diff --git a/CHANGELOG b/CHANGELOG index 08aa39e69..337545a5c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -7,6 +7,35 @@ SINGE 3.00 API Changes ----------- +- A game can be one file: singe --pack DIRECTORY GAME.game writes the game's + scripts, art, sounds, fonts, and video into an SQLite database, and + singe GAME.game (or the menu, which lists every .game file beside the game + directories) runs it. Nothing in a game has to change to be packed: + every name a script uses (dofile, require, io.open and friends, + spriteLoad, soundLoad, fontLoad, videoLoad, framefiles, controls.cfg) + goes through one lookup that tries a loose directory named like the + database, then the game's data directory, then the database, so + packed games can be modded by dropping files beside them and files a + game writes land under data//files. Inside a database names + are matched without regard to case and a leading own-directory prefix + ("DLe/Cfg/x") is ignored. singe --unpack GAME.game DIRECTORY restores + the files and singe --patch GAME.game SOURCE replaces files from a + directory or a patch database in one transaction. Loose games are + untouched by all of this. Scripts get SQLite for their own data with + require("sqlite3"). The archive installer (.game, .tool, and .patch + archives dropped beside the binary) is gone along with libarchive; a + game is a .game file or a directory, copied into place. + +- Video is decoded by libavcodec directly; FFMS2 is gone. Seeking is still + frame exact, indexing is faster, and the index files in the data + directory use a new format (old ones are rebuilt automatically). + Multi-channel audio is downmixed to stereo instead of refused. Indexing + is a few seconds at most, so the indexing screen and its artwork are gone. + Video is + decoded by the platform's hardware decoder when there is one (VA-API or + VDPAU on Linux, D3D11VA on Windows, VideoToolbox on macOS) and falls + back to software otherwise; --softwarevideo forces software. + - Singe is built on SDL3 (SDL 3.4, SDL3_image, SDL3_mixer 3.2, SDL3_ttf) instead of SDL2. Nothing changes for scripts: the same functions, constants, scancodes, and controls.cfg names. SDL2_gfx is gone; sprite @@ -160,9 +189,19 @@ Fixes video paths (the directory string was freed before use); a lone "." now means the framefile's own directory. +- A crash prints a backtrace to the console (Linux and macOS) so a report + can say where it happened; run with --program and send trace.txt too. + - Mouse positions are delivered in the video's coordinates again (SDL3 stopped scaling them for us), so crosshairs follow the pointer. +- os.clock() in scripts now returns wall time rather than processor time. + Nearly every existing game times its input debounces and prompts with + it; once the GPU decodes the video the engine mostly sleeps, and those + timers ran seconds slow. A game that wanted processor time is not + known to exist. This diverges from stock Lua and from other Singe + runtimes; new code that must be portable should use singeGetTicks(). + - A key or button still held when a game exits no longer counts as a press in the script that follows. Confirming Exit in a game with button 1 used to relaunch it from the menu. diff --git a/CMakeLists.txt b/CMakeLists.txt index 319320056..3ef18c130 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -125,9 +125,6 @@ singeEmbedImage(font) singeEmbedImage(icon) singeEmbedImage(kangarooPunchLogo) singeEmbedImage(singeLogo) -singeEmbedImage(laserDisc) -singeEmbedImage(magnifyingGlass) -singeEmbedImage(indexing) # Windows icon for the resource file. add_custom_command( @@ -225,6 +222,8 @@ set(SINGE_SOURCE src/frameFile.h src/main.c src/main.h + src/pack.c + src/pack.h src/singe.c src/singe.h src/stddclmr.h @@ -232,6 +231,14 @@ set(SINGE_SOURCE src/util.h src/videoPlayer.c src/videoPlayer.h + src/vfs.c + src/vfs.h +) + +set(SQLITE_SOURCE + thirdparty/sqlite/sqlite3.c + thirdparty/sqlite/sqlite3.h + thirdparty/lsqlite3/lsqlite3.c ) set(ARG_PARSER_SOURCE @@ -345,6 +352,7 @@ add_executable(${CMAKE_PROJECT_NAME} ${ARG_PARSER_SOURCE} ${LUA_SOURCE} ${LUA_FILESYSTEM_SOURCE} + ${SQLITE_SOURCE} ${LUA_SOCKET_SOURCE} ${LUASEC_SOURCE} ${LUA_RS232_SOURCE} @@ -367,7 +375,10 @@ set_source_files_properties(${SINGE_SOURCE} PROPERTIES COMPILE_OPTIONS "-Wall;-W target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE RS232_STATIC - FFMS_STATIC + SQLITE_DQS=0 + SQLITE_THREADSAFE=1 + SQLITE_DEFAULT_MEMSTATUS=0 + SQLITE_OMIT_SHARED_CACHE ) if(WIN32) # _WIN32_WINNT=0x0600 sets the minimum compatible version of Windows to Vista. @@ -387,6 +398,7 @@ target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${BUILD_DIR} ${BUILD_DIR}/include thirdparty/lua/src + thirdparty/sqlite thirdparty/luasec/src thirdparty/librs232/include ) @@ -401,7 +413,7 @@ target_link_directories(${CMAKE_PROJECT_NAME} PRIVATE # Platform specific system libraries. if(KANGAROO_OS STREQUAL "linux") # ffmpeg's vdpau hardware context is always compiled in on X11 hosts. - set(SYSTEM_LIBS -lX11 -lvdpau -ldl) + set(SYSTEM_LIBS -lX11 -lvdpau -ldl -rdynamic) # -rdynamic gives the crash backtrace function names elseif(KANGAROO_OS STREQUAL "pi") set(SYSTEM_LIBS -ldl) elseif(KANGAROO_OS STREQUAL "macos") @@ -454,18 +466,33 @@ else() message(FATAL_ERROR "Unknown KANGAROO_OS: ${KANGAROO_OS}") endif() +# FFmpeg's hardware decoding backends (VA-API, VDPAU, DRM, V4L2) are whatever build-all.sh +# configured; its pkg-config files name the system libraries they need, so read them back. +if(KANGAROO_OS STREQUAL "linux" OR KANGAROO_OS STREQUAL "pi") + foreach(pc libavutil libavcodec) + set(pcFile ${BUILD_DIR}/lib/pkgconfig/${pc}.pc) + if(EXISTS ${pcFile}) + file(STRINGS ${pcFile} pcLibs REGEX "^Libs:") + string(REGEX REPLACE "^Libs: *" "" pcLibs "${pcLibs}") + separate_arguments(pcLibs) + foreach(token ${pcLibs}) + if(token MATCHES "^-l" AND NOT token MATCHES "^-l(avutil|avcodec|z|m|atomic|pthread)$") + list(APPEND SYSTEM_LIBS ${token}) + endif() + endforeach() + endif() + endforeach() + list(REMOVE_DUPLICATES SYSTEM_LIBS) +endif() + # Static third party libraries built by build-all.sh. set(STATIC_LIBS - ${BUILD_DIR}/lib/libarchive.a ${BUILD_DIR}/lib/libavcodec.a ${BUILD_DIR}/lib/libavdevice.a ${BUILD_DIR}/lib/libavfilter.a ${BUILD_DIR}/lib/libavformat.a ${BUILD_DIR}/lib/libavutil.a - ${BUILD_DIR}/lib/libbz2_static.a - ${BUILD_DIR}/lib/libffms2.a ${BUILD_DIR}/lib/libfreetype.a - ${BUILD_DIR}/lib/liblzma.a ${BUILD_DIR}/lib/libopus.a ${BUILD_DIR}/lib/libopusfile.a ${BUILD_DIR}/lib/libogg.a @@ -491,7 +518,6 @@ if(NOT KANGAROO_OS STREQUAL "macos") list(APPEND STATIC_LIBS ${BUILD_DIR}/lib/libjpeg.a ${BUILD_DIR}/lib/libpng.a - -lstdc++ ) endif() diff --git a/LICENSES b/LICENSES index 402f6ec98..2d6006c5f 100644 --- a/LICENSES +++ b/LICENSES @@ -5,19 +5,17 @@ these tools, Singe would not exist. arg_parser BSD-2-Clause http://savannah.nongnu.org/projects/arg-parser binaryheap.lua MIT http://tieske.github.io/binaryheap.lua -bzip2 bzip2-1.0.6 https://sourceware.org/bzip2 copas MIT https://lunarmodules.github.io/copas ffmpeg LGPL-2.1 https://ffmpeg.org -ffms2 GPL-3.0-only https://github.com/FFMS/ffms2 freetype FTL https://freetype.org json.lua MIT https://github.com/rxi/json.lua -libarchive BSD-2-Clause https://libarchive.org libjpeg-turbo IJG https://libjpeg-turbo.org libogg BSD-3-Clause https://xiph.org/ogg libpng libpng-2.0 http://www.libpng.org librs232 MIT https://github.com/srdgame/librs232 libwebp BSD-3-Clause https://developers.google.com/speed/webp libxmp MIT https://github.com/libxmp/libxmp +lsqlite3 MIT http://lua.sqlite.org lua MIT https://www.lua.org luafilesystem MIT https://lunarmodules.github.io/luafilesystem luasec MIT https://github.com/lunarmodules/luasec @@ -30,11 +28,11 @@ SDL3 Zlib https://www.libsdl.org SDL3_image Zlib https://www.libsdl.org SDL3_mixer Zlib https://www.libsdl.org SDL3_ttf Zlib https://www.libsdl.org +sqlite Public-Domain https://sqlite.org timerwheel.lua MIT https://tieske.github.io/timerwheel.lua uthash BSD-1-Clause https://troydhanson.github.io/uthash vlc GPL-2.0 https://www.videolan.org/vlc wavpack BSD-3-Clause https://www.wavpack.com -xz Public-Domain https://github.com/tukaani-project/xz zlib Zlib https://zlib.net zstd BSD-3-Clause https://facebook.github.io/zstd diff --git a/assets/Menu.singe b/assets/Menu.singe index ed22e01ce..03dd157ac 100644 --- a/assets/Menu.singe +++ b/assets/Menu.singe @@ -409,7 +409,41 @@ function wrapText(text, maxWidth) end --- Search for games.dat files in subdirectories +-- Adds the entries of one games.dat. container is the game database the file came from, or nil. +local function loadGamesDat(source, container) + GAMES = {} + local ok, err = pcall(dofile, source) + if not ok then + debugPrint(source .. ": " .. tostring(err) .. " Skipped.") + GAMES = {} + return + end + for _, value in pairs(GAMES or {}) do + -- Since 3.00 a laserdisc game must say DISC = true; refuse the ambiguous cases here + -- with a message rather than letting the engine stop the menu when it is picked. + local title = tostring(value.TITLE or value.SCRIPT or "?") + if value.VIDEO and not value.DISC then + debugPrint(source .. ": \"" .. title .. "\" names a VIDEO without DISC = true; add DISC = true to the entry. Skipped.") + elseif value.DISC and not value.VIDEO then + debugPrint(source .. ": \"" .. title .. "\" says DISC = true but has no VIDEO. Skipped.") + else + if container then + -- Packed game: the engine opens its files through the database, and so does the menu. + value.CONTAINER = container + for _, key in ipairs({ "CABINET", "MARQUEE", "ATTRACT" }) do + if value[key] then + value[key] = container .. "/" .. value[key] + end + end + end + table.insert(GAME_LIST, value) + GAME_COUNT = GAME_COUNT + 1 + end + end + GAMES = {} +end + +-- Search for games.dat files in subdirectories and inside .game databases GAME_LIST = {} GAME_COUNT = 0 for dir in lfs.dir(".") do @@ -418,25 +452,11 @@ for dir in lfs.dir(".") do if dirattr.mode == "directory" then for file in lfs.dir(dir .. "/.") do if file == "games.dat" then - -- Load games.dat - GAMES = {} - dofile(dir .. "/games.dat") - for _, value in pairs(GAMES or {}) do - -- Since 3.00 a laserdisc game must say DISC = true; refuse the ambiguous cases here - -- with a message rather than letting the engine stop the menu when it is picked. - local title = tostring(value.TITLE or value.SCRIPT or "?") - if value.VIDEO and not value.DISC then - debugPrint(dir .. "/games.dat: \"" .. title .. "\" names a VIDEO without DISC = true; add DISC = true to the entry. Skipped.") - elseif value.DISC and not value.VIDEO then - debugPrint(dir .. "/games.dat: \"" .. title .. "\" says DISC = true but has no VIDEO. Skipped.") - else - table.insert(GAME_LIST, value) - GAME_COUNT = GAME_COUNT + 1 - end - end - GAMES = {} + loadGamesDat(dir .. "/games.dat", nil) end end + elseif dirattr.mode == "file" and dir:sub(-5):lower() == ".game" then + loadGamesDat(dir .. "/games.dat", dir) end end end diff --git a/build-all.sh b/build-all.sh index cb086554d..59003d31d 100755 --- a/build-all.sh +++ b/build-all.sh @@ -44,7 +44,14 @@ function buildAll() { export CFLAGS="-I${G_TARGET}/include ${CFLAGS:-}" export CXXFLAGS="-I${G_TARGET}/include ${CXXFLAGS:-}" export LD_LIBRARY_PATH="${G_TARGET}/lib" + # Our own libraries first, then the platform's (FFmpeg's hardware decoders need libva and libdrm). export PKG_CONFIG_LIBDIR="${G_TARGET}/lib/pkgconfig" + if [[ "${OS}" == "linux" ]]; then + export PKG_CONFIG_LIBDIR="${PKG_CONFIG_LIBDIR}:/usr/lib/${TRIPLE}/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig" + elif [[ "${OS}" == "pi" ]]; then + export PKG_CONFIG_LIBDIR="${PKG_CONFIG_LIBDIR}:${SYSROOT}/usr/lib/${TRIPLE}/pkgconfig:${SYSROOT}/usr/lib/pkgconfig:${SYSROOT}/usr/share/pkgconfig" + export PKG_CONFIG_SYSROOT_DIR="${SYSROOT}" + fi mkdir -p ${G_GENERATED} @@ -52,28 +59,9 @@ function buildAll() { if [[ "${OS}" == "pi" ]]; then export CFLAGS="--sysroot=${SYSROOT} ${CFLAGS}" export CXXFLAGS="--sysroot=${SYSROOT} ${CXXFLAGS}" - sudo chroot ${SYSROOT} apt-get -y install libasound-dev libxi-dev libvdpau-dev + sudo chroot ${SYSROOT} apt-get -y install libasound-dev libxi-dev libvdpau-dev libdrm-dev fi - pushd thirdparty/bzip2 - clearAndEnterBuild - cmake ${COMMON} \ - -DENABLE_SHARED_LIB=off \ - -DENABLE_STATIC_LIB=on \ - -DENABLE_LIB_ONLY=on \ - .. - make install - popd - - pushd thirdparty/xz - clearAndEnterBuild - cmake ${COMMON} \ - -DBUILD_SHARED_LIBS=off \ - -DBUILD_TESTING=off \ - .. - make install - popd - pushd thirdparty/zlib clearAndEnterBuild CFLAGS="-I${PWD}" ../configure \ @@ -166,42 +154,6 @@ function buildAll() { make install popd - pushd thirdparty/libarchive - clearAndEnterBuild - cmake ${COMMON} \ - -DBUILD_SHARED_LIBS=off \ - -DBUILD_TESTING=off \ - -DENABLE_CAT=off \ - -DENABLE_CNG=off \ - -DENABLE_CPIO=off \ - -DENABLE_EXPAT=off \ - -DENABLE_ICONV=off \ - -DENABLE_LIBB2=off \ - -DENABLE_LIBGCC=off \ - -DENABLE_LIBXML2=off \ - -DENABLE_LZ4=off \ - -DENABLE_LZO=off \ - -DENABLE_MBEDTLS=off \ - -DENABLE_NETTLE=off \ - -DENABLE_OPENSSL=off \ - -DENABLE_PCREPOSIX=off \ - -DENABLE_TAR=off \ - -DENABLE_TEST=off \ - -DENABLE_UNZIP=off \ - -DPOSIX_REGEX_LIB=libc \ - -DUSE_BZIP2_STATIC=on \ - -DBZIP2_INCLUDE_DIR="${G_TARGET}/include" \ - -DBZIP2_LIBRARIES="${G_TARGET}/lib/libbz2_static.a" \ - -DZLIB_ROOT="${G_TARGET}" \ - -DLIBLZMA_INCLUDE_DIR="${G_TARGET}/include" \ - -DLIBLZMA_LIBRARY="${G_TARGET}/lib/liblzma.a" \ - -DZSTD_INCLUDE_DIR="${G_TARGET}/include" \ - -DZSTD_LIBRARY="${G_TARGET}/lib/libzstd.a" \ - -DWINDOWS_VERSION=VISTA \ - .. - make install - popd - pushd thirdparty/openssl clearAndEnterBuild if [[ "${OS}" == "windows" ]]; then @@ -252,6 +204,15 @@ function buildAll() { mkdir -p "${G_TARGET}/include/sys" echo "/* File no longer used */" > "${G_TARGET}/include/sys/sysctl.h" fi + # Hardware decoding: each platform's native API. The libraries these pull in are read back + # from FFmpeg's pkg-config files by CMakeLists.txt, so the link follows this choice. + case "${OS}" in + linux) HWACCEL="--enable-vaapi --enable-vdpau --enable-libdrm" ;; + pi) HWACCEL="--enable-v4l2-m2m --enable-libdrm" ;; + macos) HWACCEL="--enable-videotoolbox" ;; + windows) HWACCEL="--enable-d3d11va --enable-dxva2" ;; + *) HWACCEL="" ;; + esac pushd thirdparty/ffmpeg clearAndEnterBuild # https://trac.ffmpeg.org/wiki/CompilationGuide/CrossCompilingForWindows @@ -260,11 +221,13 @@ function buildAll() { --disable-shared \ --disable-debug \ --disable-muxers \ - --disable-hwaccels \ + ${HWACCEL} \ --disable-encoders \ --disable-filters \ --disable-network \ --disable-devices \ + --disable-bzlib \ + --disable-lzma \ --disable-doc \ --disable-programs \ --enable-gpl \ @@ -280,21 +243,6 @@ function buildAll() { make install popd - pushd thirdparty/ffms2 - # The configure script is not checked in; generate it once. - [[ -x configure ]] || NOCONFIGURE=1 ./autogen.sh - clearAndEnterBuild - ../configure \ - --prefix=${G_TARGET} \ - --with-zlib=${G_TARGET} \ - --enable-static \ - --disable-shared \ - --target=${TRIPLE} \ - --host=${TRIPLE} \ - --build=x86_64-linux - make install-libLTLIBRARIES # This weird target prevents building the command line tools. - popd - # Embedded resources, the version header, and the manual are generated by CMake. pushd ${G_TARGET} @@ -341,7 +289,9 @@ sudo apt-get install -y \ libtool \ libasound-dev \ libxi-dev \ - libvdpau-dev + libvdpau-dev \ + libva-dev \ + libdrm-dev # Usage: build-all.sh [os arch] (default: every supported platform) diff --git a/docs/Manual.adoc b/docs/Manual.adoc index 2d640b255..625a490ca 100644 --- a/docs/Manual.adoc +++ b/docs/Manual.adoc @@ -69,9 +69,9 @@ be updated or deleted at any time. === Installing Games -Games designed for Singe 2.xx and later simply need to be unpacked and copied -into the same folder where you placed the Singe binary. The included menu -system will automatically detect them and add them to the menu. +A game is either a single `.game` file or a directory. Copy it into the same +folder where you placed the Singe binary. The included menu system will +automatically detect it and add it to the menu. === Customizing the Controls @@ -105,9 +105,10 @@ options available to be used in this file, read through Singe [OPTIONS] scriptName{.singe} ---- -The script name is the only required argument. It may be a `.singe` file, or -a directory containing a script of the same name (`ActionMax` finds -`ActionMax/ActionMax.singe`). For a laserdisc game (`--disc`) with no +The script name is the only required argument. It may be a `.singe` file, a +directory containing a script of the same name (`ActionMax` finds +`ActionMax/ActionMax.singe`), or a packed game (`DLe.game` runs the first +entry of the `games.dat` inside it). For a laserdisc game (`--disc`) with no `--framefile`, Singe looks for a video next to the script with the same base name and any extension FFmpeg can demux, then for a `.txt` framefile. @@ -122,15 +123,19 @@ name and any extension FFmpeg can demux, then for a `.txt` framefile. | `-d`, `--datadir=PATHNAME` | Directory for everything Singe writes: video indexes, `trace.txt`, screenshots, the menu's `menu.dat`. A subdirectory named for the game's directory is created inside it. Defaults to the game's own directory. | `-e`, `--volume_nonvldp=PERCENT` | Sound effect and extra video volume, `0` to `100`. | `-f`, `--fullscreen` | Exclusive full screen at the desktop resolution. +| `-H`, `--softwarevideo` | Decode video in software even when the platform offers a hardware decoder (VA-API or VDPAU on Linux, D3D11VA on Windows, VideoToolbox on macOS). Use it to rule the hardware path in or out when a video misbehaves; the program trace says which decoder is in use. | `-h`, `--help` | Show the option summary and exit. | `-k`, `--nologos` | Skip the splash screens. | `-l`, `--volume_vldp=PERCENT` | Laserdisc volume, `0` to `100`. | `-m`, `--nomouse` | Disable mouse and lightgun input entirely. | `-n`, `--nocrosshair` | Ask the game not to draw its own crosshair. Exposed to scripts as `singeWantsCrosshairs()`. | `-o`, `--audio=TRACK` | Default audio track (zero based) for videos with several, such as multi-language releases. +| `-P`, `--pack=DIRECTORY` | Pack the game in `DIRECTORY` into the database named after the options, then exit. See <>. | `-p`, `--program` | Trace engine activity to the console and to `trace.txt` in the data directory. | `-s`, `--nosound` | Mute all audio. +| `-T`, `--patch=GAME.game` | Replace files in the packed game from the directory or patch database named after the options, then exit. | `-t`, `--trace` | Trace every Lua API call, with the script line that made it, to the console and to `trace.txt`. +| `-U`, `--unpack=GAME.game` | Write the packed game's files into the directory named after the options, then exit. | `-u`, `--stretch` | Stretch the video to fill the window instead of keeping its aspect ratio. | `-v`, `--framefile=FILENAME` | Video file or framefile to use instead of the one found next to the script. | `-w`, `--fullscreen_window` | Borderless window covering the desktop. @@ -245,9 +250,9 @@ dofile("Singe/Framework.singe") * Keep your game self-contained. If you build on a third-party framework or share code between your games, copy it into your game directory. Never reference a directory beside your game; the only file outside your game a - script may load is `Singe/Framework.singe`. A future single-file game format - packs exactly one directory, and a game that reaches outside it cannot be - packed. + script may load is `Singe/Framework.singe`. A single-file game (see + <>) packs exactly one directory, and a game + that reaches outside it cannot be packed. * Stay out of the `Singe/` folder. This is managed by Singe and anything added or changed here is subject to future deletion. * Include a `games.dat`. This is extremely important for new users. While @@ -276,6 +281,7 @@ ActionMax/ One game 38AmbushAlley.singe A script frame_38AmbushAlley.txt Its framefile (or a video with the same base name) sprite_*.png, sound_*.wav, font_*.ttf +DLe.game A game packed into one file (see Single-File Games) data/ ActionMax/ Indexes, trace.txt, screenshots for that game ---- @@ -294,32 +300,98 @@ so a game can live on read-only media. === Packaging Your Game -Singe installs games itself. Drop an archive into the installation directory, -start Singe, and the archive is validated, unpacked, and deleted. Any format -libarchive reads is accepted (zip, 7z, tar.gz, and so on); the extension -tells Singe what kind of package it is: +A finished game ships as one `.game` file, described next. Nothing else is +needed: the player copies the file beside the Singe binary and the menu +lists it. Singe no longer installs archives. -[cols="1,3",options="header"] -|=== -| Extension | Rules -| `.game` | Everything must live inside one top level directory, which must contain a `games.dat`. -| `.tool` | Like a game, but no `games.dat` is required. -| `.patch` | Files may live anywhere; used to update an installed game in place. -|=== +[#singlefile] +=== Single-File Games -Every package is rejected if it contains `controls.dat`, `Framework.singe`, -a file whose extension is `exe`, `sh`, `bat`, `cmd`, or `index`, or (for -games and tools) an extensionless file whose name starts with `singe`. Paths -that escape the installation directory are refused as well. Do not ship video -index files; Singe rebuilds them on first run. - -To make a package, archive your game directory so the directory itself is the -top level entry, and rename the result: +A game can be one file. `singe --pack` writes a game directory into an +SQLite database, and Singe runs it from there: scripts, sprites, sounds, +fonts, framefiles, and video all load straight out of the database, and +installing the game is copying the file next to the executable. The menu +lists every `.game` file it finds beside the game directories. ---- -zip -r ActionMax.game ActionMax +Singe --pack DLe DLe.game Pack the DLe directory into DLe.game +Singe DLe.game Run the first games.dat entry in it +Singe --unpack DLe.game DLe Write the files back out +Singe --patch DLe.game fixes Replace files from a directory (or a patch database) ---- +Nothing in a game has to change to be packed. Every name a script uses, +whether through `dofile`, `require`, `io.open` and its relatives, +`spriteLoad`, `soundLoad`, `fontLoad`, `videoLoad`, a framefile, or a +`controls.cfg`, goes through one lookup. For a loose game that lookup is +the plain filesystem, relative to the directory Singe was started from, +exactly as before. For a packed game a name is tried in three places, in +this order, and the first hit wins: + +. A loose directory named like the database without its extension + (`DLe/` beside `DLe.game`). This is how you keep editing a packed game, + and how a player mods one: files dropped there beat the packed copies. +. The game's data directory, under `files/`. Everything a game writes + with `io.output` or `io.open(name, "w")` lands here, so a saved + `game.cfg` beats the packed original and the database is never written. +. The database itself. + +Inside a database, names are matched without regard to case, with either +path separator, and relative to the game root. A leading component equal to +the game's own directory name is ignored, so `DLe/Cfg/game.cfg`, +`Cfg/game.cfg`, and `DIR .. "Cfg/game.cfg"` all find the same file. Names +starting with `Singe/` or with the data directory stay on the filesystem; +`Singe/Framework.singe` and `singeGetDataPath()` work as always. +`require("name")` finds `name.lua`, `name/init.lua`, or `name.singe` under the +script's directory, then under the game root. + +The packer refuses a directory that has no `games.dat`, that contains +`controls.dat`, `Framework.singe`, a file whose extension is `exe`, `sh`, +`bat`, or `cmd`, or an extensionless file whose name starts with `singe`, +that has a top level entry named like the directory itself (that would make the own-directory +rule ambiguous), or whose scripts and data files reach outside the game +with `..`; it reports the file and line. Two files whose names differ only +by case cannot both be packed. Stale `.index` files are skipped. A game +that references another game's directory (a shared framework beside it) +must copy that directory inside first. + +`--patch` takes either a directory laid out like the game, whose files +replace the packed ones, or a database made by `--pack` from such a +directory. Either way the change is one transaction: the game is intact if +it is interrupted. A patch database may also carry a `removed(path)` table +naming files to delete. + +A packed game keeps its data directory exactly where the loose game would +have it (`data/DLe/` for `DLe/DLe.singe`), so saves and settings are shared +between a loose install and a packed one. The video index goes there too. +When Singe runs a game from a database the menu passes `CONTAINER` in the +`games.dat` entry it launches; the field is set by the menu, never by hand. + +For your own data, `require("sqlite3")` gives scripts the +https://lua.sqlite.org[lsqlite3] binding to the same SQLite the engine +uses. Keep such databases in `singeGetDataPath()`: + +[source,lua] +---- +local sqlite3 = require("sqlite3") +local db = sqlite3.open(singeGetDataPath() .. "scores.db") +db:exec("CREATE TABLE IF NOT EXISTS scores (name TEXT, score INTEGER)") +for row in db:nrows("SELECT name, score FROM scores ORDER BY score DESC LIMIT 10") do + print(row.name, row.score) +end +db:close() +---- + +The file format, for anyone writing tools: three tables. +`meta(key, value)` holds `version` (1), `gamedir` (the packed directory's +name), `chunk` (chunk size in bytes, 4194304), and `packer`. +`assets(path, name, size, data)` has one row per file, `path` being the +lower case forward-slash key and `name` the author's spelling; files no +larger than the chunk size are in `data`, larger ones have `data` NULL and +live in `chunks(path, chunk, data)` as consecutive numbered pieces. Singe +opens the database read only and immutable, so it runs from read-only +media and never journals beside it. + === Event Driven... Or Not? Traditionally, Singe used an event-driven programming model -- Singe handles @@ -697,6 +769,7 @@ install any additional software: | LuaSec | TLS / SSL communication | LuaSocket | TCP and UDP | LuaRS232 | RS232 serial port access +| lsqlite3 | SQLite databases, `require("sqlite3")` |=== Their usage is beyond the scope of this document. @@ -718,7 +791,11 @@ Two properties of the video file itself also matter. AAC audio carries encoder p === Video, Audio, and Container Formats -Singe decodes video with FFmpeg through FFMS2, so any container and codec the +Singe decodes video with FFmpeg's libraries directly, using the platform's hardware +decoder when it offers one for the codec (VA-API or VDPAU on Linux, D3D11VA on +Windows, VideoToolbox on macOS) and its own software decoder otherwise; the +program trace reports which, and `--softwarevideo` forces software. Any container +and codec the bundled FFmpeg can demux and decode will play: MP4, MKV, MPEG program streams, AVI, and the classic Daphne `.m2v` elementary streams with a matching `.ogg` audio file next to them. Every audio track in the file is available to @@ -726,8 +803,9 @@ audio file next to them. Every audio track in the file is available to format, channel count, and rate. The first time a video is opened, Singe indexes it and stores the index next -to the game's other data (`.index`). Indexing takes a while for large -files and happens again if the video changes. When a video is loaded, Singe +to the game's other data (`.index`). Indexing is one pass over the file +without decoding, a few seconds even for a feature length disc, and happens +again if the video changes. When a video is loaded, Singe reports its keyframe spacing in the program trace (`--program`), with a warning there if keyframes are more than two seconds apart, because a seek has to decode forward from the previous keyframe. Decoding happens on a separate thread, @@ -2177,7 +2255,7 @@ Returns the absolute path of the currently running script file. `Framework.singe milliseconds = singeGetTicks() ---- -Returns the wall clock in milliseconds since the engine started. Unlike `os.clock()`, which measures processor time and drifts whenever the engine idles, this is the clock to use for timers, debounces, and animation. +Returns the wall clock in milliseconds since the engine started. This is the clock to use for timers, debounces, and animation. Lua's `os.clock()` normally measures processor time, which drifts whenever the engine idles; because existing games use it as a wall clock, Singe replaces it with one that returns wall seconds since the engine started, so either call is safe. *Since:* 3.00 diff --git a/src/embedded.h b/src/embedded.h index 692feb245..d87f72466 100644 --- a/src/embedded.h +++ b/src/embedded.h @@ -29,9 +29,6 @@ #include "generated/icon.h" #include "generated/kangarooPunchLogo.h" #include "generated/singeLogo.h" -#include "generated/laserDisc.h" -#include "generated/magnifyingGlass.h" -#include "generated/indexing.h" #include "generated/Framework_singe.h" #include "generated/controls_cfg.h" #include "generated/Menu_singe.h" diff --git a/src/frameFile.c b/src/frameFile.c index fd08b7800..f398ae0c0 100644 --- a/src/frameFile.c +++ b/src/frameFile.c @@ -27,6 +27,7 @@ #include "../thirdparty/uthash/src/uthash.h" #include "util.h" +#include "vfs.h" #include "videoPlayer.h" #include "frameFile.h" @@ -162,7 +163,7 @@ int32_t frameFileLoad(const char *filename, const char *indexPath, SDL_Renderer FrameLineT *newFiles = NULL; FrameFileT *frameFile = NULL; - data = utilReadFile(filename, &bytes); + data = vfsRead(filename, &bytes); if (!data) { utilDie("Unable to open framefile: %s", filename); } diff --git a/src/frameFile.h b/src/frameFile.h index 6e7145c3d..f5477cb43 100644 --- a/src/frameFile.h +++ b/src/frameFile.h @@ -25,7 +25,7 @@ #define FRAMEFILE_H -#include +#include #include "common.h" diff --git a/src/main.c b/src/main.c index 0773b5d6e..4f8f1c985 100644 --- a/src/main.c +++ b/src/main.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #ifdef _WIN32 #include @@ -34,8 +33,11 @@ #include #endif -#include "include/archive.h" -#include "include/archive_entry.h" +#include +#ifndef _WIN32 +#include +#endif + #include #include #include @@ -51,6 +53,8 @@ #include "frameFile.h" #include "videoPlayer.h" #include "singe.h" +#include "pack.h" +#include "vfs.h" #include "../thirdparty/ffmpeg/libavformat/avformat.h" #include "embedded.h" @@ -61,17 +65,10 @@ #define MIXER_FREQUENCY 44100 #define MIXER_CHANNELS 2 #define MIXER_CHUNK_SAMPLES "1024" // Device buffer, kept small so the audio queue and any error in measuring it stay small -#define ARCHIVE_BLOCK_SIZE 10240 #define USAGE_OPTION_WIDTH 27 +#define CRASH_FRAMES_MAX 64 -typedef enum PackageTypeE { - PACKAGE_GAME = 0, - PACKAGE_TOOL, - PACKAGE_PATCH, - PACKAGE_COUNT -} PackageTypeE; - typedef struct RatioS { int32_t aspectNum; int32_t aspectDom; @@ -110,12 +107,6 @@ typedef struct EmbeddedFileS { static QueueT *_scriptQueue = NULL; -static const char *const _packageTypes[PACKAGE_COUNT] = { "Game", "Tool", "Patch" }; - -static const char *const _badFilenames[] = { "controls.dat", "Framework.singe", NULL }; - -static const char *const _badExtensions[] = { "exe", "sh", "bat", "cmd", "index", NULL }; - // Single source of truth for the command line: feeds both the parser and the usage text. // The overscan and Sinden options work but are hidden until the Sinden border scales mouse input. static const OptionT _options[] = { @@ -129,15 +120,19 @@ static const OptionT _options[] = { { 'e', "volume_nonvldp", ap_yes, "PERCENT", "specify sound effects volume in percent", false }, { 'f', "fullscreen", ap_no, NULL, "run in full screen mode", false }, { 'g', "sindengun", ap_yes, "'PARAMS'", "enable Sinden Light Gun support", true }, + { 'H', "softwarevideo", ap_no, NULL, "decode video in software even when a hardware decoder exists", false }, { 'h', "help", ap_no, NULL, "this display", false }, { 'k', "nologos", ap_no, NULL, "kill the splash screens", false }, { 'l', "volume_vldp", ap_yes, "PERCENT", "specify laserdisc volume in percent", false }, { 'm', "nomouse", ap_no, NULL, "disable mouse", false }, { 'n', "nocrosshair", ap_no, NULL, "request game not display gun crosshairs", false }, { 'o', "audio", ap_yes, "TRACK", "select default track for audio output", false }, + { 'P', "pack", ap_yes, "DIRECTORY", "pack a game DIRECTORY into the database named after the options", false }, { 'p', "program", ap_no, NULL, "trace Singe execution to screen and file", false }, { 's', "nosound", ap_no, NULL, "mutes all sound", false }, + { 'T', "patch", ap_yes, "DATABASE", "patch a game DATABASE from the directory or patch database named after the options", false }, { 't', "trace", ap_no, NULL, "trace script execution to screen and file", false }, + { 'U', "unpack", ap_yes, "DATABASE", "unpack a game DATABASE into the directory named after the options", false }, { 'u', "stretch", ap_no, NULL, "use ugly stretched video", false }, { 'v', "framefile", ap_yes, "FILENAME", "use an alternate video file", false }, { 'w', "fullscreen_window", ap_no, NULL, "run in windowed full screen mode", false }, @@ -180,13 +175,15 @@ static const ModeT _modes[] = { static char *_cloneString(const char *string); -static bool _extractArchive(const char *filename); static bool _extractFile(const char *filename, const uint8_t *data, size_t length); static char *_findVideoFile(const char *baseName); +#ifndef _WIN32 +static void _crashHandler(int signalNumber); +#endif static void _launcher(const char *exeName, ConfigT *conf); static void _mainTrace(const ConfigT *conf, const char *fmt, ...) __attribute__((format(printf, 2, 3))); +static bool _runTool(const ConfigT *conf); static bool _modeMatchesRatio(int32_t index, int32_t ratioIndex); -static struct archive *_openArchive(const char *filename); static ConfigT *_parseArguments(const char *exeName, int32_t argc, char *argv[]); static bool _parseInteger(const char *text, int32_t *value); static void _resolveFiles(const char *exeName, ConfigT *conf); @@ -195,8 +192,6 @@ static void _showUsage(const char *name, const char *message) __attri static void _startSDL(void); static void _stopSDL(void); static void _unpackData(const char *name); -static void _unpackGames(void); -static bool _validateArchive(const char *filename, PackageTypeE type); static char *_cloneString(const char *string) { @@ -208,87 +203,6 @@ static char *_cloneString(const char *string) { } -// https://github.com/libarchive/libarchive/wiki/Examples#user-content-A_Complete_Extractor -static bool _extractArchive(const char *filename) { - struct archive *a = NULL; - struct archive *ext = NULL; - struct archive_entry *entry = NULL; - const void *buff = NULL; - size_t size = 0; - la_int64_t offset = 0; - int32_t flags = 0; - int32_t r = 0; - bool ok = true; - - // Never let an archive write outside the current directory. - flags = ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL | ARCHIVE_EXTRACT_FFLAGS; - flags |= ARCHIVE_EXTRACT_SECURE_NODOTDOT | ARCHIVE_EXTRACT_SECURE_SYMLINKS | ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS; - - a = _openArchive(filename); - if (a == NULL) { - return false; - } - ext = archive_write_disk_new(); - archive_write_disk_set_options(ext, flags); - archive_write_disk_set_standard_lookup(ext); - - while (ok) { - r = archive_read_next_header(a, &entry); - if (r == ARCHIVE_EOF) { - break; - } - if (r < ARCHIVE_OK) { - utilSay("%s", archive_error_string(a)); - } - if (r < ARCHIVE_WARN) { - ok = false; - break; - } - r = archive_write_header(ext, entry); - if (r < ARCHIVE_OK) { - utilSay("%s", archive_error_string(ext)); - } else { - if (archive_entry_size(entry) > 0) { - for (;;) { - r = archive_read_data_block(a, &buff, &size, &offset); - if (r == ARCHIVE_EOF) { - r = ARCHIVE_OK; - break; - } - if (r < ARCHIVE_OK) { - utilSay("%s", archive_error_string(a)); - break; - } - r = archive_write_data_block(ext, buff, size, offset); - if (r < ARCHIVE_OK) { - utilSay("%s", archive_error_string(ext)); - break; - } - } - if (r < ARCHIVE_WARN) { - ok = false; - break; - } - } - } - r = archive_write_finish_entry(ext); - if (r < ARCHIVE_OK) { - utilSay("%s", archive_error_string(ext)); - } - if (r < ARCHIVE_WARN) { - ok = false; - break; - } - } - archive_read_close(a); - archive_read_free(a); - archive_write_close(ext); - archive_write_free(ext); - - return ok; -} - - // Writes an embedded support file, or rewrites it when the installed copy differs from this build's. static bool _extractFile(const char *filename, const uint8_t *data, size_t length) { FILE *out = NULL; @@ -346,7 +260,7 @@ static char *_findVideoFile(const char *baseName) { comma++; } candidate = utilCreateString("%s.%s", baseName, extension); - if (utilFileExists(candidate)) { + if (vfsExists(candidate)) { free(extensions); return candidate; } @@ -359,6 +273,22 @@ static char *_findVideoFile(const char *baseName) { } +// Last words on a crash: where it happened, so a report can name the line. Async-signal-unsafe +// calls are acceptable here; the process is already lost. +#ifndef _WIN32 +static void _crashHandler(int signalNumber) { + void *frames[CRASH_FRAMES_MAX]; + int32_t count = backtrace(frames, CRASH_FRAMES_MAX); + + fprintf(stderr, "\nSinge crashed (signal %d). Backtrace:\n", signalNumber); + backtrace_symbols_fd(frames, count, STDERR_FILENO); + fprintf(stderr, "Run with --program and send trace.txt with this.\n"); + signal(signalNumber, SIG_DFL); + raise(signalNumber); +} +#endif + + static void _launcher(const char *exeName, ConfigT *conf) { int32_t x = 0; int32_t bestResIndex = -1; @@ -495,6 +425,7 @@ static void _launcher(const char *exeName, ConfigT *conf) { // Start our video playback system _mainTrace(conf, "Initializing laserdisc video"); videoInit(mixer); + videoSetHardwareDecoding(!conf->softwareVideo); // Finish our setup _mainTrace(conf, "Disabling screen saver"); @@ -536,21 +467,6 @@ static bool _modeMatchesRatio(int32_t index, int32_t ratioIndex) { } -static struct archive *_openArchive(const char *filename) { - struct archive *a = archive_read_new(); - - archive_read_support_filter_all(a); - archive_read_support_format_all(a); - if (archive_read_open_filename(a, filename, ARCHIVE_BLOCK_SIZE) != ARCHIVE_OK) { - utilSay("!!! Cannot read %s: %s", filename, archive_error_string(a)); - archive_read_free(a); - return NULL; - } - - return a; -} - - static ConfigT *_parseArguments(const char *exeName, int32_t argc, char *argv[]) { int32_t x = 0; int32_t argIndex = 0; @@ -668,6 +584,20 @@ static ConfigT *_parseArguments(const char *exeName, int32_t argc, char *argv[]) sindenString = strdup(arg); break; + // Software video decoding + case 'H': + conf->softwareVideo = true; + break; + + // Packing tools: the second name comes from the script argument + case 'P': + case 'T': + case 'U': + conf->toolMode = (code == 'P') ? TOOL_PACK : (code == 'T') ? TOOL_PATCH : TOOL_UNPACK; + free(conf->toolSource); + conf->toolSource = strdup(arg); + break; + // Help case 'h': _showUsage(exeName, NULL); @@ -760,9 +690,9 @@ static ConfigT *_parseArguments(const char *exeName, int32_t argc, char *argv[]) } ap_free(&parser); - // A missing script is reported by main() after the support files and - // any game archives have been dealt with: running with no arguments - // is the documented way to install. + // A missing script is reported by main() after the support files have + // been dealt with: running with no arguments is the documented way to + // set up a fresh install. // Do the full screen options make sense? if (conf->fullScreen && conf->fullScreenWindow) { @@ -861,9 +791,10 @@ static void _resolveFiles(const char *exeName, ConfigT *conf) { const char *extension = NULL; char *temp = NULL; - // Exists? + // Exists? A packed game answers through its database. + vfsInit(conf->container, conf->dataDirBase, conf->dataDir); utilFixPathSeparators(&conf->scriptFile, false); - if (!utilFileExists(conf->scriptFile)) { + if (!vfsExists(conf->scriptFile)) { // Missing. Is a path? temp = NULL; if (utilPathExists(conf->scriptFile)) { @@ -884,7 +815,7 @@ static void _resolveFiles(const char *exeName, ConfigT *conf) { // Do we need to generate a video name? if (conf->videoFile) { utilFixPathSeparators(&conf->videoFile, false); - if (!utilFileExists(conf->videoFile)) { + if (!vfsExists(conf->videoFile)) { free(conf->videoFile); conf->videoFile = NULL; } @@ -900,7 +831,7 @@ static void _resolveFiles(const char *exeName, ConfigT *conf) { // If we still don't have one, try a framefile if (!conf->videoFile) { conf->videoFile = utilCreateString("%s.txt", temp); - if (!utilFileExists(conf->videoFile)) { + if (!vfsExists(conf->videoFile)) { free(conf->videoFile); conf->videoFile = NULL; } @@ -918,15 +849,12 @@ static void _resolveFiles(const char *exeName, ConfigT *conf) { } conf->isFrameFile = conf->disc && isFrameFileName(conf->videoFile); - if (conf->dataDir) { - // They provided a data directory. Append the game name. - conf->dataDirBase = conf->dataDir; - utilFixPathSeparators(&conf->dataDirBase, true); - conf->dataDir = createDataDir(conf->dataDirBase, conf->scriptFile); + if (conf->dataDirGiven || conf->container) { + // Under the base, in a directory named for the game. + conf->dataDir = createDataDirFor(conf); } else { // No data directory specified. Use the game folder. - conf->dataDirBase = utilCreateString(".%c", utilGetPathSeparator()); - conf->dataDir = utilGetUpToLastPathComponent(conf->scriptFile); + conf->dataDir = utilGetUpToLastPathComponent(conf->scriptFile); } if (!conf->dataDir) { _showUsage(exeName, "Unable to create data directory."); @@ -951,6 +879,24 @@ static void _showHeader(void) { } +// --pack, --unpack, and --patch: the option carries the source, the script argument the destination. +static bool _runTool(const ConfigT *conf) { + switch (conf->toolMode) { + case TOOL_PACK: + return packGame(conf->toolSource, conf->scriptFile); + + case TOOL_PATCH: + return packPatch(conf->toolSource, conf->scriptFile); + + case TOOL_UNPACK: + return packUnpack(conf->toolSource, conf->scriptFile); + + default: + return false; + } +} + + static void _showUsage(const char *name, const char *message) { int32_t x = 0; char *longForm = NULL; @@ -1057,148 +1003,6 @@ static void _unpackData(const char *name) { } -// Games cannot include forbidden extensions, Singe binaries, multiple folders, etc. -// Tools are like games but do not need a games.dat file. -// Patches can be pretty much anything except forbidden extensions. -static void _unpackGames(void) { - struct dirent *de = NULL; - DIR *dir = opendir("."); - struct stat fileStat; - int32_t x = 0; - int32_t count = 0; - PackageTypeE type = PACKAGE_COUNT; - - if (dir == NULL) { - utilDie("Could not open the current directory."); - } - - while ((de = readdir(dir)) != NULL) { - // Only regular files with a package extension are interesting. - if ((strcmp(de->d_name, ".") == 0) || (strcmp(de->d_name, "..") == 0)) { - continue; - } - if ((stat(de->d_name, &fileStat) != 0) || !S_ISREG(fileStat.st_mode)) { - continue; - } - type = PACKAGE_COUNT; - for (x = 0; x < PACKAGE_COUNT; x++) { - if (utilStricmp(utilGetFileExtension(de->d_name), _packageTypes[x]) == 0) { - type = (PackageTypeE)x; - break; - } - } - if (type == PACKAGE_COUNT) { - continue; - } - - _showHeader(); - count++; - if (_validateArchive(de->d_name, type)) { - utilSay(">>> Installing %s: %s", _packageTypes[type], de->d_name); - if (_extractArchive(de->d_name)) { - unlink(de->d_name); - } - } - } - - if (count > 0) { - utilNewline(); - } - - closedir(dir); -} - - -// Look through archive for things I've told people NOT to ship! -// https://github.com/libarchive/libarchive/wiki/Examples#user-content-List_contents_of_Archive_stored_in_File -static bool _validateArchive(const char *filename, PackageTypeE type) { - struct archive *a = NULL; - struct archive_entry *entry = NULL; - const char *path = NULL; - const char *name = NULL; - const char *extension = NULL; - const char *slash = NULL; - const char *typeName = _packageTypes[type]; - char *toplevel = NULL; - char *gamesDat = NULL; - int32_t x = 0; - bool ok = true; - bool hasGamesDat = false; - - a = _openArchive(filename); - if (a == NULL) { - return false; - } - - while (ok && (archive_read_next_header(a, &entry) == ARCHIVE_OK)) { - path = archive_entry_pathname(entry); - name = utilGetLastPathComponent(path); - extension = utilGetFileExtension(path); - - // Everything except a patch must live inside a single top level folder. - if (type != PACKAGE_PATCH) { - if (toplevel == NULL) { - slash = strchr(path, '/'); - if (slash == NULL) { - ok = false; - utilSay("!!! %s has files in root: %s", typeName, filename); - } else { - toplevel = utilStrndup(path, (size_t)(slash - path + 1)); - gamesDat = utilCreateString("%sgames.dat", toplevel); - } - } else { - if (!utilStartsWith(path, toplevel)) { - ok = false; - if (strchr(path, '/') == NULL) { - utilSay("!!! %s has files in root: %s", typeName, filename); - } else { - utilSay("!!! %s has multiple top level directories: %s", typeName, filename); - } - } - } - } - - if (ok) { - // Is this a forbidden file? - for (x = 0; ok && (_badFilenames[x] != NULL); x++) { - if (utilStricmp(name, _badFilenames[x]) == 0) { - ok = false; - utilSay("!!! %s has %s: %s", typeName, _badFilenames[x], filename); - } - } - // Is this a forbidden extension? - for (x = 0; ok && (_badExtensions[x] != NULL); x++) { - if (utilStricmp(extension, _badExtensions[x]) == 0) { - ok = false; - utilSay("!!! %s has %s file: %s", typeName, _badExtensions[x], filename); - } - } - // Not a patch, no extension, starts with 'singe' - could be unix binary. - if (ok && (type != PACKAGE_PATCH) && (strlen(extension) == 0) && utilStartsWith(name, "singe")) { - ok = false; - utilSay("!!! %s has singe file: %s", typeName, filename); - } - // Is this games.dat? - if (ok && (gamesDat != NULL) && (utilStricmp(path, gamesDat) == 0)) { - hasGamesDat = true; - } - } - archive_read_data_skip(a); - } - archive_read_free(a); - free(toplevel); - free(gamesDat); - - // If it's a game, did we get a games.dat? - if (ok && (type == PACKAGE_GAME) && !hasGamesDat) { - ok = false; - utilSay("!!! %s has no games.dat: %s", typeName, filename); - } - - return ok; -} - - ConfigT *cloneConf(const ConfigT *conf) { ConfigT *c = (ConfigT *)calloc(1, sizeof(ConfigT)); @@ -1209,6 +1013,8 @@ ConfigT *cloneConf(const ConfigT *conf) { // Copy everything, then give the clone its own strings. *c = *conf; c->scriptFile = _cloneString(conf->scriptFile); + c->container = _cloneString(conf->container); + c->toolSource = _cloneString(conf->toolSource); c->videoFile = _cloneString(conf->videoFile); c->dataDirBase = _cloneString(conf->dataDirBase); c->dataDir = _cloneString(conf->dataDir); @@ -1253,6 +1059,24 @@ char *createDataDir(const char *dataDirBase, const char *filename) { } +// The data directory follows the script's directory, or the database's name when the script sits at its root. +char *createDataDirFor(const ConfigT *conf) { + const char *base = NULL; + char *name = NULL; + char *path = NULL; + + if ((conf->container != NULL) && (strchr(conf->scriptFile, '/') == NULL) && (strchr(conf->scriptFile, '\\') == NULL)) { + base = utilGetLastPathComponent(conf->container); + name = utilCreateString("%.*s%c%s", (int)(strlen(base) - strlen(VFS_DATABASE_EXTENSION)), base, utilGetPathSeparator(), conf->scriptFile); + path = createDataDir(conf->dataDirBase, name); + free(name); + return path; + } + + return createDataDir(conf->dataDirBase, conf->scriptFile); +} + + void destroyConf(ConfigT **confPointer) { ConfigT *conf = *confPointer; @@ -1263,6 +1087,8 @@ void destroyConf(ConfigT **confPointer) { free(conf->dataDirBase); free(conf->videoFile); free(conf->scriptFile); + free(conf->container); + free(conf->toolSource); free(conf); *confPointer = NULL; } @@ -1329,10 +1155,19 @@ void queueScript(const ConfigT *conf) { int main(int argc, char *argv[]) { - const char *exeName = argv[0]; - char *temp = NULL; - ConfigT *conf = NULL; - QueueT *q = NULL; + const char *exeName = argv[0]; + char *temp = NULL; + ConfigT *conf = NULL; + ConfigT *replacement = NULL; + QueueT *q = NULL; + bool ok = false; + +#ifndef _WIN32 + signal(SIGSEGV, _crashHandler); + signal(SIGBUS, _crashHandler); + signal(SIGABRT, _crashHandler); + signal(SIGFPE, _crashHandler); +#endif // Options first so --help and --noconsole take effect before anything is written. conf = _parseArguments(exeName, argc, argv); @@ -1341,13 +1176,40 @@ int main(int argc, char *argv[]) { utilRedirectConsole(); _unpackData(exeName); - _unpackGames(); + + // -d names the base under which every game gets a data directory; without it the game folder serves. + if (conf->dataDir) { + conf->dataDirBase = conf->dataDir; + conf->dataDir = NULL; + conf->dataDirGiven = true; + utilFixPathSeparators(&conf->dataDirBase, true); + } else { + conf->dataDirBase = utilCreateString(".%c", utilGetPathSeparator()); + } + + // The packing tools need no window: run one and leave. + if (conf->toolMode != TOOL_NONE) { + if (!conf->scriptFile) { + _showUsage(exeName, "The packing tools need a second name after the options."); + } + ok = _runTool(conf); + destroyConf(&conf); + vfsQuit(); + return ok ? EXIT_SUCCESS : EXIT_FAILURE; + } // Nothing to run? Installing was the whole job. if (!conf->scriptFile) { _showUsage(exeName, "No script file specified."); } + // A game database on its own runs its first games.dat entry. + if (vfsIsDatabase(conf->scriptFile)) { + replacement = confFromDatabase(conf); + destroyConf(&conf); + conf = replacement; + } + // Queue initial script _resolveFiles(exeName, conf); queueScript(conf); @@ -1376,6 +1238,7 @@ int main(int argc, char *argv[]) { } _stopSDL(); + vfsQuit(); if (utilGetConsoleEnabled()) { utilWaitForKeyOnWindows(); diff --git a/src/main.h b/src/main.h index c06971cf2..da7390822 100644 --- a/src/main.h +++ b/src/main.h @@ -39,6 +39,7 @@ ConfigT *cloneConf(const ConfigT *conf); char *createDataDir(const char *dataDirBase, const char *filename); +char *createDataDirFor(const ConfigT *conf); void destroyConf(ConfigT **confPointer); bool isFrameFileName(const char *filename); bool parseSindenString(const char *sindenString, ConfigT *conf); diff --git a/src/pack.c b/src/pack.c new file mode 100644 index 000000000..f42d83db5 --- /dev/null +++ b/src/pack.c @@ -0,0 +1,609 @@ +/* + * Packer, unpacker, and patcher for single-file games. The database layout is described in vfs.c. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "sqlite3.h" + +#include "pack.h" +#include "singe.h" +#include "util.h" +#include "vfs.h" + + +#define PAGE_SIZE 4096 + + +typedef struct EntryS { + char *relative; // Forward slashes, author's case + char *full; // Filesystem path + int64_t size; + struct EntryS *next; +} EntryT; + +typedef struct WriterS { + sqlite3 *db; + sqlite3_stmt *assetStmt; + sqlite3_stmt *chunkStmt; + sqlite3_stmt *deleteChunkStmt; + int64_t chunkBytes; + int64_t files; + int64_t bytes; +} WriterT; + + +static const char *const _badFilenames[] = { "controls.dat", "Framework.singe", NULL }; +static const char *const _badExtensions[] = { "exe", "sh", "bat", "cmd", NULL }; +static const char *const _textExtensions[] = { "singe", "lua", "dat", "cfg", "txt", NULL }; + + +static bool _applyDatabase(WriterT *writer, const char *source); +static bool _applyDirectory(WriterT *writer, const char *directory, bool checkGame); +static bool _collect(const char *root, const char *relative, EntryT **list); +static bool _createTables(sqlite3 *db); +static void _entriesFree(EntryT *list); +static bool _exec(sqlite3 *db, const char *sql); +static bool _insertFile(WriterT *writer, const EntryT *entry); +static bool _isDirectory(const char *path); +static char *_keyFor(const char *relative); +static bool _scanEscapes(const EntryT *list); +static bool _writeMeta(sqlite3 *db, const char *key, const char *value); +static bool _writerClose(WriterT *writer, bool commit); +static bool _writerOpen(WriterT *writer, const char *database, bool create); + + +// Copies every asset row of a patch database into the open game, replacing what it names. +static bool _applyDatabase(WriterT *writer, const char *source) { + sqlite3_stmt *stmt = NULL; + char *sql = utilCreateString("ATTACH DATABASE '%s' AS patch", source); + int64_t chunk = 0; + bool ok = true; + + if (!_exec(writer->db, sql)) { + free(sql); + return false; + } + free(sql); + if (sqlite3_prepare_v2(writer->db, "SELECT value FROM patch.meta WHERE key = 'chunk'", -1, &stmt, NULL) == SQLITE_OK) { + if (sqlite3_step(stmt) == SQLITE_ROW) { + chunk = sqlite3_column_int64(stmt, 0); + } + sqlite3_finalize(stmt); + } + if (chunk != writer->chunkBytes) { + utilSay("!!! %s uses a different chunk size than the game.", source); + return false; + } + ok = ok && _exec(writer->db, "DELETE FROM main.chunks WHERE path IN (SELECT path FROM patch.assets)"); + ok = ok && _exec(writer->db, "INSERT OR REPLACE INTO main.assets (path, name, size, data) SELECT path, name, size, data FROM patch.assets"); + ok = ok && _exec(writer->db, "INSERT OR REPLACE INTO main.chunks (path, chunk, data) SELECT path, chunk, data FROM patch.chunks"); + if (ok && (sqlite3_prepare_v2(writer->db, "SELECT count(*) FROM patch.sqlite_master WHERE name = 'removed'", -1, &stmt, NULL) == SQLITE_OK)) { + if ((sqlite3_step(stmt) == SQLITE_ROW) && (sqlite3_column_int64(stmt, 0) > 0)) { + ok = ok && _exec(writer->db, "DELETE FROM main.chunks WHERE path IN (SELECT path FROM patch.removed)"); + ok = ok && _exec(writer->db, "DELETE FROM main.assets WHERE path IN (SELECT path FROM patch.removed)"); + } + sqlite3_finalize(stmt); + } + if (ok && (sqlite3_prepare_v2(writer->db, "SELECT count(*), coalesce(sum(size), 0) FROM patch.assets", -1, &stmt, NULL) == SQLITE_OK)) { + if (sqlite3_step(stmt) == SQLITE_ROW) { + writer->files = sqlite3_column_int64(stmt, 0); + writer->bytes = sqlite3_column_int64(stmt, 1); + } + sqlite3_finalize(stmt); + } + + return ok; +} + + +// Inserts every file below directory. checkGame enforces the rules a whole game must meet. +static bool _applyDirectory(WriterT *writer, const char *directory, bool checkGame) { + EntryT *list = NULL; + EntryT *entry = NULL; + char *gameDir = NULL; + char *reason = NULL; + const char *slash = NULL; + size_t length = 0; + bool ok = true; + + if (!_collect(directory, "", &list)) { + return false; + } + gameDir = strdup(utilGetLastPathComponent(directory)); + for (entry = list; ok && (entry != NULL); entry = entry->next) { + reason = packForbiddenReason(entry->relative, !checkGame); + if (reason != NULL) { + utilSay("!!! %s has %s: %s", directory, reason, entry->relative); + free(reason); + ok = false; + } + // A top level entry named like the game directory would make the own-directory prefix ambiguous. + if (ok && checkGame) { + slash = strchr(entry->relative, '/'); + length = slash ? (size_t)(slash - entry->relative) : strlen(entry->relative); + if ((length == strlen(gameDir)) && (strncasecmp(entry->relative, gameDir, length) == 0)) { + utilSay("!!! %s contains an entry named like the game directory (%s); rename one of them.", directory, gameDir); + ok = false; + } + } + } + if (ok && checkGame && !_scanEscapes(list)) { + ok = false; + } + for (entry = list; ok && (entry != NULL); entry = entry->next) { + ok = _insertFile(writer, entry); + } + free(gameDir); + _entriesFree(list); + + return ok; +} + + +// Recursive directory walk producing relative names with forward slashes. Stale index files are skipped. +static bool _collect(const char *root, const char *relative, EntryT **list) { + DIR *dir = NULL; + struct dirent *de = NULL; + struct stat info; + char *full = NULL; + char *child = NULL; + EntryT *entry = NULL; + bool ok = true; + + full = utilCreateString("%s%s%s", root, relative[0] ? "/" : "", relative); + dir = opendir(full); + if (dir == NULL) { + utilSay("!!! Unable to read directory %s", full); + free(full); + return false; + } + while (ok && ((de = readdir(dir)) != NULL)) { + if ((strcmp(de->d_name, ".") == 0) || (strcmp(de->d_name, "..") == 0)) { + continue; + } + child = utilCreateString("%s%s%s", relative, relative[0] ? "/" : "", de->d_name); + free(full); + full = utilCreateString("%s/%s", root, child); + if (stat(full, &info) != 0) { + utilSay("!!! Unable to stat %s", full); + ok = false; + } else if (S_ISDIR(info.st_mode)) { + ok = _collect(root, child, list); + } else if (S_ISREG(info.st_mode)) { + if (utilStricmp(utilGetFileExtension(de->d_name), "index") == 0) { + utilSay(">>> Skipping stale index %s", child); + } else { + entry = (EntryT *)calloc(1, sizeof(EntryT)); + entry->relative = strdup(child); + entry->full = strdup(full); + entry->size = (int64_t)info.st_size; + entry->next = *list; + *list = entry; + } + } + free(child); + } + closedir(dir); + free(full); + + return ok; +} + + +static bool _createTables(sqlite3 *db) { + bool ok = true; + + ok = ok && _exec(db, "CREATE TABLE meta (key TEXT PRIMARY KEY, value TEXT)"); + ok = ok && _exec(db, "CREATE TABLE assets (path TEXT PRIMARY KEY, name TEXT, size INTEGER, data BLOB)"); + ok = ok && _exec(db, "CREATE TABLE chunks (path TEXT, chunk INTEGER, data BLOB, PRIMARY KEY (path, chunk))"); + + return ok; +} + + +static void _entriesFree(EntryT *list) { + EntryT *next = NULL; + + while (list != NULL) { + next = list->next; + free(list->relative); + free(list->full); + free(list); + list = next; + } +} + + +static bool _exec(sqlite3 *db, const char *sql) { + char *error = NULL; + + if (sqlite3_exec(db, sql, NULL, NULL, &error) != SQLITE_OK) { + utilSay("!!! SQLite: %s", error); + sqlite3_free(error); + return false; + } + + return true; +} + + +// One file becomes one assets row, plus chunk rows when it is larger than the chunk size. +static bool _insertFile(WriterT *writer, const EntryT *entry) { + FILE *file = NULL; + uint8_t *buffer = NULL; + char *key = _keyFor(entry->relative); + size_t got = 0; + int64_t index = 0; + bool ok = true; + + file = fopen(entry->full, "rb"); + if (file == NULL) { + utilSay("!!! Unable to read %s", entry->full); + free(key); + return false; + } + buffer = (uint8_t *)malloc((size_t)writer->chunkBytes); + sqlite3_reset(writer->deleteChunkStmt); + sqlite3_bind_text(writer->deleteChunkStmt, 1, key, -1, SQLITE_STATIC); + sqlite3_step(writer->deleteChunkStmt); + sqlite3_reset(writer->assetStmt); + sqlite3_bind_text(writer->assetStmt, 1, key, -1, SQLITE_STATIC); + sqlite3_bind_text(writer->assetStmt, 2, entry->relative, -1, SQLITE_STATIC); + sqlite3_bind_int64(writer->assetStmt, 3, entry->size); + if (entry->size <= writer->chunkBytes) { + got = fread(buffer, 1, (size_t)entry->size, file); + sqlite3_bind_blob(writer->assetStmt, 4, buffer, (int)got, SQLITE_STATIC); + } else { + sqlite3_bind_null(writer->assetStmt, 4); + } + ok = (sqlite3_step(writer->assetStmt) == SQLITE_DONE); + sqlite3_reset(writer->assetStmt); + if (ok && (entry->size > writer->chunkBytes)) { + while (ok && ((got = fread(buffer, 1, (size_t)writer->chunkBytes, file)) > 0)) { + sqlite3_reset(writer->chunkStmt); + sqlite3_bind_text(writer->chunkStmt, 1, key, -1, SQLITE_STATIC); + sqlite3_bind_int64(writer->chunkStmt, 2, index); + sqlite3_bind_blob(writer->chunkStmt, 3, buffer, (int)got, SQLITE_STATIC); + ok = (sqlite3_step(writer->chunkStmt) == SQLITE_DONE); + sqlite3_reset(writer->chunkStmt); + index++; + } + } + if (!ok) { + utilSay("!!! SQLite: %s", sqlite3_errmsg(writer->db)); + } + writer->files++; + writer->bytes += entry->size; + fclose(file); + free(buffer); + free(key); + + return ok; +} + + +static bool _isDirectory(const char *path) { + struct stat info; + + return (stat(path, &info) == 0) && S_ISDIR(info.st_mode); +} + + +// The lookup key: lower case, forward slashes. +static char *_keyFor(const char *relative) { + char *key = strdup(relative); + char *p = NULL; + + for (p = key; *p != 0; p++) { + *p = (*p == '\\') ? '/' : (char)tolower((unsigned char)*p); + } + + return key; +} + + +// A packed game may only reach its own contents: ".." in a script or data file is refused, by line. +static bool _scanEscapes(const EntryT *list) { + const EntryT *entry = NULL; + const char *ext = NULL; + const char *offset = NULL; + char *data = NULL; + char *line = NULL; + size_t bytes = 0; + int32_t number = 0; + int32_t x = 0; + bool text = false; + bool ok = true; + + for (entry = list; entry != NULL; entry = entry->next) { + ext = utilGetFileExtension(entry->relative); + text = false; + for (x = 0; !text && (_textExtensions[x] != NULL); x++) { + text = (utilStricmp(ext, _textExtensions[x]) == 0); + } + if (!text) { + continue; + } + data = utilReadFile(entry->full, &bytes); + if (data == NULL) { + continue; + } + offset = data; + number = 0; + while ((line = utilReadLine(data, bytes, &offset)) != NULL) { + number++; + if ((strstr(line, "../") != NULL) || (strstr(line, "..\\") != NULL)) { + utilSay("!!! %s:%d reaches outside the game with \"..\"", entry->relative, number); + ok = false; + } + free(line); + } + free(data); + } + + return ok; +} + + +static bool _writeMeta(sqlite3 *db, const char *key, const char *value) { + sqlite3_stmt *stmt = NULL; + bool ok = false; + + if (sqlite3_prepare_v2(db, "INSERT OR REPLACE INTO meta (key, value) VALUES (?, ?)", -1, &stmt, NULL) == SQLITE_OK) { + sqlite3_bind_text(stmt, 1, key, -1, SQLITE_STATIC); + sqlite3_bind_text(stmt, 2, value, -1, SQLITE_STATIC); + ok = (sqlite3_step(stmt) == SQLITE_DONE); + } + sqlite3_finalize(stmt); + + return ok; +} + + +static bool _writerClose(WriterT *writer, bool commit) { + bool ok = true; + + if (writer->db == NULL) { + return false; + } + ok = _exec(writer->db, commit ? "COMMIT" : "ROLLBACK"); + sqlite3_finalize(writer->assetStmt); + sqlite3_finalize(writer->chunkStmt); + sqlite3_finalize(writer->deleteChunkStmt); + sqlite3_close(writer->db); + memset(writer, 0, sizeof(*writer)); + + return ok; +} + + +// Opens the database for writing inside one transaction; create replaces any existing file. +static bool _writerOpen(WriterT *writer, const char *database, bool create) { + sqlite3_stmt *stmt = NULL; + char *text = NULL; + bool ok = true; + + memset(writer, 0, sizeof(*writer)); + writer->chunkBytes = VFS_CHUNK_BYTES; + if (create) { + if (utilFileExists(database)) { + utilSay(">>> Replacing %s", database); + remove(database); + } + } else if (!utilFileExists(database)) { + utilSay("!!! %s does not exist.", database); + return false; + } + if (sqlite3_open_v2(database, &writer->db, SQLITE_OPEN_READWRITE | (create ? SQLITE_OPEN_CREATE : 0), NULL) != SQLITE_OK) { + utilSay("!!! Unable to open %s: %s", database, sqlite3_errmsg(writer->db)); + sqlite3_close(writer->db); + writer->db = NULL; + return false; + } + text = utilCreateString("PRAGMA page_size = %d", PAGE_SIZE); + ok = ok && _exec(writer->db, text); + free(text); + ok = ok && _exec(writer->db, "PRAGMA journal_mode = OFF"); + ok = ok && _exec(writer->db, "PRAGMA synchronous = OFF"); + if (ok && create) { + ok = _createTables(writer->db); + } + if (ok && !create) { + // An existing game must be one of ours, and its chunk size rules. + if ((sqlite3_prepare_v2(writer->db, "SELECT value FROM meta WHERE key = 'chunk'", -1, &stmt, NULL) != SQLITE_OK) || (sqlite3_step(stmt) != SQLITE_ROW)) { + utilSay("!!! %s is not a Singe game database.", database); + ok = false; + } else { + writer->chunkBytes = sqlite3_column_int64(stmt, 0); + } + sqlite3_finalize(stmt); + } + ok = ok && _exec(writer->db, "BEGIN"); + ok = ok && (sqlite3_prepare_v2(writer->db, "INSERT OR REPLACE INTO assets (path, name, size, data) VALUES (?, ?, ?, ?)", -1, &writer->assetStmt, NULL) == SQLITE_OK); + ok = ok && (sqlite3_prepare_v2(writer->db, "INSERT OR REPLACE INTO chunks (path, chunk, data) VALUES (?, ?, ?)", -1, &writer->chunkStmt, NULL) == SQLITE_OK); + ok = ok && (sqlite3_prepare_v2(writer->db, "DELETE FROM chunks WHERE path = ?", -1, &writer->deleteChunkStmt, NULL) == SQLITE_OK); + if (!ok) { + utilSay("!!! Unable to prepare %s: %s", database, sqlite3_errmsg(writer->db)); + sqlite3_finalize(writer->assetStmt); + sqlite3_finalize(writer->chunkStmt); + sqlite3_finalize(writer->deleteChunkStmt); + sqlite3_close(writer->db); + memset(writer, 0, sizeof(*writer)); + } + + return ok; +} + + +// Why a file may not ship in a game, as a new string, or NULL when it may. Shared with the archive installer. +char *packForbiddenReason(const char *path, bool isPatch) { + const char *name = utilGetLastPathComponent(path); + const char *extension = utilGetFileExtension(path); + int32_t x = 0; + + for (x = 0; _badFilenames[x] != NULL; x++) { + if (utilStricmp(name, _badFilenames[x]) == 0) { + return strdup(_badFilenames[x]); + } + } + for (x = 0; _badExtensions[x] != NULL; x++) { + if (utilStricmp(extension, _badExtensions[x]) == 0) { + return utilCreateString("%s file", _badExtensions[x]); + } + } + // No extension and starts with "singe": could be a unix binary. + if (!isPatch && (strlen(extension) == 0) && utilStartsWith(name, "singe")) { + return strdup("singe file"); + } + + return NULL; +} + + +// Packs a game directory into a new database. +bool packGame(const char *directory, const char *database) { + WriterT writer; + char *root = strdup(directory); + char *gamesDat = NULL; + char *chunk = NULL; + size_t length = strlen(root); + bool ok = true; + + while ((length > 1) && ((root[length - 1] == '/') || (root[length - 1] == '\\'))) { + root[--length] = 0; + } + if (!_isDirectory(root)) { + utilSay("!!! %s is not a directory.", root); + free(root); + return false; + } + gamesDat = utilCreateString("%s/games.dat", root); + if (!utilFileExists(gamesDat)) { + utilSay("!!! %s has no games.dat; a game database needs one at its root.", root); + free(gamesDat); + free(root); + return false; + } + free(gamesDat); + if (!_writerOpen(&writer, database, true)) { + free(root); + return false; + } + chunk = utilCreateString("%lld", (long long)writer.chunkBytes); + ok = ok && _writeMeta(writer.db, "version", "1"); + ok = ok && _writeMeta(writer.db, "gamedir", utilGetLastPathComponent(root)); + ok = ok && _writeMeta(writer.db, "chunk", chunk); + ok = ok && _writeMeta(writer.db, "packer", VERSION_STRING); + free(chunk); + ok = ok && _applyDirectory(&writer, root, true); + if (ok) { + utilSay(">>> Packed %lld files (%lld bytes) from %s into %s", (long long)writer.files, (long long)writer.bytes, root, database); + } + if (!_writerClose(&writer, ok)) { + ok = false; + } + if (!ok) { + remove(database); + } + free(root); + + return ok; +} + + +// Applies a patch, either a directory of replacement files or a patch database, in one transaction. +bool packPatch(const char *database, const char *source) { + WriterT writer; + bool ok = true; + + if (!_writerOpen(&writer, database, false)) { + return false; + } + if (_isDirectory(source)) { + ok = _applyDirectory(&writer, source, false); + } else if (utilFileExists(source)) { + ok = _applyDatabase(&writer, source); + } else { + utilSay("!!! %s does not exist.", source); + ok = false; + } + if (ok) { + utilSay(">>> Patched %s with %lld files (%lld bytes) from %s", database, (long long)writer.files, (long long)writer.bytes, source); + } + if (!_writerClose(&writer, ok)) { + ok = false; + } + + return ok; +} + + +// Writes every asset back out as files, in the author's spelling, under directory. +bool packUnpack(const char *database, const char *directory) { + sqlite3 *db = NULL; + sqlite3_stmt *assets = NULL; + sqlite3_stmt *chunks = NULL; + FILE *file = NULL; + char *path = NULL; + char *parent = NULL; + const char *name = NULL; + int64_t files = 0; + bool ok = true; + + if (!vfsIsDatabase(database)) { + utilSay("!!! %s is not a Singe game database.", database); + return false; + } + if (sqlite3_open_v2(database, &db, SQLITE_OPEN_READONLY, NULL) != SQLITE_OK) { + utilSay("!!! Unable to open %s: %s", database, sqlite3_errmsg(db)); + sqlite3_close(db); + return false; + } + ok = ok && (sqlite3_prepare_v2(db, "SELECT path, name, data FROM assets ORDER BY path", -1, &assets, NULL) == SQLITE_OK); + ok = ok && (sqlite3_prepare_v2(db, "SELECT data FROM chunks WHERE path = ? ORDER BY chunk", -1, &chunks, NULL) == SQLITE_OK); + while (ok && (sqlite3_step(assets) == SQLITE_ROW)) { + name = (const char *)sqlite3_column_text(assets, 1); + path = utilCreateString("%s/%s", directory, name ? name : (const char *)sqlite3_column_text(assets, 0)); + utilFixPathSeparators(&path, false); + parent = utilGetUpToLastPathComponent(path); + if (!utilMkDirP(parent, 0755)) { + utilSay("!!! Unable to create %s", parent); + ok = false; + } else { + file = fopen(path, "wb"); + if (file == NULL) { + utilSay("!!! Unable to write %s", path); + ok = false; + } else { + if (sqlite3_column_type(assets, 2) != SQLITE_NULL) { + fwrite(sqlite3_column_blob(assets, 2), 1, (size_t)sqlite3_column_bytes(assets, 2), file); + } else { + sqlite3_reset(chunks); + sqlite3_bind_text(chunks, 1, (const char *)sqlite3_column_text(assets, 0), -1, SQLITE_TRANSIENT); + while (sqlite3_step(chunks) == SQLITE_ROW) { + fwrite(sqlite3_column_blob(chunks, 0), 1, (size_t)sqlite3_column_bytes(chunks, 0), file); + } + } + fclose(file); + files++; + } + } + free(parent); + free(path); + } + sqlite3_finalize(assets); + sqlite3_finalize(chunks); + sqlite3_close(db); + if (ok) { + utilSay(">>> Unpacked %lld files from %s into %s", (long long)files, database, directory); + } + + return ok; +} diff --git a/src/pack.h b/src/pack.h new file mode 100644 index 000000000..4f0227367 --- /dev/null +++ b/src/pack.h @@ -0,0 +1,16 @@ +/* + * Packing games into, and out of, single-file SQLite databases. + */ + +#ifndef PACK_H +#define PACK_H + +#include + + +char *packForbiddenReason(const char *path, bool isPatch); +bool packGame(const char *directory, const char *database); +bool packPatch(const char *database, const char *source); +bool packUnpack(const char *database, const char *directory); + +#endif diff --git a/src/singe.c b/src/singe.c index 2c6b1dfd5..c85aff6c7 100644 --- a/src/singe.c +++ b/src/singe.c @@ -47,12 +47,15 @@ LUASOCKET_API int luaopen_socket_serial(lua_State *L); #endif // There is no header for rs232 binding. Make our own. int luaopen_luars232(lua_State *L); +// Nor for lsqlite3. +int luaopen_lsqlite3(lua_State *L); // There is no header for ssl.config binding. Make our own. LSEC_API int luaopen_ssl_config(lua_State *L); #include "main.h" #include "util.h" #include "frameFile.h" +#include "vfs.h" #include "videoPlayer.h" #include "singe.h" @@ -64,9 +67,6 @@ LSEC_API int luaopen_ssl_config(lua_State *L); #include "embedded.h" -#define INDEX_DISPLAY_START -1 -#define INDEX_DISPLAY_STOP -2 - // soundSetVolume/soundGetVolume use this legacy scale; the mixer uses MIX_MAX_VOLUME. #define AUDIO_MAX_VOLUME 63 #define MAX_MICE 4 @@ -100,6 +100,8 @@ LSEC_API int luaopen_ssl_config(lua_State *L); #define ANIMATION_MIN_DELAY_MS 10 // GIFs often carry a zero delay #define SCREENSHOT_MAX 10000 #define SOUND_QUEUE_SIZE 64 +#define MS_PER_SECOND_NUMBER 1000.0 +#define INPUT_GRACE_MS 1000 // Presses this soon after a script starts or focus arrives were held over from before #define EFFECT_TRACKS 16 // Sound effect "channels" scripts can play at once #define EFFECT_TAG "effects" #define HELD_KEYS_MAX 64 // Keys physically down at once @@ -112,13 +114,6 @@ LSEC_API int luaopen_ssl_config(lua_State *L); #define LOGO_FADE_STEP_MS 3 #define LOGO_HOLD_MS 750 -#define INDEX_SCREEN_WIDTH 1280 -#define INDEX_SCREEN_HEIGHT 720 -#define INDEX_RADIUS_FACTOR 0.3 -#define INDEX_UPDATE_MS 5 -#define INDEX_TEXT_OVERLAP 5 -#define INDEX_GLASS_X_FACTOR 0.15 -#define INDEX_GLASS_Y_FACTOR 0.1 // Decoded video frames are BGRA in memory; this is the matching alpha-less surface format. #if SDL_BYTEORDER == SDL_LIL_ENDIAN @@ -293,6 +288,7 @@ typedef struct GlobalS { bool keyboardState[SDL_SCANCODE_COUNT]; bool keySuppressed[SDL_SCANCODE_COUNT]; // Held before this script started; not a press for it bool buttonSuppressed[MAX_CONTROLLERS][CONTROLLER_BUTTON_COUNT]; + uint64_t inputGraceUntil; // Until then, new presses are treated as held over too int32_t keyboardLastDown; int32_t keyboardLastUp; int32_t frameFileHandle; @@ -349,6 +345,8 @@ static MIX_Track *_effectTracks[EFFECT_TRACKS]; static const LuaModuleT _luaModules[] = { // LuaFileSystem MODC("lfs", luaopen_lfs), + // SQLite for script data + MODC("sqlite3", luaopen_lsqlite3), // LuaSocket MODC("mime.core", luaopen_mime_core), MODC("socket.core", luaopen_socket_core), @@ -436,7 +434,7 @@ static SoundT *_argSound(lua_State *L, const char *method, int32_t index); static SpriteT *_argSprite(lua_State *L, const char *method, int32_t index); static const char *_argString(lua_State *L, const char *method, int32_t index); static VideoT *_argVideo(lua_State *L, const char *method, int32_t index); -static ConfigT *_buildConfFromTable(lua_State *L); +static ConfigT *_buildConfFromTable(lua_State *L, const ConfigT *base); static void _callLua(const char *func, const char *sig, ...); static int32_t _effectTrackFree(void); static void _effectStopped(void *userdata, MIX_Track *track); @@ -444,7 +442,6 @@ static int32_t _controllerSlot(SDL_JoystickID which); static bool _delayAndPump(uint32_t ms); static void _deliverKey(bool down, int32_t keysym, int32_t scancode); static void _discSeek(int64_t frame); -static void _doIndexDisplay(int32_t percent); static void _doLogos(void); static void _drawLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint32_t pixel); static void _drawPauseIndicator(const SDL_FRect *target); @@ -453,12 +450,18 @@ static void _fireMouseMoved(int32_t device, int32_t x, int32_t y, int32_ static void _fontDestroy(FontT *font); static void _freezeGame(bool freeze); static void _heldListUpdate(HeldKeyT *list, int32_t *count, bool down, int32_t keysym, int32_t scancode); +static void _installFileHooks(lua_State *L); static int32_t _loadAudioCalibration(void); static void _loadControlsFile(const char *path); static SDL_Surface *_loadEmbeddedPng(const unsigned char *data, unsigned int length); static SDL_Texture *_loadEmbeddedTexture(const unsigned char *data, unsigned int length, SDL_Surface **surface); static void _luaDie(lua_State *L, const char *method, const char *fmt, ...) __attribute__((format(printf, 3, 4))) __attribute__((noreturn)); +static int32_t _luaDofile(lua_State *L); +static int32_t _luaFileSearcher(lua_State *L); static char *_luaFormat(lua_State *L, const char *method, const char *fmt, va_list args); +static int32_t _luaIoHook(lua_State *L); +static int32_t _luaLoadfile(lua_State *L); +static int32_t _luaLoadFile(lua_State *L, const char *name, const char *mode); static int32_t _luaPanic(lua_State *L); static int32_t _luaSearcher(lua_State *L); static void _luaTrace(lua_State *L, const char *method, const char *fmt, ...) __attribute__((format(printf, 3, 4))); @@ -538,6 +541,7 @@ static int32_t apiMouseHowMany(lua_State *L); static int32_t apiMouseSetCaptured(lua_State *L); static int32_t apiMouseSetEnabled(lua_State *L); static int32_t apiMouseSetMode(lua_State *L); +static int32_t apiOsClock(lua_State *L); static int32_t apiOverlayBox(lua_State *L); static int32_t apiOverlayCircle(lua_State *L); static int32_t apiOverlayClear(lua_State *L); @@ -733,15 +737,17 @@ static VideoT *_argVideo(lua_State *L, const char *method, int32_t index) { // Builds a config for scriptExecute/scriptPush from the games.dat style table at stack index 1. -static ConfigT *_buildConfFromTable(lua_State *L) { +static ConfigT *_buildConfFromTable(lua_State *L, const ConfigT *base) { const char *confKey = NULL; const char *valueString = NULL; bool valueBoolean = false; int64_t valueNumber = 0; ConfigT *c = NULL; - // Start with current config, but every entry declares its own disc. - c = cloneConf(_global.conf); + // Start with the given config, but every entry declares its own disc and container. + c = cloneConf(base); + free(c->container); + c->container = NULL; c->disc = false; c->isFrameFile = false; free(c->videoFile); @@ -786,6 +792,13 @@ static ConfigT *_buildConfFromTable(lua_State *L) { free(c->scriptFile); c->scriptFile = strdup(valueString); utilFixPathSeparators(&c->scriptFile, false); + } else if (strcmp(confKey, "CONTAINER") == 0) { + if (valueString == NULL) { + utilDie("CONTAINER must be a string."); + } + free(c->container); + c->container = strdup(valueString); + utilFixPathSeparators(&c->container, false); } else if (strcmp(confKey, "VIDEO") == 0) { if (valueString == NULL) { utilDie("VIDEO must be a string."); @@ -837,7 +850,7 @@ static ConfigT *_buildConfFromTable(lua_State *L) { // Create new data dir location based on script location. free(c->dataDir); - c->dataDir = createDataDir(c->dataDirBase, c->scriptFile); + c->dataDir = createDataDirFor(c); if (!c->dataDir) { utilDie("Unable to create data directory for %s.", c->scriptFile); } @@ -1029,95 +1042,6 @@ static void _discSeek(int64_t frame) { } -// Indexing progress display. INDEX_DISPLAY_START sets up, 0..100 animates, INDEX_DISPLAY_STOP tears down. -static void _doIndexDisplay(int32_t percent) { - static int32_t oldW = 0; - static int32_t oldH = 0; - static int32_t radius = 0; - static int32_t angle = 0; - static uint64_t nextUpdate = 0; - static SDL_RendererLogicalPresentation oldMode = SDL_LOGICAL_PRESENTATION_DISABLED; - static SDL_Surface *surfDisc = NULL; - static SDL_Surface *surfGlass = NULL; - static SDL_Surface *surfIndex = NULL; - static SDL_Texture *texDisc = NULL; - static SDL_Texture *texGlass = NULL; - static SDL_Texture *texIndex = NULL; - SDL_FRect target; - int32_t vShift = 0; - - (void)percent; - - if (percent == INDEX_DISPLAY_START) { - SDL_GetRenderLogicalPresentation(_global.renderer, &oldW, &oldH, &oldMode); - SDL_SetRenderLogicalPresentation(_global.renderer, INDEX_SCREEN_WIDTH, INDEX_SCREEN_HEIGHT, SDL_LOGICAL_PRESENTATION_LETTERBOX); - texGlass = _loadEmbeddedTexture(magnifyingGlass_png, magnifyingGlass_png_len, &surfGlass); - texDisc = _loadEmbeddedTexture(laserDisc_png, laserDisc_png_len, &surfDisc); - texIndex = _loadEmbeddedTexture(indexing_png, indexing_png_len, &surfIndex); - radius = (int32_t)(surfDisc->w * INDEX_RADIUS_FACTOR); - nextUpdate = SDL_GetTicks() + INDEX_UPDATE_MS; - return; - } - - if (percent == INDEX_DISPLAY_STOP) { - SDL_DestroyTexture(texDisc); - SDL_DestroyTexture(texGlass); - SDL_DestroyTexture(texIndex); - SDL_DestroySurface(surfDisc); - SDL_DestroySurface(surfGlass); - SDL_DestroySurface(surfIndex); - texDisc = NULL; - texGlass = NULL; - texIndex = NULL; - surfDisc = NULL; - surfGlass = NULL; - surfIndex = NULL; - SDL_SetRenderLogicalPresentation(_global.renderer, oldW, oldH, oldMode); - SDL_SetRenderDrawColor(_global.renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); - SDL_RenderClear(_global.renderer); - SDL_RenderPresent(_global.renderer); - return; - } - - // Display animation. Indexing runs on the main thread, so keep the window's events flowing - // or the renderer never learns about a size change (fullscreen is applied asynchronously). - SDL_PumpEvents(); - SDL_SetRenderLogicalPresentation(_global.renderer, INDEX_SCREEN_WIDTH, INDEX_SCREEN_HEIGHT, SDL_LOGICAL_PRESENTATION_LETTERBOX); - SDL_SetRenderDrawColor(_global.renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); - SDL_RenderClear(_global.renderer); - - // Draw "Indexing" text - vShift = surfIndex->h - INDEX_TEXT_OVERLAP; - target.x = (float)((INDEX_SCREEN_WIDTH - surfIndex->w) / 2); - target.y = (float)(INDEX_SCREEN_HEIGHT - vShift); - target.w = (float)surfIndex->w; - target.h = (float)surfIndex->h; - SDL_RenderTexture(_global.renderer, texIndex, NULL, &target); - - // Draw laserdisc - target.x = (float)((INDEX_SCREEN_WIDTH - surfDisc->w) / 2); - target.y = (float)((INDEX_SCREEN_HEIGHT - surfDisc->h) / 2 - vShift); - target.w = (float)surfDisc->w; - target.h = (float)surfDisc->h; - SDL_RenderTexture(_global.renderer, texDisc, NULL, &target); - - // Draw magnifying glass circling the disc - target.x = (float)(int32_t)(surfDisc->w * INDEX_GLASS_X_FACTOR + (INDEX_SCREEN_WIDTH - surfGlass->w) / 2 + cos(angle * M_PI / (DEGREES_PER_CIRCLE / 2)) * radius); - target.y = (float)(int32_t)(surfDisc->h * INDEX_GLASS_Y_FACTOR + (INDEX_SCREEN_HEIGHT - surfGlass->h) / 2 - vShift + sin(angle * M_PI / (DEGREES_PER_CIRCLE / 2)) * radius); - target.w = (float)surfGlass->w; - target.h = (float)surfGlass->h; - SDL_RenderTexture(_global.renderer, texGlass, NULL, &target); - - // Update animation - if (SDL_GetTicks() > nextUpdate) { - angle = (angle + 1) % (int32_t)DEGREES_PER_CIRCLE; - nextUpdate = SDL_GetTicks() + INDEX_UPDATE_MS; - } - - SDL_RenderPresent(_global.renderer); -} - - // Splash screens: fade in the Kangaroo Punch logo, cross fade to the Singe logo, fade out. static void _doLogos(void) { int32_t i = 0; @@ -1356,6 +1280,32 @@ static void _heldListUpdate(HeldKeyT *list, int32_t *count, bool down, int32_t k } +// Replaces dofile, loadfile, and the io functions that take a file name with versions that resolve +// the name through the vfs. Each closure keeps the original as its first upvalue. +static void _installFileHooks(lua_State *L) { + static const struct { + const char *name; + int32_t mode; // 0 read, 1 io.open (mode string decides), 2 write + } ioHooks[] = { { "input", 0 }, { "lines", 0 }, { "open", 1 }, { "output", 2 } }; + size_t i = 0; + + lua_getglobal(L, "dofile"); + lua_pushcclosure(L, _luaDofile, 1); + lua_setglobal(L, "dofile"); + lua_getglobal(L, "loadfile"); + lua_pushcclosure(L, _luaLoadfile, 1); + lua_setglobal(L, "loadfile"); + lua_getglobal(L, "io"); + for (i = 0; i < sizeof(ioHooks) / sizeof(ioHooks[0]); i++) { + lua_getfield(L, -1, ioHooks[i].name); + lua_pushinteger(L, ioHooks[i].mode); + lua_pushcclosure(L, _luaIoHook, 2); + lua_setfield(L, -2, ioHooks[i].name); + } + lua_pop(L, 1); +} + + // The per-machine audio delay lives beside the data directories, since it is not a property of any game. static int32_t _loadAudioCalibration(void) { char *path = utilCreateString("%s%s", _global.conf->dataDirBase, AUDIO_CALIBRATION_FILE); @@ -1380,9 +1330,9 @@ static int32_t _loadAudioCalibration(void) { // Runs a controls.cfg if it exists. static void _loadControlsFile(const char *path) { - if (utilFileExists(path)) { + if (vfsExists(path)) { _progTrace("Loading %s", path); - if (luaL_dofile(_global.luaContext, path)) { + if (_luaLoadFile(_global.luaContext, path, NULL) || lua_pcall(_global.luaContext, 0, 0, 0)) { utilDie("%s", lua_tostring(_global.luaContext, -1)); } } @@ -1431,6 +1381,73 @@ static void _luaDie(lua_State *L, const char *method, const char *fmt, ...) { // Formats "line:method: message" for tracing and errors. Caller frees. +// dofile(name) through the vfs; without a name the original reads stdin. +static int32_t _luaDofile(lua_State *L) { + const char *name = luaL_optstring(L, 1, NULL); + + if (name == NULL) { + lua_pushvalue(L, lua_upvalueindex(1)); + lua_insert(L, 1); + lua_call(L, lua_gettop(L) - 1, LUA_MULTRET); + return lua_gettop(L); + } + lua_settop(L, 1); + if (_luaLoadFile(L, name, NULL) != LUA_OK) { + return lua_error(L); + } + lua_call(L, 0, LUA_MULTRET); + + return lua_gettop(L) - 1; +} + + +// require() of a game's own module: name.lua, name/init.lua, or name.singe under the script's +// directory, then relative to the game root. +static int32_t _luaFileSearcher(lua_State *L) { + static const char *const patterns[] = { "%s%s.lua", "%s%s/init.lua", "%s%s.singe", NULL }; + char *module = strdup(lua_tostring(L, 1)); + char *scriptDir = utilGetUpToLastPathComponent(_global.conf->scriptFile); + const char *prefixes[2]; + char *name = NULL; + char *p = NULL; + int32_t x = 0; + int32_t y = 0; + + prefixes[0] = scriptDir; + prefixes[1] = ""; + for (p = module; *p != 0; p++) { + if (*p == '.') { + *p = '/'; + } + } + for (y = 0; y < 2; y++) { + for (x = 0; patterns[x] != NULL; x++) { + name = utilCreateString(patterns[x], prefixes[y], module); + if (vfsExists(name)) { + if (_luaLoadFile(L, name, NULL) != LUA_OK) { + lua_pushfstring(L, "error loading module '%s' from file '%s':\n\t%s", lua_tostring(L, 1), name, lua_tostring(L, -1)); + free(name); + free(module); + free(scriptDir); + return lua_error(L); + } + lua_pushstring(L, name); + free(name); + free(module); + free(scriptDir); + return 2; + } + free(name); + } + } + lua_pushfstring(L, "\n\tno file '%s%s.lua' in the game", scriptDir, module); + free(module); + free(scriptDir); + + return 1; +} + + static char *_luaFormat(lua_State *L, const char *method, const char *fmt, va_list args) { lua_Debug ar; int32_t line = 0; @@ -1455,6 +1472,78 @@ static char *_luaFormat(lua_State *L, const char *method, const char *fmt, va_li // Lua panic handler: something went wrong outside a protected call. +// io.open and friends with a name resolved through the vfs. Upvalues: the original, and how the name is used. +static int32_t _luaIoHook(lua_State *L) { + int32_t mode = (int32_t)lua_tointeger(L, lua_upvalueindex(2)); + const char *modeString = NULL; + char *path = NULL; + bool writing = (mode == 2); + int32_t top = lua_gettop(L); + + if (lua_type(L, 1) == LUA_TSTRING) { + if (mode == 1) { + modeString = luaL_optstring(L, 2, "r"); + writing = (strpbrk(modeString, "wa+") != NULL); + } + path = vfsFilePath(lua_tostring(L, 1), writing); + lua_pushstring(L, path); + lua_replace(L, 1); + free(path); + } + lua_pushvalue(L, lua_upvalueindex(1)); + lua_insert(L, 1); + lua_call(L, top, LUA_MULTRET); + + return lua_gettop(L); +} + + +// loadfile(name, mode, env) through the vfs; without a name the original reads stdin. +static int32_t _luaLoadfile(lua_State *L) { + const char *name = luaL_optstring(L, 1, NULL); + const char *mode = luaL_optstring(L, 2, NULL); + + if (name == NULL) { + lua_pushvalue(L, lua_upvalueindex(1)); + lua_insert(L, 1); + lua_call(L, lua_gettop(L) - 1, LUA_MULTRET); + return lua_gettop(L); + } + if (_luaLoadFile(L, name, mode) != LUA_OK) { + lua_pushnil(L); + lua_insert(L, -2); + return 2; + } + if (!lua_isnone(L, 3)) { + lua_pushvalue(L, 3); + if (lua_setupvalue(L, -2, 1) == NULL) { + lua_pop(L, 1); + } + } + + return 1; +} + + +// Loads a chunk from the vfs, leaving the function or an error message on the stack. Returns the Lua status. +static int32_t _luaLoadFile(lua_State *L, const char *name, const char *mode) { + char *data = NULL; + char *chunkName = NULL; + size_t bytes = 0; + int32_t status = LUA_ERRFILE; + + data = vfsRead(name, &bytes); + if (data == NULL) { + lua_pushfstring(L, "cannot open %s", name); + return status; + } + chunkName = utilCreateString("@%s", name); + status = luaL_loadbufferx(L, data, bytes, chunkName, mode); + free(chunkName); + free(data); + + return status; +} static int32_t _luaPanic(lua_State *L) { lua_Debug ar; int32_t level = 0; @@ -1475,6 +1564,8 @@ static int32_t _luaPanic(lua_State *L) { // package.searchers entry serving the embedded Lua modules. // https://leiradel.github.io/2020/03/01/Embedding-Lua-Modules.html + + static int32_t _luaSearcher(lua_State *L) { const char *modname = lua_tostring(L, 1); size_t i = 0; @@ -1937,18 +2028,30 @@ static void _startLuaContext(lua_State *L) { // Register the standard libraries luaL_openlibs(L); + // Games use os.clock() as a wall clock for debounces and timers, and it is processor time: with + // the GPU decoding video the engine mostly sleeps, so those timers crawl. Give them what they meant. + lua_getglobal(L, "os"); + lua_pushcfunction(L, apiOsClock); + lua_setfield(L, -2, "clock"); + lua_pop(L, 1); + + // Every file a script names goes through the vfs. + _installFileHooks(L); + _pushConstants(L); - // Put our searcher at the front of package.searchers. + // Put our searchers at the front of package.searchers: embedded modules, then game files. lua_getglobal(L, "package"); lua_getfield(L, -1, "searchers"); length = lua_rawlen(L, -1); - for (i = length + 1; i > 1; i--) { - lua_rawgeti(L, -2, (lua_Integer)(i - 1)); + for (i = length + 2; i > 2; i--) { + lua_rawgeti(L, -2, (lua_Integer)(i - 2)); lua_rawseti(L, -2, (lua_Integer)i); } lua_pushcfunction(L, _luaSearcher); lua_rawseti(L, -2, 1); + lua_pushcfunction(L, _luaFileSearcher); + lua_rawseti(L, -2, 2); lua_pop(L, 2); } @@ -1979,6 +2082,10 @@ static void _suppressHeldInput(void) { int32_t b = 0; const bool *state = SDL_GetKeyboardState(&count); + // SDL may not know about a held key or button yet (gamepads are polled on their own thread, and + // X11 re-reports keys after the focus event), so presses that arrive soon after count as held too. + _global.inputGraceUntil = SDL_GetTicks() + INPUT_GRACE_MS; + for (x = 0; x < SDL_SCANCODE_COUNT; x++) { _global.keySuppressed[x] = (x < count) && state[x]; } @@ -2534,7 +2641,7 @@ static int32_t apiFontLoad(lua_State *L) { if (!font) { _luaDie(L, "fontLoad", "Unable to allocate new font."); } - font->font = TTF_OpenFont(name, (float)points); + font->font = TTF_OpenFontIO(vfsOpenIO(name), true, (float)points); if (!font->font) { _luaDie(L, "fontLoad", "%s", SDL_GetError()); } @@ -2771,6 +2878,14 @@ static int32_t apiMouseSetMode(lua_State *L) { } +// seconds = os.clock() Replaces Lua's processor-time clock with wall time since the engine started. +static int32_t apiOsClock(lua_State *L) { + lua_pushnumber(L, (lua_Number)SDL_GetTicks() / MS_PER_SECOND_NUMBER); + + return 1; +} + + // overlayBox(x1, y1, x2, y2) Outline only. static int32_t apiOverlayBox(lua_State *L) { int32_t x1 = 0; @@ -3077,7 +3192,7 @@ static int32_t apiScriptExecute(lua_State *L) { if (!lua_istable(L, 1)) { _luaDie(L, "scriptExecute", "Argument 1 must be a table."); } - conf = _buildConfFromTable(L); + conf = _buildConfFromTable(L, _global.conf); queueScript(conf); destroyConf(&conf); _global.running = false; @@ -3095,7 +3210,7 @@ static int32_t apiScriptPush(lua_State *L) { if (!lua_istable(L, 1)) { _luaDie(L, "scriptPush", "Argument 1 must be a table."); } - conf = _buildConfFromTable(L); + conf = _buildConfFromTable(L, _global.conf); queueScript(conf); destroyConf(&conf); queueScript(_global.conf); @@ -3353,7 +3468,7 @@ static int32_t apiSoundLoad(lua_State *L) { if (!sound) { _luaDie(L, "soundLoad", "Unable to allocate new sound."); } - sound->audio = MIX_LoadAudio(videoGetMixer(), name, true); + sound->audio = MIX_LoadAudio_IO(videoGetMixer(), vfsOpenIO(name), true, true); if (!sound->audio) { _luaDie(L, "soundLoad", "%s", SDL_GetError()); } @@ -3608,9 +3723,10 @@ static int32_t apiSpriteIsPlaying(lua_State *L) { // id = spriteLoad(filename) Animated GIF and WEBP files load as animations. static int32_t apiSpriteLoad(lua_State *L) { - const char *name = NULL; - SpriteT *sprite = NULL; - int32_t x = 0; + const char *name = NULL; + SpriteT *sprite = NULL; + SDL_IOStream *io = NULL; + int32_t x = 0; _argCheck(L, "spriteLoad", 1, 1); name = _argString(L, "spriteLoad", 1); @@ -3619,7 +3735,11 @@ static int32_t apiSpriteLoad(lua_State *L) { _luaDie(L, "spriteLoad", "Unable to allocate new sprite."); } // Try to load requested file as an animation first - sprite->animation = IMG_LoadAnimation(name); + io = vfsOpenIO(name); + if (io == NULL) { + _luaDie(L, "spriteLoad", "%s", SDL_GetError()); + } + sprite->animation = IMG_LoadAnimation_IO(io, false); if ((sprite->animation != NULL) && (sprite->animation->count < 2)) { // Only one frame - keep it as a still image. sprite->originalSurface = _surfaceCopy(sprite->animation->frames[0]); @@ -3634,10 +3754,12 @@ static int32_t apiSpriteLoad(lua_State *L) { } sprite->originalSurface = sprite->animation->frames[0]; } else { - sprite->originalSurface = IMG_Load(name); + SDL_SeekIO(io, 0, SDL_IO_SEEK_SET); + sprite->originalSurface = IMG_Load_IO(io, false); _surfaceUnpack(&sprite->originalSurface); } } + SDL_CloseIO(io); if (!sprite->originalSurface) { _luaDie(L, "spriteLoad", "%s", SDL_GetError()); } @@ -4303,6 +4425,44 @@ static int32_t apiVldpSetVerbose(lua_State *L) { // ===== Engine entry point ===== +// A game database named on the command line runs the first entry of its games.dat. +ConfigT *confFromDatabase(const ConfigT *conf) { + lua_State *L = luaL_newstate(); + ConfigT *base = cloneConf(conf); + ConfigT *result = NULL; + + base->container = strdup(conf->scriptFile); + free(base->scriptFile); + base->scriptFile = NULL; + vfsInit(base->container, base->dataDirBase, NULL); + luaL_openlibs(L); + if ((_luaLoadFile(L, "games.dat", NULL) != LUA_OK) || (lua_pcall(L, 0, 0, 0) != LUA_OK)) { + utilDie("%s: %s", base->container, lua_tostring(L, -1)); + } + lua_getglobal(L, "GAMES"); + if (!lua_istable(L, -1) || (lua_rawgeti(L, -1, 1) != LUA_TTABLE)) { + utilDie("%s: games.dat defines no GAMES entries.", base->container); + } + lua_replace(L, 1); + lua_settop(L, 1); + // --disc on the command line stands in for a DISC = true the entry forgot. + if (conf->disc) { + lua_pushboolean(L, true); + lua_setfield(L, 1, "DISC"); + } + result = _buildConfFromTable(L, base); + if (result->scriptFile == NULL) { + utilDie("%s: the first games.dat entry has no SCRIPT.", base->container); + } + free(result->container); + result->container = strdup(base->container); + lua_close(L); + destroyConf(&base); + + return result; +} + + void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) { int32_t x = 0; int32_t y = 0; @@ -4362,6 +4522,7 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) { // Local copy of config _global.conf = cloneConf(conf); + vfsInit(_global.conf->container, _global.conf->dataDirBase, _global.conf->dataDir); videoSetAudioDelay(_global.conf->audioDelayMs); videoSetAudioCalibration(_loadAudioCalibration()); utilTrace("Audio delay: device queue %d ms, calibration %d ms, game %d ms", videoGetAudioLatency(), videoGetAudioCalibration(), videoGetAudioDelay()); @@ -4584,8 +4745,6 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) { // Open main video file, if this is a laserdisc game. Otherwise the canvas is the world. if (_global.conf->disc) { _progTrace("Opening main video file"); - _doIndexDisplay(INDEX_DISPLAY_START); - videoSetIndexCallback(_doIndexDisplay); if (_global.conf->isFrameFile) { _global.frameFileHandle = frameFileLoad(_global.conf->videoFile, _global.conf->dataDir, _global.renderer, _global.conf->showCalculated); frameFileSeek(_global.frameFileHandle, 0, &_global.videoHandle, &thisFrame); // Fills in _global.videoHandle @@ -4593,8 +4752,6 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) { _global.videoHandle = videoLoad(_global.conf->videoFile, NULL, _global.conf->dataDir, _global.renderer, false); } videoSetVolume(_global.videoHandle, _global.conf->volumeVldp, _global.conf->volumeVldp); - videoSetIndexCallback(NULL); - _doIndexDisplay(INDEX_DISPLAY_STOP); _global.canvasWidth = videoGetWidth(_global.videoHandle); _global.canvasHeight = videoGetHeight(_global.videoHandle); } else { @@ -4790,7 +4947,7 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) { // Start script _progTrace("Running %s", _global.conf->scriptFile); lua_pushcfunction(_global.luaContext, _luaTraceback); - if (luaL_loadfile(_global.luaContext, _global.conf->scriptFile) || lua_pcall(_global.luaContext, 0, 0, -2)) { + if (_luaLoadFile(_global.luaContext, _global.conf->scriptFile, NULL) || lua_pcall(_global.luaContext, 0, 0, -2)) { utilDie("Error running script: %s", lua_tostring(_global.luaContext, -1)); } lua_settop(_global.luaContext, 0); @@ -4834,12 +4991,17 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) { if (slot < 0) { break; } - if ((event.gbutton.button < CONTROLLER_BUTTON_COUNT) && _global.buttonSuppressed[slot][event.gbutton.button]) { - // Held since before this script: swallow it, and its release. - if (event.type == SDL_EVENT_GAMEPAD_BUTTON_UP) { - _global.buttonSuppressed[slot][event.gbutton.button] = false; + if (event.gbutton.button < CONTROLLER_BUTTON_COUNT) { + if ((event.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN) && (SDL_GetTicks() < _global.inputGraceUntil)) { + _global.buttonSuppressed[slot][event.gbutton.button] = true; + } + if (_global.buttonSuppressed[slot][event.gbutton.button]) { + // Held since before this script: swallow it, and its release. + if (event.type == SDL_EVENT_GAMEPAD_BUTTON_UP) { + _global.buttonSuppressed[slot][event.gbutton.button] = false; + } + break; } - break; } code = CODE_GAMEPAD_BASE + slot * CODE_GAMEPAD_STRIDE + CODE_GAMEPAD_BUTTON_OFFSET + event.gbutton.button; _processKey(event.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN, 0, code); @@ -4856,12 +5018,17 @@ void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf) { if (event.key.repeat && (_global.keyboardMode == KEYBOARD_NORMAL)) { break; } - if ((event.key.scancode < SDL_SCANCODE_COUNT) && _global.keySuppressed[event.key.scancode]) { - // Held since before this script: swallow it, and its release. - if (event.type == SDL_EVENT_KEY_UP) { - _global.keySuppressed[event.key.scancode] = false; + if (event.key.scancode < SDL_SCANCODE_COUNT) { + if ((event.type == SDL_EVENT_KEY_DOWN) && (SDL_GetTicks() < _global.inputGraceUntil)) { + _global.keySuppressed[event.key.scancode] = true; + } + if (_global.keySuppressed[event.key.scancode]) { + // Held since before this script: swallow it, and its release. + if (event.type == SDL_EVENT_KEY_UP) { + _global.keySuppressed[event.key.scancode] = false; + } + break; } - break; } _processKey(event.type == SDL_EVENT_KEY_DOWN, event.key.key, event.key.scancode); break; diff --git a/src/singe.h b/src/singe.h index ddf8593ae..411227818 100644 --- a/src/singe.h +++ b/src/singe.h @@ -25,7 +25,7 @@ #define SINGE_H -#include +#include #include "common.h" #include "generated/version.h" @@ -35,6 +35,13 @@ // Number of --sindengun arguments selects the border style. +typedef enum ToolModeE { + TOOL_NONE = 0, + TOOL_PACK, + TOOL_PATCH, + TOOL_UNPACK +} ToolModeE; + typedef enum SindenModeE { SINDEN_WHITE = 1, SINDEN_WHITE_BLACK = 2, @@ -47,6 +54,10 @@ typedef enum SindenModeE { typedef struct ConfigS { char *videoFile; char *scriptFile; + char *container; // Game database holding the script, NULL for a loose game + char *toolSource; // Argument of --pack, --unpack, or --patch + ToolModeE toolMode; + bool dataDirGiven; // -d was on the command line char *dataDir; char *dataDirBase; bool resolutionWasCalculated; @@ -64,6 +75,7 @@ typedef struct ConfigS { bool scriptTracing; bool legacySpriteArgs; bool disc; // Play a laserdisc video; otherwise the canvas is the world + bool softwareVideo; // Skip the platform's hardware decoder int32_t bestRatioIndex; int32_t volumeVldp; int32_t volumeNonVldp; @@ -79,7 +91,8 @@ typedef struct ConfigS { } ConfigT; -void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf); +ConfigT *confFromDatabase(const ConfigT *conf); +void singe(SDL_Window *window, SDL_Renderer *renderer, ConfigT *conf); #endif // SINGE_H diff --git a/src/vfs.c b/src/vfs.c new file mode 100644 index 000000000..877b90c43 --- /dev/null +++ b/src/vfs.c @@ -0,0 +1,772 @@ +/* + * Singe virtual filesystem. See vfs.h for the lookup rules. + * + * Database layout (format version 1): + * meta(key TEXT PRIMARY KEY, value TEXT) version, gamedir, chunk, packer + * assets(path TEXT PRIMARY KEY, name TEXT, size INTEGER, data BLOB) + * chunks(path TEXT, chunk INTEGER, data BLOB, PRIMARY KEY(path, chunk)) + * path is the normalised key (lower case, forward slashes); name keeps the + * author's spelling for unpacking. Files larger than meta.chunk live in + * chunks with assets.data NULL. + */ + +#include +#include +#include +#include +#include +#include + +#include "sqlite3.h" + +#include "util.h" +#include "vfs.h" + + +#ifdef _WIN32 +#define fileSeek _fseeki64 +#define fileTell _ftelli64 +#else +#define fileSeek fseeko +#define fileTell ftello +#endif + +#define CACHE_DIRECTORY "cache" +#define ENGINE_DIRECTORY "Singe" +#define OVERLAY_DIRECTORY "files" +#define META_CHUNK "chunk" +#define META_GAMEDIR "gamedir" +#define META_VERSION "version" + + +typedef struct DatabaseS { + char *path; // Database file as named by the caller + char *loose; // Sibling directory holding loose overrides, trailing separator + char *overlay; // Copy-on-write directory under the data directory, trailing separator + char *cache; // Where read-only io opens of packed assets are unpacked to; never searched + char *gameDir; // Lower case own-directory prefix the packer recorded, or NULL + int64_t chunkBytes; + sqlite3 *db; + sqlite3_stmt *assetStmt; // size, data by path + sqlite3_stmt *chunkStmt; // data by path and chunk number + struct DatabaseS *next; +} DatabaseT; + +// Where a name lands. A NULL database means the plain filesystem path. +typedef struct TargetS { + DatabaseT *db; + char *path; // Filesystem path, or the loose override candidate for a packed name + char *key; // Normalised key inside the database + char *overlay; // Overlay path for the key + char *cache; // Cache path for the key +} TargetT; + +struct VfsStreamS { + FILE *file; // Filesystem-backed stream, or NULL + DatabaseT *db; + char *key; + int64_t size; + int64_t position; + int64_t chunkIndex; // Chunk held in buffer, -1 for none + int64_t chunkLength; + uint8_t *buffer; + bool whole; // buffer holds the entire asset +}; + + +static bool _assetExists(DatabaseT *db, const char *key); +static bool _assetSize(DatabaseT *db, const char *key, int64_t *size); +static DatabaseT *_databaseOpen(const char *path); +static bool _databaseReadMeta(DatabaseT *db, const char *key, char **value); +static bool _fileModified(const char *path, int64_t *size, int64_t *modified); +static bool _isAbsolute(const char *name); +static bool _isEngineName(const char *name); +static char *_normalise(const char *name); +static char *_overlayFor(const char *dataDirBase, const char *dataDir, const char *databasePath, bool isContainer, const char *directory); +static uint8_t *_readAsset(DatabaseT *db, const char *key, size_t *bytes, bool sdlMemory); +static bool _readChunk(DatabaseT *db, const char *key, int64_t index, uint8_t *buffer, int64_t *length); +static bool _resolve(const char *name, TargetT *target); +static void _targetFree(TargetT *target); +static bool _writeFile(const char *path, const uint8_t *data, size_t bytes); + + +static DatabaseT *_databases = NULL; +static DatabaseT *_container = NULL; +static char *_dataDirBase = NULL; +static char *_dataDir = NULL; + + +static bool _assetExists(DatabaseT *db, const char *key) { + int64_t size = 0; + + return _assetSize(db, key, &size); +} + + +static bool _assetSize(DatabaseT *db, const char *key, int64_t *size) { + bool found = false; + + sqlite3_reset(db->assetStmt); + sqlite3_bind_text(db->assetStmt, 1, key, -1, SQLITE_STATIC); + if (sqlite3_step(db->assetStmt) == SQLITE_ROW) { + *size = sqlite3_column_int64(db->assetStmt, 0); + found = true; + } + sqlite3_reset(db->assetStmt); + + return found; +} + + +// Opens a game database read only, or returns the cached handle. NULL when the file is not one of ours. +static DatabaseT *_databaseOpen(const char *path) { + DatabaseT *db = NULL; + char *uri = NULL; + char *value = NULL; + char *encoded = NULL; + size_t i = 0; + size_t o = 0; + int64_t version = 0; + + for (db = _databases; db != NULL; db = db->next) { + if (strcmp(db->path, path) == 0) { + return db; + } + } + + // Percent-encode the three characters a URI would misread. + encoded = (char *)calloc(strlen(path) * 3 + 1, 1); + for (i = 0; path[i] != 0; i++) { + if ((path[i] == '?') || (path[i] == '#') || (path[i] == '%')) { + sprintf(encoded + o, "%%%02X", (unsigned char)path[i]); + o += 3; + } else { + encoded[o++] = path[i]; + } + } + uri = utilCreateString("file:%s?immutable=1", encoded); + free(encoded); + + db = (DatabaseT *)calloc(1, sizeof(DatabaseT)); + db->path = strdup(path); + if (sqlite3_open_v2(uri, &db->db, SQLITE_OPEN_READONLY | SQLITE_OPEN_URI, NULL) != SQLITE_OK) { + free(uri); + sqlite3_close(db->db); + free(db->path); + free(db); + return NULL; + } + free(uri); + if (!_databaseReadMeta(db, META_VERSION, &value)) { + sqlite3_close(db->db); + free(db->path); + free(db); + return NULL; + } + version = strtoll(value, NULL, 10); + free(value); + if (version > VFS_FORMAT_VERSION) { + utilDie("%s is a format %lld game database; this Singe understands up to format %d.", path, (long long)version, VFS_FORMAT_VERSION); + } + if (sqlite3_prepare_v2(db->db, "SELECT size, data FROM assets WHERE path = ?", -1, &db->assetStmt, NULL) != SQLITE_OK) { + utilDie("%s has no assets table: %s", path, sqlite3_errmsg(db->db)); + } + if (sqlite3_prepare_v2(db->db, "SELECT data FROM chunks WHERE path = ? AND chunk = ?", -1, &db->chunkStmt, NULL) != SQLITE_OK) { + utilDie("%s has no chunks table: %s", path, sqlite3_errmsg(db->db)); + } + db->chunkBytes = VFS_CHUNK_BYTES; + if (_databaseReadMeta(db, META_CHUNK, &value)) { + db->chunkBytes = strtoll(value, NULL, 10); + free(value); + } + if (_databaseReadMeta(db, META_GAMEDIR, &value)) { + db->gameDir = _normalise(value); + free(value); + } + + // Loose overrides live in a directory named like the database without its extension. + db->loose = utilCreateString("%.*s%c", (int)(strlen(path) - strlen(VFS_DATABASE_EXTENSION)), path, utilGetPathSeparator()); + db->next = _databases; + _databases = db; + + return db; +} + + +static bool _databaseReadMeta(DatabaseT *db, const char *key, char **value) { + sqlite3_stmt *stmt = NULL; + bool found = false; + + *value = NULL; + if (sqlite3_prepare_v2(db->db, "SELECT value FROM meta WHERE key = ?", -1, &stmt, NULL) != SQLITE_OK) { + return false; + } + sqlite3_bind_text(stmt, 1, key, -1, SQLITE_STATIC); + if ((sqlite3_step(stmt) == SQLITE_ROW) && (sqlite3_column_text(stmt, 0) != NULL)) { + *value = strdup((const char *)sqlite3_column_text(stmt, 0)); + found = true; + } + sqlite3_finalize(stmt); + + return found; +} + + +static bool _fileModified(const char *path, int64_t *size, int64_t *modified) { + struct stat info; + + if (stat(path, &info) != 0) { + return false; + } + *size = (int64_t)info.st_size; + *modified = (int64_t)info.st_mtime; + + return true; +} + + +static bool _isAbsolute(const char *name) { + return (name[0] == '/') || (isalpha((unsigned char)name[0]) && (name[1] == ':')); +} + + +// Names the engine owns resolve on the filesystem even inside a packed game: Singe/ and the data directory. +static bool _isEngineName(const char *name) { + size_t length = strlen(ENGINE_DIRECTORY); + char *base = NULL; + bool engine = false; + + if ((utilStricmp(name, ENGINE_DIRECTORY) == 0) || ((strncmp(name, ENGINE_DIRECTORY, length) == 0) && (name[length] == '/'))) { + return true; + } + if (_dataDirBase != NULL) { + base = _normalise(_dataDirBase); + engine = (strncmp(name, base, strlen(base)) == 0); + free(base); + } + + return engine; +} + + +// Forward slashes, no leading "./", no doubled slashes. Case is untouched. +static char *_normalise(const char *name) { + char *out = strdup(name); + size_t i = 0; + size_t o = 0; + + for (i = 0; out[i] != 0; i++) { + char c = (out[i] == '\\') ? '/' : out[i]; + + if ((c == '/') && (o > 0) && (out[o - 1] == '/')) { + continue; + } + if ((c == '.') && (out[i + 1] == '/' || out[i + 1] == '\\') && ((o == 0) || (out[o - 1] == '/'))) { + i++; + continue; + } + out[o++] = c; + } + out[o] = 0; + + return out; +} + + +// A per-game directory under the data directory: the overlay or the cache. +static char *_overlayFor(const char *dataDirBase, const char *dataDir, const char *databasePath, bool isContainer, const char *directory) { + const char *base = NULL; + size_t length = 0; + + if (isContainer && (dataDir != NULL)) { + return utilCreateString("%s%s%c", dataDir, directory, utilGetPathSeparator()); + } + base = utilGetLastPathComponent(databasePath); + length = strlen(base) - strlen(VFS_DATABASE_EXTENSION); + + return utilCreateString("%s%.*s%c%s%c", dataDirBase ? dataDirBase : "", (int)length, base, utilGetPathSeparator(), directory, utilGetPathSeparator()); +} + + +// Whole asset, from the row or reassembled from its chunks. +static uint8_t *_readAsset(DatabaseT *db, const char *key, size_t *bytes, bool sdlMemory) { + uint8_t *data = NULL; + int64_t size = 0; + int64_t offset = 0; + int64_t index = 0; + int64_t length = 0; + + *bytes = 0; + sqlite3_reset(db->assetStmt); + sqlite3_bind_text(db->assetStmt, 1, key, -1, SQLITE_STATIC); + if (sqlite3_step(db->assetStmt) != SQLITE_ROW) { + sqlite3_reset(db->assetStmt); + return NULL; + } + size = sqlite3_column_int64(db->assetStmt, 0); + data = sdlMemory ? (uint8_t *)SDL_malloc((size_t)size + 1) : (uint8_t *)malloc((size_t)size + 1); + if (data == NULL) { + utilDie("Out of memory reading %s from %s.", key, db->path); + } + if (sqlite3_column_type(db->assetStmt, 1) != SQLITE_NULL) { + memcpy(data, sqlite3_column_blob(db->assetStmt, 1), (size_t)sqlite3_column_bytes(db->assetStmt, 1)); + offset = sqlite3_column_bytes(db->assetStmt, 1); + } + sqlite3_reset(db->assetStmt); + while (offset < size) { + if (!_readChunk(db, key, index, data + offset, &length) || (length == 0)) { + utilDie("%s in %s is missing chunk %lld.", key, db->path, (long long)index); + } + offset += length; + index++; + } + data[size] = 0; + *bytes = (size_t)size; + + return data; +} + + +static bool _readChunk(DatabaseT *db, const char *key, int64_t index, uint8_t *buffer, int64_t *length) { + bool found = false; + + *length = 0; + sqlite3_reset(db->chunkStmt); + sqlite3_bind_text(db->chunkStmt, 1, key, -1, SQLITE_STATIC); + sqlite3_bind_int64(db->chunkStmt, 2, index); + if (sqlite3_step(db->chunkStmt) == SQLITE_ROW) { + *length = sqlite3_column_bytes(db->chunkStmt, 0); + if (*length > db->chunkBytes) { + utilDie("%s in %s has an oversized chunk.", key, db->path); + } + memcpy(buffer, sqlite3_column_blob(db->chunkStmt, 0), (size_t)*length); + found = true; + } + sqlite3_reset(db->chunkStmt); + + return found; +} + + +// Decides where a name lives. Returns false only for an empty name. +static bool _resolve(const char *name, TargetT *target) { + char *norm = _normalise(name); + char *prefix = NULL; + const char *inner = NULL; + char *p = NULL; + size_t i = 0; + size_t extLen = strlen(VFS_DATABASE_EXTENSION); + + memset(target, 0, sizeof(*target)); + if (norm[0] == 0) { + free(norm); + return false; + } + + // A path that passes through a database file addresses its contents: "Games/DLe.game/Overlay/x.png". + if (!_isAbsolute(norm)) { + for (i = extLen; norm[i] != 0; i++) { + if ((norm[i] == '/') && (strncasecmp(norm + i - extLen, VFS_DATABASE_EXTENSION, extLen) == 0)) { + prefix = utilStrndup(norm, i); + if (utilFileExists(prefix)) { + target->db = _databaseOpen(prefix); + if (target->db != NULL) { + inner = norm + i + 1; + if (target->db->overlay == NULL) { + target->db->overlay = _overlayFor(_dataDirBase, _dataDir, prefix, false, OVERLAY_DIRECTORY); + target->db->cache = _overlayFor(_dataDirBase, _dataDir, prefix, false, CACHE_DIRECTORY); + } + free(prefix); + break; + } + } + free(prefix); + prefix = NULL; + } + } + } + if ((target->db == NULL) && (_container != NULL) && !_isAbsolute(norm) && !_isEngineName(norm)) { + target->db = _container; + inner = norm; + } + + if (target->db == NULL) { + target->path = strdup(name); + free(norm); + return true; + } + + // Inside a database: drop the game's own directory when the name starts with it. + if ((target->db->gameDir != NULL) && (inner[0] != 0)) { + i = strlen(target->db->gameDir); + if ((utilStricmp(inner, target->db->gameDir) == 0) || ((strncasecmp(inner, target->db->gameDir, i) == 0) && (inner[i] == '/'))) { + inner += i; + while (*inner == '/') { + inner++; + } + } + } + target->key = strdup(inner); + for (p = target->key; *p != 0; p++) { + *p = (char)tolower((unsigned char)*p); + } + target->path = utilCreateString("%s%s", target->db->loose, inner); + target->overlay = utilCreateString("%s%s", target->db->overlay, target->key); + target->cache = utilCreateString("%s%s", target->db->cache, target->key); + utilFixPathSeparators(&target->path, false); + utilFixPathSeparators(&target->overlay, false); + utilFixPathSeparators(&target->cache, false); + free(norm); + + return true; +} + + +static void _targetFree(TargetT *target) { + free(target->path); + free(target->key); + free(target->overlay); + free(target->cache); + memset(target, 0, sizeof(*target)); +} + + +static bool _writeFile(const char *path, const uint8_t *data, size_t bytes) { + char *directory = utilGetUpToLastPathComponent(path); + FILE *file = NULL; + bool ok = false; + + if ((directory[0] == 0) || utilMkDirP(directory, 0755)) { + file = fopen(path, "wb"); + if (file != NULL) { + ok = (fwrite(data, 1, bytes, file) == bytes); + fclose(file); + } + } + free(directory); + + return ok; +} + + +bool vfsExists(const char *name) { + TargetT target; + bool found = false; + + if (!_resolve(name, &target)) { + return false; + } + found = utilFileExists(target.path); + if (!found && (target.db != NULL)) { + found = utilFileExists(target.overlay) || _assetExists(target.db, target.key); + } + _targetFree(&target); + + return found; +} + + +// A filesystem path Lua's io library can open for the name. Writes land in the loose directory or +// the overlay, never the database. A packed asset opened for reading is unpacked into the cache, +// which the lookup never searches, so a later patch of the asset is not shadowed by the copy. +char *vfsFilePath(const char *name, bool forWriting) { + TargetT target; + char *path = NULL; + uint8_t *data = NULL; + size_t bytes = 0; + + if (!_resolve(name, &target)) { + return strdup(name); + } + if (target.db == NULL) { + path = target.path; + target.path = NULL; + } else if (utilFileExists(target.path)) { + path = target.path; + target.path = NULL; + } else if (forWriting || utilFileExists(target.overlay)) { + if (forWriting) { + char *directory = utilGetUpToLastPathComponent(target.overlay); + utilMkDirP(directory, 0755); + free(directory); + } + path = target.overlay; + target.overlay = NULL; + } else { + data = _readAsset(target.db, target.key, &bytes, false); + if (data != NULL) { + if (!_writeFile(target.cache, data, bytes)) { + utilDie("Unable to copy %s to %s.", name, target.cache); + } + free(data); + path = target.cache; + target.cache = NULL; + } else { + path = strdup(name); + } + } + _targetFree(&target); + + return path; +} + + +// container is the game's database, or NULL for a loose game. dataDir carries a trailing separator. +void vfsInit(const char *container, const char *dataDirBase, const char *dataDir) { + free(_dataDirBase); + free(_dataDir); + _dataDirBase = dataDirBase ? strdup(dataDirBase) : NULL; + _dataDir = dataDir ? strdup(dataDir) : NULL; + _container = NULL; + if (container != NULL) { + _container = _databaseOpen(container); + if (_container == NULL) { + utilDie("%s is not a Singe game database.", container); + } + free(_container->overlay); + free(_container->cache); + _container->overlay = _overlayFor(_dataDirBase, _dataDir, container, true, OVERLAY_DIRECTORY); + _container->cache = _overlayFor(_dataDirBase, _dataDir, container, true, CACHE_DIRECTORY); + } +} + + +bool vfsIsDatabase(const char *path) { + size_t length = strlen(path); + size_t extLen = strlen(VFS_DATABASE_EXTENSION); + + if ((length <= extLen) || (utilStricmp(path + length - extLen, VFS_DATABASE_EXTENSION) != 0) || !utilFileExists(path)) { + return false; + } + + return _databaseOpen(path) != NULL; +} + + +// Read-only stream for the SDL loaders. Packed assets are served from memory. +SDL_IOStream *vfsOpenIO(const char *name) { + TargetT target; + SDL_IOStream *io = NULL; + uint8_t *data = NULL; + size_t bytes = 0; + + if (!_resolve(name, &target)) { + return NULL; + } + if ((target.db == NULL) || utilFileExists(target.path)) { + io = SDL_IOFromFile(target.path, "rb"); + } else if (utilFileExists(target.overlay)) { + io = SDL_IOFromFile(target.overlay, "rb"); + } else { + data = _readAsset(target.db, target.key, &bytes, true); + if (data != NULL) { + io = SDL_IOFromMem(data, bytes); + if (io == NULL) { + SDL_free(data); + } else { + SDL_SetPointerProperty(SDL_GetIOProperties(io), SDL_PROP_IOSTREAM_MEMORY_FREE_FUNC_POINTER, SDL_free); + } + } else { + SDL_SetError("%s not found", name); + } + } + _targetFree(&target); + + return io; +} + + +void vfsQuit(void) { + DatabaseT *db = NULL; + DatabaseT *next = NULL; + + for (db = _databases; db != NULL; db = next) { + next = db->next; + sqlite3_finalize(db->assetStmt); + sqlite3_finalize(db->chunkStmt); + sqlite3_close(db->db); + free(db->path); + free(db->loose); + free(db->overlay); + free(db->cache); + free(db->gameDir); + free(db); + } + _databases = NULL; + _container = NULL; + free(_dataDirBase); + free(_dataDir); + _dataDirBase = NULL; + _dataDir = NULL; +} + + +// Whole file, NUL terminated, free() when done. NULL when the name resolves nowhere. +char *vfsRead(const char *name, size_t *bytes) { + TargetT target; + char *data = NULL; + + *bytes = 0; + if (!_resolve(name, &target)) { + return NULL; + } + if ((target.db == NULL) || utilFileExists(target.path)) { + data = utilReadFile(target.path, bytes); + } else if (utilFileExists(target.overlay)) { + data = utilReadFile(target.overlay, bytes); + } else { + data = (char *)_readAsset(target.db, target.key, bytes, false); + } + _targetFree(&target); + + return data; +} + + +// Size and modification time, the latter being the database's own for a packed asset. +bool vfsStat(const char *name, int64_t *size, int64_t *modified) { + TargetT target; + bool found = false; + int64_t ignore = 0; + + if (!_resolve(name, &target)) { + return false; + } + found = _fileModified(target.path, size, modified); + if (!found && (target.db != NULL)) { + found = _fileModified(target.overlay, size, modified); + if (!found && _assetSize(target.db, target.key, size)) { + found = _fileModified(target.db->path, &ignore, modified); + } + } + _targetFree(&target); + + return found; +} + + +void vfsStreamClose(VfsStreamT *stream) { + if (stream == NULL) { + return; + } + if (stream->file != NULL) { + fclose(stream->file); + } + free(stream->key); + free(stream->buffer); + free(stream); +} + + +// Seekable byte stream for the video demuxer. Chunked assets are read one chunk at a time. +VfsStreamT *vfsStreamOpen(const char *name) { + TargetT target; + VfsStreamT *stream = NULL; + const char *path = NULL; + size_t bytes = 0; + + if (!_resolve(name, &target)) { + return NULL; + } + stream = (VfsStreamT *)calloc(1, sizeof(VfsStreamT)); + stream->chunkIndex = -1; + if ((target.db == NULL) || utilFileExists(target.path)) { + path = target.path; + } else if (utilFileExists(target.overlay)) { + path = target.overlay; + } + if (path != NULL) { + stream->file = fopen(path, "rb"); + if (stream->file == NULL) { + free(stream); + stream = NULL; + } else { + fileSeek(stream->file, 0, SEEK_END); + stream->size = (int64_t)fileTell(stream->file); + fileSeek(stream->file, 0, SEEK_SET); + } + } else if (_assetSize(target.db, target.key, &stream->size)) { + stream->db = target.db; + stream->key = strdup(target.key); + if (stream->size <= target.db->chunkBytes) { + // Small enough to hold whole; the row carries the data. + stream->buffer = _readAsset(target.db, target.key, &bytes, false); + stream->chunkIndex = 0; + stream->chunkLength = (int64_t)bytes; + stream->whole = true; + } else { + stream->buffer = (uint8_t *)malloc((size_t)target.db->chunkBytes); + } + } else { + free(stream); + stream = NULL; + } + _targetFree(&target); + + return stream; +} + + +int64_t vfsStreamRead(VfsStreamT *stream, void *buffer, int64_t bytes) { + uint8_t *out = (uint8_t *)buffer; + int64_t total = 0; + int64_t index = 0; + int64_t start = 0; + int64_t take = 0; + + if (stream->file != NULL) { + total = (int64_t)fread(buffer, 1, (size_t)bytes, stream->file); + stream->position += total; + return total; + } + if (bytes > stream->size - stream->position) { + bytes = stream->size - stream->position; + } + while (total < bytes) { + index = stream->whole ? 0 : stream->position / stream->db->chunkBytes; + start = stream->whole ? stream->position : stream->position % stream->db->chunkBytes; + if (index != stream->chunkIndex) { + if (!_readChunk(stream->db, stream->key, index, stream->buffer, &stream->chunkLength)) { + break; + } + stream->chunkIndex = index; + } + take = stream->chunkLength - start; + if (take > bytes - total) { + take = bytes - total; + } + if (take <= 0) { + break; + } + memcpy(out + total, stream->buffer + start, (size_t)take); + total += take; + stream->position += take; + } + + return total; +} + + +int64_t vfsStreamSeek(VfsStreamT *stream, int64_t offset, int32_t whence) { + int64_t position = offset; + + if (whence == SEEK_CUR) { + position = stream->position + offset; + } else if (whence == SEEK_END) { + position = stream->size + offset; + } + if ((position < 0) || (position > stream->size)) { + return -1; + } + if ((stream->file != NULL) && (fileSeek(stream->file, position, SEEK_SET) != 0)) { + return -1; + } + stream->position = position; + + return position; +} + + +int64_t vfsStreamSize(VfsStreamT *stream) { + return stream->size; +} diff --git a/src/vfs.h b/src/vfs.h new file mode 100644 index 000000000..ea14083fa --- /dev/null +++ b/src/vfs.h @@ -0,0 +1,42 @@ +/* + * Singe virtual filesystem: one lookup for every file a game names. + * + * A name resolves to a loose file in the game directory, to a copy-on-write + * overlay in the data directory, or to an asset inside the game's SQLite + * database, in that order. Loose games with no database see exactly the + * filesystem they always did. + */ + +#ifndef VFS_H +#define VFS_H + +#include +#include +#include + +#include + + +#define VFS_DATABASE_EXTENSION ".game" +#define VFS_FORMAT_VERSION 1 +#define VFS_CHUNK_BYTES (4 * 1024 * 1024) + + +typedef struct VfsStreamS VfsStreamT; + + +bool vfsExists(const char *name); +char *vfsFilePath(const char *name, bool forWriting); +void vfsInit(const char *container, const char *dataDirBase, const char *dataDir); +bool vfsIsDatabase(const char *path); +SDL_IOStream *vfsOpenIO(const char *name); +void vfsQuit(void); +char *vfsRead(const char *name, size_t *bytes); +bool vfsStat(const char *name, int64_t *size, int64_t *modified); +void vfsStreamClose(VfsStreamT *stream); +VfsStreamT *vfsStreamOpen(const char *name); +int64_t vfsStreamRead(VfsStreamT *stream, void *buffer, int64_t bytes); +int64_t vfsStreamSeek(VfsStreamT *stream, int64_t offset, int32_t whence); +int64_t vfsStreamSize(VfsStreamT *stream); + +#endif diff --git a/src/videoPlayer.c b/src/videoPlayer.c index b11976baf..ddc4b8473 100644 --- a/src/videoPlayer.c +++ b/src/videoPlayer.c @@ -21,20 +21,38 @@ */ +// Frame exact video playback on libavformat and libavcodec. +// +// A laserdisc game addresses video by frame number, so the player needs to know every frame's +// presentation time before it plays anything. The first load of a file demuxes it once without +// decoding, records each video packet's timestamp and keyframe flag, sorts them into display +// order, and caches the table next to the game's other data. Seeking to frame N then means: +// find the last keyframe at or before N, seek the demuxer there, and decode forward until the +// frame whose timestamp matches N comes out. Decoding runs on a thread per player; audio is +// demuxed and decoded separately on the main thread and fed to an SDL3_mixer track. + #include +#include +#include #ifdef __linux__ #include #endif #include #include -#include "../thirdparty/ffms2/include/ffms.h" -#include "../thirdparty/uthash/src/uthash.h" -#include "../thirdparty/ffmpeg/libavformat/avformat.h" -#include "../thirdparty/ffmpeg/libavutil/dict.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "../thirdparty/uthash/src/uthash.h" #include "util.h" +#include "vfs.h" #include "videoPlayer.h" // This is kinda ugly but it lets us use the language @@ -48,36 +66,58 @@ typedef struct iso639_lang_t iso639_lang_t; #undef VLC_API -#define AUDIO_STREAM_LOW_WATERMARK (24 * 1024) -#define AUDIO_SAMPLE_PREREAD 1024 -#define AUDIO_SILENCE_SECONDS 2 -#define AUDIO_CHANNELS_MAX 2 -#define AUDIO_DRAIN_MS 400 // Long enough for any sane device queue to empty -#define AUDIO_MEASURE_TIMEOUT_MS 2000 +#define AUDIO_CHANNELS_OUT 2 // Everything is mixed as stereo +#define AUDIO_DRAIN_MS 400 // Long enough for any sane device queue to empty #define AUDIO_MEASURE_MAX_BUFFERS 64 -#define BITS_PER_BYTE 8 +#define AUDIO_MEASURE_TIMEOUT_MS 2000 +#define AUDIO_STREAM_LOW_WATERMARK (24 * 1024) // Bytes queued for the mixer before we stop decoding ahead +#define AVIO_BUFFER_BYTES (64 * 1024) // libavformat's read buffer over a vfs stream #define BYTES_PER_PIXEL 4 +#define BYTES_PER_SAMPLE 4 // Float samples +#define DEFAULT_FPS_NUMERATOR 30 +#define DEFAULT_FPS_DENOMINATOR 1 #define ERROR_BUFFER_SIZE 1024 +#define INDEX_MAGIC "SINGEIDX" +#define INDEX_VERSION 1 +#define KEYFRAME_WARN_SECONDS 2.0 // Seeks decode forward from the previous keyframe #define LANGUAGE_CODE_LENGTH 3 #define MS_PER_SECOND 1000.0 -#define PERCENT_TO_SCALE 0.01f #define PERCENT_MAX 100 -#define PLANE_COUNT 3 // Y, U, V -#define KEYFRAME_WARN_SECONDS 2.0 // Seeks decode forward from the previous keyframe +#define PERCENT_TO_SCALE 0.01f +#define PLANE_COUNT 3 // Y, U, V +#define SCALER_PLANES 4 // libswscale reads four plane pointers and strides whatever the format +#define SEEK_FORWARD_LIMIT 64 // Decode forward rather than seek when the wanted frame is this close +#define SEEK_RETRY_MAX 3 // Keyframes to back up when a seek lands past its target +#define STRIDE_ALIGNMENT 64 // libswscale stores with aligned vector instructions; rows must start aligned -// One decoded frame owned by the player (FFMS2 reuses its own buffer, so we copy). +// One video frame in display order. +typedef struct FrameInfoS { + int64_t pts; // In the video stream's time base + bool keyframe; +} FrameInfoT; + +// What the index cache file starts with. +typedef struct IndexHeaderS { + char magic[8]; + int32_t version; + int32_t streamIndex; + int64_t fileSize; + int64_t fileTime; + int64_t count; +} IndexHeaderT; + +// One decoded frame owned by the player. typedef struct FrameBufferS { - uint8_t *data[PLANE_COUNT]; - int32_t linesize[PLANE_COUNT]; + uint8_t *data[SCALER_PLANES]; // Only PLANE_COUNT are ever allocated; the rest stay NULL for libswscale + int32_t linesize[SCALER_PLANES]; int64_t frame; // -1 until something has been decoded into it } FrameBufferT; -typedef struct AudioStreamS { - FFMS_AudioSource *audioSource; - const FFMS_AudioProperties *audioProps; - char *language; -} AudioStreamT; +typedef struct AudioTrackS { + int32_t streamIndex; + char *language; +} AudioTrackT; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpadded" @@ -85,75 +125,117 @@ typedef struct VideoPlayerS { int32_t id; bool playing; bool resetTime; - uint8_t *audioBuffer; - uint8_t audioSampleBytes; - char errMsg[ERROR_BUFFER_SIZE]; - int32_t volumeLeft; - int32_t volumeRight; - int32_t videoTrack; + bool rgb; // BGRA frames for scripts to read; otherwise YUV for the GPU int32_t width; int32_t height; - int32_t audioSampleSize; - int32_t currentAudioTrack; + int32_t volumeLeft; + int32_t volumeRight; + AVRational fps; + + // Frame table, immutable after load. + FrameInfoT *frames; + int64_t frameCount; + AVRational videoTimeBase; + + // Video demuxer and decoder. Owned by the decoder thread once it starts. + AVFormatContext *videoFormat; + AVCodecContext *videoCodec; + AVPacket *videoPacket; + AVFrame *videoFrame; + struct SwsContext *sws; + AVBufferRef *hwDevice; // Hardware decoder context, NULL when decoding in software + AVFrame *hwFrame; // Decoded hardware frame transferred to system memory + enum AVPixelFormat hwPixelFormat; // What the hardware decoder hands back + int32_t videoStream; + int64_t nextDecodeFrame; // Frame the decoder will produce next, -1 when unknown + int64_t seekKeyframe; // Keyframe index of the last seek, for backing up + bool videoDrained; + bool packetPending; // videoPacket holds data the decoder refused (EAGAIN) + bool hwReported; // First hardware frame has been traced + + // Audio demuxer, decoder, and resampler. Owned by the main thread. + AVFormatContext *audioFormat; + AVCodecContext *audioCodec; + AVPacket *audioPacket; + AVFrame *audioFrame; + SwrContext *swr; + AudioTrackT *audio; int32_t audioSourceCount; - int64_t frame; - int64_t audioBufferSize; - int64_t firstFrameTime; // Presentation time (ms) of frame 0; FFMS2 aligns audio sample 0 to it - int64_t startTime; // Video time (ms) at the last play/seek - int64_t samplesPlayed; // Track frames mixed since the last reset, at trackRate - int32_t trackRate; // Sample rate the mixer pulls this track at (its own, not the device's) + int32_t currentAudioTrack; + bool audioEof; + int64_t audioSkipUntilMs; // Samples before this time are dropped after a seek + int64_t audioNextMs; // Where the next decoded audio frame is expected to start + float *audioBuffer; + int32_t audioBufferSamples; // Capacity, in sample frames + SDL_AudioSpec audioSpec; // What the resampler produces + SDL_AudioStream *audioStream; // Feeds the mixer track + MIX_Track *track; + + // Clock, driven by what the mixer has pulled from the track. + int64_t startTime; // Video time (ms) at the last play/seek + uint64_t startTicks; // Wall clock (ms) at the last play/seek + int64_t samplesPlayed; // Track frames mixed since the last reset, at trackRate + int32_t trackRate; // Sample rate the mixer pulls this track at uint64_t lastCallbackTicks; - bool audioClockValid; // A callback has run since the last reset - int64_t audioPosition; - uint64_t startTicks; // Wall clock (ms) at the last play/seek - SDL_AudioSpec audioSpec; // Format of the decoded audio - MIX_Track *track; // Mixer track fed by audioStream - SDL_AudioStream *audioStream; - SDL_Texture *videoTexture; - FFMS_ErrorInfo errInfo; - AudioStreamT *audio; - FFMS_VideoSource *videoSource; - FFMS_Track *videoTrackHandle; - const FFMS_VideoProperties *videoProps; - const FFMS_TrackTimeBase *videoTimeBase; - bool rgb; // BGRA frames for scripts to read; otherwise YUV for the GPU - FrameBufferT front; // What the texture and the script see - FrameBufferT back; // What the decoder thread fills + bool audioClockValid; // A callback has run since the last reset + int64_t frame; + + // Frame buffers and the decoder thread. + FrameBufferT front; // What the texture and the script see + FrameBufferT back; // What the decoder thread fills bool backReady; bool threadError; bool quitThread; - int64_t requestedFrame; // Waiting for the decoder, -1 when none - int64_t pendingFrame; // Last frame asked for, so it is not asked for twice - int64_t uploadedFrame; // Frame currently on the texture + int64_t requestedFrame; // Waiting for the decoder, -1 when none + int64_t pendingFrame; // Last frame asked for, so it is not asked for twice + int64_t uploadedFrame; // Frame currently on the texture + SDL_Texture *videoTexture; SDL_Thread *thread; SDL_Mutex *lock; SDL_Condition *wake; - FFMS_ErrorInfo threadErrInfo; char threadErrMsg[ERROR_BUFFER_SIZE]; UT_hash_handle hh; } VideoPlayerT; #pragma GCC diagnostic pop -static int64_t _audioClock(VideoPlayerT *v, uint64_t now); static void _allocateFrameBuffer(VideoPlayerT *v, FrameBufferT *buffer); static void _alsaSetQuiet(bool quiet); -static void _copyFrame(VideoPlayerT *v, FrameBufferT *buffer, const FFMS_Frame *frame); -static FFMS_Index *_createIndex(const char *filename, const char *indexPath, bool hasVideo, bool hasAudio, VideoPlayerT *v); -static int _decoderThread(void *data); // SDL thread entry. Not changing int. +static int64_t _audioClock(VideoPlayerT *v, uint64_t now); +static void _audioCloseTrack(VideoPlayerT *v); +static void _audioQueueFrame(VideoPlayerT *v); +static void _audioSeek(VideoPlayerT *v, int64_t ms); +static void _audioSelectTrack(VideoPlayerT *v, int32_t track); +static void _audioSetupResampler(VideoPlayerT *v); +static int _avioRead(void *opaque, uint8_t *buffer, int size); +static int64_t _avioSeek(void *opaque, int64_t offset, int whence); +static void _buildFrameTable(VideoPlayerT *v, const char *filename, const char *indexPath); +static int _compareFrames(const void *a, const void *b); // qsort callback. Not changing int. +static void _convertFrame(VideoPlayerT *v, FrameBufferT *buffer, const AVFrame *frame); +static bool _decodeFrame(VideoPlayerT *v, int64_t want); +static int _decoderThread(void *data); // SDL thread entry. Not changing int. static void _feedAudio(VideoPlayerT *v); +static int64_t _findFrameIndex(VideoPlayerT *v, int64_t pts); +static void _formatClose(AVFormatContext **format); +static AVFormatContext *_formatOpen(const char *filename); static int64_t _frameTime(VideoPlayerT *v, int64_t frame); static VideoPlayerT *_getPlayer(int32_t playerHandle, const char *caller); -static int FFMS_CC _indexCallBack(int64_t current, int64_t total, void *icPrivate); // Callback. Not changing int. -static void _loadAudio(VideoPlayerT *v, const char *filename, FFMS_Index *index); +static char *_indexFileName(const char *filename, const char *indexPath); +static void _loadAudio(VideoPlayerT *v, const char *filename); +static void _measureDeviceQueue(void *udata, MIX_Mixer *mixer, const SDL_AudioSpec *spec, float *pcm, int32_t samples); +static void _openHardware(VideoPlayerT *v, const AVCodec *decoder); +static void _openVideo(VideoPlayerT *v, const char *filename); +static bool _readIndexCache(VideoPlayerT *v, const char *indexName, const IndexHeaderT *expected); static void _reportKeyframes(VideoPlayerT *v, const char *filename); static void _requestFrame(VideoPlayerT *v); -static bool _takeDecodedFrame(VideoPlayerT *v); -static void _uploadFrame(VideoPlayerT *v); -static void _measureDeviceQueue(void *udata, MIX_Mixer *mixer, const SDL_AudioSpec *spec, float *pcm, int32_t samples); -static int64_t _msToSamples(VideoPlayerT *v, int64_t ms); static void _resetClock(VideoPlayerT *v, uint64_t now); +static void _seekVideo(VideoPlayerT *v, int64_t keyframe); +static enum AVPixelFormat _selectPixelFormat(AVCodecContext *codec, const enum AVPixelFormat *formats); // libavcodec callback. +static int64_t _streamTimeToMs(int64_t ts, AVRational timeBase); +static bool _takeDecodedFrame(VideoPlayerT *v); static void _trackMixed(void *udata, MIX_Track *track, const SDL_AudioSpec *spec, float *pcm, int32_t samples); +static void _uploadFrame(VideoPlayerT *v); +static void _writeIndexCache(VideoPlayerT *v, const char *indexName, const IndexHeaderT *header); #ifdef __linux__ @@ -163,44 +245,46 @@ typedef int (*AlsaSetErrorHandlerT)(AlsaErrorHandlerT handler); static void _alsaQuiet(const char *file, int line, const char *function, int err, const char *fmt, ...); -static void *_alsaLibrary = NULL; +static void *_alsaLibrary = NULL; #endif -static VideoIndexingCallbackT _indexingFunction = NULL; -static VideoPlayerT *_videoPlayerHash = NULL; -static int32_t _nextId = 0; -static MIX_Mixer *_mixer = NULL; -static SDL_AudioSpec _mixSpec; // What the mixer feeds the device -static int64_t _mixLatencyMs = 0; // Time between handing audio to the device and hearing it -static int32_t _audioDelayMs = 0; // Per-game correction on top of the measured latency -static int32_t _audioCalibrationMs = 0; // Per-machine correction, from the calibration screen +static VideoPlayerT *_videoPlayerHash = NULL; +static int32_t _nextId = 0; +static MIX_Mixer *_mixer = NULL; +static SDL_AudioSpec _mixSpec; // What the mixer feeds the device +static int64_t _mixLatencyMs = 0; // Time between handing audio to the device and hearing it +static int32_t _audioDelayMs = 0; // Per-game correction on top of the measured latency +static int32_t _audioCalibrationMs = 0; // Per-machine correction, from the calibration screen +static bool _hardwareDecoding = true; // Try the platform decoder before falling back to software // Startup measurement of the audio device queue (see videoInit). -static bool _measuring = false; -static int32_t _measureCount = 0; -static int64_t _measureFrames = 0; -static int64_t _measurePeriodMs = 0; -static uint64_t _measureLastTicks = 0; +static bool _measuring = false; +static int32_t _measureCount = 0; +static int64_t _measureFrames = 0; +static int64_t _measurePeriodMs = 0; +static uint64_t _measureLastTicks = 0; +// Planes are allocated the way libavcodec allocates its own: aligned start, aligned stride. +// libswscale writes rows with aligned vector stores and faults on anything less. static void _allocateFrameBuffer(VideoPlayerT *v, FrameBufferT *buffer) { int32_t chromaWidth = (v->width + 1) / 2; int32_t chromaHeight = (v->height + 1) / 2; buffer->frame = -1; if (v->rgb) { - buffer->linesize[0] = v->width * BYTES_PER_PIXEL; - buffer->data[0] = malloc((size_t)buffer->linesize[0] * (size_t)v->height); + buffer->linesize[0] = FFALIGN(v->width * BYTES_PER_PIXEL, STRIDE_ALIGNMENT); + buffer->data[0] = av_malloc((size_t)buffer->linesize[0] * (size_t)v->height); if (!buffer->data[0]) { utilDie("Unable to allocate frame buffer."); } } else { - buffer->linesize[0] = v->width; - buffer->linesize[1] = chromaWidth; - buffer->linesize[2] = chromaWidth; - buffer->data[0] = malloc((size_t)v->width * (size_t)v->height); - buffer->data[1] = malloc((size_t)chromaWidth * (size_t)chromaHeight); - buffer->data[2] = malloc((size_t)chromaWidth * (size_t)chromaHeight); + buffer->linesize[0] = FFALIGN(v->width, STRIDE_ALIGNMENT); + buffer->linesize[1] = FFALIGN(chromaWidth, STRIDE_ALIGNMENT); + buffer->linesize[2] = buffer->linesize[1]; + buffer->data[0] = av_malloc((size_t)buffer->linesize[0] * (size_t)v->height); + buffer->data[1] = av_malloc((size_t)buffer->linesize[1] * (size_t)chromaHeight); + buffer->data[2] = av_malloc((size_t)buffer->linesize[2] * (size_t)chromaHeight); if (!buffer->data[0] || !buffer->data[1] || !buffer->data[2]) { utilDie("Unable to allocate frame buffer."); } @@ -208,26 +292,6 @@ static void _allocateFrameBuffer(VideoPlayerT *v, FrameBufferT *buffer) { } -// Copies FFMS2's frame into our buffer, one plane at a time (line sizes may differ). -static void _copyFrame(VideoPlayerT *v, FrameBufferT *buffer, const FFMS_Frame *frame) { - int32_t plane = 0; - int32_t planes = v->rgb ? 1 : PLANE_COUNT; - int32_t rows = 0; - int32_t width = 0; - int32_t y = 0; - - for (plane = 0; plane < planes; plane++) { - rows = (plane == 0) ? v->height : (v->height + 1) / 2; - width = buffer->linesize[plane]; - for (y = 0; y < rows; y++) { - memcpy(buffer->data[plane] + y * buffer->linesize[plane], frame->Data[plane] + y * frame->Linesize[plane], (size_t)width); - } - } -} - - -// Presentation time (ms) the listener is hearing right now. Audio is the master clock: -// the picture is fitted to what the device has actually consumed, so the two cannot drift. #ifdef __linux__ static void _alsaQuiet(const char *file, int line, const char *function, int err, const char *fmt, ...) { (void)file; @@ -265,6 +329,8 @@ static void _alsaSetQuiet(bool quiet) { } +// Presentation time (ms) the listener is hearing right now. Audio is the master clock: +// the picture is fitted to what the device has actually consumed, so the two cannot drift. static int64_t _audioClock(VideoPlayerT *v, uint64_t now) { int64_t played = 0; int32_t rate = 0; @@ -294,52 +360,398 @@ static int64_t _audioClock(VideoPlayerT *v, uint64_t now) { } -static FFMS_Index *_createIndex(const char *filename, const char *indexPath, bool hasVideo, bool hasAudio, VideoPlayerT *v) { - char *indexName = NULL; - FFMS_Index *index = NULL; - FFMS_Indexer *indexer = NULL; +static void _audioCloseTrack(VideoPlayerT *v) { + if (v->audioCodec) { + avcodec_free_context(&v->audioCodec); + } + if (v->swr) { + swr_free(&v->swr); + } +} - // Index file - indexName = utilCreateString("%s%c%s.index", indexPath, utilGetPathSeparator(), utilGetLastPathComponent(filename)); - utilFixPathSeparators(&indexName, false); - index = FFMS_ReadIndex(indexName, &v->errInfo); - if (index && FFMS_IndexBelongsToFile(index, filename, &v->errInfo)) { - FFMS_DestroyIndex(index); - index = NULL; + +// Resamples one decoded audio frame to the track's format and queues it, dropping whatever lies +// before the seek target. +static void _audioQueueFrame(VideoPlayerT *v) { + AVStream *stream = v->audioFormat->streams[v->audio[v->currentAudioTrack].streamIndex]; + int64_t ts = v->audioFrame->best_effort_timestamp; + int64_t startMs = (ts == AV_NOPTS_VALUE) ? v->audioNextMs : _streamTimeToMs(ts, stream->time_base); + int32_t capacity = swr_get_out_samples(v->swr, v->audioFrame->nb_samples); + int32_t produced = 0; + int32_t skip = 0; + uint8_t *out = NULL; + + if (capacity < 0) { + utilDie("Unable to size the audio resampler output."); } - if (!index) { - indexer = FFMS_CreateIndexer(filename, &v->errInfo); - if (indexer == NULL) { - utilDie("%s", v->errInfo.Buffer); - } - if (hasAudio) { - FFMS_TrackTypeIndexSettings(indexer, FFMS_TYPE_AUDIO, 1, 0); - } - if (hasVideo) { - FFMS_TrackTypeIndexSettings(indexer, FFMS_TYPE_VIDEO, 1, 0); - } - _indexCallBack(0, 0, v); - FFMS_SetProgressCallback(indexer, _indexCallBack, v); - index = FFMS_DoIndexing2(indexer, FFMS_IEH_ABORT, &v->errInfo); - if (index == NULL) { - utilDie("%s", v->errInfo.Buffer); - } - if (FFMS_WriteIndex(indexName, index, &v->errInfo)) { - utilDie("%s", v->errInfo.Buffer); + if (capacity > v->audioBufferSamples) { + free(v->audioBuffer); + v->audioBufferSamples = capacity; + v->audioBuffer = malloc((size_t)capacity * AUDIO_CHANNELS_OUT * BYTES_PER_SAMPLE); + if (!v->audioBuffer) { + utilDie("Unable to allocate audio buffer."); } } + out = (uint8_t *)v->audioBuffer; + produced = swr_convert(v->swr, &out, capacity, (const uint8_t **)v->audioFrame->extended_data, v->audioFrame->nb_samples); + if (produced < 0) { + utilDie("Audio resampling failed."); + } + + // After a seek the first frame usually starts before the target; trim it. + if (startMs < v->audioSkipUntilMs) { + skip = (int32_t)((v->audioSkipUntilMs - startMs) * v->audioSpec.freq / (int64_t)MS_PER_SECOND); + if (skip > produced) { + skip = produced; + } + } + if (produced > skip) { + if (!SDL_PutAudioStreamData(v->audioStream, v->audioBuffer + (size_t)skip * AUDIO_CHANNELS_OUT, (produced - skip) * AUDIO_CHANNELS_OUT * BYTES_PER_SAMPLE)) { + utilDie("%s", SDL_GetError()); + } + } + v->audioNextMs = startMs + (int64_t)produced * (int64_t)MS_PER_SECOND / v->audioSpec.freq; +} + + +// Positions the audio demuxer so the next samples queued are the ones for video time ms. +static void _audioSeek(VideoPlayerT *v, int64_t ms) { + AVStream *stream = v->audioFormat->streams[v->audio[v->currentAudioTrack].streamIndex]; + int64_t ts = av_rescale(ms, stream->time_base.den, (int64_t)stream->time_base.num * (int64_t)MS_PER_SECOND); + + if (av_seek_frame(v->audioFormat, stream->index, ts, AVSEEK_FLAG_BACKWARD) < 0) { + // Before the first packet, or an unseekable stream: start over. + avformat_seek_file(v->audioFormat, stream->index, INT64_MIN, 0, INT64_MAX, 0); + } + avcodec_flush_buffers(v->audioCodec); + _audioSetupResampler(v); + if (v->audioPacket->data) { + av_packet_unref(v->audioPacket); + } + v->audioSkipUntilMs = ms; + v->audioNextMs = ms; + v->audioEof = false; +} + + +// Opens the decoder for one audio track and points the mixer track's stream at its output. +static void _audioSelectTrack(VideoPlayerT *v, int32_t track) { + AVStream *stream = v->audioFormat->streams[v->audio[track].streamIndex]; + const AVCodec *decoder = avcodec_find_decoder(stream->codecpar->codec_id); + SDL_AudioSpec spec; + SDL_AudioStream *fresh = NULL; + int32_t x = 0; + + if (decoder == NULL) { + utilDie("No decoder for audio track %d.", track); + } + _audioCloseTrack(v); + v->audioCodec = avcodec_alloc_context3(decoder); + if (!v->audioCodec || (avcodec_parameters_to_context(v->audioCodec, stream->codecpar) < 0) || (avcodec_open2(v->audioCodec, decoder, NULL) < 0)) { + utilDie("Unable to open audio track %d.", track); + } + v->currentAudioTrack = track; + + // Only the chosen track needs demuxing. + for (x = 0; x < (int32_t)v->audioFormat->nb_streams; x++) { + v->audioFormat->streams[x]->discard = (x == stream->index) ? AVDISCARD_DEFAULT : AVDISCARD_ALL; + } + + // The resampler always produces interleaved float stereo at the track's own rate. + spec.format = SDL_AUDIO_F32; + spec.channels = AUDIO_CHANNELS_OUT; + spec.freq = v->audioCodec->sample_rate; + if ((v->audioStream == NULL) || (spec.freq != v->audioSpec.freq)) { + fresh = SDL_CreateAudioStream(&spec, &_mixSpec); + if (!fresh) { + utilDie("%s", SDL_GetError()); + } + if (!MIX_SetTrackAudioStream(v->track, fresh)) { + utilDie("%s", SDL_GetError()); + } + if (v->audioStream) { + SDL_DestroyAudioStream(v->audioStream); + } + v->audioStream = fresh; + } + v->audioSpec = spec; + _audioSetupResampler(v); +} + + +// (Re)creates the resampler for the current track. Also the cheapest way to flush it after a seek. +static void _audioSetupResampler(VideoPlayerT *v) { + AVChannelLayout stereo = AV_CHANNEL_LAYOUT_STEREO; + + if (v->swr) { + swr_free(&v->swr); + } + if ((swr_alloc_set_opts2(&v->swr, &stereo, AV_SAMPLE_FMT_FLT, v->audioSpec.freq, &v->audioCodec->ch_layout, v->audioCodec->sample_fmt, v->audioCodec->sample_rate, 0, NULL) < 0) || (swr_init(v->swr) < 0)) { + utilDie("Unable to create the audio resampler."); + } +} + + +// Loads the frame table from the cache, or demuxes the file once to build it and caches the result. +static int _avioRead(void *opaque, uint8_t *buffer, int size) { + int64_t got = vfsStreamRead((VfsStreamT *)opaque, buffer, size); + + return (got <= 0) ? AVERROR_EOF : (int)got; +} + + +static int64_t _avioSeek(void *opaque, int64_t offset, int whence) { + VfsStreamT *stream = (VfsStreamT *)opaque; + + if (whence & AVSEEK_SIZE) { + return vfsStreamSize(stream); + } + + return vfsStreamSeek(stream, offset, whence & ~AVSEEK_FORCE); +} + + +static void _buildFrameTable(VideoPlayerT *v, const char *filename, const char *indexPath) { + AVFormatContext *format = NULL; + AVPacket *packet = NULL; + AVStream *stream = NULL; + FrameInfoT *grown = NULL; + IndexHeaderT header; + int64_t fileSize = 0; + int64_t fileTime = 0; + char *indexName = _indexFileName(filename, indexPath); + int64_t capacity = 0; + int64_t pts = 0; + uint64_t started = SDL_GetTicks(); + int64_t lastPts = AV_NOPTS_VALUE; + int64_t duration = 1; + int64_t x = 0; + int64_t kept = 0; + + if (!vfsStat(filename, &fileSize, &fileTime)) { + utilDie("Unable to stat %s", filename); + } + memset(&header, 0, sizeof(header)); + memcpy(header.magic, INDEX_MAGIC, sizeof(header.magic)); + header.version = INDEX_VERSION; + header.streamIndex = v->videoStream; + header.fileSize = fileSize; + header.fileTime = fileTime; + + if (_readIndexCache(v, indexName, &header)) { + free(indexName); + return; + } + + // Demux the whole file once. Every packet of the video stream is one frame. + format = _formatOpen(filename); + if (format == NULL) { + utilDie("Unable to open %s for indexing.", filename); + } + if (avformat_find_stream_info(format, NULL) < 0) { + utilDie("Unable to read stream information from %s.", filename); + } + stream = format->streams[v->videoStream]; + for (x = 0; x < (int64_t)format->nb_streams; x++) { + format->streams[x]->discard = (x == v->videoStream) ? AVDISCARD_DEFAULT : AVDISCARD_ALL; + } + packet = av_packet_alloc(); + if (!packet) { + utilDie("Unable to allocate a packet."); + } + if (stream->avg_frame_rate.num > 0) { + duration = av_rescale_q(1, av_inv_q(stream->avg_frame_rate), stream->time_base); + if (duration < 1) { + duration = 1; + } + } + while (av_read_frame(format, packet) >= 0) { + if (packet->stream_index == v->videoStream) { + if (v->frameCount == capacity) { + capacity = (capacity == 0) ? 4096 : capacity * 2; + grown = realloc(v->frames, sizeof(FrameInfoT) * (size_t)capacity); + if (!grown) { + utilDie("Unable to allocate the frame table."); + } + v->frames = grown; + } + // Prefer the presentation time; elementary streams may only have decode times or nothing. + pts = (packet->pts != AV_NOPTS_VALUE) ? packet->pts : packet->dts; + if (pts == AV_NOPTS_VALUE) { + pts = (lastPts == AV_NOPTS_VALUE) ? 0 : lastPts + duration; + } + lastPts = pts; + v->frames[v->frameCount].pts = pts; + v->frames[v->frameCount].keyframe = (packet->flags & AV_PKT_FLAG_KEY) != 0; + v->frameCount++; + } + av_packet_unref(packet); + } + av_packet_free(&packet); + _formatClose(&format); + if (v->frameCount == 0) { + utilDie("%s has no video frames.", filename); + } + + // Display order, one entry per timestamp. + qsort(v->frames, (size_t)v->frameCount, sizeof(FrameInfoT), _compareFrames); + for (x = 0; x < v->frameCount; x++) { + if ((kept == 0) || (v->frames[x].pts != v->frames[kept - 1].pts)) { + v->frames[kept++] = v->frames[x]; + } else if (v->frames[x].keyframe) { + v->frames[kept - 1].keyframe = true; + } + } + v->frameCount = kept; + header.count = kept; + _writeIndexCache(v, indexName, &header); + utilTrace("Indexed %s: %" PRId64 " frames in %" PRIu64 " ms", filename, kept, SDL_GetTicks() - started); free(indexName); +} - return index; + +static int _compareFrames(const void *a, const void *b) { + const FrameInfoT *fa = (const FrameInfoT *)a; + const FrameInfoT *fb = (const FrameInfoT *)b; + + return (fa->pts > fb->pts) - (fa->pts < fb->pts); +} + + +// Puts a decoded frame into our buffer in the player's format, converting only when the decoder's +// output differs (10 bit sources, 4:2:2, hardware formats). +static void _convertFrame(VideoPlayerT *v, FrameBufferT *buffer, const AVFrame *frame) { + enum AVPixelFormat wanted = v->rgb ? AV_PIX_FMT_BGRA : AV_PIX_FMT_YUV420P; + int32_t planes = v->rgb ? 1 : PLANE_COUNT; + int32_t plane = 0; + int32_t rows = 0; + int32_t bytes = 0; + + if ((frame->format == wanted) || (!v->rgb && (frame->format == AV_PIX_FMT_YUVJ420P))) { + for (plane = 0; plane < planes; plane++) { + rows = (plane == 0) ? v->height : (v->height + 1) / 2; + bytes = v->rgb ? v->width * BYTES_PER_PIXEL : ((plane == 0) ? v->width : (v->width + 1) / 2); + av_image_copy_plane(buffer->data[plane], buffer->linesize[plane], frame->data[plane], frame->linesize[plane], bytes, rows); + } + } else { + v->sws = sws_getCachedContext(v->sws, frame->width, frame->height, (enum AVPixelFormat)frame->format, v->width, v->height, wanted, SWS_BILINEAR, NULL, NULL, NULL); + if (!v->sws) { + utilDie("Unable to convert video frames."); + } + sws_scale(v->sws, (const uint8_t *const *)frame->data, frame->linesize, 0, frame->height, buffer->data, buffer->linesize); + } +} + + +// Decodes frame "want" into the back buffer. Runs on the decoder thread. +static bool _decodeFrame(VideoPlayerT *v, int64_t want) { + int64_t keyframe = want; + int64_t index = 0; + int64_t ts = 0; + int32_t retries = 0; + int32_t result = 0; + + // Decide between decoding forward and seeking. + while ((keyframe > 0) && !v->frames[keyframe].keyframe) { + keyframe--; + } + if (v->videoDrained || (v->nextDecodeFrame < 0) || (want < v->nextDecodeFrame) || (keyframe > v->nextDecodeFrame) || (want - v->nextDecodeFrame > SEEK_FORWARD_LIMIT)) { + _seekVideo(v, keyframe); + } + + for (;;) { + result = avcodec_receive_frame(v->videoCodec, v->videoFrame); + if (result == 0) { + ts = v->videoFrame->best_effort_timestamp; + index = (ts == AV_NOPTS_VALUE) ? v->nextDecodeFrame : _findFrameIndex(v, ts); + if (index == want) { + if (v->hwDevice && (v->videoFrame->format == v->hwPixelFormat)) { + // Pull the picture out of the GPU; it arrives as NV12 and is converted like any other format. + if (av_hwframe_transfer_data(v->hwFrame, v->videoFrame, 0) < 0) { + snprintf(v->threadErrMsg, sizeof(v->threadErrMsg), "Unable to read back a hardware decoded frame."); + v->threadError = true; + av_frame_unref(v->videoFrame); + return false; + } + if (!v->hwReported) { + v->hwReported = true; + utilTrace("Video %d: first hardware frame read back as %s %dx%d", v->id, av_get_pix_fmt_name((enum AVPixelFormat)v->hwFrame->format), v->hwFrame->width, v->hwFrame->height); + } + _convertFrame(v, &v->back, v->hwFrame); + av_frame_unref(v->hwFrame); + } else { + _convertFrame(v, &v->back, v->videoFrame); + } + av_frame_unref(v->videoFrame); + v->nextDecodeFrame = want + 1; + return true; + } + if (index > want) { + av_frame_unref(v->videoFrame); + // The seek landed past the target (sparse cues); back up one keyframe and try again. + if ((retries < SEEK_RETRY_MAX) && (v->seekKeyframe > 0)) { + retries++; + keyframe = v->seekKeyframe - 1; + while ((keyframe > 0) && !v->frames[keyframe].keyframe) { + keyframe--; + } + _seekVideo(v, keyframe); + continue; + } + // Best we can do: show what we have. + v->nextDecodeFrame = index + 1; + return false; + } + // Earlier than wanted: keep going. + av_frame_unref(v->videoFrame); + v->nextDecodeFrame = index + 1; + continue; + } + if (result == AVERROR_EOF) { + v->videoDrained = true; + return false; + } + if (result != AVERROR(EAGAIN)) { + av_strerror(result, v->threadErrMsg, sizeof(v->threadErrMsg)); + v->threadError = true; + return false; + } + + // The decoder wants data. + if (!v->packetPending) { + result = av_read_frame(v->videoFormat, v->videoPacket); + if (result < 0) { + // End of file: drain the decoder. + avcodec_send_packet(v->videoCodec, NULL); + continue; + } + if (v->videoPacket->stream_index != v->videoStream) { + av_packet_unref(v->videoPacket); + continue; + } + v->packetPending = true; + } + result = avcodec_send_packet(v->videoCodec, v->videoPacket); + if (result == 0) { + av_packet_unref(v->videoPacket); + v->packetPending = false; + } else if (result != AVERROR(EAGAIN)) { + av_strerror(result, v->threadErrMsg, sizeof(v->threadErrMsg)); + v->threadError = true; + av_packet_unref(v->videoPacket); + v->packetPending = false; + return false; + } + } } // Decodes whatever frame was last requested into the back buffer, then waits for the next request. -// FFMS2 seeks by decoding forward from a keyframe, so this keeps long seeks off the main loop. +// Seeks decode forward from a keyframe, so this keeps long seeks off the main loop. static int _decoderThread(void *data) { - VideoPlayerT *v = (VideoPlayerT *)data; - const FFMS_Frame *frame = NULL; - int64_t want = -1; + VideoPlayerT *v = (VideoPlayerT *)data; + int64_t want = -1; + bool got = false; SDL_LockMutex(v->lock); while (!v->quitThread) { @@ -352,17 +764,16 @@ static int _decoderThread(void *data) { v->requestedFrame = -1; SDL_UnlockMutex(v->lock); - frame = FFMS_GetFrame(v->videoSource, (int)want, &v->threadErrInfo); - if (frame != NULL) { - _copyFrame(v, &v->back, frame); - } + got = _decodeFrame(v, want); SDL_LockMutex(v->lock); - if (frame == NULL) { - v->threadError = true; - } else { + if (got) { v->back.frame = want; v->backReady = true; + } else if (!v->threadError) { + // Nothing decodable there (past the end, or a seek that could not be satisfied): let the + // main thread ask again for whatever frame it wants next rather than hanging on this one. + v->pendingFrame = -1; } } SDL_UnlockMutex(v->lock); @@ -371,39 +782,109 @@ static int _decoderThread(void *data) { } -// Keep the mixer stream topped up from the current audio track. +// Keeps the mixer track's stream topped up from the current audio track. static void _feedAudio(VideoPlayerT *v) { - AudioStreamT *track = &v->audio[v->currentAudioTrack]; - int64_t count = 0; - int32_t available = 0; + int32_t result = 0; - available = SDL_GetAudioStreamQueued(v->audioStream); - - while ((available < AUDIO_STREAM_LOW_WATERMARK) && (v->audioPosition < track->audioProps->NumSamples)) { - // Don't read past end of audio data - count = track->audioProps->NumSamples - v->audioPosition; - if (count > AUDIO_SAMPLE_PREREAD) { - count = AUDIO_SAMPLE_PREREAD; + while (!v->audioEof && (SDL_GetAudioStreamQueued(v->audioStream) < AUDIO_STREAM_LOW_WATERMARK)) { + result = avcodec_receive_frame(v->audioCodec, v->audioFrame); + if (result == 0) { + _audioQueueFrame(v); + av_frame_unref(v->audioFrame); + continue; } - // Get audio from video stream - if (FFMS_GetAudio(track->audioSource, v->audioBuffer, v->audioPosition, count, &v->errInfo)) { - utilDie("%s", v->errInfo.Buffer); + if (result == AVERROR_EOF) { + v->audioEof = true; + break; } - // Feed it to the mixer stream (streams are thread safe). - if (!SDL_PutAudioStreamData(v->audioStream, v->audioBuffer, (int32_t)(count * v->audioSampleSize))) { - utilDie("%s", SDL_GetError()); + if (result != AVERROR(EAGAIN)) { + utilDie("Audio decoding failed."); } - available = SDL_GetAudioStreamQueued(v->audioStream); - v->audioPosition += count; + result = av_read_frame(v->audioFormat, v->audioPacket); + if (result < 0) { + avcodec_send_packet(v->audioCodec, NULL); + continue; + } + if (v->audioPacket->stream_index == v->audio[v->currentAudioTrack].streamIndex) { + if (avcodec_send_packet(v->audioCodec, v->audioPacket) < 0) { + utilDie("Audio decoding failed."); + } + } + av_packet_unref(v->audioPacket); } } +// Index of the last frame whose timestamp is at or before pts. +static int64_t _findFrameIndex(VideoPlayerT *v, int64_t pts) { + int64_t low = 0; + int64_t high = v->frameCount - 1; + int64_t mid = 0; + + if (pts <= v->frames[0].pts) { + return 0; + } + while (low < high) { + mid = (low + high + 1) / 2; + if (v->frames[mid].pts <= pts) { + low = mid; + } else { + high = mid - 1; + } + } + + return low; +} + + +// Closes a demuxer opened by _formatOpen along with the stream behind it. +static void _formatClose(AVFormatContext **format) { + AVIOContext *io = NULL; + VfsStreamT *stream = NULL; + + if (*format == NULL) { + return; + } + io = (*format)->pb; + avformat_close_input(format); + if (io != NULL) { + stream = (VfsStreamT *)io->opaque; + av_freep(&io->buffer); + avio_context_free(&io); + } + vfsStreamClose(stream); +} + + +// Opens a demuxer over a vfs stream, so packed and loose videos read alike. NULL when the name resolves nowhere. +static AVFormatContext *_formatOpen(const char *filename) { + VfsStreamT *stream = vfsStreamOpen(filename); + AVFormatContext *format = NULL; + AVIOContext *io = NULL; + unsigned char *buffer = NULL; + + if (stream == NULL) { + return NULL; + } + buffer = (unsigned char *)av_malloc(AVIO_BUFFER_BYTES); + io = avio_alloc_context(buffer, AVIO_BUFFER_BYTES, 0, stream, _avioRead, NULL, _avioSeek); + format = avformat_alloc_context(); + format->pb = io; + format->flags |= AVFMT_FLAG_CUSTOM_IO; + if (avformat_open_input(&format, filename, NULL, NULL) < 0) { + av_freep(&io->buffer); + avio_context_free(&io); + vfsStreamClose(stream); + return NULL; + } + + return format; +} + + // Presentation time of a frame in milliseconds. static int64_t _frameTime(VideoPlayerT *v, int64_t frame) { - const FFMS_FrameInfo *info = FFMS_GetFrameInfo(v->videoTrackHandle, (int)frame); - - return (int64_t)((double)info->PTS * (double)v->videoTimeBase->Num / (double)v->videoTimeBase->Den); + return _streamTimeToMs(v->frames[frame].pts, v->videoTimeBase); } @@ -419,91 +900,68 @@ static VideoPlayerT *_getPlayer(int32_t playerHandle, const char *caller) { } -static int FFMS_CC _indexCallBack(int64_t current, int64_t total, void *icPrivate) { - static int32_t lastPercent = 0; - int32_t thisPercent = 0; +// Returns a new string the caller must free. - (void)icPrivate; - if ((current == 0) && (total == 0)) { - lastPercent = 0; // Reset - } else { - thisPercent = (int32_t)((double)current / (double)total * (double)PERCENT_MAX); - if ((thisPercent != lastPercent) && _indexingFunction) { - lastPercent = thisPercent; - _indexingFunction(thisPercent); - } - } +static char *_indexFileName(const char *filename, const char *indexPath) { + char *name = utilCreateString("%s%c%s.index", indexPath, utilGetPathSeparator(), utilGetLastPathComponent(filename)); - return 0; + utilFixPathSeparators(&name, false); + + return name; } -static void _loadAudio(VideoPlayerT *v, const char *filename, FFMS_Index *index) { - int32_t x = 0; - int32_t count = 0; - const FFMS_AudioProperties *first = NULL; - const FFMS_AudioProperties *props = NULL; - AVFormatContext *fmtCtx = NULL; - AVDictionaryEntry *tag = NULL; +// Opens the audio side of a file (the video file, or the separate audio file of an old framefile) and +// lists its tracks. +static void _loadAudio(VideoPlayerT *v, const char *filename) { + AVDictionaryEntry *tag = NULL; + int32_t x = 0; + int32_t count = 0; - // Count the audio tracks. - for (x = 0; x < FFMS_GetNumTracks(index); x++) { - if (FFMS_GetTrackType(FFMS_GetTrackFromIndex(index, x)) == FFMS_TYPE_AUDIO) { + v->audioFormat = _formatOpen(filename); + if (v->audioFormat == NULL) { + utilDie("Unable to open %s for audio.", filename); + } + if (avformat_find_stream_info(v->audioFormat, NULL) < 0) { + utilDie("Unable to read stream information from %s.", filename); + } + for (x = 0; x < (int32_t)v->audioFormat->nb_streams; x++) { + if (v->audioFormat->streams[x]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { count++; } } if (count == 0) { + _formatClose(&v->audioFormat); return; } - // Now create them. - v->audio = (AudioStreamT *)calloc((size_t)count, sizeof(AudioStreamT)); + v->audio = (AudioTrackT *)calloc((size_t)count, sizeof(AudioTrackT)); if (!v->audio) { utilDie("Unable to allocate audio tracks."); } - for (x = 0; x < FFMS_GetNumTracks(index); x++) { - if (FFMS_GetTrackType(FFMS_GetTrackFromIndex(index, x)) == FFMS_TYPE_AUDIO) { - v->audio[v->audioSourceCount].audioSource = FFMS_CreateAudioSource(filename, x, index, FFMS_DELAY_FIRST_VIDEO_TRACK, &v->errInfo); - if (v->audio[v->audioSourceCount].audioSource == NULL) { - utilDie("%s", v->errInfo.Buffer); + for (x = 0; x < (int32_t)v->audioFormat->nb_streams; x++) { + if (v->audioFormat->streams[x]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { + v->audio[v->audioSourceCount].streamIndex = x; + tag = av_dict_get(v->audioFormat->streams[x]->metadata, "language", NULL, 0); + if (tag != NULL) { + v->audio[v->audioSourceCount].language = strdup(tag->value); } - v->audio[v->audioSourceCount].audioProps = FFMS_GetAudioProperties(v->audio[v->audioSourceCount].audioSource); v->audioSourceCount++; } } - // Every track is fed through one SDL_AudioStream, so they must share a format. - first = v->audio[0].audioProps; - for (x = 1; x < v->audioSourceCount; x++) { - props = v->audio[x].audioProps; - if ((props->SampleFormat != first->SampleFormat) || (props->Channels != first->Channels) || (props->SampleRate != first->SampleRate)) { - utilDie("All audio tracks in %s must share the same sample format, channel count, and rate.", filename); - } + v->audioPacket = av_packet_alloc(); + v->audioFrame = av_frame_alloc(); + if (!v->audioPacket || !v->audioFrame) { + utilDie("Unable to allocate audio decoding buffers."); } - - // Use ffmpeg directly to figure out language IDs for audio tracks - if (avformat_open_input(&fmtCtx, filename, NULL, NULL) >= 0) { - count = 0; - for (x = 0; (x < (int32_t)fmtCtx->nb_streams) && (count < v->audioSourceCount); x++) { - if (fmtCtx->streams[x]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { - tag = av_dict_get(fmtCtx->streams[x]->metadata, "language", NULL, 0); - if (tag != NULL) { - v->audio[count].language = strdup(tag->value); - } - count++; - } - } - avformat_close_input(&fmtCtx); - } - - v->currentAudioTrack = 0; } -// Post-mix hook used once at startup. After the mixer thread has been stalled long enough for the -// device to drain, SDL refills the device as fast as it accepts data: a burst of callbacks a few -// microseconds apart, then one per chunk period. The burst is the queue depth between our callback +// Post-mix hook used once at startup. After the mixer has been stalled long enough for the device +// to drain, SDL refills the device as fast as it accepts data: a burst of callbacks a few +// microseconds apart, then one per chunk period. The burst is the queue depth between the mixer // and the speaker, which is what the audio clock has to subtract. static void _measureDeviceQueue(void *udata, MIX_Mixer *mixer, const SDL_AudioSpec *spec, float *pcm, int32_t samples) { uint64_t now = SDL_GetTicks(); @@ -529,21 +987,137 @@ static void _measureDeviceQueue(void *udata, MIX_Mixer *mixer, const SDL_AudioSp } -static int64_t _msToSamples(VideoPlayerT *v, int64_t ms) { - return (int64_t)((double)ms / MS_PER_SECOND * (double)v->audio[v->currentAudioTrack].audioProps->SampleRate); +// Attaches the platform's hardware decoder to the codec context when it offers one for this codec. +// Failure of any step leaves the context decoding in software. +static void _openHardware(VideoPlayerT *v, const AVCodec *decoder) { + static const enum AVHWDeviceType wanted[] = { +#if defined(_WIN32) + AV_HWDEVICE_TYPE_D3D11VA, + AV_HWDEVICE_TYPE_DXVA2, +#elif defined(__APPLE__) + AV_HWDEVICE_TYPE_VIDEOTOOLBOX, +#else + AV_HWDEVICE_TYPE_VAAPI, + AV_HWDEVICE_TYPE_VDPAU, +#endif + AV_HWDEVICE_TYPE_NONE + }; + const AVCodecHWConfig *config = NULL; + int32_t x = 0; + int32_t i = 0; + + if (!_hardwareDecoding) { + return; + } + for (x = 0; wanted[x] != AV_HWDEVICE_TYPE_NONE; x++) { + for (i = 0; (config = avcodec_get_hw_config(decoder, i)) != NULL; i++) { + if ((config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX) && (config->device_type == wanted[x])) { + if (av_hwdevice_ctx_create(&v->hwDevice, wanted[x], NULL, NULL, 0) < 0) { + utilTrace("Hardware decoding via %s is not available; decoding in software.", av_hwdevice_get_type_name(wanted[x])); + break; + } + v->hwPixelFormat = config->pix_fmt; + v->videoCodec->hw_device_ctx = av_buffer_ref(v->hwDevice); + v->videoCodec->get_format = _selectPixelFormat; + v->videoCodec->opaque = v; + v->hwFrame = av_frame_alloc(); + if (!v->hwFrame) { + utilDie("Unable to allocate the hardware frame."); + } + // The GPU does the work; frame threads would only add latency to every seek. + v->videoCodec->thread_count = 1; + utilTrace("Hardware decoding via %s.", av_hwdevice_get_type_name(wanted[x])); + return; + } + } + } +} + + +// Opens the demuxer and decoder the decoder thread will use. +static void _openVideo(VideoPlayerT *v, const char *filename) { + const AVCodec *decoder = NULL; + AVStream *stream = NULL; + int32_t x = 0; + + v->videoFormat = _formatOpen(filename); + if (v->videoFormat == NULL) { + utilDie("Unable to open %s.", filename); + } + if (avformat_find_stream_info(v->videoFormat, NULL) < 0) { + utilDie("Unable to read stream information from %s.", filename); + } + v->videoStream = av_find_best_stream(v->videoFormat, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0); + if ((v->videoStream < 0) || (decoder == NULL)) { + utilDie("%s has no decodable video.", filename); + } + for (x = 0; x < (int32_t)v->videoFormat->nb_streams; x++) { + v->videoFormat->streams[x]->discard = (x == v->videoStream) ? AVDISCARD_DEFAULT : AVDISCARD_ALL; + } + stream = v->videoFormat->streams[v->videoStream]; + v->videoTimeBase = stream->time_base; + v->width = stream->codecpar->width; + v->height = stream->codecpar->height; + v->fps = av_guess_frame_rate(v->videoFormat, stream, NULL); + if ((v->fps.num <= 0) || (v->fps.den <= 0)) { + v->fps.num = DEFAULT_FPS_NUMERATOR; + v->fps.den = DEFAULT_FPS_DENOMINATOR; + } + + v->videoCodec = avcodec_alloc_context3(decoder); + if (!v->videoCodec || (avcodec_parameters_to_context(v->videoCodec, stream->codecpar) < 0)) { + utilDie("Unable to set up the video decoder for %s.", filename); + } + v->videoCodec->thread_count = 0; // Let libavcodec pick + _openHardware(v, decoder); + if (avcodec_open2(v->videoCodec, decoder, NULL) < 0) { + utilDie("Unable to open the video decoder for %s.", filename); + } + v->videoPacket = av_packet_alloc(); + v->videoFrame = av_frame_alloc(); + if (!v->videoPacket || !v->videoFrame) { + utilDie("Unable to allocate video decoding buffers."); + } + v->nextDecodeFrame = -1; + v->seekKeyframe = 0; +} + + +// Loads a cached frame table if it matches this file. Returns false when the table must be rebuilt. +static bool _readIndexCache(VideoPlayerT *v, const char *indexName, const IndexHeaderT *expected) { + size_t bytes = 0; + char *data = utilReadFile(indexName, &bytes); + IndexHeaderT header; + bool valid = false; + + if (data && (bytes >= sizeof(IndexHeaderT))) { + memcpy(&header, data, sizeof(header)); + valid = (memcmp(header.magic, expected->magic, sizeof(header.magic)) == 0) && (header.version == expected->version) && (header.streamIndex == expected->streamIndex) && (header.fileSize == expected->fileSize) && (header.fileTime == expected->fileTime) && (header.count > 0) && (bytes == sizeof(IndexHeaderT) + sizeof(FrameInfoT) * (size_t)header.count); + } + if (valid) { + v->frameCount = header.count; + v->frames = malloc(sizeof(FrameInfoT) * (size_t)v->frameCount); + if (!v->frames) { + utilDie("Unable to allocate the frame table."); + } + memcpy(v->frames, data + sizeof(IndexHeaderT), sizeof(FrameInfoT) * (size_t)v->frameCount); + } + free(data); + + return valid; } // Tells the author how far a seek may have to decode. Keyframe spacing is a property of the file. static void _reportKeyframes(VideoPlayerT *v, const char *filename) { - int32_t frame = 0; - int32_t lastKeyframe = 0; - int32_t keyframes = 0; - int32_t longestGap = 0; + int64_t frame = 0; + int64_t lastKeyframe = 0; + int64_t keyframes = 0; + int64_t longestGap = 0; double seconds = 0.0; - for (frame = 0; frame < v->videoProps->NumFrames; frame++) { - if (FFMS_GetFrameInfo(v->videoTrackHandle, frame)->KeyFrame) { + for (frame = 0; frame < v->frameCount; frame++) { + if (v->frames[frame].keyframe) { if ((keyframes > 0) && (frame - lastKeyframe > longestGap)) { longestGap = frame - lastKeyframe; } @@ -551,13 +1125,11 @@ static void _reportKeyframes(VideoPlayerT *v, const char *filename) { keyframes++; } } - if (v->videoProps->NumFrames - lastKeyframe > longestGap) { - longestGap = v->videoProps->NumFrames - lastKeyframe; + if (v->frameCount - lastKeyframe > longestGap) { + longestGap = v->frameCount - lastKeyframe; } - if (v->videoProps->FPSNumerator > 0) { - seconds = (double)longestGap * (double)v->videoProps->FPSDenominator / (double)v->videoProps->FPSNumerator; - } - utilTrace("%s: %d frames, %d keyframes, longest gap %d frames (%.1f seconds)", filename, v->videoProps->NumFrames, keyframes, longestGap, seconds); + seconds = (double)longestGap * (double)v->fps.den / (double)v->fps.num; + utilTrace("%s: %" PRId64 " frames, %" PRId64 " keyframes, longest gap %" PRId64 " frames (%.1f seconds)", filename, v->frameCount, keyframes, longestGap, seconds); if (seconds > KEYFRAME_WARN_SECONDS) { utilTrace("Warning: %s has keyframes up to %.1f seconds apart; seeking into that video may stall. Re-encode with a keyframe interval of two seconds or less.", filename, seconds); } @@ -588,12 +1160,49 @@ static void _resetClock(VideoPlayerT *v, uint64_t now) { v->lastCallbackTicks = now; v->audioClockValid = false; MIX_UnlockMixer(_mixer); - // FFMS2 shifted the audio so sample 0 lines up with frame 0, whatever that frame's timestamp is. - v->audioPosition = _msToSamples(v, v->startTime - v->firstFrameTime); - if (v->audioPosition < 0) { - v->audioPosition = 0; + // Video and audio share the container's timeline, so the frame's time is the audio's time. + _audioSeek(v, v->startTime); + } +} + + +// Positions the video demuxer at a keyframe and resets the decoder. Decoder thread only. +static void _seekVideo(VideoPlayerT *v, int64_t keyframe) { + if (av_seek_frame(v->videoFormat, v->videoStream, v->frames[keyframe].pts, AVSEEK_FLAG_BACKWARD) < 0) { + avformat_seek_file(v->videoFormat, v->videoStream, INT64_MIN, 0, INT64_MAX, 0); + keyframe = 0; + } + avcodec_flush_buffers(v->videoCodec); + if (v->packetPending) { + av_packet_unref(v->videoPacket); + v->packetPending = false; + } + // Streams without timestamps are counted from here; the rest are matched by timestamp. + v->nextDecodeFrame = keyframe; + v->seekKeyframe = keyframe; + v->videoDrained = false; +} + + +// libavcodec asks which of the formats it can produce we want; take the hardware one when offered. +static enum AVPixelFormat _selectPixelFormat(AVCodecContext *codec, const enum AVPixelFormat *formats) { + VideoPlayerT *v = (VideoPlayerT *)codec->opaque; + int32_t x = 0; + + for (x = 0; formats[x] != AV_PIX_FMT_NONE; x++) { + if (formats[x] == v->hwPixelFormat) { + return formats[x]; } } + // The hardware declined this stream: fall back to the decoder's first software format. + utilTrace("Video %d: hardware decoder declined the stream; decoding in software.", v->id); + + return formats[0]; +} + + +static int64_t _streamTimeToMs(int64_t ts, AVRational timeBase) { + return av_rescale(ts, (int64_t)timeBase.num * (int64_t)MS_PER_SECOND, timeBase.den); } @@ -604,7 +1213,7 @@ static bool _takeDecodedFrame(VideoPlayerT *v) { SDL_LockMutex(v->lock); if (v->threadError) { - utilDie("%s", v->threadErrInfo.Buffer); + utilDie("Video decoding failed: %s", v->threadErrMsg); } if (v->backReady) { temp = v->front; @@ -649,6 +1258,23 @@ static void _uploadFrame(VideoPlayerT *v) { } +static void _writeIndexCache(VideoPlayerT *v, const char *indexName, const IndexHeaderT *header) { + FILE *out = fopen(indexName, "wb"); + + if (!out) { + utilSay("Warning: Unable to write %s; the video will be indexed again next time.", indexName); + return; + } + if ((fwrite(header, sizeof(IndexHeaderT), 1, out) != 1) || (fwrite(v->frames, sizeof(FrameInfoT), (size_t)v->frameCount, out) != (size_t)v->frameCount)) { + fclose(out); + unlink(indexName); + utilSay("Warning: Unable to write %s; the video will be indexed again next time.", indexName); + return; + } + fclose(out); +} + + int32_t videoGetAudioCalibration(void) { return _audioCalibrationMs; } @@ -665,12 +1291,6 @@ int32_t videoGetAudioLatency(void) { } -// The mixer every sound and video goes through. -MIX_Mixer *videoGetMixer(void) { - return _mixer; -} - - int32_t videoGetAudioTrack(int32_t playerHandle) { return _getPlayer(playerHandle, "videoGetAudioTrack")->currentAudioTrack; } @@ -687,7 +1307,7 @@ int64_t videoGetFrame(int32_t playerHandle) { int64_t videoGetFrameCount(int32_t playerHandle) { - return _getPlayer(playerHandle, "videoGetFrameCount")->videoProps->NumFrames; + return _getPlayer(playerHandle, "videoGetFrameCount")->frameCount; } @@ -727,6 +1347,12 @@ const char *videoGetLanguageDescription(const char *languageCode) { } +// The mixer every sound and video goes through. +MIX_Mixer *videoGetMixer(void) { + return _mixer; +} + + // Reads one pixel of the frame being shown. Returns false if there is no frame yet. bool videoGetPixel(int32_t playerHandle, int32_t x, int32_t y, uint8_t *r, uint8_t *g, uint8_t *b) { VideoPlayerT *v = _getPlayer(playerHandle, "videoGetPixel"); @@ -795,9 +1421,6 @@ int32_t videoGetWidth(int32_t playerHandle) { void videoInit(MIX_Mixer *mixer) { uint64_t started = 0; - // Start FFMS - FFMS_Init(0, 0); - // Fetch mixer settings _mixer = mixer; if (!MIX_GetMixerFormat(_mixer, &_mixSpec)) { @@ -837,21 +1460,17 @@ bool videoIsPlaying(int32_t playerHandle) { } -// audioFilename may be NULL when the audio lives in the video file. rgb players decode to BGRA so -// scripts can read the pixels; everything else stays YUV and is converted by the GPU. // The mixer's audio thread runs the sound and video callbacks; hold this to read what they write. void videoLockAudio(void) { MIX_LockMixer(_mixer); } +// audioFilename may be NULL when the audio lives in the video file. rgb players decode to BGRA so +// scripts can read the pixels; everything else stays YUV and is converted by the GPU. int32_t videoLoad(const char *videoFilename, const char *audioFilename, const char *indexPath, SDL_Renderer *renderer, bool rgb) { - int32_t pixelFormats[2]; - FFMS_Index *vIndex = NULL; - FFMS_Index *aIndex = NULL; - VideoPlayerT *v = NULL; - const FFMS_Frame *frame = NULL; - SDL_PropertiesID playProps = 0; + VideoPlayerT *v = NULL; + SDL_PropertiesID playProps = 0; // Create new videoPlayer v = calloc(1, sizeof(VideoPlayerT)); @@ -860,69 +1479,22 @@ int32_t videoLoad(const char *videoFilename, const char *audioFilename, const ch } // Set some starting values (everything else is zero from calloc) - v->currentAudioTrack = -1; - v->videoTrack = -1; - v->volumeLeft = VIDEO_VOLUME_MAX; - v->volumeRight = VIDEO_VOLUME_MAX; - v->errInfo.Buffer = v->errMsg; - v->errInfo.BufferSize = sizeof(v->errMsg); - v->errInfo.ErrorType = FFMS_ERROR_SUCCESS; - v->errInfo.SubType = FFMS_ERROR_SUCCESS; - v->threadErrInfo = v->errInfo; - v->threadErrInfo.Buffer = v->threadErrMsg; - v->rgb = rgb; - v->requestedFrame = -1; - v->pendingFrame = -1; - v->uploadedFrame = -1; + v->currentAudioTrack = -1; + v->videoStream = -1; + v->volumeLeft = VIDEO_VOLUME_MAX; + v->volumeRight = VIDEO_VOLUME_MAX; + v->rgb = rgb; + v->requestedFrame = -1; + v->pendingFrame = -1; + v->uploadedFrame = -1; + v->front.frame = -1; + v->back.frame = -1; - if (audioFilename) { - vIndex = _createIndex(videoFilename, indexPath, true, false, v); - aIndex = _createIndex(audioFilename, indexPath, false, true, v); - } else { - vIndex = _createIndex(videoFilename, indexPath, true, true, v); - aIndex = vIndex; - audioFilename = videoFilename; - } - - // Find video track - v->videoTrack = FFMS_GetFirstTrackOfType(vIndex, FFMS_TYPE_VIDEO, &v->errInfo); - if (v->videoTrack < 0) { - utilDie("%s", v->errInfo.Buffer); - } - v->videoSource = FFMS_CreateVideoSource(videoFilename, v->videoTrack, vIndex, -1, FFMS_SEEK_NORMAL, &v->errInfo); - if (v->videoSource == NULL) { - utilDie("%s", v->errInfo.Buffer); - } - - // Get video properties. The frame returned here is only valid until the next FFMS_GetFrame. - v->videoProps = FFMS_GetVideoProperties(v->videoSource); - v->videoTrackHandle = FFMS_GetTrackFromVideo(v->videoSource); - v->videoTimeBase = FFMS_GetTimeBase(v->videoTrackHandle); - v->firstFrameTime = (v->videoProps->NumFrames > 0) ? _frameTime(v, 0) : 0; - frame = FFMS_GetFrame(v->videoSource, 0, &v->errInfo); - if (frame == NULL) { - utilDie("%s", v->errInfo.Buffer); - } - v->width = frame->EncodedWidth; - v->height = frame->EncodedHeight; - - // Set up output video format. YUV 4:2:0 is what the decoder produces, so no conversion runs. - pixelFormats[0] = FFMS_GetPixFmt(rgb ? "bgra" : "yuv420p"); - pixelFormats[1] = -1; - if (FFMS_SetOutputFormatV2(v->videoSource, pixelFormats, v->width, v->height, FFMS_RESIZER_BICUBIC, &v->errInfo)) { - utilDie("%s", v->errInfo.Buffer); - } + // Video: demuxer, frame table, decoder. + _openVideo(v, videoFilename); + _buildFrameTable(v, videoFilename, indexPath); _reportKeyframes(v, videoFilename); - // Find audio track(s) - _loadAudio(v, audioFilename, aIndex); - - // Indicies are now part of audioSource & videoSource, so release these - if (aIndex != vIndex) { - FFMS_DestroyIndex(aIndex); - } - FFMS_DestroyIndex(vIndex); - // Create video texture v->videoTexture = SDL_CreateTexture(renderer, rgb ? SDL_PIXELFORMAT_BGRA32 : SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING, v->width, v->height); if (v->videoTexture == NULL) { @@ -944,59 +1516,15 @@ int32_t videoLoad(const char *videoFilename, const char *audioFilename, const ch utilDie("%s", SDL_GetError()); } - // Do we have audio? + // Audio: a mixer track that never halts, fed from its own demuxer on the main thread. + _loadAudio(v, audioFilename ? audioFilename : videoFilename); if (v->audioSourceCount > 0) { - // Determine audio format - switch (v->audio[0].audioProps->SampleFormat) { - case FFMS_FMT_U8: - v->audioSpec.format = SDL_AUDIO_U8; - v->audioSampleBytes = 1; - break; - - case FFMS_FMT_S16: - v->audioSpec.format = SDL_AUDIO_S16; - v->audioSampleBytes = 2; - break; - - case FFMS_FMT_S32: - v->audioSpec.format = SDL_AUDIO_S32; - v->audioSampleBytes = 4; - break; - - case FFMS_FMT_FLT: - v->audioSpec.format = SDL_AUDIO_F32; - v->audioSampleBytes = 4; - break; - - default: - utilDie("Unknown audio sample format."); - } - if (v->audio[0].audioProps->Channels > AUDIO_CHANNELS_MAX) { - utilDie("Only mono and stereo audio are supported."); - } - v->audioSpec.channels = v->audio[0].audioProps->Channels; - v->audioSpec.freq = v->audio[0].audioProps->SampleRate; - - // The stream converts decoded audio to the mixer's format; the track pulls from it. - v->audioStream = SDL_CreateAudioStream(&v->audioSpec, &_mixSpec); - if (!v->audioStream) { - utilDie("%s", SDL_GetError()); - } - - // Create a buffer to read audio into before conversion - v->audioSampleSize = v->audioSampleBytes * v->audio[0].audioProps->Channels; - v->audioBufferSize = v->audioSampleSize * AUDIO_SAMPLE_PREREAD; - v->audioBuffer = (uint8_t *)malloc((size_t)v->audioBufferSize); - if (!v->audioBuffer) { - utilDie("Unable to allocate %" PRId64 " byte audio buffer.", v->audioBufferSize); - } - - // A mixer track that never halts: it goes quiet when the stream runs dry and resumes as data arrives. v->track = MIX_CreateTrack(_mixer); if (!v->track) { utilDie("%s", SDL_GetError()); } - if (!MIX_SetTrackAudioStream(v->track, v->audioStream) || !MIX_SetTrackRawCallback(v->track, _trackMixed, v)) { + _audioSelectTrack(v, 0); + if (!MIX_SetTrackRawCallback(v->track, _trackMixed, v)) { utilDie("%s", SDL_GetError()); } playProps = SDL_CreateProperties(); @@ -1046,14 +1574,12 @@ void videoQuit(void) { HASH_ITER(hh, _videoPlayerHash, v, t) { videoUnload(v->id); } - - FFMS_Deinit(); } void videoSeek(int32_t playerHandle, int64_t seekFrame) { VideoPlayerT *v = _getPlayer(playerHandle, "videoSeek"); - int64_t count = v->videoProps->NumFrames; + int64_t count = v->frameCount; // Wrap into range. if (count > 0) { @@ -1077,6 +1603,12 @@ void videoSetAudioDelay(int32_t milliseconds) { } +// Chosen before any video loads; existing players keep whatever they opened with. +void videoSetHardwareDecoding(bool enabled) { + _hardwareDecoding = enabled; +} + + void videoSetAudioTrack(int32_t playerHandle, int32_t track) { VideoPlayerT *v = _getPlayer(playerHandle, "videoSetAudioTrack"); @@ -1084,22 +1616,16 @@ void videoSetAudioTrack(int32_t playerHandle, int32_t track) { utilDie("Invalid audio track %d in videoSetAudioTrack.", track); } if (track != v->currentAudioTrack) { - v->currentAudioTrack = track; + _audioSelectTrack(v, track); // Drop the queued audio from the old track and realign. v->resetTime = true; } } -void videoSetIndexCallback(VideoIndexingCallbackT callback) { - _indexingFunction = callback; -} - - void videoSetVolume(int32_t playerHandle, int32_t leftPercent, int32_t rightPercent) { - VideoPlayerT *v = _getPlayer(playerHandle, "videoSetVolume"); - - MIX_StereoGains gains; + VideoPlayerT *v = _getPlayer(playerHandle, "videoSetVolume"); + MIX_StereoGains gains; v->volumeLeft = leftPercent; v->volumeRight = rightPercent; @@ -1120,17 +1646,6 @@ void videoUnload(int32_t playerHandle) { VideoPlayerT *v = _getPlayer(playerHandle, "videoUnload"); int32_t x = 0; - if (v->audioSourceCount > 0) { - MIX_DestroyTrack(v->track); - SDL_DestroyAudioStream(v->audioStream); - free(v->audioBuffer); - for (x = 0; x < v->audioSourceCount; x++) { - free(v->audio[x].language); - FFMS_DestroyAudioSource(v->audio[x].audioSource); - } - free(v->audio); - } - // Stop the decoder before touching anything it uses. SDL_LockMutex(v->lock); v->quitThread = true; @@ -1140,13 +1655,33 @@ void videoUnload(int32_t playerHandle) { SDL_DestroyCondition(v->wake); SDL_DestroyMutex(v->lock); for (x = 0; x < PLANE_COUNT; x++) { - free(v->front.data[x]); - free(v->back.data[x]); + av_free(v->front.data[x]); + av_free(v->back.data[x]); } - - FFMS_DestroyVideoSource(v->videoSource); + sws_freeContext(v->sws); + av_frame_free(&v->hwFrame); + av_frame_free(&v->videoFrame); + av_packet_free(&v->videoPacket); + avcodec_free_context(&v->videoCodec); + av_buffer_unref(&v->hwDevice); + _formatClose(&v->videoFormat); + free(v->frames); SDL_DestroyTexture(v->videoTexture); + if (v->audioSourceCount > 0) { + MIX_DestroyTrack(v->track); + SDL_DestroyAudioStream(v->audioStream); + _audioCloseTrack(v); + av_frame_free(&v->audioFrame); + av_packet_free(&v->audioPacket); + _formatClose(&v->audioFormat); + for (x = 0; x < v->audioSourceCount; x++) { + free(v->audio[x].language); + } + free(v->audio); + free(v->audioBuffer); + } + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" HASH_DEL(_videoPlayerHash, v); @@ -1157,11 +1692,11 @@ void videoUnload(int32_t playerHandle) { // Advances playback to match the audio clock (or the wall clock for silent videos). Returns the frame now on the texture. int64_t videoUpdate(int32_t playerHandle, SDL_Texture **texture) { - VideoPlayerT *v = _getPlayer(playerHandle, "videoUpdate"); - uint64_t now = SDL_GetTicks(); - int64_t elapsed = 0; - int64_t count = v->videoProps->NumFrames; - int64_t next = 0; + VideoPlayerT *v = _getPlayer(playerHandle, "videoUpdate"); + uint64_t now = SDL_GetTicks(); + int64_t elapsed = 0; + int64_t count = v->frameCount; + int64_t next = 0; int64_t lastDuration = 0; if (v->resetTime) { @@ -1182,7 +1717,7 @@ int64_t videoUpdate(int32_t playerHandle, SDL_Texture **texture) { } // Past the end of the last frame? Loop. if (next >= count) { - lastDuration = (int64_t)(MS_PER_SECOND * (double)v->videoProps->FPSDenominator / (double)v->videoProps->FPSNumerator); + lastDuration = (int64_t)(MS_PER_SECOND * (double)v->fps.den / (double)v->fps.num); if (elapsed >= _frameTime(v, count - 1) + lastDuration) { v->frame = 0; _resetClock(v, now); diff --git a/src/videoPlayer.h b/src/videoPlayer.h index 208c3c030..551b55b0f 100644 --- a/src/videoPlayer.h +++ b/src/videoPlayer.h @@ -35,9 +35,6 @@ #define VIDEO_AUDIO_DELAY_MAX 1000 // Milliseconds either way -typedef void (*VideoIndexingCallbackT)(int32_t percent); - - int32_t videoGetAudioCalibration(void); int32_t videoGetAudioDelay(void); int32_t videoGetAudioLatency(void); @@ -64,7 +61,7 @@ void videoSeek(int32_t playerHandle, int64_t seekFrame); void videoSetAudioCalibration(int32_t milliseconds); void videoSetAudioDelay(int32_t milliseconds); void videoSetAudioTrack(int32_t playerHandle, int32_t track); -void videoSetIndexCallback(VideoIndexingCallbackT callback); +void videoSetHardwareDecoding(bool enabled); void videoSetVolume(int32_t playerHandle, int32_t leftPercent, int32_t rightPercent); void videoUnlockAudio(void); void videoUnload(int32_t playerHandle); diff --git a/thirdparty/bzip2/.appveyor.yml b/thirdparty/bzip2/.appveyor.yml deleted file mode 100644 index fcf0bcef2..000000000 --- a/thirdparty/bzip2/.appveyor.yml +++ /dev/null @@ -1,83 +0,0 @@ -environment: - matrix: - - - COMPILER: MSVC2019 - PLATFORM: x86 - CC: cl.exe - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - CMAKE_GENERATOR: NMake Makefiles - - - COMPILER: MSVC2019 - PLATFORM: amd64 - CC: cl.exe - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - CMAKE_GENERATOR: NMake Makefiles - - - COMPILER: MSVC2017 - PLATFORM: x86 - CC: cl.exe - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - CMAKE_GENERATOR: NMake Makefiles - - - COMPILER: MSVC2017 - PLATFORM: amd64 - CC: cl.exe - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - CMAKE_GENERATOR: NMake Makefiles - - - COMPILER: MSVC2015 - PLATFORM: x86 - CC: cl.exe - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - CMAKE_GENERATOR: NMake Makefiles - - - COMPILER: MSVC2015 - PLATFORM: amd64 - CC: cl.exe - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - CMAKE_GENERATOR: NMake Makefiles - - - COMPILER: GCC - ARCH: 32 - CC: gcc.exe - CMAKE_GENERATOR: MinGW Makefiles - - - COMPILER: GCC - ARCH: 64 - CC: gcc.exe - CMAKE_GENERATOR: MinGW Makefiles - -install: - -- if [%COMPILER%]==[MSVC2015] if [%PLATFORM%]==[amd64] call "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64 -- if [%COMPILER%]==[MSVC2015] if [%PLATFORM%]==[amd64] call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86_amd64 -- if [%COMPILER%]==[MSVC2015] if [%PLATFORM%]==[x86] call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86 - -- if [%COMPILER%]==[MSVC2017] if [%PLATFORM%]==[amd64] call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat" -- if [%COMPILER%]==[MSVC2017] if [%PLATFORM%]==[x86] call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars32.bat" - -- if [%COMPILER%]==[MSVC2019] call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" %PLATFORM% - -- if [%COMPILER%]==[GCC] del /F /Q "C:\Program Files\Git\usr\bin\sh.exe" -- if [%COMPILER%]==[GCC] set "PATH=C:\msys64\mingw%ARCH%\bin;%PATH%" - -build_script: -# Clone the files for the large test suite -# FIXME: git submodule isn't working with the MinGW environment: -# fatal: 'submodule' appears to be a git command, but we were not able to execute it. Maybe git-submodule is broken? -- if not [%COMPILER%]==[GCC] git submodule update --init --recursive - -- mkdir build -- cd build - -- cmake -G "%CMAKE_GENERATOR%" -DCMAKE_BUILD_TYPE=Release .. -- cmake --build . --target install - -test_script: -- ctest -V -C Release - -# Enable this to be able to login to the build worker. You can use the -# `remmina` program in Ubuntu, use the login information that the line below -# prints into the log. -#on_finish: -#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) diff --git a/thirdparty/bzip2/.gitattributes b/thirdparty/bzip2/.gitattributes deleted file mode 100644 index 2253303d2..000000000 --- a/thirdparty/bzip2/.gitattributes +++ /dev/null @@ -1,16 +0,0 @@ -# Handle line endings automatically for files detected as text -# and leave all files detected as binary untouched. -* text=auto - -# -# The above will handle all files NOT found below -# - -# Files that should be left untouched (binary is macro for -text -diff) -*.ref binary - -# -# Exclude files from exporting -# -.gitattributes export-ignore -.gitignore export-ignore diff --git a/thirdparty/bzip2/.gitignore b/thirdparty/bzip2/.gitignore deleted file mode 100644 index d496125f1..000000000 --- a/thirdparty/bzip2/.gitignore +++ /dev/null @@ -1,32 +0,0 @@ -# cmake -CMakeCache.txt -CMakeFiles/ -cmake_install.cmake -install_manifest.txt -CTestTestfile.cmake -build.ninja -rules.ninja -.ninja_deps -.ninja_log -lib*.dylib -lib*.so -lib*.so.* -lib*.a - -# example build directories -build -builddir - -# vscode config directory -.vscode - -# Windows build outputs -*.dll -*.exe -*.exp -*.lib -*.obj -*.res - -# python unit tests -__pycache__ diff --git a/thirdparty/bzip2/.gitlab-ci.yml b/thirdparty/bzip2/.gitlab-ci.yml deleted file mode 100644 index 455e65795..000000000 --- a/thirdparty/bzip2/.gitlab-ci.yml +++ /dev/null @@ -1,204 +0,0 @@ -# CI setup based on https://gitlab.gnome.org/GNOME/librsvg/blob/master/.gitlab-ci.yml - -variables: - AMD64_DEBIAN_TESTING: debian:testing - AMD64_UBUNTU_BIONIC: ubuntu:bionic - AMD64_FEDORA_LATEST: "registry.fedoraproject.org/fedora:35" - AMD64_FEDORA_RAWHIDE: "registry.fedoraproject.org/fedora:rawhide" - AMD64_OPENSUSE_LEAP: opensuse/leap - AMD64_OPENSUSE_TUMBLEWEED: opensuse/tumbleweed - - I386_UBUNTU_BIONIC: "i386/ubuntu:bionic" - - GIT_SUBMODULE_STRATEGY: recursive - -stages: - - test - -.meson_test: - stage: test - script: - - meson builddir - - ninja -C builddir - - meson test -C builddir --print-errorlogs - after_script: - - cp builddir/meson-logs/meson-log.txt . - - rm -rf builddir - artifacts: - paths: - - "meson-log.txt" - -.cmake_test_debug: - stage: test - script: - - mkdir builddir && cd builddir - - cmake .. -DCMAKE_BUILD_TYPE="Debug" -D ENABLE_SHARED_LIB=ON -D ENABLE_STATIC_LIB=OFF - - cmake --build . - - make check - after_script: - - cp builddir/CMakeFiles/CMakeOutput.log . - - rm -rf builddir - artifacts: - paths: - - "CMakeOutput.log" - -.cmake_test: - stage: test - script: - - mkdir builddir && cd builddir - - cmake .. -DCMAKE_BUILD_TYPE="Release" -D ENABLE_SHARED_LIB=ON -D ENABLE_STATIC_LIB=OFF - - cmake --build . - - make check - after_script: - - cp builddir/CMakeFiles/CMakeOutput.log . - - rm -rf builddir - artifacts: - paths: - - "CMakeOutput.log" - -.cmake_test_shared_static: - stage: test - script: - - mkdir builddir && cd builddir - - cmake .. -DCMAKE_BUILD_TYPE="Release" -D ENABLE_SHARED_LIB=ON -D ENABLE_STATIC_LIB=ON - - cmake --build . - - make check - after_script: - - cp builddir/CMakeFiles/CMakeOutput.log . - - rm -rf builddir - artifacts: - paths: - - "CMakeOutput.log" - -.cmake_test_static_only: - stage: test - script: - - mkdir builddir && cd builddir - - cmake .. -DCMAKE_BUILD_TYPE="Release" -D ENABLE_SHARED_LIB=OFF -D ENABLE_STATIC_LIB=ON - - cmake --build . - - make check - after_script: - - cp builddir/CMakeFiles/CMakeOutput.log . - - rm -rf builddir - artifacts: - paths: - - "CMakeOutput.log" - -debian:testing:meson: - extends: ".meson_test" - image: $AMD64_DEBIAN_TESTING - before_script: - - apt-get update -y - - apt-get install -y gcc meson python3-distutils python3-pytest valgrind - -debian:testing:cmake:debug: - extends: ".cmake_test_debug" - image: $AMD64_DEBIAN_TESTING - before_script: - - apt-get update -y - - apt-get install -y gcc make python3-pytest cmake valgrind - -debian:testing:cmake: - extends: ".cmake_test" - image: $AMD64_DEBIAN_TESTING - before_script: - - apt-get update -y - - apt-get install -y gcc make python3-pytest cmake valgrind - -debian:testing:cmake:shared_static: - extends: ".cmake_test_shared_static" - image: $AMD64_DEBIAN_TESTING - before_script: - - apt-get update -y - - apt-get install -y gcc make python3-pytest cmake valgrind - -debian:testing:cmake:static_only: - extends: ".cmake_test_static_only" - image: $AMD64_DEBIAN_TESTING - before_script: - - apt-get update -y - - apt-get install -y gcc make python3-pytest cmake valgrind - -ubuntu:bionic:meson: - extends: ".meson_test" - image: $AMD64_UBUNTU_BIONIC - before_script: - - apt-get update -y - - apt-get install -y gcc python3-pip ninja-build valgrind - - pip3 install meson pytest - -ubuntu:bionic:cmake: - extends: ".cmake_test" - image: $AMD64_UBUNTU_BIONIC - before_script: - - apt-get update -y - - apt-get install -y gcc make python3-pip valgrind - - pip3 install --upgrade pip - - pip3 install pytest cmake - -ubuntu:bionic:i386:meson: - extends: ".meson_test" - image: $I386_UBUNTU_BIONIC - before_script: - - apt-get update -y - - apt-get install -y gcc python3-pip ninja-build valgrind - - pip3 install meson pytest - -ubuntu:bionic:i386:cmake: - extends: ".cmake_test" - image: $I386_UBUNTU_BIONIC - before_script: - - apt-get update -y - - apt-get install -y gcc make python3-pip valgrind - - pip3 install --upgrade pip - - pip3 install pytest cmake - -fedora:30:meson: - extends: ".meson_test" - image: $AMD64_FEDORA_LATEST - before_script: - - dnf install -y gcc meson python3-pytest valgrind - -fedora:30:cmake: - extends: ".cmake_test" - image: $AMD64_FEDORA_LATEST - before_script: - - dnf install -y gcc cmake python3-pytest valgrind - -fedora:rawhide:meson: - extends: ".meson_test" - image: $AMD64_FEDORA_RAWHIDE - before_script: - - dnf install -y gcc meson python3-pytest valgrind - -fedora:rawhide:cmake: - extends: ".cmake_test" - image: $AMD64_FEDORA_RAWHIDE - before_script: - - dnf install -y gcc cmake python3-pytest valgrind - -opensuse/leap:meson: - extends: ".meson_test" - image: $AMD64_OPENSUSE_LEAP - before_script: - - zypper install -y gcc ninja python3-pip valgrind - - pip3 install meson pytest - -opensuse/leap:cmake: - extends: ".cmake_test" - image: $AMD64_OPENSUSE_LEAP - before_script: - - zypper install -y gcc cmake python3-pip valgrind - - pip3 install pytest - -opensuse/tumbleweed:meson: - extends: ".meson_test" - image: $AMD64_OPENSUSE_TUMBLEWEED - before_script: - - zypper install -y gcc meson python3-pytest valgrind - -opensuse/tumbleweed:cmake: - extends: ".cmake_test" - image: $AMD64_OPENSUSE_TUMBLEWEED - before_script: - - zypper install -y gcc cmake python3-pytest valgrind diff --git a/thirdparty/bzip2/AUTHORS b/thirdparty/bzip2/AUTHORS deleted file mode 100644 index 8a61bd61f..000000000 --- a/thirdparty/bzip2/AUTHORS +++ /dev/null @@ -1,19 +0,0 @@ -Alson van der Meulen -Bo Lindbergh -Bo Thorsen -Jeremy Fusco -Joerg Prante -Jorj Bauer -Juan Pedro Vallejo -Julian Seward -Leland Lucius -Marty Leisner -Matthias Krings -Michael Carmack -Mikolaj Izdebski -Nicholas Nethercote -Rich Ireland -Robert Linden -Solar Designer -Trond Eivind Glomsrod -Volker Schmidt diff --git a/thirdparty/bzip2/CMakeLists.txt b/thirdparty/bzip2/CMakeLists.txt deleted file mode 100644 index c4b0b6efc..000000000 --- a/thirdparty/bzip2/CMakeLists.txt +++ /dev/null @@ -1,472 +0,0 @@ -cmake_minimum_required(VERSION 3.12) - -project(bzip2 - VERSION 1.1.0 - DESCRIPTION "This Bzip2/libbz2 a program and library for lossless block-sorting data compression." - LANGUAGES C) - -# See versioning rule: -# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html -# -# KEEP THESE IN SYNC WITH meson.build OR STUFF WILL BREAK! -set(LT_CURRENT 1) -set(LT_REVISION 9) -set(LT_AGE 0) - -set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH}) -include(Version) -include(SymLink) - -set(BZ_VERSION ${PROJECT_VERSION}) -configure_file ( - ${PROJECT_SOURCE_DIR}/bz_version.h.in - ${PROJECT_BINARY_DIR}/bz_version.h -) -include_directories(${PROJECT_BINARY_DIR}) - -math(EXPR LT_SOVERSION "${LT_CURRENT} - ${LT_AGE}") -set(LT_VERSION "${LT_SOVERSION}.${LT_AGE}.${LT_REVISION}") -set(PACKAGE_VERSION ${PROJECT_VERSION}) -HexVersion(PACKAGE_VERSION_NUM ${PROJECT_VERSION_MAJOR} ${PROJECT_VERSION_MINOR} ${PROJECT_VERSION_PATCH}) - -set(ENABLE_APP_DEFAULT ON) -set(ENABLE_TESTS_DEFAULT ON) -set(ENABLE_EXAMPLES_DEFAULT OFF) -set(ENABLE_DOCS_DEFAULT OFF) -include(CMakeOptions.txt) - -if(ENABLE_LIB_ONLY AND (ENABLE_APP OR ENABLE_EXAMPLES)) - # Remember when disabled options are disabled for later diagnostics. - set(ENABLE_LIB_ONLY_DISABLED_OTHERS 1) -else() - set(ENABLE_LIB_ONLY_DISABLED_OTHERS 0) -endif() -if(ENABLE_LIB_ONLY) - set(ENABLE_APP OFF) - set(ENABLE_EXAMPLES OFF) -endif() - -# Do not disable assertions based on CMAKE_BUILD_TYPE. -foreach(_build_type Release MinSizeRel RelWithDebInfo) - foreach(_lang C) - string(TOUPPER CMAKE_${_lang}_FLAGS_${_build_type} _var) - string(REGEX REPLACE "(^|)[/-]D *NDEBUG($|)" " " ${_var} "${${_var}}") - endforeach() -endforeach() - -# Support the latest c++ standard available. -include(ExtractValidFlags) - -if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the build type" FORCE) - - # Include "None" as option to disable any additional (optimization) flags, - # relying on just CMAKE_C_FLAGS and CMAKE_CXX_FLAGS (which are empty by - # default). These strings are presented in cmake-gui. - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS - None Debug Release MinSizeRel RelWithDebInfo) -endif() - -include(GNUInstallDirs) - -if(ENABLE_TESTS OR ENABLE_DOCS) - # For test scripts and documentation - find_package(Python3 REQUIRED) -endif() - -# -# Find other Test dependencies -# - pytest (optional) -# - unittest (if pytest not present) -# - valgrind (optional, Linux only) -# -if(ENABLE_TESTS) - # Try finding pytest from the PATH - execute_process( - COMMAND pytest --version - RESULT_VARIABLE PYTEST_EXIT_CODE - ERROR_QUIET OUTPUT_QUIET - ) - - if(${PYTEST_EXIT_CODE} EQUAL 0) - # pytest found in the path. - set(PythonTest_COMMAND "pytest;-v") - else() - # Not in the path, try using: python3 -m pytest - execute_process( - COMMAND ${Python3_EXECUTABLE} -m pytest --version - RESULT_VARIABLE PYTEST_MODULE_EXIT_CODE - ERROR_QUIET OUTPUT_QUIET - ) - - if(${PYTEST_MODULE_EXIT_CODE} EQUAL 0) - # pytest isn't in the path, but the Python 3 we found has it. - set(PythonTest_COMMAND "${Python3_EXECUTABLE};-m;pytest;-v") - else() - # pytest couldn't be found, verify that we can at least use: python3 -m unittest - execute_process( - COMMAND ${Python3_EXECUTABLE} -m unittest --help - RESULT_VARIABLE UNITTEST_MODULE_EXIT_CODE - ERROR_QUIET OUTPUT_QUIET - ) - - if(${UNITTEST_MODULE_EXIT_CODE} EQUAL 0) - # No pytest :-(, but we'll get by with unittest - message("Python 3 package 'pytest' is not installed for ${Python3_EXECUTABLE} and is not available in your PATH.") - message("Failed unit tests will be easier to read if you install pytest.") - message("Eg: python3 -m pip install --user pytest") - - set(PythonTest_COMMAND "${Python3_EXECUTABLE};-m;unittest;--verbose") - else() - # No unittest either! - # Some weird Python installations do exist that lack standard modules like unittest. - # Let's make sure these folks know the Python 3 install we found won't cut it. - message("Python 3 found: ${Python3_EXECUTABLE}, but it is missing the unittest module (wierd!).") - message(FATAL_ERROR "The tests won't work with this Python installation. You can disable the tests by reconfiguring with: -D ENABLE_TESTS=OFF") - endif() - endif() - endif() - - # Check for valgrind. If it exists, we'll enable extra tests that use valgrind. - if(CMAKE_SYSTEM_NAME STREQUAL "Linux") - find_package(Valgrind) - endif() -endif() - -# Checks for header files. -include(CheckIncludeFile) -check_include_file(arpa/inet.h HAVE_ARPA_INET_H) -check_include_file(fcntl.h HAVE_FCNTL_H) -check_include_file(inttypes.h HAVE_INTTYPES_H) -check_include_file(limits.h HAVE_LIMITS_H) -check_include_file(netdb.h HAVE_NETDB_H) -check_include_file(netinet/in.h HAVE_NETINET_IN_H) -check_include_file(pwd.h HAVE_PWD_H) -check_include_file(sys/socket.h HAVE_SYS_SOCKET_H) -check_include_file(sys/time.h HAVE_SYS_TIME_H) -check_include_file(syslog.h HAVE_SYSLOG_H) -check_include_file(time.h HAVE_TIME_H) -check_include_file(unistd.h HAVE_UNISTD_H) - -include(CheckTypeSize) -# Checks for typedefs, structures, and compiler characteristics. -# AC_TYPE_SIZE_T -check_type_size("ssize_t" SIZEOF_SSIZE_T) -if(NOT SIZEOF_SSIZE_T) - # ssize_t is a signed type in POSIX storing at least -1. - # Set it to "int" to match the behavior of AC_TYPE_SSIZE_T (autotools). - set(ssize_t int) -endif() - -include(CheckStructHasMember) -check_struct_has_member("struct tm" tm_gmtoff time.h HAVE_STRUCT_TM_TM_GMTOFF) - -# Checks for library functions. -include(CheckFunctionExists) -check_function_exists(_Exit HAVE__EXIT) -check_function_exists(accept4 HAVE_ACCEPT4) -check_function_exists(mkostemp HAVE_MKOSTEMP) - -include(CheckSymbolExists) -# XXX does this correctly detect initgroups (un)availability on cygwin? -check_symbol_exists(initgroups grp.h HAVE_DECL_INITGROUPS) -if(NOT HAVE_DECL_INITGROUPS AND HAVE_UNISTD_H) - # FreeBSD declares initgroups() in unistd.h - check_symbol_exists(initgroups unistd.h HAVE_DECL_INITGROUPS2) - if(HAVE_DECL_INITGROUPS2) - set(HAVE_DECL_INITGROUPS 1) - endif() -endif() - -set(WARNCFLAGS) -if(CMAKE_C_COMPILER_ID MATCHES "MSVC") - if(ENABLE_WERROR) - set(WARNCFLAGS /WX) - endif() -else() - if(ENABLE_WERROR) - extract_valid_c_flags(WARNCFLAGS -Werror) - endif() - - # For C compiler - # Please keep this list in sync with meson.build - extract_valid_c_flags(WARNCFLAGS - -Wall - -Wextra - -Wmissing-prototypes - -Wstrict-prototypes - -Wmissing-declarations - -Wpointer-arith - -Wdeclaration-after-statement - -Wformat-security - -Wwrite-strings - -Wshadow - -Winline - -Wnested-externs - -Wfloat-equal - -Wundef - -Wendif-labels - -Wempty-body - -Wcast-align - -Wclobbered - -Wvla - -Wpragmas - -Wunreachable-code - -Waddress - -Wattributes - -Wdiv-by-zero - -Wshorten-64-to-32 - -Wconversion - -Wextended-offsetof - -Wformat-nonliteral - -Wlanguage-extension-token - -Wmissing-field-initializers - -Wmissing-noreturn - -Wmissing-variable-declarations - # -Wpadded # Not used because we cannot change public structs - -Wsign-conversion - # -Wswitch-enum # Not used because this basically disallows default case - -Wunreachable-code-break - -Wunused-macros - -Wunused-parameter - -Wredundant-decls - -Wheader-guard - -Wno-format-nonliteral # This is required because we pass format string as "const char*. - ) -endif() - -if(ENABLE_DEBUG) - set(DEBUGBUILD 1) -endif() - -#add_definitions(-DHAVE_CONFIG_H) -#configure_file(cmakeconfig.h.in config.h) - -# autotools-compatible names -# Sphinx expects relative paths in the .rst files. Use the fact that the files -# below are all one directory level deep. -file(RELATIVE_PATH top_srcdir ${CMAKE_CURRENT_BINARY_DIR}/dir ${CMAKE_CURRENT_SOURCE_DIR}) -file(RELATIVE_PATH top_builddir ${CMAKE_CURRENT_BINARY_DIR}/dir ${CMAKE_CURRENT_BINARY_DIR}) -set(abs_top_srcdir ${CMAKE_CURRENT_SOURCE_DIR}) -set(abs_top_builddir ${CMAKE_CURRENT_BINARY_DIR}) -# bzip2.pc (pkg-config file) -set(prefix ${CMAKE_INSTALL_PREFIX}) -set(exec_prefix ${CMAKE_INSTALL_PREFIX}) -set(bindir ${CMAKE_INSTALL_FULL_BINDIR}) -set(sbindir ${CMAKE_INSTALL_FULL_SBINDIR}) -set(libdir ${CMAKE_INSTALL_FULL_LIBDIR}) -set(includedir ${CMAKE_INSTALL_FULL_INCLUDEDIR}) -set(VERSION ${PACKAGE_VERSION}) - -configure_file( - bzip2.pc.in - ${CMAKE_CURRENT_BINARY_DIR}/bzip2.pc - @ONLY) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/bzip2.pc - DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) - -# -# The build targets. -# In a larger project, the following would be in subdirectories and -# These targets would be included with `add_subdirectory()` -# -set(BZ2_SOURCES - blocksort.c - huffman.c - crctable.c - randtable.c - compress.c - decompress.c - bzlib.c) - -# The bz2 OBJECT-library, required for bzip2, bzip2recover. -add_library(bz2_ObjLib OBJECT) -target_sources(bz2_ObjLib - PRIVATE ${BZ2_SOURCES} - PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/bzlib_private.h - INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/bzlib.h) - -# Windows resource file -set(BZ2_RES "") -if(WIN32) - configure_file( - version.rc.in - ${CMAKE_CURRENT_BINARY_DIR}/version.rc - @ONLY) - - set(BZ2_RES ${CMAKE_CURRENT_BINARY_DIR}/version.rc) -endif() - -if(ENABLE_SHARED_LIB) - # The libbz2 shared library. - add_library(bz2 SHARED ${BZ2_RES}) - target_sources(bz2 - PRIVATE ${BZ2_SOURCES} - ${CMAKE_CURRENT_SOURCE_DIR}/libbz2.def - PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/bzlib_private.h - INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/bzlib.h) - - # Always use '-fPIC'/'-fPIE' option for shared libraries. - set_property(TARGET bz2 PROPERTY POSITION_INDEPENDENT_CODE ON) - - set_target_properties(bz2 PROPERTIES - COMPILE_FLAGS "${WARNCFLAGS}" - VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION}) - install(TARGETS bz2 DESTINATION ${CMAKE_INSTALL_LIBDIR}) - install(FILES bzlib.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) - - if(USE_OLD_SONAME) - # Hack to support the old libbz2.so.1.0 version by including an extra copy. - # Technically the old SONAME is not libtool compatible. - # This hack is to support binary compatibility with libbz2 in some distro packages. - if(UNIX AND NOT APPLE) - add_library(bz2_old_soname SHARED ${BZ2_RES}) - target_sources(bz2_old_soname - PRIVATE ${BZ2_SOURCES} - ${CMAKE_CURRENT_SOURCE_DIR}/libbz2.def - PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/bzlib_private.h - INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/bzlib.h - ) - set_target_properties(bz2_old_soname PROPERTIES - COMPILE_FLAGS "${WARNCFLAGS}" - VERSION ${LT_SOVERSION}.${LT_AGE} SOVERSION ${LT_SOVERSION}.${LT_AGE} - OUTPUT_NAME bz2 - ) - install(TARGETS bz2_old_soname DESTINATION ${CMAKE_INSTALL_LIBDIR}) - endif() - endif() -endif() - -if(ENABLE_STATIC_LIB) - # The libbz2 static library. - add_library(bz2_static STATIC) - target_sources(bz2_static - PRIVATE ${BZ2_SOURCES} - PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/bzlib_private.h - INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/bzlib.h) - - # Use '-fPIC'/'-fPIE' option for static libraries by default. - # You may build with ENABLE_STATIC_LIB_IS_PIC=OFF to disable PIC for the static library. - if(ENABLE_STATIC_LIB_IS_PIC) - set_property(TARGET bz2_static PROPERTY POSITION_INDEPENDENT_CODE ON) - endif() - - set_target_properties(bz2_static PROPERTIES - COMPILE_FLAGS "${WARNCFLAGS}" - VERSION ${LT_VERSION} - SOVERSION ${LT_SOVERSION} - ARCHIVE_OUTPUT_NAME bz2_static) - target_compile_definitions(bz2_static PUBLIC BZ2_STATICLIB) - install(TARGETS bz2_static DESTINATION ${CMAKE_INSTALL_LIBDIR}) - install(FILES bzlib.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) -endif() - -if(ENABLE_APP) - # The bzip2 executable. - add_executable(bzip2) - target_sources(bzip2 - PRIVATE bzip2.c) - target_link_libraries(bzip2 - PRIVATE bz2_ObjLib) - if(WIN32) - target_compile_definitions(bzip2 PUBLIC BZ_LCCWIN32 BZ_UNIX=0) - else() - target_compile_definitions(bzip2 PUBLIC BZ_LCCWIN32=0 BZ_UNIX) - endif() - install(TARGETS bzip2 DESTINATION ${CMAKE_INSTALL_BINDIR}) - - # Create bzip2 copies bzcat and bunzip. - # The default behavior is altered in bzip2.c code by checking the program name. - install_target_symlink(bzip2 bzcat) - install_target_symlink(bzip2 bunzip) - - # The bzip2recover executable. - add_executable(bzip2recover) - target_sources(bzip2recover - PRIVATE bzip2recover.c) - target_link_libraries(bzip2recover - PRIVATE bz2_ObjLib) - if(WIN32) - target_compile_definitions(bzip2recover PUBLIC BZ_LCCWIN32 BZ_UNIX=0) - else() - target_compile_definitions(bzip2recover PUBLIC BZ_LCCWIN32=0 BZ_UNIX) - endif() - install(TARGETS bzip2recover DESTINATION ${CMAKE_INSTALL_BINDIR}) - - if(ENABLE_EXAMPLES) - if(ENABLE_SHARED_LIB) - # The dlltest executable. - add_executable(dlltest) - target_sources(dlltest - PRIVATE dlltest.c) - target_link_libraries(dlltest bz2) - install(TARGETS dlltest DESTINATION ${CMAKE_INSTALL_BINDIR}) - endif() - endif() - - if(NOT WIN32) - # Install shell scripts, and renamed copies. - install(PROGRAMS bzdiff bzgrep bzmore - DESTINATION ${CMAKE_INSTALL_BINDIR}) - - install_script_symlink(bzdiff bzcmp) - - install_script_symlink(bzgrep bzegrep) - install_script_symlink(bzgrep bzfgrep) - - install_script_symlink(bzmore bzless) - endif() - -endif() - -if(ENABLE_APP AND Python3_FOUND) - enable_testing() - add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}) - add_subdirectory(tests) -endif() - -add_subdirectory(man) - -set(DOCGEN_EXECS xsltproc perl xmllint grep pdfxmltex pdftops) - -if(ENABLE_DOCS) - foreach(EXEC IN LISTS DOCGEN_EXECS) - find_program(${EXEC}_EXEC ${EXEC}) - if(NOT ${EXEC}_EXEC) - message(WARNING "Missing '${EXEC}', required to generate docs!") - set(MISSING_GENERATOR TRUE) - endif() - endforeach() - - if(MISSING_GENERATOR) - message(FATAL_ERROR "Unable to generate docs.") - endif() - - add_subdirectory(docs) -endif() - -# The Summary Info. -string(TOUPPER "${CMAKE_BUILD_TYPE}" _build_type) -message(STATUS "Summary of build options: - - Package version: ${VERSION} - Library version: ${LT_CURRENT}:${LT_REVISION}:${LT_AGE} - Install prefix: ${CMAKE_INSTALL_PREFIX} - Target system: ${CMAKE_SYSTEM_NAME} - Compiler: - Build type: ${CMAKE_BUILD_TYPE} - C compiler: ${CMAKE_C_COMPILER} - CFLAGS: ${CMAKE_C_FLAGS_${_build_type}} ${CMAKE_C_FLAGS} - WARNCFLAGS: ${WARNCFLAGS} - Test: - Python: ${Python3_FOUND} (${Python3_VERSION}, ${Python3_EXECUTABLE}) - Docs: - Build docs: ${ENABLE_DOCS} - Features: - Applications: ${ENABLE_APP} - Examples: ${ENABLE_EXAMPLES} -") -if(ENABLE_LIB_ONLY_DISABLED_OTHERS) - message("Only the library will be built. To build other components " - "(such as applications and examples), set ENABLE_LIB_ONLY=OFF.") -endif() diff --git a/thirdparty/bzip2/CMakeOptions.txt b/thirdparty/bzip2/CMakeOptions.txt deleted file mode 100644 index 9f0cbc08d..000000000 --- a/thirdparty/bzip2/CMakeOptions.txt +++ /dev/null @@ -1,27 +0,0 @@ -# Features that can be enabled for cmake (see CMakeLists.txt) - -option(ENABLE_WERROR "Turn on compile time warnings") - -option(ENABLE_DEBUG "Turn on debug output") - -option(ENABLE_APP "Build applications (bzip2, and bzip2recover)" - ${ENABLE_APP_DEFAULT}) - -option(ENABLE_TESTS "Build/enable unit tests." - ${ENABLE_TESTS_DEFAULT}) - -option(ENABLE_DOCS "Generate documentation" - ${ENABLE_DOCS_DEFAULT}) - -option(ENABLE_EXAMPLES "Build examples" - ${ENABLE_EXAMPLES_DEFAULT}) - -option(ENABLE_LIB_ONLY "Build libbz2 only. This is a short hand for -DENABLE_APP=0 -DENABLE_EXAMPLES=0") - -option(ENABLE_STATIC_LIB "Build libbz2 in static mode also") - -option(ENABLE_SHARED_LIB "Build libbz2 as a shared library" ON) - -option(USE_OLD_SONAME "Use libbz2.so.1.0 for compatibility with old Makefiles" OFF) - -option(ENABLE_STATIC_LIB_IS_PIC "Enable position independent code for the static library" ON) diff --git a/thirdparty/bzip2/COMPILING.md b/thirdparty/bzip2/COMPILING.md deleted file mode 100644 index fa33ce453..000000000 --- a/thirdparty/bzip2/COMPILING.md +++ /dev/null @@ -1,281 +0,0 @@ -# Compiling bzip2 - -The following build systems are available for Bzip2: - -* [Meson]: This is our preferred build system for Unix-like systems. -* [CMake]: Build tool for Unix and Windows. - -Meson works for Unix-like OSes and Windows; nmake is only for Windows. - -[Meson]: https://mesonbuild.com -[CMake]: https://cmake.org - -> _Important note when compiling for Linux_: -> -> The SONAME for libbz2 for version 1.0 was: `libbz2.so.1.0` -> Some distros patched it to libbz2.so.1 to be supported by libtool. -> Others did not. -> -> We had to make a choice when switching from Makefiles -> CMake + Meson. -> So, the SONAME for libbz2 for version 1.1 is now: `libbz2.so.1` -> -> Distros that need it to be ABI compatible with the old SONAME may either: -> 1. Use CMake for the build with the option `-D USE_OLD_SONAME=ON`. -> This will build an extra copy of the library with the old SONAME. -> -> 2. Use `patchelf --set-soname` after the build to change the SONAME and -> install an extra symlink manually: `libbz2.so.1.0 -> libbz2.so.1.0.9` -> -> You can check the SONAME with: `objdump -p libbz2.so.1.0.9 | grep SONAME` - -## Using Meson - -Meson provides a [large number of built-in options](https://mesonbuild.com/Builtin-options.html) -to control compilation. A few important ones are listed below: - -- -Ddefault_library=[static|shared|both], defaults to shared, if you wish to - statically link libbz2 into the binaries set this to `static` -- --backend : defaults to ninja, use `vs` if you want to use msbuild -- --unity : This enables a unity build (sometimes called a jumbo build), makes a single build faster but rebuilds slower -- -Dbuildtype=[debug|debugoptmized|release|minsize|plain] : Controls default optimization/debug generation args, - defaults to `debug`, use `plain` if you wish to pass your own cflags. - -Meson recognizes environment variables like `$CFLAGS` and `$CC`. -It is recommended that you do not use `$CFLAGS`, and instead use `-Dc_args` and -`-DC_link_args`, as Meson will remember these even if you need to reconfigure -from scratch (such as when you update Meson), it will not remember `$CFLAGS`. - -Meson will never change compilers once configured, so `$CC` is perfectly safe. - -### Unix-like (Linux, *BSD, Cygwin, macOS) - -You will need: - - Python 3.6 or newer (for 3.5 for Meson and 3.6 for the tests) - - Python's 'pytest' module, for running the tests. - - meson (Version 0.56 or newer) - - ninja - - pkg-config - - A C compiler such as GCC or Clang - -Some linux distros package managers refer to ninja as ninja-build, fedora -and debian/ubuntu both do this. Your OS probably provides Meson, although -it may be too old, in that case you can use python3's pip to install Meson: - -```sh -sudo pip3 install meson -``` -or, for a user local install: -```sh -pip3 install --user meson -``` - -Once you have installed the dependencies, the following should work -to use the standard Meson configuration, a `builddir` for -compilation, and a `/usr` prefix for installation: - -```sh -meson --prefix /usr builddir/ -ninja -C builddir -meson test -C builddir --print-errorlogs -[sudo] ninja -C builddir install -``` - -You can use `meson configure builddir` to check configuration options. -Currently bzip only has one project specific option, which is to force the -generation of documentation on or off. - -Ninja acepts many of the same arguments as make, although it will -automatically detect the number of CPU cores available and use an appropriate -number of threads. - -### Windows - -You will need: -- Python 3.6 or newer -- Meson -- Visual Studio 2015+ (Community edition is fine) - -You can install Meson with Python's pip package manager: -```cmd -python -m pip install meson -``` -or you can [download pre-bundled installers of meson directly from meson's github](https://github.com/mesonbuild/meson/releases). - -Either should work fine for the purposes of building Bzip2. - -You will also need pkg-config. There are many sources of pkg-config, I -recommend installing from Chocolatey because it's easy. Chocolatey can also -provide Ninja, though Ninja is not required on Windows if you want to use -msbuild. - -If you want to use MSVC or a compatible compiler launch the associated -environment cmd to run Meson from; the environments required to make those -compilers work is quite complex otherwise. - -Once you have all of that installed you can invoke Meson to configure the -build. By default Meson will generate a Ninja backend. If you would prefer to -use msbuild, pass the backend flag `--backend=vs`. MSVC (and compatible -compilers like clang-cl and ICL) work with Ninja as well. - -```cmd -meson $builddir -ninja -C $builddir -meson test -C builddir --print-errorlogs -``` - -or: -```cmd -meson $builddir --backend=vs -cd $builddir -msbuild bzip2.sln /m -``` - -## Using CMake - -### Requirements - -For Linux/Unix: - - Python 3.6 or newer (for 3.5 for Meson and 3.6 for the tests) - - CMake (Version 3.12 or newer) - - A C compiler such as GCC or Clang - -For Windows: -- Python 3.6 or newer -- CMake -- Visual Studio 2015+ (Community edition is fine) - -### Build instructions for Unix & Windows (CMake) - -Bzip2 can be compiled with the [CMake] build system. -You can use these commands to build Bzip2 in a certain `build` directory. - -#### Basic Release build - -Linux/Unix: -```sh -mkdir build && cd build -cmake .. -DCMAKE_BUILD_TYPE="Release" -cmake --build . -ctest -V -``` - -Windows: -```ps1 -mkdir build && cd build -cmake .. -cmake --build . --config Release -ctest -C Release -V -``` - -#### Basic Debug build - -Linux/Unix: -```sh -mkdir build && cd build -cmake .. -DCMAKE_BUILD_TYPE="Debug" -cmake --build . -ctest -V -``` - -Windows: -```ps1 -mkdir build && cd build -cmake .. -cmake --build . --config Debug -ctest -C Release -V -``` - -#### Build and install to a specific install location (prefix) - -Linux/Unix: -```sh -mkdir build && cd build -cmake .. -DCMAKE_BUILD_TYPE="Release" -DCMAKE_INSTALL_PREFIX=install -cmake --build . -ctest -V -cmake --build . --target install -``` - -Windows: -```ps1 -mkdir build && cd build -cmake .. -DCMAKE_INSTALL_PREFIX=install -cmake --build . --config Release -ctest -C Release -V -cmake --build . --config Release --target install -``` - -#### Other CMake Options - -`ENABLE_EXAMPLES`: Default: `OFF` -Enabling this option will also build the "dlltest" example executable. E.g.: -```sh -mkdir build && cd build -cmake .. -DENABLE_EXAMPLES=ON -cmake --build . -``` - -`ENABLE_DOCS`: Default: `OFF` -Enabling this option will generate extra documentation. E.g.: -```sh -mkdir build && cd build -cmake .. -DENABLE_DOCS=ON -cmake --build . -``` - -`ENABLE_APP`: Default: `ON` -Disabling this option will prevent building `bzip` or any of the other programs -that come with `bzip2`. It will also disable the tests. E.g.: -```sh -mkdir build && cd build -cmake .. -DENABLE_APP=OFF -cmake --build . -``` - -`ENABLE_LIB_ONLY`: Default: `OFF` -Enabling this option is similar to disabling `ENABLE_APP`. Only libbz2 will be -compiled. It will also disable the tests. E.g.: -```sh -mkdir build && cd build -cmake .. -DENABLE_LIB_ONLY=ON -cmake --build . -``` - -`ENABLE_STATIC_LIB`: Default: `OFF` -Enabling this option will build a static version of libbz2. -If `ENABLE_SHARED_LIB` is also enabled, the apps will link with the shared one. -E.g.: -```sh -mkdir build && cd build -cmake .. -DENABLE_STATIC_LIB=ON -cmake --build . -``` - -`ENABLE_SHARED_LIB`: Default: `ON` -Disabling this option will not build a shared version of libbz2. You must enable -`ENABLE_STATIC_LIB` if you disable `ENABLE_SHARED_LIB`. E.g.: -```sh -mkdir build && cd build -cmake .. -DENABLE_SHARED_LIB=OFF -DENABLE_STATIC_LIB=ON -cmake --build . -``` - -`USE_OLD_SONAME`: Default: `OFF` -Enabling this option will build an extra copy of the shared library that uses -the old SONAME. This option is made available for some linux distributions that -still distribute libbz2 with the old SONAME. E.g.: -```sh -mkdir build && cd build -cmake .. -DUSE_OLD_SONAME=ON -cmake --build . -``` - -`ENABLE_STATIC_LIB_IS_PIC`: Default: `ON` -Disabling this option will make it so that building the static library will not -use the '-fPIC'/'-fPIE' compiler options. You may need to disable this option if -your compiler cannot generate position-independent code for your platform. E.g.: -```sh -mkdir build && cd build -cmake .. -DENABLE_STATIC_LIB_IS_PIC=OFF -cmake --build . -``` diff --git a/thirdparty/bzip2/COPYING b/thirdparty/bzip2/COPYING deleted file mode 100644 index 604eb1c1d..000000000 --- a/thirdparty/bzip2/COPYING +++ /dev/null @@ -1,42 +0,0 @@ - --------------------------------------------------------------------------- - -This program, "bzip2", the associated library "libbzip2", and all -documentation, are copyright (C) 1996-2010 Julian R Seward. 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. - -2. 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. - -3. Altered source versions must be plainly marked as such, and must - not be misrepresented as being the original software. - -4. 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. - -Julian Seward, jseward@acm.org -bzip2/libbzip2 version 1.1.0 of 6 September 2010 - --------------------------------------------------------------------------- diff --git a/thirdparty/bzip2/NEWS.md b/thirdparty/bzip2/NEWS.md deleted file mode 100644 index cb07adfa6..000000000 --- a/thirdparty/bzip2/NEWS.md +++ /dev/null @@ -1,468 +0,0 @@ -# Bzip2 News - -## 1.1.0 (unreleased) - -### General Announcements - -[Micah Snyder](https://gitlab.com/micahsnyder) is the new maintainer of Bzip2 -for feature development (v1.1+). - -The Bzip2 feature development project is hosted on GitLab and can be found at -https://gitlab.com/bzip2/bzip2 - -Bzip2 version 1.0 is being maintained by Mark Wielaard at Sourceware and can be -found at https://sourceware.org/git/?p=bzip2.git - -### Changes - -Build system changes: - -* Instead of the historical Makefile, Bzip2 now comes with two supported build - systems (Meson and CMake). - Either of the supported ones should build a shared library as per modern - practices. Please see the file [COMPILING.md](COMPILING.md) for details. - -Important note when compiling for Linux: - -* The SONAME for libbz2 for version 1.0 was: `libbz2.so.1.0` - Some distros patched it to `libbz2.so.1` to be supported by libtool. - Others did not. - - We had to make a choice when switching from Makefiles -> CMake + Meson. - So, the SONAME for libbz2 for version 1.1 is now: `libbz2.so.1` - - Distros that need it to be ABI compatible with the old SONAME may either: - - 1. Use CMake for the build with the option `-D USE_OLD_SONAME=ON`. - This will build an extra copy of the library with the old SONAME. - - 2. Use `patchelf --set-soname` after the build to change the SONAME and - install an extra symlink manually: `libbz2.so.1.0 -> libbz2.so.1.0.9` - - You can check the SONAME with: `objdump -p libbz2.so.1.0.9 | grep SONAME` - -Other changes, fixes: - -* Use `O_CLOEXEC` for `bzopen()`. (Federico Mena Quintero) - -* Fix `mingw` compilation. (Marty E. Plummer, Dylan Baker) - -* Fix Visual Studio compilation. (Phil Ross) - -* Don't let `bzip2recover` overwrite existing output files by default. - (Colin Phipps) - -### Special Thanks - -* Julian Seward for ceding maintainership and providing lots of advice - and interesting anecdotes. - -* Mark Wielaard for constructing a repository based on tarballs from - the original releases. For a different construction by Evan Nemerson, see - https://gitlab.com/bzip2/bzip2/issues/7 - -* Federico Mena Quintero for his maintainership of the project June 2019 - - June 2021. Federico picked up the project from Julian Seward. He coordinated - and contributed to a patching and modernization effort, completed in this - release. - -* Erich Córdoba and Jordan Petridis for the Continuous Integration - infrastructure. - -* Phil Ross for the Windows build fixes. - -* Dylan Baker for the Meson infrastructure. - -* Micah Snyder for the CMake infrastructure. - -* Stanislav Brabec for an Autotools infrastructure, which - became the basis for the Meson/CMake ones. - -* Jens Korte for fixing up the README. - -* All the people who submitted distribution-specific patches. - - -## 1.0.8 (13 Jul 19) - -* Accept as many selectors as the file format allows. - This relaxes the fix for CVE-2019-12900 from 1.0.7 - so that Bzip2 allows decompression of `.bz2` files that - use (too) many selectors again. - -* Fix handling of large (> 4GB) files on Windows. (Phil Ross) - -* Cleanup of `bzdiff` script so it doesn't use any bash extensions. - (Led) - -* Cleanup of `bzgrep` script so it handle multiple archives - correctly. (Kristýna Streitová) - -* There is now a bz2-files test suite at - https://sourceware.org/git/bzip2-tests.git - - -## 1.0.7 (27 Jun 19) - -* Fix undefined behavior in the macros `SET_BH`, `CLEAR_BH`, & `ISSET_BH` - with the shift-left operator (Paul Kehrer). - -* `bunzip2`: Fix return value when combining `--test` (`-t`) and `-q`. - -* `bzip2recover`: Fix buffer overflow for large `argv[0]`. (Ivana Varekova) - https://bugzilla.redhat.com/show_bug.cgi?id=226979 - -* CVE-2016-3189 - Fix use-after-free in `bzip2recover`. (Jakub Martisko) - https://bugzilla.redhat.com/show_bug.cgi?id=1319648 - -* CVE-2019-12900 - Make sure `nSelectors` is not out of range. - Found through fuzzing karchive. (Albert Astals Cid) - - -## 1.0.6 (6 Sept 10) - -* CVE-2010-0405: Security fix. This was reported by Mikolaj Izdebski. - -* Make the documentation build on Ubuntu 10.04 - - -## 1.0.5 (10 Dec 07) - -Security fix only. Fixes CERT-FI 20469 as it applies to bzip2. - - -## 1.0.4 (20 Dec 06) - -Fixes some minor bugs since the last version, 1.0.3. - -* Fix file permissions race problem (CAN-2005-0953). - -* Avoid possible segfault in BZ2_bzclose. From Coverity's NetBSD - scan. - -* 'const'/prototype cleanups in the C code. - -* Change default install location to /usr/local, and handle multiple - 'make install's without error. - -* Sanitise file names more carefully in bzgrep. Fixes CAN-2005-0758 - to the extent that applies to bzgrep. - -* Use 'mktemp' rather than 'tempfile' in bzdiff. - -* Tighten up a couple of assertions in blocksort.c following automated - analysis. - -* Fix minor doc/comment bugs. - - -## 1.0.3 (15 Feb 05) - -Fixes some minor bugs since the last version, 1.0.2. - -* Further robustification against corrupted compressed data. - There are currently no known bitstreams which can cause the - decompressor to crash, loop or access memory which does not - belong to it. If you are using bzip2 or the library to - decompress bitstreams from untrusted sources, an upgrade - to 1.0.3 is recommended. This fixes CAN-2005-1260. - -* The documentation has been converted to XML, from which html - and pdf can be derived. - -* Various minor bugs in the documentation have been fixed. - -* Fixes for various compilation warnings with newer versions of - gcc, and on 64-bit platforms. - -* The BZ_NO_STDIO cpp symbol was not properly observed in 1.0.2. - This has been fixed. - - -## 1.0.2 - -A bug fix release, addressing various minor issues which have appeared -in the 18 or so months since 1.0.1 was released. Most of the fixes -are to do with file-handling or documentation bugs. To the best of my -knowledge, there have been no data-loss-causing bugs reported in the -compression/decompression engine of 1.0.0 or 1.0.1. - -Note that this release does not improve the rather crude build system -for Unix platforms. The general plan here is to autoconfiscate/ -libtoolise 1.0.2 soon after release, and release the result as 1.1.0 -or perhaps 1.2.0. That, however, is still just a plan at this point. - -Here are the changes in 1.0.2. Bug-reporters and/or patch-senders in -parentheses. - -* Fix an infinite segfault loop in 1.0.1 when a directory is - encountered in -f (force) mode. - (Trond Eivind Glomsrod, Nicholas Nethercote, Volker Schmidt) - -* Avoid double fclose() of output file on certain I/O error paths. - (Solar Designer) - -* Don't fail with internal error 1007 when fed a long stream (> 48MB) - of byte 251. Also print useful message suggesting that 1007s may be - caused by bad memory. - (noticed by Juan Pedro Vallejo, fixed by me) - -* Fix uninitialised variable silly bug in demo prog dlltest.c. - (Jorj Bauer) - -* Remove 512-MB limitation on recovered file size for bzip2recover - on selected platforms which support 64-bit ints. At the moment - all GCC supported platforms, and Win32. - (me, Alson van der Meulen) - -* Hard-code header byte values, to give correct operation on platforms - using EBCDIC as their native character set (IBM's OS/390). - (Leland Lucius) - -* Copy file access times correctly. - (Marty Leisner) - -* Add distclean and check targets to Makefile. - (Michael Carmack) - -* Parameterise use of ar and ranlib in Makefile. Also add $(LDFLAGS). - (Rich Ireland, Bo Thorsen) - -* Pass -p (create parent dirs as needed) to mkdir during make install. - (Jeremy Fusco) - -* Dereference symlinks when copying file permissions in -f mode. - (Volker Schmidt) - -* Majorly simplify implementation of uInt64_qrm10. - (Bo Lindbergh) - -* Check the input file still exists before deleting the output one, - when aborting in cleanUpAndFail(). - (Joerg Prante, Robert Linden, Matthias Krings) - -Also a bunch of patches courtesy of Philippe Troin, the Debian maintainer -of bzip2: - -* Wrapper scripts (with manpages): bzdiff, bzgrep, bzmore. - -* Spelling changes and minor enhancements in bzip2.1. - -* Avoid race condition between creating the output file and setting its - interim permissions safely, by using fopen_output_safely(). - No changes to bzip2recover since there is no issue with file - permissions there. - -* do not print senseless report with -v when compressing an empty - file. - -* bzcat -f works on non-bzip2 files. - -* do not try to escape shell meta-characters on unix (the shell takes - care of these). - -* added --fast and --best aliases for -1 -9 for gzip compatibility. - - -## 1.0.1 - -* Modified dlltest.c so it uses the new BZ2_ naming scheme. -* Modified makefile-msc to fix minor build probs on Win2k. -* Updated README.COMPILATION.PROBLEMS. - -There are no functionality changes or bug fixes relative to version -1.0.0. This is just a documentation update + a fix for minor Win32 -build problems. For almost everyone, upgrading from 1.0.0 to 1.0.1 is -utterly pointless. Don't bother. - - -## 1.0 - -Several minor bugfixes and enhancements: - -* Large file support. The library uses 64-bit counters to - count the volume of data passing through it. bzip2.c - is now compiled with -D_FILE_OFFSET_BITS=64 to get large - file support from the C library. -v correctly prints out - file sizes greater than 4 gigabytes. All these changes have - been made without assuming a 64-bit platform or a C compiler - which supports 64-bit ints, so, except for the C library - aspect, they are fully portable. - -* Decompression robustness. The library/program should be - robust to any corruption of compressed data, detecting and - handling _all_ corruption, instead of merely relying on - the CRCs. What this means is that the program should - never crash, given corrupted data, and the library should - always return BZ_DATA_ERROR. - -* Fixed an obscure race-condition bug only ever observed on - Solaris, in which, if you were very unlucky and issued - control-C at exactly the wrong time, both input and output - files would be deleted. - -* Don't run out of file handles on test/decompression when - large numbers of files have invalid magic numbers. - -* Avoid library namespace pollution. Prefix all exported - symbols with BZ2_. - -* Minor sorting enhancements from my DCC2000 paper. - -* Advance the version number to 1.0, so as to counteract the - (false-in-this-case) impression some people have that programs - with version numbers less than 1.0 are in some way, experimental, - pre-release versions. - -* Create an initial Makefile-libbz2_so to build a shared library. - Yes, I know I should really use libtool et al ... - -* Make the program exit with 2 instead of 0 when decompression - fails due to a bad magic number (ie, an invalid bzip2 header). - Also exit with 1 (as the manual claims :-) whenever a diagnostic - message would have been printed AND the corresponding operation - is aborted, for example - bzip2: Output file xx already exists. - When a diagnostic message is printed but the operation is not - aborted, for example - bzip2: Can't guess original name for wurble -- using wurble.out - then the exit value 0 is returned, unless some other problem is - also detected. - - I think it corresponds more closely to what the manual claims now. - - -## 0.9.5d - -The only functional change is to make bzlibVersion() in the library -return the correct string. This has no effect whatsoever on the -functioning of the bzip2 program or library. Added a couple of casts -so the library compiles without warnings at level 3 in MS Visual -Studio 6.0. Included a Y2K statement in the file Y2K_INFO. All other -changes are minor documentation changes. - - -## 0.9.5c - -Changed BZ_N_OVERSHOOT to be ... + 2 instead of ... + 1. The + 1 -version could cause the sorted order to be wrong in some extremely -obscure cases. Also changed setting of quadrant in blocksort.c. - - -## 0.9.5b - -Open stdin/stdout in binary mode for DJGPP. - - -## 0.9.5a - -Major change: add a fallback sorting algorithm (blocksort.c) -to give reasonable behaviour even for very repetitive inputs. -Nuked --repetitive-best and --repetitive-fast since they are -no longer useful. - -Minor changes: mostly a whole bunch of small changes/ -bugfixes in the driver (bzip2.c). Changes pertaining to the -user interface are: - - allow decompression of symlink'd files to stdout - decompress/test files even without .bz2 extension - give more accurate error messages for I/O errors - when compressing/decompressing to stdout, don't catch control-C - read flags from BZIP2 and BZIP environment variables - decline to break hard links to a file unless forced with -f - allow -c flag even with no filenames - preserve file ownerships as far as possible - make -s -1 give the expected block size (100k) - add a flag -q --quiet to suppress nonessential warnings - stop decoding flags after --, so files beginning in - can be handled - resolved inconsistent naming: bzcat or bz2cat ? - bzip2 --help now returns 0 - -Programming-level changes are: - - fixed syntax error in GET_LL4 for Borland C++ 5.02 - let bzBuffToBuffDecompress return BZ_DATA_ERROR{_MAGIC} - fix overshoot of mode-string end in bzopen_or_bzdopen - wrapped bzlib.h in #ifdef __cplusplus ... extern "C" { ... } - close file handles under all error conditions - added minor mods so it compiles with DJGPP out of the box - fixed Makefile so it doesn't give problems with BSD make - fix uninitialised memory reads in dlltest.c - -Summary: - - * Compression speed is much less sensitive to the input - data than in previous versions. Specifically, the very - slow performance caused by repetitive data is fixed. - * Many small improvements in file and flag handling. - * A Y2K statement. - - -## 0.9.0c - -Fixed some problems in the library pertaining to some boundary cases. -This makes the library behave more correctly in those situations. The -fixes apply only to features (calls and parameters) not used by -bzip2.c, so the non-fixedness of them in previous versions has no -effect on reliability of bzip2.c. - -In bzlib.c: - * made zero-length BZ_FLUSH work correctly in bzCompress(). - * fixed bzWrite/bzRead to ignore zero-length requests. - * fixed bzread to correctly handle read requests after EOF. - * wrong parameter order in call to bzDecompressInit in - bzBuffToBuffDecompress. Fixed. - -In compress.c: - * changed setting of nGroups in sendMTFValues() so as to - do a bit better on small files. This _does_ effect - bzip2.c. - - -## 0.9.0b - -Fixed a problem with error reporting in bzip2.c. This does not effect -the library in any way. Problem is: versions 0.9.0 and 0.9.0a (of the -program proper) compress and decompress correctly, but give misleading -error messages (internal panics) when an I/O error occurs, instead of -reporting the problem correctly. This shouldn't give any data loss -(as far as I can see), but is confusing. - -Made the inline declarations disappear for non-GCC compilers. - - -## 0.9.0a - -Removed 'ranlib' from Makefile, since most modern Unix-es -don't need it, or even know about it. - - -## 0.9.0 - -First version after 0.1pl2. - - * Approx 10% faster compression, 30% faster decompression - * -t (test mode) is a lot quicker - * Can decompress concatenated compressed files - * Programming interface, so programs can directly read/write .bz2 files - * Less restrictive (BSD-style) licensing - * Flag handling more compatible with GNU gzip - * Much more documentation, i.e., a proper user manual - * Hopefully, improved portability (at least of the library) - - - - ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.1.0 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward - - 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. - ------------------------------------------------------------------ diff --git a/thirdparty/bzip2/README.XML.STUFF b/thirdparty/bzip2/README.XML.STUFF deleted file mode 100644 index e5c3f9d2d..000000000 --- a/thirdparty/bzip2/README.XML.STUFF +++ /dev/null @@ -1,45 +0,0 @@ - ---------------------------------------------------------------- - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.1.0 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward - - 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. - ---------------------------------------------------------------- - -The script xmlproc.sh takes an xml file as input, -and processes it to create .pdf, .html or .ps output. -It uses format.pl, a perl script to format
 blocks nicely,
- and add CDATA tags so writers do not have to use eg. <
-
-The file "entities.xml" must be edited to reflect current
-version, year, etc.
-
-
-Usage:
-
-  ./xmlproc.sh -v manual.xml
-  Validates an xml file to ensure no dtd-compliance errors
-
-  ./xmlproc.sh -html manual.xml
-  Output: manual.html
-
-  ./xmlproc.sh -pdf manual.xml
-  Output: manual.pdf
-
-  ./xmlproc.sh -ps manual.xml
-  Output: manual.ps
-
-
-Notum bene:
-- pdfxmltex barfs if given a filename with an underscore in it
-
-- xmltex won't work yet - there's a bug in passivetex
-    which we are all waiting for Sebastian to fix.
-  So we are going the xml -> pdf -> ps route for the time being,
-    using pdfxmltex.
diff --git a/thirdparty/bzip2/README.md b/thirdparty/bzip2/README.md
deleted file mode 100644
index 1d0c4aa73..000000000
--- a/thirdparty/bzip2/README.md
+++ /dev/null
@@ -1,120 +0,0 @@
-Bzip2
-=====
-
-This is Bzip2/libbz2; a program and library for lossless, block-sorting data
-compression.
-
-This document pertains to the Bzip2 feature development effort hosted on
-[GitLab.com](https://gitlab.com/bzip2/bzip2).
-
-The documentation here may differ from that on the Bzip2 1.0.x project page
-maintained by Mark Wielaard on[sourceware.org](https://sourceware.org/bzip2/).
-
-Copyright (C) 1996-2010 Julian Seward 
-
-Copyright (C) 2019-2020 Federico Mena Quintero 
-
-Copyright (C) 2021 [Micah Snyder](https://gitlab.com/micahsnyder).
-
-Please read the [WARNING](#warning), [DISCLAIMER](#disclaimer) and
-[PATENTS](#patents) sections in this file for important information.
-
-This program is released under the terms of the license contained in the
-[COPYING](COPYING) file.
-
-------------------------------------------------------------------
-
-This version is fully compatible with the previous public releases.
-
-Complete documentation is available in Postscript form (manual.ps),
-PDF (manual.pdf) or HTML (manual.html).  A plain-text version of the
-manual page is available as bzip2.txt.
-
-## Community Code of Conduct
-
-There is a code of conduct for contributors to Bzip2/libbz2.
-Please see the [`code-of-conduct.md`](code-of-conduct.md) file.
-
-## Contributing to Bzip2's development
-
-The Bzip2 project is hosted on GitLab for feature development work.
-It can be found at https://gitlab.com/bzip2/bzip2
-
-Changes to be included in the next feature version are committed to the
-`master` branch.
-
-Feature releases are maintained in `release/*` branches.
-
-Long-term feature and experimental development will occur in feature branches.
-*Feature branches are unstable.* Feature branches may be rebased and force-
-pushed on occasion to keep them up-to-date and to resolve merge conflicts.
-
-The `rustify` branch is a feature branch that represents an effort to
-gradually port Bzip2 to [Rust](https://www.rust-lang.org).
-
-## Report a Bug
-
-Please report bugs via [GitLab Issues](https://gitlab.com/bzip2/bzip2/issues).
-
-Before you create a new issue, please verify that no one else has already
-reported the same issue.
-
-## Compiling Bzip2 and libbz2
-
-Please see the [`COMPILING.md`](COMPILING.md) file for details.
-This includes instructions for building using Meson or CMake.
-
-## WARNING
-
-This program and library (attempts to) compress data by performing several
-non-trivial transformations on it. Unless you are 100% familiar with *all* the
-algorithms contained herein, and with the consequences of modifying them, you
-should NOT meddle with the compression or decompression machinery.
-Incorrect changes can and very likely *will* lead to disastrous loss of data.
-
-**Please contact the maintainers if you want to modify the algorithms.**
-
-## DISCLAIMER
-
-**I TAKE NO RESPONSIBILITY FOR ANY LOSS OF DATA ARISING FROM THE USE OF THIS
-PROGRAM/LIBRARY, HOWSOEVER CAUSED.**
-
-Every compression of a file implies an assumption that the compressed file can
-be decompressed to reproduce the original. Great efforts in design, coding and
-testing have been made to ensure that this program works correctly.
-
-However, the complexity of the algorithms, and, in particular, the presence of
-various special cases in the code which occur with very low but non-zero
-probability make it impossible to rule out the possibility of bugs remaining in
-the program.
-
-DO NOT COMPRESS ANY DATA WITH THIS PROGRAM UNLESS YOU ARE PREPARED TO ACCEPT
-THE POSSIBILITY, HOWEVER SMALL, THAT THE DATA WILL NOT BE RECOVERABLE.
-
-That is not to say this program is inherently unreliable.
-Indeed, I very much hope the opposite is true.
-Bzip2/libbz2 has been carefully constructed and extensively tested.
-
-## PATENTS
-
-To the best of my knowledge, Bzip2/libbz2 does not use any patented algorithms.
-However, I do not have the resources to carry out a patent search.
-Therefore I cannot give any guarantee of the above statement.
-
-## Maintainers
-
-As of June 2021, [Micah Snyder](https://gitlab.com/micahsnyder) is the
-maintainer of Bzip2/libbz2 for feature development work (I.e. versions 1.1+).
-
-The Bzip2 feature development project is hosted on GitLab and can be found at
-https://gitlab.com/bzip2/bzip2
-
-Bzip2 version 1.0 is maintained by [Mark Wielaard](https://www.klomp.org/mark/)
-at Sourceware and can be found at https://sourceware.org/git/?p=bzip2.git
-
-### Special thanks
-
-Thanks to Julian Seward, the original author of Bzip2/libbz2, for creating the
-program and making it a very compelling alternative to previous compression
-programs back in the early 2000's. Thanks to Julian also for letting Federico,
-Mark, and Micah carry on with the maintainership of the program.
diff --git a/thirdparty/bzip2/blocksort.c b/thirdparty/bzip2/blocksort.c
deleted file mode 100644
index 1c3ee9404..000000000
--- a/thirdparty/bzip2/blocksort.c
+++ /dev/null
@@ -1,1094 +0,0 @@
-
-/*-------------------------------------------------------------*/
-/*--- Block sorting machinery                               ---*/
-/*---                                           blocksort.c ---*/
-/*-------------------------------------------------------------*/
-
-/* ------------------------------------------------------------------
-   This file is part of bzip2/libbzip2, a program and library for
-   lossless, block-sorting data compression.
-
-   bzip2/libbzip2 version 1.1.0 of 6 September 2010
-   Copyright (C) 1996-2010 Julian Seward 
-
-   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"
-
-/*---------------------------------------------*/
-/*--- Fallback O(N log(N)^2) sorting        ---*/
-/*--- algorithm, for repetitive blocks      ---*/
-/*---------------------------------------------*/
-
-/*---------------------------------------------*/
-static
-__inline__
-void fallbackSimpleSort ( UInt32* fmap,
-                          UInt32* eclass,
-                          Int32   lo,
-                          Int32   hi )
-{
-   Int32 i, j, tmp;
-   UInt32 ec_tmp;
-
-   if (lo == hi) return;
-
-   if (hi - lo > 3) {
-      for ( i = hi-4; i >= lo; i-- ) {
-         tmp = fmap[i];
-         ec_tmp = eclass[tmp];
-         for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 )
-            fmap[j-4] = fmap[j];
-         fmap[j-4] = tmp;
-      }
-   }
-
-   for ( i = hi-1; i >= lo; i-- ) {
-      tmp = fmap[i];
-      ec_tmp = eclass[tmp];
-      for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ )
-         fmap[j-1] = fmap[j];
-      fmap[j-1] = tmp;
-   }
-}
-
-
-/*---------------------------------------------*/
-#define fswap(zz1, zz2) \
-   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
-
-#define fvswap(zzp1, zzp2, zzn)       \
-{                                     \
-   Int32 yyp1 = (zzp1);               \
-   Int32 yyp2 = (zzp2);               \
-   Int32 yyn  = (zzn);                \
-   while (yyn > 0) {                  \
-      fswap(fmap[yyp1], fmap[yyp2]);  \
-      yyp1++; yyp2++; yyn--;          \
-   }                                  \
-}
-
-
-#define fmin(a,b) ((a) < (b)) ? (a) : (b)
-
-#define fpush(lz,hz) { stackLo[sp] = lz; \
-                       stackHi[sp] = hz; \
-                       sp++; }
-
-#define fpop(lz,hz) { sp--;              \
-                      lz = stackLo[sp];  \
-                      hz = stackHi[sp]; }
-
-#define FALLBACK_QSORT_SMALL_THRESH 10
-#define FALLBACK_QSORT_STACK_SIZE   100
-
-
-static
-void fallbackQSort3 ( UInt32* fmap,
-                      UInt32* eclass,
-                      Int32   loSt,
-                      Int32   hiSt )
-{
-   Int32 unLo, unHi, ltLo, gtHi, n, m;
-   Int32 sp, lo, hi;
-   UInt32 med, r, r3;
-   Int32 stackLo[FALLBACK_QSORT_STACK_SIZE];
-   Int32 stackHi[FALLBACK_QSORT_STACK_SIZE];
-
-   r = 0;
-
-   sp = 0;
-   fpush ( loSt, hiSt );
-
-   while (sp > 0) {
-
-      AssertH ( sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004 );
-
-      fpop ( lo, hi );
-      if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
-         fallbackSimpleSort ( fmap, eclass, lo, hi );
-         continue;
-      }
-
-      /* Random partitioning.  Median of 3 sometimes fails to
-         avoid bad cases.  Median of 9 seems to help but
-         looks rather expensive.  This too seems to work but
-         is cheaper.  Guidance for the magic constants
-         7621 and 32768 is taken from Sedgewick's algorithms
-         book, chapter 35.
-      */
-      r = ((r * 7621) + 1) % 32768;
-      r3 = r % 3;
-      if (r3 == 0) med = eclass[fmap[lo]]; else
-      if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else
-                   med = eclass[fmap[hi]];
-
-      unLo = ltLo = lo;
-      unHi = gtHi = hi;
-
-      while (1) {
-         while (1) {
-            if (unLo > unHi) break;
-            n = (Int32)eclass[fmap[unLo]] - (Int32)med;
-            if (n == 0) {
-               fswap(fmap[unLo], fmap[ltLo]);
-               ltLo++; unLo++;
-               continue;
-            };
-            if (n > 0) break;
-            unLo++;
-         }
-         while (1) {
-            if (unLo > unHi) break;
-            n = (Int32)eclass[fmap[unHi]] - (Int32)med;
-            if (n == 0) {
-               fswap(fmap[unHi], fmap[gtHi]);
-               gtHi--; unHi--;
-               continue;
-            };
-            if (n < 0) break;
-            unHi--;
-         }
-         if (unLo > unHi) break;
-         fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
-      }
-
-      AssertD ( unHi == unLo-1, "fallbackQSort3(2)" );
-
-      if (gtHi < ltLo) continue;
-
-      n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n);
-      m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m);
-
-      n = lo + unLo - ltLo - 1;
-      m = hi - (gtHi - unHi) + 1;
-
-      if (n - lo > hi - m) {
-         fpush ( lo, n );
-         fpush ( m, hi );
-      } else {
-         fpush ( m, hi );
-         fpush ( lo, n );
-      }
-   }
-}
-
-#undef fmin
-#undef fpush
-#undef fpop
-#undef fswap
-#undef fvswap
-#undef FALLBACK_QSORT_SMALL_THRESH
-#undef FALLBACK_QSORT_STACK_SIZE
-
-
-/*---------------------------------------------*/
-/* Pre:
-      nblock > 0
-      eclass exists for [0 .. nblock-1]
-      ((UChar*)eclass) [0 .. nblock-1] holds block
-      ptr exists for [0 .. nblock-1]
-
-   Post:
-      ((UChar*)eclass) [0 .. nblock-1] holds block
-      All other areas of eclass destroyed
-      fmap [0 .. nblock-1] holds sorted order
-      bhtab [ 0 .. 2+(nblock/32) ] destroyed
-*/
-
-#define       SET_BH(zz)  bhtab[(zz) >> 5] |= ((UInt32)1 << ((zz) & 31))
-#define     CLEAR_BH(zz)  bhtab[(zz) >> 5] &= ~((UInt32)1 << ((zz) & 31))
-#define     ISSET_BH(zz)  (bhtab[(zz) >> 5] & ((UInt32)1 << ((zz) & 31)))
-#define      WORD_BH(zz)  bhtab[(zz) >> 5]
-#define UNALIGNED_BH(zz)  ((zz) & 0x01f)
-
-static
-void fallbackSort ( UInt32* fmap,
-                    UInt32* eclass,
-                    UInt32* bhtab,
-                    Int32   nblock,
-                    Int32   verb )
-{
-   Int32 ftab[257];
-   Int32 ftabCopy[256];
-   Int32 H, i, j, k, l, r, cc, cc1;
-   Int32 nNotDone;
-   Int32 nBhtab;
-   UChar* eclass8 = (UChar*)eclass;
-
-   /*--
-      Initial 1-char radix sort to generate
-      initial fmap and initial BH bits.
-   --*/
-   if (verb >= 4)
-      VPrintf0 ( "        bucket sorting ...\n" );
-   for (i = 0; i < 257;    i++) ftab[i] = 0;
-   for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
-   for (i = 0; i < 256;    i++) ftabCopy[i] = ftab[i];
-   for (i = 1; i < 257;    i++) ftab[i] += ftab[i-1];
-
-   for (i = 0; i < nblock; i++) {
-      j = eclass8[i];
-      k = ftab[j] - 1;
-      ftab[j] = k;
-      fmap[k] = i;
-   }
-
-   nBhtab = 2 + (nblock / 32);
-   for (i = 0; i < nBhtab; i++) bhtab[i] = 0;
-   for (i = 0; i < 256; i++) SET_BH(ftab[i]);
-
-   /*--
-      Inductively refine the buckets.  Kind-of an
-      "exponential radix sort" (!), inspired by the
-      Manber-Myers suffix array construction algorithm.
-   --*/
-
-   /*-- set sentinel bits for block-end detection --*/
-   for (i = 0; i < 32; i++) {
-      SET_BH(nblock + 2*i);
-      CLEAR_BH(nblock + 2*i + 1);
-   }
-
-   /*-- the log(N) loop --*/
-   H = 1;
-   while (1) {
-
-      if (verb >= 4)
-         VPrintf1 ( "        depth %6d has ", H );
-
-      j = 0;
-      for (i = 0; i < nblock; i++) {
-         if (ISSET_BH(i)) j = i;
-         k = fmap[i] - H; if (k < 0) k += nblock;
-         eclass[k] = j;
-      }
-
-      nNotDone = 0;
-      r = -1;
-      while (1) {
-
-         /*-- find the next non-singleton bucket --*/
-         k = r + 1;
-         while (ISSET_BH(k) && UNALIGNED_BH(k)) k++;
-         if (ISSET_BH(k)) {
-            while (WORD_BH(k) == 0xffffffff) k += 32;
-            while (ISSET_BH(k)) k++;
-         }
-         l = k - 1;
-         if (l >= nblock) break;
-         while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++;
-         if (!ISSET_BH(k)) {
-            while (WORD_BH(k) == 0x00000000) k += 32;
-            while (!ISSET_BH(k)) k++;
-         }
-         r = k - 1;
-         if (r >= nblock) break;
-
-         /*-- now [l, r] bracket current bucket --*/
-         if (r > l) {
-            nNotDone += (r - l + 1);
-            fallbackQSort3 ( fmap, eclass, l, r );
-
-            /*-- scan bucket and generate header bits-- */
-            cc = -1;
-            for (i = l; i <= r; i++) {
-               cc1 = eclass[fmap[i]];
-               if (cc != cc1) { SET_BH(i); cc = cc1; };
-            }
-         }
-      }
-
-      if (verb >= 4)
-         VPrintf1 ( "%6d unresolved strings\n", nNotDone );
-
-      H *= 2;
-      if (H > nblock || nNotDone == 0) break;
-   }
-
-   /*--
-      Reconstruct the original block in
-      eclass8 [0 .. nblock-1], since the
-      previous phase destroyed it.
-   --*/
-   if (verb >= 4)
-      VPrintf0 ( "        reconstructing block ...\n" );
-   j = 0;
-   for (i = 0; i < nblock; i++) {
-      while (ftabCopy[j] == 0) j++;
-      ftabCopy[j]--;
-      eclass8[fmap[i]] = (UChar)j;
-   }
-   AssertH ( j < 256, 1005 );
-}
-
-#undef       SET_BH
-#undef     CLEAR_BH
-#undef     ISSET_BH
-#undef      WORD_BH
-#undef UNALIGNED_BH
-
-
-/*---------------------------------------------*/
-/*--- The main, O(N^2 log(N)) sorting       ---*/
-/*--- algorithm.  Faster for "normal"       ---*/
-/*--- non-repetitive blocks.                ---*/
-/*---------------------------------------------*/
-
-/*---------------------------------------------*/
-static
-__inline__
-Bool mainGtU ( UInt32  i1,
-               UInt32  i2,
-               UChar*  block,
-               UInt16* quadrant,
-               UInt32  nblock,
-               Int32*  budget )
-{
-   Int32  k;
-   UChar  c1, c2;
-   UInt16 s1, s2;
-
-   AssertD ( i1 != i2, "mainGtU" );
-   /* 1 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 > c2);
-   i1++; i2++;
-   /* 2 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 > c2);
-   i1++; i2++;
-   /* 3 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 > c2);
-   i1++; i2++;
-   /* 4 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 > c2);
-   i1++; i2++;
-   /* 5 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 > c2);
-   i1++; i2++;
-   /* 6 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 > c2);
-   i1++; i2++;
-   /* 7 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 > c2);
-   i1++; i2++;
-   /* 8 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 > c2);
-   i1++; i2++;
-   /* 9 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 > c2);
-   i1++; i2++;
-   /* 10 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 > c2);
-   i1++; i2++;
-   /* 11 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 > c2);
-   i1++; i2++;
-   /* 12 */
-   c1 = block[i1]; c2 = block[i2];
-   if (c1 != c2) return (c1 > c2);
-   i1++; i2++;
-
-   k = nblock + 8;
-
-   do {
-      /* 1 */
-      c1 = block[i1]; c2 = block[i2];
-      if (c1 != c2) return (c1 > c2);
-      s1 = quadrant[i1]; s2 = quadrant[i2];
-      if (s1 != s2) return (s1 > s2);
-      i1++; i2++;
-      /* 2 */
-      c1 = block[i1]; c2 = block[i2];
-      if (c1 != c2) return (c1 > c2);
-      s1 = quadrant[i1]; s2 = quadrant[i2];
-      if (s1 != s2) return (s1 > s2);
-      i1++; i2++;
-      /* 3 */
-      c1 = block[i1]; c2 = block[i2];
-      if (c1 != c2) return (c1 > c2);
-      s1 = quadrant[i1]; s2 = quadrant[i2];
-      if (s1 != s2) return (s1 > s2);
-      i1++; i2++;
-      /* 4 */
-      c1 = block[i1]; c2 = block[i2];
-      if (c1 != c2) return (c1 > c2);
-      s1 = quadrant[i1]; s2 = quadrant[i2];
-      if (s1 != s2) return (s1 > s2);
-      i1++; i2++;
-      /* 5 */
-      c1 = block[i1]; c2 = block[i2];
-      if (c1 != c2) return (c1 > c2);
-      s1 = quadrant[i1]; s2 = quadrant[i2];
-      if (s1 != s2) return (s1 > s2);
-      i1++; i2++;
-      /* 6 */
-      c1 = block[i1]; c2 = block[i2];
-      if (c1 != c2) return (c1 > c2);
-      s1 = quadrant[i1]; s2 = quadrant[i2];
-      if (s1 != s2) return (s1 > s2);
-      i1++; i2++;
-      /* 7 */
-      c1 = block[i1]; c2 = block[i2];
-      if (c1 != c2) return (c1 > c2);
-      s1 = quadrant[i1]; s2 = quadrant[i2];
-      if (s1 != s2) return (s1 > s2);
-      i1++; i2++;
-      /* 8 */
-      c1 = block[i1]; c2 = block[i2];
-      if (c1 != c2) return (c1 > c2);
-      s1 = quadrant[i1]; s2 = quadrant[i2];
-      if (s1 != s2) return (s1 > s2);
-      i1++; i2++;
-
-      if (i1 >= nblock) i1 -= nblock;
-      if (i2 >= nblock) i2 -= nblock;
-
-      k -= 8;
-      (*budget)--;
-   }
-      while (k >= 0);
-
-   return False;
-}
-
-
-/*---------------------------------------------*/
-/*--
-   Knuth's increments seem to work better
-   than Incerpi-Sedgewick here.  Possibly
-   because the number of elems to sort is
-   usually small, typically <= 20.
---*/
-static
-Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
-                   9841, 29524, 88573, 265720,
-                   797161, 2391484 };
-
-static
-void mainSimpleSort ( UInt32* ptr,
-                      UChar*  block,
-                      UInt16* quadrant,
-                      Int32   nblock,
-                      Int32   lo,
-                      Int32   hi,
-                      Int32   d,
-                      Int32*  budget )
-{
-   Int32 i, j, h, bigN, hp;
-   UInt32 v;
-
-   bigN = hi - lo + 1;
-   if (bigN < 2) return;
-
-   hp = 0;
-   while (incs[hp] < bigN) hp++;
-   hp--;
-
-   for (; hp >= 0; hp--) {
-      h = incs[hp];
-
-      i = lo + h;
-      while (True) {
-
-         /*-- copy 1 --*/
-         if (i > hi) break;
-         v = ptr[i];
-         j = i;
-         while ( mainGtU (
-                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget
-                 ) ) {
-            ptr[j] = ptr[j-h];
-            j = j - h;
-            if (j <= (lo + h - 1)) break;
-         }
-         ptr[j] = v;
-         i++;
-
-         /*-- copy 2 --*/
-         if (i > hi) break;
-         v = ptr[i];
-         j = i;
-         while ( mainGtU (
-                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget
-                 ) ) {
-            ptr[j] = ptr[j-h];
-            j = j - h;
-            if (j <= (lo + h - 1)) break;
-         }
-         ptr[j] = v;
-         i++;
-
-         /*-- copy 3 --*/
-         if (i > hi) break;
-         v = ptr[i];
-         j = i;
-         while ( mainGtU (
-                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget
-                 ) ) {
-            ptr[j] = ptr[j-h];
-            j = j - h;
-            if (j <= (lo + h - 1)) break;
-         }
-         ptr[j] = v;
-         i++;
-
-         if (*budget < 0) return;
-      }
-   }
-}
-
-
-/*---------------------------------------------*/
-/*--
-   The following is an implementation of
-   an elegant 3-way quicksort for strings,
-   described in a paper "Fast Algorithms for
-   Sorting and Searching Strings", by Robert
-   Sedgewick and Jon L. Bentley.
---*/
-
-#define mswap(zz1, zz2) \
-   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
-
-#define mvswap(zzp1, zzp2, zzn)       \
-{                                     \
-   Int32 yyp1 = (zzp1);               \
-   Int32 yyp2 = (zzp2);               \
-   Int32 yyn  = (zzn);                \
-   while (yyn > 0) {                  \
-      mswap(ptr[yyp1], ptr[yyp2]);    \
-      yyp1++; yyp2++; yyn--;          \
-   }                                  \
-}
-
-static
-__inline__
-UChar mmed3 ( UChar a, UChar b, UChar c )
-{
-   UChar t;
-   if (a > b) { t = a; a = b; b = t; };
-   if (b > c) {
-      b = c;
-      if (a > b) b = a;
-   }
-   return b;
-}
-
-#define mmin(a,b) ((a) < (b)) ? (a) : (b)
-
-#define mpush(lz,hz,dz) { stackLo[sp] = lz; \
-                          stackHi[sp] = hz; \
-                          stackD [sp] = dz; \
-                          sp++; }
-
-#define mpop(lz,hz,dz) { sp--;             \
-                         lz = stackLo[sp]; \
-                         hz = stackHi[sp]; \
-                         dz = stackD [sp]; }
-
-
-#define mnextsize(az) (nextHi[az]-nextLo[az])
-
-#define mnextswap(az,bz)                                        \
-   { Int32 tz;                                                  \
-     tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
-     tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
-     tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; }
-
-
-#define MAIN_QSORT_SMALL_THRESH 20
-#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
-#define MAIN_QSORT_STACK_SIZE 100
-
-static
-void mainQSort3 ( UInt32* ptr,
-                  UChar*  block,
-                  UInt16* quadrant,
-                  Int32   nblock,
-                  Int32   loSt,
-                  Int32   hiSt,
-                  Int32   dSt,
-                  Int32*  budget )
-{
-   Int32 unLo, unHi, ltLo, gtHi, n, m, med;
-   Int32 sp, lo, hi, d;
-
-   Int32 stackLo[MAIN_QSORT_STACK_SIZE];
-   Int32 stackHi[MAIN_QSORT_STACK_SIZE];
-   Int32 stackD [MAIN_QSORT_STACK_SIZE];
-
-   Int32 nextLo[3];
-   Int32 nextHi[3];
-   Int32 nextD [3];
-
-   sp = 0;
-   mpush ( loSt, hiSt, dSt );
-
-   while (sp > 0) {
-
-      AssertH ( sp < MAIN_QSORT_STACK_SIZE - 2, 1001 );
-
-      mpop ( lo, hi, d );
-      if (hi - lo < MAIN_QSORT_SMALL_THRESH ||
-          d > MAIN_QSORT_DEPTH_THRESH) {
-         mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget );
-         if (*budget < 0) return;
-         continue;
-      }
-
-      med = (Int32)
-            mmed3 ( block[ptr[ lo         ]+d],
-                    block[ptr[ hi         ]+d],
-                    block[ptr[ (lo+hi)>>1 ]+d] );
-
-      unLo = ltLo = lo;
-      unHi = gtHi = hi;
-
-      while (True) {
-         while (True) {
-            if (unLo > unHi) break;
-            n = ((Int32)block[ptr[unLo]+d]) - med;
-            if (n == 0) {
-               mswap(ptr[unLo], ptr[ltLo]);
-               ltLo++; unLo++; continue;
-            };
-            if (n >  0) break;
-            unLo++;
-         }
-         while (True) {
-            if (unLo > unHi) break;
-            n = ((Int32)block[ptr[unHi]+d]) - med;
-            if (n == 0) {
-               mswap(ptr[unHi], ptr[gtHi]);
-               gtHi--; unHi--; continue;
-            };
-            if (n <  0) break;
-            unHi--;
-         }
-         if (unLo > unHi) break;
-         mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--;
-      }
-
-      AssertD ( unHi == unLo-1, "mainQSort3(2)" );
-
-      if (gtHi < ltLo) {
-         mpush(lo, hi, d+1 );
-         continue;
-      }
-
-      n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n);
-      m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m);
-
-      n = lo + unLo - ltLo - 1;
-      m = hi - (gtHi - unHi) + 1;
-
-      nextLo[0] = lo;  nextHi[0] = n;   nextD[0] = d;
-      nextLo[1] = m;   nextHi[1] = hi;  nextD[1] = d;
-      nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
-
-      if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
-      if (mnextsize(1) < mnextsize(2)) mnextswap(1,2);
-      if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
-
-      AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" );
-      AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" );
-
-      mpush (nextLo[0], nextHi[0], nextD[0]);
-      mpush (nextLo[1], nextHi[1], nextD[1]);
-      mpush (nextLo[2], nextHi[2], nextD[2]);
-   }
-}
-
-#undef mswap
-#undef mvswap
-#undef mpush
-#undef mpop
-#undef mmin
-#undef mnextsize
-#undef mnextswap
-#undef MAIN_QSORT_SMALL_THRESH
-#undef MAIN_QSORT_DEPTH_THRESH
-#undef MAIN_QSORT_STACK_SIZE
-
-
-/*---------------------------------------------*/
-/* Pre:
-      nblock > N_OVERSHOOT
-      block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
-      ((UChar*)block32) [0 .. nblock-1] holds block
-      ptr exists for [0 .. nblock-1]
-
-   Post:
-      ((UChar*)block32) [0 .. nblock-1] holds block
-      All other areas of block32 destroyed
-      ftab [0 .. 65536 ] destroyed
-      ptr [0 .. nblock-1] holds sorted order
-      if (*budget < 0), sorting was abandoned
-*/
-
-#define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8])
-#define SETMASK (1 << 21)
-#define CLEARMASK (~(SETMASK))
-
-static
-void mainSort ( UInt32* ptr,
-                UChar*  block,
-                UInt16* quadrant,
-                UInt32* ftab,
-                Int32   nblock,
-                Int32   verb,
-                Int32*  budget )
-{
-   Int32  i, j, k, ss, sb;
-   Int32  runningOrder[256];
-   Bool   bigDone[256];
-   Int32  copyStart[256];
-   Int32  copyEnd  [256];
-   UChar  c1;
-   Int32  numQSorted;
-   UInt16 s;
-   if (verb >= 4) VPrintf0 ( "        main sort initialise ...\n" );
-
-   /*-- set up the 2-byte frequency table --*/
-   for (i = 65536; i >= 0; i--) ftab[i] = 0;
-
-   j = block[0] << 8;
-   i = nblock-1;
-   for (; i >= 3; i -= 4) {
-      quadrant[i] = 0;
-      j = (j >> 8) | ( ((UInt16)block[i]) << 8);
-      ftab[j]++;
-      quadrant[i-1] = 0;
-      j = (j >> 8) | ( ((UInt16)block[i-1]) << 8);
-      ftab[j]++;
-      quadrant[i-2] = 0;
-      j = (j >> 8) | ( ((UInt16)block[i-2]) << 8);
-      ftab[j]++;
-      quadrant[i-3] = 0;
-      j = (j >> 8) | ( ((UInt16)block[i-3]) << 8);
-      ftab[j]++;
-   }
-   for (; i >= 0; i--) {
-      quadrant[i] = 0;
-      j = (j >> 8) | ( ((UInt16)block[i]) << 8);
-      ftab[j]++;
-   }
-
-   /*-- (emphasises close relationship of block & quadrant) --*/
-   for (i = 0; i < BZ_N_OVERSHOOT; i++) {
-      block   [nblock+i] = block[i];
-      quadrant[nblock+i] = 0;
-   }
-
-   if (verb >= 4) VPrintf0 ( "        bucket sorting ...\n" );
-
-   /*-- Complete the initial radix sort --*/
-   for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1];
-
-   s = block[0] << 8;
-   i = nblock-1;
-   for (; i >= 3; i -= 4) {
-      s = (s >> 8) | (block[i] << 8);
-      j = ftab[s] -1;
-      ftab[s] = j;
-      ptr[j] = i;
-      s = (s >> 8) | (block[i-1] << 8);
-      j = ftab[s] -1;
-      ftab[s] = j;
-      ptr[j] = i-1;
-      s = (s >> 8) | (block[i-2] << 8);
-      j = ftab[s] -1;
-      ftab[s] = j;
-      ptr[j] = i-2;
-      s = (s >> 8) | (block[i-3] << 8);
-      j = ftab[s] -1;
-      ftab[s] = j;
-      ptr[j] = i-3;
-   }
-   for (; i >= 0; i--) {
-      s = (s >> 8) | (block[i] << 8);
-      j = ftab[s] -1;
-      ftab[s] = j;
-      ptr[j] = i;
-   }
-
-   /*--
-      Now ftab contains the first loc of every small bucket.
-      Calculate the running order, from smallest to largest
-      big bucket.
-   --*/
-   for (i = 0; i <= 255; i++) {
-      bigDone     [i] = False;
-      runningOrder[i] = i;
-   }
-
-   {
-      Int32 vv;
-      Int32 h = 1;
-      do h = 3 * h + 1; while (h <= 256);
-      do {
-         h = h / 3;
-         for (i = h; i <= 255; i++) {
-            vv = runningOrder[i];
-            j = i;
-            while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) {
-               runningOrder[j] = runningOrder[j-h];
-               j = j - h;
-               if (j <= (h - 1)) goto zero;
-            }
-            zero:
-            runningOrder[j] = vv;
-         }
-      } while (h != 1);
-   }
-
-   /*--
-      The main sorting loop.
-   --*/
-
-   numQSorted = 0;
-
-   for (i = 0; i <= 255; i++) {
-
-      /*--
-         Process big buckets, starting with the least full.
-         Basically this is a 3-step process in which we call
-         mainQSort3 to sort the small buckets [ss, j], but
-         also make a big effort to avoid the calls if we can.
-      --*/
-      ss = runningOrder[i];
-
-      /*--
-         Step 1:
-         Complete the big bucket [ss] by quicksorting
-         any unsorted small buckets [ss, j], for j != ss.
-         Hopefully previous pointer-scanning phases have already
-         completed many of the small buckets [ss, j], so
-         we don't have to sort them at all.
-      --*/
-      for (j = 0; j <= 255; j++) {
-         if (j != ss) {
-            sb = (ss << 8) + j;
-            if ( ! (ftab[sb] & SETMASK) ) {
-               Int32 lo = ftab[sb]   & CLEARMASK;
-               Int32 hi = (ftab[sb+1] & CLEARMASK) - 1;
-               if (hi > lo) {
-                  if (verb >= 4)
-                     VPrintf4 ( "        qsort [0x%x, 0x%x]   "
-                                "done %d   this %d\n",
-                                ss, j, numQSorted, hi - lo + 1 );
-                  mainQSort3 (
-                     ptr, block, quadrant, nblock,
-                     lo, hi, BZ_N_RADIX, budget
-                  );
-                  numQSorted += (hi - lo + 1);
-                  if (*budget < 0) return;
-               }
-            }
-            ftab[sb] |= SETMASK;
-         }
-      }
-
-      AssertH ( !bigDone[ss], 1006 );
-
-      /*--
-         Step 2:
-         Now scan this big bucket [ss] so as to synthesise the
-         sorted order for small buckets [t, ss] for all t,
-         including, magically, the bucket [ss,ss] too.
-         This will avoid doing Real Work in subsequent Step 1's.
-      --*/
-      {
-         for (j = 0; j <= 255; j++) {
-            copyStart[j] =  ftab[(j << 8) + ss]     & CLEARMASK;
-            copyEnd  [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1;
-         }
-         for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) {
-            k = ptr[j]-1; if (k < 0) k += nblock;
-            c1 = block[k];
-            if (!bigDone[c1])
-               ptr[ copyStart[c1]++ ] = k;
-         }
-         for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) {
-            k = ptr[j]-1; if (k < 0) k += nblock;
-            c1 = block[k];
-            if (!bigDone[c1])
-               ptr[ copyEnd[c1]-- ] = k;
-         }
-      }
-
-      AssertH ( (copyStart[ss]-1 == copyEnd[ss])
-                ||
-                /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1.
-                   Necessity for this case is demonstrated by compressing
-                   a sequence of approximately 48.5 million of character
-                   251; 1.0.0/1.0.1 will then die here. */
-                (copyStart[ss] == 0 && copyEnd[ss] == nblock-1),
-                1007 )
-
-      for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK;
-
-      /*--
-         Step 3:
-         The [ss] big bucket is now done.  Record this fact,
-         and update the quadrant descriptors.  Remember to
-         update quadrants in the overshoot area too, if
-         necessary.  The "if (i < 255)" test merely skips
-         this updating for the last bucket processed, since
-         updating for the last bucket is pointless.
-
-         The quadrant array provides a way to incrementally
-         cache sort orderings, as they appear, so as to
-         make subsequent comparisons in fullGtU() complete
-         faster.  For repetitive blocks this makes a big
-         difference (but not big enough to be able to avoid
-         the fallback sorting mechanism, exponential radix sort).
-
-         The precise meaning is: at all times:
-
-            for 0 <= i < nblock and 0 <= j <= nblock
-
-            if block[i] != block[j],
-
-               then the relative values of quadrant[i] and
-                    quadrant[j] are meaningless.
-
-               else {
-                  if quadrant[i] < quadrant[j]
-                     then the string starting at i lexicographically
-                     precedes the string starting at j
-
-                  else if quadrant[i] > quadrant[j]
-                     then the string starting at j lexicographically
-                     precedes the string starting at i
-
-                  else
-                     the relative ordering of the strings starting
-                     at i and j has not yet been determined.
-               }
-      --*/
-      bigDone[ss] = True;
-
-      if (i < 255) {
-         Int32 bbStart  = ftab[ss << 8] & CLEARMASK;
-         Int32 bbSize   = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart;
-         Int32 shifts   = 0;
-
-         while ((bbSize >> shifts) > 65534) shifts++;
-
-         for (j = bbSize-1; j >= 0; j--) {
-            Int32 a2update     = ptr[bbStart + j];
-            UInt16 qVal        = (UInt16)(j >> shifts);
-            quadrant[a2update] = qVal;
-            if (a2update < BZ_N_OVERSHOOT)
-               quadrant[a2update + nblock] = qVal;
-         }
-         AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 );
-      }
-
-   }
-
-   if (verb >= 4)
-      VPrintf3 ( "        %d pointers, %d sorted, %d scanned\n",
-                 nblock, numQSorted, nblock - numQSorted );
-}
-
-#undef BIGFREQ
-#undef SETMASK
-#undef CLEARMASK
-
-
-/*---------------------------------------------*/
-/* Pre:
-      nblock > 0
-      arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
-      ((UChar*)arr2)  [0 .. nblock-1] holds block
-      arr1 exists for [0 .. nblock-1]
-
-   Post:
-      ((UChar*)arr2) [0 .. nblock-1] holds block
-      All other areas of block destroyed
-      ftab [ 0 .. 65536 ] destroyed
-      arr1 [0 .. nblock-1] holds sorted order
-*/
-void BZ2_blockSort ( EState* s )
-{
-   UInt32* ptr    = s->ptr;
-   UChar*  block  = s->block;
-   UInt32* ftab   = s->ftab;
-   Int32   nblock = s->nblock;
-   Int32   verb   = s->verbosity;
-   Int32   wfact  = s->workFactor;
-   UInt16* quadrant;
-   Int32   budget;
-   Int32   budgetInit;
-   Int32   i;
-
-   if (nblock < 10000) {
-      fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
-   } else {
-      /* Calculate the location for quadrant, remembering to get
-         the alignment right.  Assumes that &(block[0]) is at least
-         2-byte aligned -- this should be ok since block is really
-         the first section of arr2.
-      */
-      i = nblock+BZ_N_OVERSHOOT;
-      if (i & 1) i++;
-      quadrant = (UInt16*)(&(block[i]));
-
-      /* (wfact-1) / 3 puts the default-factor-30
-         transition point at very roughly the same place as
-         with v0.1 and v0.9.0.
-         Not that it particularly matters any more, since the
-         resulting compressed stream is now the same regardless
-         of whether or not we use the main sort or fallback sort.
-      */
-      if (wfact < 1  ) wfact = 1;
-      if (wfact > 100) wfact = 100;
-      budgetInit = nblock * ((wfact-1) / 3);
-      budget = budgetInit;
-
-      mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget );
-      if (verb >= 3)
-         VPrintf3 ( "      %d work, %d block, ratio %5.2f\n",
-                    budgetInit - budget,
-                    nblock,
-                    (float)(budgetInit - budget) /
-                    (float)(nblock==0 ? 1 : nblock) );
-      if (budget < 0) {
-         if (verb >= 2)
-            VPrintf0 ( "    too repetitive; using fallback"
-                       " sorting algorithm\n" );
-         fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
-      }
-   }
-
-   s->origPtr = -1;
-   for (i = 0; i < s->nblock; i++)
-      if (ptr[i] == 0)
-         { s->origPtr = i; break; };
-
-   AssertH( s->origPtr != -1, 1003 );
-}
-
-
-/*-------------------------------------------------------------*/
-/*--- end                                       blocksort.c ---*/
-/*-------------------------------------------------------------*/
diff --git a/thirdparty/bzip2/bz_version.h.in b/thirdparty/bzip2/bz_version.h.in
deleted file mode 100644
index 1adb1b55b..000000000
--- a/thirdparty/bzip2/bz_version.h.in
+++ /dev/null
@@ -1 +0,0 @@
-#define BZ_VERSION "@BZ_VERSION@"
diff --git a/thirdparty/bzip2/bzdiff b/thirdparty/bzip2/bzdiff
deleted file mode 100755
index bd96c27c3..000000000
--- a/thirdparty/bzip2/bzdiff
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/bin/sh
-# sh is buggy on RS/6000 AIX 3.2. Replace above line with #!/bin/ksh
-
-# Bzcmp/diff wrapped for bzip2, 
-# adapted from zdiff by Philippe Troin  for Debian GNU/Linux.
-
-# Bzcmp and bzdiff are used to invoke the cmp or the  diff  pro-
-# gram  on compressed files.  All options specified are passed
-# directly to cmp or diff.  If only 1 file is specified,  then
-# the  files  compared  are file1 and an uncompressed file1.gz.
-# If two files are specified, then they are  uncompressed  (if
-# necessary) and fed to cmp or diff.  The exit status from cmp
-# or diff is preserved.
-
-PATH="/usr/bin:/bin:$PATH"; export PATH
-prog=`echo $0 | sed 's|.*/||'`
-case "$prog" in
-  *cmp) comp=${CMP-cmp}   ;;
-  *)    comp=${DIFF-diff} ;;
-esac
-
-OPTIONS=
-FILES=
-for ARG
-do
-    case "$ARG" in
-    -*)	OPTIONS="$OPTIONS $ARG";;
-     *)	if test -f "$ARG"; then
-            FILES="$FILES $ARG"
-        else
-            echo "${prog}: $ARG not found or not a regular file"
-	    exit 1
-        fi ;;
-    esac
-done
-if test -z "$FILES"; then
-	echo "Usage: $prog [${comp}_options] file [file]"
-	exit 1
-fi
-set $FILES
-if test $# -eq 1; then
-	FILE=`echo "$1" | sed 's/.bz2$//'`
-	bzip2 -cd "$FILE.bz2" | $comp $OPTIONS - "$FILE"
-	STAT="$?"
-
-elif test $# -eq 2; then
-	case "$1" in
-        *.bz2)
-                case "$2" in
-	        *.bz2)
-			F=`echo "$2" | sed 's|.*/||;s|.bz2$||'`
-			tmp=`mktemp "${TMPDIR:-/tmp}"/bzdiff.XXXXXXXXXX` || {
-			      echo 'cannot create a temporary file' >&2
-			      exit 1
-			}
-                        bzip2 -cdfq "$2" > "$tmp"
-                        bzip2 -cdfq "$1" | $comp $OPTIONS - "$tmp"
-                        STAT="$?"
-			/bin/rm -f "$tmp";;
-
-                *)      bzip2 -cdfq "$1" | $comp $OPTIONS - "$2"
-                        STAT="$?";;
-                esac;;
-        *)      case "$2" in
-	        *.bz2)
-                        bzip2 -cdfq "$2" | $comp $OPTIONS "$1" -
-                        STAT="$?";;
-                *)      $comp $OPTIONS "$1" "$2"
-                        STAT="$?";;
-                esac;;
-	esac
-else
-	echo "Usage: $prog [${comp}_options] file [file]"
-	exit 1
-fi
-exit "$STAT"
diff --git a/thirdparty/bzip2/bzgrep b/thirdparty/bzip2/bzgrep
deleted file mode 100644
index cd29ba880..000000000
--- a/thirdparty/bzip2/bzgrep
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/bin/sh
-
-# Bzgrep wrapped for bzip2, 
-# adapted from zgrep by Philippe Troin  for Debian GNU/Linux.
-## zgrep notice:
-## zgrep -- a wrapper around a grep program that decompresses files as needed
-## Adapted from a version sent by Charles Levert 
-
-PATH="/usr/bin:$PATH"; export PATH
-
-prog=`echo $0 | sed 's|.*/||'`
-case "$prog" in
-	*egrep)	grep=${EGREP-grep -E}	;;
-	*fgrep)	grep=${FGREP-grep -F}	;;
-	*)	grep=${GREP-grep}	;;
-esac
-pat=""
-while test $# -ne 0; do
-  case "$1" in
-  -e | -f) opt="$opt $1"; shift; pat="$1"
-           if test "$grep" = grep; then  # grep is buggy with -e on SVR4
-             grep="grep -E"
-           fi;;
-  -A | -B) opt="$opt $1 $2"; shift;;
-  -*)	   opt="$opt $1";;
-   *)      if test -z "$pat"; then
-	     pat="$1"
-	   else
-	     break;
-           fi;;
-  esac
-  shift
-done
-
-if test -z "$pat"; then
-  echo "grep through bzip2 files"
-  echo "usage: $prog [grep_options] pattern [files]"
-  exit 1
-fi
-
-list=0
-silent=0
-op=`echo "$opt" | sed -e 's/ //g' -e 's/-//g'`
-case "$op" in
-  *l*) list=1
-esac
-case "$op" in
-  *h*) silent=1
-esac
-
-if test $# -eq 0; then
-  bzip2 -cdfq | $grep $opt "$pat"
-  exit $?
-fi
-
-res=0
-for i do
-  if test -f "$i"; then :; else if test -f "$i.bz2"; then i="$i.bz2"; fi; fi
-  if test $list -eq 1; then
-    bzip2 -cdfq "$i" | $grep $opt "$pat" 2>&1 > /dev/null && echo $i
-    r=$?
-  elif test $# -eq 1 -o $silent -eq 1; then
-    bzip2 -cdfq "$i" | $grep $opt "$pat"
-    r=$?
-  else
-    j=$(echo "$i" | sed 's/\\/&&/g;s/|/\\&/g;s/&/\\&/g')
-    j=`printf "%s" "$j" | tr '\n' ' '`
-    # A trick adapted from
-    # https://groups.google.com/forum/#!original/comp.unix.shell/x1345iu10eg/Nn1n-1r1uU0J
-    # that has the same effect as the following bash code:
-    # bzip2 -cdfq "$i" | $grep $opt "$pat" | sed "s|^|${j}:|"
-    # r=${PIPESTATUS[1]}
-    exec 3>&1
-    eval `
-      exec 4>&1 >&3 3>&-
-      {
-        bzip2 -cdfq "$i" 4>&-
-      } | {
-        $grep $opt "$pat" 4>&-; echo "r=$?;" >&4
-      } | sed "s|^|${j}:|"
-    `
-  fi
-  test "$r" -ne 0 && res="$r"
-done
-exit $res
diff --git a/thirdparty/bzip2/bzip2.c b/thirdparty/bzip2/bzip2.c
deleted file mode 100644
index a3a916b5b..000000000
--- a/thirdparty/bzip2/bzip2.c
+++ /dev/null
@@ -1,2029 +0,0 @@
-
-/*-----------------------------------------------------------*/
-/*--- A block-sorting, lossless compressor        bzip2.c ---*/
-/*-----------------------------------------------------------*/
-
-/* ------------------------------------------------------------------
-   This file is part of bzip2/libbzip2, a program and library for
-   lossless, block-sorting data compression.
-
-   bzip2/libbzip2 version 1.1.0 of 6 September 2010
-   Copyright (C) 1996-2010 Julian Seward 
-
-   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.
-   ------------------------------------------------------------------ */
-
-
-/*---------------------------------------------*/
-/*--
-  Some stuff for all platforms.
---*/
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include "bzlib.h"
-
-#define ERROR_IF_EOF(i)       { if ((i) == EOF)  ioError(); }
-#define ERROR_IF_NOT_ZERO(i)  { if ((i) != 0)    ioError(); }
-#define ERROR_IF_MINUS_ONE(i) { if ((i) == (-1)) ioError(); }
-
-
-/*---------------------------------------------*/
-/*--
-   Platform-specific stuff.
---*/
-
-#if BZ_UNIX
-#   include 
-#   include 
-#   include 
-#   include 
-#   include 
-#   include 
-
-#   define PATH_SEP    '/'
-#   define MY_LSTAT    lstat
-#   define MY_STAT     stat
-#   define MY_S_ISREG  S_ISREG
-#   define MY_S_ISDIR  S_ISDIR
-
-#   define APPEND_FILESPEC(root, name) \
-      root=snocString((root), (name))
-
-#   define APPEND_FLAG(root, name) \
-      root=snocString((root), (name))
-
-#   define SET_BINARY_MODE(fd) /**/
-
-#   ifdef __GNUC__
-#      define NORETURN __attribute__ ((noreturn))
-#   else
-#      define NORETURN /**/
-#   endif
-
-#   ifdef __DJGPP__
-#     include 
-#     include 
-#     undef MY_LSTAT
-#     undef MY_STAT
-#     define MY_LSTAT stat
-#     define MY_STAT stat
-#     undef SET_BINARY_MODE
-#     define SET_BINARY_MODE(fd)                        \
-        do {                                            \
-           int retVal = setmode ( fileno ( fd ),        \
-                                  O_BINARY );           \
-           ERROR_IF_MINUS_ONE ( retVal );               \
-        } while ( 0 )
-#   endif
-
-#   ifdef __CYGWIN__
-#     include 
-#     include 
-#     undef SET_BINARY_MODE
-#     define SET_BINARY_MODE(fd)                        \
-        do {                                            \
-           int retVal = setmode ( fileno ( fd ),        \
-                                  O_BINARY );           \
-           ERROR_IF_MINUS_ONE ( retVal );               \
-        } while ( 0 )
-#   endif
-#endif /* BZ_UNIX */
-
-
-
-#if BZ_LCCWIN32
-#   include 
-#   include 
-#   include 
-
-#   define NORETURN       /**/
-#   define PATH_SEP       '\\'
-#   define MY_LSTAT       _stati64
-#   define MY_STAT        _stati64
-#   define MY_S_ISREG(x)  ((x) & _S_IFREG)
-#   define MY_S_ISDIR(x)  ((x) & _S_IFDIR)
-
-#   define APPEND_FLAG(root, name) \
-      root=snocString((root), (name))
-
-#   define APPEND_FILESPEC(root, name)                \
-      root = snocString ((root), (name))
-
-#   define SET_BINARY_MODE(fd)                        \
-      do {                                            \
-         int retVal = setmode ( fileno ( fd ),        \
-                                O_BINARY );           \
-         ERROR_IF_MINUS_ONE ( retVal );               \
-      } while ( 0 )
-
-#endif /* BZ_LCCWIN32 */
-
-#if _WIN32
-#define fileno          _fileno
-#define write           _write
-#define isatty          _isatty
-#define setmode         _setmode
-#define STDERR_FILENO   _fileno(stderr)
-#endif
-
-/*---------------------------------------------*/
-/*--
-  Some more stuff for all platforms :-)
---*/
-
-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)
-
-/*--
-  IntNative is your platform's `native' int size.
-  Only here to avoid probs with 64-bit platforms.
---*/
-typedef int IntNative;
-
-
-/*---------------------------------------------------*/
-/*--- Misc (file handling) data decls             ---*/
-/*---------------------------------------------------*/
-
-Int32   verbosity;
-Bool    keepInputFiles, smallMode, deleteOutputOnInterrupt;
-Bool    forceOverwrite, testFailsExist, unzFailsExist, noisy;
-Int32   numFileNames, numFilesProcessed, blockSize100k;
-Int32   exitValue;
-
-/*-- source modes; F==file, I==stdin, O==stdout --*/
-#define SM_I2O           1
-#define SM_F2O           2
-#define SM_F2F           3
-
-/*-- operation modes --*/
-#define OM_Z             1
-#define OM_UNZ           2
-#define OM_TEST          3
-
-Int32   opMode;
-Int32   srcMode;
-
-#define FILE_NAME_LEN 1034
-
-Int32   longestFileName;
-Char    inName [FILE_NAME_LEN];
-Char    outName[FILE_NAME_LEN];
-Char    tmpName[FILE_NAME_LEN];
-Char    *progName;
-Char    progNameReally[FILE_NAME_LEN];
-FILE    *outputHandleJustInCase;
-Int32   workFactor;
-
-static void    panic                 ( const Char* ) NORETURN;
-static void    ioError               ( void )        NORETURN;
-static void    outOfMemory           ( void )        NORETURN;
-static void    configError           ( void )        NORETURN;
-static void    crcError              ( void )        NORETURN;
-static void    cleanUpAndFail        ( Int32 )       NORETURN;
-static void    compressedStreamEOF   ( void )        NORETURN;
-
-static void    copyFileName ( Char*, Char* );
-static void*   myMalloc     ( Int32 );
-static void    applySavedFileAttrToOutputFile ( IntNative fd );
-
-
-
-/*---------------------------------------------------*/
-/*--- An implementation of 64-bit ints.  Sigh.    ---*/
-/*--- Roll on widespread deployment of ANSI C9X ! ---*/
-/*---------------------------------------------------*/
-
-typedef
-   struct { UChar b[8]; }
-   UInt64;
-
-
-static
-void uInt64_from_UInt32s ( UInt64* n, UInt32 lo32, UInt32 hi32 )
-{
-   n->b[7] = (UChar)((hi32 >> 24) & 0xFF);
-   n->b[6] = (UChar)((hi32 >> 16) & 0xFF);
-   n->b[5] = (UChar)((hi32 >> 8)  & 0xFF);
-   n->b[4] = (UChar) (hi32        & 0xFF);
-   n->b[3] = (UChar)((lo32 >> 24) & 0xFF);
-   n->b[2] = (UChar)((lo32 >> 16) & 0xFF);
-   n->b[1] = (UChar)((lo32 >> 8)  & 0xFF);
-   n->b[0] = (UChar) (lo32        & 0xFF);
-}
-
-
-static
-double uInt64_to_double ( UInt64* n )
-{
-   Int32  i;
-   double base = 1.0;
-   double sum  = 0.0;
-   for (i = 0; i < 8; i++) {
-      sum  += base * (double)(n->b[i]);
-      base *= 256.0;
-   }
-   return sum;
-}
-
-
-static
-Bool uInt64_isZero ( UInt64* n )
-{
-   Int32 i;
-   for (i = 0; i < 8; i++)
-      if (n->b[i] != 0) return 0;
-   return 1;
-}
-
-
-/* Divide *n by 10, and return the remainder.  */
-static
-Int32 uInt64_qrm10 ( UInt64* n )
-{
-   UInt32 rem, tmp;
-   Int32  i;
-   rem = 0;
-   for (i = 7; i >= 0; i--) {
-      tmp = rem * 256 + n->b[i];
-      n->b[i] = tmp / 10;
-      rem = tmp % 10;
-   }
-   return rem;
-}
-
-
-/* ... and the Whole Entire Point of all this UInt64 stuff is
-   so that we can supply the following function.
-*/
-static
-void uInt64_toAscii ( char* outbuf, UInt64* n )
-{
-   Int32  i, q;
-   UChar  buf[32];
-   Int32  nBuf   = 0;
-   UInt64 n_copy = *n;
-   do {
-      q = uInt64_qrm10 ( &n_copy );
-      buf[nBuf] = q + '0';
-      nBuf++;
-   } while (!uInt64_isZero(&n_copy));
-   outbuf[nBuf] = 0;
-   for (i = 0; i < nBuf; i++)
-      outbuf[i] = buf[nBuf-i-1];
-}
-
-
-/*---------------------------------------------------*/
-/*--- Processing of complete files and streams    ---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------*/
-static
-Bool myfeof ( FILE* f )
-{
-   Int32 c = fgetc ( f );
-   if (c == EOF) return True;
-   ungetc ( c, f );
-   return False;
-}
-
-
-/*---------------------------------------------*/
-static
-void compressStream ( FILE *stream, FILE *zStream )
-{
-   BZFILE* bzf = NULL;
-   UChar   ibuf[5000];
-   Int32   nIbuf;
-   UInt32  nbytes_in_lo32, nbytes_in_hi32;
-   UInt32  nbytes_out_lo32, nbytes_out_hi32;
-   Int32   bzerr, bzerr_dummy, ret;
-
-   SET_BINARY_MODE(stream);
-   SET_BINARY_MODE(zStream);
-
-   if (ferror(stream)) goto errhandler_io;
-   if (ferror(zStream)) goto errhandler_io;
-
-   bzf = BZ2_bzWriteOpen ( &bzerr, zStream,
-                           blockSize100k, verbosity, workFactor );
-   if (bzerr != BZ_OK) goto errhandler;
-
-   if (verbosity >= 2) fprintf ( stderr, "\n" );
-
-   while (True) {
-
-      if (myfeof(stream)) break;
-      nIbuf = fread ( ibuf, sizeof(UChar), 5000, stream );
-      if (ferror(stream)) goto errhandler_io;
-      if (nIbuf > 0) BZ2_bzWrite ( &bzerr, bzf, (void*)ibuf, nIbuf );
-      if (bzerr != BZ_OK) goto errhandler;
-
-   }
-
-   BZ2_bzWriteClose64 ( &bzerr, bzf, 0,
-                        &nbytes_in_lo32, &nbytes_in_hi32,
-                        &nbytes_out_lo32, &nbytes_out_hi32 );
-   if (bzerr != BZ_OK) goto errhandler;
-
-   if (ferror(zStream)) goto errhandler_io;
-   ret = fflush ( zStream );
-   if (ret == EOF) goto errhandler_io;
-   if (zStream != stdout) {
-      Int32 fd = fileno ( zStream );
-      if (fd < 0) goto errhandler_io;
-      applySavedFileAttrToOutputFile ( fd );
-      ret = fclose ( zStream );
-      outputHandleJustInCase = NULL;
-      if (ret == EOF) goto errhandler_io;
-   }
-   outputHandleJustInCase = NULL;
-   if (ferror(stream)) goto errhandler_io;
-   ret = fclose ( stream );
-   if (ret == EOF) goto errhandler_io;
-
-   if (verbosity >= 1) {
-      if (nbytes_in_lo32 == 0 && nbytes_in_hi32 == 0) {
-         fprintf ( stderr, " no data compressed.\n");
-      } else {
-         Char   buf_nin[32], buf_nout[32];
-         UInt64 nbytes_in,   nbytes_out;
-         double nbytes_in_d, nbytes_out_d;
-         uInt64_from_UInt32s ( &nbytes_in,
-            nbytes_in_lo32, nbytes_in_hi32 );
-         uInt64_from_UInt32s ( &nbytes_out,
-            nbytes_out_lo32, nbytes_out_hi32 );
-         nbytes_in_d  = uInt64_to_double ( &nbytes_in );
-         nbytes_out_d = uInt64_to_double ( &nbytes_out );
-         uInt64_toAscii ( buf_nin, &nbytes_in );
-         uInt64_toAscii ( buf_nout, &nbytes_out );
-         fprintf ( stderr, "%6.3f:1, %6.3f bits/byte, "
-            "%5.2f%% saved, %s in, %s out.\n",
-            nbytes_in_d / nbytes_out_d,
-            (8.0 * nbytes_out_d) / nbytes_in_d,
-            100.0 * (1.0 - nbytes_out_d / nbytes_in_d),
-            buf_nin,
-            buf_nout
-         );
-      }
-   }
-
-   return;
-
-errhandler:
-   BZ2_bzWriteClose64 ( &bzerr_dummy, bzf, 1,
-                        &nbytes_in_lo32, &nbytes_in_hi32,
-                        &nbytes_out_lo32, &nbytes_out_hi32 );
-   switch (bzerr) {
-      case BZ_CONFIG_ERROR:
-         configError(); break;
-      case BZ_MEM_ERROR:
-         outOfMemory (); break;
-      case BZ_IO_ERROR:
-         errhandler_io:
-         ioError(); break;
-      default:
-         panic ( "compress:unexpected error" );
-   }
-
-   panic ( "compress:end" );
-   /*notreached*/
-}
-
-
-
-/*---------------------------------------------*/
-static
-Bool uncompressStream ( FILE *zStream, FILE *stream )
-{
-   BZFILE* bzf = NULL;
-   Int32   bzerr, bzerr_dummy, ret, nread, streamNo, i;
-   UChar   obuf[5000];
-   UChar   unused[BZ_MAX_UNUSED];
-   Int32   nUnused;
-   void*   unusedTmpV;
-   UChar*  unusedTmp;
-
-   nUnused = 0;
-   streamNo = 0;
-
-   SET_BINARY_MODE(stream);
-   SET_BINARY_MODE(zStream);
-
-   if (ferror(stream)) goto errhandler_io;
-   if (ferror(zStream)) goto errhandler_io;
-
-   while (True) {
-
-      bzf = BZ2_bzReadOpen (
-               &bzerr, zStream, verbosity,
-               (int)smallMode, unused, nUnused
-            );
-      if (bzf == NULL || bzerr != BZ_OK) goto errhandler;
-      streamNo++;
-
-      while (bzerr == BZ_OK) {
-         nread = BZ2_bzRead ( &bzerr, bzf, obuf, 5000 );
-         if (bzerr == BZ_DATA_ERROR_MAGIC) goto trycat;
-         if ((bzerr == BZ_OK || bzerr == BZ_STREAM_END) && nread > 0)
-            fwrite ( obuf, sizeof(UChar), nread, stream );
-         if (ferror(stream)) goto errhandler_io;
-      }
-      if (bzerr != BZ_STREAM_END) goto errhandler;
-
-      BZ2_bzReadGetUnused ( &bzerr, bzf, &unusedTmpV, &nUnused );
-      if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
-
-      unusedTmp = (UChar*)unusedTmpV;
-      for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
-
-      BZ2_bzReadClose ( &bzerr, bzf );
-      if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
-
-      if (nUnused == 0 && myfeof(zStream)) break;
-   }
-
-closeok:
-   if (ferror(zStream)) goto errhandler_io;
-   if (stream != stdout) {
-      Int32 fd = fileno ( stream );
-      if (fd < 0) goto errhandler_io;
-      applySavedFileAttrToOutputFile ( fd );
-   }
-   ret = fclose ( zStream );
-   if (ret == EOF) goto errhandler_io;
-
-   if (ferror(stream)) goto errhandler_io;
-   ret = fflush ( stream );
-   if (ret != 0) goto errhandler_io;
-   if (stream != stdout) {
-      ret = fclose ( stream );
-      outputHandleJustInCase = NULL;
-      if (ret == EOF) goto errhandler_io;
-   }
-   outputHandleJustInCase = NULL;
-   if (verbosity >= 2) fprintf ( stderr, "\n    " );
-   return True;
-
-trycat:
-   if (forceOverwrite) {
-      rewind(zStream);
-      while (True) {
-         if (myfeof(zStream)) break;
-         nread = fread ( obuf, sizeof(UChar), 5000, zStream );
-         if (ferror(zStream)) goto errhandler_io;
-         if (nread > 0) fwrite ( obuf, sizeof(UChar), nread, stream );
-         if (ferror(stream)) goto errhandler_io;
-      }
-      goto closeok;
-   }
-
-errhandler:
-   BZ2_bzReadClose ( &bzerr_dummy, bzf );
-   switch (bzerr) {
-      case BZ_CONFIG_ERROR:
-         configError(); break;
-      case BZ_IO_ERROR:
-         errhandler_io:
-         ioError(); break;
-      case BZ_DATA_ERROR:
-         crcError();
-      case BZ_MEM_ERROR:
-         outOfMemory();
-      case BZ_UNEXPECTED_EOF:
-         compressedStreamEOF();
-      case BZ_DATA_ERROR_MAGIC:
-         if (zStream != stdin) fclose(zStream);
-         if (stream != stdout) fclose(stream);
-         if (streamNo == 1) {
-            return False;
-         } else {
-            if (noisy)
-            fprintf ( stderr,
-                      "\n%s: %s: trailing garbage after EOF ignored\n",
-                      progName, inName );
-            return True;
-         }
-      default:
-         panic ( "decompress:unexpected error" );
-   }
-
-   panic ( "decompress:end" );
-   return True; /*notreached*/
-}
-
-
-/*---------------------------------------------*/
-static
-Bool testStream ( FILE *zStream )
-{
-   BZFILE* bzf = NULL;
-   Int32   bzerr, bzerr_dummy, ret, streamNo, i;
-   UChar   obuf[5000];
-   UChar   unused[BZ_MAX_UNUSED];
-   Int32   nUnused;
-   void*   unusedTmpV;
-   UChar*  unusedTmp;
-
-   nUnused = 0;
-   streamNo = 0;
-
-   SET_BINARY_MODE(zStream);
-   if (ferror(zStream)) goto errhandler_io;
-
-   while (True) {
-
-      bzf = BZ2_bzReadOpen (
-               &bzerr, zStream, verbosity,
-               (int)smallMode, unused, nUnused
-            );
-      if (bzf == NULL || bzerr != BZ_OK) goto errhandler;
-      streamNo++;
-
-      while (bzerr == BZ_OK) {
-         BZ2_bzRead ( &bzerr, bzf, obuf, 5000 );
-         if (bzerr == BZ_DATA_ERROR_MAGIC) goto errhandler;
-      }
-      if (bzerr != BZ_STREAM_END) goto errhandler;
-
-      BZ2_bzReadGetUnused ( &bzerr, bzf, &unusedTmpV, &nUnused );
-      if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
-
-      unusedTmp = (UChar*)unusedTmpV;
-      for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
-
-      BZ2_bzReadClose ( &bzerr, bzf );
-      if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
-      if (nUnused == 0 && myfeof(zStream)) break;
-
-   }
-
-   if (ferror(zStream)) goto errhandler_io;
-   ret = fclose ( zStream );
-   if (ret == EOF) goto errhandler_io;
-
-   if (verbosity >= 2) fprintf ( stderr, "\n    " );
-   return True;
-
-errhandler:
-   BZ2_bzReadClose ( &bzerr_dummy, bzf );
-   if (verbosity == 0)
-      fprintf ( stderr, "%s: %s: ", progName, inName );
-   switch (bzerr) {
-      case BZ_CONFIG_ERROR:
-         configError(); break;
-      case BZ_IO_ERROR:
-         errhandler_io:
-         ioError(); break;
-      case BZ_DATA_ERROR:
-         fprintf ( stderr,
-                   "data integrity (CRC) error in data\n" );
-         return False;
-      case BZ_MEM_ERROR:
-         outOfMemory();
-      case BZ_UNEXPECTED_EOF:
-         fprintf ( stderr,
-                   "file ends unexpectedly\n" );
-         return False;
-      case BZ_DATA_ERROR_MAGIC:
-         if (zStream != stdin) fclose(zStream);
-         if (streamNo == 1) {
-          fprintf ( stderr,
-                    "bad magic number (file not created by bzip2)\n" );
-            return False;
-         } else {
-            if (noisy)
-            fprintf ( stderr,
-                      "trailing garbage after EOF ignored\n" );
-            return True;
-         }
-      default:
-         panic ( "test:unexpected error" );
-   }
-
-   panic ( "test:end" );
-   return True; /*notreached*/
-}
-
-
-/*---------------------------------------------------*/
-/*--- Error [non-] handling grunge                ---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------*/
-static
-void setExit ( Int32 v )
-{
-   if (v > exitValue) exitValue = v;
-}
-
-
-/*---------------------------------------------*/
-static
-void cadvise ( void )
-{
-   if (noisy)
-   fprintf (
-      stderr,
-      "\nIt is possible that the compressed file(s) have become corrupted.\n"
-        "You can use the -tvv option to test integrity of such files.\n\n"
-        "You can use the `bzip2recover' program to attempt to recover\n"
-        "data from undamaged sections of corrupted files.\n\n"
-    );
-}
-
-
-/*---------------------------------------------*/
-static
-void showFileNames ( void )
-{
-   if (noisy)
-   fprintf (
-      stderr,
-      "\tInput file = %s, output file = %s\n",
-      inName, outName
-   );
-}
-
-
-/*---------------------------------------------*/
-static
-void cleanUpAndFail ( Int32 ec )
-{
-   IntNative      retVal;
-   struct MY_STAT statBuf;
-
-   if ( srcMode == SM_F2F
-        && opMode != OM_TEST
-        && deleteOutputOnInterrupt ) {
-
-      /* Check whether input file still exists.  Delete output file
-         only if input exists to avoid loss of data.  Joerg Prante, 5
-         January 2002.  (JRS 06-Jan-2002: other changes in 1.0.2 mean
-         this is less likely to happen.  But to be ultra-paranoid, we
-         do the check anyway.)  */
-      retVal = MY_STAT ( inName, &statBuf );
-      if (retVal == 0) {
-         if (noisy)
-            fprintf ( stderr,
-                      "%s: Deleting output file %s, if it exists.\n",
-                      progName, outName );
-         if (outputHandleJustInCase != NULL)
-            fclose ( outputHandleJustInCase );
-         retVal = remove ( outName );
-         if (retVal != 0)
-            fprintf ( stderr,
-                      "%s: WARNING: deletion of output file "
-                      "(apparently) failed.\n",
-                      progName );
-      } else {
-         fprintf ( stderr,
-                   "%s: WARNING: deletion of output file suppressed\n",
-                    progName );
-         fprintf ( stderr,
-                   "%s:    since input file no longer exists.  Output file\n",
-                   progName );
-         fprintf ( stderr,
-                   "%s:    `%s' may be incomplete.\n",
-                   progName, outName );
-         fprintf ( stderr,
-                   "%s:    I suggest doing an integrity test (bzip2 -tv)"
-                   " of it.\n",
-                   progName );
-      }
-   }
-
-   if (noisy && numFileNames > 0 && numFilesProcessed < numFileNames) {
-      fprintf ( stderr,
-                "%s: WARNING: some files have not been processed:\n"
-                "%s:    %d specified on command line, %d not processed yet.\n\n",
-                progName, progName,
-                numFileNames, numFileNames - numFilesProcessed );
-   }
-   setExit(ec);
-   exit(exitValue);
-}
-
-
-/*---------------------------------------------*/
-static
-void panic ( const Char* s )
-{
-   fprintf ( stderr,
-             "\n%s: PANIC -- internal consistency error:\n"
-             "\t%s\n"
-             "\tThis is a BUG.  Please report it at:\n"
-             "\thttps://gitlab.com/bzip2/bzip2/-/issues\n",
-             progName, s );
-   showFileNames();
-   cleanUpAndFail( 3 );
-}
-
-
-/*---------------------------------------------*/
-static
-void crcError ( void )
-{
-   fprintf ( stderr,
-             "\n%s: Data integrity error when decompressing.\n",
-             progName );
-   showFileNames();
-   cadvise();
-   cleanUpAndFail( 2 );
-}
-
-
-/*---------------------------------------------*/
-static
-void compressedStreamEOF ( void )
-{
-   if (noisy) {
-      fprintf ( stderr,
-         "\n%s: Compressed file ends unexpectedly;\n\t"
-         "perhaps it is corrupted?  *Possible* reason follows.\n",
-         progName );
-      perror ( progName );
-      showFileNames();
-      cadvise();
-   }
-   cleanUpAndFail( 2 );
-}
-
-
-/*---------------------------------------------*/
-static
-void ioError ( void )
-{
-   fprintf ( stderr,
-             "\n%s: I/O or other error, bailing out.  "
-             "Possible reason follows.\n",
-             progName );
-   perror ( progName );
-   showFileNames();
-   cleanUpAndFail( 1 );
-}
-
-
-/*---------------------------------------------*/
-static
-void mySignalCatcher ( IntNative n )
-{
-   fprintf ( stderr,
-             "\n%s: Control-C or similar caught, quitting.\n",
-             progName );
-   cleanUpAndFail(1);
-}
-
-
-/*---------------------------------------------*/
-static
-void mySIGSEGVorSIGBUScatcher ( IntNative n )
-{
-   const char *msg;
-   if (opMode == OM_Z)
-      msg = ": Caught a SIGSEGV or SIGBUS whilst compressing.\n"
-      "\n"
-      "   Possible causes are (most likely first):\n"
-      "   (1) This computer has unreliable memory or cache hardware\n"
-      "       (a surprisingly common problem; try a different machine.)\n"
-      "   (2) A bug in the compiler used to create this executable\n"
-      "       (unlikely, if you didn't compile bzip2 yourself.)\n"
-      "   (3) A real bug in bzip2 -- I hope this should never be the case.\n"
-      "   The user's manual, Section 4.3, has more info on (1) and (2).\n"
-      "   \n"
-      "   If you suspect this is a bug in bzip2, or are unsure about (1)\n"
-      "   or (2), report it at: https://gitlab.com/bzip2/bzip2/-/issues\n"
-      "   Section 4.3 of the user's manual describes the info a useful\n"
-      "   bug report should have.  If the manual is available on your\n"
-      "   system, please try and read it before mailing me.  If you don't\n"
-      "   have the manual or can't be bothered to read it, mail me anyway.\n"
-      "\n";
-   else
-      msg = ": Caught a SIGSEGV or SIGBUS whilst decompressing.\n"
-      "\n"
-      "   Possible causes are (most likely first):\n"
-      "   (1) The compressed data is corrupted, and bzip2's usual checks\n"
-      "       failed to detect this.  Try bzip2 -tvv my_file.bz2.\n"
-      "   (2) This computer has unreliable memory or cache hardware\n"
-      "       (a surprisingly common problem; try a different machine.)\n"
-      "   (3) A bug in the compiler used to create this executable\n"
-      "       (unlikely, if you didn't compile bzip2 yourself.)\n"
-      "   (4) A real bug in bzip2 -- I hope this should never be the case.\n"
-      "   The user's manual, Section 4.3, has more info on (2) and (3).\n"
-      "   \n"
-      "   If you suspect this is a bug in bzip2, or are unsure about (2)\n"
-      "   or (3), report it at: https://gitlab.com/bzip2/bzip2/-/issues\n"
-      "   Section 4.3 of the user's manual describes the info a useful\n"
-      "   bug report should have.  If the manual is available on your\n"
-      "   system, please try and read it before mailing me.  If you don't\n"
-      "   have the manual or can't be bothered to read it, mail me anyway.\n"
-      "\n";
-   write ( STDERR_FILENO, "\n", 1 );
-   write ( STDERR_FILENO, progName, strlen ( progName ) );
-   write ( STDERR_FILENO, msg, strlen ( msg ) );
-
-   msg = "\tInput file = ";
-   write ( STDERR_FILENO, msg, strlen (msg) );
-   write ( STDERR_FILENO, inName, strlen (inName) );
-   write ( STDERR_FILENO, "\n", 1 );
-   msg = "\tOutput file = ";
-   write ( STDERR_FILENO, msg, strlen (msg) );
-   write ( STDERR_FILENO, outName, strlen (outName) );
-   write ( STDERR_FILENO, "\n", 1 );
-
-   /* Don't call cleanupAndFail. If we ended up here something went
-      terribly wrong. Trying to clean up might fail spectacularly. */
-
-   if (opMode == OM_Z) setExit(3); else setExit(2);
-   _exit(exitValue);
-}
-
-
-/*---------------------------------------------*/
-static
-void outOfMemory ( void )
-{
-   fprintf ( stderr,
-             "\n%s: couldn't allocate enough memory\n",
-             progName );
-   showFileNames();
-   cleanUpAndFail(1);
-}
-
-
-/*---------------------------------------------*/
-static
-void configError ( void )
-{
-   fprintf ( stderr,
-             "bzip2: I'm not configured correctly for this platform!\n"
-             "\tI require Int32, Int16 and Char to have sizes\n"
-             "\tof 4, 2 and 1 bytes to run properly, and they don't.\n"
-             "\tProbably you can fix this by defining them correctly,\n"
-             "\tand recompiling.  Bye!\n" );
-   setExit(3);
-   exit(exitValue);
-}
-
-
-/*---------------------------------------------------*/
-/*--- The main driver machinery                   ---*/
-/*---------------------------------------------------*/
-
-/* All rather crufty.  The main problem is that input files
-   are stat()d multiple times before use.  This should be
-   cleaned up.
-*/
-
-/*---------------------------------------------*/
-static
-void pad ( Char *s )
-{
-   Int32 i;
-   if ( (Int32)strlen(s) >= longestFileName ) return;
-   for (i = 1; i <= longestFileName - (Int32)strlen(s); i++)
-      fprintf ( stderr, " " );
-}
-
-
-/*---------------------------------------------*/
-static
-void copyFileName ( Char* to, Char* from )
-{
-   if ( strlen(from) > FILE_NAME_LEN-10 )  {
-      fprintf (
-         stderr,
-         "bzip2: file name\n`%s'\n"
-         "is suspiciously (more than %d chars) long.\n"
-         "Try using a reasonable file name instead.  Sorry! :-)\n",
-         from, FILE_NAME_LEN-10
-      );
-      setExit(1);
-      exit(exitValue);
-   }
-
-  strncpy(to,from,FILE_NAME_LEN-10);
-  to[FILE_NAME_LEN-10]='\0';
-}
-
-
-/*---------------------------------------------*/
-static
-Bool fileExists ( Char* name )
-{
-   FILE *tmp   = fopen ( name, "rb" );
-   Bool exists = (tmp != NULL);
-   if (tmp != NULL) fclose ( tmp );
-   return exists;
-}
-
-
-/*---------------------------------------------*/
-/* Open an output file safely with O_EXCL and good permissions.
-   This avoids a race condition in versions < 1.0.2, in which
-   the file was first opened and then had its interim permissions
-   set safely.  We instead use open() to create the file with
-   the interim permissions required. (--- --- rw-).
-
-   For non-Unix platforms, if we are not worrying about
-   security issues, simple this simply behaves like fopen.
-*/
-static
-FILE* fopen_output_safely ( Char* name, const char* mode )
-{
-#  if BZ_UNIX
-   FILE*     fp;
-   IntNative fh;
-   fh = open(name, O_WRONLY|O_CREAT|O_EXCL, S_IWUSR|S_IRUSR);
-   if (fh == -1) return NULL;
-   fp = fdopen(fh, mode);
-   if (fp == NULL) close(fh);
-   return fp;
-#  else
-   return fopen(name, mode);
-#  endif
-}
-
-
-/*---------------------------------------------*/
-/*--
-  if in doubt, return True
---*/
-static
-Bool notAStandardFile ( Char* name )
-{
-   IntNative      i;
-   struct MY_STAT statBuf;
-
-   i = MY_LSTAT ( name, &statBuf );
-   if (i != 0) return True;
-   if (MY_S_ISREG(statBuf.st_mode)) return False;
-   return True;
-}
-
-
-/*---------------------------------------------*/
-/*--
-  rac 11/21/98 see if file has hard links to it
---*/
-static
-Int32 countHardLinks ( Char* name )
-{
-   IntNative      i;
-   struct MY_STAT statBuf;
-
-   i = MY_LSTAT ( name, &statBuf );
-   if (i != 0) return 0;
-   return (statBuf.st_nlink - 1);
-}
-
-
-/*---------------------------------------------*/
-/* Copy modification date, access date, permissions and owner from the
-   source to destination file.  We have to copy this meta-info off
-   into fileMetaInfo before starting to compress / decompress it,
-   because doing it afterwards means we get the wrong access time.
-
-   To complicate matters, in compress() and decompress() below, the
-   sequence of tests preceding the call to saveInputFileMetaInfo()
-   involves calling fileExists(), which in turn establishes its result
-   by attempting to fopen() the file, and if successful, immediately
-   fclose()ing it again.  So we have to assume that the fopen() call
-   does not cause the access time field to be updated.
-
-   Reading of the man page for stat() (man 2 stat) on RedHat 7.2 seems
-   to imply that merely doing open() will not affect the access time.
-   Therefore we merely need to hope that the C library only does
-   open() as a result of fopen(), and not any kind of read()-ahead
-   cleverness.
-
-   It sounds pretty fragile to me.  Whether this carries across
-   robustly to arbitrary Unix-like platforms (or even works robustly
-   on this one, RedHat 7.2) is unknown to me.  Nevertheless ...
-*/
-#if BZ_UNIX
-static
-struct MY_STAT fileMetaInfo;
-#endif
-
-static
-void saveInputFileMetaInfo ( Char *srcName )
-{
-#  if BZ_UNIX
-   IntNative retVal;
-   /* Note use of stat here, not lstat. */
-   retVal = MY_STAT( srcName, &fileMetaInfo );
-   ERROR_IF_NOT_ZERO ( retVal );
-#  endif
-}
-
-
-static
-void applySavedTimeInfoToOutputFile ( Char *dstName )
-{
-#  if BZ_UNIX
-   IntNative      retVal;
-   struct utimbuf uTimBuf;
-
-   uTimBuf.actime = fileMetaInfo.st_atime;
-   uTimBuf.modtime = fileMetaInfo.st_mtime;
-
-   retVal = utime ( dstName, &uTimBuf );
-   ERROR_IF_NOT_ZERO ( retVal );
-#  endif
-}
-
-static
-void applySavedFileAttrToOutputFile ( IntNative fd )
-{
-#  if BZ_UNIX
-   IntNative retVal;
-
-   retVal = fchmod ( fd, fileMetaInfo.st_mode );
-   ERROR_IF_NOT_ZERO ( retVal );
-
-   (void) fchown ( fd, fileMetaInfo.st_uid, fileMetaInfo.st_gid );
-   /* chown() will in many cases return with EPERM, which can
-      be safely ignored.
-   */
-#  endif
-}
-
-
-/*---------------------------------------------*/
-static
-Bool containsDubiousChars ( Char* name )
-{
-#  if BZ_UNIX
-   /* On unix, files can contain any characters and the file expansion
-    * is performed by the shell.
-    */
-   return False;
-#  else /* ! BZ_UNIX */
-   /* On non-unix (Win* platforms), wildcard characters are not allowed in
-    * filenames.
-    */
-   for (; *name != '\0'; name++)
-      if (*name == '?' || *name == '*') return True;
-   return False;
-#  endif /* BZ_UNIX */
-}
-
-
-/*---------------------------------------------*/
-#define BZ_N_SUFFIX_PAIRS 4
-
-const Char* zSuffix[BZ_N_SUFFIX_PAIRS]
-   = { ".bz2", ".bz", ".tbz2", ".tbz" };
-const Char* unzSuffix[BZ_N_SUFFIX_PAIRS]
-   = { "", "", ".tar", ".tar" };
-
-static
-Bool hasSuffix ( Char* s, const Char* suffix )
-{
-   Int32 ns = strlen(s);
-   Int32 nx = strlen(suffix);
-   if (ns < nx) return False;
-   if (strcmp(s + ns - nx, suffix) == 0) return True;
-   return False;
-}
-
-static
-Bool mapSuffix ( Char* name,
-                 const Char* oldSuffix,
-                 const Char* newSuffix )
-{
-   if (!hasSuffix(name,oldSuffix)) return False;
-   name[strlen(name)-strlen(oldSuffix)] = 0;
-   strcat ( name, newSuffix );
-   return True;
-}
-
-
-/*---------------------------------------------*/
-static
-void compress ( Char *name )
-{
-   FILE  *inStr;
-   FILE  *outStr;
-   Int32 n, i;
-   struct MY_STAT statBuf;
-
-   deleteOutputOnInterrupt = False;
-
-   if (name == NULL && srcMode != SM_I2O)
-      panic ( "compress: bad modes\n" );
-
-   switch (srcMode) {
-      case SM_I2O:
-         copyFileName ( inName, (Char*)"(stdin)" );
-         copyFileName ( outName, (Char*)"(stdout)" );
-         break;
-      case SM_F2F:
-         copyFileName ( inName, name );
-         copyFileName ( outName, name );
-         strcat ( outName, ".bz2" );
-         break;
-      case SM_F2O:
-         copyFileName ( inName, name );
-         copyFileName ( outName, (Char*)"(stdout)" );
-         break;
-   }
-
-   if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
-      if (noisy)
-      fprintf ( stderr, "%s: There are no files matching `%s'.\n",
-                progName, inName );
-      setExit(1);
-      return;
-   }
-   if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
-      fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
-                progName, inName, strerror(errno) );
-      setExit(1);
-      return;
-   }
-   for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++) {
-      if (hasSuffix(inName, zSuffix[i])) {
-         if (noisy)
-         fprintf ( stderr,
-                   "%s: Input file %s already has %s suffix.\n",
-                   progName, inName, zSuffix[i] );
-         setExit(1);
-         return;
-      }
-   }
-   if ( srcMode == SM_F2F || srcMode == SM_F2O ) {
-      MY_STAT(inName, &statBuf);
-      if ( MY_S_ISDIR(statBuf.st_mode) ) {
-         fprintf( stderr,
-                  "%s: Input file %s is a directory.\n",
-                  progName,inName);
-         setExit(1);
-         return;
-      }
-   }
-   if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) {
-      if (noisy)
-      fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
-                progName, inName );
-      setExit(1);
-      return;
-   }
-   if ( srcMode == SM_F2F && fileExists ( outName ) ) {
-      if (forceOverwrite) {
-         remove(outName);
-      } else {
-         fprintf ( stderr, "%s: Output file %s already exists.\n",
-            progName, outName );
-         setExit(1);
-         return;
-      }
-   }
-   if ( srcMode == SM_F2F && !forceOverwrite &&
-        (n=countHardLinks ( inName )) > 0) {
-      fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
-                progName, inName, n, n > 1 ? "s" : "" );
-      setExit(1);
-      return;
-   }
-
-   if ( srcMode == SM_F2F ) {
-      /* Save the file's meta-info before we open it.  Doing it later
-         means we mess up the access times. */
-      saveInputFileMetaInfo ( inName );
-   }
-
-   switch ( srcMode ) {
-
-      case SM_I2O:
-         inStr = stdin;
-         outStr = stdout;
-         if ( isatty ( fileno ( stdout ) ) ) {
-            fprintf ( stderr,
-                      "%s: I won't write compressed data to a terminal.\n",
-                      progName );
-            fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
-                              progName, progName );
-            setExit(1);
-            return;
-         };
-         break;
-
-      case SM_F2O:
-         inStr = fopen ( inName, "rb" );
-         outStr = stdout;
-         if ( isatty ( fileno ( stdout ) ) ) {
-            fprintf ( stderr,
-                      "%s: I won't write compressed data to a terminal.\n",
-                      progName );
-            fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
-                              progName, progName );
-            if ( inStr != NULL ) fclose ( inStr );
-            setExit(1);
-            return;
-         };
-         if ( inStr == NULL ) {
-            fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
-                      progName, inName, strerror(errno) );
-            setExit(1);
-            return;
-         };
-         break;
-
-      case SM_F2F:
-         inStr = fopen ( inName, "rb" );
-         outStr = fopen_output_safely ( outName, "wb" );
-         if ( outStr == NULL) {
-            fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
-                      progName, outName, strerror(errno) );
-            if ( inStr != NULL ) fclose ( inStr );
-            setExit(1);
-            return;
-         }
-         if ( inStr == NULL ) {
-            fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
-                      progName, inName, strerror(errno) );
-            if ( outStr != NULL ) fclose ( outStr );
-            setExit(1);
-            return;
-         };
-         break;
-
-      default:
-         panic ( "compress: bad srcMode" );
-         break;
-   }
-
-   if (verbosity >= 1) {
-      fprintf ( stderr,  "  %s: ", inName );
-      pad ( inName );
-      fflush ( stderr );
-   }
-
-   /*--- Now the input and output handles are sane.  Do the Biz. ---*/
-   outputHandleJustInCase = outStr;
-   deleteOutputOnInterrupt = True;
-   compressStream ( inStr, outStr );
-   outputHandleJustInCase = NULL;
-
-   /*--- If there was an I/O error, we won't get here. ---*/
-   if ( srcMode == SM_F2F ) {
-      applySavedTimeInfoToOutputFile ( outName );
-      deleteOutputOnInterrupt = False;
-      if ( !keepInputFiles ) {
-         IntNative retVal = remove ( inName );
-         ERROR_IF_NOT_ZERO ( retVal );
-      }
-   }
-
-   deleteOutputOnInterrupt = False;
-}
-
-
-/*---------------------------------------------*/
-static
-void uncompress ( Char *name )
-{
-   FILE  *inStr;
-   FILE  *outStr;
-   Int32 n, i;
-   Bool  magicNumberOK;
-   Bool  cantGuess;
-   struct MY_STAT statBuf;
-
-   deleteOutputOnInterrupt = False;
-
-   if (name == NULL && srcMode != SM_I2O)
-      panic ( "uncompress: bad modes\n" );
-
-   cantGuess = False;
-   switch (srcMode) {
-      case SM_I2O:
-         copyFileName ( inName, (Char*)"(stdin)" );
-         copyFileName ( outName, (Char*)"(stdout)" );
-         break;
-      case SM_F2F:
-         copyFileName ( inName, name );
-         copyFileName ( outName, name );
-         for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++)
-            if (mapSuffix(outName,zSuffix[i],unzSuffix[i]))
-               goto zzz;
-         cantGuess = True;
-         strcat ( outName, ".out" );
-         break;
-      case SM_F2O:
-         copyFileName ( inName, name );
-         copyFileName ( outName, (Char*)"(stdout)" );
-         break;
-   }
-
-   zzz:
-   if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
-      if (noisy)
-      fprintf ( stderr, "%s: There are no files matching `%s'.\n",
-                progName, inName );
-      setExit(1);
-      return;
-   }
-   if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
-      fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
-                progName, inName, strerror(errno) );
-      setExit(1);
-      return;
-   }
-   if ( srcMode == SM_F2F || srcMode == SM_F2O ) {
-      MY_STAT(inName, &statBuf);
-      if ( MY_S_ISDIR(statBuf.st_mode) ) {
-         fprintf( stderr,
-                  "%s: Input file %s is a directory.\n",
-                  progName,inName);
-         setExit(1);
-         return;
-      }
-   }
-   if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) {
-      if (noisy)
-      fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
-                progName, inName );
-      setExit(1);
-      return;
-   }
-   if ( /* srcMode == SM_F2F implied && */ cantGuess ) {
-      if (noisy)
-      fprintf ( stderr,
-                "%s: Can't guess original name for %s -- using %s\n",
-                progName, inName, outName );
-      /* just a warning, no return */
-   }
-   if ( srcMode == SM_F2F && fileExists ( outName ) ) {
-      if (forceOverwrite) {
-         remove(outName);
-      } else {
-         fprintf ( stderr, "%s: Output file %s already exists.\n",
-                     progName, outName );
-         setExit(1);
-         return;
-      }
-   }
-   if ( srcMode == SM_F2F && !forceOverwrite &&
-        (n=countHardLinks ( inName ) ) > 0) {
-      fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
-                progName, inName, n, n > 1 ? "s" : "" );
-      setExit(1);
-      return;
-   }
-
-   if ( srcMode == SM_F2F ) {
-      /* Save the file's meta-info before we open it.  Doing it later
-         means we mess up the access times. */
-      saveInputFileMetaInfo ( inName );
-   }
-
-   switch ( srcMode ) {
-
-      case SM_I2O:
-         inStr = stdin;
-         outStr = stdout;
-         if ( isatty ( fileno ( stdin ) ) ) {
-            fprintf ( stderr,
-                      "%s: I won't read compressed data from a terminal.\n",
-                      progName );
-            fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
-                              progName, progName );
-            setExit(1);
-            return;
-         };
-         break;
-
-      case SM_F2O:
-         inStr = fopen ( inName, "rb" );
-         outStr = stdout;
-         if ( inStr == NULL ) {
-            fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
-                      progName, inName, strerror(errno) );
-            if ( inStr != NULL ) fclose ( inStr );
-            setExit(1);
-            return;
-         };
-         break;
-
-      case SM_F2F:
-         inStr = fopen ( inName, "rb" );
-         outStr = fopen_output_safely ( outName, "wb" );
-         if ( outStr == NULL) {
-            fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
-                      progName, outName, strerror(errno) );
-            if ( inStr != NULL ) fclose ( inStr );
-            setExit(1);
-            return;
-         }
-         if ( inStr == NULL ) {
-            fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
-                      progName, inName, strerror(errno) );
-            if ( outStr != NULL ) fclose ( outStr );
-            setExit(1);
-            return;
-         };
-         break;
-
-      default:
-         panic ( "uncompress: bad srcMode" );
-         break;
-   }
-
-   if (verbosity >= 1) {
-      fprintf ( stderr, "  %s: ", inName );
-      pad ( inName );
-      fflush ( stderr );
-   }
-
-   /*--- Now the input and output handles are sane.  Do the Biz. ---*/
-   outputHandleJustInCase = outStr;
-   deleteOutputOnInterrupt = True;
-   magicNumberOK = uncompressStream ( inStr, outStr );
-   outputHandleJustInCase = NULL;
-
-   /*--- If there was an I/O error, we won't get here. ---*/
-   if ( magicNumberOK ) {
-      if ( srcMode == SM_F2F ) {
-         applySavedTimeInfoToOutputFile ( outName );
-         deleteOutputOnInterrupt = False;
-         if ( !keepInputFiles ) {
-            IntNative retVal = remove ( inName );
-            ERROR_IF_NOT_ZERO ( retVal );
-         }
-      }
-   } else {
-      unzFailsExist = True;
-      deleteOutputOnInterrupt = False;
-      if ( srcMode == SM_F2F ) {
-         IntNative retVal = remove ( outName );
-         ERROR_IF_NOT_ZERO ( retVal );
-      }
-   }
-   deleteOutputOnInterrupt = False;
-
-   if ( magicNumberOK ) {
-      if (verbosity >= 1)
-         fprintf ( stderr, "done\n" );
-   } else {
-      setExit(2);
-      if (verbosity >= 1)
-         fprintf ( stderr, "not a bzip2 file.\n" ); else
-         fprintf ( stderr,
-                   "%s: %s is not a bzip2 file.\n",
-                   progName, inName );
-   }
-
-}
-
-
-/*---------------------------------------------*/
-static
-void testf ( Char *name )
-{
-   FILE *inStr;
-   Bool allOK;
-   struct MY_STAT statBuf;
-
-   deleteOutputOnInterrupt = False;
-
-   if (name == NULL && srcMode != SM_I2O)
-      panic ( "testf: bad modes\n" );
-
-   copyFileName ( outName, (Char*)"(none)" );
-   switch (srcMode) {
-      case SM_I2O: copyFileName ( inName, (Char*)"(stdin)" ); break;
-      case SM_F2F: copyFileName ( inName, name ); break;
-      case SM_F2O: copyFileName ( inName, name ); break;
-   }
-
-   if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
-      if (noisy)
-      fprintf ( stderr, "%s: There are no files matching `%s'.\n",
-                progName, inName );
-      setExit(1);
-      return;
-   }
-   if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
-      fprintf ( stderr, "%s: Can't open input %s: %s.\n",
-                progName, inName, strerror(errno) );
-      setExit(1);
-      return;
-   }
-   if ( srcMode != SM_I2O ) {
-      MY_STAT(inName, &statBuf);
-      if ( MY_S_ISDIR(statBuf.st_mode) ) {
-         fprintf( stderr,
-                  "%s: Input file %s is a directory.\n",
-                  progName,inName);
-         setExit(1);
-         return;
-      }
-   }
-
-   switch ( srcMode ) {
-
-      case SM_I2O:
-         if ( isatty ( fileno ( stdin ) ) ) {
-            fprintf ( stderr,
-                      "%s: I won't read compressed data from a terminal.\n",
-                      progName );
-            fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
-                              progName, progName );
-            setExit(1);
-            return;
-         };
-         inStr = stdin;
-         break;
-
-      case SM_F2O: case SM_F2F:
-         inStr = fopen ( inName, "rb" );
-         if ( inStr == NULL ) {
-            fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
-                      progName, inName, strerror(errno) );
-            setExit(1);
-            return;
-         };
-         break;
-
-      default:
-         panic ( "testf: bad srcMode" );
-         break;
-   }
-
-   if (verbosity >= 1) {
-      fprintf ( stderr, "  %s: ", inName );
-      pad ( inName );
-      fflush ( stderr );
-   }
-
-   /*--- Now the input handle is sane.  Do the Biz. ---*/
-   outputHandleJustInCase = NULL;
-   allOK = testStream ( inStr );
-
-   if (allOK && verbosity >= 1) fprintf ( stderr, "ok\n" );
-   if (!allOK) testFailsExist = True;
-}
-
-
-/*---------------------------------------------*/
-static
-void license ( void )
-{
-   fprintf ( stdout,
-
-    "bzip2, a block-sorting file compressor.  "
-    "Version %s.\n"
-    "   \n"
-    "   Copyright (C) 1996-2010 by Julian Seward.\n"
-    "   \n"
-    "   This program is free software; you can redistribute it and/or modify\n"
-    "   it under the terms set out in the LICENSE file, which is included\n"
-    "   in the bzip2-1.0.6 source distribution.\n"
-    "   \n"
-    "   This program is distributed in the hope that it will be useful,\n"
-    "   but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
-    "   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
-    "   LICENSE file for more details.\n"
-    "   \n",
-    BZ2_bzlibVersion()
-   );
-}
-
-
-/*---------------------------------------------*/
-static
-void usage ( Char *fullProgName )
-{
-   fprintf (
-      stderr,
-      "bzip2, a block-sorting file compressor.  "
-      "Version %s.\n"
-      "\n   usage: %s [flags and input files in any order]\n"
-      "\n"
-      "   -h --help           print this message\n"
-      "   -d --decompress     force decompression\n"
-      "   -z --compress       force compression\n"
-      "   -k --keep           keep (don't delete) input files\n"
-      "   -f --force          overwrite existing output files\n"
-      "   -t --test           test compressed file integrity\n"
-      "   -c --stdout         output to standard out\n"
-      "   -q --quiet          suppress noncritical error messages\n"
-      "   -v --verbose        be verbose (a 2nd -v gives more)\n"
-      "   -L --license        display software version & license\n"
-      "   -V --version        display software version & license\n"
-      "   -s --small          use less memory (at most 2500k)\n"
-      "   -1 .. -9            set block size to 100k .. 900k\n"
-      "   --fast              alias for -1\n"
-      "   --best              alias for -9\n"
-      "\n"
-      "   If invoked as `bzip2', default action is to compress.\n"
-      "              as `bunzip2',  default action is to decompress.\n"
-      "              as `bzcat', default action is to decompress to stdout.\n"
-      "\n"
-      "   If no file names are given, bzip2 compresses or decompresses\n"
-      "   from standard input to standard output.  You can combine\n"
-      "   short flags, so `-v -4' means the same as -v4 or -4v, &c.\n"
-#     if BZ_UNIX
-      "\n"
-#     endif
-      ,
-
-      BZ2_bzlibVersion(),
-      fullProgName
-   );
-}
-
-
-/*---------------------------------------------*/
-static
-void redundant ( Char* flag )
-{
-   fprintf (
-      stderr,
-      "%s: %s is redundant in versions 0.9.5 and above\n",
-      progName, flag );
-}
-
-
-/*---------------------------------------------*/
-/*--
-  All the garbage from here to main() is purely to
-  implement a linked list of command-line arguments,
-  into which main() copies argv[1 .. argc-1].
-
-  The purpose of this exercise is to facilitate
-  the expansion of wildcard characters * and ? in
-  filenames for OSs which don't know how to do it
-  themselves, like MSDOS, Windows 95 and NT.
-
-  The actual Dirty Work is done by the platform-
-  specific macro APPEND_FILESPEC.
---*/
-
-typedef
-   struct zzzz {
-      Char        *name;
-      struct zzzz *link;
-   }
-   Cell;
-
-
-/*---------------------------------------------*/
-static
-void *myMalloc ( Int32 n )
-{
-   void* p;
-
-   p = malloc ( (size_t)n );
-   if (p == NULL) outOfMemory ();
-   return p;
-}
-
-
-/*---------------------------------------------*/
-static
-Cell *mkCell ( void )
-{
-   Cell *c;
-
-   c = (Cell*) myMalloc ( sizeof ( Cell ) );
-   c->name = NULL;
-   c->link = NULL;
-   return c;
-}
-
-
-/*---------------------------------------------*/
-static
-Cell *snocString ( Cell *root, Char *name )
-{
-   if (root == NULL) {
-      Cell *tmp = mkCell();
-      tmp->name = (Char*) myMalloc ( 5 + strlen(name) );
-      strcpy ( tmp->name, name );
-      return tmp;
-   } else {
-      Cell *tmp = root;
-      while (tmp->link != NULL) tmp = tmp->link;
-      tmp->link = snocString ( tmp->link, name );
-      return root;
-   }
-}
-
-
-/*---------------------------------------------*/
-static
-void addFlagsFromEnvVar ( Cell** argList, Char* varName )
-{
-   Int32 i, j, k;
-   Char *envbase, *p;
-
-   envbase = getenv(varName);
-   if (envbase != NULL) {
-      p = envbase;
-      i = 0;
-      while (True) {
-         if (p[i] == 0) break;
-         p += i;
-         i = 0;
-         while (isspace((Int32)(p[0]))) p++;
-         while (p[i] != 0 && !isspace((Int32)(p[i]))) i++;
-         if (i > 0) {
-            k = i; if (k > FILE_NAME_LEN-10) k = FILE_NAME_LEN-10;
-            for (j = 0; j < k; j++) tmpName[j] = p[j];
-            tmpName[k] = 0;
-            APPEND_FLAG(*argList, tmpName);
-         }
-      }
-   }
-}
-
-
-/*---------------------------------------------*/
-#define ISFLAG(s) (strcmp(aa->name, (s))==0)
-
-IntNative main ( IntNative argc, Char *argv[] )
-{
-   Int32  i, j;
-   Char   *tmp;
-   Cell   *argList;
-   Cell   *aa;
-   Bool   decode;
-
-   /*-- Be really really really paranoid :-) --*/
-   if (sizeof(Int32) != 4 || sizeof(UInt32) != 4  ||
-       sizeof(Int16) != 2 || sizeof(UInt16) != 2  ||
-       sizeof(Char)  != 1 || sizeof(UChar)  != 1)
-      configError();
-
-   /*-- Initialise --*/
-   outputHandleJustInCase  = NULL;
-   smallMode               = False;
-   keepInputFiles          = False;
-   forceOverwrite          = False;
-   noisy                   = True;
-   verbosity               = 0;
-   blockSize100k           = 9;
-   testFailsExist          = False;
-   unzFailsExist           = False;
-   numFileNames            = 0;
-   numFilesProcessed       = 0;
-   workFactor              = 30;
-   deleteOutputOnInterrupt = False;
-   exitValue               = 0;
-   i = j = 0; /* avoid bogus warning from egcs-1.1.X */
-
-   /*-- Set up signal handlers for mem access errors --*/
-   signal (SIGSEGV, mySIGSEGVorSIGBUScatcher);
-#  if BZ_UNIX
-#  ifndef __DJGPP__
-   signal (SIGBUS,  mySIGSEGVorSIGBUScatcher);
-#  endif
-#  endif
-
-   copyFileName ( inName,  (Char*)"(none)" );
-   copyFileName ( outName, (Char*)"(none)" );
-
-   copyFileName ( progNameReally, argv[0] );
-   progName = &progNameReally[0];
-   for (tmp = &progNameReally[0]; *tmp != '\0'; tmp++)
-      if (*tmp == PATH_SEP) progName = tmp + 1;
-
-
-   /*-- Copy flags from env var BZIP2, and
-        expand filename wildcards in arg list.
-   --*/
-   argList = NULL;
-   addFlagsFromEnvVar ( &argList,  (Char*)"BZIP2" );
-   addFlagsFromEnvVar ( &argList,  (Char*)"BZIP" );
-   for (i = 1; i <= argc-1; i++)
-      APPEND_FILESPEC(argList, argv[i]);
-
-
-   /*-- Find the length of the longest filename --*/
-   longestFileName = 7;
-   numFileNames    = 0;
-   decode          = True;
-   for (aa = argList; aa != NULL; aa = aa->link) {
-      if (ISFLAG("--")) { decode = False; continue; }
-      if (aa->name[0] == '-' && decode) continue;
-      numFileNames++;
-      if (longestFileName < (Int32)strlen(aa->name) )
-         longestFileName = (Int32)strlen(aa->name);
-   }
-
-
-   /*-- Determine source modes; flag handling may change this too. --*/
-   if (numFileNames == 0)
-      srcMode = SM_I2O; else srcMode = SM_F2F;
-
-
-   /*-- Determine what to do (compress/uncompress/test/cat). --*/
-   /*-- Note that subsequent flag handling may change this. --*/
-   opMode = OM_Z;
-
-   if ( (strstr ( progName, "unzip" ) != 0) ||
-        (strstr ( progName, "UNZIP" ) != 0) )
-      opMode = OM_UNZ;
-
-   if ( (strstr ( progName, "z2cat" ) != 0) ||
-        (strstr ( progName, "Z2CAT" ) != 0) ||
-        (strstr ( progName, "zcat" ) != 0)  ||
-        (strstr ( progName, "ZCAT" ) != 0) )  {
-      opMode = OM_UNZ;
-      srcMode = (numFileNames == 0) ? SM_I2O : SM_F2O;
-   }
-
-
-   /*-- Look at the flags. --*/
-   for (aa = argList; aa != NULL; aa = aa->link) {
-      if (ISFLAG("--")) break;
-      if (aa->name[0] == '-' && aa->name[1] != '-') {
-         for (j = 1; aa->name[j] != '\0'; j++) {
-            switch (aa->name[j]) {
-               case 'c': srcMode          = SM_F2O; break;
-               case 'd': opMode           = OM_UNZ; break;
-               case 'z': opMode           = OM_Z; break;
-               case 'f': forceOverwrite   = True; break;
-               case 't': opMode           = OM_TEST; break;
-               case 'k': keepInputFiles   = True; break;
-               case 's': smallMode        = True; break;
-               case 'q': noisy            = False; break;
-               case '1': blockSize100k    = 1; break;
-               case '2': blockSize100k    = 2; break;
-               case '3': blockSize100k    = 3; break;
-               case '4': blockSize100k    = 4; break;
-               case '5': blockSize100k    = 5; break;
-               case '6': blockSize100k    = 6; break;
-               case '7': blockSize100k    = 7; break;
-               case '8': blockSize100k    = 8; break;
-               case '9': blockSize100k    = 9; break;
-               case 'V':
-               case 'L': license();
-                         exit ( 0 );
-                         break;
-               case 'v': verbosity++; break;
-               case 'h': usage ( progName );
-                         exit ( 0 );
-                         break;
-               default:  fprintf ( stderr, "%s: Bad flag `%s'\n",
-                                   progName, aa->name );
-                         usage ( progName );
-                         exit ( 1 );
-                         break;
-            }
-         }
-      }
-   }
-
-   /*-- And again ... --*/
-   for (aa = argList; aa != NULL; aa = aa->link) {
-      if (ISFLAG("--")) break;
-      if (ISFLAG("--stdout"))            srcMode          = SM_F2O;  else
-      if (ISFLAG("--decompress"))        opMode           = OM_UNZ;  else
-      if (ISFLAG("--compress"))          opMode           = OM_Z;    else
-      if (ISFLAG("--force"))             forceOverwrite   = True;    else
-      if (ISFLAG("--test"))              opMode           = OM_TEST; else
-      if (ISFLAG("--keep"))              keepInputFiles   = True;    else
-      if (ISFLAG("--small"))             smallMode        = True;    else
-      if (ISFLAG("--quiet"))             noisy            = False;   else
-      if (ISFLAG("--version"))           { license(); exit ( 0 ); }  else
-      if (ISFLAG("--license"))           { license(); exit ( 0 ); }  else
-      if (ISFLAG("--exponential"))       workFactor = 1;             else
-      if (ISFLAG("--repetitive-best"))   redundant(aa->name);        else
-      if (ISFLAG("--repetitive-fast"))   redundant(aa->name);        else
-      if (ISFLAG("--fast"))              blockSize100k = 1;          else
-      if (ISFLAG("--best"))              blockSize100k = 9;          else
-      if (ISFLAG("--verbose"))           verbosity++;                else
-      if (ISFLAG("--help"))              { usage ( progName ); exit ( 0 ); }
-         else
-         if (strncmp ( aa->name, "--", 2) == 0) {
-            fprintf ( stderr, "%s: Bad flag `%s'\n", progName, aa->name );
-            usage ( progName );
-            exit ( 1 );
-         }
-   }
-
-   if (verbosity > 4) verbosity = 4;
-   if (opMode == OM_Z && smallMode && blockSize100k > 2)
-      blockSize100k = 2;
-
-   if (opMode == OM_TEST && srcMode == SM_F2O) {
-      fprintf ( stderr, "%s: -c and -t cannot be used together.\n",
-                progName );
-      exit ( 1 );
-   }
-
-   if (srcMode == SM_F2O && numFileNames == 0)
-      srcMode = SM_I2O;
-
-   if (opMode != OM_Z) blockSize100k = 0;
-
-   if (srcMode == SM_F2F) {
-      signal (SIGINT,  mySignalCatcher);
-      signal (SIGTERM, mySignalCatcher);
-#     if BZ_UNIX
-      signal (SIGHUP,  mySignalCatcher);
-#     endif
-   }
-
-   if (opMode == OM_Z) {
-      if (srcMode == SM_I2O) {
-         compress ( NULL );
-      } else {
-         decode = True;
-         for (aa = argList; aa != NULL; aa = aa->link) {
-            if (ISFLAG("--")) { decode = False; continue; }
-            if (aa->name[0] == '-' && decode) continue;
-            numFilesProcessed++;
-            compress ( aa->name );
-         }
-      }
-   }
-   else
-
-   if (opMode == OM_UNZ) {
-      unzFailsExist = False;
-      if (srcMode == SM_I2O) {
-         uncompress ( NULL );
-      } else {
-         decode = True;
-         for (aa = argList; aa != NULL; aa = aa->link) {
-            if (ISFLAG("--")) { decode = False; continue; }
-            if (aa->name[0] == '-' && decode) continue;
-            numFilesProcessed++;
-            uncompress ( aa->name );
-         }
-      }
-      if (unzFailsExist) {
-         setExit(2);
-         exit(exitValue);
-      }
-   }
-
-   else {
-      testFailsExist = False;
-      if (srcMode == SM_I2O) {
-         testf ( NULL );
-      } else {
-         decode = True;
-         for (aa = argList; aa != NULL; aa = aa->link) {
-            if (ISFLAG("--")) { decode = False; continue; }
-            if (aa->name[0] == '-' && decode) continue;
-            numFilesProcessed++;
-            testf ( aa->name );
-         }
-      }
-      if (testFailsExist) {
-         if (noisy) {
-            fprintf ( stderr,
-              "\n"
-              "You can use the `bzip2recover' program to attempt to recover\n"
-              "data from undamaged sections of corrupted files.\n\n"
-            );
-         }
-         setExit(2);
-         exit(exitValue);
-      }
-   }
-
-   /* Free the argument list memory to mollify leak detectors
-      (eg) Purify, Checker.  Serves no other useful purpose.
-   */
-   aa = argList;
-   while (aa != NULL) {
-      Cell* aa2 = aa->link;
-      if (aa->name != NULL) free(aa->name);
-      free(aa);
-      aa = aa2;
-   }
-
-   return exitValue;
-}
-
-
-/*-----------------------------------------------------------*/
-/*--- end                                         bzip2.c ---*/
-/*-----------------------------------------------------------*/
diff --git a/thirdparty/bzip2/bzip2.doap b/thirdparty/bzip2/bzip2.doap
deleted file mode 100644
index 187faad2a..000000000
--- a/thirdparty/bzip2/bzip2.doap
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-  Bzip2
-  Program and library for lossless, block-sorting data compression
-
-  
-    Bzip2/libbz2 is a program and library for lossless, block-sorting
-    data compression.  It is used widely to compress file archives and
-    as a component of compressed data streams.
-  
-
-  
-  
-  
-  C
-  Rust
-
-  
-    
-      Micah Snyder
-      
-    
-  
-
-
diff --git a/thirdparty/bzip2/bzip2.pc.in b/thirdparty/bzip2/bzip2.pc.in
deleted file mode 100644
index b48a055c6..000000000
--- a/thirdparty/bzip2/bzip2.pc.in
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-bindir=@bindir@
-libdir=@libdir@
-includedir=@includedir@
-
-Name: bzip2
-Description: Lossless, block-sorting data compression
-Version: @VERSION@
-Libs: -L${libdir} -lbz2
-Cflags: -I${includedir}
diff --git a/thirdparty/bzip2/bzip2.txt b/thirdparty/bzip2/bzip2.txt
deleted file mode 100644
index efaace8d3..000000000
--- a/thirdparty/bzip2/bzip2.txt
+++ /dev/null
@@ -1,390 +0,0 @@
-
-NAME
-       bzip2, bunzip2 - a block-sorting file compressor, v1.0.6
-       bzcat - decompresses files to stdout
-       bzip2recover - recovers data from damaged bzip2 files
-
-
-SYNOPSIS
-       bzip2 [ -cdfkqstvzVL123456789 ] [ filenames ...  ]
-       bunzip2 [ -fkvsVL ] [ filenames ...  ]
-       bzcat [ -s ] [ filenames ...  ]
-       bzip2recover filename
-
-
-DESCRIPTION
-       bzip2  compresses  files  using  the Burrows-Wheeler block
-       sorting text compression algorithm,  and  Huffman  coding.
-       Compression  is  generally  considerably  better than that
-       achieved by more conventional LZ77/LZ78-based compressors,
-       and  approaches  the performance of the PPM family of sta-
-       tistical compressors.
-
-       The command-line options are deliberately very similar  to
-       those of GNU gzip, but they are not identical.
-
-       bzip2  expects  a list of file names to accompany the com-
-       mand-line flags.  Each file is replaced  by  a  compressed
-       version  of  itself,  with  the  name "original_name.bz2".
-       Each compressed file has the same modification date,  per-
-       missions, and, when possible, ownership as the correspond-
-       ing original, so that these properties  can  be  correctly
-       restored  at  decompression  time.   File name handling is
-       naive in the sense that there is no mechanism for preserv-
-       ing  original file names, permissions, ownerships or dates
-       in filesystems which lack these concepts, or have  serious
-       file name length restrictions, such as MS-DOS.
-
-       bzip2  and  bunzip2 will by default not overwrite existing
-       files.  If you want this to happen, specify the -f flag.
-
-       If no file names  are  specified,  bzip2  compresses  from
-       standard  input  to  standard output.  In this case, bzip2
-       will decline to write compressed output to a terminal,  as
-       this  would  be  entirely  incomprehensible  and therefore
-       pointless.
-
-       bunzip2 (or bzip2 -d) decompresses  all  specified  files.
-       Files which were not created by bzip2 will be detected and
-       ignored, and a warning issued.  bzip2  attempts  to  guess
-       the  filename  for  the decompressed file from that of the
-       compressed file as follows:
-
-              filename.bz2    becomes   filename
-              filename.bz     becomes   filename
-              filename.tbz2   becomes   filename.tar
-              filename.tbz    becomes   filename.tar
-              anyothername    becomes   anyothername.out
-
-       If the file does not end in one of the recognised endings,
-       .bz2,  .bz,  .tbz2 or .tbz, bzip2 complains that it cannot
-       guess the name of the original file, and uses the original
-       name with .out appended.
-
-       As  with compression, supplying no filenames causes decom-
-       pression from standard input to standard output.
-
-       bunzip2 will correctly decompress a file which is the con-
-       catenation of two or more compressed files.  The result is
-       the concatenation of the corresponding uncompressed files.
-       Integrity testing (-t) of concatenated compressed files is
-       also supported.
-
-       You can also compress or decompress files to the  standard
-       output  by giving the -c flag.  Multiple files may be com-
-       pressed and decompressed like this.  The resulting outputs
-       are  fed  sequentially to stdout.  Compression of multiple
-       files in this manner generates a stream containing  multi-
-       ple compressed file representations.  Such a stream can be
-       decompressed correctly only  by  bzip2  version  0.9.0  or
-       later.   Earlier  versions of bzip2 will stop after decom-
-       pressing the first file in the stream.
-
-       bzcat (or bzip2 -dc) decompresses all specified  files  to
-       the standard output.
-
-       bzip2  will  read arguments from the environment variables
-       BZIP2 and BZIP, in  that  order,  and  will  process  them
-       before  any  arguments  read  from the command line.  This
-       gives a convenient way to supply default arguments.
-
-       Compression is always performed, even  if  the  compressed
-       file  is slightly larger than the original.  Files of less
-       than about one hundred bytes tend to get larger, since the
-       compression  mechanism  has  a  constant  overhead  in the
-       region of 50 bytes.  Random data (including the output  of
-       most  file  compressors)  is  coded at about 8.05 bits per
-       byte, giving an expansion of around 0.5%.
-
-       As a self-check for your  protection,  bzip2  uses  32-bit
-       CRCs  to make sure that the decompressed version of a file
-       is identical to the original.  This guards against corrup-
-       tion  of  the compressed data, and against undetected bugs
-       in bzip2 (hopefully very unlikely).  The chances  of  data
-       corruption  going  undetected  is  microscopic,  about one
-       chance in four billion for each file processed.  Be aware,
-       though,  that  the  check occurs upon decompression, so it
-       can only tell you that something is wrong.  It can't  help
-       you  recover  the original uncompressed data.  You can use
-       bzip2recover to try to recover data from damaged files.
-
-       Return values: 0 for a normal exit,  1  for  environmental
-       problems  (file not found, invalid flags, I/O errors, &c),
-       2 to indicate a corrupt compressed file, 3 for an internal
-       consistency error (eg, bug) which caused bzip2 to panic.
-
-
-OPTIONS
-       -c --stdout
-              Compress or decompress to standard output.
-
-       -d --decompress
-              Force  decompression.  bzip2, bunzip2 and bzcat are
-              really the same program,  and  the  decision  about
-              what  actions to take is done on the basis of which
-              name is used.  This flag overrides that  mechanism,
-              and forces bzip2 to decompress.
-
-       -z --compress
-              The   complement   to   -d:   forces   compression,
-              regardless of the invocation name.
-
-       -t --test
-              Check integrity of the specified file(s), but don't
-              decompress  them.   This  really  performs  a trial
-              decompression and throws away the result.
-
-       -f --force
-              Force overwrite of output files.   Normally,  bzip2
-              will  not  overwrite  existing  output files.  Also
-              forces bzip2 to break hard links to files, which it
-              otherwise wouldn't do.
-
-              bzip2  normally  declines to decompress files which
-              don't have the  correct  magic  header  bytes.   If
-              forced  (-f),  however,  it  will  pass  such files
-              through unmodified.  This is how GNU gzip  behaves.
-
-       -k --keep
-              Keep  (don't delete) input files during compression
-              or decompression.
-
-       -s --small
-              Reduce memory usage, for compression, decompression
-              and  testing.   Files  are  decompressed and tested
-              using a modified algorithm which only requires  2.5
-              bytes  per  block byte.  This means any file can be
-              decompressed in 2300k of memory,  albeit  at  about
-              half the normal speed.
-
-              During  compression,  -s  selects  a  block size of
-              200k, which limits memory use to  around  the  same
-              figure,  at  the expense of your compression ratio.
-              In short, if your  machine  is  low  on  memory  (8
-              megabytes  or  less),  use  -s for everything.  See
-              MEMORY MANAGEMENT below.
-
-       -q --quiet
-              Suppress non-essential warning messages.   Messages
-              pertaining  to I/O errors and other critical events
-              will not be suppressed.
-
-       -v --verbose
-              Verbose mode -- show the compression ratio for each
-              file  processed.   Further  -v's  increase the ver-
-              bosity level, spewing out lots of information which
-              is primarily of interest for diagnostic purposes.
-
-       -L --license -V --version
-              Display  the  software  version,  license terms and
-              conditions.
-
-       -1 (or --fast) to -9 (or --best)
-              Set the block size to 100 k, 200 k ..  900  k  when
-              compressing.   Has  no  effect  when decompressing.
-              See MEMORY MANAGEMENT below.  The --fast and --best
-              aliases  are  primarily for GNU gzip compatibility.
-              In particular, --fast doesn't make things  signifi-
-              cantly  faster.   And  --best  merely  selects  the
-              default behaviour.
-
-       --     Treats all subsequent arguments as file names, even
-              if they start with a dash.  This is so you can han-
-              dle files with names beginning  with  a  dash,  for
-              example: bzip2 -- -myfilename.
-
-       --repetitive-fast --repetitive-best
-              These  flags  are  redundant  in versions 0.9.5 and
-              above.  They provided some coarse control over  the
-              behaviour  of the sorting algorithm in earlier ver-
-              sions, which was sometimes useful.  0.9.5 and above
-              have  an  improved  algorithm  which  renders these
-              flags irrelevant.
-
-
-MEMORY MANAGEMENT
-       bzip2 compresses large files in blocks.   The  block  size
-       affects  both  the  compression  ratio  achieved,  and the
-       amount of memory needed for compression and decompression.
-       The  flags  -1  through  -9  specify  the block size to be
-       100,000 bytes through 900,000 bytes (the default)  respec-
-       tively.   At  decompression  time, the block size used for
-       compression is read from  the  header  of  the  compressed
-       file, and bunzip2 then allocates itself just enough memory
-       to decompress the file.  Since block sizes are  stored  in
-       compressed  files,  it follows that the flags -1 to -9 are
-       irrelevant to and so ignored during decompression.
-
-       Compression and decompression requirements, in bytes,  can
-       be estimated as:
-
-              Compression:   400k + ( 8 x block size )
-
-              Decompression: 100k + ( 4 x block size ), or
-                             100k + ( 2.5 x block size )
-
-       Larger  block  sizes  give  rapidly  diminishing  marginal
-       returns.  Most of the compression comes from the first two
-       or  three hundred k of block size, a fact worth bearing in
-       mind when using bzip2  on  small  machines.   It  is  also
-       important  to  appreciate  that  the  decompression memory
-       requirement is set at compression time by  the  choice  of
-       block size.
-
-       For  files  compressed  with  the default 900k block size,
-       bunzip2 will require about 3700 kbytes to decompress.   To
-       support decompression of any file on a 4 megabyte machine,
-       bunzip2 has an option to  decompress  using  approximately
-       half this amount of memory, about 2300 kbytes.  Decompres-
-       sion speed is also halved, so you should use  this  option
-       only where necessary.  The relevant flag is -s.
-
-       In general, try and use the largest block size memory con-
-       straints  allow,  since  that  maximises  the  compression
-       achieved.   Compression and decompression speed are virtu-
-       ally unaffected by block size.
-
-       Another significant point applies to files which fit in  a
-       single  block  --  that  means  most files you'd encounter
-       using a large block  size.   The  amount  of  real  memory
-       touched is proportional to the size of the file, since the
-       file is smaller than a block.  For example, compressing  a
-       file  20,000  bytes  long  with the flag -9 will cause the
-       compressor to allocate around 7600k of  memory,  but  only
-       touch 400k + 20000 * 8 = 560 kbytes of it.  Similarly, the
-       decompressor will allocate 3700k but  only  touch  100k  +
-       20000 * 4 = 180 kbytes.
-
-       Here  is a table which summarises the maximum memory usage
-       for different block sizes.  Also  recorded  is  the  total
-       compressed  size for 14 files of the Calgary Text Compres-
-       sion Corpus totalling 3,141,622 bytes.  This column  gives
-       some  feel  for  how  compression  varies with block size.
-       These figures tend to understate the advantage  of  larger
-       block  sizes  for  larger files, since the Corpus is domi-
-       nated by smaller files.
-
-                  Compress   Decompress   Decompress   Corpus
-           Flag     usage      usage       -s usage     Size
-
-            -1      1200k       500k         350k      914704
-            -2      2000k       900k         600k      877703
-            -3      2800k      1300k         850k      860338
-            -4      3600k      1700k        1100k      846899
-            -5      4400k      2100k        1350k      845160
-            -6      5200k      2500k        1600k      838626
-            -7      6100k      2900k        1850k      834096
-            -8      6800k      3300k        2100k      828642
-            -9      7600k      3700k        2350k      828642
-
-
-RECOVERING DATA FROM DAMAGED FILES
-       bzip2 compresses files in blocks, usually 900kbytes  long.
-       Each block is handled independently.  If a media or trans-
-       mission error causes a multi-block  .bz2  file  to  become
-       damaged,  it  may  be  possible  to  recover data from the
-       undamaged blocks in the file.
-
-       The compressed representation of each block  is  delimited
-       by  a  48-bit pattern, which makes it possible to find the
-       block boundaries with reasonable  certainty.   Each  block
-       also  carries its own 32-bit CRC, so damaged blocks can be
-       distinguished from undamaged ones.
-
-       bzip2recover is a  simple  program  whose  purpose  is  to
-       search  for blocks in .bz2 files, and write each block out
-       into its own .bz2 file.  You can then use bzip2 -t to test
-       the integrity of the resulting files, and decompress those
-       which are undamaged.
-
-       bzip2recover takes a single argument, the name of the dam-
-       aged    file,    and    writes    a    number   of   files
-       "rec00001file.bz2",  "rec00002file.bz2",  etc,  containing
-       the   extracted   blocks.   The   output   filenames   are
-       designed  so  that the use of wildcards in subsequent pro-
-       cessing  -- for example, "bzip2 -dc  rec*file.bz2 > recov-
-       ered_data" -- processes the files in the correct order.
-
-       bzip2recover should be of most use dealing with large .bz2
-       files,  as  these will contain many blocks.  It is clearly
-       futile to use it on damaged single-block  files,  since  a
-       damaged  block  cannot  be recovered.  If you wish to min-
-       imise any potential data loss through media  or  transmis-
-       sion errors, you might consider compressing with a smaller
-       block size.
-
-
-PERFORMANCE NOTES
-       The sorting phase of compression gathers together  similar
-       strings  in  the  file.  Because of this, files containing
-       very long runs of  repeated  symbols,  like  "aabaabaabaab
-       ..."   (repeated  several hundred times) may compress more
-       slowly than normal.  Versions 0.9.5 and  above  fare  much
-       better  than previous versions in this respect.  The ratio
-       between worst-case and average-case compression time is in
-       the  region  of  10:1.  For previous versions, this figure
-       was more like 100:1.  You can use the -vvvv option to mon-
-       itor progress in great detail, if you want.
-
-       Decompression speed is unaffected by these phenomena.
-
-       bzip2  usually  allocates  several  megabytes of memory to
-       operate in, and then charges all over it in a fairly  ran-
-       dom  fashion.   This means that performance, both for com-
-       pressing and decompressing, is largely determined  by  the
-       speed  at  which  your  machine  can service cache misses.
-       Because of this, small changes to the code to  reduce  the
-       miss  rate  have  been observed to give disproportionately
-       large performance improvements.  I imagine bzip2 will per-
-       form best on machines with very large caches.
-
-
-CAVEATS
-       I/O  error  messages  are not as helpful as they could be.
-       bzip2 tries hard to detect I/O errors  and  exit  cleanly,
-       but  the  details  of  what  the problem is sometimes seem
-       rather misleading.
-
-       This manual page pertains to version 1.1.0 of bzip2.  Com-
-       pressed  data created by this version is entirely forwards
-       and  backwards  compatible  with   the   previous   public
-       releases,  versions  0.1pl2,  0.9.0,  0.9.5, 1.0.0, 1.0.1,
-       1.0.2 and above, but with the  following  exception: 0.9.0
-       and above can  correctly decompress  multiple concatenated
-       compressed files.  0.1pl2  cannot do this;  it  will  stop
-       after  decompressing just the first file in the stream.
-
-       bzip2recover  versions prior to 1.0.2 used 32-bit integers
-       to represent bit positions in compressed  files,  so  they
-       could  not handle compressed files more than 512 megabytes
-       long.  Versions 1.0.2 and above use 64-bit  ints  on  some
-       platforms  which  support them (GNU supported targets, and
-       Windows).  To establish whether or  not  bzip2recover  was
-       built  with  such  a limitation, run it without arguments.
-       In any event you can build yourself an  unlimited  version
-       if  you  can  recompile  it  with MaybeUInt64 set to be an
-       unsigned 64-bit integer.
-
-
-AUTHOR
-       Julian Seward, jseward@acm.org
-
-       https://gitlab.com/bzip2/bzip2
-
-       The ideas embodied in bzip2 are due to (at least) the fol-
-       lowing  people: Michael Burrows and David Wheeler (for the
-       block sorting transformation), David Wheeler  (again,  for
-       the Huffman coder), Peter Fenwick (for the structured cod-
-       ing model in the original bzip, and many refinements), and
-       Alistair  Moffat,  Radford  Neal  and  Ian Witten (for the
-       arithmetic  coder  in  the  original  bzip).   I  am  much
-       indebted for their help, support and advice.  See the man-
-       ual in the source distribution for pointers to sources  of
-       documentation.  Christian von Roques encouraged me to look
-       for faster sorting algorithms, so as to speed up  compres-
-       sion.  Bela Lubkin encouraged me to improve the worst-case
-       compression performance.  Donna Robinson XMLised the docu-
-       mentation.   The bz* scripts are derived from those of GNU
-       gzip.  Many people sent patches, helped  with  portability
-       problems,  lent  machines,  gave advice and were generally
-       helpful.
diff --git a/thirdparty/bzip2/bzip2recover.c b/thirdparty/bzip2/bzip2recover.c
deleted file mode 100644
index b2a666ba3..000000000
--- a/thirdparty/bzip2/bzip2recover.c
+++ /dev/null
@@ -1,544 +0,0 @@
-/*-----------------------------------------------------------*/
-/*--- Block recoverer program for bzip2                   ---*/
-/*---                                      bzip2recover.c ---*/
-/*-----------------------------------------------------------*/
-
-/* ------------------------------------------------------------------
-   This file is part of bzip2/libbzip2, a program and library for
-   lossless, block-sorting data compression.
-
-   bzip2/libbzip2 version 1.1.0 of 6 September 2010
-   Copyright (C) 1996-2010 Julian Seward 
-
-   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.
-   ------------------------------------------------------------------ */
-
-/* This program is a complete hack and should be rewritten properly.
-   It isn't very complicated. */
-
-#if BZ_UNIX
-#   include 
-#   include 
-#   include 
-#   include 
-#endif
-
-#include 
-#include 
-#include 
-#include 
-
-
-/* This program records bit locations in the file to be recovered.
-   That means that if 64-bit ints are not supported, we will not
-   be able to recover .bz2 files over 512MB (2^32 bits) long.
-   On GNU supported platforms, we take advantage of the 64-bit
-   int support to circumvent this problem.  Ditto MSVC.
-
-   This change occurred in version 1.0.2; all prior versions have
-   the 512MB limitation.
-*/
-#ifdef __GNUC__
-   typedef  unsigned long long int  MaybeUInt64;
-#  define MaybeUInt64_FMT "%Lu"
-#else
-#ifdef _MSC_VER
-   typedef  unsigned __int64  MaybeUInt64;
-#  define MaybeUInt64_FMT "%I64u"
-#else
-   typedef  unsigned int   MaybeUInt64;
-#  define MaybeUInt64_FMT "%u"
-#endif
-#endif
-
-typedef  unsigned int   UInt32;
-typedef  int            Int32;
-typedef  unsigned char  UChar;
-typedef  char           Char;
-typedef  unsigned char  Bool;
-#define True    ((Bool)1)
-#define False   ((Bool)0)
-
-
-#define BZ_MAX_FILENAME 2000
-
-Char inFileName[BZ_MAX_FILENAME];
-Char outFileName[BZ_MAX_FILENAME];
-Char progName[BZ_MAX_FILENAME];
-
-MaybeUInt64 bytesOut = 0;
-MaybeUInt64 bytesIn  = 0;
-
-
-/*---------------------------------------------------*/
-/*--- 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' */
-
-
-/*---------------------------------------------------*/
-/*--- I/O errors                                  ---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------*/
-static void readError ( void )
-{
-   fprintf ( stderr,
-             "%s: I/O error reading `%s', possible reason follows.\n",
-            progName, inFileName );
-   perror ( progName );
-   fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
-             progName );
-   exit ( 1 );
-}
-
-
-/*---------------------------------------------*/
-static void writeError ( void )
-{
-   fprintf ( stderr,
-             "%s: I/O error reading `%s', possible reason follows.\n",
-            progName, inFileName );
-   perror ( progName );
-   fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
-             progName );
-   exit ( 1 );
-}
-
-
-/*---------------------------------------------*/
-static void mallocFail ( Int32 n )
-{
-   fprintf ( stderr,
-             "%s: malloc failed on request for %d bytes.\n",
-            progName, n );
-   fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
-             progName );
-   exit ( 1 );
-}
-
-
-/*---------------------------------------------*/
-static void tooManyBlocks ( Int32 max_handled_blocks )
-{
-   fprintf ( stderr,
-             "%s: `%s' appears to contain more than %d blocks\n",
-            progName, inFileName, max_handled_blocks );
-   fprintf ( stderr,
-             "%s: and cannot be handled.  To fix, increase\n",
-             progName );
-   fprintf ( stderr,
-             "%s: BZ_MAX_HANDLED_BLOCKS in bzip2recover.c, and recompile.\n",
-             progName );
-   exit ( 1 );
-}
-
-
-
-/*---------------------------------------------------*/
-/*--- Bit stream I/O                              ---*/
-/*---------------------------------------------------*/
-
-typedef
-   struct {
-      FILE*  handle;
-      Int32  buffer;
-      Int32  buffLive;
-      Char   mode;
-   }
-   BitStream;
-
-
-/*---------------------------------------------*/
-static BitStream* bsOpenReadStream ( FILE* stream )
-{
-   BitStream *bs = malloc ( sizeof(BitStream) );
-   if (bs == NULL) mallocFail ( sizeof(BitStream) );
-   bs->handle = stream;
-   bs->buffer = 0;
-   bs->buffLive = 0;
-   bs->mode = 'r';
-   return bs;
-}
-
-
-/*---------------------------------------------*/
-static BitStream* bsOpenWriteStream ( FILE* stream )
-{
-   BitStream *bs = malloc ( sizeof(BitStream) );
-   if (bs == NULL) mallocFail ( sizeof(BitStream) );
-   bs->handle = stream;
-   bs->buffer = 0;
-   bs->buffLive = 0;
-   bs->mode = 'w';
-   return bs;
-}
-
-
-/*---------------------------------------------*/
-static void bsPutBit ( BitStream* bs, Int32 bit )
-{
-   if (bs->buffLive == 8) {
-      Int32 retVal = putc ( (UChar) bs->buffer, bs->handle );
-      if (retVal == EOF) writeError();
-      bytesOut++;
-      bs->buffLive = 1;
-      bs->buffer = bit & 0x1;
-   } else {
-      bs->buffer = ( (bs->buffer << 1) | (bit & 0x1) );
-      bs->buffLive++;
-   };
-}
-
-
-/*---------------------------------------------*/
-/*--
-   Returns 0 or 1, or 2 to indicate EOF.
---*/
-static Int32 bsGetBit ( BitStream* bs )
-{
-   if (bs->buffLive > 0) {
-      bs->buffLive --;
-      return ( ((bs->buffer) >> (bs->buffLive)) & 0x1 );
-   } else {
-      Int32 retVal = getc ( bs->handle );
-      if ( retVal == EOF ) {
-         if (errno != 0) readError();
-         return 2;
-      }
-      bs->buffLive = 7;
-      bs->buffer = retVal;
-      return ( ((bs->buffer) >> 7) & 0x1 );
-   }
-}
-
-
-/*---------------------------------------------*/
-static void bsClose ( BitStream* bs )
-{
-   Int32 retVal;
-
-   if ( bs->mode == 'w' ) {
-      while ( bs->buffLive < 8 ) {
-         bs->buffLive++;
-         bs->buffer <<= 1;
-      };
-      retVal = putc ( (UChar) (bs->buffer), bs->handle );
-      if (retVal == EOF) writeError();
-      bytesOut++;
-      retVal = fflush ( bs->handle );
-      if (retVal == EOF) writeError();
-   }
-   retVal = fclose ( bs->handle );
-   if (retVal == EOF) {
-      if (bs->mode == 'w') writeError(); else readError();
-   }
-   free ( bs );
-}
-
-
-/*---------------------------------------------*/
-static void bsPutUChar ( BitStream* bs, UChar c )
-{
-   Int32 i;
-   for (i = 7; i >= 0; i--)
-      bsPutBit ( bs, (((UInt32) c) >> i) & 0x1 );
-}
-
-
-/*---------------------------------------------*/
-static void bsPutUInt32 ( BitStream* bs, UInt32 c )
-{
-   Int32 i;
-
-   for (i = 31; i >= 0; i--)
-      bsPutBit ( bs, (c >> i) & 0x1 );
-}
-
-
-/*---------------------------------------------*/
-static Bool endsInBz2 ( Char* name )
-{
-   Int32 n = strlen ( name );
-   if (n <= 4) return False;
-   return
-      (name[n-4] == '.' &&
-       name[n-3] == 'b' &&
-       name[n-2] == 'z' &&
-       name[n-1] == '2');
-}
-
-/* Same as from bzip2.c
- *
- * Opens a file, but refuses to overwrite an existing one.
- */
-static
-FILE* fopen_output_safely ( Char* name, const char* mode )
-{
-#  if BZ_UNIX
-   FILE*     fp;
-   int       fh;
-   fh = open(name, O_WRONLY|O_CREAT|O_EXCL, S_IWUSR|S_IRUSR);
-   if (fh == -1) return NULL;
-   fp = fdopen(fh, mode);
-   if (fp == NULL) close(fh);
-   return fp;
-#  else
-   return fopen(name, mode);
-#  endif
-}
-
-
-
-/*---------------------------------------------------*/
-/*---                                             ---*/
-/*---------------------------------------------------*/
-
-/* This logic isn't really right when it comes to Cygwin. */
-#ifdef _WIN32
-#  define  BZ_SPLIT_SYM  '\\'  /* path splitter on Windows platform */
-#else
-#  define  BZ_SPLIT_SYM  '/'   /* path splitter on Unix platform */
-#endif
-
-#define BLOCK_HEADER_HI  0x00003141UL
-#define BLOCK_HEADER_LO  0x59265359UL
-
-#define BLOCK_ENDMARK_HI 0x00001772UL
-#define BLOCK_ENDMARK_LO 0x45385090UL
-
-/* Increase if necessary.  However, a .bz2 file with > 50000 blocks
-   would have an uncompressed size of at least 40GB, so the chances
-   are low you'll need to up this.
-*/
-#define BZ_MAX_HANDLED_BLOCKS 50000
-
-MaybeUInt64 bStart [BZ_MAX_HANDLED_BLOCKS];
-MaybeUInt64 bEnd   [BZ_MAX_HANDLED_BLOCKS];
-MaybeUInt64 rbStart[BZ_MAX_HANDLED_BLOCKS];
-MaybeUInt64 rbEnd  [BZ_MAX_HANDLED_BLOCKS];
-
-Int32 main ( Int32 argc, Char** argv )
-{
-   FILE*       inFile;
-   FILE*       outFile;
-   BitStream*  bsIn, *bsWr;
-   Int32       b, wrBlock, currBlock, rbCtr;
-   MaybeUInt64 bitsRead;
-
-   UInt32      buffHi, buffLo, blockCRC;
-   Char*       p;
-
-   strncpy ( progName, argv[0], BZ_MAX_FILENAME-1);
-   progName[BZ_MAX_FILENAME-1]='\0';
-   inFileName[0] = outFileName[0] = 0;
-
-   fprintf ( stderr,
-             "bzip2recover 1.0.6: extracts blocks from damaged .bz2 files.\n" );
-
-   if (argc != 2) {
-      fprintf ( stderr, "%s: usage is `%s damaged_file_name'.\n",
-                        progName, progName );
-      switch (sizeof(MaybeUInt64)) {
-         case 8:
-            fprintf(stderr,
-                    "\trestrictions on size of recovered file: None\n");
-            break;
-         case 4:
-            fprintf(stderr,
-                    "\trestrictions on size of recovered file: 512 MB\n");
-            fprintf(stderr,
-                    "\tto circumvent, recompile with MaybeUInt64 as an\n"
-                    "\tunsigned 64-bit int.\n");
-            break;
-         default:
-            fprintf(stderr,
-                    "\tsizeof(MaybeUInt64) is not 4 or 8 -- "
-                    "configuration error.\n");
-            break;
-      }
-      exit(1);
-   }
-
-   if (strlen(argv[1]) >= BZ_MAX_FILENAME-20) {
-      fprintf ( stderr,
-                "%s: supplied filename is suspiciously (>= %d chars) long.  Bye!\n",
-                progName, (int)strlen(argv[1]) );
-      exit(1);
-   }
-
-   strcpy ( inFileName, argv[1] );
-
-   inFile = fopen ( inFileName, "rb" );
-   if (inFile == NULL) {
-      fprintf ( stderr, "%s: can't read `%s'\n", progName, inFileName );
-      exit(1);
-   }
-
-   bsIn = bsOpenReadStream ( inFile );
-   fprintf ( stderr, "%s: searching for block boundaries ...\n", progName );
-
-   bitsRead = 0;
-   buffHi = buffLo = 0;
-   currBlock = 0;
-   bStart[currBlock] = 0;
-
-   rbCtr = 0;
-
-   while (True) {
-      b = bsGetBit ( bsIn );
-      bitsRead++;
-      if (b == 2) {
-         if (bitsRead >= bStart[currBlock] &&
-            (bitsRead - bStart[currBlock]) >= 40) {
-            bEnd[currBlock] = bitsRead-1;
-            if (currBlock > 0)
-               fprintf ( stderr, "   block %d runs from " MaybeUInt64_FMT
-                                 " to " MaybeUInt64_FMT " (incomplete)\n",
-                         currBlock,  bStart[currBlock], bEnd[currBlock] );
-         } else
-            currBlock--;
-         break;
-      }
-      buffHi = (buffHi << 1) | (buffLo >> 31);
-      buffLo = (buffLo << 1) | (b & 1);
-      if ( ( (buffHi & 0x0000ffff) == BLOCK_HEADER_HI
-             && buffLo == BLOCK_HEADER_LO)
-           ||
-           ( (buffHi & 0x0000ffff) == BLOCK_ENDMARK_HI
-             && buffLo == BLOCK_ENDMARK_LO)
-         ) {
-         if (bitsRead > 49) {
-            bEnd[currBlock] = bitsRead-49;
-         } else {
-            bEnd[currBlock] = 0;
-         }
-         if (currBlock > 0 &&
-             (bEnd[currBlock] - bStart[currBlock]) >= 130) {
-            fprintf ( stderr, "   block %d runs from " MaybeUInt64_FMT
-                              " to " MaybeUInt64_FMT "\n",
-                      rbCtr+1,  bStart[currBlock], bEnd[currBlock] );
-            rbStart[rbCtr] = bStart[currBlock];
-            rbEnd[rbCtr] = bEnd[currBlock];
-            rbCtr++;
-         }
-         if (currBlock >= BZ_MAX_HANDLED_BLOCKS)
-            tooManyBlocks(BZ_MAX_HANDLED_BLOCKS);
-         currBlock++;
-
-         bStart[currBlock] = bitsRead;
-      }
-   }
-
-   bsClose ( bsIn );
-
-   /*-- identified blocks run from 1 to rbCtr inclusive. --*/
-
-   if (rbCtr < 1) {
-      fprintf ( stderr,
-                "%s: sorry, I couldn't find any block boundaries.\n",
-                progName );
-      exit(1);
-   };
-
-   fprintf ( stderr, "%s: splitting into blocks\n", progName );
-
-   inFile = fopen ( inFileName, "rb" );
-   if (inFile == NULL) {
-      fprintf ( stderr, "%s: can't open `%s'\n", progName, inFileName );
-      exit(1);
-   }
-   bsIn = bsOpenReadStream ( inFile );
-
-   /*-- placate gcc's dataflow analyser --*/
-   blockCRC = 0; bsWr = 0;
-
-   bitsRead = 0;
-   outFile = NULL;
-   wrBlock = 0;
-   while (True) {
-      b = bsGetBit(bsIn);
-      if (b == 2) break;
-      buffHi = (buffHi << 1) | (buffLo >> 31);
-      buffLo = (buffLo << 1) | (b & 1);
-      if (bitsRead == 47+rbStart[wrBlock])
-         blockCRC = (buffHi << 16) | (buffLo >> 16);
-
-      if (outFile != NULL && bitsRead >= rbStart[wrBlock]
-                          && bitsRead <= rbEnd[wrBlock]) {
-         bsPutBit ( bsWr, b );
-      }
-
-      bitsRead++;
-
-      if (bitsRead == rbEnd[wrBlock]+1) {
-         if (outFile != NULL) {
-            bsPutUChar ( bsWr, 0x17 ); bsPutUChar ( bsWr, 0x72 );
-            bsPutUChar ( bsWr, 0x45 ); bsPutUChar ( bsWr, 0x38 );
-            bsPutUChar ( bsWr, 0x50 ); bsPutUChar ( bsWr, 0x90 );
-            bsPutUInt32 ( bsWr, blockCRC );
-            bsClose ( bsWr );
-            outFile = NULL;
-         }
-         if (wrBlock >= rbCtr) break;
-         wrBlock++;
-      } else
-      if (bitsRead == rbStart[wrBlock]) {
-         /* Create the output file name, correctly handling leading paths.
-            (31.10.2001 by Sergey E. Kusikov) */
-         Char* split;
-         Int32 ofs, k;
-         for (k = 0; k < BZ_MAX_FILENAME; k++)
-            outFileName[k] = 0;
-         strcpy (outFileName, inFileName);
-         split = strrchr (outFileName, BZ_SPLIT_SYM);
-         if (split == NULL) {
-            split = outFileName;
-         } else {
-            ++split;
-         }
-         /* Now split points to the start of the basename. */
-         ofs  = split - outFileName;
-         sprintf (split, "rec%5d", wrBlock+1);
-         for (p = split; *p != 0; p++) if (*p == ' ') *p = '0';
-         strcat (outFileName, inFileName + ofs);
-
-         if ( !endsInBz2(outFileName)) strcat ( outFileName, ".bz2" );
-
-         fprintf ( stderr, "   writing block %d to `%s' ...\n",
-                           wrBlock+1, outFileName );
-
-         outFile = fopen_output_safely ( outFileName, "wb" );
-         if (outFile == NULL) {
-            fprintf ( stderr, "%s: can't write `%s'\n",
-                      progName, outFileName );
-            exit(1);
-         }
-         bsWr = bsOpenWriteStream ( outFile );
-         bsPutUChar ( bsWr, BZ_HDR_B );
-         bsPutUChar ( bsWr, BZ_HDR_Z );
-         bsPutUChar ( bsWr, BZ_HDR_h );
-         bsPutUChar ( bsWr, BZ_HDR_0 + 9 );
-         bsPutUChar ( bsWr, 0x31 ); bsPutUChar ( bsWr, 0x41 );
-         bsPutUChar ( bsWr, 0x59 ); bsPutUChar ( bsWr, 0x26 );
-         bsPutUChar ( bsWr, 0x53 ); bsPutUChar ( bsWr, 0x59 );
-      }
-   }
-
-   fprintf ( stderr, "%s: finished\n", progName );
-   return 0;
-}
-
-
-
-/*-----------------------------------------------------------*/
-/*--- end                                  bzip2recover.c ---*/
-/*-----------------------------------------------------------*/
diff --git a/thirdparty/bzip2/bzlib.c b/thirdparty/bzip2/bzlib.c
deleted file mode 100644
index 91b4cbc48..000000000
--- a/thirdparty/bzip2/bzlib.c
+++ /dev/null
@@ -1,1580 +0,0 @@
-
-/*-------------------------------------------------------------*/
-/*--- Library top-level functions.                          ---*/
-/*---                                               bzlib.c ---*/
-/*-------------------------------------------------------------*/
-
-/* ------------------------------------------------------------------
-   This file is part of bzip2/libbzip2, a program and library for
-   lossless, block-sorting data compression.
-
-   bzip2/libbzip2 version 1.1.0 of 6 September 2010
-   Copyright (C) 1996-2010 Julian Seward 
-
-   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   -- made zero-length BZ_FLUSH work correctly in bzCompress().
-     fixed bzWrite/bzRead to ignore zero-length requests.
-     fixed bzread to correctly handle read requests after EOF.
-     wrong parameter order in call to bzDecompressInit in
-     bzBuffToBuffDecompress.  Fixed.
-*/
-
-#include "bzlib_private.h"
-#include "bz_version.h"
-
-
-/*---------------------------------------------------*/
-/*--- Compression stuff                           ---*/
-/*---------------------------------------------------*/
-
-
-/*---------------------------------------------------*/
-#ifndef BZ_NO_STDIO
-void BZ2_bz__AssertH__fail ( int errcode )
-{
-   fprintf(stderr,
-      "\n\nbzip2/libbzip2: internal error number %d.\n"
-      "This is a bug in bzip2/libbzip2, %s.\n"
-      "Please report it at: https://gitlab.com/bzip2/bzip2/-/issues\n"
-      "If this happened when you were using some program which uses\n"
-      "libbzip2 as a component, you should also report this bug to\n"
-      "the author(s) of that program.\n"
-      "Please make an effort to report this bug;\n"
-      "timely and accurate bug reports eventually lead to higher\n"
-      "quality software.  Thanks.\n\n",
-      errcode,
-      BZ2_bzlibVersion()
-   );
-
-   if (errcode == 1007) {
-   fprintf(stderr,
-      "\n*** A special note about internal error number 1007 ***\n"
-      "\n"
-      "Experience suggests that a common cause of i.e. 1007\n"
-      "is unreliable memory or other hardware.  The 1007 assertion\n"
-      "just happens to cross-check the results of huge numbers of\n"
-      "memory reads/writes, and so acts (unintendedly) as a stress\n"
-      "test of your memory system.\n"
-      "\n"
-      "I suggest the following: try compressing the file again,\n"
-      "possibly monitoring progress in detail with the -vv flag.\n"
-      "\n"
-      "* If the error cannot be reproduced, and/or happens at different\n"
-      "  points in compression, you may have a flaky memory system.\n"
-      "  Try a memory-test program.  I have used Memtest86\n"
-      "  (www.memtest86.com).  At the time of writing it is free (GPLd).\n"
-      "  Memtest86 tests memory much more thorougly than your BIOSs\n"
-      "  power-on test, and may find failures that the BIOS doesn't.\n"
-      "\n"
-      "* If the error can be repeatably reproduced, this is a bug in\n"
-      "  bzip2, and I would very much like to hear about it.  Please\n"
-      "  let me know, and, ideally, save a copy of the file causing the\n"
-      "  problem -- without which I will be unable to investigate it.\n"
-      "\n"
-   );
-   }
-
-   exit(3);
-}
-#endif
-
-
-/*---------------------------------------------------*/
-static
-int bz_config_ok ( void )
-{
-   if (sizeof(int)   != 4) return 0;
-   if (sizeof(short) != 2) return 0;
-   if (sizeof(char)  != 1) return 0;
-   return 1;
-}
-
-
-/*---------------------------------------------------*/
-static
-void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
-{
-   void* v = malloc ( items * size );
-   return v;
-}
-
-static
-void default_bzfree ( void* opaque, void* addr )
-{
-   if (addr != NULL) free ( addr );
-}
-
-
-/*---------------------------------------------------*/
-static
-void prepare_new_block ( EState* s )
-{
-   Int32 i;
-   s->nblock = 0;
-   s->numZ = 0;
-   s->state_out_pos = 0;
-   BZ_INITIALISE_CRC ( s->blockCRC );
-   for (i = 0; i < 256; i++) s->inUse[i] = False;
-   s->blockNo++;
-}
-
-
-/*---------------------------------------------------*/
-static
-void init_RL ( EState* s )
-{
-   s->state_in_ch  = 256;
-   s->state_in_len = 0;
-}
-
-
-static
-Bool isempty_RL ( EState* s )
-{
-   if (s->state_in_ch < 256 && s->state_in_len > 0)
-      return False; else
-      return True;
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzCompressInit)
-                    ( bz_stream* strm,
-                     int        blockSize100k,
-                     int        verbosity,
-                     int        workFactor )
-{
-   Int32   n;
-   EState* s;
-
-   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
-
-   if (strm == NULL ||
-       blockSize100k < 1 || blockSize100k > 9 ||
-       workFactor < 0 || workFactor > 250)
-     return BZ_PARAM_ERROR;
-
-   if (workFactor == 0) workFactor = 30;
-   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
-   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
-
-   s = BZALLOC( sizeof(EState) );
-   if (s == NULL) return BZ_MEM_ERROR;
-   s->strm = strm;
-
-   s->arr1 = NULL;
-   s->arr2 = NULL;
-   s->ftab = NULL;
-
-   n       = 100000 * blockSize100k;
-   s->arr1 = BZALLOC( n                  * sizeof(UInt32) );
-   s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
-   s->ftab = BZALLOC( 65537              * sizeof(UInt32) );
-
-   if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
-      if (s->arr1 != NULL) BZFREE(s->arr1);
-      if (s->arr2 != NULL) BZFREE(s->arr2);
-      if (s->ftab != NULL) BZFREE(s->ftab);
-      if (s       != NULL) BZFREE(s);
-      return BZ_MEM_ERROR;
-   }
-
-   s->blockNo           = 0;
-   s->state             = BZ_S_INPUT;
-   s->mode              = BZ_M_RUNNING;
-   s->combinedCRC       = 0;
-   s->blockSize100k     = blockSize100k;
-   s->nblockMAX         = 100000 * blockSize100k - 19;
-   s->verbosity         = verbosity;
-   s->workFactor        = workFactor;
-
-   s->block             = (UChar*)s->arr2;
-   s->mtfv              = (UInt16*)s->arr1;
-   s->zbits             = NULL;
-   s->ptr               = (UInt32*)s->arr1;
-
-   strm->state          = s;
-   strm->total_in_lo32  = 0;
-   strm->total_in_hi32  = 0;
-   strm->total_out_lo32 = 0;
-   strm->total_out_hi32 = 0;
-   init_RL ( s );
-   prepare_new_block ( s );
-   return BZ_OK;
-}
-
-
-/*---------------------------------------------------*/
-static
-void add_pair_to_block ( EState* s )
-{
-   Int32 i;
-   UChar ch = (UChar)(s->state_in_ch);
-   for (i = 0; i < s->state_in_len; i++) {
-      BZ_UPDATE_CRC( s->blockCRC, ch );
-   }
-   s->inUse[s->state_in_ch] = True;
-   switch (s->state_in_len) {
-      case 1:
-         s->block[s->nblock] = (UChar)ch; s->nblock++;
-         break;
-      case 2:
-         s->block[s->nblock] = (UChar)ch; s->nblock++;
-         s->block[s->nblock] = (UChar)ch; s->nblock++;
-         break;
-      case 3:
-         s->block[s->nblock] = (UChar)ch; s->nblock++;
-         s->block[s->nblock] = (UChar)ch; s->nblock++;
-         s->block[s->nblock] = (UChar)ch; s->nblock++;
-         break;
-      default:
-         s->inUse[s->state_in_len-4] = True;
-         s->block[s->nblock] = (UChar)ch; s->nblock++;
-         s->block[s->nblock] = (UChar)ch; s->nblock++;
-         s->block[s->nblock] = (UChar)ch; s->nblock++;
-         s->block[s->nblock] = (UChar)ch; s->nblock++;
-         s->block[s->nblock] = ((UChar)(s->state_in_len-4));
-         s->nblock++;
-         break;
-   }
-}
-
-
-/*---------------------------------------------------*/
-static
-void flush_RL ( EState* s )
-{
-   if (s->state_in_ch < 256) add_pair_to_block ( s );
-   init_RL ( s );
-}
-
-
-/*---------------------------------------------------*/
-#define ADD_CHAR_TO_BLOCK(zs,zchh0)               \
-{                                                 \
-   UInt32 zchh = (UInt32)(zchh0);                 \
-   /*-- fast track the common case --*/           \
-   if (zchh != zs->state_in_ch &&                 \
-       zs->state_in_len == 1) {                   \
-      UChar ch = (UChar)(zs->state_in_ch);        \
-      BZ_UPDATE_CRC( zs->blockCRC, ch );          \
-      zs->inUse[zs->state_in_ch] = True;          \
-      zs->block[zs->nblock] = (UChar)ch;          \
-      zs->nblock++;                               \
-      zs->state_in_ch = zchh;                     \
-   }                                              \
-   else                                           \
-   /*-- general, uncommon cases --*/              \
-   if (zchh != zs->state_in_ch ||                 \
-      zs->state_in_len == 255) {                  \
-      if (zs->state_in_ch < 256)                  \
-         add_pair_to_block ( zs );                \
-      zs->state_in_ch = zchh;                     \
-      zs->state_in_len = 1;                       \
-   } else {                                       \
-      zs->state_in_len++;                         \
-   }                                              \
-}
-
-
-/*---------------------------------------------------*/
-static
-Bool copy_input_until_stop ( EState* s )
-{
-   Bool progress_in = False;
-
-   if (s->mode == BZ_M_RUNNING) {
-
-      /*-- fast track the common case --*/
-      while (True) {
-         /*-- block full? --*/
-         if (s->nblock >= s->nblockMAX) break;
-         /*-- no input? --*/
-         if (s->strm->avail_in == 0) break;
-         progress_in = True;
-         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
-         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++;
-      }
-
-   } else {
-
-      /*-- general, uncommon case --*/
-      while (True) {
-         /*-- block full? --*/
-         if (s->nblock >= s->nblockMAX) break;
-         /*-- no input? --*/
-         if (s->strm->avail_in == 0) break;
-         /*-- flush/finish end? --*/
-         if (s->avail_in_expect == 0) break;
-         progress_in = True;
-         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
-         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++;
-         s->avail_in_expect--;
-      }
-   }
-   return progress_in;
-}
-
-
-/*---------------------------------------------------*/
-static
-Bool copy_output_until_stop ( EState* s )
-{
-   Bool progress_out = False;
-
-   while (True) {
-
-      /*-- no output space? --*/
-      if (s->strm->avail_out == 0) break;
-
-      /*-- block done? --*/
-      if (s->state_out_pos >= s->numZ) break;
-
-      progress_out = True;
-      *(s->strm->next_out) = s->zbits[s->state_out_pos];
-      s->state_out_pos++;
-      s->strm->avail_out--;
-      s->strm->next_out++;
-      s->strm->total_out_lo32++;
-      if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
-   }
-
-   return progress_out;
-}
-
-
-/*---------------------------------------------------*/
-static
-Bool handle_compress ( bz_stream* strm )
-{
-   Bool progress_in  = False;
-   Bool progress_out = False;
-   EState* s = strm->state;
-
-   while (True) {
-
-      if (s->state == BZ_S_OUTPUT) {
-         progress_out |= copy_output_until_stop ( s );
-         if (s->state_out_pos < s->numZ) break;
-         if (s->mode == BZ_M_FINISHING &&
-             s->avail_in_expect == 0 &&
-             isempty_RL(s)) break;
-         prepare_new_block ( s );
-         s->state = BZ_S_INPUT;
-         if (s->mode == BZ_M_FLUSHING &&
-             s->avail_in_expect == 0 &&
-             isempty_RL(s)) break;
-      }
-
-      if (s->state == BZ_S_INPUT) {
-         progress_in |= copy_input_until_stop ( s );
-         if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
-            flush_RL ( s );
-            BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
-            s->state = BZ_S_OUTPUT;
-         }
-         else
-         if (s->nblock >= s->nblockMAX) {
-            BZ2_compressBlock ( s, False );
-            s->state = BZ_S_OUTPUT;
-         }
-         else
-         if (s->strm->avail_in == 0) {
-            break;
-         }
-      }
-
-   }
-
-   return progress_in || progress_out;
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
-{
-   Bool progress;
-   EState* s;
-   if (strm == NULL) return BZ_PARAM_ERROR;
-   s = strm->state;
-   if (s == NULL) return BZ_PARAM_ERROR;
-   if (s->strm != strm) return BZ_PARAM_ERROR;
-
-   preswitch:
-   switch (s->mode) {
-
-      case BZ_M_IDLE:
-         return BZ_SEQUENCE_ERROR;
-
-      case BZ_M_RUNNING:
-         if (action == BZ_RUN) {
-            progress = handle_compress ( strm );
-            return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
-         }
-         else
-         if (action == BZ_FLUSH) {
-            s->avail_in_expect = strm->avail_in;
-            s->mode = BZ_M_FLUSHING;
-            goto preswitch;
-         }
-         else
-         if (action == BZ_FINISH) {
-            s->avail_in_expect = strm->avail_in;
-            s->mode = BZ_M_FINISHING;
-            goto preswitch;
-         }
-         else
-            return BZ_PARAM_ERROR;
-
-      case BZ_M_FLUSHING:
-         if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
-         if (s->avail_in_expect != s->strm->avail_in)
-            return BZ_SEQUENCE_ERROR;
-         progress = handle_compress ( strm );
-         if (s->avail_in_expect > 0 || !isempty_RL(s) ||
-             s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
-         s->mode = BZ_M_RUNNING;
-         return BZ_RUN_OK;
-
-      case BZ_M_FINISHING:
-         if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
-         if (s->avail_in_expect != s->strm->avail_in)
-            return BZ_SEQUENCE_ERROR;
-         progress = handle_compress ( strm );
-         if (!progress) return BZ_SEQUENCE_ERROR;
-         if (s->avail_in_expect > 0 || !isempty_RL(s) ||
-             s->state_out_pos < s->numZ) return BZ_FINISH_OK;
-         s->mode = BZ_M_IDLE;
-         return BZ_STREAM_END;
-   }
-   return BZ_OK; /*--not reached--*/
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzCompressEnd)  ( bz_stream *strm )
-{
-   EState* s;
-   if (strm == NULL) return BZ_PARAM_ERROR;
-   s = strm->state;
-   if (s == NULL) return BZ_PARAM_ERROR;
-   if (s->strm != strm) return BZ_PARAM_ERROR;
-
-   if (s->arr1 != NULL) BZFREE(s->arr1);
-   if (s->arr2 != NULL) BZFREE(s->arr2);
-   if (s->ftab != NULL) BZFREE(s->ftab);
-   BZFREE(strm->state);
-
-   strm->state = NULL;
-
-   return BZ_OK;
-}
-
-
-/*---------------------------------------------------*/
-/*--- Decompression stuff                         ---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzDecompressInit)
-                     ( bz_stream* strm,
-                       int        verbosity,
-                       int        small )
-{
-   DState* s;
-
-   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
-
-   if (strm == NULL) return BZ_PARAM_ERROR;
-   if (small != 0 && small != 1) return BZ_PARAM_ERROR;
-   if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
-
-   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
-   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
-
-   s = BZALLOC( sizeof(DState) );
-   if (s == NULL) return BZ_MEM_ERROR;
-   s->strm                  = strm;
-   strm->state              = s;
-   s->state                 = BZ_X_MAGIC_1;
-   s->bsLive                = 0;
-   s->bsBuff                = 0;
-   s->calculatedCombinedCRC = 0;
-   strm->total_in_lo32      = 0;
-   strm->total_in_hi32      = 0;
-   strm->total_out_lo32     = 0;
-   strm->total_out_hi32     = 0;
-   s->smallDecompress       = (Bool)small;
-   s->ll4                   = NULL;
-   s->ll16                  = NULL;
-   s->tt                    = NULL;
-   s->currBlockNo           = 0;
-   s->verbosity             = verbosity;
-
-   return BZ_OK;
-}
-
-
-/*---------------------------------------------------*/
-/* Return  True iff data corruption is discovered.
-   Returns False if there is no problem.
-*/
-static
-Bool unRLE_obuf_to_output_FAST ( DState* s )
-{
-   UChar k1;
-
-   if (s->blockRandomised) {
-
-      while (True) {
-         /* try to finish existing run */
-         while (True) {
-            if (s->strm->avail_out == 0) return False;
-            if (s->state_out_len == 0) break;
-            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
-            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
-            s->state_out_len--;
-            s->strm->next_out++;
-            s->strm->avail_out--;
-            s->strm->total_out_lo32++;
-            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
-         }
-
-         /* can a new run be started? */
-         if (s->nblock_used == s->save_nblock+1) return False;
-
-         /* Only caused by corrupt data stream? */
-         if (s->nblock_used > s->save_nblock+1)
-            return True;
-
-         s->state_out_len = 1;
-         s->state_out_ch = s->k0;
-         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
-         k1 ^= BZ_RAND_MASK; s->nblock_used++;
-         if (s->nblock_used == s->save_nblock+1) continue;
-         if (k1 != s->k0) { s->k0 = k1; continue; };
-
-         s->state_out_len = 2;
-         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
-         k1 ^= BZ_RAND_MASK; s->nblock_used++;
-         if (s->nblock_used == s->save_nblock+1) continue;
-         if (k1 != s->k0) { s->k0 = k1; continue; };
-
-         s->state_out_len = 3;
-         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
-         k1 ^= BZ_RAND_MASK; s->nblock_used++;
-         if (s->nblock_used == s->save_nblock+1) continue;
-         if (k1 != s->k0) { s->k0 = k1; continue; };
-
-         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
-         k1 ^= BZ_RAND_MASK; s->nblock_used++;
-         s->state_out_len = ((Int32)k1) + 4;
-         BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK;
-         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
-      }
-
-   } else {
-
-      /* restore */
-      UInt32        c_calculatedBlockCRC = s->calculatedBlockCRC;
-      UChar         c_state_out_ch       = s->state_out_ch;
-      Int32         c_state_out_len      = s->state_out_len;
-      Int32         c_nblock_used        = s->nblock_used;
-      Int32         c_k0                 = s->k0;
-      UInt32*       c_tt                 = s->tt;
-      UInt32        c_tPos               = s->tPos;
-      char*         cs_next_out          = s->strm->next_out;
-      unsigned int  cs_avail_out         = s->strm->avail_out;
-      Int32         ro_blockSize100k     = s->blockSize100k;
-      /* end restore */
-
-      UInt32       avail_out_INIT = cs_avail_out;
-      Int32        s_save_nblockPP = s->save_nblock+1;
-      unsigned int total_out_lo32_old;
-
-      while (True) {
-
-         /* try to finish existing run */
-         if (c_state_out_len > 0) {
-            while (True) {
-               if (cs_avail_out == 0) goto return_notr;
-               if (c_state_out_len == 1) break;
-               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
-               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
-               c_state_out_len--;
-               cs_next_out++;
-               cs_avail_out--;
-            }
-            s_state_out_len_eq_one:
-            {
-               if (cs_avail_out == 0) {
-                  c_state_out_len = 1; goto return_notr;
-               };
-               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
-               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
-               cs_next_out++;
-               cs_avail_out--;
-            }
-         }
-         /* Only caused by corrupt data stream? */
-         if (c_nblock_used > s_save_nblockPP)
-            return True;
-
-         /* can a new run be started? */
-         if (c_nblock_used == s_save_nblockPP) {
-            c_state_out_len = 0; goto return_notr;
-         };
-         c_state_out_ch = c_k0;
-         BZ_GET_FAST_C(k1); c_nblock_used++;
-         if (k1 != c_k0) {
-            c_k0 = k1; goto s_state_out_len_eq_one;
-         };
-         if (c_nblock_used == s_save_nblockPP)
-            goto s_state_out_len_eq_one;
-
-         c_state_out_len = 2;
-         BZ_GET_FAST_C(k1); c_nblock_used++;
-         if (c_nblock_used == s_save_nblockPP) continue;
-         if (k1 != c_k0) { c_k0 = k1; continue; };
-
-         c_state_out_len = 3;
-         BZ_GET_FAST_C(k1); c_nblock_used++;
-         if (c_nblock_used == s_save_nblockPP) continue;
-         if (k1 != c_k0) { c_k0 = k1; continue; };
-
-         BZ_GET_FAST_C(k1); c_nblock_used++;
-         c_state_out_len = ((Int32)k1) + 4;
-         BZ_GET_FAST_C(c_k0); c_nblock_used++;
-      }
-
-      return_notr:
-      total_out_lo32_old = s->strm->total_out_lo32;
-      s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
-      if (s->strm->total_out_lo32 < total_out_lo32_old)
-         s->strm->total_out_hi32++;
-
-      /* save */
-      s->calculatedBlockCRC = c_calculatedBlockCRC;
-      s->state_out_ch       = c_state_out_ch;
-      s->state_out_len      = c_state_out_len;
-      s->nblock_used        = c_nblock_used;
-      s->k0                 = c_k0;
-      s->tt                 = c_tt;
-      s->tPos               = c_tPos;
-      s->strm->next_out     = cs_next_out;
-      s->strm->avail_out    = cs_avail_out;
-      /* end save */
-   }
-   return False;
-}
-
-
-
-/*---------------------------------------------------*/
-__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
-{
-   Int32 nb, na, mid;
-   nb = 0;
-   na = 256;
-   do {
-      mid = (nb + na) >> 1;
-      if (indx >= cftab[mid]) nb = mid; else na = mid;
-   }
-   while (na - nb != 1);
-   return nb;
-}
-
-
-/*---------------------------------------------------*/
-/* Return  True iff data corruption is discovered.
-   Returns False if there is no problem.
-*/
-static
-Bool unRLE_obuf_to_output_SMALL ( DState* s )
-{
-   UChar k1;
-
-   if (s->blockRandomised) {
-
-      while (True) {
-         /* try to finish existing run */
-         while (True) {
-            if (s->strm->avail_out == 0) return False;
-            if (s->state_out_len == 0) break;
-            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
-            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
-            s->state_out_len--;
-            s->strm->next_out++;
-            s->strm->avail_out--;
-            s->strm->total_out_lo32++;
-            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
-         }
-
-         /* can a new run be started? */
-         if (s->nblock_used == s->save_nblock+1) return False;
-
-         /* Only caused by corrupt data stream? */
-         if (s->nblock_used > s->save_nblock+1)
-            return True;
-
-         s->state_out_len = 1;
-         s->state_out_ch = s->k0;
-         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
-         k1 ^= BZ_RAND_MASK; s->nblock_used++;
-         if (s->nblock_used == s->save_nblock+1) continue;
-         if (k1 != s->k0) { s->k0 = k1; continue; };
-
-         s->state_out_len = 2;
-         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
-         k1 ^= BZ_RAND_MASK; s->nblock_used++;
-         if (s->nblock_used == s->save_nblock+1) continue;
-         if (k1 != s->k0) { s->k0 = k1; continue; };
-
-         s->state_out_len = 3;
-         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
-         k1 ^= BZ_RAND_MASK; s->nblock_used++;
-         if (s->nblock_used == s->save_nblock+1) continue;
-         if (k1 != s->k0) { s->k0 = k1; continue; };
-
-         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
-         k1 ^= BZ_RAND_MASK; s->nblock_used++;
-         s->state_out_len = ((Int32)k1) + 4;
-         BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK;
-         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
-      }
-
-   } else {
-
-      while (True) {
-         /* try to finish existing run */
-         while (True) {
-            if (s->strm->avail_out == 0) return False;
-            if (s->state_out_len == 0) break;
-            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
-            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
-            s->state_out_len--;
-            s->strm->next_out++;
-            s->strm->avail_out--;
-            s->strm->total_out_lo32++;
-            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
-         }
-
-         /* can a new run be started? */
-         if (s->nblock_used == s->save_nblock+1) return False;
-
-         /* Only caused by corrupt data stream? */
-         if (s->nblock_used > s->save_nblock+1)
-            return True;
-
-         s->state_out_len = 1;
-         s->state_out_ch = s->k0;
-         BZ_GET_SMALL(k1); s->nblock_used++;
-         if (s->nblock_used == s->save_nblock+1) continue;
-         if (k1 != s->k0) { s->k0 = k1; continue; };
-
-         s->state_out_len = 2;
-         BZ_GET_SMALL(k1); s->nblock_used++;
-         if (s->nblock_used == s->save_nblock+1) continue;
-         if (k1 != s->k0) { s->k0 = k1; continue; };
-
-         s->state_out_len = 3;
-         BZ_GET_SMALL(k1); s->nblock_used++;
-         if (s->nblock_used == s->save_nblock+1) continue;
-         if (k1 != s->k0) { s->k0 = k1; continue; };
-
-         BZ_GET_SMALL(k1); s->nblock_used++;
-         s->state_out_len = ((Int32)k1) + 4;
-         BZ_GET_SMALL(s->k0); s->nblock_used++;
-      }
-
-   }
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
-{
-   Bool    corrupt;
-   DState* s;
-   if (strm == NULL) return BZ_PARAM_ERROR;
-   s = strm->state;
-   if (s == NULL) return BZ_PARAM_ERROR;
-   if (s->strm != strm) return BZ_PARAM_ERROR;
-
-   while (True) {
-      if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
-      if (s->state == BZ_X_OUTPUT) {
-         if (s->smallDecompress)
-            corrupt = unRLE_obuf_to_output_SMALL ( s ); else
-            corrupt = unRLE_obuf_to_output_FAST  ( s );
-         if (corrupt) return BZ_DATA_ERROR;
-         if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
-            BZ_FINALISE_CRC ( s->calculatedBlockCRC );
-            if (s->verbosity >= 3)
-               VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC,
-                          s->calculatedBlockCRC );
-            if (s->verbosity >= 2) VPrintf0 ( "]" );
-            if (s->calculatedBlockCRC != s->storedBlockCRC)
-               return BZ_DATA_ERROR;
-            s->calculatedCombinedCRC
-               = (s->calculatedCombinedCRC << 1) |
-                    (s->calculatedCombinedCRC >> 31);
-            s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
-            s->state = BZ_X_BLKHDR_1;
-         } else {
-            return BZ_OK;
-         }
-      }
-      if (s->state >= BZ_X_MAGIC_1) {
-         Int32 r = BZ2_decompress ( s );
-         if (r == BZ_STREAM_END) {
-            if (s->verbosity >= 3)
-               VPrintf2 ( "\n    combined CRCs: stored = 0x%08x, computed = 0x%08x",
-                          s->storedCombinedCRC, s->calculatedCombinedCRC );
-            if (s->calculatedCombinedCRC != s->storedCombinedCRC)
-               return BZ_DATA_ERROR;
-            return r;
-         }
-         if (s->state != BZ_X_OUTPUT) return r;
-      }
-   }
-
-   AssertH ( 0, 6001 );
-
-   return 0;  /*NOTREACHED*/
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzDecompressEnd)  ( bz_stream *strm )
-{
-   DState* s;
-   if (strm == NULL) return BZ_PARAM_ERROR;
-   s = strm->state;
-   if (s == NULL) return BZ_PARAM_ERROR;
-   if (s->strm != strm) return BZ_PARAM_ERROR;
-
-   if (s->tt   != NULL) BZFREE(s->tt);
-   if (s->ll16 != NULL) BZFREE(s->ll16);
-   if (s->ll4  != NULL) BZFREE(s->ll4);
-
-   BZFREE(strm->state);
-   strm->state = NULL;
-
-   return BZ_OK;
-}
-
-
-#ifndef BZ_NO_STDIO
-/*---------------------------------------------------*/
-/*--- File I/O stuff                              ---*/
-/*---------------------------------------------------*/
-
-#define BZ_SETERR(eee)                    \
-{                                         \
-   if (bzerror != NULL) *bzerror = eee;   \
-   if (bzf != NULL) bzf->lastErr = eee;   \
-}
-
-typedef
-   struct {
-      FILE*     handle;
-      Char      buf[BZ_MAX_UNUSED];
-      Int32     bufN;
-      Bool      writing;
-      bz_stream strm;
-      Int32     lastErr;
-      Bool      initialisedOk;
-   }
-   bzFile;
-
-
-/*---------------------------------------------*/
-static Bool myfeof ( FILE* f )
-{
-   Int32 c = fgetc ( f );
-   if (c == EOF) return True;
-   ungetc ( c, f );
-   return False;
-}
-
-
-/*---------------------------------------------------*/
-BZFILE* BZ_API(BZ2_bzWriteOpen)
-                    ( int*  bzerror,
-                      FILE* f,
-                      int   blockSize100k,
-                      int   verbosity,
-                      int   workFactor )
-{
-   Int32   ret;
-   bzFile* bzf = NULL;
-
-   BZ_SETERR(BZ_OK);
-
-   if (f == NULL ||
-       (blockSize100k < 1 || blockSize100k > 9) ||
-       (workFactor < 0 || workFactor > 250) ||
-       (verbosity < 0 || verbosity > 4))
-      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
-
-   if (ferror(f))
-      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
-
-   bzf = malloc ( sizeof(bzFile) );
-   if (bzf == NULL)
-      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
-
-   BZ_SETERR(BZ_OK);
-   bzf->initialisedOk = False;
-   bzf->bufN          = 0;
-   bzf->handle        = f;
-   bzf->writing       = True;
-   bzf->strm.bzalloc  = NULL;
-   bzf->strm.bzfree   = NULL;
-   bzf->strm.opaque   = NULL;
-
-   if (workFactor == 0) workFactor = 30;
-   ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k,
-                              verbosity, workFactor );
-   if (ret != BZ_OK)
-      { BZ_SETERR(ret); free(bzf); return NULL; };
-
-   bzf->strm.avail_in = 0;
-   bzf->initialisedOk = True;
-   return bzf;
-}
-
-
-
-/*---------------------------------------------------*/
-void BZ_API(BZ2_bzWrite)
-             ( int*    bzerror,
-               BZFILE* b,
-               void*   buf,
-               int     len )
-{
-   Int32 n, n2, ret;
-   bzFile* bzf = (bzFile*)b;
-
-   BZ_SETERR(BZ_OK);
-   if (bzf == NULL || buf == NULL || len < 0)
-      { BZ_SETERR(BZ_PARAM_ERROR); return; };
-   if (!(bzf->writing))
-      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
-   if (ferror(bzf->handle))
-      { BZ_SETERR(BZ_IO_ERROR); return; };
-
-   if (len == 0)
-      { BZ_SETERR(BZ_OK); return; };
-
-   bzf->strm.avail_in = len;
-   bzf->strm.next_in  = buf;
-
-   while (True) {
-      bzf->strm.avail_out = BZ_MAX_UNUSED;
-      bzf->strm.next_out = bzf->buf;
-      ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
-      if (ret != BZ_RUN_OK)
-         { BZ_SETERR(ret); return; };
-
-      if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
-         n = BZ_MAX_UNUSED - bzf->strm.avail_out;
-         n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
-                       n, bzf->handle );
-         if (n != n2 || ferror(bzf->handle))
-            { BZ_SETERR(BZ_IO_ERROR); return; };
-      }
-
-      if (bzf->strm.avail_in == 0)
-         { BZ_SETERR(BZ_OK); return; };
-   }
-}
-
-
-/*---------------------------------------------------*/
-void BZ_API(BZ2_bzWriteClose)
-                  ( int*          bzerror,
-                    BZFILE*       b,
-                    int           abandon,
-                    unsigned int* nbytes_in,
-                    unsigned int* nbytes_out )
-{
-   BZ2_bzWriteClose64 ( bzerror, b, abandon,
-                        nbytes_in, NULL, nbytes_out, NULL );
-}
-
-
-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 )
-{
-   Int32   n, n2, ret;
-   bzFile* bzf = (bzFile*)b;
-
-   if (bzf == NULL)
-      { BZ_SETERR(BZ_OK); return; };
-   if (!(bzf->writing))
-      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
-   if (ferror(bzf->handle))
-      { BZ_SETERR(BZ_IO_ERROR); return; };
-
-   if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
-   if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
-   if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
-   if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
-
-   if ((!abandon) && bzf->lastErr == BZ_OK) {
-      while (True) {
-         bzf->strm.avail_out = BZ_MAX_UNUSED;
-         bzf->strm.next_out = bzf->buf;
-         ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
-         if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
-            { BZ_SETERR(ret); return; };
-
-         if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
-            n = BZ_MAX_UNUSED - bzf->strm.avail_out;
-            n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
-                          n, bzf->handle );
-            if (n != n2 || ferror(bzf->handle))
-               { BZ_SETERR(BZ_IO_ERROR); return; };
-         }
-
-         if (ret == BZ_STREAM_END) break;
-      }
-   }
-
-   if ( !abandon && !ferror ( bzf->handle ) ) {
-      fflush ( bzf->handle );
-      if (ferror(bzf->handle))
-         { BZ_SETERR(BZ_IO_ERROR); return; };
-   }
-
-   if (nbytes_in_lo32 != NULL)
-      *nbytes_in_lo32 = bzf->strm.total_in_lo32;
-   if (nbytes_in_hi32 != NULL)
-      *nbytes_in_hi32 = bzf->strm.total_in_hi32;
-   if (nbytes_out_lo32 != NULL)
-      *nbytes_out_lo32 = bzf->strm.total_out_lo32;
-   if (nbytes_out_hi32 != NULL)
-      *nbytes_out_hi32 = bzf->strm.total_out_hi32;
-
-   BZ_SETERR(BZ_OK);
-   BZ2_bzCompressEnd ( &(bzf->strm) );
-   free ( bzf );
-}
-
-
-/*---------------------------------------------------*/
-BZFILE* BZ_API(BZ2_bzReadOpen)
-                   ( int*  bzerror,
-                     FILE* f,
-                     int   verbosity,
-                     int   small,
-                     void* unused,
-                     int   nUnused )
-{
-   bzFile* bzf = NULL;
-   int     ret;
-
-   BZ_SETERR(BZ_OK);
-
-   if (f == NULL ||
-       (small != 0 && small != 1) ||
-       (verbosity < 0 || verbosity > 4) ||
-       (unused == NULL && nUnused != 0) ||
-       (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
-      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
-
-   if (ferror(f))
-      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
-
-   bzf = malloc ( sizeof(bzFile) );
-   if (bzf == NULL)
-      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
-
-   BZ_SETERR(BZ_OK);
-
-   bzf->initialisedOk = False;
-   bzf->handle        = f;
-   bzf->bufN          = 0;
-   bzf->writing       = False;
-   bzf->strm.bzalloc  = NULL;
-   bzf->strm.bzfree   = NULL;
-   bzf->strm.opaque   = NULL;
-
-   while (nUnused > 0) {
-      bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
-      unused = ((void*)( 1 + ((UChar*)(unused))  ));
-      nUnused--;
-   }
-
-   ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
-   if (ret != BZ_OK)
-      { BZ_SETERR(ret); free(bzf); return NULL; };
-
-   bzf->strm.avail_in = bzf->bufN;
-   bzf->strm.next_in  = bzf->buf;
-
-   bzf->initialisedOk = True;
-   return bzf;
-}
-
-
-/*---------------------------------------------------*/
-void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
-{
-   bzFile* bzf = (bzFile*)b;
-
-   BZ_SETERR(BZ_OK);
-   if (bzf == NULL)
-      { BZ_SETERR(BZ_OK); return; };
-
-   if (bzf->writing)
-      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
-
-   if (bzf->initialisedOk)
-      (void)BZ2_bzDecompressEnd ( &(bzf->strm) );
-   free ( bzf );
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzRead)
-           ( int*    bzerror,
-             BZFILE* b,
-             void*   buf,
-             int     len )
-{
-   Int32   n, ret;
-   bzFile* bzf = (bzFile*)b;
-
-   BZ_SETERR(BZ_OK);
-
-   if (bzf == NULL || buf == NULL || len < 0)
-      { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
-
-   if (bzf->writing)
-      { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
-
-   if (len == 0)
-      { BZ_SETERR(BZ_OK); return 0; };
-
-   bzf->strm.avail_out = len;
-   bzf->strm.next_out = buf;
-
-   while (True) {
-
-      if (ferror(bzf->handle))
-         { BZ_SETERR(BZ_IO_ERROR); return 0; };
-
-      if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
-         n = fread ( bzf->buf, sizeof(UChar),
-                     BZ_MAX_UNUSED, bzf->handle );
-         if (ferror(bzf->handle))
-            { BZ_SETERR(BZ_IO_ERROR); return 0; };
-         bzf->bufN = n;
-         bzf->strm.avail_in = bzf->bufN;
-         bzf->strm.next_in = bzf->buf;
-      }
-
-      ret = BZ2_bzDecompress ( &(bzf->strm) );
-
-      if (ret != BZ_OK && ret != BZ_STREAM_END)
-         { BZ_SETERR(ret); return 0; };
-
-      if (ret == BZ_OK && myfeof(bzf->handle) &&
-          bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
-         { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
-
-      if (ret == BZ_STREAM_END)
-         { BZ_SETERR(BZ_STREAM_END);
-           return len - bzf->strm.avail_out; };
-      if (bzf->strm.avail_out == 0)
-         { BZ_SETERR(BZ_OK); return len; };
-
-   }
-
-   return 0; /*not reached*/
-}
-
-
-/*---------------------------------------------------*/
-void BZ_API(BZ2_bzReadGetUnused)
-                     ( int*    bzerror,
-                       BZFILE* b,
-                       void**  unused,
-                       int*    nUnused )
-{
-   bzFile* bzf = (bzFile*)b;
-   if (bzf == NULL)
-      { BZ_SETERR(BZ_PARAM_ERROR); return; };
-   if (bzf->lastErr != BZ_STREAM_END)
-      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
-   if (unused == NULL || nUnused == NULL)
-      { BZ_SETERR(BZ_PARAM_ERROR); return; };
-
-   BZ_SETERR(BZ_OK);
-   *nUnused = bzf->strm.avail_in;
-   *unused = bzf->strm.next_in;
-}
-#endif
-
-
-/*---------------------------------------------------*/
-/*--- Misc convenience stuff                      ---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzBuffToBuffCompress)
-                         ( char*         dest,
-                           unsigned int* destLen,
-                           char*         source,
-                           unsigned int  sourceLen,
-                           int           blockSize100k,
-                           int           verbosity,
-                           int           workFactor )
-{
-   bz_stream strm;
-   int ret;
-
-   if (dest == NULL || destLen == NULL ||
-       source == NULL ||
-       blockSize100k < 1 || blockSize100k > 9 ||
-       verbosity < 0 || verbosity > 4 ||
-       workFactor < 0 || workFactor > 250)
-      return BZ_PARAM_ERROR;
-
-   if (workFactor == 0) workFactor = 30;
-   strm.bzalloc = NULL;
-   strm.bzfree = NULL;
-   strm.opaque = NULL;
-   ret = BZ2_bzCompressInit ( &strm, blockSize100k,
-                              verbosity, workFactor );
-   if (ret != BZ_OK) return ret;
-
-   strm.next_in = source;
-   strm.next_out = dest;
-   strm.avail_in = sourceLen;
-   strm.avail_out = *destLen;
-
-   ret = BZ2_bzCompress ( &strm, BZ_FINISH );
-   if (ret == BZ_FINISH_OK) goto output_overflow;
-   if (ret != BZ_STREAM_END) goto errhandler;
-
-   /* normal termination */
-   *destLen -= strm.avail_out;
-   BZ2_bzCompressEnd ( &strm );
-   return BZ_OK;
-
-   output_overflow:
-   BZ2_bzCompressEnd ( &strm );
-   return BZ_OUTBUFF_FULL;
-
-   errhandler:
-   BZ2_bzCompressEnd ( &strm );
-   return ret;
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzBuffToBuffDecompress)
-                           ( char*         dest,
-                             unsigned int* destLen,
-                             char*         source,
-                             unsigned int  sourceLen,
-                             int           small,
-                             int           verbosity )
-{
-   bz_stream strm;
-   int ret;
-
-   if (dest == NULL || destLen == NULL ||
-       source == NULL ||
-       (small != 0 && small != 1) ||
-       verbosity < 0 || verbosity > 4)
-          return BZ_PARAM_ERROR;
-
-   strm.bzalloc = NULL;
-   strm.bzfree = NULL;
-   strm.opaque = NULL;
-   ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
-   if (ret != BZ_OK) return ret;
-
-   strm.next_in = source;
-   strm.next_out = dest;
-   strm.avail_in = sourceLen;
-   strm.avail_out = *destLen;
-
-   ret = BZ2_bzDecompress ( &strm );
-   if (ret == BZ_OK) goto output_overflow_or_eof;
-   if (ret != BZ_STREAM_END) goto errhandler;
-
-   /* normal termination */
-   *destLen -= strm.avail_out;
-   BZ2_bzDecompressEnd ( &strm );
-   return BZ_OK;
-
-   output_overflow_or_eof:
-   if (strm.avail_out > 0) {
-      BZ2_bzDecompressEnd ( &strm );
-      return BZ_UNEXPECTED_EOF;
-   } else {
-      BZ2_bzDecompressEnd ( &strm );
-      return BZ_OUTBUFF_FULL;
-   };
-
-   errhandler:
-   BZ2_bzDecompressEnd ( &strm );
-   return ret;
-}
-
-
-/*---------------------------------------------------*/
-/*--
-   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.
---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------------*/
-/*--
-   return version like "0.9.5d, 4-Sept-1999".
---*/
-const char * BZ_API(BZ2_bzlibVersion)(void)
-{
-   return BZ_VERSION;
-}
-
-
-#ifndef BZ_NO_STDIO
-/*---------------------------------------------------*/
-
-#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
-#   include 
-#   include 
-#   define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
-#else
-#   define SET_BINARY_MODE(file)
-#endif
-static
-BZFILE * bzopen_or_bzdopen
-               ( const char *path,   /* no use when bzdopen */
-                 int fd,             /* no use when bzdopen */
-                 const char *mode,
-                 int open_mode)      /* bzopen: 0, bzdopen:1 */
-{
-   int    bzerr;
-   char   unused[BZ_MAX_UNUSED];
-   int    blockSize100k = 9;
-   int    writing       = 0;
-   char   mode2[10]     = "";
-   FILE   *fp           = NULL;
-   BZFILE *bzfp         = NULL;
-   int    verbosity     = 0;
-   int    workFactor    = 30;
-   int    smallMode     = 0;
-   int    nUnused       = 0;
-
-   if (mode == NULL) return NULL;
-   while (*mode) {
-      switch (*mode) {
-      case 'r':
-         writing = 0; break;
-      case 'w':
-         writing = 1; break;
-      case 's':
-         smallMode = 1; break;
-      default:
-         if (isdigit((int)(*mode))) {
-            blockSize100k = *mode-BZ_HDR_0;
-         }
-      }
-      mode++;
-   }
-
-   strcat(mode2, writing ? "wb" : "rb" );
-
-   /* open fds with O_CLOEXEC _only_ when we are the initiator
-    * aka. bzopen() but not bzdopen() */
-   if(open_mode == 0) {
-      strcat (mode2, writing ? "e" : "e" );
-   }
-
-   if (open_mode==0) {
-      if (path==NULL || strcmp(path,"")==0) {
-        fp = (writing ? stdout : stdin);
-        SET_BINARY_MODE(fp);
-      } else {
-        fp = fopen(path,mode2);
-      }
-   } else {
-#ifdef BZ_STRICT_ANSI
-      fp = NULL;
-#else
-      fp = fdopen(fd,mode2);
-#endif
-   }
-   if (fp == NULL) return NULL;
-
-   if (writing) {
-      /* Guard against total chaos and anarchy -- JRS */
-      if (blockSize100k < 1) blockSize100k = 1;
-      if (blockSize100k > 9) blockSize100k = 9;
-      bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k,
-                             verbosity,workFactor);
-   } else {
-      bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
-                            unused,nUnused);
-   }
-   if (bzfp == NULL) {
-      if (fp != stdin && fp != stdout) fclose(fp);
-      return NULL;
-   }
-   return bzfp;
-}
-
-
-/*---------------------------------------------------*/
-/*--
-   open file for read or write.
-      ex) bzopen("file","w9")
-      case path="" or NULL => use stdin or stdout.
---*/
-BZFILE * BZ_API(BZ2_bzopen)
-               ( const char *path,
-                 const char *mode )
-{
-   return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
-}
-
-
-/*---------------------------------------------------*/
-BZFILE * BZ_API(BZ2_bzdopen)
-               ( int fd,
-                 const char *mode )
-{
-   return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
-{
-   int bzerr, nread;
-   if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
-   nread = BZ2_bzRead(&bzerr,b,buf,len);
-   if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
-      return nread;
-   } else {
-      return -1;
-   }
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
-{
-   int bzerr;
-
-   BZ2_bzWrite(&bzerr,b,buf,len);
-   if(bzerr == BZ_OK){
-      return len;
-   }else{
-      return -1;
-   }
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzflush) (BZFILE *b)
-{
-   /* do nothing now... */
-   return 0;
-}
-
-
-/*---------------------------------------------------*/
-void BZ_API(BZ2_bzclose) (BZFILE* b)
-{
-   int bzerr;
-   FILE *fp;
-
-   if (b==NULL) {return;}
-   fp = ((bzFile *)b)->handle;
-   if(((bzFile*)b)->writing){
-      BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
-      if(bzerr != BZ_OK){
-         BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
-      }
-   }else{
-      BZ2_bzReadClose(&bzerr,b);
-   }
-   if(fp!=stdin && fp!=stdout){
-      fclose(fp);
-   }
-}
-
-
-/*---------------------------------------------------*/
-/*--
-   return last error code
---*/
-static const char *bzerrorstrings[] = {
-       "OK"
-      ,"SEQUENCE_ERROR"
-      ,"PARAM_ERROR"
-      ,"MEM_ERROR"
-      ,"DATA_ERROR"
-      ,"DATA_ERROR_MAGIC"
-      ,"IO_ERROR"
-      ,"UNEXPECTED_EOF"
-      ,"OUTBUFF_FULL"
-      ,"CONFIG_ERROR"
-      ,"???"   /* for future */
-      ,"???"   /* for future */
-      ,"???"   /* for future */
-      ,"???"   /* for future */
-      ,"???"   /* for future */
-      ,"???"   /* for future */
-};
-
-
-const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
-{
-   int err = ((bzFile *)b)->lastErr;
-
-   if(err>0) err = 0;
-   *errnum = err;
-   return bzerrorstrings[err*-1];
-}
-#endif
-
-
-/*-------------------------------------------------------------*/
-/*--- end                                           bzlib.c ---*/
-/*-------------------------------------------------------------*/
diff --git a/thirdparty/bzip2/bzlib.h b/thirdparty/bzip2/bzlib.h
deleted file mode 100644
index 96e1b546d..000000000
--- a/thirdparty/bzip2/bzlib.h
+++ /dev/null
@@ -1,287 +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.1.0 of 6 September 2010
-   Copyright (C) 1996-2010 Julian Seward 
-
-   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 
-#endif
-
-#ifdef _WIN32
-#   include 
-#   ifdef small
-      /* windows.h define small to char */
-#      undef small
-#   endif
-#   ifndef WINAPI
-#   define WINAPI
-#   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
-#endif
-
-#ifndef BZ_EXTERN
-#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 ---*/
-/*-------------------------------------------------------------*/
diff --git a/thirdparty/bzip2/bzlib_private.h b/thirdparty/bzip2/bzlib_private.h
deleted file mode 100644
index 73f895057..000000000
--- a/thirdparty/bzip2/bzlib_private.h
+++ /dev/null
@@ -1,507 +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.1.0 of 6 September 2010
-   Copyright (C) 1996-2010 Julian Seward 
-
-   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 
-
-#ifndef BZ_NO_STDIO
-#include 
-#include 
-#include 
-#endif
-
-#include "bzlib.h"
-
-
-
-/*-- General stuff. --*/
-
-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 ---*/
-/*-------------------------------------------------------------*/
diff --git a/thirdparty/bzip2/bzmore b/thirdparty/bzip2/bzmore
deleted file mode 100644
index d31404340..000000000
--- a/thirdparty/bzip2/bzmore
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/bin/sh
-
-# Bzmore wrapped for bzip2, 
-# adapted from zmore by Philippe Troin  for Debian GNU/Linux.
-
-PATH="/usr/bin:$PATH"; export PATH
-
-prog=`echo $0 | sed 's|.*/||'`
-case "$prog" in
-	*less)	more=less	;;
-	*)	more=more       ;;
-esac
-
-if test "`echo -n a`" = "-n a"; then
-  # looks like a SysV system:
-  n1=''; n2='\c'
-else
-  n1='-n'; n2=''
-fi
-oldtty=`stty -g 2>/dev/null`
-if stty -cbreak 2>/dev/null; then
-  cb='cbreak'; ncb='-cbreak'
-else
-  # 'stty min 1' resets eof to ^a on both SunOS and SysV!
-  cb='min 1 -icanon'; ncb='icanon eof ^d'
-fi
-if test $? -eq 0 -a -n "$oldtty"; then
-   trap 'stty $oldtty 2>/dev/null; exit' 0 2 3 5 10 13 15
-else
-   trap 'stty $ncb echo 2>/dev/null; exit' 0 2 3 5 10 13 15
-fi
-
-if test $# = 0; then
-    if test -t 0; then
-	echo usage: $prog files...
-    else
-	bzip2 -cdfq | eval $more
-    fi
-else
-    FIRST=1
-    for FILE
-    do
-	if test $FIRST -eq 0; then
-		echo $n1 "--More--(Next file: $FILE)$n2"
-		stty $cb -echo 2>/dev/null
-		ANS=`dd bs=1 count=1 2>/dev/null` 
-		stty $ncb echo 2>/dev/null
-		echo " "
-		if test "$ANS" = 'e' -o "$ANS" = 'q'; then
-			exit
-		fi
-	fi
-	if test "$ANS" != 's'; then
-		echo "------> $FILE <------"
-		bzip2 -cdfq "$FILE" | eval $more
-	fi
-	if test -t; then
-		FIRST=0
-	fi
-    done
-fi
diff --git a/thirdparty/bzip2/cmake/ExtractValidFlags.cmake b/thirdparty/bzip2/cmake/ExtractValidFlags.cmake
deleted file mode 100644
index 2081a0e76..000000000
--- a/thirdparty/bzip2/cmake/ExtractValidFlags.cmake
+++ /dev/null
@@ -1,18 +0,0 @@
-# Convenience function that checks the availability of certain
-# C or C++ compiler flags and returns valid ones as a string.
-
-include(CheckCCompilerFlag)
-include(CheckCXXCompilerFlag)
-
-function(extract_valid_c_flags varname)
-  set(valid_flags)
-  foreach(flag IN LISTS ARGN)
-    string(REGEX REPLACE "[^a-zA-Z0-9_]+" "_" flag_var ${flag})
-    set(flag_var "C_FLAG_${flag_var}")
-    check_c_compiler_flag("${flag}" "${flag_var}")
-    if(${flag_var})
-      set(valid_flags "${valid_flags} ${flag}")
-    endif()
-  endforeach()
-  set(${varname} "${valid_flags}" PARENT_SCOPE)
-endfunction()
diff --git a/thirdparty/bzip2/cmake/FindCUnit.cmake b/thirdparty/bzip2/cmake/FindCUnit.cmake
deleted file mode 100644
index ada87c165..000000000
--- a/thirdparty/bzip2/cmake/FindCUnit.cmake
+++ /dev/null
@@ -1,40 +0,0 @@
-# - Try to find cunit
-# Once done this will define
-#  CUNIT_FOUND        - System has cunit
-#  CUNIT_INCLUDE_DIRS - The cunit include directories
-#  CUNIT_LIBRARIES    - The libraries needed to use cunit
-
-find_package(PkgConfig QUIET)
-pkg_check_modules(PC_CUNIT QUIET cunit)
-
-find_path(CUNIT_INCLUDE_DIR
-  NAMES CUnit/CUnit.h
-  HINTS ${PC_CUNIT_INCLUDE_DIRS}
-)
-find_library(CUNIT_LIBRARY
-  NAMES cunit
-  HINTS ${PC_CUNIT_LIBRARY_DIRS}
-)
-
-if(CUNIT_INCLUDE_DIR)
-  set(_version_regex "^#define[ \t]+CU_VERSION[ \t]+\"([^\"]+)\".*")
-  file(STRINGS "${CUNIT_INCLUDE_DIR}/CUnit/CUnit.h"
-    CUNIT_VERSION REGEX "${_version_regex}")
-  string(REGEX REPLACE "${_version_regex}" "\\1"
-    CUNIT_VERSION "${CUNIT_VERSION}")
-  unset(_version_regex)
-endif()
-
-include(FindPackageHandleStandardArgs)
-# handle the QUIETLY and REQUIRED arguments and set CUNIT_FOUND to TRUE
-# if all listed variables are TRUE and the requested version matches.
-find_package_handle_standard_args(CUnit REQUIRED_VARS
-                                  CUNIT_LIBRARY CUNIT_INCLUDE_DIR
-                                  VERSION_VAR CUNIT_VERSION)
-
-if(CUNIT_FOUND)
-  set(CUNIT_LIBRARIES     ${CUNIT_LIBRARY})
-  set(CUNIT_INCLUDE_DIRS  ${CUNIT_INCLUDE_DIR})
-endif()
-
-mark_as_advanced(CUNIT_INCLUDE_DIR CUNIT_LIBRARY)
diff --git a/thirdparty/bzip2/cmake/FindValgrind.cmake b/thirdparty/bzip2/cmake/FindValgrind.cmake
deleted file mode 100644
index e55ba4e7c..000000000
--- a/thirdparty/bzip2/cmake/FindValgrind.cmake
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Find the Valgrind program.
-#
-# If found, will set: Valgrind_FOUND, Valgrind_VERSION, and Valgrind_EXECUTABLE
-#
-# If you have a custom install location for Valgrind, you can provide a hint
-# by settings -DValgrind_HOME=
-#
-
-find_program(Valgrind_EXECUTABLE valgrind
-    HINTS "${Valgrind_HOME}"
-    PATH_SUFFIXES "bin"
-)
-if(Valgrind_EXECUTABLE)
-    execute_process(COMMAND "${Valgrind_EXECUTABLE}" --version
-        OUTPUT_VARIABLE Valgrind_VERSION_OUTPUT
-        ERROR_VARIABLE  Valgrind_VERSION_ERROR
-        RESULT_VARIABLE Valgrind_VERSION_RESULT
-    )
-    if(NOT ${Valgrind_VERSION_RESULT} EQUAL 0)
-        message(STATUS "Valgrind not found: Failed to determine version.")
-        unset(Valgrind_EXECUTABLE)
-    else()
-        string(REGEX
-            MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?(-nightly)?"
-            Valgrind_VERSION "${Valgrind_VERSION_OUTPUT}"
-        )
-        set(Valgrind_VERSION "${Valgrind_VERSION}")
-        set(Valgrind_FOUND 1)
-        message(STATUS "Valgrind found: ${Valgrind_EXECUTABLE}, ${Valgrind_VERSION}")
-    endif()
-
-    mark_as_advanced(Valgrind_EXECUTABLE Valgrind_VERSION)
-else()
-    message(STATUS "Valgrind not found.")
-endif()
diff --git a/thirdparty/bzip2/cmake/SymLink.cmake b/thirdparty/bzip2/cmake/SymLink.cmake
deleted file mode 100644
index 19f7739c7..000000000
--- a/thirdparty/bzip2/cmake/SymLink.cmake
+++ /dev/null
@@ -1,26 +0,0 @@
-# Install a symlink of script to the "bin" directory.
-# Not intended for use on Windows.
-function(install_script_symlink original symlink)
-    add_custom_command(OUTPUT ${symlink}
-        COMMAND ${CMAKE_COMMAND} -E create_symlink ${original} ${symlink}
-        DEPENDS ${original}
-        COMMENT "Generating symbolic link ${symlink} of ${original}")
-    add_custom_target(${symlink}_tgt ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${symlink})
-    install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${symlink} DESTINATION ${CMAKE_INSTALL_BINDIR})
-endfunction()
-
-# Install a symlink of binary target to the "bin" directory.
-# On Windows, it will be a copy instead of a symlink.
-function(install_target_symlink original symlink)
-    if(WIN32)
-        set(op copy)
-        set(symlink "${symlink}.exe")
-    else()
-        set(op create_symlink)
-    endif()
-    add_custom_command(TARGET ${original} POST_BUILD
-        COMMAND ${CMAKE_COMMAND} -E ${op} $ ${symlink}
-        WORKING_DIRECTORY $
-        COMMENT "Generating symbolic link (or copy) ${symlink} of ${original}")
-    install(PROGRAMS $/${symlink} DESTINATION ${CMAKE_INSTALL_BINDIR})
-endfunction()
diff --git a/thirdparty/bzip2/cmake/Version.cmake b/thirdparty/bzip2/cmake/Version.cmake
deleted file mode 100644
index 8ac4849c9..000000000
--- a/thirdparty/bzip2/cmake/Version.cmake
+++ /dev/null
@@ -1,11 +0,0 @@
-# Converts a version such as 1.2.255 to 0x0102ff
-function(HexVersion version_hex_var major minor patch)
-  math(EXPR version_dec "${major} * 256 * 256 + ${minor} * 256 + ${patch}")
-  set(version_hex "0x")
-  foreach(i RANGE 5 0 -1)
-    math(EXPR num "(${version_dec} >> (4 * ${i})) & 15")
-    string(SUBSTRING "0123456789abcdef" ${num} 1 num_hex)
-    set(version_hex "${version_hex}${num_hex}")
-  endforeach()
-  set(${version_hex_var} "${version_hex}" PARENT_SCOPE)
-endfunction()
diff --git a/thirdparty/bzip2/code-of-conduct.md b/thirdparty/bzip2/code-of-conduct.md
deleted file mode 100644
index 941574a19..000000000
--- a/thirdparty/bzip2/code-of-conduct.md
+++ /dev/null
@@ -1,74 +0,0 @@
-# Contributor Covenant Code of Conduct
-
-## Our Pledge
-
-In the interest of fostering an open and welcoming environment, we as
-contributors and maintainers pledge to making participation in our project and
-our community a harassment-free experience for everyone, regardless of age, body
-size, disability, ethnicity, gender identity and expression, level of experience,
-education, socio-economic status, nationality, personal appearance, race,
-religion, or sexual identity and orientation.
-
-## Our Standards
-
-Examples of behavior that contributes to creating a positive environment
-include:
-
-* Using welcoming and inclusive language
-* Being respectful of differing viewpoints and experiences
-* Gracefully accepting constructive criticism
-* Focusing on what is best for the community
-* Showing empathy towards other community members
-
-Examples of unacceptable behavior by participants include:
-
-* The use of sexualized language or imagery and unwelcome sexual attention or
-  advances
-* Trolling, insulting/derogatory comments, and personal or political attacks
-* Public or private harassment
-* Publishing others' private information, such as a physical or electronic
-  address, without explicit permission
-* Other conduct which could reasonably be considered inappropriate in a
-  professional setting
-
-## Our Responsibilities
-
-Project maintainers are responsible for clarifying the standards of acceptable
-behavior and are expected to take appropriate and fair corrective action in
-response to any instances of unacceptable behavior.
-
-Project maintainers have the right and responsibility to remove, edit, or
-reject comments, commits, code, wiki edits, issues, and other contributions
-that are not aligned to this Code of Conduct, or to ban temporarily or
-permanently any contributor for other behaviors that they deem inappropriate,
-threatening, offensive, or harmful.
-
-## Scope
-
-This Code of Conduct applies both within project spaces and in public spaces
-when an individual is representing the project or its community. Examples of
-representing a project or community include using an official project e-mail
-address, posting via an official social media account, or acting as an appointed
-representative at an online or offline event. Representation of a project may be
-further defined and clarified by project maintainers.
-
-## Enforcement
-
-Instances of abusive, harassing, or otherwise unacceptable behavior may be
-reported by contacting the project team at federico@gnome.org. All
-complaints will be reviewed and investigated and will result in a response that
-is deemed necessary and appropriate to the circumstances. The project team is
-obligated to maintain confidentiality with regard to the reporter of an incident.
-Further details of specific enforcement policies may be posted separately.
-
-Project maintainers who do not follow or enforce the Code of Conduct in good
-faith may face temporary or permanent repercussions as determined by other
-members of the project's leadership.
-
-## Attribution
-
-This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
-available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
-
-[homepage]: https://www.contributor-covenant.org
-
diff --git a/thirdparty/bzip2/compress.c b/thirdparty/bzip2/compress.c
deleted file mode 100644
index 8b7711db0..000000000
--- a/thirdparty/bzip2/compress.c
+++ /dev/null
@@ -1,671 +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.1.0 of 6 September 2010
-   Copyright (C) 1996-2010 Julian Seward 
-
-   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 <= BZ_MAX_SELECTORS,
-            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 ---*/
-/*-------------------------------------------------------------*/
diff --git a/thirdparty/bzip2/crctable.c b/thirdparty/bzip2/crctable.c
deleted file mode 100644
index baf615690..000000000
--- a/thirdparty/bzip2/crctable.c
+++ /dev/null
@@ -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.1.0 of 6 September 2010
-   Copyright (C) 1996-2010 Julian Seward 
-
-   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 ---*/
-/*-------------------------------------------------------------*/
diff --git a/thirdparty/bzip2/decompress.c b/thirdparty/bzip2/decompress.c
deleted file mode 100644
index 3b2da0d93..000000000
--- a/thirdparty/bzip2/decompress.c
+++ /dev/null
@@ -1,652 +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.1.0 of 6 September 2010
-   Copyright (C) 1996-2010 Julian Seward 
-
-   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 > BZ_N_GROUPS) 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);
-         }
-         /* Having more than BZ_MAX_SELECTORS doesn't make much sense
-            since they will never be used, but some implementations might
-            "round up" the number of selectors, so just ignore those. */
-         if (i < BZ_MAX_SELECTORS)
-           s->selectorMtf[i] = j;
-      }
-      if (nSelectors > BZ_MAX_SELECTORS)
-        nSelectors = BZ_MAX_SELECTORS;
-
-      /*--- 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 ---*/
-/*-------------------------------------------------------------*/
diff --git a/thirdparty/bzip2/dlltest.c b/thirdparty/bzip2/dlltest.c
deleted file mode 100644
index 4e27da280..000000000
--- a/thirdparty/bzip2/dlltest.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
-   minibz2
-      libbz2.dll test program.
-      by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
-      This file is Public Domain.  Welcome any email to me.
-
-   usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]
-*/
-
-#define BZ_IMPORT
-#include 
-#include 
-#include "bzlib.h"
-#ifdef _WIN32
-#include 
-#endif
-
-
-#ifdef _WIN32
-
-#define BZ2_LIBNAME "libbz2-1.0.2.DLL" 
-
-#include 
-static int BZ2DLLLoaded = 0;
-static HINSTANCE BZ2DLLhLib;
-int BZ2DLLLoadLibrary(void)
-{
-   HINSTANCE hLib;
-
-   if(BZ2DLLLoaded==1){return 0;}
-   hLib=LoadLibrary(BZ2_LIBNAME);
-   if(hLib == NULL){
-      fprintf(stderr,"Can't load %s\n",BZ2_LIBNAME);
-      return -1;
-   }
-   BZ2_bzlibVersion=GetProcAddress(hLib,"BZ2_bzlibVersion");
-   BZ2_bzopen=GetProcAddress(hLib,"BZ2_bzopen");
-   BZ2_bzdopen=GetProcAddress(hLib,"BZ2_bzdopen");
-   BZ2_bzread=GetProcAddress(hLib,"BZ2_bzread");
-   BZ2_bzwrite=GetProcAddress(hLib,"BZ2_bzwrite");
-   BZ2_bzflush=GetProcAddress(hLib,"BZ2_bzflush");
-   BZ2_bzclose=GetProcAddress(hLib,"BZ2_bzclose");
-   BZ2_bzerror=GetProcAddress(hLib,"BZ2_bzerror");
-
-   if (!BZ2_bzlibVersion || !BZ2_bzopen || !BZ2_bzdopen
-       || !BZ2_bzread || !BZ2_bzwrite || !BZ2_bzflush
-       || !BZ2_bzclose || !BZ2_bzerror) {
-      fprintf(stderr,"GetProcAddress failed.\n");
-      return -1;
-   }
-   BZ2DLLLoaded=1;
-   BZ2DLLhLib=hLib;
-   return 0;
-
-}
-int BZ2DLLFreeLibrary(void)
-{
-   if(BZ2DLLLoaded==0){return 0;}
-   FreeLibrary(BZ2DLLhLib);
-   BZ2DLLLoaded=0;
-}
-#endif /* WIN32 */
-
-void usage(void)
-{
-   puts("usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]");
-}
-
-int main(int argc,char *argv[])
-{
-   int decompress = 0;
-   int level = 9;
-   char *fn_r = NULL;
-   char *fn_w = NULL;
-
-#ifdef _WIN32
-   if(BZ2DLLLoadLibrary()<0){
-      fprintf(stderr,"Loading of %s failed.  Giving up.\n", BZ2_LIBNAME);
-      exit(1);
-   }
-   printf("Loading of %s succeeded.  Library version is %s.\n",
-          BZ2_LIBNAME, BZ2_bzlibVersion() );
-#endif
-   while(++argv,--argc){
-      if(**argv =='-' || **argv=='/'){
-         char *p;
-
-         for(p=*argv+1;*p;p++){
-            if(*p=='d'){
-               decompress = 1;
-            }else if('1'<=*p && *p<='9'){
-               level = *p - '0';
-            }else{
-               usage();
-               exit(1);
-            }
-         }
-      }else{
-         break;
-      }
-   }
-   if(argc>=1){
-      fn_r = *argv;
-      argc--;argv++;
-   }else{
-      fn_r = NULL;
-   }
-   if(argc>=1){
-      fn_w = *argv;
-      argc--;argv++;
-   }else{
-      fn_w = NULL;
-   }
-   {
-      int len;
-      char buff[0x1000];
-      char mode[10];
-
-      if(decompress){
-         BZFILE *BZ2fp_r = NULL;
-         FILE *fp_w = NULL;
-
-         if(fn_w){
-            if((fp_w = fopen(fn_w,"wb"))==NULL){
-               printf("can't open [%s]\n",fn_w);
-               perror("reason:");
-               exit(1);
-            }
-         }else{
-            fp_w = stdout;
-         }
-         if((fn_r == NULL && (BZ2fp_r = BZ2_bzdopen(fileno(stdin),"rb"))==NULL)
-            || (fn_r != NULL && (BZ2fp_r = BZ2_bzopen(fn_r,"rb"))==NULL)){
-            printf("can't bz2openstream\n");
-            exit(1);
-         }
-         while((len=BZ2_bzread(BZ2fp_r,buff,0x1000))>0){
-            fwrite(buff,1,len,fp_w);
-         }
-         BZ2_bzclose(BZ2fp_r);
-         if(fp_w != stdout) fclose(fp_w);
-      }else{
-         BZFILE *BZ2fp_w = NULL;
-         FILE *fp_r = NULL;
-
-         if(fn_r){
-            if((fp_r = fopen(fn_r,"rb"))==NULL){
-               printf("can't open [%s]\n",fn_r);
-               perror("reason:");
-               exit(1);
-            }
-         }else{
-            fp_r = stdin;
-         }
-         mode[0]='w';
-         mode[1] = '0' + level;
-         mode[2] = '\0';
-
-         if((fn_w == NULL && (BZ2fp_w = BZ2_bzdopen(fileno(stdout),mode))==NULL)
-            || (fn_w !=NULL && (BZ2fp_w = BZ2_bzopen(fn_w,mode))==NULL)){
-            printf("can't bz2openstream\n");
-            exit(1);
-         }
-         while((len=fread(buff,1,0x1000,fp_r))>0){
-            BZ2_bzwrite(BZ2fp_w,buff,len);
-         }
-         BZ2_bzclose(BZ2fp_w);
-         if(fp_r!=stdin)fclose(fp_r);
-      }
-   }
-#ifdef _WIN32
-   BZ2DLLFreeLibrary();
-#endif
-   return 0;
-}
diff --git a/thirdparty/bzip2/docs/CMakeLists.txt b/thirdparty/bzip2/docs/CMakeLists.txt
deleted file mode 100644
index da877a295..000000000
--- a/thirdparty/bzip2/docs/CMakeLists.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-set(DOC_TYPES pdf ps html)
-
-find_program(PROG_SH sh)
-if(NOT PROG_SH)
-    message(FATAL_ERROR "Generator not found!")
-endif()
-
-foreach(t IN LISTS DOC_TYPES)
-    add_custom_command(
-        OUTPUT
-            manual.${t}
-        COMMAND
-            ${PROG_SH} xmlproc.sh -${t} manual.${t}
-    )
-
-    install(
-        FILES
-            ${CMAKE_CURRENT_BINARY_DIR}/manual.${t}
-        DESTINATION
-            ${CMAKE_INSTALL_PREFIX}/docs)
-endforeach()
diff --git a/thirdparty/bzip2/docs/RELEASING.md b/thirdparty/bzip2/docs/RELEASING.md
deleted file mode 100644
index 44bf09778..000000000
--- a/thirdparty/bzip2/docs/RELEASING.md
+++ /dev/null
@@ -1,14 +0,0 @@
-# Release Checklist
-
-* [ ] Increment package version at the top of [meson.build](../meson.build) and
-  [CMakeLists.txt](../CMakeLists.txt)
-
-* [ ] Increment library revision in [meson.build](../meson.build) and
-  [CMakeLists.txt](../CMakeLists.txt)
-
-* [ ] If interfaces were added, changed, or deleted, adjust per
-  [meson.build](../meson.build) and [CMakeLists.txt](../CMakeLists.txt).
-  See the GNU libtool versioning rules for library revision numbering advice:
-  http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
-
-* [ ] On release day, create a new `release/*` branch and create a release tag.
diff --git a/thirdparty/bzip2/docs/bz-common.xsl b/thirdparty/bzip2/docs/bz-common.xsl
deleted file mode 100644
index 66fcd6fe0..000000000
--- a/thirdparty/bzip2/docs/bz-common.xsl
+++ /dev/null
@@ -1,39 +0,0 @@
- 
-
-
-
- 
-
-
-
- 
- 
-   
-    
-      
-     
-  
-
-
-
-
-set       toc,title
-book      toc,title,figure,table,example,equation
-chapter   toc,title
-section   toc
-sect1     toc
-sect2     toc
-sect3     toc
-sect4     nop
-sect5     nop
-qandaset  toc
-qandadiv  nop
-appendix  toc,title
-article/appendix  nop
-article   toc,title
-preface   toc,title
-reference toc,title
-
-
-
diff --git a/thirdparty/bzip2/docs/bz-fo.xsl b/thirdparty/bzip2/docs/bz-fo.xsl
deleted file mode 100644
index ba3e30123..000000000
--- a/thirdparty/bzip2/docs/bz-fo.xsl
+++ /dev/null
@@ -1,276 +0,0 @@
- 
-
-
-
-
-
-
-
-
-
-
-
-
-      
-     
-   
-
-
-
-
- 
-
-
-
-
-
-
-  
-
-
-
-
-  blue
-
-
-
-
-  
-    
-  
-
-
-
-  
-    
-  
-
-
-
-
-  
-  
-  
-    
-      
-    
-  
-  
-    
-      
-        
-          
-          
-          
-        
-      
-    
-    
-          
-    
-  
-  
-    
-      
-        
-      
-    
-    
-      
-        
-      
-    
-  
-
-
-
-
-  
-  
-  
-    
-      
-        
-      
-    
-    
-          
-    
-  
-  
-    
-      
-        
-      
-    
-    
-      
-        
-      
-    
-  
-
-
-
-
-
-  
-    
-  
-    
-  
-  
-    
-      
-    
-  
-
-
-
-
-
-  
-  
-  
-  
-    
-      0pt
-    
-  
-  
-    
-      
-      
-      
-        
-          
-            baseline
-             
-               
-            
-          
-          
-            baseline
-            
-              
-                
-                
-                
-                
-              
-            
-          
-        
-      
-    
-  
-  
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
-
-
-
-
-  
-  
-  
-  
-    
-      0pt
-    
-  
-  
-    
-      
-        
-        
-        
-      
-      
-      
-      
-        
-          
-            baseline
-            
-               
-            
-          
-          
-            baseline
-            
-              
-                
-                
-                
-                
-              
-            
-          
-        
-      
-    
-  
-  
-  
-    
-      
-    
-    
-      
-    
-    
-      
-    
-  
-
-
-
-
-
-
-  always
-  
-    
-  
-  
-    
-    pt
-  
-  
-    
-    pt
-  
-  false
-
-
-
-
diff --git a/thirdparty/bzip2/docs/bz-html.xsl b/thirdparty/bzip2/docs/bz-html.xsl
deleted file mode 100644
index b6000d586..000000000
--- a/thirdparty/bzip2/docs/bz-html.xsl
+++ /dev/null
@@ -1,23 +0,0 @@
- 
- ]>
-
-
-
-
-
-
-
-
-
-
-
-  
-link rel="stylesheet" type="text/css" href="bzip.css" />
-  
-  
-
-
-
diff --git a/thirdparty/bzip2/docs/bzip.css b/thirdparty/bzip2/docs/bzip.css
deleted file mode 100644
index 43193d8db..000000000
--- a/thirdparty/bzip2/docs/bzip.css
+++ /dev/null
@@ -1,74 +0,0 @@
-/* Colours:
-#74240f  dark brown      h1, h2, h3, h4
-#336699  medium blue     links
-#339999  turquoise       link hover colour
-#202020  almost black    general text
-#761596  purple          md5sum text
-#626262  dark gray       pre border
-#eeeeee  very light gray pre background
-#f2f2f9  very light blue nav table background
-#3366cc  medium blue     nav table border
-*/
-
-a, a:link, a:visited, a:active { color: #336699; }
-a:hover { color: #339999; }
-
-body { font: 80%/126% sans-serif; }
-h1, h2, h3, h4 { color: #74240f; }
-
-dt { color: #336699; font-weight: bold }
-dd { 
- margin-left: 1.5em; 
- padding-bottom: 0.8em;
-}
-
-/* -- ruler -- */
-div.hr_blue { 
-  height:  3px; 
-  background:#ffffff url("/images/hr_blue.png") repeat-x; }
-div.hr_blue hr { display:none; }
-
-/* release styles */
-#release p { margin-top: 0.4em; }
-#release .md5sum { color: #761596; }
-
-
-/* ------ styles for docs|manuals|howto ------ */
-/* -- lists -- */
-ul  { 
- margin:     0px 4px 16px 16px;
- padding:    0px;
- list-style: url("/images/li-blue.png"); 
-}
-ul li { 
- margin-bottom: 10px;
-}
-ul ul	{ 
- list-style-type:  none; 
- list-style-image: none; 
- margin-left:      0px; 
-}
-
-/* header / footer nav tables */
-table.nav {
- border:     solid 1px #3366cc;
- background: #f2f2f9;
- background-color: #f2f2f9;
- margin-bottom: 0.5em;
-}
-/* don't have underlined links in chunked nav menus */
-table.nav a { text-decoration: none; }
-table.nav a:hover { text-decoration: underline; }
-table.nav td { font-size: 85%; }
-
-code, tt, pre { font-size: 120%; }
-code, tt { color: #761596; }
-
-div.literallayout, pre.programlisting, pre.screen {
- color:      #000000;
- padding:    0.5em;
- background: #eeeeee;
- border:     1px solid #626262;
- background-color: #eeeeee;
- margin: 4px 0px 4px 0px; 
-}
diff --git a/thirdparty/bzip2/docs/entities.xml b/thirdparty/bzip2/docs/entities.xml
deleted file mode 100644
index 9c20be492..000000000
--- a/thirdparty/bzip2/docs/entities.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/thirdparty/bzip2/docs/format.pl b/thirdparty/bzip2/docs/format.pl
deleted file mode 100755
index 12faf9441..000000000
--- a/thirdparty/bzip2/docs/format.pl
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/usr/bin/perl -w
-#
-# ------------------------------------------------------------------
-# This file is part of bzip2/libbzip2, a program and library for
-# lossless, block-sorting data compression.
-#
-# bzip2/libbzip2 version 1.1.0 of 6 September 2010
-# Copyright (C) 1996-2010 Julian Seward 
-#
-# 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.
-# ------------------------------------------------------------------
-#
-use strict;
-
-# get command line values:
-if ( $#ARGV !=1 ) {
-    die "Usage:  $0 xml_infile xml_outfile\n";
-}
-
-my $infile = shift;
-# check infile exists
-die "Can't find file \"$infile\""
-  unless -f $infile;
-# check we can read infile
-if (! -r $infile) {
-    die "Can't read input $infile\n";
-}
-# check we can open infile
-open( INFILE,"<$infile" ) or
-    die "Can't input $infile $!";
-
-#my $outfile = 'fmt-manual.xml';
-my $outfile = shift;
-#print "Infile: $infile, Outfile: $outfile\n";
-# check we can write to outfile
-open( OUTFILE,">$outfile" ) or
-    die "Can't output $outfile $! for writing";
-
-my ($prev, $curr, $str);
-$prev = ''; $curr = '';
-while (  ) {
-
-		print OUTFILE $prev;
-    $prev = $curr;
-    $curr = $_;
-    $str = '';
-
-    if ( $prev =~ /$|$/ ) {
-        chomp $prev;
-        $curr = join( '', $prev, "|<\/screen>/ ) {
-        chomp $prev;
-        $curr = join( '', $prev, "]]>", $curr );
-				$prev = '';
-        next;
-    }
-}
-print OUTFILE $curr;
-close INFILE;
-close OUTFILE;
-exit;
diff --git a/thirdparty/bzip2/docs/manual.xml b/thirdparty/bzip2/docs/manual.xml
deleted file mode 100644
index 73a8aca45..000000000
--- a/thirdparty/bzip2/docs/manual.xml
+++ /dev/null
@@ -1,2929 +0,0 @@
- 
-
- %common-ents;
-]>
-
-
-
- 
-  bzip2 and libbzip2, version &bz-version;
-  A program and library for data compression
-  
-   &bz-lifespan;
-   Julian Seward
-  
-  Version &bz-version; of &bz-date;
-
-  
-   
-    Julian
-    Seward
-    
-     &bz-url;
-    
-   
-  
-
-  
-
-  This program, bzip2, the
-  associated library libbzip2, and
-  all documentation, are copyright © &bz-lifespan; Julian Seward.
-  All rights reserved.
-
-  Redistribution and use in source and binary forms, with
-  or without modification, are permitted provided that the
-  following conditions are met:
-
-  
-
-   Redistributions of source code must retain the
-   above copyright notice, this list of conditions and the
-   following disclaimer.
-
-   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.
-
-   Altered source versions must be plainly marked
-   as such, and must not be misrepresented as being the original
-   software.
-
-   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.
-
- PATENTS: To the best of my knowledge,
- bzip2 and
- libbzip2 do not use any patented
- algorithms.  However, I do not have the resources to carry
- out a patent search.  Therefore I cannot give any guarantee of
- the above statement.
- 
-
-
-
-
-
-
-
-
-Introduction
-
-bzip2 compresses files
-using the Burrows-Wheeler block-sorting text compression
-algorithm, and Huffman coding.  Compression is generally
-considerably better than that achieved by more conventional
-LZ77/LZ78-based compressors, and approaches the performance of
-the PPM family of statistical compressors.
-
-bzip2 is built on top of
-libbzip2, a flexible library for
-handling compressed data in the
-bzip2 format.  This manual
-describes both how to use the program and how to work with the
-library interface.  Most of the manual is devoted to this
-library, not the program, which is good news if your interest is
-only in the program.
-
-
-
-  describes how to use
- bzip2; this is the only part
- you need to read if you just want to know how to operate the
- program.
-
-  describes the
- programming interfaces in detail, and
-
-  records some
- miscellaneous notes which I thought ought to be recorded
- somewhere.
-
-
-
-
-
-
-
-How to use bzip2
-
-This chapter contains a copy of the
-bzip2 man page, and nothing
-else.
-
-
-NAME
-
-
-
- bzip2,
-  bunzip2 - a block-sorting file
-  compressor, v&bz-version;
-
- bzcat -
-   decompresses files to stdout
-
- bzip2recover -
-   recovers data from damaged bzip2 files
-
-
-
-
-
-
-
-SYNOPSIS
-
-
-
- bzip2 [
-  -cdfkqstvzVL123456789 ] [ filenames ...  ]
-
- bzip2 [
-  -h | --help ]
-
- bunzip2 [
-  -fkvsVL ] [ filenames ...  ]
-
- bunzip2 [
-  -h | --help ]
-
- bzcat [ -s ] [
-  filenames ...  ]
-
- bzcat [
-  -h | --help ]
-
- bzip2recover
-  filename
-
-
-
-
-
-
-
-DESCRIPTION
-
-bzip2 compresses files
-using the Burrows-Wheeler block sorting text compression
-algorithm, and Huffman coding.  Compression is generally
-considerably better than that achieved by more conventional
-LZ77/LZ78-based compressors, and approaches the performance of
-the PPM family of statistical compressors.
-
-The command-line options are deliberately very similar to
-those of GNU gzip, but they are
-not identical.
-
-bzip2 expects a list of
-file names to accompany the command-line flags.  Each file is
-replaced by a compressed version of itself, with the name
-original_name.bz2.  Each
-compressed file has the same modification date, permissions, and,
-when possible, ownership as the corresponding original, so that
-these properties can be correctly restored at decompression time.
-File name handling is naive in the sense that there is no
-mechanism for preserving original file names, permissions,
-ownerships or dates in filesystems which lack these concepts, or
-have serious file name length restrictions, such as
-MS-DOS.
-
-bzip2 and
-bunzip2 will by default not
-overwrite existing files.  If you want this to happen, specify
-the -f flag.
-
-If no file names are specified,
-bzip2 compresses from standard
-input to standard output.  In this case,
-bzip2 will decline to write
-compressed output to a terminal, as this would be entirely
-incomprehensible and therefore pointless.
-
-bunzip2 (or
-bzip2 -d) decompresses all
-specified files.  Files which were not created by
-bzip2 will be detected and
-ignored, and a warning issued.
-bzip2 attempts to guess the
-filename for the decompressed file from that of the compressed
-file as follows:
-
-
-
- filename.bz2 
-  becomes
-  filename
-
- filename.bz 
-  becomes
-  filename
-
- filename.tbz2
-  becomes
-  filename.tar
-
- filename.tbz 
-  becomes
-  filename.tar
-
- anyothername 
-  becomes
-  anyothername.out
-
-
-
-If the file does not end in one of the recognised endings,
-.bz2,
-.bz,
-.tbz2 or
-.tbz,
-bzip2 complains that it cannot
-guess the name of the original file, and uses the original name
-with .out appended.
-
-As with compression, supplying no filenames causes
-decompression from standard input to standard output.
-
-bunzip2 will correctly
-decompress a file which is the concatenation of two or more
-compressed files.  The result is the concatenation of the
-corresponding uncompressed files.  Integrity testing
-(-t) of concatenated compressed
-files is also supported.
-
-You can also compress or decompress files to the standard
-output by giving the -c flag.
-Multiple files may be compressed and decompressed like this.  The
-resulting outputs are fed sequentially to stdout.  Compression of
-multiple files in this manner generates a stream containing
-multiple compressed file representations.  Such a stream can be
-decompressed correctly only by
-bzip2 version 0.9.0 or later.
-Earlier versions of bzip2 will
-stop after decompressing the first file in the stream.
-
-bzcat (or
-bzip2 -dc) decompresses all
-specified files to the standard output.
-
-bzip2 will read arguments
-from the environment variables
-BZIP2 and
-BZIP, in that order, and will
-process them before any arguments read from the command line.
-This gives a convenient way to supply default arguments.
-
-Compression is always performed, even if the compressed
-file is slightly larger than the original.  Files of less than
-about one hundred bytes tend to get larger, since the compression
-mechanism has a constant overhead in the region of 50 bytes.
-Random data (including the output of most file compressors) is
-coded at about 8.05 bits per byte, giving an expansion of around
-0.5%.
-
-As a self-check for your protection,
-bzip2 uses 32-bit CRCs to make
-sure that the decompressed version of a file is identical to the
-original.  This guards against corruption of the compressed data,
-and against undetected bugs in
-bzip2 (hopefully very unlikely).
-The chances of data corruption going undetected is microscopic,
-about one chance in four billion for each file processed.  Be
-aware, though, that the check occurs upon decompression, so it
-can only tell you that something is wrong.  It can't help you
-recover the original uncompressed data.  You can use
-bzip2recover to try to recover
-data from damaged files.
-
-Return values: 0 for a normal exit, 1 for environmental
-problems (file not found, invalid flags, I/O errors, etc.), 2
-to indicate a corrupt compressed file, 3 for an internal
-consistency error (eg, bug) which caused
-bzip2 to panic.
-
-
-
-
-
-OPTIONS
-
-
-
- 
- -c --stdout
- Compress or decompress to standard
-  output.
- 
-
- 
- -d --decompress
- Force decompression.
-  bzip2,
-  bunzip2 and
-  bzcat are really the same
-  program, and the decision about what actions to take is done on
-  the basis of which name is used.  This flag overrides that
-  mechanism, and forces bzip2 to decompress.
- 
-
- 
- -z --compress
- The complement to
-  -d: forces compression,
-  regardless of the invocation name.
- 
-
- 
- -t --test
- Check integrity of the specified file(s), but
-  don't decompress them.  This really performs a trial
-  decompression and throws away the result.
- 
-
- 
- -f --force
- Force overwrite of output files.  Normally,
-  bzip2 will not overwrite
-  existing output files.  Also forces
-  bzip2 to break hard links to
-  files, which it otherwise wouldn't do.
-  bzip2 normally declines
-  to decompress files which don't have the correct magic header
-  bytes. If forced (-f),
-  however, it will pass such files through unmodified. This is
-  how GNU gzip behaves.
- 
- 
-
- 
- -k --keep
- Keep (don't delete) input files during
-  compression or decompression.
- 
-
- 
- -s --small
- Reduce memory usage, for compression,
-  decompression and testing.  Files are decompressed and tested
-  using a modified algorithm which only requires 2.5 bytes per
-  block byte.  This means any file can be decompressed in 2300k
-  of memory, albeit at about half the normal speed.
-  During compression, -s
-  selects a block size of 200k, which limits memory use to around
-  the same figure, at the expense of your compression ratio.  In
-  short, if your machine is low on memory (8 megabytes or less),
-  use -s for everything.  See
-   below.
- 
-
- 
- -q --quiet
- Suppress non-essential warning messages.
-  Messages pertaining to I/O errors and other critical events
-  will not be suppressed.
- 
-
- -h --help
- Print a help message and exit.
- 
-
- 
- -v --verbose
- Verbose mode -- show the compression ratio for
-  each file processed.  Further
-  -v's increase the verbosity
-  level, spewing out lots of information which is primarily of
-  interest for diagnostic purposes.
- 
-
- 
- -L --license -V --version
- Display the software version, license terms and
-  conditions.
- 
-
- 
- -1 (or
- --fast) to
- -9 (or
- -best)
- Set the block size to 100 k, 200 k ...  900 k
-  when compressing.  Has no effect when decompressing.  See  below.  The
-  --fast and
-  --best aliases are primarily
-  for GNU gzip compatibility.
-  In particular, --fast doesn't
-  make things significantly faster.  And
-  --best merely selects the
-  default behaviour.
- 
-
- 
- --
- Treats all subsequent arguments as file names,
-  even if they start with a dash.  This is so you can handle
-  files with names beginning with a dash, for example:
-  bzip2 --
-  -myfilename.
- 
-
- 
- --repetitive-fast
- --repetitive-best
- These flags are redundant in versions 0.9.5 and
-  above.  They provided some coarse control over the behaviour of
-  the sorting algorithm in earlier versions, which was sometimes
-  useful.  0.9.5 and above have an improved algorithm which
-  renders these flags irrelevant.
- 
-
-
-
-
-
-
-
-MEMORY MANAGEMENT
-
-bzip2 compresses large
-files in blocks.  The block size affects both the compression
-ratio achieved, and the amount of memory needed for compression
-and decompression.  The flags -1
-through -9 specify the block
-size to be 100,000 bytes through 900,000 bytes (the default)
-respectively.  At decompression time, the block size used for
-compression is read from the header of the compressed file, and
-bunzip2 then allocates itself
-just enough memory to decompress the file.  Since block sizes are
-stored in compressed files, it follows that the flags
--1 to
--9 are irrelevant to and so
-ignored during decompression.
-
-Compression and decompression requirements, in bytes, can be
-estimated as:
-
-Compression:   400k + ( 8 x block size )
-
-Decompression: 100k + ( 4 x block size ), or
-               100k + ( 2.5 x block size )
-
-
-Larger block sizes give rapidly diminishing marginal
-returns.  Most of the compression comes from the first two or
-three hundred k of block size, a fact worth bearing in mind when
-using bzip2 on small machines.
-It is also important to appreciate that the decompression memory
-requirement is set at compression time by the choice of block
-size.
-
-For files compressed with the default 900k block size,
-bunzip2 will require about 3700
-kbytes to decompress.  To support decompression of any file on a
-4 megabyte machine, bunzip2 has
-an option to decompress using approximately half this amount of
-memory, about 2300 kbytes.  Decompression speed is also halved,
-so you should use this option only where necessary.  The relevant
-flag is -s.
-
-In general, try and use the largest block size memory
-constraints allow, since that maximises the compression achieved.
-Compression and decompression speed are virtually unaffected by
-block size.
-
-Another significant point applies to files which fit in a
-single block -- that means most files you'd encounter using a
-large block size.  The amount of real memory touched is
-proportional to the size of the file, since the file is smaller
-than a block.  For example, compressing a file 20,000 bytes long
-with the flag -9 will cause the
-compressor to allocate around 7600k of memory, but only touch
-400k + 20000 * 8 = 560 kbytes of it.  Similarly, the decompressor
-will allocate 3700k but only touch 100k + 20000 * 4 = 180
-kbytes.
-
-Here is a table which summarises the maximum memory usage
-for different block sizes.  Also recorded is the total compressed
-size for 14 files of the Calgary Text Compression Corpus
-totalling 3,141,622 bytes.  This column gives some feel for how
-compression varies with block size.  These figures tend to
-understate the advantage of larger block sizes for larger files,
-since the Corpus is dominated by smaller files.
-
-
-        Compress   Decompress   Decompress   Corpus
-Flag     usage      usage       -s usage     Size
-
- -1      1200k       500k         350k      914704
- -2      2000k       900k         600k      877703
- -3      2800k      1300k         850k      860338
- -4      3600k      1700k        1100k      846899
- -5      4400k      2100k        1350k      845160
- -6      5200k      2500k        1600k      838626
- -7      6100k      2900k        1850k      834096
- -8      6800k      3300k        2100k      828642
- -9      7600k      3700k        2350k      828642
-
-
-
-
-
-
-RECOVERING DATA FROM DAMAGED FILES
-
-bzip2 compresses files in
-blocks, usually 900kbytes long.  Each block is handled
-independently.  If a media or transmission error causes a
-multi-block .bz2 file to become
-damaged, it may be possible to recover data from the undamaged
-blocks in the file.
-
-The compressed representation of each block is delimited by
-a 48-bit pattern, which makes it possible to find the block
-boundaries with reasonable certainty.  Each block also carries
-its own 32-bit CRC, so damaged blocks can be distinguished from
-undamaged ones.
-
-bzip2recover is a simple
-program whose purpose is to search for blocks in
-.bz2 files, and write each block
-out into its own .bz2 file.  You
-can then use bzip2 -t to test
-the integrity of the resulting files, and decompress those which
-are undamaged.
-
-bzip2recover takes a
-single argument, the name of the damaged file, and writes a
-number of files rec0001file.bz2,
-rec0002file.bz2, etc, containing
-the extracted blocks.  The output filenames are designed so that
-the use of wildcards in subsequent processing -- for example,
-bzip2 -dc rec*file.bz2 >
-recovered_data -- lists the files in the correct
-order.
-
-bzip2recover should be of
-most use dealing with large .bz2
-files, as these will contain many blocks.  It is clearly futile
-to use it on damaged single-block files, since a damaged block
-cannot be recovered.  If you wish to minimise any potential data
-loss through media or transmission errors, you might consider
-compressing with a smaller block size.
-
-
-
-
-
-PERFORMANCE NOTES
-
-The sorting phase of compression gathers together similar
-strings in the file.  Because of this, files containing very long
-runs of repeated symbols, like "aabaabaabaab ..."  (repeated
-several hundred times) may compress more slowly than normal.
-Versions 0.9.5 and above fare much better than previous versions
-in this respect.  The ratio between worst-case and average-case
-compression time is in the region of 10:1.  For previous
-versions, this figure was more like 100:1.  You can use the
--vvvv option to monitor progress
-in great detail, if you want.
-
-Decompression speed is unaffected by these
-phenomena.
-
-bzip2 usually allocates
-several megabytes of memory to operate in, and then charges all
-over it in a fairly random fashion.  This means that performance,
-both for compressing and decompressing, is largely determined by
-the speed at which your machine can service cache misses.
-Because of this, small changes to the code to reduce the miss
-rate have been observed to give disproportionately large
-performance improvements.  I imagine
-bzip2 will perform best on
-machines with very large caches.
-
-
-
-
-
-
-CAVEATS
-
-I/O error messages are not as helpful as they could be.
-bzip2 tries hard to detect I/O
-errors and exit cleanly, but the details of what the problem is
-sometimes seem rather misleading.
-
-This manual page pertains to version &bz-version; of
-bzip2.  Compressed data created by
-this version is entirely forwards and backwards compatible with the
-previous public releases, versions 0.1pl2, 0.9.0 and 0.9.5, 1.0.0,
-1.0.1, 1.0.2 and 1.0.3, but with the following exception: 0.9.0 and
-above can correctly decompress multiple concatenated compressed files.
-0.1pl2 cannot do this; it will stop after decompressing just the first
-file in the stream.
-
-bzip2recover versions
-prior to 1.0.2 used 32-bit integers to represent bit positions in
-compressed files, so it could not handle compressed files more
-than 512 megabytes long.  Versions 1.0.2 and above use 64-bit ints
-on some platforms which support them (GNU supported targets, and
-Windows). To establish whether or not
-bzip2recover was built with such
-a limitation, run it without arguments. In any event you can
-build yourself an unlimited version if you can recompile it with
-MaybeUInt64 set to be an
-unsigned 64-bit integer.
-
-
-
-
-
-
-AUTHOR
-
-Julian Seward,
-&bz-email;
-
-The ideas embodied in
-bzip2 are due to (at least) the
-following people: Michael Burrows and David Wheeler (for the
-block sorting transformation), David Wheeler (again, for the
-Huffman coder), Peter Fenwick (for the structured coding model in
-the original bzip, and many
-refinements), and Alistair Moffat, Radford Neal and Ian Witten
-(for the arithmetic coder in the original
-bzip).  I am much indebted for
-their help, support and advice.  See the manual in the source
-distribution for pointers to sources of documentation.  Christian
-von Roques encouraged me to look for faster sorting algorithms,
-so as to speed up compression.  Bela Lubkin encouraged me to
-improve the worst-case compression performance.
-Donna Robinson XMLised the documentation.
-Many people sent
-patches, helped with portability problems, lent machines, gave
-advice and were generally helpful.
-
-
-
-
-
-
-
-
-
-Programming with <computeroutput>libbzip2</computeroutput>
-
-
-This chapter describes the programming interface to
-libbzip2.
-
-For general background information, particularly about
-memory use and performance aspects, you'd be well advised to read
- as well.
-
-
-
-Top-level structure
-
-libbzip2 is a flexible
-library for compressing and decompressing data in the
-bzip2 data format.  Although
-packaged as a single entity, it helps to regard the library as
-three separate parts: the low level interface, and the high level
-interface, and some utility functions.
-
-The structure of
-libbzip2's interfaces is similar
-to that of Jean-loup Gailly's and Mark Adler's excellent
-zlib library.
-
-All externally visible symbols have names beginning
-BZ2_.  This is new in version
-1.0.  The intention is to minimise pollution of the namespaces of
-library clients.
-
-To use any part of the library, you need to
-#include <bzlib.h>
-into your sources.
-
-
-
-
-Low-level summary
-
-This interface provides services for compressing and
-decompressing data in memory.  There's no provision for dealing
-with files, streams or any other I/O mechanisms, just straight
-memory-to-memory work.  In fact, this part of the library can be
-compiled without inclusion of
-stdio.h, which may be helpful
-for embedded applications.
-
-The low-level part of the library has no global variables
-and is therefore thread-safe.
-
-Six routines make up the low level interface:
-BZ2_bzCompressInit,
-BZ2_bzCompress, and
-BZ2_bzCompressEnd for
-compression, and a corresponding trio
-BZ2_bzDecompressInit,
-BZ2_bzDecompress and
-BZ2_bzDecompressEnd for
-decompression.  The *Init
-functions allocate memory for compression/decompression and do
-other initialisations, whilst the
-*End functions close down
-operations and release memory.
-
-The real work is done by
-BZ2_bzCompress and
-BZ2_bzDecompress.  These
-compress and decompress data from a user-supplied input buffer to
-a user-supplied output buffer.  These buffers can be any size;
-arbitrary quantities of data are handled by making repeated calls
-to these functions.  This is a flexible mechanism allowing a
-consumer-pull style of activity, or producer-push, or a mixture
-of both.
-
-
-
-
-
-High-level summary
-
-This interface provides some handy wrappers around the
-low-level interface to facilitate reading and writing
-bzip2 format files
-(.bz2 files).  The routines
-provide hooks to facilitate reading files in which the
-bzip2 data stream is embedded
-within some larger-scale file structure, or where there are
-multiple bzip2 data streams
-concatenated end-to-end.
-
-For reading files,
-BZ2_bzReadOpen,
-BZ2_bzRead,
-BZ2_bzReadClose and
-BZ2_bzReadGetUnused are
-supplied.  For writing files,
-BZ2_bzWriteOpen,
-BZ2_bzWrite and
-BZ2_bzWriteFinish are
-available.
-
-As with the low-level library, no global variables are used
-so the library is per se thread-safe.  However, if I/O errors
-occur whilst reading or writing the underlying compressed files,
-you may have to consult errno to
-determine the cause of the error.  In that case, you'd need a C
-library which correctly supports
-errno in a multithreaded
-environment.
-
-To make the library a little simpler and more portable,
-BZ2_bzReadOpen and
-BZ2_bzWriteOpen require you to
-pass them file handles (FILE*s)
-which have previously been opened for reading or writing
-respectively.  That avoids portability problems associated with
-file operations and file attributes, whilst not being much of an
-imposition on the programmer.
-
-
-
-
-
-Utility functions summary
-
-For very simple needs,
-BZ2_bzBuffToBuffCompress and
-BZ2_bzBuffToBuffDecompress are
-provided.  These compress data in memory from one buffer to
-another buffer in a single function call.  You should assess
-whether these functions fulfill your memory-to-memory
-compression/decompression requirements before investing effort in
-understanding the more general but more complex low-level
-interface.
-
-Yoshioka Tsuneo
-(tsuneo@rr.iij4u.or.jp) has
-contributed some functions to give better
-zlib compatibility.  These
-functions are BZ2_bzopen,
-BZ2_bzread,
-BZ2_bzwrite,
-BZ2_bzflush,
-BZ2_bzclose,
-BZ2_bzerror and
-BZ2_bzlibVersion.  You may find
-these functions more convenient for simple file reading and
-writing, than those in the high-level interface.  These functions
-are not (yet) officially part of the library, and are minimally
-documented here.  If they break, you get to keep all the pieces.
-I hope to document them properly when time permits.
-
-Yoshioka also contributed modifications to allow the
-library to be built as a Windows DLL.
-
-
-
-
-
-
-
-Error handling
-
-The library is designed to recover cleanly in all
-situations, including the worst-case situation of decompressing
-random data.  I'm not 100% sure that it can always do this, so
-you might want to add a signal handler to catch segmentation
-violations during decompression if you are feeling especially
-paranoid.  I would be interested in hearing more about the
-robustness of the library to corrupted compressed data.
-
-Version 1.0.3 more robust in this respect than any
-previous version.  Investigations with Valgrind (a tool for detecting
-problems with memory management) indicate
-that, at least for the few files I tested, all single-bit errors
-in the decompressed data are caught properly, with no
-segmentation faults, no uses of uninitialised data, no out of
-range reads or writes, and no infinite looping in the decompressor.
-So it's certainly pretty robust, although
-I wouldn't claim it to be totally bombproof.
-
-The file bzlib.h contains
-all definitions needed to use the library.  In particular, you
-should definitely not include
-bzlib_private.h.
-
-In bzlib.h, the various
-return values are defined.  The following list is not intended as
-an exhaustive description of the circumstances in which a given
-value may be returned -- those descriptions are given later.
-Rather, it is intended to convey the rough meaning of each return
-value.  The first five actions are normal and not intended to
-denote an error situation.
-
-
-
- 
-  BZ_OK
-  The requested action was completed
-   successfully.
- 
-
- 
-  BZ_RUN_OK, BZ_FLUSH_OK,
-    BZ_FINISH_OK
-  In
-   BZ2_bzCompress, the requested
-   flush/finish/nothing-special action was completed
-   successfully.
- 
-
- 
-  BZ_STREAM_END
-  Compression of data was completed, or the
-   logical stream end was detected during
-   decompression.
- 
-
-
-
-The following return values indicate an error of some
-kind.
-
-
-
- 
-  BZ_CONFIG_ERROR
-  Indicates that the library has been improperly
-   compiled on your platform -- a major configuration error.
-   Specifically, it means that
-   sizeof(char),
-   sizeof(short) and
-   sizeof(int) are not 1, 2 and
-   4 respectively, as they should be.  Note that the library
-   should still work properly on 64-bit platforms which follow
-   the LP64 programming model -- that is, where
-   sizeof(long) and
-   sizeof(void*) are 8.  Under
-   LP64, sizeof(int) is still 4,
-   so libbzip2, which doesn't
-   use the long type, is
-   OK.
- 
-
- 
-  BZ_SEQUENCE_ERROR
-  When using the library, it is important to call
-   the functions in the correct sequence and with data structures
-   (buffers etc) in the correct states.
-   libbzip2 checks as much as it
-   can to ensure this is happening, and returns
-   BZ_SEQUENCE_ERROR if not.
-   Code which complies precisely with the function semantics, as
-   detailed below, should never receive this value; such an event
-   denotes buggy code which you should
-   investigate.
- 
-
- 
-  BZ_PARAM_ERROR
-  Returned when a parameter to a function call is
-   out of range or otherwise manifestly incorrect.  As with
-   BZ_SEQUENCE_ERROR, this
-   denotes a bug in the client code.  The distinction between
-   BZ_PARAM_ERROR and
-   BZ_SEQUENCE_ERROR is a bit
-   hazy, but still worth making.
- 
-
- 
-  BZ_MEM_ERROR
-  Returned when a request to allocate memory
-   failed.  Note that the quantity of memory needed to decompress
-   a stream cannot be determined until the stream's header has
-   been read.  So
-   BZ2_bzDecompress and
-   BZ2_bzRead may return
-   BZ_MEM_ERROR even though some
-   of the compressed data has been read.  The same is not true
-   for compression; once
-   BZ2_bzCompressInit or
-   BZ2_bzWriteOpen have
-   successfully completed,
-   BZ_MEM_ERROR cannot
-   occur.
- 
-
- 
-  BZ_DATA_ERROR
-  Returned when a data integrity error is
-   detected during decompression.  Most importantly, this means
-   when stored and computed CRCs for the data do not match.  This
-   value is also returned upon detection of any other anomaly in
-   the compressed data.
- 
-
- 
-  BZ_DATA_ERROR_MAGIC
-  As a special case of
-   BZ_DATA_ERROR, it is
-   sometimes useful to know when the compressed stream does not
-   start with the correct magic bytes ('B' 'Z'
-   'h').
- 
-
- 
-  BZ_IO_ERROR
-  Returned by
-   BZ2_bzRead and
-   BZ2_bzWrite when there is an
-   error reading or writing in the compressed file, and by
-   BZ2_bzReadOpen and
-   BZ2_bzWriteOpen for attempts
-   to use a file for which the error indicator (viz,
-   ferror(f)) is set.  On
-   receipt of BZ_IO_ERROR, the
-   caller should consult errno
-   and/or perror to acquire
-   operating-system specific information about the
-   problem.
- 
-
- 
-  BZ_UNEXPECTED_EOF
-  Returned by
-   BZ2_bzRead when the
-   compressed file finishes before the logical end of stream is
-   detected.
- 
-
- 
-  BZ_OUTBUFF_FULL
-  Returned by
-   BZ2_bzBuffToBuffCompress and
-   BZ2_bzBuffToBuffDecompress to
-   indicate that the output data will not fit into the output
-   buffer provided.
- 
-
-
-
-
-
-
-
-
-Low-level interface
-
-
-
-BZ2_bzCompressInit
-
-
-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;
-
-int BZ2_bzCompressInit ( bz_stream *strm,
-                         int blockSize100k,
-                         int verbosity,
-                         int workFactor );
-
-
-Prepares for compression.  The
-bz_stream structure holds all
-data pertaining to the compression activity.  A
-bz_stream structure should be
-allocated and initialised prior to the call.  The fields of
-bz_stream comprise the entirety
-of the user-visible data.  state
-is a pointer to the private data structures required for
-compression.
-
-Custom memory allocators are supported, via fields
-bzalloc,
-bzfree, and
-opaque.  The value
-opaque is passed to as the first
-argument to all calls to bzalloc
-and bzfree, but is otherwise
-ignored by the library.  The call bzalloc (
-opaque, n, m ) is expected to return a pointer
-p to n *
-m bytes of memory, and bzfree (
-opaque, p ) should free that memory.
-
-If you don't want to use a custom memory allocator, set
-bzalloc,
-bzfree and
-opaque to
-NULL, and the library will then
-use the standard malloc /
-free routines.
-
-Before calling
-BZ2_bzCompressInit, fields
-bzalloc,
-bzfree and
-opaque should be filled
-appropriately, as just described.  Upon return, the internal
-state will have been allocated and initialised, and
-total_in_lo32,
-total_in_hi32,
-total_out_lo32 and
-total_out_hi32 will have been
-set to zero.  These four fields are used by the library to inform
-the caller of the total amount of data passed into and out of the
-library, respectively.  You should not try to change them.  As of
-version 1.0, 64-bit counts are maintained, even on 32-bit
-platforms, using the _hi32
-fields to store the upper 32 bits of the count.  So, for example,
-the total amount of data in is (total_in_hi32
-<< 32) + total_in_lo32.
-
-Parameter blockSize100k
-specifies the block size to be used for compression.  It should
-be a value between 1 and 9 inclusive, and the actual block size
-used is 100000 x this figure.  9 gives the best compression but
-takes most memory.
-
-Parameter verbosity should
-be set to a number between 0 and 4 inclusive.  0 is silent, and
-greater numbers give increasingly verbose monitoring/debugging
-output.  If the library has been compiled with
--DBZ_NO_STDIO, no such output
-will appear for any verbosity setting.
-
-Parameter workFactor
-controls how the compression phase behaves when presented with
-worst case, highly repetitive, input data.  If compression runs
-into difficulties caused by repetitive data, the library switches
-from the standard sorting algorithm to a fallback algorithm.  The
-fallback is slower than the standard algorithm by perhaps a
-factor of three, but always behaves reasonably, no matter how bad
-the input.
-
-Lower values of workFactor
-reduce the amount of effort the standard algorithm will expend
-before resorting to the fallback.  You should set this parameter
-carefully; too low, and many inputs will be handled by the
-fallback algorithm and so compress rather slowly, too high, and
-your average-to-worst case compression times can become very
-large.  The default value of 30 gives reasonable behaviour over a
-wide range of circumstances.
-
-Allowable values range from 0 to 250 inclusive.  0 is a
-special case, equivalent to using the default value of 30.
-
-Note that the compressed output generated is the same
-regardless of whether or not the fallback algorithm is
-used.
-
-Be aware also that this parameter may disappear entirely in
-future versions of the library.  In principle it should be
-possible to devise a good way to automatically choose which
-algorithm to use.  Such a mechanism would render the parameter
-obsolete.
-
-Possible return values:
-
-
-BZ_CONFIG_ERROR
-  if the library has been mis-compiled
-BZ_PARAM_ERROR
-  if strm is NULL
-  or blockSize < 1 or blockSize > 9
-  or verbosity < 0 or verbosity > 4
-  or workFactor < 0 or workFactor > 250
-BZ_MEM_ERROR
-  if not enough memory is available
-BZ_OK
-  otherwise
-
-
-Allowable next actions:
-
-
-BZ2_bzCompress
-  if BZ_OK is returned
-  no specific action needed in case of error
-
-
-
-
-
-
-BZ2_bzCompress
-
-
-int BZ2_bzCompress ( bz_stream *strm, int action );
-
-
-Provides more input and/or output buffer space for the
-library.  The caller maintains input and output buffers, and
-calls BZ2_bzCompress to transfer
-data between them.
-
-Before each call to
-BZ2_bzCompress,
-next_in should point at the data
-to be compressed, and avail_in
-should indicate how many bytes the library may read.
-BZ2_bzCompress updates
-next_in,
-avail_in and
-total_in to reflect the number
-of bytes it has read.
-
-Similarly, next_out should
-point to a buffer in which the compressed data is to be placed,
-with avail_out indicating how
-much output space is available.
-BZ2_bzCompress updates
-next_out,
-avail_out and
-total_out to reflect the number
-of bytes output.
-
-You may provide and remove as little or as much data as you
-like on each call of
-BZ2_bzCompress.  In the limit,
-it is acceptable to supply and remove data one byte at a time,
-although this would be terribly inefficient.  You should always
-ensure that at least one byte of output space is available at
-each call.
-
-A second purpose of
-BZ2_bzCompress is to request a
-change of mode of the compressed stream.
-
-Conceptually, a compressed stream can be in one of four
-states: IDLE, RUNNING, FLUSHING and FINISHING.  Before
-initialisation
-(BZ2_bzCompressInit) and after
-termination (BZ2_bzCompressEnd),
-a stream is regarded as IDLE.
-
-Upon initialisation
-(BZ2_bzCompressInit), the stream
-is placed in the RUNNING state.  Subsequent calls to
-BZ2_bzCompress should pass
-BZ_RUN as the requested action;
-other actions are illegal and will result in
-BZ_SEQUENCE_ERROR.
-
-At some point, the calling program will have provided all
-the input data it wants to.  It will then want to finish up -- in
-effect, asking the library to process any data it might have
-buffered internally.  In this state,
-BZ2_bzCompress will no longer
-attempt to read data from
-next_in, but it will want to
-write data to next_out.  Because
-the output buffer supplied by the user can be arbitrarily small,
-the finishing-up operation cannot necessarily be done with a
-single call of
-BZ2_bzCompress.
-
-Instead, the calling program passes
-BZ_FINISH as an action to
-BZ2_bzCompress.  This changes
-the stream's state to FINISHING.  Any remaining input (ie,
-next_in[0 .. avail_in-1]) is
-compressed and transferred to the output buffer.  To do this,
-BZ2_bzCompress must be called
-repeatedly until all the output has been consumed.  At that
-point, BZ2_bzCompress returns
-BZ_STREAM_END, and the stream's
-state is set back to IDLE.
-BZ2_bzCompressEnd should then be
-called.
-
-Just to make sure the calling program does not cheat, the
-library makes a note of avail_in
-at the time of the first call to
-BZ2_bzCompress which has
-BZ_FINISH as an action (ie, at
-the time the program has announced its intention to not supply
-any more input).  By comparing this value with that of
-avail_in over subsequent calls
-to BZ2_bzCompress, the library
-can detect any attempts to slip in more data to compress.  Any
-calls for which this is detected will return
-BZ_SEQUENCE_ERROR.  This
-indicates a programming mistake which should be corrected.
-
-Instead of asking to finish, the calling program may ask
-BZ2_bzCompress to take all the
-remaining input, compress it and terminate the current
-(Burrows-Wheeler) compression block.  This could be useful for
-error control purposes.  The mechanism is analogous to that for
-finishing: call BZ2_bzCompress
-with an action of BZ_FLUSH,
-remove output data, and persist with the
-BZ_FLUSH action until the value
-BZ_RUN is returned.  As with
-finishing, BZ2_bzCompress
-detects any attempt to provide more input data once the flush has
-begun.
-
-Once the flush is complete, the stream returns to the
-normal RUNNING state.
-
-This all sounds pretty complex, but isn't really.  Here's a
-table which shows which actions are allowable in each state, what
-action will be taken, what the next state is, and what the
-non-error return values are.  Note that you can't explicitly ask
-what state the stream is in, but nor do you need to -- it can be
-inferred from the values returned by
-BZ2_bzCompress.
-
-
-IDLE/any
-  Illegal.  IDLE state only exists after BZ2_bzCompressEnd or
-  before BZ2_bzCompressInit.
-  Return value = BZ_SEQUENCE_ERROR
-
-RUNNING/BZ_RUN
-  Compress from next_in to next_out as much as possible.
-  Next state = RUNNING
-  Return value = BZ_RUN_OK
-
-RUNNING/BZ_FLUSH
-  Remember current value of next_in. Compress from next_in
-  to next_out as much as possible, but do not accept any more input.
-  Next state = FLUSHING
-  Return value = BZ_FLUSH_OK
-
-RUNNING/BZ_FINISH
-  Remember current value of next_in. Compress from next_in
-  to next_out as much as possible, but do not accept any more input.
-  Next state = FINISHING
-  Return value = BZ_FINISH_OK
-
-FLUSHING/BZ_FLUSH
-  Compress from next_in to next_out as much as possible,
-  but do not accept any more input.
-  If all the existing input has been used up and all compressed
-  output has been removed
-    Next state = RUNNING; Return value = BZ_RUN_OK
-  else
-    Next state = FLUSHING; Return value = BZ_FLUSH_OK
-
-FLUSHING/other
-  Illegal.
-  Return value = BZ_SEQUENCE_ERROR
-
-FINISHING/BZ_FINISH
-  Compress from next_in to next_out as much as possible,
-  but to not accept any more input.
-  If all the existing input has been used up and all compressed
-  output has been removed
-    Next state = IDLE; Return value = BZ_STREAM_END
-  else
-    Next state = FINISHING; Return value = BZ_FINISH_OK
-
-FINISHING/other
-  Illegal.
-  Return value = BZ_SEQUENCE_ERROR
-
-
-
-That still looks complicated?  Well, fair enough.  The
-usual sequence of calls for compressing a load of data is:
-
-
-
- Get started with
-  BZ2_bzCompressInit.
-
- Shovel data in and shlurp out its compressed form
-  using zero or more calls of
-  BZ2_bzCompress with action =
-  BZ_RUN.
-
- Finish up. Repeatedly call
-  BZ2_bzCompress with action =
-  BZ_FINISH, copying out the
-  compressed output, until
-  BZ_STREAM_END is
-  returned. Close up and go home.  Call
-  BZ2_bzCompressEnd.
-
-
-
-If the data you want to compress fits into your input
-buffer all at once, you can skip the calls of
-BZ2_bzCompress ( ..., BZ_RUN )
-and just do the BZ2_bzCompress ( ..., BZ_FINISH
-) calls.
-
-All required memory is allocated by
-BZ2_bzCompressInit.  The
-compression library can accept any data at all (obviously).  So
-you shouldn't get any error return values from the
-BZ2_bzCompress calls.  If you
-do, they will be
-BZ_SEQUENCE_ERROR, and indicate
-a bug in your programming.
-
-Trivial other possible return values:
-
-
-BZ_PARAM_ERROR
-  if strm is NULL, or strm->s is NULL
-
-
-
-
-
-
-BZ2_bzCompressEnd
-
-
-int BZ2_bzCompressEnd ( bz_stream *strm );
-
-
-Releases all memory associated with a compression
-stream.
-
-Possible return values:
-
-
-BZ_PARAM_ERROR  if strm is NULL or strm->s is NULL
-BZ_OK           otherwise
-
-
-
-
-
-
-BZ2_bzDecompressInit
-
-
-int BZ2_bzDecompressInit ( bz_stream *strm, int verbosity, int small );
-
-
-Prepares for decompression.  As with
-BZ2_bzCompressInit, a
-bz_stream record should be
-allocated and initialised before the call.  Fields
-bzalloc,
-bzfree and
-opaque should be set if a custom
-memory allocator is required, or made
-NULL for the normal
-malloc /
-free routines.  Upon return, the
-internal state will have been initialised, and
-total_in and
-total_out will be zero.
-
-For the meaning of parameter
-verbosity, see
-BZ2_bzCompressInit.
-
-If small is nonzero, the
-library will use an alternative decompression algorithm which
-uses less memory but at the cost of decompressing more slowly
-(roughly speaking, half the speed, but the maximum memory
-requirement drops to around 2300k).  See 
-for more information on memory management.
-
-Note that the amount of memory needed to decompress a
-stream cannot be determined until the stream's header has been
-read, so even if
-BZ2_bzDecompressInit succeeds, a
-subsequent BZ2_bzDecompress
-could fail with
-BZ_MEM_ERROR.
-
-Possible return values:
-
-
-BZ_CONFIG_ERROR
-  if the library has been mis-compiled
-BZ_PARAM_ERROR
-  if ( small != 0 && small != 1 )
-  or (verbosity <; 0 || verbosity > 4)
-BZ_MEM_ERROR
-  if insufficient memory is available
-
-
-Allowable next actions:
-
-
-BZ2_bzDecompress
-  if BZ_OK was returned
-  no specific action required in case of error
-
-
-
-
-
-
-BZ2_bzDecompress
-
-
-int BZ2_bzDecompress ( bz_stream *strm );
-
-
-Provides more input and/out output buffer space for the
-library.  The caller maintains input and output buffers, and uses
-BZ2_bzDecompress to transfer
-data between them.
-
-Before each call to
-BZ2_bzDecompress,
-next_in should point at the
-compressed data, and avail_in
-should indicate how many bytes the library may read.
-BZ2_bzDecompress updates
-next_in,
-avail_in and
-total_in to reflect the number
-of bytes it has read.
-
-Similarly, next_out should
-point to a buffer in which the uncompressed output is to be
-placed, with avail_out
-indicating how much output space is available.
-BZ2_bzCompress updates
-next_out,
-avail_out and
-total_out to reflect the number
-of bytes output.
-
-You may provide and remove as little or as much data as you
-like on each call of
-BZ2_bzDecompress.  In the limit,
-it is acceptable to supply and remove data one byte at a time,
-although this would be terribly inefficient.  You should always
-ensure that at least one byte of output space is available at
-each call.
-
-Use of BZ2_bzDecompress is
-simpler than
-BZ2_bzCompress.
-
-You should provide input and remove output as described
-above, and repeatedly call
-BZ2_bzDecompress until
-BZ_STREAM_END is returned.
-Appearance of BZ_STREAM_END
-denotes that BZ2_bzDecompress
-has detected the logical end of the compressed stream.
-BZ2_bzDecompress will not
-produce BZ_STREAM_END until all
-output data has been placed into the output buffer, so once
-BZ_STREAM_END appears, you are
-guaranteed to have available all the decompressed output, and
-BZ2_bzDecompressEnd can safely
-be called.
-
-If case of an error return value, you should call
-BZ2_bzDecompressEnd to clean up
-and release memory.
-
-Possible return values:
-
-
-BZ_PARAM_ERROR
-  if strm is NULL or strm->s is NULL
-  or strm->avail_out < 1
-BZ_DATA_ERROR
-  if a data integrity error is detected in the compressed stream
-BZ_DATA_ERROR_MAGIC
-  if the compressed stream doesn't begin with the right magic bytes
-BZ_MEM_ERROR
-  if there wasn't enough memory available
-BZ_STREAM_END
-  if the logical end of the data stream was detected and all
-  output in has been consumed, eg s-->avail_out > 0
-BZ_SEQUENCE_ERROR
-  if called after an earlier call already returned BZ_STREAM_END
-BZ_OK
-  otherwise
-
-
-Allowable next actions:
-
-
-BZ2_bzDecompress
-  if BZ_OK was returned
-BZ2_bzDecompressEnd
-  otherwise
-
-
-
-
-
-
-BZ2_bzDecompressEnd
-
-
-int BZ2_bzDecompressEnd ( bz_stream *strm );
-
-
-Releases all memory associated with a decompression
-stream.
-
-Possible return values:
-
-
-BZ_PARAM_ERROR
-  if strm is NULL or strm->s is NULL
-BZ_OK
-  otherwise
-
-
-Allowable next actions:
-
-
-  None.
-
-
-
-
-
-
-
-
-High-level interface
-
-This interface provides functions for reading and writing
-bzip2 format files.  First, some
-general points.
-
-
-
- All of the functions take an
-  int* first argument,
-  bzerror.  After each call,
-  bzerror should be consulted
-  first to determine the outcome of the call.  If
-  bzerror is
-  BZ_OK, the call completed
-  successfully, and only then should the return value of the
-  function (if any) be consulted.  If
-  bzerror is
-  BZ_IO_ERROR, there was an
-  error reading/writing the underlying compressed file, and you
-  should then consult errno /
-  perror to determine the cause
-  of the difficulty.  bzerror
-  may also be set to various other values; precise details are
-  given on a per-function basis below.
-
- If bzerror indicates
-  an error (ie, anything except
-  BZ_OK and
-  BZ_STREAM_END), you should
-  immediately call
-  BZ2_bzReadClose (or
-  BZ2_bzWriteClose, depending on
-  whether you are attempting to read or to write) to free up all
-  resources associated with the stream.  Once an error has been
-  indicated, behaviour of all calls except
-  BZ2_bzReadClose
-  (BZ2_bzWriteClose) is
-  undefined.  The implication is that (1)
-  bzerror should be checked
-  after each call, and (2) if
-  bzerror indicates an error,
-  BZ2_bzReadClose
-  (BZ2_bzWriteClose) should then
-  be called to clean up.
-
- The FILE* arguments
-  passed to BZ2_bzReadOpen /
-  BZ2_bzWriteOpen should be set
-  to binary mode.  Most Unix systems will do this by default, but
-  other platforms, including Windows and Mac, will not.  If you
-  omit this, you may encounter problems when moving code to new
-  platforms.
-
- Memory allocation requests are handled by
-  malloc /
-  free.  At present there is no
-  facility for user-defined memory allocators in the file I/O
-  functions (could easily be added, though).
-
-
-
-
-
-
-BZ2_bzReadOpen
-
-
-typedef void BZFILE;
-
-BZFILE *BZ2_bzReadOpen( int *bzerror, FILE *f,
-                        int verbosity, int small,
-                        void *unused, int nUnused );
-
-
-Prepare to read compressed data from file handle
-f.
-f should refer to a file which
-has been opened for reading, and for which the error indicator
-(ferror(f))is not set.  If
-small is 1, the library will try
-to decompress using less memory, at the expense of speed.
-
-For reasons explained below,
-BZ2_bzRead will decompress the
-nUnused bytes starting at
-unused, before starting to read
-from the file f.  At most
-BZ_MAX_UNUSED bytes may be
-supplied like this.  If this facility is not required, you should
-pass NULL and
-0 for
-unused and
-nUnused respectively.
-
-For the meaning of parameters
-small and
-verbosity, see
-BZ2_bzDecompressInit.
-
-The amount of memory needed to decompress a file cannot be
-determined until the file's header has been read.  So it is
-possible that BZ2_bzReadOpen
-returns BZ_OK but a subsequent
-call of BZ2_bzRead will return
-BZ_MEM_ERROR.
-
-Possible assignments to
-bzerror:
-
-
-BZ_CONFIG_ERROR
-  if the library has been mis-compiled
-BZ_PARAM_ERROR
-  if f is NULL
-  or small is neither 0 nor 1
-  or ( unused == NULL && nUnused != 0 )
-  or ( unused != NULL && !(0 <= nUnused <= BZ_MAX_UNUSED) )
-BZ_IO_ERROR
-  if ferror(f) is nonzero
-BZ_MEM_ERROR
-  if insufficient memory is available
-BZ_OK
-  otherwise.
-
-
-Possible return values:
-
-
-Pointer to an abstract BZFILE
-  if bzerror is BZ_OK
-NULL
-  otherwise
-
-
-Allowable next actions:
-
-
-BZ2_bzRead
-  if bzerror is BZ_OK
-BZ2_bzClose
-  otherwise
-
-
-
-
-
-
-BZ2_bzRead
-
-
-int BZ2_bzRead ( int *bzerror, BZFILE *b, void *buf, int len );
-
-
-Reads up to len
-(uncompressed) bytes from the compressed file
-b into the buffer
-buf.  If the read was
-successful, bzerror is set to
-BZ_OK and the number of bytes
-read is returned.  If the logical end-of-stream was detected,
-bzerror will be set to
-BZ_STREAM_END, and the number of
-bytes read is returned.  All other
-bzerror values denote an
-error.
-
-BZ2_bzRead will supply
-len bytes, unless the logical
-stream end is detected or an error occurs.  Because of this, it
-is possible to detect the stream end by observing when the number
-of bytes returned is less than the number requested.
-Nevertheless, this is regarded as inadvisable; you should instead
-check bzerror after every call
-and watch out for
-BZ_STREAM_END.
-
-Internally, BZ2_bzRead
-copies data from the compressed file in chunks of size
-BZ_MAX_UNUSED bytes before
-decompressing it.  If the file contains more bytes than strictly
-needed to reach the logical end-of-stream,
-BZ2_bzRead will almost certainly
-read some of the trailing data before signalling
-BZ_SEQUENCE_END.  To collect the
-read but unused data once
-BZ_SEQUENCE_END has appeared,
-call BZ2_bzReadGetUnused
-immediately before
-BZ2_bzReadClose.
-
-Possible assignments to
-bzerror:
-
-
-BZ_PARAM_ERROR
-  if b is NULL or buf is NULL or len < 0
-BZ_SEQUENCE_ERROR
-  if b was opened with BZ2_bzWriteOpen
-BZ_IO_ERROR
-  if there is an error reading from the compressed file
-BZ_UNEXPECTED_EOF
-  if the compressed file ended before
-  the logical end-of-stream was detected
-BZ_DATA_ERROR
-  if a data integrity error was detected in the compressed stream
-BZ_DATA_ERROR_MAGIC
-  if the stream does not begin with the requisite header bytes
-  (ie, is not a bzip2 data file).  This is really
-  a special case of BZ_DATA_ERROR.
-BZ_MEM_ERROR
-  if insufficient memory was available
-BZ_STREAM_END
-  if the logical end of stream was detected.
-BZ_OK
-  otherwise.
-
-
-Possible return values:
-
-
-number of bytes read
-  if bzerror is BZ_OK or BZ_STREAM_END
-undefined
-  otherwise
-
-
-Allowable next actions:
-
-
-collect data from buf, then BZ2_bzRead or BZ2_bzReadClose
-  if bzerror is BZ_OK
-collect data from buf, then BZ2_bzReadClose or BZ2_bzReadGetUnused
-  if bzerror is BZ_SEQUENCE_END
-BZ2_bzReadClose
-  otherwise
-
-
-
-
-
-
-BZ2_bzReadGetUnused
-
-
-void BZ2_bzReadGetUnused( int* bzerror, BZFILE *b,
-                          void** unused, int* nUnused );
-
-
-Returns data which was read from the compressed file but
-was not needed to get to the logical end-of-stream.
-*unused is set to the address of
-the data, and *nUnused to the
-number of bytes.  *nUnused will
-be set to a value between 0 and
-BZ_MAX_UNUSED inclusive.
-
-This function may only be called once
-BZ2_bzRead has signalled
-BZ_STREAM_END but before
-BZ2_bzReadClose.
-
-Possible assignments to
-bzerror:
-
-
-BZ_PARAM_ERROR
-  if b is NULL
-  or unused is NULL or nUnused is NULL
-BZ_SEQUENCE_ERROR
-  if BZ_STREAM_END has not been signalled
-  or if b was opened with BZ2_bzWriteOpen
-BZ_OK
-  otherwise
-
-
-Allowable next actions:
-
-
-BZ2_bzReadClose
-
-
-
-
-
-
-BZ2_bzReadClose
-
-
-void BZ2_bzReadClose ( int *bzerror, BZFILE *b );
-
-
-Releases all memory pertaining to the compressed file
-b.
-BZ2_bzReadClose does not call
-fclose on the underlying file
-handle, so you should do that yourself if appropriate.
-BZ2_bzReadClose should be called
-to clean up after all error situations.
-
-Possible assignments to
-bzerror:
-
-
-BZ_SEQUENCE_ERROR
-  if b was opened with BZ2_bzOpenWrite
-BZ_OK
-  otherwise
-
-
-Allowable next actions:
-
-
-none
-
-
-
-
-
-
-BZ2_bzWriteOpen
-
-
-BZFILE *BZ2_bzWriteOpen( int *bzerror, FILE *f,
-                         int blockSize100k, int verbosity,
-                         int workFactor );
-
-
-Prepare to write compressed data to file handle
-f.
-f should refer to a file which
-has been opened for writing, and for which the error indicator
-(ferror(f))is not set.
-
-For the meaning of parameters
-blockSize100k,
-verbosity and
-workFactor, see
-BZ2_bzCompressInit.
-
-All required memory is allocated at this stage, so if the
-call completes successfully,
-BZ_MEM_ERROR cannot be signalled
-by a subsequent call to
-BZ2_bzWrite.
-
-Possible assignments to
-bzerror:
-
-
-BZ_CONFIG_ERROR
-  if the library has been mis-compiled
-BZ_PARAM_ERROR
-  if f is NULL
-  or blockSize100k < 1 or blockSize100k > 9
-BZ_IO_ERROR
-  if ferror(f) is nonzero
-BZ_MEM_ERROR
-  if insufficient memory is available
-BZ_OK
-  otherwise
-
-
-Possible return values:
-
-
-Pointer to an abstract BZFILE
-  if bzerror is BZ_OK
-NULL
-  otherwise
-
-
-Allowable next actions:
-
-
-BZ2_bzWrite
-  if bzerror is BZ_OK
-  (you could go directly to BZ2_bzWriteClose, but this would be pretty pointless)
-BZ2_bzWriteClose
-  otherwise
-
-
-
-
-
-
-BZ2_bzWrite
-
-
-void BZ2_bzWrite ( int *bzerror, BZFILE *b, void *buf, int len );
-
-
-Absorbs len bytes from the
-buffer buf, eventually to be
-compressed and written to the file.
-
-Possible assignments to
-bzerror:
-
-
-BZ_PARAM_ERROR
-  if b is NULL or buf is NULL or len < 0
-BZ_SEQUENCE_ERROR
-  if b was opened with BZ2_bzReadOpen
-BZ_IO_ERROR
-  if there is an error writing the compressed file.
-BZ_OK
-  otherwise
-
-
-
-
-
-
-BZ2_bzWriteClose
-
-
-void BZ2_bzWriteClose( int *bzerror, BZFILE* f,
-                       int abandon,
-                       unsigned int* nbytes_in,
-                       unsigned int* nbytes_out );
-
-void BZ2_bzWriteClose64( int *bzerror, BZFILE* f,
-                         int abandon,
-                         unsigned int* nbytes_in_lo32,
-                         unsigned int* nbytes_in_hi32,
-                         unsigned int* nbytes_out_lo32,
-                         unsigned int* nbytes_out_hi32 );
-
-
-Compresses and flushes to the compressed file all data so
-far supplied by BZ2_bzWrite.
-The logical end-of-stream markers are also written, so subsequent
-calls to BZ2_bzWrite are
-illegal.  All memory associated with the compressed file
-b is released.
-fflush is called on the
-compressed file, but it is not
-fclose'd.
-
-If BZ2_bzWriteClose is
-called to clean up after an error, the only action is to release
-the memory.  The library records the error codes issued by
-previous calls, so this situation will be detected automatically.
-There is no attempt to complete the compression operation, nor to
-fflush the compressed file.  You
-can force this behaviour to happen even in the case of no error,
-by passing a nonzero value to
-abandon.
-
-If nbytes_in is non-null,
-*nbytes_in will be set to be the
-total volume of uncompressed data handled.  Similarly,
-nbytes_out will be set to the
-total volume of compressed data written.  For compatibility with
-older versions of the library,
-BZ2_bzWriteClose only yields the
-lower 32 bits of these counts.  Use
-BZ2_bzWriteClose64 if you want
-the full 64 bit counts.  These two functions are otherwise
-absolutely identical.
-
-Possible assignments to
-bzerror:
-
-
-BZ_SEQUENCE_ERROR
-  if b was opened with BZ2_bzReadOpen
-BZ_IO_ERROR
-  if there is an error writing the compressed file
-BZ_OK
-  otherwise
-
-
-
-
-
-
-Handling embedded compressed data streams
-
-The high-level library facilitates use of
-bzip2 data streams which form
-some part of a surrounding, larger data stream.
-
-
-
- For writing, the library takes an open file handle,
-  writes compressed data to it,
-  fflushes it but does not
-  fclose it.  The calling
-  application can write its own data before and after the
-  compressed data stream, using that same file handle.
-
- Reading is more complex, and the facilities are not as
-  general as they could be since generality is hard to reconcile
-  with efficiency.  BZ2_bzRead
-  reads from the compressed file in blocks of size
-  BZ_MAX_UNUSED bytes, and in
-  doing so probably will overshoot the logical end of compressed
-  stream.  To recover this data once decompression has ended,
-  call BZ2_bzReadGetUnused after
-  the last call of BZ2_bzRead
-  (the one returning
-  BZ_STREAM_END) but before
-  calling
-  BZ2_bzReadClose.
-
-
-
-This mechanism makes it easy to decompress multiple
-bzip2 streams placed end-to-end.
-As the end of one stream, when
-BZ2_bzRead returns
-BZ_STREAM_END, call
-BZ2_bzReadGetUnused to collect
-the unused data (copy it into your own buffer somewhere).  That
-data forms the start of the next compressed stream.  To start
-uncompressing that next stream, call
-BZ2_bzReadOpen again, feeding in
-the unused data via the unused /
-nUnused parameters.  Keep doing
-this until BZ_STREAM_END return
-coincides with the physical end of file
-(feof(f)).  In this situation
-BZ2_bzReadGetUnused will of
-course return no data.
-
-This should give some feel for how the high-level interface
-can be used.  If you require extra flexibility, you'll have to
-bite the bullet and get to grips with the low-level
-interface.
-
-
-
-
-
-Standard file-reading/writing code
-
-Here's how you'd write data to a compressed file:
-
-
-FILE*   f;
-BZFILE* b;
-int     nBuf;
-char    buf[ /* whatever size you like */ ];
-int     bzerror;
-int     nWritten;
-
-f = fopen ( "myfile.bz2", "w" );
-if ( !f ) {
- /* handle error */
-}
-b = BZ2_bzWriteOpen( &bzerror, f, 9 );
-if (bzerror != BZ_OK) {
- BZ2_bzWriteClose ( b );
- /* handle error */
-}
-
-while ( /* condition */ ) {
- /* get data to write into buf, and set nBuf appropriately */
- nWritten = BZ2_bzWrite ( &bzerror, b, buf, nBuf );
- if (bzerror == BZ_IO_ERROR) {
-   BZ2_bzWriteClose ( &bzerror, b );
-   /* handle error */
- }
-}
-
-BZ2_bzWriteClose( &bzerror, b );
-if (bzerror == BZ_IO_ERROR) {
- /* handle error */
-}
-
-
-And to read from a compressed file:
-
-
-FILE*   f;
-BZFILE* b;
-int     nBuf;
-char    buf[ /* whatever size you like */ ];
-int     bzerror;
-int     nWritten;
-
-f = fopen ( "myfile.bz2", "r" );
-if ( !f ) {
-  /* handle error */
-}
-b = BZ2_bzReadOpen ( &bzerror, f, 0, NULL, 0 );
-if ( bzerror != BZ_OK ) {
-  BZ2_bzReadClose ( &bzerror, b );
-  /* handle error */
-}
-
-bzerror = BZ_OK;
-while ( bzerror == BZ_OK && /* arbitrary other conditions */) {
-  nBuf = BZ2_bzRead ( &bzerror, b, buf, /* size of buf */ );
-  if ( bzerror == BZ_OK ) {
-    /* do something with buf[0 .. nBuf-1] */
-  }
-}
-if ( bzerror != BZ_STREAM_END ) {
-   BZ2_bzReadClose ( &bzerror, b );
-   /* handle error */
-} else {
-   BZ2_bzReadClose ( &bzerror, b );
-}
-
-
-
-
-
-
-
-
-Utility functions
-
-
-
-BZ2_bzBuffToBuffCompress
-
-
-int BZ2_bzBuffToBuffCompress( char*         dest,
-                              unsigned int* destLen,
-                              char*         source,
-                              unsigned int  sourceLen,
-                              int           blockSize100k,
-                              int           verbosity,
-                              int           workFactor );
-
-
-Attempts to compress the data in source[0
-.. sourceLen-1] into the destination buffer,
-dest[0 .. *destLen-1].  If the
-destination buffer is big enough,
-*destLen is set to the size of
-the compressed data, and BZ_OK
-is returned.  If the compressed data won't fit,
-*destLen is unchanged, and
-BZ_OUTBUFF_FULL is
-returned.
-
-Compression in this manner is a one-shot event, done with a
-single call to this function.  The resulting compressed data is a
-complete bzip2 format data
-stream.  There is no mechanism for making additional calls to
-provide extra input data.  If you want that kind of mechanism,
-use the low-level interface.
-
-For the meaning of parameters
-blockSize100k,
-verbosity and
-workFactor, see
-BZ2_bzCompressInit.
-
-To guarantee that the compressed data will fit in its
-buffer, allocate an output buffer of size 1% larger than the
-uncompressed data, plus six hundred extra bytes.
-
-BZ2_bzBuffToBuffDecompress
-will not write data at or beyond
-dest[*destLen], even in case of
-buffer overflow.
-
-Possible return values:
-
-
-BZ_CONFIG_ERROR
-  if the library has been mis-compiled
-BZ_PARAM_ERROR
-  if dest is NULL or destLen is NULL
-  or blockSize100k < 1 or blockSize100k > 9
-  or verbosity < 0 or verbosity > 4
-  or workFactor < 0 or workFactor > 250
-BZ_MEM_ERROR
-  if insufficient memory is available
-BZ_OUTBUFF_FULL
-  if the size of the compressed data exceeds *destLen
-BZ_OK
-  otherwise
-
-
-
-
-
-
-BZ2_bzBuffToBuffDecompress
-
-
-int BZ2_bzBuffToBuffDecompress( char*         dest,
-                                unsigned int* destLen,
-                                char*         source,
-                                unsigned int  sourceLen,
-                                int           small,
-                                int           verbosity );
-
-
-Attempts to decompress the data in source[0
-.. sourceLen-1] into the destination buffer,
-dest[0 .. *destLen-1].  If the
-destination buffer is big enough,
-*destLen is set to the size of
-the uncompressed data, and BZ_OK
-is returned.  If the compressed data won't fit,
-*destLen is unchanged, and
-BZ_OUTBUFF_FULL is
-returned.
-
-source is assumed to hold
-a complete bzip2 format data
-stream.
-BZ2_bzBuffToBuffDecompress tries
-to decompress the entirety of the stream into the output
-buffer.
-
-For the meaning of parameters
-small and
-verbosity, see
-BZ2_bzDecompressInit.
-
-Because the compression ratio of the compressed data cannot
-be known in advance, there is no easy way to guarantee that the
-output buffer will be big enough.  You may of course make
-arrangements in your code to record the size of the uncompressed
-data, but such a mechanism is beyond the scope of this
-library.
-
-BZ2_bzBuffToBuffDecompress
-will not write data at or beyond
-dest[*destLen], even in case of
-buffer overflow.
-
-Possible return values:
-
-
-BZ_CONFIG_ERROR
-  if the library has been mis-compiled
-BZ_PARAM_ERROR
-  if dest is NULL or destLen is NULL
-  or small != 0 && small != 1
-  or verbosity < 0 or verbosity > 4
-BZ_MEM_ERROR
-  if insufficient memory is available
-BZ_OUTBUFF_FULL
-  if the size of the compressed data exceeds *destLen
-BZ_DATA_ERROR
-  if a data integrity error was detected in the compressed data
-BZ_DATA_ERROR_MAGIC
-  if the compressed data doesn't begin with the right magic bytes
-BZ_UNEXPECTED_EOF
-  if the compressed data ends unexpectedly
-BZ_OK
-  otherwise
-
-
-
-
-
-
-
-
-zlib compatibility functions
-
-Yoshioka Tsuneo has contributed some functions to give
-better zlib compatibility.
-These functions are BZ2_bzopen,
-BZ2_bzread,
-BZ2_bzwrite,
-BZ2_bzflush,
-BZ2_bzclose,
-BZ2_bzerror and
-BZ2_bzlibVersion.  These
-functions are not (yet) officially part of the library.  If they
-break, you get to keep all the pieces.  Nevertheless, I think
-they work ok.
-
-
-typedef void BZFILE;
-
-const char * BZ2_bzlibVersion ( void );
-
-
-Returns a string indicating the library version.
-
-
-BZFILE * BZ2_bzopen  ( const char *path, const char *mode );
-BZFILE * BZ2_bzdopen ( int        fd,    const char *mode );
-
-
-Opens a .bz2 file for
-reading or writing, using either its name or a pre-existing file
-descriptor.  Analogous to fopen
-and fdopen.
-
-
-int BZ2_bzread  ( BZFILE* b, void* buf, int len );
-int BZ2_bzwrite ( BZFILE* b, void* buf, int len );
-
-
-Reads/writes data from/to a previously opened
-BZFILE.  Analogous to
-fread and
-fwrite.
-
-
-int  BZ2_bzflush ( BZFILE* b );
-void BZ2_bzclose ( BZFILE* b );
-
-
-Flushes/closes a BZFILE.
-BZ2_bzflush doesn't actually do
-anything.  Analogous to fflush
-and fclose.
-
-
-const char * BZ2_bzerror ( BZFILE *b, int *errnum )
-
-
-Returns a string describing the more recent error status of
-b, and also sets
-*errnum to its numerical
-value.
-
-
-
-
-
-Using the library in a stdio-free environment
-
-
-
-Getting rid of stdio
-
-In a deeply embedded application, you might want to use
-just the memory-to-memory functions.  You can do this
-conveniently by compiling the library with preprocessor symbol
-BZ_NO_STDIO defined.  Doing this
-gives you a library containing only the following eight
-functions:
-
-BZ2_bzCompressInit,
-BZ2_bzCompress,
-BZ2_bzCompressEnd
-BZ2_bzDecompressInit,
-BZ2_bzDecompress,
-BZ2_bzDecompressEnd
-BZ2_bzBuffToBuffCompress,
-BZ2_bzBuffToBuffDecompress
-
-When compiled like this, all functions will ignore
-verbosity settings.
-
-
-
-
-
-Critical error handling
-
-libbzip2 contains a number
-of internal assertion checks which should, needless to say, never
-be activated.  Nevertheless, if an assertion should fail,
-behaviour depends on whether or not the library was compiled with
-BZ_NO_STDIO set.
-
-For a normal compile, an assertion failure yields the
-message:
-
-
-bzip2/libbzip2: internal error number N. -This is a bug in bzip2/libbzip2, &bz-version; of &bz-date;. -Please report it at: https://gitlab.com/bzip2/bzip2/-/issues. -If this happened when you were using some program which uses -libbzip2 as a component, you should also report this bug to -the author(s) of that program. -Please make an effort to report this bug; -timely and accurate bug reports eventually lead to higher -quality software. Thanks. -
- -where N is some error code -number. If N == 1007, it also -prints some extra text advising the reader that unreliable memory -is often associated with internal error 1007. (This is a -frequently-observed-phenomenon with versions 1.0.0/1.0.1). - -exit(3) is then -called. - -For a stdio-free library, -assertion failures result in a call to a function declared -as: - - -extern void bz_internal_error ( int errcode ); - - -The relevant code is passed as a parameter. You should -supply such a function. - -In either case, once an assertion failure has occurred, any -bz_stream records involved can -be regarded as invalid. You should not attempt to resume normal -operation with them. - -You may, of course, change critical error handling to suit -your needs. As I said above, critical errors indicate bugs in -the library and should not occur. All "normal" error situations -are indicated via error return codes from functions, and can be -recovered from. - -
- -
- -
- - - - -Miscellanea - -These are just some random thoughts of mine. Your mileage -may vary. - - - -Limitations of the compressed file format - -bzip2-1.0.X, -0.9.5 and -0.9.0 use exactly the same file -format as the original version, -bzip2-0.1. This decision was -made in the interests of stability. Creating yet another -incompatible compressed file format would create further -confusion and disruption for users. - -Nevertheless, this is not a painless decision. Development -work since the release of -bzip2-0.1 in August 1997 has -shown complexities in the file format which slow down -decompression and, in retrospect, are unnecessary. These -are: - - - - The run-length encoder, which is the first of the - compression transformations, is entirely irrelevant. The - original purpose was to protect the sorting algorithm from the - very worst case input: a string of repeated symbols. But - algorithm steps Q6a and Q6b in the original Burrows-Wheeler - technical report (SRC-124) show how repeats can be handled - without difficulty in block sorting. - - The randomisation mechanism doesn't really need to be - there. Udi Manber and Gene Myers published a suffix array - construction algorithm a few years back, which can be employed - to sort any block, no matter how repetitive, in O(N log N) - time. Subsequent work by Kunihiko Sadakane has produced a - derivative O(N (log N)^2) algorithm which usually outperforms - the Manber-Myers algorithm. - - I could have changed to Sadakane's algorithm, but I find - it to be slower than bzip2's - existing algorithm for most inputs, and the randomisation - mechanism protects adequately against bad cases. I didn't - think it was a good tradeoff to make. Partly this is due to - the fact that I was not flooded with email complaints about - bzip2-0.1's performance on - repetitive data, so perhaps it isn't a problem for real - inputs. - - Probably the best long-term solution, and the one I have - incorporated into 0.9.5 and above, is to use the existing - sorting algorithm initially, and fall back to an O(N (log N)^2) - algorithm if the standard algorithm gets into - difficulties. - - The compressed file format was never designed to be - handled by a library, and I have had to jump though some hoops - to produce an efficient implementation of decompression. It's - a bit hairy. Try passing - decompress.c through the C - preprocessor and you'll see what I mean. Much of this - complexity could have been avoided if the compressed size of - each block of data was recorded in the data stream. - - An Adler-32 checksum, rather than a CRC32 checksum, - would be faster to compute. - - - -It would be fair to say that the -bzip2 format was frozen before I -properly and fully understood the performance consequences of -doing so. - -Improvements which I was able to incorporate into 0.9.0, -despite using the same file format, are: - - - - Single array implementation of the inverse BWT. This - significantly speeds up decompression, presumably because it - reduces the number of cache misses. - - Faster inverse MTF transform for large MTF values. - The new implementation is based on the notion of sliding blocks - of values. - - bzip2-0.9.0 now reads - and writes files with fread - and fwrite; version 0.1 used - putc and - getc. Duh! Well, you live - and learn. - - - -Further ahead, it would be nice to be able to do random -access into files. This will require some careful design of -compressed file formats. - - - - - -Portability issues - -After some consideration, I have decided not to use GNU -autoconf to configure 0.9.5 or -1.0. - -autoconf, admirable and -wonderful though it is, mainly assists with portability problems -between Unix-like platforms. But -bzip2 doesn't have much in the -way of portability problems on Unix; most of the difficulties -appear when porting to the Mac, or to Microsoft's operating -systems. autoconf doesn't help -in those cases, and brings in a whole load of new -complexity. - -Most people should be able to compile the library and -program under Unix straight out-of-the-box, so to speak, -especially if you have a version of GNU C available. - -There are a couple of -__inline__ directives in the -code. GNU C (gcc) should be -able to handle them. If you're not using GNU C, your C compiler -shouldn't see them at all. If your compiler does, for some -reason, see them and doesn't like them, just -#define -__inline__ to be -/* */. One easy way to do this -is to compile with the flag --D__inline__=, which should be -understood by most Unix compilers. - -If you still have difficulties, try compiling with the -macro BZ_STRICT_ANSI defined. -This should enable you to build the library in a strictly ANSI -compliant environment. Building the program itself like this is -dangerous and not supported, since you remove -bzip2's checks against -compressing directories, symbolic links, devices, and other -not-really-a-file entities. This could cause filesystem -corruption! - -One other thing: if you create a -bzip2 binary for public distribution, -please consider linking it statically (gcc --static). This avoids all sorts of library-version -issues that others may encounter later on. - -If you build bzip2 on -Win32, you must set BZ_UNIX to 0 -and BZ_LCCWIN32 to 1, in the -file bzip2.c, before compiling. -Otherwise the resulting binary won't work correctly. - - - - - -Reporting bugs - -I tried pretty hard to make sure -bzip2 is bug free, both by -design and by testing. Hopefully you'll never need to read this -section for real. - -Nevertheless, if bzip2 dies -with a segmentation fault, a bus error or an internal assertion -failure, it will ask you to email me a bug report. Experience from -years of feedback of bzip2 users indicates that almost all these -problems can be traced to either compiler bugs or hardware -problems. - - - - Recompile the program with no optimisation, and - see if it works. And/or try a different compiler. I heard all - sorts of stories about various flavours of GNU C (and other - compilers) generating bad code for - bzip2, and I've run across two - such examples myself. - - 2.7.X versions of GNU C are known to generate bad code - from time to time, at high optimisation levels. If you get - problems, try using the flags - -O2 - -fomit-frame-pointer - -fno-strength-reduce. You - should specifically not use - -funroll-loops. - - You may notice that the Makefile runs six tests as part - of the build process. If the program passes all of these, it's - a pretty good (but not 100%) indication that the compiler has - done its job correctly. - - If bzip2 - crashes randomly, and the crashes are not repeatable, you may - have a flaky memory subsystem. - bzip2 really hammers your - memory hierarchy, and if it's a bit marginal, you may get these - problems. Ditto if your disk or I/O subsystem is slowly - failing. Yup, this really does happen. - - Try using a different machine of the same type, and see - if you can repeat the problem. - - This isn't really a bug, but ... If - bzip2 tells you your file is - corrupted on decompression, and you obtained the file via FTP, - there is a possibility that you forgot to tell FTP to do a - binary mode transfer. That absolutely will cause the file to - be non-decompressible. You'll have to transfer it - again. - - - -If you've incorporated -libbzip2 into your own program -and are getting problems, please, please, please, check that the -parameters you are passing in calls to the library, are correct, -and in accordance with what the documentation says is allowable. -I have tried to make the library robust against such problems, -but I'm sure I haven't succeeded. - -Finally, if the above comments don't help, you'll have to -send me a bug report. Now, it's just amazing how many people -will send me a bug report saying something like: - - -bzip2 crashed with segmentation fault on my machine - - -and absolutely nothing else. Needless to say, a such a -report is totally, utterly, completely and -comprehensively 100% useless; a waste of your time, my time, and -net bandwidth. With no details at all, there's no way -I can possibly begin to figure out what the problem is. - -The rules of the game are: facts, facts, facts. Don't omit -them because "oh, they won't be relevant". At the bare -minimum: - - -Machine type. Operating system version. -Exact version of bzip2 (do bzip2 -V). -Exact version of the compiler used. -Flags passed to the compiler. - - -However, the most important single thing that will help me -is the file that you were trying to compress or decompress at the -time the problem happened. Without that, my ability to do -anything more than speculate about the cause, is limited. - - - - - -Did you get the right package? - -bzip2 is a resource hog. -It soaks up large amounts of CPU cycles and memory. Also, it -gives very large latencies. In the worst case, you can feed many -megabytes of uncompressed data into the library before getting -any compressed output, so this probably rules out applications -requiring interactive behaviour. - -These aren't faults of my implementation, I hope, but more -an intrinsic property of the Burrows-Wheeler transform -(unfortunately). Maybe this isn't what you want. - -If you want a compressor and/or library which is faster, -uses less memory but gets pretty good compression, and has -minimal latency, consider Jean-loup Gailly's and Mark Adler's -work, zlib-1.2.1 and -gzip-1.2.4. Look for them at -http://www.zlib.org and -http://www.gzip.org -respectively. - -For something faster and lighter still, you might try Markus F -X J Oberhumer's LZO real-time -compression/decompression library, at -http://www.oberhumer.com/opensource. - - - - - - -Further Reading - -bzip2 is not research -work, in the sense that it doesn't present any new ideas. -Rather, it's an engineering exercise based on existing -ideas. - -Four documents describe essentially all the ideas behind -bzip2: - -Michael Burrows and D. J. Wheeler: - "A block-sorting lossless data compression algorithm" - 10th May 1994. - Digital SRC Research Report 124. - ftp://ftp.digital.com/pub/DEC/SRC/research-reports/SRC-124.ps.gz - If you have trouble finding it, try searching at the - New Zealand Digital Library, http://www.nzdl.org. - -Daniel S. Hirschberg and Debra A. LeLewer - "Efficient Decoding of Prefix Codes" - Communications of the ACM, April 1990, Vol 33, Number 4. - You might be able to get an electronic copy of this - from the ACM Digital Library. - -David J. Wheeler - Program bred3.c and accompanying document bred3.ps. - This contains the idea behind the multi-table Huffman coding scheme. - ftp://ftp.cl.cam.ac.uk/users/djw3/ - -Jon L. Bentley and Robert Sedgewick - "Fast Algorithms for Sorting and Searching Strings" - Available from Sedgewick's web page, - www.cs.princeton.edu/~rs - - -The following paper gives valuable additional insights into -the algorithm, but is not immediately the basis of any code used -in bzip2. - -Peter Fenwick: - Block Sorting Text Compression - Proceedings of the 19th Australasian Computer Science Conference, - Melbourne, Australia. Jan 31 - Feb 2, 1996. - ftp://ftp.cs.auckland.ac.nz/pub/peter-f/ACSC96paper.ps - -Kunihiko Sadakane's sorting algorithm, mentioned above, is -available from: - -http://naomi.is.s.u-tokyo.ac.jp/~sada/papers/Sada98b.ps.gz - - -The Manber-Myers suffix array construction algorithm is -described in a paper available from: - -http://www.cs.arizona.edu/people/gene/PAPERS/suffix.ps - - -Finally, the following papers document some -investigations I made into the performance of sorting -and decompression algorithms: - -Julian Seward - On the Performance of BWT Sorting Algorithms - Proceedings of the IEEE Data Compression Conference 2000 - Snowbird, Utah. 28-30 March 2000. - -Julian Seward - Space-time Tradeoffs in the Inverse B-W Transform - Proceedings of the IEEE Data Compression Conference 2001 - Snowbird, Utah. 27-29 March 2001. - - - - - - -
diff --git a/thirdparty/bzip2/docs/meson.build b/thirdparty/bzip2/docs/meson.build deleted file mode 100644 index 7d8009bc0..000000000 --- a/thirdparty/bzip2/docs/meson.build +++ /dev/null @@ -1,17 +0,0 @@ -build_docs = get_option('docs') -docs = find_program('xsltproc', required : build_docs).found() -docs = docs and find_program('perl', required : build_docs).found() -docs = docs and find_program('xmllint', required : build_docs).found() -docs = docs and find_program('grep', required : build_docs).found() -docs = docs and find_program('pdfxmltex', required : build_docs).found() -docs = docs and find_program('pdftops', required : build_docs).found() -prog_sh = find_program('sh', required : build_docs) -if docs and prog_sh.found() - foreach t : ['pdf', 'ps', 'html'] - custom_target( - 'manual.' + t, - command : [prog_sh, 'xmlproc.sh', '-' + t, '@OUTPUT@'], - output : 'manual.' + t, - ) - endforeach -endif diff --git a/thirdparty/bzip2/docs/xmlproc.sh b/thirdparty/bzip2/docs/xmlproc.sh deleted file mode 100755 index 146311717..000000000 --- a/thirdparty/bzip2/docs/xmlproc.sh +++ /dev/null @@ -1,114 +0,0 @@ -#!/bin/bash -# see the README file for usage etc. -# -# ------------------------------------------------------------------ -# This file is part of bzip2/libbzip2, a program and library for -# lossless, block-sorting data compression. -# -# bzip2/libbzip2 version 1.1.0 of 6 September 2010 -# Copyright (C) 1996-2010 Julian Seward -# -# 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. -# ---------------------------------------------------------------- - - -usage() { - echo ''; - echo 'Usage: xmlproc.sh -[option] '; - echo 'Specify a target from:'; - echo '-v verify xml file conforms to dtd'; - echo '-html output in html format (single file)'; - echo '-ps output in postscript format'; - echo '-pdf output in pdf format'; - exit; -} - -if test $# -ne 2; then - usage -fi -# assign the variable for the output type -action=$1; shift -# assign the output filename -xmlfile=$1; shift -# and check user input it correct -if !(test -f $xmlfile); then - echo "No such file: $xmlfile"; - exit; -fi -# some other stuff we will use -OUT=output -xsl_fo=bz-fo.xsl -xsl_html=bz-html.xsl - -basename=$xmlfile -basename=${basename//'.xml'/''} - -fofile="${basename}.fo" -htmlfile="${basename}.html" -pdffile="${basename}.pdf" -psfile="${basename}.ps" -xmlfmtfile="${basename}.fmt" - -# first process the xmlfile with CDATA tags -./format.pl $xmlfile $xmlfmtfile -# so the shell knows where the catalogs live -export XML_CATALOG_FILES=/etc/xml/catalog - -# post-processing tidy up -cleanup() { - echo "Cleaning up: $@" - while [ $# != 0 ] - do - arg=$1; shift; - echo " deleting $arg"; - rm $arg - done -} - -case $action in - -v) - flags='--noout --xinclude --noblanks --postvalid' - dtd='--dtdvalid http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd' - xmllint $flags $dtd $xmlfmtfile 2> $OUT - grep -F 'error' $OUT - rm $OUT - ;; - - -html) - echo "Creating $htmlfile ..." - xsltproc --nonet --xinclude -o $htmlfile $xsl_html $xmlfmtfile - cleanup $xmlfmtfile - ;; - - -pdf) - echo "Creating $pdffile ..." - xsltproc --nonet --xinclude -o $fofile $xsl_fo $xmlfmtfile - pdfxmltex $fofile >$OUT $OUT $OUT $OUT $OUT $OUT $OUT $OUT $OUT - - 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 ---*/ -/*-------------------------------------------------------------*/ diff --git a/thirdparty/bzip2/install_links.py b/thirdparty/bzip2/install_links.py deleted file mode 100755 index c17b697cc..000000000 --- a/thirdparty/bzip2/install_links.py +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env python3 - -"""Create a symlink or a copy of an installed file.""" - -import argparse -import os -import shutil - - -def main(): - parser = argparse.ArgumentParser() - parser.add_argument('bindir') - parser.add_argument('source') - parser.add_argument('dest', nargs='+') - parser.add_argument('--use-links', action='store_true') - args = parser.parse_args() - - os.chdir(os.environ['MESON_INSTALL_DESTDIR_PREFIX']) - os.chdir(args.bindir) - - # Windows doesn't really use symlinks, just copy in that case. Windows - # before vista (xp) doesn't have symlinks at all. - if args.use_links: - func = os.symlink - verb = 'Linking' - else: - func = shutil.copy - verb = 'Copying' - - # at least os.symlink will fail if the destination already exists, just - # remove the dest if it already exists. - for dest in args.dest: - if os.path.exists(dest): - os.unlink(dest) - - func(args.source, dest) - print('{} {} to {}'.format(verb, args.source, dest)) - - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/thirdparty/bzip2/libbz2.def b/thirdparty/bzip2/libbz2.def deleted file mode 100644 index 68b59cbd0..000000000 --- a/thirdparty/bzip2/libbz2.def +++ /dev/null @@ -1,26 +0,0 @@ -LIBRARY bz2-1 -EXPORTS - BZ2_bzCompressInit - BZ2_bzCompress - BZ2_bzCompressEnd - BZ2_bzDecompressInit - BZ2_bzDecompress - BZ2_bzDecompressEnd - BZ2_bzReadOpen - BZ2_bzReadClose - BZ2_bzReadGetUnused - BZ2_bzRead - BZ2_bzWriteOpen - BZ2_bzWrite - BZ2_bzWriteClose - BZ2_bzWriteClose64 - BZ2_bzBuffToBuffCompress - BZ2_bzBuffToBuffDecompress - BZ2_bzlibVersion - BZ2_bzopen - BZ2_bzdopen - BZ2_bzread - BZ2_bzwrite - BZ2_bzflush - BZ2_bzclose - BZ2_bzerror diff --git a/thirdparty/bzip2/man/CMakeLists.txt b/thirdparty/bzip2/man/CMakeLists.txt deleted file mode 100644 index 24c8faff0..000000000 --- a/thirdparty/bzip2/man/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -set(MAN_FILES bzip2.1 bzgrep.1 bzdiff.1 bzmore.1) -foreach(m IN LISTS MAN_FILES) - install( - FILES - ${CMAKE_CURRENT_SOURCE_DIR}/${m} - DESTINATION - ${CMAKE_INSTALL_PREFIX}/man/man1) -endforeach() diff --git a/thirdparty/bzip2/man/bzdiff.1 b/thirdparty/bzip2/man/bzdiff.1 deleted file mode 100644 index adb7a8e72..000000000 --- a/thirdparty/bzip2/man/bzdiff.1 +++ /dev/null @@ -1,47 +0,0 @@ -\"Shamelessly copied from zmore.1 by Philippe Troin -\"for Debian GNU/Linux -.TH BZDIFF 1 -.SH NAME -bzcmp, bzdiff \- compare bzip2 compressed files -.SH SYNOPSIS -.B bzcmp -[ cmp_options ] file1 -[ file2 ] -.br -.B bzdiff -[ diff_options ] file1 -[ file2 ] -.SH DESCRIPTION -.I Bzcmp -and -.I bzdiff -are used to invoke the -.I cmp -or the -.I diff -program on bzip2 compressed files. All options specified are passed -directly to -.I cmp -or -.IR diff "." -If only 1 file is specified, then the files compared are -.I file1 -and an uncompressed -.IR file1 ".bz2." -If two files are specified, then they are uncompressed if necessary and fed to -.I cmp -or -.IR diff "." -The exit status from -.I cmp -or -.I diff -is preserved. -.SH "SEE ALSO" -cmp(1), diff(1), bzmore(1), bzless(1), bzgrep(1), bzip2(1) -.SH BUGS -Messages from the -.I cmp -or -.I diff -programs refer to temporary filenames instead of those specified. diff --git a/thirdparty/bzip2/man/bzgrep.1 b/thirdparty/bzip2/man/bzgrep.1 deleted file mode 100644 index c99e3be3f..000000000 --- a/thirdparty/bzip2/man/bzgrep.1 +++ /dev/null @@ -1,56 +0,0 @@ -\"Shamelessly copied from zmore.1 by Philippe Troin -\"for Debian GNU/Linux -.TH BZGREP 1 -.SH NAME -bzgrep, bzfgrep, bzegrep \- search possibly bzip2 compressed files for a regular expression -.SH SYNOPSIS -.B bzgrep -[ grep options ] -.BI [\ -e\ ] " pattern" -.IR filename ".\|.\|." -.br -.B bzegrep -[ grep -E options ] -.BI [\ -e\ ] " pattern" -.IR filename ".\|.\|." -.br -.B bzfgrep -[ grep -F options ] -.BI [\ -e\ ] " pattern" -.IR filename ".\|.\|." -.SH DESCRIPTION -.IR Bzgrep -is used to invoke the -.I grep -on bzip2-compressed files. All options specified are passed directly to -.I grep. -If no file is specified, then the standard input is decompressed -if necessary and fed to grep. -Otherwise the given files are uncompressed if necessary and fed to -.I grep. -.PP -If -.I bzgrep -is invoked as -.I bzegrep -or -.I bzfgrep -then -.I grep -E -or -.I grep -F -is used instead of -.I grep. -If the GREP environment variable is set, -.I bzgrep -uses it as the -.I grep -program to be invoked. For example: - - for sh: GREP="grep -F" bzgrep string files - for csh: (setenv GREP "grep -F"; bzgrep string files) -.SH AUTHOR -Charles Levert (charles@comm.polymtl.ca). Adapted to bzip2 by Philippe -Troin for Debian GNU/Linux. -.SH "SEE ALSO" -grep(1), bzdiff(1), bzmore(1), bzless(1), bzip2(1) diff --git a/thirdparty/bzip2/man/bzip2.1 b/thirdparty/bzip2/man/bzip2.1 deleted file mode 100644 index ee41b821b..000000000 --- a/thirdparty/bzip2/man/bzip2.1 +++ /dev/null @@ -1,475 +0,0 @@ -.TH bzip2 1 -.SH NAME -bzip2, bunzip2 \- a block-sorting file compressor, v1.0.6 -.br -bzcat \- decompresses files to stdout -.br -bzip2recover \- recovers data from damaged bzip2 files - -.SH SYNOPSIS -.ll +8 -.B bzip2 -.RB [ " \-cdfkqstvzVL123456789 " ] -[ -.I "filenames \&..." -] -.br -.B bzip2 -.RB [ " \-h|\-\-help " ] -.ll -8 -.br -.B bunzip2 -.RB [ " \-fkvsVL " ] -[ -.I "filenames \&..." -] -.br -.B bunzip2 -.RB [ " \-h|\-\-help " ] -.br -.B bzcat -.RB [ " \-s " ] -[ -.I "filenames \&..." -] -.br -.B bzcat -.RB [ " \-h|\-\-help " ] -.br -.B bzip2recover -.I "filename" - -.SH DESCRIPTION -.I bzip2 -compresses files using the Burrows-Wheeler block sorting -text compression algorithm, and Huffman coding. Compression is -generally considerably better than that achieved by more conventional -LZ77/LZ78-based compressors, and approaches the performance of the PPM -family of statistical compressors. - -The command-line options are deliberately very similar to -those of -.I GNU gzip, -but they are not identical. - -.I bzip2 -expects a list of file names to accompany the -command-line flags. Each file is replaced by a compressed version of -itself, with the name "original_name.bz2". -Each compressed file -has the same modification date, permissions, and, when possible, -ownership as the corresponding original, so that these properties can -be correctly restored at decompression time. File name handling is -naive in the sense that there is no mechanism for preserving original -file names, permissions, ownerships or dates in filesystems which lack -these concepts, or have serious file name length restrictions, such as -MS-DOS. - -.I bzip2 -and -.I bunzip2 -will by default not overwrite existing -files. If you want this to happen, specify the \-f flag. - -If no file names are specified, -.I bzip2 -compresses from standard -input to standard output. In this case, -.I bzip2 -will decline to -write compressed output to a terminal, as this would be entirely -incomprehensible and therefore pointless. - -.I bunzip2 -(or -.I bzip2 \-d) -decompresses all -specified files. Files which were not created by -.I bzip2 -will be detected and ignored, and a warning issued. -.I bzip2 -attempts to guess the filename for the decompressed file -from that of the compressed file as follows: - - filename.bz2 becomes filename - filename.bz becomes filename - filename.tbz2 becomes filename.tar - filename.tbz becomes filename.tar - anyothername becomes anyothername.out - -If the file does not end in one of the recognised endings, -.I .bz2, -.I .bz, -.I .tbz2 -or -.I .tbz, -.I bzip2 -complains that it cannot -guess the name of the original file, and uses the original name -with -.I .out -appended. - -As with compression, supplying no -filenames causes decompression from -standard input to standard output. - -.I bunzip2 -will correctly decompress a file which is the -concatenation of two or more compressed files. The result is the -concatenation of the corresponding uncompressed files. Integrity -testing (\-t) -of concatenated -compressed files is also supported. - -You can also compress or decompress files to the standard output by -giving the \-c flag. Multiple files may be compressed and -decompressed like this. The resulting outputs are fed sequentially to -stdout. Compression of multiple files -in this manner generates a stream -containing multiple compressed file representations. Such a stream -can be decompressed correctly only by -.I bzip2 -version 0.9.0 or -later. Earlier versions of -.I bzip2 -will stop after decompressing -the first file in the stream. - -.I bzcat -(or -.I bzip2 -dc) -decompresses all specified files to -the standard output. - -.I bzip2 -will read arguments from the environment variables -.I BZIP2 -and -.I BZIP, -in that order, and will process them -before any arguments read from the command line. This gives a -convenient way to supply default arguments. - -Compression is always performed, even if the compressed -file is slightly -larger than the original. Files of less than about one hundred bytes -tend to get larger, since the compression mechanism has a constant -overhead in the region of 50 bytes. Random data (including the output -of most file compressors) is coded at about 8.05 bits per byte, giving -an expansion of around 0.5%. - -As a self-check for your protection, -.I bzip2 -uses 32-bit CRCs to -make sure that the decompressed version of a file is identical to the -original. This guards against corruption of the compressed data, and -against undetected bugs in -.I bzip2 -(hopefully very unlikely). The -chances of data corruption going undetected is microscopic, about one -chance in four billion for each file processed. Be aware, though, that -the check occurs upon decompression, so it can only tell you that -something is wrong. It can't help you -recover the original uncompressed -data. You can use -.I bzip2recover -to try to recover data from -damaged files. - -Unlike -.I GNU gzip, -.I bzip2 -will not create a series of -.I .bz2 -suffixes even when using the -.I --force -option: - - filename.bz2 does not become filename.bz2.bz2 - -Return values: 0 for a normal exit, 1 for environmental problems (file -not found, invalid flags, I/O errors, &c), 2 to indicate a corrupt -compressed file, 3 for an internal consistency error (eg, bug) which -caused -.I bzip2 -to panic. - -.SH OPTIONS -.TP -.B \-c --stdout -Compress or decompress to standard output. -.TP -.B \-d --decompress -Force decompression. -.I bzip2, -.I bunzip2 -and -.I bzcat -are -really the same program, and the decision about what actions to take is -done on the basis of which name is used. This flag overrides that -mechanism, and forces -.I bzip2 -to decompress. -.TP -.B \-z --compress -The complement to \-d: forces compression, regardless of the -invocation name. -.TP -.B \-t --test -Check integrity of the specified file(s), but don't decompress them. -This really performs a trial decompression and throws away the result. -.TP -.B \-f --force -Force overwrite of output files. Normally, -.I bzip2 -will not overwrite -existing output files. Also forces -.I bzip2 -to break hard links -to files, which it otherwise wouldn't do. - -bzip2 normally declines to decompress files which don't have the -correct magic header bytes. If forced (-f), however, it will pass -such files through unmodified. This is how GNU gzip behaves. -.TP -.B \-k --keep -Keep (don't delete) input files during compression -or decompression. -.TP -.B \-s --small -Reduce memory usage, for compression, decompression and testing. Files -are decompressed and tested using a modified algorithm which only -requires 2.5 bytes per block byte. This means any file can be -decompressed in 2300\ k of memory, albeit at about half the normal speed. - -During compression, \-s selects a block size of 200\ k, which limits -memory use to around the same figure, at the expense of your compression -ratio. In short, if your machine is low on memory (8 megabytes or -less), use \-s for everything. See MEMORY MANAGEMENT below. -.TP -.B \-q --quiet -Suppress non-essential warning messages. Messages pertaining to -I/O errors and other critical events will not be suppressed. -.TP -.B \-v --verbose -Verbose mode -- show the compression ratio for each file processed. -Further \-v's increase the verbosity level, spewing out lots of -information which is primarily of interest for diagnostic purposes. -.TP -.B \-h \-\-help -Print a help message and exit. -.TP -.B \-L --license -V --version -Display the software version, license terms and conditions. -.TP -.B \-1 (or \-\-fast) to \-9 (or \-\-best) -Set the block size to 100 k, 200 k ... 900 k when compressing. Has no -effect when decompressing. See MEMORY MANAGEMENT below. -The \-\-fast and \-\-best aliases are primarily for GNU gzip -compatibility. In particular, \-\-fast doesn't make things -significantly faster. -And \-\-best merely selects the default behaviour. -.TP -.B \-- -Treats all subsequent arguments as file names, even if they start -with a dash. This is so you can handle files with names beginning -with a dash, for example: bzip2 \-- \-myfilename. -.TP -.B \--repetitive-fast --repetitive-best -These flags are redundant in versions 0.9.5 and above. They provided -some coarse control over the behaviour of the sorting algorithm in -earlier versions, which was sometimes useful. 0.9.5 and above have an -improved algorithm which renders these flags irrelevant. - -.SH MEMORY MANAGEMENT -.I bzip2 -compresses large files in blocks. The block size affects -both the compression ratio achieved, and the amount of memory needed for -compression and decompression. The flags \-1 through \-9 -specify the block size to be 100,000 bytes through 900,000 bytes (the -default) respectively. At decompression time, the block size used for -compression is read from the header of the compressed file, and -.I bunzip2 -then allocates itself just enough memory to decompress -the file. Since block sizes are stored in compressed files, it follows -that the flags \-1 to \-9 are irrelevant to and so ignored -during decompression. - -Compression and decompression requirements, -in bytes, can be estimated as: - - Compression: 400\ k + ( 8 x block size ) - - Decompression: 100\ k + ( 4 x block size ), or - 100\ k + ( 2.5 x block size ) - -Larger block sizes give rapidly diminishing marginal returns. Most of -the compression comes from the first two or three hundred k of block -size, a fact worth bearing in mind when using -.I bzip2 -on small machines. -It is also important to appreciate that the decompression memory -requirement is set at compression time by the choice of block size. - -For files compressed with the default 900\ k block size, -.I bunzip2 -will require about 3700 kbytes to decompress. To support decompression -of any file on a 4 megabyte machine, -.I bunzip2 -has an option to -decompress using approximately half this amount of memory, about 2300 -kbytes. Decompression speed is also halved, so you should use this -option only where necessary. The relevant flag is -s. - -In general, try and use the largest block size memory constraints allow, -since that maximises the compression achieved. Compression and -decompression speed are virtually unaffected by block size. - -Another significant point applies to files which fit in a single block --- that means most files you'd encounter using a large block size. The -amount of real memory touched is proportional to the size of the file, -since the file is smaller than a block. For example, compressing a file -20,000 bytes long with the flag -9 will cause the compressor to -allocate around 7600\ k of memory, but only touch 400\ k + 20000 * 8 = 560 -kbytes of it. Similarly, the decompressor will allocate 3700\ k but only -touch 100\ k + 20000 * 4 = 180 kbytes. - -Here is a table which summarises the maximum memory usage for different -block sizes. Also recorded is the total compressed size for 14 files of -the Calgary Text Compression Corpus totalling 3,141,622 bytes. This -column gives some feel for how compression varies with block size. -These figures tend to understate the advantage of larger block sizes for -larger files, since the Corpus is dominated by smaller files. - - Compress Decompress Decompress Corpus - Flag usage usage -s usage Size - - -1 1200k 500k 350k 914704 - -2 2000k 900k 600k 877703 - -3 2800k 1300k 850k 860338 - -4 3600k 1700k 1100k 846899 - -5 4400k 2100k 1350k 845160 - -6 5200k 2500k 1600k 838626 - -7 6100k 2900k 1850k 834096 - -8 6800k 3300k 2100k 828642 - -9 7600k 3700k 2350k 828642 - -.SH RECOVERING DATA FROM DAMAGED FILES -.I bzip2 -compresses files in blocks, usually 900\ kbytes long. Each -block is handled independently. If a media or transmission error causes -a multi-block .bz2 -file to become damaged, it may be possible to -recover data from the undamaged blocks in the file. - -The compressed representation of each block is delimited by a 48-bit -pattern, which makes it possible to find the block boundaries with -reasonable certainty. Each block also carries its own 32-bit CRC, so -damaged blocks can be distinguished from undamaged ones. - -.I bzip2recover -is a simple program whose purpose is to search for -blocks in .bz2 files, and write each block out into its own .bz2 -file. You can then use -.I bzip2 -\-t -to test the -integrity of the resulting files, and decompress those which are -undamaged. - -.I bzip2recover -takes a single argument, the name of the damaged file, -and writes a number of files "rec00001file.bz2", -"rec00002file.bz2", etc., containing the extracted blocks. -The output filenames are designed so that the use of -wildcards in subsequent processing -- for example, -"bzip2 -dc rec*file.bz2 > recovered_data" -- processes the files in -the correct order. - -.I bzip2recover -should be of most use dealing with large .bz2 -files, as these will contain many blocks. It is clearly -futile to use it on damaged single-block files, since a -damaged block cannot be recovered. If you wish to minimise -any potential data loss through media or transmission errors, -you might consider compressing with a smaller -block size. - -.SH PERFORMANCE NOTES -The sorting phase of compression gathers together similar strings in the -file. Because of this, files containing very long runs of repeated -symbols, like "aabaabaabaab ...\&" (repeated several hundred times) may -compress more slowly than normal. Versions 0.9.5 and above fare much -better than previous versions in this respect. The ratio between -worst-case and average-case compression time is in the region of 10:1. -For previous versions, this figure was more like 100:1. You can use the -\-vvvv option to monitor progress in great detail, if you want. - -Decompression speed is unaffected by these phenomena. - -.I bzip2 -usually allocates several megabytes of memory to operate -in, and then charges all over it in a fairly random fashion. This means -that performance, both for compressing and decompressing, is largely -determined by the speed at which your machine can service cache misses. -Because of this, small changes to the code to reduce the miss rate have -been observed to give disproportionately large performance improvements. -I imagine -.I bzip2 -will perform best on machines with very large caches. - -.SH CAVEATS -I/O error messages are not as helpful as they could be. -.I bzip2 -tries hard to detect I/O errors and exit cleanly, but the details of -what the problem is sometimes seem rather misleading. - -This manual page pertains to version 1.1.0 of -.I bzip2. -Compressed data created by this version is entirely forwards and -backwards compatible with the previous public releases, versions -0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1, 1.0.2 and above, but with the following -exception: 0.9.0 and above can correctly decompress multiple -concatenated compressed files. 0.1pl2 cannot do this; it will stop -after decompressing just the first file in the stream. - -.I bzip2recover -versions prior to 1.0.2 used 32-bit integers to represent -bit positions in compressed files, so they could not handle compressed -files more than 512 megabytes long. Versions 1.0.2 and above use -64-bit ints on some platforms which support them (GNU supported -targets, and Windows). To establish whether or not bzip2recover was -built with such a limitation, run it without arguments. In any event -you can build yourself an unlimited version if you can recompile it -with MaybeUInt64 set to be an unsigned 64-bit integer. - - - -.SH AUTHOR -Julian Seward, jseward@acm.org. - -https://gitlab.com/bzip2/bzip2 - -The ideas embodied in -.I bzip2 -are due to (at least) the following -people: Michael Burrows and David Wheeler (for the block sorting -transformation), David Wheeler (again, for the Huffman coder), Peter -Fenwick (for the structured coding model in the original -.I bzip, -and many refinements), and Alistair Moffat, Radford Neal and Ian Witten -(for the arithmetic coder in the original -.I bzip). -I am much -indebted for their help, support and advice. See the manual in the -source distribution for pointers to sources of documentation. Christian -von Roques encouraged me to look for faster sorting algorithms, so as to -speed up compression. Bela Lubkin encouraged me to improve the -worst-case compression performance. -Donna Robinson XMLised the documentation. -The bz* scripts are derived from those of GNU gzip. -Many people sent patches, helped -with portability problems, lent machines, gave advice and were generally -helpful. diff --git a/thirdparty/bzip2/man/bzip2.1.preformatted b/thirdparty/bzip2/man/bzip2.1.preformatted deleted file mode 100644 index 32ebc1d3e..000000000 --- a/thirdparty/bzip2/man/bzip2.1.preformatted +++ /dev/null @@ -1,399 +0,0 @@ -bzip2(1) bzip2(1) - - - -NNAAMMEE - bzip2, bunzip2 − a blockâ€sorting file compressor, v1.0.6 - bzcat − decompresses files to stdout - bzip2recover − recovers data from damaged bzip2 files - - -SSYYNNOOPPSSIISS - bbzziipp22 [ −−ccddffkkqqssttvvzzVVLL112233445566778899 ] [ _f_i_l_e_n_a_m_e_s _._._. ] - bbuunnzziipp22 [ −−ffkkvvssVVLL ] [ _f_i_l_e_n_a_m_e_s _._._. ] - bbzzccaatt [ −−ss ] [ _f_i_l_e_n_a_m_e_s _._._. ] - bbzziipp22rreeccoovveerr _f_i_l_e_n_a_m_e - - -DDEESSCCRRIIPPTTIIOONN - _b_z_i_p_2 compresses files using the Burrowsâ€Wheeler block - sorting text compression algorithm, and Huffman coding. - Compression is generally considerably better than that - achieved by more conventional LZ77/LZ78â€based compressors, - and approaches the performance of the PPM family of sta­ - tistical compressors. - - The commandâ€line options are deliberately very similar to - those of _G_N_U _g_z_i_p_, but they are not identical. - - _b_z_i_p_2 expects a list of file names to accompany the com­ - mandâ€line flags. Each file is replaced by a compressed - version of itself, with the name "original_name.bz2". - Each compressed file has the same modification date, per­ - missions, and, when possible, ownership as the correspond­ - ing original, so that these properties can be correctly - restored at decompression time. File name handling is - naive in the sense that there is no mechanism for preserv­ - ing original file names, permissions, ownerships or dates - in filesystems which lack these concepts, or have serious - file name length restrictions, such as MSâ€DOS. - - _b_z_i_p_2 and _b_u_n_z_i_p_2 will by default not overwrite existing - files. If you want this to happen, specify the −f flag. - - If no file names are specified, _b_z_i_p_2 compresses from - standard input to standard output. In this case, _b_z_i_p_2 - will decline to write compressed output to a terminal, as - this would be entirely incomprehensible and therefore - pointless. - - _b_u_n_z_i_p_2 (or _b_z_i_p_2 _−_d_) decompresses all specified files. - Files which were not created by _b_z_i_p_2 will be detected and - ignored, and a warning issued. _b_z_i_p_2 attempts to guess - the filename for the decompressed file from that of the - compressed file as follows: - - filename.bz2 becomes filename - filename.bz becomes filename - filename.tbz2 becomes filename.tar - filename.tbz becomes filename.tar - anyothername becomes anyothername.out - - If the file does not end in one of the recognised endings, - _._b_z_2_, _._b_z_, _._t_b_z_2 or _._t_b_z_, _b_z_i_p_2 complains that it cannot - guess the name of the original file, and uses the original - name with _._o_u_t appended. - - As with compression, supplying no filenames causes decom­ - pression from standard input to standard output. - - _b_u_n_z_i_p_2 will correctly decompress a file which is the con­ - catenation of two or more compressed files. The result is - the concatenation of the corresponding uncompressed files. - Integrity testing (−t) of concatenated compressed files is - also supported. - - You can also compress or decompress files to the standard - output by giving the −c flag. Multiple files may be com­ - pressed and decompressed like this. The resulting outputs - are fed sequentially to stdout. Compression of multiple - files in this manner generates a stream containing multi­ - ple compressed file representations. Such a stream can be - decompressed correctly only by _b_z_i_p_2 version 0.9.0 or - later. Earlier versions of _b_z_i_p_2 will stop after decom­ - pressing the first file in the stream. - - _b_z_c_a_t (or _b_z_i_p_2 _â€_d_c_) decompresses all specified files to - the standard output. - - _b_z_i_p_2 will read arguments from the environment variables - _B_Z_I_P_2 and _B_Z_I_P_, in that order, and will process them - before any arguments read from the command line. This - gives a convenient way to supply default arguments. - - Compression is always performed, even if the compressed - file is slightly larger than the original. Files of less - than about one hundred bytes tend to get larger, since the - compression mechanism has a constant overhead in the - region of 50 bytes. Random data (including the output of - most file compressors) is coded at about 8.05 bits per - byte, giving an expansion of around 0.5%. - - As a selfâ€check for your protection, _b_z_i_p_2 uses 32â€bit - CRCs to make sure that the decompressed version of a file - is identical to the original. This guards against corrup­ - tion of the compressed data, and against undetected bugs - in _b_z_i_p_2 (hopefully very unlikely). The chances of data - corruption going undetected is microscopic, about one - chance in four billion for each file processed. Be aware, - though, that the check occurs upon decompression, so it - can only tell you that something is wrong. It can’t help - you recover the original uncompressed data. You can use - _b_z_i_p_2_r_e_c_o_v_e_r to try to recover data from damaged files. - - Return values: 0 for a normal exit, 1 for environmental - problems (file not found, invalid flags, I/O errors, &c), - 2 to indicate a corrupt compressed file, 3 for an internal - consistency error (eg, bug) which caused _b_z_i_p_2 to panic. - - -OOPPTTIIOONNSS - −−cc â€â€â€â€ssttddoouutt - Compress or decompress to standard output. - - −−dd â€â€â€â€ddeeccoommpprreessss - Force decompression. _b_z_i_p_2_, _b_u_n_z_i_p_2 and _b_z_c_a_t are - really the same program, and the decision about - what actions to take is done on the basis of which - name is used. This flag overrides that mechanism, - and forces _b_z_i_p_2 to decompress. - - −−zz â€â€â€â€ccoommpprreessss - The complement to −d: forces compression, - regardless of the invocation name. - - −−tt â€â€â€â€tteesstt - Check integrity of the specified file(s), but don’t - decompress them. This really performs a trial - decompression and throws away the result. - - −−ff â€â€â€â€ffoorrccee - Force overwrite of output files. Normally, _b_z_i_p_2 - will not overwrite existing output files. Also - forces _b_z_i_p_2 to break hard links to files, which it - otherwise wouldn’t do. - - bzip2 normally declines to decompress files which - don’t have the correct magic header bytes. If - forced (â€f), however, it will pass such files - through unmodified. This is how GNU gzip behaves. - - −−kk â€â€â€â€kkeeeepp - Keep (don’t delete) input files during compression - or decompression. - - −−ss â€â€â€â€ssmmaallll - Reduce memory usage, for compression, decompression - and testing. Files are decompressed and tested - using a modified algorithm which only requires 2.5 - bytes per block byte. This means any file can be - decompressed in 2300k of memory, albeit at about - half the normal speed. - - During compression, −s selects a block size of - 200k, which limits memory use to around the same - figure, at the expense of your compression ratio. - In short, if your machine is low on memory (8 - megabytes or less), use −s for everything. See - MEMORY MANAGEMENT below. - - −−qq â€â€â€â€qquuiieett - Suppress nonâ€essential warning messages. Messages - pertaining to I/O errors and other critical events - will not be suppressed. - - −−vv â€â€â€â€vveerrbboossee - Verbose mode â€â€ show the compression ratio for each - file processed. Further −v’s increase the ver­ - bosity level, spewing out lots of information which - is primarily of interest for diagnostic purposes. - - −−LL â€â€â€â€lliicceennssee â€â€VV â€â€â€â€vveerrssiioonn - Display the software version, license terms and - conditions. - - −−11 ((oorr −−−−ffaasstt)) ttoo −−99 ((oorr −−−−bbeesstt)) - Set the block size to 100 k, 200 k .. 900 k when - compressing. Has no effect when decompressing. - See MEMORY MANAGEMENT below. The −−fast and −−best - aliases are primarily for GNU gzip compatibility. - In particular, −−fast doesn’t make things signifi­ - cantly faster. And −−best merely selects the - default behaviour. - - −− Treats all subsequent arguments as file names, even - if they start with a dash. This is so you can han­ - dle files with names beginning with a dash, for - example: bzip2 −†−myfilename. - - −−â€â€rreeppeettiittiivveeâ€â€ffaasstt â€â€â€â€rreeppeettiittiivveeâ€â€bbeesstt - These flags are redundant in versions 0.9.5 and - above. They provided some coarse control over the - behaviour of the sorting algorithm in earlier ver­ - sions, which was sometimes useful. 0.9.5 and above - have an improved algorithm which renders these - flags irrelevant. - - -MMEEMMOORRYY MMAANNAAGGEEMMEENNTT - _b_z_i_p_2 compresses large files in blocks. The block size - affects both the compression ratio achieved, and the - amount of memory needed for compression and decompression. - The flags −1 through −9 specify the block size to be - 100,000 bytes through 900,000 bytes (the default) respec­ - tively. At decompression time, the block size used for - compression is read from the header of the compressed - file, and _b_u_n_z_i_p_2 then allocates itself just enough memory - to decompress the file. Since block sizes are stored in - compressed files, it follows that the flags −1 to −9 are - irrelevant to and so ignored during decompression. - - Compression and decompression requirements, in bytes, can - be estimated as: - - Compression: 400k + ( 8 x block size ) - - Decompression: 100k + ( 4 x block size ), or - 100k + ( 2.5 x block size ) - - Larger block sizes give rapidly diminishing marginal - returns. Most of the compression comes from the first two - or three hundred k of block size, a fact worth bearing in - mind when using _b_z_i_p_2 on small machines. It is also - important to appreciate that the decompression memory - requirement is set at compression time by the choice of - block size. - - For files compressed with the default 900k block size, - _b_u_n_z_i_p_2 will require about 3700 kbytes to decompress. To - support decompression of any file on a 4 megabyte machine, - _b_u_n_z_i_p_2 has an option to decompress using approximately - half this amount of memory, about 2300 kbytes. Decompres­ - sion speed is also halved, so you should use this option - only where necessary. The relevant flag is â€s. - - In general, try and use the largest block size memory con­ - straints allow, since that maximises the compression - achieved. Compression and decompression speed are virtu­ - ally unaffected by block size. - - Another significant point applies to files which fit in a - single block â€â€ that means most files you’d encounter - using a large block size. The amount of real memory - touched is proportional to the size of the file, since the - file is smaller than a block. For example, compressing a - file 20,000 bytes long with the flag â€9 will cause the - compressor to allocate around 7600k of memory, but only - touch 400k + 20000 * 8 = 560 kbytes of it. Similarly, the - decompressor will allocate 3700k but only touch 100k + - 20000 * 4 = 180 kbytes. - - Here is a table which summarises the maximum memory usage - for different block sizes. Also recorded is the total - compressed size for 14 files of the Calgary Text Compres­ - sion Corpus totalling 3,141,622 bytes. This column gives - some feel for how compression varies with block size. - These figures tend to understate the advantage of larger - block sizes for larger files, since the Corpus is domi­ - nated by smaller files. - - Compress Decompress Decompress Corpus - Flag usage usage â€s usage Size - - â€1 1200k 500k 350k 914704 - â€2 2000k 900k 600k 877703 - â€3 2800k 1300k 850k 860338 - â€4 3600k 1700k 1100k 846899 - â€5 4400k 2100k 1350k 845160 - â€6 5200k 2500k 1600k 838626 - â€7 6100k 2900k 1850k 834096 - â€8 6800k 3300k 2100k 828642 - â€9 7600k 3700k 2350k 828642 - - -RREECCOOVVEERRIINNGG DDAATTAA FFRROOMM DDAAMMAAGGEEDD FFIILLEESS - _b_z_i_p_2 compresses files in blocks, usually 900kbytes long. - Each block is handled independently. If a media or trans­ - mission error causes a multiâ€block .bz2 file to become - damaged, it may be possible to recover data from the - undamaged blocks in the file. - - The compressed representation of each block is delimited - by a 48â€bit pattern, which makes it possible to find the - block boundaries with reasonable certainty. Each block - also carries its own 32â€bit CRC, so damaged blocks can be - distinguished from undamaged ones. - - _b_z_i_p_2_r_e_c_o_v_e_r is a simple program whose purpose is to - search for blocks in .bz2 files, and write each block out - into its own .bz2 file. You can then use _b_z_i_p_2 −t to test - the integrity of the resulting files, and decompress those - which are undamaged. - - _b_z_i_p_2_r_e_c_o_v_e_r takes a single argument, the name of the dam­ - aged file, and writes a number of files - "rec00001file.bz2", "rec00002file.bz2", etc, containing - the extracted blocks. The output filenames are - designed so that the use of wildcards in subsequent pro­ - cessing â€â€ for example, "bzip2 â€dc rec*file.bz2 > recov­ - ered_data" â€â€ processes the files in the correct order. - - _b_z_i_p_2_r_e_c_o_v_e_r should be of most use dealing with large .bz2 - files, as these will contain many blocks. It is clearly - futile to use it on damaged singleâ€block files, since a - damaged block cannot be recovered. If you wish to min­ - imise any potential data loss through media or transmis­ - sion errors, you might consider compressing with a smaller - block size. - - -PPEERRFFOORRMMAANNCCEE NNOOTTEESS - The sorting phase of compression gathers together similar - strings in the file. Because of this, files containing - very long runs of repeated symbols, like "aabaabaabaab - ..." (repeated several hundred times) may compress more - slowly than normal. Versions 0.9.5 and above fare much - better than previous versions in this respect. The ratio - between worstâ€case and averageâ€case compression time is in - the region of 10:1. For previous versions, this figure - was more like 100:1. You can use the −vvvv option to mon­ - itor progress in great detail, if you want. - - Decompression speed is unaffected by these phenomena. - - _b_z_i_p_2 usually allocates several megabytes of memory to - operate in, and then charges all over it in a fairly ran­ - dom fashion. This means that performance, both for com­ - pressing and decompressing, is largely determined by the - speed at which your machine can service cache misses. - Because of this, small changes to the code to reduce the - miss rate have been observed to give disproportionately - large performance improvements. I imagine _b_z_i_p_2 will per­ - form best on machines with very large caches. - - -CCAAVVEEAATTSS - I/O error messages are not as helpful as they could be. - _b_z_i_p_2 tries hard to detect I/O errors and exit cleanly, - but the details of what the problem is sometimes seem - rather misleading. - - This manual page pertains to version 1.1.0 of _b_z_i_p_2_. Com­ - pressed data created by this version is entirely forwards - and backwards compatible with the previous public - releases, versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1, - 1.0.2 and above, but with the following exception: 0.9.0 - and above can correctly decompress multiple concatenated - compressed files. 0.1pl2 cannot do this; it will stop - after decompressing just the first file in the stream. - - _b_z_i_p_2_r_e_c_o_v_e_r versions prior to 1.0.2 used 32â€bit integers - to represent bit positions in compressed files, so they - could not handle compressed files more than 512 megabytes - long. Versions 1.0.2 and above use 64â€bit ints on some - platforms which support them (GNU supported targets, and - Windows). To establish whether or not bzip2recover was - built with such a limitation, run it without arguments. - In any event you can build yourself an unlimited version - if you can recompile it with MaybeUInt64 set to be an - unsigned 64â€bit integer. - - - - -AAUUTTHHOORR - Julian Seward, jseward@acm.org. - - https://gitlab.com/bzip2/bzip2 - - The ideas embodied in _b_z_i_p_2 are due to (at least) the fol­ - lowing people: Michael Burrows and David Wheeler (for the - block sorting transformation), David Wheeler (again, for - the Huffman coder), Peter Fenwick (for the structured cod­ - ing model in the original _b_z_i_p_, and many refinements), and - Alistair Moffat, Radford Neal and Ian Witten (for the - arithmetic coder in the original _b_z_i_p_)_. I am much - indebted for their help, support and advice. See the man­ - ual in the source distribution for pointers to sources of - documentation. Christian von Roques encouraged me to look - for faster sorting algorithms, so as to speed up compres­ - sion. Bela Lubkin encouraged me to improve the worstâ€case - compression performance. Donna Robinson XMLised the docu­ - mentation. The bz* scripts are derived from those of GNU - gzip. Many people sent patches, helped with portability - problems, lent machines, gave advice and were generally - helpful. - - - - bzip2(1) diff --git a/thirdparty/bzip2/man/bzmore.1 b/thirdparty/bzip2/man/bzmore.1 deleted file mode 100644 index b437d3b03..000000000 --- a/thirdparty/bzip2/man/bzmore.1 +++ /dev/null @@ -1,152 +0,0 @@ -.\"Shamelessly copied from zmore.1 by Philippe Troin -.\"for Debian GNU/Linux -.TH BZMORE 1 -.SH NAME -bzmore, bzless \- file perusal filter for crt viewing of bzip2 compressed text -.SH SYNOPSIS -.B bzmore -[ name ... ] -.br -.B bzless -[ name ... ] -.SH NOTE -In the following description, -.I bzless -and -.I less -can be used interchangeably with -.I bzmore -and -.I more. -.SH DESCRIPTION -.I Bzmore -is a filter which allows examination of compressed or plain text files -one screenful at a time on a soft-copy terminal. -.I bzmore -works on files compressed with -.I bzip2 -and also on uncompressed files. -If a file does not exist, -.I bzmore -looks for a file of the same name with the addition of a .bz2 suffix. -.PP -.I Bzmore -normally pauses after each screenful, printing --More-- -at the bottom of the screen. -If the user then types a carriage return, one more line is displayed. -If the user hits a space, -another screenful is displayed. Other possibilities are enumerated later. -.PP -.I Bzmore -looks in the file -.I /etc/termcap -to determine terminal characteristics, -and to determine the default window size. -On a terminal capable of displaying 24 lines, -the default window size is 22 lines. -Other sequences which may be typed when -.I bzmore -pauses, and their effects, are as follows (\fIi\fP is an optional integer -argument, defaulting to 1) : -.PP -.IP \fIi\|\fP -display -.I i -more lines, (or another screenful if no argument is given) -.PP -.IP ^D -display 11 more lines (a ``scroll''). -If -.I i -is given, then the scroll size is set to \fIi\|\fP. -.PP -.IP d -same as ^D (control-D) -.PP -.IP \fIi\|\fPz -same as typing a space except that \fIi\|\fP, if present, becomes the new -window size. Note that the window size reverts back to the default at the -end of the current file. -.PP -.IP \fIi\|\fPs -skip \fIi\|\fP lines and print a screenful of lines -.PP -.IP \fIi\|\fPf -skip \fIi\fP screenfuls and print a screenful of lines -.PP -.IP "q or Q" -quit reading the current file; go on to the next (if any) -.PP -.IP "e or q" -When the prompt --More--(Next file: -.IR file ) -is printed, this command causes bzmore to exit. -.PP -.IP s -When the prompt --More--(Next file: -.IR file ) -is printed, this command causes bzmore to skip the next file and continue. -.PP -.IP = -Display the current line number. -.PP -.IP \fIi\|\fP/expr -search for the \fIi\|\fP-th occurrence of the regular expression \fIexpr.\fP -If the pattern is not found, -.I bzmore -goes on to the next file (if any). -Otherwise, a screenful is displayed, starting two lines before the place -where the expression was found. -The user's erase and kill characters may be used to edit the regular -expression. -Erasing back past the first column cancels the search command. -.PP -.IP \fIi\|\fPn -search for the \fIi\|\fP-th occurrence of the last regular expression entered. -.PP -.IP !command -invoke a shell with \fIcommand\|\fP. -The character `!' in "command" are replaced with the -previous shell command. The sequence "\\!" is replaced by "!". -.PP -.IP ":q or :Q" -quit reading the current file; go on to the next (if any) -(same as q or Q). -.PP -.IP . -(dot) repeat the previous command. -.PP -The commands take effect immediately, i.e., it is not necessary to -type a carriage return. -Up to the time when the command character itself is given, -the user may hit the line kill character to cancel the numerical -argument being formed. -In addition, the user may hit the erase character to redisplay the ---More-- message. -.PP -At any time when output is being sent to the terminal, the user can -hit the quit key (normally control\-\\). -.I Bzmore -will stop sending output, and will display the usual --More-- -prompt. -The user may then enter one of the above commands in the normal manner. -Unfortunately, some output is lost when this is done, due to the -fact that any characters waiting in the terminal's output queue -are flushed when the quit signal occurs. -.PP -The terminal is set to -.I noecho -mode by this program so that the output can be continuous. -What you type will thus not show on your terminal, except for the / and ! -commands. -.PP -If the standard output is not a teletype, then -.I bzmore -acts just like -.I bzcat, -except that a header is printed before each file. -.SH FILES -.DT -/etc/termcap Terminal data base -.SH "SEE ALSO" -more(1), less(1), bzip2(1), bzdiff(1), bzgrep(1) diff --git a/thirdparty/bzip2/man/meson.build b/thirdparty/bzip2/man/meson.build deleted file mode 100644 index cd0fafc65..000000000 --- a/thirdparty/bzip2/man/meson.build +++ /dev/null @@ -1,19 +0,0 @@ -install_man('bzip2.1', 'bzgrep.1', 'bzdiff.1', 'bzmore.1') - -# Install copies of some of the man files -man1dir = join_paths(get_option('prefix'), get_option('mandir'), 'man1') -foreach m : [['bzip2.1', ['bunzip2.1', 'bzcat']], - ['bzgrep.1', ['bzegrep.1', 'bzfgrep.1']], - ['bzmore.1', ['bzless.1']], - ['bzdiff.1', ['bzcmp.1']]] - _input = m[0] - foreach o : m[1] - configure_file( - input : _input, - output : o, - copy : true, - install : true, - install_dir : man1dir, - ) - endforeach -endforeach diff --git a/thirdparty/bzip2/meson.build b/thirdparty/bzip2/meson.build deleted file mode 100644 index 756d71ead..000000000 --- a/thirdparty/bzip2/meson.build +++ /dev/null @@ -1,177 +0,0 @@ -project( - 'bzip2', - ['c'], - version : '1.1.0', - meson_version : '>= 0.56.0', - default_options : ['c_std=c89', 'warning_level=1'], -) - -conf_data = configuration_data() -conf_data.set('BZ_VERSION', meson.project_version()) -configure_file( - input: 'bz_version.h.in', - output: 'bz_version.h', - configuration: conf_data -) - -cc = meson.get_compiler('c') -add_project_arguments(cc.get_supported_arguments([ - # Please keep this list in sync with CMakeLists.txt - '-Wall', - '-Wextra', - '-Wmissing-prototypes', - '-Wstrict-prototypes', - '-Wmissing-declarations', - '-Wpointer-arith', - '-Wdeclaration-after-statement', - '-Wformat-security', - '-Wwrite-strings', - '-Wshadow', - '-Winline', - '-Wnested-externs', - '-Wfloat-equal', - '-Wundef', - '-Wendif-labels', - '-Wempty-body', - '-Wcast-align', - '-Wclobbered', - '-Wvla', - '-Wpragmas', - '-Wunreachable-code', - '-Waddress', - '-Wattributes', - '-Wdiv-by-zero', - '-Wshorten-64-to-32', - '-Wconversion', - '-Wextended-offsetof', - '-Wformat-nonliteral', - '-Wlanguage-extension-token', - '-Wmissing-field-initializers', - '-Wmissing-noreturn', - '-Wmissing-variable-declarations', - # '-Wpadded', # Not used because we cannot change public structs - '-Wsign-conversion', - # '-Wswitch-enum', # Not used because this basically disallows default case - '-Wunreachable-code-break', - '-Wunused-macros', - '-Wunused-parameter', - '-Wredundant-decls', - '-Wheader-guard', - '-Wno-format-nonliteral', # This is required because we pass format string as "const char*. - ]), - language : 'c', -) - -add_project_arguments('-D_GNU_SOURCE', language : 'c') - -os_defines = [] -if host_machine.system() == 'windows' - os_defines += '-DBZ_LCCWIN32=1' - os_defines += '-DBZ_UNIX=0' -else - os_defines += '-DBZ_LCCWIN32=0' - os_defines += '-DBZ_UNIX=1' -endif - -c_args = [] -# The or is a workaround for https://github.com/mesonbuild/meson/issues/5530 -if cc.has_function_attribute('visibility') or (cc.get_id() == 'clang' and host_machine.system() == 'darwin') - c_args += '-DBZ_EXTERN=__attribute__((__visibility__("default")))' -endif - -bz_sources = ['blocksort.c', 'huffman.c', 'crctable.c', 'randtable.c', 'compress.c', 'decompress.c', 'bzlib.c'] - -## Library versioning -## -## New package version: -## revision += 1 -## -## New interfaces: -## current += 1 -## revision = 0 -## age += 1 -## -## Deleted/changed interfaces: -## current += 1 -## revision = 0 -## age = 0 -## -## KEEP THESE IN SYNC WITH CMakeLists.txt OR STUFF WILL BREAK! -bz2_lt_current = 1 -bz2_lt_revision = 9 -bz2_lt_age = 0 - -bz2_soversion = bz2_lt_current - bz2_lt_age -bz2_lt_version = '@0@.@1@.@2@'.format(bz2_soversion, bz2_lt_age, bz2_lt_revision) - -if ['msvc', 'clang-cl', 'intel-cl'].contains(cc.get_id()) - libbzip2 = library( - 'bz2', - bz_sources, - c_args : c_args, - vs_module_defs : 'libbz2.def', - version : bz2_lt_version, - soversion : bz2_soversion, - install : true, - ) -else - libbzip2 = library( - 'bz2', - bz_sources, - c_args : c_args, - gnu_symbol_visibility : 'hidden', - version : bz2_lt_version, - soversion : bz2_soversion, - install : true, - ) -endif - -bzip2 = executable( - 'bzip2', - ['bzip2.c'], - link_with : [libbzip2], - install : true, - c_args : os_defines, -) - -executable( - 'bzip2recover', - ['bzip2recover.c'], - link_with : [libbzip2], - install : true, - c_args : os_defines, -) - -## Install wrapper scripts -install_data( - 'bzgrep', 'bzmore', 'bzdiff', - install_dir : get_option('bindir'), - install_mode : 'rwxr-xr-x', -) - -## Create aliases. Use links if possible, but copies if not. -# Copies are mainly meant for windows, which doesn't have symlinks. -bindir = get_option('bindir') -targets = [['bzmore', 'bzless'], ['bzdiff', 'bzcmp'], ['bzgrep', 'bzegrep', 'bzfgrep'], - ['bzip2', 'bunzip2', 'bzcat']] -extra_args = [] -if host_machine.system() != 'windows' and build_machine.system() != 'windows' - extra_args = '--use-links' -endif -foreach t : targets - meson.add_install_script('install_links.py', get_option('bindir'), t, extra_args) -endforeach - -## Generate pkg-config automaically from built library information -pkg = import('pkgconfig') -pkg.generate( - libbzip2, - description : 'Lossless, block-sorting data compression', -) - -## install headers -install_headers('bzlib.h') - -subdir('man') -subdir('docs') -subdir('tests') diff --git a/thirdparty/bzip2/meson_options.txt b/thirdparty/bzip2/meson_options.txt deleted file mode 100644 index 0a147a327..000000000 --- a/thirdparty/bzip2/meson_options.txt +++ /dev/null @@ -1,5 +0,0 @@ -option( - 'docs', - type : 'feature', - description : 'generate documentation in html, pdf, and ps format', -) diff --git a/thirdparty/bzip2/mk251.c b/thirdparty/bzip2/mk251.c deleted file mode 100644 index 439fd9111..000000000 --- a/thirdparty/bzip2/mk251.c +++ /dev/null @@ -1,31 +0,0 @@ - -/* Spew out a long sequence of the byte 251. When fed to bzip2 - versions 1.0.0 or 1.0.1, causes it to die with internal error - 1007 in blocksort.c. This assertion misses an extremely rare - case, which is fixed in this version (1.0.2) and above. -*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.1.0 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward - - 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 - -int main () -{ - int i; - for (i = 0; i < 48500000 ; i++) - putchar(251); - return 0; -} diff --git a/thirdparty/bzip2/patches-not-included.txt b/thirdparty/bzip2/patches-not-included.txt deleted file mode 100644 index 9811aef6e..000000000 --- a/thirdparty/bzip2/patches-not-included.txt +++ /dev/null @@ -1,7 +0,0 @@ -These are the patches from openSUSE that are not included in this Git -repository: - -* bzip2-point-to-doc-pkg.patch - modifies the README file to mention a - bzip2-doc package instead of the bzip2.txt file from the source - distribution. This is suitable for distributions which repackage - the original files into different packages. diff --git a/thirdparty/bzip2/randtable.c b/thirdparty/bzip2/randtable.c deleted file mode 100644 index de6517db4..000000000 --- a/thirdparty/bzip2/randtable.c +++ /dev/null @@ -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.1.0 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward - - 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 ---*/ -/*-------------------------------------------------------------*/ diff --git a/thirdparty/bzip2/spewG.c b/thirdparty/bzip2/spewG.c deleted file mode 100644 index 8b060ee7d..000000000 --- a/thirdparty/bzip2/spewG.c +++ /dev/null @@ -1,54 +0,0 @@ - -/* spew out a thoroughly gigantic file designed so that bzip2 - can compress it reasonably rapidly. This is to help test - support for large files (> 2GB) in a reasonable amount of time. - I suggest you use the undocumented --exponential option to - bzip2 when compressing the resulting file; this saves a bit of - time. Note: *don't* bother with --exponential when compressing - Real Files; it'll just waste a lot of CPU time :-) - (but is otherwise harmless). -*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.1.0 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward - - 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. ------------------------------------------------------------------- */ - - -#define _FILE_OFFSET_BITS 64 - -#include -#include - -/* The number of megabytes of junk to spew out (roughly) */ -#define MEGABYTES 5000 - -#define N_BUF 1000000 -char buf[N_BUF]; - -int main ( int argc, char** argv ) -{ - int ii, kk, p; - srandom(1); - setbuffer ( stdout, buf, N_BUF ); - for (kk = 0; kk < MEGABYTES * 515; kk+=3) { - p = 25+random()%50; - for (ii = 0; ii < p; ii++) - printf ( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ); - for (ii = 0; ii < p-1; ii++) - printf ( "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" ); - for (ii = 0; ii < p+1; ii++) - printf ( "ccccccccccccccccccccccccccccccccccccc" ); - } - fflush(stdout); - return 0; -} diff --git a/thirdparty/bzip2/tests/CMakeLists.txt b/thirdparty/bzip2/tests/CMakeLists.txt deleted file mode 100644 index b7c4b0424..000000000 --- a/thirdparty/bzip2/tests/CMakeLists.txt +++ /dev/null @@ -1,75 +0,0 @@ - -# -# Paths to pass to our tests via environment variables -# -if(WIN32) - file(TO_NATIVE_PATH ${CMAKE_SOURCE_DIR} SOURCE) - file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR} BUILD) - file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR} TMP) - - if(ENABLE_STATIC_LIB) - file(TO_NATIVE_PATH $ LIBBZ2) - else() - file(TO_NATIVE_PATH $ LIBBZ2) - endif() - - file(TO_NATIVE_PATH $ BZIP2) - -else() # Not WIN32 - if(ENABLE_SHARED_LIB) - set(LD_LIBRARY_PATH $:$ENV{LD_LIBRARY_PATH}) - endif() - - set(SOURCE ${CMAKE_SOURCE_DIR}) - set(BUILD ${CMAKE_BINARY_DIR}) - set(TMP ${CMAKE_CURRENT_BINARY_DIR}) - - if(ENABLE_STATIC_LIB) - set(LIBBZ2 $) - else() - set(LIBBZ2 $) - endif() - - set(BZIP2 $) - -endif() - -set(ENVIRONMENT - PYTHONTRACEMALLOC=1 VERSION=${PROJECT_VERSION} - LD_LIBRARY_PATH=${LD_LIBRARY_PATH} - DYLD_LIBRARY_PATH=${LD_LIBRARY_PATH} - PATH_SOURCE=${SOURCE} - PATH_BUILD=${BUILD} - PATH_TMP=${TMP} - PATH_LIBBZ2=${LIBBZ2} - PATH_BZIP2=${BZIP2} -) - -# -# The Tests -# ~~~~~~~~~ -# -# Run all tests with: `ctest` -# or: `ctest -V` for verbose output -# -# Run a specific test with the `-R` option, like this: -# `ctest -V -R quick -# - -add_test(NAME quick COMMAND ${PythonTest_COMMAND};quick_test.py - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) -if(Valgrind_FOUND) - set_property(TEST quick PROPERTY ENVIRONMENT ${ENVIRONMENT} VALGRIND=${Valgrind_EXECUTABLE}) -else() - set_property(TEST quick PROPERTY ENVIRONMENT ${ENVIRONMENT}) -endif() - -if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/input/bzip2-testfiles/README.md) - add_test(NAME large COMMAND ${PythonTest_COMMAND};large_test.py - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) - if(Valgrind_FOUND) - set_property(TEST large PROPERTY ENVIRONMENT ${ENVIRONMENT} VALGRIND=${Valgrind_EXECUTABLE}) - else() - set_property(TEST large PROPERTY ENVIRONMENT ${ENVIRONMENT}) - endif() -endif() diff --git a/thirdparty/bzip2/tests/README.md b/thirdparty/bzip2/tests/README.md deleted file mode 100644 index b28b21c08..000000000 --- a/thirdparty/bzip2/tests/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# Tests - -BZip2 has two test suites: - -1. The quick test suite is the original test suite. It is small and runs very - quickly to verify correct compression and decompression of simple files. - -2. The large test suite is a large collection of test files gathered from - various sources. It includes not only good `.bz2` files but also bad ones. - -The quick tests will run under Valgrind if Valgrind is installed on the system -and was discovered by CMake/Meson at build time. If you installed Valgrind after -build time, you may have to do a clean build for the Valgrind to be detected. - -The slow tests have Valgrind disabled, because with it enabled it takes upwards -of 35 minutes to run. - -## Running the Tests - -Run the tests using CMake or Meson's test commands. - -For CMake: - ```sh - ctest -V - ``` - -For Meson: - ```sh - meson test -C builddir --print-errorlogs - ``` - -## Quick Test Suite - -The quick test suite is a small set of `.bz2` compressed files and original -reference files. - -BZip2 must be able to: - -1. Compress the reference files without error and decompress the newly created - compressed version into a file that matches the original reference file. - Multiple compression modes are tested. - -2. Decompress the `.bz2` files without error. The decompressed file must match - the original reference file. - -## Large Test Suite - -The large test suite tests a collection of "interesting" `.bz2` files that can -be used to test bzip2 works correctly. They come from different projects. - -The test files for the Large Test Suite are in a separate repository that was -added here as a Git submodule: https://gitlab.com/bzip2/bzip2-testfiles - -To run the larger test suite, you must first pull down the submodule before -running `ctest`. - -E.g.: -```sh -git submodule update --init --recursive -``` - -For each `.bz2` file found it is decompressed, recompressed and decompressed -again. Once with the default bzip2 settings and once in `--small` (`-s`) mode. -Each time after decompression, the resulting file is checked against the MD5 -reference hash to verify that decompression worked correctly. - -For each `.bz2.bad` file, decompression is also tried twice, first in default- -mode and again in small-mode. The bzip2 binary is expected to return either `1` -or `2` as exit status. Any other exit code is interpreted as failure. diff --git a/thirdparty/bzip2/tests/input/quick/sample1.bz2 b/thirdparty/bzip2/tests/input/quick/sample1.bz2 deleted file mode 100644 index 5007dbfb7..000000000 --- a/thirdparty/bzip2/tests/input/quick/sample1.bz2 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4b442283e085497c528c0122c7ec64bf12aac422b3faff57b97de3378b7a7a4 -size 32348 diff --git a/thirdparty/bzip2/tests/input/quick/sample1.ref b/thirdparty/bzip2/tests/input/quick/sample1.ref deleted file mode 100644 index a56e52b77..000000000 Binary files a/thirdparty/bzip2/tests/input/quick/sample1.ref and /dev/null differ diff --git a/thirdparty/bzip2/tests/input/quick/sample2.bz2 b/thirdparty/bzip2/tests/input/quick/sample2.bz2 deleted file mode 100644 index 942e4661b..000000000 --- a/thirdparty/bzip2/tests/input/quick/sample2.bz2 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c74d44033766ea66171f51bd2ce6e3ad9ce4e0749e03ee4bee3074ab2a4b9c7f -size 73732 diff --git a/thirdparty/bzip2/tests/input/quick/sample2.ref b/thirdparty/bzip2/tests/input/quick/sample2.ref deleted file mode 100644 index 34af95839..000000000 Binary files a/thirdparty/bzip2/tests/input/quick/sample2.ref and /dev/null differ diff --git a/thirdparty/bzip2/tests/input/quick/sample3.bz2 b/thirdparty/bzip2/tests/input/quick/sample3.bz2 deleted file mode 100644 index a5445e808..000000000 --- a/thirdparty/bzip2/tests/input/quick/sample3.bz2 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fc60721da6329daa4bfe5ef3b32d2de0bebac626ce8522ae033dc3a9296c7779 -size 235 diff --git a/thirdparty/bzip2/tests/input/quick/sample3.ref b/thirdparty/bzip2/tests/input/quick/sample3.ref deleted file mode 100644 index 775a2f68e..000000000 --- a/thirdparty/bzip2/tests/input/quick/sample3.ref +++ /dev/null @@ -1,30007 +0,0 @@ -This file is exceedingly boring. If you find yourself -reading it, please (1) take it from me that you can safely -guess what the rest of the file says, and (2) seek professional -help. - -ps. there are no further sarcastic remarks in this file. - -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh -ugh diff --git a/thirdparty/bzip2/tests/large_test.py b/thirdparty/bzip2/tests/large_test.py deleted file mode 100644 index 322774b9f..000000000 --- a/thirdparty/bzip2/tests/large_test.py +++ /dev/null @@ -1,134 +0,0 @@ -#!/usr/bin/env python3 -''' -Test correct decompression of good and bad .bz2 files found in: -https://gitlab.com/bzip2/bzip2-testfiles -''' - -__copyright__ = 'Copyright (C) 2022 Micah Snyder' - -from hashlib import md5 -import os -from pathlib import Path - -import testcase - -TRY_VALGRIND = False # You can enable this if you want, but it will take a very - # long time to run, like a half hour or more. - -path_source = Path(os.getenv('PATH_SOURCE')) - -def generate_test_function(*args): - ''' - Generate a test with the given args. - ''' - def foo(self): - self.run_test(*args) - return foo - -class TC(testcase.TestCase): - - def run_test(self, sample: Path, extra_arg: str = ''): - ''' - Verify correct behavior when bzip2 tries to decompress the given file. - ''' - if sample.suffix == '.bad': - # Try to decompress, with the expectation that it will fail, gracefully: - # - First with default settings - # - Second time using `--small` mode - - # Decompress. We can keep the OG file. - cmd = [str(TC.bzip2), '--decompress', '--keep', '--stdout', str(sample)] - (ec, out, err) = self.execute(cmd, try_valgrind=TRY_VALGRIND) - - # Check that bzip2 failed gracefully. - assert ec == 2 or ec == 1 - - # Decompress small-mode. We can keep the OG file. - cmd = [str(TC.bzip2), '--decompress', '--small', '--keep', '--stdout', str(sample)] - (ec, out, err) = self.execute(cmd, try_valgrind=TRY_VALGRIND) - - # Check that bzip2 failed gracefully. - assert ec == 2 or ec == 1 - - elif sample.suffix == '.bz2': - # Try to decompress, with the expectation that it will succeed and - # that the decompressed file's MD5 matches the reference file. - # - # Then, compress the result again, and decompress it again, verifying - # once more that the (second) decompressed file's MD5 matches the reference file. - - # Verify that the decompressed MD5 reference file DOES exist. - with (sample.parent / (sample.stem + '.md5')).open('r') as md5_file: - - # Get the reference hash - ref_hash = md5_file.read().split(' ')[0].strip() - - # Decompress. We can keep the OG file. - cmd = [str(TC.bzip2), '--decompress', '--keep', '--stdout', str(sample)] - if extra_arg != '': - cmd.append(extra_arg) - (ec, out, err) = self.execute(cmd, try_valgrind=TRY_VALGRIND) - - # Check that bzip2 thinks it succeeded. - assert ec == 0 - - # Verify that the decompressed file matches the .md5 reference. - out_hash = md5(out).hexdigest() - assert out_hash == ref_hash - - # Write it to a temp file - tempfile_path = TC.path_tmp / (sample.name + '.decompressed') - print(f'Writing decompressed {sample.name} file to disk as {tempfile_path.name}...') - with tempfile_path.open('wb') as tmpfile: - tmpfile.write(out) - - # Compress. No need to keep the temp file. - cmd = [str(TC.bzip2), '--compress', '--stdout', str(tempfile_path)] - if extra_arg != '': - cmd.append(extra_arg) - (ec, out, err) = self.execute(cmd, try_valgrind=TRY_VALGRIND) - - # Check that bzip2 thinks it succeeded. - assert ec == 0 - - # Write it to a temp file - tempfile_path = TC.path_tmp / (tempfile_path.name + '.bz2') - print(f'Writing compressed {sample.name} file to disk as {tempfile_path.name}...') - with tempfile_path.open('wb') as tmpfile: - tmpfile.write(out) - - # Decompress the compressed tempfile. No point keeping it. - cmd = [str(TC.bzip2), '--decompress', '--stdout', str(tempfile_path)] - if extra_arg != '': - cmd.append(extra_arg) - (ec, out, err) = self.execute(cmd, try_valgrind=TRY_VALGRIND) - - # Check that bzip2 thinks it succeeded. - assert ec == 0 - - # Calculate hash of decompressed file. - out_hash = md5(out).hexdigest() - - # Verify the decomp-comp-decomped file still matches the ref hash. - assert out_hash == ref_hash - - -# loop through directories in 'bzip2/tests/input/bzip2-testfiles'... -# -# For each of those directories, run a test on the files within that have -# the '.bad' or '.bz2' suffix. -testfiles_path = path_source / 'tests' / 'input' / 'bzip2-testfiles' -if testfiles_path.is_dir: - for sample in testfiles_path.glob('**/*'): - if sample.suffix == '.bad' or sample.suffix == '.bz2': - # Generate a test function for the sample. - bug_validation_test = generate_test_function(sample) - - # Add the test function to the test class. - setattr(TC, f'test_{sample.parent.name}_{sample.name}', bug_validation_test) - - # Generate a test function for the sample. - bug_validation_test = generate_test_function(sample, '--small') - - # Add the test function to the test class. - setattr(TC, f'test_{sample.parent.name}_{sample.name}_small', bug_validation_test) diff --git a/thirdparty/bzip2/tests/meson.build b/thirdparty/bzip2/tests/meson.build deleted file mode 100644 index 37b9631b9..000000000 --- a/thirdparty/bzip2/tests/meson.build +++ /dev/null @@ -1,46 +0,0 @@ -prog_python = import('python').find_installation('python3') - -r = run_command(prog_python, '-m', 'pytest', '--help', check: false) -errortxt = r.stderr().strip() -if errortxt.contains('No module named pytest') - error('pytest for python3 is required to run the tests. Please `pip3 install pytest` and try again.') -endif - -valgrind = find_program('valgrind', required : false) - -fs = import('fs') -env = environment() - -environment = [ - 'PYTHONTRACEMALLOC=1', - 'VERSION=' + meson.project_version(), - 'LD_LIBRARY_PATH=' + fs.parent(libbzip2.full_path()), - 'DYLD_LIBRARY_PATH=' + fs.parent(libbzip2.full_path()), - 'PATH_SOURCE=' + meson.project_source_root(), - 'PATH_BUILD=' + meson.project_build_root(), - 'PATH_TMP=' + meson.current_build_dir(), - 'PATH_LIBBZ2=' + libbzip2.full_path(), - 'PATH_BZIP2=' + bzip2.full_path(), -] - -if valgrind.found() == true - environment += 'VALGRIND=' + valgrind.full_path() -endif - -test( - 'quick_test.py', - prog_python, - args : ['-m', 'pytest', '-vv', meson.current_source_dir() + '/quick_test.py'], - env : environment, - timeout : 500 -) - -if (fs.exists(meson.current_source_dir() + '/input/bzip2-testfiles/README.md')) - test( - 'large_test.py', - prog_python, - args : ['-m', 'pytest', '-vv', meson.current_source_dir() + '/large_test.py'], - env : environment, - timeout : 10000 - ) -endif diff --git a/thirdparty/bzip2/tests/quick_test.py b/thirdparty/bzip2/tests/quick_test.py deleted file mode 100644 index caf83a0c4..000000000 --- a/thirdparty/bzip2/tests/quick_test.py +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env python3 -''' -basic compression/decompression tests. -''' - -__copyright__ = 'Copyright (C) 2022 Micah Snyder' - -from hashlib import md5 -import os -from pathlib import Path - -import testcase - -TRY_VALGRIND = True - -path_source = Path(os.getenv('PATH_SOURCE')) - -def generate_test_function(*args): - ''' - Generate a test with the given args. - ''' - def foo(self): - self.run_test(*args) - return foo - -class TC(testcase.TestCase): - - def tearDown(self): - super().tearDown() - self.verify_valgrind_log() - - def run_test(self, sample: Path, block_size: int = 0): - ''' - Verify correct behavior when bzip2 tries to decompress the given file. - - Note: block_size is only used for the compression test. - ''' - if sample.suffix == '.ref': - # Try to decompress, with the expectation that it will fail, gracefully: - # - First with default settings - # - Second time using `--small` mode - - # Compress. We can keep the OG file. - cmd = [str(TC.bzip2), '--compress', str(block_size), '--keep', '--stdout', str(sample)] - (ec, out, err) = self.execute(cmd, try_valgrind=TRY_VALGRIND) - - # Check that bzip2 thinks it succeeded. - assert ec == 0 - - # Write it to a temp file - tempfile_path = TC.path_tmp / (sample.name + '.bz2') - print(f'Writing compressed {sample.name} file to disk as {tempfile_path.name}...') - with tempfile_path.open('wb') as tmpfile: - tmpfile.write(out) - - # Decompress the compresed tempfile. No point keeping it. - cmd = [str(TC.bzip2), '--decompress', '--stdout', str(tempfile_path)] - (ec, out, err) = self.execute(cmd, try_valgrind=TRY_VALGRIND) - - # Check that bzip2 thinks it succeeded. - assert ec == 0 - - # Calculate hash of decompressed file. - out_hash = md5(out).hexdigest() - - # Verify that the MD5 of the original reference file matches MD5 of - # the compressed & decompressed file. - with sample.open('rb') as reffile: - # Calcualte hash of reference file. - refcontents = reffile.read() - ref_hash = md5(refcontents).hexdigest() - - print(f'Checking that {tempfile_path.name} matches {sample.name} when decompressed...') - assert out_hash == ref_hash, \ - 'decompression output and reference file differ:\n' + \ - TC.hex_compare(out, refcontents) - - elif sample.suffix == '.bz2': - # Try to decompress, with the expectation that it will succeed and - # that the decompressed file's MD5 matches the reference file. - # - # Then, compress the result again, and decompress it again, verifying - # once more that the (second) decompressed file's MD5 matches the reference file. - - # Verify that the MD5 of the original reference file matches MD5 of - # the decompressed file. - reffile_path = sample.parent / (sample.stem + '.ref') - with reffile_path.open('rb') as reffile: - # Calcualte hash of reference file. - refcontents = reffile.read() - ref_hash = md5(refcontents).hexdigest() - - # Decompress. We can keep the OG file. - cmd = [str(TC.bzip2), '--decompress', '--keep', '--stdout', str(sample)] - (ec, out, err) = self.execute(cmd, try_valgrind=TRY_VALGRIND) - - # Check that bzip2 thinks it succeeded. - assert ec == 0 - - # Calculate hash of decompressed file. - out_hash = md5(out).hexdigest() - - # Verify that the decompressed file matches the MD5 of the original reference file. - print(f'Checking that {sample.name} matches {reffile_path.name} when decompressed...') - assert out_hash == ref_hash, \ - 'decompression output and reference file differ:\n' + \ - TC.hex_compare(out, refcontents) - - -# loop through directories in 'bzip2/tests/input/quick'... -# -# For each of those directories, run a test on the files within that have -# the '.bad' or '.bz2' suffix. -testfiles_path = path_source / 'tests' / 'input' / 'quick' -if testfiles_path.is_dir: - for sample in testfiles_path.glob('**/*'): - - if sample.suffix == '.ref': - for block_size in [-1, -2, -3]: - # Generate a test function for the sample. - bug_validation_test = generate_test_function(sample, block_size) - - # Add the test function to the test class. - setattr(TC, f'test_comp_decomp_{sample.name}_{abs(block_size)}', bug_validation_test) - - elif sample.suffix == '.bz2': - # Generate a test function for the sample. - bug_validation_test = generate_test_function(sample) - - # Add the test function to the test class. - setattr(TC, f'test_decomp_only_{sample.name}', bug_validation_test) diff --git a/thirdparty/bzip2/tests/testcase.py b/thirdparty/bzip2/tests/testcase.py deleted file mode 100644 index 725ba5972..000000000 --- a/thirdparty/bzip2/tests/testcase.py +++ /dev/null @@ -1,215 +0,0 @@ - -''' -Wrapper for Python's unittest.TestCase that sets up BZip2 testing environment. -''' - -__copyright__ = "Copyright (C) 2022 Micah Snyder" - -from math import ceil -import os -from pathlib import Path -import platform -import shutil -import subprocess -import tempfile -import unittest -from typing import Tuple, Union, NamedTuple - -# Use older Python 3.5 syntax. -CmdResult = NamedTuple('CmdResult', [('ec', int), ('out', bytes), ('err', bytes)]) - -class TestCase(unittest.TestCase): - - version = "" - - path_source = None - path_build = None - path_tmp = None - - bzip2 = None - - valgrind = "" # Not 'None' because we'll use this variable even if valgrind not found. - valgrind_args = [] - - original_working_directory = "" - - @classmethod - def setUpClass(cls): - ''' - Prepare test environment: - - Create a temporary testing directory. - - Get paths needed for tests from environment variables. - ''' - cls.operating_system = platform.platform().split("-")[0].lower() - - # The bzip2 program uses the BZIP and BZIP2 environment variables as - # additional input. We must purge them to prevent OS environment - # variables from affecting the test suite. - os.environ.pop('BZIP', None) - os.environ.pop('BZIP2', None) - - # Version may be used for testing bzip2 --version output, etc. - cls.version = os.getenv("VERSION") - if cls.version == None: - raise Exception("VERSION environment variable not defined! Aborting...") - - # Get test paths from environment variables. - cls.path_source = Path(os.getenv("PATH_SOURCE")) - cls.path_build = Path(os.getenv("PATH_BUILD")) - cls.bzip2 = Path(os.getenv("PATH_BZIP2")) if os.getenv("PATH_BZIP2") != None else None - - # Generate temp directory - cls.path_tmp = Path(tempfile.mkdtemp(prefix=(cls.__name__ + "-"), dir=os.getenv("TMP"))) - - # Enable valgrind testing if VALGRIND variable set to path of Valgrind executable. - if os.getenv('VALGRIND') != None: - valgrind = Path(os.getenv("VALGRIND")) - - if valgrind.is_file(): - cls.valgrind = valgrind - - logfile = cls.path_tmp / 'valgrind.log' - cls.valgrind_args = [ - '-v', - '--trace-children=yes', - '--track-fds=yes', - '--leak-check=full', - '--gen-suppressions=all', - '--show-leak-kinds=definite', - '--errors-for-leak-kinds=definite', - f'--log-file={logfile}', - '--error-exitcode=123', - ] - - # Perform all tests with cwd set to the cls.path_tmp, created above. - cls.original_working_directory = os.getcwd() - os.chdir(cls.path_tmp) - - @classmethod - def tearDownClass(cls): - ''' - Clean up after ourselves, - Delete the generated tmp directory. - ''' - print("") - - # Restore current working directory before deleting cls.path_tmp. - os.chdir(cls.original_working_directory) - - if None == os.getenv("KEEPTEMP"): - try: - shutil.rmtree(cls.path_tmp) - print("Removed tmp directory: {}".format(cls.path_tmp)) - except Exception: - print("No tmp directory to clean up.") - - def setUp(self): - print('\n') - - def tearDown(self): - print('\n') - - def execute(self, cmd: list, try_valgrind: bool = True) -> CmdResult: - ''' - Execute a subprocess.Popen list of commands. - Return a tuple of - ''' - # Use valgrind if we have it. - if try_valgrind and self.valgrind != '': - cmd = [str(self.valgrind),] + self.valgrind_args + cmd - - print(f"Running: {' '.join(cmd)}\n") - p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - out, err = p.communicate() - - # Check the valgrind log for errors. - if try_valgrind and self.valgrind != '': - self.verify_valgrind_log() - - return CmdResult(p.returncode, out, err) - - def verify_valgrind_log(self, log_file: Union[Path, None]=None): - ''' - Check if valgrind log file contains errors. - If valgrind not enabled this is basically a nop. - ''' - if self.valgrind == "": - return - - if log_file == None: - log_file = self.path_tmp / 'valgrind.log' - - if not log_file.exists(): - raise AssertionError('{} not found. Valgrind failed to run?'.format(log_file)) - - errors = False - print('Verifying {}...'.format(log_file)) - try: - with log_file.open('r') as the_log: - assert 'ERROR SUMMARY: 0 errors' not in the_log - except AssertionError: - print("*" * 80) - print('Valgrind test failed!'.center(80, ' ')) - print('Please submit a bug report with this log to https://gitlab.com/bzip2/bzip2/issues'.center(69, ' ')) - print(str(log_file).center(80, ' ')) - print("*" * 80) - errors = True - finally: - with log_file.open('r') as log: - found_summary = False - for line in log.readlines(): - if 'ERROR SUMMARY' in line: - found_summary = True - if (found_summary or errors) and len(line) < 500: - print(line.rstrip('\n')) - if errors: - raise AssertionError('Valgrind test FAILED!') - - @staticmethod - def hex_compare(actual: bytes, expected: bytes, size: int = 16): - ''' - Return string with hex comparison of two buffers - ''' - a_lines = ceil(float(len(actual)) / float(size)) - e_lines = ceil(float(len(expected)) / float(size)) - lines = max(a_lines, e_lines) - - comparison = ' ' + \ - f'output ({len(actual)}):'.ljust(size*2 + 3) + \ - f'expected ({len(expected)}):\n' - - def render_slice(to_print, to_compare): - line = '' - for byte in range(0, size): - if byte == size / 2: - line += ' ' - - if byte < len(to_print): - if byte >= len(to_compare) or to_print[byte] != to_compare[byte]: - line += '\x1b[1;33m{:02x}\x1b[0m'.format(to_print[byte]) # bold yellow - else: - line += '{:02x}'.format(to_print[byte]) # plain - else: - line += ' ' - - return line - - prev_is_dots = False - for line in range(0, lines): - a_line = actual[line * size : line * size + size] - e_line = expected[line * size : line * size + size] - - if a_line == e_line: - if prev_is_dots == False: - comparison += " ...\n" - prev_is_dots = True - else: - text_line = '{:8d}: {} {}'.format( - line * size, - render_slice(a_line, e_line), - render_slice(e_line, a_line) - ) - comparison += text_line + '\n' - prev_is_dots = False - - return comparison + '\n' diff --git a/thirdparty/bzip2/unzcrash.c b/thirdparty/bzip2/unzcrash.c deleted file mode 100644 index 36a36f5af..000000000 --- a/thirdparty/bzip2/unzcrash.c +++ /dev/null @@ -1,141 +0,0 @@ - -/* A test program written to test robustness to decompression of - corrupted data. Usage is - unzcrash filename - and the program will read the specified file, compress it (in memory), - and then repeatedly decompress it, each time with a different bit of - the compressed data inverted, so as to test all possible one-bit errors. - This should not cause any invalid memory accesses. If it does, - I want to know about it! - - PS. As you can see from the above description, the process is - incredibly slow. A file of size eg 5KB will cause it to run for - many hours. -*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.1.0 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward - - 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 -#include -#include "bzlib.h" - -#define M_BLOCK 1000000 - -typedef unsigned char uchar; - -#define M_BLOCK_OUT (M_BLOCK + 1000000) -uchar inbuf[M_BLOCK]; -uchar outbuf[M_BLOCK_OUT]; -uchar zbuf[M_BLOCK + 600 + (M_BLOCK / 100)]; - -int nIn, nOut, nZ; - -static char *bzerrorstrings[] = { - "OK" - ,"SEQUENCE_ERROR" - ,"PARAM_ERROR" - ,"MEM_ERROR" - ,"DATA_ERROR" - ,"DATA_ERROR_MAGIC" - ,"IO_ERROR" - ,"UNEXPECTED_EOF" - ,"OUTBUFF_FULL" - ,"???" /* for future */ - ,"???" /* for future */ - ,"???" /* for future */ - ,"???" /* for future */ - ,"???" /* for future */ - ,"???" /* for future */ -}; - -void flip_bit ( int bit ) -{ - int byteno = bit / 8; - int bitno = bit % 8; - uchar mask = 1 << bitno; - //fprintf ( stderr, "(byte %d bit %d mask %d)", - // byteno, bitno, (int)mask ); - zbuf[byteno] ^= mask; -} - -int main ( int argc, char** argv ) -{ - FILE* f; - int r; - int bit; - int i; - - if (argc != 2) { - fprintf ( stderr, "usage: unzcrash filename\n" ); - return 1; - } - - f = fopen ( argv[1], "r" ); - if (!f) { - fprintf ( stderr, "unzcrash: can't open %s\n", argv[1] ); - return 1; - } - - nIn = fread ( inbuf, 1, M_BLOCK, f ); - fprintf ( stderr, "%d bytes read\n", nIn ); - - nZ = M_BLOCK; - r = BZ2_bzBuffToBuffCompress ( - zbuf, &nZ, inbuf, nIn, 9, 0, 30 ); - - assert (r == BZ_OK); - fprintf ( stderr, "%d after compression\n", nZ ); - - for (bit = 0; bit < nZ*8; bit++) { - fprintf ( stderr, "bit %d ", bit ); - flip_bit ( bit ); - nOut = M_BLOCK_OUT; - r = BZ2_bzBuffToBuffDecompress ( - outbuf, &nOut, zbuf, nZ, 0, 0 ); - fprintf ( stderr, " %d %s ", r, bzerrorstrings[-r] ); - - if (r != BZ_OK) { - fprintf ( stderr, "\n" ); - } else { - if (nOut != nIn) { - fprintf(stderr, "nIn/nOut mismatch %d %d\n", nIn, nOut ); - return 1; - } else { - for (i = 0; i < nOut; i++) - if (inbuf[i] != outbuf[i]) { - fprintf(stderr, "mismatch at %d\n", i ); - return 1; - } - if (i == nOut) fprintf(stderr, "really ok!\n" ); - } - } - - flip_bit ( bit ); - } - -#if 0 - assert (nOut == nIn); - for (i = 0; i < nOut; i++) { - if (inbuf[i] != outbuf[i]) { - fprintf ( stderr, "difference at %d !\n", i ); - return 1; - } - } -#endif - - fprintf ( stderr, "all ok\n" ); - return 0; -} diff --git a/thirdparty/bzip2/version.rc b/thirdparty/bzip2/version.rc deleted file mode 100644 index 3476c715f..000000000 --- a/thirdparty/bzip2/version.rc +++ /dev/null @@ -1,48 +0,0 @@ -#include - -LANGUAGE 0x09,0x01 - -1 VERSIONINFO - FILEVERSION 1,0,7,0 - PRODUCTVERSION 1,0,7,0 - FILEFLAGSMASK 0x3fL - FILEFLAGS 0x00L - FILEOS VOS__WINDOWS32 -#if defined(BZ21DLL) - FILETYPE VFT_DLL -#else - FILETYPE VFT_APP -#endif - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - // VALUE "Comments", "\0" - VALUE "CompanyName", "bzip2, https://gitlab.com/bzip2/bzip2\0" - VALUE "FileDescription", "bzip2\0" - VALUE "FileVersion", "1.1.0\0" -#if defined(BZ21DLL) - VALUE "InternalName", "bz2-1\0" - VALUE "OriginalFilename", "bz2-1.dll\0" -#elif defined(BZIP2) - VALUE "InternalName", "bzip2\0" - VALUE "OriginalFilename", "bzip2.exe\0" -#elif defined(BZIP2RECOVER) - VALUE "InternalName", "bzip2recover\0" - VALUE "OriginalFilename", "bzip2recover.exe\0" -#endif - VALUE "LegalCopyright", "Copyright (C) 1996-2010 Julian Seward . Copyright (C) 2019 Federico Mena Quintero . All rights reserved.\0" - // VALUE "LegalTrademarks", "\0" - // VALUE "PrivateBuild", "\0" - VALUE "ProductName", "bzip2\0" - VALUE "ProductVersion", "1.1.0\0" - // VALUE "SpecialBuild", "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 0x4b0 - END -END diff --git a/thirdparty/bzip2/version.rc.in b/thirdparty/bzip2/version.rc.in deleted file mode 100644 index 29b2953e8..000000000 --- a/thirdparty/bzip2/version.rc.in +++ /dev/null @@ -1,54 +0,0 @@ -#include - -VS_VERSION_INFO VERSIONINFO - -FILEVERSION @PROJECT_VERSION_MAJOR@, @PROJECT_VERSION_MINOR@, @PROJECT_VERSION_PATCH@, 0 -PRODUCTVERSION @PROJECT_VERSION_MAJOR@, @PROJECT_VERSION_MINOR@, @PROJECT_VERSION_PATCH@, 0 -FILEFLAGSMASK 0x3fL -FILEOS VOS__WINDOWS32 -#if defined(LIBBZ2) - FILETYPE VFT_DLL -#else - FILETYPE VFT_APP -#endif -FILESUBTYPE 0x0L -#ifdef _DEBUG - #define VER_STR "@PROJECT_VERSION@.0 (MSVC debug)" - #define DBG "d" - FILEFLAGS 0x1L -#else - #define VER_STR "@PROJECT_VERSION@.0 (MSVC release)" - #define DBG "" - FILEFLAGS 0x0L -#endif -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - // VALUE "Comments", "" - VALUE "CompanyName", "bzip2, https://gitlab.com/bzip2/bzip2" - VALUE "FileDescription", "bzip2" - VALUE "FileVersion", "1.0.6" -#if defined(LIBBZ2) - VALUE "InternalName", "libbz2" - VALUE "OriginalFilename", "libbz2.dll" -#elif defined(BZIP2) - VALUE "InternalName", "bzip2" - VALUE "OriginalFilename", "bzip2.exe" -#elif defined(BZIP2RECOVER) - VALUE "InternalName", "bzip2recover" - VALUE "OriginalFilename", "bzip2recover.exe" -#endif - VALUE "LegalCopyright", "Copyright (C) 1996-2010 Julian Seward . All rights reserved." - VALUE "LegalTrademarks", "" - VALUE "ProductName", "bzip2" - VALUE "ProductVersion", "1.0.6" - // VALUE "SpecialBuild", "" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 0x4b0 - END -END diff --git a/thirdparty/ffms2/.gitattributes b/thirdparty/ffms2/.gitattributes deleted file mode 100644 index fc5f2320e..000000000 --- a/thirdparty/ffms2/.gitattributes +++ /dev/null @@ -1,18 +0,0 @@ -# Auto detect text files and perform LF normalization -* text=auto - -# But don't mess up Unix scripts in the process -*.sh eol=lf -*.in eol=lf -*.am eol=lf -*.ac eol=lf -*.m4 eol=lf -# Scripts that don't have extensions... -/install-sh eol=lf -/compile eol=lf -/configure eol=lf -/config.guess eol=lf -/config.sub eol=lf -/depcomp eol=lf -/install-sh eol=lf -/missing eol=lf diff --git a/thirdparty/ffms2/.gitignore b/thirdparty/ffms2/.gitignore deleted file mode 100644 index e844bcb25..000000000 --- a/thirdparty/ffms2/.gitignore +++ /dev/null @@ -1,93 +0,0 @@ - -# / -/deps -/testing -/todo.txt - -# /build-msvc/ -/build-msvc/*.sdf -/build-msvc/*.suo -/build-msvc/*.user -/build-msvc/ffms2.ncb -/build-msvc/ffmsindex -/build-msvc/bin -/build-msvc/obj - -# /src/config/ -/src/config/config.h -/src/config/config.h.in~ -/src/config/auto_config.h -/src/config/stamp-h1 - -# /src/core/ -/src/core/.deps -/src/core/.libs -/src/core/.dirstamp -/src/core/*.o -/src/core/*.lo -/src/core/*.la - -# /src/index/ -/src/index/.deps -/src/index/.libs -/src/index/.dirstamp -/src/index/*.o -/src/index/*.exe -/src/index/ffmsindex - -# /src/vapoursynth/ -/src/vapoursynth/.deps -/src/vapoursynth/.libs -/src/vapoursynth/.dirstamp -/src/vapoursynth/*.o -/src/vapoursynth/*.lo - -# /test -/test/samples -/test/display_matrix -/test/hdr -/test/.libs -/test/*.o -/test/*.a -/test/indexer - - -### Autotools ### -# automake -Makefile.in -.deps/ - -# autoconf -/ffms2.pc -/autom4te.cache -/aclocal.m4 -/compile -/config.cache -/config.guess -/config.guess~ -config.h.in -/config.log -/config.status -/config.sub -/config.sub~ -/configure -/configure~ -/configure.scan -/depcomp -/install-sh -/missing -/stamp-h1 - -# libtool -/libtool -/ltmain.sh - -# m4 -m4/libtool.m4 -m4/ltoptions.m4 -m4/ltsugar.m4 -m4/ltversion.m4 -m4/lt~obsolete.m4 - -# Generated Makefile -Makefile diff --git a/thirdparty/ffms2/COPYING b/thirdparty/ffms2/COPYING deleted file mode 100644 index 45cbe08a4..000000000 --- a/thirdparty/ffms2/COPYING +++ /dev/null @@ -1,31 +0,0 @@ -The FFMS2 source is licensed under the MIT license, but its binaries -are licensed under the GPL because GPL components of FFmpeg are -used. FFmpeg can be built as either LGPL, GPLv2, GPLv3, or even be -nonredistributable. Refer to FFmpeg's sources for licensing information. - -Text of MIT license: ------------------------------------------------------------ -Copyright (c) - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------ - diff --git a/thirdparty/ffms2/INSTALL b/thirdparty/ffms2/INSTALL deleted file mode 100644 index 7d1c323be..000000000 --- a/thirdparty/ffms2/INSTALL +++ /dev/null @@ -1,365 +0,0 @@ -Installation Instructions -************************* - -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, -2006, 2007, 2008, 2009 Free Software Foundation, Inc. - - Copying and distribution of this file, with or without modification, -are permitted in any medium without royalty provided the copyright -notice and this notice are preserved. This file is offered as-is, -without warranty of any kind. - -Basic Installation -================== - - Briefly, the shell commands `./configure; make; make install' should -configure, build, and install this package. The following -more-detailed instructions are generic; see the `README' file for -instructions specific to this package. Some packages provide this -`INSTALL' file but do not implement all of the features documented -below. The lack of an optional feature in a given package is not -necessarily a bug. More recommendations for GNU packages can be found -in *note Makefile Conventions: (standards)Makefile Conventions. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, and a -file `config.log' containing compiler output (useful mainly for -debugging `configure'). - - It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. Caching is -disabled by default to prevent problems with accidental use of stale -cache files. - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you -may remove or edit it. - - The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You need `configure.ac' if -you want to change it or regenerate `configure' using a newer version -of `autoconf'. - - The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. - - Running `configure' might take a while. While running, it prints - some messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package, generally using the just-built uninstalled binaries. - - 4. Type `make install' to install the programs and any data files and - documentation. When installing into a prefix owned by root, it is - recommended that the package be configured and built as a regular - user, and only the `make install' phase executed with root - privileges. - - 5. Optionally, type `make installcheck' to repeat any self-tests, but - this time using the binaries in their final installed location. - This target does not install anything. Running this target as a - regular user, particularly if the prior `make install' required - root privileges, verifies that the installation completed - correctly. - - 6. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - - 7. Often, you can also type `make uninstall' to remove the installed - files again. In practice, not all packages have tested that - uninstallation works correctly, even though it is required by the - GNU Coding Standards. - - 8. Some packages, particularly those that use Automake, provide `make - distcheck', which can by used by developers to test that all other - targets like `make install' and `make uninstall' work correctly. - This target is generally not run by end users. - -Compilers and Options -===================== - - Some systems require unusual options for compilation or linking that -the `configure' script does not know about. Run `./configure --help' -for details on some of the pertinent environment variables. - - You can give `configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here -is an example: - - ./configure CC=c99 CFLAGS=-g LIBS=-lposix - - *Note Defining Variables::, for more details. - -Compiling For Multiple Architectures -==================================== - - You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you can use GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. This -is known as a "VPATH" build. - - With a non-GNU `make', it is safer to compile the package for one -architecture at a time in the source code directory. After you have -installed the package for one architecture, use `make distclean' before -reconfiguring for another architecture. - - On MacOS X 10.5 and later systems, you can create libraries and -executables that work on multiple system types--known as "fat" or -"universal" binaries--by specifying multiple `-arch' options to the -compiler but only a single `-arch' option to the preprocessor. Like -this: - - ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ - CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ - CPP="gcc -E" CXXCPP="g++ -E" - - This is not guaranteed to produce working output in all cases, you -may have to build one architecture at a time and combine the results -using the `lipo' tool if you have problems. - -Installation Names -================== - - By default, `make install' installs the package's commands under -`/usr/local/bin', include files under `/usr/local/include', etc. You -can specify an installation prefix other than `/usr/local' by giving -`configure' the option `--prefix=PREFIX', where PREFIX must be an -absolute file name. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -pass the option `--exec-prefix=PREFIX' to `configure', the package uses -PREFIX as the prefix for installing programs and libraries. -Documentation and other data files still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=DIR' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. In general, the -default for these options is expressed in terms of `${prefix}', so that -specifying just `--prefix' will affect all of the other directory -specifications that were not explicitly provided. - - The most portable way to affect installation locations is to pass the -correct locations to `configure'; however, many packages provide one or -both of the following shortcuts of passing variable assignments to the -`make install' command line to change installation locations without -having to reconfigure or recompile. - - The first method involves providing an override variable for each -affected directory. For example, `make install -prefix=/alternate/directory' will choose an alternate location for all -directory configuration variables that were expressed in terms of -`${prefix}'. Any directories that were specified during `configure', -but not in terms of `${prefix}', must each be overridden at install -time for the entire installation to be relocated. The approach of -makefile variable overrides for each directory variable is required by -the GNU Coding Standards, and ideally causes no recompilation. -However, some platforms have known limitations with the semantics of -shared libraries that end up requiring recompilation when using this -method, particularly noticeable in packages that use GNU Libtool. - - The second method involves providing the `DESTDIR' variable. For -example, `make install DESTDIR=/alternate/directory' will prepend -`/alternate/directory' before all installation names. The approach of -`DESTDIR' overrides is not required by the GNU Coding Standards, and -does not work on platforms that have drive letters. On the other hand, -it does better at avoiding recompilation issues, and works well even -when some directory options were not specified in terms of `${prefix}' -at `configure' time. - -Optional Features -================= - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - - Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - - Some packages offer the ability to configure how verbose the -execution of `make' will be. For these packages, running `./configure ---enable-silent-rules' sets the default to minimal output, which can be -overridden with `make V=1'; while running `./configure ---disable-silent-rules' sets the default to verbose, which can be -overridden with `make V=0'. - -Particular systems -================== - - On HP-UX, the default C compiler is not ANSI C compatible. If GNU -CC is not installed, it is recommended to use the following options in -order to use an ANSI C compiler: - - ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" - -and if that doesn't work, install pre-built binaries of GCC for HP-UX. - - On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot -parse its `' header file. The option `-nodtk' can be used as -a workaround. If GNU CC is not installed, it is therefore recommended -to try - - ./configure CC="cc" - -and if that doesn't work, try - - ./configure CC="cc -nodtk" - - On Solaris, don't put `/usr/ucb' early in your `PATH'. This -directory contains several dysfunctional programs; working variants of -these programs are available in `/usr/bin'. So, if you need `/usr/ucb' -in your `PATH', put it _after_ `/usr/bin'. - - On Haiku, software installed for all users goes in `/boot/common', -not `/usr/local'. It is recommended to use the following options: - - ./configure --prefix=/boot/common - -Specifying the System Type -========================== - - There may be some features `configure' cannot figure out -automatically, but needs to determine by the type of machine the package -will run on. Usually, assuming the package is built to be run on the -_same_ architectures, `configure' can figure that out, but if it prints -a message saying it cannot guess the machine type, give it the -`--build=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name which has the form: - - CPU-COMPANY-SYSTEM - -where SYSTEM can have one of these forms: - - OS - KERNEL-OS - - See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the machine type. - - If you are _building_ compiler tools for cross-compiling, you should -use the option `--target=TYPE' to select the type of system they will -produce code for. - - If you want to _use_ a cross compiler, that generates code for a -platform different from the build platform, you should specify the -"host" platform (i.e., that on which the generated programs will -eventually be run) with `--host=TYPE'. - -Sharing Defaults -================ - - If you want to set default values for `configure' scripts to share, -you can create a site shell script called `config.site' that gives -default values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Defining Variables -================== - - Variables not defined in a site shell script can be set in the -environment passed to `configure'. However, some packages may run -configure again during the build, and the customized values of these -variables may be lost. In order to avoid this problem, you should set -them in the `configure' command line, using `VAR=value'. For example: - - ./configure CC=/usr/local2/bin/gcc - -causes the specified `gcc' to be used as the C compiler (unless it is -overridden in the site shell script). - -Unfortunately, this technique does not work for `CONFIG_SHELL' due to -an Autoconf bug. Until the bug is fixed you can use this workaround: - - CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash - -`configure' Invocation -====================== - - `configure' recognizes the following options to control how it -operates. - -`--help' -`-h' - Print a summary of all of the options to `configure', and exit. - -`--help=short' -`--help=recursive' - Print a summary of the options unique to this package's - `configure', and exit. The `short' variant lists options used - only in the top level, while the `recursive' variant lists options - also present in any nested packages. - -`--version' -`-V' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`--cache-file=FILE' - Enable the cache: use and save the results of the tests in FILE, - traditionally `config.cache'. FILE defaults to `/dev/null' to - disable caching. - -`--config-cache' -`-C' - Alias for `--cache-file=config.cache'. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`--prefix=DIR' - Use DIR as the installation prefix. *note Installation Names:: - for more details, including other options available for fine-tuning - the installation locations. - -`--no-create' -`-n' - Run the configure checks, but stop before creating any output - files. - -`configure' also accepts some other, not widely useful, options. Run -`configure --help' for more details. - diff --git a/thirdparty/ffms2/Makefile.am b/thirdparty/ffms2/Makefile.am deleted file mode 100644 index 261a58def..000000000 --- a/thirdparty/ffms2/Makefile.am +++ /dev/null @@ -1,89 +0,0 @@ -ACLOCAL_AMFLAGS = -I m4 -AUTOMAKE_OPTIONS = foreign - -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = ffms2.pc - -dist_doc_DATA = doc/ffms2-api.md doc/ffms2-changelog.md - -AM_CPPFLAGS = \ - -I. \ - -I$(top_srcdir)/include \ - -I$(top_srcdir)/src/config \ - -D_FILE_OFFSET_BITS=64 \ - -DFFMS_EXPORTS \ - -D__STDC_CONSTANT_MACROS \ - @FFMPEG_CFLAGS@ \ - @ZLIB_CPPFLAGS@ \ - -include config.h -AM_CXXFLAGS = -std=c++11 -fvisibility=hidden - -lib_LTLIBRARIES = src/core/libffms2.la -src_core_libffms2_la_LDFLAGS = @src_core_libffms2_la_LDFLAGS@ -src_core_libffms2_la_LIBADD = @FFMPEG_LIBS@ @ZLIB_LDFLAGS@ -lz @LTUNDEF@ -src_core_libffms2_la_SOURCES = \ - src/core/audiosource.cpp \ - src/core/audiosource.h \ - src/core/ffms.cpp \ - src/core/filehandle.cpp \ - src/core/filehandle.h \ - src/core/indexing.cpp \ - src/core/indexing.h \ - src/core/track.cpp \ - src/core/track.h \ - src/core/utils.cpp \ - src/core/utils.h \ - src/core/videosource.cpp \ - src/core/videosource.h \ - src/core/videoutils.cpp \ - src/core/videoutils.h \ - src/core/zipfile.cpp \ - src/core/zipfile.h \ - src/vapoursynth/VapourSynth4.h \ - src/vapoursynth/VSHelper4.h \ - src/vapoursynth/vapoursource4.cpp \ - src/vapoursynth/vapoursource4.h \ - src/vapoursynth/vapoursynth4.cpp - -if AVISYNTH -src_core_libffms2_la_SOURCES += \ - src/avisynth/avssources.cpp \ - src/avisynth/avssources.h \ - src/avisynth/avisynth.cpp -endif - -include_HEADERS = $(top_srcdir)/include/ffms.h $(top_srcdir)/include/ffmscompat.h - -bin_PROGRAMS = src/index/ffmsindex -src_index_ffmsindex_SOURCES = src/index/ffmsindex.cpp -src_index_ffmsindex_LDADD = -lavutil src/core/libffms2.la - -.PHONY: test test-build test-clean test-sync test-run -clean-local: test-clean - -SAMPLES_DIR = $(abs_top_builddir)/test/samples -SAMPLES_URL = https://storage.googleapis.com/ffms2tests - -test: test-setup test-build test-run - -test-setup: - @$(MKDIR_P) $(abs_top_builddir)/test - @$(MKDIR_P) $(SAMPLES_DIR) - @if [ ! -e "$(abs_top_builddir)/test/Makefile" ]; then \ - $(LN_S) $(abs_top_srcdir)/test/Makefile $(abs_top_builddir)/test/Makefile; \ - fi - -test-build: test-setup src/core/libffms2.la - @if [ ! -d "$(abs_top_srcdir)/test/googletest" ]; then \ - echo "googletest submodule not initalized."; \ - fi - @$(MAKE) -C test USER_DIR=$(abs_top_srcdir) SAMPLES_DIR=$(SAMPLES_DIR) CXX=$(CXX) AR=$(AR) - -test-sync: test-setup - @$(MAKE) -C test sync USER_DIR=$(abs_top_srcdir) SAMPLES_DIR=$(SAMPLES_DIR) SAMPLES_URL=$(SAMPLES_URL) CXX=$(CXX) AR=$(AR) - -test-run: test-build - @$(MAKE) -C test run USER_DIR=$(abs_top_srcdir) SAMPLES_DIR=$(SAMPLES_DIR) CXX=$(CXX) AR=$(AR) -k - -test-clean: - @$(MAKE) -C test clean USER_DIR=$(abs_top_srcdir) CXX=$(CXX) AR=$(AR) diff --git a/thirdparty/ffms2/README.md b/thirdparty/ffms2/README.md deleted file mode 100644 index 2572039c6..000000000 --- a/thirdparty/ffms2/README.md +++ /dev/null @@ -1,32 +0,0 @@ -[![Build Status](https://api.travis-ci.org/FFMS/ffms2.svg?branch=master)](https://travis-ci.org/FFMS/ffms2) - -**FFmpegSource** (usually known as **FFMS** or **FFMS2**) is a cross-platform wrapper library around [FFmpeg](http://ffmpeg.org). It gives you an easy, convenient way to say "open and decompress this media file for me, I don't care how you do it" and get frame- and sample-accurate access (usually), without having to bother with the sometimes less than straightforward and less than perfectly documented FFmpeg API. - -The library is written in C++, but the public API is pure C, so if you can link to a C library, you can use FFMS2. The source is available under the MIT license, but the license of the binaries depends on how FFmpeg was compiled. There are optional components that require a GPL FFmpeg, and if those are compiled in FFMS2 itself becomes covered by the GPL as well. The official Windows builds are GPLv3 for this reason. - -For more information on using the library, see the [API documentation](doc/ffms2-api.md) and the [changelog](doc/ffms2-changelog.md). - -### Avisynth and VapourSynth plugin -For the end user, the most visible use of FFMS is the implementation of both an [Avisynth](http://avisynth.nl) and a [VapourSynth](http://www.vapoursynth.com) source plugin that uses the FFMS library to open media files. This plugin is a part of the FFMS2 project and is available for download here; for documentation see the [Avisynth user guide](doc/ffms2-avisynth.md). - -### Features -In addition to being able to open almost any common audio or video format, the Avisynth plugin has a number of more or less unique properties that other Avisynth source filters lack: - - * It is the only source filter that has support for Unicode filenames that are not representable in the system codepage. - * It is the only source filter that has proper variable framerate (VFR) support. - * It is the only general-purpose (i.e. not restricted to one or a few formats) source filter that will work reliably when running Avisynth under Wine. - * It is the only general-purpose source filter that does not rely on external decoders. - * It is (probably) the only source filter that supports mid-stream video resolution switches. - -### Versions and variants -If you're confused by all the different variants, here's a small explanation: - - * Vanilla (no suffix): standard 32-bit version. If you don't know what you want, you want this. - * -x64: 64-bit version; mostly for use with 64-bit Avisynth. - * -avs-cplugin: Variant of the Avisynth plugin written in C. Primary purpose is to get access to the new colorspaces available in Avisynth 2.6. - * SDK: software developer's kit, for people who want to develop Windows applications that use FFMS2, using Microsoft Visual Studio 2008 or later. - -Packages marked rNUMBER are testing builds made in-between releases. Download them if you need some bleeding-edge feature or just want to test out the upcoming version. Do note that they may be less stable than the official release versions. - -### Why is it called FFmpegSource, that makes no sense at all!?! -FFMS originated as an Avisynth file reader plugin, and those are traditionally called FooSource, where Foo usually is the method used to open the file. For historical reasons the entire project is still called FFmpegSource, although these days the name is pretty misleading and makes people think it has something to do with FFmpeg's source code or somesuch. To avoid confusion, it's probably better to refer to the library as FFMS (2, since version 1 was only an Avisynth plugin...) and keep the FFmpegSource name for the Avisynth plugin. diff --git a/thirdparty/ffms2/autogen.sh b/thirdparty/ffms2/autogen.sh deleted file mode 100755 index 9ae414e57..000000000 --- a/thirdparty/ffms2/autogen.sh +++ /dev/null @@ -1,6 +0,0 @@ -#! /bin/sh -mkdir -p src/config -echo Running autoreconf... -autoreconf -ivf -echo Running configure... -./configure "$@" diff --git a/thirdparty/ffms2/build-msvc/Readme.txt b/thirdparty/ffms2/build-msvc/Readme.txt deleted file mode 100644 index b663be908..000000000 --- a/thirdparty/ffms2/build-msvc/Readme.txt +++ /dev/null @@ -1,9 +0,0 @@ -BUILD INSTRUCTIONS FOR WINDOWS - -The included projects require Visual Studio 2019 with an integrated vcpkg. - -Run `vcpkg install ffmpeg:x64-windows-static` or `vcpkg install ffmpeg:x86-windows-static` -depending on the configuration you want to build. - -In addition to this the Avisynth+ headers are also needed. The include path is set -to be relative to the FFMS2 directory by default. \ No newline at end of file diff --git a/thirdparty/ffms2/build-msvc/ffms2.sln b/thirdparty/ffms2/build-msvc/ffms2.sln deleted file mode 100644 index 9dc358a74..000000000 --- a/thirdparty/ffms2/build-msvc/ffms2.sln +++ /dev/null @@ -1,41 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26228.9 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ffms2", "ffms2.vcxproj", "{2CF8C7D2-55E5-4861-A58A-A79B84D0D9EA}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ffmsindex", "ffmsindex.vcxproj", "{8665C229-CA77-4B41-ADC5-F3998F0C85A6}" - ProjectSection(ProjectDependencies) = postProject - {2CF8C7D2-55E5-4861-A58A-A79B84D0D9EA} = {2CF8C7D2-55E5-4861-A58A-A79B84D0D9EA} - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {2CF8C7D2-55E5-4861-A58A-A79B84D0D9EA}.Debug|x64.ActiveCfg = Debug|x64 - {2CF8C7D2-55E5-4861-A58A-A79B84D0D9EA}.Debug|x64.Build.0 = Debug|x64 - {2CF8C7D2-55E5-4861-A58A-A79B84D0D9EA}.Debug|x86.ActiveCfg = Debug|Win32 - {2CF8C7D2-55E5-4861-A58A-A79B84D0D9EA}.Debug|x86.Build.0 = Debug|Win32 - {2CF8C7D2-55E5-4861-A58A-A79B84D0D9EA}.Release|x64.ActiveCfg = Release|x64 - {2CF8C7D2-55E5-4861-A58A-A79B84D0D9EA}.Release|x64.Build.0 = Release|x64 - {2CF8C7D2-55E5-4861-A58A-A79B84D0D9EA}.Release|x86.ActiveCfg = Release|Win32 - {2CF8C7D2-55E5-4861-A58A-A79B84D0D9EA}.Release|x86.Build.0 = Release|Win32 - {8665C229-CA77-4B41-ADC5-F3998F0C85A6}.Debug|x64.ActiveCfg = Debug|x64 - {8665C229-CA77-4B41-ADC5-F3998F0C85A6}.Debug|x64.Build.0 = Debug|x64 - {8665C229-CA77-4B41-ADC5-F3998F0C85A6}.Debug|x86.ActiveCfg = Debug|Win32 - {8665C229-CA77-4B41-ADC5-F3998F0C85A6}.Debug|x86.Build.0 = Debug|Win32 - {8665C229-CA77-4B41-ADC5-F3998F0C85A6}.Release|x64.ActiveCfg = Release|x64 - {8665C229-CA77-4B41-ADC5-F3998F0C85A6}.Release|x64.Build.0 = Release|x64 - {8665C229-CA77-4B41-ADC5-F3998F0C85A6}.Release|x86.ActiveCfg = Release|Win32 - {8665C229-CA77-4B41-ADC5-F3998F0C85A6}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/thirdparty/ffms2/build-msvc/ffms2.vcxproj b/thirdparty/ffms2/build-msvc/ffms2.vcxproj deleted file mode 100644 index 6b8522559..000000000 --- a/thirdparty/ffms2/build-msvc/ffms2.vcxproj +++ /dev/null @@ -1,189 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 15.0 - {2CF8C7D2-55E5-4861-A58A-A79B84D0D9EA} - Win32Proj - ffms2 - 10.0 - x64-windows-static - x86-windows-static - - - - DynamicLibrary - true - v143 - Unicode - - - DynamicLibrary - false - v143 - true - Unicode - - - DynamicLibrary - true - v143 - Unicode - - - DynamicLibrary - false - v143 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - $(SolutionDir)bin\$(Platform)\$(Configuration)\ - $(SolutionDir)obj\$(Platform)\$(Configuration)\ - ../include;../../AviSynthPlus/avs_core/include;$(IncludePath) - - - true - $(SolutionDir)bin\$(Platform)\$(Configuration)\ - $(SolutionDir)obj\$(Platform)\$(Configuration)\ - ../include;../../AviSynthPlus/avs_core/include;$(IncludePath) - - - false - $(SolutionDir)bin\$(Platform)\$(Configuration)\ - $(SolutionDir)obj\$(Platform)\$(Configuration)\ - ../include;../../AviSynthPlus/avs_core/include;$(IncludePath) - - - false - $(SolutionDir)bin\$(Platform)\$(Configuration)\ - $(SolutionDir)obj\$(Platform)\$(Configuration)\ - ../include;../../AviSynthPlus/avs_core/include;$(IncludePath) - - - - Level3 - Disabled - FFMS_EXPORTS;_CRT_SECURE_NO_WARNINGS;__STDC_CONSTANT_MACROS;FFMS_WIN_DEBUG;WIN32;_DEBUG;_WINDOWS;_USRDLL;FFMS2_EXPORTS;%(PreprocessorDefinitions) - MultiThreadedDebug - - - Windows - psapi.lib;uuid.lib;oleaut32.lib;shlwapi.lib;gdi32.lib;vfw32.lib;secur32.lib;ws2_32.lib;mfplat.lib;mfuuid.lib;strmiids.lib;ole32.lib;user32.lib;bcrypt.lib;%(AdditionalDependencies) - - - - - Level3 - Disabled - FFMS_EXPORTS;_CRT_SECURE_NO_WARNINGS;__STDC_CONSTANT_MACROS;FFMS_WIN_DEBUG;_DEBUG;_WINDOWS;_USRDLL;FFMS2_EXPORTS;%(PreprocessorDefinitions) - MultiThreadedDebug - - - Windows - psapi.lib;uuid.lib;oleaut32.lib;shlwapi.lib;gdi32.lib;vfw32.lib;secur32.lib;ws2_32.lib;mfplat.lib;mfuuid.lib;strmiids.lib;ole32.lib;user32.lib;bcrypt.lib;%(AdditionalDependencies) - - - - - Level3 - MaxSpeed - true - true - FFMS_EXPORTS;_CRT_SECURE_NO_WARNINGS;__STDC_CONSTANT_MACROS;WIN32;NDEBUG;_WINDOWS;_USRDLL;FFMS2_EXPORTS;%(PreprocessorDefinitions) - MultiThreaded - - - Windows - true - true - psapi.lib;uuid.lib;oleaut32.lib;shlwapi.lib;gdi32.lib;vfw32.lib;secur32.lib;ws2_32.lib;mfplat.lib;mfuuid.lib;strmiids.lib;ole32.lib;user32.lib;bcrypt.lib;%(AdditionalDependencies) - - - - - Level3 - MaxSpeed - true - true - FFMS_EXPORTS;_CRT_SECURE_NO_WARNINGS;__STDC_CONSTANT_MACROS;NDEBUG;_WINDOWS;_USRDLL;FFMS2_EXPORTS;%(PreprocessorDefinitions) - MultiThreaded - - - Windows - true - true - psapi.lib;uuid.lib;oleaut32.lib;shlwapi.lib;gdi32.lib;vfw32.lib;secur32.lib;ws2_32.lib;mfplat.lib;mfuuid.lib;strmiids.lib;ole32.lib;user32.lib;bcrypt.lib;%(AdditionalDependencies) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/thirdparty/ffms2/build-msvc/ffms2.vcxproj.filters b/thirdparty/ffms2/build-msvc/ffms2.vcxproj.filters deleted file mode 100644 index ef535cde0..000000000 --- a/thirdparty/ffms2/build-msvc/ffms2.vcxproj.filters +++ /dev/null @@ -1,111 +0,0 @@ - - - - - {5e4ea0a8-9b1a-49ee-8b02-e498d4d5cc80} - - - {94e424bf-1254-46b5-9282-7c6b99280638} - - - {e25264ca-e3fd-4fd6-a1d1-839ae9b2ade2} - - - {731b163b-dd24-4aba-8bef-86c3b364157e} - - - {a2513788-a12f-43c1-99aa-b9f20cd6a099} - - - {8cc15f2a-6612-4e85-96b3-d3abfe15ddab} - - - {95efeead-393a-4518-b1f2-9b8b6bb8c3d6} - - - - - API - - - Utils - - - Utils - - - Utils - - - Video - - - Video - - - Indexing - - - Indexing - - - Audio - - - Avisynth - - - Avisynth - - - Vapoursynth - - - Vapoursynth - - - - - API - - - Utils - - - Utils - - - Utils - - - Utils - - - Video - - - Video - - - Indexing - - - Indexing - - - Audio - - - Avisynth - - - Vapoursynth - - - Vapoursynth - - - Vapoursynth - - - \ No newline at end of file diff --git a/thirdparty/ffms2/build-msvc/ffmsindex.vcxproj b/thirdparty/ffms2/build-msvc/ffmsindex.vcxproj deleted file mode 100644 index b299b8c98..000000000 --- a/thirdparty/ffms2/build-msvc/ffmsindex.vcxproj +++ /dev/null @@ -1,177 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 15.0 - {8665C229-CA77-4B41-ADC5-F3998F0C85A6} - Win32Proj - ffmsindex - 10.0 - x64-windows-static - x86-windows-static - - - - Application - true - v143 - Unicode - - - Application - false - v143 - true - Unicode - - - Application - true - v143 - Unicode - - - Application - false - v143 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - $(SolutionDir)bin\$(Platform)\$(Configuration)\ - $(SolutionDir)ffmsindex\$(Platform)\$(Configuration)\ - ../include;$(IncludePath) - - - true - $(SolutionDir)bin\$(Platform)\$(Configuration)\ - $(SolutionDir)ffmsindex\$(Platform)\$(Configuration)\ - ../include;$(IncludePath) - - - false - $(SolutionDir)bin\$(Platform)\$(Configuration)\ - $(SolutionDir)ffmsindex\$(Platform)\$(Configuration)\ - ../include;$(IncludePath) - - - false - $(SolutionDir)bin\$(Platform)\$(Configuration)\ - $(SolutionDir)ffmsindex\$(Platform)\$(Configuration)\ - ../include;$(IncludePath) - - - - - - Level3 - Disabled - _CRT_SECURE_NO_WARNINGS;__STDC_CONSTANT_MACROS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDebug - - - Console - - - - - - - Level3 - Disabled - _CRT_SECURE_NO_WARNINGS;__STDC_CONSTANT_MACROS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDebug - - - Console - - - - - Level3 - - - MaxSpeed - true - true - _CRT_SECURE_NO_WARNINGS;__STDC_CONSTANT_MACROS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreaded - - - Console - true - true - - - - - Level3 - - - MaxSpeed - true - true - _CRT_SECURE_NO_WARNINGS;__STDC_CONSTANT_MACROS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreaded - - - Console - true - true - - - - - - - - - - - - {2cf8c7d2-55e5-4861-a58a-a79b84d0d9ea} - - - - - - - - - \ No newline at end of file diff --git a/thirdparty/ffms2/build-msvc/ffmsindex.vcxproj.filters b/thirdparty/ffms2/build-msvc/ffmsindex.vcxproj.filters deleted file mode 100644 index 0b8020200..000000000 --- a/thirdparty/ffms2/build-msvc/ffmsindex.vcxproj.filters +++ /dev/null @@ -1,34 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {25d75b48-9985-40fd-be86-bd4ca73d5209} - - - - - Source Files - - - - - Header Files - - - Header Files - - - - - Manifests - - - \ No newline at end of file diff --git a/thirdparty/ffms2/configure.ac b/thirdparty/ffms2/configure.ac deleted file mode 100644 index 98cb9c8f5..000000000 --- a/thirdparty/ffms2/configure.ac +++ /dev/null @@ -1,159 +0,0 @@ -AC_PREREQ([2.71]) -AC_INIT([ffms2],[esyscmd([sh version.sh])]) -AC_CONFIG_SRCDIR([src/core/ffms.cpp]) -AC_CONFIG_MACRO_DIR([m4]) -AM_INIT_AUTOMAKE([1.11 subdir-objects]) -AM_SILENT_RULES([yes]) -AM_MAINTAINER_MODE([disable]) - -VERSION_INFO="5:0:0" - -AC_MSG_CHECKING([if debug build is enabled]) - -AC_ARG_ENABLE([debug], - [AS_HELP_STRING([--enable-debug],[Enable debug build. [default=no]])], - [enable_debug=yes], - [enable_debug=no] - ) - -AC_MSG_RESULT([$enable_debug]) - -if test "$enable_debug" = yes; then - OPT_FLAGS="-O0 -g" -else - OPT_FLAGS="-O3" -fi - -if test -z "$CFLAGS"; then - CFLAGS="$OPT_FLAGS -Wall -Wextra" -fi - -if test -z "$CXXFLAGS"; then - CXXFLAGS="$OPT_FLAGS -Wall -Wextra" -fi - -AC_ARG_ENABLE([avisynth], - [AS_HELP_STRING([--enable-avisynth],[Enable AviSynth+ plugin. [default=no]])], - [enable_avisynth=yes], - [enable_avisynth=no] - ) - -AC_MSG_RESULT([$enable_avisynth]) -AM_CONDITIONAL([AVISYNTH], [test "x$enable_avisynth" != "xno"]) - -AC_CONFIG_HEADERS([src/config/config.h]) -AC_PROG_CC -AC_PROG_CXX -AC_PROG_LN_S -AC_PROG_MKDIR_P - -AC_CANONICAL_HOST -AS_CASE([$host], - [*mingw* | *cygwin*], [ - AC_ENABLE_STATIC - AC_DISABLE_SHARED - ], [ - AC_ENABLE_SHARED - AC_DISABLE_STATIC]) - -LT_INIT - -if echo "$host" | $GREP "cygwin" >/dev/null 2>&1 && test "$enable_shared" = "yes"; then - AC_MSG_ERROR([Shared build is broken on cygwin. - Please remove --enable-shared from your configure options or build with another --host.]) -fi - -dnl Workaround for a bug in libtool -dnl The windows libtool uses a file magic checking method that only accepts -dnl dynamic libraries. Change it for libtool's alternative checking method. -if test "$lt_cv_file_magic_cmd" = "func_win32_libid" ; then - deplibs_check_method='file_magic file format pei*-(i386|x86-64)|(.*architecture: i386)?' - file_magic_cmd='$OBJDUMP -f' -fi - -FFMS_VERSION="$(sh $(dirname -- "$0")/version.sh)" -AC_SUBST([FFMS_VERSION]) - -CHECK_ZLIB - -dnl Save CFLAGS and LIBS for later, as anything else we add will be from pkg-config -dnl and thus should be separate in our .pc file. -_CFLAGS="$CFLAGS" -_CPPFLAGS="$CPPFLAGS" -_LIBS="$LIBS" - -PKG_PROG_PKG_CONFIG([0.22]) -pkgconfigdir="\$(libdir)/pkgconfig" -AC_SUBST(pkgconfigdir) - -PKG_CHECK_MODULES(FFMPEG, [libavformat >= 53.20.0 libavcodec >= 53.24.0 libswscale >= 0.7.0 libavutil >= 51.21.0 libswresample >= 1.0.0]) - -dnl As of 0eec06ed8747923faa6a98e474f224d922dc487d ffmpeg only adds -lrt to lavc's -dnl LIBS, but lavu needs it, so move it to the end if it's present -FFMPEG_LIBS=$(echo $FFMPEG_LIBS | sed 's/\(.*\)-lrt \(.*\)/\1\2 -lrt/') - -AC_SUBST([FFMPEG_CFLAGS]) -AC_SUBST([FFMPEG_LIBS]) - -CPPFLAGS="$CPPFLAGS -D__STDC_CONSTANT_MACROS" -CFLAGS="$_CFLAGS $FFMPEG_CFLAGS" - -AC_DEFUN([TEST_FFMPEG], - [AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - #include - #include - ]],[[ - avformat_network_init(); - swscale_version(); - ]])], [eval $1=yes], [eval $1=no]) - ]) - -AC_MSG_CHECKING([whether FFmpeg works]) -LIBS="$_LIBS $FFMPEG_LIBS" -TEST_FFMPEG([FFMPEG_WORKS]) -AC_MSG_RESULT([$FFMPEG_WORKS]) -if test "$FFMPEG_WORKS" = no; then -AC_MSG_FAILURE([cannot link with FFmpeg]) -fi - -src_core_libffms2_la_LDFLAGS="" -AC_MSG_CHECKING([whether -Wl,-Bsymbolic is needed]) -if test "$enable_shared" = yes; then - _LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -shared $lt_prog_compiler_pic" - TEST_FFMPEG([no_bsymbolic]) - if test "$no_bsymbolic" = "no"; then - LDFLAGS="$LDFLAGS -Wl,-Bsymbolic" - TEST_FFMPEG([bsymbolic]) - if test "$bsymbolic" = "yes"; then - src_core_libffms2_la_LDFLAGS="$src_core_libffms2_la_LDFLAGS -Wl,-Bsymbolic" - else - AC_MSG_RESULT($bsymbolic) - AC_MSG_FAILURE([cannot build ffms2 as a shared library]) - fi - else - bsymbolic=no - fi - LDFLAGS="$_LDFLAGS" - src_core_libffms2_la_LDFLAGS="$src_core_libffms2_la_LDFLAGS -version-info $VERSION_INFO" -else - bsymbolic=no -fi -AC_SUBST([src_core_libffms2_la_LDFLAGS]) - -CFLAGS="$_CFLAGS" -CPPFLAGS="$_CPPFLAGS" -LIBS="$_LIBS" -AC_MSG_RESULT($bsymbolic) - -if echo "$host" | $GREP "mingw" >/dev/null 2>&1; then - LTUNDEF="-no-undefined" -fi -AC_SUBST([LTUNDEF]) - -AC_CONFIG_FILES([ -Makefile -ffms2.pc -]) -AC_OUTPUT - diff --git a/thirdparty/ffms2/doc/ffms2-api.md b/thirdparty/ffms2/doc/ffms2-api.md deleted file mode 100644 index 2152e01bd..000000000 --- a/thirdparty/ffms2/doc/ffms2-api.md +++ /dev/null @@ -1,1421 +0,0 @@ -# FFmpegSource2 API Documentation -FFmpegSource2 (FFMS2) is a wrapper library around Libav/FFmpeg, plus some additional components to deal with file formats libavformat has (or used to have) problems with. -It gives you a convenient way to say "open and decompress this media file for me, I don't care how you do it", without having to bother with the sometimes less than straightforward and less than perfectly documented Libav/FFmpeg internals. -May be frame and/or sample accurate on good days. -The library is written in C++, but the public API is C-friendly and it is possible to simply include and link directly with a pure C application. - -The source is MIT licensed and can be obtained from GitHub; see https://github.com/FFMS/ffms2. - -## Limitations -FFMS2 does not mux or encode anything. -FFMS2 does not give you fine control over codec internals. -FFMS2 does not let you demux raw compressed data, you get it decompressed or not at all. -FFMS2 does not provide you with a good solution for realtime playback, since it needs to index the input file before you can retreive frames or audio samples. -FFMS2 does not currently handle things like subtitles, file attachments or chapters. -FFMS2's video frame and audio sample retrieval functions are not threadsafe; you may only have one request going at a time, per source context. - -## Compilation -FFMS2 has the following dependencies: - - - **[FFmpeg][ffmpeg]** - - Further recommended configuration options: `--disable-debug --disable-muxers --disable-encoders --disable-filters --disable-hwaccels --disable-network --disable-devices - - **[zlib][zlib]** - -Compiling the library on non-Windows is trivial; the usual `./configure && make && make install` will suffice if FFmpeg and zlib are installed to the default locations. - -### Windows-specific compilation notes -You have several options on how to build FFMS2 on Windows. - -You can build both FFmpeg and FFMS2 with MinGW-w64, FFmpeg with clang-cl and FFMS2 with VC++ (shared only), or both with VC++. -The standard Avisynth 2.5 plugin requires building FFMS2 with VC++, while the Avisynth C plugin (which supports Avisynth 2.6) requires building with MinGW (and using the `c_plugin`branch). VapouSynth works as-is with MinGW-w64. - -These days building everything with MinGW works without doing anything unusual. - -You'll have to manually add the location which you installed the headers and libraries to to VC++'s search paths (and if you're building both 32-bit and 64-bit, be sure to add the correct ones). - -[ffmpeg]: http://www.ffmpeg.org -[zlib]: http://www.zlib.net - -## Quickstart guide for impatient people -If you don't want to know anything about anything and just want to open some video with FFMS2 in the absolutely simplest possible manner, without selective indexing, progress reporting, saved index files, keyframe or timecode reading or anything like that, here's how to do it with the absolutely bare minimum of code. - -```c++ -#include - -int main (...) { - /* Initialize the library. */ - FFMS_Init(0, 0); - - /* Index the source file. Note that this example does not index any audio tracks. */ - char errmsg[1024]; - FFMS_ErrorInfo errinfo; - errinfo.Buffer = errmsg; - errinfo.BufferSize = sizeof(errmsg); - errinfo.ErrorType = FFMS_ERROR_SUCCESS; - errinfo.SubType = FFMS_ERROR_SUCCESS; - const char *sourcefile = "somefilename"; - - FFMS_Indexer *indexer = FFMS_CreateIndexer(sourcefile, &errinfo); - if (indexer == NULL) { - /* handle error (print errinfo.Buffer somewhere) */ - } - - FFMS_Index *index = FFMS_DoIndexing2(indexer, FFMS_IEH_ABORT, &errinfo); - if (index == NULL) { - /* handle error (you should know what to do by now) */ - } - - /* Retrieve the track number of the first video track */ - int trackno = FFMS_GetFirstTrackOfType(index, FFMS_TYPE_VIDEO, &errinfo); - if (trackno < 0) { - /* no video tracks found in the file, this is bad and you should handle it */ - /* (print the errmsg somewhere) */ - } - - /* We now have enough information to create the video source object */ - FFMS_VideoSource *videosource = FFMS_CreateVideoSource(sourcefile, trackno, index, 1, FFMS_SEEK_NORMAL, &errinfo); - if (videosource == NULL) { - /* handle error */ - } - - /* Since the index is copied into the video source object upon its creation, - we can and should now destroy the index object. */ - FFMS_DestroyIndex(index); - - /* Retrieve video properties so we know what we're getting. - As the lack of the errmsg parameter indicates, this function cannot fail. */ - const FFMS_VideoProperties *videoprops = FFMS_GetVideoProperties(videosource); - - /* Now you may want to do something with the info, like check how many frames the video has */ - int num_frames = videoprops->NumFrames; - - /* Get the first frame for examination so we know what we're getting. This is required - because resolution and colorspace is a per frame property and NOT global for the video. */ - const FFMS_Frame *propframe = FFMS_GetFrame(videosource, 0, &errinfo); - - /* Now you may want to do something with the info; particularly interesting values are: - propframe->EncodedWidth; (frame width in pixels) - propframe->EncodedHeight; (frame height in pixels) - propframe->EncodedPixelFormat; (actual frame colorspace) - */ - - /* If you want to change the output colorspace or resize the output frame size, - now is the time to do it. IMPORTANT: This step is also required to prevent - resolution and colorspace changes midstream. You can you can always tell a frame's - original properties by examining the Encoded* properties in FFMS_Frame. */ - /* See libavutil/pixfmt.h for the list of pixel formats/colorspaces. - To get the name of a given pixel format, strip the leading PIX_FMT_ - and convert to lowercase. For example, PIX_FMT_YUV420P becomes "yuv420p". */ - - /* A -1 terminated list of the acceptable output formats. */ - int pixfmts[2]; - pixfmts[0] = FFMS_GetPixFmt("bgra"); - pixfmts[1] = -1; - - if (FFMS_SetOutputFormatV2(videosource, pixfmts, propframe->EncodedWidth, propframe->EncodedHeight, - FFMS_RESIZER_BICUBIC, &errinfo)) { - /* handle error */ - } - - /* now we're ready to actually retrieve the video frames */ - int framenumber = 0; /* valid until next call to FFMS_GetFrame* on the same video object */ - const FFMS_Frame *curframe = FFMS_GetFrame(videosource, framenumber, &errinfo); - if (curframe == NULL) { - /* handle error */ - } - /* do something with curframe */ - /* continue doing this until you're bored, or something */ - - /* now it's time to clean up */ - FFMS_DestroyVideoSource(videosource); - - /* uninitialize the library. */ - FFMS_Deinit(); - - return 0; -} -``` -And that's pretty much it. Easy, ain't it? - -## Indexing and You -Before opening a media file with FFMS2, you **must** index it. -This is to ensure that keyframe positions, timecode data and other interesting things are known so that frame-accurate seeking is easily possible. - -First, you create an indexer object using [FFMS_CreateIndexer][CreateIndexer] and the source filename. -The indexer can be queried for information about the file using [FFMS_GetNumTracksI][GetNumTracksI], [FFMS_GetTrackTypeI][GetTrackTypeI] and [FFMS_GetCodecNameI][GetCodecNameI] to determine how many tracks there are and what their respective types are. -You can configure things like what tracks to index using [FFMS_TrackIndexSettings][TrackIndexSettings], [FFMS_TrackTypeIndexSettings][TrackTypeIndexSettings], [FFMS_SetAudioNameCallback][SetAudioNameCallback] and [FFMS_SetProgressCallback][SetProgressCallback]. -When you have done so, you call [FFMS_DoIndexing2][DoIndexing2] to perform the actual indexing. -If you change your mind and decide there are no tracks interesting to you in the file, call [FFMS_CancelIndexing][CancelIndexing]. -Both [FFMS_DoIndexing2][DoIndexing2] and [FFMS_CancelIndexing][CancelIndexing] destroys the indexer object and frees its memory. - -When you have indexed the file you can write the index object to a disk file using [FFMS_WriteIndex][WriteIndex], which is useful if you expect to open the same file more than once, since it saves you from reindexing it every time. -It can be particularly time-saving with very large files or files with a lot of audio tracks, since both of those can take quite some time to index. - -To create an index object from a saved disk file, use [FFMS_ReadIndex][ReadIndex]. -Note that index files can only be read by the exact same version of FFMS2 as they were written with. -Attempting to open an index written with a different version will give you an index mismatch error. -If you want to verify that a given index file actually is an index of the source file you think it is, use [FFMS_IndexBelongsToFile][IndexBelongsToFile]. - -## Constants for primaries, transfer and matrix -The constants for these are the same as defined in ISO/IEC 23001-8_2013 § 7.1-7.3. To avoid unnecessary duplication they are no longer declared in ffms.h. If you still need them either transcribe them yourself or include libavutil/pixfmt.h from FFmpeg. - -## Function Reference - -Most functions that can fail in one way or another (as well as some that should be able to but currently don't) support error reporting using the `ErrorInfo` parameter. -Example: -```c++ -char errmsg[1024]; -FFMS_ErrorInfo errinfo; -errinfo.Buffer = errmsg; -errinfo.BufferSize = sizeof(errmsg); -errinfo.ErrorType = FFMS_ERROR_SUCCESS; -errinfo.SubType = FFMS_ERROR_SUCCESS; - -const FFMS_Frame *frame = FFMS_GetFrame(vb, frameno, &errinfo); -/* failure? */ -if (frame == NULL) { - printf("failed to get frame number %d, error message: %s", frameno, errinfo.Buffer); - /* etc... */ -} -``` -How many characters you want to allocate to the error message is up to you; if you allocate too few the messages will get truncated. -1024 should be enough for anyone. - -[errorhandling]: #function-reference - -### FFMS_Init - initializes the library - -[Init]: #ffms_init---initializes-the-library -```c++ -void FFMS_Init(int Unused, int Unused2); -``` -Initializes the FFMS2 library. -This function must be called once at the start of your program, before doing any other FFMS2 function calls. -This function is threadsafe and will only run once. - -#### Arguments - -##### `int Unused` - -This argument is no longer used and is left only for API/ABI compatibility. Pass 0. - -##### `int Unused2` - -This argument is also no longer used and is left only for API/ABI compatibility. Pass 0. - -### FFMS_Deinit - deinitializes the library - -[Deinit]: ##ffms_deinit---deinitializes-the-library -```c++ -void FFMS_Deinit() -``` -Deinitializes the FFMS2 library. -This function must be called once at the end of your program, and no more FFMS2 function calls must be made. -This function is threadsafe and will only be run once. - -### FFMS_GetLogLevel - gets FFmpeg message level - -[GetLogLevel]: #ffms_getloglevel---gets-ffmpeg-message-level -```c++ -int FFMS_GetLogLevel(); -``` -Retrieves FFmpeg's current logging/message level (i.e. how much diagnostic noise it prints to `STDERR`). -If you want to make any sense of the returned value you'd better `#include ` from the FFmpeg source tree to get the relevant constant definitions. -Alternatively, just copy the relevant constant definitions into your own code and hope the FFmpeg devs doesn't change them randomly for no particular reason like they do with everything else. - -### FFMS_SetLogLevel - sets FFmpeg message level - -[SetLogLevel]: #ffms_setloglevel---sets-ffmpeg-message-level -```c++ -void FFMS_SetLogLevel(int Level); -``` -Sets FFmpeg's logging/message level; see [FFMS_GetLogLevel][GetLogLevel] for details. - -### FFMS_CreateVideoSource - creates a video source object - -[CreateVideoSource]: #ffms_createvideosource---creates-a-video-source-object -```c++ -FFMS_VideoSource *FFMS_CreateVideoSource(const char *SourceFile, int Track, FFMS_Index *Index, - int Threads, int SeekMode, FFMS_ErrorInfo *ErrorInfo); -``` -Creates a `FFMS_VideoSource` object with the given properties. -The `FFMS_VideoSource` object represents a video stream, and can be passed to other functions to retreive frames and metadata from said stream. -The video stream in question must be indexed first (see the indexing functions). -Note that the index object is copied into the `FFMS_VideoSource` object upon its creation, so once you've created the video source you can generally destroy the index object immediately, since all info you can retrieve from it is also retrievable from the `FFMS_VideoSource` object. - -#### Arguments - -##### `const char *SourceFile` -The source file to open. Can be an absolute or relative path. - -##### `int Track` -The track number of the video track to open, as seen by the relevant demuxer. -See [FFMS_GetNumTracks][GetNumTracks], [FFMS_GetTrackType][GetTrackType], [FFMS_GetFirstTrackOfType][GetFirstTrackOfType] and their variants for further information on how to determine this. - -##### `FFMS_Index *Index` -A pointer to a FFMS_Index object containing indexing information for the track you want to open. - -##### `int Threads` -The number of decoding threads to use. -Anything less than 1 will use threads equal to the number of CPU cores. -Values >1 have no effect if FFmpeg was not compiled with threading support. - -##### `int SeekMode` -For a list of valid values, see [FFMS_SeekMode][SeekMode]. -Controls how seeking (random access) is handled and hence affects frame accuracy. -You will almost always want to use `FFMS_SEEK_NORMAL`. - -##### `FFMS_ErrorInfo *ErrorInfo` -See [Error handling][errorhandling]. - -#### Return values -Returns a pointer to the created `FFMS_VideoSource` object on success. -Returns `NULL` and sets `ErrorMsg` on failure. - -### FFMS_CreateAudioSource - creates an audio source object - -[CreateAudioSource]: #ffms_createaudiosource---creates-an-audio-source-object -```c++ -FFMS_AudioSource *FFMS_CreateAudioSource(const char *SourceFile, int Track, FFMS_Index *Index, int DelayMode, - FFMS_ErrorInfo *ErrorInfo); -``` -Does exactly the same thing as [FFMS_CreateVideoSource][CreateVideoSource], but for audio tracks. -Except for DelayMode, arguments and return values are identical. - -#### Arguments - -##### `int DelayMode` -Controls how audio with a non-zero first PTS is handled; in other words what FFMS does about audio delay. -Possible arguments are: - - - **FFMS_DELAY_NO_SHIFT**: No adjustment is made; the first decodable audio sample becomes the first sample in the output. - May lead to audio/video desync. - - **FFMS_DELAY_TIME_ZERO**: Samples are created (with silence) or discarded so that sample 0 in the decoded audio starts at time zero. - - **FFMS_DELAY_FIRST_VIDEO_TRACK**: Samples are created (with silence) or discarded so that sample 0 in the decoded audio starts at the same time as frame 0 of the first video track. - This is what most users want and is a sane default. - - **Any integer >= 0**: Identical to `FFMS_DELAY_FIRST_VIDEO_TRACK`, but interprets the argument as a track number and adjusts the audio relative to the video track with that number (if the given track number isn't a video track, audio source creation will fail). - -### FFMS_DestroyVideoSource, FFMS_DestroyAudioSource - deallocates a video or audio source object - -[DestroyVideoSource]: #ffms_destroyvideosource-ffms_destroyaudiosource---deallocates-a-video-or-audio-source-object -[DestroyAudioSource]: #ffms_destroyvideosource-ffms_destroyaudiosource---deallocates-a-video-or-audio-source-object -```c++ -void FFMS_DestroyVideoSource(FFMS_VideoSource *V); -void FFMS_DestroyAudioSource(FFMS_AudioSource *A); -``` -Deallocates the given `FFMS_VideoSource` or `FFMS_AudioSource` object and frees the memory allocated by [FFMS_CreateVideoSource][CreateVideoSource] or [FFMS_CreateAudioSource][CreateAudioSource], respectively. - -### FFMS_GetVideoProperties - retrieves video properties - -[GetVideoProperties]: #ffms_getvideoproperties---retrieves-video-properties -```c++ -const FFMS_VideoProperties *FFMS_GetVideoProperties(FFMS_VideoSource *V); -``` -Retreives the video properties from the given `FFMS_VideoSource` object and stores them in a [FFMS_VideoProperties][VideoProperties] struct. -Returns a pointer to said struct. - -### FFMS_GetAudioProperties - retrieves audio properties - -[GetAudioProperties]: #ffms_getaudioproperties---retrieves-audio-properties -```c++ -const FFMS_AudioProperties *FFMS_GetAudioProperties(FFMS_AudioSource *A); -``` -Does the exact same thing as [FFMS_GetVideoProperties][GetVideoProperties], but for an `FFMS_AudioSource` object. -See [FFMS_AudioProperties][AudioProperties]. - -### FFMS_GetFrame - retrieves a given video frame - -[GetFrame]: #ffms_getframe---retrieves-a-given-video-frame -```c++ -const FFMS_Frame *FFMS_GetFrame(FFMS_VideoSource *V, int n, FFMS_ErrorInfo *ErrorInfo); -``` -Gets and decodes a video frame from the video stream represented by the given `FFMS_VideoSource` object and stores it in a [FFMS_Frame][Frame] struct. -The colorspace and resolution of the frame can be changed by calling [FFMS_SetOutputFormatV2][SetOutputFormatV2] with the appropriate parameters before calling this function. -Note that this function is not thread-safe (you can only request one frame at a time from a given `FFMS_VideoSource` object) and that the returned pointer to the `FFMS_Frame` is a `const` pointer. - -#### Arguments - -##### `FFMS_VideoSource *V` -A pointer to the `FFMS_VideoSource` object that represents the video stream you want to retrieve a frame from. - -##### `int n` -The frame number to get. Frame numbering starts from zero, and hence the first frame is number 0 (not 1) and the last frame is number `FFMS_VideoProperties->NumFrames` minus 1. -Requesting a frame number beyond the stream end or before the stream start (i.e. negative) may cause undefined behavior. - -##### `FFMS_ErrorInfo *ErrorInfo` -See [Error handling][errorhandling]. - -#### Return values -Returns a pointer to the `FFMS_Frame` on success. Returns `NULL` and sets `ErrorMsg` on failure. - -The returned frame is owned by the given `FFMS_VideoSource`, and remains valid until the video source is destroyed, a different frame is requested from the video source, or the video source's input or output format is changed. -Note that while `FFMS_GetFrame` tends to return the same pointer with each call, it is not safe to rely on this as the output frame will sometimes be reallocated. - -### FFMS_GetFrameByTime - retrieves a video frame at a given timestamp - -[GetFrameByTime]: #ffms_getframebytime---retrieves-a-video-frame-at-a-given-timestamp -```c++ -const FFMS_Frame *FFMS_GetFrameByTime(FFMS_VideoSource *V, double Time, FFMS_ErrorInfo *ErrorInfo); -``` -Does the exact same thing as [FFMS_GetFrame][GetFrame] except instead of giving it a frame number you give it a timestamp in seconds, and it will retrieve the frame that starts closest to that timestamp. -This function exists for the people who are too lazy to build and traverse a mapping between frame numbers and timestamps themselves. - -### FFMS_GetAudio - decodes a number of audio samples - -[GetAudio]: #ffms_getaudio---decodes-a-number-of-audio-samples -```c++ -int FFMS_GetAudio(FFMS_AudioSource *A, void *Buf, int64_t Start, int64_t Count, FFMS_ErrorInfo *ErrorInfo); -``` -Decodes the requested audio samples from the audio stream represented by the given `FFMS_AudioSource` object and stores them in the given buffer. -Note that this function is not thread-safe; you can only request one decoding operation at a time from a given `FFMS_AudioSource` object. - -#### Arguments - -##### `FFMS_AudioSource *A` -A pointer to the `FFMS_AudioSource` object that represents the audio stream you want to get samples from. - -##### `void *Buf` -A pointer to the buffer where the decoded samples will end up. -You are responsible for allocating and freeing this buffer yourself, so you better check the [FFMS_AudioProperties][GetAudioProperties] for the sample format, number of channels, channel layout etc first, so you know how much memory you need to allocate. -The formula to calculate the required size of the buffer is (obviously) `num_bytes = bytes_per_sample * num_channels * num_samples`. - -##### `int64_t Start, int64_t Count` -The range of samples you want decoded. -The output is `Count` samples long, starting from `Start` (inclusive). -Like video frame numbers, sample numbers start from zero and hence the last sample in the stream is number `FFMS_AudioProperties->NumSamples` minus 1. -Requesting samples beyond the stream end or before the stream start may result in undefined behavior. - -##### `FFMS_ErrorInfo *ErrorInfo` -See [Error handling][errorhandling]. - -#### Return values -Returns 0 on success. -Returns non-0 and sets `ErrorMsg` on failure. - -### FFMS_SetOutputFormatV2 - sets the output format for video frames - -[SetOutputFormatV2]: #ffms_setoutputformatv2---sets-the-output-format-for-video-frames -```c++ -int FFMS_SetOutputFormatV2(FFMS_VideoSource *V, int *TargetFormats, int Width, int Height, int Resizer, - FFMS_ErrorInfo *ErrorInfo); -``` -Sets the colorspace and frame dimensions to be used for output of frames from the given `FFMS_VideoSource` by all further calls to [FFMS_GetFrame][GetFrame] and [FFMS_GetFrameByTime][GetFrameByTime], until next time you call `FFMS_SetOutputFormatV2` or [FFMS_ResetOutputFormatV][ResetOutputFormatV]. -You can change the output format at any time without having to reinitialize the `FFMS_VideoSource` object or anything else. -Can be used to convert the video to grayscale or monochrome if you are so inclined. -If you provided a list of more than one colorspace/pixelformat, you should probably check the [FFMS_Frame][Frame] properties afterwards to see which one got selected. -And remember to do so for EVERY frame or you may get a nasty surprise. -Added in version 2.16.3.0 and replaces `FFMS_SetOutputFormatV`. - -#### Arguments - -##### `FFMS_VideoSource *V` -A pointer to the `FFMS_VideoSource` object that represents the video stream you want to change the output format for. - -##### `int *TargetFormats` -The desired output colorspace(s). -It is a -1 terminated list of acceptable output colorspace to choose from. -The destination that gives the least lossy conversion from the source colorspace will automatically be selected, **on a frame basis**. -To get the integer constant representing a given colorspace, see [FFMS_GetPixFmt][GetPixFmt]. - -Example: -```c++ -int targetformats[3]; -targetformats[0] = pixfmt1; -targetformats[1] = pixfmt2; -targetformats[2] = -1; -``` - -##### `int Width, int Height` -The desired image dimensions, in pixels. -If you do not want to resize just pass the input dimensions. -Passing invalid dimensions (like 0 or negative) has undefined behavior. - -##### `int Resizer` -The desired image resizing algorithm, represented by an integer as enumerated in [FFMS_Resizers][Resizers]. -You must choose one even if you're not actually rescaling the image, because the video may change resolution mid-stream and then you will be using a resizer whether you want it or not (you will only know that the resolution changed after you actually decoded a frame with a new resolution), and it may also get used for rescaling subsampled chroma planes. - -##### `FFMS_ErrorInfo *ErrorInfo` -See [Error handling][errorhandling]. - -#### Return values -Returns 0 on success. -Returns non-0 and sets `ErrorMsg` on failure. - -### FFMS_ResetOutputFormatV - resets the video output format - -[ResetOutputFormatV]: #ffms_resetoutputformatv---resets-the-video-output-format -```c++ -void FFMS_ResetOutputFormatV(FFMS_VideoSource *V); -``` -Resets the output format for the given `FFMS_VideoSource` object so that no conversion takes place. -Note that the results of this function may vary wildly, particularly if the video changes resolution mid-stream. -If you call it, you'd better call [FFMS_GetFrame][GetFrame] afterwards and examine the properties to see what you actually ended up with. - -### FFMS_SetInputFormatV - override the source format for video frames - -[SetInputFormatV]: #ffms_setinputformatv---override-the-source-format-for-video-frames -```c++ -int FFMS_SetInputFormatV(FFMS_VideoSource *V, int ColorSpace, int ColorRange, int PixelFormat, - FFMS_ErrorInfo *ErrorInfo); -``` -Override the source colorspace passed to SWScale for conversions and resizing for all further calls to [FFMS_GetFrame][GetFrame] and [FFMS_GetFrameByTime][GetFrameByTime], until next time you call `FFMS_SetInputFormatV` or [FFMS_ResetInputFormatV][ResetInputFormatV]. -You can change the input format at any time without having to reinitialize the `FFMS_VideoSource` object or anything else. -This is intended primarily for compatibility with programs which use the wrong YUV colorspace when converting to or from RGB, but can also be useful for files which have incorrect colorspace flags. -Values passed are not checked for sanity; if you wish you may tell FFMS2 to pretend that a RGB files is actually YUV using this function, but doing so is unlikely to have useful results. -This function only has an effect if the output format is also set with [FFMS_SetOutputFormatV2][SetOutpurFormatV2]. -Added in version 2.17.1.0. - -#### Arguments - -##### `FFMS_VideoSource *V` -A pointer to the `FFMS_VideoSource` object that represents the video stream you want to change the input format for. - -##### `int ColorSpace` -The desired input colorspace, or FFMS_CS_UNSPECIFIED to leave it unchanged. -See [FFMS_ColorSpaces][ColorSpaces]. - -##### `int ColorRange` -The desired input colorrange, or FFMS_CR_UNSPECIFIED to leave it unchanged. -See [FFMS_ColorRanges][ColorRanges]. - -##### `int PixelFormat` -The desired input pixel format; see [FFMS_GetPixFmt][GetPixFmt]. `FFMS_GetPixFmt("")` will leave the pixel format unchanged. - -##### `FFMS_ErrorInfo *ErrorInfo` -See [Error handling][errorhandling]. - -#### Return values -Returns 0 on success. -Returns non-0 and sets `ErrorMsg` on failure. - -### FFMS_ResetInputFormatV - resets the video input format - -[ResetInputFormatV]: #ffms_resetinputformatv---resets-the-video-input-format -```c++ -void FFMS_ResetInputFormatV(FFMS_VideoSource *V); -``` -Resets the input format for the given `FFMS_VideoSource` object to the values specified in the source file. - -### FFMS_DestroyIndex - deallocates an index object - -[DestroyIndex]: #ffms_destroyindex---deallocates-an-index-object -```c++ -void FFMS_DestroyFFMS_Index(FFMS_Index *Index); -``` -Deallocates the given `FFMS_Index` object and frees the memory that was allocated when it was created. - -### FFMS_GetErrorHandling - gets which error handling mode was used when creating the given index - -[GetErrorHandling]: #ffms_geterrorhandling---gets-which-error-handling-mode-was-used-when-creating-the-given-index -```c++ -int FFMS_GetErrorHandling(FFMS_Index *Index); -``` -Returns the value of the ErrorHandling parameter which was passed to [FFMS_DoIndexing2][DoIndexing2]. - -### FFMS_GetFirstTrackOfType - gets the track number of the first track of a given type - -[GetFirstTrackOfType]: #ffms_getfirsttrackoftype---gets-the-track-number-of-the-first-track-of-a-given-type -```c++ -int FFMS_GetFirstTrackOfType(FFMS_Index *Index, int TrackType, FFMS_ErrorInfo *ErrorInfo); -``` -Finds the first track of the given [FFMS_TrackType][TrackType] in the given `FFMS_Index` and returns its track number, suitable for use as an argument to [FFMS_CreateVideoSource][CreateVideoSource] or [FFMS_CreateAudioSource][CreateAudioSource], as well as to some other functions. - -#### Arguments - -##### `FFMS_Index *Index` -A pointer to the `FFMS_Index` object that represents the media file you want to look for tracks in. - -##### `int TrackType` -The track type to look for. -See [FFMS_TrackType][TrackType]. - -##### `FFMS_ErrorInfo *ErrorInfo` -See [Error handling][errorhandling]. - -#### Return values -Returns the track number (an integer greater than or equal to 0) on success. -Returns a negative integer and sets ErrorMsg on failure (i.e. if no track of the given type was found). - -### FFMS_GetFirstIndexedTrackOfType - gets the track number of the first track of a given type - -[GetFirstIndexedTrackOfType]: #ffms_getfirstindexedtrackoftype---gets-the-track-number-of-the-first-track-of-a-given-type -```c++ -int FFMS_GetFirstIndexedTrackOfType(FFMS_Index *Index, int TrackType, FFMS_ErrorInfo *ErrorInfo); -``` -Does the exact same thing as [FFMS_GetFirstTrackOfType][GetFirstTrackOfType] but ignores tracks that have not been indexed. - -### FFMS_GetNumTracks - gets the number of tracks in a given index - -[GetNumTracks]: #ffms_getnumtracks---gets-the-number-of-tracks-in-a-given-index -```c++ -int FFMS_GetNumTracks(FFMS_Index *Index); -``` -Returns the total number of tracks in the media file represented by the given `FFMS_Index`. - -### FFMS_GetNumTracksI - gets the number of tracks in a given indexer - -[GetNumTracksI]: #ffms_getnumtracksi---gets-the-number-of-tracks-in-a-given-indexer -```c++ -int FFMS_GetNumTracksI(FFMS_Indexer *Indexer); -``` -Returns the total number of tracks in the media file represented by the given `FFMS_Indexer`. -In other words, does the same thing as [FFMS_GetNumTracks][GetNumTracks] but does not require indexing the entire file first. - -### FFMS_GetTrackType - gets the track type of a given track - -[GetTrackType]: #ffms_gettracktype---gets-the-track-type-of-a-given-track -```c++ -int FFMS_GetTrackType(FFMS_Track *T); -``` -Returns an integer representing the [FFMS_TrackType][TrackType] of the track represented by the given `FFMS_Track` object. - -### FFMS_GetTrackTypeI - gets the track type of a given track - -[GetTrackTypeI]: #ffms_gettracktypei---gets-the-track-type-of-a-given-track -```c++ -int FFMS_GetTrackTypeI(FFMS_Indexer *Indexer, int Track); -``` -Returns an integer representing the [FFMS_TrackType][TrackType] of the track number `Track` in the media file represented by the given `FFMS_Indexer`. -In other words, does the same thing as [FFMS_GetTrackType][GetTrackType], but does not require having indexed the file first. -If you have indexed the file, use [FFMS_GetTrackType][GetTrackType] instead since the `FFMS_Indexer` object is destructed when the index is created. -Note that specifying an invalid track number may lead to undefined behavior. - -### FFMS_GetCodecNameI - gets the name of the codec used for a given track - -[GetCodecNameI]: #ffms_getcodecnamei---gets-the-name-of-the-codec-used-for-a-given-track -```c++ -const char *FFMS_GetCodecNameI(FFMS_Indexer *Indexer, int Track); -``` -Returns the human-readable name ("long name" in FFmpeg terms) of the codec used in the given track number in the media file represented by the given `FFMS_Indexer` object. -Useful if you want to, say, pop up a menu asking the user which tracks he or she wishes to index. -Note that specifying an invalid track number may lead to undefined behavior. - -### FFMS_GetFormatNameI - gets the name of the container format used in the given indexer - -[GetFormatNameI]: #ffms_getformatnamei---gets-the-name-of-the-container-format-used-in-the-given-indexer -```c++ -const char *FFMS_GetFormatNameI(FFMS_Indexer *Indexer); -``` -Returns the human-readable name ("long name" in FFmpeg terms) of the container format used by the file represented by the given `FFMS_Indexer`. - -### FFMS_GetNumFrames - gets the number of frames in a given track - -[GetNumFrames]: #ffms_getnumframes---gets-the-number-of-frames-in-a-given-track -```c++ -int FFMS_GetNumFrames(FFMS_Track *T); -``` -Returns the number of frames in the track represented by the given `FFMS_Track`. -For a video track this is the number of video frames, which can be useful; for an audio track it's the number of packets, which is almost never useful, since nothing in the API exposes those. -A return value of 0 indicates the track has not been indexed. - -### FFMS_GetFrameInfo - gets information about a given frame - -[GetFrameInfo]: #ffms_getframeinfo---gets-information-about-a-given-frame -```c++ -const FFMS_FrameInfo *FFMS_GetFrameInfo(FFMS_Track *T, int Frame); -``` -Gets information about the given frame (identified by its frame number) from the indexing information in the given `FFMS_Track` and stores it in a [FFMS_FrameInfo][FrameInfo] struct. -Using this function on a `FFMS_Track` representing a non-video track has undefined behavior. - -#### Arguments - -##### `FFMS_Track *T` -A pointer to the `FFMS_Track` object that represents the video track containing the frame you want to get information about. - -##### `int Frame` -The frame number to get information about. -See [FFMS_GetFrame][GetFrame] for information about frame numbers. -Requesting information about a frame before the start or after the end of the video track may result in undefined behavior, so don't do that. - -##### `FFMS_ErrorInfo *ErrorInfo` -See [Error handling][errorhandling]. - -#### Return values -Returns a pointer to the [FFMS_FrameInfo][FrameInfo] struct on success. -Returns `NULL` and sets `ErrorMsg` on failure. - -### FFMS_GetTrackFromIndex - retrieves track info from an index - -[GetTrackFromIndex]: #ffms_gettrackfromindex---retrieves-track-info-from-an-index -```c+++ -FFMS_Track *FFMS_GetTrackFromIndex(FFMS_Index *Index, int Track); -``` -Gets track data for the given track number from the given `FFMS_Index` object, stores it in a `FFMS_Track` object and returns a pointer to it. -Use this function if you don't want to (or cannot) open the track with [FFMS_CreateVideoSource][CreateVideoSource] or [FFMS_CreateAudioSource][CreateAudioSource] first. -If you already have a `FFMS_VideoSource` or `FFMS_AudioSource` object it's safer to use [FFMS_GetTrackFromVideo][GetTrackFromVideo] or [FFMS_GetTrackFromAudio][GetTrackFromAudio] instead. -Note that specifying a nonexistent or invalid track number leads to undefined behavior (usually an access violation). -Also note that the returned `FFMS_Track` object is only valid until its parent `FFMS_Index` object is destroyed. - -#### Arguments - -##### `FFMS_Index *Index` -A pointer to the `FFMS_Index` object that represents the media file containing the track whose index information you want to get. - -##### `int Track` -The track number, as seen by the relevant demuxer (see [FFMS_GetNumTracks][GetNumTracks], [FFMS_GetTrackType][GetTrackType], [FFMS_GetFirstTrackOfType][GetFirstTrackOfType] and their variants). - -##### `FFMS_ErrorInfo *ErrorInfo` -See [Error handling][errorhandling]. - -#### Return values -Returns the `FFMS_Track` on success. -Note that requesting indexing information for a track that has not been indexed will not cause an error, it will just return an empty `FFMS_Track` (check for >0 frames using [FFMS_GetNumFrames][GetNumFrames] to see if the returned object actually contains indexing information). - -### FFMS_GetTrackFromVideo, FFMS_GetTrackFromAudio - retrieves track info from audio or video source - -[GetTrackFromVideo]: #ffms_gettrackfromvideo-ffms_gettrackfromaudio---retrieves-track-info-from-audio-or-video-source -[GetTrackFromAudio]: #ffms_gettrackfromvideo-ffms_gettrackfromaudio---retrieves-track-info-from-audio-or-video-source -```c++ -FFMS_Track *FFMS_GetTrackFromVideo(FFMS_VideoSource *V); -FFMS_Track *FFMS_GetTrackFromAudio(FFMS_AudioSource *A); -``` -Gets information about the track represented by the given `FFMS_VideoSource` or `FFMS_AudioSource` object and returns a pointer to a `FFMS_Track` object containing said information. -It's generally safer to use these functions instead of [FFMS_GetTrackFromIndex][GetTrackFromIndex], since unlike that function they cannot cause access violations if you specified an nonexistent tracknumber, return a `FFMS_Track` that doesn't actually contain any indexing information, or return an object that ceases to be valid when the index is destroyed. -Note that the returned `FFMS_Track` object is only valid until its parent `FFMS_VideoSource` or `FFMS_AudioSource` object is destroyed. - -### FFMS_GetTimeBase - retrieves the time base for the given track - -[GetTimeBase]: #ffms_gettimebase---retrieves-the-time-base-for-the-given-track -```c++ -const FFMS_TrackTimeBase *FFMS_GetTimeBase(FFMS_Track *T); -``` -Finds the basic time unit for the track represented by the given `FFMS_Track`, stores it in a [FFMS_TrackTimeBase][TrackTimeBase] struct and returns a pointer to said struct. -Note that it is only meaningful for video tracks. - -### FFMS_WriteTimecodes - writes timecodes for the given track to disk - -[WriteTimecodes]: #ffms_writetimecodes---writes-timecodes-for-the-given-track-to-disk -```c++ -int FFMS_WriteTimecodes(FFMS_Track *T, const char *TimecodeFile, FFMS_ErrorInfo *ErrorInfo); -``` -Writes Matroska v2 timecodes for the track represented by the given `FFMS_Track` to the given file. -Only meaningful for video tracks. - -#### Arguments - -##### `FFMS_Track *T` -A pointer to the `FFMS_Track` object that represents the video track you want to write timecodes for. - -##### `const char *TimecodeFile` -The filename to write to. -Can be a relative or absolute path. -The file will be truncated and overwritten if it already exists. - -##### `FFMS_ErrorInfo *ErrorInfo` -See [Error handling][errorhandling]. - -#### Return values -Returns 0 on success. -Returns non-0 and sets `ErrorMsg` on failure. - -### FFMS_CreateIndexer - creates an indexer object for the given file - -[CreateIndexer]: #ffms_createindexer---creates-an-indexer-object-for-the-given-file -```c++ -FFMS_Indexer *FFMS_CreateIndexer(const char *SourceFile, FFMS_ErrorInfo *ErrorInfo); -``` -Creates a `FFMS_Indexer` object for the given `SourceFile` and returns a pointer to it. -See [Indexing and You](#indexing-and-you) for details on how to use the indexer. -Is basically a shorthand for `FFMS_CreateIndexerWithDemuxer(SourceFile, FFMS_SOURCE_DEFAULT, ErrorInfo)`. - -#### Return values -Returns a pointer to the `FFMS_Indexer` on success. -Returns `NULL` and sets `ErrorMsg` on failure. - -#### Return values -Returns a pointer to the `FFMS_Indexer` on success. -Returns `NULL` and sets `ErrorMsg` on failure. - -### FFMS_DoIndexing2 - indexes the file represented by an indexer object - -[DoIndexing2]: #ffms_doindexing2---indexes-the-file-represented-by-an-indexer-object -```c++ -FFMS_Index *FFMS_DoIndexing2(FFMS_Indexer *Indexer, int ErrorHandling, FFMS_ErrorInfo *ErrorInfo); -``` -Runs the passed indexer and returns a `FFMS_Index` object representing the file in question. -See the Indexing and You section for more details about indexing. -Note that calling this function destroys the `FFMS_Indexer` object and frees the memory allocated by [FFMS_CreateIndexer][CreateIndexer] (even if indexing fails for any reason). - -#### Arguments - -##### `FFMS_Indexer *Indexer` -The Indexer to run. -Created with [FFMS_CreateIndexer][CreateIndexer] and configured with [FFMS_TrackIndexSettings][TrackIndexSettings], [FFMS_TrackTypeIndexSettings][TrackTypeIndexSettings], [FFMS_SetAudioNameCallback][SetAudioNameCallback] and [FFMS_SetProgressCallback][SetProgressCallback]. - -##### `int ErrorHandling` -Depending on the setting audio decoding errors will have different results. -See [FFMS_IndexErrorHandling][IndexErrorHandling] for valid values. -FFMS_IEH_STOP_TRACK should be the best default to just make it work. -Has no effect for tracks which have dumping enabled, which will always cause indexing to fail on audio decoding errors. - -##### `FFMS_ErrorInfo *ErrorInfo` -See [Error handling][errorhandling]. - -#### Return values -Returns a pointer to the created `FFMS_Index` on success. -Returns `NULL` and sets `ErrorMsg` on failure. - - -### FFMS_TrackIndexSettings - enable or disable indexing of a track - -[TrackIndexSettings]: #ffms_trackindexsettings---enable-or-disable-indexing-of-a-track -```c++ -void FFMS_TrackIndexSettings(FFMS_Indexer *Indexer, int Track, int Index, int Dump); -``` - -Enable or disable indexing of a track, and for audio tracks, enable or disable dumping the decoded audio during indexing. - -#### Arguments - -##### `FFMS_Indexer *Indexer` -The indexer to configure. - -##### `int Track` -The track index to configure. - -##### `int Index` -Enable indexing the given track if non-zero, and disable if zero. -By default, all video tracks are indexed and all audio tracks are not. - -##### `int Dump` -Currently ignored. - -By default, no tracks are dumped. - -### FFMS_TrackTypeIndexSettings - enable or disable indexing of a tracks of a given type - -[TrackTypeIndexSettings]: #ffms_tracktypeindexsettings---enable-or-disable-indexing-of-a-tracks-of-a-given-type -```c++ -void FFMS_TrackTypeIndexSettings(FFMS_Indexer *Indexer, int TrackType, int Index, int Dump); -``` - -Like [FFMS_TrackIndexSettings][TrackIndexSettings], but configures all tracks of the given [FFMS_TrackType][TrackType] at once. - -### FFMS_SetProgressCallback - set callback function for indexing progress updates - -[SetProgressCallback]: #ffms_setprogresscallback---set-callback-function-for-indexing-progress-updates -```c++ -void FFMS_SetProgressCallback(FFMS_Indexer *Indexer, TIndexCallback IC, void *ICPrivate); -``` - -If you supply a progress callback, FFMS2 will call it regularly during indexing to report progress and give you the chance to interrupt indexing. - -The callback should have the following signature: -```c++ -int FFMS_CC FunctionName(int64_t Current, int64_t Total, void *ICPrivate); -``` -The callback function's arguments are as follows: - - `int64_t Current, int64_t Total` - The indexing progress (amount done/total amount). - - `void *Private` - the same pointer as the one you passed as the `Private` argument to `FFMS_SetProgressCallback`. - Can be used for anything you like, but one example (in a GUI program) is to use it for passing a progress ticker object that you can update with each call to the indexing function. - -Return 0 from the callback function to continue indexing, non-0 to cancel indexing (returning non-0 will make `FFMS_DoIndexing2` fail with the reason "indexing cancelled by user"). - -### FFMS_CancelIndexing - destroys the given indexer object - -[CancelIndexing]: #ffms_cancelindexing---destroys-the-given-indexer-object -```c++ -void FFMS_CancelIndexing(FFMS_Indexer *Indexer); -``` -Destroys the given `FFMS_Indexer` object and frees the memory allocated by [FFMS_CreateIndexer][CreateIndexer]. - -### FFMS_ReadIndex - reads an index file from disk - -[ReadIndex]: #ffms_readindex---reads-an-index-file-from-disk -```c++ -FFMS_Index *FFMS_ReadIndex(const char *IndexFile, FFMS_ErrorInfo *ErrorInfo); -``` -Attempts to read indexing information from the given `IndexFile`, which can be an absolute or relative path. -Returns the `FFMS_Index` on success; returns `NULL` and sets `ErrorMsg` on failure. - -### FFMS_ReadIndexFromBuffer - reads an index from a user-supplied buffer - -[ReadIndexFromBuffer]: #ffms_readindexfrombffer---reads-an-index-from-a-user-supplied-buffer -```c++ -FFMS_Index *FFMS_ReadIndexFromBuffer(const uint8_t *Buffer, size_t Size, FFMS_ErrorInfo *ErrorInfo); -``` - -Attempts to read indexing information from the super supplied buffer, `Buffer, of size `Size`. -Returns the `FFMS_Index` on success; returns `NULL` and sets `ErrorMsg` on failure. - -### FFMS_IndexBelongsToFile - check if a given index belongs to a given file - -[IndexBelongsToFile]: #ffms_indexbelongstofile---check-if-a-given-index-belongs-to-a-given-file -```c++ -int FFMS_IndexBelongsToFile(FFMS_Index *Index, const char *SourceFile, FFMS_ErrorInfo *ErrorInfo); -``` -Makes a heuristic (but very reliable) guess about whether the given `FFMS_Index` is an index of the given `SourceFile` or not. -Useful to determine if the index object you just read with [FFMS_ReadIndex][ReadIndex] is actually relevant to your interests, since the only two ways to pair up index files with source files are a) trust the user blindly, or b) comparing the filenames; neither is very reliable. - -#### Arguments - -##### `FFMS_Index *Index` -The index object to check. - -##### `const char *SourceFile` -The source file to verify the index against. - -#### Return values -Returns 0 if the given index is determined to belong to the given file. -Returns non-0 and sets `ErrorMsg` otherwise. - -### FFMS_WriteIndex - writes an index object to disk - -[WriteIndex]: #ffms_writeindex---writes-an-index-object-to-disk -```c++ -int FFMS_WriteIndex(const char *IndexFile, FFMS_Index *TrackIndices, FFMS_ErrorInfo *ErrorInfo); -``` -Writes the indexing information from the given `FFMS_Index` to the given `IndexFile` (which can be an absolute or relative path; it will be truncated and overwritten if it already exists). -Returns 0 on success; returns non-0 and sets `ErrorMsg` on failure. - -### FFMS_WriteIndexToBuffer - writes an index to memory - -[WriteIndexToBuffer]: #ffms_writeindextobuffer---writes-an-index-to-memory -```c++ -int FFMS_WriteIndexToBuffer(uint8_t **BufferPtr, size_t *Size, FFMS_Index *Index, FFMS_ErrorInfo *ErrorInfo) -``` - -Writes the indexing information from the given `FFMS_Index` to memory, and sets `BufferPtr` to point to the buffer, and `Size` to the size of the returned buffer. Users are required to free the resulting buffer with [FFMS_FreeIndexBuffer][FreeIndexBuffer]. -Returns 0 on success; returns non-0 and sets `ErrorMsg` on failure. - -### FFMS_FreeIndexBuffer - frees a buffer allocated by [FFMS_WriteIndexToBuffer][WriteIndexToBuffer] - -[FreeIndexBuffer]: #ffms_freeindexbuffer---frees-a-buffer-alloctaed-by-ffms_writeindextobuffer -```c++ -void FFMS_FreeIndexBuffer(uint8_t **BufferPtr) -``` - -Frees the buffer pointed to by `BufferPtr` and sets it to NULL. - -### FFMS_GetPixFmt - gets a colorspace identifier from a colorspace name - -[GetPixFmt]: #ffms_getpixfmt---gets-a-colorspace-identifier-from-a-colorspace-name -```c++ -int FFMS_GetPixFmt(const char *Name); -``` -Translates a given colorspace/pixel format `Name` to an integer constant representing it, suitable for passing to [FFMS_SetOutputFormatV2][SetOutputFormatV2] (after some manipulation, see that function for details). -This function exists so that you don't have to include a FFmpeg header file in every single program you ever write. -For a list of colorspaces and their names, see `libavutil/pixfmt.h`. -To get the name of a colorspace, strip the leading `PIX_FMT_` and convert the remainder to lowercase. -For example, the name of `PIX_FMT_YUV420P` is `yuv420p`. -It is strongly recommended to use this function instead of including pixfmt.h directly, since this function guarantees that you will always get the constant definitions from the version of FFmpeg that FFMS2 was linked against. - -#### Arguments - -##### `const char *Name` -The name of the desired colorspace/pixel format, as a nul-terminated ASCII string. - -#### Return values -Returns the integer constant representing the given colorspace/pixel format on success. -Returns the integer constant representing `PIX_FMT_NONE` (that is, -1) on failure (i.e. if no matching colorspace was found), but note that you can call `FFMS_GetPixFmt("none")` and get the same return value without it being a failed call, strictly speaking. - -### FFMS_GetVersion - returns FFMS_VERSION constant - -[GetVersion]: #ffms_getversion---returns-ffms_version-constant -```c++ -int FFMS_GetVersion(); -``` -Returns the FFMS_VERSION constant as defined in ffms.h as an integer. - -## Data Structures -The following public data structures may be of interest. - -### FFMS_Frame - -[Frame]: #ffms_frame -```c++ -typedef struct { - const uint8_t *Data[4]; - int Linesize[4]; - int EncodedWidth; - int EncodedHeight; - int EncodedPixelFormat; - int ScaledWidth; - int ScaledHeight; - int ConvertedPixelFormat; - int KeyFrame; - int RepeatPict; - int InterlacedFrame; - int TopFieldFirst; - char PictType; - int ColorSpace; - int ColorRange; - int ColorPrimaries; - int TransferCharateristics; - int ChromaLocation; - int HasMasteringDisplayPrimaries; - double MasteringDisplayPrimariesX[3]; - double MasteringDisplayPrimariesY[3]; - double MasteringDisplayWhitePointX; - double MasteringDisplayWhitePointY; - int HasMasteringDisplayLuminance; - double MasteringDisplayMinLuminance; - double MasteringDisplayMaxLuminance; - int HasContentLightLevel; - unsigned int ContentLightLevelMax; - unsigned int ContentLightLevelAverage; -} FFMS_Frame; -``` -A struct representing a video frame. -The fields are: - - `uint8_t *Data[4]` - An array of pointers to the picture planes (fields containing actual pixel data). - Planar formats use more than one plane, for example YV12 uses one plane each for the Y, U and V data. - Packed formats (such as the various RGB32 flavors) use only the first plane. - If you want to determine if plane `i` contains data or not, check for `FFMS_Frame->Linesize[i] != 0`. - - `int Linesize[4]` - An array of integers representing the length of each scan line in each of the four picture planes, in bytes. - In alternative terminology, this is the "pitch" of the plane. - Usually, the total size in bytes of picture plane `i` is `FFMS_Frame->Linesize[i] * FFMS_VideoProperties->Height`, but do note that some pixel formats (most notably YV12) has vertical chroma subsampling, and then the U/V planes may be of a different height than the primary plane. - This may be negative; if so the image is stored inverted in memory and `Data` actually points of the last row of the data. - You usually do not need to worry about this, as it mostly works correctly by default if you're processing the image correctly. - - `int EncodedWidth; int EncodedHeight` - The original resolution of the frame (in pixels), as encoded in the compressed file, before any scaling was applied. - Note that must not necessarily be the same for all frames in a stream. - - `int EncodedPixelFormat` - The original pixel format of the frame, as encoded in the compressed file. - - `int ScaledWidth; int ScaledHeight;` - The output resolution of the frame (in pixels), i.e. the resolution of what is actually stored in the `Data` field. Set to -1 if no scaling is done. - - `int ConvertedPixelFormat` - The output pixel format of the frame, i.e. the pixel format of what is actually stored in the `Data` field. - - `int KeyFrame` - Nonzero if the frame is a keyframe, 0 otherwise. - - `int RepeatPict` - An integer repesenting the RFF flag for this frame; i.e. the frame shall be displayed for `1+RepeatPict` time units, where the time units are expressed in the special RFF timebase available in `FFMS_VideoProperties->RFFDenominator` and `FFMS_VideoProperties->RFFNumerator`. - Note that if you actually end up using this, you need to ignore the usual timestamps (calculated via the `FFMS_TrackTimeBase` and the frame PTS) since they are fundamentally incompatible with RFF flags. - - `int InterlacedFrame` - Nonzero if the frame was coded as interlaced, zero otherwise. - - `int TopFieldFirst` - Nonzero if the frame has the top field first, zero if it has the bottom field first. - Only relevant if `InterlacedFrame` is nonzero. - - `char PictType` - A single character denoting coding type (I/B/P etc) of the compressed frame. - See the Constants and Preprocessor Definitions section for more information about what the different letters mean. - - `int ColorSpace` - Identifies the YUV color coefficients used in the frame. - Same as in the MPEG-2 specs; see the [FFMS_ColorSpaces][ColorSpaces] enum. - - `int ColorRange` - Identifies the luma range of the frame. - See the [FFMS_ColorRanges][ColorRanges] enum. - - `int ColorPrimaries;` - Identifies the color primaries of the frame. - - `int TransferCharateristics;` - Identifies the transfer characteristics of the frame. - - `int ChromaLocation;` - Identifies the chroma location for the frame. Corresponds to [FFMS_ChromaLocations][ChromaLocations]. - - `int HasMasteringDisplayPrimaries;` - If this is non-zero, the following four properties are set. - - `double MasteringDisplayPrimariesX[3];` - RGB chromaticy coordinates of the mastering display (x coord). - - `double MasteringDisplayPrimariesY[3];` - RGB chromaticy coordinates of the mastering display (y coord). - - `double MasteringDisplayWhitePointX;` - White point coordinate of the mastering display (x coord). - - `double MasteringDisplayWhitePointY;` - White point coordinate of the mastering display (y coord). - - `int HasMasteringDisplayLuminance;` - If this is non-zero, the following two properties are set. - - `double MasteringDisplayMinLuminance;` - Minimum luminance of the mastering display (cd/m^2). - - `double MasteringDisplayMaxLuminance;` - Maximum luminance of the mastering display (cd/m^2). - - `int HasContentLightLevel;` - If this is non-zero, the following two properties are set. - - `unsigned int ContentLightLevelMax;` - Maximum content luminance (cd/m^2). - - `unsigned int ContentLightLevelAverage;` - Average content luminance (cd/m^2). - -### FFMS_TrackTimeBase - -[TrackTimeBase]: #ffms_tracktimebase -```c++ -typedef struct { - int64_t Num; - int64_t Den; -} FFMS_TrackTimeBase; -``` -A struct representing the basic time unit of a track, as a rational number where `Num` is the numerator and `Den` is the denominator. -Note that while this rational number may occasionally turn out to be equal to 1/framerate for some CFR video tracks, it really has no relation whatsoever with the video framerate and you should definitely not assume anything framerate-related based on it. - -### FFMS_FrameInfo - -[FrameInfo]: #ffms_frameinfo -```c++ -typedef struct { - int64_t PTS; - int RepeatPict; - int KeyFrame; -} FFMS_FrameInfo; -``` -A struct representing basic metadata about a given video frame. -The fields are: - - `int64_t PTS` - The decoding timestamp of the frame. - To convert this to a timestamp in wallclock milliseconds, use the relation `int64_t timestamp = (int64_t)((FFMS_FrameInfo->PTS * FFMS_TrackTimeBase->Num) / (double)FFMS_TrackTimeBase->Den)`. - - `int RepeatPict` - RFF flag for the frame; same as in `FFMS_Frame`, see that structure for an explanation. - - `int KeyFrame` - Non-zero if the frame is a keyframe, zero otherwise. - -### FFMS_VideoProperties - -[VideoProperties]: #ffms_videoproperties -```c++ -typedef struct { - int FPSDenominator; - int FPSNumerator; - int RFFDenominator; - int RFFNumerator; - int NumFrames; - int SARNum; - int SARDen; - int CropTop; - int CropBottom; - int CropLeft; - int CropRight; - int TopFieldFirst; - int ColorSpace; // [DEPRECATED] - int ColorRange; // [DEPRECATED] - double FirstTime; - double LastTime; - int Rotation; - int Stereo3DType; - int Stereo3DFlags; - double LastEndTime; - int HasMasteringDisplayPrimaries; - double MasteringDisplayPrimariesX[3]; - double MasteringDisplayPrimariesY[3]; - double MasteringDisplayWhitePointX; - double MasteringDisplayWhitePointY; - int HasMasteringDisplayLuminance; - double MasteringDisplayMinLuminance; - double MasteringDisplayMaxLuminance; - int HasContentLightLevel; - unsigned int ContentLightLevelMax; - unsigned int ContentLightLevelAverage; - int Flip; -} FFMS_VideoProperties; -``` -A struct containing metadata about a video track. -The fields are: - - `int FPSDenominator; int FPSNumerator;` - The nominal framerate of the track, as a rational number. - For Matroska files, this number is based on the average frame duration of all frames, while for everything else it's based on the duration of the first frame. - While it might seem tempting to use these values to extrapolate wallclock timestamps for each frame, you really shouldn't do that since it makes your code unable to handle variable framerate properly. - The ugly reality is that these values are pretty much only useful for informational purposes; they are only somewhat reliable for antiquated containers like AVI. - Normally they should never be used for practical purposes; generate individual frame timestamps from `FFMS_FrameInfo->PTS` instead. - - `int RFFDenominator; int RFFNumerator;` - The special RFF timebase, as a rational number. - See `RepeatPict` in the `FFMS_Frame` documentation for more information. - - `int NumFrames;` - The number of frames in the video track. - - `int SARNum; int SARDen;` - The sample aspect ratio of the video frames, as a rational number where `SARNum` is the numerator and `SARDen` is the denominator. - Note that this is a metadata setting that you are free to ignore, but if you want the proper display aspect ratio with anamorphic material, you should honor it. - On the other hand, there are situations (like when encoding) where you should probably ignore it because the user expects it to be ignored. - - `int CropTop; int CropBottom; int CropLeft; int CropRight;` - The number of pixels in each direction you should crop the frame before displaying it. - Note that like the SAR, this is a metadata setting and you are free to ignore it, but if you want things to display 100% correctly you should honor it. - - `int TopFieldFirst` - Nonzero if the stream has the top field first, zero if it has the bottom field first. - - `int ColorSpace` - Identifies the YUV color coefficients used in the stream. - Same as in the MPEG-2 specs; see the [FFMS_ColorSpaces][ColorSpaces] enum. - The ColorSpace property in FFMS_Frame should be instead of this, as this can vary between frames unless you've asked for everything to be converted to a single value with `FFMS_SetOutputFormatV2`. - - `int ColorRange` - Identifies the luma range of the stream. - See the [FFMS_ColorRanges][ColorRanges] enum. - The ColorRange property in FFMS_Frame should be instead of this, as this can vary between frames unless you've asked for everything to be converted to a single value with `FFMS_SetOutputFormatV2`. - - `double FirstTime; double LastTime;` - The first and last timestamp of the stream respectively, in seconds. - Useful if you want to know if the stream has a delay, or for quickly determining its length in seconds. - - `int Rotation;` - The rotation of the video, in degrees. - - `int Stereo3DType;` - The type of stereo 3D the video is. Corresponts to entries in [FFMS_Stereo3DType][Stereo3DType]. - - `int Stereo3DFlags;` - Stereo 3D flags. Corresponds to entries in [FFMS_Stereo3DFlags][Stereo3DFlags]. - - `double LastEndTime;` - The end time of the last packet of the stream, in milliseconds. - - `int HasMasteringDisplayPrimaries;` - If this is non-zero, the following four properties are set. - - `double MasteringDisplayPrimariesX[3];` - RGB chromaticy coordinates of the mastering display (x coord). - - `double MasteringDisplayPrimariesY[3];` - RGB chromaticy coordinates of the mastering display (y coord). - - `double MasteringDisplayWhitePointX;` - White point coordinate of the mastering display (x coord). - - `double MasteringDisplayWhitePointY;` - White point coordinate of the mastering display (y coord). - - `int HasMasteringDisplayLuminance;` - If this is non-zero, the following two properties are set. - - `double MasteringDisplayMinLuminance;` - Minimum luminance of the mastering display (cd/m^2). - - `double MasteringDisplayMaxLuminance;` - Maximum luminance of the mastering display (cd/m^2). - - `int HasContentLightLevel;` - If this is non-zero, the following two properties are set. - - `unsigned int ContentLightLevelMax;` - Maximum content luminance (cd/m^2). - - `unsigned int ContentLightLevelAverage;` - Average content luminance (cd/m^2). - - `int Flip;` - Flip direction to be applied *before* rotation: 0 for no operation, >0 for horizontal flip, <0 for vertical flip. - -### FFMS_AudioProperties - -[AudioProperties]: #ffms_audioproperties -```c++ -typedef struct { - int SampleFormat; - int SampleRate; - int BitsPerSample; - int Channels; - int64_t ChannelLayout; - int64_t NumSamples; - double FirstTime; - double LastTime; - double LastEndTime; -} FFMS_AudioProperties; -``` -A struct containing metadata about an audio track. -The fields are: - - `int SampleFormat` - An integer that represents the audio sample format. - See [FFMS_SampleFormat][SampleFormat]. - - `int SampleRate` - The audio samplerate, in samples per second. - - `int BitsPerSample` - The number of bits per audio sample. - Note that this signifies the number of bits actually used to *code* each sample, not the number of bits used to *store* each sample, and may hence be different from what the `SampleFormat` would imply. - Figuring out which bytes are significant and which aren't is left as an exercise for the reader. - - `int Channels` - The number of audio channels. - - `int64_t ChannelLayout` - The channel layout of the audio stream. - Constructed by binary OR'ing the relevant integers from `FFMS_AudioChannel` together, which means that if the audio has the channel `FFMS_CH_EXAMPLE`, the operation `(ChannelOrder & FFMS_CH_EXAMPLE)` will evaluate to true. - The samples are interleaved in the order the channels are listed in the [FFMS_AudioChannel][AudioChannel] enum. - - `int64_t NumSamples` - The number of samples in the audio track. - - `double FirstTime; double LastTime;` - The first and last timestamp of the stream respectively, in milliseconds. - Useful if you want to know if the stream has a delay, or for quickly determining its length in seconds. - - `double LastEndTime;` - The end time of the last packet of the stream, in milliseconds. - -## Constants and Preprocessor Definitions -The following constants and preprocessor definititions defined in ffms.h are suitable for public usage. - -### FFMS_Errors - -[Errors]: #ffms_errors -```c++ -enum FFMS_Errors { - // No error - FFMS_ERROR_SUCCESS = 0, - - // Main types - where the error occurred - FFMS_ERROR_INDEX = 1, // index file handling - FFMS_ERROR_INDEXING, // indexing - FFMS_ERROR_POSTPROCESSING, // video postprocessing (libpostproc) - FFMS_ERROR_SCALING, // image scaling (libswscale) - FFMS_ERROR_DECODING, // audio/video decoding - FFMS_ERROR_SEEKING, // seeking - FFMS_ERROR_PARSER, // file parsing - FFMS_ERROR_TRACK, // track handling - FFMS_ERROR_WAVE_WRITER, // WAVE64 file writer - FFMS_ERROR_CANCELLED, // operation aborted - - // Subtypes - what caused the error - FFMS_ERROR_UNKNOWN = 20, // unknown error - FFMS_ERROR_UNSUPPORTED, // format or operation is not supported with this binary - FFMS_ERROR_FILE_READ, // cannot read from file - FFMS_ERROR_FILE_WRITE, // cannot write to file - FFMS_ERROR_NO_FILE, // no such file or directory - FFMS_ERROR_VERSION, // wrong version - FFMS_ERROR_ALLOCATION_FAILED, // out of memory - FFMS_ERROR_INVALID_ARGUMENT, // invalid or nonsensical argument - FFMS_ERROR_CODEC, // decoder error - FFMS_ERROR_NOT_AVAILABLE, // requested mode or operation unavailable in this binary - FFMS_ERROR_FILE_MISMATCH, // provided index does not match the file - FFMS_ERROR_USER // problem exists between keyboard and chair -}; -``` -Used to identify errors. Should be self-explanatory. - -### FFMS_SeekMode - -[SeekMode]: #ffms_seekmode -```c++ -enum FFMS_SeekMode { - FFMS_SEEK_LINEAR_NO_RW = -1, - FFMS_SEEK_LINEAR = 0, - FFMS_SEEK_NORMAL = 1, - FFMS_SEEK_UNSAFE = 2, - FFMS_SEEK_AGGRESSIVE = 3 -}; -``` -Used in [FFMS_CreateVideoSource][CreateVideoSource] to control the way seeking is handled. -Explanation of the values: - - `FFMS_SEEK_LINEAR_NO_RW` - Linear access without rewind; i.e. will throw an error if each successive requested frame number isn't bigger than the last one. - Only intended for opening images but might work on well with some obscure video format. - - `FFMS_SEEK_LINEAR` - Linear access (i.e. if you request frame `n` without having requested frames 0 to `n-1` in order first, all frames from 0 to `n` will have to be decoded before `n` can be delivered). - The definition of slow, but should make some formats "usable". - - `FFMS_SEEK_NORMAL` - Safe normal. - Bases seeking decisions on the keyframe positions reported by libavformat. - - `FFMS_SEEK_UNSAFE` - Unsafe normal. - Same as `FFMS_SEEK_NORMAL` but no error will be thrown if the exact destination has to be guessed. - - `FFMS_SEEK_AGGRESSIVE` - Aggressive. - Seeks in the forward direction even if no closer keyframe is known to exist. - Only useful for testing and containers where libavformat doesn't report keyframes properly. - -### FFMS_IndexErrorHandling - -[IndexErrorHandling]: #ffms_indexerrorhandling -```c++ -enum FFMS_IndexErrorHandling { - FFMS_IEH_ABORT = 0, - FFMS_IEH_CLEAR_TRACK = 1, - FFMS_IEH_STOP_TRACK = 2, - FFMS_IEH_IGNORE = 3 -}; -``` -Used by the indexing functions to control behavior when a decoding error is encountered. - - `FFMS_IEH_ABORT` - abort indexing and raise an error - - `FFMS_IEH_CLEAR_TRACK` - clear all indexing entries for the track (i.e. return a blank track) - - `FFMS_IEH_STOP_TRACK` - stop indexing but keep previous indexing entries (i.e. return a track that stops where the error occurred) - - `FFMS_IEH_IGNORE` - ignore the error and pretend it's raining - -### FFMS_TrackType - -[TrackType]: #ffms_tracktype -```c++ -enum FFMS_TrackType { - FFMS_TYPE_UNKNOWN = -1, - FFMS_TYPE_VIDEO, - FFMS_TYPE_AUDIO, - FFMS_TYPE_DATA, - FFMS_TYPE_SUBTITLE, - FFMS_TYPE_ATTACHMENT -}; -``` -Used for determining the type of a given track. Note that there are currently no functions to handle any type of track other than `FFMS_TYPE_VIDEO` and `FFMS_TYPE_AUDIO`. -See [FFMS_GetTrackType][GetTrackType], [FFMS_GetFirstTrackOfType][GetFirstTrackOfType] and their variants. - -### FFMS_SampleFormat - -[SampleFormat]: #ffms_sampleformat -```c++ -enum FFMS_SampleFormat { - FFMS_FMT_U8 = 0, - FFMS_FMT_S16, - FFMS_FMT_S32, - FFMS_FMT_FLT, - FFMS_FMT_DBL -}; -``` -Identifies various audio sample formats. - - - `FFMS_FMT_U8` - One 8-bit unsigned integer (`uint8_t`) per sample. - - `FFMS_FMT_S16` - One 16-bit signed integer (`int16_t`) per sample. - - `FFMS_FMT_S32` - One 32-bit signed integer (`int32_t`) per sample. - - `FFMS_FMT_FLT` - One 32-bit (single precision) floating point value (`float_t`) per sample. - - `FFMS_FMT_DBL` - One 64-bit (double precision) floating point value (`double_t`) per sample. - -### FFMS_AudioChannel - -[AudioChannel]: #ffms_audiochannel -```c++ -enum FFMS_AudioChannel { - FFMS_CH_FRONT_LEFT = 0x00000001, - FFMS_CH_FRONT_RIGHT = 0x00000002, - FFMS_CH_FRONT_CENTER = 0x00000004, - FFMS_CH_LOW_FREQUENCY = 0x00000008, - FFMS_CH_BACK_LEFT = 0x00000010, - FFMS_CH_BACK_RIGHT = 0x00000020, - FFMS_CH_FRONT_LEFT_OF_CENTER = 0x00000040, - FFMS_CH_FRONT_RIGHT_OF_CENTER = 0x00000080, - FFMS_CH_BACK_CENTER = 0x00000100, - FFMS_CH_SIDE_LEFT = 0x00000200, - FFMS_CH_SIDE_RIGHT = 0x00000400, - FFMS_CH_TOP_CENTER = 0x00000800, - FFMS_CH_TOP_FRONT_LEFT = 0x00001000, - FFMS_CH_TOP_FRONT_CENTER = 0x00002000, - FFMS_CH_TOP_FRONT_RIGHT = 0x00004000, - FFMS_CH_TOP_BACK_LEFT = 0x00008000, - FFMS_CH_TOP_BACK_CENTER = 0x00010000, - FFMS_CH_TOP_BACK_RIGHT = 0x00020000, - FFMS_CH_STEREO_LEFT = 0x20000000, - FFMS_CH_STEREO_RIGHT = 0x40000000 -}; -``` -Describes the audio channel layout of an audio stream. -The names should be self-explanatory. - -As you might have noticed, these constants are the same as the ones used for the `dwChannelMask` property of Microsoft's `WAVEFORMATEXTENSIBLE` struct; see [its MSDN documentation page](http://msdn.microsoft.com/en-us/library/dd757714%28v=vs.85%29.aspx) for more information. -The exceptions to this convenient compatibility are `FFMS_CH_STEREO_LEFT` and `FFMS_CH_STEREO_RIGHT`, which are FFmpeg extensions. - -### FFMS_Resizers - -[Resizers]: #ffms_resizers -```c++ -enum FFMS_Resizers { - FFMS_RESIZER_FAST_BILINEAR = 0x01, - FFMS_RESIZER_BILINEAR = 0x02, - FFMS_RESIZER_BICUBIC = 0x04, - FFMS_RESIZER_X = 0x08, - FFMS_RESIZER_POINT = 0x10, - FFMS_RESIZER_AREA = 0x20, - FFMS_RESIZER_BICUBLIN = 0x40, - FFMS_RESIZER_GAUSS = 0x80, - FFMS_RESIZER_SINC = 0x100, - FFMS_RESIZER_LANCZOS = 0x200, - FFMS_RESIZER_SPLINE = 0x400 -}; -``` -Describes various image resizing algorithms, as used in the arguments to [FFMS_SetOutputFormatV2][SetOutputFormatV2]. -The names should be self-explanatory. - -### FFMS_AudioDelayModes - -[AudioDelayModes]: #ffms_audiodelaymodes -```c++ -enum FFMS_AudioDelayModes { - FFMS_DELAY_NO_SHIFT = -3, - FFMS_DELAY_TIME_ZERO = -2, - FFMS_DELAY_FIRST_VIDEO_TRACK = -1 -}; -``` -Describes the different audio delay handling modes. -See [FFMS_CreateAudioSource][CreateAudioSource] for a detailed explanation. - -### FFMS_ChromaLocations - -[ChromaLocations]: #ffms_chromalocations -```c++ -typedef enum FFMS_ChromaLocations { - FFMS_LOC_UNSPECIFIED = 0, - FFMS_LOC_LEFT = 1, - FFMS_LOC_CENTER = 2, - FFMS_LOC_TOPLEFT = 3, - FFMS_LOC_TOP = 4, - FFMS_LOC_BOTTOMLEFT = 5, - FFMS_LOC_BOTTOM = 6 -} FFMS_ChromaLocations; -``` -Identifies the location of chroma samples in a frame. - -### FFMS_ColorRanges - -[ColorRanges]: #ffms_colorranges -```c++ -enum FFMS_ColorRanges { - FFMS_CR_UNSPECIFIED = 0, - FFMS_CR_MPEG = 1, - FFMS_CR_JPEG = 2, -}; -``` -Identifies the valid range of luma values in a YUV stream. -`FFMS_CR_MPEG` is the standard "TV range" with head- and footroom. -That is, valid luma values range from 16 to 235 with 8-bit color. -`FFMS_CR_JPEG` is "full range"; all representable luma values are valid. - -### FFMS_Stereo3DType -[Stereo3DType]: #ffms_stereo3dtype -```c++ -typedef enum FFMS_Stereo3DType { - FFMS_S3D_TYPE_2D = 0, - FFMS_S3D_TYPE_SIDEBYSIDE, - FFMS_S3D_TYPE_TOPBOTTOM, - FFMS_S3D_TYPE_FRAMESEQUENCE, - FFMS_S3D_TYPE_CHECKERBOARD, - FFMS_S3D_TYPE_SIDEBYSIDE_QUINCUNX, - FFMS_S3D_TYPE_LINES, - FFMS_S3D_TYPE_COLUMNS -} FFMS_Stereo3DType; -``` -Identifies the type of stereo 3D the video is. - -### FFMS_Stereo3DFlags -[Stereo3DFlags]: #ffms_stereo3dflags -```c++ -typedef enum FFMS_Stereo3DFlags { - FFMS_S3D_FLAGS_INVERT = 1 -} FFMS_Stereo3DFlags; -``` -Various flags for stereo 3D videos. - -### FFMS_CC -```c++ -#ifdef _WIN32 -# define FFMS_CC __stdcall -#else -# define FFMS_CC -#endif -``` -The calling convention used by FFMS2 API functions and callbacks. -Defined to `__stdcall` if `_WIN32` is defined. Otherwise defined, but not used. - -### Picture types -As stored in `FFMS_Frame->PictType`: -``` -I: Intra -P: Predicted -B: Bi-dir predicted -S: S(GMC)-VOP MPEG4 -i: Switching Intra -p: Switching Predicted -b: FF_BI_TYPE (no good explanation available) -?: Unknown -``` - -## Audio Filename Format Strings -The following variables can be used: - - - `%sourcefile%` - same as the source file name, i.e. the file the audio is decoded from - - `%trackn%` - the track number - - `%trackzn%` - the track number zero padded to 2 digits - - `%samplerate%` - the audio sample rate - - `%channels%` - number of audio channels - - `%bps%` - bits per sample - - `%delay%` - delay, or more exactly the first timestamp encountered in the audio stream - -Example string: `%sourcefile%_track%trackzn%.w64` diff --git a/thirdparty/ffms2/doc/ffms2-avisynth.md b/thirdparty/ffms2/doc/ffms2-avisynth.md deleted file mode 100644 index b981fb53d..000000000 --- a/thirdparty/ffms2/doc/ffms2-avisynth.md +++ /dev/null @@ -1,406 +0,0 @@ -# FFmpegSource2 Avisynth User Manual - -Opens files using FFmpeg and nothing else. -May be frame accurate on good days. -The source is MIT licensed and can be obtained from https://github.com/FFMS/ffms2/. -The precompiled binary is GPL3 licensed. -If you are religious you may consider this the second coming. - -## Donate - -Donate if you like this software. -Collecting weird clips from the internet and making them play takes more time than you'd think. - -[![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=fredrik%2emellbin%40gmail%2ecom&lc=US&item_name=IVTC%2eORG&no_note=0¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHostedGuest) - -## Limitations - - - Because of LAVF's demuxer, most raw streams (such as elementary h264 and other mpeg video streams) will fail to work properly. - - FFAudioSource() will have to remake any index implicitly created by FFVideoSource() and therefore code like - ``` - AudioDub(FFVideoSource(X), FFAudioSource(X)) - ``` - will require two indexing passes. Apart from the time consumed this is harmless. - To work around it open the audio first: - ``` - A = FFAudioSource(X) - V = FFVideoSource(X) - AudioDub(V, A) - ``` - or use FFIndex(), like so: - ``` - FFIndex(X) - AudioDub(FFVideoSource(X), FFAudioSource(X)) - ``` - - Interlaced H.264 mostly works these days, but seeking may occasionally result in corruption. - - Transport Streams will not decode reliably without seekmode -1. - - Open-GOP H.264 will sometimes produces corruption when seeking. - -## Compatibility - -### Video - - AVI, MKV, MP4, FLV: Frame accurate - - WMV: Frame accurate(?) but avformat seems to pick keyframes relatively far away - - OGM: Frame accurate(?) - - VOB, MPG: Seeking seems to be off by one or two frames now and then - - M2TS, TS: Seeking seems to be off a few frames here and there - - Image files: Most formats can be opened if seekmode=-1 is set, no animation support - -### Audio -Seeking should be sample-accurate with most codecs in AVI, MKV, MP4 and FLV. -Decoding linearly will almost always give correct results, and forward-seeks from trimming should result in at most a few hundred samples of corruption. - -## Indexing and You - -Before FFMS2 can open a file, it must be indexed first so that keyframe/sample positions are known and seeking is easily accomplished. -This is done automatically when using `FFVideoSource()` or `FFAudioSource()`, -but if you want to you can invoke the indexing yourself by calling `FFIndex()`, or by running `ffmsindex.exe`. -By default the index is written to a file so it can be reused the next time you open the same file, but this behavior can be turned off if desired. - -If you wonder why FFMS2 takes so long opening files, the indexing is the answer. -If you want a progress report on the indexing, you can use the supplied `ffmsindex.exe` commandline program. - -## Function reference - -### FFIndex -``` -FFIndex(string source, string cachefile = source + ".ffindex", int indexmask = -1, - int errorhandling = 3, bool overwrite = false, bool enable_drefs = false, bool use_absolute_path = false) -``` -Indexes a number of tracks in a given source file and writes the index file to disk, where it can be picked up and used by `FFVideoSource` or `FFAudioSource`. -Normally you do not need to call this function manually; it's invoked automatically if necessary by `FFVideoSource`/`FFAudioSource`. -It does, however, give you more control over how indexing is done. - -Note that this function returns an integer, not a clip (since it doesn't open video, nor audio). -The return value isn't particularly interesting, but for the record it's 0 if the index file already exists (and is valid) and overwrite was not enabled, 1 if the index file was created and no previous index existed, and 2 if the index file was created by overwriting an existing, valid index file. - -#### Arguments - -##### string source -The source file to index. - -##### string cachefile = source + ".ffindex" -The filename of the index file (where the indexing data is saved). -Defaults to `sourcefilename.ffindex`. - -##### int indexmask = -1 -A binary mask representing what audio tracks should be indexed (all video tracks are always indexed; you have no choice in the matter). -The mask is constructed by bitshifting 1 left by the track number; if multiple tracks are desired, bitwise OR each value so created together to get the full mask. -In other words, the mask is a bit field where each bit is a track number (the least significant bit is track number 0). -Since Avisynth doesn't have any bitwise operators at all, constructing a mask for more than one track inside an Avisynth script is a rather annoying task; for a single track the mask is, naturally, 2 to the power of the track number minus 1 (i.e. if you want to index track 3, the mask is `2^(3-1) = 4`). - -Since the mask works like it does, and FFMS2 is designed to run on a machine that uses two's complement integers, -1 (the default) means index all tracks and 0 means index none. - -Note that FFMS2's idea about what track has what number may be completely different from what any other application might think, and that track numbering starts from 1. - -##### int errorhandling = 3 -Controls what happens if an audio decoding error is encountered during indexing. -Possible values are: - - - **0**: Raise an error and abort indexing. No index file is written. - - **1**: Clear the affected track (effectively making it silent) and continue. - - **2**: Stop indexing the track but keep all the index entries so far, effectively ending the track where the error occured. - - **3**: Pretend it's raining and continue anyway. This is the default; if you encounter odd noises in the audio, try mode 0 instead and see if it's FFMS2's fault. - -##### bool overwrite = false -If set to true, `FFIndex()` will reindex the source file and overwrite the index file even if the index file already exists and is valid. -Mostly useful for trackmask changes and testing. - -##### bint enable_drefs = False -Corresponds to the FFmpeg demuxer option of the same name. You will know if you need it. - -##### bint use_absolute_path = False -Corresponds to the FFmpeg demuxer option of the same name. You will know if you need it. - -### FFVideoSource -``` -FFVideoSource(string source, int track = -1, bool cache = true, - string cachefile = source + ".ffindex", int fpsnum = -1, int fpsden = 1, - int threads = -1, string timecodes = "", int seekmode = 1, int rffmode = 0, - int width = -1, int height = -1, string resizer = "BICUBIC", - string colorspace = "", string varprefix = "") -``` -Opens video. Will invoke indexing of all video tracks (but no audio tracks) if no valid index file is found. - -#### Arguments - -##### string source -The source file to open. - -##### int track = -1 -The video track number to open, as seen by the relevant demuxer. -Track numbers start from zero, and are guaranteed to be continous (i.e. there must be a track 1 if there is a track 0 and a track 2). -1 means open the first video track. -Note that FFMS2's idea about what track has what number may (or may not) be completely different from what some other application might think. -Trying to open an audio track with `FFVideoSource` will naturally fail. - -##### bool cache = true -If set to true (the default), `FFVideoSource` will first check if the `cachefile` contains a valid index, and if it does, that index will be used. -If no index is found, all video tracks will be indexed, and the indexing data will be written to `cachefile` afterwards. -If set to false, `FFVideoSource` will not look for an existing index file; instead all video tracks will be indexed when the script is opened, and the indexing data will be discarded after the script is closed; you will have to index again next time you open the script. - -##### string cachefile = source + ".ffindex" -The filename of the index file (where the indexing data is saved). -Defaults to `sourcefilename.ffindex`. -Note that if you didn't change this parameter from its default value and `FFVideoSource` encounters an index file that doesn't seem to match the file it's trying to open, it will automatically reindex and then overwrite the old index file. -On the other hand, if you *do* change it, `FFVideoSource` will assume you have your reasons and throw an error instead if the index doesn't match the file. - -##### int fpsnum = -1, int fpsden = 1 -Controls the framerate of the output; used for VFR to CFR conversions. -If `fpsnum` is less than or equal to zero (the default), the output will contain the same frames that the input did, and the frame rate reported to Avisynth will be set based on the input clip's average frame duration. -If `fpsnum` is greater than zero, `FFVideoSource` will force a constant frame rate, expressed as a rational number where `fpsnum` is the numerator and `fpsden` is the denominator. -This may naturally cause `FFVideoSource` to drop or duplicate frames to achieve the desired frame rate, and the output is not guaranteed to have the same number of frames that the input did. - -##### int threads = -1 -The number of decoding threads to request from libavcodec. -Setting it to less than or equal to zero means it defaults to the number of logical CPU's reported by Windows. -Note that this setting might be completely ignored by libavcodec under a number of conditions; most commonly because a lot of decoders actually do not support multithreading. - -##### string timecodes = "" -Filename to write Matroska v2 timecodes for the opened video track to. -If the file exists, it will be truncated and overwritten. -Set to the empty string to disable timecodes writing (this is the default). - -##### int seekmode = 1 -Controls how seeking is done. -Mostly useful for getting uncooperative files to work. -Valid modes are: - - - **-1**: Linear access without rewind; i.e. will throw an error if each successive requested frame number isn't bigger than the last one. - Only intended for opening images but might work on well with some obscure video format. - - **0**: Linear access (i.e. if you request frame `n` without having requested all frames from 0 to `n-1` in order first, all frames from 0 to `n` will have to be decoded before `n` can be delivered). - The definition of slow, but should make some formats "usable". - - **1**: Safe normal. Bases seeking decisions on the keyframe positions reported by libavformat. - - **2**: Unsafe normal. Same as mode 1, but no error will be thrown if the exact seek destination has to be guessed. - - **3**: Aggressive. Seeks in the forward direction even if no closer keyframe is known to exist. Only useful for testing and containers where libavformat doesn't report keyframes properly. - -##### int rffmode = 0 -Controls how RFF flags in the video stream are treated; in other words it's equivalent to the "field operation" mode switch in DVD2AVI/DGIndex. -Valid modes are: - - - **0**: Ignore all flags (the default mode). - - **1**: Honor all pulldown flags. - - **2**: Equivalent to DVD2AVI's "force film" mode. - -Note that using modes 1 or 2 will make `FFVideoSource` throw an error if the video stream has no RFF flags at all. -When using either of those modes, it will also make the output be assumed as CFR, disallow vertical scaling and disallow setting the output colorspace. -`FFPICT_TYPE` will also not be set as the output is a combination of several frames. -Other subtle behavior changes may also exist. - -Also note that "force film" is mostly useless and only here for completeness' sake, since if your source really is safe to force film on, using mode 0 will have the exact same effect while being considerably more efficient. - -##### int width = -1, int height = -1 -Sets the resolution of the output video, in pixels. -Setting either dimension to less than or equal to zero means the resolution of the first decoded video frame is used for that dimension. -These parameters are mostly useful because FFMS2 supports video streams that change resolution mid-stream; since Avisynth does not, these parameters are used to set single resolution for the output. - -##### string resizer = "BICUBIC" -The resizing algorithm to use if rescaling the image is necessary. -If the video uses subsampled chroma but your chosen output colorspace does not, the chosen resizer will be used to upscale the chroma planes, even if you did not request an image rescaling. -The available choices are `FAST_BILINEAR`, `BILINEAR`, `BICUBIC` (default), `X`, `POINT`, `AREA`, `BICUBLIN`, `GAUSS`, `SINC`, `LANCZOS` and `SPLINE`. -Note that `SPLINE` is completely different from Avisynth's builtin Spline resizers. - -##### string colorspace = "" -Convert the output from whatever it was to the given colorspace, which can be one of `YV12`, `YV16`, `YV24`, `Y8`, `YUY2`, `YV411`, `YUV9`, `RGB24` or `RGB32`. -They can also be referred to with the more systematic names of `YUVsssPx`, `YUVAsssPx`, `Yx`, `RGBPx` or `RGBAPx` where `x` is the desired bitdepth and `sss` represents the subsampling. Formats with an `A` also have an alpha channel. -Examples: `YUV420P8`, `RGBAP16`, `Y16` -Setting this to an empty string (the default) means keeping the same colorspace as the input or in case it's not supported it'll be converted to the closest existing match. - -##### string varprefix = "" -A string that is added as a prefix to all exported Avisynth variables. -This makes it possible to differentiate between variables from different clips. -For convenience the last used FFMS function in a script sets the global variable `FFVAR_PREFIX` to its own variable prefix so that `FFInfo()` can default to it. - -### FFAudioSource -``` -FFAudioSource(string source, int track = -1, bool cache = true, - string cachefile = source + ".ffindex", int adjustdelay = -1, - int fillgaps = -1, float drc_scale = 0, -string varprefix = "") -``` -Opens audio. -Invokes indexing of all tracks if no valid index file is found, or if the requested track isn't present in the index. - -#### Arguments -Are exactly the same as to `FFVideoSource`, but with these additional options: - -##### int adjustdelay = -1 -Controls how audio delay is handled, i.e. what happens if the first audio sample in the file doesn't have a timestamp of zero. -The following arguments are valid: - - - **-3**: No adjustment is made; the first decodable audio sample becomes the first sample in the output. - - **-2**: Samples are created (with silence) or discarded so that sample 0 in the decoded audio starts at time zero. - - **-1**: Samples are created (with silence) or discarded so that sample 0 in the decoded audio starts at the same time as frame 0 of the first video track. This is the default, and probably what most people want. - - **Any integer >= 0**: Same as -1, but adjust relative to the video track with the given track number instead. - If the provided track number isn't a video track, an error is raised. - --2 obviously does the same thing as -1 if the first video frame of the first video track starts at time zero. -In some containers this will always be the case, in others (most notably 188-byte MPEG TS) it will almost never happen. - -##### int fillgaps = -1 -Determines how audio with discontinuous timestamps are handled. - - **-1**: Apply zero filled gaps to audio in containers where it's usually necessary. - - **0**: Never zero fill gaps. - - **1**: Always zero fill gaps. - -##### float drc_scale = 0 -Controls the amount of DRC that's applied to (E)AC-3 audio. 0 means no DRC and 1 means fully applied DRC in accordance with how it's flagged in the stream. - -### FFmpegSource2/FFMS2 -``` -FFmpegSource2/FFMS2(string source, int vtrack = -1, int atrack = -2, bool cache = true, - string cachefile = source + ".ffindex", int fpsnum = -1, int fpsden = 1, - int threads = -1, string timecodes = "", int seekmode = 1, - bool overwrite = false, int width = -1, int height = -1, - string resizer = "BICUBIC", string colorspace = "", int rffmode = 0, - int adjustdelay = -1, string varprefix = "") -``` -A convenience function that combines the functionality of `FFVideoSource` and `FFAudioSource`. -The arguments do the same thing as in `FFVideoSource` and `FFAudioSource`; see those functions for details. -`vtrack` and `atrack` are the video and audio track to open, respectively; setting `atrack` <= -2 means audio is disabled. - -**Note:** the shorter FFMS2 alias was added in 2.22 - -### FFImageSource -``` -FFImageSource(string source, int width = -1, int height = -1, - string resizer = "BICUBIC", string colorspace = "") -``` -A convenience alias for `FFVideoSource`, with the options set optimally for using it as an image reader. -Disables caching and seeking for maximum compatiblity. - -### FFInfo -``` -FFInfo(clip c, bool framenum = true, bool frametype = true, bool cfrtime = true, - bool vfrtime = true, string varprefix = "", bool colorspace = true, - bool colorrange = true, bool cropping = true, bool sar =true, bool version = true, - bool showprefix = false) -``` -A helper function similar to Avisynth's internal `Info()` function; shows general information about the current frame. -Note that not all values are exported in all source modes, so some information may not always be shown. -The arguments can be used to disable the drawing of certain information if so desired. -Use the varprefix argument to determine which clip you want information about. - -**Note:** this function is provided by `FFMS2.avsi` and is not available unless that script has been imported or autoloaded. - -### FFFormatTime -FFFormatTime(int ms) -A helper function used to format a time given in milliseconds into a h:mm:ss.ttt string. -Used internally by `FFInfo`. - -**Note:** this function is provided by `FFMS2.avsi` and is not available unless that script has been imported or autoloaded. - -### FFColorSpace -FFColorSpace(int i) -A helper function used to convert a colorspace number into a human readable string. -Used internally by `FFInfo`. - -**Note:** this function is provided by `FFMS2.avsi` and is not available unless that script has been imported or autoloaded. - -### FFColorRange -FFColorRange(int i) -A helper function used to convert a color range number into a human readable string. -Used internally by `FFInfo`. - -**Note:** this function is provided by `FFMS2.avsi` and is not available unless that script has been imported or autoloaded. - -### FFCropping -FFCropping(int l, int t, int r, int b) -A helper function used to convert cropping information into a human readable string. -Used internally by `FFInfo`. - -**Note:** this function is provided by `FFMS2.avsi` and is not available unless that script has been imported or autoloaded. - -### FFSampAR -FFSampAR(int num,int den) -A helper function used to convert the sample aspect ratio into a human readable string. -Used internally by `FFInfo`. - -**Note:** this function is provided by `FFMS2.avsi` and is not available unless that script has been imported or autoloaded. - -### FFPictType -FFPictType(int ch) -A helper function used to convert a picture type character into a human readable string. -Used internally by `FFInfo`. - -**Note:** this function is provided by `FFMS2.avsi` and is not available unless that script has been imported or autoloaded. - -### FFSetLogLevel -``` -FFSetLogLevel(int Level = -8) -``` -Sets the FFmpeg logging level, i.e. how much diagnostic spam it prints to STDERR. -Since most applications that open Avisynth scripts do not provide a way to display things printed to STDERR, and since it's rather hard to make any sense of the printed messages unless you're quite familiar with FFmpeg internals, the usefulness of this function is rather limited for end users. It's mostly intended for debugging. -Defaults to quiet (no messages printed); a list of meaningful values can be found in `ffms.h`. - -### FFGetLogLevel -``` -FFGetLogLevel() -``` -Returns the current log level, as an integer. - -### FFGetVersion -``` -FFGetVersion() -``` -Returns the FFMS2 version, as a string. - -## Exported Avisynth variables -All variable names are prefixed by the `varprefix` argument to the respective `FFVideoSource` or `FFAudioSource` call that generated them. - -##### FFSAR_NUM, FFSAR_DEN, FFSAR -The playback aspect ratio specified by the container. -`FFSAR_NUM` and `FFSAR_DEN` make up the rational number of the ratio; `FFSAR` is only provided for convenience and may not be set in case it cannot be calculated (i.e. if `FFSAR_DEN` is zero). - -##### FFCROP_LEFT, FFCROP_RIGHT, FFCROP_TOP, FFCROP_BOTTOM -The on-playback cropping specified by the container. - -##### FFCOLOR_SPACE -The colorimetry the input claims to be using. Only meaningful for YUV inputs. -The source for this variable is a metadata flag that can arbitrarily be set or manipulated at will by incompetent users or buggy programs without changing the actual video content, so blindly trusting its correctness is not recommended. - -The value is exported as a cryptic numerical constant that matches the values in the MPEG-2 specification. -You can find the gory details in the FFMS2 API documentation, but the important ones are: - - - **0**: RGB (usually indicates the stream isn't actually YUV, but RGB flagged as YUV) - - **1**: ITU-R Rec.709 - - **2**: Unknown or unspecified - - **5 and 6**: ITU-R Rec.601 - -##### FFCOLOR_RANGE -The color range the input video claims to be using. -Much like FFCOLOR_SPACE, the source for this variable is a metadata flag that can freely be set to arbitrary values, so trusting it blindly might not be a good idea. - -Note that using the width/height/colorspace parameters to FFVideoSource may under some circumstances change the output color range. - - - **0**: Unknown/unspecified - - **1**: Limited range (usually 16-235) - - **2**: Full range (0-255) - -##### FFPICT_TYPE -The picture type of the most recently requested frame as the ASCII number of the character listed below. -Use `Chr()` to convert it to an actual letter in Avisynth. Use after_frame=true in Avisynth's conditional scripting for proper results. -Only set when rffmode=0. -The FFmpeg source definition of the characters: -``` -I: Intra -P: Predicted -B: Bi-dir predicted -S: S(GMC)-VOP MPEG4 -i: Switching Intra -p: Switching Predicted -b: FF_BI_TYPE (no good explanation available) -?: Unknown -``` - -##### FFVFR_TIME -The actual time of the source frame in milliseconds. -Only set when no type of CFR conversion is being done (`rffmode` and `fpsnum` left at their defaults). - -##### FFCHANNEL_LAYOUT -The audio channel layout of the audio stream. -This is exported as a very cryptic integer that is constructed in the same way as the `dwChannelMask` property of the Windows `WAVEFORMATEXTENSIBLE` struct. -If you don't know what a `WAVEFORMATEXTENSIBLE` is or what the `dwChannelMask` does, don't worry about it. - -##### FFVAR_PREFIX -The variable prefix of the last called FFMS source function. -Note that this is a global variable. diff --git a/thirdparty/ffms2/doc/ffms2-changelog.md b/thirdparty/ffms2/doc/ffms2-changelog.md deleted file mode 100644 index c2b1f1080..000000000 --- a/thirdparty/ffms2/doc/ffms2-changelog.md +++ /dev/null @@ -1,359 +0,0 @@ -# FFmpegSource2 Changelog -- 2.xxx - - Fixed all issues with FFmpeg 6.0 which is now the minimum requirement - - Added HDR10+ and DolbyVision metadata - - Fixed audio decoding that could otherwise get stuck in an infinite loop on certain files - - Fixed framerate in Avisynth when using VFR=>CFR mode - - Dropped VapourSynth API3 support - - Indexer now has a configurable progress update interval - - Alpha planes are now correctly marked as being full range - - The full set of demuxer options can now be passed using the FFMS2 API - - Now sets channel layout in Avisynth+ - -- 2.3000 - - Added support for VapourSynth API4 (Myrsloik) - - Added basic Avisynth+ frame property support (Myrsloik) - - Added Rotation and Flip properties for VapourSynth (Myrsloik) - - Added long path support for ffmsindex in windows (Myrsloik) - - The audio gap fill logic is now optional and usually disabled by default (Myrsloik) - - Allow the drc_scale option to be set when decoding audio (Myrsloik) - - Allow the enable_drefs and use_absolute_path demuxer options to be used when indexing (Myrsloik) - -- 2.40 - - Avisynth+ linux support (qyot27) - - Added LastEndTime track property to make it possible to take the last frame's duration into account (Myrsloik) - - Removed several deprecated functions and enums from the API (Myrsloik) - - No longer assumes sub 1 fps framerates are invalid (Myrsloik) - - Added support for floating point format output in VapourSynth and Avisynth+ (Myrsloik) - - Fixed issue with dropped/repeated frames in vc1 with multiple b-frames after seeking (Myrsloik) - - Fixed issue with dropped/repeated frames in h264 when the reorder buffer size is too small (Myrsloik) - - Improved seeking in mpeg and mpegts streams (Myrsloik) - - Added rgb(a)p and several additional formats as output to Avisynth+ (Myrsloik) - - Added VP9 support (Daemon404) - - Fixed incorrectly reporting the output as limited range when it's in fact unknown and likely to be full range (Myrsloik) - - Added mastering display metadata output (Myrsloik) - - VapourSynth source now defaults to not outputting alpha (Myrsloik) - - Removed the now unused demuxer, dumpmask, audiofile and utf8 arguments from the source filters (Myrsloik) - - Removed ability to dump audio tracks (Myrsloik) - - Fixed incorrect colorimetry metadata reported when converting the output to another colorspace (Myrsloik) - - Sources now simply reference the index instead of copying large parts of it (Myrsloik) - - Use new FFmpeg decoding API (Myrsloik) - - Fixed several bugs in output format selection (Myrsloik) - - FFMSIndex will now properly error out with invalid arguments (Myrsloik) - - Add rotation metadata export (Myrsloik) - - Add stereoscopic metadata export (Myrsloik) - - Created new Visual Studio 2017 projects (Myrsloik) - - Removed old mingw version support (Myrsloik) - - Removed support for old FFmpeg versions (Myrsloik) - - Removed libav support (Myrsloik) - - Discontinuous Timestamp Support (Daemon404) - - Add FFMS_Deinit (Daemon404) - - Fix mid-stream parameter changes (Daemon404) - - Fix decoding H.264 PAFF files with one field per packet (Daemon404) - - Fix delay calculations for H.264 PAFF files (Daemon404) - - Fix frame rate calculation for fields with one field per packet (Daemon404) - -- 2.23 - - Updated FFmpeg APIs used (Daemon404) - - Added new API that can read/write indexes to a memory buffer (Daemon404) - - Added support for high bitdepth output in Avisynth+ (Myrsloik) - - vapoursource: Add nfMakeLinear flag to better performance in most cases (Myrsloik) - - Remove bad colorspace matrix guessing for YUV (Myrsloik) - - Tell libavformat to discard packets we don't want (Daemon404) - - Restore original FFCopyrightInfringement behavior (Myrsloik) - - Make FFMS_Init threadsafe (Daemon404) - - Support latest libav* APIs (Daemon404) - -- 2.22 - - Fix possible off by 1 frame until first seek issue introduced in 2.21 (Myrsloik) - - avisynth: Make FFMS2 a shorter alias for FFmpegSource2 to save some typing (Myrsloik) - - avisynth: Moved all source functions in ffms2.avsi into the actual plugin (Myrsloik) - - avisynth: Use 2.6 RC API and add output support for all new colorspaces (Myrsloik) - - vapoursource: Fix swapped RGB channels bug introduced in 2.21 (Myrsloik) - - swscale: Drop pointless and slow bitexact flag from resizer settings (kodabb) - - Add support for files with gaps between the audio packets (Plorkyeran) - -- 2.21 - - Add missing constants for log levels (Myrsloik) - - Fix bad decoder flush that discards the palette of raw video (Myrsloik) - - Remove the SWScale function from Avisynth since SWScale is useless (Myrsloik) - - Fix common framerate correction (Myrsloik) - - vapoursource: The framerate and frame durations are now normalized (Myrsloik) - - vapoursource: Add support for outputting the alpha channel too (Myrsloik) - - vapoursource: Fix resizer selection so bicubic isn't always used (Myrsloik) - - vapoursource: Set chroma location and full colorspace information (Myrsloik) - - Add support for indexing files with more than 32 tracks and the possibility to skip indexing of video tracks (Myrsloik) - - The Avisynth plugin now sets all per frame variables in all modes to avoid ugly and slow FFInfo() errors (Myrsloik) - - vapoursource: Fix crash on single frame files (Myrsloik) - - Remove the Matroska and Haali demuxers (qyot27, Plorkyeran) - - Fix adjustments for positive audio delay (tophf) - - Don't try to index video tracks in unsupported formats (Daemon404) - - Don't use scientific notation in timecode files (Daemon404) - - Fix utf8 support in FFVideoSource (nixxquality) - - Improve handling of files where only some packets have timestamps (Plorkyeran) - - Fix memory leaks in the VapourSynth error handling (Plorkyeran) - -- 2.20 - - Add support for Opus in MKV when ffmpeg/libav are built with libopus (qyot27) - - vapoursource: Provide _AbsoluteTime metadata (Daemon404) - - Fix a pile of small things found by Coverity (Daemon404) - - Add support for HEVC in MKV (qyot27) - - Fix infinite loop on garbage data at the beginning of AAC files (Plorkyeran) - - Deal with the never-ending bitrot from FFmpeg/Libav API changes (Daemon404, Plorkyeran) - - Make indexes not arch-specific and trivially smaller (Plorkyeran) - - Fix bug where the first b-frame was replaced with the frame before it with open-gop h.264 (Plorkyeran) - - Fix seeking issues with open-gop h.264 (Plorkyeran) - - Fix corruption when seeking in interlaced h.264 (Plorkyeran) - - Add support for multiple frames per audio packet as FFmpeg seems to have started doing that (Plorkyeran) - - Fix seeking in Y4M files (Plorkyeran) - - Fix dumping audio while indexing files - - Add support for Matroska files with extremely large CodecPrivate sections - - Speed up indexing Matroska files a bit - -- 2.18 - - Fix regression (r483) with rffmode that caused it to error out even if using the default output colorspace. (TheRyuu) - - High(er) quality YUV->RGB conversion. (TheRyuu) - - Fix indexing on files with cover art. (TheRyuu) - - Add support for libav/ffmpeg built with msvc, this is the default on windows when building with msvc. (TheRyuu) - - Remove postproc support. (TheRyuu) - - Deprecate the CPUFeatures argument to FFMS_Init since postproc was the only thing still using it. (Plorkyeran) - - Added VapourSynth support. (Myrsloik) - - ffmsindex can now output keyframe numbers to a file while indexing. (Plorkyeran) - - configure now defaults to building a shared library, except when building MinGW/Cygwin, since you usually want static for those. (Plorkyeran) - - The source color space and color range used when converting with swscale can now be overridden. (Plorkyeran) - - Fix issues with unicode filenames when building with mingw. (Plorkyeran) - - Fix progress reporting when indexing files with non-zero initial timestamp with haali's splitter. (Plorkyeran) - - Add support for formats with packet durations but no packet timestamps. (Plorkyeran) - - Fix corruption when seeking in VC-1 in MKV. (Plorkyeran) - - Fix bug that resulted in files opened with Haali's splitter sometimes always decoding from the beginning on every seek. (Plorkyeran) - - Add support for VP8. (Plorkyeran) - - Fix crash when indexing video formats with no parser. (Plorkyeran) - - Fix compilation errors with recent versions of libav/ffmpeg. (Plorkyeran) - - Fix NVOP handling with frame-based threading (aka zero-size frames with mp4 bug). (Plorkyeran) - - Add support for vc1image. (Plorkyeran) - - Use the container SAR when the codec SAR is unset when opening via lavf. (Plorkyeran) - - Actually set the ColorRange and ColorSpace of frames when nothing has been overridden. (Plorkyeran) - - Add support for files without timestamps to lavf audio. (Plorkyeran) - - Fix handling of audio delay with invalid inital timestamps. (Plorkyeran) - - Sort of partially fix interlaced H.264. (Plorkyeran) - - Fix errors when the client asks for audio past the end of the file. (Plorkyeran) - - Fix rounding error with MKV timestamps that resulted in things getting a FPS like 60001/1001. (TheRyuu) - - Bump required version to libav 0.8/FFmpeg 0.9. (Plorkyeran) - - Switch to avcodec_decode_audio4. (Plorkyeran) - - Add support for planar audio from lavc. (Plorkyeran) - - Add SetOutputFormatA for audio resampling/mixing using libavresample. (Plorkyeran) - - Zero-length index files are now rejected rather than bad things happening. - -- 2.17 - - Reworked color matrix and color range handling a bit, which fixed a bug that could cause FFMS2 to always output TV range even if the input was full range. (TheFluff) - - The autotools build system can now create debug builds properly. (Daemon404) - - Deprecated parts of the API will now cause compiler warnings when you use them. (TheFluff) - - Added a `FFMS_GetVersion` function to the API (lets library users get the version number at runtime) and exposed it in Avisynth as `FFGetVersion`. (TheRyuu, TheFluff) - - Added a variable prefix option to the Avisynth functions. Its primary purpose is to get subsequent calls to source functions from overwriting variables from earlier calls. (TheFluff) - - Make it possible to open single-frame videos without explicitly setting seekmode to -1 for you weird people who want to open images with ffms (Plorkyeran) - - Fixed bug where indices would sometimes be incorrectly considered valid (TheRyuu) - - Add support for recent versions of Libav/FFmpeg built as shared libraries (Plorkyeran, TheRyuu, Kovensky) - - When possible, non-API symbols are no longer exported (Daemon404, TheFluff) - - Deprecate postprocessing support. Libav and FFmpeg are planning on removing it at some point in the near future and it's really not very useful. - - Fix the pkg-config version on OS X (Plorkyeran). - - Fixed a bug that could cause the `FFmpegSource2()` Avisynth function to not use UTF8 filenames even when told to do so. (pandv2) - - Fixed a few minor memory leaks. (Plorkyeran) - - Adjusting audio delay relative to the first video track should now work properly again (was broken in 2.16). (Plorkyeran) - - General bitrot fixes to deal with changes in Libav/FFmpeg (everyone) - - Corrected handling of codec private data when using a non-libavformat parser. Fixes decoding of FFV1 and UTVideo in MKV, among other things. (TheFluff) - - Bump minimum required version of FFmpeg to 0.6. - -- 2.16 - - Reimplemented output colorspace selection, this should fix all issues with the Avisynth plugin when opening yuv420p10 or yuv444 material plus several other less common cases. (Myrsloik) - - Added `FFMS_SetOutputFormatV2` to the API. This function allows you to specify PixelFormats >= 64 for use as output. (Myrsloik) - - Fixed a serious bug that could cause crashes and completely useless index files with h264 in Matroska. (Myrsloik) - - Automatically detect number of decoding threads. The Avisynth video source funtion already did this, now moved so the API can use it as well. (TheRyuu) - - Re-add the ability to target x64 with MSVC, since it's a bit more sane now. (TheRyuu) - - Fixed a bug that could cause crashes when reading audio if FFMS2 was compiled with GCC. (Myrsloik) - - ffmsindex will no longer crash if it cannot open the file given to it for indexing. (TheFluff) - - FFMS2 will no longer crash if the video decoder feeds it an empty frame (can sometimes happen when using lots of decoder threads); you'll get a nice error message instead. (TheFluff) - - The C-plugin can now act as both an Avisynth 2.6 plugin (including support for new colorspaces) as well as an Avisynth 2.5 one, in the same binary. (kemuri_-9) - - Fixed an issue that could cause opening Vorbis audio to fail because FFMS2 couldn't find an initial valid PTS. (TheFluff) - - FFMS2 will no longer crash if forced or tricked into using an index file generated by a FFMS2 version compiled for a different architecture. (TheRyuu) - - Fixed a crash when the last frame was requested using the Avisynth plugin's forced CFR mode. (Plorkyeran) - - Fixed various issues with decoding audio from the Ogg container without Haali's splitter. (Myrsloik, TheFluff) - - Fixed the "invalid postprocessing settings", it is caused by a parsing bug in libpostproc and a workaround has been added (Myrsloik) - - Tinkered a bit with the non-MSVS build system. (Daemon404, Kovensky) - -- 2.15 - - FFVideoSource and FFAudioSource will now automatically reindex and overwrite the index file if it doesn't match the file being opened and the `cachefile` argument is left as the default. (Plorkyeran) - - FFMS2 can now be used to decode Lagarith, but note that libavcodec's decoder is very experimental at the moment. (Plorkyeran) - - SWScale can now use SSE2 optimizations for certain operations if your CPU supports it. (kemuri_-9) - - Fixed a bug that could cause SWScale initialization to fail. (kemuri_-9) - - Fixed a bug that could cause index files to never be considered valid, forcing a reindexing every time a script was loaded. (TheRyuu) - - Trying to use postprocessing on a fullrange YUV clip will no longer cause errors. (TheFluff) - - Fixed a few random decoding bugs related to unaligned memory or buffers that were not initialized properly. (TheFluff) - - It is now possible to force FFMS2 to use a specific demuxer instead of letting it pick one automatically. (TheFluff) - - When converting YUV to RGB, FFMS2 will now try to actually use the correct color coefficients rather than assuming everything is bt470bg. (Plorkyeran) - - Moved support for container-level audio delay from the Avisynth plugin to the core and exposed it in the API (Plorkyeran) - - Audio decoding has been substantially reworked. Linearly decoding audio now almost always works correctly and seeking is now actually sample-accurate for many formats. (Plorkyeran) - - It is now possible to build 64bit versions of the plugin for use with Avisynth (and whatever else) from MSVC by means of black magic (this probably only works when the planets are aligned, also 64bit builds might require msvcr90.dll). (TheRyuu) - - The Avisynth plugin now supports UTF8 filenames; ffmsindex.exe also supports Unicode filenames. FFMS_USE_UTF8_PATHS is now a runtime option instead of a compile-time one. (TheFluff) - - The FFInfo() function (supplied by ffms2.avsi) will now round timestamps to nearest millisecond instead of truncating them. It's also been cleaned up in general and no longer relies on global variables. (Gavino) - - Containers opened with libavformat will now report a framerate based on the average frame duration instead of the duration of the first frame, just like Matroska files and files opened with Haali's splitter does. Should fix CFR framerates being reported incorrectly in dumb containers like FLV. (TheFluff) - - PC/TV luma range (16-235 versus 0-255) detection should now be a bit more reliable. (TheFluff) - - Fixed a crash when opening files with Unicode filename support enabled. (Plorkyeran) - -- 2.14 - - Reworked filename handling a bit. Index files should no longer get a garbled name when using the Avisynth plugin and an input filename in the local codepage (issue 9), and FFMS_USE_UTF8_PATHS does no longer require patching ffmpeg. (TheFluff, nielsm) - - Fixed a bunch of compiler warnings and added versioning for the shared library when building under Unix. (Kovensky) - - Fixed an invalid memory access bug that could cause random crashes or other errors when opening files. (TheFluff) - - The timebase for video tracks is now corrected if it's invalid. (kemuri_-9) - - Fixed a number of multithreaded decoding issues. (kemuri_-9) - - Use aligned memory for audio decoding buffers; fixes some crashes during audio decoding. (greg) - - Fixed a bug that caused ffmsindex -c to fail. (chdheu) - - Added support for MKV files using header stripping compression. (TheFluff) - - It is now possible to compile FFMS2 using a ffmpeg without libpostproc compiled in (this will obviously cause postprocessing-related functions to fail). Hence it is now possible to build a GPL-free FFMS2, since the rest of ffmpeg can be compiled as LGPL. (TheFluff) - - Audio streams that change channel layout, sample rate or bitdepth mid-stream will no longer cause crashes; an error will be raised during indexing instead. (TheFluff) - - Fix a potential crash when ffmpeg thought it couldn't decode a certain format, but was wrong. Fixes issues with some FLV's. (Plorkyeran) - - Fix heap corruption that could cause crashes and odd issues when opening H.264 in MPEG-TS with Haali's splitter. (Plorkyeran) - - Fix a memleak when decoding H.264 in MPEG-TS using Haali's splitter. (kemuri-_9) - - Updated FFmpeg to rev 25329. - -- 2.13 - - Fixed a bug where the Avisynth plugin would drop the last frame when converting to CFR (lanwcp) - - The Avisynth plugin will now attempt to detect and use NTSC fractional framerates for CFR files if applicable, instead of reporting something based on the average framerate (astrange, TheFluff) - - The errorhandling parameter to FFIndex() will now actually do what the documentation claims it does (TheFluff) - - Fixed a progress reporting crash when opening images (TheFluff) - - Replaced the CMake build system with an autotools one that hopefully works better (Kovensky) - - Fixed various compilation issues with MinGW (TheFluff) - - Fixed h264 in mkv which was remuxed from bd sources, there are no longer decoding artifacts after seeking - - Use pts instead of dts for seeking with lavf, fixes various timecode problems on mp4 files with certain obscure delay headers - - Now compresses the index files with zlib to save space - - Removed the boost dependency - - Fixed the framerate calculation for AVC video in the RFF modes - - Improved/fixed the NVOP detection in MPEG4 and how timestamps are calculated (lanwcp, Myrsloik) - - Fixed an issue where the first 15 audio frames would never be redecoded if needed again - - Fixed/added support for uncompressed video and audio formats in matroska, fixes Blank.Clip.720p.x264-darkhold.mkv (Emess) - - The indexer and test is now statically linked so no extra runtimes are needed - - FFmpeg is now compiled with runtime cpu detection, allows opterons and old cpus to work properly - - Updated FFmpeg to rev 21782 - -- 2.12 - - Added support for (L)PCM in TS/PS - - Fixed some possible memory corruption on initialization in the indexers - - Improved the API slightly by making resolution and colorspace frame properties only like they actually are - - Fixed adjustdelay=-1 when no video track is present, previously it would crash - - Updated FFmpeg to rev 19824, FFmpeg-mt unchanged at 24/08/2009 - with faad2, opencore-amr nb/wb, and pthreads - -- 2.11 - - Now 100% less beta - - FFMSIndex can now write timecode files - - Optimized index reading and writing, file opening should be faster especially for big files - - Fixed a crash bug on zlib compressed streams in matroska - - Added an argument to FFAudioSource that makes it automatically adjust the delay relative to the first video track (default), the specified track (any track type possible) or relative to the zero timestamp, no adjustment is done for files with no video track in the default mode - - Now exports the colorimetry info in a format easily usable with ColorMatrix, see FFCOLOR_SPACE and FFCOLOR_RANGE in the manual, the reported information may be unreliable - - Added an FFImageSource() function to ffms2.avsi which invokes FFVideoSource with the optimal settings for use on images - - Now exports the actual frame presentation time in FFVFR_TIME, added the general information function FFInfo() and FFFormatTime() functions to ffms2.avsi in addition to fixing the missing backslash - - The seek/read method has been changed in the matroska video source to only need the information in the index and nothing more, this matches the audio source and should make seeking faster in some cases - - No longer drops the last audio frame - - It is now possible to force indexing of broken tracks when using FFIndex and from the API, this can in many cases help when the last frame of an avi file is corrupted which would otherwise prevent indexing of all working data - - Fixed a bug that would prevent the SWScale and FFPP filters from working because of randomly added flags - - Added support for RFF flags, the three possible modes should be equivalent to the ones found in DGDecode - - Added a workaround for mpeg4 files with NVOPs - - Fixed a bug where the first frame would be corrupted if the colorspace/dimensions were set for the output - - Now VC1 in TS decoding works in many cases - - Added the missing install target to CMake and changed the default output library name (Kovensky) - - Now reverts to using LAVF if Haali's splitter isn't installed (note that LAVF is VERY bad at seeking in these formats) - - Now requires the boost headers (but not libraries) to compile because boost::format is so convenient - - More API changes to return proper error codes and more source cleanups - - Updated FFmpeg to rev 19776, FFmpeg-mt to 24/08/2009 - with faad2, opencore-amr nb/wb, and w32threads (pthreads for FFmpeg-mt) - -- 2.00 beta 10 - - Possibly fixed h264 in transport stream decoding, now a suitable bitstream filter is added (could theoretically break other h264 in ts files so make sure to report if any such files stop working) - - Now returns the frame type as a character to make presentation easier and to remove the random numbers from the API - - Fixed the identification of certain codecs (like VC1) in some transport streams - - Fixed a bug introduced in SeekMode=1 by the changes in beta 6, prevents an access violation from happening in very rare conditions - - Some (but not all) stream properties are now retrieved from the container and passed to libavcodec, this makes a few more formats work like vc1 in mkv/ts - - It is now possible to specify the desired output colorspace and resolution in FFVideoSource, this is mostly useful for file where the resolution changes to avoid excessive up/downscaling - - Added support for files where the video frames have changing size and colorspace - - The library part can now be compiled to accept UTF8 encoded strings, this allows full unicode support on windows when FFmpeg is compiled with a small patch applied (TheFluff) - - Added proper detection of when the opened file and index is mismatched and throws an error when it happens instead of undefined behavior, should not add a noticable delay to file opening - - Added a proper cmake based build system and vs2008 project files to make developement and use easier (TheFluff, JEEB, Kovensky) - - Added API documentation by TheFluff and revised many argument descriptions to reflect how they currently work - - The output audio filename can now be specified in avisynth (was ignored previously) with variables such as track number and delay possible to use - - Indexing with Haali's splitters should now show progress in most cases - - Fixed a few more memory leaks in indexing - - Now checks for failed seeking when LAVF is used and retries with more aggressive seeking options before failing - - Updated FFmpeg to rev 19479 (now compiled with the opencore amr decoder) - -- 2.00 beta 9 - - Dumping audio now actually implies indexing too in FFIndex, previously nothing would be done if the index mask wasn't set as well - - FFAudioSource will now first load the index and returns the first indexed audio track with track=-1, if no audio tracks are indexed or the chosen track isn't indexed the equivalent of FFIndex(indexmask = -1, overwrite = cache) is executed first - - Codec lookup for non-lavf opened files now to a large part use the same lookup tables as lavf, this should improve the number of properly recognized codecs - - Now uses the average framerate for files opened with Haali's splitters, before it was always reported as 30 fps - - Implemented audio decoding using Haali's splitters, FFAudioSource now works on ts, ps and ogm - - Can now be compiled with ICL 10.1 (probably other versions too) - - How indexing works has been split internally so the track numbers and types are reported, this makes it possible to create an interactive GUI or ask which audio tracks are to be indexed - - Now has stricter index checking to detect when different FFmpeg versions were used to create an index of the same version - - Fixed memory leaks when audio sources were destroyed and when errors happened during indexing - - Fixed access violations occurring when a track of the wrong type was specified or didn't exist in FFVideoSource and FFAudioSource - - Fixed access violations occurring when unindexed or empty audio tracks in matroska/lavf read files were opened - - Less type conversion/signedness warnings - - When audio track dumping is performed a custom callback can now be supplied to name the tracks - - The audio track delay is now exposed in the API in the same way as video tracks - - A big type and argument name cleanup in the API, many things have been renamed to be clearer and ffms.h should be completely C friendly now - - Removed FFNoLog and replaced it with FFSetLogLevel and FFGetLogLevel, the default logging is now also set to quiet, the magical numbers to supply it can be found in avutil/log.h - - Updated FFmpeg to rev 18972 (now with faad2 again by popular demand, updated to GCC 4.4.0 for compiling all libraries) - -- 2.00 beta 8 - - Improved the audio decoding quality a lot by adding a simple cache, no more seeking is done when playing a file linearly and pops and other artifacts should be much more uncommon - - Fixed a bug that would most of the time drop frame 0 and sometimes frame 1 - - Updated Haali's matroska parser code to the latest version - - Updated FFmpeg to rev 18774 - -- 2.00 beta 7 - - Using ffms2 as a library no longer requires an installed pixfmt.h from libavutil, it is however still required to compile ffms2 and the avisynth plugin part - - Fix a crash bug at the end of files with b-frames in beta 6 caused by uninitialized null packets - - Includes TheFluff's wrapper function for 1.21 style syntax - - Added a simple regression test application to the source - - Removed a few pointless functions from the API - - Fixed the accessing of codecprivate data with Haali's splitters - - Timecode output should be fixed to include decimals AND not be in scientific format - - Fixed a memory leak when using Haali's splitters - - Updated FFmpeg to rev 18717 - -- 2.00 beta 6 - - Haali's splitters have been improved for video and now have audio dumping during indexing implemented - - SeekMode=1 has improved logic which will make it go back and decode more frames if necessary to figure out where it is, in theory SeekMode=0 should now be mostly obsolete - - Haali's splitters are now used to open mpeg ps and ogm in addition to mpeg ts, only ogm is frame accurate at this time - - Negative timecodes and other bugs caused by an integer overflow fixed - - Updated FFmpeg to rev 18442 (once again compilation fixes for the changes) - -- 2.00 beta 5 - - FFMSIndex should now print the progress properly when another application reads its output - - Added missing variables and explanations to the manual - - Can now directly be compiled as a library for use in *nix - - Fixed the missing decimals in saved timecode files - -- 2.00 beta 4 - - Added the function FFNoLog which suppresses all messages from ffmpeg - - Experimental new TS parsing using Haali's splitter (with bugs) - - Everything is now compiled with VS2008 and GCC 4.3.2 - - Updated FFmpeg to rev 16383 (no libfaad2 this time) - -- 2.00 beta 3 - - Compiled with libfaad2 again (has anyone seen a single aac file lavc can open right now?) - - More API changes (and even more are likely to come) - - Several access violations and memory leaks on opening and indexing files fixed - - Added a VFR to CFR mode - - Readded FFAudioSource support for other containers (glitches still present now and then but no separate raw cache is required and possibly less buggy) - - Renamed the dll to FFMS2.dll, FFMS2 is now the official short name of the project - - Updated FFmpeg to rev 15522 - -- 2.00 beta 2 - - More API changes (and more are likely to come) - - Includes a simple CLI indexing application - - FFIndex now takes a few more arguments - - Readded FFAudioSource (only matroska supported for now) - - Updated FFmpeg to rev 15396 - -- 2.00 beta 1 - - Can now be used as a stand alone library for making indices and retrieving frames - - Rewrote most things - - Updated FFmpeg to rev 15301 diff --git a/thirdparty/ffms2/doc/ffms2-vapoursynth.md b/thirdparty/ffms2/doc/ffms2-vapoursynth.md deleted file mode 100644 index dc9e8abb7..000000000 --- a/thirdparty/ffms2/doc/ffms2-vapoursynth.md +++ /dev/null @@ -1,201 +0,0 @@ -# FFmpegSource2 VapourSynth User Manual - -Opens files using FFmpeg and (almost) nothing else. -May be frame accurate on good days. -The source is MIT licensed and can be obtained from https://github.com/FFMS/ffms2/. -The precompiled binary is GPL3 licensed. -If you are religious you may consider this the second coming. - -## Donate - -Donate if you like this software. -Collecting weird clips from the internet and making them play takes more time than you'd think. - -[![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=fredrik%2emellbin%40gmail%2ecom&lc=US&item_name=IVTC%2eORG&no_note=0¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHostedGuest) - -## Limitations - - No audio support in VapourSynth - - Because of LAVF's demuxer, most raw streams (such as elementary h264 and other mpeg video streams) will fail to work properly. - - Interlaced H.264 mostly works these days, but seeking may occasionally result in corruption. - - Transport Streams will not decode reliably without seekmode -1. - - Open-GOP H.264 will sometimes produces corruption when seeking. - -## Compatibility - - - AVI, MKV, MP4, FLV: Frame accurate - - WMV: Frame accurate(?) but avformat seems to pick keyframes relatively far away - - OGM: Frame accurate(?) - - VOB, MPG: Seeking seems to be off by one or two frames now and then - - M2TS, TS: Seeking seems to be off a few frames here and there - - Image files: Most formats can be opened if seekmode=-1 is set, no animation support - -## Indexing and You - -Before FFMS2 can open a file, it must be indexed first so that keyframe/sample positions are known and seeking is easily accomplished. -This is done automatically when using `Source()`, -but if you want to you can invoke the indexing yourself by calling `Index()`, or by running `ffmsindex`. -By default the index is written to a file so it can be reused the next time you open the same file, but this behavior can be turned off if desired. - -If you wonder why FFMS2 takes so long opening files, the indexing is the answer. -If you want a progress report on the indexing, you can use the supplied `ffmsindex` commandline program. - -## Function reference - -### Index -``` -ffms2.Index(string source[, string cachefile = source + ".ffindex", int[] indextracks = [], - int errorhandling = 3, bint overwrite = False, bint enable_drefs = False, bint use_absolute_path = False]) -``` -Indexes a number of tracks in a given source file and writes the index file to disk, where it can be picked up and used by `Source`. -Normally you do not need to call this function manually; it's invoked automatically if necessary by `Source`. -It does, however, give you more control over how indexing is done. - -Note that this function returns an integer, not a clip (since it doesn't open video, nor audio). -The return value isn't particularly interesting, but for the record it's 0 if the index file already exists (and is valid) and overwrite was not enabled, 1 if the index file was created and no previous index existed, and 2 if the index file was created by overwriting an existing, valid index file. - -#### Arguments - -##### string source -The source file to index. - -##### string cachefile = source + ".ffindex" -The filename of the index file (where the indexing data is saved). -Defaults to `sourcefilename.ffindex`. - -##### int[] indextracks = [] -An array containing a list of which audio tracks should be indexed (all video tracks are always indexed; you have no choice in the matter). -It's possible to use -1 to simply tell it to index all tracks.´without having to list them individually. - -Note that FFMS2's idea about what track has what number may be completely different from what any other application might think. - -##### int errorhandling = 3 -Controls what happens if an audio decoding error is encountered during indexing. -Possible values are: - - - **0**: Raise an error and abort indexing. No index file is written. - - **1**: Clear the affected track (effectively making it silent) and continue. - - **2**: Stop indexing the track but keep all the index entries so far, effectively ending the track where the error occured. - - **3**: Pretend it's raining and continue anyway. This is the default; if you encounter odd noises in the audio, try mode 0 instead and see if it's FFMS2's fault. - -##### bint overwrite = False -If set to true, `FFIndex()` will reindex the source file and overwrite the index file even if the index file already exists and is valid. -Mostly useful for trackmask changes and testing. - -##### bint enable_drefs = False -Corresponds to the FFmpeg demuxer option of the same name. You will know if you need it. - -##### bint use_absolute_path = False -Corresponds to the FFmpeg demuxer option of the same name. You will know if you need it. - -### Source -``` -ffms2.Source(string source[, int track = -1, bint cache = True, - string cachefile = source + ".ffindex", int fpsnum = -1, int fpsden = 1, - int threads = -1, string timecodes = "", int seekmode = 1, - int width = -1, int height = -1, string resizer = "BICUBIC", - int format, bint alpha = False]) -``` -Opens video. Will invoke indexing of all video tracks (but no audio tracks) if no valid index file is found. - -#### Arguments - -##### string source -The source file to open. - -##### int track = -1 -The video track number to open, as seen by the relevant demuxer. -Track numbers start from zero, and are guaranteed to be continous (i.e. there must be a track 1 if there is a track 0 and a track 2). -1 means open the first video track. -Note that FFMS2's idea about what track has what number may (or may not) be completely different from what some other application might think. - -##### bint cache = True -If set to true (the default), `Source` will first check if the `cachefile` contains a valid index, and if it does, that index will be used. -If no index is found, all video tracks will be indexed, and the indexing data will be written to `cachefile` afterwards. -If set to false, `Source` will not look for an existing index file; instead all video tracks will be indexed when the script is opened, and the indexing data will be discarded after the script is closed; you will have to index again next time you open the script. - -##### string cachefile = source + ".ffindex" -The filename of the index file (where the indexing data is saved). -Defaults to `sourcefilename.ffindex`. -Note that if you didn't change this parameter from its default value and `Source` encounters an index file that doesn't seem to match the file it's trying to open, it will automatically reindex and then overwrite the old index file. -On the other hand, if you *do* change it, `Source` will assume you have your reasons and throw an error instead if the index doesn't match the file. - -##### int fpsnum = -1, int fpsden = 1 -Controls the framerate of the output; used for VFR to CFR conversions. -If `fpsnum` is less than or equal to zero (the default), the output will contain the same frames that the input did, and the frame rate reported to VapourSynth will be set based on the input clip's average frame duration. -If `fpsnum` is greater than zero, `Source` will force a constant frame rate, expressed as a rational number where `fpsnum` is the numerator and `fpsden` is the denominator. -This may naturally cause `Source` to drop or duplicate frames to achieve the desired frame rate, and the output is not guaranteed to have the same number of frames that the input did. - -##### int threads = -1 -The number of decoding threads to request from libavcodec. -Setting it to less than or equal to zero means it defaults to the number of logical CPU's reported by the OS. -Note that this setting might be completely ignored by libavcodec under a number of conditions; most commonly because a lot of decoders actually do not support multithreading. - -##### string timecodes = "" -Filename to write Matroska v2 timecodes for the opened video track to. -If the file exists, it will be truncated and overwritten. -Set to the empty string to disable timecodes writing (this is the default). - -##### int seekmode = 1 -Controls how seeking is done. -Mostly useful for getting uncooperative files to work. -Valid modes are: - - - **-1**: Linear access without rewind; i.e. will throw an error if each successive requested frame number isn't bigger than the last one. - Only intended for opening images but might work on well with some obscure video format. - - **0**: Linear access (i.e. if you request frame `n` without having requested all frames from 0 to `n-1` in order first, all frames from 0 to `n` will have to be decoded before `n` can be delivered). - The definition of slow, but should make some formats "usable". - - **1**: Safe normal. Bases seeking decisions on the keyframe positions reported by libavformat. - - **2**: Unsafe normal. Same as mode 1, but no error will be thrown if the exact seek destination has to be guessed. - - **3**: Aggressive. Seeks in the forward direction even if no closer keyframe is known to exist. Only useful for testing and containers where libavformat doesn't report keyframes properly. - -##### int width = -1, int height = -1 -Sets the resolution of the output video, in pixels. -Setting either dimension to less than or equal to zero means the resolution of the first decoded video frame is used for that dimension. -These parameters are mostly useful because FFMS2 supports video streams that change resolution mid-stream which would otherwise have to be handled with a more complicated script. - -##### string resizer = "BICUBIC" -The resizing algorithm to use if rescaling the image is necessary. -If the video uses subsampled chroma but your chosen output colorspace does not, the chosen resizer will be used to upscale the chroma planes, even if you did not request an image rescaling. -The available choices are `FAST_BILINEAR`, `BILINEAR`, `BICUBIC` (default), `X`, `POINT`, `AREA`, `BICUBLIN`, `GAUSS`, `SINC`, `LANCZOS` and `SPLINE`. - -##### int format -Convert the output from whatever it was to the given format. If not specified the best matching output format is used. - -##### bint alpha = False -Output the alpha channel as a second clip if it is present in the file. When set to True an array of two clips will be returned with alpha in the second one. If there is alpha information present. - -#### Exported VapourSynth frame properties -There are several useful frame properties that are set. See the VapourSynth manual for a detailed explanation of them. - - - _DurationNum - - _DurationDen - - _AbsoluteTime - - _SARNum - - _SARDen - - _Matrix - - _Primaries - - _Transfer - - _ChromaLocation - - _ColorRange - - _PictType - - _FieldBased - -### SetLogLevel -``` -ffms2.SetLogLevel(int Level = -8) -``` -Sets the FFmpeg logging level, i.e. how much diagnostic spam it prints to STDERR. -Since many applications that open VapourSynth scripts do not provide a way to display things printed to STDERR, and since it's rather hard to make any sense of the printed messages unless you're quite familiar with FFmpeg internals, the usefulness of this function is rather limited for end users. It's mostly intended for debugging. -Defaults to quiet (no messages printed); a list of meaningful values can be found in `ffms.h`. - -### GetLogLevel -``` -ffms2.GetLogLevel() -``` -Returns the current log level, as an integer. - -### GetVersion -``` -ffms2.GetVersion() -``` -Returns the FFMS2 version, as a string. - diff --git a/thirdparty/ffms2/etc/COPYING.GPLv3 b/thirdparty/ffms2/etc/COPYING.GPLv3 deleted file mode 100644 index 94a9ed024..000000000 --- a/thirdparty/ffms2/etc/COPYING.GPLv3 +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/thirdparty/ffms2/etc/FFMS2.avsi b/thirdparty/ffms2/etc/FFMS2.avsi deleted file mode 100644 index cb4ea607d..000000000 --- a/thirdparty/ffms2/etc/FFMS2.avsi +++ /dev/null @@ -1,75 +0,0 @@ -# FFmpegSource 2.22 helper functions -# Created by TheFluff - -function FFFormatTime(int ms) { - - s = ms / 1000 - ms = ms % 1000 - m = s / 60 - s = s % 60 - h = m / 60 - m = m % 60 - - return ms < 0 ? "" : string(h) + ":" + string(m,"%02.0f") + ":" + string(s,"%02.0f") + "." + string(ms,"%03.0f") -} - -function FFColorSpace(int i) { - i=(i<0||i>10) ? 2 : i - return Select(i,"RGB","BT709 (ITU-R Rec.709)","Unspecified","Unspecified","FCC","BT470BG (ITU-R Rec.601)","SMPTE 170M (ITU-R Rec.601)","SMPTE 240M","YCoCg","BT2020 NCL","BT2020 NC") -} - -function FFColorRange(int i) { - i=(i<0||i>2) ? 0 : i - return Select(i,"Unknown/Unspecified","Limited range","Full range") -} - -function FFCropping(int l, int t, int r, int b) { - return "Left="+String(l)+" Top="+String(t)+" Right="+String(r)+" Bottom="+String(b) -} - -function FFSampAR(int num, int den) { - return num > 0 ? String(num)+":"+String(den)+((num<=0 || den<=0)?"":string(Float(num)/den," (%.3f)")) : "Unknown/Unspecified" -} - -function FFPictType(int ch) { - s=chr(ch) - s = s + ( - \ ch==73?" (Intra)":ch==80?" (Predicted)":ch==66?" (Bi-dir predicted)":ch==83?" (S(GMC)-VOP MPEG4)" - \ : ch==105?" (Switching Intra)":ch==112?" (Switching Predicted)":ch==98?" (FF_BI_TYPE)" - \ : " (Unknown)") - return s -} - -function FFInfo(clip c, bool "framenum", bool "frametype", bool "cfrtime", bool "vfrtime", string "varprefix", - \ bool "colorspace",bool "colorrange",bool "cropping",bool "sar",bool "version",bool "showprefix") { - - framenum = default(framenum,true) - frametype = default(frametype,true) - cfrtime = default(cfrtime,true) - vfrtime = default(vfrtime,true) - varprefix = default(varprefix, FFVAR_PREFIX) - colorSpace = default(colorspace,true) - colorrange = default(colorrange,true) - cropping = default(cropping,true) - sar = default(sar,true) - version = default(version,true) - showprefix = default(showprefix,false) - - c.frameevaluate(""" - fftempstring = "" - varprefix = """" + varprefix + """" - """) - - version ? frameevaluate("""fftempstring = fftempstring + "Version: " + FFGetVersion + "\n" """, after_frame=true) : nop() - framenum ? frameevaluate("""fftempstring = fftempstring + "Frame Number: " + string(current_frame) + " of " + string(framecount()) + "\n" """, after_frame=true) : nop() - frametype ? frameevaluate("""fftempstring = fftempstring + "Picture Type: " + FFPictType(eval(varprefix + "FFPICT_TYPE")) + "\n" """, after_frame=true) : nop() - cfrtime ? frameevaluate("""fftempstring = fftempstring + "CFR Time: " + FFFormatTime(round((current_frame * 1000) / framerate())) + "\n" """, after_frame=true) : nop() - vfrtime ? frameevaluate("""fftempstring = fftempstring + "VFR Time: " + FFFormatTime(eval(varprefix + "FFVFR_TIME")) + "\n" """, after_frame=true) : nop() - colorspace ? frameevaluate("""fftempstring = fftempstring + "ColorSpace: " + FFColorSpace(eval(varprefix + "FFCOLOR_SPACE")) + "\n" """, after_frame=true) : nop() - colorrange ? frameevaluate("""fftempstring = fftempstring + "Color Range: " + FFColorRange(eval(varprefix + "FFCOLOR_RANGE")) + "\n" """, after_frame=true) : nop() - cropping ? frameevaluate("""fftempstring = fftempstring + "Cropping: " + FFCropping(eval(varprefix + "FFCROP_LEFT"),eval(varprefix + "FFCROP_TOP"),eval(varprefix + "FFCROP_RIGHT"),eval(varprefix + "FFCROP_BOTTOM")) + "\n" """, after_frame=true) : nop() - sar ? frameevaluate("""fftempstring = fftempstring + "SAR: " + FFSampAR(eval(varprefix + "FFSAR_NUM"),eval(varprefix + "FFSAR_DEN")) + "\n" """, after_frame=true) : nop() - showprefix ? frameevaluate("""fftempstring = fftempstring + "Prefix: '" + varprefix + "'\n" """, after_frame=true) : nop() - - return scriptclip("subtitle(fftempstring, lsp = 1)", after_frame=true) -} \ No newline at end of file diff --git a/thirdparty/ffms2/ffms2.pc.in b/thirdparty/ffms2/ffms2.pc.in deleted file mode 100644 index 7a2a35ee8..000000000 --- a/thirdparty/ffms2/ffms2.pc.in +++ /dev/null @@ -1,14 +0,0 @@ -# @configure_input@ - -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: ffms2 -Description: The Fabulous FM Library 2 -Requires.private: libavformat libavcodec libswscale libavutil libswresample -Version: @FFMS_VERSION@ -Libs.private: @ZLIB_LDFLAGS@ -lz -Libs: -L${libdir} -lffms2 -Cflags: -I${includedir} diff --git a/thirdparty/ffms2/include/ffms.h b/thirdparty/ffms2/include/ffms.h deleted file mode 100644 index e37ea3562..000000000 --- a/thirdparty/ffms2/include/ffms.h +++ /dev/null @@ -1,474 +0,0 @@ -// Copyright (c) 2007-2018 Fredrik Mellbin -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#ifndef FFMS_H -#define FFMS_H - -// Version format: major - minor - micro - bump -#define FFMS_VERSION ((3 << 24) | (1 << 16) | (1 << 8) | 0) - -#include -#include - - -/******** -* The following preprocessor voodoo ensures that all API symbols are exported -* as intended on all supported platforms, that non-API symbols are hidden (where possible), -* and that the correct calling convention and extern declarations are used. -* The end result should be that linking to FFMS2 Just Works. -********/ - -// Convenience for C++ users. -#if defined(__cplusplus) -# define FFMS_EXTERN_C extern "C" -#else -# define FFMS_EXTERN_C -#endif - -// On win32, we need to ensure we use stdcall with all compilers. -#if defined(_WIN32) && !defined(_WIN64) -# define FFMS_CC __stdcall -#else -# define FFMS_CC -#endif - -// compiler-specific deprecation attributes -#ifndef FFMS_EXPORTS -# if defined(__GNUC__) && (__GNUC__ >= 4) -# define FFMS_DEPRECATED __attribute__((deprecated)) -# elif defined(_MSC_VER) -# define FFMS_DEPRECATED __declspec(deprecated) -# endif -#endif - -#ifndef FFMS_DEPRECATED -// Define as empty if the compiler doesn't support deprecation attributes or -// if we're building FFMS2 itself -# define FFMS_DEPRECATED -#endif - -// And now for some symbol hide-and-seek... -#if defined(_WIN32) && !defined(FFMS_STATIC) // MSVC -# if defined(FFMS_EXPORTS) // building the FFMS2 library itself, with visible API symbols -# define FFMS_API(ret) FFMS_EXTERN_C __declspec(dllexport) ret FFMS_CC -# define FFMS_DEPRECATED_API(ret) FFMS_EXTERN_C FFMS_DEPRECATED __declspec(dllexport) ret FFMS_CC -# else // building something that depends on FFMS2 -# define FFMS_API(ret) FFMS_EXTERN_C __declspec(dllimport) ret FFMS_CC -# define FFMS_DEPRECATED_API(ret) FFMS_EXTERN_C FFMS_DEPRECATED __declspec(dllimport) ret FFMS_CC -# endif // defined(FFMS_EXPORTS) -// GCC 4 or later: export API symbols only. Some GCC 3.x versions support the visibility attribute too, -// but we don't really care enough about that to add compatibility defines for it. -#elif defined(__GNUC__) && __GNUC__ >= 4 -# define FFMS_API(ret) FFMS_EXTERN_C __attribute__((visibility("default"))) ret FFMS_CC -# define FFMS_DEPRECATED_API(ret) FFMS_EXTERN_C FFMS_DEPRECATED __attribute__((visibility("default"))) ret FFMS_CC -#else // fallback for everything else -# define FFMS_API(ret) FFMS_EXTERN_C ret FFMS_CC -# define FFMS_DEPRECATED_API(ret) FFMS_EXTERN_C FFMS_DEPRECATED ret FFMS_CC -#endif // defined(_MSC_VER) - - -// we now return you to your regularly scheduled programming. - -typedef struct FFMS_ErrorInfo { - int ErrorType; - int SubType; - int BufferSize; - char *Buffer; -} FFMS_ErrorInfo; - -typedef struct FFMS_VideoSource FFMS_VideoSource; -typedef struct FFMS_AudioSource FFMS_AudioSource; -typedef struct FFMS_Indexer FFMS_Indexer; -typedef struct FFMS_Index FFMS_Index; -typedef struct FFMS_Track FFMS_Track; - -typedef enum FFMS_Errors { - // No error - FFMS_ERROR_SUCCESS = 0, - - // Main types - where the error occurred - FFMS_ERROR_INDEX = 1, // index file handling - FFMS_ERROR_INDEXING, // indexing - FFMS_ERROR_POSTPROCESSING, // video postprocessing (libpostproc) - FFMS_ERROR_SCALING, // image scaling (libswscale) - FFMS_ERROR_DECODING, // audio/video decoding - FFMS_ERROR_SEEKING, // seeking - FFMS_ERROR_PARSER, // file parsing - FFMS_ERROR_TRACK, // track handling - FFMS_ERROR_WAVE_WRITER, // WAVE64 file writer - FFMS_ERROR_CANCELLED, // operation aborted - FFMS_ERROR_RESAMPLING, // audio resampling (libavresample) - - // Subtypes - what caused the error - FFMS_ERROR_UNKNOWN = 20, // unknown error - FFMS_ERROR_UNSUPPORTED, // format or operation is not supported with this binary - FFMS_ERROR_FILE_READ, // cannot read from file - FFMS_ERROR_FILE_WRITE, // cannot write to file - FFMS_ERROR_NO_FILE, // no such file or directory - FFMS_ERROR_VERSION, // wrong version - FFMS_ERROR_ALLOCATION_FAILED, // out of memory - FFMS_ERROR_INVALID_ARGUMENT, // invalid or nonsensical argument - FFMS_ERROR_CODEC, // decoder error - FFMS_ERROR_NOT_AVAILABLE, // requested mode or operation unavailable in this binary - FFMS_ERROR_FILE_MISMATCH, // provided index does not match the file - FFMS_ERROR_USER // problem exists between keyboard and chair -} FFMS_Errors; - -typedef enum FFMS_SeekMode { - FFMS_SEEK_LINEAR_NO_RW = -1, - FFMS_SEEK_LINEAR = 0, - FFMS_SEEK_NORMAL = 1, - FFMS_SEEK_UNSAFE = 2, - FFMS_SEEK_AGGRESSIVE = 3 -} FFMS_SeekMode; - -typedef enum FFMS_IndexErrorHandling { - FFMS_IEH_ABORT = 0, - FFMS_IEH_CLEAR_TRACK = 1, - FFMS_IEH_STOP_TRACK = 2, - FFMS_IEH_IGNORE = 3 -} FFMS_IndexErrorHandling; - -typedef enum FFMS_TrackType { - FFMS_TYPE_UNKNOWN = -1, - FFMS_TYPE_VIDEO, - FFMS_TYPE_AUDIO, - FFMS_TYPE_DATA, - FFMS_TYPE_SUBTITLE, - FFMS_TYPE_ATTACHMENT -} FFMS_TrackType; - -typedef enum FFMS_SampleFormat { - FFMS_FMT_U8 = 0, - FFMS_FMT_S16, - FFMS_FMT_S32, - FFMS_FMT_FLT, - FFMS_FMT_DBL -} FFMS_SampleFormat; - -typedef enum FFMS_AudioChannel { - FFMS_CH_FRONT_LEFT = 0x00000001, - FFMS_CH_FRONT_RIGHT = 0x00000002, - FFMS_CH_FRONT_CENTER = 0x00000004, - FFMS_CH_LOW_FREQUENCY = 0x00000008, - FFMS_CH_BACK_LEFT = 0x00000010, - FFMS_CH_BACK_RIGHT = 0x00000020, - FFMS_CH_FRONT_LEFT_OF_CENTER = 0x00000040, - FFMS_CH_FRONT_RIGHT_OF_CENTER = 0x00000080, - FFMS_CH_BACK_CENTER = 0x00000100, - FFMS_CH_SIDE_LEFT = 0x00000200, - FFMS_CH_SIDE_RIGHT = 0x00000400, - FFMS_CH_TOP_CENTER = 0x00000800, - FFMS_CH_TOP_FRONT_LEFT = 0x00001000, - FFMS_CH_TOP_FRONT_CENTER = 0x00002000, - FFMS_CH_TOP_FRONT_RIGHT = 0x00004000, - FFMS_CH_TOP_BACK_LEFT = 0x00008000, - FFMS_CH_TOP_BACK_CENTER = 0x00010000, - FFMS_CH_TOP_BACK_RIGHT = 0x00020000, - FFMS_CH_STEREO_LEFT = 0x20000000, - FFMS_CH_STEREO_RIGHT = 0x40000000 -} FFMS_AudioChannel; - -typedef enum FFMS_Resizers { - FFMS_RESIZER_FAST_BILINEAR = 0x0001, - FFMS_RESIZER_BILINEAR = 0x0002, - FFMS_RESIZER_BICUBIC = 0x0004, - FFMS_RESIZER_X = 0x0008, - FFMS_RESIZER_POINT = 0x0010, - FFMS_RESIZER_AREA = 0x0020, - FFMS_RESIZER_BICUBLIN = 0x0040, - FFMS_RESIZER_GAUSS = 0x0080, - FFMS_RESIZER_SINC = 0x0100, - FFMS_RESIZER_LANCZOS = 0x0200, - FFMS_RESIZER_SPLINE = 0x0400 -} FFMS_Resizers; - -typedef enum FFMS_AudioDelayModes { - FFMS_DELAY_NO_SHIFT = -3, - FFMS_DELAY_TIME_ZERO = -2, - FFMS_DELAY_FIRST_VIDEO_TRACK = -1 -} FFMS_AudioDelayModes; - -typedef enum FFMS_AudioGapFillModes { - FFMS_GAP_FILL_AUTO = -1, - FFMS_GAP_FILL_DISABLED = 0, - FFMS_GAP_FILL_ENABLED = -1 -} FFMS_AudioGapFillModes; - -typedef enum FFMS_ChromaLocations { - FFMS_LOC_UNSPECIFIED = 0, - FFMS_LOC_LEFT = 1, - FFMS_LOC_CENTER = 2, - FFMS_LOC_TOPLEFT = 3, - FFMS_LOC_TOP = 4, - FFMS_LOC_BOTTOMLEFT = 5, - FFMS_LOC_BOTTOM = 6 -} FFMS_ChromaLocations; - -typedef enum FFMS_ColorRanges { - FFMS_CR_UNSPECIFIED = 0, - FFMS_CR_MPEG = 1, // 219*2^(n-8), i.e. 16-235 with 8-bit samples - FFMS_CR_JPEG = 2 // 2^n-1, or "fullrange" -} FFMS_ColorRanges; - -typedef enum FFMS_Stereo3DType { - FFMS_S3D_TYPE_2D = 0, - FFMS_S3D_TYPE_SIDEBYSIDE, - FFMS_S3D_TYPE_TOPBOTTOM, - FFMS_S3D_TYPE_FRAMESEQUENCE, - FFMS_S3D_TYPE_CHECKERBOARD, - FFMS_S3D_TYPE_SIDEBYSIDE_QUINCUNX, - FFMS_S3D_TYPE_LINES, - FFMS_S3D_TYPE_COLUMNS -} FFMS_Stereo3DType; - -typedef enum FFMS_Stereo3DFlags { - FFMS_S3D_FLAGS_INVERT = 1 -} FFMS_Stereo3DFlags; - -typedef enum FFMS_MixingCoefficientType { - FFMS_MIXING_COEFFICIENT_Q8 = 0, - FFMS_MIXING_COEFFICIENT_Q15 = 1, - FFMS_MIXING_COEFFICIENT_FLT = 2 -} FFMS_MixingCoefficientType; - -typedef enum FFMS_MatrixEncoding { - FFMS_MATRIX_ENCODING_NONE = 0, - FFMS_MATRIX_ENCODING_DOBLY = 1, - FFMS_MATRIX_ENCODING_PRO_LOGIC_II = 2, - FFMS_MATRIX_ENCODING_PRO_LOGIC_IIX = 3, - FFMS_MATRIX_ENCODING_PRO_LOGIC_IIZ = 4, - FFMS_MATRIX_ENCODING_DOLBY_EX = 5, - FFMS_MATRIX_ENCODING_DOLBY_HEADPHONE = 6 -} FFMS_MatrixEncoding; - -typedef enum FFMS_ResampleFilterType { - FFMS_RESAMPLE_FILTER_CUBIC = 0, - FFMS_RESAMPLE_FILTER_SINC = 1, /* misnamed as multiple windowsed sinc filters exist, actually called BLACKMAN_NUTTALL */ - FFMS_RESAMPLE_FILTER_KAISER = 2 -} FFMS_ResampleFilterType; - -typedef enum FFMS_AudioDitherMethod { - FFMS_RESAMPLE_DITHER_NONE = 0, - FFMS_RESAMPLE_DITHER_RECTANGULAR = 1, - FFMS_RESAMPLE_DITHER_TRIANGULAR = 2, - FFMS_RESAMPLE_DITHER_TRIANGULAR_HIGHPASS = 3, - FFMS_RESAMPLE_DITHER_TRIANGULAR_NOISESHAPING = 4 -} FFMS_AudioDitherMethod; - -typedef enum FFMS_LogLevels { - FFMS_LOG_QUIET = -8, - FFMS_LOG_PANIC = 0, - FFMS_LOG_FATAL = 8, - FFMS_LOG_ERROR = 16, - FFMS_LOG_WARNING = 24, - FFMS_LOG_INFO = 32, - FFMS_LOG_VERBOSE = 40, - FFMS_LOG_DEBUG = 48, - FFMS_LOG_TRACE = 56 -} FFMS_LogLevels; - -typedef struct FFMS_ResampleOptions { - int64_t ChannelLayout; - FFMS_SampleFormat SampleFormat; - int SampleRate; - FFMS_MixingCoefficientType MixingCoefficientType; - double CenterMixLevel; - double SurroundMixLevel; - double LFEMixLevel; - int Normalize; - int ForceResample; - int ResampleFilterSize; - int ResamplePhaseShift; - int LinearInterpolation; - double CutoffFrequencyRatio; - FFMS_MatrixEncoding MatrixedStereoEncoding; - FFMS_ResampleFilterType FilterType; - int KaiserBeta; - FFMS_AudioDitherMethod DitherMethod; -} FFMS_ResampleOptions; - - -typedef struct FFMS_Frame { - const uint8_t *Data[4]; - int Linesize[4]; - int EncodedWidth; - int EncodedHeight; - int EncodedPixelFormat; - int ScaledWidth; - int ScaledHeight; - int ConvertedPixelFormat; - int KeyFrame; - int RepeatPict; - int InterlacedFrame; - int TopFieldFirst; - char PictType; - int ColorSpace; - int ColorRange; - /* Introduced in FFMS_VERSION ((2 << 24) | (21 << 16) | (0 << 8) | 0) */ - int ColorPrimaries; - int TransferCharateristics; - int ChromaLocation; - /* Introduced in FFMS_VERSION ((2 << 24) | (27 << 16) | (0 << 8) | 0) */ - int HasMasteringDisplayPrimaries; /* Non-zero if the 4 fields below are valid */ - double MasteringDisplayPrimariesX[3]; - double MasteringDisplayPrimariesY[3]; - double MasteringDisplayWhitePointX; - double MasteringDisplayWhitePointY; - int HasMasteringDisplayLuminance; /* Non-zero if the 2 fields below are valid */ - double MasteringDisplayMinLuminance; - double MasteringDisplayMaxLuminance; - int HasContentLightLevel; /* Non-zero if the 2 fields below are valid */ - unsigned int ContentLightLevelMax; - unsigned int ContentLightLevelAverage; - /* Introduced in FFMS_VERSION ((3 << 24) | (0 << 16) | (1 << 8) | 0) */ - uint8_t *DolbyVisionRPU; - int DolbyVisionRPUSize; - /* Introduced in FFMS_VERSION ((3 << 24) | (1 << 16) | (1 << 8) | 0) */ - uint8_t *HDR10Plus; - int HDR10PlusSize; -} FFMS_Frame; - -typedef struct FFMS_TrackTimeBase { - int64_t Num; - int64_t Den; -} FFMS_TrackTimeBase; - -typedef struct FFMS_FrameInfo { - int64_t PTS; - int RepeatPict; - int KeyFrame; - int64_t OriginalPTS; -} FFMS_FrameInfo; - -typedef struct FFMS_VideoProperties { - int FPSDenominator; - int FPSNumerator; - int RFFDenominator; - int RFFNumerator; - int NumFrames; - int SARNum; - int SARDen; - int CropTop; - int CropBottom; - int CropLeft; - int CropRight; - int TopFieldFirst; - FFMS_DEPRECATED int ColorSpace; /* Provided in FFMS_Frame */ - FFMS_DEPRECATED int ColorRange; /* Provided in FFMS_Frame */ - double FirstTime; - double LastTime; - /* Introduced in FFMS_VERSION ((2 << 24) | (24 << 16) | (0 << 8) | 0) */ - int Rotation; /* A positive number in degrees */ - int Stereo3DType; - int Stereo3DFlags; - /* Introduced in FFMS_VERSION ((2 << 24) | (30 << 16) | (0 << 8) | 0) */ - double LastEndTime; - int HasMasteringDisplayPrimaries; /* Non-zero if the 4 fields below are valid */ - double MasteringDisplayPrimariesX[3]; - double MasteringDisplayPrimariesY[3]; - double MasteringDisplayWhitePointX; - double MasteringDisplayWhitePointY; - int HasMasteringDisplayLuminance; /* Non-zero if the 2 fields below are valid */ - double MasteringDisplayMinLuminance; - double MasteringDisplayMaxLuminance; - int HasContentLightLevel; /* Non-zero if the 2 fields below are valid */ - unsigned int ContentLightLevelMax; - unsigned int ContentLightLevelAverage; - /* Introduced in FFMS_VERSION ((2 << 24) | (31 << 16) | (0 << 8) | 0) */ - int Flip; /* -1 = Vertical flip, 1 = Horizontal flip */ -} FFMS_VideoProperties; - -typedef struct FFMS_AudioProperties { - int SampleFormat; - int SampleRate; - int BitsPerSample; - int Channels; - int64_t ChannelLayout; // should probably be a plain int, none of the constants are >32 bits long - int64_t NumSamples; - double FirstTime; - double LastTime; - /* Introduced in FFMS_VERSION ((2 << 24) | (30 << 16) | (0 << 8) | 0) */ - double LastEndTime; -} FFMS_AudioProperties; - -typedef struct FFMS_KeyValuePair { - const char *Key; - const char *Value; -} FFMS_KeyValuePair; - -typedef int (FFMS_CC *TIndexCallback)(int64_t Current, int64_t Total, void *ICPrivate); - -/* Most functions return 0 on success */ -/* Functions without error message output can be assumed to never fail in a graceful way */ -FFMS_API(void) FFMS_Init(int, int); /* Pass 0 to both arguments, kept to partially preserve abi */ -FFMS_API(void) FFMS_Deinit(); -FFMS_API(int) FFMS_GetVersion(); -FFMS_API(int) FFMS_GetLogLevel(); -FFMS_API(void) FFMS_SetLogLevel(int Level); -FFMS_API(FFMS_VideoSource *) FFMS_CreateVideoSource(const char *SourceFile, int Track, FFMS_Index *Index, int Threads, int SeekMode, FFMS_ErrorInfo *ErrorInfo); -FFMS_API(FFMS_AudioSource *) FFMS_CreateAudioSource(const char *SourceFile, int Track, FFMS_Index *Index, int DelayMode, FFMS_ErrorInfo *ErrorInfo); -FFMS_API(FFMS_AudioSource *) FFMS_CreateAudioSource2(const char *SourceFile, int Track, FFMS_Index *Index, int DelayMode, int FillGaps, double DrcScale, FFMS_ErrorInfo *ErrorInfo); -FFMS_API(void) FFMS_DestroyVideoSource(FFMS_VideoSource *V); -FFMS_API(void) FFMS_DestroyAudioSource(FFMS_AudioSource *A); -FFMS_API(const FFMS_VideoProperties *) FFMS_GetVideoProperties(FFMS_VideoSource *V); -FFMS_API(const FFMS_AudioProperties *) FFMS_GetAudioProperties(FFMS_AudioSource *A); -FFMS_API(const FFMS_Frame *) FFMS_GetFrame(FFMS_VideoSource *V, int n, FFMS_ErrorInfo *ErrorInfo); -FFMS_API(const FFMS_Frame *) FFMS_GetFrameByTime(FFMS_VideoSource *V, double Time, FFMS_ErrorInfo *ErrorInfo); -FFMS_API(int) FFMS_GetAudio(FFMS_AudioSource *A, void *Buf, int64_t Start, int64_t Count, FFMS_ErrorInfo *ErrorInfo); -FFMS_API(int) FFMS_SetOutputFormatV2(FFMS_VideoSource *V, const int *TargetFormats, int Width, int Height, int Resizer, FFMS_ErrorInfo *ErrorInfo); /* Introduced in FFMS_VERSION ((2 << 24) | (15 << 16) | (3 << 8) | 0) */ -FFMS_API(void) FFMS_ResetOutputFormatV(FFMS_VideoSource *V); -FFMS_API(int) FFMS_SetInputFormatV(FFMS_VideoSource *V, int ColorSpace, int ColorRange, int Format, FFMS_ErrorInfo *ErrorInfo); /* Introduced in FFMS_VERSION ((2 << 24) | (17 << 16) | (1 << 8) | 0) */ -FFMS_API(void) FFMS_ResetInputFormatV(FFMS_VideoSource *V); -FFMS_API(FFMS_ResampleOptions *) FFMS_CreateResampleOptions(FFMS_AudioSource *A); /* Introduced in FFMS_VERSION ((2 << 24) | (15 << 16) | (4 << 8) | 0) */ -FFMS_API(int) FFMS_SetOutputFormatA(FFMS_AudioSource *A, const FFMS_ResampleOptions*options, FFMS_ErrorInfo *ErrorInfo); /* Introduced in FFMS_VERSION ((2 << 24) | (15 << 16) | (4 << 8) | 0) */ -FFMS_API(void) FFMS_DestroyResampleOptions(FFMS_ResampleOptions *options); /* Introduced in FFMS_VERSION ((2 << 24) | (15 << 16) | (4 << 8) | 0) */ -FFMS_API(void) FFMS_DestroyIndex(FFMS_Index *Index); -FFMS_API(int) FFMS_GetFirstTrackOfType(FFMS_Index *Index, int TrackType, FFMS_ErrorInfo *ErrorInfo); -FFMS_API(int) FFMS_GetFirstIndexedTrackOfType(FFMS_Index *Index, int TrackType, FFMS_ErrorInfo *ErrorInfo); -FFMS_API(int) FFMS_GetNumTracks(FFMS_Index *Index); -FFMS_API(int) FFMS_GetNumTracksI(FFMS_Indexer *Indexer); -FFMS_API(int) FFMS_GetTrackType(FFMS_Track *T); -FFMS_API(int) FFMS_GetTrackTypeI(FFMS_Indexer *Indexer, int Track); -FFMS_API(FFMS_IndexErrorHandling) FFMS_GetErrorHandling(FFMS_Index *Index); -FFMS_API(const char *) FFMS_GetCodecNameI(FFMS_Indexer *Indexer, int Track); -FFMS_API(const char *) FFMS_GetFormatNameI(FFMS_Indexer *Indexer); -FFMS_API(int) FFMS_GetNumFrames(FFMS_Track *T); -FFMS_API(const FFMS_FrameInfo *) FFMS_GetFrameInfo(FFMS_Track *T, int Frame); -FFMS_API(FFMS_Track *) FFMS_GetTrackFromIndex(FFMS_Index *Index, int Track); -FFMS_API(FFMS_Track *) FFMS_GetTrackFromVideo(FFMS_VideoSource *V); -FFMS_API(FFMS_Track *) FFMS_GetTrackFromAudio(FFMS_AudioSource *A); -FFMS_API(const FFMS_TrackTimeBase *) FFMS_GetTimeBase(FFMS_Track *T); -FFMS_API(int) FFMS_WriteTimecodes(FFMS_Track *T, const char *TimecodeFile, FFMS_ErrorInfo *ErrorInfo); -FFMS_API(FFMS_Indexer *) FFMS_CreateIndexer(const char *SourceFile, FFMS_ErrorInfo *ErrorInfo); -FFMS_API(FFMS_Indexer *) FFMS_CreateIndexer2(const char *SourceFile, const FFMS_KeyValuePair *DemuxerOptions, int NumOptions, FFMS_ErrorInfo *ErrorInfo); -FFMS_API(void) FFMS_TrackIndexSettings(FFMS_Indexer *Indexer, int Track, int Index, int); /* Pass 0 to last argument, kapt to preserve abi. Introduced in FFMS_VERSION ((2 << 24) | (21 << 16) | (0 << 8) | 0) */ -FFMS_API(void) FFMS_TrackTypeIndexSettings(FFMS_Indexer *Indexer, int TrackType, int Index, int); /* Pass 0 to last argument, kapt to preserve abi. Introduced in FFMS_VERSION ((2 << 24) | (21 << 16) | (0 << 8) | 0) */ -FFMS_API(void) FFMS_SetProgressCallback(FFMS_Indexer *Indexer, TIndexCallback IC, void *ICPrivate); /* Introduced in FFMS_VERSION ((2 << 24) | (21 << 16) | (0 << 8) | 0) */ -FFMS_API(FFMS_Index *) FFMS_DoIndexing2(FFMS_Indexer *Indexer, int ErrorHandling, FFMS_ErrorInfo *ErrorInfo); /* Introduced in FFMS_VERSION ((2 << 24) | (21 << 16) | (0 << 8) | 0) */ -FFMS_API(void) FFMS_CancelIndexing(FFMS_Indexer *Indexer); -FFMS_API(FFMS_Index *) FFMS_ReadIndex(const char *IndexFile, FFMS_ErrorInfo *ErrorInfo); -FFMS_API(FFMS_Index *) FFMS_ReadIndexFromBuffer(const uint8_t *Buffer, size_t Size, FFMS_ErrorInfo *ErrorInfo); -FFMS_API(int) FFMS_IndexBelongsToFile(FFMS_Index *Index, const char *SourceFile, FFMS_ErrorInfo *ErrorInfo); -FFMS_API(int) FFMS_WriteIndex(const char *IndexFile, FFMS_Index *Index, FFMS_ErrorInfo *ErrorInfo); -FFMS_API(int) FFMS_WriteIndexToBuffer(uint8_t **BufferPtr, size_t *Size, FFMS_Index *Index, FFMS_ErrorInfo *ErrorInfo); -FFMS_API(void) FFMS_FreeIndexBuffer(uint8_t **BufferPtr); -FFMS_API(int) FFMS_GetPixFmt(const char *Name); -#endif diff --git a/thirdparty/ffms2/include/ffmscompat.h b/thirdparty/ffms2/include/ffmscompat.h deleted file mode 100644 index 349a45cfd..000000000 --- a/thirdparty/ffms2/include/ffmscompat.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2007-2011 Fredrik Mellbin -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#ifndef FFMSCOMPAT_H -#define FFMSCOMPAT_H - -#define VERSION_CHECK(LIB, cmp, major, minor, micro) ((LIB) cmp (AV_VERSION_INT(major, minor, micro))) - -#endif // FFMSCOMPAT_H diff --git a/thirdparty/ffms2/m4/check_zlib.m4 b/thirdparty/ffms2/m4/check_zlib.m4 deleted file mode 100644 index 4e6ff5000..000000000 --- a/thirdparty/ffms2/m4/check_zlib.m4 +++ /dev/null @@ -1,28 +0,0 @@ -AC_DEFUN([CHECK_ZLIB],[ - AC_ARG_WITH(zlib,AS_HELP_STRING([--with-zlib=DIR],[specify zlib's root installation folder]), - [ZLIB_HOME="$with_zlib"]) - - if test -n "${ZLIB_HOME}" -a "${ZLIB_HOME}" != "yes" -a "${ZLIB_HOME}" != "no" ; then - ZLIB_CPPFLAGS="-I${ZLIB_HOME}/include" - ZLIB_LDFLAGS="-L${ZLIB_HOME}/lib" - fi - - ZLIB_OLD_LDFLAGS=$LDFLAGS - ZLIB_OLD_CPPFLAGS=$CPPFLAGS - LDFLAGS="$LDFLAGS $ZLIB_LDFLAGS" - CPPFLAGS="$CPPFLAGS $ZLIB_CPPFLAGS" - AC_LANG_PUSH(C) - AC_CHECK_HEADER(zlib.h, [zlib_cv_zlib_h=yes], [zlib_cv_zlib_h=no]) - AC_CHECK_LIB(z, inflateEnd, [zlib_cv_libz=yes], [zlib_cv_libz=no]) - AC_LANG_POP(C) - LDFLAGS=$ZLIB_OLD_LDFLAGS - CPPFLAGS=$ZLIB_OLD_CPPFLAGS - if test "$zlib_cv_libz" = "yes" -a "$zlib_cv_zlib_h" = "yes" - then - HAVE_ZLIB=yes - AC_SUBST([ZLIB_CPPFLAGS]) - AC_SUBST([ZLIB_LDFLAGS]) - else - AC_MSG_FAILURE([cannot locate zlib.h and -lz, specify a valid zlib installation using --with-zlib=DIR]) - fi -]) diff --git a/thirdparty/ffms2/src/avisynth/avisynth.cpp b/thirdparty/ffms2/src/avisynth/avisynth.cpp deleted file mode 100644 index 4ee90ba4f..000000000 --- a/thirdparty/ffms2/src/avisynth/avisynth.cpp +++ /dev/null @@ -1,368 +0,0 @@ -// Copyright (c) 2007-2017 Fredrik Mellbin -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#include -#include "ffms.h" -#include "avssources.h" -#include "../core/utils.h" - -#ifdef _WIN32 -#define AVS_EXPORT __declspec(dllexport) -#else -#define AVS_EXPORT __attribute__((visibility("default"))) -#endif - -static AVSValue __cdecl CreateFFIndex(AVSValue Args, void* UserData, IScriptEnvironment* Env) { - if (!Args[0].Defined()) - Env->ThrowError("FFIndex: No source specified"); - - FFMS_Init(0, 0); - - const char *Source = Args[0].AsString(); - const char *CacheFile = Args[1].AsString(""); - int IndexMask = Args[2].AsInt(-1); - int ErrorHandling = Args[3].AsInt(FFMS_IEH_IGNORE); - bool OverWrite = Args[4].AsBool(false); - bool EnableDrefs = Args[5].AsBool(false); - bool UseAbsolutePath = Args[6].AsBool(false); - - std::string DefaultCache(Source); - DefaultCache.append(".ffindex"); - if (!strcmp(CacheFile, "")) - CacheFile = DefaultCache.c_str(); - - ErrorInfo E; - FFMS_Index *Index = FFMS_ReadIndex(CacheFile, &E); - if (OverWrite || !Index || (Index && FFMS_IndexBelongsToFile(Index, Source, 0) != FFMS_ERROR_SUCCESS)) { - FFMS_KeyValuePair LAVFOpts[] = {{ "enable_drefs", EnableDrefs ? "1" : "0" }, { "use_absolute_path", UseAbsolutePath ? "1" : "0" }}; - FFMS_Indexer *Indexer = FFMS_CreateIndexer2(Source, LAVFOpts, 2, &E); - if (!Indexer) - Env->ThrowError("FFIndex: %s", E.Buffer); - - // Treat -1 as meaning track numbers above sizeof(int) too - if (IndexMask == -1) - FFMS_TrackTypeIndexSettings(Indexer, FFMS_TYPE_AUDIO, 1, 0); - - // Apply attributes to remaining tracks (will set the attributes again on some tracks) - for (int i = 0; i < sizeof(IndexMask) * 8; i++) { - if ((IndexMask >> i) & 1) - FFMS_TrackIndexSettings(Indexer, i, 1, 0); - } - - Index = FFMS_DoIndexing2(Indexer, ErrorHandling, &E); - if (!Index) - Env->ThrowError("FFIndex: %s", E.Buffer); - if (FFMS_WriteIndex(CacheFile, Index, &E)) { - FFMS_DestroyIndex(Index); - Env->ThrowError("FFIndex: %s", E.Buffer); - } - FFMS_DestroyIndex(Index); - if (!OverWrite) - return AVSValue(1); - else - return AVSValue(2); - } else { - FFMS_DestroyIndex(Index); - return AVSValue(0); - } -} - -static AVSValue __cdecl CreateFFVideoSource(AVSValue Args, void* UserData, IScriptEnvironment* Env) { - FFMS_Init(0, 0); - - if (!Args[0].Defined()) - Env->ThrowError("FFVideoSource: No source specified"); - - const char *Source = Args[0].AsString(); - int Track = Args[1].AsInt(-1); - bool Cache = Args[2].AsBool(true); - const char *CacheFile = Args[3].AsString(""); - int FPSNum = Args[4].AsInt(-1); - int FPSDen = Args[5].AsInt(1); - int Threads = Args[6].AsInt(-1); - const char *Timecodes = Args[7].AsString(""); - int SeekMode = Args[8].AsInt(1); - int RFFMode = Args[9].AsInt(0); - int Width = Args[10].AsInt(0); - int Height = Args[11].AsInt(0); - const char *Resizer = Args[12].AsString("BICUBIC"); - const char *ColorSpace = Args[13].AsString(""); - const char *VarPrefix = Args[14].AsString(""); - - if (FPSDen < 1) - Env->ThrowError("FFVideoSource: FPS denominator needs to be 1 or higher"); - - if (Track <= -2) - Env->ThrowError("FFVideoSource: No video track selected"); - - if (SeekMode < -1 || SeekMode > 3) - Env->ThrowError("FFVideoSource: Invalid seekmode selected"); - - if (RFFMode < 0 || RFFMode > 2) - Env->ThrowError("FFVideoSource: Invalid RFF mode selected"); - - if (RFFMode > 0 && FPSNum > 0) - Env->ThrowError("FFVideoSource: RFF modes may not be combined with CFR conversion"); - - if (IsSamePath(Source, Timecodes)) - Env->ThrowError("FFVideoSource: Timecodes will overwrite the source"); - - ErrorInfo E; - FFMS_Index *Index = nullptr; - std::string DefaultCache; - if (Cache) { - if (*CacheFile) { - if (IsSamePath(Source, CacheFile)) - Env->ThrowError("FFVideoSource: Cache will overwrite the source"); - Index = FFMS_ReadIndex(CacheFile, &E); - } else { - DefaultCache = Source; - DefaultCache += ".ffindex"; - CacheFile = DefaultCache.c_str(); - Index = FFMS_ReadIndex(CacheFile, &E); - // Reindex if the index doesn't match the file and its name wasn't - // explicitly given - if (Index && FFMS_IndexBelongsToFile(Index, Source, 0) != FFMS_ERROR_SUCCESS) { - FFMS_DestroyIndex(Index); - Index = 0; - } - } - } - - if (!Index) { - FFMS_Indexer *Indexer = FFMS_CreateIndexer(Source, &E); - if (!Indexer) - Env->ThrowError("FFVideoSource: %s", E.Buffer); - - Index = FFMS_DoIndexing2(Indexer, FFMS_IEH_CLEAR_TRACK, &E); - if (!Index) - Env->ThrowError("FFVideoSource: %s", E.Buffer); - - if (Cache) - if (FFMS_WriteIndex(CacheFile, Index, &E)) { - FFMS_DestroyIndex(Index); - Env->ThrowError("FFVideoSource: %s", E.Buffer); - } - } - - if (Track == -1) - Track = FFMS_GetFirstIndexedTrackOfType(Index, FFMS_TYPE_VIDEO, &E); - if (Track < 0) - Env->ThrowError("FFVideoSource: No video track found"); - - if (strcmp(Timecodes, "")) { - if (FFMS_WriteTimecodes(FFMS_GetTrackFromIndex(Index, Track), Timecodes, &E)) { - FFMS_DestroyIndex(Index); - Env->ThrowError("FFVideoSource: %s", E.Buffer); - } - } - - AvisynthVideoSource *Filter; - - try { - Filter = new AvisynthVideoSource(Source, Track, Index, FPSNum, FPSDen, Threads, SeekMode, RFFMode, Width, Height, Resizer, ColorSpace, VarPrefix, Env); - } catch (...) { - FFMS_DestroyIndex(Index); - throw; - } - - FFMS_DestroyIndex(Index); - return Filter; -} - -static AVSValue __cdecl CreateFFAudioSource(AVSValue Args, void* UserData, IScriptEnvironment* Env) { - FFMS_Init(0, 0); - - if (!Args[0].Defined()) - Env->ThrowError("FFAudioSource: No source specified"); - - const char *Source = Args[0].AsString(); - int Track = Args[1].AsInt(-1); - bool Cache = Args[2].AsBool(true); - const char *CacheFile = Args[3].AsString(""); - int AdjustDelay = Args[4].AsInt(-1); - int FillGaps = Args[5].AsInt(-1); - double DrcScale = Args[6].AsFloat(0); - const char *VarPrefix = Args[7].AsString(""); - - if (Track <= -2) - Env->ThrowError("FFAudioSource: No audio track selected"); - - ErrorInfo E; - FFMS_Index *Index = nullptr; - std::string DefaultCache; - if (Cache) { - if (*CacheFile) { - if (IsSamePath(Source, CacheFile)) - Env->ThrowError("FFAudioSource: Cache will overwrite the source"); - Index = FFMS_ReadIndex(CacheFile, &E); - } else { - DefaultCache = Source; - DefaultCache += ".ffindex"; - CacheFile = DefaultCache.c_str(); - Index = FFMS_ReadIndex(CacheFile, &E); - // Reindex if the index doesn't match the file and its name wasn't - // explicitly given - if (Index && FFMS_IndexBelongsToFile(Index, Source, 0) != FFMS_ERROR_SUCCESS) { - FFMS_DestroyIndex(Index); - Index = 0; - } - } - } - - // Index needs to be remade if it is an unindexed audio track - if (Index && Track >= 0 && Track < FFMS_GetNumTracks(Index) - && FFMS_GetTrackType(FFMS_GetTrackFromIndex(Index, Track)) == FFMS_TYPE_AUDIO - && FFMS_GetNumFrames(FFMS_GetTrackFromIndex(Index, Track)) == 0) { - FFMS_DestroyIndex(Index); - Index = nullptr; - } - - // More complicated for finding a default track, reindex the file if at least one audio track exists - if (Index && FFMS_GetFirstTrackOfType(Index, FFMS_TYPE_AUDIO, &E) >= 0 - && FFMS_GetFirstIndexedTrackOfType(Index, FFMS_TYPE_AUDIO, &E) < 0) { - for (int i = 0; i < FFMS_GetNumTracks(Index); i++) { - if (FFMS_GetTrackType(FFMS_GetTrackFromIndex(Index, i)) == FFMS_TYPE_AUDIO) { - FFMS_DestroyIndex(Index); - Index = nullptr; - break; - } - } - } - - if (!Index) { - FFMS_Indexer *Indexer = FFMS_CreateIndexer(Source, &E); - if (!Indexer) - Env->ThrowError("FFAudioSource: %s", E.Buffer); - - FFMS_TrackTypeIndexSettings(Indexer, FFMS_TYPE_AUDIO, 1, 0); - - Index = FFMS_DoIndexing2(Indexer, FFMS_IEH_CLEAR_TRACK, &E); - if (!Index) - Env->ThrowError("FFAudioSource: %s", E.Buffer); - - if (Cache) - if (FFMS_WriteIndex(CacheFile, Index, &E)) { - FFMS_DestroyIndex(Index); - Env->ThrowError("FFAudioSource: %s", E.Buffer); - } - } - - if (Track == -1) - Track = FFMS_GetFirstIndexedTrackOfType(Index, FFMS_TYPE_AUDIO, &E); - if (Track < 0) - Env->ThrowError("FFAudioSource: No audio track found"); - - if (AdjustDelay < -3) - Env->ThrowError("FFAudioSource: Invalid delay adjustment specified"); - if (AdjustDelay >= FFMS_GetNumTracks(Index)) - Env->ThrowError("FFAudioSource: Invalid track to calculate delay from specified"); - - AvisynthAudioSource *Filter; - - try { - Filter = new AvisynthAudioSource(Source, Track, Index, AdjustDelay, FillGaps, DrcScale, VarPrefix, Env); - } catch (...) { - FFMS_DestroyIndex(Index); - throw; - } - - FFMS_DestroyIndex(Index); - return Filter; -} - -static AVSValue __cdecl CreateFFmpegSource2(AVSValue Args, void* UserData, IScriptEnvironment* Env) { - const char *FFIArgNames[] = { "source", "cachefile", "indexmask", "overwrite", "enable_drefs", "use_absolute_path"}; - const char *FFVArgNames[] = { "source", "track", "cache", "cachefile", "fpsnum", "fpsden", "threads", "timecodes", "seekmode", "rffmode", "width", "height", "resizer", "colorspace", "varprefix" }; - const char *FFAArgNames[] = { "source", "track", "cache", "cachefile", "adjustdelay", "fill_gaps", "drc_scale", "varprefix"}; - - bool Cache = Args[3].AsBool(true); - bool WithAudio = Args[2].AsInt(-2) > -2; - if (Cache) { - AVSValue FFIArgs[] = { Args[0], Args[4], WithAudio ? -1 : 0, Args[10], Args[17], Args[18]}; - static_assert((sizeof(FFIArgs) / sizeof(FFIArgs[0])) == (sizeof(FFIArgNames) / sizeof(FFIArgNames[0])), "Arg error"); - Env->Invoke("FFIndex", AVSValue(FFIArgs, sizeof(FFIArgs) / sizeof(FFIArgs[0])), FFIArgNames); - } - - AVSValue FFVArgs[] = { Args[0], Args[1], Args[3], Args[4], Args[5], Args[6], Args[7], Args[8], Args[9], Args[15], Args[11], Args[12], Args[13], Args[14], Args[21] }; - static_assert((sizeof(FFVArgs) / sizeof(FFVArgs[0])) == (sizeof(FFVArgNames) / sizeof(FFVArgNames[0])), "Arg error"); - AVSValue Video = Env->Invoke("FFVideoSource", AVSValue(FFVArgs, sizeof(FFVArgs) / sizeof(FFVArgs[0])), FFVArgNames); - - AVSValue Audio; - if (WithAudio) { - AVSValue FFAArgs[] = { Args[0], Args[2], Args[3], Args[4], Args[16], Args[19], Args[20], Args[21] }; - static_assert((sizeof(FFAArgs) / sizeof(FFAArgs[0])) == (sizeof(FFAArgNames) / sizeof(FFAArgNames[0])), "Arg error"); - Audio = Env->Invoke("FFAudioSource", AVSValue(FFAArgs, sizeof(FFAArgs) / sizeof(FFAArgs[0])), FFAArgNames); - AVSValue ADArgs[] = { Video, Audio }; - return Env->Invoke("AudioDubEx", AVSValue(ADArgs, sizeof(ADArgs) / sizeof(ADArgs[0]))); - } else { - return Video; - } -} - -static AVSValue __cdecl CreateFFImageSource(AVSValue Args, void* UserData, IScriptEnvironment* Env) { - const char *FFISArgNames[] = { "source", "width", "height", "resizer", "colorspace", "varprefix", "cache", "seekmode" }; - AVSValue FFISArgs[] = { Args[0], Args[1], Args[2], Args[3], Args[4], Args[5], false, -1 }; - static_assert((sizeof(FFISArgs) / sizeof(FFISArgs[0])) == (sizeof(FFISArgNames) / sizeof(FFISArgNames[0])), "Arg error"); - return Env->Invoke("FFVideoSource", AVSValue(FFISArgs, sizeof(FFISArgs) / sizeof(FFISArgs[0])), FFISArgNames); -} - -static AVSValue __cdecl CreateFFCopyrightInfringement(AVSValue Args, void* UserData, IScriptEnvironment* Env) { - const char *ArgNames[] = { "source" }; - Env->Invoke("FFIndex", Args, ArgNames); - AVSValue ExArgs[2] = { Env->Invoke("FFVideoSource", Args, ArgNames), Env->Invoke("FFAudioSource", Args, ArgNames) }; - return Env->Invoke("AudioDubEx", AVSValue(ExArgs, sizeof(ExArgs) / sizeof(ExArgs[0]))); -} - -static AVSValue __cdecl FFGetLogLevel(AVSValue Args, void* UserData, IScriptEnvironment* Env) { - return FFMS_GetLogLevel(); -} - -static AVSValue __cdecl FFSetLogLevel(AVSValue Args, void* UserData, IScriptEnvironment* Env) { - FFMS_SetLogLevel(Args[0].AsInt()); - return FFMS_GetLogLevel(); -} - -static AVSValue __cdecl FFGetVersion(AVSValue Args, void* UserData, IScriptEnvironment* Env) { - int Version = FFMS_GetVersion(); - return Env->Sprintf("%d.%d.%d.%d", Version >> 24, (Version & 0xFF0000) >> 16, (Version & 0xFF00) >> 8, Version & 0xFF); -} - -const AVS_Linkage *AVS_linkage = nullptr; - -extern "C" AVS_EXPORT const char* __stdcall AvisynthPluginInit3(IScriptEnvironment* Env, const AVS_Linkage* const vectors) { - AVS_linkage = vectors; - - Env->AddFunction("FFIndex", "[source]s[cachefile]s[indexmask]i[errorhandling]i[overwrite]b[enable_drefs]b[use_absolute_path]b", CreateFFIndex, nullptr); - Env->AddFunction("FFVideoSource", "[source]s[track]i[cache]b[cachefile]s[fpsnum]i[fpsden]i[threads]i[timecodes]s[seekmode]i[rffmode]i[width]i[height]i[resizer]s[colorspace]s[varprefix]s", CreateFFVideoSource, nullptr); - Env->AddFunction("FFAudioSource", "[source]s[track]i[cache]b[cachefile]s[adjustdelay]i[fill_gaps]i[drc_scale]f[varprefix]s", CreateFFAudioSource, nullptr); - - Env->AddFunction("FFmpegSource2", "[source]s[vtrack]i[atrack]i[cache]b[cachefile]s[fpsnum]i[fpsden]i[threads]i[timecodes]s[seekmode]i[overwrite]b[width]i[height]i[resizer]s[colorspace]s[rffmode]i[adjustdelay]i[enable_drefs]b[use_absolute_path]b[fill_gaps]i[drc_scale]f[varprefix]s", CreateFFmpegSource2, nullptr); - Env->AddFunction("FFMS2", "[source]s[vtrack]i[atrack]i[cache]b[cachefile]s[fpsnum]i[fpsden]i[threads]i[timecodes]s[seekmode]i[overwrite]b[width]i[height]i[resizer]s[colorspace]s[rffmode]i[adjustdelay]i[enable_drefs]b[use_absolute_path]b[fill_gaps]i[drc_scale]f[varprefix]s", CreateFFmpegSource2, nullptr); - - Env->AddFunction("FFImageSource", "[source]s[width]i[height]i[resizer]s[colorspace]s[varprefix]s", CreateFFImageSource, nullptr); - Env->AddFunction("FFCopyrightInfringement", "[source]s", CreateFFCopyrightInfringement, nullptr); - - Env->AddFunction("FFGetLogLevel", "", FFGetLogLevel, nullptr); - Env->AddFunction("FFSetLogLevel", "i", FFSetLogLevel, nullptr); - Env->AddFunction("FFGetVersion", "", FFGetVersion, nullptr); - - return "FFmpegSource - The Second Coming V2.0 Final"; -} diff --git a/thirdparty/ffms2/src/avisynth/avssources.cpp b/thirdparty/ffms2/src/avisynth/avssources.cpp deleted file mode 100644 index c02b75651..000000000 --- a/thirdparty/ffms2/src/avisynth/avssources.cpp +++ /dev/null @@ -1,696 +0,0 @@ -// Copyright (c) 2007-2017 Fredrik Mellbin -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#define NOMINMAX -#include "avssources.h" -#include "../vapoursynth/VSHelper4.h" -#include "../core/utils.h" - -#include -#include - -static AVPixelFormat CSNameToPIXFMT(const char *CSName, AVPixelFormat Default, bool HighBitDepth) { - if (!CSName) - return AV_PIX_FMT_NONE; - std::string s = CSName; - std::transform(s.begin(), s.end(), s.begin(), toupper); - if (s == "") - return Default; - if (s == "YUV9" || s == "YUV410P8") - return AV_PIX_FMT_YUV410P; - if (s == "YV411" || s == "YUV411P8") - return AV_PIX_FMT_YUV411P; - if (s == "YV12" || s == "YUV420P8") - return AV_PIX_FMT_YUV420P; - if (s == "YV16" || s == "YUV422P8") - return AV_PIX_FMT_YUV422P; - if (s == "YV24" || s == "YUV444P8") - return AV_PIX_FMT_YUV444P; - if (s == "Y8" || s == "GRAY8") - return AV_PIX_FMT_GRAY8; - if (s == "YUY2") - return AV_PIX_FMT_YUYV422; - if (s == "RGB24") - return AV_PIX_FMT_BGR24; - if (s == "RGB32") - return AV_PIX_FMT_RGB32; - if (HighBitDepth) { - if (s == "YUVA420P8") - return AV_PIX_FMT_YUVA420P; - if (s == "YUVA422P8") - return AV_PIX_FMT_YUVA422P; - if (s == "YUVA444P8") - return AV_PIX_FMT_YUVA444P; - if (s == "YUV420P16") - return AV_PIX_FMT_YUV420P16; - if (s == "YUVA420P16") - return AV_PIX_FMT_YUVA420P16; - if (s == "YUV422P16") - return AV_PIX_FMT_YUV422P16; - if (s == "YUVA422P16") - return AV_PIX_FMT_YUVA422P16; - if (s == "YUV444P16") - return AV_PIX_FMT_YUV444P16; - if (s == "YUVA444P16") - return AV_PIX_FMT_YUVA444P16; - if (s == "YUV420P10") - return AV_PIX_FMT_YUV420P10; - if (s == "YUVA420P10") - return AV_PIX_FMT_YUVA420P10; - if (s == "YUV422P10") - return AV_PIX_FMT_YUV422P10; - if (s == "YUVA422P10") - return AV_PIX_FMT_YUVA422P10; - if (s == "YUV444P10") - return AV_PIX_FMT_YUV444P10; - if (s == "YUVA444P10") - return AV_PIX_FMT_YUVA444P10; - if (s == "RGBP8") - return AV_PIX_FMT_GBRP; - if (s == "RGBP10") - return AV_PIX_FMT_GBRP10; - if (s == "RGBP12") - return AV_PIX_FMT_GBRP12; - if (s == "RGBP16") - return AV_PIX_FMT_GBRP16; - if (s == "RGBPS") - return AV_PIX_FMT_GBRPF32; - if (s == "RGBAP8") - return AV_PIX_FMT_GBRAP; - if (s == "RGBAP10") - return AV_PIX_FMT_GBRAP10; - if (s == "RGBAP12") - return AV_PIX_FMT_GBRAP12; - if (s == "RGBAP16") - return AV_PIX_FMT_GBRAP16; - if (s == "RGBAPS") - return AV_PIX_FMT_GBRAPF32; - if (s == "Y10" || s == "GRAY10") - return AV_PIX_FMT_GRAY10; - if (s == "Y12" || s == "GRAY12") - return AV_PIX_FMT_GRAY12; - if (s == "Y16" || s == "GRAY16") - return AV_PIX_FMT_GRAY16; - } - - return AV_PIX_FMT_NONE; -} - -AvisynthVideoSource::AvisynthVideoSource(const char *SourceFile, int Track, FFMS_Index *Index, - int FPSNum, int FPSDen, int Threads, int SeekMode, int RFFMode, - int ResizeToWidth, int ResizeToHeight, const char *ResizerName, - const char *ConvertToFormatName, const char *VarPrefix, IScriptEnvironment* Env) - : FPSNum(FPSNum) - , FPSDen(FPSDen) - , RFFMode(RFFMode) - , VarPrefix(VarPrefix) { - VI = {}; - - // check if the two functions we need for many bits are present - VI.pixel_type = VideoInfo::CS_Y16; - HighBitDepth = (VI.ComponentSize() == 2 && VI.IsY()); - VI.pixel_type = VideoInfo::CS_UNKNOWN; - - ErrorInfo E; - V = FFMS_CreateVideoSource(SourceFile, Track, Index, Threads, SeekMode, &E); - if (!V) - Env->ThrowError("FFVideoSource: %s", E.Buffer); - - try { - InitOutputFormat(ResizeToWidth, ResizeToHeight, ResizerName, ConvertToFormatName, Env); - } catch (AvisynthError &) { - FFMS_DestroyVideoSource(V); - throw; - } - - const FFMS_VideoProperties *VP = FFMS_GetVideoProperties(V); - - if (RFFMode > 0) { - // This part assumes things, and so should you - - FFMS_Track *VTrack = FFMS_GetTrackFromVideo(V); - - if (FFMS_GetFrameInfo(VTrack, 0)->RepeatPict < 0) { - FFMS_DestroyVideoSource(V); - Env->ThrowError("FFVideoSource: No RFF flags present"); - } - - int RepeatMin = FFMS_GetFrameInfo(VTrack, 0)->RepeatPict; - int NumFields = 0; - - for (int i = 0; i < VP->NumFrames; i++) { - int RepeatPict = FFMS_GetFrameInfo(VTrack, i)->RepeatPict; - NumFields += RepeatPict + 1; - RepeatMin = std::min(RepeatMin, RepeatPict); - } - - for (int i = 0; i < VP->NumFrames; i++) { - int RepeatPict = FFMS_GetFrameInfo(VTrack, i)->RepeatPict; - - if (((RepeatPict + 1) * 2) % (RepeatMin + 1)) { - FFMS_DestroyVideoSource(V); - Env->ThrowError("FFVideoSource: Unsupported RFF flag pattern"); - } - } - - VI.fps_denominator = VP->RFFDenominator * (RepeatMin + 1); - VI.fps_numerator = VP->RFFNumerator; - VI.num_frames = (NumFields + RepeatMin) / (RepeatMin + 1); - - int DestField = 0; - FieldList.resize(VI.num_frames); - for (int i = 0; i < VP->NumFrames; i++) { - int RepeatPict = FFMS_GetFrameInfo(VTrack, i)->RepeatPict; - int RepeatFields = ((RepeatPict + 1) * 2) / (RepeatMin + 1); - - for (int j = 0; j < RepeatFields; j++) { - if ((DestField + (VP->TopFieldFirst ? 0 : 1)) & 1) - FieldList[DestField / 2].Top = i; - else - FieldList[DestField / 2].Bottom = i; - DestField++; - } - } - - if (RFFMode == 2) { - VI.num_frames = (VI.num_frames * 4) / 5; - VI.fps_denominator *= 5; - VI.fps_numerator *= 4; - - int OutputFrames = 0; - - for (int i = 0; i < VI.num_frames / 4; i++) { - bool HasDropped = false; - - FieldList[OutputFrames].Top = FieldList[i * 5].Top; - FieldList[OutputFrames].Bottom = FieldList[i * 5].Top; - OutputFrames++; - - for (int j = 1; j < 5; j++) { - if (!HasDropped && FieldList[i * 5 + j - 1].Top == FieldList[i * 5 + j].Top) { - HasDropped = true; - continue; - } - - FieldList[OutputFrames].Top = FieldList[i * 5 + j].Top; - FieldList[OutputFrames].Bottom = FieldList[i * 5 + j].Top; - OutputFrames++; - } - - if (!HasDropped) - OutputFrames--; - } - - if (OutputFrames > 0) - for (int i = OutputFrames - 1; i < static_cast(FieldList.size()); i++) { - FieldList[i].Top = FieldList[OutputFrames - 1].Top; - FieldList[i].Bottom = FieldList[OutputFrames - 1].Top; - } - - FieldList.resize(VI.num_frames); - } - } else { - if (FPSNum > 0 && FPSDen > 0) { - VI.fps_denominator = FPSDen; - VI.fps_numerator = FPSNum; - if (VP->NumFrames > 1) { - VI.num_frames = static_cast((VP->LastTime - VP->FirstTime) * (1 + 1. / (VP->NumFrames - 1)) * FPSNum / FPSDen + 0.5); - if (VI.num_frames < 1) VI.num_frames = 1; - } else { - VI.num_frames = 1; - } - } else { - VI.fps_denominator = VP->FPSDenominator; - VI.fps_numerator = VP->FPSNumerator; - VI.num_frames = VP->NumFrames; - } - } - - // Set AR variables - Env->SetVar(Env->Sprintf("%s%s", this->VarPrefix, "FFSAR_NUM"), VP->SARNum); - Env->SetVar(Env->Sprintf("%s%s", this->VarPrefix, "FFSAR_DEN"), VP->SARDen); - if (VP->SARNum > 0 && VP->SARDen > 0) - Env->SetVar(Env->Sprintf("%s%s", this->VarPrefix, "FFSAR"), VP->SARNum / (double)VP->SARDen); - - // Set crop variables - Env->SetVar(Env->Sprintf("%s%s", this->VarPrefix, "FFCROP_LEFT"), VP->CropLeft); - Env->SetVar(Env->Sprintf("%s%s", this->VarPrefix, "FFCROP_RIGHT"), VP->CropRight); - Env->SetVar(Env->Sprintf("%s%s", this->VarPrefix, "FFCROP_TOP"), VP->CropTop); - Env->SetVar(Env->Sprintf("%s%s", this->VarPrefix, "FFCROP_BOTTOM"), VP->CropBottom); - - Env->SetGlobalVar("FFVAR_PREFIX", this->VarPrefix); - - has_at_least_v8 = true; - try { - Env->CheckVersion(8); - } catch (const AvisynthError &) { - has_at_least_v8 = false; - } -} - -AvisynthVideoSource::~AvisynthVideoSource() { - FFMS_DestroyVideoSource(V); -} - -static int GetSubSamplingH(const VideoInfo &vi) { - if ((vi.IsYUV() || vi.IsYUVA()) && !vi.IsY() && vi.IsPlanar()) - return vi.GetPlaneHeightSubsampling(PLANAR_U); - else - return 0; -} - -static int GetSubSamplingW(const VideoInfo &vi) { - if ((vi.IsYUV() || vi.IsYUVA()) && !vi.IsY() && vi.IsPlanar()) - return vi.GetPlaneWidthSubsampling(PLANAR_U); - else - return 0; -} - -void AvisynthVideoSource::InitOutputFormat( - int ResizeToWidth, int ResizeToHeight, const char *ResizerName, - const char *ConvertToFormatName, IScriptEnvironment *Env) { - - ErrorInfo E; - const FFMS_VideoProperties *VP = FFMS_GetVideoProperties(V); - const FFMS_Frame *F = FFMS_GetFrame(V, 0, &E); - if (!F) - Env->ThrowError("FFVideoSource: %s", E.Buffer); - - std::vector TargetFormats; - if (HighBitDepth) { - TargetFormats.push_back(FFMS_GetPixFmt("yuv420p16")); - TargetFormats.push_back(FFMS_GetPixFmt("yuva420p16")); - TargetFormats.push_back(FFMS_GetPixFmt("yuv422p16")); - TargetFormats.push_back(FFMS_GetPixFmt("yuva422p16")); - TargetFormats.push_back(FFMS_GetPixFmt("yuv444p16")); - TargetFormats.push_back(FFMS_GetPixFmt("yuva444p16")); - TargetFormats.push_back(FFMS_GetPixFmt("yuv420p10")); - TargetFormats.push_back(FFMS_GetPixFmt("yuva420p10")); - TargetFormats.push_back(FFMS_GetPixFmt("yuv422p10")); - TargetFormats.push_back(FFMS_GetPixFmt("yuva422p10")); - TargetFormats.push_back(FFMS_GetPixFmt("yuv444p10")); - TargetFormats.push_back(FFMS_GetPixFmt("yuva444p10")); - TargetFormats.push_back(FFMS_GetPixFmt("gbrpf32")); - TargetFormats.push_back(FFMS_GetPixFmt("gbrapf32")); - TargetFormats.push_back(FFMS_GetPixFmt("gbrp16")); - TargetFormats.push_back(FFMS_GetPixFmt("gbrap16")); - TargetFormats.push_back(FFMS_GetPixFmt("gbrp12")); - TargetFormats.push_back(FFMS_GetPixFmt("gbrap12")); - TargetFormats.push_back(FFMS_GetPixFmt("gbrp10")); - TargetFormats.push_back(FFMS_GetPixFmt("gbrap10")); - TargetFormats.push_back(FFMS_GetPixFmt("gray16")); - TargetFormats.push_back(FFMS_GetPixFmt("gray12")); - TargetFormats.push_back(FFMS_GetPixFmt("gray10")); - TargetFormats.push_back(FFMS_GetPixFmt("yuva420p")); - TargetFormats.push_back(FFMS_GetPixFmt("yuva422p")); - TargetFormats.push_back(FFMS_GetPixFmt("yuva444p")); - } - TargetFormats.push_back(FFMS_GetPixFmt("yuv410p")); - TargetFormats.push_back(FFMS_GetPixFmt("yuv411p")); - TargetFormats.push_back(FFMS_GetPixFmt("yuv420p")); - TargetFormats.push_back(FFMS_GetPixFmt("yuv422p")); - TargetFormats.push_back(FFMS_GetPixFmt("yuv444p")); - TargetFormats.push_back(FFMS_GetPixFmt("gray8")); - TargetFormats.push_back(FFMS_GetPixFmt("yuyv422")); - TargetFormats.push_back(FFMS_GetPixFmt("bgra")); - - // Remove unsupported formats from list so they don't appear as an early termination - TargetFormats.erase(std::remove(TargetFormats.begin(), TargetFormats.end(), -1), TargetFormats.end()); - - TargetFormats.push_back(-1); - - // PIX_FMT_NV21 is misused as a return value different to the defined ones in the function - AVPixelFormat TargetPixelFormat = CSNameToPIXFMT(ConvertToFormatName, AV_PIX_FMT_NV21, HighBitDepth); - if (TargetPixelFormat == AV_PIX_FMT_NONE) - Env->ThrowError("FFVideoSource: Invalid colorspace name specified"); - - if (TargetPixelFormat != AV_PIX_FMT_NV21) { - TargetFormats.clear(); - TargetFormats.push_back(TargetPixelFormat); - TargetFormats.push_back(-1); - } - - if (ResizeToWidth <= 0) - ResizeToWidth = F->EncodedWidth; - - if (ResizeToHeight <= 0) - ResizeToHeight = F->EncodedHeight; - - int Resizer = ResizerNameToSWSResizer(ResizerName); - if (Resizer == 0) - Env->ThrowError("FFVideoSource: Invalid resizer name specified"); - - if (FFMS_SetOutputFormatV2(V, TargetFormats.data(), - ResizeToWidth, ResizeToHeight, Resizer, &E)) - Env->ThrowError("FFVideoSource: No suitable output format found"); - - F = FFMS_GetFrame(V, 0, &E); - TargetFormats.clear(); - TargetFormats.push_back(F->ConvertedPixelFormat); - TargetFormats.push_back(-1); - - // This trick is required to first get the "best" default format and then set only that format as the output - if (FFMS_SetOutputFormatV2(V, TargetFormats.data(), - ResizeToWidth, ResizeToHeight, Resizer, &E)) - Env->ThrowError("FFVideoSource: No suitable output format found"); - - F = FFMS_GetFrame(V, 0, &E); - - if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuvj420p") || F->ConvertedPixelFormat == FFMS_GetPixFmt("yuv420p")) - VI.pixel_type = VideoInfo::CS_I420; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuva420p")) - VI.pixel_type = VideoInfo::CS_YUVA420; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuvj422p") || F->ConvertedPixelFormat == FFMS_GetPixFmt("yuv422p")) - VI.pixel_type = VideoInfo::CS_YV16; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuva422p")) - VI.pixel_type = VideoInfo::CS_YUVA422; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuvj444p") || F->ConvertedPixelFormat == FFMS_GetPixFmt("yuv444p")) - VI.pixel_type = VideoInfo::CS_YV24; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuva444p")) - VI.pixel_type = VideoInfo::CS_YUVA444; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuv411p")) - VI.pixel_type = VideoInfo::CS_YV411; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuv410p")) - VI.pixel_type = VideoInfo::CS_YUV9; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("gray8")) - VI.pixel_type = VideoInfo::CS_Y8; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuyv422")) - VI.pixel_type = VideoInfo::CS_YUY2; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("rgb32")) - VI.pixel_type = VideoInfo::CS_BGR32; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("bgr24")) - VI.pixel_type = VideoInfo::CS_BGR24; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuv420p16")) - VI.pixel_type = VideoInfo::CS_YUV420P16; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuva420p16")) - VI.pixel_type = VideoInfo::CS_YUVA420P16; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuv422p16")) - VI.pixel_type = VideoInfo::CS_YUV422P16; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuva422p16")) - VI.pixel_type = VideoInfo::CS_YUVA422P16; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuv444p16")) - VI.pixel_type = VideoInfo::CS_YUV444P16; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuva444p16")) - VI.pixel_type = VideoInfo::CS_YUVA444P16; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuv420p10")) - VI.pixel_type = VideoInfo::CS_YUV420P10; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuva420p10")) - VI.pixel_type = VideoInfo::CS_YUVA420P10; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuv422p10")) - VI.pixel_type = VideoInfo::CS_YUV422P10; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuva422p10")) - VI.pixel_type = VideoInfo::CS_YUVA422P10; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuv444p10")) - VI.pixel_type = VideoInfo::CS_YUV444P10; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuva444p10")) - VI.pixel_type = VideoInfo::CS_YUVA444P10; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("gbrpf32")) - VI.pixel_type = VideoInfo::CS_RGBPS; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("gbrp16")) - VI.pixel_type = VideoInfo::CS_RGBP16; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("gbrp12")) - VI.pixel_type = VideoInfo::CS_RGBP12; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("gbrp10")) - VI.pixel_type = VideoInfo::CS_RGBP10; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("gbrapf32")) - VI.pixel_type = VideoInfo::CS_RGBAPS; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("gbrap16")) - VI.pixel_type = VideoInfo::CS_RGBAP16; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("gbrap12")) - VI.pixel_type = VideoInfo::CS_RGBAP12; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("gbrap10")) - VI.pixel_type = VideoInfo::CS_RGBAP10; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("gbrp")) - VI.pixel_type = VideoInfo::CS_RGBP; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("gbrap")) - VI.pixel_type = VideoInfo::CS_RGBAP; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("gray16")) - VI.pixel_type = VideoInfo::CS_Y16; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("gray12")) - VI.pixel_type = VideoInfo::CS_Y12; - else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("gray10")) - VI.pixel_type = VideoInfo::CS_Y10; - else - Env->ThrowError("FFVideoSource: No suitable output format found"); - - if (RFFMode > 0 && ResizeToHeight != F->EncodedHeight) - Env->ThrowError("FFVideoSource: Vertical scaling not allowed in RFF mode"); - - if (RFFMode > 0 && TargetPixelFormat != AV_PIX_FMT_NV21) - Env->ThrowError("FFVideoSource: Only the default output colorspace can be used in RFF mode"); - - // set color information variables - Env->SetVar(Env->Sprintf("%s%s", this->VarPrefix, "FFCOLOR_SPACE"), F->ColorSpace); - Env->SetVar(Env->Sprintf("%s%s", this->VarPrefix, "FFCOLOR_RANGE"), F->ColorRange); - - if (VP->TopFieldFirst) - VI.image_type = VideoInfo::IT_TFF; - else - VI.image_type = VideoInfo::IT_BFF; - - VI.width = F->ScaledWidth; - VI.height = F->ScaledHeight; - - // Crop to obey subsampling width/height requirements - VI.width -= VI.width % (1 << GetSubSamplingW(VI)); - VI.height -= VI.height % (1 << (GetSubSamplingH(VI) + (RFFMode > 0 ? 1 : 0))); -} - -static void BlitPlane(const FFMS_Frame *Frame, PVideoFrame &Dst, IScriptEnvironment *Env, int Plane, int PlaneId) { - Env->BitBlt(Dst->GetWritePtr(PlaneId), Dst->GetPitch(PlaneId), - Frame->Data[Plane], Frame->Linesize[Plane], - Dst->GetRowSize(PlaneId), Dst->GetHeight(PlaneId)); -} - -void AvisynthVideoSource::OutputFrame(const FFMS_Frame *Frame, PVideoFrame &Dst, IScriptEnvironment *Env) { - if (VI.IsPlanar()) { - BlitPlane(Frame, Dst, Env, 0, VI.IsRGB() ? PLANAR_G : PLANAR_Y); - if (HighBitDepth ? !VI.IsY() : !VI.IsY8()) { - BlitPlane(Frame, Dst, Env, 1, VI.IsRGB() ? PLANAR_B : PLANAR_U); - BlitPlane(Frame, Dst, Env, 2, VI.IsRGB() ? PLANAR_R : PLANAR_V); - } - if (VI.IsYUVA() || VI.IsPlanarRGBA()) - BlitPlane(Frame, Dst, Env, 3, PLANAR_A); - } else if (VI.IsYUY2()) { - BlitPlane(Frame, Dst, Env, 0, 0); - } else if (VI.IsRGB24() || VI.IsRGB32()) { - Env->BitBlt( - Dst->GetWritePtr() + Dst->GetPitch() * (Dst->GetHeight() - 1), -Dst->GetPitch(), - Frame->Data[0], Frame->Linesize[0], - Dst->GetRowSize(), Dst->GetHeight()); - } else { - assert(false); - } -} - -static void BlitField(const FFMS_Frame *Frame, PVideoFrame &Dst, IScriptEnvironment *Env, int Plane, int PlaneId, int Field) { - Env->BitBlt( - Dst->GetWritePtr(PlaneId) + Dst->GetPitch(PlaneId) * Field, Dst->GetPitch(PlaneId) * 2, - Frame->Data[Plane] + Frame->Linesize[Plane] * Field, Frame->Linesize[Plane] * 2, - Dst->GetRowSize(PlaneId), Dst->GetHeight(PlaneId) / 2); -} - -void AvisynthVideoSource::OutputField(const FFMS_Frame *Frame, PVideoFrame &Dst, int Field, IScriptEnvironment *Env) { - const FFMS_Frame *SrcPicture = Frame; - if (VI.IsPlanar()) { - BlitField(Frame, Dst, Env, 0, VI.IsRGB() ? PLANAR_G : PLANAR_Y, Field); - if (HighBitDepth ? !VI.IsY() : !VI.IsY8()) { - BlitField(Frame, Dst, Env, 1, VI.IsRGB() ? PLANAR_B : PLANAR_U, Field); - BlitField(Frame, Dst, Env, 2, VI.IsRGB() ? PLANAR_R : PLANAR_V, Field); - } - if (VI.IsYUVA() || VI.IsPlanarRGBA()) - BlitField(Frame, Dst, Env, 3, PLANAR_A, Field); - } else if (VI.IsYUY2()) { - BlitField(Frame, Dst, Env, 0, 0, Field); - } else if (VI.IsRGB24() || VI.IsRGB32()) { - Env->BitBlt( - Dst->GetWritePtr() + Dst->GetPitch() * (Dst->GetHeight() - 1 - Field), -Dst->GetPitch() * 2, - SrcPicture->Data[0] + SrcPicture->Linesize[0] * Field, SrcPicture->Linesize[0] * 2, - Dst->GetRowSize(), Dst->GetHeight() / 2); - } else { - assert(false); - } -} - -PVideoFrame AvisynthVideoSource::GetFrame(int n, IScriptEnvironment *Env) { - n = std::min(std::max(n, 0), VI.num_frames - 1); - - PVideoFrame Dst = Env->NewVideoFrame(VI); - AVSMap *props = has_at_least_v8 ? Env->getFramePropsRW(Dst) : nullptr; - - ErrorInfo E; - const FFMS_Frame *Frame; - if (RFFMode > 0) { - Frame = FFMS_GetFrame(V, std::min(FieldList[n].Top, FieldList[n].Bottom), &E); - if (Frame == nullptr) - Env->ThrowError("FFVideoSource: %s", E.Buffer); - if (FieldList[n].Top == FieldList[n].Bottom) { - OutputFrame(Frame, Dst, Env); - } else { - int FirstField = std::min(FieldList[n].Top, FieldList[n].Bottom) == FieldList[n].Bottom; - OutputField(Frame, Dst, FirstField, Env); - Frame = FFMS_GetFrame(V, std::max(FieldList[n].Top, FieldList[n].Bottom), &E); - if (Frame == nullptr) - Env->ThrowError("FFVideoSource: %s", E.Buffer); - OutputField(Frame, Dst, !FirstField, Env); - } - Env->SetVar(Env->Sprintf("%s%s", this->VarPrefix, "FFVFR_TIME"), -1); - Env->SetVar(Env->Sprintf("%s%s", this->VarPrefix, "FFPICT_TYPE"), static_cast('U')); - if (has_at_least_v8) { - Env->propSetInt(props, "_DurationNum", FPSNum, 0); - Env->propSetInt(props, "_DurationDen", FPSDen, 0); - // don't set absolute time since it's ill-defined - } - } else { - if (FPSNum > 0 && FPSDen > 0) { - double currentTime = FFMS_GetVideoProperties(V)->FirstTime + - (double)(n * (int64_t)FPSDen) / FPSNum; - Frame = FFMS_GetFrameByTime(V, currentTime, &E); - Env->SetVar(Env->Sprintf("%s%s", this->VarPrefix, "FFVFR_TIME"), -1); - if (has_at_least_v8) { - Env->propSetInt(props, "_DurationNum", FPSDen, 0); - Env->propSetInt(props, "_DurationDen", FPSNum, 0); - Env->propSetFloat(props, "_AbsoluteTime", currentTime, 0); - } - } else { - Frame = FFMS_GetFrame(V, n, &E); - FFMS_Track *T = FFMS_GetTrackFromVideo(V); - const FFMS_TrackTimeBase *TB = FFMS_GetTimeBase(T); - Env->SetVar(Env->Sprintf("%s%s", this->VarPrefix, "FFVFR_TIME"), static_cast(FFMS_GetFrameInfo(T, n)->PTS * static_cast(TB->Num) / TB->Den)); - if (has_at_least_v8) { - int64_t num; - if (n + 1 < VI.num_frames) - num = FFMS_GetFrameInfo(T, n + 1)->PTS - FFMS_GetFrameInfo(T, n)->PTS; - else if (n > 0) // simply use the second to last frame's duration for the last one, should be good enough - num = FFMS_GetFrameInfo(T, n)->PTS - FFMS_GetFrameInfo(T, n - 1)->PTS; - else // just make it one timebase if it's a single frame clip - num = 1; - int64_t DurNum = TB->Num * num; - int64_t DurDen = TB->Den * 1000; - vsh::muldivRational(&DurNum, &DurDen, 1, 1); - Env->propSetInt(props, "_DurationNum", DurNum, 0); - Env->propSetInt(props, "_DurationDen", DurDen, 0); - Env->propSetFloat(props, "_AbsoluteTime", ((static_cast(TB->Num) / 1000) * FFMS_GetFrameInfo(T, n)->PTS) / TB->Den, 0); - } - } - - if (Frame == nullptr) - Env->ThrowError("FFVideoSource: %s", E.Buffer); - - Env->SetVar(Env->Sprintf("%s%s", this->VarPrefix, "FFPICT_TYPE"), static_cast(Frame->PictType)); - OutputFrame(Frame, Dst, Env); - } - - if (has_at_least_v8) { - const FFMS_VideoProperties *VP = FFMS_GetVideoProperties(V); - if (VP->SARNum > 0 && VP->SARDen > 0) { - Env->propSetInt(props, "_SARNum", VP->SARNum, 0); - Env->propSetInt(props, "_SARDen", VP->SARDen, 0); - } - - Env->propSetInt(props, "_Matrix", Frame->ColorSpace, 0); - Env->propSetInt(props, "_Primaries", Frame->ColorPrimaries, 0); - Env->propSetInt(props, "_Transfer", Frame->TransferCharateristics, 0); - if (Frame->ChromaLocation > 0) - Env->propSetInt(props, "_ChromaLocation", Frame->ChromaLocation - 1, 0); - - if (Frame->ColorRange == FFMS_CR_MPEG) - Env->propSetInt(props, "_ColorRange", 1, 0); - else if (Frame->ColorRange == FFMS_CR_JPEG) - Env->propSetInt(props, "_ColorRange", 0, 0); - if (RFFMode == 0) - Env->propSetData(props, "_PictType", &Frame->PictType, 1, 0); - - // Set field information - int FieldBased = 0; - if (Frame->InterlacedFrame) - FieldBased = (Frame->TopFieldFirst ? 2 : 1); - Env->propSetInt(props, "_FieldBased", FieldBased, 0); - - if (Frame->HasMasteringDisplayPrimaries) { - Env->propSetFloatArray(props, "MasteringDisplayPrimariesX", Frame->MasteringDisplayPrimariesX, 3); - Env->propSetFloatArray(props, "MasteringDisplayPrimariesY", Frame->MasteringDisplayPrimariesY, 3); - Env->propSetFloat(props, "MasteringDisplayWhitePointX", Frame->MasteringDisplayWhitePointX, 0); - Env->propSetFloat(props, "MasteringDisplayWhitePointY", Frame->MasteringDisplayWhitePointY, 0); - } - - if (Frame->HasMasteringDisplayLuminance) { - Env->propSetFloat(props, "MasteringDisplayMinLuminance", Frame->MasteringDisplayMinLuminance, 0); - Env->propSetFloat(props, "MasteringDisplayMaxLuminance", Frame->MasteringDisplayMaxLuminance, 0); - } - - if (Frame->HasContentLightLevel) { - Env->propSetFloat(props, "ContentLightLevelMax", Frame->ContentLightLevelMax, 0); - Env->propSetFloat(props, "ContentLightLevelAverage", Frame->ContentLightLevelAverage, 0); - } - - if (Frame->DolbyVisionRPU && Frame->DolbyVisionRPUSize > 0) { - Env->propSetData(props, "DolbyVisionRPU", reinterpret_cast(Frame->DolbyVisionRPU), Frame->DolbyVisionRPUSize, 0); - } - - if (Frame->HDR10Plus && Frame->HDR10PlusSize > 0) { - Env->propSetData(props, "HDR10Plus", reinterpret_cast(Frame->HDR10Plus), Frame->HDR10PlusSize, 0); - } - } - - return Dst; -} - -bool AvisynthVideoSource::GetParity(int n) { - return VI.image_type == VideoInfo::IT_TFF; -} - -AvisynthAudioSource::AvisynthAudioSource(const char *SourceFile, int Track, FFMS_Index *Index, - int AdjustDelay, int FillGaps, double DrcScale, const char *VarPrefix, IScriptEnvironment* Env) { - VI = {}; - - ErrorInfo E; - A = FFMS_CreateAudioSource2(SourceFile, Track, Index, AdjustDelay, FillGaps, DrcScale, &E); - if (!A) - Env->ThrowError("FFAudioSource: %s", E.Buffer); - - const FFMS_AudioProperties *AP = FFMS_GetAudioProperties(A); - VI.nchannels = AP->Channels; - VI.num_audio_samples = AP->NumSamples; - VI.audio_samples_per_second = AP->SampleRate; - VI.SetChannelMask(true, AP->ChannelLayout); - - Env->SetVar(Env->Sprintf("%s%s", VarPrefix, "FFCHANNEL_LAYOUT"), static_cast(AP->ChannelLayout)); - - Env->SetGlobalVar("FFVAR_PREFIX", VarPrefix); - - switch (AP->SampleFormat) { - case FFMS_FMT_U8: VI.sample_type = SAMPLE_INT8; break; - case FFMS_FMT_S16: VI.sample_type = SAMPLE_INT16; break; - case FFMS_FMT_S32: VI.sample_type = SAMPLE_INT32; break; - case FFMS_FMT_FLT: VI.sample_type = SAMPLE_FLOAT; break; - default: Env->ThrowError("FFAudioSource: Bad audio format"); - } -} - -AvisynthAudioSource::~AvisynthAudioSource() { - FFMS_DestroyAudioSource(A); -} - -void AvisynthAudioSource::GetAudio(void* Buf, int64_t Start, int64_t Count, IScriptEnvironment *Env) { - ErrorInfo E; - if (FFMS_GetAudio(A, Buf, Start, Count, &E)) - Env->ThrowError("FFAudioSource: %s", E.Buffer); -} diff --git a/thirdparty/ffms2/src/avisynth/avssources.h b/thirdparty/ffms2/src/avisynth/avssources.h deleted file mode 100644 index d777cc719..000000000 --- a/thirdparty/ffms2/src/avisynth/avssources.h +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (c) 2007-2017 Fredrik Mellbin -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#ifndef FFAVSSOURCES_H -#define FFAVSSOURCES_H - -#include -#ifdef _WIN32 -#include -#endif -#include -#include "ffms.h" - -struct ErrorInfo : FFMS_ErrorInfo { - char ErrorBuffer[1024]; - ErrorInfo() { - Buffer = ErrorBuffer; - BufferSize = sizeof(ErrorBuffer); - } -}; - -class AvisynthVideoSource : public IClip { - struct FrameFields { - int Top; - int Bottom; - }; - - VideoInfo VI; - bool HighBitDepth; - FFMS_VideoSource *V; - int FPSNum; - int FPSDen; - int RFFMode; - std::vector FieldList; - const char *VarPrefix; - bool has_at_least_v8; - - void InitOutputFormat(int ResizeToWidth, int ResizeToHeight, - const char *ResizerName, const char *ConvertToFormatName, IScriptEnvironment *Env); - void OutputFrame(const FFMS_Frame *Frame, PVideoFrame &Dst, IScriptEnvironment *Env); - void OutputField(const FFMS_Frame *Frame, PVideoFrame &Dst, int Field, IScriptEnvironment *Env); -public: - AvisynthVideoSource(const char *SourceFile, int Track, FFMS_Index *Index, - int FPSNum, int FPSDen, int Threads, int SeekMode, int RFFMode, - int ResizeToWidth, int ResizeToHeight, const char *ResizerName, - const char *ConvertToFormatName, const char *VarPrefix, IScriptEnvironment* Env); - ~AvisynthVideoSource(); - bool __stdcall GetParity(int n); - int __stdcall SetCacheHints(int cachehints, int frame_range) { return 0; } - const VideoInfo& __stdcall GetVideoInfo() { return VI; } - void __stdcall GetAudio(void* Buf, int64_t Start, int64_t Count, IScriptEnvironment *Env) {} - PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment *Env); -}; - -class AvisynthAudioSource : public IClip { - VideoInfo VI; - FFMS_AudioSource *A; -public: - AvisynthAudioSource(const char *SourceFile, int Track, FFMS_Index *Index, - int AdjustDelay, int FillGaps, double DrcScale, const char *VarPrefix, IScriptEnvironment* Env); - ~AvisynthAudioSource(); - bool __stdcall GetParity(int n) { return false; } - int __stdcall SetCacheHints(int cachehints, int frame_range) { return 0; } - const VideoInfo& __stdcall GetVideoInfo() { return VI; } - void __stdcall GetAudio(void* Buf, int64_t Start, int64_t Count, IScriptEnvironment *Env); - PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment *Env) { return nullptr; }; -}; - -#endif diff --git a/thirdparty/ffms2/src/core/audiosource.cpp b/thirdparty/ffms2/src/core/audiosource.cpp deleted file mode 100644 index dbc55cda0..000000000 --- a/thirdparty/ffms2/src/core/audiosource.cpp +++ /dev/null @@ -1,577 +0,0 @@ -// Copyright (c) 2010 Thomas Goyne -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#include "audiosource.h" - -#include "indexing.h" - -#include -#include - -extern "C" { -#include -} - -namespace { -#define MAPPER(m, n) OptionMapper(n, &FFMS_ResampleOptions::m) - OptionMapper resample_options[] = { - MAPPER(ChannelLayout, "out_channel_layout"), - MAPPER(SampleFormat, "out_sample_fmt"), - MAPPER(SampleRate, "out_sample_rate"), - MAPPER(MixingCoefficientType, "mix_coeff_type"), - MAPPER(CenterMixLevel, "center_mix_level"), - MAPPER(SurroundMixLevel, "surround_mix_level"), - MAPPER(LFEMixLevel, "lfe_mix_level"), - MAPPER(Normalize, "normalize_mix_level"), - MAPPER(ForceResample, "force_resampling"), - MAPPER(ResampleFilterSize, "filter_size"), - MAPPER(ResamplePhaseShift, "phase_shift"), - MAPPER(LinearInterpolation, "linear_interp"), - MAPPER(CutoffFrequencyRatio, "cutoff"), - MAPPER(MatrixedStereoEncoding, "matrix_encoding"), - MAPPER(FilterType, "filter_type"), - MAPPER(KaiserBeta, "kaiser_beta"), - MAPPER(DitherMethod, "dither_method") - }; -#undef MAPPER -} - -FFMS_AudioSource::FFMS_AudioSource(const char *SourceFile, FFMS_Index &Index, int Track, int DelayMode, int FillGaps, double DrcScale) - : DrcScale(DrcScale), LastValidTS(AV_NOPTS_VALUE), SourceFile(SourceFile), ResampleContext{ swr_alloc() }, TrackNumber(Track) { - try { - if (FillGaps < -1 || FillGaps > 1) - throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_INVALID_ARGUMENT, - "Invalid gap fill mode"); - - if (Track < 0 || Track >= static_cast(Index.size())) - throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_INVALID_ARGUMENT, - "Out of bounds track index selected"); - - if (Index[Track].TT != FFMS_TYPE_AUDIO) - throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_INVALID_ARGUMENT, - "Not an audio track"); - - if (Index[Track].empty()) - throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_INVALID_ARGUMENT, - "Audio track contains no audio frames"); - - if (!Index.CompareFileSignature(SourceFile)) - throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_FILE_MISMATCH, - "The index does not match the source file"); - - Frames = Index[Track]; - LAVFOpts = Index.LAVFOpts; - - DecodeFrame = av_frame_alloc(); - if (!DecodeFrame) - throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_ALLOCATION_FAILED, - "Couldn't allocate frame"); - OpenFile(); - - if (FillGaps == 1 || (FillGaps == -1 && (!strcmp(FormatContext->iformat->name, "flv")))) - Frames.FillAudioGaps(); - - if (Frames.back().PTS == Frames.front().PTS) - SeekOffset = -1; - else - SeekOffset = 10; - - Init(Index, DelayMode); - } catch (...) { - Free(); - throw; - } -} - - -#define EXCESSIVE_CACHE_SIZE 400 - -void FFMS_AudioSource::Init(const FFMS_Index &Index, int DelayMode) { - // Decode the first packet to ensure all properties are initialized - // Don't cache it since it might be in the wrong format - for (size_t i = 0; i < Frames.size(); i++) { - if (DecodeNextBlock()) - break; - } - - // Read properties of the audio which may not be available until the first - // frame has been decoded - FillAP(AP, CodecContext, Frames); - - if (AP.SampleRate <= 0 || AP.BitsPerSample <= 0) - throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC, - "Codec returned zero size audio"); - - auto opt = CreateResampleOptions(); - SetOutputFormat(*opt); - - if (DelayMode < FFMS_DELAY_NO_SHIFT) - throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_INVALID_ARGUMENT, - "Bad audio delay compensation mode"); - - if (DelayMode == FFMS_DELAY_NO_SHIFT) return; - - if (DelayMode > (signed)Index.size()) - throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_INVALID_ARGUMENT, - "Out of bounds track index selected for audio delay compensation"); - - if (DelayMode >= 0 && Index[DelayMode].TT != FFMS_TYPE_VIDEO) - throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_INVALID_ARGUMENT, - "Audio delay compensation must be relative to a video track"); - - if (DelayMode == FFMS_DELAY_FIRST_VIDEO_TRACK) { - for (size_t i = 0; i < Index.size(); ++i) { - if (Index[i].TT == FFMS_TYPE_VIDEO && !Index[i].empty()) { - DelayMode = static_cast(i); - break; - } - } - } - - if (DelayMode >= 0) { - const FFMS_Track &VTrack = Index[DelayMode]; - Delay = -(VTrack[0].PTS * VTrack.TB.Num * AP.SampleRate / (VTrack.TB.Den * 1000)); - } - - if (Frames.HasTS) { - int i = 0; - while (Frames[i].PTS == AV_NOPTS_VALUE) ++i; - Delay += Frames[i].PTS * Frames.TB.Num * AP.SampleRate / (Frames.TB.Den * 1000); - for (; i > 0; --i) - Delay -= Frames[i].SampleCount; - } - - AP.NumSamples += Delay; -} - -void FFMS_AudioSource::CacheBeginning() { - // Nothing to do if the cache is already populated - if (!Cache.empty()) return; - - // The first packet after a seek is often decoded incorrectly, which - // makes it impossible to ever correctly seek back to the beginning, so - // store the first block now - - // In addition, anything with the same PTS as the first packet can't be - // distinguished from the first packet and so can't be seeked to, so - // store those as well - - // Some of LAVF's splitters don't like to seek to the beginning of the - // file (ts and?), so cache a few blocks even if PTSes are unique - // Packet 7 is the last packet I've had be unseekable to, so cache up to - // 10 for a bit of an extra buffer - auto end = Cache.end(); - while (PacketNumber < Frames.size() && - ((Frames[0].PTS != AV_NOPTS_VALUE && Frames[PacketNumber].PTS == Frames[0].PTS) || - Cache.size() < 10)) { - - // Vorbis in particular seems to like having 60+ packets at the start - // of the file with a PTS of 0, so we might need to expand the search - // range to account for that. - // Expanding slightly before it's strictly needed to ensure there's a - // bit of space for an actual cache - if (Cache.size() >= MaxCacheBlocks - 5) { - if (MaxCacheBlocks >= EXCESSIVE_CACHE_SIZE) - throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_ALLOCATION_FAILED, - "Exceeded the search range for an initial valid audio PTS"); - MaxCacheBlocks *= 2; - } - - DecodeNextBlock(&end); - } - // Store the iterator to the last element of the cache which is used for - // correctness rather than speed, so that when looking for one to delete - // we know how much to skip - CacheNoDelete = Cache.end(); - --CacheNoDelete; -} - -static int PopCount(int64_t v) { - int c = 0; - for (size_t i = 0; i < 64; i++) { - if (v & 1) - c++; - v >>= 1; - } - return c; -} - -void FFMS_AudioSource::SetOutputFormat(FFMS_ResampleOptions const& opt) { - if (opt.SampleRate != AP.SampleRate) - throw FFMS_Exception(FFMS_ERROR_RESAMPLING, FFMS_ERROR_UNSUPPORTED, - "Sample rate changes are currently unsupported."); - - // Cache stores audio in the output format, so clear it and reopen the file - Cache.clear(); - PacketNumber = 0; - OpenFile(); - avcodec_flush_buffers(CodecContext); - - BytesPerSample = av_get_bytes_per_sample(static_cast(opt.SampleFormat)) * PopCount(opt.ChannelLayout); - NeedsResample = - opt.SampleFormat != (int)CodecContext->sample_fmt || - opt.SampleRate != AP.SampleRate || - opt.ChannelLayout != AP.ChannelLayout || - opt.ForceResample; - - if (!NeedsResample) return; - - SwrContext *rawCtx = swr_alloc(); - - AVChannelLayout ChLayoutOut = { AV_CHANNEL_ORDER_NATIVE, PopCount(opt.ChannelLayout), static_cast(opt.ChannelLayout), nullptr }; - AVChannelLayout ChLayoutIn = { AV_CHANNEL_ORDER_NATIVE, PopCount(AP.ChannelLayout), static_cast(AP.ChannelLayout), nullptr }; - swr_alloc_set_opts2(&rawCtx, &ChLayoutOut, (AVSampleFormat)opt.SampleFormat, opt.SampleRate, &ChLayoutIn, CodecContext->sample_fmt, AP.SampleRate, 0, nullptr); - - FFResampleContext newContext{ rawCtx }; - - SetOptions(opt, newContext.get(), resample_options); - - if (swr_init(newContext.get())) - throw FFMS_Exception(FFMS_ERROR_RESAMPLING, FFMS_ERROR_UNKNOWN, - "Could not open avresample context"); - newContext.swap(ResampleContext); -} - -std::unique_ptr FFMS_AudioSource::CreateResampleOptions() const { - auto ret = ReadOptions(ResampleContext.get(), resample_options); - ret->SampleRate = AP.SampleRate; - ret->SampleFormat = static_cast(AP.SampleFormat); - ret->ChannelLayout = AP.ChannelLayout; - return ret; -} - -void FFMS_AudioSource::ResampleAndCache(CacheIterator pos) { - AudioBlock& block = *pos; - - size_t size = DecodeFrame->nb_samples * BytesPerSample; - auto dst = block.Grow(size); - - uint8_t *OutPlanes[1] = { dst }; - - swr_convert(ResampleContext.get(), OutPlanes, DecodeFrame->nb_samples, (const uint8_t **)DecodeFrame->extended_data, DecodeFrame->nb_samples); -} - -FFMS_AudioSource::AudioBlock *FFMS_AudioSource::CacheBlock(CacheIterator &pos) { - // If the previous block has the same Start sample as this one, then - // we got multiple frames of audio out of a single packet and should - // combine them - auto block = pos; - if (pos == Cache.begin() || (--block)->Start != CurrentSample) - block = Cache.emplace(pos, CurrentSample); - - block->Samples += DecodeFrame->nb_samples; - - if (NeedsResample) - ResampleAndCache(block); - else { - const uint8_t *data = DecodeFrame->extended_data[0]; - auto dst = block->Grow(DecodeFrame->nb_samples * BytesPerSample); - memcpy(dst, data, DecodeFrame->nb_samples * BytesPerSample); - } - - if (Cache.size() >= MaxCacheBlocks) { - // Kill the oldest one - auto min = CacheNoDelete; - // Never drop the first one as the first packet decoded after a seek - // is often decoded incorrectly and we can't seek to before the first one - ++min; - for (auto it = min; it != Cache.end(); ++it) - if (it->Age < min->Age) min = it; - if (min == pos) ++pos; - Cache.erase(min); - } - return &*block; -} - -int FFMS_AudioSource::DecodeNextBlock(CacheIterator *pos) { - AVPacket *Packet = av_packet_alloc(); - if (!Packet) - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_ALLOCATION_FAILED, - "Could not allocate packet."); - if (!ReadPacket(Packet)) { - av_packet_free(&Packet); - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_UNKNOWN, - "ReadPacket unexpectedly failed to read a packet"); - } - - CurrentFrame = &Frames[PacketNumber]; - CurrentSample = CurrentFrame->SampleStart; - - // Value code intentionally ignored, combined with the checks when indexing this mostly gives the expected behavior - avcodec_send_packet(CodecContext, Packet); - - int NumberOfSamples = 0; - AudioBlock *CachedBlock = nullptr; - - while (true) { - av_frame_unref(DecodeFrame); - int Ret = avcodec_receive_frame(CodecContext, DecodeFrame); - if (Ret == 0) { - NumberOfSamples += DecodeFrame->nb_samples; - if (DecodeFrame->nb_samples > 0) { - if (pos) - CachedBlock = CacheBlock(*pos); - } - break; - } else if (Ret == AVERROR(EAGAIN)) { - if (!ReadPacket(Packet)) { - av_packet_free(&Packet); - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_UNKNOWN, - "ReadPacket unexpectedly failed to read a packet"); - } - avcodec_send_packet(CodecContext, Packet); - } else if (Ret == AVERROR_EOF) { - break; - } else { - throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_DECODING, "Audio decoding error"); - } - } - - av_packet_free(&Packet); - - // Zero sample packets aren't included in the index - if (!NumberOfSamples) - return NumberOfSamples; - ++PacketNumber; - - // Add padding after the packet, if needed - if (!CachedBlock || CachedBlock->Samples == CurrentFrame->SampleCount) - return NumberOfSamples; - - const int64_t MissingSamples = static_cast(CurrentFrame->SampleCount - CachedBlock->Samples); - // This can apparently happen in some rare circumstances, caused by inaccurate seeking? - if (MissingSamples <= 0) - return NumberOfSamples; - CachedBlock->Samples += MissingSamples; - const int64_t MissingBytes = MissingSamples * BytesPerSample; - if (MissingSamples > 200 || MissingSamples > CachedBlock->Samples - MissingSamples) - memset(CachedBlock->Grow(MissingBytes), 0, MissingBytes); - else { - auto ptr = CachedBlock->Grow(MissingBytes); - memcpy(ptr, ptr - MissingBytes, MissingBytes); - } - return NumberOfSamples; -} - -static bool SampleStartComp(const FrameInfo &a, const FrameInfo &b) { - return a.SampleStart < b.SampleStart; -} - -void FFMS_AudioSource::GetAudio(void *Buf, int64_t Start, int64_t Count) { - if (Start < 0 || Start + Count > AP.NumSamples || Count < 0) - throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_INVALID_ARGUMENT, - "Out of bounds audio samples requested"); - - CacheBeginning(); - - uint8_t *Dst = static_cast(Buf); - - // Apply audio delay (if any) and fill any samples before the start time with zero - Start -= Delay; - if (Start < 0) { - size_t Bytes = static_cast(BytesPerSample * FFMIN(-Start, Count)); - memset(Dst, 0, Bytes); - - Count += Start; - // Entire request was before the start of the audio - if (Count <= 0) return; - - Start = 0; - Dst += Bytes; - } - - auto it = Cache.begin(); - - while (Count > 0) { - // Find first useful cache block - while (it != Cache.end() && it->Start + it->Samples <= Start) ++it; - - // Cache has the next block we want - if (it != Cache.end() && it->Start <= Start) { - int64_t SrcOffset = FFMAX(0, Start - it->Start); - int64_t DstOffset = FFMAX(0, it->Start - Start); - int64_t CopySamples = FFMIN(it->Samples - SrcOffset, Count - DstOffset); - size_t Bytes = static_cast(CopySamples * BytesPerSample); - - memcpy(Dst + DstOffset * BytesPerSample, it->Data.get() + SrcOffset * BytesPerSample, Bytes); - Start += CopySamples; - Count -= CopySamples; - Dst += Bytes; - ++it; - } - // Decode another block - else { - if (Start < CurrentSample && SeekOffset == -1) - throw FFMS_Exception(FFMS_ERROR_SEEKING, FFMS_ERROR_CODEC, "Audio stream is not seekable"); - - if (SeekOffset >= 0 && (Start < CurrentSample || Start > CurrentSample + DecodeFrame->nb_samples * 5)) { - FrameInfo f; - f.SampleStart = Start; - size_t NewPacketNumber = std::distance( - Frames.begin(), - std::lower_bound(Frames.begin(), Frames.end(), f, SampleStartComp)); - NewPacketNumber = NewPacketNumber > static_cast(SeekOffset + 15) - ? NewPacketNumber - SeekOffset - 15 - : 0; - while (NewPacketNumber > 0 && !Frames[NewPacketNumber].KeyFrame) --NewPacketNumber; - - // Only seek forward if it'll actually result in moving forward - if (Start < CurrentSample || static_cast(NewPacketNumber) > PacketNumber) { - PacketNumber = NewPacketNumber; - CurrentSample = -1; - av_frame_unref(DecodeFrame); - avcodec_flush_buffers(CodecContext); - Seek(); - } - } - - // Decode until we hit the block we want - if (PacketNumber >= Frames.size()) - throw FFMS_Exception(FFMS_ERROR_SEEKING, FFMS_ERROR_CODEC, "Seeking is severely broken"); - while (CurrentSample + CurrentFrame->SampleCount <= Start && PacketNumber < Frames.size()) - DecodeNextBlock(&it); - if (CurrentSample > Start) - throw FFMS_Exception(FFMS_ERROR_SEEKING, FFMS_ERROR_CODEC, "Seeking is severely broken"); - - // The block we want is now in the cache immediately before it - --it; - } - } -} - -size_t FFMS_AudioSource::GetSeekablePacketNumber(FFMS_Track const& Frames, size_t PacketNumber) { - // Packets don't always have unique PTSes, so we may not be able to - // uniquely identify the packet we want. This function attempts to find - // a PTS we can seek to which will let us figure out which packet we're - // on before we get to the packet we actually wanted - - // MatroskaAudioSource doesn't need this, as it seeks by byte offset - // rather than PTS. LAVF theoretically can seek by byte offset, but we - // don't use it as not all demuxers support it and it's broken in some of - // those that claim to support it - - // However much we might wish to, we can't seek to before packet zero - if (PacketNumber == 0) return PacketNumber; - - // Desired packet's PTS is unique, so don't do anything - if (Frames[PacketNumber].PTS != Frames[PacketNumber - 1].PTS && - (PacketNumber + 1 == Frames.size() || Frames[PacketNumber].PTS != Frames[PacketNumber + 1].PTS)) - return PacketNumber; - - // When decoding, we only reliably know what packet we're at when the - // newly parsed packet has a different PTS from the previous one. As such, - // we walk backwards until we hit a different PTS and then seek to there, - // so that we can then decode until we hit the PTS group we actually wanted - // (and thereby know that we're at the first packet in the group rather - // than whatever the splitter happened to choose) - - // This doesn't work if our desired packet has the same PTS as the first - // packet, but this scenario should never come up anyway; we permanently - // cache the decoded results from those packets, so there's no need to ever - // seek to them - int64_t PTS = Frames[PacketNumber].PTS; - while (PacketNumber > 0 && PTS == Frames[PacketNumber].PTS) - --PacketNumber; - return PacketNumber; -} - -void FFMS_AudioSource::OpenFile() { - avcodec_free_context(&CodecContext); - avformat_close_input(&FormatContext); - - LAVFOpenFile(SourceFile.c_str(), FormatContext, TrackNumber, LAVFOpts); - - auto *Codec = avcodec_find_decoder(FormatContext->streams[TrackNumber]->codecpar->codec_id); - if (Codec == nullptr) - throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC, - "Audio codec not found"); - - CodecContext = avcodec_alloc_context3(Codec); - if (CodecContext == nullptr) - throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_ALLOCATION_FAILED, - "Could not allocate audio decoding context"); - - if (avcodec_parameters_to_context(CodecContext, FormatContext->streams[TrackNumber]->codecpar) < 0) - throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC, - "Could not copy audio codec parameters"); - - AVDictionary *CodecDict = nullptr; - if (Codec->id == AV_CODEC_ID_AC3 || Codec->id == AV_CODEC_ID_EAC3) - av_dict_set(&CodecDict, "drc_scale", std::to_string(DrcScale).c_str(), 0); - - if (avcodec_open2(CodecContext, Codec, &CodecDict) < 0) - throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC, - "Could not open audio codec"); - - av_dict_free(&CodecDict); -} - -void FFMS_AudioSource::Free() { - av_frame_free(&DecodeFrame); - avcodec_free_context(&CodecContext); - avformat_close_input(&FormatContext); -} - -FFMS_AudioSource::~FFMS_AudioSource() { - Free(); -} - -int64_t FFMS_AudioSource::FrameTS(size_t Packet) const { - return Frames.HasTS ? Frames[Packet].PTS : Frames[Packet].FilePos; -} - -void FFMS_AudioSource::Seek() { - size_t TargetPacket = GetSeekablePacketNumber(Frames, PacketNumber); - LastValidTS = AV_NOPTS_VALUE; - - int Flags = Frames.HasTS ? AVSEEK_FLAG_BACKWARD : AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_BYTE; - - if (av_seek_frame(FormatContext, TrackNumber, FrameTS(TargetPacket), Flags) < 0) - av_seek_frame(FormatContext, TrackNumber, FrameTS(TargetPacket), Flags | AVSEEK_FLAG_ANY); - - if (TargetPacket != PacketNumber) { - // Decode until the PTS changes so we know where we are - int64_t LastPTS = FrameTS(PacketNumber); - while (LastPTS == FrameTS(PacketNumber)) DecodeNextBlock(); - } -} - -bool FFMS_AudioSource::ReadPacket(AVPacket *Packet) { - while (av_read_frame(FormatContext, Packet) >= 0) { - if (Packet->stream_index == TrackNumber) { - // Required because not all audio packets, especially in ogg, have a pts. Use the previous valid packet's pts instead. - if (Packet->pts == AV_NOPTS_VALUE) - Packet->pts = LastValidTS; - else - LastValidTS = Packet->pts; - - // This only happens if a really shitty demuxer seeks to a packet without pts *hrm* ogg *hrm* so read until a valid pts is reached - int64_t PacketTS = Frames.HasTS ? Packet->pts : Packet->pos; - if (PacketTS != AV_NOPTS_VALUE) { - while (PacketNumber > 0 && FrameTS(PacketNumber) > PacketTS) --PacketNumber; - while (FrameTS(PacketNumber) < PacketTS) ++PacketNumber; - return true; - } - } - av_packet_unref(Packet); - } - return false; -} - diff --git a/thirdparty/ffms2/src/core/audiosource.h b/thirdparty/ffms2/src/core/audiosource.h deleted file mode 100644 index a8efc474b..000000000 --- a/thirdparty/ffms2/src/core/audiosource.h +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright (c) 2007-2011 Fredrik Mellbin -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#ifndef FFAUDIOSOURCE_H -#define FFAUDIOSOURCE_H - -#include "utils.h" -#include "track.h" - -#include -#include -#include - -struct FFMS_AudioSource { - struct AudioBlock { - struct Free { - void operator()(uint8_t *ptr) const { - free(ptr); - } - }; - - int64_t Age; - int64_t Start; - int64_t Samples = 0; - size_t DataSize = 0; - std::unique_ptr Data; - - AudioBlock(int64_t Start) - : Start(Start) { - static std::atomic Now{ 0 }; - Age = Now++; - } - - uint8_t *Grow(size_t size) { - auto ptr = static_cast(realloc(Data.get(), DataSize + size)); - if (!ptr) - throw std::bad_alloc(); - Data.release(); - Data.reset(ptr); - ptr += DataSize; - DataSize += size; - return ptr; - } - }; - typedef std::list::iterator CacheIterator; - - AVFormatContext *FormatContext = nullptr; - std::map LAVFOpts; - double DrcScale; - int64_t LastValidTS; - std::string SourceFile; - - // delay in samples to apply to the audio - int64_t Delay = 0; - // cache of decoded audio blocks - std::list Cache; - // max size of the cache in blocks - size_t MaxCacheBlocks = 50; - // pointer to last element of the cache which should never be deleted - CacheIterator CacheNoDelete; - // bytes per sample * number of channels, *after* resampling if applicable - size_t BytesPerSample = 0; - - bool NeedsResample = false; - - struct SwrFreeWrapper { - void operator()(SwrContext *c) const { - swr_free(&c); - } - }; - - typedef std::unique_ptr FFResampleContext; - FFResampleContext ResampleContext; - - // Insert the current audio frame into the cache - AudioBlock *CacheBlock(CacheIterator &pos); - - // Interleave the current audio frame and insert it into the cache - void ResampleAndCache(CacheIterator pos); - - // Cache the unseekable beginning of the file once the output format is set - void CacheBeginning(); - - // Called after seeking - void Seek(); - // Read the next packet from the file - bool ReadPacket(AVPacket *); - - // Close and reopen the source file to seek back to the beginning. Only - // needs to do anything for formats that can't seek to the beginning otherwise. - // - // If the file is not already open, it is merely just opened. - void OpenFile(); - - // First sample which is stored in the decoding buffer - int64_t CurrentSample = -1; - // Next packet to be read - size_t PacketNumber = 0; - // Current audio frame - const FrameInfo *CurrentFrame = nullptr; - // Track which this corresponds to - int TrackNumber; - // Number of packets which the demuxer requires to know where it is - // If -1, seeking is assumed to be impossible - int SeekOffset = 0; - - // Buffer which audio is decoded into - AVFrame *DecodeFrame = nullptr; - FFMS_Track Frames; - AVCodecContext *CodecContext = nullptr; - FFMS_AudioProperties AP = {}; - - int DecodeNextBlock(CacheIterator *cachePos = 0); - // Initialization which has to be done after the codec is opened - void Init(const FFMS_Index &Index, int DelayMode); - - int64_t FrameTS(size_t Packet) const; - - void Free(); -public: - FFMS_AudioSource(const char *SourceFile, FFMS_Index &Index, int Track, int DelayMode, int FillGaps, double DrcScale); - ~FFMS_AudioSource(); - FFMS_Track *GetTrack() { return &Frames; } - const FFMS_AudioProperties& GetAudioProperties() const { return AP; } - void GetAudio(void *Buf, int64_t Start, int64_t Count); - - std::unique_ptr CreateResampleOptions() const; - void SetOutputFormat(FFMS_ResampleOptions const& opt); - - static size_t GetSeekablePacketNumber(FFMS_Track const& Frames, size_t PacketNumber); -}; - -#endif diff --git a/thirdparty/ffms2/src/core/ffms.cpp b/thirdparty/ffms2/src/core/ffms.cpp deleted file mode 100644 index 7572af120..000000000 --- a/thirdparty/ffms2/src/core/ffms.cpp +++ /dev/null @@ -1,425 +0,0 @@ -// Copyright (c) 2007-2017 Fredrik Mellbin -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#include "ffms.h" - -#include "audiosource.h" -#include "indexing.h" -#include "videosource.h" -#include "videoutils.h" - -extern "C" { -#include -#include -} - -#include -#include -#include - -#ifdef FFMS_WIN_DEBUG -# include -#endif - -static std::once_flag FFmpegOnce; - -#ifdef FFMS_WIN_DEBUG - -static void av_log_windebug_callback(void* ptr, int level, const char* fmt, va_list vl) { - if (level > av_log_get_level()) - return; - - static int print_prefix = 1; - static int count; - static char line[1024] = {}, prev[1024] = {}; - auto avc = ptr ? *static_cast(ptr) : nullptr; - - int written = 0; - if (print_prefix && avc) { - written = snprintf(line, sizeof(line), "[%s @ %p]", avc->item_name(ptr), ptr); - } - - written += vsnprintf(line + written, sizeof(line) - written, fmt, vl); - - print_prefix = line[written - 1] == '\n'; - line[sizeof(line) - 1] = 0; - if (print_prefix && !strcmp(line, prev)) { - count++; - return; - } - if (count > 0) { - std::stringstream ss; - ss << " Last message repeated " << count << " times\n"; - OutputDebugStringA(ss.str().c_str()); - count = 0; - } - OutputDebugStringA(line); - strcpy(prev, line); -} - -#endif - -FFMS_API(void) FFMS_Init(int, int) { - std::call_once(FFmpegOnce, []() { -#ifdef FFMS_WIN_DEBUG - av_log_set_callback(av_log_windebug_callback); - av_log_set_level(AV_LOG_INFO); -#else - av_log_set_level(AV_LOG_QUIET); -#endif - }); -} - -FFMS_API(void) FFMS_Deinit() { - -} - -FFMS_API(int) FFMS_GetVersion() { - return FFMS_VERSION; -} - -FFMS_API(int) FFMS_GetLogLevel() { - return av_log_get_level(); -} - -FFMS_API(void) FFMS_SetLogLevel(int Level) { - av_log_set_level(Level); -} - -FFMS_API(FFMS_VideoSource *) FFMS_CreateVideoSource(const char *SourceFile, int Track, FFMS_Index *Index, int Threads, int SeekMode, FFMS_ErrorInfo *ErrorInfo) { - try { - return new FFMS_VideoSource(SourceFile, *Index, Track, Threads, SeekMode); - } catch (FFMS_Exception &e) { - e.CopyOut(ErrorInfo); - return nullptr; - } -} - -FFMS_API(FFMS_AudioSource *) FFMS_CreateAudioSource(const char *SourceFile, int Track, FFMS_Index *Index, int DelayMode, FFMS_ErrorInfo *ErrorInfo) { - return FFMS_CreateAudioSource2(SourceFile, Track, Index, DelayMode, -1, 0, ErrorInfo); -} - -FFMS_API(FFMS_AudioSource *) FFMS_CreateAudioSource2(const char *SourceFile, int Track, FFMS_Index *Index, int DelayMode, int FillGaps, double DrcScale, FFMS_ErrorInfo *ErrorInfo) { - try { - return new FFMS_AudioSource(SourceFile, *Index, Track, DelayMode, FillGaps, DrcScale); - } catch (FFMS_Exception &e) { - e.CopyOut(ErrorInfo); - return nullptr; - } -} - -FFMS_API(void) FFMS_DestroyVideoSource(FFMS_VideoSource *V) { - delete V; -} - -FFMS_API(void) FFMS_DestroyAudioSource(FFMS_AudioSource *A) { - delete A; -} - -FFMS_API(const FFMS_VideoProperties *) FFMS_GetVideoProperties(FFMS_VideoSource *V) { - return &V->GetVideoProperties(); -} - -FFMS_API(const FFMS_AudioProperties *) FFMS_GetAudioProperties(FFMS_AudioSource *A) { - return &A->GetAudioProperties(); -} - -FFMS_API(const FFMS_Frame *) FFMS_GetFrame(FFMS_VideoSource *V, int n, FFMS_ErrorInfo *ErrorInfo) { - ClearErrorInfo(ErrorInfo); - try { - return V->GetFrame(n); - } catch (FFMS_Exception &e) { - e.CopyOut(ErrorInfo); - return nullptr; - } -} - -FFMS_API(const FFMS_Frame *) FFMS_GetFrameByTime(FFMS_VideoSource *V, double Time, FFMS_ErrorInfo *ErrorInfo) { - ClearErrorInfo(ErrorInfo); - try { - return V->GetFrameByTime(Time); - } catch (FFMS_Exception &e) { - e.CopyOut(ErrorInfo); - return nullptr; - } -} - -FFMS_API(int) FFMS_GetAudio(FFMS_AudioSource *A, void *Buf, int64_t Start, int64_t Count, FFMS_ErrorInfo *ErrorInfo) { - ClearErrorInfo(ErrorInfo); - try { - A->GetAudio(Buf, Start, Count); - } catch (FFMS_Exception &e) { - return e.CopyOut(ErrorInfo); - } - return FFMS_ERROR_SUCCESS; -} - -FFMS_API(int) FFMS_SetOutputFormatV2(FFMS_VideoSource *V, const int *TargetFormats, int Width, int Height, int Resizer, FFMS_ErrorInfo *ErrorInfo) { - ClearErrorInfo(ErrorInfo); - try { - V->SetOutputFormat(reinterpret_cast(TargetFormats), Width, Height, Resizer); - } catch (FFMS_Exception &e) { - return e.CopyOut(ErrorInfo); - } - return FFMS_ERROR_SUCCESS; -} - -FFMS_API(void) FFMS_ResetOutputFormatV(FFMS_VideoSource *V) { - V->ResetOutputFormat(); -} - -FFMS_API(int) FFMS_SetInputFormatV(FFMS_VideoSource *V, int ColorSpace, int ColorRange, int Format, FFMS_ErrorInfo *ErrorInfo) { - ClearErrorInfo(ErrorInfo); - try { - V->SetInputFormat(ColorSpace, ColorRange, static_cast(Format)); - } catch (FFMS_Exception &e) { - return e.CopyOut(ErrorInfo); - } - return FFMS_ERROR_SUCCESS; -} - -FFMS_API(void) FFMS_ResetInputFormatV(FFMS_VideoSource *V) { - V->ResetInputFormat(); -} - -FFMS_API(FFMS_ResampleOptions *) FFMS_CreateResampleOptions(FFMS_AudioSource *A) { - return A->CreateResampleOptions().release(); -} - -FFMS_API(void) FFMS_DestroyResampleOptions(FFMS_ResampleOptions *options) { - delete options; -} - -FFMS_API(int) FFMS_SetOutputFormatA(FFMS_AudioSource *A, const FFMS_ResampleOptions *options, FFMS_ErrorInfo *ErrorInfo) { - ClearErrorInfo(ErrorInfo); - try { - A->SetOutputFormat(*options); - } catch (FFMS_Exception &e) { - return e.CopyOut(ErrorInfo); - } - return FFMS_ERROR_SUCCESS; -} - -FFMS_API(void) FFMS_DestroyIndex(FFMS_Index *Index) { - delete Index; -} - -FFMS_API(FFMS_IndexErrorHandling) FFMS_GetErrorHandling(FFMS_Index *Index) { - return static_cast(Index->ErrorHandling); -} - -FFMS_API(int) FFMS_GetFirstTrackOfType(FFMS_Index *Index, int TrackType, FFMS_ErrorInfo *ErrorInfo) { - ClearErrorInfo(ErrorInfo); - for (int i = 0; i < static_cast(Index->size()); i++) - if ((*Index)[i].TT == TrackType) - return i; - - try { - throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_NOT_AVAILABLE, - "No suitable, indexed track found"); - } catch (FFMS_Exception &e) { - e.CopyOut(ErrorInfo); - return -1; - } -} - -FFMS_API(int) FFMS_GetFirstIndexedTrackOfType(FFMS_Index *Index, int TrackType, FFMS_ErrorInfo *ErrorInfo) { - ClearErrorInfo(ErrorInfo); - for (int i = 0; i < static_cast(Index->size()); i++) - if ((*Index)[i].TT == TrackType && !(*Index)[i].empty()) - return i; - try { - throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_NOT_AVAILABLE, - "No suitable, indexed track found"); - } catch (FFMS_Exception &e) { - e.CopyOut(ErrorInfo); - return -1; - } -} - -FFMS_API(int) FFMS_GetNumTracks(FFMS_Index *Index) { - return static_cast(Index->size()); -} - -FFMS_API(int) FFMS_GetNumTracksI(FFMS_Indexer *Indexer) { - return Indexer->GetNumberOfTracks(); -} - -FFMS_API(int) FFMS_GetTrackType(FFMS_Track *T) { - return T->TT; -} - -FFMS_API(int) FFMS_GetTrackTypeI(FFMS_Indexer *Indexer, int Track) { - return Indexer->GetTrackType(Track); -} - -FFMS_API(const char *) FFMS_GetCodecNameI(FFMS_Indexer *Indexer, int Track) { - return Indexer->GetTrackCodec(Track); -} - -FFMS_API(int) FFMS_GetNumFrames(FFMS_Track *T) { - return T->VisibleFrameCount(); -} - -FFMS_API(const FFMS_FrameInfo *) FFMS_GetFrameInfo(FFMS_Track *T, int Frame) { - return T->GetFrameInfo(static_cast(Frame)); -} - -FFMS_API(FFMS_Track *) FFMS_GetTrackFromIndex(FFMS_Index *Index, int Track) { - return &(*Index)[Track]; -} - -FFMS_API(FFMS_Track *) FFMS_GetTrackFromVideo(FFMS_VideoSource *V) { - return V->GetTrack(); -} - -FFMS_API(FFMS_Track *) FFMS_GetTrackFromAudio(FFMS_AudioSource *A) { - return A->GetTrack(); -} - -FFMS_API(const FFMS_TrackTimeBase *) FFMS_GetTimeBase(FFMS_Track *T) { - return &T->TB; -} - -FFMS_API(int) FFMS_WriteTimecodes(FFMS_Track *T, const char *TimecodeFile, FFMS_ErrorInfo *ErrorInfo) { - ClearErrorInfo(ErrorInfo); - try { - T->WriteTimecodes(TimecodeFile); - } catch (FFMS_Exception &e) { - return e.CopyOut(ErrorInfo); - } - return FFMS_ERROR_SUCCESS; -} - -FFMS_API(FFMS_Indexer *) FFMS_CreateIndexer(const char *SourceFile, FFMS_ErrorInfo *ErrorInfo) { - return FFMS_CreateIndexer2(SourceFile, nullptr, 0, ErrorInfo); -} - -FFMS_API(FFMS_Indexer *) FFMS_CreateIndexer2(const char *SourceFile, const FFMS_KeyValuePair *DemuxerOptions, int NumOptions, FFMS_ErrorInfo *ErrorInfo) { - ClearErrorInfo(ErrorInfo); - try { - return new FFMS_Indexer(SourceFile, DemuxerOptions, NumOptions); - } catch (FFMS_Exception &e) { - e.CopyOut(ErrorInfo); - return nullptr; - } -} - -FFMS_API(FFMS_Index *) FFMS_DoIndexing2(FFMS_Indexer *Indexer, int ErrorHandling, FFMS_ErrorInfo *ErrorInfo) { - ClearErrorInfo(ErrorInfo); - - Indexer->SetErrorHandling(ErrorHandling); - - FFMS_Index *Index = nullptr; - try { - Index = Indexer->DoIndexing(); - } catch (FFMS_Exception &e) { - e.CopyOut(ErrorInfo); - } - delete Indexer; - return Index; -} - -FFMS_API(void) FFMS_TrackIndexSettings(FFMS_Indexer *Indexer, int Track, int Index, int) { - Indexer->SetIndexTrack(Track, !!Index); -} - -FFMS_API(void) FFMS_TrackTypeIndexSettings(FFMS_Indexer *Indexer, int TrackType, int Index, int) { - Indexer->SetIndexTrackType(TrackType, !!Index); -} - -FFMS_API(void) FFMS_SetProgressCallback(FFMS_Indexer *Indexer, TIndexCallback IC, void *ICPrivate) { - Indexer->SetProgressCallback(IC, ICPrivate); -} - -FFMS_API(void) FFMS_CancelIndexing(FFMS_Indexer *Indexer) { - delete Indexer; -} - -FFMS_API(FFMS_Index *) FFMS_ReadIndex(const char *IndexFile, FFMS_ErrorInfo *ErrorInfo) { - ClearErrorInfo(ErrorInfo); - try { - return new FFMS_Index(IndexFile); - } catch (FFMS_Exception &e) { - e.CopyOut(ErrorInfo); - return nullptr; - } -} - -FFMS_API(FFMS_Index *) FFMS_ReadIndexFromBuffer(const uint8_t *Buffer, size_t Size, FFMS_ErrorInfo *ErrorInfo) { - ClearErrorInfo(ErrorInfo); - try { - return new FFMS_Index(Buffer, Size); - } catch (FFMS_Exception &e) { - e.CopyOut(ErrorInfo); - return nullptr; - } -} - -FFMS_API(int) FFMS_IndexBelongsToFile(FFMS_Index *Index, const char *SourceFile, FFMS_ErrorInfo *ErrorInfo) { - ClearErrorInfo(ErrorInfo); - try { - if (!Index->CompareFileSignature(SourceFile)) - throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_FILE_MISMATCH, - "The index does not belong to the file"); - } catch (FFMS_Exception &e) { - return e.CopyOut(ErrorInfo); - } - return FFMS_ERROR_SUCCESS; -} - -FFMS_API(int) FFMS_WriteIndex(const char *IndexFile, FFMS_Index *Index, FFMS_ErrorInfo *ErrorInfo) { - ClearErrorInfo(ErrorInfo); - try { - Index->WriteIndexFile(IndexFile); - } catch (FFMS_Exception &e) { - return e.CopyOut(ErrorInfo); - } - return FFMS_ERROR_SUCCESS; -} - -FFMS_API(int) FFMS_WriteIndexToBuffer(uint8_t **BufferPtr, size_t *Size, FFMS_Index *Index, FFMS_ErrorInfo *ErrorInfo) { - ClearErrorInfo(ErrorInfo); - uint8_t *buf; - - try { - buf = Index->WriteIndexBuffer(Size); - } catch (FFMS_Exception &e) { - *Size = 0; - *BufferPtr = nullptr; - return e.CopyOut(ErrorInfo); - } - - *BufferPtr = buf; - - return FFMS_ERROR_SUCCESS; -} - -FFMS_API(void) FFMS_FreeIndexBuffer(uint8_t **BufferPtr) { - av_freep(BufferPtr); -} - -FFMS_API(int) FFMS_GetPixFmt(const char *Name) { - return av_get_pix_fmt(Name); -} - -FFMS_API(const char *) FFMS_GetFormatNameI(FFMS_Indexer *Indexer) { - return Indexer->GetFormatName(); -} diff --git a/thirdparty/ffms2/src/core/filehandle.cpp b/thirdparty/ffms2/src/core/filehandle.cpp deleted file mode 100644 index 111af55eb..000000000 --- a/thirdparty/ffms2/src/core/filehandle.cpp +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (c) 2014 Thomas Goyne -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#include "filehandle.h" - -#include "utils.h" - -#include - -extern "C" { -#include -} - -static AVIOContext *ffms_fopen(const char *filename, const char *mode) { - int flags = 0; - if (strchr(mode, 'r')) - flags |= AVIO_FLAG_READ; - if (strchr(mode, 'w')) - flags |= AVIO_FLAG_WRITE; - - AVIOContext *ctx; - int ret = avio_open2(&ctx, filename, flags, nullptr, nullptr); - if (ret < 0) - return nullptr; - return ctx; -} - -FileHandle::FileHandle(const char *filename, const char *mode, int error_source, int error_cause) - : avio(ffms_fopen(filename, mode)) - , filename(filename) - , error_source(error_source) - , error_cause(error_cause) { - if (!avio) - throw FFMS_Exception(error_source, FFMS_ERROR_NO_FILE, - "Failed to open '" + this->filename + "'"); -} - -FileHandle::~FileHandle() { - avio_close(avio); -} - -void FileHandle::Seek(int64_t offset, int origin) { - int64_t ret = avio_seek(avio, offset, origin); - if (ret < 0) - throw FFMS_Exception(error_source, error_cause, - "Failed to seek in '" + filename + "'"); -} - -int64_t FileHandle::Tell() { - int64_t ret = avio_tell(avio); - if (ret < 0) - throw FFMS_Exception(error_source, error_cause, - "Failed to read position in '" + filename + "'"); - return ret; -} - -size_t FileHandle::Read(char *buffer, size_t size) { - int count = avio_read(avio, (unsigned char *)buffer, size); - if (count < 0) - throw FFMS_Exception(error_source, FFMS_ERROR_FILE_READ, - "Failed to read from '" + filename + "'"); - return (size_t)count; -} - -size_t FileHandle::Write(const char *buffer, size_t size) { - avio_write(avio, (const unsigned char *)buffer, size); - avio_flush(avio); - if (avio->error < 0) - throw FFMS_Exception(error_source, FFMS_ERROR_FILE_WRITE, - "Failed to write to '" + filename + "'"); - return size; -} - -int64_t FileHandle::Size() { - int64_t size = avio_size(avio); - if (size < 0) - throw FFMS_Exception(error_source, FFMS_ERROR_FILE_READ, - "Failed to get file size for '" + filename + "'"); - return size; -} - -int FileHandle::Printf(const char *fmt, ...) { - va_list args; - va_start(args, fmt); - - std::vector OutBuffer(100); - int ret = -1; - while (OutBuffer.size() < 1024 * 1024) { - ret = vsnprintf(OutBuffer.data(), OutBuffer.size(), fmt, args); - if (ret > 0 && ret < (int)OutBuffer.size()) - break; - OutBuffer.resize(OutBuffer.size() * 2); - } - - va_end(args); - - avio_write(avio, reinterpret_cast(OutBuffer.data()), ret); - avio_flush(avio); - - return avio->error < 0 ? avio->error : ret; -} diff --git a/thirdparty/ffms2/src/core/filehandle.h b/thirdparty/ffms2/src/core/filehandle.h deleted file mode 100644 index eadad7e80..000000000 --- a/thirdparty/ffms2/src/core/filehandle.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2014 Thomas Goyne -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#pragma once - -#include -#include - -struct AVIOContext; - -class FileHandle { - AVIOContext *avio; - std::string filename; - int error_source; - int error_cause; - -public: - FileHandle(const char *filename, const char *mode, int error_source, int error_cause); - FileHandle() : avio(nullptr) {} - ~FileHandle(); - - void Seek(int64_t offset, int origin); - int64_t Tell(); - int64_t Size(); - - size_t Read(char *buffer, size_t size); - size_t Write(const char *buffer, size_t size); - int Printf(const char *fmt, ...) -#ifdef __GNUC__ - __attribute__((format(printf, 2, 3))) -#endif - ; -}; diff --git a/thirdparty/ffms2/src/core/indexing.cpp b/thirdparty/ffms2/src/core/indexing.cpp deleted file mode 100644 index 8c55a5790..000000000 --- a/thirdparty/ffms2/src/core/indexing.cpp +++ /dev/null @@ -1,603 +0,0 @@ -// Copyright (c) 2007-2017 Fredrik Mellbin -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#include "indexing.h" - -#include "track.h" -#include "videoutils.h" -#include "zipfile.h" - -#include -#include -#include -#include - -extern "C" { -#include -#include -} - -#define INDEXID 0x53920873 -#define INDEX_VERSION 7 - -SharedAVContext::~SharedAVContext() { - avcodec_free_context(&CodecContext); - if (Parser) - av_parser_close(Parser); -} - -void FFMS_Index::CalculateFileSignature(const char *Filename, int64_t *Filesize, uint8_t Digest[20]) { - FileHandle file(Filename, "rb", FFMS_ERROR_INDEX, FFMS_ERROR_FILE_READ); - - std::unique_ptr ctx{ av_sha_alloc(), av_free }; - av_sha_init(ctx.get(), 160); - - try { - *Filesize = file.Size(); - std::vector FileBuffer(static_cast(std::min(1024 * 1024, *Filesize))); - size_t BytesRead = file.Read(FileBuffer.data(), FileBuffer.size()); - av_sha_update(ctx.get(), reinterpret_cast(FileBuffer.data()), BytesRead); - - if (*Filesize > static_cast(FileBuffer.size())) { - file.Seek(*Filesize - static_cast(FileBuffer.size()), SEEK_SET); - BytesRead = file.Read(FileBuffer.data(), FileBuffer.size()); - av_sha_update(ctx.get(), reinterpret_cast(FileBuffer.data()), BytesRead); - } - } catch (...) { - av_sha_final(ctx.get(), Digest); - throw; - } - av_sha_final(ctx.get(), Digest); -} - -void FFMS_Index::Finalize(std::vector const& video_contexts, const char *Format) { - for (size_t i = 0, end = size(); i != end; ++i) { - FFMS_Track& track = (*this)[i]; - - // Some audio tracks are simply insane junk (seen with als) and will have a single(?) super long packet and - // apart from that look legit and be chosen instead of usable audio. This hopefully rejects some of it. - // Caused by sample in https://github.com/FFMS/ffms2/issues/351 - if (track.TT == FFMS_TYPE_AUDIO) { - if (track.size() <= 10 && track.size() > 0 && track[0].SampleCount > 1000000) - track.clear(); - } - - // H.264 PAFF needs to have some frames hidden - // - // Don't send any WMV/ASF files, since they (as far as we know) cannot contain PAFF, - // but may also have valid, split packets, with pos equal to the previous pos. - if (video_contexts[i].CodecContext && video_contexts[i].CodecContext->codec_id == AV_CODEC_ID_H264 && !!strcmp(Format, "asf")) - track.MaybeHideFrames(); - track.FinalizeTrack(); - - if (track.TT != FFMS_TYPE_VIDEO) continue; - - if (video_contexts[i].CodecContext && video_contexts[i].CodecContext->has_b_frames) { - track.MaxBFrames = video_contexts[i].CodecContext->has_b_frames; - continue; - } - - // Whether or not has_b_frames gets set during indexing seems - // to vary based on version of FFmpeg/Libav, so do an extra - // check for b-frames if it's 0. - for (size_t f = 0; f < track.size(); ++f) { - if (track[f].FrameType == AV_PICTURE_TYPE_B) { - track.MaxBFrames = 1; - break; - } - } - } -} - -bool FFMS_Index::CompareFileSignature(const char *Filename) { - int64_t CFilesize; - uint8_t CDigest[20]; - CalculateFileSignature(Filename, &CFilesize, CDigest); - return (CFilesize == Filesize && !memcmp(CDigest, Digest, sizeof(Digest))); -} - -void FFMS_Index::WriteIndex(ZipFile &zf) { - // Write the index file header - zf.Write(INDEXID); - zf.Write(FFMS_VERSION); - zf.Write(INDEX_VERSION); - zf.Write(size()); - zf.Write(ErrorHandling); - zf.Write(avutil_version()); - zf.Write(avformat_version()); - zf.Write(avcodec_version()); - zf.Write(swscale_version()); - zf.Write(Filesize); - zf.Write(Digest); - - zf.Write(LAVFOpts.size()); - for (const auto &iter : LAVFOpts) { - zf.Write(iter.first.length()); - zf.Write(iter.first.data(), iter.first.length()); - zf.Write(iter.second.length()); - zf.Write(iter.second.data(), iter.second.length()); - } - - for (size_t i = 0; i < size(); ++i) - at(i).Write(zf); - - zf.Finish(); -} - -void FFMS_Index::WriteIndexFile(const char *IndexFile) { - ZipFile zf(IndexFile, "wb"); - - WriteIndex(zf); -} - -uint8_t *FFMS_Index::WriteIndexBuffer(size_t *Size) { - ZipFile zf; - - WriteIndex(zf); - - return zf.GetBuffer(Size); -} - -void FFMS_Index::ReadIndex(ZipFile &zf, const char *IndexFile) { - // Read the index file header - if (zf.Read() != INDEXID) - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, - std::string("'") + IndexFile + "' is not a valid index file"); - - if (zf.Read() != FFMS_VERSION) - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, - std::string("'") + IndexFile + "' was not created with the expected FFMS2 version"); - - if (zf.Read() != INDEX_VERSION) - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, - std::string("'") + IndexFile + "' is not the expected index version"); - - uint32_t Tracks = zf.Read(); - ErrorHandling = zf.Read(); - - if (zf.Read() != avutil_version() || - zf.Read() != avformat_version() || - zf.Read() != avcodec_version() || - zf.Read() != swscale_version()) - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, - std::string("A different FFmpeg build was used to create '") + IndexFile + "'"); - - Filesize = zf.Read(); - zf.Read(Digest, sizeof(Digest)); - - uint32_t NumOptions = zf.Read(); - std::vector KeyBuffer; - std::vector ValueBuffer; - for (uint32_t i = 0; i < NumOptions; i++) { - uint32_t KeyLength = zf.Read(); - KeyBuffer.resize(KeyLength); - zf.Read(KeyBuffer.data(), KeyLength); - - uint32_t ValueLength = zf.Read(); - ValueBuffer.resize(ValueLength); - zf.Read(ValueBuffer.data(), ValueLength); - - LAVFOpts[std::string(KeyBuffer.data(), KeyLength)] = std::string(ValueBuffer.data(), ValueLength); - } - - reserve(Tracks); - try { - for (size_t i = 0; i < Tracks; ++i) - emplace_back(zf); - } catch (FFMS_Exception const&) { - throw; - } catch (...) { - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, - std::string("Unknown error while reading index information in '") + IndexFile + "'"); - } -} - -FFMS_Index::FFMS_Index(const char *IndexFile) { - ZipFile zf(IndexFile, "rb"); - - ReadIndex(zf, IndexFile); -} - -FFMS_Index::FFMS_Index(const uint8_t *Buffer, size_t Size) { - ZipFile zf(Buffer, Size); - - ReadIndex(zf, "User supplied buffer"); -} - -FFMS_Index::FFMS_Index(int64_t Filesize, uint8_t Digest[20], int ErrorHandling, const std::map &LAVFOpts) - : ErrorHandling(ErrorHandling) - , Filesize(Filesize), LAVFOpts(LAVFOpts) { - memcpy(this->Digest, Digest, sizeof(this->Digest)); -} - -void FFMS_Indexer::SetIndexTrack(int Track, bool Index) { - if (Track < 0 || Track >= GetNumberOfTracks()) - return; - if (Index) - IndexMask.insert(Track); - else - IndexMask.erase(Track); -}; - -void FFMS_Indexer::SetIndexTrackType(int TrackType, bool Index) { - for (int i = 0; i < GetNumberOfTracks(); i++) { - if (GetTrackType(i) == TrackType) { - if (Index) - IndexMask.insert(i); - else - IndexMask.erase(i); - } - } -} - -void FFMS_Indexer::SetErrorHandling(int ErrorHandling_) { - if (ErrorHandling_ != FFMS_IEH_ABORT && ErrorHandling_ != FFMS_IEH_CLEAR_TRACK && - ErrorHandling_ != FFMS_IEH_STOP_TRACK && ErrorHandling_ != FFMS_IEH_IGNORE) - throw FFMS_Exception(FFMS_ERROR_INDEXING, FFMS_ERROR_INVALID_ARGUMENT, - "Invalid error handling mode specified"); - ErrorHandling = ErrorHandling_; -} - -void FFMS_Indexer::SetProgressCallback(TIndexCallback IC_, void *ICPrivate_) { - IC = IC_; - ICPrivate = ICPrivate_; -} - -FFMS_Indexer::FFMS_Indexer(const char *Filename, const FFMS_KeyValuePair *DemuxerOptions, int NumOptions) - : SourceFile(Filename) { - try { - AVDictionary *Dict = nullptr; - for (int i = 0; i < NumOptions; i++) { - if (!DemuxerOptions[i].Key && !DemuxerOptions[i].Value) - throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_INVALID_ARGUMENT, - "Demuxer key-value pairs can't have NULL strings"); - LAVFOpts[DemuxerOptions[i].Key] = DemuxerOptions[i].Value; - av_dict_set(&Dict, DemuxerOptions[i].Key, DemuxerOptions[i].Value, 0); - } - - if (avformat_open_input(&FormatContext, Filename, nullptr, &Dict) != 0) - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, - std::string("Can't open '") + Filename + "'"); - - av_dict_free(&Dict); - - FFMS_Index::CalculateFileSignature(Filename, &Filesize, Digest); - - if (avformat_find_stream_info(FormatContext, nullptr) < 0) { - avformat_close_input(&FormatContext); - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, - "Couldn't find stream information"); - } - - for (unsigned int i = 0; i < FormatContext->nb_streams; i++) - if (FormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) - IndexMask.insert(i); - - DecodeFrame = av_frame_alloc(); - if (!DecodeFrame) - throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_ALLOCATION_FAILED, - "Couldn't allocate frame"); - } catch (...) { - Free(); - throw; - } -} - -uint32_t FFMS_Indexer::IndexAudioPacket(int Track, AVPacket *Packet, SharedAVContext &Context, FFMS_Index &TrackIndices) { - AVCodecContext *CodecContext = Context.CodecContext; - int64_t StartSample = Context.CurrentSample; - int Ret = avcodec_send_packet(CodecContext, Packet); - if (Ret != 0) { - if (ErrorHandling == FFMS_IEH_ABORT) { - throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_DECODING, "Audio decoding error"); - } else if (ErrorHandling == FFMS_IEH_CLEAR_TRACK) { - TrackIndices[Track].clear(); - IndexMask.erase(Track); - } else if (ErrorHandling == FFMS_IEH_STOP_TRACK) { - IndexMask.erase(Track); - } - } - - while (true) { - av_frame_unref(DecodeFrame); - Ret = avcodec_receive_frame(CodecContext, DecodeFrame); - if (Ret == 0) { - CheckAudioProperties(Track, CodecContext); - Context.CurrentSample += DecodeFrame->nb_samples; - } else if (Ret == AVERROR_EOF || Ret == AVERROR(EAGAIN)) { - break; - } else { - if (ErrorHandling == FFMS_IEH_ABORT) { - throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_DECODING, "Audio decoding error"); - } else if (ErrorHandling == FFMS_IEH_CLEAR_TRACK) { - TrackIndices[Track].clear(); - IndexMask.erase(Track); - } else if (ErrorHandling == FFMS_IEH_STOP_TRACK) { - IndexMask.erase(Track); - } - } - } - - return static_cast(Context.CurrentSample - StartSample); -} - -void FFMS_Indexer::CheckAudioProperties(int Track, AVCodecContext *Context) { - auto it = LastAudioProperties.find(Track); - if (it == LastAudioProperties.end()) { - FFMS_AudioProperties &AP = LastAudioProperties[Track]; - AP.SampleRate = Context->sample_rate; - AP.SampleFormat = Context->sample_fmt; - AP.Channels = Context->ch_layout.nb_channels; - } else if (it->second.SampleRate != Context->sample_rate || - it->second.SampleFormat != Context->sample_fmt || - it->second.Channels != Context->ch_layout.nb_channels) { - std::ostringstream buf; // fixme, dodgy comparison and maybe wrong since it skips layout comp - buf << - "Audio format change detected. This is currently unsupported." - << " Channels: " << it->second.Channels << " -> " << Context->ch_layout.nb_channels << ";" - << " Sample rate: " << it->second.SampleRate << " -> " << Context->sample_rate << ";" - << " Sample format: " << av_get_sample_fmt_name((AVSampleFormat)it->second.SampleFormat) << " -> " - << av_get_sample_fmt_name(Context->sample_fmt); - throw FFMS_Exception(FFMS_ERROR_UNSUPPORTED, FFMS_ERROR_DECODING, buf.str()); - } -} - -void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket *pkt, int *RepeatPict, - int *FrameType, bool *Invisible, enum AVPictureStructure *LastPicStruct) { - if (VideoContext.Parser) { - uint8_t *OB; - int OBSize; - bool IncompleteFrame = false; - - av_parser_parse2(VideoContext.Parser, - VideoContext.CodecContext, - &OB, &OBSize, - pkt->data, pkt->size, - pkt->pts, pkt->dts, pkt->pos); - - // H.264 (PAFF) and HEVC may have one field per packet, so we need to track - // when we have a full or half frame available, and mark one of them as - // hidden, so we do not get duplicate frames. - if (VideoContext.CodecContext->codec_id == AV_CODEC_ID_H264 || - VideoContext.CodecContext->codec_id == AV_CODEC_ID_HEVC) { - if ((VideoContext.Parser->picture_structure == AV_PICTURE_STRUCTURE_TOP_FIELD && - *LastPicStruct == AV_PICTURE_STRUCTURE_BOTTOM_FIELD) || - (VideoContext.Parser->picture_structure == AV_PICTURE_STRUCTURE_BOTTOM_FIELD && - *LastPicStruct == AV_PICTURE_STRUCTURE_TOP_FIELD)) { - IncompleteFrame = true; - *LastPicStruct = AV_PICTURE_STRUCTURE_UNKNOWN; - } else { - *LastPicStruct = VideoContext.Parser->picture_structure; - } - } - - *RepeatPict = VideoContext.Parser->repeat_pict; - *FrameType = VideoContext.Parser->pict_type; - *Invisible = (IncompleteFrame || VideoContext.Parser->repeat_pict < 0 || (pkt->flags & AV_PKT_FLAG_DISCARD)); - } else { - *Invisible = !!(pkt->flags & AV_PKT_FLAG_DISCARD); - } - - if (VideoContext.CodecContext->codec_id == AV_CODEC_ID_VP8) - ParseVP8(pkt->data[0], Invisible, FrameType); - else if (VideoContext.CodecContext->codec_id == AV_CODEC_ID_VP9) - ParseVP9(pkt->data[0], FrameType); -} - -void FFMS_Indexer::Free() { - av_frame_free(&DecodeFrame); - avformat_close_input(&FormatContext); -} - -FFMS_Indexer::~FFMS_Indexer() { - Free(); -} - -int FFMS_Indexer::GetNumberOfTracks() { - return FormatContext->nb_streams; -} - -const char *FFMS_Indexer::GetFormatName() { - return FormatContext->iformat->name; -} - -FFMS_TrackType FFMS_Indexer::GetTrackType(int Track) { - return static_cast(FormatContext->streams[Track]->codecpar->codec_type); -} - -const char *FFMS_Indexer::GetTrackCodec(int Track) { - auto *codec = avcodec_find_decoder(FormatContext->streams[Track]->codecpar->codec_id); - return codec ? codec->name : nullptr; -} - -FFMS_Index *FFMS_Indexer::DoIndexing() { - std::vector AVContexts(FormatContext->nb_streams); - - auto TrackIndices = std::unique_ptr(new FFMS_Index(Filesize, Digest, ErrorHandling, LAVFOpts)); - bool UseDTS = !strcmp(FormatContext->iformat->name, "mpeg") || !strcmp(FormatContext->iformat->name, "mpegts") || !strcmp(FormatContext->iformat->name, "mpegtsraw") || !strcmp(FormatContext->iformat->name, "nuv"); - - for (unsigned int i = 0; i < FormatContext->nb_streams; i++) { - TrackIndices->emplace_back((int64_t)FormatContext->streams[i]->time_base.num * 1000, - FormatContext->streams[i]->time_base.den, - static_cast(FormatContext->streams[i]->codecpar->codec_type), - !!(FormatContext->iformat->flags & AVFMT_TS_DISCONT), - UseDTS); - - if (IndexMask.count(i) && FormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { - auto *VideoCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id); - if (!VideoCodec) { - FormatContext->streams[i]->discard = AVDISCARD_ALL; - IndexMask.erase(i); - continue; - } - - AVContexts[i].CodecContext = avcodec_alloc_context3(VideoCodec); - if (AVContexts[i].CodecContext == nullptr) - throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_ALLOCATION_FAILED, - "Could not allocate video codec context"); - - if (avcodec_parameters_to_context(AVContexts[i].CodecContext, FormatContext->streams[i]->codecpar) < 0) - throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_DECODING, - "Could not copy video codec parameters"); - - if (avcodec_open2(AVContexts[i].CodecContext, VideoCodec, nullptr) < 0) - throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_DECODING, - "Could not open video codec"); - - AVContexts[i].Parser = av_parser_init(FormatContext->streams[i]->codecpar->codec_id); - if (AVContexts[i].Parser) - AVContexts[i].Parser->flags = PARSER_FLAG_COMPLETE_FRAMES; - - if (FormatContext->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC) { - FormatContext->streams[i]->discard = AVDISCARD_ALL; - IndexMask.erase(i); - } else { - IndexMask.insert(i); - } - } else if (IndexMask.count(i) && FormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { - auto *AudioCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id); - if (AudioCodec == nullptr) - throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_UNSUPPORTED, - "Audio codec not found"); - - AVContexts[i].CodecContext = avcodec_alloc_context3(AudioCodec); - if (AVContexts[i].CodecContext == nullptr) - throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_ALLOCATION_FAILED, - "Could not allocate audio codec context"); - - if (avcodec_parameters_to_context(AVContexts[i].CodecContext, FormatContext->streams[i]->codecpar) < 0) - throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_DECODING, - "Could not copy audio codec parameters"); - - if (avcodec_open2(AVContexts[i].CodecContext, AudioCodec, nullptr) < 0) - throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_DECODING, - "Could not open audio codec"); - - (*TrackIndices)[i].HasTS = false; - } else { - FormatContext->streams[i]->discard = AVDISCARD_ALL; - IndexMask.erase(i); - } - } - - AVPacket *Packet = av_packet_alloc(); - if (!Packet) - throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_ALLOCATION_FAILED, - "Could not allocate packet."); - std::vector LastValidTS(FormatContext->nb_streams, AV_NOPTS_VALUE); - - int64_t filesize = avio_size(FormatContext->pb); - enum AVPictureStructure LastPicStruct = AV_PICTURE_STRUCTURE_UNKNOWN; - int ret; - while ((ret = av_read_frame(FormatContext, Packet)) >= 0) { - // Update progress - // FormatContext->pb can apparently be NULL when opening images. - if (IC && FormatContext->pb) { - if ((*IC)(FormatContext->pb->pos, filesize, ICPrivate)) { - av_packet_free(&Packet); - throw FFMS_Exception(FFMS_ERROR_CANCELLED, FFMS_ERROR_USER, - "Cancelled by user"); - } - } - if (!IndexMask.count(Packet->stream_index)) { - av_packet_unref(Packet); - continue; - } - - int Track = Packet->stream_index; - FFMS_Track &TrackInfo = (*TrackIndices)[Track]; - bool KeyFrame = !!(Packet->flags & AV_PKT_FLAG_KEY); - ReadTS(Packet, LastValidTS[Track], (*TrackIndices)[Track].UseDTS); - - if (FormatContext->streams[Track]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { - int64_t PTS = TrackInfo.UseDTS ? Packet->dts : Packet->pts; - if (PTS == AV_NOPTS_VALUE) { - // VPx alt-refs are output as packets which lack timestmps or durations, since - // they are invisible. Currently, the timestamp mangling code in libavformat - // will sometimes add a bogus timestamp and duration, if the webm in question - // has the block duration set (which is a hack, and not really a frame duration - // at all). In the future, libav* will only output packets without timestamps - // or duration, so we need to handle it here, regardless. This does not handle - // NVOPs. We set the duration based on the last PTS, for these packets, because - // FFMS2 currently sorts packets by PTS, which will break decoding, otherwise. - bool HasAltRefs = (FormatContext->streams[Track]->codecpar->codec_id == AV_CODEC_ID_VP8 || - FormatContext->streams[Track]->codecpar->codec_id == AV_CODEC_ID_VP9); - if (Packet->duration == 0 && !HasAltRefs) { - av_packet_free(&Packet); - throw FFMS_Exception(FFMS_ERROR_INDEXING, FFMS_ERROR_PARSER, - "Invalid packet pts, dts, and duration"); - } - - if (TrackInfo.empty()) - PTS = 0; - else - PTS = TrackInfo.back().PTS + TrackInfo.LastDuration; - - TrackInfo.HasTS = false; - } - - int RepeatPict = -1; - int FrameType = 0; - bool Invisible = false; - ParseVideoPacket(AVContexts[Track], Packet, &RepeatPict, &FrameType, &Invisible, &LastPicStruct); - - TrackInfo.AddVideoFrame(PTS, RepeatPict, KeyFrame, - FrameType, Packet->pos, Invisible); - } else if (FormatContext->streams[Track]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { - // For video seeking timestamps are used only if all packets have - // timestamps, while for audio they're used if any have timestamps, - // as it's pretty common for only some packets to have timestamps - if (LastValidTS[Track] != AV_NOPTS_VALUE) - TrackInfo.HasTS = true; - - int64_t StartSample = AVContexts[Track].CurrentSample; - uint32_t SampleCount = IndexAudioPacket(Track, Packet, AVContexts[Track], *TrackIndices); - TrackInfo.SampleRate = AVContexts[Track].CodecContext->sample_rate; - - TrackInfo.AddAudioFrame(LastValidTS[Track], - StartSample, SampleCount, KeyFrame, Packet->pos, Packet->flags & AV_PKT_FLAG_DISCARD); - } - - if (!(Packet->flags & AV_PKT_FLAG_DISCARD)) - TrackInfo.LastDuration = Packet->duration; - - av_packet_unref(Packet); - } - av_packet_free(&Packet); - if (IsIOError(ret)) { - char error[1024]; - av_strerror(ret, error, 1024); - std::string cerr(error); - throw FFMS_Exception(FFMS_ERROR_INDEXING, FFMS_ERROR_FILE_READ, - "Indexing failed: " + cerr); - } - - TrackIndices->Finalize(AVContexts, FormatContext->iformat->name); - return TrackIndices.release(); -} - -void FFMS_Indexer::ReadTS(const AVPacket *Packet, int64_t &TS, bool &UseDTS) { - if (!UseDTS && Packet->pts != AV_NOPTS_VALUE) - TS = Packet->pts; - if (TS == AV_NOPTS_VALUE) - UseDTS = true; - if (UseDTS && Packet->dts != AV_NOPTS_VALUE) - TS = Packet->dts; -} diff --git a/thirdparty/ffms2/src/core/indexing.h b/thirdparty/ffms2/src/core/indexing.h deleted file mode 100644 index 2cd0039d4..000000000 --- a/thirdparty/ffms2/src/core/indexing.h +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) 2007-2017 Fredrik Mellbin -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#ifndef INDEXING_H -#define INDEXING_H - -#include "utils.h" - -#include -#include -#include -#include - -extern "C" { -#include -} - -class Wave64Writer; -class ZipFile; - -struct SharedAVContext { - AVCodecContext *CodecContext = nullptr; - AVCodecParserContext *Parser = nullptr; - int64_t CurrentSample = 0; - ~SharedAVContext(); -}; - -struct FFMS_Index : public std::vector { - FFMS_Index(FFMS_Index const&) = delete; - FFMS_Index& operator=(FFMS_Index const&) = delete; - void ReadIndex(ZipFile &zf, const char* IndexFile); - void WriteIndex(ZipFile &zf); -public: - static void CalculateFileSignature(const char *Filename, int64_t *Filesize, uint8_t Digest[20]); - - int ErrorHandling; - int64_t Filesize; - uint8_t Digest[20]; - std::map LAVFOpts; - - void Finalize(std::vector const& video_contexts, const char *Format); - bool CompareFileSignature(const char *Filename); - void WriteIndexFile(const char *IndexFile); - uint8_t *WriteIndexBuffer(size_t *Size); - - FFMS_Index(const char *IndexFile); - FFMS_Index(const uint8_t *Buffer, size_t Size); - FFMS_Index(int64_t Filesize, uint8_t Digest[20], int ErrorHandling, const std::map &LAVFOpts); -}; - -struct FFMS_Indexer { -private: - std::map LastAudioProperties; - FFMS_Indexer(FFMS_Indexer const&) = delete; - FFMS_Indexer& operator=(FFMS_Indexer const&) = delete; - AVFormatContext *FormatContext = nullptr; - std::set IndexMask; - std::map LAVFOpts; - int ErrorHandling = FFMS_IEH_CLEAR_TRACK; - TIndexCallback IC = nullptr; - void *ICPrivate = nullptr; - std::string SourceFile; - AVFrame *DecodeFrame = nullptr; - - int64_t Filesize; - uint8_t Digest[20]; - - void ReadTS(const AVPacket *Packet, int64_t &TS, bool &UseDTS); - void CheckAudioProperties(int Track, AVCodecContext *Context); - uint32_t IndexAudioPacket(int Track, AVPacket *Packet, SharedAVContext &Context, FFMS_Index &TrackIndices); - void ParseVideoPacket(SharedAVContext &VideoContext, AVPacket *pkt, int *RepeatPict, int *FrameType, bool *Invisible, enum AVPictureStructure *LastPicStruct); - void Free(); -public: - FFMS_Indexer(const char *Filename, const FFMS_KeyValuePair *DemuxerOptions, int NumOptions); - ~FFMS_Indexer(); - - void SetIndexTrack(int Track, bool Index); - void SetIndexTrackType(int TrackType, bool Index); - void SetErrorHandling(int ErrorHandling_); - void SetProgressCallback(TIndexCallback IC_, void *ICPrivate_); - - FFMS_Index *DoIndexing(); - int GetNumberOfTracks(); - FFMS_TrackType GetTrackType(int Track); - const char *GetTrackCodec(int Track); - const char *GetFormatName(); -}; - - -#endif diff --git a/thirdparty/ffms2/src/core/track.cpp b/thirdparty/ffms2/src/core/track.cpp deleted file mode 100644 index 01c9e116f..000000000 --- a/thirdparty/ffms2/src/core/track.cpp +++ /dev/null @@ -1,420 +0,0 @@ -// Copyright (c) 2014 Thomas Goyne -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#include "track.h" - -#include "utils.h" -#include "zipfile.h" -#include "indexing.h" - -#include -#include -#include - -extern "C" { -#include -#include -#include -} - -namespace { -FrameInfo ReadFrame(ZipFile &stream, FrameInfo const& prev, const FFMS_TrackType TT) { - FrameInfo f{}; - f.PTS = stream.Read() + prev.PTS; - f.OriginalPTS = stream.Read() + prev.OriginalPTS; - f.KeyFrame = !!stream.Read(); - f.FilePos = stream.Read() + prev.FilePos; - f.Hidden = !!stream.Read(); - - if (TT == FFMS_TYPE_AUDIO) { - f.SampleStart = prev.SampleStart + prev.SampleCount; - f.SampleCount = stream.Read() + prev.SampleCount; - } else if (TT == FFMS_TYPE_VIDEO) { - f.OriginalPos = static_cast(stream.Read() + prev.OriginalPos + 1); - f.RepeatPict = stream.Read(); - } - return f; -} - -static void WriteFrame(ZipFile &stream, FrameInfo const& f, FrameInfo const& prev, const FFMS_TrackType TT) { - stream.Write(f.PTS - prev.PTS); - stream.Write(f.OriginalPTS - prev.OriginalPTS); - stream.Write(f.KeyFrame); - stream.Write(f.FilePos - prev.FilePos); - stream.Write(f.Hidden); - - if (TT == FFMS_TYPE_AUDIO) - stream.Write(f.SampleCount - prev.SampleCount); - else if (TT == FFMS_TYPE_VIDEO) { - stream.Write(static_cast(f.OriginalPos) - prev.OriginalPos - 1); - stream.Write(f.RepeatPict); - } -} -} - -FFMS_Track::FFMS_Track() - : Data(std::make_shared()) -{ -} - -FFMS_Track::FFMS_Track(int64_t Num, int64_t Den, FFMS_TrackType TT, bool HasDiscontTS, bool UseDTS, bool HasTS) - : Data(std::make_shared()) - , TT(TT) - , UseDTS(UseDTS) - , HasTS(HasTS) - , HasDiscontTS(HasDiscontTS) { - TB.Num = Num; - TB.Den = Den; -} - -FFMS_Track::FFMS_Track(ZipFile &stream) - : Data(std::make_shared()) { - frame_vec &Frames = Data->Frames; - TT = static_cast(stream.Read()); - TB.Num = stream.Read(); - TB.Den = stream.Read(); - LastDuration = stream.Read(); - MaxBFrames = stream.Read(); - UseDTS = !!stream.Read(); - HasTS = !!stream.Read(); - HasDiscontTS = !!stream.Read(); - size_t FrameCount = static_cast(stream.Read()); - - if (!FrameCount) return; - - FrameInfo temp{}; - Frames.reserve(FrameCount); - for (size_t i = 0; i < FrameCount; ++i) - Frames.push_back(ReadFrame(stream, i == 0 ? temp : Frames.back(), TT)); - - if (TT == FFMS_TYPE_VIDEO) - GeneratePublicInfo(); -} - -void FFMS_Track::Write(ZipFile &stream) const { - frame_vec &Frames = Data->Frames; - stream.Write(TT); - stream.Write(TB.Num); - stream.Write(TB.Den); - stream.Write(LastDuration); - stream.Write(MaxBFrames); - stream.Write(UseDTS); - stream.Write(HasTS); - stream.Write(HasDiscontTS); - stream.Write(size()); - - if (empty()) return; - - FrameInfo temp{}; - for (size_t i = 0; i < size(); ++i) - WriteFrame(stream, Frames[i], i == 0 ? temp : Frames[i - 1], TT); -} - -void FFMS_Track::AddVideoFrame(int64_t PTS, int RepeatPict, bool KeyFrame, int FrameType, int64_t FilePos, bool Hidden) { - Data->Frames.push_back({ PTS, 0, FilePos, 0, 0, 0, FrameType, RepeatPict, KeyFrame, Hidden }); -} - -void FFMS_Track::AddAudioFrame(int64_t PTS, int64_t SampleStart, uint32_t SampleCount, bool KeyFrame, int64_t FilePos, bool Hidden) { - if (SampleCount > 0) { - Data->Frames.push_back({ PTS, 0, FilePos, SampleStart, SampleCount, - 0, 0, 0, KeyFrame, Hidden }); - } -} - -void FFMS_Track::WriteTimecodes(const char *TimecodeFile) const { - frame_vec &Frames = Data->Frames; - FileHandle file(TimecodeFile, "w", FFMS_ERROR_TRACK, FFMS_ERROR_FILE_WRITE); - - file.Printf("# timecode format v2\n"); - for (size_t i = 0; i < size(); ++i) { - if (!Frames[i].Hidden) - file.Printf("%.02f\n", (Frames[i].PTS * TB.Num) / (double)TB.Den); - } -} - -static bool PTSComparison(FrameInfo FI1, FrameInfo FI2) { - return FI1.PTS < FI2.PTS; -} - -int FFMS_Track::FrameFromPTS(int64_t PTS) const { - FrameInfo F; - F.PTS = PTS; - - auto Pos = std::lower_bound(begin(), end(), F, PTSComparison); - while (Pos != end() && Pos->Hidden && Pos->PTS == PTS) - Pos++; - - if (Pos == end() || Pos->PTS != PTS) - return -1; - return std::distance(begin(), Pos); -} - -int FFMS_Track::FrameFromPos(int64_t Pos) const { - for (size_t i = 0; i < size(); i++) - if (Data->Frames[i].FilePos == Pos && !Data->Frames[i].Hidden) - return static_cast(i); - return -1; -} - -int FFMS_Track::ClosestFrameFromPTS(int64_t PTS) const { - FrameInfo F; - F.PTS = PTS; - - auto Pos = std::lower_bound(begin(), end(), F, PTSComparison); - while (Pos != end() && Pos->Hidden && Pos->PTS == PTS) - Pos++; - - if (Pos == end()) - return static_cast(size() - 1); - size_t Frame = std::distance(begin(), Pos); - if (Pos == begin() || FFABS(Pos->PTS - PTS) <= FFABS((Pos - 1)->PTS - PTS)) - return static_cast(Frame); - return static_cast(Frame - 1); -} - -int FFMS_Track::FindClosestVideoKeyFrame(int Frame) const { - frame_vec &Frames = Data->Frames; - Frame = std::min(std::max(Frame, 0), static_cast(size()) - 1); - for (; Frame > 0 && !Frames[Frame].KeyFrame; Frame--); - for (; Frame > 0 && !Frames[Frames[Frame].OriginalPos].KeyFrame; Frame--); - return Frame; -} - -int FFMS_Track::RealFrameNumber(int Frame) const { - return Data->RealFrameNumbers[Frame]; -} - -int FFMS_Track::VisibleFrameCount() const { - return TT == FFMS_TYPE_AUDIO ? static_cast(Data->Frames.size()) : static_cast(Data->RealFrameNumbers.size()); -} - -void FFMS_Track::MaybeReorderFrames() { - frame_vec &Frames = Data->Frames; - // First check if we need to do anything - bool has_b_frames = false; - for (size_t i = 1; i < size(); ++i) { - // If the timestamps are already out of order, then they actually are - // presentation timestamps and we don't need to do anything - if (Frames[i].PTS < Frames[i - 1].PTS) - return; - - if (Frames[i].FrameType == AV_PICTURE_TYPE_B) { - has_b_frames = true; - - // Reordering files with multiple b-frames is currently not - // supported - if (Frames[i - 1].FrameType == AV_PICTURE_TYPE_B) - return; - } - } - - // Don't need to do anything if there are no b-frames as presentation order - // equals decoding order - if (!has_b_frames) - return; - - // We have b-frames, but the timestamps are monotonically increasing. This - // means that the timestamps we have are decoding timestamps, and we want - // presentation time stamps. Convert DTS to PTS by swapping the timestamp - // of each b-frame with the frame before it. This only works for the - // specific case of b-frames which reference the frame immediately after - // them temporally, but that happens to cover the only files I've seen - // with b-frames and no presentation timestamps. - for (size_t i = 1; i < size(); ++i) { - if (Frames[i].FrameType == AV_PICTURE_TYPE_B) - std::swap(Frames[i].PTS, Frames[i - 1].PTS); - } -} - -void FFMS_Track::MaybeHideFrames() { - frame_vec &Frames = Data->Frames; - // Awful handling for interlaced H.264: each frame is output twice, so hide - // frames with an invalid file position. The PTS will not match sometimes, - // since libavformat makes up timestamps... but only sometimes. - for (size_t i = 1; i < size(); ++i) { - FrameInfo const& prev = Frames[i - 1]; - FrameInfo& cur = Frames[i]; - - if (prev.FilePos >= 0 && (cur.FilePos == -1 || cur.FilePos == prev.FilePos) && !prev.Hidden) - cur.Hidden = true; - } -} - -void FFMS_Track::FillAudioGaps() { - frame_vec &Frames = Data->Frames; - // There may not be audio data for the entire duration of the audio track, - // as some formats support gaps between the end time of one packet and the - // PTS of the next audio packet, and we should zero-fill those gaps. - // However, garbage or missing timestamps for audio tracks are very common, - // so we only want to trust them if they're all present, monotonically - // increasing, and result in a total duration meaningfully longer than the - // samples we have would cover. - if (size() < 2 || !HasTS || front().PTS == AV_NOPTS_VALUE || back().PTS == AV_NOPTS_VALUE) - return; - - const auto DurationToSamples = [this](int64_t Dur) { - auto Num = TB.Num * SampleRate; - auto Den = TB.Den * 1000; - return av_rescale(Dur, Num, Den); - }; - - const auto SamplesToDuration = [this](int64_t Samples) { - auto Num = TB.Den * 1000; - auto Den = TB.Num * SampleRate; - return av_rescale(Samples, Num, Den); - }; - - if (HasDiscontTS) { - int64_t shift = 0; - Frames[0].OriginalPTS = Frames[0].PTS; - for (size_t i = 1; i < size(); i++) { - Frames[i].OriginalPTS = Frames[i].PTS; - if (Frames[i].PTS != AV_NOPTS_VALUE && Frames[i].OriginalPTS <= Frames[i-1].OriginalPTS) - shift = -(Frames[i].PTS) + Frames[i-1].PTS + SamplesToDuration(Frames[i-1].SampleCount); - Frames[i].PTS += shift; - } - } - - const auto ActualSamples = back().SampleStart + back().SampleCount; - const auto ExpectedSamples = DurationToSamples(back().PTS - front().PTS) + back().SampleCount; - if (ActualSamples + 5 > ExpectedSamples) // arbitrary threshold to cover rounding/not worth adjusting - return; - - // Verify that every frame has a timestamp and that they monotonically - // increase, as otherwise we can't trust them - auto PrevPTS = front().PTS - 1; - for (auto const& frame : *this) { - if (frame.PTS == AV_NOPTS_VALUE || frame.PTS <= PrevPTS) - return; - PrevPTS = frame.PTS; - } - - // There are some missing samples and the timestamps appear to all be valid, - // so go ahead and extend the frames to cover the gaps - const auto FirstPTS = front().PTS; - auto PrevFrame = &Frames.front(); - int32_t Shift = 0; - for (auto& Frame : Frames) { - if (Shift > 0) - Frame.SampleStart += Shift; - - const auto ExpectedStartSample = DurationToSamples(Frame.PTS - FirstPTS); - const auto Gap = static_cast(ExpectedStartSample - Frame.SampleStart); - if (Gap > 0) { - PrevFrame->SampleCount += Gap; - Frame.SampleStart = ExpectedStartSample; - } - Shift += Gap; - PrevFrame = &Frame; - } -} - -void FFMS_Track::FinalizeTrack() { - frame_vec &Frames = Data->Frames; - // With some formats (such as Vorbis) a bad final packet results in a - // frame with PTS 0, which we don't want to sort to the beginning - if (size() > 2 && front().PTS >= back().PTS) - Frames.pop_back(); - - if (TT != FFMS_TYPE_VIDEO) - return; - - for (size_t i = 0; i < size(); i++) { - Frames[i].OriginalPos = i; - Frames[i].OriginalPTS = Frames[i].PTS; - } - - MaybeReorderFrames(); - - if (size() > 2 && HasDiscontTS) { - std::vector secs = { 0 }; - - auto lastPTS = Frames[0].PTS; - const auto thresh = std::abs(Frames[1].PTS - Frames[0].PTS) * 16; // A bad approximation of 16 frames, the max reorder buffer size. - for (size_t i = 0; i < size(); i++) { - if (Frames[i].PTS < lastPTS && (lastPTS - Frames[i].PTS) > thresh && i + 1 < size()) { - secs.push_back(i); - i++; // Sections must be at least 2 frames long. - } - lastPTS = Frames[i].PTS; - } - - // We need to sort each distinct sections by PTS to account for any reordering. - for (size_t i = 0; i < secs.size() - 1; i++) - sort(Frames.begin() + secs[i], Frames.begin() + secs[i + 1], PTSComparison); - sort(Frames.begin() + secs.back(), Frames.end(), PTSComparison); - - // Try and make up some sane timestamps based on previous sections, while - // keeping the same frame durations. - for (size_t i = 1; i < secs.size(); i++) { - const auto shift = -(Frames[secs[i]].PTS) + (Frames[secs[i] + 1].PTS - Frames[secs[i]].PTS) + Frames[secs[i] - 1].PTS; - size_t end; - if (i == secs.size() - 1) - end = Frames.size(); - else - end = secs[i + 1]; - for (size_t j = secs[i]; j < end; j++) - Frames[j].PTS += shift; - } - } else { - sort(Frames.begin(), Frames.end(), PTSComparison); - } - - std::vector ReorderTemp; - ReorderTemp.reserve(size()); - - for (size_t i = 0; i < size(); i++) - ReorderTemp.push_back(Frames[i].OriginalPos); - - for (size_t i = 0; i < size(); i++) - Frames[ReorderTemp[i]].OriginalPos = i; - - GeneratePublicInfo(); - - // If the last packet in the file did not have a duration set, - // fudge one based on the previous frame's duration. - if (LastDuration == 0) { - size_t InfoSize = Data->PublicFrameInfo.size(); - if (InfoSize >= 2) - LastDuration = Data->PublicFrameInfo[InfoSize - 1].PTS - Data->PublicFrameInfo[InfoSize - 2].PTS; - } -} - -void FFMS_Track::GeneratePublicInfo() { - frame_vec &Frames = Data->Frames; - std::vector &RealFrameNumbers = Data->RealFrameNumbers; - std::vector &PublicFrameInfo = Data->PublicFrameInfo; - RealFrameNumbers.reserve(size()); - PublicFrameInfo.reserve(size()); - for (size_t i = 0; i < size(); ++i) { - if (Frames[i].Hidden) - continue; - RealFrameNumbers.push_back(static_cast(i)); - - FFMS_FrameInfo info = { Frames[i].PTS, Frames[i].RepeatPict, Frames[i].KeyFrame, Frames[i].OriginalPTS }; - PublicFrameInfo.push_back(info); - } -} - -const FFMS_FrameInfo *FFMS_Track::GetFrameInfo(size_t N) const { - std::vector &PublicFrameInfo = Data->PublicFrameInfo; - if (N >= PublicFrameInfo.size()) return nullptr; - return &PublicFrameInfo[N]; -} diff --git a/thirdparty/ffms2/src/core/track.h b/thirdparty/ffms2/src/core/track.h deleted file mode 100644 index f6a9fbb2c..000000000 --- a/thirdparty/ffms2/src/core/track.h +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) 2013 Thomas Goyne -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#ifndef TRACK_H -#define TRACK_H - -#include "ffms.h" - -#include -#include -#include - -class ZipFile; - -struct FrameInfo { - int64_t PTS; - int64_t OriginalPTS; - int64_t FilePos; - int64_t SampleStart; - uint32_t SampleCount; - size_t OriginalPos; - int FrameType; - int RepeatPict; - bool KeyFrame; - bool Hidden; -}; - -struct FFMS_Track { -private: - typedef std::vector frame_vec; - struct TrackData { - frame_vec Frames; - std::vector RealFrameNumbers; - std::vector PublicFrameInfo; - }; - - std::shared_ptr Data; - - void MaybeReorderFrames(); - void GeneratePublicInfo(); - -public: - FFMS_TrackType TT = FFMS_TYPE_UNKNOWN; - FFMS_TrackTimeBase TB = FFMS_TrackTimeBase{ 0, 0 }; - int MaxBFrames = 0; - bool UseDTS = false; - bool HasTS = false; - bool HasDiscontTS = false; - int64_t LastDuration = 0; - int SampleRate = 0; // not persisted - - void AddVideoFrame(int64_t PTS, int RepeatPict, bool KeyFrame, int FrameType, int64_t FilePos = 0, bool Invisible = false); - void AddAudioFrame(int64_t PTS, int64_t SampleStart, uint32_t SampleCount, bool KeyFrame, int64_t FilePos = 0, bool Invisible = false); - - void MaybeHideFrames(); - void FinalizeTrack(); - void FillAudioGaps(); - - int FindClosestVideoKeyFrame(int Frame) const; - int FrameFromPTS(int64_t PTS) const; - int FrameFromPos(int64_t Pos) const; - int ClosestFrameFromPTS(int64_t PTS) const; - int RealFrameNumber(int Frame) const; - int VisibleFrameCount() const; - - const FFMS_FrameInfo *GetFrameInfo(size_t N) const; - - void WriteTimecodes(const char *TimecodeFile) const; - void Write(ZipFile &Stream) const; - - typedef frame_vec::allocator_type allocator_type; - typedef frame_vec::size_type size_type; - typedef frame_vec::difference_type difference_type; - typedef frame_vec::const_pointer pointer; - typedef frame_vec::const_reference reference; - typedef frame_vec::value_type value_type; - typedef frame_vec::const_iterator iterator; - typedef frame_vec::const_reverse_iterator reverse_iterator; - - void clear() { - Data = std::make_shared(); - } - - bool empty() const { return Data->Frames.empty(); } - size_type size() const { return Data->Frames.size(); } - reference operator[](size_type pos) const { return Data->Frames[pos]; } - reference front() const { return Data->Frames.front(); } - reference back() const { return Data->Frames.back(); } - iterator begin() const { return Data->Frames.begin(); } - iterator end() const { return Data->Frames.end(); } - - FFMS_Track(); - FFMS_Track(ZipFile &Stream); - FFMS_Track(int64_t Num, int64_t Den, FFMS_TrackType TT, bool HasDiscontTS, bool UseDTS, bool HasTS = true); -}; - -#endif diff --git a/thirdparty/ffms2/src/core/utils.cpp b/thirdparty/ffms2/src/core/utils.cpp deleted file mode 100644 index 8a3a519d9..000000000 --- a/thirdparty/ffms2/src/core/utils.cpp +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright (c) 2007-2015 Fredrik Mellbin -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -extern "C" { -#include -} - -#include "utils.h" - -#include "indexing.h" -#include "track.h" - -#ifdef _WIN32 -# define WIN32_LEAN_AND_MEAN -# include -#endif // _WIN32 - -#include -#include - -FFMS_Exception::FFMS_Exception(int ErrorType, int SubType, const char *Message) : _Message(Message), _ErrorType(ErrorType), _SubType(SubType) {} -FFMS_Exception::FFMS_Exception(int ErrorType, int SubType, const std::string &Message) : _Message(Message), _ErrorType(ErrorType), _SubType(SubType) {} - -int FFMS_Exception::CopyOut(FFMS_ErrorInfo *ErrorInfo) const { - if (ErrorInfo) { - ErrorInfo->ErrorType = _ErrorType; - ErrorInfo->SubType = _SubType; - - if (ErrorInfo->BufferSize > 0) { - memset(ErrorInfo->Buffer, 0, ErrorInfo->BufferSize); - _Message.copy(ErrorInfo->Buffer, ErrorInfo->BufferSize - 1); - } - } - - return (_ErrorType << 16) | _SubType; -} - -void ClearErrorInfo(FFMS_ErrorInfo *ErrorInfo) { - if (ErrorInfo) { - ErrorInfo->ErrorType = FFMS_ERROR_SUCCESS; - ErrorInfo->SubType = FFMS_ERROR_SUCCESS; - - if (ErrorInfo->BufferSize > 0) - ErrorInfo->Buffer[0] = 0; - } -} - -void FillAP(FFMS_AudioProperties &AP, AVCodecContext *CTX, FFMS_Track &Frames) { - AP.SampleFormat = static_cast(av_get_packed_sample_fmt(CTX->sample_fmt)); - AP.BitsPerSample = av_get_bytes_per_sample(CTX->sample_fmt) * 8; - AP.Channels = CTX->ch_layout.nb_channels; - - if (CTX->ch_layout.order == AV_CHANNEL_ORDER_NATIVE) { - AP.ChannelLayout = CTX->ch_layout.u.mask; - } else if (CTX->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) { - AVChannelLayout ch = {}; - av_channel_layout_default(&ch, CTX->ch_layout.nb_channels); - AP.ChannelLayout = ch.u.mask; - } else { - throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_UNSUPPORTED, "Ambisonics and custom channel orders not supported"); - } - - AP.SampleRate = CTX->sample_rate; - if (!Frames.empty()) { - AP.NumSamples = (Frames.back()).SampleStart + (Frames.back()).SampleCount; - AP.FirstTime = ((Frames.front().PTS * Frames.TB.Num) / (double)Frames.TB.Den) / 1000; - AP.LastTime = ((Frames.back().PTS * Frames.TB.Num) / (double)Frames.TB.Den) / 1000; - AP.LastEndTime = (((Frames.back().PTS + Frames.LastDuration) * Frames.TB.Num) / (double)Frames.TB.Den) / 1000; - } -} - -void LAVFOpenFile(const char *SourceFile, AVFormatContext *&FormatContext, int Track, const std::map &LAVFOpts) { - AVDictionary *Dict = nullptr; - for (const auto &iter : LAVFOpts) - av_dict_set(&Dict, iter.first.c_str(), iter.second.c_str(), 0); - - if (avformat_open_input(&FormatContext, SourceFile, nullptr, &Dict) != 0) - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, - std::string("Couldn't open '") + SourceFile + "'"); - - av_dict_free(&Dict); - - if (avformat_find_stream_info(FormatContext, nullptr) < 0) { - avformat_close_input(&FormatContext); - FormatContext = nullptr; - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, - "Couldn't find stream information"); - } - - for (int i = 0; i < (int)FormatContext->nb_streams; i++) - if (i != Track) - FormatContext->streams[i]->discard = AVDISCARD_ALL; -} - -int ResizerNameToSWSResizer(const char *ResizerName) { - if (!ResizerName) - return 0; - std::string s = ResizerName; - std::transform(s.begin(), s.end(), s.begin(), toupper); - if (s == "FAST_BILINEAR") - return SWS_FAST_BILINEAR; - if (s == "BILINEAR") - return SWS_BILINEAR; - if (s == "BICUBIC") - return SWS_BICUBIC; - if (s == "X") - return SWS_X; - if (s == "POINT") - return SWS_POINT; - if (s == "AREA") - return SWS_AREA; - if (s == "BICUBLIN") - return SWS_BICUBLIN; - if (s == "GAUSS") - return SWS_GAUSS; - if (s == "SINC") - return SWS_SINC; - if (s == "LANCZOS") - return SWS_LANCZOS; - if (s == "SPLINE") - return SWS_SPLINE; - return 0; -} - -bool IsSamePath(const char *p1, const char *p2) { - // assume windows is the only OS with a case insensitive filesystem and ignore all path complications -#ifndef _WIN32 - return !strcmp(p1, p2); -#else - return !_stricmp(p1, p2); -#endif -} - -bool IsIOError(int error) { - switch (error) { - case AVERROR(EIO): - case AVERROR(ETIMEDOUT): - case AVERROR(EPROTO): - case AVERROR(EADDRINUSE): - case AVERROR(EADDRNOTAVAIL): - case AVERROR(ENETDOWN): - case AVERROR(ENETUNREACH): - case AVERROR(ENETRESET): - case AVERROR(ECONNABORTED): - case AVERROR(ECONNRESET): - case AVERROR(ECONNREFUSED): - case AVERROR(EHOSTUNREACH): -#ifndef _WIN32 - case AVERROR(ESHUTDOWN): - case AVERROR(EHOSTDOWN): -#endif - return true; - default: - return false; - } -} diff --git a/thirdparty/ffms2/src/core/utils.h b/thirdparty/ffms2/src/core/utils.h deleted file mode 100644 index bd310995c..000000000 --- a/thirdparty/ffms2/src/core/utils.h +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright (c) 2007-2011 Fredrik Mellbin -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#ifndef UTILS_H -#define UTILS_H - -#include "ffms.h" - -extern "C" { -#include -#include -#include -#include -#include -#include -} - -// must be included after ffmpeg headers -#include "ffmscompat.h" - -#include -#include -#include -#include -#include - -class FFMS_Exception { - std::string _Message; - int _ErrorType; - int _SubType; - -public: - FFMS_Exception(int ErrorType, int SubType, const char *Message = ""); - FFMS_Exception(int ErrorType, int SubType, const std::string &Message); - const std::string &GetErrorMessage() const { return _Message; } - int CopyOut(FFMS_ErrorInfo *ErrorInfo) const; -}; - -template -std::unique_ptr make_unique(Args&&... args) { - return std::unique_ptr(new T(std::forward(args)...)); -} - -void ClearErrorInfo(FFMS_ErrorInfo *ErrorInfo); -void FillAP(FFMS_AudioProperties &AP, AVCodecContext *CTX, FFMS_Track &Frames); - -void LAVFOpenFile(const char *SourceFile, AVFormatContext *&FormatContext, int Track, const std::map &LAVFOpts); - -namespace optdetail { - template - T get_av_opt(void *v, const char *name) { - int64_t value = 0; - av_opt_get_int(v, name, 0, &value); - return static_cast(value); - } - - template<> - inline double get_av_opt(void *v, const char *name) { - double value = 0.0; - av_opt_get_double(v, name, 0, &value); - return value; - } - - template - void set_av_opt(void *v, const char *name, T value) { - av_opt_set_int(v, name, value, 0); - } - - template<> - inline void set_av_opt(void *v, const char *name, double value) { - av_opt_set_double(v, name, value, 0); - } -} - -template -class OptionMapper { - struct OptionMapperBase { - virtual void ToOpt(FFMS_Struct const& src, void *dst) const = 0; - virtual void FromOpt(FFMS_Struct &dst, void *src) const = 0; - virtual ~OptionMapperBase() = default; - }; - - template - class OptionMapperImpl : public OptionMapperBase { - T(FFMS_Struct::*ptr); - const char *name; - - public: - OptionMapperImpl(T(FFMS_Struct::*ptr), const char *name) : ptr(ptr), name(name) {} - void ToOpt(FFMS_Struct const& src, void *dst) const { optdetail::set_av_opt(dst, name, src.*ptr); } - void FromOpt(FFMS_Struct &dst, void *src) const { dst.*ptr = optdetail::get_av_opt(src, name); } - }; - - std::unique_ptr impl; - -public: - template - OptionMapper(const char *opt_name, T(FFMS_Struct::*member)) : impl(new OptionMapperImpl(member, opt_name)) {} - - void ToOpt(FFMS_Struct const& src, void *dst) const { impl->ToOpt(src, dst); } - void FromOpt(FFMS_Struct &dst, void *src) const { impl->FromOpt(dst, src); } -}; - -template -std::unique_ptr ReadOptions(void *opt, OptionMapper(&options)[N]) { - auto ret = make_unique(); - for (int i = 0; i < N; ++i) - options[i].FromOpt(*ret, opt); - return ret; -} - -template -void SetOptions(T const& src, void *opt, OptionMapper(&options)[N]) { - for (int i = 0; i < N; ++i) - options[i].ToOpt(src, opt); -} - -int ResizerNameToSWSResizer(const char *ResizerName); -bool IsSamePath(const char *p1, const char *p2); -bool IsIOError(int error); - -#endif diff --git a/thirdparty/ffms2/src/core/videosource.cpp b/thirdparty/ffms2/src/core/videosource.cpp deleted file mode 100644 index 443bb3388..000000000 --- a/thirdparty/ffms2/src/core/videosource.cpp +++ /dev/null @@ -1,860 +0,0 @@ -// Copyright (c) 2007-2017 Fredrik Mellbin -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#include "videosource.h" -#include "indexing.h" -#include "videoutils.h" -#include -#include - - -void FFMS_VideoSource::SanityCheckFrameForData(AVFrame *Frame) { - for (int i = 0; i < 4; i++) { - if (Frame->data[i] != nullptr && Frame->linesize[i] != 0) - return; - } - - throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC, "Insanity detected: decoder returned an empty frame"); -} - -void FFMS_VideoSource::GetFrameCheck(int n) { - if (n < 0 || n >= VP.NumFrames) - throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_INVALID_ARGUMENT, - "Out of bounds frame requested"); -} - -FFMS_Frame *FFMS_VideoSource::OutputFrame(AVFrame *Frame) { - SanityCheckFrameForData(Frame); - - if (LastFrameWidth != Frame->width || LastFrameHeight != Frame->height || LastFramePixelFormat != Frame->format) { - if (TargetHeight > 0 && TargetWidth > 0 && !TargetPixelFormats.empty()) { - if (!InputFormatOverridden) { - InputFormat = AV_PIX_FMT_NONE; - InputColorSpace = AVCOL_SPC_UNSPECIFIED; - InputColorRange = AVCOL_RANGE_UNSPECIFIED; - } - - ReAdjustOutputFormat(Frame); - } else { - OutputFormat = (AVPixelFormat) Frame->format; - } - } - - if (SWS) { - sws_scale(SWS, Frame->data, Frame->linesize, 0, Frame->height, SWSFrameData, SWSFrameLinesize); - for (int i = 0; i < 4; i++) { - LocalFrame.Data[i] = SWSFrameData[i]; - LocalFrame.Linesize[i] = SWSFrameLinesize[i]; - } - } else { - // Special case to avoid ugly casts - for (int i = 0; i < 4; i++) { - LocalFrame.Data[i] = Frame->data[i]; - LocalFrame.Linesize[i] = Frame->linesize[i]; - } - } - - LocalFrame.EncodedWidth = Frame->width; - LocalFrame.EncodedHeight = Frame->height; - LocalFrame.EncodedPixelFormat = Frame->format; - LocalFrame.ScaledWidth = TargetWidth; - LocalFrame.ScaledHeight = TargetHeight; - LocalFrame.ConvertedPixelFormat = OutputFormat; - LocalFrame.KeyFrame = Frame->key_frame; - LocalFrame.PictType = av_get_picture_type_char(Frame->pict_type); - LocalFrame.RepeatPict = Frame->repeat_pict; - LocalFrame.InterlacedFrame = Frame->interlaced_frame; - LocalFrame.TopFieldFirst = Frame->top_field_first; - LocalFrame.ColorSpace = OutputColorSpaceSet ? OutputColorSpace : Frame->colorspace; - LocalFrame.ColorRange = OutputColorRangeSet ? OutputColorRange : Frame->color_range; - LocalFrame.ColorPrimaries = (OutputColorPrimaries >= 0) ? OutputColorPrimaries : Frame->color_primaries; - LocalFrame.TransferCharateristics = (OutputTransferCharateristics >= 0) ? OutputTransferCharateristics : Frame->color_trc; - LocalFrame.ChromaLocation = (OutputChromaLocation >= 0) ? OutputChromaLocation : Frame->chroma_location; - - const AVFrameSideData *MasteringDisplaySideData = av_frame_get_side_data(Frame, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA); - if (MasteringDisplaySideData) { - const AVMasteringDisplayMetadata *MasteringDisplay = reinterpret_cast(MasteringDisplaySideData->data); - if (MasteringDisplay->has_primaries) { - LocalFrame.HasMasteringDisplayPrimaries = MasteringDisplay->has_primaries; - for (int i = 0; i < 3; i++) { - LocalFrame.MasteringDisplayPrimariesX[i] = av_q2d(MasteringDisplay->display_primaries[i][0]); - LocalFrame.MasteringDisplayPrimariesY[i] = av_q2d(MasteringDisplay->display_primaries[i][1]); - } - LocalFrame.MasteringDisplayWhitePointX = av_q2d(MasteringDisplay->white_point[0]); - LocalFrame.MasteringDisplayWhitePointY = av_q2d(MasteringDisplay->white_point[1]); - } - if (MasteringDisplay->has_luminance) { - LocalFrame.HasMasteringDisplayLuminance = MasteringDisplay->has_luminance; - LocalFrame.MasteringDisplayMinLuminance = av_q2d(MasteringDisplay->min_luminance); - LocalFrame.MasteringDisplayMaxLuminance = av_q2d(MasteringDisplay->max_luminance); - } - } - LocalFrame.HasMasteringDisplayPrimaries = !!LocalFrame.MasteringDisplayPrimariesX[0] && !!LocalFrame.MasteringDisplayPrimariesY[0] && - !!LocalFrame.MasteringDisplayPrimariesX[1] && !!LocalFrame.MasteringDisplayPrimariesY[1] && - !!LocalFrame.MasteringDisplayPrimariesX[2] && !!LocalFrame.MasteringDisplayPrimariesY[2] && - !!LocalFrame.MasteringDisplayWhitePointX && !!LocalFrame.MasteringDisplayWhitePointY; - /* MasteringDisplayMinLuminance can be 0 */ - LocalFrame.HasMasteringDisplayLuminance = !!LocalFrame.MasteringDisplayMaxLuminance; - - const AVFrameSideData *DolbyVisionRPUSideData = av_frame_get_side_data(Frame, AV_FRAME_DATA_DOVI_RPU_BUFFER); - if (DolbyVisionRPUSideData) { - if (DolbyVisionRPUSideData->size > RPUBufferSize) { - void *tmp = av_realloc(RPUBuffer, DolbyVisionRPUSideData->size); - if (!tmp) - throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_ALLOCATION_FAILED, - "Could not allocate RPU buffer."); - RPUBuffer = reinterpret_cast(tmp); - RPUBufferSize = DolbyVisionRPUSideData->size; - } - - memcpy(RPUBuffer, DolbyVisionRPUSideData->data, DolbyVisionRPUSideData->size); - - LocalFrame.DolbyVisionRPU = RPUBuffer; - LocalFrame.DolbyVisionRPUSize = DolbyVisionRPUSideData->size; - } - -#if VERSION_CHECK(LIBAVUTIL_VERSION_INT, >=, 58, 5, 100) - AVFrameSideData *HDR10PlusSideData = av_frame_get_side_data(Frame, AV_FRAME_DATA_DYNAMIC_HDR_PLUS); - if (HDR10PlusSideData) { - uint8_t *T35Buffer = nullptr; - size_t T35Size; - int ret = av_dynamic_hdr_plus_to_t35(reinterpret_cast(HDR10PlusSideData->data), &T35Buffer, &T35Size); - if (ret < 0) - throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_INVALID_ARGUMENT, - "HDR10+ dynamic metadata could not be serialized."); - if (T35Size > HDR10PlusBufferSize) { - void *tmp = av_realloc(HDR10PlusBuffer, T35Size); - if (!tmp) - throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_ALLOCATION_FAILED, - "Could not allocate HDR10+ buffer."); - HDR10PlusBuffer = reinterpret_cast(tmp); - HDR10PlusBufferSize = T35Size; - } - - memcpy(HDR10PlusBuffer, T35Buffer, T35Size); - av_free(T35Buffer); - - LocalFrame.HDR10Plus = HDR10PlusBuffer; - LocalFrame.HDR10PlusSize = T35Size; - } -#endif - - const AVFrameSideData *ContentLightSideData = av_frame_get_side_data(Frame, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL); - if (ContentLightSideData) { - const AVContentLightMetadata *ContentLightLevel = reinterpret_cast(ContentLightSideData->data); - LocalFrame.ContentLightLevelMax = ContentLightLevel->MaxCLL; - LocalFrame.ContentLightLevelAverage = ContentLightLevel->MaxFALL; - } - /* Only check for either of them */ - LocalFrame.HasContentLightLevel = !!LocalFrame.ContentLightLevelMax || !!LocalFrame.ContentLightLevelAverage; - - LastFrameHeight = Frame->height; - LastFrameWidth = Frame->width; - LastFramePixelFormat = (AVPixelFormat) Frame->format; - - return &LocalFrame; -} - -FFMS_VideoSource::FFMS_VideoSource(const char *SourceFile, FFMS_Index &Index, int Track, int Threads, int SeekMode) - : Index(Index), SeekMode(SeekMode) { - - try { - if (Track < 0 || Track >= static_cast(Index.size())) - throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_INVALID_ARGUMENT, - "Out of bounds track index selected"); - - if (Index[Track].TT != FFMS_TYPE_VIDEO) - throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_INVALID_ARGUMENT, - "Not a video track"); - - if (Index[Track].empty()) - throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_INVALID_ARGUMENT, - "Video track contains no frames"); - - if (!Index.CompareFileSignature(SourceFile)) - throw FFMS_Exception(FFMS_ERROR_INDEX, FFMS_ERROR_FILE_MISMATCH, - "The index does not match the source file"); - - Frames = Index[Track]; - VideoTrack = Track; - - if (Threads < 1) - DecodingThreads = (std::min)(std::thread::hardware_concurrency(), 16u); - else - DecodingThreads = Threads; - - DecodeFrame = av_frame_alloc(); - LastDecodedFrame = av_frame_alloc(); - - if (!DecodeFrame || !LastDecodedFrame) - throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_ALLOCATION_FAILED, - "Could not allocate dummy frame."); - - // Dummy allocations so the unallocated case doesn't have to be handled later - if (av_image_alloc(SWSFrameData, SWSFrameLinesize, 16, 16, AV_PIX_FMT_GRAY8, 4) < 0) - throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_ALLOCATION_FAILED, - "Could not allocate dummy frame."); - - LAVFOpenFile(SourceFile, FormatContext, VideoTrack, Index.LAVFOpts); - - auto *Codec = avcodec_find_decoder(FormatContext->streams[VideoTrack]->codecpar->codec_id); - if (Codec == nullptr) - throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC, - "Video codec not found"); - - CodecContext = avcodec_alloc_context3(Codec); - if (CodecContext == nullptr) - throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_ALLOCATION_FAILED, - "Could not allocate video codec context."); - if (avcodec_parameters_to_context(CodecContext, FormatContext->streams[VideoTrack]->codecpar) < 0) - throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC, - "Could not copy video decoder parameters."); - CodecContext->thread_count = DecodingThreads; - CodecContext->has_b_frames = Frames.MaxBFrames; - - // Full explanation by more clever person availale here: https://github.com/Nevcairiel/LAVFilters/issues/113 - if (CodecContext->codec_id == AV_CODEC_ID_H264 && CodecContext->has_b_frames) - CodecContext->has_b_frames = 15; // the maximum possible value for h264 - - if (avcodec_open2(CodecContext, Codec, nullptr) < 0) - throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC, - "Could not open video codec"); - - // Similar yet different to h264 workaround above - // vc1 simply sets has_b_frames to 1 no matter how many there are so instead we set it to the max value - // in order to not confuse our own delay guesses later - // Doesn't affect actual vc1 reordering unlike h264 - if (CodecContext->codec_id == AV_CODEC_ID_VC1 && CodecContext->has_b_frames) - Delay = 7 + (CodecContext->thread_count - 1); // the maximum possible value for vc1 - else - Delay = CodecContext->has_b_frames + (CodecContext->thread_count - 1); // Normal decoder delay - - // Always try to decode a frame to make sure all required parameters are known - int64_t DummyPTS = 0, DummyPos = 0; - DecodeNextFrame(DummyPTS, DummyPos); - - //VP.image_type = VideoInfo::IT_TFF; - VP.FPSDenominator = FormatContext->streams[VideoTrack]->time_base.num; - VP.FPSNumerator = FormatContext->streams[VideoTrack]->time_base.den; - - // sanity check framerate - if (VP.FPSDenominator <= 0 || VP.FPSNumerator <= 0) { - VP.FPSDenominator = 1; - VP.FPSNumerator = 30; - } - - // Calculate the average framerate - size_t TotalFrames = 0; - for (size_t i = 0; i < Frames.size(); i++) - if (!Frames[i].Hidden) - TotalFrames++; - - if (TotalFrames >= 2) { - double PTSDiff = (double)(Frames.back().PTS - Frames.front().PTS); - double TD = (double)(Frames.TB.Den); - double TN = (double)(Frames.TB.Num); - VP.FPSDenominator = (unsigned int)(PTSDiff * TN / TD * 1000.0 / (TotalFrames - 1)); - VP.FPSNumerator = 1000000; - } - - // Set the video properties from the codec context - SetVideoProperties(); - - // Set the SAR from the container if the codec SAR is invalid - if (VP.SARNum <= 0 || VP.SARDen <= 0) { - VP.SARNum = FormatContext->streams[VideoTrack]->sample_aspect_ratio.num; - VP.SARDen = FormatContext->streams[VideoTrack]->sample_aspect_ratio.den; - } - - // Set stereoscopic 3d type - VP.Stereo3DType = FFMS_S3D_TYPE_2D; - VP.Stereo3DFlags = 0; - - for (int i = 0; i < FormatContext->streams[VideoTrack]->nb_side_data; i++) { - if (FormatContext->streams[VideoTrack]->side_data[i].type == AV_PKT_DATA_STEREO3D) { - const AVStereo3D *StereoSideData = (const AVStereo3D *)FormatContext->streams[VideoTrack]->side_data[i].data; - VP.Stereo3DType = StereoSideData->type; - VP.Stereo3DFlags = StereoSideData->flags; - } else if (FormatContext->streams[VideoTrack]->side_data[i].type == AV_PKT_DATA_MASTERING_DISPLAY_METADATA) { - const AVMasteringDisplayMetadata *MasteringDisplay = (const AVMasteringDisplayMetadata *)FormatContext->streams[VideoTrack]->side_data[i].data; - if (MasteringDisplay->has_primaries) { - VP.HasMasteringDisplayPrimaries = MasteringDisplay->has_primaries; - for (int i = 0; i < 3; i++) { - VP.MasteringDisplayPrimariesX[i] = av_q2d(MasteringDisplay->display_primaries[i][0]); - VP.MasteringDisplayPrimariesY[i] = av_q2d(MasteringDisplay->display_primaries[i][1]); - } - VP.MasteringDisplayWhitePointX = av_q2d(MasteringDisplay->white_point[0]); - VP.MasteringDisplayWhitePointY = av_q2d(MasteringDisplay->white_point[1]); - } - if (MasteringDisplay->has_luminance) { - VP.HasMasteringDisplayLuminance = MasteringDisplay->has_luminance; - VP.MasteringDisplayMinLuminance = av_q2d(MasteringDisplay->min_luminance); - VP.MasteringDisplayMaxLuminance = av_q2d(MasteringDisplay->max_luminance); - } - - VP.HasMasteringDisplayPrimaries = !!VP.MasteringDisplayPrimariesX[0] && !!VP.MasteringDisplayPrimariesY[0] && - !!VP.MasteringDisplayPrimariesX[1] && !!VP.MasteringDisplayPrimariesY[1] && - !!VP.MasteringDisplayPrimariesX[2] && !!VP.MasteringDisplayPrimariesY[2] && - !!VP.MasteringDisplayWhitePointX && !!VP.MasteringDisplayWhitePointY; - /* MasteringDisplayMinLuminance can be 0 */ - VP.HasMasteringDisplayLuminance = !!VP.MasteringDisplayMaxLuminance; - } else if (FormatContext->streams[VideoTrack]->side_data[i].type == AV_PKT_DATA_CONTENT_LIGHT_LEVEL) { - const AVContentLightMetadata *ContentLightLevel = (const AVContentLightMetadata *)FormatContext->streams[VideoTrack]->side_data[i].data; - - VP.ContentLightLevelMax = ContentLightLevel->MaxCLL; - VP.ContentLightLevelAverage = ContentLightLevel->MaxFALL; - - /* Only check for either of them */ - VP.HasContentLightLevel = !!VP.ContentLightLevelMax || !!VP.ContentLightLevelAverage; - } - } - - // Set rotation - VP.Rotation = 0; - VP.Flip = 0; - int32_t *RotationMatrix = reinterpret_cast(av_stream_get_side_data(FormatContext->streams[VideoTrack], AV_PKT_DATA_DISPLAYMATRIX, nullptr)); - if (RotationMatrix) { - int64_t det = (int64_t)RotationMatrix[0] * RotationMatrix[4] - (int64_t)RotationMatrix[1] * RotationMatrix[3]; - if (det < 0) { - /* Always assume an horizontal flip for simplicity, it can be changed later if rotation is 180. */ - VP.Flip = 1; - - /* Flip the matrix to decouple flip and rotation operations. */ - av_display_matrix_flip(RotationMatrix, 1, 0); - } - - int rot = lround(av_display_rotation_get(RotationMatrix)); - - if (rot == 180 && det < 0) { - /* This is a vertical flip with no rotation. */ - VP.Flip = -1; - } else { - /* It is possible to have a 90/270 rotation and a horizontal flip: - * in this case, the rotation angle applies to the video frame - * (rather than the rendering frame), so add this step to nullify - * the conversion below. */ - if (VP.Flip) - rot *= -1; - - /* Return a positive value, noting that this converts angles - * from the rendering frame to the video frame. */ - VP.Rotation = -rot; - if (VP.Rotation < 0) - VP.Rotation += 360; - } - } - - if (SeekMode >= 0 && Frames.size() > 1) { - if (Seek(0) < 0) { - throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC, - "Video track is unseekable"); - } else { - avcodec_flush_buffers(CodecContext); - // Since we seeked to frame 0 we need to specify that frame 0 is once again the next frame that wil be decoded - CurrentFrame = 0; - } - } - - // Cannot "output" without doing all other initialization - // This is the additional mess required for seekmode=-1 to work in a reasonable way - OutputFrame(DecodeFrame); - - if (LocalFrame.HasMasteringDisplayPrimaries) { - VP.HasMasteringDisplayPrimaries = LocalFrame.HasMasteringDisplayPrimaries; - for (int i = 0; i < 3; i++) { - VP.MasteringDisplayPrimariesX[i] = LocalFrame.MasteringDisplayPrimariesX[i]; - VP.MasteringDisplayPrimariesY[i] = LocalFrame.MasteringDisplayPrimariesY[i]; - } - - // Simply copy this from the first frame to make it easier to access - VP.MasteringDisplayWhitePointX = LocalFrame.MasteringDisplayWhitePointX; - VP.MasteringDisplayWhitePointY = LocalFrame.MasteringDisplayWhitePointY; - } - if (LocalFrame.HasMasteringDisplayLuminance) { - VP.HasMasteringDisplayLuminance = LocalFrame.HasMasteringDisplayLuminance; - VP.MasteringDisplayMinLuminance = LocalFrame.MasteringDisplayMinLuminance; - VP.MasteringDisplayMaxLuminance = LocalFrame.MasteringDisplayMaxLuminance; - } - if (LocalFrame.HasContentLightLevel) { - VP.HasContentLightLevel = LocalFrame.HasContentLightLevel; - VP.ContentLightLevelMax = LocalFrame.ContentLightLevelMax; - VP.ContentLightLevelAverage = LocalFrame.ContentLightLevelAverage; - } - } catch (FFMS_Exception &) { - Free(); - throw; - } -} - -FFMS_VideoSource::~FFMS_VideoSource() { - Free(); -} - -FFMS_Frame *FFMS_VideoSource::GetFrameByTime(double Time) { - int Frame = Frames.ClosestFrameFromPTS(static_cast((Time * 1000 * Frames.TB.Den) / Frames.TB.Num)); - return GetFrame(Frame); -} - -static AVColorRange handle_jpeg(AVPixelFormat *format) { - switch (*format) { - case AV_PIX_FMT_YUVJ420P: *format = AV_PIX_FMT_YUV420P; return AVCOL_RANGE_JPEG; - case AV_PIX_FMT_YUVJ422P: *format = AV_PIX_FMT_YUV422P; return AVCOL_RANGE_JPEG; - case AV_PIX_FMT_YUVJ444P: *format = AV_PIX_FMT_YUV444P; return AVCOL_RANGE_JPEG; - case AV_PIX_FMT_YUVJ440P: *format = AV_PIX_FMT_YUV440P; return AVCOL_RANGE_JPEG; - default: return AVCOL_RANGE_UNSPECIFIED; - } -} - -void FFMS_VideoSource::SetOutputFormat(const AVPixelFormat *TargetFormats, int Width, int Height, int Resizer) { - TargetWidth = Width; - TargetHeight = Height; - TargetResizer = Resizer; - TargetPixelFormats.clear(); - while (*TargetFormats != AV_PIX_FMT_NONE) - TargetPixelFormats.push_back(*TargetFormats++); - OutputColorSpaceSet = true; - OutputColorRangeSet = true; - OutputFormat = AV_PIX_FMT_NONE; - - ReAdjustOutputFormat(DecodeFrame); - OutputFrame(DecodeFrame); -} - -void FFMS_VideoSource::SetInputFormat(int ColorSpace, int ColorRange, AVPixelFormat Format) { - InputFormatOverridden = true; - - if (Format != AV_PIX_FMT_NONE) - InputFormat = Format; - if (ColorRange != AVCOL_RANGE_UNSPECIFIED) - InputColorRange = (AVColorRange)ColorRange; - if (ColorSpace != AVCOL_SPC_UNSPECIFIED) - InputColorSpace = (AVColorSpace)ColorSpace; - - if (TargetPixelFormats.size()) { - ReAdjustOutputFormat(DecodeFrame); - OutputFrame(DecodeFrame); - } -} - -void FFMS_VideoSource::DetectInputFormat() { - if (InputFormat == AV_PIX_FMT_NONE) - InputFormat = CodecContext->pix_fmt; - - AVColorRange RangeFromFormat = handle_jpeg(&InputFormat); - - if (InputColorRange == AVCOL_RANGE_UNSPECIFIED) - InputColorRange = RangeFromFormat; - if (InputColorRange == AVCOL_RANGE_UNSPECIFIED) - InputColorRange = CodecContext->color_range; - - if (InputColorSpace == AVCOL_SPC_UNSPECIFIED) - InputColorSpace = CodecContext->colorspace; -} - -void FFMS_VideoSource::ReAdjustOutputFormat(AVFrame *Frame) { - if (SWS) { - sws_freeContext(SWS); - SWS = nullptr; - } - - DetectInputFormat(); - - OutputFormat = FindBestPixelFormat(TargetPixelFormats, InputFormat); - if (OutputFormat == AV_PIX_FMT_NONE) { - ResetOutputFormat(); - throw FFMS_Exception(FFMS_ERROR_SCALING, FFMS_ERROR_INVALID_ARGUMENT, - "No suitable output format found"); - } - - OutputColorRange = handle_jpeg(&OutputFormat); - if (OutputColorRange == AVCOL_RANGE_UNSPECIFIED) - OutputColorRange = CodecContext->color_range; - if (OutputColorRange == AVCOL_RANGE_UNSPECIFIED) - OutputColorRange = InputColorRange; - - OutputColorSpace = CodecContext->colorspace; - if (OutputColorSpace == AVCOL_SPC_UNSPECIFIED) - OutputColorSpace = InputColorSpace; - - BCSType InputType = GuessCSType(InputFormat); - BCSType OutputType = GuessCSType(OutputFormat); - - if (InputType != OutputType) { - if (OutputType == cRGB) { - OutputColorSpace = AVCOL_SPC_RGB; - OutputColorRange = AVCOL_RANGE_UNSPECIFIED; - OutputColorPrimaries = AVCOL_PRI_UNSPECIFIED; - OutputTransferCharateristics = AVCOL_TRC_UNSPECIFIED; - OutputChromaLocation = AVCHROMA_LOC_UNSPECIFIED; - } else if (OutputType == cYUV) { - OutputColorSpace = AVCOL_SPC_BT470BG; - OutputColorRange = AVCOL_RANGE_MPEG; - OutputColorPrimaries = AVCOL_PRI_UNSPECIFIED; - OutputTransferCharateristics = AVCOL_TRC_UNSPECIFIED; - OutputChromaLocation = AVCHROMA_LOC_LEFT; - } else if (OutputType == cGRAY) { - OutputColorSpace = AVCOL_SPC_UNSPECIFIED; - OutputColorRange = AVCOL_RANGE_UNSPECIFIED; - OutputColorPrimaries = AVCOL_PRI_UNSPECIFIED; - OutputTransferCharateristics = AVCOL_TRC_UNSPECIFIED; - OutputChromaLocation = AVCHROMA_LOC_UNSPECIFIED; - } - } else { - OutputColorPrimaries = -1; - OutputTransferCharateristics = -1; - OutputChromaLocation = -1; - } - - if (InputFormat != OutputFormat || - TargetWidth != CodecContext->width || - TargetHeight != CodecContext->height || - InputColorSpace != OutputColorSpace || - InputColorRange != OutputColorRange) { - SWS = GetSwsContext( - Frame->width, Frame->height, InputFormat, InputColorSpace, InputColorRange, - TargetWidth, TargetHeight, OutputFormat, OutputColorSpace, OutputColorRange, - TargetResizer); - - if (!SWS) { - ResetOutputFormat(); - throw FFMS_Exception(FFMS_ERROR_SCALING, FFMS_ERROR_INVALID_ARGUMENT, - "Failed to allocate SWScale context"); - } - } - - av_freep(&SWSFrameData[0]); - if (av_image_alloc(SWSFrameData, SWSFrameLinesize, TargetWidth, TargetHeight, OutputFormat, 4) < 0) - throw FFMS_Exception(FFMS_ERROR_SCALING, FFMS_ERROR_ALLOCATION_FAILED, - "Could not allocate frame with new resolution."); -} - -void FFMS_VideoSource::ResetOutputFormat() { - if (SWS) { - sws_freeContext(SWS); - SWS = nullptr; - } - - TargetWidth = -1; - TargetHeight = -1; - TargetPixelFormats.clear(); - - OutputFormat = AV_PIX_FMT_NONE; - OutputColorSpace = AVCOL_SPC_UNSPECIFIED; - OutputColorRange = AVCOL_RANGE_UNSPECIFIED; - OutputColorSpaceSet = false; - OutputColorRangeSet = false; - - OutputFrame(DecodeFrame); -} - -void FFMS_VideoSource::ResetInputFormat() { - InputFormatOverridden = false; - InputFormat = AV_PIX_FMT_NONE; - InputColorSpace = AVCOL_SPC_UNSPECIFIED; - InputColorRange = AVCOL_RANGE_UNSPECIFIED; - - ReAdjustOutputFormat(DecodeFrame); - OutputFrame(DecodeFrame); -} - -void FFMS_VideoSource::SetVideoProperties() { - VP.RFFDenominator = CodecContext->time_base.num; - VP.RFFNumerator = CodecContext->time_base.den; - if (CodecContext->codec_id == AV_CODEC_ID_H264) { - if (VP.RFFNumerator & 1) - VP.RFFDenominator *= 2; - else - VP.RFFNumerator /= 2; - } - VP.NumFrames = Frames.VisibleFrameCount(); - VP.TopFieldFirst = DecodeFrame->top_field_first; - VP.ColorSpace = CodecContext->colorspace; - VP.ColorRange = CodecContext->color_range; - // these pixfmt's are deprecated but still used - if (CodecContext->pix_fmt == AV_PIX_FMT_YUVJ420P || - CodecContext->pix_fmt == AV_PIX_FMT_YUVJ422P || - CodecContext->pix_fmt == AV_PIX_FMT_YUVJ444P - ) - VP.ColorRange = AVCOL_RANGE_JPEG; - - - VP.FirstTime = ((Frames[Frames.RealFrameNumber(0)].PTS * Frames.TB.Num) / (double)Frames.TB.Den) / 1000; - VP.LastTime = ((Frames[Frames.RealFrameNumber(Frames.VisibleFrameCount()-1)].PTS * Frames.TB.Num) / (double)Frames.TB.Den) / 1000; - VP.LastEndTime = (((Frames[Frames.RealFrameNumber(Frames.VisibleFrameCount()-1)].PTS + Frames.LastDuration) * Frames.TB.Num) / (double)Frames.TB.Den) / 1000; - - if (CodecContext->width <= 0 || CodecContext->height <= 0) - throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC, - "Codec returned zero size video"); - - // attempt to correct framerate to the proper NTSC fraction, if applicable - CorrectRationalFramerate(&VP.FPSNumerator, &VP.FPSDenominator); - // correct the timebase, if necessary - CorrectTimebase(&VP, &Frames.TB); - - // Set AR variables - VP.SARNum = CodecContext->sample_aspect_ratio.num; - VP.SARDen = CodecContext->sample_aspect_ratio.den; - - // Set input and output formats now that we have a CodecContext - DetectInputFormat(); - - OutputFormat = InputFormat; - OutputColorSpace = InputColorSpace; - OutputColorRange = InputColorRange; -} - -bool FFMS_VideoSource::HasPendingDelayedFrames() { - if (InitialDecode == -1) { - if (DelayCounter > Delay) { - --DelayCounter; - return true; - } - InitialDecode = 0; - } - return false; -} - -bool FFMS_VideoSource::DecodePacket(AVPacket *Packet) { - std::swap(DecodeFrame, LastDecodedFrame); - avcodec_send_packet(CodecContext, Packet); - - int Ret = avcodec_receive_frame(CodecContext, DecodeFrame); - if (Ret != 0) { - std::swap(DecodeFrame, LastDecodedFrame); - if (!(Packet->flags & AV_PKT_FLAG_DISCARD)) - DelayCounter++; - } else if (!!(Packet->flags & AV_PKT_FLAG_DISCARD)) { - // If sending discarded frame when the decode buffer is not empty, caller - // may still obtained bufferred decoded frames and the number of frames - // in the buffer decreases. - DelayCounter--; - } - - if (Ret == 0 && InitialDecode == 1) - InitialDecode = -1; - - // H.264 (PAFF) and HEVC can have one field per packet, and decoding delay needs - // to be adjusted accordingly. - if (CodecContext->codec_id == AV_CODEC_ID_H264 || CodecContext->codec_id == AV_CODEC_ID_HEVC) { - if (LastDecodedFrame->interlaced_frame == 1) - HaveSeenInterlacedFrame = true; - if (!PAFFAdjusted && DelayCounter > Delay && HaveSeenInterlacedFrame && LastDecodedFrame->repeat_pict == 0 && Ret != 0) { - int OldBFrameDelay = Delay - (CodecContext->thread_count - 1); - Delay = 1 + OldBFrameDelay * 2 + (CodecContext->thread_count - 1); - PAFFAdjusted = true; - } - } - - return (Ret == 0) || (DelayCounter > Delay && !InitialDecode); -} - -int FFMS_VideoSource::Seek(int n) { - int ret = -1; - - DelayCounter = 0; - InitialDecode = 1; - - if (!SeekByPos || Frames[n].FilePos < 0) { - ret = av_seek_frame(FormatContext, VideoTrack, Frames[n].PTS, AVSEEK_FLAG_BACKWARD); - if (ret >= 0) - return ret; - } - - if (Frames[n].FilePos >= 0) { - ret = av_seek_frame(FormatContext, VideoTrack, Frames[n].FilePos + PosOffset, AVSEEK_FLAG_BYTE); - if (ret >= 0) - SeekByPos = true; - } - return ret; -} - -int FFMS_VideoSource::ReadFrame(AVPacket *pkt) { - int ret = av_read_frame(FormatContext, pkt); - if (ret >= 0 || ret == AVERROR(EOF)) return ret; - - // Lavf reports the beginning of the actual video data as the packet's - // position, but the reader requires the header, so we end up seeking - // to the wrong position. Wait until a read actual fails to adjust the - // seek targets, so that if this ever gets fixed upstream our workaround - // doesn't re-break it. - if (strcmp(FormatContext->iformat->name, "yuv4mpegpipe") == 0) { - PosOffset = -6; - Seek(CurrentFrame); - return av_read_frame(FormatContext, pkt); - } - return ret; -} - -void FFMS_VideoSource::Free() { - av_freep(&RPUBuffer); - av_freep(&HDR10PlusBuffer); - avcodec_free_context(&CodecContext); - avformat_close_input(&FormatContext); - if (SWS) - sws_freeContext(SWS); - av_freep(&SWSFrameData[0]); - av_frame_free(&DecodeFrame); - av_frame_free(&LastDecodedFrame); -} - -void FFMS_VideoSource::DecodeNextFrame(int64_t &AStartTime, int64_t &Pos) { - AStartTime = -1; - - if (HasPendingDelayedFrames()) - return; - - AVPacket *Packet = av_packet_alloc(); - if (!Packet) - throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_ALLOCATION_FAILED, - "Could not allocate packet."); - - int ret; - while ((ret = ReadFrame(Packet)) >= 0) { - if (Packet->stream_index != VideoTrack) { - av_packet_unref(Packet); - continue; - } - - if (AStartTime < 0) - AStartTime = Frames.UseDTS ? Packet->dts : Packet->pts; - - if (Pos < 0) - Pos = Packet->pos; - - bool FrameFinished = DecodePacket(Packet); - av_packet_unref(Packet); - if (FrameFinished) { - av_packet_free(&Packet); - return; - } - } - if (IsIOError(ret)) { - char err[1024]; - av_strerror(ret, err, 1024); - std::string serr(err); - throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_FILE_READ, - "Failed to read packet: " + serr); - } - - // Flush final frames - DecodePacket(Packet); - av_packet_free(&Packet); -} - -bool FFMS_VideoSource::SeekTo(int n, int SeekOffset) { - if (SeekMode >= 0) { - int TargetFrame = n + SeekOffset; - if (TargetFrame < 0) - throw FFMS_Exception(FFMS_ERROR_SEEKING, FFMS_ERROR_UNKNOWN, - "Frame accurate seeking is not possible in this file"); - - if (SeekMode < 3) - TargetFrame = Frames.FindClosestVideoKeyFrame(TargetFrame); - - if (SeekMode == 0) { - if (n < CurrentFrame) { - Seek(0); - avcodec_flush_buffers(CodecContext); - CurrentFrame = 0; - } - } else { - // 10 frames is used as a margin to prevent excessive seeking since the predicted best keyframe isn't always selected by avformat - if (n < CurrentFrame || TargetFrame > CurrentFrame + 10 || (SeekMode == 3 && n > CurrentFrame + 10)) { - Seek(TargetFrame); - avcodec_flush_buffers(CodecContext); - return true; - } - } - } else if (n < CurrentFrame) { - throw FFMS_Exception(FFMS_ERROR_SEEKING, FFMS_ERROR_INVALID_ARGUMENT, - "Non-linear access attempted"); - } - return false; -} - -FFMS_Frame *FFMS_VideoSource::GetFrame(int n) { - GetFrameCheck(n); - n = Frames.RealFrameNumber(n); - - if (LastFrameNum == n) - return &LocalFrame; - - int SeekOffset = 0; - bool Seek = true; - - do { - bool HasSeeked = false; - if (Seek) { - HasSeeked = SeekTo(n, SeekOffset); - Seek = false; - } - - int64_t StartTime = AV_NOPTS_VALUE, FilePos = -1; - bool Hidden = (((unsigned) CurrentFrame < Frames.size()) && Frames[CurrentFrame].Hidden); - if (HasSeeked || !Hidden || PAFFAdjusted) - DecodeNextFrame(StartTime, FilePos); - - if (!HasSeeked) - continue; - - if (StartTime == AV_NOPTS_VALUE && !Frames.HasTS) { - if (FilePos >= 0) { - CurrentFrame = Frames.FrameFromPos(FilePos); - if (CurrentFrame >= 0) - continue; - } - // If the track doesn't have timestamps or file positions then - // just trust that we got to the right place, since we have no - // way to tell where we are - else { - CurrentFrame = n; - continue; - } - } - - CurrentFrame = Frames.FrameFromPTS(StartTime); - - // Is the seek destination time known? Does it belong to a frame? - if (CurrentFrame < 0) { - if (SeekMode == 1 || StartTime < 0) { - // No idea where we are so go back a bit further - SeekOffset -= 10; - Seek = true; - continue; - } - CurrentFrame = Frames.ClosestFrameFromPTS(StartTime); - } - - // We want to know the frame number that we just got out of the decoder, - // but what we currently know is the frame number of the first packet - // we fed into the decoder, and these can be different with open-gop or - // aggressive (non-keyframe) seeking. - int64_t Pos = Frames[CurrentFrame].FilePos; - if (CurrentFrame > 0 && Pos != -1) { - int Prev = CurrentFrame - 1; - while (Prev >= 0 && Frames[Prev].FilePos != -1 && Frames[Prev].FilePos > Pos) - --Prev; - CurrentFrame = Prev + 1; - } - } while (++CurrentFrame <= n); - - LastFrameNum = n; - return OutputFrame(DecodeFrame); -} diff --git a/thirdparty/ffms2/src/core/videosource.h b/thirdparty/ffms2/src/core/videosource.h deleted file mode 100644 index 760532ed7..000000000 --- a/thirdparty/ffms2/src/core/videosource.h +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (c) 2007-2017 Fredrik Mellbin -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#ifndef FFVIDEOSOURCE_H -#define FFVIDEOSOURCE_H - -extern "C" { -#include -#include -#include -#include -#include -#include -#include - -#include "ffmscompat.h" -#if VERSION_CHECK(LIBAVUTIL_VERSION_INT, >=, 58, 5, 100) -#include -#endif -} - -#include - -#include "track.h" -#include "utils.h" - -struct FFMS_VideoSource { -private: - SwsContext *SWS = nullptr; - - int Delay = 0; - int DelayCounter = 0; - int InitialDecode = 1; - bool PAFFAdjusted = false; - - int LastFrameHeight = -1; - int LastFrameWidth = -1; - AVPixelFormat LastFramePixelFormat = AV_PIX_FMT_NONE; - - int TargetHeight = -1; - int TargetWidth = -1; - std::vector TargetPixelFormats; - int TargetResizer = 0; - - AVPixelFormat OutputFormat = AV_PIX_FMT_NONE; - AVColorRange OutputColorRange = AVCOL_RANGE_UNSPECIFIED; - AVColorSpace OutputColorSpace = AVCOL_SPC_UNSPECIFIED; - bool OutputColorRangeSet = false; - bool OutputColorSpaceSet = false; - - int OutputColorPrimaries = -1; - int OutputTransferCharateristics = -1; - int OutputChromaLocation = -1; - - bool InputFormatOverridden = false; - AVPixelFormat InputFormat = AV_PIX_FMT_NONE; - AVColorRange InputColorRange = AVCOL_RANGE_UNSPECIFIED; - AVColorSpace InputColorSpace = AVCOL_SPC_UNSPECIFIED; - - uint8_t *SWSFrameData[4] = {}; - int SWSFrameLinesize[4] = {}; - - void DetectInputFormat(); - bool HasPendingDelayedFrames(); - - FFMS_VideoProperties VP = {}; - FFMS_Frame LocalFrame = {}; - uint8_t *RPUBuffer = nullptr; - size_t RPUBufferSize = 0; - uint8_t *HDR10PlusBuffer = nullptr; - size_t HDR10PlusBufferSize = 0; - AVFrame *DecodeFrame = nullptr; - AVFrame *LastDecodedFrame = nullptr; - int LastFrameNum = 0; - FFMS_Index &Index; - FFMS_Track Frames; - int VideoTrack; - int CurrentFrame = 1; - int DecodingThreads; - AVCodecContext *CodecContext = nullptr; - AVFormatContext *FormatContext = nullptr; - int SeekMode; - bool SeekByPos = false; - int PosOffset = 0; - bool HaveSeenInterlacedFrame = false; - - void ReAdjustOutputFormat(AVFrame *Frame); - FFMS_Frame *OutputFrame(AVFrame *Frame); - void SetVideoProperties(); - bool DecodePacket(AVPacket *Packet); - void DecodeNextFrame(int64_t &PTS, int64_t &Pos); - bool SeekTo(int n, int SeekOffset); - int Seek(int n); - int ReadFrame(AVPacket *pkt); - void Free(); - static void SanityCheckFrameForData(AVFrame *Frame); -public: - FFMS_VideoSource(const char *SourceFile, FFMS_Index &Index, int Track, int Threads, int SeekMode); - ~FFMS_VideoSource(); - const FFMS_VideoProperties& GetVideoProperties() { return VP; } - FFMS_Track *GetTrack() { return &Frames; } - FFMS_Frame *GetFrame(int n); - void GetFrameCheck(int n); - FFMS_Frame *GetFrameByTime(double Time); - void SetOutputFormat(const AVPixelFormat *TargetFormats, int Width, int Height, int Resizer); - void ResetOutputFormat(); - void SetInputFormat(int ColorSpace, int ColorRange, AVPixelFormat Format); - void ResetInputFormat(); -}; - -#endif diff --git a/thirdparty/ffms2/src/core/videoutils.cpp b/thirdparty/ffms2/src/core/videoutils.cpp deleted file mode 100644 index 4b5b1fd60..000000000 --- a/thirdparty/ffms2/src/core/videoutils.cpp +++ /dev/null @@ -1,260 +0,0 @@ -// Copyright (c) 2007-2015 The FFmpegSource Project -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - - -#include "videoutils.h" - -#include -#include - -/* if you have this, we'll assume you have a new enough libavutil too */ -extern "C" { -#include -} - -SwsContext *GetSwsContext(int SrcW, int SrcH, AVPixelFormat SrcFormat, int SrcColorSpace, int SrcColorRange, int DstW, int DstH, AVPixelFormat DstFormat, int DstColorSpace, int DstColorRange, int64_t Flags) { - Flags |= SWS_FULL_CHR_H_INT | SWS_FULL_CHR_H_INP | SWS_ACCURATE_RND; - SwsContext *Context = sws_alloc_context(); - if (!Context) return nullptr; - - // 0 = limited range, 1 = full range - int SrcRange = SrcColorRange == AVCOL_RANGE_JPEG; - if (SrcColorRange == AVCOL_RANGE_UNSPECIFIED) - SrcRange = (GuessCSType(SrcFormat) != cYUV); - int DstRange = DstColorRange == AVCOL_RANGE_JPEG; - if (DstColorRange == AVCOL_RANGE_UNSPECIFIED) - DstRange = (GuessCSType(DstFormat) != cYUV); - - av_opt_set_int(Context, "sws_flags", Flags, 0); - av_opt_set_int(Context, "srcw", SrcW, 0); - av_opt_set_int(Context, "srch", SrcH, 0); - av_opt_set_int(Context, "dstw", DstW, 0); - av_opt_set_int(Context, "dsth", DstH, 0); - av_opt_set_int(Context, "src_range", SrcRange, 0); - av_opt_set_int(Context, "dst_range", DstRange, 0); - av_opt_set_int(Context, "src_format", SrcFormat, 0); - av_opt_set_int(Context, "dst_format", DstFormat, 0); - - sws_setColorspaceDetails(Context, - sws_getCoefficients(SrcColorSpace), SrcRange, - sws_getCoefficients(DstColorSpace), DstRange, - 0, 1 << 16, 1 << 16); - - if (sws_init_context(Context, nullptr, nullptr) < 0) { - sws_freeContext(Context); - return nullptr; - } - - return Context; -} - -/*************************** -** -** Two functions for making FFMS pretend it's not quite as VFR-based as it really is. -** -***************************/ - - -// attempt to correct framerate to a common fraction if close to one -void CorrectRationalFramerate(int *Num, int *Den) { - // Make sure fps is a normalized rational number - av_reduce(Den, Num, *Den, *Num, INT_MAX); - - const double fps = static_cast(*Num) / *Den; - const int fpsList[] = { 24, 25, 30, 48, 50, 60, 100, 120 }; - - for (size_t i = 0; i < sizeof(fpsList) / sizeof(fpsList[0]); i++) { - const double delta = (fpsList[i] - static_cast(fpsList[i]) / 1.001) / 2.0; - if (fabs(fps - fpsList[i]) < delta) { - *Num = fpsList[i]; - *Den = 1; - break; - } else if ((fpsList[i] % 25) && (fabs(fps - static_cast(fpsList[i]) / 1.001) < delta)) { - *Num = fpsList[i] * 1000; - *Den = 1001; - break; - } - } -} - -// correct the timebase if it is invalid -void CorrectTimebase(FFMS_VideoProperties *VP, FFMS_TrackTimeBase *TTimebase) { - double Timebase = (double)TTimebase->Num / TTimebase->Den; - double FPS = (double)VP->FPSNumerator / VP->FPSDenominator; - if ((1000 / Timebase) / FPS < 1) { - TTimebase->Den = VP->FPSNumerator; - TTimebase->Num = (int64_t)VP->FPSDenominator * 1000; - } -} - -/*************************** -** -** Since avcodec_find_best_pix_fmt() is broken, we have our own implementation of it here. -** -***************************/ - -BCSType GuessCSType(AVPixelFormat p) { - // guessing the colorspace type from the name is kinda hackish but libav doesn't export this kind of metadata - // special case since pal8 is assumed to be rgb32 - if (p == AV_PIX_FMT_PAL8) - return cRGB; - if (av_pix_fmt_desc_get(p)->flags & AV_PIX_FMT_FLAG_HWACCEL) - return cUNUSABLE; - if (av_pix_fmt_desc_get(p)->flags & AV_PIX_FMT_FLAG_PAL) - return cUNUSABLE; - if (av_pix_fmt_desc_get(p)->flags & AV_PIX_FMT_FLAG_RGB) - return cRGB; - if (av_pix_fmt_desc_get(p)->nb_components <= 2) - return cGRAY; - if (av_pix_fmt_desc_get(p)->nb_components >= 3) - return cYUV; - return cUNUSABLE; // should never come here -} - -struct LossAttributes { - AVPixelFormat Format; - int ChromaUndersampling; - int ChromaOversampling; - int DepthDifference; - int CSLoss; // 0 = no difference, 1 = unused, 2 = full conversion required, 3 = alpha loss, 4 = full conversion plus alpha loss, 5 = complete color loss - int CSGain; // alpha plane added, gray converted to yuv/rgb -}; - -static int GetPseudoDepth(const AVPixFmtDescriptor &Desc) { - // Comparing the pseudo depth makes sure that rgb565-ish formats get selected over rgb555-ish ones - int depth = 0; - for (int i = 0; i < Desc.nb_components; i++) - depth = FFMAX(depth, Desc.comp[i].depth); - return depth; -} - -static LossAttributes CalculateLoss(AVPixelFormat Dst, AVPixelFormat Src) { - const AVPixFmtDescriptor &SrcDesc = *av_pix_fmt_desc_get(Src); - const AVPixFmtDescriptor &DstDesc = *av_pix_fmt_desc_get(Dst); - BCSType SrcCS = GuessCSType(Src); - BCSType DstCS = GuessCSType(Dst); - - LossAttributes Loss; - Loss.Format = Dst; - Loss.DepthDifference = GetPseudoDepth(DstDesc) - GetPseudoDepth(SrcDesc); - Loss.ChromaOversampling = FFMAX(0, SrcDesc.log2_chroma_h - DstDesc.log2_chroma_h) + FFMAX(0, SrcDesc.log2_chroma_w - DstDesc.log2_chroma_w); - Loss.ChromaUndersampling = FFMAX(0, DstDesc.log2_chroma_h - SrcDesc.log2_chroma_h) + FFMAX(0, DstDesc.log2_chroma_w - SrcDesc.log2_chroma_w); - Loss.CSGain = 0; - - if (SrcCS == DstCS) { - Loss.CSLoss = 0; - } else if (SrcCS == cGRAY) { - Loss.CSGain = 1; - Loss.ChromaOversampling = 0; - Loss.ChromaUndersampling = 0; - Loss.CSLoss = 0; - } else if (DstCS == cGRAY) { - Loss.ChromaOversampling = 0; - Loss.ChromaUndersampling = 0; - Loss.CSLoss = 5; - } else { - Loss.CSLoss = 2; - } - - if (Loss.CSLoss < 3 && (DstDesc.nb_components == SrcDesc.nb_components - 1)) { - if (Loss.CSLoss == 2) - Loss.CSLoss = 4; - else - Loss.CSLoss = 3; - } - - // Added alpha plane - if (Loss.CSLoss == 0 && (SrcDesc.nb_components == DstDesc.nb_components - 1)) { - Loss.CSGain = 1; - } - - return Loss; -} - -AVPixelFormat FindBestPixelFormat(const std::vector &Dsts, AVPixelFormat Src) { - // some trivial special cases to make sure there's as little conversion as possible - if (Dsts.empty()) - return AV_PIX_FMT_NONE; - if (Dsts.size() == 1) - return Dsts[0]; - - // is the input in the output? - auto i = std::find(Dsts.begin(), Dsts.end(), Src); - if (i != Dsts.end()) - return Src; - - // If it's an evil paletted format pretend it's normal RGB when calculating loss - if (Src == AV_PIX_FMT_PAL8) - Src = AV_PIX_FMT_RGB32; - - std::vector OutputDsts; - for (auto DstFmt = Dsts.begin(); DstFmt != Dsts.end(); ++DstFmt) { - // Skip outputing to formwats we can't convert to, this avoids swscale init failures later in the code - if (sws_isSupportedOutput(*DstFmt)) - OutputDsts.push_back(*DstFmt); - } - - if (OutputDsts.empty()) - return AV_PIX_FMT_NONE; - - i = OutputDsts.begin(); - LossAttributes Loss = CalculateLoss(*i++, Src); - for (; i != OutputDsts.end(); ++i) { - LossAttributes CLoss = CalculateLoss(*i, Src); - if (Loss.CSLoss >= 3 && CLoss.CSLoss < Loss.CSLoss) { // favor the same color format output - Loss = CLoss; - } else if (Loss.DepthDifference >= 0 && CLoss.DepthDifference >= 0) { // focus on chroma undersamling and conversion loss if the target depth has been achieved - if ((CLoss.ChromaUndersampling < Loss.ChromaUndersampling) - || (CLoss.ChromaUndersampling == Loss.ChromaUndersampling && CLoss.CSLoss < Loss.CSLoss) - || (CLoss.ChromaUndersampling == Loss.ChromaUndersampling && CLoss.CSLoss == Loss.CSLoss && CLoss.DepthDifference < Loss.DepthDifference) - || (CLoss.ChromaUndersampling == Loss.ChromaUndersampling && CLoss.CSLoss == Loss.CSLoss - && CLoss.DepthDifference == Loss.DepthDifference && CLoss.ChromaOversampling < Loss.ChromaOversampling)) - Loss = CLoss; - } else { // put priority on reaching the same depth as the input - if ((CLoss.DepthDifference > Loss.DepthDifference) - || (CLoss.DepthDifference == Loss.DepthDifference && CLoss.ChromaUndersampling < Loss.ChromaUndersampling) - || (CLoss.DepthDifference == Loss.DepthDifference && CLoss.ChromaUndersampling == Loss.ChromaUndersampling && CLoss.CSLoss < Loss.CSLoss) - || (CLoss.DepthDifference == Loss.DepthDifference && CLoss.ChromaUndersampling == Loss.ChromaUndersampling - && CLoss.CSLoss == Loss.CSLoss && CLoss.ChromaOversampling < Loss.ChromaOversampling)) - Loss = CLoss; - else if (CLoss.DepthDifference == Loss.DepthDifference && CLoss.ChromaUndersampling == Loss.ChromaUndersampling - && CLoss.CSLoss == Loss.CSLoss && CLoss.ChromaOversampling == Loss.ChromaOversampling && CLoss.CSGain < Loss.CSGain) - Loss = CLoss; - } - } - - return Loss.Format; -} - -void ParseVP8(const uint8_t Buf, bool *Invisible, int *PictType) { - *PictType = (Buf & 0x01) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I; - *Invisible = (*Invisible || !(Buf & 0x10)); -} - -void ParseVP9(const uint8_t Buf, int *PictType) -{ - int profile = ((Buf & 0x20) >> 5) | ((Buf & 0x10) >> 3); - int shift = (profile == 3); - - if (Buf & (0x8 >> shift)) - *PictType = AV_PICTURE_TYPE_P; - else - *PictType = (Buf & (0x4 >> shift)) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I; -} diff --git a/thirdparty/ffms2/src/core/videoutils.h b/thirdparty/ffms2/src/core/videoutils.h deleted file mode 100644 index a9bc65602..000000000 --- a/thirdparty/ffms2/src/core/videoutils.h +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2007-2015 The FFmpegSource Project -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -extern "C" { -#include -#include -#include -#include -#include -} -// must be included after ffmpeg headers -#include "ffmscompat.h" - -#include - -#include "ffms.h" - -enum BCSType { - cGRAY, - cYUV, - cRGB, - cUNUSABLE -}; - -// swscale and pp-related functions -SwsContext *GetSwsContext(int SrcW, int SrcH, AVPixelFormat SrcFormat, int SrcColorSpace, int SrcColorRange, int DstW, int DstH, AVPixelFormat DstFormat, int DstColorSpace, int DstColorRange, int64_t Flags); -BCSType GuessCSType(AVPixelFormat p); - -// timebase-related functions -void CorrectRationalFramerate(int *Num, int *Den); -void CorrectTimebase(FFMS_VideoProperties *VP, FFMS_TrackTimeBase *TTimebase); - -// our implementation of avcodec_find_best_pix_fmt() -AVPixelFormat FindBestPixelFormat(const std::vector &Dsts, AVPixelFormat Src); - -// handling of alt-refs in VP8 and VP9 -void ParseVP8(const uint8_t Buf, bool *Invisible, int *PictType); -void ParseVP9(const uint8_t Buf, int *PictType); diff --git a/thirdparty/ffms2/src/core/zipfile.cpp b/thirdparty/ffms2/src/core/zipfile.cpp deleted file mode 100644 index 048f97ee9..000000000 --- a/thirdparty/ffms2/src/core/zipfile.cpp +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright (c) 2014 Thomas Goyne -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#include "zipfile.h" - -extern "C" { -#include -} - -#include "utils.h" - -ZipFile::ZipFile(const char *filename, const char *mode) - : file(filename, mode, FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ) - , is_file(true) - , state(Initial) { - buffer.resize(65536); - z = {}; -} - -ZipFile::ZipFile() - : is_file(false) - , state(Initial) { - buffer.resize(65536); - z = {}; -} - -ZipFile::ZipFile(const uint8_t *in_buffer, const size_t size) - : index_buffer(in_buffer, in_buffer + size) - , is_file(false) - , state(Initial) { - z = {}; -} - -ZipFile::~ZipFile() { - if (state == Inflate) - inflateEnd(&z); - if (state == Deflate) - deflateEnd(&z); -} - -void ZipFile::Read(void *data, size_t size) { - if (state == Deflate) { - deflateEnd(&z); - state = Initial; - } - if (state != Inflate) { - if (inflateInit(&z) != Z_OK) - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, "Failed to initialize zlib"); - state = Inflate; - } - - z.next_out = static_cast(data); - z.avail_out = size; - if (!z.avail_in && !is_file) { - z.next_in = reinterpret_cast(&index_buffer[0]); - z.avail_in = index_buffer.size(); - } - do { - if (!z.avail_in && is_file) { - z.next_in = reinterpret_cast(&buffer[0]); - z.avail_in = file.Read(&buffer[0], buffer.size()); - } - if (!z.avail_in) { - if (!is_file) - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, "Failed to read data: Buffer is empty"); - else if (!file.Tell()) - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, "Failed to read data: File is empty"); - } - - switch (inflate(&z, Z_SYNC_FLUSH)) { - case Z_NEED_DICT: - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, "Failed to read data: Dictionary error."); - case Z_DATA_ERROR: - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, "Failed to read data: Data error."); - case Z_MEM_ERROR: - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, "Failed to read data: Memory error."); - case Z_STREAM_END: - if (z.avail_out > 0) - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, "Failed to read data: Stream ended early"); - } - } while (z.avail_out); -} - -int ZipFile::Write(const void *data, size_t size) { - if (state == Inflate) { - inflateEnd(&z); - state = Initial; - } - if (state != Deflate) { - if (deflateInit(&z, 5) != Z_OK) - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_FILE_READ, "Failed to initialize zlib"); - state = Deflate; - } - - z.next_in = static_cast(const_cast(data)); - z.avail_in = size; - int ret = 0; - do { - z.avail_out = buffer.size(); - z.next_out = reinterpret_cast(&buffer[0]); - ret = deflate(&z, size > 0 ? Z_NO_FLUSH : Z_FINISH); - uInt written = buffer.size() - z.avail_out; - if (written) { - if (is_file) - file.Write(&buffer[0], written); - else - index_buffer.insert(index_buffer.end(), &buffer[0], &buffer[written]); - } - } while (z.avail_out == 0); - return ret; -} - -void ZipFile::Finish() { - while (Write(nullptr, 0) != Z_STREAM_END); - deflateEnd(&z); - state = Initial; -} - -uint8_t *ZipFile::GetBuffer(size_t *size) { - uint8_t *ret = (uint8_t *)av_malloc(index_buffer.size()); - if (ret == nullptr) - throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_ALLOCATION_FAILED, "Failed to allocate index return buffer"); - - memcpy(ret, reinterpret_cast(&index_buffer[0]), index_buffer.size()); - *size = index_buffer.size(); - - return ret; -} diff --git a/thirdparty/ffms2/src/core/zipfile.h b/thirdparty/ffms2/src/core/zipfile.h deleted file mode 100644 index ec1eaf26f..000000000 --- a/thirdparty/ffms2/src/core/zipfile.h +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) 2014 Thomas Goyne -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#ifndef ZIPFILE_H -#define ZIPFILE_H - -#include "filehandle.h" - -#include -#include - -class ZipFile { - FileHandle file; - std::vector buffer; - std::vector index_buffer; - bool is_file; - z_stream z; - enum { - Initial, - Inflate, - Deflate - } state; - -public: - ZipFile(const char *filename, const char *mode); - ZipFile(const uint8_t *in_buffer, const size_t size); - ZipFile(); - ~ZipFile(); - - void Read(void *buffer, size_t size); - int Write(const void *buffer, size_t size); - void Finish(); - uint8_t *GetBuffer(size_t *size); - - template - T Read() { - T ret = T(); - Read(&ret, sizeof(T)); - return ret; - } - - template - void Write(T const& value) { - Write(&value, sizeof value); - } -}; - -#endif diff --git a/thirdparty/ffms2/src/index/ffmsindex.cpp b/thirdparty/ffms2/src/index/ffmsindex.cpp deleted file mode 100644 index 9ff2fdae2..000000000 --- a/thirdparty/ffms2/src/index/ffmsindex.cpp +++ /dev/null @@ -1,361 +0,0 @@ -// Copyright (c) 2008-2009 Karl Blomster -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#include "ffms.h" - -#ifdef _WIN32 -#include "vsutf16.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern "C" { -#include -} - -namespace { - -long long IndexMask = 0; -int Verbose = 0; -int IgnoreErrors = 0; -bool Overwrite = false; -bool PrintProgress = true; -bool WriteTC = false; -bool WriteKF = false; -int64_t ProgressInterval = 1000000; // One second -std::vector LAVFOpts; -std::string InputFile; -std::string CacheFile; - -struct Error { - std::string msg; - Error(const char *msg) : msg(msg) {} - Error(const char *msg, FFMS_ErrorInfo const& e) : msg(msg) { - this->msg.append(e.Buffer); - } -}; - -struct Progress { - int Percent; - int64_t Time; -}; - -void PrintUsage() { - std::cout << - "FFmpegSource2 indexing app\n" - "Usage: ffmsindex [options] inputfile [outputfile]\n" - "If no output filename is specified, inputfile.ffindex will be used.\n" - "\n" - "Options:\n" - "-f Force overwriting of existing index file, if any (default: no)\n" - "-v Set FFmpeg verbosity level. Can be repeated for more verbosity. (default: no messages printed)\n" - "-p Disable progress reporting. (default: progress reporting on)\n" - "-c Write timecodes for all video tracks to outputfile_track00.tc.txt (default: no)\n" - "-k Write keyframes for all video tracks to outputfile_track00.kf.txt (default: no)\n" - "-t N Set the audio indexing mask to N (-1 means index all tracks, 0 means index none, default: 0)\n" - "-s N Set audio decoding error handling. See the documentation for details. (default: 0)\n" - "-u N Set the progress update frequency in seconds. Set to 0 for every percent. (default: 1)\n" - "-o string Set demuxer options to be used in the form of 'key=val:key=val'. (default: none)\n" - "\n" - "FFmpeg Demuxer Options:\n" - "--enable_drefs\n" - "--use_absolute_path\n" - << std::endl; -} - -int64_t getTimeInMicroSeconds() { - static std::chrono::time_point StartTime = std::chrono::steady_clock::now(); - std::chrono::time_point Now = std::chrono::steady_clock::now(); - return std::chrono::duration_cast(Now - StartTime).count(); -} - -int64_t parseSecondsToMicroseconds(const char *str) { - double val = std::strtod(str, nullptr); - int64_t ret = (int64_t) (val * 1000000.0); - return ret; -} - -void freeDemuxerOpts() { - for (FFMS_KeyValuePair pair : LAVFOpts) { - free(const_cast(pair.Key)); - free(const_cast(pair.Value)); - } - LAVFOpts.clear(); -} - -std::vector parseDemuxerOpts(const char *str) { - AVDictionary *dict = nullptr; - int ret = av_dict_parse_string(&dict, str, "=", ":", 0); - if (ret < 0) - throw Error("Cannot parse demuxer options."); - - AVDictionaryEntry *en = nullptr; - while ((en = av_dict_get(dict, "", en, AV_DICT_IGNORE_SUFFIX)) != NULL) { - FFMS_KeyValuePair pair; - pair.Key = strdup(en->key); - if (!pair.Key) - goto fail; - pair.Value = strdup(en->value); - if (!pair.Value) { - free(const_cast(pair.Key)); - goto fail; - } - LAVFOpts.push_back(pair); - } - return LAVFOpts; -fail: - freeDemuxerOpts(); - throw Error("Could not allocate key/value pair."); -} - -void ParseCMDLine(int argc, const char *argv[]) { - for (int i = 1; i < argc; ++i) { - const char *Option = argv[i]; -#define OPTION_ARG(dst, flag, parse) try { dst = parse(i + 1 < argc ? argv[i+1] : throw Error("Error: missing argument for -" flag)); i++; } catch (std::logic_error &) { throw Error("Error: invalid argument specified for -" flag); } - - if (!strcmp(Option, "-f")) { - Overwrite = true; - } else if (!strcmp(Option, "-v")) { - Verbose++; - } else if (!strcmp(Option, "-p")) { - PrintProgress = false; - } else if (!strcmp(Option, "-c")) { - WriteTC = true; - } else if (!strcmp(Option, "-k")) { - WriteKF = true; - } else if (!strcmp(Option, "-t")) { - OPTION_ARG(IndexMask, "t", std::stoll); - } else if (!strcmp(Option, "-s")) { - OPTION_ARG(IgnoreErrors, "s", std::stoi); - } else if (!strcmp(Option, "-u")) { - OPTION_ARG(ProgressInterval, "u", parseSecondsToMicroseconds); - } else if (!strcmp(Option, "-o")) { - OPTION_ARG(LAVFOpts, "o", parseDemuxerOpts); - } else if (!strcmp(Option, "--enable_drefs")) { - parseDemuxerOpts("enable_drefs=1"); - } else if (!strcmp(Option, "--use_absolute_path")) { - parseDemuxerOpts("use_absolute_path=1"); - } else if (InputFile.empty()) { - InputFile = Option; - } else if (CacheFile.empty()) { - CacheFile = Option; - } else { - std::cout << "Warning: ignoring unknown option " << Option << std::endl; - } - } - - if (IgnoreErrors < 0 || IgnoreErrors > 3) - throw Error("Error: invalid error handling mode"); - if (InputFile.empty()) - throw Error("Error: no input file specified"); - - if (CacheFile.empty()) { - CacheFile = InputFile; - CacheFile.append(".ffindex"); - } -} - -int FFMS_CC UpdateProgress(int64_t Current, int64_t Total, void *Private) { - if (!PrintProgress) - return 0; - - int Percentage = int((double(Current) / double(Total)) * 100); - - if (Private) { - Progress *LastProgress = (Progress *)Private; - int64_t CurTime = getTimeInMicroSeconds(); - if (Percentage <= LastProgress->Percent || (LastProgress->Time != 0 && (CurTime - LastProgress->Time) <= ProgressInterval)) - return 0; - LastProgress->Percent = Percentage; - LastProgress->Time = CurTime; - } - - std::cout << "Indexing, please wait... " << Percentage << "% \r" << std::flush; - - return 0; -} - -std::string DumpFilename(FFMS_Track *Track, int TrackNum, const char *Suffix) { - if (FFMS_GetTrackType(Track) != FFMS_TYPE_VIDEO || !FFMS_GetNumFrames(Track)) - return ""; - - char tn[11]; - snprintf(tn, 11, "%02" PRIu32"", (uint32_t) TrackNum); - return CacheFile + "_track" + tn + Suffix; -} - -void DoIndexing() { - char ErrorMsg[1024]; - FFMS_ErrorInfo E; - E.Buffer = ErrorMsg; - E.BufferSize = sizeof(ErrorMsg); - - Progress ProgressTracker = { 0, getTimeInMicroSeconds() }; - - FFMS_Index *Index = FFMS_ReadIndex(CacheFile.c_str(), &E); - if (Index) { - FFMS_DestroyIndex(Index); - if (!Overwrite) - throw Error("Error: index file already exists, use -f if you are sure you want to overwrite it."); - } - - UpdateProgress(0, 100, nullptr); - - FFMS_Indexer *Indexer = FFMS_CreateIndexer2(InputFile.c_str(), LAVFOpts.data(), LAVFOpts.size(), &E); - if (Indexer == nullptr) - throw Error("\nFailed to initialize indexing: ", E); - - FFMS_SetProgressCallback(Indexer, UpdateProgress, &ProgressTracker); - - // Treat -1 as meaning track numbers above sizeof(long long) * 8 too, dumping implies indexing - if (IndexMask == -1) - FFMS_TrackTypeIndexSettings(Indexer, FFMS_TYPE_AUDIO, 1, 0); - - // Apply attributes to remaining tracks (will set the attributes again on some tracks) - for (int i = 0; i < static_cast(sizeof(IndexMask) * 8); i++) { - if ((IndexMask >> i) & 1) - FFMS_TrackIndexSettings(Indexer, i, 1, 0); - } - - Index = FFMS_DoIndexing2(Indexer, IgnoreErrors, &E); - - // The indexer is always freed - Indexer = nullptr; - - freeDemuxerOpts(); - - if (Index == nullptr) - throw Error("\nIndexing error: ", E); - - UpdateProgress(100, 100, nullptr); - - std::cout << std::endl; - - if (WriteTC) { - if (PrintProgress) - std::cout << "Writing timecodes... "; - int NumTracks = FFMS_GetNumTracks(Index); - for (int t = 0; t < NumTracks; t++) { - FFMS_Track *Track = FFMS_GetTrackFromIndex(Index, t); - std::string Filename = DumpFilename(Track, t, ".tc.txt"); - if (!Filename.empty()) { - if (FFMS_WriteTimecodes(Track, Filename.c_str(), &E)) - std::cout << std::endl << "Failed to write timecodes file " - << Filename << ": " << E.Buffer << std::endl; - } - } - if (PrintProgress) - std::cout << "done." << std::endl; - } - - if (WriteKF) { - if (PrintProgress) - std::cout << "Writing keyframes... "; - int NumTracks = FFMS_GetNumTracks(Index); - for (int t = 0; t < NumTracks; t++) { - FFMS_Track *Track = FFMS_GetTrackFromIndex(Index, t); - std::string Filename = DumpFilename(Track, t, ".kf.txt"); - if (!Filename.empty()) { - std::ofstream kf(Filename.c_str()); - kf << "# keyframe format v1\n" - "fps 0\n"; - - int FrameCount = FFMS_GetNumFrames(Track); - for (int CurFrameNum = 0; CurFrameNum < FrameCount; CurFrameNum++) { - if (FFMS_GetFrameInfo(Track, CurFrameNum)->KeyFrame) - kf << CurFrameNum << "\n"; - } - } - } - if (PrintProgress) - std::cout << "done. " << std::endl; - } - - if (PrintProgress) - std::cout << "Writing index... "; - - int error = FFMS_WriteIndex(CacheFile.c_str(), Index, &E); - FFMS_DestroyIndex(Index); - if (error) - throw Error("Error writing index: ", E); - - if (PrintProgress) - std::cout << "done." << std::endl; -} - -} // namespace { - -#ifdef _WIN32 -int wmain(int argc, const wchar_t *_argv[]) { - std::vector StringPtrs(argc); - std::vector StringStorage(argc); - - for (int i = 0; i < argc; i++) { - StringStorage[i] = utf16_to_utf8(_argv[i]); - StringPtrs[i] = StringStorage[i].c_str(); - } - - const char **argv = StringPtrs.data(); -#else -int main(int argc, const char *argv[]) { -#endif - try { - if (argc <= 1) { - PrintUsage(); - return 0; - } - - ParseCMDLine(argc, argv); - } catch (Error const& e) { - std::cout << e.msg << std::endl << std::flush; - return 1; - } - - FFMS_Init(0, 0); - - switch (Verbose) { - case 0: FFMS_SetLogLevel(FFMS_LOG_QUIET); break; - case 1: FFMS_SetLogLevel(FFMS_LOG_WARNING); break; - case 2: FFMS_SetLogLevel(FFMS_LOG_INFO); break; - case 3: FFMS_SetLogLevel(FFMS_LOG_VERBOSE); break; - default: FFMS_SetLogLevel(FFMS_LOG_DEBUG); // if user used -v 4 or more times, he deserves the spam - } - - try { - DoIndexing(); - } catch (Error const& e) { - std::cout << e.msg << std::endl << std::flush; - FFMS_Deinit(); - return 1; - } - - FFMS_Deinit(); - return 0; -} diff --git a/thirdparty/ffms2/src/index/ffmsindex.manifest b/thirdparty/ffms2/src/index/ffmsindex.manifest deleted file mode 100644 index 3268efc66..000000000 --- a/thirdparty/ffms2/src/index/ffmsindex.manifest +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - true - - - \ No newline at end of file diff --git a/thirdparty/ffms2/src/index/vsutf16.h b/thirdparty/ffms2/src/index/vsutf16.h deleted file mode 100644 index 11faef07d..000000000 --- a/thirdparty/ffms2/src/index/vsutf16.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -* Copyright (c) 2017 Fredrik Mellbin -* -* This file is part of VapourSynth. -* -* VapourSynth is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; either -* version 2.1 of the License, or (at your option) any later version. -* -* VapourSynth is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with VapourSynth; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef VSUTF16_H -#define VSUTF16_H - -#include -#ifndef NOMINMAX -#define NOMINMAX -#endif -#include - -static std::string utf16_to_utf8(const std::wstring &wstr) { - int required_size = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, nullptr, 0, nullptr, nullptr); - std::string buffer; - buffer.resize(required_size - 1); - WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), static_cast(wstr.size()), &buffer[0], required_size, nullptr, nullptr); - return buffer; -} - -static std::wstring utf16_from_utf8(const std::string &str) { - int required_size = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, nullptr, 0); - std::wstring wbuffer; - wbuffer.resize(required_size - 1); - MultiByteToWideChar(CP_UTF8, 0, str.c_str(), static_cast(str.size()), &wbuffer[0], required_size); - return wbuffer; -} - -#endif \ No newline at end of file diff --git a/thirdparty/ffms2/src/vapoursynth/VSHelper4.h b/thirdparty/ffms2/src/vapoursynth/VSHelper4.h deleted file mode 100644 index 9392c0530..000000000 --- a/thirdparty/ffms2/src/vapoursynth/VSHelper4.h +++ /dev/null @@ -1,219 +0,0 @@ -/***************************************************************************** -* Copyright (c) 2012-2020 Fredrik Mellbin -* --- Legal stuff --- -* This program is free software. It comes without any warranty, to -* the extent permitted by applicable law. You can redistribute it -* and/or modify it under the terms of the Do What The Fuck You Want -* To Public License, Version 2, as published by Sam Hocevar. See -* http://sam.zoy.org/wtfpl/COPYING for more details. -*****************************************************************************/ - -#ifndef VSHELPER4_H -#define VSHELPER4_H - -#include -#include -#include -#include -#include -#include -#include -#ifdef _WIN32 -#include -#endif -#include "VapourSynth4.h" - -#define VSH_STD_PLUGIN_ID "com.vapoursynth.std" -#define VSH_RESIZE_PLUGIN_ID "com.vapoursynth.resize" -#define VSH_TEXT_PLUGIN_ID "com.vapoursynth.text" - -#ifdef __cplusplus -namespace vsh { -#define VSH4_MANGLE_FUNCTION_NAME(name) name -#define VSH4_BOOLEAN_TYPE bool -#else -#define VSH4_MANGLE_FUNCTION_NAME(name) vsh_##name -#define VSH4_BOOLEAN_TYPE int -#endif - -/* Visual Studio doesn't recognize inline in c mode */ -#if defined(_MSC_VER) && !defined(__cplusplus) -#define inline _inline -#endif - -/* A kinda portable definition of the C99 restrict keyword (or its inofficial C++ equivalent) */ -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* Available in C99 */ -#define VS_RESTRICT restrict -#elif defined(__cplusplus) || defined(_MSC_VER) /* Almost all relevant C++ compilers support it so just assume it works */ -#define VS_RESTRICT __restrict -#else /* Not supported */ -#define VS_RESTRICT -#endif - -#ifdef _WIN32 -#define VSH_ALIGNED_MALLOC(pptr, size, alignment) do { *(pptr) = _aligned_malloc((size), (alignment)); } while (0) -#define VSH_ALIGNED_FREE(ptr) do { _aligned_free((ptr)); } while (0) -#else -#define VSH_ALIGNED_MALLOC(pptr, size, alignment) do { if(posix_memalign((void**)(pptr), (alignment), (size))) *((void**)pptr) = NULL; } while (0) -#define VSH_ALIGNED_FREE(ptr) do { free((ptr)); } while (0) -#endif - -#define VSMAX(a,b) ((a) > (b) ? (a) : (b)) -#define VSMIN(a,b) ((a) > (b) ? (b) : (a)) - -#ifdef __cplusplus -/* A nicer templated malloc for all the C++ users out there */ -#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900) -template -#else -template -#endif -static inline T *vsh_aligned_malloc(size_t size, size_t alignment) { -#ifdef _WIN32 - return (T *)_aligned_malloc(size, alignment); -#else - void *tmp = NULL; - if (posix_memalign(&tmp, alignment, size)) - tmp = 0; - return (T *)tmp; -#endif -} - -static inline void vsh_aligned_free(void *ptr) { - VSH_ALIGNED_FREE(ptr); -} -#endif /* __cplusplus */ - -/* convenience function for checking if the format never changes between frames */ -static inline VSH4_BOOLEAN_TYPE VSH4_MANGLE_FUNCTION_NAME(isConstantVideoFormat)(const VSVideoInfo *vi) { - return vi->height > 0 && vi->width > 0 && vi->format.colorFamily != cfUndefined; -} - -/* convenience function to check for if two clips have the same format (unknown/changeable will be considered the same too) */ -static inline VSH4_BOOLEAN_TYPE VSH4_MANGLE_FUNCTION_NAME(isSameVideoFormat)(const VSVideoFormat *v1, const VSVideoFormat *v2) { - return v1->colorFamily == v2->colorFamily && v1->sampleType == v2->sampleType && v1->bitsPerSample == v2->bitsPerSample && v1->subSamplingW == v2->subSamplingW && v1->subSamplingH == v2->subSamplingH; -} - -/* convenience function to check for if two clips have the same format (but not framerate) while also including width and height (unknown/changeable will be considered the same too) */ -static inline VSH4_BOOLEAN_TYPE VSH4_MANGLE_FUNCTION_NAME(isSameVideoInfo)(const VSVideoInfo *v1, const VSVideoInfo *v2) { - return v1->height == v2->height && v1->width == v2->width && VSH4_MANGLE_FUNCTION_NAME(isSameVideoFormat)(&v1->format, &v2->format); -} - -/* convenience function to check for if two clips have the same format while also including samplerate (unknown/changeable will be considered the same too) */ -static inline VSH4_BOOLEAN_TYPE VSH4_MANGLE_FUNCTION_NAME(isSameAudioFormat)(const VSAudioFormat *a1, const VSAudioFormat *a2) { - return a1->bitsPerSample == a2->bitsPerSample && a1->sampleType == a2->sampleType && a1->channelLayout == a2->channelLayout; -} - -/* convenience function to check for if two clips have the same format while also including samplerate (unknown/changeable will be considered the same too) */ -static inline VSH4_BOOLEAN_TYPE VSH4_MANGLE_FUNCTION_NAME(isSameAudioInfo)(const VSAudioInfo *a1, const VSAudioInfo *a2) { - return a1->sampleRate == a2->sampleRate && VSH4_MANGLE_FUNCTION_NAME(isSameAudioFormat)(&a1->format, &a2->format); -} - -/* multiplies and divides a rational number, such as a frame duration, in place and reduces the result */ -static inline void VSH4_MANGLE_FUNCTION_NAME(muldivRational)(int64_t *num, int64_t *den, int64_t mul, int64_t div) { - /* do nothing if the rational number is invalid */ - if (!*den) - return; - - /* nobody wants to accidentally divide by zero */ - assert(div); - - int64_t a, b; - *num *= mul; - *den *= div; - a = *num; - b = *den; - while (b != 0) { - int64_t t = a; - a = b; - b = t % b; - } - if (a < 0) - a = -a; - *num /= a; - *den /= a; -} - -/* reduces a rational number */ -static inline void VSH4_MANGLE_FUNCTION_NAME(reduceRational)(int64_t *num, int64_t *den) { - VSH4_MANGLE_FUNCTION_NAME(muldivRational)(num, den, 1, 1); -} - -/* add two rational numbers and reduces the result */ -static inline void VSH4_MANGLE_FUNCTION_NAME(addRational)(int64_t *num, int64_t *den, int64_t addnum, int64_t addden) { - /* do nothing if the rational number is invalid */ - if (!*den) - return; - - /* nobody wants to accidentally add an invalid rational number */ - assert(addden); - - if (*den == addden) { - *num += addnum; - } else { - int64_t temp = addden; - addnum *= *den; - addden *= *den; - *num *= temp; - *den *= temp; - - *num += addnum; - - VSH4_MANGLE_FUNCTION_NAME(reduceRational)(num, den); - } -} - -/* converts an int64 to int with saturation, useful to silence warnings when reading int properties among other things */ -static inline int VSH4_MANGLE_FUNCTION_NAME(int64ToIntS)(int64_t i) { - if (i > INT_MAX) - return INT_MAX; - else if (i < INT_MIN) - return INT_MIN; - else return (int)i; -} - -/* converts a double to float with saturation, useful to silence warnings when reading float properties among other things */ -static inline float VSH4_MANGLE_FUNCTION_NAME(doubleToFloatS)(double d) { - if (!isfinite(d)) - return (float)d; - else if (d > FLT_MAX) - return FLT_MAX; - else if (d < -FLT_MAX) - return -FLT_MAX; - else - return (float)d; -} - -static inline void VSH4_MANGLE_FUNCTION_NAME(bitblt)(void *dstp, ptrdiff_t dst_stride, const void *srcp, ptrdiff_t src_stride, size_t row_size, size_t height) { - if (height) { - if (src_stride == dst_stride && src_stride == (ptrdiff_t)row_size) { - memcpy(dstp, srcp, row_size * height); - } else { - const uint8_t *srcp8 = (const uint8_t *)srcp; - uint8_t *dstp8 = (uint8_t *)dstp; - size_t i; - for (i = 0; i < height; i++) { - memcpy(dstp8, srcp8, row_size); - srcp8 += src_stride; - dstp8 += dst_stride; - } - } - } -} - -/* check if the frame dimensions are valid for a given format */ -/* returns non-zero for valid width and height */ -static inline VSH4_BOOLEAN_TYPE VSH4_MANGLE_FUNCTION_NAME(areValidDimensions)(const VSVideoFormat *fi, int width, int height) { - return !(width % (1 << fi->subSamplingW) || height % (1 << fi->subSamplingH)); -} - -/* Visual Studio doesn't recognize inline in c mode */ -#if defined(_MSC_VER) && !defined(__cplusplus) -#undef inline -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/thirdparty/ffms2/src/vapoursynth/VapourSynth4.h b/thirdparty/ffms2/src/vapoursynth/VapourSynth4.h deleted file mode 100644 index a7844c604..000000000 --- a/thirdparty/ffms2/src/vapoursynth/VapourSynth4.h +++ /dev/null @@ -1,476 +0,0 @@ -/* -* Copyright (c) 2012-2021 Fredrik Mellbin -* -* This file is part of VapourSynth. -* -* VapourSynth is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; either -* version 2.1 of the License, or (at your option) any later version. -* -* VapourSynth is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with VapourSynth; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef VAPOURSYNTH4_H -#define VAPOURSYNTH4_H - -#include -#include - -#define VS_MAKE_VERSION(major, minor) (((major) << 16) | (minor)) -#define VAPOURSYNTH_API_MAJOR 4 -#define VAPOURSYNTH_API_MINOR 0 -#define VAPOURSYNTH_API_VERSION VS_MAKE_VERSION(VAPOURSYNTH_API_MAJOR, VAPOURSYNTH_API_MINOR) - -#define VS_AUDIO_FRAME_SAMPLES 3072 - -/* Convenience for C++ users. */ -#ifdef __cplusplus -# define VS_EXTERN_C extern "C" -# if __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L) -# define VS_NOEXCEPT noexcept -# else -# define VS_NOEXCEPT -# endif -#else -# define VS_EXTERN_C -# define VS_NOEXCEPT -#endif - -#if defined(_WIN32) && !defined(_WIN64) -# define VS_CC __stdcall -#else -# define VS_CC -#endif - -/* And now for some symbol hide-and-seek... */ -#if defined(_WIN32) /* Windows being special */ -# define VS_EXTERNAL_API(ret) VS_EXTERN_C __declspec(dllexport) ret VS_CC -#elif defined(__GNUC__) && __GNUC__ >= 4 -# define VS_EXTERNAL_API(ret) VS_EXTERN_C __attribute__((visibility("default"))) ret VS_CC -#else -# define VS_EXTERNAL_API(ret) VS_EXTERN_C ret VS_CC -#endif - -#if !defined(VS_CORE_EXPORTS) && defined(_WIN32) -# define VS_API(ret) VS_EXTERN_C __declspec(dllimport) ret VS_CC -#else -# define VS_API(ret) VS_EXTERNAL_API(ret) -#endif - -typedef struct VSFrame VSFrame; -typedef struct VSNode VSNode; -typedef struct VSCore VSCore; -typedef struct VSPlugin VSPlugin; -typedef struct VSPluginFunction VSPluginFunction; -typedef struct VSFunction VSFunction; -typedef struct VSMap VSMap; -typedef struct VSLogHandle VSLogHandle; -typedef struct VSFrameContext VSFrameContext; -typedef struct VSPLUGINAPI VSPLUGINAPI; -typedef struct VSAPI VSAPI; - -typedef enum VSColorFamily { - cfUndefined = 0, - cfGray = 1, - cfRGB = 2, - cfYUV = 3 -} VSColorFamily; - -typedef enum VSSampleType { - stInteger = 0, - stFloat = 1 -} VSSampleType; - -#define VS_MAKE_VIDEO_ID(colorFamily, sampleType, bitsPerSample, subSamplingW, subSamplingH) ((colorFamily << 28) | (sampleType << 24) | (bitsPerSample << 16) | (subSamplingW << 8) | (subSamplingH << 0)) - -typedef enum VSPresetFormat { - pfNone = 0, - - pfGray8 = VS_MAKE_VIDEO_ID(cfGray, stInteger, 8, 0, 0), - pfGray16 = VS_MAKE_VIDEO_ID(cfGray, stInteger, 16, 0, 0), - - pfGrayH = VS_MAKE_VIDEO_ID(cfGray, stFloat, 16, 0, 0), - pfGrayS = VS_MAKE_VIDEO_ID(cfGray, stFloat, 32, 0, 0), - - pfYUV410P8 = VS_MAKE_VIDEO_ID(cfYUV, stInteger, 8, 2, 2), - pfYUV411P8 = VS_MAKE_VIDEO_ID(cfYUV, stInteger, 8, 2, 0), - pfYUV440P8 = VS_MAKE_VIDEO_ID(cfYUV, stInteger, 8, 0, 1), - - pfYUV420P8 = VS_MAKE_VIDEO_ID(cfYUV, stInteger, 8, 1, 1), - pfYUV422P8 = VS_MAKE_VIDEO_ID(cfYUV, stInteger, 8, 1, 0), - pfYUV444P8 = VS_MAKE_VIDEO_ID(cfYUV, stInteger, 8, 0, 0), - - pfYUV420P10 = VS_MAKE_VIDEO_ID(cfYUV, stInteger, 10, 1, 1), - pfYUV422P10 = VS_MAKE_VIDEO_ID(cfYUV, stInteger, 10, 1, 0), - pfYUV444P10 = VS_MAKE_VIDEO_ID(cfYUV, stInteger, 10, 0, 0), - - pfYUV420P12 = VS_MAKE_VIDEO_ID(cfYUV, stInteger, 12, 1, 1), - pfYUV422P12 = VS_MAKE_VIDEO_ID(cfYUV, stInteger, 12, 1, 0), - pfYUV444P12 = VS_MAKE_VIDEO_ID(cfYUV, stInteger, 12, 0, 0), - - pfYUV420P14 = VS_MAKE_VIDEO_ID(cfYUV, stInteger, 14, 1, 1), - pfYUV422P14 = VS_MAKE_VIDEO_ID(cfYUV, stInteger, 14, 1, 0), - pfYUV444P14 = VS_MAKE_VIDEO_ID(cfYUV, stInteger, 14, 0, 0), - - pfYUV420P16 = VS_MAKE_VIDEO_ID(cfYUV, stInteger, 16, 1, 1), - pfYUV422P16 = VS_MAKE_VIDEO_ID(cfYUV, stInteger, 16, 1, 0), - pfYUV444P16 = VS_MAKE_VIDEO_ID(cfYUV, stInteger, 16, 0, 0), - - pfYUV444PH = VS_MAKE_VIDEO_ID(cfYUV, stFloat, 16, 0, 0), - pfYUV444PS = VS_MAKE_VIDEO_ID(cfYUV, stFloat, 32, 0, 0), - - pfRGB24 = VS_MAKE_VIDEO_ID(cfRGB, stInteger, 8, 0, 0), - pfRGB30 = VS_MAKE_VIDEO_ID(cfRGB, stInteger, 10, 0, 0), - pfRGB36 = VS_MAKE_VIDEO_ID(cfRGB, stInteger, 12, 0, 0), - pfRGB42 = VS_MAKE_VIDEO_ID(cfRGB, stInteger, 14, 0, 0), - pfRGB48 = VS_MAKE_VIDEO_ID(cfRGB, stInteger, 16, 0, 0), - - pfRGBH = VS_MAKE_VIDEO_ID(cfRGB, stFloat, 16, 0, 0), - pfRGBS = VS_MAKE_VIDEO_ID(cfRGB, stFloat, 32, 0, 0), -} VSPresetFormat; - -#undef VS_MAKE_VIDEO_ID - - -typedef enum VSFilterMode { - fmParallel = 0, /* completely parallel execution */ - fmParallelRequests = 1, /* for filters that are serial in nature but can request one or more frames they need in advance */ - fmUnordered = 2, /* for filters that modify their internal state every request like source filters that read a file */ - fmFrameState = 3 /* DO NOT USE UNLESS ABSOLUTELY NECESSARY, for compatibility with external code that can only keep the processing state of a single frame at a time */ -} VSFilterMode; - -typedef enum VSMediaType { - mtVideo = 1, - mtAudio = 2 -} VSMediaType; - -typedef struct VSVideoFormat { - int colorFamily; /* see VSColorFamily */ - int sampleType; /* see VSSampleType */ - int bitsPerSample; /* number of significant bits */ - int bytesPerSample; /* actual storage is always in a power of 2 and the smallest possible that can fit the number of bits used per sample */ - - int subSamplingW; /* log2 subsampling factor, applied to second and third plane */ - int subSamplingH; /* log2 subsampling factor, applied to second and third plane */ - - int numPlanes; /* implicit from colorFamily */ -} VSVideoFormat; - -typedef enum VSAudioChannels { - acFrontLeft = 0, - acFrontRight = 1, - acFrontCenter = 2, - acLowFrequency = 3, - acBackLeft = 4, - acBackRight = 5, - acFrontLeftOFCenter = 6, - acFrontRightOFCenter = 7, - acBackCenter = 8, - acSideLeft = 9, - acSideRight = 10, - acTopCenter = 11, - acTopFrontLeft = 12, - acTopFrontCenter = 13, - acTopFrontRight = 14, - acTopBackLeft = 15, - acTopBackCenter = 16, - acTopBackRight = 17, - acStereoLeft = 29, - acStereoRight = 30, - acWideLeft = 31, - acWideRight = 32, - acSurroundDirectLeft = 33, - acSurroundDirectRight = 34, - acLowFrequency2 = 35 -} VSAudioChannels; - -typedef struct VSAudioFormat { - int sampleType; - int bitsPerSample; - int bytesPerSample; /* implicit from bitsPerSample */ - int numChannels; /* implicit from channelLayout */ - uint64_t channelLayout; -} VSAudioFormat; - -typedef enum VSFilterFlags { - ffStrictSpatial = 1 -} VSFilterFlags; - -typedef enum VSPropertyType { - ptUnset = 0, - ptInt = 1, - ptFloat = 2, - ptData = 3, - ptFunction = 4, - ptVideoNode = 5, - ptAudioNode = 6, - ptVideoFrame = 7, - ptAudioFrame = 8 -} VSPropertyType; - -typedef enum VSMapPropertyError { - peSuccess = 0, - peUnset = 1, /* no key exists */ - peType = 2, /* key exists but not of a compatible type */ - peIndex = 4, /* index out of bounds */ - peError = 3 /* map has error state set */ -} VSMapPropertyError; - -typedef enum VSMapAppendMode { - maReplace = 0, - maAppend = 1 -} VSMapAppendMode; - -typedef struct VSCoreInfo { - const char *versionString; - int core; - int api; - int numThreads; - int64_t maxFramebufferSize; - int64_t usedFramebufferSize; -} VSCoreInfo; - -typedef struct VSVideoInfo { - VSVideoFormat format; - int64_t fpsNum; - int64_t fpsDen; - int width; - int height; - int numFrames; -} VSVideoInfo; - -typedef struct VSAudioInfo { - VSAudioFormat format; - int sampleRate; - int64_t numSamples; - int numFrames; /* the total number of audio frames needed to hold numSamples, implicit from numSamples when calling createAudioFilter */ -} VSAudioInfo; - -typedef enum VSActivationReason { - arInitial = 0, - arAllFramesReady = 1, - arError = -1 -} VSActivationReason; - -typedef enum VSMessageType { - mtDebug = 0, - mtInformation = 1, - mtWarning = 2, - mtCritical = 3, - mtFatal = 4 /* also terminates the process, should generally not be used by normal filters */ -} VSMessageType; - -typedef enum VSCoreCreationFlags { - ccfEnableGraphInspection = 1, - ccfDisableAutoLoading = 2, - ccfDisableLibraryUnloading = 4 -} VSCoreCreationFlags; - -typedef enum VSPluginConfigFlags { - pcModifiable = 1 -} VSPluginConfigFlags; - -typedef enum VSDataTypeHint { - dtUnknown = -1, - dtBinary = 0, - dtUtf8 = 1 -} VSDataTypeHint; - -typedef enum VSRequestPattern { - rpGeneral = 0, /* General pattern */ - rpNoFrameReuse = 1, /* When requesting all output frames from the filter no frame will be requested more than once from this input clip, never requests frames beyond the end of the clip */ - rpStrictSpatial = 2 /* Always (and only) requests frame n from input clip when generating output frame n, never requests frames beyond the end of the clip */ -} VSRequestPattern; - -/* Core entry point */ -typedef const VSAPI *(VS_CC *VSGetVapourSynthAPI)(int version); - -/* Plugin, function and filter related */ -typedef void (VS_CC *VSPublicFunction)(const VSMap *in, VSMap *out, void *userData, VSCore *core, const VSAPI *vsapi); -typedef void (VS_CC *VSInitPlugin)(VSPlugin *plugin, const VSPLUGINAPI *vspapi); -typedef void (VS_CC *VSFreeFunctionData)(void *userData); -typedef const VSFrame *(VS_CC *VSFilterGetFrame)(int n, int activationReason, void *instanceData, void **frameData, VSFrameContext *frameCtx, VSCore *core, const VSAPI *vsapi); -typedef void (VS_CC *VSFilterFree)(void *instanceData, VSCore *core, const VSAPI *vsapi); - -/* Other */ -typedef void (VS_CC *VSFrameDoneCallback)(void *userData, const VSFrame *f, int n, VSNode *node, const char *errorMsg); -typedef void (VS_CC *VSLogHandler)(int msgType, const char *msg, void *userData); -typedef void (VS_CC *VSLogHandlerFree)(void *userData); - -struct VSPLUGINAPI { - int (VS_CC *getAPIVersion)(void) VS_NOEXCEPT; /* returns VAPOURSYNTH_API_VERSION of the library */ - int (VS_CC *configPlugin)(const char *identifier, const char *pluginNamespace, const char *name, int pluginVersion, int apiVersion, int flags, VSPlugin *plugin) VS_NOEXCEPT; /* use the VS_MAKE_VERSION macro for pluginVersion */ - int (VS_CC *registerFunction)(const char *name, const char *args, const char *returnType, VSPublicFunction argsFunc, void *functionData, VSPlugin *plugin) VS_NOEXCEPT; /* non-zero return value on success */ -}; - -typedef struct VSFilterDependency { - VSNode *source; - int requestPattern; /* VSRequestPattern */ -} VSFilterDependency; - -struct VSAPI { - /* Audio and video filter related including nodes */ - void (VS_CC *createVideoFilter)(VSMap *out, const char *name, const VSVideoInfo *vi, VSFilterGetFrame getFrame, VSFilterFree free, int filterMode, const VSFilterDependency *dependencies, int numDeps, void *instanceData, VSCore *core) VS_NOEXCEPT; /* output nodes are appended to the clip key in the out map */ - VSNode *(VS_CC *createVideoFilter2)(const char *name, const VSVideoInfo *vi, VSFilterGetFrame getFrame, VSFilterFree free, int filterMode, const VSFilterDependency *dependencies, int numDeps, void *instanceData, VSCore *core) VS_NOEXCEPT; /* same as createVideoFilter but returns a pointer to the VSNode directly or NULL on failure */ - void (VS_CC *createAudioFilter)(VSMap *out, const char *name, const VSAudioInfo *ai, VSFilterGetFrame getFrame, VSFilterFree free, int filterMode, const VSFilterDependency *dependencies, int numDeps, void *instanceData, VSCore *core) VS_NOEXCEPT; /* output nodes are appended to the clip key in the out map */ - VSNode *(VS_CC *createAudioFilter2)(const char *name, const VSAudioInfo *ai, VSFilterGetFrame getFrame, VSFilterFree free, int filterMode, const VSFilterDependency *dependencies, int numDeps, void *instanceData, VSCore *core) VS_NOEXCEPT; /* same as createAudioFilter but returns a pointer to the VSNode directly or NULL on failure */ - int (VS_CC *setLinearFilter)(VSNode *node) VS_NOEXCEPT; /* Use right after create*Filter*, sets the correct cache mode for using the cacheFrame API and returns the recommended upper number of additional frames to cache per request */ - void (VS_CC *setCacheMode)(VSNode *node, int mode) VS_NOEXCEPT; /* -1: default (auto), 0: force disable, 1: force enable, changing the cache mode also resets all options to their default */ - void (VS_CC *setCacheOptions)(VSNode *node, int fixedSize, int maxSize, int maxHistorySize) VS_NOEXCEPT; /* passing -1 means no change */ - - void (VS_CC *freeNode)(VSNode *node) VS_NOEXCEPT; - VSNode *(VS_CC *addNodeRef)(VSNode *node) VS_NOEXCEPT; - int (VS_CC *getNodeType)(VSNode *node) VS_NOEXCEPT; /* returns VSMediaType */ - const VSVideoInfo *(VS_CC *getVideoInfo)(VSNode *node) VS_NOEXCEPT; - const VSAudioInfo *(VS_CC *getAudioInfo)(VSNode *node) VS_NOEXCEPT; - - /* Frame related functions */ - VSFrame *(VS_CC *newVideoFrame)(const VSVideoFormat *format, int width, int height, const VSFrame *propSrc, VSCore *core) VS_NOEXCEPT; - VSFrame *(VS_CC *newVideoFrame2)(const VSVideoFormat *format, int width, int height, const VSFrame **planeSrc, const int *planes, const VSFrame *propSrc, VSCore *core) VS_NOEXCEPT; /* same as newVideoFrame but allows the specified planes to be effectively copied from the source frames */ - VSFrame *(VS_CC *newAudioFrame)(const VSAudioFormat *format, int numSamples, const VSFrame *propSrc, VSCore *core) VS_NOEXCEPT; - VSFrame *(VS_CC *newAudioFrame2)(const VSAudioFormat *format, int numSamples, const VSFrame **channelSrc, const int *channels, const VSFrame *propSrc, VSCore *core) VS_NOEXCEPT; /* same as newAudioFrame but allows the specified channels to be effectively copied from the source frames */ - void (VS_CC *freeFrame)(const VSFrame *f) VS_NOEXCEPT; - const VSFrame *(VS_CC *addFrameRef)(const VSFrame *f) VS_NOEXCEPT; - VSFrame *(VS_CC *copyFrame)(const VSFrame *f, VSCore *core) VS_NOEXCEPT; - const VSMap *(VS_CC *getFramePropertiesRO)(const VSFrame *f) VS_NOEXCEPT; - VSMap *(VS_CC *getFramePropertiesRW)(VSFrame *f) VS_NOEXCEPT; - - ptrdiff_t (VS_CC *getStride)(const VSFrame *f, int plane) VS_NOEXCEPT; - const uint8_t *(VS_CC *getReadPtr)(const VSFrame *f, int plane) VS_NOEXCEPT; - uint8_t *(VS_CC *getWritePtr)(VSFrame *f, int plane) VS_NOEXCEPT; /* calling this function invalidates previously gotten read pointers to the same frame */ - - const VSVideoFormat *(VS_CC *getVideoFrameFormat)(const VSFrame *f) VS_NOEXCEPT; - const VSAudioFormat *(VS_CC *getAudioFrameFormat)(const VSFrame *f) VS_NOEXCEPT; - int (VS_CC *getFrameType)(const VSFrame *f) VS_NOEXCEPT; /* returns VSMediaType */ - int (VS_CC *getFrameWidth)(const VSFrame *f, int plane) VS_NOEXCEPT; - int (VS_CC *getFrameHeight)(const VSFrame *f, int plane) VS_NOEXCEPT; - int (VS_CC *getFrameLength)(const VSFrame *f) VS_NOEXCEPT; /* returns the number of samples for audio frames */ - - /* General format functions */ - int (VS_CC *getVideoFormatName)(const VSVideoFormat *format, char *buffer) VS_NOEXCEPT; /* up to 32 characters including terminating null may be written to the buffer, non-zero return value on success */ - int (VS_CC *getAudioFormatName)(const VSAudioFormat *format, char *buffer) VS_NOEXCEPT; /* up to 32 characters including terminating null may be written to the buffer, non-zero return value on success */ - int (VS_CC *queryVideoFormat)(VSVideoFormat *format, int colorFamily, int sampleType, int bitsPerSample, int subSamplingW, int subSamplingH, VSCore *core) VS_NOEXCEPT; /* non-zero return value on success */ - int (VS_CC *queryAudioFormat)(VSAudioFormat *format, int sampleType, int bitsPerSample, uint64_t channelLayout, VSCore *core) VS_NOEXCEPT; /* non-zero return value on success */ - uint32_t (VS_CC *queryVideoFormatID)(int colorFamily, int sampleType, int bitsPerSample, int subSamplingW, int subSamplingH, VSCore *core) VS_NOEXCEPT; /* returns 0 on failure */ - int (VS_CC *getVideoFormatByID)(VSVideoFormat *format, uint32_t id, VSCore *core) VS_NOEXCEPT; /* non-zero return value on success */ - - /* Frame request and filter getframe functions */ - const VSFrame *(VS_CC *getFrame)(int n, VSNode *node, char *errorMsg, int bufSize) VS_NOEXCEPT; /* only for external applications using the core as a library or for requesting frames in a filter constructor, do not use inside a filter's getframe function */ - void (VS_CC *getFrameAsync)(int n, VSNode *node, VSFrameDoneCallback callback, void *userData) VS_NOEXCEPT; /* only for external applications using the core as a library or for requesting frames in a filter constructor, do not use inside a filter's getframe function */ - const VSFrame *(VS_CC *getFrameFilter)(int n, VSNode *node, VSFrameContext *frameCtx) VS_NOEXCEPT; /* only use inside a filter's getframe function */ - void (VS_CC *requestFrameFilter)(int n, VSNode *node, VSFrameContext *frameCtx) VS_NOEXCEPT; /* only use inside a filter's getframe function */ - void (VS_CC *releaseFrameEarly)(VSNode *node, int n, VSFrameContext *frameCtx) VS_NOEXCEPT; /* only use inside a filter's getframe function, unless this function is called a requested frame is kept in memory until the end of processing the current frame */ - void (VS_CC *cacheFrame)(const VSFrame *frame, int n, VSFrameContext *frameCtx) VS_NOEXCEPT; /* used to store intermediate frames in cache, useful for filters where random access is slow, must call setLinearFilter on the node before using or the result is undefined */ - void (VS_CC *setFilterError)(const char *errorMessage, VSFrameContext *frameCtx) VS_NOEXCEPT; /* used to signal errors in the filter getframe function */ - - /* External functions */ - VSFunction *(VS_CC *createFunction)(VSPublicFunction func, void *userData, VSFreeFunctionData free, VSCore *core) VS_NOEXCEPT; - void (VS_CC *freeFunction)(VSFunction *f) VS_NOEXCEPT; - VSFunction *(VS_CC *addFunctionRef)(VSFunction *f) VS_NOEXCEPT; - void (VS_CC *callFunction)(VSFunction *func, const VSMap *in, VSMap *out) VS_NOEXCEPT; - - /* Map and property access functions */ - VSMap *(VS_CC *createMap)(void) VS_NOEXCEPT; - void (VS_CC *freeMap)(VSMap *map) VS_NOEXCEPT; - void (VS_CC *clearMap)(VSMap *map) VS_NOEXCEPT; - void (VS_CC *copyMap)(const VSMap *src, VSMap *dst) VS_NOEXCEPT; /* copies all values in src to dst, if a key already exists in dst it's replaced */ - - void (VS_CC *mapSetError)(VSMap *map, const char *errorMessage) VS_NOEXCEPT; /* used to signal errors outside filter getframe function */ - const char *(VS_CC *mapGetError)(const VSMap *map) VS_NOEXCEPT; /* used to query errors, returns 0 if no error */ - - int (VS_CC *mapNumKeys)(const VSMap *map) VS_NOEXCEPT; - const char *(VS_CC *mapGetKey)(const VSMap *map, int index) VS_NOEXCEPT; - int (VS_CC *mapDeleteKey)(VSMap *map, const char *key) VS_NOEXCEPT; - int (VS_CC *mapNumElements)(const VSMap *map, const char *key) VS_NOEXCEPT; /* returns -1 if a key doesn't exist */ - int (VS_CC *mapGetType)(const VSMap *map, const char *key) VS_NOEXCEPT; /* returns VSPropertyType */ - int (VS_CC *mapSetEmpty)(VSMap *map, const char *key, int type) VS_NOEXCEPT; - - int64_t (VS_CC *mapGetInt)(const VSMap *map, const char *key, int index, int *error) VS_NOEXCEPT; - int (VS_CC *mapGetIntSaturated)(const VSMap *map, const char *key, int index, int *error) VS_NOEXCEPT; - const int64_t *(VS_CC *mapGetIntArray)(const VSMap *map, const char *key, int *error) VS_NOEXCEPT; - int (VS_CC *mapSetInt)(VSMap *map, const char *key, int64_t i, int append) VS_NOEXCEPT; - int (VS_CC *mapSetIntArray)(VSMap *map, const char *key, const int64_t *i, int size) VS_NOEXCEPT; - - double (VS_CC *mapGetFloat)(const VSMap *map, const char *key, int index, int *error) VS_NOEXCEPT; - float (VS_CC *mapGetFloatSaturated)(const VSMap *map, const char *key, int index, int *error) VS_NOEXCEPT; - const double *(VS_CC *mapGetFloatArray)(const VSMap *map, const char *key, int *error) VS_NOEXCEPT; - int (VS_CC *mapSetFloat)(VSMap *map, const char *key, double d, int append) VS_NOEXCEPT; - int (VS_CC *mapSetFloatArray)(VSMap *map, const char *key, const double *d, int size) VS_NOEXCEPT; - - const char *(VS_CC *mapGetData)(const VSMap *map, const char *key, int index, int *error) VS_NOEXCEPT; - int (VS_CC *mapGetDataSize)(const VSMap *map, const char *key, int index, int *error) VS_NOEXCEPT; - int (VS_CC *mapGetDataTypeHint)(const VSMap *map, const char *key, int index, int *error) VS_NOEXCEPT; /* returns VSDataTypeHint */ - int (VS_CC *mapSetData)(VSMap *map, const char *key, const char *data, int size, int type, int append) VS_NOEXCEPT; - - VSNode *(VS_CC *mapGetNode)(const VSMap *map, const char *key, int index, int *error) VS_NOEXCEPT; - int (VS_CC *mapSetNode)(VSMap *map, const char *key, VSNode *node, int append) VS_NOEXCEPT; /* returns 0 on success */ - int (VS_CC *mapConsumeNode)(VSMap *map, const char *key, VSNode *node, int append) VS_NOEXCEPT; /* always consumes the reference, even on error */ - - const VSFrame *(VS_CC *mapGetFrame)(const VSMap *map, const char *key, int index, int *error) VS_NOEXCEPT; - int (VS_CC *mapSetFrame)(VSMap *map, const char *key, const VSFrame *f, int append) VS_NOEXCEPT; /* returns 0 on success */ - int (VS_CC *mapConsumeFrame)(VSMap *map, const char *key, const VSFrame *f, int append) VS_NOEXCEPT; /* always consumes the reference, even on error */ - - VSFunction *(VS_CC *mapGetFunction)(const VSMap *map, const char *key, int index, int *error) VS_NOEXCEPT; - int (VS_CC *mapSetFunction)(VSMap *map, const char *key, VSFunction *func, int append) VS_NOEXCEPT; /* returns 0 on success */ - int (VS_CC *mapConsumeFunction)(VSMap *map, const char *key, VSFunction *func, int append) VS_NOEXCEPT; /* always consumes the reference, even on error */ - - /* Plugin and plugin function related */ - int (VS_CC *registerFunction)(const char *name, const char *args, const char *returnType, VSPublicFunction argsFunc, void *functionData, VSPlugin *plugin) VS_NOEXCEPT; /* non-zero return value on success */ - VSPlugin *(VS_CC *getPluginByID)(const char *identifier, VSCore *core) VS_NOEXCEPT; - VSPlugin *(VS_CC *getPluginByNamespace)(const char *ns, VSCore *core) VS_NOEXCEPT; - VSPlugin *(VS_CC *getNextPlugin)(VSPlugin *plugin, VSCore *core) VS_NOEXCEPT; /* pass NULL to get the first plugin */ - const char *(VS_CC *getPluginName)(VSPlugin *plugin) VS_NOEXCEPT; - const char *(VS_CC *getPluginID)(VSPlugin *plugin) VS_NOEXCEPT; - const char *(VS_CC *getPluginNamespace)(VSPlugin *plugin) VS_NOEXCEPT; - VSPluginFunction *(VS_CC *getNextPluginFunction)(VSPluginFunction *func, VSPlugin *plugin) VS_NOEXCEPT; /* pass NULL to get the first plugin function */ - VSPluginFunction *(VS_CC *getPluginFunctionByName)(const char *name, VSPlugin *plugin) VS_NOEXCEPT; - const char *(VS_CC *getPluginFunctionName)(VSPluginFunction *func) VS_NOEXCEPT; - const char *(VS_CC *getPluginFunctionArguments)(VSPluginFunction *func) VS_NOEXCEPT; /* returns an argument format string */ - const char *(VS_CC *getPluginFunctionReturnType)(VSPluginFunction *func) VS_NOEXCEPT; /* returns an argument format string */ - const char *(VS_CC *getPluginPath)(const VSPlugin *plugin) VS_NOEXCEPT; /* the full path to the loaded library file containing the plugin entry point */ - int (VS_CC *getPluginVersion)(const VSPlugin *plugin) VS_NOEXCEPT; - VSMap *(VS_CC *invoke)(VSPlugin *plugin, const char *name, const VSMap *args) VS_NOEXCEPT; /* user must free the returned VSMap */ - - /* Core and information */ - VSCore *(VS_CC *createCore)(int flags) VS_NOEXCEPT; /* flags uses the VSCoreFlags enum */ - void (VS_CC *freeCore)(VSCore *core) VS_NOEXCEPT; /* only call this function after all node, frame and function references belonging to the core have been freed */ - int64_t(VS_CC *setMaxCacheSize)(int64_t bytes, VSCore *core) VS_NOEXCEPT; /* the total cache size at which vapoursynth more aggressively tries to reclaim memory, it is not a hard limit */ - int (VS_CC *setThreadCount)(int threads, VSCore *core) VS_NOEXCEPT; /* setting threads to 0 means automatic detection */ - void (VS_CC *getCoreInfo)(VSCore *core, VSCoreInfo *info) VS_NOEXCEPT; - int (VS_CC *getAPIVersion)(void) VS_NOEXCEPT; - - /* Message handler */ - void (VS_CC *logMessage)(int msgType, const char *msg, VSCore *core) VS_NOEXCEPT; - VSLogHandle *(VS_CC *addLogHandler)(VSLogHandler handler, VSLogHandlerFree free, void *userData, VSCore *core) VS_NOEXCEPT; /* free and userData can be NULL, returns a handle that can be passed to removeLogHandler */ - int (VS_CC *removeLogHandler)(VSLogHandle *handle, VSCore *core) VS_NOEXCEPT; /* returns non-zero if successfully removed */ - - /* Graph information */ - - /* - * NOT PART OF THE STABLE API! - * These functions only exist to retrieve internal details for debug purposes and graph visualization - * They will only only work properly when used on a core created with cfEnableGraphInspection and are - * not safe to use concurrently with frame requests or other API functions - * NOT PART OF THE STABLE API! - */ - - const char *(VS_CC *getNodeCreationFunctionName)(VSNode *node, int level) VS_NOEXCEPT; /* level=0 returns the name of the function that created the filter, specifying a higher level will retrieve the function above that invoked it or NULL if a non-existent level is requested */ - const VSMap *(VS_CC *getNodeCreationFunctionArguments)(VSNode *node, int level) VS_NOEXCEPT; /* level=0 returns a copy of the arguments passed to the function that created the filter, returns NULL if a non-existent level is requested */ - const char *(VS_CC *getNodeName)(VSNode *node) VS_NOEXCEPT; /* the name passed to create*Filter */ - int (VS_CC *getNodeFilterMode)(VSNode *node) VS_NOEXCEPT; /* VSFilterMode */ - int64_t (VS_CC *getNodeFilterTime)(VSNode *node) VS_NOEXCEPT; /* time spent processing frames in nanoseconds */ - const VSFilterDependency *(VS_CC *getNodeDependencies)(VSNode *node) VS_NOEXCEPT; - int (VS_CC *getNumNodeDependencies)(VSNode *node) VS_NOEXCEPT; -}; - -VS_API(const VSAPI *) getVapourSynthAPI(int version) VS_NOEXCEPT; - -#endif /* VAPOURSYNTH4_H */ diff --git a/thirdparty/ffms2/src/vapoursynth/vapoursource4.cpp b/thirdparty/ffms2/src/vapoursynth/vapoursource4.cpp deleted file mode 100644 index 043e41740..000000000 --- a/thirdparty/ffms2/src/vapoursynth/vapoursource4.cpp +++ /dev/null @@ -1,408 +0,0 @@ -// Copyright (c) 2012-2018 Fredrik Mellbin -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#include "vapoursource4.h" -#include "VSHelper4.h" -#include "../core/utils.h" - -#include -#include -#include -#include -#include -#include - -static int GetNumPixFmts() { - int n = 0; - while (av_get_pix_fmt_name((AVPixelFormat)n)) - n++; - return n; -} - -static bool IsRealNativeEndianPlanar(const AVPixFmtDescriptor &desc) { - // reject all special flags - if (desc.flags & (AV_PIX_FMT_FLAG_PAL | AV_PIX_FMT_FLAG_BAYER | AV_PIX_FMT_FLAG_HWACCEL | AV_PIX_FMT_FLAG_BITSTREAM)) - return false; - int used_planes = 0; - for (int i = 0; i < desc.nb_components; i++) - used_planes = std::max(used_planes, (int)desc.comp[i].plane + 1); - bool temp = (used_planes == desc.nb_components) && (desc.comp[0].depth >= 8); - if (!temp) - return false; - else if (desc.comp[0].depth == 8) - return temp; - else - return (AV_PIX_FMT_YUV420P10 == AV_PIX_FMT_YUV420P10BE ? !!(desc.flags & AV_PIX_FMT_FLAG_BE) : !(desc.flags & AV_PIX_FMT_FLAG_BE)); -} - -static int GetSampleType(const AVPixFmtDescriptor &desc) { - return (desc.flags & AV_PIX_FMT_FLAG_FLOAT) ? stFloat : stInteger; -} - -static bool HasAlpha(const AVPixFmtDescriptor &desc) { - return !!(desc.flags & AV_PIX_FMT_FLAG_ALPHA); -} - -static int GetColorFamily(const AVPixFmtDescriptor &desc) { - if (desc.nb_components <= 2) - return cfGray; - else if (desc.flags & AV_PIX_FMT_FLAG_RGB) - return cfRGB; - else - return cfYUV; -} - -static int FormatConversionToPixelFormat(int id, bool alpha, VSCore *core, const VSAPI *vsapi) { - VSVideoFormat f; - vsapi->getVideoFormatByID(&f, id, core); - int npixfmt = GetNumPixFmts(); - // Look for a suitable format without alpha first to not waste memory - if (!alpha) { - for (int i = 0; i < npixfmt; i++) { - const AVPixFmtDescriptor &desc = *av_pix_fmt_desc_get((AVPixelFormat)i); - if (IsRealNativeEndianPlanar(desc) && !HasAlpha(desc) - && GetColorFamily(desc) == f.colorFamily - && desc.comp[0].depth == f.bitsPerSample - && desc.log2_chroma_w == f.subSamplingW - && desc.log2_chroma_h == f.subSamplingH - && GetSampleType(desc) == f.sampleType) - return i; - } - } - // Try all remaining formats - for (int i = 0; i < npixfmt; i++) { - const AVPixFmtDescriptor &desc = *av_pix_fmt_desc_get((AVPixelFormat)i); - if (IsRealNativeEndianPlanar(desc) && HasAlpha(desc) - && GetColorFamily(desc) == f.colorFamily - && desc.comp[0].depth == f.bitsPerSample - && desc.log2_chroma_w == f.subSamplingW - && desc.log2_chroma_h == f.subSamplingH - && GetSampleType(desc) == f.sampleType) - return i; - } - return AV_PIX_FMT_NONE; -} - -static void FormatConversionToVS(VSVideoFormat &f, int id, VSCore *core, const VSAPI *vsapi) { - const AVPixFmtDescriptor &desc = *av_pix_fmt_desc_get((AVPixelFormat)id); - vsapi->queryVideoFormat(&f, - GetColorFamily(desc), - GetSampleType(desc), - desc.comp[0].depth, - desc.log2_chroma_w, - desc.log2_chroma_h, core); -} - -const VSFrame *VS_CC VSVideoSource4::GetVSFrame(int n, VSCore *core, const VSAPI *vsapi) { - char ErrorMsg[1024]; - FFMS_ErrorInfo E; - E.Buffer = ErrorMsg; - E.BufferSize = sizeof(ErrorMsg); - - VSFrame *Dst = vsapi->newVideoFrame(&VI[0].format, VI[0].width, VI[0].height, nullptr, core); - VSMap *Props = vsapi->getFramePropertiesRW(Dst); - - const FFMS_Frame *Frame = nullptr; - - if (FPSNum > 0 && FPSDen > 0) { - double currentTime = FFMS_GetVideoProperties(V)->FirstTime + - (double)(n * (int64_t)FPSDen) / FPSNum; - Frame = FFMS_GetFrameByTime(V, currentTime, &E); - vsapi->mapSetInt(Props, "_DurationNum", FPSDen, maReplace); - vsapi->mapSetInt(Props, "_DurationDen", FPSNum, maReplace); - vsapi->mapSetFloat(Props, "_AbsoluteTime", currentTime, maReplace); - } else { - Frame = FFMS_GetFrame(V, n, &E); - FFMS_Track *T = FFMS_GetTrackFromVideo(V); - const FFMS_TrackTimeBase *TB = FFMS_GetTimeBase(T); - int64_t num; - if (n + 1 < VI[0].numFrames) - num = FFMS_GetFrameInfo(T, n + 1)->PTS - FFMS_GetFrameInfo(T, n)->PTS; - else if (n > 0) // simply use the second to last frame's duration for the last one, should be good enough - num = FFMS_GetFrameInfo(T, n)->PTS - FFMS_GetFrameInfo(T, n - 1)->PTS; - else // just make it one timebase if it's a single frame clip - num = 1; - int64_t DurNum = TB->Num * num; - int64_t DurDen = TB->Den * 1000; - vsh::muldivRational(&DurNum, &DurDen, 1, 1); - vsapi->mapSetInt(Props, "_DurationNum", DurNum, maReplace); - vsapi->mapSetInt(Props, "_DurationDen", DurDen, maReplace); - vsapi->mapSetFloat(Props, "_AbsoluteTime", ((static_cast(TB->Num) / 1000) * FFMS_GetFrameInfo(T, n)->PTS) / TB->Den, maReplace); - } - - if (Frame == nullptr) - throw std::runtime_error(E.Buffer); - - // Set AR variables - if (SARNum > 0 && SARDen > 0) { - vsapi->mapSetInt(Props, "_SARNum", SARNum, maReplace); - vsapi->mapSetInt(Props, "_SARDen", SARDen, maReplace); - } - - vsapi->mapSetInt(Props, "_Matrix", Frame->ColorSpace, maReplace); - vsapi->mapSetInt(Props, "_Primaries", Frame->ColorPrimaries, maReplace); - vsapi->mapSetInt(Props, "_Transfer", Frame->TransferCharateristics, maReplace); - if (Frame->ChromaLocation > 0) - vsapi->mapSetInt(Props, "_ChromaLocation", Frame->ChromaLocation - 1, maReplace); - - if (Frame->ColorRange == FFMS_CR_MPEG) - vsapi->mapSetInt(Props, "_ColorRange", 1, maReplace); - else if (Frame->ColorRange == FFMS_CR_JPEG) - vsapi->mapSetInt(Props, "_ColorRange", 0, maReplace); - vsapi->mapSetData(Props, "_PictType", &Frame->PictType, 1, dtUtf8, maReplace); - - // Set field information - int FieldBased = 0; - if (Frame->InterlacedFrame) - FieldBased = (Frame->TopFieldFirst ? 2 : 1); - vsapi->mapSetInt(Props, "_FieldBased", FieldBased, maReplace); - - if (Frame->HasMasteringDisplayPrimaries) { - vsapi->mapSetFloatArray(Props, "MasteringDisplayPrimariesX", Frame->MasteringDisplayPrimariesX, 3); - vsapi->mapSetFloatArray(Props, "MasteringDisplayPrimariesY", Frame->MasteringDisplayPrimariesY, 3); - vsapi->mapSetFloat(Props, "MasteringDisplayWhitePointX", Frame->MasteringDisplayWhitePointX, maReplace); - vsapi->mapSetFloat(Props, "MasteringDisplayWhitePointY", Frame->MasteringDisplayWhitePointY, maReplace); - } - - if (Frame->HasMasteringDisplayLuminance) { - vsapi->mapSetFloat(Props, "MasteringDisplayMinLuminance", Frame->MasteringDisplayMinLuminance, maReplace); - vsapi->mapSetFloat(Props, "MasteringDisplayMaxLuminance", Frame->MasteringDisplayMaxLuminance, maReplace); - } - - if (Frame->HasContentLightLevel) { - vsapi->mapSetFloat(Props, "ContentLightLevelMax", Frame->ContentLightLevelMax, maReplace); - vsapi->mapSetFloat(Props, "ContentLightLevelAverage", Frame->ContentLightLevelAverage, maReplace); - } - - if (Frame->DolbyVisionRPU && Frame->DolbyVisionRPUSize > 0) { - vsapi->mapSetData(Props, "DolbyVisionRPU", reinterpret_cast(Frame->DolbyVisionRPU), Frame->DolbyVisionRPUSize, dtBinary, maReplace); - } - - if (Frame->HDR10Plus && Frame->HDR10PlusSize > 0) { - vsapi->mapSetData(Props, "HDR10Plus", reinterpret_cast(Frame->HDR10Plus), Frame->HDR10PlusSize, dtBinary, maReplace); - } - - OutputFrame(Frame, Dst, vsapi); - if (OutputAlpha) { - VSFrame *AlphaDst = vsapi->newVideoFrame(&VI[1].format, VI[1].width, VI[1].height, nullptr, core); - vsapi->mapSetInt(vsapi->getFramePropertiesRW(AlphaDst), "_ColorRange", 0, maReplace); - OutputAlphaFrame(Frame, VI[0].format.numPlanes, AlphaDst, vsapi); - vsapi->mapConsumeFrame(Props, "_Alpha", AlphaDst, maReplace); - } - - const FFMS_VideoProperties *VP = FFMS_GetVideoProperties(V); - vsapi->mapSetInt(Props, "Flip", VP->Flip, maReplace); - vsapi->mapSetInt(Props, "Rotation", VP->Rotation, maReplace); - - return Dst; -} - -const VSFrame *VS_CC VSVideoSource4::GetFrame(int n, int activationReason, void *instanceData, void **, VSFrameContext *frameCtx, VSCore *core, const VSAPI *vsapi) { - VSVideoSource4 *vs = static_cast(instanceData); - if (activationReason == arInitial) { - if (vs->LastFrame < n && vs->LastFrame > n - vs->CacheThreshold) { - for (int i = vs->LastFrame + 1; i < n; i++) { - try { - const VSFrame *frame = vs->GetVSFrame(i, core, vsapi); - vsapi->cacheFrame(frame, i, frameCtx); - vsapi->freeFrame(frame); - } catch (std::runtime_error &) { - // don't care if it errors out on frames we don't actually have to deliver - } - } - } - - try { - const VSFrame *frame = vs->GetVSFrame(n, core, vsapi); - vs->LastFrame = n; - return frame; - } catch (std::runtime_error &e) { - vsapi->setFilterError(e.what(), frameCtx); - } - - } - - return nullptr; -} - -void VS_CC VSVideoSource4::Free(void *instanceData, VSCore *, const VSAPI *) { - FFMS_Deinit(); - delete static_cast(instanceData); -} - -VSVideoSource4::VSVideoSource4(const char *SourceFile, int Track, FFMS_Index *Index, - int AFPSNum, int AFPSDen, int Threads, int SeekMode, int /*RFFMode*/, - int ResizeToWidth, int ResizeToHeight, const char *ResizerName, - int Format, bool OutputAlpha, const VSAPI *vsapi, VSCore *core) - : FPSNum(AFPSNum), FPSDen(AFPSDen), OutputAlpha(OutputAlpha) { - - VI[0] = {}; - VI[1] = {}; - - char ErrorMsg[1024]; - FFMS_ErrorInfo E; - E.Buffer = ErrorMsg; - E.BufferSize = sizeof(ErrorMsg); - - V = FFMS_CreateVideoSource(SourceFile, Track, Index, Threads, SeekMode, &E); - if (!V) { - throw std::runtime_error(std::string("Source: ") + E.Buffer); - } - try { - InitOutputFormat(ResizeToWidth, ResizeToHeight, ResizerName, Format, vsapi, core); - } catch (std::exception &) { - FFMS_DestroyVideoSource(V); - throw; - } - - const FFMS_VideoProperties *VP = FFMS_GetVideoProperties(V); - - if (FPSNum > 0 && FPSDen > 0) { - vsh::muldivRational(&FPSNum, &FPSDen, 1, 1); - VI[0].fpsDen = FPSDen; - VI[0].fpsNum = FPSNum; - if (VP->NumFrames > 1) { - VI[0].numFrames = static_cast((VP->LastTime - VP->FirstTime) * (1 + 1. / (VP->NumFrames - 1)) * FPSNum / FPSDen + 0.5); - if (VI[0].numFrames < 1) - VI[0].numFrames = 1; - } else { - VI[0].numFrames = 1; - } - } else { - VI[0].fpsDen = VP->FPSDenominator; - VI[0].fpsNum = VP->FPSNumerator; - VI[0].numFrames = VP->NumFrames; - vsh::muldivRational(&VI[0].fpsNum, &VI[0].fpsDen, 1, 1); - } - - if (OutputAlpha) { - VI[1] = VI[0]; - vsapi->queryVideoFormat(&VI[1].format, cfGray, VI[0].format.sampleType, VI[0].format.bitsPerSample, 0, 0, core); - } - - SARNum = VP->SARNum; - SARDen = VP->SARDen; -} - -VSVideoSource4::~VSVideoSource4() { - FFMS_DestroyVideoSource(V); -} - -const VSVideoInfo *VSVideoSource4::GetVideoInfo() const { - return &VI[0]; -} - -void VSVideoSource4::SetCacheThreshold(int threshold) { - CacheThreshold = threshold; -} - -void VSVideoSource4::InitOutputFormat(int ResizeToWidth, int ResizeToHeight, - const char *ResizerName, int ConvertToFormat, const VSAPI *vsapi, VSCore *core) { - - char ErrorMsg[1024]; - FFMS_ErrorInfo E; - E.Buffer = ErrorMsg; - E.BufferSize = sizeof(ErrorMsg); - - const FFMS_Frame *F = FFMS_GetFrame(V, 0, &E); - if (!F) { - std::string buf = "Source: "; - buf += E.Buffer; - throw std::runtime_error(buf); - } - - std::vector TargetFormats; - int npixfmt = GetNumPixFmts(); - for (int i = 0; i < npixfmt; i++) - if (IsRealNativeEndianPlanar(*av_pix_fmt_desc_get((AVPixelFormat)i))) - TargetFormats.push_back(i); - TargetFormats.push_back(AV_PIX_FMT_NONE); - - int TargetPixelFormat = AV_PIX_FMT_NONE; - if (ConvertToFormat != pfNone) { - TargetPixelFormat = FormatConversionToPixelFormat(ConvertToFormat, OutputAlpha, core, vsapi); - if (TargetPixelFormat == AV_PIX_FMT_NONE) - throw std::runtime_error(std::string("Source: Invalid output colorspace specified")); - - TargetFormats.clear(); - TargetFormats.push_back(TargetPixelFormat); - TargetFormats.push_back(-1); - } - - if (ResizeToWidth <= 0) - ResizeToWidth = F->EncodedWidth; - - if (ResizeToHeight <= 0) - ResizeToHeight = F->EncodedHeight; - - int Resizer = ResizerNameToSWSResizer(ResizerName); - if (Resizer == 0) - throw std::runtime_error(std::string("Source: Invalid resizer name specified")); - - if (FFMS_SetOutputFormatV2(V, &TargetFormats[0], - ResizeToWidth, ResizeToHeight, Resizer, &E)) - throw std::runtime_error(std::string("Source: No suitable output format found")); - - F = FFMS_GetFrame(V, 0, &E); - TargetFormats.clear(); - TargetFormats.push_back(F->ConvertedPixelFormat); - TargetFormats.push_back(-1); - - // This trick is required to first get the "best" default format and then set only that format as the output - if (FFMS_SetOutputFormatV2(V, TargetFormats.data(), ResizeToWidth, ResizeToHeight, Resizer, &E)) - throw std::runtime_error(std::string("Source: No suitable output format found")); - - F = FFMS_GetFrame(V, 0, &E); - - // Don't output alpha if the clip doesn't have it - if (!HasAlpha(*av_pix_fmt_desc_get((AVPixelFormat)F->ConvertedPixelFormat))) - OutputAlpha = false; - - FormatConversionToVS(VI[0].format, F->ConvertedPixelFormat, core, vsapi); - if (VI[0].format.colorFamily == cfUndefined) - throw std::runtime_error(std::string("Source: No suitable output format found")); - - VI[0].width = F->ScaledWidth; - VI[0].height = F->ScaledHeight; - - // Crop to obey subsampling width/height requirements - VI[0].width -= VI[0].width % (1 << VI[0].format.subSamplingW); - VI[0].height -= VI[0].height % (1 << VI[0].format.subSamplingH); -} - -void VSVideoSource4::OutputFrame(const FFMS_Frame *Frame, VSFrame *Dst, const VSAPI *vsapi) { - const int RGBPlaneOrder[3] = { 2, 0, 1 }; - const VSVideoFormat *fi = vsapi->getVideoFrameFormat(Dst); - if (fi->colorFamily == cfRGB) { - for (int i = 0; i < fi->numPlanes; i++) - vsh::bitblt(vsapi->getWritePtr(Dst, i), vsapi->getStride(Dst, i), Frame->Data[RGBPlaneOrder[i]], Frame->Linesize[RGBPlaneOrder[i]], - vsapi->getFrameWidth(Dst, i) * fi->bytesPerSample, vsapi->getFrameHeight(Dst, i)); - } else { - for (int i = 0; i < fi->numPlanes; i++) - vsh::bitblt(vsapi->getWritePtr(Dst, i), vsapi->getStride(Dst, i), Frame->Data[i], Frame->Linesize[i], - vsapi->getFrameWidth(Dst, i) * fi->bytesPerSample, vsapi->getFrameHeight(Dst, i)); - } -} - -void VSVideoSource4::OutputAlphaFrame(const FFMS_Frame *Frame, int Plane, VSFrame *Dst, const VSAPI *vsapi) { - const VSVideoFormat *fi = vsapi->getVideoFrameFormat(Dst); - vsh::bitblt(vsapi->getWritePtr(Dst, 0), vsapi->getStride(Dst, 0), Frame->Data[Plane], Frame->Linesize[Plane], - vsapi->getFrameWidth(Dst, 0) * fi->bytesPerSample, vsapi->getFrameHeight(Dst, 0)); -} diff --git a/thirdparty/ffms2/src/vapoursynth/vapoursource4.h b/thirdparty/ffms2/src/vapoursynth/vapoursource4.h deleted file mode 100644 index c57f058b8..000000000 --- a/thirdparty/ffms2/src/vapoursynth/vapoursource4.h +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) 2012-2017 Fredrik Mellbin -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#ifndef FFVAPOURSOURCES_H -#define FFVAPOURSOURCES_H - -extern "C" { -#include -#include -#include -#include -#include -#include -} - -#include "VapourSynth4.h" -#include "ffms.h" -#include "ffmscompat.h" - -struct VSVideoSource4 { -private: - VSVideoInfo VI[2]; - FFMS_VideoSource *V; - int64_t FPSNum; - int64_t FPSDen; - int SARNum; - int SARDen; - bool OutputAlpha; - int LastFrame = -1; - int CacheThreshold = 0; - - void InitOutputFormat(int ResizeToWidth, int ResizeToHeight, - const char *ResizerName, int ConvertToFormat, const VSAPI *vsapi, VSCore *core); - static void OutputFrame(const FFMS_Frame *Frame, VSFrame *Dst, const VSAPI *vsapi); - static void OutputAlphaFrame(const FFMS_Frame *Frame, int Plane, VSFrame *Dst, const VSAPI *vsapi); -public: - VSVideoSource4(const char *SourceFile, int Track, FFMS_Index *Index, - int AFPSNum, int AFPSDen, int Threads, int SeekMode, int RFFMode, - int ResizeToWidth, int ResizeToHeight, const char *ResizerName, - int Format, bool OutputAlpha, const VSAPI *vsapi, VSCore *core); - ~VSVideoSource4(); - - const VSVideoInfo *GetVideoInfo() const; - void SetCacheThreshold(int threshold); - - static void VS_CC Init(VSMap *in, VSMap *out, void **instanceData, VSNode *node, VSCore *core, const VSAPI *vsapi); - const VSFrame *VS_CC GetVSFrame(int n, VSCore *core, const VSAPI *vsapi); - static const VSFrame *VS_CC GetFrame(int n, int activationReason, void *instanceData, void **frameData, VSFrameContext *frameCtx, VSCore *core, const VSAPI *vsapi); - static void VS_CC Free(void *instanceData, VSCore *core, const VSAPI *vsapi); -}; - -#endif diff --git a/thirdparty/ffms2/src/vapoursynth/vapoursynth4.cpp b/thirdparty/ffms2/src/vapoursynth/vapoursynth4.cpp deleted file mode 100644 index 601429779..000000000 --- a/thirdparty/ffms2/src/vapoursynth/vapoursynth4.cpp +++ /dev/null @@ -1,243 +0,0 @@ -// Copyright (c) 2012-2017 Fredrik Mellbin -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#include "ffms.h" -#include "vapoursource4.h" -#include "VSHelper4.h" -#include "../core/utils.h" - -#include -#include -#include -#include - -static void VS_CC CreateIndex(const VSMap *in, VSMap *out, void *, VSCore *, const VSAPI *vsapi) { - FFMS_Init(0, 0); - - char ErrorMsg[1024]; - FFMS_ErrorInfo E; - E.Buffer = ErrorMsg; - E.BufferSize = sizeof(ErrorMsg); - int err; - - std::set IndexTracks; - - const char *Source = vsapi->mapGetData(in, "source", 0, nullptr); - const char *CacheFile = vsapi->mapGetData(in, "cachefile", 0, &err); - - int NumIndexTracks = vsapi->mapNumElements(in, "indextracks"); - bool IndexAllTracks = (NumIndexTracks == 1) && (vsapi->mapGetIntSaturated(in, "indextracks", 0, nullptr) == -1); - if (!IndexAllTracks) { - for (int i = 0; i < NumIndexTracks; i++) { - int Track = vsapi->mapGetIntSaturated(in, "indextracks", i, nullptr); - IndexTracks.insert(Track); - } - } - - int ErrorHandling = vsapi->mapGetIntSaturated(in, "errorhandling", 0, &err); - if (err) - ErrorHandling = FFMS_IEH_IGNORE; - bool OverWrite = !!vsapi->mapGetInt(in, "overwrite", 0, &err); - - std::string DefaultCache(Source); - if (!CacheFile || !strcmp(CacheFile, "")) { - DefaultCache.append(".ffindex"); - CacheFile = DefaultCache.c_str(); - } - - bool EnableDrefs = !!vsapi->mapGetInt(in, "enable_drefs", 0, &err); - bool UseAbsolutePath = !!vsapi->mapGetInt(in, "use_absolute_path", 0, &err); - - FFMS_Index *Index = FFMS_ReadIndex(CacheFile, &E); - if (OverWrite || !Index || (Index && FFMS_IndexBelongsToFile(Index, Source, nullptr) != FFMS_ERROR_SUCCESS)) { - FFMS_KeyValuePair LAVFOpts[] = {{ "enable_drefs", EnableDrefs ? "1" : "0" }, { "use_absolute_path", UseAbsolutePath ? "1" : "0" }}; - FFMS_Indexer *Indexer = FFMS_CreateIndexer2(Source, LAVFOpts, 2, &E); - if (!Indexer) { - FFMS_DestroyIndex(Index); - return vsapi->mapSetError(out, (std::string("Index: ") + E.Buffer).c_str()); - } - - if (IndexAllTracks) { - FFMS_TrackTypeIndexSettings(Indexer, FFMS_TYPE_AUDIO, 1, 0); - } else { - for (int i : IndexTracks) - FFMS_TrackIndexSettings(Indexer, i, 1, 0); - } - - Index = FFMS_DoIndexing2(Indexer, ErrorHandling, &E); - if (!Index) - return vsapi->mapSetError(out, (std::string("Index: ") + E.Buffer).c_str()); - if (FFMS_WriteIndex(CacheFile, Index, &E)) { - FFMS_DestroyIndex(Index); - return vsapi->mapSetError(out, (std::string("Index: ") + E.Buffer).c_str()); - } - FFMS_DestroyIndex(Index); - if (!OverWrite) - vsapi->mapSetData(out, "result", "Index generated", -1, dtUtf8, maReplace); - else - vsapi->mapSetData(out, "result", "Index generated (forced overwrite)", -1, dtUtf8, maReplace); - } else { - FFMS_DestroyIndex(Index); - vsapi->mapSetData(out, "result", "Valid index already exists", -1, dtUtf8, maReplace); - } - FFMS_Deinit(); -} - -static void VS_CC CreateSource(const VSMap *in, VSMap *out, void *, VSCore *core, const VSAPI *vsapi) { - FFMS_Init(0, 0); - - char ErrorMsg[1024]; - FFMS_ErrorInfo E; - E.Buffer = ErrorMsg; - E.BufferSize = sizeof(ErrorMsg); - int err; - - const char *Source = vsapi->mapGetData(in, "source", 0, nullptr); - int Track = vsapi->mapGetIntSaturated(in, "track", 0, &err); - if (err) - Track = -1; - bool Cache = !!vsapi->mapGetInt(in, "cache", 0, &err); - if (err) - Cache = true; - const char *CacheFile = vsapi->mapGetData(in, "cachefile", 0, &err); - int FPSNum = vsapi->mapGetIntSaturated(in, "fpsnum", 0, &err); - if (err) - FPSNum = -1; - int FPSDen = vsapi->mapGetIntSaturated(in, "fpsden", 0, &err); - if (err) - FPSDen = 1; - int Threads = vsapi->mapGetIntSaturated(in, "threads", 0, &err); - const char *Timecodes = vsapi->mapGetData(in, "timecodes", 0, &err); - int SeekMode = vsapi->mapGetIntSaturated(in, "seekmode", 0, &err); - if (err) - SeekMode = FFMS_SEEK_NORMAL; - int RFFMode = vsapi->mapGetIntSaturated(in, "rffmode", 0, &err); - int Width = vsapi->mapGetIntSaturated(in, "width", 0, &err); - int Height = vsapi->mapGetIntSaturated(in, "height", 0, &err); - const char *Resizer = vsapi->mapGetData(in, "resizer", 0, &err); - if (err) - Resizer = "BICUBIC"; - int Format = vsapi->mapGetIntSaturated(in, "format", 0, &err); - - bool OutputAlpha = !!vsapi->mapGetInt(in, "alpha", 0, &err); - - if (FPSDen < 1) - return vsapi->mapSetError(out, "Source: FPS denominator needs to be 1 or higher"); - if (Track <= -2) - return vsapi->mapSetError(out, "Source: No video track selected"); - if (SeekMode < -1 || SeekMode > 3) - return vsapi->mapSetError(out, "Source: Invalid seekmode selected"); - if (RFFMode < 0 || RFFMode > 2) - return vsapi->mapSetError(out, "Source: Invalid RFF mode selected"); - if (RFFMode > 0 && FPSNum > 0) - return vsapi->mapSetError(out, "Source: RFF modes may not be combined with CFR conversion"); - if (Timecodes && IsSamePath(Source, Timecodes)) - return vsapi->mapSetError(out, "Source: Timecodes will overwrite the source"); - - FFMS_Index *Index = nullptr; - std::string DefaultCache; - if (Cache) { - if (CacheFile && *CacheFile) { - if (IsSamePath(Source, CacheFile)) - return vsapi->mapSetError(out, "Source: Cache will overwrite the source"); - Index = FFMS_ReadIndex(CacheFile, &E); - } else { - DefaultCache = Source; - DefaultCache += ".ffindex"; - CacheFile = DefaultCache.c_str(); - Index = FFMS_ReadIndex(CacheFile, &E); - // Reindex if the index doesn't match the file and its name wasn't - // explicitly given - if (Index && FFMS_IndexBelongsToFile(Index, Source, nullptr) != FFMS_ERROR_SUCCESS) { - FFMS_DestroyIndex(Index); - Index = nullptr; - } - } - } - - if (!Index) { - FFMS_Indexer *Indexer = FFMS_CreateIndexer(Source, &E); - if (!Indexer) - return vsapi->mapSetError(out, (std::string("Index: ") + E.Buffer).c_str()); - - Index = FFMS_DoIndexing2(Indexer, FFMS_IEH_CLEAR_TRACK, &E); - if (!Index) - return vsapi->mapSetError(out, (std::string("Index: ") + E.Buffer).c_str()); - - if (Cache) - if (FFMS_WriteIndex(CacheFile, Index, &E)) { - FFMS_DestroyIndex(Index); - return vsapi->mapSetError(out, (std::string("Index: ") + E.Buffer).c_str()); - } - } - - if (Track == -1) - Track = FFMS_GetFirstIndexedTrackOfType(Index, FFMS_TYPE_VIDEO, &E); - if (Track < 0) { - FFMS_DestroyIndex(Index); - return vsapi->mapSetError(out, "Source: No video track found"); - } - - if (Timecodes && strcmp(Timecodes, "")) { - if (FFMS_WriteTimecodes(FFMS_GetTrackFromIndex(Index, Track), Timecodes, &E)) { - FFMS_DestroyIndex(Index); - return vsapi->mapSetError(out, (std::string("Index: ") + E.Buffer).c_str()); - } - } - - VSVideoSource4 *vs; - try { - vs = new VSVideoSource4(Source, Track, Index, FPSNum, FPSDen, Threads, SeekMode, RFFMode, Width, Height, Resizer, Format, OutputAlpha, vsapi, core); - } catch (std::exception const& e) { - FFMS_DestroyIndex(Index); - return vsapi->mapSetError(out, e.what()); - } - - VSNode *node = vsapi->createVideoFilter2("Source", vs->GetVideoInfo(), VSVideoSource4::GetFrame, VSVideoSource4::Free, fmUnordered, nullptr, 0, vs, core); - vs->SetCacheThreshold(vsapi->setLinearFilter(node)); - vsapi->mapConsumeNode(out, "clip", node, maAppend); - - FFMS_DestroyIndex(Index); -} - -static void VS_CC GetLogLevel(const VSMap *, VSMap *out, void *, VSCore *, const VSAPI *vsapi) { - vsapi->mapSetInt(out, "level", FFMS_GetLogLevel(), maReplace); -} - -static void VS_CC SetLogLevel(const VSMap *in, VSMap *out, void *, VSCore *, const VSAPI *vsapi) { - FFMS_SetLogLevel(vsapi->mapGetIntSaturated(in, "level", 0, nullptr)); - vsapi->mapSetInt(out, "level", FFMS_GetLogLevel(), maReplace); -} - -static void VS_CC GetVersion(const VSMap *, VSMap *out, void *, VSCore *, const VSAPI *vsapi) { - int Version = FFMS_GetVersion(); - char buf[100]; - sprintf(buf, "%d.%d.%d.%d", Version >> 24, (Version & 0xFF0000) >> 16, (Version & 0xFF00) >> 8, Version & 0xFF); - vsapi->mapSetData(out, "version", buf, -1, maReplace, dtUtf8); -} - -VS_EXTERNAL_API(void) VapourSynthPluginInit2(VSPlugin *plugin, const VSPLUGINAPI *vspapi) { - vspapi->configPlugin("com.vapoursynth.ffms2", "ffms2", "FFmpegSource 2 for VapourSynth", FFMS_GetVersion(), VAPOURSYNTH_API_VERSION, 0, plugin); - vspapi->registerFunction("Index", "source:data;cachefile:data:opt;indextracks:int[]:opt;errorhandling:int:opt;overwrite:int:opt;enable_drefs:int:opt;use_absolute_path:int:opt;", "result:data;", CreateIndex, nullptr, plugin); - vspapi->registerFunction("Source", "source:data;track:int:opt;cache:int:opt;cachefile:data:opt;fpsnum:int:opt;fpsden:int:opt;threads:int:opt;timecodes:data:opt;seekmode:int:opt;width:int:opt;height:int:opt;resizer:data:opt;format:int:opt;alpha:int:opt;", "clip:vnode;", CreateSource, nullptr, plugin); - vspapi->registerFunction("GetLogLevel", "", "level:int;", GetLogLevel, nullptr, plugin); - vspapi->registerFunction("SetLogLevel", "level:int;", "level:int;", SetLogLevel, nullptr, plugin); - vspapi->registerFunction("Version", "", "version:data;", GetVersion, nullptr, plugin); -} diff --git a/thirdparty/ffms2/test/data/data.h b/thirdparty/ffms2/test/data/data.h deleted file mode 100644 index e7ef1f7fb..000000000 --- a/thirdparty/ffms2/test/data/data.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _TEST_DATA_H -#define _TEST_DATA_H - -#include - -typedef struct TestFrameData { - int64_t PTS; - int64_t Duration; - int Width; - int Height; - const char *PixelFormat; - bool Keyframe; - uint8_t SHA256[32]; // SHA256 of the frame's decode planes -} TestFrameData; - -#endif diff --git a/thirdparty/ffms2/test/data/test.mp4.cpp b/thirdparty/ffms2/test/data/test.mp4.cpp deleted file mode 100644 index b8ba29acb..000000000 --- a/thirdparty/ffms2/test/data/test.mp4.cpp +++ /dev/null @@ -1,95 +0,0 @@ -// Autogenerated from test.mp4 by gendata with ffmpeg version N-91852-gf55d987bad - -#ifndef _FFMS_TEST_TESTMP4DATA_H -#define _FFMS_TEST_TESTMP4DATA_H - -#include "data.h" - -const TestFrameData testmp4data[84] = { - { 0, 1001, 960, 540, "yuv420p", true, { 0x70, 0x81, 0xF9, 0x06, 0xCA, 0x58, 0xCA, 0x64, 0x8D, 0x38, 0x27, 0xB9, 0x2B, 0x40, 0x0E, 0x7C, 0xA0, 0x09, 0xBB, 0x65, 0xF7, 0xD6, 0x2F, 0x58, 0xAF, 0x5D, 0xCB, 0x58, 0xCE, 0xF2, 0x0B, 0x19 } }, - { 1001, 1001, 960, 540, "yuv420p", false, { 0x10, 0x8D, 0x32, 0xDD, 0x97, 0x04, 0x92, 0xF1, 0x8A, 0x2C, 0xBE, 0xA2, 0xC5, 0x8E, 0x0B, 0x7A, 0xF9, 0xA1, 0xF7, 0x93, 0xA3, 0xA8, 0xE1, 0xB9, 0x84, 0xCC, 0xB1, 0x37, 0x53, 0x21, 0xAA, 0x26 } }, - { 2002, 1001, 960, 540, "yuv420p", false, { 0x1D, 0xD7, 0x53, 0x52, 0x95, 0x1E, 0x42, 0xA1, 0xDF, 0x51, 0x59, 0x86, 0x7F, 0xA8, 0xA6, 0xB5, 0x48, 0xD4, 0xA7, 0x0E, 0x5C, 0xF9, 0x1F, 0x7D, 0x7C, 0x2B, 0x76, 0x82, 0xDF, 0x5E, 0xDA, 0x04 } }, - { 3003, 1001, 960, 540, "yuv420p", false, { 0x79, 0xE8, 0xE9, 0xDA, 0x95, 0xB1, 0xEC, 0x3C, 0x73, 0xE2, 0x10, 0xBF, 0x5C, 0x50, 0x5F, 0x7B, 0x8D, 0x29, 0x76, 0xA2, 0x0C, 0x45, 0xEB, 0xF3, 0xE3, 0xB4, 0xE8, 0xEE, 0x51, 0x53, 0x47, 0x13 } }, - { 4004, 1001, 960, 540, "yuv420p", false, { 0x40, 0x81, 0xC5, 0xDD, 0x3B, 0xD6, 0x8C, 0xC4, 0x24, 0x7D, 0x80, 0xAF, 0xBF, 0x60, 0x66, 0x6E, 0x8C, 0x9B, 0xDD, 0xD1, 0x0F, 0xC1, 0x03, 0x2A, 0xB2, 0x03, 0x40, 0x6F, 0x1B, 0xED, 0x54, 0x90 } }, - { 5005, 1001, 960, 540, "yuv420p", false, { 0xF3, 0xBE, 0xD8, 0xBF, 0xE9, 0x17, 0xD9, 0xAA, 0x3D, 0x20, 0x85, 0x26, 0x35, 0x38, 0x3C, 0x52, 0x63, 0x10, 0x6B, 0x40, 0x1F, 0x55, 0xC7, 0x47, 0xEF, 0x0B, 0x58, 0x9A, 0xDC, 0xD6, 0x9A, 0x97 } }, - { 6006, 1001, 960, 540, "yuv420p", false, { 0x8C, 0x69, 0x01, 0x4E, 0x27, 0x10, 0xCB, 0x2E, 0x7E, 0x59, 0x4D, 0x1F, 0x78, 0x25, 0xAB, 0x1E, 0x8D, 0xED, 0x99, 0x7B, 0xF9, 0xC1, 0x5D, 0xA4, 0xC5, 0x48, 0x7B, 0xFA, 0x2E, 0xCA, 0x61, 0x29 } }, - { 7007, 1001, 960, 540, "yuv420p", false, { 0x37, 0x6F, 0xD8, 0x44, 0x0F, 0xE9, 0x39, 0x33, 0x06, 0xA7, 0x2A, 0xA7, 0xB2, 0x1D, 0x36, 0x30, 0x14, 0xDF, 0x27, 0xB0, 0xF6, 0x2A, 0xDB, 0x57, 0xEB, 0x3E, 0x61, 0xE7, 0xD0, 0xA6, 0xB4, 0x32 } }, - { 8008, 1001, 960, 540, "yuv420p", false, { 0xA2, 0xE8, 0xAD, 0x3B, 0x26, 0x5F, 0x21, 0x93, 0xC8, 0xF2, 0x88, 0x03, 0xF0, 0xAB, 0x95, 0xBB, 0x4F, 0x26, 0x87, 0x70, 0xBE, 0x52, 0x06, 0xC6, 0xB6, 0x0D, 0x5E, 0x7E, 0x4D, 0x2D, 0x1D, 0x3E } }, - { 9009, 1001, 960, 540, "yuv420p", false, { 0xA8, 0xB6, 0x7C, 0x42, 0x03, 0xA3, 0xB4, 0x26, 0x1E, 0x08, 0xC2, 0x23, 0x6D, 0xC0, 0x16, 0x45, 0x9D, 0x62, 0x42, 0x09, 0x98, 0x36, 0x4A, 0x6B, 0x24, 0xDD, 0x03, 0xB3, 0xA9, 0xCB, 0x9A, 0x88 } }, - { 10010, 1001, 960, 540, "yuv420p", false, { 0x91, 0xF2, 0xA4, 0xCA, 0x2C, 0x09, 0xCE, 0x19, 0x78, 0x30, 0x54, 0x72, 0xB1, 0x3B, 0x5D, 0x46, 0x8F, 0xEB, 0x0B, 0xE4, 0xBB, 0xFC, 0x6F, 0x4A, 0x47, 0x5F, 0xB5, 0x23, 0x61, 0x1C, 0x9C, 0x27 } }, - { 11011, 1001, 960, 540, "yuv420p", false, { 0x30, 0xE1, 0x9C, 0x0D, 0xCD, 0xB3, 0x23, 0xE9, 0xBD, 0xA2, 0x51, 0xB0, 0xAF, 0xCB, 0x4E, 0x40, 0x3B, 0x4F, 0x4B, 0x8D, 0xA0, 0xCE, 0x1F, 0x56, 0xFB, 0xB7, 0x8E, 0x4D, 0xE0, 0xCE, 0x53, 0x28 } }, - { 12012, 1001, 960, 540, "yuv420p", false, { 0x12, 0xA5, 0x45, 0x98, 0x31, 0xFF, 0xCB, 0x31, 0x7F, 0x8D, 0x99, 0xCD, 0xEC, 0x82, 0x5D, 0x11, 0x97, 0x7C, 0xE7, 0xF1, 0x13, 0x0D, 0x3D, 0x64, 0x66, 0xBD, 0xF4, 0x37, 0x65, 0xBE, 0xC7, 0xCC } }, - { 13013, 1001, 960, 540, "yuv420p", false, { 0x01, 0x68, 0x57, 0xD7, 0xF9, 0x8A, 0x7D, 0xA2, 0x45, 0x3B, 0xAE, 0x2E, 0xBA, 0x17, 0xBD, 0x32, 0x1A, 0x60, 0xD9, 0x17, 0xCB, 0x62, 0xD4, 0x4D, 0xAD, 0xA1, 0x55, 0xF6, 0xE1, 0xA3, 0x45, 0x86 } }, - { 14014, 1001, 960, 540, "yuv420p", false, { 0x63, 0x78, 0x87, 0x73, 0x35, 0x72, 0xA9, 0xCF, 0x17, 0xEB, 0x88, 0x8A, 0x11, 0x7C, 0x52, 0xFF, 0x93, 0x25, 0xBA, 0xD6, 0xA5, 0xE9, 0xC8, 0xD3, 0x06, 0x99, 0xA0, 0xC8, 0x5C, 0x93, 0xD5, 0x77 } }, - { 15015, 1001, 960, 540, "yuv420p", false, { 0xC6, 0x71, 0xFA, 0xF8, 0x1E, 0x0A, 0x28, 0x01, 0x1D, 0x6D, 0xFD, 0xB9, 0x23, 0xFE, 0x13, 0x4E, 0xD5, 0x6A, 0xEB, 0xB4, 0x5C, 0xBD, 0x53, 0x8C, 0x22, 0xD9, 0xA4, 0xD6, 0x79, 0x6F, 0xCE, 0x6B } }, - { 16016, 1001, 960, 540, "yuv420p", false, { 0x4F, 0x69, 0xF4, 0x53, 0x0D, 0xD3, 0x67, 0x81, 0xB1, 0x73, 0x14, 0x9C, 0x0E, 0x72, 0xD7, 0x39, 0xBC, 0x8E, 0xC2, 0xF4, 0x27, 0x34, 0x5A, 0xD0, 0xE4, 0xC2, 0x7A, 0xE1, 0xE3, 0xFF, 0x9B, 0xCA } }, - { 17017, 1001, 960, 540, "yuv420p", false, { 0x98, 0x35, 0xE9, 0xE6, 0x71, 0x68, 0x62, 0xED, 0xFE, 0x5E, 0x18, 0xB8, 0xD0, 0xD0, 0xFB, 0x9A, 0xF8, 0xEF, 0x7E, 0xEB, 0x1E, 0xB7, 0xBC, 0x59, 0x54, 0x21, 0x58, 0xF7, 0xB7, 0xC2, 0x6C, 0x05 } }, - { 18018, 1001, 960, 540, "yuv420p", false, { 0x0B, 0xC4, 0x89, 0xDE, 0xA3, 0x1E, 0x50, 0x12, 0x71, 0xA9, 0x91, 0x45, 0xD9, 0x4D, 0xB5, 0xAC, 0x37, 0x19, 0x91, 0x3A, 0xC6, 0xA2, 0x22, 0xE5, 0x64, 0xF5, 0x36, 0x94, 0x1E, 0x18, 0x94, 0x74 } }, - { 19019, 1001, 960, 540, "yuv420p", false, { 0x53, 0x83, 0x8B, 0x5E, 0x99, 0x2D, 0xF3, 0x6B, 0xE4, 0x2A, 0x98, 0x3B, 0x90, 0x38, 0xA0, 0x3F, 0xDA, 0x0B, 0x33, 0x3B, 0x98, 0x48, 0x71, 0xCC, 0xA5, 0xAD, 0xFB, 0x97, 0x6F, 0xC4, 0x3D, 0x58 } }, - { 20020, 1001, 960, 540, "yuv420p", false, { 0x30, 0xCE, 0x7C, 0x25, 0xF4, 0x45, 0x44, 0x6D, 0xF6, 0x33, 0xD3, 0x71, 0xFD, 0x72, 0x35, 0x39, 0xE5, 0xE4, 0xB4, 0x90, 0xA9, 0x44, 0xAF, 0x5B, 0xB2, 0x2A, 0x03, 0x06, 0xC6, 0x8D, 0xF0, 0x7B } }, - { 21021, 1001, 960, 540, "yuv420p", false, { 0x8D, 0x9F, 0xA7, 0x9E, 0xE2, 0xA4, 0x02, 0xD0, 0xA9, 0x5F, 0xCB, 0x24, 0x21, 0xDB, 0x30, 0x92, 0x6F, 0xDD, 0x7F, 0xF9, 0x8B, 0x07, 0x79, 0x16, 0x50, 0x7E, 0x65, 0x6C, 0x1C, 0x4A, 0x11, 0x4B } }, - { 22022, 1001, 960, 540, "yuv420p", false, { 0x01, 0x0B, 0xEA, 0x36, 0xDF, 0x88, 0xD2, 0xE8, 0xD0, 0xF3, 0x63, 0xBF, 0xB8, 0x14, 0xE4, 0x99, 0xB5, 0x6E, 0x08, 0xB5, 0x78, 0x6C, 0xBA, 0x56, 0xA1, 0x17, 0x91, 0x4A, 0xE5, 0x77, 0xD8, 0x51 } }, - { 23023, 1001, 960, 540, "yuv420p", false, { 0xED, 0x62, 0x86, 0x2B, 0xE8, 0x7B, 0x85, 0xFC, 0xDC, 0xC6, 0x2B, 0xC0, 0xF9, 0x37, 0xB2, 0xA9, 0x45, 0x87, 0x33, 0x3D, 0x89, 0xFE, 0x82, 0x66, 0x6E, 0xA7, 0x17, 0xF4, 0x2D, 0xAD, 0x05, 0x6F } }, - { 24024, 1001, 960, 540, "yuv420p", false, { 0x10, 0xE9, 0xB7, 0x24, 0x0B, 0x68, 0x7B, 0x0F, 0xBC, 0xEB, 0x25, 0xC4, 0xF8, 0x8B, 0xAC, 0x18, 0x26, 0x8B, 0xC0, 0x97, 0x09, 0x36, 0x6C, 0xE2, 0x49, 0xE2, 0x44, 0x86, 0xF1, 0xE6, 0x09, 0x9C } }, - { 25025, 1001, 960, 540, "yuv420p", false, { 0x78, 0xF9, 0x8E, 0xCF, 0x18, 0x3F, 0x6C, 0x11, 0x15, 0xDD, 0xCF, 0x6C, 0xCD, 0x29, 0x91, 0xAB, 0x9A, 0xD2, 0x91, 0x45, 0x78, 0x47, 0xAB, 0xEC, 0x51, 0x18, 0x25, 0x8B, 0xA1, 0xCA, 0x6A, 0x59 } }, - { 26026, 1001, 960, 540, "yuv420p", false, { 0x78, 0x26, 0x43, 0xA7, 0xFD, 0x62, 0x41, 0x25, 0x99, 0x47, 0x7A, 0x6A, 0xF9, 0xDF, 0xC8, 0x6E, 0x1E, 0x81, 0x82, 0xC3, 0x11, 0x20, 0x37, 0x9E, 0x59, 0x4C, 0x58, 0x73, 0x49, 0x78, 0xF7, 0xE3 } }, - { 27027, 1001, 960, 540, "yuv420p", false, { 0x77, 0x11, 0xA1, 0xC9, 0x93, 0x0F, 0x64, 0x2A, 0x28, 0x67, 0x2D, 0xA1, 0xA0, 0xD5, 0x4C, 0xF3, 0x24, 0xBD, 0xD9, 0x47, 0x2F, 0x0F, 0x66, 0x15, 0xF5, 0x26, 0x62, 0x5D, 0x91, 0x4F, 0x32, 0xEF } }, - { 28028, 1001, 960, 540, "yuv420p", false, { 0xF5, 0xFB, 0xDB, 0x3B, 0x37, 0x37, 0xD4, 0xF5, 0x94, 0xF4, 0x20, 0x34, 0xA7, 0x88, 0x81, 0xD8, 0xA4, 0xF8, 0x0D, 0xFE, 0x98, 0xDF, 0x75, 0x79, 0xD9, 0xAC, 0x10, 0xC7, 0x55, 0xBF, 0xDB, 0xDD } }, - { 29029, 1001, 960, 540, "yuv420p", false, { 0xE0, 0xA0, 0x54, 0xAC, 0x4E, 0x2C, 0x65, 0xF5, 0xD5, 0x00, 0x6E, 0x8C, 0x09, 0x1B, 0xB6, 0x37, 0x15, 0xAC, 0x1D, 0x56, 0x43, 0xBC, 0x99, 0xB7, 0xF5, 0xFB, 0xEA, 0x82, 0x32, 0x98, 0x3C, 0xE6 } }, - { 30030, 1001, 960, 540, "yuv420p", false, { 0xE5, 0xAF, 0xB4, 0x02, 0x08, 0x20, 0x6E, 0xC3, 0xF1, 0xA1, 0x39, 0x93, 0xE2, 0x21, 0x21, 0x6B, 0xFE, 0xC1, 0xCA, 0xE2, 0x8D, 0xF8, 0x0B, 0x60, 0xB2, 0x93, 0x3B, 0x21, 0x92, 0xB3, 0xC8, 0x59 } }, - { 31031, 1001, 960, 540, "yuv420p", false, { 0x40, 0xEA, 0xED, 0x7E, 0xC2, 0x76, 0x93, 0xC2, 0x4C, 0xA0, 0x11, 0x30, 0xF4, 0x37, 0x1C, 0xCA, 0xA1, 0xE4, 0x20, 0x4F, 0x42, 0xE0, 0x9F, 0xF6, 0x4C, 0x94, 0xE3, 0x1D, 0x00, 0xB7, 0x91, 0xAA } }, - { 32032, 1001, 960, 540, "yuv420p", false, { 0x4F, 0x94, 0xE0, 0x72, 0xD2, 0xB8, 0x92, 0x67, 0x0F, 0x95, 0x42, 0x05, 0x56, 0x85, 0x03, 0x5F, 0x3E, 0xA2, 0xD2, 0x4F, 0xE0, 0x05, 0x94, 0xC3, 0xDD, 0x0C, 0x53, 0x0A, 0x0F, 0xD3, 0x47, 0x45 } }, - { 33033, 1001, 960, 540, "yuv420p", false, { 0x63, 0xAF, 0x87, 0x28, 0x4E, 0xB0, 0x8B, 0xD8, 0xDD, 0x44, 0x2A, 0xF4, 0xAE, 0xD8, 0x07, 0x35, 0x73, 0x9A, 0xB8, 0x2C, 0x40, 0x4B, 0xDC, 0xA4, 0x0D, 0x3B, 0x39, 0x6B, 0xD7, 0x9C, 0x89, 0x35 } }, - { 34034, 1001, 960, 540, "yuv420p", false, { 0xC5, 0x21, 0x0E, 0x40, 0xD7, 0x44, 0xAF, 0x75, 0xAD, 0x49, 0x23, 0xA9, 0x79, 0xE3, 0x46, 0x54, 0xE7, 0xA5, 0xFC, 0x62, 0x54, 0x31, 0x64, 0xC4, 0xB1, 0xF4, 0x79, 0xC8, 0xBC, 0x71, 0x44, 0x62 } }, - { 35035, 1001, 960, 540, "yuv420p", false, { 0x43, 0xF7, 0x12, 0xB0, 0x20, 0xEC, 0x8C, 0xBC, 0xCD, 0xA9, 0xD8, 0xDC, 0x1A, 0xFC, 0xE7, 0x90, 0x58, 0xEC, 0x80, 0x38, 0x46, 0xA3, 0x80, 0x31, 0x9B, 0x35, 0xD5, 0x3B, 0xF1, 0x53, 0x64, 0xE5 } }, - { 36036, 1001, 960, 540, "yuv420p", false, { 0x1F, 0x8B, 0x64, 0x56, 0x96, 0x92, 0xFB, 0x7A, 0xEC, 0x16, 0x8B, 0x4B, 0xC5, 0x92, 0x90, 0x5B, 0x31, 0x89, 0xDF, 0x67, 0x85, 0x14, 0x0A, 0xC2, 0xF3, 0xE3, 0x82, 0x6A, 0x45, 0x54, 0x6A, 0x67 } }, - { 37037, 1001, 960, 540, "yuv420p", false, { 0x10, 0x31, 0xC3, 0x0F, 0x04, 0xB9, 0x5D, 0xDB, 0x2B, 0xCA, 0xAA, 0x36, 0x4C, 0x9E, 0x81, 0xD8, 0x83, 0x91, 0x83, 0xAE, 0x87, 0x87, 0x66, 0xC0, 0x87, 0x3A, 0x5C, 0x62, 0x40, 0x31, 0xEA, 0x4F } }, - { 38038, 1001, 960, 540, "yuv420p", false, { 0x7F, 0x85, 0xEB, 0x9B, 0x00, 0xCA, 0xD9, 0x1C, 0x5D, 0xAA, 0x13, 0xCA, 0x0A, 0xF2, 0xB2, 0x20, 0xA5, 0x0B, 0xEE, 0x61, 0x76, 0x7C, 0x53, 0xB2, 0xF0, 0x68, 0xA5, 0x4B, 0x7C, 0x29, 0xD0, 0x4A } }, - { 39039, 1001, 960, 540, "yuv420p", false, { 0x2C, 0xF9, 0xF5, 0xCC, 0xD2, 0xF3, 0x97, 0xB0, 0x44, 0xCE, 0xF2, 0xE7, 0x00, 0xA6, 0x58, 0x99, 0x37, 0xB6, 0x05, 0xA1, 0x04, 0x1E, 0x7A, 0x91, 0x48, 0x71, 0x03, 0x8D, 0xFD, 0x19, 0x67, 0x2B } }, - { 40040, 1001, 960, 540, "yuv420p", false, { 0xE2, 0x38, 0xDA, 0x68, 0x57, 0x2D, 0x6C, 0x25, 0xBF, 0x26, 0x5F, 0x95, 0xBC, 0xC6, 0xC8, 0x51, 0x23, 0xFF, 0x6C, 0x6A, 0x77, 0xAD, 0xC1, 0x2A, 0x29, 0x1B, 0xC2, 0xCB, 0xE0, 0x3E, 0xDF, 0xB7 } }, - { 41041, 1001, 960, 540, "yuv420p", false, { 0x72, 0xFF, 0x1D, 0x8A, 0x05, 0x82, 0x5C, 0x9F, 0x54, 0x75, 0x1F, 0x6D, 0xAE, 0x53, 0x28, 0x6E, 0x71, 0x6D, 0x9E, 0x7B, 0xB1, 0x00, 0xED, 0xF1, 0x0F, 0x43, 0x2F, 0xC1, 0xDC, 0xFE, 0xD1, 0x00 } }, - { 42042, 1001, 960, 540, "yuv420p", false, { 0xCE, 0x70, 0x01, 0xEB, 0x28, 0xD8, 0xD5, 0x8B, 0xC8, 0xEC, 0xBA, 0x34, 0x04, 0xD4, 0xA9, 0x77, 0xFD, 0xB7, 0xF4, 0x4C, 0x14, 0x39, 0x14, 0x6A, 0xC8, 0xAF, 0xCB, 0xAE, 0x88, 0x3A, 0xDB, 0x56 } }, - { 43043, 1001, 960, 540, "yuv420p", false, { 0xA9, 0x96, 0x9D, 0xEC, 0xBB, 0x3B, 0xAB, 0x6A, 0xF7, 0xC2, 0x72, 0x3A, 0x67, 0xB5, 0x0F, 0xBE, 0x45, 0x47, 0x54, 0x62, 0x56, 0xD8, 0x60, 0xEC, 0x46, 0x04, 0xB9, 0x61, 0xFF, 0xE8, 0xCA, 0xBC } }, - { 44044, 1001, 960, 540, "yuv420p", false, { 0xCA, 0x40, 0x76, 0xE9, 0x08, 0x5A, 0xF3, 0x57, 0xB9, 0x3A, 0xF5, 0x92, 0x5E, 0xB4, 0x5E, 0x22, 0x38, 0x62, 0x66, 0x00, 0x12, 0x64, 0x31, 0x6D, 0x48, 0xB0, 0x96, 0xD8, 0x03, 0xA0, 0x6B, 0xE7 } }, - { 45045, 1001, 960, 540, "yuv420p", false, { 0x71, 0x10, 0x24, 0x5B, 0xA0, 0x4C, 0xBF, 0x6E, 0x6E, 0x72, 0xC9, 0x0D, 0x43, 0x51, 0x8B, 0xFE, 0x1E, 0x2D, 0xF6, 0x44, 0x2F, 0x5B, 0x0F, 0x6A, 0xA7, 0x26, 0xB5, 0xD2, 0x48, 0x69, 0x8D, 0xEB } }, - { 46046, 1001, 960, 540, "yuv420p", false, { 0xB5, 0x8E, 0x9E, 0xA3, 0xDB, 0x51, 0xDD, 0xC9, 0xC0, 0x9C, 0xDC, 0x29, 0x6C, 0x96, 0xDF, 0x4E, 0xC1, 0xEC, 0x61, 0x42, 0xEB, 0x1E, 0x7E, 0xF3, 0x56, 0x82, 0x5C, 0xA9, 0x42, 0x83, 0x61, 0x8C } }, - { 47047, 1001, 960, 540, "yuv420p", false, { 0x4E, 0xA2, 0xC6, 0xEA, 0xA3, 0x9F, 0x97, 0x9B, 0x96, 0x6E, 0xF2, 0xFB, 0x52, 0x3A, 0x23, 0x22, 0x6A, 0x37, 0x12, 0x21, 0xF9, 0xDF, 0xA3, 0xB4, 0x37, 0xA6, 0x71, 0x75, 0x43, 0xA6, 0x44, 0xF2 } }, - { 48048, 1001, 960, 540, "yuv420p", false, { 0xE8, 0xE6, 0x7F, 0x94, 0xDA, 0x2B, 0x4A, 0xD8, 0x16, 0xC9, 0xDC, 0x2C, 0xE6, 0xF4, 0x4D, 0x6A, 0x36, 0x3E, 0xBD, 0x5D, 0xD8, 0xB3, 0x45, 0x95, 0xDC, 0x0F, 0xB7, 0x76, 0xDF, 0x7C, 0xE5, 0x30 } }, - { 49049, 1001, 960, 540, "yuv420p", false, { 0x4E, 0x84, 0x01, 0x72, 0x40, 0x7E, 0x88, 0x6E, 0x92, 0x05, 0xC8, 0x10, 0xAF, 0x99, 0x84, 0x68, 0xD7, 0x8B, 0x59, 0xBF, 0x05, 0x1D, 0x28, 0xA5, 0x1C, 0xDC, 0xBF, 0x8B, 0xDE, 0x39, 0xEE, 0x46 } }, - { 50050, 1001, 960, 540, "yuv420p", false, { 0x9F, 0xC6, 0x9E, 0xAE, 0x02, 0x75, 0xE3, 0x19, 0x1F, 0x9B, 0x49, 0x06, 0xBB, 0x7D, 0xBD, 0x00, 0xBE, 0x7C, 0x4A, 0xAB, 0x9D, 0x74, 0xF1, 0xF2, 0xCC, 0xA9, 0xC7, 0x81, 0xEF, 0x67, 0x42, 0x9E } }, - { 51051, 1001, 960, 540, "yuv420p", false, { 0xCA, 0x59, 0xBA, 0xA4, 0x4C, 0x8E, 0x26, 0xE3, 0xB1, 0x88, 0xD6, 0xD8, 0x26, 0x3E, 0x5E, 0x41, 0x2B, 0x54, 0x90, 0x9A, 0x54, 0x60, 0x89, 0xD7, 0xBB, 0x9D, 0x61, 0x3A, 0x09, 0x65, 0xEE, 0x40 } }, - { 52052, 1001, 960, 540, "yuv420p", false, { 0xA3, 0x6C, 0x49, 0x3E, 0xFC, 0xCE, 0xAD, 0x8A, 0xDC, 0xE6, 0x4E, 0x99, 0x04, 0x07, 0xDA, 0x5C, 0x96, 0xD5, 0x9E, 0xE7, 0x65, 0x75, 0xDA, 0x54, 0x65, 0xDB, 0x41, 0x8F, 0xFD, 0x36, 0x03, 0xD3 } }, - { 53053, 1001, 960, 540, "yuv420p", false, { 0x77, 0xB8, 0xFB, 0x7A, 0x61, 0x99, 0x71, 0xD7, 0x9E, 0x40, 0xF4, 0x25, 0x6E, 0x70, 0x0E, 0xE4, 0x3F, 0xC2, 0xB0, 0x8D, 0x9E, 0xF6, 0xA3, 0xAC, 0x87, 0xC2, 0xA6, 0x9F, 0x11, 0x99, 0xBC, 0xAA } }, - { 54054, 1001, 960, 540, "yuv420p", false, { 0x37, 0x58, 0xE3, 0xF0, 0x5E, 0xCE, 0xF1, 0xAB, 0xDA, 0xF2, 0xB2, 0xB2, 0xC1, 0x20, 0x09, 0x57, 0x88, 0x3B, 0xEB, 0x3E, 0xF0, 0x9F, 0xED, 0xE8, 0x17, 0x03, 0x0E, 0xAF, 0xA4, 0x32, 0xE5, 0x6B } }, - { 55055, 1001, 960, 540, "yuv420p", false, { 0xD0, 0xD8, 0x93, 0xFC, 0xAF, 0x3E, 0xCB, 0xF6, 0xF6, 0xBD, 0x29, 0xC4, 0x05, 0xA2, 0x2C, 0x9F, 0x61, 0xFA, 0x2A, 0x95, 0x6C, 0x5F, 0xE4, 0xC5, 0x00, 0xF1, 0x95, 0xF9, 0xBE, 0xC1, 0xD6, 0x8C } }, - { 56056, 1001, 960, 540, "yuv420p", false, { 0x42, 0xAC, 0xA4, 0xEC, 0x79, 0x58, 0xA1, 0xC2, 0x35, 0xAA, 0x2D, 0x30, 0x0F, 0x84, 0x7A, 0x98, 0x3C, 0x13, 0x32, 0x36, 0x10, 0x53, 0xA9, 0xCF, 0xBF, 0x67, 0x47, 0x7F, 0xF2, 0x59, 0xD0, 0xF5 } }, - { 57057, 1001, 960, 540, "yuv420p", false, { 0x84, 0x3D, 0xBA, 0x78, 0xB4, 0x52, 0x53, 0x65, 0xD6, 0xBC, 0x22, 0x89, 0x33, 0xA4, 0xB9, 0x14, 0x1C, 0x46, 0x92, 0x21, 0xAC, 0x52, 0x87, 0x13, 0x30, 0xF1, 0x0C, 0xFC, 0x21, 0x3F, 0x89, 0x7B } }, - { 58058, 1001, 960, 540, "yuv420p", false, { 0x0D, 0x5E, 0x06, 0xC6, 0x07, 0x0A, 0x9B, 0xF3, 0x9F, 0x26, 0x23, 0xA4, 0x24, 0xA7, 0x27, 0x15, 0x4F, 0x87, 0x55, 0xBC, 0x50, 0x92, 0x42, 0x6D, 0x23, 0x10, 0x57, 0xBD, 0xC4, 0x61, 0xD9, 0x91 } }, - { 59059, 1001, 960, 540, "yuv420p", false, { 0xF6, 0xB0, 0x68, 0x18, 0x65, 0x78, 0xA1, 0x00, 0x60, 0xA6, 0x78, 0x7E, 0x70, 0xDE, 0xBE, 0x61, 0x9D, 0x2A, 0x1B, 0x80, 0x12, 0xA5, 0xDB, 0x31, 0x54, 0x1B, 0xCA, 0xD5, 0x4A, 0x5F, 0xE4, 0x0C } }, - { 60060, 1001, 960, 540, "yuv420p", false, { 0x58, 0xCD, 0xB7, 0x78, 0x92, 0xBB, 0x0A, 0xE6, 0xA4, 0x27, 0xCA, 0x21, 0x4F, 0xED, 0x38, 0x12, 0x38, 0x56, 0xE6, 0x34, 0x99, 0x5C, 0x4A, 0x6E, 0xFB, 0xB5, 0x4E, 0x5B, 0x59, 0xB3, 0x32, 0x81 } }, - { 61061, 1001, 960, 540, "yuv420p", false, { 0xF7, 0x64, 0x38, 0x53, 0xC6, 0x73, 0x1D, 0xF1, 0x13, 0x67, 0x47, 0x4E, 0xBE, 0xCC, 0x73, 0xBB, 0x0C, 0x1C, 0xAD, 0x7F, 0xFD, 0xC5, 0x6B, 0xF5, 0x99, 0xE9, 0x6E, 0x3B, 0x2E, 0x14, 0x95, 0xD0 } }, - { 62062, 1001, 960, 540, "yuv420p", false, { 0xC5, 0x37, 0xEF, 0xAE, 0xD0, 0x30, 0x8B, 0x4E, 0xBA, 0x09, 0xC2, 0x7B, 0x9E, 0x01, 0x10, 0xED, 0x59, 0x37, 0x19, 0x73, 0x3D, 0x11, 0x8A, 0x86, 0x87, 0x21, 0xC9, 0x95, 0x95, 0xC6, 0x5A, 0x1E } }, - { 63063, 1001, 960, 540, "yuv420p", false, { 0xC9, 0x57, 0x6B, 0xF5, 0x04, 0xE6, 0x4C, 0x97, 0x5D, 0xFA, 0xD5, 0x24, 0xB5, 0xBE, 0x9E, 0x5A, 0xF6, 0xB4, 0x88, 0x8A, 0x7A, 0x15, 0x05, 0x72, 0xCA, 0x96, 0x6D, 0xF4, 0x18, 0xB5, 0xF5, 0xF8 } }, - { 64064, 1001, 960, 540, "yuv420p", false, { 0xDE, 0x5A, 0x39, 0xA4, 0xF1, 0x21, 0x1A, 0x4C, 0xD6, 0x83, 0x34, 0xAB, 0xF9, 0x02, 0x51, 0x6D, 0x5D, 0x46, 0x7F, 0x4D, 0xD7, 0xD5, 0x1F, 0x9C, 0xE4, 0xF0, 0xB2, 0x0A, 0x05, 0x4A, 0x04, 0xA3 } }, - { 65065, 1001, 960, 540, "yuv420p", false, { 0x85, 0x30, 0xBA, 0x26, 0x12, 0x69, 0xFA, 0xA0, 0x11, 0x7E, 0xBE, 0x41, 0xA9, 0x56, 0x75, 0xD6, 0x93, 0xAF, 0x5F, 0x65, 0x41, 0x41, 0x29, 0x6F, 0xC6, 0x34, 0xEE, 0xA7, 0x40, 0xD8, 0xE0, 0x25 } }, - { 66066, 1001, 960, 540, "yuv420p", false, { 0x39, 0x7A, 0x96, 0x4C, 0xED, 0x78, 0xD7, 0x60, 0x8A, 0x9C, 0xD7, 0x84, 0xF3, 0x9E, 0x10, 0x75, 0x75, 0x9D, 0xC7, 0x5B, 0x7E, 0xB8, 0x50, 0x8A, 0xDE, 0xC0, 0xD7, 0xC1, 0xA3, 0x94, 0xCA, 0x45 } }, - { 67067, 1001, 960, 540, "yuv420p", false, { 0xE1, 0x0A, 0xDC, 0xF6, 0xF9, 0x36, 0x5E, 0xE4, 0xF9, 0x26, 0xD7, 0xA1, 0x91, 0xA8, 0x49, 0x71, 0x76, 0x14, 0xB9, 0xA4, 0xE4, 0x14, 0x19, 0x7D, 0xB0, 0xEB, 0xAE, 0x69, 0x41, 0x38, 0x6E, 0xB2 } }, - { 68068, 1001, 960, 540, "yuv420p", false, { 0xBA, 0xD3, 0xC0, 0x58, 0xC4, 0xE2, 0xDC, 0xA0, 0x06, 0x43, 0xB7, 0xA5, 0x52, 0xA1, 0xDF, 0x94, 0xA6, 0xC2, 0xAE, 0xC8, 0x19, 0xE3, 0xBC, 0xA9, 0x7C, 0xBD, 0x65, 0x61, 0x81, 0xF7, 0xB4, 0xBF } }, - { 69069, 1001, 960, 540, "yuv420p", false, { 0xAB, 0x67, 0x91, 0xE1, 0xF6, 0x94, 0x93, 0x85, 0xB2, 0xBE, 0xFE, 0xFC, 0xBD, 0xFD, 0x6C, 0xFF, 0x4D, 0x17, 0xC5, 0x20, 0x13, 0xED, 0x48, 0xD2, 0xEE, 0x59, 0xD4, 0x49, 0xE2, 0x2C, 0x79, 0x90 } }, - { 70070, 1001, 960, 540, "yuv420p", false, { 0xEB, 0xF2, 0xA6, 0x10, 0xD5, 0xCF, 0x4B, 0x4D, 0xFA, 0x95, 0xCC, 0xD3, 0x54, 0xE9, 0x39, 0x86, 0xF4, 0x8A, 0x1C, 0xEF, 0x42, 0xD8, 0x53, 0x23, 0x7B, 0x98, 0x34, 0x78, 0xE5, 0xFA, 0x8D, 0x9E } }, - { 71071, 1001, 960, 540, "yuv420p", false, { 0xC7, 0x88, 0xFD, 0x06, 0xBE, 0x42, 0xB3, 0xDE, 0xD3, 0x66, 0x39, 0xC2, 0x57, 0x3C, 0x7C, 0x6A, 0x97, 0x5B, 0x71, 0xD1, 0x91, 0x63, 0x89, 0x12, 0x92, 0xCC, 0xBE, 0xAD, 0x5A, 0x2E, 0x75, 0x2E } }, - { 72072, 1001, 960, 540, "yuv420p", false, { 0x4D, 0x6B, 0x3C, 0x3C, 0x94, 0x28, 0xEB, 0xCA, 0xC6, 0x53, 0xB6, 0x0D, 0xA4, 0x91, 0x41, 0x68, 0xA8, 0xB9, 0x0A, 0x93, 0x2C, 0x72, 0x45, 0x49, 0xE3, 0x51, 0x27, 0x01, 0xA6, 0x13, 0x6A, 0x5A } }, - { 73073, 1001, 960, 540, "yuv420p", false, { 0x97, 0x83, 0x55, 0x3F, 0x34, 0x36, 0x1C, 0x53, 0x65, 0xFB, 0xED, 0xF7, 0x8C, 0xB8, 0x82, 0xEB, 0x74, 0x71, 0xA9, 0x58, 0xBB, 0x34, 0xD5, 0x34, 0x56, 0x88, 0x95, 0x3A, 0xE1, 0x3E, 0xB0, 0x57 } }, - { 74074, 1001, 960, 540, "yuv420p", false, { 0xA8, 0x05, 0xC6, 0x01, 0xF3, 0x58, 0x10, 0xC6, 0x60, 0x69, 0xBC, 0x62, 0xFB, 0xB5, 0x2E, 0xFE, 0xD4, 0x77, 0x3A, 0x4C, 0x70, 0xF2, 0x96, 0xFB, 0x04, 0xF9, 0xF4, 0xE1, 0xFC, 0x9C, 0xA5, 0x1A } }, - { 75075, 1001, 960, 540, "yuv420p", false, { 0x58, 0xA8, 0x80, 0x6C, 0x3E, 0x66, 0xE4, 0x13, 0x19, 0x7A, 0xAB, 0x4A, 0xA8, 0xA0, 0x95, 0xBF, 0x9B, 0xD2, 0xC6, 0x41, 0x71, 0x14, 0xB0, 0xC0, 0x58, 0x67, 0x1A, 0x7D, 0x16, 0x05, 0x35, 0xD8 } }, - { 76076, 1001, 960, 540, "yuv420p", false, { 0x68, 0x84, 0x2F, 0xF5, 0x45, 0x6D, 0x9B, 0x49, 0x02, 0xEF, 0x3B, 0x21, 0x62, 0x77, 0x5B, 0xD0, 0x1A, 0xD5, 0x28, 0x1D, 0xE5, 0x0F, 0xF9, 0x6F, 0x29, 0xFC, 0x8E, 0x72, 0xF2, 0x5D, 0x46, 0x23 } }, - { 77077, 1001, 960, 540, "yuv420p", false, { 0x41, 0x28, 0x5A, 0x38, 0x79, 0xE3, 0xD7, 0xAB, 0xCA, 0x20, 0x7D, 0x53, 0x72, 0x19, 0x46, 0xC5, 0x2A, 0xE8, 0x17, 0xE4, 0x61, 0x02, 0xFC, 0x46, 0x69, 0xE1, 0x05, 0xB1, 0x9B, 0xBE, 0xF7, 0xB9 } }, - { 78078, 1001, 960, 540, "yuv420p", false, { 0xB3, 0x9E, 0x9D, 0x13, 0x47, 0xCF, 0x43, 0xCC, 0xC7, 0xBD, 0xC9, 0xB2, 0x31, 0x35, 0xD3, 0x5C, 0x42, 0xDF, 0x42, 0x9A, 0x37, 0x6B, 0x9C, 0xB4, 0xA5, 0x54, 0x82, 0xD5, 0x9E, 0x5B, 0xBC, 0xB9 } }, - { 79079, 1001, 960, 540, "yuv420p", false, { 0xF2, 0xF4, 0x23, 0x9C, 0x7D, 0xFB, 0x76, 0x60, 0x9D, 0x2D, 0x8E, 0xD9, 0x79, 0xE5, 0x18, 0x3F, 0xF2, 0x5B, 0x5C, 0x1E, 0x77, 0xEF, 0xC6, 0x3E, 0xDD, 0x02, 0x04, 0xCC, 0x6C, 0x44, 0xEE, 0xA0 } }, - { 80080, 1001, 960, 540, "yuv420p", false, { 0xB1, 0x45, 0x63, 0x50, 0xD3, 0x3C, 0x3E, 0x74, 0x4A, 0xEB, 0x61, 0x35, 0x9A, 0x03, 0xF2, 0x14, 0x9C, 0x66, 0x36, 0x8A, 0x2C, 0x12, 0x9A, 0x8A, 0xE1, 0xF9, 0x77, 0xC9, 0xC7, 0xE6, 0xD7, 0x0A } }, - { 81081, 1001, 960, 540, "yuv420p", false, { 0x8C, 0x6B, 0xD7, 0x1B, 0xC8, 0x3E, 0xF9, 0x21, 0xA2, 0x3D, 0x43, 0xD0, 0xF8, 0x41, 0x96, 0x17, 0xED, 0x19, 0x2B, 0xC1, 0x71, 0x65, 0x04, 0x58, 0x0F, 0x7C, 0x90, 0xDF, 0x01, 0xC0, 0x19, 0x68 } }, - { 82082, 1001, 960, 540, "yuv420p", false, { 0x2F, 0x09, 0xB7, 0xAA, 0x9E, 0x42, 0x85, 0xB5, 0x0D, 0xCA, 0xE3, 0x43, 0x0E, 0x38, 0xBE, 0x59, 0x96, 0x6F, 0x92, 0x33, 0x2B, 0x20, 0xE2, 0x99, 0x3E, 0x61, 0xA7, 0xF4, 0x4E, 0xEA, 0x80, 0x34 } }, - { 83083, 1001, 960, 540, "yuv420p", false, { 0x1E, 0xCC, 0xEA, 0x17, 0x60, 0x82, 0x3A, 0x10, 0x83, 0xB3, 0x33, 0x00, 0x72, 0xB5, 0x8C, 0xF9, 0x8E, 0x27, 0xD2, 0x90, 0xDF, 0x17, 0x0C, 0xD8, 0x1F, 0x26, 0x3C, 0xBC, 0x3E, 0xC7, 0x72, 0x8D } } -}; - -#endif // _FFMS_TEST_TESTMP4DATA_H diff --git a/thirdparty/ffms2/test/display_matrix.cpp b/thirdparty/ffms2/test/display_matrix.cpp deleted file mode 100644 index 866fb0383..000000000 --- a/thirdparty/ffms2/test/display_matrix.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include - -#include "tests.h" - -namespace { - -class DisplayMatrixTest : public ::testing::Test { -protected: - virtual void SetUp(); - virtual void TearDown(); - bool DoIndexing(std::string); - - FFMS_Indexer* indexer; - FFMS_Index* index; - int video_track_idx; - FFMS_VideoSource* video_source; - const FFMS_VideoProperties* VP; - - FFMS_ErrorInfo E; - char ErrorMsg[1024]; - - std::string SamplesDir; -}; - -void DisplayMatrixTest::SetUp() { - indexer = nullptr; - index = nullptr; - video_track_idx = -1; - video_source = nullptr; - VP = nullptr; - E.Buffer = ErrorMsg; - E.BufferSize = sizeof(ErrorMsg); - SamplesDir = STRINGIFY(SAMPLES_DIR); - - FFMS_Init(0,0); -} - -void DisplayMatrixTest::TearDown() { - FFMS_DestroyIndex(index); - FFMS_DestroyVideoSource(video_source); - FFMS_Deinit(); -} - -bool DisplayMatrixTest::DoIndexing(std::string file_name) { - indexer = FFMS_CreateIndexer(file_name.c_str(), &E); - NULL_CHECK(indexer); - FFMS_TrackTypeIndexSettings(indexer, FFMS_TYPE_VIDEO, 1, 0); - - index = FFMS_DoIndexing2(indexer, 0, &E); - NULL_CHECK(index); - - video_track_idx = FFMS_GetFirstTrackOfType(index, FFMS_TYPE_VIDEO, &E); - EXPECT_GE(0, video_track_idx); - - video_source = FFMS_CreateVideoSource(file_name.c_str(), video_track_idx, index, 1, FFMS_SEEK_NORMAL, &E); - NULL_CHECK(video_source); - - VP = FFMS_GetVideoProperties(video_source); // Can't fail - - return true; -} - -TEST_F(DisplayMatrixTest, HFlip270) { - std::string FilePath = SamplesDir + "/qrvideo_hflip_90.mov"; - - ASSERT_TRUE(DoIndexing(FilePath)); - - ASSERT_EQ(VP->Flip, 1); - ASSERT_EQ(VP->Rotation, 90); -} - -TEST_F(DisplayMatrixTest, HFlip90) { - std::string FilePath = SamplesDir + "/qrvideo_hflip_270.mov"; - - ASSERT_TRUE(DoIndexing(FilePath)); - - ASSERT_EQ(VP->Flip, 1); - ASSERT_EQ(VP->Rotation, 270); -} - -TEST_F(DisplayMatrixTest, VFlip180) { - std::string FilePath = SamplesDir + "/qrvideo_vflip.mov"; - - ASSERT_TRUE(DoIndexing(FilePath)); - - ASSERT_EQ(VP->Flip, 1); - ASSERT_EQ(VP->Rotation, 180); -} - -} //namespace - -int main(int argc, char **argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/thirdparty/ffms2/test/hdr.cpp b/thirdparty/ffms2/test/hdr.cpp deleted file mode 100644 index f3f803649..000000000 --- a/thirdparty/ffms2/test/hdr.cpp +++ /dev/null @@ -1,162 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include - -#include "tests.h" - -typedef struct HDR10Data { - double MasteringDisplayPrimariesX[3]; - double MasteringDisplayPrimariesY[3]; - double MasteringDisplayWhitePointX; - double MasteringDisplayWhitePointY; - double MasteringDisplayMinLuminance; - double MasteringDisplayMaxLuminance; -} HDR10Data; - -// Tests relative error with an error of 1e-5, given the accuracy of -// the hardcoded test values, and how it would affect HDR. -#define TEST_DOUBLE(A, B) (fabs((A / B) - 1) < (double) 1e-5) - -const HDR10Data StreamHDR10Data = { - { 35400.0 / 50000.0, 8500.0 / 50000.0, 6550.0 / 50000.0 }, - { 14599.0 / 50000.0 , 39850.0 / 50000.0 , 2300.0 / 50000.0 }, - 15634.0 / 50000.0, - 16450.0 / 50000.0, - 10.0 / 10000.0, - 10000000.0 / 10000.0 -}; - -const HDR10Data ContainerHDR10Data { - { 34000.0 / 50000.0, 13250.0 / 50000.0, 7500.0 / 50000.0 }, - { 16000.0 / 50000.0, 34500.0 / 50000.0, 3000.0 / 50000.0 }, - 15635.0 / 50000.0, - 16450.0 / 50000.0, - 100.0 / 10000.0, - 10000000.0 / 10000.0 -}; - -namespace { - -class HDR10Test : public ::testing::Test { -protected: - virtual void SetUp(); - virtual void TearDown(); - bool DoIndexing(std::string); - - FFMS_Indexer* indexer; - FFMS_Index* index; - int video_track_idx; - FFMS_VideoSource* video_source; - const FFMS_VideoProperties* VP; - - FFMS_ErrorInfo E; - char ErrorMsg[1024]; - - std::string SamplesDir; -}; - -void HDR10Test::SetUp() { - indexer = nullptr; - index = nullptr; - video_track_idx = -1; - video_source = nullptr; - VP = nullptr; - E.Buffer = ErrorMsg; - E.BufferSize = sizeof(ErrorMsg); - SamplesDir = STRINGIFY(SAMPLES_DIR); - - FFMS_Init(0,0); -} - -void HDR10Test::TearDown() { - FFMS_DestroyIndex(index); - FFMS_DestroyVideoSource(video_source); - FFMS_Deinit(); -} - -bool HDR10Test::DoIndexing(std::string file_name) { - indexer = FFMS_CreateIndexer(file_name.c_str(), &E); - NULL_CHECK(indexer); - FFMS_TrackTypeIndexSettings(indexer, FFMS_TYPE_VIDEO, 1, 0); - - index = FFMS_DoIndexing2(indexer, 0, &E); - NULL_CHECK(index); - - video_track_idx = FFMS_GetFirstTrackOfType(index, FFMS_TYPE_VIDEO, &E); - EXPECT_GE(0, video_track_idx); - - video_source = FFMS_CreateVideoSource(file_name.c_str(), video_track_idx, index, 1, FFMS_SEEK_NORMAL, &E); - NULL_CHECK(video_source); - - VP = FFMS_GetVideoProperties(video_source); // Can't fail - - return true; -} - -TEST_F(HDR10Test, StreamData) { - std::string FilePath = SamplesDir + "/hdr10tags-stream.mp4"; - - ASSERT_TRUE(DoIndexing(FilePath)); - - ASSERT_TRUE(!!VP->HasMasteringDisplayPrimaries); - for (int i = 0; i < 3; i++) { - ASSERT_TRUE(TEST_DOUBLE(VP->MasteringDisplayPrimariesX[i], StreamHDR10Data.MasteringDisplayPrimariesX[i])); - ASSERT_TRUE(TEST_DOUBLE(VP->MasteringDisplayPrimariesY[i], StreamHDR10Data.MasteringDisplayPrimariesY[i])); - } - ASSERT_TRUE(TEST_DOUBLE(VP->MasteringDisplayWhitePointX, StreamHDR10Data.MasteringDisplayWhitePointX)); - ASSERT_TRUE(TEST_DOUBLE(VP->MasteringDisplayWhitePointY, StreamHDR10Data.MasteringDisplayWhitePointY)); - - ASSERT_TRUE(!!VP->HasMasteringDisplayLuminance); - ASSERT_TRUE(TEST_DOUBLE(VP->MasteringDisplayMinLuminance, StreamHDR10Data.MasteringDisplayMinLuminance)); - ASSERT_TRUE(TEST_DOUBLE(VP->MasteringDisplayMaxLuminance, StreamHDR10Data.MasteringDisplayMaxLuminance)); -} - -TEST_F(HDR10Test, ContainerData) { - std::string FilePath = SamplesDir + "/hdr10tags-container.mkv"; - - ASSERT_TRUE(DoIndexing(FilePath)); - - // Stream HDR metadata should be used. - ASSERT_TRUE(!!VP->HasMasteringDisplayPrimaries); - for (int i = 0; i < 3; i++) { - ASSERT_TRUE(TEST_DOUBLE(VP->MasteringDisplayPrimariesX[i], ContainerHDR10Data.MasteringDisplayPrimariesX[i])); - ASSERT_TRUE(TEST_DOUBLE(VP->MasteringDisplayPrimariesY[i], ContainerHDR10Data.MasteringDisplayPrimariesY[i])); - } - ASSERT_TRUE(TEST_DOUBLE(VP->MasteringDisplayWhitePointX, ContainerHDR10Data.MasteringDisplayWhitePointX)); - ASSERT_TRUE(TEST_DOUBLE(VP->MasteringDisplayWhitePointY, ContainerHDR10Data.MasteringDisplayWhitePointY)); - - ASSERT_TRUE(!!VP->HasMasteringDisplayLuminance); - ASSERT_TRUE(TEST_DOUBLE(VP->MasteringDisplayMinLuminance, ContainerHDR10Data.MasteringDisplayMinLuminance)); - ASSERT_TRUE(TEST_DOUBLE(VP->MasteringDisplayMaxLuminance, ContainerHDR10Data.MasteringDisplayMaxLuminance)); -} - -TEST_F(HDR10Test, StreamAndContainerData) { - std::string FilePath = SamplesDir + "/hdr10tags-both.mkv"; - - ASSERT_TRUE(DoIndexing(FilePath)); - - // Stream HDR metadata should be used. - ASSERT_TRUE(!!VP->HasMasteringDisplayPrimaries); - for (int i = 0; i < 3; i++) { - ASSERT_TRUE(TEST_DOUBLE(VP->MasteringDisplayPrimariesX[i], StreamHDR10Data.MasteringDisplayPrimariesX[i])); - ASSERT_TRUE(TEST_DOUBLE(VP->MasteringDisplayPrimariesY[i], StreamHDR10Data.MasteringDisplayPrimariesY[i])); - } - ASSERT_TRUE(TEST_DOUBLE(VP->MasteringDisplayWhitePointX, StreamHDR10Data.MasteringDisplayWhitePointX)); - ASSERT_TRUE(TEST_DOUBLE(VP->MasteringDisplayWhitePointY, StreamHDR10Data.MasteringDisplayWhitePointY)); - - ASSERT_TRUE(!!VP->HasMasteringDisplayLuminance); - ASSERT_TRUE(TEST_DOUBLE(VP->MasteringDisplayMinLuminance, StreamHDR10Data.MasteringDisplayMinLuminance)); - ASSERT_TRUE(TEST_DOUBLE(VP->MasteringDisplayMaxLuminance, StreamHDR10Data.MasteringDisplayMaxLuminance)); -} - -} //namespace - -int main(int argc, char **argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/thirdparty/ffms2/test/indexer.cpp b/thirdparty/ffms2/test/indexer.cpp deleted file mode 100644 index 4286bf7ff..000000000 --- a/thirdparty/ffms2/test/indexer.cpp +++ /dev/null @@ -1,142 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include - -#include "data/test.mp4.cpp" -#include "tests.h" - - -namespace { - -const TestDataMap TestFiles[] = { - TEST_ENTRY("test.mp4", testmp4data) -}; - -class IndexerTest : public ::testing::TestWithParam { -protected: - virtual void SetUp(); - virtual void TearDown(); - bool DoIndexing(std::string); - - FFMS_Indexer* indexer; - FFMS_Index* index; - int video_track_idx; - FFMS_VideoSource* video_source; - const FFMS_VideoProperties* VP; - - FFMS_ErrorInfo E; - char ErrorMsg[1024]; - - std::string SamplesDir; -}; - -void IndexerTest::SetUp() { - indexer = nullptr; - index = nullptr; - video_track_idx = -1; - video_source = nullptr; - VP = nullptr; - E.Buffer = ErrorMsg; - E.BufferSize = sizeof(ErrorMsg); - SamplesDir = STRINGIFY(SAMPLES_DIR); - - FFMS_Init(0,0); -} - -void IndexerTest::TearDown() { - FFMS_DestroyIndex(index); - FFMS_DestroyVideoSource(video_source); - FFMS_Deinit(); -} - -bool IndexerTest::DoIndexing(std::string file_name) { - indexer = FFMS_CreateIndexer(file_name.c_str(), &E); - NULL_CHECK(indexer); - FFMS_TrackTypeIndexSettings(indexer, FFMS_TYPE_VIDEO, 1, 0); - - index = FFMS_DoIndexing2(indexer, 0, &E); - NULL_CHECK(index); - - video_track_idx = FFMS_GetFirstTrackOfType(index, FFMS_TYPE_VIDEO, &E); - EXPECT_GE(0, video_track_idx); - - video_source = FFMS_CreateVideoSource(file_name.c_str(), video_track_idx, index, 1, FFMS_SEEK_NORMAL, &E); - NULL_CHECK(video_source); - - VP = FFMS_GetVideoProperties(video_source); // Can't fail - - return true; -} - -TEST_P(IndexerTest, ValidateFrameCount) { - TestDataMap P = GetParam(); - std::string FilePath = SamplesDir + "/" + P.Filename; - - ASSERT_TRUE(DoIndexing(FilePath)); - - ASSERT_EQ(P.TestDataLen, VP->NumFrames); -} - -TEST_P(IndexerTest, ReverseAccessingFrame) { - TestDataMap P = GetParam(); - std::string FilePath = SamplesDir + "/" + P.Filename; - - ASSERT_TRUE(DoIndexing(FilePath)); - for (int i = VP->NumFrames - 1; i > 0; i--) { - std::stringstream ss; - ss << "Testing Frame: " << i; - SCOPED_TRACE(ss.str()); - - FFMS_Track *track = FFMS_GetTrackFromIndex(index, video_track_idx); - const FFMS_FrameInfo *info = FFMS_GetFrameInfo(track, i); - - const FFMS_Frame* frame = FFMS_GetFrame(video_source, i, &E); - ASSERT_NE(nullptr, frame); - ASSERT_TRUE(CheckFrame(frame, info, &P.TestData[i])); - } -} - -TEST_P(IndexerTest, RandomAccessingFrame) { - TestDataMap P = GetParam(); - std::string FilePath = SamplesDir + "/" + P.Filename; - - ASSERT_TRUE(DoIndexing(FilePath)); - - std::vector FrameNums; - for (int i = 0; i < VP->NumFrames; i++) - FrameNums.push_back(i); - - std::random_device Device; - std::mt19937 Gen(Device()); - - std::shuffle(FrameNums.begin(), FrameNums.end(), Gen); - - for (int i = 0; i < VP->NumFrames; i++) { - int num = FrameNums[i]; - - std::stringstream ss; - ss << "Testing Frame: " << num; - SCOPED_TRACE(ss.str()); - - FFMS_Track *track = FFMS_GetTrackFromIndex(index, video_track_idx); - const FFMS_FrameInfo *info = FFMS_GetFrameInfo(track, num); - - const FFMS_Frame* frame = FFMS_GetFrame(video_source, num, &E); - ASSERT_NE(nullptr, frame); - ASSERT_TRUE(CheckFrame(frame, info, &P.TestData[num])); - } -} - -INSTANTIATE_TEST_CASE_P(ValidateIndexer, IndexerTest, ::testing::ValuesIn(TestFiles)); - -} //namespace - -int main(int argc, char **argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/thirdparty/ffms2/test/tests.cpp b/thirdparty/ffms2/test/tests.cpp deleted file mode 100644 index 62ec9f294..000000000 --- a/thirdparty/ffms2/test/tests.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include - -#include -#include - -extern "C" { -#include -#include -#include -} - -#include "tests.h" - -bool CheckFrame(const FFMS_Frame *Frame, const FFMS_FrameInfo *info, const TestFrameData *Data) { - EQ_CHECK(info->PTS, Data->PTS); - EQ_CHECK(!!info->KeyFrame, Data->Keyframe); - EQ_CHECK(!!Frame->KeyFrame, Data->Keyframe); - EQ_CHECK(Frame->EncodedWidth, Data->Width); - EQ_CHECK(Frame->EncodedHeight, Data->Height); - - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get((AVPixelFormat) Frame->ConvertedPixelFormat); - NULL_CHECK(desc); - - EXPECT_STREQ(desc->name, Data->PixelFormat); - if (!!strcmp(desc->name, Data->PixelFormat)) - return false; - - struct AVSHA *sha = av_sha_alloc(); - NULL_CHECK(sha); - - int ret = av_sha_init(sha, 256); - EQ_CHECK(ret, 0); - - for (int i = 0; i < av_pix_fmt_count_planes((AVPixelFormat) Frame->ConvertedPixelFormat); i++) { - const int subh = i == 0 ? 0 : desc->log2_chroma_h; - const int subw = i == 0 ? 0 : desc->log2_chroma_w; - for (int y = 0; y < Frame->EncodedHeight >> subh; y++) - av_sha_update(sha, Frame->Data[i] + y * Frame->Linesize[i], Frame->EncodedWidth >> subw); - } - - uint8_t digest[32]; - av_sha_final(sha, &digest[0]); - av_free(sha); - - bool ok; - - EXPECT_TRUE((ok = !memcmp(&Data->SHA256[0], &digest[0], 32))); - - return ok; -} diff --git a/thirdparty/ffms2/test/tests.h b/thirdparty/ffms2/test/tests.h deleted file mode 100644 index 4e86ce1ab..000000000 --- a/thirdparty/ffms2/test/tests.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef _FFMS2_TESTS_H -#define _FFMS2_TESTS_H - -#include -#include - -extern "C" { -#include -#include -#include -} - -#include "data/data.h" - -#define NULL_CHECK(arg) do { \ - EXPECT_NE(nullptr, arg); \ - if (arg == nullptr) \ - return false; \ - } while(0) - -#define EQ_CHECK(arg1,arg2) do { \ - EXPECT_EQ(arg1, arg2); \ - if (arg1 != arg2) \ - return false; \ - } while (0) - -#define STRINGIFY2(x) #x -#define STRINGIFY(x) STRINGIFY2(x) - -#define TEST_ENTRY(file, data) { file, data, sizeof(data) / sizeof(*data) } - -typedef struct TestDataMap { - const char *Filename; - const TestFrameData *TestData; - const size_t TestDataLen; -} TestDataMap; - -bool CheckFrame(const FFMS_Frame *Frame, const FFMS_FrameInfo *info, const TestFrameData *Data); - -#endif diff --git a/thirdparty/ffms2/test/tools/gendata b/thirdparty/ffms2/test/tools/gendata deleted file mode 100755 index 5baef6c53..000000000 --- a/thirdparty/ffms2/test/tools/gendata +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/env perl - -use strict; -use warnings; - -my $filename = shift; -my $arrayname = shift; -my $track = shift; -my @timestamps; -my @hashes; -my @durations; -my @widths; -my @heights; -my @pixfmts; -my @keyframes; -my $ticks = 1; -my $frames = 0; - -if (!defined($filename) || !defined($arrayname) || !defined($track)) { - print("Usage: gendata [filename] [arrayname] [track] > output.cpp\n"); - exit(0); -} - -my $version = "Unknown"; - -for (`ffmpeg -version 2>&1`) { - chomp; - s/^(ffmpeg version .+) Copyright.+/$1/; - $version = $_; - last; -} - -print("// Autogenerated from $filename by gendata with $version\n\n"); -print("#ifndef _FFMS_TEST_".uc($arrayname)."_H\n"); -print("#define _FFMS_TEST_".uc($arrayname)."_H\n\n"); -print("#include \"data.h\"\n\n"); - -for (`ffmpeg -i $filename -map $track:0 -f framehash - 2>/dev/null`) { - if (/^#/) { - if (!/^#tb/) { - next; - } - chomp; - s/^#tb \d: //; - my @tb = split('/'); - $ticks = int($tb[0]); - next; - } - chomp; - s/\s//g; - my @fields = split(','); - push(@hashes, $fields[5]); - $frames++; -} - -for (`ffprobe -show_frames -select_streams $track $filename 2>/dev/null`) { - chomp; - - if (/^width/) { - my @w = split('='); - push(@widths, int($w[1])); - } elsif (/^height/) { - my @h = split('='); - push(@heights, int($h[1])); - } elsif (/^pix_fmt/) { - my @p = split('='); - push(@pixfmts, $p[1]); - } elsif (/^key_frame/) { - my @k = split('='); - push(@keyframes, (int($k[1]) == 1 ? "true" : "false")); - } elsif (/^pkt_pts=/) { - my @t = split('='); - push(@timestamps, int($t[1])); - } elsif (/^pkt_duration=/) { - my @d = split('='); - push(@durations, int($d[1])); - } else { - next; - } -} - -print("const TestFrameData $arrayname\[$frames] = {\n"); - -for (my $i = 0; $i < $frames; $i++) { - print(" { $timestamps[$i], $durations[$i], $widths[$i], $heights[$i], \"$pixfmts[$i]\", $keyframes[$i], {"); - - my $hash = $hashes[$i]; - $hash =~ s/(..)/ 0x\U$1,/g; - $hash =~ s/,$//; - print($hash); - - print(" } }"); - - if ($i != $frames - 1) { - print(","); - } - - print("\n"); -} - -print("};\n\n"); -print("#endif // _FFMS_TEST_".uc($arrayname)."_H\n"); diff --git a/thirdparty/ffms2/version.sh b/thirdparty/ffms2/version.sh deleted file mode 100755 index 47fed1227..000000000 --- a/thirdparty/ffms2/version.sh +++ /dev/null @@ -1,27 +0,0 @@ -#! /bin/sh - -strip_echo () { - printf '%s' "$(echo "$@" | tr -d '\n')" -} - -echo_maybe () { - if test -n "$2"; then - strip_echo "$1$2" - exit 1 - fi -} - -# Make sure we're in an useful dir (for out-of-tree builds) -cd "$(dirname $0)" - -echo_maybe '' "$(cat .version 2>/dev/null)" -echo_maybe '' "$(awk -F '[(< |)]+' '/define FFMS_VERSION/ { printf "%d.%d.%d%s", $3, $5, $7, ($9 ? sprintf(".%d", $9) : "") }' include/ffms.h)" -echo_maybe '' "$(perl -ne '/define FFMS_VERSION.*?(\d+) << 24.*?(\d+) << 16.*?(\d+) << 8.*?(\d+)/ && print "$1.$2.$3". ($4 ? ".$4" : "")' include/ffms.h)" -# All of the following break pkg-config version checking! -# But if we get to this point we can't output anything "proper" anymore so at least try to be useful -echo_maybe 'r' "$(git log HEAD~1.. 2>/dev/null | grep git-svn-id | cut -d@ -f2 | cut -d' ' -f1)" -echo_maybe 'git-r' "$(git log HEAD~1.. 2>/dev/null | sed 1q | cut -d' ' -f2 | head -c7)" -# While git returns no output when not on a git repository, -# svnversion still does, so run it last -echo_maybe 'r' "$(svnversion 2>/dev/null)" -echo_maybe '' "unknown" diff --git a/thirdparty/jbigkit/ANNOUNCE b/thirdparty/jbigkit/ANNOUNCE deleted file mode 100644 index 8d0e2c6aa..000000000 --- a/thirdparty/jbigkit/ANNOUNCE +++ /dev/null @@ -1,172 +0,0 @@ - -JBIG-KIT lossless image compression library -------------------------------------------- - -by Markus Kuhn - - -The latest release of JBIG-KIT can be downloaded from - - http://www.cl.cam.ac.uk/~mgk25/jbigkit/ - -JBIG-KIT implements a highly effective data compression algorithm for -bi-level high-resolution images such as fax pages or scanned -documents. - -JBIG-KIT provides two variants of a portable library of compression -and decompression functions with a documented interface. You can very -easily include into your image or document processing software. In -addition, JBIG-KIT provides ready-to-use compression and decompression -programs with a simple command line interface (similar to the -converters found in Jef Poskanzer's PBM graphics file conversion -package). - -JBIG-KIT implements the specification - - International Standard ISO/IEC 11544:1993 and ITU-T Recommendation - T.82(1993), "Information technology - Coded representation of picture - and audio information - progressive bi-level image compression", - , - -which is commonly referred to as the "JBIG1 standard". JBIG (Joint -Bi-level Image experts Group) is the committee which developed this -international standard for the lossless compression of images using -arithmetic coding. Like the well-known compression algorithms JPEG and -MPEG, JBIG has also been developed and published by the International -Organization for Standardization (ISO) and the International -Telecommunication Union (ITU). See also - - http://www.jpeg.org/jbig/ - http://www.iso.ch/ - http://www.itu.int/ - -The JBIG compression algorithm offers the following features: - - - Close to state-of-the-art lossless compression ratio for high - resolution bi-level images. - - - About 1.1 to 1.5 times better compression ratio on typical - scanned documents compared to G4 fax compression (ITU-T T.6), - which has been the best compression algorithm for scanned - documents available prior to JBIG. - - - Up to 30 times better compression of scanned images with dithered - images compared to G4 fax compression. - - - About 2 times better compression on typical 300 dpi documents - compared to 'gzip -9' on raw bitmaps. - - - About 3-4 times better compression than GIF on typical 300 dpi - documents. - - - Even much better competitive compression results on computer - generated images which are free of scanning distortions. - - - JBIG supports hierarchical "progressive" encoding, that means it is - possible to encode a low resolution image first, followed by - resolution enhancement data. This allows, for instance, a document - browser to display already a good 75 dpi low resolution version of - an image, while the data necessary to reconstruct the full 300 dpi - version for laser printer reproduction is still arriving (say - over a slow network link or mass storage medium). - - - The various resolution layers of a JBIG image in progressive - encoding mode together require not much more space than a - normal non-progressive mode encoded image (which JBIG also - supports). - - - The progressive encoding mode utilizes a quite sophisticated - resolution reduction algorithm which offers high quality low - resolution versions that preserve the shape of characters as well - as the integrity of thin lines and dithered images. - - - JBIG supports multiple bit planes and can this way also be used - for grayscale and color images, although the main field of - application is compression of bi-level images, i.e. images with - only two different pixel values. For grayscale images with up to - 6 bit per pixel, JBIG performs superior to JPEG's lossless - mode. - -JBIG-KIT can be used as free software under the GNU General Public -License. Other license arrangements more suitable for commercial -applications are available as well, please contact the author for -details. JBIG-KIT provides two portable libraries implemented in -ANSI/ISO C for encoding and decoding JBIG data streams, along with -documentation. The first library, jbig.c, implements nearly all of the -options that the JBIG standard provides, but keeps the entire -uncompressed image in memory. The second library, jbig85.c, implements -only the ITU-R T.85 subset of the standard that black/white fax -machines use (single bit per pixel, no "progressive" encoding), and -keeps only three lines of the uncompressed image in memory, making it -particularly attractive for low-memory embedded applications. - -The libraries are not intended for 8-bit or 16-bit machine -architectures (e.g., old MS-DOS C compilers). For maximum performance, -a 32-bit processor is required (64-bit systems work too, of course). -On architectures with 16-bit pointer arithmetic, the full-featured -jbig.c library can process only very small images. - -Special features of the full-featured jbig.c variant: - - - Fully reentrant multithread-capable design (no global or static - variables, isolated malloc()/free() calls, etc.) - - - Capable of handling incomplete and growing JBIG data streams in - order to allow earliest display of low resolution versions - - - Capable of handling several incoming data streams simultaneously - in one single process and thread - - - Especially designed with applications in mind that want to display - incoming data as early as possible (e.g., similar to the way in - which Netscape Navigator handles incoming GIF images) - - - Implements all JBIG features and options including progressive and - sequential encoding, multiple bit planes, user specified - resolution reduction and deterministic prediction tables, adaptive - template changes for optimal performance on half-tone images, - deterministic prediction, typical prediction in lowest and - differential layers, various stripe orderings, etc; only the SEQ - and HITOLO options are currently not supported by the decoder - (they are normally never required, but could be added later in - case of user requirements) - - - Suitable for fax applications, satisfies ITU-T T.85 profile - - - Efficient code, optimized utilization of 32-bit processor - registers - - - Very easy to use documented C library interface - - - Included Gray code conversion routines for efficient encoding - of grayscale images - - - Ready-to-use pbmtojbg and jbgtopbm converters. - -Special features of the light-weight jbig85.c variant: - - - Suitable for low-memory embedded applications - - - Implements only the JBIG1 subset defined in the ITU-T T.85 - profile (single bit plane, no differential layers) - - - Requires only three pixel rows of the uncompressed image to be - kept in memory - - - Handles all NEWLEN modes of operation required by ITU-T T.85 with - just a single pass over the data, automatically performing the - necessary lookahead after the last stripe - - - Codec buffers only a few bytes of arithmetic-codec data and outputs - resulting bytes or lines as soon as they are available. - -I will try to provide free support and maintenance for this software -for the foreseeable future, depending on my available time. - -Happy compressing ... - -Markus Kuhn - --- -Markus Kuhn, Computer Laboratory, University of Cambridge -http://www.cl.cam.ac.uk/~mgk25/ || CB3 0FD, Great Britain diff --git a/thirdparty/jbigkit/CHANGES b/thirdparty/jbigkit/CHANGES deleted file mode 100644 index b37d64ee8..000000000 --- a/thirdparty/jbigkit/CHANGES +++ /dev/null @@ -1,260 +0,0 @@ - -JBIG-KIT revision history -------------------------- - -Changes in upcoming version (TBA) - - - The jbig.c decoder will now, by default, return JBG_ENOMEM if the - final image layer would occupy more than two gigabytes. Users can - adjust this limit by changing sd->maxmem right after having called - jbg_dec_init(&sd). This is to reduce the risk of denial-of-service - attacks through excessive image dimensions (e.g., CVE-2017-9937). - - - minor bug fixes and documentation clarifications - -Changes in version 2.1 (2014-04-08) - -This is a security-critical bug-fix release that remains API and ABI -backwards compatible to version 2.0. Users who process BIE data from -untrusted sources should upgrade. - - - fixed a buffer-overflow vulnerability in the jbig.c decoder, - reported by Florian Weimer (Red Hat): CVE-2013-6369 - - - fixed ability of corrupted input data to force jbig85.c decoder - into an end-less loop - - - fixed a bug in the processing of private deterministic-prediction - tables (DPPRIV=1) in jbig.c decoder - - - fixed integer-type mismatches in printf arguments on 64-bit systems - - - fuzz-testing script added - - -Changes in version 2.0 (2008-08-30) - -Main new features of release 2.0: - - - This release adds a separate lightweight "T.85" version of the - encoder and decoder library (jbig85.c, jbig85.h). This new T.85 - library is optimized for embedded low-memory applications, such as - printers and fax machines. It implements only the subset of the - JBIG standard that is required by the ITU-T T.85 fax profile, - namely only a single bit plane (P = 1) and no differential layers - (DL = D = HITOLO = SEQ = ILEAVE = SMID = TPDON = DPON = DPON = - DPLAST = 0) and some other restrictions (MY = 0, MX < 128). - - The T.85 library requires only three pixel rows of the - uncompressed image to reside in memory at any time. This 3-line - buffer has to be allocated by the calling application, therefore - the T.85 library will not call any heap management functions such - as malloc() or free() itself. It can fully deal with endless-paper - fax, where the height of the encoded image is not known initially. - - - There are also two new example applications pbmtojbg85 and - jbgtopbm85 included that provide command-line access to the new - T.85 library. - -API changes in 2.0 to the original full jbig.c library (compared to 1.6): - - - jbg_dec_getwidth(), jbg_dec_getheight(), jbg_dec_getsize(), and - jbg_dec_getsize_merged() return now an unsigned long value - (was: long), and return 0 (was: -1) if no image is available yet - - - jbg_dec_in() return values changed; the least significant bits of - the error codes now provide more information about what caused the - error, beyond what the more general error text messages returned by - jbg_strerror() reveal - - - non-English translations of error messages are now provided - in a separate PO file (e.g., for use with GNU gettext), - jbg_strerror() no longer has a language attribute and the - JBG_EN, JBG_DE_8859_1, JBG_DE_UTF_8 constants no longer exist - -Other changes in 2.0 to the original full jbig.c library: - - - the arithmetic codec routines are now located in a separate source - file (they are now used by both the full library jbig.c and the new - T.85 library jbig85.c, and might also be of use to other applications) - - - arithmetic decoder behaviour slightly changed to enable the - lookahead needed to handle T.85-style NEWLEN after the final - stripe - - - added encoder support for adding comment marker segment - - - added encoder option for using SDRST marker instead of SDNORM - (only useful to make encoder able to generate a wider range - of test data) - - - macro JBG_LICENCE can be changed from the default value "GPL" to a - licence agreement reference code to if the library is used under a - commercial licence, to clarify under which exact licence the - library is used in a particular application - -Changes in 2.0 to the command-line wrappers for jbig.c: - - - added pbmtojbg options -C and -r, which provide command-line - access to the previous two extensions - - - slightly improved diagnostic output of jbgtopbm option -d - - - pbmtojbg has a new option -f as a shortcut for all the options - needed to make the output comply to the basic ITU-T T.85 fax - profile - - - jbgtopbm now outputs image dimensions in header padded to 10 - digits fixed width, for consistency with jbgtopbm85 - to allow for later in-place update of height due to NEWLEN - - -Changes in version 1.6 (2004-06-11) - - - various small changes to reduce the risk of 32-bit unsigned - integer overflows when dealing with extremely large images - - - robuster treatment of L0 = 0xffffffff - - - minor API modification in jbg_enc_options(): parameter l0 changed - from type long to unsigned long; previous value now remains - unchanged when l0 == 0 (was: l0 < 0) - - - lots of type casts added such that the C source code is now - also compilable as C++ - - -Changes in version 1.5 (2003-06-11) - - - fixed two minor memory leaks (special thanks to Davide Pizzolato - for locating one of these) - - - jbgtopbm does not attempt any more to parse multiple concatenated - BIEs (options -m must be used now to enable this feature explicitly), - in order to handle BIEs with data after the last expected SDE gracefully - - - various extensions to improve support of JBIG fax applications - (ITU-T T.85 profile): - - o support for maximum adaptive template pixel offset increased - to MX=127 in both encoder and decoder - - o encoder now has a hook for producing BIEs with a NEWLEN marker - segment and VLENGTH=1, in order to assist in testing decoders - for T.85 conformance (see also new pbmtojbg option -Y) - - o a new function jbg_newlen() can be used to scan an - entire in-memory BIE for NEWLEN marker segments and update the - YD value in the BIE header, which can be applied to BIE data - before passing it to the decoder for T.85 compliance - (Background: the incremental design of the JBIG-KIT decoder - makes it infeasible to look ahead for NEWLEN marker segments - that occur after the SDE with the last image line, therefore - this second pass is necessary to handle the old-style fax - applications permitted by T.85 in which the low-RAM encoder - doesn't know the height of the image at the start of - transmission) - - -Changes in version 1.4 (2002-04-09) - - - typo fixed in stripe number calculation, which caused encoder and - decoder to fail on certain image sizes (special thanks to Koen Denecker - for locating this one) - - -Changes in version 1.3 (2002-03-23): - - - bugs fixed in jbg_split_planes(), jbg_dec_merge_planes() that - caused a failure for more than eight planes per pixel - - - example converters now can handle PGM files with up to 32 bits - per pixel - - -Changes in version 1.2 (2000-04-08): - - - bug in the decoder fixed, which caused the rest of the input file - to be skipped whenever a comment marker was encountered (special - thanks to Ben Rudiak-Gould for - reporting this one) - - -Changes in version 1.1 (1999-11-16): - - - serious bug in the encoder fixed, which for a very small - percentage of images has caused an unterminated linked list to be - created internally that could have been responsible for - segmentation violations or non-terminating encoders - (special thanks to Hisashi Saiga for - tracking that one down) - - - minor bug in the "jbgtopbm -d" diagnostic output fixed - - -Changes in version 1.0 (1998-04-11): - - - two bugs fixed that caused the encoder and decoder to fail - under certain modes of operation with several bit planes - - - added new functions jbg_split_planes(), jbg_dec_merge_planes(), - and jbg_dec_getsize_merged() for easy handling of grayscale - images - - - added support for compressing grayscale PGM files to pbmtojbg - and jbgtopbm - - - more changes to avoid paranoid compiler warnings - - -Changes in version 0.9 (1996-01-09): - - - encoder won't break any more on input bitmap data with incorrect - zero padding - - - pbmtojbg displays a warning if input file has incorrect zero - padding - - - various minor improvements suggested by Stefan Willer - - - - many minor changes in order to avoid warnings from paranoid - compilers - - -Changes in version 0.8 (1995-09-20): - - - namespace cleared up, all names externally visible from the library - start now with jbg_ or JBG_ - - - minor non-critical bug fixed which caused library to fail compatibility - test and showed up especially on DEC Alpha systems - - - jbg_dec_gethight() is now called jbg_dec_getheight() - - - filenames conform now to MS-DOS limits - - - Bug in pbmtojbg fixed (handling of ASCII PBM files) - - -Changes in version 0.7 (1995-06-10): - - - more problems on 16-bit int systems and on Macintosh systems fixed - (special thanks to Jean-Pierre Gachen ) - - - global Makefile - - -Changes in version 0.6 (1995-06-08): - - - memory leak fixed - - - should now also work on systems where int is only 16-bit large - - - changes of the JBIG "Technical Corrigendum 1" included (special - thanks to Dr. Sebestyen from Siemens AG for sending me a copy - of the draft) - - -First release: version 0.5 (1995-05-28) - diff --git a/thirdparty/jbigkit/COPYING b/thirdparty/jbigkit/COPYING deleted file mode 100644 index a43ea2126..000000000 --- a/thirdparty/jbigkit/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) 19yy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/thirdparty/jbigkit/INSTALL b/thirdparty/jbigkit/INSTALL deleted file mode 100644 index 45d68f57c..000000000 --- a/thirdparty/jbigkit/INSTALL +++ /dev/null @@ -1,163 +0,0 @@ - -Getting started with JBIG-KIT ------------------------------ - -Markus Kuhn -- 2014-03-27 - - -JBIG-KIT is a portable C library that should work on any platform with -an ANSI/ISO C compiler, such as GNU gcc. - -To get started, compile the demonstration software in pbmtools/ and -test it with some of the provided example files. - -On a Unix system, check Makefile to suit your compiler, then start -"make". If libjbig.a and/or libjbig85.a have been produced correctly, -then activate the automatic library test suite with "make test", or -just start libjbig/tstcodec and libjbig/tstcodec85. If these tests -fail, please do let me know. - -On other operating systems, just link libjbig/jbig.c and -libjbig/jbig_ar.c together with any application in which you want to -use the full JBIG-KIT library. Likewise, just link libjbig/jbig85.c -and libjbig/jbig_ar.c together with any application in which you want -to use the simpler variant optimized for fax applications. - -In subdirectory pbmtools/, you will find the programs pbmtojbg and -jbgtopbm. These are two file converters, serving as examples for -applications that use the full JBIG-KIT library (jbig.c). After -testing them on some of the example JBIG files, you can move these -executable files together with their respective man pages (in a UNIX -style environment) to the appropriate directories. Options -h and ---help will give you short command-line usage summaries. The programs -pbmtojbg85 and jbgtopbm85 are very similar, but demonstrate use of the -simpler jbig85.c library instead. - -The subdirectory examples/ contains a few files as raw JBIG data -streams (called bi-level image entities (BIE) in the standard). - -Try - - jbgtopbm ccitt1.jbg ccitt1.pbm - -to decompress CCITT test letter #1 into a portable bitmap file, which -you can then further convert using Jef Poskanzer's PBM tools -, or view with many popular -image file viewers, such as the "display" command from ImageMagick. - -The ccitt1.jbg image is 1728 x 2376 pixels large and may not fit onto -your display screen. However, fortunately, I have stored it in JBIG's -"progressive mode" with the following resolution layers: - - layer 0: 216 x 297 pixel - layer 1: 432 x 594 pixel - layer 2: 864 x 1188 pixel - layer 3: 1728 x 2376 pixel - -In progressive mode, each layer has twice the resolution of the -previous one. Resolution layer 0 encodes all its pixels independent -from any other data; all other resolution layers encode only the -difference between the previous and the new resolution layer, which -requires much less space than encoding resolution layers without -referring to the lower layer. By default, the BIE files produced by -pbmtojbg will all start with a lowest resolution layer 0 that fits -onto a 640 x 480 screen. - -In order to tell jbgtopbm that you do not want to decode higher -resolution layers if they will not fit onto your (say) 1024 x 768 -pixel display, simply use - - jbgtopbm -x 1024 -y 768 ccitt1.jbg ccitt1.pbm - -You will get a 4 times smaller image, the highest resolution layer -that still fits onto your screen. You can also directly pipe the image -to another application using standard output, by removing the second -file name, e.g. - - jbgtopbm -x 1024 -y 768 ccitt1.jbg | display - -In fact, the data in the first quarter of the input file is sufficient -to decode the requested resolution: - - head --bytes=4000 ccitt1.jbg | ../pbmtools/jbgtopbm -x 1024 -y 768 | display - -Now let's do some compression. With - - jbgtopbm ccitt1.jbg ccitt1.pbm - -followed by - - pbmtojbg ccitt1.pbm test.jbg - -you produce again the same data stream as ccitt1.jbg. However if you -want that the lowest resolution layer is not larger than 70 x 100 -pixels ("thumb nail" image), then use - - pbmtojbg -v -x 100 -y 150 ccitt1.pbm test.jbg - -Option -v will output some technical data, and will tell you that five -incremental resolution layers have been created, in addition to the -lowest 54 x 75 pixel large layer 0. Look at the lowest resolution -layer in test.jbg with - - jbgtopbm -x 100 test.jbg | display - -and you will still be able to clearly recognize the layout and line -structure of the page, which the implemented bi-level -resolution-reduction algorithm tried to preserve. With - - pbmtojbg -q ccitt1.pbm test.jbg - -you can enforce a single resolution layer, which usually requires a -slightly less space than progressive encoding. - - -OK, another small exercise. Assume you want to build a document -database in which you want to store scanned images in two resolution -layers, one for screen previewing and one for laser-printer output. -However, you do not want your decision to store images in two -resolutions to cause too much additional storage requirement. You -decide that 3 resolution layers in JBIG fit your requirement and you -want to store - - layer 0: 432 x 594 pixels - -in the first file test-low.jbg and the two layers - - layer 1: 864 x 1188 pixels - layer 2: 1728 x 2376 pixels - -in the second file test-high.jbg. No problem, just call - - pbmtojbg -d 2 -l 0 -h 0 ccitt1.pbm test-low.jbg - pbmtojbg -d 2 -l 1 -h 2 ccitt1.pbm test-high.jbg - -where option -d specifies the total number of layers and -l/-h select -the range of layers written to the output file. You will see that the -low and high resolution file together are only 1.6 kB larger than if -you had stored only the high-res version directly without progressive -mode (option -q). Progressive mode has reduced the additional storage -requirement by 50% compared to storing the 3.2 kB low-resolution -version independently of the high resolution image. - -In order to view only the screen version, use - - jbgtopbm test-low.jbg | display - -and in order to send the full version to the printer, just concatenate -both BIE files like in - - cat test-low.jbg test-high.jbg | jbgtopbm -m | .... - - -All this functionality, and more, are available as functions in the -libjbig C library, which you can link into your application. Just copy -the relevant files from libjbig/ into your own source-code directory -and adapt your Makefile. In libjbig/jbig.txt, you will find -documentation about how to use the full library, while -libjbig/jbig85.txt documents the fax variant of the library. The -latter lacks progressive encoding, but can instead deal better with -images where the height is not yet known at the start of a -transmission. - -Markus diff --git a/thirdparty/jbigkit/Makefile b/thirdparty/jbigkit/Makefile deleted file mode 100644 index 8ea75490d..000000000 --- a/thirdparty/jbigkit/Makefile +++ /dev/null @@ -1,44 +0,0 @@ -# Unix makefile for JBIG-KIT - -# Select an ANSI/ISO C compiler here, GNU gcc is recommended -CC = gcc - -# Options for the compiler: A high optimization level is suggested -CFLAGS = -O2 -W -Wno-unused-result -# CFLAGS = -O -g -W -Wall -Wno-unused-result -ansi -pedantic # -DDEBUG - -export CC CFLAGS - -VERSION=2.1 - -all: lib pbm - @echo "Enter 'make test' in order to start some automatic tests." - -lib: - cd libjbig && $(MAKE) -e - -pbm: lib - cd pbmtools && $(MAKE) -e - -test: lib pbm - cd libjbig && $(MAKE) test - cd pbmtools && $(MAKE) test - -analyze: - cd libjbig && $(MAKE) analyze - cd pbmtools && $(MAKE) analyze - -clean: - rm -f *~ core - cd libjbig && $(MAKE) clean - cd pbmtools && $(MAKE) clean - -distribution: - rm -rf jbigkit-$(VERSION) - git archive v$(VERSION) --prefix jbigkit-$(VERSION)/ | tar xvf - - $(MAKE) -C jbigkit-$(VERSION)/pbmtools txt - tar cvaf jbigkit-$(VERSION).tar.gz jbigkit-$(VERSION) - -release: - rsync -t jbigkit-$(VERSION).tar.gz $(HOME)/public_html/download/ - rsync -t jbigkit-$(VERSION)/CHANGES $(HOME)/public_html/jbigkit/ diff --git a/thirdparty/jbigkit/TODO b/thirdparty/jbigkit/TODO deleted file mode 100644 index c0b01a323..000000000 --- a/thirdparty/jbigkit/TODO +++ /dev/null @@ -1,51 +0,0 @@ -Features that may appear in some future release regarding jbig.c: - - - function to prepare incompletely decoded images for display by Xlib - - - use a more efficient resolution-reduction method suggested by - Dr. Klaus Bartz - - - investigate whether there is a standard way of embedding JBIG - into TIFF and implement it (see also RFC 2301) - - - test for and eliminate warning messages from compilers - other than GCC - - - multichannel (e.g., RGB) support, PPM support - - - add dynamic library target to Makefile (patch by David Woodhouse), - for the benefit of Linux packagers - -The NEWLEN handling in jbig.c remains less than ideal. There is no -easy fix as NEWLEN is inherently incompatible with many of the other -options that jbig.c supports. The whole point of the VLENGTH bit may -have been to allow recipients to choose between a jbig.c (VLENGTH=0) -and jbig85.c (VLENGTH=1) style of decoder implementation. The cleanest -option would really be to remove NEWLEN support entirely from jbig.c -and to urge users who need it to use jbig85.c instead. Short of that, -the new NEWLEN look-ahead architecture from jbig85.c could be -backported to jbig.c, but this would only only slightly increase the -number of cases where the jbig.c decoder could deal with a NEWLEN -marker without a prior invocation of the jbg_newlen() pre-processing -pass. - -The following past feature requests for jbig.c probably have become -less important since the release of jbig85.c: - - - compile-time option to remove progressive encoding and - resolution-reduction support (in the interest of reducing code size) - - - investigate how to best deal with broken BIEs that contain - multiple NEWLEN marker segments, which are not permitted by ITU-T - T.85, but which have been observed coming from some fax machines; - possible options for jbg_newlen(): use first, last, or minimum - value - - - version of jbg_newlen() for dealing with BIEs that are split - into several blocks - - - call-back function for progress meter - -Features that may appear in some future release regarding jbig85.c: - - - man pages for pbmtojbg85 and jbgtopbm85 diff --git a/thirdparty/jbigkit/contrib/INDEX b/thirdparty/jbigkit/contrib/INDEX deleted file mode 100644 index 3e8542aa5..000000000 --- a/thirdparty/jbigkit/contrib/INDEX +++ /dev/null @@ -1,16 +0,0 @@ -Here are some files which users of JBIG-KIT have contributed and which -I have included into the package in the hope that you might find them -useful. If you have questions with regard to these files, better -contact the respective contributors directly. - ---------------------------------------------------------------------------- - -atariprj.tar - - From: Stefan Willer - - These are four hierarchical project files for use with the Atari ST - Pure-C development environment. With these files, installing - JBIG-KIT should be child's play for Atari ST users (except the - necessary line end changes in all text files). - diff --git a/thirdparty/jbigkit/contrib/atariprj.tar b/thirdparty/jbigkit/contrib/atariprj.tar deleted file mode 100644 index a706bbad8..000000000 --- a/thirdparty/jbigkit/contrib/atariprj.tar +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:af05800c10a87864a539dd86bd4f4546bb362207e6b2695dbc0925edea49074f -size 10240 diff --git a/thirdparty/jbigkit/examples/README b/thirdparty/jbigkit/examples/README deleted file mode 100644 index c43b4f885..000000000 --- a/thirdparty/jbigkit/examples/README +++ /dev/null @@ -1,8 +0,0 @@ -The files in this directory are a few sample images and documents -stored as raw bi-level image entities (BIE) (the data stream specified -by the JBIG standard). - -The source data for the test examples ccitt* and lena.bie is available from - - ftp://ftp.funet.fi/pub/graphics/misc/test-images/ - diff --git a/thirdparty/jbigkit/examples/ccitt1.jbg b/thirdparty/jbigkit/examples/ccitt1.jbg deleted file mode 100644 index 6288c679e..000000000 --- a/thirdparty/jbigkit/examples/ccitt1.jbg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:93159675c3bb72b5baf8f4cc50a6d5bdc4c7636d00b3df35d103fdbfb94df3d0 -size 16830 diff --git a/thirdparty/jbigkit/examples/ccitt2.jbg b/thirdparty/jbigkit/examples/ccitt2.jbg deleted file mode 100644 index 06d2d1883..000000000 --- a/thirdparty/jbigkit/examples/ccitt2.jbg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4a228c2c9ce68f0eced024218d8974bf6b28759ed23efa883827b7b9d2eddff8 -size 8958 diff --git a/thirdparty/jbigkit/examples/ccitt3.jbg b/thirdparty/jbigkit/examples/ccitt3.jbg deleted file mode 100644 index 3f384aaa4..000000000 --- a/thirdparty/jbigkit/examples/ccitt3.jbg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:282a6acf9f7b354920665b3f622c7a8a24c9f6f6d5cbba1b26996871972f1a37 -size 23642 diff --git a/thirdparty/jbigkit/examples/ccitt4.jbg b/thirdparty/jbigkit/examples/ccitt4.jbg deleted file mode 100644 index b8c2903dd..000000000 --- a/thirdparty/jbigkit/examples/ccitt4.jbg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e4eec46656b7e3949819200bc5c5393f6fc7c92b7c5ccb1ae8bd41e0130a9e2f -size 58748 diff --git a/thirdparty/jbigkit/examples/ccitt5.jbg b/thirdparty/jbigkit/examples/ccitt5.jbg deleted file mode 100644 index 4ee2f7407..000000000 --- a/thirdparty/jbigkit/examples/ccitt5.jbg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:601c65798210409d7affde011f08681b1d24874f19d3808355c3062fab9a416a -size 28092 diff --git a/thirdparty/jbigkit/examples/ccitt6.jbg b/thirdparty/jbigkit/examples/ccitt6.jbg deleted file mode 100644 index 9b98be86e..000000000 --- a/thirdparty/jbigkit/examples/ccitt6.jbg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a074accefbe45a9d9f4768df2bb595c9927a5f79d9546d044a278555d952319a -size 13503 diff --git a/thirdparty/jbigkit/examples/ccitt7.jbg b/thirdparty/jbigkit/examples/ccitt7.jbg deleted file mode 100644 index e8efb6e9d..000000000 --- a/thirdparty/jbigkit/examples/ccitt7.jbg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0d6e4c8aeb8ccc04463b5edd74e59a759525ccbc767712ea9cdbaefdaf5ddec1 -size 60640 diff --git a/thirdparty/jbigkit/examples/ccitt8.jbg b/thirdparty/jbigkit/examples/ccitt8.jbg deleted file mode 100644 index 7e7fad090..000000000 --- a/thirdparty/jbigkit/examples/ccitt8.jbg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:45a19ab97f4ca29fe7fe02c75308d0fe6f01cc486352127aa9ab8f6a9578e675 -size 15135 diff --git a/thirdparty/jbigkit/examples/jbgtests.m b/thirdparty/jbigkit/examples/jbgtests.m deleted file mode 100644 index 2ebc77b36..000000000 --- a/thirdparty/jbigkit/examples/jbgtests.m +++ /dev/null @@ -1,10 +0,0 @@ -% MATLAB code to generate test files that exercise a JBIG codec - -width = 1200; -img = []; -for y=1:650; - mx = ceil(y / 5); - line = uint8(repmat(round(rand(1,mx)),1,ceil(width/mx))) == 1; - img = [img ; line(1:width)]; -end -imwrite(img, 'mx.png', 'PNG'); diff --git a/thirdparty/jbigkit/examples/multi.pgm b/thirdparty/jbigkit/examples/multi.pgm deleted file mode 100644 index 603a0bcd8..000000000 --- a/thirdparty/jbigkit/examples/multi.pgm +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3a73e95a31682faf804e5fb9d55f4e56e24ccdcfa52bb183bb704bfffffd777f -size 52 diff --git a/thirdparty/jbigkit/examples/mx.jbg b/thirdparty/jbigkit/examples/mx.jbg deleted file mode 100644 index 4f69228aa..000000000 --- a/thirdparty/jbigkit/examples/mx.jbg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0e131764d51a5d43f86ead9a66423247f6fa152b67bedf90a21a85d593bab60c -size 74847 diff --git a/thirdparty/jbigkit/examples/sandra.pgm b/thirdparty/jbigkit/examples/sandra.pgm deleted file mode 100644 index ce0a52594..000000000 --- a/thirdparty/jbigkit/examples/sandra.pgm +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2ef7cd894cf592766bc9246d01211313484165a7766e9294c725a9fd37d71302 -size 26878 diff --git a/thirdparty/jbigkit/examples/xvlogo.jbg b/thirdparty/jbigkit/examples/xvlogo.jbg deleted file mode 100644 index 8efb1a5a2..000000000 --- a/thirdparty/jbigkit/examples/xvlogo.jbg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f111aace8710a3d7c2873e58e6ea1ae23d6a22ec274b4a92ab4b0cba0538353e -size 8628 diff --git a/thirdparty/jbigkit/libjbig/Makefile b/thirdparty/jbigkit/libjbig/Makefile deleted file mode 100644 index 10362bc1c..000000000 --- a/thirdparty/jbigkit/libjbig/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# Unix makefile for the JBIG-KIT library - -# Select an ANSI/ISO C compiler here, GNU gcc is recommended -CC = gcc - -# Options for the compiler: A high optimization level is suggested -CFLAGS = -g -O -W -Wall -ansi -pedantic # --coverage - -all: libjbig.a libjbig85.a tstcodec tstcodec85 tstjoint - -tstcodec: tstcodec.o jbig.o jbig_ar.o - $(CC) $(LDFLAGS) $(CFLAGS) -o tstcodec tstcodec.o jbig.o jbig_ar.o - -tstcodec85: tstcodec85.o jbig85.o jbig_ar.o - $(CC) $(LDFLAGS) $(CFLAGS) -o tstcodec85 tstcodec85.o jbig85.o jbig_ar.o - -tstjoint: tstjoint.o jbig.o jbig85.o jbig_ar.o - $(CC) $(LDFLAGS) $(CFLAGS) -o tstjoint \ - tstjoint.o jbig.o jbig85.o jbig_ar.o - -libjbig.a: jbig.o jbig_ar.o - rm -f libjbig.a - ar rc libjbig.a jbig.o jbig_ar.o - -ranlib libjbig.a - -libjbig85.a: jbig85.o jbig_ar.o - rm -f libjbig85.a - ar rc libjbig85.a jbig85.o jbig_ar.o - -ranlib libjbig85.a - -jbig.o: jbig.c jbig.h jbig_ar.h -jbig85.o: jbig85.c jbig85.h jbig_ar.h -jbig_ar.o: jbig_ar.c jbig_ar.h -tstcodec.o: tstcodec.c jbig.h -tstcodec85.o: tstcodec85.c jbig85.h - -update-po: jbig.c jbig85.c Makefile - xgettext -ojbig.pot -k_ \ - --copyright-holder='Markus Kuhn' \ - --msgid-bugs-address='http://www.cl.cam.ac.uk/~mgk25/jbigkit/' \ - --package-name jbigkit \ - jbig.c jbig85.c - cd po && for po in *.po ; do \ - msgmerge --update $$po ../jbig.pot ; done - -analyze: - clang --analyze *.c - -test: tstcodec tstcodec85 tstjoint - ./tstcodec - ./tstcodec85 - ./tstjoint - -t82test.pbm: tstcodec - ./tstcodec $@ - -clean: - rm -f *.o *.gcda *.gcno *.gcov *.plist *~ core gmon.out dbg_d\=??.pbm - rm -f t82test.pbm - rm -f tstcodec tstcodec85 tstjoint diff --git a/thirdparty/jbigkit/libjbig/jbig.c b/thirdparty/jbigkit/libjbig/jbig.c deleted file mode 100644 index 289b6d87f..000000000 --- a/thirdparty/jbigkit/libjbig/jbig.c +++ /dev/null @@ -1,3292 +0,0 @@ -/* - * Portable JBIG image compression library - * - * Copyright 1995-2014 -- Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/ - * - * This module implements a portable standard C encoder and decoder - * using the JBIG1 lossless bi-level image compression algorithm - * specified in International Standard ISO 11544:1993 and - * ITU-T Recommendation T.82. See the file jbig.txt for usage - * instructions and application examples. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * If you want to use this program under different license conditions, - * then contact the author for an arrangement. - */ - -#ifdef DEBUG -#include -#else -#define NDEBUG -#endif - -#include -#include -#include - -#include "jbig.h" - -#define MX_MAX 127 /* maximal supported mx offset for - * adaptive template in the encoder */ - -#define TPB2CX 0x195 /* contexts for TP special pixels */ -#define TPB3CX 0x0e5 -#define TPDCX 0xc3f - -/* marker codes */ -#define MARKER_STUFF 0x00 -#define MARKER_RESERVE 0x01 -#define MARKER_SDNORM 0x02 -#define MARKER_SDRST 0x03 -#define MARKER_ABORT 0x04 -#define MARKER_NEWLEN 0x05 -#define MARKER_ATMOVE 0x06 -#define MARKER_COMMENT 0x07 -#define MARKER_ESC 0xff - -/* loop array indices */ -#define STRIPE 0 -#define LAYER 1 -#define PLANE 2 - -/* special jbg_buf pointers (instead of NULL) */ -#define SDE_DONE ((struct jbg_buf *) -1) -#define SDE_TODO ((struct jbg_buf *) 0) - -/* object code version id */ - -const char jbg_version[] = - "JBIG-KIT " JBG_VERSION " -- (c) 1995-2014 Markus Kuhn -- " - "Licence: " JBG_LICENCE "\n"; - -/* - * The following array specifies for each combination of the 3 - * ordering bits, which ii[] variable represents which dimension - * of s->sde. - */ -static const int iindex[8][3] = { - { 2, 1, 0 }, /* no ordering bit set */ - { -1, -1, -1}, /* SMID -> illegal combination */ - { 2, 0, 1 }, /* ILEAVE */ - { 1, 0, 2 }, /* SMID + ILEAVE */ - { 0, 2, 1 }, /* SEQ */ - { 1, 2, 0 }, /* SEQ + SMID */ - { 0, 1, 2 }, /* SEQ + ILEAVE */ - { -1, -1, -1 } /* SEQ + SMID + ILEAVE -> illegal combination */ -}; - -#define _(String) String /* to mark translatable string for GNU gettext */ - -/* - * Array with English ASCII error messages that correspond - * to return values from public functions in this library. - */ -static const char *errmsg[] = { - _("All OK"), /* JBG_EOK */ - _("Reached specified image size"), /* JBG_EOK_INTR */ - _("Unexpected end of input data stream"), /* JBG_EAGAIN */ - _("Not enough memory available"), /* JBG_ENOMEM */ - _("ABORT marker segment encountered"), /* JBG_EABORT */ - _("Unknown marker segment encountered"), /* JBG_EMARKER */ - _("Input data stream contains invalid data"), /* JBG_EINVAL */ - _("Input data stream uses unimplemented JBIG features"), /* JBG_EIMPL */ - _("Incremental BIE does not continue previous one") /* JBG_ENOCONT */ -}; - - -/* - * The following three functions are the only places in this code, were - * C library memory management functions are called. The whole JBIG - * library has been designed in order to allow multi-threaded - * execution. No static or global variables are used, so all fuctions - * are fully reentrant. However if you want to use this multi-thread - * capability and your malloc, realloc and free are not reentrant, - * then simply add the necessary semaphores or mutex primitives below. - * In contrast to C's malloc() and realloc(), but like C's calloc(), - * these functions take two parameters nmemb and size that are multiplied - * before being passed on to the corresponding C function. - * This we can catch all overflows during a size_t multiplication a - * a single place. - */ - -#ifndef SIZE_MAX -#define SIZE_MAX ((size_t) -1) /* largest value of size_t */ -#endif - -static void *checked_malloc(size_t nmemb, size_t size) -{ - void *p; - - /* Full manual exception handling is ugly here for performance - * reasons. If an adequate handling of lack of memory is required, - * then use C++ and throw a C++ exception instead of abort(). */ - - /* assert that nmemb * size <= SIZE_MAX */ - if (size > SIZE_MAX / nmemb) - abort(); - - p = malloc(nmemb * size); - - if (!p) - abort(); - -#if 0 - fprintf(stderr, "%p = malloc(%lu * %lu)\n", p, - (unsigned long) nmemb, (unsigned long) size); -#endif - - return p; -} - - -static void *checked_realloc(void *ptr, size_t nmemb, size_t size) -{ - void *p; - - /* Full manual exception handling is ugly here for performance - * reasons. If an adequate handling of lack of memory is required, - * then use C++ and throw a C++ exception here instead of abort(). */ - - /* assert that nmemb * size <= SIZE_MAX */ - if (size > SIZE_MAX / nmemb) - abort(); - - p = realloc(ptr, nmemb * size); - - if (!p) - abort(); - -#if 0 - fprintf(stderr, "%p = realloc(%p, %lu * %lu)\n", p, ptr, - (unsigned long) nmemb, (unsigned long) size); -#endif - - return p; -} - - -static void checked_free(void *ptr) -{ - free(ptr); - -#if 0 - fprintf(stderr, "free(%p)\n", ptr); -#endif - -} - - - - -/* - * Memory management for buffers which are used for temporarily - * storing SDEs by the encoder. - * - * The following functions manage a set of struct jbg_buf storage - * containers were each can keep JBG_BUFSIZE bytes. The jbg_buf - * containers can be linked to form linear double-chained lists for - * which a number of operations are provided. Blocks which are - * tempoarily not used any more are returned to a freelist which each - * encoder keeps. Only the destructor of the encoder actually returns - * the block via checked_free() to the stdlib memory management. - */ - - -/* - * Allocate a new buffer block and initialize it. Try to get it from - * the free_list, and if it is empty, call checked_malloc(). - */ -static struct jbg_buf *jbg_buf_init(struct jbg_buf **free_list) -{ - struct jbg_buf *new_block; - - /* Test whether a block from the free list is available */ - if (*free_list) { - new_block = *free_list; - *free_list = new_block->next; - } else { - /* request a new memory block */ - new_block = (struct jbg_buf *) checked_malloc(1, sizeof(struct jbg_buf)); - } - new_block->len = 0; - new_block->next = NULL; - new_block->previous = NULL; - new_block->last = new_block; - new_block->free_list = free_list; - - return new_block; -} - - -/* - * Return an entire free_list to the memory management of stdlib. - * This is only done by jbg_enc_free(). - */ -static void jbg_buf_free(struct jbg_buf **free_list) -{ - struct jbg_buf *tmp; - - while (*free_list) { - tmp = (*free_list)->next; - checked_free(*free_list); - *free_list = tmp; - } - - return; -} - - -/* - * Append a single byte to a single list that starts with the block - * *(struct jbg_buf *) head. The type of *head is void here in order to - * keep the interface of the arithmetic encoder gereric, which uses this - * function as a call-back function in order to deliver single bytes - * for a PSCD. - */ -static void jbg_buf_write(int b, void *head) -{ - struct jbg_buf *now; - - now = ((struct jbg_buf *) head)->last; - if (now->len < JBG_BUFSIZE - 1) { - now->d[now->len++] = b; - return; - } - now->next = jbg_buf_init(((struct jbg_buf *) head)->free_list); - now->next->previous = now; - now->next->d[now->next->len++] = b; - ((struct jbg_buf *) head)->last = now->next; - - return; -} - - -/* - * Remove any trailing zero bytes from the end of a linked jbg_buf list, - * however make sure that no zero byte is removed which directly - * follows a 0xff byte (i.e., keep MARKER_ESC MARKER_STUFF sequences - * intact). This function is used to remove any redundant final zero - * bytes from a PSCD. - */ -static void jbg_buf_remove_zeros(struct jbg_buf *head) -{ - struct jbg_buf *last; - - while (1) { - /* remove trailing 0x00 in last block of list until this block is empty */ - last = head->last; - while (last->len && last->d[last->len - 1] == 0) - last->len--; - /* if block became really empty, remove it in case it is not the - * only remaining block and then loop to next block */ - if (last->previous && !last->len) { - head->last->next = *head->free_list; - *head->free_list = head->last; - head->last = last->previous; - head->last->next = NULL; - } else - break; - } - - /* - * If the final non-zero byte is 0xff (MARKER_ESC), then we just have - * removed a MARKER_STUFF and we will append it again now in order - * to preserve PSCD status of byte stream. - */ - if (head->last->len && head->last->d[head->last->len - 1] == MARKER_ESC) - jbg_buf_write(MARKER_STUFF, head); - - return; -} - - -/* - * The jbg_buf list which starts with block *new_prefix is concatenated - * with the list which starts with block **start and *start will then point - * to the first block of the new list. - */ -static void jbg_buf_prefix(struct jbg_buf *new_prefix, struct jbg_buf **start) -{ - new_prefix->last->next = *start; - new_prefix->last->next->previous = new_prefix->last; - new_prefix->last = new_prefix->last->next->last; - *start = new_prefix; - - return; -} - - -/* - * Send the contents of a jbg_buf list that starts with block **head to - * the call back function data_out and return the blocks of the jbg_buf - * list to the freelist from which these jbg_buf blocks have been taken. - * After the call, *head == NULL. - */ -static void jbg_buf_output(struct jbg_buf **head, - void (*data_out)(unsigned char *start, - size_t len, void *file), - void *file) -{ - struct jbg_buf *tmp; - - while (*head) { - data_out((*head)->d, (*head)->len, file); - tmp = (*head)->next; - (*head)->next = *(*head)->free_list; - *(*head)->free_list = *head; - *head = tmp; - } - - return; -} - - -/* - * Calculate y = ceil(x/2) applied n times, which is equivalent to - * y = ceil(x/(2^n)). This function is used to - * determine the number of pixels per row or column after n resolution - * reductions. E.g. X[d-1] = jbg_ceil_half(X[d], 1) and X[0] = - * jbg_ceil_half(X[d], d) as defined in clause 6.2.3 of T.82. - */ -unsigned long jbg_ceil_half(unsigned long x, int n) -{ - unsigned long mask; - - assert(n >= 0 && n < 32); - mask = (1UL << n) - 1; /* the lowest n bits are 1 here */ - return (x >> n) + ((mask & x) != 0); -} - - -/* - * Set L0 (the number of lines in a stripe at lowest resolution) - * to a default value, such that there are about 35 stripes, as - * suggested in Annex C of ITU-T T.82, without exceeding the - * limit 128/2^D suggested in Annex A. - */ -static void jbg_set_default_l0(struct jbg_enc_state *s) -{ - s->l0 = jbg_ceil_half(s->yd, s->d) / 35; /* 35 stripes/image */ - while ((s->l0 << s->d) > 128) /* but <= 128 lines/stripe */ - --s->l0; - if (s->l0 < 2) s->l0 = 2; -} - - -/* - * Calculate the number of stripes, as defined in clause 6.2.3 of T.82. - */ -unsigned long jbg_stripes(unsigned long l0, unsigned long yd, - unsigned long d) -{ - unsigned long y0 = jbg_ceil_half(yd, d); - - return y0 / l0 + (y0 % l0 != 0); -} - - -/* - * Resolution reduction table given by ITU-T T.82 Table 17 - */ - -static char jbg_resred[4096] = { - 0,0,0,1,0,0,0,1,0,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, - 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1, - 0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1, - 1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,1,0,1,0,0,1,1,1,0,1,1, - 0,0,0,1,0,0,0,1,0,0,1,0,0,0,1,1,0,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0,0,1,1,1,0,1,1,0,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0,0,1,0,1,0,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,1,0,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0,0,1,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1, - 1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1, - 0,0,1,1,0,0,0,1,0,0,0,1,0,0,1,1,0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0,1,1,0,1,1,1,1,1,1,0,1,1,1,0, - 0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,1,0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1, - 0,0,0,1,0,0,0,1,0,1,1,0,1,0,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1, - 1,1,1,0,1,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1, - 1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1,1,1,1,1,1, - 0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0,1,1,0,1,0,1,1,0,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0,0,1,0,1,0,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,1,0,1,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,0,1,1,1,1,0,1,1, - 1,0,0,1,0,0,1,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,0, - 0,0,1,0,1,1,1,1,0,0,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0, - 0,0,0,0,1,0,0,1,0,0,1,1,0,1,1,1,0,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0,1,1,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,0,1,1,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0,0,1,1,1,0,1,0,1,0,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1, - 0,0,1,0,0,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,1, - 0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,1,0,0,1,0,0,1,1, - 0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0,0,1,0,0,0,0,1,0,1,0,1,0,1,0,1, - 0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,1,0,1,1,1, - 0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,1,0,1,0,1,1,0,0,0,1,0,0,1,1, - 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,1,1,0,0,1,1, - 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,1, - 0,0,1,0,0,1,1,1,0,0,0,0,1,0,0,1,0,0,0,1,1,1,1,0,1,0,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,1,0, - 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,1,1,1,0,1,1,1, - 0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,1,1,0,1,0,0,0,1,1,0,1,0,0,0,0,1,1,1,1,0,0,1,1,1,0,1,1,0,0,1,1, - 0,0,0,0,0,0,0,0,1,1,0,1,0,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1, - 0,0,1,1,0,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,0,1,0,0,0,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, - 0,0,0,1,0,0,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, - 0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1, - 0,0,1,1,1,1,1,1,0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,0,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1, - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,1,1,0,1,1, - 0,0,0,1,0,0,0,1,0,0,1,0,0,0,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0,0,1,0,1,0,1,1,0,1,1,1,0,1,1,1, - 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,0,1,0,1,1,0,1,1,0,1,1,1,1,1,1,1, - 0,0,0,0,1,0,0,1,0,0,1,1,0,0,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1, - 1,0,1,0,1,0,0,1,1,0,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,0,1,1,0,1,1,1, - 0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,1,1,0,1,1,0,1,1,1,1, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,1,1,0,1,0,1,0,1,1,0,1,0,1,0,0,0,1,1,1,1,1,1,1,1,1, - 1,1,1,0,1,0,0,0,1,1,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1, - 1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,1,1,0,1,1, - 0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,1,0,0,1,1,0,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0,0,1,0,1,0,0,1,0,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,1,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,1,0,1,0,0,0,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1, - 1,0,0,0,1,0,0,0,0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,1,1,0,1,1,0, - 0,0,1,1,1,1,1,1,0,0,0,0,1,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,1,1,0,1,1,1,1,1,1,1, - 0,0,0,0,1,0,0,0,0,0,0,1,0,0,1,1,0,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1, - 0,0,1,0,1,0,1,1,0,0,1,0,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,0,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1, - 0,0,1,0,1,0,1,1,0,1,1,1,1,1,1,1,0,0,1,1,1,0,1,1,0,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,1, - 0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1, - 0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0,0,1,0,0,0,0,1,0,1,0,1,0,1,0,1, - 0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,1,0,1,0,0,1,1, - 0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,1, - 0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,1, - 0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,1,1, - 1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0, - 0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,1, - 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,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,1,0,0,1,1, - 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1, - 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,1,0,0,0,1,0,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,1, - 0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,0,1,1,0,0,0,1,0,1,1,1,0,1,1,1 -}; - -/* - * Deterministic prediction tables given by ITU-T T.82 tables - * 19 to 22. The table below is organized differently, the - * index bits are permutated for higher efficiency. - */ - -static char jbg_dptable[256 + 512 + 2048 + 4096] = { - /* phase 0: offset=0 */ - 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2, - 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2,0,2,2,2,2,2,2,2, - 0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2,0,2,0,2,2,2,2,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - /* phase 1: offset=256 */ - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2, - 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,0,2,0,2,2,2,2,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2, - 0,2,2,2,2,1,2,1,2,2,2,2,1,1,1,1,2,0,2,0,2,2,2,2,0,2,0,2,2,2,2,2, - 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,2,2,2,2,0,2,2,2,2,2,2,2, - 0,2,0,2,2,2,2,2,2,2,2,2,2,0,2,0,2,2,0,0,2,2,2,2,2,0,0,2,2,2,2,2, - 0,2,2,2,2,1,2,1,2,2,2,2,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1, - 1,2,1,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,1,1,2,2,2,2,2,0,2,2,2,2,2,2, - 2,2,2,2,2,0,2,0,2,2,2,2,0,0,0,0,0,2,0,2,2,2,2,2,0,2,2,2,2,2,2,2, - 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,2,2,2,0,2,0,2,2,2,2,2, - 2,2,2,2,2,1,1,1,2,2,2,2,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,0,1,2,0,2,0,2,2,2,2,2,0,2,0,2,2,2,2,1, - 0,2,0,2,2,1,2,1,2,2,2,2,1,1,1,1,0,0,0,0,2,2,2,2,0,2,0,2,2,2,2,1, - 2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,0,0,0,2,2,2,2,2, - 2,2,2,2,2,1,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,1,2,1,2,2,2,2,1, - 2,2,2,2,2,2,2,2,0,2,0,2,2,1,2,2,2,2,2,2,2,2,2,2,0,0,0,2,2,2,2,2, - /* phase 2: offset=768 */ - 2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,2,2,2,2,1,1,1,1, - 0,2,2,2,2,1,2,1,2,2,2,2,1,2,1,2,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1, - 2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,1,2,1,2,2,2,2,2,1,1,1, - 2,0,2,2,2,1,2,1,0,2,2,2,1,2,1,2,2,2,2,0,2,2,2,2,0,2,0,2,2,2,2,2, - 0,2,0,0,1,1,1,1,2,2,2,2,1,1,1,1,0,2,0,2,1,1,1,1,2,2,2,2,1,1,1,1, - 2,2,0,2,2,2,1,2,2,2,2,2,1,2,1,2,2,2,0,2,2,1,2,1,0,2,0,2,1,1,1,1, - 2,0,0,2,2,2,2,2,0,2,0,2,2,0,2,0,2,0,2,0,2,2,2,1,2,2,0,2,1,1,2,1, - 2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,2,2,2,2,1,1,1,1, - 0,0,0,0,2,2,2,2,0,0,0,0,2,2,2,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,0,2,2,2,2,1,0,2,2,2,1,1,1,1,2,0,2,2,2,2,2,2,0,2,0,2,2,1,2,1, - 2,0,2,0,2,2,2,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2, - 0,2,2,2,1,2,1,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2, - 2,2,0,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,2,2,1,2,1,0,2,2,2,1,1,1,1, - 2,2,2,0,2,2,2,2,2,2,0,2,2,0,2,0,2,1,2,2,2,2,2,2,1,2,1,2,2,2,2,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,2,2,1, - 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,1,1,1,2,2,2,2,1,1,1,1, - 2,2,2,1,2,2,2,2,2,2,1,2,0,0,0,0,2,2,0,2,2,1,2,2,2,2,2,2,1,1,1,1, - 2,0,0,0,2,2,2,2,0,2,2,2,2,2,2,0,2,2,2,0,2,2,2,2,2,0,0,2,2,2,2,2, - 2,2,2,2,2,2,2,2,2,2,0,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,1, - 0,2,0,2,2,1,1,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2, - 2,0,2,0,2,1,2,1,0,2,0,2,2,2,1,2,2,0,2,0,2,2,2,2,0,2,0,2,2,2,1,2, - 2,2,2,0,2,2,2,2,2,2,0,2,2,2,2,2,2,2,1,2,2,2,2,2,2,0,1,2,2,2,2,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1, - 0,2,2,2,1,2,1,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2, - 2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,1,2,1,0,2,2,2,1,1,1,1, - 2,0,2,0,2,1,2,2,0,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,1,2,2, - 2,0,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,0,2,0,2,2,2,2,0,0,0,0,2,1,2,1, - 2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,0,0,2,2,2,1,2,2,2, - 0,0,2,0,2,2,2,2,0,2,0,2,2,0,2,0,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1, - 2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,0,2,0,2,2,2,1, - 2,2,0,0,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,2,2,2,2,1,1,1,1, - 0,2,2,2,1,2,1,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2, - 2,0,0,2,2,2,2,2,0,2,0,2,2,2,2,2,1,0,1,2,2,2,2,1,0,2,2,2,1,1,1,1, - 2,2,2,2,2,2,2,2,2,2,0,2,2,0,2,0,2,1,2,2,2,2,2,2,2,2,0,2,2,1,2,2, - 0,2,0,0,1,1,1,1,0,2,2,2,1,1,1,1,2,2,2,2,2,2,2,2,2,0,2,2,1,2,1,1, - 2,2,0,2,2,1,2,2,2,2,2,2,1,2,2,2,2,0,2,2,2,2,2,2,0,2,0,2,1,2,1,1, - 2,0,2,0,2,2,2,2,0,2,0,2,2,1,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,1, - 2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1, - 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 0,2,2,2,2,0,2,0,2,2,2,2,0,0,0,0,2,2,2,2,2,1,1,2,2,2,2,2,1,2,2,2, - 2,0,2,2,2,1,2,1,0,2,2,2,2,2,1,2,2,0,2,0,2,2,2,2,0,2,0,2,2,1,2,2, - 0,2,0,0,2,2,2,2,1,2,2,2,2,2,2,0,2,1,2,2,2,2,2,2,1,2,2,2,2,2,2,2, - 0,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,1,0,2,2, - 0,0,0,2,2,1,1,1,2,2,2,2,1,2,2,2,2,0,2,0,2,2,2,1,2,2,2,2,1,2,1,2, - 0,0,0,0,2,2,2,2,2,2,0,2,2,1,2,2,2,1,2,1,2,2,2,2,1,2,1,2,0,2,2,2, - 2,0,2,0,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1, - 0,2,2,2,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,1,2,2,2,2,2,0,2,2,1,2,2,0,0,0,2,2,2,2,2,1,2,2,0,2,2,2,1,2,1,2, - 2,0,2,0,2,2,2,2,0,2,0,2,2,1,2,2,0,2,0,0,2,2,2,2,2,2,2,2,2,1,2,2, - 2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,0,2,0,2,2,2,1, - 1,2,0,2,2,1,2,1,2,2,2,2,1,2,2,2,2,0,2,0,2,2,2,2,2,0,2,2,1,1,1,1, - 0,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,2,1,2,1, - 2,2,0,0,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1, - 2,2,2,0,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,2,2,2,2,2,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2, - 2,0,2,0,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,1,0,2,0,2,2,2,1,2, - 2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2, - 2,0,2,0,2,2,2,2,2,0,2,0,2,2,2,2,2,0,2,0,2,2,2,2,0,0,0,0,2,1,2,1, - 2,2,2,2,2,1,2,1,0,2,0,2,2,2,2,2,2,0,2,0,2,2,2,2,0,2,0,2,2,2,2,1, - 2,0,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,0, - 2,0,2,0,2,2,2,1,2,2,2,0,2,2,2,1,2,0,2,0,2,2,2,2,0,0,0,2,2,2,2,1, - 2,0,2,0,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2, - /* phase 3: offset=2816 */ - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1, - 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,2,0,2,0,1,2,1,2,0,2,0,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,0,2,2,2,1,2,0,2,2,2,1,2,2,2,2,0,2,0,2,1,2,1,0,0,0,0,1,1,1,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,0,2,2,2,1,2, - 2,2,2,1,2,2,2,0,1,1,1,1,0,0,0,0,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,0,0,0,0,1,1,1,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,0,0,0,0,1,1,1,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,2,0,2,0,2, - 2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,2,0,2,0,2,1,2,1, - 2,0,0,0,2,1,1,1,0,0,0,0,1,1,1,1,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2, - 2,0,2,2,2,1,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,0,0,2,0,1,1,2,1, - 2,2,2,0,2,2,2,1,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1, - 0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,2,0,2,0,2,1,2,1,0,0,0,0,1,1,1,1, - 2,0,0,2,2,1,1,2,2,2,2,2,2,2,2,2,2,1,2,1,2,0,2,0,2,1,1,1,2,0,0,0, - 2,1,2,1,2,0,2,0,1,2,1,2,0,2,0,2,2,2,2,0,2,2,2,1,2,0,2,0,2,1,2,1, - 2,0,2,0,2,1,2,1,0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1, - 2,2,2,2,2,2,2,2,2,0,0,0,2,1,1,1,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2, - 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2, - 2,0,0,0,2,1,1,1,0,0,0,0,1,1,1,1,2,0,2,0,2,1,2,1,0,0,2,0,1,1,2,1, - 2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,0,0,0,2,1,1,1, - 2,2,2,1,2,2,2,0,2,1,1,1,2,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,1,2,1,2,0,2,0,1,2,1,2,0,2,0,2, - 2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1, - 2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,2,1,1,1,0,0,0,0,1,1,1,1, - 2,0,2,2,2,1,2,2,0,0,2,0,1,1,2,1,2,1,2,1,2,0,2,0,2,2,2,2,2,2,2,2, - 2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,0,0,0,0,1,1,1,1, - 2,0,0,0,2,1,1,1,0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,2,1,0,2,2,0,1,2, - 2,2,2,1,2,2,2,0,2,1,1,1,2,0,0,0,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1, - 2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1, - 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2, - 2,1,2,1,2,0,2,0,1,2,1,1,0,2,0,0,0,0,2,1,1,1,2,0,0,0,0,0,1,1,1,1, - 2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,0,2,1,2,1,2,0,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,0,2,2,2,1,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,0,2,2,2,1,2,2,2,0,0,2,2,1,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2, - 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2, - 2,0,2,0,2,1,2,1,0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,0,0,0,0,1,1,1,1, - 2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,0,0,0,2,1,1,1, - 2,2,2,0,2,2,2,1,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2, - 2,0,2,2,2,1,2,2,2,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1, - 2,1,2,1,2,0,2,0,1,2,1,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,1,2,1,2,0,2,0,1,2,1,1,0,2,0,0,2,0,2,2,2,1,2,2,0,2,1,2,1,2,0,2, - 2,2,2,1,2,2,2,0,2,2,1,2,2,2,0,2,2,1,2,2,2,0,2,2,2,2,0,2,2,2,1,2, - 0,0,2,0,1,1,2,1,0,0,1,0,1,1,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,0,2,2,2,1,1,2,2,2,0,2,2,2,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1, - 2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1, - 2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,0,0,2,2,1,1,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2, - 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2, - 2,0,0,0,2,1,1,1,0,0,0,0,1,1,1,1,2,2,2,1,2,2,2,0,2,1,2,1,2,0,2,0, - 2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2,0,2,0,0,1,2,1,1,2,0,0,0,2,1,1,1, - 2,2,2,2,2,2,2,2,2,1,1,1,2,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,0,2,2,2,1,2,2,0,2,2,2,1,2,2,1,2,1,2,0,2,0,2,0,2,2,2,1,2,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,1,1,1,2,0,0,0, - 2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,0,0,1,2,1,1, - 2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,0,2,2,2,1,2,2,2, - 2,1,2,1,2,0,2,0,2,1,2,2,2,0,2,2,2,2,2,0,2,2,2,1,2,0,2,0,2,1,2,1, - 2,0,2,0,2,1,2,1,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2, - 2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,2,0,1,0,0,1,0,1,1, - 2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,1,2,2,1,0,2,0,2,2,2,1,2,2,2, - 2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,0,2,2,2,1,2,2,0,2,2,2,1,2, - 2,0,2,0,2,1,2,1,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2, - 0,2,0,0,1,2,1,1,2,0,0,0,2,1,1,1,2,2,2,2,2,2,2,2,1,0,1,2,0,1,0,2, - 2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,1,2,2,2,0,2,2,1,1,2,2,0,0,2,2, - 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,1,2,1,2,0,2,0,2,1,2,2,2,0,2,2,2,0,2,2,2,1,2,2,0,2,2,2,1,2,2,2, - 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,1,2,2,2,0,2,2,2, - 2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,2, - 0,0,0,0,1,1,1,1,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,2,0,2,0,2,2,0,2,2,2,1,2, - 2,0,2,0,2,1,2,1,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2, - 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,1,2,2,2,0,1,1,2,1,0,0,2,0,2,0,2,2,2,1,2,2,0,2,2,2,1,2,2,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,0,2,2,2,1,2, - 2,0,2,0,2,1,2,1,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2, - 0,2,0,0,1,2,1,1,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,2,0,0,0,2,1,1,1,2, - 2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1, - 2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,0,0,2,1,1,1,2,0,0,2,2,2,1,2,2,2, - 2,1,2,1,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,0,1,2,1,1, - 0,0,2,2,1,1,2,2,0,2,1,2,1,2,0,2,2,1,2,1,2,0,2,0,1,2,1,2,0,2,0,2, - 2,2,2,2,2,2,2,2,1,2,1,2,0,2,0,2,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1, - 2,2,0,0,2,2,1,1,2,2,0,0,2,2,1,1,2,2,2,2,2,2,2,2,2,2,0,0,2,2,1,1, - 2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,0,0,1,2,1,1, - 2,2,2,0,2,2,2,1,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,1,1,1,2,0,0,0,2, - 2,2,2,2,2,2,2,2,1,1,1,2,0,0,0,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2, - 2,0,2,0,2,1,2,1,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,0,0,0,2,1,1,1, - 2,0,2,2,2,1,2,2,0,2,2,2,1,2,2,2,2,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2, - 2,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,0,2,0,2,1,2,1,2,1,2,0,2,0,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,0,2,0,2,1,2,1,1,2,1,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,2,2,2,2,2,1,2,1,2,0,2,0,2,2,1,2,1,2,0,2,0,2,2,2,2,2,2,2,2, - 2,0,2,1,2,1,2,0,0,2,1,2,1,2,0,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1, - 2,0,2,0,2,1,2,1,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1, - 2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,1,2,1,2,0,2,0,1,1,1,2,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1, - 2,0,2,0,2,1,2,1,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, -}; - - -/* - * Initialize the status struct for the encoder. - */ -void jbg_enc_init(struct jbg_enc_state *s, unsigned long x, unsigned long y, - int planes, unsigned char **p, - void (*data_out)(unsigned char *start, size_t len, - void *file), - void *file) -{ - unsigned long l, lx; - int i; - - assert(x > 0 && y > 0 && planes > 0 && planes < 256); - s->xd = x; - s->yd = y; - s->yd1 = y; /* This is the hight initially announced in BIH. To provoke - generation of NEWLEN for T.85 compatibility tests, - overwrite with new value s->yd1 > s->yd */ - s->planes = planes; - s->data_out = data_out; - s->file = file; - - s->d = 0; - s->dl = 0; - s->dh = s->d; - jbg_set_default_l0(s); - s->mx = 8; - s->my = 0; - s->order = JBG_ILEAVE | JBG_SMID; - s->options = JBG_TPBON | JBG_TPDON | JBG_DPON; - s->comment = NULL; - s->dppriv = jbg_dptable; - s->res_tab = jbg_resred; - - s->highres = (int *) checked_malloc(planes, sizeof(int)); - s->lhp[0] = p; - s->lhp[1] = (unsigned char **) - checked_malloc(planes, sizeof(unsigned char *)); - for (i = 0; i < planes; i++) { - s->highres[i] = 0; - s->lhp[1][i] = (unsigned char *) - checked_malloc(jbg_ceil_half(y, 1), jbg_ceil_half(x, 1+3)); - } - - s->free_list = NULL; - s->s = (struct jbg_arenc_state *) - checked_malloc(s->planes, sizeof(struct jbg_arenc_state)); - s->tx = (int *) checked_malloc(s->planes, sizeof(int)); - lx = jbg_ceil_half(x, 1); - s->tp = (char *) checked_malloc(lx, sizeof(char)); - for (l = 0; l < lx; s->tp[l++] = 2) ; - s->sde = NULL; - - return; -} - - -/* - * This function selects the number of differential layers based on - * the maximum size requested for the lowest resolution layer. If - * possible, a number of differential layers is selected, which will - * keep the size of the lowest resolution layer below or equal to the - * given width x and height y. However not more than 6 differential - * resolution layers will be used. In addition, a reasonable value for - * l0 (height of one stripe in the lowest resolution layer) is - * selected, which obeys the recommended limitations for l0 in annex A - * and C of the JBIG standard. The selected number of resolution layers - * is returned. - */ -int jbg_enc_lrlmax(struct jbg_enc_state *s, unsigned long x, - unsigned long y) -{ - for (s->d = 0; s->d < 6; s->d++) - if (jbg_ceil_half(s->xd, s->d) <= x && jbg_ceil_half(s->yd, s->d) <= y) - break; - s->dl = 0; - s->dh = s->d; - jbg_set_default_l0(s); - return s->d; -} - - -/* - * As an alternative to jbg_enc_lrlmax(), the following function allows - * to specify the number of layers directly. The stripe height and layer - * range is also adjusted automatically here. - */ -void jbg_enc_layers(struct jbg_enc_state *s, int d) -{ - if (d < 0 || d > 31) - return; - s->d = d; - s->dl = 0; - s->dh = s->d; - jbg_set_default_l0(s); - return; -} - - -/* - * Specify the highest and lowest resolution layers which will be - * written to the output file. Call this function not before - * jbg_enc_layers() or jbg_enc_lrlmax(), because these two functions - * reset the lowest and highest resolution layer to default values. - * Negative values are ignored. The total number of layers is returned. - */ -int jbg_enc_lrange(struct jbg_enc_state *s, int dl, int dh) -{ - if (dl >= 0 && dl <= s->d) s->dl = dl; - if (dh >= s->dl && dh <= s->d) s->dh = dh; - - return s->d; -} - - -/* - * The following function allows to specify the bits describing the - * options of the format as well as the maximum AT movement window and - * the number of layer 0 lines per stripes. - */ -void jbg_enc_options(struct jbg_enc_state *s, int order, int options, - unsigned long l0, int mx, int my) -{ - if (order >= 0 && order <= 0x0f) s->order = order; - if (options >= 0) s->options = options; - if (l0 > 0) s->l0 = l0; - if (mx >= 0 && mx < 128) s->mx = mx; - if (my >= 0 && my < 256) s->my = my; - - return; -} - - -/* - * This function actually does all the tricky work involved in producing - * a SDE, which is stored in the appropriate s->sde[][][] element - * for later output in the correct order. - */ -static void encode_sde(struct jbg_enc_state *s, - long stripe, int layer, int plane) -{ - unsigned char *hp, *lp1, *lp2, *p0, *p1, *q1, *q2; - unsigned long hl, ll, hx, hy, lx, ly, hbpl, lbpl; - unsigned long line_h0 = 0, line_h1 = 0; - unsigned long line_h2, line_h3, line_l1, line_l2, line_l3; - struct jbg_arenc_state *se; - unsigned long y; /* current line number in highres image */ - unsigned long i; /* current line number within highres stripe */ - unsigned long j; /* current column number in highres image */ - long o; - unsigned a, p, t; - int ltp, ltp_old, cx; - unsigned long c_all, c[MX_MAX + 1], cmin, cmax, clmin, clmax; - int tmax, at_determined; - int new_tx; - long new_tx_line = -1; - int reset; - struct jbg_buf *new_jbg_buf; - -#ifdef DEBUG - static long tp_lines, tp_exceptions, tp_pixels, dp_pixels; - static long encoded_pixels; -#endif - - /* return immediately if this stripe has already been encoded */ - if (s->sde[stripe][layer][plane] != SDE_TODO) - return; - -#ifdef DEBUG - if (stripe == 0) - tp_lines = tp_exceptions = tp_pixels = dp_pixels = encoded_pixels = 0; - fprintf(stderr, "encode_sde: s/d/p = %2ld/%2d/%2d\n", - stripe, layer, plane); -#endif - - /* number of lines per stripe in highres image */ - hl = s->l0 << layer; - /* number of lines per stripe in lowres image */ - ll = hl >> 1; - /* current line number in highres image */ - y = stripe * hl; - /* number of pixels in highres image */ - hx = jbg_ceil_half(s->xd, s->d - layer); - hy = jbg_ceil_half(s->yd, s->d - layer); - /* number of pixels in lowres image */ - lx = jbg_ceil_half(hx, 1); - ly = jbg_ceil_half(hy, 1); - /* bytes per line in highres and lowres image */ - hbpl = jbg_ceil_half(hx, 3); - lbpl = jbg_ceil_half(lx, 3); - /* pointer to first image byte of highres stripe */ - hp = s->lhp[s->highres[plane]][plane] + stripe * hl * hbpl; - lp2 = s->lhp[1 - s->highres[plane]][plane] + stripe * ll * lbpl; - lp1 = lp2 + lbpl; - - /* check whether we can refer to any state of a previous stripe */ - reset = (stripe == 0) || (s->options & JBG_SDRST); - - /* initialize arithmetic encoder */ - se = s->s + plane; - arith_encode_init(se, !reset); - s->sde[stripe][layer][plane] = jbg_buf_init(&s->free_list); - se->byte_out = jbg_buf_write; - se->file = s->sde[stripe][layer][plane]; - - /* initialize adaptive template movement algorithm */ - c_all = 0; - for (t = 0; t <= s->mx; t++) - c[t] = 0; - if (stripe == 0) /* the SDRST case is handled at the end */ - s->tx[plane] = 0; - new_tx = -1; - at_determined = 0; /* we haven't yet decided the template move */ - if (s->mx == 0) - at_determined = 1; - - /* initialize typical prediction */ - ltp = 0; - if (reset) - ltp_old = 0; - else { - ltp_old = 1; - p1 = hp - hbpl; - if (y > 1) { - q1 = p1 - hbpl; - while (p1 < hp && (ltp_old = (*p1++ == *q1++)) != 0) ; - } else - while (p1 < hp && (ltp_old = (*p1++ == 0)) != 0) ; - } - - if (layer == 0) { - - /* - * Encode lowest resolution layer - */ - - for (i = 0; i < hl && y < hy; i++, y++) { - - /* check whether it is worth to perform an ATMOVE */ - if (!at_determined && c_all > 2048) { - cmin = clmin = 0xffffffffL; - cmax = clmax = 0; - tmax = 0; - for (t = (s->options & JBG_LRLTWO) ? 5 : 3; t <= s->mx; t++) { - if (c[t] > cmax) cmax = c[t]; - if (c[t] < cmin) cmin = c[t]; - if (c[t] > c[tmax]) tmax = t; - } - clmin = (c[0] < cmin) ? c[0] : cmin; - clmax = (c[0] > cmax) ? c[0] : cmax; - if (c_all - cmax < (c_all >> 3) && - cmax - c[s->tx[plane]] > c_all - cmax && - cmax - c[s->tx[plane]] > (c_all >> 4) && - /* ^ T.82 said < here, fixed in Cor.1/25 */ - cmax - (c_all - c[s->tx[plane]]) > c_all - cmax && - cmax - (c_all - c[s->tx[plane]]) > (c_all >> 4) && - cmax - cmin > (c_all >> 2) && - (s->tx[plane] || clmax - clmin > (c_all >> 3))) { - /* we have decided to perform an ATMOVE */ - new_tx = tmax; - if (!(s->options & JBG_DELAY_AT)) { - new_tx_line = i; - s->tx[plane] = new_tx; - } -#ifdef DEBUG - fprintf(stderr, "ATMOVE: line=%ld, tx=%d, c_all=%ld\n", - i, new_tx, c_all); -#endif - } - at_determined = 1; - } - assert(s->tx[plane] >= 0); /* i.e., tx can safely be cast to unsigned */ - - /* typical prediction */ - if (s->options & JBG_TPBON) { - ltp = 1; - p1 = hp; - if (i > 0 || !reset) { - q1 = hp - hbpl; - while (q1 < hp && (ltp = (*p1++ == *q1++)) != 0) ; - } else - while (p1 < hp + hbpl && (ltp = (*p1++ == 0)) != 0) ; - arith_encode(se, (s->options & JBG_LRLTWO) ? TPB2CX : TPB3CX, - ltp == ltp_old); -#ifdef DEBUG - tp_lines += ltp; -#endif - ltp_old = ltp; - if (ltp) { - /* skip next line */ - hp += hbpl; - continue; - } - } - - /* - * Layout of the variables line_h1, line_h2, line_h3, which contain - * as bits the neighbour pixels of the currently coded pixel X: - * - * 76543210765432107654321076543210 line_h3 - * 76543210765432107654321076543210 line_h2 - * 76543210765432107654321X76543210 line_h1 - */ - - line_h1 = line_h2 = line_h3 = 0; - if (i > 0 || !reset) line_h2 = (long)*(hp - hbpl) << 8; - if (i > 1 || !reset) line_h3 = (long)*(hp - hbpl - hbpl) << 8; - - /* encode line */ - for (j = 0; j < hx; hp++) { - line_h1 |= *hp; - if (j < hbpl * 8 - 8 && (i > 0 || !reset)) { - line_h2 |= *(hp - hbpl + 1); - if (i > 1 || !reset) - line_h3 |= *(hp - hbpl - hbpl + 1); - } - if (s->options & JBG_LRLTWO) { - /* two line template */ - do { - line_h1 <<= 1; line_h2 <<= 1; line_h3 <<= 1; - if (s->tx[plane]) { - if ((unsigned) s->tx[plane] > j) - a = 0; - else { - o = (j - s->tx[plane]) - (j & ~7L); - a = (hp[o >> 3] >> (7 - (o & 7))) & 1; - a <<= 4; - } - assert(s->tx[plane] > 23 || - a == ((line_h1 >> (4 + s->tx[plane])) & 0x010)); - arith_encode(se, (((line_h2 >> 10) & 0x3e0) | a | - ((line_h1 >> 9) & 0x00f)), - (line_h1 >> 8) & 1); - } - else - arith_encode(se, (((line_h2 >> 10) & 0x3f0) | - ((line_h1 >> 9) & 0x00f)), - (line_h1 >> 8) & 1); -#ifdef DEBUG - encoded_pixels++; -#endif - /* statistics for adaptive template changes */ - if (!at_determined && j >= s->mx && j < hx-2) { - p = (line_h1 & 0x100) != 0; /* current pixel value */ - c[0] += ((line_h2 & 0x4000) != 0) == p; /* default position */ - assert(!(((line_h2 >> 6) ^ line_h1) & 0x100) == - (((line_h2 & 0x4000) != 0) == p)); - for (t = 5; t <= s->mx && t <= j; t++) { - o = (j - t) - (j & ~7L); - a = (hp[o >> 3] >> (7 - (o & 7))) & 1; - assert(t > 23 || - (a == p) == !(((line_h1 >> t) ^ line_h1) & 0x100)); - c[t] += a == p; - } - for (; t <= s->mx; t++) { - c[t] += 0 == p; - } - ++c_all; - } - } while (++j & 7 && j < hx); - } else { - /* three line template */ - do { - line_h1 <<= 1; line_h2 <<= 1; line_h3 <<= 1; - if (s->tx[plane]) { - if ((unsigned) s->tx[plane] > j) - a = 0; - else { - o = (j - s->tx[plane]) - (j & ~7L); - a = (hp[o >> 3] >> (7 - (o & 7))) & 1; - a <<= 2; - } - assert(s->tx[plane] > 23 || - a == ((line_h1 >> (6 + s->tx[plane])) & 0x004)); - arith_encode(se, (((line_h3 >> 8) & 0x380) | - ((line_h2 >> 12) & 0x078) | a | - ((line_h1 >> 9) & 0x003)), - (line_h1 >> 8) & 1); - } else - arith_encode(se, (((line_h3 >> 8) & 0x380) | - ((line_h2 >> 12) & 0x07c) | - ((line_h1 >> 9) & 0x003)), - (line_h1 >> 8) & 1); -#ifdef DEBUG - encoded_pixels++; -#endif - /* statistics for adaptive template changes */ - if (!at_determined && j >= s->mx && j < hx-2) { - p = (line_h1 & 0x100) != 0; /* current pixel value */ - c[0] += ((line_h2 & 0x4000) != 0) == p; /* default position */ - assert(!(((line_h2 >> 6) ^ line_h1) & 0x100) == - (((line_h2 & 0x4000) != 0) == p)); - for (t = 3; t <= s->mx && t <= j; t++) { - o = (j - t) - (j & ~7L); - a = (hp[o >> 3] >> (7 - (o & 7))) & 1; - assert(t > 23 || - (a == p) == !(((line_h1 >> t) ^ line_h1) & 0x100)); - c[t] += a == p; - } - for (; t <= s->mx; t++) { - c[t] += 0 == p; - } - ++c_all; - } - } while (++j & 7 && j < hx); - } /* if (s->options & JBG_LRLTWO) */ - } /* for (j = ...) */ - } /* for (i = ...) */ - - } else { - - /* - * Encode differential layer - */ - - for (i = 0; i < hl && y < hy; i++, y++) { - - /* check whether it is worth to perform an ATMOVE */ - if (!at_determined && c_all > 2048) { - cmin = clmin = 0xffffffffL; - cmax = clmax = 0; - tmax = 0; - for (t = 3; t <= s->mx; t++) { - if (c[t] > cmax) cmax = c[t]; - if (c[t] < cmin) cmin = c[t]; - if (c[t] > c[tmax]) tmax = t; - } - clmin = (c[0] < cmin) ? c[0] : cmin; - clmax = (c[0] > cmax) ? c[0] : cmax; - if (c_all - cmax < (c_all >> 3) && - cmax - c[s->tx[plane]] > c_all - cmax && - cmax - c[s->tx[plane]] > (c_all >> 4) && - /* ^ T.82 said < here, fixed in Cor.1/25 */ - cmax - (c_all - c[s->tx[plane]]) > c_all - cmax && - cmax - (c_all - c[s->tx[plane]]) > (c_all >> 4) && - cmax - cmin > (c_all >> 2) && - (s->tx[plane] || clmax - clmin > (c_all >> 3))) { - /* we have decided to perform an ATMOVE */ - new_tx = tmax; - if (!(s->options & JBG_DELAY_AT)) { - new_tx_line = i; - s->tx[plane] = new_tx; - } -#ifdef DEBUG - fprintf(stderr, "ATMOVE: line=%ld, tx=%d, c_all=%ld\n", - i, new_tx, c_all); -#endif - } - at_determined = 1; - } - - if ((i >> 1) >= ll - 1 || (y >> 1) >= ly - 1) - lp1 = lp2; - - /* typical prediction */ - if (s->options & JBG_TPDON && (i & 1) == 0) { - q1 = lp1; q2 = lp2; - p0 = p1 = hp; - if (i < hl - 1 && y < hy - 1) - p0 = hp + hbpl; - if (i > 1 || !reset) - line_l3 = (long)*(q2 - lbpl) << 8; - else - line_l3 = 0; - line_l2 = (long)*q2 << 8; - line_l1 = (long)*q1 << 8; - ltp = 1; - for (j = 0; j < lx && ltp; q1++, q2++) { - if (j < lbpl * 8 - 8) { - if (i > 1 || !reset) - line_l3 |= *(q2 - lbpl + 1); - line_l2 |= *(q2 + 1); - line_l1 |= *(q1 + 1); - } - do { - if ((j >> 2) < hbpl) { - line_h1 = *(p1++); - line_h0 = *(p0++); - } - do { - line_l3 <<= 1; - line_l2 <<= 1; - line_l1 <<= 1; - line_h1 <<= 2; - line_h0 <<= 2; - cx = (((line_l3 >> 15) & 0x007) | - ((line_l2 >> 12) & 0x038) | - ((line_l1 >> 9) & 0x1c0)); - if (cx == 0x000) - if ((line_h1 & 0x300) == 0 && (line_h0 & 0x300) == 0) - s->tp[j] = 0; - else { - ltp = 0; -#ifdef DEBUG - tp_exceptions++; -#endif - } - else if (cx == 0x1ff) - if ((line_h1 & 0x300) == 0x300 && (line_h0 & 0x300) == 0x300) - s->tp[j] = 1; - else { - ltp = 0; -#ifdef DEBUG - tp_exceptions++; -#endif - } - else - s->tp[j] = 2; - } while (++j & 3 && j < lx); - } while (j & 7 && j < lx); - } /* for (j = ...) */ - arith_encode(se, TPDCX, !ltp); -#ifdef DEBUG - tp_lines += ltp; -#endif - } - - - /* - * Layout of the variables line_h1, line_h2, line_h3, which contain - * as bits the high resolution neighbour pixels of the currently coded - * highres pixel X: - * - * 76543210 76543210 76543210 76543210 line_h3 - * 76543210 76543210 76543210 76543210 line_h2 - * 76543210 76543210 7654321X 76543210 line_h1 - * - * Layout of the variables line_l1, line_l2, line_l3, which contain - * the low resolution pixels near the currently coded pixel as bits. - * The lowres pixel in which the currently coded highres pixel is - * located is marked as Y: - * - * 76543210 76543210 76543210 76543210 line_l3 - * 76543210 7654321Y 76543210 76543210 line_l2 - * 76543210 76543210 76543210 76543210 line_l1 - */ - - - line_h1 = line_h2 = line_h3 = line_l1 = line_l2 = line_l3 = 0; - if (i > 0 || !reset) line_h2 = (long)*(hp - hbpl) << 8; - if (i > 1 || !reset) { - line_h3 = (long)*(hp - hbpl - hbpl) << 8; - line_l3 = (long)*(lp2 - lbpl) << 8; - } - line_l2 = (long)*lp2 << 8; - line_l1 = (long)*lp1 << 8; - - /* encode line */ - for (j = 0; j < hx; lp1++, lp2++) { - if ((j >> 1) < lbpl * 8 - 8) { - if (i > 1 || !reset) - line_l3 |= *(lp2 - lbpl + 1); - line_l2 |= *(lp2 + 1); - line_l1 |= *(lp1 + 1); - } - do { /* ... while (j & 15 && j < hx) */ - - assert(hp - (s->lhp[s->highres[plane]][plane] + - (stripe * hl + i) * hbpl) - == (ptrdiff_t) j >> 3); - - assert(lp2 - (s->lhp[1-s->highres[plane]][plane] + - (stripe * ll + (i>>1)) * lbpl) - == (ptrdiff_t) j >> 4); - - line_h1 |= *hp; - if (j < hbpl * 8 - 8) { - if (i > 0 || !reset) { - line_h2 |= *(hp - hbpl + 1); - if (i > 1 || !reset) - line_h3 |= *(hp - hbpl - hbpl + 1); - } - } - do { /* ... while (j & 7 && j < hx) */ - line_l1 <<= 1; line_l2 <<= 1; line_l3 <<= 1; - if (ltp && s->tp[j >> 1] < 2) { - /* pixel are typical and have not to be encoded */ - line_h1 <<= 2; line_h2 <<= 2; line_h3 <<= 2; -#ifdef DEBUG - do { - ++tp_pixels; - } while (++j & 1 && j < hx); -#else - j += 2; -#endif - } else - do { /* ... while (++j & 1 && j < hx) */ - line_h1 <<= 1; line_h2 <<= 1; line_h3 <<= 1; - - /* deterministic prediction */ - if (s->options & JBG_DPON) { - if ((y & 1) == 0) { - if ((j & 1) == 0) { - /* phase 0 */ - if (s->dppriv[((line_l3 >> 16) & 0x003) | - ((line_l2 >> 14) & 0x00c) | - ((line_h1 >> 5) & 0x010) | - ((line_h2 >> 10) & 0x0e0)] < 2) { -#ifdef DEBUG - ++dp_pixels; -#endif - continue; - } - } else { - /* phase 1 */ - if (s->dppriv[(((line_l3 >> 16) & 0x003) | - ((line_l2 >> 14) & 0x00c) | - ((line_h1 >> 5) & 0x030) | - ((line_h2 >> 10) & 0x1c0)) + 256] < 2) { -#ifdef DEBUG - ++dp_pixels; -#endif - continue; - } - } - } else { - if ((j & 1) == 0) { - /* phase 2 */ - if (s->dppriv[(((line_l3 >> 16) & 0x003) | - ((line_l2 >> 14) & 0x00c) | - ((line_h1 >> 5) & 0x010) | - ((line_h2 >> 10) & 0x0e0) | - ((line_h3 >> 7) & 0x700)) + 768] < 2) { -#ifdef DEBUG - ++dp_pixels; -#endif - continue; - } - } else { - /* phase 3 */ - if (s->dppriv[(((line_l3 >> 16) & 0x003) | - ((line_l2 >> 14) & 0x00c) | - ((line_h1 >> 5) & 0x030) | - ((line_h2 >> 10) & 0x1c0) | - ((line_h3 >> 7) & 0xe00)) + 2816] < 2) { -#ifdef DEBUG - ++dp_pixels; -#endif - continue; - } - } - } - } - - /* determine context */ - if (s->tx[plane]) { - if ((unsigned) s->tx[plane] > j) - a = 0; - else { - o = (j - s->tx[plane]) - (j & ~7L); - a = (hp[o >> 3] >> (7 - (o & 7))) & 1; - a <<= 4; - } - assert(s->tx[plane] > 23 || - a == ((line_h1 >> (4 + s->tx[plane])) & 0x010)); - cx = (((line_h1 >> 9) & 0x003) | a | - ((line_h2 >> 13) & 0x00c) | - ((line_h3 >> 11) & 0x020)); - } else - cx = (((line_h1 >> 9) & 0x003) | - ((line_h2 >> 13) & 0x01c) | - ((line_h3 >> 11) & 0x020)); - if (j & 1) - cx |= (((line_l2 >> 9) & 0x0c0) | - ((line_l1 >> 7) & 0x300)) | (1UL << 10); - else - cx |= (((line_l2 >> 10) & 0x0c0) | - ((line_l1 >> 8) & 0x300)); - cx |= (y & 1) << 11; - - arith_encode(se, cx, (line_h1 >> 8) & 1); -#ifdef DEBUG - encoded_pixels++; -#endif - - /* statistics for adaptive template changes */ - if (!at_determined && j >= s->mx) { - c[0] += !(((line_h2 >> 6) ^ line_h1) & 0x100); - for (t = 3; t <= s->mx; t++) - c[t] += !(((line_h1 >> t) ^ line_h1) & 0x100); - ++c_all; - } - - } while (++j & 1 && j < hx); - } while (j & 7 && j < hx); - hp++; - } while (j & 15 && j < hx); - } /* for (j = ...) */ - - /* low resolution pixels are used twice */ - if ((i & 1) == 0) { - lp1 -= lbpl; - lp2 -= lbpl; - } - - } /* for (i = ...) */ - } - - arith_encode_flush(se); - jbg_buf_remove_zeros(s->sde[stripe][layer][plane]); - jbg_buf_write(MARKER_ESC, s->sde[stripe][layer][plane]); - jbg_buf_write((s->options & JBG_SDRST) ? MARKER_SDRST : MARKER_SDNORM, - s->sde[stripe][layer][plane]); - if (s->options & JBG_SDRST) - s->tx[plane] = 0; - - /* add ATMOVE */ - if (new_tx != -1) { - if (s->options & JBG_DELAY_AT) { - /* ATMOVE will become active at the first line of the next stripe */ - s->tx[plane] = new_tx; - jbg_buf_write(MARKER_ESC, s->sde[stripe][layer][plane]); - jbg_buf_write(MARKER_ATMOVE, s->sde[stripe][layer][plane]); - jbg_buf_write(0, s->sde[stripe][layer][plane]); - jbg_buf_write(0, s->sde[stripe][layer][plane]); - jbg_buf_write(0, s->sde[stripe][layer][plane]); - jbg_buf_write(0, s->sde[stripe][layer][plane]); - jbg_buf_write(s->tx[plane], s->sde[stripe][layer][plane]); - jbg_buf_write(0, s->sde[stripe][layer][plane]); - } else { - /* ATMOVE has already become active during this stripe - * => we have to prefix the SDE data with an ATMOVE marker */ - new_jbg_buf = jbg_buf_init(&s->free_list); - jbg_buf_write(MARKER_ESC, new_jbg_buf); - jbg_buf_write(MARKER_ATMOVE, new_jbg_buf); - jbg_buf_write((new_tx_line >> 24) & 0xff, new_jbg_buf); - jbg_buf_write((new_tx_line >> 16) & 0xff, new_jbg_buf); - jbg_buf_write((new_tx_line >> 8) & 0xff, new_jbg_buf); - jbg_buf_write(new_tx_line & 0xff, new_jbg_buf); - jbg_buf_write(new_tx, new_jbg_buf); - jbg_buf_write(0, new_jbg_buf); - jbg_buf_prefix(new_jbg_buf, &s->sde[stripe][layer][plane]); - } - } - -#if 0 - if (stripe == s->stripes - 1) - fprintf(stderr, "tp_lines = %ld, tp_exceptions = %ld, tp_pixels = %ld, " - "dp_pixels = %ld, encoded_pixels = %ld\n", - tp_lines, tp_exceptions, tp_pixels, dp_pixels, encoded_pixels); -#endif - - return; -} - - -/* - * Create the next lower resolution version of an image - */ -static void resolution_reduction(struct jbg_enc_state *s, int plane, - int higher_layer) -{ - unsigned long hl, ll, hx, hy, lx, ly, hbpl, lbpl; - unsigned char *hp1, *hp2, *hp3, *lp; - unsigned long line_h1, line_h2, line_h3, line_l2; - unsigned long y; /* current line number in lowres image */ - unsigned long i; /* current line number within lowres stripe */ - unsigned long j; /* current column number in lowres image */ - int pix, k, l; - - /* number of lines per stripe in highres image */ - hl = s->l0 << higher_layer; - /* number of lines per stripe in lowres image */ - ll = hl >> 1; - /* number of pixels in highres image */ - hx = jbg_ceil_half(s->xd, s->d - higher_layer); - hy = jbg_ceil_half(s->yd, s->d - higher_layer); - /* number of pixels in lowres image */ - lx = jbg_ceil_half(hx, 1); - ly = jbg_ceil_half(hy, 1); - /* bytes per line in highres and lowres image */ - hbpl = jbg_ceil_half(hx, 3); - lbpl = jbg_ceil_half(lx, 3); - /* pointers to first image bytes */ - hp2 = s->lhp[s->highres[plane]][plane]; - hp1 = hp2 + hbpl; - hp3 = hp2 - hbpl; - lp = s->lhp[1 - s->highres[plane]][plane]; - -#ifdef DEBUG - fprintf(stderr, "resolution_reduction: plane = %d, higher_layer = %d\n", - plane, higher_layer); -#endif - - /* - * Layout of the variables line_h1, line_h2, line_h3, which contain - * as bits the high resolution neighbour pixels of the currently coded - * lowres pixel /\: - * \/ - * - * 76543210 76543210 76543210 76543210 line_h3 - * 76543210 76543210 765432/\ 76543210 line_h2 - * 76543210 76543210 765432\/ 76543210 line_h1 - * - * Layout of the variable line_l2, which contains the low resolution - * pixels near the currently coded pixel as bits. The lowres pixel - * which is currently coded is marked as X: - * - * 76543210 76543210 76543210 76543210 line_l2 - * X - */ - - for (y = 0; y < ly;) { - for (i = 0; i < ll && y < ly; i++, y++) { - if (2*y + 1 >= hy) - hp1 = hp2; - pix = 0; - line_h1 = line_h2 = line_h3 = line_l2 = 0; - for (j = 0; j < lbpl * 8; j += 8) { - *lp = 0; - if (i > 0 || (y > 0 && !(s->options & JBG_SDRST))) - line_l2 |= *(lp-lbpl); - for (k = 0; k < 8 && j + k < lx; k += 4) { - if (((j + k) >> 2) < hbpl) { - if (i > 0 || (y > 0 && !(s->options & JBG_SDRST))) - line_h3 |= *hp3; - ++hp3; - line_h2 |= *(hp2++); - line_h1 |= *(hp1++); - } - for (l = 0; l < 4 && j + k + l < lx; l++) { - line_h3 <<= 2; - line_h2 <<= 2; - line_h1 <<= 2; - line_l2 <<= 1; - pix = s->res_tab[((line_h1 >> 8) & 0x007) | - ((line_h2 >> 5) & 0x038) | - ((line_h3 >> 2) & 0x1c0) | - (pix << 9) | ((line_l2 << 2) & 0xc00)]; - *lp = (*lp << 1) | pix; - } - } - ++lp; - } - *(lp - 1) <<= lbpl * 8 - lx; - hp1 += hbpl; - hp2 += hbpl; - hp3 += hbpl; - } - } - -#ifdef DEBUG - { - FILE *f; - char fn[50]; - - sprintf(fn, "dbg_d=%02d.pbm", higher_layer - 1); - f = fopen(fn, "wb"); - fprintf(f, "P4\n%lu %lu\n", lx, ly); - fwrite(s->lhp[1 - s->highres[plane]][plane], 1, lbpl * ly, f); - fclose(f); - } -#endif - - return; -} - - -/* - * This function is called inside the three loops of jbg_enc_out() in - * order to write the next SDE. It has first to generate the required - * SDE and all SDEs which have to be encoded before this SDE can be - * created. The problem here is that if we want to output a lower - * resolution layer, we have to apply the resolution reduction - * algorithm first to get it. As we try to safe as much memory as - * possible, the resolution reduction will overwrite previous higher - * resolution bitmaps. Consequently, we have to encode and buffer SDEs - * which depend on higher resolution layers before we can start the - * resolution reduction. All the logic about which SDE has to be - * encoded before resolution reduction is allowed is handled - * here. This approach may be a bit more complex than alternative ways - * of doing it, but it minimizes the amount of temporary memory used. - */ -static void output_sde(struct jbg_enc_state *s, - unsigned long stripe, int layer, int plane) -{ - int lfcl; /* lowest fully coded layer */ - long i; - unsigned long u; - - assert(s->sde[stripe][layer][plane] != SDE_DONE); - - if (s->sde[stripe][layer][plane] != SDE_TODO) { -#ifdef DEBUG - fprintf(stderr, "writing SDE: s/d/p = %2lu/%2d/%2d\n", - stripe, layer, plane); -#endif - jbg_buf_output(&s->sde[stripe][layer][plane], s->data_out, s->file); - s->sde[stripe][layer][plane] = SDE_DONE; - return; - } - - /* Determine the smallest resolution layer in this plane for which - * not yet all stripes have been encoded into SDEs. This layer will - * have to be completely coded, before we can apply the next - * resolution reduction step. */ - lfcl = 0; - for (i = s->d; i >= 0; i--) - if (s->sde[s->stripes - 1][i][plane] == SDE_TODO) { - lfcl = i + 1; - break; - } - if (lfcl > s->d && s->d > 0 && stripe == 0) { - /* perform the first resolution reduction */ - resolution_reduction(s, plane, s->d); - } - /* In case HITOLO is not used, we have to encode and store the higher - * resolution layers first, although we do not need them right now. */ - while (lfcl - 1 > layer) { - for (u = 0; u < s->stripes; u++) - encode_sde(s, u, lfcl - 1, plane); - --lfcl; - s->highres[plane] ^= 1; - if (lfcl > 1) - resolution_reduction(s, plane, lfcl - 1); - } - - encode_sde(s, stripe, layer, plane); - -#ifdef DEBUG - fprintf(stderr, "writing SDE: s/d/p = %2lu/%2d/%2d\n", stripe, layer, plane); -#endif - jbg_buf_output(&s->sde[stripe][layer][plane], s->data_out, s->file); - s->sde[stripe][layer][plane] = SDE_DONE; - - if (stripe == s->stripes - 1 && layer > 0 && - s->sde[0][layer-1][plane] == SDE_TODO) { - s->highres[plane] ^= 1; - if (layer > 1) - resolution_reduction(s, plane, layer - 1); - } - - return; -} - - -/* - * Convert the table which controls the deterministic prediction - * process from the internal format into the representation required - * for the 1728 byte long DPTABLE element of a BIH. - * - * The bit order of the DPTABLE format (see also ITU-T T.82 figure 13) is - * - * high res: 4 5 6 low res: 0 1 - * 7 8 9 2 3 - * 10 11 12 - * - * were 4 table entries are packed into one byte, while we here use - * internally an unpacked 6912 byte long table indexed by the following - * bit order: - * - * high res: 7 6 5 high res: 8 7 6 low res: 1 0 - * (phase 0) 4 . . (phase 1) 5 4 . 3 2 - * . . . . . . - * - * high res: 10 9 8 high res: 11 10 9 - * (phase 2) 7 6 5 (phase 3) 8 7 6 - * 4 . . 5 4 . - */ -void jbg_int2dppriv(unsigned char *dptable, const char *internal) -{ - int i, j, k; - int trans0[ 8] = { 1, 0, 3, 2, 7, 6, 5, 4 }; - int trans1[ 9] = { 1, 0, 3, 2, 8, 7, 6, 5, 4 }; - int trans2[11] = { 1, 0, 3, 2, 10, 9, 8, 7, 6, 5, 4 }; - int trans3[12] = { 1, 0, 3, 2, 11, 10, 9, 8, 7, 6, 5, 4 }; - - for (i = 0; i < 1728; dptable[i++] = 0) ; - -#define FILL_TABLE1(offset, len, trans) \ - for (i = 0; i < len; i++) { \ - k = 0; \ - for (j = 0; i >> j; j++) \ - k |= ((i >> j) & 1) << trans[j]; \ - dptable[(i + offset) >> 2] |= \ - (internal[k + offset] & 3) << ((3 - (i&3)) << 1); \ - } - - FILL_TABLE1( 0, 256, trans0); - FILL_TABLE1( 256, 512, trans1); - FILL_TABLE1( 768, 2048, trans2); - FILL_TABLE1(2816, 4096, trans3); - - return; -} - - -/* - * Convert the table which controls the deterministic prediction - * process from the 1728 byte long DPTABLE format into the 6912 byte long - * internal format. - */ -void jbg_dppriv2int(char *internal, const unsigned char *dptable) -{ - int i, j, k; - int trans0[ 8] = { 1, 0, 3, 2, 7, 6, 5, 4 }; - int trans1[ 9] = { 1, 0, 3, 2, 8, 7, 6, 5, 4 }; - int trans2[11] = { 1, 0, 3, 2, 10, 9, 8, 7, 6, 5, 4 }; - int trans3[12] = { 1, 0, 3, 2, 11, 10, 9, 8, 7, 6, 5, 4 }; - -#define FILL_TABLE2(offset, len, trans) \ - for (i = 0; i < len; i++) { \ - k = 0; \ - for (j = 0; i >> j; j++) \ - k |= ((i >> j) & 1) << trans[j]; \ - internal[k + offset] = \ - (dptable[(i + offset) >> 2] >> ((3 - (i & 3)) << 1)) & 3; \ - } - - FILL_TABLE2( 0, 256, trans0); - FILL_TABLE2( 256, 512, trans1); - FILL_TABLE2( 768, 2048, trans2); - FILL_TABLE2(2816, 4096, trans3); - - return; -} - - -/* - * Encode one full BIE and pass the generated data to the specified - * call-back function - */ -void jbg_enc_out(struct jbg_enc_state *s) -{ - unsigned long bpl; - unsigned char buf[20]; - unsigned long xd, yd, y; - long ii[3], is[3], ie[3]; /* generic variables for the 3 nested loops */ - unsigned long stripe; - int layer, plane; - int order; - unsigned char dpbuf[1728]; - - /* some sanity checks */ - s->order &= JBG_HITOLO | JBG_SEQ | JBG_ILEAVE | JBG_SMID; - order = s->order & (JBG_SEQ | JBG_ILEAVE | JBG_SMID); - if (iindex[order][0] < 0) - s->order = order = JBG_SMID | JBG_ILEAVE; - if (s->options & JBG_DPON && s->dppriv != jbg_dptable) - s->options |= JBG_DPPRIV; - if (s->mx > MX_MAX) - s->mx = MX_MAX; - s->my = 0; - if (s->mx && s->mx < ((s->options & JBG_LRLTWO) ? 5U : 3U)) - s->mx = 0; - if (s->d > 255 || s->d < 0 || s->dh > s->d || s->dh < 0 || - s->dl < 0 || s->dl > s->dh || s->planes < 0 || s->planes > 255) - return; - /* prevent uint32 overflow: s->l0 * 2 ^ s->d < 2 ^ 32 */ - if (s->d > 31 || (s->d != 0 && s->l0 >= (1UL << (32 - s->d)))) - return; - if (s->yd1 < s->yd) - s->yd1 = s->yd; - if (s->yd1 > s->yd) - s->options |= JBG_VLENGTH; - - /* ensure correct zero padding of bitmap at the final byte of each line */ - if (s->xd & 7) { - bpl = jbg_ceil_half(s->xd, 3); /* bytes per line */ - for (plane = 0; plane < s->planes; plane++) - for (y = 0; y < s->yd; y++) - s->lhp[0][plane][y * bpl + bpl - 1] &= ~((1 << (8 - (s->xd & 7))) - 1); - } - - /* prepare BIH */ - buf[0] = s->dl; - buf[1] = s->dh; - buf[2] = s->planes; - buf[3] = 0; - xd = jbg_ceil_half(s->xd, s->d - s->dh); - yd = jbg_ceil_half(s->yd1, s->d - s->dh); - buf[4] = xd >> 24; - buf[5] = (xd >> 16) & 0xff; - buf[6] = (xd >> 8) & 0xff; - buf[7] = xd & 0xff; - buf[8] = yd >> 24; - buf[9] = (yd >> 16) & 0xff; - buf[10] = (yd >> 8) & 0xff; - buf[11] = yd & 0xff; - buf[12] = s->l0 >> 24; - buf[13] = (s->l0 >> 16) & 0xff; - buf[14] = (s->l0 >> 8) & 0xff; - buf[15] = s->l0 & 0xff; - buf[16] = s->mx; - buf[17] = s->my; - buf[18] = s->order; - buf[19] = s->options & 0x7f; - -#if 0 - /* sanitize L0 (if it was set to 0xffffffff for T.85-style NEWLEN tests) */ - if (s->l0 > (s->yd >> s->d)) - s->l0 = s->yd >> s->d; -#endif - - /* calculate number of stripes that will be required */ - s->stripes = jbg_stripes(s->l0, s->yd, s->d); - - /* allocate buffers for SDE pointers */ - if (s->sde == NULL) { - s->sde = (struct jbg_buf ****) - checked_malloc(s->stripes, sizeof(struct jbg_buf ***)); - for (stripe = 0; stripe < s->stripes; stripe++) { - s->sde[stripe] = (struct jbg_buf ***) - checked_malloc(s->d + 1, sizeof(struct jbg_buf **)); - for (layer = 0; layer < s->d + 1; layer++) { - s->sde[stripe][layer] = (struct jbg_buf **) - checked_malloc(s->planes, sizeof(struct jbg_buf *)); - for (plane = 0; plane < s->planes; plane++) - s->sde[stripe][layer][plane] = SDE_TODO; - } - } - } - - /* output BIH */ - s->data_out(buf, 20, s->file); - if ((s->options & (JBG_DPON | JBG_DPPRIV | JBG_DPLAST)) == - (JBG_DPON | JBG_DPPRIV)) { - /* write private table */ - jbg_int2dppriv(dpbuf, s->dppriv); - s->data_out(dpbuf, 1728, s->file); - } - -#if 0 - /* - * Encode everything first. This is a simple-minded alternative to - * all the tricky on-demand encoding logic in output_sde() for - * debugging purposes. - */ - for (layer = s->dh; layer >= s->dl; layer--) { - for (plane = 0; plane < s->planes; plane++) { - if (layer > 0) - resolution_reduction(s, plane, layer); - for (stripe = 0; stripe < s->stripes; stripe++) - encode_sde(s, stripe, layer, plane); - s->highres[plane] ^= 1; - } - } -#endif - - /* - * Generic loops over all SDEs. Which loop represents layer, plane and - * stripe depends on the option flags. - */ - - /* start and end value for each loop */ - is[iindex[order][STRIPE]] = 0; - ie[iindex[order][STRIPE]] = s->stripes - 1; - is[iindex[order][LAYER]] = s->dl; - ie[iindex[order][LAYER]] = s->dh; - is[iindex[order][PLANE]] = 0; - ie[iindex[order][PLANE]] = s->planes - 1; - - for (ii[0] = is[0]; ii[0] <= ie[0]; ii[0]++) - for (ii[1] = is[1]; ii[1] <= ie[1]; ii[1]++) - for (ii[2] = is[2]; ii[2] <= ie[2]; ii[2]++) { - - stripe = ii[iindex[order][STRIPE]]; - if (s->order & JBG_HITOLO) - layer = s->dh - (ii[iindex[order][LAYER]] - s->dl); - else - layer = ii[iindex[order][LAYER]]; - plane = ii[iindex[order][PLANE]]; - - /* output comment marker segment if there is any pending */ - if (s->comment) { - buf[0] = MARKER_ESC; - buf[1] = MARKER_COMMENT; - buf[2] = s->comment_len >> 24; - buf[3] = (s->comment_len >> 16) & 0xff; - buf[4] = (s->comment_len >> 8) & 0xff; - buf[5] = s->comment_len & 0xff; - s->data_out(buf, 6, s->file); - s->data_out(s->comment, s->comment_len, s->file); - s->comment = NULL; - } - - output_sde(s, stripe, layer, plane); - - /* - * When we generate a NEWLEN test case (s->yd1 > s->yd), output - * NEWLEN after last stripe if we have only a single - * resolution layer or plane (see ITU-T T.85 profile), otherwise - * output NEWLEN before last stripe. - */ - if (s->yd1 > s->yd && - (stripe == s->stripes - 1 || - (stripe == s->stripes - 2 && - (s->dl != s->dh || s->planes > 1)))) { - s->yd1 = s->yd; - yd = jbg_ceil_half(s->yd, s->d - s->dh); - buf[0] = MARKER_ESC; - buf[1] = MARKER_NEWLEN; - buf[2] = yd >> 24; - buf[3] = (yd >> 16) & 0xff; - buf[4] = (yd >> 8) & 0xff; - buf[5] = yd & 0xff; - s->data_out(buf, 6, s->file); -#ifdef DEBUG - fprintf(stderr, "NEWLEN: yd=%lu\n", yd); -#endif - if (stripe == s->stripes - 1) { - buf[1] = MARKER_SDNORM; - s->data_out(buf, 2, s->file); - } - } - - } - - return; -} - - -void jbg_enc_free(struct jbg_enc_state *s) -{ - unsigned long stripe; - int layer, plane; - -#ifdef DEBUG - fprintf(stderr, "jbg_enc_free(%p)\n", (void *) s); -#endif - - /* clear buffers for SDEs */ - if (s->sde) { - for (stripe = 0; stripe < s->stripes; stripe++) { - for (layer = 0; layer < s->d + 1; layer++) { - for (plane = 0; plane < s->planes; plane++) - if (s->sde[stripe][layer][plane] != SDE_DONE && - s->sde[stripe][layer][plane] != SDE_TODO) - jbg_buf_free(&s->sde[stripe][layer][plane]); - checked_free(s->sde[stripe][layer]); - } - checked_free(s->sde[stripe]); - } - checked_free(s->sde); - } - - /* clear free_list */ - jbg_buf_free(&s->free_list); - - /* clear memory for arithmetic encoder states */ - checked_free(s->s); - - /* clear memory for differential-layer typical prediction buffer */ - checked_free(s->tp); - - /* clear memory for adaptive template pixel offsets */ - checked_free(s->tx); - - /* clear lowres image buffers */ - if (s->lhp[1]) { - for (plane = 0; plane < s->planes; plane++) - checked_free(s->lhp[1][plane]); - checked_free(s->lhp[1]); - } - - /* clear buffer for index of highres image in lhp */ - checked_free(s->highres); - - return; -} - - -/* - * Convert the error codes used by jbg_dec_in() into an English ASCII string - */ -const char *jbg_strerror(int errnum) -{ - errnum >>= 4; - if (errnum < 0 || (unsigned) errnum >= sizeof(errmsg)/sizeof(errmsg[0])) - return "Unknown error code passed to jbg_strerror()"; - - return errmsg[errnum]; -} - - -/* - * The constructor for a decoder - */ -void jbg_dec_init(struct jbg_dec_state *s) -{ - s->order = 0; - s->d = -1; - s->bie_len = 0; - s->buf_len = 0; - s->dppriv = NULL; - s->xmax = 4294967295UL; - s->ymax = 4294967295UL; - s->dmax = 256; - s->maxmem = 2000000000; /* no final image larger than 2 GB by default */ - s->s = NULL; - - return; -} - - -/* - * Specify a maximum image size for the decoder. If the JBIG file has - * the order bit ILEAVE, but not the bit SEQ set, then the decoder - * will abort to decode after the image has reached the maximal - * resolution layer which is still not wider than xmax or higher than - * ymax. - */ -void jbg_dec_maxsize(struct jbg_dec_state *s, unsigned long xmax, - unsigned long ymax) -{ - if (xmax > 0) s->xmax = xmax; - if (ymax > 0) s->ymax = ymax; - - return; -} - - -/* - * Decode the new len PSDC bytes to which data points and add them to - * the current stripe. Return the number of bytes which have actually - * been read (this will be less than len if a marker segment was - * part of the data or if the final byte was 0xff, in which case - * this code cannot determine whether we have a marker segment). - */ -static size_t decode_pscd(struct jbg_dec_state *s, unsigned char *data, - size_t len) -{ - unsigned long stripe; - unsigned int layer, plane; - unsigned long hl, ll, y, hx, hy, lx, ly, hbpl, lbpl; - unsigned char *hp, *lp1, *lp2, *p1, *q1; - register unsigned long line_h1, line_h2, line_h3; - register unsigned long line_l1, line_l2, line_l3; - struct jbg_ardec_state *se; - unsigned long x; - long o; - unsigned a; - int n; - int pix, cx = 0, slntp, tx; - - /* SDE loop variables */ - stripe = s->ii[iindex[s->order & 7][STRIPE]]; - layer = s->ii[iindex[s->order & 7][LAYER]]; - plane = s->ii[iindex[s->order & 7][PLANE]]; - - /* forward data to arithmetic decoder */ - se = s->s[plane] + layer - s->dl; - se->pscd_ptr = data; - se->pscd_end = data + len; - - /* number of lines per stripe in highres image */ - hl = s->l0 << layer; - /* number of lines per stripe in lowres image */ - ll = hl >> 1; - /* current line number in highres image */ - y = stripe * hl + s->i; - /* number of pixels in highres image */ - hx = jbg_ceil_half(s->xd, s->d - layer); - hy = jbg_ceil_half(s->yd, s->d - layer); - /* number of pixels in lowres image */ - lx = jbg_ceil_half(hx, 1); - ly = jbg_ceil_half(hy, 1); - /* bytes per line in highres and lowres image */ - hbpl = jbg_ceil_half(hx, 3); - lbpl = jbg_ceil_half(lx, 3); - /* pointer to highres and lowres image bytes */ - hp = s->lhp[ layer & 1][plane] + (stripe * hl + s->i) * hbpl + - (s->x >> 3); - lp2 = s->lhp[(layer-1) & 1][plane] + (stripe * ll + (s->i >> 1)) * lbpl + - (s->x >> 4); - lp1 = lp2 + lbpl; - - /* restore a few local variables */ - line_h1 = s->line_h1; - line_h2 = s->line_h2; - line_h3 = s->line_h3; - line_l1 = s->line_l1; - line_l2 = s->line_l2; - line_l3 = s->line_l3; - x = s->x; - -#ifdef DEBUG - if (s->x == 0 && s->i == 0 && s->pseudo) - fprintf(stderr, "decode_pscd(%p, %p, %ld): s/d/p = %2lu/%2u/%2u\n", - (void *) s, (void *) data, (long) len, stripe, layer, plane); -#endif - - if (s->x == 0 && s->i == 0 && - (stripe == 0 || s->reset[plane][layer - s->dl]) && s->pseudo) { - s->tx[plane][layer - s->dl] = s->ty[plane][layer - s->dl] = 0; - s->lntp[plane][layer - s->dl] = 1; - } - - if (layer == 0) { - - /* - * Decode lowest resolution layer - */ - - for (; s->i < hl && y < hy; s->i++, y++) { - - /* adaptive template changes */ - if (x == 0 && s->pseudo) - for (n = 0; n < s->at_moves; n++) - if (s->at_line[n] == s->i) { - s->tx[plane][layer - s->dl] = s->at_tx[n]; - s->ty[plane][layer - s->dl] = s->at_ty[n]; -#ifdef DEBUG - fprintf(stderr, "ATMOVE: line=%lu, tx=%d, ty=%d.\n", s->i, - s->tx[plane][layer - s->dl], s->ty[plane][layer - s->dl]); -#endif - } - tx = s->tx[plane][layer - s->dl]; - assert(tx >= 0); /* i.e., tx can safely be cast to unsigned */ - - /* typical prediction */ - if (s->options & JBG_TPBON && s->pseudo) { - slntp = arith_decode(se, (s->options & JBG_LRLTWO) ? TPB2CX : TPB3CX); - if (slntp < 0) - goto leave; - s->lntp[plane][layer - s->dl] = - !(slntp ^ s->lntp[plane][layer - s->dl]); - if (!s->lntp[plane][layer - s->dl]) { - /* this line is 'typical' (i.e. identical to the previous one) */ - p1 = hp; - if (s->i == 0 && (stripe == 0 || s->reset[plane][layer - s->dl])) - while (p1 < hp + hbpl) *p1++ = 0; - else { - q1 = hp - hbpl; - while (q1 < hp) *p1++ = *q1++; - } - hp += hbpl; - continue; - } - /* this line is 'not typical' and has to be coded completely */ - } - s->pseudo = 0; - - /* - * Layout of the variables line_h1, line_h2, line_h3, which contain - * as bits the neighbour pixels of the currently decoded pixel X: - * - * 76543210 76543210 76543210 76543210 line_h3 - * 76543210 76543210 76543210 76543210 line_h2 - * 76543210 76543210 76543210 76543210 X line_h1 - */ - - if (x == 0) { - line_h1 = line_h2 = line_h3 = 0; - if (s->i > 0 || (y > 0 && !s->reset[plane][layer - s->dl])) - line_h2 = (long)*(hp - hbpl) << 8; - if (s->i > 1 || (y > 1 && !s->reset[plane][layer - s->dl])) - line_h3 = (long)*(hp - hbpl - hbpl) << 8; - } - - /* - * Another tiny JBIG standard bug: - * - * While implementing the line_h3 handling here, I discovered - * another problem with the ITU-T T.82(1993 E) specification. - * This might be a somewhat pathological case, however. The - * standard is unclear about how a decoder should behave in the - * following situation: - * - * Assume we are in layer 0 and all stripes are single lines - * (L0=1 allowed by table 9). We are now decoding the first (and - * only) line of the third stripe. Assume, the first stripe was - * terminated by SDRST and the second stripe was terminated by - * SDNORM. While decoding the only line of the third stripe with - * the three-line template, we need access to pixels from the - * previous two stripes. We know that the previous stripe - * terminated with SDNROM, so we access the pixel from the - * second stripe. But do we have to replace the pixels from the - * first stripe by background pixels, because this stripe ended - * with SDRST? The standard, especially clause 6.2.5 does never - * mention this case, so the behaviour is undefined here. My - * current implementation remembers only the marker used to - * terminate the previous stripe. In the above example, the - * pixels of the first stripe are accessed despite the fact that - * this stripe ended with SDRST. An alternative (only slightly - * more complicated) implementation would be to remember the end - * marker (SDNORM or SDRST) of the previous two stripes in a - * plane/layer and to act accordingly when accessing the two - * previous lines. What am I supposed to do here? - * - * As the standard is unclear about the correct behaviour in the - * situation of the above example, I strongly suggest to avoid - * the following situation while encoding data with JBIG: - * - * LRLTWO = 0, L0=1 and both SDNORM and SDRST appear in layer 0. - * - * I guess that only a very few if any encoders will switch - * between SDNORM and SDRST, so let us hope that this ambiguity - * in the standard will never cause any interoperability - * problems. - * - * Markus Kuhn -- 1995-04-30 - */ - - /* decode line */ - while (x < hx) { - if ((x & 7) == 0) { - if (x < hbpl * 8 - 8 && - (s->i > 0 || (y > 0 && !s->reset[plane][layer - s->dl]))) { - line_h2 |= *(hp - hbpl + 1); - if (s->i > 1 || (y > 1 && !s->reset[plane][layer - s->dl])) - line_h3 |= *(hp - hbpl - hbpl + 1); - } - } - if (s->options & JBG_LRLTWO) { - /* two line template */ - do { - if (tx) { - if ((unsigned) tx > x) - a = 0; - else if (tx < 8) - a = ((line_h1 >> (tx - 5)) & 0x010); - else { - o = (x - tx) - (x & ~7L); - a = (hp[o >> 3] >> (7 - (o & 7))) & 1; - a <<= 4; - } - assert(tx > 31 || - a == ((line_h1 >> (tx - 5)) & 0x010)); - pix = arith_decode(se, (((line_h2 >> 9) & 0x3e0) | a | - (line_h1 & 0x00f))); - } else - pix = arith_decode(se, (((line_h2 >> 9) & 0x3f0) | - (line_h1 & 0x00f))); - if (pix < 0) - goto leave; - line_h1 = (line_h1 << 1) | pix; - line_h2 <<= 1; - } while ((++x & 7) && x < hx); - } else { - /* three line template */ - do { - if (tx) { - if ((unsigned) tx > x) - a = 0; - else if (tx < 8) - a = ((line_h1 >> (tx - 3)) & 0x004); - else { - o = (x - tx) - (x & ~7L); - a = (hp[o >> 3] >> (7 - (o & 7))) & 1; - a <<= 2; - } - assert(tx > 31 || - a == ((line_h1 >> (tx - 3)) & 0x004)); - pix = arith_decode(se, (((line_h3 >> 7) & 0x380) | - ((line_h2 >> 11) & 0x078) | a | - (line_h1 & 0x003))); - } else - pix = arith_decode(se, (((line_h3 >> 7) & 0x380) | - ((line_h2 >> 11) & 0x07c) | - (line_h1 & 0x003))); - if (pix < 0) - goto leave; - - line_h1 = (line_h1 << 1) | pix; - line_h2 <<= 1; - line_h3 <<= 1; - } while ((++x & 7) && x < hx); - } /* if (s->options & JBG_LRLTWO) */ - *hp++ = line_h1; - } /* while */ - *(hp - 1) <<= hbpl * 8 - hx; - x = 0; - s->pseudo = 1; - } /* for (i = ...) */ - - } else { - - /* - * Decode differential layer - */ - - for (; s->i < hl && y < hy; s->i++, y++) { - - /* adaptive template changes */ - if (x == 0) - for (n = 0; n < s->at_moves; n++) - if (s->at_line[n] == s->i) { - s->tx[plane][layer - s->dl] = s->at_tx[n]; - s->ty[plane][layer - s->dl] = s->at_ty[n]; -#ifdef DEBUG - fprintf(stderr, "ATMOVE: line=%lu, tx=%d, ty=%d.\n", s->i, - s->tx[plane][layer - s->dl], s->ty[plane][layer - s->dl]); -#endif - } - tx = s->tx[plane][layer - s->dl]; - - /* handle lower border of low-resolution image */ - if ((s->i >> 1) >= ll - 1 || (y >> 1) >= ly - 1) - lp1 = lp2; - - /* typical prediction */ - if ((s->options & JBG_TPDON) && s->pseudo) { - if ((s->lntp[plane][layer - s->dl] = arith_decode(se, TPDCX)) < 0) - goto leave; - } - s->pseudo = 0; - - /* - * Layout of the variables line_h1, line_h2, line_h3, which contain - * as bits the high resolution neighbour pixels of the currently - * decoded highres pixel X: - * - * 76543210 76543210 76543210 76543210 line_h3 - * 76543210 76543210 76543210 76543210 line_h2 - * 76543210 76543210 76543210 76543210 X line_h1 - * - * Layout of the variables line_l1, line_l2, line_l3, which contain - * the low resolution pixels near the currently decoded pixel as bits. - * The lowres pixel in which the currently coded highres pixel is - * located is marked as Y: - * - * 76543210 76543210 76543210 76543210 line_l3 - * 76543210 76543210 Y6543210 76543210 line_l2 - * 76543210 76543210 76543210 76543210 line_l1 - */ - - - if (x == 0) { - line_h1 = line_h2 = line_h3 = line_l1 = line_l2 = line_l3 = 0; - if (s->i > 0 || (y > 0 && !s->reset[plane][layer - s->dl])) { - line_h2 = (long)*(hp - hbpl) << 8; - if (s->i > 1 || (y > 1 && !s->reset[plane][layer - s->dl])) - line_h3 = (long)*(hp - hbpl - hbpl) << 8; - } - if (s->i > 1 || (y > 1 && !s->reset[plane][layer-s->dl])) - line_l3 = (long)*(lp2 - lbpl) << 8; - line_l2 = (long)*lp2 << 8; - line_l1 = (long)*lp1 << 8; - } - - /* decode line */ - while (x < hx) { - if ((x & 15) == 0) - if ((x >> 1) < lbpl * 8 - 8) { - line_l1 |= *(lp1 + 1); - line_l2 |= *(lp2 + 1); - if (s->i > 1 || - (y > 1 && !s->reset[plane][layer - s->dl])) - line_l3 |= *(lp2 - lbpl + 1); - } - do { - - assert(hp - (s->lhp[ layer &1][plane] + (stripe * hl + s->i) - * hbpl) == (ptrdiff_t) x >> 3); - assert(lp2 - (s->lhp[(layer-1) &1][plane] + (stripe * ll + (s->i>>1)) - * lbpl) == (ptrdiff_t) x >> 4); - - if ((x & 7) == 0) - if (x < hbpl * 8 - 8) { - if (s->i > 0 || (y > 0 && !s->reset[plane][layer - s->dl])) { - line_h2 |= *(hp + 1 - hbpl); - if (s->i > 1 || (y > 1 && !s->reset[plane][layer - s->dl])) - line_h3 |= *(hp + 1 - hbpl - hbpl); - } - } - do { - if (!s->lntp[plane][layer - s->dl]) - cx = (((line_l3 >> 14) & 0x007) | - ((line_l2 >> 11) & 0x038) | - ((line_l1 >> 8) & 0x1c0)); - if (!s->lntp[plane][layer - s->dl] && - (cx == 0x000 || cx == 0x1ff)) { - /* pixels are typical and have not to be decoded */ - do { - line_h1 = (line_h1 << 1) | (cx & 1); - } while ((++x & 1) && x < hx); - line_h2 <<= 2; line_h3 <<= 2; - } else - do { - - /* deterministic prediction */ - if (s->options & JBG_DPON) - if ((y & 1) == 0) - if ((x & 1) == 0) - /* phase 0 */ - pix = s->dppriv[((line_l3 >> 15) & 0x003) | - ((line_l2 >> 13) & 0x00c) | - ((line_h1 << 4) & 0x010) | - ((line_h2 >> 9) & 0x0e0)]; - else - /* phase 1 */ - pix = s->dppriv[(((line_l3 >> 15) & 0x003) | - ((line_l2 >> 13) & 0x00c) | - ((line_h1 << 4) & 0x030) | - ((line_h2 >> 9) & 0x1c0)) + 256]; - else - if ((x & 1) == 0) - /* phase 2 */ - pix = s->dppriv[(((line_l3 >> 15) & 0x003) | - ((line_l2 >> 13) & 0x00c) | - ((line_h1 << 4) & 0x010) | - ((line_h2 >> 9) & 0x0e0) | - ((line_h3 >> 6) & 0x700)) + 768]; - else - /* phase 3 */ - pix = s->dppriv[(((line_l3 >> 15) & 0x003) | - ((line_l2 >> 13) & 0x00c) | - ((line_h1 << 4) & 0x030) | - ((line_h2 >> 9) & 0x1c0) | - ((line_h3 >> 6) & 0xe00)) + 2816]; - else - pix = 2; - - if (pix & 2) { - if (tx) - cx = ((line_h1 & 0x003) | - (((line_h1 << 2) >> (tx - 3)) & 0x010) | - ((line_h2 >> 12) & 0x00c) | - ((line_h3 >> 10) & 0x020)); - else - cx = ((line_h1 & 0x003) | - ((line_h2 >> 12) & 0x01c) | - ((line_h3 >> 10) & 0x020)); - if (x & 1) - cx |= (((line_l2 >> 8) & 0x0c0) | - ((line_l1 >> 6) & 0x300)) | (1UL << 10); - else - cx |= (((line_l2 >> 9) & 0x0c0) | - ((line_l1 >> 7) & 0x300)); - cx |= (y & 1) << 11; - - pix = arith_decode(se, cx); - if (pix < 0) - goto leave; - } - - line_h1 = (line_h1 << 1) | pix; - line_h2 <<= 1; - line_h3 <<= 1; - - } while ((++x & 1) && x < hx); - line_l1 <<= 1; line_l2 <<= 1; line_l3 <<= 1; - } while ((x & 7) && x < hx); - *hp++ = line_h1; - } while ((x & 15) && x < hx); - ++lp1; - ++lp2; - } /* while */ - x = 0; - - *(hp - 1) <<= hbpl * 8 - hx; - if ((s->i & 1) == 0) { - /* low resolution pixels are used twice */ - lp1 -= lbpl; - lp2 -= lbpl; - } else - s->pseudo = 1; - - } /* for (i = ...) */ - - } - - leave: - - /* save a few local variables */ - s->line_h1 = line_h1; - s->line_h2 = line_h2; - s->line_h3 = line_h3; - s->line_l1 = line_l1; - s->line_l2 = line_l2; - s->line_l3 = line_l3; - s->x = x; - - return se->pscd_ptr - data; -} - - -/* - * Provide to the decoder a new BIE fragment of len bytes starting at data. - * - * Unless cnt is NULL, *cnt will contain the number of actually read bytes - * on return. - * - * Normal return values: - * - * JBG_EAGAIN All data bytes provided so far have been processed - * (*cnt == len) but the end of the data stream has - * not yet been recognized. Call the function again - * with additional BIE bytes. - * JBG_EOK The function has reached the end of a and - * a full image has been decoded. The function can - * be called again with data from the next BIE, if - * there exists one, in order to get to a higher - * resolution layer. The remaining len - *cnt bytes - * of the previous data block will then have to passed - * to this function again if len > *cnt. - * JBG_EOK_INTR Parsing the BIE has been interrupted as had been - * requested by a jbg_dec_maxsize() specification. - * This function can be called again with the - * rest of the BIE to continue the decoding process. - * The remaining len - *cnt bytes of the previous - * data block will then have to be passed to this - * function again if len > *cnt. - * - * Any other return value indicates that the decoding process was - * aborted by a serious problem and the only function you can then - * still call is jbg_dec_free() in order to remove the mess, and - * jbg85_strerror() to find out what to tell the user. (Looking at the - * least significant bits of the return value will provide additional - * information by identifying which test exactly has failed.) - */ -int jbg_dec_in(struct jbg_dec_state *s, unsigned char *data, size_t len, - size_t *cnt) -{ - int i, j, required_length; - unsigned long x, y; - unsigned long is[3], ie[3]; - size_t dummy_cnt; - unsigned char *dppriv; - - if (!cnt) cnt = &dummy_cnt; - *cnt = 0; - if (len < 1) return JBG_EAGAIN; - - /* read in 20-byte BIH */ - if (s->bie_len < 20) { - while (s->bie_len < 20 && *cnt < len) - s->buffer[s->bie_len++] = data[(*cnt)++]; - if (s->bie_len < 20) - return JBG_EAGAIN; - /* test whether this looks like a valid JBIG header at all */ - if (s->buffer[1] < s->buffer[0]) - return JBG_EINVAL | 1; - if (s->buffer[3] != 0) return JBG_EINVAL | 2; /* padding != 0 */ - if ((s->buffer[18] & 0xf0) != 0) return JBG_EINVAL | 3; /* padding != 0 */ - if ((s->buffer[19] & 0x80) != 0) return JBG_EINVAL | 4; /* padding != 0 */ - if (s->buffer[0] != s->d + 1) - return JBG_ENOCONT | 1; - s->dl = s->buffer[0]; - s->d = s->buffer[1]; - if (s->dl == 0) - s->planes = s->buffer[2]; - else - if (s->planes != s->buffer[2]) - return JBG_ENOCONT | 2; - x = (((long) s->buffer[ 4] << 24) | ((long) s->buffer[ 5] << 16) | - ((long) s->buffer[ 6] << 8) | (long) s->buffer[ 7]); - y = (((long) s->buffer[ 8] << 24) | ((long) s->buffer[ 9] << 16) | - ((long) s->buffer[10] << 8) | (long) s->buffer[11]); - if (s->dl != 0 && ((s->xd << (s->d - s->dl + 1)) != x && - (s->yd << (s->d - s->dl + 1)) != y)) - return JBG_ENOCONT | 3; - s->xd = x; - s->yd = y; - s->l0 = (((long) s->buffer[12] << 24) | ((long) s->buffer[13] << 16) | - ((long) s->buffer[14] << 8) | (long) s->buffer[15]); - /* ITU-T T.85 trick not directly supported by decoder; for full - * T.85 compatibility with respect to all NEWLEN marker scenarios, - * preprocess BIE with jbg_newlen() before passing it to the decoder, - * or consider using the decoder found in jbig85.c instead. */ - if (s->yd == 0xffffffff) - return JBG_EIMPL | 1; - if (!s->planes) return JBG_EINVAL | 5; - if (!s->xd) return JBG_EINVAL | 6; - if (!s->yd) return JBG_EINVAL | 7; - if (!s->l0) return JBG_EINVAL | 8; - /* prevent uint32 overflow: s->l0 * 2 ^ s->d < 2 ^ 32 */ - if (s->d > 31) - return JBG_EIMPL | 2; - if ((s->d != 0 && s->l0 >= (1UL << (32 - s->d)))) - return JBG_EIMPL | 3; - s->mx = s->buffer[16]; - if (s->mx > 127) - return JBG_EINVAL | 9; - s->my = s->buffer[17]; -#if 0 - if (s->my > 0) - return JBG_EIMPL | 4; -#endif - s->order = s->buffer[18]; - if (iindex[s->order & 7][0] < 0) - return JBG_EINVAL | 10; - /* HITOLO and SEQ currently not yet implemented */ - if (s->dl != s->d && (s->order & JBG_HITOLO || s->order & JBG_SEQ)) - return JBG_EIMPL | 5; - s->options = s->buffer[19]; - - /* will the final image require more bytes than permitted by s->maxmem? */ - if (s->maxmem / s->planes / s->yd / jbg_ceil_half(s->xd, 3) == 0) - return JBG_ENOMEM; /* increase s->maxmem if needed */ - - /* calculate number of stripes that will be required */ - s->stripes = jbg_stripes(s->l0, s->yd, s->d); - - /* some initialization */ - s->ii[iindex[s->order & 7][STRIPE]] = 0; - s->ii[iindex[s->order & 7][LAYER]] = s->dl; - s->ii[iindex[s->order & 7][PLANE]] = 0; - if (s->dl == 0) { - s->s = (struct jbg_ardec_state **) - checked_malloc(s->planes, sizeof(struct jbg_ardec_state *)); - s->tx = (int **) checked_malloc(s->planes, sizeof(int *)); - s->ty = (int **) checked_malloc(s->planes, sizeof(int *)); - s->reset = (int **) checked_malloc(s->planes, sizeof(int *)); - s->lntp = (int **) checked_malloc(s->planes, sizeof(int *)); - s->lhp[0] = (unsigned char **) - checked_malloc(s->planes, sizeof(unsigned char *)); - s->lhp[1] = (unsigned char **) - checked_malloc(s->planes, sizeof(unsigned char *)); - for (i = 0; i < s->planes; i++) { - s->s[i] = (struct jbg_ardec_state *) - checked_malloc(s->d - s->dl + 1, sizeof(struct jbg_ardec_state)); - s->tx[i] = (int *) checked_malloc(s->d - s->dl + 1, sizeof(int)); - s->ty[i] = (int *) checked_malloc(s->d - s->dl + 1, sizeof(int)); - s->reset[i] = (int *) checked_malloc(s->d - s->dl + 1, sizeof(int)); - s->lntp[i] = (int *) checked_malloc(s->d - s->dl + 1, sizeof(int)); - s->lhp[ s->d & 1][i] = (unsigned char *) - checked_malloc(s->yd, jbg_ceil_half(s->xd, 3)); - s->lhp[(s->d-1) & 1][i] = (unsigned char *) - checked_malloc(jbg_ceil_half(s->yd, 1), jbg_ceil_half(s->xd, 1+3)); - } - } else { - for (i = 0; i < s->planes; i++) { - s->s[i] = (struct jbg_ardec_state *) - checked_realloc(s->s[i], s->d - s->dl + 1, - sizeof(struct jbg_ardec_state)); - s->tx[i] = (int *) checked_realloc(s->tx[i], - s->d - s->dl + 1, sizeof(int)); - s->ty[i] = (int *) checked_realloc(s->ty[i], - s->d - s->dl + 1, sizeof(int)); - s->reset[i] = (int *) checked_realloc(s->reset[i], - s->d - s->dl + 1, sizeof(int)); - s->lntp[i] = (int *) checked_realloc(s->lntp[i], - s->d - s->dl + 1, sizeof(int)); - s->lhp[ s->d & 1][i] = (unsigned char *) - checked_realloc(s->lhp[ s->d & 1][i], - s->yd, jbg_ceil_half(s->xd, 3)); - s->lhp[(s->d-1) & 1][i] = (unsigned char *) - checked_realloc(s->lhp[(s->d-1) & 1][i], - jbg_ceil_half(s->yd, 1), jbg_ceil_half(s->xd, 1+3)); - } - } - for (i = 0; i < s->planes; i++) - for (j = 0; j <= s->d - s->dl; j++) - arith_decode_init(s->s[i] + j, 0); - if (s->dl == 0 || (s->options & JBG_DPON && !(s->options & JBG_DPPRIV))) - s->dppriv = jbg_dptable; - s->comment_skip = 0; - s->buf_len = 0; - s->x = 0; - s->i = 0; - s->pseudo = 1; - s->at_moves = 0; - } - - /* read in DPTABLE */ - if (s->bie_len < 20 + 1728 && - (s->options & (JBG_DPON | JBG_DPPRIV | JBG_DPLAST)) == - (JBG_DPON | JBG_DPPRIV)) { - assert(s->bie_len >= 20); - if (!s->dppriv || s->dppriv == jbg_dptable) - s->dppriv = (char *) checked_malloc(1728, sizeof(char)); - while (s->bie_len < 20 + 1728 && *cnt < len) - s->dppriv[s->bie_len++ - 20] = data[(*cnt)++]; - if (s->bie_len < 20 + 1728) - return JBG_EAGAIN; - dppriv = (unsigned char *) s->dppriv; - s->dppriv = (char *) checked_malloc(6912, sizeof(char)); - jbg_dppriv2int(s->dppriv, dppriv); - checked_free(dppriv); - } - - /* - * BID processing loop - */ - - while (*cnt < len) { - - /* process floating marker segments */ - - /* skip COMMENT contents */ - if (s->comment_skip) { - if (s->comment_skip <= len - *cnt) { - *cnt += s->comment_skip; - s->comment_skip = 0; - } else { - s->comment_skip -= len - *cnt; - *cnt = len; - } - continue; - } - - /* load complete marker segments into s->buffer for processing */ - if (s->buf_len > 0) { - assert(s->buffer[0] == MARKER_ESC); - while (s->buf_len < 2 && *cnt < len) - s->buffer[s->buf_len++] = data[(*cnt)++]; - if (s->buf_len < 2) continue; - switch (s->buffer[1]) { - case MARKER_COMMENT: required_length = 6; break; - case MARKER_ATMOVE: required_length = 8; break; - case MARKER_NEWLEN: required_length = 6; break; - case MARKER_ABORT: - case MARKER_SDNORM: - case MARKER_SDRST: required_length = 2; break; - case MARKER_STUFF: - /* forward stuffed 0xff to arithmetic decoder */ - s->buf_len = 0; - decode_pscd(s, s->buffer, 2); - continue; - default: - return JBG_EMARKER; - } - while (s->buf_len < required_length && *cnt < len) - s->buffer[s->buf_len++] = data[(*cnt)++]; - if (s->buf_len < required_length) continue; - /* now the buffer is filled with exactly one marker segment */ - switch (s->buffer[1]) { - case MARKER_COMMENT: - s->comment_skip = - (((long) s->buffer[2] << 24) | ((long) s->buffer[3] << 16) | - ((long) s->buffer[4] << 8) | (long) s->buffer[5]); - break; - case MARKER_ATMOVE: - if (s->at_moves < JBG_ATMOVES_MAX) { - s->at_line[s->at_moves] = - (((long) s->buffer[2] << 24) | ((long) s->buffer[3] << 16) | - ((long) s->buffer[4] << 8) | (long) s->buffer[5]); - s->at_tx[s->at_moves] = (signed char) s->buffer[6]; - s->at_ty[s->at_moves] = s->buffer[7]; - if (s->at_tx[s->at_moves] < - (int) s->mx || - s->at_tx[s->at_moves] > (int) s->mx || - s->at_ty[s->at_moves] > (int) s->my || - (s->at_ty[s->at_moves] == 0 && s->at_tx[s->at_moves] < 0)) - return JBG_EINVAL | 11; - if (s->at_ty[s->at_moves] != 0) - return JBG_EIMPL | 6; - s->at_moves++; - } else - return JBG_EIMPL | 7; /* more than JBG_ATMOVES_MAX ATMOVES */ - break; - case MARKER_NEWLEN: - y = (((long) s->buffer[2] << 24) | ((long) s->buffer[3] << 16) | - ((long) s->buffer[4] << 8) | (long) s->buffer[5]); - if (y > s->yd) return JBG_EINVAL | 12; - if (!(s->options & JBG_VLENGTH)) return JBG_EINVAL | 13; - s->yd = y; - /* calculate again number of stripes that will be required */ - s->stripes = jbg_stripes(s->l0, s->yd, s->d); - break; - case MARKER_ABORT: - return JBG_EABORT; - - case MARKER_SDNORM: - case MARKER_SDRST: - /* decode final pixels based on trailing zero bytes */ - decode_pscd(s, s->buffer, 2); - - arith_decode_init(s->s[s->ii[iindex[s->order & 7][PLANE]]] + - s->ii[iindex[s->order & 7][LAYER]] - s->dl, - s->ii[iindex[s->order & 7][STRIPE]] != s->stripes - 1 - && s->buffer[1] != MARKER_SDRST); - - s->reset[s->ii[iindex[s->order & 7][PLANE]]] - [s->ii[iindex[s->order & 7][LAYER]] - s->dl] = - (s->buffer[1] == MARKER_SDRST); - - /* prepare for next SDE */ - s->x = 0; - s->i = 0; - s->pseudo = 1; - s->at_moves = 0; - - /* increment layer/stripe/plane loop variables */ - /* start and end value for each loop: */ - is[iindex[s->order & 7][STRIPE]] = 0; - ie[iindex[s->order & 7][STRIPE]] = s->stripes - 1; - is[iindex[s->order & 7][LAYER]] = s->dl; - ie[iindex[s->order & 7][LAYER]] = s->d; - is[iindex[s->order & 7][PLANE]] = 0; - ie[iindex[s->order & 7][PLANE]] = s->planes - 1; - i = 2; /* index to innermost loop */ - do { - j = 0; /* carry flag */ - if (++s->ii[i] > ie[i]) { - /* handling overflow of loop variable */ - j = 1; - if (i > 0) - s->ii[i] = is[i]; - } - } while (--i >= 0 && j); - - s->buf_len = 0; - - /* check whether this have been all SDEs */ - if (j) { -#ifdef DEBUG - fprintf(stderr, "This was the final SDE in this BIE, " - "%ld bytes left.\n", (long) (len - *cnt)); -#endif - s->bie_len = 0; - return JBG_EOK; - } - - /* check whether we have to abort because of xmax/ymax */ - if (iindex[s->order & 7][LAYER] == 0 && i < 0) { - /* LAYER is the outermost loop and we have just gone to next layer */ - if (jbg_ceil_half(s->xd, s->d - s->ii[0]) > s->xmax || - jbg_ceil_half(s->yd, s->d - s->ii[0]) > s->ymax) { - s->xmax = 4294967295UL; - s->ymax = 4294967295UL; - return JBG_EOK_INTR; - } - if (s->ii[0] > (unsigned long) s->dmax) { - s->dmax = 256; - return JBG_EOK_INTR; - } - } - - break; - } - s->buf_len = 0; - - } else if (data[*cnt] == MARKER_ESC) - s->buffer[s->buf_len++] = data[(*cnt)++]; - - else { - - /* we have found PSCD bytes */ - *cnt += decode_pscd(s, data + *cnt, len - *cnt); - if (*cnt < len && data[*cnt] != 0xff) { -#ifdef DEBUG - fprintf(stderr, "PSCD was longer than expected, unread bytes " - "%02x %02x %02x %02x ...\n", data[*cnt], data[*cnt+1], - data[*cnt+2], data[*cnt+3]); -#endif - return JBG_EINVAL | 14; - } - - } - } /* of BID processing loop 'while (*cnt < len) ...' */ - - return JBG_EAGAIN; -} - - -/* - * After jbg_dec_in() returned JBG_EOK or JBG_EOK_INTR, you can call this - * function in order to find out the width of the image. Returns 0 if - * there is no image available yet. - */ -unsigned long jbg_dec_getwidth(const struct jbg_dec_state *s) -{ - if (s->d < 0) - return 0; - if (iindex[s->order & 7][LAYER] == 0) { - if (s->ii[0] < 1) - return 0; - else - return jbg_ceil_half(s->xd, s->d - (s->ii[0] - 1)); - } - - return s->xd; -} - - -/* - * After jbg_dec_in() returned JBG_EOK or JBG_EOK_INTR, you can call this - * function in order to find out the height of the image. Returns 0 if - * there is no image available yet. - */ -unsigned long jbg_dec_getheight(const struct jbg_dec_state *s) -{ - if (s->d < 0) - return 0; - if (iindex[s->order & 7][LAYER] == 0) { - if (s->ii[0] < 1) - return 0; - else - return jbg_ceil_half(s->yd, s->d - (s->ii[0] - 1)); - } - - return s->yd; -} - - -/* - * After jbg_dec_in() returned JBG_EOK or JBG_EOK_INTR, you can call this - * function in order to get a pointer to the image. Returns NULL if - * there is no image available yet. - */ -unsigned char *jbg_dec_getimage(const struct jbg_dec_state *s, int plane) -{ - if (s->d < 0) - return NULL; - if (iindex[s->order & 7][LAYER] == 0) { - if (s->ii[0] < 1) - return NULL; - else - return s->lhp[(s->ii[0] - 1) & 1][plane]; - } - - return s->lhp[s->d & 1][plane]; -} - - -/* - * After jbg_dec_in() returned JBG_EOK or JBG_EOK_INTR, you can call - * this function in order to find out the size in bytes of one - * bitplane of the image. - */ -unsigned long jbg_dec_getsize(const struct jbg_dec_state *s) -{ - if (s->d < 0) - return 0; - if (iindex[s->order & 7][LAYER] == 0) { - if (s->ii[0] < 1) - return 0; - else - return - jbg_ceil_half(s->xd, s->d - (s->ii[0] - 1) + 3) * /* overflow risk? */ - jbg_ceil_half(s->yd, s->d - (s->ii[0] - 1)); - } - - return jbg_ceil_half(s->xd, 3) * s->yd; -} - - -/* - * After jbg_dec_in() returned JBG_EOK or JBG_EOK_INTR, you can call - * this function in order to find out the size of the image that you - * can retrieve with jbg_merge_planes(). - */ -unsigned long jbg_dec_getsize_merged(const struct jbg_dec_state *s) -{ - if (s->d < 0) - return 0; - if (iindex[s->order & 7][LAYER] == 0) { - if (s->ii[0] < 1) - return 0; - else - return - jbg_ceil_half(s->xd, s->d - (s->ii[0] - 1)) * /* overflow risk? */ - jbg_ceil_half(s->yd, s->d - (s->ii[0] - 1)) * - ((s->planes + 7) / 8); - } - - return s->xd * s->yd * ((s->planes + 7) / 8); -} - - -/* - * The destructor function which releases any resources obtained by the - * other decoder functions. - */ -void jbg_dec_free(struct jbg_dec_state *s) -{ - int i; - - if (s->d < 0 || s->s == NULL) - return; - s->d = -2; - - for (i = 0; i < s->planes; i++) { - checked_free(s->s[i]); - checked_free(s->tx[i]); - checked_free(s->ty[i]); - checked_free(s->reset[i]); - checked_free(s->lntp[i]); - checked_free(s->lhp[0][i]); - checked_free(s->lhp[1][i]); - } - - checked_free(s->s); - checked_free(s->tx); - checked_free(s->ty); - checked_free(s->reset); - checked_free(s->lntp); - checked_free(s->lhp[0]); - checked_free(s->lhp[1]); - if (s->dppriv && s->dppriv != jbg_dptable) - checked_free(s->dppriv); - - s->s = NULL; - - return; -} - - -/* - * Split bigendian integer pixel field into separate bit planes. In the - * src array, every pixel is represented by a ((has_planes + 7) / 8) byte - * long word, most significant byte first. While has_planes describes - * the number of used bits per pixel in the source image, encode_plane - * is the number of most significant bits among those that we - * actually transfer to dest. - */ -void jbg_split_planes(unsigned long x, unsigned long y, int has_planes, - int encode_planes, - const unsigned char *src, unsigned char **dest, - int use_graycode) -{ - unsigned long bpl = jbg_ceil_half(x, 3); /* bytes per line in dest plane */ - unsigned long line, i; - unsigned k = 8; - int p; - unsigned prev; /* previous *src byte shifted by 8 bit to the left */ - register int bits, msb = has_planes - 1; - int bitno; - - /* sanity checks */ - if (encode_planes > has_planes) - encode_planes = has_planes; - use_graycode = use_graycode != 0 && encode_planes > 1; - - for (p = 0; p < encode_planes; p++) - memset(dest[p], 0, bpl * y); - - for (line = 0; line < y; line++) { /* lines loop */ - for (i = 0; i * 8 < x; i++) { /* dest bytes loop */ - for (k = 0; k < 8 && i * 8 + k < x; k++) { /* pixel loop */ - prev = 0; - for (p = 0; p < encode_planes; p++) { /* bit planes loop */ - /* calculate which bit in *src do we want */ - bitno = (msb - p) & 7; - /* put this bit with its left neighbor right adjusted into bits */ - bits = (prev | *src) >> bitno; - /* go to next *src byte, but keep old */ - if (bitno == 0) - prev = *src++ << 8; - /* make space for inserting new bit */ - dest[p][bpl * line + i] <<= 1; - /* insert bit, if requested apply Gray encoding */ - dest[p][bpl * line + i] |= (bits ^ (use_graycode & (bits>>1))) & 1; - /* - * Theorem: Let b(n),...,b(1),b(0) be the digits of a - * binary word and let g(n),...,g(1),g(0) be the digits of the - * corresponding Gray code word, then g(i) = b(i) xor b(i+1). - */ - } - /* skip unused *src bytes */ - for (;p < has_planes; p++) - if (((msb - p) & 7) == 0) - src++; - } - } - for (p = 0; p < encode_planes; p++) /* right padding loop */ - dest[p][bpl * (line + 1) - 1] <<= 8 - k; - } - - return; -} - -/* - * Merge the separate bit planes decoded by the JBIG decoder into an - * integer pixel field. This is essentially the counterpart to - * jbg_split_planes(). - */ -void jbg_dec_merge_planes(const struct jbg_dec_state *s, int use_graycode, - void (*data_out)(unsigned char *start, size_t len, - void *file), void *file) -{ -#define BUFLEN 4096 - unsigned long bpl, line, i; - unsigned k = 8; - int p; - unsigned char buf[BUFLEN]; - unsigned char *bp = buf; - unsigned char **src; - unsigned long x, y; - unsigned v; - - /* sanity check */ - use_graycode = use_graycode != 0; - - x = jbg_dec_getwidth(s); - y = jbg_dec_getheight(s); - if (x == 0 || y == 0) - return; - bpl = jbg_ceil_half(x, 3); /* bytes per line in src plane */ - - if (iindex[s->order & 7][LAYER] == 0) - if (s->ii[0] < 1) - return; - else - src = s->lhp[(s->ii[0] - 1) & 1]; - else - src = s->lhp[s->d & 1]; - - for (line = 0; line < y; line++) { /* lines loop */ - for (i = 0; i * 8 < x; i++) { /* src bytes loop */ - for (k = 0; k < 8 && i * 8 + k < x; k++) { /* pixel loop */ - v = 0; - for (p = 0; p < s->planes;) { /* dest bytes loop */ - do { - v = (v << 1) | - (((src[p][bpl * line + i] >> (7 - k)) & 1) ^ - (use_graycode & v)); - } while ((s->planes - ++p) & 7); - *bp++ = v; - if (bp - buf == BUFLEN) { - data_out(buf, BUFLEN, file); - bp = buf; - } - } - } - } - } - - if (bp - buf > 0) - data_out(buf, bp - buf, file); - - return; -} - - -/* - * Given a pointer p to the first byte of either a marker segment or a - * PSCD, as well as the length len of the remaining data, return - * either the pointer to the first byte of the next marker segment or - * PSCD, or p+len if this was the last one, or NULL if some error was - * encountered. Possible errors are: - * - * - not enough bytes left for complete marker segment - * - no marker segment terminates the PSCD - * - unknown marker code encountered - * - */ -unsigned char *jbg_next_pscdms(unsigned char *p, size_t len) -{ - unsigned char *pp; - unsigned long l; - - if (len < 2) - return NULL; /* not enough bytes left for complete marker segment */ - - if (p[0] != MARKER_ESC || p[1] == MARKER_STUFF) { - do { - while (p[0] == MARKER_ESC && p[1] == MARKER_STUFF) { - p += 2; - len -= 2; - if (len < 2) - return NULL; /* not enough bytes left for complete marker segment */ - } - assert(len >= 2); - pp = (unsigned char *) memchr(p, MARKER_ESC, len - 1); - if (!pp) - return NULL; /* no marker segment terminates the PSCD */ - l = pp - p; - assert(l < len); - p += l; - len -= l; - } while (p[1] == MARKER_STUFF); - } else { - switch (p[1]) { - case MARKER_SDNORM: - case MARKER_SDRST: - case MARKER_ABORT: - return p + 2; - case MARKER_NEWLEN: - if (len < 6) - return NULL; /* not enough bytes left for complete marker segment */ - return p + 6; - case MARKER_ATMOVE: - if (len < 8) - return NULL; /* not enough bytes left for complete marker segment */ - return p + 8; - case MARKER_COMMENT: - if (len < 6) - return NULL; /* not enough bytes left for complete marker segment */ - l = (((long) p[2] << 24) | ((long) p[3] << 16) | - ((long) p[4] << 8) | (long) p[5]); - if (len - 6 < l) - return NULL; /* not enough bytes left for complete marker segment */ - return p + 6 + l; - default: - /* unknown marker sequence encountered */ - return NULL; - } - } - - return p; -} - - -/* - * Scan a complete BIE for a NEWLEN marker segment, then read the new - * YD value found in it and use it to overwrite the one in the BIE - * header. Use this procedure if a BIE initially declares an - * unreasonably high provisional YD value (e.g., 0xffffffff) or - * depends on the fact that section 6.2.6.2 of ITU-T T.82 says that a - * NEWLEN marker segment "could refer to a line in the immediately - * preceding stripe due to an unexpected termination of the image or - * the use of only such stripe". ITU-T.85 explicitely suggests the - * use of this for fax machines that start transmission before having - * encountered the end of the page. None of this is necessary for - * BIEs produced by JBIG-KIT, which normally does not use NEWLEN. - */ -int jbg_newlen(unsigned char *bie, size_t len) -{ - unsigned char *p = bie + 20; - int i; - unsigned long y, yn; - - if (len < 20) - return JBG_EAGAIN; - if ((bie[19] & (JBG_DPON | JBG_DPPRIV | JBG_DPLAST)) - == (JBG_DPON | JBG_DPPRIV)) - p += 1728; /* skip DPTABLE */ - if (p >= bie + len) - return JBG_EAGAIN; - - while ((p = jbg_next_pscdms(p, len - (p - bie)))) { - if (p == bie + len) - return JBG_EOK; - else if (p[0] == MARKER_ESC) - switch (p[1]) { - case MARKER_NEWLEN: - if (p + 5 >= bie + len) - return JBG_EAGAIN; - y = (((long) bie[ 8] << 24) | ((long) bie[ 9] << 16) | - ((long) bie[10] << 8) | (long) bie[11]); - yn = (((long) p[2] << 24) | ((long) p[3] << 16) | - ((long) p[4] << 8) | (long) p[5]); - if (yn > y) return JBG_EINVAL | 12; - /* overwrite YD in BIH with YD from NEWLEN */ - for (i = 0; i < 4; i++) { - bie[8+i] = p[2+i]; - } - return JBG_EOK; - case MARKER_ABORT: - return JBG_EABORT; - } - } - return JBG_EINVAL | 0; -} diff --git a/thirdparty/jbigkit/libjbig/jbig.h b/thirdparty/jbigkit/libjbig/jbig.h deleted file mode 100644 index 2577399a6..000000000 --- a/thirdparty/jbigkit/libjbig/jbig.h +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Header file for the portable JBIG compression library - * - * Copyright 1995-2014 -- Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/ - */ - -#ifndef JBG_H -#define JBG_H - -#include -#include "jbig_ar.h" - -/* - * JBIG-KIT version number - */ - -#define JBG_VERSION "2.1" -#define JBG_VERSION_MAJOR 2 -#define JBG_VERSION_MINOR 1 - -/* - * JBIG-KIT licence agreement reference code: - * If you use JBIG-KIT under a commercial licence, please replace - * below the letters GPL with the reference code that you received - * with your licence agreement. (This code is typically a letter "A" - * followed by four decimal digits, e.g. "A1234".) - */ - -#define JBG_LICENCE "GPL" - -/* - * Buffer block for SDEs which are temporarily stored by encoder - */ - -#define JBG_BUFSIZE 4000 - -struct jbg_buf { - unsigned char d[JBG_BUFSIZE]; /* one block of a buffer list */ - int len; /* length of the data in this block */ - struct jbg_buf *next; /* pointer to next block */ - struct jbg_buf *previous; /* pointer to previous block * - * (unused in freelist) */ - struct jbg_buf *last; /* only used in list head: final block of list */ - struct jbg_buf **free_list; /* pointer to pointer to head of free list */ -}; - -/* - * Maximum number of ATMOVEs per stripe that decoder can handle - */ - -#define JBG_ATMOVES_MAX 64 - -/* - * Option and order flags - */ - -#define JBG_HITOLO 0x08 -#define JBG_SEQ 0x04 -#define JBG_ILEAVE 0x02 -#define JBG_SMID 0x01 - -#define JBG_LRLTWO 0x40 -#define JBG_VLENGTH 0x20 -#define JBG_TPDON 0x10 -#define JBG_TPBON 0x08 -#define JBG_DPON 0x04 -#define JBG_DPPRIV 0x02 -#define JBG_DPLAST 0x01 - -/* encoding options that will not be indicated in the header */ - -#define JBG_DELAY_AT 0x100 /* Delay ATMOVE until the first line of the next - * stripe. Option available for compatibility - * with conformance test example in clause 7.2. */ - -#define JBG_SDRST 0x200 /* Use SDRST instead of SDNORM. This option is - * there for anyone who needs to generate - * test data that covers the SDRST cases. */ - -/* - * Possible error code return values - */ - -#define JBG_EOK (0 << 4) -#define JBG_EOK_INTR (1 << 4) -#define JBG_EAGAIN (2 << 4) -#define JBG_ENOMEM (3 << 4) -#define JBG_EABORT (4 << 4) -#define JBG_EMARKER (5 << 4) -#define JBG_EINVAL (6 << 4) -#define JBG_EIMPL (7 << 4) -#define JBG_ENOCONT (8 << 4) - -/* - * Status of a JBIG encoder - */ - -struct jbg_enc_state { - int d; /* resolution layer of the input image */ - unsigned long xd, yd; /* size of the input image (resolution layer d) */ - unsigned long yd1; /* BIH announced height of image, use yd1 != yd to - emulate T.85-style NEWLEN height updates for tests */ - int planes; /* number of different bitmap planes */ - int dl; /* lowest resolution layer in the next BIE */ - int dh; /* highest resolution layer in the next BIE */ - unsigned long l0; /* number of lines per stripe at lowest * - * resolution layer 0 */ - unsigned long stripes; /* number of stripes required (determ. by l0) */ - unsigned char **lhp[2]; /* pointers to lower/higher resolution images */ - int *highres; /* index [plane] of highres image in lhp[] */ - int order; /* SDE ordering parameters */ - int options; /* encoding parameters */ - unsigned mx, my; /* maximum ATMOVE window size */ - int *tx; /* array [plane] with x-offset of adaptive template pixel */ - char *dppriv; /* optional private deterministic prediction table */ - char *res_tab; /* table for the resolution reduction algorithm */ - struct jbg_buf ****sde; /* array [stripe][layer][plane] pointers to * - * buffers for stored SDEs */ - struct jbg_arenc_state *s; /* array [planes] for arithm. encoder status */ - struct jbg_buf *free_list; /* list of currently unused SDE block buffers */ - void (*data_out)(unsigned char *start, size_t len, void *file); - /* data write callback */ - void *file; /* parameter passed to data_out() */ - char *tp; /* buffer for temp. values used by diff. typical prediction */ - unsigned char *comment; /* content of comment marker segment to be added - at next opportunity (will be reset to NULL - as soon as comment has been written) */ - unsigned long comment_len; /* length of data pointed to by comment */ -}; - - -/* - * Status of a JBIG decoder - */ - -struct jbg_dec_state { - /* data from BIH */ - int d; /* resolution layer of the full image */ - int dl; /* first resolution layer in this BIE */ - unsigned long xd, yd; /* size of the full image (resolution layer d) */ - int planes; /* number of different bitmap planes */ - unsigned long l0; /* number of lines per stripe at lowest * - * resolution layer 0 */ - unsigned long stripes; /* number of stripes required (determ. by l0) */ - int order; /* SDE ordering parameters */ - int options; /* encoding parameters */ - int mx, my; /* maximum ATMOVE window size */ - char *dppriv; /* optional private deterministic prediction table */ - - /* loop variables */ - unsigned long ii[3]; /* current stripe, layer, plane (outer loop first) */ - - /* - * Pointers to array [planes] of lower/higher resolution images. - * lhp[d & 1] contains image of layer d. - */ - unsigned char **lhp[2]; - - /* status information */ - int **tx, **ty; /* array [plane][layer-dl] with x,y-offset of AT pixel */ - struct jbg_ardec_state **s; /* array [plane][layer-dl] for arithmetic * - * decoder status */ - int **reset; /* array [plane][layer-dl] remembers if previous stripe * - * in that plane/resolution ended with SDRST. */ - unsigned long bie_len; /* number of bytes read so far */ - unsigned char buffer[20]; /* used to store BIH or marker segments fragm. */ - int buf_len; /* number of bytes in buffer */ - unsigned long comment_skip; /* remaining bytes of a COMMENT segment */ - unsigned long x; /* x position of next pixel in current SDE */ - unsigned long i; /* line in current SDE (first line of each stripe is 0) */ - int at_moves; /* number of AT moves in the current stripe */ - unsigned long at_line[JBG_ATMOVES_MAX]; /* lines at which an * - * AT move will happen */ - int at_tx[JBG_ATMOVES_MAX], at_ty[JBG_ATMOVES_MAX]; /* ATMOVE offsets in * - * current stripe */ - unsigned long line_h1, line_h2, line_h3; /* variables of decode_pscd */ - unsigned long line_l1, line_l2, line_l3; - int pseudo; /* flag for TPBON/TPDON: next pixel is pseudo pixel */ - int **lntp; /* flag [plane][layer-dl] for TP: line is not typical */ - - unsigned long xmax, ymax; /* if possible abort before image gets * - * larger than this size */ - int dmax; /* abort after this layer */ - size_t maxmem; /* return JBG_ENOMEM if final image layer D - would require more than maxmem bytes */ -}; - - -/* some macros (too trivial for a function) */ - -#define jbg_dec_getplanes(s) ((s)->planes) - - -/* function prototypes */ - -void jbg_enc_init(struct jbg_enc_state *s, unsigned long x, unsigned long y, - int planes, unsigned char **p, - void (*data_out)(unsigned char *start, size_t len, - void *file), - void *file); -int jbg_enc_lrlmax(struct jbg_enc_state *s, unsigned long mwidth, - unsigned long mheight); -void jbg_enc_layers(struct jbg_enc_state *s, int d); -int jbg_enc_lrange(struct jbg_enc_state *s, int dl, int dh); -void jbg_enc_options(struct jbg_enc_state *s, int order, int options, - unsigned long l0, int mx, int my); -void jbg_enc_out(struct jbg_enc_state *s); -void jbg_enc_free(struct jbg_enc_state *s); - -void jbg_dec_init(struct jbg_dec_state *s); -void jbg_dec_maxsize(struct jbg_dec_state *s, unsigned long xmax, - unsigned long ymax); -int jbg_dec_in(struct jbg_dec_state *s, unsigned char *data, size_t len, - size_t *cnt); -unsigned long jbg_dec_getwidth(const struct jbg_dec_state *s); -unsigned long jbg_dec_getheight(const struct jbg_dec_state *s); -unsigned char *jbg_dec_getimage(const struct jbg_dec_state *s, int plane); -unsigned long jbg_dec_getsize(const struct jbg_dec_state *s); -void jbg_dec_merge_planes(const struct jbg_dec_state *s, int use_graycode, - void (*data_out)(unsigned char *start, size_t len, - void *file), void *file); -unsigned long jbg_dec_getsize_merged(const struct jbg_dec_state *s); -void jbg_dec_free(struct jbg_dec_state *s); - -const char *jbg_strerror(int errnum); -void jbg_int2dppriv(unsigned char *dptable, const char *internal); -void jbg_dppriv2int(char *internal, const unsigned char *dptable); -unsigned long jbg_ceil_half(unsigned long x, int n); -void jbg_split_planes(unsigned long x, unsigned long y, int has_planes, - int encode_planes, - const unsigned char *src, unsigned char **dest, - int use_graycode); -int jbg_newlen(unsigned char *bie, size_t len); - -#endif /* JBG_H */ diff --git a/thirdparty/jbigkit/libjbig/jbig.txt b/thirdparty/jbigkit/libjbig/jbig.txt deleted file mode 100644 index 4547b1234..000000000 --- a/thirdparty/jbigkit/libjbig/jbig.txt +++ /dev/null @@ -1,828 +0,0 @@ - -Using the JBIG-KIT library --------------------------- - -Markus Kuhn -- 2020-08-03 - - -This text explains how to use the functions provided by the JBIG-KIT -portable image compression library jbig.c in your application -software. The jbig.c library is a full-featured implementation of the -JBIG1 standard aimed at applications that can hold the entire -uncompressed and compressed image in RAM. - -[For applications that require only the single-bit-per-pixel "fax -subset" of the JBIG1 standard defined in ITU-T Recommendation T.85 -, the alternative implementation -found in jbig85.c may be preferable. It keeps not more than three -lines of the uncompressed image in RAM, which makes it particularly -suitable for embedded applications. For information on how to use -jbig85.c, please refer to the separate documentation file jbig85.txt.] - - -1 Introduction to JBIG - -We start with a short introduction to JBIG1. More detailed information -is provided in the "Introduction and overview" section of the JBIG1 -standard. Information on how to obtain a copy of the standard is -available from or -. - -Image data encoded with the JBIG algorithm is separated into planes, -layers, and stripes. Each plane contains one bit per pixel. The number -of planes stored in a JBIG data stream is the number of bits per -pixel. Resolution layers are numbered from 0 to D with 0 being the -layer with the lowest resolution and D the one with the highest. Each -next higher resolution layer has twice the number of rows and columns. -Layer 0 is encoded independently of any other data, all other -resolution layers are encoded as only the difference between the next -lower and the current layer. For applications that require very quick -access to parts of an image, it is possible to divide an image into -several horizontal stripes. All stripes of one resolution layer have -equal size, except perhaps the final one. The number of stripes of an -image is equal in all resolution layers and in all bit planes. - -The compressed data stream specified by the JBIG standard is called a -bi-level image entity (BIE). A BIE consists of a 20-byte header, -followed by an optional 1728-byte table (usually not present, except -in special applications) followed by a sequence of stripe data -entities (SDE). Each SDE encodes the content of one single stripe in -one plane of one resolution layer. Between the SDEs, other information -blocks (called floating marker segments) can also be present. They are -used to change certain parameters of the algorithm in the middle of an -image or contain additional application specific information. A BIE -looks like this: - - - +------------------------------------------------+ - | | - | 20-byte header (with image size, #planes, | - | #layers, stripe size, first layer, options, | - | SDE ordering, ...) | - | | - +------------------------------------------------+ - | | - | optional 1728-byte table | - | | - +------------------------------------------------+ - | | - | optional floating marker segments | - | | - +------------------------------------------------+ - | | - | stripe data entity | - | | - +------------------------------------------------+ - | | - | optional floating marker segments | - | | - +------------------------------------------------+ - | | - | stripe data entity | - | | - +------------------------------------------------+ - ... - +------------------------------------------------+ - | | - | stripe data entity | - | | - +------------------------------------------------+ - - -One BIE can contain all resolution layers of an image, but it is also -possible to store various resolution layers in several BIEs. The BIE -header contains the number of the first and the last resolution layer -stored in this BIE, as well as the size of the highest resolution -layer stored in this BIE. Progressive coding is deactivated by simply -storing the image in one single resolution layer. - -Different applications might have different requirements for the order -in which the SDEs for stripes of various planes and layers are stored -in the BIE, so all possible sensible orderings are allowed by the -standard and indicated by four bits in the header. - -It is possible to use the raw BIE data stream as specified by the JBIG -standard directly as the format of a file used for storing images. -This is what the pbmtojbg, jbgtopbm, pbmtojbg85, and jbgtopbm85 -conversion tools do that are provided in this package as demonstration -applications. However, as the BIE format has been designed for a large -number of very different applications, and to allow efficient direct -processing by special JBIG hardware chip implementations, the BIE -header contains only the minimum amount of information absolutely -required by the decompression algorithm. Many features expected from a -good file format are missing in the BIE data stream: - - - no "magic code" in the first few bytes to allow identification - of the file format on a typeless file system and to allow - automatic distinction from other compression algorithms - - - no standardized way to encode additional information such as a - textual description, information about the meaning of various bit - planes, the physical size and resolution of the document, etc. - - - a checksum to ensure image integrity - - - encryption and signature mechanisms - - - many things more - -Raw BIE data streams alone may therefore not be a suitable format for -document archiving and exchange. A standard format for this purpose -would typically combine a BIE representing the image data with an -additional header providing auxiliary information into one file. -Existing established multi-purpose file formats with a rich set of -auxiliary information attributes like TIFF could be extended easily to -also hold JBIG compressed data. - -On the other hand, in e.g. database applications, a BIE might be -stored directly in a binary variable-length field. Auxiliary -information would then be stored in other fields of the same record, -to simplify search operations. - - -2 Compressing an image - -2.1 Format of the source image - -To be processed by the jbig.c encoder, the image has to be present in -memory as separate bitmap planes. Each byte of a bitmap contains eight -pixels, where the most significant bit represents the leftmost of -these. Each line of a bitmap has to be stored in an integral number of -bytes. If the image width is not an integral multiple of eight, then -the final byte has to be padded with zero bits. - -For example the 23x5 pixels large single plane image: - - .XXXXX..XXX...X...XXX.. - .....X..X..X..X..X..... - .....X..XXX...X..X.XXX. - .X...X..X..X..X..X...X. - ..XXX...XXX...X...XXX.. - -is represented by the 15 bytes - - 01111100 11100010 00111000 - 00000100 10010010 01000000 - 00000100 11100010 01011100 - 01000100 10010010 01000100 - 00111000 11100010 00111000 - -or in hexadecimal notation - - 7c e2 38 04 92 40 04 e2 5c 44 92 44 38 e2 38 - -This is the format used in binary PBM files and it can also be handled -directly by the Xlib library of the X Window System. - -As JBIG can also handle images with multiple bit planes, the jbig.c -library functions accept and return always arrays of pointers to -bitmaps with one pointer per plane. - -For single-plane images, the standard recommends that a 0 pixel -represents the background and a 1 pixel represents the foreground -colour of an image, in other words, 0 is white and 1 is black for -scanned paper documents. For images with several bits per pixel, the -JBIG standard makes no recommendations about how various colours should -be encoded. - -For grey-scale images, by using a Gray code instead of a simple binary -weighted representation of the pixel intensity, some increase in -coding efficiency can be reached. - -A Gray code is also a binary representation of integer numbers, but it -has the property that the representations of the integer numbers i and -(i+1) always differ in exactly one bit. For example, the numbers 0 to -7 can be represented in normal binary code and Gray code as in the -following table: - - normal - number binary code Gray code - --------------------------------------- - 0 000 000 - 1 001 001 - 2 010 011 - 3 011 010 - 4 100 110 - 5 101 111 - 6 110 101 - 7 111 100 - -The form of Gray code shown above has the property that the second -half of the code (numbers 4 - 7) is simply the mirrored first half -(numbers 3 - 0) with the first bit set to one. This way, arbitrarily -large Gray codes can be generated quickly by mirroring the above -example and prefixing the first half with zeros and the second half -with ones as often as required. In grey-scale images, it is common -practise to use the all-0 code for black and the all-1 code for white. - -No matter whether a Gray code or a binary code is used for encoding a -pixel intensity in several bit planes, it always makes sense to store -the most significant (leftmost) bit in plane 0, which is transmitted -first. This way, a decoder could increase the precision of the -displayed pixel intensities while data is still being received and the -basic structure of the image will become visible as early as possible -during the transmission. - - -2.2 A simple compression application - -In order to use jbig.c in your application, just link your executable -with both jbig.c and jbig_ar.c. Both are already combined into -libjbig.a by the provided Makefile, so on Unix systems, just add --ljbig and -L. to the command line options of your compiler. On other -systems you will probably have to write a new Makefile. Make sure your -compiler can find the file jbig.h and put the line - - #include "jbig.h" - -into your source code. - -The library interface follows object-oriented programming principles. -You have to declare a variable (object) - - struct jbg_enc_state s; - -which contains the current status of an encoder. Then you initialize -the encoder by calling the constructor function - - void jbg_enc_init(struct jbg_enc_state *s, unsigned long x, unsigned long y, - int pl, unsigned char **p, - void (*data_out)(unsigned char *start, size_t len, - void *file), - void *file); - -The parameters have the following meaning: - - s A pointer to the jbg_enc_state structure that you want - to initialize. - - x The width of your image in pixels. - - y The height of your image in pixels (lines). - - pl the number of bitmap planes you want to encode. - - p A pointer to an array of pl pointers, where each is again - pointing to the first byte of a bitmap as described in - section 2.1. - - data_out This is a call-back function that the encoder will - call during the compression process by in order to - deliver the BIE data to your application. The - parameters of the function data_out are a pointer - start to the new block of data being delivered, as - well as the number len of delivered bytes. The pointer - file is transparently delivered to data_out, as - specified in jbg_enc_init(). Typically, data_out will - write the BIE portion to a file, send it to a network - connection, or append it to some memory buffer. - - file A pointer parameter that is passed on to data_out() - and can be used, for instance, to allow data_out() to - distinguish by which compression task it has been - called in multi-threaded applications. - -In the simplest case, the compression is then started by calling the -function - - void jbg_enc_out(struct jbg_enc_state *s); - -which will deliver the complete BIE to data_out() in several calls. -After jbg_enc_out has returned, a call to the destructor function - - void jbg_enc_free(struct jbg_enc_state *s); - -will release any heap memory allocated by the previous functions. - - -A minimal example application, which sends the BIE of the above bitmap -to stdout, looks like this: - ---------------------------------------------------------------------------- -/* A sample JBIG encoding application */ - -#include -#include "jbig.h" - -void output_bie(unsigned char *start, size_t len, void *file) -{ - fwrite(start, 1, len, (FILE *) file); - - return; -} - -int main() -{ - unsigned char bitmap[15] = { - /* 23 x 5 pixels, "JBIG" */ - 0x7c, 0xe2, 0x38, 0x04, 0x92, 0x40, 0x04, 0xe2, - 0x5c, 0x44, 0x92, 0x44, 0x38, 0xe2, 0x38 - }; - unsigned char *bitmaps[1] = { bitmap }; - struct jbg_enc_state se; - - jbg_enc_init(&se, 23, 5, 1, bitmaps, - output_bie, stdout); /* initialize encoder */ - jbg_enc_out(&se); /* encode image */ - jbg_enc_free(&se); /* release allocated resources */ - - return 0; -} ---------------------------------------------------------------------------- - -This software produces a 42 byte long BIE. (JBIG is not very good at -compressing extremely small images like in this example, because the -arithmetic encoder requires some startup data in order to generate -reasonable statistics which influence the compression process and -because there is some header overhead.) - - -2.3 More about compression - -If jbg_enc_out() is called directly after jbg_enc_init(), the -following default values are used for various compression parameters: - - - Only one single resolution layer is used, i.e. no progressive - mode. - - - The number of lines per stripe is selected so that approximately - 35 stripes per image are used (as recommended in annex C of the - standard together with the suggested adaptive template change - algorithm). However, not less than 2 and not more than 128 lines - are used in order to stay within the suggested minimum parameter - support range specified in annex A of the standard). - - - All optional parts of the JBIG algorithm are activated (TPBON, - TPDON and DPON). - - - The default resolution reduction table and the default deterministic - prediction table are used - - - The maximal vertical offset of the adaptive template pixel is 0 - and the maximal horizontal offset is 8 (mx = 8, my = 0). - -In order to change any of these default parameters, additional -functions have to be called between jbg_enc_init() and jbg_enc_out(). - -In order to activate progressive encoding, it is possible to specify -with - - void jbg_enc_layers(struct jbg_enc_state *s, int d); - -the number d of differential resolution layers which shall be encoded -in addition to the lowest resolution layer 0. For example, if a -document with 60-micrometer pixels has to be stored, and the lowest -resolution layer shall have 240-micrometer pixels, so that a screen -previewer can directly decompress only the required resolution, then a -call - - jbg_enc_layers(&se, 2); - -will cause three layers with 240, 120 and 60 micrometers resolution to -be generated. - -If the application does not know what typical resolutions are used and -simply wants to ensure that the lowest resolution layer will fit into -a given maximal window size, then as an alternative, a call to - - int jbg_enc_lrlmax(struct jbg_enc_state *s, unsigned long mwidth, - unsigned long mheight); - -will cause the library to automatically determine the suitable number -of resolutions so that the lowest resolution layer 0 will not be -larger than mwidth x mheight pixels. E.g. if one wants to ensure that -systems with a 640 x 480 pixel large screen can decode the required -resolution directly, then call - - jbg_enc_lrlmax(&se, 640, 480); - -The return value is the number of differential layers selected. - -After the number of resolution layers has been specified by calls to -jbg_enc_layers() or jbg_enc_lrlmax(), by default, all these layers -will be written into the BIE. This can be changed with a call to - - int jbg_enc_lrange(struct jbg_enc_state *s, int dl, int dh); - -Parameter dl specifies the lowest resolution layer and dh the highest -resolution layer that will appear in the BIE. For instance, if layer 0 -shall be written to the first BIE and layer 1 and 2 shall be written -to a second one, then before writing the first BIE, call - - jbg_enc_lrange(&se, 0, 0); - -and before writing the second BIE with jbg_enc_out(), call - - jbg_enc_lrange(&se, 1, 2); - -If any of the parameters is negative, it will be ignored. The return -value is the total number of differential layers that will represent -the input image. This way, jbg_enc_lrange(&se, -1, -1) can be used to -query the layer of the full image resolution. - -A number of other more exotic options of the JBIG algorithm can be -modified by calling - - void jbg_enc_options(struct jbg_enc_state *s, int order, int options, - long l0, int mx, int my); - -before calling jbg_enc_out(). - -The order parameter can be a combination of the bits JBG_HITOLO, -JBG_SEQ, JBG_ILEAVE and JBG_SMID and it determines in which order -the SDEs are stored in the BIE. The bits have the following meaning: - - JBG_HITOLO Usually, the lower resolution layers are stored before - the higher resolution layers, so that a decoder can - already start to display a low resolution version of - the full image once a prefix of the BIE has been - received. When this bit is set, however, the BIE will - contain the higher layers before the lower layers. This - avoids additional buffer memory in the encoder and is - intended for applications where the encoder is connected - to a database which can easily reorder the SDEs before - sending them to a decoder. Warning: JBIG decoders are - not expected to support the HITOLO option (e.g. the - jbig.c decoder currently does not) so you should - normally not use it. - - JBG_SEQ Usually, at first all stripes of one resolution layer - are written to the BIE and then all stripes of the next - layer, and so on. When the SEQ bit is set however, then - all layers of the first stripe will be written, - followed by all layers of the second stripe, etc. This - option also should normally never be required and is - not supported by the current jbig.c decoder. - - JBG_SMID In case there exist several bit planes, then the order of - the stripes is determined by three loops over all stripes, - all planes and all layers. When SMID is set, the loop - over all stripes is the middle loop. - - JBG_ILEAVE If this bit is set, then at first all layers of one - plane are written before the encoder starts with the next - plane. - -The above description may be somewhat confusing, but the following -table (see also Table 11 in ITU-T T.82) clarifies how the three bits -JBG_SEQ, JBIG_ILEAVE and JBG_SMID influence the ordering of the loops -over all stripes, planes and layers: - - - Loops: - JBG_SEQ JBG_ILEAVE JBG_SMID | Outer Middle Inner - ------------------------------------+--------------------------- - 0 0 0 | p d s - 0 1 0 | d p s - 0 1 1 | d s p - 1 0 0 | s p d - 1 0 1 | p s d - 1 1 0 | s d p - - p: plane, s: stripe, d: layer - - -By default, the order combination JBG_ILEAVE | JBG_SMID is used. - -The options value can contain the following bits, which activate -some of the optional algorithms defined by JBIG: - - JBG_LRLTWO Normally, in the lowest resolution layer, pixels - from three lines around the next pixel are used - in order to determine the context in which the next - pixel is encoded. Some people in the JBIG committee - seem to have argued that using only 2 lines will - make software implementations a little bit faster, - however others have argued that using only two lines - will decrease compression efficiency by around 5%. - As you might expect from a committee, now both - alternatives are allowed and if JBG_LRLTWO is set, - the slightly faster but 5% less well compressing two - line alternative is selected. God bless the committees. - Although probably nobody will ever need this option, - it has been implemented in jbig.c and is off by - default. - - JBG_TPDON This activates the "typical prediction" algorithm - for differential layers which avoids that large - areas of equal colour have to be encoded at all. - This is on by default and there is no good reason to - switch it off except for debugging or preparing data - for cheap JBIG hardware that might not support this - option. - - JBG_TPBON Like JBG_TPDON this activates the "typical prediction" - algorithm in the lowest resolution layer. Also activated - by default. - - JBG_DPON This bit activates for the differential resolution - layers the "deterministic prediction" algorithm, - which avoids that higher resolution layer pixels are - encoded when their value can already be determined - with the knowledge of the neighbour pixels, the - corresponding lower resolution pixels and the - resolution reduction algorithm. This is also - activated by default and one reason for deactivating - it would be if the default resolution reduction - algorithm were replaced by another one. - - JBG_DELAY_AT Use a slightly less efficient algorithm to determine - when an adaptive template change is necessary. With - this bit set, the encoder output is compatible to the - conformance test examples in cause 7.2 of ITU-T T.82. - Then all adaptive template changes are delayed until - the first line of the next stripe. This option is by - default deactivated and is only required for passing a - special compatibility test suite. - -In addition, parameter l0 in jbg_enc_options() allows you to specify -the number of lines per stripe in resolution layer 0. The parameters -mx and my change the maximal offset allowed for the adaptive template -pixel. JBIG-KIT now supports the full range of possible mx values up -to 127 in the encoder and decoder, but my is at the moment ignored and -always set to 0. As the standard requires of all decoder -implementations only to support maximum values mx = 16 and my = 0, -higher values should normally be avoided in order to guarantee -interoperability. The ITU-T T.85 profile for JBIG in fax machines -requires support for mx = 127 and my = 0. Default is mx = 8 and my = -0. If any of the parameters order, options, mx or my is negative, or -l0 is zero, then the corresponding current value remains unmodified. - -The resolution reduction and deterministic prediction tables can also -be replaced. However as these options are anyway only for experts, -please have a look at the source code of jbg_enc_out() and the struct -members dppriv and res_tab of struct jbg_enc_state for the details of -how to do this, in case you really need it. The functions -jbg_int2dppriv and jbg_dppriv2int are provided in order to convert the -DPTABLE data from the format used in the standard into the more -efficient format used internally by JBIG-KIT. - -If you want to encode a grey-scale image, you can use the library -function - - void jbg_split_planes(unsigned long x, unsigned long y, int has_planes, - int encode_planes, - const unsigned char *src, unsigned char **dest, - int use_graycode); - -It separates an image in which each pixel is represented by one or -more bytes into separate bit planes. The dest array of pointers to -these bit planes can then be handed over to jbg_enc_init(). The -variables x and y specify the width and height of the image in pixels, -and has_planes specifies how many bits per pixel are used. As each -pixel is represented by an integral number of consecutive bytes, of -which each contains up to eight bits, the total length of the input -image array src[] will therefore be x * y * ((has_planes + 7) / 8) -bytes. The pixels are stored as usually in English reading order, and -for each pixel the integer value is stored with the most significant -byte coming first (Bigendian). This is exactly the format used in raw -PGM files. In encode_planes, the number of bit planes that shall be -extracted can be specified. This allows for instance to extract only -the most significant 8 bits of a 12-bit image, where each pixel is -represented by two bytes, by specifying has_planes = 12 and -encode_planes = 8. If use_graycode is zero, then the binary code of -the pixel integer values will be used instead of the Gray code. Plane -0 contains always the most significant bit. - - -3 Decompressing an image - -Like with the compression functions, if you want to use the jbig.c -library, you have to put the line - - #include "jbig.h" - -into your source code and link your executable with libjbig.a. - -The state of a JBIG decoder is stored completely in a struct and you -will have to define a variable like - - struct jbg_dec_state sd; - -which is initialized by a call to - - void jbg_dec_init(struct jbg_dec_state *s); - -After this, you can directly start to pass data from the BIE to the decoder -by calling the function - - int jbg_dec_in(struct jbg_dec_state *s, unsigned char *data, size_t len, - size_t *cnt); - -The pointer data points to the first byte of a data block with length -len, which contains bytes from a BIE. It is not necessary to pass a -whole BIE at once to jbg_dec_in(), it can arrive fragmented in any way -by calling jbg_dec_in() several times. It is also possible to send -several BIEs concatenated to jbg_dec_in(), however these then have to -fit together. If you send several BIEs to the decoder, the lowest -resolution layer in each following BIE has to be the highest -resolution layer in the previous BIE plus one and the image sizes and -number of planes also have to fit together, otherwise jbg_dec_in() -will return the error JBG_ENOCONT after the header of the new BIE has -been received completely. - -If pointer cnt is not NULL, then the number of bytes actually read -from the data block will be stored there. In case the data block did -not contain the end of the BIE, then the value JBG_EAGAIN will be -returned and *cnt equals len. - -Once the end of a BIE has been reached, the return value of -jbg_dec_in() will be JBG_EOK. After this has happened, the functions -and macros - - unsigned long jbg_dec_getwidth(struct jbg_dec_state *s); - unsigned long jbg_dec_getheight(struct jbg_dec_state *s); - int jbg_dec_getplanes(struct jbg_dec_state *s); - unsigned char *jbg_dec_getimage(struct jbg_dec_state *s, int plane); - unsigned long jbg_dec_getsize(struct jbg_dec_state *s); - -can be used to query the dimensions of the now completely decoded -image and to get a pointer to all bitmap planes. The bitmaps are -stored as described in section 2.1. The function jbg_dec_getsize() -calculates the number of bytes which one bitmap requires. - -The function - - void jbg_dec_merge_planes(const struct jbg_dec_state *s, int use_graycode, - void (*data_out)(unsigned char *start, size_t len, - void *file), void *file); - -allows you to merge the bit planes that can be accessed individually -with jbg_dec_getimage() into an array with one or more bytes per pixel -(i.e., the format provided to jbg_split_planes()). If use_graycode is -zero, then a binary encoding will be used. The output array will be -delivered via the callback function data_out, exactly in the same way -in which the encoder provides the BIE. The function - - unsigned long jbg_dec_getsize_merged(const struct jbg_dec_state *s); - -determines how long the data array delivered by jbg_dec_merge_planes() -is going to be. - -Before calling jbg_dec_in() the first time, it is possible to specify with -a call to - - void jbg_dec_maxsize(struct jbg_dec_state *s, unsigned long xmax, - unsigned long ymax); - -an abort criterion for progressively encoded images. For instance if an -application will display a whole document on a screen which is 1024 x -768 pixels large, then this application should call - - jbg_dec_maxsize(&sd, 1024, 768); - -before the decoding process starts. If the image has been encoded in -progressive mode (i.e. with several resolution layers), then the -decoder will stop with a return value JBG_EOK_INTR after the largest -resolution layer that is still smaller than 1024 x 768. However this -is no guarantee that the image which can then be read out using -jbg_dec_getimage(), etc. is really not larger than the specified -maximal size. The application will have to check the size of the -image, because the decoder does not automatically apply a resolution -reduction if no suitable resolution layer is available in the BIE. - -If jbg_dec_in() returned JBG_EOK_INTR or JBG_EOK, then it is possible -to continue calling jbg_dec_in() with the remaining data in order to -either decode the remaining resolution layers of the current BIE or in -order to add another BIE with additional resolution layers. In both -cases, after jbg_dec_in() returned JBG_EOK_INTR or JBG_EOK, *cnt is -probably not equal to len and the remainder of the data block which -has not yet been processed by the decoder has to be delivered to -jbg_dec_in() again. - -If any other return value than JBG_EOK, JBG_EOK_INTR or JBG_EAGAIN -has been returned by jbg_dec_in(), then an error has occurred and - - void jbg_dec_free(struct jbg_dec_state *s); - -should be called in order to release any allocated memory. The -destructor jbg_dec_free() should of course also be called, once the -decoded bitmap returned by jbg_dec_getimage() is no longer required -and the memory can be released. - -The function - - const char *jbg_strerror(int errnum); - -returns a pointer to a short single line test message that explains -the return value of jbg_dec_in(). This message can be used in order to -provide the user a brief informative message about what when wrong -while decompressing a JBIG image. The po/ subdirectory contains *.po -files that translate the English ASCII strings returned by -jbg_strerror() into other languages (e.g., for use with GNU gettext). -The four least-significant bits of the return value of jbg_dec_in() -may contain additional detailed technical information about the exact -test that spotted the error condition (see source code for details), -i.e. more than the text message returned by jbg_strerror() reveals. -Therefore it may be useful to display the return value itself as a -hexadecimal number, in addition to the string returned by -jbg_strerror(). - -The current implementation of the jbig.c decoder has the following -limitations: - - - The maximal vertical offset MY of the adaptive template pixel - must be zero. - - - HITOLO and SEQ bits must not be set in the order value. - - - Not more than JBG_ATMOVES_MAX (currently set to 64) ATMOVE - marker segments can be handled per stripe. - - - the number D of differential layers must be less than 32 - -None of the above limitations can be exceeded by a JBIG data stream -that conforms to the ITU-T T.85 application profile for the use of -JBIG1 in fax machines. - -The maximum image size that a BIE header (BIH) can indicate is X_D = -2^32-1 pixels wide, Y_D = 2^32-1 lines high, with P = 255 bits per -pixel. Such an image would, in uncompressed form, require about 588 -exabytes. Once jbg_dec_in() has received the 20-byte long BIH at the -start of the BIE, it will call malloc() to allocate enough memory to -hold the uncompressed image planes. Users may, therefore, want to -defend their application against excessive image-size parameters in a -received BIH, by checking X_D, Y_D, and P against appropriate safety -limits before handing over the BIE header to jbg_dec_in(). BIE headers -indicating too large images might be abused for denial of service -attacks, to exhaust the memory of a system (e.g., CVE-2017-9937). To -manage this risk, the jbig.c decoder will now, by default, return "Not -enough memory available" (JBG_ENOMEM) if the resulting final image -layer would occupy more than 2 gigabytes. Users can adjust this limit -by changing sd->maxmem right after having called jbg_dec_init(&sd). -The actual amount of memory allocated with malloc() calls during the -decoding process is somewhat higher (at least 25%) than the limit set -in sd->maxmem, as the decoder requires additional heap memory that -depends on the image dimensions. - -The jbg_dec_in() function will return "Input data stream uses -unimplemented JBIG features" (JBG_EIMPL | 1) if Y_D equals 0xffffffff, -which is an extreme value commonly used to encode images according to -ITU-T T.85 where the height was unknown when the BIH was emitted. - -All malloc(), realloc() and free() functions called by jbig.c are -wrapped by the functions checked_malloc(), checked_realloc() and -checked_free(). These simply call abort() when memory allocation -fails. Developpers of embedded systems may want to replace them with -alternative forms of exception handling. - -There are two more limitations of the current implementation of the -jbig.c decoder that might cause problems with processing JBIG data -stream that conform to ITU-T T.85: - - - The jbig.c decoder was designed to operate incrementally. - Each received byte is processed immediately as soon as it arrives. - As a result, it does not look beyond the SDRST/SDNORM at the end - of all stripes for any immediately following NEWLEN marker that - might reduce the number of lines encoded by the current stripe. - However section 6.2.6.2 of ITU-T T.82 says that a NEWLEN marker - segment "could refer to a line in the immediately preceding stripe - due to an unexpected termination of the image or the use of only - such stripe", and ITU-T.85 explicitly suggests the use of this - for fax machines that start transmission before having encountered - the end of the page. - - - The image size initially indicated in the BIE header is used to - allocate memory for a bitmap of this size. This means that BIEs - that set initially Y_D = 0xffffffff (as suggested in ITU-T T.85 - for fax machines that do not know the height of the page at the - start of the transmission) cannot be decoded directly by this - version. - -For both issues, there is a workaround available: - -If you encounter a BIE that has in the header the VLENGTH=1 option bit -set, then first wait until you have received the entire BIE and stored -it in memory. Then call the function - - int jbg_newlen(unsigned char *bie, size_t len); - -where bie is a pointer to the first byte of the BIE and len its length -in bytes. This function will scan the entire BIE for the first NEWLEN -marker segment. It will then take the updated image-height value YD -from it and use it to overwrite the YD value in the BIE header. The -jbg_newlen() can return some of the same error codes as jbg_dec_in(), -namely JBG_EOK if everything went fine, JBG_EAGAIN is the data -provided is too short to be a valid BIE, JBG_EINVAL if a format error -was encountered, and JBG_EABORT if an ABORT marker segment was found. -After having patched the image-height value in the BIE using -jbg_newlen(), simply hand over the BIE as usual to jbg_dec_in(). - -In general, for applications where NEWLEN markers can appear, in -particular fax reception, you should consider using the jbig85.c -decoder instead, as it can process BIEs with NEWLEN markers in a -single pass. - -A more detailed description of the JBIG-KIT implementation is - - Markus Kuhn: Effiziente Kompression von bi-level Bilddaten durch - kontextsensitive arithmetische Codierung. Studienarbeit, Lehrstuhl - für Betriebssysteme, IMMD IV, Universität Erlangen-Nürnberg, - Erlangen, July 1995. (German, 62 pages) - - -Please quote the above if you use JBIG-KIT in your research project. - -*** Happy compressing *** - -[end] diff --git a/thirdparty/jbigkit/libjbig/jbig85.c b/thirdparty/jbigkit/libjbig/jbig85.c deleted file mode 100644 index 924b51140..000000000 --- a/thirdparty/jbigkit/libjbig/jbig85.c +++ /dev/null @@ -1,1091 +0,0 @@ -/* - * T.85 "light" version of the portable JBIG image compression library - * - * Copyright 1995-2014 -- Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/ - * - * This module implements a portable standard C encoder and decoder - * using the JBIG1 lossless bi-level image compression algorithm - * specified in International Standard ISO 11544:1993 and - * ITU-T Recommendation T.82. See the file jbig.txt for usage - * instructions and application examples. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * If you want to use this program under different license conditions, - * then contact the author for an arrangement. - */ - -#ifdef DEBUG -#include -#else -#define NDEBUG -#endif - -#include -#include -#include - -#include "jbig85.h" - -#define TPB2CX 0x195 /* contexts for TP special pixels */ -#define TPB3CX 0x0e5 - -/* marker codes */ -#define MARKER_STUFF 0x00 -#define MARKER_RESERVE 0x01 -#define MARKER_SDNORM 0x02 -#define MARKER_SDRST 0x03 -#define MARKER_ABORT 0x04 -#define MARKER_NEWLEN 0x05 -#define MARKER_ATMOVE 0x06 -#define MARKER_COMMENT 0x07 -#define MARKER_ESC 0xff - -/* object code version id */ - -const char jbg85_version[] = - "JBIG-KIT " JBG85_VERSION " (T.85 version) -- (c) 1995-2014 Markus Kuhn -- " - "Licence: " JBG85_LICENCE "\n"; - -#define _(String) String /* to mark translatable string for GNU gettext */ - -/* - * Array with English ASCII error messages that correspond - * to return values from public functions in this library. - */ -static const char *errmsg[] = { - _("All OK"), /* JBG_EOK */ - _("Reached specified image size"), /* JBG_EOK_INTR */ - _("Unexpected end of input data stream"), /* JBG_EAGAIN */ - _("Not enough memory available"), /* JBG_ENOMEM */ - _("ABORT marker segment encountered"), /* JBG_EABORT */ - _("Unknown marker segment encountered"), /* JBG_EMARKER */ - _("Input data stream contains invalid data"), /* JBG_EINVAL */ - _("Input data stream uses unimplemented JBIG features") /* JBG_EIMPL */ -}; - - -/* - * Callback adapter function for arithmetic encoder - */ -static void enc_byte_out(int byte, void *s) -{ - unsigned char c = byte; - ((struct jbg85_enc_state *)s)->data_out(&c, sizeof(unsigned char), - ((struct jbg85_enc_state *)s)->file); -} - - -/* - * Initialize the status struct for the encoder. - */ -void jbg85_enc_init(struct jbg85_enc_state *s, - unsigned long x0, unsigned long y0, - void (*data_out)(unsigned char *start, size_t len, - void *file), - void *file) -{ - assert(x0 > 0 && y0 > 0); - s->x0 = x0; - s->y0 = y0; - s->newlen = 0; /* no NEWLEN pending or output */ - s->data_out = data_out; - s->file = file; - - s->l0 = s->y0 / 35; /* 35 stripes/image suggested default */ - if (s->l0 > 128) s->l0 = 128; - else if (s->l0 < 2) s->l0 = 2; -#if 1 - s->l0 = 128; /* T.85 BASIC setting */ -#endif - s->mx = 127; - s->new_tx = -1; /* no ATMOVE pending */ - s->tx = 0; - s->options = JBG_TPBON | JBG_VLENGTH; - s->comment = NULL; /* no COMMENT pending */ - s->y = 0; - s->i = 0; - s->ltp_old = 0; - - /* initialize arithmetic encoder */ - arith_encode_init(&s->s, 0); - s->s.byte_out = &enc_byte_out; - s->s.file = s; - - return; -} - - -/* - * The following function allows to specify the bits describing the - * options of the format as well as the maximum AT movement window and - * the number of layer 0 lines per stripes. - */ -void jbg85_enc_options(struct jbg85_enc_state *s, int options, - unsigned long l0, int mx) -{ - if (s->y > 0) return; /* too late to change anything now */ - - if (options >= 0) s->options = options; - if (l0 > 0) s->l0 = l0; - if (mx >= 0 && mx < 128) s->mx = mx; - - return; -} - - -/* auxiliary routine to write out NEWLEN */ -static void output_newlen(struct jbg85_enc_state *s) -{ - unsigned char buf[6]; - - assert(s->i == 0); - if (s->newlen != 1) - return; - buf[0] = MARKER_ESC; - buf[1] = MARKER_NEWLEN; - buf[2] = s->y0 >> 24; - buf[3] = (s->y0 >> 16) & 0xff; - buf[4] = (s->y0 >> 8) & 0xff; - buf[5] = s->y0 & 0xff; - s->data_out(buf, 6, s->file); - s->newlen = 2; - if (s->y == s->y0) { - /* if newlen refers to a line in the preceeding stripe, ITU-T T.82 - * section 6.2.6.2 requires us to append another SDNORM */ - buf[1] = MARKER_SDNORM; - s->data_out(buf, 2, s->file); - } -} - - -/* - * Encode one full BIE and pass the generated data to the specified - * call-back function - */ -void jbg85_enc_lineout(struct jbg85_enc_state *s, unsigned char *line, - unsigned char *prevline, unsigned char *prevprevline) -{ - unsigned char buf[20]; - unsigned long bpl; - unsigned char *hp1, *hp2, *hp3, *p1, *q1; - unsigned long line_h1 = 0, line_h2, line_h3; - unsigned long j; /* loop variable for pixel column */ - long o; - unsigned a, p, t; - int ltp; - unsigned long cmin, cmax, clmin, clmax; - int tmax; -#ifdef DEBUG - static long tp_lines; - static long encoded_pixels; -#endif - - if (s->y >= s->y0) { - /* we have already output the full image, go away */ - return; - } - - /* line 0 has no previous line */ - if (s->y < 1) - prevline = NULL; - if (s->y < 2) - prevprevline = NULL; - - /* things that need to be done before the first line is encoded */ - if (s->y == 0) { - /* prepare BIH */ - buf[0] = 0; /* DL = initial layer to be transmitted */ - buf[1] = 0; /* D = number of differential layers */ - buf[2] = 1; /* P = number of bit planes */ - buf[3] = 0; - buf[4] = s->x0 >> 24; - buf[5] = (s->x0 >> 16) & 0xff; - buf[6] = (s->x0 >> 8) & 0xff; - buf[7] = s->x0 & 0xff; - buf[8] = s->y0 >> 24; - buf[9] = (s->y0 >> 16) & 0xff; - buf[10] = (s->y0 >> 8) & 0xff; - buf[11] = s->y0 & 0xff; - buf[12] = s->l0 >> 24; - buf[13] = (s->l0 >> 16) & 0xff; - buf[14] = (s->l0 >> 8) & 0xff; - buf[15] = s->l0 & 0xff; - buf[16] = s->mx; - buf[17] = 0; /* MY = maximum vertical offset allowed for AT pixel */ - buf[18] = 0; /* order: HITOLO = SEQ = ILEAVE = SMID = 0 */ - buf[19] = s->options & (JBG_LRLTWO | JBG_VLENGTH | JBG_TPBON); - - /* output BIH */ - s->data_out(buf, 20, s->file); - } - - /* things that need to be done before the next SDE is encoded */ - if (s->i == 0) { - - /* output NEWLEN if there is any pending */ - output_newlen(s); - - /* output comment marker segment if there is any pending */ - if (s->comment) { - buf[0] = MARKER_ESC; - buf[1] = MARKER_COMMENT; - buf[2] = s->comment_len >> 24; - buf[3] = (s->comment_len >> 16) & 0xff; - buf[4] = (s->comment_len >> 8) & 0xff; - buf[5] = s->comment_len & 0xff; - s->data_out(buf, 6, s->file); - s->data_out(s->comment, s->comment_len, s->file); - s->comment = NULL; - } - - /* output ATMOVE if there is any pending */ - if (s->new_tx != -1 && s->new_tx != s->tx) { - s->tx = s->new_tx; - buf[0] = MARKER_ESC; - buf[1] = MARKER_ATMOVE; - buf[2] = 0; - buf[3] = 0; - buf[4] = 0; - buf[5] = 0; - buf[6] = s->tx; - buf[7] = 0; - s->data_out(buf, 8, s->file); - } - - /* initialize adaptive template movement algorithm */ - if (s->mx == 0) { - s->new_tx = 0; /* ATMOVE has been disabled */ - } else { - s->c_all = 0; - for (t = 0; t <= s->mx; t++) - s->c[t] = 0; - s->new_tx = -1; /* we have yet to determine ATMOVE ... */ - } - - /* restart arithmetic encoder */ - arith_encode_init(&s->s, 1); - } - -#ifdef DEBUG - if (s->y == 0) - tp_lines = encoded_pixels = 0; - fprintf(stderr, "encode line %lu (%2lu of stripe)\n", s->y, s->i); -#endif - - /* bytes per line */ - bpl = (s->x0 >> 3) + !!(s->x0 & 7); - /* ensure correct zero padding of bitmap at the final byte of each line */ - if (s->x0 & 7) { - line[bpl - 1] &= ~((1 << (8 - (s->x0 & 7))) - 1); - } - - /* typical prediction */ - ltp = 0; - if (s->options & JBG_TPBON) { - p1 = line; - q1 = prevline; - ltp = 1; - if (q1) - while (p1 < line + bpl && (ltp = (*p1++ == *q1++)) != 0) ; - else - while (p1 < line + bpl && (ltp = (*p1++ == 0 )) != 0) ; - arith_encode(&s->s, (s->options & JBG_LRLTWO) ? TPB2CX : TPB3CX, - ltp == s->ltp_old); -#ifdef DEBUG - tp_lines += ltp; -#endif - s->ltp_old = ltp; - } - - if (!ltp) { - - /* - * Layout of the variables line_h1, line_h2, line_h3, which contain - * as bits the neighbour pixels of the currently coded pixel X: - * - * 76543210765432107654321076543210 line_h3 - * 76543210765432107654321076543210 line_h2 - * 76543210765432107654321X76543210 line_h1 - */ - - /* pointer to first image byte of the three lines of interest */ - hp3 = prevprevline; - hp2 = prevline; - hp1 = line; - - line_h1 = line_h2 = line_h3 = 0; - if (hp2) line_h2 = (long)*hp2 << 8; - if (hp3) line_h3 = (long)*hp3 << 8; - - /* encode line */ - for (j = 0; j < s->x0;) { - line_h1 |= *hp1; - if (j < bpl * 8 - 8 && hp2) { - line_h2 |= *(hp2 + 1); - if (hp3) - line_h3 |= *(hp3 + 1); - } - if (s->options & JBG_LRLTWO) { - /* two line template */ - do { - line_h1 <<= 1; line_h2 <<= 1; line_h3 <<= 1; - if (s->tx) { - if ((unsigned) s->tx > j) - a = 0; - else { - o = (j - s->tx) - (j & ~7L); - a = (hp1[o >> 3] >> (7 - (o & 7))) & 1; - a <<= 4; - } - assert(s->tx > 23 || - a == ((line_h1 >> (4 + s->tx)) & 0x010)); - arith_encode(&s->s, (((line_h2 >> 10) & 0x3e0) | a | - ((line_h1 >> 9) & 0x00f)), - (line_h1 >> 8) & 1); - } - else - arith_encode(&s->s, (((line_h2 >> 10) & 0x3f0) | - ((line_h1 >> 9) & 0x00f)), - (line_h1 >> 8) & 1); -#ifdef DEBUG - encoded_pixels++; -#endif - /* statistics for adaptive template changes */ - if (s->new_tx == -1 && j >= s->mx && j < s->x0 - 2) { - p = (line_h1 & 0x100) != 0; /* current pixel value */ - s->c[0] += ((line_h2 & 0x4000) != 0) == p; /* default position */ - assert(!(((line_h2 >> 6) ^ line_h1) & 0x100) == - (((line_h2 & 0x4000) != 0) == p)); - for (t = 5; t <= s->mx && t <= j; t++) { - o = (j - t) - (j & ~7L); - a = (hp1[o >> 3] >> (7 - (o & 7))) & 1; - assert(t > 23 || - (a == p) == !(((line_h1 >> t) ^ line_h1) & 0x100)); - s->c[t] += a == p; - } - for (; t <= s->mx; t++) { - s->c[t] += 0 == p; - } - ++s->c_all; - } - } while (++j & 7 && j < s->x0); - } else { - /* three line template */ - do { - line_h1 <<= 1; line_h2 <<= 1; line_h3 <<= 1; - if (s->tx) { - if ((unsigned) s->tx > j) - a = 0; - else { - o = (j - s->tx) - (j & ~7L); - a = (hp1[o >> 3] >> (7 - (o & 7))) & 1; - a <<= 2; - } - assert(s->tx > 23 || - a == ((line_h1 >> (6 + s->tx)) & 0x004)); - arith_encode(&s->s, (((line_h3 >> 8) & 0x380) | - ((line_h2 >> 12) & 0x078) | a | - ((line_h1 >> 9) & 0x003)), - (line_h1 >> 8) & 1); - } else - arith_encode(&s->s, (((line_h3 >> 8) & 0x380) | - ((line_h2 >> 12) & 0x07c) | - ((line_h1 >> 9) & 0x003)), - (line_h1 >> 8) & 1); -#ifdef DEBUG - encoded_pixels++; -#endif - /* statistics for adaptive template changes */ - if (s->new_tx == -1 && j >= s->mx && j < s->x0 - 2) { - p = (line_h1 & 0x100) != 0; /* current pixel value */ - s->c[0] += ((line_h2 & 0x4000) != 0) == p; /* default position */ - assert(!(((line_h2 >> 6) ^ line_h1) & 0x100) == - (((line_h2 & 0x4000) != 0) == p)); - for (t = 3; t <= s->mx && t <= j; t++) { - o = (j - t) - (j & ~7L); - a = (hp1[o >> 3] >> (7 - (o & 7))) & 1; - assert(t > 23 || - (a == p) == !(((line_h1 >> t) ^ line_h1) & 0x100)); - s->c[t] += a == p; - } - for (; t <= s->mx; t++) { - s->c[t] += 0 == p; - } - ++s->c_all; - } - } while (++j & 7 && j < s->x0); - } /* if (s->options & JBG_LRLTWO) */ - hp1++; - if (hp2) hp2++; - if (hp3) hp3++; - } /* for (j = ...) */ - } /* if (!ltp) */ - - /* line is complete now, deal with end of stripe */ - s->i++; s->y++; - if (s->i == s->l0 || s->y == s->y0) { - /* end of stripe reached */ - arith_encode_flush(&s->s); - buf[0] = MARKER_ESC; - buf[1] = MARKER_SDNORM; - s->data_out(buf, 2, s->file); - s->i = 0; - - /* output NEWLEN if there is any pending */ - output_newlen(s); - } - - /* check whether it is worth to perform an ATMOVE */ - if (s->new_tx == -1 && s->c_all > 2048) { - cmin = clmin = 0xffffffffL; - cmax = clmax = 0; - tmax = 0; - for (t = (s->options & JBG_LRLTWO) ? 5 : 3; t <= s->mx; t++) { - if (s->c[t] > cmax) cmax = s->c[t]; - if (s->c[t] < cmin) cmin = s->c[t]; - if (s->c[t] > s->c[tmax]) tmax = t; - } - clmin = (s->c[0] < cmin) ? s->c[0] : cmin; - clmax = (s->c[0] > cmax) ? s->c[0] : cmax; - if (s->c_all - cmax < (s->c_all >> 3) && - cmax - s->c[s->tx] > s->c_all - cmax && - cmax - s->c[s->tx] > (s->c_all >> 4) && - /* ^ T.82 said < here, fixed in Cor.1/25 */ - cmax - (s->c_all - s->c[s->tx]) > s->c_all - cmax && - cmax - (s->c_all - s->c[s->tx]) > (s->c_all >> 4) && - cmax - cmin > (s->c_all >> 2) && - (s->tx || clmax - clmin > (s->c_all >> 3))) { - /* we have decided to perform an ATMOVE */ - s->new_tx = tmax; -#ifdef DEBUG - fprintf(stderr, "ATMOVE: tx=%d, c_all=%lu\n", - s->new_tx, s->c_all); -#endif - } else { - s->new_tx = s->tx; /* we have decided not to perform an ATMOVE */ - } - } - assert(s->tx >= 0); /* i.e., tx can safely be cast to unsigned */ - -#ifdef DEBUG - if (s->y == s->y0) - fprintf(stderr, "tp_lines = %ld, encoded_pixels = %ld\n", - tp_lines, encoded_pixels); -#endif - - return; -} - - -/* - * Inform encoder about new (reduced) height of image - */ -void jbg85_enc_newlen(struct jbg85_enc_state *s, unsigned long newlen) -{ - unsigned char buf[6]; - - if (s->newlen == 2 || newlen >= s->y0 || newlen < 1 || - !(s->options & JBG_VLENGTH)) { - /* invalid invocation or parameter */ - return; - } - if (newlen < s->y) { - /* we are already beyond the new end, therefore move the new end */ - newlen = s->y; - } - if (s->y > 0 && s->y0 != newlen) - s->newlen = 1; - s->y0 = newlen; - if (s->y == s->y0) { - /* we are already at the end; finish the current stripe if necessary */ - if (s->i > 0) { - arith_encode_flush(&s->s); - buf[0] = MARKER_ESC; - buf[1] = MARKER_SDNORM; - s->data_out(buf, 2, s->file); - s->i = 0; - } - /* output NEWLEN if there is any pending */ - output_newlen(s); - } -} - - -/* - * Abort encoding process immediately by outputting an ABORT marker segment - */ -void jbg85_enc_abort(struct jbg85_enc_state *s) -{ - unsigned char buf[2]; - - buf[0] = MARKER_ESC; - buf[1] = MARKER_ABORT; - s->data_out(buf, 2, s->file); - s->y = s->y0; /* just to prevent further calls to jbg85_enc_lineout() */ -} - - -/* - * Convert the error codes used by jbg85_dec_in() into an English ASCII string - */ -const char *jbg85_strerror(int errnum) -{ - errnum >>= 4; - if (errnum < 0 || (unsigned) errnum >= sizeof(errmsg)/sizeof(errmsg[0])) - return "Unknown error code passed to jbg85_strerror()"; - - return errmsg[errnum]; -} - - -/* - * The constructor for a decoder - */ -void jbg85_dec_init(struct jbg85_dec_state *s, - unsigned char *buf, size_t buflen, - int (*line_out)(const struct jbg85_dec_state *s, - unsigned char *start, size_t len, - unsigned long y, void *file), - void *file) -{ - s->x0 = 0; - s->y0 = 0; - s->linebuf = buf; - s->linebuf_len = buflen; - s->line_out = line_out; - s->file = file; - s->bie_len = 0; - s->end_of_bie = 0; - s->x = 0; - s->y = 0; - s->i = 0; - s->comment_skip = 0; - s->buf_len = 0; - s->pseudo = 1; - s->at_moves = 0; - s->tx = 0; - s->lntp = 1; - s->p[0] = 0; - s->p[1] = -1; - s->p[2] = -1; - arith_decode_init(&s->s, 0); - return; -} - - -/* - * Decode the new len PSCD bytes to which data points and output - * decoded lines as they are completed. Return the number of bytes - * which have actually been read. This will be less than len if a - * marker segment was part of the data or if the final byte was - * 0xff, meaning that this code can not determine whether we have a - * marker segment. - */ -static size_t decode_pscd(struct jbg85_dec_state *s, unsigned char *data, - size_t len) -{ - unsigned char *hp1, *hp2, *hp3, *p1; - register unsigned long line_h1, line_h2, line_h3; - unsigned long x; - long o; - unsigned a; - int n; - int pix, slntp; - int buflines = 3 - !!(s->options & JBG_LRLTWO); - - /* forward data to arithmetic decoder */ - s->s.pscd_ptr = data; - s->s.pscd_end = data + len; - - /* restore a few local variables */ - line_h1 = s->line_h1; - line_h2 = s->line_h2; - line_h3 = s->line_h3; - x = s->x; - -#ifdef DEBUG - if (x == 0 && s->i == 0 && s->pseudo) - fprintf(stderr, "decode_pscd(%p, %p, %ld)\n", - (void *) s, (void *) data, (long) len); -#endif - - s->intr = 0; - for (; s->i < s->l0 && s->y < s->y0 && !s->intr; s->i++, s->y++) { - - /* pointer to image byte */ - hp1 = s->linebuf + s->p[0] * s->bpl + (x >> 3); - hp2 = s->linebuf + s->p[1] * s->bpl + (x >> 3); - hp3 = s->linebuf + s->p[2] * s->bpl + (x >> 3); - - /* adaptive template changes */ - if (x == 0 && s->pseudo) - for (n = 0; n < s->at_moves; n++) - if (s->at_line[n] == s->i) { - s->tx = s->at_tx[n]; -#ifdef DEBUG - fprintf(stderr, "ATMOVE: line=%lu, tx=%d.\n", s->i, s->tx); -#endif - } - assert(s->tx >= 0); /* i.e., tx can safely be cast to unsigned */ - - /* typical prediction */ - if (s->options & JBG_TPBON && s->pseudo) { - slntp = arith_decode(&s->s, (s->options & JBG_LRLTWO) ? TPB2CX : TPB3CX); - if (slntp < 0) - goto leave; - s->lntp = - !(slntp ^ s->lntp); - if (!s->lntp) { - /* this line is 'typical' (i.e. identical to the previous one) */ - if (s->p[1] < 0) { - /* first line of page or (following SDRST) of stripe */ - for (p1 = hp1; p1 < hp1 + s->bpl; *p1++ = 0) ; - s->intr = s->line_out(s, hp1, s->bpl, s->y, s->file); - /* rotate the ring buffer that holds the last three lines */ - s->p[2] = s->p[1]; - s->p[1] = s->p[0]; - if (++(s->p[0]) >= buflines) s->p[0] = 0; - } else { - s->intr = s->line_out(s, hp2, s->bpl, s->y, s->file); - /* duplicate the last line in the ring buffer */ - s->p[2] = s->p[1]; - } - continue; - } - /* this line is 'not typical' and has to be coded completely */ - } - s->pseudo = 0; - - /* - * Layout of the variables line_h1, line_h2, line_h3, which contain - * as bits the neighbour pixels of the currently decoded pixel X: - * - * 76543210 76543210 76543210 76543210 line_h3 - * 76543210 76543210 76543210 76543210 line_h2 - * 76543210 76543210 76543210 76543210 X line_h1 - */ - - if (x == 0) { - line_h1 = line_h2 = line_h3 = 0; - if (s->p[1] >= 0) - line_h2 = (long)*hp2 << 8; - if (s->p[2] >= 0) - line_h3 = (long)*hp3 << 8; - } - - /* decode line */ - while (x < s->x0) { - if ((x & 7) == 0) { - if (x < (s->bpl - 1) * 8 && s->p[1] >= 0) { - line_h2 |= *(hp2 + 1); - if (s->p[2] >= 0) - line_h3 |= *(hp3 + 1); - } - } - if (s->options & JBG_LRLTWO) { - /* two line template */ - do { - if (s->tx) { - if ((unsigned) s->tx > x) - a = 0; - else if (s->tx < 8) - a = ((line_h1 >> (s->tx - 5)) & 0x010); - else { - o = (x - s->tx) - (x & ~7L); - a = (hp1[o >> 3] >> (7 - (o & 7))) & 1; - a <<= 4; - } - assert(s->tx > 31 || - a == ((line_h1 >> (s->tx - 5)) & 0x010)); - pix = arith_decode(&s->s, (((line_h2 >> 9) & 0x3e0) | a | - (line_h1 & 0x00f))); - } else - pix = arith_decode(&s->s, (((line_h2 >> 9) & 0x3f0) | - (line_h1 & 0x00f))); - if (pix < 0) - goto leave; - line_h1 = (line_h1 << 1) | pix; - line_h2 <<= 1; - } while ((++x & 7) && x < s->x0); - } else { - /* three line template */ - do { - if (s->tx) { - if ((unsigned) s->tx > x) - a = 0; - else if (s->tx < 8) - a = ((line_h1 >> (s->tx - 3)) & 0x004); - else { - o = (x - s->tx) - (x & ~7L); - a = (hp1[o >> 3] >> (7 - (o & 7))) & 1; - a <<= 2; - } - assert(s->tx > 31 || - a == ((line_h1 >> (s->tx - 3)) & 0x004)); - pix = arith_decode(&s->s, (((line_h3 >> 7) & 0x380) | - ((line_h2 >> 11) & 0x078) | a | - (line_h1 & 0x003))); - } else - pix = arith_decode(&s->s, (((line_h3 >> 7) & 0x380) | - ((line_h2 >> 11) & 0x07c) | - (line_h1 & 0x003))); - if (pix < 0) - goto leave; - line_h1 = (line_h1 << 1) | pix; - line_h2 <<= 1; - line_h3 <<= 1; - } while ((++x & 7) && x < s->x0); - } /* if (s->options & JBG_LRLTWO) */ - *hp1++ = line_h1; - hp2++; - hp3++; - } /* while (x < s->x0) */ - *(hp1 - 1) <<= s->bpl * 8 - s->x0; - s->intr = s->line_out(s, s->linebuf + s->p[0] * s->bpl, - s->bpl, s->y, s->file); - x = 0; - s->pseudo = 1; - /* rotate the ring buffer that holds the last three lines */ - s->p[2] = s->p[1]; - s->p[1] = s->p[0]; - if (++(s->p[0]) >= buflines) s->p[0] = 0; - } /* for (i = ...) */ - - leave: - - /* save a few local variables */ - s->line_h1 = line_h1; - s->line_h2 = line_h2; - s->line_h3 = line_h3; - s->x = x; - - return s->s.pscd_ptr - data; -} - -/* - * Helper routine for processing SDNORM/SDRST marker segment - * (which is found in s->buffer[0..1]) - */ -static int finish_sde(struct jbg85_dec_state *s) -{ - /* decode final pixels based on trailing zero bytes */ - s->s.nopadding = 0; - if (decode_pscd(s, s->buffer, 2) != 2 && s->intr) - return 1; - - /* prepare decoder for next SDE */ - arith_decode_init(&s->s, s->buffer[1] == MARKER_SDNORM); - s->s.nopadding = s->options & JBG_VLENGTH; - - s->x = 0; - s->i = 0; - s->pseudo = 1; - s->at_moves = 0; - if (s->buffer[1] == MARKER_SDRST) { - s->tx = 0; - s->lntp = 1; - s->p[0] = 0; - s->p[1] = -1; - s->p[2] = -1; - } - - return 0; -} - -/* - * Provide to the decoder a new BIE fragment of len bytes starting at data. - * - * Unless cnt is NULL, *cnt will contain the number of actually read bytes - * on return. - * - * Normal return values: - * - * JBG_EAGAIN All data bytes provided so far have been processed - * (*cnt == len) but the end of the data stream has - * not yet been recognized. Call the function again - * with additional BIE bytes. - * JBG_EOK The function has reached the end of the BIE and - * the full image has been decoded. - * JBG_EOK_INTR Parsing the BIE has been interrupted as had been - * requested by a non-zero return value of line_out(). - * This function can be called again with the - * rest of the BIE to continue the decoding process. - * The remaining len - *cnt bytes of the previous - * data block will then have to be passed to this - * function again (only if len > *cnt). - * - * Any other return value indicates that the decoding process was - * aborted by a serious problem and the only function you can then - * still call is jbg85_strerror() to find out what to tell the user. - * (Looking at the least significant bits of the return value will - * provide additional information by identifying which test exactly - * has failed.) - */ -int jbg85_dec_in(struct jbg85_dec_state *s, unsigned char *data, size_t len, - size_t *cnt) -{ - int required_length; - unsigned long y; - size_t dummy_cnt; - - if (!cnt) cnt = &dummy_cnt; - *cnt = 0; - - /* read in 20-byte BIH */ - if (s->bie_len < 20) { - while (s->bie_len < 20 && *cnt < len) - s->buffer[s->bie_len++] = data[(*cnt)++]; - if (s->bie_len < 20) - return JBG_EAGAIN; - /* parse header parameters */ - s->x0 = (((long) s->buffer[ 4] << 24) | ((long) s->buffer[ 5] << 16) | - ((long) s->buffer[ 6] << 8) | (long) s->buffer[ 7]); - s->y0 = (((long) s->buffer[ 8] << 24) | ((long) s->buffer[ 9] << 16) | - ((long) s->buffer[10] << 8) | (long) s->buffer[11]); - s->l0 = (((long) s->buffer[12] << 24) | ((long) s->buffer[13] << 16) | - ((long) s->buffer[14] << 8) | (long) s->buffer[15]); - s->bpl = (s->x0 >> 3) + !!(s->x0 & 7); /* bytes per line */ - s->mx = s->buffer[16]; - s->options = s->buffer[19]; - s->s.nopadding = s->options & JBG_VLENGTH; - /* test whether this looks like a valid JBIG header at all */ - if (s->buffer[1] < s->buffer[0]) return JBG_EINVAL | 1; - /* are padding bits zero as required? */ - if (s->buffer[3] != 0) return JBG_EINVAL | 2; /* padding != 0 */ - if ((s->buffer[18] & 0xf0) != 0) return JBG_EINVAL | 3; /* padding != 0 */ - if ((s->buffer[19] & 0x80) != 0) return JBG_EINVAL | 4; /* padding != 0 */ - if (!s->buffer[2]) return JBG_EINVAL | 5; - if (!s->x0) return JBG_EINVAL | 6; - if (!s->y0) return JBG_EINVAL | 7; - if (!s->l0) return JBG_EINVAL | 8; - if (s->mx > 127) - return JBG_EINVAL | 9; - if (s->buffer[ 0] != 0) return JBG_EIMPL | 8; /* parameter outside T.85 */ - if (s->buffer[ 1] != 0) return JBG_EIMPL | 9; /* parameter outside T.85 */ - if (s->buffer[ 2] != 1) return JBG_EIMPL |10; /* parameter outside T.85 */ - if (s->buffer[17] != 0) return JBG_EIMPL |11; /* parameter outside T.85 */ -#if JBG85_STRICT_ORDER_BITS - if (s->buffer[18] != 0) return JBG_EIMPL |12; /* parameter outside T.85 */ -#endif - if (s->options & 0x17) return JBG_EIMPL |13; /* parameter outside T.85 */ - if (s->x0 > (s->linebuf_len / ((s->options & JBG_LRLTWO) ? 2 : 3)) * 8) - return JBG_ENOMEM; /* provided line buffer is too short */ - } - - /* - * BID processing loop - */ - - while (*cnt < len || s->end_of_bie == 1) { - if (s->end_of_bie == 1) s->end_of_bie = 2; - - /* process floating marker segments */ - - /* skip COMMENT contents */ - if (s->comment_skip) { - if (s->comment_skip <= len - *cnt) { - *cnt += s->comment_skip; - s->comment_skip = 0; - } else { - s->comment_skip -= len - *cnt; - *cnt = len; - } - continue; - } - - /* load marker segments into s->buffer for processing */ - if (s->buf_len > 0) { - assert(s->buffer[0] == MARKER_ESC); - /* load enough bytes to determine length of marker segment */ - while (s->buf_len < 2 && *cnt < len) - s->buffer[s->buf_len++] = data[(*cnt)++]; - if (s->buf_len < 2) continue; - switch (s->buffer[1]) { - case MARKER_COMMENT: required_length = 6; break; - case MARKER_ATMOVE: required_length = 8; break; - case MARKER_NEWLEN: required_length = 6; break; - case MARKER_SDNORM: - case MARKER_SDRST: - if ((s->options & JBG_VLENGTH) && !s->end_of_bie) { - /* peek ahead whether a NEWLEN marker segment follows */ - required_length = 2 + 1; - if (s->buf_len == 2 + 1 && s->buffer[2] == MARKER_ESC) - required_length = 2 + 2; /* SDNORM + 2 marker sequence bytes */ - else if (s->buf_len >= 2 + 2 && s->buffer[3] == MARKER_NEWLEN) - required_length = 2 + 6; /* SDNORM + NEWLEN */ - } else { - /* no further NEWLEN allowed or end of BIE reached */ - required_length = 2; - } - break; - case MARKER_ABORT: - s->buf_len = 0; - return JBG_EABORT; - case MARKER_STUFF: - /* forward stuffed 0xff to arithmetic decoder */ - if (decode_pscd(s, s->buffer, 2) == 2 || !s->intr) - s->buf_len = 0; - if (s->intr) - return JBG_EOK_INTR; /* line_out() requested interrupt */ - continue; - default: - return JBG_EMARKER; - } - /* load minimal number of additional bytes required for processing */ - while (s->buf_len < required_length && *cnt < len) - s->buffer[s->buf_len++] = data[(*cnt)++]; - if (s->buf_len < required_length) continue; - /* now the buffer is filled with exactly one marker segment - * (or in the case of SDNORM/SDRST sometimes also with - * two additional peek-ahead bytes) */ - switch (s->buffer[1]) { - case MARKER_COMMENT: - s->comment_skip = - (((long) s->buffer[2] << 24) | ((long) s->buffer[3] << 16) | - ((long) s->buffer[4] << 8) | (long) s->buffer[5]); - break; - case MARKER_ATMOVE: - if (s->at_moves < JBG85_ATMOVES_MAX) { - s->at_line[s->at_moves] = - (((long) s->buffer[2] << 24) | ((long) s->buffer[3] << 16) | - ((long) s->buffer[4] << 8) | (long) s->buffer[5]); - s->at_tx[s->at_moves] = (signed char) s->buffer[6]; - if (s->at_tx[s->at_moves] > (int) s->mx || - (s->at_tx[s->at_moves] < ((s->options & JBG_LRLTWO) ? 5 : 3) && - s->at_tx[s->at_moves] != 0) || - s->buffer[7] != 0) - return JBG_EINVAL | 11; - s->at_moves++; - } else - return JBG_EIMPL | 14; /* more than JBG85_ATMOVES_MAX ATMOVES */ - break; - case MARKER_NEWLEN: - y = (((long) s->buffer[2] << 24) | ((long) s->buffer[3] << 16) | - ((long) s->buffer[4] << 8) | (long) s->buffer[5]); - if (y > s->y0) return JBG_EINVAL | 12; -#ifndef JBG85_TOLERATE_MULTIPLE_NEWLEN - if (!(s->options & JBG_VLENGTH)) return JBG_EINVAL | 13; - s->options &= ~JBG_VLENGTH; -#endif - s->y0 = y; - break; - - case MARKER_SDNORM: - case MARKER_SDRST: - - switch (s->buf_len) { - case 2: - /* process regular SDNORM/SDRST without peek-ahead bytes */ - if (finish_sde(s)) - return JBG_EOK_INTR; /* line_out() requested interrupt */ - /* check whether this was the last SDE */ - if (s->y >= s->y0) return JBG_EOK; - break; - case 2+1: - /* process single peek-ahead byte */ - if (s->buffer[2] == MARKER_ESC) - continue; /* next time we'll have s->buf_len == 2 + 2 */ - else { - /* push back the single peek-ahead PCSD byte */ - assert(*cnt > 0); - (*cnt)--; - s->buf_len--; - if (finish_sde(s)) { - return JBG_EOK_INTR; /* line_out() requested interrupt */ - } - } - break; - case 2+2: - /* process 2-byte peek-ahead marker sequence */ - if (s->buffer[2] == MARKER_ESC && s->buffer[3] == MARKER_NEWLEN) - continue; /* next time we'll have s->buf_len == 2 + 6 */ - else { - if (finish_sde(s)) - return JBG_EOK_INTR; /* line_out() requested interrupt */ - /* recycle the two peek-ahead marker sequence bytes */ - s->buffer[0] = s->buffer[2]; - s->buffer[1] = s->buffer[3]; - s->buf_len = 2; - if (s->intr) - return JBG_EOK_INTR; /* line_out() requested interrupt */ - continue; - } - case 2+6: - /* process peek-ahead NEWLEN marker sequence */ - y = (((long) s->buffer[4] << 24) | ((long) s->buffer[5] << 16) | - ((long) s->buffer[6] << 8) | (long) s->buffer[7]); - if (y > s->y0) return JBG_EINVAL | 12; - if (!(s->options & JBG_VLENGTH)) return JBG_EINVAL | 13; - s->y0 = y; - if (finish_sde(s)) - return JBG_EOK_INTR; /* line_out() requested interrupt */ - s->buf_len = 0; - s->options &= ~JBG_VLENGTH; - /* we leave returning JBG_EOK to the following SDNORM/RST */ - break; - } - - if (s->intr) { - s->buf_len = 0; - return JBG_EOK_INTR; /* line_out() requested interrupt */ - } - - } /* switch (s->buffer[1]) */ - s->buf_len = 0; - - } else if (*cnt < len && data[*cnt] == MARKER_ESC) - s->buffer[s->buf_len++] = data[(*cnt)++]; - - else { - - /* we have found PSCD bytes */ - *cnt += decode_pscd(s, data + *cnt, len - *cnt); - if (s->intr) - return JBG_EOK_INTR; /* line_out() requested interrupt */ - if (*cnt < len && data[*cnt] != MARKER_ESC) { -#ifdef DEBUG - fprintf(stderr, "PSCD was longer than expected, unread bytes " - "%02x %02x %02x %02x ...\n", data[*cnt], data[*cnt+1], - data[*cnt+2], data[*cnt+3]); -#endif - return JBG_EINVAL | 14; /* PSCD was longer than expected */ - } - - } - } /* of BID processing loop 'while (*cnt < len) ...' */ - - return JBG_EAGAIN; -} - - -/* - * After the final BIE byte has been delivered to jbg85_dec_in(), it - * may still return with JBG_EAGAIN in case the VLENGTH=1 option was - * used and no NEWLEN marker section has appeared yet. This is because - * such a BIE is not self-terminating (i.e., there could still be a - * NEWLEN followed by an SDNORM or SDRST lurk after the final stripe, - * which needs to be processed before the final line is output, see - * ITU-T Recommendation T.85, Appendix I). Therefore, after the last - * byte has been delivered, call this routine to signal the end of the - * BIE. This is necessary to allow the routine to finish processing - * BIEs with option VLENGTH=1 that do not actually contain any NEWLEN - * marker section. - */ -int jbg85_dec_end(struct jbg85_dec_state *s) -{ - s->end_of_bie = 1; - return jbg85_dec_in(s, NULL, 0, NULL); -} diff --git a/thirdparty/jbigkit/libjbig/jbig85.h b/thirdparty/jbigkit/libjbig/jbig85.h deleted file mode 100644 index 7bdf9a018..000000000 --- a/thirdparty/jbigkit/libjbig/jbig85.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Header file for the T.85 "light" version of the portable - * JBIG image compression library - * - * Copyright 1995-2014 -- Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/ - */ - -#ifndef JBG85_H -#define JBG85_H - -#include -#include "jbig_ar.h" - -/* - * JBIG-KIT version number - */ - -#define JBG85_VERSION "2.1" -#define JBG85_VERSION_MAJOR 2 -#define JBG85_VERSION_MINOR 1 - -/* - * JBIG-KIT licence agreement reference code: - * If you use JBIG-KIT under a commercial licence, please replace - * below the letters GPL with the reference code that you received - * with your licence agreement. (This code is typically a letter "A" - * followed by four decimal digits, e.g. "A1234".) - */ - -#define JBG85_LICENCE "GPL" - -/* - * Maximum number of ATMOVEs per stripe that decoder can handle - */ - -#define JBG85_ATMOVES_MAX 1 - -#ifndef JBG_LRLTWO - -/* - * Option and order flags - */ - -#define JBG_LRLTWO 0x40 -#define JBG_VLENGTH 0x20 -#define JBG_TPBON 0x08 - -/* - * Possible error code return values - */ - -#define JBG_EOK (0 << 4) -#define JBG_EOK_INTR (1 << 4) -#define JBG_EAGAIN (2 << 4) -#define JBG_ENOMEM (3 << 4) -#define JBG_EABORT (4 << 4) -#define JBG_EMARKER (5 << 4) -#define JBG_EINVAL (6 << 4) -#define JBG_EIMPL (7 << 4) - -#endif - -/* - * Status of a JBIG encoder - */ - -struct jbg85_enc_state { - unsigned long x0, y0; /* size of the input image */ - unsigned long l0; /* number of lines per stripe */ - int options; /* encoding parameters */ - int newlen; /* 0 = jbg85_enc_newlen() has not yet been called - 1 = jbg85_enc_newlen() has updated y0, NEWLEN pending - 2 = NEWLEN has already been output */ - unsigned mx; /* maximum ATMOVE window size */ - unsigned long y; /* next line number to be encoded */ - unsigned long i; /* next per-stripe line number to be encoded */ - int tx; /* x-offset of adaptive template pixel */ - unsigned long c_all, c[128]; /* adaptive template algorithm variables */ - int new_tx; /* -1 = no ATMOVE pending, otherwise new TX value */ - int ltp_old; /* true if line y-1 was "typical" */ - struct jbg_arenc_state s; /* arithmetic encoder status */ - void (*data_out)(unsigned char *start, size_t len, void *file); - /* data write callback */ - void *file; /* parameter passed to data_out() */ - unsigned char *comment; /* content of comment marker segment to be added - at next opportunity (will be reset to NULL - as soon as comment has been written) */ - unsigned long comment_len; /* length of data pointed to by comment */ -}; - - -/* - * Status of a JBIG decoder - */ - -struct jbg85_dec_state { - /* data from BIH */ - unsigned long x0, y0; /* size of the full image */ - unsigned long l0; /* number of lines per stripe */ - int options; /* encoding parameters */ - int mx; /* maximum ATMOVE window size */ - /* image data */ - int p[3]; /* curr. line starts at linebuf+bpl*p[0], prev. line starts - * at linebuf+bpl*p[1], its predecessor at linebuf+bpl*p[2] */ - unsigned char *linebuf; /* buffer region provided by caller */ - size_t linebuf_len; - size_t bpl; /* bytes per line */ - /* status information */ - int tx; /* x-offset of AT pixel */ - struct jbg_ardec_state s; /* arithmetic decoder status */ - unsigned long bie_len; /* number of bytes read so far */ - unsigned char buffer[20]; /* used to store BIH or marker segments fragm. */ - int buf_len; /* number of bytes in buffer */ - unsigned long comment_skip; /* remaining bytes of a COMMENT segment */ - unsigned long x; /* x position of next pixel */ - unsigned long stripe; /* current stripe */ - unsigned long y; /* line in image (first line is 0) */ - unsigned long i; /* line in current stripe (first line of stripe is 0) */ - int at_moves; /* number of AT moves in the current stripe */ - unsigned long at_line[JBG85_ATMOVES_MAX]; /* lines at which an * - * AT move will happen */ - int at_tx[JBG85_ATMOVES_MAX]; /* ATMOVE x-offsets in current stripe */ - unsigned long line_h1, line_h2, line_h3; /* variables of decode_pscd */ - int pseudo; /* flag for TPBON/TPDON: next pixel is pseudo pixel */ - int lntp; /* flag for TP: line is not typical */ - int (*line_out)(const struct jbg85_dec_state *s, - unsigned char *start, size_t len, - unsigned long y, void *file); - /* data write callback */ - void *file; /* parameter passed to data_out() */ - int intr; /* flag that line_out requested interrupt */ - int end_of_bie; /* flag that the end of the BIE has been signalled */ -}; - - -/* function prototypes */ - -void jbg85_enc_init(struct jbg85_enc_state *s, - unsigned long x0, unsigned long y0, - void (*data_out)(unsigned char *start, size_t len, - void *file), - void *file); -void jbg85_enc_options(struct jbg85_enc_state *s, int options, - unsigned long l0, int mx); -void jbg85_enc_lineout(struct jbg85_enc_state *s, unsigned char *line, - unsigned char *prevline, unsigned char *prevprevline); -void jbg85_enc_newlen(struct jbg85_enc_state *s, unsigned long y0); -void jbg85_enc_abort(struct jbg85_enc_state *s); - -void jbg85_dec_init(struct jbg85_dec_state *s, - unsigned char *buf, size_t buflen, - int (*line_out)(const struct jbg85_dec_state *s, - unsigned char *start, size_t len, - unsigned long y, void *file), - void *file); -int jbg85_dec_in(struct jbg85_dec_state *s, unsigned char *data, size_t len, - size_t *cnt); -int jbg85_dec_end(struct jbg85_dec_state *s); -const char *jbg85_strerror(int errnum); - -/* some macros for examining decoder state */ - -#define jbg85_dec_finished(s) ((s)->bie_len == 20 && (s)->y >= (s)->y0) -/* enquire about image size */ -#define jbg85_dec_getwidth(s) ((s)->x0) -#define jbg85_dec_getheight(s) ((s)->y0) -/* enquire about validity of image-size results */ -#define jbg85_dec_validwidth(s) ((s)->bie_len == 20) -#define jbg85_dec_finalheight(s) ((s)->bie_len == 20 && \ - ((((s)->options & JBG_VLENGHT) == 0) || \ - ((s)->y >= (s)->y0))) - -#endif /* JBG85_H */ diff --git a/thirdparty/jbigkit/libjbig/jbig85.txt b/thirdparty/jbigkit/libjbig/jbig85.txt deleted file mode 100644 index fc2d6fa6f..000000000 --- a/thirdparty/jbigkit/libjbig/jbig85.txt +++ /dev/null @@ -1,618 +0,0 @@ - -Using the T.85 "light" version of the JBIG-KIT library ------------------------------------------------------- - -Markus Kuhn -- 2008-08-30 - - -This text explains how to use the functions provided by the JBIG-KIT -portable image compression library jbig85.c in your application -software. - - -1 Distinguishing features - -The jbig85.c library implements only the "single-progression -sequential coding" subset of the JBIG1 standard, which is defined in -ITU-T Recommendation T.85 , also -known as the "facsimile application profile". This means that the -JBIG1 data streams that the jbig85.c library can process can have - - - no progressive encoding, i.e. the image is always encoded in a - single resolution layer (and not as a sequence of layers of a - resolution pyramid); - - - only a single plane, i.e. the raw data are black/white images with - only one bit per pixel information. - -The jbig85.c library is not suitable for continuous-tone (colour or -grey-scale) image applications, including the fax method described in -ITU-R Recommendation T.43. For these applications, use the full jbig.c -library instead. - -The T.85 restrictions are sufficient for black/white fax transmission -and several other common bi-level image applications (printer drivers, -document archiving, etc.). They simplify the design of the encoder and -decoder and allow the jbig85.c library to provide several advantages -over the full-featured jbig.c: - - - Only the last three lines of the uncompressed image need to be - kept in RAM at any time. - - - All memory allocation is done outside the jbig85.c library, which - performs no calls to malloc(), free(), etc. - - - The implementation can handle images whose height (number of pixel - rows) is not yet known before the last line has been encoded or - decoded. - - - All usage modes of the NEWLEN marker segment are supported, - including a NEWLEN occurring after the final stripe, as required by - ITU-T Recommendation T.85, using only a single pass over the data. - - - The code is smaller and there is no need to store tables related - to the resolution-reduction algorithms. - -This makes the jbig85.c library particularly suited for very small -embedded applications, e.g. low-end fax machines, along with the fact -that the library is non-recursive and requires only a very small stack -(typically just a bit over 100 bytes on a 32-bit system). The jbig85.c -library may also be a good choice where very large black/white images -are processed. - -The jbig85.c and jbig.c libraries both can be linked simultaneously -with the same application if you #include jbig85.h after jbig.h into -your source code. - - -2 Introduction to JBIG (T.85 subset) - -We start with a short introduction to the T.85 subset of JBIG1. More -detailed information is provided in the "Introduction and overview" -section of the JBIG1 standard. Information on how to obtain a copy of -the standard is available from -or . - -The JBIG1 standard allows the encoder to divide an image into several -horizontal stripes. All stripes have equal size, except perhaps the -final one. - -The compressed data stream specified by the JBIG standard is called a -bi-level image entity (BIE). A BIE consists of a 20-byte header, -followed by a sequence of stripe data entities (SDE). Each SDE encodes -the content of one single stripe in one plane of one resolution layer. -Between the SDEs, other information blocks (called floating marker -segments) can also be present. They are used to change certain -parameters of the algorithm in the middle of an image or contain -additional application specific information. A BIE looks like this: - - - +------------------------------------------------+ - | | - | 20-byte header (specifying image size, stripe | - | size, and options) | - | | - +------------------------------------------------+ - | | - | optional floating marker segments | - | | - +------------------------------------------------+ - | | - | stripe data entity | - | | - +------------------------------------------------+ - | | - | optional floating marker segments | - | | - +------------------------------------------------+ - | | - | stripe data entity | - | | - +------------------------------------------------+ - ... - +------------------------------------------------+ - | | - | stripe data entity | - | | - +------------------------------------------------+ - -It is possible to use the raw BIE data stream as specified by the JBIG -standard directly as the format of a file used for storing images. -This is what the pbmtojbg, jbgtopbm, pbmtojbg85, and jbgtopbm85 -conversion tools do that are provided in this package as demonstration -applications. However, as the BIE format has been designed for a large -number of very different applications, and to allow efficient direct -processing by special JBIG hardware chip implementations, the BIE -header contains only the minimum amount of information absolutely -required by the decompression algorithm. Many features expected from a -good file format are missing in the BIE data stream: - - - no "magic code" in the first few bytes to allow identification - of the file format on a typeless file system and to allow - automatic distinction from other compression algorithms - - - no standardized way to encode additional information such as a - textual description, the physical size and resolution of the - document, etc. - - - a checksum to ensure image integrity - - - encryption and signature mechanisms - - - many things more - -Raw BIE data streams alone may therefore not be a suitable format for -document archiving and exchange. A standard format for this purpose -would typically combine a BIE representing the image data with an -additional header providing auxiliary information into one file. -Existing established multi-purpose file formats with a rich set of -auxiliary information attributes like TIFF could be extended easily to -also hold JBIG compressed data. - -On the other hand, in e.g. database applications, a BIE might be -stored directly in a binary variable-length field. Auxiliary -information would then be stored in other fields of the same record, -to simplify search operations. - - -2 Compressing an image - -2.1 Format of the source image - -To be processed by the jbig85.c encoder, the image has to be present -in memory a bitmap. Each byte of a bitmap contains eight pixels, where -the most significant bit represents the leftmost of these. Each line -of a bitmap has to be stored in an integral number of bytes. If the -image width is not an integral multiple of eight, then the final byte -has to be padded with zero bits. - -For example the 23x5 pixels large single plane image: - - .XXXXX..XXX...X...XXX.. - .....X..X..X..X..X..... - .....X..XXX...X..X.XXX. - .X...X..X..X..X..X...X. - ..XXX...XXX...X...XXX.. - -is represented by the 15 bytes - - 01111100 11100010 00111000 - 00000100 10010010 01000000 - 00000100 11100010 01011100 - 01000100 10010010 01000100 - 00111000 11100010 00111000 - -or in hexadecimal notation - - 7c e2 38 04 92 40 04 e2 5c 44 92 44 38 e2 38 - -This is the format used in binary PBM files and it can also be handled -directly by the Xlib library of the X Window System. - -The standard recommends that a 0 pixel represents the background and a -1 pixel represents the foreground colour of an image, in other words, 0 -is white and 1 is black for scanned paper documents. - - -2.2 A simple compression application - -In order to use jbig85.c in your application, just link your -executable with both jbig85.c and jbig_ar.c. Both are already combined -into libjbig85.a by the provided Makefile, so on Unix systems, just -add -ljbig85 and -L. to the command line options of your compiler. On -other systems you will probably have to write a new Makefile. Make -sure your compiler can find the file jbig85.h and put the line - - #include "jbig85.h" - -into your source code. - -The library interface follows object-oriented programming principles. -You have to declare a variable (object) - - struct jbg85_enc_state s; - -which contains the current status of an encoder. Then you initialize -the encoder by calling - - void jbg85_enc_init(struct jbg85_enc_state *s, - unsigned long x, unsigned long y, - void (*data_out)(unsigned char *start, size_t len, - void *file), - void *file); - -The parameters have the following meaning: - - s A pointer to the jbg85_enc_state structure that you want - to initialize. - - x The width of your image in pixels. - - y The height of your image in pixels (lines). This can be - a larger value than the actual height of the image, or - even 2^32-1 (or equally -1), if the height of the - image is not yet known. In that case, leave the - JBG_VLENGTH option set (see below) and call - jbg85_enc_newlen() as soon as the actual image height - is known. - - data_out This is a call-back function that the encoder will - call during the compression process in order to - deliver the BIE data to your application. The - parameters of the function data_out are a pointer - start to the new block of data being delivered, as - well as the number len of delivered bytes. The pointer - file is transparently delivered to data_out, as - specified in jbg85_enc_init(). Typically, data_out - will write the BIE portion to a file, send it to a - network connection, or append it to some memory - buffer. - - file A pointer parameter that is passed on to data_out() - and can be used, for instance, to allow data_out() to - distinguish by which compression task it has been - called in multi-threaded applications. - -The compression can then be started by calling the function - - void jbg85_enc_lineout(struct jbg85_enc_state *s, unsigned char *line, - unsigned char *prevline, unsigned char *prevprevline); - -successively for each line of the image, top to bottom. The parameters -are: - - line A pointer to the first byte of the line to be encoded. - - prevline A pointer to the data that the line parameter pointed - to in the previous call. The value will be ignored - if this is the first call. - - prevprevline A pointer to the data that the prevline parameter pointed - to in the previous call. The value will be ignored - if this is the first or second call. - -After jbg85_enc_lineout() has been called for all lines of the image, -the complete BIE will have been delivered via several callbacks to -data_out(). These BIE bytes are delivered as soon as possible, as the -encoder cannot buffer more than a few bytes internally. - -A minimal example application, which sends the BIE of the above bitmap -to stdout, looks like this: - ---------------------------------------------------------------------------- -/* A sample JBIG T.85 encoding application */ - -#include -#include "jbig85.h" - -void output_bie(unsigned char *start, size_t len, void *file) -{ - fwrite(start, 1, len, (FILE *) file); - - return; -} - -int main() -{ - unsigned char bitmap[15] = { - /* 23 x 5 pixels, "JBIG" */ - 0x7c, 0xe2, 0x38, 0x04, 0x92, 0x40, 0x04, 0xe2, - 0x5c, 0x44, 0x92, 0x44, 0x38, 0xe2, 0x38 - }; - struct jbg85_enc_state se; - int i; - - jbg85_enc_init(&se, 23, 5, output_bie, stdout); /* initialize encoder */ - jbg85_enc_options(&se, JBG_TPBON, 0, -1); /* clear JBG_VLENGTH option */ - for (i = 0; i < 5; i++) { - /* encode line */ - jbg85_enc_lineout(&se, bitmap+i*3, bitmap+(i-1)*3, bitmap+(i-2)*3); - } - - return 0; -} ---------------------------------------------------------------------------- - -This software produces a 37 byte long BIE. (JBIG is not very good at -compressing extremely small images like in this example, because the -arithmetic encoder requires some startup data in order to generate -reasonable statistics which influence the compression process and -because there is some header overhead.) - - -2.3 More about compression - -If jbg85_enc_lineout() is called directly after jbg85_enc_init(), the -following default values are used for various compression parameters: - - - The number of lines per stripe (l0) is set to 128, which is the - T.85 BASIC setting. - - - The typical-prediction (TPBON) and variable-length (VLENGTH) options - are activated, but the two-line template (LRLTWO) option is not. - - - The maximal horizontal offset of the adaptive template pixel is 127 - (mx = 127, my = 0). - -In order to change any of these default parameters, an additional -function has to be called between jbg85_enc_init() and the first -jbg85_enc_lineout(): - - void jbg85_enc_options(struct jbg85_enc_state *s, int options, - unsigned long l0, int mx) - -The options value can contain the following bits, which activate some -of the optional algorithms defined by JBIG: - - JBG_LRLTWO This option bit changes the JBIG algorithm such that the - context in which the probability of a pixel is - estimated includes only the previous line (two-line - template), rather than the previous two lines - (three-line template). This option is off by default - and the author cannot think of a good reason to set it. - [Some people in the JBIG committee seem to have - argued that using a two-line template will make - software implementations a little bit faster, while - others have argued that using only two lines will - decrease compression efficiency by around 5%. As you - might expect from a committee, now both alternatives - are allowed (and add to the implementation and testing - complexity of every decoder).] - - JBG_TPBON This bit activates the "typical prediction" algorithm. It - is set by default. Typical prediction means that JBIG - prefixes each line to be encoded with a "pseudopixel" - that indicates if the line is identical to the - previous line, and skips encoding the line if it is. - This helps to encode empty parts of a page very - efficiently in just a few bytes, therefore this - option should be left on. (The only reason the author - could think of for ever deactivating this option is - if you know in advance that there will never be two - identical lines follow each other in the image to be - encoded, in which case deactivating this option might - provide a tiny performance improvement.) - - JBG_VLENGTH This bit indicates that the image height y provided - to jbg85_enc_init() was only an estimate and may - be lowered sometimes during the encoding process - using a call to jbg85_enc_newlen(). This feature - is intended for fax machines that start transmitting - a page while still scanning it and without knowing - how long the page is going to be. - -Value -1 for options keeps the current setting, the default is -JBG_TPBON | JBG_VLENGTH. - -The other parameters are: - - l0 Sets the number of lines per stripe (valid range: - 1 to 2^32-1, default 128, value 0 keeps the current - setting). - - mx Changes the maximal offset allowed for the adaptive - template pixel (valid range: 0 to 127, default 127, - value -1 keeps the current setting). - -If the JBG_VLENGTH option was set, then you can call at any time the -function - - void jbg85_enc_newlen(struct jbg85_enc_state *s, unsigned long newlen) - -in order to announce the actual height of the image. You can call this -function only once per image, and the provided new height value newlen -must not be larger than the estimate y originally provided. It is good -practice to call jbg85_enc_newlen() as soon as the height of the image -is known. However, it is even possible to call it after the last line -has already been encoded using jbg85_enc_lineout(). The latter case -will result in a somewhat odd BIE, where an additional empty stripe -has to be appended just to announce the new length. This is not pretty -and was not described in great detail in the original JBIG1 standard, -but decoders are required by ITU-T T.85 to understand even this -extremely late announcement of the end of the image. - -If the image height y initially given to jbg85_enc_init() is already -the correct final value and you will therefore never call -jbg85_enc_newlen(), then it is good practice to clear the JBG_VLENGTH -option bit, which is set by default, e.g. by calling - - jbg85_enc_options(&s, JBG_TPBON, 0, -1); - -between jbg85_enc_init() and jbg85_enc_lineout(). - -The JBIG standard also has a provision for aborting a BIE with a -special abort marker segment, and calling - - void jbg85_enc_abort(struct jbg85_enc_state *s); - -does that. This is probably only needed if there is no other way -(e.g., end-of-file) of telling the decoder that no further data bytes -will be coming. - - -3 Decompressing an image - -Like with the compression functions, if you want to use the jbig85.c -library, you have to put the line - - #include "jbig85.h" - -into your source code and link your executable with libjbig85.a. - -The state of a JBIG decoder is stored completely in a struct and you -will have to define a variable like - - struct jbg85_dec_state s; - -which is initialized by a call to - - void jbg85_dec_init(struct jbg85_dec_state *s, - unsigned char *buf, size_t buflen, - int (*line_out)(const struct jbg85_dec_state *s, - unsigned char *start, size_t len, - unsigned long y, void *file), - void *file); - -The parameters are: - - buf A memory buffer that is long enough to store up to - three lines of the image. This buffer will be used - by the decoder to temporarily store decoded lines. - If the decoded image uses the LRLTWO option, the buffer - has to be only sufficient for two uncompressed - image lines. - - buflen The length in bytes of the buffer area to which buf - points. Knowing this value prevents accidental buffer - overflows and allows the decoder to abort with - JBG_ENOMEM if the provided buffer was too small, once - it knows the width of the image to be decoded from - parsing its 20-byte header. If xmax is the expected - maximum width of the image in pixels, then buflen - should be at least ((xmax >> 3) + !!(xmax & 7)) * 3 - bytes. [If only BIEs with option LRLTWO set will be - received, then ((xmax >> 3) + !!(xmax & 7)) * 2 - bytes will be sufficient.] - - line_out This call-back function will be used whenever the decoder - has completed another line. The start parameter will - point to the location in buf where the len bytes of - the just decoded line reside. The line_out() function - has to read (and copy or output) this line, but it is - not allowed to modify it in-place, as the decoder will - also need to access it while decoding the following - two lines. The parameter y is just the line number - (starting from 0) and file is the jbg85_dec_init() - parameter of the same name passed on. The normal - return value of line_out is zero; a non-zero value - can be returned to request an interrupt of the decoding - process (see discussion of JBG_EOK_INTR below). - - file A pointer parameter that is passed on to line_out() - and can be used, for instance, to allow line_out() to - distinguish by which compression task it has been - called in multi-threaded applications. - -After this, you can directly start to pass data from the BIE to the decoder -by calling the function - - int jbg85_dec_in(struct jbg85_dec_state *s, unsigned char *data, size_t len, - size_t *cnt); - -The pointer data points to the first byte of a data block with length -len, which contains bytes from a BIE. It is not necessary to pass a -whole BIE at once to jbg85_dec_in(), it can arrive fragmented in any -way by calling jbg85_dec_in() several times. Only a single BIE can be -delivered via jbg85_dec_in() calls and the decoder has to be -reinitialized with jbg85_dec_init() before it is ready to accept -another BIE. - -If pointer cnt is not NULL, then the number of bytes actually read -from the data block will be stored there. In case the decoder did not -recognize the end of the BIE in the data block, then the value -JBG_EAGAIN will be returned and *cnt equals len. - -Once the end of a BIE has been reached, the return value of -jbg85_dec_in() will be JBG_EOK. - -The decoder can recognize the end of a BIE only if either the VLENGTH -option is not set, or if there has been a NEWLEN marker segment before -the start of the last stripe. Otherwise, the decoder cannot know -whether there is or is not a NEWLEN marker segment following the last -stripe. For this reason, jbg85_dec_in() can return JBG_EAGAIN even -though you have already given it the last byte of the BIE. In this -case, call - - int jbg85_dec_end(struct jbg85_dec_state *s); - -to explicitely signal to the decoder that it has already received all -bytes of the BIE. This function will then output any remaining lines -and return JBG_EOK if no problem has occurred. - -The macros - - unsigned long jbg85_dec_getwidth(struct jbg85_dec_state *s); - unsigned long jbg85_dec_getheight(struct jbg85_dec_state *s); - -can be used to query the dimensions of the image. The width will be -known already after the first 20 bytes of the BIE have been provided, -and also during the first callback to line_out(). But the height might -not have reached its final value before jbg85_dec_in() has returned -JBG_EOK. The additional boolean macros - - int jbg85_dec_validwidth(struct jbg85_dec_state *s); - int jbg85_dec_finalheight(struct jbg85_dec_state *s); - int jbg85_dec_finished(struct jbg85_dec_state *s); - -tell, whether the width and final height are already known, and -whether the decoder has finished outputting all lines. - -If one of the callbacks to line_out() provides a non-zero return -value, then the decoder will interrupt the decoding process and -jbg85_dec_in() or jbg85_dec_end() will return JBG_EOK_INTR. This -feature might be useful to stop the decoding process temporarily, e.g. -to load a new sheet of paper, where performing this task is -inconvenient to complete inside line_out(). It is then possible to -continue calling jbg85_dec_in() with the remaining data (or -jbg85_dec_end() if there isn't any left) in order to decode the -remaining lines of the BIE. After jbg85_dec_in() returned -JBG_EOK_INTR, *cnt is probably not equal to len and the remainder of -the data block which has not yet been processed by the decoder has to -be delivered to jbg85_dec_in() again. Any line that has already been -delivered to line_out() will not be delivered again. - -If any other return value than JBG_EOK, JBG_EOK_INTR or JBG_EAGAIN has -been returned by jbg85_dec_in() or jbg85_dec_end(), then an error has -occurred and the decoding process has been aborted. The function - - const char *jbg85_strerror(int errnum); - -returns a pointer to a short single-line test message that explains -the return value of jbg85_dec_in() or jbg85_dec_end(). This message -can be used in order to provide the user a brief informative message -about what when wrong while decompressing a JBIG image. The po/ -subdirectory contains *.po files that translate the English ASCII -strings returned by jbg85_strerror() into other languages (e.g., for -use with GNU gettext). The four least-significant bits of the return -value of jbg85_dec_in() or jbg85_dec_end() may contain additional -detailed technical information about the exact test that spotted the -error condition (see source code for details), i.e. more than the text -message returned by jbg85_strerror() reveals. Therefore it may be -useful to display the return value itself as a hexadecimal number, in -addition to the string returned by jbg85_strerror(). - - -4 Additional notes - -The following remarks will not affect the normal user of the library -but might be of interest to some users who have to deal with exotic -cases, in particular dealing with broken non-JBIG-KIT encoders out -there: - - - There has been one report about malformed BIEs produced by another - JBIG implementation that violates the standard by containing - several NEWLEN marker segments in the same BIE. The jbig85.c - decoder will normally abort with JBG_EINVALID when it encounters - such an illegal BIE. The compile-time option - JBG85_TOLERATE_MULTIPLE_NEWLEN can be used to make the decoder - more tolerant to this type of syntax error. - - - Even though the T.85 standard prescribes all-zero values for the - order bits HITOLO, SEQ, ILEAVE, SMID, the jbig85.c decoder will - not complain about any other values of these bits, as they do not - affect the decoding process when there is only a single plane and - resolution layer (the only case supported by this decoder). The - compile-time option JBG85_STRICT_ORDER_BITS will make the decoder - less tolerant and abort with JBG_EIMPL if the received order bits - do not comply with the T.85 "single-progression sequential coding" - requirements. - - - The T.85 standard allows only a single ATMOVE marker segment per - SDE, and the jbig85.c decoder enforces this limit by default. This - limit can be increased by setting JBG85_ATMOVES_MAX in jbig85.h to - the desired value. The encoder will never output more than a - single ATMOVE marker segment per stripe. - -*** Happy decompressing *** - -[end] diff --git a/thirdparty/jbigkit/libjbig/jbig_ar.c b/thirdparty/jbigkit/libjbig/jbig_ar.c deleted file mode 100644 index 32e5bf64d..000000000 --- a/thirdparty/jbigkit/libjbig/jbig_ar.c +++ /dev/null @@ -1,417 +0,0 @@ -/* - * Arithmetic encoder and decoder of the portable JBIG - * compression library - * - * Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/jbigkit/ - * - * This module implements a portable standard C arithmetic encoder - * and decoder used by the JBIG lossless bi-level image compression - * algorithm as specified in International Standard ISO 11544:1993 - * and ITU-T Recommendation T.82. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * If you want to use this program under different license conditions, - * then contact the author for an arrangement. - */ - -#include -#include "jbig_ar.h" - -/* - * Probability estimation tables for the arithmetic encoder/decoder - * given by ITU T.82 Table 24. - */ - -static short lsztab[113] = { - 0x5a1d, 0x2586, 0x1114, 0x080b, 0x03d8, 0x01da, 0x00e5, 0x006f, - 0x0036, 0x001a, 0x000d, 0x0006, 0x0003, 0x0001, 0x5a7f, 0x3f25, - 0x2cf2, 0x207c, 0x17b9, 0x1182, 0x0cef, 0x09a1, 0x072f, 0x055c, - 0x0406, 0x0303, 0x0240, 0x01b1, 0x0144, 0x00f5, 0x00b7, 0x008a, - 0x0068, 0x004e, 0x003b, 0x002c, 0x5ae1, 0x484c, 0x3a0d, 0x2ef1, - 0x261f, 0x1f33, 0x19a8, 0x1518, 0x1177, 0x0e74, 0x0bfb, 0x09f8, - 0x0861, 0x0706, 0x05cd, 0x04de, 0x040f, 0x0363, 0x02d4, 0x025c, - 0x01f8, 0x01a4, 0x0160, 0x0125, 0x00f6, 0x00cb, 0x00ab, 0x008f, - 0x5b12, 0x4d04, 0x412c, 0x37d8, 0x2fe8, 0x293c, 0x2379, 0x1edf, - 0x1aa9, 0x174e, 0x1424, 0x119c, 0x0f6b, 0x0d51, 0x0bb6, 0x0a40, - 0x5832, 0x4d1c, 0x438e, 0x3bdd, 0x34ee, 0x2eae, 0x299a, 0x2516, - 0x5570, 0x4ca9, 0x44d9, 0x3e22, 0x3824, 0x32b4, 0x2e17, 0x56a8, - 0x4f46, 0x47e5, 0x41cf, 0x3c3d, 0x375e, 0x5231, 0x4c0f, 0x4639, - 0x415e, 0x5627, 0x50e7, 0x4b85, 0x5597, 0x504f, 0x5a10, 0x5522, - 0x59eb -}; - -static unsigned char nmpstab[113] = { - 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 13, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 9, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 32, - 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 48, - 81, 82, 83, 84, 85, 86, 87, 71, - 89, 90, 91, 92, 93, 94, 86, 96, - 97, 98, 99, 100, 93, 102, 103, 104, - 99, 106, 107, 103, 109, 107, 111, 109, - 111 -}; - -/* - * least significant 7 bits (mask 0x7f) of nlpstab[] contain NLPS value, - * most significant bit (mask 0x80) contains SWTCH bit - */ -static unsigned char nlpstab[113] = { - 129, 14, 16, 18, 20, 23, 25, 28, - 30, 33, 35, 9, 10, 12, 143, 36, - 38, 39, 40, 42, 43, 45, 46, 48, - 49, 51, 52, 54, 56, 57, 59, 60, - 62, 63, 32, 33, 165, 64, 65, 67, - 68, 69, 70, 72, 73, 74, 75, 77, - 78, 79, 48, 50, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 61, 61, - 193, 80, 81, 82, 83, 84, 86, 87, - 87, 72, 72, 74, 74, 75, 77, 77, - 208, 88, 89, 90, 91, 92, 93, 86, - 216, 95, 96, 97, 99, 99, 93, 223, - 101, 102, 103, 104, 99, 105, 106, 107, - 103, 233, 108, 109, 110, 111, 238, 112, - 240 -}; - -/* - * The next functions implement the arithmedic encoder and decoder - * required for JBIG. The same algorithm is also used in the arithmetic - * variant of JPEG. - */ - -/* marker codes */ -#define MARKER_STUFF 0x00 -#define MARKER_ESC 0xff - -void arith_encode_init(struct jbg_arenc_state *s, int reuse_st) -{ - int i; - - if (!reuse_st) - for (i = 0; i < 4096; s->st[i++] = 0) ; - s->c = 0; - s->a = 0x10000L; - s->sc = 0; - s->ct = 11; - s->buffer = -1; /* empty */ - - return; -} - - -void arith_encode_flush(struct jbg_arenc_state *s) -{ - unsigned long temp; - - /* find the s->c in the coding interval with the largest - * number of trailing zero bits */ - if ((temp = (s->a - 1 + s->c) & 0xffff0000L) < s->c) - s->c = temp + 0x8000; - else - s->c = temp; - /* send remaining bytes to output */ - s->c <<= s->ct; - if (s->c & 0xf8000000L) { - /* one final overflow has to be handled */ - if (s->buffer >= 0) { - s->byte_out(s->buffer + 1, s->file); - if (s->buffer + 1 == MARKER_ESC) - s->byte_out(MARKER_STUFF, s->file); - } - /* output 0x00 bytes only when more non-0x00 will follow */ - if (s->c & 0x7fff800L) - for (; s->sc; --s->sc) - s->byte_out(0x00, s->file); - } else { - if (s->buffer >= 0) - s->byte_out(s->buffer, s->file); - /* T.82 figure 30 says buffer+1 for the above line! Typo? */ - for (; s->sc; --s->sc) { - s->byte_out(0xff, s->file); - s->byte_out(MARKER_STUFF, s->file); - } - } - /* output final bytes only if they are not 0x00 */ - if (s->c & 0x7fff800L) { - s->byte_out((s->c >> 19) & 0xff, s->file); - if (((s->c >> 19) & 0xff) == MARKER_ESC) - s->byte_out(MARKER_STUFF, s->file); - if (s->c & 0x7f800L) { - s->byte_out((s->c >> 11) & 0xff, s->file); - if (((s->c >> 11) & 0xff) == MARKER_ESC) - s->byte_out(MARKER_STUFF, s->file); - } - } - - return; -} - - -void arith_encode(struct jbg_arenc_state *s, int cx, int pix) -{ - register unsigned lsz, ss; - register unsigned char *st; - long temp; - - assert(cx >= 0 && cx < 4096); - st = s->st + cx; - ss = *st & 0x7f; - assert(ss < 113); - lsz = lsztab[ss]; - -#if 0 - fprintf(stderr, "pix = %d, cx = %d, mps = %d, st = %3d, lsz = 0x%04x, " - "a = 0x%05lx, c = 0x%08lx, ct = %2d, buf = 0x%02x\n", - pix, cx, !!(s->st[cx] & 0x80), ss, lsz, s->a, s->c, s->ct, - s->buffer); -#endif - - if (((pix << 7) ^ s->st[cx]) & 0x80) { - /* encode the less probable symbol */ - if ((s->a -= lsz) >= lsz) { - /* If the interval size (lsz) for the less probable symbol (LPS) - * is larger than the interval size for the MPS, then exchange - * the two symbols for coding efficiency, otherwise code the LPS - * as usual: */ - s->c += s->a; - s->a = lsz; - } - /* Check whether MPS/LPS exchange is necessary - * and chose next probability estimator status */ - *st &= 0x80; - *st ^= nlpstab[ss]; - } else { - /* encode the more probable symbol */ - if ((s->a -= lsz) & 0xffff8000L) - return; /* A >= 0x8000 -> ready, no renormalization required */ - if (s->a < lsz) { - /* If the interval size (lsz) for the less probable symbol (LPS) - * is larger than the interval size for the MPS, then exchange - * the two symbols for coding efficiency: */ - s->c += s->a; - s->a = lsz; - } - /* chose next probability estimator status */ - *st &= 0x80; - *st |= nmpstab[ss]; - } - - /* renormalization of coding interval */ - do { - s->a <<= 1; - s->c <<= 1; - --s->ct; - if (s->ct == 0) { - /* another byte is ready for output */ - temp = s->c >> 19; - if (temp & 0xffffff00L) { - /* handle overflow over all buffered 0xff bytes */ - if (s->buffer >= 0) { - ++s->buffer; - s->byte_out(s->buffer, s->file); - if (s->buffer == MARKER_ESC) - s->byte_out(MARKER_STUFF, s->file); - } - for (; s->sc; --s->sc) - s->byte_out(0x00, s->file); - s->buffer = temp & 0xff; /* new output byte, might overflow later */ - assert(s->buffer != 0xff); - /* can s->buffer really never become 0xff here? */ - } else if (temp == 0xff) { - /* buffer 0xff byte (which might overflow later) */ - ++s->sc; - } else { - /* output all buffered 0xff bytes, they will not overflow any more */ - if (s->buffer >= 0) - s->byte_out(s->buffer, s->file); - for (; s->sc; --s->sc) { - s->byte_out(0xff, s->file); - s->byte_out(MARKER_STUFF, s->file); - } - s->buffer = temp; /* buffer new output byte (can still overflow) */ - } - s->c &= 0x7ffffL; - s->ct = 8; - } - } while (s->a < 0x8000); - - return; -} - - -void arith_decode_init(struct jbg_ardec_state *s, int reuse_st) -{ - int i; - - if (!reuse_st) - for (i = 0; i < 4096; s->st[i++] = 0) ; - s->c = 0; - s->a = 1; - s->ct = 0; - s->startup = 1; - s->nopadding = 0; - return; -} - -/* - * Decode and return one symbol from the provided PSCD byte stream - * that starts in s->pscd_ptr and ends in the byte before s->pscd_end. - * The context cx is a 12-bit integer in the range 0..4095. This - * function will advance s->pscd_ptr each time it has consumed all - * information from that PSCD byte. - * - * If a symbol has been decoded successfully, the return value will be - * 0 or 1 (depending on the symbol). - * - * If the decoder was not able to decode a symbol from the provided - * PSCD, then the return value will be -1, and two cases can be - * distinguished: - * - * s->pscd_ptr == s->pscd_end: - * - * The decoder has used up all information in the provided PSCD - * bytes. Further PSCD bytes have to be provided (via new values of - * s->pscd_ptr and/or s->pscd_end) before another symbol can be - * decoded. - * - * s->pscd_ptr == s->pscd_end - 1: - * - * The decoder has used up all provided PSCD bytes except for the - * very last byte, because that has the value 0xff. The decoder can - * at this point not yet tell whether this 0xff belongs to a - * MARKER_STUFF sequence or marks the end of the PSCD. Further PSCD - * bytes have to be provided (via new values of s->pscd_ptr and/or - * s->pscd_end), including the not yet processed 0xff byte, before - * another symbol can be decoded successfully. - * - * If s->nopadding != 0, the decoder will return -2 when it reaches - * the first two bytes of the marker segment that follows (and - * terminates) the PSCD, but before decoding the first symbol that - * depends on a bit in the input data that could have been the result - * of zero padding, and might, therefore, never have been encoded. - * This gives the caller the opportunity to lookahead early enough - * beyond a terminating SDNORM/SDRST for a trailing NEWLEN (as - * required by T.85) before decoding remaining symbols. Call the - * decoder again afterwards as often as necessary (leaving s->pscd_ptr - * pointing to the start of the marker segment) to retrieve any - * required remaining symbols that might depend on padding. - * - * [Note that each PSCD can be decoded into an infinitely long - * sequence of symbols, because the encoder might have truncated away - * an arbitrarily long sequence of trailing 0x00 bytes, which the - * decoder will append automatically as needed when it reaches the end - * of the PSCD. Therefore, the decoder cannot report any end of the - * symbol sequence and other means (external to the PSCD and - * arithmetic decoding process) are needed to determine that.] - */ - -int arith_decode(struct jbg_ardec_state *s, int cx) -{ - register unsigned lsz, ss; - register unsigned char *st; - int pix; - - /* renormalization */ - while (s->a < 0x8000 || s->startup) { - while (s->ct <= 8 && s->ct >= 0) { - /* first we can move a new byte into s->c */ - if (s->pscd_ptr >= s->pscd_end) { - return -1; /* more bytes needed */ - } - if (*s->pscd_ptr == 0xff) - if (s->pscd_ptr + 1 >= s->pscd_end) { - return -1; /* final 0xff byte not processed */ - } else { - if (*(s->pscd_ptr + 1) == MARKER_STUFF) { - s->c |= 0xffL << (8 - s->ct); - s->ct += 8; - s->pscd_ptr += 2; - } else { - s->ct = -1; /* start padding with zero bytes */ - if (s->nopadding) { - s->nopadding = 0; - return -2; /* subsequent symbols might depend on zero padding */ - } - } - } - else { - s->c |= (long)*(s->pscd_ptr++) << (8 - s->ct); - s->ct += 8; - } - } - s->c <<= 1; - s->a <<= 1; - if (s->ct >= 0) s->ct--; - if (s->a == 0x10000L) - s->startup = 0; - } - - st = s->st + cx; - ss = *st & 0x7f; - assert(ss < 113); - lsz = lsztab[ss]; - -#if 0 - fprintf(stderr, "cx = %d, mps = %d, st = %3d, lsz = 0x%04x, a = 0x%05lx, " - "c = 0x%08lx, ct = %2d\n", - cx, !!(s->st[cx] & 0x80), ss, lsz, s->a, s->c, s->ct); -#endif - - if ((s->c >> 16) < (s->a -= lsz)) - if (s->a & 0xffff8000L) - return *st >> 7; - else { - /* MPS_EXCHANGE */ - if (s->a < lsz) { - pix = 1 - (*st >> 7); - /* Check whether MPS/LPS exchange is necessary - * and chose next probability estimator status */ - *st &= 0x80; - *st ^= nlpstab[ss]; - } else { - pix = *st >> 7; - *st &= 0x80; - *st |= nmpstab[ss]; - } - } - else { - /* LPS_EXCHANGE */ - if (s->a < lsz) { - s->c -= s->a << 16; - s->a = lsz; - pix = *st >> 7; - *st &= 0x80; - *st |= nmpstab[ss]; - } else { - s->c -= s->a << 16; - s->a = lsz; - pix = 1 - (*st >> 7); - /* Check whether MPS/LPS exchange is necessary - * and chose next probability estimator status */ - *st &= 0x80; - *st ^= nlpstab[ss]; - } - } - - return pix; -} diff --git a/thirdparty/jbigkit/libjbig/jbig_ar.h b/thirdparty/jbigkit/libjbig/jbig_ar.h deleted file mode 100644 index d58b1ae02..000000000 --- a/thirdparty/jbigkit/libjbig/jbig_ar.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Header file for the arithmetic encoder and decoder of - * the portable JBIG compression library - * - * Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/jbigkit/ - */ - -#ifndef JBG_AR_H -#define JBG_AR_H - -/* - * Status of arithmetic encoder - */ - -struct jbg_arenc_state { - unsigned char st[4096]; /* probability status for contexts, MSB = MPS */ - unsigned long c; /* register C: base of coding intervall, * - * layout as in Table 23 */ - unsigned long a; /* register A: normalized size of coding interval */ - long sc; /* number of buffered 0xff values that might still overflow */ - int ct; /* bit shift counter, determines when next byte will be written */ - int buffer; /* buffer for most recent output byte != 0xff */ - void (*byte_out)(int, void *); /* function that receives all PSCD bytes */ - void *file; /* parameter passed to byte_out */ -}; - -/* - * Status of arithmetic decoder - */ - -struct jbg_ardec_state { - unsigned char st[4096]; /* probability status for contexts, MSB = MPS */ - unsigned long c; /* register C: base of coding intervall, * - * layout as in Table 25 */ - unsigned long a; /* register A: normalized size of coding interval */ - unsigned char *pscd_ptr; /* pointer to next PSCD data byte */ - unsigned char *pscd_end; /* pointer to byte after PSCD */ - int ct; /* bit-shift counter, determines when next byte will be read; - * special value -1 signals that zero-padding has started */ - int startup; /* boolean flag that controls initial fill of s->c */ - int nopadding; /* boolean flag that triggers return -2 between - * reaching PSCD end and decoding the first symbol - * that might never have been encoded in the first - * place */ -}; - -void arith_encode_init(struct jbg_arenc_state *s, int reuse_st); -void arith_encode_flush(struct jbg_arenc_state *s); -void arith_encode(struct jbg_arenc_state *s, int cx, int pix); -void arith_decode_init(struct jbg_ardec_state *s, int reuse_st); -int arith_decode(struct jbg_ardec_state *s, int cx); - -#endif /* JBG_AR_H */ diff --git a/thirdparty/jbigkit/libjbig/po/README.txt b/thirdparty/jbigkit/libjbig/po/README.txt deleted file mode 100644 index 64ba523cd..000000000 --- a/thirdparty/jbigkit/libjbig/po/README.txt +++ /dev/null @@ -1,20 +0,0 @@ -Older versions of jbig.c contained a list of human-readable -result/error messages in both English and German. - -These messages are highly technical and unlikely to be of much use to -end users who are not familiar with the JBIG1 standard (which has only -been published in English, Spanish and French). Therefore, in the -interest of simplicity, since release 2.0 the source code contains in -errmsg[] now only the English version of these messages. - -The German version is preserved here in the form of a PO translation -file, as used by the GNU gettext package, just in case anyone still -finds it of use. - -See http://www.gnu.org/software/gettext/manual/gettext.html for -information on the PO file format and tools for creating and using -them. - -JBIG-KIT itself does not use gettext, but the included po files might -help users of the library to translate the strings returned by -jbg_strerror() or jbg85_strerror() into other languages. diff --git a/thirdparty/jbigkit/libjbig/po/de.po b/thirdparty/jbigkit/libjbig/po/de.po deleted file mode 100644 index f29ead8f4..000000000 --- a/thirdparty/jbigkit/libjbig/po/de.po +++ /dev/null @@ -1,52 +0,0 @@ -# German translations for jbigkit package -# Copyright (C) 2008 Markus Kuhn -# This file is distributed under the same license as the jbigkit package. -# -msgid "" -msgstr "" -"Project-Id-Version: jbigkit 2.0\n" -"Report-Msgid-Bugs-To: http://www.cl.cam.ac.uk/~mgk25/jbigkit/\n" -"POT-Creation-Date: 2014-03-24 15:35+0000\n" -"PO-Revision-Date: 2008-08-27 20:16+0100\n" -"Last-Translator: Markus Kuhn \n" -"Language: de\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#: jbig.c:98 jbig85.c:69 -msgid "All OK" -msgstr "Kein Problem" - -#: jbig.c:99 jbig85.c:70 -msgid "Reached specified image size" -msgstr "Angeforderte Bildgröße erreicht" - -#: jbig.c:100 jbig85.c:71 -msgid "Unexpected end of input data stream" -msgstr "Unerwartetes Ende des Eingabedatenstroms" - -#: jbig.c:101 jbig85.c:72 -msgid "Not enough memory available" -msgstr "Nicht genügend Speicher vorhanden" - -#: jbig.c:102 jbig85.c:73 -msgid "ABORT marker segment encountered" -msgstr "Es wurde eine Abbruch-Sequenz gefunden" - -#: jbig.c:103 jbig85.c:74 -msgid "Unknown marker segment encountered" -msgstr "Es wurde eine unbekannte Marker-Sequenz gefunden" - -#: jbig.c:104 jbig85.c:75 -msgid "Input data stream contains invalid data" -msgstr "Es wurden ungültige Daten gefunden" - -#: jbig.c:105 jbig85.c:76 -msgid "Input data stream uses unimplemented JBIG features" -msgstr "Eingabedatenstrom benutzt nicht implementierte JBIG Optionen" - -#: jbig.c:106 -msgid "Incremental BIE does not continue previous one" -msgstr "Neue Bilddaten passen nicht zu vorangegangenen" diff --git a/thirdparty/jbigkit/libjbig/po/pl.po b/thirdparty/jbigkit/libjbig/po/pl.po deleted file mode 100644 index 18864f44b..000000000 --- a/thirdparty/jbigkit/libjbig/po/pl.po +++ /dev/null @@ -1,51 +0,0 @@ -# Polish translation for jbigkit. -# This file is distributed under the same license as the jbigkit package. -# Jakub Bogusz , 2010-2014 -# -msgid "" -msgstr "" -"Project-Id-Version: jbigkit 2.0\n" -"Report-Msgid-Bugs-To: http://www.cl.cam.ac.uk/~mgk25/jbigkit/\n" -"POT-Creation-Date: 2014-03-24 15:35+0000\n" -"PO-Revision-Date: 2014-11-16 16:45+0100\n" -"Last-Translator: Jakub Bogusz \n" -"Language-Team: Polish \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: jbig.c:98 jbig85.c:69 -msgid "All OK" -msgstr "Poprawnie" - -#: jbig.c:99 jbig85.c:70 -msgid "Reached specified image size" -msgstr "OsiÄ…gniÄ™to okreÅ›lony rozmiar obrazu" - -#: jbig.c:100 jbig85.c:71 -msgid "Unexpected end of input data stream" -msgstr "Nieoczekiwany koniec strumienia danych wejÅ›ciowych" - -#: jbig.c:101 jbig85.c:72 -msgid "Not enough memory available" -msgstr "Zbyt maÅ‚o dostÄ™pnej pamiÄ™ci" - -#: jbig.c:102 jbig85.c:73 -msgid "ABORT marker segment encountered" -msgstr "Napotkano segment znacznika ABORT" - -#: jbig.c:103 jbig85.c:74 -msgid "Unknown marker segment encountered" -msgstr "Napotkano segment nieznanego znacznika" - -#: jbig.c:104 jbig85.c:75 -msgid "Input data stream contains invalid data" -msgstr "StrumieÅ„ danych wejÅ›ciowych zawiera błędne dane" - -#: jbig.c:105 jbig85.c:76 -msgid "Input data stream uses unimplemented JBIG features" -msgstr "StrumieÅ„ danych wejÅ›ciowych korzysta z niezaimplementowanych cech JBIG" - -#: jbig.c:106 -msgid "Incremental BIE does not continue previous one" -msgstr "Przyrostowe dane obrazu nie sÄ… kontynuacjÄ… poprzednich" diff --git a/thirdparty/jbigkit/libjbig/po/ru.po b/thirdparty/jbigkit/libjbig/po/ru.po deleted file mode 100644 index 6e0711398..000000000 --- a/thirdparty/jbigkit/libjbig/po/ru.po +++ /dev/null @@ -1,53 +0,0 @@ -# Russian translations for jbigkit package. -# This file is distributed under the same license as the jbigkit package. -# Russian translation by ghostmansd@gmil.com, -# with some changes by Sergei Skorobogatov. -# -msgid "" -msgstr "" -"Project-Id-Version: jbigkit 2.1\n" -"Report-Msgid-Bugs-To: http://www.cl.cam.ac.uk/~mgk25/jbigkit/\n" -"POT-Creation-Date: 2014-03-24 15:35+0000\n" -"PO-Revision-Date: 2014-03-21 18:06+0000\n" -"Language: ru\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" -"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" - -#: jbig.c:98 jbig85.c:69 -msgid "All OK" -msgstr "УÑпешное завершение" - -#: jbig.c:99 jbig85.c:70 -msgid "Reached specified image size" -msgstr "Указанный размер доÑтигнут" - -#: jbig.c:100 jbig85.c:71 -msgid "Unexpected end of input data stream" -msgstr "Ðеожиданный конец входного потока" - -#: jbig.c:101 jbig85.c:72 -msgid "Not enough memory available" -msgstr "ÐедоÑтаточно памÑти" - -#: jbig.c:102 jbig85.c:73 -msgid "ABORT marker segment encountered" -msgstr "Обнаружен Ñегмент прерываниÑ" - -#: jbig.c:103 jbig85.c:74 -msgid "Unknown marker segment encountered" -msgstr "Обнаружен неизвеÑтный Ñегмент" - -#: jbig.c:104 jbig85.c:75 -msgid "Input data stream contains invalid data" -msgstr "Входной поток Ñодержит неверные данные" - -#: jbig.c:105 jbig85.c:76 -msgid "Input data stream uses unimplemented JBIG features" -msgstr "Входной поток иÑпользует нереализованные функции" - -#: jbig.c:106 -msgid "Incremental BIE does not continue previous one" -msgstr "Следующий тип данных BIE не продолжает предыдущий" diff --git a/thirdparty/jbigkit/libjbig/tstcodec.c b/thirdparty/jbigkit/libjbig/tstcodec.c deleted file mode 100644 index 4e7bb74e7..000000000 --- a/thirdparty/jbigkit/libjbig/tstcodec.c +++ /dev/null @@ -1,550 +0,0 @@ -/* - * A sequence of test procedures for this JBIG implementation - * - * Run this test sequence after each modification on the JBIG library. - * - * Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/ - */ - -#include -#include -#include -#include - -#include "jbig.h" - -#define TESTBUF_SIZE 400000L -#define TESTPIC_SIZE 477995L - -#define FAILED "F\bFA\bAI\bIL\bLE\bED\bD" -#define PASSED "PASSED" - -unsigned char *testbuf; -unsigned char *testpic; - -long testbuf_len; - - -static void *checkedmalloc(size_t n) -{ - void *p; - - if ((p = malloc(n)) == NULL) { - fprintf(stderr, "Sorry, not enough memory available!\n"); - exit(1); - } - - return p; -} - -static void testbuf_write(int v, void *dummy) -{ - if (testbuf_len < TESTBUF_SIZE) - testbuf[testbuf_len++] = v; - (void) dummy; - return; -} - - -static void testbuf_writel(unsigned char *start, size_t len, void *dummy) -{ - if (testbuf_len < TESTBUF_SIZE) { - if (testbuf_len + len < TESTBUF_SIZE) - memcpy(testbuf + testbuf_len, start, len); - else - memcpy(testbuf + testbuf_len, start, TESTBUF_SIZE - testbuf_len); - } - testbuf_len += len; - -#ifdef DEBUG - { - unsigned char *p; - unsigned sum = 0; - - for (p = start; p - start < (ptrdiff_t) len; sum = (sum ^ *p++) << 1); - printf(" testbuf_writel: %4lu bytes, checksum %04x\n", - (unsigned long) len, sum & 0xffff); - } -#endif - - (void) dummy; - return; -} - - -/* - * Store the artificial test image defined in T.82, clause 7.2.1 at - * pic. The image requires 477995 bytes of memory, is 1960 x 1951 pixels - * large and has one plane. - */ -static void testimage(unsigned char *pic) -{ - unsigned long i, j, sum; - unsigned int prsg, repeat[8]; - unsigned char *p; - - memset(pic, 0, TESTPIC_SIZE); - p = pic; - prsg = 1; - for (j = 0; j < 1951; j++) - for (i = 0; i < 1960; i++) { - if (j >= 192) { - if (j < 1023 || ((i >> 3) & 3) == 0) { - sum = (prsg & 1) + ((prsg >> 2) & 1) + ((prsg >> 11) & 1) + - ((prsg >> 15) & 1); - prsg = (prsg << 1) + (sum & 1); - if ((prsg & 3) == 0) { - *p |= 1 << (7 - (i & 7)); - repeat[i & 7] = 1; - } else { - repeat[i & 7] = 0; - } - } else { - if (repeat[i & 7]) - *p |= 1 << (7 - (i & 7)); - } - } - if ((i & 7) == 7) ++p; - } - - /* verify test image */ - sum = 0; - for (i = 0; i < TESTPIC_SIZE; i++) - for (j = 0; j < 8; j++) - sum += (pic[i] >> j) & 1; - if (sum != 861965L) - printf("WARNING: Artificial test image has %lu (not 861965) " - "foreground pixels!\n", sum); - - return; -} - - -/* - * Perform a full test cycle with one set of parameters. Encode an image - * and compare the length of the result with correct_length. Then decode - * the image again both in one single chunk or byte by byte and compare - * the results with the original input image. - */ -static int test_cycle(unsigned char **orig_image, int width, int height, - int options, int order, int layers, int planes, - unsigned long l0, int mx, long correct_length, - const char *test_id) -{ - struct jbg_enc_state sje; - struct jbg_dec_state sjd; - int trouble = 0; - long l; - size_t plane_size; - int i, result; - unsigned char **image; - - plane_size = ((width + 7) / 8) * height; - image = (unsigned char **) checkedmalloc(planes * sizeof(unsigned char *)); - for (i = 0; i < planes; i++) { - image[i] = (unsigned char *) checkedmalloc(plane_size); - memcpy(image[i], orig_image[i], plane_size); - } - - printf("\nTest %s.1: Encoding ...\n", test_id); - testbuf_len = 0; - jbg_enc_init(&sje, width, height, planes, image, testbuf_writel, NULL); - jbg_enc_layers(&sje, layers); - jbg_enc_options(&sje, order, options, l0, mx, 0); - jbg_enc_out(&sje); - jbg_enc_free(&sje); - for (i = 0; i < planes; i++) - free(image[i]); - free(image); - printf("Encoded BIE has %6ld bytes: ", testbuf_len); - if (correct_length >= 0) - if (testbuf_len == correct_length) - puts(PASSED); - else { - trouble++; - printf(FAILED ", correct would have been %ld\n", correct_length); - } - else - puts(""); - - printf("Test %s.2: Decoding whole chunk ...\n", test_id); - jbg_dec_init(&sjd); - result = jbg_dec_in(&sjd, testbuf, testbuf_len, NULL); - if (result != JBG_EOK) { - printf("Decoder complained with return value %d: " FAILED "\n" - "Cause: '%s'\n", result, jbg_strerror(result)); - trouble++; - } else { - printf("Image comparison: "); - result = 1; - for (i = 0; i < planes; i++) { - if (memcmp(orig_image[i], sjd.lhp[layers & 1][i], - ((width + 7) / 8) * height)) { - result = 0; - trouble++; - printf(FAILED " for plane %d\n", i); - } - } - if (result) - puts(PASSED); - } - jbg_dec_free(&sjd); - - printf("Test %s.3: Decoding with single-byte feed ...\n", test_id); - jbg_dec_init(&sjd); - result = JBG_EAGAIN; - for (l = 0; l < testbuf_len; l++) { - result = jbg_dec_in(&sjd, testbuf + l, 1, NULL); - if (l < testbuf_len - 1 && result != JBG_EAGAIN) { - printf("Decoder complained with return value %d at byte %ld: " FAILED - "\nCause: '%s'\n", result, l, jbg_strerror(result)); - trouble++; - break; - } - } - if (l == testbuf_len) { - if (result != JBG_EOK) { - printf("Decoder complained with return value %d at final byte: " FAILED - "\nCause: '%s'\n", result, jbg_strerror(result)); - trouble++; - } else { - printf("Image comparison: "); - result = 1; - for (i = 0; i < planes; i++) { - if (memcmp(orig_image[i], sjd.lhp[layers & 1][i], - ((width + 7) / 8) * height)) { - result = 0; - trouble++; - printf(FAILED " for plane %d\n", i); - } - } - if (result) - puts(PASSED); - } - } - - jbg_dec_free(&sjd); - puts(""); - - return trouble != 0; -} - - -int main(int argc, char **argv) -{ - int trouble, problems = 0; - struct jbg_arenc_state *se; - struct jbg_ardec_state *sd; - long i; - int pix, order, layers; - char test[10]; - size_t st; - unsigned char *pp; - unsigned char *ppp[4]; - - int t82pix[16] = { - 0x05e0, 0x0000, 0x8b00, 0x01c4, 0x1700, 0x0034, 0x7fff, 0x1a3f, - 0x951b, 0x05d8, 0x1d17, 0xe770, 0x0000, 0x0000, 0x0656, 0x0e6a - }; - int t82cx[16] = { - 0x0fe0, 0x0000, 0x0f00, 0x00f0, 0xff00, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 - }; - unsigned char t82sde[32] = { - 0x69, 0x89, 0x99, 0x5c, 0x32, 0xea, 0xfa, 0xa0, - 0xd5, 0xff, 0x00, 0x52, 0x7f, 0xff, 0x00, 0xff, - 0x00, 0xff, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x3f, - 0xff, 0x00, 0x2d, 0x20, 0x82, 0x91, 0xff, 0x02 - }; - - /* three 23x5 pixel test images with the letters JBIG */ - unsigned char jbig_normal[15*4] = { - 0x7c, 0xe2, 0x38, 0x04, 0x92, 0x40, 0x04, 0xe2, 0x5c, 0x44, - 0x92, 0x44, 0x38, 0xe2, 0x38, - 0x7c, 0xe2, 0x38, 0x04, 0x92, 0x40, 0x04, 0xe2, 0x5c, 0x44, - 0x92, 0x44, 0x38, 0xe2, 0x38, - 0x7c, 0xe2, 0x38, 0x04, 0x92, 0x40, 0x04, 0xe2, 0x5c, 0x44, - 0x92, 0x44, 0x38, 0xe2, 0x38, - 0x7c, 0xe2, 0x38, 0x04, 0x92, 0x40, 0x04, 0xe2, 0x5c, 0x44, - 0x92, 0x44, 0x38, 0xe2, 0x38 - }; - unsigned char jbig_upsidedown[15*4] = { - 0x38, 0xe2, 0x38, 0x44, 0x92, 0x44, 0x04, 0xe2, 0x5c, 0x04, - 0x92, 0x40, 0x7c, 0xe2, 0x38, - 0x38, 0xe2, 0x38, 0x44, 0x92, 0x44, 0x04, 0xe2, 0x5c, 0x04, - 0x92, 0x40, 0x7c, 0xe2, 0x38, - 0x38, 0xe2, 0x38, 0x44, 0x92, 0x44, 0x04, 0xe2, 0x5c, 0x04, - 0x92, 0x40, 0x7c, 0xe2, 0x38, - 0x38, 0xe2, 0x38, 0x44, 0x92, 0x44, 0x04, 0xe2, 0x5c, 0x04, - 0x92, 0x40, 0x7c, 0xe2, 0x38 - }; - unsigned char jbig_inverse[15*4] = { - 0xff^0x7c, 0xff^0xe2, 0xfe^0x38, 0xff^0x04, 0xff^0x92, - 0xfe^0x40, 0xff^0x04, 0xff^0xe2, 0xfe^0x5c, 0xff^0x44, - 0xff^0x92, 0xfe^0x44, 0xff^0x38, 0xff^0xe2, 0xfe^0x38, - 0xff^0x7c, 0xff^0xe2, 0xfe^0x38, 0xff^0x04, 0xff^0x92, - 0xfe^0x40, 0xff^0x04, 0xff^0xe2, 0xfe^0x5c, 0xff^0x44, - 0xff^0x92, 0xfe^0x44, 0xff^0x38, 0xff^0xe2, 0xfe^0x38, - 0xff^0x7c, 0xff^0xe2, 0xfe^0x38, 0xff^0x04, 0xff^0x92, - 0xfe^0x40, 0xff^0x04, 0xff^0xe2, 0xfe^0x5c, 0xff^0x44, - 0xff^0x92, 0xfe^0x44, 0xff^0x38, 0xff^0xe2, 0xfe^0x38, - 0xff^0x7c, 0xff^0xe2, 0xfe^0x38, 0xff^0x04, 0xff^0x92, - 0xfe^0x40, 0xff^0x04, 0xff^0xe2, 0xfe^0x5c, 0xff^0x44, - 0xff^0x92, 0xfe^0x44, 0xff^0x38, 0xff^0xe2, 0xfe^0x38 - }; - int orders[] = { - 0, - JBG_ILEAVE, - JBG_ILEAVE | JBG_SMID, -#if 0 - JBG_SEQ, - JBG_SEQ | JBG_SMID, - JBG_SEQ | JBG_ILEAVE, - JBG_HITOLO, - JBG_HITOLO | JBG_ILEAVE, - JBG_HITOLO | JBG_ILEAVE | JBG_SMID, - JBG_HITOLO | JBG_SEQ, - JBG_HITOLO | JBG_SEQ | JBG_SMID, - JBG_HITOLO | JBG_SEQ | JBG_ILEAVE -#endif - }; - - printf("\nAutomatic JBIG Compatibility Test Suite\n" - "---------------------------------------\n\n" - "JBIG-KIT Version " JBG_VERSION - " -- This test may take a few minutes.\n\n\n"); - - /* allocate test buffer memory */ - testbuf = (unsigned char *) checkedmalloc(TESTBUF_SIZE); - testpic = (unsigned char *) checkedmalloc(TESTPIC_SIZE); - se = (struct jbg_arenc_state *) checkedmalloc(sizeof(struct jbg_arenc_state)); - sd = (struct jbg_ardec_state *) checkedmalloc(sizeof(struct jbg_ardec_state)); - - /* test a few properties of the machine architecture */ - testbuf[0] = 42; - testbuf[0x10000L] = 0x42; - st = 1 << 16; - testbuf[st]++; - pp = testbuf + 0x4000; - pp += 0x4000; - pp += 0x4000; - pp += 0x4000; - if (testbuf[0] != 42 || *pp != 0x43) { - printf("Porting error detected:\n\n" - "Pointer arithmetic with this compiler has not at least 32 bits!\n" - "Are you sure, you have not compiled this program on an 8-bit\n" - "or 16-bit architecture? This compiler mode can obviously not\n" - "handle arrays with a size of more than 65536 bytes. With this\n" - "memory model, JBIG-KIT can only handle very small images and\n" - "not even this compatibility test suite will run. :-(\n\n"); - exit(1); - } - - /* only supported command line option: - * output file name for exporting test image */ - if (argc > 1) { - FILE *f; - - puts("Generating test image ..."); - testimage(testpic); - printf("Storing in '%s' ...\n", argv[1]); - - /* write out test image as PBM file */ - f = fopen(argv[1], "wb"); - if (!f) abort(); - fprintf(f, "P4\n"); -#if 0 - fprintf(f, "# Test image as defined in ITU-T T.82, clause 7.2.1\n"); -#endif - fprintf(f, "%10lu\n%10lu\n", 1960LU, 1951LU); - fwrite(testpic, 1, TESTPIC_SIZE, f); - fclose(f); - exit(0); - } - -#if 1 - puts("1) Arithmetic encoder test sequence from ITU-T T.82, clause 7.1\n" - "---------------------------------------------------------------\n"); - arith_encode_init(se, 0); - testbuf_len = 0; - se->byte_out = testbuf_write; - for (i = 0; i < 16 * 16; i++) - arith_encode(se, (t82cx[i >> 4] >> ((15 - i) & 15)) & 1, - (t82pix[i >> 4] >> ((15 - i) & 15)) & 1); - arith_encode_flush(se); - printf("result of encoder:\n "); - for (i = 0; i < testbuf_len && i < TESTBUF_SIZE; i++) - printf("%02x", testbuf[i]); - printf("\nexpected result:\n "); - for (i = 0; i < 30; i++) - printf("%02x", t82sde[i]); - printf("\n\nTest 1: "); - if (testbuf_len != 30 || memcmp(testbuf, t82sde, 30)) { - problems++; - printf(FAILED); - } else - printf(PASSED); - printf("\n\n"); - - - puts("2) Arithmetic decoder test sequence from ITU-T T.82, clause 7.1\n" - "---------------------------------------------------------------\n"); - printf("Test 2.1: Decoding whole chunk ...\n"); - arith_decode_init(sd, 0); - sd->pscd_ptr = t82sde; - sd->pscd_end = t82sde + 32; - trouble = 0; - for (i = 0; i < 16 * 16 && !trouble; i++) { - pix = arith_decode(sd, (t82cx[i >> 4] >> ((15 - i) & 15)) & 1); - if (pix < 0) { - printf("Problem at pixel %ld, byte %ld.\n\n", - i+1, (long) (sd->pscd_ptr - sd->pscd_end)); - trouble++; - break; - } - if (pix != ((t82pix[i >> 4] >> ((15 - i) & 15)) & 1)) { - printf("Wrong PIX answer (%d) at pixel %ld.\n\n", pix, i+1); - trouble++; - break; - } - } - if (!trouble && sd->pscd_ptr != sd->pscd_end - 2) { - printf("%ld bytes left after decoder finished.\n\n", - (long) (sd->pscd_end - sd->pscd_ptr - 2)); - trouble++; - } - printf("Test result: "); - if (trouble) { - problems++; - puts(FAILED); - } else - puts(PASSED); - printf("\n"); - - printf("Test 2.2: Decoding with single byte feed ...\n"); - arith_decode_init(sd, 0); - pp = t82sde; - sd->pscd_ptr = pp; - sd->pscd_end = pp + 1; - trouble = 0; - for (i = 0; i < 16 * 16 && !trouble; i++) { - pix = arith_decode(sd, (t82cx[i >> 4] >> ((15 - i) & 15)) & 1); - while (pix < 0 && sd->pscd_end < t82sde + 32) { - pp++; - if (sd->pscd_ptr != pp - 1) - sd->pscd_ptr = pp; - sd->pscd_end = pp + 1; - pix = arith_decode(sd, (t82cx[i >> 4] >> ((15 - i) & 15)) & 1); - } - if (pix < 0) { - printf("Problem at pixel %ld, byte %ld.\n\n", - i+1, (long) (sd->pscd_ptr - sd->pscd_end)); - trouble++; - break; - } - if (pix != ((t82pix[i >> 4] >> ((15 - i) & 15)) & 1)) { - printf("Wrong PIX answer (%d) at pixel %ld.\n\n", pix, i+1); - trouble++; - break; - } - } - if (!trouble && sd->pscd_ptr != sd->pscd_end - 2) { - printf("%ld bytes left after decoder finished.\n\n", - (long) (sd->pscd_end - sd->pscd_ptr - 2)); - trouble++; - } - printf("Test result: "); - if (trouble) { - problems++; - puts(FAILED); - } else - puts(PASSED); - printf("\n"); - - puts("3) Parametric algorithm test sequence from ITU-T T.82, clause 7.2\n" - "-----------------------------------------------------------------\n"); - puts("Generating test image ..."); - testimage(testpic); - putchar('\n'); - pp = testpic; - - puts("Test 3.1: TPBON=0, Mx=0, LRLTWO=0, L0=1951, 0 layers"); - problems += test_cycle(&pp, 1960, 1951, JBG_DELAY_AT, - 0, 0, 1, 1951, 0, 317384L, "3.1"); - puts("Test 3.2: TPBON=0, Mx=0, LRLTWO=1, L0=1951, 0 layers"); - problems += test_cycle(&pp, 1960, 1951, JBG_DELAY_AT | JBG_LRLTWO, - 0, 0, 1, 1951, 0, 317132L, "3.2"); - puts("Test 3.3: TPBON=1, Mx=8, LRLTWO=0, L0=128, 0 layers"); - problems += test_cycle(&pp, 1960, 1951, JBG_DELAY_AT | JBG_TPBON, - 0, 0, 1, 128, 8, 253653L, "3.3"); - puts("Test 3.4: TPBON=1, DPON=1, TPDON=1, Mx=8, LRLTWO=0, L0=2, 6 layers"); - problems += test_cycle(&pp, 1960, 1951, - JBG_DELAY_AT | JBG_TPBON | JBG_TPDON | JBG_DPON, - 0, 6, 1, 2, 8, 279314L, "3.4"); - puts("Test 3.5: as Test 3.4 but with DPPRIV=1"); - problems += test_cycle(&pp, 1960, 1951, - JBG_DELAY_AT | JBG_TPBON | JBG_TPDON | JBG_DPON | - JBG_DPPRIV, - 0, 6, 1, 2, 8, 279314L + 1728, "3.5"); -#if 0 /* Note: option SEQ is currently not supported by the decoder */ - puts("Test 3.6: as Test 3.4 but with order bit SEQ set"); - problems += test_cycle(&pp, 1960, 1951, - JBG_DELAY_AT | JBG_TPBON | JBG_TPDON | JBG_DPON, - JBG_SEQ, 6, 1, 2, 8, 279314L, "3.6"); -#endif -#endif - - puts("4) Same T.82 tests with SDRST instead of SDNORM\n" - "-----------------------------------------------\n"); - - puts("Test 4.0: TPBON=1, Mx=8, LRLTWO=0, L0=128, 0 layers"); - problems += test_cycle(&pp, 1960, 1951, JBG_SDRST | JBG_TPBON, - 0, 0, 1, 128, 8, -1, "4.0"); - - puts("Test 4.1: TPBON=0, Mx=0, LRLTWO=0, L0=1951, 0 layers"); - problems += test_cycle(&pp, 1960, 1951, JBG_SDRST, - 0, 0, 1, 1951, 0, -1, "4.1"); - puts("Test 4.2: TPBON=0, Mx=0, LRLTWO=1, L0=1951, 0 layers"); - problems += test_cycle(&pp, 1960, 1951, JBG_LRLTWO | JBG_SDRST, - 0, 0, 1, 1951, 0, -1, "4.2"); - puts("Test 4.3: TPBON=1, Mx=8, LRLTWO=0, L0=128, 0 layers"); - problems += test_cycle(&pp, 1960, 1951, JBG_TPBON | JBG_SDRST, - 0, 0, 1, 128, 8, -1, "4.3"); - puts("Test 4.4: TPBON=1, DPON=1, TPDON=1, Mx=8, LRLTWO=0, L0=2, 6 layers"); - problems += test_cycle(&pp, 1960, 1951, - JBG_TPBON | JBG_TPDON | - JBG_DPON | JBG_SDRST, - 0, 6, 1, 2, 8, -1, "4.4"); - - puts("5) Small test image, 0-3 layers, 4 planes, different orders\n" - "-----------------------------------------------------------\n"); - - /* test a simple multi-plane image */ - ppp[0] = jbig_normal; - ppp[1] = jbig_upsidedown; - ppp[2] = jbig_inverse; - ppp[3] = jbig_inverse; - - i = 0; - for (layers = 0; layers <= 3; layers++) - for (order = 0; order < (int) (sizeof(orders)/sizeof(int)); order++) { - sprintf(test, "5.%ld", ++i); - printf("Test %s: order=%d, %d layers, 4 planes", test, orders[order], - layers); - problems += test_cycle(ppp, 23, 5*4, JBG_TPBON | JBG_TPDON | JBG_DPON, - orders[order], layers, 4, 2, 8, -1, test); - } - - - printf("\nTest result summary: the library has %s the test suite.\n\n", - problems ? FAILED : PASSED); - if (problems) - puts("This is bad. If you cannot identify the problem yourself, please " - "send\nthis output plus a detailed description of your " - "compile environment\n(OS, compiler, version, options, etc.) to " - "Markus Kuhn\n."); - else - puts("Congratulations, everything is fine.\n"); - - return problems != 0; -} diff --git a/thirdparty/jbigkit/libjbig/tstcodec85.c b/thirdparty/jbigkit/libjbig/tstcodec85.c deleted file mode 100644 index 7e4940328..000000000 --- a/thirdparty/jbigkit/libjbig/tstcodec85.c +++ /dev/null @@ -1,450 +0,0 @@ -/* - * A sequence of test procedures for this JBIG implementation - * - * Run this test sequence after each modification on the JBIG library. - * - * Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/ - */ - -#include -#include -#include -#include -#include - -#include "jbig85.h" - -#define TESTBUF_SIZE 400000L -#define TESTPIC_SIZE 477995L - -#define FAILED "F\bFA\bAI\bIL\bLE\bED\bD" -#define PASSED "PASSED" - -unsigned char *testbuf; -unsigned char *testpic; - -long testbuf_len; - - -static void *checkedmalloc(size_t n) -{ - void *p; - - if ((p = calloc(1, n)) == NULL) { - fprintf(stderr, "Sorry, not enough memory available!\n"); - exit(1); - } - - return p; -} - -static void testbuf_write(int v, void *dummy) -{ - if (testbuf_len < TESTBUF_SIZE) - testbuf[testbuf_len++] = v; - (void) dummy; - return; -} - - -static void testbuf_writel(unsigned char *start, size_t len, void *dummy) -{ - if (testbuf_len < TESTBUF_SIZE) { - if (testbuf_len + len < TESTBUF_SIZE) - memcpy(testbuf + testbuf_len, start, len); - else - memcpy(testbuf + testbuf_len, start, TESTBUF_SIZE - testbuf_len); - } - testbuf_len += len; - -#ifdef DEBUG - { - unsigned char *p; - unsigned sum = 0; - - for (p = start; p - start < (ptrdiff_t) len; sum = (sum ^ *p++) << 1); - printf(" testbuf_writel: %4lu bytes, checksum %04x\n", - (unsigned long) len, sum & 0xffff); - } -#endif - - (void) dummy; - return; -} - - -static int line_out(const struct jbg85_dec_state *s, - unsigned char *start, size_t len, - unsigned long y, void *bitmap) -{ - assert(jbg85_dec_validwidth(s)); - assert(len == (jbg85_dec_getwidth(s) >> 3) + !!(jbg85_dec_getwidth(s) & 7)); - assert(y < jbg85_dec_getheight(s)); - memcpy((unsigned char *) bitmap + len * y, start, len); - return 0; -} - - -/* - * Store the artificial test image defined in T.82, clause 7.2.1 at - * pic. The image requires 477995 bytes of memory, is 1960 x 1951 pixels - * large and has one plane. - */ -static void testimage(unsigned char *pic) -{ - unsigned long i, j, sum; - unsigned int prsg, repeat[8]; - unsigned char *p; - - memset(pic, 0, TESTPIC_SIZE); - p = pic; - prsg = 1; - for (j = 0; j < 1951; j++) - for (i = 0; i < 1960; i++) { - if (j >= 192) { - if (j < 1023 || ((i >> 3) & 3) == 0) { - sum = (prsg & 1) + ((prsg >> 2) & 1) + ((prsg >> 11) & 1) + - ((prsg >> 15) & 1); - prsg = (prsg << 1) + (sum & 1); - if ((prsg & 3) == 0) { - *p |= 1 << (7 - (i & 7)); - repeat[i & 7] = 1; - } else { - repeat[i & 7] = 0; - } - } else { - if (repeat[i & 7]) - *p |= 1 << (7 - (i & 7)); - } - } - if ((i & 7) == 7) ++p; - } - - /* verify test image */ - sum = 0; - for (i = 0; i < TESTPIC_SIZE; i++) - for (j = 0; j < 8; j++) - sum += (pic[i] >> j) & 1; - if (sum != 861965L) - printf("WARNING: Artificial test image has %lu (not 861965) " - "foreground pixels!\n", sum); - - return; -} - - -/* - * Perform a full test cycle with one set of parameters. Encode an image - * and compare the length of the result with correct_length. Then decode - * the image again both in one single chunk or byte by byte and compare - * the results with the original input image. - */ -static int test_cycle(unsigned char *orig_image, int width, int height, - int options, unsigned long l0, int mx, - long correct_length, const char *test_id) -{ - struct jbg85_enc_state sje; - struct jbg85_dec_state sjd; - int trouble = 0; - long l; - size_t plane_size, buffer_len; - int i, result; - unsigned char *image, *buffer; - size_t bpl; - size_t cnt; - - bpl = (width + 7) / 8; - plane_size = bpl * height; - image = (unsigned char *) checkedmalloc(plane_size); - memcpy(image, orig_image, plane_size); - - printf("\nTest-85 %s.1: Encoding ...\n", test_id); - testbuf_len = 0; - jbg85_enc_init(&sje, width, height, testbuf_writel, NULL); - jbg85_enc_options(&sje, options, l0, mx); - for (i = 0; i < height; i++) - jbg85_enc_lineout(&sje, - image + i * bpl, - image + (i-1) * bpl, - image + (i-2) * bpl); - free(image); - printf("Encoded BIE has %6ld bytes: ", testbuf_len); - if (correct_length >= 0) - if (testbuf_len == correct_length) - puts(PASSED); - else { - trouble++; - printf(FAILED ", correct would have been %ld\n", correct_length); - } - else - puts(""); - -#if 1 - buffer_len = ((width >> 3) + !!(width & 7)) * 3; - buffer = (unsigned char *) checkedmalloc(buffer_len); - image = (unsigned char *) checkedmalloc(plane_size); - printf("Test-85 %s.2: Decoding whole chunk ...\n", test_id); - jbg85_dec_init(&sjd, buffer, buffer_len, line_out, image); - result = jbg85_dec_in(&sjd, testbuf, testbuf_len, &cnt); - if (result != JBG_EOK) { - printf("Decoder complained with return value 0x%02x: " - FAILED "\nCause: '%s'\n", result, jbg85_strerror(result)); - printf("%ld bytes of BIE read, %lu lines decoded.\n", - (long) cnt, sjd.y); - trouble++; - } else { - printf("Image comparison: "); - result = 1; - if (memcmp(orig_image, image, plane_size)) { - result = 0; - trouble++; - printf(FAILED); - } - if (result) - puts(PASSED); - } - free(image); - - image = (unsigned char *) checkedmalloc(plane_size); - printf("Test-85 %s.3: Decoding with single-byte feed ...\n", test_id); - jbg85_dec_init(&sjd, buffer, buffer_len, line_out, image); - result = JBG_EAGAIN; - for (l = 0; l < testbuf_len; l++) { - result = jbg85_dec_in(&sjd, testbuf + l, 1, NULL); - if (l < testbuf_len - 1 && result != JBG_EAGAIN) { - printf("Decoder complained with return value 0x%02x at byte %ld: " - FAILED "\nCause: '%s'\n", result, l, jbg85_strerror(result)); - trouble++; - break; - } - } - if (l == testbuf_len) { - if (result != JBG_EOK) { - printf("Decoder complained with return value 0x%02x at final byte: " - FAILED "\nCause: '%s'\n", result, jbg85_strerror(result)); - trouble++; - } else { - printf("Image comparison: "); - result = 1; - if (memcmp(orig_image, image, plane_size)) { - result = 0; - trouble++; - printf(FAILED); - } - if (result) - puts(PASSED); - } - } - free(image); - -#endif - puts(""); - - return trouble != 0; -} - - -int main(int argc, char **argv) -{ - int trouble, problems = 0; - struct jbg_arenc_state *se; - struct jbg_ardec_state *sd; - long i; - int pix; - unsigned char *pp; - - int t82pix[16] = { - 0x05e0, 0x0000, 0x8b00, 0x01c4, 0x1700, 0x0034, 0x7fff, 0x1a3f, - 0x951b, 0x05d8, 0x1d17, 0xe770, 0x0000, 0x0000, 0x0656, 0x0e6a - }; - int t82cx[16] = { - 0x0fe0, 0x0000, 0x0f00, 0x00f0, 0xff00, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 - }; - unsigned char t82sde[32] = { - 0x69, 0x89, 0x99, 0x5c, 0x32, 0xea, 0xfa, 0xa0, - 0xd5, 0xff, 0x00, 0x52, 0x7f, 0xff, 0x00, 0xff, - 0x00, 0xff, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x3f, - 0xff, 0x00, 0x2d, 0x20, 0x82, 0x91, 0xff, 0x02 - }; - - printf("\nAutomatic JBIG Compatibility Test Suite\n" - "---------------------------------------\n\n" - "JBIG-KIT Version " JBG85_VERSION " (T.85 version)" - " -- This test may take a few minutes.\n\n\n"); - - /* allocate test buffer memory */ - testbuf = (unsigned char *) checkedmalloc(TESTBUF_SIZE); - testpic = (unsigned char *) checkedmalloc(TESTPIC_SIZE); - se = (struct jbg_arenc_state *) checkedmalloc(sizeof(struct jbg_arenc_state)); - sd = (struct jbg_ardec_state *) checkedmalloc(sizeof(struct jbg_ardec_state)); - - /* only supported command line option: - * output file name for exporting test image */ - if (argc > 1) { - FILE *f; - - puts("Generating test image ..."); - testimage(testpic); - printf("Storing in '%s' ...\n", argv[1]); - - /* write out test image as PBM file */ - f = fopen(argv[1], "wb"); - if (!f) abort(); - fprintf(f, "P4\n"); -#if 0 - fprintf(f, "# Test image as defined in ITU-T T.82, clause 7.2.1\n"); -#endif - fprintf(f, "1960 1951\n"); - fwrite(testpic, 1, TESTPIC_SIZE, f); - fclose(f); - exit(0); - } - -#if 1 - puts("1) Arithmetic encoder test sequence from ITU-T T.82, clause 7.1\n" - "---------------------------------------------------------------\n"); - arith_encode_init(se, 0); - testbuf_len = 0; - se->byte_out = testbuf_write; - for (i = 0; i < 16 * 16; i++) - arith_encode(se, (t82cx[i >> 4] >> ((15 - i) & 15)) & 1, - (t82pix[i >> 4] >> ((15 - i) & 15)) & 1); - arith_encode_flush(se); - printf("result of encoder:\n "); - for (i = 0; i < testbuf_len && i < TESTBUF_SIZE; i++) - printf("%02x", testbuf[i]); - printf("\nexpected result:\n "); - for (i = 0; i < 30; i++) - printf("%02x", t82sde[i]); - printf("\n\nTest 1: "); - if (testbuf_len != 30 || memcmp(testbuf, t82sde, 30)) { - problems++; - printf(FAILED); - } else - printf(PASSED); - printf("\n\n"); - - - puts("2) Arithmetic decoder test sequence from ITU-T T.82, clause 7.1\n" - "---------------------------------------------------------------\n"); - printf("Test 2.1: Decoding whole chunk ...\n"); - arith_decode_init(sd, 0); - sd->pscd_ptr = t82sde; - sd->pscd_end = t82sde + 32; - trouble = 0; - for (i = 0; i < 16 * 16 && !trouble; i++) { - pix = arith_decode(sd, (t82cx[i >> 4] >> ((15 - i) & 15)) & 1); - if (pix < 0) { - printf("Problem at pixel %ld, byte %ld.\n\n", - i+1, (long) (sd->pscd_ptr - sd->pscd_end)); - trouble++; - break; - } - if (pix != ((t82pix[i >> 4] >> ((15 - i) & 15)) & 1)) { - printf("Wrong PIX answer (%d) at pixel %ld.\n\n", pix, i+1); - trouble++; - break; - } - } - if (!trouble && sd->pscd_ptr != sd->pscd_end - 2) { - printf("%ld bytes left after decoder finished.\n\n", - (long) (sd->pscd_end - sd->pscd_ptr - 2)); - trouble++; - } - printf("Test result: "); - if (trouble) { - problems++; - puts(FAILED); - } else - puts(PASSED); - printf("\n"); - - printf("Test 2.2: Decoding with single byte feed ...\n"); - arith_decode_init(sd, 0); - pp = t82sde; - sd->pscd_ptr = pp; - sd->pscd_end = pp + 1; - trouble = 0; - for (i = 0; i < 16 * 16 && !trouble; i++) { - pix = arith_decode(sd, (t82cx[i >> 4] >> ((15 - i) & 15)) & 1); - while (pix < 0 && sd->pscd_end < t82sde + 32) { - pp++; - if (sd->pscd_ptr != pp - 1) - sd->pscd_ptr = pp; - sd->pscd_end = pp + 1; - pix = arith_decode(sd, (t82cx[i >> 4] >> ((15 - i) & 15)) & 1); - } - if (pix < 0) { - printf("Problem at pixel %ld, byte %ld.\n\n", - i+1, (long) (sd->pscd_ptr - sd->pscd_end)); - trouble++; - break; - } - if (pix != ((t82pix[i >> 4] >> ((15 - i) & 15)) & 1)) { - printf("Wrong PIX answer (%d) at pixel %ld.\n\n", pix, i+1); - trouble++; - break; - } - } - if (!trouble && sd->pscd_ptr != sd->pscd_end - 2) { - printf("%ld bytes left after decoder finished.\n\n", - (long) (sd->pscd_end - sd->pscd_ptr - 2)); - trouble++; - } - printf("Test result: "); - if (trouble) { - problems++; - puts(FAILED); - } else - puts(PASSED); - printf("\n"); - - puts("3) Parametric algorithm test sequence from ITU-T T.82, clause 7.2\n" - "-----------------------------------------------------------------\n"); - puts("Generating test image ..."); - testimage(testpic); - putchar('\n'); - - puts("Test-85 3.1: TPBON=0, Mx=0, LRLTWO=0, L0=1951, 0 layers"); - problems += test_cycle(testpic, 1960, 1951, 0, - 1951, 0, 317384L, "3.1"); - puts("Test-85 3.2: TPBON=0, Mx=0, LRLTWO=1, L0=1951, 0 layers"); - problems += test_cycle(testpic, 1960, 1951, JBG_LRLTWO, - 1951, 0, 317132L, "3.2"); - puts("Test-85 3.3: TPBON=1, Mx=8, LRLTWO=0, L0=128, 0 layers"); - problems += test_cycle(testpic, 1960, 1951, JBG_TPBON, - 128, 8, 253653L, "3.3"); -#endif - -#if 0 - puts("4) Same T.82 tests with SDRST instead of SDNORM\n" - "-----------------------------------------------\n"); - - puts("Test-85 4.0: TPBON=1, Mx=8, LRLTWO=0, L0=128, 0 layers"); - problems += test_cycle(&pp, 1960, 1951, JBG_SDRST | JBG_TPBON, - 128, 8, -1, "4.0"); - - puts("Test-85 4.1: TPBON=0, Mx=0, LRLTWO=0, L0=1951, 0 layers"); - problems += test_cycle(&pp, 1960, 1951, JBG_SDRST, - 1951, 0, -1, "4.1"); - puts("Test-85 4.2: TPBON=0, Mx=0, LRLTWO=1, L0=1951, 0 layers"); - problems += test_cycle(&pp, 1960, 1951, JBG_LRLTWO | JBG_SDRST, - 1951, 0, -1, "4.2"); - puts("Test-85 4.3: TPBON=1, Mx=8, LRLTWO=0, L0=128, 0 layers"); - problems += test_cycle(&pp, 1960, 1951, JBG_TPBON | JBG_SDRST, - 128, 8, -1, "4.3"); -#endif - - printf("\nTest result summary: the T.85 library has %s the test suite.\n\n", - problems ? FAILED : PASSED); - if (problems) - puts("This is bad. If you cannot identify the problem yourself, please " - "send\nthis output plus a detailed description of your " - "compile environment\n(OS, compiler, version, options, etc.) to " - "Markus Kuhn\n."); - else - puts("Congratulations, everything is fine.\n"); - - return problems != 0; -} diff --git a/thirdparty/jbigkit/libjbig/tstjoint.c b/thirdparty/jbigkit/libjbig/tstjoint.c deleted file mode 100644 index 511d2947d..000000000 --- a/thirdparty/jbigkit/libjbig/tstjoint.c +++ /dev/null @@ -1,14 +0,0 @@ -/* - * This test file exists to check for any compile-time problems - * when linking an application with both jbig.c and jbig85.c simultanenously. - * - * Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/ - */ - -#include "jbig.h" -#include "jbig85.h" - -int main() -{ - return 0; -} diff --git a/thirdparty/jbigkit/pbmtools/Makefile b/thirdparty/jbigkit/pbmtools/Makefile deleted file mode 100644 index 95545a486..000000000 --- a/thirdparty/jbigkit/pbmtools/Makefile +++ /dev/null @@ -1,182 +0,0 @@ -# GNU makefile for the JBIG-KIT PBM tools - -.DELETE_ON_ERROR: - -# Select an ANSI/ISO C compiler here, e.g. GNU gcc is recommended -CC = gcc - -# Options for the compiler -CFLAGS = -g -O -W -Wall -Wno-unused-result -ansi -pedantic # --coverage -CPPFLAGS = -I../libjbig -LDFLAGS = -L../libjbig - -.PHONY: txt pdf test test82 test85 clean - -all: pbmtojbg jbgtopbm pbmtojbg85 jbgtopbm85 txt - -txt: pbmtojbg.txt jbgtopbm.txt pbm.txt pgm.txt - -pdf: pbmtojbg.pdf jbgtopbm.pdf pbm.pdf pgm.pdf - -pbmtojbg: pbmtojbg.o ../libjbig/libjbig.a - $(CC) $(LDFLAGS) $(CFLAGS) -o pbmtojbg pbmtojbg.o -ljbig - -jbgtopbm: jbgtopbm.o ../libjbig/libjbig.a - $(CC) $(LDFLAGS) $(CFLAGS) -o jbgtopbm jbgtopbm.o -ljbig - -pbmtojbg85: pbmtojbg85.o ../libjbig/libjbig85.a - $(CC) $(LDFLAGS) $(CFLAGS) -o pbmtojbg85 pbmtojbg85.o -ljbig85 - -jbgtopbm85: jbgtopbm85.o ../libjbig/libjbig85.a - $(CC) $(LDFLAGS) $(CFLAGS) -o jbgtopbm85 jbgtopbm85.o -ljbig85 - -jbgtopbm.o: jbgtopbm.c ../libjbig/jbig.h -pbmtojbg.o: pbmtojbg.c ../libjbig/jbig.h -jbgtopbm85.o: jbgtopbm85.c ../libjbig/jbig85.h -pbmtojbg85.o: pbmtojbg85.c ../libjbig/jbig85.h - -../libjbig/libjbig.a: ../libjbig/jbig.c ../libjbig/jbig.h \ - ../libjbig/jbig_ar.c ../libjbig/jbig_ar.h - $(MAKE) -C ../libjbig libjbig.a - -../libjbig/libjbig85.a: ../libjbig/jbig85.c ../libjbig/jbig85.h \ - ../libjbig/jbig_ar.c ../libjbig/jbig_ar.h - $(MAKE) -C ../libjbig libjbig85.a - -analyze: - clang $(CPPFLAGS) --analyze *.c - -test: test82 test85 - -test82: pbmtojbg jbgtopbm - $(MAKE) IMG=ccitt1 OPTIONSP= dotest1 - $(MAKE) IMG=ccitt2 OPTIONSP= dotest1 - $(MAKE) IMG=ccitt3 OPTIONSP= dotest1 - $(MAKE) IMG=xvlogo "OPTIONSP=-d 3" dotest1 - $(MAKE) IMG=sandra OPTIONSP= OPTIONSJ= dotest2g - $(MAKE) IMG=sandra OPTIONSP=-b OPTIONSJ=-b dotest2g - $(MAKE) IMG=sandra OPTIONSP=-q OPTIONSJ= dotest2g - $(MAKE) IMG=sandra "OPTIONSP=-o 0" OPTIONSJ= dotest2g - $(MAKE) IMG=sandra "OPTIONSP=-o 2" OPTIONSJ= dotest2g - $(MAKE) IMG=multi OPTIONSP= OPTIONSJ= dotest2g - $(MAKE) IMG=multi OPTIONSP=-b OPTIONSJ=-b dotest2g - $(MAKE) IMG=mx "OPTIONSP=-q -s 3 -m 127" dotest1 - $(MAKE) IMG=mx "OPTIONSP=-q -s 3 -m 127" dotest2b - $(MAKE) IMG=mx "OPTIONSP=-q -s 3 -m 127 -p 92" dotest2b - $(MAKE) IMG=mx "OPTIONSP=-q -Y -1" dotest2b - $(MAKE) IMG=mx "OPTIONSP=-Y -1" dotest2b - rm -f test-*.jbg test-*.pbm test-*.pgm - ./jbgtopbm ../examples/ccitt1.jbg | ./pbmtojbg > test-ccitt1.jbg - cmp ../examples/ccitt1.jbg test-ccitt1.jbg - rm -f test-*.jbg test-*.pbm test-*.pgm - ./jbgtopbm < ../examples/ccitt1.jbg | ./pbmtojbg - test-ccitt1.jbg - cmp ../examples/ccitt1.jbg test-ccitt1.jbg - rm -f test-*.jbg test-*.pbm test-*.pgm - ./jbgtopbm < ../examples/ccitt1.jbg - test-ccitt1.pbm ; \ - ./pbmtojbg test-ccitt1.pbm test-ccitt1.jbg - cmp ../examples/ccitt1.jbg test-ccitt1.jbg - rm -f test-*.jbg test-*.pbm test-*.pgm - ./jbgtopbm ../examples/ccitt1.jbg test-ccitt1.pbm ; \ - ./pbmtojbg test-ccitt1.pbm >test-ccitt1.jbg - cmp ../examples/ccitt1.jbg test-ccitt1.jbg - rm -f test-*.jbg test-*.pbm test-*.pgm - @echo - @echo "The pbmtools have PASSED the functional tests. Good!" - @echo - -dotest1: - ./jbgtopbm ../examples/$(IMG).jbg test-$(IMG).pbm - ./pbmtojbg $(OPTIONSP) test-$(IMG).pbm test-$(IMG).jbg - cmp test-$(IMG).jbg ../examples/$(IMG).jbg - -dotest2b: - ./pbmtojbg $(OPTIONSP) test-$(IMG).pbm test-$(IMG).jbg - ./jbgtopbm $(OPTIONSJ) test-$(IMG).jbg test-$(IMG)-2.pbm - cmp test-$(IMG).pbm test-$(IMG)-2.pbm - -dotest2g: - ./pbmtojbg $(OPTIONSP) ../examples/$(IMG).pgm test-$(IMG).jbg - ./jbgtopbm $(OPTIONSJ) test-$(IMG).jbg test-$(IMG).pgm - cmp test-$(IMG).pgm ../examples/$(IMG).pgm - -test85: pbmtojbg jbgtopbm pbmtojbg85 jbgtopbm85 test-t82.pbm - $(MAKE) IMG=t82 "OPTIONSP=-p 0" dotest85 - $(MAKE) IMG=t82 "OPTIONSP=-p 8" dotest85 - $(MAKE) IMG=t82 "OPTIONSP=-p 8 -r" dotest85b - $(MAKE) IMG=t82 "OPTIONSP=-p 64" dotest85 - $(MAKE) IMG=t82 "OPTIONSP=-p 72" dotest85 - $(MAKE) IMG=t82 "OPTIONSP=-s 2 -C c" dotest85 - $(MAKE) IMG=t82 "OPTIONSP=-s 99999" dotest85 - $(MAKE) IMG=t82 "OPTIONSP=-Y 9999 0" dotest85 - $(MAKE) IMG=t82 "OPTIONSP=-Y 1951 0" dotest85 - $(MAKE) IMG=t82 "OPTIONSP=-Y -1 127" dotest85 - $(MAKE) IMG=t82 "OPTIONSP=-Y -1 128" dotest85 - $(MAKE) IMG=t82 "OPTIONSP=-Y -1 1919" dotest85 - $(MAKE) IMG=t82 "OPTIONSP=-Y -1 1920" dotest85 - $(MAKE) IMG=t82 "OPTIONSP=-Y -1 1949" dotest85 - $(MAKE) IMG=t82 "OPTIONSP=-Y -1 1950" dotest85 - $(MAKE) IMG=ccitt1 dotest85 - $(MAKE) IMG=ccitt2 dotest85 - $(MAKE) IMG=ccitt3 dotest85 - rm -f test-*.jbg test-*.jbg85 test-*.pbm - @echo - @echo "The T.85 pbmtools have PASSED the functional tests. Good!" - @echo - -dotest85: test-$(IMG).pbm - ./pbmtojbg85 $(OPTIONSP) test-$(IMG).pbm test-$(IMG).jbg85 - ls -l test-$(IMG).jbg85 - ./jbgtopbm test-$(IMG).jbg85 test-$(IMG).pbm85 - cmp test-$(IMG).pbm test-$(IMG).pbm85 - rm test-$(IMG).pbm85 - ./jbgtopbm85 test-$(IMG).jbg85 test-$(IMG).pbm85 - cmp test-$(IMG).pbm test-$(IMG).pbm85 - rm test-$(IMG).pbm85 - ./jbgtopbm85 -B 1 test-$(IMG).jbg85 test-$(IMG).pbm85 - cmp test-$(IMG).pbm test-$(IMG).pbm85 - -dotest85b: test-$(IMG).pbm - ./pbmtojbg -f $(OPTIONSP) test-$(IMG).pbm test-$(IMG).jbg85 - ls -l test-$(IMG).jbg85 - ./jbgtopbm test-$(IMG).jbg85 test-$(IMG).pbm85 - cmp test-$(IMG).pbm test-$(IMG).pbm85 - rm test-$(IMG).pbm85 - ./jbgtopbm85 test-$(IMG).jbg85 test-$(IMG).pbm85 - cmp test-$(IMG).pbm test-$(IMG).pbm85 - rm test-$(IMG).pbm85 - ./jbgtopbm85 -B 1 test-$(IMG).jbg85 test-$(IMG).pbm85 - cmp test-$(IMG).pbm test-$(IMG).pbm85 - -test-%.pbm: ../examples/%.jbg - ./jbgtopbm $< $@ - -test-t82.pbm: - $(MAKE) -C ../libjbig tstcodec - ../libjbig/tstcodec $@ - -FOPT=-c 1000 -p 300000 -m 3 -fuzz: test-t82.pbm - while \ - ./pbmtojbg -f test-t82.pbm | ./jbgfuzz.pl $(FOPT) && \ - ./pbmtojbg test-t82.pbm | ./jbgfuzz.pl $(FOPT) -d jbgtopbm ; \ - do true; done - -MAN2TXT=groff -man -Tascii -P -c -P -b -P -u -%.txt: %.1 - $(MAN2TXT) $< >$@ -%.txt: %.5 - $(MAN2TXT) $< >$@ -MAN2PS=groff -man -Tps -%.ps: %.1 - $(MAN2PS) $< >$@ -%.ps: %.5 - $(MAN2PS) $< >$@ -%.pdf: %.ps - ps2pdf $< - - -clean: - rm -f *.o *~ core pbmtojbg jbgtopbm pbmtojbg85 jbgtopbm85 - rm -f test-*.jbg test-*.pbm test-*.pgm test-*.jbg85 test-*.pbm85 - rm -f *.gcda *.gcno *.plist - rm -f *.ps *.pdf diff --git a/thirdparty/jbigkit/pbmtools/jbgfuzz.pl b/thirdparty/jbigkit/pbmtools/jbgfuzz.pl deleted file mode 100755 index 6f366a19a..000000000 --- a/thirdparty/jbigkit/pbmtools/jbgfuzz.pl +++ /dev/null @@ -1,105 +0,0 @@ -#!/usr/bin/perl -# Simple fuzz tester for JBIG-KIT decoder -- Markus Kuhn -# -# Usage example: -# -# $ ../libjbig/tstcodec t.pbm -# $ ./pbmtojbg -f t.pbm | ./jbgfuzz.pl - -use strict; - -my $fntst = '/tmp/test.jbg'; # fuzz testing file to be generated -my $fntmp = $fntst . '~'; # temporary file (for atomic update) -my $fnvalid = '-'; # valid example BIE file -my $pbmtools = '.'; # location of jbgtopbm and jbgtopbm85 -my $count = "inf"; # how many times shall we try? -my @decoders; - -my $prefix_len = 2000; -my $rnd_suffix_len = 2000; -my $mutation_rate = 10; # percentage of bytes substituted in prefix - -while ($_ = shift @ARGV) { - if ($_ eq '-c') { - $count = shift @ARGV; - } elsif ($_ eq '-m') { - $mutation_rate = shift @ARGV; - } elsif ($_ eq '-p') { - $prefix_len = shift @ARGV; - } elsif ($_ eq '-r') { - $rnd_suffix_len = shift @ARGV; - } elsif ($_ eq '-d') { - push @decoders, shift @ARGV; - } elsif ($_ eq '-t') { - $pbmtools = shift @ARGV; - } else { - $fnvalid = $_; - } -} - -@decoders = ('jbgtopbm', 'jbgtopbm85') unless @decoders; - -# read some bytes from a valid BIE -my $valid_prefix; -my $in; -open($in, "<$fnvalid") || die("$fnvalid: $!\n"); -read $in, $valid_prefix, $prefix_len; -close $in || die("$fnvalid: $!\n"); - -# open a source of random bytes -my $fn_rnd = '/dev/urandom'; -my $rnd; -open($rnd, '<', $fn_rnd) || die; - -for (my $i = 0; $i < $count; $i++) { - my $out; - open($out, '>', $fntmp) || die("$fntmp: $!\n"); - my $prefix; - # randomly substitute some prefix bytes with random bytes - $prefix = $valid_prefix; - if (length($prefix) != $prefix_len) { - warn("Truncating requested $prefix_len byte prefix to available ". - length($prefix)." bytes.\n"); - $prefix_len = length($prefix); - } - #print "\nB: ".join(',', unpack('C4N3C4', substr($prefix, 0, 20)))."\n"; - for (my $p = 0; $p < $prefix_len; $p++) { - if (rand(100) < $mutation_rate) { - substr($prefix, $p, 1) = chr(int(rand(256))); - } - } - #print "A: ".join(',', unpack('C4N3C4', substr($prefix, 0, 20)))."\n"; - # constrain header - my ($dl,$d,$p,$res,$xd,$yd,$l0,$mx,$my,$order,$options,$rest) = - unpack('C4N3C4a*', $prefix); - redo if $xd * $yd > 1e9; # eliminate excessive image sizes - $prefix = pack('C4N3C4a*', $dl,$d,$p,$res,$xd,$yd,$l0,$mx,$my, - $order,$options,$rest); - print $out $prefix; - # append random suffix - my $data; - read $rnd, $data, $rnd_suffix_len; - print $out $data; - close($out) || die("$fntmp: $!\n"); - rename($fntmp, $fntst) || die("mv $fntmp $fntst: $!\n"); - # now feed fuzz input into decoder(s) - for my $jbgtopbm (@decoders) { - printf "%5d: ", $i; - $_ = `$pbmtools/$jbgtopbm $fntst /dev/null 2>&1`; - my $r = $?; - if ($r == 0) { - print "no error encountered\n"; - next; - } elsif ($r == 256) { - my $err; - if (/(\(error code.*\))/) { - $err = $1; - print $err, "\n"; - } else { - die("$_\nno error code found\n"); - } - } else { - die("$_\nreturn value: $r\n"); - } - } -} diff --git a/thirdparty/jbigkit/pbmtools/jbgtopbm.1 b/thirdparty/jbigkit/pbmtools/jbgtopbm.1 deleted file mode 100644 index 66d3c3839..000000000 --- a/thirdparty/jbigkit/pbmtools/jbgtopbm.1 +++ /dev/null @@ -1,114 +0,0 @@ -.TH JBGTOPBM 1 "2014-08-22" -.SH NAME -jbgtopbm \- JBIG1 to portable bitmap file converter -.SH SYNOPSIS -.B jbgtopbm -[ -.I options -] -[ -.I input-file -| \- [ -.I output-file -]] -.br -.SH DESCRIPTION -Reads in a -.I JBIG1 -bi-level image entity (BIE), decompresses it, and outputs a portable -bitmap (PBM) file. - -.I JBIG1 -is a highly effective lossless compression algorithm for -bi-level images (one bit per pixel), which is particularly suitable -for scanned document pages. - -A -.I JBIG1 -encoded image can be stored in several resolutions in one or several -BIEs. All resolution layers except the lowest one are stored -efficiently as differences to the next lower resolution layer. Options -.B -x -and -.B -y -can be used to stop the decompression at a specified maximal output -image size. With option -.B -m -the input file can consist of multiple concatenated BIEs -which contain different increasing resolution layers of the same -image. - -If more than one bit per pixel is stored in the JBIG1 file, then a PGM -file will be produced. -.SH OPTIONS -.TP 12 -.B \- -A single hyphen instead of an input file name will cause -.I jbgtopbm -to read the data from standard input instead from a file. -.TP -.BI \-x " number" -Decode only up to the largest resolution layer which is still not -more than -.I number -pixels wide. If no such resolution layer exists, then use the smallest -one available. -.TP -.BI \-y " number" -Decode only up to the largest resolution layer which is still not -more than -.I number -pixels high. If no such resolution layer exists, then use the smallest -one available. Options -.B \-x -and -.B \-y -can also be used together in which case the largest layer that satisfies -both limits will be selected. -.TP -.B \-m -Process multiple concatenated BIEs. If there are bytes left after the -final SDE in the first BIE, then with this option -.I jbgtopbm -will attempt to decode these as the start of another BIE that may -contain higher resolution data. Normally, any remaining bytes will -generate a warning message. -.TP -.B \-b -Use binary values instead of Gray code words in order to decode pixel -values from multiple bitplanes. This option has only an effect if the -input has more than one bitplane and a PGM output file is produced. -Note that the decoder has to be used in the same mode as the encoder -and cannot determine from the BIE, whether Gray or binary code words -were used by the encoder. -.TP -.B \-d -Diagnose a single BIE. With this option, -.I jbgtopbm -will print a summary of the header information found in the input -file, followed by a list of all PSCD and ESC marker sequences -encountered until the end of the file is reached. -.TP -.BI \-p " number" -If the input contains multiple bitplanes, then extract only the -specified single plane as a PBM file. The first plane has number 0. -.SH BUGS -Using standard input and standard output for binary data works only on -systems where there is no difference between binary and text streams -(e.g., Unix). On other systems (e.g., MS-DOS), using standard input or -standard output may cause control characters like CR or LF to be -inserted or deleted and this will damage the binary data. -.SH STANDARDS -This program implements the -.I JBIG1 -image coding algorithm as specified in international standard ISO/IEC -11544:1993 and ITU-T Recommendation T.82(1993). -.SH AUTHOR -Markus Kuhn wrote -.UR http://www.cl.cam.ac.uk/~mgk25/jbigkit/ -.I JBIG-KIT -.UE , -which includes -.IR jbgtopbm . -.SH SEE ALSO -pbm(5), pgm(5), pbmtojbg(1) diff --git a/thirdparty/jbigkit/pbmtools/jbgtopbm.c b/thirdparty/jbigkit/pbmtools/jbgtopbm.c deleted file mode 100644 index 097087e44..000000000 --- a/thirdparty/jbigkit/pbmtools/jbgtopbm.c +++ /dev/null @@ -1,489 +0,0 @@ -/* - * jbgtopbm - JBIG to Portable Bitmap converter - * - * Markus Kuhn - http://www.cl.cam.ac.uk/~mgk25/jbigkit/ - */ - -#include -#include -#include -#include -#include "jbig.h" - -char *progname; /* global pointer to argv[0] */ - - -/* - * Print usage message and abort - */ -static void usage(void) -{ - fprintf(stderr, "JBIGtoPBM converter " JBG_VERSION " -- " - "reads a bi-level image entity (BIE) as input file\n\n" - "usage: %s [] [ | - []]\n\n" - "options:\n\n", progname); - fprintf(stderr, - " -x number\tif possible decode only up to a resolution layer not\n" - "\t\twider than the given number of pixels\n" - " -y number\tif possible decode only up to a resolution layer not\n" - "\t\thigher than the given number of pixels\n" - " -m\t\tdecode a progressive sequence of multiple concatenated BIEs\n" - " -b\t\tuse binary code for multiple bit planes (default: Gray code)\n" - " -d\t\tdiagnose single BIE, print header, list marker sequences\n" - " -p number\tdecode only one single bit plane (0 = first plane)\n\n"); - exit(1); -} - - -/* - * Call-back routine for merged image output - */ -void write_it(unsigned char *data, size_t len, void *file) -{ - fwrite(data, len, 1, (FILE *) file); -} - -/* - * Remalloc a buffer and append a file f into its content. - * If *buflen == 0, then malloc a buffer first. - */ -void read_file(unsigned char **buf, size_t *buflen, size_t *len, FILE *f) -{ - if (*buflen == 0) { - *buflen = 4000; - *len = 0; - *buf = (unsigned char *) malloc(*buflen); - if (!*buf) { - fprintf(stderr, "Sorry, not enough memory available!\n"); - exit(1); - } - } - do { - *len += fread(*buf + *len, 1, *buflen - *len, f); - if (*len == *buflen) { - *buflen *= 2; - *buf = (unsigned char *) realloc(*buf, *buflen); - if (!*buf) { - fprintf(stderr, "Sorry, not enough memory available!\n"); - exit(1); - } - } - if (ferror(f)) { - perror("Problem while reading input file"); - exit(1); - } - } while (!feof(f)); - if (!*len) return; - *buflen = *len; - *buf = (unsigned char *) realloc(*buf, *buflen); - if (!*buf) { - fprintf(stderr, "Oops, realloc failed when shrinking buffer!\n"); - exit(1); - } - - return; -} - - -/* marker codes */ -#define MARKER_STUFF 0x00 -#define MARKER_SDNORM 0x02 -#define MARKER_SDRST 0x03 -#define MARKER_ABORT 0x04 -#define MARKER_NEWLEN 0x05 -#define MARKER_ATMOVE 0x06 -#define MARKER_COMMENT 0x07 -#define MARKER_ESC 0xff - - -/* - * Output (prefix of) a short byte sequence in hexadecimal - * for diagnostic purposes - */ -void fprint_bytes(FILE *f, unsigned char *p, size_t len, int width) -{ - size_t i; - size_t max = width / 3; - if (len > max) - max -= 7; - for (i = 0; i < len && i < max; i++) - fprintf(f, "%02x ", p[i]); - if (len > i) - fprintf(f, "... %lu bytes total", (unsigned long) len); - fprintf(f, "\n"); -} - -/* - * Read BIE and output human readable description of content - */ -void diagnose_bie(FILE *fin) -{ - unsigned char *bie, *p, *pnext; - size_t buflen = 0, len; - unsigned long xd, yd, l0; - int dl, d; - FILE *f = stdout; - extern unsigned char *jbg_next_pscdms(unsigned char *p, size_t len); - extern unsigned long jbg_stripes(unsigned long l0, unsigned long yd, - unsigned long d); - unsigned long stripes; - int layers, planes; - unsigned long sdes, sde = 0; - double size; - - /* read BIH */ - read_file(&bie, &buflen, &len, fin); - if (len < 20) { - fprintf(f, "Error: Input file is %lu < 20 bytes long and therefore " - "does not contain an intact BIE header!\n", (unsigned long) len); - free(bie); - return; - } - - /* parse BIH */ - fprintf(f, "BIH:\n\n DL = %d\n D = %d\n P = %d\n" - " - = %d\n XD = %lu\n YD = %lu\n L0 = %lu\n MX = %d\n" - " MY = %d\n", - dl = bie[0], d = bie[1], planes = bie[2], bie[3], - xd = ((unsigned long)bie[ 4] << 24) | ((unsigned long)bie[ 5] << 16)| - ((unsigned long) bie[ 6] << 8) | ((unsigned long) bie[ 7]), - yd = ((unsigned long)bie[ 8] << 24) | ((unsigned long)bie[ 9] << 16)| - ((unsigned long) bie[10] << 8) | ((unsigned long) bie[11]), - l0 = ((unsigned long)bie[12] << 24) | ((unsigned long)bie[13] << 16)| - ((unsigned long) bie[14] << 8) | ((unsigned long) bie[15]), - bie[16], bie[17]); - fprintf(f, " order = %d %s%s%s%s%s\n", bie[18], - bie[18] & JBG_HITOLO ? " HITOLO" : "", - bie[18] & JBG_SEQ ? " SEQ" : "", - bie[18] & JBG_ILEAVE ? " ILEAVE" : "", - bie[18] & JBG_SMID ? " SMID" : "", - bie[18] & 0xf0 ? " other" : ""); - fprintf(f, " options = %d %s%s%s%s%s%s%s%s\n\n", bie[19], - bie[19] & JBG_LRLTWO ? " LRLTWO" : "", - bie[19] & JBG_VLENGTH ? " VLENGTH" : "", - bie[19] & JBG_TPDON ? " TPDON" : "", - bie[19] & JBG_TPBON ? " TPBON" : "", - bie[19] & JBG_DPON ? " DPON" : "", - bie[19] & JBG_DPPRIV ? " DPPRIV" : "", - bie[19] & JBG_DPLAST ? " DPLAST" : "", - bie[19] & 0x80 ? " other" : ""); - if (d < dl) { fprintf(f, "D >= DL required!\n"); return; } - if (l0 == 0) { fprintf(f, "L0 > 0 required!\n"); return; } - stripes = jbg_stripes(l0, yd, d); - layers = d - dl + 1; - fprintf(f, " %lu stripes, %d layers, %d planes => ", - stripes, layers, planes); - if (planes == 0 || (ULONG_MAX / layers) / planes >= stripes) { - sdes = stripes * layers * planes; - fprintf(f, "%lu SDEs\n", sdes); - } else { - /* handle integer overflow */ - fprintf(f, ">%lu SDEs!\n", ULONG_MAX); - return; - } - size = (double) planes * (double) yd * (double) jbg_ceil_half(xd, 3); - fprintf(f, " decompressed %.15g bytes\n\n", size); - if (planes == 0) { fprintf(f, "P > 0 required!\n\n"); } - - /* parse BID */ - fprintf(f, "BID:\n\n"); - p = bie + 20; /* skip BIH */ - if ((bie[19] & (JBG_DPON | JBG_DPPRIV | JBG_DPLAST)) - == (JBG_DPON | JBG_DPPRIV)) - p += 1728; /* skip DPTABLE */ - if (p > bie + len) { - fprintf(f, "Error: Input file is %lu < 20+1728 bytes long and therefore " - "does not contain an intact BIE header with DPTABLE!\n", - (unsigned long) len); - return; - } - while (p != bie + len) { - if (p > bie + len - 2) { - fprintf(f, "%06lx: Error: single byte 0x%02x left\n", - (long) (p - bie), *p); - return; - } - pnext = jbg_next_pscdms(p, len - (p - bie)); - if (p[0] != MARKER_ESC || p[1] == MARKER_STUFF) { - fprintf(f, "%06lx: PSCD: ", (long) (p - bie)); - fprint_bytes(f, p, pnext ? (size_t) (pnext - p) : len - (p - bie), 60); - if (!pnext) { - fprintf(f, "Error: PSCD not terminated by SDNORM or SDRST marker\n"); - return; - } - } else - switch (p[1]) { - case MARKER_SDNORM: - case MARKER_SDRST: - fprintf(f, "%06lx: ESC %s, ending SDE #%lu", (long) (p - bie), - (p[1] == MARKER_SDNORM) ? "SDNORM" : "SDRST", ++sde); - if (sde == sdes) - fprintf(f, " (final SDE)"); - else if (sde == sdes + 1) - fprintf(f, " (first surplus SDE, VLENGTH = %d)", - (bie[19] & JBG_VLENGTH) > 0); - fprintf(f, "\n"); - break; - case MARKER_ABORT: - fprintf(f, "%06lx: ESC ABORT\n", (long) (p - bie)); - break; - case MARKER_NEWLEN: - fprintf(f, "%06lx: ESC NEWLEN ", (long) (p - bie)); - if (p + 5 < bie + len) { - fprintf(f, "YD = %lu\n", - yd = (((long) p[2] << 24) | ((long) p[3] << 16) | - ((long) p[4] << 8) | (long) p[5])); - stripes = jbg_stripes(l0, yd, d); - fprintf(f, " %lu stripes, %d layers, %d planes => ", - stripes, layers, planes); - if ((ULONG_MAX / layers) / planes >= stripes) { - sdes = stripes * layers * planes; - fprintf(f, "%lu SDEs\n", sdes); - } else { - /* handle integer overflow */ - fprintf(f, ">%lu SDEs!\n", ULONG_MAX); - return; - } - } else - fprintf(f, "unexpected EOF\n"); - break; - case MARKER_ATMOVE: - fprintf(f, "%06lx: ESC ATMOVE ", (long) (p - bie)); - if (p + 7 < bie + len) - fprintf(f, "YAT = %lu, tX = %d, tY = %d\n", - (((long) p[2] << 24) | ((long) p[3] << 16) | - ((long) p[4] << 8) | (long) p[5]), p[6], p[7]); - else - fprintf(f, "unexpected EOF\n"); - break; - case MARKER_COMMENT: - fprintf(f, "%06lx: ESC COMMENT ", (long) (p - bie)); - if (p + 5 < bie + len) - fprintf(f, "LC = %lu\n", - (((long) p[2] << 24) | ((long) p[3] << 16) | - ((long) p[4] << 8) | (long) p[5])); - else - fprintf(f, "unexpected EOF\n"); - break; - default: - fprintf(f, "%06lx: ESC 0x%02x\n", (long) (p - bie), p[1]); - } - if (!pnext) { - fprintf(f, "Error encountered!\n"); - return; - } - p = pnext; - } - - free(bie); - - return; -} - - -int main (int argc, char **argv) -{ - FILE *fin = stdin, *fout = stdout; - const char *fnin = NULL, *fnout = NULL; - int i, j, result; - int all_args = 0, files = 0; - struct jbg_dec_state s; - unsigned char *buffer, *p; - size_t buflen, len, cnt; - size_t bytes_read = 0; - unsigned long xmax = 4294967295UL, ymax = 4294967295UL, max; - int plane = -1, use_graycode = 1, diagnose = 0, multi = 0; - - buflen = 8000; - buffer = (unsigned char *) malloc(buflen); - if (!buffer) { - printf("Sorry, not enough memory available!\n"); - exit(1); - } - - /* parse command line arguments */ - progname = argv[0]; - for (i = 1; i < argc; i++) { - if (!all_args && argv[i][0] == '-') - if (argv[i][1] == 0) { - if (files++) usage(); - } else - for (j = 1; j > 0 && argv[i][j]; j++) - switch(argv[i][j]) { - case '-' : - all_args = 1; - break; - case 'b': - use_graycode = 0; - break; - case 'm': - multi = 1; - break; - case 'd': - diagnose = 1; - break; - case 'x': - if (++i >= argc) usage(); - xmax = atol(argv[i]); - j = -1; - break; - case 'y': - if (++i >= argc) usage(); - ymax = atol(argv[i]); - j = -1; - break; - case 'p': - if (++i >= argc) usage(); - plane = atoi(argv[i]); - j = -1; - break; - default: - usage(); - } - else - switch (files++) { - case 0: fnin = argv[i]; break; - case 1: fnout = argv[i]; break; - default: - usage(); - } - } - - if (fnin) { - fin = fopen(fnin, "rb"); - if (!fin) { - fprintf(stderr, "Can't open input file '%s", fnin); - perror("'"); - exit(1); - } - } else - fnin = ""; - if (diagnose) { - diagnose_bie(fin); - exit(0); - } - if (fnout) { - fout = fopen(fnout, "wb"); - if (!fout) { - fprintf(stderr, "Can't open input file '%s", fnout); - perror("'"); - exit(1); - } - } else - fnout = ""; - - /* send input file to decoder */ - jbg_dec_init(&s); - jbg_dec_maxsize(&s, xmax, ymax); - /* read BIH first to check VLENGTH */ - len = fread(buffer, 1, 20, fin); - if (len < 20) { - fprintf(stderr, "Input file '%s' (%lu bytes) must be at least " - "20 bytes long\n", fnin, (unsigned long) len); - if (fout != stdout) { - fclose(fout); - remove(fnout); - } - exit(1); - } - if (buffer[19] & JBG_VLENGTH) { - /* VLENGTH = 1 => we might encounter a NEWLEN, therefore read entire - * input file into memory and run two passes over it */ - read_file(&buffer, &buflen, &len, fin); - /* scan for NEWLEN marker segments and update BIE header accordingly */ - result = jbg_newlen(buffer, len); - /* feed data to decoder */ - if (result == JBG_EOK) { - p = (unsigned char *) buffer; - result = JBG_EAGAIN; - while (len > 0 && - (result == JBG_EAGAIN || (result == JBG_EOK && multi))) { - result = jbg_dec_in(&s, p, len, &cnt); - p += cnt; - len -= cnt; - bytes_read += cnt; - } - } - } else { - /* VLENGTH = 0 => we can simply pass the input file directly to decoder */ - result = JBG_EAGAIN; - do { - cnt = 0; - p = (unsigned char *) buffer; - while (len > 0 && - (result == JBG_EAGAIN || (result == JBG_EOK && multi))) { - result = jbg_dec_in(&s, p, len, &cnt); - p += cnt; - len -= cnt; - bytes_read += cnt; - } - if (!(result == JBG_EAGAIN || (result == JBG_EOK && multi))) - break; - len = fread(buffer, 1, buflen, fin); - } while (len > 0); - if (ferror(fin)) { - fprintf(stderr, "Problem while reading input file '%s", fnin); - perror("'"); - if (fout != stdout) { - fclose(fout); - remove(fnout); - } - exit(1); - } - } - if (result != JBG_EOK && result != JBG_EOK_INTR) { - fprintf(stderr, "Problem with input file '%s': %s\n" - "(error code 0x%02x, %lu = 0x%04lx BIE bytes processed)\n", - fnin, jbg_strerror(result), result, - (unsigned long) bytes_read, (unsigned long) bytes_read); - if (fout != stdout) { - fclose(fout); - remove(fnout); - } - exit(1); - } - if (plane >= 0 && jbg_dec_getplanes(&s) <= plane) { - fprintf(stderr, "Image has only %d planes!\n", jbg_dec_getplanes(&s)); - if (fout != stdout) { - fclose(fout); - remove(fnout); - } - exit(1); - } - - if (jbg_dec_getplanes(&s) == 1 || plane >= 0) { - /* write PBM output file */ - fprintf(fout, "P4\n%10lu\n%10lu\n", jbg_dec_getwidth(&s), - jbg_dec_getheight(&s)); - fwrite(jbg_dec_getimage(&s, plane < 0 ? 0 : plane), 1, - jbg_dec_getsize(&s), fout); - } else { - /* write PGM output file */ - if ((size_t) jbg_dec_getplanes(&s) > sizeof(unsigned long) * 8) { - fprintf(stderr, "Image has too many planes (%d)!\n", - jbg_dec_getplanes(&s)); - if (fout != stdout) { - fclose(fout); - remove(fnout); - } - exit(1); - } - max = 0; - for (i = jbg_dec_getplanes(&s); i > 0; i--) - max = (max << 1) | 1; - fprintf(fout, "P5\n%10lu\n%10lu\n%lu\n", jbg_dec_getwidth(&s), - jbg_dec_getheight(&s), max); - jbg_dec_merge_planes(&s, use_graycode, write_it, fout); - } - - /* check for file errors and close fout */ - if (ferror(fout) || fclose(fout)) { - fprintf(stderr, "Problem while writing output file '%s", fnout); - perror("'"); - exit(1); - } - - jbg_dec_free(&s); - - return 0; -} diff --git a/thirdparty/jbigkit/pbmtools/jbgtopbm85.c b/thirdparty/jbigkit/pbmtools/jbgtopbm85.c deleted file mode 100644 index 9bce58755..000000000 --- a/thirdparty/jbigkit/pbmtools/jbgtopbm85.c +++ /dev/null @@ -1,205 +0,0 @@ -/* - * jbgtopbm85 - JBIG to Portable Bitmap converter (T.85 version) - * - * Markus Kuhn - http://www.cl.cam.ac.uk/~mgk25/jbigkit/ - */ - -#include -#include -#include -#include -#include "jbig85.h" - -char *progname; /* global pointer to argv[0] */ -unsigned long y_0; -fpos_t ypos; -int ypos_error = 1; -unsigned long ymax = 0; - -/* - * Print usage message and abort - */ -static void usage(void) -{ - fprintf(stderr, "JBIGtoPBM converter " JBG85_VERSION " (T.85 version) --\n" - "reads a bi-level image entity (BIE) as input file\n\n" - "usage: %s [ | - []]\n\n", progname); - fprintf(stderr, "options:\n\n" - " -x number\tmaximum number of pixels per line for which memory\n" - "\t\tis allocated (default: 8192)\n" - " -y number\tinterrupt decoder after this number of lines\n" - " -B number\tinput buffer size\n\n"); - exit(1); -} - - -/* - * Call-back routine for merged image output - */ -int line_out(const struct jbg85_dec_state *s, - unsigned char *start, size_t len, unsigned long y, void *file) -{ - if (y == 0) { - /* prefix first line with PBM header */ - fprintf((FILE *) file, "P4\n"); - fprintf((FILE *) file, "%10lu\n", jbg85_dec_getwidth(s)); - /* store file position of height, so we can update it after NEWLEN */ - y_0 = jbg85_dec_getheight(s); - ypos_error = fgetpos((FILE *) file, &ypos); - fprintf((FILE *) file, "%10lu\n", y_0); /* pad number to 10 bytes */ - } - fwrite(start, len, 1, (FILE *) file); - return y == ymax - 1; -} - - -int main (int argc, char **argv) -{ - FILE *fin = stdin, *fout = stdout; - const char *fnin = NULL, *fnout = NULL; - int i, j, result; - int all_args = 0, files = 0; - struct jbg85_dec_state s; - unsigned char *inbuf, *outbuf; - size_t inbuflen = 8192, outbuflen, len, cnt, cnt2; - unsigned long xmax = 8192; - size_t bytes_read = 0; - - /* parse command line arguments */ - progname = argv[0]; - for (i = 1; i < argc; i++) { - if (!all_args && argv[i][0] == '-') - if (argv[i][1] == 0) { - if (files++) usage(); - } else - for (j = 1; j > 0 && argv[i][j]; j++) - switch(argv[i][j]) { - case '-' : - all_args = 1; - break; - case 'x': - if (++i >= argc) usage(); - j = -1; - xmax = atol(argv[i]); - break; - case 'y': - if (++i >= argc) usage(); - j = -1; - ymax = atol(argv[i]); - break; - case 'B': - if (++i >= argc) usage(); - j = -1; - inbuflen = atol(argv[i]); - if (inbuflen < 1) usage(); - break; - default: - usage(); - } - else - switch (files++) { - case 0: fnin = argv[i]; break; - case 1: fnout = argv[i]; break; - default: - usage(); - } - } - - inbuf = (unsigned char *) malloc(inbuflen); - outbuflen = ((xmax >> 3) + !!(xmax & 7)) * 3; - outbuf = (unsigned char *) malloc(outbuflen); - if (!inbuf || !outbuf) { - printf("Sorry, not enough memory available!\n"); - exit(1); - } - - if (fnin) { - fin = fopen(fnin, "rb"); - if (!fin) { - fprintf(stderr, "Can't open input file '%s", fnin); - perror("'"); - exit(1); - } - } else - fnin = ""; - if (fnout) { - fout = fopen(fnout, "wb"); - if (!fout) { - fprintf(stderr, "Can't open input file '%s", fnout); - perror("'"); - exit(1); - } - } else - fnout = ""; - - /* send input file to decoder */ - jbg85_dec_init(&s, outbuf, outbuflen, line_out, fout); - result = JBG_EAGAIN; - while ((len = fread(inbuf, 1, inbuflen, fin))) { - result = jbg85_dec_in(&s, inbuf, len, &cnt); - bytes_read += cnt; - while (result == JBG_EOK_INTR) { - /* demonstrate decoder interrupt at given line number */ - printf("Decoding interrupted after %lu lines and %lu BIE bytes " - "... continuing ...\n", s.y, (unsigned long) bytes_read); - /* and now continue decoding */ - result = jbg85_dec_in(&s, inbuf + cnt, len - cnt, &cnt2); - bytes_read += cnt2; - cnt += cnt2; - } - if (result != JBG_EAGAIN) - break; - } - if (ferror(fin)) { - fprintf(stderr, "Problem while reading input file '%s", fnin); - perror("'"); - if (fout != stdout) { - fclose(fout); - remove(fnout); - } - exit(1); - } - if (result == JBG_EAGAIN || result == JBG_EOK_INTR) { - /* signal end-of-BIE explicitely */ - result = jbg85_dec_end(&s); - while (result == JBG_EOK_INTR) { - /* demonstrate decoder interrupt at given line number */ - printf("Decoding interrupted after %lu lines and %lu BIE bytes " - "... continuing ...\n", s.y, (unsigned long) bytes_read); - result = jbg85_dec_end(&s); - } - } - if (result != JBG_EOK) { - fprintf(stderr, "Problem with input file '%s': %s\n" - "(error code 0x%02x, %lu = 0x%04lx BIE bytes " - "and %lu pixel rows processed)\n", - fnin, jbg85_strerror(result), result, - (unsigned long) bytes_read, (unsigned long) bytes_read, s.y); - if (fout != stdout) { - fclose(fout); - /*remove(fnout);*/ - } - exit(1); - } - - /* do we have to update the image height in the PBM header? */ - if (!ypos_error && y_0 != jbg85_dec_getheight(&s)) { - if (fsetpos(fout, &ypos) == 0) { - fprintf(fout, "%10lu", jbg85_dec_getheight(&s)); /* pad to 10 bytes */ - } else { - fprintf(stderr, "Problem while updating height in output file '%s", - fnout); - perror("'"); - exit(1); - } - } - - /* check for file errors and close fout */ - if (ferror(fout) || fclose(fout)) { - fprintf(stderr, "Problem while writing output file '%s", fnout); - perror("'"); - exit(1); - } - - return 0; -} diff --git a/thirdparty/jbigkit/pbmtools/pbm.5 b/thirdparty/jbigkit/pbmtools/pbm.5 deleted file mode 100644 index 9b46dc0b1..000000000 --- a/thirdparty/jbigkit/pbmtools/pbm.5 +++ /dev/null @@ -1,91 +0,0 @@ -.TH pbm 5 "27 September 1991" -.SH NAME -pbm - portable bitmap file format -.SH DESCRIPTION -The portable bitmap format is a lowest common denominator monochrome -file format. -.IX "PBM file format" -It was originally designed to make it reasonable to mail bitmaps -between different types of machines using the typical stupid network -mailers we have today. -Now it serves as the common language of a large family of bitmap -conversion filters. -The definition is as follows: -.IP - 2 -A "magic number" for identifying the file type. -A pbm file's magic number is the two characters "P1". -.IX "magic numbers" -.IP - 2 -Whitespace (blanks, TABs, CRs, LFs). -.IP - 2 -A width, formatted as ASCII characters in decimal. -.IP - 2 -Whitespace. -.IP - 2 -A height, again in ASCII decimal. -.IP - 2 -Whitespace. -.IP - 2 -Width * height bits, each either '1' or '0', starting at the top-left -corner of the bitmap, proceeding in normal English reading order. -.IP - 2 -The character '1' means black, '0' means white. -.IP - 2 -Whitespace in the bits section is ignored. -.IP - 2 -Characters from a "#" to the next end-of-line are ignored (comments). -.IP - 2 -No line should be longer than 70 characters. -.PP -Here is an example of a small bitmap in this format: -.nf -P1 -# feep.pbm -24 7 -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 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1 0 -0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 -0 1 1 1 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 1 1 1 1 0 -0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 -0 1 0 0 0 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 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 -.fi -.PP -Programs that read this format should be as lenient as possible, -accepting anything that looks remotely like a bitmap. -.PP -There is also a variant on the format, available -by setting the RAWBITS option at compile time. This variant is -.IX RAWBITS -different in the following ways: -.IP - 2 -The "magic number" is "P4" instead of "P1". -.IP - 2 -The bits are stored eight per byte, high bit first low bit last. -.IP - 2 -No whitespace is allowed in the bits section, and only a single character -of whitespace (typically a newline) is allowed after the height. -.IP - 2 -The files are eight times smaller and many times faster to read and write. -.SH "SEE ALSO" -atktopbm(1), brushtopbm(1), cmuwmtopbm(1), g3topbm(1), -gemtopbm(1), icontopbm(1), -macptopbm(1), mgrtopbm(1), pi3topbm(1), xbmtopbm(1), -ybmtopbm(1), -pbmto10x(1), pnmtoascii(1), pbmtoatk(1), pbmtobbnbg(1), -pbmtocmuwm(1), pbmtoepson(1), -pbmtog3(1), pbmtogem(1), pbmtogo(1), pbmtoicon(1), pbmtolj(1), -pbmtomacp(1), pbmtomgr(1), pbmtopi3(1), pbmtoplot(1), pbmtoptx(1), -pbmtox10bm(1), pbmtoxbm(1), pbmtoybm(1), -pbmtozinc(1), -pbmlife(1), pbmmake(1), pbmmask(1), pbmreduce(1), -pbmtext(1), pbmupc(1), -pnm(5), pgm(5), ppm(5) -.SH AUTHOR -Copyright (C) 1989, 1991 by Jef Poskanzer. -.\" Permission to use, copy, modify, and distribute this software and its -.\" documentation for any purpose and without fee is hereby granted, provided -.\" that the above copyright notice appear in all copies and that both that -.\" copyright notice and this permission notice appear in supporting -.\" documentation. This software is provided "as is" without express or -.\" implied warranty. diff --git a/thirdparty/jbigkit/pbmtools/pbmtojbg.1 b/thirdparty/jbigkit/pbmtools/pbmtojbg.1 deleted file mode 100644 index 63a49eac3..000000000 --- a/thirdparty/jbigkit/pbmtools/pbmtojbg.1 +++ /dev/null @@ -1,306 +0,0 @@ -.TH PBMTOJBG 1 "2014-08-22" -.SH NAME -pbmtojbg \- portable bitmap to JBIG1 file converter -.SH SYNOPSIS -.B pbmtojbg -[ -.I options -] -[ -.I input-file -| \- [ -.I output-file -]] -.br -.SH DESCRIPTION -Reads a file in portable bitmap (PBM) format, compresses it, -and outputs the image as a -.I JBIG1 -bi-level image entity (BIE). - -.I JBIG1 -is a highly effective, lossless compression algorithm for -bi-level images (one bit per pixel), which is particularly suitable -for scanned document pages. - -A -.I JBIG1 -encoded image can be stored in several resolution layers (progressive mode). -This allows the decoder to recover a lower-resolution version of the -encoded image without having to read the complete file. -These resolution layers can be stored all in one single BIE or they -can be stored in several separate BIE files. -All resolution layers, except the lowest one, are stored merely as -differences to the next lower resolution layer. This requires less -space than encoding the full image completely every time. Each resolution -layer has twice the number of horizontal and vertical pixels than -the next lower layer. - -For best speed and compression, if you are not interested in -efficiently extracting lower-resolution versions from the compressed -file, use sequential mode (single resolution layer, option -.BR \-q ). - -.I JBIG1 -files can also store several bits per pixel, as separate bitmap planes, -and -.I pbmtojbg -can read a portable graymap format (PGM) file and transform it into -a multi-plane BIE. - -.SH OPTIONS -.TP 12 -.BI \- -A single hyphen instead of an input file name causes -.I pbmtojbg -to read the data from standard input instead of from a file. -.TP -.BI \-v -List technical details of the created file (verbose mode). -.TP -.BI \-f -This option makes the output file comply with the \[lq]facsimile application -profile\[rq] defined in ITU-T Recommendation T.85. It is a shortcut for -.BR "-q -o 0 -p 8 -s 128 -t 1 -m 127" . -.TP -.BI \-C " string" -Add the -.I string -in a comment marker segment to the produced data stream. -.br -(There is no support at present for adding comments that contain a -zero byte.) -.P -Options affecting the number of resolution layers produced: -.TP 12 -.BI \-q -Encode the image in one single resolution layer (sequential mode), which -is usually the most efficient compression method. By default, the number -of resolution layers is instead chosen automatically such that the lowest layer -image is not larger than 640 \(mu 480 pixels. -This option is just a shortcut for -.BR "-d 0" . -.TP -.BI \-x " number" -Specify the maximal horizontal size of the lowest resolution layer. -Default: 640 pixels -.TP -.BI \-y " number" -Specify the maximal vertical size of the lowest resolution layer. -Default: 480 pixels -.TP -.BI \-d " number" -Specify the total number of differential resolution layers into which to split -the input image (in addition to the lowest layer). Each additional -layer reduces both the width and height of layer 0 by 50%. -This option overrides options -.B \-x -and -.BR \-y , -which are usually a more convenient way of selecting the number of -resolution layers. -.TP -.BI \-l " number" -Select the lowest resolution layer -.I D\s-2\dL\u\s0 -that will appear in the generated -BIE. -.I JBIG1 -can store the various resolution layers of an image in progressive mode -split across several BIEs. Options -.B \-l -and -.B \-h -allow you to select the resolution-layer interval that will appear -in the created BIE. The lowest resolution layer has number 0 and -this is also the default value. The default is to write all layers. -.TP -.BI \-h " number" -Select the highest resolution layer -.I D -that will appear in the generated BIE. The default is to write all layers. -See also option -.BR \-l . -.P -Options for changing other parameters indicated in the BIE header: -.TP 12 -.BI \-s " number" -The -.I JBIG1 -algorithm splits each image into horizontal stripes. This -option specifies -.IR L\s-2\d0\u\s0 , -the layer-0 height of each such stripe (except for the last one, -which can be shorter). -The default is to split the whole image into approximately 35 stripes. -.TP -.BI \-m " number" -Select the maximum horizontal offset -.I M\s-2\dX\u\s0 -of the adaptive template pixel. -The -.I JBIG1 -encoder uses ten neighbour pixels to estimate the probability of the -next pixel being black or white. It can adjust the location of one -of these ten context pixels. -This is especially useful for dithered images, as long as the -distance of this adaptive pixel can be adjusted to the period of the -dither pattern. By default, the adaptive template pixel is allowed to -move up to 8 pixels away horizontally. This encoder supports distances -up to 127 pixels. -.br -Annex A of the standard suggests that decoders should support at least -a horizontal distance of 16 pixels, so using values not higher than 16 -for -.I number -might increase the chances of interoperability with other -.I JBIG1 -implementations. On the other hand, the T.85 fax application profile -requires decoders to support horizontal offsets up to 127 pixels, -which is the maximum value permitted by the standard. (The maximal -vertical offset -.I M\s-2\dY\u\s0 -of the adaptive template pixel is always zero for this -encoder.) -.TP -.BI \-o " number" -Specify the order in which image data appears in the output. -.I JBIG1 -separates an image into several horizontal stripes, resolution layers -and planes, were each plane contains one bit per pixel. One single -stripe in one plane and layer is encoded as a data unit called stripe -data entity (SDE) inside the BIE. There are 12 different possible -orders in which the SDEs can be stored inside the BIE and -.I number -selects which one shall be used. For receiving applications, the order of -the SDEs mainly matters if they want to start decoding an image before -it has been received completely. -For instance, some applications may prefer that the outermost of the -three loops (stripes, layers, planes) is over all layers so that all -data of the lowest resolution layer is transmitted first. -.br -The following values for -.I number -select these loop arrangements for writing the SDEs (outermost -loop first): - - 0 planes, layers, stripes -.br - 2 layers, planes, stripes -.br - 3 layers, stripes, planes -.br - 4 stripes, planes, layers -.br - 5 planes, stripes, layers -.br - 6 stripes, layers, planes - -All loops count starting with zero, however by adding 8 to the above -order code, the layer loop can be reversed so that it counts down to zero -and then higher resolution layers will be stored before lower layers. -The default order is 3, which writes at first all planes of the first -stripe and then completes layer 0 before continuing with the next -layer, and so on. -.TP -.BI \-p " number" -This option activates or deactivates various optional algorithms -defined in the -.I JBIG1 -standard. Just add the numbers of the following options which you want to -activate in -order to get the -.I number -value: - - 4 deterministic prediction (DPON) -.br - 8 layer 0 typical prediction (TPBON) -.br - 16 diff. layer typ. pred. (TPDON) -.br - 64 layer 0 two-line template (LRLTWO) - -This option is only for specialist applications (e.g., communication with -.I JBIG1 -subset implementations, debugging). The default is 28, which usually -provides the best compression result. -.P -Options affecting the processing of PGM files: -.TP 12 -.BI \-b -Use binary values instead of Gray code words in order to encode pixel -values in multiple bit planes. This option has only an effect if the -input is a PGM file and if more than one plane is produced. Note that -the decoder has to make the same choice, but the BIE does not -indicate whether Gray or binary code words were used by the encoder. -.TP -.BI \-t " number" -Encode only the specified number of most significant bit planes. This -option reduces the depth of an input PGM file if not all -bits per pixel are needed in the output. -.P -Options to help generating test files: -.TP 12 -.BI \-r -Use the SDRST marker instead of the normal SDNORM marker. The probably -only useful application for this option is to generate test data for -checking whether a -.I JBIG1 -decoder has implemented SDRST correctly. In a normal -.I JBIG1 -data stream, each stripe data entity (SDE) is terminated by an SDNORM -marker, which preserves the state of the arithmetic encoder (and more) -for the next stripe in the same layer. The alternative SDRST marker -resets this state at the end of the stripe. -.TP -.BI \-Y " number" -Specify a preliminary image height -.IR Y\s-2\dD\u\s0 . -A long time ago, there were fax -machines that couldn't even hold a single page in memory. They had to -start transmitting data before the page was scanned in completely and -before even the height of the resulting image was known. -The authors of the standard added a rather ugly hack to JBIG1 -to support this use case. The NEWLEN marker segment can -override the image height stated in the BIE header anywhere later in -the data stream. Normally -.I pbmtojbg -never generates NEWLEN marker segments, as it knows the correct image -height when it outputs the header. This option is solely intended for -the purpose of generating test files with NEWLEN marker segments. It -can be used to specify a higher initial image height for use in the -BIE header, and -.I pbmtojbg -will then add a NEWLEN marker segment at the latest possible -opportunity to the data stream to signal the correct final height. -It will also set the VLENGTH flag in the BIE header. -.TP -.BI \-c -Determine the adaptive template pixel movement as suggested in Annex C -of the standard. By default the template change takes place directly -in the next line, which is most effective. However, a few conformance -test examples in the standard require the adaptive template change to -be delayed until the first line of the next stripe. This option -selects this special behavior, which is normally not useful other than -for conformance testing. -.SH BUGS -Using standard input and standard output for binary data works only on -systems where there is no difference between binary and text streams -(e.g., Unix). On other systems (e.g., MS-DOS), using standard input or -standard output may cause control characters like CR or LF to be -inserted or deleted and this will damage the binary data. -.SH STANDARDS -This program implements the -.I JBIG1 -image coding algorithm as specified in international standard ISO/IEC -11544:1993 and ITU-T Recommendation T.82(1993). -.SH AUTHOR -Markus Kuhn wrote -.UR http://www.cl.cam.ac.uk/~mgk25/jbigkit/ -.I JBIG-KIT -.UE , -which includes -.IR pbmtojbg . -.SH SEE ALSO -pbm(5), pgm(5), jbgtopbm(1) diff --git a/thirdparty/jbigkit/pbmtools/pbmtojbg.c b/thirdparty/jbigkit/pbmtools/pbmtojbg.c deleted file mode 100644 index 8892a0878..000000000 --- a/thirdparty/jbigkit/pbmtools/pbmtojbg.c +++ /dev/null @@ -1,455 +0,0 @@ -/* - * pbmtojbg - Portable Bitmap to JBIG converter - * - * Markus Kuhn - http://www.cl.cam.ac.uk/~mgk25/jbigkit/ - */ - -#include -#include -#include -#include -#include -#include "jbig.h" - - -char *progname; /* global pointer to argv[0] */ -unsigned long total_length = 0; /* used for determining output file length */ - - -/* - * Print usage message and abort - */ -static void usage(void) -{ - fprintf(stderr, - "PBMtoJBIG converter " JBG_VERSION " -- " - "creates bi-level image entity (BIE) as output file\n\n" - "usage: %s [] [ | - []]\n\n" - "options:\n\n", progname); - fprintf(stderr, - " -q\t\tsequential coding, no differential layers (like -d 0)\n" - " -x number\tmaximum width of lowest resolution layer (default 640)\n" - " -y number\tmaximum height of lowest resolution layer (default 480)\n" - " -l number\tlowest layer written to output file (default 0)\n" - " -h number\thighest layer written to output file (default max)\n" - " -b\t\tuse binary code for multiple bitplanes (default: Gray code)\n" - " -d number\ttotal number of differential layers (overrides -x and -y)\n" - " -s number\theight of a stripe in layer 0\n"); - fprintf(stderr, - " -m number\tmaximum adaptive template pixel horizontal offset (default 8)\n" - " -t number\tencode only that many most significant planes\n" - " -o number\torder byte value: add 1=SMID, 2=ILEAVE, 4=SEQ, 8=HITOLO\n" - "\t\t(default 3 = ILEAVE+SMID)\n" - " -p number\toptions byte value: add DPON=4, TPBON=8, TPDON=16, LRLTWO=64\n" - "\t\t(default 28 = DPON+TPBON+TPDON)\n"); - fprintf(stderr, - " -C string\tadd the provided string as a comment marker segment\n" - " -c\t\tdelay adaptive template changes to first line of next stripe\n" - "\t\t(only provided for a conformance test)\n" - " -r\t\tterminate each stripe with SDRST marker\n" - "\t\t(only intended for decoder testing)\n" ); - fprintf(stderr, - " -Y number\tannounce in header initially this larger image height\n" - "\t\t(only for generating test files with NEWLEN and VLENGTH=1)\n" - " -f\t\tchose encoding options for T.85 fax profile complianance\n" - " -v\t\tverbose output\n\n"); - exit(1); -} - - -/* - * malloc() with exception handler - */ -void *checkedmalloc(size_t n) -{ - void *p; - - if ((p = malloc(n)) == NULL) { - fprintf(stderr, "Sorry, not enough memory available!\n"); - exit(1); - } - - return p; -} - - -/* - * Read an ASCII integer number from file f and skip any PBM - * comments which are encountered. - */ -static unsigned long getint(FILE *f) -{ - int c; - unsigned long i; - - while ((c = getc(f)) != EOF) - if (c == '#') - while ((c = getc(f)) != EOF && !(c == 13 || c == 10)) ; - else if (!isspace(c)) - break; - if (c == EOF) return 0; - ungetc(c, f); - if (fscanf(f, "%lu", &i) != 1) { - fprintf(stderr, "Unsigned integer value expected!\n"); - exit(1); - } - - return i; -} - - -/* - * Callback procedure which is used by JBIG encoder to deliver the - * encoded data. It simply sends the bytes to the output file. - */ -static void data_out(unsigned char *start, size_t len, void *file) -{ - fwrite(start, len, 1, (FILE *) file); - total_length += len; - return; -} - - -int main (int argc, char **argv) -{ - FILE *fin = stdin, *fout = stdout; - const char *fnin = NULL, *fnout = NULL; - int i, j, c; - int all_args = 0, files = 0; - unsigned long x, y; - unsigned long width, height, max, v; - unsigned long bpl; - int bpp, planes, encode_planes = -1; - size_t bitmap_size; - char type; - unsigned char **bitmap, *p, *image; - struct jbg_enc_state s; - int verbose = 0, delay_at = 0, reset = 0, use_graycode = 1; - long mwidth = 640, mheight = 480; - int dl = -1, dh = -1, d = -1, mx = -1; - unsigned long l0 = 0, y1 = 0; - char *comment = NULL; - int options = JBG_TPDON | JBG_TPBON | JBG_DPON; - int order = JBG_ILEAVE | JBG_SMID; - - /* parse command line arguments */ - progname = argv[0]; - for (i = 1; i < argc; i++) { - if (!all_args && argv[i][0] == '-') - if (argv[i][1] == 0) { - if (files++) usage(); - } else - for (j = 1; j > 0 && argv[i][j]; j++) - switch(argv[i][j]) { - case '-' : - all_args = 1; - break; - case 0 : - if (files++) usage(); - break; - case 'v': - verbose = 1; - break; - case 'b': - use_graycode = 0; - break; - case 'c': - delay_at = 1; - break; - case 'r': - reset = 1; - break; - case 'f': - d = 0; - order = 0; - options = 8; - l0 = 128; - encode_planes = 1; - mx = 127; - break; - case 'x': - if (++i >= argc) usage(); - j = -1; - mwidth = atol(argv[i]); - break; - case 'y': - if (++i >= argc) usage(); - j = -1; - mheight = atol(argv[i]); - break; - case 'Y': - if (++i >= argc) usage(); - j = -1; - y1 = atol(argv[i]); - break; - case 'o': - if (++i >= argc) usage(); - j = -1; - order = atoi(argv[i]); - break; - case 'p': - if (++i >= argc) usage(); - j = -1; - options = atoi(argv[i]); - break; - case 'l': - if (++i >= argc) usage(); - j = -1; - dl = atoi(argv[i]); - break; - case 'h': - if (++i >= argc) usage(); - j = -1; - dh = atoi(argv[i]); - break; - case 'q': - d = 0; - break; - case 'd': - if (++i >= argc) usage(); - j = -1; - d = atoi(argv[i]); - break; - case 's': - if (++i >= argc) usage(); - j = -1; - l0 = atol(argv[i]); - break; - case 't': - if (++i >= argc) usage(); - j = -1; - encode_planes = atoi(argv[i]); - break; - case 'm': - if (++i >= argc) usage(); - j = -1; - mx = atoi(argv[i]); - break; - case 'C': - if (++i >= argc) usage(); - j = -1; - comment = argv[i]; - break; - default: - usage(); - } - else - switch (files++) { - case 0: fnin = argv[i]; break; - case 1: fnout = argv[i]; break; - default: - usage(); - } - } - - if (fnin) { - fin = fopen(fnin, "rb"); - if (!fin) { - fprintf(stderr, "Can't open input file '%s", fnin); - perror("'"); - exit(1); - } - } else - fnin = ""; - if (fnout) { - fout = fopen(fnout, "wb"); - if (!fout) { - fprintf(stderr, "Can't open input file '%s", fnout); - perror("'"); - exit(1); - } - } else - fnout = ""; - - /* read PBM header */ - while ((c = getc(fin)) != EOF && (isspace(c) || c == '#')) - if (c == '#') - while ((c = getc(fin)) != EOF && !(c == 13 || c == 10)) ; - if (c != 'P') { - fprintf(stderr, "Input file '%s' does not look like a PBM file!\n", fnin); - exit(1); - } - type = getc(fin); - width = getint(fin); - height = getint(fin); - if (width < 1 || height < 1 || - width > 0xffffffff || height > 0xffffffff) { - fprintf(stderr, "Invalid width or height!\n"); - exit(1); - } - if (type == '2' || type == '5' || - type == '3' || type == '6') - max = getint(fin); - else - max = 1; - if (max < 1) { - fprintf(stderr, "Invalid maxval!\n"); - exit(1); - } - for (planes = 0, v = max; v; planes++, v >>= 1) ; - bpp = (planes + 7) / 8; - if (encode_planes < 1 || encode_planes > planes) - encode_planes = planes; - fgetc(fin); /* skip line feed */ - - /* read PBM image data */ - bpl = jbg_ceil_half(width, 3); /* bytes per line */ - if (ULONG_MAX / height < bpl) { - fprintf(stderr, "Image too large!\n"); - exit(1); - } - bitmap_size = bpl * (size_t) height; - bitmap = (unsigned char **) checkedmalloc(sizeof(unsigned char *) * - encode_planes); - for (i = 0; i < encode_planes; i++) - bitmap[i] = (unsigned char *) checkedmalloc(bitmap_size); - switch (type) { - case '1': - /* PBM text format */ - p = bitmap[0]; - for (y = 0; y < height; y++) - for (x = 0; x <= ((width-1) | 7); x++) { - *p <<= 1; - if (x < width) - *p |= getint(fin) & 1; - if ((x & 7) == 7) - ++p; - } - break; - case '4': - /* PBM raw binary format */ - fread(bitmap[0], bitmap_size, 1, fin); - break; - case '2': - case '5': - /* PGM */ - if ((ULONG_MAX / bpp) / height < width) { - fprintf(stderr, "Image too large!\n"); - exit(1); - } - image = (unsigned char *) checkedmalloc(width * height * bpp); - if (type == '2') { - for (x = 0; x < width * height; x++) { - v = getint(fin); - for (j = 0; j < bpp; j++) - image[x * bpp + (bpp - 1) - j] = v >> (j * 8); - } - } else - fread(image, width * height, bpp, fin); - jbg_split_planes(width, height, planes, encode_planes, image, bitmap, - use_graycode); - free(image); - break; - default: - fprintf(stderr, "Unsupported PBM type P%c!\n", type); - exit(1); - } - if (ferror(fin)) { - fprintf(stderr, "Problem while reading input file '%s", fnin); - perror("'"); - exit(1); - } - if (feof(fin)) { - fprintf(stderr, "Unexpected end of input file '%s'!\n", fnin); - exit(1); - } - - /* Test for valid parameters */ - if (width < 1 || height < 1) { - fprintf(stderr, "Image dimensions must be positive!\n"); - exit(1); - } - if (encode_planes < 1 || encode_planes > 255) { - fprintf(stderr, "Number of planes must be in range 1-255!\n"); - exit(1); - } - - /* Test the final byte in each image line for correct zero padding */ - if ((width & 7) && type == '4') { - for (y = 0; y < height; y++) - if (bitmap[0][y * bpl + bpl - 1] & ((1 << (8 - (width & 7))) - 1)) { - fprintf(stderr, "Warning: No zero padding in last byte (0x%02x) of " - "line %lu!\n", bitmap[0][y * bpl + bpl - 1], y + 1); - break; - } - } - - /* Apply JBIG algorithm and write BIE to output file */ - - /* initialize parameter struct for JBIG encoder*/ - jbg_enc_init(&s, width, height, encode_planes, bitmap, data_out, fout); - - /* Select number of resolution layers either directly or based - * on a given maximum size for the lowest resolution layer */ - if (d >= 0) - jbg_enc_layers(&s, d); - else - jbg_enc_lrlmax(&s, mwidth, mheight); - - /* Specify a few other options (each is ignored if negative) */ - if (delay_at) - options |= JBG_DELAY_AT; - if (reset) - options |= JBG_SDRST; - if (comment) { - s.comment_len = strlen(comment); - s.comment = (unsigned char *) comment; - } - if (y1) - s.yd1 = y1; - jbg_enc_lrange(&s, dl, dh); - jbg_enc_options(&s, order, options, l0, mx, -1); - - /* now encode everything and send it to data_out() */ - jbg_enc_out(&s); - - /* give encoder a chance to free its temporary data structures */ - jbg_enc_free(&s); - - /* check for file errors and close fout */ - if (ferror(fout) || fclose(fout)) { - fprintf(stderr, "Problem while writing output file '%s", fnout); - perror("'"); - exit(1); - } - - /* In case the user wants to know all the gory details ... */ - if (verbose) { - fprintf(stderr, "Information about the created JBIG bi-level image entity " - "(BIE):\n\n"); - fprintf(stderr, " input image size: %lu x %lu pixel\n", - s.xd, s.yd); - fprintf(stderr, " bit planes: %d\n", s.planes); - if (s.planes > 1) - fprintf(stderr, " encoding: %s code, MSB first\n", - use_graycode ? "Gray" : "binary"); - fprintf(stderr, " stripes: %lu\n", s.stripes); - fprintf(stderr, " lines per stripe in layer 0: %lu\n", s.l0); - fprintf(stderr, " total number of diff. layers: %d\n", s.d); - fprintf(stderr, " lowest layer in BIE: %d\n", s.dl); - fprintf(stderr, " highest layer in BIE: %d\n", s.dh); - fprintf(stderr, " lowest layer size: %lu x %lu pixel\n", - jbg_ceil_half(s.xd, s.d - s.dl), jbg_ceil_half(s.yd, s.d - s.dl)); - fprintf(stderr, " highest layer size: %lu x %lu pixel\n", - jbg_ceil_half(s.xd, s.d - s.dh), jbg_ceil_half(s.yd, s.d - s.dh)); - fprintf(stderr, " option bits:%s%s%s%s%s%s%s\n", - s.options & JBG_LRLTWO ? " LRLTWO" : "", - s.options & JBG_VLENGTH ? " VLENGTH" : "", - s.options & JBG_TPDON ? " TPDON" : "", - s.options & JBG_TPBON ? " TPBON" : "", - s.options & JBG_DPON ? " DPON" : "", - s.options & JBG_DPPRIV ? " DPPRIV" : "", - s.options & JBG_DPLAST ? " DPLAST" : ""); - fprintf(stderr, " order bits:%s%s%s%s\n", - s.order & JBG_HITOLO ? " HITOLO" : "", - s.order & JBG_SEQ ? " SEQ" : "", - s.order & JBG_ILEAVE ? " ILEAVE" : "", - s.order & JBG_SMID ? " SMID" : ""); - fprintf(stderr, " AT maximum x-offset: %d\n" - " AT maximum y-offset: %d\n", s.mx, s.my); - fprintf(stderr, " length of output file: %lu byte\n\n", - total_length); - } - - return 0; -} diff --git a/thirdparty/jbigkit/pbmtools/pbmtojbg85.c b/thirdparty/jbigkit/pbmtools/pbmtojbg85.c deleted file mode 100644 index 710efe1df..000000000 --- a/thirdparty/jbigkit/pbmtools/pbmtojbg85.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - * pbmtojbg85 - Portable Bitmap to JBIG converter (T.85 version) - * - * Markus Kuhn - http://www.cl.cam.ac.uk/~mgk25/jbigkit/ - */ - -#include -#include -#include -#include -#include -#include "jbig85.h" - - -char *progname; /* global pointer to argv[0] */ - - -/* - * Print usage message and abort - */ -static void usage(void) -{ - fprintf(stderr, - "PBMtoJBIG converter " JBG85_VERSION " (T.85 version) --\n" - "creates bi-level image entity (BIE) as output file\n\n" - "usage: %s [] [ | - []]\n\n" - "options:\n\n", progname); - fprintf(stderr, - " -s number\theight of a stripe\n"); - fprintf(stderr, - " -m number\tmaximum adaptive template pixel horizontal offset (default 8)\n" - " -p number\toptions byte value: add TPBON=8, LRLTWO=64\n" - "\t\t(default 8 = TPBON)\n"); - fprintf(stderr, - " -C string\tadd the provided string as a comment marker segment\n"); - fprintf(stderr, - " -Y yi yr\tannounce in header initially the larger image height yi\n" - "\t\tand then announce after line yr has been encoded the real height\n" - "\t\tusing NEWLEN marker (for testing NEWLEN and VLENGTH=1 function)\n\n"); - exit(1); -} - - -/* - * malloc() with exception handler - */ -void *checkedmalloc(size_t n) -{ - void *p; - - if ((p = malloc(n)) == NULL) { - fprintf(stderr, "Sorry, not enough memory available!\n"); - exit(1); - } - - return p; -} - - -/* - * Read an ASCII integer number from file f and skip any PBM - * comments which are encountered. - */ -static unsigned long getint(FILE *f) -{ - int c; - unsigned long i; - - while ((c = getc(f)) != EOF) - if (c == '#') - while ((c = getc(f)) != EOF && !(c == 13 || c == 10)) ; - else if (!isspace(c)) - break; - if (c == EOF) return 0; - ungetc(c, f); - if (fscanf(f, "%lu", &i) != 1) { - fprintf(stderr, "Unsigned integer value expected!\n"); - exit(1); - } - - return i; -} - - -/* - * Callback procedure which is used by JBIG encoder to deliver the - * encoded data. It simply sends the bytes to the output file. - */ -static void data_out(unsigned char *start, size_t len, void *file) -{ - fwrite(start, len, 1, (FILE *) file); - return; -} - - -int main (int argc, char **argv) -{ - FILE *fin = stdin, *fout = stdout; - const char *fnin = NULL, *fnout = NULL; - int i, j, c; - int all_args = 0, files = 0; - unsigned long x, y; - unsigned long width, height; - size_t bpl; - char type; - unsigned char *p, *lines, *next_line; - unsigned char *prev_line = NULL, *prevprev_line = NULL; - struct jbg85_enc_state s; - int mx = -1; - unsigned long l0 = 0, yi = 0, yr = 0; - char *comment = NULL; - int options = JBG_TPBON; - - /* parse command line arguments */ - progname = argv[0]; - for (i = 1; i < argc; i++) { - if (!all_args && argv[i][0] == '-') - if (argv[i][1] == 0) { - if (files++) usage(); - } else - for (j = 1; j > 0 && argv[i][j]; j++) - switch(argv[i][j]) { - case '-' : - all_args = 1; - break; - case 0 : - if (files++) usage(); - break; - case 'Y': - if (i+2 >= argc) usage(); - j = -1; - yi = atol(argv[++i]); - yr = atol(argv[++i]); - break; - case 'p': - if (++i >= argc) usage(); - j = -1; - options = atoi(argv[i]); - break; - case 's': - if (++i >= argc) usage(); - j = -1; - l0 = atol(argv[i]); - break; - case 'm': - if (++i >= argc) usage(); - j = -1; - mx = atoi(argv[i]); - break; - case 'C': - if (++i >= argc) usage(); - j = -1; - comment = argv[i]; - break; - default: - usage(); - } - else - switch (files++) { - case 0: fnin = argv[i]; break; - case 1: fnout = argv[i]; break; - default: - usage(); - } - } - - /* open input file */ - if (fnin) { - fin = fopen(fnin, "rb"); - if (!fin) { - fprintf(stderr, "Can't open input file '%s", fnin); - perror("'"); - exit(1); - } - } else - fnin = ""; - - /* read PBM header */ - while ((c = getc(fin)) != EOF && (isspace(c) || c == '#')) - if (c == '#') - while ((c = getc(fin)) != EOF && !(c == 13 || c == 10)) ; - type = getc(fin); - if (c != 'P' || (type != '1' && type != '4')) { - fprintf(stderr, "Input file '%s' does not look like a PBM file!\n", fnin); - exit(1); - } - width = getint(fin); - height = getint(fin); - fgetc(fin); /* skip line feed */ - - /* Test for valid parameters */ - if (width < 1 || height < 1 || - width > 0xffffffff || height > 0xffffffff) { - fprintf(stderr, "Invalid width or height!\n"); - exit(1); - } - - /* allocate buffer for a single image line */ - bpl = (width >> 3) + !!(width & 7); /* bytes per line */ - lines = (unsigned char *) checkedmalloc(bpl * 3); - - /* open output file */ - if (fnout) { - fout = fopen(fnout, "wb"); - if (!fout) { - fprintf(stderr, "Can't open input file '%s", fnout); - perror("'"); - exit(1); - } - } else - fnout = ""; - - /* initialize parameter struct for JBIG encoder*/ - jbg85_enc_init(&s, width, yi ? yi : height, data_out, fout); - - /* Specify a few other options (each is ignored if negative) */ - if (yi) - options |= JBG_VLENGTH; - if (comment) { - s.comment_len = strlen(comment); - s.comment = (unsigned char *) comment; - } - jbg85_enc_options(&s, options, l0, mx); - - for (y = 0; y < height; y++) { - - /* Use a 3-line ring buffer, because the encoder requires that the two - * previously supplied lines are still in memory when the next line is - * processed. */ - next_line = lines + (y%3)*bpl; - - switch (type) { - case '1': - /* PBM text format */ - p = next_line; - for (x = 0; x <= ((width-1) | 7); x++) { - *p <<= 1; - if (x < width) - *p |= getint(fin) & 1; - if ((x & 7) == 7) - ++p; - } - break; - case '4': - /* PBM raw binary format */ - fread(next_line, bpl, 1, fin); - break; - default: - fprintf(stderr, "Unsupported PBM type P%c!\n", type); - exit(1); - } - if (ferror(fin)) { - fprintf(stderr, "Problem while reading input file '%s", fnin); - perror("'"); - exit(1); - } - if (feof(fin)) { - fprintf(stderr, "Unexpected end of input file '%s'!\n", fnin); - exit(1); - } - - /* JBIG compress another line and write out result via callback */ - jbg85_enc_lineout(&s, next_line, prev_line, prevprev_line); - prevprev_line = prev_line; - prev_line = next_line; - - /* adjust final image height via NEWLEN */ - if (yi && y == yr) - jbg85_enc_newlen(&s, height); - } - - /* check for file errors and close fout */ - if (ferror(fout) || fclose(fout)) { - fprintf(stderr, "Problem while writing output file '%s", fnout); - perror("'"); - exit(1); - } - - return 0; -} diff --git a/thirdparty/jbigkit/pbmtools/pgm.5 b/thirdparty/jbigkit/pbmtools/pgm.5 deleted file mode 100644 index 94a352a1e..000000000 --- a/thirdparty/jbigkit/pbmtools/pgm.5 +++ /dev/null @@ -1,90 +0,0 @@ -.TH pgm 5 "12 November 1991" -.SH NAME -pgm - portable graymap file format -.SH DESCRIPTION -The portable graymap format is a lowest common denominator grayscale -file format. -.IX "PGM file format" -The definition is as follows: -.IP - 2 -A "magic number" for identifying the file type. -A pgm file's magic number is the two characters "P2". -.IX "magic numbers" -.IP - 2 -Whitespace (blanks, TABs, CRs, LFs). -.IP - 2 -A width, formatted as ASCII characters in decimal. -.IP - 2 -Whitespace. -.IP - 2 -A height, again in ASCII decimal. -.IP - 2 -Whitespace. -.IP - 2 -The maximum gray value, again in ASCII decimal. -.IP - 2 -Whitespace. -.IP - 2 -Width * height gray values, each in ASCII decimal, between 0 and the specified -maximum value, separated by whitespace, starting at the top-left -corner of the graymap, proceeding in normal English reading order. -A value of 0 means black, and the maximum value means white. -.IP - 2 -Characters from a "#" to the next end-of-line are ignored (comments). -.IP - 2 -No line should be longer than 70 characters. -.PP -Here is an example of a small graymap in this format: -.nf -P2 -# feep.pgm -24 7 -15 -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 3 3 3 3 0 0 7 7 7 7 0 0 11 11 11 11 0 0 15 15 15 15 0 -0 3 0 0 0 0 0 7 0 0 0 0 0 11 0 0 0 0 0 15 0 0 15 0 -0 3 3 3 0 0 0 7 7 7 0 0 0 11 11 11 0 0 0 15 15 15 15 0 -0 3 0 0 0 0 0 7 0 0 0 0 0 11 0 0 0 0 0 15 0 0 0 0 -0 3 0 0 0 0 0 7 7 7 7 0 0 11 11 11 11 0 0 15 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 -.fi -.PP -Programs that read this format should be as lenient as possible, -accepting anything that looks remotely like a graymap. -.PP -There is also a variant on the format, available -by setting the RAWBITS option at compile time. This variant is -different in the following ways: -.IX RAWBITS -.IP - 2 -The "magic number" is "P5" instead of "P2". -.IP - 2 -The gray values are stored as plain bytes, instead of ASCII decimal. -.IP - 2 -No whitespace is allowed in the grays section, and only a single character -of whitespace (typically a newline) is allowed after the maxval. -.IP - 2 -The files are smaller and many times faster to read and write. -.PP -Note that this raw format can only be used for maxvals less than -or equal to 255. -If you use the -.I pgm -library and try to write a file with a larger maxval, -it will automatically fall back on the slower but more general plain -format. -.SH "SEE ALSO" -fitstopgm(1), fstopgm(1), hipstopgm(1), lispmtopgm(1), psidtopgm(1), -rawtopgm(1), -pgmbentley(1), pgmcrater(1), pgmedge(1), pgmenhance(1), pgmhist(1), pgmnorm(1), -pgmoil(1), pgmramp(1), pgmtexture(1), -pgmtofits(1), pgmtofs(1), pgmtolispm(1), pgmtopbm(1), -pnm(5), pbm(5), ppm(5) -.SH AUTHOR -Copyright (C) 1989, 1991 by Jef Poskanzer. -.\" Permission to use, copy, modify, and distribute this software and its -.\" documentation for any purpose and without fee is hereby granted, provided -.\" that the above copyright notice appear in all copies and that both that -.\" copyright notice and this permission notice appear in supporting -.\" documentation. This software is provided "as is" without express or -.\" implied warranty. diff --git a/thirdparty/libarchive/CMakeLists.txt b/thirdparty/libarchive/CMakeLists.txt deleted file mode 100644 index ff1b025b9..000000000 --- a/thirdparty/libarchive/CMakeLists.txt +++ /dev/null @@ -1,2114 +0,0 @@ -# -CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12 FATAL_ERROR) -if(POLICY CMP0065) - cmake_policy(SET CMP0065 NEW) #3.4 don't use `-rdynamic` with executables -endif() -if(POLICY CMP0074) - cmake_policy(SET CMP0074 NEW) #3.12.0 `find_package()`` uses ``_ROOT`` variables. -endif() -# -PROJECT(libarchive C) -# -SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/build/cmake") -if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY) - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${libarchive_BINARY_DIR}/bin) -endif() -# -# Set the Build type for make based generators. -# You can choose following types: -# Debug : Debug build -# Release : Release build -# RelWithDebInfo : Release build with Debug Info -# MinSizeRel : Release Min Size build -IF(NOT CMAKE_BUILD_TYPE) - SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build Type" FORCE) -ENDIF(NOT CMAKE_BUILD_TYPE) -# Set a value type to properly display CMAKE_BUILD_TYPE on GUI if the -# value type is "UNINITIALIZED". -GET_PROPERTY(cached_type CACHE CMAKE_BUILD_TYPE PROPERTY TYPE) -IF("${cached_type}" STREQUAL "UNINITIALIZED") - SET(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING "Build Type" FORCE) -ENDIF("${cached_type}" STREQUAL "UNINITIALIZED") -# Check the Build Type. -IF(NOT "${CMAKE_BUILD_TYPE}" - MATCHES "^(Debug|Release|RelWithDebInfo|MinSizeRel)\$") - MESSAGE(FATAL_ERROR - "Unknown keyword for CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}\n" - "Acceptable keywords: Debug,Release,RelWithDebInfo,MinSizeRel") -ENDIF(NOT "${CMAKE_BUILD_TYPE}" - MATCHES "^(Debug|Release|RelWithDebInfo|MinSizeRel)\$") - -# On MacOS, prefer MacPorts libraries to system libraries. -# I haven't come up with a compelling argument for this to be conditional. -list(APPEND CMAKE_PREFIX_PATH /opt/local) -# Enable @rpath in the install name. -# detail in "cmake --help-policy CMP0042" -SET(CMAKE_MACOSX_RPATH ON) - -# -# Version - read from 'version' file. -# -FILE(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/build/version _version) -STRING(REGEX REPLACE - "^([0-9])[0-9][0-9][0-9][0-9][0-9][0-9][a-z]*$" "\\1" _major ${_version}) -STRING(REGEX REPLACE - "^[0-9]([0-9][0-9][0-9])[0-9][0-9][0-9][a-z]*$" "\\1" _minor ${_version}) -STRING(REGEX REPLACE - "^[0-9][0-9][0-9][0-9]([0-9][0-9][0-9])[a-z]*$" "\\1" _revision ${_version}) -STRING(REGEX REPLACE - "^[0-9][0-9][0-9][0-9][0-9][0-9][0-9]([a-z]*)$" "\\1" _quality ${_version}) -SET(_version_number ${_major}${_minor}${_revision}) -STRING(REGEX REPLACE "[0]*([^0]*[0-9])$" "\\1" _trimmed_minor ${_minor}) -STRING(REGEX REPLACE "[0]*([^0]*[0-9])$" "\\1" _trimmed_revision ${_revision}) -# -SET(VERSION "${_major}.${_trimmed_minor}.${_trimmed_revision}${_quality}") -SET(BSDCPIO_VERSION_STRING "${VERSION}") -SET(BSDTAR_VERSION_STRING "${VERSION}") -SET(BSDCAT_VERSION_STRING "${VERSION}") -SET(BSDUNZIP_VERSION_STRING "${VERSION}") -SET(LIBARCHIVE_VERSION_NUMBER "${_version_number}") -SET(LIBARCHIVE_VERSION_STRING "${VERSION}") - -# INTERFACE_VERSION increments with every release -# libarchive 2.7 == interface version 9 = 2 + 7 -# libarchive 2.8 == interface version 10 = 2 + 8 -# libarchive 2.9 == interface version 11 = 2 + 9 -# libarchive 3.0 == interface version 12 -# libarchive 3.1 == interface version 13 -math(EXPR INTERFACE_VERSION "13 + ${_minor}") - -# Set SOVERSION == Interface version -# ?? Should there be more here ?? -SET(SOVERSION "${INTERFACE_VERSION}") - -# Enable CMAKE_PUSH_CHECK_STATE() and CMAKE_POP_CHECK_STATE() macros -# saving and restoring the state of the variables. -INCLUDE(CMakePushCheckState) - -# Initialize the state of the variables. This initialization is not -# necessary but this shows you what value the variables initially have. -SET(CMAKE_REQUIRED_DEFINITIONS) -SET(CMAKE_REQUIRED_INCLUDES) -SET(CMAKE_REQUIRED_LIBRARIES) -SET(CMAKE_REQUIRED_FLAGS) -if (CMAKE_BUILD_TYPE STREQUAL "Debug") - OPTION(ENABLE_WERROR "Treat warnings as errors - default is ON for Debug, OFF otherwise." ON) -else () - OPTION(ENABLE_WERROR "Treat warnings as errors - default is ON for Debug, OFF otherwise." OFF) -endif () - -# Especially for early development, we want to be a little -# aggressive about diagnosing build problems; this can get -# relaxed somewhat in final shipping versions. -IF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR - CMAKE_C_COMPILER_ID MATCHES "^Clang$") - SET(CMAKE_REQUIRED_FLAGS "-Wall -Wformat -Wformat-security") - ################################################################# - # Set compile flags for all build types. - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wformat -Wformat-security") - if (ENABLE_WERROR) - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror") - endif () - ################################################################# - # Set compile flags for debug build. - # This is added into CMAKE_C_FLAGS when CMAKE_BUILD_TYPE is "Debug" - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g") - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wextra") - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wunused") - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wshadow") - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wmissing-prototypes") - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wcast-qual") - # Ideally this will be a compile/link time check, yet there's no obvious way - # how considering how old our minimum required cmake version is. The official - # cmake.org side does not host the manual pages even. Normally we can use - # either of the following two, yet neither is supported as of 3.0.2 - # - check_linker_flag - does not exist - # - try_compile - does not support linker flags - # - # The CI fails with this on MacOS - IF(NOT CMAKE_SYSTEM_NAME MATCHES "Darwin") - # Place the functions and data into separate sections, allowing the linker - # to garbage collect the unused ones. - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections") - SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections") - SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections") - # Printing the discarded section is "too much", so enable on demand. - #SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -Wl,--print-gc-sections") - #SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -Wl,--print-gc-sections") - ENDIF(NOT CMAKE_SYSTEM_NAME MATCHES "Darwin") -ENDIF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR - CMAKE_C_COMPILER_ID MATCHES "^Clang$") -IF (CMAKE_C_COMPILER_ID MATCHES "^XL$") - SET(CMAKE_C_COMPILER "xlc_r") - SET(CMAKE_REQUIRED_FLAGS "-qflag=e:e -qformat=sec") - ################################################################# - # Set compile flags for all build types. - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -qflag=e:e -qformat=sec") - if (ENABLE_WERROR) - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -qhalt=w") - endif () - ################################################################# - # Set compile flags for debug build. - # This is added into CMAKE_C_FLAGS when CMAKE_BUILD_TYPE is "Debug" - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g") - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -qflag=w:w") - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -qinfo=pro:use") -ENDIF(CMAKE_C_COMPILER_ID MATCHES "^XL$") -IF (MSVC) - if (ENABLE_WERROR) - # /WX option is the same as gcc's -Werror option. - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX") - endif () - ################################################################# - # Set compile flags for debug build. - # This is added into CMAKE_C_FLAGS when CMAKE_BUILD_TYPE is "Debug" - # Enable level 4 C4062: The enumerate has no associated handler in a switch - # statement and there is no default that can catch it. - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /w14062") - # Enable level 4 C4254: A larger bit field was assigned to a smaller bit - # field. - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /w14254") - # Enable level 4 C4295: An array was initialized but the last character in - # the array is not a null; accessing the array may - # produce unexpected results. - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /w14295") - # Enable level 4 C4296: An unsigned variable was used in a comparison - # operation with zero. - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /w14296") - # Enable level 4 C4389: An operation involved signed and unsigned variables. - # This could result in a loss of data. - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /w14389") - # Enable level 4 C4505: The given function is local and not referenced in - # the body of the module; therefore, the function is - # dead code. - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /w14505") - # Enable level 4 C4514: The optimizer removed an inline function that is not - # called. - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /w14514") - # Enable level 4 C4702: Unreachable code. - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /w14702") - # Enable level 4 C4706: The test value in a conditional expression was the - # result of an assignment. - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /w14706") - # /Oi option enables built-in functions. - SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Oi") - ################################################################# - # Set compile flags for release build. - SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Oi") -ENDIF (MSVC) - -# Enable CTest/CDash support -include(CTest) - -option(BUILD_SHARED_LIBS "Build shared libraries" ON) - -OPTION(ENABLE_MBEDTLS "Enable use of mbed TLS" OFF) -OPTION(ENABLE_NETTLE "Enable use of Nettle" OFF) -OPTION(ENABLE_OPENSSL "Enable use of OpenSSL" ON) -OPTION(ENABLE_LIBB2 "Enable the use of the system LIBB2 library if found" ON) -OPTION(ENABLE_LZ4 "Enable the use of the system LZ4 library if found" ON) -OPTION(ENABLE_LZO "Enable the use of the system LZO library if found" OFF) -OPTION(ENABLE_LZMA "Enable the use of the system LZMA library if found" ON) -OPTION(ENABLE_ZSTD "Enable the use of the system zstd library if found" ON) - -OPTION(ENABLE_ZLIB "Enable the use of the system ZLIB library if found" ON) -OPTION(ENABLE_BZip2 "Enable the use of the system BZip2 library if found" ON) -OPTION(ENABLE_LIBXML2 "Enable the use of the system libxml2 library if found" ON) -OPTION(ENABLE_EXPAT "Enable the use of the system EXPAT library if found" ON) -OPTION(ENABLE_PCREPOSIX "Enable the use of the system PCREPOSIX library if found" ON) -OPTION(ENABLE_LIBGCC "Enable the use of the system LibGCC library if found" ON) -# CNG is used for encrypt/decrypt Zip archives on Windows. -OPTION(ENABLE_CNG "Enable the use of CNG(Crypto Next Generation)" ON) - -OPTION(ENABLE_TAR "Enable tar building" ON) -OPTION(ENABLE_TAR_SHARED "Enable dynamic build of tar" FALSE) -OPTION(ENABLE_CPIO "Enable cpio building" ON) -OPTION(ENABLE_CPIO_SHARED "Enable dynamic build of cpio" FALSE) -OPTION(ENABLE_CAT "Enable cat building" ON) -OPTION(ENABLE_CAT_SHARED "Enable dynamic build of cat" FALSE) -IF(WIN32 AND NOT CYGWIN) - SET(ENABLE_UNZIP FALSE) - SET(ENABLE_UNZIP_SHARED FALSE) -ELSE() - OPTION(ENABLE_UNZIP "Enable unzip building" ON) - OPTION(ENABLE_UNZIP_SHARED "Enable dynamic build of unzip" FALSE) -ENDIF() -OPTION(ENABLE_XATTR "Enable extended attribute support" ON) -OPTION(ENABLE_ACL "Enable ACL support" ON) -OPTION(ENABLE_ICONV "Enable iconv support" ON) -OPTION(ENABLE_TEST "Enable unit and regression tests" ON) -OPTION(ENABLE_COVERAGE "Enable code coverage (GCC only, automatically sets ENABLE_TEST to ON)" FALSE) -OPTION(ENABLE_INSTALL "Enable installing of libraries" ON) - -SET(POSIX_REGEX_LIB "AUTO" CACHE STRING "Choose what library should provide POSIX regular expression support") -SET(ENABLE_SAFESEH "AUTO" CACHE STRING "Enable use of /SAFESEH linker flag (MSVC only)") -SET(WINDOWS_VERSION "WIN10" CACHE STRING "Set Windows version to use (Windows only)") - -IF(ENABLE_COVERAGE) - include(LibarchiveCodeCoverage) -ENDIF(ENABLE_COVERAGE) - -IF(ENABLE_TEST) - ENABLE_TESTING() -ENDIF(ENABLE_TEST) - -IF(WIN32) - IF(WINDOWS_VERSION STREQUAL "WIN10") - SET(NTDDI_VERSION 0x0A000000) - SET(_WIN32_WINNT 0x0A00) - SET(WINVER 0x0A00) - ELSEIF(WINDOWS_VERSION STREQUAL "WIN8") - SET(NTDDI_VERSION 0x06020000) - SET(_WIN32_WINNT 0x0602) - SET(WINVER 0x0602) - ELSEIF(WINDOWS_VERSION STREQUAL "WIN7") - SET(NTDDI_VERSION 0x06010000) - SET(_WIN32_WINNT 0x0601) - SET(WINVER 0x0601) - ELSEIF(WINDOWS_VERSION STREQUAL "WS08") - SET(NTDDI_VERSION 0x06000100) - SET(_WIN32_WINNT 0x0600) - SET(WINVER 0x0600) - ELSEIF(WINDOWS_VERSION STREQUAL "VISTA") - SET(NTDDI_VERSION 0x06000000) - SET(_WIN32_WINNT 0x0600) - SET(WINVER 0x0600) - ELSEIF(WINDOWS_VERSION STREQUAL "WS03") - SET(NTDDI_VERSION 0x05020000) - SET(_WIN32_WINNT 0x0502) - SET(WINVER 0x0502) - ELSEIF(WINDOWS_VERSION STREQUAL "WINXP") - SET(NTDDI_VERSION 0x05010000) - SET(_WIN32_WINNT 0x0501) - SET(WINVER 0x0501) - ELSE(WINDOWS_VERSION STREQUAL "WIN10") - # Default to Windows Server 2003 API if we don't recognize the specifier - SET(NTDDI_VERSION 0x05020000) - SET(_WIN32_WINNT 0x0502) - SET(WINVER 0x0502) - ENDIF(WINDOWS_VERSION STREQUAL "WIN10") -ENDIF(WIN32) - -IF(MSVC) - IF(ENABLE_SAFESEH STREQUAL "YES") - SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH") - SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH") - SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /SAFESEH") - SET(ENV{LDFLAGS} "$ENV{LDFLAGS} /SAFESEH") - ELSEIF(ENABLE_SAFESEH STREQUAL "NO") - SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO") - SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH:NO") - SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /SAFESEH:NO") - SET(ENV{LDFLAGS} "$ENV{LDFLAGS} /SAFESEH:NO") - ENDIF(ENABLE_SAFESEH STREQUAL "YES") -ENDIF(MSVC) - -IF("${CMAKE_C_PLATFORM_ID}" MATCHES "^(HP-UX)$") - ADD_DEFINITIONS(-D_XOPEN_SOURCE=500) # Ask wchar.h for mbstate_t -ENDIF() - -IF(MINGW) - ADD_DEFINITIONS(-D__USE_MINGW_ANSI_STDIO) - ADD_DEFINITIONS(-D__MINGW_USE_VC2005_COMPAT) -ENDIF() - -# -INCLUDE(CheckCSourceCompiles) -INCLUDE(CheckCSourceRuns) -INCLUDE(CheckFileOffsetBits) -INCLUDE(CheckFuncs) -INCLUDE(CheckHeaderDirent) -INCLUDE(CheckIncludeFile) -INCLUDE(CheckIncludeFiles) -INCLUDE(CheckLibraryExists) -INCLUDE(CheckStructHasMember) -INCLUDE(CheckSymbolExists) -INCLUDE(CheckTypeExists) -INCLUDE(CheckTypeSize) - -# -# Generate list.h -# -MACRO (GENERATE_LIST_H _listfile _cmlist __list_sources) - SET(_argv ${ARGV}) - # Remove _listfile and _cmlist from _argv - LIST(REMOVE_AT _argv 0 1) - IF (NOT EXISTS "${_listfile}" OR - ${_cmlist} IS_NEWER_THAN "${_listfile}") - - MESSAGE(STATUS "Generating ${_listfile}") - FILE(WRITE ${_listfile} "") - FOREACH (testfile ${_argv}) - IF (testfile MATCHES "^test_[^/]+[.]c$") - FILE(STRINGS ${testfile} testvar REGEX "^DEFINE_TEST") - FOREACH (deftest ${testvar}) - FILE(APPEND ${_listfile} "${deftest}\n") - ENDFOREACH (deftest) - ENDIF (testfile MATCHES "^test_[^/]+[.]c$") - ENDFOREACH (testfile) - - ENDIF (NOT EXISTS "${_listfile}" OR - ${_cmlist} IS_NEWER_THAN "${_listfile}") -ENDMACRO (GENERATE_LIST_H) -# -# Generate installation rules for man pages. -# -MACRO (INSTALL_MAN __mans) - FOREACH (_man ${ARGV}) - STRING(REGEX REPLACE "^.+[.]([1-9])" "\\1" _mansect ${_man}) - INSTALL(FILES ${_man} DESTINATION "share/man/man${_mansect}") - ENDFOREACH (_man) -ENDMACRO (INSTALL_MAN __mans) -# -# Find out what macro is needed to use libraries on Windows. -# -MACRO (TRY_MACRO_FOR_LIBRARY INCLUDES LIBRARIES - TRY_TYPE SAMPLE_SOURCE MACRO_LIST) - IF(WIN32 AND NOT CYGWIN) - CMAKE_PUSH_CHECK_STATE() # Save the state of the variables - SET(CMAKE_REQUIRED_INCLUDES ${INCLUDES}) - SET(CMAKE_REQUIRED_LIBRARIES ${LIBRARIES}) - FOREACH(VAR ${MACRO_LIST}) - # Clear ${VAR} from CACHE If the libraries which ${VAR} was - # checked with are changed. - SET(VAR_WITH_LIB "${VAR}_WITH_LIB") - GET_PROPERTY(PREV_VAR_WITH_LIB VARIABLE PROPERTY ${VAR_WITH_LIB}) - IF(NOT "${PREV_VAR_WITH_LIB}" STREQUAL "${LIBRARIES}") - UNSET(${VAR} CACHE) - ENDIF(NOT "${PREV_VAR_WITH_LIB}" STREQUAL "${LIBRARIES}") - # Check if the library can be used with the macro. - IF("${TRY_TYPE}" MATCHES "COMPILES") - CHECK_C_SOURCE_COMPILES("${SAMPLE_SOURCE}" ${VAR}) - ELSEIF("${TRY_TYPE}" MATCHES "RUNS") - IF(CMAKE_CROSSCOMPILING) - MESSAGE(WARNING "Cannot test run \"${VAR}\" when cross-compiling") - ELSE(CMAKE_CROSSCOMPILING) - CHECK_C_SOURCE_RUNS("${SAMPLE_SOURCE}" ${VAR}) - ENDIF(CMAKE_CROSSCOMPILING) - ELSE("${TRY_TYPE}" MATCHES "COMPILES") - MESSAGE(FATAL_ERROR "UNKNOWN KEYWORD \"${TRY_TYPE}\" FOR TRY_TYPE") - ENDIF("${TRY_TYPE}" MATCHES "COMPILES") - # Save the libraries which ${VAR} is checked with. - SET(${VAR_WITH_LIB} "${LIBRARIES}" CACHE INTERNAL - "Macro ${VAR} is checked with") - ENDFOREACH(VAR) - CMAKE_POP_CHECK_STATE() # Restore the state of the variables - ENDIF(WIN32 AND NOT CYGWIN) -ENDMACRO (TRY_MACRO_FOR_LIBRARY) -# -# Check compress/decompress libraries -# -IF(WIN32 AND NOT CMAKE_CL_64 AND NOT CYGWIN) - # GnuWin32 is only for Win32, not Win64. - SET(__GNUWIN32PATH "C:/Program Files/GnuWin32") -ENDIF(WIN32 AND NOT CMAKE_CL_64 AND NOT CYGWIN) -IF(DEFINED __GNUWIN32PATH AND EXISTS "${__GNUWIN32PATH}") - # You have to add a path available DLL file into PATH environment variable. - # Maybe DLL path is "C:/Program Files/GnuWin32/bin". - # The zlib and the bzip2 Setup program have installed programs and DLLs into - # "C:/Program Files/GnuWin32" by default. - # This is convenience setting for Windows. - SET(CMAKE_PREFIX_PATH ${__GNUWIN32PATH} $(CMAKE_PREFIX_PATH)) - # - # If you didn't use Setup program or installed into nonstandard path, - # cmake cannot find out your zlib or bzip2 libraries and include files, - # you should execute cmake with -DCMAKE_PREFIX_PATH option. - # e.g. - # cmake -DCMAKE_PREFIX_PATH= - # - # If compiling error occurred in zconf.h, You may need patch to zconf.h. - #--- zconf.h.orig 2005-07-21 00:40:26.000000000 - #+++ zconf.h 2009-01-19 11:39:10.093750000 - #@@ -286,7 +286,7 @@ - # - # #if 1 /* HAVE_UNISTD_H -- this line is updated by ./configure */ - # # include /* for off_t */ - #-# include /* for SEEK_* and off_t */ - #+# include /* for SEEK_* and off_t */ - # # ifdef VMS - # # include /* for off_t */ - # # endif -ENDIF(DEFINED __GNUWIN32PATH AND EXISTS "${__GNUWIN32PATH}") - -SET(ADDITIONAL_LIBS "") -# -# Find ZLIB -# -IF(ENABLE_ZLIB) - FIND_PACKAGE(ZLIB) -ELSE() - SET(ZLIB_FOUND FALSE) # Override cached value -ENDIF() -IF(ZLIB_FOUND) - SET(HAVE_LIBZ 1) - SET(HAVE_ZLIB_H 1) - INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR}) - LIST(APPEND ADDITIONAL_LIBS ${ZLIB_LIBRARIES}) - IF(WIN32 AND NOT CYGWIN) - # - # Test if ZLIB_WINAPI macro is needed to use. - # - TRY_MACRO_FOR_LIBRARY( - "${ZLIB_INCLUDE_DIR}" "${ZLIB_LIBRARIES}" - RUNS - "#include \nint main() {uLong f = zlibCompileFlags(); return (f&(1U<<10))?0:-1; }" - ZLIB_WINAPI) - IF(ZLIB_WINAPI) - ADD_DEFINITIONS(-DZLIB_WINAPI) - ELSE(ZLIB_WINAPI) - # Test if a macro is needed for the library. - TRY_MACRO_FOR_LIBRARY( - "${ZLIB_INCLUDE_DIR}" "${ZLIB_LIBRARIES}" - COMPILES - "#include \nint main() {return zlibVersion()?1:0; }" - "ZLIB_DLL;WITHOUT_ZLIB_DLL") - IF(ZLIB_DLL) - ADD_DEFINITIONS(-DZLIB_DLL) - ENDIF(ZLIB_DLL) - ENDIF(ZLIB_WINAPI) - ENDIF(WIN32 AND NOT CYGWIN) -ENDIF(ZLIB_FOUND) -MARK_AS_ADVANCED(CLEAR ZLIB_INCLUDE_DIR) -MARK_AS_ADVANCED(CLEAR ZLIB_LIBRARY) -# -# Find BZip2 -# -IF(ENABLE_BZip2) - FIND_PACKAGE(BZip2) -ELSE() - SET(BZIP2_FOUND FALSE) # Override cached value -ENDIF() -IF(BZIP2_FOUND) - SET(HAVE_LIBBZ2 1) - SET(HAVE_BZLIB_H 1) - INCLUDE_DIRECTORIES(${BZIP2_INCLUDE_DIR}) - LIST(APPEND ADDITIONAL_LIBS ${BZIP2_LIBRARIES}) - # Test if a macro is needed for the library. - TRY_MACRO_FOR_LIBRARY( - "${BZIP2_INCLUDE_DIR}" "${BZIP2_LIBRARIES}" - COMPILES - "#include \nint main() {return BZ2_bzlibVersion()?1:0; }" - "USE_BZIP2_DLL;USE_BZIP2_STATIC") - IF(USE_BZIP2_DLL) - ADD_DEFINITIONS(-DUSE_BZIP2_DLL) - ELSEIF(USE_BZIP2_STATIC) - ADD_DEFINITIONS(-DUSE_BZIP2_STATIC) - ENDIF(USE_BZIP2_DLL) -ENDIF(BZIP2_FOUND) -MARK_AS_ADVANCED(CLEAR BZIP2_INCLUDE_DIR) -MARK_AS_ADVANCED(CLEAR BZIP2_LIBRARIES) - - -# -# Find LZMA -# -IF(ENABLE_LZMA) - FIND_PACKAGE(LibLZMA) -ELSE() - SET(LIBLZMA_FOUND FALSE) # Override cached value -ENDIF() - -IF(LIBLZMA_FOUND) - SET(HAVE_LIBLZMA 1) - SET(HAVE_LZMA_H 1) - CMAKE_PUSH_CHECK_STATE() - SET(CMAKE_REQUIRED_INCLUDES ${LIBLZMA_INCLUDE_DIR}) - SET(CMAKE_REQUIRED_LIBRARIES ${LIBLZMA_LIBRARIES}) - INCLUDE_DIRECTORIES(${LIBLZMA_INCLUDE_DIRS}) - LIST(APPEND ADDITIONAL_LIBS ${LIBLZMA_LIBRARIES}) - # Test if a macro is needed for the library. - TRY_MACRO_FOR_LIBRARY( - "${LIBLZMA_INCLUDE_DIRS}" "${LIBLZMA_LIBRARIES}" - COMPILES - "#include \nint main() {return (int)lzma_version_number(); }" - "WITHOUT_LZMA_API_STATIC;LZMA_API_STATIC") - CHECK_C_SOURCE_COMPILES( - "#include \n#if LZMA_VERSION < 50020000\n#error unsupported\n#endif\nint main(void){lzma_stream_encoder_mt(0, 0); return 0;}" - HAVE_LZMA_STREAM_ENCODER_MT) - IF(NOT WITHOUT_LZMA_API_STATIC AND LZMA_API_STATIC) - ADD_DEFINITIONS(-DLZMA_API_STATIC) - ENDIF(NOT WITHOUT_LZMA_API_STATIC AND LZMA_API_STATIC) - CMAKE_POP_CHECK_STATE() -ELSE(LIBLZMA_FOUND) -# LZMA not found and will not be used. - SET(HAVE_LZMA_STREAM_ENCODER_MT 0) -ENDIF(LIBLZMA_FOUND) -MARK_AS_ADVANCED(CLEAR LIBLZMA_INCLUDE_DIR) -MARK_AS_ADVANCED(CLEAR LIBLZMA_LIBRARY) - -# -# Find LZO2 -# -IF(ENABLE_LZO) - IF (LZO2_INCLUDE_DIR) - # Already in cache, be silent - SET(LZO2_FIND_QUIETLY TRUE) - ENDIF (LZO2_INCLUDE_DIR) - - FIND_PATH(LZO2_INCLUDE_DIR lzo/lzoconf.h) - FIND_LIBRARY(LZO2_LIBRARY NAMES lzo2 liblzo2) - INCLUDE(FindPackageHandleStandardArgs) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(LZO2 DEFAULT_MSG LZO2_LIBRARY LZO2_INCLUDE_DIR) -ELSE(ENABLE_LZO) - SET(LZO2_FOUND FALSE) # Override cached value -ENDIF(ENABLE_LZO) -IF(LZO2_FOUND) - SET(HAVE_LIBLZO2 1) - SET(HAVE_LZO_LZOCONF_H 1) - SET(HAVE_LZO_LZO1X_H 1) - INCLUDE_DIRECTORIES(${LZO2_INCLUDE_DIR}) - LIST(APPEND ADDITIONAL_LIBS ${LZO2_LIBRARY}) - # - # TODO: test for static library. - # -ENDIF(LZO2_FOUND) -MARK_AS_ADVANCED(CLEAR LZO2_INCLUDE_DIR) -MARK_AS_ADVANCED(CLEAR LZO2_LIBRARY) -# -# Find libb2 -# -IF(ENABLE_LIBB2) - IF (LIBB2_INCLUDE_DIR) - # Already in cache, be silent - SET(LIBB2_FIND_QUIETLY TRUE) - ENDIF (LIBB2_INCLUDE_DIR) - - FIND_PATH(LIBB2_INCLUDE_DIR blake2.h) - FIND_LIBRARY(LIBB2_LIBRARY NAMES b2 libb2) - INCLUDE(FindPackageHandleStandardArgs) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBB2 DEFAULT_MSG LIBB2_LIBRARY LIBB2_INCLUDE_DIR) -ELSE(ENABLE_LIBB2) - SET(LIBB2_FOUND FALSE) # Override cached value -ENDIF(ENABLE_LIBB2) -IF(LIBB2_FOUND) - SET(HAVE_LIBB2 1) - SET(HAVE_BLAKE2_H 1) - SET(ARCHIVE_BLAKE2 FALSE) - LIST(APPEND ADDITIONAL_LIBS ${LIBB2_LIBRARY}) - INCLUDE_DIRECTORIES(${LIBB2_INCLUDE_DIR}) - CMAKE_PUSH_CHECK_STATE() - SET(CMAKE_REQUIRED_LIBRARIES ${LIBB2_LIBRARY}) - SET(CMAKE_REQUIRED_INCLUDES ${LIBB2_INCLUDE_DIR}) - CHECK_FUNCTION_EXISTS(blake2sp_init HAVE_LIBB2) - CMAKE_POP_CHECK_STATE() -ELSE(LIBB2_FOUND) - SET(ARCHIVE_BLAKE2 TRUE) -ENDIF(LIBB2_FOUND) -# -# Find LZ4 -# -IF(ENABLE_LZ4) - IF (LZ4_INCLUDE_DIR) - # Already in cache, be silent - SET(LZ4_FIND_QUIETLY TRUE) - ENDIF (LZ4_INCLUDE_DIR) - - FIND_PATH(LZ4_INCLUDE_DIR lz4.h) - FIND_LIBRARY(LZ4_LIBRARY NAMES lz4 liblz4) - INCLUDE(FindPackageHandleStandardArgs) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(LZ4 DEFAULT_MSG LZ4_LIBRARY LZ4_INCLUDE_DIR) -ELSE(ENABLE_LZ4) - SET(LZ4_FOUND FALSE) # Override cached value -ENDIF(ENABLE_LZ4) -IF(LZ4_FOUND) - SET(HAVE_LIBLZ4 1) - SET(HAVE_LZ4_H 1) - CMAKE_PUSH_CHECK_STATE() # Save the state of the variables - SET(CMAKE_REQUIRED_INCLUDES ${LZ4_INCLUDE_DIR}) - CHECK_INCLUDE_FILES("lz4hc.h" HAVE_LZ4HC_H) - CMAKE_POP_CHECK_STATE() # Restore the state of the variables - INCLUDE_DIRECTORIES(${LZ4_INCLUDE_DIR}) - LIST(APPEND ADDITIONAL_LIBS ${LZ4_LIBRARY}) - # - # TODO: test for static library. - # -ENDIF(LZ4_FOUND) -MARK_AS_ADVANCED(CLEAR LZ4_INCLUDE_DIR) -MARK_AS_ADVANCED(CLEAR LZ4_LIBRARY) -# -# Find Zstd -# -IF(ENABLE_ZSTD) - IF (ZSTD_INCLUDE_DIR) - # Already in cache, be silent - SET(ZSTD_FIND_QUIETLY TRUE) - ENDIF (ZSTD_INCLUDE_DIR) - - IF(UNIX) - FIND_PACKAGE(PkgConfig QUIET) - PKG_SEARCH_MODULE(PC_ZSTD libzstd) - ENDIF() - - FIND_PATH(ZSTD_INCLUDE_DIR zstd.h HINTS ${PC_ZSTD_INCLUDEDIR} ${PC_ZSTD_INCLUDE_DIRS}) - FIND_LIBRARY(ZSTD_LIBRARY NAMES zstd libzstd HINTS ${PC_ZSTD_LIBDIR} ${PC_ZSTD_LIBRARY_DIRS}) - INCLUDE(FindPackageHandleStandardArgs) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZSTD DEFAULT_MSG ZSTD_LIBRARY ZSTD_INCLUDE_DIR) -ELSE(ENABLE_ZSTD) - SET(ZSTD_FOUND FALSE) # Override cached value -ENDIF(ENABLE_ZSTD) -IF(ZSTD_FOUND) - SET(HAVE_ZSTD_H 1) - INCLUDE_DIRECTORIES(${ZSTD_INCLUDE_DIR}) - LIST(APPEND ADDITIONAL_LIBS ${ZSTD_LIBRARY}) - CMAKE_PUSH_CHECK_STATE() - SET(CMAKE_REQUIRED_LIBRARIES ${ZSTD_LIBRARY}) - SET(CMAKE_REQUIRED_INCLUDES ${ZSTD_INCLUDE_DIR}) - CHECK_FUNCTION_EXISTS(ZSTD_decompressStream HAVE_LIBZSTD) - CHECK_FUNCTION_EXISTS(ZSTD_compressStream HAVE_LIBZSTD_COMPRESSOR) - # - # TODO: test for static library. - # - CMAKE_POP_CHECK_STATE() -ENDIF(ZSTD_FOUND) -MARK_AS_ADVANCED(CLEAR ZSTD_INCLUDE_DIR) -MARK_AS_ADVANCED(CLEAR ZSTD_LIBRARY) - - -# -# Check headers -# -CHECK_HEADER_DIRENT() - -SET(INCLUDES "") -MACRO (LA_CHECK_INCLUDE_FILE header var) - CHECK_INCLUDE_FILES("${INCLUDES};${header}" ${var}) - IF (${var}) - SET(INCLUDES ${INCLUDES} ${header}) - ENDIF (${var}) -ENDMACRO (LA_CHECK_INCLUDE_FILE) - -# Some FreeBSD headers assume sys/types.h was already included. -LA_CHECK_INCLUDE_FILE("sys/types.h" HAVE_SYS_TYPES_H) - -# Alphabetize the rest unless there's a compelling reason -LA_CHECK_INCLUDE_FILE("acl/libacl.h" HAVE_ACL_LIBACL_H) -LA_CHECK_INCLUDE_FILE("attr/xattr.h" HAVE_ATTR_XATTR_H) -LA_CHECK_INCLUDE_FILE("ctype.h" HAVE_CTYPE_H) -LA_CHECK_INCLUDE_FILE("copyfile.h" HAVE_COPYFILE_H) -LA_CHECK_INCLUDE_FILE("direct.h" HAVE_DIRECT_H) -LA_CHECK_INCLUDE_FILE("dlfcn.h" HAVE_DLFCN_H) -LA_CHECK_INCLUDE_FILE("errno.h" HAVE_ERRNO_H) -LA_CHECK_INCLUDE_FILE("ext2fs/ext2_fs.h" HAVE_EXT2FS_EXT2_FS_H) - -CHECK_C_SOURCE_COMPILES("#include -#include -int main(void) { return EXT2_IOC_GETFLAGS; }" HAVE_WORKING_EXT2_IOC_GETFLAGS) - -LA_CHECK_INCLUDE_FILE("fcntl.h" HAVE_FCNTL_H) -LA_CHECK_INCLUDE_FILE("fnmatch.h" HAVE_FNMATCH_H) -LA_CHECK_INCLUDE_FILE("grp.h" HAVE_GRP_H) -LA_CHECK_INCLUDE_FILE("inttypes.h" HAVE_INTTYPES_H) -LA_CHECK_INCLUDE_FILE("io.h" HAVE_IO_H) -LA_CHECK_INCLUDE_FILE("langinfo.h" HAVE_LANGINFO_H) -LA_CHECK_INCLUDE_FILE("limits.h" HAVE_LIMITS_H) -LA_CHECK_INCLUDE_FILE("linux/types.h" HAVE_LINUX_TYPES_H) -LA_CHECK_INCLUDE_FILE("linux/fiemap.h" HAVE_LINUX_FIEMAP_H) -LA_CHECK_INCLUDE_FILE("linux/fs.h" HAVE_LINUX_FS_H) - -CHECK_C_SOURCE_COMPILES("#include -#include -int main(void) { return FS_IOC_GETFLAGS; }" HAVE_WORKING_FS_IOC_GETFLAGS) - -LA_CHECK_INCLUDE_FILE("linux/magic.h" HAVE_LINUX_MAGIC_H) -LA_CHECK_INCLUDE_FILE("locale.h" HAVE_LOCALE_H) -LA_CHECK_INCLUDE_FILE("membership.h" HAVE_MEMBERSHIP_H) -LA_CHECK_INCLUDE_FILE("memory.h" HAVE_MEMORY_H) -LA_CHECK_INCLUDE_FILE("paths.h" HAVE_PATHS_H) -LA_CHECK_INCLUDE_FILE("poll.h" HAVE_POLL_H) -LA_CHECK_INCLUDE_FILE("process.h" HAVE_PROCESS_H) -LA_CHECK_INCLUDE_FILE("pthread.h" HAVE_PTHREAD_H) -LA_CHECK_INCLUDE_FILE("pwd.h" HAVE_PWD_H) -LA_CHECK_INCLUDE_FILE("readpassphrase.h" HAVE_READPASSPHRASE_H) -LA_CHECK_INCLUDE_FILE("regex.h" HAVE_REGEX_H) -LA_CHECK_INCLUDE_FILE("signal.h" HAVE_SIGNAL_H) -LA_CHECK_INCLUDE_FILE("spawn.h" HAVE_SPAWN_H) -LA_CHECK_INCLUDE_FILE("stdarg.h" HAVE_STDARG_H) -LA_CHECK_INCLUDE_FILE("stdint.h" HAVE_STDINT_H) -LA_CHECK_INCLUDE_FILE("stdlib.h" HAVE_STDLIB_H) -LA_CHECK_INCLUDE_FILE("string.h" HAVE_STRING_H) -LA_CHECK_INCLUDE_FILE("strings.h" HAVE_STRINGS_H) -LA_CHECK_INCLUDE_FILE("sys/acl.h" HAVE_SYS_ACL_H) -LA_CHECK_INCLUDE_FILE("sys/cdefs.h" HAVE_SYS_CDEFS_H) -LA_CHECK_INCLUDE_FILE("sys/extattr.h" HAVE_SYS_EXTATTR_H) -LA_CHECK_INCLUDE_FILE("sys/ioctl.h" HAVE_SYS_IOCTL_H) -LA_CHECK_INCLUDE_FILE("sys/mkdev.h" HAVE_SYS_MKDEV_H) -LA_CHECK_INCLUDE_FILE("sys/mount.h" HAVE_SYS_MOUNT_H) -LA_CHECK_INCLUDE_FILE("sys/param.h" HAVE_SYS_PARAM_H) -LA_CHECK_INCLUDE_FILE("sys/poll.h" HAVE_SYS_POLL_H) -LA_CHECK_INCLUDE_FILE("sys/queue.h" HAVE_SYS_QUEUE_H) -LA_CHECK_INCLUDE_FILE("sys/richacl.h" HAVE_SYS_RICHACL_H) -LA_CHECK_INCLUDE_FILE("sys/select.h" HAVE_SYS_SELECT_H) -LA_CHECK_INCLUDE_FILE("sys/stat.h" HAVE_SYS_STAT_H) -LA_CHECK_INCLUDE_FILE("sys/statfs.h" HAVE_SYS_STATFS_H) -LA_CHECK_INCLUDE_FILE("sys/statvfs.h" HAVE_SYS_STATVFS_H) -LA_CHECK_INCLUDE_FILE("sys/sysmacros.h" HAVE_SYS_SYSMACROS_H) -LA_CHECK_INCLUDE_FILE("sys/time.h" HAVE_SYS_TIME_H) -LA_CHECK_INCLUDE_FILE("sys/utime.h" HAVE_SYS_UTIME_H) -LA_CHECK_INCLUDE_FILE("sys/utsname.h" HAVE_SYS_UTSNAME_H) -LA_CHECK_INCLUDE_FILE("sys/vfs.h" HAVE_SYS_VFS_H) -LA_CHECK_INCLUDE_FILE("sys/wait.h" HAVE_SYS_WAIT_H) -LA_CHECK_INCLUDE_FILE("sys/xattr.h" HAVE_SYS_XATTR_H) -LA_CHECK_INCLUDE_FILE("time.h" HAVE_TIME_H) -LA_CHECK_INCLUDE_FILE("unistd.h" HAVE_UNISTD_H) -LA_CHECK_INCLUDE_FILE("utime.h" HAVE_UTIME_H) -LA_CHECK_INCLUDE_FILE("wchar.h" HAVE_WCHAR_H) -LA_CHECK_INCLUDE_FILE("wctype.h" HAVE_WCTYPE_H) -LA_CHECK_INCLUDE_FILE("windows.h" HAVE_WINDOWS_H) -IF(ENABLE_CNG) - LA_CHECK_INCLUDE_FILE("bcrypt.h" HAVE_BCRYPT_H) - IF(HAVE_BCRYPT_H) - LIST(APPEND ADDITIONAL_LIBS "bcrypt") - ENDIF(HAVE_BCRYPT_H) -ELSE(ENABLE_CNG) - UNSET(HAVE_BCRYPT_H CACHE) -ENDIF(ENABLE_CNG) -# Following files need windows.h, so we should test it after windows.h test. -LA_CHECK_INCLUDE_FILE("wincrypt.h" HAVE_WINCRYPT_H) -LA_CHECK_INCLUDE_FILE("winioctl.h" HAVE_WINIOCTL_H) - -# -# Check whether use of __EXTENSIONS__ is safe. -# We need some macro such as _GNU_SOURCE to use extension functions. -# -SET(_INCLUDE_FILES) -FOREACH (it ${_HEADER}) - SET(_INCLUDE_FILES "${_INCLUDE_FILES}#include <${it}>\n") -ENDFOREACH (it) - -CHECK_C_SOURCE_COMPILES( - "#define __EXTENSIONS__ 1 - ${_INCLUDE_FILES} - int main() { return 0;}" - SAFE_TO_DEFINE_EXTENSIONS) - -# -# Find mbed TLS -# -IF(ENABLE_MBEDTLS) - FIND_PACKAGE(MbedTLS) - IF(MBEDTLS_FOUND) - SET(HAVE_LIBMBEDCRYPTO 1) - LIST(APPEND ADDITIONAL_LIBS ${MBEDCRYPTO_LIBRARY}) - INCLUDE_DIRECTORIES(${MBEDTLS_INCLUDE_DIRS}) - - LIST(APPEND CMAKE_REQUIRED_INCLUDES ${MBEDTLS_INCLUDE_DIRS}) - LA_CHECK_INCLUDE_FILE("mbedtls/aes.h" HAVE_MBEDTLS_AES_H) - LA_CHECK_INCLUDE_FILE("mbedtls/md.h" HAVE_MBEDTLS_MD_H) - LA_CHECK_INCLUDE_FILE("mbedtls/pkcs5.h" HAVE_MBEDTLS_PKCS5_H) - - ENDIF(MBEDTLS_FOUND) - MARK_AS_ADVANCED(CLEAR MBEDTLS_INCLUDE_DIRS) - MARK_AS_ADVANCED(CLEAR MBEDCRYPTO_LIBRARY) -ENDIF(ENABLE_MBEDTLS) - -# -# Find Nettle -# -IF(ENABLE_NETTLE) - FIND_PACKAGE(Nettle) - IF(NETTLE_FOUND) - SET(HAVE_LIBNETTLE 1) - LIST(APPEND ADDITIONAL_LIBS ${NETTLE_LIBRARIES}) - INCLUDE_DIRECTORIES(${NETTLE_INCLUDE_DIR}) - - LIST(APPEND CMAKE_REQUIRED_INCLUDES ${NETTLE_INCLUDE_DIR}) - LA_CHECK_INCLUDE_FILE("nettle/aes.h" HAVE_NETTLE_AES_H) - LA_CHECK_INCLUDE_FILE("nettle/hmac.h" HAVE_NETTLE_HMAC_H) - LA_CHECK_INCLUDE_FILE("nettle/md5.h" HAVE_NETTLE_MD5_H) - LA_CHECK_INCLUDE_FILE("nettle/pbkdf2.h" HAVE_NETTLE_PBKDF2_H) - LA_CHECK_INCLUDE_FILE("nettle/ripemd160.h" HAVE_NETTLE_RIPEMD160_H) - LA_CHECK_INCLUDE_FILE("nettle/sha.h" HAVE_NETTLE_SHA_H) - - ENDIF(NETTLE_FOUND) - MARK_AS_ADVANCED(CLEAR NETTLE_INCLUDE_DIR) - MARK_AS_ADVANCED(CLEAR NETTLE_LIBRARIES) -ENDIF(ENABLE_NETTLE) - -# -# Find OpenSSL -# (Except on Mac, where OpenSSL is deprecated.) -# -IF(ENABLE_OPENSSL AND NOT CMAKE_SYSTEM_NAME MATCHES "Darwin") - FIND_PACKAGE(OpenSSL) - IF(OPENSSL_FOUND) - SET(HAVE_LIBCRYPTO 1) - INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR}) - LIST(APPEND ADDITIONAL_LIBS ${OPENSSL_CRYPTO_LIBRARY}) - SET(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY}) - SET(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR}) - LA_CHECK_INCLUDE_FILE("openssl/evp.h" HAVE_OPENSSL_EVP_H) - CHECK_FUNCTION_EXISTS(PKCS5_PBKDF2_HMAC_SHA1 HAVE_PKCS5_PBKDF2_HMAC_SHA1) - ENDIF(OPENSSL_FOUND) -ELSE() - SET(OPENSSL_FOUND FALSE) # Override cached value -ENDIF() - -# FreeBSD libmd -IF(NOT OPENSSL_FOUND) - CHECK_LIBRARY_EXISTS(md "MD5Init" "" LIBMD_FOUND) - IF(LIBMD_FOUND) - CMAKE_PUSH_CHECK_STATE() # Save the state of the variables - SET(CMAKE_REQUIRED_LIBRARIES "md") - FIND_LIBRARY(LIBMD_LIBRARY NAMES md) - LIST(APPEND ADDITIONAL_LIBS ${LIBMD_LIBRARY}) - CMAKE_POP_CHECK_STATE() # Restore the state of the variables - ENDIF(LIBMD_FOUND) -ENDIF(NOT OPENSSL_FOUND) - -# -# How to prove that CRYPTO functions, which have several names on various -# platforms, just see if archive_digest.c can compile and link against -# required libraries. -# -MACRO(CHECK_CRYPTO ALGORITHMS IMPLEMENTATION) - FOREACH(ALGORITHM ${ALGORITHMS}) - IF(NOT ARCHIVE_CRYPTO_${ALGORITHM}) - STRING(TOLOWER "${ALGORITHM}" lower_algorithm) - STRING(TOUPPER "${ALGORITHM}" algorithm) - IF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND NOT OPENSSL_FOUND) - SET(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} FALSE) - ELSEIF("${IMPLEMENTATION}" MATCHES "^MBEDTLS$" AND NOT MBEDTLS_FOUND) - SET(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} FALSE) - ELSEIF("${IMPLEMENTATION}" MATCHES "^NETTLE$" AND NOT NETTLE_FOUND) - SET(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} FALSE) - ENDIF("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND NOT OPENSSL_FOUND) - - IF(NOT DEFINED ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}) - # Probe the local implementation for whether this - # crypto implementation is available on this platform. - SET(TRY_CRYPTO_REQUIRED_INCLUDES - "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_BINARY_DIR};${CMAKE_CURRENT_SOURCE_DIR}/libarchive;${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp") - SET(TRY_CRYPTO_REQUIRED_LIBS) - IF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND) - SET(TRY_CRYPTO_REQUIRED_INCLUDES - "${TRY_CRYPTO_REQUIRED_INCLUDES};${OPENSSL_INCLUDE_DIR}") - SET(TRY_CRYPTO_REQUIRED_LIBS - "-DLINK_LIBRARIES:STRING=${OPENSSL_LIBRARIES}") - ELSEIF("${IMPLEMENTATION}" MATCHES "^MBEDTLS$" AND MBEDTLS_FOUND) - SET(TRY_CRYPTO_REQUIRED_INCLUDES - "${TRY_CRYPTO_REQUIRED_INCLUDES};${MBEDTLS_INCLUDE_DIRS}") - SET(TRY_CRYPTO_REQUIRED_LIBS - "-DLINK_LIBRARIES:STRING=${MBEDCRYPTO_LIBRARY}") - ELSEIF("${IMPLEMENTATION}" MATCHES "^NETTLE$" AND NETTLE_FOUND) - SET(TRY_CRYPTO_REQUIRED_INCLUDES - "${TRY_CRYPTO_REQUIRED_INCLUDES};${NETTLE_INCLUDE_DIR}") - SET(TRY_CRYPTO_REQUIRED_LIBS - "-DLINK_LIBRARIES:STRING=${NETTLE_LIBRARY}") - ELSEIF("${IMPLEMENTATION}" MATCHES "^LIBMD$" AND LIBMD_FOUND) - SET(TRY_CRYPTO_REQUIRED_LIBS - "-DLINK_LIBRARIES:STRING=${LIBMD_LIBRARY}") - ENDIF("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND) - - CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/build/cmake/config.h.in - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/confdefs.h) - FILE(READ "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/confdefs.h" - CONFDEFS_H) - FILE(READ "${CMAKE_CURRENT_SOURCE_DIR}/libarchive/archive_digest.c" - ARCHIVE_CRYPTO_C) - - SET(SOURCE "${CONFDEFS_H} - -#define ARCHIVE_${algorithm}_COMPILE_TEST -#define ARCHIVE_CRYPTO_${algorithm}_${IMPLEMENTATION} -#define PLATFORM_CONFIG_H \"check_crypto_md.h\" - -${ARCHIVE_CRYPTO_C} - -int -main(int argc, char **argv) -{ - archive_${lower_algorithm}_ctx ctx; - archive_${lower_algorithm}_init(&ctx); - archive_${lower_algorithm}_update(&ctx, *argv, argc); - archive_${lower_algorithm}_final(&ctx, NULL); - return 0; -} -") - - FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_md.h" "") - FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_md.c" "${SOURCE}") - MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}") - - TRY_COMPILE(ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} - ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_md.c - CMAKE_FLAGS - "${TRY_CRYPTO_REQUIRED_LIBS}" - "${TRY_CRYPTO_REQUIRED_INCLUDES}" - OUTPUT_VARIABLE OUTPUT) - - # Inform user whether or not we found it; if not, log why we didn't. - IF (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}) - MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} -- found") - SET(ARCHIVE_CRYPTO_${ALGORITHM} 1) - ELSE (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}) - MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} -- not found") - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Checking support for ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION} failed with the following output:\n" - "${OUTPUT}\n" - "Source file was:\n${SOURCE}\n") - ENDIF (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}) - ENDIF(NOT DEFINED ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}) - - # Add appropriate libs/includes depending on whether the implementation - # was found on this platform. - IF (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}) - IF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND) - INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR}) - LIST(APPEND ADDITIONAL_LIBS ${OPENSSL_LIBRARIES}) - LIST(REMOVE_DUPLICATES ADDITIONAL_LIBS) - ENDIF ("${IMPLEMENTATION}" MATCHES "^OPENSSL$" AND OPENSSL_FOUND) - ENDIF (ARCHIVE_CRYPTO_${ALGORITHM}_${IMPLEMENTATION}) - ENDIF(NOT ARCHIVE_CRYPTO_${ALGORITHM}) - ENDFOREACH(ALGORITHM ${ALGORITHMS}) -ENDMACRO(CHECK_CRYPTO ALGORITHMS IMPLEMENTATION) - -# -# CRYPTO functions on Windows is defined at archive_windows.c, thus we do not -# need the test what the functions can be mapped to archive_{crypto name}_init, -# archive_{crypto name}_update and archive_{crypto name}_final. -# The functions on Windows use CALG_{crypto name} macro to create a crypt object -# and then we need to know what CALG_{crypto name} macros is available to show -# ARCHIVE_CRYPTO_{crypto name}_WIN macros because Windows 2000 and earlier version -# of Windows XP do not support SHA256, SHA384 and SHA512. -# -MACRO(CHECK_CRYPTO_WIN CRYPTO_LIST) - IF(WIN32 AND NOT CYGWIN) - FOREACH(CRYPTO ${CRYPTO_LIST}) - IF(NOT ARCHIVE_CRYPTO_${CRYPTO}) - IF(NOT DEFINED ARCHIVE_CRYPTO_${CRYPTO}_WIN) - STRING(TOUPPER "${CRYPTO}" crypto) - SET(ALGID "") - IF ("${CRYPTO}" MATCHES "^MD5$") - SET(ALGID "CALG_MD5") - ENDIF ("${CRYPTO}" MATCHES "^MD5$") - IF ("${CRYPTO}" MATCHES "^SHA1$") - SET(ALGID "CALG_SHA1") - ENDIF ("${CRYPTO}" MATCHES "^SHA1$") - IF ("${CRYPTO}" MATCHES "^SHA256$") - SET(ALGID "CALG_SHA_256") - ENDIF ("${CRYPTO}" MATCHES "^SHA256$") - IF ("${CRYPTO}" MATCHES "^SHA384$") - SET(ALGID "CALG_SHA_384") - ENDIF ("${CRYPTO}" MATCHES "^SHA384$") - IF ("${CRYPTO}" MATCHES "^SHA512$") - SET(ALGID "CALG_SHA_512") - ENDIF ("${CRYPTO}" MATCHES "^SHA512$") - - CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/build/cmake/config.h.in - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/confdefs.h) - FILE(READ "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/confdefs.h" - CONFDEFS_H) - - SET(SOURCE "${CONFDEFS_H} - -#define ${crypto}_COMPILE_TEST -#include -#include - -int -main(int argc, char **argv) -{ - return ${ALGID}; -} -") - SET(SOURCE_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check_crypto_win.c") - - FILE(WRITE "${SOURCE_FILE}" "${SOURCE}") - MESSAGE(STATUS "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN") - - TRY_COMPILE(ARCHIVE_CRYPTO_${CRYPTO}_WIN - ${CMAKE_BINARY_DIR} - ${SOURCE_FILE} - CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_BINARY_DIR};${CMAKE_CURRENT_SOURCE_DIR}/libarchive" - OUTPUT_VARIABLE OUTPUT) - - IF (ARCHIVE_CRYPTO_${CRYPTO}_WIN) - MESSAGE(STATUS - "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN -- found") - SET(ARCHIVE_CRYPTO_${CRYPTO} 1) - ELSE (ARCHIVE_CRYPTO_${CRYPTO}_WIN) - MESSAGE(STATUS - "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN -- not found") - FILE(APPEND - ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Checking support for ARCHIVE_CRYPTO_${CRYPTO}_WIN failed with the following output:\n" - "${OUTPUT}\n" - "Source file was:\n${SOURCE}\n") - ENDIF (ARCHIVE_CRYPTO_${CRYPTO}_WIN) - - ENDIF(NOT DEFINED ARCHIVE_CRYPTO_${CRYPTO}_WIN) - ENDIF(NOT ARCHIVE_CRYPTO_${CRYPTO}) - ENDFOREACH(CRYPTO) - ENDIF(WIN32 AND NOT CYGWIN) -ENDMACRO(CHECK_CRYPTO_WIN CRYPTO_LIST) - -# -# Find iconv -# POSIX defines the second arg as const char ** -# and requires it to be in libc. But we can accept -# a non-const argument here and can support iconv() -# being in libiconv. -# -MACRO(CHECK_ICONV LIB TRY_ICONV_CONST) - IF(NOT HAVE_ICONV) - CMAKE_PUSH_CHECK_STATE() # Save the state of the variables - IF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR - CMAKE_C_COMPILER_ID MATCHES "^Clang$") - # - # During checking iconv proto type, we should use -Werror to avoid the - # success of iconv detection with a warning which success is a miss - # detection. So this needs for all build mode(even it's a release mode). - # - SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror") - ENDIF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR - CMAKE_C_COMPILER_ID MATCHES "^Clang$") - IF (CMAKE_C_COMPILER_ID MATCHES "^XL$") - SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -qhalt=w -qflag=w:w") - ENDIF (CMAKE_C_COMPILER_ID MATCHES "^XL$") - IF (MSVC) - # NOTE: /WX option is the same as gcc's -Werror option. - SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} /WX") - ENDIF (MSVC) - # - CHECK_C_SOURCE_COMPILES( - "#include - #include - int main() { - ${TRY_ICONV_CONST} char *ccp; - iconv_t cd = iconv_open(\"\", \"\"); - iconv(cd, &ccp, (size_t *)0, (char **)0, (size_t *)0); - iconv_close(cd); - return 0; - }" - HAVE_ICONV_${LIB}_${TRY_ICONV_CONST}) - IF(HAVE_ICONV_${LIB}_${TRY_ICONV_CONST}) - SET(HAVE_ICONV true) - SET(ICONV_CONST ${TRY_ICONV_CONST}) - ENDIF(HAVE_ICONV_${LIB}_${TRY_ICONV_CONST}) - CMAKE_POP_CHECK_STATE() # Restore the state of the variables - ENDIF(NOT HAVE_ICONV) -ENDMACRO(CHECK_ICONV TRY_ICONV_CONST) - -IF(ENABLE_ICONV) - CMAKE_PUSH_CHECK_STATE() # Save the state of the variables - FIND_PATH(ICONV_INCLUDE_DIR iconv.h) - IF(ICONV_INCLUDE_DIR) - #SET(INCLUDES ${INCLUDES} "iconv.h") - SET(HAVE_ICONV_H 1) - INCLUDE_DIRECTORIES(${ICONV_INCLUDE_DIR}) - SET(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR}) - CHECK_ICONV("libc" "const") - CHECK_ICONV("libc" "") - - # If iconv isn't in libc and we have a libiconv, try that. - FIND_LIBRARY(LIBICONV_PATH NAMES iconv libiconv) - IF(NOT HAVE_ICONV AND LIBICONV_PATH) - LIST(APPEND CMAKE_REQUIRED_LIBRARIES ${LIBICONV_PATH}) - # Test if a macro is needed for the library. - TRY_MACRO_FOR_LIBRARY( - "${ICONV_INCLUDE_DIR}" "${LIBICONV_PATH}" - COMPILES - "#include \nint main() {return iconv_close((iconv_t)0);}" - "WITHOUT_LIBICONV_STATIC;LIBICONV_STATIC") - IF(NOT WITHOUT_LIBICONV_STATIC AND LIBICONV_STATIC) - ADD_DEFINITIONS(-DLIBICONV_STATIC) - ENDIF(NOT WITHOUT_LIBICONV_STATIC AND LIBICONV_STATIC) - # - # Set up CMAKE_REQUIRED_* for CHECK_ICONV - # - SET(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR}) - SET(CMAKE_REQUIRED_LIBRARIES ${LIBICONV_PATH}) - IF(LIBICONV_STATIC) - # LIBICONV_STATIC is necessary for the success of CHECK_ICONV - # on Windows. - SET(CMAKE_REQUIRED_DEFINITIONS "-DLIBICONV_STATIC") - ELSE(LIBICONV_STATIC) - SET(CMAKE_REQUIRED_DEFINITIONS) - ENDIF(LIBICONV_STATIC) - CHECK_ICONV("libiconv" "const") - CHECK_ICONV("libiconv" "") - IF (HAVE_ICONV) - LIST(APPEND ADDITIONAL_LIBS ${LIBICONV_PATH}) - ENDIF(HAVE_ICONV) - ENDIF(NOT HAVE_ICONV AND LIBICONV_PATH) - ENDIF(ICONV_INCLUDE_DIR) - # - # Find locale_charset() for libiconv. - # - IF(LIBICONV_PATH) - SET(CMAKE_REQUIRED_DEFINITIONS) - SET(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR}) - SET(CMAKE_REQUIRED_LIBRARIES) - CHECK_INCLUDE_FILES("localcharset.h" HAVE_LOCALCHARSET_H) - FIND_LIBRARY(LIBCHARSET_PATH NAMES charset libcharset) - IF(LIBCHARSET_PATH) - SET(CMAKE_REQUIRED_LIBRARIES ${LIBCHARSET_PATH}) - IF(WIN32 AND NOT CYGWIN) - # Test if a macro is needed for the library. - TRY_MACRO_FOR_LIBRARY( - "${ICONV_INCLUDE_DIR}" "${LIBCHARSET_PATH}" - COMPILES - "#include \nint main() {return locale_charset()?1:0;}" - "WITHOUT_LIBCHARSET_STATIC;LIBCHARSET_STATIC") - IF(NOT WITHOUT_LIBCHARSET_STATIC AND LIBCHARSET_STATIC) - ADD_DEFINITIONS(-DLIBCHARSET_STATIC) - ENDIF(NOT WITHOUT_LIBCHARSET_STATIC AND LIBCHARSET_STATIC) - IF(WITHOUT_LIBCHARSET_STATIC OR LIBCHARSET_STATIC) - SET(HAVE_LOCALE_CHARSET ON CACHE INTERNAL - "Have function locale_charset") - ENDIF(WITHOUT_LIBCHARSET_STATIC OR LIBCHARSET_STATIC) - ELSE(WIN32 AND NOT CYGWIN) - CHECK_FUNCTION_EXISTS_GLIBC(locale_charset HAVE_LOCALE_CHARSET) - ENDIF(WIN32 AND NOT CYGWIN) - IF(HAVE_LOCALE_CHARSET) - LIST(APPEND ADDITIONAL_LIBS ${LIBCHARSET_PATH}) - ENDIF(HAVE_LOCALE_CHARSET) - ENDIF(LIBCHARSET_PATH) - ENDIF(LIBICONV_PATH) - CMAKE_POP_CHECK_STATE() # Restore the state of the variables -ELSE(ENABLE_ICONV) - # Make sure ICONV variables are not in CACHE after ENABLE_ICONV disabled - # (once enabled). - UNSET(HAVE_LOCALE_CHARSET CACHE) - UNSET(HAVE_ICONV CACHE) - UNSET(HAVE_ICONV_libc_ CACHE) - UNSET(HAVE_ICONV_libc_const CACHE) - UNSET(HAVE_ICONV_libiconv_ CACHE) - UNSET(HAVE_ICONV_libiconv_const CACHE) - UNSET(ICONV_INCLUDE_DIR CACHE) - UNSET(LIBICONV_PATH CACHE) - UNSET(LIBICONV_DLL CACHE) - UNSET(LIBICONV_STATIC CACHE) - UNSET(LIBCHARSET_DLL CACHE) - UNSET(LIBCHARSET_STATIC CACHE) -ENDIF(ENABLE_ICONV) - -# -# Find Libxml2 -# -IF(ENABLE_LIBXML2) - FIND_PACKAGE(LibXml2) -ELSE() - SET(LIBXML2_FOUND FALSE) -ENDIF() -IF(LIBXML2_FOUND) - CMAKE_PUSH_CHECK_STATE() # Save the state of the variables - INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR}) - LIST(APPEND ADDITIONAL_LIBS ${LIBXML2_LIBRARIES}) - SET(HAVE_LIBXML2 1) - # libxml2's include files use iconv.h - SET(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR}) - CHECK_INCLUDE_FILES("libxml/xmlreader.h" HAVE_LIBXML_XMLREADER_H) - CHECK_INCLUDE_FILES("libxml/xmlwriter.h" HAVE_LIBXML_XMLWRITER_H) - # Test if a macro is needed for the library. - TRY_MACRO_FOR_LIBRARY( - "${ICONV_INCLUDE_DIR};${LIBXML2_INCLUDE_DIR}" - "ws2_32.lib;${ZLIB_LIBRARIES};${LIBICONV_PATH};${LIBXML2_LIBRARIES}" - COMPILES - "#include \n#include \nint main() {return xmlTextReaderRead((xmlTextReaderPtr)(void *)0);}" - "WITHOUT_LIBXML_STATIC;LIBXML_STATIC") - IF(NOT WITHOUT_LIBXML_STATIC AND LIBXML_STATIC) - ADD_DEFINITIONS(-DLIBXML_STATIC) - ENDIF(NOT WITHOUT_LIBXML_STATIC AND LIBXML_STATIC) - CMAKE_POP_CHECK_STATE() # Restore the state of the variables -ELSE(LIBXML2_FOUND) - # - # Find Expat - # - IF(ENABLE_EXPAT) - FIND_PACKAGE(EXPAT) - ELSE() - SET(EXPAT_FOUND FALSE) - ENDIF() - IF(EXPAT_FOUND) - CMAKE_PUSH_CHECK_STATE() # Save the state of the variables - INCLUDE_DIRECTORIES(${EXPAT_INCLUDE_DIR}) - LIST(APPEND ADDITIONAL_LIBS ${EXPAT_LIBRARIES}) - SET(HAVE_LIBEXPAT 1) - LA_CHECK_INCLUDE_FILE("expat.h" HAVE_EXPAT_H) - CMAKE_POP_CHECK_STATE() # Restore the state of the variables - ENDIF(EXPAT_FOUND) -ENDIF(LIBXML2_FOUND) -MARK_AS_ADVANCED(CLEAR LIBXML2_INCLUDE_DIR) -MARK_AS_ADVANCED(CLEAR LIBXML2_LIBRARIES) - -# -# POSIX Regular Expression support -# -IF(POSIX_REGEX_LIB MATCHES "^(AUTO|LIBC|LIBREGEX)$") - # - # If PCREPOSIX is not found or not requested, try using regex - # from libc or libregex - # - FIND_PATH(REGEX_INCLUDE_DIR regex.h) - IF(REGEX_INCLUDE_DIR) - CHECK_FUNCTION_EXISTS_GLIBC(regcomp HAVE_REGCOMP_LIBC) - # - # If libc does not provide regex, find libregex. - # - IF(NOT HAVE_REGCOMP_LIBC) - CMAKE_PUSH_CHECK_STATE() # Save the state of the variables - FIND_LIBRARY(REGEX_LIBRARY regex) - IF(REGEX_LIBRARY) - SET(CMAKE_REQUIRED_LIBRARIES ${REGEX_LIBRARY}) - CHECK_FUNCTION_EXISTS_GLIBC(regcomp HAVE_REGCOMP_LIBREGEX) - IF(HAVE_REGCOMP_LIBREGEX) - LIST(APPEND ADDITIONAL_LIBS ${REGEX_LIBRARY}) - # - # If regex.h is not found, retry looking for regex.h at - # REGEX_INCLUDE_DIR - # - IF(NOT HAVE_REGEX_H) - UNSET(HAVE_REGEX_H CACHE) - INCLUDE_DIRECTORIES(${REGEX_INCLUDE_DIR}) - SET(CMAKE_REQUIRED_INCLUDES ${REGEX_INCLUDE_DIR}) - LA_CHECK_INCLUDE_FILE("regex.h" HAVE_REGEX_H) - ENDIF(NOT HAVE_REGEX_H) - # Test if a macro is needed for the library. - TRY_MACRO_FOR_LIBRARY( - "${REGEX_INCLUDE_DIR}" "${REGEX_LIBRARY}" - COMPILES - "#include \n#include \nint main() {regex_t r;return regcomp(&r, \"\", 0);}" - "USE_REGEX_DLL;USE_REGEX_STATIC") - IF(USE_REGEX_DLL) - ADD_DEFINITIONS(-DUSE_REGEX_DLL) - ELSEIF(USE_REGEX_STATIC) - ADD_DEFINITIONS(-DUSE_REGEX_STATIC) - ENDIF(USE_REGEX_DLL) - ENDIF(HAVE_REGCOMP_LIBREGEX) - ENDIF(REGEX_LIBRARY) - CMAKE_POP_CHECK_STATE() # Restore the state of the variables - ENDIF(NOT HAVE_REGCOMP_LIBC) - ENDIF(REGEX_INCLUDE_DIR) - IF(HAVE_REGCOMP_LIBC OR HAVE_REGCOMP_LIBREGEX) - SET(FOUND_POSIX_REGEX_LIB 1) - ENDIF(HAVE_REGCOMP_LIBC OR HAVE_REGCOMP_LIBREGEX) -ENDIF(POSIX_REGEX_LIB MATCHES "^(AUTO|LIBC|LIBREGEX)$") - -IF(NOT FOUND_POSIX_REGEX_LIB AND POSIX_REGEX_LIB MATCHES "^(AUTO|LIBPCREPOSIX)$") - # - # If requested, try finding library for PCREPOSIX - # - IF(ENABLE_LIBGCC) - FIND_PACKAGE(LIBGCC) - ELSE() - MESSAGE(FATAL_ERROR "libgcc not found.") - SET(LIBGCC_FOUND FALSE) # Override cached value - ENDIF() - IF(ENABLE_PCREPOSIX) - FIND_PACKAGE(PCREPOSIX) - ELSE() - SET(PCREPOSIX_FOUND FALSE) # Override cached value - ENDIF() - IF(PCREPOSIX_FOUND) - INCLUDE_DIRECTORIES(${PCRE_INCLUDE_DIR}) - LIST(APPEND ADDITIONAL_LIBS ${PCREPOSIX_LIBRARIES}) - # Test if a macro is needed for the library. - TRY_MACRO_FOR_LIBRARY( - "${PCRE_INCLUDE_DIR}" "${PCREPOSIX_LIBRARIES}" - COMPILES - "#include \nint main() {regex_t r;return regcomp(&r, \"\", 0);}" - "WITHOUT_PCRE_STATIC;PCRE_STATIC") - IF(NOT WITHOUT_PCRE_STATIC AND PCRE_STATIC) - ADD_DEFINITIONS(-DPCRE_STATIC) - ELSEIF(NOT WITHOUT_PCRE_STATIC AND NOT PCRE_STATIC AND PCRE_FOUND) - # Determine if pcre static libraries are to be used. - LIST(APPEND ADDITIONAL_LIBS ${PCRE_LIBRARIES}) - SET(TMP_LIBRARIES ${PCREPOSIX_LIBRARIES} ${PCRE_LIBRARIES}) - MESSAGE(STATUS "trying again with -lpcre included") - TRY_MACRO_FOR_LIBRARY( - "${PCRE_INCLUDE_DIR}" "${TMP_LIBRARIES}" - COMPILES - "#include \nint main() {regex_t r;return regcomp(&r, \"\", 0);}" - "WITHOUT_PCRE_STATIC;PCRE_STATIC") - IF(NOT WITHOUT_PCRE_STATIC AND PCRE_STATIC) - ADD_DEFINITIONS(-DPCRE_STATIC) - ELSEIF(NOT WITHOUT_PCRE_STATIC AND NOT PCRE_STATIC AND MSVC AND LIBGCC_FOUND) - # When doing a Visual Studio build using pcre static libraries - # built using the mingw toolchain, -lgcc is needed to resolve - # ___chkstk_ms. - MESSAGE(STATUS "Visual Studio build detected, trying again with -lgcc included") - LIST(APPEND ADDITIONAL_LIBS ${LIBGCC_LIBRARIES}) - SET(TMP_LIBRARIES ${PCREPOSIX_LIBRARIES} ${PCRE_LIBRARIES} ${LIBGCC_LIBRARIES}) - TRY_MACRO_FOR_LIBRARY( - "${PCRE_INCLUDE_DIR}" "${TMP_LIBRARIES}" - COMPILES - "#include \nint main() {regex_t r;return regcomp(&r, \"\", 0);}" - "WITHOUT_PCRE_STATIC;PCRE_STATIC") - IF(NOT WITHOUT_PCRE_STATIC AND PCRE_STATIC) - ADD_DEFINITIONS(-DPCRE_STATIC) - ENDIF(NOT WITHOUT_PCRE_STATIC AND PCRE_STATIC) - ENDIF(NOT WITHOUT_PCRE_STATIC AND PCRE_STATIC) - ENDIF(NOT WITHOUT_PCRE_STATIC AND PCRE_STATIC) - ENDIF(PCREPOSIX_FOUND) - MARK_AS_ADVANCED(CLEAR PCRE_INCLUDE_DIR) - MARK_AS_ADVANCED(CLEAR PCREPOSIX_LIBRARIES) - MARK_AS_ADVANCED(CLEAR PCRE_LIBRARIES) - MARK_AS_ADVANCED(CLEAR LIBGCC_LIBRARIES) -ENDIF(NOT FOUND_POSIX_REGEX_LIB AND POSIX_REGEX_LIB MATCHES "^(AUTO|LIBPCREPOSIX)$") - -# -# Check functions -# -CMAKE_PUSH_CHECK_STATE() # Save the state of the variables -IF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR - CMAKE_C_COMPILER_ID MATCHES "^Clang$") - # - # During checking functions, we should use -fno-builtin to avoid the - # failure of function detection which failure is an error "conflicting - # types for built-in function" caused by using -Werror option. - # - SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-builtin") -ENDIF (CMAKE_C_COMPILER_ID MATCHES "^GNU$" OR - CMAKE_C_COMPILER_ID MATCHES "^Clang$") -CHECK_SYMBOL_EXISTS(_CrtSetReportMode "crtdbg.h" HAVE__CrtSetReportMode) -CHECK_FUNCTION_EXISTS_GLIBC(arc4random_buf HAVE_ARC4RANDOM_BUF) -CHECK_FUNCTION_EXISTS_GLIBC(chflags HAVE_CHFLAGS) -CHECK_FUNCTION_EXISTS_GLIBC(chown HAVE_CHOWN) -CHECK_FUNCTION_EXISTS_GLIBC(chroot HAVE_CHROOT) -CHECK_FUNCTION_EXISTS_GLIBC(ctime_r HAVE_CTIME_R) -CHECK_FUNCTION_EXISTS_GLIBC(fchdir HAVE_FCHDIR) -CHECK_FUNCTION_EXISTS_GLIBC(fchflags HAVE_FCHFLAGS) -CHECK_FUNCTION_EXISTS_GLIBC(fchmod HAVE_FCHMOD) -CHECK_FUNCTION_EXISTS_GLIBC(fchown HAVE_FCHOWN) -CHECK_FUNCTION_EXISTS_GLIBC(fcntl HAVE_FCNTL) -CHECK_FUNCTION_EXISTS_GLIBC(fdopendir HAVE_FDOPENDIR) -CHECK_FUNCTION_EXISTS_GLIBC(fnmatch HAVE_FNMATCH) -CHECK_FUNCTION_EXISTS_GLIBC(fork HAVE_FORK) -CHECK_FUNCTION_EXISTS_GLIBC(fstat HAVE_FSTAT) -CHECK_FUNCTION_EXISTS_GLIBC(fstatat HAVE_FSTATAT) -CHECK_FUNCTION_EXISTS_GLIBC(fstatfs HAVE_FSTATFS) -CHECK_FUNCTION_EXISTS_GLIBC(fstatvfs HAVE_FSTATVFS) -CHECK_FUNCTION_EXISTS_GLIBC(ftruncate HAVE_FTRUNCATE) -CHECK_FUNCTION_EXISTS_GLIBC(futimens HAVE_FUTIMENS) -CHECK_FUNCTION_EXISTS_GLIBC(futimes HAVE_FUTIMES) -CHECK_FUNCTION_EXISTS_GLIBC(futimesat HAVE_FUTIMESAT) -CHECK_FUNCTION_EXISTS_GLIBC(geteuid HAVE_GETEUID) -CHECK_FUNCTION_EXISTS_GLIBC(getgrgid_r HAVE_GETGRGID_R) -CHECK_FUNCTION_EXISTS_GLIBC(getgrnam_r HAVE_GETGRNAM_R) -CHECK_FUNCTION_EXISTS_GLIBC(getline HAVE_GETLINE) -CHECK_FUNCTION_EXISTS_GLIBC(getpwnam_r HAVE_GETPWNAM_R) -CHECK_FUNCTION_EXISTS_GLIBC(getpwuid_r HAVE_GETPWUID_R) -CHECK_FUNCTION_EXISTS_GLIBC(getpid HAVE_GETPID) -CHECK_FUNCTION_EXISTS_GLIBC(getvfsbyname HAVE_GETVFSBYNAME) -CHECK_FUNCTION_EXISTS_GLIBC(gmtime_r HAVE_GMTIME_R) -CHECK_FUNCTION_EXISTS_GLIBC(lchflags HAVE_LCHFLAGS) -CHECK_FUNCTION_EXISTS_GLIBC(lchmod HAVE_LCHMOD) -CHECK_FUNCTION_EXISTS_GLIBC(lchown HAVE_LCHOWN) -CHECK_FUNCTION_EXISTS_GLIBC(link HAVE_LINK) -CHECK_FUNCTION_EXISTS_GLIBC(linkat HAVE_LINKAT) -CHECK_FUNCTION_EXISTS_GLIBC(localtime_r HAVE_LOCALTIME_R) -CHECK_FUNCTION_EXISTS_GLIBC(lstat HAVE_LSTAT) -CHECK_FUNCTION_EXISTS_GLIBC(lutimes HAVE_LUTIMES) -CHECK_FUNCTION_EXISTS_GLIBC(mbrtowc HAVE_MBRTOWC) -CHECK_FUNCTION_EXISTS_GLIBC(memmove HAVE_MEMMOVE) -CHECK_FUNCTION_EXISTS_GLIBC(mkdir HAVE_MKDIR) -CHECK_FUNCTION_EXISTS_GLIBC(mkfifo HAVE_MKFIFO) -CHECK_FUNCTION_EXISTS_GLIBC(mknod HAVE_MKNOD) -CHECK_FUNCTION_EXISTS_GLIBC(mkstemp HAVE_MKSTEMP) -CHECK_FUNCTION_EXISTS_GLIBC(nl_langinfo HAVE_NL_LANGINFO) -CHECK_FUNCTION_EXISTS_GLIBC(openat HAVE_OPENAT) -CHECK_FUNCTION_EXISTS_GLIBC(pipe HAVE_PIPE) -CHECK_FUNCTION_EXISTS_GLIBC(poll HAVE_POLL) -CHECK_FUNCTION_EXISTS_GLIBC(posix_spawnp HAVE_POSIX_SPAWNP) -CHECK_FUNCTION_EXISTS_GLIBC(readlink HAVE_READLINK) -CHECK_FUNCTION_EXISTS_GLIBC(readpassphrase HAVE_READPASSPHRASE) -CHECK_FUNCTION_EXISTS_GLIBC(select HAVE_SELECT) -CHECK_FUNCTION_EXISTS_GLIBC(setenv HAVE_SETENV) -CHECK_FUNCTION_EXISTS_GLIBC(setlocale HAVE_SETLOCALE) -CHECK_FUNCTION_EXISTS_GLIBC(sigaction HAVE_SIGACTION) -CHECK_FUNCTION_EXISTS_GLIBC(statfs HAVE_STATFS) -CHECK_FUNCTION_EXISTS_GLIBC(statvfs HAVE_STATVFS) -CHECK_FUNCTION_EXISTS_GLIBC(strchr HAVE_STRCHR) -CHECK_FUNCTION_EXISTS_GLIBC(strdup HAVE_STRDUP) -CHECK_FUNCTION_EXISTS_GLIBC(strerror HAVE_STRERROR) -CHECK_FUNCTION_EXISTS_GLIBC(strncpy_s HAVE_STRNCPY_S) -CHECK_FUNCTION_EXISTS_GLIBC(strnlen HAVE_STRNLEN) -CHECK_FUNCTION_EXISTS_GLIBC(strrchr HAVE_STRRCHR) -CHECK_FUNCTION_EXISTS_GLIBC(symlink HAVE_SYMLINK) -CHECK_FUNCTION_EXISTS_GLIBC(timegm HAVE_TIMEGM) -CHECK_FUNCTION_EXISTS_GLIBC(tzset HAVE_TZSET) -CHECK_FUNCTION_EXISTS_GLIBC(unlinkat HAVE_UNLINKAT) -CHECK_FUNCTION_EXISTS_GLIBC(unsetenv HAVE_UNSETENV) -CHECK_FUNCTION_EXISTS_GLIBC(utime HAVE_UTIME) -CHECK_FUNCTION_EXISTS_GLIBC(utimes HAVE_UTIMES) -CHECK_FUNCTION_EXISTS_GLIBC(utimensat HAVE_UTIMENSAT) -CHECK_FUNCTION_EXISTS_GLIBC(vfork HAVE_VFORK) -CHECK_FUNCTION_EXISTS_GLIBC(wcrtomb HAVE_WCRTOMB) -CHECK_FUNCTION_EXISTS_GLIBC(wcscmp HAVE_WCSCMP) -CHECK_FUNCTION_EXISTS_GLIBC(wcscpy HAVE_WCSCPY) -CHECK_FUNCTION_EXISTS_GLIBC(wcslen HAVE_WCSLEN) -CHECK_FUNCTION_EXISTS_GLIBC(wctomb HAVE_WCTOMB) -CHECK_FUNCTION_EXISTS_GLIBC(_fseeki64 HAVE__FSEEKI64) -CHECK_FUNCTION_EXISTS_GLIBC(_get_timezone HAVE__GET_TIMEZONE) -CHECK_SYMBOL_EXISTS(ctime_s "time.h" HAVE_CTIME_S) -CHECK_SYMBOL_EXISTS(gmtime_s "time.h" HAVE_GMTIME_S) -CHECK_SYMBOL_EXISTS(localtime_s "time.h" HAVE_LOCALTIME_S) -CHECK_SYMBOL_EXISTS(_mkgmtime "time.h" HAVE__MKGMTIME) - -SET(CMAKE_REQUIRED_LIBRARIES "") -CHECK_FUNCTION_EXISTS(cygwin_conv_path HAVE_CYGWIN_CONV_PATH) -CHECK_FUNCTION_EXISTS(fseeko HAVE_FSEEKO) -CHECK_FUNCTION_EXISTS(strerror_r HAVE_STRERROR_R) -CHECK_FUNCTION_EXISTS(strftime HAVE_STRFTIME) -CHECK_FUNCTION_EXISTS(vprintf HAVE_VPRINTF) -CHECK_FUNCTION_EXISTS(wmemcmp HAVE_WMEMCMP) -CHECK_FUNCTION_EXISTS(wmemcpy HAVE_WMEMCPY) -CHECK_FUNCTION_EXISTS(wmemmove HAVE_WMEMMOVE) - -CMAKE_POP_CHECK_STATE() # Restore the state of the variables - -CHECK_C_SOURCE_COMPILES( - "#include \n#include \nint main(void) { struct vfsconf v; return sizeof(v);}" - HAVE_STRUCT_VFSCONF) - -CHECK_C_SOURCE_COMPILES( - "#include \n#include \nint main(void) { struct xvfsconf v; return sizeof(v);}" - HAVE_STRUCT_XVFSCONF) - -CHECK_C_SOURCE_COMPILES( - "#include \n#include \nint main(void) { struct statfs s; return sizeof(s);}" - HAVE_STRUCT_STATFS) - -# Make sure we have the POSIX version of readdir_r, not the -# older 2-argument version. -CHECK_C_SOURCE_COMPILES( - "#include \nint main() {DIR *d = opendir(\".\"); struct dirent e,*r; return readdir_r(d,&e,&r);}" - HAVE_READDIR_R) - -# dirfd can be either a function or a macro. -CHECK_C_SOURCE_COMPILES( - "#include \nint main() {DIR *d = opendir(\".\"); return dirfd(d);}" - HAVE_DIRFD) - -# Only detect readlinkat() if we also have AT_FDCWD in unistd.h. -# NOTE: linux requires fcntl.h for AT_FDCWD. -CHECK_C_SOURCE_COMPILES( - "#include \n#include \nint main() {char buf[10]; return readlinkat(AT_FDCWD, \"\", buf, 0);}" - HAVE_READLINKAT) - -# To verify major(), we need to both include the header -# of interest and verify that the result can be linked. -# CHECK_FUNCTION_EXISTS doesn't accept a header argument, -# CHECK_SYMBOL_EXISTS doesn't test linkage. -CHECK_C_SOURCE_COMPILES( - "#include \nint main() { return major(256); }" - MAJOR_IN_MKDEV) -CHECK_C_SOURCE_COMPILES( - "#include \nint main() { return major(256); }" - MAJOR_IN_SYSMACROS) - -IF(HAVE_STRERROR_R) - SET(HAVE_DECL_STRERROR_R 1) -ENDIF(HAVE_STRERROR_R) - -# -# Check defines -# -SET(headers "limits.h") -IF(HAVE_STDINT_H) - LIST(APPEND headers "stdint.h") -ENDIF(HAVE_STDINT_H) -IF(HAVE_INTTYPES_H) - LIST(APPEND headers "inttypes.h") -ENDIF(HAVE_INTTYPES_H) -CHECK_SYMBOL_EXISTS(EFTYPE "errno.h" HAVE_EFTYPE) -CHECK_SYMBOL_EXISTS(EILSEQ "errno.h" HAVE_EILSEQ) -CHECK_SYMBOL_EXISTS(D_MD_ORDER "langinfo.h" HAVE_D_MD_ORDER) -CHECK_SYMBOL_EXISTS(INT32_MAX "${headers}" HAVE_DECL_INT32_MAX) -CHECK_SYMBOL_EXISTS(INT32_MIN "${headers}" HAVE_DECL_INT32_MIN) -CHECK_SYMBOL_EXISTS(INT64_MAX "${headers}" HAVE_DECL_INT64_MAX) -CHECK_SYMBOL_EXISTS(INT64_MIN "${headers}" HAVE_DECL_INT64_MIN) -CHECK_SYMBOL_EXISTS(INTMAX_MAX "${headers}" HAVE_DECL_INTMAX_MAX) -CHECK_SYMBOL_EXISTS(INTMAX_MIN "${headers}" HAVE_DECL_INTMAX_MIN) -CHECK_SYMBOL_EXISTS(UINT32_MAX "${headers}" HAVE_DECL_UINT32_MAX) -CHECK_SYMBOL_EXISTS(UINT64_MAX "${headers}" HAVE_DECL_UINT64_MAX) -CHECK_SYMBOL_EXISTS(UINTMAX_MAX "${headers}" HAVE_DECL_UINTMAX_MAX) -CHECK_SYMBOL_EXISTS(SIZE_MAX "${headers}" HAVE_DECL_SIZE_MAX) -CHECK_SYMBOL_EXISTS(SSIZE_MAX "limits.h" HAVE_DECL_SSIZE_MAX) - -# -# Check struct members -# -# Check for tm_gmtoff in struct tm -CHECK_STRUCT_HAS_MEMBER("struct tm" tm_gmtoff - "time.h" HAVE_STRUCT_TM_TM_GMTOFF) -CHECK_STRUCT_HAS_MEMBER("struct tm" __tm_gmtoff - "time.h" HAVE_STRUCT_TM___TM_GMTOFF) - -IF(HAVE_STRUCT_STATFS) -# Check for f_namemax in struct statfs -CHECK_STRUCT_HAS_MEMBER("struct statfs" f_namemax - "sys/param.h;sys/mount.h" HAVE_STRUCT_STATFS_F_NAMEMAX) -# Check for f_iosize in struct statfs -CHECK_STRUCT_HAS_MEMBER("struct statfs" f_iosize - "sys/param.h;sys/mount.h" HAVE_STRUCT_STATFS_F_IOSIZE) -ENDIF(HAVE_STRUCT_STATFS) - -# Check for birthtime in struct stat -CHECK_STRUCT_HAS_MEMBER("struct stat" st_birthtime - "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_BIRTHTIME) - -# Check for high-resolution timestamps in struct stat -CHECK_STRUCT_HAS_MEMBER("struct stat" st_birthtimespec.tv_nsec - "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC) -CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtimespec.tv_nsec - "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) -CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtim.tv_nsec - "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) -CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtime_n - "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIME_N) -CHECK_STRUCT_HAS_MEMBER("struct stat" st_umtime - "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_UMTIME) -CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtime_usec - "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_MTIME_USEC) -# Check for block size support in struct stat -CHECK_STRUCT_HAS_MEMBER("struct stat" st_blksize - "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_BLKSIZE) -# Check for st_flags in struct stat (BSD fflags) -CHECK_STRUCT_HAS_MEMBER("struct stat" st_flags - "sys/types.h;sys/stat.h" HAVE_STRUCT_STAT_ST_FLAGS) - -IF(HAVE_SYS_STATVFS_H) - CHECK_STRUCT_HAS_MEMBER("struct statvfs" f_iosize - "sys/types.h;sys/statvfs.h" HAVE_STRUCT_STATVFS_F_IOSIZE) -ENDIF() - -# -# -CHECK_STRUCT_HAS_MEMBER("struct tm" tm_sec - "sys/types.h;sys/time.h;time.h" HAVE_SYS_TIME_H) - -# -# Check for integer types -# -# -CHECK_TYPE_SIZE("short" SIZEOF_SHORT) -CHECK_TYPE_SIZE("int" SIZEOF_INT) -CHECK_TYPE_SIZE("long" SIZEOF_LONG) -CHECK_TYPE_SIZE("long long" SIZEOF_LONG_LONG) - -CHECK_TYPE_SIZE("unsigned short" SIZEOF_UNSIGNED_SHORT) -CHECK_TYPE_SIZE("unsigned" SIZEOF_UNSIGNED) -CHECK_TYPE_SIZE("unsigned long" SIZEOF_UNSIGNED_LONG) -CHECK_TYPE_SIZE("unsigned long long" SIZEOF_UNSIGNED_LONG_LONG) - -CHECK_TYPE_SIZE("__int64" __INT64) -CHECK_TYPE_SIZE("unsigned __int64" UNSIGNED___INT64) - -CHECK_TYPE_SIZE(int16_t INT16_T) -CHECK_TYPE_SIZE(int32_t INT32_T) -CHECK_TYPE_SIZE(int64_t INT64_T) -CHECK_TYPE_SIZE(intmax_t INTMAX_T) -CHECK_TYPE_SIZE(uint8_t UINT8_T) -CHECK_TYPE_SIZE(uint16_t UINT16_T) -CHECK_TYPE_SIZE(uint32_t UINT32_T) -CHECK_TYPE_SIZE(uint64_t UINT64_T) -CHECK_TYPE_SIZE(uintmax_t UINTMAX_T) - -CHECK_TYPE_SIZE(dev_t DEV_T) -IF(NOT HAVE_DEV_T) - IF(MSVC) - SET(dev_t "unsigned int") - ENDIF(MSVC) -ENDIF(NOT HAVE_DEV_T) -# -CHECK_TYPE_SIZE(gid_t GID_T) -IF(NOT HAVE_GID_T) - IF(WIN32) - SET(gid_t "short") - ELSE(WIN32) - SET(gid_t "unsigned int") - ENDIF(WIN32) -ENDIF(NOT HAVE_GID_T) -# -CHECK_TYPE_SIZE(id_t ID_T) -IF(NOT HAVE_ID_T) - IF(WIN32) - SET(id_t "short") - ELSE(WIN32) - SET(id_t "unsigned int") - ENDIF(WIN32) -ENDIF(NOT HAVE_ID_T) -# -CHECK_TYPE_SIZE(mode_t MODE_T) -IF(NOT HAVE_MODE_T) - IF(WIN32) - SET(mode_t "unsigned short") - ELSE(WIN32) - SET(mode_t "int") - ENDIF(WIN32) -ENDIF(NOT HAVE_MODE_T) -# -CHECK_TYPE_SIZE(off_t OFF_T) -IF(NOT HAVE_OFF_T) - SET(off_t "__int64") -ENDIF(NOT HAVE_OFF_T) -# -CHECK_TYPE_SIZE(size_t SIZE_T) -IF(NOT HAVE_SIZE_T) - IF("${CMAKE_SIZEOF_VOID_P}" EQUAL 8) - SET(size_t "uint64_t") - ELSE("${CMAKE_SIZEOF_VOID_P}" EQUAL 8) - SET(size_t "uint32_t") - ENDIF("${CMAKE_SIZEOF_VOID_P}" EQUAL 8) -ENDIF(NOT HAVE_SIZE_T) -# -CHECK_TYPE_SIZE(ssize_t SSIZE_T) -IF(NOT HAVE_SSIZE_T) - IF("${CMAKE_SIZEOF_VOID_P}" EQUAL 8) - SET(ssize_t "int64_t") - ELSE("${CMAKE_SIZEOF_VOID_P}" EQUAL 8) - SET(ssize_t "long") - ENDIF("${CMAKE_SIZEOF_VOID_P}" EQUAL 8) -ENDIF(NOT HAVE_SSIZE_T) -# -CHECK_TYPE_SIZE(uid_t UID_T) -IF(NOT HAVE_UID_T) - IF(WIN32) - SET(uid_t "short") - ELSE(WIN32) - SET(uid_t "unsigned int") - ENDIF(WIN32) -ENDIF(NOT HAVE_UID_T) -# -CHECK_TYPE_SIZE(pid_t PID_T) -IF(NOT HAVE_PID_T) - IF(WIN32) - SET(pid_t "int") - ELSE(WIN32) - MESSAGE(FATAL_ERROR "pid_t doesn't exist on this platform?") - ENDIF(WIN32) -ENDIF(NOT HAVE_PID_T) -# -CHECK_TYPE_SIZE(intptr_t INTPTR_T) -IF(NOT HAVE_INTPTR_T) - IF("${CMAKE_SIZEOF_VOID_P}" EQUAL 8) - SET(intptr_t "int64_t") - ELSE() - SET(intptr_t "int32_t") - ENDIF() -ENDIF(NOT HAVE_INTPTR_T) -# -CHECK_TYPE_SIZE(uintptr_t UINTPTR_T) -IF(NOT HAVE_UINTPTR_T) - IF("${CMAKE_SIZEOF_VOID_P}" EQUAL 8) - SET(uintptr_t "uint64_t") - ELSE() - SET(uintptr_t "uint32_t") - ENDIF() -ENDIF(NOT HAVE_UINTPTR_T) -# -CHECK_TYPE_SIZE(wchar_t SIZEOF_WCHAR_T) -IF(HAVE_SIZEOF_WCHAR_T) - SET(HAVE_WCHAR_T 1) -ENDIF(HAVE_SIZEOF_WCHAR_T) -# -# Check if _FILE_OFFSET_BITS macro needed for large files -# -CHECK_FILE_OFFSET_BITS() - -# -# Check for Extended Attribute libraries, headers, and functions -# -IF(ENABLE_XATTR) - CHECK_LIBRARY_EXISTS(attr "setxattr" "" HAVE_LIBATTR) - IF(HAVE_LIBATTR) - SET(CMAKE_REQUIRED_LIBRARIES "attr") - ELSE() - CHECK_LIBRARY_EXISTS(gnu "setxattr" "" HAVE_LIBATTR_GNU) - IF(HAVE_LIBATTR_GNU) - SET(CMAKE_REQUIRED_LIBRARIES "gnu") - ENDIF() - ENDIF(HAVE_LIBATTR) - CHECK_SYMBOL_EXISTS(EXTATTR_NAMESPACE_USER "sys/types.h;sys/extattr.h" HAVE_DECL_EXTATTR_NAMESPACE_USER) - CHECK_SYMBOL_EXISTS(XATTR_NOFOLLOW "sys/xattr.h" HAVE_DECL_XATTR_NOFOLLOW) - IF(HAVE_SYS_XATTR_H AND HAVE_DECL_XATTR_NOFOLLOW) - CHECK_FUNCTION_EXISTS(fgetxattr HAVE_FGETXATTR) - CHECK_FUNCTION_EXISTS(flistxattr HAVE_FLISTXATTR) - CHECK_FUNCTION_EXISTS(fsetxattr HAVE_FSETXATTR) - CHECK_FUNCTION_EXISTS(getxattr HAVE_GETXATTR) - CHECK_FUNCTION_EXISTS(listxattr HAVE_LISTXATTR) - CHECK_FUNCTION_EXISTS(setxattr HAVE_SETXATTR) - IF(HAVE_FGETXATTR AND - HAVE_FLISTXATTR AND - HAVE_FSETXATTR AND - HAVE_GETXATTR AND - HAVE_LISTXATTR AND - HAVE_SETXATTR) - SET(ARCHIVE_XATTR_DARWIN TRUE) - ENDIF() - ELSEIF(HAVE_SYS_EXTATTR_H AND HAVE_DECL_EXTATTR_NAMESPACE_USER) - # FreeBSD xattr support - CHECK_FUNCTION_EXISTS(extattr_get_fd HAVE_EXTATTR_GET_FD) - CHECK_FUNCTION_EXISTS(extattr_get_file HAVE_EXTATTR_GET_FILE) - CHECK_FUNCTION_EXISTS(extattr_get_link HAVE_EXTATTR_GET_LINK) - CHECK_FUNCTION_EXISTS(extattr_list_fd HAVE_EXTATTR_LIST_FD) - CHECK_FUNCTION_EXISTS(extattr_list_file HAVE_EXTATTR_LIST_FILE) - CHECK_FUNCTION_EXISTS(extattr_list_link HAVE_EXTATTR_LIST_LINK) - CHECK_FUNCTION_EXISTS(extattr_set_fd HAVE_EXTATTR_SET_FD) - CHECK_FUNCTION_EXISTS(extattr_set_link HAVE_EXTATTR_SET_LINK) - IF(HAVE_EXTATTR_GET_FD AND - HAVE_EXTATTR_GET_FILE AND - HAVE_EXTATTR_GET_LINK AND - HAVE_EXTATTR_LIST_FD AND - HAVE_EXTATTR_LIST_FILE AND - HAVE_EXTATTR_LIST_LINK AND - HAVE_EXTATTR_SET_FD AND - HAVE_EXTATTR_SET_LINK) - SET(ARCHIVE_XATTR_FREEBSD TRUE) - ENDIF() - ELSEIF(HAVE_SYS_XATTR_H OR HAVE_ATTR_XATTR_H) - # Linux xattr support - CHECK_FUNCTION_EXISTS_GLIBC(fgetxattr HAVE_FGETXATTR) - CHECK_FUNCTION_EXISTS_GLIBC(flistxattr HAVE_FLISTXATTR) - CHECK_FUNCTION_EXISTS_GLIBC(fsetxattr HAVE_FSETXATTR) - CHECK_FUNCTION_EXISTS_GLIBC(getxattr HAVE_GETXATTR) - CHECK_FUNCTION_EXISTS_GLIBC(lgetxattr HAVE_LGETXATTR) - CHECK_FUNCTION_EXISTS_GLIBC(listxattr HAVE_LISTXATTR) - CHECK_FUNCTION_EXISTS_GLIBC(llistxattr HAVE_LLISTXATTR) - CHECK_FUNCTION_EXISTS_GLIBC(lsetxattr HAVE_LSETXATTR) - IF(HAVE_FGETXATTR AND - HAVE_FLISTXATTR AND - HAVE_FSETXATTR AND - HAVE_GETXATTR AND - HAVE_LGETXATTR AND - HAVE_LISTXATTR AND - HAVE_LLISTXATTR AND - HAVE_LSETXATTR) - SET(ARCHIVE_XATTR_LINUX TRUE) - ENDIF() - ELSEIF(HAVE_SYS_EA_H) - # AIX xattr support - CHECK_FUNCTION_EXISTS(fgetea HAVE_FGETEA) - CHECK_FUNCTION_EXISTS(flistea HAVE_FLISTEA) - CHECK_FUNCTION_EXISTS(fsetea HAVE_FSETEA) - CHECK_FUNCTION_EXISTS(getea HAVE_GETEA) - CHECK_FUNCTION_EXISTS(lgetea HAVE_LGETEA) - CHECK_FUNCTION_EXISTS(listea HAVE_LISTEA) - CHECK_FUNCTION_EXISTS(llistea HAVE_LLISTEA) - CHECK_FUNCTION_EXISTS(lsetea HAVE_LSETEA) - IF(HAVE_FGETEA AND - HAVE_FLISTEA AND - HAVE_FSETEA AND - HAVE_GETEA AND - HAVE_LGETEA AND - HAVE_LISTEA AND - HAVE_LLISTEA AND - HAVE_LSETEA) - SET(ARCHIVE_XATTR_AIX TRUE) - ENDIF() - ENDIF() - - IF(ARCHIVE_XATTR_DARWIN) - MESSAGE(STATUS "Extended attributes support: Darwin") - ELSEIF(ARCHIVE_XATTR_FREEBSD) - MESSAGE(STATUS "Extended attributes support: FreeBSD") - ELSEIF(ARCHIVE_XATTR_LINUX) - MESSAGE(STATUS "Extended attributes support: Linux") - ELSEIF(ARCHIVE_XATTR_AIX) - MESSAGE(STATUS "Extended attributes support: AIX") - ELSE() - MESSAGE(STATUS "Extended attributes support: none") - ENDIF() -ELSE(ENABLE_XATTR) - SET(ARCHIVE_XATTR_DARWIN FALSE) - SET(ARCHIVE_XATTR_FREEBSD FALSE) - SET(ARCHIVE_XATTR_LINUX FALSE) - SET(ARCHIVE_XATTR_AIX FALSE) -ENDIF(ENABLE_XATTR) - -# -# Check for ACL libraries, headers, and functions -# -# The ACL support in libarchive is written against the POSIX1e draft, -# which was never officially approved and varies quite a bit across -# platforms. Worse, some systems have completely non-POSIX acl functions, -# which makes the following checks rather more complex than I would like. -# -IF(ENABLE_ACL) - # Solaris and derivates ACLs - CHECK_FUNCTION_EXISTS(acl HAVE_ACL) - CHECK_FUNCTION_EXISTS(facl HAVE_FACL) - - # Libacl - CHECK_LIBRARY_EXISTS(acl "acl_get_file" "" HAVE_LIBACL) - IF(HAVE_LIBACL) - SET(CMAKE_REQUIRED_LIBRARIES "acl") - FIND_LIBRARY(ACL_LIBRARY NAMES acl) - LIST(APPEND ADDITIONAL_LIBS ${ACL_LIBRARY}) - ENDIF(HAVE_LIBACL) - - CHECK_TYPE_EXISTS(acl_t "sys/types.h;sys/acl.h" HAVE_ACL_T) - CHECK_TYPE_EXISTS(acl_entry_t "sys/types.h;sys/acl.h" HAVE_ACL_ENTRY_T) - CHECK_TYPE_EXISTS(acl_permset_t "sys/types.h;sys/acl.h" HAVE_ACL_PERMSET_T) - CHECK_TYPE_EXISTS(acl_tag_t "sys/types.h;sys/acl.h" HAVE_ACL_TAG_T) - - IF(HAVE_ACL AND HAVE_FACL) - CHECK_TYPE_EXISTS(aclent_t "sys/acl.h" HAVE_ACLENT_T) - IF(HAVE_ACLENT_T) - CHECK_SYMBOL_EXISTS(GETACL "sys/acl.h" HAVE_DECL_GETACL) - CHECK_SYMBOL_EXISTS(GETACLCNT "sys/acl.h" HAVE_DECL_GETACLCNT) - CHECK_SYMBOL_EXISTS(SETACL "sys/acl.h" HAVE_DECL_SETACL) - IF(HAVE_DECL_GETACL AND - HAVE_DECL_GETACLCNT AND - HAVE_DECL_SETACL) - SET(ARCHIVE_ACL_SUNOS TRUE) - ENDIF() - CHECK_TYPE_EXISTS(ace_t "sys/acl.h" HAVE_ACE_T) - IF(HAVE_ACE_T) - CHECK_SYMBOL_EXISTS(ACE_GETACL "sys/acl.h" HAVE_DECL_ACE_GETACL) - CHECK_SYMBOL_EXISTS(ACE_GETACLCNT "sys/acl.h" HAVE_DECL_ACE_GETACLCNT) - CHECK_SYMBOL_EXISTS(ACE_SETACL "sys/acl.h" HAVE_DECL_ACE_SETACL) - IF(HAVE_DECL_ACE_GETACL AND - HAVE_DECL_ACE_GETACLCNT AND - HAVE_DECL_ACE_SETACL) - SET(ARCHIVE_ACL_SUNOS_NFS4 TRUE) - ENDIF() - ENDIF(HAVE_ACE_T) - ENDIF(HAVE_ACLENT_T) - ENDIF(HAVE_ACL AND HAVE_FACL) - - IF(HAVE_ACL_T AND HAVE_ACL_ENTRY_T AND HAVE_ACL_PERMSET_T AND HAVE_ACL_TAG_T) - CHECK_FUNCTION_EXISTS_GLIBC(acl_add_perm HAVE_ACL_ADD_PERM) - CHECK_FUNCTION_EXISTS_GLIBC(acl_clear_perms HAVE_ACL_CLEAR_PERMS) - CHECK_FUNCTION_EXISTS_GLIBC(acl_create_entry HAVE_ACL_CREATE_ENTRY) - CHECK_FUNCTION_EXISTS_GLIBC(acl_delete_def_file HAVE_ACL_DELETE_DEF_FILE) - CHECK_FUNCTION_EXISTS_GLIBC(acl_free HAVE_ACL_FREE) - CHECK_FUNCTION_EXISTS_GLIBC(acl_get_entry HAVE_ACL_GET_ENTRY) - CHECK_FUNCTION_EXISTS_GLIBC(acl_get_fd HAVE_ACL_GET_FD) - CHECK_FUNCTION_EXISTS_GLIBC(acl_get_file HAVE_ACL_GET_FILE) - CHECK_FUNCTION_EXISTS_GLIBC(acl_get_permset HAVE_ACL_GET_PERMSET) - CHECK_FUNCTION_EXISTS_GLIBC(acl_get_qualifier HAVE_ACL_GET_QUALIFIER) - CHECK_FUNCTION_EXISTS_GLIBC(acl_get_tag_type HAVE_ACL_GET_TAG_TYPE) - CHECK_FUNCTION_EXISTS_GLIBC(acl_init HAVE_ACL_INIT) - CHECK_FUNCTION_EXISTS_GLIBC(acl_set_fd HAVE_ACL_SET_FD) - CHECK_FUNCTION_EXISTS_GLIBC(acl_set_file HAVE_ACL_SET_FILE) - CHECK_FUNCTION_EXISTS_GLIBC(acl_set_qualifier HAVE_ACL_SET_QUALIFIER) - CHECK_FUNCTION_EXISTS_GLIBC(acl_set_tag_type HAVE_ACL_SET_TAG_TYPE) - IF(HAVE_ACL_ADD_PERM AND - HAVE_ACL_CLEAR_PERMS AND - HAVE_ACL_CREATE_ENTRY AND - HAVE_ACL_DELETE_DEF_FILE AND - HAVE_ACL_FREE AND - HAVE_ACL_GET_ENTRY AND - HAVE_ACL_GET_FD AND - HAVE_ACL_GET_FILE AND - HAVE_ACL_GET_PERMSET AND - HAVE_ACL_GET_QUALIFIER AND - HAVE_ACL_GET_TAG_TYPE AND - HAVE_ACL_INIT AND - HAVE_ACL_SET_FD AND - HAVE_ACL_SET_FILE AND - HAVE_ACL_SET_QUALIFIER AND - HAVE_ACL_SET_TAG_TYPE) - SET(HAVE_POSIX_ACL_FUNCS 1) - ENDIF() - - CHECK_FUNCTION_EXISTS_GLIBC(acl_get_perm HAVE_ACL_GET_PERM) - - IF(HAVE_POSIX_ACL_FUNCS AND HAVE_ACL_LIBACL_H AND HAVE_LIBACL AND - HAVE_ACL_GET_PERM) - SET(ARCHIVE_ACL_LIBACL TRUE) - ELSE() - CHECK_FUNCTION_EXISTS(acl_add_flag_np HAVE_ACL_ADD_FLAG_NP) - CHECK_FUNCTION_EXISTS(acl_clear_flags_np HAVE_ACL_CLEAR_FLAGS_NP) - CHECK_FUNCTION_EXISTS(acl_get_brand_np HAVE_ACL_GET_BRAND_NP) - CHECK_FUNCTION_EXISTS(acl_get_entry_type_np HAVE_ACL_GET_ENTRY_TYPE_NP) - CHECK_FUNCTION_EXISTS(acl_get_flag_np HAVE_ACL_GET_FLAG_NP) - CHECK_FUNCTION_EXISTS(acl_get_flagset_np HAVE_ACL_GET_FLAGSET_NP) - CHECK_FUNCTION_EXISTS(acl_get_fd_np HAVE_ACL_GET_FD_NP) - CHECK_FUNCTION_EXISTS(acl_get_link_np HAVE_ACL_GET_LINK_NP) - CHECK_FUNCTION_EXISTS(acl_get_perm_np HAVE_ACL_GET_PERM_NP) - CHECK_FUNCTION_EXISTS(acl_is_trivial_np HAVE_ACL_IS_TRIVIAL_NP) - CHECK_FUNCTION_EXISTS(acl_set_entry_type_np HAVE_ACL_SET_ENTRY_TYPE_NP) - CHECK_FUNCTION_EXISTS(acl_set_fd_np HAVE_ACL_SET_FD_NP) - CHECK_FUNCTION_EXISTS(acl_set_link_np HAVE_ACL_SET_LINK_NP) - CHECK_FUNCTION_EXISTS(mbr_gid_to_uuid HAVE_MBR_GID_TO_UUID) - CHECK_FUNCTION_EXISTS(mbr_uid_to_uuid HAVE_MBR_UID_TO_UUID) - CHECK_FUNCTION_EXISTS(mbr_uuid_to_id HAVE_MBR_UUID_TO_ID) - - CHECK_C_SOURCE_COMPILES("#include -#include -int main(void) { return ACL_TYPE_EXTENDED; }" HAVE_DECL_ACL_TYPE_EXTENDED) - CHECK_C_SOURCE_COMPILES("#include -#include -int main(void) { return ACL_SYNCHRONIZE; }" HAVE_DECL_ACL_SYNCHRONIZE) - CHECK_SYMBOL_EXISTS(ACL_TYPE_NFS4 "sys/acl.h" HAVE_DECL_ACL_TYPE_NFS4) - CHECK_SYMBOL_EXISTS(ACL_USER "sys/acl.h" HAVE_DECL_ACL_USER) - - IF(HAVE_POSIX_ACL_FUNCS AND - HAVE_ACL_GET_FD_NP AND - HAVE_ACL_GET_PERM_NP AND - NOT HAVE_ACL_GET_PERM AND - HAVE_ACL_SET_FD_NP) - IF(HAVE_DECL_ACL_USER) - SET(ARCHIVE_ACL_FREEBSD TRUE) - IF(HAVE_DECL_ACL_TYPE_NFS4 AND - HAVE_ACL_ADD_FLAG_NP AND - HAVE_ACL_CLEAR_FLAGS_NP AND - HAVE_ACL_GET_BRAND_NP AND - HAVE_ACL_GET_ENTRY_TYPE_NP AND - HAVE_ACL_GET_FLAGSET_NP AND - HAVE_ACL_SET_ENTRY_TYPE_NP) - SET(ARCHIVE_ACL_FREEBSD_NFS4 TRUE) - ENDIF() - ELSEIF(HAVE_DECL_ACL_TYPE_EXTENDED AND - HAVE_MEMBERSHIP_H AND - HAVE_ACL_ADD_FLAG_NP AND - HAVE_ACL_CLEAR_FLAGS_NP AND - HAVE_ACL_GET_FLAGSET_NP AND - HAVE_ACL_GET_LINK_NP AND - HAVE_ACL_SET_LINK_NP AND - HAVE_MBR_UID_TO_UUID AND - HAVE_MBR_GID_TO_UUID AND - HAVE_MBR_UUID_TO_ID) - SET(ARCHIVE_ACL_DARWIN TRUE) - ENDIF() - ENDIF() - ENDIF() - ENDIF(HAVE_ACL_T AND HAVE_ACL_ENTRY_T AND HAVE_ACL_PERMSET_T AND - HAVE_ACL_TAG_T) - - # Richacl - CHECK_LIBRARY_EXISTS(richacl "richacl_get_file" "" HAVE_LIBRICHACL) - IF(HAVE_LIBRICHACL) - SET(CMAKE_REQUIRED_LIBRARIES "richacl") - FIND_LIBRARY(RICHACL_LIBRARY NAMES richacl) - LIST(APPEND ADDITIONAL_LIBS ${RICHACL_LIBRARY}) - ENDIF(HAVE_LIBRICHACL) - - CHECK_STRUCT_HAS_MEMBER("struct richace" e_type "sys/richacl.h" - HAVE_STRUCT_RICHACE) - CHECK_STRUCT_HAS_MEMBER("struct richacl" a_flags "sys/richacl.h" - HAVE_STRUCT_RICHACL) - - IF(HAVE_LIBRICHACL AND HAVE_STRUCT_RICHACL AND HAVE_STRUCT_RICHACE) - CHECK_FUNCTION_EXISTS_GLIBC(richacl_alloc HAVE_RICHACL_ALLOC) - CHECK_FUNCTION_EXISTS_GLIBC(richacl_equiv_mode HAVE_RICHACL_EQUIV_MODE) - CHECK_FUNCTION_EXISTS_GLIBC(richacl_free HAVE_RICHACL_FREE) - CHECK_FUNCTION_EXISTS_GLIBC(richacl_get_fd HAVE_RICHACL_GET_FD) - CHECK_FUNCTION_EXISTS_GLIBC(richacl_get_file HAVE_RICHACL_GET_FILE) - CHECK_FUNCTION_EXISTS_GLIBC(richacl_set_fd HAVE_RICHACL_SET_FD) - CHECK_FUNCTION_EXISTS_GLIBC(richacl_set_file HAVE_RICHACL_SET_FILE) - IF(HAVE_RICHACL_ALLOC AND - HAVE_RICHACL_EQUIV_MODE AND - HAVE_RICHACL_FREE AND - HAVE_RICHACL_GET_FD AND - HAVE_RICHACL_GET_FILE AND - HAVE_RICHACL_SET_FD AND - HAVE_RICHACL_SET_FILE) - SET(ARCHIVE_ACL_LIBRICHACL TRUE) - ENDIF() - ENDIF(HAVE_LIBRICHACL AND HAVE_STRUCT_RICHACL AND HAVE_STRUCT_RICHACE) - - IF(ARCHIVE_ACL_DARWIN) - MESSAGE(STATUS "ACL support: Darwin (limited NFSv4)") - ELSEIF(ARCHIVE_ACL_FREEBSD_NFS4) - MESSAGE(STATUS "ACL support: FreeBSD (POSIX.1e and NFSv4)") - ELSEIF(ARCHIVE_ACL_FREEBSD) - MESSAGE(STATUS "ACL support: FreeBSD (POSIX.1e)") - ELSEIF(ARCHIVE_ACL_LIBACL OR ARCHIVE_ACL_LIBRICHACL) - IF(ARCHIVE_ACL_LIBACL AND ARCHIVE_ACL_LIBRICHACL) - MESSAGE(STATUS "ACL support: libacl (POSIX.1e) + librichacl (NFSv4)") - ELSEIF(ARCHIVE_ACL_LIBRICHACL) - MESSAGE(STATUS "ACL support: librichacl (NFSv4)") - ELSE() - MESSAGE(STATUS "ACL support: libacl (POSIX.1e)") - ENDIF() - ELSEIF(ARCHIVE_ACL_SUNOS_NFS4) - MESSAGE(STATUS "ACL support: Solaris (POSIX.1e and NFSv4)") - ELSEIF(ARCHIVE_ACL_SUNOS) - MESSAGE(STATUS "ACL support: Solaris (POSIX.1e)") - ELSE() - MESSAGE(STATUS "ACL support: none") - ENDIF() - -ELSE(ENABLE_ACL) - # If someone runs cmake, then disables ACL support, we need - # to forcibly override the cached values for these. - SET(ARCHIVE_ACL_DARWIN FALSE) - SET(ARCHIVE_ACL_FREEBSD FALSE) - SET(ARCHIVE_ACL_FREEBSD_NFS4 FALSE) - SET(ARCHIVE_ACL_LIBACL FALSE) - SET(ARCHIVE_ACL_SUNOS FALSE) - SET(ARCHIVE_ACL_SUNOS_NFS4 FALSE) -ENDIF(ENABLE_ACL) - -# -# Check MD5/RMD160/SHA support -# NOTE: Crypto checks must be run last before generating config.h -# -CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA384;SHA512" LIBC) -CHECK_CRYPTO("SHA256;SHA384;SHA512" LIBC2) -CHECK_CRYPTO("SHA256;SHA384;SHA512" LIBC3) -CHECK_CRYPTO("MD5;SHA1;SHA256;SHA384;SHA512" LIBSYSTEM) -CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA384;SHA512" MBEDTLS) -CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA384;SHA512" NETTLE) -CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA384;SHA512" OPENSSL) - -# Libmd has to be probed after OpenSSL. -CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA512" LIBMD) - -CHECK_CRYPTO_WIN("MD5;SHA1;SHA256;SHA384;SHA512") - -# Check visibility annotations -SET(OLD_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") -SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fvisibility=hidden -Werror") -CHECK_C_SOURCE_COMPILES("void __attribute__((visibility(\"default\"))) foo(void); -int main() { return 0; }" HAVE_VISIBILITY_ATTR) -IF (HAVE_VISIBILITY_ATTR) - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden") - ADD_DEFINITIONS(-D__LIBARCHIVE_ENABLE_VISIBILITY) -ENDIF(HAVE_VISIBILITY_ATTR) -SET(CMAKE_REQUIRED_FLAGS "${OLD_CMAKE_REQUIRED_FLAGS}") - -# Generate "config.h" from "build/cmake/config.h.in" -CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/build/cmake/config.h.in - ${CMAKE_CURRENT_BINARY_DIR}/config.h) -INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR}) -ADD_DEFINITIONS(-DHAVE_CONFIG_H) - -# Handle generation of the libarchive.pc file for pkg-config -INCLUDE(CreatePkgConfigFile) - -# -# Register installation of PDF documents. -# -IF(WIN32 AND NOT CYGWIN) - # - # On Windows platform, It's better that we install PDF documents - # on one's computer. - # These PDF documents are available in the release package. - # - IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/doc/pdf) - INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/doc/pdf - DESTINATION share/man - FILES_MATCHING PATTERN "*.pdf" - ) - ENDIF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/doc/pdf) -ENDIF(WIN32 AND NOT CYGWIN) -# -# -# -INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/libarchive) -# -IF(MSVC) - ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE) -ENDIF(MSVC) - -IF(APPLE) - # CC_MD5_Init() functions are deprecated on macOS 10.15, but we want to use them - ADD_DEFINITIONS(-Wno-deprecated-declarations) -ENDIF(APPLE) - -IF(ENABLE_TEST) - ADD_CUSTOM_TARGET(run_all_tests) -ENDIF(ENABLE_TEST) - -add_subdirectory(libarchive) -add_subdirectory(cat) -add_subdirectory(tar) -add_subdirectory(cpio) -add_subdirectory(unzip) diff --git a/thirdparty/libarchive/COPYING b/thirdparty/libarchive/COPYING deleted file mode 100644 index 1b9723574..000000000 --- a/thirdparty/libarchive/COPYING +++ /dev/null @@ -1,65 +0,0 @@ -The libarchive distribution as a whole is Copyright by Tim Kientzle -and is subject to the copyright notice reproduced at the bottom of -this file. - -Each individual file in this distribution should have a clear -copyright/licensing statement at the beginning of the file. If any do -not, please let me know and I will rectify it. The following is -intended to summarize the copyright status of the individual files; -the actual statements in the files are controlling. - -* Except as listed below, all C sources (including .c and .h files) - and documentation files are subject to the copyright notice reproduced - at the bottom of this file. - -* The following source files are also subject in whole or in part to - a 3-clause UC Regents copyright; please read the individual source - files for details: - libarchive/archive_read_support_filter_compress.c - libarchive/archive_write_add_filter_compress.c - libarchive/mtree.5 - -* The following source files are in the public domain: - libarchive/archive_getdate.c - -* The following source files are triple-licensed with the ability to choose - from CC0 1.0 Universal, OpenSSL or Apache 2.0 licenses: - libarchive/archive_blake2.h - libarchive/archive_blake2_impl.h - libarchive/archive_blake2s_ref.c - libarchive/archive_blake2sp_ref.c - -* The build files---including Makefiles, configure scripts, - and auxiliary scripts used as part of the compile process---have - widely varying licensing terms. Please check individual files before - distributing them to see if those restrictions apply to you. - -I intend for all new source code to use the license below and hope over -time to replace code with other licenses with new implementations that -do use the license below. The varying licensing of the build scripts -seems to be an unavoidable mess. - - -Copyright (c) 2003-2018 -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. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. diff --git a/thirdparty/libarchive/INSTALL b/thirdparty/libarchive/INSTALL deleted file mode 100644 index 2fafbd504..000000000 --- a/thirdparty/libarchive/INSTALL +++ /dev/null @@ -1,35 +0,0 @@ -More complete build documentation is available on the libarchive -Wiki: https://github.com/libarchive/libarchive/wiki - -On most Unix-like systems, you should be able to install libarchive, -bsdtar, and bsdcpio using the following common steps: - ./configure - make - make install - -If you need to customize the target directories or otherwise adjust -the build setting, use - ./configure --help -to list the configure options. - -If you are developing libarchive and need to update the -configure script and other build files: - /bin/sh build/autogen.sh - -To create a distribution, please use the 'distcheck' target: - /bin/sh build/autogen.sh && ./configure && make distcheck - -On Unix-like and non-Unix-like systems, use the "cmake" utility (available from -http://cmake.org/) to generate suitable build files for your platform. -Cmake requires the name of the directory containing CmakeLists.txt and -the "generator" to use for your build environment. For example, to -build with Xcode on Mac OS, you can use the following command: - cmake -G "Xcode" ~/libarchive-download-dir/ -The result will be appropriate makefiles, solution files, or project -files that can be used with the corresponding development tool. -The default on Unix-like systems is to generate Makefiles, so you -can also use cmake instead of the configure script: - cmake ~/libarchive-download-dir/ - make - make install -See the libarchive Wiki or the cmake site for further documentation. diff --git a/thirdparty/libarchive/Makefile.am b/thirdparty/libarchive/Makefile.am deleted file mode 100644 index 42424a233..000000000 --- a/thirdparty/libarchive/Makefile.am +++ /dev/null @@ -1,1550 +0,0 @@ -## Process this file with automake to produce Makefile.in - -AUTOMAKE_OPTIONS= foreign subdir-objects -ACLOCAL_AMFLAGS = -I build/autoconf - -# -# What to build and install -# -lib_LTLIBRARIES= libarchive.la -noinst_LTLIBRARIES= libarchive_fe.la -bin_PROGRAMS= $(bsdtar_programs) $(bsdcpio_programs) $(bsdcat_programs) $(bsdunzip_programs) -man_MANS= $(libarchive_man_MANS) $(bsdtar_man_MANS) $(bsdcpio_man_MANS) $(bsdcat_man_MANS) $(bsdunzip_man_MANS) -BUILT_SOURCES= libarchive/test/list.h tar/test/list.h cpio/test/list.h cat/test/list.h unzip/test/list.h - -# -# What to test: We always test libarchive, test bsdtar and bsdcpio only -# if we built them. -# -check_PROGRAMS= libarchive_test $(bsdtar_test_programs) $(bsdcpio_test_programs) $(bsdcat_test_programs) $(bsdunzip_test_programs) -TESTS= libarchive_test $(bsdtar_test_programs) $(bsdcpio_test_programs) $(bsdcat_test_programs) $(bsdunzip_test_programs) -TESTS_ENVIRONMENT= $(libarchive_TESTS_ENVIRONMENT) $(bsdtar_TESTS_ENVIRONMENT) $(bsdcpio_TESTS_ENVIRONMENT) $(bsdcat_TESTS_ENVIRONMENT) $(bsdunzip_TESTS_ENVIRONMENT) -# Always build and test both bsdtar and bsdcpio as part of 'distcheck' -DISTCHECK_CONFIGURE_FLAGS = --enable-bsdtar --enable-bsdcpio -# The next line is commented out by default in shipping libarchive releases. -# It is uncommented by default in trunk. -# DEV_CFLAGS=-Werror -Wextra -Wunused -Wshadow -Wmissing-prototypes -Wcast-qual -g -AM_CFLAGS=$(DEV_CFLAGS) -PLATFORMCPPFLAGS = @PLATFORMCPPFLAGS@ -AM_CPPFLAGS=$(PLATFORMCPPFLAGS) - -# -# What to include in the distribution -# -EXTRA_DIST= \ - CMakeLists.txt \ - README.md \ - build/autogen.sh \ - build/bump-version.sh \ - build/clean.sh \ - build/cmake \ - build/version \ - contrib \ - doc \ - examples \ - $(libarchive_EXTRA_DIST) \ - $(libarchive_test_EXTRA_DIST) \ - $(bsdtar_EXTRA_DIST) \ - $(bsdtar_test_EXTRA_DIST) \ - $(bsdcpio_EXTRA_DIST) \ - $(bsdcpio_test_EXTRA_DIST) \ - $(bsdcat_EXTRA_DIST) \ - $(bsdcat_test_EXTRA_DIST) \ - $(bsdunzip_EXTRA_DIST) \ - $(bsdunzip_test_EXTRA_DIST) - -# a) Clean out some unneeded files and directories -# b) Collect all documentation and format it for distribution. -dist-hook: - rm -rf `find $(distdir) -name CVS -type d` - rm -rf `find $(distdir) -name .svn -type d` - rm -f `find $(distdir) -name '*~'` - rm -f `find $(distdir) -name '*.out'` - rm -f `find $(distdir) -name '*.core'` - -rm -f $(distdir)/*/Makefile $(distdir)/*/*/Makefile - cd $(distdir)/doc && /bin/sh update.sh - -# -# Extra rules for cleanup -# -DISTCLEANFILES= \ - libarchive/test/list.h \ - tar/test/list.h \ - cpio/test/list.h \ - cat/test/list.h \ - unzip/test/list.h - -distclean-local: - -rm -rf .ref - -rm -rf autom4te.cache/ - -rm -f *~ - -[ -f libarchive/Makefile ] && cd libarchive && make clean - -[ -f libarchive/test/Makefile ] && cd libarchive/test && make clean - -[ -f tar/Makefile ] && cd tar && make clean - -[ -f tar/test/Makefile ] && cd tar/test && make clean - -[ -f cpio/Makefile ] && cd cpio && make clean - -[ -f cpio/test/Makefile ] && cd cpio/test && make clean - -[ -f cat/Makefile ] && cd cat && make clean - -[ -f cat/test/Makefile ] && cd cat/test && make clean - -[ -f unzip/Makefile ] && cd unzip && make clean - -[ -f unzip/test/Makefile ] && cd unzip/test && make clean - -# -# Libarchive headers, source, etc. -# -# - -include_HEADERS= libarchive/archive.h libarchive/archive_entry.h - -libarchive_la_SOURCES= \ - libarchive/archive_acl.c \ - libarchive/archive_acl_private.h \ - libarchive/archive_check_magic.c \ - libarchive/archive_cmdline.c \ - libarchive/archive_cmdline_private.h \ - libarchive/archive_crc32.h \ - libarchive/archive_cryptor.c \ - libarchive/archive_cryptor_private.h \ - libarchive/archive_digest.c \ - libarchive/archive_digest_private.h \ - libarchive/archive_endian.h \ - libarchive/archive_entry.c \ - libarchive/archive_entry.h \ - libarchive/archive_entry_copy_stat.c \ - libarchive/archive_entry_link_resolver.c \ - libarchive/archive_entry_locale.h \ - libarchive/archive_entry_private.h \ - libarchive/archive_entry_sparse.c \ - libarchive/archive_entry_stat.c \ - libarchive/archive_entry_strmode.c \ - libarchive/archive_entry_xattr.c \ - libarchive/archive_getdate.c \ - libarchive/archive_getdate.h \ - libarchive/archive_hmac.c \ - libarchive/archive_hmac_private.h \ - libarchive/archive_match.c \ - libarchive/archive_openssl_evp_private.h \ - libarchive/archive_openssl_hmac_private.h \ - libarchive/archive_options.c \ - libarchive/archive_options_private.h \ - libarchive/archive_pack_dev.h \ - libarchive/archive_pack_dev.c \ - libarchive/archive_pathmatch.c \ - libarchive/archive_pathmatch.h \ - libarchive/archive_platform.h \ - libarchive/archive_platform_acl.h \ - libarchive/archive_platform_xattr.h \ - libarchive/archive_ppmd_private.h \ - libarchive/archive_ppmd7.c \ - libarchive/archive_ppmd7_private.h \ - libarchive/archive_ppmd8.c \ - libarchive/archive_ppmd8_private.h \ - libarchive/archive_private.h \ - libarchive/archive_random.c \ - libarchive/archive_random_private.h \ - libarchive/archive_rb.c \ - libarchive/archive_rb.h \ - libarchive/archive_read.c \ - libarchive/archive_read_add_passphrase.c \ - libarchive/archive_read_append_filter.c \ - libarchive/archive_read_data_into_fd.c \ - libarchive/archive_read_disk_entry_from_file.c \ - libarchive/archive_read_disk_posix.c \ - libarchive/archive_read_disk_private.h \ - libarchive/archive_read_disk_set_standard_lookup.c \ - libarchive/archive_read_extract.c \ - libarchive/archive_read_extract2.c \ - libarchive/archive_read_open_fd.c \ - libarchive/archive_read_open_file.c \ - libarchive/archive_read_open_filename.c \ - libarchive/archive_read_open_memory.c \ - libarchive/archive_read_private.h \ - libarchive/archive_read_set_format.c \ - libarchive/archive_read_set_options.c \ - libarchive/archive_read_support_filter_all.c \ - libarchive/archive_read_support_filter_bzip2.c \ - libarchive/archive_read_support_filter_by_code.c \ - libarchive/archive_read_support_filter_compress.c \ - libarchive/archive_read_support_filter_grzip.c \ - libarchive/archive_read_support_filter_gzip.c \ - libarchive/archive_read_support_filter_lrzip.c \ - libarchive/archive_read_support_filter_lz4.c \ - libarchive/archive_read_support_filter_lzop.c \ - libarchive/archive_read_support_filter_none.c \ - libarchive/archive_read_support_filter_program.c \ - libarchive/archive_read_support_filter_rpm.c \ - libarchive/archive_read_support_filter_uu.c \ - libarchive/archive_read_support_filter_xz.c \ - libarchive/archive_read_support_filter_zstd.c \ - libarchive/archive_read_support_format_7zip.c \ - libarchive/archive_read_support_format_all.c \ - libarchive/archive_read_support_format_ar.c \ - libarchive/archive_read_support_format_by_code.c \ - libarchive/archive_read_support_format_cab.c \ - libarchive/archive_read_support_format_cpio.c \ - libarchive/archive_read_support_format_empty.c \ - libarchive/archive_read_support_format_iso9660.c \ - libarchive/archive_read_support_format_lha.c \ - libarchive/archive_read_support_format_mtree.c \ - libarchive/archive_read_support_format_rar.c \ - libarchive/archive_read_support_format_rar5.c \ - libarchive/archive_read_support_format_raw.c \ - libarchive/archive_read_support_format_tar.c \ - libarchive/archive_read_support_format_warc.c \ - libarchive/archive_read_support_format_xar.c \ - libarchive/archive_read_support_format_zip.c \ - libarchive/archive_string.c \ - libarchive/archive_string.h \ - libarchive/archive_string_composition.h \ - libarchive/archive_string_sprintf.c \ - libarchive/archive_util.c \ - libarchive/archive_version_details.c \ - libarchive/archive_virtual.c \ - libarchive/archive_write.c \ - libarchive/archive_write_disk_posix.c \ - libarchive/archive_write_disk_private.h \ - libarchive/archive_write_disk_set_standard_lookup.c \ - libarchive/archive_write_open_fd.c \ - libarchive/archive_write_open_file.c \ - libarchive/archive_write_open_filename.c \ - libarchive/archive_write_open_memory.c \ - libarchive/archive_write_private.h \ - libarchive/archive_write_add_filter.c \ - libarchive/archive_write_add_filter_b64encode.c \ - libarchive/archive_write_add_filter_by_name.c \ - libarchive/archive_write_add_filter_bzip2.c \ - libarchive/archive_write_add_filter_compress.c \ - libarchive/archive_write_add_filter_grzip.c \ - libarchive/archive_write_add_filter_gzip.c \ - libarchive/archive_write_add_filter_lrzip.c \ - libarchive/archive_write_add_filter_lz4.c \ - libarchive/archive_write_add_filter_lzop.c \ - libarchive/archive_write_add_filter_none.c \ - libarchive/archive_write_add_filter_program.c \ - libarchive/archive_write_add_filter_uuencode.c \ - libarchive/archive_write_add_filter_xz.c \ - libarchive/archive_write_add_filter_zstd.c \ - libarchive/archive_write_set_format.c \ - libarchive/archive_write_set_format_7zip.c \ - libarchive/archive_write_set_format_ar.c \ - libarchive/archive_write_set_format_by_name.c \ - libarchive/archive_write_set_format_cpio.c \ - libarchive/archive_write_set_format_cpio_binary.c \ - libarchive/archive_write_set_format_cpio_newc.c \ - libarchive/archive_write_set_format_cpio_odc.c \ - libarchive/archive_write_set_format_filter_by_ext.c \ - libarchive/archive_write_set_format_iso9660.c \ - libarchive/archive_write_set_format_mtree.c \ - libarchive/archive_write_set_format_pax.c \ - libarchive/archive_write_set_format_private.h \ - libarchive/archive_write_set_format_raw.c \ - libarchive/archive_write_set_format_shar.c \ - libarchive/archive_write_set_format_ustar.c \ - libarchive/archive_write_set_format_v7tar.c \ - libarchive/archive_write_set_format_gnutar.c \ - libarchive/archive_write_set_format_warc.c \ - libarchive/archive_write_set_format_xar.c \ - libarchive/archive_write_set_format_zip.c \ - libarchive/archive_write_set_options.c \ - libarchive/archive_write_set_passphrase.c \ - libarchive/archive_xxhash.h \ - libarchive/config_freebsd.h \ - libarchive/filter_fork_posix.c \ - libarchive/filter_fork.h \ - libarchive/xxhash.c - -if INC_WINDOWS_FILES -libarchive_la_SOURCES+= \ - libarchive/archive_entry_copy_bhfi.c \ - libarchive/archive_read_disk_windows.c \ - libarchive/archive_windows.h \ - libarchive/archive_windows.c \ - libarchive/archive_write_disk_windows.c \ - libarchive/filter_fork_windows.c -endif - -if INC_BLAKE2 -libarchive_la_SOURCES+= \ - libarchive/archive_blake2.h \ - libarchive/archive_blake2_impl.h \ - libarchive/archive_blake2s_ref.c \ - libarchive/archive_blake2sp_ref.c -endif - -if INC_LINUX_ACL -libarchive_la_SOURCES+= libarchive/archive_disk_acl_linux.c -else -if INC_SUNOS_ACL -libarchive_la_SOURCES+= libarchive/archive_disk_acl_sunos.c -else -if INC_DARWIN_ACL -libarchive_la_SOURCES+= libarchive/archive_disk_acl_darwin.c -else -if INC_FREEBSD_ACL -libarchive_la_SOURCES+= libarchive/archive_disk_acl_freebsd.c -endif -endif -endif -endif - -# -no-undefined marks that libarchive doesn't rely on symbols -# defined in the application. This is mandatory for cygwin. -libarchive_la_LDFLAGS= -no-undefined -version-info $(ARCHIVE_LIBTOOL_VERSION) $(GC_SECTIONS) -libarchive_la_LIBADD= $(LTLIBICONV) - -# Manpages to install -libarchive_man_MANS= \ - libarchive/archive_entry.3 \ - libarchive/archive_entry_acl.3 \ - libarchive/archive_entry_linkify.3 \ - libarchive/archive_entry_misc.3 \ - libarchive/archive_entry_paths.3 \ - libarchive/archive_entry_perms.3 \ - libarchive/archive_entry_stat.3 \ - libarchive/archive_entry_time.3 \ - libarchive/archive_read.3 \ - libarchive/archive_read_add_passphrase.3 \ - libarchive/archive_read_data.3 \ - libarchive/archive_read_disk.3 \ - libarchive/archive_read_extract.3 \ - libarchive/archive_read_filter.3 \ - libarchive/archive_read_format.3 \ - libarchive/archive_read_free.3 \ - libarchive/archive_read_header.3 \ - libarchive/archive_read_new.3 \ - libarchive/archive_read_open.3 \ - libarchive/archive_read_set_options.3 \ - libarchive/archive_util.3 \ - libarchive/archive_write.3 \ - libarchive/archive_write_blocksize.3 \ - libarchive/archive_write_data.3 \ - libarchive/archive_write_disk.3 \ - libarchive/archive_write_filter.3 \ - libarchive/archive_write_finish_entry.3 \ - libarchive/archive_write_format.3 \ - libarchive/archive_write_free.3 \ - libarchive/archive_write_header.3 \ - libarchive/archive_write_new.3 \ - libarchive/archive_write_open.3 \ - libarchive/archive_write_set_options.3 \ - libarchive/archive_write_set_passphrase.3 \ - libarchive/cpio.5 \ - libarchive/libarchive.3 \ - libarchive/libarchive_changes.3 \ - libarchive/libarchive_internals.3 \ - libarchive/libarchive-formats.5 \ - libarchive/mtree.5 \ - libarchive/tar.5 - -# Additional libarchive files to include in the distribution -libarchive_EXTRA_DIST= \ - libarchive/archive_windows.c \ - libarchive/archive_windows.h \ - libarchive/filter_fork_windows.c \ - libarchive/CMakeLists.txt \ - $(libarchive_man_MANS) - -# pkgconfig -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = build/pkgconfig/libarchive.pc - -# Sources needed by all test programs -test_utils_SOURCES= \ - test_utils/test_utils.c \ - test_utils/test_utils.h \ - test_utils/test_main.c \ - test_utils/test_common.h - -# -# -# libarchive_test program -# -# -libarchive_test_SOURCES= \ - $(libarchive_la_SOURCES) \ - $(test_utils_SOURCES) \ - libarchive/test/read_open_memory.c \ - libarchive/test/test.h \ - libarchive/test/test_acl_nfs4.c \ - libarchive/test/test_acl_pax.c \ - libarchive/test/test_acl_platform_nfs4.c \ - libarchive/test/test_acl_platform_posix1e.c \ - libarchive/test/test_acl_posix1e.c \ - libarchive/test/test_acl_text.c \ - libarchive/test/test_archive_api_feature.c \ - libarchive/test/test_archive_clear_error.c \ - libarchive/test/test_archive_cmdline.c \ - libarchive/test/test_archive_digest.c \ - libarchive/test/test_archive_getdate.c \ - libarchive/test/test_archive_match_owner.c \ - libarchive/test/test_archive_match_path.c \ - libarchive/test/test_archive_match_time.c \ - libarchive/test/test_archive_pathmatch.c \ - libarchive/test/test_archive_read_add_passphrase.c \ - libarchive/test/test_archive_read_close_twice.c \ - libarchive/test/test_archive_read_close_twice_open_fd.c \ - libarchive/test/test_archive_read_close_twice_open_filename.c \ - libarchive/test/test_archive_read_multiple_data_objects.c \ - libarchive/test/test_archive_read_next_header_empty.c \ - libarchive/test/test_archive_read_next_header_raw.c \ - libarchive/test/test_archive_read_open2.c \ - libarchive/test/test_archive_read_set_filter_option.c \ - libarchive/test/test_archive_read_set_format_option.c \ - libarchive/test/test_archive_read_set_option.c \ - libarchive/test/test_archive_read_set_options.c \ - libarchive/test/test_archive_read_support.c \ - libarchive/test/test_archive_set_error.c \ - libarchive/test/test_archive_string.c \ - libarchive/test/test_archive_string_conversion.c \ - libarchive/test/test_archive_write_add_filter_by_name.c \ - libarchive/test/test_archive_write_set_filter_option.c \ - libarchive/test/test_archive_write_set_format_by_name.c \ - libarchive/test/test_archive_write_set_format_filter_by_ext.c \ - libarchive/test/test_archive_write_set_format_option.c \ - libarchive/test/test_archive_write_set_option.c \ - libarchive/test/test_archive_write_set_options.c \ - libarchive/test/test_archive_write_set_passphrase.c \ - libarchive/test/test_bad_fd.c \ - libarchive/test/test_compat_bzip2.c \ - libarchive/test/test_compat_cpio.c \ - libarchive/test/test_compat_gtar.c \ - libarchive/test/test_compat_gzip.c \ - libarchive/test/test_compat_lz4.c \ - libarchive/test/test_compat_lzip.c \ - libarchive/test/test_compat_lzma.c \ - libarchive/test/test_compat_lzop.c \ - libarchive/test/test_compat_mac.c \ - libarchive/test/test_compat_perl_archive_tar.c \ - libarchive/test/test_compat_plexus_archiver_tar.c \ - libarchive/test/test_compat_solaris_tar_acl.c \ - libarchive/test/test_compat_solaris_pax_sparse.c \ - libarchive/test/test_compat_star_acl.c \ - libarchive/test/test_compat_tar_directory.c \ - libarchive/test/test_compat_tar_hardlink.c \ - libarchive/test/test_compat_uudecode.c \ - libarchive/test/test_compat_uudecode_large.c \ - libarchive/test/test_compat_xz.c \ - libarchive/test/test_compat_zip.c \ - libarchive/test/test_compat_zstd.c \ - libarchive/test/test_empty_write.c \ - libarchive/test/test_entry.c \ - libarchive/test/test_entry_strmode.c \ - libarchive/test/test_extattr_freebsd.c \ - libarchive/test/test_filter_count.c \ - libarchive/test/test_fuzz.c \ - libarchive/test/test_gnutar_filename_encoding.c \ - libarchive/test/test_link_resolver.c \ - libarchive/test/test_open_failure.c \ - libarchive/test/test_open_fd.c \ - libarchive/test/test_open_file.c \ - libarchive/test/test_open_filename.c \ - libarchive/test/test_pax_filename_encoding.c \ - libarchive/test/test_pax_xattr_header.c \ - libarchive/test/test_read_data_large.c \ - libarchive/test/test_read_disk.c \ - libarchive/test/test_read_disk_directory_traversals.c \ - libarchive/test/test_read_disk_entry_from_file.c \ - libarchive/test/test_read_extract.c \ - libarchive/test/test_read_file_nonexistent.c \ - libarchive/test/test_read_filter_compress.c \ - libarchive/test/test_read_filter_grzip.c \ - libarchive/test/test_read_filter_lrzip.c \ - libarchive/test/test_read_filter_lzop.c \ - libarchive/test/test_read_filter_lzop_multiple_parts.c \ - libarchive/test/test_read_filter_program.c \ - libarchive/test/test_read_filter_program_signature.c \ - libarchive/test/test_read_filter_uudecode.c \ - libarchive/test/test_read_filter_uudecode_raw.c \ - libarchive/test/test_read_format_7zip.c \ - libarchive/test/test_read_format_7zip_encryption_data.c \ - libarchive/test/test_read_format_7zip_encryption_partially.c \ - libarchive/test/test_read_format_7zip_encryption_header.c \ - libarchive/test/test_read_format_7zip_malformed.c \ - libarchive/test/test_read_format_7zip_packinfo_digests.c \ - libarchive/test/test_read_format_ar.c \ - libarchive/test/test_read_format_cab.c \ - libarchive/test/test_read_format_cab_filename.c \ - libarchive/test/test_read_format_cpio_afio.c \ - libarchive/test/test_read_format_cpio_bin.c \ - libarchive/test/test_read_format_cpio_bin_Z.c \ - libarchive/test/test_read_format_cpio_bin_be.c \ - libarchive/test/test_read_format_cpio_bin_bz2.c \ - libarchive/test/test_read_format_cpio_bin_gz.c \ - libarchive/test/test_read_format_cpio_bin_le.c \ - libarchive/test/test_read_format_cpio_bin_lzip.c \ - libarchive/test/test_read_format_cpio_bin_lzma.c \ - libarchive/test/test_read_format_cpio_bin_xz.c \ - libarchive/test/test_read_format_cpio_filename.c \ - libarchive/test/test_read_format_cpio_odc.c \ - libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c \ - libarchive/test/test_read_format_cpio_svr4_gzip.c \ - libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c \ - libarchive/test/test_read_format_cpio_svr4c_Z.c \ - libarchive/test/test_read_format_empty.c \ - libarchive/test/test_read_format_gtar_filename.c \ - libarchive/test/test_read_format_gtar_gz.c \ - libarchive/test/test_read_format_gtar_lzma.c \ - libarchive/test/test_read_format_gtar_sparse.c \ - libarchive/test/test_read_format_gtar_sparse_skip_entry.c \ - libarchive/test/test_read_format_iso_Z.c \ - libarchive/test/test_read_format_iso_multi_extent.c \ - libarchive/test/test_read_format_iso_xorriso.c \ - libarchive/test/test_read_format_isojoliet_bz2.c \ - libarchive/test/test_read_format_isojoliet_long.c \ - libarchive/test/test_read_format_isojoliet_rr.c \ - libarchive/test/test_read_format_isojoliet_versioned.c \ - libarchive/test/test_read_format_isorr_bz2.c \ - libarchive/test/test_read_format_isorr_ce.c \ - libarchive/test/test_read_format_isorr_new_bz2.c \ - libarchive/test/test_read_format_isorr_rr_moved.c \ - libarchive/test/test_read_format_isozisofs_bz2.c \ - libarchive/test/test_read_format_lha.c \ - libarchive/test/test_read_format_lha_bugfix_0.c \ - libarchive/test/test_read_format_lha_filename.c \ - libarchive/test/test_read_format_lha_filename_utf16.c \ - libarchive/test/test_read_format_mtree.c \ - libarchive/test/test_read_format_mtree_crash747.c \ - libarchive/test/test_read_format_pax_bz2.c \ - libarchive/test/test_read_format_rar.c \ - libarchive/test/test_read_format_rar_encryption_data.c \ - libarchive/test/test_read_format_rar_encryption_partially.c \ - libarchive/test/test_read_format_rar_encryption_header.c \ - libarchive/test/test_read_format_rar_filter.c \ - libarchive/test/test_read_format_rar_invalid1.c \ - libarchive/test/test_read_format_rar5.c \ - libarchive/test/test_read_format_raw.c \ - libarchive/test/test_read_format_tar.c \ - libarchive/test/test_read_format_tar_concatenated.c \ - libarchive/test/test_read_format_tar_empty_pax.c \ - libarchive/test/test_read_format_tar_empty_filename.c \ - libarchive/test/test_read_format_tar_empty_with_gnulabel.c \ - libarchive/test/test_read_format_tar_filename.c \ - libarchive/test/test_read_format_tar_invalid_pax_size.c \ - libarchive/test/test_read_format_tbz.c \ - libarchive/test/test_read_format_tgz.c \ - libarchive/test/test_read_format_tlz.c \ - libarchive/test/test_read_format_txz.c \ - libarchive/test/test_read_format_tz.c \ - libarchive/test/test_read_format_ustar_filename.c \ - libarchive/test/test_read_format_warc.c \ - libarchive/test/test_read_format_xar.c \ - libarchive/test/test_read_format_zip.c \ - libarchive/test/test_read_format_zip_7075_utf8_paths.c \ - libarchive/test/test_read_format_zip_comment_stored.c \ - libarchive/test/test_read_format_zip_encryption_data.c \ - libarchive/test/test_read_format_zip_encryption_partially.c \ - libarchive/test/test_read_format_zip_encryption_header.c \ - libarchive/test/test_read_format_zip_extra_padding.c \ - libarchive/test/test_read_format_zip_filename.c \ - libarchive/test/test_read_format_zip_high_compression.c \ - libarchive/test/test_read_format_zip_jar.c \ - libarchive/test/test_read_format_zip_mac_metadata.c \ - libarchive/test/test_read_format_zip_malformed.c \ - libarchive/test/test_read_format_zip_msdos.c \ - libarchive/test/test_read_format_zip_nested.c \ - libarchive/test/test_read_format_zip_nofiletype.c \ - libarchive/test/test_read_format_zip_padded.c \ - libarchive/test/test_read_format_zip_sfx.c \ - libarchive/test/test_read_format_zip_traditional_encryption_data.c \ - libarchive/test/test_read_format_zip_winzip_aes.c \ - libarchive/test/test_read_format_zip_winzip_aes_large.c \ - libarchive/test/test_read_format_zip_zip64.c \ - libarchive/test/test_read_format_zip_with_invalid_traditional_eocd.c \ - libarchive/test/test_read_large.c \ - libarchive/test/test_read_pax_xattr_rht_security_selinux.c \ - libarchive/test/test_read_pax_xattr_schily.c \ - libarchive/test/test_read_pax_truncated.c \ - libarchive/test/test_read_position.c \ - libarchive/test/test_read_set_format.c \ - libarchive/test/test_read_too_many_filters.c \ - libarchive/test/test_read_truncated.c \ - libarchive/test/test_read_truncated_filter.c \ - libarchive/test/test_short_writes.c \ - libarchive/test/test_sparse_basic.c \ - libarchive/test/test_tar_filenames.c \ - libarchive/test/test_tar_large.c \ - libarchive/test/test_ustar_filenames.c \ - libarchive/test/test_ustar_filename_encoding.c \ - libarchive/test/test_warn_missing_hardlink_target.c \ - libarchive/test/test_write_disk.c \ - libarchive/test/test_write_disk_appledouble.c \ - libarchive/test/test_write_disk_failures.c \ - libarchive/test/test_write_disk_fixup.c \ - libarchive/test/test_write_disk_hardlink.c \ - libarchive/test/test_write_disk_hfs_compression.c \ - libarchive/test/test_write_disk_lookup.c \ - libarchive/test/test_write_disk_mac_metadata.c \ - libarchive/test/test_write_disk_no_hfs_compression.c \ - libarchive/test/test_write_disk_perms.c \ - libarchive/test/test_write_disk_secure.c \ - libarchive/test/test_write_disk_secure744.c \ - libarchive/test/test_write_disk_secure745.c \ - libarchive/test/test_write_disk_secure746.c \ - libarchive/test/test_write_disk_sparse.c \ - libarchive/test/test_write_disk_symlink.c \ - libarchive/test/test_write_disk_times.c \ - libarchive/test/test_write_filter_b64encode.c \ - libarchive/test/test_write_filter_bzip2.c \ - libarchive/test/test_write_filter_compress.c \ - libarchive/test/test_write_filter_gzip.c \ - libarchive/test/test_write_filter_gzip_timestamp.c \ - libarchive/test/test_write_filter_lrzip.c \ - libarchive/test/test_write_filter_lz4.c \ - libarchive/test/test_write_filter_lzip.c \ - libarchive/test/test_write_filter_lzma.c \ - libarchive/test/test_write_filter_lzop.c \ - libarchive/test/test_write_filter_program.c \ - libarchive/test/test_write_filter_uuencode.c \ - libarchive/test/test_write_filter_xz.c \ - libarchive/test/test_write_filter_zstd.c \ - libarchive/test/test_write_format_7zip.c \ - libarchive/test/test_write_format_7zip_empty.c \ - libarchive/test/test_write_format_7zip_large.c \ - libarchive/test/test_write_format_ar.c \ - libarchive/test/test_write_format_cpio.c \ - libarchive/test/test_write_format_cpio_empty.c \ - libarchive/test/test_write_format_cpio_newc.c \ - libarchive/test/test_write_format_cpio_odc.c \ - libarchive/test/test_write_format_gnutar.c \ - libarchive/test/test_write_format_gnutar_filenames.c \ - libarchive/test/test_write_format_iso9660.c \ - libarchive/test/test_write_format_iso9660_boot.c \ - libarchive/test/test_write_format_iso9660_empty.c \ - libarchive/test/test_write_format_iso9660_filename.c \ - libarchive/test/test_write_format_iso9660_zisofs.c \ - libarchive/test/test_write_format_mtree.c \ - libarchive/test/test_write_format_mtree_absolute_path.c \ - libarchive/test/test_write_format_mtree_classic.c \ - libarchive/test/test_write_format_mtree_classic_indent.c\ - libarchive/test/test_write_format_mtree_fflags.c \ - libarchive/test/test_write_format_mtree_no_separator.c \ - libarchive/test/test_write_format_mtree_quoted_filename.c\ - libarchive/test/test_write_format_pax.c \ - libarchive/test/test_write_format_raw.c \ - libarchive/test/test_write_format_raw_b64.c \ - libarchive/test/test_write_format_shar_empty.c \ - libarchive/test/test_write_format_tar.c \ - libarchive/test/test_write_format_tar_empty.c \ - libarchive/test/test_write_format_tar_sparse.c \ - libarchive/test/test_write_format_tar_ustar.c \ - libarchive/test/test_write_format_tar_v7tar.c \ - libarchive/test/test_write_format_warc.c \ - libarchive/test/test_write_format_warc_empty.c \ - libarchive/test/test_write_format_xar.c \ - libarchive/test/test_write_format_xar_empty.c \ - libarchive/test/test_write_format_zip.c \ - libarchive/test/test_write_format_zip_compression_store.c \ - libarchive/test/test_write_format_zip_entry_size_unset.c \ - libarchive/test/test_write_format_zip_empty.c \ - libarchive/test/test_write_format_zip_empty_zip64.c \ - libarchive/test/test_write_format_zip_file.c \ - libarchive/test/test_write_format_zip_file_zip64.c \ - libarchive/test/test_write_format_zip_large.c \ - libarchive/test/test_write_format_zip_zip64.c \ - libarchive/test/test_write_open_memory.c \ - libarchive/test/test_write_read_format_zip.c \ - libarchive/test/test_xattr_platform.c \ - libarchive/test/test_zip_filename_encoding.c - -libarchive_test_CPPFLAGS= \ - -I$(top_srcdir)/libarchive \ - -I$(top_srcdir)/libarchive/test \ - -I$(top_srcdir)/test_utils \ - -I$(top_builddir)/libarchive/test \ - -DLIBARCHIVE_STATIC $(PLATFORMCPPFLAGS) - -libarchive_test_LDADD= $(LTLIBICONV) - -# The "list.h" file just lists all of the tests defined in all of the sources. -# Building it automatically provides a sanity-check on libarchive_test_SOURCES -# above. -libarchive/test/list.h: Makefile - $(MKDIR_P) libarchive/test - cat $(top_srcdir)/libarchive/test/test_*.c | grep '^DEFINE_TEST' > libarchive/test/list.h - -libarchive_TESTS_ENVIRONMENT= LIBARCHIVE_TEST_FILES=`cd $(top_srcdir);/bin/pwd`/libarchive/test LRZIP=NOCONFIG - -libarchive_test_EXTRA_DIST=\ - libarchive/test/list.h \ - libarchive/test/test_acl_pax_posix1e.tar.uu \ - libarchive/test/test_acl_pax_nfs4.tar.uu \ - libarchive/test/test_archive_string_conversion.txt.Z.uu \ - libarchive/test/test_compat_bzip2_1.tbz.uu \ - libarchive/test/test_compat_bzip2_2.tbz.uu \ - libarchive/test/test_compat_cpio_1.cpio.uu \ - libarchive/test/test_compat_gtar_1.tar.uu \ - libarchive/test/test_compat_gtar_2.tar.uu \ - libarchive/test/test_compat_gzip_1.tgz.uu \ - libarchive/test/test_compat_gzip_2.tgz.uu \ - libarchive/test/test_compat_lz4_1.tar.lz4.uu \ - libarchive/test/test_compat_lz4_2.tar.lz4.uu \ - libarchive/test/test_compat_lz4_3.tar.lz4.uu \ - libarchive/test/test_compat_lz4_B4.tar.lz4.uu \ - libarchive/test/test_compat_lz4_B4BD.tar.lz4.uu \ - libarchive/test/test_compat_lz4_B4BDBX.tar.lz4.uu \ - libarchive/test/test_compat_lz4_B5.tar.lz4.uu \ - libarchive/test/test_compat_lz4_B5BD.tar.lz4.uu \ - libarchive/test/test_compat_lz4_B6.tar.lz4.uu \ - libarchive/test/test_compat_lz4_B6BD.tar.lz4.uu \ - libarchive/test/test_compat_lz4_B7.tar.lz4.uu \ - libarchive/test/test_compat_lz4_B7BD.tar.lz4.uu \ - libarchive/test/test_compat_lzip_1.tlz.uu \ - libarchive/test/test_compat_lzip_2.tlz.uu \ - libarchive/test/test_compat_lzma_1.tlz.uu \ - libarchive/test/test_compat_lzma_2.tlz.uu \ - libarchive/test/test_compat_lzma_3.tlz.uu \ - libarchive/test/test_compat_lzop_1.tar.lzo.uu \ - libarchive/test/test_compat_lzop_2.tar.lzo.uu \ - libarchive/test/test_compat_lzop_3.tar.lzo.uu \ - libarchive/test/test_compat_mac-1.tar.Z.uu \ - libarchive/test/test_compat_mac-2.tar.Z.uu \ - libarchive/test/test_compat_perl_archive_tar.tar.uu \ - libarchive/test/test_compat_plexus_archiver_tar.tar.uu \ - libarchive/test/test_compat_solaris_pax_sparse_1.pax.Z.uu \ - libarchive/test/test_compat_solaris_pax_sparse_2.pax.Z.uu \ - libarchive/test/test_compat_solaris_tar_acl.tar.uu \ - libarchive/test/test_compat_star_acl_nfs4.tar.uu \ - libarchive/test/test_compat_star_acl_posix1e.tar.uu \ - libarchive/test/test_compat_tar_directory_1.tar.uu \ - libarchive/test/test_compat_tar_hardlink_1.tar.uu \ - libarchive/test/test_compat_uudecode_large.tar.Z.uu \ - libarchive/test/test_compat_xz_1.txz.uu \ - libarchive/test/test_compat_zip_1.zip.uu \ - libarchive/test/test_compat_zip_2.zip.uu \ - libarchive/test/test_compat_zip_3.zip.uu \ - libarchive/test/test_compat_zip_4.zip.uu \ - libarchive/test/test_compat_zip_5.zip.uu \ - libarchive/test/test_compat_zip_6.zip.uu \ - libarchive/test/test_compat_zip_7.xps.uu \ - libarchive/test/test_compat_zip_8.zip.uu \ - libarchive/test/test_compat_zstd_1.tar.zst.uu \ - libarchive/test/test_compat_zstd_2.tar.zst.uu \ - libarchive/test/test_fuzz.cab.uu \ - libarchive/test/test_fuzz.lzh.uu \ - libarchive/test/test_fuzz_1.iso.Z.uu \ - libarchive/test/test_pax_filename_encoding.tar.uu \ - libarchive/test/test_pax_xattr_header_all.tar.uu \ - libarchive/test/test_pax_xattr_header_libarchive.tar.uu \ - libarchive/test/test_pax_xattr_header_schily.tar.uu \ - libarchive/test/test_rar_multivolume_multiple_files.part1.rar.uu \ - libarchive/test/test_rar_multivolume_multiple_files.part2.rar.uu \ - libarchive/test/test_rar_multivolume_multiple_files.part3.rar.uu \ - libarchive/test/test_rar_multivolume_multiple_files.part4.rar.uu \ - libarchive/test/test_rar_multivolume_multiple_files.part5.rar.uu \ - libarchive/test/test_rar_multivolume_multiple_files.part6.rar.uu \ - libarchive/test/test_rar_multivolume_single_file.part1.rar.uu \ - libarchive/test/test_rar_multivolume_single_file.part2.rar.uu \ - libarchive/test/test_rar_multivolume_single_file.part3.rar.uu \ - libarchive/test/test_rar_multivolume_uncompressed_files.part01.rar.uu \ - libarchive/test/test_rar_multivolume_uncompressed_files.part02.rar.uu \ - libarchive/test/test_rar_multivolume_uncompressed_files.part03.rar.uu \ - libarchive/test/test_rar_multivolume_uncompressed_files.part04.rar.uu \ - libarchive/test/test_rar_multivolume_uncompressed_files.part05.rar.uu \ - libarchive/test/test_rar_multivolume_uncompressed_files.part06.rar.uu \ - libarchive/test/test_rar_multivolume_uncompressed_files.part07.rar.uu \ - libarchive/test/test_rar_multivolume_uncompressed_files.part08.rar.uu \ - libarchive/test/test_rar_multivolume_uncompressed_files.part09.rar.uu \ - libarchive/test/test_rar_multivolume_uncompressed_files.part10.rar.uu \ - libarchive/test/test_read_filter_grzip.tar.grz.uu \ - libarchive/test/test_read_filter_lrzip.tar.lrz.uu \ - libarchive/test/test_read_filter_lzop.tar.lzo.uu \ - libarchive/test/test_read_filter_lzop_multiple_parts.tar.lzo.uu \ - libarchive/test/test_read_filter_uudecode_raw.uu \ - libarchive/test/test_read_filter_uudecode_base64_raw.uu \ - libarchive/test/test_read_format_mtree_crash747.mtree.bz2.uu \ - libarchive/test/test_read_format_mtree_noprint.mtree.uu \ - libarchive/test/test_read_format_7zip_bcj2_bzip2.7z.uu \ - libarchive/test/test_read_format_7zip_bcj2_copy_1.7z.uu \ - libarchive/test/test_read_format_7zip_bcj2_copy_2.7z.uu \ - libarchive/test/test_read_format_7zip_bcj2_copy_lzma.7z.uu \ - libarchive/test/test_read_format_7zip_bcj2_deflate.7z.uu \ - libarchive/test/test_read_format_7zip_bcj2_lzma1_1.7z.uu \ - libarchive/test/test_read_format_7zip_bcj2_lzma1_2.7z.uu \ - libarchive/test/test_read_format_7zip_bcj2_lzma2_1.7z.uu \ - libarchive/test/test_read_format_7zip_bcj2_lzma2_2.7z.uu \ - libarchive/test/test_read_format_7zip_bcj_bzip2.7z.uu \ - libarchive/test/test_read_format_7zip_bcj_copy.7z.uu \ - libarchive/test/test_read_format_7zip_bcj_deflate.7z.uu \ - libarchive/test/test_read_format_7zip_bcj_lzma1.7z.uu \ - libarchive/test/test_read_format_7zip_bcj_lzma2.7z.uu \ - libarchive/test/test_read_format_7zip_bzip2.7z.uu \ - libarchive/test/test_read_format_7zip_copy.7z.uu \ - libarchive/test/test_read_format_7zip_copy_2.7z.uu \ - libarchive/test/test_read_format_7zip_deflate.7z.uu \ - libarchive/test/test_read_format_7zip_deflate_arm64.7z.uu \ - libarchive/test/test_read_format_7zip_delta_lzma1.7z.uu \ - libarchive/test/test_read_format_7zip_delta4_lzma1.7z.uu \ - libarchive/test/test_read_format_7zip_delta_lzma2.7z.uu \ - libarchive/test/test_read_format_7zip_delta4_lzma2.7z.uu \ - libarchive/test/test_read_format_7zip_empty_archive.7z.uu \ - libarchive/test/test_read_format_7zip_empty_file.7z.uu \ - libarchive/test/test_read_format_7zip_encryption.7z.uu \ - libarchive/test/test_read_format_7zip_encryption_header.7z.uu \ - libarchive/test/test_read_format_7zip_encryption_partially.7z.uu \ - libarchive/test/test_read_format_7zip_lzma1.7z.uu \ - libarchive/test/test_read_format_7zip_lzma1_2.7z.uu \ - libarchive/test/test_read_format_7zip_lzma1_lzma2.7z.uu \ - libarchive/test/test_read_format_7zip_lzma2.7z.uu \ - libarchive/test/test_read_format_7zip_lzma2_arm64.7z.uu \ - libarchive/test/test_read_format_7zip_lzma2_arm.7z.uu \ - libarchive/test/test_read_format_7zip_malformed.7z.uu \ - libarchive/test/test_read_format_7zip_malformed2.7z.uu \ - libarchive/test/test_read_format_7zip_packinfo_digests.7z.uu \ - libarchive/test/test_read_format_7zip_ppmd.7z.uu \ - libarchive/test/test_read_format_7zip_solid_zstd.7z.uu \ - libarchive/test/test_read_format_7zip_symbolic_name.7z.uu \ - libarchive/test/test_read_format_7zip_win_attrib.7z.uu \ - libarchive/test/test_read_format_7zip_zstd_arm.7z.uu \ - libarchive/test/test_read_format_7zip_zstd_bcj.7z.uu \ - libarchive/test/test_read_format_7zip_zstd_nobcj.7z.uu \ - libarchive/test/test_read_format_7zip_zstd.7z.uu \ - libarchive/test/test_read_format_ar.ar.uu \ - libarchive/test/test_read_format_cab_1.cab.uu \ - libarchive/test/test_read_format_cab_2.cab.uu \ - libarchive/test/test_read_format_cab_3.cab.uu \ - libarchive/test/test_read_format_cab_filename_cp932.cab.uu \ - libarchive/test/test_read_format_cpio_bin_be.cpio.uu \ - libarchive/test/test_read_format_cpio_bin_le.cpio.uu \ - libarchive/test/test_read_format_cpio_filename_cp866.cpio.uu \ - libarchive/test/test_read_format_cpio_filename_eucjp.cpio.uu \ - libarchive/test/test_read_format_cpio_filename_koi8r.cpio.uu \ - libarchive/test/test_read_format_cpio_filename_utf8_jp.cpio.uu \ - libarchive/test/test_read_format_cpio_filename_utf8_ru.cpio.uu \ - libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.rpm.uu \ - libarchive/test/test_read_format_cpio_svr4_gzip_rpm.rpm.uu \ - libarchive/test/test_read_format_gtar_filename_cp866.tar.Z.uu \ - libarchive/test/test_read_format_gtar_filename_eucjp.tar.Z.uu \ - libarchive/test/test_read_format_gtar_filename_koi8r.tar.Z.uu \ - libarchive/test/test_read_format_gtar_sparse_1_13.tar.uu \ - libarchive/test/test_read_format_gtar_sparse_1_17.tar.uu \ - libarchive/test/test_read_format_gtar_sparse_1_17_posix00.tar.uu \ - libarchive/test/test_read_format_gtar_sparse_1_17_posix01.tar.uu \ - libarchive/test/test_read_format_gtar_sparse_1_17_posix10.tar.uu \ - libarchive/test/test_read_format_gtar_sparse_1_17_posix10_modified.tar.uu \ - libarchive/test/test_read_format_gtar_sparse_skip_entry.tar.Z.uu \ - libarchive/test/test_read_format_iso.iso.Z.uu \ - libarchive/test/test_read_format_iso_2.iso.Z.uu \ - libarchive/test/test_read_format_iso_joliet.iso.Z.uu \ - libarchive/test/test_read_format_iso_joliet_by_nero.iso.Z.uu \ - libarchive/test/test_read_format_iso_joliet_long.iso.Z.uu \ - libarchive/test/test_read_format_iso_joliet_rockridge.iso.Z.uu \ - libarchive/test/test_read_format_iso_multi_extent.iso.Z.uu \ - libarchive/test/test_read_format_iso_rockridge.iso.Z.uu \ - libarchive/test/test_read_format_iso_rockridge_ce.iso.Z.uu \ - libarchive/test/test_read_format_iso_rockridge_new.iso.Z.uu \ - libarchive/test/test_read_format_iso_rockridge_rr_moved.iso.Z.uu \ - libarchive/test/test_read_format_iso_xorriso.iso.Z.uu \ - libarchive/test/test_read_format_iso_zisofs.iso.Z.uu \ - libarchive/test/test_read_format_lha_bugfix_0.lzh.uu \ - libarchive/test/test_read_format_lha_filename_cp932.lzh.uu \ - libarchive/test/test_read_format_lha_filename_utf16.lzh.uu \ - libarchive/test/test_read_format_lha_header0.lzh.uu \ - libarchive/test/test_read_format_lha_header1.lzh.uu \ - libarchive/test/test_read_format_lha_header2.lzh.uu \ - libarchive/test/test_read_format_lha_header3.lzh.uu \ - libarchive/test/test_read_format_lha_lh0.lzh.uu \ - libarchive/test/test_read_format_lha_lh6.lzh.uu \ - libarchive/test/test_read_format_lha_lh7.lzh.uu \ - libarchive/test/test_read_format_lha_withjunk.lzh.uu \ - libarchive/test/test_read_format_mtree.mtree.uu \ - libarchive/test/test_read_format_mtree_nomagic.mtree.uu \ - libarchive/test/test_read_format_mtree_nomagic2.mtree.uu \ - libarchive/test/test_read_format_mtree_nomagic3.mtree.uu \ - libarchive/test/test_read_format_rar.rar.uu \ - libarchive/test/test_read_format_rar_binary_data.rar.uu \ - libarchive/test/test_read_format_rar_compress_best.rar.uu \ - libarchive/test/test_read_format_rar_compress_normal.rar.uu \ - libarchive/test/test_read_format_rar_encryption_data.rar.uu \ - libarchive/test/test_read_format_rar_encryption_header.rar.uu \ - libarchive/test/test_read_format_rar_encryption_partially.rar.uu \ - libarchive/test/test_read_format_rar_filter.rar.uu \ - libarchive/test/test_read_format_rar_invalid1.rar.uu \ - libarchive/test/test_read_format_rar_multi_lzss_blocks.rar.uu \ - libarchive/test/test_read_format_rar_multivolume.part0001.rar.uu \ - libarchive/test/test_read_format_rar_multivolume.part0002.rar.uu \ - libarchive/test/test_read_format_rar_multivolume.part0003.rar.uu \ - libarchive/test/test_read_format_rar_multivolume.part0004.rar.uu \ - libarchive/test/test_read_format_rar_noeof.rar.uu \ - libarchive/test/test_read_format_rar_ppmd_lzss_conversion.rar.uu \ - libarchive/test/test_read_format_rar_ppmd_use_after_free.rar.uu \ - libarchive/test/test_read_format_rar_ppmd_use_after_free2.rar.uu \ - libarchive/test/test_read_format_rar_sfx.exe.uu \ - libarchive/test/test_read_format_rar_subblock.rar.uu \ - libarchive/test/test_read_format_rar_unicode.rar.uu \ - libarchive/test/test_read_format_rar_windows.rar.uu \ - libarchive/test/test_read_format_rar5_arm.rar.uu \ - libarchive/test/test_read_format_rar5_blake2.rar.uu \ - libarchive/test/test_read_format_rar5_compressed.rar.uu \ - libarchive/test/test_read_format_rar5_different_window_size.rar.uu \ - libarchive/test/test_read_format_rar5_different_solid_window_size.rar.uu \ - libarchive/test/test_read_format_rar5_distance_overflow.rar.uu \ - libarchive/test/test_read_format_rar5_extra_field_version.rar.uu \ - libarchive/test/test_read_format_rar5_fileattr.rar.uu \ - libarchive/test/test_read_format_rar5_hardlink.rar.uu \ - libarchive/test/test_read_format_rar5_invalid_dict_reference.rar.uu \ - libarchive/test/test_read_format_rar5_leftshift1.rar.uu \ - libarchive/test/test_read_format_rar5_leftshift2.rar.uu \ - libarchive/test/test_read_format_rar5_multiarchive.part01.rar.uu \ - libarchive/test/test_read_format_rar5_multiarchive.part02.rar.uu \ - libarchive/test/test_read_format_rar5_multiarchive.part03.rar.uu \ - libarchive/test/test_read_format_rar5_multiarchive.part04.rar.uu \ - libarchive/test/test_read_format_rar5_multiarchive.part05.rar.uu \ - libarchive/test/test_read_format_rar5_multiarchive.part06.rar.uu \ - libarchive/test/test_read_format_rar5_multiarchive.part07.rar.uu \ - libarchive/test/test_read_format_rar5_multiarchive.part08.rar.uu \ - libarchive/test/test_read_format_rar5_multiarchive_solid.part01.rar.uu \ - libarchive/test/test_read_format_rar5_multiarchive_solid.part02.rar.uu \ - libarchive/test/test_read_format_rar5_multiarchive_solid.part03.rar.uu \ - libarchive/test/test_read_format_rar5_multiarchive_solid.part04.rar.uu \ - libarchive/test/test_read_format_rar5_multiple_files.rar.uu \ - libarchive/test/test_read_format_rar5_multiple_files_solid.rar.uu \ - libarchive/test/test_read_format_rar5_nonempty_dir_stream.rar.uu \ - libarchive/test/test_read_format_rar5_owner.rar.uu \ - libarchive/test/test_read_format_rar5_readtables_overflow.rar.uu \ - libarchive/test/test_read_format_rar5_sfx.exe.uu \ - libarchive/test/test_read_format_rar5_solid.rar.uu \ - libarchive/test/test_read_format_rar5_stored.rar.uu \ - libarchive/test/test_read_format_rar5_stored_manyfiles.rar.uu \ - libarchive/test/test_read_format_rar5_symlink.rar.uu \ - libarchive/test/test_read_format_rar5_truncated_huff.rar.uu \ - libarchive/test/test_read_format_rar5_win32.rar.uu \ - libarchive/test/test_read_format_rar5_arm_filter_on_window_boundary.rar.uu \ - libarchive/test/test_read_format_rar5_different_winsize_on_merge.rar.uu \ - libarchive/test/test_read_format_rar5_block_size_is_too_small.rar.uu \ - libarchive/test/test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu \ - libarchive/test/test_read_format_rar5_window_buf_and_size_desync.rar.uu \ - libarchive/test/test_read_format_rar5_bad_window_sz_in_mltarc_file.rar.uu \ - libarchive/test/test_read_format_raw.bufr.uu \ - libarchive/test/test_read_format_raw.data.gz.uu \ - libarchive/test/test_read_format_raw.data.Z.uu \ - libarchive/test/test_read_format_raw.data.uu \ - libarchive/test/test_read_format_tar_concatenated.tar.uu \ - libarchive/test/test_read_format_tar_empty_filename.tar.uu \ - libarchive/test/test_read_format_tar_empty_with_gnulabel.tar.uu \ - libarchive/test/test_read_format_tar_empty_pax.tar.Z.uu \ - libarchive/test/test_read_format_tar_filename_koi8r.tar.Z.uu \ - libarchive/test/test_read_format_tar_invalid_pax_size.tar.uu \ - libarchive/test/test_read_format_ustar_filename_cp866.tar.Z.uu \ - libarchive/test/test_read_format_ustar_filename_eucjp.tar.Z.uu \ - libarchive/test/test_read_format_ustar_filename_koi8r.tar.Z.uu \ - libarchive/test/test_read_format_warc.warc.uu \ - libarchive/test/test_read_format_zip.zip.uu \ - libarchive/test/test_read_format_zip_7075_utf8_paths.zip.uu \ - libarchive/test/test_read_format_zip_7z_deflate.zip.uu \ - libarchive/test/test_read_format_zip_7z_lzma.zip.uu \ - libarchive/test/test_read_format_zip_bz2_hang.zip.uu \ - libarchive/test/test_read_format_zip_bzip2.zipx.uu \ - libarchive/test/test_read_format_zip_bzip2_multi.zipx.uu \ - libarchive/test/test_read_format_zip_comment_stored_1.zip.uu \ - libarchive/test/test_read_format_zip_comment_stored_2.zip.uu \ - libarchive/test/test_read_format_zip_encryption_data.zip.uu \ - libarchive/test/test_read_format_zip_encryption_header.zip.uu \ - libarchive/test/test_read_format_zip_encryption_partially.zip.uu \ - libarchive/test/test_read_format_zip_extra_padding.zip.uu \ - libarchive/test/test_read_format_zip_filename_cp866.zip.uu \ - libarchive/test/test_read_format_zip_filename_cp932.zip.uu \ - libarchive/test/test_read_format_zip_filename_koi8r.zip.uu \ - libarchive/test/test_read_format_zip_filename_utf8_jp.zip.uu \ - libarchive/test/test_read_format_zip_filename_utf8_ru.zip.uu \ - libarchive/test/test_read_format_zip_filename_utf8_ru2.zip.uu \ - libarchive/test/test_read_format_zip_high_compression.zip.uu \ - libarchive/test/test_read_format_zip_length_at_end.zip.uu \ - libarchive/test/test_read_format_zip_lzma.zipx.uu \ - libarchive/test/test_read_format_zip_lzma_alone_leak.zipx.uu \ - libarchive/test/test_read_format_zip_lzma_multi.zipx.uu \ - libarchive/test/test_read_format_zip_lzma_stream_end.zipx.uu \ - libarchive/test/test_read_format_zip_jar.jar.uu \ - libarchive/test/test_read_format_zip_mac_metadata.zip.uu \ - libarchive/test/test_read_format_zip_malformed1.zip.uu \ - libarchive/test/test_read_format_zip_msdos.zip.uu \ - libarchive/test/test_read_format_zip_nested.zip.uu \ - libarchive/test/test_read_format_zip_nofiletype.zip.uu \ - libarchive/test/test_read_format_zip_padded1.zip.uu \ - libarchive/test/test_read_format_zip_padded2.zip.uu \ - libarchive/test/test_read_format_zip_padded3.zip.uu \ - libarchive/test/test_read_format_zip_ppmd8.zipx.uu \ - libarchive/test/test_read_format_zip_ppmd8_crash_1.zipx.uu \ - libarchive/test/test_read_format_zip_ppmd8_crash_2.zipx.uu \ - libarchive/test/test_read_format_zip_ppmd8_multi.zipx.uu \ - libarchive/test/test_read_format_zip_sfx.uu \ - libarchive/test/test_read_format_zip_symlink.zip.uu \ - libarchive/test/test_read_format_zip_traditional_encryption_data.zip.uu \ - libarchive/test/test_read_format_zip_ux.zip.uu \ - libarchive/test/test_read_format_zip_winzip_aes128.zip.uu \ - libarchive/test/test_read_format_zip_winzip_aes256.zip.uu \ - libarchive/test/test_read_format_zip_winzip_aes256_large.zip.uu \ - libarchive/test/test_read_format_zip_winzip_aes256_stored.zip.uu \ - libarchive/test/test_read_format_zip_with_invalid_traditional_eocd.zip.uu \ - libarchive/test/test_read_format_zip_xz_multi.zipx.uu \ - libarchive/test/test_read_format_zip_zip64a.zip.uu \ - libarchive/test/test_read_format_zip_zip64b.zip.uu \ - libarchive/test/test_read_format_zip_zstd.zipx.uu \ - libarchive/test/test_read_format_zip_zstd_multi.zipx.uu \ - libarchive/test/test_read_large_splitted_rar_aa.uu \ - libarchive/test/test_read_large_splitted_rar_ab.uu \ - libarchive/test/test_read_large_splitted_rar_ac.uu \ - libarchive/test/test_read_large_splitted_rar_ad.uu \ - libarchive/test/test_read_large_splitted_rar_ae.uu \ - libarchive/test/test_read_pax_xattr_rht_security_selinux.tar.uu \ - libarchive/test/test_read_pax_xattr_schily.tar.uu \ - libarchive/test/test_read_splitted_rar_aa.uu \ - libarchive/test/test_read_splitted_rar_ab.uu \ - libarchive/test/test_read_splitted_rar_ac.uu \ - libarchive/test/test_read_splitted_rar_ad.uu \ - libarchive/test/test_read_too_many_filters.gz.uu \ - libarchive/test/test_splitted_rar_seek_support_aa.uu \ - libarchive/test/test_splitted_rar_seek_support_ab.uu \ - libarchive/test/test_splitted_rar_seek_support_ac.uu \ - libarchive/test/test_write_disk_appledouble.cpio.gz.uu \ - libarchive/test/test_write_disk_hfs_compression.tgz.uu \ - libarchive/test/test_write_disk_mac_metadata.tar.gz.uu \ - libarchive/test/test_write_disk_no_hfs_compression.tgz.uu \ - libarchive/test/CMakeLists.txt \ - libarchive/test/README - -# -# Common code for libarchive frontends (cpio, tar) -# -libarchive_fe_la_SOURCES= \ - libarchive_fe/err.c \ - libarchive_fe/err.h \ - libarchive_fe/lafe_platform.h \ - libarchive_fe/line_reader.c \ - libarchive_fe/line_reader.h \ - libarchive_fe/passphrase.c \ - libarchive_fe/passphrase.h - -libarchive_fe_la_CPPFLAGS= -I$(top_srcdir)/libarchive -# -# -# bsdtar source, docs, etc. -# -# - -bsdtar_SOURCES= \ - tar/bsdtar.c \ - tar/bsdtar.h \ - tar/bsdtar_platform.h \ - tar/cmdline.c \ - tar/creation_set.c \ - tar/read.c \ - tar/subst.c \ - tar/util.c \ - tar/write.c - -if INC_WINDOWS_FILES -bsdtar_SOURCES+= \ - tar/bsdtar_windows.h \ - tar/bsdtar_windows.c -endif - -bsdtar_DEPENDENCIES= libarchive.la libarchive_fe.la - -if STATIC_BSDTAR -bsdtar_ldstatic= -static -bsdtar_ccstatic= -DLIBARCHIVE_STATIC -else -bsdtar_ldstatic= -bsdtar_ccstatic= -endif - -bsdtar_LDADD= libarchive.la libarchive_fe.la $(LTLIBICONV) -bsdtar_CPPFLAGS= -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe $(bsdtar_ccstatic) $(PLATFORMCPPFLAGS) -bsdtar_LDFLAGS= $(bsdtar_ldstatic) $(GC_SECTIONS) - -bsdtar_EXTRA_DIST= \ - tar/bsdtar.1 \ - tar/bsdtar_windows.h \ - tar/bsdtar_windows.c \ - tar/CMakeLists.txt \ - tar/config_freebsd.h - - -if BUILD_BSDTAR -bsdtar_man_MANS= tar/bsdtar.1 -bsdtar_programs= bsdtar -else -bsdtar_man_MANS= -bsdtar_programs= -endif - -# -# bsdtar_test -# - -bsdtar_test_SOURCES= \ - $(test_utils_SOURCES) \ - tar/test/test.h \ - tar/test/test_0.c \ - tar/test/test_basic.c \ - tar/test/test_copy.c \ - tar/test/test_empty_mtree.c \ - tar/test/test_extract_tar_Z.c \ - tar/test/test_extract_tar_bz2.c \ - tar/test/test_extract_tar_grz.c \ - tar/test/test_extract_tar_gz.c \ - tar/test/test_extract_tar_lrz.c \ - tar/test/test_extract_tar_lz.c \ - tar/test/test_extract_tar_lz4.c \ - tar/test/test_extract_tar_lzma.c \ - tar/test/test_extract_tar_lzo.c \ - tar/test/test_extract_tar_xz.c \ - tar/test/test_extract_tar_zstd.c \ - tar/test/test_format_newc.c \ - tar/test/test_help.c \ - tar/test/test_leading_slash.c \ - tar/test/test_missing_file.c \ - tar/test/test_option_C_mtree.c \ - tar/test/test_option_C_upper.c \ - tar/test/test_option_H_upper.c \ - tar/test/test_option_L_upper.c \ - tar/test/test_option_O_upper.c \ - tar/test/test_option_T_upper.c \ - tar/test/test_option_U_upper.c \ - tar/test/test_option_X_upper.c \ - tar/test/test_option_acls.c \ - tar/test/test_option_a.c \ - tar/test/test_option_b.c \ - tar/test/test_option_b64encode.c \ - tar/test/test_option_exclude.c \ - tar/test/test_option_exclude_vcs.c \ - tar/test/test_option_fflags.c \ - tar/test/test_option_gid_gname.c \ - tar/test/test_option_grzip.c \ - tar/test/test_option_ignore_zeros.c \ - tar/test/test_option_j.c \ - tar/test/test_option_k.c \ - tar/test/test_option_keep_newer_files.c \ - tar/test/test_option_lrzip.c \ - tar/test/test_option_lz4.c \ - tar/test/test_option_lzma.c \ - tar/test/test_option_lzop.c \ - tar/test/test_option_n.c \ - tar/test/test_option_newer_than.c \ - tar/test/test_option_nodump.c \ - tar/test/test_option_older_than.c \ - tar/test/test_option_passphrase.c \ - tar/test/test_option_q.c \ - tar/test/test_option_r.c \ - tar/test/test_option_s.c \ - tar/test/test_option_safe_writes.c \ - tar/test/test_option_uid_uname.c \ - tar/test/test_option_uuencode.c \ - tar/test/test_option_xattrs.c \ - tar/test/test_option_xz.c \ - tar/test/test_option_z.c \ - tar/test/test_option_zstd.c \ - tar/test/test_patterns.c \ - tar/test/test_print_longpath.c \ - tar/test/test_stdio.c \ - tar/test/test_strip_components.c \ - tar/test/test_symlink_dir.c \ - tar/test/test_version.c \ - tar/test/test_windows.c - -bsdtar_test_CPPFLAGS=\ - -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe \ - -I$(top_srcdir)/test_utils \ - -I$(top_srcdir)/tar -I$(top_srcdir)/tar/test \ - -I$(top_builddir)/tar/test \ - $(PLATFORMCPPFLAGS) - -tar/test/list.h: Makefile - $(MKDIR_P) tar/test - cat $(top_srcdir)/tar/test/test_*.c | grep '^DEFINE_TEST' > tar/test/list.h - -if BUILD_BSDTAR -bsdtar_test_programs= bsdtar_test -bsdtar_TESTS_ENVIRONMENT= BSDTAR=`cd $(top_builddir);/bin/pwd`/bsdtar$(EXEEXT) BSDTAR_TEST_FILES=`cd $(top_srcdir);/bin/pwd`/tar/test -else -bsdtar_test_programs= -bsdtar_TESTS_ENVIRONMENT= -endif - -bsdtar_test_EXTRA_DIST= \ - tar/test/list.h \ - tar/test/test_extract.tar.Z.uu \ - tar/test/test_extract.tar.bz2.uu \ - tar/test/test_extract.tar.grz.uu \ - tar/test/test_extract.tar.gz.uu \ - tar/test/test_extract.tar.lrz.uu \ - tar/test/test_extract.tar.lz.uu \ - tar/test/test_extract.tar.lz4.uu \ - tar/test/test_extract.tar.zst.uu \ - tar/test/test_extract.tar.lzma.uu \ - tar/test/test_extract.tar.lzo.uu \ - tar/test/test_extract.tar.xz.uu \ - tar/test/test_leading_slash.tar.uu \ - tar/test/test_option_keep_newer_files.tar.Z.uu \ - tar/test/test_option_passphrase.zip.uu \ - tar/test/test_option_s.tar.Z.uu \ - tar/test/test_patterns_2.tar.uu \ - tar/test/test_patterns_3.tar.uu \ - tar/test/test_patterns_4.tar.uu \ - tar/test/test_print_longpath.tar.Z.uu \ - tar/test/CMakeLists.txt - - -# -# -# bsdcpio source, docs, etc. -# -# - -bsdcpio_SOURCES= \ - cpio/cmdline.c \ - cpio/cpio.c \ - cpio/cpio.h \ - cpio/cpio_platform.h - -if INC_WINDOWS_FILES -bsdcpio_SOURCES+= \ - cpio/cpio_windows.h \ - cpio/cpio_windows.c -endif - -bsdcpio_DEPENDENCIES = libarchive.la libarchive_fe.la - - -if STATIC_BSDCPIO -bsdcpio_ldstatic= -static -bsdcpio_ccstatic= -DLIBARCHIVE_STATIC -else -bsdcpio_ldstatic= -bsdcpio_ccstatic= -endif - -bsdcpio_LDADD= libarchive_fe.la libarchive.la $(LTLIBICONV) -bsdcpio_CPPFLAGS= -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe $(bsdcpio_ccstatic) $(PLATFORMCPPFLAGS) -bsdcpio_LDFLAGS= $(bsdcpio_ldstatic) $(GC_SECTIONS) - -bsdcpio_EXTRA_DIST= \ - cpio/bsdcpio.1 \ - cpio/cpio_windows.h \ - cpio/cpio_windows.c \ - cpio/CMakeLists.txt \ - cpio/config_freebsd.h - - -if BUILD_BSDCPIO -# Manpages to install -bsdcpio_man_MANS= cpio/bsdcpio.1 -bsdcpio_programs= bsdcpio -else -bsdcpio_man_MANS= -bsdcpio_programs= -endif - -# -# bsdcpio_test -# - -bsdcpio_test_SOURCES= \ - $(test_utils_SOURCES) \ - cpio/cmdline.c \ - cpio/test/test.h \ - cpio/test/test_0.c \ - cpio/test/test_basic.c \ - cpio/test/test_cmdline.c \ - cpio/test/test_extract_cpio_Z.c \ - cpio/test/test_extract_cpio_bz2.c \ - cpio/test/test_extract_cpio_grz.c \ - cpio/test/test_extract_cpio_gz.c \ - cpio/test/test_extract_cpio_lrz.c \ - cpio/test/test_extract_cpio_lz.c \ - cpio/test/test_extract_cpio_lz4.c \ - cpio/test/test_extract_cpio_lzma.c \ - cpio/test/test_extract_cpio_lzo.c \ - cpio/test/test_extract_cpio_xz.c \ - cpio/test/test_extract_cpio_zstd.c \ - cpio/test/test_format_newc.c \ - cpio/test/test_gcpio_compat.c \ - cpio/test/test_missing_file.c \ - cpio/test/test_option_0.c \ - cpio/test/test_option_B_upper.c \ - cpio/test/test_option_C_upper.c \ - cpio/test/test_option_J_upper.c \ - cpio/test/test_option_L_upper.c \ - cpio/test/test_option_Z_upper.c \ - cpio/test/test_option_a.c \ - cpio/test/test_option_b64encode.c \ - cpio/test/test_option_c.c \ - cpio/test/test_option_d.c \ - cpio/test/test_option_f.c \ - cpio/test/test_option_grzip.c \ - cpio/test/test_option_help.c \ - cpio/test/test_option_l.c \ - cpio/test/test_option_lrzip.c \ - cpio/test/test_option_lz4.c \ - cpio/test/test_option_lzma.c \ - cpio/test/test_option_lzop.c \ - cpio/test/test_option_m.c \ - cpio/test/test_option_passphrase.c \ - cpio/test/test_option_t.c \ - cpio/test/test_option_u.c \ - cpio/test/test_option_uuencode.c \ - cpio/test/test_option_version.c \ - cpio/test/test_option_xz.c \ - cpio/test/test_option_y.c \ - cpio/test/test_option_z.c \ - cpio/test/test_option_zstd.c \ - cpio/test/test_owner_parse.c \ - cpio/test/test_passthrough_dotdot.c \ - cpio/test/test_passthrough_reverse.c - -bsdcpio_test_CPPFLAGS= \ - -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe \ - -I$(top_srcdir)/test_utils \ - -I$(top_srcdir)/cpio -I$(top_srcdir)/cpio/test \ - -I$(top_builddir)/cpio/test \ - $(PLATFORMCPPFLAGS) -bsdcpio_test_LDADD=libarchive_fe.la - -cpio/test/list.h: Makefile - $(MKDIR_P) cpio/test - cat $(top_srcdir)/cpio/test/test_*.c | grep '^DEFINE_TEST' > cpio/test/list.h - -if BUILD_BSDCPIO -bsdcpio_test_programs= bsdcpio_test -bsdcpio_TESTS_ENVIRONMENT= BSDCPIO=`cd $(top_builddir);/bin/pwd`/bsdcpio$(EXEEXT) BSDCPIO_TEST_FILES=`cd $(top_srcdir);/bin/pwd`/cpio/test -else -bsdcpio_test_programs= -bsdcpio_TESTS_ENVIRONMENT= -endif - -bsdcpio_test_EXTRA_DIST= \ - cpio/test/list.h \ - cpio/test/test_extract.cpio.Z.uu \ - cpio/test/test_extract.cpio.bz2.uu \ - cpio/test/test_extract.cpio.grz.uu \ - cpio/test/test_extract.cpio.gz.uu \ - cpio/test/test_extract.cpio.lrz.uu \ - cpio/test/test_extract.cpio.lz.uu \ - cpio/test/test_extract.cpio.lz4.uu \ - cpio/test/test_extract.cpio.zst.uu \ - cpio/test/test_extract.cpio.lzma.uu \ - cpio/test/test_extract.cpio.lzo.uu \ - cpio/test/test_extract.cpio.xz.uu \ - cpio/test/test_gcpio_compat_ref.bin.uu \ - cpio/test/test_gcpio_compat_ref.crc.uu \ - cpio/test/test_gcpio_compat_ref.newc.uu \ - cpio/test/test_gcpio_compat_ref.ustar.uu \ - cpio/test/test_gcpio_compat_ref_nosym.bin.uu \ - cpio/test/test_gcpio_compat_ref_nosym.crc.uu \ - cpio/test/test_gcpio_compat_ref_nosym.newc.uu \ - cpio/test/test_gcpio_compat_ref_nosym.ustar.uu \ - cpio/test/test_option_f.cpio.uu \ - cpio/test/test_option_m.cpio.uu \ - cpio/test/test_option_passphrase.zip.uu \ - cpio/test/test_option_t.cpio.uu \ - cpio/test/test_option_t.stdout.uu \ - cpio/test/test_option_tv.stdout.uu \ - cpio/test/CMakeLists.txt - -# -# -# bsdcat source, docs, etc. -# -# - -bsdcat_SOURCES= \ - cat/bsdcat.c \ - cat/bsdcat.h \ - cat/bsdcat_platform.h \ - cat/cmdline.c - -if INC_WINDOWS_FILES -bsdcat_SOURCES+= -endif - -bsdcat_DEPENDENCIES = libarchive.la libarchive_fe.la - - -if STATIC_BSDCAT -bsdcat_ldstatic= -static -bsdcat_ccstatic= -DLIBARCHIVE_STATIC -else -bsdcat_ldstatic= -bsdcat_ccstatic= -endif - -bsdcat_LDADD= libarchive_fe.la libarchive.la $(LTLIBICONV) -bsdcat_CPPFLAGS= -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe $(bsdcat_ccstatic) $(PLATFORMCPPFLAGS) -bsdcat_LDFLAGS= $(bsdcat_ldstatic) $(GC_SECTIONS) - -bsdcat_EXTRA_DIST= \ - cat/bsdcat.1 \ - cat/CMakeLists.txt - - -if BUILD_BSDCAT -# Manpages to install -bsdcat_man_MANS= cat/bsdcat.1 -bsdcat_programs= bsdcat -else -bsdcat_man_MANS= -bsdcat_programs= -endif - -# -# bsdcat_test -# - -bsdcat_test_SOURCES= \ - $(test_utils_SOURCES) \ - cat/test/test.h \ - cat/test/test_0.c \ - cat/test/test_empty_gz.c \ - cat/test/test_empty_lz4.c \ - cat/test/test_empty_xz.c \ - cat/test/test_empty_zstd.c \ - cat/test/test_error.c \ - cat/test/test_error_mixed.c \ - cat/test/test_expand_Z.c \ - cat/test/test_expand_bz2.c \ - cat/test/test_expand_gz.c \ - cat/test/test_expand_lz4.c \ - cat/test/test_expand_mixed.c \ - cat/test/test_expand_plain.c \ - cat/test/test_expand_xz.c \ - cat/test/test_expand_zstd.c \ - cat/test/test_help.c \ - cat/test/test_stdin.c \ - cat/test/test_version.c - -bsdcat_test_CPPFLAGS= \ - -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe \ - -I$(top_srcdir)/test_utils \ - -I$(top_srcdir)/cat -I$(top_srcdir)/cat/test \ - -I$(top_builddir)/cat/test \ - $(PLATFORMCPPFLAGS) -bsdcat_test_LDADD=libarchive_fe.la - -cat/test/list.h: Makefile - $(MKDIR_P) cat/test - cat $(top_srcdir)/cat/test/test_*.c | grep '^DEFINE_TEST' > cat/test/list.h - -if BUILD_BSDCAT -bsdcat_test_programs= bsdcat_test -bsdcat_TESTS_ENVIRONMENT= BSDCAT=`cd $(top_builddir);/bin/pwd`/bsdcat$(EXEEXT) BSDCAT_TEST_FILES=`cd $(top_srcdir);/bin/pwd`/cat/test -else -bsdcat_test_programs= -bsdcat_TESTS_ENVIRONMENT= -endif - -bsdcat_test_EXTRA_DIST= \ - cat/test/list.h \ - cat/test/test_empty.gz.uu \ - cat/test/test_empty.lz4.uu \ - cat/test/test_empty.zst.uu \ - cat/test/test_empty.xz.uu \ - cat/test/test_expand.Z.uu \ - cat/test/test_expand.bz2.uu \ - cat/test/test_expand.gz.uu \ - cat/test/test_expand.lz4.uu \ - cat/test/test_expand.zst.uu \ - cat/test/test_expand.plain.uu \ - cat/test/test_expand.xz.uu \ - cat/test/CMakeLists.txt - -# -# -# bsdunzip source, docs, etc. -# -# - -bsdunzip_SOURCES= \ - unzip/bsdunzip.c \ - unzip/bsdunzip.h \ - unzip/bsdunzip_platform.h \ - unzip/cmdline.c \ - unzip/la_getline.c \ - unzip/la_queue.h - -if INC_WINDOWS_FILES -bsdunzip_SOURCES+= -endif - -bsdunzip_DEPENDENCIES = libarchive.la libarchive_fe.la - - -if STATIC_BSDUNZIP -bsdunzip_ldstatic= -static -bsdunzip_ccstatic= -DLIBARCHIVE_STATIC -else -bsdunzip_ldstatic= -bsdunzip_ccstatic= -endif - -bsdunzip_LDADD= libarchive_fe.la libarchive.la $(LTLIBICONV) -bsdunzip_CPPFLAGS= -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe $(bsdunzip_ccstatic) $(PLATFORMCPPFLAGS) -bsdunzip_LDFLAGS= $(bsdunzip_ldstatic) $(GC_SECTIONS) - -bsdunzip_EXTRA_DIST= \ - unzip/bsdunzip.1 \ - unzip/CMakeLists.txt - - -if BUILD_BSDUNZIP -# Manpages to install -bsdunzip_man_MANS= unzip/bsdunzip.1 -bsdunzip_programs= bsdunzip -else -bsdunzip_man_MANS= -bsdunzip_programs= -endif - -# -# bsdunzip_test -# - -bsdunzip_test_SOURCES= \ - $(test_utils_SOURCES) \ - unzip/test/test.h \ - unzip/test/test_0.c \ - unzip/test/test_basic.c \ - unzip/test/test_glob.c \ - unzip/test/test_not_exist.c \ - unzip/test/test_singlefile.c \ - unzip/test/test_C.c \ - unzip/test/test_p.c \ - unzip/test/test_d.c \ - unzip/test/test_j.c \ - unzip/test/test_L.c \ - unzip/test/test_n.c \ - unzip/test/test_o.c \ - unzip/test/test_q.c \ - unzip/test/test_t.c \ - unzip/test/test_t_bad.c \ - unzip/test/test_version.c \ - unzip/test/test_x.c \ - unzip/test/test_Z1.c \ - unzip/test/test_P_encryption.c - -bsdunzip_test_CPPFLAGS= \ - -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe \ - -I$(top_srcdir)/test_utils \ - -I$(top_srcdir)/unzip -I$(top_srcdir)/unzip/test \ - -I$(top_builddir)/unzip/test \ - $(PLATFORMCPPFLAGS) -bsdunzip_test_LDADD=libarchive_fe.la - -unzip/test/list.h: Makefile - $(MKDIR_P) unzip/test - cat $(top_srcdir)/unzip/test/test_*.c | grep '^DEFINE_TEST' > unzip/test/list.h - -if BUILD_BSDUNZIP -bsdunzip_test_programs= bsdunzip_test -bsdunzip_TESTS_ENVIRONMENT= BSDUNZIP=`cd $(top_builddir);/bin/pwd`/bsdunzip$(EXEEXT) BSDUNZIP_TEST_FILES=`cd $(top_srcdir);/bin/pwd`/unzip/test -else -bsdunzip_test_programs= -bsdunzip_TESTS_ENVIRONMENT= -endif - -bsdunzip_test_EXTRA_DIST= \ - unzip/test/list.h \ - unzip/test/test_basic.zip.uu \ - unzip/test/test_encrypted.zip.uu \ - unzip/test/test_singlefile.zip.uu \ - unzip/test/test_t_bad.zip.uu \ - unzip/test/CMakeLists.txt diff --git a/thirdparty/libarchive/Makefile.in b/thirdparty/libarchive/Makefile.in deleted file mode 100644 index a7d376f56..000000000 --- a/thirdparty/libarchive/Makefile.in +++ /dev/null @@ -1,17572 +0,0 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2021 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - - - - -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -bin_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ - $(am__EXEEXT_4) -check_PROGRAMS = libarchive_test$(EXEEXT) $(am__EXEEXT_5) \ - $(am__EXEEXT_6) $(am__EXEEXT_7) $(am__EXEEXT_8) -TESTS = libarchive_test$(EXEEXT) $(am__EXEEXT_5) $(am__EXEEXT_6) \ - $(am__EXEEXT_7) $(am__EXEEXT_8) -@INC_WINDOWS_FILES_TRUE@am__append_1 = \ -@INC_WINDOWS_FILES_TRUE@ libarchive/archive_entry_copy_bhfi.c \ -@INC_WINDOWS_FILES_TRUE@ libarchive/archive_read_disk_windows.c \ -@INC_WINDOWS_FILES_TRUE@ libarchive/archive_windows.h \ -@INC_WINDOWS_FILES_TRUE@ libarchive/archive_windows.c \ -@INC_WINDOWS_FILES_TRUE@ libarchive/archive_write_disk_windows.c \ -@INC_WINDOWS_FILES_TRUE@ libarchive/filter_fork_windows.c - -@INC_BLAKE2_TRUE@am__append_2 = \ -@INC_BLAKE2_TRUE@ libarchive/archive_blake2.h \ -@INC_BLAKE2_TRUE@ libarchive/archive_blake2_impl.h \ -@INC_BLAKE2_TRUE@ libarchive/archive_blake2s_ref.c \ -@INC_BLAKE2_TRUE@ libarchive/archive_blake2sp_ref.c - -@INC_LINUX_ACL_TRUE@am__append_3 = libarchive/archive_disk_acl_linux.c -@INC_LINUX_ACL_FALSE@@INC_SUNOS_ACL_TRUE@am__append_4 = libarchive/archive_disk_acl_sunos.c -@INC_DARWIN_ACL_TRUE@@INC_LINUX_ACL_FALSE@@INC_SUNOS_ACL_FALSE@am__append_5 = libarchive/archive_disk_acl_darwin.c -@INC_DARWIN_ACL_FALSE@@INC_FREEBSD_ACL_TRUE@@INC_LINUX_ACL_FALSE@@INC_SUNOS_ACL_FALSE@am__append_6 = libarchive/archive_disk_acl_freebsd.c -@INC_WINDOWS_FILES_TRUE@am__append_7 = \ -@INC_WINDOWS_FILES_TRUE@ tar/bsdtar_windows.h \ -@INC_WINDOWS_FILES_TRUE@ tar/bsdtar_windows.c - -@INC_WINDOWS_FILES_TRUE@am__append_8 = \ -@INC_WINDOWS_FILES_TRUE@ cpio/cpio_windows.h \ -@INC_WINDOWS_FILES_TRUE@ cpio/cpio_windows.c - -@INC_WINDOWS_FILES_TRUE@am__append_9 = -@INC_WINDOWS_FILES_TRUE@am__append_10 = -subdir = . -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = \ - $(top_srcdir)/build/autoconf/ax_append_compile_flags.m4 \ - $(top_srcdir)/build/autoconf/ax_append_flag.m4 \ - $(top_srcdir)/build/autoconf/ax_check_compile_flag.m4 \ - $(top_srcdir)/build/autoconf/ax_require_defined.m4 \ - $(top_srcdir)/build/autoconf/check_stdcall_func.m4 \ - $(top_srcdir)/build/autoconf/iconv.m4 \ - $(top_srcdir)/build/autoconf/la_uid_t.m4 \ - $(top_srcdir)/build/autoconf/lib-ld.m4 \ - $(top_srcdir)/build/autoconf/lib-link.m4 \ - $(top_srcdir)/build/autoconf/lib-prefix.m4 \ - $(top_srcdir)/build/autoconf/m4_ax_compile_check_sizeof.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ - $(am__configure_deps) $(include_HEADERS) $(am__DIST_COMMON) -am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ - configure.lineno config.status.lineno -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = config.h -CONFIG_CLEAN_FILES = build/pkgconfig/libarchive.pc -CONFIG_CLEAN_VPATH_FILES = -@BUILD_BSDTAR_TRUE@am__EXEEXT_1 = bsdtar$(EXEEXT) -@BUILD_BSDCPIO_TRUE@am__EXEEXT_2 = bsdcpio$(EXEEXT) -@BUILD_BSDCAT_TRUE@am__EXEEXT_3 = bsdcat$(EXEEXT) -@BUILD_BSDUNZIP_TRUE@am__EXEEXT_4 = bsdunzip$(EXEEXT) -am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)" \ - "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man3dir)" \ - "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(pkgconfigdir)" \ - "$(DESTDIR)$(includedir)" -@BUILD_BSDTAR_TRUE@am__EXEEXT_5 = bsdtar_test$(EXEEXT) -@BUILD_BSDCPIO_TRUE@am__EXEEXT_6 = bsdcpio_test$(EXEEXT) -@BUILD_BSDCAT_TRUE@am__EXEEXT_7 = bsdcat_test$(EXEEXT) -@BUILD_BSDUNZIP_TRUE@am__EXEEXT_8 = bsdunzip_test$(EXEEXT) -PROGRAMS = $(bin_PROGRAMS) -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) -am__DEPENDENCIES_1 = -libarchive_la_DEPENDENCIES = $(am__DEPENDENCIES_1) -am__libarchive_la_SOURCES_DIST = libarchive/archive_acl.c \ - libarchive/archive_acl_private.h \ - libarchive/archive_check_magic.c libarchive/archive_cmdline.c \ - libarchive/archive_cmdline_private.h \ - libarchive/archive_crc32.h libarchive/archive_cryptor.c \ - libarchive/archive_cryptor_private.h \ - libarchive/archive_digest.c \ - libarchive/archive_digest_private.h \ - libarchive/archive_endian.h libarchive/archive_entry.c \ - libarchive/archive_entry.h \ - libarchive/archive_entry_copy_stat.c \ - libarchive/archive_entry_link_resolver.c \ - libarchive/archive_entry_locale.h \ - libarchive/archive_entry_private.h \ - libarchive/archive_entry_sparse.c \ - libarchive/archive_entry_stat.c \ - libarchive/archive_entry_strmode.c \ - libarchive/archive_entry_xattr.c libarchive/archive_getdate.c \ - libarchive/archive_getdate.h libarchive/archive_hmac.c \ - libarchive/archive_hmac_private.h libarchive/archive_match.c \ - libarchive/archive_openssl_evp_private.h \ - libarchive/archive_openssl_hmac_private.h \ - libarchive/archive_options.c \ - libarchive/archive_options_private.h \ - libarchive/archive_pack_dev.h libarchive/archive_pack_dev.c \ - libarchive/archive_pathmatch.c libarchive/archive_pathmatch.h \ - libarchive/archive_platform.h \ - libarchive/archive_platform_acl.h \ - libarchive/archive_platform_xattr.h \ - libarchive/archive_ppmd_private.h libarchive/archive_ppmd7.c \ - libarchive/archive_ppmd7_private.h libarchive/archive_ppmd8.c \ - libarchive/archive_ppmd8_private.h \ - libarchive/archive_private.h libarchive/archive_random.c \ - libarchive/archive_random_private.h libarchive/archive_rb.c \ - libarchive/archive_rb.h libarchive/archive_read.c \ - libarchive/archive_read_add_passphrase.c \ - libarchive/archive_read_append_filter.c \ - libarchive/archive_read_data_into_fd.c \ - libarchive/archive_read_disk_entry_from_file.c \ - libarchive/archive_read_disk_posix.c \ - libarchive/archive_read_disk_private.h \ - libarchive/archive_read_disk_set_standard_lookup.c \ - libarchive/archive_read_extract.c \ - libarchive/archive_read_extract2.c \ - libarchive/archive_read_open_fd.c \ - libarchive/archive_read_open_file.c \ - libarchive/archive_read_open_filename.c \ - libarchive/archive_read_open_memory.c \ - libarchive/archive_read_private.h \ - libarchive/archive_read_set_format.c \ - libarchive/archive_read_set_options.c \ - libarchive/archive_read_support_filter_all.c \ - libarchive/archive_read_support_filter_bzip2.c \ - libarchive/archive_read_support_filter_by_code.c \ - libarchive/archive_read_support_filter_compress.c \ - libarchive/archive_read_support_filter_grzip.c \ - libarchive/archive_read_support_filter_gzip.c \ - libarchive/archive_read_support_filter_lrzip.c \ - libarchive/archive_read_support_filter_lz4.c \ - libarchive/archive_read_support_filter_lzop.c \ - libarchive/archive_read_support_filter_none.c \ - libarchive/archive_read_support_filter_program.c \ - libarchive/archive_read_support_filter_rpm.c \ - libarchive/archive_read_support_filter_uu.c \ - libarchive/archive_read_support_filter_xz.c \ - libarchive/archive_read_support_filter_zstd.c \ - libarchive/archive_read_support_format_7zip.c \ - libarchive/archive_read_support_format_all.c \ - libarchive/archive_read_support_format_ar.c \ - libarchive/archive_read_support_format_by_code.c \ - libarchive/archive_read_support_format_cab.c \ - libarchive/archive_read_support_format_cpio.c \ - libarchive/archive_read_support_format_empty.c \ - libarchive/archive_read_support_format_iso9660.c \ - libarchive/archive_read_support_format_lha.c \ - libarchive/archive_read_support_format_mtree.c \ - libarchive/archive_read_support_format_rar.c \ - libarchive/archive_read_support_format_rar5.c \ - libarchive/archive_read_support_format_raw.c \ - libarchive/archive_read_support_format_tar.c \ - libarchive/archive_read_support_format_warc.c \ - libarchive/archive_read_support_format_xar.c \ - libarchive/archive_read_support_format_zip.c \ - libarchive/archive_string.c libarchive/archive_string.h \ - libarchive/archive_string_composition.h \ - libarchive/archive_string_sprintf.c libarchive/archive_util.c \ - libarchive/archive_version_details.c \ - libarchive/archive_virtual.c libarchive/archive_write.c \ - libarchive/archive_write_disk_posix.c \ - libarchive/archive_write_disk_private.h \ - libarchive/archive_write_disk_set_standard_lookup.c \ - libarchive/archive_write_open_fd.c \ - libarchive/archive_write_open_file.c \ - libarchive/archive_write_open_filename.c \ - libarchive/archive_write_open_memory.c \ - libarchive/archive_write_private.h \ - libarchive/archive_write_add_filter.c \ - libarchive/archive_write_add_filter_b64encode.c \ - libarchive/archive_write_add_filter_by_name.c \ - libarchive/archive_write_add_filter_bzip2.c \ - libarchive/archive_write_add_filter_compress.c \ - libarchive/archive_write_add_filter_grzip.c \ - libarchive/archive_write_add_filter_gzip.c \ - libarchive/archive_write_add_filter_lrzip.c \ - libarchive/archive_write_add_filter_lz4.c \ - libarchive/archive_write_add_filter_lzop.c \ - libarchive/archive_write_add_filter_none.c \ - libarchive/archive_write_add_filter_program.c \ - libarchive/archive_write_add_filter_uuencode.c \ - libarchive/archive_write_add_filter_xz.c \ - libarchive/archive_write_add_filter_zstd.c \ - libarchive/archive_write_set_format.c \ - libarchive/archive_write_set_format_7zip.c \ - libarchive/archive_write_set_format_ar.c \ - libarchive/archive_write_set_format_by_name.c \ - libarchive/archive_write_set_format_cpio.c \ - libarchive/archive_write_set_format_cpio_binary.c \ - libarchive/archive_write_set_format_cpio_newc.c \ - libarchive/archive_write_set_format_cpio_odc.c \ - libarchive/archive_write_set_format_filter_by_ext.c \ - libarchive/archive_write_set_format_iso9660.c \ - libarchive/archive_write_set_format_mtree.c \ - libarchive/archive_write_set_format_pax.c \ - libarchive/archive_write_set_format_private.h \ - libarchive/archive_write_set_format_raw.c \ - libarchive/archive_write_set_format_shar.c \ - libarchive/archive_write_set_format_ustar.c \ - libarchive/archive_write_set_format_v7tar.c \ - libarchive/archive_write_set_format_gnutar.c \ - libarchive/archive_write_set_format_warc.c \ - libarchive/archive_write_set_format_xar.c \ - libarchive/archive_write_set_format_zip.c \ - libarchive/archive_write_set_options.c \ - libarchive/archive_write_set_passphrase.c \ - libarchive/archive_xxhash.h libarchive/config_freebsd.h \ - libarchive/filter_fork_posix.c libarchive/filter_fork.h \ - libarchive/xxhash.c libarchive/archive_entry_copy_bhfi.c \ - libarchive/archive_read_disk_windows.c \ - libarchive/archive_windows.h libarchive/archive_windows.c \ - libarchive/archive_write_disk_windows.c \ - libarchive/filter_fork_windows.c libarchive/archive_blake2.h \ - libarchive/archive_blake2_impl.h \ - libarchive/archive_blake2s_ref.c \ - libarchive/archive_blake2sp_ref.c \ - libarchive/archive_disk_acl_linux.c \ - libarchive/archive_disk_acl_sunos.c \ - libarchive/archive_disk_acl_darwin.c \ - libarchive/archive_disk_acl_freebsd.c -am__dirstamp = $(am__leading_dot)dirstamp -@INC_WINDOWS_FILES_TRUE@am__objects_1 = \ -@INC_WINDOWS_FILES_TRUE@ libarchive/archive_entry_copy_bhfi.lo \ -@INC_WINDOWS_FILES_TRUE@ libarchive/archive_read_disk_windows.lo \ -@INC_WINDOWS_FILES_TRUE@ libarchive/archive_windows.lo \ -@INC_WINDOWS_FILES_TRUE@ libarchive/archive_write_disk_windows.lo \ -@INC_WINDOWS_FILES_TRUE@ libarchive/filter_fork_windows.lo -@INC_BLAKE2_TRUE@am__objects_2 = libarchive/archive_blake2s_ref.lo \ -@INC_BLAKE2_TRUE@ libarchive/archive_blake2sp_ref.lo -@INC_LINUX_ACL_TRUE@am__objects_3 = \ -@INC_LINUX_ACL_TRUE@ libarchive/archive_disk_acl_linux.lo -@INC_LINUX_ACL_FALSE@@INC_SUNOS_ACL_TRUE@am__objects_4 = libarchive/archive_disk_acl_sunos.lo -@INC_DARWIN_ACL_TRUE@@INC_LINUX_ACL_FALSE@@INC_SUNOS_ACL_FALSE@am__objects_5 = libarchive/archive_disk_acl_darwin.lo -@INC_DARWIN_ACL_FALSE@@INC_FREEBSD_ACL_TRUE@@INC_LINUX_ACL_FALSE@@INC_SUNOS_ACL_FALSE@am__objects_6 = libarchive/archive_disk_acl_freebsd.lo -am_libarchive_la_OBJECTS = libarchive/archive_acl.lo \ - libarchive/archive_check_magic.lo \ - libarchive/archive_cmdline.lo libarchive/archive_cryptor.lo \ - libarchive/archive_digest.lo libarchive/archive_entry.lo \ - libarchive/archive_entry_copy_stat.lo \ - libarchive/archive_entry_link_resolver.lo \ - libarchive/archive_entry_sparse.lo \ - libarchive/archive_entry_stat.lo \ - libarchive/archive_entry_strmode.lo \ - libarchive/archive_entry_xattr.lo \ - libarchive/archive_getdate.lo libarchive/archive_hmac.lo \ - libarchive/archive_match.lo libarchive/archive_options.lo \ - libarchive/archive_pack_dev.lo libarchive/archive_pathmatch.lo \ - libarchive/archive_ppmd7.lo libarchive/archive_ppmd8.lo \ - libarchive/archive_random.lo libarchive/archive_rb.lo \ - libarchive/archive_read.lo \ - libarchive/archive_read_add_passphrase.lo \ - libarchive/archive_read_append_filter.lo \ - libarchive/archive_read_data_into_fd.lo \ - libarchive/archive_read_disk_entry_from_file.lo \ - libarchive/archive_read_disk_posix.lo \ - libarchive/archive_read_disk_set_standard_lookup.lo \ - libarchive/archive_read_extract.lo \ - libarchive/archive_read_extract2.lo \ - libarchive/archive_read_open_fd.lo \ - libarchive/archive_read_open_file.lo \ - libarchive/archive_read_open_filename.lo \ - libarchive/archive_read_open_memory.lo \ - libarchive/archive_read_set_format.lo \ - libarchive/archive_read_set_options.lo \ - libarchive/archive_read_support_filter_all.lo \ - libarchive/archive_read_support_filter_bzip2.lo \ - libarchive/archive_read_support_filter_by_code.lo \ - libarchive/archive_read_support_filter_compress.lo \ - libarchive/archive_read_support_filter_grzip.lo \ - libarchive/archive_read_support_filter_gzip.lo \ - libarchive/archive_read_support_filter_lrzip.lo \ - libarchive/archive_read_support_filter_lz4.lo \ - libarchive/archive_read_support_filter_lzop.lo \ - libarchive/archive_read_support_filter_none.lo \ - libarchive/archive_read_support_filter_program.lo \ - libarchive/archive_read_support_filter_rpm.lo \ - libarchive/archive_read_support_filter_uu.lo \ - libarchive/archive_read_support_filter_xz.lo \ - libarchive/archive_read_support_filter_zstd.lo \ - libarchive/archive_read_support_format_7zip.lo \ - libarchive/archive_read_support_format_all.lo \ - libarchive/archive_read_support_format_ar.lo \ - libarchive/archive_read_support_format_by_code.lo \ - libarchive/archive_read_support_format_cab.lo \ - libarchive/archive_read_support_format_cpio.lo \ - libarchive/archive_read_support_format_empty.lo \ - libarchive/archive_read_support_format_iso9660.lo \ - libarchive/archive_read_support_format_lha.lo \ - libarchive/archive_read_support_format_mtree.lo \ - libarchive/archive_read_support_format_rar.lo \ - libarchive/archive_read_support_format_rar5.lo \ - libarchive/archive_read_support_format_raw.lo \ - libarchive/archive_read_support_format_tar.lo \ - libarchive/archive_read_support_format_warc.lo \ - libarchive/archive_read_support_format_xar.lo \ - libarchive/archive_read_support_format_zip.lo \ - libarchive/archive_string.lo \ - libarchive/archive_string_sprintf.lo \ - libarchive/archive_util.lo \ - libarchive/archive_version_details.lo \ - libarchive/archive_virtual.lo libarchive/archive_write.lo \ - libarchive/archive_write_disk_posix.lo \ - libarchive/archive_write_disk_set_standard_lookup.lo \ - libarchive/archive_write_open_fd.lo \ - libarchive/archive_write_open_file.lo \ - libarchive/archive_write_open_filename.lo \ - libarchive/archive_write_open_memory.lo \ - libarchive/archive_write_add_filter.lo \ - libarchive/archive_write_add_filter_b64encode.lo \ - libarchive/archive_write_add_filter_by_name.lo \ - libarchive/archive_write_add_filter_bzip2.lo \ - libarchive/archive_write_add_filter_compress.lo \ - libarchive/archive_write_add_filter_grzip.lo \ - libarchive/archive_write_add_filter_gzip.lo \ - libarchive/archive_write_add_filter_lrzip.lo \ - libarchive/archive_write_add_filter_lz4.lo \ - libarchive/archive_write_add_filter_lzop.lo \ - libarchive/archive_write_add_filter_none.lo \ - libarchive/archive_write_add_filter_program.lo \ - libarchive/archive_write_add_filter_uuencode.lo \ - libarchive/archive_write_add_filter_xz.lo \ - libarchive/archive_write_add_filter_zstd.lo \ - libarchive/archive_write_set_format.lo \ - libarchive/archive_write_set_format_7zip.lo \ - libarchive/archive_write_set_format_ar.lo \ - libarchive/archive_write_set_format_by_name.lo \ - libarchive/archive_write_set_format_cpio.lo \ - libarchive/archive_write_set_format_cpio_binary.lo \ - libarchive/archive_write_set_format_cpio_newc.lo \ - libarchive/archive_write_set_format_cpio_odc.lo \ - libarchive/archive_write_set_format_filter_by_ext.lo \ - libarchive/archive_write_set_format_iso9660.lo \ - libarchive/archive_write_set_format_mtree.lo \ - libarchive/archive_write_set_format_pax.lo \ - libarchive/archive_write_set_format_raw.lo \ - libarchive/archive_write_set_format_shar.lo \ - libarchive/archive_write_set_format_ustar.lo \ - libarchive/archive_write_set_format_v7tar.lo \ - libarchive/archive_write_set_format_gnutar.lo \ - libarchive/archive_write_set_format_warc.lo \ - libarchive/archive_write_set_format_xar.lo \ - libarchive/archive_write_set_format_zip.lo \ - libarchive/archive_write_set_options.lo \ - libarchive/archive_write_set_passphrase.lo \ - libarchive/filter_fork_posix.lo libarchive/xxhash.lo \ - $(am__objects_1) $(am__objects_2) $(am__objects_3) \ - $(am__objects_4) $(am__objects_5) $(am__objects_6) -libarchive_la_OBJECTS = $(am_libarchive_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -libarchive_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(libarchive_la_LDFLAGS) $(LDFLAGS) -o $@ -libarchive_fe_la_LIBADD = -am_libarchive_fe_la_OBJECTS = libarchive_fe/la-err.lo \ - libarchive_fe/la-line_reader.lo libarchive_fe/la-passphrase.lo -libarchive_fe_la_OBJECTS = $(am_libarchive_fe_la_OBJECTS) -am__objects_7 = -am_bsdcat_OBJECTS = cat/bsdcat-bsdcat.$(OBJEXT) \ - cat/bsdcat-cmdline.$(OBJEXT) $(am__objects_7) -bsdcat_OBJECTS = $(am_bsdcat_OBJECTS) -bsdcat_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(bsdcat_LDFLAGS) $(LDFLAGS) -o $@ -am__objects_8 = test_utils/bsdcat_test-test_utils.$(OBJEXT) \ - test_utils/bsdcat_test-test_main.$(OBJEXT) -am_bsdcat_test_OBJECTS = $(am__objects_8) \ - cat/test/bsdcat_test-test_0.$(OBJEXT) \ - cat/test/bsdcat_test-test_empty_gz.$(OBJEXT) \ - cat/test/bsdcat_test-test_empty_lz4.$(OBJEXT) \ - cat/test/bsdcat_test-test_empty_xz.$(OBJEXT) \ - cat/test/bsdcat_test-test_empty_zstd.$(OBJEXT) \ - cat/test/bsdcat_test-test_error.$(OBJEXT) \ - cat/test/bsdcat_test-test_error_mixed.$(OBJEXT) \ - cat/test/bsdcat_test-test_expand_Z.$(OBJEXT) \ - cat/test/bsdcat_test-test_expand_bz2.$(OBJEXT) \ - cat/test/bsdcat_test-test_expand_gz.$(OBJEXT) \ - cat/test/bsdcat_test-test_expand_lz4.$(OBJEXT) \ - cat/test/bsdcat_test-test_expand_mixed.$(OBJEXT) \ - cat/test/bsdcat_test-test_expand_plain.$(OBJEXT) \ - cat/test/bsdcat_test-test_expand_xz.$(OBJEXT) \ - cat/test/bsdcat_test-test_expand_zstd.$(OBJEXT) \ - cat/test/bsdcat_test-test_help.$(OBJEXT) \ - cat/test/bsdcat_test-test_stdin.$(OBJEXT) \ - cat/test/bsdcat_test-test_version.$(OBJEXT) -bsdcat_test_OBJECTS = $(am_bsdcat_test_OBJECTS) -bsdcat_test_DEPENDENCIES = libarchive_fe.la -am__bsdcpio_SOURCES_DIST = cpio/cmdline.c cpio/cpio.c cpio/cpio.h \ - cpio/cpio_platform.h cpio/cpio_windows.h cpio/cpio_windows.c -@INC_WINDOWS_FILES_TRUE@am__objects_9 = \ -@INC_WINDOWS_FILES_TRUE@ cpio/bsdcpio-cpio_windows.$(OBJEXT) -am_bsdcpio_OBJECTS = cpio/bsdcpio-cmdline.$(OBJEXT) \ - cpio/bsdcpio-cpio.$(OBJEXT) $(am__objects_9) -bsdcpio_OBJECTS = $(am_bsdcpio_OBJECTS) -bsdcpio_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(bsdcpio_LDFLAGS) $(LDFLAGS) -o $@ -am__objects_10 = test_utils/bsdcpio_test-test_utils.$(OBJEXT) \ - test_utils/bsdcpio_test-test_main.$(OBJEXT) -am_bsdcpio_test_OBJECTS = $(am__objects_10) \ - cpio/bsdcpio_test-cmdline.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_0.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_basic.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_cmdline.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_extract_cpio_Z.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_extract_cpio_bz2.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_extract_cpio_grz.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_extract_cpio_gz.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_extract_cpio_lrz.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_extract_cpio_lz.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_extract_cpio_lz4.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_extract_cpio_lzma.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_extract_cpio_lzo.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_extract_cpio_xz.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_extract_cpio_zstd.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_format_newc.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_gcpio_compat.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_missing_file.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_0.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_B_upper.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_C_upper.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_J_upper.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_L_upper.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_Z_upper.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_a.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_b64encode.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_c.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_d.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_f.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_grzip.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_help.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_l.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_lrzip.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_lz4.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_lzma.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_lzop.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_m.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_passphrase.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_t.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_u.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_uuencode.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_version.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_xz.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_y.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_z.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_option_zstd.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_owner_parse.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_passthrough_dotdot.$(OBJEXT) \ - cpio/test/bsdcpio_test-test_passthrough_reverse.$(OBJEXT) -bsdcpio_test_OBJECTS = $(am_bsdcpio_test_OBJECTS) -bsdcpio_test_DEPENDENCIES = libarchive_fe.la -am__bsdtar_SOURCES_DIST = tar/bsdtar.c tar/bsdtar.h \ - tar/bsdtar_platform.h tar/cmdline.c tar/creation_set.c \ - tar/read.c tar/subst.c tar/util.c tar/write.c \ - tar/bsdtar_windows.h tar/bsdtar_windows.c -@INC_WINDOWS_FILES_TRUE@am__objects_11 = \ -@INC_WINDOWS_FILES_TRUE@ tar/bsdtar-bsdtar_windows.$(OBJEXT) -am_bsdtar_OBJECTS = tar/bsdtar-bsdtar.$(OBJEXT) \ - tar/bsdtar-cmdline.$(OBJEXT) tar/bsdtar-creation_set.$(OBJEXT) \ - tar/bsdtar-read.$(OBJEXT) tar/bsdtar-subst.$(OBJEXT) \ - tar/bsdtar-util.$(OBJEXT) tar/bsdtar-write.$(OBJEXT) \ - $(am__objects_11) -bsdtar_OBJECTS = $(am_bsdtar_OBJECTS) -bsdtar_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(bsdtar_LDFLAGS) $(LDFLAGS) -o $@ -am__objects_12 = test_utils/bsdtar_test-test_utils.$(OBJEXT) \ - test_utils/bsdtar_test-test_main.$(OBJEXT) -am_bsdtar_test_OBJECTS = $(am__objects_12) \ - tar/test/bsdtar_test-test_0.$(OBJEXT) \ - tar/test/bsdtar_test-test_basic.$(OBJEXT) \ - tar/test/bsdtar_test-test_copy.$(OBJEXT) \ - tar/test/bsdtar_test-test_empty_mtree.$(OBJEXT) \ - tar/test/bsdtar_test-test_extract_tar_Z.$(OBJEXT) \ - tar/test/bsdtar_test-test_extract_tar_bz2.$(OBJEXT) \ - tar/test/bsdtar_test-test_extract_tar_grz.$(OBJEXT) \ - tar/test/bsdtar_test-test_extract_tar_gz.$(OBJEXT) \ - tar/test/bsdtar_test-test_extract_tar_lrz.$(OBJEXT) \ - tar/test/bsdtar_test-test_extract_tar_lz.$(OBJEXT) \ - tar/test/bsdtar_test-test_extract_tar_lz4.$(OBJEXT) \ - tar/test/bsdtar_test-test_extract_tar_lzma.$(OBJEXT) \ - tar/test/bsdtar_test-test_extract_tar_lzo.$(OBJEXT) \ - tar/test/bsdtar_test-test_extract_tar_xz.$(OBJEXT) \ - tar/test/bsdtar_test-test_extract_tar_zstd.$(OBJEXT) \ - tar/test/bsdtar_test-test_format_newc.$(OBJEXT) \ - tar/test/bsdtar_test-test_help.$(OBJEXT) \ - tar/test/bsdtar_test-test_leading_slash.$(OBJEXT) \ - tar/test/bsdtar_test-test_missing_file.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_C_mtree.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_C_upper.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_H_upper.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_L_upper.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_O_upper.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_T_upper.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_U_upper.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_X_upper.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_acls.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_a.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_b.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_b64encode.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_exclude.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_exclude_vcs.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_fflags.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_gid_gname.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_grzip.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_ignore_zeros.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_j.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_k.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_keep_newer_files.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_lrzip.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_lz4.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_lzma.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_lzop.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_n.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_newer_than.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_nodump.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_older_than.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_passphrase.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_q.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_r.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_s.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_safe_writes.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_uid_uname.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_uuencode.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_xattrs.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_xz.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_z.$(OBJEXT) \ - tar/test/bsdtar_test-test_option_zstd.$(OBJEXT) \ - tar/test/bsdtar_test-test_patterns.$(OBJEXT) \ - tar/test/bsdtar_test-test_print_longpath.$(OBJEXT) \ - tar/test/bsdtar_test-test_stdio.$(OBJEXT) \ - tar/test/bsdtar_test-test_strip_components.$(OBJEXT) \ - tar/test/bsdtar_test-test_symlink_dir.$(OBJEXT) \ - tar/test/bsdtar_test-test_version.$(OBJEXT) \ - tar/test/bsdtar_test-test_windows.$(OBJEXT) -bsdtar_test_OBJECTS = $(am_bsdtar_test_OBJECTS) -bsdtar_test_LDADD = $(LDADD) -am_bsdunzip_OBJECTS = unzip/bsdunzip-bsdunzip.$(OBJEXT) \ - unzip/bsdunzip-cmdline.$(OBJEXT) \ - unzip/bsdunzip-la_getline.$(OBJEXT) $(am__objects_7) -bsdunzip_OBJECTS = $(am_bsdunzip_OBJECTS) -bsdunzip_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(bsdunzip_LDFLAGS) $(LDFLAGS) -o $@ -am__objects_13 = test_utils/bsdunzip_test-test_utils.$(OBJEXT) \ - test_utils/bsdunzip_test-test_main.$(OBJEXT) -am_bsdunzip_test_OBJECTS = $(am__objects_13) \ - unzip/test/bsdunzip_test-test_0.$(OBJEXT) \ - unzip/test/bsdunzip_test-test_basic.$(OBJEXT) \ - unzip/test/bsdunzip_test-test_glob.$(OBJEXT) \ - unzip/test/bsdunzip_test-test_not_exist.$(OBJEXT) \ - unzip/test/bsdunzip_test-test_singlefile.$(OBJEXT) \ - unzip/test/bsdunzip_test-test_C.$(OBJEXT) \ - unzip/test/bsdunzip_test-test_p.$(OBJEXT) \ - unzip/test/bsdunzip_test-test_d.$(OBJEXT) \ - unzip/test/bsdunzip_test-test_j.$(OBJEXT) \ - unzip/test/bsdunzip_test-test_L.$(OBJEXT) \ - unzip/test/bsdunzip_test-test_n.$(OBJEXT) \ - unzip/test/bsdunzip_test-test_o.$(OBJEXT) \ - unzip/test/bsdunzip_test-test_q.$(OBJEXT) \ - unzip/test/bsdunzip_test-test_t.$(OBJEXT) \ - unzip/test/bsdunzip_test-test_t_bad.$(OBJEXT) \ - unzip/test/bsdunzip_test-test_version.$(OBJEXT) \ - unzip/test/bsdunzip_test-test_x.$(OBJEXT) \ - unzip/test/bsdunzip_test-test_Z1.$(OBJEXT) \ - unzip/test/bsdunzip_test-test_P_encryption.$(OBJEXT) -bsdunzip_test_OBJECTS = $(am_bsdunzip_test_OBJECTS) -bsdunzip_test_DEPENDENCIES = libarchive_fe.la -am__libarchive_test_SOURCES_DIST = libarchive/archive_acl.c \ - libarchive/archive_acl_private.h \ - libarchive/archive_check_magic.c libarchive/archive_cmdline.c \ - libarchive/archive_cmdline_private.h \ - libarchive/archive_crc32.h libarchive/archive_cryptor.c \ - libarchive/archive_cryptor_private.h \ - libarchive/archive_digest.c \ - libarchive/archive_digest_private.h \ - libarchive/archive_endian.h libarchive/archive_entry.c \ - libarchive/archive_entry.h \ - libarchive/archive_entry_copy_stat.c \ - libarchive/archive_entry_link_resolver.c \ - libarchive/archive_entry_locale.h \ - libarchive/archive_entry_private.h \ - libarchive/archive_entry_sparse.c \ - libarchive/archive_entry_stat.c \ - libarchive/archive_entry_strmode.c \ - libarchive/archive_entry_xattr.c libarchive/archive_getdate.c \ - libarchive/archive_getdate.h libarchive/archive_hmac.c \ - libarchive/archive_hmac_private.h libarchive/archive_match.c \ - libarchive/archive_openssl_evp_private.h \ - libarchive/archive_openssl_hmac_private.h \ - libarchive/archive_options.c \ - libarchive/archive_options_private.h \ - libarchive/archive_pack_dev.h libarchive/archive_pack_dev.c \ - libarchive/archive_pathmatch.c libarchive/archive_pathmatch.h \ - libarchive/archive_platform.h \ - libarchive/archive_platform_acl.h \ - libarchive/archive_platform_xattr.h \ - libarchive/archive_ppmd_private.h libarchive/archive_ppmd7.c \ - libarchive/archive_ppmd7_private.h libarchive/archive_ppmd8.c \ - libarchive/archive_ppmd8_private.h \ - libarchive/archive_private.h libarchive/archive_random.c \ - libarchive/archive_random_private.h libarchive/archive_rb.c \ - libarchive/archive_rb.h libarchive/archive_read.c \ - libarchive/archive_read_add_passphrase.c \ - libarchive/archive_read_append_filter.c \ - libarchive/archive_read_data_into_fd.c \ - libarchive/archive_read_disk_entry_from_file.c \ - libarchive/archive_read_disk_posix.c \ - libarchive/archive_read_disk_private.h \ - libarchive/archive_read_disk_set_standard_lookup.c \ - libarchive/archive_read_extract.c \ - libarchive/archive_read_extract2.c \ - libarchive/archive_read_open_fd.c \ - libarchive/archive_read_open_file.c \ - libarchive/archive_read_open_filename.c \ - libarchive/archive_read_open_memory.c \ - libarchive/archive_read_private.h \ - libarchive/archive_read_set_format.c \ - libarchive/archive_read_set_options.c \ - libarchive/archive_read_support_filter_all.c \ - libarchive/archive_read_support_filter_bzip2.c \ - libarchive/archive_read_support_filter_by_code.c \ - libarchive/archive_read_support_filter_compress.c \ - libarchive/archive_read_support_filter_grzip.c \ - libarchive/archive_read_support_filter_gzip.c \ - libarchive/archive_read_support_filter_lrzip.c \ - libarchive/archive_read_support_filter_lz4.c \ - libarchive/archive_read_support_filter_lzop.c \ - libarchive/archive_read_support_filter_none.c \ - libarchive/archive_read_support_filter_program.c \ - libarchive/archive_read_support_filter_rpm.c \ - libarchive/archive_read_support_filter_uu.c \ - libarchive/archive_read_support_filter_xz.c \ - libarchive/archive_read_support_filter_zstd.c \ - libarchive/archive_read_support_format_7zip.c \ - libarchive/archive_read_support_format_all.c \ - libarchive/archive_read_support_format_ar.c \ - libarchive/archive_read_support_format_by_code.c \ - libarchive/archive_read_support_format_cab.c \ - libarchive/archive_read_support_format_cpio.c \ - libarchive/archive_read_support_format_empty.c \ - libarchive/archive_read_support_format_iso9660.c \ - libarchive/archive_read_support_format_lha.c \ - libarchive/archive_read_support_format_mtree.c \ - libarchive/archive_read_support_format_rar.c \ - libarchive/archive_read_support_format_rar5.c \ - libarchive/archive_read_support_format_raw.c \ - libarchive/archive_read_support_format_tar.c \ - libarchive/archive_read_support_format_warc.c \ - libarchive/archive_read_support_format_xar.c \ - libarchive/archive_read_support_format_zip.c \ - libarchive/archive_string.c libarchive/archive_string.h \ - libarchive/archive_string_composition.h \ - libarchive/archive_string_sprintf.c libarchive/archive_util.c \ - libarchive/archive_version_details.c \ - libarchive/archive_virtual.c libarchive/archive_write.c \ - libarchive/archive_write_disk_posix.c \ - libarchive/archive_write_disk_private.h \ - libarchive/archive_write_disk_set_standard_lookup.c \ - libarchive/archive_write_open_fd.c \ - libarchive/archive_write_open_file.c \ - libarchive/archive_write_open_filename.c \ - libarchive/archive_write_open_memory.c \ - libarchive/archive_write_private.h \ - libarchive/archive_write_add_filter.c \ - libarchive/archive_write_add_filter_b64encode.c \ - libarchive/archive_write_add_filter_by_name.c \ - libarchive/archive_write_add_filter_bzip2.c \ - libarchive/archive_write_add_filter_compress.c \ - libarchive/archive_write_add_filter_grzip.c \ - libarchive/archive_write_add_filter_gzip.c \ - libarchive/archive_write_add_filter_lrzip.c \ - libarchive/archive_write_add_filter_lz4.c \ - libarchive/archive_write_add_filter_lzop.c \ - libarchive/archive_write_add_filter_none.c \ - libarchive/archive_write_add_filter_program.c \ - libarchive/archive_write_add_filter_uuencode.c \ - libarchive/archive_write_add_filter_xz.c \ - libarchive/archive_write_add_filter_zstd.c \ - libarchive/archive_write_set_format.c \ - libarchive/archive_write_set_format_7zip.c \ - libarchive/archive_write_set_format_ar.c \ - libarchive/archive_write_set_format_by_name.c \ - libarchive/archive_write_set_format_cpio.c \ - libarchive/archive_write_set_format_cpio_binary.c \ - libarchive/archive_write_set_format_cpio_newc.c \ - libarchive/archive_write_set_format_cpio_odc.c \ - libarchive/archive_write_set_format_filter_by_ext.c \ - libarchive/archive_write_set_format_iso9660.c \ - libarchive/archive_write_set_format_mtree.c \ - libarchive/archive_write_set_format_pax.c \ - libarchive/archive_write_set_format_private.h \ - libarchive/archive_write_set_format_raw.c \ - libarchive/archive_write_set_format_shar.c \ - libarchive/archive_write_set_format_ustar.c \ - libarchive/archive_write_set_format_v7tar.c \ - libarchive/archive_write_set_format_gnutar.c \ - libarchive/archive_write_set_format_warc.c \ - libarchive/archive_write_set_format_xar.c \ - libarchive/archive_write_set_format_zip.c \ - libarchive/archive_write_set_options.c \ - libarchive/archive_write_set_passphrase.c \ - libarchive/archive_xxhash.h libarchive/config_freebsd.h \ - libarchive/filter_fork_posix.c libarchive/filter_fork.h \ - libarchive/xxhash.c libarchive/archive_entry_copy_bhfi.c \ - libarchive/archive_read_disk_windows.c \ - libarchive/archive_windows.h libarchive/archive_windows.c \ - libarchive/archive_write_disk_windows.c \ - libarchive/filter_fork_windows.c libarchive/archive_blake2.h \ - libarchive/archive_blake2_impl.h \ - libarchive/archive_blake2s_ref.c \ - libarchive/archive_blake2sp_ref.c \ - libarchive/archive_disk_acl_linux.c \ - libarchive/archive_disk_acl_sunos.c \ - libarchive/archive_disk_acl_darwin.c \ - libarchive/archive_disk_acl_freebsd.c test_utils/test_utils.c \ - test_utils/test_utils.h test_utils/test_main.c \ - test_utils/test_common.h libarchive/test/read_open_memory.c \ - libarchive/test/test.h libarchive/test/test_acl_nfs4.c \ - libarchive/test/test_acl_pax.c \ - libarchive/test/test_acl_platform_nfs4.c \ - libarchive/test/test_acl_platform_posix1e.c \ - libarchive/test/test_acl_posix1e.c \ - libarchive/test/test_acl_text.c \ - libarchive/test/test_archive_api_feature.c \ - libarchive/test/test_archive_clear_error.c \ - libarchive/test/test_archive_cmdline.c \ - libarchive/test/test_archive_digest.c \ - libarchive/test/test_archive_getdate.c \ - libarchive/test/test_archive_match_owner.c \ - libarchive/test/test_archive_match_path.c \ - libarchive/test/test_archive_match_time.c \ - libarchive/test/test_archive_pathmatch.c \ - libarchive/test/test_archive_read_add_passphrase.c \ - libarchive/test/test_archive_read_close_twice.c \ - libarchive/test/test_archive_read_close_twice_open_fd.c \ - libarchive/test/test_archive_read_close_twice_open_filename.c \ - libarchive/test/test_archive_read_multiple_data_objects.c \ - libarchive/test/test_archive_read_next_header_empty.c \ - libarchive/test/test_archive_read_next_header_raw.c \ - libarchive/test/test_archive_read_open2.c \ - libarchive/test/test_archive_read_set_filter_option.c \ - libarchive/test/test_archive_read_set_format_option.c \ - libarchive/test/test_archive_read_set_option.c \ - libarchive/test/test_archive_read_set_options.c \ - libarchive/test/test_archive_read_support.c \ - libarchive/test/test_archive_set_error.c \ - libarchive/test/test_archive_string.c \ - libarchive/test/test_archive_string_conversion.c \ - libarchive/test/test_archive_write_add_filter_by_name.c \ - libarchive/test/test_archive_write_set_filter_option.c \ - libarchive/test/test_archive_write_set_format_by_name.c \ - libarchive/test/test_archive_write_set_format_filter_by_ext.c \ - libarchive/test/test_archive_write_set_format_option.c \ - libarchive/test/test_archive_write_set_option.c \ - libarchive/test/test_archive_write_set_options.c \ - libarchive/test/test_archive_write_set_passphrase.c \ - libarchive/test/test_bad_fd.c \ - libarchive/test/test_compat_bzip2.c \ - libarchive/test/test_compat_cpio.c \ - libarchive/test/test_compat_gtar.c \ - libarchive/test/test_compat_gzip.c \ - libarchive/test/test_compat_lz4.c \ - libarchive/test/test_compat_lzip.c \ - libarchive/test/test_compat_lzma.c \ - libarchive/test/test_compat_lzop.c \ - libarchive/test/test_compat_mac.c \ - libarchive/test/test_compat_perl_archive_tar.c \ - libarchive/test/test_compat_plexus_archiver_tar.c \ - libarchive/test/test_compat_solaris_tar_acl.c \ - libarchive/test/test_compat_solaris_pax_sparse.c \ - libarchive/test/test_compat_star_acl.c \ - libarchive/test/test_compat_tar_directory.c \ - libarchive/test/test_compat_tar_hardlink.c \ - libarchive/test/test_compat_uudecode.c \ - libarchive/test/test_compat_uudecode_large.c \ - libarchive/test/test_compat_xz.c \ - libarchive/test/test_compat_zip.c \ - libarchive/test/test_compat_zstd.c \ - libarchive/test/test_empty_write.c \ - libarchive/test/test_entry.c \ - libarchive/test/test_entry_strmode.c \ - libarchive/test/test_extattr_freebsd.c \ - libarchive/test/test_filter_count.c \ - libarchive/test/test_fuzz.c \ - libarchive/test/test_gnutar_filename_encoding.c \ - libarchive/test/test_link_resolver.c \ - libarchive/test/test_open_failure.c \ - libarchive/test/test_open_fd.c \ - libarchive/test/test_open_file.c \ - libarchive/test/test_open_filename.c \ - libarchive/test/test_pax_filename_encoding.c \ - libarchive/test/test_pax_xattr_header.c \ - libarchive/test/test_read_data_large.c \ - libarchive/test/test_read_disk.c \ - libarchive/test/test_read_disk_directory_traversals.c \ - libarchive/test/test_read_disk_entry_from_file.c \ - libarchive/test/test_read_extract.c \ - libarchive/test/test_read_file_nonexistent.c \ - libarchive/test/test_read_filter_compress.c \ - libarchive/test/test_read_filter_grzip.c \ - libarchive/test/test_read_filter_lrzip.c \ - libarchive/test/test_read_filter_lzop.c \ - libarchive/test/test_read_filter_lzop_multiple_parts.c \ - libarchive/test/test_read_filter_program.c \ - libarchive/test/test_read_filter_program_signature.c \ - libarchive/test/test_read_filter_uudecode.c \ - libarchive/test/test_read_filter_uudecode_raw.c \ - libarchive/test/test_read_format_7zip.c \ - libarchive/test/test_read_format_7zip_encryption_data.c \ - libarchive/test/test_read_format_7zip_encryption_partially.c \ - libarchive/test/test_read_format_7zip_encryption_header.c \ - libarchive/test/test_read_format_7zip_malformed.c \ - libarchive/test/test_read_format_7zip_packinfo_digests.c \ - libarchive/test/test_read_format_ar.c \ - libarchive/test/test_read_format_cab.c \ - libarchive/test/test_read_format_cab_filename.c \ - libarchive/test/test_read_format_cpio_afio.c \ - libarchive/test/test_read_format_cpio_bin.c \ - libarchive/test/test_read_format_cpio_bin_Z.c \ - libarchive/test/test_read_format_cpio_bin_be.c \ - libarchive/test/test_read_format_cpio_bin_bz2.c \ - libarchive/test/test_read_format_cpio_bin_gz.c \ - libarchive/test/test_read_format_cpio_bin_le.c \ - libarchive/test/test_read_format_cpio_bin_lzip.c \ - libarchive/test/test_read_format_cpio_bin_lzma.c \ - libarchive/test/test_read_format_cpio_bin_xz.c \ - libarchive/test/test_read_format_cpio_filename.c \ - libarchive/test/test_read_format_cpio_odc.c \ - libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c \ - libarchive/test/test_read_format_cpio_svr4_gzip.c \ - libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c \ - libarchive/test/test_read_format_cpio_svr4c_Z.c \ - libarchive/test/test_read_format_empty.c \ - libarchive/test/test_read_format_gtar_filename.c \ - libarchive/test/test_read_format_gtar_gz.c \ - libarchive/test/test_read_format_gtar_lzma.c \ - libarchive/test/test_read_format_gtar_sparse.c \ - libarchive/test/test_read_format_gtar_sparse_skip_entry.c \ - libarchive/test/test_read_format_iso_Z.c \ - libarchive/test/test_read_format_iso_multi_extent.c \ - libarchive/test/test_read_format_iso_xorriso.c \ - libarchive/test/test_read_format_isojoliet_bz2.c \ - libarchive/test/test_read_format_isojoliet_long.c \ - libarchive/test/test_read_format_isojoliet_rr.c \ - libarchive/test/test_read_format_isojoliet_versioned.c \ - libarchive/test/test_read_format_isorr_bz2.c \ - libarchive/test/test_read_format_isorr_ce.c \ - libarchive/test/test_read_format_isorr_new_bz2.c \ - libarchive/test/test_read_format_isorr_rr_moved.c \ - libarchive/test/test_read_format_isozisofs_bz2.c \ - libarchive/test/test_read_format_lha.c \ - libarchive/test/test_read_format_lha_bugfix_0.c \ - libarchive/test/test_read_format_lha_filename.c \ - libarchive/test/test_read_format_lha_filename_utf16.c \ - libarchive/test/test_read_format_mtree.c \ - libarchive/test/test_read_format_mtree_crash747.c \ - libarchive/test/test_read_format_pax_bz2.c \ - libarchive/test/test_read_format_rar.c \ - libarchive/test/test_read_format_rar_encryption_data.c \ - libarchive/test/test_read_format_rar_encryption_partially.c \ - libarchive/test/test_read_format_rar_encryption_header.c \ - libarchive/test/test_read_format_rar_filter.c \ - libarchive/test/test_read_format_rar_invalid1.c \ - libarchive/test/test_read_format_rar5.c \ - libarchive/test/test_read_format_raw.c \ - libarchive/test/test_read_format_tar.c \ - libarchive/test/test_read_format_tar_concatenated.c \ - libarchive/test/test_read_format_tar_empty_pax.c \ - libarchive/test/test_read_format_tar_empty_filename.c \ - libarchive/test/test_read_format_tar_empty_with_gnulabel.c \ - libarchive/test/test_read_format_tar_filename.c \ - libarchive/test/test_read_format_tar_invalid_pax_size.c \ - libarchive/test/test_read_format_tbz.c \ - libarchive/test/test_read_format_tgz.c \ - libarchive/test/test_read_format_tlz.c \ - libarchive/test/test_read_format_txz.c \ - libarchive/test/test_read_format_tz.c \ - libarchive/test/test_read_format_ustar_filename.c \ - libarchive/test/test_read_format_warc.c \ - libarchive/test/test_read_format_xar.c \ - libarchive/test/test_read_format_zip.c \ - libarchive/test/test_read_format_zip_7075_utf8_paths.c \ - libarchive/test/test_read_format_zip_comment_stored.c \ - libarchive/test/test_read_format_zip_encryption_data.c \ - libarchive/test/test_read_format_zip_encryption_partially.c \ - libarchive/test/test_read_format_zip_encryption_header.c \ - libarchive/test/test_read_format_zip_extra_padding.c \ - libarchive/test/test_read_format_zip_filename.c \ - libarchive/test/test_read_format_zip_high_compression.c \ - libarchive/test/test_read_format_zip_jar.c \ - libarchive/test/test_read_format_zip_mac_metadata.c \ - libarchive/test/test_read_format_zip_malformed.c \ - libarchive/test/test_read_format_zip_msdos.c \ - libarchive/test/test_read_format_zip_nested.c \ - libarchive/test/test_read_format_zip_nofiletype.c \ - libarchive/test/test_read_format_zip_padded.c \ - libarchive/test/test_read_format_zip_sfx.c \ - libarchive/test/test_read_format_zip_traditional_encryption_data.c \ - libarchive/test/test_read_format_zip_winzip_aes.c \ - libarchive/test/test_read_format_zip_winzip_aes_large.c \ - libarchive/test/test_read_format_zip_zip64.c \ - libarchive/test/test_read_format_zip_with_invalid_traditional_eocd.c \ - libarchive/test/test_read_large.c \ - libarchive/test/test_read_pax_xattr_rht_security_selinux.c \ - libarchive/test/test_read_pax_xattr_schily.c \ - libarchive/test/test_read_pax_truncated.c \ - libarchive/test/test_read_position.c \ - libarchive/test/test_read_set_format.c \ - libarchive/test/test_read_too_many_filters.c \ - libarchive/test/test_read_truncated.c \ - libarchive/test/test_read_truncated_filter.c \ - libarchive/test/test_short_writes.c \ - libarchive/test/test_sparse_basic.c \ - libarchive/test/test_tar_filenames.c \ - libarchive/test/test_tar_large.c \ - libarchive/test/test_ustar_filenames.c \ - libarchive/test/test_ustar_filename_encoding.c \ - libarchive/test/test_warn_missing_hardlink_target.c \ - libarchive/test/test_write_disk.c \ - libarchive/test/test_write_disk_appledouble.c \ - libarchive/test/test_write_disk_failures.c \ - libarchive/test/test_write_disk_fixup.c \ - libarchive/test/test_write_disk_hardlink.c \ - libarchive/test/test_write_disk_hfs_compression.c \ - libarchive/test/test_write_disk_lookup.c \ - libarchive/test/test_write_disk_mac_metadata.c \ - libarchive/test/test_write_disk_no_hfs_compression.c \ - libarchive/test/test_write_disk_perms.c \ - libarchive/test/test_write_disk_secure.c \ - libarchive/test/test_write_disk_secure744.c \ - libarchive/test/test_write_disk_secure745.c \ - libarchive/test/test_write_disk_secure746.c \ - libarchive/test/test_write_disk_sparse.c \ - libarchive/test/test_write_disk_symlink.c \ - libarchive/test/test_write_disk_times.c \ - libarchive/test/test_write_filter_b64encode.c \ - libarchive/test/test_write_filter_bzip2.c \ - libarchive/test/test_write_filter_compress.c \ - libarchive/test/test_write_filter_gzip.c \ - libarchive/test/test_write_filter_gzip_timestamp.c \ - libarchive/test/test_write_filter_lrzip.c \ - libarchive/test/test_write_filter_lz4.c \ - libarchive/test/test_write_filter_lzip.c \ - libarchive/test/test_write_filter_lzma.c \ - libarchive/test/test_write_filter_lzop.c \ - libarchive/test/test_write_filter_program.c \ - libarchive/test/test_write_filter_uuencode.c \ - libarchive/test/test_write_filter_xz.c \ - libarchive/test/test_write_filter_zstd.c \ - libarchive/test/test_write_format_7zip.c \ - libarchive/test/test_write_format_7zip_empty.c \ - libarchive/test/test_write_format_7zip_large.c \ - libarchive/test/test_write_format_ar.c \ - libarchive/test/test_write_format_cpio.c \ - libarchive/test/test_write_format_cpio_empty.c \ - libarchive/test/test_write_format_cpio_newc.c \ - libarchive/test/test_write_format_cpio_odc.c \ - libarchive/test/test_write_format_gnutar.c \ - libarchive/test/test_write_format_gnutar_filenames.c \ - libarchive/test/test_write_format_iso9660.c \ - libarchive/test/test_write_format_iso9660_boot.c \ - libarchive/test/test_write_format_iso9660_empty.c \ - libarchive/test/test_write_format_iso9660_filename.c \ - libarchive/test/test_write_format_iso9660_zisofs.c \ - libarchive/test/test_write_format_mtree.c \ - libarchive/test/test_write_format_mtree_absolute_path.c \ - libarchive/test/test_write_format_mtree_classic.c \ - libarchive/test/test_write_format_mtree_classic_indent.c \ - libarchive/test/test_write_format_mtree_fflags.c \ - libarchive/test/test_write_format_mtree_no_separator.c \ - libarchive/test/test_write_format_mtree_quoted_filename.c \ - libarchive/test/test_write_format_pax.c \ - libarchive/test/test_write_format_raw.c \ - libarchive/test/test_write_format_raw_b64.c \ - libarchive/test/test_write_format_shar_empty.c \ - libarchive/test/test_write_format_tar.c \ - libarchive/test/test_write_format_tar_empty.c \ - libarchive/test/test_write_format_tar_sparse.c \ - libarchive/test/test_write_format_tar_ustar.c \ - libarchive/test/test_write_format_tar_v7tar.c \ - libarchive/test/test_write_format_warc.c \ - libarchive/test/test_write_format_warc_empty.c \ - libarchive/test/test_write_format_xar.c \ - libarchive/test/test_write_format_xar_empty.c \ - libarchive/test/test_write_format_zip.c \ - libarchive/test/test_write_format_zip_compression_store.c \ - libarchive/test/test_write_format_zip_entry_size_unset.c \ - libarchive/test/test_write_format_zip_empty.c \ - libarchive/test/test_write_format_zip_empty_zip64.c \ - libarchive/test/test_write_format_zip_file.c \ - libarchive/test/test_write_format_zip_file_zip64.c \ - libarchive/test/test_write_format_zip_large.c \ - libarchive/test/test_write_format_zip_zip64.c \ - libarchive/test/test_write_open_memory.c \ - libarchive/test/test_write_read_format_zip.c \ - libarchive/test/test_xattr_platform.c \ - libarchive/test/test_zip_filename_encoding.c -@INC_WINDOWS_FILES_TRUE@am__objects_14 = libarchive/test-archive_entry_copy_bhfi.$(OBJEXT) \ -@INC_WINDOWS_FILES_TRUE@ libarchive/test-archive_read_disk_windows.$(OBJEXT) \ -@INC_WINDOWS_FILES_TRUE@ libarchive/test-archive_windows.$(OBJEXT) \ -@INC_WINDOWS_FILES_TRUE@ libarchive/test-archive_write_disk_windows.$(OBJEXT) \ -@INC_WINDOWS_FILES_TRUE@ libarchive/test-filter_fork_windows.$(OBJEXT) -@INC_BLAKE2_TRUE@am__objects_15 = libarchive/test-archive_blake2s_ref.$(OBJEXT) \ -@INC_BLAKE2_TRUE@ libarchive/test-archive_blake2sp_ref.$(OBJEXT) -@INC_LINUX_ACL_TRUE@am__objects_16 = libarchive/test-archive_disk_acl_linux.$(OBJEXT) -@INC_LINUX_ACL_FALSE@@INC_SUNOS_ACL_TRUE@am__objects_17 = libarchive/test-archive_disk_acl_sunos.$(OBJEXT) -@INC_DARWIN_ACL_TRUE@@INC_LINUX_ACL_FALSE@@INC_SUNOS_ACL_FALSE@am__objects_18 = libarchive/test-archive_disk_acl_darwin.$(OBJEXT) -@INC_DARWIN_ACL_FALSE@@INC_FREEBSD_ACL_TRUE@@INC_LINUX_ACL_FALSE@@INC_SUNOS_ACL_FALSE@am__objects_19 = libarchive/test-archive_disk_acl_freebsd.$(OBJEXT) -am__objects_20 = libarchive/test-archive_acl.$(OBJEXT) \ - libarchive/test-archive_check_magic.$(OBJEXT) \ - libarchive/test-archive_cmdline.$(OBJEXT) \ - libarchive/test-archive_cryptor.$(OBJEXT) \ - libarchive/test-archive_digest.$(OBJEXT) \ - libarchive/test-archive_entry.$(OBJEXT) \ - libarchive/test-archive_entry_copy_stat.$(OBJEXT) \ - libarchive/test-archive_entry_link_resolver.$(OBJEXT) \ - libarchive/test-archive_entry_sparse.$(OBJEXT) \ - libarchive/test-archive_entry_stat.$(OBJEXT) \ - libarchive/test-archive_entry_strmode.$(OBJEXT) \ - libarchive/test-archive_entry_xattr.$(OBJEXT) \ - libarchive/test-archive_getdate.$(OBJEXT) \ - libarchive/test-archive_hmac.$(OBJEXT) \ - libarchive/test-archive_match.$(OBJEXT) \ - libarchive/test-archive_options.$(OBJEXT) \ - libarchive/test-archive_pack_dev.$(OBJEXT) \ - libarchive/test-archive_pathmatch.$(OBJEXT) \ - libarchive/test-archive_ppmd7.$(OBJEXT) \ - libarchive/test-archive_ppmd8.$(OBJEXT) \ - libarchive/test-archive_random.$(OBJEXT) \ - libarchive/test-archive_rb.$(OBJEXT) \ - libarchive/test-archive_read.$(OBJEXT) \ - libarchive/test-archive_read_add_passphrase.$(OBJEXT) \ - libarchive/test-archive_read_append_filter.$(OBJEXT) \ - libarchive/test-archive_read_data_into_fd.$(OBJEXT) \ - libarchive/test-archive_read_disk_entry_from_file.$(OBJEXT) \ - libarchive/test-archive_read_disk_posix.$(OBJEXT) \ - libarchive/test-archive_read_disk_set_standard_lookup.$(OBJEXT) \ - libarchive/test-archive_read_extract.$(OBJEXT) \ - libarchive/test-archive_read_extract2.$(OBJEXT) \ - libarchive/test-archive_read_open_fd.$(OBJEXT) \ - libarchive/test-archive_read_open_file.$(OBJEXT) \ - libarchive/test-archive_read_open_filename.$(OBJEXT) \ - libarchive/test-archive_read_open_memory.$(OBJEXT) \ - libarchive/test-archive_read_set_format.$(OBJEXT) \ - libarchive/test-archive_read_set_options.$(OBJEXT) \ - libarchive/test-archive_read_support_filter_all.$(OBJEXT) \ - libarchive/test-archive_read_support_filter_bzip2.$(OBJEXT) \ - libarchive/test-archive_read_support_filter_by_code.$(OBJEXT) \ - libarchive/test-archive_read_support_filter_compress.$(OBJEXT) \ - libarchive/test-archive_read_support_filter_grzip.$(OBJEXT) \ - libarchive/test-archive_read_support_filter_gzip.$(OBJEXT) \ - libarchive/test-archive_read_support_filter_lrzip.$(OBJEXT) \ - libarchive/test-archive_read_support_filter_lz4.$(OBJEXT) \ - libarchive/test-archive_read_support_filter_lzop.$(OBJEXT) \ - libarchive/test-archive_read_support_filter_none.$(OBJEXT) \ - libarchive/test-archive_read_support_filter_program.$(OBJEXT) \ - libarchive/test-archive_read_support_filter_rpm.$(OBJEXT) \ - libarchive/test-archive_read_support_filter_uu.$(OBJEXT) \ - libarchive/test-archive_read_support_filter_xz.$(OBJEXT) \ - libarchive/test-archive_read_support_filter_zstd.$(OBJEXT) \ - libarchive/test-archive_read_support_format_7zip.$(OBJEXT) \ - libarchive/test-archive_read_support_format_all.$(OBJEXT) \ - libarchive/test-archive_read_support_format_ar.$(OBJEXT) \ - libarchive/test-archive_read_support_format_by_code.$(OBJEXT) \ - libarchive/test-archive_read_support_format_cab.$(OBJEXT) \ - libarchive/test-archive_read_support_format_cpio.$(OBJEXT) \ - libarchive/test-archive_read_support_format_empty.$(OBJEXT) \ - libarchive/test-archive_read_support_format_iso9660.$(OBJEXT) \ - libarchive/test-archive_read_support_format_lha.$(OBJEXT) \ - libarchive/test-archive_read_support_format_mtree.$(OBJEXT) \ - libarchive/test-archive_read_support_format_rar.$(OBJEXT) \ - libarchive/test-archive_read_support_format_rar5.$(OBJEXT) \ - libarchive/test-archive_read_support_format_raw.$(OBJEXT) \ - libarchive/test-archive_read_support_format_tar.$(OBJEXT) \ - libarchive/test-archive_read_support_format_warc.$(OBJEXT) \ - libarchive/test-archive_read_support_format_xar.$(OBJEXT) \ - libarchive/test-archive_read_support_format_zip.$(OBJEXT) \ - libarchive/test-archive_string.$(OBJEXT) \ - libarchive/test-archive_string_sprintf.$(OBJEXT) \ - libarchive/test-archive_util.$(OBJEXT) \ - libarchive/test-archive_version_details.$(OBJEXT) \ - libarchive/test-archive_virtual.$(OBJEXT) \ - libarchive/test-archive_write.$(OBJEXT) \ - libarchive/test-archive_write_disk_posix.$(OBJEXT) \ - libarchive/test-archive_write_disk_set_standard_lookup.$(OBJEXT) \ - libarchive/test-archive_write_open_fd.$(OBJEXT) \ - libarchive/test-archive_write_open_file.$(OBJEXT) \ - libarchive/test-archive_write_open_filename.$(OBJEXT) \ - libarchive/test-archive_write_open_memory.$(OBJEXT) \ - libarchive/test-archive_write_add_filter.$(OBJEXT) \ - libarchive/test-archive_write_add_filter_b64encode.$(OBJEXT) \ - libarchive/test-archive_write_add_filter_by_name.$(OBJEXT) \ - libarchive/test-archive_write_add_filter_bzip2.$(OBJEXT) \ - libarchive/test-archive_write_add_filter_compress.$(OBJEXT) \ - libarchive/test-archive_write_add_filter_grzip.$(OBJEXT) \ - libarchive/test-archive_write_add_filter_gzip.$(OBJEXT) \ - libarchive/test-archive_write_add_filter_lrzip.$(OBJEXT) \ - libarchive/test-archive_write_add_filter_lz4.$(OBJEXT) \ - libarchive/test-archive_write_add_filter_lzop.$(OBJEXT) \ - libarchive/test-archive_write_add_filter_none.$(OBJEXT) \ - libarchive/test-archive_write_add_filter_program.$(OBJEXT) \ - libarchive/test-archive_write_add_filter_uuencode.$(OBJEXT) \ - libarchive/test-archive_write_add_filter_xz.$(OBJEXT) \ - libarchive/test-archive_write_add_filter_zstd.$(OBJEXT) \ - libarchive/test-archive_write_set_format.$(OBJEXT) \ - libarchive/test-archive_write_set_format_7zip.$(OBJEXT) \ - libarchive/test-archive_write_set_format_ar.$(OBJEXT) \ - libarchive/test-archive_write_set_format_by_name.$(OBJEXT) \ - libarchive/test-archive_write_set_format_cpio.$(OBJEXT) \ - libarchive/test-archive_write_set_format_cpio_binary.$(OBJEXT) \ - libarchive/test-archive_write_set_format_cpio_newc.$(OBJEXT) \ - libarchive/test-archive_write_set_format_cpio_odc.$(OBJEXT) \ - libarchive/test-archive_write_set_format_filter_by_ext.$(OBJEXT) \ - libarchive/test-archive_write_set_format_iso9660.$(OBJEXT) \ - libarchive/test-archive_write_set_format_mtree.$(OBJEXT) \ - libarchive/test-archive_write_set_format_pax.$(OBJEXT) \ - libarchive/test-archive_write_set_format_raw.$(OBJEXT) \ - libarchive/test-archive_write_set_format_shar.$(OBJEXT) \ - libarchive/test-archive_write_set_format_ustar.$(OBJEXT) \ - libarchive/test-archive_write_set_format_v7tar.$(OBJEXT) \ - libarchive/test-archive_write_set_format_gnutar.$(OBJEXT) \ - libarchive/test-archive_write_set_format_warc.$(OBJEXT) \ - libarchive/test-archive_write_set_format_xar.$(OBJEXT) \ - libarchive/test-archive_write_set_format_zip.$(OBJEXT) \ - libarchive/test-archive_write_set_options.$(OBJEXT) \ - libarchive/test-archive_write_set_passphrase.$(OBJEXT) \ - libarchive/test-filter_fork_posix.$(OBJEXT) \ - libarchive/test-xxhash.$(OBJEXT) $(am__objects_14) \ - $(am__objects_15) $(am__objects_16) $(am__objects_17) \ - $(am__objects_18) $(am__objects_19) -am__objects_21 = test_utils/libarchive_test-test_utils.$(OBJEXT) \ - test_utils/libarchive_test-test_main.$(OBJEXT) -am_libarchive_test_OBJECTS = $(am__objects_20) $(am__objects_21) \ - libarchive/test/test-read_open_memory.$(OBJEXT) \ - libarchive/test/test-test_acl_nfs4.$(OBJEXT) \ - libarchive/test/test-test_acl_pax.$(OBJEXT) \ - libarchive/test/test-test_acl_platform_nfs4.$(OBJEXT) \ - libarchive/test/test-test_acl_platform_posix1e.$(OBJEXT) \ - libarchive/test/test-test_acl_posix1e.$(OBJEXT) \ - libarchive/test/test-test_acl_text.$(OBJEXT) \ - libarchive/test/test-test_archive_api_feature.$(OBJEXT) \ - libarchive/test/test-test_archive_clear_error.$(OBJEXT) \ - libarchive/test/test-test_archive_cmdline.$(OBJEXT) \ - libarchive/test/test-test_archive_digest.$(OBJEXT) \ - libarchive/test/test-test_archive_getdate.$(OBJEXT) \ - libarchive/test/test-test_archive_match_owner.$(OBJEXT) \ - libarchive/test/test-test_archive_match_path.$(OBJEXT) \ - libarchive/test/test-test_archive_match_time.$(OBJEXT) \ - libarchive/test/test-test_archive_pathmatch.$(OBJEXT) \ - libarchive/test/test-test_archive_read_add_passphrase.$(OBJEXT) \ - libarchive/test/test-test_archive_read_close_twice.$(OBJEXT) \ - libarchive/test/test-test_archive_read_close_twice_open_fd.$(OBJEXT) \ - libarchive/test/test-test_archive_read_close_twice_open_filename.$(OBJEXT) \ - libarchive/test/test-test_archive_read_multiple_data_objects.$(OBJEXT) \ - libarchive/test/test-test_archive_read_next_header_empty.$(OBJEXT) \ - libarchive/test/test-test_archive_read_next_header_raw.$(OBJEXT) \ - libarchive/test/test-test_archive_read_open2.$(OBJEXT) \ - libarchive/test/test-test_archive_read_set_filter_option.$(OBJEXT) \ - libarchive/test/test-test_archive_read_set_format_option.$(OBJEXT) \ - libarchive/test/test-test_archive_read_set_option.$(OBJEXT) \ - libarchive/test/test-test_archive_read_set_options.$(OBJEXT) \ - libarchive/test/test-test_archive_read_support.$(OBJEXT) \ - libarchive/test/test-test_archive_set_error.$(OBJEXT) \ - libarchive/test/test-test_archive_string.$(OBJEXT) \ - libarchive/test/test-test_archive_string_conversion.$(OBJEXT) \ - libarchive/test/test-test_archive_write_add_filter_by_name.$(OBJEXT) \ - libarchive/test/test-test_archive_write_set_filter_option.$(OBJEXT) \ - libarchive/test/test-test_archive_write_set_format_by_name.$(OBJEXT) \ - libarchive/test/test-test_archive_write_set_format_filter_by_ext.$(OBJEXT) \ - libarchive/test/test-test_archive_write_set_format_option.$(OBJEXT) \ - libarchive/test/test-test_archive_write_set_option.$(OBJEXT) \ - libarchive/test/test-test_archive_write_set_options.$(OBJEXT) \ - libarchive/test/test-test_archive_write_set_passphrase.$(OBJEXT) \ - libarchive/test/test-test_bad_fd.$(OBJEXT) \ - libarchive/test/test-test_compat_bzip2.$(OBJEXT) \ - libarchive/test/test-test_compat_cpio.$(OBJEXT) \ - libarchive/test/test-test_compat_gtar.$(OBJEXT) \ - libarchive/test/test-test_compat_gzip.$(OBJEXT) \ - libarchive/test/test-test_compat_lz4.$(OBJEXT) \ - libarchive/test/test-test_compat_lzip.$(OBJEXT) \ - libarchive/test/test-test_compat_lzma.$(OBJEXT) \ - libarchive/test/test-test_compat_lzop.$(OBJEXT) \ - libarchive/test/test-test_compat_mac.$(OBJEXT) \ - libarchive/test/test-test_compat_perl_archive_tar.$(OBJEXT) \ - libarchive/test/test-test_compat_plexus_archiver_tar.$(OBJEXT) \ - libarchive/test/test-test_compat_solaris_tar_acl.$(OBJEXT) \ - libarchive/test/test-test_compat_solaris_pax_sparse.$(OBJEXT) \ - libarchive/test/test-test_compat_star_acl.$(OBJEXT) \ - libarchive/test/test-test_compat_tar_directory.$(OBJEXT) \ - libarchive/test/test-test_compat_tar_hardlink.$(OBJEXT) \ - libarchive/test/test-test_compat_uudecode.$(OBJEXT) \ - libarchive/test/test-test_compat_uudecode_large.$(OBJEXT) \ - libarchive/test/test-test_compat_xz.$(OBJEXT) \ - libarchive/test/test-test_compat_zip.$(OBJEXT) \ - libarchive/test/test-test_compat_zstd.$(OBJEXT) \ - libarchive/test/test-test_empty_write.$(OBJEXT) \ - libarchive/test/test-test_entry.$(OBJEXT) \ - libarchive/test/test-test_entry_strmode.$(OBJEXT) \ - libarchive/test/test-test_extattr_freebsd.$(OBJEXT) \ - libarchive/test/test-test_filter_count.$(OBJEXT) \ - libarchive/test/test-test_fuzz.$(OBJEXT) \ - libarchive/test/test-test_gnutar_filename_encoding.$(OBJEXT) \ - libarchive/test/test-test_link_resolver.$(OBJEXT) \ - libarchive/test/test-test_open_failure.$(OBJEXT) \ - libarchive/test/test-test_open_fd.$(OBJEXT) \ - libarchive/test/test-test_open_file.$(OBJEXT) \ - libarchive/test/test-test_open_filename.$(OBJEXT) \ - libarchive/test/test-test_pax_filename_encoding.$(OBJEXT) \ - libarchive/test/test-test_pax_xattr_header.$(OBJEXT) \ - libarchive/test/test-test_read_data_large.$(OBJEXT) \ - libarchive/test/test-test_read_disk.$(OBJEXT) \ - libarchive/test/test-test_read_disk_directory_traversals.$(OBJEXT) \ - libarchive/test/test-test_read_disk_entry_from_file.$(OBJEXT) \ - libarchive/test/test-test_read_extract.$(OBJEXT) \ - libarchive/test/test-test_read_file_nonexistent.$(OBJEXT) \ - libarchive/test/test-test_read_filter_compress.$(OBJEXT) \ - libarchive/test/test-test_read_filter_grzip.$(OBJEXT) \ - libarchive/test/test-test_read_filter_lrzip.$(OBJEXT) \ - libarchive/test/test-test_read_filter_lzop.$(OBJEXT) \ - libarchive/test/test-test_read_filter_lzop_multiple_parts.$(OBJEXT) \ - libarchive/test/test-test_read_filter_program.$(OBJEXT) \ - libarchive/test/test-test_read_filter_program_signature.$(OBJEXT) \ - libarchive/test/test-test_read_filter_uudecode.$(OBJEXT) \ - libarchive/test/test-test_read_filter_uudecode_raw.$(OBJEXT) \ - libarchive/test/test-test_read_format_7zip.$(OBJEXT) \ - libarchive/test/test-test_read_format_7zip_encryption_data.$(OBJEXT) \ - libarchive/test/test-test_read_format_7zip_encryption_partially.$(OBJEXT) \ - libarchive/test/test-test_read_format_7zip_encryption_header.$(OBJEXT) \ - libarchive/test/test-test_read_format_7zip_malformed.$(OBJEXT) \ - libarchive/test/test-test_read_format_7zip_packinfo_digests.$(OBJEXT) \ - libarchive/test/test-test_read_format_ar.$(OBJEXT) \ - libarchive/test/test-test_read_format_cab.$(OBJEXT) \ - libarchive/test/test-test_read_format_cab_filename.$(OBJEXT) \ - libarchive/test/test-test_read_format_cpio_afio.$(OBJEXT) \ - libarchive/test/test-test_read_format_cpio_bin.$(OBJEXT) \ - libarchive/test/test-test_read_format_cpio_bin_Z.$(OBJEXT) \ - libarchive/test/test-test_read_format_cpio_bin_be.$(OBJEXT) \ - libarchive/test/test-test_read_format_cpio_bin_bz2.$(OBJEXT) \ - libarchive/test/test-test_read_format_cpio_bin_gz.$(OBJEXT) \ - libarchive/test/test-test_read_format_cpio_bin_le.$(OBJEXT) \ - libarchive/test/test-test_read_format_cpio_bin_lzip.$(OBJEXT) \ - libarchive/test/test-test_read_format_cpio_bin_lzma.$(OBJEXT) \ - libarchive/test/test-test_read_format_cpio_bin_xz.$(OBJEXT) \ - libarchive/test/test-test_read_format_cpio_filename.$(OBJEXT) \ - libarchive/test/test-test_read_format_cpio_odc.$(OBJEXT) \ - libarchive/test/test-test_read_format_cpio_svr4_bzip2_rpm.$(OBJEXT) \ - libarchive/test/test-test_read_format_cpio_svr4_gzip.$(OBJEXT) \ - libarchive/test/test-test_read_format_cpio_svr4_gzip_rpm.$(OBJEXT) \ - libarchive/test/test-test_read_format_cpio_svr4c_Z.$(OBJEXT) \ - libarchive/test/test-test_read_format_empty.$(OBJEXT) \ - libarchive/test/test-test_read_format_gtar_filename.$(OBJEXT) \ - libarchive/test/test-test_read_format_gtar_gz.$(OBJEXT) \ - libarchive/test/test-test_read_format_gtar_lzma.$(OBJEXT) \ - libarchive/test/test-test_read_format_gtar_sparse.$(OBJEXT) \ - libarchive/test/test-test_read_format_gtar_sparse_skip_entry.$(OBJEXT) \ - libarchive/test/test-test_read_format_iso_Z.$(OBJEXT) \ - libarchive/test/test-test_read_format_iso_multi_extent.$(OBJEXT) \ - libarchive/test/test-test_read_format_iso_xorriso.$(OBJEXT) \ - libarchive/test/test-test_read_format_isojoliet_bz2.$(OBJEXT) \ - libarchive/test/test-test_read_format_isojoliet_long.$(OBJEXT) \ - libarchive/test/test-test_read_format_isojoliet_rr.$(OBJEXT) \ - libarchive/test/test-test_read_format_isojoliet_versioned.$(OBJEXT) \ - libarchive/test/test-test_read_format_isorr_bz2.$(OBJEXT) \ - libarchive/test/test-test_read_format_isorr_ce.$(OBJEXT) \ - libarchive/test/test-test_read_format_isorr_new_bz2.$(OBJEXT) \ - libarchive/test/test-test_read_format_isorr_rr_moved.$(OBJEXT) \ - libarchive/test/test-test_read_format_isozisofs_bz2.$(OBJEXT) \ - libarchive/test/test-test_read_format_lha.$(OBJEXT) \ - libarchive/test/test-test_read_format_lha_bugfix_0.$(OBJEXT) \ - libarchive/test/test-test_read_format_lha_filename.$(OBJEXT) \ - libarchive/test/test-test_read_format_lha_filename_utf16.$(OBJEXT) \ - libarchive/test/test-test_read_format_mtree.$(OBJEXT) \ - libarchive/test/test-test_read_format_mtree_crash747.$(OBJEXT) \ - libarchive/test/test-test_read_format_pax_bz2.$(OBJEXT) \ - libarchive/test/test-test_read_format_rar.$(OBJEXT) \ - libarchive/test/test-test_read_format_rar_encryption_data.$(OBJEXT) \ - libarchive/test/test-test_read_format_rar_encryption_partially.$(OBJEXT) \ - libarchive/test/test-test_read_format_rar_encryption_header.$(OBJEXT) \ - libarchive/test/test-test_read_format_rar_filter.$(OBJEXT) \ - libarchive/test/test-test_read_format_rar_invalid1.$(OBJEXT) \ - libarchive/test/test-test_read_format_rar5.$(OBJEXT) \ - libarchive/test/test-test_read_format_raw.$(OBJEXT) \ - libarchive/test/test-test_read_format_tar.$(OBJEXT) \ - libarchive/test/test-test_read_format_tar_concatenated.$(OBJEXT) \ - libarchive/test/test-test_read_format_tar_empty_pax.$(OBJEXT) \ - libarchive/test/test-test_read_format_tar_empty_filename.$(OBJEXT) \ - libarchive/test/test-test_read_format_tar_empty_with_gnulabel.$(OBJEXT) \ - libarchive/test/test-test_read_format_tar_filename.$(OBJEXT) \ - libarchive/test/test-test_read_format_tar_invalid_pax_size.$(OBJEXT) \ - libarchive/test/test-test_read_format_tbz.$(OBJEXT) \ - libarchive/test/test-test_read_format_tgz.$(OBJEXT) \ - libarchive/test/test-test_read_format_tlz.$(OBJEXT) \ - libarchive/test/test-test_read_format_txz.$(OBJEXT) \ - libarchive/test/test-test_read_format_tz.$(OBJEXT) \ - libarchive/test/test-test_read_format_ustar_filename.$(OBJEXT) \ - libarchive/test/test-test_read_format_warc.$(OBJEXT) \ - libarchive/test/test-test_read_format_xar.$(OBJEXT) \ - libarchive/test/test-test_read_format_zip.$(OBJEXT) \ - libarchive/test/test-test_read_format_zip_7075_utf8_paths.$(OBJEXT) \ - libarchive/test/test-test_read_format_zip_comment_stored.$(OBJEXT) \ - libarchive/test/test-test_read_format_zip_encryption_data.$(OBJEXT) \ - libarchive/test/test-test_read_format_zip_encryption_partially.$(OBJEXT) \ - libarchive/test/test-test_read_format_zip_encryption_header.$(OBJEXT) \ - libarchive/test/test-test_read_format_zip_extra_padding.$(OBJEXT) \ - libarchive/test/test-test_read_format_zip_filename.$(OBJEXT) \ - libarchive/test/test-test_read_format_zip_high_compression.$(OBJEXT) \ - libarchive/test/test-test_read_format_zip_jar.$(OBJEXT) \ - libarchive/test/test-test_read_format_zip_mac_metadata.$(OBJEXT) \ - libarchive/test/test-test_read_format_zip_malformed.$(OBJEXT) \ - libarchive/test/test-test_read_format_zip_msdos.$(OBJEXT) \ - libarchive/test/test-test_read_format_zip_nested.$(OBJEXT) \ - libarchive/test/test-test_read_format_zip_nofiletype.$(OBJEXT) \ - libarchive/test/test-test_read_format_zip_padded.$(OBJEXT) \ - libarchive/test/test-test_read_format_zip_sfx.$(OBJEXT) \ - libarchive/test/test-test_read_format_zip_traditional_encryption_data.$(OBJEXT) \ - libarchive/test/test-test_read_format_zip_winzip_aes.$(OBJEXT) \ - libarchive/test/test-test_read_format_zip_winzip_aes_large.$(OBJEXT) \ - libarchive/test/test-test_read_format_zip_zip64.$(OBJEXT) \ - libarchive/test/test-test_read_format_zip_with_invalid_traditional_eocd.$(OBJEXT) \ - libarchive/test/test-test_read_large.$(OBJEXT) \ - libarchive/test/test-test_read_pax_xattr_rht_security_selinux.$(OBJEXT) \ - libarchive/test/test-test_read_pax_xattr_schily.$(OBJEXT) \ - libarchive/test/test-test_read_pax_truncated.$(OBJEXT) \ - libarchive/test/test-test_read_position.$(OBJEXT) \ - libarchive/test/test-test_read_set_format.$(OBJEXT) \ - libarchive/test/test-test_read_too_many_filters.$(OBJEXT) \ - libarchive/test/test-test_read_truncated.$(OBJEXT) \ - libarchive/test/test-test_read_truncated_filter.$(OBJEXT) \ - libarchive/test/test-test_short_writes.$(OBJEXT) \ - libarchive/test/test-test_sparse_basic.$(OBJEXT) \ - libarchive/test/test-test_tar_filenames.$(OBJEXT) \ - libarchive/test/test-test_tar_large.$(OBJEXT) \ - libarchive/test/test-test_ustar_filenames.$(OBJEXT) \ - libarchive/test/test-test_ustar_filename_encoding.$(OBJEXT) \ - libarchive/test/test-test_warn_missing_hardlink_target.$(OBJEXT) \ - libarchive/test/test-test_write_disk.$(OBJEXT) \ - libarchive/test/test-test_write_disk_appledouble.$(OBJEXT) \ - libarchive/test/test-test_write_disk_failures.$(OBJEXT) \ - libarchive/test/test-test_write_disk_fixup.$(OBJEXT) \ - libarchive/test/test-test_write_disk_hardlink.$(OBJEXT) \ - libarchive/test/test-test_write_disk_hfs_compression.$(OBJEXT) \ - libarchive/test/test-test_write_disk_lookup.$(OBJEXT) \ - libarchive/test/test-test_write_disk_mac_metadata.$(OBJEXT) \ - libarchive/test/test-test_write_disk_no_hfs_compression.$(OBJEXT) \ - libarchive/test/test-test_write_disk_perms.$(OBJEXT) \ - libarchive/test/test-test_write_disk_secure.$(OBJEXT) \ - libarchive/test/test-test_write_disk_secure744.$(OBJEXT) \ - libarchive/test/test-test_write_disk_secure745.$(OBJEXT) \ - libarchive/test/test-test_write_disk_secure746.$(OBJEXT) \ - libarchive/test/test-test_write_disk_sparse.$(OBJEXT) \ - libarchive/test/test-test_write_disk_symlink.$(OBJEXT) \ - libarchive/test/test-test_write_disk_times.$(OBJEXT) \ - libarchive/test/test-test_write_filter_b64encode.$(OBJEXT) \ - libarchive/test/test-test_write_filter_bzip2.$(OBJEXT) \ - libarchive/test/test-test_write_filter_compress.$(OBJEXT) \ - libarchive/test/test-test_write_filter_gzip.$(OBJEXT) \ - libarchive/test/test-test_write_filter_gzip_timestamp.$(OBJEXT) \ - libarchive/test/test-test_write_filter_lrzip.$(OBJEXT) \ - libarchive/test/test-test_write_filter_lz4.$(OBJEXT) \ - libarchive/test/test-test_write_filter_lzip.$(OBJEXT) \ - libarchive/test/test-test_write_filter_lzma.$(OBJEXT) \ - libarchive/test/test-test_write_filter_lzop.$(OBJEXT) \ - libarchive/test/test-test_write_filter_program.$(OBJEXT) \ - libarchive/test/test-test_write_filter_uuencode.$(OBJEXT) \ - libarchive/test/test-test_write_filter_xz.$(OBJEXT) \ - libarchive/test/test-test_write_filter_zstd.$(OBJEXT) \ - libarchive/test/test-test_write_format_7zip.$(OBJEXT) \ - libarchive/test/test-test_write_format_7zip_empty.$(OBJEXT) \ - libarchive/test/test-test_write_format_7zip_large.$(OBJEXT) \ - libarchive/test/test-test_write_format_ar.$(OBJEXT) \ - libarchive/test/test-test_write_format_cpio.$(OBJEXT) \ - libarchive/test/test-test_write_format_cpio_empty.$(OBJEXT) \ - libarchive/test/test-test_write_format_cpio_newc.$(OBJEXT) \ - libarchive/test/test-test_write_format_cpio_odc.$(OBJEXT) \ - libarchive/test/test-test_write_format_gnutar.$(OBJEXT) \ - libarchive/test/test-test_write_format_gnutar_filenames.$(OBJEXT) \ - libarchive/test/test-test_write_format_iso9660.$(OBJEXT) \ - libarchive/test/test-test_write_format_iso9660_boot.$(OBJEXT) \ - libarchive/test/test-test_write_format_iso9660_empty.$(OBJEXT) \ - libarchive/test/test-test_write_format_iso9660_filename.$(OBJEXT) \ - libarchive/test/test-test_write_format_iso9660_zisofs.$(OBJEXT) \ - libarchive/test/test-test_write_format_mtree.$(OBJEXT) \ - libarchive/test/test-test_write_format_mtree_absolute_path.$(OBJEXT) \ - libarchive/test/test-test_write_format_mtree_classic.$(OBJEXT) \ - libarchive/test/test-test_write_format_mtree_classic_indent.$(OBJEXT) \ - libarchive/test/test-test_write_format_mtree_fflags.$(OBJEXT) \ - libarchive/test/test-test_write_format_mtree_no_separator.$(OBJEXT) \ - libarchive/test/test-test_write_format_mtree_quoted_filename.$(OBJEXT) \ - libarchive/test/test-test_write_format_pax.$(OBJEXT) \ - libarchive/test/test-test_write_format_raw.$(OBJEXT) \ - libarchive/test/test-test_write_format_raw_b64.$(OBJEXT) \ - libarchive/test/test-test_write_format_shar_empty.$(OBJEXT) \ - libarchive/test/test-test_write_format_tar.$(OBJEXT) \ - libarchive/test/test-test_write_format_tar_empty.$(OBJEXT) \ - libarchive/test/test-test_write_format_tar_sparse.$(OBJEXT) \ - libarchive/test/test-test_write_format_tar_ustar.$(OBJEXT) \ - libarchive/test/test-test_write_format_tar_v7tar.$(OBJEXT) \ - libarchive/test/test-test_write_format_warc.$(OBJEXT) \ - libarchive/test/test-test_write_format_warc_empty.$(OBJEXT) \ - libarchive/test/test-test_write_format_xar.$(OBJEXT) \ - libarchive/test/test-test_write_format_xar_empty.$(OBJEXT) \ - libarchive/test/test-test_write_format_zip.$(OBJEXT) \ - libarchive/test/test-test_write_format_zip_compression_store.$(OBJEXT) \ - libarchive/test/test-test_write_format_zip_entry_size_unset.$(OBJEXT) \ - libarchive/test/test-test_write_format_zip_empty.$(OBJEXT) \ - libarchive/test/test-test_write_format_zip_empty_zip64.$(OBJEXT) \ - libarchive/test/test-test_write_format_zip_file.$(OBJEXT) \ - libarchive/test/test-test_write_format_zip_file_zip64.$(OBJEXT) \ - libarchive/test/test-test_write_format_zip_large.$(OBJEXT) \ - libarchive/test/test-test_write_format_zip_zip64.$(OBJEXT) \ - libarchive/test/test-test_write_open_memory.$(OBJEXT) \ - libarchive/test/test-test_write_read_format_zip.$(OBJEXT) \ - libarchive/test/test-test_xattr_platform.$(OBJEXT) \ - libarchive/test/test-test_zip_filename_encoding.$(OBJEXT) -libarchive_test_OBJECTS = $(am_libarchive_test_OBJECTS) -libarchive_test_DEPENDENCIES = $(am__DEPENDENCIES_1) -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -depcomp = $(SHELL) $(top_srcdir)/build/autoconf/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = cat/$(DEPDIR)/bsdcat-bsdcat.Po \ - cat/$(DEPDIR)/bsdcat-cmdline.Po \ - cat/test/$(DEPDIR)/bsdcat_test-test_0.Po \ - cat/test/$(DEPDIR)/bsdcat_test-test_empty_gz.Po \ - cat/test/$(DEPDIR)/bsdcat_test-test_empty_lz4.Po \ - cat/test/$(DEPDIR)/bsdcat_test-test_empty_xz.Po \ - cat/test/$(DEPDIR)/bsdcat_test-test_empty_zstd.Po \ - cat/test/$(DEPDIR)/bsdcat_test-test_error.Po \ - cat/test/$(DEPDIR)/bsdcat_test-test_error_mixed.Po \ - cat/test/$(DEPDIR)/bsdcat_test-test_expand_Z.Po \ - cat/test/$(DEPDIR)/bsdcat_test-test_expand_bz2.Po \ - cat/test/$(DEPDIR)/bsdcat_test-test_expand_gz.Po \ - cat/test/$(DEPDIR)/bsdcat_test-test_expand_lz4.Po \ - cat/test/$(DEPDIR)/bsdcat_test-test_expand_mixed.Po \ - cat/test/$(DEPDIR)/bsdcat_test-test_expand_plain.Po \ - cat/test/$(DEPDIR)/bsdcat_test-test_expand_xz.Po \ - cat/test/$(DEPDIR)/bsdcat_test-test_expand_zstd.Po \ - cat/test/$(DEPDIR)/bsdcat_test-test_help.Po \ - cat/test/$(DEPDIR)/bsdcat_test-test_stdin.Po \ - cat/test/$(DEPDIR)/bsdcat_test-test_version.Po \ - cpio/$(DEPDIR)/bsdcpio-cmdline.Po \ - cpio/$(DEPDIR)/bsdcpio-cpio.Po \ - cpio/$(DEPDIR)/bsdcpio-cpio_windows.Po \ - cpio/$(DEPDIR)/bsdcpio_test-cmdline.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_0.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_basic.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_cmdline.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_Z.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_bz2.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_grz.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_gz.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lrz.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lz.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lz4.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lzma.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lzo.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_xz.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_zstd.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_format_newc.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_gcpio_compat.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_missing_file.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_0.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_B_upper.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_C_upper.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_J_upper.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_L_upper.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_Z_upper.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_a.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_b64encode.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_c.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_d.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_f.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_grzip.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_help.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_l.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lrzip.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lz4.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lzma.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lzop.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_m.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_passphrase.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_t.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_u.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_uuencode.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_version.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_xz.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_y.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_z.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_option_zstd.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_owner_parse.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_passthrough_dotdot.Po \ - cpio/test/$(DEPDIR)/bsdcpio_test-test_passthrough_reverse.Po \ - libarchive/$(DEPDIR)/archive_acl.Plo \ - libarchive/$(DEPDIR)/archive_blake2s_ref.Plo \ - libarchive/$(DEPDIR)/archive_blake2sp_ref.Plo \ - libarchive/$(DEPDIR)/archive_check_magic.Plo \ - libarchive/$(DEPDIR)/archive_cmdline.Plo \ - libarchive/$(DEPDIR)/archive_cryptor.Plo \ - libarchive/$(DEPDIR)/archive_digest.Plo \ - libarchive/$(DEPDIR)/archive_disk_acl_darwin.Plo \ - libarchive/$(DEPDIR)/archive_disk_acl_freebsd.Plo \ - libarchive/$(DEPDIR)/archive_disk_acl_linux.Plo \ - libarchive/$(DEPDIR)/archive_disk_acl_sunos.Plo \ - libarchive/$(DEPDIR)/archive_entry.Plo \ - libarchive/$(DEPDIR)/archive_entry_copy_bhfi.Plo \ - libarchive/$(DEPDIR)/archive_entry_copy_stat.Plo \ - libarchive/$(DEPDIR)/archive_entry_link_resolver.Plo \ - libarchive/$(DEPDIR)/archive_entry_sparse.Plo \ - libarchive/$(DEPDIR)/archive_entry_stat.Plo \ - libarchive/$(DEPDIR)/archive_entry_strmode.Plo \ - libarchive/$(DEPDIR)/archive_entry_xattr.Plo \ - libarchive/$(DEPDIR)/archive_getdate.Plo \ - libarchive/$(DEPDIR)/archive_hmac.Plo \ - libarchive/$(DEPDIR)/archive_match.Plo \ - libarchive/$(DEPDIR)/archive_options.Plo \ - libarchive/$(DEPDIR)/archive_pack_dev.Plo \ - libarchive/$(DEPDIR)/archive_pathmatch.Plo \ - libarchive/$(DEPDIR)/archive_ppmd7.Plo \ - libarchive/$(DEPDIR)/archive_ppmd8.Plo \ - libarchive/$(DEPDIR)/archive_random.Plo \ - libarchive/$(DEPDIR)/archive_rb.Plo \ - libarchive/$(DEPDIR)/archive_read.Plo \ - libarchive/$(DEPDIR)/archive_read_add_passphrase.Plo \ - libarchive/$(DEPDIR)/archive_read_append_filter.Plo \ - libarchive/$(DEPDIR)/archive_read_data_into_fd.Plo \ - libarchive/$(DEPDIR)/archive_read_disk_entry_from_file.Plo \ - libarchive/$(DEPDIR)/archive_read_disk_posix.Plo \ - libarchive/$(DEPDIR)/archive_read_disk_set_standard_lookup.Plo \ - libarchive/$(DEPDIR)/archive_read_disk_windows.Plo \ - libarchive/$(DEPDIR)/archive_read_extract.Plo \ - libarchive/$(DEPDIR)/archive_read_extract2.Plo \ - libarchive/$(DEPDIR)/archive_read_open_fd.Plo \ - libarchive/$(DEPDIR)/archive_read_open_file.Plo \ - libarchive/$(DEPDIR)/archive_read_open_filename.Plo \ - libarchive/$(DEPDIR)/archive_read_open_memory.Plo \ - libarchive/$(DEPDIR)/archive_read_set_format.Plo \ - libarchive/$(DEPDIR)/archive_read_set_options.Plo \ - libarchive/$(DEPDIR)/archive_read_support_filter_all.Plo \ - libarchive/$(DEPDIR)/archive_read_support_filter_by_code.Plo \ - libarchive/$(DEPDIR)/archive_read_support_filter_bzip2.Plo \ - libarchive/$(DEPDIR)/archive_read_support_filter_compress.Plo \ - libarchive/$(DEPDIR)/archive_read_support_filter_grzip.Plo \ - libarchive/$(DEPDIR)/archive_read_support_filter_gzip.Plo \ - libarchive/$(DEPDIR)/archive_read_support_filter_lrzip.Plo \ - libarchive/$(DEPDIR)/archive_read_support_filter_lz4.Plo \ - libarchive/$(DEPDIR)/archive_read_support_filter_lzop.Plo \ - libarchive/$(DEPDIR)/archive_read_support_filter_none.Plo \ - libarchive/$(DEPDIR)/archive_read_support_filter_program.Plo \ - libarchive/$(DEPDIR)/archive_read_support_filter_rpm.Plo \ - libarchive/$(DEPDIR)/archive_read_support_filter_uu.Plo \ - libarchive/$(DEPDIR)/archive_read_support_filter_xz.Plo \ - libarchive/$(DEPDIR)/archive_read_support_filter_zstd.Plo \ - libarchive/$(DEPDIR)/archive_read_support_format_7zip.Plo \ - libarchive/$(DEPDIR)/archive_read_support_format_all.Plo \ - libarchive/$(DEPDIR)/archive_read_support_format_ar.Plo \ - libarchive/$(DEPDIR)/archive_read_support_format_by_code.Plo \ - libarchive/$(DEPDIR)/archive_read_support_format_cab.Plo \ - libarchive/$(DEPDIR)/archive_read_support_format_cpio.Plo \ - libarchive/$(DEPDIR)/archive_read_support_format_empty.Plo \ - libarchive/$(DEPDIR)/archive_read_support_format_iso9660.Plo \ - libarchive/$(DEPDIR)/archive_read_support_format_lha.Plo \ - libarchive/$(DEPDIR)/archive_read_support_format_mtree.Plo \ - libarchive/$(DEPDIR)/archive_read_support_format_rar.Plo \ - libarchive/$(DEPDIR)/archive_read_support_format_rar5.Plo \ - libarchive/$(DEPDIR)/archive_read_support_format_raw.Plo \ - libarchive/$(DEPDIR)/archive_read_support_format_tar.Plo \ - libarchive/$(DEPDIR)/archive_read_support_format_warc.Plo \ - libarchive/$(DEPDIR)/archive_read_support_format_xar.Plo \ - libarchive/$(DEPDIR)/archive_read_support_format_zip.Plo \ - libarchive/$(DEPDIR)/archive_string.Plo \ - libarchive/$(DEPDIR)/archive_string_sprintf.Plo \ - libarchive/$(DEPDIR)/archive_util.Plo \ - libarchive/$(DEPDIR)/archive_version_details.Plo \ - libarchive/$(DEPDIR)/archive_virtual.Plo \ - libarchive/$(DEPDIR)/archive_windows.Plo \ - libarchive/$(DEPDIR)/archive_write.Plo \ - libarchive/$(DEPDIR)/archive_write_add_filter.Plo \ - libarchive/$(DEPDIR)/archive_write_add_filter_b64encode.Plo \ - libarchive/$(DEPDIR)/archive_write_add_filter_by_name.Plo \ - libarchive/$(DEPDIR)/archive_write_add_filter_bzip2.Plo \ - libarchive/$(DEPDIR)/archive_write_add_filter_compress.Plo \ - libarchive/$(DEPDIR)/archive_write_add_filter_grzip.Plo \ - libarchive/$(DEPDIR)/archive_write_add_filter_gzip.Plo \ - libarchive/$(DEPDIR)/archive_write_add_filter_lrzip.Plo \ - libarchive/$(DEPDIR)/archive_write_add_filter_lz4.Plo \ - libarchive/$(DEPDIR)/archive_write_add_filter_lzop.Plo \ - libarchive/$(DEPDIR)/archive_write_add_filter_none.Plo \ - libarchive/$(DEPDIR)/archive_write_add_filter_program.Plo \ - libarchive/$(DEPDIR)/archive_write_add_filter_uuencode.Plo \ - libarchive/$(DEPDIR)/archive_write_add_filter_xz.Plo \ - libarchive/$(DEPDIR)/archive_write_add_filter_zstd.Plo \ - libarchive/$(DEPDIR)/archive_write_disk_posix.Plo \ - libarchive/$(DEPDIR)/archive_write_disk_set_standard_lookup.Plo \ - libarchive/$(DEPDIR)/archive_write_disk_windows.Plo \ - libarchive/$(DEPDIR)/archive_write_open_fd.Plo \ - libarchive/$(DEPDIR)/archive_write_open_file.Plo \ - libarchive/$(DEPDIR)/archive_write_open_filename.Plo \ - libarchive/$(DEPDIR)/archive_write_open_memory.Plo \ - libarchive/$(DEPDIR)/archive_write_set_format.Plo \ - libarchive/$(DEPDIR)/archive_write_set_format_7zip.Plo \ - libarchive/$(DEPDIR)/archive_write_set_format_ar.Plo \ - libarchive/$(DEPDIR)/archive_write_set_format_by_name.Plo \ - libarchive/$(DEPDIR)/archive_write_set_format_cpio.Plo \ - libarchive/$(DEPDIR)/archive_write_set_format_cpio_binary.Plo \ - libarchive/$(DEPDIR)/archive_write_set_format_cpio_newc.Plo \ - libarchive/$(DEPDIR)/archive_write_set_format_cpio_odc.Plo \ - libarchive/$(DEPDIR)/archive_write_set_format_filter_by_ext.Plo \ - libarchive/$(DEPDIR)/archive_write_set_format_gnutar.Plo \ - libarchive/$(DEPDIR)/archive_write_set_format_iso9660.Plo \ - libarchive/$(DEPDIR)/archive_write_set_format_mtree.Plo \ - libarchive/$(DEPDIR)/archive_write_set_format_pax.Plo \ - libarchive/$(DEPDIR)/archive_write_set_format_raw.Plo \ - libarchive/$(DEPDIR)/archive_write_set_format_shar.Plo \ - libarchive/$(DEPDIR)/archive_write_set_format_ustar.Plo \ - libarchive/$(DEPDIR)/archive_write_set_format_v7tar.Plo \ - libarchive/$(DEPDIR)/archive_write_set_format_warc.Plo \ - libarchive/$(DEPDIR)/archive_write_set_format_xar.Plo \ - libarchive/$(DEPDIR)/archive_write_set_format_zip.Plo \ - libarchive/$(DEPDIR)/archive_write_set_options.Plo \ - libarchive/$(DEPDIR)/archive_write_set_passphrase.Plo \ - libarchive/$(DEPDIR)/filter_fork_posix.Plo \ - libarchive/$(DEPDIR)/filter_fork_windows.Plo \ - libarchive/$(DEPDIR)/test-archive_acl.Po \ - libarchive/$(DEPDIR)/test-archive_blake2s_ref.Po \ - libarchive/$(DEPDIR)/test-archive_blake2sp_ref.Po \ - libarchive/$(DEPDIR)/test-archive_check_magic.Po \ - libarchive/$(DEPDIR)/test-archive_cmdline.Po \ - libarchive/$(DEPDIR)/test-archive_cryptor.Po \ - libarchive/$(DEPDIR)/test-archive_digest.Po \ - libarchive/$(DEPDIR)/test-archive_disk_acl_darwin.Po \ - libarchive/$(DEPDIR)/test-archive_disk_acl_freebsd.Po \ - libarchive/$(DEPDIR)/test-archive_disk_acl_linux.Po \ - libarchive/$(DEPDIR)/test-archive_disk_acl_sunos.Po \ - libarchive/$(DEPDIR)/test-archive_entry.Po \ - libarchive/$(DEPDIR)/test-archive_entry_copy_bhfi.Po \ - libarchive/$(DEPDIR)/test-archive_entry_copy_stat.Po \ - libarchive/$(DEPDIR)/test-archive_entry_link_resolver.Po \ - libarchive/$(DEPDIR)/test-archive_entry_sparse.Po \ - libarchive/$(DEPDIR)/test-archive_entry_stat.Po \ - libarchive/$(DEPDIR)/test-archive_entry_strmode.Po \ - libarchive/$(DEPDIR)/test-archive_entry_xattr.Po \ - libarchive/$(DEPDIR)/test-archive_getdate.Po \ - libarchive/$(DEPDIR)/test-archive_hmac.Po \ - libarchive/$(DEPDIR)/test-archive_match.Po \ - libarchive/$(DEPDIR)/test-archive_options.Po \ - libarchive/$(DEPDIR)/test-archive_pack_dev.Po \ - libarchive/$(DEPDIR)/test-archive_pathmatch.Po \ - libarchive/$(DEPDIR)/test-archive_ppmd7.Po \ - libarchive/$(DEPDIR)/test-archive_ppmd8.Po \ - libarchive/$(DEPDIR)/test-archive_random.Po \ - libarchive/$(DEPDIR)/test-archive_rb.Po \ - libarchive/$(DEPDIR)/test-archive_read.Po \ - libarchive/$(DEPDIR)/test-archive_read_add_passphrase.Po \ - libarchive/$(DEPDIR)/test-archive_read_append_filter.Po \ - libarchive/$(DEPDIR)/test-archive_read_data_into_fd.Po \ - libarchive/$(DEPDIR)/test-archive_read_disk_entry_from_file.Po \ - libarchive/$(DEPDIR)/test-archive_read_disk_posix.Po \ - libarchive/$(DEPDIR)/test-archive_read_disk_set_standard_lookup.Po \ - libarchive/$(DEPDIR)/test-archive_read_disk_windows.Po \ - libarchive/$(DEPDIR)/test-archive_read_extract.Po \ - libarchive/$(DEPDIR)/test-archive_read_extract2.Po \ - libarchive/$(DEPDIR)/test-archive_read_open_fd.Po \ - libarchive/$(DEPDIR)/test-archive_read_open_file.Po \ - libarchive/$(DEPDIR)/test-archive_read_open_filename.Po \ - libarchive/$(DEPDIR)/test-archive_read_open_memory.Po \ - libarchive/$(DEPDIR)/test-archive_read_set_format.Po \ - libarchive/$(DEPDIR)/test-archive_read_set_options.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_filter_all.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_filter_by_code.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_filter_bzip2.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_filter_compress.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_filter_grzip.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_filter_gzip.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_filter_lrzip.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_filter_lz4.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_filter_lzop.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_filter_none.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_filter_program.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_filter_rpm.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_filter_uu.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_filter_xz.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_filter_zstd.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_format_7zip.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_format_all.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_format_ar.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_format_by_code.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_format_cab.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_format_cpio.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_format_empty.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_format_iso9660.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_format_lha.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_format_mtree.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_format_rar.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_format_rar5.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_format_raw.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_format_tar.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_format_warc.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_format_xar.Po \ - libarchive/$(DEPDIR)/test-archive_read_support_format_zip.Po \ - libarchive/$(DEPDIR)/test-archive_string.Po \ - libarchive/$(DEPDIR)/test-archive_string_sprintf.Po \ - libarchive/$(DEPDIR)/test-archive_util.Po \ - libarchive/$(DEPDIR)/test-archive_version_details.Po \ - libarchive/$(DEPDIR)/test-archive_virtual.Po \ - libarchive/$(DEPDIR)/test-archive_windows.Po \ - libarchive/$(DEPDIR)/test-archive_write.Po \ - libarchive/$(DEPDIR)/test-archive_write_add_filter.Po \ - libarchive/$(DEPDIR)/test-archive_write_add_filter_b64encode.Po \ - libarchive/$(DEPDIR)/test-archive_write_add_filter_by_name.Po \ - libarchive/$(DEPDIR)/test-archive_write_add_filter_bzip2.Po \ - libarchive/$(DEPDIR)/test-archive_write_add_filter_compress.Po \ - libarchive/$(DEPDIR)/test-archive_write_add_filter_grzip.Po \ - libarchive/$(DEPDIR)/test-archive_write_add_filter_gzip.Po \ - libarchive/$(DEPDIR)/test-archive_write_add_filter_lrzip.Po \ - libarchive/$(DEPDIR)/test-archive_write_add_filter_lz4.Po \ - libarchive/$(DEPDIR)/test-archive_write_add_filter_lzop.Po \ - libarchive/$(DEPDIR)/test-archive_write_add_filter_none.Po \ - libarchive/$(DEPDIR)/test-archive_write_add_filter_program.Po \ - libarchive/$(DEPDIR)/test-archive_write_add_filter_uuencode.Po \ - libarchive/$(DEPDIR)/test-archive_write_add_filter_xz.Po \ - libarchive/$(DEPDIR)/test-archive_write_add_filter_zstd.Po \ - libarchive/$(DEPDIR)/test-archive_write_disk_posix.Po \ - libarchive/$(DEPDIR)/test-archive_write_disk_set_standard_lookup.Po \ - libarchive/$(DEPDIR)/test-archive_write_disk_windows.Po \ - libarchive/$(DEPDIR)/test-archive_write_open_fd.Po \ - libarchive/$(DEPDIR)/test-archive_write_open_file.Po \ - libarchive/$(DEPDIR)/test-archive_write_open_filename.Po \ - libarchive/$(DEPDIR)/test-archive_write_open_memory.Po \ - libarchive/$(DEPDIR)/test-archive_write_set_format.Po \ - libarchive/$(DEPDIR)/test-archive_write_set_format_7zip.Po \ - libarchive/$(DEPDIR)/test-archive_write_set_format_ar.Po \ - libarchive/$(DEPDIR)/test-archive_write_set_format_by_name.Po \ - libarchive/$(DEPDIR)/test-archive_write_set_format_cpio.Po \ - libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_binary.Po \ - libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_newc.Po \ - libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_odc.Po \ - libarchive/$(DEPDIR)/test-archive_write_set_format_filter_by_ext.Po \ - libarchive/$(DEPDIR)/test-archive_write_set_format_gnutar.Po \ - libarchive/$(DEPDIR)/test-archive_write_set_format_iso9660.Po \ - libarchive/$(DEPDIR)/test-archive_write_set_format_mtree.Po \ - libarchive/$(DEPDIR)/test-archive_write_set_format_pax.Po \ - libarchive/$(DEPDIR)/test-archive_write_set_format_raw.Po \ - libarchive/$(DEPDIR)/test-archive_write_set_format_shar.Po \ - libarchive/$(DEPDIR)/test-archive_write_set_format_ustar.Po \ - libarchive/$(DEPDIR)/test-archive_write_set_format_v7tar.Po \ - libarchive/$(DEPDIR)/test-archive_write_set_format_warc.Po \ - libarchive/$(DEPDIR)/test-archive_write_set_format_xar.Po \ - libarchive/$(DEPDIR)/test-archive_write_set_format_zip.Po \ - libarchive/$(DEPDIR)/test-archive_write_set_options.Po \ - libarchive/$(DEPDIR)/test-archive_write_set_passphrase.Po \ - libarchive/$(DEPDIR)/test-filter_fork_posix.Po \ - libarchive/$(DEPDIR)/test-filter_fork_windows.Po \ - libarchive/$(DEPDIR)/test-xxhash.Po \ - libarchive/$(DEPDIR)/xxhash.Plo \ - libarchive/test/$(DEPDIR)/test-read_open_memory.Po \ - libarchive/test/$(DEPDIR)/test-test_acl_nfs4.Po \ - libarchive/test/$(DEPDIR)/test-test_acl_pax.Po \ - libarchive/test/$(DEPDIR)/test-test_acl_platform_nfs4.Po \ - libarchive/test/$(DEPDIR)/test-test_acl_platform_posix1e.Po \ - libarchive/test/$(DEPDIR)/test-test_acl_posix1e.Po \ - libarchive/test/$(DEPDIR)/test-test_acl_text.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_api_feature.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_clear_error.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_cmdline.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_digest.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_getdate.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_match_owner.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_match_path.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_match_time.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_pathmatch.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_read_add_passphrase.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice_open_fd.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice_open_filename.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_read_multiple_data_objects.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_read_next_header_empty.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_read_next_header_raw.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_read_open2.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_read_set_filter_option.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_read_set_format_option.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_read_set_option.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_read_set_options.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_read_support.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_set_error.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_string.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_string_conversion.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_write_add_filter_by_name.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_write_set_filter_option.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_by_name.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_filter_by_ext.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_option.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_write_set_option.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_write_set_options.Po \ - libarchive/test/$(DEPDIR)/test-test_archive_write_set_passphrase.Po \ - libarchive/test/$(DEPDIR)/test-test_bad_fd.Po \ - libarchive/test/$(DEPDIR)/test-test_compat_bzip2.Po \ - libarchive/test/$(DEPDIR)/test-test_compat_cpio.Po \ - libarchive/test/$(DEPDIR)/test-test_compat_gtar.Po \ - libarchive/test/$(DEPDIR)/test-test_compat_gzip.Po \ - libarchive/test/$(DEPDIR)/test-test_compat_lz4.Po \ - libarchive/test/$(DEPDIR)/test-test_compat_lzip.Po \ - libarchive/test/$(DEPDIR)/test-test_compat_lzma.Po \ - libarchive/test/$(DEPDIR)/test-test_compat_lzop.Po \ - libarchive/test/$(DEPDIR)/test-test_compat_mac.Po \ - libarchive/test/$(DEPDIR)/test-test_compat_perl_archive_tar.Po \ - libarchive/test/$(DEPDIR)/test-test_compat_plexus_archiver_tar.Po \ - libarchive/test/$(DEPDIR)/test-test_compat_solaris_pax_sparse.Po \ - libarchive/test/$(DEPDIR)/test-test_compat_solaris_tar_acl.Po \ - libarchive/test/$(DEPDIR)/test-test_compat_star_acl.Po \ - libarchive/test/$(DEPDIR)/test-test_compat_tar_directory.Po \ - libarchive/test/$(DEPDIR)/test-test_compat_tar_hardlink.Po \ - libarchive/test/$(DEPDIR)/test-test_compat_uudecode.Po \ - libarchive/test/$(DEPDIR)/test-test_compat_uudecode_large.Po \ - libarchive/test/$(DEPDIR)/test-test_compat_xz.Po \ - libarchive/test/$(DEPDIR)/test-test_compat_zip.Po \ - libarchive/test/$(DEPDIR)/test-test_compat_zstd.Po \ - libarchive/test/$(DEPDIR)/test-test_empty_write.Po \ - libarchive/test/$(DEPDIR)/test-test_entry.Po \ - libarchive/test/$(DEPDIR)/test-test_entry_strmode.Po \ - libarchive/test/$(DEPDIR)/test-test_extattr_freebsd.Po \ - libarchive/test/$(DEPDIR)/test-test_filter_count.Po \ - libarchive/test/$(DEPDIR)/test-test_fuzz.Po \ - libarchive/test/$(DEPDIR)/test-test_gnutar_filename_encoding.Po \ - libarchive/test/$(DEPDIR)/test-test_link_resolver.Po \ - libarchive/test/$(DEPDIR)/test-test_open_failure.Po \ - libarchive/test/$(DEPDIR)/test-test_open_fd.Po \ - libarchive/test/$(DEPDIR)/test-test_open_file.Po \ - libarchive/test/$(DEPDIR)/test-test_open_filename.Po \ - libarchive/test/$(DEPDIR)/test-test_pax_filename_encoding.Po \ - libarchive/test/$(DEPDIR)/test-test_pax_xattr_header.Po \ - libarchive/test/$(DEPDIR)/test-test_read_data_large.Po \ - libarchive/test/$(DEPDIR)/test-test_read_disk.Po \ - libarchive/test/$(DEPDIR)/test-test_read_disk_directory_traversals.Po \ - libarchive/test/$(DEPDIR)/test-test_read_disk_entry_from_file.Po \ - libarchive/test/$(DEPDIR)/test-test_read_extract.Po \ - libarchive/test/$(DEPDIR)/test-test_read_file_nonexistent.Po \ - libarchive/test/$(DEPDIR)/test-test_read_filter_compress.Po \ - libarchive/test/$(DEPDIR)/test-test_read_filter_grzip.Po \ - libarchive/test/$(DEPDIR)/test-test_read_filter_lrzip.Po \ - libarchive/test/$(DEPDIR)/test-test_read_filter_lzop.Po \ - libarchive/test/$(DEPDIR)/test-test_read_filter_lzop_multiple_parts.Po \ - libarchive/test/$(DEPDIR)/test-test_read_filter_program.Po \ - libarchive/test/$(DEPDIR)/test-test_read_filter_program_signature.Po \ - libarchive/test/$(DEPDIR)/test-test_read_filter_uudecode.Po \ - libarchive/test/$(DEPDIR)/test-test_read_filter_uudecode_raw.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_7zip.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_data.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_header.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_partially.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_7zip_malformed.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_7zip_packinfo_digests.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_ar.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_cab.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_cab_filename.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_cpio_afio.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_Z.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_be.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_bz2.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_gz.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_le.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_lzip.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_lzma.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_xz.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_cpio_filename.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_cpio_odc.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_bzip2_rpm.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_gzip.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_gzip_rpm.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4c_Z.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_empty.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_gtar_filename.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_gtar_gz.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_gtar_lzma.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_gtar_sparse.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_gtar_sparse_skip_entry.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_iso_Z.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_iso_multi_extent.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_iso_xorriso.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_bz2.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_long.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_rr.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_versioned.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_isorr_bz2.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_isorr_ce.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_isorr_new_bz2.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_isorr_rr_moved.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_isozisofs_bz2.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_lha.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_lha_bugfix_0.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_lha_filename.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_lha_filename_utf16.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_mtree.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_mtree_crash747.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_pax_bz2.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_rar.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_rar5.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_data.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_header.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_partially.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_rar_filter.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_rar_invalid1.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_raw.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_tar.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_tar_concatenated.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_filename.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_pax.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_with_gnulabel.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_tar_filename.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_tar_invalid_pax_size.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_tbz.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_tgz.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_tlz.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_txz.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_tz.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_ustar_filename.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_warc.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_xar.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_zip.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_zip_7075_utf8_paths.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_zip_comment_stored.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_data.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_header.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_partially.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_zip_extra_padding.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_zip_filename.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_zip_high_compression.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_zip_jar.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_zip_mac_metadata.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_zip_malformed.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_zip_msdos.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_zip_nested.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_zip_nofiletype.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_zip_padded.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_zip_sfx.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_zip_traditional_encryption_data.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_zip_winzip_aes.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_zip_winzip_aes_large.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_zip_with_invalid_traditional_eocd.Po \ - libarchive/test/$(DEPDIR)/test-test_read_format_zip_zip64.Po \ - libarchive/test/$(DEPDIR)/test-test_read_large.Po \ - libarchive/test/$(DEPDIR)/test-test_read_pax_truncated.Po \ - libarchive/test/$(DEPDIR)/test-test_read_pax_xattr_rht_security_selinux.Po \ - libarchive/test/$(DEPDIR)/test-test_read_pax_xattr_schily.Po \ - libarchive/test/$(DEPDIR)/test-test_read_position.Po \ - libarchive/test/$(DEPDIR)/test-test_read_set_format.Po \ - libarchive/test/$(DEPDIR)/test-test_read_too_many_filters.Po \ - libarchive/test/$(DEPDIR)/test-test_read_truncated.Po \ - libarchive/test/$(DEPDIR)/test-test_read_truncated_filter.Po \ - libarchive/test/$(DEPDIR)/test-test_short_writes.Po \ - libarchive/test/$(DEPDIR)/test-test_sparse_basic.Po \ - libarchive/test/$(DEPDIR)/test-test_tar_filenames.Po \ - libarchive/test/$(DEPDIR)/test-test_tar_large.Po \ - libarchive/test/$(DEPDIR)/test-test_ustar_filename_encoding.Po \ - libarchive/test/$(DEPDIR)/test-test_ustar_filenames.Po \ - libarchive/test/$(DEPDIR)/test-test_warn_missing_hardlink_target.Po \ - libarchive/test/$(DEPDIR)/test-test_write_disk.Po \ - libarchive/test/$(DEPDIR)/test-test_write_disk_appledouble.Po \ - libarchive/test/$(DEPDIR)/test-test_write_disk_failures.Po \ - libarchive/test/$(DEPDIR)/test-test_write_disk_fixup.Po \ - libarchive/test/$(DEPDIR)/test-test_write_disk_hardlink.Po \ - libarchive/test/$(DEPDIR)/test-test_write_disk_hfs_compression.Po \ - libarchive/test/$(DEPDIR)/test-test_write_disk_lookup.Po \ - libarchive/test/$(DEPDIR)/test-test_write_disk_mac_metadata.Po \ - libarchive/test/$(DEPDIR)/test-test_write_disk_no_hfs_compression.Po \ - libarchive/test/$(DEPDIR)/test-test_write_disk_perms.Po \ - libarchive/test/$(DEPDIR)/test-test_write_disk_secure.Po \ - libarchive/test/$(DEPDIR)/test-test_write_disk_secure744.Po \ - libarchive/test/$(DEPDIR)/test-test_write_disk_secure745.Po \ - libarchive/test/$(DEPDIR)/test-test_write_disk_secure746.Po \ - libarchive/test/$(DEPDIR)/test-test_write_disk_sparse.Po \ - libarchive/test/$(DEPDIR)/test-test_write_disk_symlink.Po \ - libarchive/test/$(DEPDIR)/test-test_write_disk_times.Po \ - libarchive/test/$(DEPDIR)/test-test_write_filter_b64encode.Po \ - libarchive/test/$(DEPDIR)/test-test_write_filter_bzip2.Po \ - libarchive/test/$(DEPDIR)/test-test_write_filter_compress.Po \ - libarchive/test/$(DEPDIR)/test-test_write_filter_gzip.Po \ - libarchive/test/$(DEPDIR)/test-test_write_filter_gzip_timestamp.Po \ - libarchive/test/$(DEPDIR)/test-test_write_filter_lrzip.Po \ - libarchive/test/$(DEPDIR)/test-test_write_filter_lz4.Po \ - libarchive/test/$(DEPDIR)/test-test_write_filter_lzip.Po \ - libarchive/test/$(DEPDIR)/test-test_write_filter_lzma.Po \ - libarchive/test/$(DEPDIR)/test-test_write_filter_lzop.Po \ - libarchive/test/$(DEPDIR)/test-test_write_filter_program.Po \ - libarchive/test/$(DEPDIR)/test-test_write_filter_uuencode.Po \ - libarchive/test/$(DEPDIR)/test-test_write_filter_xz.Po \ - libarchive/test/$(DEPDIR)/test-test_write_filter_zstd.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_7zip.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_7zip_empty.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_7zip_large.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_ar.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_cpio.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_cpio_empty.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_cpio_newc.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_cpio_odc.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_gnutar.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_gnutar_filenames.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_iso9660.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_boot.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_empty.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_filename.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_zisofs.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_mtree.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_mtree_absolute_path.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_mtree_classic.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_mtree_classic_indent.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_mtree_fflags.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_mtree_no_separator.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_mtree_quoted_filename.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_pax.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_raw.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_raw_b64.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_shar_empty.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_tar.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_tar_empty.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_tar_sparse.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_tar_ustar.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_tar_v7tar.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_warc.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_warc_empty.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_xar.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_xar_empty.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_zip.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_zip_compression_store.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_zip_empty.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_zip_empty_zip64.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_zip_entry_size_unset.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_zip_file.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_zip_file_zip64.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_zip_large.Po \ - libarchive/test/$(DEPDIR)/test-test_write_format_zip_zip64.Po \ - libarchive/test/$(DEPDIR)/test-test_write_open_memory.Po \ - libarchive/test/$(DEPDIR)/test-test_write_read_format_zip.Po \ - libarchive/test/$(DEPDIR)/test-test_xattr_platform.Po \ - libarchive/test/$(DEPDIR)/test-test_zip_filename_encoding.Po \ - libarchive_fe/$(DEPDIR)/la-err.Plo \ - libarchive_fe/$(DEPDIR)/la-line_reader.Plo \ - libarchive_fe/$(DEPDIR)/la-passphrase.Plo \ - tar/$(DEPDIR)/bsdtar-bsdtar.Po \ - tar/$(DEPDIR)/bsdtar-bsdtar_windows.Po \ - tar/$(DEPDIR)/bsdtar-cmdline.Po \ - tar/$(DEPDIR)/bsdtar-creation_set.Po \ - tar/$(DEPDIR)/bsdtar-read.Po tar/$(DEPDIR)/bsdtar-subst.Po \ - tar/$(DEPDIR)/bsdtar-util.Po tar/$(DEPDIR)/bsdtar-write.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_0.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_basic.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_copy.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_empty_mtree.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_Z.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_bz2.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_grz.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_gz.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lrz.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lz.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lz4.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lzma.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lzo.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_xz.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_zstd.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_format_newc.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_help.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_leading_slash.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_missing_file.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_C_mtree.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_C_upper.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_H_upper.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_L_upper.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_O_upper.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_T_upper.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_U_upper.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_X_upper.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_a.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_acls.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_b.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_b64encode.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_exclude.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_exclude_vcs.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_fflags.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_gid_gname.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_grzip.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_ignore_zeros.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_j.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_k.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_keep_newer_files.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_lrzip.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_lz4.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_lzma.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_lzop.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_n.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_newer_than.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_nodump.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_older_than.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_passphrase.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_q.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_r.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_s.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_safe_writes.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_uid_uname.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_uuencode.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_xattrs.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_xz.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_z.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_option_zstd.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_patterns.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_print_longpath.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_stdio.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_strip_components.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_symlink_dir.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_version.Po \ - tar/test/$(DEPDIR)/bsdtar_test-test_windows.Po \ - test_utils/$(DEPDIR)/bsdcat_test-test_main.Po \ - test_utils/$(DEPDIR)/bsdcat_test-test_utils.Po \ - test_utils/$(DEPDIR)/bsdcpio_test-test_main.Po \ - test_utils/$(DEPDIR)/bsdcpio_test-test_utils.Po \ - test_utils/$(DEPDIR)/bsdtar_test-test_main.Po \ - test_utils/$(DEPDIR)/bsdtar_test-test_utils.Po \ - test_utils/$(DEPDIR)/bsdunzip_test-test_main.Po \ - test_utils/$(DEPDIR)/bsdunzip_test-test_utils.Po \ - test_utils/$(DEPDIR)/libarchive_test-test_main.Po \ - test_utils/$(DEPDIR)/libarchive_test-test_utils.Po \ - unzip/$(DEPDIR)/bsdunzip-bsdunzip.Po \ - unzip/$(DEPDIR)/bsdunzip-cmdline.Po \ - unzip/$(DEPDIR)/bsdunzip-la_getline.Po \ - unzip/test/$(DEPDIR)/bsdunzip_test-test_0.Po \ - unzip/test/$(DEPDIR)/bsdunzip_test-test_C.Po \ - unzip/test/$(DEPDIR)/bsdunzip_test-test_L.Po \ - unzip/test/$(DEPDIR)/bsdunzip_test-test_P_encryption.Po \ - unzip/test/$(DEPDIR)/bsdunzip_test-test_Z1.Po \ - unzip/test/$(DEPDIR)/bsdunzip_test-test_basic.Po \ - unzip/test/$(DEPDIR)/bsdunzip_test-test_d.Po \ - unzip/test/$(DEPDIR)/bsdunzip_test-test_glob.Po \ - unzip/test/$(DEPDIR)/bsdunzip_test-test_j.Po \ - unzip/test/$(DEPDIR)/bsdunzip_test-test_n.Po \ - unzip/test/$(DEPDIR)/bsdunzip_test-test_not_exist.Po \ - unzip/test/$(DEPDIR)/bsdunzip_test-test_o.Po \ - unzip/test/$(DEPDIR)/bsdunzip_test-test_p.Po \ - unzip/test/$(DEPDIR)/bsdunzip_test-test_q.Po \ - unzip/test/$(DEPDIR)/bsdunzip_test-test_singlefile.Po \ - unzip/test/$(DEPDIR)/bsdunzip_test-test_t.Po \ - unzip/test/$(DEPDIR)/bsdunzip_test-test_t_bad.Po \ - unzip/test/$(DEPDIR)/bsdunzip_test-test_version.Po \ - unzip/test/$(DEPDIR)/bsdunzip_test-test_x.Po -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(libarchive_la_SOURCES) $(libarchive_fe_la_SOURCES) \ - $(bsdcat_SOURCES) $(bsdcat_test_SOURCES) $(bsdcpio_SOURCES) \ - $(bsdcpio_test_SOURCES) $(bsdtar_SOURCES) \ - $(bsdtar_test_SOURCES) $(bsdunzip_SOURCES) \ - $(bsdunzip_test_SOURCES) $(libarchive_test_SOURCES) -DIST_SOURCES = $(am__libarchive_la_SOURCES_DIST) \ - $(libarchive_fe_la_SOURCES) $(bsdcat_SOURCES) \ - $(bsdcat_test_SOURCES) $(am__bsdcpio_SOURCES_DIST) \ - $(bsdcpio_test_SOURCES) $(am__bsdtar_SOURCES_DIST) \ - $(bsdtar_test_SOURCES) $(bsdunzip_SOURCES) \ - $(bsdunzip_test_SOURCES) $(am__libarchive_test_SOURCES_DIST) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -man1dir = $(mandir)/man1 -man3dir = $(mandir)/man3 -man5dir = $(mandir)/man5 -NROFF = nroff -MANS = $(man_MANS) -DATA = $(pkgconfig_DATA) -HEADERS = $(include_HEADERS) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ - config.h.in -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -AM_RECURSIVE_TARGETS = cscope check recheck -am__tty_colors_dummy = \ - mgn= red= grn= lgn= blu= brg= std=; \ - am__color_tests=no -am__tty_colors = { \ - $(am__tty_colors_dummy); \ - if test "X$(AM_COLOR_TESTS)" = Xno; then \ - am__color_tests=no; \ - elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ - am__color_tests=yes; \ - elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ - am__color_tests=yes; \ - fi; \ - if test $$am__color_tests = yes; then \ - red=''; \ - grn=''; \ - lgn=''; \ - blu=''; \ - mgn=''; \ - brg=''; \ - std=''; \ - fi; \ -} -am__recheck_rx = ^[ ]*:recheck:[ ]* -am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* -am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* -# A command that, given a newline-separated list of test names on the -# standard input, print the name of the tests that are to be re-run -# upon "make recheck". -am__list_recheck_tests = $(AWK) '{ \ - recheck = 1; \ - while ((rc = (getline line < ($$0 ".trs"))) != 0) \ - { \ - if (rc < 0) \ - { \ - if ((getline line2 < ($$0 ".log")) < 0) \ - recheck = 0; \ - break; \ - } \ - else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ - { \ - recheck = 0; \ - break; \ - } \ - else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ - { \ - break; \ - } \ - }; \ - if (recheck) \ - print $$0; \ - close ($$0 ".trs"); \ - close ($$0 ".log"); \ -}' -# A command that, given a newline-separated list of test names on the -# standard input, create the global log from their .trs and .log files. -am__create_global_log = $(AWK) ' \ -function fatal(msg) \ -{ \ - print "fatal: making $@: " msg | "cat >&2"; \ - exit 1; \ -} \ -function rst_section(header) \ -{ \ - print header; \ - len = length(header); \ - for (i = 1; i <= len; i = i + 1) \ - printf "="; \ - printf "\n\n"; \ -} \ -{ \ - copy_in_global_log = 1; \ - global_test_result = "RUN"; \ - while ((rc = (getline line < ($$0 ".trs"))) != 0) \ - { \ - if (rc < 0) \ - fatal("failed to read from " $$0 ".trs"); \ - if (line ~ /$(am__global_test_result_rx)/) \ - { \ - sub("$(am__global_test_result_rx)", "", line); \ - sub("[ ]*$$", "", line); \ - global_test_result = line; \ - } \ - else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ - copy_in_global_log = 0; \ - }; \ - if (copy_in_global_log) \ - { \ - rst_section(global_test_result ": " $$0); \ - while ((rc = (getline line < ($$0 ".log"))) != 0) \ - { \ - if (rc < 0) \ - fatal("failed to read from " $$0 ".log"); \ - print line; \ - }; \ - printf "\n"; \ - }; \ - close ($$0 ".trs"); \ - close ($$0 ".log"); \ -}' -# Restructured Text title. -am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } -# Solaris 10 'make', and several other traditional 'make' implementations, -# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it -# by disabling -e (using the XSI extension "set +e") if it's set. -am__sh_e_setup = case $$- in *e*) set +e;; esac -# Default flags passed to test drivers. -am__common_driver_flags = \ - --color-tests "$$am__color_tests" \ - --enable-hard-errors "$$am__enable_hard_errors" \ - --expect-failure "$$am__expect_failure" -# To be inserted before the command running the test. Creates the -# directory for the log if needed. Stores in $dir the directory -# containing $f, in $tst the test, in $log the log. Executes the -# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and -# passes TESTS_ENVIRONMENT. Set up options for the wrapper that -# will run the test scripts (or their associated LOG_COMPILER, if -# thy have one). -am__check_pre = \ -$(am__sh_e_setup); \ -$(am__vpath_adj_setup) $(am__vpath_adj) \ -$(am__tty_colors); \ -srcdir=$(srcdir); export srcdir; \ -case "$@" in \ - */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ - *) am__odir=.;; \ -esac; \ -test "x$$am__odir" = x"." || test -d "$$am__odir" \ - || $(MKDIR_P) "$$am__odir" || exit $$?; \ -if test -f "./$$f"; then dir=./; \ -elif test -f "$$f"; then dir=; \ -else dir="$(srcdir)/"; fi; \ -tst=$$dir$$f; log='$@'; \ -if test -n '$(DISABLE_HARD_ERRORS)'; then \ - am__enable_hard_errors=no; \ -else \ - am__enable_hard_errors=yes; \ -fi; \ -case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ - am__expect_failure=yes;; \ - *) \ - am__expect_failure=no;; \ -esac; \ -$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) -# A shell command to get the names of the tests scripts with any registered -# extension removed (i.e., equivalently, the names of the test logs, with -# the '.log' extension removed). The result is saved in the shell variable -# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, -# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", -# since that might cause problem with VPATH rewrites for suffix-less tests. -# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. -am__set_TESTS_bases = \ - bases='$(TEST_LOGS)'; \ - bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ - bases=`echo $$bases` -AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' -RECHECK_LOGS = $(TEST_LOGS) -TEST_SUITE_LOG = test-suite.log -TEST_EXTENSIONS = @EXEEXT@ .test -LOG_DRIVER = $(SHELL) $(top_srcdir)/build/autoconf/test-driver -LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) -am__set_b = \ - case '$@' in \ - */*) \ - case '$*' in \ - */*) b='$*';; \ - *) b=`echo '$@' | sed 's/\.log$$//'`; \ - esac;; \ - *) \ - b='$*';; \ - esac -am__test_logs1 = $(TESTS:=.log) -am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) -TEST_LOGS = $(am__test_logs2:.test.log=.log) -TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build/autoconf/test-driver -TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ - $(TEST_LOG_FLAGS) -am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \ - $(top_srcdir)/build/autoconf/compile \ - $(top_srcdir)/build/autoconf/config.guess \ - $(top_srcdir)/build/autoconf/config.rpath \ - $(top_srcdir)/build/autoconf/config.sub \ - $(top_srcdir)/build/autoconf/depcomp \ - $(top_srcdir)/build/autoconf/install-sh \ - $(top_srcdir)/build/autoconf/ltmain.sh \ - $(top_srcdir)/build/autoconf/missing \ - $(top_srcdir)/build/autoconf/test-driver \ - $(top_srcdir)/build/pkgconfig/libarchive.pc.in COPYING INSTALL \ - NEWS README.md build/autoconf/compile \ - build/autoconf/config.guess build/autoconf/config.rpath \ - build/autoconf/config.sub build/autoconf/depcomp \ - build/autoconf/install-sh build/autoconf/ltmain.sh \ - build/autoconf/missing -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -distdir = $(PACKAGE)-$(VERSION) -top_distdir = $(distdir) -am__remove_distdir = \ - if test -d "$(distdir)"; then \ - find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ - && rm -rf "$(distdir)" \ - || { sleep 5 && rm -rf "$(distdir)"; }; \ - else :; fi -am__post_remove_distdir = $(am__remove_distdir) -DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.xz $(distdir).zip -GZIP_ENV = --best -DIST_TARGETS = dist-xz dist-gzip dist-zip -# Exists only to be overridden by the user if desired. -AM_DISTCHECK_DVI_TARGET = dvi -distuninstallcheck_listfiles = find . -type f -print -am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ - | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' -distcleancheck_listfiles = find . -type f -print -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -ARCHIVE_LIBTOOL_VERSION = @ARCHIVE_LIBTOOL_VERSION@ -AS = @AS@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -BSDCAT_VERSION_STRING = @BSDCAT_VERSION_STRING@ -BSDCPIO_VERSION_STRING = @BSDCPIO_VERSION_STRING@ -BSDTAR_VERSION_STRING = @BSDTAR_VERSION_STRING@ -BSDUNZIP_VERSION_STRING = @BSDUNZIP_VERSION_STRING@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CSCOPE = @CSCOPE@ -CTAGS = @CTAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -ETAGS = @ETAGS@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GC_SECTIONS = @GC_SECTIONS@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBARCHIVE_VERSION_NUMBER = @LIBARCHIVE_VERSION_NUMBER@ -LIBARCHIVE_VERSION_STRING = @LIBARCHIVE_VERSION_STRING@ -LIBICONV = @LIBICONV@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBSREQUIRED = @LIBSREQUIRED@ -LIBTOOL = @LIBTOOL@ -LIBXML2_PC_CFLAGS = @LIBXML2_PC_CFLAGS@ -LIBXML2_PC_LIBS = @LIBXML2_PC_LIBS@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBICONV = @LTLIBICONV@ -LTLIBOBJS = @LTLIBOBJS@ -LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PKG_CONFIG = @PKG_CONFIG@ -PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ -PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ -PLATFORMCPPFLAGS = @PLATFORMCPPFLAGS@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -runstatedir = @runstatedir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -AUTOMAKE_OPTIONS = foreign subdir-objects -ACLOCAL_AMFLAGS = -I build/autoconf - -# -# What to build and install -# -lib_LTLIBRARIES = libarchive.la -noinst_LTLIBRARIES = libarchive_fe.la -man_MANS = $(libarchive_man_MANS) $(bsdtar_man_MANS) $(bsdcpio_man_MANS) $(bsdcat_man_MANS) $(bsdunzip_man_MANS) -BUILT_SOURCES = libarchive/test/list.h tar/test/list.h cpio/test/list.h cat/test/list.h unzip/test/list.h -TESTS_ENVIRONMENT = $(libarchive_TESTS_ENVIRONMENT) $(bsdtar_TESTS_ENVIRONMENT) $(bsdcpio_TESTS_ENVIRONMENT) $(bsdcat_TESTS_ENVIRONMENT) $(bsdunzip_TESTS_ENVIRONMENT) -# Always build and test both bsdtar and bsdcpio as part of 'distcheck' -DISTCHECK_CONFIGURE_FLAGS = --enable-bsdtar --enable-bsdcpio -# The next line is commented out by default in shipping libarchive releases. -# It is uncommented by default in trunk. -# DEV_CFLAGS=-Werror -Wextra -Wunused -Wshadow -Wmissing-prototypes -Wcast-qual -g -AM_CFLAGS = $(DEV_CFLAGS) -AM_CPPFLAGS = $(PLATFORMCPPFLAGS) - -# -# What to include in the distribution -# -EXTRA_DIST = \ - CMakeLists.txt \ - README.md \ - build/autogen.sh \ - build/bump-version.sh \ - build/clean.sh \ - build/cmake \ - build/version \ - contrib \ - doc \ - examples \ - $(libarchive_EXTRA_DIST) \ - $(libarchive_test_EXTRA_DIST) \ - $(bsdtar_EXTRA_DIST) \ - $(bsdtar_test_EXTRA_DIST) \ - $(bsdcpio_EXTRA_DIST) \ - $(bsdcpio_test_EXTRA_DIST) \ - $(bsdcat_EXTRA_DIST) \ - $(bsdcat_test_EXTRA_DIST) \ - $(bsdunzip_EXTRA_DIST) \ - $(bsdunzip_test_EXTRA_DIST) - - -# -# Extra rules for cleanup -# -DISTCLEANFILES = \ - libarchive/test/list.h \ - tar/test/list.h \ - cpio/test/list.h \ - cat/test/list.h \ - unzip/test/list.h - - -# -# Libarchive headers, source, etc. -# -# -include_HEADERS = libarchive/archive.h libarchive/archive_entry.h -libarchive_la_SOURCES = libarchive/archive_acl.c \ - libarchive/archive_acl_private.h \ - libarchive/archive_check_magic.c libarchive/archive_cmdline.c \ - libarchive/archive_cmdline_private.h \ - libarchive/archive_crc32.h libarchive/archive_cryptor.c \ - libarchive/archive_cryptor_private.h \ - libarchive/archive_digest.c \ - libarchive/archive_digest_private.h \ - libarchive/archive_endian.h libarchive/archive_entry.c \ - libarchive/archive_entry.h \ - libarchive/archive_entry_copy_stat.c \ - libarchive/archive_entry_link_resolver.c \ - libarchive/archive_entry_locale.h \ - libarchive/archive_entry_private.h \ - libarchive/archive_entry_sparse.c \ - libarchive/archive_entry_stat.c \ - libarchive/archive_entry_strmode.c \ - libarchive/archive_entry_xattr.c libarchive/archive_getdate.c \ - libarchive/archive_getdate.h libarchive/archive_hmac.c \ - libarchive/archive_hmac_private.h libarchive/archive_match.c \ - libarchive/archive_openssl_evp_private.h \ - libarchive/archive_openssl_hmac_private.h \ - libarchive/archive_options.c \ - libarchive/archive_options_private.h \ - libarchive/archive_pack_dev.h libarchive/archive_pack_dev.c \ - libarchive/archive_pathmatch.c libarchive/archive_pathmatch.h \ - libarchive/archive_platform.h \ - libarchive/archive_platform_acl.h \ - libarchive/archive_platform_xattr.h \ - libarchive/archive_ppmd_private.h libarchive/archive_ppmd7.c \ - libarchive/archive_ppmd7_private.h libarchive/archive_ppmd8.c \ - libarchive/archive_ppmd8_private.h \ - libarchive/archive_private.h libarchive/archive_random.c \ - libarchive/archive_random_private.h libarchive/archive_rb.c \ - libarchive/archive_rb.h libarchive/archive_read.c \ - libarchive/archive_read_add_passphrase.c \ - libarchive/archive_read_append_filter.c \ - libarchive/archive_read_data_into_fd.c \ - libarchive/archive_read_disk_entry_from_file.c \ - libarchive/archive_read_disk_posix.c \ - libarchive/archive_read_disk_private.h \ - libarchive/archive_read_disk_set_standard_lookup.c \ - libarchive/archive_read_extract.c \ - libarchive/archive_read_extract2.c \ - libarchive/archive_read_open_fd.c \ - libarchive/archive_read_open_file.c \ - libarchive/archive_read_open_filename.c \ - libarchive/archive_read_open_memory.c \ - libarchive/archive_read_private.h \ - libarchive/archive_read_set_format.c \ - libarchive/archive_read_set_options.c \ - libarchive/archive_read_support_filter_all.c \ - libarchive/archive_read_support_filter_bzip2.c \ - libarchive/archive_read_support_filter_by_code.c \ - libarchive/archive_read_support_filter_compress.c \ - libarchive/archive_read_support_filter_grzip.c \ - libarchive/archive_read_support_filter_gzip.c \ - libarchive/archive_read_support_filter_lrzip.c \ - libarchive/archive_read_support_filter_lz4.c \ - libarchive/archive_read_support_filter_lzop.c \ - libarchive/archive_read_support_filter_none.c \ - libarchive/archive_read_support_filter_program.c \ - libarchive/archive_read_support_filter_rpm.c \ - libarchive/archive_read_support_filter_uu.c \ - libarchive/archive_read_support_filter_xz.c \ - libarchive/archive_read_support_filter_zstd.c \ - libarchive/archive_read_support_format_7zip.c \ - libarchive/archive_read_support_format_all.c \ - libarchive/archive_read_support_format_ar.c \ - libarchive/archive_read_support_format_by_code.c \ - libarchive/archive_read_support_format_cab.c \ - libarchive/archive_read_support_format_cpio.c \ - libarchive/archive_read_support_format_empty.c \ - libarchive/archive_read_support_format_iso9660.c \ - libarchive/archive_read_support_format_lha.c \ - libarchive/archive_read_support_format_mtree.c \ - libarchive/archive_read_support_format_rar.c \ - libarchive/archive_read_support_format_rar5.c \ - libarchive/archive_read_support_format_raw.c \ - libarchive/archive_read_support_format_tar.c \ - libarchive/archive_read_support_format_warc.c \ - libarchive/archive_read_support_format_xar.c \ - libarchive/archive_read_support_format_zip.c \ - libarchive/archive_string.c libarchive/archive_string.h \ - libarchive/archive_string_composition.h \ - libarchive/archive_string_sprintf.c libarchive/archive_util.c \ - libarchive/archive_version_details.c \ - libarchive/archive_virtual.c libarchive/archive_write.c \ - libarchive/archive_write_disk_posix.c \ - libarchive/archive_write_disk_private.h \ - libarchive/archive_write_disk_set_standard_lookup.c \ - libarchive/archive_write_open_fd.c \ - libarchive/archive_write_open_file.c \ - libarchive/archive_write_open_filename.c \ - libarchive/archive_write_open_memory.c \ - libarchive/archive_write_private.h \ - libarchive/archive_write_add_filter.c \ - libarchive/archive_write_add_filter_b64encode.c \ - libarchive/archive_write_add_filter_by_name.c \ - libarchive/archive_write_add_filter_bzip2.c \ - libarchive/archive_write_add_filter_compress.c \ - libarchive/archive_write_add_filter_grzip.c \ - libarchive/archive_write_add_filter_gzip.c \ - libarchive/archive_write_add_filter_lrzip.c \ - libarchive/archive_write_add_filter_lz4.c \ - libarchive/archive_write_add_filter_lzop.c \ - libarchive/archive_write_add_filter_none.c \ - libarchive/archive_write_add_filter_program.c \ - libarchive/archive_write_add_filter_uuencode.c \ - libarchive/archive_write_add_filter_xz.c \ - libarchive/archive_write_add_filter_zstd.c \ - libarchive/archive_write_set_format.c \ - libarchive/archive_write_set_format_7zip.c \ - libarchive/archive_write_set_format_ar.c \ - libarchive/archive_write_set_format_by_name.c \ - libarchive/archive_write_set_format_cpio.c \ - libarchive/archive_write_set_format_cpio_binary.c \ - libarchive/archive_write_set_format_cpio_newc.c \ - libarchive/archive_write_set_format_cpio_odc.c \ - libarchive/archive_write_set_format_filter_by_ext.c \ - libarchive/archive_write_set_format_iso9660.c \ - libarchive/archive_write_set_format_mtree.c \ - libarchive/archive_write_set_format_pax.c \ - libarchive/archive_write_set_format_private.h \ - libarchive/archive_write_set_format_raw.c \ - libarchive/archive_write_set_format_shar.c \ - libarchive/archive_write_set_format_ustar.c \ - libarchive/archive_write_set_format_v7tar.c \ - libarchive/archive_write_set_format_gnutar.c \ - libarchive/archive_write_set_format_warc.c \ - libarchive/archive_write_set_format_xar.c \ - libarchive/archive_write_set_format_zip.c \ - libarchive/archive_write_set_options.c \ - libarchive/archive_write_set_passphrase.c \ - libarchive/archive_xxhash.h libarchive/config_freebsd.h \ - libarchive/filter_fork_posix.c libarchive/filter_fork.h \ - libarchive/xxhash.c $(am__append_1) $(am__append_2) \ - $(am__append_3) $(am__append_4) $(am__append_5) \ - $(am__append_6) - -# -no-undefined marks that libarchive doesn't rely on symbols -# defined in the application. This is mandatory for cygwin. -libarchive_la_LDFLAGS = -no-undefined -version-info $(ARCHIVE_LIBTOOL_VERSION) $(GC_SECTIONS) -libarchive_la_LIBADD = $(LTLIBICONV) - -# Manpages to install -libarchive_man_MANS = \ - libarchive/archive_entry.3 \ - libarchive/archive_entry_acl.3 \ - libarchive/archive_entry_linkify.3 \ - libarchive/archive_entry_misc.3 \ - libarchive/archive_entry_paths.3 \ - libarchive/archive_entry_perms.3 \ - libarchive/archive_entry_stat.3 \ - libarchive/archive_entry_time.3 \ - libarchive/archive_read.3 \ - libarchive/archive_read_add_passphrase.3 \ - libarchive/archive_read_data.3 \ - libarchive/archive_read_disk.3 \ - libarchive/archive_read_extract.3 \ - libarchive/archive_read_filter.3 \ - libarchive/archive_read_format.3 \ - libarchive/archive_read_free.3 \ - libarchive/archive_read_header.3 \ - libarchive/archive_read_new.3 \ - libarchive/archive_read_open.3 \ - libarchive/archive_read_set_options.3 \ - libarchive/archive_util.3 \ - libarchive/archive_write.3 \ - libarchive/archive_write_blocksize.3 \ - libarchive/archive_write_data.3 \ - libarchive/archive_write_disk.3 \ - libarchive/archive_write_filter.3 \ - libarchive/archive_write_finish_entry.3 \ - libarchive/archive_write_format.3 \ - libarchive/archive_write_free.3 \ - libarchive/archive_write_header.3 \ - libarchive/archive_write_new.3 \ - libarchive/archive_write_open.3 \ - libarchive/archive_write_set_options.3 \ - libarchive/archive_write_set_passphrase.3 \ - libarchive/cpio.5 \ - libarchive/libarchive.3 \ - libarchive/libarchive_changes.3 \ - libarchive/libarchive_internals.3 \ - libarchive/libarchive-formats.5 \ - libarchive/mtree.5 \ - libarchive/tar.5 - - -# Additional libarchive files to include in the distribution -libarchive_EXTRA_DIST = \ - libarchive/archive_windows.c \ - libarchive/archive_windows.h \ - libarchive/filter_fork_windows.c \ - libarchive/CMakeLists.txt \ - $(libarchive_man_MANS) - - -# pkgconfig -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = build/pkgconfig/libarchive.pc - -# Sources needed by all test programs -test_utils_SOURCES = \ - test_utils/test_utils.c \ - test_utils/test_utils.h \ - test_utils/test_main.c \ - test_utils/test_common.h - - -# -# -# libarchive_test program -# -# -libarchive_test_SOURCES = \ - $(libarchive_la_SOURCES) \ - $(test_utils_SOURCES) \ - libarchive/test/read_open_memory.c \ - libarchive/test/test.h \ - libarchive/test/test_acl_nfs4.c \ - libarchive/test/test_acl_pax.c \ - libarchive/test/test_acl_platform_nfs4.c \ - libarchive/test/test_acl_platform_posix1e.c \ - libarchive/test/test_acl_posix1e.c \ - libarchive/test/test_acl_text.c \ - libarchive/test/test_archive_api_feature.c \ - libarchive/test/test_archive_clear_error.c \ - libarchive/test/test_archive_cmdline.c \ - libarchive/test/test_archive_digest.c \ - libarchive/test/test_archive_getdate.c \ - libarchive/test/test_archive_match_owner.c \ - libarchive/test/test_archive_match_path.c \ - libarchive/test/test_archive_match_time.c \ - libarchive/test/test_archive_pathmatch.c \ - libarchive/test/test_archive_read_add_passphrase.c \ - libarchive/test/test_archive_read_close_twice.c \ - libarchive/test/test_archive_read_close_twice_open_fd.c \ - libarchive/test/test_archive_read_close_twice_open_filename.c \ - libarchive/test/test_archive_read_multiple_data_objects.c \ - libarchive/test/test_archive_read_next_header_empty.c \ - libarchive/test/test_archive_read_next_header_raw.c \ - libarchive/test/test_archive_read_open2.c \ - libarchive/test/test_archive_read_set_filter_option.c \ - libarchive/test/test_archive_read_set_format_option.c \ - libarchive/test/test_archive_read_set_option.c \ - libarchive/test/test_archive_read_set_options.c \ - libarchive/test/test_archive_read_support.c \ - libarchive/test/test_archive_set_error.c \ - libarchive/test/test_archive_string.c \ - libarchive/test/test_archive_string_conversion.c \ - libarchive/test/test_archive_write_add_filter_by_name.c \ - libarchive/test/test_archive_write_set_filter_option.c \ - libarchive/test/test_archive_write_set_format_by_name.c \ - libarchive/test/test_archive_write_set_format_filter_by_ext.c \ - libarchive/test/test_archive_write_set_format_option.c \ - libarchive/test/test_archive_write_set_option.c \ - libarchive/test/test_archive_write_set_options.c \ - libarchive/test/test_archive_write_set_passphrase.c \ - libarchive/test/test_bad_fd.c \ - libarchive/test/test_compat_bzip2.c \ - libarchive/test/test_compat_cpio.c \ - libarchive/test/test_compat_gtar.c \ - libarchive/test/test_compat_gzip.c \ - libarchive/test/test_compat_lz4.c \ - libarchive/test/test_compat_lzip.c \ - libarchive/test/test_compat_lzma.c \ - libarchive/test/test_compat_lzop.c \ - libarchive/test/test_compat_mac.c \ - libarchive/test/test_compat_perl_archive_tar.c \ - libarchive/test/test_compat_plexus_archiver_tar.c \ - libarchive/test/test_compat_solaris_tar_acl.c \ - libarchive/test/test_compat_solaris_pax_sparse.c \ - libarchive/test/test_compat_star_acl.c \ - libarchive/test/test_compat_tar_directory.c \ - libarchive/test/test_compat_tar_hardlink.c \ - libarchive/test/test_compat_uudecode.c \ - libarchive/test/test_compat_uudecode_large.c \ - libarchive/test/test_compat_xz.c \ - libarchive/test/test_compat_zip.c \ - libarchive/test/test_compat_zstd.c \ - libarchive/test/test_empty_write.c \ - libarchive/test/test_entry.c \ - libarchive/test/test_entry_strmode.c \ - libarchive/test/test_extattr_freebsd.c \ - libarchive/test/test_filter_count.c \ - libarchive/test/test_fuzz.c \ - libarchive/test/test_gnutar_filename_encoding.c \ - libarchive/test/test_link_resolver.c \ - libarchive/test/test_open_failure.c \ - libarchive/test/test_open_fd.c \ - libarchive/test/test_open_file.c \ - libarchive/test/test_open_filename.c \ - libarchive/test/test_pax_filename_encoding.c \ - libarchive/test/test_pax_xattr_header.c \ - libarchive/test/test_read_data_large.c \ - libarchive/test/test_read_disk.c \ - libarchive/test/test_read_disk_directory_traversals.c \ - libarchive/test/test_read_disk_entry_from_file.c \ - libarchive/test/test_read_extract.c \ - libarchive/test/test_read_file_nonexistent.c \ - libarchive/test/test_read_filter_compress.c \ - libarchive/test/test_read_filter_grzip.c \ - libarchive/test/test_read_filter_lrzip.c \ - libarchive/test/test_read_filter_lzop.c \ - libarchive/test/test_read_filter_lzop_multiple_parts.c \ - libarchive/test/test_read_filter_program.c \ - libarchive/test/test_read_filter_program_signature.c \ - libarchive/test/test_read_filter_uudecode.c \ - libarchive/test/test_read_filter_uudecode_raw.c \ - libarchive/test/test_read_format_7zip.c \ - libarchive/test/test_read_format_7zip_encryption_data.c \ - libarchive/test/test_read_format_7zip_encryption_partially.c \ - libarchive/test/test_read_format_7zip_encryption_header.c \ - libarchive/test/test_read_format_7zip_malformed.c \ - libarchive/test/test_read_format_7zip_packinfo_digests.c \ - libarchive/test/test_read_format_ar.c \ - libarchive/test/test_read_format_cab.c \ - libarchive/test/test_read_format_cab_filename.c \ - libarchive/test/test_read_format_cpio_afio.c \ - libarchive/test/test_read_format_cpio_bin.c \ - libarchive/test/test_read_format_cpio_bin_Z.c \ - libarchive/test/test_read_format_cpio_bin_be.c \ - libarchive/test/test_read_format_cpio_bin_bz2.c \ - libarchive/test/test_read_format_cpio_bin_gz.c \ - libarchive/test/test_read_format_cpio_bin_le.c \ - libarchive/test/test_read_format_cpio_bin_lzip.c \ - libarchive/test/test_read_format_cpio_bin_lzma.c \ - libarchive/test/test_read_format_cpio_bin_xz.c \ - libarchive/test/test_read_format_cpio_filename.c \ - libarchive/test/test_read_format_cpio_odc.c \ - libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c \ - libarchive/test/test_read_format_cpio_svr4_gzip.c \ - libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c \ - libarchive/test/test_read_format_cpio_svr4c_Z.c \ - libarchive/test/test_read_format_empty.c \ - libarchive/test/test_read_format_gtar_filename.c \ - libarchive/test/test_read_format_gtar_gz.c \ - libarchive/test/test_read_format_gtar_lzma.c \ - libarchive/test/test_read_format_gtar_sparse.c \ - libarchive/test/test_read_format_gtar_sparse_skip_entry.c \ - libarchive/test/test_read_format_iso_Z.c \ - libarchive/test/test_read_format_iso_multi_extent.c \ - libarchive/test/test_read_format_iso_xorriso.c \ - libarchive/test/test_read_format_isojoliet_bz2.c \ - libarchive/test/test_read_format_isojoliet_long.c \ - libarchive/test/test_read_format_isojoliet_rr.c \ - libarchive/test/test_read_format_isojoliet_versioned.c \ - libarchive/test/test_read_format_isorr_bz2.c \ - libarchive/test/test_read_format_isorr_ce.c \ - libarchive/test/test_read_format_isorr_new_bz2.c \ - libarchive/test/test_read_format_isorr_rr_moved.c \ - libarchive/test/test_read_format_isozisofs_bz2.c \ - libarchive/test/test_read_format_lha.c \ - libarchive/test/test_read_format_lha_bugfix_0.c \ - libarchive/test/test_read_format_lha_filename.c \ - libarchive/test/test_read_format_lha_filename_utf16.c \ - libarchive/test/test_read_format_mtree.c \ - libarchive/test/test_read_format_mtree_crash747.c \ - libarchive/test/test_read_format_pax_bz2.c \ - libarchive/test/test_read_format_rar.c \ - libarchive/test/test_read_format_rar_encryption_data.c \ - libarchive/test/test_read_format_rar_encryption_partially.c \ - libarchive/test/test_read_format_rar_encryption_header.c \ - libarchive/test/test_read_format_rar_filter.c \ - libarchive/test/test_read_format_rar_invalid1.c \ - libarchive/test/test_read_format_rar5.c \ - libarchive/test/test_read_format_raw.c \ - libarchive/test/test_read_format_tar.c \ - libarchive/test/test_read_format_tar_concatenated.c \ - libarchive/test/test_read_format_tar_empty_pax.c \ - libarchive/test/test_read_format_tar_empty_filename.c \ - libarchive/test/test_read_format_tar_empty_with_gnulabel.c \ - libarchive/test/test_read_format_tar_filename.c \ - libarchive/test/test_read_format_tar_invalid_pax_size.c \ - libarchive/test/test_read_format_tbz.c \ - libarchive/test/test_read_format_tgz.c \ - libarchive/test/test_read_format_tlz.c \ - libarchive/test/test_read_format_txz.c \ - libarchive/test/test_read_format_tz.c \ - libarchive/test/test_read_format_ustar_filename.c \ - libarchive/test/test_read_format_warc.c \ - libarchive/test/test_read_format_xar.c \ - libarchive/test/test_read_format_zip.c \ - libarchive/test/test_read_format_zip_7075_utf8_paths.c \ - libarchive/test/test_read_format_zip_comment_stored.c \ - libarchive/test/test_read_format_zip_encryption_data.c \ - libarchive/test/test_read_format_zip_encryption_partially.c \ - libarchive/test/test_read_format_zip_encryption_header.c \ - libarchive/test/test_read_format_zip_extra_padding.c \ - libarchive/test/test_read_format_zip_filename.c \ - libarchive/test/test_read_format_zip_high_compression.c \ - libarchive/test/test_read_format_zip_jar.c \ - libarchive/test/test_read_format_zip_mac_metadata.c \ - libarchive/test/test_read_format_zip_malformed.c \ - libarchive/test/test_read_format_zip_msdos.c \ - libarchive/test/test_read_format_zip_nested.c \ - libarchive/test/test_read_format_zip_nofiletype.c \ - libarchive/test/test_read_format_zip_padded.c \ - libarchive/test/test_read_format_zip_sfx.c \ - libarchive/test/test_read_format_zip_traditional_encryption_data.c \ - libarchive/test/test_read_format_zip_winzip_aes.c \ - libarchive/test/test_read_format_zip_winzip_aes_large.c \ - libarchive/test/test_read_format_zip_zip64.c \ - libarchive/test/test_read_format_zip_with_invalid_traditional_eocd.c \ - libarchive/test/test_read_large.c \ - libarchive/test/test_read_pax_xattr_rht_security_selinux.c \ - libarchive/test/test_read_pax_xattr_schily.c \ - libarchive/test/test_read_pax_truncated.c \ - libarchive/test/test_read_position.c \ - libarchive/test/test_read_set_format.c \ - libarchive/test/test_read_too_many_filters.c \ - libarchive/test/test_read_truncated.c \ - libarchive/test/test_read_truncated_filter.c \ - libarchive/test/test_short_writes.c \ - libarchive/test/test_sparse_basic.c \ - libarchive/test/test_tar_filenames.c \ - libarchive/test/test_tar_large.c \ - libarchive/test/test_ustar_filenames.c \ - libarchive/test/test_ustar_filename_encoding.c \ - libarchive/test/test_warn_missing_hardlink_target.c \ - libarchive/test/test_write_disk.c \ - libarchive/test/test_write_disk_appledouble.c \ - libarchive/test/test_write_disk_failures.c \ - libarchive/test/test_write_disk_fixup.c \ - libarchive/test/test_write_disk_hardlink.c \ - libarchive/test/test_write_disk_hfs_compression.c \ - libarchive/test/test_write_disk_lookup.c \ - libarchive/test/test_write_disk_mac_metadata.c \ - libarchive/test/test_write_disk_no_hfs_compression.c \ - libarchive/test/test_write_disk_perms.c \ - libarchive/test/test_write_disk_secure.c \ - libarchive/test/test_write_disk_secure744.c \ - libarchive/test/test_write_disk_secure745.c \ - libarchive/test/test_write_disk_secure746.c \ - libarchive/test/test_write_disk_sparse.c \ - libarchive/test/test_write_disk_symlink.c \ - libarchive/test/test_write_disk_times.c \ - libarchive/test/test_write_filter_b64encode.c \ - libarchive/test/test_write_filter_bzip2.c \ - libarchive/test/test_write_filter_compress.c \ - libarchive/test/test_write_filter_gzip.c \ - libarchive/test/test_write_filter_gzip_timestamp.c \ - libarchive/test/test_write_filter_lrzip.c \ - libarchive/test/test_write_filter_lz4.c \ - libarchive/test/test_write_filter_lzip.c \ - libarchive/test/test_write_filter_lzma.c \ - libarchive/test/test_write_filter_lzop.c \ - libarchive/test/test_write_filter_program.c \ - libarchive/test/test_write_filter_uuencode.c \ - libarchive/test/test_write_filter_xz.c \ - libarchive/test/test_write_filter_zstd.c \ - libarchive/test/test_write_format_7zip.c \ - libarchive/test/test_write_format_7zip_empty.c \ - libarchive/test/test_write_format_7zip_large.c \ - libarchive/test/test_write_format_ar.c \ - libarchive/test/test_write_format_cpio.c \ - libarchive/test/test_write_format_cpio_empty.c \ - libarchive/test/test_write_format_cpio_newc.c \ - libarchive/test/test_write_format_cpio_odc.c \ - libarchive/test/test_write_format_gnutar.c \ - libarchive/test/test_write_format_gnutar_filenames.c \ - libarchive/test/test_write_format_iso9660.c \ - libarchive/test/test_write_format_iso9660_boot.c \ - libarchive/test/test_write_format_iso9660_empty.c \ - libarchive/test/test_write_format_iso9660_filename.c \ - libarchive/test/test_write_format_iso9660_zisofs.c \ - libarchive/test/test_write_format_mtree.c \ - libarchive/test/test_write_format_mtree_absolute_path.c \ - libarchive/test/test_write_format_mtree_classic.c \ - libarchive/test/test_write_format_mtree_classic_indent.c\ - libarchive/test/test_write_format_mtree_fflags.c \ - libarchive/test/test_write_format_mtree_no_separator.c \ - libarchive/test/test_write_format_mtree_quoted_filename.c\ - libarchive/test/test_write_format_pax.c \ - libarchive/test/test_write_format_raw.c \ - libarchive/test/test_write_format_raw_b64.c \ - libarchive/test/test_write_format_shar_empty.c \ - libarchive/test/test_write_format_tar.c \ - libarchive/test/test_write_format_tar_empty.c \ - libarchive/test/test_write_format_tar_sparse.c \ - libarchive/test/test_write_format_tar_ustar.c \ - libarchive/test/test_write_format_tar_v7tar.c \ - libarchive/test/test_write_format_warc.c \ - libarchive/test/test_write_format_warc_empty.c \ - libarchive/test/test_write_format_xar.c \ - libarchive/test/test_write_format_xar_empty.c \ - libarchive/test/test_write_format_zip.c \ - libarchive/test/test_write_format_zip_compression_store.c \ - libarchive/test/test_write_format_zip_entry_size_unset.c \ - libarchive/test/test_write_format_zip_empty.c \ - libarchive/test/test_write_format_zip_empty_zip64.c \ - libarchive/test/test_write_format_zip_file.c \ - libarchive/test/test_write_format_zip_file_zip64.c \ - libarchive/test/test_write_format_zip_large.c \ - libarchive/test/test_write_format_zip_zip64.c \ - libarchive/test/test_write_open_memory.c \ - libarchive/test/test_write_read_format_zip.c \ - libarchive/test/test_xattr_platform.c \ - libarchive/test/test_zip_filename_encoding.c - -libarchive_test_CPPFLAGS = \ - -I$(top_srcdir)/libarchive \ - -I$(top_srcdir)/libarchive/test \ - -I$(top_srcdir)/test_utils \ - -I$(top_builddir)/libarchive/test \ - -DLIBARCHIVE_STATIC $(PLATFORMCPPFLAGS) - -libarchive_test_LDADD = $(LTLIBICONV) -libarchive_TESTS_ENVIRONMENT = LIBARCHIVE_TEST_FILES=`cd $(top_srcdir);/bin/pwd`/libarchive/test LRZIP=NOCONFIG -libarchive_test_EXTRA_DIST = \ - libarchive/test/list.h \ - libarchive/test/test_acl_pax_posix1e.tar.uu \ - libarchive/test/test_acl_pax_nfs4.tar.uu \ - libarchive/test/test_archive_string_conversion.txt.Z.uu \ - libarchive/test/test_compat_bzip2_1.tbz.uu \ - libarchive/test/test_compat_bzip2_2.tbz.uu \ - libarchive/test/test_compat_cpio_1.cpio.uu \ - libarchive/test/test_compat_gtar_1.tar.uu \ - libarchive/test/test_compat_gtar_2.tar.uu \ - libarchive/test/test_compat_gzip_1.tgz.uu \ - libarchive/test/test_compat_gzip_2.tgz.uu \ - libarchive/test/test_compat_lz4_1.tar.lz4.uu \ - libarchive/test/test_compat_lz4_2.tar.lz4.uu \ - libarchive/test/test_compat_lz4_3.tar.lz4.uu \ - libarchive/test/test_compat_lz4_B4.tar.lz4.uu \ - libarchive/test/test_compat_lz4_B4BD.tar.lz4.uu \ - libarchive/test/test_compat_lz4_B4BDBX.tar.lz4.uu \ - libarchive/test/test_compat_lz4_B5.tar.lz4.uu \ - libarchive/test/test_compat_lz4_B5BD.tar.lz4.uu \ - libarchive/test/test_compat_lz4_B6.tar.lz4.uu \ - libarchive/test/test_compat_lz4_B6BD.tar.lz4.uu \ - libarchive/test/test_compat_lz4_B7.tar.lz4.uu \ - libarchive/test/test_compat_lz4_B7BD.tar.lz4.uu \ - libarchive/test/test_compat_lzip_1.tlz.uu \ - libarchive/test/test_compat_lzip_2.tlz.uu \ - libarchive/test/test_compat_lzma_1.tlz.uu \ - libarchive/test/test_compat_lzma_2.tlz.uu \ - libarchive/test/test_compat_lzma_3.tlz.uu \ - libarchive/test/test_compat_lzop_1.tar.lzo.uu \ - libarchive/test/test_compat_lzop_2.tar.lzo.uu \ - libarchive/test/test_compat_lzop_3.tar.lzo.uu \ - libarchive/test/test_compat_mac-1.tar.Z.uu \ - libarchive/test/test_compat_mac-2.tar.Z.uu \ - libarchive/test/test_compat_perl_archive_tar.tar.uu \ - libarchive/test/test_compat_plexus_archiver_tar.tar.uu \ - libarchive/test/test_compat_solaris_pax_sparse_1.pax.Z.uu \ - libarchive/test/test_compat_solaris_pax_sparse_2.pax.Z.uu \ - libarchive/test/test_compat_solaris_tar_acl.tar.uu \ - libarchive/test/test_compat_star_acl_nfs4.tar.uu \ - libarchive/test/test_compat_star_acl_posix1e.tar.uu \ - libarchive/test/test_compat_tar_directory_1.tar.uu \ - libarchive/test/test_compat_tar_hardlink_1.tar.uu \ - libarchive/test/test_compat_uudecode_large.tar.Z.uu \ - libarchive/test/test_compat_xz_1.txz.uu \ - libarchive/test/test_compat_zip_1.zip.uu \ - libarchive/test/test_compat_zip_2.zip.uu \ - libarchive/test/test_compat_zip_3.zip.uu \ - libarchive/test/test_compat_zip_4.zip.uu \ - libarchive/test/test_compat_zip_5.zip.uu \ - libarchive/test/test_compat_zip_6.zip.uu \ - libarchive/test/test_compat_zip_7.xps.uu \ - libarchive/test/test_compat_zip_8.zip.uu \ - libarchive/test/test_compat_zstd_1.tar.zst.uu \ - libarchive/test/test_compat_zstd_2.tar.zst.uu \ - libarchive/test/test_fuzz.cab.uu \ - libarchive/test/test_fuzz.lzh.uu \ - libarchive/test/test_fuzz_1.iso.Z.uu \ - libarchive/test/test_pax_filename_encoding.tar.uu \ - libarchive/test/test_pax_xattr_header_all.tar.uu \ - libarchive/test/test_pax_xattr_header_libarchive.tar.uu \ - libarchive/test/test_pax_xattr_header_schily.tar.uu \ - libarchive/test/test_rar_multivolume_multiple_files.part1.rar.uu \ - libarchive/test/test_rar_multivolume_multiple_files.part2.rar.uu \ - libarchive/test/test_rar_multivolume_multiple_files.part3.rar.uu \ - libarchive/test/test_rar_multivolume_multiple_files.part4.rar.uu \ - libarchive/test/test_rar_multivolume_multiple_files.part5.rar.uu \ - libarchive/test/test_rar_multivolume_multiple_files.part6.rar.uu \ - libarchive/test/test_rar_multivolume_single_file.part1.rar.uu \ - libarchive/test/test_rar_multivolume_single_file.part2.rar.uu \ - libarchive/test/test_rar_multivolume_single_file.part3.rar.uu \ - libarchive/test/test_rar_multivolume_uncompressed_files.part01.rar.uu \ - libarchive/test/test_rar_multivolume_uncompressed_files.part02.rar.uu \ - libarchive/test/test_rar_multivolume_uncompressed_files.part03.rar.uu \ - libarchive/test/test_rar_multivolume_uncompressed_files.part04.rar.uu \ - libarchive/test/test_rar_multivolume_uncompressed_files.part05.rar.uu \ - libarchive/test/test_rar_multivolume_uncompressed_files.part06.rar.uu \ - libarchive/test/test_rar_multivolume_uncompressed_files.part07.rar.uu \ - libarchive/test/test_rar_multivolume_uncompressed_files.part08.rar.uu \ - libarchive/test/test_rar_multivolume_uncompressed_files.part09.rar.uu \ - libarchive/test/test_rar_multivolume_uncompressed_files.part10.rar.uu \ - libarchive/test/test_read_filter_grzip.tar.grz.uu \ - libarchive/test/test_read_filter_lrzip.tar.lrz.uu \ - libarchive/test/test_read_filter_lzop.tar.lzo.uu \ - libarchive/test/test_read_filter_lzop_multiple_parts.tar.lzo.uu \ - libarchive/test/test_read_filter_uudecode_raw.uu \ - libarchive/test/test_read_filter_uudecode_base64_raw.uu \ - libarchive/test/test_read_format_mtree_crash747.mtree.bz2.uu \ - libarchive/test/test_read_format_mtree_noprint.mtree.uu \ - libarchive/test/test_read_format_7zip_bcj2_bzip2.7z.uu \ - libarchive/test/test_read_format_7zip_bcj2_copy_1.7z.uu \ - libarchive/test/test_read_format_7zip_bcj2_copy_2.7z.uu \ - libarchive/test/test_read_format_7zip_bcj2_copy_lzma.7z.uu \ - libarchive/test/test_read_format_7zip_bcj2_deflate.7z.uu \ - libarchive/test/test_read_format_7zip_bcj2_lzma1_1.7z.uu \ - libarchive/test/test_read_format_7zip_bcj2_lzma1_2.7z.uu \ - libarchive/test/test_read_format_7zip_bcj2_lzma2_1.7z.uu \ - libarchive/test/test_read_format_7zip_bcj2_lzma2_2.7z.uu \ - libarchive/test/test_read_format_7zip_bcj_bzip2.7z.uu \ - libarchive/test/test_read_format_7zip_bcj_copy.7z.uu \ - libarchive/test/test_read_format_7zip_bcj_deflate.7z.uu \ - libarchive/test/test_read_format_7zip_bcj_lzma1.7z.uu \ - libarchive/test/test_read_format_7zip_bcj_lzma2.7z.uu \ - libarchive/test/test_read_format_7zip_bzip2.7z.uu \ - libarchive/test/test_read_format_7zip_copy.7z.uu \ - libarchive/test/test_read_format_7zip_copy_2.7z.uu \ - libarchive/test/test_read_format_7zip_deflate.7z.uu \ - libarchive/test/test_read_format_7zip_deflate_arm64.7z.uu \ - libarchive/test/test_read_format_7zip_delta_lzma1.7z.uu \ - libarchive/test/test_read_format_7zip_delta4_lzma1.7z.uu \ - libarchive/test/test_read_format_7zip_delta_lzma2.7z.uu \ - libarchive/test/test_read_format_7zip_delta4_lzma2.7z.uu \ - libarchive/test/test_read_format_7zip_empty_archive.7z.uu \ - libarchive/test/test_read_format_7zip_empty_file.7z.uu \ - libarchive/test/test_read_format_7zip_encryption.7z.uu \ - libarchive/test/test_read_format_7zip_encryption_header.7z.uu \ - libarchive/test/test_read_format_7zip_encryption_partially.7z.uu \ - libarchive/test/test_read_format_7zip_lzma1.7z.uu \ - libarchive/test/test_read_format_7zip_lzma1_2.7z.uu \ - libarchive/test/test_read_format_7zip_lzma1_lzma2.7z.uu \ - libarchive/test/test_read_format_7zip_lzma2.7z.uu \ - libarchive/test/test_read_format_7zip_lzma2_arm64.7z.uu \ - libarchive/test/test_read_format_7zip_lzma2_arm.7z.uu \ - libarchive/test/test_read_format_7zip_malformed.7z.uu \ - libarchive/test/test_read_format_7zip_malformed2.7z.uu \ - libarchive/test/test_read_format_7zip_packinfo_digests.7z.uu \ - libarchive/test/test_read_format_7zip_ppmd.7z.uu \ - libarchive/test/test_read_format_7zip_solid_zstd.7z.uu \ - libarchive/test/test_read_format_7zip_symbolic_name.7z.uu \ - libarchive/test/test_read_format_7zip_win_attrib.7z.uu \ - libarchive/test/test_read_format_7zip_zstd_arm.7z.uu \ - libarchive/test/test_read_format_7zip_zstd_bcj.7z.uu \ - libarchive/test/test_read_format_7zip_zstd_nobcj.7z.uu \ - libarchive/test/test_read_format_7zip_zstd.7z.uu \ - libarchive/test/test_read_format_ar.ar.uu \ - libarchive/test/test_read_format_cab_1.cab.uu \ - libarchive/test/test_read_format_cab_2.cab.uu \ - libarchive/test/test_read_format_cab_3.cab.uu \ - libarchive/test/test_read_format_cab_filename_cp932.cab.uu \ - libarchive/test/test_read_format_cpio_bin_be.cpio.uu \ - libarchive/test/test_read_format_cpio_bin_le.cpio.uu \ - libarchive/test/test_read_format_cpio_filename_cp866.cpio.uu \ - libarchive/test/test_read_format_cpio_filename_eucjp.cpio.uu \ - libarchive/test/test_read_format_cpio_filename_koi8r.cpio.uu \ - libarchive/test/test_read_format_cpio_filename_utf8_jp.cpio.uu \ - libarchive/test/test_read_format_cpio_filename_utf8_ru.cpio.uu \ - libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.rpm.uu \ - libarchive/test/test_read_format_cpio_svr4_gzip_rpm.rpm.uu \ - libarchive/test/test_read_format_gtar_filename_cp866.tar.Z.uu \ - libarchive/test/test_read_format_gtar_filename_eucjp.tar.Z.uu \ - libarchive/test/test_read_format_gtar_filename_koi8r.tar.Z.uu \ - libarchive/test/test_read_format_gtar_sparse_1_13.tar.uu \ - libarchive/test/test_read_format_gtar_sparse_1_17.tar.uu \ - libarchive/test/test_read_format_gtar_sparse_1_17_posix00.tar.uu \ - libarchive/test/test_read_format_gtar_sparse_1_17_posix01.tar.uu \ - libarchive/test/test_read_format_gtar_sparse_1_17_posix10.tar.uu \ - libarchive/test/test_read_format_gtar_sparse_1_17_posix10_modified.tar.uu \ - libarchive/test/test_read_format_gtar_sparse_skip_entry.tar.Z.uu \ - libarchive/test/test_read_format_iso.iso.Z.uu \ - libarchive/test/test_read_format_iso_2.iso.Z.uu \ - libarchive/test/test_read_format_iso_joliet.iso.Z.uu \ - libarchive/test/test_read_format_iso_joliet_by_nero.iso.Z.uu \ - libarchive/test/test_read_format_iso_joliet_long.iso.Z.uu \ - libarchive/test/test_read_format_iso_joliet_rockridge.iso.Z.uu \ - libarchive/test/test_read_format_iso_multi_extent.iso.Z.uu \ - libarchive/test/test_read_format_iso_rockridge.iso.Z.uu \ - libarchive/test/test_read_format_iso_rockridge_ce.iso.Z.uu \ - libarchive/test/test_read_format_iso_rockridge_new.iso.Z.uu \ - libarchive/test/test_read_format_iso_rockridge_rr_moved.iso.Z.uu \ - libarchive/test/test_read_format_iso_xorriso.iso.Z.uu \ - libarchive/test/test_read_format_iso_zisofs.iso.Z.uu \ - libarchive/test/test_read_format_lha_bugfix_0.lzh.uu \ - libarchive/test/test_read_format_lha_filename_cp932.lzh.uu \ - libarchive/test/test_read_format_lha_filename_utf16.lzh.uu \ - libarchive/test/test_read_format_lha_header0.lzh.uu \ - libarchive/test/test_read_format_lha_header1.lzh.uu \ - libarchive/test/test_read_format_lha_header2.lzh.uu \ - libarchive/test/test_read_format_lha_header3.lzh.uu \ - libarchive/test/test_read_format_lha_lh0.lzh.uu \ - libarchive/test/test_read_format_lha_lh6.lzh.uu \ - libarchive/test/test_read_format_lha_lh7.lzh.uu \ - libarchive/test/test_read_format_lha_withjunk.lzh.uu \ - libarchive/test/test_read_format_mtree.mtree.uu \ - libarchive/test/test_read_format_mtree_nomagic.mtree.uu \ - libarchive/test/test_read_format_mtree_nomagic2.mtree.uu \ - libarchive/test/test_read_format_mtree_nomagic3.mtree.uu \ - libarchive/test/test_read_format_rar.rar.uu \ - libarchive/test/test_read_format_rar_binary_data.rar.uu \ - libarchive/test/test_read_format_rar_compress_best.rar.uu \ - libarchive/test/test_read_format_rar_compress_normal.rar.uu \ - libarchive/test/test_read_format_rar_encryption_data.rar.uu \ - libarchive/test/test_read_format_rar_encryption_header.rar.uu \ - libarchive/test/test_read_format_rar_encryption_partially.rar.uu \ - libarchive/test/test_read_format_rar_filter.rar.uu \ - libarchive/test/test_read_format_rar_invalid1.rar.uu \ - libarchive/test/test_read_format_rar_multi_lzss_blocks.rar.uu \ - libarchive/test/test_read_format_rar_multivolume.part0001.rar.uu \ - libarchive/test/test_read_format_rar_multivolume.part0002.rar.uu \ - libarchive/test/test_read_format_rar_multivolume.part0003.rar.uu \ - libarchive/test/test_read_format_rar_multivolume.part0004.rar.uu \ - libarchive/test/test_read_format_rar_noeof.rar.uu \ - libarchive/test/test_read_format_rar_ppmd_lzss_conversion.rar.uu \ - libarchive/test/test_read_format_rar_ppmd_use_after_free.rar.uu \ - libarchive/test/test_read_format_rar_ppmd_use_after_free2.rar.uu \ - libarchive/test/test_read_format_rar_sfx.exe.uu \ - libarchive/test/test_read_format_rar_subblock.rar.uu \ - libarchive/test/test_read_format_rar_unicode.rar.uu \ - libarchive/test/test_read_format_rar_windows.rar.uu \ - libarchive/test/test_read_format_rar5_arm.rar.uu \ - libarchive/test/test_read_format_rar5_blake2.rar.uu \ - libarchive/test/test_read_format_rar5_compressed.rar.uu \ - libarchive/test/test_read_format_rar5_different_window_size.rar.uu \ - libarchive/test/test_read_format_rar5_different_solid_window_size.rar.uu \ - libarchive/test/test_read_format_rar5_distance_overflow.rar.uu \ - libarchive/test/test_read_format_rar5_extra_field_version.rar.uu \ - libarchive/test/test_read_format_rar5_fileattr.rar.uu \ - libarchive/test/test_read_format_rar5_hardlink.rar.uu \ - libarchive/test/test_read_format_rar5_invalid_dict_reference.rar.uu \ - libarchive/test/test_read_format_rar5_leftshift1.rar.uu \ - libarchive/test/test_read_format_rar5_leftshift2.rar.uu \ - libarchive/test/test_read_format_rar5_multiarchive.part01.rar.uu \ - libarchive/test/test_read_format_rar5_multiarchive.part02.rar.uu \ - libarchive/test/test_read_format_rar5_multiarchive.part03.rar.uu \ - libarchive/test/test_read_format_rar5_multiarchive.part04.rar.uu \ - libarchive/test/test_read_format_rar5_multiarchive.part05.rar.uu \ - libarchive/test/test_read_format_rar5_multiarchive.part06.rar.uu \ - libarchive/test/test_read_format_rar5_multiarchive.part07.rar.uu \ - libarchive/test/test_read_format_rar5_multiarchive.part08.rar.uu \ - libarchive/test/test_read_format_rar5_multiarchive_solid.part01.rar.uu \ - libarchive/test/test_read_format_rar5_multiarchive_solid.part02.rar.uu \ - libarchive/test/test_read_format_rar5_multiarchive_solid.part03.rar.uu \ - libarchive/test/test_read_format_rar5_multiarchive_solid.part04.rar.uu \ - libarchive/test/test_read_format_rar5_multiple_files.rar.uu \ - libarchive/test/test_read_format_rar5_multiple_files_solid.rar.uu \ - libarchive/test/test_read_format_rar5_nonempty_dir_stream.rar.uu \ - libarchive/test/test_read_format_rar5_owner.rar.uu \ - libarchive/test/test_read_format_rar5_readtables_overflow.rar.uu \ - libarchive/test/test_read_format_rar5_sfx.exe.uu \ - libarchive/test/test_read_format_rar5_solid.rar.uu \ - libarchive/test/test_read_format_rar5_stored.rar.uu \ - libarchive/test/test_read_format_rar5_stored_manyfiles.rar.uu \ - libarchive/test/test_read_format_rar5_symlink.rar.uu \ - libarchive/test/test_read_format_rar5_truncated_huff.rar.uu \ - libarchive/test/test_read_format_rar5_win32.rar.uu \ - libarchive/test/test_read_format_rar5_arm_filter_on_window_boundary.rar.uu \ - libarchive/test/test_read_format_rar5_different_winsize_on_merge.rar.uu \ - libarchive/test/test_read_format_rar5_block_size_is_too_small.rar.uu \ - libarchive/test/test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu \ - libarchive/test/test_read_format_rar5_window_buf_and_size_desync.rar.uu \ - libarchive/test/test_read_format_rar5_bad_window_sz_in_mltarc_file.rar.uu \ - libarchive/test/test_read_format_raw.bufr.uu \ - libarchive/test/test_read_format_raw.data.gz.uu \ - libarchive/test/test_read_format_raw.data.Z.uu \ - libarchive/test/test_read_format_raw.data.uu \ - libarchive/test/test_read_format_tar_concatenated.tar.uu \ - libarchive/test/test_read_format_tar_empty_filename.tar.uu \ - libarchive/test/test_read_format_tar_empty_with_gnulabel.tar.uu \ - libarchive/test/test_read_format_tar_empty_pax.tar.Z.uu \ - libarchive/test/test_read_format_tar_filename_koi8r.tar.Z.uu \ - libarchive/test/test_read_format_tar_invalid_pax_size.tar.uu \ - libarchive/test/test_read_format_ustar_filename_cp866.tar.Z.uu \ - libarchive/test/test_read_format_ustar_filename_eucjp.tar.Z.uu \ - libarchive/test/test_read_format_ustar_filename_koi8r.tar.Z.uu \ - libarchive/test/test_read_format_warc.warc.uu \ - libarchive/test/test_read_format_zip.zip.uu \ - libarchive/test/test_read_format_zip_7075_utf8_paths.zip.uu \ - libarchive/test/test_read_format_zip_7z_deflate.zip.uu \ - libarchive/test/test_read_format_zip_7z_lzma.zip.uu \ - libarchive/test/test_read_format_zip_bz2_hang.zip.uu \ - libarchive/test/test_read_format_zip_bzip2.zipx.uu \ - libarchive/test/test_read_format_zip_bzip2_multi.zipx.uu \ - libarchive/test/test_read_format_zip_comment_stored_1.zip.uu \ - libarchive/test/test_read_format_zip_comment_stored_2.zip.uu \ - libarchive/test/test_read_format_zip_encryption_data.zip.uu \ - libarchive/test/test_read_format_zip_encryption_header.zip.uu \ - libarchive/test/test_read_format_zip_encryption_partially.zip.uu \ - libarchive/test/test_read_format_zip_extra_padding.zip.uu \ - libarchive/test/test_read_format_zip_filename_cp866.zip.uu \ - libarchive/test/test_read_format_zip_filename_cp932.zip.uu \ - libarchive/test/test_read_format_zip_filename_koi8r.zip.uu \ - libarchive/test/test_read_format_zip_filename_utf8_jp.zip.uu \ - libarchive/test/test_read_format_zip_filename_utf8_ru.zip.uu \ - libarchive/test/test_read_format_zip_filename_utf8_ru2.zip.uu \ - libarchive/test/test_read_format_zip_high_compression.zip.uu \ - libarchive/test/test_read_format_zip_length_at_end.zip.uu \ - libarchive/test/test_read_format_zip_lzma.zipx.uu \ - libarchive/test/test_read_format_zip_lzma_alone_leak.zipx.uu \ - libarchive/test/test_read_format_zip_lzma_multi.zipx.uu \ - libarchive/test/test_read_format_zip_lzma_stream_end.zipx.uu \ - libarchive/test/test_read_format_zip_jar.jar.uu \ - libarchive/test/test_read_format_zip_mac_metadata.zip.uu \ - libarchive/test/test_read_format_zip_malformed1.zip.uu \ - libarchive/test/test_read_format_zip_msdos.zip.uu \ - libarchive/test/test_read_format_zip_nested.zip.uu \ - libarchive/test/test_read_format_zip_nofiletype.zip.uu \ - libarchive/test/test_read_format_zip_padded1.zip.uu \ - libarchive/test/test_read_format_zip_padded2.zip.uu \ - libarchive/test/test_read_format_zip_padded3.zip.uu \ - libarchive/test/test_read_format_zip_ppmd8.zipx.uu \ - libarchive/test/test_read_format_zip_ppmd8_crash_1.zipx.uu \ - libarchive/test/test_read_format_zip_ppmd8_crash_2.zipx.uu \ - libarchive/test/test_read_format_zip_ppmd8_multi.zipx.uu \ - libarchive/test/test_read_format_zip_sfx.uu \ - libarchive/test/test_read_format_zip_symlink.zip.uu \ - libarchive/test/test_read_format_zip_traditional_encryption_data.zip.uu \ - libarchive/test/test_read_format_zip_ux.zip.uu \ - libarchive/test/test_read_format_zip_winzip_aes128.zip.uu \ - libarchive/test/test_read_format_zip_winzip_aes256.zip.uu \ - libarchive/test/test_read_format_zip_winzip_aes256_large.zip.uu \ - libarchive/test/test_read_format_zip_winzip_aes256_stored.zip.uu \ - libarchive/test/test_read_format_zip_with_invalid_traditional_eocd.zip.uu \ - libarchive/test/test_read_format_zip_xz_multi.zipx.uu \ - libarchive/test/test_read_format_zip_zip64a.zip.uu \ - libarchive/test/test_read_format_zip_zip64b.zip.uu \ - libarchive/test/test_read_format_zip_zstd.zipx.uu \ - libarchive/test/test_read_format_zip_zstd_multi.zipx.uu \ - libarchive/test/test_read_large_splitted_rar_aa.uu \ - libarchive/test/test_read_large_splitted_rar_ab.uu \ - libarchive/test/test_read_large_splitted_rar_ac.uu \ - libarchive/test/test_read_large_splitted_rar_ad.uu \ - libarchive/test/test_read_large_splitted_rar_ae.uu \ - libarchive/test/test_read_pax_xattr_rht_security_selinux.tar.uu \ - libarchive/test/test_read_pax_xattr_schily.tar.uu \ - libarchive/test/test_read_splitted_rar_aa.uu \ - libarchive/test/test_read_splitted_rar_ab.uu \ - libarchive/test/test_read_splitted_rar_ac.uu \ - libarchive/test/test_read_splitted_rar_ad.uu \ - libarchive/test/test_read_too_many_filters.gz.uu \ - libarchive/test/test_splitted_rar_seek_support_aa.uu \ - libarchive/test/test_splitted_rar_seek_support_ab.uu \ - libarchive/test/test_splitted_rar_seek_support_ac.uu \ - libarchive/test/test_write_disk_appledouble.cpio.gz.uu \ - libarchive/test/test_write_disk_hfs_compression.tgz.uu \ - libarchive/test/test_write_disk_mac_metadata.tar.gz.uu \ - libarchive/test/test_write_disk_no_hfs_compression.tgz.uu \ - libarchive/test/CMakeLists.txt \ - libarchive/test/README - - -# -# Common code for libarchive frontends (cpio, tar) -# -libarchive_fe_la_SOURCES = \ - libarchive_fe/err.c \ - libarchive_fe/err.h \ - libarchive_fe/lafe_platform.h \ - libarchive_fe/line_reader.c \ - libarchive_fe/line_reader.h \ - libarchive_fe/passphrase.c \ - libarchive_fe/passphrase.h - -libarchive_fe_la_CPPFLAGS = -I$(top_srcdir)/libarchive -# -# -# bsdtar source, docs, etc. -# -# -bsdtar_SOURCES = tar/bsdtar.c tar/bsdtar.h tar/bsdtar_platform.h \ - tar/cmdline.c tar/creation_set.c tar/read.c tar/subst.c \ - tar/util.c tar/write.c $(am__append_7) -bsdtar_DEPENDENCIES = libarchive.la libarchive_fe.la -@STATIC_BSDTAR_FALSE@bsdtar_ldstatic = -@STATIC_BSDTAR_TRUE@bsdtar_ldstatic = -static -@STATIC_BSDTAR_FALSE@bsdtar_ccstatic = -@STATIC_BSDTAR_TRUE@bsdtar_ccstatic = -DLIBARCHIVE_STATIC -bsdtar_LDADD = libarchive.la libarchive_fe.la $(LTLIBICONV) -bsdtar_CPPFLAGS = -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe $(bsdtar_ccstatic) $(PLATFORMCPPFLAGS) -bsdtar_LDFLAGS = $(bsdtar_ldstatic) $(GC_SECTIONS) -bsdtar_EXTRA_DIST = \ - tar/bsdtar.1 \ - tar/bsdtar_windows.h \ - tar/bsdtar_windows.c \ - tar/CMakeLists.txt \ - tar/config_freebsd.h - -@BUILD_BSDTAR_FALSE@bsdtar_man_MANS = -@BUILD_BSDTAR_TRUE@bsdtar_man_MANS = tar/bsdtar.1 -@BUILD_BSDTAR_FALSE@bsdtar_programs = -@BUILD_BSDTAR_TRUE@bsdtar_programs = bsdtar - -# -# bsdtar_test -# -bsdtar_test_SOURCES = \ - $(test_utils_SOURCES) \ - tar/test/test.h \ - tar/test/test_0.c \ - tar/test/test_basic.c \ - tar/test/test_copy.c \ - tar/test/test_empty_mtree.c \ - tar/test/test_extract_tar_Z.c \ - tar/test/test_extract_tar_bz2.c \ - tar/test/test_extract_tar_grz.c \ - tar/test/test_extract_tar_gz.c \ - tar/test/test_extract_tar_lrz.c \ - tar/test/test_extract_tar_lz.c \ - tar/test/test_extract_tar_lz4.c \ - tar/test/test_extract_tar_lzma.c \ - tar/test/test_extract_tar_lzo.c \ - tar/test/test_extract_tar_xz.c \ - tar/test/test_extract_tar_zstd.c \ - tar/test/test_format_newc.c \ - tar/test/test_help.c \ - tar/test/test_leading_slash.c \ - tar/test/test_missing_file.c \ - tar/test/test_option_C_mtree.c \ - tar/test/test_option_C_upper.c \ - tar/test/test_option_H_upper.c \ - tar/test/test_option_L_upper.c \ - tar/test/test_option_O_upper.c \ - tar/test/test_option_T_upper.c \ - tar/test/test_option_U_upper.c \ - tar/test/test_option_X_upper.c \ - tar/test/test_option_acls.c \ - tar/test/test_option_a.c \ - tar/test/test_option_b.c \ - tar/test/test_option_b64encode.c \ - tar/test/test_option_exclude.c \ - tar/test/test_option_exclude_vcs.c \ - tar/test/test_option_fflags.c \ - tar/test/test_option_gid_gname.c \ - tar/test/test_option_grzip.c \ - tar/test/test_option_ignore_zeros.c \ - tar/test/test_option_j.c \ - tar/test/test_option_k.c \ - tar/test/test_option_keep_newer_files.c \ - tar/test/test_option_lrzip.c \ - tar/test/test_option_lz4.c \ - tar/test/test_option_lzma.c \ - tar/test/test_option_lzop.c \ - tar/test/test_option_n.c \ - tar/test/test_option_newer_than.c \ - tar/test/test_option_nodump.c \ - tar/test/test_option_older_than.c \ - tar/test/test_option_passphrase.c \ - tar/test/test_option_q.c \ - tar/test/test_option_r.c \ - tar/test/test_option_s.c \ - tar/test/test_option_safe_writes.c \ - tar/test/test_option_uid_uname.c \ - tar/test/test_option_uuencode.c \ - tar/test/test_option_xattrs.c \ - tar/test/test_option_xz.c \ - tar/test/test_option_z.c \ - tar/test/test_option_zstd.c \ - tar/test/test_patterns.c \ - tar/test/test_print_longpath.c \ - tar/test/test_stdio.c \ - tar/test/test_strip_components.c \ - tar/test/test_symlink_dir.c \ - tar/test/test_version.c \ - tar/test/test_windows.c - -bsdtar_test_CPPFLAGS = \ - -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe \ - -I$(top_srcdir)/test_utils \ - -I$(top_srcdir)/tar -I$(top_srcdir)/tar/test \ - -I$(top_builddir)/tar/test \ - $(PLATFORMCPPFLAGS) - -@BUILD_BSDTAR_FALSE@bsdtar_test_programs = -@BUILD_BSDTAR_TRUE@bsdtar_test_programs = bsdtar_test -@BUILD_BSDTAR_FALSE@bsdtar_TESTS_ENVIRONMENT = -@BUILD_BSDTAR_TRUE@bsdtar_TESTS_ENVIRONMENT = BSDTAR=`cd $(top_builddir);/bin/pwd`/bsdtar$(EXEEXT) BSDTAR_TEST_FILES=`cd $(top_srcdir);/bin/pwd`/tar/test -bsdtar_test_EXTRA_DIST = \ - tar/test/list.h \ - tar/test/test_extract.tar.Z.uu \ - tar/test/test_extract.tar.bz2.uu \ - tar/test/test_extract.tar.grz.uu \ - tar/test/test_extract.tar.gz.uu \ - tar/test/test_extract.tar.lrz.uu \ - tar/test/test_extract.tar.lz.uu \ - tar/test/test_extract.tar.lz4.uu \ - tar/test/test_extract.tar.zst.uu \ - tar/test/test_extract.tar.lzma.uu \ - tar/test/test_extract.tar.lzo.uu \ - tar/test/test_extract.tar.xz.uu \ - tar/test/test_leading_slash.tar.uu \ - tar/test/test_option_keep_newer_files.tar.Z.uu \ - tar/test/test_option_passphrase.zip.uu \ - tar/test/test_option_s.tar.Z.uu \ - tar/test/test_patterns_2.tar.uu \ - tar/test/test_patterns_3.tar.uu \ - tar/test/test_patterns_4.tar.uu \ - tar/test/test_print_longpath.tar.Z.uu \ - tar/test/CMakeLists.txt - - -# -# -# bsdcpio source, docs, etc. -# -# -bsdcpio_SOURCES = cpio/cmdline.c cpio/cpio.c cpio/cpio.h \ - cpio/cpio_platform.h $(am__append_8) -bsdcpio_DEPENDENCIES = libarchive.la libarchive_fe.la -@STATIC_BSDCPIO_FALSE@bsdcpio_ldstatic = -@STATIC_BSDCPIO_TRUE@bsdcpio_ldstatic = -static -@STATIC_BSDCPIO_FALSE@bsdcpio_ccstatic = -@STATIC_BSDCPIO_TRUE@bsdcpio_ccstatic = -DLIBARCHIVE_STATIC -bsdcpio_LDADD = libarchive_fe.la libarchive.la $(LTLIBICONV) -bsdcpio_CPPFLAGS = -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe $(bsdcpio_ccstatic) $(PLATFORMCPPFLAGS) -bsdcpio_LDFLAGS = $(bsdcpio_ldstatic) $(GC_SECTIONS) -bsdcpio_EXTRA_DIST = \ - cpio/bsdcpio.1 \ - cpio/cpio_windows.h \ - cpio/cpio_windows.c \ - cpio/CMakeLists.txt \ - cpio/config_freebsd.h - -@BUILD_BSDCPIO_FALSE@bsdcpio_man_MANS = - -# Manpages to install -@BUILD_BSDCPIO_TRUE@bsdcpio_man_MANS = cpio/bsdcpio.1 -@BUILD_BSDCPIO_FALSE@bsdcpio_programs = -@BUILD_BSDCPIO_TRUE@bsdcpio_programs = bsdcpio - -# -# bsdcpio_test -# -bsdcpio_test_SOURCES = \ - $(test_utils_SOURCES) \ - cpio/cmdline.c \ - cpio/test/test.h \ - cpio/test/test_0.c \ - cpio/test/test_basic.c \ - cpio/test/test_cmdline.c \ - cpio/test/test_extract_cpio_Z.c \ - cpio/test/test_extract_cpio_bz2.c \ - cpio/test/test_extract_cpio_grz.c \ - cpio/test/test_extract_cpio_gz.c \ - cpio/test/test_extract_cpio_lrz.c \ - cpio/test/test_extract_cpio_lz.c \ - cpio/test/test_extract_cpio_lz4.c \ - cpio/test/test_extract_cpio_lzma.c \ - cpio/test/test_extract_cpio_lzo.c \ - cpio/test/test_extract_cpio_xz.c \ - cpio/test/test_extract_cpio_zstd.c \ - cpio/test/test_format_newc.c \ - cpio/test/test_gcpio_compat.c \ - cpio/test/test_missing_file.c \ - cpio/test/test_option_0.c \ - cpio/test/test_option_B_upper.c \ - cpio/test/test_option_C_upper.c \ - cpio/test/test_option_J_upper.c \ - cpio/test/test_option_L_upper.c \ - cpio/test/test_option_Z_upper.c \ - cpio/test/test_option_a.c \ - cpio/test/test_option_b64encode.c \ - cpio/test/test_option_c.c \ - cpio/test/test_option_d.c \ - cpio/test/test_option_f.c \ - cpio/test/test_option_grzip.c \ - cpio/test/test_option_help.c \ - cpio/test/test_option_l.c \ - cpio/test/test_option_lrzip.c \ - cpio/test/test_option_lz4.c \ - cpio/test/test_option_lzma.c \ - cpio/test/test_option_lzop.c \ - cpio/test/test_option_m.c \ - cpio/test/test_option_passphrase.c \ - cpio/test/test_option_t.c \ - cpio/test/test_option_u.c \ - cpio/test/test_option_uuencode.c \ - cpio/test/test_option_version.c \ - cpio/test/test_option_xz.c \ - cpio/test/test_option_y.c \ - cpio/test/test_option_z.c \ - cpio/test/test_option_zstd.c \ - cpio/test/test_owner_parse.c \ - cpio/test/test_passthrough_dotdot.c \ - cpio/test/test_passthrough_reverse.c - -bsdcpio_test_CPPFLAGS = \ - -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe \ - -I$(top_srcdir)/test_utils \ - -I$(top_srcdir)/cpio -I$(top_srcdir)/cpio/test \ - -I$(top_builddir)/cpio/test \ - $(PLATFORMCPPFLAGS) - -bsdcpio_test_LDADD = libarchive_fe.la -@BUILD_BSDCPIO_FALSE@bsdcpio_test_programs = -@BUILD_BSDCPIO_TRUE@bsdcpio_test_programs = bsdcpio_test -@BUILD_BSDCPIO_FALSE@bsdcpio_TESTS_ENVIRONMENT = -@BUILD_BSDCPIO_TRUE@bsdcpio_TESTS_ENVIRONMENT = BSDCPIO=`cd $(top_builddir);/bin/pwd`/bsdcpio$(EXEEXT) BSDCPIO_TEST_FILES=`cd $(top_srcdir);/bin/pwd`/cpio/test -bsdcpio_test_EXTRA_DIST = \ - cpio/test/list.h \ - cpio/test/test_extract.cpio.Z.uu \ - cpio/test/test_extract.cpio.bz2.uu \ - cpio/test/test_extract.cpio.grz.uu \ - cpio/test/test_extract.cpio.gz.uu \ - cpio/test/test_extract.cpio.lrz.uu \ - cpio/test/test_extract.cpio.lz.uu \ - cpio/test/test_extract.cpio.lz4.uu \ - cpio/test/test_extract.cpio.zst.uu \ - cpio/test/test_extract.cpio.lzma.uu \ - cpio/test/test_extract.cpio.lzo.uu \ - cpio/test/test_extract.cpio.xz.uu \ - cpio/test/test_gcpio_compat_ref.bin.uu \ - cpio/test/test_gcpio_compat_ref.crc.uu \ - cpio/test/test_gcpio_compat_ref.newc.uu \ - cpio/test/test_gcpio_compat_ref.ustar.uu \ - cpio/test/test_gcpio_compat_ref_nosym.bin.uu \ - cpio/test/test_gcpio_compat_ref_nosym.crc.uu \ - cpio/test/test_gcpio_compat_ref_nosym.newc.uu \ - cpio/test/test_gcpio_compat_ref_nosym.ustar.uu \ - cpio/test/test_option_f.cpio.uu \ - cpio/test/test_option_m.cpio.uu \ - cpio/test/test_option_passphrase.zip.uu \ - cpio/test/test_option_t.cpio.uu \ - cpio/test/test_option_t.stdout.uu \ - cpio/test/test_option_tv.stdout.uu \ - cpio/test/CMakeLists.txt - - -# -# -# bsdcat source, docs, etc. -# -# -bsdcat_SOURCES = cat/bsdcat.c cat/bsdcat.h cat/bsdcat_platform.h \ - cat/cmdline.c $(am__append_9) -bsdcat_DEPENDENCIES = libarchive.la libarchive_fe.la -@STATIC_BSDCAT_FALSE@bsdcat_ldstatic = -@STATIC_BSDCAT_TRUE@bsdcat_ldstatic = -static -@STATIC_BSDCAT_FALSE@bsdcat_ccstatic = -@STATIC_BSDCAT_TRUE@bsdcat_ccstatic = -DLIBARCHIVE_STATIC -bsdcat_LDADD = libarchive_fe.la libarchive.la $(LTLIBICONV) -bsdcat_CPPFLAGS = -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe $(bsdcat_ccstatic) $(PLATFORMCPPFLAGS) -bsdcat_LDFLAGS = $(bsdcat_ldstatic) $(GC_SECTIONS) -bsdcat_EXTRA_DIST = \ - cat/bsdcat.1 \ - cat/CMakeLists.txt - -@BUILD_BSDCAT_FALSE@bsdcat_man_MANS = - -# Manpages to install -@BUILD_BSDCAT_TRUE@bsdcat_man_MANS = cat/bsdcat.1 -@BUILD_BSDCAT_FALSE@bsdcat_programs = -@BUILD_BSDCAT_TRUE@bsdcat_programs = bsdcat - -# -# bsdcat_test -# -bsdcat_test_SOURCES = \ - $(test_utils_SOURCES) \ - cat/test/test.h \ - cat/test/test_0.c \ - cat/test/test_empty_gz.c \ - cat/test/test_empty_lz4.c \ - cat/test/test_empty_xz.c \ - cat/test/test_empty_zstd.c \ - cat/test/test_error.c \ - cat/test/test_error_mixed.c \ - cat/test/test_expand_Z.c \ - cat/test/test_expand_bz2.c \ - cat/test/test_expand_gz.c \ - cat/test/test_expand_lz4.c \ - cat/test/test_expand_mixed.c \ - cat/test/test_expand_plain.c \ - cat/test/test_expand_xz.c \ - cat/test/test_expand_zstd.c \ - cat/test/test_help.c \ - cat/test/test_stdin.c \ - cat/test/test_version.c - -bsdcat_test_CPPFLAGS = \ - -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe \ - -I$(top_srcdir)/test_utils \ - -I$(top_srcdir)/cat -I$(top_srcdir)/cat/test \ - -I$(top_builddir)/cat/test \ - $(PLATFORMCPPFLAGS) - -bsdcat_test_LDADD = libarchive_fe.la -@BUILD_BSDCAT_FALSE@bsdcat_test_programs = -@BUILD_BSDCAT_TRUE@bsdcat_test_programs = bsdcat_test -@BUILD_BSDCAT_FALSE@bsdcat_TESTS_ENVIRONMENT = -@BUILD_BSDCAT_TRUE@bsdcat_TESTS_ENVIRONMENT = BSDCAT=`cd $(top_builddir);/bin/pwd`/bsdcat$(EXEEXT) BSDCAT_TEST_FILES=`cd $(top_srcdir);/bin/pwd`/cat/test -bsdcat_test_EXTRA_DIST = \ - cat/test/list.h \ - cat/test/test_empty.gz.uu \ - cat/test/test_empty.lz4.uu \ - cat/test/test_empty.zst.uu \ - cat/test/test_empty.xz.uu \ - cat/test/test_expand.Z.uu \ - cat/test/test_expand.bz2.uu \ - cat/test/test_expand.gz.uu \ - cat/test/test_expand.lz4.uu \ - cat/test/test_expand.zst.uu \ - cat/test/test_expand.plain.uu \ - cat/test/test_expand.xz.uu \ - cat/test/CMakeLists.txt - - -# -# -# bsdunzip source, docs, etc. -# -# -bsdunzip_SOURCES = unzip/bsdunzip.c unzip/bsdunzip.h \ - unzip/bsdunzip_platform.h unzip/cmdline.c unzip/la_getline.c \ - unzip/la_queue.h $(am__append_10) -bsdunzip_DEPENDENCIES = libarchive.la libarchive_fe.la -@STATIC_BSDUNZIP_FALSE@bsdunzip_ldstatic = -@STATIC_BSDUNZIP_TRUE@bsdunzip_ldstatic = -static -@STATIC_BSDUNZIP_FALSE@bsdunzip_ccstatic = -@STATIC_BSDUNZIP_TRUE@bsdunzip_ccstatic = -DLIBARCHIVE_STATIC -bsdunzip_LDADD = libarchive_fe.la libarchive.la $(LTLIBICONV) -bsdunzip_CPPFLAGS = -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe $(bsdunzip_ccstatic) $(PLATFORMCPPFLAGS) -bsdunzip_LDFLAGS = $(bsdunzip_ldstatic) $(GC_SECTIONS) -bsdunzip_EXTRA_DIST = \ - unzip/bsdunzip.1 \ - unzip/CMakeLists.txt - -@BUILD_BSDUNZIP_FALSE@bsdunzip_man_MANS = - -# Manpages to install -@BUILD_BSDUNZIP_TRUE@bsdunzip_man_MANS = unzip/bsdunzip.1 -@BUILD_BSDUNZIP_FALSE@bsdunzip_programs = -@BUILD_BSDUNZIP_TRUE@bsdunzip_programs = bsdunzip - -# -# bsdunzip_test -# -bsdunzip_test_SOURCES = \ - $(test_utils_SOURCES) \ - unzip/test/test.h \ - unzip/test/test_0.c \ - unzip/test/test_basic.c \ - unzip/test/test_glob.c \ - unzip/test/test_not_exist.c \ - unzip/test/test_singlefile.c \ - unzip/test/test_C.c \ - unzip/test/test_p.c \ - unzip/test/test_d.c \ - unzip/test/test_j.c \ - unzip/test/test_L.c \ - unzip/test/test_n.c \ - unzip/test/test_o.c \ - unzip/test/test_q.c \ - unzip/test/test_t.c \ - unzip/test/test_t_bad.c \ - unzip/test/test_version.c \ - unzip/test/test_x.c \ - unzip/test/test_Z1.c \ - unzip/test/test_P_encryption.c - -bsdunzip_test_CPPFLAGS = \ - -I$(top_srcdir)/libarchive -I$(top_srcdir)/libarchive_fe \ - -I$(top_srcdir)/test_utils \ - -I$(top_srcdir)/unzip -I$(top_srcdir)/unzip/test \ - -I$(top_builddir)/unzip/test \ - $(PLATFORMCPPFLAGS) - -bsdunzip_test_LDADD = libarchive_fe.la -@BUILD_BSDUNZIP_FALSE@bsdunzip_test_programs = -@BUILD_BSDUNZIP_TRUE@bsdunzip_test_programs = bsdunzip_test -@BUILD_BSDUNZIP_FALSE@bsdunzip_TESTS_ENVIRONMENT = -@BUILD_BSDUNZIP_TRUE@bsdunzip_TESTS_ENVIRONMENT = BSDUNZIP=`cd $(top_builddir);/bin/pwd`/bsdunzip$(EXEEXT) BSDUNZIP_TEST_FILES=`cd $(top_srcdir);/bin/pwd`/unzip/test -bsdunzip_test_EXTRA_DIST = \ - unzip/test/list.h \ - unzip/test/test_basic.zip.uu \ - unzip/test/test_encrypted.zip.uu \ - unzip/test/test_singlefile.zip.uu \ - unzip/test/test_t_bad.zip.uu \ - unzip/test/CMakeLists.txt - -all: $(BUILT_SOURCES) config.h - $(MAKE) $(AM_MAKEFLAGS) all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs -am--refresh: Makefile - @: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ - $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - echo ' $(SHELL) ./config.status'; \ - $(SHELL) ./config.status;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - $(SHELL) ./config.status --recheck - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - $(am__cd) $(srcdir) && $(AUTOCONF) -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) -$(am__aclocal_m4_deps): - -config.h: stamp-h1 - @test -f $@ || rm -f stamp-h1 - @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 - -stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status - @rm -f stamp-h1 - cd $(top_builddir) && $(SHELL) ./config.status config.h -$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) - rm -f stamp-h1 - touch $@ - -distclean-hdr: - -rm -f config.h stamp-h1 -build/pkgconfig/libarchive.pc: $(top_builddir)/config.status $(top_srcdir)/build/pkgconfig/libarchive.pc.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -install-binPROGRAMS: $(bin_PROGRAMS) - @$(NORMAL_INSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ - fi; \ - for p in $$list; do echo "$$p $$p"; done | \ - sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p \ - || test -f $$p1 \ - ; then echo "$$p"; echo "$$p"; else :; fi; \ - done | \ - sed -e 'p;s,.*/,,;n;h' \ - -e 's|.*|.|' \ - -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ - sed 'N;N;N;s,\n, ,g' | \ - $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ - { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ - if ($$2 == $$4) files[d] = files[d] " " $$1; \ - else { print "f", $$3 "/" $$4, $$1; } } \ - END { for (d in files) print "f", d, files[d] }' | \ - while read type dir files; do \ - if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ - test -z "$$files" || { \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ - } \ - ; done - -uninstall-binPROGRAMS: - @$(NORMAL_UNINSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - files=`for p in $$list; do echo "$$p"; done | \ - sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' \ - `; \ - test -n "$$list" || exit 0; \ - echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(bindir)" && rm -f $$files - -clean-binPROGRAMS: - @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list - -clean-checkPROGRAMS: - @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list - -install-libLTLIBRARIES: $(lib_LTLIBRARIES) - @$(NORMAL_INSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - list2=; for p in $$list; do \ - if test -f $$p; then \ - list2="$$list2 $$p"; \ - else :; fi; \ - done; \ - test -z "$$list2" || { \ - echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ - } - -uninstall-libLTLIBRARIES: - @$(NORMAL_UNINSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ - done - -clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - @list='$(lib_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } - -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } -libarchive/$(am__dirstamp): - @$(MKDIR_P) libarchive - @: > libarchive/$(am__dirstamp) -libarchive/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) libarchive/$(DEPDIR) - @: > libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_acl.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_check_magic.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_cmdline.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_cryptor.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_digest.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_entry.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_entry_copy_stat.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_entry_link_resolver.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_entry_sparse.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_entry_stat.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_entry_strmode.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_entry_xattr.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_getdate.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_hmac.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_match.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_options.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_pack_dev.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_pathmatch.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_ppmd7.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_ppmd8.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_random.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_rb.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_add_passphrase.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_append_filter.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_data_into_fd.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_disk_entry_from_file.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_disk_posix.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_disk_set_standard_lookup.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_extract.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_extract2.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_open_fd.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_open_file.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_open_filename.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_open_memory.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_set_format.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_set_options.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_filter_all.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_filter_bzip2.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_filter_by_code.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_filter_compress.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_filter_grzip.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_filter_gzip.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_filter_lrzip.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_filter_lz4.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_filter_lzop.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_filter_none.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_filter_program.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_filter_rpm.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_filter_uu.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_filter_xz.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_filter_zstd.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_format_7zip.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_format_all.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_format_ar.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_format_by_code.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_format_cab.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_format_cpio.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_format_empty.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_format_iso9660.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_format_lha.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_format_mtree.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_format_rar.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_format_rar5.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_format_raw.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_format_tar.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_format_warc.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_format_xar.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_support_format_zip.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_string.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_string_sprintf.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_util.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_version_details.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_virtual.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_disk_posix.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_disk_set_standard_lookup.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_open_fd.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_open_file.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_open_filename.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_open_memory.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_add_filter.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_add_filter_b64encode.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_add_filter_by_name.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_add_filter_bzip2.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_add_filter_compress.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_add_filter_grzip.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_add_filter_gzip.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_add_filter_lrzip.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_add_filter_lz4.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_add_filter_lzop.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_add_filter_none.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_add_filter_program.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_add_filter_uuencode.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_add_filter_xz.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_add_filter_zstd.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_set_format.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_set_format_7zip.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_set_format_ar.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_set_format_by_name.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_set_format_cpio.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_set_format_cpio_binary.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_set_format_cpio_newc.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_set_format_cpio_odc.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_set_format_filter_by_ext.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_set_format_iso9660.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_set_format_mtree.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_set_format_pax.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_set_format_raw.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_set_format_shar.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_set_format_ustar.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_set_format_v7tar.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_set_format_gnutar.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_set_format_warc.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_set_format_xar.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_set_format_zip.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_set_options.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_set_passphrase.lo: \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/filter_fork_posix.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/xxhash.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_entry_copy_bhfi.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_read_disk_windows.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_windows.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_write_disk_windows.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/filter_fork_windows.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_blake2s_ref.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_blake2sp_ref.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_disk_acl_linux.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_disk_acl_sunos.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_disk_acl_darwin.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/archive_disk_acl_freebsd.lo: libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) - -libarchive.la: $(libarchive_la_OBJECTS) $(libarchive_la_DEPENDENCIES) $(EXTRA_libarchive_la_DEPENDENCIES) - $(AM_V_CCLD)$(libarchive_la_LINK) -rpath $(libdir) $(libarchive_la_OBJECTS) $(libarchive_la_LIBADD) $(LIBS) -libarchive_fe/$(am__dirstamp): - @$(MKDIR_P) libarchive_fe - @: > libarchive_fe/$(am__dirstamp) -libarchive_fe/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) libarchive_fe/$(DEPDIR) - @: > libarchive_fe/$(DEPDIR)/$(am__dirstamp) -libarchive_fe/la-err.lo: libarchive_fe/$(am__dirstamp) \ - libarchive_fe/$(DEPDIR)/$(am__dirstamp) -libarchive_fe/la-line_reader.lo: libarchive_fe/$(am__dirstamp) \ - libarchive_fe/$(DEPDIR)/$(am__dirstamp) -libarchive_fe/la-passphrase.lo: libarchive_fe/$(am__dirstamp) \ - libarchive_fe/$(DEPDIR)/$(am__dirstamp) - -libarchive_fe.la: $(libarchive_fe_la_OBJECTS) $(libarchive_fe_la_DEPENDENCIES) $(EXTRA_libarchive_fe_la_DEPENDENCIES) - $(AM_V_CCLD)$(LINK) $(libarchive_fe_la_OBJECTS) $(libarchive_fe_la_LIBADD) $(LIBS) -cat/$(am__dirstamp): - @$(MKDIR_P) cat - @: > cat/$(am__dirstamp) -cat/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) cat/$(DEPDIR) - @: > cat/$(DEPDIR)/$(am__dirstamp) -cat/bsdcat-bsdcat.$(OBJEXT): cat/$(am__dirstamp) \ - cat/$(DEPDIR)/$(am__dirstamp) -cat/bsdcat-cmdline.$(OBJEXT): cat/$(am__dirstamp) \ - cat/$(DEPDIR)/$(am__dirstamp) - -bsdcat$(EXEEXT): $(bsdcat_OBJECTS) $(bsdcat_DEPENDENCIES) $(EXTRA_bsdcat_DEPENDENCIES) - @rm -f bsdcat$(EXEEXT) - $(AM_V_CCLD)$(bsdcat_LINK) $(bsdcat_OBJECTS) $(bsdcat_LDADD) $(LIBS) -test_utils/$(am__dirstamp): - @$(MKDIR_P) test_utils - @: > test_utils/$(am__dirstamp) -test_utils/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) test_utils/$(DEPDIR) - @: > test_utils/$(DEPDIR)/$(am__dirstamp) -test_utils/bsdcat_test-test_utils.$(OBJEXT): \ - test_utils/$(am__dirstamp) \ - test_utils/$(DEPDIR)/$(am__dirstamp) -test_utils/bsdcat_test-test_main.$(OBJEXT): \ - test_utils/$(am__dirstamp) \ - test_utils/$(DEPDIR)/$(am__dirstamp) -cat/test/$(am__dirstamp): - @$(MKDIR_P) cat/test - @: > cat/test/$(am__dirstamp) -cat/test/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) cat/test/$(DEPDIR) - @: > cat/test/$(DEPDIR)/$(am__dirstamp) -cat/test/bsdcat_test-test_0.$(OBJEXT): cat/test/$(am__dirstamp) \ - cat/test/$(DEPDIR)/$(am__dirstamp) -cat/test/bsdcat_test-test_empty_gz.$(OBJEXT): \ - cat/test/$(am__dirstamp) cat/test/$(DEPDIR)/$(am__dirstamp) -cat/test/bsdcat_test-test_empty_lz4.$(OBJEXT): \ - cat/test/$(am__dirstamp) cat/test/$(DEPDIR)/$(am__dirstamp) -cat/test/bsdcat_test-test_empty_xz.$(OBJEXT): \ - cat/test/$(am__dirstamp) cat/test/$(DEPDIR)/$(am__dirstamp) -cat/test/bsdcat_test-test_empty_zstd.$(OBJEXT): \ - cat/test/$(am__dirstamp) cat/test/$(DEPDIR)/$(am__dirstamp) -cat/test/bsdcat_test-test_error.$(OBJEXT): cat/test/$(am__dirstamp) \ - cat/test/$(DEPDIR)/$(am__dirstamp) -cat/test/bsdcat_test-test_error_mixed.$(OBJEXT): \ - cat/test/$(am__dirstamp) cat/test/$(DEPDIR)/$(am__dirstamp) -cat/test/bsdcat_test-test_expand_Z.$(OBJEXT): \ - cat/test/$(am__dirstamp) cat/test/$(DEPDIR)/$(am__dirstamp) -cat/test/bsdcat_test-test_expand_bz2.$(OBJEXT): \ - cat/test/$(am__dirstamp) cat/test/$(DEPDIR)/$(am__dirstamp) -cat/test/bsdcat_test-test_expand_gz.$(OBJEXT): \ - cat/test/$(am__dirstamp) cat/test/$(DEPDIR)/$(am__dirstamp) -cat/test/bsdcat_test-test_expand_lz4.$(OBJEXT): \ - cat/test/$(am__dirstamp) cat/test/$(DEPDIR)/$(am__dirstamp) -cat/test/bsdcat_test-test_expand_mixed.$(OBJEXT): \ - cat/test/$(am__dirstamp) cat/test/$(DEPDIR)/$(am__dirstamp) -cat/test/bsdcat_test-test_expand_plain.$(OBJEXT): \ - cat/test/$(am__dirstamp) cat/test/$(DEPDIR)/$(am__dirstamp) -cat/test/bsdcat_test-test_expand_xz.$(OBJEXT): \ - cat/test/$(am__dirstamp) cat/test/$(DEPDIR)/$(am__dirstamp) -cat/test/bsdcat_test-test_expand_zstd.$(OBJEXT): \ - cat/test/$(am__dirstamp) cat/test/$(DEPDIR)/$(am__dirstamp) -cat/test/bsdcat_test-test_help.$(OBJEXT): cat/test/$(am__dirstamp) \ - cat/test/$(DEPDIR)/$(am__dirstamp) -cat/test/bsdcat_test-test_stdin.$(OBJEXT): cat/test/$(am__dirstamp) \ - cat/test/$(DEPDIR)/$(am__dirstamp) -cat/test/bsdcat_test-test_version.$(OBJEXT): cat/test/$(am__dirstamp) \ - cat/test/$(DEPDIR)/$(am__dirstamp) - -bsdcat_test$(EXEEXT): $(bsdcat_test_OBJECTS) $(bsdcat_test_DEPENDENCIES) $(EXTRA_bsdcat_test_DEPENDENCIES) - @rm -f bsdcat_test$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(bsdcat_test_OBJECTS) $(bsdcat_test_LDADD) $(LIBS) -cpio/$(am__dirstamp): - @$(MKDIR_P) cpio - @: > cpio/$(am__dirstamp) -cpio/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) cpio/$(DEPDIR) - @: > cpio/$(DEPDIR)/$(am__dirstamp) -cpio/bsdcpio-cmdline.$(OBJEXT): cpio/$(am__dirstamp) \ - cpio/$(DEPDIR)/$(am__dirstamp) -cpio/bsdcpio-cpio.$(OBJEXT): cpio/$(am__dirstamp) \ - cpio/$(DEPDIR)/$(am__dirstamp) -cpio/bsdcpio-cpio_windows.$(OBJEXT): cpio/$(am__dirstamp) \ - cpio/$(DEPDIR)/$(am__dirstamp) - -bsdcpio$(EXEEXT): $(bsdcpio_OBJECTS) $(bsdcpio_DEPENDENCIES) $(EXTRA_bsdcpio_DEPENDENCIES) - @rm -f bsdcpio$(EXEEXT) - $(AM_V_CCLD)$(bsdcpio_LINK) $(bsdcpio_OBJECTS) $(bsdcpio_LDADD) $(LIBS) -test_utils/bsdcpio_test-test_utils.$(OBJEXT): \ - test_utils/$(am__dirstamp) \ - test_utils/$(DEPDIR)/$(am__dirstamp) -test_utils/bsdcpio_test-test_main.$(OBJEXT): \ - test_utils/$(am__dirstamp) \ - test_utils/$(DEPDIR)/$(am__dirstamp) -cpio/bsdcpio_test-cmdline.$(OBJEXT): cpio/$(am__dirstamp) \ - cpio/$(DEPDIR)/$(am__dirstamp) -cpio/test/$(am__dirstamp): - @$(MKDIR_P) cpio/test - @: > cpio/test/$(am__dirstamp) -cpio/test/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) cpio/test/$(DEPDIR) - @: > cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_0.$(OBJEXT): cpio/test/$(am__dirstamp) \ - cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_basic.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_cmdline.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_extract_cpio_Z.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_extract_cpio_bz2.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_extract_cpio_grz.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_extract_cpio_gz.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_extract_cpio_lrz.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_extract_cpio_lz.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_extract_cpio_lz4.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_extract_cpio_lzma.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_extract_cpio_lzo.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_extract_cpio_xz.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_extract_cpio_zstd.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_format_newc.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_gcpio_compat.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_missing_file.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_0.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_B_upper.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_C_upper.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_J_upper.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_L_upper.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_Z_upper.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_a.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_b64encode.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_c.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_d.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_f.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_grzip.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_help.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_l.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_lrzip.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_lz4.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_lzma.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_lzop.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_m.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_passphrase.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_t.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_u.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_uuencode.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_version.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_xz.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_y.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_z.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_option_zstd.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_owner_parse.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_passthrough_dotdot.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) -cpio/test/bsdcpio_test-test_passthrough_reverse.$(OBJEXT): \ - cpio/test/$(am__dirstamp) cpio/test/$(DEPDIR)/$(am__dirstamp) - -bsdcpio_test$(EXEEXT): $(bsdcpio_test_OBJECTS) $(bsdcpio_test_DEPENDENCIES) $(EXTRA_bsdcpio_test_DEPENDENCIES) - @rm -f bsdcpio_test$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(bsdcpio_test_OBJECTS) $(bsdcpio_test_LDADD) $(LIBS) -tar/$(am__dirstamp): - @$(MKDIR_P) tar - @: > tar/$(am__dirstamp) -tar/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) tar/$(DEPDIR) - @: > tar/$(DEPDIR)/$(am__dirstamp) -tar/bsdtar-bsdtar.$(OBJEXT): tar/$(am__dirstamp) \ - tar/$(DEPDIR)/$(am__dirstamp) -tar/bsdtar-cmdline.$(OBJEXT): tar/$(am__dirstamp) \ - tar/$(DEPDIR)/$(am__dirstamp) -tar/bsdtar-creation_set.$(OBJEXT): tar/$(am__dirstamp) \ - tar/$(DEPDIR)/$(am__dirstamp) -tar/bsdtar-read.$(OBJEXT): tar/$(am__dirstamp) \ - tar/$(DEPDIR)/$(am__dirstamp) -tar/bsdtar-subst.$(OBJEXT): tar/$(am__dirstamp) \ - tar/$(DEPDIR)/$(am__dirstamp) -tar/bsdtar-util.$(OBJEXT): tar/$(am__dirstamp) \ - tar/$(DEPDIR)/$(am__dirstamp) -tar/bsdtar-write.$(OBJEXT): tar/$(am__dirstamp) \ - tar/$(DEPDIR)/$(am__dirstamp) -tar/bsdtar-bsdtar_windows.$(OBJEXT): tar/$(am__dirstamp) \ - tar/$(DEPDIR)/$(am__dirstamp) - -bsdtar$(EXEEXT): $(bsdtar_OBJECTS) $(bsdtar_DEPENDENCIES) $(EXTRA_bsdtar_DEPENDENCIES) - @rm -f bsdtar$(EXEEXT) - $(AM_V_CCLD)$(bsdtar_LINK) $(bsdtar_OBJECTS) $(bsdtar_LDADD) $(LIBS) -test_utils/bsdtar_test-test_utils.$(OBJEXT): \ - test_utils/$(am__dirstamp) \ - test_utils/$(DEPDIR)/$(am__dirstamp) -test_utils/bsdtar_test-test_main.$(OBJEXT): \ - test_utils/$(am__dirstamp) \ - test_utils/$(DEPDIR)/$(am__dirstamp) -tar/test/$(am__dirstamp): - @$(MKDIR_P) tar/test - @: > tar/test/$(am__dirstamp) -tar/test/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) tar/test/$(DEPDIR) - @: > tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_0.$(OBJEXT): tar/test/$(am__dirstamp) \ - tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_basic.$(OBJEXT): tar/test/$(am__dirstamp) \ - tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_copy.$(OBJEXT): tar/test/$(am__dirstamp) \ - tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_empty_mtree.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_extract_tar_Z.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_extract_tar_bz2.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_extract_tar_grz.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_extract_tar_gz.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_extract_tar_lrz.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_extract_tar_lz.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_extract_tar_lz4.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_extract_tar_lzma.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_extract_tar_lzo.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_extract_tar_xz.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_extract_tar_zstd.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_format_newc.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_help.$(OBJEXT): tar/test/$(am__dirstamp) \ - tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_leading_slash.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_missing_file.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_C_mtree.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_C_upper.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_H_upper.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_L_upper.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_O_upper.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_T_upper.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_U_upper.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_X_upper.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_acls.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_a.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_b.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_b64encode.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_exclude.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_exclude_vcs.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_fflags.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_gid_gname.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_grzip.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_ignore_zeros.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_j.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_k.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_keep_newer_files.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_lrzip.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_lz4.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_lzma.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_lzop.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_n.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_newer_than.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_nodump.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_older_than.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_passphrase.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_q.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_r.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_s.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_safe_writes.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_uid_uname.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_uuencode.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_xattrs.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_xz.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_z.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_option_zstd.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_patterns.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_print_longpath.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_stdio.$(OBJEXT): tar/test/$(am__dirstamp) \ - tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_strip_components.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_symlink_dir.$(OBJEXT): \ - tar/test/$(am__dirstamp) tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_version.$(OBJEXT): tar/test/$(am__dirstamp) \ - tar/test/$(DEPDIR)/$(am__dirstamp) -tar/test/bsdtar_test-test_windows.$(OBJEXT): tar/test/$(am__dirstamp) \ - tar/test/$(DEPDIR)/$(am__dirstamp) - -bsdtar_test$(EXEEXT): $(bsdtar_test_OBJECTS) $(bsdtar_test_DEPENDENCIES) $(EXTRA_bsdtar_test_DEPENDENCIES) - @rm -f bsdtar_test$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(bsdtar_test_OBJECTS) $(bsdtar_test_LDADD) $(LIBS) -unzip/$(am__dirstamp): - @$(MKDIR_P) unzip - @: > unzip/$(am__dirstamp) -unzip/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) unzip/$(DEPDIR) - @: > unzip/$(DEPDIR)/$(am__dirstamp) -unzip/bsdunzip-bsdunzip.$(OBJEXT): unzip/$(am__dirstamp) \ - unzip/$(DEPDIR)/$(am__dirstamp) -unzip/bsdunzip-cmdline.$(OBJEXT): unzip/$(am__dirstamp) \ - unzip/$(DEPDIR)/$(am__dirstamp) -unzip/bsdunzip-la_getline.$(OBJEXT): unzip/$(am__dirstamp) \ - unzip/$(DEPDIR)/$(am__dirstamp) - -bsdunzip$(EXEEXT): $(bsdunzip_OBJECTS) $(bsdunzip_DEPENDENCIES) $(EXTRA_bsdunzip_DEPENDENCIES) - @rm -f bsdunzip$(EXEEXT) - $(AM_V_CCLD)$(bsdunzip_LINK) $(bsdunzip_OBJECTS) $(bsdunzip_LDADD) $(LIBS) -test_utils/bsdunzip_test-test_utils.$(OBJEXT): \ - test_utils/$(am__dirstamp) \ - test_utils/$(DEPDIR)/$(am__dirstamp) -test_utils/bsdunzip_test-test_main.$(OBJEXT): \ - test_utils/$(am__dirstamp) \ - test_utils/$(DEPDIR)/$(am__dirstamp) -unzip/test/$(am__dirstamp): - @$(MKDIR_P) unzip/test - @: > unzip/test/$(am__dirstamp) -unzip/test/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) unzip/test/$(DEPDIR) - @: > unzip/test/$(DEPDIR)/$(am__dirstamp) -unzip/test/bsdunzip_test-test_0.$(OBJEXT): unzip/test/$(am__dirstamp) \ - unzip/test/$(DEPDIR)/$(am__dirstamp) -unzip/test/bsdunzip_test-test_basic.$(OBJEXT): \ - unzip/test/$(am__dirstamp) \ - unzip/test/$(DEPDIR)/$(am__dirstamp) -unzip/test/bsdunzip_test-test_glob.$(OBJEXT): \ - unzip/test/$(am__dirstamp) \ - unzip/test/$(DEPDIR)/$(am__dirstamp) -unzip/test/bsdunzip_test-test_not_exist.$(OBJEXT): \ - unzip/test/$(am__dirstamp) \ - unzip/test/$(DEPDIR)/$(am__dirstamp) -unzip/test/bsdunzip_test-test_singlefile.$(OBJEXT): \ - unzip/test/$(am__dirstamp) \ - unzip/test/$(DEPDIR)/$(am__dirstamp) -unzip/test/bsdunzip_test-test_C.$(OBJEXT): unzip/test/$(am__dirstamp) \ - unzip/test/$(DEPDIR)/$(am__dirstamp) -unzip/test/bsdunzip_test-test_p.$(OBJEXT): unzip/test/$(am__dirstamp) \ - unzip/test/$(DEPDIR)/$(am__dirstamp) -unzip/test/bsdunzip_test-test_d.$(OBJEXT): unzip/test/$(am__dirstamp) \ - unzip/test/$(DEPDIR)/$(am__dirstamp) -unzip/test/bsdunzip_test-test_j.$(OBJEXT): unzip/test/$(am__dirstamp) \ - unzip/test/$(DEPDIR)/$(am__dirstamp) -unzip/test/bsdunzip_test-test_L.$(OBJEXT): unzip/test/$(am__dirstamp) \ - unzip/test/$(DEPDIR)/$(am__dirstamp) -unzip/test/bsdunzip_test-test_n.$(OBJEXT): unzip/test/$(am__dirstamp) \ - unzip/test/$(DEPDIR)/$(am__dirstamp) -unzip/test/bsdunzip_test-test_o.$(OBJEXT): unzip/test/$(am__dirstamp) \ - unzip/test/$(DEPDIR)/$(am__dirstamp) -unzip/test/bsdunzip_test-test_q.$(OBJEXT): unzip/test/$(am__dirstamp) \ - unzip/test/$(DEPDIR)/$(am__dirstamp) -unzip/test/bsdunzip_test-test_t.$(OBJEXT): unzip/test/$(am__dirstamp) \ - unzip/test/$(DEPDIR)/$(am__dirstamp) -unzip/test/bsdunzip_test-test_t_bad.$(OBJEXT): \ - unzip/test/$(am__dirstamp) \ - unzip/test/$(DEPDIR)/$(am__dirstamp) -unzip/test/bsdunzip_test-test_version.$(OBJEXT): \ - unzip/test/$(am__dirstamp) \ - unzip/test/$(DEPDIR)/$(am__dirstamp) -unzip/test/bsdunzip_test-test_x.$(OBJEXT): unzip/test/$(am__dirstamp) \ - unzip/test/$(DEPDIR)/$(am__dirstamp) -unzip/test/bsdunzip_test-test_Z1.$(OBJEXT): \ - unzip/test/$(am__dirstamp) \ - unzip/test/$(DEPDIR)/$(am__dirstamp) -unzip/test/bsdunzip_test-test_P_encryption.$(OBJEXT): \ - unzip/test/$(am__dirstamp) \ - unzip/test/$(DEPDIR)/$(am__dirstamp) - -bsdunzip_test$(EXEEXT): $(bsdunzip_test_OBJECTS) $(bsdunzip_test_DEPENDENCIES) $(EXTRA_bsdunzip_test_DEPENDENCIES) - @rm -f bsdunzip_test$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(bsdunzip_test_OBJECTS) $(bsdunzip_test_LDADD) $(LIBS) -libarchive/test-archive_acl.$(OBJEXT): libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_check_magic.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_cmdline.$(OBJEXT): libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_cryptor.$(OBJEXT): libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_digest.$(OBJEXT): libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_entry.$(OBJEXT): libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_entry_copy_stat.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_entry_link_resolver.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_entry_sparse.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_entry_stat.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_entry_strmode.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_entry_xattr.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_getdate.$(OBJEXT): libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_hmac.$(OBJEXT): libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_match.$(OBJEXT): libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_options.$(OBJEXT): libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_pack_dev.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_pathmatch.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_ppmd7.$(OBJEXT): libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_ppmd8.$(OBJEXT): libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_random.$(OBJEXT): libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_rb.$(OBJEXT): libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read.$(OBJEXT): libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_add_passphrase.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_append_filter.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_data_into_fd.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_disk_entry_from_file.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_disk_posix.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_disk_set_standard_lookup.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_extract.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_extract2.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_open_fd.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_open_file.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_open_filename.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_open_memory.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_set_format.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_set_options.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_filter_all.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_filter_bzip2.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_filter_by_code.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_filter_compress.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_filter_grzip.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_filter_gzip.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_filter_lrzip.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_filter_lz4.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_filter_lzop.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_filter_none.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_filter_program.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_filter_rpm.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_filter_uu.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_filter_xz.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_filter_zstd.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_format_7zip.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_format_all.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_format_ar.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_format_by_code.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_format_cab.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_format_cpio.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_format_empty.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_format_iso9660.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_format_lha.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_format_mtree.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_format_rar.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_format_rar5.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_format_raw.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_format_tar.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_format_warc.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_format_xar.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_support_format_zip.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_string.$(OBJEXT): libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_string_sprintf.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_util.$(OBJEXT): libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_version_details.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_virtual.$(OBJEXT): libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write.$(OBJEXT): libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_disk_posix.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_disk_set_standard_lookup.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_open_fd.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_open_file.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_open_filename.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_open_memory.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_add_filter.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_add_filter_b64encode.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_add_filter_by_name.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_add_filter_bzip2.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_add_filter_compress.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_add_filter_grzip.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_add_filter_gzip.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_add_filter_lrzip.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_add_filter_lz4.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_add_filter_lzop.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_add_filter_none.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_add_filter_program.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_add_filter_uuencode.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_add_filter_xz.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_add_filter_zstd.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_set_format.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_set_format_7zip.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_set_format_ar.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_set_format_by_name.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_set_format_cpio.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_set_format_cpio_binary.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_set_format_cpio_newc.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_set_format_cpio_odc.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_set_format_filter_by_ext.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_set_format_iso9660.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_set_format_mtree.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_set_format_pax.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_set_format_raw.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_set_format_shar.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_set_format_ustar.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_set_format_v7tar.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_set_format_gnutar.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_set_format_warc.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_set_format_xar.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_set_format_zip.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_set_options.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_set_passphrase.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-filter_fork_posix.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-xxhash.$(OBJEXT): libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_entry_copy_bhfi.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_read_disk_windows.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_windows.$(OBJEXT): libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_write_disk_windows.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-filter_fork_windows.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_blake2s_ref.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_blake2sp_ref.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_disk_acl_linux.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_disk_acl_sunos.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_disk_acl_darwin.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -libarchive/test-archive_disk_acl_freebsd.$(OBJEXT): \ - libarchive/$(am__dirstamp) \ - libarchive/$(DEPDIR)/$(am__dirstamp) -test_utils/libarchive_test-test_utils.$(OBJEXT): \ - test_utils/$(am__dirstamp) \ - test_utils/$(DEPDIR)/$(am__dirstamp) -test_utils/libarchive_test-test_main.$(OBJEXT): \ - test_utils/$(am__dirstamp) \ - test_utils/$(DEPDIR)/$(am__dirstamp) -libarchive/test/$(am__dirstamp): - @$(MKDIR_P) libarchive/test - @: > libarchive/test/$(am__dirstamp) -libarchive/test/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) libarchive/test/$(DEPDIR) - @: > libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-read_open_memory.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_acl_nfs4.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_acl_pax.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_acl_platform_nfs4.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_acl_platform_posix1e.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_acl_posix1e.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_acl_text.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_api_feature.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_clear_error.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_cmdline.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_digest.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_getdate.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_match_owner.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_match_path.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_match_time.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_pathmatch.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_read_add_passphrase.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_read_close_twice.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_read_close_twice_open_fd.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_read_close_twice_open_filename.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_read_multiple_data_objects.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_read_next_header_empty.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_read_next_header_raw.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_read_open2.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_read_set_filter_option.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_read_set_format_option.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_read_set_option.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_read_set_options.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_read_support.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_set_error.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_string.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_string_conversion.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_write_add_filter_by_name.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_write_set_filter_option.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_write_set_format_by_name.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_write_set_format_filter_by_ext.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_write_set_format_option.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_write_set_option.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_write_set_options.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_archive_write_set_passphrase.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_bad_fd.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_compat_bzip2.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_compat_cpio.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_compat_gtar.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_compat_gzip.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_compat_lz4.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_compat_lzip.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_compat_lzma.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_compat_lzop.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_compat_mac.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_compat_perl_archive_tar.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_compat_plexus_archiver_tar.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_compat_solaris_tar_acl.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_compat_solaris_pax_sparse.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_compat_star_acl.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_compat_tar_directory.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_compat_tar_hardlink.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_compat_uudecode.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_compat_uudecode_large.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_compat_xz.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_compat_zip.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_compat_zstd.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_empty_write.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_entry.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_entry_strmode.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_extattr_freebsd.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_filter_count.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_fuzz.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_gnutar_filename_encoding.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_link_resolver.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_open_failure.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_open_fd.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_open_file.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_open_filename.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_pax_filename_encoding.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_pax_xattr_header.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_data_large.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_disk.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_disk_directory_traversals.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_disk_entry_from_file.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_extract.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_file_nonexistent.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_filter_compress.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_filter_grzip.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_filter_lrzip.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_filter_lzop.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_filter_lzop_multiple_parts.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_filter_program.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_filter_program_signature.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_filter_uudecode.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_filter_uudecode_raw.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_7zip.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_7zip_encryption_data.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_7zip_encryption_partially.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_7zip_encryption_header.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_7zip_malformed.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_7zip_packinfo_digests.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_ar.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_cab.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_cab_filename.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_cpio_afio.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_cpio_bin.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_cpio_bin_Z.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_cpio_bin_be.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_cpio_bin_bz2.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_cpio_bin_gz.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_cpio_bin_le.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_cpio_bin_lzip.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_cpio_bin_lzma.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_cpio_bin_xz.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_cpio_filename.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_cpio_odc.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_cpio_svr4_bzip2_rpm.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_cpio_svr4_gzip.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_cpio_svr4_gzip_rpm.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_cpio_svr4c_Z.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_empty.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_gtar_filename.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_gtar_gz.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_gtar_lzma.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_gtar_sparse.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_gtar_sparse_skip_entry.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_iso_Z.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_iso_multi_extent.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_iso_xorriso.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_isojoliet_bz2.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_isojoliet_long.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_isojoliet_rr.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_isojoliet_versioned.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_isorr_bz2.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_isorr_ce.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_isorr_new_bz2.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_isorr_rr_moved.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_isozisofs_bz2.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_lha.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_lha_bugfix_0.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_lha_filename.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_lha_filename_utf16.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_mtree.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_mtree_crash747.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_pax_bz2.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_rar.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_rar_encryption_data.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_rar_encryption_partially.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_rar_encryption_header.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_rar_filter.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_rar_invalid1.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_rar5.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_raw.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_tar.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_tar_concatenated.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_tar_empty_pax.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_tar_empty_filename.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_tar_empty_with_gnulabel.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_tar_filename.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_tar_invalid_pax_size.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_tbz.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_tgz.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_tlz.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_txz.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_tz.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_ustar_filename.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_warc.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_xar.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_zip.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_zip_7075_utf8_paths.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_zip_comment_stored.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_zip_encryption_data.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_zip_encryption_partially.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_zip_encryption_header.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_zip_extra_padding.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_zip_filename.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_zip_high_compression.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_zip_jar.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_zip_mac_metadata.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_zip_malformed.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_zip_msdos.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_zip_nested.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_zip_nofiletype.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_zip_padded.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_zip_sfx.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_zip_traditional_encryption_data.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_zip_winzip_aes.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_zip_winzip_aes_large.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_zip_zip64.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_format_zip_with_invalid_traditional_eocd.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_large.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_pax_xattr_rht_security_selinux.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_pax_xattr_schily.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_pax_truncated.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_position.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_set_format.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_too_many_filters.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_truncated.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_read_truncated_filter.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_short_writes.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_sparse_basic.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_tar_filenames.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_tar_large.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_ustar_filenames.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_ustar_filename_encoding.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_warn_missing_hardlink_target.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_disk.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_disk_appledouble.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_disk_failures.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_disk_fixup.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_disk_hardlink.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_disk_hfs_compression.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_disk_lookup.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_disk_mac_metadata.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_disk_no_hfs_compression.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_disk_perms.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_disk_secure.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_disk_secure744.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_disk_secure745.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_disk_secure746.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_disk_sparse.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_disk_symlink.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_disk_times.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_filter_b64encode.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_filter_bzip2.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_filter_compress.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_filter_gzip.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_filter_gzip_timestamp.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_filter_lrzip.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_filter_lz4.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_filter_lzip.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_filter_lzma.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_filter_lzop.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_filter_program.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_filter_uuencode.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_filter_xz.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_filter_zstd.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_7zip.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_7zip_empty.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_7zip_large.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_ar.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_cpio.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_cpio_empty.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_cpio_newc.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_cpio_odc.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_gnutar.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_gnutar_filenames.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_iso9660.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_iso9660_boot.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_iso9660_empty.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_iso9660_filename.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_iso9660_zisofs.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_mtree.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_mtree_absolute_path.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_mtree_classic.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_mtree_classic_indent.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_mtree_fflags.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_mtree_no_separator.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_mtree_quoted_filename.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_pax.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_raw.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_raw_b64.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_shar_empty.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_tar.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_tar_empty.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_tar_sparse.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_tar_ustar.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_tar_v7tar.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_warc.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_warc_empty.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_xar.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_xar_empty.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_zip.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_zip_compression_store.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_zip_entry_size_unset.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_zip_empty.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_zip_empty_zip64.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_zip_file.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_zip_file_zip64.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_zip_large.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_format_zip_zip64.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_open_memory.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_write_read_format_zip.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_xattr_platform.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) -libarchive/test/test-test_zip_filename_encoding.$(OBJEXT): \ - libarchive/test/$(am__dirstamp) \ - libarchive/test/$(DEPDIR)/$(am__dirstamp) - -libarchive_test$(EXEEXT): $(libarchive_test_OBJECTS) $(libarchive_test_DEPENDENCIES) $(EXTRA_libarchive_test_DEPENDENCIES) - @rm -f libarchive_test$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(libarchive_test_OBJECTS) $(libarchive_test_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -rm -f cat/*.$(OBJEXT) - -rm -f cat/test/*.$(OBJEXT) - -rm -f cpio/*.$(OBJEXT) - -rm -f cpio/test/*.$(OBJEXT) - -rm -f libarchive/*.$(OBJEXT) - -rm -f libarchive/*.lo - -rm -f libarchive/test/*.$(OBJEXT) - -rm -f libarchive_fe/*.$(OBJEXT) - -rm -f libarchive_fe/*.lo - -rm -f tar/*.$(OBJEXT) - -rm -f tar/test/*.$(OBJEXT) - -rm -f test_utils/*.$(OBJEXT) - -rm -f unzip/*.$(OBJEXT) - -rm -f unzip/test/*.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@cat/$(DEPDIR)/bsdcat-bsdcat.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cat/$(DEPDIR)/bsdcat-cmdline.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cat/test/$(DEPDIR)/bsdcat_test-test_0.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cat/test/$(DEPDIR)/bsdcat_test-test_empty_gz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cat/test/$(DEPDIR)/bsdcat_test-test_empty_lz4.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cat/test/$(DEPDIR)/bsdcat_test-test_empty_xz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cat/test/$(DEPDIR)/bsdcat_test-test_empty_zstd.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cat/test/$(DEPDIR)/bsdcat_test-test_error.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cat/test/$(DEPDIR)/bsdcat_test-test_error_mixed.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cat/test/$(DEPDIR)/bsdcat_test-test_expand_Z.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cat/test/$(DEPDIR)/bsdcat_test-test_expand_bz2.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cat/test/$(DEPDIR)/bsdcat_test-test_expand_gz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cat/test/$(DEPDIR)/bsdcat_test-test_expand_lz4.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cat/test/$(DEPDIR)/bsdcat_test-test_expand_mixed.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cat/test/$(DEPDIR)/bsdcat_test-test_expand_plain.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cat/test/$(DEPDIR)/bsdcat_test-test_expand_xz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cat/test/$(DEPDIR)/bsdcat_test-test_expand_zstd.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cat/test/$(DEPDIR)/bsdcat_test-test_help.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cat/test/$(DEPDIR)/bsdcat_test-test_stdin.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cat/test/$(DEPDIR)/bsdcat_test-test_version.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/$(DEPDIR)/bsdcpio-cmdline.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/$(DEPDIR)/bsdcpio-cpio.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/$(DEPDIR)/bsdcpio-cpio_windows.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/$(DEPDIR)/bsdcpio_test-cmdline.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_0.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_basic.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_cmdline.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_Z.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_bz2.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_grz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_gz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lrz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lz4.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lzma.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lzo.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_xz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_zstd.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_format_newc.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_gcpio_compat.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_missing_file.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_0.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_B_upper.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_C_upper.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_J_upper.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_L_upper.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_Z_upper.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_a.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_b64encode.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_c.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_d.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_f.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_grzip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_help.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_l.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lrzip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lz4.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lzma.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lzop.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_m.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_passphrase.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_t.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_u.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_uuencode.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_version.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_xz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_y.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_z.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_option_zstd.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_owner_parse.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_passthrough_dotdot.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@cpio/test/$(DEPDIR)/bsdcpio_test-test_passthrough_reverse.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_acl.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_blake2s_ref.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_blake2sp_ref.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_check_magic.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_cmdline.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_cryptor.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_digest.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_disk_acl_darwin.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_disk_acl_freebsd.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_disk_acl_linux.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_disk_acl_sunos.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_entry.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_entry_copy_bhfi.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_entry_copy_stat.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_entry_link_resolver.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_entry_sparse.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_entry_stat.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_entry_strmode.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_entry_xattr.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_getdate.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_hmac.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_match.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_options.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_pack_dev.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_pathmatch.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_ppmd7.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_ppmd8.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_random.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_rb.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_add_passphrase.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_append_filter.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_data_into_fd.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_disk_entry_from_file.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_disk_posix.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_disk_set_standard_lookup.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_disk_windows.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_extract.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_extract2.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_open_fd.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_open_file.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_open_filename.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_open_memory.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_set_format.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_set_options.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_filter_all.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_filter_by_code.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_filter_bzip2.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_filter_compress.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_filter_grzip.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_filter_gzip.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_filter_lrzip.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_filter_lz4.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_filter_lzop.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_filter_none.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_filter_program.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_filter_rpm.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_filter_uu.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_filter_xz.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_filter_zstd.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_format_7zip.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_format_all.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_format_ar.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_format_by_code.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_format_cab.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_format_cpio.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_format_empty.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_format_iso9660.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_format_lha.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_format_mtree.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_format_rar.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_format_rar5.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_format_raw.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_format_tar.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_format_warc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_format_xar.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_read_support_format_zip.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_string.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_string_sprintf.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_util.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_version_details.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_virtual.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_windows.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_add_filter.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_add_filter_b64encode.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_add_filter_by_name.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_add_filter_bzip2.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_add_filter_compress.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_add_filter_grzip.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_add_filter_gzip.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_add_filter_lrzip.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_add_filter_lz4.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_add_filter_lzop.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_add_filter_none.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_add_filter_program.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_add_filter_uuencode.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_add_filter_xz.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_add_filter_zstd.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_disk_posix.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_disk_set_standard_lookup.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_disk_windows.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_open_fd.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_open_file.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_open_filename.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_open_memory.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_set_format.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_set_format_7zip.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_set_format_ar.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_set_format_by_name.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_set_format_cpio.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_set_format_cpio_binary.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_set_format_cpio_newc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_set_format_cpio_odc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_set_format_filter_by_ext.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_set_format_gnutar.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_set_format_iso9660.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_set_format_mtree.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_set_format_pax.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_set_format_raw.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_set_format_shar.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_set_format_ustar.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_set_format_v7tar.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_set_format_warc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_set_format_xar.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_set_format_zip.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_set_options.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/archive_write_set_passphrase.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/filter_fork_posix.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/filter_fork_windows.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_acl.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_blake2s_ref.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_blake2sp_ref.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_check_magic.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_cmdline.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_cryptor.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_digest.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_disk_acl_darwin.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_disk_acl_freebsd.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_disk_acl_linux.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_disk_acl_sunos.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_entry.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_entry_copy_bhfi.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_entry_copy_stat.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_entry_link_resolver.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_entry_sparse.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_entry_stat.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_entry_strmode.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_entry_xattr.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_getdate.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_hmac.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_match.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_options.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_pack_dev.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_pathmatch.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_ppmd7.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_ppmd8.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_random.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_rb.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_add_passphrase.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_append_filter.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_data_into_fd.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_disk_entry_from_file.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_disk_posix.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_disk_set_standard_lookup.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_disk_windows.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_extract.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_extract2.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_open_fd.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_open_file.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_open_filename.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_open_memory.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_set_format.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_set_options.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_filter_all.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_filter_by_code.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_filter_bzip2.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_filter_compress.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_filter_grzip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_filter_gzip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_filter_lrzip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_filter_lz4.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_filter_lzop.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_filter_none.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_filter_program.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_filter_rpm.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_filter_uu.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_filter_xz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_filter_zstd.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_format_7zip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_format_all.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_format_ar.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_format_by_code.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_format_cab.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_format_cpio.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_format_empty.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_format_iso9660.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_format_lha.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_format_mtree.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_format_rar.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_format_rar5.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_format_raw.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_format_tar.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_format_warc.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_format_xar.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_read_support_format_zip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_string.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_string_sprintf.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_util.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_version_details.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_virtual.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_windows.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_add_filter.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_add_filter_b64encode.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_add_filter_by_name.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_add_filter_bzip2.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_add_filter_compress.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_add_filter_grzip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_add_filter_gzip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_add_filter_lrzip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_add_filter_lz4.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_add_filter_lzop.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_add_filter_none.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_add_filter_program.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_add_filter_uuencode.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_add_filter_xz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_add_filter_zstd.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_disk_posix.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_disk_set_standard_lookup.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_disk_windows.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_open_fd.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_open_file.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_open_filename.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_open_memory.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_set_format.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_set_format_7zip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_set_format_ar.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_set_format_by_name.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_set_format_cpio.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_binary.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_newc.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_odc.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_set_format_filter_by_ext.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_set_format_gnutar.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_set_format_iso9660.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_set_format_mtree.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_set_format_pax.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_set_format_raw.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_set_format_shar.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_set_format_ustar.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_set_format_v7tar.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_set_format_warc.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_set_format_xar.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_set_format_zip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_set_options.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-archive_write_set_passphrase.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-filter_fork_posix.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-filter_fork_windows.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/test-xxhash.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/$(DEPDIR)/xxhash.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-read_open_memory.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_acl_nfs4.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_acl_pax.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_acl_platform_nfs4.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_acl_platform_posix1e.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_acl_posix1e.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_acl_text.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_api_feature.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_clear_error.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_cmdline.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_digest.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_getdate.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_match_owner.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_match_path.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_match_time.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_pathmatch.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_read_add_passphrase.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice_open_fd.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice_open_filename.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_read_multiple_data_objects.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_read_next_header_empty.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_read_next_header_raw.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_read_open2.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_read_set_filter_option.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_read_set_format_option.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_read_set_option.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_read_set_options.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_read_support.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_set_error.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_string.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_string_conversion.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_write_add_filter_by_name.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_write_set_filter_option.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_by_name.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_filter_by_ext.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_option.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_write_set_option.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_write_set_options.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_archive_write_set_passphrase.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_bad_fd.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_compat_bzip2.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_compat_cpio.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_compat_gtar.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_compat_gzip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_compat_lz4.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_compat_lzip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_compat_lzma.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_compat_lzop.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_compat_mac.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_compat_perl_archive_tar.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_compat_plexus_archiver_tar.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_compat_solaris_pax_sparse.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_compat_solaris_tar_acl.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_compat_star_acl.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_compat_tar_directory.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_compat_tar_hardlink.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_compat_uudecode.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_compat_uudecode_large.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_compat_xz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_compat_zip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_compat_zstd.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_empty_write.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_entry.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_entry_strmode.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_extattr_freebsd.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_filter_count.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_fuzz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_gnutar_filename_encoding.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_link_resolver.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_open_failure.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_open_fd.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_open_file.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_open_filename.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_pax_filename_encoding.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_pax_xattr_header.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_data_large.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_disk.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_disk_directory_traversals.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_disk_entry_from_file.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_extract.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_file_nonexistent.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_filter_compress.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_filter_grzip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_filter_lrzip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_filter_lzop.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_filter_lzop_multiple_parts.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_filter_program.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_filter_program_signature.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_filter_uudecode.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_filter_uudecode_raw.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_7zip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_data.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_header.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_partially.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_7zip_malformed.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_7zip_packinfo_digests.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_ar.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_cab.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_cab_filename.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_cpio_afio.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_Z.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_be.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_bz2.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_gz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_le.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_lzip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_lzma.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_xz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_cpio_filename.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_cpio_odc.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_bzip2_rpm.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_gzip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_gzip_rpm.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4c_Z.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_empty.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_gtar_filename.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_gtar_gz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_gtar_lzma.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_gtar_sparse.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_gtar_sparse_skip_entry.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_iso_Z.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_iso_multi_extent.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_iso_xorriso.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_bz2.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_long.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_rr.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_versioned.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_isorr_bz2.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_isorr_ce.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_isorr_new_bz2.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_isorr_rr_moved.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_isozisofs_bz2.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_lha.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_lha_bugfix_0.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_lha_filename.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_lha_filename_utf16.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_mtree.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_mtree_crash747.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_pax_bz2.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_rar.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_rar5.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_data.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_header.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_partially.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_rar_filter.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_rar_invalid1.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_raw.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_tar.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_tar_concatenated.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_filename.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_pax.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_with_gnulabel.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_tar_filename.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_tar_invalid_pax_size.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_tbz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_tgz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_tlz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_txz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_tz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_ustar_filename.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_warc.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_xar.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_zip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_zip_7075_utf8_paths.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_zip_comment_stored.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_data.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_header.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_partially.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_zip_extra_padding.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_zip_filename.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_zip_high_compression.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_zip_jar.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_zip_mac_metadata.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_zip_malformed.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_zip_msdos.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_zip_nested.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_zip_nofiletype.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_zip_padded.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_zip_sfx.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_zip_traditional_encryption_data.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_zip_winzip_aes.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_zip_winzip_aes_large.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_zip_with_invalid_traditional_eocd.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_format_zip_zip64.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_large.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_pax_truncated.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_pax_xattr_rht_security_selinux.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_pax_xattr_schily.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_position.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_set_format.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_too_many_filters.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_truncated.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_read_truncated_filter.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_short_writes.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_sparse_basic.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_tar_filenames.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_tar_large.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_ustar_filename_encoding.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_ustar_filenames.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_warn_missing_hardlink_target.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_disk.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_disk_appledouble.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_disk_failures.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_disk_fixup.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_disk_hardlink.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_disk_hfs_compression.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_disk_lookup.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_disk_mac_metadata.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_disk_no_hfs_compression.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_disk_perms.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_disk_secure.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_disk_secure744.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_disk_secure745.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_disk_secure746.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_disk_sparse.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_disk_symlink.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_disk_times.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_filter_b64encode.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_filter_bzip2.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_filter_compress.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_filter_gzip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_filter_gzip_timestamp.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_filter_lrzip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_filter_lz4.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_filter_lzip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_filter_lzma.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_filter_lzop.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_filter_program.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_filter_uuencode.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_filter_xz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_filter_zstd.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_7zip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_7zip_empty.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_7zip_large.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_ar.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_cpio.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_cpio_empty.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_cpio_newc.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_cpio_odc.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_gnutar.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_gnutar_filenames.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_iso9660.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_boot.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_empty.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_filename.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_zisofs.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_mtree.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_mtree_absolute_path.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_mtree_classic.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_mtree_classic_indent.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_mtree_fflags.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_mtree_no_separator.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_mtree_quoted_filename.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_pax.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_raw.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_raw_b64.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_shar_empty.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_tar.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_tar_empty.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_tar_sparse.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_tar_ustar.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_tar_v7tar.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_warc.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_warc_empty.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_xar.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_xar_empty.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_zip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_zip_compression_store.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_zip_empty.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_zip_empty_zip64.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_zip_entry_size_unset.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_zip_file.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_zip_file_zip64.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_zip_large.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_format_zip_zip64.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_open_memory.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_write_read_format_zip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_xattr_platform.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive/test/$(DEPDIR)/test-test_zip_filename_encoding.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive_fe/$(DEPDIR)/la-err.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive_fe/$(DEPDIR)/la-line_reader.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@libarchive_fe/$(DEPDIR)/la-passphrase.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/$(DEPDIR)/bsdtar-bsdtar.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/$(DEPDIR)/bsdtar-bsdtar_windows.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/$(DEPDIR)/bsdtar-cmdline.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/$(DEPDIR)/bsdtar-creation_set.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/$(DEPDIR)/bsdtar-read.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/$(DEPDIR)/bsdtar-subst.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/$(DEPDIR)/bsdtar-util.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/$(DEPDIR)/bsdtar-write.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_0.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_basic.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_copy.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_empty_mtree.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_Z.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_bz2.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_grz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_gz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lrz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lz4.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lzma.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lzo.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_xz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_zstd.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_format_newc.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_help.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_leading_slash.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_missing_file.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_C_mtree.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_C_upper.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_H_upper.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_L_upper.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_O_upper.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_T_upper.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_U_upper.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_X_upper.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_a.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_acls.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_b.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_b64encode.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_exclude.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_exclude_vcs.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_fflags.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_gid_gname.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_grzip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_ignore_zeros.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_j.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_k.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_keep_newer_files.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_lrzip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_lz4.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_lzma.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_lzop.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_n.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_newer_than.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_nodump.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_older_than.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_passphrase.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_q.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_r.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_s.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_safe_writes.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_uid_uname.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_uuencode.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_xattrs.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_xz.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_z.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_option_zstd.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_patterns.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_print_longpath.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_stdio.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_strip_components.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_symlink_dir.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_version.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@tar/test/$(DEPDIR)/bsdtar_test-test_windows.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@test_utils/$(DEPDIR)/bsdcat_test-test_main.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@test_utils/$(DEPDIR)/bsdcat_test-test_utils.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@test_utils/$(DEPDIR)/bsdcpio_test-test_main.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@test_utils/$(DEPDIR)/bsdcpio_test-test_utils.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@test_utils/$(DEPDIR)/bsdtar_test-test_main.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@test_utils/$(DEPDIR)/bsdtar_test-test_utils.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@test_utils/$(DEPDIR)/bsdunzip_test-test_main.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@test_utils/$(DEPDIR)/bsdunzip_test-test_utils.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@test_utils/$(DEPDIR)/libarchive_test-test_main.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@test_utils/$(DEPDIR)/libarchive_test-test_utils.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unzip/$(DEPDIR)/bsdunzip-bsdunzip.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unzip/$(DEPDIR)/bsdunzip-cmdline.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unzip/$(DEPDIR)/bsdunzip-la_getline.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unzip/test/$(DEPDIR)/bsdunzip_test-test_0.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unzip/test/$(DEPDIR)/bsdunzip_test-test_C.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unzip/test/$(DEPDIR)/bsdunzip_test-test_L.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unzip/test/$(DEPDIR)/bsdunzip_test-test_P_encryption.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unzip/test/$(DEPDIR)/bsdunzip_test-test_Z1.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unzip/test/$(DEPDIR)/bsdunzip_test-test_basic.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unzip/test/$(DEPDIR)/bsdunzip_test-test_d.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unzip/test/$(DEPDIR)/bsdunzip_test-test_glob.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unzip/test/$(DEPDIR)/bsdunzip_test-test_j.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unzip/test/$(DEPDIR)/bsdunzip_test-test_n.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unzip/test/$(DEPDIR)/bsdunzip_test-test_not_exist.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unzip/test/$(DEPDIR)/bsdunzip_test-test_o.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unzip/test/$(DEPDIR)/bsdunzip_test-test_p.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unzip/test/$(DEPDIR)/bsdunzip_test-test_q.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unzip/test/$(DEPDIR)/bsdunzip_test-test_singlefile.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unzip/test/$(DEPDIR)/bsdunzip_test-test_t.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unzip/test/$(DEPDIR)/bsdunzip_test-test_t_bad.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unzip/test/$(DEPDIR)/bsdunzip_test-test_version.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@unzip/test/$(DEPDIR)/bsdunzip_test-test_x.Po@am__quote@ # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - -libarchive_fe/la-err.lo: libarchive_fe/err.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_fe_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive_fe/la-err.lo -MD -MP -MF libarchive_fe/$(DEPDIR)/la-err.Tpo -c -o libarchive_fe/la-err.lo `test -f 'libarchive_fe/err.c' || echo '$(srcdir)/'`libarchive_fe/err.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive_fe/$(DEPDIR)/la-err.Tpo libarchive_fe/$(DEPDIR)/la-err.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive_fe/err.c' object='libarchive_fe/la-err.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_fe_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive_fe/la-err.lo `test -f 'libarchive_fe/err.c' || echo '$(srcdir)/'`libarchive_fe/err.c - -libarchive_fe/la-line_reader.lo: libarchive_fe/line_reader.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_fe_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive_fe/la-line_reader.lo -MD -MP -MF libarchive_fe/$(DEPDIR)/la-line_reader.Tpo -c -o libarchive_fe/la-line_reader.lo `test -f 'libarchive_fe/line_reader.c' || echo '$(srcdir)/'`libarchive_fe/line_reader.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive_fe/$(DEPDIR)/la-line_reader.Tpo libarchive_fe/$(DEPDIR)/la-line_reader.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive_fe/line_reader.c' object='libarchive_fe/la-line_reader.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_fe_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive_fe/la-line_reader.lo `test -f 'libarchive_fe/line_reader.c' || echo '$(srcdir)/'`libarchive_fe/line_reader.c - -libarchive_fe/la-passphrase.lo: libarchive_fe/passphrase.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_fe_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive_fe/la-passphrase.lo -MD -MP -MF libarchive_fe/$(DEPDIR)/la-passphrase.Tpo -c -o libarchive_fe/la-passphrase.lo `test -f 'libarchive_fe/passphrase.c' || echo '$(srcdir)/'`libarchive_fe/passphrase.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive_fe/$(DEPDIR)/la-passphrase.Tpo libarchive_fe/$(DEPDIR)/la-passphrase.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive_fe/passphrase.c' object='libarchive_fe/la-passphrase.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_fe_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive_fe/la-passphrase.lo `test -f 'libarchive_fe/passphrase.c' || echo '$(srcdir)/'`libarchive_fe/passphrase.c - -cat/bsdcat-bsdcat.o: cat/bsdcat.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/bsdcat-bsdcat.o -MD -MP -MF cat/$(DEPDIR)/bsdcat-bsdcat.Tpo -c -o cat/bsdcat-bsdcat.o `test -f 'cat/bsdcat.c' || echo '$(srcdir)/'`cat/bsdcat.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/$(DEPDIR)/bsdcat-bsdcat.Tpo cat/$(DEPDIR)/bsdcat-bsdcat.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/bsdcat.c' object='cat/bsdcat-bsdcat.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/bsdcat-bsdcat.o `test -f 'cat/bsdcat.c' || echo '$(srcdir)/'`cat/bsdcat.c - -cat/bsdcat-bsdcat.obj: cat/bsdcat.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/bsdcat-bsdcat.obj -MD -MP -MF cat/$(DEPDIR)/bsdcat-bsdcat.Tpo -c -o cat/bsdcat-bsdcat.obj `if test -f 'cat/bsdcat.c'; then $(CYGPATH_W) 'cat/bsdcat.c'; else $(CYGPATH_W) '$(srcdir)/cat/bsdcat.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/$(DEPDIR)/bsdcat-bsdcat.Tpo cat/$(DEPDIR)/bsdcat-bsdcat.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/bsdcat.c' object='cat/bsdcat-bsdcat.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/bsdcat-bsdcat.obj `if test -f 'cat/bsdcat.c'; then $(CYGPATH_W) 'cat/bsdcat.c'; else $(CYGPATH_W) '$(srcdir)/cat/bsdcat.c'; fi` - -cat/bsdcat-cmdline.o: cat/cmdline.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/bsdcat-cmdline.o -MD -MP -MF cat/$(DEPDIR)/bsdcat-cmdline.Tpo -c -o cat/bsdcat-cmdline.o `test -f 'cat/cmdline.c' || echo '$(srcdir)/'`cat/cmdline.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/$(DEPDIR)/bsdcat-cmdline.Tpo cat/$(DEPDIR)/bsdcat-cmdline.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/cmdline.c' object='cat/bsdcat-cmdline.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/bsdcat-cmdline.o `test -f 'cat/cmdline.c' || echo '$(srcdir)/'`cat/cmdline.c - -cat/bsdcat-cmdline.obj: cat/cmdline.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/bsdcat-cmdline.obj -MD -MP -MF cat/$(DEPDIR)/bsdcat-cmdline.Tpo -c -o cat/bsdcat-cmdline.obj `if test -f 'cat/cmdline.c'; then $(CYGPATH_W) 'cat/cmdline.c'; else $(CYGPATH_W) '$(srcdir)/cat/cmdline.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/$(DEPDIR)/bsdcat-cmdline.Tpo cat/$(DEPDIR)/bsdcat-cmdline.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/cmdline.c' object='cat/bsdcat-cmdline.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/bsdcat-cmdline.obj `if test -f 'cat/cmdline.c'; then $(CYGPATH_W) 'cat/cmdline.c'; else $(CYGPATH_W) '$(srcdir)/cat/cmdline.c'; fi` - -test_utils/bsdcat_test-test_utils.o: test_utils/test_utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_utils/bsdcat_test-test_utils.o -MD -MP -MF test_utils/$(DEPDIR)/bsdcat_test-test_utils.Tpo -c -o test_utils/bsdcat_test-test_utils.o `test -f 'test_utils/test_utils.c' || echo '$(srcdir)/'`test_utils/test_utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test_utils/$(DEPDIR)/bsdcat_test-test_utils.Tpo test_utils/$(DEPDIR)/bsdcat_test-test_utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_utils/test_utils.c' object='test_utils/bsdcat_test-test_utils.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_utils/bsdcat_test-test_utils.o `test -f 'test_utils/test_utils.c' || echo '$(srcdir)/'`test_utils/test_utils.c - -test_utils/bsdcat_test-test_utils.obj: test_utils/test_utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_utils/bsdcat_test-test_utils.obj -MD -MP -MF test_utils/$(DEPDIR)/bsdcat_test-test_utils.Tpo -c -o test_utils/bsdcat_test-test_utils.obj `if test -f 'test_utils/test_utils.c'; then $(CYGPATH_W) 'test_utils/test_utils.c'; else $(CYGPATH_W) '$(srcdir)/test_utils/test_utils.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test_utils/$(DEPDIR)/bsdcat_test-test_utils.Tpo test_utils/$(DEPDIR)/bsdcat_test-test_utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_utils/test_utils.c' object='test_utils/bsdcat_test-test_utils.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_utils/bsdcat_test-test_utils.obj `if test -f 'test_utils/test_utils.c'; then $(CYGPATH_W) 'test_utils/test_utils.c'; else $(CYGPATH_W) '$(srcdir)/test_utils/test_utils.c'; fi` - -test_utils/bsdcat_test-test_main.o: test_utils/test_main.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_utils/bsdcat_test-test_main.o -MD -MP -MF test_utils/$(DEPDIR)/bsdcat_test-test_main.Tpo -c -o test_utils/bsdcat_test-test_main.o `test -f 'test_utils/test_main.c' || echo '$(srcdir)/'`test_utils/test_main.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test_utils/$(DEPDIR)/bsdcat_test-test_main.Tpo test_utils/$(DEPDIR)/bsdcat_test-test_main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_utils/test_main.c' object='test_utils/bsdcat_test-test_main.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_utils/bsdcat_test-test_main.o `test -f 'test_utils/test_main.c' || echo '$(srcdir)/'`test_utils/test_main.c - -test_utils/bsdcat_test-test_main.obj: test_utils/test_main.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_utils/bsdcat_test-test_main.obj -MD -MP -MF test_utils/$(DEPDIR)/bsdcat_test-test_main.Tpo -c -o test_utils/bsdcat_test-test_main.obj `if test -f 'test_utils/test_main.c'; then $(CYGPATH_W) 'test_utils/test_main.c'; else $(CYGPATH_W) '$(srcdir)/test_utils/test_main.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test_utils/$(DEPDIR)/bsdcat_test-test_main.Tpo test_utils/$(DEPDIR)/bsdcat_test-test_main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_utils/test_main.c' object='test_utils/bsdcat_test-test_main.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_utils/bsdcat_test-test_main.obj `if test -f 'test_utils/test_main.c'; then $(CYGPATH_W) 'test_utils/test_main.c'; else $(CYGPATH_W) '$(srcdir)/test_utils/test_main.c'; fi` - -cat/test/bsdcat_test-test_0.o: cat/test/test_0.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_0.o -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_0.Tpo -c -o cat/test/bsdcat_test-test_0.o `test -f 'cat/test/test_0.c' || echo '$(srcdir)/'`cat/test/test_0.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_0.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_0.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_0.c' object='cat/test/bsdcat_test-test_0.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_0.o `test -f 'cat/test/test_0.c' || echo '$(srcdir)/'`cat/test/test_0.c - -cat/test/bsdcat_test-test_0.obj: cat/test/test_0.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_0.obj -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_0.Tpo -c -o cat/test/bsdcat_test-test_0.obj `if test -f 'cat/test/test_0.c'; then $(CYGPATH_W) 'cat/test/test_0.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_0.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_0.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_0.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_0.c' object='cat/test/bsdcat_test-test_0.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_0.obj `if test -f 'cat/test/test_0.c'; then $(CYGPATH_W) 'cat/test/test_0.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_0.c'; fi` - -cat/test/bsdcat_test-test_empty_gz.o: cat/test/test_empty_gz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_empty_gz.o -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_empty_gz.Tpo -c -o cat/test/bsdcat_test-test_empty_gz.o `test -f 'cat/test/test_empty_gz.c' || echo '$(srcdir)/'`cat/test/test_empty_gz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_empty_gz.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_empty_gz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_empty_gz.c' object='cat/test/bsdcat_test-test_empty_gz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_empty_gz.o `test -f 'cat/test/test_empty_gz.c' || echo '$(srcdir)/'`cat/test/test_empty_gz.c - -cat/test/bsdcat_test-test_empty_gz.obj: cat/test/test_empty_gz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_empty_gz.obj -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_empty_gz.Tpo -c -o cat/test/bsdcat_test-test_empty_gz.obj `if test -f 'cat/test/test_empty_gz.c'; then $(CYGPATH_W) 'cat/test/test_empty_gz.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_empty_gz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_empty_gz.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_empty_gz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_empty_gz.c' object='cat/test/bsdcat_test-test_empty_gz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_empty_gz.obj `if test -f 'cat/test/test_empty_gz.c'; then $(CYGPATH_W) 'cat/test/test_empty_gz.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_empty_gz.c'; fi` - -cat/test/bsdcat_test-test_empty_lz4.o: cat/test/test_empty_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_empty_lz4.o -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_empty_lz4.Tpo -c -o cat/test/bsdcat_test-test_empty_lz4.o `test -f 'cat/test/test_empty_lz4.c' || echo '$(srcdir)/'`cat/test/test_empty_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_empty_lz4.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_empty_lz4.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_empty_lz4.c' object='cat/test/bsdcat_test-test_empty_lz4.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_empty_lz4.o `test -f 'cat/test/test_empty_lz4.c' || echo '$(srcdir)/'`cat/test/test_empty_lz4.c - -cat/test/bsdcat_test-test_empty_lz4.obj: cat/test/test_empty_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_empty_lz4.obj -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_empty_lz4.Tpo -c -o cat/test/bsdcat_test-test_empty_lz4.obj `if test -f 'cat/test/test_empty_lz4.c'; then $(CYGPATH_W) 'cat/test/test_empty_lz4.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_empty_lz4.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_empty_lz4.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_empty_lz4.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_empty_lz4.c' object='cat/test/bsdcat_test-test_empty_lz4.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_empty_lz4.obj `if test -f 'cat/test/test_empty_lz4.c'; then $(CYGPATH_W) 'cat/test/test_empty_lz4.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_empty_lz4.c'; fi` - -cat/test/bsdcat_test-test_empty_xz.o: cat/test/test_empty_xz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_empty_xz.o -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_empty_xz.Tpo -c -o cat/test/bsdcat_test-test_empty_xz.o `test -f 'cat/test/test_empty_xz.c' || echo '$(srcdir)/'`cat/test/test_empty_xz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_empty_xz.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_empty_xz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_empty_xz.c' object='cat/test/bsdcat_test-test_empty_xz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_empty_xz.o `test -f 'cat/test/test_empty_xz.c' || echo '$(srcdir)/'`cat/test/test_empty_xz.c - -cat/test/bsdcat_test-test_empty_xz.obj: cat/test/test_empty_xz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_empty_xz.obj -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_empty_xz.Tpo -c -o cat/test/bsdcat_test-test_empty_xz.obj `if test -f 'cat/test/test_empty_xz.c'; then $(CYGPATH_W) 'cat/test/test_empty_xz.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_empty_xz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_empty_xz.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_empty_xz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_empty_xz.c' object='cat/test/bsdcat_test-test_empty_xz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_empty_xz.obj `if test -f 'cat/test/test_empty_xz.c'; then $(CYGPATH_W) 'cat/test/test_empty_xz.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_empty_xz.c'; fi` - -cat/test/bsdcat_test-test_empty_zstd.o: cat/test/test_empty_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_empty_zstd.o -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_empty_zstd.Tpo -c -o cat/test/bsdcat_test-test_empty_zstd.o `test -f 'cat/test/test_empty_zstd.c' || echo '$(srcdir)/'`cat/test/test_empty_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_empty_zstd.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_empty_zstd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_empty_zstd.c' object='cat/test/bsdcat_test-test_empty_zstd.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_empty_zstd.o `test -f 'cat/test/test_empty_zstd.c' || echo '$(srcdir)/'`cat/test/test_empty_zstd.c - -cat/test/bsdcat_test-test_empty_zstd.obj: cat/test/test_empty_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_empty_zstd.obj -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_empty_zstd.Tpo -c -o cat/test/bsdcat_test-test_empty_zstd.obj `if test -f 'cat/test/test_empty_zstd.c'; then $(CYGPATH_W) 'cat/test/test_empty_zstd.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_empty_zstd.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_empty_zstd.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_empty_zstd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_empty_zstd.c' object='cat/test/bsdcat_test-test_empty_zstd.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_empty_zstd.obj `if test -f 'cat/test/test_empty_zstd.c'; then $(CYGPATH_W) 'cat/test/test_empty_zstd.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_empty_zstd.c'; fi` - -cat/test/bsdcat_test-test_error.o: cat/test/test_error.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_error.o -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_error.Tpo -c -o cat/test/bsdcat_test-test_error.o `test -f 'cat/test/test_error.c' || echo '$(srcdir)/'`cat/test/test_error.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_error.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_error.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_error.c' object='cat/test/bsdcat_test-test_error.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_error.o `test -f 'cat/test/test_error.c' || echo '$(srcdir)/'`cat/test/test_error.c - -cat/test/bsdcat_test-test_error.obj: cat/test/test_error.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_error.obj -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_error.Tpo -c -o cat/test/bsdcat_test-test_error.obj `if test -f 'cat/test/test_error.c'; then $(CYGPATH_W) 'cat/test/test_error.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_error.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_error.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_error.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_error.c' object='cat/test/bsdcat_test-test_error.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_error.obj `if test -f 'cat/test/test_error.c'; then $(CYGPATH_W) 'cat/test/test_error.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_error.c'; fi` - -cat/test/bsdcat_test-test_error_mixed.o: cat/test/test_error_mixed.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_error_mixed.o -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_error_mixed.Tpo -c -o cat/test/bsdcat_test-test_error_mixed.o `test -f 'cat/test/test_error_mixed.c' || echo '$(srcdir)/'`cat/test/test_error_mixed.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_error_mixed.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_error_mixed.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_error_mixed.c' object='cat/test/bsdcat_test-test_error_mixed.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_error_mixed.o `test -f 'cat/test/test_error_mixed.c' || echo '$(srcdir)/'`cat/test/test_error_mixed.c - -cat/test/bsdcat_test-test_error_mixed.obj: cat/test/test_error_mixed.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_error_mixed.obj -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_error_mixed.Tpo -c -o cat/test/bsdcat_test-test_error_mixed.obj `if test -f 'cat/test/test_error_mixed.c'; then $(CYGPATH_W) 'cat/test/test_error_mixed.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_error_mixed.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_error_mixed.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_error_mixed.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_error_mixed.c' object='cat/test/bsdcat_test-test_error_mixed.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_error_mixed.obj `if test -f 'cat/test/test_error_mixed.c'; then $(CYGPATH_W) 'cat/test/test_error_mixed.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_error_mixed.c'; fi` - -cat/test/bsdcat_test-test_expand_Z.o: cat/test/test_expand_Z.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_expand_Z.o -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_expand_Z.Tpo -c -o cat/test/bsdcat_test-test_expand_Z.o `test -f 'cat/test/test_expand_Z.c' || echo '$(srcdir)/'`cat/test/test_expand_Z.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_expand_Z.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_expand_Z.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_expand_Z.c' object='cat/test/bsdcat_test-test_expand_Z.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_expand_Z.o `test -f 'cat/test/test_expand_Z.c' || echo '$(srcdir)/'`cat/test/test_expand_Z.c - -cat/test/bsdcat_test-test_expand_Z.obj: cat/test/test_expand_Z.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_expand_Z.obj -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_expand_Z.Tpo -c -o cat/test/bsdcat_test-test_expand_Z.obj `if test -f 'cat/test/test_expand_Z.c'; then $(CYGPATH_W) 'cat/test/test_expand_Z.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_expand_Z.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_expand_Z.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_expand_Z.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_expand_Z.c' object='cat/test/bsdcat_test-test_expand_Z.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_expand_Z.obj `if test -f 'cat/test/test_expand_Z.c'; then $(CYGPATH_W) 'cat/test/test_expand_Z.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_expand_Z.c'; fi` - -cat/test/bsdcat_test-test_expand_bz2.o: cat/test/test_expand_bz2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_expand_bz2.o -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_expand_bz2.Tpo -c -o cat/test/bsdcat_test-test_expand_bz2.o `test -f 'cat/test/test_expand_bz2.c' || echo '$(srcdir)/'`cat/test/test_expand_bz2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_expand_bz2.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_expand_bz2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_expand_bz2.c' object='cat/test/bsdcat_test-test_expand_bz2.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_expand_bz2.o `test -f 'cat/test/test_expand_bz2.c' || echo '$(srcdir)/'`cat/test/test_expand_bz2.c - -cat/test/bsdcat_test-test_expand_bz2.obj: cat/test/test_expand_bz2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_expand_bz2.obj -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_expand_bz2.Tpo -c -o cat/test/bsdcat_test-test_expand_bz2.obj `if test -f 'cat/test/test_expand_bz2.c'; then $(CYGPATH_W) 'cat/test/test_expand_bz2.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_expand_bz2.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_expand_bz2.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_expand_bz2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_expand_bz2.c' object='cat/test/bsdcat_test-test_expand_bz2.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_expand_bz2.obj `if test -f 'cat/test/test_expand_bz2.c'; then $(CYGPATH_W) 'cat/test/test_expand_bz2.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_expand_bz2.c'; fi` - -cat/test/bsdcat_test-test_expand_gz.o: cat/test/test_expand_gz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_expand_gz.o -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_expand_gz.Tpo -c -o cat/test/bsdcat_test-test_expand_gz.o `test -f 'cat/test/test_expand_gz.c' || echo '$(srcdir)/'`cat/test/test_expand_gz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_expand_gz.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_expand_gz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_expand_gz.c' object='cat/test/bsdcat_test-test_expand_gz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_expand_gz.o `test -f 'cat/test/test_expand_gz.c' || echo '$(srcdir)/'`cat/test/test_expand_gz.c - -cat/test/bsdcat_test-test_expand_gz.obj: cat/test/test_expand_gz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_expand_gz.obj -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_expand_gz.Tpo -c -o cat/test/bsdcat_test-test_expand_gz.obj `if test -f 'cat/test/test_expand_gz.c'; then $(CYGPATH_W) 'cat/test/test_expand_gz.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_expand_gz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_expand_gz.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_expand_gz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_expand_gz.c' object='cat/test/bsdcat_test-test_expand_gz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_expand_gz.obj `if test -f 'cat/test/test_expand_gz.c'; then $(CYGPATH_W) 'cat/test/test_expand_gz.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_expand_gz.c'; fi` - -cat/test/bsdcat_test-test_expand_lz4.o: cat/test/test_expand_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_expand_lz4.o -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_expand_lz4.Tpo -c -o cat/test/bsdcat_test-test_expand_lz4.o `test -f 'cat/test/test_expand_lz4.c' || echo '$(srcdir)/'`cat/test/test_expand_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_expand_lz4.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_expand_lz4.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_expand_lz4.c' object='cat/test/bsdcat_test-test_expand_lz4.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_expand_lz4.o `test -f 'cat/test/test_expand_lz4.c' || echo '$(srcdir)/'`cat/test/test_expand_lz4.c - -cat/test/bsdcat_test-test_expand_lz4.obj: cat/test/test_expand_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_expand_lz4.obj -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_expand_lz4.Tpo -c -o cat/test/bsdcat_test-test_expand_lz4.obj `if test -f 'cat/test/test_expand_lz4.c'; then $(CYGPATH_W) 'cat/test/test_expand_lz4.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_expand_lz4.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_expand_lz4.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_expand_lz4.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_expand_lz4.c' object='cat/test/bsdcat_test-test_expand_lz4.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_expand_lz4.obj `if test -f 'cat/test/test_expand_lz4.c'; then $(CYGPATH_W) 'cat/test/test_expand_lz4.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_expand_lz4.c'; fi` - -cat/test/bsdcat_test-test_expand_mixed.o: cat/test/test_expand_mixed.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_expand_mixed.o -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_expand_mixed.Tpo -c -o cat/test/bsdcat_test-test_expand_mixed.o `test -f 'cat/test/test_expand_mixed.c' || echo '$(srcdir)/'`cat/test/test_expand_mixed.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_expand_mixed.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_expand_mixed.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_expand_mixed.c' object='cat/test/bsdcat_test-test_expand_mixed.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_expand_mixed.o `test -f 'cat/test/test_expand_mixed.c' || echo '$(srcdir)/'`cat/test/test_expand_mixed.c - -cat/test/bsdcat_test-test_expand_mixed.obj: cat/test/test_expand_mixed.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_expand_mixed.obj -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_expand_mixed.Tpo -c -o cat/test/bsdcat_test-test_expand_mixed.obj `if test -f 'cat/test/test_expand_mixed.c'; then $(CYGPATH_W) 'cat/test/test_expand_mixed.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_expand_mixed.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_expand_mixed.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_expand_mixed.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_expand_mixed.c' object='cat/test/bsdcat_test-test_expand_mixed.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_expand_mixed.obj `if test -f 'cat/test/test_expand_mixed.c'; then $(CYGPATH_W) 'cat/test/test_expand_mixed.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_expand_mixed.c'; fi` - -cat/test/bsdcat_test-test_expand_plain.o: cat/test/test_expand_plain.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_expand_plain.o -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_expand_plain.Tpo -c -o cat/test/bsdcat_test-test_expand_plain.o `test -f 'cat/test/test_expand_plain.c' || echo '$(srcdir)/'`cat/test/test_expand_plain.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_expand_plain.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_expand_plain.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_expand_plain.c' object='cat/test/bsdcat_test-test_expand_plain.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_expand_plain.o `test -f 'cat/test/test_expand_plain.c' || echo '$(srcdir)/'`cat/test/test_expand_plain.c - -cat/test/bsdcat_test-test_expand_plain.obj: cat/test/test_expand_plain.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_expand_plain.obj -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_expand_plain.Tpo -c -o cat/test/bsdcat_test-test_expand_plain.obj `if test -f 'cat/test/test_expand_plain.c'; then $(CYGPATH_W) 'cat/test/test_expand_plain.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_expand_plain.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_expand_plain.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_expand_plain.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_expand_plain.c' object='cat/test/bsdcat_test-test_expand_plain.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_expand_plain.obj `if test -f 'cat/test/test_expand_plain.c'; then $(CYGPATH_W) 'cat/test/test_expand_plain.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_expand_plain.c'; fi` - -cat/test/bsdcat_test-test_expand_xz.o: cat/test/test_expand_xz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_expand_xz.o -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_expand_xz.Tpo -c -o cat/test/bsdcat_test-test_expand_xz.o `test -f 'cat/test/test_expand_xz.c' || echo '$(srcdir)/'`cat/test/test_expand_xz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_expand_xz.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_expand_xz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_expand_xz.c' object='cat/test/bsdcat_test-test_expand_xz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_expand_xz.o `test -f 'cat/test/test_expand_xz.c' || echo '$(srcdir)/'`cat/test/test_expand_xz.c - -cat/test/bsdcat_test-test_expand_xz.obj: cat/test/test_expand_xz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_expand_xz.obj -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_expand_xz.Tpo -c -o cat/test/bsdcat_test-test_expand_xz.obj `if test -f 'cat/test/test_expand_xz.c'; then $(CYGPATH_W) 'cat/test/test_expand_xz.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_expand_xz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_expand_xz.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_expand_xz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_expand_xz.c' object='cat/test/bsdcat_test-test_expand_xz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_expand_xz.obj `if test -f 'cat/test/test_expand_xz.c'; then $(CYGPATH_W) 'cat/test/test_expand_xz.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_expand_xz.c'; fi` - -cat/test/bsdcat_test-test_expand_zstd.o: cat/test/test_expand_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_expand_zstd.o -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_expand_zstd.Tpo -c -o cat/test/bsdcat_test-test_expand_zstd.o `test -f 'cat/test/test_expand_zstd.c' || echo '$(srcdir)/'`cat/test/test_expand_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_expand_zstd.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_expand_zstd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_expand_zstd.c' object='cat/test/bsdcat_test-test_expand_zstd.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_expand_zstd.o `test -f 'cat/test/test_expand_zstd.c' || echo '$(srcdir)/'`cat/test/test_expand_zstd.c - -cat/test/bsdcat_test-test_expand_zstd.obj: cat/test/test_expand_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_expand_zstd.obj -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_expand_zstd.Tpo -c -o cat/test/bsdcat_test-test_expand_zstd.obj `if test -f 'cat/test/test_expand_zstd.c'; then $(CYGPATH_W) 'cat/test/test_expand_zstd.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_expand_zstd.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_expand_zstd.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_expand_zstd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_expand_zstd.c' object='cat/test/bsdcat_test-test_expand_zstd.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_expand_zstd.obj `if test -f 'cat/test/test_expand_zstd.c'; then $(CYGPATH_W) 'cat/test/test_expand_zstd.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_expand_zstd.c'; fi` - -cat/test/bsdcat_test-test_help.o: cat/test/test_help.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_help.o -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_help.Tpo -c -o cat/test/bsdcat_test-test_help.o `test -f 'cat/test/test_help.c' || echo '$(srcdir)/'`cat/test/test_help.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_help.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_help.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_help.c' object='cat/test/bsdcat_test-test_help.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_help.o `test -f 'cat/test/test_help.c' || echo '$(srcdir)/'`cat/test/test_help.c - -cat/test/bsdcat_test-test_help.obj: cat/test/test_help.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_help.obj -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_help.Tpo -c -o cat/test/bsdcat_test-test_help.obj `if test -f 'cat/test/test_help.c'; then $(CYGPATH_W) 'cat/test/test_help.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_help.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_help.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_help.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_help.c' object='cat/test/bsdcat_test-test_help.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_help.obj `if test -f 'cat/test/test_help.c'; then $(CYGPATH_W) 'cat/test/test_help.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_help.c'; fi` - -cat/test/bsdcat_test-test_stdin.o: cat/test/test_stdin.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_stdin.o -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_stdin.Tpo -c -o cat/test/bsdcat_test-test_stdin.o `test -f 'cat/test/test_stdin.c' || echo '$(srcdir)/'`cat/test/test_stdin.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_stdin.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_stdin.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_stdin.c' object='cat/test/bsdcat_test-test_stdin.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_stdin.o `test -f 'cat/test/test_stdin.c' || echo '$(srcdir)/'`cat/test/test_stdin.c - -cat/test/bsdcat_test-test_stdin.obj: cat/test/test_stdin.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_stdin.obj -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_stdin.Tpo -c -o cat/test/bsdcat_test-test_stdin.obj `if test -f 'cat/test/test_stdin.c'; then $(CYGPATH_W) 'cat/test/test_stdin.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_stdin.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_stdin.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_stdin.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_stdin.c' object='cat/test/bsdcat_test-test_stdin.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_stdin.obj `if test -f 'cat/test/test_stdin.c'; then $(CYGPATH_W) 'cat/test/test_stdin.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_stdin.c'; fi` - -cat/test/bsdcat_test-test_version.o: cat/test/test_version.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_version.o -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_version.Tpo -c -o cat/test/bsdcat_test-test_version.o `test -f 'cat/test/test_version.c' || echo '$(srcdir)/'`cat/test/test_version.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_version.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_version.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_version.c' object='cat/test/bsdcat_test-test_version.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_version.o `test -f 'cat/test/test_version.c' || echo '$(srcdir)/'`cat/test/test_version.c - -cat/test/bsdcat_test-test_version.obj: cat/test/test_version.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cat/test/bsdcat_test-test_version.obj -MD -MP -MF cat/test/$(DEPDIR)/bsdcat_test-test_version.Tpo -c -o cat/test/bsdcat_test-test_version.obj `if test -f 'cat/test/test_version.c'; then $(CYGPATH_W) 'cat/test/test_version.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_version.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cat/test/$(DEPDIR)/bsdcat_test-test_version.Tpo cat/test/$(DEPDIR)/bsdcat_test-test_version.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cat/test/test_version.c' object='cat/test/bsdcat_test-test_version.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcat_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cat/test/bsdcat_test-test_version.obj `if test -f 'cat/test/test_version.c'; then $(CYGPATH_W) 'cat/test/test_version.c'; else $(CYGPATH_W) '$(srcdir)/cat/test/test_version.c'; fi` - -cpio/bsdcpio-cmdline.o: cpio/cmdline.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/bsdcpio-cmdline.o -MD -MP -MF cpio/$(DEPDIR)/bsdcpio-cmdline.Tpo -c -o cpio/bsdcpio-cmdline.o `test -f 'cpio/cmdline.c' || echo '$(srcdir)/'`cpio/cmdline.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/$(DEPDIR)/bsdcpio-cmdline.Tpo cpio/$(DEPDIR)/bsdcpio-cmdline.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/cmdline.c' object='cpio/bsdcpio-cmdline.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/bsdcpio-cmdline.o `test -f 'cpio/cmdline.c' || echo '$(srcdir)/'`cpio/cmdline.c - -cpio/bsdcpio-cmdline.obj: cpio/cmdline.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/bsdcpio-cmdline.obj -MD -MP -MF cpio/$(DEPDIR)/bsdcpio-cmdline.Tpo -c -o cpio/bsdcpio-cmdline.obj `if test -f 'cpio/cmdline.c'; then $(CYGPATH_W) 'cpio/cmdline.c'; else $(CYGPATH_W) '$(srcdir)/cpio/cmdline.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/$(DEPDIR)/bsdcpio-cmdline.Tpo cpio/$(DEPDIR)/bsdcpio-cmdline.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/cmdline.c' object='cpio/bsdcpio-cmdline.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/bsdcpio-cmdline.obj `if test -f 'cpio/cmdline.c'; then $(CYGPATH_W) 'cpio/cmdline.c'; else $(CYGPATH_W) '$(srcdir)/cpio/cmdline.c'; fi` - -cpio/bsdcpio-cpio.o: cpio/cpio.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/bsdcpio-cpio.o -MD -MP -MF cpio/$(DEPDIR)/bsdcpio-cpio.Tpo -c -o cpio/bsdcpio-cpio.o `test -f 'cpio/cpio.c' || echo '$(srcdir)/'`cpio/cpio.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/$(DEPDIR)/bsdcpio-cpio.Tpo cpio/$(DEPDIR)/bsdcpio-cpio.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/cpio.c' object='cpio/bsdcpio-cpio.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/bsdcpio-cpio.o `test -f 'cpio/cpio.c' || echo '$(srcdir)/'`cpio/cpio.c - -cpio/bsdcpio-cpio.obj: cpio/cpio.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/bsdcpio-cpio.obj -MD -MP -MF cpio/$(DEPDIR)/bsdcpio-cpio.Tpo -c -o cpio/bsdcpio-cpio.obj `if test -f 'cpio/cpio.c'; then $(CYGPATH_W) 'cpio/cpio.c'; else $(CYGPATH_W) '$(srcdir)/cpio/cpio.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/$(DEPDIR)/bsdcpio-cpio.Tpo cpio/$(DEPDIR)/bsdcpio-cpio.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/cpio.c' object='cpio/bsdcpio-cpio.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/bsdcpio-cpio.obj `if test -f 'cpio/cpio.c'; then $(CYGPATH_W) 'cpio/cpio.c'; else $(CYGPATH_W) '$(srcdir)/cpio/cpio.c'; fi` - -cpio/bsdcpio-cpio_windows.o: cpio/cpio_windows.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/bsdcpio-cpio_windows.o -MD -MP -MF cpio/$(DEPDIR)/bsdcpio-cpio_windows.Tpo -c -o cpio/bsdcpio-cpio_windows.o `test -f 'cpio/cpio_windows.c' || echo '$(srcdir)/'`cpio/cpio_windows.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/$(DEPDIR)/bsdcpio-cpio_windows.Tpo cpio/$(DEPDIR)/bsdcpio-cpio_windows.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/cpio_windows.c' object='cpio/bsdcpio-cpio_windows.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/bsdcpio-cpio_windows.o `test -f 'cpio/cpio_windows.c' || echo '$(srcdir)/'`cpio/cpio_windows.c - -cpio/bsdcpio-cpio_windows.obj: cpio/cpio_windows.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/bsdcpio-cpio_windows.obj -MD -MP -MF cpio/$(DEPDIR)/bsdcpio-cpio_windows.Tpo -c -o cpio/bsdcpio-cpio_windows.obj `if test -f 'cpio/cpio_windows.c'; then $(CYGPATH_W) 'cpio/cpio_windows.c'; else $(CYGPATH_W) '$(srcdir)/cpio/cpio_windows.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/$(DEPDIR)/bsdcpio-cpio_windows.Tpo cpio/$(DEPDIR)/bsdcpio-cpio_windows.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/cpio_windows.c' object='cpio/bsdcpio-cpio_windows.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/bsdcpio-cpio_windows.obj `if test -f 'cpio/cpio_windows.c'; then $(CYGPATH_W) 'cpio/cpio_windows.c'; else $(CYGPATH_W) '$(srcdir)/cpio/cpio_windows.c'; fi` - -test_utils/bsdcpio_test-test_utils.o: test_utils/test_utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_utils/bsdcpio_test-test_utils.o -MD -MP -MF test_utils/$(DEPDIR)/bsdcpio_test-test_utils.Tpo -c -o test_utils/bsdcpio_test-test_utils.o `test -f 'test_utils/test_utils.c' || echo '$(srcdir)/'`test_utils/test_utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test_utils/$(DEPDIR)/bsdcpio_test-test_utils.Tpo test_utils/$(DEPDIR)/bsdcpio_test-test_utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_utils/test_utils.c' object='test_utils/bsdcpio_test-test_utils.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_utils/bsdcpio_test-test_utils.o `test -f 'test_utils/test_utils.c' || echo '$(srcdir)/'`test_utils/test_utils.c - -test_utils/bsdcpio_test-test_utils.obj: test_utils/test_utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_utils/bsdcpio_test-test_utils.obj -MD -MP -MF test_utils/$(DEPDIR)/bsdcpio_test-test_utils.Tpo -c -o test_utils/bsdcpio_test-test_utils.obj `if test -f 'test_utils/test_utils.c'; then $(CYGPATH_W) 'test_utils/test_utils.c'; else $(CYGPATH_W) '$(srcdir)/test_utils/test_utils.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test_utils/$(DEPDIR)/bsdcpio_test-test_utils.Tpo test_utils/$(DEPDIR)/bsdcpio_test-test_utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_utils/test_utils.c' object='test_utils/bsdcpio_test-test_utils.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_utils/bsdcpio_test-test_utils.obj `if test -f 'test_utils/test_utils.c'; then $(CYGPATH_W) 'test_utils/test_utils.c'; else $(CYGPATH_W) '$(srcdir)/test_utils/test_utils.c'; fi` - -test_utils/bsdcpio_test-test_main.o: test_utils/test_main.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_utils/bsdcpio_test-test_main.o -MD -MP -MF test_utils/$(DEPDIR)/bsdcpio_test-test_main.Tpo -c -o test_utils/bsdcpio_test-test_main.o `test -f 'test_utils/test_main.c' || echo '$(srcdir)/'`test_utils/test_main.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test_utils/$(DEPDIR)/bsdcpio_test-test_main.Tpo test_utils/$(DEPDIR)/bsdcpio_test-test_main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_utils/test_main.c' object='test_utils/bsdcpio_test-test_main.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_utils/bsdcpio_test-test_main.o `test -f 'test_utils/test_main.c' || echo '$(srcdir)/'`test_utils/test_main.c - -test_utils/bsdcpio_test-test_main.obj: test_utils/test_main.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_utils/bsdcpio_test-test_main.obj -MD -MP -MF test_utils/$(DEPDIR)/bsdcpio_test-test_main.Tpo -c -o test_utils/bsdcpio_test-test_main.obj `if test -f 'test_utils/test_main.c'; then $(CYGPATH_W) 'test_utils/test_main.c'; else $(CYGPATH_W) '$(srcdir)/test_utils/test_main.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test_utils/$(DEPDIR)/bsdcpio_test-test_main.Tpo test_utils/$(DEPDIR)/bsdcpio_test-test_main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_utils/test_main.c' object='test_utils/bsdcpio_test-test_main.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_utils/bsdcpio_test-test_main.obj `if test -f 'test_utils/test_main.c'; then $(CYGPATH_W) 'test_utils/test_main.c'; else $(CYGPATH_W) '$(srcdir)/test_utils/test_main.c'; fi` - -cpio/bsdcpio_test-cmdline.o: cpio/cmdline.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/bsdcpio_test-cmdline.o -MD -MP -MF cpio/$(DEPDIR)/bsdcpio_test-cmdline.Tpo -c -o cpio/bsdcpio_test-cmdline.o `test -f 'cpio/cmdline.c' || echo '$(srcdir)/'`cpio/cmdline.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/$(DEPDIR)/bsdcpio_test-cmdline.Tpo cpio/$(DEPDIR)/bsdcpio_test-cmdline.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/cmdline.c' object='cpio/bsdcpio_test-cmdline.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/bsdcpio_test-cmdline.o `test -f 'cpio/cmdline.c' || echo '$(srcdir)/'`cpio/cmdline.c - -cpio/bsdcpio_test-cmdline.obj: cpio/cmdline.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/bsdcpio_test-cmdline.obj -MD -MP -MF cpio/$(DEPDIR)/bsdcpio_test-cmdline.Tpo -c -o cpio/bsdcpio_test-cmdline.obj `if test -f 'cpio/cmdline.c'; then $(CYGPATH_W) 'cpio/cmdline.c'; else $(CYGPATH_W) '$(srcdir)/cpio/cmdline.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/$(DEPDIR)/bsdcpio_test-cmdline.Tpo cpio/$(DEPDIR)/bsdcpio_test-cmdline.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/cmdline.c' object='cpio/bsdcpio_test-cmdline.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/bsdcpio_test-cmdline.obj `if test -f 'cpio/cmdline.c'; then $(CYGPATH_W) 'cpio/cmdline.c'; else $(CYGPATH_W) '$(srcdir)/cpio/cmdline.c'; fi` - -cpio/test/bsdcpio_test-test_0.o: cpio/test/test_0.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_0.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_0.Tpo -c -o cpio/test/bsdcpio_test-test_0.o `test -f 'cpio/test/test_0.c' || echo '$(srcdir)/'`cpio/test/test_0.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_0.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_0.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_0.c' object='cpio/test/bsdcpio_test-test_0.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_0.o `test -f 'cpio/test/test_0.c' || echo '$(srcdir)/'`cpio/test/test_0.c - -cpio/test/bsdcpio_test-test_0.obj: cpio/test/test_0.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_0.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_0.Tpo -c -o cpio/test/bsdcpio_test-test_0.obj `if test -f 'cpio/test/test_0.c'; then $(CYGPATH_W) 'cpio/test/test_0.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_0.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_0.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_0.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_0.c' object='cpio/test/bsdcpio_test-test_0.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_0.obj `if test -f 'cpio/test/test_0.c'; then $(CYGPATH_W) 'cpio/test/test_0.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_0.c'; fi` - -cpio/test/bsdcpio_test-test_basic.o: cpio/test/test_basic.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_basic.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_basic.Tpo -c -o cpio/test/bsdcpio_test-test_basic.o `test -f 'cpio/test/test_basic.c' || echo '$(srcdir)/'`cpio/test/test_basic.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_basic.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_basic.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_basic.c' object='cpio/test/bsdcpio_test-test_basic.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_basic.o `test -f 'cpio/test/test_basic.c' || echo '$(srcdir)/'`cpio/test/test_basic.c - -cpio/test/bsdcpio_test-test_basic.obj: cpio/test/test_basic.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_basic.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_basic.Tpo -c -o cpio/test/bsdcpio_test-test_basic.obj `if test -f 'cpio/test/test_basic.c'; then $(CYGPATH_W) 'cpio/test/test_basic.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_basic.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_basic.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_basic.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_basic.c' object='cpio/test/bsdcpio_test-test_basic.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_basic.obj `if test -f 'cpio/test/test_basic.c'; then $(CYGPATH_W) 'cpio/test/test_basic.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_basic.c'; fi` - -cpio/test/bsdcpio_test-test_cmdline.o: cpio/test/test_cmdline.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_cmdline.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_cmdline.Tpo -c -o cpio/test/bsdcpio_test-test_cmdline.o `test -f 'cpio/test/test_cmdline.c' || echo '$(srcdir)/'`cpio/test/test_cmdline.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_cmdline.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_cmdline.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_cmdline.c' object='cpio/test/bsdcpio_test-test_cmdline.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_cmdline.o `test -f 'cpio/test/test_cmdline.c' || echo '$(srcdir)/'`cpio/test/test_cmdline.c - -cpio/test/bsdcpio_test-test_cmdline.obj: cpio/test/test_cmdline.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_cmdline.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_cmdline.Tpo -c -o cpio/test/bsdcpio_test-test_cmdline.obj `if test -f 'cpio/test/test_cmdline.c'; then $(CYGPATH_W) 'cpio/test/test_cmdline.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_cmdline.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_cmdline.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_cmdline.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_cmdline.c' object='cpio/test/bsdcpio_test-test_cmdline.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_cmdline.obj `if test -f 'cpio/test/test_cmdline.c'; then $(CYGPATH_W) 'cpio/test/test_cmdline.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_cmdline.c'; fi` - -cpio/test/bsdcpio_test-test_extract_cpio_Z.o: cpio/test/test_extract_cpio_Z.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_extract_cpio_Z.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_Z.Tpo -c -o cpio/test/bsdcpio_test-test_extract_cpio_Z.o `test -f 'cpio/test/test_extract_cpio_Z.c' || echo '$(srcdir)/'`cpio/test/test_extract_cpio_Z.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_Z.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_Z.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_extract_cpio_Z.c' object='cpio/test/bsdcpio_test-test_extract_cpio_Z.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_extract_cpio_Z.o `test -f 'cpio/test/test_extract_cpio_Z.c' || echo '$(srcdir)/'`cpio/test/test_extract_cpio_Z.c - -cpio/test/bsdcpio_test-test_extract_cpio_Z.obj: cpio/test/test_extract_cpio_Z.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_extract_cpio_Z.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_Z.Tpo -c -o cpio/test/bsdcpio_test-test_extract_cpio_Z.obj `if test -f 'cpio/test/test_extract_cpio_Z.c'; then $(CYGPATH_W) 'cpio/test/test_extract_cpio_Z.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_extract_cpio_Z.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_Z.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_Z.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_extract_cpio_Z.c' object='cpio/test/bsdcpio_test-test_extract_cpio_Z.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_extract_cpio_Z.obj `if test -f 'cpio/test/test_extract_cpio_Z.c'; then $(CYGPATH_W) 'cpio/test/test_extract_cpio_Z.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_extract_cpio_Z.c'; fi` - -cpio/test/bsdcpio_test-test_extract_cpio_bz2.o: cpio/test/test_extract_cpio_bz2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_extract_cpio_bz2.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_bz2.Tpo -c -o cpio/test/bsdcpio_test-test_extract_cpio_bz2.o `test -f 'cpio/test/test_extract_cpio_bz2.c' || echo '$(srcdir)/'`cpio/test/test_extract_cpio_bz2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_bz2.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_bz2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_extract_cpio_bz2.c' object='cpio/test/bsdcpio_test-test_extract_cpio_bz2.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_extract_cpio_bz2.o `test -f 'cpio/test/test_extract_cpio_bz2.c' || echo '$(srcdir)/'`cpio/test/test_extract_cpio_bz2.c - -cpio/test/bsdcpio_test-test_extract_cpio_bz2.obj: cpio/test/test_extract_cpio_bz2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_extract_cpio_bz2.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_bz2.Tpo -c -o cpio/test/bsdcpio_test-test_extract_cpio_bz2.obj `if test -f 'cpio/test/test_extract_cpio_bz2.c'; then $(CYGPATH_W) 'cpio/test/test_extract_cpio_bz2.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_extract_cpio_bz2.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_bz2.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_bz2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_extract_cpio_bz2.c' object='cpio/test/bsdcpio_test-test_extract_cpio_bz2.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_extract_cpio_bz2.obj `if test -f 'cpio/test/test_extract_cpio_bz2.c'; then $(CYGPATH_W) 'cpio/test/test_extract_cpio_bz2.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_extract_cpio_bz2.c'; fi` - -cpio/test/bsdcpio_test-test_extract_cpio_grz.o: cpio/test/test_extract_cpio_grz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_extract_cpio_grz.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_grz.Tpo -c -o cpio/test/bsdcpio_test-test_extract_cpio_grz.o `test -f 'cpio/test/test_extract_cpio_grz.c' || echo '$(srcdir)/'`cpio/test/test_extract_cpio_grz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_grz.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_grz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_extract_cpio_grz.c' object='cpio/test/bsdcpio_test-test_extract_cpio_grz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_extract_cpio_grz.o `test -f 'cpio/test/test_extract_cpio_grz.c' || echo '$(srcdir)/'`cpio/test/test_extract_cpio_grz.c - -cpio/test/bsdcpio_test-test_extract_cpio_grz.obj: cpio/test/test_extract_cpio_grz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_extract_cpio_grz.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_grz.Tpo -c -o cpio/test/bsdcpio_test-test_extract_cpio_grz.obj `if test -f 'cpio/test/test_extract_cpio_grz.c'; then $(CYGPATH_W) 'cpio/test/test_extract_cpio_grz.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_extract_cpio_grz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_grz.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_grz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_extract_cpio_grz.c' object='cpio/test/bsdcpio_test-test_extract_cpio_grz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_extract_cpio_grz.obj `if test -f 'cpio/test/test_extract_cpio_grz.c'; then $(CYGPATH_W) 'cpio/test/test_extract_cpio_grz.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_extract_cpio_grz.c'; fi` - -cpio/test/bsdcpio_test-test_extract_cpio_gz.o: cpio/test/test_extract_cpio_gz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_extract_cpio_gz.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_gz.Tpo -c -o cpio/test/bsdcpio_test-test_extract_cpio_gz.o `test -f 'cpio/test/test_extract_cpio_gz.c' || echo '$(srcdir)/'`cpio/test/test_extract_cpio_gz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_gz.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_gz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_extract_cpio_gz.c' object='cpio/test/bsdcpio_test-test_extract_cpio_gz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_extract_cpio_gz.o `test -f 'cpio/test/test_extract_cpio_gz.c' || echo '$(srcdir)/'`cpio/test/test_extract_cpio_gz.c - -cpio/test/bsdcpio_test-test_extract_cpio_gz.obj: cpio/test/test_extract_cpio_gz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_extract_cpio_gz.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_gz.Tpo -c -o cpio/test/bsdcpio_test-test_extract_cpio_gz.obj `if test -f 'cpio/test/test_extract_cpio_gz.c'; then $(CYGPATH_W) 'cpio/test/test_extract_cpio_gz.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_extract_cpio_gz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_gz.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_gz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_extract_cpio_gz.c' object='cpio/test/bsdcpio_test-test_extract_cpio_gz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_extract_cpio_gz.obj `if test -f 'cpio/test/test_extract_cpio_gz.c'; then $(CYGPATH_W) 'cpio/test/test_extract_cpio_gz.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_extract_cpio_gz.c'; fi` - -cpio/test/bsdcpio_test-test_extract_cpio_lrz.o: cpio/test/test_extract_cpio_lrz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_extract_cpio_lrz.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lrz.Tpo -c -o cpio/test/bsdcpio_test-test_extract_cpio_lrz.o `test -f 'cpio/test/test_extract_cpio_lrz.c' || echo '$(srcdir)/'`cpio/test/test_extract_cpio_lrz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lrz.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lrz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_extract_cpio_lrz.c' object='cpio/test/bsdcpio_test-test_extract_cpio_lrz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_extract_cpio_lrz.o `test -f 'cpio/test/test_extract_cpio_lrz.c' || echo '$(srcdir)/'`cpio/test/test_extract_cpio_lrz.c - -cpio/test/bsdcpio_test-test_extract_cpio_lrz.obj: cpio/test/test_extract_cpio_lrz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_extract_cpio_lrz.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lrz.Tpo -c -o cpio/test/bsdcpio_test-test_extract_cpio_lrz.obj `if test -f 'cpio/test/test_extract_cpio_lrz.c'; then $(CYGPATH_W) 'cpio/test/test_extract_cpio_lrz.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_extract_cpio_lrz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lrz.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lrz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_extract_cpio_lrz.c' object='cpio/test/bsdcpio_test-test_extract_cpio_lrz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_extract_cpio_lrz.obj `if test -f 'cpio/test/test_extract_cpio_lrz.c'; then $(CYGPATH_W) 'cpio/test/test_extract_cpio_lrz.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_extract_cpio_lrz.c'; fi` - -cpio/test/bsdcpio_test-test_extract_cpio_lz.o: cpio/test/test_extract_cpio_lz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_extract_cpio_lz.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lz.Tpo -c -o cpio/test/bsdcpio_test-test_extract_cpio_lz.o `test -f 'cpio/test/test_extract_cpio_lz.c' || echo '$(srcdir)/'`cpio/test/test_extract_cpio_lz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lz.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_extract_cpio_lz.c' object='cpio/test/bsdcpio_test-test_extract_cpio_lz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_extract_cpio_lz.o `test -f 'cpio/test/test_extract_cpio_lz.c' || echo '$(srcdir)/'`cpio/test/test_extract_cpio_lz.c - -cpio/test/bsdcpio_test-test_extract_cpio_lz.obj: cpio/test/test_extract_cpio_lz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_extract_cpio_lz.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lz.Tpo -c -o cpio/test/bsdcpio_test-test_extract_cpio_lz.obj `if test -f 'cpio/test/test_extract_cpio_lz.c'; then $(CYGPATH_W) 'cpio/test/test_extract_cpio_lz.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_extract_cpio_lz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lz.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_extract_cpio_lz.c' object='cpio/test/bsdcpio_test-test_extract_cpio_lz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_extract_cpio_lz.obj `if test -f 'cpio/test/test_extract_cpio_lz.c'; then $(CYGPATH_W) 'cpio/test/test_extract_cpio_lz.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_extract_cpio_lz.c'; fi` - -cpio/test/bsdcpio_test-test_extract_cpio_lz4.o: cpio/test/test_extract_cpio_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_extract_cpio_lz4.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lz4.Tpo -c -o cpio/test/bsdcpio_test-test_extract_cpio_lz4.o `test -f 'cpio/test/test_extract_cpio_lz4.c' || echo '$(srcdir)/'`cpio/test/test_extract_cpio_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lz4.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lz4.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_extract_cpio_lz4.c' object='cpio/test/bsdcpio_test-test_extract_cpio_lz4.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_extract_cpio_lz4.o `test -f 'cpio/test/test_extract_cpio_lz4.c' || echo '$(srcdir)/'`cpio/test/test_extract_cpio_lz4.c - -cpio/test/bsdcpio_test-test_extract_cpio_lz4.obj: cpio/test/test_extract_cpio_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_extract_cpio_lz4.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lz4.Tpo -c -o cpio/test/bsdcpio_test-test_extract_cpio_lz4.obj `if test -f 'cpio/test/test_extract_cpio_lz4.c'; then $(CYGPATH_W) 'cpio/test/test_extract_cpio_lz4.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_extract_cpio_lz4.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lz4.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lz4.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_extract_cpio_lz4.c' object='cpio/test/bsdcpio_test-test_extract_cpio_lz4.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_extract_cpio_lz4.obj `if test -f 'cpio/test/test_extract_cpio_lz4.c'; then $(CYGPATH_W) 'cpio/test/test_extract_cpio_lz4.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_extract_cpio_lz4.c'; fi` - -cpio/test/bsdcpio_test-test_extract_cpio_lzma.o: cpio/test/test_extract_cpio_lzma.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_extract_cpio_lzma.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lzma.Tpo -c -o cpio/test/bsdcpio_test-test_extract_cpio_lzma.o `test -f 'cpio/test/test_extract_cpio_lzma.c' || echo '$(srcdir)/'`cpio/test/test_extract_cpio_lzma.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lzma.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lzma.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_extract_cpio_lzma.c' object='cpio/test/bsdcpio_test-test_extract_cpio_lzma.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_extract_cpio_lzma.o `test -f 'cpio/test/test_extract_cpio_lzma.c' || echo '$(srcdir)/'`cpio/test/test_extract_cpio_lzma.c - -cpio/test/bsdcpio_test-test_extract_cpio_lzma.obj: cpio/test/test_extract_cpio_lzma.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_extract_cpio_lzma.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lzma.Tpo -c -o cpio/test/bsdcpio_test-test_extract_cpio_lzma.obj `if test -f 'cpio/test/test_extract_cpio_lzma.c'; then $(CYGPATH_W) 'cpio/test/test_extract_cpio_lzma.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_extract_cpio_lzma.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lzma.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lzma.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_extract_cpio_lzma.c' object='cpio/test/bsdcpio_test-test_extract_cpio_lzma.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_extract_cpio_lzma.obj `if test -f 'cpio/test/test_extract_cpio_lzma.c'; then $(CYGPATH_W) 'cpio/test/test_extract_cpio_lzma.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_extract_cpio_lzma.c'; fi` - -cpio/test/bsdcpio_test-test_extract_cpio_lzo.o: cpio/test/test_extract_cpio_lzo.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_extract_cpio_lzo.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lzo.Tpo -c -o cpio/test/bsdcpio_test-test_extract_cpio_lzo.o `test -f 'cpio/test/test_extract_cpio_lzo.c' || echo '$(srcdir)/'`cpio/test/test_extract_cpio_lzo.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lzo.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lzo.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_extract_cpio_lzo.c' object='cpio/test/bsdcpio_test-test_extract_cpio_lzo.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_extract_cpio_lzo.o `test -f 'cpio/test/test_extract_cpio_lzo.c' || echo '$(srcdir)/'`cpio/test/test_extract_cpio_lzo.c - -cpio/test/bsdcpio_test-test_extract_cpio_lzo.obj: cpio/test/test_extract_cpio_lzo.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_extract_cpio_lzo.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lzo.Tpo -c -o cpio/test/bsdcpio_test-test_extract_cpio_lzo.obj `if test -f 'cpio/test/test_extract_cpio_lzo.c'; then $(CYGPATH_W) 'cpio/test/test_extract_cpio_lzo.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_extract_cpio_lzo.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lzo.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lzo.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_extract_cpio_lzo.c' object='cpio/test/bsdcpio_test-test_extract_cpio_lzo.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_extract_cpio_lzo.obj `if test -f 'cpio/test/test_extract_cpio_lzo.c'; then $(CYGPATH_W) 'cpio/test/test_extract_cpio_lzo.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_extract_cpio_lzo.c'; fi` - -cpio/test/bsdcpio_test-test_extract_cpio_xz.o: cpio/test/test_extract_cpio_xz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_extract_cpio_xz.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_xz.Tpo -c -o cpio/test/bsdcpio_test-test_extract_cpio_xz.o `test -f 'cpio/test/test_extract_cpio_xz.c' || echo '$(srcdir)/'`cpio/test/test_extract_cpio_xz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_xz.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_xz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_extract_cpio_xz.c' object='cpio/test/bsdcpio_test-test_extract_cpio_xz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_extract_cpio_xz.o `test -f 'cpio/test/test_extract_cpio_xz.c' || echo '$(srcdir)/'`cpio/test/test_extract_cpio_xz.c - -cpio/test/bsdcpio_test-test_extract_cpio_xz.obj: cpio/test/test_extract_cpio_xz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_extract_cpio_xz.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_xz.Tpo -c -o cpio/test/bsdcpio_test-test_extract_cpio_xz.obj `if test -f 'cpio/test/test_extract_cpio_xz.c'; then $(CYGPATH_W) 'cpio/test/test_extract_cpio_xz.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_extract_cpio_xz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_xz.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_xz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_extract_cpio_xz.c' object='cpio/test/bsdcpio_test-test_extract_cpio_xz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_extract_cpio_xz.obj `if test -f 'cpio/test/test_extract_cpio_xz.c'; then $(CYGPATH_W) 'cpio/test/test_extract_cpio_xz.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_extract_cpio_xz.c'; fi` - -cpio/test/bsdcpio_test-test_extract_cpio_zstd.o: cpio/test/test_extract_cpio_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_extract_cpio_zstd.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_zstd.Tpo -c -o cpio/test/bsdcpio_test-test_extract_cpio_zstd.o `test -f 'cpio/test/test_extract_cpio_zstd.c' || echo '$(srcdir)/'`cpio/test/test_extract_cpio_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_zstd.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_zstd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_extract_cpio_zstd.c' object='cpio/test/bsdcpio_test-test_extract_cpio_zstd.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_extract_cpio_zstd.o `test -f 'cpio/test/test_extract_cpio_zstd.c' || echo '$(srcdir)/'`cpio/test/test_extract_cpio_zstd.c - -cpio/test/bsdcpio_test-test_extract_cpio_zstd.obj: cpio/test/test_extract_cpio_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_extract_cpio_zstd.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_zstd.Tpo -c -o cpio/test/bsdcpio_test-test_extract_cpio_zstd.obj `if test -f 'cpio/test/test_extract_cpio_zstd.c'; then $(CYGPATH_W) 'cpio/test/test_extract_cpio_zstd.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_extract_cpio_zstd.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_zstd.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_zstd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_extract_cpio_zstd.c' object='cpio/test/bsdcpio_test-test_extract_cpio_zstd.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_extract_cpio_zstd.obj `if test -f 'cpio/test/test_extract_cpio_zstd.c'; then $(CYGPATH_W) 'cpio/test/test_extract_cpio_zstd.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_extract_cpio_zstd.c'; fi` - -cpio/test/bsdcpio_test-test_format_newc.o: cpio/test/test_format_newc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_format_newc.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_format_newc.Tpo -c -o cpio/test/bsdcpio_test-test_format_newc.o `test -f 'cpio/test/test_format_newc.c' || echo '$(srcdir)/'`cpio/test/test_format_newc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_format_newc.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_format_newc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_format_newc.c' object='cpio/test/bsdcpio_test-test_format_newc.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_format_newc.o `test -f 'cpio/test/test_format_newc.c' || echo '$(srcdir)/'`cpio/test/test_format_newc.c - -cpio/test/bsdcpio_test-test_format_newc.obj: cpio/test/test_format_newc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_format_newc.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_format_newc.Tpo -c -o cpio/test/bsdcpio_test-test_format_newc.obj `if test -f 'cpio/test/test_format_newc.c'; then $(CYGPATH_W) 'cpio/test/test_format_newc.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_format_newc.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_format_newc.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_format_newc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_format_newc.c' object='cpio/test/bsdcpio_test-test_format_newc.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_format_newc.obj `if test -f 'cpio/test/test_format_newc.c'; then $(CYGPATH_W) 'cpio/test/test_format_newc.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_format_newc.c'; fi` - -cpio/test/bsdcpio_test-test_gcpio_compat.o: cpio/test/test_gcpio_compat.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_gcpio_compat.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_gcpio_compat.Tpo -c -o cpio/test/bsdcpio_test-test_gcpio_compat.o `test -f 'cpio/test/test_gcpio_compat.c' || echo '$(srcdir)/'`cpio/test/test_gcpio_compat.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_gcpio_compat.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_gcpio_compat.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_gcpio_compat.c' object='cpio/test/bsdcpio_test-test_gcpio_compat.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_gcpio_compat.o `test -f 'cpio/test/test_gcpio_compat.c' || echo '$(srcdir)/'`cpio/test/test_gcpio_compat.c - -cpio/test/bsdcpio_test-test_gcpio_compat.obj: cpio/test/test_gcpio_compat.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_gcpio_compat.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_gcpio_compat.Tpo -c -o cpio/test/bsdcpio_test-test_gcpio_compat.obj `if test -f 'cpio/test/test_gcpio_compat.c'; then $(CYGPATH_W) 'cpio/test/test_gcpio_compat.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_gcpio_compat.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_gcpio_compat.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_gcpio_compat.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_gcpio_compat.c' object='cpio/test/bsdcpio_test-test_gcpio_compat.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_gcpio_compat.obj `if test -f 'cpio/test/test_gcpio_compat.c'; then $(CYGPATH_W) 'cpio/test/test_gcpio_compat.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_gcpio_compat.c'; fi` - -cpio/test/bsdcpio_test-test_missing_file.o: cpio/test/test_missing_file.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_missing_file.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_missing_file.Tpo -c -o cpio/test/bsdcpio_test-test_missing_file.o `test -f 'cpio/test/test_missing_file.c' || echo '$(srcdir)/'`cpio/test/test_missing_file.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_missing_file.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_missing_file.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_missing_file.c' object='cpio/test/bsdcpio_test-test_missing_file.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_missing_file.o `test -f 'cpio/test/test_missing_file.c' || echo '$(srcdir)/'`cpio/test/test_missing_file.c - -cpio/test/bsdcpio_test-test_missing_file.obj: cpio/test/test_missing_file.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_missing_file.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_missing_file.Tpo -c -o cpio/test/bsdcpio_test-test_missing_file.obj `if test -f 'cpio/test/test_missing_file.c'; then $(CYGPATH_W) 'cpio/test/test_missing_file.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_missing_file.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_missing_file.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_missing_file.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_missing_file.c' object='cpio/test/bsdcpio_test-test_missing_file.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_missing_file.obj `if test -f 'cpio/test/test_missing_file.c'; then $(CYGPATH_W) 'cpio/test/test_missing_file.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_missing_file.c'; fi` - -cpio/test/bsdcpio_test-test_option_0.o: cpio/test/test_option_0.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_0.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_0.Tpo -c -o cpio/test/bsdcpio_test-test_option_0.o `test -f 'cpio/test/test_option_0.c' || echo '$(srcdir)/'`cpio/test/test_option_0.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_0.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_0.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_0.c' object='cpio/test/bsdcpio_test-test_option_0.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_0.o `test -f 'cpio/test/test_option_0.c' || echo '$(srcdir)/'`cpio/test/test_option_0.c - -cpio/test/bsdcpio_test-test_option_0.obj: cpio/test/test_option_0.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_0.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_0.Tpo -c -o cpio/test/bsdcpio_test-test_option_0.obj `if test -f 'cpio/test/test_option_0.c'; then $(CYGPATH_W) 'cpio/test/test_option_0.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_0.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_0.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_0.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_0.c' object='cpio/test/bsdcpio_test-test_option_0.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_0.obj `if test -f 'cpio/test/test_option_0.c'; then $(CYGPATH_W) 'cpio/test/test_option_0.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_0.c'; fi` - -cpio/test/bsdcpio_test-test_option_B_upper.o: cpio/test/test_option_B_upper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_B_upper.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_B_upper.Tpo -c -o cpio/test/bsdcpio_test-test_option_B_upper.o `test -f 'cpio/test/test_option_B_upper.c' || echo '$(srcdir)/'`cpio/test/test_option_B_upper.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_B_upper.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_B_upper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_B_upper.c' object='cpio/test/bsdcpio_test-test_option_B_upper.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_B_upper.o `test -f 'cpio/test/test_option_B_upper.c' || echo '$(srcdir)/'`cpio/test/test_option_B_upper.c - -cpio/test/bsdcpio_test-test_option_B_upper.obj: cpio/test/test_option_B_upper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_B_upper.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_B_upper.Tpo -c -o cpio/test/bsdcpio_test-test_option_B_upper.obj `if test -f 'cpio/test/test_option_B_upper.c'; then $(CYGPATH_W) 'cpio/test/test_option_B_upper.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_B_upper.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_B_upper.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_B_upper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_B_upper.c' object='cpio/test/bsdcpio_test-test_option_B_upper.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_B_upper.obj `if test -f 'cpio/test/test_option_B_upper.c'; then $(CYGPATH_W) 'cpio/test/test_option_B_upper.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_B_upper.c'; fi` - -cpio/test/bsdcpio_test-test_option_C_upper.o: cpio/test/test_option_C_upper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_C_upper.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_C_upper.Tpo -c -o cpio/test/bsdcpio_test-test_option_C_upper.o `test -f 'cpio/test/test_option_C_upper.c' || echo '$(srcdir)/'`cpio/test/test_option_C_upper.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_C_upper.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_C_upper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_C_upper.c' object='cpio/test/bsdcpio_test-test_option_C_upper.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_C_upper.o `test -f 'cpio/test/test_option_C_upper.c' || echo '$(srcdir)/'`cpio/test/test_option_C_upper.c - -cpio/test/bsdcpio_test-test_option_C_upper.obj: cpio/test/test_option_C_upper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_C_upper.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_C_upper.Tpo -c -o cpio/test/bsdcpio_test-test_option_C_upper.obj `if test -f 'cpio/test/test_option_C_upper.c'; then $(CYGPATH_W) 'cpio/test/test_option_C_upper.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_C_upper.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_C_upper.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_C_upper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_C_upper.c' object='cpio/test/bsdcpio_test-test_option_C_upper.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_C_upper.obj `if test -f 'cpio/test/test_option_C_upper.c'; then $(CYGPATH_W) 'cpio/test/test_option_C_upper.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_C_upper.c'; fi` - -cpio/test/bsdcpio_test-test_option_J_upper.o: cpio/test/test_option_J_upper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_J_upper.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_J_upper.Tpo -c -o cpio/test/bsdcpio_test-test_option_J_upper.o `test -f 'cpio/test/test_option_J_upper.c' || echo '$(srcdir)/'`cpio/test/test_option_J_upper.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_J_upper.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_J_upper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_J_upper.c' object='cpio/test/bsdcpio_test-test_option_J_upper.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_J_upper.o `test -f 'cpio/test/test_option_J_upper.c' || echo '$(srcdir)/'`cpio/test/test_option_J_upper.c - -cpio/test/bsdcpio_test-test_option_J_upper.obj: cpio/test/test_option_J_upper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_J_upper.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_J_upper.Tpo -c -o cpio/test/bsdcpio_test-test_option_J_upper.obj `if test -f 'cpio/test/test_option_J_upper.c'; then $(CYGPATH_W) 'cpio/test/test_option_J_upper.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_J_upper.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_J_upper.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_J_upper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_J_upper.c' object='cpio/test/bsdcpio_test-test_option_J_upper.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_J_upper.obj `if test -f 'cpio/test/test_option_J_upper.c'; then $(CYGPATH_W) 'cpio/test/test_option_J_upper.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_J_upper.c'; fi` - -cpio/test/bsdcpio_test-test_option_L_upper.o: cpio/test/test_option_L_upper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_L_upper.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_L_upper.Tpo -c -o cpio/test/bsdcpio_test-test_option_L_upper.o `test -f 'cpio/test/test_option_L_upper.c' || echo '$(srcdir)/'`cpio/test/test_option_L_upper.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_L_upper.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_L_upper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_L_upper.c' object='cpio/test/bsdcpio_test-test_option_L_upper.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_L_upper.o `test -f 'cpio/test/test_option_L_upper.c' || echo '$(srcdir)/'`cpio/test/test_option_L_upper.c - -cpio/test/bsdcpio_test-test_option_L_upper.obj: cpio/test/test_option_L_upper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_L_upper.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_L_upper.Tpo -c -o cpio/test/bsdcpio_test-test_option_L_upper.obj `if test -f 'cpio/test/test_option_L_upper.c'; then $(CYGPATH_W) 'cpio/test/test_option_L_upper.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_L_upper.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_L_upper.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_L_upper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_L_upper.c' object='cpio/test/bsdcpio_test-test_option_L_upper.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_L_upper.obj `if test -f 'cpio/test/test_option_L_upper.c'; then $(CYGPATH_W) 'cpio/test/test_option_L_upper.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_L_upper.c'; fi` - -cpio/test/bsdcpio_test-test_option_Z_upper.o: cpio/test/test_option_Z_upper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_Z_upper.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_Z_upper.Tpo -c -o cpio/test/bsdcpio_test-test_option_Z_upper.o `test -f 'cpio/test/test_option_Z_upper.c' || echo '$(srcdir)/'`cpio/test/test_option_Z_upper.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_Z_upper.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_Z_upper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_Z_upper.c' object='cpio/test/bsdcpio_test-test_option_Z_upper.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_Z_upper.o `test -f 'cpio/test/test_option_Z_upper.c' || echo '$(srcdir)/'`cpio/test/test_option_Z_upper.c - -cpio/test/bsdcpio_test-test_option_Z_upper.obj: cpio/test/test_option_Z_upper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_Z_upper.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_Z_upper.Tpo -c -o cpio/test/bsdcpio_test-test_option_Z_upper.obj `if test -f 'cpio/test/test_option_Z_upper.c'; then $(CYGPATH_W) 'cpio/test/test_option_Z_upper.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_Z_upper.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_Z_upper.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_Z_upper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_Z_upper.c' object='cpio/test/bsdcpio_test-test_option_Z_upper.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_Z_upper.obj `if test -f 'cpio/test/test_option_Z_upper.c'; then $(CYGPATH_W) 'cpio/test/test_option_Z_upper.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_Z_upper.c'; fi` - -cpio/test/bsdcpio_test-test_option_a.o: cpio/test/test_option_a.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_a.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_a.Tpo -c -o cpio/test/bsdcpio_test-test_option_a.o `test -f 'cpio/test/test_option_a.c' || echo '$(srcdir)/'`cpio/test/test_option_a.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_a.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_a.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_a.c' object='cpio/test/bsdcpio_test-test_option_a.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_a.o `test -f 'cpio/test/test_option_a.c' || echo '$(srcdir)/'`cpio/test/test_option_a.c - -cpio/test/bsdcpio_test-test_option_a.obj: cpio/test/test_option_a.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_a.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_a.Tpo -c -o cpio/test/bsdcpio_test-test_option_a.obj `if test -f 'cpio/test/test_option_a.c'; then $(CYGPATH_W) 'cpio/test/test_option_a.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_a.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_a.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_a.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_a.c' object='cpio/test/bsdcpio_test-test_option_a.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_a.obj `if test -f 'cpio/test/test_option_a.c'; then $(CYGPATH_W) 'cpio/test/test_option_a.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_a.c'; fi` - -cpio/test/bsdcpio_test-test_option_b64encode.o: cpio/test/test_option_b64encode.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_b64encode.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_b64encode.Tpo -c -o cpio/test/bsdcpio_test-test_option_b64encode.o `test -f 'cpio/test/test_option_b64encode.c' || echo '$(srcdir)/'`cpio/test/test_option_b64encode.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_b64encode.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_b64encode.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_b64encode.c' object='cpio/test/bsdcpio_test-test_option_b64encode.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_b64encode.o `test -f 'cpio/test/test_option_b64encode.c' || echo '$(srcdir)/'`cpio/test/test_option_b64encode.c - -cpio/test/bsdcpio_test-test_option_b64encode.obj: cpio/test/test_option_b64encode.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_b64encode.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_b64encode.Tpo -c -o cpio/test/bsdcpio_test-test_option_b64encode.obj `if test -f 'cpio/test/test_option_b64encode.c'; then $(CYGPATH_W) 'cpio/test/test_option_b64encode.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_b64encode.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_b64encode.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_b64encode.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_b64encode.c' object='cpio/test/bsdcpio_test-test_option_b64encode.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_b64encode.obj `if test -f 'cpio/test/test_option_b64encode.c'; then $(CYGPATH_W) 'cpio/test/test_option_b64encode.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_b64encode.c'; fi` - -cpio/test/bsdcpio_test-test_option_c.o: cpio/test/test_option_c.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_c.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_c.Tpo -c -o cpio/test/bsdcpio_test-test_option_c.o `test -f 'cpio/test/test_option_c.c' || echo '$(srcdir)/'`cpio/test/test_option_c.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_c.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_c.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_c.c' object='cpio/test/bsdcpio_test-test_option_c.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_c.o `test -f 'cpio/test/test_option_c.c' || echo '$(srcdir)/'`cpio/test/test_option_c.c - -cpio/test/bsdcpio_test-test_option_c.obj: cpio/test/test_option_c.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_c.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_c.Tpo -c -o cpio/test/bsdcpio_test-test_option_c.obj `if test -f 'cpio/test/test_option_c.c'; then $(CYGPATH_W) 'cpio/test/test_option_c.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_c.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_c.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_c.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_c.c' object='cpio/test/bsdcpio_test-test_option_c.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_c.obj `if test -f 'cpio/test/test_option_c.c'; then $(CYGPATH_W) 'cpio/test/test_option_c.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_c.c'; fi` - -cpio/test/bsdcpio_test-test_option_d.o: cpio/test/test_option_d.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_d.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_d.Tpo -c -o cpio/test/bsdcpio_test-test_option_d.o `test -f 'cpio/test/test_option_d.c' || echo '$(srcdir)/'`cpio/test/test_option_d.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_d.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_d.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_d.c' object='cpio/test/bsdcpio_test-test_option_d.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_d.o `test -f 'cpio/test/test_option_d.c' || echo '$(srcdir)/'`cpio/test/test_option_d.c - -cpio/test/bsdcpio_test-test_option_d.obj: cpio/test/test_option_d.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_d.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_d.Tpo -c -o cpio/test/bsdcpio_test-test_option_d.obj `if test -f 'cpio/test/test_option_d.c'; then $(CYGPATH_W) 'cpio/test/test_option_d.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_d.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_d.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_d.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_d.c' object='cpio/test/bsdcpio_test-test_option_d.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_d.obj `if test -f 'cpio/test/test_option_d.c'; then $(CYGPATH_W) 'cpio/test/test_option_d.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_d.c'; fi` - -cpio/test/bsdcpio_test-test_option_f.o: cpio/test/test_option_f.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_f.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_f.Tpo -c -o cpio/test/bsdcpio_test-test_option_f.o `test -f 'cpio/test/test_option_f.c' || echo '$(srcdir)/'`cpio/test/test_option_f.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_f.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_f.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_f.c' object='cpio/test/bsdcpio_test-test_option_f.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_f.o `test -f 'cpio/test/test_option_f.c' || echo '$(srcdir)/'`cpio/test/test_option_f.c - -cpio/test/bsdcpio_test-test_option_f.obj: cpio/test/test_option_f.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_f.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_f.Tpo -c -o cpio/test/bsdcpio_test-test_option_f.obj `if test -f 'cpio/test/test_option_f.c'; then $(CYGPATH_W) 'cpio/test/test_option_f.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_f.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_f.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_f.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_f.c' object='cpio/test/bsdcpio_test-test_option_f.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_f.obj `if test -f 'cpio/test/test_option_f.c'; then $(CYGPATH_W) 'cpio/test/test_option_f.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_f.c'; fi` - -cpio/test/bsdcpio_test-test_option_grzip.o: cpio/test/test_option_grzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_grzip.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_grzip.Tpo -c -o cpio/test/bsdcpio_test-test_option_grzip.o `test -f 'cpio/test/test_option_grzip.c' || echo '$(srcdir)/'`cpio/test/test_option_grzip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_grzip.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_grzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_grzip.c' object='cpio/test/bsdcpio_test-test_option_grzip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_grzip.o `test -f 'cpio/test/test_option_grzip.c' || echo '$(srcdir)/'`cpio/test/test_option_grzip.c - -cpio/test/bsdcpio_test-test_option_grzip.obj: cpio/test/test_option_grzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_grzip.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_grzip.Tpo -c -o cpio/test/bsdcpio_test-test_option_grzip.obj `if test -f 'cpio/test/test_option_grzip.c'; then $(CYGPATH_W) 'cpio/test/test_option_grzip.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_grzip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_grzip.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_grzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_grzip.c' object='cpio/test/bsdcpio_test-test_option_grzip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_grzip.obj `if test -f 'cpio/test/test_option_grzip.c'; then $(CYGPATH_W) 'cpio/test/test_option_grzip.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_grzip.c'; fi` - -cpio/test/bsdcpio_test-test_option_help.o: cpio/test/test_option_help.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_help.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_help.Tpo -c -o cpio/test/bsdcpio_test-test_option_help.o `test -f 'cpio/test/test_option_help.c' || echo '$(srcdir)/'`cpio/test/test_option_help.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_help.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_help.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_help.c' object='cpio/test/bsdcpio_test-test_option_help.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_help.o `test -f 'cpio/test/test_option_help.c' || echo '$(srcdir)/'`cpio/test/test_option_help.c - -cpio/test/bsdcpio_test-test_option_help.obj: cpio/test/test_option_help.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_help.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_help.Tpo -c -o cpio/test/bsdcpio_test-test_option_help.obj `if test -f 'cpio/test/test_option_help.c'; then $(CYGPATH_W) 'cpio/test/test_option_help.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_help.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_help.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_help.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_help.c' object='cpio/test/bsdcpio_test-test_option_help.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_help.obj `if test -f 'cpio/test/test_option_help.c'; then $(CYGPATH_W) 'cpio/test/test_option_help.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_help.c'; fi` - -cpio/test/bsdcpio_test-test_option_l.o: cpio/test/test_option_l.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_l.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_l.Tpo -c -o cpio/test/bsdcpio_test-test_option_l.o `test -f 'cpio/test/test_option_l.c' || echo '$(srcdir)/'`cpio/test/test_option_l.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_l.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_l.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_l.c' object='cpio/test/bsdcpio_test-test_option_l.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_l.o `test -f 'cpio/test/test_option_l.c' || echo '$(srcdir)/'`cpio/test/test_option_l.c - -cpio/test/bsdcpio_test-test_option_l.obj: cpio/test/test_option_l.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_l.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_l.Tpo -c -o cpio/test/bsdcpio_test-test_option_l.obj `if test -f 'cpio/test/test_option_l.c'; then $(CYGPATH_W) 'cpio/test/test_option_l.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_l.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_l.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_l.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_l.c' object='cpio/test/bsdcpio_test-test_option_l.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_l.obj `if test -f 'cpio/test/test_option_l.c'; then $(CYGPATH_W) 'cpio/test/test_option_l.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_l.c'; fi` - -cpio/test/bsdcpio_test-test_option_lrzip.o: cpio/test/test_option_lrzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_lrzip.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lrzip.Tpo -c -o cpio/test/bsdcpio_test-test_option_lrzip.o `test -f 'cpio/test/test_option_lrzip.c' || echo '$(srcdir)/'`cpio/test/test_option_lrzip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lrzip.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lrzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_lrzip.c' object='cpio/test/bsdcpio_test-test_option_lrzip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_lrzip.o `test -f 'cpio/test/test_option_lrzip.c' || echo '$(srcdir)/'`cpio/test/test_option_lrzip.c - -cpio/test/bsdcpio_test-test_option_lrzip.obj: cpio/test/test_option_lrzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_lrzip.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lrzip.Tpo -c -o cpio/test/bsdcpio_test-test_option_lrzip.obj `if test -f 'cpio/test/test_option_lrzip.c'; then $(CYGPATH_W) 'cpio/test/test_option_lrzip.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_lrzip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lrzip.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lrzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_lrzip.c' object='cpio/test/bsdcpio_test-test_option_lrzip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_lrzip.obj `if test -f 'cpio/test/test_option_lrzip.c'; then $(CYGPATH_W) 'cpio/test/test_option_lrzip.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_lrzip.c'; fi` - -cpio/test/bsdcpio_test-test_option_lz4.o: cpio/test/test_option_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_lz4.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lz4.Tpo -c -o cpio/test/bsdcpio_test-test_option_lz4.o `test -f 'cpio/test/test_option_lz4.c' || echo '$(srcdir)/'`cpio/test/test_option_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lz4.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lz4.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_lz4.c' object='cpio/test/bsdcpio_test-test_option_lz4.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_lz4.o `test -f 'cpio/test/test_option_lz4.c' || echo '$(srcdir)/'`cpio/test/test_option_lz4.c - -cpio/test/bsdcpio_test-test_option_lz4.obj: cpio/test/test_option_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_lz4.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lz4.Tpo -c -o cpio/test/bsdcpio_test-test_option_lz4.obj `if test -f 'cpio/test/test_option_lz4.c'; then $(CYGPATH_W) 'cpio/test/test_option_lz4.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_lz4.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lz4.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lz4.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_lz4.c' object='cpio/test/bsdcpio_test-test_option_lz4.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_lz4.obj `if test -f 'cpio/test/test_option_lz4.c'; then $(CYGPATH_W) 'cpio/test/test_option_lz4.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_lz4.c'; fi` - -cpio/test/bsdcpio_test-test_option_lzma.o: cpio/test/test_option_lzma.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_lzma.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lzma.Tpo -c -o cpio/test/bsdcpio_test-test_option_lzma.o `test -f 'cpio/test/test_option_lzma.c' || echo '$(srcdir)/'`cpio/test/test_option_lzma.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lzma.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lzma.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_lzma.c' object='cpio/test/bsdcpio_test-test_option_lzma.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_lzma.o `test -f 'cpio/test/test_option_lzma.c' || echo '$(srcdir)/'`cpio/test/test_option_lzma.c - -cpio/test/bsdcpio_test-test_option_lzma.obj: cpio/test/test_option_lzma.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_lzma.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lzma.Tpo -c -o cpio/test/bsdcpio_test-test_option_lzma.obj `if test -f 'cpio/test/test_option_lzma.c'; then $(CYGPATH_W) 'cpio/test/test_option_lzma.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_lzma.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lzma.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lzma.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_lzma.c' object='cpio/test/bsdcpio_test-test_option_lzma.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_lzma.obj `if test -f 'cpio/test/test_option_lzma.c'; then $(CYGPATH_W) 'cpio/test/test_option_lzma.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_lzma.c'; fi` - -cpio/test/bsdcpio_test-test_option_lzop.o: cpio/test/test_option_lzop.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_lzop.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lzop.Tpo -c -o cpio/test/bsdcpio_test-test_option_lzop.o `test -f 'cpio/test/test_option_lzop.c' || echo '$(srcdir)/'`cpio/test/test_option_lzop.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lzop.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lzop.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_lzop.c' object='cpio/test/bsdcpio_test-test_option_lzop.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_lzop.o `test -f 'cpio/test/test_option_lzop.c' || echo '$(srcdir)/'`cpio/test/test_option_lzop.c - -cpio/test/bsdcpio_test-test_option_lzop.obj: cpio/test/test_option_lzop.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_lzop.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lzop.Tpo -c -o cpio/test/bsdcpio_test-test_option_lzop.obj `if test -f 'cpio/test/test_option_lzop.c'; then $(CYGPATH_W) 'cpio/test/test_option_lzop.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_lzop.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lzop.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lzop.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_lzop.c' object='cpio/test/bsdcpio_test-test_option_lzop.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_lzop.obj `if test -f 'cpio/test/test_option_lzop.c'; then $(CYGPATH_W) 'cpio/test/test_option_lzop.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_lzop.c'; fi` - -cpio/test/bsdcpio_test-test_option_m.o: cpio/test/test_option_m.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_m.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_m.Tpo -c -o cpio/test/bsdcpio_test-test_option_m.o `test -f 'cpio/test/test_option_m.c' || echo '$(srcdir)/'`cpio/test/test_option_m.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_m.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_m.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_m.c' object='cpio/test/bsdcpio_test-test_option_m.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_m.o `test -f 'cpio/test/test_option_m.c' || echo '$(srcdir)/'`cpio/test/test_option_m.c - -cpio/test/bsdcpio_test-test_option_m.obj: cpio/test/test_option_m.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_m.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_m.Tpo -c -o cpio/test/bsdcpio_test-test_option_m.obj `if test -f 'cpio/test/test_option_m.c'; then $(CYGPATH_W) 'cpio/test/test_option_m.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_m.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_m.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_m.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_m.c' object='cpio/test/bsdcpio_test-test_option_m.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_m.obj `if test -f 'cpio/test/test_option_m.c'; then $(CYGPATH_W) 'cpio/test/test_option_m.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_m.c'; fi` - -cpio/test/bsdcpio_test-test_option_passphrase.o: cpio/test/test_option_passphrase.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_passphrase.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_passphrase.Tpo -c -o cpio/test/bsdcpio_test-test_option_passphrase.o `test -f 'cpio/test/test_option_passphrase.c' || echo '$(srcdir)/'`cpio/test/test_option_passphrase.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_passphrase.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_passphrase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_passphrase.c' object='cpio/test/bsdcpio_test-test_option_passphrase.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_passphrase.o `test -f 'cpio/test/test_option_passphrase.c' || echo '$(srcdir)/'`cpio/test/test_option_passphrase.c - -cpio/test/bsdcpio_test-test_option_passphrase.obj: cpio/test/test_option_passphrase.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_passphrase.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_passphrase.Tpo -c -o cpio/test/bsdcpio_test-test_option_passphrase.obj `if test -f 'cpio/test/test_option_passphrase.c'; then $(CYGPATH_W) 'cpio/test/test_option_passphrase.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_passphrase.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_passphrase.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_passphrase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_passphrase.c' object='cpio/test/bsdcpio_test-test_option_passphrase.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_passphrase.obj `if test -f 'cpio/test/test_option_passphrase.c'; then $(CYGPATH_W) 'cpio/test/test_option_passphrase.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_passphrase.c'; fi` - -cpio/test/bsdcpio_test-test_option_t.o: cpio/test/test_option_t.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_t.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_t.Tpo -c -o cpio/test/bsdcpio_test-test_option_t.o `test -f 'cpio/test/test_option_t.c' || echo '$(srcdir)/'`cpio/test/test_option_t.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_t.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_t.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_t.c' object='cpio/test/bsdcpio_test-test_option_t.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_t.o `test -f 'cpio/test/test_option_t.c' || echo '$(srcdir)/'`cpio/test/test_option_t.c - -cpio/test/bsdcpio_test-test_option_t.obj: cpio/test/test_option_t.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_t.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_t.Tpo -c -o cpio/test/bsdcpio_test-test_option_t.obj `if test -f 'cpio/test/test_option_t.c'; then $(CYGPATH_W) 'cpio/test/test_option_t.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_t.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_t.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_t.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_t.c' object='cpio/test/bsdcpio_test-test_option_t.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_t.obj `if test -f 'cpio/test/test_option_t.c'; then $(CYGPATH_W) 'cpio/test/test_option_t.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_t.c'; fi` - -cpio/test/bsdcpio_test-test_option_u.o: cpio/test/test_option_u.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_u.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_u.Tpo -c -o cpio/test/bsdcpio_test-test_option_u.o `test -f 'cpio/test/test_option_u.c' || echo '$(srcdir)/'`cpio/test/test_option_u.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_u.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_u.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_u.c' object='cpio/test/bsdcpio_test-test_option_u.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_u.o `test -f 'cpio/test/test_option_u.c' || echo '$(srcdir)/'`cpio/test/test_option_u.c - -cpio/test/bsdcpio_test-test_option_u.obj: cpio/test/test_option_u.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_u.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_u.Tpo -c -o cpio/test/bsdcpio_test-test_option_u.obj `if test -f 'cpio/test/test_option_u.c'; then $(CYGPATH_W) 'cpio/test/test_option_u.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_u.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_u.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_u.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_u.c' object='cpio/test/bsdcpio_test-test_option_u.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_u.obj `if test -f 'cpio/test/test_option_u.c'; then $(CYGPATH_W) 'cpio/test/test_option_u.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_u.c'; fi` - -cpio/test/bsdcpio_test-test_option_uuencode.o: cpio/test/test_option_uuencode.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_uuencode.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_uuencode.Tpo -c -o cpio/test/bsdcpio_test-test_option_uuencode.o `test -f 'cpio/test/test_option_uuencode.c' || echo '$(srcdir)/'`cpio/test/test_option_uuencode.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_uuencode.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_uuencode.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_uuencode.c' object='cpio/test/bsdcpio_test-test_option_uuencode.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_uuencode.o `test -f 'cpio/test/test_option_uuencode.c' || echo '$(srcdir)/'`cpio/test/test_option_uuencode.c - -cpio/test/bsdcpio_test-test_option_uuencode.obj: cpio/test/test_option_uuencode.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_uuencode.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_uuencode.Tpo -c -o cpio/test/bsdcpio_test-test_option_uuencode.obj `if test -f 'cpio/test/test_option_uuencode.c'; then $(CYGPATH_W) 'cpio/test/test_option_uuencode.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_uuencode.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_uuencode.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_uuencode.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_uuencode.c' object='cpio/test/bsdcpio_test-test_option_uuencode.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_uuencode.obj `if test -f 'cpio/test/test_option_uuencode.c'; then $(CYGPATH_W) 'cpio/test/test_option_uuencode.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_uuencode.c'; fi` - -cpio/test/bsdcpio_test-test_option_version.o: cpio/test/test_option_version.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_version.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_version.Tpo -c -o cpio/test/bsdcpio_test-test_option_version.o `test -f 'cpio/test/test_option_version.c' || echo '$(srcdir)/'`cpio/test/test_option_version.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_version.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_version.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_version.c' object='cpio/test/bsdcpio_test-test_option_version.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_version.o `test -f 'cpio/test/test_option_version.c' || echo '$(srcdir)/'`cpio/test/test_option_version.c - -cpio/test/bsdcpio_test-test_option_version.obj: cpio/test/test_option_version.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_version.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_version.Tpo -c -o cpio/test/bsdcpio_test-test_option_version.obj `if test -f 'cpio/test/test_option_version.c'; then $(CYGPATH_W) 'cpio/test/test_option_version.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_version.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_version.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_version.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_version.c' object='cpio/test/bsdcpio_test-test_option_version.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_version.obj `if test -f 'cpio/test/test_option_version.c'; then $(CYGPATH_W) 'cpio/test/test_option_version.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_version.c'; fi` - -cpio/test/bsdcpio_test-test_option_xz.o: cpio/test/test_option_xz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_xz.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_xz.Tpo -c -o cpio/test/bsdcpio_test-test_option_xz.o `test -f 'cpio/test/test_option_xz.c' || echo '$(srcdir)/'`cpio/test/test_option_xz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_xz.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_xz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_xz.c' object='cpio/test/bsdcpio_test-test_option_xz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_xz.o `test -f 'cpio/test/test_option_xz.c' || echo '$(srcdir)/'`cpio/test/test_option_xz.c - -cpio/test/bsdcpio_test-test_option_xz.obj: cpio/test/test_option_xz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_xz.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_xz.Tpo -c -o cpio/test/bsdcpio_test-test_option_xz.obj `if test -f 'cpio/test/test_option_xz.c'; then $(CYGPATH_W) 'cpio/test/test_option_xz.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_xz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_xz.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_xz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_xz.c' object='cpio/test/bsdcpio_test-test_option_xz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_xz.obj `if test -f 'cpio/test/test_option_xz.c'; then $(CYGPATH_W) 'cpio/test/test_option_xz.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_xz.c'; fi` - -cpio/test/bsdcpio_test-test_option_y.o: cpio/test/test_option_y.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_y.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_y.Tpo -c -o cpio/test/bsdcpio_test-test_option_y.o `test -f 'cpio/test/test_option_y.c' || echo '$(srcdir)/'`cpio/test/test_option_y.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_y.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_y.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_y.c' object='cpio/test/bsdcpio_test-test_option_y.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_y.o `test -f 'cpio/test/test_option_y.c' || echo '$(srcdir)/'`cpio/test/test_option_y.c - -cpio/test/bsdcpio_test-test_option_y.obj: cpio/test/test_option_y.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_y.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_y.Tpo -c -o cpio/test/bsdcpio_test-test_option_y.obj `if test -f 'cpio/test/test_option_y.c'; then $(CYGPATH_W) 'cpio/test/test_option_y.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_y.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_y.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_y.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_y.c' object='cpio/test/bsdcpio_test-test_option_y.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_y.obj `if test -f 'cpio/test/test_option_y.c'; then $(CYGPATH_W) 'cpio/test/test_option_y.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_y.c'; fi` - -cpio/test/bsdcpio_test-test_option_z.o: cpio/test/test_option_z.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_z.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_z.Tpo -c -o cpio/test/bsdcpio_test-test_option_z.o `test -f 'cpio/test/test_option_z.c' || echo '$(srcdir)/'`cpio/test/test_option_z.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_z.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_z.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_z.c' object='cpio/test/bsdcpio_test-test_option_z.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_z.o `test -f 'cpio/test/test_option_z.c' || echo '$(srcdir)/'`cpio/test/test_option_z.c - -cpio/test/bsdcpio_test-test_option_z.obj: cpio/test/test_option_z.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_z.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_z.Tpo -c -o cpio/test/bsdcpio_test-test_option_z.obj `if test -f 'cpio/test/test_option_z.c'; then $(CYGPATH_W) 'cpio/test/test_option_z.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_z.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_z.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_z.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_z.c' object='cpio/test/bsdcpio_test-test_option_z.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_z.obj `if test -f 'cpio/test/test_option_z.c'; then $(CYGPATH_W) 'cpio/test/test_option_z.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_z.c'; fi` - -cpio/test/bsdcpio_test-test_option_zstd.o: cpio/test/test_option_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_zstd.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_zstd.Tpo -c -o cpio/test/bsdcpio_test-test_option_zstd.o `test -f 'cpio/test/test_option_zstd.c' || echo '$(srcdir)/'`cpio/test/test_option_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_zstd.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_zstd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_zstd.c' object='cpio/test/bsdcpio_test-test_option_zstd.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_zstd.o `test -f 'cpio/test/test_option_zstd.c' || echo '$(srcdir)/'`cpio/test/test_option_zstd.c - -cpio/test/bsdcpio_test-test_option_zstd.obj: cpio/test/test_option_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_option_zstd.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_option_zstd.Tpo -c -o cpio/test/bsdcpio_test-test_option_zstd.obj `if test -f 'cpio/test/test_option_zstd.c'; then $(CYGPATH_W) 'cpio/test/test_option_zstd.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_zstd.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_option_zstd.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_option_zstd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_option_zstd.c' object='cpio/test/bsdcpio_test-test_option_zstd.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_option_zstd.obj `if test -f 'cpio/test/test_option_zstd.c'; then $(CYGPATH_W) 'cpio/test/test_option_zstd.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_option_zstd.c'; fi` - -cpio/test/bsdcpio_test-test_owner_parse.o: cpio/test/test_owner_parse.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_owner_parse.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_owner_parse.Tpo -c -o cpio/test/bsdcpio_test-test_owner_parse.o `test -f 'cpio/test/test_owner_parse.c' || echo '$(srcdir)/'`cpio/test/test_owner_parse.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_owner_parse.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_owner_parse.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_owner_parse.c' object='cpio/test/bsdcpio_test-test_owner_parse.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_owner_parse.o `test -f 'cpio/test/test_owner_parse.c' || echo '$(srcdir)/'`cpio/test/test_owner_parse.c - -cpio/test/bsdcpio_test-test_owner_parse.obj: cpio/test/test_owner_parse.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_owner_parse.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_owner_parse.Tpo -c -o cpio/test/bsdcpio_test-test_owner_parse.obj `if test -f 'cpio/test/test_owner_parse.c'; then $(CYGPATH_W) 'cpio/test/test_owner_parse.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_owner_parse.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_owner_parse.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_owner_parse.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_owner_parse.c' object='cpio/test/bsdcpio_test-test_owner_parse.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_owner_parse.obj `if test -f 'cpio/test/test_owner_parse.c'; then $(CYGPATH_W) 'cpio/test/test_owner_parse.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_owner_parse.c'; fi` - -cpio/test/bsdcpio_test-test_passthrough_dotdot.o: cpio/test/test_passthrough_dotdot.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_passthrough_dotdot.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_passthrough_dotdot.Tpo -c -o cpio/test/bsdcpio_test-test_passthrough_dotdot.o `test -f 'cpio/test/test_passthrough_dotdot.c' || echo '$(srcdir)/'`cpio/test/test_passthrough_dotdot.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_passthrough_dotdot.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_passthrough_dotdot.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_passthrough_dotdot.c' object='cpio/test/bsdcpio_test-test_passthrough_dotdot.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_passthrough_dotdot.o `test -f 'cpio/test/test_passthrough_dotdot.c' || echo '$(srcdir)/'`cpio/test/test_passthrough_dotdot.c - -cpio/test/bsdcpio_test-test_passthrough_dotdot.obj: cpio/test/test_passthrough_dotdot.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_passthrough_dotdot.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_passthrough_dotdot.Tpo -c -o cpio/test/bsdcpio_test-test_passthrough_dotdot.obj `if test -f 'cpio/test/test_passthrough_dotdot.c'; then $(CYGPATH_W) 'cpio/test/test_passthrough_dotdot.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_passthrough_dotdot.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_passthrough_dotdot.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_passthrough_dotdot.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_passthrough_dotdot.c' object='cpio/test/bsdcpio_test-test_passthrough_dotdot.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_passthrough_dotdot.obj `if test -f 'cpio/test/test_passthrough_dotdot.c'; then $(CYGPATH_W) 'cpio/test/test_passthrough_dotdot.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_passthrough_dotdot.c'; fi` - -cpio/test/bsdcpio_test-test_passthrough_reverse.o: cpio/test/test_passthrough_reverse.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_passthrough_reverse.o -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_passthrough_reverse.Tpo -c -o cpio/test/bsdcpio_test-test_passthrough_reverse.o `test -f 'cpio/test/test_passthrough_reverse.c' || echo '$(srcdir)/'`cpio/test/test_passthrough_reverse.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_passthrough_reverse.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_passthrough_reverse.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_passthrough_reverse.c' object='cpio/test/bsdcpio_test-test_passthrough_reverse.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_passthrough_reverse.o `test -f 'cpio/test/test_passthrough_reverse.c' || echo '$(srcdir)/'`cpio/test/test_passthrough_reverse.c - -cpio/test/bsdcpio_test-test_passthrough_reverse.obj: cpio/test/test_passthrough_reverse.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cpio/test/bsdcpio_test-test_passthrough_reverse.obj -MD -MP -MF cpio/test/$(DEPDIR)/bsdcpio_test-test_passthrough_reverse.Tpo -c -o cpio/test/bsdcpio_test-test_passthrough_reverse.obj `if test -f 'cpio/test/test_passthrough_reverse.c'; then $(CYGPATH_W) 'cpio/test/test_passthrough_reverse.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_passthrough_reverse.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cpio/test/$(DEPDIR)/bsdcpio_test-test_passthrough_reverse.Tpo cpio/test/$(DEPDIR)/bsdcpio_test-test_passthrough_reverse.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cpio/test/test_passthrough_reverse.c' object='cpio/test/bsdcpio_test-test_passthrough_reverse.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdcpio_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cpio/test/bsdcpio_test-test_passthrough_reverse.obj `if test -f 'cpio/test/test_passthrough_reverse.c'; then $(CYGPATH_W) 'cpio/test/test_passthrough_reverse.c'; else $(CYGPATH_W) '$(srcdir)/cpio/test/test_passthrough_reverse.c'; fi` - -tar/bsdtar-bsdtar.o: tar/bsdtar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/bsdtar-bsdtar.o -MD -MP -MF tar/$(DEPDIR)/bsdtar-bsdtar.Tpo -c -o tar/bsdtar-bsdtar.o `test -f 'tar/bsdtar.c' || echo '$(srcdir)/'`tar/bsdtar.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/$(DEPDIR)/bsdtar-bsdtar.Tpo tar/$(DEPDIR)/bsdtar-bsdtar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/bsdtar.c' object='tar/bsdtar-bsdtar.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/bsdtar-bsdtar.o `test -f 'tar/bsdtar.c' || echo '$(srcdir)/'`tar/bsdtar.c - -tar/bsdtar-bsdtar.obj: tar/bsdtar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/bsdtar-bsdtar.obj -MD -MP -MF tar/$(DEPDIR)/bsdtar-bsdtar.Tpo -c -o tar/bsdtar-bsdtar.obj `if test -f 'tar/bsdtar.c'; then $(CYGPATH_W) 'tar/bsdtar.c'; else $(CYGPATH_W) '$(srcdir)/tar/bsdtar.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/$(DEPDIR)/bsdtar-bsdtar.Tpo tar/$(DEPDIR)/bsdtar-bsdtar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/bsdtar.c' object='tar/bsdtar-bsdtar.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/bsdtar-bsdtar.obj `if test -f 'tar/bsdtar.c'; then $(CYGPATH_W) 'tar/bsdtar.c'; else $(CYGPATH_W) '$(srcdir)/tar/bsdtar.c'; fi` - -tar/bsdtar-cmdline.o: tar/cmdline.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/bsdtar-cmdline.o -MD -MP -MF tar/$(DEPDIR)/bsdtar-cmdline.Tpo -c -o tar/bsdtar-cmdline.o `test -f 'tar/cmdline.c' || echo '$(srcdir)/'`tar/cmdline.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/$(DEPDIR)/bsdtar-cmdline.Tpo tar/$(DEPDIR)/bsdtar-cmdline.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/cmdline.c' object='tar/bsdtar-cmdline.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/bsdtar-cmdline.o `test -f 'tar/cmdline.c' || echo '$(srcdir)/'`tar/cmdline.c - -tar/bsdtar-cmdline.obj: tar/cmdline.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/bsdtar-cmdline.obj -MD -MP -MF tar/$(DEPDIR)/bsdtar-cmdline.Tpo -c -o tar/bsdtar-cmdline.obj `if test -f 'tar/cmdline.c'; then $(CYGPATH_W) 'tar/cmdline.c'; else $(CYGPATH_W) '$(srcdir)/tar/cmdline.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/$(DEPDIR)/bsdtar-cmdline.Tpo tar/$(DEPDIR)/bsdtar-cmdline.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/cmdline.c' object='tar/bsdtar-cmdline.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/bsdtar-cmdline.obj `if test -f 'tar/cmdline.c'; then $(CYGPATH_W) 'tar/cmdline.c'; else $(CYGPATH_W) '$(srcdir)/tar/cmdline.c'; fi` - -tar/bsdtar-creation_set.o: tar/creation_set.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/bsdtar-creation_set.o -MD -MP -MF tar/$(DEPDIR)/bsdtar-creation_set.Tpo -c -o tar/bsdtar-creation_set.o `test -f 'tar/creation_set.c' || echo '$(srcdir)/'`tar/creation_set.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/$(DEPDIR)/bsdtar-creation_set.Tpo tar/$(DEPDIR)/bsdtar-creation_set.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/creation_set.c' object='tar/bsdtar-creation_set.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/bsdtar-creation_set.o `test -f 'tar/creation_set.c' || echo '$(srcdir)/'`tar/creation_set.c - -tar/bsdtar-creation_set.obj: tar/creation_set.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/bsdtar-creation_set.obj -MD -MP -MF tar/$(DEPDIR)/bsdtar-creation_set.Tpo -c -o tar/bsdtar-creation_set.obj `if test -f 'tar/creation_set.c'; then $(CYGPATH_W) 'tar/creation_set.c'; else $(CYGPATH_W) '$(srcdir)/tar/creation_set.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/$(DEPDIR)/bsdtar-creation_set.Tpo tar/$(DEPDIR)/bsdtar-creation_set.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/creation_set.c' object='tar/bsdtar-creation_set.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/bsdtar-creation_set.obj `if test -f 'tar/creation_set.c'; then $(CYGPATH_W) 'tar/creation_set.c'; else $(CYGPATH_W) '$(srcdir)/tar/creation_set.c'; fi` - -tar/bsdtar-read.o: tar/read.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/bsdtar-read.o -MD -MP -MF tar/$(DEPDIR)/bsdtar-read.Tpo -c -o tar/bsdtar-read.o `test -f 'tar/read.c' || echo '$(srcdir)/'`tar/read.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/$(DEPDIR)/bsdtar-read.Tpo tar/$(DEPDIR)/bsdtar-read.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/read.c' object='tar/bsdtar-read.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/bsdtar-read.o `test -f 'tar/read.c' || echo '$(srcdir)/'`tar/read.c - -tar/bsdtar-read.obj: tar/read.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/bsdtar-read.obj -MD -MP -MF tar/$(DEPDIR)/bsdtar-read.Tpo -c -o tar/bsdtar-read.obj `if test -f 'tar/read.c'; then $(CYGPATH_W) 'tar/read.c'; else $(CYGPATH_W) '$(srcdir)/tar/read.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/$(DEPDIR)/bsdtar-read.Tpo tar/$(DEPDIR)/bsdtar-read.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/read.c' object='tar/bsdtar-read.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/bsdtar-read.obj `if test -f 'tar/read.c'; then $(CYGPATH_W) 'tar/read.c'; else $(CYGPATH_W) '$(srcdir)/tar/read.c'; fi` - -tar/bsdtar-subst.o: tar/subst.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/bsdtar-subst.o -MD -MP -MF tar/$(DEPDIR)/bsdtar-subst.Tpo -c -o tar/bsdtar-subst.o `test -f 'tar/subst.c' || echo '$(srcdir)/'`tar/subst.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/$(DEPDIR)/bsdtar-subst.Tpo tar/$(DEPDIR)/bsdtar-subst.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/subst.c' object='tar/bsdtar-subst.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/bsdtar-subst.o `test -f 'tar/subst.c' || echo '$(srcdir)/'`tar/subst.c - -tar/bsdtar-subst.obj: tar/subst.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/bsdtar-subst.obj -MD -MP -MF tar/$(DEPDIR)/bsdtar-subst.Tpo -c -o tar/bsdtar-subst.obj `if test -f 'tar/subst.c'; then $(CYGPATH_W) 'tar/subst.c'; else $(CYGPATH_W) '$(srcdir)/tar/subst.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/$(DEPDIR)/bsdtar-subst.Tpo tar/$(DEPDIR)/bsdtar-subst.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/subst.c' object='tar/bsdtar-subst.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/bsdtar-subst.obj `if test -f 'tar/subst.c'; then $(CYGPATH_W) 'tar/subst.c'; else $(CYGPATH_W) '$(srcdir)/tar/subst.c'; fi` - -tar/bsdtar-util.o: tar/util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/bsdtar-util.o -MD -MP -MF tar/$(DEPDIR)/bsdtar-util.Tpo -c -o tar/bsdtar-util.o `test -f 'tar/util.c' || echo '$(srcdir)/'`tar/util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/$(DEPDIR)/bsdtar-util.Tpo tar/$(DEPDIR)/bsdtar-util.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/util.c' object='tar/bsdtar-util.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/bsdtar-util.o `test -f 'tar/util.c' || echo '$(srcdir)/'`tar/util.c - -tar/bsdtar-util.obj: tar/util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/bsdtar-util.obj -MD -MP -MF tar/$(DEPDIR)/bsdtar-util.Tpo -c -o tar/bsdtar-util.obj `if test -f 'tar/util.c'; then $(CYGPATH_W) 'tar/util.c'; else $(CYGPATH_W) '$(srcdir)/tar/util.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/$(DEPDIR)/bsdtar-util.Tpo tar/$(DEPDIR)/bsdtar-util.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/util.c' object='tar/bsdtar-util.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/bsdtar-util.obj `if test -f 'tar/util.c'; then $(CYGPATH_W) 'tar/util.c'; else $(CYGPATH_W) '$(srcdir)/tar/util.c'; fi` - -tar/bsdtar-write.o: tar/write.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/bsdtar-write.o -MD -MP -MF tar/$(DEPDIR)/bsdtar-write.Tpo -c -o tar/bsdtar-write.o `test -f 'tar/write.c' || echo '$(srcdir)/'`tar/write.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/$(DEPDIR)/bsdtar-write.Tpo tar/$(DEPDIR)/bsdtar-write.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/write.c' object='tar/bsdtar-write.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/bsdtar-write.o `test -f 'tar/write.c' || echo '$(srcdir)/'`tar/write.c - -tar/bsdtar-write.obj: tar/write.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/bsdtar-write.obj -MD -MP -MF tar/$(DEPDIR)/bsdtar-write.Tpo -c -o tar/bsdtar-write.obj `if test -f 'tar/write.c'; then $(CYGPATH_W) 'tar/write.c'; else $(CYGPATH_W) '$(srcdir)/tar/write.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/$(DEPDIR)/bsdtar-write.Tpo tar/$(DEPDIR)/bsdtar-write.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/write.c' object='tar/bsdtar-write.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/bsdtar-write.obj `if test -f 'tar/write.c'; then $(CYGPATH_W) 'tar/write.c'; else $(CYGPATH_W) '$(srcdir)/tar/write.c'; fi` - -tar/bsdtar-bsdtar_windows.o: tar/bsdtar_windows.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/bsdtar-bsdtar_windows.o -MD -MP -MF tar/$(DEPDIR)/bsdtar-bsdtar_windows.Tpo -c -o tar/bsdtar-bsdtar_windows.o `test -f 'tar/bsdtar_windows.c' || echo '$(srcdir)/'`tar/bsdtar_windows.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/$(DEPDIR)/bsdtar-bsdtar_windows.Tpo tar/$(DEPDIR)/bsdtar-bsdtar_windows.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/bsdtar_windows.c' object='tar/bsdtar-bsdtar_windows.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/bsdtar-bsdtar_windows.o `test -f 'tar/bsdtar_windows.c' || echo '$(srcdir)/'`tar/bsdtar_windows.c - -tar/bsdtar-bsdtar_windows.obj: tar/bsdtar_windows.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/bsdtar-bsdtar_windows.obj -MD -MP -MF tar/$(DEPDIR)/bsdtar-bsdtar_windows.Tpo -c -o tar/bsdtar-bsdtar_windows.obj `if test -f 'tar/bsdtar_windows.c'; then $(CYGPATH_W) 'tar/bsdtar_windows.c'; else $(CYGPATH_W) '$(srcdir)/tar/bsdtar_windows.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/$(DEPDIR)/bsdtar-bsdtar_windows.Tpo tar/$(DEPDIR)/bsdtar-bsdtar_windows.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/bsdtar_windows.c' object='tar/bsdtar-bsdtar_windows.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/bsdtar-bsdtar_windows.obj `if test -f 'tar/bsdtar_windows.c'; then $(CYGPATH_W) 'tar/bsdtar_windows.c'; else $(CYGPATH_W) '$(srcdir)/tar/bsdtar_windows.c'; fi` - -test_utils/bsdtar_test-test_utils.o: test_utils/test_utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_utils/bsdtar_test-test_utils.o -MD -MP -MF test_utils/$(DEPDIR)/bsdtar_test-test_utils.Tpo -c -o test_utils/bsdtar_test-test_utils.o `test -f 'test_utils/test_utils.c' || echo '$(srcdir)/'`test_utils/test_utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test_utils/$(DEPDIR)/bsdtar_test-test_utils.Tpo test_utils/$(DEPDIR)/bsdtar_test-test_utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_utils/test_utils.c' object='test_utils/bsdtar_test-test_utils.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_utils/bsdtar_test-test_utils.o `test -f 'test_utils/test_utils.c' || echo '$(srcdir)/'`test_utils/test_utils.c - -test_utils/bsdtar_test-test_utils.obj: test_utils/test_utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_utils/bsdtar_test-test_utils.obj -MD -MP -MF test_utils/$(DEPDIR)/bsdtar_test-test_utils.Tpo -c -o test_utils/bsdtar_test-test_utils.obj `if test -f 'test_utils/test_utils.c'; then $(CYGPATH_W) 'test_utils/test_utils.c'; else $(CYGPATH_W) '$(srcdir)/test_utils/test_utils.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test_utils/$(DEPDIR)/bsdtar_test-test_utils.Tpo test_utils/$(DEPDIR)/bsdtar_test-test_utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_utils/test_utils.c' object='test_utils/bsdtar_test-test_utils.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_utils/bsdtar_test-test_utils.obj `if test -f 'test_utils/test_utils.c'; then $(CYGPATH_W) 'test_utils/test_utils.c'; else $(CYGPATH_W) '$(srcdir)/test_utils/test_utils.c'; fi` - -test_utils/bsdtar_test-test_main.o: test_utils/test_main.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_utils/bsdtar_test-test_main.o -MD -MP -MF test_utils/$(DEPDIR)/bsdtar_test-test_main.Tpo -c -o test_utils/bsdtar_test-test_main.o `test -f 'test_utils/test_main.c' || echo '$(srcdir)/'`test_utils/test_main.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test_utils/$(DEPDIR)/bsdtar_test-test_main.Tpo test_utils/$(DEPDIR)/bsdtar_test-test_main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_utils/test_main.c' object='test_utils/bsdtar_test-test_main.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_utils/bsdtar_test-test_main.o `test -f 'test_utils/test_main.c' || echo '$(srcdir)/'`test_utils/test_main.c - -test_utils/bsdtar_test-test_main.obj: test_utils/test_main.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_utils/bsdtar_test-test_main.obj -MD -MP -MF test_utils/$(DEPDIR)/bsdtar_test-test_main.Tpo -c -o test_utils/bsdtar_test-test_main.obj `if test -f 'test_utils/test_main.c'; then $(CYGPATH_W) 'test_utils/test_main.c'; else $(CYGPATH_W) '$(srcdir)/test_utils/test_main.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test_utils/$(DEPDIR)/bsdtar_test-test_main.Tpo test_utils/$(DEPDIR)/bsdtar_test-test_main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_utils/test_main.c' object='test_utils/bsdtar_test-test_main.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_utils/bsdtar_test-test_main.obj `if test -f 'test_utils/test_main.c'; then $(CYGPATH_W) 'test_utils/test_main.c'; else $(CYGPATH_W) '$(srcdir)/test_utils/test_main.c'; fi` - -tar/test/bsdtar_test-test_0.o: tar/test/test_0.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_0.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_0.Tpo -c -o tar/test/bsdtar_test-test_0.o `test -f 'tar/test/test_0.c' || echo '$(srcdir)/'`tar/test/test_0.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_0.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_0.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_0.c' object='tar/test/bsdtar_test-test_0.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_0.o `test -f 'tar/test/test_0.c' || echo '$(srcdir)/'`tar/test/test_0.c - -tar/test/bsdtar_test-test_0.obj: tar/test/test_0.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_0.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_0.Tpo -c -o tar/test/bsdtar_test-test_0.obj `if test -f 'tar/test/test_0.c'; then $(CYGPATH_W) 'tar/test/test_0.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_0.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_0.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_0.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_0.c' object='tar/test/bsdtar_test-test_0.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_0.obj `if test -f 'tar/test/test_0.c'; then $(CYGPATH_W) 'tar/test/test_0.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_0.c'; fi` - -tar/test/bsdtar_test-test_basic.o: tar/test/test_basic.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_basic.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_basic.Tpo -c -o tar/test/bsdtar_test-test_basic.o `test -f 'tar/test/test_basic.c' || echo '$(srcdir)/'`tar/test/test_basic.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_basic.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_basic.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_basic.c' object='tar/test/bsdtar_test-test_basic.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_basic.o `test -f 'tar/test/test_basic.c' || echo '$(srcdir)/'`tar/test/test_basic.c - -tar/test/bsdtar_test-test_basic.obj: tar/test/test_basic.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_basic.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_basic.Tpo -c -o tar/test/bsdtar_test-test_basic.obj `if test -f 'tar/test/test_basic.c'; then $(CYGPATH_W) 'tar/test/test_basic.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_basic.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_basic.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_basic.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_basic.c' object='tar/test/bsdtar_test-test_basic.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_basic.obj `if test -f 'tar/test/test_basic.c'; then $(CYGPATH_W) 'tar/test/test_basic.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_basic.c'; fi` - -tar/test/bsdtar_test-test_copy.o: tar/test/test_copy.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_copy.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_copy.Tpo -c -o tar/test/bsdtar_test-test_copy.o `test -f 'tar/test/test_copy.c' || echo '$(srcdir)/'`tar/test/test_copy.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_copy.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_copy.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_copy.c' object='tar/test/bsdtar_test-test_copy.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_copy.o `test -f 'tar/test/test_copy.c' || echo '$(srcdir)/'`tar/test/test_copy.c - -tar/test/bsdtar_test-test_copy.obj: tar/test/test_copy.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_copy.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_copy.Tpo -c -o tar/test/bsdtar_test-test_copy.obj `if test -f 'tar/test/test_copy.c'; then $(CYGPATH_W) 'tar/test/test_copy.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_copy.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_copy.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_copy.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_copy.c' object='tar/test/bsdtar_test-test_copy.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_copy.obj `if test -f 'tar/test/test_copy.c'; then $(CYGPATH_W) 'tar/test/test_copy.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_copy.c'; fi` - -tar/test/bsdtar_test-test_empty_mtree.o: tar/test/test_empty_mtree.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_empty_mtree.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_empty_mtree.Tpo -c -o tar/test/bsdtar_test-test_empty_mtree.o `test -f 'tar/test/test_empty_mtree.c' || echo '$(srcdir)/'`tar/test/test_empty_mtree.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_empty_mtree.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_empty_mtree.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_empty_mtree.c' object='tar/test/bsdtar_test-test_empty_mtree.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_empty_mtree.o `test -f 'tar/test/test_empty_mtree.c' || echo '$(srcdir)/'`tar/test/test_empty_mtree.c - -tar/test/bsdtar_test-test_empty_mtree.obj: tar/test/test_empty_mtree.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_empty_mtree.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_empty_mtree.Tpo -c -o tar/test/bsdtar_test-test_empty_mtree.obj `if test -f 'tar/test/test_empty_mtree.c'; then $(CYGPATH_W) 'tar/test/test_empty_mtree.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_empty_mtree.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_empty_mtree.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_empty_mtree.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_empty_mtree.c' object='tar/test/bsdtar_test-test_empty_mtree.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_empty_mtree.obj `if test -f 'tar/test/test_empty_mtree.c'; then $(CYGPATH_W) 'tar/test/test_empty_mtree.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_empty_mtree.c'; fi` - -tar/test/bsdtar_test-test_extract_tar_Z.o: tar/test/test_extract_tar_Z.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_extract_tar_Z.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_Z.Tpo -c -o tar/test/bsdtar_test-test_extract_tar_Z.o `test -f 'tar/test/test_extract_tar_Z.c' || echo '$(srcdir)/'`tar/test/test_extract_tar_Z.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_Z.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_Z.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_extract_tar_Z.c' object='tar/test/bsdtar_test-test_extract_tar_Z.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_extract_tar_Z.o `test -f 'tar/test/test_extract_tar_Z.c' || echo '$(srcdir)/'`tar/test/test_extract_tar_Z.c - -tar/test/bsdtar_test-test_extract_tar_Z.obj: tar/test/test_extract_tar_Z.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_extract_tar_Z.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_Z.Tpo -c -o tar/test/bsdtar_test-test_extract_tar_Z.obj `if test -f 'tar/test/test_extract_tar_Z.c'; then $(CYGPATH_W) 'tar/test/test_extract_tar_Z.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_extract_tar_Z.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_Z.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_Z.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_extract_tar_Z.c' object='tar/test/bsdtar_test-test_extract_tar_Z.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_extract_tar_Z.obj `if test -f 'tar/test/test_extract_tar_Z.c'; then $(CYGPATH_W) 'tar/test/test_extract_tar_Z.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_extract_tar_Z.c'; fi` - -tar/test/bsdtar_test-test_extract_tar_bz2.o: tar/test/test_extract_tar_bz2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_extract_tar_bz2.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_bz2.Tpo -c -o tar/test/bsdtar_test-test_extract_tar_bz2.o `test -f 'tar/test/test_extract_tar_bz2.c' || echo '$(srcdir)/'`tar/test/test_extract_tar_bz2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_bz2.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_bz2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_extract_tar_bz2.c' object='tar/test/bsdtar_test-test_extract_tar_bz2.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_extract_tar_bz2.o `test -f 'tar/test/test_extract_tar_bz2.c' || echo '$(srcdir)/'`tar/test/test_extract_tar_bz2.c - -tar/test/bsdtar_test-test_extract_tar_bz2.obj: tar/test/test_extract_tar_bz2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_extract_tar_bz2.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_bz2.Tpo -c -o tar/test/bsdtar_test-test_extract_tar_bz2.obj `if test -f 'tar/test/test_extract_tar_bz2.c'; then $(CYGPATH_W) 'tar/test/test_extract_tar_bz2.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_extract_tar_bz2.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_bz2.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_bz2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_extract_tar_bz2.c' object='tar/test/bsdtar_test-test_extract_tar_bz2.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_extract_tar_bz2.obj `if test -f 'tar/test/test_extract_tar_bz2.c'; then $(CYGPATH_W) 'tar/test/test_extract_tar_bz2.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_extract_tar_bz2.c'; fi` - -tar/test/bsdtar_test-test_extract_tar_grz.o: tar/test/test_extract_tar_grz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_extract_tar_grz.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_grz.Tpo -c -o tar/test/bsdtar_test-test_extract_tar_grz.o `test -f 'tar/test/test_extract_tar_grz.c' || echo '$(srcdir)/'`tar/test/test_extract_tar_grz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_grz.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_grz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_extract_tar_grz.c' object='tar/test/bsdtar_test-test_extract_tar_grz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_extract_tar_grz.o `test -f 'tar/test/test_extract_tar_grz.c' || echo '$(srcdir)/'`tar/test/test_extract_tar_grz.c - -tar/test/bsdtar_test-test_extract_tar_grz.obj: tar/test/test_extract_tar_grz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_extract_tar_grz.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_grz.Tpo -c -o tar/test/bsdtar_test-test_extract_tar_grz.obj `if test -f 'tar/test/test_extract_tar_grz.c'; then $(CYGPATH_W) 'tar/test/test_extract_tar_grz.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_extract_tar_grz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_grz.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_grz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_extract_tar_grz.c' object='tar/test/bsdtar_test-test_extract_tar_grz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_extract_tar_grz.obj `if test -f 'tar/test/test_extract_tar_grz.c'; then $(CYGPATH_W) 'tar/test/test_extract_tar_grz.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_extract_tar_grz.c'; fi` - -tar/test/bsdtar_test-test_extract_tar_gz.o: tar/test/test_extract_tar_gz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_extract_tar_gz.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_gz.Tpo -c -o tar/test/bsdtar_test-test_extract_tar_gz.o `test -f 'tar/test/test_extract_tar_gz.c' || echo '$(srcdir)/'`tar/test/test_extract_tar_gz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_gz.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_gz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_extract_tar_gz.c' object='tar/test/bsdtar_test-test_extract_tar_gz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_extract_tar_gz.o `test -f 'tar/test/test_extract_tar_gz.c' || echo '$(srcdir)/'`tar/test/test_extract_tar_gz.c - -tar/test/bsdtar_test-test_extract_tar_gz.obj: tar/test/test_extract_tar_gz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_extract_tar_gz.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_gz.Tpo -c -o tar/test/bsdtar_test-test_extract_tar_gz.obj `if test -f 'tar/test/test_extract_tar_gz.c'; then $(CYGPATH_W) 'tar/test/test_extract_tar_gz.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_extract_tar_gz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_gz.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_gz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_extract_tar_gz.c' object='tar/test/bsdtar_test-test_extract_tar_gz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_extract_tar_gz.obj `if test -f 'tar/test/test_extract_tar_gz.c'; then $(CYGPATH_W) 'tar/test/test_extract_tar_gz.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_extract_tar_gz.c'; fi` - -tar/test/bsdtar_test-test_extract_tar_lrz.o: tar/test/test_extract_tar_lrz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_extract_tar_lrz.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lrz.Tpo -c -o tar/test/bsdtar_test-test_extract_tar_lrz.o `test -f 'tar/test/test_extract_tar_lrz.c' || echo '$(srcdir)/'`tar/test/test_extract_tar_lrz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lrz.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lrz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_extract_tar_lrz.c' object='tar/test/bsdtar_test-test_extract_tar_lrz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_extract_tar_lrz.o `test -f 'tar/test/test_extract_tar_lrz.c' || echo '$(srcdir)/'`tar/test/test_extract_tar_lrz.c - -tar/test/bsdtar_test-test_extract_tar_lrz.obj: tar/test/test_extract_tar_lrz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_extract_tar_lrz.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lrz.Tpo -c -o tar/test/bsdtar_test-test_extract_tar_lrz.obj `if test -f 'tar/test/test_extract_tar_lrz.c'; then $(CYGPATH_W) 'tar/test/test_extract_tar_lrz.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_extract_tar_lrz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lrz.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lrz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_extract_tar_lrz.c' object='tar/test/bsdtar_test-test_extract_tar_lrz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_extract_tar_lrz.obj `if test -f 'tar/test/test_extract_tar_lrz.c'; then $(CYGPATH_W) 'tar/test/test_extract_tar_lrz.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_extract_tar_lrz.c'; fi` - -tar/test/bsdtar_test-test_extract_tar_lz.o: tar/test/test_extract_tar_lz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_extract_tar_lz.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lz.Tpo -c -o tar/test/bsdtar_test-test_extract_tar_lz.o `test -f 'tar/test/test_extract_tar_lz.c' || echo '$(srcdir)/'`tar/test/test_extract_tar_lz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lz.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_extract_tar_lz.c' object='tar/test/bsdtar_test-test_extract_tar_lz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_extract_tar_lz.o `test -f 'tar/test/test_extract_tar_lz.c' || echo '$(srcdir)/'`tar/test/test_extract_tar_lz.c - -tar/test/bsdtar_test-test_extract_tar_lz.obj: tar/test/test_extract_tar_lz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_extract_tar_lz.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lz.Tpo -c -o tar/test/bsdtar_test-test_extract_tar_lz.obj `if test -f 'tar/test/test_extract_tar_lz.c'; then $(CYGPATH_W) 'tar/test/test_extract_tar_lz.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_extract_tar_lz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lz.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_extract_tar_lz.c' object='tar/test/bsdtar_test-test_extract_tar_lz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_extract_tar_lz.obj `if test -f 'tar/test/test_extract_tar_lz.c'; then $(CYGPATH_W) 'tar/test/test_extract_tar_lz.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_extract_tar_lz.c'; fi` - -tar/test/bsdtar_test-test_extract_tar_lz4.o: tar/test/test_extract_tar_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_extract_tar_lz4.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lz4.Tpo -c -o tar/test/bsdtar_test-test_extract_tar_lz4.o `test -f 'tar/test/test_extract_tar_lz4.c' || echo '$(srcdir)/'`tar/test/test_extract_tar_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lz4.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lz4.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_extract_tar_lz4.c' object='tar/test/bsdtar_test-test_extract_tar_lz4.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_extract_tar_lz4.o `test -f 'tar/test/test_extract_tar_lz4.c' || echo '$(srcdir)/'`tar/test/test_extract_tar_lz4.c - -tar/test/bsdtar_test-test_extract_tar_lz4.obj: tar/test/test_extract_tar_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_extract_tar_lz4.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lz4.Tpo -c -o tar/test/bsdtar_test-test_extract_tar_lz4.obj `if test -f 'tar/test/test_extract_tar_lz4.c'; then $(CYGPATH_W) 'tar/test/test_extract_tar_lz4.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_extract_tar_lz4.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lz4.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lz4.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_extract_tar_lz4.c' object='tar/test/bsdtar_test-test_extract_tar_lz4.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_extract_tar_lz4.obj `if test -f 'tar/test/test_extract_tar_lz4.c'; then $(CYGPATH_W) 'tar/test/test_extract_tar_lz4.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_extract_tar_lz4.c'; fi` - -tar/test/bsdtar_test-test_extract_tar_lzma.o: tar/test/test_extract_tar_lzma.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_extract_tar_lzma.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lzma.Tpo -c -o tar/test/bsdtar_test-test_extract_tar_lzma.o `test -f 'tar/test/test_extract_tar_lzma.c' || echo '$(srcdir)/'`tar/test/test_extract_tar_lzma.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lzma.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lzma.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_extract_tar_lzma.c' object='tar/test/bsdtar_test-test_extract_tar_lzma.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_extract_tar_lzma.o `test -f 'tar/test/test_extract_tar_lzma.c' || echo '$(srcdir)/'`tar/test/test_extract_tar_lzma.c - -tar/test/bsdtar_test-test_extract_tar_lzma.obj: tar/test/test_extract_tar_lzma.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_extract_tar_lzma.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lzma.Tpo -c -o tar/test/bsdtar_test-test_extract_tar_lzma.obj `if test -f 'tar/test/test_extract_tar_lzma.c'; then $(CYGPATH_W) 'tar/test/test_extract_tar_lzma.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_extract_tar_lzma.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lzma.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lzma.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_extract_tar_lzma.c' object='tar/test/bsdtar_test-test_extract_tar_lzma.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_extract_tar_lzma.obj `if test -f 'tar/test/test_extract_tar_lzma.c'; then $(CYGPATH_W) 'tar/test/test_extract_tar_lzma.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_extract_tar_lzma.c'; fi` - -tar/test/bsdtar_test-test_extract_tar_lzo.o: tar/test/test_extract_tar_lzo.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_extract_tar_lzo.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lzo.Tpo -c -o tar/test/bsdtar_test-test_extract_tar_lzo.o `test -f 'tar/test/test_extract_tar_lzo.c' || echo '$(srcdir)/'`tar/test/test_extract_tar_lzo.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lzo.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lzo.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_extract_tar_lzo.c' object='tar/test/bsdtar_test-test_extract_tar_lzo.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_extract_tar_lzo.o `test -f 'tar/test/test_extract_tar_lzo.c' || echo '$(srcdir)/'`tar/test/test_extract_tar_lzo.c - -tar/test/bsdtar_test-test_extract_tar_lzo.obj: tar/test/test_extract_tar_lzo.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_extract_tar_lzo.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lzo.Tpo -c -o tar/test/bsdtar_test-test_extract_tar_lzo.obj `if test -f 'tar/test/test_extract_tar_lzo.c'; then $(CYGPATH_W) 'tar/test/test_extract_tar_lzo.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_extract_tar_lzo.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lzo.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lzo.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_extract_tar_lzo.c' object='tar/test/bsdtar_test-test_extract_tar_lzo.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_extract_tar_lzo.obj `if test -f 'tar/test/test_extract_tar_lzo.c'; then $(CYGPATH_W) 'tar/test/test_extract_tar_lzo.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_extract_tar_lzo.c'; fi` - -tar/test/bsdtar_test-test_extract_tar_xz.o: tar/test/test_extract_tar_xz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_extract_tar_xz.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_xz.Tpo -c -o tar/test/bsdtar_test-test_extract_tar_xz.o `test -f 'tar/test/test_extract_tar_xz.c' || echo '$(srcdir)/'`tar/test/test_extract_tar_xz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_xz.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_xz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_extract_tar_xz.c' object='tar/test/bsdtar_test-test_extract_tar_xz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_extract_tar_xz.o `test -f 'tar/test/test_extract_tar_xz.c' || echo '$(srcdir)/'`tar/test/test_extract_tar_xz.c - -tar/test/bsdtar_test-test_extract_tar_xz.obj: tar/test/test_extract_tar_xz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_extract_tar_xz.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_xz.Tpo -c -o tar/test/bsdtar_test-test_extract_tar_xz.obj `if test -f 'tar/test/test_extract_tar_xz.c'; then $(CYGPATH_W) 'tar/test/test_extract_tar_xz.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_extract_tar_xz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_xz.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_xz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_extract_tar_xz.c' object='tar/test/bsdtar_test-test_extract_tar_xz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_extract_tar_xz.obj `if test -f 'tar/test/test_extract_tar_xz.c'; then $(CYGPATH_W) 'tar/test/test_extract_tar_xz.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_extract_tar_xz.c'; fi` - -tar/test/bsdtar_test-test_extract_tar_zstd.o: tar/test/test_extract_tar_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_extract_tar_zstd.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_zstd.Tpo -c -o tar/test/bsdtar_test-test_extract_tar_zstd.o `test -f 'tar/test/test_extract_tar_zstd.c' || echo '$(srcdir)/'`tar/test/test_extract_tar_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_zstd.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_zstd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_extract_tar_zstd.c' object='tar/test/bsdtar_test-test_extract_tar_zstd.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_extract_tar_zstd.o `test -f 'tar/test/test_extract_tar_zstd.c' || echo '$(srcdir)/'`tar/test/test_extract_tar_zstd.c - -tar/test/bsdtar_test-test_extract_tar_zstd.obj: tar/test/test_extract_tar_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_extract_tar_zstd.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_zstd.Tpo -c -o tar/test/bsdtar_test-test_extract_tar_zstd.obj `if test -f 'tar/test/test_extract_tar_zstd.c'; then $(CYGPATH_W) 'tar/test/test_extract_tar_zstd.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_extract_tar_zstd.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_zstd.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_zstd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_extract_tar_zstd.c' object='tar/test/bsdtar_test-test_extract_tar_zstd.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_extract_tar_zstd.obj `if test -f 'tar/test/test_extract_tar_zstd.c'; then $(CYGPATH_W) 'tar/test/test_extract_tar_zstd.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_extract_tar_zstd.c'; fi` - -tar/test/bsdtar_test-test_format_newc.o: tar/test/test_format_newc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_format_newc.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_format_newc.Tpo -c -o tar/test/bsdtar_test-test_format_newc.o `test -f 'tar/test/test_format_newc.c' || echo '$(srcdir)/'`tar/test/test_format_newc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_format_newc.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_format_newc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_format_newc.c' object='tar/test/bsdtar_test-test_format_newc.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_format_newc.o `test -f 'tar/test/test_format_newc.c' || echo '$(srcdir)/'`tar/test/test_format_newc.c - -tar/test/bsdtar_test-test_format_newc.obj: tar/test/test_format_newc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_format_newc.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_format_newc.Tpo -c -o tar/test/bsdtar_test-test_format_newc.obj `if test -f 'tar/test/test_format_newc.c'; then $(CYGPATH_W) 'tar/test/test_format_newc.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_format_newc.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_format_newc.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_format_newc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_format_newc.c' object='tar/test/bsdtar_test-test_format_newc.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_format_newc.obj `if test -f 'tar/test/test_format_newc.c'; then $(CYGPATH_W) 'tar/test/test_format_newc.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_format_newc.c'; fi` - -tar/test/bsdtar_test-test_help.o: tar/test/test_help.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_help.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_help.Tpo -c -o tar/test/bsdtar_test-test_help.o `test -f 'tar/test/test_help.c' || echo '$(srcdir)/'`tar/test/test_help.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_help.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_help.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_help.c' object='tar/test/bsdtar_test-test_help.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_help.o `test -f 'tar/test/test_help.c' || echo '$(srcdir)/'`tar/test/test_help.c - -tar/test/bsdtar_test-test_help.obj: tar/test/test_help.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_help.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_help.Tpo -c -o tar/test/bsdtar_test-test_help.obj `if test -f 'tar/test/test_help.c'; then $(CYGPATH_W) 'tar/test/test_help.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_help.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_help.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_help.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_help.c' object='tar/test/bsdtar_test-test_help.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_help.obj `if test -f 'tar/test/test_help.c'; then $(CYGPATH_W) 'tar/test/test_help.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_help.c'; fi` - -tar/test/bsdtar_test-test_leading_slash.o: tar/test/test_leading_slash.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_leading_slash.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_leading_slash.Tpo -c -o tar/test/bsdtar_test-test_leading_slash.o `test -f 'tar/test/test_leading_slash.c' || echo '$(srcdir)/'`tar/test/test_leading_slash.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_leading_slash.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_leading_slash.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_leading_slash.c' object='tar/test/bsdtar_test-test_leading_slash.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_leading_slash.o `test -f 'tar/test/test_leading_slash.c' || echo '$(srcdir)/'`tar/test/test_leading_slash.c - -tar/test/bsdtar_test-test_leading_slash.obj: tar/test/test_leading_slash.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_leading_slash.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_leading_slash.Tpo -c -o tar/test/bsdtar_test-test_leading_slash.obj `if test -f 'tar/test/test_leading_slash.c'; then $(CYGPATH_W) 'tar/test/test_leading_slash.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_leading_slash.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_leading_slash.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_leading_slash.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_leading_slash.c' object='tar/test/bsdtar_test-test_leading_slash.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_leading_slash.obj `if test -f 'tar/test/test_leading_slash.c'; then $(CYGPATH_W) 'tar/test/test_leading_slash.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_leading_slash.c'; fi` - -tar/test/bsdtar_test-test_missing_file.o: tar/test/test_missing_file.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_missing_file.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_missing_file.Tpo -c -o tar/test/bsdtar_test-test_missing_file.o `test -f 'tar/test/test_missing_file.c' || echo '$(srcdir)/'`tar/test/test_missing_file.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_missing_file.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_missing_file.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_missing_file.c' object='tar/test/bsdtar_test-test_missing_file.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_missing_file.o `test -f 'tar/test/test_missing_file.c' || echo '$(srcdir)/'`tar/test/test_missing_file.c - -tar/test/bsdtar_test-test_missing_file.obj: tar/test/test_missing_file.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_missing_file.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_missing_file.Tpo -c -o tar/test/bsdtar_test-test_missing_file.obj `if test -f 'tar/test/test_missing_file.c'; then $(CYGPATH_W) 'tar/test/test_missing_file.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_missing_file.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_missing_file.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_missing_file.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_missing_file.c' object='tar/test/bsdtar_test-test_missing_file.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_missing_file.obj `if test -f 'tar/test/test_missing_file.c'; then $(CYGPATH_W) 'tar/test/test_missing_file.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_missing_file.c'; fi` - -tar/test/bsdtar_test-test_option_C_mtree.o: tar/test/test_option_C_mtree.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_C_mtree.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_C_mtree.Tpo -c -o tar/test/bsdtar_test-test_option_C_mtree.o `test -f 'tar/test/test_option_C_mtree.c' || echo '$(srcdir)/'`tar/test/test_option_C_mtree.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_C_mtree.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_C_mtree.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_C_mtree.c' object='tar/test/bsdtar_test-test_option_C_mtree.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_C_mtree.o `test -f 'tar/test/test_option_C_mtree.c' || echo '$(srcdir)/'`tar/test/test_option_C_mtree.c - -tar/test/bsdtar_test-test_option_C_mtree.obj: tar/test/test_option_C_mtree.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_C_mtree.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_C_mtree.Tpo -c -o tar/test/bsdtar_test-test_option_C_mtree.obj `if test -f 'tar/test/test_option_C_mtree.c'; then $(CYGPATH_W) 'tar/test/test_option_C_mtree.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_C_mtree.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_C_mtree.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_C_mtree.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_C_mtree.c' object='tar/test/bsdtar_test-test_option_C_mtree.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_C_mtree.obj `if test -f 'tar/test/test_option_C_mtree.c'; then $(CYGPATH_W) 'tar/test/test_option_C_mtree.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_C_mtree.c'; fi` - -tar/test/bsdtar_test-test_option_C_upper.o: tar/test/test_option_C_upper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_C_upper.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_C_upper.Tpo -c -o tar/test/bsdtar_test-test_option_C_upper.o `test -f 'tar/test/test_option_C_upper.c' || echo '$(srcdir)/'`tar/test/test_option_C_upper.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_C_upper.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_C_upper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_C_upper.c' object='tar/test/bsdtar_test-test_option_C_upper.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_C_upper.o `test -f 'tar/test/test_option_C_upper.c' || echo '$(srcdir)/'`tar/test/test_option_C_upper.c - -tar/test/bsdtar_test-test_option_C_upper.obj: tar/test/test_option_C_upper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_C_upper.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_C_upper.Tpo -c -o tar/test/bsdtar_test-test_option_C_upper.obj `if test -f 'tar/test/test_option_C_upper.c'; then $(CYGPATH_W) 'tar/test/test_option_C_upper.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_C_upper.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_C_upper.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_C_upper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_C_upper.c' object='tar/test/bsdtar_test-test_option_C_upper.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_C_upper.obj `if test -f 'tar/test/test_option_C_upper.c'; then $(CYGPATH_W) 'tar/test/test_option_C_upper.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_C_upper.c'; fi` - -tar/test/bsdtar_test-test_option_H_upper.o: tar/test/test_option_H_upper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_H_upper.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_H_upper.Tpo -c -o tar/test/bsdtar_test-test_option_H_upper.o `test -f 'tar/test/test_option_H_upper.c' || echo '$(srcdir)/'`tar/test/test_option_H_upper.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_H_upper.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_H_upper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_H_upper.c' object='tar/test/bsdtar_test-test_option_H_upper.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_H_upper.o `test -f 'tar/test/test_option_H_upper.c' || echo '$(srcdir)/'`tar/test/test_option_H_upper.c - -tar/test/bsdtar_test-test_option_H_upper.obj: tar/test/test_option_H_upper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_H_upper.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_H_upper.Tpo -c -o tar/test/bsdtar_test-test_option_H_upper.obj `if test -f 'tar/test/test_option_H_upper.c'; then $(CYGPATH_W) 'tar/test/test_option_H_upper.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_H_upper.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_H_upper.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_H_upper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_H_upper.c' object='tar/test/bsdtar_test-test_option_H_upper.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_H_upper.obj `if test -f 'tar/test/test_option_H_upper.c'; then $(CYGPATH_W) 'tar/test/test_option_H_upper.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_H_upper.c'; fi` - -tar/test/bsdtar_test-test_option_L_upper.o: tar/test/test_option_L_upper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_L_upper.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_L_upper.Tpo -c -o tar/test/bsdtar_test-test_option_L_upper.o `test -f 'tar/test/test_option_L_upper.c' || echo '$(srcdir)/'`tar/test/test_option_L_upper.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_L_upper.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_L_upper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_L_upper.c' object='tar/test/bsdtar_test-test_option_L_upper.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_L_upper.o `test -f 'tar/test/test_option_L_upper.c' || echo '$(srcdir)/'`tar/test/test_option_L_upper.c - -tar/test/bsdtar_test-test_option_L_upper.obj: tar/test/test_option_L_upper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_L_upper.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_L_upper.Tpo -c -o tar/test/bsdtar_test-test_option_L_upper.obj `if test -f 'tar/test/test_option_L_upper.c'; then $(CYGPATH_W) 'tar/test/test_option_L_upper.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_L_upper.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_L_upper.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_L_upper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_L_upper.c' object='tar/test/bsdtar_test-test_option_L_upper.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_L_upper.obj `if test -f 'tar/test/test_option_L_upper.c'; then $(CYGPATH_W) 'tar/test/test_option_L_upper.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_L_upper.c'; fi` - -tar/test/bsdtar_test-test_option_O_upper.o: tar/test/test_option_O_upper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_O_upper.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_O_upper.Tpo -c -o tar/test/bsdtar_test-test_option_O_upper.o `test -f 'tar/test/test_option_O_upper.c' || echo '$(srcdir)/'`tar/test/test_option_O_upper.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_O_upper.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_O_upper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_O_upper.c' object='tar/test/bsdtar_test-test_option_O_upper.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_O_upper.o `test -f 'tar/test/test_option_O_upper.c' || echo '$(srcdir)/'`tar/test/test_option_O_upper.c - -tar/test/bsdtar_test-test_option_O_upper.obj: tar/test/test_option_O_upper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_O_upper.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_O_upper.Tpo -c -o tar/test/bsdtar_test-test_option_O_upper.obj `if test -f 'tar/test/test_option_O_upper.c'; then $(CYGPATH_W) 'tar/test/test_option_O_upper.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_O_upper.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_O_upper.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_O_upper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_O_upper.c' object='tar/test/bsdtar_test-test_option_O_upper.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_O_upper.obj `if test -f 'tar/test/test_option_O_upper.c'; then $(CYGPATH_W) 'tar/test/test_option_O_upper.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_O_upper.c'; fi` - -tar/test/bsdtar_test-test_option_T_upper.o: tar/test/test_option_T_upper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_T_upper.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_T_upper.Tpo -c -o tar/test/bsdtar_test-test_option_T_upper.o `test -f 'tar/test/test_option_T_upper.c' || echo '$(srcdir)/'`tar/test/test_option_T_upper.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_T_upper.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_T_upper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_T_upper.c' object='tar/test/bsdtar_test-test_option_T_upper.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_T_upper.o `test -f 'tar/test/test_option_T_upper.c' || echo '$(srcdir)/'`tar/test/test_option_T_upper.c - -tar/test/bsdtar_test-test_option_T_upper.obj: tar/test/test_option_T_upper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_T_upper.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_T_upper.Tpo -c -o tar/test/bsdtar_test-test_option_T_upper.obj `if test -f 'tar/test/test_option_T_upper.c'; then $(CYGPATH_W) 'tar/test/test_option_T_upper.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_T_upper.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_T_upper.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_T_upper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_T_upper.c' object='tar/test/bsdtar_test-test_option_T_upper.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_T_upper.obj `if test -f 'tar/test/test_option_T_upper.c'; then $(CYGPATH_W) 'tar/test/test_option_T_upper.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_T_upper.c'; fi` - -tar/test/bsdtar_test-test_option_U_upper.o: tar/test/test_option_U_upper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_U_upper.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_U_upper.Tpo -c -o tar/test/bsdtar_test-test_option_U_upper.o `test -f 'tar/test/test_option_U_upper.c' || echo '$(srcdir)/'`tar/test/test_option_U_upper.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_U_upper.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_U_upper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_U_upper.c' object='tar/test/bsdtar_test-test_option_U_upper.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_U_upper.o `test -f 'tar/test/test_option_U_upper.c' || echo '$(srcdir)/'`tar/test/test_option_U_upper.c - -tar/test/bsdtar_test-test_option_U_upper.obj: tar/test/test_option_U_upper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_U_upper.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_U_upper.Tpo -c -o tar/test/bsdtar_test-test_option_U_upper.obj `if test -f 'tar/test/test_option_U_upper.c'; then $(CYGPATH_W) 'tar/test/test_option_U_upper.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_U_upper.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_U_upper.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_U_upper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_U_upper.c' object='tar/test/bsdtar_test-test_option_U_upper.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_U_upper.obj `if test -f 'tar/test/test_option_U_upper.c'; then $(CYGPATH_W) 'tar/test/test_option_U_upper.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_U_upper.c'; fi` - -tar/test/bsdtar_test-test_option_X_upper.o: tar/test/test_option_X_upper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_X_upper.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_X_upper.Tpo -c -o tar/test/bsdtar_test-test_option_X_upper.o `test -f 'tar/test/test_option_X_upper.c' || echo '$(srcdir)/'`tar/test/test_option_X_upper.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_X_upper.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_X_upper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_X_upper.c' object='tar/test/bsdtar_test-test_option_X_upper.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_X_upper.o `test -f 'tar/test/test_option_X_upper.c' || echo '$(srcdir)/'`tar/test/test_option_X_upper.c - -tar/test/bsdtar_test-test_option_X_upper.obj: tar/test/test_option_X_upper.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_X_upper.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_X_upper.Tpo -c -o tar/test/bsdtar_test-test_option_X_upper.obj `if test -f 'tar/test/test_option_X_upper.c'; then $(CYGPATH_W) 'tar/test/test_option_X_upper.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_X_upper.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_X_upper.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_X_upper.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_X_upper.c' object='tar/test/bsdtar_test-test_option_X_upper.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_X_upper.obj `if test -f 'tar/test/test_option_X_upper.c'; then $(CYGPATH_W) 'tar/test/test_option_X_upper.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_X_upper.c'; fi` - -tar/test/bsdtar_test-test_option_acls.o: tar/test/test_option_acls.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_acls.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_acls.Tpo -c -o tar/test/bsdtar_test-test_option_acls.o `test -f 'tar/test/test_option_acls.c' || echo '$(srcdir)/'`tar/test/test_option_acls.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_acls.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_acls.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_acls.c' object='tar/test/bsdtar_test-test_option_acls.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_acls.o `test -f 'tar/test/test_option_acls.c' || echo '$(srcdir)/'`tar/test/test_option_acls.c - -tar/test/bsdtar_test-test_option_acls.obj: tar/test/test_option_acls.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_acls.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_acls.Tpo -c -o tar/test/bsdtar_test-test_option_acls.obj `if test -f 'tar/test/test_option_acls.c'; then $(CYGPATH_W) 'tar/test/test_option_acls.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_acls.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_acls.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_acls.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_acls.c' object='tar/test/bsdtar_test-test_option_acls.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_acls.obj `if test -f 'tar/test/test_option_acls.c'; then $(CYGPATH_W) 'tar/test/test_option_acls.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_acls.c'; fi` - -tar/test/bsdtar_test-test_option_a.o: tar/test/test_option_a.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_a.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_a.Tpo -c -o tar/test/bsdtar_test-test_option_a.o `test -f 'tar/test/test_option_a.c' || echo '$(srcdir)/'`tar/test/test_option_a.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_a.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_a.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_a.c' object='tar/test/bsdtar_test-test_option_a.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_a.o `test -f 'tar/test/test_option_a.c' || echo '$(srcdir)/'`tar/test/test_option_a.c - -tar/test/bsdtar_test-test_option_a.obj: tar/test/test_option_a.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_a.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_a.Tpo -c -o tar/test/bsdtar_test-test_option_a.obj `if test -f 'tar/test/test_option_a.c'; then $(CYGPATH_W) 'tar/test/test_option_a.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_a.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_a.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_a.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_a.c' object='tar/test/bsdtar_test-test_option_a.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_a.obj `if test -f 'tar/test/test_option_a.c'; then $(CYGPATH_W) 'tar/test/test_option_a.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_a.c'; fi` - -tar/test/bsdtar_test-test_option_b.o: tar/test/test_option_b.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_b.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_b.Tpo -c -o tar/test/bsdtar_test-test_option_b.o `test -f 'tar/test/test_option_b.c' || echo '$(srcdir)/'`tar/test/test_option_b.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_b.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_b.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_b.c' object='tar/test/bsdtar_test-test_option_b.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_b.o `test -f 'tar/test/test_option_b.c' || echo '$(srcdir)/'`tar/test/test_option_b.c - -tar/test/bsdtar_test-test_option_b.obj: tar/test/test_option_b.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_b.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_b.Tpo -c -o tar/test/bsdtar_test-test_option_b.obj `if test -f 'tar/test/test_option_b.c'; then $(CYGPATH_W) 'tar/test/test_option_b.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_b.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_b.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_b.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_b.c' object='tar/test/bsdtar_test-test_option_b.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_b.obj `if test -f 'tar/test/test_option_b.c'; then $(CYGPATH_W) 'tar/test/test_option_b.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_b.c'; fi` - -tar/test/bsdtar_test-test_option_b64encode.o: tar/test/test_option_b64encode.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_b64encode.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_b64encode.Tpo -c -o tar/test/bsdtar_test-test_option_b64encode.o `test -f 'tar/test/test_option_b64encode.c' || echo '$(srcdir)/'`tar/test/test_option_b64encode.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_b64encode.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_b64encode.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_b64encode.c' object='tar/test/bsdtar_test-test_option_b64encode.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_b64encode.o `test -f 'tar/test/test_option_b64encode.c' || echo '$(srcdir)/'`tar/test/test_option_b64encode.c - -tar/test/bsdtar_test-test_option_b64encode.obj: tar/test/test_option_b64encode.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_b64encode.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_b64encode.Tpo -c -o tar/test/bsdtar_test-test_option_b64encode.obj `if test -f 'tar/test/test_option_b64encode.c'; then $(CYGPATH_W) 'tar/test/test_option_b64encode.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_b64encode.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_b64encode.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_b64encode.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_b64encode.c' object='tar/test/bsdtar_test-test_option_b64encode.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_b64encode.obj `if test -f 'tar/test/test_option_b64encode.c'; then $(CYGPATH_W) 'tar/test/test_option_b64encode.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_b64encode.c'; fi` - -tar/test/bsdtar_test-test_option_exclude.o: tar/test/test_option_exclude.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_exclude.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_exclude.Tpo -c -o tar/test/bsdtar_test-test_option_exclude.o `test -f 'tar/test/test_option_exclude.c' || echo '$(srcdir)/'`tar/test/test_option_exclude.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_exclude.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_exclude.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_exclude.c' object='tar/test/bsdtar_test-test_option_exclude.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_exclude.o `test -f 'tar/test/test_option_exclude.c' || echo '$(srcdir)/'`tar/test/test_option_exclude.c - -tar/test/bsdtar_test-test_option_exclude.obj: tar/test/test_option_exclude.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_exclude.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_exclude.Tpo -c -o tar/test/bsdtar_test-test_option_exclude.obj `if test -f 'tar/test/test_option_exclude.c'; then $(CYGPATH_W) 'tar/test/test_option_exclude.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_exclude.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_exclude.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_exclude.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_exclude.c' object='tar/test/bsdtar_test-test_option_exclude.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_exclude.obj `if test -f 'tar/test/test_option_exclude.c'; then $(CYGPATH_W) 'tar/test/test_option_exclude.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_exclude.c'; fi` - -tar/test/bsdtar_test-test_option_exclude_vcs.o: tar/test/test_option_exclude_vcs.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_exclude_vcs.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_exclude_vcs.Tpo -c -o tar/test/bsdtar_test-test_option_exclude_vcs.o `test -f 'tar/test/test_option_exclude_vcs.c' || echo '$(srcdir)/'`tar/test/test_option_exclude_vcs.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_exclude_vcs.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_exclude_vcs.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_exclude_vcs.c' object='tar/test/bsdtar_test-test_option_exclude_vcs.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_exclude_vcs.o `test -f 'tar/test/test_option_exclude_vcs.c' || echo '$(srcdir)/'`tar/test/test_option_exclude_vcs.c - -tar/test/bsdtar_test-test_option_exclude_vcs.obj: tar/test/test_option_exclude_vcs.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_exclude_vcs.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_exclude_vcs.Tpo -c -o tar/test/bsdtar_test-test_option_exclude_vcs.obj `if test -f 'tar/test/test_option_exclude_vcs.c'; then $(CYGPATH_W) 'tar/test/test_option_exclude_vcs.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_exclude_vcs.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_exclude_vcs.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_exclude_vcs.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_exclude_vcs.c' object='tar/test/bsdtar_test-test_option_exclude_vcs.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_exclude_vcs.obj `if test -f 'tar/test/test_option_exclude_vcs.c'; then $(CYGPATH_W) 'tar/test/test_option_exclude_vcs.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_exclude_vcs.c'; fi` - -tar/test/bsdtar_test-test_option_fflags.o: tar/test/test_option_fflags.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_fflags.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_fflags.Tpo -c -o tar/test/bsdtar_test-test_option_fflags.o `test -f 'tar/test/test_option_fflags.c' || echo '$(srcdir)/'`tar/test/test_option_fflags.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_fflags.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_fflags.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_fflags.c' object='tar/test/bsdtar_test-test_option_fflags.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_fflags.o `test -f 'tar/test/test_option_fflags.c' || echo '$(srcdir)/'`tar/test/test_option_fflags.c - -tar/test/bsdtar_test-test_option_fflags.obj: tar/test/test_option_fflags.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_fflags.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_fflags.Tpo -c -o tar/test/bsdtar_test-test_option_fflags.obj `if test -f 'tar/test/test_option_fflags.c'; then $(CYGPATH_W) 'tar/test/test_option_fflags.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_fflags.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_fflags.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_fflags.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_fflags.c' object='tar/test/bsdtar_test-test_option_fflags.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_fflags.obj `if test -f 'tar/test/test_option_fflags.c'; then $(CYGPATH_W) 'tar/test/test_option_fflags.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_fflags.c'; fi` - -tar/test/bsdtar_test-test_option_gid_gname.o: tar/test/test_option_gid_gname.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_gid_gname.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_gid_gname.Tpo -c -o tar/test/bsdtar_test-test_option_gid_gname.o `test -f 'tar/test/test_option_gid_gname.c' || echo '$(srcdir)/'`tar/test/test_option_gid_gname.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_gid_gname.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_gid_gname.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_gid_gname.c' object='tar/test/bsdtar_test-test_option_gid_gname.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_gid_gname.o `test -f 'tar/test/test_option_gid_gname.c' || echo '$(srcdir)/'`tar/test/test_option_gid_gname.c - -tar/test/bsdtar_test-test_option_gid_gname.obj: tar/test/test_option_gid_gname.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_gid_gname.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_gid_gname.Tpo -c -o tar/test/bsdtar_test-test_option_gid_gname.obj `if test -f 'tar/test/test_option_gid_gname.c'; then $(CYGPATH_W) 'tar/test/test_option_gid_gname.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_gid_gname.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_gid_gname.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_gid_gname.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_gid_gname.c' object='tar/test/bsdtar_test-test_option_gid_gname.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_gid_gname.obj `if test -f 'tar/test/test_option_gid_gname.c'; then $(CYGPATH_W) 'tar/test/test_option_gid_gname.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_gid_gname.c'; fi` - -tar/test/bsdtar_test-test_option_grzip.o: tar/test/test_option_grzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_grzip.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_grzip.Tpo -c -o tar/test/bsdtar_test-test_option_grzip.o `test -f 'tar/test/test_option_grzip.c' || echo '$(srcdir)/'`tar/test/test_option_grzip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_grzip.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_grzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_grzip.c' object='tar/test/bsdtar_test-test_option_grzip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_grzip.o `test -f 'tar/test/test_option_grzip.c' || echo '$(srcdir)/'`tar/test/test_option_grzip.c - -tar/test/bsdtar_test-test_option_grzip.obj: tar/test/test_option_grzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_grzip.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_grzip.Tpo -c -o tar/test/bsdtar_test-test_option_grzip.obj `if test -f 'tar/test/test_option_grzip.c'; then $(CYGPATH_W) 'tar/test/test_option_grzip.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_grzip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_grzip.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_grzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_grzip.c' object='tar/test/bsdtar_test-test_option_grzip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_grzip.obj `if test -f 'tar/test/test_option_grzip.c'; then $(CYGPATH_W) 'tar/test/test_option_grzip.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_grzip.c'; fi` - -tar/test/bsdtar_test-test_option_ignore_zeros.o: tar/test/test_option_ignore_zeros.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_ignore_zeros.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_ignore_zeros.Tpo -c -o tar/test/bsdtar_test-test_option_ignore_zeros.o `test -f 'tar/test/test_option_ignore_zeros.c' || echo '$(srcdir)/'`tar/test/test_option_ignore_zeros.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_ignore_zeros.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_ignore_zeros.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_ignore_zeros.c' object='tar/test/bsdtar_test-test_option_ignore_zeros.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_ignore_zeros.o `test -f 'tar/test/test_option_ignore_zeros.c' || echo '$(srcdir)/'`tar/test/test_option_ignore_zeros.c - -tar/test/bsdtar_test-test_option_ignore_zeros.obj: tar/test/test_option_ignore_zeros.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_ignore_zeros.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_ignore_zeros.Tpo -c -o tar/test/bsdtar_test-test_option_ignore_zeros.obj `if test -f 'tar/test/test_option_ignore_zeros.c'; then $(CYGPATH_W) 'tar/test/test_option_ignore_zeros.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_ignore_zeros.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_ignore_zeros.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_ignore_zeros.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_ignore_zeros.c' object='tar/test/bsdtar_test-test_option_ignore_zeros.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_ignore_zeros.obj `if test -f 'tar/test/test_option_ignore_zeros.c'; then $(CYGPATH_W) 'tar/test/test_option_ignore_zeros.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_ignore_zeros.c'; fi` - -tar/test/bsdtar_test-test_option_j.o: tar/test/test_option_j.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_j.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_j.Tpo -c -o tar/test/bsdtar_test-test_option_j.o `test -f 'tar/test/test_option_j.c' || echo '$(srcdir)/'`tar/test/test_option_j.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_j.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_j.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_j.c' object='tar/test/bsdtar_test-test_option_j.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_j.o `test -f 'tar/test/test_option_j.c' || echo '$(srcdir)/'`tar/test/test_option_j.c - -tar/test/bsdtar_test-test_option_j.obj: tar/test/test_option_j.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_j.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_j.Tpo -c -o tar/test/bsdtar_test-test_option_j.obj `if test -f 'tar/test/test_option_j.c'; then $(CYGPATH_W) 'tar/test/test_option_j.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_j.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_j.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_j.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_j.c' object='tar/test/bsdtar_test-test_option_j.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_j.obj `if test -f 'tar/test/test_option_j.c'; then $(CYGPATH_W) 'tar/test/test_option_j.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_j.c'; fi` - -tar/test/bsdtar_test-test_option_k.o: tar/test/test_option_k.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_k.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_k.Tpo -c -o tar/test/bsdtar_test-test_option_k.o `test -f 'tar/test/test_option_k.c' || echo '$(srcdir)/'`tar/test/test_option_k.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_k.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_k.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_k.c' object='tar/test/bsdtar_test-test_option_k.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_k.o `test -f 'tar/test/test_option_k.c' || echo '$(srcdir)/'`tar/test/test_option_k.c - -tar/test/bsdtar_test-test_option_k.obj: tar/test/test_option_k.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_k.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_k.Tpo -c -o tar/test/bsdtar_test-test_option_k.obj `if test -f 'tar/test/test_option_k.c'; then $(CYGPATH_W) 'tar/test/test_option_k.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_k.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_k.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_k.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_k.c' object='tar/test/bsdtar_test-test_option_k.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_k.obj `if test -f 'tar/test/test_option_k.c'; then $(CYGPATH_W) 'tar/test/test_option_k.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_k.c'; fi` - -tar/test/bsdtar_test-test_option_keep_newer_files.o: tar/test/test_option_keep_newer_files.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_keep_newer_files.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_keep_newer_files.Tpo -c -o tar/test/bsdtar_test-test_option_keep_newer_files.o `test -f 'tar/test/test_option_keep_newer_files.c' || echo '$(srcdir)/'`tar/test/test_option_keep_newer_files.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_keep_newer_files.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_keep_newer_files.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_keep_newer_files.c' object='tar/test/bsdtar_test-test_option_keep_newer_files.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_keep_newer_files.o `test -f 'tar/test/test_option_keep_newer_files.c' || echo '$(srcdir)/'`tar/test/test_option_keep_newer_files.c - -tar/test/bsdtar_test-test_option_keep_newer_files.obj: tar/test/test_option_keep_newer_files.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_keep_newer_files.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_keep_newer_files.Tpo -c -o tar/test/bsdtar_test-test_option_keep_newer_files.obj `if test -f 'tar/test/test_option_keep_newer_files.c'; then $(CYGPATH_W) 'tar/test/test_option_keep_newer_files.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_keep_newer_files.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_keep_newer_files.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_keep_newer_files.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_keep_newer_files.c' object='tar/test/bsdtar_test-test_option_keep_newer_files.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_keep_newer_files.obj `if test -f 'tar/test/test_option_keep_newer_files.c'; then $(CYGPATH_W) 'tar/test/test_option_keep_newer_files.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_keep_newer_files.c'; fi` - -tar/test/bsdtar_test-test_option_lrzip.o: tar/test/test_option_lrzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_lrzip.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_lrzip.Tpo -c -o tar/test/bsdtar_test-test_option_lrzip.o `test -f 'tar/test/test_option_lrzip.c' || echo '$(srcdir)/'`tar/test/test_option_lrzip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_lrzip.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_lrzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_lrzip.c' object='tar/test/bsdtar_test-test_option_lrzip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_lrzip.o `test -f 'tar/test/test_option_lrzip.c' || echo '$(srcdir)/'`tar/test/test_option_lrzip.c - -tar/test/bsdtar_test-test_option_lrzip.obj: tar/test/test_option_lrzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_lrzip.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_lrzip.Tpo -c -o tar/test/bsdtar_test-test_option_lrzip.obj `if test -f 'tar/test/test_option_lrzip.c'; then $(CYGPATH_W) 'tar/test/test_option_lrzip.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_lrzip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_lrzip.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_lrzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_lrzip.c' object='tar/test/bsdtar_test-test_option_lrzip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_lrzip.obj `if test -f 'tar/test/test_option_lrzip.c'; then $(CYGPATH_W) 'tar/test/test_option_lrzip.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_lrzip.c'; fi` - -tar/test/bsdtar_test-test_option_lz4.o: tar/test/test_option_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_lz4.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_lz4.Tpo -c -o tar/test/bsdtar_test-test_option_lz4.o `test -f 'tar/test/test_option_lz4.c' || echo '$(srcdir)/'`tar/test/test_option_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_lz4.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_lz4.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_lz4.c' object='tar/test/bsdtar_test-test_option_lz4.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_lz4.o `test -f 'tar/test/test_option_lz4.c' || echo '$(srcdir)/'`tar/test/test_option_lz4.c - -tar/test/bsdtar_test-test_option_lz4.obj: tar/test/test_option_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_lz4.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_lz4.Tpo -c -o tar/test/bsdtar_test-test_option_lz4.obj `if test -f 'tar/test/test_option_lz4.c'; then $(CYGPATH_W) 'tar/test/test_option_lz4.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_lz4.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_lz4.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_lz4.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_lz4.c' object='tar/test/bsdtar_test-test_option_lz4.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_lz4.obj `if test -f 'tar/test/test_option_lz4.c'; then $(CYGPATH_W) 'tar/test/test_option_lz4.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_lz4.c'; fi` - -tar/test/bsdtar_test-test_option_lzma.o: tar/test/test_option_lzma.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_lzma.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_lzma.Tpo -c -o tar/test/bsdtar_test-test_option_lzma.o `test -f 'tar/test/test_option_lzma.c' || echo '$(srcdir)/'`tar/test/test_option_lzma.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_lzma.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_lzma.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_lzma.c' object='tar/test/bsdtar_test-test_option_lzma.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_lzma.o `test -f 'tar/test/test_option_lzma.c' || echo '$(srcdir)/'`tar/test/test_option_lzma.c - -tar/test/bsdtar_test-test_option_lzma.obj: tar/test/test_option_lzma.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_lzma.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_lzma.Tpo -c -o tar/test/bsdtar_test-test_option_lzma.obj `if test -f 'tar/test/test_option_lzma.c'; then $(CYGPATH_W) 'tar/test/test_option_lzma.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_lzma.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_lzma.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_lzma.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_lzma.c' object='tar/test/bsdtar_test-test_option_lzma.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_lzma.obj `if test -f 'tar/test/test_option_lzma.c'; then $(CYGPATH_W) 'tar/test/test_option_lzma.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_lzma.c'; fi` - -tar/test/bsdtar_test-test_option_lzop.o: tar/test/test_option_lzop.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_lzop.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_lzop.Tpo -c -o tar/test/bsdtar_test-test_option_lzop.o `test -f 'tar/test/test_option_lzop.c' || echo '$(srcdir)/'`tar/test/test_option_lzop.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_lzop.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_lzop.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_lzop.c' object='tar/test/bsdtar_test-test_option_lzop.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_lzop.o `test -f 'tar/test/test_option_lzop.c' || echo '$(srcdir)/'`tar/test/test_option_lzop.c - -tar/test/bsdtar_test-test_option_lzop.obj: tar/test/test_option_lzop.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_lzop.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_lzop.Tpo -c -o tar/test/bsdtar_test-test_option_lzop.obj `if test -f 'tar/test/test_option_lzop.c'; then $(CYGPATH_W) 'tar/test/test_option_lzop.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_lzop.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_lzop.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_lzop.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_lzop.c' object='tar/test/bsdtar_test-test_option_lzop.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_lzop.obj `if test -f 'tar/test/test_option_lzop.c'; then $(CYGPATH_W) 'tar/test/test_option_lzop.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_lzop.c'; fi` - -tar/test/bsdtar_test-test_option_n.o: tar/test/test_option_n.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_n.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_n.Tpo -c -o tar/test/bsdtar_test-test_option_n.o `test -f 'tar/test/test_option_n.c' || echo '$(srcdir)/'`tar/test/test_option_n.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_n.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_n.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_n.c' object='tar/test/bsdtar_test-test_option_n.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_n.o `test -f 'tar/test/test_option_n.c' || echo '$(srcdir)/'`tar/test/test_option_n.c - -tar/test/bsdtar_test-test_option_n.obj: tar/test/test_option_n.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_n.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_n.Tpo -c -o tar/test/bsdtar_test-test_option_n.obj `if test -f 'tar/test/test_option_n.c'; then $(CYGPATH_W) 'tar/test/test_option_n.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_n.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_n.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_n.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_n.c' object='tar/test/bsdtar_test-test_option_n.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_n.obj `if test -f 'tar/test/test_option_n.c'; then $(CYGPATH_W) 'tar/test/test_option_n.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_n.c'; fi` - -tar/test/bsdtar_test-test_option_newer_than.o: tar/test/test_option_newer_than.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_newer_than.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_newer_than.Tpo -c -o tar/test/bsdtar_test-test_option_newer_than.o `test -f 'tar/test/test_option_newer_than.c' || echo '$(srcdir)/'`tar/test/test_option_newer_than.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_newer_than.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_newer_than.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_newer_than.c' object='tar/test/bsdtar_test-test_option_newer_than.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_newer_than.o `test -f 'tar/test/test_option_newer_than.c' || echo '$(srcdir)/'`tar/test/test_option_newer_than.c - -tar/test/bsdtar_test-test_option_newer_than.obj: tar/test/test_option_newer_than.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_newer_than.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_newer_than.Tpo -c -o tar/test/bsdtar_test-test_option_newer_than.obj `if test -f 'tar/test/test_option_newer_than.c'; then $(CYGPATH_W) 'tar/test/test_option_newer_than.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_newer_than.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_newer_than.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_newer_than.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_newer_than.c' object='tar/test/bsdtar_test-test_option_newer_than.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_newer_than.obj `if test -f 'tar/test/test_option_newer_than.c'; then $(CYGPATH_W) 'tar/test/test_option_newer_than.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_newer_than.c'; fi` - -tar/test/bsdtar_test-test_option_nodump.o: tar/test/test_option_nodump.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_nodump.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_nodump.Tpo -c -o tar/test/bsdtar_test-test_option_nodump.o `test -f 'tar/test/test_option_nodump.c' || echo '$(srcdir)/'`tar/test/test_option_nodump.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_nodump.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_nodump.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_nodump.c' object='tar/test/bsdtar_test-test_option_nodump.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_nodump.o `test -f 'tar/test/test_option_nodump.c' || echo '$(srcdir)/'`tar/test/test_option_nodump.c - -tar/test/bsdtar_test-test_option_nodump.obj: tar/test/test_option_nodump.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_nodump.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_nodump.Tpo -c -o tar/test/bsdtar_test-test_option_nodump.obj `if test -f 'tar/test/test_option_nodump.c'; then $(CYGPATH_W) 'tar/test/test_option_nodump.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_nodump.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_nodump.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_nodump.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_nodump.c' object='tar/test/bsdtar_test-test_option_nodump.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_nodump.obj `if test -f 'tar/test/test_option_nodump.c'; then $(CYGPATH_W) 'tar/test/test_option_nodump.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_nodump.c'; fi` - -tar/test/bsdtar_test-test_option_older_than.o: tar/test/test_option_older_than.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_older_than.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_older_than.Tpo -c -o tar/test/bsdtar_test-test_option_older_than.o `test -f 'tar/test/test_option_older_than.c' || echo '$(srcdir)/'`tar/test/test_option_older_than.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_older_than.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_older_than.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_older_than.c' object='tar/test/bsdtar_test-test_option_older_than.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_older_than.o `test -f 'tar/test/test_option_older_than.c' || echo '$(srcdir)/'`tar/test/test_option_older_than.c - -tar/test/bsdtar_test-test_option_older_than.obj: tar/test/test_option_older_than.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_older_than.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_older_than.Tpo -c -o tar/test/bsdtar_test-test_option_older_than.obj `if test -f 'tar/test/test_option_older_than.c'; then $(CYGPATH_W) 'tar/test/test_option_older_than.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_older_than.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_older_than.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_older_than.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_older_than.c' object='tar/test/bsdtar_test-test_option_older_than.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_older_than.obj `if test -f 'tar/test/test_option_older_than.c'; then $(CYGPATH_W) 'tar/test/test_option_older_than.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_older_than.c'; fi` - -tar/test/bsdtar_test-test_option_passphrase.o: tar/test/test_option_passphrase.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_passphrase.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_passphrase.Tpo -c -o tar/test/bsdtar_test-test_option_passphrase.o `test -f 'tar/test/test_option_passphrase.c' || echo '$(srcdir)/'`tar/test/test_option_passphrase.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_passphrase.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_passphrase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_passphrase.c' object='tar/test/bsdtar_test-test_option_passphrase.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_passphrase.o `test -f 'tar/test/test_option_passphrase.c' || echo '$(srcdir)/'`tar/test/test_option_passphrase.c - -tar/test/bsdtar_test-test_option_passphrase.obj: tar/test/test_option_passphrase.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_passphrase.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_passphrase.Tpo -c -o tar/test/bsdtar_test-test_option_passphrase.obj `if test -f 'tar/test/test_option_passphrase.c'; then $(CYGPATH_W) 'tar/test/test_option_passphrase.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_passphrase.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_passphrase.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_passphrase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_passphrase.c' object='tar/test/bsdtar_test-test_option_passphrase.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_passphrase.obj `if test -f 'tar/test/test_option_passphrase.c'; then $(CYGPATH_W) 'tar/test/test_option_passphrase.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_passphrase.c'; fi` - -tar/test/bsdtar_test-test_option_q.o: tar/test/test_option_q.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_q.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_q.Tpo -c -o tar/test/bsdtar_test-test_option_q.o `test -f 'tar/test/test_option_q.c' || echo '$(srcdir)/'`tar/test/test_option_q.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_q.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_q.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_q.c' object='tar/test/bsdtar_test-test_option_q.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_q.o `test -f 'tar/test/test_option_q.c' || echo '$(srcdir)/'`tar/test/test_option_q.c - -tar/test/bsdtar_test-test_option_q.obj: tar/test/test_option_q.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_q.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_q.Tpo -c -o tar/test/bsdtar_test-test_option_q.obj `if test -f 'tar/test/test_option_q.c'; then $(CYGPATH_W) 'tar/test/test_option_q.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_q.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_q.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_q.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_q.c' object='tar/test/bsdtar_test-test_option_q.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_q.obj `if test -f 'tar/test/test_option_q.c'; then $(CYGPATH_W) 'tar/test/test_option_q.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_q.c'; fi` - -tar/test/bsdtar_test-test_option_r.o: tar/test/test_option_r.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_r.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_r.Tpo -c -o tar/test/bsdtar_test-test_option_r.o `test -f 'tar/test/test_option_r.c' || echo '$(srcdir)/'`tar/test/test_option_r.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_r.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_r.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_r.c' object='tar/test/bsdtar_test-test_option_r.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_r.o `test -f 'tar/test/test_option_r.c' || echo '$(srcdir)/'`tar/test/test_option_r.c - -tar/test/bsdtar_test-test_option_r.obj: tar/test/test_option_r.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_r.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_r.Tpo -c -o tar/test/bsdtar_test-test_option_r.obj `if test -f 'tar/test/test_option_r.c'; then $(CYGPATH_W) 'tar/test/test_option_r.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_r.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_r.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_r.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_r.c' object='tar/test/bsdtar_test-test_option_r.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_r.obj `if test -f 'tar/test/test_option_r.c'; then $(CYGPATH_W) 'tar/test/test_option_r.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_r.c'; fi` - -tar/test/bsdtar_test-test_option_s.o: tar/test/test_option_s.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_s.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_s.Tpo -c -o tar/test/bsdtar_test-test_option_s.o `test -f 'tar/test/test_option_s.c' || echo '$(srcdir)/'`tar/test/test_option_s.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_s.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_s.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_s.c' object='tar/test/bsdtar_test-test_option_s.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_s.o `test -f 'tar/test/test_option_s.c' || echo '$(srcdir)/'`tar/test/test_option_s.c - -tar/test/bsdtar_test-test_option_s.obj: tar/test/test_option_s.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_s.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_s.Tpo -c -o tar/test/bsdtar_test-test_option_s.obj `if test -f 'tar/test/test_option_s.c'; then $(CYGPATH_W) 'tar/test/test_option_s.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_s.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_s.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_s.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_s.c' object='tar/test/bsdtar_test-test_option_s.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_s.obj `if test -f 'tar/test/test_option_s.c'; then $(CYGPATH_W) 'tar/test/test_option_s.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_s.c'; fi` - -tar/test/bsdtar_test-test_option_safe_writes.o: tar/test/test_option_safe_writes.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_safe_writes.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_safe_writes.Tpo -c -o tar/test/bsdtar_test-test_option_safe_writes.o `test -f 'tar/test/test_option_safe_writes.c' || echo '$(srcdir)/'`tar/test/test_option_safe_writes.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_safe_writes.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_safe_writes.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_safe_writes.c' object='tar/test/bsdtar_test-test_option_safe_writes.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_safe_writes.o `test -f 'tar/test/test_option_safe_writes.c' || echo '$(srcdir)/'`tar/test/test_option_safe_writes.c - -tar/test/bsdtar_test-test_option_safe_writes.obj: tar/test/test_option_safe_writes.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_safe_writes.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_safe_writes.Tpo -c -o tar/test/bsdtar_test-test_option_safe_writes.obj `if test -f 'tar/test/test_option_safe_writes.c'; then $(CYGPATH_W) 'tar/test/test_option_safe_writes.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_safe_writes.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_safe_writes.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_safe_writes.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_safe_writes.c' object='tar/test/bsdtar_test-test_option_safe_writes.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_safe_writes.obj `if test -f 'tar/test/test_option_safe_writes.c'; then $(CYGPATH_W) 'tar/test/test_option_safe_writes.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_safe_writes.c'; fi` - -tar/test/bsdtar_test-test_option_uid_uname.o: tar/test/test_option_uid_uname.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_uid_uname.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_uid_uname.Tpo -c -o tar/test/bsdtar_test-test_option_uid_uname.o `test -f 'tar/test/test_option_uid_uname.c' || echo '$(srcdir)/'`tar/test/test_option_uid_uname.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_uid_uname.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_uid_uname.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_uid_uname.c' object='tar/test/bsdtar_test-test_option_uid_uname.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_uid_uname.o `test -f 'tar/test/test_option_uid_uname.c' || echo '$(srcdir)/'`tar/test/test_option_uid_uname.c - -tar/test/bsdtar_test-test_option_uid_uname.obj: tar/test/test_option_uid_uname.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_uid_uname.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_uid_uname.Tpo -c -o tar/test/bsdtar_test-test_option_uid_uname.obj `if test -f 'tar/test/test_option_uid_uname.c'; then $(CYGPATH_W) 'tar/test/test_option_uid_uname.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_uid_uname.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_uid_uname.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_uid_uname.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_uid_uname.c' object='tar/test/bsdtar_test-test_option_uid_uname.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_uid_uname.obj `if test -f 'tar/test/test_option_uid_uname.c'; then $(CYGPATH_W) 'tar/test/test_option_uid_uname.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_uid_uname.c'; fi` - -tar/test/bsdtar_test-test_option_uuencode.o: tar/test/test_option_uuencode.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_uuencode.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_uuencode.Tpo -c -o tar/test/bsdtar_test-test_option_uuencode.o `test -f 'tar/test/test_option_uuencode.c' || echo '$(srcdir)/'`tar/test/test_option_uuencode.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_uuencode.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_uuencode.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_uuencode.c' object='tar/test/bsdtar_test-test_option_uuencode.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_uuencode.o `test -f 'tar/test/test_option_uuencode.c' || echo '$(srcdir)/'`tar/test/test_option_uuencode.c - -tar/test/bsdtar_test-test_option_uuencode.obj: tar/test/test_option_uuencode.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_uuencode.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_uuencode.Tpo -c -o tar/test/bsdtar_test-test_option_uuencode.obj `if test -f 'tar/test/test_option_uuencode.c'; then $(CYGPATH_W) 'tar/test/test_option_uuencode.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_uuencode.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_uuencode.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_uuencode.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_uuencode.c' object='tar/test/bsdtar_test-test_option_uuencode.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_uuencode.obj `if test -f 'tar/test/test_option_uuencode.c'; then $(CYGPATH_W) 'tar/test/test_option_uuencode.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_uuencode.c'; fi` - -tar/test/bsdtar_test-test_option_xattrs.o: tar/test/test_option_xattrs.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_xattrs.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_xattrs.Tpo -c -o tar/test/bsdtar_test-test_option_xattrs.o `test -f 'tar/test/test_option_xattrs.c' || echo '$(srcdir)/'`tar/test/test_option_xattrs.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_xattrs.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_xattrs.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_xattrs.c' object='tar/test/bsdtar_test-test_option_xattrs.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_xattrs.o `test -f 'tar/test/test_option_xattrs.c' || echo '$(srcdir)/'`tar/test/test_option_xattrs.c - -tar/test/bsdtar_test-test_option_xattrs.obj: tar/test/test_option_xattrs.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_xattrs.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_xattrs.Tpo -c -o tar/test/bsdtar_test-test_option_xattrs.obj `if test -f 'tar/test/test_option_xattrs.c'; then $(CYGPATH_W) 'tar/test/test_option_xattrs.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_xattrs.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_xattrs.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_xattrs.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_xattrs.c' object='tar/test/bsdtar_test-test_option_xattrs.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_xattrs.obj `if test -f 'tar/test/test_option_xattrs.c'; then $(CYGPATH_W) 'tar/test/test_option_xattrs.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_xattrs.c'; fi` - -tar/test/bsdtar_test-test_option_xz.o: tar/test/test_option_xz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_xz.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_xz.Tpo -c -o tar/test/bsdtar_test-test_option_xz.o `test -f 'tar/test/test_option_xz.c' || echo '$(srcdir)/'`tar/test/test_option_xz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_xz.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_xz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_xz.c' object='tar/test/bsdtar_test-test_option_xz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_xz.o `test -f 'tar/test/test_option_xz.c' || echo '$(srcdir)/'`tar/test/test_option_xz.c - -tar/test/bsdtar_test-test_option_xz.obj: tar/test/test_option_xz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_xz.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_xz.Tpo -c -o tar/test/bsdtar_test-test_option_xz.obj `if test -f 'tar/test/test_option_xz.c'; then $(CYGPATH_W) 'tar/test/test_option_xz.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_xz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_xz.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_xz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_xz.c' object='tar/test/bsdtar_test-test_option_xz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_xz.obj `if test -f 'tar/test/test_option_xz.c'; then $(CYGPATH_W) 'tar/test/test_option_xz.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_xz.c'; fi` - -tar/test/bsdtar_test-test_option_z.o: tar/test/test_option_z.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_z.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_z.Tpo -c -o tar/test/bsdtar_test-test_option_z.o `test -f 'tar/test/test_option_z.c' || echo '$(srcdir)/'`tar/test/test_option_z.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_z.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_z.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_z.c' object='tar/test/bsdtar_test-test_option_z.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_z.o `test -f 'tar/test/test_option_z.c' || echo '$(srcdir)/'`tar/test/test_option_z.c - -tar/test/bsdtar_test-test_option_z.obj: tar/test/test_option_z.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_z.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_z.Tpo -c -o tar/test/bsdtar_test-test_option_z.obj `if test -f 'tar/test/test_option_z.c'; then $(CYGPATH_W) 'tar/test/test_option_z.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_z.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_z.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_z.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_z.c' object='tar/test/bsdtar_test-test_option_z.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_z.obj `if test -f 'tar/test/test_option_z.c'; then $(CYGPATH_W) 'tar/test/test_option_z.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_z.c'; fi` - -tar/test/bsdtar_test-test_option_zstd.o: tar/test/test_option_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_zstd.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_zstd.Tpo -c -o tar/test/bsdtar_test-test_option_zstd.o `test -f 'tar/test/test_option_zstd.c' || echo '$(srcdir)/'`tar/test/test_option_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_zstd.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_zstd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_zstd.c' object='tar/test/bsdtar_test-test_option_zstd.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_zstd.o `test -f 'tar/test/test_option_zstd.c' || echo '$(srcdir)/'`tar/test/test_option_zstd.c - -tar/test/bsdtar_test-test_option_zstd.obj: tar/test/test_option_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_option_zstd.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_option_zstd.Tpo -c -o tar/test/bsdtar_test-test_option_zstd.obj `if test -f 'tar/test/test_option_zstd.c'; then $(CYGPATH_W) 'tar/test/test_option_zstd.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_zstd.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_option_zstd.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_option_zstd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_option_zstd.c' object='tar/test/bsdtar_test-test_option_zstd.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_option_zstd.obj `if test -f 'tar/test/test_option_zstd.c'; then $(CYGPATH_W) 'tar/test/test_option_zstd.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_option_zstd.c'; fi` - -tar/test/bsdtar_test-test_patterns.o: tar/test/test_patterns.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_patterns.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_patterns.Tpo -c -o tar/test/bsdtar_test-test_patterns.o `test -f 'tar/test/test_patterns.c' || echo '$(srcdir)/'`tar/test/test_patterns.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_patterns.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_patterns.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_patterns.c' object='tar/test/bsdtar_test-test_patterns.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_patterns.o `test -f 'tar/test/test_patterns.c' || echo '$(srcdir)/'`tar/test/test_patterns.c - -tar/test/bsdtar_test-test_patterns.obj: tar/test/test_patterns.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_patterns.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_patterns.Tpo -c -o tar/test/bsdtar_test-test_patterns.obj `if test -f 'tar/test/test_patterns.c'; then $(CYGPATH_W) 'tar/test/test_patterns.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_patterns.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_patterns.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_patterns.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_patterns.c' object='tar/test/bsdtar_test-test_patterns.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_patterns.obj `if test -f 'tar/test/test_patterns.c'; then $(CYGPATH_W) 'tar/test/test_patterns.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_patterns.c'; fi` - -tar/test/bsdtar_test-test_print_longpath.o: tar/test/test_print_longpath.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_print_longpath.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_print_longpath.Tpo -c -o tar/test/bsdtar_test-test_print_longpath.o `test -f 'tar/test/test_print_longpath.c' || echo '$(srcdir)/'`tar/test/test_print_longpath.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_print_longpath.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_print_longpath.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_print_longpath.c' object='tar/test/bsdtar_test-test_print_longpath.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_print_longpath.o `test -f 'tar/test/test_print_longpath.c' || echo '$(srcdir)/'`tar/test/test_print_longpath.c - -tar/test/bsdtar_test-test_print_longpath.obj: tar/test/test_print_longpath.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_print_longpath.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_print_longpath.Tpo -c -o tar/test/bsdtar_test-test_print_longpath.obj `if test -f 'tar/test/test_print_longpath.c'; then $(CYGPATH_W) 'tar/test/test_print_longpath.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_print_longpath.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_print_longpath.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_print_longpath.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_print_longpath.c' object='tar/test/bsdtar_test-test_print_longpath.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_print_longpath.obj `if test -f 'tar/test/test_print_longpath.c'; then $(CYGPATH_W) 'tar/test/test_print_longpath.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_print_longpath.c'; fi` - -tar/test/bsdtar_test-test_stdio.o: tar/test/test_stdio.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_stdio.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_stdio.Tpo -c -o tar/test/bsdtar_test-test_stdio.o `test -f 'tar/test/test_stdio.c' || echo '$(srcdir)/'`tar/test/test_stdio.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_stdio.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_stdio.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_stdio.c' object='tar/test/bsdtar_test-test_stdio.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_stdio.o `test -f 'tar/test/test_stdio.c' || echo '$(srcdir)/'`tar/test/test_stdio.c - -tar/test/bsdtar_test-test_stdio.obj: tar/test/test_stdio.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_stdio.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_stdio.Tpo -c -o tar/test/bsdtar_test-test_stdio.obj `if test -f 'tar/test/test_stdio.c'; then $(CYGPATH_W) 'tar/test/test_stdio.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_stdio.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_stdio.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_stdio.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_stdio.c' object='tar/test/bsdtar_test-test_stdio.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_stdio.obj `if test -f 'tar/test/test_stdio.c'; then $(CYGPATH_W) 'tar/test/test_stdio.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_stdio.c'; fi` - -tar/test/bsdtar_test-test_strip_components.o: tar/test/test_strip_components.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_strip_components.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_strip_components.Tpo -c -o tar/test/bsdtar_test-test_strip_components.o `test -f 'tar/test/test_strip_components.c' || echo '$(srcdir)/'`tar/test/test_strip_components.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_strip_components.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_strip_components.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_strip_components.c' object='tar/test/bsdtar_test-test_strip_components.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_strip_components.o `test -f 'tar/test/test_strip_components.c' || echo '$(srcdir)/'`tar/test/test_strip_components.c - -tar/test/bsdtar_test-test_strip_components.obj: tar/test/test_strip_components.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_strip_components.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_strip_components.Tpo -c -o tar/test/bsdtar_test-test_strip_components.obj `if test -f 'tar/test/test_strip_components.c'; then $(CYGPATH_W) 'tar/test/test_strip_components.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_strip_components.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_strip_components.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_strip_components.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_strip_components.c' object='tar/test/bsdtar_test-test_strip_components.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_strip_components.obj `if test -f 'tar/test/test_strip_components.c'; then $(CYGPATH_W) 'tar/test/test_strip_components.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_strip_components.c'; fi` - -tar/test/bsdtar_test-test_symlink_dir.o: tar/test/test_symlink_dir.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_symlink_dir.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_symlink_dir.Tpo -c -o tar/test/bsdtar_test-test_symlink_dir.o `test -f 'tar/test/test_symlink_dir.c' || echo '$(srcdir)/'`tar/test/test_symlink_dir.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_symlink_dir.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_symlink_dir.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_symlink_dir.c' object='tar/test/bsdtar_test-test_symlink_dir.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_symlink_dir.o `test -f 'tar/test/test_symlink_dir.c' || echo '$(srcdir)/'`tar/test/test_symlink_dir.c - -tar/test/bsdtar_test-test_symlink_dir.obj: tar/test/test_symlink_dir.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_symlink_dir.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_symlink_dir.Tpo -c -o tar/test/bsdtar_test-test_symlink_dir.obj `if test -f 'tar/test/test_symlink_dir.c'; then $(CYGPATH_W) 'tar/test/test_symlink_dir.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_symlink_dir.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_symlink_dir.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_symlink_dir.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_symlink_dir.c' object='tar/test/bsdtar_test-test_symlink_dir.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_symlink_dir.obj `if test -f 'tar/test/test_symlink_dir.c'; then $(CYGPATH_W) 'tar/test/test_symlink_dir.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_symlink_dir.c'; fi` - -tar/test/bsdtar_test-test_version.o: tar/test/test_version.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_version.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_version.Tpo -c -o tar/test/bsdtar_test-test_version.o `test -f 'tar/test/test_version.c' || echo '$(srcdir)/'`tar/test/test_version.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_version.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_version.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_version.c' object='tar/test/bsdtar_test-test_version.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_version.o `test -f 'tar/test/test_version.c' || echo '$(srcdir)/'`tar/test/test_version.c - -tar/test/bsdtar_test-test_version.obj: tar/test/test_version.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_version.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_version.Tpo -c -o tar/test/bsdtar_test-test_version.obj `if test -f 'tar/test/test_version.c'; then $(CYGPATH_W) 'tar/test/test_version.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_version.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_version.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_version.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_version.c' object='tar/test/bsdtar_test-test_version.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_version.obj `if test -f 'tar/test/test_version.c'; then $(CYGPATH_W) 'tar/test/test_version.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_version.c'; fi` - -tar/test/bsdtar_test-test_windows.o: tar/test/test_windows.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_windows.o -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_windows.Tpo -c -o tar/test/bsdtar_test-test_windows.o `test -f 'tar/test/test_windows.c' || echo '$(srcdir)/'`tar/test/test_windows.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_windows.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_windows.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_windows.c' object='tar/test/bsdtar_test-test_windows.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_windows.o `test -f 'tar/test/test_windows.c' || echo '$(srcdir)/'`tar/test/test_windows.c - -tar/test/bsdtar_test-test_windows.obj: tar/test/test_windows.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tar/test/bsdtar_test-test_windows.obj -MD -MP -MF tar/test/$(DEPDIR)/bsdtar_test-test_windows.Tpo -c -o tar/test/bsdtar_test-test_windows.obj `if test -f 'tar/test/test_windows.c'; then $(CYGPATH_W) 'tar/test/test_windows.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_windows.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tar/test/$(DEPDIR)/bsdtar_test-test_windows.Tpo tar/test/$(DEPDIR)/bsdtar_test-test_windows.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tar/test/test_windows.c' object='tar/test/bsdtar_test-test_windows.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdtar_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tar/test/bsdtar_test-test_windows.obj `if test -f 'tar/test/test_windows.c'; then $(CYGPATH_W) 'tar/test/test_windows.c'; else $(CYGPATH_W) '$(srcdir)/tar/test/test_windows.c'; fi` - -unzip/bsdunzip-bsdunzip.o: unzip/bsdunzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/bsdunzip-bsdunzip.o -MD -MP -MF unzip/$(DEPDIR)/bsdunzip-bsdunzip.Tpo -c -o unzip/bsdunzip-bsdunzip.o `test -f 'unzip/bsdunzip.c' || echo '$(srcdir)/'`unzip/bsdunzip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/$(DEPDIR)/bsdunzip-bsdunzip.Tpo unzip/$(DEPDIR)/bsdunzip-bsdunzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/bsdunzip.c' object='unzip/bsdunzip-bsdunzip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/bsdunzip-bsdunzip.o `test -f 'unzip/bsdunzip.c' || echo '$(srcdir)/'`unzip/bsdunzip.c - -unzip/bsdunzip-bsdunzip.obj: unzip/bsdunzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/bsdunzip-bsdunzip.obj -MD -MP -MF unzip/$(DEPDIR)/bsdunzip-bsdunzip.Tpo -c -o unzip/bsdunzip-bsdunzip.obj `if test -f 'unzip/bsdunzip.c'; then $(CYGPATH_W) 'unzip/bsdunzip.c'; else $(CYGPATH_W) '$(srcdir)/unzip/bsdunzip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/$(DEPDIR)/bsdunzip-bsdunzip.Tpo unzip/$(DEPDIR)/bsdunzip-bsdunzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/bsdunzip.c' object='unzip/bsdunzip-bsdunzip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/bsdunzip-bsdunzip.obj `if test -f 'unzip/bsdunzip.c'; then $(CYGPATH_W) 'unzip/bsdunzip.c'; else $(CYGPATH_W) '$(srcdir)/unzip/bsdunzip.c'; fi` - -unzip/bsdunzip-cmdline.o: unzip/cmdline.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/bsdunzip-cmdline.o -MD -MP -MF unzip/$(DEPDIR)/bsdunzip-cmdline.Tpo -c -o unzip/bsdunzip-cmdline.o `test -f 'unzip/cmdline.c' || echo '$(srcdir)/'`unzip/cmdline.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/$(DEPDIR)/bsdunzip-cmdline.Tpo unzip/$(DEPDIR)/bsdunzip-cmdline.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/cmdline.c' object='unzip/bsdunzip-cmdline.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/bsdunzip-cmdline.o `test -f 'unzip/cmdline.c' || echo '$(srcdir)/'`unzip/cmdline.c - -unzip/bsdunzip-cmdline.obj: unzip/cmdline.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/bsdunzip-cmdline.obj -MD -MP -MF unzip/$(DEPDIR)/bsdunzip-cmdline.Tpo -c -o unzip/bsdunzip-cmdline.obj `if test -f 'unzip/cmdline.c'; then $(CYGPATH_W) 'unzip/cmdline.c'; else $(CYGPATH_W) '$(srcdir)/unzip/cmdline.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/$(DEPDIR)/bsdunzip-cmdline.Tpo unzip/$(DEPDIR)/bsdunzip-cmdline.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/cmdline.c' object='unzip/bsdunzip-cmdline.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/bsdunzip-cmdline.obj `if test -f 'unzip/cmdline.c'; then $(CYGPATH_W) 'unzip/cmdline.c'; else $(CYGPATH_W) '$(srcdir)/unzip/cmdline.c'; fi` - -unzip/bsdunzip-la_getline.o: unzip/la_getline.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/bsdunzip-la_getline.o -MD -MP -MF unzip/$(DEPDIR)/bsdunzip-la_getline.Tpo -c -o unzip/bsdunzip-la_getline.o `test -f 'unzip/la_getline.c' || echo '$(srcdir)/'`unzip/la_getline.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/$(DEPDIR)/bsdunzip-la_getline.Tpo unzip/$(DEPDIR)/bsdunzip-la_getline.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/la_getline.c' object='unzip/bsdunzip-la_getline.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/bsdunzip-la_getline.o `test -f 'unzip/la_getline.c' || echo '$(srcdir)/'`unzip/la_getline.c - -unzip/bsdunzip-la_getline.obj: unzip/la_getline.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/bsdunzip-la_getline.obj -MD -MP -MF unzip/$(DEPDIR)/bsdunzip-la_getline.Tpo -c -o unzip/bsdunzip-la_getline.obj `if test -f 'unzip/la_getline.c'; then $(CYGPATH_W) 'unzip/la_getline.c'; else $(CYGPATH_W) '$(srcdir)/unzip/la_getline.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/$(DEPDIR)/bsdunzip-la_getline.Tpo unzip/$(DEPDIR)/bsdunzip-la_getline.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/la_getline.c' object='unzip/bsdunzip-la_getline.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/bsdunzip-la_getline.obj `if test -f 'unzip/la_getline.c'; then $(CYGPATH_W) 'unzip/la_getline.c'; else $(CYGPATH_W) '$(srcdir)/unzip/la_getline.c'; fi` - -test_utils/bsdunzip_test-test_utils.o: test_utils/test_utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_utils/bsdunzip_test-test_utils.o -MD -MP -MF test_utils/$(DEPDIR)/bsdunzip_test-test_utils.Tpo -c -o test_utils/bsdunzip_test-test_utils.o `test -f 'test_utils/test_utils.c' || echo '$(srcdir)/'`test_utils/test_utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test_utils/$(DEPDIR)/bsdunzip_test-test_utils.Tpo test_utils/$(DEPDIR)/bsdunzip_test-test_utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_utils/test_utils.c' object='test_utils/bsdunzip_test-test_utils.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_utils/bsdunzip_test-test_utils.o `test -f 'test_utils/test_utils.c' || echo '$(srcdir)/'`test_utils/test_utils.c - -test_utils/bsdunzip_test-test_utils.obj: test_utils/test_utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_utils/bsdunzip_test-test_utils.obj -MD -MP -MF test_utils/$(DEPDIR)/bsdunzip_test-test_utils.Tpo -c -o test_utils/bsdunzip_test-test_utils.obj `if test -f 'test_utils/test_utils.c'; then $(CYGPATH_W) 'test_utils/test_utils.c'; else $(CYGPATH_W) '$(srcdir)/test_utils/test_utils.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test_utils/$(DEPDIR)/bsdunzip_test-test_utils.Tpo test_utils/$(DEPDIR)/bsdunzip_test-test_utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_utils/test_utils.c' object='test_utils/bsdunzip_test-test_utils.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_utils/bsdunzip_test-test_utils.obj `if test -f 'test_utils/test_utils.c'; then $(CYGPATH_W) 'test_utils/test_utils.c'; else $(CYGPATH_W) '$(srcdir)/test_utils/test_utils.c'; fi` - -test_utils/bsdunzip_test-test_main.o: test_utils/test_main.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_utils/bsdunzip_test-test_main.o -MD -MP -MF test_utils/$(DEPDIR)/bsdunzip_test-test_main.Tpo -c -o test_utils/bsdunzip_test-test_main.o `test -f 'test_utils/test_main.c' || echo '$(srcdir)/'`test_utils/test_main.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test_utils/$(DEPDIR)/bsdunzip_test-test_main.Tpo test_utils/$(DEPDIR)/bsdunzip_test-test_main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_utils/test_main.c' object='test_utils/bsdunzip_test-test_main.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_utils/bsdunzip_test-test_main.o `test -f 'test_utils/test_main.c' || echo '$(srcdir)/'`test_utils/test_main.c - -test_utils/bsdunzip_test-test_main.obj: test_utils/test_main.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_utils/bsdunzip_test-test_main.obj -MD -MP -MF test_utils/$(DEPDIR)/bsdunzip_test-test_main.Tpo -c -o test_utils/bsdunzip_test-test_main.obj `if test -f 'test_utils/test_main.c'; then $(CYGPATH_W) 'test_utils/test_main.c'; else $(CYGPATH_W) '$(srcdir)/test_utils/test_main.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test_utils/$(DEPDIR)/bsdunzip_test-test_main.Tpo test_utils/$(DEPDIR)/bsdunzip_test-test_main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_utils/test_main.c' object='test_utils/bsdunzip_test-test_main.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_utils/bsdunzip_test-test_main.obj `if test -f 'test_utils/test_main.c'; then $(CYGPATH_W) 'test_utils/test_main.c'; else $(CYGPATH_W) '$(srcdir)/test_utils/test_main.c'; fi` - -unzip/test/bsdunzip_test-test_0.o: unzip/test/test_0.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_0.o -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_0.Tpo -c -o unzip/test/bsdunzip_test-test_0.o `test -f 'unzip/test/test_0.c' || echo '$(srcdir)/'`unzip/test/test_0.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_0.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_0.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_0.c' object='unzip/test/bsdunzip_test-test_0.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_0.o `test -f 'unzip/test/test_0.c' || echo '$(srcdir)/'`unzip/test/test_0.c - -unzip/test/bsdunzip_test-test_0.obj: unzip/test/test_0.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_0.obj -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_0.Tpo -c -o unzip/test/bsdunzip_test-test_0.obj `if test -f 'unzip/test/test_0.c'; then $(CYGPATH_W) 'unzip/test/test_0.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_0.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_0.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_0.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_0.c' object='unzip/test/bsdunzip_test-test_0.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_0.obj `if test -f 'unzip/test/test_0.c'; then $(CYGPATH_W) 'unzip/test/test_0.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_0.c'; fi` - -unzip/test/bsdunzip_test-test_basic.o: unzip/test/test_basic.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_basic.o -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_basic.Tpo -c -o unzip/test/bsdunzip_test-test_basic.o `test -f 'unzip/test/test_basic.c' || echo '$(srcdir)/'`unzip/test/test_basic.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_basic.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_basic.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_basic.c' object='unzip/test/bsdunzip_test-test_basic.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_basic.o `test -f 'unzip/test/test_basic.c' || echo '$(srcdir)/'`unzip/test/test_basic.c - -unzip/test/bsdunzip_test-test_basic.obj: unzip/test/test_basic.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_basic.obj -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_basic.Tpo -c -o unzip/test/bsdunzip_test-test_basic.obj `if test -f 'unzip/test/test_basic.c'; then $(CYGPATH_W) 'unzip/test/test_basic.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_basic.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_basic.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_basic.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_basic.c' object='unzip/test/bsdunzip_test-test_basic.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_basic.obj `if test -f 'unzip/test/test_basic.c'; then $(CYGPATH_W) 'unzip/test/test_basic.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_basic.c'; fi` - -unzip/test/bsdunzip_test-test_glob.o: unzip/test/test_glob.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_glob.o -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_glob.Tpo -c -o unzip/test/bsdunzip_test-test_glob.o `test -f 'unzip/test/test_glob.c' || echo '$(srcdir)/'`unzip/test/test_glob.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_glob.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_glob.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_glob.c' object='unzip/test/bsdunzip_test-test_glob.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_glob.o `test -f 'unzip/test/test_glob.c' || echo '$(srcdir)/'`unzip/test/test_glob.c - -unzip/test/bsdunzip_test-test_glob.obj: unzip/test/test_glob.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_glob.obj -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_glob.Tpo -c -o unzip/test/bsdunzip_test-test_glob.obj `if test -f 'unzip/test/test_glob.c'; then $(CYGPATH_W) 'unzip/test/test_glob.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_glob.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_glob.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_glob.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_glob.c' object='unzip/test/bsdunzip_test-test_glob.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_glob.obj `if test -f 'unzip/test/test_glob.c'; then $(CYGPATH_W) 'unzip/test/test_glob.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_glob.c'; fi` - -unzip/test/bsdunzip_test-test_not_exist.o: unzip/test/test_not_exist.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_not_exist.o -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_not_exist.Tpo -c -o unzip/test/bsdunzip_test-test_not_exist.o `test -f 'unzip/test/test_not_exist.c' || echo '$(srcdir)/'`unzip/test/test_not_exist.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_not_exist.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_not_exist.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_not_exist.c' object='unzip/test/bsdunzip_test-test_not_exist.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_not_exist.o `test -f 'unzip/test/test_not_exist.c' || echo '$(srcdir)/'`unzip/test/test_not_exist.c - -unzip/test/bsdunzip_test-test_not_exist.obj: unzip/test/test_not_exist.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_not_exist.obj -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_not_exist.Tpo -c -o unzip/test/bsdunzip_test-test_not_exist.obj `if test -f 'unzip/test/test_not_exist.c'; then $(CYGPATH_W) 'unzip/test/test_not_exist.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_not_exist.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_not_exist.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_not_exist.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_not_exist.c' object='unzip/test/bsdunzip_test-test_not_exist.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_not_exist.obj `if test -f 'unzip/test/test_not_exist.c'; then $(CYGPATH_W) 'unzip/test/test_not_exist.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_not_exist.c'; fi` - -unzip/test/bsdunzip_test-test_singlefile.o: unzip/test/test_singlefile.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_singlefile.o -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_singlefile.Tpo -c -o unzip/test/bsdunzip_test-test_singlefile.o `test -f 'unzip/test/test_singlefile.c' || echo '$(srcdir)/'`unzip/test/test_singlefile.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_singlefile.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_singlefile.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_singlefile.c' object='unzip/test/bsdunzip_test-test_singlefile.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_singlefile.o `test -f 'unzip/test/test_singlefile.c' || echo '$(srcdir)/'`unzip/test/test_singlefile.c - -unzip/test/bsdunzip_test-test_singlefile.obj: unzip/test/test_singlefile.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_singlefile.obj -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_singlefile.Tpo -c -o unzip/test/bsdunzip_test-test_singlefile.obj `if test -f 'unzip/test/test_singlefile.c'; then $(CYGPATH_W) 'unzip/test/test_singlefile.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_singlefile.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_singlefile.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_singlefile.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_singlefile.c' object='unzip/test/bsdunzip_test-test_singlefile.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_singlefile.obj `if test -f 'unzip/test/test_singlefile.c'; then $(CYGPATH_W) 'unzip/test/test_singlefile.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_singlefile.c'; fi` - -unzip/test/bsdunzip_test-test_C.o: unzip/test/test_C.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_C.o -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_C.Tpo -c -o unzip/test/bsdunzip_test-test_C.o `test -f 'unzip/test/test_C.c' || echo '$(srcdir)/'`unzip/test/test_C.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_C.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_C.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_C.c' object='unzip/test/bsdunzip_test-test_C.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_C.o `test -f 'unzip/test/test_C.c' || echo '$(srcdir)/'`unzip/test/test_C.c - -unzip/test/bsdunzip_test-test_C.obj: unzip/test/test_C.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_C.obj -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_C.Tpo -c -o unzip/test/bsdunzip_test-test_C.obj `if test -f 'unzip/test/test_C.c'; then $(CYGPATH_W) 'unzip/test/test_C.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_C.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_C.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_C.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_C.c' object='unzip/test/bsdunzip_test-test_C.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_C.obj `if test -f 'unzip/test/test_C.c'; then $(CYGPATH_W) 'unzip/test/test_C.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_C.c'; fi` - -unzip/test/bsdunzip_test-test_p.o: unzip/test/test_p.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_p.o -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_p.Tpo -c -o unzip/test/bsdunzip_test-test_p.o `test -f 'unzip/test/test_p.c' || echo '$(srcdir)/'`unzip/test/test_p.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_p.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_p.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_p.c' object='unzip/test/bsdunzip_test-test_p.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_p.o `test -f 'unzip/test/test_p.c' || echo '$(srcdir)/'`unzip/test/test_p.c - -unzip/test/bsdunzip_test-test_p.obj: unzip/test/test_p.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_p.obj -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_p.Tpo -c -o unzip/test/bsdunzip_test-test_p.obj `if test -f 'unzip/test/test_p.c'; then $(CYGPATH_W) 'unzip/test/test_p.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_p.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_p.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_p.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_p.c' object='unzip/test/bsdunzip_test-test_p.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_p.obj `if test -f 'unzip/test/test_p.c'; then $(CYGPATH_W) 'unzip/test/test_p.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_p.c'; fi` - -unzip/test/bsdunzip_test-test_d.o: unzip/test/test_d.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_d.o -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_d.Tpo -c -o unzip/test/bsdunzip_test-test_d.o `test -f 'unzip/test/test_d.c' || echo '$(srcdir)/'`unzip/test/test_d.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_d.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_d.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_d.c' object='unzip/test/bsdunzip_test-test_d.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_d.o `test -f 'unzip/test/test_d.c' || echo '$(srcdir)/'`unzip/test/test_d.c - -unzip/test/bsdunzip_test-test_d.obj: unzip/test/test_d.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_d.obj -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_d.Tpo -c -o unzip/test/bsdunzip_test-test_d.obj `if test -f 'unzip/test/test_d.c'; then $(CYGPATH_W) 'unzip/test/test_d.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_d.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_d.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_d.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_d.c' object='unzip/test/bsdunzip_test-test_d.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_d.obj `if test -f 'unzip/test/test_d.c'; then $(CYGPATH_W) 'unzip/test/test_d.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_d.c'; fi` - -unzip/test/bsdunzip_test-test_j.o: unzip/test/test_j.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_j.o -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_j.Tpo -c -o unzip/test/bsdunzip_test-test_j.o `test -f 'unzip/test/test_j.c' || echo '$(srcdir)/'`unzip/test/test_j.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_j.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_j.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_j.c' object='unzip/test/bsdunzip_test-test_j.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_j.o `test -f 'unzip/test/test_j.c' || echo '$(srcdir)/'`unzip/test/test_j.c - -unzip/test/bsdunzip_test-test_j.obj: unzip/test/test_j.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_j.obj -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_j.Tpo -c -o unzip/test/bsdunzip_test-test_j.obj `if test -f 'unzip/test/test_j.c'; then $(CYGPATH_W) 'unzip/test/test_j.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_j.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_j.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_j.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_j.c' object='unzip/test/bsdunzip_test-test_j.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_j.obj `if test -f 'unzip/test/test_j.c'; then $(CYGPATH_W) 'unzip/test/test_j.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_j.c'; fi` - -unzip/test/bsdunzip_test-test_L.o: unzip/test/test_L.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_L.o -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_L.Tpo -c -o unzip/test/bsdunzip_test-test_L.o `test -f 'unzip/test/test_L.c' || echo '$(srcdir)/'`unzip/test/test_L.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_L.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_L.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_L.c' object='unzip/test/bsdunzip_test-test_L.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_L.o `test -f 'unzip/test/test_L.c' || echo '$(srcdir)/'`unzip/test/test_L.c - -unzip/test/bsdunzip_test-test_L.obj: unzip/test/test_L.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_L.obj -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_L.Tpo -c -o unzip/test/bsdunzip_test-test_L.obj `if test -f 'unzip/test/test_L.c'; then $(CYGPATH_W) 'unzip/test/test_L.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_L.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_L.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_L.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_L.c' object='unzip/test/bsdunzip_test-test_L.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_L.obj `if test -f 'unzip/test/test_L.c'; then $(CYGPATH_W) 'unzip/test/test_L.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_L.c'; fi` - -unzip/test/bsdunzip_test-test_n.o: unzip/test/test_n.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_n.o -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_n.Tpo -c -o unzip/test/bsdunzip_test-test_n.o `test -f 'unzip/test/test_n.c' || echo '$(srcdir)/'`unzip/test/test_n.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_n.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_n.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_n.c' object='unzip/test/bsdunzip_test-test_n.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_n.o `test -f 'unzip/test/test_n.c' || echo '$(srcdir)/'`unzip/test/test_n.c - -unzip/test/bsdunzip_test-test_n.obj: unzip/test/test_n.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_n.obj -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_n.Tpo -c -o unzip/test/bsdunzip_test-test_n.obj `if test -f 'unzip/test/test_n.c'; then $(CYGPATH_W) 'unzip/test/test_n.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_n.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_n.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_n.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_n.c' object='unzip/test/bsdunzip_test-test_n.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_n.obj `if test -f 'unzip/test/test_n.c'; then $(CYGPATH_W) 'unzip/test/test_n.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_n.c'; fi` - -unzip/test/bsdunzip_test-test_o.o: unzip/test/test_o.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_o.o -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_o.Tpo -c -o unzip/test/bsdunzip_test-test_o.o `test -f 'unzip/test/test_o.c' || echo '$(srcdir)/'`unzip/test/test_o.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_o.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_o.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_o.c' object='unzip/test/bsdunzip_test-test_o.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_o.o `test -f 'unzip/test/test_o.c' || echo '$(srcdir)/'`unzip/test/test_o.c - -unzip/test/bsdunzip_test-test_o.obj: unzip/test/test_o.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_o.obj -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_o.Tpo -c -o unzip/test/bsdunzip_test-test_o.obj `if test -f 'unzip/test/test_o.c'; then $(CYGPATH_W) 'unzip/test/test_o.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_o.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_o.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_o.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_o.c' object='unzip/test/bsdunzip_test-test_o.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_o.obj `if test -f 'unzip/test/test_o.c'; then $(CYGPATH_W) 'unzip/test/test_o.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_o.c'; fi` - -unzip/test/bsdunzip_test-test_q.o: unzip/test/test_q.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_q.o -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_q.Tpo -c -o unzip/test/bsdunzip_test-test_q.o `test -f 'unzip/test/test_q.c' || echo '$(srcdir)/'`unzip/test/test_q.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_q.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_q.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_q.c' object='unzip/test/bsdunzip_test-test_q.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_q.o `test -f 'unzip/test/test_q.c' || echo '$(srcdir)/'`unzip/test/test_q.c - -unzip/test/bsdunzip_test-test_q.obj: unzip/test/test_q.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_q.obj -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_q.Tpo -c -o unzip/test/bsdunzip_test-test_q.obj `if test -f 'unzip/test/test_q.c'; then $(CYGPATH_W) 'unzip/test/test_q.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_q.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_q.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_q.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_q.c' object='unzip/test/bsdunzip_test-test_q.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_q.obj `if test -f 'unzip/test/test_q.c'; then $(CYGPATH_W) 'unzip/test/test_q.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_q.c'; fi` - -unzip/test/bsdunzip_test-test_t.o: unzip/test/test_t.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_t.o -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_t.Tpo -c -o unzip/test/bsdunzip_test-test_t.o `test -f 'unzip/test/test_t.c' || echo '$(srcdir)/'`unzip/test/test_t.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_t.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_t.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_t.c' object='unzip/test/bsdunzip_test-test_t.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_t.o `test -f 'unzip/test/test_t.c' || echo '$(srcdir)/'`unzip/test/test_t.c - -unzip/test/bsdunzip_test-test_t.obj: unzip/test/test_t.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_t.obj -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_t.Tpo -c -o unzip/test/bsdunzip_test-test_t.obj `if test -f 'unzip/test/test_t.c'; then $(CYGPATH_W) 'unzip/test/test_t.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_t.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_t.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_t.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_t.c' object='unzip/test/bsdunzip_test-test_t.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_t.obj `if test -f 'unzip/test/test_t.c'; then $(CYGPATH_W) 'unzip/test/test_t.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_t.c'; fi` - -unzip/test/bsdunzip_test-test_t_bad.o: unzip/test/test_t_bad.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_t_bad.o -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_t_bad.Tpo -c -o unzip/test/bsdunzip_test-test_t_bad.o `test -f 'unzip/test/test_t_bad.c' || echo '$(srcdir)/'`unzip/test/test_t_bad.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_t_bad.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_t_bad.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_t_bad.c' object='unzip/test/bsdunzip_test-test_t_bad.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_t_bad.o `test -f 'unzip/test/test_t_bad.c' || echo '$(srcdir)/'`unzip/test/test_t_bad.c - -unzip/test/bsdunzip_test-test_t_bad.obj: unzip/test/test_t_bad.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_t_bad.obj -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_t_bad.Tpo -c -o unzip/test/bsdunzip_test-test_t_bad.obj `if test -f 'unzip/test/test_t_bad.c'; then $(CYGPATH_W) 'unzip/test/test_t_bad.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_t_bad.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_t_bad.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_t_bad.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_t_bad.c' object='unzip/test/bsdunzip_test-test_t_bad.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_t_bad.obj `if test -f 'unzip/test/test_t_bad.c'; then $(CYGPATH_W) 'unzip/test/test_t_bad.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_t_bad.c'; fi` - -unzip/test/bsdunzip_test-test_version.o: unzip/test/test_version.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_version.o -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_version.Tpo -c -o unzip/test/bsdunzip_test-test_version.o `test -f 'unzip/test/test_version.c' || echo '$(srcdir)/'`unzip/test/test_version.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_version.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_version.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_version.c' object='unzip/test/bsdunzip_test-test_version.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_version.o `test -f 'unzip/test/test_version.c' || echo '$(srcdir)/'`unzip/test/test_version.c - -unzip/test/bsdunzip_test-test_version.obj: unzip/test/test_version.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_version.obj -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_version.Tpo -c -o unzip/test/bsdunzip_test-test_version.obj `if test -f 'unzip/test/test_version.c'; then $(CYGPATH_W) 'unzip/test/test_version.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_version.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_version.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_version.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_version.c' object='unzip/test/bsdunzip_test-test_version.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_version.obj `if test -f 'unzip/test/test_version.c'; then $(CYGPATH_W) 'unzip/test/test_version.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_version.c'; fi` - -unzip/test/bsdunzip_test-test_x.o: unzip/test/test_x.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_x.o -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_x.Tpo -c -o unzip/test/bsdunzip_test-test_x.o `test -f 'unzip/test/test_x.c' || echo '$(srcdir)/'`unzip/test/test_x.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_x.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_x.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_x.c' object='unzip/test/bsdunzip_test-test_x.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_x.o `test -f 'unzip/test/test_x.c' || echo '$(srcdir)/'`unzip/test/test_x.c - -unzip/test/bsdunzip_test-test_x.obj: unzip/test/test_x.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_x.obj -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_x.Tpo -c -o unzip/test/bsdunzip_test-test_x.obj `if test -f 'unzip/test/test_x.c'; then $(CYGPATH_W) 'unzip/test/test_x.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_x.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_x.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_x.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_x.c' object='unzip/test/bsdunzip_test-test_x.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_x.obj `if test -f 'unzip/test/test_x.c'; then $(CYGPATH_W) 'unzip/test/test_x.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_x.c'; fi` - -unzip/test/bsdunzip_test-test_Z1.o: unzip/test/test_Z1.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_Z1.o -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_Z1.Tpo -c -o unzip/test/bsdunzip_test-test_Z1.o `test -f 'unzip/test/test_Z1.c' || echo '$(srcdir)/'`unzip/test/test_Z1.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_Z1.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_Z1.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_Z1.c' object='unzip/test/bsdunzip_test-test_Z1.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_Z1.o `test -f 'unzip/test/test_Z1.c' || echo '$(srcdir)/'`unzip/test/test_Z1.c - -unzip/test/bsdunzip_test-test_Z1.obj: unzip/test/test_Z1.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_Z1.obj -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_Z1.Tpo -c -o unzip/test/bsdunzip_test-test_Z1.obj `if test -f 'unzip/test/test_Z1.c'; then $(CYGPATH_W) 'unzip/test/test_Z1.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_Z1.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_Z1.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_Z1.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_Z1.c' object='unzip/test/bsdunzip_test-test_Z1.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_Z1.obj `if test -f 'unzip/test/test_Z1.c'; then $(CYGPATH_W) 'unzip/test/test_Z1.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_Z1.c'; fi` - -unzip/test/bsdunzip_test-test_P_encryption.o: unzip/test/test_P_encryption.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_P_encryption.o -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_P_encryption.Tpo -c -o unzip/test/bsdunzip_test-test_P_encryption.o `test -f 'unzip/test/test_P_encryption.c' || echo '$(srcdir)/'`unzip/test/test_P_encryption.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_P_encryption.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_P_encryption.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_P_encryption.c' object='unzip/test/bsdunzip_test-test_P_encryption.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_P_encryption.o `test -f 'unzip/test/test_P_encryption.c' || echo '$(srcdir)/'`unzip/test/test_P_encryption.c - -unzip/test/bsdunzip_test-test_P_encryption.obj: unzip/test/test_P_encryption.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT unzip/test/bsdunzip_test-test_P_encryption.obj -MD -MP -MF unzip/test/$(DEPDIR)/bsdunzip_test-test_P_encryption.Tpo -c -o unzip/test/bsdunzip_test-test_P_encryption.obj `if test -f 'unzip/test/test_P_encryption.c'; then $(CYGPATH_W) 'unzip/test/test_P_encryption.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_P_encryption.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) unzip/test/$(DEPDIR)/bsdunzip_test-test_P_encryption.Tpo unzip/test/$(DEPDIR)/bsdunzip_test-test_P_encryption.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unzip/test/test_P_encryption.c' object='unzip/test/bsdunzip_test-test_P_encryption.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(bsdunzip_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o unzip/test/bsdunzip_test-test_P_encryption.obj `if test -f 'unzip/test/test_P_encryption.c'; then $(CYGPATH_W) 'unzip/test/test_P_encryption.c'; else $(CYGPATH_W) '$(srcdir)/unzip/test/test_P_encryption.c'; fi` - -libarchive/test-archive_acl.o: libarchive/archive_acl.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_acl.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_acl.Tpo -c -o libarchive/test-archive_acl.o `test -f 'libarchive/archive_acl.c' || echo '$(srcdir)/'`libarchive/archive_acl.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_acl.Tpo libarchive/$(DEPDIR)/test-archive_acl.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_acl.c' object='libarchive/test-archive_acl.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_acl.o `test -f 'libarchive/archive_acl.c' || echo '$(srcdir)/'`libarchive/archive_acl.c - -libarchive/test-archive_acl.obj: libarchive/archive_acl.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_acl.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_acl.Tpo -c -o libarchive/test-archive_acl.obj `if test -f 'libarchive/archive_acl.c'; then $(CYGPATH_W) 'libarchive/archive_acl.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_acl.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_acl.Tpo libarchive/$(DEPDIR)/test-archive_acl.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_acl.c' object='libarchive/test-archive_acl.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_acl.obj `if test -f 'libarchive/archive_acl.c'; then $(CYGPATH_W) 'libarchive/archive_acl.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_acl.c'; fi` - -libarchive/test-archive_check_magic.o: libarchive/archive_check_magic.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_check_magic.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_check_magic.Tpo -c -o libarchive/test-archive_check_magic.o `test -f 'libarchive/archive_check_magic.c' || echo '$(srcdir)/'`libarchive/archive_check_magic.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_check_magic.Tpo libarchive/$(DEPDIR)/test-archive_check_magic.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_check_magic.c' object='libarchive/test-archive_check_magic.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_check_magic.o `test -f 'libarchive/archive_check_magic.c' || echo '$(srcdir)/'`libarchive/archive_check_magic.c - -libarchive/test-archive_check_magic.obj: libarchive/archive_check_magic.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_check_magic.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_check_magic.Tpo -c -o libarchive/test-archive_check_magic.obj `if test -f 'libarchive/archive_check_magic.c'; then $(CYGPATH_W) 'libarchive/archive_check_magic.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_check_magic.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_check_magic.Tpo libarchive/$(DEPDIR)/test-archive_check_magic.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_check_magic.c' object='libarchive/test-archive_check_magic.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_check_magic.obj `if test -f 'libarchive/archive_check_magic.c'; then $(CYGPATH_W) 'libarchive/archive_check_magic.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_check_magic.c'; fi` - -libarchive/test-archive_cmdline.o: libarchive/archive_cmdline.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_cmdline.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_cmdline.Tpo -c -o libarchive/test-archive_cmdline.o `test -f 'libarchive/archive_cmdline.c' || echo '$(srcdir)/'`libarchive/archive_cmdline.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_cmdline.Tpo libarchive/$(DEPDIR)/test-archive_cmdline.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_cmdline.c' object='libarchive/test-archive_cmdline.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_cmdline.o `test -f 'libarchive/archive_cmdline.c' || echo '$(srcdir)/'`libarchive/archive_cmdline.c - -libarchive/test-archive_cmdline.obj: libarchive/archive_cmdline.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_cmdline.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_cmdline.Tpo -c -o libarchive/test-archive_cmdline.obj `if test -f 'libarchive/archive_cmdline.c'; then $(CYGPATH_W) 'libarchive/archive_cmdline.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_cmdline.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_cmdline.Tpo libarchive/$(DEPDIR)/test-archive_cmdline.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_cmdline.c' object='libarchive/test-archive_cmdline.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_cmdline.obj `if test -f 'libarchive/archive_cmdline.c'; then $(CYGPATH_W) 'libarchive/archive_cmdline.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_cmdline.c'; fi` - -libarchive/test-archive_cryptor.o: libarchive/archive_cryptor.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_cryptor.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_cryptor.Tpo -c -o libarchive/test-archive_cryptor.o `test -f 'libarchive/archive_cryptor.c' || echo '$(srcdir)/'`libarchive/archive_cryptor.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_cryptor.Tpo libarchive/$(DEPDIR)/test-archive_cryptor.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_cryptor.c' object='libarchive/test-archive_cryptor.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_cryptor.o `test -f 'libarchive/archive_cryptor.c' || echo '$(srcdir)/'`libarchive/archive_cryptor.c - -libarchive/test-archive_cryptor.obj: libarchive/archive_cryptor.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_cryptor.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_cryptor.Tpo -c -o libarchive/test-archive_cryptor.obj `if test -f 'libarchive/archive_cryptor.c'; then $(CYGPATH_W) 'libarchive/archive_cryptor.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_cryptor.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_cryptor.Tpo libarchive/$(DEPDIR)/test-archive_cryptor.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_cryptor.c' object='libarchive/test-archive_cryptor.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_cryptor.obj `if test -f 'libarchive/archive_cryptor.c'; then $(CYGPATH_W) 'libarchive/archive_cryptor.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_cryptor.c'; fi` - -libarchive/test-archive_digest.o: libarchive/archive_digest.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_digest.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_digest.Tpo -c -o libarchive/test-archive_digest.o `test -f 'libarchive/archive_digest.c' || echo '$(srcdir)/'`libarchive/archive_digest.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_digest.Tpo libarchive/$(DEPDIR)/test-archive_digest.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_digest.c' object='libarchive/test-archive_digest.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_digest.o `test -f 'libarchive/archive_digest.c' || echo '$(srcdir)/'`libarchive/archive_digest.c - -libarchive/test-archive_digest.obj: libarchive/archive_digest.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_digest.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_digest.Tpo -c -o libarchive/test-archive_digest.obj `if test -f 'libarchive/archive_digest.c'; then $(CYGPATH_W) 'libarchive/archive_digest.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_digest.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_digest.Tpo libarchive/$(DEPDIR)/test-archive_digest.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_digest.c' object='libarchive/test-archive_digest.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_digest.obj `if test -f 'libarchive/archive_digest.c'; then $(CYGPATH_W) 'libarchive/archive_digest.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_digest.c'; fi` - -libarchive/test-archive_entry.o: libarchive/archive_entry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_entry.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_entry.Tpo -c -o libarchive/test-archive_entry.o `test -f 'libarchive/archive_entry.c' || echo '$(srcdir)/'`libarchive/archive_entry.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_entry.Tpo libarchive/$(DEPDIR)/test-archive_entry.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_entry.c' object='libarchive/test-archive_entry.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_entry.o `test -f 'libarchive/archive_entry.c' || echo '$(srcdir)/'`libarchive/archive_entry.c - -libarchive/test-archive_entry.obj: libarchive/archive_entry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_entry.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_entry.Tpo -c -o libarchive/test-archive_entry.obj `if test -f 'libarchive/archive_entry.c'; then $(CYGPATH_W) 'libarchive/archive_entry.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_entry.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_entry.Tpo libarchive/$(DEPDIR)/test-archive_entry.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_entry.c' object='libarchive/test-archive_entry.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_entry.obj `if test -f 'libarchive/archive_entry.c'; then $(CYGPATH_W) 'libarchive/archive_entry.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_entry.c'; fi` - -libarchive/test-archive_entry_copy_stat.o: libarchive/archive_entry_copy_stat.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_entry_copy_stat.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_entry_copy_stat.Tpo -c -o libarchive/test-archive_entry_copy_stat.o `test -f 'libarchive/archive_entry_copy_stat.c' || echo '$(srcdir)/'`libarchive/archive_entry_copy_stat.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_entry_copy_stat.Tpo libarchive/$(DEPDIR)/test-archive_entry_copy_stat.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_entry_copy_stat.c' object='libarchive/test-archive_entry_copy_stat.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_entry_copy_stat.o `test -f 'libarchive/archive_entry_copy_stat.c' || echo '$(srcdir)/'`libarchive/archive_entry_copy_stat.c - -libarchive/test-archive_entry_copy_stat.obj: libarchive/archive_entry_copy_stat.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_entry_copy_stat.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_entry_copy_stat.Tpo -c -o libarchive/test-archive_entry_copy_stat.obj `if test -f 'libarchive/archive_entry_copy_stat.c'; then $(CYGPATH_W) 'libarchive/archive_entry_copy_stat.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_entry_copy_stat.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_entry_copy_stat.Tpo libarchive/$(DEPDIR)/test-archive_entry_copy_stat.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_entry_copy_stat.c' object='libarchive/test-archive_entry_copy_stat.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_entry_copy_stat.obj `if test -f 'libarchive/archive_entry_copy_stat.c'; then $(CYGPATH_W) 'libarchive/archive_entry_copy_stat.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_entry_copy_stat.c'; fi` - -libarchive/test-archive_entry_link_resolver.o: libarchive/archive_entry_link_resolver.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_entry_link_resolver.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_entry_link_resolver.Tpo -c -o libarchive/test-archive_entry_link_resolver.o `test -f 'libarchive/archive_entry_link_resolver.c' || echo '$(srcdir)/'`libarchive/archive_entry_link_resolver.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_entry_link_resolver.Tpo libarchive/$(DEPDIR)/test-archive_entry_link_resolver.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_entry_link_resolver.c' object='libarchive/test-archive_entry_link_resolver.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_entry_link_resolver.o `test -f 'libarchive/archive_entry_link_resolver.c' || echo '$(srcdir)/'`libarchive/archive_entry_link_resolver.c - -libarchive/test-archive_entry_link_resolver.obj: libarchive/archive_entry_link_resolver.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_entry_link_resolver.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_entry_link_resolver.Tpo -c -o libarchive/test-archive_entry_link_resolver.obj `if test -f 'libarchive/archive_entry_link_resolver.c'; then $(CYGPATH_W) 'libarchive/archive_entry_link_resolver.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_entry_link_resolver.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_entry_link_resolver.Tpo libarchive/$(DEPDIR)/test-archive_entry_link_resolver.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_entry_link_resolver.c' object='libarchive/test-archive_entry_link_resolver.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_entry_link_resolver.obj `if test -f 'libarchive/archive_entry_link_resolver.c'; then $(CYGPATH_W) 'libarchive/archive_entry_link_resolver.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_entry_link_resolver.c'; fi` - -libarchive/test-archive_entry_sparse.o: libarchive/archive_entry_sparse.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_entry_sparse.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_entry_sparse.Tpo -c -o libarchive/test-archive_entry_sparse.o `test -f 'libarchive/archive_entry_sparse.c' || echo '$(srcdir)/'`libarchive/archive_entry_sparse.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_entry_sparse.Tpo libarchive/$(DEPDIR)/test-archive_entry_sparse.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_entry_sparse.c' object='libarchive/test-archive_entry_sparse.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_entry_sparse.o `test -f 'libarchive/archive_entry_sparse.c' || echo '$(srcdir)/'`libarchive/archive_entry_sparse.c - -libarchive/test-archive_entry_sparse.obj: libarchive/archive_entry_sparse.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_entry_sparse.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_entry_sparse.Tpo -c -o libarchive/test-archive_entry_sparse.obj `if test -f 'libarchive/archive_entry_sparse.c'; then $(CYGPATH_W) 'libarchive/archive_entry_sparse.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_entry_sparse.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_entry_sparse.Tpo libarchive/$(DEPDIR)/test-archive_entry_sparse.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_entry_sparse.c' object='libarchive/test-archive_entry_sparse.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_entry_sparse.obj `if test -f 'libarchive/archive_entry_sparse.c'; then $(CYGPATH_W) 'libarchive/archive_entry_sparse.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_entry_sparse.c'; fi` - -libarchive/test-archive_entry_stat.o: libarchive/archive_entry_stat.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_entry_stat.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_entry_stat.Tpo -c -o libarchive/test-archive_entry_stat.o `test -f 'libarchive/archive_entry_stat.c' || echo '$(srcdir)/'`libarchive/archive_entry_stat.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_entry_stat.Tpo libarchive/$(DEPDIR)/test-archive_entry_stat.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_entry_stat.c' object='libarchive/test-archive_entry_stat.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_entry_stat.o `test -f 'libarchive/archive_entry_stat.c' || echo '$(srcdir)/'`libarchive/archive_entry_stat.c - -libarchive/test-archive_entry_stat.obj: libarchive/archive_entry_stat.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_entry_stat.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_entry_stat.Tpo -c -o libarchive/test-archive_entry_stat.obj `if test -f 'libarchive/archive_entry_stat.c'; then $(CYGPATH_W) 'libarchive/archive_entry_stat.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_entry_stat.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_entry_stat.Tpo libarchive/$(DEPDIR)/test-archive_entry_stat.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_entry_stat.c' object='libarchive/test-archive_entry_stat.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_entry_stat.obj `if test -f 'libarchive/archive_entry_stat.c'; then $(CYGPATH_W) 'libarchive/archive_entry_stat.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_entry_stat.c'; fi` - -libarchive/test-archive_entry_strmode.o: libarchive/archive_entry_strmode.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_entry_strmode.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_entry_strmode.Tpo -c -o libarchive/test-archive_entry_strmode.o `test -f 'libarchive/archive_entry_strmode.c' || echo '$(srcdir)/'`libarchive/archive_entry_strmode.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_entry_strmode.Tpo libarchive/$(DEPDIR)/test-archive_entry_strmode.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_entry_strmode.c' object='libarchive/test-archive_entry_strmode.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_entry_strmode.o `test -f 'libarchive/archive_entry_strmode.c' || echo '$(srcdir)/'`libarchive/archive_entry_strmode.c - -libarchive/test-archive_entry_strmode.obj: libarchive/archive_entry_strmode.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_entry_strmode.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_entry_strmode.Tpo -c -o libarchive/test-archive_entry_strmode.obj `if test -f 'libarchive/archive_entry_strmode.c'; then $(CYGPATH_W) 'libarchive/archive_entry_strmode.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_entry_strmode.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_entry_strmode.Tpo libarchive/$(DEPDIR)/test-archive_entry_strmode.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_entry_strmode.c' object='libarchive/test-archive_entry_strmode.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_entry_strmode.obj `if test -f 'libarchive/archive_entry_strmode.c'; then $(CYGPATH_W) 'libarchive/archive_entry_strmode.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_entry_strmode.c'; fi` - -libarchive/test-archive_entry_xattr.o: libarchive/archive_entry_xattr.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_entry_xattr.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_entry_xattr.Tpo -c -o libarchive/test-archive_entry_xattr.o `test -f 'libarchive/archive_entry_xattr.c' || echo '$(srcdir)/'`libarchive/archive_entry_xattr.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_entry_xattr.Tpo libarchive/$(DEPDIR)/test-archive_entry_xattr.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_entry_xattr.c' object='libarchive/test-archive_entry_xattr.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_entry_xattr.o `test -f 'libarchive/archive_entry_xattr.c' || echo '$(srcdir)/'`libarchive/archive_entry_xattr.c - -libarchive/test-archive_entry_xattr.obj: libarchive/archive_entry_xattr.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_entry_xattr.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_entry_xattr.Tpo -c -o libarchive/test-archive_entry_xattr.obj `if test -f 'libarchive/archive_entry_xattr.c'; then $(CYGPATH_W) 'libarchive/archive_entry_xattr.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_entry_xattr.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_entry_xattr.Tpo libarchive/$(DEPDIR)/test-archive_entry_xattr.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_entry_xattr.c' object='libarchive/test-archive_entry_xattr.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_entry_xattr.obj `if test -f 'libarchive/archive_entry_xattr.c'; then $(CYGPATH_W) 'libarchive/archive_entry_xattr.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_entry_xattr.c'; fi` - -libarchive/test-archive_getdate.o: libarchive/archive_getdate.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_getdate.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_getdate.Tpo -c -o libarchive/test-archive_getdate.o `test -f 'libarchive/archive_getdate.c' || echo '$(srcdir)/'`libarchive/archive_getdate.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_getdate.Tpo libarchive/$(DEPDIR)/test-archive_getdate.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_getdate.c' object='libarchive/test-archive_getdate.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_getdate.o `test -f 'libarchive/archive_getdate.c' || echo '$(srcdir)/'`libarchive/archive_getdate.c - -libarchive/test-archive_getdate.obj: libarchive/archive_getdate.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_getdate.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_getdate.Tpo -c -o libarchive/test-archive_getdate.obj `if test -f 'libarchive/archive_getdate.c'; then $(CYGPATH_W) 'libarchive/archive_getdate.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_getdate.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_getdate.Tpo libarchive/$(DEPDIR)/test-archive_getdate.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_getdate.c' object='libarchive/test-archive_getdate.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_getdate.obj `if test -f 'libarchive/archive_getdate.c'; then $(CYGPATH_W) 'libarchive/archive_getdate.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_getdate.c'; fi` - -libarchive/test-archive_hmac.o: libarchive/archive_hmac.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_hmac.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_hmac.Tpo -c -o libarchive/test-archive_hmac.o `test -f 'libarchive/archive_hmac.c' || echo '$(srcdir)/'`libarchive/archive_hmac.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_hmac.Tpo libarchive/$(DEPDIR)/test-archive_hmac.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_hmac.c' object='libarchive/test-archive_hmac.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_hmac.o `test -f 'libarchive/archive_hmac.c' || echo '$(srcdir)/'`libarchive/archive_hmac.c - -libarchive/test-archive_hmac.obj: libarchive/archive_hmac.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_hmac.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_hmac.Tpo -c -o libarchive/test-archive_hmac.obj `if test -f 'libarchive/archive_hmac.c'; then $(CYGPATH_W) 'libarchive/archive_hmac.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_hmac.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_hmac.Tpo libarchive/$(DEPDIR)/test-archive_hmac.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_hmac.c' object='libarchive/test-archive_hmac.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_hmac.obj `if test -f 'libarchive/archive_hmac.c'; then $(CYGPATH_W) 'libarchive/archive_hmac.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_hmac.c'; fi` - -libarchive/test-archive_match.o: libarchive/archive_match.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_match.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_match.Tpo -c -o libarchive/test-archive_match.o `test -f 'libarchive/archive_match.c' || echo '$(srcdir)/'`libarchive/archive_match.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_match.Tpo libarchive/$(DEPDIR)/test-archive_match.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_match.c' object='libarchive/test-archive_match.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_match.o `test -f 'libarchive/archive_match.c' || echo '$(srcdir)/'`libarchive/archive_match.c - -libarchive/test-archive_match.obj: libarchive/archive_match.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_match.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_match.Tpo -c -o libarchive/test-archive_match.obj `if test -f 'libarchive/archive_match.c'; then $(CYGPATH_W) 'libarchive/archive_match.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_match.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_match.Tpo libarchive/$(DEPDIR)/test-archive_match.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_match.c' object='libarchive/test-archive_match.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_match.obj `if test -f 'libarchive/archive_match.c'; then $(CYGPATH_W) 'libarchive/archive_match.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_match.c'; fi` - -libarchive/test-archive_options.o: libarchive/archive_options.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_options.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_options.Tpo -c -o libarchive/test-archive_options.o `test -f 'libarchive/archive_options.c' || echo '$(srcdir)/'`libarchive/archive_options.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_options.Tpo libarchive/$(DEPDIR)/test-archive_options.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_options.c' object='libarchive/test-archive_options.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_options.o `test -f 'libarchive/archive_options.c' || echo '$(srcdir)/'`libarchive/archive_options.c - -libarchive/test-archive_options.obj: libarchive/archive_options.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_options.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_options.Tpo -c -o libarchive/test-archive_options.obj `if test -f 'libarchive/archive_options.c'; then $(CYGPATH_W) 'libarchive/archive_options.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_options.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_options.Tpo libarchive/$(DEPDIR)/test-archive_options.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_options.c' object='libarchive/test-archive_options.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_options.obj `if test -f 'libarchive/archive_options.c'; then $(CYGPATH_W) 'libarchive/archive_options.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_options.c'; fi` - -libarchive/test-archive_pack_dev.o: libarchive/archive_pack_dev.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_pack_dev.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_pack_dev.Tpo -c -o libarchive/test-archive_pack_dev.o `test -f 'libarchive/archive_pack_dev.c' || echo '$(srcdir)/'`libarchive/archive_pack_dev.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_pack_dev.Tpo libarchive/$(DEPDIR)/test-archive_pack_dev.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_pack_dev.c' object='libarchive/test-archive_pack_dev.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_pack_dev.o `test -f 'libarchive/archive_pack_dev.c' || echo '$(srcdir)/'`libarchive/archive_pack_dev.c - -libarchive/test-archive_pack_dev.obj: libarchive/archive_pack_dev.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_pack_dev.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_pack_dev.Tpo -c -o libarchive/test-archive_pack_dev.obj `if test -f 'libarchive/archive_pack_dev.c'; then $(CYGPATH_W) 'libarchive/archive_pack_dev.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_pack_dev.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_pack_dev.Tpo libarchive/$(DEPDIR)/test-archive_pack_dev.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_pack_dev.c' object='libarchive/test-archive_pack_dev.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_pack_dev.obj `if test -f 'libarchive/archive_pack_dev.c'; then $(CYGPATH_W) 'libarchive/archive_pack_dev.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_pack_dev.c'; fi` - -libarchive/test-archive_pathmatch.o: libarchive/archive_pathmatch.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_pathmatch.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_pathmatch.Tpo -c -o libarchive/test-archive_pathmatch.o `test -f 'libarchive/archive_pathmatch.c' || echo '$(srcdir)/'`libarchive/archive_pathmatch.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_pathmatch.Tpo libarchive/$(DEPDIR)/test-archive_pathmatch.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_pathmatch.c' object='libarchive/test-archive_pathmatch.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_pathmatch.o `test -f 'libarchive/archive_pathmatch.c' || echo '$(srcdir)/'`libarchive/archive_pathmatch.c - -libarchive/test-archive_pathmatch.obj: libarchive/archive_pathmatch.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_pathmatch.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_pathmatch.Tpo -c -o libarchive/test-archive_pathmatch.obj `if test -f 'libarchive/archive_pathmatch.c'; then $(CYGPATH_W) 'libarchive/archive_pathmatch.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_pathmatch.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_pathmatch.Tpo libarchive/$(DEPDIR)/test-archive_pathmatch.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_pathmatch.c' object='libarchive/test-archive_pathmatch.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_pathmatch.obj `if test -f 'libarchive/archive_pathmatch.c'; then $(CYGPATH_W) 'libarchive/archive_pathmatch.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_pathmatch.c'; fi` - -libarchive/test-archive_ppmd7.o: libarchive/archive_ppmd7.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_ppmd7.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_ppmd7.Tpo -c -o libarchive/test-archive_ppmd7.o `test -f 'libarchive/archive_ppmd7.c' || echo '$(srcdir)/'`libarchive/archive_ppmd7.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_ppmd7.Tpo libarchive/$(DEPDIR)/test-archive_ppmd7.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_ppmd7.c' object='libarchive/test-archive_ppmd7.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_ppmd7.o `test -f 'libarchive/archive_ppmd7.c' || echo '$(srcdir)/'`libarchive/archive_ppmd7.c - -libarchive/test-archive_ppmd7.obj: libarchive/archive_ppmd7.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_ppmd7.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_ppmd7.Tpo -c -o libarchive/test-archive_ppmd7.obj `if test -f 'libarchive/archive_ppmd7.c'; then $(CYGPATH_W) 'libarchive/archive_ppmd7.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_ppmd7.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_ppmd7.Tpo libarchive/$(DEPDIR)/test-archive_ppmd7.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_ppmd7.c' object='libarchive/test-archive_ppmd7.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_ppmd7.obj `if test -f 'libarchive/archive_ppmd7.c'; then $(CYGPATH_W) 'libarchive/archive_ppmd7.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_ppmd7.c'; fi` - -libarchive/test-archive_ppmd8.o: libarchive/archive_ppmd8.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_ppmd8.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_ppmd8.Tpo -c -o libarchive/test-archive_ppmd8.o `test -f 'libarchive/archive_ppmd8.c' || echo '$(srcdir)/'`libarchive/archive_ppmd8.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_ppmd8.Tpo libarchive/$(DEPDIR)/test-archive_ppmd8.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_ppmd8.c' object='libarchive/test-archive_ppmd8.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_ppmd8.o `test -f 'libarchive/archive_ppmd8.c' || echo '$(srcdir)/'`libarchive/archive_ppmd8.c - -libarchive/test-archive_ppmd8.obj: libarchive/archive_ppmd8.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_ppmd8.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_ppmd8.Tpo -c -o libarchive/test-archive_ppmd8.obj `if test -f 'libarchive/archive_ppmd8.c'; then $(CYGPATH_W) 'libarchive/archive_ppmd8.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_ppmd8.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_ppmd8.Tpo libarchive/$(DEPDIR)/test-archive_ppmd8.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_ppmd8.c' object='libarchive/test-archive_ppmd8.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_ppmd8.obj `if test -f 'libarchive/archive_ppmd8.c'; then $(CYGPATH_W) 'libarchive/archive_ppmd8.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_ppmd8.c'; fi` - -libarchive/test-archive_random.o: libarchive/archive_random.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_random.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_random.Tpo -c -o libarchive/test-archive_random.o `test -f 'libarchive/archive_random.c' || echo '$(srcdir)/'`libarchive/archive_random.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_random.Tpo libarchive/$(DEPDIR)/test-archive_random.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_random.c' object='libarchive/test-archive_random.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_random.o `test -f 'libarchive/archive_random.c' || echo '$(srcdir)/'`libarchive/archive_random.c - -libarchive/test-archive_random.obj: libarchive/archive_random.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_random.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_random.Tpo -c -o libarchive/test-archive_random.obj `if test -f 'libarchive/archive_random.c'; then $(CYGPATH_W) 'libarchive/archive_random.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_random.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_random.Tpo libarchive/$(DEPDIR)/test-archive_random.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_random.c' object='libarchive/test-archive_random.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_random.obj `if test -f 'libarchive/archive_random.c'; then $(CYGPATH_W) 'libarchive/archive_random.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_random.c'; fi` - -libarchive/test-archive_rb.o: libarchive/archive_rb.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_rb.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_rb.Tpo -c -o libarchive/test-archive_rb.o `test -f 'libarchive/archive_rb.c' || echo '$(srcdir)/'`libarchive/archive_rb.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_rb.Tpo libarchive/$(DEPDIR)/test-archive_rb.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_rb.c' object='libarchive/test-archive_rb.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_rb.o `test -f 'libarchive/archive_rb.c' || echo '$(srcdir)/'`libarchive/archive_rb.c - -libarchive/test-archive_rb.obj: libarchive/archive_rb.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_rb.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_rb.Tpo -c -o libarchive/test-archive_rb.obj `if test -f 'libarchive/archive_rb.c'; then $(CYGPATH_W) 'libarchive/archive_rb.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_rb.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_rb.Tpo libarchive/$(DEPDIR)/test-archive_rb.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_rb.c' object='libarchive/test-archive_rb.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_rb.obj `if test -f 'libarchive/archive_rb.c'; then $(CYGPATH_W) 'libarchive/archive_rb.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_rb.c'; fi` - -libarchive/test-archive_read.o: libarchive/archive_read.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read.Tpo -c -o libarchive/test-archive_read.o `test -f 'libarchive/archive_read.c' || echo '$(srcdir)/'`libarchive/archive_read.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read.Tpo libarchive/$(DEPDIR)/test-archive_read.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read.c' object='libarchive/test-archive_read.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read.o `test -f 'libarchive/archive_read.c' || echo '$(srcdir)/'`libarchive/archive_read.c - -libarchive/test-archive_read.obj: libarchive/archive_read.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read.Tpo -c -o libarchive/test-archive_read.obj `if test -f 'libarchive/archive_read.c'; then $(CYGPATH_W) 'libarchive/archive_read.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read.Tpo libarchive/$(DEPDIR)/test-archive_read.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read.c' object='libarchive/test-archive_read.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read.obj `if test -f 'libarchive/archive_read.c'; then $(CYGPATH_W) 'libarchive/archive_read.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read.c'; fi` - -libarchive/test-archive_read_add_passphrase.o: libarchive/archive_read_add_passphrase.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_add_passphrase.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_add_passphrase.Tpo -c -o libarchive/test-archive_read_add_passphrase.o `test -f 'libarchive/archive_read_add_passphrase.c' || echo '$(srcdir)/'`libarchive/archive_read_add_passphrase.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_add_passphrase.Tpo libarchive/$(DEPDIR)/test-archive_read_add_passphrase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_add_passphrase.c' object='libarchive/test-archive_read_add_passphrase.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_add_passphrase.o `test -f 'libarchive/archive_read_add_passphrase.c' || echo '$(srcdir)/'`libarchive/archive_read_add_passphrase.c - -libarchive/test-archive_read_add_passphrase.obj: libarchive/archive_read_add_passphrase.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_add_passphrase.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_add_passphrase.Tpo -c -o libarchive/test-archive_read_add_passphrase.obj `if test -f 'libarchive/archive_read_add_passphrase.c'; then $(CYGPATH_W) 'libarchive/archive_read_add_passphrase.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_add_passphrase.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_add_passphrase.Tpo libarchive/$(DEPDIR)/test-archive_read_add_passphrase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_add_passphrase.c' object='libarchive/test-archive_read_add_passphrase.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_add_passphrase.obj `if test -f 'libarchive/archive_read_add_passphrase.c'; then $(CYGPATH_W) 'libarchive/archive_read_add_passphrase.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_add_passphrase.c'; fi` - -libarchive/test-archive_read_append_filter.o: libarchive/archive_read_append_filter.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_append_filter.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_append_filter.Tpo -c -o libarchive/test-archive_read_append_filter.o `test -f 'libarchive/archive_read_append_filter.c' || echo '$(srcdir)/'`libarchive/archive_read_append_filter.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_append_filter.Tpo libarchive/$(DEPDIR)/test-archive_read_append_filter.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_append_filter.c' object='libarchive/test-archive_read_append_filter.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_append_filter.o `test -f 'libarchive/archive_read_append_filter.c' || echo '$(srcdir)/'`libarchive/archive_read_append_filter.c - -libarchive/test-archive_read_append_filter.obj: libarchive/archive_read_append_filter.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_append_filter.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_append_filter.Tpo -c -o libarchive/test-archive_read_append_filter.obj `if test -f 'libarchive/archive_read_append_filter.c'; then $(CYGPATH_W) 'libarchive/archive_read_append_filter.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_append_filter.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_append_filter.Tpo libarchive/$(DEPDIR)/test-archive_read_append_filter.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_append_filter.c' object='libarchive/test-archive_read_append_filter.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_append_filter.obj `if test -f 'libarchive/archive_read_append_filter.c'; then $(CYGPATH_W) 'libarchive/archive_read_append_filter.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_append_filter.c'; fi` - -libarchive/test-archive_read_data_into_fd.o: libarchive/archive_read_data_into_fd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_data_into_fd.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_data_into_fd.Tpo -c -o libarchive/test-archive_read_data_into_fd.o `test -f 'libarchive/archive_read_data_into_fd.c' || echo '$(srcdir)/'`libarchive/archive_read_data_into_fd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_data_into_fd.Tpo libarchive/$(DEPDIR)/test-archive_read_data_into_fd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_data_into_fd.c' object='libarchive/test-archive_read_data_into_fd.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_data_into_fd.o `test -f 'libarchive/archive_read_data_into_fd.c' || echo '$(srcdir)/'`libarchive/archive_read_data_into_fd.c - -libarchive/test-archive_read_data_into_fd.obj: libarchive/archive_read_data_into_fd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_data_into_fd.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_data_into_fd.Tpo -c -o libarchive/test-archive_read_data_into_fd.obj `if test -f 'libarchive/archive_read_data_into_fd.c'; then $(CYGPATH_W) 'libarchive/archive_read_data_into_fd.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_data_into_fd.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_data_into_fd.Tpo libarchive/$(DEPDIR)/test-archive_read_data_into_fd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_data_into_fd.c' object='libarchive/test-archive_read_data_into_fd.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_data_into_fd.obj `if test -f 'libarchive/archive_read_data_into_fd.c'; then $(CYGPATH_W) 'libarchive/archive_read_data_into_fd.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_data_into_fd.c'; fi` - -libarchive/test-archive_read_disk_entry_from_file.o: libarchive/archive_read_disk_entry_from_file.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_disk_entry_from_file.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_disk_entry_from_file.Tpo -c -o libarchive/test-archive_read_disk_entry_from_file.o `test -f 'libarchive/archive_read_disk_entry_from_file.c' || echo '$(srcdir)/'`libarchive/archive_read_disk_entry_from_file.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_disk_entry_from_file.Tpo libarchive/$(DEPDIR)/test-archive_read_disk_entry_from_file.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_disk_entry_from_file.c' object='libarchive/test-archive_read_disk_entry_from_file.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_disk_entry_from_file.o `test -f 'libarchive/archive_read_disk_entry_from_file.c' || echo '$(srcdir)/'`libarchive/archive_read_disk_entry_from_file.c - -libarchive/test-archive_read_disk_entry_from_file.obj: libarchive/archive_read_disk_entry_from_file.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_disk_entry_from_file.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_disk_entry_from_file.Tpo -c -o libarchive/test-archive_read_disk_entry_from_file.obj `if test -f 'libarchive/archive_read_disk_entry_from_file.c'; then $(CYGPATH_W) 'libarchive/archive_read_disk_entry_from_file.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_disk_entry_from_file.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_disk_entry_from_file.Tpo libarchive/$(DEPDIR)/test-archive_read_disk_entry_from_file.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_disk_entry_from_file.c' object='libarchive/test-archive_read_disk_entry_from_file.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_disk_entry_from_file.obj `if test -f 'libarchive/archive_read_disk_entry_from_file.c'; then $(CYGPATH_W) 'libarchive/archive_read_disk_entry_from_file.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_disk_entry_from_file.c'; fi` - -libarchive/test-archive_read_disk_posix.o: libarchive/archive_read_disk_posix.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_disk_posix.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_disk_posix.Tpo -c -o libarchive/test-archive_read_disk_posix.o `test -f 'libarchive/archive_read_disk_posix.c' || echo '$(srcdir)/'`libarchive/archive_read_disk_posix.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_disk_posix.Tpo libarchive/$(DEPDIR)/test-archive_read_disk_posix.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_disk_posix.c' object='libarchive/test-archive_read_disk_posix.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_disk_posix.o `test -f 'libarchive/archive_read_disk_posix.c' || echo '$(srcdir)/'`libarchive/archive_read_disk_posix.c - -libarchive/test-archive_read_disk_posix.obj: libarchive/archive_read_disk_posix.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_disk_posix.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_disk_posix.Tpo -c -o libarchive/test-archive_read_disk_posix.obj `if test -f 'libarchive/archive_read_disk_posix.c'; then $(CYGPATH_W) 'libarchive/archive_read_disk_posix.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_disk_posix.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_disk_posix.Tpo libarchive/$(DEPDIR)/test-archive_read_disk_posix.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_disk_posix.c' object='libarchive/test-archive_read_disk_posix.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_disk_posix.obj `if test -f 'libarchive/archive_read_disk_posix.c'; then $(CYGPATH_W) 'libarchive/archive_read_disk_posix.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_disk_posix.c'; fi` - -libarchive/test-archive_read_disk_set_standard_lookup.o: libarchive/archive_read_disk_set_standard_lookup.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_disk_set_standard_lookup.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_disk_set_standard_lookup.Tpo -c -o libarchive/test-archive_read_disk_set_standard_lookup.o `test -f 'libarchive/archive_read_disk_set_standard_lookup.c' || echo '$(srcdir)/'`libarchive/archive_read_disk_set_standard_lookup.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_disk_set_standard_lookup.Tpo libarchive/$(DEPDIR)/test-archive_read_disk_set_standard_lookup.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_disk_set_standard_lookup.c' object='libarchive/test-archive_read_disk_set_standard_lookup.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_disk_set_standard_lookup.o `test -f 'libarchive/archive_read_disk_set_standard_lookup.c' || echo '$(srcdir)/'`libarchive/archive_read_disk_set_standard_lookup.c - -libarchive/test-archive_read_disk_set_standard_lookup.obj: libarchive/archive_read_disk_set_standard_lookup.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_disk_set_standard_lookup.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_disk_set_standard_lookup.Tpo -c -o libarchive/test-archive_read_disk_set_standard_lookup.obj `if test -f 'libarchive/archive_read_disk_set_standard_lookup.c'; then $(CYGPATH_W) 'libarchive/archive_read_disk_set_standard_lookup.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_disk_set_standard_lookup.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_disk_set_standard_lookup.Tpo libarchive/$(DEPDIR)/test-archive_read_disk_set_standard_lookup.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_disk_set_standard_lookup.c' object='libarchive/test-archive_read_disk_set_standard_lookup.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_disk_set_standard_lookup.obj `if test -f 'libarchive/archive_read_disk_set_standard_lookup.c'; then $(CYGPATH_W) 'libarchive/archive_read_disk_set_standard_lookup.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_disk_set_standard_lookup.c'; fi` - -libarchive/test-archive_read_extract.o: libarchive/archive_read_extract.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_extract.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_extract.Tpo -c -o libarchive/test-archive_read_extract.o `test -f 'libarchive/archive_read_extract.c' || echo '$(srcdir)/'`libarchive/archive_read_extract.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_extract.Tpo libarchive/$(DEPDIR)/test-archive_read_extract.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_extract.c' object='libarchive/test-archive_read_extract.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_extract.o `test -f 'libarchive/archive_read_extract.c' || echo '$(srcdir)/'`libarchive/archive_read_extract.c - -libarchive/test-archive_read_extract.obj: libarchive/archive_read_extract.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_extract.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_extract.Tpo -c -o libarchive/test-archive_read_extract.obj `if test -f 'libarchive/archive_read_extract.c'; then $(CYGPATH_W) 'libarchive/archive_read_extract.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_extract.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_extract.Tpo libarchive/$(DEPDIR)/test-archive_read_extract.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_extract.c' object='libarchive/test-archive_read_extract.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_extract.obj `if test -f 'libarchive/archive_read_extract.c'; then $(CYGPATH_W) 'libarchive/archive_read_extract.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_extract.c'; fi` - -libarchive/test-archive_read_extract2.o: libarchive/archive_read_extract2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_extract2.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_extract2.Tpo -c -o libarchive/test-archive_read_extract2.o `test -f 'libarchive/archive_read_extract2.c' || echo '$(srcdir)/'`libarchive/archive_read_extract2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_extract2.Tpo libarchive/$(DEPDIR)/test-archive_read_extract2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_extract2.c' object='libarchive/test-archive_read_extract2.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_extract2.o `test -f 'libarchive/archive_read_extract2.c' || echo '$(srcdir)/'`libarchive/archive_read_extract2.c - -libarchive/test-archive_read_extract2.obj: libarchive/archive_read_extract2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_extract2.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_extract2.Tpo -c -o libarchive/test-archive_read_extract2.obj `if test -f 'libarchive/archive_read_extract2.c'; then $(CYGPATH_W) 'libarchive/archive_read_extract2.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_extract2.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_extract2.Tpo libarchive/$(DEPDIR)/test-archive_read_extract2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_extract2.c' object='libarchive/test-archive_read_extract2.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_extract2.obj `if test -f 'libarchive/archive_read_extract2.c'; then $(CYGPATH_W) 'libarchive/archive_read_extract2.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_extract2.c'; fi` - -libarchive/test-archive_read_open_fd.o: libarchive/archive_read_open_fd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_open_fd.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_open_fd.Tpo -c -o libarchive/test-archive_read_open_fd.o `test -f 'libarchive/archive_read_open_fd.c' || echo '$(srcdir)/'`libarchive/archive_read_open_fd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_open_fd.Tpo libarchive/$(DEPDIR)/test-archive_read_open_fd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_open_fd.c' object='libarchive/test-archive_read_open_fd.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_open_fd.o `test -f 'libarchive/archive_read_open_fd.c' || echo '$(srcdir)/'`libarchive/archive_read_open_fd.c - -libarchive/test-archive_read_open_fd.obj: libarchive/archive_read_open_fd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_open_fd.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_open_fd.Tpo -c -o libarchive/test-archive_read_open_fd.obj `if test -f 'libarchive/archive_read_open_fd.c'; then $(CYGPATH_W) 'libarchive/archive_read_open_fd.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_open_fd.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_open_fd.Tpo libarchive/$(DEPDIR)/test-archive_read_open_fd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_open_fd.c' object='libarchive/test-archive_read_open_fd.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_open_fd.obj `if test -f 'libarchive/archive_read_open_fd.c'; then $(CYGPATH_W) 'libarchive/archive_read_open_fd.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_open_fd.c'; fi` - -libarchive/test-archive_read_open_file.o: libarchive/archive_read_open_file.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_open_file.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_open_file.Tpo -c -o libarchive/test-archive_read_open_file.o `test -f 'libarchive/archive_read_open_file.c' || echo '$(srcdir)/'`libarchive/archive_read_open_file.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_open_file.Tpo libarchive/$(DEPDIR)/test-archive_read_open_file.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_open_file.c' object='libarchive/test-archive_read_open_file.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_open_file.o `test -f 'libarchive/archive_read_open_file.c' || echo '$(srcdir)/'`libarchive/archive_read_open_file.c - -libarchive/test-archive_read_open_file.obj: libarchive/archive_read_open_file.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_open_file.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_open_file.Tpo -c -o libarchive/test-archive_read_open_file.obj `if test -f 'libarchive/archive_read_open_file.c'; then $(CYGPATH_W) 'libarchive/archive_read_open_file.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_open_file.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_open_file.Tpo libarchive/$(DEPDIR)/test-archive_read_open_file.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_open_file.c' object='libarchive/test-archive_read_open_file.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_open_file.obj `if test -f 'libarchive/archive_read_open_file.c'; then $(CYGPATH_W) 'libarchive/archive_read_open_file.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_open_file.c'; fi` - -libarchive/test-archive_read_open_filename.o: libarchive/archive_read_open_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_open_filename.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_open_filename.Tpo -c -o libarchive/test-archive_read_open_filename.o `test -f 'libarchive/archive_read_open_filename.c' || echo '$(srcdir)/'`libarchive/archive_read_open_filename.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_open_filename.Tpo libarchive/$(DEPDIR)/test-archive_read_open_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_open_filename.c' object='libarchive/test-archive_read_open_filename.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_open_filename.o `test -f 'libarchive/archive_read_open_filename.c' || echo '$(srcdir)/'`libarchive/archive_read_open_filename.c - -libarchive/test-archive_read_open_filename.obj: libarchive/archive_read_open_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_open_filename.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_open_filename.Tpo -c -o libarchive/test-archive_read_open_filename.obj `if test -f 'libarchive/archive_read_open_filename.c'; then $(CYGPATH_W) 'libarchive/archive_read_open_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_open_filename.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_open_filename.Tpo libarchive/$(DEPDIR)/test-archive_read_open_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_open_filename.c' object='libarchive/test-archive_read_open_filename.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_open_filename.obj `if test -f 'libarchive/archive_read_open_filename.c'; then $(CYGPATH_W) 'libarchive/archive_read_open_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_open_filename.c'; fi` - -libarchive/test-archive_read_open_memory.o: libarchive/archive_read_open_memory.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_open_memory.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_open_memory.Tpo -c -o libarchive/test-archive_read_open_memory.o `test -f 'libarchive/archive_read_open_memory.c' || echo '$(srcdir)/'`libarchive/archive_read_open_memory.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_open_memory.Tpo libarchive/$(DEPDIR)/test-archive_read_open_memory.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_open_memory.c' object='libarchive/test-archive_read_open_memory.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_open_memory.o `test -f 'libarchive/archive_read_open_memory.c' || echo '$(srcdir)/'`libarchive/archive_read_open_memory.c - -libarchive/test-archive_read_open_memory.obj: libarchive/archive_read_open_memory.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_open_memory.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_open_memory.Tpo -c -o libarchive/test-archive_read_open_memory.obj `if test -f 'libarchive/archive_read_open_memory.c'; then $(CYGPATH_W) 'libarchive/archive_read_open_memory.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_open_memory.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_open_memory.Tpo libarchive/$(DEPDIR)/test-archive_read_open_memory.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_open_memory.c' object='libarchive/test-archive_read_open_memory.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_open_memory.obj `if test -f 'libarchive/archive_read_open_memory.c'; then $(CYGPATH_W) 'libarchive/archive_read_open_memory.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_open_memory.c'; fi` - -libarchive/test-archive_read_set_format.o: libarchive/archive_read_set_format.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_set_format.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_set_format.Tpo -c -o libarchive/test-archive_read_set_format.o `test -f 'libarchive/archive_read_set_format.c' || echo '$(srcdir)/'`libarchive/archive_read_set_format.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_set_format.Tpo libarchive/$(DEPDIR)/test-archive_read_set_format.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_set_format.c' object='libarchive/test-archive_read_set_format.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_set_format.o `test -f 'libarchive/archive_read_set_format.c' || echo '$(srcdir)/'`libarchive/archive_read_set_format.c - -libarchive/test-archive_read_set_format.obj: libarchive/archive_read_set_format.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_set_format.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_set_format.Tpo -c -o libarchive/test-archive_read_set_format.obj `if test -f 'libarchive/archive_read_set_format.c'; then $(CYGPATH_W) 'libarchive/archive_read_set_format.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_set_format.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_set_format.Tpo libarchive/$(DEPDIR)/test-archive_read_set_format.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_set_format.c' object='libarchive/test-archive_read_set_format.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_set_format.obj `if test -f 'libarchive/archive_read_set_format.c'; then $(CYGPATH_W) 'libarchive/archive_read_set_format.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_set_format.c'; fi` - -libarchive/test-archive_read_set_options.o: libarchive/archive_read_set_options.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_set_options.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_set_options.Tpo -c -o libarchive/test-archive_read_set_options.o `test -f 'libarchive/archive_read_set_options.c' || echo '$(srcdir)/'`libarchive/archive_read_set_options.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_set_options.Tpo libarchive/$(DEPDIR)/test-archive_read_set_options.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_set_options.c' object='libarchive/test-archive_read_set_options.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_set_options.o `test -f 'libarchive/archive_read_set_options.c' || echo '$(srcdir)/'`libarchive/archive_read_set_options.c - -libarchive/test-archive_read_set_options.obj: libarchive/archive_read_set_options.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_set_options.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_set_options.Tpo -c -o libarchive/test-archive_read_set_options.obj `if test -f 'libarchive/archive_read_set_options.c'; then $(CYGPATH_W) 'libarchive/archive_read_set_options.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_set_options.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_set_options.Tpo libarchive/$(DEPDIR)/test-archive_read_set_options.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_set_options.c' object='libarchive/test-archive_read_set_options.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_set_options.obj `if test -f 'libarchive/archive_read_set_options.c'; then $(CYGPATH_W) 'libarchive/archive_read_set_options.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_set_options.c'; fi` - -libarchive/test-archive_read_support_filter_all.o: libarchive/archive_read_support_filter_all.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_all.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_all.Tpo -c -o libarchive/test-archive_read_support_filter_all.o `test -f 'libarchive/archive_read_support_filter_all.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_all.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_all.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_all.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_all.c' object='libarchive/test-archive_read_support_filter_all.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_all.o `test -f 'libarchive/archive_read_support_filter_all.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_all.c - -libarchive/test-archive_read_support_filter_all.obj: libarchive/archive_read_support_filter_all.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_all.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_all.Tpo -c -o libarchive/test-archive_read_support_filter_all.obj `if test -f 'libarchive/archive_read_support_filter_all.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_all.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_all.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_all.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_all.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_all.c' object='libarchive/test-archive_read_support_filter_all.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_all.obj `if test -f 'libarchive/archive_read_support_filter_all.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_all.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_all.c'; fi` - -libarchive/test-archive_read_support_filter_bzip2.o: libarchive/archive_read_support_filter_bzip2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_bzip2.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_bzip2.Tpo -c -o libarchive/test-archive_read_support_filter_bzip2.o `test -f 'libarchive/archive_read_support_filter_bzip2.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_bzip2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_bzip2.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_bzip2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_bzip2.c' object='libarchive/test-archive_read_support_filter_bzip2.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_bzip2.o `test -f 'libarchive/archive_read_support_filter_bzip2.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_bzip2.c - -libarchive/test-archive_read_support_filter_bzip2.obj: libarchive/archive_read_support_filter_bzip2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_bzip2.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_bzip2.Tpo -c -o libarchive/test-archive_read_support_filter_bzip2.obj `if test -f 'libarchive/archive_read_support_filter_bzip2.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_bzip2.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_bzip2.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_bzip2.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_bzip2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_bzip2.c' object='libarchive/test-archive_read_support_filter_bzip2.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_bzip2.obj `if test -f 'libarchive/archive_read_support_filter_bzip2.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_bzip2.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_bzip2.c'; fi` - -libarchive/test-archive_read_support_filter_by_code.o: libarchive/archive_read_support_filter_by_code.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_by_code.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_by_code.Tpo -c -o libarchive/test-archive_read_support_filter_by_code.o `test -f 'libarchive/archive_read_support_filter_by_code.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_by_code.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_by_code.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_by_code.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_by_code.c' object='libarchive/test-archive_read_support_filter_by_code.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_by_code.o `test -f 'libarchive/archive_read_support_filter_by_code.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_by_code.c - -libarchive/test-archive_read_support_filter_by_code.obj: libarchive/archive_read_support_filter_by_code.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_by_code.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_by_code.Tpo -c -o libarchive/test-archive_read_support_filter_by_code.obj `if test -f 'libarchive/archive_read_support_filter_by_code.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_by_code.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_by_code.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_by_code.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_by_code.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_by_code.c' object='libarchive/test-archive_read_support_filter_by_code.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_by_code.obj `if test -f 'libarchive/archive_read_support_filter_by_code.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_by_code.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_by_code.c'; fi` - -libarchive/test-archive_read_support_filter_compress.o: libarchive/archive_read_support_filter_compress.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_compress.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_compress.Tpo -c -o libarchive/test-archive_read_support_filter_compress.o `test -f 'libarchive/archive_read_support_filter_compress.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_compress.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_compress.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_compress.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_compress.c' object='libarchive/test-archive_read_support_filter_compress.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_compress.o `test -f 'libarchive/archive_read_support_filter_compress.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_compress.c - -libarchive/test-archive_read_support_filter_compress.obj: libarchive/archive_read_support_filter_compress.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_compress.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_compress.Tpo -c -o libarchive/test-archive_read_support_filter_compress.obj `if test -f 'libarchive/archive_read_support_filter_compress.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_compress.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_compress.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_compress.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_compress.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_compress.c' object='libarchive/test-archive_read_support_filter_compress.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_compress.obj `if test -f 'libarchive/archive_read_support_filter_compress.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_compress.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_compress.c'; fi` - -libarchive/test-archive_read_support_filter_grzip.o: libarchive/archive_read_support_filter_grzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_grzip.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_grzip.Tpo -c -o libarchive/test-archive_read_support_filter_grzip.o `test -f 'libarchive/archive_read_support_filter_grzip.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_grzip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_grzip.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_grzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_grzip.c' object='libarchive/test-archive_read_support_filter_grzip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_grzip.o `test -f 'libarchive/archive_read_support_filter_grzip.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_grzip.c - -libarchive/test-archive_read_support_filter_grzip.obj: libarchive/archive_read_support_filter_grzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_grzip.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_grzip.Tpo -c -o libarchive/test-archive_read_support_filter_grzip.obj `if test -f 'libarchive/archive_read_support_filter_grzip.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_grzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_grzip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_grzip.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_grzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_grzip.c' object='libarchive/test-archive_read_support_filter_grzip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_grzip.obj `if test -f 'libarchive/archive_read_support_filter_grzip.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_grzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_grzip.c'; fi` - -libarchive/test-archive_read_support_filter_gzip.o: libarchive/archive_read_support_filter_gzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_gzip.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_gzip.Tpo -c -o libarchive/test-archive_read_support_filter_gzip.o `test -f 'libarchive/archive_read_support_filter_gzip.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_gzip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_gzip.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_gzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_gzip.c' object='libarchive/test-archive_read_support_filter_gzip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_gzip.o `test -f 'libarchive/archive_read_support_filter_gzip.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_gzip.c - -libarchive/test-archive_read_support_filter_gzip.obj: libarchive/archive_read_support_filter_gzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_gzip.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_gzip.Tpo -c -o libarchive/test-archive_read_support_filter_gzip.obj `if test -f 'libarchive/archive_read_support_filter_gzip.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_gzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_gzip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_gzip.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_gzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_gzip.c' object='libarchive/test-archive_read_support_filter_gzip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_gzip.obj `if test -f 'libarchive/archive_read_support_filter_gzip.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_gzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_gzip.c'; fi` - -libarchive/test-archive_read_support_filter_lrzip.o: libarchive/archive_read_support_filter_lrzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_lrzip.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_lrzip.Tpo -c -o libarchive/test-archive_read_support_filter_lrzip.o `test -f 'libarchive/archive_read_support_filter_lrzip.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_lrzip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_lrzip.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_lrzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_lrzip.c' object='libarchive/test-archive_read_support_filter_lrzip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_lrzip.o `test -f 'libarchive/archive_read_support_filter_lrzip.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_lrzip.c - -libarchive/test-archive_read_support_filter_lrzip.obj: libarchive/archive_read_support_filter_lrzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_lrzip.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_lrzip.Tpo -c -o libarchive/test-archive_read_support_filter_lrzip.obj `if test -f 'libarchive/archive_read_support_filter_lrzip.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_lrzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_lrzip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_lrzip.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_lrzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_lrzip.c' object='libarchive/test-archive_read_support_filter_lrzip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_lrzip.obj `if test -f 'libarchive/archive_read_support_filter_lrzip.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_lrzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_lrzip.c'; fi` - -libarchive/test-archive_read_support_filter_lz4.o: libarchive/archive_read_support_filter_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_lz4.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_lz4.Tpo -c -o libarchive/test-archive_read_support_filter_lz4.o `test -f 'libarchive/archive_read_support_filter_lz4.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_lz4.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_lz4.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_lz4.c' object='libarchive/test-archive_read_support_filter_lz4.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_lz4.o `test -f 'libarchive/archive_read_support_filter_lz4.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_lz4.c - -libarchive/test-archive_read_support_filter_lz4.obj: libarchive/archive_read_support_filter_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_lz4.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_lz4.Tpo -c -o libarchive/test-archive_read_support_filter_lz4.obj `if test -f 'libarchive/archive_read_support_filter_lz4.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_lz4.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_lz4.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_lz4.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_lz4.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_lz4.c' object='libarchive/test-archive_read_support_filter_lz4.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_lz4.obj `if test -f 'libarchive/archive_read_support_filter_lz4.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_lz4.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_lz4.c'; fi` - -libarchive/test-archive_read_support_filter_lzop.o: libarchive/archive_read_support_filter_lzop.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_lzop.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_lzop.Tpo -c -o libarchive/test-archive_read_support_filter_lzop.o `test -f 'libarchive/archive_read_support_filter_lzop.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_lzop.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_lzop.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_lzop.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_lzop.c' object='libarchive/test-archive_read_support_filter_lzop.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_lzop.o `test -f 'libarchive/archive_read_support_filter_lzop.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_lzop.c - -libarchive/test-archive_read_support_filter_lzop.obj: libarchive/archive_read_support_filter_lzop.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_lzop.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_lzop.Tpo -c -o libarchive/test-archive_read_support_filter_lzop.obj `if test -f 'libarchive/archive_read_support_filter_lzop.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_lzop.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_lzop.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_lzop.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_lzop.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_lzop.c' object='libarchive/test-archive_read_support_filter_lzop.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_lzop.obj `if test -f 'libarchive/archive_read_support_filter_lzop.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_lzop.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_lzop.c'; fi` - -libarchive/test-archive_read_support_filter_none.o: libarchive/archive_read_support_filter_none.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_none.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_none.Tpo -c -o libarchive/test-archive_read_support_filter_none.o `test -f 'libarchive/archive_read_support_filter_none.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_none.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_none.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_none.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_none.c' object='libarchive/test-archive_read_support_filter_none.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_none.o `test -f 'libarchive/archive_read_support_filter_none.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_none.c - -libarchive/test-archive_read_support_filter_none.obj: libarchive/archive_read_support_filter_none.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_none.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_none.Tpo -c -o libarchive/test-archive_read_support_filter_none.obj `if test -f 'libarchive/archive_read_support_filter_none.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_none.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_none.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_none.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_none.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_none.c' object='libarchive/test-archive_read_support_filter_none.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_none.obj `if test -f 'libarchive/archive_read_support_filter_none.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_none.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_none.c'; fi` - -libarchive/test-archive_read_support_filter_program.o: libarchive/archive_read_support_filter_program.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_program.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_program.Tpo -c -o libarchive/test-archive_read_support_filter_program.o `test -f 'libarchive/archive_read_support_filter_program.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_program.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_program.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_program.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_program.c' object='libarchive/test-archive_read_support_filter_program.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_program.o `test -f 'libarchive/archive_read_support_filter_program.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_program.c - -libarchive/test-archive_read_support_filter_program.obj: libarchive/archive_read_support_filter_program.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_program.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_program.Tpo -c -o libarchive/test-archive_read_support_filter_program.obj `if test -f 'libarchive/archive_read_support_filter_program.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_program.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_program.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_program.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_program.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_program.c' object='libarchive/test-archive_read_support_filter_program.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_program.obj `if test -f 'libarchive/archive_read_support_filter_program.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_program.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_program.c'; fi` - -libarchive/test-archive_read_support_filter_rpm.o: libarchive/archive_read_support_filter_rpm.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_rpm.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_rpm.Tpo -c -o libarchive/test-archive_read_support_filter_rpm.o `test -f 'libarchive/archive_read_support_filter_rpm.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_rpm.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_rpm.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_rpm.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_rpm.c' object='libarchive/test-archive_read_support_filter_rpm.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_rpm.o `test -f 'libarchive/archive_read_support_filter_rpm.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_rpm.c - -libarchive/test-archive_read_support_filter_rpm.obj: libarchive/archive_read_support_filter_rpm.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_rpm.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_rpm.Tpo -c -o libarchive/test-archive_read_support_filter_rpm.obj `if test -f 'libarchive/archive_read_support_filter_rpm.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_rpm.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_rpm.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_rpm.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_rpm.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_rpm.c' object='libarchive/test-archive_read_support_filter_rpm.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_rpm.obj `if test -f 'libarchive/archive_read_support_filter_rpm.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_rpm.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_rpm.c'; fi` - -libarchive/test-archive_read_support_filter_uu.o: libarchive/archive_read_support_filter_uu.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_uu.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_uu.Tpo -c -o libarchive/test-archive_read_support_filter_uu.o `test -f 'libarchive/archive_read_support_filter_uu.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_uu.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_uu.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_uu.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_uu.c' object='libarchive/test-archive_read_support_filter_uu.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_uu.o `test -f 'libarchive/archive_read_support_filter_uu.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_uu.c - -libarchive/test-archive_read_support_filter_uu.obj: libarchive/archive_read_support_filter_uu.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_uu.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_uu.Tpo -c -o libarchive/test-archive_read_support_filter_uu.obj `if test -f 'libarchive/archive_read_support_filter_uu.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_uu.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_uu.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_uu.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_uu.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_uu.c' object='libarchive/test-archive_read_support_filter_uu.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_uu.obj `if test -f 'libarchive/archive_read_support_filter_uu.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_uu.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_uu.c'; fi` - -libarchive/test-archive_read_support_filter_xz.o: libarchive/archive_read_support_filter_xz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_xz.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_xz.Tpo -c -o libarchive/test-archive_read_support_filter_xz.o `test -f 'libarchive/archive_read_support_filter_xz.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_xz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_xz.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_xz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_xz.c' object='libarchive/test-archive_read_support_filter_xz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_xz.o `test -f 'libarchive/archive_read_support_filter_xz.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_xz.c - -libarchive/test-archive_read_support_filter_xz.obj: libarchive/archive_read_support_filter_xz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_xz.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_xz.Tpo -c -o libarchive/test-archive_read_support_filter_xz.obj `if test -f 'libarchive/archive_read_support_filter_xz.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_xz.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_xz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_xz.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_xz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_xz.c' object='libarchive/test-archive_read_support_filter_xz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_xz.obj `if test -f 'libarchive/archive_read_support_filter_xz.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_xz.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_xz.c'; fi` - -libarchive/test-archive_read_support_filter_zstd.o: libarchive/archive_read_support_filter_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_zstd.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_zstd.Tpo -c -o libarchive/test-archive_read_support_filter_zstd.o `test -f 'libarchive/archive_read_support_filter_zstd.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_zstd.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_zstd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_zstd.c' object='libarchive/test-archive_read_support_filter_zstd.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_zstd.o `test -f 'libarchive/archive_read_support_filter_zstd.c' || echo '$(srcdir)/'`libarchive/archive_read_support_filter_zstd.c - -libarchive/test-archive_read_support_filter_zstd.obj: libarchive/archive_read_support_filter_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_filter_zstd.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_filter_zstd.Tpo -c -o libarchive/test-archive_read_support_filter_zstd.obj `if test -f 'libarchive/archive_read_support_filter_zstd.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_zstd.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_zstd.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_filter_zstd.Tpo libarchive/$(DEPDIR)/test-archive_read_support_filter_zstd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_filter_zstd.c' object='libarchive/test-archive_read_support_filter_zstd.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_filter_zstd.obj `if test -f 'libarchive/archive_read_support_filter_zstd.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_filter_zstd.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_filter_zstd.c'; fi` - -libarchive/test-archive_read_support_format_7zip.o: libarchive/archive_read_support_format_7zip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_7zip.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_7zip.Tpo -c -o libarchive/test-archive_read_support_format_7zip.o `test -f 'libarchive/archive_read_support_format_7zip.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_7zip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_7zip.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_7zip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_7zip.c' object='libarchive/test-archive_read_support_format_7zip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_7zip.o `test -f 'libarchive/archive_read_support_format_7zip.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_7zip.c - -libarchive/test-archive_read_support_format_7zip.obj: libarchive/archive_read_support_format_7zip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_7zip.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_7zip.Tpo -c -o libarchive/test-archive_read_support_format_7zip.obj `if test -f 'libarchive/archive_read_support_format_7zip.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_7zip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_7zip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_7zip.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_7zip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_7zip.c' object='libarchive/test-archive_read_support_format_7zip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_7zip.obj `if test -f 'libarchive/archive_read_support_format_7zip.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_7zip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_7zip.c'; fi` - -libarchive/test-archive_read_support_format_all.o: libarchive/archive_read_support_format_all.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_all.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_all.Tpo -c -o libarchive/test-archive_read_support_format_all.o `test -f 'libarchive/archive_read_support_format_all.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_all.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_all.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_all.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_all.c' object='libarchive/test-archive_read_support_format_all.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_all.o `test -f 'libarchive/archive_read_support_format_all.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_all.c - -libarchive/test-archive_read_support_format_all.obj: libarchive/archive_read_support_format_all.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_all.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_all.Tpo -c -o libarchive/test-archive_read_support_format_all.obj `if test -f 'libarchive/archive_read_support_format_all.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_all.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_all.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_all.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_all.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_all.c' object='libarchive/test-archive_read_support_format_all.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_all.obj `if test -f 'libarchive/archive_read_support_format_all.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_all.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_all.c'; fi` - -libarchive/test-archive_read_support_format_ar.o: libarchive/archive_read_support_format_ar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_ar.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_ar.Tpo -c -o libarchive/test-archive_read_support_format_ar.o `test -f 'libarchive/archive_read_support_format_ar.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_ar.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_ar.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_ar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_ar.c' object='libarchive/test-archive_read_support_format_ar.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_ar.o `test -f 'libarchive/archive_read_support_format_ar.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_ar.c - -libarchive/test-archive_read_support_format_ar.obj: libarchive/archive_read_support_format_ar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_ar.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_ar.Tpo -c -o libarchive/test-archive_read_support_format_ar.obj `if test -f 'libarchive/archive_read_support_format_ar.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_ar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_ar.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_ar.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_ar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_ar.c' object='libarchive/test-archive_read_support_format_ar.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_ar.obj `if test -f 'libarchive/archive_read_support_format_ar.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_ar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_ar.c'; fi` - -libarchive/test-archive_read_support_format_by_code.o: libarchive/archive_read_support_format_by_code.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_by_code.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_by_code.Tpo -c -o libarchive/test-archive_read_support_format_by_code.o `test -f 'libarchive/archive_read_support_format_by_code.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_by_code.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_by_code.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_by_code.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_by_code.c' object='libarchive/test-archive_read_support_format_by_code.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_by_code.o `test -f 'libarchive/archive_read_support_format_by_code.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_by_code.c - -libarchive/test-archive_read_support_format_by_code.obj: libarchive/archive_read_support_format_by_code.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_by_code.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_by_code.Tpo -c -o libarchive/test-archive_read_support_format_by_code.obj `if test -f 'libarchive/archive_read_support_format_by_code.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_by_code.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_by_code.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_by_code.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_by_code.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_by_code.c' object='libarchive/test-archive_read_support_format_by_code.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_by_code.obj `if test -f 'libarchive/archive_read_support_format_by_code.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_by_code.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_by_code.c'; fi` - -libarchive/test-archive_read_support_format_cab.o: libarchive/archive_read_support_format_cab.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_cab.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_cab.Tpo -c -o libarchive/test-archive_read_support_format_cab.o `test -f 'libarchive/archive_read_support_format_cab.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_cab.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_cab.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_cab.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_cab.c' object='libarchive/test-archive_read_support_format_cab.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_cab.o `test -f 'libarchive/archive_read_support_format_cab.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_cab.c - -libarchive/test-archive_read_support_format_cab.obj: libarchive/archive_read_support_format_cab.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_cab.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_cab.Tpo -c -o libarchive/test-archive_read_support_format_cab.obj `if test -f 'libarchive/archive_read_support_format_cab.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_cab.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_cab.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_cab.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_cab.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_cab.c' object='libarchive/test-archive_read_support_format_cab.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_cab.obj `if test -f 'libarchive/archive_read_support_format_cab.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_cab.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_cab.c'; fi` - -libarchive/test-archive_read_support_format_cpio.o: libarchive/archive_read_support_format_cpio.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_cpio.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_cpio.Tpo -c -o libarchive/test-archive_read_support_format_cpio.o `test -f 'libarchive/archive_read_support_format_cpio.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_cpio.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_cpio.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_cpio.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_cpio.c' object='libarchive/test-archive_read_support_format_cpio.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_cpio.o `test -f 'libarchive/archive_read_support_format_cpio.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_cpio.c - -libarchive/test-archive_read_support_format_cpio.obj: libarchive/archive_read_support_format_cpio.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_cpio.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_cpio.Tpo -c -o libarchive/test-archive_read_support_format_cpio.obj `if test -f 'libarchive/archive_read_support_format_cpio.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_cpio.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_cpio.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_cpio.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_cpio.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_cpio.c' object='libarchive/test-archive_read_support_format_cpio.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_cpio.obj `if test -f 'libarchive/archive_read_support_format_cpio.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_cpio.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_cpio.c'; fi` - -libarchive/test-archive_read_support_format_empty.o: libarchive/archive_read_support_format_empty.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_empty.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_empty.Tpo -c -o libarchive/test-archive_read_support_format_empty.o `test -f 'libarchive/archive_read_support_format_empty.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_empty.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_empty.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_empty.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_empty.c' object='libarchive/test-archive_read_support_format_empty.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_empty.o `test -f 'libarchive/archive_read_support_format_empty.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_empty.c - -libarchive/test-archive_read_support_format_empty.obj: libarchive/archive_read_support_format_empty.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_empty.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_empty.Tpo -c -o libarchive/test-archive_read_support_format_empty.obj `if test -f 'libarchive/archive_read_support_format_empty.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_empty.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_empty.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_empty.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_empty.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_empty.c' object='libarchive/test-archive_read_support_format_empty.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_empty.obj `if test -f 'libarchive/archive_read_support_format_empty.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_empty.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_empty.c'; fi` - -libarchive/test-archive_read_support_format_iso9660.o: libarchive/archive_read_support_format_iso9660.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_iso9660.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_iso9660.Tpo -c -o libarchive/test-archive_read_support_format_iso9660.o `test -f 'libarchive/archive_read_support_format_iso9660.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_iso9660.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_iso9660.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_iso9660.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_iso9660.c' object='libarchive/test-archive_read_support_format_iso9660.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_iso9660.o `test -f 'libarchive/archive_read_support_format_iso9660.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_iso9660.c - -libarchive/test-archive_read_support_format_iso9660.obj: libarchive/archive_read_support_format_iso9660.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_iso9660.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_iso9660.Tpo -c -o libarchive/test-archive_read_support_format_iso9660.obj `if test -f 'libarchive/archive_read_support_format_iso9660.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_iso9660.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_iso9660.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_iso9660.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_iso9660.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_iso9660.c' object='libarchive/test-archive_read_support_format_iso9660.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_iso9660.obj `if test -f 'libarchive/archive_read_support_format_iso9660.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_iso9660.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_iso9660.c'; fi` - -libarchive/test-archive_read_support_format_lha.o: libarchive/archive_read_support_format_lha.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_lha.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_lha.Tpo -c -o libarchive/test-archive_read_support_format_lha.o `test -f 'libarchive/archive_read_support_format_lha.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_lha.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_lha.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_lha.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_lha.c' object='libarchive/test-archive_read_support_format_lha.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_lha.o `test -f 'libarchive/archive_read_support_format_lha.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_lha.c - -libarchive/test-archive_read_support_format_lha.obj: libarchive/archive_read_support_format_lha.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_lha.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_lha.Tpo -c -o libarchive/test-archive_read_support_format_lha.obj `if test -f 'libarchive/archive_read_support_format_lha.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_lha.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_lha.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_lha.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_lha.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_lha.c' object='libarchive/test-archive_read_support_format_lha.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_lha.obj `if test -f 'libarchive/archive_read_support_format_lha.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_lha.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_lha.c'; fi` - -libarchive/test-archive_read_support_format_mtree.o: libarchive/archive_read_support_format_mtree.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_mtree.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_mtree.Tpo -c -o libarchive/test-archive_read_support_format_mtree.o `test -f 'libarchive/archive_read_support_format_mtree.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_mtree.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_mtree.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_mtree.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_mtree.c' object='libarchive/test-archive_read_support_format_mtree.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_mtree.o `test -f 'libarchive/archive_read_support_format_mtree.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_mtree.c - -libarchive/test-archive_read_support_format_mtree.obj: libarchive/archive_read_support_format_mtree.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_mtree.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_mtree.Tpo -c -o libarchive/test-archive_read_support_format_mtree.obj `if test -f 'libarchive/archive_read_support_format_mtree.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_mtree.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_mtree.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_mtree.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_mtree.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_mtree.c' object='libarchive/test-archive_read_support_format_mtree.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_mtree.obj `if test -f 'libarchive/archive_read_support_format_mtree.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_mtree.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_mtree.c'; fi` - -libarchive/test-archive_read_support_format_rar.o: libarchive/archive_read_support_format_rar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_rar.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_rar.Tpo -c -o libarchive/test-archive_read_support_format_rar.o `test -f 'libarchive/archive_read_support_format_rar.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_rar.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_rar.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_rar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_rar.c' object='libarchive/test-archive_read_support_format_rar.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_rar.o `test -f 'libarchive/archive_read_support_format_rar.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_rar.c - -libarchive/test-archive_read_support_format_rar.obj: libarchive/archive_read_support_format_rar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_rar.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_rar.Tpo -c -o libarchive/test-archive_read_support_format_rar.obj `if test -f 'libarchive/archive_read_support_format_rar.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_rar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_rar.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_rar.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_rar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_rar.c' object='libarchive/test-archive_read_support_format_rar.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_rar.obj `if test -f 'libarchive/archive_read_support_format_rar.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_rar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_rar.c'; fi` - -libarchive/test-archive_read_support_format_rar5.o: libarchive/archive_read_support_format_rar5.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_rar5.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_rar5.Tpo -c -o libarchive/test-archive_read_support_format_rar5.o `test -f 'libarchive/archive_read_support_format_rar5.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_rar5.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_rar5.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_rar5.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_rar5.c' object='libarchive/test-archive_read_support_format_rar5.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_rar5.o `test -f 'libarchive/archive_read_support_format_rar5.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_rar5.c - -libarchive/test-archive_read_support_format_rar5.obj: libarchive/archive_read_support_format_rar5.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_rar5.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_rar5.Tpo -c -o libarchive/test-archive_read_support_format_rar5.obj `if test -f 'libarchive/archive_read_support_format_rar5.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_rar5.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_rar5.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_rar5.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_rar5.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_rar5.c' object='libarchive/test-archive_read_support_format_rar5.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_rar5.obj `if test -f 'libarchive/archive_read_support_format_rar5.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_rar5.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_rar5.c'; fi` - -libarchive/test-archive_read_support_format_raw.o: libarchive/archive_read_support_format_raw.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_raw.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_raw.Tpo -c -o libarchive/test-archive_read_support_format_raw.o `test -f 'libarchive/archive_read_support_format_raw.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_raw.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_raw.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_raw.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_raw.c' object='libarchive/test-archive_read_support_format_raw.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_raw.o `test -f 'libarchive/archive_read_support_format_raw.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_raw.c - -libarchive/test-archive_read_support_format_raw.obj: libarchive/archive_read_support_format_raw.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_raw.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_raw.Tpo -c -o libarchive/test-archive_read_support_format_raw.obj `if test -f 'libarchive/archive_read_support_format_raw.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_raw.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_raw.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_raw.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_raw.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_raw.c' object='libarchive/test-archive_read_support_format_raw.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_raw.obj `if test -f 'libarchive/archive_read_support_format_raw.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_raw.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_raw.c'; fi` - -libarchive/test-archive_read_support_format_tar.o: libarchive/archive_read_support_format_tar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_tar.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_tar.Tpo -c -o libarchive/test-archive_read_support_format_tar.o `test -f 'libarchive/archive_read_support_format_tar.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_tar.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_tar.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_tar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_tar.c' object='libarchive/test-archive_read_support_format_tar.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_tar.o `test -f 'libarchive/archive_read_support_format_tar.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_tar.c - -libarchive/test-archive_read_support_format_tar.obj: libarchive/archive_read_support_format_tar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_tar.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_tar.Tpo -c -o libarchive/test-archive_read_support_format_tar.obj `if test -f 'libarchive/archive_read_support_format_tar.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_tar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_tar.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_tar.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_tar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_tar.c' object='libarchive/test-archive_read_support_format_tar.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_tar.obj `if test -f 'libarchive/archive_read_support_format_tar.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_tar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_tar.c'; fi` - -libarchive/test-archive_read_support_format_warc.o: libarchive/archive_read_support_format_warc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_warc.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_warc.Tpo -c -o libarchive/test-archive_read_support_format_warc.o `test -f 'libarchive/archive_read_support_format_warc.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_warc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_warc.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_warc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_warc.c' object='libarchive/test-archive_read_support_format_warc.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_warc.o `test -f 'libarchive/archive_read_support_format_warc.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_warc.c - -libarchive/test-archive_read_support_format_warc.obj: libarchive/archive_read_support_format_warc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_warc.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_warc.Tpo -c -o libarchive/test-archive_read_support_format_warc.obj `if test -f 'libarchive/archive_read_support_format_warc.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_warc.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_warc.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_warc.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_warc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_warc.c' object='libarchive/test-archive_read_support_format_warc.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_warc.obj `if test -f 'libarchive/archive_read_support_format_warc.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_warc.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_warc.c'; fi` - -libarchive/test-archive_read_support_format_xar.o: libarchive/archive_read_support_format_xar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_xar.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_xar.Tpo -c -o libarchive/test-archive_read_support_format_xar.o `test -f 'libarchive/archive_read_support_format_xar.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_xar.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_xar.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_xar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_xar.c' object='libarchive/test-archive_read_support_format_xar.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_xar.o `test -f 'libarchive/archive_read_support_format_xar.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_xar.c - -libarchive/test-archive_read_support_format_xar.obj: libarchive/archive_read_support_format_xar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_xar.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_xar.Tpo -c -o libarchive/test-archive_read_support_format_xar.obj `if test -f 'libarchive/archive_read_support_format_xar.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_xar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_xar.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_xar.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_xar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_xar.c' object='libarchive/test-archive_read_support_format_xar.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_xar.obj `if test -f 'libarchive/archive_read_support_format_xar.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_xar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_xar.c'; fi` - -libarchive/test-archive_read_support_format_zip.o: libarchive/archive_read_support_format_zip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_zip.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_zip.Tpo -c -o libarchive/test-archive_read_support_format_zip.o `test -f 'libarchive/archive_read_support_format_zip.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_zip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_zip.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_zip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_zip.c' object='libarchive/test-archive_read_support_format_zip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_zip.o `test -f 'libarchive/archive_read_support_format_zip.c' || echo '$(srcdir)/'`libarchive/archive_read_support_format_zip.c - -libarchive/test-archive_read_support_format_zip.obj: libarchive/archive_read_support_format_zip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_support_format_zip.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_support_format_zip.Tpo -c -o libarchive/test-archive_read_support_format_zip.obj `if test -f 'libarchive/archive_read_support_format_zip.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_zip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_zip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_support_format_zip.Tpo libarchive/$(DEPDIR)/test-archive_read_support_format_zip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_support_format_zip.c' object='libarchive/test-archive_read_support_format_zip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_support_format_zip.obj `if test -f 'libarchive/archive_read_support_format_zip.c'; then $(CYGPATH_W) 'libarchive/archive_read_support_format_zip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_support_format_zip.c'; fi` - -libarchive/test-archive_string.o: libarchive/archive_string.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_string.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_string.Tpo -c -o libarchive/test-archive_string.o `test -f 'libarchive/archive_string.c' || echo '$(srcdir)/'`libarchive/archive_string.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_string.Tpo libarchive/$(DEPDIR)/test-archive_string.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_string.c' object='libarchive/test-archive_string.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_string.o `test -f 'libarchive/archive_string.c' || echo '$(srcdir)/'`libarchive/archive_string.c - -libarchive/test-archive_string.obj: libarchive/archive_string.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_string.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_string.Tpo -c -o libarchive/test-archive_string.obj `if test -f 'libarchive/archive_string.c'; then $(CYGPATH_W) 'libarchive/archive_string.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_string.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_string.Tpo libarchive/$(DEPDIR)/test-archive_string.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_string.c' object='libarchive/test-archive_string.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_string.obj `if test -f 'libarchive/archive_string.c'; then $(CYGPATH_W) 'libarchive/archive_string.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_string.c'; fi` - -libarchive/test-archive_string_sprintf.o: libarchive/archive_string_sprintf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_string_sprintf.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_string_sprintf.Tpo -c -o libarchive/test-archive_string_sprintf.o `test -f 'libarchive/archive_string_sprintf.c' || echo '$(srcdir)/'`libarchive/archive_string_sprintf.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_string_sprintf.Tpo libarchive/$(DEPDIR)/test-archive_string_sprintf.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_string_sprintf.c' object='libarchive/test-archive_string_sprintf.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_string_sprintf.o `test -f 'libarchive/archive_string_sprintf.c' || echo '$(srcdir)/'`libarchive/archive_string_sprintf.c - -libarchive/test-archive_string_sprintf.obj: libarchive/archive_string_sprintf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_string_sprintf.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_string_sprintf.Tpo -c -o libarchive/test-archive_string_sprintf.obj `if test -f 'libarchive/archive_string_sprintf.c'; then $(CYGPATH_W) 'libarchive/archive_string_sprintf.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_string_sprintf.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_string_sprintf.Tpo libarchive/$(DEPDIR)/test-archive_string_sprintf.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_string_sprintf.c' object='libarchive/test-archive_string_sprintf.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_string_sprintf.obj `if test -f 'libarchive/archive_string_sprintf.c'; then $(CYGPATH_W) 'libarchive/archive_string_sprintf.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_string_sprintf.c'; fi` - -libarchive/test-archive_util.o: libarchive/archive_util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_util.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_util.Tpo -c -o libarchive/test-archive_util.o `test -f 'libarchive/archive_util.c' || echo '$(srcdir)/'`libarchive/archive_util.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_util.Tpo libarchive/$(DEPDIR)/test-archive_util.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_util.c' object='libarchive/test-archive_util.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_util.o `test -f 'libarchive/archive_util.c' || echo '$(srcdir)/'`libarchive/archive_util.c - -libarchive/test-archive_util.obj: libarchive/archive_util.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_util.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_util.Tpo -c -o libarchive/test-archive_util.obj `if test -f 'libarchive/archive_util.c'; then $(CYGPATH_W) 'libarchive/archive_util.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_util.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_util.Tpo libarchive/$(DEPDIR)/test-archive_util.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_util.c' object='libarchive/test-archive_util.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_util.obj `if test -f 'libarchive/archive_util.c'; then $(CYGPATH_W) 'libarchive/archive_util.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_util.c'; fi` - -libarchive/test-archive_version_details.o: libarchive/archive_version_details.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_version_details.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_version_details.Tpo -c -o libarchive/test-archive_version_details.o `test -f 'libarchive/archive_version_details.c' || echo '$(srcdir)/'`libarchive/archive_version_details.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_version_details.Tpo libarchive/$(DEPDIR)/test-archive_version_details.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_version_details.c' object='libarchive/test-archive_version_details.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_version_details.o `test -f 'libarchive/archive_version_details.c' || echo '$(srcdir)/'`libarchive/archive_version_details.c - -libarchive/test-archive_version_details.obj: libarchive/archive_version_details.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_version_details.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_version_details.Tpo -c -o libarchive/test-archive_version_details.obj `if test -f 'libarchive/archive_version_details.c'; then $(CYGPATH_W) 'libarchive/archive_version_details.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_version_details.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_version_details.Tpo libarchive/$(DEPDIR)/test-archive_version_details.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_version_details.c' object='libarchive/test-archive_version_details.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_version_details.obj `if test -f 'libarchive/archive_version_details.c'; then $(CYGPATH_W) 'libarchive/archive_version_details.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_version_details.c'; fi` - -libarchive/test-archive_virtual.o: libarchive/archive_virtual.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_virtual.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_virtual.Tpo -c -o libarchive/test-archive_virtual.o `test -f 'libarchive/archive_virtual.c' || echo '$(srcdir)/'`libarchive/archive_virtual.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_virtual.Tpo libarchive/$(DEPDIR)/test-archive_virtual.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_virtual.c' object='libarchive/test-archive_virtual.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_virtual.o `test -f 'libarchive/archive_virtual.c' || echo '$(srcdir)/'`libarchive/archive_virtual.c - -libarchive/test-archive_virtual.obj: libarchive/archive_virtual.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_virtual.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_virtual.Tpo -c -o libarchive/test-archive_virtual.obj `if test -f 'libarchive/archive_virtual.c'; then $(CYGPATH_W) 'libarchive/archive_virtual.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_virtual.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_virtual.Tpo libarchive/$(DEPDIR)/test-archive_virtual.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_virtual.c' object='libarchive/test-archive_virtual.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_virtual.obj `if test -f 'libarchive/archive_virtual.c'; then $(CYGPATH_W) 'libarchive/archive_virtual.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_virtual.c'; fi` - -libarchive/test-archive_write.o: libarchive/archive_write.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write.Tpo -c -o libarchive/test-archive_write.o `test -f 'libarchive/archive_write.c' || echo '$(srcdir)/'`libarchive/archive_write.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write.Tpo libarchive/$(DEPDIR)/test-archive_write.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write.c' object='libarchive/test-archive_write.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write.o `test -f 'libarchive/archive_write.c' || echo '$(srcdir)/'`libarchive/archive_write.c - -libarchive/test-archive_write.obj: libarchive/archive_write.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write.Tpo -c -o libarchive/test-archive_write.obj `if test -f 'libarchive/archive_write.c'; then $(CYGPATH_W) 'libarchive/archive_write.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write.Tpo libarchive/$(DEPDIR)/test-archive_write.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write.c' object='libarchive/test-archive_write.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write.obj `if test -f 'libarchive/archive_write.c'; then $(CYGPATH_W) 'libarchive/archive_write.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write.c'; fi` - -libarchive/test-archive_write_disk_posix.o: libarchive/archive_write_disk_posix.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_disk_posix.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_disk_posix.Tpo -c -o libarchive/test-archive_write_disk_posix.o `test -f 'libarchive/archive_write_disk_posix.c' || echo '$(srcdir)/'`libarchive/archive_write_disk_posix.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_disk_posix.Tpo libarchive/$(DEPDIR)/test-archive_write_disk_posix.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_disk_posix.c' object='libarchive/test-archive_write_disk_posix.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_disk_posix.o `test -f 'libarchive/archive_write_disk_posix.c' || echo '$(srcdir)/'`libarchive/archive_write_disk_posix.c - -libarchive/test-archive_write_disk_posix.obj: libarchive/archive_write_disk_posix.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_disk_posix.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_disk_posix.Tpo -c -o libarchive/test-archive_write_disk_posix.obj `if test -f 'libarchive/archive_write_disk_posix.c'; then $(CYGPATH_W) 'libarchive/archive_write_disk_posix.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_disk_posix.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_disk_posix.Tpo libarchive/$(DEPDIR)/test-archive_write_disk_posix.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_disk_posix.c' object='libarchive/test-archive_write_disk_posix.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_disk_posix.obj `if test -f 'libarchive/archive_write_disk_posix.c'; then $(CYGPATH_W) 'libarchive/archive_write_disk_posix.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_disk_posix.c'; fi` - -libarchive/test-archive_write_disk_set_standard_lookup.o: libarchive/archive_write_disk_set_standard_lookup.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_disk_set_standard_lookup.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_disk_set_standard_lookup.Tpo -c -o libarchive/test-archive_write_disk_set_standard_lookup.o `test -f 'libarchive/archive_write_disk_set_standard_lookup.c' || echo '$(srcdir)/'`libarchive/archive_write_disk_set_standard_lookup.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_disk_set_standard_lookup.Tpo libarchive/$(DEPDIR)/test-archive_write_disk_set_standard_lookup.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_disk_set_standard_lookup.c' object='libarchive/test-archive_write_disk_set_standard_lookup.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_disk_set_standard_lookup.o `test -f 'libarchive/archive_write_disk_set_standard_lookup.c' || echo '$(srcdir)/'`libarchive/archive_write_disk_set_standard_lookup.c - -libarchive/test-archive_write_disk_set_standard_lookup.obj: libarchive/archive_write_disk_set_standard_lookup.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_disk_set_standard_lookup.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_disk_set_standard_lookup.Tpo -c -o libarchive/test-archive_write_disk_set_standard_lookup.obj `if test -f 'libarchive/archive_write_disk_set_standard_lookup.c'; then $(CYGPATH_W) 'libarchive/archive_write_disk_set_standard_lookup.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_disk_set_standard_lookup.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_disk_set_standard_lookup.Tpo libarchive/$(DEPDIR)/test-archive_write_disk_set_standard_lookup.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_disk_set_standard_lookup.c' object='libarchive/test-archive_write_disk_set_standard_lookup.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_disk_set_standard_lookup.obj `if test -f 'libarchive/archive_write_disk_set_standard_lookup.c'; then $(CYGPATH_W) 'libarchive/archive_write_disk_set_standard_lookup.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_disk_set_standard_lookup.c'; fi` - -libarchive/test-archive_write_open_fd.o: libarchive/archive_write_open_fd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_open_fd.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_open_fd.Tpo -c -o libarchive/test-archive_write_open_fd.o `test -f 'libarchive/archive_write_open_fd.c' || echo '$(srcdir)/'`libarchive/archive_write_open_fd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_open_fd.Tpo libarchive/$(DEPDIR)/test-archive_write_open_fd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_open_fd.c' object='libarchive/test-archive_write_open_fd.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_open_fd.o `test -f 'libarchive/archive_write_open_fd.c' || echo '$(srcdir)/'`libarchive/archive_write_open_fd.c - -libarchive/test-archive_write_open_fd.obj: libarchive/archive_write_open_fd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_open_fd.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_open_fd.Tpo -c -o libarchive/test-archive_write_open_fd.obj `if test -f 'libarchive/archive_write_open_fd.c'; then $(CYGPATH_W) 'libarchive/archive_write_open_fd.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_open_fd.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_open_fd.Tpo libarchive/$(DEPDIR)/test-archive_write_open_fd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_open_fd.c' object='libarchive/test-archive_write_open_fd.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_open_fd.obj `if test -f 'libarchive/archive_write_open_fd.c'; then $(CYGPATH_W) 'libarchive/archive_write_open_fd.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_open_fd.c'; fi` - -libarchive/test-archive_write_open_file.o: libarchive/archive_write_open_file.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_open_file.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_open_file.Tpo -c -o libarchive/test-archive_write_open_file.o `test -f 'libarchive/archive_write_open_file.c' || echo '$(srcdir)/'`libarchive/archive_write_open_file.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_open_file.Tpo libarchive/$(DEPDIR)/test-archive_write_open_file.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_open_file.c' object='libarchive/test-archive_write_open_file.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_open_file.o `test -f 'libarchive/archive_write_open_file.c' || echo '$(srcdir)/'`libarchive/archive_write_open_file.c - -libarchive/test-archive_write_open_file.obj: libarchive/archive_write_open_file.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_open_file.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_open_file.Tpo -c -o libarchive/test-archive_write_open_file.obj `if test -f 'libarchive/archive_write_open_file.c'; then $(CYGPATH_W) 'libarchive/archive_write_open_file.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_open_file.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_open_file.Tpo libarchive/$(DEPDIR)/test-archive_write_open_file.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_open_file.c' object='libarchive/test-archive_write_open_file.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_open_file.obj `if test -f 'libarchive/archive_write_open_file.c'; then $(CYGPATH_W) 'libarchive/archive_write_open_file.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_open_file.c'; fi` - -libarchive/test-archive_write_open_filename.o: libarchive/archive_write_open_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_open_filename.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_open_filename.Tpo -c -o libarchive/test-archive_write_open_filename.o `test -f 'libarchive/archive_write_open_filename.c' || echo '$(srcdir)/'`libarchive/archive_write_open_filename.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_open_filename.Tpo libarchive/$(DEPDIR)/test-archive_write_open_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_open_filename.c' object='libarchive/test-archive_write_open_filename.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_open_filename.o `test -f 'libarchive/archive_write_open_filename.c' || echo '$(srcdir)/'`libarchive/archive_write_open_filename.c - -libarchive/test-archive_write_open_filename.obj: libarchive/archive_write_open_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_open_filename.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_open_filename.Tpo -c -o libarchive/test-archive_write_open_filename.obj `if test -f 'libarchive/archive_write_open_filename.c'; then $(CYGPATH_W) 'libarchive/archive_write_open_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_open_filename.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_open_filename.Tpo libarchive/$(DEPDIR)/test-archive_write_open_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_open_filename.c' object='libarchive/test-archive_write_open_filename.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_open_filename.obj `if test -f 'libarchive/archive_write_open_filename.c'; then $(CYGPATH_W) 'libarchive/archive_write_open_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_open_filename.c'; fi` - -libarchive/test-archive_write_open_memory.o: libarchive/archive_write_open_memory.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_open_memory.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_open_memory.Tpo -c -o libarchive/test-archive_write_open_memory.o `test -f 'libarchive/archive_write_open_memory.c' || echo '$(srcdir)/'`libarchive/archive_write_open_memory.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_open_memory.Tpo libarchive/$(DEPDIR)/test-archive_write_open_memory.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_open_memory.c' object='libarchive/test-archive_write_open_memory.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_open_memory.o `test -f 'libarchive/archive_write_open_memory.c' || echo '$(srcdir)/'`libarchive/archive_write_open_memory.c - -libarchive/test-archive_write_open_memory.obj: libarchive/archive_write_open_memory.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_open_memory.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_open_memory.Tpo -c -o libarchive/test-archive_write_open_memory.obj `if test -f 'libarchive/archive_write_open_memory.c'; then $(CYGPATH_W) 'libarchive/archive_write_open_memory.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_open_memory.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_open_memory.Tpo libarchive/$(DEPDIR)/test-archive_write_open_memory.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_open_memory.c' object='libarchive/test-archive_write_open_memory.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_open_memory.obj `if test -f 'libarchive/archive_write_open_memory.c'; then $(CYGPATH_W) 'libarchive/archive_write_open_memory.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_open_memory.c'; fi` - -libarchive/test-archive_write_add_filter.o: libarchive/archive_write_add_filter.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter.Tpo -c -o libarchive/test-archive_write_add_filter.o `test -f 'libarchive/archive_write_add_filter.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter.c' object='libarchive/test-archive_write_add_filter.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter.o `test -f 'libarchive/archive_write_add_filter.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter.c - -libarchive/test-archive_write_add_filter.obj: libarchive/archive_write_add_filter.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter.Tpo -c -o libarchive/test-archive_write_add_filter.obj `if test -f 'libarchive/archive_write_add_filter.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter.c' object='libarchive/test-archive_write_add_filter.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter.obj `if test -f 'libarchive/archive_write_add_filter.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter.c'; fi` - -libarchive/test-archive_write_add_filter_b64encode.o: libarchive/archive_write_add_filter_b64encode.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_b64encode.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_b64encode.Tpo -c -o libarchive/test-archive_write_add_filter_b64encode.o `test -f 'libarchive/archive_write_add_filter_b64encode.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_b64encode.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_b64encode.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_b64encode.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_b64encode.c' object='libarchive/test-archive_write_add_filter_b64encode.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_b64encode.o `test -f 'libarchive/archive_write_add_filter_b64encode.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_b64encode.c - -libarchive/test-archive_write_add_filter_b64encode.obj: libarchive/archive_write_add_filter_b64encode.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_b64encode.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_b64encode.Tpo -c -o libarchive/test-archive_write_add_filter_b64encode.obj `if test -f 'libarchive/archive_write_add_filter_b64encode.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_b64encode.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_b64encode.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_b64encode.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_b64encode.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_b64encode.c' object='libarchive/test-archive_write_add_filter_b64encode.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_b64encode.obj `if test -f 'libarchive/archive_write_add_filter_b64encode.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_b64encode.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_b64encode.c'; fi` - -libarchive/test-archive_write_add_filter_by_name.o: libarchive/archive_write_add_filter_by_name.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_by_name.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_by_name.Tpo -c -o libarchive/test-archive_write_add_filter_by_name.o `test -f 'libarchive/archive_write_add_filter_by_name.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_by_name.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_by_name.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_by_name.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_by_name.c' object='libarchive/test-archive_write_add_filter_by_name.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_by_name.o `test -f 'libarchive/archive_write_add_filter_by_name.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_by_name.c - -libarchive/test-archive_write_add_filter_by_name.obj: libarchive/archive_write_add_filter_by_name.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_by_name.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_by_name.Tpo -c -o libarchive/test-archive_write_add_filter_by_name.obj `if test -f 'libarchive/archive_write_add_filter_by_name.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_by_name.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_by_name.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_by_name.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_by_name.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_by_name.c' object='libarchive/test-archive_write_add_filter_by_name.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_by_name.obj `if test -f 'libarchive/archive_write_add_filter_by_name.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_by_name.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_by_name.c'; fi` - -libarchive/test-archive_write_add_filter_bzip2.o: libarchive/archive_write_add_filter_bzip2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_bzip2.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_bzip2.Tpo -c -o libarchive/test-archive_write_add_filter_bzip2.o `test -f 'libarchive/archive_write_add_filter_bzip2.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_bzip2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_bzip2.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_bzip2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_bzip2.c' object='libarchive/test-archive_write_add_filter_bzip2.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_bzip2.o `test -f 'libarchive/archive_write_add_filter_bzip2.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_bzip2.c - -libarchive/test-archive_write_add_filter_bzip2.obj: libarchive/archive_write_add_filter_bzip2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_bzip2.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_bzip2.Tpo -c -o libarchive/test-archive_write_add_filter_bzip2.obj `if test -f 'libarchive/archive_write_add_filter_bzip2.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_bzip2.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_bzip2.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_bzip2.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_bzip2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_bzip2.c' object='libarchive/test-archive_write_add_filter_bzip2.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_bzip2.obj `if test -f 'libarchive/archive_write_add_filter_bzip2.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_bzip2.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_bzip2.c'; fi` - -libarchive/test-archive_write_add_filter_compress.o: libarchive/archive_write_add_filter_compress.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_compress.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_compress.Tpo -c -o libarchive/test-archive_write_add_filter_compress.o `test -f 'libarchive/archive_write_add_filter_compress.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_compress.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_compress.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_compress.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_compress.c' object='libarchive/test-archive_write_add_filter_compress.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_compress.o `test -f 'libarchive/archive_write_add_filter_compress.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_compress.c - -libarchive/test-archive_write_add_filter_compress.obj: libarchive/archive_write_add_filter_compress.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_compress.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_compress.Tpo -c -o libarchive/test-archive_write_add_filter_compress.obj `if test -f 'libarchive/archive_write_add_filter_compress.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_compress.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_compress.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_compress.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_compress.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_compress.c' object='libarchive/test-archive_write_add_filter_compress.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_compress.obj `if test -f 'libarchive/archive_write_add_filter_compress.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_compress.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_compress.c'; fi` - -libarchive/test-archive_write_add_filter_grzip.o: libarchive/archive_write_add_filter_grzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_grzip.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_grzip.Tpo -c -o libarchive/test-archive_write_add_filter_grzip.o `test -f 'libarchive/archive_write_add_filter_grzip.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_grzip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_grzip.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_grzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_grzip.c' object='libarchive/test-archive_write_add_filter_grzip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_grzip.o `test -f 'libarchive/archive_write_add_filter_grzip.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_grzip.c - -libarchive/test-archive_write_add_filter_grzip.obj: libarchive/archive_write_add_filter_grzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_grzip.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_grzip.Tpo -c -o libarchive/test-archive_write_add_filter_grzip.obj `if test -f 'libarchive/archive_write_add_filter_grzip.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_grzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_grzip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_grzip.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_grzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_grzip.c' object='libarchive/test-archive_write_add_filter_grzip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_grzip.obj `if test -f 'libarchive/archive_write_add_filter_grzip.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_grzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_grzip.c'; fi` - -libarchive/test-archive_write_add_filter_gzip.o: libarchive/archive_write_add_filter_gzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_gzip.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_gzip.Tpo -c -o libarchive/test-archive_write_add_filter_gzip.o `test -f 'libarchive/archive_write_add_filter_gzip.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_gzip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_gzip.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_gzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_gzip.c' object='libarchive/test-archive_write_add_filter_gzip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_gzip.o `test -f 'libarchive/archive_write_add_filter_gzip.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_gzip.c - -libarchive/test-archive_write_add_filter_gzip.obj: libarchive/archive_write_add_filter_gzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_gzip.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_gzip.Tpo -c -o libarchive/test-archive_write_add_filter_gzip.obj `if test -f 'libarchive/archive_write_add_filter_gzip.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_gzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_gzip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_gzip.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_gzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_gzip.c' object='libarchive/test-archive_write_add_filter_gzip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_gzip.obj `if test -f 'libarchive/archive_write_add_filter_gzip.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_gzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_gzip.c'; fi` - -libarchive/test-archive_write_add_filter_lrzip.o: libarchive/archive_write_add_filter_lrzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_lrzip.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_lrzip.Tpo -c -o libarchive/test-archive_write_add_filter_lrzip.o `test -f 'libarchive/archive_write_add_filter_lrzip.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_lrzip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_lrzip.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_lrzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_lrzip.c' object='libarchive/test-archive_write_add_filter_lrzip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_lrzip.o `test -f 'libarchive/archive_write_add_filter_lrzip.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_lrzip.c - -libarchive/test-archive_write_add_filter_lrzip.obj: libarchive/archive_write_add_filter_lrzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_lrzip.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_lrzip.Tpo -c -o libarchive/test-archive_write_add_filter_lrzip.obj `if test -f 'libarchive/archive_write_add_filter_lrzip.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_lrzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_lrzip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_lrzip.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_lrzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_lrzip.c' object='libarchive/test-archive_write_add_filter_lrzip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_lrzip.obj `if test -f 'libarchive/archive_write_add_filter_lrzip.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_lrzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_lrzip.c'; fi` - -libarchive/test-archive_write_add_filter_lz4.o: libarchive/archive_write_add_filter_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_lz4.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_lz4.Tpo -c -o libarchive/test-archive_write_add_filter_lz4.o `test -f 'libarchive/archive_write_add_filter_lz4.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_lz4.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_lz4.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_lz4.c' object='libarchive/test-archive_write_add_filter_lz4.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_lz4.o `test -f 'libarchive/archive_write_add_filter_lz4.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_lz4.c - -libarchive/test-archive_write_add_filter_lz4.obj: libarchive/archive_write_add_filter_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_lz4.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_lz4.Tpo -c -o libarchive/test-archive_write_add_filter_lz4.obj `if test -f 'libarchive/archive_write_add_filter_lz4.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_lz4.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_lz4.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_lz4.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_lz4.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_lz4.c' object='libarchive/test-archive_write_add_filter_lz4.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_lz4.obj `if test -f 'libarchive/archive_write_add_filter_lz4.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_lz4.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_lz4.c'; fi` - -libarchive/test-archive_write_add_filter_lzop.o: libarchive/archive_write_add_filter_lzop.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_lzop.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_lzop.Tpo -c -o libarchive/test-archive_write_add_filter_lzop.o `test -f 'libarchive/archive_write_add_filter_lzop.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_lzop.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_lzop.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_lzop.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_lzop.c' object='libarchive/test-archive_write_add_filter_lzop.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_lzop.o `test -f 'libarchive/archive_write_add_filter_lzop.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_lzop.c - -libarchive/test-archive_write_add_filter_lzop.obj: libarchive/archive_write_add_filter_lzop.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_lzop.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_lzop.Tpo -c -o libarchive/test-archive_write_add_filter_lzop.obj `if test -f 'libarchive/archive_write_add_filter_lzop.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_lzop.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_lzop.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_lzop.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_lzop.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_lzop.c' object='libarchive/test-archive_write_add_filter_lzop.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_lzop.obj `if test -f 'libarchive/archive_write_add_filter_lzop.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_lzop.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_lzop.c'; fi` - -libarchive/test-archive_write_add_filter_none.o: libarchive/archive_write_add_filter_none.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_none.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_none.Tpo -c -o libarchive/test-archive_write_add_filter_none.o `test -f 'libarchive/archive_write_add_filter_none.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_none.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_none.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_none.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_none.c' object='libarchive/test-archive_write_add_filter_none.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_none.o `test -f 'libarchive/archive_write_add_filter_none.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_none.c - -libarchive/test-archive_write_add_filter_none.obj: libarchive/archive_write_add_filter_none.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_none.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_none.Tpo -c -o libarchive/test-archive_write_add_filter_none.obj `if test -f 'libarchive/archive_write_add_filter_none.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_none.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_none.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_none.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_none.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_none.c' object='libarchive/test-archive_write_add_filter_none.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_none.obj `if test -f 'libarchive/archive_write_add_filter_none.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_none.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_none.c'; fi` - -libarchive/test-archive_write_add_filter_program.o: libarchive/archive_write_add_filter_program.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_program.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_program.Tpo -c -o libarchive/test-archive_write_add_filter_program.o `test -f 'libarchive/archive_write_add_filter_program.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_program.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_program.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_program.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_program.c' object='libarchive/test-archive_write_add_filter_program.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_program.o `test -f 'libarchive/archive_write_add_filter_program.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_program.c - -libarchive/test-archive_write_add_filter_program.obj: libarchive/archive_write_add_filter_program.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_program.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_program.Tpo -c -o libarchive/test-archive_write_add_filter_program.obj `if test -f 'libarchive/archive_write_add_filter_program.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_program.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_program.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_program.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_program.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_program.c' object='libarchive/test-archive_write_add_filter_program.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_program.obj `if test -f 'libarchive/archive_write_add_filter_program.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_program.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_program.c'; fi` - -libarchive/test-archive_write_add_filter_uuencode.o: libarchive/archive_write_add_filter_uuencode.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_uuencode.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_uuencode.Tpo -c -o libarchive/test-archive_write_add_filter_uuencode.o `test -f 'libarchive/archive_write_add_filter_uuencode.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_uuencode.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_uuencode.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_uuencode.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_uuencode.c' object='libarchive/test-archive_write_add_filter_uuencode.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_uuencode.o `test -f 'libarchive/archive_write_add_filter_uuencode.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_uuencode.c - -libarchive/test-archive_write_add_filter_uuencode.obj: libarchive/archive_write_add_filter_uuencode.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_uuencode.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_uuencode.Tpo -c -o libarchive/test-archive_write_add_filter_uuencode.obj `if test -f 'libarchive/archive_write_add_filter_uuencode.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_uuencode.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_uuencode.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_uuencode.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_uuencode.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_uuencode.c' object='libarchive/test-archive_write_add_filter_uuencode.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_uuencode.obj `if test -f 'libarchive/archive_write_add_filter_uuencode.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_uuencode.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_uuencode.c'; fi` - -libarchive/test-archive_write_add_filter_xz.o: libarchive/archive_write_add_filter_xz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_xz.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_xz.Tpo -c -o libarchive/test-archive_write_add_filter_xz.o `test -f 'libarchive/archive_write_add_filter_xz.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_xz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_xz.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_xz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_xz.c' object='libarchive/test-archive_write_add_filter_xz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_xz.o `test -f 'libarchive/archive_write_add_filter_xz.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_xz.c - -libarchive/test-archive_write_add_filter_xz.obj: libarchive/archive_write_add_filter_xz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_xz.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_xz.Tpo -c -o libarchive/test-archive_write_add_filter_xz.obj `if test -f 'libarchive/archive_write_add_filter_xz.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_xz.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_xz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_xz.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_xz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_xz.c' object='libarchive/test-archive_write_add_filter_xz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_xz.obj `if test -f 'libarchive/archive_write_add_filter_xz.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_xz.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_xz.c'; fi` - -libarchive/test-archive_write_add_filter_zstd.o: libarchive/archive_write_add_filter_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_zstd.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_zstd.Tpo -c -o libarchive/test-archive_write_add_filter_zstd.o `test -f 'libarchive/archive_write_add_filter_zstd.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_zstd.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_zstd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_zstd.c' object='libarchive/test-archive_write_add_filter_zstd.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_zstd.o `test -f 'libarchive/archive_write_add_filter_zstd.c' || echo '$(srcdir)/'`libarchive/archive_write_add_filter_zstd.c - -libarchive/test-archive_write_add_filter_zstd.obj: libarchive/archive_write_add_filter_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_add_filter_zstd.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_add_filter_zstd.Tpo -c -o libarchive/test-archive_write_add_filter_zstd.obj `if test -f 'libarchive/archive_write_add_filter_zstd.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_zstd.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_zstd.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_add_filter_zstd.Tpo libarchive/$(DEPDIR)/test-archive_write_add_filter_zstd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_add_filter_zstd.c' object='libarchive/test-archive_write_add_filter_zstd.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_add_filter_zstd.obj `if test -f 'libarchive/archive_write_add_filter_zstd.c'; then $(CYGPATH_W) 'libarchive/archive_write_add_filter_zstd.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_add_filter_zstd.c'; fi` - -libarchive/test-archive_write_set_format.o: libarchive/archive_write_set_format.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format.Tpo -c -o libarchive/test-archive_write_set_format.o `test -f 'libarchive/archive_write_set_format.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format.c' object='libarchive/test-archive_write_set_format.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format.o `test -f 'libarchive/archive_write_set_format.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format.c - -libarchive/test-archive_write_set_format.obj: libarchive/archive_write_set_format.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format.Tpo -c -o libarchive/test-archive_write_set_format.obj `if test -f 'libarchive/archive_write_set_format.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format.c' object='libarchive/test-archive_write_set_format.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format.obj `if test -f 'libarchive/archive_write_set_format.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format.c'; fi` - -libarchive/test-archive_write_set_format_7zip.o: libarchive/archive_write_set_format_7zip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_7zip.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_7zip.Tpo -c -o libarchive/test-archive_write_set_format_7zip.o `test -f 'libarchive/archive_write_set_format_7zip.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_7zip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_7zip.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_7zip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_7zip.c' object='libarchive/test-archive_write_set_format_7zip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_7zip.o `test -f 'libarchive/archive_write_set_format_7zip.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_7zip.c - -libarchive/test-archive_write_set_format_7zip.obj: libarchive/archive_write_set_format_7zip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_7zip.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_7zip.Tpo -c -o libarchive/test-archive_write_set_format_7zip.obj `if test -f 'libarchive/archive_write_set_format_7zip.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_7zip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_7zip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_7zip.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_7zip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_7zip.c' object='libarchive/test-archive_write_set_format_7zip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_7zip.obj `if test -f 'libarchive/archive_write_set_format_7zip.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_7zip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_7zip.c'; fi` - -libarchive/test-archive_write_set_format_ar.o: libarchive/archive_write_set_format_ar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_ar.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_ar.Tpo -c -o libarchive/test-archive_write_set_format_ar.o `test -f 'libarchive/archive_write_set_format_ar.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_ar.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_ar.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_ar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_ar.c' object='libarchive/test-archive_write_set_format_ar.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_ar.o `test -f 'libarchive/archive_write_set_format_ar.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_ar.c - -libarchive/test-archive_write_set_format_ar.obj: libarchive/archive_write_set_format_ar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_ar.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_ar.Tpo -c -o libarchive/test-archive_write_set_format_ar.obj `if test -f 'libarchive/archive_write_set_format_ar.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_ar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_ar.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_ar.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_ar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_ar.c' object='libarchive/test-archive_write_set_format_ar.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_ar.obj `if test -f 'libarchive/archive_write_set_format_ar.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_ar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_ar.c'; fi` - -libarchive/test-archive_write_set_format_by_name.o: libarchive/archive_write_set_format_by_name.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_by_name.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_by_name.Tpo -c -o libarchive/test-archive_write_set_format_by_name.o `test -f 'libarchive/archive_write_set_format_by_name.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_by_name.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_by_name.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_by_name.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_by_name.c' object='libarchive/test-archive_write_set_format_by_name.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_by_name.o `test -f 'libarchive/archive_write_set_format_by_name.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_by_name.c - -libarchive/test-archive_write_set_format_by_name.obj: libarchive/archive_write_set_format_by_name.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_by_name.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_by_name.Tpo -c -o libarchive/test-archive_write_set_format_by_name.obj `if test -f 'libarchive/archive_write_set_format_by_name.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_by_name.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_by_name.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_by_name.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_by_name.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_by_name.c' object='libarchive/test-archive_write_set_format_by_name.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_by_name.obj `if test -f 'libarchive/archive_write_set_format_by_name.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_by_name.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_by_name.c'; fi` - -libarchive/test-archive_write_set_format_cpio.o: libarchive/archive_write_set_format_cpio.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_cpio.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_cpio.Tpo -c -o libarchive/test-archive_write_set_format_cpio.o `test -f 'libarchive/archive_write_set_format_cpio.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_cpio.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_cpio.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_cpio.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_cpio.c' object='libarchive/test-archive_write_set_format_cpio.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_cpio.o `test -f 'libarchive/archive_write_set_format_cpio.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_cpio.c - -libarchive/test-archive_write_set_format_cpio.obj: libarchive/archive_write_set_format_cpio.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_cpio.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_cpio.Tpo -c -o libarchive/test-archive_write_set_format_cpio.obj `if test -f 'libarchive/archive_write_set_format_cpio.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_cpio.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_cpio.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_cpio.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_cpio.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_cpio.c' object='libarchive/test-archive_write_set_format_cpio.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_cpio.obj `if test -f 'libarchive/archive_write_set_format_cpio.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_cpio.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_cpio.c'; fi` - -libarchive/test-archive_write_set_format_cpio_binary.o: libarchive/archive_write_set_format_cpio_binary.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_cpio_binary.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_binary.Tpo -c -o libarchive/test-archive_write_set_format_cpio_binary.o `test -f 'libarchive/archive_write_set_format_cpio_binary.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_cpio_binary.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_binary.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_binary.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_cpio_binary.c' object='libarchive/test-archive_write_set_format_cpio_binary.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_cpio_binary.o `test -f 'libarchive/archive_write_set_format_cpio_binary.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_cpio_binary.c - -libarchive/test-archive_write_set_format_cpio_binary.obj: libarchive/archive_write_set_format_cpio_binary.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_cpio_binary.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_binary.Tpo -c -o libarchive/test-archive_write_set_format_cpio_binary.obj `if test -f 'libarchive/archive_write_set_format_cpio_binary.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_cpio_binary.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_cpio_binary.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_binary.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_binary.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_cpio_binary.c' object='libarchive/test-archive_write_set_format_cpio_binary.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_cpio_binary.obj `if test -f 'libarchive/archive_write_set_format_cpio_binary.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_cpio_binary.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_cpio_binary.c'; fi` - -libarchive/test-archive_write_set_format_cpio_newc.o: libarchive/archive_write_set_format_cpio_newc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_cpio_newc.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_newc.Tpo -c -o libarchive/test-archive_write_set_format_cpio_newc.o `test -f 'libarchive/archive_write_set_format_cpio_newc.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_cpio_newc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_newc.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_newc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_cpio_newc.c' object='libarchive/test-archive_write_set_format_cpio_newc.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_cpio_newc.o `test -f 'libarchive/archive_write_set_format_cpio_newc.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_cpio_newc.c - -libarchive/test-archive_write_set_format_cpio_newc.obj: libarchive/archive_write_set_format_cpio_newc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_cpio_newc.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_newc.Tpo -c -o libarchive/test-archive_write_set_format_cpio_newc.obj `if test -f 'libarchive/archive_write_set_format_cpio_newc.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_cpio_newc.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_cpio_newc.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_newc.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_newc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_cpio_newc.c' object='libarchive/test-archive_write_set_format_cpio_newc.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_cpio_newc.obj `if test -f 'libarchive/archive_write_set_format_cpio_newc.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_cpio_newc.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_cpio_newc.c'; fi` - -libarchive/test-archive_write_set_format_cpio_odc.o: libarchive/archive_write_set_format_cpio_odc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_cpio_odc.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_odc.Tpo -c -o libarchive/test-archive_write_set_format_cpio_odc.o `test -f 'libarchive/archive_write_set_format_cpio_odc.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_cpio_odc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_odc.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_odc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_cpio_odc.c' object='libarchive/test-archive_write_set_format_cpio_odc.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_cpio_odc.o `test -f 'libarchive/archive_write_set_format_cpio_odc.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_cpio_odc.c - -libarchive/test-archive_write_set_format_cpio_odc.obj: libarchive/archive_write_set_format_cpio_odc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_cpio_odc.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_odc.Tpo -c -o libarchive/test-archive_write_set_format_cpio_odc.obj `if test -f 'libarchive/archive_write_set_format_cpio_odc.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_cpio_odc.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_cpio_odc.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_odc.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_odc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_cpio_odc.c' object='libarchive/test-archive_write_set_format_cpio_odc.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_cpio_odc.obj `if test -f 'libarchive/archive_write_set_format_cpio_odc.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_cpio_odc.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_cpio_odc.c'; fi` - -libarchive/test-archive_write_set_format_filter_by_ext.o: libarchive/archive_write_set_format_filter_by_ext.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_filter_by_ext.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_filter_by_ext.Tpo -c -o libarchive/test-archive_write_set_format_filter_by_ext.o `test -f 'libarchive/archive_write_set_format_filter_by_ext.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_filter_by_ext.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_filter_by_ext.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_filter_by_ext.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_filter_by_ext.c' object='libarchive/test-archive_write_set_format_filter_by_ext.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_filter_by_ext.o `test -f 'libarchive/archive_write_set_format_filter_by_ext.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_filter_by_ext.c - -libarchive/test-archive_write_set_format_filter_by_ext.obj: libarchive/archive_write_set_format_filter_by_ext.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_filter_by_ext.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_filter_by_ext.Tpo -c -o libarchive/test-archive_write_set_format_filter_by_ext.obj `if test -f 'libarchive/archive_write_set_format_filter_by_ext.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_filter_by_ext.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_filter_by_ext.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_filter_by_ext.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_filter_by_ext.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_filter_by_ext.c' object='libarchive/test-archive_write_set_format_filter_by_ext.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_filter_by_ext.obj `if test -f 'libarchive/archive_write_set_format_filter_by_ext.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_filter_by_ext.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_filter_by_ext.c'; fi` - -libarchive/test-archive_write_set_format_iso9660.o: libarchive/archive_write_set_format_iso9660.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_iso9660.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_iso9660.Tpo -c -o libarchive/test-archive_write_set_format_iso9660.o `test -f 'libarchive/archive_write_set_format_iso9660.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_iso9660.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_iso9660.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_iso9660.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_iso9660.c' object='libarchive/test-archive_write_set_format_iso9660.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_iso9660.o `test -f 'libarchive/archive_write_set_format_iso9660.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_iso9660.c - -libarchive/test-archive_write_set_format_iso9660.obj: libarchive/archive_write_set_format_iso9660.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_iso9660.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_iso9660.Tpo -c -o libarchive/test-archive_write_set_format_iso9660.obj `if test -f 'libarchive/archive_write_set_format_iso9660.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_iso9660.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_iso9660.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_iso9660.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_iso9660.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_iso9660.c' object='libarchive/test-archive_write_set_format_iso9660.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_iso9660.obj `if test -f 'libarchive/archive_write_set_format_iso9660.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_iso9660.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_iso9660.c'; fi` - -libarchive/test-archive_write_set_format_mtree.o: libarchive/archive_write_set_format_mtree.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_mtree.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_mtree.Tpo -c -o libarchive/test-archive_write_set_format_mtree.o `test -f 'libarchive/archive_write_set_format_mtree.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_mtree.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_mtree.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_mtree.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_mtree.c' object='libarchive/test-archive_write_set_format_mtree.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_mtree.o `test -f 'libarchive/archive_write_set_format_mtree.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_mtree.c - -libarchive/test-archive_write_set_format_mtree.obj: libarchive/archive_write_set_format_mtree.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_mtree.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_mtree.Tpo -c -o libarchive/test-archive_write_set_format_mtree.obj `if test -f 'libarchive/archive_write_set_format_mtree.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_mtree.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_mtree.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_mtree.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_mtree.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_mtree.c' object='libarchive/test-archive_write_set_format_mtree.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_mtree.obj `if test -f 'libarchive/archive_write_set_format_mtree.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_mtree.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_mtree.c'; fi` - -libarchive/test-archive_write_set_format_pax.o: libarchive/archive_write_set_format_pax.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_pax.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_pax.Tpo -c -o libarchive/test-archive_write_set_format_pax.o `test -f 'libarchive/archive_write_set_format_pax.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_pax.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_pax.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_pax.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_pax.c' object='libarchive/test-archive_write_set_format_pax.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_pax.o `test -f 'libarchive/archive_write_set_format_pax.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_pax.c - -libarchive/test-archive_write_set_format_pax.obj: libarchive/archive_write_set_format_pax.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_pax.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_pax.Tpo -c -o libarchive/test-archive_write_set_format_pax.obj `if test -f 'libarchive/archive_write_set_format_pax.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_pax.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_pax.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_pax.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_pax.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_pax.c' object='libarchive/test-archive_write_set_format_pax.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_pax.obj `if test -f 'libarchive/archive_write_set_format_pax.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_pax.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_pax.c'; fi` - -libarchive/test-archive_write_set_format_raw.o: libarchive/archive_write_set_format_raw.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_raw.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_raw.Tpo -c -o libarchive/test-archive_write_set_format_raw.o `test -f 'libarchive/archive_write_set_format_raw.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_raw.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_raw.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_raw.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_raw.c' object='libarchive/test-archive_write_set_format_raw.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_raw.o `test -f 'libarchive/archive_write_set_format_raw.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_raw.c - -libarchive/test-archive_write_set_format_raw.obj: libarchive/archive_write_set_format_raw.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_raw.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_raw.Tpo -c -o libarchive/test-archive_write_set_format_raw.obj `if test -f 'libarchive/archive_write_set_format_raw.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_raw.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_raw.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_raw.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_raw.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_raw.c' object='libarchive/test-archive_write_set_format_raw.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_raw.obj `if test -f 'libarchive/archive_write_set_format_raw.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_raw.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_raw.c'; fi` - -libarchive/test-archive_write_set_format_shar.o: libarchive/archive_write_set_format_shar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_shar.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_shar.Tpo -c -o libarchive/test-archive_write_set_format_shar.o `test -f 'libarchive/archive_write_set_format_shar.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_shar.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_shar.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_shar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_shar.c' object='libarchive/test-archive_write_set_format_shar.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_shar.o `test -f 'libarchive/archive_write_set_format_shar.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_shar.c - -libarchive/test-archive_write_set_format_shar.obj: libarchive/archive_write_set_format_shar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_shar.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_shar.Tpo -c -o libarchive/test-archive_write_set_format_shar.obj `if test -f 'libarchive/archive_write_set_format_shar.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_shar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_shar.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_shar.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_shar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_shar.c' object='libarchive/test-archive_write_set_format_shar.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_shar.obj `if test -f 'libarchive/archive_write_set_format_shar.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_shar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_shar.c'; fi` - -libarchive/test-archive_write_set_format_ustar.o: libarchive/archive_write_set_format_ustar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_ustar.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_ustar.Tpo -c -o libarchive/test-archive_write_set_format_ustar.o `test -f 'libarchive/archive_write_set_format_ustar.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_ustar.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_ustar.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_ustar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_ustar.c' object='libarchive/test-archive_write_set_format_ustar.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_ustar.o `test -f 'libarchive/archive_write_set_format_ustar.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_ustar.c - -libarchive/test-archive_write_set_format_ustar.obj: libarchive/archive_write_set_format_ustar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_ustar.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_ustar.Tpo -c -o libarchive/test-archive_write_set_format_ustar.obj `if test -f 'libarchive/archive_write_set_format_ustar.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_ustar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_ustar.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_ustar.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_ustar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_ustar.c' object='libarchive/test-archive_write_set_format_ustar.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_ustar.obj `if test -f 'libarchive/archive_write_set_format_ustar.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_ustar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_ustar.c'; fi` - -libarchive/test-archive_write_set_format_v7tar.o: libarchive/archive_write_set_format_v7tar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_v7tar.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_v7tar.Tpo -c -o libarchive/test-archive_write_set_format_v7tar.o `test -f 'libarchive/archive_write_set_format_v7tar.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_v7tar.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_v7tar.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_v7tar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_v7tar.c' object='libarchive/test-archive_write_set_format_v7tar.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_v7tar.o `test -f 'libarchive/archive_write_set_format_v7tar.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_v7tar.c - -libarchive/test-archive_write_set_format_v7tar.obj: libarchive/archive_write_set_format_v7tar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_v7tar.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_v7tar.Tpo -c -o libarchive/test-archive_write_set_format_v7tar.obj `if test -f 'libarchive/archive_write_set_format_v7tar.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_v7tar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_v7tar.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_v7tar.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_v7tar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_v7tar.c' object='libarchive/test-archive_write_set_format_v7tar.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_v7tar.obj `if test -f 'libarchive/archive_write_set_format_v7tar.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_v7tar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_v7tar.c'; fi` - -libarchive/test-archive_write_set_format_gnutar.o: libarchive/archive_write_set_format_gnutar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_gnutar.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_gnutar.Tpo -c -o libarchive/test-archive_write_set_format_gnutar.o `test -f 'libarchive/archive_write_set_format_gnutar.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_gnutar.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_gnutar.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_gnutar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_gnutar.c' object='libarchive/test-archive_write_set_format_gnutar.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_gnutar.o `test -f 'libarchive/archive_write_set_format_gnutar.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_gnutar.c - -libarchive/test-archive_write_set_format_gnutar.obj: libarchive/archive_write_set_format_gnutar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_gnutar.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_gnutar.Tpo -c -o libarchive/test-archive_write_set_format_gnutar.obj `if test -f 'libarchive/archive_write_set_format_gnutar.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_gnutar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_gnutar.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_gnutar.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_gnutar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_gnutar.c' object='libarchive/test-archive_write_set_format_gnutar.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_gnutar.obj `if test -f 'libarchive/archive_write_set_format_gnutar.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_gnutar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_gnutar.c'; fi` - -libarchive/test-archive_write_set_format_warc.o: libarchive/archive_write_set_format_warc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_warc.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_warc.Tpo -c -o libarchive/test-archive_write_set_format_warc.o `test -f 'libarchive/archive_write_set_format_warc.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_warc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_warc.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_warc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_warc.c' object='libarchive/test-archive_write_set_format_warc.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_warc.o `test -f 'libarchive/archive_write_set_format_warc.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_warc.c - -libarchive/test-archive_write_set_format_warc.obj: libarchive/archive_write_set_format_warc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_warc.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_warc.Tpo -c -o libarchive/test-archive_write_set_format_warc.obj `if test -f 'libarchive/archive_write_set_format_warc.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_warc.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_warc.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_warc.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_warc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_warc.c' object='libarchive/test-archive_write_set_format_warc.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_warc.obj `if test -f 'libarchive/archive_write_set_format_warc.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_warc.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_warc.c'; fi` - -libarchive/test-archive_write_set_format_xar.o: libarchive/archive_write_set_format_xar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_xar.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_xar.Tpo -c -o libarchive/test-archive_write_set_format_xar.o `test -f 'libarchive/archive_write_set_format_xar.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_xar.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_xar.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_xar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_xar.c' object='libarchive/test-archive_write_set_format_xar.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_xar.o `test -f 'libarchive/archive_write_set_format_xar.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_xar.c - -libarchive/test-archive_write_set_format_xar.obj: libarchive/archive_write_set_format_xar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_xar.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_xar.Tpo -c -o libarchive/test-archive_write_set_format_xar.obj `if test -f 'libarchive/archive_write_set_format_xar.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_xar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_xar.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_xar.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_xar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_xar.c' object='libarchive/test-archive_write_set_format_xar.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_xar.obj `if test -f 'libarchive/archive_write_set_format_xar.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_xar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_xar.c'; fi` - -libarchive/test-archive_write_set_format_zip.o: libarchive/archive_write_set_format_zip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_zip.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_zip.Tpo -c -o libarchive/test-archive_write_set_format_zip.o `test -f 'libarchive/archive_write_set_format_zip.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_zip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_zip.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_zip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_zip.c' object='libarchive/test-archive_write_set_format_zip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_zip.o `test -f 'libarchive/archive_write_set_format_zip.c' || echo '$(srcdir)/'`libarchive/archive_write_set_format_zip.c - -libarchive/test-archive_write_set_format_zip.obj: libarchive/archive_write_set_format_zip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_format_zip.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_format_zip.Tpo -c -o libarchive/test-archive_write_set_format_zip.obj `if test -f 'libarchive/archive_write_set_format_zip.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_zip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_zip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_format_zip.Tpo libarchive/$(DEPDIR)/test-archive_write_set_format_zip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_format_zip.c' object='libarchive/test-archive_write_set_format_zip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_format_zip.obj `if test -f 'libarchive/archive_write_set_format_zip.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_format_zip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_format_zip.c'; fi` - -libarchive/test-archive_write_set_options.o: libarchive/archive_write_set_options.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_options.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_options.Tpo -c -o libarchive/test-archive_write_set_options.o `test -f 'libarchive/archive_write_set_options.c' || echo '$(srcdir)/'`libarchive/archive_write_set_options.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_options.Tpo libarchive/$(DEPDIR)/test-archive_write_set_options.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_options.c' object='libarchive/test-archive_write_set_options.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_options.o `test -f 'libarchive/archive_write_set_options.c' || echo '$(srcdir)/'`libarchive/archive_write_set_options.c - -libarchive/test-archive_write_set_options.obj: libarchive/archive_write_set_options.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_options.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_options.Tpo -c -o libarchive/test-archive_write_set_options.obj `if test -f 'libarchive/archive_write_set_options.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_options.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_options.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_options.Tpo libarchive/$(DEPDIR)/test-archive_write_set_options.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_options.c' object='libarchive/test-archive_write_set_options.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_options.obj `if test -f 'libarchive/archive_write_set_options.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_options.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_options.c'; fi` - -libarchive/test-archive_write_set_passphrase.o: libarchive/archive_write_set_passphrase.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_passphrase.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_passphrase.Tpo -c -o libarchive/test-archive_write_set_passphrase.o `test -f 'libarchive/archive_write_set_passphrase.c' || echo '$(srcdir)/'`libarchive/archive_write_set_passphrase.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_passphrase.Tpo libarchive/$(DEPDIR)/test-archive_write_set_passphrase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_passphrase.c' object='libarchive/test-archive_write_set_passphrase.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_passphrase.o `test -f 'libarchive/archive_write_set_passphrase.c' || echo '$(srcdir)/'`libarchive/archive_write_set_passphrase.c - -libarchive/test-archive_write_set_passphrase.obj: libarchive/archive_write_set_passphrase.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_set_passphrase.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_set_passphrase.Tpo -c -o libarchive/test-archive_write_set_passphrase.obj `if test -f 'libarchive/archive_write_set_passphrase.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_passphrase.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_passphrase.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_set_passphrase.Tpo libarchive/$(DEPDIR)/test-archive_write_set_passphrase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_set_passphrase.c' object='libarchive/test-archive_write_set_passphrase.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_set_passphrase.obj `if test -f 'libarchive/archive_write_set_passphrase.c'; then $(CYGPATH_W) 'libarchive/archive_write_set_passphrase.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_set_passphrase.c'; fi` - -libarchive/test-filter_fork_posix.o: libarchive/filter_fork_posix.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-filter_fork_posix.o -MD -MP -MF libarchive/$(DEPDIR)/test-filter_fork_posix.Tpo -c -o libarchive/test-filter_fork_posix.o `test -f 'libarchive/filter_fork_posix.c' || echo '$(srcdir)/'`libarchive/filter_fork_posix.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-filter_fork_posix.Tpo libarchive/$(DEPDIR)/test-filter_fork_posix.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/filter_fork_posix.c' object='libarchive/test-filter_fork_posix.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-filter_fork_posix.o `test -f 'libarchive/filter_fork_posix.c' || echo '$(srcdir)/'`libarchive/filter_fork_posix.c - -libarchive/test-filter_fork_posix.obj: libarchive/filter_fork_posix.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-filter_fork_posix.obj -MD -MP -MF libarchive/$(DEPDIR)/test-filter_fork_posix.Tpo -c -o libarchive/test-filter_fork_posix.obj `if test -f 'libarchive/filter_fork_posix.c'; then $(CYGPATH_W) 'libarchive/filter_fork_posix.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/filter_fork_posix.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-filter_fork_posix.Tpo libarchive/$(DEPDIR)/test-filter_fork_posix.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/filter_fork_posix.c' object='libarchive/test-filter_fork_posix.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-filter_fork_posix.obj `if test -f 'libarchive/filter_fork_posix.c'; then $(CYGPATH_W) 'libarchive/filter_fork_posix.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/filter_fork_posix.c'; fi` - -libarchive/test-xxhash.o: libarchive/xxhash.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-xxhash.o -MD -MP -MF libarchive/$(DEPDIR)/test-xxhash.Tpo -c -o libarchive/test-xxhash.o `test -f 'libarchive/xxhash.c' || echo '$(srcdir)/'`libarchive/xxhash.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-xxhash.Tpo libarchive/$(DEPDIR)/test-xxhash.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/xxhash.c' object='libarchive/test-xxhash.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-xxhash.o `test -f 'libarchive/xxhash.c' || echo '$(srcdir)/'`libarchive/xxhash.c - -libarchive/test-xxhash.obj: libarchive/xxhash.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-xxhash.obj -MD -MP -MF libarchive/$(DEPDIR)/test-xxhash.Tpo -c -o libarchive/test-xxhash.obj `if test -f 'libarchive/xxhash.c'; then $(CYGPATH_W) 'libarchive/xxhash.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/xxhash.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-xxhash.Tpo libarchive/$(DEPDIR)/test-xxhash.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/xxhash.c' object='libarchive/test-xxhash.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-xxhash.obj `if test -f 'libarchive/xxhash.c'; then $(CYGPATH_W) 'libarchive/xxhash.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/xxhash.c'; fi` - -libarchive/test-archive_entry_copy_bhfi.o: libarchive/archive_entry_copy_bhfi.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_entry_copy_bhfi.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_entry_copy_bhfi.Tpo -c -o libarchive/test-archive_entry_copy_bhfi.o `test -f 'libarchive/archive_entry_copy_bhfi.c' || echo '$(srcdir)/'`libarchive/archive_entry_copy_bhfi.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_entry_copy_bhfi.Tpo libarchive/$(DEPDIR)/test-archive_entry_copy_bhfi.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_entry_copy_bhfi.c' object='libarchive/test-archive_entry_copy_bhfi.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_entry_copy_bhfi.o `test -f 'libarchive/archive_entry_copy_bhfi.c' || echo '$(srcdir)/'`libarchive/archive_entry_copy_bhfi.c - -libarchive/test-archive_entry_copy_bhfi.obj: libarchive/archive_entry_copy_bhfi.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_entry_copy_bhfi.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_entry_copy_bhfi.Tpo -c -o libarchive/test-archive_entry_copy_bhfi.obj `if test -f 'libarchive/archive_entry_copy_bhfi.c'; then $(CYGPATH_W) 'libarchive/archive_entry_copy_bhfi.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_entry_copy_bhfi.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_entry_copy_bhfi.Tpo libarchive/$(DEPDIR)/test-archive_entry_copy_bhfi.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_entry_copy_bhfi.c' object='libarchive/test-archive_entry_copy_bhfi.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_entry_copy_bhfi.obj `if test -f 'libarchive/archive_entry_copy_bhfi.c'; then $(CYGPATH_W) 'libarchive/archive_entry_copy_bhfi.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_entry_copy_bhfi.c'; fi` - -libarchive/test-archive_read_disk_windows.o: libarchive/archive_read_disk_windows.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_disk_windows.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_disk_windows.Tpo -c -o libarchive/test-archive_read_disk_windows.o `test -f 'libarchive/archive_read_disk_windows.c' || echo '$(srcdir)/'`libarchive/archive_read_disk_windows.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_disk_windows.Tpo libarchive/$(DEPDIR)/test-archive_read_disk_windows.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_disk_windows.c' object='libarchive/test-archive_read_disk_windows.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_disk_windows.o `test -f 'libarchive/archive_read_disk_windows.c' || echo '$(srcdir)/'`libarchive/archive_read_disk_windows.c - -libarchive/test-archive_read_disk_windows.obj: libarchive/archive_read_disk_windows.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_read_disk_windows.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_read_disk_windows.Tpo -c -o libarchive/test-archive_read_disk_windows.obj `if test -f 'libarchive/archive_read_disk_windows.c'; then $(CYGPATH_W) 'libarchive/archive_read_disk_windows.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_disk_windows.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_read_disk_windows.Tpo libarchive/$(DEPDIR)/test-archive_read_disk_windows.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_read_disk_windows.c' object='libarchive/test-archive_read_disk_windows.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_read_disk_windows.obj `if test -f 'libarchive/archive_read_disk_windows.c'; then $(CYGPATH_W) 'libarchive/archive_read_disk_windows.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_read_disk_windows.c'; fi` - -libarchive/test-archive_windows.o: libarchive/archive_windows.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_windows.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_windows.Tpo -c -o libarchive/test-archive_windows.o `test -f 'libarchive/archive_windows.c' || echo '$(srcdir)/'`libarchive/archive_windows.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_windows.Tpo libarchive/$(DEPDIR)/test-archive_windows.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_windows.c' object='libarchive/test-archive_windows.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_windows.o `test -f 'libarchive/archive_windows.c' || echo '$(srcdir)/'`libarchive/archive_windows.c - -libarchive/test-archive_windows.obj: libarchive/archive_windows.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_windows.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_windows.Tpo -c -o libarchive/test-archive_windows.obj `if test -f 'libarchive/archive_windows.c'; then $(CYGPATH_W) 'libarchive/archive_windows.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_windows.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_windows.Tpo libarchive/$(DEPDIR)/test-archive_windows.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_windows.c' object='libarchive/test-archive_windows.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_windows.obj `if test -f 'libarchive/archive_windows.c'; then $(CYGPATH_W) 'libarchive/archive_windows.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_windows.c'; fi` - -libarchive/test-archive_write_disk_windows.o: libarchive/archive_write_disk_windows.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_disk_windows.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_disk_windows.Tpo -c -o libarchive/test-archive_write_disk_windows.o `test -f 'libarchive/archive_write_disk_windows.c' || echo '$(srcdir)/'`libarchive/archive_write_disk_windows.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_disk_windows.Tpo libarchive/$(DEPDIR)/test-archive_write_disk_windows.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_disk_windows.c' object='libarchive/test-archive_write_disk_windows.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_disk_windows.o `test -f 'libarchive/archive_write_disk_windows.c' || echo '$(srcdir)/'`libarchive/archive_write_disk_windows.c - -libarchive/test-archive_write_disk_windows.obj: libarchive/archive_write_disk_windows.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_write_disk_windows.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_write_disk_windows.Tpo -c -o libarchive/test-archive_write_disk_windows.obj `if test -f 'libarchive/archive_write_disk_windows.c'; then $(CYGPATH_W) 'libarchive/archive_write_disk_windows.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_disk_windows.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_write_disk_windows.Tpo libarchive/$(DEPDIR)/test-archive_write_disk_windows.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_write_disk_windows.c' object='libarchive/test-archive_write_disk_windows.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_write_disk_windows.obj `if test -f 'libarchive/archive_write_disk_windows.c'; then $(CYGPATH_W) 'libarchive/archive_write_disk_windows.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_write_disk_windows.c'; fi` - -libarchive/test-filter_fork_windows.o: libarchive/filter_fork_windows.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-filter_fork_windows.o -MD -MP -MF libarchive/$(DEPDIR)/test-filter_fork_windows.Tpo -c -o libarchive/test-filter_fork_windows.o `test -f 'libarchive/filter_fork_windows.c' || echo '$(srcdir)/'`libarchive/filter_fork_windows.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-filter_fork_windows.Tpo libarchive/$(DEPDIR)/test-filter_fork_windows.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/filter_fork_windows.c' object='libarchive/test-filter_fork_windows.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-filter_fork_windows.o `test -f 'libarchive/filter_fork_windows.c' || echo '$(srcdir)/'`libarchive/filter_fork_windows.c - -libarchive/test-filter_fork_windows.obj: libarchive/filter_fork_windows.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-filter_fork_windows.obj -MD -MP -MF libarchive/$(DEPDIR)/test-filter_fork_windows.Tpo -c -o libarchive/test-filter_fork_windows.obj `if test -f 'libarchive/filter_fork_windows.c'; then $(CYGPATH_W) 'libarchive/filter_fork_windows.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/filter_fork_windows.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-filter_fork_windows.Tpo libarchive/$(DEPDIR)/test-filter_fork_windows.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/filter_fork_windows.c' object='libarchive/test-filter_fork_windows.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-filter_fork_windows.obj `if test -f 'libarchive/filter_fork_windows.c'; then $(CYGPATH_W) 'libarchive/filter_fork_windows.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/filter_fork_windows.c'; fi` - -libarchive/test-archive_blake2s_ref.o: libarchive/archive_blake2s_ref.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_blake2s_ref.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_blake2s_ref.Tpo -c -o libarchive/test-archive_blake2s_ref.o `test -f 'libarchive/archive_blake2s_ref.c' || echo '$(srcdir)/'`libarchive/archive_blake2s_ref.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_blake2s_ref.Tpo libarchive/$(DEPDIR)/test-archive_blake2s_ref.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_blake2s_ref.c' object='libarchive/test-archive_blake2s_ref.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_blake2s_ref.o `test -f 'libarchive/archive_blake2s_ref.c' || echo '$(srcdir)/'`libarchive/archive_blake2s_ref.c - -libarchive/test-archive_blake2s_ref.obj: libarchive/archive_blake2s_ref.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_blake2s_ref.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_blake2s_ref.Tpo -c -o libarchive/test-archive_blake2s_ref.obj `if test -f 'libarchive/archive_blake2s_ref.c'; then $(CYGPATH_W) 'libarchive/archive_blake2s_ref.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_blake2s_ref.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_blake2s_ref.Tpo libarchive/$(DEPDIR)/test-archive_blake2s_ref.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_blake2s_ref.c' object='libarchive/test-archive_blake2s_ref.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_blake2s_ref.obj `if test -f 'libarchive/archive_blake2s_ref.c'; then $(CYGPATH_W) 'libarchive/archive_blake2s_ref.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_blake2s_ref.c'; fi` - -libarchive/test-archive_blake2sp_ref.o: libarchive/archive_blake2sp_ref.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_blake2sp_ref.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_blake2sp_ref.Tpo -c -o libarchive/test-archive_blake2sp_ref.o `test -f 'libarchive/archive_blake2sp_ref.c' || echo '$(srcdir)/'`libarchive/archive_blake2sp_ref.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_blake2sp_ref.Tpo libarchive/$(DEPDIR)/test-archive_blake2sp_ref.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_blake2sp_ref.c' object='libarchive/test-archive_blake2sp_ref.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_blake2sp_ref.o `test -f 'libarchive/archive_blake2sp_ref.c' || echo '$(srcdir)/'`libarchive/archive_blake2sp_ref.c - -libarchive/test-archive_blake2sp_ref.obj: libarchive/archive_blake2sp_ref.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_blake2sp_ref.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_blake2sp_ref.Tpo -c -o libarchive/test-archive_blake2sp_ref.obj `if test -f 'libarchive/archive_blake2sp_ref.c'; then $(CYGPATH_W) 'libarchive/archive_blake2sp_ref.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_blake2sp_ref.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_blake2sp_ref.Tpo libarchive/$(DEPDIR)/test-archive_blake2sp_ref.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_blake2sp_ref.c' object='libarchive/test-archive_blake2sp_ref.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_blake2sp_ref.obj `if test -f 'libarchive/archive_blake2sp_ref.c'; then $(CYGPATH_W) 'libarchive/archive_blake2sp_ref.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_blake2sp_ref.c'; fi` - -libarchive/test-archive_disk_acl_linux.o: libarchive/archive_disk_acl_linux.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_disk_acl_linux.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_disk_acl_linux.Tpo -c -o libarchive/test-archive_disk_acl_linux.o `test -f 'libarchive/archive_disk_acl_linux.c' || echo '$(srcdir)/'`libarchive/archive_disk_acl_linux.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_disk_acl_linux.Tpo libarchive/$(DEPDIR)/test-archive_disk_acl_linux.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_disk_acl_linux.c' object='libarchive/test-archive_disk_acl_linux.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_disk_acl_linux.o `test -f 'libarchive/archive_disk_acl_linux.c' || echo '$(srcdir)/'`libarchive/archive_disk_acl_linux.c - -libarchive/test-archive_disk_acl_linux.obj: libarchive/archive_disk_acl_linux.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_disk_acl_linux.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_disk_acl_linux.Tpo -c -o libarchive/test-archive_disk_acl_linux.obj `if test -f 'libarchive/archive_disk_acl_linux.c'; then $(CYGPATH_W) 'libarchive/archive_disk_acl_linux.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_disk_acl_linux.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_disk_acl_linux.Tpo libarchive/$(DEPDIR)/test-archive_disk_acl_linux.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_disk_acl_linux.c' object='libarchive/test-archive_disk_acl_linux.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_disk_acl_linux.obj `if test -f 'libarchive/archive_disk_acl_linux.c'; then $(CYGPATH_W) 'libarchive/archive_disk_acl_linux.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_disk_acl_linux.c'; fi` - -libarchive/test-archive_disk_acl_sunos.o: libarchive/archive_disk_acl_sunos.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_disk_acl_sunos.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_disk_acl_sunos.Tpo -c -o libarchive/test-archive_disk_acl_sunos.o `test -f 'libarchive/archive_disk_acl_sunos.c' || echo '$(srcdir)/'`libarchive/archive_disk_acl_sunos.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_disk_acl_sunos.Tpo libarchive/$(DEPDIR)/test-archive_disk_acl_sunos.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_disk_acl_sunos.c' object='libarchive/test-archive_disk_acl_sunos.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_disk_acl_sunos.o `test -f 'libarchive/archive_disk_acl_sunos.c' || echo '$(srcdir)/'`libarchive/archive_disk_acl_sunos.c - -libarchive/test-archive_disk_acl_sunos.obj: libarchive/archive_disk_acl_sunos.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_disk_acl_sunos.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_disk_acl_sunos.Tpo -c -o libarchive/test-archive_disk_acl_sunos.obj `if test -f 'libarchive/archive_disk_acl_sunos.c'; then $(CYGPATH_W) 'libarchive/archive_disk_acl_sunos.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_disk_acl_sunos.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_disk_acl_sunos.Tpo libarchive/$(DEPDIR)/test-archive_disk_acl_sunos.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_disk_acl_sunos.c' object='libarchive/test-archive_disk_acl_sunos.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_disk_acl_sunos.obj `if test -f 'libarchive/archive_disk_acl_sunos.c'; then $(CYGPATH_W) 'libarchive/archive_disk_acl_sunos.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_disk_acl_sunos.c'; fi` - -libarchive/test-archive_disk_acl_darwin.o: libarchive/archive_disk_acl_darwin.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_disk_acl_darwin.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_disk_acl_darwin.Tpo -c -o libarchive/test-archive_disk_acl_darwin.o `test -f 'libarchive/archive_disk_acl_darwin.c' || echo '$(srcdir)/'`libarchive/archive_disk_acl_darwin.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_disk_acl_darwin.Tpo libarchive/$(DEPDIR)/test-archive_disk_acl_darwin.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_disk_acl_darwin.c' object='libarchive/test-archive_disk_acl_darwin.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_disk_acl_darwin.o `test -f 'libarchive/archive_disk_acl_darwin.c' || echo '$(srcdir)/'`libarchive/archive_disk_acl_darwin.c - -libarchive/test-archive_disk_acl_darwin.obj: libarchive/archive_disk_acl_darwin.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_disk_acl_darwin.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_disk_acl_darwin.Tpo -c -o libarchive/test-archive_disk_acl_darwin.obj `if test -f 'libarchive/archive_disk_acl_darwin.c'; then $(CYGPATH_W) 'libarchive/archive_disk_acl_darwin.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_disk_acl_darwin.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_disk_acl_darwin.Tpo libarchive/$(DEPDIR)/test-archive_disk_acl_darwin.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_disk_acl_darwin.c' object='libarchive/test-archive_disk_acl_darwin.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_disk_acl_darwin.obj `if test -f 'libarchive/archive_disk_acl_darwin.c'; then $(CYGPATH_W) 'libarchive/archive_disk_acl_darwin.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_disk_acl_darwin.c'; fi` - -libarchive/test-archive_disk_acl_freebsd.o: libarchive/archive_disk_acl_freebsd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_disk_acl_freebsd.o -MD -MP -MF libarchive/$(DEPDIR)/test-archive_disk_acl_freebsd.Tpo -c -o libarchive/test-archive_disk_acl_freebsd.o `test -f 'libarchive/archive_disk_acl_freebsd.c' || echo '$(srcdir)/'`libarchive/archive_disk_acl_freebsd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_disk_acl_freebsd.Tpo libarchive/$(DEPDIR)/test-archive_disk_acl_freebsd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_disk_acl_freebsd.c' object='libarchive/test-archive_disk_acl_freebsd.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_disk_acl_freebsd.o `test -f 'libarchive/archive_disk_acl_freebsd.c' || echo '$(srcdir)/'`libarchive/archive_disk_acl_freebsd.c - -libarchive/test-archive_disk_acl_freebsd.obj: libarchive/archive_disk_acl_freebsd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test-archive_disk_acl_freebsd.obj -MD -MP -MF libarchive/$(DEPDIR)/test-archive_disk_acl_freebsd.Tpo -c -o libarchive/test-archive_disk_acl_freebsd.obj `if test -f 'libarchive/archive_disk_acl_freebsd.c'; then $(CYGPATH_W) 'libarchive/archive_disk_acl_freebsd.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_disk_acl_freebsd.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/$(DEPDIR)/test-archive_disk_acl_freebsd.Tpo libarchive/$(DEPDIR)/test-archive_disk_acl_freebsd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/archive_disk_acl_freebsd.c' object='libarchive/test-archive_disk_acl_freebsd.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test-archive_disk_acl_freebsd.obj `if test -f 'libarchive/archive_disk_acl_freebsd.c'; then $(CYGPATH_W) 'libarchive/archive_disk_acl_freebsd.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/archive_disk_acl_freebsd.c'; fi` - -test_utils/libarchive_test-test_utils.o: test_utils/test_utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_utils/libarchive_test-test_utils.o -MD -MP -MF test_utils/$(DEPDIR)/libarchive_test-test_utils.Tpo -c -o test_utils/libarchive_test-test_utils.o `test -f 'test_utils/test_utils.c' || echo '$(srcdir)/'`test_utils/test_utils.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test_utils/$(DEPDIR)/libarchive_test-test_utils.Tpo test_utils/$(DEPDIR)/libarchive_test-test_utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_utils/test_utils.c' object='test_utils/libarchive_test-test_utils.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_utils/libarchive_test-test_utils.o `test -f 'test_utils/test_utils.c' || echo '$(srcdir)/'`test_utils/test_utils.c - -test_utils/libarchive_test-test_utils.obj: test_utils/test_utils.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_utils/libarchive_test-test_utils.obj -MD -MP -MF test_utils/$(DEPDIR)/libarchive_test-test_utils.Tpo -c -o test_utils/libarchive_test-test_utils.obj `if test -f 'test_utils/test_utils.c'; then $(CYGPATH_W) 'test_utils/test_utils.c'; else $(CYGPATH_W) '$(srcdir)/test_utils/test_utils.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test_utils/$(DEPDIR)/libarchive_test-test_utils.Tpo test_utils/$(DEPDIR)/libarchive_test-test_utils.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_utils/test_utils.c' object='test_utils/libarchive_test-test_utils.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_utils/libarchive_test-test_utils.obj `if test -f 'test_utils/test_utils.c'; then $(CYGPATH_W) 'test_utils/test_utils.c'; else $(CYGPATH_W) '$(srcdir)/test_utils/test_utils.c'; fi` - -test_utils/libarchive_test-test_main.o: test_utils/test_main.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_utils/libarchive_test-test_main.o -MD -MP -MF test_utils/$(DEPDIR)/libarchive_test-test_main.Tpo -c -o test_utils/libarchive_test-test_main.o `test -f 'test_utils/test_main.c' || echo '$(srcdir)/'`test_utils/test_main.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test_utils/$(DEPDIR)/libarchive_test-test_main.Tpo test_utils/$(DEPDIR)/libarchive_test-test_main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_utils/test_main.c' object='test_utils/libarchive_test-test_main.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_utils/libarchive_test-test_main.o `test -f 'test_utils/test_main.c' || echo '$(srcdir)/'`test_utils/test_main.c - -test_utils/libarchive_test-test_main.obj: test_utils/test_main.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_utils/libarchive_test-test_main.obj -MD -MP -MF test_utils/$(DEPDIR)/libarchive_test-test_main.Tpo -c -o test_utils/libarchive_test-test_main.obj `if test -f 'test_utils/test_main.c'; then $(CYGPATH_W) 'test_utils/test_main.c'; else $(CYGPATH_W) '$(srcdir)/test_utils/test_main.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test_utils/$(DEPDIR)/libarchive_test-test_main.Tpo test_utils/$(DEPDIR)/libarchive_test-test_main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_utils/test_main.c' object='test_utils/libarchive_test-test_main.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_utils/libarchive_test-test_main.obj `if test -f 'test_utils/test_main.c'; then $(CYGPATH_W) 'test_utils/test_main.c'; else $(CYGPATH_W) '$(srcdir)/test_utils/test_main.c'; fi` - -libarchive/test/test-read_open_memory.o: libarchive/test/read_open_memory.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-read_open_memory.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-read_open_memory.Tpo -c -o libarchive/test/test-read_open_memory.o `test -f 'libarchive/test/read_open_memory.c' || echo '$(srcdir)/'`libarchive/test/read_open_memory.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-read_open_memory.Tpo libarchive/test/$(DEPDIR)/test-read_open_memory.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/read_open_memory.c' object='libarchive/test/test-read_open_memory.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-read_open_memory.o `test -f 'libarchive/test/read_open_memory.c' || echo '$(srcdir)/'`libarchive/test/read_open_memory.c - -libarchive/test/test-read_open_memory.obj: libarchive/test/read_open_memory.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-read_open_memory.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-read_open_memory.Tpo -c -o libarchive/test/test-read_open_memory.obj `if test -f 'libarchive/test/read_open_memory.c'; then $(CYGPATH_W) 'libarchive/test/read_open_memory.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/read_open_memory.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-read_open_memory.Tpo libarchive/test/$(DEPDIR)/test-read_open_memory.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/read_open_memory.c' object='libarchive/test/test-read_open_memory.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-read_open_memory.obj `if test -f 'libarchive/test/read_open_memory.c'; then $(CYGPATH_W) 'libarchive/test/read_open_memory.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/read_open_memory.c'; fi` - -libarchive/test/test-test_acl_nfs4.o: libarchive/test/test_acl_nfs4.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_acl_nfs4.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_acl_nfs4.Tpo -c -o libarchive/test/test-test_acl_nfs4.o `test -f 'libarchive/test/test_acl_nfs4.c' || echo '$(srcdir)/'`libarchive/test/test_acl_nfs4.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_acl_nfs4.Tpo libarchive/test/$(DEPDIR)/test-test_acl_nfs4.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_acl_nfs4.c' object='libarchive/test/test-test_acl_nfs4.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_acl_nfs4.o `test -f 'libarchive/test/test_acl_nfs4.c' || echo '$(srcdir)/'`libarchive/test/test_acl_nfs4.c - -libarchive/test/test-test_acl_nfs4.obj: libarchive/test/test_acl_nfs4.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_acl_nfs4.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_acl_nfs4.Tpo -c -o libarchive/test/test-test_acl_nfs4.obj `if test -f 'libarchive/test/test_acl_nfs4.c'; then $(CYGPATH_W) 'libarchive/test/test_acl_nfs4.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_acl_nfs4.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_acl_nfs4.Tpo libarchive/test/$(DEPDIR)/test-test_acl_nfs4.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_acl_nfs4.c' object='libarchive/test/test-test_acl_nfs4.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_acl_nfs4.obj `if test -f 'libarchive/test/test_acl_nfs4.c'; then $(CYGPATH_W) 'libarchive/test/test_acl_nfs4.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_acl_nfs4.c'; fi` - -libarchive/test/test-test_acl_pax.o: libarchive/test/test_acl_pax.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_acl_pax.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_acl_pax.Tpo -c -o libarchive/test/test-test_acl_pax.o `test -f 'libarchive/test/test_acl_pax.c' || echo '$(srcdir)/'`libarchive/test/test_acl_pax.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_acl_pax.Tpo libarchive/test/$(DEPDIR)/test-test_acl_pax.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_acl_pax.c' object='libarchive/test/test-test_acl_pax.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_acl_pax.o `test -f 'libarchive/test/test_acl_pax.c' || echo '$(srcdir)/'`libarchive/test/test_acl_pax.c - -libarchive/test/test-test_acl_pax.obj: libarchive/test/test_acl_pax.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_acl_pax.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_acl_pax.Tpo -c -o libarchive/test/test-test_acl_pax.obj `if test -f 'libarchive/test/test_acl_pax.c'; then $(CYGPATH_W) 'libarchive/test/test_acl_pax.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_acl_pax.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_acl_pax.Tpo libarchive/test/$(DEPDIR)/test-test_acl_pax.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_acl_pax.c' object='libarchive/test/test-test_acl_pax.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_acl_pax.obj `if test -f 'libarchive/test/test_acl_pax.c'; then $(CYGPATH_W) 'libarchive/test/test_acl_pax.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_acl_pax.c'; fi` - -libarchive/test/test-test_acl_platform_nfs4.o: libarchive/test/test_acl_platform_nfs4.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_acl_platform_nfs4.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_acl_platform_nfs4.Tpo -c -o libarchive/test/test-test_acl_platform_nfs4.o `test -f 'libarchive/test/test_acl_platform_nfs4.c' || echo '$(srcdir)/'`libarchive/test/test_acl_platform_nfs4.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_acl_platform_nfs4.Tpo libarchive/test/$(DEPDIR)/test-test_acl_platform_nfs4.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_acl_platform_nfs4.c' object='libarchive/test/test-test_acl_platform_nfs4.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_acl_platform_nfs4.o `test -f 'libarchive/test/test_acl_platform_nfs4.c' || echo '$(srcdir)/'`libarchive/test/test_acl_platform_nfs4.c - -libarchive/test/test-test_acl_platform_nfs4.obj: libarchive/test/test_acl_platform_nfs4.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_acl_platform_nfs4.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_acl_platform_nfs4.Tpo -c -o libarchive/test/test-test_acl_platform_nfs4.obj `if test -f 'libarchive/test/test_acl_platform_nfs4.c'; then $(CYGPATH_W) 'libarchive/test/test_acl_platform_nfs4.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_acl_platform_nfs4.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_acl_platform_nfs4.Tpo libarchive/test/$(DEPDIR)/test-test_acl_platform_nfs4.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_acl_platform_nfs4.c' object='libarchive/test/test-test_acl_platform_nfs4.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_acl_platform_nfs4.obj `if test -f 'libarchive/test/test_acl_platform_nfs4.c'; then $(CYGPATH_W) 'libarchive/test/test_acl_platform_nfs4.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_acl_platform_nfs4.c'; fi` - -libarchive/test/test-test_acl_platform_posix1e.o: libarchive/test/test_acl_platform_posix1e.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_acl_platform_posix1e.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_acl_platform_posix1e.Tpo -c -o libarchive/test/test-test_acl_platform_posix1e.o `test -f 'libarchive/test/test_acl_platform_posix1e.c' || echo '$(srcdir)/'`libarchive/test/test_acl_platform_posix1e.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_acl_platform_posix1e.Tpo libarchive/test/$(DEPDIR)/test-test_acl_platform_posix1e.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_acl_platform_posix1e.c' object='libarchive/test/test-test_acl_platform_posix1e.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_acl_platform_posix1e.o `test -f 'libarchive/test/test_acl_platform_posix1e.c' || echo '$(srcdir)/'`libarchive/test/test_acl_platform_posix1e.c - -libarchive/test/test-test_acl_platform_posix1e.obj: libarchive/test/test_acl_platform_posix1e.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_acl_platform_posix1e.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_acl_platform_posix1e.Tpo -c -o libarchive/test/test-test_acl_platform_posix1e.obj `if test -f 'libarchive/test/test_acl_platform_posix1e.c'; then $(CYGPATH_W) 'libarchive/test/test_acl_platform_posix1e.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_acl_platform_posix1e.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_acl_platform_posix1e.Tpo libarchive/test/$(DEPDIR)/test-test_acl_platform_posix1e.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_acl_platform_posix1e.c' object='libarchive/test/test-test_acl_platform_posix1e.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_acl_platform_posix1e.obj `if test -f 'libarchive/test/test_acl_platform_posix1e.c'; then $(CYGPATH_W) 'libarchive/test/test_acl_platform_posix1e.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_acl_platform_posix1e.c'; fi` - -libarchive/test/test-test_acl_posix1e.o: libarchive/test/test_acl_posix1e.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_acl_posix1e.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_acl_posix1e.Tpo -c -o libarchive/test/test-test_acl_posix1e.o `test -f 'libarchive/test/test_acl_posix1e.c' || echo '$(srcdir)/'`libarchive/test/test_acl_posix1e.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_acl_posix1e.Tpo libarchive/test/$(DEPDIR)/test-test_acl_posix1e.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_acl_posix1e.c' object='libarchive/test/test-test_acl_posix1e.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_acl_posix1e.o `test -f 'libarchive/test/test_acl_posix1e.c' || echo '$(srcdir)/'`libarchive/test/test_acl_posix1e.c - -libarchive/test/test-test_acl_posix1e.obj: libarchive/test/test_acl_posix1e.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_acl_posix1e.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_acl_posix1e.Tpo -c -o libarchive/test/test-test_acl_posix1e.obj `if test -f 'libarchive/test/test_acl_posix1e.c'; then $(CYGPATH_W) 'libarchive/test/test_acl_posix1e.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_acl_posix1e.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_acl_posix1e.Tpo libarchive/test/$(DEPDIR)/test-test_acl_posix1e.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_acl_posix1e.c' object='libarchive/test/test-test_acl_posix1e.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_acl_posix1e.obj `if test -f 'libarchive/test/test_acl_posix1e.c'; then $(CYGPATH_W) 'libarchive/test/test_acl_posix1e.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_acl_posix1e.c'; fi` - -libarchive/test/test-test_acl_text.o: libarchive/test/test_acl_text.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_acl_text.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_acl_text.Tpo -c -o libarchive/test/test-test_acl_text.o `test -f 'libarchive/test/test_acl_text.c' || echo '$(srcdir)/'`libarchive/test/test_acl_text.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_acl_text.Tpo libarchive/test/$(DEPDIR)/test-test_acl_text.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_acl_text.c' object='libarchive/test/test-test_acl_text.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_acl_text.o `test -f 'libarchive/test/test_acl_text.c' || echo '$(srcdir)/'`libarchive/test/test_acl_text.c - -libarchive/test/test-test_acl_text.obj: libarchive/test/test_acl_text.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_acl_text.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_acl_text.Tpo -c -o libarchive/test/test-test_acl_text.obj `if test -f 'libarchive/test/test_acl_text.c'; then $(CYGPATH_W) 'libarchive/test/test_acl_text.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_acl_text.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_acl_text.Tpo libarchive/test/$(DEPDIR)/test-test_acl_text.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_acl_text.c' object='libarchive/test/test-test_acl_text.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_acl_text.obj `if test -f 'libarchive/test/test_acl_text.c'; then $(CYGPATH_W) 'libarchive/test/test_acl_text.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_acl_text.c'; fi` - -libarchive/test/test-test_archive_api_feature.o: libarchive/test/test_archive_api_feature.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_api_feature.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_api_feature.Tpo -c -o libarchive/test/test-test_archive_api_feature.o `test -f 'libarchive/test/test_archive_api_feature.c' || echo '$(srcdir)/'`libarchive/test/test_archive_api_feature.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_api_feature.Tpo libarchive/test/$(DEPDIR)/test-test_archive_api_feature.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_api_feature.c' object='libarchive/test/test-test_archive_api_feature.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_api_feature.o `test -f 'libarchive/test/test_archive_api_feature.c' || echo '$(srcdir)/'`libarchive/test/test_archive_api_feature.c - -libarchive/test/test-test_archive_api_feature.obj: libarchive/test/test_archive_api_feature.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_api_feature.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_api_feature.Tpo -c -o libarchive/test/test-test_archive_api_feature.obj `if test -f 'libarchive/test/test_archive_api_feature.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_api_feature.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_api_feature.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_api_feature.Tpo libarchive/test/$(DEPDIR)/test-test_archive_api_feature.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_api_feature.c' object='libarchive/test/test-test_archive_api_feature.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_api_feature.obj `if test -f 'libarchive/test/test_archive_api_feature.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_api_feature.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_api_feature.c'; fi` - -libarchive/test/test-test_archive_clear_error.o: libarchive/test/test_archive_clear_error.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_clear_error.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_clear_error.Tpo -c -o libarchive/test/test-test_archive_clear_error.o `test -f 'libarchive/test/test_archive_clear_error.c' || echo '$(srcdir)/'`libarchive/test/test_archive_clear_error.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_clear_error.Tpo libarchive/test/$(DEPDIR)/test-test_archive_clear_error.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_clear_error.c' object='libarchive/test/test-test_archive_clear_error.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_clear_error.o `test -f 'libarchive/test/test_archive_clear_error.c' || echo '$(srcdir)/'`libarchive/test/test_archive_clear_error.c - -libarchive/test/test-test_archive_clear_error.obj: libarchive/test/test_archive_clear_error.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_clear_error.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_clear_error.Tpo -c -o libarchive/test/test-test_archive_clear_error.obj `if test -f 'libarchive/test/test_archive_clear_error.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_clear_error.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_clear_error.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_clear_error.Tpo libarchive/test/$(DEPDIR)/test-test_archive_clear_error.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_clear_error.c' object='libarchive/test/test-test_archive_clear_error.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_clear_error.obj `if test -f 'libarchive/test/test_archive_clear_error.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_clear_error.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_clear_error.c'; fi` - -libarchive/test/test-test_archive_cmdline.o: libarchive/test/test_archive_cmdline.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_cmdline.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_cmdline.Tpo -c -o libarchive/test/test-test_archive_cmdline.o `test -f 'libarchive/test/test_archive_cmdline.c' || echo '$(srcdir)/'`libarchive/test/test_archive_cmdline.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_cmdline.Tpo libarchive/test/$(DEPDIR)/test-test_archive_cmdline.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_cmdline.c' object='libarchive/test/test-test_archive_cmdline.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_cmdline.o `test -f 'libarchive/test/test_archive_cmdline.c' || echo '$(srcdir)/'`libarchive/test/test_archive_cmdline.c - -libarchive/test/test-test_archive_cmdline.obj: libarchive/test/test_archive_cmdline.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_cmdline.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_cmdline.Tpo -c -o libarchive/test/test-test_archive_cmdline.obj `if test -f 'libarchive/test/test_archive_cmdline.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_cmdline.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_cmdline.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_cmdline.Tpo libarchive/test/$(DEPDIR)/test-test_archive_cmdline.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_cmdline.c' object='libarchive/test/test-test_archive_cmdline.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_cmdline.obj `if test -f 'libarchive/test/test_archive_cmdline.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_cmdline.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_cmdline.c'; fi` - -libarchive/test/test-test_archive_digest.o: libarchive/test/test_archive_digest.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_digest.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_digest.Tpo -c -o libarchive/test/test-test_archive_digest.o `test -f 'libarchive/test/test_archive_digest.c' || echo '$(srcdir)/'`libarchive/test/test_archive_digest.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_digest.Tpo libarchive/test/$(DEPDIR)/test-test_archive_digest.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_digest.c' object='libarchive/test/test-test_archive_digest.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_digest.o `test -f 'libarchive/test/test_archive_digest.c' || echo '$(srcdir)/'`libarchive/test/test_archive_digest.c - -libarchive/test/test-test_archive_digest.obj: libarchive/test/test_archive_digest.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_digest.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_digest.Tpo -c -o libarchive/test/test-test_archive_digest.obj `if test -f 'libarchive/test/test_archive_digest.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_digest.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_digest.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_digest.Tpo libarchive/test/$(DEPDIR)/test-test_archive_digest.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_digest.c' object='libarchive/test/test-test_archive_digest.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_digest.obj `if test -f 'libarchive/test/test_archive_digest.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_digest.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_digest.c'; fi` - -libarchive/test/test-test_archive_getdate.o: libarchive/test/test_archive_getdate.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_getdate.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_getdate.Tpo -c -o libarchive/test/test-test_archive_getdate.o `test -f 'libarchive/test/test_archive_getdate.c' || echo '$(srcdir)/'`libarchive/test/test_archive_getdate.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_getdate.Tpo libarchive/test/$(DEPDIR)/test-test_archive_getdate.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_getdate.c' object='libarchive/test/test-test_archive_getdate.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_getdate.o `test -f 'libarchive/test/test_archive_getdate.c' || echo '$(srcdir)/'`libarchive/test/test_archive_getdate.c - -libarchive/test/test-test_archive_getdate.obj: libarchive/test/test_archive_getdate.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_getdate.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_getdate.Tpo -c -o libarchive/test/test-test_archive_getdate.obj `if test -f 'libarchive/test/test_archive_getdate.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_getdate.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_getdate.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_getdate.Tpo libarchive/test/$(DEPDIR)/test-test_archive_getdate.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_getdate.c' object='libarchive/test/test-test_archive_getdate.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_getdate.obj `if test -f 'libarchive/test/test_archive_getdate.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_getdate.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_getdate.c'; fi` - -libarchive/test/test-test_archive_match_owner.o: libarchive/test/test_archive_match_owner.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_match_owner.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_match_owner.Tpo -c -o libarchive/test/test-test_archive_match_owner.o `test -f 'libarchive/test/test_archive_match_owner.c' || echo '$(srcdir)/'`libarchive/test/test_archive_match_owner.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_match_owner.Tpo libarchive/test/$(DEPDIR)/test-test_archive_match_owner.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_match_owner.c' object='libarchive/test/test-test_archive_match_owner.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_match_owner.o `test -f 'libarchive/test/test_archive_match_owner.c' || echo '$(srcdir)/'`libarchive/test/test_archive_match_owner.c - -libarchive/test/test-test_archive_match_owner.obj: libarchive/test/test_archive_match_owner.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_match_owner.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_match_owner.Tpo -c -o libarchive/test/test-test_archive_match_owner.obj `if test -f 'libarchive/test/test_archive_match_owner.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_match_owner.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_match_owner.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_match_owner.Tpo libarchive/test/$(DEPDIR)/test-test_archive_match_owner.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_match_owner.c' object='libarchive/test/test-test_archive_match_owner.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_match_owner.obj `if test -f 'libarchive/test/test_archive_match_owner.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_match_owner.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_match_owner.c'; fi` - -libarchive/test/test-test_archive_match_path.o: libarchive/test/test_archive_match_path.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_match_path.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_match_path.Tpo -c -o libarchive/test/test-test_archive_match_path.o `test -f 'libarchive/test/test_archive_match_path.c' || echo '$(srcdir)/'`libarchive/test/test_archive_match_path.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_match_path.Tpo libarchive/test/$(DEPDIR)/test-test_archive_match_path.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_match_path.c' object='libarchive/test/test-test_archive_match_path.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_match_path.o `test -f 'libarchive/test/test_archive_match_path.c' || echo '$(srcdir)/'`libarchive/test/test_archive_match_path.c - -libarchive/test/test-test_archive_match_path.obj: libarchive/test/test_archive_match_path.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_match_path.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_match_path.Tpo -c -o libarchive/test/test-test_archive_match_path.obj `if test -f 'libarchive/test/test_archive_match_path.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_match_path.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_match_path.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_match_path.Tpo libarchive/test/$(DEPDIR)/test-test_archive_match_path.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_match_path.c' object='libarchive/test/test-test_archive_match_path.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_match_path.obj `if test -f 'libarchive/test/test_archive_match_path.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_match_path.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_match_path.c'; fi` - -libarchive/test/test-test_archive_match_time.o: libarchive/test/test_archive_match_time.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_match_time.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_match_time.Tpo -c -o libarchive/test/test-test_archive_match_time.o `test -f 'libarchive/test/test_archive_match_time.c' || echo '$(srcdir)/'`libarchive/test/test_archive_match_time.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_match_time.Tpo libarchive/test/$(DEPDIR)/test-test_archive_match_time.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_match_time.c' object='libarchive/test/test-test_archive_match_time.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_match_time.o `test -f 'libarchive/test/test_archive_match_time.c' || echo '$(srcdir)/'`libarchive/test/test_archive_match_time.c - -libarchive/test/test-test_archive_match_time.obj: libarchive/test/test_archive_match_time.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_match_time.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_match_time.Tpo -c -o libarchive/test/test-test_archive_match_time.obj `if test -f 'libarchive/test/test_archive_match_time.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_match_time.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_match_time.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_match_time.Tpo libarchive/test/$(DEPDIR)/test-test_archive_match_time.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_match_time.c' object='libarchive/test/test-test_archive_match_time.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_match_time.obj `if test -f 'libarchive/test/test_archive_match_time.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_match_time.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_match_time.c'; fi` - -libarchive/test/test-test_archive_pathmatch.o: libarchive/test/test_archive_pathmatch.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_pathmatch.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_pathmatch.Tpo -c -o libarchive/test/test-test_archive_pathmatch.o `test -f 'libarchive/test/test_archive_pathmatch.c' || echo '$(srcdir)/'`libarchive/test/test_archive_pathmatch.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_pathmatch.Tpo libarchive/test/$(DEPDIR)/test-test_archive_pathmatch.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_pathmatch.c' object='libarchive/test/test-test_archive_pathmatch.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_pathmatch.o `test -f 'libarchive/test/test_archive_pathmatch.c' || echo '$(srcdir)/'`libarchive/test/test_archive_pathmatch.c - -libarchive/test/test-test_archive_pathmatch.obj: libarchive/test/test_archive_pathmatch.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_pathmatch.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_pathmatch.Tpo -c -o libarchive/test/test-test_archive_pathmatch.obj `if test -f 'libarchive/test/test_archive_pathmatch.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_pathmatch.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_pathmatch.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_pathmatch.Tpo libarchive/test/$(DEPDIR)/test-test_archive_pathmatch.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_pathmatch.c' object='libarchive/test/test-test_archive_pathmatch.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_pathmatch.obj `if test -f 'libarchive/test/test_archive_pathmatch.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_pathmatch.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_pathmatch.c'; fi` - -libarchive/test/test-test_archive_read_add_passphrase.o: libarchive/test/test_archive_read_add_passphrase.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_read_add_passphrase.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_read_add_passphrase.Tpo -c -o libarchive/test/test-test_archive_read_add_passphrase.o `test -f 'libarchive/test/test_archive_read_add_passphrase.c' || echo '$(srcdir)/'`libarchive/test/test_archive_read_add_passphrase.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_read_add_passphrase.Tpo libarchive/test/$(DEPDIR)/test-test_archive_read_add_passphrase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_read_add_passphrase.c' object='libarchive/test/test-test_archive_read_add_passphrase.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_read_add_passphrase.o `test -f 'libarchive/test/test_archive_read_add_passphrase.c' || echo '$(srcdir)/'`libarchive/test/test_archive_read_add_passphrase.c - -libarchive/test/test-test_archive_read_add_passphrase.obj: libarchive/test/test_archive_read_add_passphrase.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_read_add_passphrase.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_read_add_passphrase.Tpo -c -o libarchive/test/test-test_archive_read_add_passphrase.obj `if test -f 'libarchive/test/test_archive_read_add_passphrase.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_read_add_passphrase.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_read_add_passphrase.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_read_add_passphrase.Tpo libarchive/test/$(DEPDIR)/test-test_archive_read_add_passphrase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_read_add_passphrase.c' object='libarchive/test/test-test_archive_read_add_passphrase.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_read_add_passphrase.obj `if test -f 'libarchive/test/test_archive_read_add_passphrase.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_read_add_passphrase.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_read_add_passphrase.c'; fi` - -libarchive/test/test-test_archive_read_close_twice.o: libarchive/test/test_archive_read_close_twice.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_read_close_twice.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice.Tpo -c -o libarchive/test/test-test_archive_read_close_twice.o `test -f 'libarchive/test/test_archive_read_close_twice.c' || echo '$(srcdir)/'`libarchive/test/test_archive_read_close_twice.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice.Tpo libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_read_close_twice.c' object='libarchive/test/test-test_archive_read_close_twice.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_read_close_twice.o `test -f 'libarchive/test/test_archive_read_close_twice.c' || echo '$(srcdir)/'`libarchive/test/test_archive_read_close_twice.c - -libarchive/test/test-test_archive_read_close_twice.obj: libarchive/test/test_archive_read_close_twice.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_read_close_twice.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice.Tpo -c -o libarchive/test/test-test_archive_read_close_twice.obj `if test -f 'libarchive/test/test_archive_read_close_twice.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_read_close_twice.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_read_close_twice.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice.Tpo libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_read_close_twice.c' object='libarchive/test/test-test_archive_read_close_twice.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_read_close_twice.obj `if test -f 'libarchive/test/test_archive_read_close_twice.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_read_close_twice.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_read_close_twice.c'; fi` - -libarchive/test/test-test_archive_read_close_twice_open_fd.o: libarchive/test/test_archive_read_close_twice_open_fd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_read_close_twice_open_fd.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice_open_fd.Tpo -c -o libarchive/test/test-test_archive_read_close_twice_open_fd.o `test -f 'libarchive/test/test_archive_read_close_twice_open_fd.c' || echo '$(srcdir)/'`libarchive/test/test_archive_read_close_twice_open_fd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice_open_fd.Tpo libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice_open_fd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_read_close_twice_open_fd.c' object='libarchive/test/test-test_archive_read_close_twice_open_fd.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_read_close_twice_open_fd.o `test -f 'libarchive/test/test_archive_read_close_twice_open_fd.c' || echo '$(srcdir)/'`libarchive/test/test_archive_read_close_twice_open_fd.c - -libarchive/test/test-test_archive_read_close_twice_open_fd.obj: libarchive/test/test_archive_read_close_twice_open_fd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_read_close_twice_open_fd.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice_open_fd.Tpo -c -o libarchive/test/test-test_archive_read_close_twice_open_fd.obj `if test -f 'libarchive/test/test_archive_read_close_twice_open_fd.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_read_close_twice_open_fd.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_read_close_twice_open_fd.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice_open_fd.Tpo libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice_open_fd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_read_close_twice_open_fd.c' object='libarchive/test/test-test_archive_read_close_twice_open_fd.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_read_close_twice_open_fd.obj `if test -f 'libarchive/test/test_archive_read_close_twice_open_fd.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_read_close_twice_open_fd.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_read_close_twice_open_fd.c'; fi` - -libarchive/test/test-test_archive_read_close_twice_open_filename.o: libarchive/test/test_archive_read_close_twice_open_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_read_close_twice_open_filename.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice_open_filename.Tpo -c -o libarchive/test/test-test_archive_read_close_twice_open_filename.o `test -f 'libarchive/test/test_archive_read_close_twice_open_filename.c' || echo '$(srcdir)/'`libarchive/test/test_archive_read_close_twice_open_filename.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice_open_filename.Tpo libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice_open_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_read_close_twice_open_filename.c' object='libarchive/test/test-test_archive_read_close_twice_open_filename.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_read_close_twice_open_filename.o `test -f 'libarchive/test/test_archive_read_close_twice_open_filename.c' || echo '$(srcdir)/'`libarchive/test/test_archive_read_close_twice_open_filename.c - -libarchive/test/test-test_archive_read_close_twice_open_filename.obj: libarchive/test/test_archive_read_close_twice_open_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_read_close_twice_open_filename.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice_open_filename.Tpo -c -o libarchive/test/test-test_archive_read_close_twice_open_filename.obj `if test -f 'libarchive/test/test_archive_read_close_twice_open_filename.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_read_close_twice_open_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_read_close_twice_open_filename.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice_open_filename.Tpo libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice_open_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_read_close_twice_open_filename.c' object='libarchive/test/test-test_archive_read_close_twice_open_filename.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_read_close_twice_open_filename.obj `if test -f 'libarchive/test/test_archive_read_close_twice_open_filename.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_read_close_twice_open_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_read_close_twice_open_filename.c'; fi` - -libarchive/test/test-test_archive_read_multiple_data_objects.o: libarchive/test/test_archive_read_multiple_data_objects.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_read_multiple_data_objects.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_read_multiple_data_objects.Tpo -c -o libarchive/test/test-test_archive_read_multiple_data_objects.o `test -f 'libarchive/test/test_archive_read_multiple_data_objects.c' || echo '$(srcdir)/'`libarchive/test/test_archive_read_multiple_data_objects.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_read_multiple_data_objects.Tpo libarchive/test/$(DEPDIR)/test-test_archive_read_multiple_data_objects.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_read_multiple_data_objects.c' object='libarchive/test/test-test_archive_read_multiple_data_objects.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_read_multiple_data_objects.o `test -f 'libarchive/test/test_archive_read_multiple_data_objects.c' || echo '$(srcdir)/'`libarchive/test/test_archive_read_multiple_data_objects.c - -libarchive/test/test-test_archive_read_multiple_data_objects.obj: libarchive/test/test_archive_read_multiple_data_objects.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_read_multiple_data_objects.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_read_multiple_data_objects.Tpo -c -o libarchive/test/test-test_archive_read_multiple_data_objects.obj `if test -f 'libarchive/test/test_archive_read_multiple_data_objects.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_read_multiple_data_objects.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_read_multiple_data_objects.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_read_multiple_data_objects.Tpo libarchive/test/$(DEPDIR)/test-test_archive_read_multiple_data_objects.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_read_multiple_data_objects.c' object='libarchive/test/test-test_archive_read_multiple_data_objects.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_read_multiple_data_objects.obj `if test -f 'libarchive/test/test_archive_read_multiple_data_objects.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_read_multiple_data_objects.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_read_multiple_data_objects.c'; fi` - -libarchive/test/test-test_archive_read_next_header_empty.o: libarchive/test/test_archive_read_next_header_empty.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_read_next_header_empty.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_read_next_header_empty.Tpo -c -o libarchive/test/test-test_archive_read_next_header_empty.o `test -f 'libarchive/test/test_archive_read_next_header_empty.c' || echo '$(srcdir)/'`libarchive/test/test_archive_read_next_header_empty.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_read_next_header_empty.Tpo libarchive/test/$(DEPDIR)/test-test_archive_read_next_header_empty.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_read_next_header_empty.c' object='libarchive/test/test-test_archive_read_next_header_empty.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_read_next_header_empty.o `test -f 'libarchive/test/test_archive_read_next_header_empty.c' || echo '$(srcdir)/'`libarchive/test/test_archive_read_next_header_empty.c - -libarchive/test/test-test_archive_read_next_header_empty.obj: libarchive/test/test_archive_read_next_header_empty.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_read_next_header_empty.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_read_next_header_empty.Tpo -c -o libarchive/test/test-test_archive_read_next_header_empty.obj `if test -f 'libarchive/test/test_archive_read_next_header_empty.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_read_next_header_empty.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_read_next_header_empty.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_read_next_header_empty.Tpo libarchive/test/$(DEPDIR)/test-test_archive_read_next_header_empty.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_read_next_header_empty.c' object='libarchive/test/test-test_archive_read_next_header_empty.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_read_next_header_empty.obj `if test -f 'libarchive/test/test_archive_read_next_header_empty.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_read_next_header_empty.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_read_next_header_empty.c'; fi` - -libarchive/test/test-test_archive_read_next_header_raw.o: libarchive/test/test_archive_read_next_header_raw.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_read_next_header_raw.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_read_next_header_raw.Tpo -c -o libarchive/test/test-test_archive_read_next_header_raw.o `test -f 'libarchive/test/test_archive_read_next_header_raw.c' || echo '$(srcdir)/'`libarchive/test/test_archive_read_next_header_raw.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_read_next_header_raw.Tpo libarchive/test/$(DEPDIR)/test-test_archive_read_next_header_raw.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_read_next_header_raw.c' object='libarchive/test/test-test_archive_read_next_header_raw.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_read_next_header_raw.o `test -f 'libarchive/test/test_archive_read_next_header_raw.c' || echo '$(srcdir)/'`libarchive/test/test_archive_read_next_header_raw.c - -libarchive/test/test-test_archive_read_next_header_raw.obj: libarchive/test/test_archive_read_next_header_raw.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_read_next_header_raw.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_read_next_header_raw.Tpo -c -o libarchive/test/test-test_archive_read_next_header_raw.obj `if test -f 'libarchive/test/test_archive_read_next_header_raw.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_read_next_header_raw.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_read_next_header_raw.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_read_next_header_raw.Tpo libarchive/test/$(DEPDIR)/test-test_archive_read_next_header_raw.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_read_next_header_raw.c' object='libarchive/test/test-test_archive_read_next_header_raw.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_read_next_header_raw.obj `if test -f 'libarchive/test/test_archive_read_next_header_raw.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_read_next_header_raw.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_read_next_header_raw.c'; fi` - -libarchive/test/test-test_archive_read_open2.o: libarchive/test/test_archive_read_open2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_read_open2.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_read_open2.Tpo -c -o libarchive/test/test-test_archive_read_open2.o `test -f 'libarchive/test/test_archive_read_open2.c' || echo '$(srcdir)/'`libarchive/test/test_archive_read_open2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_read_open2.Tpo libarchive/test/$(DEPDIR)/test-test_archive_read_open2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_read_open2.c' object='libarchive/test/test-test_archive_read_open2.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_read_open2.o `test -f 'libarchive/test/test_archive_read_open2.c' || echo '$(srcdir)/'`libarchive/test/test_archive_read_open2.c - -libarchive/test/test-test_archive_read_open2.obj: libarchive/test/test_archive_read_open2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_read_open2.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_read_open2.Tpo -c -o libarchive/test/test-test_archive_read_open2.obj `if test -f 'libarchive/test/test_archive_read_open2.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_read_open2.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_read_open2.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_read_open2.Tpo libarchive/test/$(DEPDIR)/test-test_archive_read_open2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_read_open2.c' object='libarchive/test/test-test_archive_read_open2.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_read_open2.obj `if test -f 'libarchive/test/test_archive_read_open2.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_read_open2.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_read_open2.c'; fi` - -libarchive/test/test-test_archive_read_set_filter_option.o: libarchive/test/test_archive_read_set_filter_option.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_read_set_filter_option.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_read_set_filter_option.Tpo -c -o libarchive/test/test-test_archive_read_set_filter_option.o `test -f 'libarchive/test/test_archive_read_set_filter_option.c' || echo '$(srcdir)/'`libarchive/test/test_archive_read_set_filter_option.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_read_set_filter_option.Tpo libarchive/test/$(DEPDIR)/test-test_archive_read_set_filter_option.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_read_set_filter_option.c' object='libarchive/test/test-test_archive_read_set_filter_option.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_read_set_filter_option.o `test -f 'libarchive/test/test_archive_read_set_filter_option.c' || echo '$(srcdir)/'`libarchive/test/test_archive_read_set_filter_option.c - -libarchive/test/test-test_archive_read_set_filter_option.obj: libarchive/test/test_archive_read_set_filter_option.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_read_set_filter_option.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_read_set_filter_option.Tpo -c -o libarchive/test/test-test_archive_read_set_filter_option.obj `if test -f 'libarchive/test/test_archive_read_set_filter_option.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_read_set_filter_option.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_read_set_filter_option.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_read_set_filter_option.Tpo libarchive/test/$(DEPDIR)/test-test_archive_read_set_filter_option.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_read_set_filter_option.c' object='libarchive/test/test-test_archive_read_set_filter_option.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_read_set_filter_option.obj `if test -f 'libarchive/test/test_archive_read_set_filter_option.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_read_set_filter_option.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_read_set_filter_option.c'; fi` - -libarchive/test/test-test_archive_read_set_format_option.o: libarchive/test/test_archive_read_set_format_option.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_read_set_format_option.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_read_set_format_option.Tpo -c -o libarchive/test/test-test_archive_read_set_format_option.o `test -f 'libarchive/test/test_archive_read_set_format_option.c' || echo '$(srcdir)/'`libarchive/test/test_archive_read_set_format_option.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_read_set_format_option.Tpo libarchive/test/$(DEPDIR)/test-test_archive_read_set_format_option.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_read_set_format_option.c' object='libarchive/test/test-test_archive_read_set_format_option.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_read_set_format_option.o `test -f 'libarchive/test/test_archive_read_set_format_option.c' || echo '$(srcdir)/'`libarchive/test/test_archive_read_set_format_option.c - -libarchive/test/test-test_archive_read_set_format_option.obj: libarchive/test/test_archive_read_set_format_option.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_read_set_format_option.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_read_set_format_option.Tpo -c -o libarchive/test/test-test_archive_read_set_format_option.obj `if test -f 'libarchive/test/test_archive_read_set_format_option.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_read_set_format_option.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_read_set_format_option.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_read_set_format_option.Tpo libarchive/test/$(DEPDIR)/test-test_archive_read_set_format_option.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_read_set_format_option.c' object='libarchive/test/test-test_archive_read_set_format_option.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_read_set_format_option.obj `if test -f 'libarchive/test/test_archive_read_set_format_option.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_read_set_format_option.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_read_set_format_option.c'; fi` - -libarchive/test/test-test_archive_read_set_option.o: libarchive/test/test_archive_read_set_option.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_read_set_option.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_read_set_option.Tpo -c -o libarchive/test/test-test_archive_read_set_option.o `test -f 'libarchive/test/test_archive_read_set_option.c' || echo '$(srcdir)/'`libarchive/test/test_archive_read_set_option.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_read_set_option.Tpo libarchive/test/$(DEPDIR)/test-test_archive_read_set_option.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_read_set_option.c' object='libarchive/test/test-test_archive_read_set_option.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_read_set_option.o `test -f 'libarchive/test/test_archive_read_set_option.c' || echo '$(srcdir)/'`libarchive/test/test_archive_read_set_option.c - -libarchive/test/test-test_archive_read_set_option.obj: libarchive/test/test_archive_read_set_option.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_read_set_option.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_read_set_option.Tpo -c -o libarchive/test/test-test_archive_read_set_option.obj `if test -f 'libarchive/test/test_archive_read_set_option.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_read_set_option.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_read_set_option.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_read_set_option.Tpo libarchive/test/$(DEPDIR)/test-test_archive_read_set_option.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_read_set_option.c' object='libarchive/test/test-test_archive_read_set_option.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_read_set_option.obj `if test -f 'libarchive/test/test_archive_read_set_option.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_read_set_option.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_read_set_option.c'; fi` - -libarchive/test/test-test_archive_read_set_options.o: libarchive/test/test_archive_read_set_options.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_read_set_options.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_read_set_options.Tpo -c -o libarchive/test/test-test_archive_read_set_options.o `test -f 'libarchive/test/test_archive_read_set_options.c' || echo '$(srcdir)/'`libarchive/test/test_archive_read_set_options.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_read_set_options.Tpo libarchive/test/$(DEPDIR)/test-test_archive_read_set_options.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_read_set_options.c' object='libarchive/test/test-test_archive_read_set_options.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_read_set_options.o `test -f 'libarchive/test/test_archive_read_set_options.c' || echo '$(srcdir)/'`libarchive/test/test_archive_read_set_options.c - -libarchive/test/test-test_archive_read_set_options.obj: libarchive/test/test_archive_read_set_options.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_read_set_options.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_read_set_options.Tpo -c -o libarchive/test/test-test_archive_read_set_options.obj `if test -f 'libarchive/test/test_archive_read_set_options.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_read_set_options.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_read_set_options.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_read_set_options.Tpo libarchive/test/$(DEPDIR)/test-test_archive_read_set_options.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_read_set_options.c' object='libarchive/test/test-test_archive_read_set_options.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_read_set_options.obj `if test -f 'libarchive/test/test_archive_read_set_options.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_read_set_options.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_read_set_options.c'; fi` - -libarchive/test/test-test_archive_read_support.o: libarchive/test/test_archive_read_support.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_read_support.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_read_support.Tpo -c -o libarchive/test/test-test_archive_read_support.o `test -f 'libarchive/test/test_archive_read_support.c' || echo '$(srcdir)/'`libarchive/test/test_archive_read_support.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_read_support.Tpo libarchive/test/$(DEPDIR)/test-test_archive_read_support.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_read_support.c' object='libarchive/test/test-test_archive_read_support.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_read_support.o `test -f 'libarchive/test/test_archive_read_support.c' || echo '$(srcdir)/'`libarchive/test/test_archive_read_support.c - -libarchive/test/test-test_archive_read_support.obj: libarchive/test/test_archive_read_support.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_read_support.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_read_support.Tpo -c -o libarchive/test/test-test_archive_read_support.obj `if test -f 'libarchive/test/test_archive_read_support.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_read_support.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_read_support.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_read_support.Tpo libarchive/test/$(DEPDIR)/test-test_archive_read_support.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_read_support.c' object='libarchive/test/test-test_archive_read_support.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_read_support.obj `if test -f 'libarchive/test/test_archive_read_support.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_read_support.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_read_support.c'; fi` - -libarchive/test/test-test_archive_set_error.o: libarchive/test/test_archive_set_error.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_set_error.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_set_error.Tpo -c -o libarchive/test/test-test_archive_set_error.o `test -f 'libarchive/test/test_archive_set_error.c' || echo '$(srcdir)/'`libarchive/test/test_archive_set_error.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_set_error.Tpo libarchive/test/$(DEPDIR)/test-test_archive_set_error.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_set_error.c' object='libarchive/test/test-test_archive_set_error.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_set_error.o `test -f 'libarchive/test/test_archive_set_error.c' || echo '$(srcdir)/'`libarchive/test/test_archive_set_error.c - -libarchive/test/test-test_archive_set_error.obj: libarchive/test/test_archive_set_error.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_set_error.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_set_error.Tpo -c -o libarchive/test/test-test_archive_set_error.obj `if test -f 'libarchive/test/test_archive_set_error.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_set_error.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_set_error.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_set_error.Tpo libarchive/test/$(DEPDIR)/test-test_archive_set_error.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_set_error.c' object='libarchive/test/test-test_archive_set_error.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_set_error.obj `if test -f 'libarchive/test/test_archive_set_error.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_set_error.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_set_error.c'; fi` - -libarchive/test/test-test_archive_string.o: libarchive/test/test_archive_string.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_string.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_string.Tpo -c -o libarchive/test/test-test_archive_string.o `test -f 'libarchive/test/test_archive_string.c' || echo '$(srcdir)/'`libarchive/test/test_archive_string.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_string.Tpo libarchive/test/$(DEPDIR)/test-test_archive_string.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_string.c' object='libarchive/test/test-test_archive_string.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_string.o `test -f 'libarchive/test/test_archive_string.c' || echo '$(srcdir)/'`libarchive/test/test_archive_string.c - -libarchive/test/test-test_archive_string.obj: libarchive/test/test_archive_string.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_string.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_string.Tpo -c -o libarchive/test/test-test_archive_string.obj `if test -f 'libarchive/test/test_archive_string.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_string.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_string.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_string.Tpo libarchive/test/$(DEPDIR)/test-test_archive_string.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_string.c' object='libarchive/test/test-test_archive_string.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_string.obj `if test -f 'libarchive/test/test_archive_string.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_string.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_string.c'; fi` - -libarchive/test/test-test_archive_string_conversion.o: libarchive/test/test_archive_string_conversion.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_string_conversion.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_string_conversion.Tpo -c -o libarchive/test/test-test_archive_string_conversion.o `test -f 'libarchive/test/test_archive_string_conversion.c' || echo '$(srcdir)/'`libarchive/test/test_archive_string_conversion.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_string_conversion.Tpo libarchive/test/$(DEPDIR)/test-test_archive_string_conversion.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_string_conversion.c' object='libarchive/test/test-test_archive_string_conversion.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_string_conversion.o `test -f 'libarchive/test/test_archive_string_conversion.c' || echo '$(srcdir)/'`libarchive/test/test_archive_string_conversion.c - -libarchive/test/test-test_archive_string_conversion.obj: libarchive/test/test_archive_string_conversion.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_string_conversion.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_string_conversion.Tpo -c -o libarchive/test/test-test_archive_string_conversion.obj `if test -f 'libarchive/test/test_archive_string_conversion.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_string_conversion.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_string_conversion.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_string_conversion.Tpo libarchive/test/$(DEPDIR)/test-test_archive_string_conversion.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_string_conversion.c' object='libarchive/test/test-test_archive_string_conversion.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_string_conversion.obj `if test -f 'libarchive/test/test_archive_string_conversion.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_string_conversion.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_string_conversion.c'; fi` - -libarchive/test/test-test_archive_write_add_filter_by_name.o: libarchive/test/test_archive_write_add_filter_by_name.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_write_add_filter_by_name.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_write_add_filter_by_name.Tpo -c -o libarchive/test/test-test_archive_write_add_filter_by_name.o `test -f 'libarchive/test/test_archive_write_add_filter_by_name.c' || echo '$(srcdir)/'`libarchive/test/test_archive_write_add_filter_by_name.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_write_add_filter_by_name.Tpo libarchive/test/$(DEPDIR)/test-test_archive_write_add_filter_by_name.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_write_add_filter_by_name.c' object='libarchive/test/test-test_archive_write_add_filter_by_name.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_write_add_filter_by_name.o `test -f 'libarchive/test/test_archive_write_add_filter_by_name.c' || echo '$(srcdir)/'`libarchive/test/test_archive_write_add_filter_by_name.c - -libarchive/test/test-test_archive_write_add_filter_by_name.obj: libarchive/test/test_archive_write_add_filter_by_name.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_write_add_filter_by_name.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_write_add_filter_by_name.Tpo -c -o libarchive/test/test-test_archive_write_add_filter_by_name.obj `if test -f 'libarchive/test/test_archive_write_add_filter_by_name.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_write_add_filter_by_name.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_write_add_filter_by_name.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_write_add_filter_by_name.Tpo libarchive/test/$(DEPDIR)/test-test_archive_write_add_filter_by_name.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_write_add_filter_by_name.c' object='libarchive/test/test-test_archive_write_add_filter_by_name.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_write_add_filter_by_name.obj `if test -f 'libarchive/test/test_archive_write_add_filter_by_name.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_write_add_filter_by_name.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_write_add_filter_by_name.c'; fi` - -libarchive/test/test-test_archive_write_set_filter_option.o: libarchive/test/test_archive_write_set_filter_option.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_write_set_filter_option.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_write_set_filter_option.Tpo -c -o libarchive/test/test-test_archive_write_set_filter_option.o `test -f 'libarchive/test/test_archive_write_set_filter_option.c' || echo '$(srcdir)/'`libarchive/test/test_archive_write_set_filter_option.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_write_set_filter_option.Tpo libarchive/test/$(DEPDIR)/test-test_archive_write_set_filter_option.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_write_set_filter_option.c' object='libarchive/test/test-test_archive_write_set_filter_option.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_write_set_filter_option.o `test -f 'libarchive/test/test_archive_write_set_filter_option.c' || echo '$(srcdir)/'`libarchive/test/test_archive_write_set_filter_option.c - -libarchive/test/test-test_archive_write_set_filter_option.obj: libarchive/test/test_archive_write_set_filter_option.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_write_set_filter_option.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_write_set_filter_option.Tpo -c -o libarchive/test/test-test_archive_write_set_filter_option.obj `if test -f 'libarchive/test/test_archive_write_set_filter_option.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_write_set_filter_option.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_write_set_filter_option.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_write_set_filter_option.Tpo libarchive/test/$(DEPDIR)/test-test_archive_write_set_filter_option.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_write_set_filter_option.c' object='libarchive/test/test-test_archive_write_set_filter_option.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_write_set_filter_option.obj `if test -f 'libarchive/test/test_archive_write_set_filter_option.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_write_set_filter_option.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_write_set_filter_option.c'; fi` - -libarchive/test/test-test_archive_write_set_format_by_name.o: libarchive/test/test_archive_write_set_format_by_name.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_write_set_format_by_name.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_by_name.Tpo -c -o libarchive/test/test-test_archive_write_set_format_by_name.o `test -f 'libarchive/test/test_archive_write_set_format_by_name.c' || echo '$(srcdir)/'`libarchive/test/test_archive_write_set_format_by_name.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_by_name.Tpo libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_by_name.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_write_set_format_by_name.c' object='libarchive/test/test-test_archive_write_set_format_by_name.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_write_set_format_by_name.o `test -f 'libarchive/test/test_archive_write_set_format_by_name.c' || echo '$(srcdir)/'`libarchive/test/test_archive_write_set_format_by_name.c - -libarchive/test/test-test_archive_write_set_format_by_name.obj: libarchive/test/test_archive_write_set_format_by_name.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_write_set_format_by_name.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_by_name.Tpo -c -o libarchive/test/test-test_archive_write_set_format_by_name.obj `if test -f 'libarchive/test/test_archive_write_set_format_by_name.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_write_set_format_by_name.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_write_set_format_by_name.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_by_name.Tpo libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_by_name.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_write_set_format_by_name.c' object='libarchive/test/test-test_archive_write_set_format_by_name.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_write_set_format_by_name.obj `if test -f 'libarchive/test/test_archive_write_set_format_by_name.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_write_set_format_by_name.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_write_set_format_by_name.c'; fi` - -libarchive/test/test-test_archive_write_set_format_filter_by_ext.o: libarchive/test/test_archive_write_set_format_filter_by_ext.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_write_set_format_filter_by_ext.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_filter_by_ext.Tpo -c -o libarchive/test/test-test_archive_write_set_format_filter_by_ext.o `test -f 'libarchive/test/test_archive_write_set_format_filter_by_ext.c' || echo '$(srcdir)/'`libarchive/test/test_archive_write_set_format_filter_by_ext.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_filter_by_ext.Tpo libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_filter_by_ext.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_write_set_format_filter_by_ext.c' object='libarchive/test/test-test_archive_write_set_format_filter_by_ext.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_write_set_format_filter_by_ext.o `test -f 'libarchive/test/test_archive_write_set_format_filter_by_ext.c' || echo '$(srcdir)/'`libarchive/test/test_archive_write_set_format_filter_by_ext.c - -libarchive/test/test-test_archive_write_set_format_filter_by_ext.obj: libarchive/test/test_archive_write_set_format_filter_by_ext.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_write_set_format_filter_by_ext.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_filter_by_ext.Tpo -c -o libarchive/test/test-test_archive_write_set_format_filter_by_ext.obj `if test -f 'libarchive/test/test_archive_write_set_format_filter_by_ext.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_write_set_format_filter_by_ext.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_write_set_format_filter_by_ext.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_filter_by_ext.Tpo libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_filter_by_ext.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_write_set_format_filter_by_ext.c' object='libarchive/test/test-test_archive_write_set_format_filter_by_ext.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_write_set_format_filter_by_ext.obj `if test -f 'libarchive/test/test_archive_write_set_format_filter_by_ext.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_write_set_format_filter_by_ext.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_write_set_format_filter_by_ext.c'; fi` - -libarchive/test/test-test_archive_write_set_format_option.o: libarchive/test/test_archive_write_set_format_option.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_write_set_format_option.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_option.Tpo -c -o libarchive/test/test-test_archive_write_set_format_option.o `test -f 'libarchive/test/test_archive_write_set_format_option.c' || echo '$(srcdir)/'`libarchive/test/test_archive_write_set_format_option.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_option.Tpo libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_option.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_write_set_format_option.c' object='libarchive/test/test-test_archive_write_set_format_option.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_write_set_format_option.o `test -f 'libarchive/test/test_archive_write_set_format_option.c' || echo '$(srcdir)/'`libarchive/test/test_archive_write_set_format_option.c - -libarchive/test/test-test_archive_write_set_format_option.obj: libarchive/test/test_archive_write_set_format_option.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_write_set_format_option.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_option.Tpo -c -o libarchive/test/test-test_archive_write_set_format_option.obj `if test -f 'libarchive/test/test_archive_write_set_format_option.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_write_set_format_option.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_write_set_format_option.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_option.Tpo libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_option.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_write_set_format_option.c' object='libarchive/test/test-test_archive_write_set_format_option.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_write_set_format_option.obj `if test -f 'libarchive/test/test_archive_write_set_format_option.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_write_set_format_option.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_write_set_format_option.c'; fi` - -libarchive/test/test-test_archive_write_set_option.o: libarchive/test/test_archive_write_set_option.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_write_set_option.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_write_set_option.Tpo -c -o libarchive/test/test-test_archive_write_set_option.o `test -f 'libarchive/test/test_archive_write_set_option.c' || echo '$(srcdir)/'`libarchive/test/test_archive_write_set_option.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_write_set_option.Tpo libarchive/test/$(DEPDIR)/test-test_archive_write_set_option.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_write_set_option.c' object='libarchive/test/test-test_archive_write_set_option.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_write_set_option.o `test -f 'libarchive/test/test_archive_write_set_option.c' || echo '$(srcdir)/'`libarchive/test/test_archive_write_set_option.c - -libarchive/test/test-test_archive_write_set_option.obj: libarchive/test/test_archive_write_set_option.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_write_set_option.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_write_set_option.Tpo -c -o libarchive/test/test-test_archive_write_set_option.obj `if test -f 'libarchive/test/test_archive_write_set_option.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_write_set_option.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_write_set_option.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_write_set_option.Tpo libarchive/test/$(DEPDIR)/test-test_archive_write_set_option.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_write_set_option.c' object='libarchive/test/test-test_archive_write_set_option.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_write_set_option.obj `if test -f 'libarchive/test/test_archive_write_set_option.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_write_set_option.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_write_set_option.c'; fi` - -libarchive/test/test-test_archive_write_set_options.o: libarchive/test/test_archive_write_set_options.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_write_set_options.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_write_set_options.Tpo -c -o libarchive/test/test-test_archive_write_set_options.o `test -f 'libarchive/test/test_archive_write_set_options.c' || echo '$(srcdir)/'`libarchive/test/test_archive_write_set_options.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_write_set_options.Tpo libarchive/test/$(DEPDIR)/test-test_archive_write_set_options.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_write_set_options.c' object='libarchive/test/test-test_archive_write_set_options.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_write_set_options.o `test -f 'libarchive/test/test_archive_write_set_options.c' || echo '$(srcdir)/'`libarchive/test/test_archive_write_set_options.c - -libarchive/test/test-test_archive_write_set_options.obj: libarchive/test/test_archive_write_set_options.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_write_set_options.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_write_set_options.Tpo -c -o libarchive/test/test-test_archive_write_set_options.obj `if test -f 'libarchive/test/test_archive_write_set_options.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_write_set_options.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_write_set_options.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_write_set_options.Tpo libarchive/test/$(DEPDIR)/test-test_archive_write_set_options.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_write_set_options.c' object='libarchive/test/test-test_archive_write_set_options.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_write_set_options.obj `if test -f 'libarchive/test/test_archive_write_set_options.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_write_set_options.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_write_set_options.c'; fi` - -libarchive/test/test-test_archive_write_set_passphrase.o: libarchive/test/test_archive_write_set_passphrase.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_write_set_passphrase.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_write_set_passphrase.Tpo -c -o libarchive/test/test-test_archive_write_set_passphrase.o `test -f 'libarchive/test/test_archive_write_set_passphrase.c' || echo '$(srcdir)/'`libarchive/test/test_archive_write_set_passphrase.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_write_set_passphrase.Tpo libarchive/test/$(DEPDIR)/test-test_archive_write_set_passphrase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_write_set_passphrase.c' object='libarchive/test/test-test_archive_write_set_passphrase.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_write_set_passphrase.o `test -f 'libarchive/test/test_archive_write_set_passphrase.c' || echo '$(srcdir)/'`libarchive/test/test_archive_write_set_passphrase.c - -libarchive/test/test-test_archive_write_set_passphrase.obj: libarchive/test/test_archive_write_set_passphrase.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_archive_write_set_passphrase.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_archive_write_set_passphrase.Tpo -c -o libarchive/test/test-test_archive_write_set_passphrase.obj `if test -f 'libarchive/test/test_archive_write_set_passphrase.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_write_set_passphrase.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_write_set_passphrase.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_archive_write_set_passphrase.Tpo libarchive/test/$(DEPDIR)/test-test_archive_write_set_passphrase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_archive_write_set_passphrase.c' object='libarchive/test/test-test_archive_write_set_passphrase.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_archive_write_set_passphrase.obj `if test -f 'libarchive/test/test_archive_write_set_passphrase.c'; then $(CYGPATH_W) 'libarchive/test/test_archive_write_set_passphrase.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_archive_write_set_passphrase.c'; fi` - -libarchive/test/test-test_bad_fd.o: libarchive/test/test_bad_fd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_bad_fd.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_bad_fd.Tpo -c -o libarchive/test/test-test_bad_fd.o `test -f 'libarchive/test/test_bad_fd.c' || echo '$(srcdir)/'`libarchive/test/test_bad_fd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_bad_fd.Tpo libarchive/test/$(DEPDIR)/test-test_bad_fd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_bad_fd.c' object='libarchive/test/test-test_bad_fd.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_bad_fd.o `test -f 'libarchive/test/test_bad_fd.c' || echo '$(srcdir)/'`libarchive/test/test_bad_fd.c - -libarchive/test/test-test_bad_fd.obj: libarchive/test/test_bad_fd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_bad_fd.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_bad_fd.Tpo -c -o libarchive/test/test-test_bad_fd.obj `if test -f 'libarchive/test/test_bad_fd.c'; then $(CYGPATH_W) 'libarchive/test/test_bad_fd.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_bad_fd.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_bad_fd.Tpo libarchive/test/$(DEPDIR)/test-test_bad_fd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_bad_fd.c' object='libarchive/test/test-test_bad_fd.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_bad_fd.obj `if test -f 'libarchive/test/test_bad_fd.c'; then $(CYGPATH_W) 'libarchive/test/test_bad_fd.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_bad_fd.c'; fi` - -libarchive/test/test-test_compat_bzip2.o: libarchive/test/test_compat_bzip2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_bzip2.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_bzip2.Tpo -c -o libarchive/test/test-test_compat_bzip2.o `test -f 'libarchive/test/test_compat_bzip2.c' || echo '$(srcdir)/'`libarchive/test/test_compat_bzip2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_bzip2.Tpo libarchive/test/$(DEPDIR)/test-test_compat_bzip2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_bzip2.c' object='libarchive/test/test-test_compat_bzip2.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_bzip2.o `test -f 'libarchive/test/test_compat_bzip2.c' || echo '$(srcdir)/'`libarchive/test/test_compat_bzip2.c - -libarchive/test/test-test_compat_bzip2.obj: libarchive/test/test_compat_bzip2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_bzip2.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_bzip2.Tpo -c -o libarchive/test/test-test_compat_bzip2.obj `if test -f 'libarchive/test/test_compat_bzip2.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_bzip2.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_bzip2.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_bzip2.Tpo libarchive/test/$(DEPDIR)/test-test_compat_bzip2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_bzip2.c' object='libarchive/test/test-test_compat_bzip2.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_bzip2.obj `if test -f 'libarchive/test/test_compat_bzip2.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_bzip2.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_bzip2.c'; fi` - -libarchive/test/test-test_compat_cpio.o: libarchive/test/test_compat_cpio.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_cpio.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_cpio.Tpo -c -o libarchive/test/test-test_compat_cpio.o `test -f 'libarchive/test/test_compat_cpio.c' || echo '$(srcdir)/'`libarchive/test/test_compat_cpio.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_cpio.Tpo libarchive/test/$(DEPDIR)/test-test_compat_cpio.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_cpio.c' object='libarchive/test/test-test_compat_cpio.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_cpio.o `test -f 'libarchive/test/test_compat_cpio.c' || echo '$(srcdir)/'`libarchive/test/test_compat_cpio.c - -libarchive/test/test-test_compat_cpio.obj: libarchive/test/test_compat_cpio.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_cpio.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_cpio.Tpo -c -o libarchive/test/test-test_compat_cpio.obj `if test -f 'libarchive/test/test_compat_cpio.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_cpio.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_cpio.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_cpio.Tpo libarchive/test/$(DEPDIR)/test-test_compat_cpio.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_cpio.c' object='libarchive/test/test-test_compat_cpio.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_cpio.obj `if test -f 'libarchive/test/test_compat_cpio.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_cpio.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_cpio.c'; fi` - -libarchive/test/test-test_compat_gtar.o: libarchive/test/test_compat_gtar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_gtar.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_gtar.Tpo -c -o libarchive/test/test-test_compat_gtar.o `test -f 'libarchive/test/test_compat_gtar.c' || echo '$(srcdir)/'`libarchive/test/test_compat_gtar.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_gtar.Tpo libarchive/test/$(DEPDIR)/test-test_compat_gtar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_gtar.c' object='libarchive/test/test-test_compat_gtar.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_gtar.o `test -f 'libarchive/test/test_compat_gtar.c' || echo '$(srcdir)/'`libarchive/test/test_compat_gtar.c - -libarchive/test/test-test_compat_gtar.obj: libarchive/test/test_compat_gtar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_gtar.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_gtar.Tpo -c -o libarchive/test/test-test_compat_gtar.obj `if test -f 'libarchive/test/test_compat_gtar.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_gtar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_gtar.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_gtar.Tpo libarchive/test/$(DEPDIR)/test-test_compat_gtar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_gtar.c' object='libarchive/test/test-test_compat_gtar.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_gtar.obj `if test -f 'libarchive/test/test_compat_gtar.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_gtar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_gtar.c'; fi` - -libarchive/test/test-test_compat_gzip.o: libarchive/test/test_compat_gzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_gzip.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_gzip.Tpo -c -o libarchive/test/test-test_compat_gzip.o `test -f 'libarchive/test/test_compat_gzip.c' || echo '$(srcdir)/'`libarchive/test/test_compat_gzip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_gzip.Tpo libarchive/test/$(DEPDIR)/test-test_compat_gzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_gzip.c' object='libarchive/test/test-test_compat_gzip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_gzip.o `test -f 'libarchive/test/test_compat_gzip.c' || echo '$(srcdir)/'`libarchive/test/test_compat_gzip.c - -libarchive/test/test-test_compat_gzip.obj: libarchive/test/test_compat_gzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_gzip.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_gzip.Tpo -c -o libarchive/test/test-test_compat_gzip.obj `if test -f 'libarchive/test/test_compat_gzip.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_gzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_gzip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_gzip.Tpo libarchive/test/$(DEPDIR)/test-test_compat_gzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_gzip.c' object='libarchive/test/test-test_compat_gzip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_gzip.obj `if test -f 'libarchive/test/test_compat_gzip.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_gzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_gzip.c'; fi` - -libarchive/test/test-test_compat_lz4.o: libarchive/test/test_compat_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_lz4.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_lz4.Tpo -c -o libarchive/test/test-test_compat_lz4.o `test -f 'libarchive/test/test_compat_lz4.c' || echo '$(srcdir)/'`libarchive/test/test_compat_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_lz4.Tpo libarchive/test/$(DEPDIR)/test-test_compat_lz4.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_lz4.c' object='libarchive/test/test-test_compat_lz4.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_lz4.o `test -f 'libarchive/test/test_compat_lz4.c' || echo '$(srcdir)/'`libarchive/test/test_compat_lz4.c - -libarchive/test/test-test_compat_lz4.obj: libarchive/test/test_compat_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_lz4.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_lz4.Tpo -c -o libarchive/test/test-test_compat_lz4.obj `if test -f 'libarchive/test/test_compat_lz4.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_lz4.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_lz4.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_lz4.Tpo libarchive/test/$(DEPDIR)/test-test_compat_lz4.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_lz4.c' object='libarchive/test/test-test_compat_lz4.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_lz4.obj `if test -f 'libarchive/test/test_compat_lz4.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_lz4.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_lz4.c'; fi` - -libarchive/test/test-test_compat_lzip.o: libarchive/test/test_compat_lzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_lzip.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_lzip.Tpo -c -o libarchive/test/test-test_compat_lzip.o `test -f 'libarchive/test/test_compat_lzip.c' || echo '$(srcdir)/'`libarchive/test/test_compat_lzip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_lzip.Tpo libarchive/test/$(DEPDIR)/test-test_compat_lzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_lzip.c' object='libarchive/test/test-test_compat_lzip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_lzip.o `test -f 'libarchive/test/test_compat_lzip.c' || echo '$(srcdir)/'`libarchive/test/test_compat_lzip.c - -libarchive/test/test-test_compat_lzip.obj: libarchive/test/test_compat_lzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_lzip.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_lzip.Tpo -c -o libarchive/test/test-test_compat_lzip.obj `if test -f 'libarchive/test/test_compat_lzip.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_lzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_lzip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_lzip.Tpo libarchive/test/$(DEPDIR)/test-test_compat_lzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_lzip.c' object='libarchive/test/test-test_compat_lzip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_lzip.obj `if test -f 'libarchive/test/test_compat_lzip.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_lzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_lzip.c'; fi` - -libarchive/test/test-test_compat_lzma.o: libarchive/test/test_compat_lzma.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_lzma.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_lzma.Tpo -c -o libarchive/test/test-test_compat_lzma.o `test -f 'libarchive/test/test_compat_lzma.c' || echo '$(srcdir)/'`libarchive/test/test_compat_lzma.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_lzma.Tpo libarchive/test/$(DEPDIR)/test-test_compat_lzma.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_lzma.c' object='libarchive/test/test-test_compat_lzma.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_lzma.o `test -f 'libarchive/test/test_compat_lzma.c' || echo '$(srcdir)/'`libarchive/test/test_compat_lzma.c - -libarchive/test/test-test_compat_lzma.obj: libarchive/test/test_compat_lzma.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_lzma.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_lzma.Tpo -c -o libarchive/test/test-test_compat_lzma.obj `if test -f 'libarchive/test/test_compat_lzma.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_lzma.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_lzma.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_lzma.Tpo libarchive/test/$(DEPDIR)/test-test_compat_lzma.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_lzma.c' object='libarchive/test/test-test_compat_lzma.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_lzma.obj `if test -f 'libarchive/test/test_compat_lzma.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_lzma.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_lzma.c'; fi` - -libarchive/test/test-test_compat_lzop.o: libarchive/test/test_compat_lzop.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_lzop.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_lzop.Tpo -c -o libarchive/test/test-test_compat_lzop.o `test -f 'libarchive/test/test_compat_lzop.c' || echo '$(srcdir)/'`libarchive/test/test_compat_lzop.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_lzop.Tpo libarchive/test/$(DEPDIR)/test-test_compat_lzop.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_lzop.c' object='libarchive/test/test-test_compat_lzop.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_lzop.o `test -f 'libarchive/test/test_compat_lzop.c' || echo '$(srcdir)/'`libarchive/test/test_compat_lzop.c - -libarchive/test/test-test_compat_lzop.obj: libarchive/test/test_compat_lzop.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_lzop.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_lzop.Tpo -c -o libarchive/test/test-test_compat_lzop.obj `if test -f 'libarchive/test/test_compat_lzop.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_lzop.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_lzop.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_lzop.Tpo libarchive/test/$(DEPDIR)/test-test_compat_lzop.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_lzop.c' object='libarchive/test/test-test_compat_lzop.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_lzop.obj `if test -f 'libarchive/test/test_compat_lzop.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_lzop.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_lzop.c'; fi` - -libarchive/test/test-test_compat_mac.o: libarchive/test/test_compat_mac.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_mac.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_mac.Tpo -c -o libarchive/test/test-test_compat_mac.o `test -f 'libarchive/test/test_compat_mac.c' || echo '$(srcdir)/'`libarchive/test/test_compat_mac.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_mac.Tpo libarchive/test/$(DEPDIR)/test-test_compat_mac.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_mac.c' object='libarchive/test/test-test_compat_mac.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_mac.o `test -f 'libarchive/test/test_compat_mac.c' || echo '$(srcdir)/'`libarchive/test/test_compat_mac.c - -libarchive/test/test-test_compat_mac.obj: libarchive/test/test_compat_mac.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_mac.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_mac.Tpo -c -o libarchive/test/test-test_compat_mac.obj `if test -f 'libarchive/test/test_compat_mac.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_mac.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_mac.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_mac.Tpo libarchive/test/$(DEPDIR)/test-test_compat_mac.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_mac.c' object='libarchive/test/test-test_compat_mac.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_mac.obj `if test -f 'libarchive/test/test_compat_mac.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_mac.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_mac.c'; fi` - -libarchive/test/test-test_compat_perl_archive_tar.o: libarchive/test/test_compat_perl_archive_tar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_perl_archive_tar.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_perl_archive_tar.Tpo -c -o libarchive/test/test-test_compat_perl_archive_tar.o `test -f 'libarchive/test/test_compat_perl_archive_tar.c' || echo '$(srcdir)/'`libarchive/test/test_compat_perl_archive_tar.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_perl_archive_tar.Tpo libarchive/test/$(DEPDIR)/test-test_compat_perl_archive_tar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_perl_archive_tar.c' object='libarchive/test/test-test_compat_perl_archive_tar.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_perl_archive_tar.o `test -f 'libarchive/test/test_compat_perl_archive_tar.c' || echo '$(srcdir)/'`libarchive/test/test_compat_perl_archive_tar.c - -libarchive/test/test-test_compat_perl_archive_tar.obj: libarchive/test/test_compat_perl_archive_tar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_perl_archive_tar.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_perl_archive_tar.Tpo -c -o libarchive/test/test-test_compat_perl_archive_tar.obj `if test -f 'libarchive/test/test_compat_perl_archive_tar.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_perl_archive_tar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_perl_archive_tar.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_perl_archive_tar.Tpo libarchive/test/$(DEPDIR)/test-test_compat_perl_archive_tar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_perl_archive_tar.c' object='libarchive/test/test-test_compat_perl_archive_tar.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_perl_archive_tar.obj `if test -f 'libarchive/test/test_compat_perl_archive_tar.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_perl_archive_tar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_perl_archive_tar.c'; fi` - -libarchive/test/test-test_compat_plexus_archiver_tar.o: libarchive/test/test_compat_plexus_archiver_tar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_plexus_archiver_tar.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_plexus_archiver_tar.Tpo -c -o libarchive/test/test-test_compat_plexus_archiver_tar.o `test -f 'libarchive/test/test_compat_plexus_archiver_tar.c' || echo '$(srcdir)/'`libarchive/test/test_compat_plexus_archiver_tar.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_plexus_archiver_tar.Tpo libarchive/test/$(DEPDIR)/test-test_compat_plexus_archiver_tar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_plexus_archiver_tar.c' object='libarchive/test/test-test_compat_plexus_archiver_tar.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_plexus_archiver_tar.o `test -f 'libarchive/test/test_compat_plexus_archiver_tar.c' || echo '$(srcdir)/'`libarchive/test/test_compat_plexus_archiver_tar.c - -libarchive/test/test-test_compat_plexus_archiver_tar.obj: libarchive/test/test_compat_plexus_archiver_tar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_plexus_archiver_tar.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_plexus_archiver_tar.Tpo -c -o libarchive/test/test-test_compat_plexus_archiver_tar.obj `if test -f 'libarchive/test/test_compat_plexus_archiver_tar.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_plexus_archiver_tar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_plexus_archiver_tar.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_plexus_archiver_tar.Tpo libarchive/test/$(DEPDIR)/test-test_compat_plexus_archiver_tar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_plexus_archiver_tar.c' object='libarchive/test/test-test_compat_plexus_archiver_tar.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_plexus_archiver_tar.obj `if test -f 'libarchive/test/test_compat_plexus_archiver_tar.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_plexus_archiver_tar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_plexus_archiver_tar.c'; fi` - -libarchive/test/test-test_compat_solaris_tar_acl.o: libarchive/test/test_compat_solaris_tar_acl.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_solaris_tar_acl.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_solaris_tar_acl.Tpo -c -o libarchive/test/test-test_compat_solaris_tar_acl.o `test -f 'libarchive/test/test_compat_solaris_tar_acl.c' || echo '$(srcdir)/'`libarchive/test/test_compat_solaris_tar_acl.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_solaris_tar_acl.Tpo libarchive/test/$(DEPDIR)/test-test_compat_solaris_tar_acl.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_solaris_tar_acl.c' object='libarchive/test/test-test_compat_solaris_tar_acl.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_solaris_tar_acl.o `test -f 'libarchive/test/test_compat_solaris_tar_acl.c' || echo '$(srcdir)/'`libarchive/test/test_compat_solaris_tar_acl.c - -libarchive/test/test-test_compat_solaris_tar_acl.obj: libarchive/test/test_compat_solaris_tar_acl.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_solaris_tar_acl.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_solaris_tar_acl.Tpo -c -o libarchive/test/test-test_compat_solaris_tar_acl.obj `if test -f 'libarchive/test/test_compat_solaris_tar_acl.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_solaris_tar_acl.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_solaris_tar_acl.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_solaris_tar_acl.Tpo libarchive/test/$(DEPDIR)/test-test_compat_solaris_tar_acl.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_solaris_tar_acl.c' object='libarchive/test/test-test_compat_solaris_tar_acl.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_solaris_tar_acl.obj `if test -f 'libarchive/test/test_compat_solaris_tar_acl.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_solaris_tar_acl.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_solaris_tar_acl.c'; fi` - -libarchive/test/test-test_compat_solaris_pax_sparse.o: libarchive/test/test_compat_solaris_pax_sparse.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_solaris_pax_sparse.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_solaris_pax_sparse.Tpo -c -o libarchive/test/test-test_compat_solaris_pax_sparse.o `test -f 'libarchive/test/test_compat_solaris_pax_sparse.c' || echo '$(srcdir)/'`libarchive/test/test_compat_solaris_pax_sparse.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_solaris_pax_sparse.Tpo libarchive/test/$(DEPDIR)/test-test_compat_solaris_pax_sparse.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_solaris_pax_sparse.c' object='libarchive/test/test-test_compat_solaris_pax_sparse.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_solaris_pax_sparse.o `test -f 'libarchive/test/test_compat_solaris_pax_sparse.c' || echo '$(srcdir)/'`libarchive/test/test_compat_solaris_pax_sparse.c - -libarchive/test/test-test_compat_solaris_pax_sparse.obj: libarchive/test/test_compat_solaris_pax_sparse.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_solaris_pax_sparse.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_solaris_pax_sparse.Tpo -c -o libarchive/test/test-test_compat_solaris_pax_sparse.obj `if test -f 'libarchive/test/test_compat_solaris_pax_sparse.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_solaris_pax_sparse.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_solaris_pax_sparse.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_solaris_pax_sparse.Tpo libarchive/test/$(DEPDIR)/test-test_compat_solaris_pax_sparse.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_solaris_pax_sparse.c' object='libarchive/test/test-test_compat_solaris_pax_sparse.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_solaris_pax_sparse.obj `if test -f 'libarchive/test/test_compat_solaris_pax_sparse.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_solaris_pax_sparse.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_solaris_pax_sparse.c'; fi` - -libarchive/test/test-test_compat_star_acl.o: libarchive/test/test_compat_star_acl.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_star_acl.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_star_acl.Tpo -c -o libarchive/test/test-test_compat_star_acl.o `test -f 'libarchive/test/test_compat_star_acl.c' || echo '$(srcdir)/'`libarchive/test/test_compat_star_acl.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_star_acl.Tpo libarchive/test/$(DEPDIR)/test-test_compat_star_acl.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_star_acl.c' object='libarchive/test/test-test_compat_star_acl.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_star_acl.o `test -f 'libarchive/test/test_compat_star_acl.c' || echo '$(srcdir)/'`libarchive/test/test_compat_star_acl.c - -libarchive/test/test-test_compat_star_acl.obj: libarchive/test/test_compat_star_acl.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_star_acl.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_star_acl.Tpo -c -o libarchive/test/test-test_compat_star_acl.obj `if test -f 'libarchive/test/test_compat_star_acl.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_star_acl.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_star_acl.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_star_acl.Tpo libarchive/test/$(DEPDIR)/test-test_compat_star_acl.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_star_acl.c' object='libarchive/test/test-test_compat_star_acl.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_star_acl.obj `if test -f 'libarchive/test/test_compat_star_acl.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_star_acl.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_star_acl.c'; fi` - -libarchive/test/test-test_compat_tar_directory.o: libarchive/test/test_compat_tar_directory.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_tar_directory.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_tar_directory.Tpo -c -o libarchive/test/test-test_compat_tar_directory.o `test -f 'libarchive/test/test_compat_tar_directory.c' || echo '$(srcdir)/'`libarchive/test/test_compat_tar_directory.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_tar_directory.Tpo libarchive/test/$(DEPDIR)/test-test_compat_tar_directory.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_tar_directory.c' object='libarchive/test/test-test_compat_tar_directory.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_tar_directory.o `test -f 'libarchive/test/test_compat_tar_directory.c' || echo '$(srcdir)/'`libarchive/test/test_compat_tar_directory.c - -libarchive/test/test-test_compat_tar_directory.obj: libarchive/test/test_compat_tar_directory.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_tar_directory.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_tar_directory.Tpo -c -o libarchive/test/test-test_compat_tar_directory.obj `if test -f 'libarchive/test/test_compat_tar_directory.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_tar_directory.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_tar_directory.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_tar_directory.Tpo libarchive/test/$(DEPDIR)/test-test_compat_tar_directory.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_tar_directory.c' object='libarchive/test/test-test_compat_tar_directory.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_tar_directory.obj `if test -f 'libarchive/test/test_compat_tar_directory.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_tar_directory.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_tar_directory.c'; fi` - -libarchive/test/test-test_compat_tar_hardlink.o: libarchive/test/test_compat_tar_hardlink.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_tar_hardlink.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_tar_hardlink.Tpo -c -o libarchive/test/test-test_compat_tar_hardlink.o `test -f 'libarchive/test/test_compat_tar_hardlink.c' || echo '$(srcdir)/'`libarchive/test/test_compat_tar_hardlink.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_tar_hardlink.Tpo libarchive/test/$(DEPDIR)/test-test_compat_tar_hardlink.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_tar_hardlink.c' object='libarchive/test/test-test_compat_tar_hardlink.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_tar_hardlink.o `test -f 'libarchive/test/test_compat_tar_hardlink.c' || echo '$(srcdir)/'`libarchive/test/test_compat_tar_hardlink.c - -libarchive/test/test-test_compat_tar_hardlink.obj: libarchive/test/test_compat_tar_hardlink.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_tar_hardlink.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_tar_hardlink.Tpo -c -o libarchive/test/test-test_compat_tar_hardlink.obj `if test -f 'libarchive/test/test_compat_tar_hardlink.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_tar_hardlink.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_tar_hardlink.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_tar_hardlink.Tpo libarchive/test/$(DEPDIR)/test-test_compat_tar_hardlink.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_tar_hardlink.c' object='libarchive/test/test-test_compat_tar_hardlink.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_tar_hardlink.obj `if test -f 'libarchive/test/test_compat_tar_hardlink.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_tar_hardlink.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_tar_hardlink.c'; fi` - -libarchive/test/test-test_compat_uudecode.o: libarchive/test/test_compat_uudecode.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_uudecode.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_uudecode.Tpo -c -o libarchive/test/test-test_compat_uudecode.o `test -f 'libarchive/test/test_compat_uudecode.c' || echo '$(srcdir)/'`libarchive/test/test_compat_uudecode.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_uudecode.Tpo libarchive/test/$(DEPDIR)/test-test_compat_uudecode.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_uudecode.c' object='libarchive/test/test-test_compat_uudecode.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_uudecode.o `test -f 'libarchive/test/test_compat_uudecode.c' || echo '$(srcdir)/'`libarchive/test/test_compat_uudecode.c - -libarchive/test/test-test_compat_uudecode.obj: libarchive/test/test_compat_uudecode.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_uudecode.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_uudecode.Tpo -c -o libarchive/test/test-test_compat_uudecode.obj `if test -f 'libarchive/test/test_compat_uudecode.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_uudecode.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_uudecode.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_uudecode.Tpo libarchive/test/$(DEPDIR)/test-test_compat_uudecode.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_uudecode.c' object='libarchive/test/test-test_compat_uudecode.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_uudecode.obj `if test -f 'libarchive/test/test_compat_uudecode.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_uudecode.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_uudecode.c'; fi` - -libarchive/test/test-test_compat_uudecode_large.o: libarchive/test/test_compat_uudecode_large.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_uudecode_large.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_uudecode_large.Tpo -c -o libarchive/test/test-test_compat_uudecode_large.o `test -f 'libarchive/test/test_compat_uudecode_large.c' || echo '$(srcdir)/'`libarchive/test/test_compat_uudecode_large.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_uudecode_large.Tpo libarchive/test/$(DEPDIR)/test-test_compat_uudecode_large.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_uudecode_large.c' object='libarchive/test/test-test_compat_uudecode_large.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_uudecode_large.o `test -f 'libarchive/test/test_compat_uudecode_large.c' || echo '$(srcdir)/'`libarchive/test/test_compat_uudecode_large.c - -libarchive/test/test-test_compat_uudecode_large.obj: libarchive/test/test_compat_uudecode_large.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_uudecode_large.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_uudecode_large.Tpo -c -o libarchive/test/test-test_compat_uudecode_large.obj `if test -f 'libarchive/test/test_compat_uudecode_large.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_uudecode_large.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_uudecode_large.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_uudecode_large.Tpo libarchive/test/$(DEPDIR)/test-test_compat_uudecode_large.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_uudecode_large.c' object='libarchive/test/test-test_compat_uudecode_large.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_uudecode_large.obj `if test -f 'libarchive/test/test_compat_uudecode_large.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_uudecode_large.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_uudecode_large.c'; fi` - -libarchive/test/test-test_compat_xz.o: libarchive/test/test_compat_xz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_xz.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_xz.Tpo -c -o libarchive/test/test-test_compat_xz.o `test -f 'libarchive/test/test_compat_xz.c' || echo '$(srcdir)/'`libarchive/test/test_compat_xz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_xz.Tpo libarchive/test/$(DEPDIR)/test-test_compat_xz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_xz.c' object='libarchive/test/test-test_compat_xz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_xz.o `test -f 'libarchive/test/test_compat_xz.c' || echo '$(srcdir)/'`libarchive/test/test_compat_xz.c - -libarchive/test/test-test_compat_xz.obj: libarchive/test/test_compat_xz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_xz.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_xz.Tpo -c -o libarchive/test/test-test_compat_xz.obj `if test -f 'libarchive/test/test_compat_xz.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_xz.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_xz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_xz.Tpo libarchive/test/$(DEPDIR)/test-test_compat_xz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_xz.c' object='libarchive/test/test-test_compat_xz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_xz.obj `if test -f 'libarchive/test/test_compat_xz.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_xz.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_xz.c'; fi` - -libarchive/test/test-test_compat_zip.o: libarchive/test/test_compat_zip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_zip.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_zip.Tpo -c -o libarchive/test/test-test_compat_zip.o `test -f 'libarchive/test/test_compat_zip.c' || echo '$(srcdir)/'`libarchive/test/test_compat_zip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_zip.Tpo libarchive/test/$(DEPDIR)/test-test_compat_zip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_zip.c' object='libarchive/test/test-test_compat_zip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_zip.o `test -f 'libarchive/test/test_compat_zip.c' || echo '$(srcdir)/'`libarchive/test/test_compat_zip.c - -libarchive/test/test-test_compat_zip.obj: libarchive/test/test_compat_zip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_zip.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_zip.Tpo -c -o libarchive/test/test-test_compat_zip.obj `if test -f 'libarchive/test/test_compat_zip.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_zip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_zip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_zip.Tpo libarchive/test/$(DEPDIR)/test-test_compat_zip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_zip.c' object='libarchive/test/test-test_compat_zip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_zip.obj `if test -f 'libarchive/test/test_compat_zip.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_zip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_zip.c'; fi` - -libarchive/test/test-test_compat_zstd.o: libarchive/test/test_compat_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_zstd.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_zstd.Tpo -c -o libarchive/test/test-test_compat_zstd.o `test -f 'libarchive/test/test_compat_zstd.c' || echo '$(srcdir)/'`libarchive/test/test_compat_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_zstd.Tpo libarchive/test/$(DEPDIR)/test-test_compat_zstd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_zstd.c' object='libarchive/test/test-test_compat_zstd.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_zstd.o `test -f 'libarchive/test/test_compat_zstd.c' || echo '$(srcdir)/'`libarchive/test/test_compat_zstd.c - -libarchive/test/test-test_compat_zstd.obj: libarchive/test/test_compat_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_compat_zstd.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_compat_zstd.Tpo -c -o libarchive/test/test-test_compat_zstd.obj `if test -f 'libarchive/test/test_compat_zstd.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_zstd.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_zstd.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_compat_zstd.Tpo libarchive/test/$(DEPDIR)/test-test_compat_zstd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_compat_zstd.c' object='libarchive/test/test-test_compat_zstd.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_compat_zstd.obj `if test -f 'libarchive/test/test_compat_zstd.c'; then $(CYGPATH_W) 'libarchive/test/test_compat_zstd.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_compat_zstd.c'; fi` - -libarchive/test/test-test_empty_write.o: libarchive/test/test_empty_write.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_empty_write.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_empty_write.Tpo -c -o libarchive/test/test-test_empty_write.o `test -f 'libarchive/test/test_empty_write.c' || echo '$(srcdir)/'`libarchive/test/test_empty_write.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_empty_write.Tpo libarchive/test/$(DEPDIR)/test-test_empty_write.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_empty_write.c' object='libarchive/test/test-test_empty_write.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_empty_write.o `test -f 'libarchive/test/test_empty_write.c' || echo '$(srcdir)/'`libarchive/test/test_empty_write.c - -libarchive/test/test-test_empty_write.obj: libarchive/test/test_empty_write.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_empty_write.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_empty_write.Tpo -c -o libarchive/test/test-test_empty_write.obj `if test -f 'libarchive/test/test_empty_write.c'; then $(CYGPATH_W) 'libarchive/test/test_empty_write.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_empty_write.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_empty_write.Tpo libarchive/test/$(DEPDIR)/test-test_empty_write.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_empty_write.c' object='libarchive/test/test-test_empty_write.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_empty_write.obj `if test -f 'libarchive/test/test_empty_write.c'; then $(CYGPATH_W) 'libarchive/test/test_empty_write.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_empty_write.c'; fi` - -libarchive/test/test-test_entry.o: libarchive/test/test_entry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_entry.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_entry.Tpo -c -o libarchive/test/test-test_entry.o `test -f 'libarchive/test/test_entry.c' || echo '$(srcdir)/'`libarchive/test/test_entry.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_entry.Tpo libarchive/test/$(DEPDIR)/test-test_entry.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_entry.c' object='libarchive/test/test-test_entry.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_entry.o `test -f 'libarchive/test/test_entry.c' || echo '$(srcdir)/'`libarchive/test/test_entry.c - -libarchive/test/test-test_entry.obj: libarchive/test/test_entry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_entry.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_entry.Tpo -c -o libarchive/test/test-test_entry.obj `if test -f 'libarchive/test/test_entry.c'; then $(CYGPATH_W) 'libarchive/test/test_entry.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_entry.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_entry.Tpo libarchive/test/$(DEPDIR)/test-test_entry.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_entry.c' object='libarchive/test/test-test_entry.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_entry.obj `if test -f 'libarchive/test/test_entry.c'; then $(CYGPATH_W) 'libarchive/test/test_entry.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_entry.c'; fi` - -libarchive/test/test-test_entry_strmode.o: libarchive/test/test_entry_strmode.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_entry_strmode.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_entry_strmode.Tpo -c -o libarchive/test/test-test_entry_strmode.o `test -f 'libarchive/test/test_entry_strmode.c' || echo '$(srcdir)/'`libarchive/test/test_entry_strmode.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_entry_strmode.Tpo libarchive/test/$(DEPDIR)/test-test_entry_strmode.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_entry_strmode.c' object='libarchive/test/test-test_entry_strmode.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_entry_strmode.o `test -f 'libarchive/test/test_entry_strmode.c' || echo '$(srcdir)/'`libarchive/test/test_entry_strmode.c - -libarchive/test/test-test_entry_strmode.obj: libarchive/test/test_entry_strmode.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_entry_strmode.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_entry_strmode.Tpo -c -o libarchive/test/test-test_entry_strmode.obj `if test -f 'libarchive/test/test_entry_strmode.c'; then $(CYGPATH_W) 'libarchive/test/test_entry_strmode.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_entry_strmode.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_entry_strmode.Tpo libarchive/test/$(DEPDIR)/test-test_entry_strmode.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_entry_strmode.c' object='libarchive/test/test-test_entry_strmode.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_entry_strmode.obj `if test -f 'libarchive/test/test_entry_strmode.c'; then $(CYGPATH_W) 'libarchive/test/test_entry_strmode.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_entry_strmode.c'; fi` - -libarchive/test/test-test_extattr_freebsd.o: libarchive/test/test_extattr_freebsd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_extattr_freebsd.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_extattr_freebsd.Tpo -c -o libarchive/test/test-test_extattr_freebsd.o `test -f 'libarchive/test/test_extattr_freebsd.c' || echo '$(srcdir)/'`libarchive/test/test_extattr_freebsd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_extattr_freebsd.Tpo libarchive/test/$(DEPDIR)/test-test_extattr_freebsd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_extattr_freebsd.c' object='libarchive/test/test-test_extattr_freebsd.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_extattr_freebsd.o `test -f 'libarchive/test/test_extattr_freebsd.c' || echo '$(srcdir)/'`libarchive/test/test_extattr_freebsd.c - -libarchive/test/test-test_extattr_freebsd.obj: libarchive/test/test_extattr_freebsd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_extattr_freebsd.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_extattr_freebsd.Tpo -c -o libarchive/test/test-test_extattr_freebsd.obj `if test -f 'libarchive/test/test_extattr_freebsd.c'; then $(CYGPATH_W) 'libarchive/test/test_extattr_freebsd.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_extattr_freebsd.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_extattr_freebsd.Tpo libarchive/test/$(DEPDIR)/test-test_extattr_freebsd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_extattr_freebsd.c' object='libarchive/test/test-test_extattr_freebsd.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_extattr_freebsd.obj `if test -f 'libarchive/test/test_extattr_freebsd.c'; then $(CYGPATH_W) 'libarchive/test/test_extattr_freebsd.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_extattr_freebsd.c'; fi` - -libarchive/test/test-test_filter_count.o: libarchive/test/test_filter_count.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_filter_count.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_filter_count.Tpo -c -o libarchive/test/test-test_filter_count.o `test -f 'libarchive/test/test_filter_count.c' || echo '$(srcdir)/'`libarchive/test/test_filter_count.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_filter_count.Tpo libarchive/test/$(DEPDIR)/test-test_filter_count.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_filter_count.c' object='libarchive/test/test-test_filter_count.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_filter_count.o `test -f 'libarchive/test/test_filter_count.c' || echo '$(srcdir)/'`libarchive/test/test_filter_count.c - -libarchive/test/test-test_filter_count.obj: libarchive/test/test_filter_count.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_filter_count.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_filter_count.Tpo -c -o libarchive/test/test-test_filter_count.obj `if test -f 'libarchive/test/test_filter_count.c'; then $(CYGPATH_W) 'libarchive/test/test_filter_count.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_filter_count.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_filter_count.Tpo libarchive/test/$(DEPDIR)/test-test_filter_count.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_filter_count.c' object='libarchive/test/test-test_filter_count.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_filter_count.obj `if test -f 'libarchive/test/test_filter_count.c'; then $(CYGPATH_W) 'libarchive/test/test_filter_count.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_filter_count.c'; fi` - -libarchive/test/test-test_fuzz.o: libarchive/test/test_fuzz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_fuzz.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_fuzz.Tpo -c -o libarchive/test/test-test_fuzz.o `test -f 'libarchive/test/test_fuzz.c' || echo '$(srcdir)/'`libarchive/test/test_fuzz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_fuzz.Tpo libarchive/test/$(DEPDIR)/test-test_fuzz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_fuzz.c' object='libarchive/test/test-test_fuzz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_fuzz.o `test -f 'libarchive/test/test_fuzz.c' || echo '$(srcdir)/'`libarchive/test/test_fuzz.c - -libarchive/test/test-test_fuzz.obj: libarchive/test/test_fuzz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_fuzz.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_fuzz.Tpo -c -o libarchive/test/test-test_fuzz.obj `if test -f 'libarchive/test/test_fuzz.c'; then $(CYGPATH_W) 'libarchive/test/test_fuzz.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_fuzz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_fuzz.Tpo libarchive/test/$(DEPDIR)/test-test_fuzz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_fuzz.c' object='libarchive/test/test-test_fuzz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_fuzz.obj `if test -f 'libarchive/test/test_fuzz.c'; then $(CYGPATH_W) 'libarchive/test/test_fuzz.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_fuzz.c'; fi` - -libarchive/test/test-test_gnutar_filename_encoding.o: libarchive/test/test_gnutar_filename_encoding.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_gnutar_filename_encoding.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_gnutar_filename_encoding.Tpo -c -o libarchive/test/test-test_gnutar_filename_encoding.o `test -f 'libarchive/test/test_gnutar_filename_encoding.c' || echo '$(srcdir)/'`libarchive/test/test_gnutar_filename_encoding.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_gnutar_filename_encoding.Tpo libarchive/test/$(DEPDIR)/test-test_gnutar_filename_encoding.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_gnutar_filename_encoding.c' object='libarchive/test/test-test_gnutar_filename_encoding.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_gnutar_filename_encoding.o `test -f 'libarchive/test/test_gnutar_filename_encoding.c' || echo '$(srcdir)/'`libarchive/test/test_gnutar_filename_encoding.c - -libarchive/test/test-test_gnutar_filename_encoding.obj: libarchive/test/test_gnutar_filename_encoding.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_gnutar_filename_encoding.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_gnutar_filename_encoding.Tpo -c -o libarchive/test/test-test_gnutar_filename_encoding.obj `if test -f 'libarchive/test/test_gnutar_filename_encoding.c'; then $(CYGPATH_W) 'libarchive/test/test_gnutar_filename_encoding.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_gnutar_filename_encoding.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_gnutar_filename_encoding.Tpo libarchive/test/$(DEPDIR)/test-test_gnutar_filename_encoding.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_gnutar_filename_encoding.c' object='libarchive/test/test-test_gnutar_filename_encoding.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_gnutar_filename_encoding.obj `if test -f 'libarchive/test/test_gnutar_filename_encoding.c'; then $(CYGPATH_W) 'libarchive/test/test_gnutar_filename_encoding.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_gnutar_filename_encoding.c'; fi` - -libarchive/test/test-test_link_resolver.o: libarchive/test/test_link_resolver.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_link_resolver.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_link_resolver.Tpo -c -o libarchive/test/test-test_link_resolver.o `test -f 'libarchive/test/test_link_resolver.c' || echo '$(srcdir)/'`libarchive/test/test_link_resolver.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_link_resolver.Tpo libarchive/test/$(DEPDIR)/test-test_link_resolver.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_link_resolver.c' object='libarchive/test/test-test_link_resolver.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_link_resolver.o `test -f 'libarchive/test/test_link_resolver.c' || echo '$(srcdir)/'`libarchive/test/test_link_resolver.c - -libarchive/test/test-test_link_resolver.obj: libarchive/test/test_link_resolver.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_link_resolver.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_link_resolver.Tpo -c -o libarchive/test/test-test_link_resolver.obj `if test -f 'libarchive/test/test_link_resolver.c'; then $(CYGPATH_W) 'libarchive/test/test_link_resolver.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_link_resolver.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_link_resolver.Tpo libarchive/test/$(DEPDIR)/test-test_link_resolver.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_link_resolver.c' object='libarchive/test/test-test_link_resolver.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_link_resolver.obj `if test -f 'libarchive/test/test_link_resolver.c'; then $(CYGPATH_W) 'libarchive/test/test_link_resolver.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_link_resolver.c'; fi` - -libarchive/test/test-test_open_failure.o: libarchive/test/test_open_failure.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_open_failure.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_open_failure.Tpo -c -o libarchive/test/test-test_open_failure.o `test -f 'libarchive/test/test_open_failure.c' || echo '$(srcdir)/'`libarchive/test/test_open_failure.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_open_failure.Tpo libarchive/test/$(DEPDIR)/test-test_open_failure.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_open_failure.c' object='libarchive/test/test-test_open_failure.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_open_failure.o `test -f 'libarchive/test/test_open_failure.c' || echo '$(srcdir)/'`libarchive/test/test_open_failure.c - -libarchive/test/test-test_open_failure.obj: libarchive/test/test_open_failure.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_open_failure.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_open_failure.Tpo -c -o libarchive/test/test-test_open_failure.obj `if test -f 'libarchive/test/test_open_failure.c'; then $(CYGPATH_W) 'libarchive/test/test_open_failure.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_open_failure.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_open_failure.Tpo libarchive/test/$(DEPDIR)/test-test_open_failure.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_open_failure.c' object='libarchive/test/test-test_open_failure.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_open_failure.obj `if test -f 'libarchive/test/test_open_failure.c'; then $(CYGPATH_W) 'libarchive/test/test_open_failure.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_open_failure.c'; fi` - -libarchive/test/test-test_open_fd.o: libarchive/test/test_open_fd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_open_fd.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_open_fd.Tpo -c -o libarchive/test/test-test_open_fd.o `test -f 'libarchive/test/test_open_fd.c' || echo '$(srcdir)/'`libarchive/test/test_open_fd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_open_fd.Tpo libarchive/test/$(DEPDIR)/test-test_open_fd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_open_fd.c' object='libarchive/test/test-test_open_fd.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_open_fd.o `test -f 'libarchive/test/test_open_fd.c' || echo '$(srcdir)/'`libarchive/test/test_open_fd.c - -libarchive/test/test-test_open_fd.obj: libarchive/test/test_open_fd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_open_fd.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_open_fd.Tpo -c -o libarchive/test/test-test_open_fd.obj `if test -f 'libarchive/test/test_open_fd.c'; then $(CYGPATH_W) 'libarchive/test/test_open_fd.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_open_fd.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_open_fd.Tpo libarchive/test/$(DEPDIR)/test-test_open_fd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_open_fd.c' object='libarchive/test/test-test_open_fd.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_open_fd.obj `if test -f 'libarchive/test/test_open_fd.c'; then $(CYGPATH_W) 'libarchive/test/test_open_fd.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_open_fd.c'; fi` - -libarchive/test/test-test_open_file.o: libarchive/test/test_open_file.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_open_file.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_open_file.Tpo -c -o libarchive/test/test-test_open_file.o `test -f 'libarchive/test/test_open_file.c' || echo '$(srcdir)/'`libarchive/test/test_open_file.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_open_file.Tpo libarchive/test/$(DEPDIR)/test-test_open_file.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_open_file.c' object='libarchive/test/test-test_open_file.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_open_file.o `test -f 'libarchive/test/test_open_file.c' || echo '$(srcdir)/'`libarchive/test/test_open_file.c - -libarchive/test/test-test_open_file.obj: libarchive/test/test_open_file.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_open_file.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_open_file.Tpo -c -o libarchive/test/test-test_open_file.obj `if test -f 'libarchive/test/test_open_file.c'; then $(CYGPATH_W) 'libarchive/test/test_open_file.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_open_file.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_open_file.Tpo libarchive/test/$(DEPDIR)/test-test_open_file.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_open_file.c' object='libarchive/test/test-test_open_file.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_open_file.obj `if test -f 'libarchive/test/test_open_file.c'; then $(CYGPATH_W) 'libarchive/test/test_open_file.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_open_file.c'; fi` - -libarchive/test/test-test_open_filename.o: libarchive/test/test_open_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_open_filename.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_open_filename.Tpo -c -o libarchive/test/test-test_open_filename.o `test -f 'libarchive/test/test_open_filename.c' || echo '$(srcdir)/'`libarchive/test/test_open_filename.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_open_filename.Tpo libarchive/test/$(DEPDIR)/test-test_open_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_open_filename.c' object='libarchive/test/test-test_open_filename.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_open_filename.o `test -f 'libarchive/test/test_open_filename.c' || echo '$(srcdir)/'`libarchive/test/test_open_filename.c - -libarchive/test/test-test_open_filename.obj: libarchive/test/test_open_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_open_filename.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_open_filename.Tpo -c -o libarchive/test/test-test_open_filename.obj `if test -f 'libarchive/test/test_open_filename.c'; then $(CYGPATH_W) 'libarchive/test/test_open_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_open_filename.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_open_filename.Tpo libarchive/test/$(DEPDIR)/test-test_open_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_open_filename.c' object='libarchive/test/test-test_open_filename.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_open_filename.obj `if test -f 'libarchive/test/test_open_filename.c'; then $(CYGPATH_W) 'libarchive/test/test_open_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_open_filename.c'; fi` - -libarchive/test/test-test_pax_filename_encoding.o: libarchive/test/test_pax_filename_encoding.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_pax_filename_encoding.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_pax_filename_encoding.Tpo -c -o libarchive/test/test-test_pax_filename_encoding.o `test -f 'libarchive/test/test_pax_filename_encoding.c' || echo '$(srcdir)/'`libarchive/test/test_pax_filename_encoding.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_pax_filename_encoding.Tpo libarchive/test/$(DEPDIR)/test-test_pax_filename_encoding.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_pax_filename_encoding.c' object='libarchive/test/test-test_pax_filename_encoding.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_pax_filename_encoding.o `test -f 'libarchive/test/test_pax_filename_encoding.c' || echo '$(srcdir)/'`libarchive/test/test_pax_filename_encoding.c - -libarchive/test/test-test_pax_filename_encoding.obj: libarchive/test/test_pax_filename_encoding.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_pax_filename_encoding.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_pax_filename_encoding.Tpo -c -o libarchive/test/test-test_pax_filename_encoding.obj `if test -f 'libarchive/test/test_pax_filename_encoding.c'; then $(CYGPATH_W) 'libarchive/test/test_pax_filename_encoding.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_pax_filename_encoding.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_pax_filename_encoding.Tpo libarchive/test/$(DEPDIR)/test-test_pax_filename_encoding.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_pax_filename_encoding.c' object='libarchive/test/test-test_pax_filename_encoding.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_pax_filename_encoding.obj `if test -f 'libarchive/test/test_pax_filename_encoding.c'; then $(CYGPATH_W) 'libarchive/test/test_pax_filename_encoding.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_pax_filename_encoding.c'; fi` - -libarchive/test/test-test_pax_xattr_header.o: libarchive/test/test_pax_xattr_header.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_pax_xattr_header.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_pax_xattr_header.Tpo -c -o libarchive/test/test-test_pax_xattr_header.o `test -f 'libarchive/test/test_pax_xattr_header.c' || echo '$(srcdir)/'`libarchive/test/test_pax_xattr_header.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_pax_xattr_header.Tpo libarchive/test/$(DEPDIR)/test-test_pax_xattr_header.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_pax_xattr_header.c' object='libarchive/test/test-test_pax_xattr_header.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_pax_xattr_header.o `test -f 'libarchive/test/test_pax_xattr_header.c' || echo '$(srcdir)/'`libarchive/test/test_pax_xattr_header.c - -libarchive/test/test-test_pax_xattr_header.obj: libarchive/test/test_pax_xattr_header.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_pax_xattr_header.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_pax_xattr_header.Tpo -c -o libarchive/test/test-test_pax_xattr_header.obj `if test -f 'libarchive/test/test_pax_xattr_header.c'; then $(CYGPATH_W) 'libarchive/test/test_pax_xattr_header.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_pax_xattr_header.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_pax_xattr_header.Tpo libarchive/test/$(DEPDIR)/test-test_pax_xattr_header.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_pax_xattr_header.c' object='libarchive/test/test-test_pax_xattr_header.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_pax_xattr_header.obj `if test -f 'libarchive/test/test_pax_xattr_header.c'; then $(CYGPATH_W) 'libarchive/test/test_pax_xattr_header.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_pax_xattr_header.c'; fi` - -libarchive/test/test-test_read_data_large.o: libarchive/test/test_read_data_large.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_data_large.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_data_large.Tpo -c -o libarchive/test/test-test_read_data_large.o `test -f 'libarchive/test/test_read_data_large.c' || echo '$(srcdir)/'`libarchive/test/test_read_data_large.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_data_large.Tpo libarchive/test/$(DEPDIR)/test-test_read_data_large.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_data_large.c' object='libarchive/test/test-test_read_data_large.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_data_large.o `test -f 'libarchive/test/test_read_data_large.c' || echo '$(srcdir)/'`libarchive/test/test_read_data_large.c - -libarchive/test/test-test_read_data_large.obj: libarchive/test/test_read_data_large.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_data_large.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_data_large.Tpo -c -o libarchive/test/test-test_read_data_large.obj `if test -f 'libarchive/test/test_read_data_large.c'; then $(CYGPATH_W) 'libarchive/test/test_read_data_large.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_data_large.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_data_large.Tpo libarchive/test/$(DEPDIR)/test-test_read_data_large.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_data_large.c' object='libarchive/test/test-test_read_data_large.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_data_large.obj `if test -f 'libarchive/test/test_read_data_large.c'; then $(CYGPATH_W) 'libarchive/test/test_read_data_large.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_data_large.c'; fi` - -libarchive/test/test-test_read_disk.o: libarchive/test/test_read_disk.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_disk.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_disk.Tpo -c -o libarchive/test/test-test_read_disk.o `test -f 'libarchive/test/test_read_disk.c' || echo '$(srcdir)/'`libarchive/test/test_read_disk.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_disk.Tpo libarchive/test/$(DEPDIR)/test-test_read_disk.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_disk.c' object='libarchive/test/test-test_read_disk.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_disk.o `test -f 'libarchive/test/test_read_disk.c' || echo '$(srcdir)/'`libarchive/test/test_read_disk.c - -libarchive/test/test-test_read_disk.obj: libarchive/test/test_read_disk.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_disk.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_disk.Tpo -c -o libarchive/test/test-test_read_disk.obj `if test -f 'libarchive/test/test_read_disk.c'; then $(CYGPATH_W) 'libarchive/test/test_read_disk.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_disk.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_disk.Tpo libarchive/test/$(DEPDIR)/test-test_read_disk.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_disk.c' object='libarchive/test/test-test_read_disk.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_disk.obj `if test -f 'libarchive/test/test_read_disk.c'; then $(CYGPATH_W) 'libarchive/test/test_read_disk.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_disk.c'; fi` - -libarchive/test/test-test_read_disk_directory_traversals.o: libarchive/test/test_read_disk_directory_traversals.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_disk_directory_traversals.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_disk_directory_traversals.Tpo -c -o libarchive/test/test-test_read_disk_directory_traversals.o `test -f 'libarchive/test/test_read_disk_directory_traversals.c' || echo '$(srcdir)/'`libarchive/test/test_read_disk_directory_traversals.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_disk_directory_traversals.Tpo libarchive/test/$(DEPDIR)/test-test_read_disk_directory_traversals.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_disk_directory_traversals.c' object='libarchive/test/test-test_read_disk_directory_traversals.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_disk_directory_traversals.o `test -f 'libarchive/test/test_read_disk_directory_traversals.c' || echo '$(srcdir)/'`libarchive/test/test_read_disk_directory_traversals.c - -libarchive/test/test-test_read_disk_directory_traversals.obj: libarchive/test/test_read_disk_directory_traversals.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_disk_directory_traversals.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_disk_directory_traversals.Tpo -c -o libarchive/test/test-test_read_disk_directory_traversals.obj `if test -f 'libarchive/test/test_read_disk_directory_traversals.c'; then $(CYGPATH_W) 'libarchive/test/test_read_disk_directory_traversals.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_disk_directory_traversals.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_disk_directory_traversals.Tpo libarchive/test/$(DEPDIR)/test-test_read_disk_directory_traversals.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_disk_directory_traversals.c' object='libarchive/test/test-test_read_disk_directory_traversals.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_disk_directory_traversals.obj `if test -f 'libarchive/test/test_read_disk_directory_traversals.c'; then $(CYGPATH_W) 'libarchive/test/test_read_disk_directory_traversals.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_disk_directory_traversals.c'; fi` - -libarchive/test/test-test_read_disk_entry_from_file.o: libarchive/test/test_read_disk_entry_from_file.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_disk_entry_from_file.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_disk_entry_from_file.Tpo -c -o libarchive/test/test-test_read_disk_entry_from_file.o `test -f 'libarchive/test/test_read_disk_entry_from_file.c' || echo '$(srcdir)/'`libarchive/test/test_read_disk_entry_from_file.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_disk_entry_from_file.Tpo libarchive/test/$(DEPDIR)/test-test_read_disk_entry_from_file.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_disk_entry_from_file.c' object='libarchive/test/test-test_read_disk_entry_from_file.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_disk_entry_from_file.o `test -f 'libarchive/test/test_read_disk_entry_from_file.c' || echo '$(srcdir)/'`libarchive/test/test_read_disk_entry_from_file.c - -libarchive/test/test-test_read_disk_entry_from_file.obj: libarchive/test/test_read_disk_entry_from_file.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_disk_entry_from_file.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_disk_entry_from_file.Tpo -c -o libarchive/test/test-test_read_disk_entry_from_file.obj `if test -f 'libarchive/test/test_read_disk_entry_from_file.c'; then $(CYGPATH_W) 'libarchive/test/test_read_disk_entry_from_file.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_disk_entry_from_file.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_disk_entry_from_file.Tpo libarchive/test/$(DEPDIR)/test-test_read_disk_entry_from_file.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_disk_entry_from_file.c' object='libarchive/test/test-test_read_disk_entry_from_file.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_disk_entry_from_file.obj `if test -f 'libarchive/test/test_read_disk_entry_from_file.c'; then $(CYGPATH_W) 'libarchive/test/test_read_disk_entry_from_file.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_disk_entry_from_file.c'; fi` - -libarchive/test/test-test_read_extract.o: libarchive/test/test_read_extract.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_extract.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_extract.Tpo -c -o libarchive/test/test-test_read_extract.o `test -f 'libarchive/test/test_read_extract.c' || echo '$(srcdir)/'`libarchive/test/test_read_extract.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_extract.Tpo libarchive/test/$(DEPDIR)/test-test_read_extract.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_extract.c' object='libarchive/test/test-test_read_extract.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_extract.o `test -f 'libarchive/test/test_read_extract.c' || echo '$(srcdir)/'`libarchive/test/test_read_extract.c - -libarchive/test/test-test_read_extract.obj: libarchive/test/test_read_extract.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_extract.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_extract.Tpo -c -o libarchive/test/test-test_read_extract.obj `if test -f 'libarchive/test/test_read_extract.c'; then $(CYGPATH_W) 'libarchive/test/test_read_extract.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_extract.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_extract.Tpo libarchive/test/$(DEPDIR)/test-test_read_extract.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_extract.c' object='libarchive/test/test-test_read_extract.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_extract.obj `if test -f 'libarchive/test/test_read_extract.c'; then $(CYGPATH_W) 'libarchive/test/test_read_extract.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_extract.c'; fi` - -libarchive/test/test-test_read_file_nonexistent.o: libarchive/test/test_read_file_nonexistent.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_file_nonexistent.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_file_nonexistent.Tpo -c -o libarchive/test/test-test_read_file_nonexistent.o `test -f 'libarchive/test/test_read_file_nonexistent.c' || echo '$(srcdir)/'`libarchive/test/test_read_file_nonexistent.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_file_nonexistent.Tpo libarchive/test/$(DEPDIR)/test-test_read_file_nonexistent.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_file_nonexistent.c' object='libarchive/test/test-test_read_file_nonexistent.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_file_nonexistent.o `test -f 'libarchive/test/test_read_file_nonexistent.c' || echo '$(srcdir)/'`libarchive/test/test_read_file_nonexistent.c - -libarchive/test/test-test_read_file_nonexistent.obj: libarchive/test/test_read_file_nonexistent.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_file_nonexistent.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_file_nonexistent.Tpo -c -o libarchive/test/test-test_read_file_nonexistent.obj `if test -f 'libarchive/test/test_read_file_nonexistent.c'; then $(CYGPATH_W) 'libarchive/test/test_read_file_nonexistent.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_file_nonexistent.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_file_nonexistent.Tpo libarchive/test/$(DEPDIR)/test-test_read_file_nonexistent.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_file_nonexistent.c' object='libarchive/test/test-test_read_file_nonexistent.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_file_nonexistent.obj `if test -f 'libarchive/test/test_read_file_nonexistent.c'; then $(CYGPATH_W) 'libarchive/test/test_read_file_nonexistent.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_file_nonexistent.c'; fi` - -libarchive/test/test-test_read_filter_compress.o: libarchive/test/test_read_filter_compress.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_filter_compress.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_filter_compress.Tpo -c -o libarchive/test/test-test_read_filter_compress.o `test -f 'libarchive/test/test_read_filter_compress.c' || echo '$(srcdir)/'`libarchive/test/test_read_filter_compress.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_filter_compress.Tpo libarchive/test/$(DEPDIR)/test-test_read_filter_compress.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_filter_compress.c' object='libarchive/test/test-test_read_filter_compress.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_filter_compress.o `test -f 'libarchive/test/test_read_filter_compress.c' || echo '$(srcdir)/'`libarchive/test/test_read_filter_compress.c - -libarchive/test/test-test_read_filter_compress.obj: libarchive/test/test_read_filter_compress.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_filter_compress.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_filter_compress.Tpo -c -o libarchive/test/test-test_read_filter_compress.obj `if test -f 'libarchive/test/test_read_filter_compress.c'; then $(CYGPATH_W) 'libarchive/test/test_read_filter_compress.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_filter_compress.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_filter_compress.Tpo libarchive/test/$(DEPDIR)/test-test_read_filter_compress.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_filter_compress.c' object='libarchive/test/test-test_read_filter_compress.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_filter_compress.obj `if test -f 'libarchive/test/test_read_filter_compress.c'; then $(CYGPATH_W) 'libarchive/test/test_read_filter_compress.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_filter_compress.c'; fi` - -libarchive/test/test-test_read_filter_grzip.o: libarchive/test/test_read_filter_grzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_filter_grzip.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_filter_grzip.Tpo -c -o libarchive/test/test-test_read_filter_grzip.o `test -f 'libarchive/test/test_read_filter_grzip.c' || echo '$(srcdir)/'`libarchive/test/test_read_filter_grzip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_filter_grzip.Tpo libarchive/test/$(DEPDIR)/test-test_read_filter_grzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_filter_grzip.c' object='libarchive/test/test-test_read_filter_grzip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_filter_grzip.o `test -f 'libarchive/test/test_read_filter_grzip.c' || echo '$(srcdir)/'`libarchive/test/test_read_filter_grzip.c - -libarchive/test/test-test_read_filter_grzip.obj: libarchive/test/test_read_filter_grzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_filter_grzip.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_filter_grzip.Tpo -c -o libarchive/test/test-test_read_filter_grzip.obj `if test -f 'libarchive/test/test_read_filter_grzip.c'; then $(CYGPATH_W) 'libarchive/test/test_read_filter_grzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_filter_grzip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_filter_grzip.Tpo libarchive/test/$(DEPDIR)/test-test_read_filter_grzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_filter_grzip.c' object='libarchive/test/test-test_read_filter_grzip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_filter_grzip.obj `if test -f 'libarchive/test/test_read_filter_grzip.c'; then $(CYGPATH_W) 'libarchive/test/test_read_filter_grzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_filter_grzip.c'; fi` - -libarchive/test/test-test_read_filter_lrzip.o: libarchive/test/test_read_filter_lrzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_filter_lrzip.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_filter_lrzip.Tpo -c -o libarchive/test/test-test_read_filter_lrzip.o `test -f 'libarchive/test/test_read_filter_lrzip.c' || echo '$(srcdir)/'`libarchive/test/test_read_filter_lrzip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_filter_lrzip.Tpo libarchive/test/$(DEPDIR)/test-test_read_filter_lrzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_filter_lrzip.c' object='libarchive/test/test-test_read_filter_lrzip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_filter_lrzip.o `test -f 'libarchive/test/test_read_filter_lrzip.c' || echo '$(srcdir)/'`libarchive/test/test_read_filter_lrzip.c - -libarchive/test/test-test_read_filter_lrzip.obj: libarchive/test/test_read_filter_lrzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_filter_lrzip.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_filter_lrzip.Tpo -c -o libarchive/test/test-test_read_filter_lrzip.obj `if test -f 'libarchive/test/test_read_filter_lrzip.c'; then $(CYGPATH_W) 'libarchive/test/test_read_filter_lrzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_filter_lrzip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_filter_lrzip.Tpo libarchive/test/$(DEPDIR)/test-test_read_filter_lrzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_filter_lrzip.c' object='libarchive/test/test-test_read_filter_lrzip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_filter_lrzip.obj `if test -f 'libarchive/test/test_read_filter_lrzip.c'; then $(CYGPATH_W) 'libarchive/test/test_read_filter_lrzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_filter_lrzip.c'; fi` - -libarchive/test/test-test_read_filter_lzop.o: libarchive/test/test_read_filter_lzop.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_filter_lzop.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_filter_lzop.Tpo -c -o libarchive/test/test-test_read_filter_lzop.o `test -f 'libarchive/test/test_read_filter_lzop.c' || echo '$(srcdir)/'`libarchive/test/test_read_filter_lzop.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_filter_lzop.Tpo libarchive/test/$(DEPDIR)/test-test_read_filter_lzop.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_filter_lzop.c' object='libarchive/test/test-test_read_filter_lzop.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_filter_lzop.o `test -f 'libarchive/test/test_read_filter_lzop.c' || echo '$(srcdir)/'`libarchive/test/test_read_filter_lzop.c - -libarchive/test/test-test_read_filter_lzop.obj: libarchive/test/test_read_filter_lzop.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_filter_lzop.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_filter_lzop.Tpo -c -o libarchive/test/test-test_read_filter_lzop.obj `if test -f 'libarchive/test/test_read_filter_lzop.c'; then $(CYGPATH_W) 'libarchive/test/test_read_filter_lzop.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_filter_lzop.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_filter_lzop.Tpo libarchive/test/$(DEPDIR)/test-test_read_filter_lzop.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_filter_lzop.c' object='libarchive/test/test-test_read_filter_lzop.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_filter_lzop.obj `if test -f 'libarchive/test/test_read_filter_lzop.c'; then $(CYGPATH_W) 'libarchive/test/test_read_filter_lzop.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_filter_lzop.c'; fi` - -libarchive/test/test-test_read_filter_lzop_multiple_parts.o: libarchive/test/test_read_filter_lzop_multiple_parts.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_filter_lzop_multiple_parts.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_filter_lzop_multiple_parts.Tpo -c -o libarchive/test/test-test_read_filter_lzop_multiple_parts.o `test -f 'libarchive/test/test_read_filter_lzop_multiple_parts.c' || echo '$(srcdir)/'`libarchive/test/test_read_filter_lzop_multiple_parts.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_filter_lzop_multiple_parts.Tpo libarchive/test/$(DEPDIR)/test-test_read_filter_lzop_multiple_parts.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_filter_lzop_multiple_parts.c' object='libarchive/test/test-test_read_filter_lzop_multiple_parts.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_filter_lzop_multiple_parts.o `test -f 'libarchive/test/test_read_filter_lzop_multiple_parts.c' || echo '$(srcdir)/'`libarchive/test/test_read_filter_lzop_multiple_parts.c - -libarchive/test/test-test_read_filter_lzop_multiple_parts.obj: libarchive/test/test_read_filter_lzop_multiple_parts.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_filter_lzop_multiple_parts.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_filter_lzop_multiple_parts.Tpo -c -o libarchive/test/test-test_read_filter_lzop_multiple_parts.obj `if test -f 'libarchive/test/test_read_filter_lzop_multiple_parts.c'; then $(CYGPATH_W) 'libarchive/test/test_read_filter_lzop_multiple_parts.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_filter_lzop_multiple_parts.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_filter_lzop_multiple_parts.Tpo libarchive/test/$(DEPDIR)/test-test_read_filter_lzop_multiple_parts.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_filter_lzop_multiple_parts.c' object='libarchive/test/test-test_read_filter_lzop_multiple_parts.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_filter_lzop_multiple_parts.obj `if test -f 'libarchive/test/test_read_filter_lzop_multiple_parts.c'; then $(CYGPATH_W) 'libarchive/test/test_read_filter_lzop_multiple_parts.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_filter_lzop_multiple_parts.c'; fi` - -libarchive/test/test-test_read_filter_program.o: libarchive/test/test_read_filter_program.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_filter_program.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_filter_program.Tpo -c -o libarchive/test/test-test_read_filter_program.o `test -f 'libarchive/test/test_read_filter_program.c' || echo '$(srcdir)/'`libarchive/test/test_read_filter_program.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_filter_program.Tpo libarchive/test/$(DEPDIR)/test-test_read_filter_program.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_filter_program.c' object='libarchive/test/test-test_read_filter_program.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_filter_program.o `test -f 'libarchive/test/test_read_filter_program.c' || echo '$(srcdir)/'`libarchive/test/test_read_filter_program.c - -libarchive/test/test-test_read_filter_program.obj: libarchive/test/test_read_filter_program.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_filter_program.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_filter_program.Tpo -c -o libarchive/test/test-test_read_filter_program.obj `if test -f 'libarchive/test/test_read_filter_program.c'; then $(CYGPATH_W) 'libarchive/test/test_read_filter_program.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_filter_program.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_filter_program.Tpo libarchive/test/$(DEPDIR)/test-test_read_filter_program.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_filter_program.c' object='libarchive/test/test-test_read_filter_program.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_filter_program.obj `if test -f 'libarchive/test/test_read_filter_program.c'; then $(CYGPATH_W) 'libarchive/test/test_read_filter_program.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_filter_program.c'; fi` - -libarchive/test/test-test_read_filter_program_signature.o: libarchive/test/test_read_filter_program_signature.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_filter_program_signature.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_filter_program_signature.Tpo -c -o libarchive/test/test-test_read_filter_program_signature.o `test -f 'libarchive/test/test_read_filter_program_signature.c' || echo '$(srcdir)/'`libarchive/test/test_read_filter_program_signature.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_filter_program_signature.Tpo libarchive/test/$(DEPDIR)/test-test_read_filter_program_signature.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_filter_program_signature.c' object='libarchive/test/test-test_read_filter_program_signature.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_filter_program_signature.o `test -f 'libarchive/test/test_read_filter_program_signature.c' || echo '$(srcdir)/'`libarchive/test/test_read_filter_program_signature.c - -libarchive/test/test-test_read_filter_program_signature.obj: libarchive/test/test_read_filter_program_signature.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_filter_program_signature.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_filter_program_signature.Tpo -c -o libarchive/test/test-test_read_filter_program_signature.obj `if test -f 'libarchive/test/test_read_filter_program_signature.c'; then $(CYGPATH_W) 'libarchive/test/test_read_filter_program_signature.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_filter_program_signature.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_filter_program_signature.Tpo libarchive/test/$(DEPDIR)/test-test_read_filter_program_signature.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_filter_program_signature.c' object='libarchive/test/test-test_read_filter_program_signature.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_filter_program_signature.obj `if test -f 'libarchive/test/test_read_filter_program_signature.c'; then $(CYGPATH_W) 'libarchive/test/test_read_filter_program_signature.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_filter_program_signature.c'; fi` - -libarchive/test/test-test_read_filter_uudecode.o: libarchive/test/test_read_filter_uudecode.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_filter_uudecode.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_filter_uudecode.Tpo -c -o libarchive/test/test-test_read_filter_uudecode.o `test -f 'libarchive/test/test_read_filter_uudecode.c' || echo '$(srcdir)/'`libarchive/test/test_read_filter_uudecode.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_filter_uudecode.Tpo libarchive/test/$(DEPDIR)/test-test_read_filter_uudecode.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_filter_uudecode.c' object='libarchive/test/test-test_read_filter_uudecode.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_filter_uudecode.o `test -f 'libarchive/test/test_read_filter_uudecode.c' || echo '$(srcdir)/'`libarchive/test/test_read_filter_uudecode.c - -libarchive/test/test-test_read_filter_uudecode.obj: libarchive/test/test_read_filter_uudecode.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_filter_uudecode.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_filter_uudecode.Tpo -c -o libarchive/test/test-test_read_filter_uudecode.obj `if test -f 'libarchive/test/test_read_filter_uudecode.c'; then $(CYGPATH_W) 'libarchive/test/test_read_filter_uudecode.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_filter_uudecode.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_filter_uudecode.Tpo libarchive/test/$(DEPDIR)/test-test_read_filter_uudecode.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_filter_uudecode.c' object='libarchive/test/test-test_read_filter_uudecode.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_filter_uudecode.obj `if test -f 'libarchive/test/test_read_filter_uudecode.c'; then $(CYGPATH_W) 'libarchive/test/test_read_filter_uudecode.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_filter_uudecode.c'; fi` - -libarchive/test/test-test_read_filter_uudecode_raw.o: libarchive/test/test_read_filter_uudecode_raw.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_filter_uudecode_raw.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_filter_uudecode_raw.Tpo -c -o libarchive/test/test-test_read_filter_uudecode_raw.o `test -f 'libarchive/test/test_read_filter_uudecode_raw.c' || echo '$(srcdir)/'`libarchive/test/test_read_filter_uudecode_raw.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_filter_uudecode_raw.Tpo libarchive/test/$(DEPDIR)/test-test_read_filter_uudecode_raw.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_filter_uudecode_raw.c' object='libarchive/test/test-test_read_filter_uudecode_raw.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_filter_uudecode_raw.o `test -f 'libarchive/test/test_read_filter_uudecode_raw.c' || echo '$(srcdir)/'`libarchive/test/test_read_filter_uudecode_raw.c - -libarchive/test/test-test_read_filter_uudecode_raw.obj: libarchive/test/test_read_filter_uudecode_raw.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_filter_uudecode_raw.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_filter_uudecode_raw.Tpo -c -o libarchive/test/test-test_read_filter_uudecode_raw.obj `if test -f 'libarchive/test/test_read_filter_uudecode_raw.c'; then $(CYGPATH_W) 'libarchive/test/test_read_filter_uudecode_raw.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_filter_uudecode_raw.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_filter_uudecode_raw.Tpo libarchive/test/$(DEPDIR)/test-test_read_filter_uudecode_raw.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_filter_uudecode_raw.c' object='libarchive/test/test-test_read_filter_uudecode_raw.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_filter_uudecode_raw.obj `if test -f 'libarchive/test/test_read_filter_uudecode_raw.c'; then $(CYGPATH_W) 'libarchive/test/test_read_filter_uudecode_raw.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_filter_uudecode_raw.c'; fi` - -libarchive/test/test-test_read_format_7zip.o: libarchive/test/test_read_format_7zip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_7zip.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_7zip.Tpo -c -o libarchive/test/test-test_read_format_7zip.o `test -f 'libarchive/test/test_read_format_7zip.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_7zip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_7zip.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_7zip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_7zip.c' object='libarchive/test/test-test_read_format_7zip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_7zip.o `test -f 'libarchive/test/test_read_format_7zip.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_7zip.c - -libarchive/test/test-test_read_format_7zip.obj: libarchive/test/test_read_format_7zip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_7zip.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_7zip.Tpo -c -o libarchive/test/test-test_read_format_7zip.obj `if test -f 'libarchive/test/test_read_format_7zip.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_7zip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_7zip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_7zip.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_7zip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_7zip.c' object='libarchive/test/test-test_read_format_7zip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_7zip.obj `if test -f 'libarchive/test/test_read_format_7zip.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_7zip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_7zip.c'; fi` - -libarchive/test/test-test_read_format_7zip_encryption_data.o: libarchive/test/test_read_format_7zip_encryption_data.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_7zip_encryption_data.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_data.Tpo -c -o libarchive/test/test-test_read_format_7zip_encryption_data.o `test -f 'libarchive/test/test_read_format_7zip_encryption_data.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_7zip_encryption_data.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_data.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_data.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_7zip_encryption_data.c' object='libarchive/test/test-test_read_format_7zip_encryption_data.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_7zip_encryption_data.o `test -f 'libarchive/test/test_read_format_7zip_encryption_data.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_7zip_encryption_data.c - -libarchive/test/test-test_read_format_7zip_encryption_data.obj: libarchive/test/test_read_format_7zip_encryption_data.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_7zip_encryption_data.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_data.Tpo -c -o libarchive/test/test-test_read_format_7zip_encryption_data.obj `if test -f 'libarchive/test/test_read_format_7zip_encryption_data.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_7zip_encryption_data.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_7zip_encryption_data.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_data.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_data.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_7zip_encryption_data.c' object='libarchive/test/test-test_read_format_7zip_encryption_data.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_7zip_encryption_data.obj `if test -f 'libarchive/test/test_read_format_7zip_encryption_data.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_7zip_encryption_data.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_7zip_encryption_data.c'; fi` - -libarchive/test/test-test_read_format_7zip_encryption_partially.o: libarchive/test/test_read_format_7zip_encryption_partially.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_7zip_encryption_partially.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_partially.Tpo -c -o libarchive/test/test-test_read_format_7zip_encryption_partially.o `test -f 'libarchive/test/test_read_format_7zip_encryption_partially.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_7zip_encryption_partially.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_partially.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_partially.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_7zip_encryption_partially.c' object='libarchive/test/test-test_read_format_7zip_encryption_partially.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_7zip_encryption_partially.o `test -f 'libarchive/test/test_read_format_7zip_encryption_partially.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_7zip_encryption_partially.c - -libarchive/test/test-test_read_format_7zip_encryption_partially.obj: libarchive/test/test_read_format_7zip_encryption_partially.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_7zip_encryption_partially.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_partially.Tpo -c -o libarchive/test/test-test_read_format_7zip_encryption_partially.obj `if test -f 'libarchive/test/test_read_format_7zip_encryption_partially.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_7zip_encryption_partially.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_7zip_encryption_partially.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_partially.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_partially.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_7zip_encryption_partially.c' object='libarchive/test/test-test_read_format_7zip_encryption_partially.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_7zip_encryption_partially.obj `if test -f 'libarchive/test/test_read_format_7zip_encryption_partially.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_7zip_encryption_partially.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_7zip_encryption_partially.c'; fi` - -libarchive/test/test-test_read_format_7zip_encryption_header.o: libarchive/test/test_read_format_7zip_encryption_header.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_7zip_encryption_header.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_header.Tpo -c -o libarchive/test/test-test_read_format_7zip_encryption_header.o `test -f 'libarchive/test/test_read_format_7zip_encryption_header.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_7zip_encryption_header.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_header.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_header.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_7zip_encryption_header.c' object='libarchive/test/test-test_read_format_7zip_encryption_header.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_7zip_encryption_header.o `test -f 'libarchive/test/test_read_format_7zip_encryption_header.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_7zip_encryption_header.c - -libarchive/test/test-test_read_format_7zip_encryption_header.obj: libarchive/test/test_read_format_7zip_encryption_header.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_7zip_encryption_header.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_header.Tpo -c -o libarchive/test/test-test_read_format_7zip_encryption_header.obj `if test -f 'libarchive/test/test_read_format_7zip_encryption_header.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_7zip_encryption_header.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_7zip_encryption_header.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_header.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_header.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_7zip_encryption_header.c' object='libarchive/test/test-test_read_format_7zip_encryption_header.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_7zip_encryption_header.obj `if test -f 'libarchive/test/test_read_format_7zip_encryption_header.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_7zip_encryption_header.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_7zip_encryption_header.c'; fi` - -libarchive/test/test-test_read_format_7zip_malformed.o: libarchive/test/test_read_format_7zip_malformed.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_7zip_malformed.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_7zip_malformed.Tpo -c -o libarchive/test/test-test_read_format_7zip_malformed.o `test -f 'libarchive/test/test_read_format_7zip_malformed.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_7zip_malformed.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_7zip_malformed.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_7zip_malformed.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_7zip_malformed.c' object='libarchive/test/test-test_read_format_7zip_malformed.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_7zip_malformed.o `test -f 'libarchive/test/test_read_format_7zip_malformed.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_7zip_malformed.c - -libarchive/test/test-test_read_format_7zip_malformed.obj: libarchive/test/test_read_format_7zip_malformed.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_7zip_malformed.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_7zip_malformed.Tpo -c -o libarchive/test/test-test_read_format_7zip_malformed.obj `if test -f 'libarchive/test/test_read_format_7zip_malformed.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_7zip_malformed.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_7zip_malformed.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_7zip_malformed.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_7zip_malformed.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_7zip_malformed.c' object='libarchive/test/test-test_read_format_7zip_malformed.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_7zip_malformed.obj `if test -f 'libarchive/test/test_read_format_7zip_malformed.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_7zip_malformed.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_7zip_malformed.c'; fi` - -libarchive/test/test-test_read_format_7zip_packinfo_digests.o: libarchive/test/test_read_format_7zip_packinfo_digests.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_7zip_packinfo_digests.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_7zip_packinfo_digests.Tpo -c -o libarchive/test/test-test_read_format_7zip_packinfo_digests.o `test -f 'libarchive/test/test_read_format_7zip_packinfo_digests.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_7zip_packinfo_digests.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_7zip_packinfo_digests.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_7zip_packinfo_digests.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_7zip_packinfo_digests.c' object='libarchive/test/test-test_read_format_7zip_packinfo_digests.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_7zip_packinfo_digests.o `test -f 'libarchive/test/test_read_format_7zip_packinfo_digests.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_7zip_packinfo_digests.c - -libarchive/test/test-test_read_format_7zip_packinfo_digests.obj: libarchive/test/test_read_format_7zip_packinfo_digests.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_7zip_packinfo_digests.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_7zip_packinfo_digests.Tpo -c -o libarchive/test/test-test_read_format_7zip_packinfo_digests.obj `if test -f 'libarchive/test/test_read_format_7zip_packinfo_digests.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_7zip_packinfo_digests.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_7zip_packinfo_digests.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_7zip_packinfo_digests.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_7zip_packinfo_digests.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_7zip_packinfo_digests.c' object='libarchive/test/test-test_read_format_7zip_packinfo_digests.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_7zip_packinfo_digests.obj `if test -f 'libarchive/test/test_read_format_7zip_packinfo_digests.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_7zip_packinfo_digests.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_7zip_packinfo_digests.c'; fi` - -libarchive/test/test-test_read_format_ar.o: libarchive/test/test_read_format_ar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_ar.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_ar.Tpo -c -o libarchive/test/test-test_read_format_ar.o `test -f 'libarchive/test/test_read_format_ar.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_ar.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_ar.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_ar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_ar.c' object='libarchive/test/test-test_read_format_ar.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_ar.o `test -f 'libarchive/test/test_read_format_ar.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_ar.c - -libarchive/test/test-test_read_format_ar.obj: libarchive/test/test_read_format_ar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_ar.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_ar.Tpo -c -o libarchive/test/test-test_read_format_ar.obj `if test -f 'libarchive/test/test_read_format_ar.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_ar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_ar.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_ar.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_ar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_ar.c' object='libarchive/test/test-test_read_format_ar.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_ar.obj `if test -f 'libarchive/test/test_read_format_ar.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_ar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_ar.c'; fi` - -libarchive/test/test-test_read_format_cab.o: libarchive/test/test_read_format_cab.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cab.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cab.Tpo -c -o libarchive/test/test-test_read_format_cab.o `test -f 'libarchive/test/test_read_format_cab.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cab.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cab.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cab.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cab.c' object='libarchive/test/test-test_read_format_cab.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cab.o `test -f 'libarchive/test/test_read_format_cab.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cab.c - -libarchive/test/test-test_read_format_cab.obj: libarchive/test/test_read_format_cab.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cab.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cab.Tpo -c -o libarchive/test/test-test_read_format_cab.obj `if test -f 'libarchive/test/test_read_format_cab.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cab.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cab.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cab.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cab.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cab.c' object='libarchive/test/test-test_read_format_cab.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cab.obj `if test -f 'libarchive/test/test_read_format_cab.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cab.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cab.c'; fi` - -libarchive/test/test-test_read_format_cab_filename.o: libarchive/test/test_read_format_cab_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cab_filename.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cab_filename.Tpo -c -o libarchive/test/test-test_read_format_cab_filename.o `test -f 'libarchive/test/test_read_format_cab_filename.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cab_filename.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cab_filename.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cab_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cab_filename.c' object='libarchive/test/test-test_read_format_cab_filename.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cab_filename.o `test -f 'libarchive/test/test_read_format_cab_filename.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cab_filename.c - -libarchive/test/test-test_read_format_cab_filename.obj: libarchive/test/test_read_format_cab_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cab_filename.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cab_filename.Tpo -c -o libarchive/test/test-test_read_format_cab_filename.obj `if test -f 'libarchive/test/test_read_format_cab_filename.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cab_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cab_filename.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cab_filename.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cab_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cab_filename.c' object='libarchive/test/test-test_read_format_cab_filename.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cab_filename.obj `if test -f 'libarchive/test/test_read_format_cab_filename.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cab_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cab_filename.c'; fi` - -libarchive/test/test-test_read_format_cpio_afio.o: libarchive/test/test_read_format_cpio_afio.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_afio.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_afio.Tpo -c -o libarchive/test/test-test_read_format_cpio_afio.o `test -f 'libarchive/test/test_read_format_cpio_afio.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_afio.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_afio.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_afio.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_afio.c' object='libarchive/test/test-test_read_format_cpio_afio.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_afio.o `test -f 'libarchive/test/test_read_format_cpio_afio.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_afio.c - -libarchive/test/test-test_read_format_cpio_afio.obj: libarchive/test/test_read_format_cpio_afio.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_afio.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_afio.Tpo -c -o libarchive/test/test-test_read_format_cpio_afio.obj `if test -f 'libarchive/test/test_read_format_cpio_afio.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_afio.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_afio.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_afio.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_afio.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_afio.c' object='libarchive/test/test-test_read_format_cpio_afio.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_afio.obj `if test -f 'libarchive/test/test_read_format_cpio_afio.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_afio.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_afio.c'; fi` - -libarchive/test/test-test_read_format_cpio_bin.o: libarchive/test/test_read_format_cpio_bin.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_bin.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin.Tpo -c -o libarchive/test/test-test_read_format_cpio_bin.o `test -f 'libarchive/test/test_read_format_cpio_bin.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_bin.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_bin.c' object='libarchive/test/test-test_read_format_cpio_bin.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_bin.o `test -f 'libarchive/test/test_read_format_cpio_bin.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_bin.c - -libarchive/test/test-test_read_format_cpio_bin.obj: libarchive/test/test_read_format_cpio_bin.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_bin.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin.Tpo -c -o libarchive/test/test-test_read_format_cpio_bin.obj `if test -f 'libarchive/test/test_read_format_cpio_bin.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_bin.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_bin.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_bin.c' object='libarchive/test/test-test_read_format_cpio_bin.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_bin.obj `if test -f 'libarchive/test/test_read_format_cpio_bin.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_bin.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_bin.c'; fi` - -libarchive/test/test-test_read_format_cpio_bin_Z.o: libarchive/test/test_read_format_cpio_bin_Z.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_bin_Z.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_Z.Tpo -c -o libarchive/test/test-test_read_format_cpio_bin_Z.o `test -f 'libarchive/test/test_read_format_cpio_bin_Z.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_bin_Z.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_Z.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_Z.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_bin_Z.c' object='libarchive/test/test-test_read_format_cpio_bin_Z.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_bin_Z.o `test -f 'libarchive/test/test_read_format_cpio_bin_Z.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_bin_Z.c - -libarchive/test/test-test_read_format_cpio_bin_Z.obj: libarchive/test/test_read_format_cpio_bin_Z.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_bin_Z.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_Z.Tpo -c -o libarchive/test/test-test_read_format_cpio_bin_Z.obj `if test -f 'libarchive/test/test_read_format_cpio_bin_Z.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_bin_Z.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_bin_Z.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_Z.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_Z.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_bin_Z.c' object='libarchive/test/test-test_read_format_cpio_bin_Z.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_bin_Z.obj `if test -f 'libarchive/test/test_read_format_cpio_bin_Z.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_bin_Z.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_bin_Z.c'; fi` - -libarchive/test/test-test_read_format_cpio_bin_be.o: libarchive/test/test_read_format_cpio_bin_be.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_bin_be.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_be.Tpo -c -o libarchive/test/test-test_read_format_cpio_bin_be.o `test -f 'libarchive/test/test_read_format_cpio_bin_be.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_bin_be.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_be.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_be.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_bin_be.c' object='libarchive/test/test-test_read_format_cpio_bin_be.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_bin_be.o `test -f 'libarchive/test/test_read_format_cpio_bin_be.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_bin_be.c - -libarchive/test/test-test_read_format_cpio_bin_be.obj: libarchive/test/test_read_format_cpio_bin_be.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_bin_be.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_be.Tpo -c -o libarchive/test/test-test_read_format_cpio_bin_be.obj `if test -f 'libarchive/test/test_read_format_cpio_bin_be.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_bin_be.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_bin_be.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_be.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_be.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_bin_be.c' object='libarchive/test/test-test_read_format_cpio_bin_be.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_bin_be.obj `if test -f 'libarchive/test/test_read_format_cpio_bin_be.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_bin_be.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_bin_be.c'; fi` - -libarchive/test/test-test_read_format_cpio_bin_bz2.o: libarchive/test/test_read_format_cpio_bin_bz2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_bin_bz2.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_bz2.Tpo -c -o libarchive/test/test-test_read_format_cpio_bin_bz2.o `test -f 'libarchive/test/test_read_format_cpio_bin_bz2.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_bin_bz2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_bz2.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_bz2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_bin_bz2.c' object='libarchive/test/test-test_read_format_cpio_bin_bz2.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_bin_bz2.o `test -f 'libarchive/test/test_read_format_cpio_bin_bz2.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_bin_bz2.c - -libarchive/test/test-test_read_format_cpio_bin_bz2.obj: libarchive/test/test_read_format_cpio_bin_bz2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_bin_bz2.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_bz2.Tpo -c -o libarchive/test/test-test_read_format_cpio_bin_bz2.obj `if test -f 'libarchive/test/test_read_format_cpio_bin_bz2.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_bin_bz2.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_bin_bz2.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_bz2.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_bz2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_bin_bz2.c' object='libarchive/test/test-test_read_format_cpio_bin_bz2.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_bin_bz2.obj `if test -f 'libarchive/test/test_read_format_cpio_bin_bz2.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_bin_bz2.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_bin_bz2.c'; fi` - -libarchive/test/test-test_read_format_cpio_bin_gz.o: libarchive/test/test_read_format_cpio_bin_gz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_bin_gz.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_gz.Tpo -c -o libarchive/test/test-test_read_format_cpio_bin_gz.o `test -f 'libarchive/test/test_read_format_cpio_bin_gz.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_bin_gz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_gz.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_gz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_bin_gz.c' object='libarchive/test/test-test_read_format_cpio_bin_gz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_bin_gz.o `test -f 'libarchive/test/test_read_format_cpio_bin_gz.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_bin_gz.c - -libarchive/test/test-test_read_format_cpio_bin_gz.obj: libarchive/test/test_read_format_cpio_bin_gz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_bin_gz.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_gz.Tpo -c -o libarchive/test/test-test_read_format_cpio_bin_gz.obj `if test -f 'libarchive/test/test_read_format_cpio_bin_gz.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_bin_gz.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_bin_gz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_gz.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_gz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_bin_gz.c' object='libarchive/test/test-test_read_format_cpio_bin_gz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_bin_gz.obj `if test -f 'libarchive/test/test_read_format_cpio_bin_gz.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_bin_gz.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_bin_gz.c'; fi` - -libarchive/test/test-test_read_format_cpio_bin_le.o: libarchive/test/test_read_format_cpio_bin_le.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_bin_le.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_le.Tpo -c -o libarchive/test/test-test_read_format_cpio_bin_le.o `test -f 'libarchive/test/test_read_format_cpio_bin_le.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_bin_le.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_le.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_le.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_bin_le.c' object='libarchive/test/test-test_read_format_cpio_bin_le.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_bin_le.o `test -f 'libarchive/test/test_read_format_cpio_bin_le.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_bin_le.c - -libarchive/test/test-test_read_format_cpio_bin_le.obj: libarchive/test/test_read_format_cpio_bin_le.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_bin_le.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_le.Tpo -c -o libarchive/test/test-test_read_format_cpio_bin_le.obj `if test -f 'libarchive/test/test_read_format_cpio_bin_le.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_bin_le.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_bin_le.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_le.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_le.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_bin_le.c' object='libarchive/test/test-test_read_format_cpio_bin_le.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_bin_le.obj `if test -f 'libarchive/test/test_read_format_cpio_bin_le.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_bin_le.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_bin_le.c'; fi` - -libarchive/test/test-test_read_format_cpio_bin_lzip.o: libarchive/test/test_read_format_cpio_bin_lzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_bin_lzip.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_lzip.Tpo -c -o libarchive/test/test-test_read_format_cpio_bin_lzip.o `test -f 'libarchive/test/test_read_format_cpio_bin_lzip.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_bin_lzip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_lzip.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_lzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_bin_lzip.c' object='libarchive/test/test-test_read_format_cpio_bin_lzip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_bin_lzip.o `test -f 'libarchive/test/test_read_format_cpio_bin_lzip.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_bin_lzip.c - -libarchive/test/test-test_read_format_cpio_bin_lzip.obj: libarchive/test/test_read_format_cpio_bin_lzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_bin_lzip.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_lzip.Tpo -c -o libarchive/test/test-test_read_format_cpio_bin_lzip.obj `if test -f 'libarchive/test/test_read_format_cpio_bin_lzip.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_bin_lzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_bin_lzip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_lzip.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_lzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_bin_lzip.c' object='libarchive/test/test-test_read_format_cpio_bin_lzip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_bin_lzip.obj `if test -f 'libarchive/test/test_read_format_cpio_bin_lzip.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_bin_lzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_bin_lzip.c'; fi` - -libarchive/test/test-test_read_format_cpio_bin_lzma.o: libarchive/test/test_read_format_cpio_bin_lzma.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_bin_lzma.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_lzma.Tpo -c -o libarchive/test/test-test_read_format_cpio_bin_lzma.o `test -f 'libarchive/test/test_read_format_cpio_bin_lzma.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_bin_lzma.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_lzma.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_lzma.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_bin_lzma.c' object='libarchive/test/test-test_read_format_cpio_bin_lzma.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_bin_lzma.o `test -f 'libarchive/test/test_read_format_cpio_bin_lzma.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_bin_lzma.c - -libarchive/test/test-test_read_format_cpio_bin_lzma.obj: libarchive/test/test_read_format_cpio_bin_lzma.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_bin_lzma.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_lzma.Tpo -c -o libarchive/test/test-test_read_format_cpio_bin_lzma.obj `if test -f 'libarchive/test/test_read_format_cpio_bin_lzma.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_bin_lzma.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_bin_lzma.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_lzma.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_lzma.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_bin_lzma.c' object='libarchive/test/test-test_read_format_cpio_bin_lzma.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_bin_lzma.obj `if test -f 'libarchive/test/test_read_format_cpio_bin_lzma.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_bin_lzma.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_bin_lzma.c'; fi` - -libarchive/test/test-test_read_format_cpio_bin_xz.o: libarchive/test/test_read_format_cpio_bin_xz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_bin_xz.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_xz.Tpo -c -o libarchive/test/test-test_read_format_cpio_bin_xz.o `test -f 'libarchive/test/test_read_format_cpio_bin_xz.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_bin_xz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_xz.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_xz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_bin_xz.c' object='libarchive/test/test-test_read_format_cpio_bin_xz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_bin_xz.o `test -f 'libarchive/test/test_read_format_cpio_bin_xz.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_bin_xz.c - -libarchive/test/test-test_read_format_cpio_bin_xz.obj: libarchive/test/test_read_format_cpio_bin_xz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_bin_xz.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_xz.Tpo -c -o libarchive/test/test-test_read_format_cpio_bin_xz.obj `if test -f 'libarchive/test/test_read_format_cpio_bin_xz.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_bin_xz.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_bin_xz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_xz.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_xz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_bin_xz.c' object='libarchive/test/test-test_read_format_cpio_bin_xz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_bin_xz.obj `if test -f 'libarchive/test/test_read_format_cpio_bin_xz.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_bin_xz.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_bin_xz.c'; fi` - -libarchive/test/test-test_read_format_cpio_filename.o: libarchive/test/test_read_format_cpio_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_filename.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_filename.Tpo -c -o libarchive/test/test-test_read_format_cpio_filename.o `test -f 'libarchive/test/test_read_format_cpio_filename.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_filename.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_filename.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_filename.c' object='libarchive/test/test-test_read_format_cpio_filename.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_filename.o `test -f 'libarchive/test/test_read_format_cpio_filename.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_filename.c - -libarchive/test/test-test_read_format_cpio_filename.obj: libarchive/test/test_read_format_cpio_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_filename.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_filename.Tpo -c -o libarchive/test/test-test_read_format_cpio_filename.obj `if test -f 'libarchive/test/test_read_format_cpio_filename.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_filename.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_filename.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_filename.c' object='libarchive/test/test-test_read_format_cpio_filename.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_filename.obj `if test -f 'libarchive/test/test_read_format_cpio_filename.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_filename.c'; fi` - -libarchive/test/test-test_read_format_cpio_odc.o: libarchive/test/test_read_format_cpio_odc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_odc.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_odc.Tpo -c -o libarchive/test/test-test_read_format_cpio_odc.o `test -f 'libarchive/test/test_read_format_cpio_odc.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_odc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_odc.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_odc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_odc.c' object='libarchive/test/test-test_read_format_cpio_odc.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_odc.o `test -f 'libarchive/test/test_read_format_cpio_odc.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_odc.c - -libarchive/test/test-test_read_format_cpio_odc.obj: libarchive/test/test_read_format_cpio_odc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_odc.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_odc.Tpo -c -o libarchive/test/test-test_read_format_cpio_odc.obj `if test -f 'libarchive/test/test_read_format_cpio_odc.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_odc.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_odc.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_odc.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_odc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_odc.c' object='libarchive/test/test-test_read_format_cpio_odc.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_odc.obj `if test -f 'libarchive/test/test_read_format_cpio_odc.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_odc.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_odc.c'; fi` - -libarchive/test/test-test_read_format_cpio_svr4_bzip2_rpm.o: libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_svr4_bzip2_rpm.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_bzip2_rpm.Tpo -c -o libarchive/test/test-test_read_format_cpio_svr4_bzip2_rpm.o `test -f 'libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_bzip2_rpm.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_bzip2_rpm.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c' object='libarchive/test/test-test_read_format_cpio_svr4_bzip2_rpm.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_svr4_bzip2_rpm.o `test -f 'libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c - -libarchive/test/test-test_read_format_cpio_svr4_bzip2_rpm.obj: libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_svr4_bzip2_rpm.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_bzip2_rpm.Tpo -c -o libarchive/test/test-test_read_format_cpio_svr4_bzip2_rpm.obj `if test -f 'libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_bzip2_rpm.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_bzip2_rpm.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c' object='libarchive/test/test-test_read_format_cpio_svr4_bzip2_rpm.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_svr4_bzip2_rpm.obj `if test -f 'libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c'; fi` - -libarchive/test/test-test_read_format_cpio_svr4_gzip.o: libarchive/test/test_read_format_cpio_svr4_gzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_svr4_gzip.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_gzip.Tpo -c -o libarchive/test/test-test_read_format_cpio_svr4_gzip.o `test -f 'libarchive/test/test_read_format_cpio_svr4_gzip.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_svr4_gzip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_gzip.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_gzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_svr4_gzip.c' object='libarchive/test/test-test_read_format_cpio_svr4_gzip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_svr4_gzip.o `test -f 'libarchive/test/test_read_format_cpio_svr4_gzip.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_svr4_gzip.c - -libarchive/test/test-test_read_format_cpio_svr4_gzip.obj: libarchive/test/test_read_format_cpio_svr4_gzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_svr4_gzip.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_gzip.Tpo -c -o libarchive/test/test-test_read_format_cpio_svr4_gzip.obj `if test -f 'libarchive/test/test_read_format_cpio_svr4_gzip.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_svr4_gzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_svr4_gzip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_gzip.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_gzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_svr4_gzip.c' object='libarchive/test/test-test_read_format_cpio_svr4_gzip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_svr4_gzip.obj `if test -f 'libarchive/test/test_read_format_cpio_svr4_gzip.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_svr4_gzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_svr4_gzip.c'; fi` - -libarchive/test/test-test_read_format_cpio_svr4_gzip_rpm.o: libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_svr4_gzip_rpm.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_gzip_rpm.Tpo -c -o libarchive/test/test-test_read_format_cpio_svr4_gzip_rpm.o `test -f 'libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_gzip_rpm.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_gzip_rpm.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c' object='libarchive/test/test-test_read_format_cpio_svr4_gzip_rpm.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_svr4_gzip_rpm.o `test -f 'libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c - -libarchive/test/test-test_read_format_cpio_svr4_gzip_rpm.obj: libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_svr4_gzip_rpm.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_gzip_rpm.Tpo -c -o libarchive/test/test-test_read_format_cpio_svr4_gzip_rpm.obj `if test -f 'libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_gzip_rpm.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_gzip_rpm.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c' object='libarchive/test/test-test_read_format_cpio_svr4_gzip_rpm.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_svr4_gzip_rpm.obj `if test -f 'libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c'; fi` - -libarchive/test/test-test_read_format_cpio_svr4c_Z.o: libarchive/test/test_read_format_cpio_svr4c_Z.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_svr4c_Z.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4c_Z.Tpo -c -o libarchive/test/test-test_read_format_cpio_svr4c_Z.o `test -f 'libarchive/test/test_read_format_cpio_svr4c_Z.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_svr4c_Z.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4c_Z.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4c_Z.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_svr4c_Z.c' object='libarchive/test/test-test_read_format_cpio_svr4c_Z.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_svr4c_Z.o `test -f 'libarchive/test/test_read_format_cpio_svr4c_Z.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_cpio_svr4c_Z.c - -libarchive/test/test-test_read_format_cpio_svr4c_Z.obj: libarchive/test/test_read_format_cpio_svr4c_Z.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_cpio_svr4c_Z.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4c_Z.Tpo -c -o libarchive/test/test-test_read_format_cpio_svr4c_Z.obj `if test -f 'libarchive/test/test_read_format_cpio_svr4c_Z.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_svr4c_Z.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_svr4c_Z.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4c_Z.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4c_Z.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_cpio_svr4c_Z.c' object='libarchive/test/test-test_read_format_cpio_svr4c_Z.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_cpio_svr4c_Z.obj `if test -f 'libarchive/test/test_read_format_cpio_svr4c_Z.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_cpio_svr4c_Z.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_cpio_svr4c_Z.c'; fi` - -libarchive/test/test-test_read_format_empty.o: libarchive/test/test_read_format_empty.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_empty.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_empty.Tpo -c -o libarchive/test/test-test_read_format_empty.o `test -f 'libarchive/test/test_read_format_empty.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_empty.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_empty.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_empty.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_empty.c' object='libarchive/test/test-test_read_format_empty.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_empty.o `test -f 'libarchive/test/test_read_format_empty.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_empty.c - -libarchive/test/test-test_read_format_empty.obj: libarchive/test/test_read_format_empty.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_empty.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_empty.Tpo -c -o libarchive/test/test-test_read_format_empty.obj `if test -f 'libarchive/test/test_read_format_empty.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_empty.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_empty.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_empty.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_empty.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_empty.c' object='libarchive/test/test-test_read_format_empty.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_empty.obj `if test -f 'libarchive/test/test_read_format_empty.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_empty.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_empty.c'; fi` - -libarchive/test/test-test_read_format_gtar_filename.o: libarchive/test/test_read_format_gtar_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_gtar_filename.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_gtar_filename.Tpo -c -o libarchive/test/test-test_read_format_gtar_filename.o `test -f 'libarchive/test/test_read_format_gtar_filename.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_gtar_filename.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_gtar_filename.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_gtar_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_gtar_filename.c' object='libarchive/test/test-test_read_format_gtar_filename.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_gtar_filename.o `test -f 'libarchive/test/test_read_format_gtar_filename.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_gtar_filename.c - -libarchive/test/test-test_read_format_gtar_filename.obj: libarchive/test/test_read_format_gtar_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_gtar_filename.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_gtar_filename.Tpo -c -o libarchive/test/test-test_read_format_gtar_filename.obj `if test -f 'libarchive/test/test_read_format_gtar_filename.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_gtar_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_gtar_filename.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_gtar_filename.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_gtar_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_gtar_filename.c' object='libarchive/test/test-test_read_format_gtar_filename.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_gtar_filename.obj `if test -f 'libarchive/test/test_read_format_gtar_filename.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_gtar_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_gtar_filename.c'; fi` - -libarchive/test/test-test_read_format_gtar_gz.o: libarchive/test/test_read_format_gtar_gz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_gtar_gz.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_gtar_gz.Tpo -c -o libarchive/test/test-test_read_format_gtar_gz.o `test -f 'libarchive/test/test_read_format_gtar_gz.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_gtar_gz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_gtar_gz.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_gtar_gz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_gtar_gz.c' object='libarchive/test/test-test_read_format_gtar_gz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_gtar_gz.o `test -f 'libarchive/test/test_read_format_gtar_gz.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_gtar_gz.c - -libarchive/test/test-test_read_format_gtar_gz.obj: libarchive/test/test_read_format_gtar_gz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_gtar_gz.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_gtar_gz.Tpo -c -o libarchive/test/test-test_read_format_gtar_gz.obj `if test -f 'libarchive/test/test_read_format_gtar_gz.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_gtar_gz.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_gtar_gz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_gtar_gz.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_gtar_gz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_gtar_gz.c' object='libarchive/test/test-test_read_format_gtar_gz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_gtar_gz.obj `if test -f 'libarchive/test/test_read_format_gtar_gz.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_gtar_gz.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_gtar_gz.c'; fi` - -libarchive/test/test-test_read_format_gtar_lzma.o: libarchive/test/test_read_format_gtar_lzma.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_gtar_lzma.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_gtar_lzma.Tpo -c -o libarchive/test/test-test_read_format_gtar_lzma.o `test -f 'libarchive/test/test_read_format_gtar_lzma.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_gtar_lzma.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_gtar_lzma.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_gtar_lzma.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_gtar_lzma.c' object='libarchive/test/test-test_read_format_gtar_lzma.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_gtar_lzma.o `test -f 'libarchive/test/test_read_format_gtar_lzma.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_gtar_lzma.c - -libarchive/test/test-test_read_format_gtar_lzma.obj: libarchive/test/test_read_format_gtar_lzma.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_gtar_lzma.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_gtar_lzma.Tpo -c -o libarchive/test/test-test_read_format_gtar_lzma.obj `if test -f 'libarchive/test/test_read_format_gtar_lzma.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_gtar_lzma.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_gtar_lzma.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_gtar_lzma.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_gtar_lzma.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_gtar_lzma.c' object='libarchive/test/test-test_read_format_gtar_lzma.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_gtar_lzma.obj `if test -f 'libarchive/test/test_read_format_gtar_lzma.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_gtar_lzma.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_gtar_lzma.c'; fi` - -libarchive/test/test-test_read_format_gtar_sparse.o: libarchive/test/test_read_format_gtar_sparse.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_gtar_sparse.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_gtar_sparse.Tpo -c -o libarchive/test/test-test_read_format_gtar_sparse.o `test -f 'libarchive/test/test_read_format_gtar_sparse.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_gtar_sparse.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_gtar_sparse.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_gtar_sparse.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_gtar_sparse.c' object='libarchive/test/test-test_read_format_gtar_sparse.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_gtar_sparse.o `test -f 'libarchive/test/test_read_format_gtar_sparse.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_gtar_sparse.c - -libarchive/test/test-test_read_format_gtar_sparse.obj: libarchive/test/test_read_format_gtar_sparse.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_gtar_sparse.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_gtar_sparse.Tpo -c -o libarchive/test/test-test_read_format_gtar_sparse.obj `if test -f 'libarchive/test/test_read_format_gtar_sparse.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_gtar_sparse.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_gtar_sparse.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_gtar_sparse.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_gtar_sparse.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_gtar_sparse.c' object='libarchive/test/test-test_read_format_gtar_sparse.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_gtar_sparse.obj `if test -f 'libarchive/test/test_read_format_gtar_sparse.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_gtar_sparse.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_gtar_sparse.c'; fi` - -libarchive/test/test-test_read_format_gtar_sparse_skip_entry.o: libarchive/test/test_read_format_gtar_sparse_skip_entry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_gtar_sparse_skip_entry.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_gtar_sparse_skip_entry.Tpo -c -o libarchive/test/test-test_read_format_gtar_sparse_skip_entry.o `test -f 'libarchive/test/test_read_format_gtar_sparse_skip_entry.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_gtar_sparse_skip_entry.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_gtar_sparse_skip_entry.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_gtar_sparse_skip_entry.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_gtar_sparse_skip_entry.c' object='libarchive/test/test-test_read_format_gtar_sparse_skip_entry.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_gtar_sparse_skip_entry.o `test -f 'libarchive/test/test_read_format_gtar_sparse_skip_entry.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_gtar_sparse_skip_entry.c - -libarchive/test/test-test_read_format_gtar_sparse_skip_entry.obj: libarchive/test/test_read_format_gtar_sparse_skip_entry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_gtar_sparse_skip_entry.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_gtar_sparse_skip_entry.Tpo -c -o libarchive/test/test-test_read_format_gtar_sparse_skip_entry.obj `if test -f 'libarchive/test/test_read_format_gtar_sparse_skip_entry.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_gtar_sparse_skip_entry.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_gtar_sparse_skip_entry.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_gtar_sparse_skip_entry.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_gtar_sparse_skip_entry.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_gtar_sparse_skip_entry.c' object='libarchive/test/test-test_read_format_gtar_sparse_skip_entry.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_gtar_sparse_skip_entry.obj `if test -f 'libarchive/test/test_read_format_gtar_sparse_skip_entry.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_gtar_sparse_skip_entry.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_gtar_sparse_skip_entry.c'; fi` - -libarchive/test/test-test_read_format_iso_Z.o: libarchive/test/test_read_format_iso_Z.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_iso_Z.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_iso_Z.Tpo -c -o libarchive/test/test-test_read_format_iso_Z.o `test -f 'libarchive/test/test_read_format_iso_Z.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_iso_Z.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_iso_Z.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_iso_Z.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_iso_Z.c' object='libarchive/test/test-test_read_format_iso_Z.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_iso_Z.o `test -f 'libarchive/test/test_read_format_iso_Z.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_iso_Z.c - -libarchive/test/test-test_read_format_iso_Z.obj: libarchive/test/test_read_format_iso_Z.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_iso_Z.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_iso_Z.Tpo -c -o libarchive/test/test-test_read_format_iso_Z.obj `if test -f 'libarchive/test/test_read_format_iso_Z.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_iso_Z.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_iso_Z.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_iso_Z.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_iso_Z.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_iso_Z.c' object='libarchive/test/test-test_read_format_iso_Z.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_iso_Z.obj `if test -f 'libarchive/test/test_read_format_iso_Z.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_iso_Z.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_iso_Z.c'; fi` - -libarchive/test/test-test_read_format_iso_multi_extent.o: libarchive/test/test_read_format_iso_multi_extent.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_iso_multi_extent.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_iso_multi_extent.Tpo -c -o libarchive/test/test-test_read_format_iso_multi_extent.o `test -f 'libarchive/test/test_read_format_iso_multi_extent.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_iso_multi_extent.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_iso_multi_extent.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_iso_multi_extent.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_iso_multi_extent.c' object='libarchive/test/test-test_read_format_iso_multi_extent.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_iso_multi_extent.o `test -f 'libarchive/test/test_read_format_iso_multi_extent.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_iso_multi_extent.c - -libarchive/test/test-test_read_format_iso_multi_extent.obj: libarchive/test/test_read_format_iso_multi_extent.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_iso_multi_extent.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_iso_multi_extent.Tpo -c -o libarchive/test/test-test_read_format_iso_multi_extent.obj `if test -f 'libarchive/test/test_read_format_iso_multi_extent.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_iso_multi_extent.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_iso_multi_extent.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_iso_multi_extent.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_iso_multi_extent.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_iso_multi_extent.c' object='libarchive/test/test-test_read_format_iso_multi_extent.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_iso_multi_extent.obj `if test -f 'libarchive/test/test_read_format_iso_multi_extent.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_iso_multi_extent.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_iso_multi_extent.c'; fi` - -libarchive/test/test-test_read_format_iso_xorriso.o: libarchive/test/test_read_format_iso_xorriso.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_iso_xorriso.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_iso_xorriso.Tpo -c -o libarchive/test/test-test_read_format_iso_xorriso.o `test -f 'libarchive/test/test_read_format_iso_xorriso.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_iso_xorriso.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_iso_xorriso.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_iso_xorriso.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_iso_xorriso.c' object='libarchive/test/test-test_read_format_iso_xorriso.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_iso_xorriso.o `test -f 'libarchive/test/test_read_format_iso_xorriso.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_iso_xorriso.c - -libarchive/test/test-test_read_format_iso_xorriso.obj: libarchive/test/test_read_format_iso_xorriso.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_iso_xorriso.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_iso_xorriso.Tpo -c -o libarchive/test/test-test_read_format_iso_xorriso.obj `if test -f 'libarchive/test/test_read_format_iso_xorriso.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_iso_xorriso.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_iso_xorriso.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_iso_xorriso.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_iso_xorriso.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_iso_xorriso.c' object='libarchive/test/test-test_read_format_iso_xorriso.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_iso_xorriso.obj `if test -f 'libarchive/test/test_read_format_iso_xorriso.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_iso_xorriso.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_iso_xorriso.c'; fi` - -libarchive/test/test-test_read_format_isojoliet_bz2.o: libarchive/test/test_read_format_isojoliet_bz2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_isojoliet_bz2.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_bz2.Tpo -c -o libarchive/test/test-test_read_format_isojoliet_bz2.o `test -f 'libarchive/test/test_read_format_isojoliet_bz2.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_isojoliet_bz2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_bz2.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_bz2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_isojoliet_bz2.c' object='libarchive/test/test-test_read_format_isojoliet_bz2.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_isojoliet_bz2.o `test -f 'libarchive/test/test_read_format_isojoliet_bz2.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_isojoliet_bz2.c - -libarchive/test/test-test_read_format_isojoliet_bz2.obj: libarchive/test/test_read_format_isojoliet_bz2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_isojoliet_bz2.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_bz2.Tpo -c -o libarchive/test/test-test_read_format_isojoliet_bz2.obj `if test -f 'libarchive/test/test_read_format_isojoliet_bz2.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_isojoliet_bz2.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_isojoliet_bz2.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_bz2.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_bz2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_isojoliet_bz2.c' object='libarchive/test/test-test_read_format_isojoliet_bz2.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_isojoliet_bz2.obj `if test -f 'libarchive/test/test_read_format_isojoliet_bz2.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_isojoliet_bz2.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_isojoliet_bz2.c'; fi` - -libarchive/test/test-test_read_format_isojoliet_long.o: libarchive/test/test_read_format_isojoliet_long.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_isojoliet_long.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_long.Tpo -c -o libarchive/test/test-test_read_format_isojoliet_long.o `test -f 'libarchive/test/test_read_format_isojoliet_long.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_isojoliet_long.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_long.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_long.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_isojoliet_long.c' object='libarchive/test/test-test_read_format_isojoliet_long.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_isojoliet_long.o `test -f 'libarchive/test/test_read_format_isojoliet_long.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_isojoliet_long.c - -libarchive/test/test-test_read_format_isojoliet_long.obj: libarchive/test/test_read_format_isojoliet_long.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_isojoliet_long.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_long.Tpo -c -o libarchive/test/test-test_read_format_isojoliet_long.obj `if test -f 'libarchive/test/test_read_format_isojoliet_long.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_isojoliet_long.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_isojoliet_long.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_long.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_long.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_isojoliet_long.c' object='libarchive/test/test-test_read_format_isojoliet_long.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_isojoliet_long.obj `if test -f 'libarchive/test/test_read_format_isojoliet_long.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_isojoliet_long.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_isojoliet_long.c'; fi` - -libarchive/test/test-test_read_format_isojoliet_rr.o: libarchive/test/test_read_format_isojoliet_rr.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_isojoliet_rr.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_rr.Tpo -c -o libarchive/test/test-test_read_format_isojoliet_rr.o `test -f 'libarchive/test/test_read_format_isojoliet_rr.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_isojoliet_rr.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_rr.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_rr.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_isojoliet_rr.c' object='libarchive/test/test-test_read_format_isojoliet_rr.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_isojoliet_rr.o `test -f 'libarchive/test/test_read_format_isojoliet_rr.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_isojoliet_rr.c - -libarchive/test/test-test_read_format_isojoliet_rr.obj: libarchive/test/test_read_format_isojoliet_rr.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_isojoliet_rr.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_rr.Tpo -c -o libarchive/test/test-test_read_format_isojoliet_rr.obj `if test -f 'libarchive/test/test_read_format_isojoliet_rr.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_isojoliet_rr.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_isojoliet_rr.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_rr.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_rr.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_isojoliet_rr.c' object='libarchive/test/test-test_read_format_isojoliet_rr.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_isojoliet_rr.obj `if test -f 'libarchive/test/test_read_format_isojoliet_rr.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_isojoliet_rr.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_isojoliet_rr.c'; fi` - -libarchive/test/test-test_read_format_isojoliet_versioned.o: libarchive/test/test_read_format_isojoliet_versioned.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_isojoliet_versioned.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_versioned.Tpo -c -o libarchive/test/test-test_read_format_isojoliet_versioned.o `test -f 'libarchive/test/test_read_format_isojoliet_versioned.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_isojoliet_versioned.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_versioned.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_versioned.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_isojoliet_versioned.c' object='libarchive/test/test-test_read_format_isojoliet_versioned.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_isojoliet_versioned.o `test -f 'libarchive/test/test_read_format_isojoliet_versioned.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_isojoliet_versioned.c - -libarchive/test/test-test_read_format_isojoliet_versioned.obj: libarchive/test/test_read_format_isojoliet_versioned.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_isojoliet_versioned.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_versioned.Tpo -c -o libarchive/test/test-test_read_format_isojoliet_versioned.obj `if test -f 'libarchive/test/test_read_format_isojoliet_versioned.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_isojoliet_versioned.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_isojoliet_versioned.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_versioned.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_versioned.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_isojoliet_versioned.c' object='libarchive/test/test-test_read_format_isojoliet_versioned.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_isojoliet_versioned.obj `if test -f 'libarchive/test/test_read_format_isojoliet_versioned.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_isojoliet_versioned.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_isojoliet_versioned.c'; fi` - -libarchive/test/test-test_read_format_isorr_bz2.o: libarchive/test/test_read_format_isorr_bz2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_isorr_bz2.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_isorr_bz2.Tpo -c -o libarchive/test/test-test_read_format_isorr_bz2.o `test -f 'libarchive/test/test_read_format_isorr_bz2.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_isorr_bz2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_isorr_bz2.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_isorr_bz2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_isorr_bz2.c' object='libarchive/test/test-test_read_format_isorr_bz2.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_isorr_bz2.o `test -f 'libarchive/test/test_read_format_isorr_bz2.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_isorr_bz2.c - -libarchive/test/test-test_read_format_isorr_bz2.obj: libarchive/test/test_read_format_isorr_bz2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_isorr_bz2.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_isorr_bz2.Tpo -c -o libarchive/test/test-test_read_format_isorr_bz2.obj `if test -f 'libarchive/test/test_read_format_isorr_bz2.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_isorr_bz2.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_isorr_bz2.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_isorr_bz2.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_isorr_bz2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_isorr_bz2.c' object='libarchive/test/test-test_read_format_isorr_bz2.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_isorr_bz2.obj `if test -f 'libarchive/test/test_read_format_isorr_bz2.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_isorr_bz2.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_isorr_bz2.c'; fi` - -libarchive/test/test-test_read_format_isorr_ce.o: libarchive/test/test_read_format_isorr_ce.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_isorr_ce.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_isorr_ce.Tpo -c -o libarchive/test/test-test_read_format_isorr_ce.o `test -f 'libarchive/test/test_read_format_isorr_ce.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_isorr_ce.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_isorr_ce.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_isorr_ce.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_isorr_ce.c' object='libarchive/test/test-test_read_format_isorr_ce.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_isorr_ce.o `test -f 'libarchive/test/test_read_format_isorr_ce.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_isorr_ce.c - -libarchive/test/test-test_read_format_isorr_ce.obj: libarchive/test/test_read_format_isorr_ce.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_isorr_ce.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_isorr_ce.Tpo -c -o libarchive/test/test-test_read_format_isorr_ce.obj `if test -f 'libarchive/test/test_read_format_isorr_ce.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_isorr_ce.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_isorr_ce.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_isorr_ce.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_isorr_ce.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_isorr_ce.c' object='libarchive/test/test-test_read_format_isorr_ce.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_isorr_ce.obj `if test -f 'libarchive/test/test_read_format_isorr_ce.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_isorr_ce.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_isorr_ce.c'; fi` - -libarchive/test/test-test_read_format_isorr_new_bz2.o: libarchive/test/test_read_format_isorr_new_bz2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_isorr_new_bz2.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_isorr_new_bz2.Tpo -c -o libarchive/test/test-test_read_format_isorr_new_bz2.o `test -f 'libarchive/test/test_read_format_isorr_new_bz2.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_isorr_new_bz2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_isorr_new_bz2.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_isorr_new_bz2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_isorr_new_bz2.c' object='libarchive/test/test-test_read_format_isorr_new_bz2.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_isorr_new_bz2.o `test -f 'libarchive/test/test_read_format_isorr_new_bz2.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_isorr_new_bz2.c - -libarchive/test/test-test_read_format_isorr_new_bz2.obj: libarchive/test/test_read_format_isorr_new_bz2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_isorr_new_bz2.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_isorr_new_bz2.Tpo -c -o libarchive/test/test-test_read_format_isorr_new_bz2.obj `if test -f 'libarchive/test/test_read_format_isorr_new_bz2.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_isorr_new_bz2.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_isorr_new_bz2.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_isorr_new_bz2.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_isorr_new_bz2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_isorr_new_bz2.c' object='libarchive/test/test-test_read_format_isorr_new_bz2.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_isorr_new_bz2.obj `if test -f 'libarchive/test/test_read_format_isorr_new_bz2.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_isorr_new_bz2.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_isorr_new_bz2.c'; fi` - -libarchive/test/test-test_read_format_isorr_rr_moved.o: libarchive/test/test_read_format_isorr_rr_moved.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_isorr_rr_moved.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_isorr_rr_moved.Tpo -c -o libarchive/test/test-test_read_format_isorr_rr_moved.o `test -f 'libarchive/test/test_read_format_isorr_rr_moved.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_isorr_rr_moved.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_isorr_rr_moved.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_isorr_rr_moved.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_isorr_rr_moved.c' object='libarchive/test/test-test_read_format_isorr_rr_moved.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_isorr_rr_moved.o `test -f 'libarchive/test/test_read_format_isorr_rr_moved.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_isorr_rr_moved.c - -libarchive/test/test-test_read_format_isorr_rr_moved.obj: libarchive/test/test_read_format_isorr_rr_moved.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_isorr_rr_moved.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_isorr_rr_moved.Tpo -c -o libarchive/test/test-test_read_format_isorr_rr_moved.obj `if test -f 'libarchive/test/test_read_format_isorr_rr_moved.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_isorr_rr_moved.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_isorr_rr_moved.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_isorr_rr_moved.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_isorr_rr_moved.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_isorr_rr_moved.c' object='libarchive/test/test-test_read_format_isorr_rr_moved.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_isorr_rr_moved.obj `if test -f 'libarchive/test/test_read_format_isorr_rr_moved.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_isorr_rr_moved.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_isorr_rr_moved.c'; fi` - -libarchive/test/test-test_read_format_isozisofs_bz2.o: libarchive/test/test_read_format_isozisofs_bz2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_isozisofs_bz2.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_isozisofs_bz2.Tpo -c -o libarchive/test/test-test_read_format_isozisofs_bz2.o `test -f 'libarchive/test/test_read_format_isozisofs_bz2.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_isozisofs_bz2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_isozisofs_bz2.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_isozisofs_bz2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_isozisofs_bz2.c' object='libarchive/test/test-test_read_format_isozisofs_bz2.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_isozisofs_bz2.o `test -f 'libarchive/test/test_read_format_isozisofs_bz2.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_isozisofs_bz2.c - -libarchive/test/test-test_read_format_isozisofs_bz2.obj: libarchive/test/test_read_format_isozisofs_bz2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_isozisofs_bz2.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_isozisofs_bz2.Tpo -c -o libarchive/test/test-test_read_format_isozisofs_bz2.obj `if test -f 'libarchive/test/test_read_format_isozisofs_bz2.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_isozisofs_bz2.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_isozisofs_bz2.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_isozisofs_bz2.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_isozisofs_bz2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_isozisofs_bz2.c' object='libarchive/test/test-test_read_format_isozisofs_bz2.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_isozisofs_bz2.obj `if test -f 'libarchive/test/test_read_format_isozisofs_bz2.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_isozisofs_bz2.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_isozisofs_bz2.c'; fi` - -libarchive/test/test-test_read_format_lha.o: libarchive/test/test_read_format_lha.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_lha.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_lha.Tpo -c -o libarchive/test/test-test_read_format_lha.o `test -f 'libarchive/test/test_read_format_lha.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_lha.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_lha.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_lha.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_lha.c' object='libarchive/test/test-test_read_format_lha.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_lha.o `test -f 'libarchive/test/test_read_format_lha.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_lha.c - -libarchive/test/test-test_read_format_lha.obj: libarchive/test/test_read_format_lha.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_lha.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_lha.Tpo -c -o libarchive/test/test-test_read_format_lha.obj `if test -f 'libarchive/test/test_read_format_lha.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_lha.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_lha.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_lha.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_lha.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_lha.c' object='libarchive/test/test-test_read_format_lha.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_lha.obj `if test -f 'libarchive/test/test_read_format_lha.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_lha.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_lha.c'; fi` - -libarchive/test/test-test_read_format_lha_bugfix_0.o: libarchive/test/test_read_format_lha_bugfix_0.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_lha_bugfix_0.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_lha_bugfix_0.Tpo -c -o libarchive/test/test-test_read_format_lha_bugfix_0.o `test -f 'libarchive/test/test_read_format_lha_bugfix_0.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_lha_bugfix_0.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_lha_bugfix_0.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_lha_bugfix_0.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_lha_bugfix_0.c' object='libarchive/test/test-test_read_format_lha_bugfix_0.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_lha_bugfix_0.o `test -f 'libarchive/test/test_read_format_lha_bugfix_0.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_lha_bugfix_0.c - -libarchive/test/test-test_read_format_lha_bugfix_0.obj: libarchive/test/test_read_format_lha_bugfix_0.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_lha_bugfix_0.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_lha_bugfix_0.Tpo -c -o libarchive/test/test-test_read_format_lha_bugfix_0.obj `if test -f 'libarchive/test/test_read_format_lha_bugfix_0.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_lha_bugfix_0.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_lha_bugfix_0.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_lha_bugfix_0.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_lha_bugfix_0.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_lha_bugfix_0.c' object='libarchive/test/test-test_read_format_lha_bugfix_0.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_lha_bugfix_0.obj `if test -f 'libarchive/test/test_read_format_lha_bugfix_0.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_lha_bugfix_0.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_lha_bugfix_0.c'; fi` - -libarchive/test/test-test_read_format_lha_filename.o: libarchive/test/test_read_format_lha_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_lha_filename.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_lha_filename.Tpo -c -o libarchive/test/test-test_read_format_lha_filename.o `test -f 'libarchive/test/test_read_format_lha_filename.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_lha_filename.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_lha_filename.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_lha_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_lha_filename.c' object='libarchive/test/test-test_read_format_lha_filename.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_lha_filename.o `test -f 'libarchive/test/test_read_format_lha_filename.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_lha_filename.c - -libarchive/test/test-test_read_format_lha_filename.obj: libarchive/test/test_read_format_lha_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_lha_filename.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_lha_filename.Tpo -c -o libarchive/test/test-test_read_format_lha_filename.obj `if test -f 'libarchive/test/test_read_format_lha_filename.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_lha_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_lha_filename.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_lha_filename.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_lha_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_lha_filename.c' object='libarchive/test/test-test_read_format_lha_filename.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_lha_filename.obj `if test -f 'libarchive/test/test_read_format_lha_filename.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_lha_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_lha_filename.c'; fi` - -libarchive/test/test-test_read_format_lha_filename_utf16.o: libarchive/test/test_read_format_lha_filename_utf16.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_lha_filename_utf16.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_lha_filename_utf16.Tpo -c -o libarchive/test/test-test_read_format_lha_filename_utf16.o `test -f 'libarchive/test/test_read_format_lha_filename_utf16.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_lha_filename_utf16.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_lha_filename_utf16.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_lha_filename_utf16.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_lha_filename_utf16.c' object='libarchive/test/test-test_read_format_lha_filename_utf16.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_lha_filename_utf16.o `test -f 'libarchive/test/test_read_format_lha_filename_utf16.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_lha_filename_utf16.c - -libarchive/test/test-test_read_format_lha_filename_utf16.obj: libarchive/test/test_read_format_lha_filename_utf16.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_lha_filename_utf16.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_lha_filename_utf16.Tpo -c -o libarchive/test/test-test_read_format_lha_filename_utf16.obj `if test -f 'libarchive/test/test_read_format_lha_filename_utf16.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_lha_filename_utf16.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_lha_filename_utf16.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_lha_filename_utf16.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_lha_filename_utf16.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_lha_filename_utf16.c' object='libarchive/test/test-test_read_format_lha_filename_utf16.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_lha_filename_utf16.obj `if test -f 'libarchive/test/test_read_format_lha_filename_utf16.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_lha_filename_utf16.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_lha_filename_utf16.c'; fi` - -libarchive/test/test-test_read_format_mtree.o: libarchive/test/test_read_format_mtree.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_mtree.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_mtree.Tpo -c -o libarchive/test/test-test_read_format_mtree.o `test -f 'libarchive/test/test_read_format_mtree.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_mtree.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_mtree.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_mtree.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_mtree.c' object='libarchive/test/test-test_read_format_mtree.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_mtree.o `test -f 'libarchive/test/test_read_format_mtree.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_mtree.c - -libarchive/test/test-test_read_format_mtree.obj: libarchive/test/test_read_format_mtree.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_mtree.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_mtree.Tpo -c -o libarchive/test/test-test_read_format_mtree.obj `if test -f 'libarchive/test/test_read_format_mtree.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_mtree.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_mtree.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_mtree.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_mtree.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_mtree.c' object='libarchive/test/test-test_read_format_mtree.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_mtree.obj `if test -f 'libarchive/test/test_read_format_mtree.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_mtree.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_mtree.c'; fi` - -libarchive/test/test-test_read_format_mtree_crash747.o: libarchive/test/test_read_format_mtree_crash747.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_mtree_crash747.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_mtree_crash747.Tpo -c -o libarchive/test/test-test_read_format_mtree_crash747.o `test -f 'libarchive/test/test_read_format_mtree_crash747.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_mtree_crash747.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_mtree_crash747.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_mtree_crash747.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_mtree_crash747.c' object='libarchive/test/test-test_read_format_mtree_crash747.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_mtree_crash747.o `test -f 'libarchive/test/test_read_format_mtree_crash747.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_mtree_crash747.c - -libarchive/test/test-test_read_format_mtree_crash747.obj: libarchive/test/test_read_format_mtree_crash747.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_mtree_crash747.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_mtree_crash747.Tpo -c -o libarchive/test/test-test_read_format_mtree_crash747.obj `if test -f 'libarchive/test/test_read_format_mtree_crash747.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_mtree_crash747.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_mtree_crash747.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_mtree_crash747.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_mtree_crash747.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_mtree_crash747.c' object='libarchive/test/test-test_read_format_mtree_crash747.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_mtree_crash747.obj `if test -f 'libarchive/test/test_read_format_mtree_crash747.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_mtree_crash747.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_mtree_crash747.c'; fi` - -libarchive/test/test-test_read_format_pax_bz2.o: libarchive/test/test_read_format_pax_bz2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_pax_bz2.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_pax_bz2.Tpo -c -o libarchive/test/test-test_read_format_pax_bz2.o `test -f 'libarchive/test/test_read_format_pax_bz2.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_pax_bz2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_pax_bz2.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_pax_bz2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_pax_bz2.c' object='libarchive/test/test-test_read_format_pax_bz2.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_pax_bz2.o `test -f 'libarchive/test/test_read_format_pax_bz2.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_pax_bz2.c - -libarchive/test/test-test_read_format_pax_bz2.obj: libarchive/test/test_read_format_pax_bz2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_pax_bz2.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_pax_bz2.Tpo -c -o libarchive/test/test-test_read_format_pax_bz2.obj `if test -f 'libarchive/test/test_read_format_pax_bz2.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_pax_bz2.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_pax_bz2.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_pax_bz2.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_pax_bz2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_pax_bz2.c' object='libarchive/test/test-test_read_format_pax_bz2.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_pax_bz2.obj `if test -f 'libarchive/test/test_read_format_pax_bz2.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_pax_bz2.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_pax_bz2.c'; fi` - -libarchive/test/test-test_read_format_rar.o: libarchive/test/test_read_format_rar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_rar.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_rar.Tpo -c -o libarchive/test/test-test_read_format_rar.o `test -f 'libarchive/test/test_read_format_rar.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_rar.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_rar.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_rar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_rar.c' object='libarchive/test/test-test_read_format_rar.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_rar.o `test -f 'libarchive/test/test_read_format_rar.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_rar.c - -libarchive/test/test-test_read_format_rar.obj: libarchive/test/test_read_format_rar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_rar.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_rar.Tpo -c -o libarchive/test/test-test_read_format_rar.obj `if test -f 'libarchive/test/test_read_format_rar.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_rar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_rar.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_rar.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_rar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_rar.c' object='libarchive/test/test-test_read_format_rar.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_rar.obj `if test -f 'libarchive/test/test_read_format_rar.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_rar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_rar.c'; fi` - -libarchive/test/test-test_read_format_rar_encryption_data.o: libarchive/test/test_read_format_rar_encryption_data.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_rar_encryption_data.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_data.Tpo -c -o libarchive/test/test-test_read_format_rar_encryption_data.o `test -f 'libarchive/test/test_read_format_rar_encryption_data.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_rar_encryption_data.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_data.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_data.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_rar_encryption_data.c' object='libarchive/test/test-test_read_format_rar_encryption_data.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_rar_encryption_data.o `test -f 'libarchive/test/test_read_format_rar_encryption_data.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_rar_encryption_data.c - -libarchive/test/test-test_read_format_rar_encryption_data.obj: libarchive/test/test_read_format_rar_encryption_data.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_rar_encryption_data.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_data.Tpo -c -o libarchive/test/test-test_read_format_rar_encryption_data.obj `if test -f 'libarchive/test/test_read_format_rar_encryption_data.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_rar_encryption_data.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_rar_encryption_data.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_data.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_data.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_rar_encryption_data.c' object='libarchive/test/test-test_read_format_rar_encryption_data.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_rar_encryption_data.obj `if test -f 'libarchive/test/test_read_format_rar_encryption_data.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_rar_encryption_data.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_rar_encryption_data.c'; fi` - -libarchive/test/test-test_read_format_rar_encryption_partially.o: libarchive/test/test_read_format_rar_encryption_partially.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_rar_encryption_partially.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_partially.Tpo -c -o libarchive/test/test-test_read_format_rar_encryption_partially.o `test -f 'libarchive/test/test_read_format_rar_encryption_partially.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_rar_encryption_partially.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_partially.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_partially.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_rar_encryption_partially.c' object='libarchive/test/test-test_read_format_rar_encryption_partially.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_rar_encryption_partially.o `test -f 'libarchive/test/test_read_format_rar_encryption_partially.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_rar_encryption_partially.c - -libarchive/test/test-test_read_format_rar_encryption_partially.obj: libarchive/test/test_read_format_rar_encryption_partially.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_rar_encryption_partially.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_partially.Tpo -c -o libarchive/test/test-test_read_format_rar_encryption_partially.obj `if test -f 'libarchive/test/test_read_format_rar_encryption_partially.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_rar_encryption_partially.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_rar_encryption_partially.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_partially.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_partially.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_rar_encryption_partially.c' object='libarchive/test/test-test_read_format_rar_encryption_partially.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_rar_encryption_partially.obj `if test -f 'libarchive/test/test_read_format_rar_encryption_partially.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_rar_encryption_partially.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_rar_encryption_partially.c'; fi` - -libarchive/test/test-test_read_format_rar_encryption_header.o: libarchive/test/test_read_format_rar_encryption_header.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_rar_encryption_header.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_header.Tpo -c -o libarchive/test/test-test_read_format_rar_encryption_header.o `test -f 'libarchive/test/test_read_format_rar_encryption_header.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_rar_encryption_header.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_header.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_header.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_rar_encryption_header.c' object='libarchive/test/test-test_read_format_rar_encryption_header.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_rar_encryption_header.o `test -f 'libarchive/test/test_read_format_rar_encryption_header.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_rar_encryption_header.c - -libarchive/test/test-test_read_format_rar_encryption_header.obj: libarchive/test/test_read_format_rar_encryption_header.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_rar_encryption_header.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_header.Tpo -c -o libarchive/test/test-test_read_format_rar_encryption_header.obj `if test -f 'libarchive/test/test_read_format_rar_encryption_header.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_rar_encryption_header.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_rar_encryption_header.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_header.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_header.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_rar_encryption_header.c' object='libarchive/test/test-test_read_format_rar_encryption_header.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_rar_encryption_header.obj `if test -f 'libarchive/test/test_read_format_rar_encryption_header.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_rar_encryption_header.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_rar_encryption_header.c'; fi` - -libarchive/test/test-test_read_format_rar_filter.o: libarchive/test/test_read_format_rar_filter.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_rar_filter.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_rar_filter.Tpo -c -o libarchive/test/test-test_read_format_rar_filter.o `test -f 'libarchive/test/test_read_format_rar_filter.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_rar_filter.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_rar_filter.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_rar_filter.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_rar_filter.c' object='libarchive/test/test-test_read_format_rar_filter.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_rar_filter.o `test -f 'libarchive/test/test_read_format_rar_filter.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_rar_filter.c - -libarchive/test/test-test_read_format_rar_filter.obj: libarchive/test/test_read_format_rar_filter.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_rar_filter.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_rar_filter.Tpo -c -o libarchive/test/test-test_read_format_rar_filter.obj `if test -f 'libarchive/test/test_read_format_rar_filter.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_rar_filter.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_rar_filter.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_rar_filter.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_rar_filter.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_rar_filter.c' object='libarchive/test/test-test_read_format_rar_filter.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_rar_filter.obj `if test -f 'libarchive/test/test_read_format_rar_filter.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_rar_filter.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_rar_filter.c'; fi` - -libarchive/test/test-test_read_format_rar_invalid1.o: libarchive/test/test_read_format_rar_invalid1.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_rar_invalid1.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_rar_invalid1.Tpo -c -o libarchive/test/test-test_read_format_rar_invalid1.o `test -f 'libarchive/test/test_read_format_rar_invalid1.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_rar_invalid1.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_rar_invalid1.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_rar_invalid1.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_rar_invalid1.c' object='libarchive/test/test-test_read_format_rar_invalid1.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_rar_invalid1.o `test -f 'libarchive/test/test_read_format_rar_invalid1.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_rar_invalid1.c - -libarchive/test/test-test_read_format_rar_invalid1.obj: libarchive/test/test_read_format_rar_invalid1.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_rar_invalid1.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_rar_invalid1.Tpo -c -o libarchive/test/test-test_read_format_rar_invalid1.obj `if test -f 'libarchive/test/test_read_format_rar_invalid1.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_rar_invalid1.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_rar_invalid1.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_rar_invalid1.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_rar_invalid1.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_rar_invalid1.c' object='libarchive/test/test-test_read_format_rar_invalid1.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_rar_invalid1.obj `if test -f 'libarchive/test/test_read_format_rar_invalid1.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_rar_invalid1.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_rar_invalid1.c'; fi` - -libarchive/test/test-test_read_format_rar5.o: libarchive/test/test_read_format_rar5.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_rar5.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_rar5.Tpo -c -o libarchive/test/test-test_read_format_rar5.o `test -f 'libarchive/test/test_read_format_rar5.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_rar5.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_rar5.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_rar5.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_rar5.c' object='libarchive/test/test-test_read_format_rar5.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_rar5.o `test -f 'libarchive/test/test_read_format_rar5.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_rar5.c - -libarchive/test/test-test_read_format_rar5.obj: libarchive/test/test_read_format_rar5.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_rar5.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_rar5.Tpo -c -o libarchive/test/test-test_read_format_rar5.obj `if test -f 'libarchive/test/test_read_format_rar5.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_rar5.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_rar5.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_rar5.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_rar5.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_rar5.c' object='libarchive/test/test-test_read_format_rar5.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_rar5.obj `if test -f 'libarchive/test/test_read_format_rar5.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_rar5.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_rar5.c'; fi` - -libarchive/test/test-test_read_format_raw.o: libarchive/test/test_read_format_raw.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_raw.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_raw.Tpo -c -o libarchive/test/test-test_read_format_raw.o `test -f 'libarchive/test/test_read_format_raw.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_raw.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_raw.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_raw.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_raw.c' object='libarchive/test/test-test_read_format_raw.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_raw.o `test -f 'libarchive/test/test_read_format_raw.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_raw.c - -libarchive/test/test-test_read_format_raw.obj: libarchive/test/test_read_format_raw.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_raw.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_raw.Tpo -c -o libarchive/test/test-test_read_format_raw.obj `if test -f 'libarchive/test/test_read_format_raw.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_raw.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_raw.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_raw.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_raw.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_raw.c' object='libarchive/test/test-test_read_format_raw.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_raw.obj `if test -f 'libarchive/test/test_read_format_raw.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_raw.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_raw.c'; fi` - -libarchive/test/test-test_read_format_tar.o: libarchive/test/test_read_format_tar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_tar.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_tar.Tpo -c -o libarchive/test/test-test_read_format_tar.o `test -f 'libarchive/test/test_read_format_tar.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_tar.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_tar.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_tar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_tar.c' object='libarchive/test/test-test_read_format_tar.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_tar.o `test -f 'libarchive/test/test_read_format_tar.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_tar.c - -libarchive/test/test-test_read_format_tar.obj: libarchive/test/test_read_format_tar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_tar.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_tar.Tpo -c -o libarchive/test/test-test_read_format_tar.obj `if test -f 'libarchive/test/test_read_format_tar.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_tar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_tar.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_tar.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_tar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_tar.c' object='libarchive/test/test-test_read_format_tar.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_tar.obj `if test -f 'libarchive/test/test_read_format_tar.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_tar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_tar.c'; fi` - -libarchive/test/test-test_read_format_tar_concatenated.o: libarchive/test/test_read_format_tar_concatenated.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_tar_concatenated.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_tar_concatenated.Tpo -c -o libarchive/test/test-test_read_format_tar_concatenated.o `test -f 'libarchive/test/test_read_format_tar_concatenated.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_tar_concatenated.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_tar_concatenated.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_tar_concatenated.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_tar_concatenated.c' object='libarchive/test/test-test_read_format_tar_concatenated.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_tar_concatenated.o `test -f 'libarchive/test/test_read_format_tar_concatenated.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_tar_concatenated.c - -libarchive/test/test-test_read_format_tar_concatenated.obj: libarchive/test/test_read_format_tar_concatenated.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_tar_concatenated.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_tar_concatenated.Tpo -c -o libarchive/test/test-test_read_format_tar_concatenated.obj `if test -f 'libarchive/test/test_read_format_tar_concatenated.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_tar_concatenated.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_tar_concatenated.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_tar_concatenated.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_tar_concatenated.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_tar_concatenated.c' object='libarchive/test/test-test_read_format_tar_concatenated.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_tar_concatenated.obj `if test -f 'libarchive/test/test_read_format_tar_concatenated.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_tar_concatenated.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_tar_concatenated.c'; fi` - -libarchive/test/test-test_read_format_tar_empty_pax.o: libarchive/test/test_read_format_tar_empty_pax.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_tar_empty_pax.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_pax.Tpo -c -o libarchive/test/test-test_read_format_tar_empty_pax.o `test -f 'libarchive/test/test_read_format_tar_empty_pax.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_tar_empty_pax.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_pax.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_pax.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_tar_empty_pax.c' object='libarchive/test/test-test_read_format_tar_empty_pax.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_tar_empty_pax.o `test -f 'libarchive/test/test_read_format_tar_empty_pax.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_tar_empty_pax.c - -libarchive/test/test-test_read_format_tar_empty_pax.obj: libarchive/test/test_read_format_tar_empty_pax.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_tar_empty_pax.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_pax.Tpo -c -o libarchive/test/test-test_read_format_tar_empty_pax.obj `if test -f 'libarchive/test/test_read_format_tar_empty_pax.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_tar_empty_pax.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_tar_empty_pax.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_pax.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_pax.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_tar_empty_pax.c' object='libarchive/test/test-test_read_format_tar_empty_pax.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_tar_empty_pax.obj `if test -f 'libarchive/test/test_read_format_tar_empty_pax.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_tar_empty_pax.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_tar_empty_pax.c'; fi` - -libarchive/test/test-test_read_format_tar_empty_filename.o: libarchive/test/test_read_format_tar_empty_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_tar_empty_filename.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_filename.Tpo -c -o libarchive/test/test-test_read_format_tar_empty_filename.o `test -f 'libarchive/test/test_read_format_tar_empty_filename.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_tar_empty_filename.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_filename.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_tar_empty_filename.c' object='libarchive/test/test-test_read_format_tar_empty_filename.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_tar_empty_filename.o `test -f 'libarchive/test/test_read_format_tar_empty_filename.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_tar_empty_filename.c - -libarchive/test/test-test_read_format_tar_empty_filename.obj: libarchive/test/test_read_format_tar_empty_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_tar_empty_filename.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_filename.Tpo -c -o libarchive/test/test-test_read_format_tar_empty_filename.obj `if test -f 'libarchive/test/test_read_format_tar_empty_filename.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_tar_empty_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_tar_empty_filename.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_filename.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_tar_empty_filename.c' object='libarchive/test/test-test_read_format_tar_empty_filename.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_tar_empty_filename.obj `if test -f 'libarchive/test/test_read_format_tar_empty_filename.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_tar_empty_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_tar_empty_filename.c'; fi` - -libarchive/test/test-test_read_format_tar_empty_with_gnulabel.o: libarchive/test/test_read_format_tar_empty_with_gnulabel.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_tar_empty_with_gnulabel.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_with_gnulabel.Tpo -c -o libarchive/test/test-test_read_format_tar_empty_with_gnulabel.o `test -f 'libarchive/test/test_read_format_tar_empty_with_gnulabel.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_tar_empty_with_gnulabel.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_with_gnulabel.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_with_gnulabel.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_tar_empty_with_gnulabel.c' object='libarchive/test/test-test_read_format_tar_empty_with_gnulabel.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_tar_empty_with_gnulabel.o `test -f 'libarchive/test/test_read_format_tar_empty_with_gnulabel.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_tar_empty_with_gnulabel.c - -libarchive/test/test-test_read_format_tar_empty_with_gnulabel.obj: libarchive/test/test_read_format_tar_empty_with_gnulabel.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_tar_empty_with_gnulabel.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_with_gnulabel.Tpo -c -o libarchive/test/test-test_read_format_tar_empty_with_gnulabel.obj `if test -f 'libarchive/test/test_read_format_tar_empty_with_gnulabel.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_tar_empty_with_gnulabel.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_tar_empty_with_gnulabel.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_with_gnulabel.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_with_gnulabel.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_tar_empty_with_gnulabel.c' object='libarchive/test/test-test_read_format_tar_empty_with_gnulabel.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_tar_empty_with_gnulabel.obj `if test -f 'libarchive/test/test_read_format_tar_empty_with_gnulabel.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_tar_empty_with_gnulabel.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_tar_empty_with_gnulabel.c'; fi` - -libarchive/test/test-test_read_format_tar_filename.o: libarchive/test/test_read_format_tar_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_tar_filename.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_tar_filename.Tpo -c -o libarchive/test/test-test_read_format_tar_filename.o `test -f 'libarchive/test/test_read_format_tar_filename.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_tar_filename.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_tar_filename.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_tar_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_tar_filename.c' object='libarchive/test/test-test_read_format_tar_filename.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_tar_filename.o `test -f 'libarchive/test/test_read_format_tar_filename.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_tar_filename.c - -libarchive/test/test-test_read_format_tar_filename.obj: libarchive/test/test_read_format_tar_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_tar_filename.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_tar_filename.Tpo -c -o libarchive/test/test-test_read_format_tar_filename.obj `if test -f 'libarchive/test/test_read_format_tar_filename.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_tar_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_tar_filename.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_tar_filename.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_tar_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_tar_filename.c' object='libarchive/test/test-test_read_format_tar_filename.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_tar_filename.obj `if test -f 'libarchive/test/test_read_format_tar_filename.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_tar_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_tar_filename.c'; fi` - -libarchive/test/test-test_read_format_tar_invalid_pax_size.o: libarchive/test/test_read_format_tar_invalid_pax_size.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_tar_invalid_pax_size.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_tar_invalid_pax_size.Tpo -c -o libarchive/test/test-test_read_format_tar_invalid_pax_size.o `test -f 'libarchive/test/test_read_format_tar_invalid_pax_size.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_tar_invalid_pax_size.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_tar_invalid_pax_size.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_tar_invalid_pax_size.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_tar_invalid_pax_size.c' object='libarchive/test/test-test_read_format_tar_invalid_pax_size.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_tar_invalid_pax_size.o `test -f 'libarchive/test/test_read_format_tar_invalid_pax_size.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_tar_invalid_pax_size.c - -libarchive/test/test-test_read_format_tar_invalid_pax_size.obj: libarchive/test/test_read_format_tar_invalid_pax_size.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_tar_invalid_pax_size.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_tar_invalid_pax_size.Tpo -c -o libarchive/test/test-test_read_format_tar_invalid_pax_size.obj `if test -f 'libarchive/test/test_read_format_tar_invalid_pax_size.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_tar_invalid_pax_size.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_tar_invalid_pax_size.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_tar_invalid_pax_size.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_tar_invalid_pax_size.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_tar_invalid_pax_size.c' object='libarchive/test/test-test_read_format_tar_invalid_pax_size.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_tar_invalid_pax_size.obj `if test -f 'libarchive/test/test_read_format_tar_invalid_pax_size.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_tar_invalid_pax_size.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_tar_invalid_pax_size.c'; fi` - -libarchive/test/test-test_read_format_tbz.o: libarchive/test/test_read_format_tbz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_tbz.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_tbz.Tpo -c -o libarchive/test/test-test_read_format_tbz.o `test -f 'libarchive/test/test_read_format_tbz.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_tbz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_tbz.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_tbz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_tbz.c' object='libarchive/test/test-test_read_format_tbz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_tbz.o `test -f 'libarchive/test/test_read_format_tbz.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_tbz.c - -libarchive/test/test-test_read_format_tbz.obj: libarchive/test/test_read_format_tbz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_tbz.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_tbz.Tpo -c -o libarchive/test/test-test_read_format_tbz.obj `if test -f 'libarchive/test/test_read_format_tbz.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_tbz.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_tbz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_tbz.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_tbz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_tbz.c' object='libarchive/test/test-test_read_format_tbz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_tbz.obj `if test -f 'libarchive/test/test_read_format_tbz.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_tbz.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_tbz.c'; fi` - -libarchive/test/test-test_read_format_tgz.o: libarchive/test/test_read_format_tgz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_tgz.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_tgz.Tpo -c -o libarchive/test/test-test_read_format_tgz.o `test -f 'libarchive/test/test_read_format_tgz.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_tgz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_tgz.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_tgz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_tgz.c' object='libarchive/test/test-test_read_format_tgz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_tgz.o `test -f 'libarchive/test/test_read_format_tgz.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_tgz.c - -libarchive/test/test-test_read_format_tgz.obj: libarchive/test/test_read_format_tgz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_tgz.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_tgz.Tpo -c -o libarchive/test/test-test_read_format_tgz.obj `if test -f 'libarchive/test/test_read_format_tgz.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_tgz.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_tgz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_tgz.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_tgz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_tgz.c' object='libarchive/test/test-test_read_format_tgz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_tgz.obj `if test -f 'libarchive/test/test_read_format_tgz.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_tgz.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_tgz.c'; fi` - -libarchive/test/test-test_read_format_tlz.o: libarchive/test/test_read_format_tlz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_tlz.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_tlz.Tpo -c -o libarchive/test/test-test_read_format_tlz.o `test -f 'libarchive/test/test_read_format_tlz.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_tlz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_tlz.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_tlz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_tlz.c' object='libarchive/test/test-test_read_format_tlz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_tlz.o `test -f 'libarchive/test/test_read_format_tlz.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_tlz.c - -libarchive/test/test-test_read_format_tlz.obj: libarchive/test/test_read_format_tlz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_tlz.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_tlz.Tpo -c -o libarchive/test/test-test_read_format_tlz.obj `if test -f 'libarchive/test/test_read_format_tlz.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_tlz.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_tlz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_tlz.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_tlz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_tlz.c' object='libarchive/test/test-test_read_format_tlz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_tlz.obj `if test -f 'libarchive/test/test_read_format_tlz.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_tlz.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_tlz.c'; fi` - -libarchive/test/test-test_read_format_txz.o: libarchive/test/test_read_format_txz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_txz.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_txz.Tpo -c -o libarchive/test/test-test_read_format_txz.o `test -f 'libarchive/test/test_read_format_txz.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_txz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_txz.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_txz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_txz.c' object='libarchive/test/test-test_read_format_txz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_txz.o `test -f 'libarchive/test/test_read_format_txz.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_txz.c - -libarchive/test/test-test_read_format_txz.obj: libarchive/test/test_read_format_txz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_txz.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_txz.Tpo -c -o libarchive/test/test-test_read_format_txz.obj `if test -f 'libarchive/test/test_read_format_txz.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_txz.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_txz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_txz.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_txz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_txz.c' object='libarchive/test/test-test_read_format_txz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_txz.obj `if test -f 'libarchive/test/test_read_format_txz.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_txz.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_txz.c'; fi` - -libarchive/test/test-test_read_format_tz.o: libarchive/test/test_read_format_tz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_tz.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_tz.Tpo -c -o libarchive/test/test-test_read_format_tz.o `test -f 'libarchive/test/test_read_format_tz.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_tz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_tz.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_tz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_tz.c' object='libarchive/test/test-test_read_format_tz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_tz.o `test -f 'libarchive/test/test_read_format_tz.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_tz.c - -libarchive/test/test-test_read_format_tz.obj: libarchive/test/test_read_format_tz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_tz.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_tz.Tpo -c -o libarchive/test/test-test_read_format_tz.obj `if test -f 'libarchive/test/test_read_format_tz.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_tz.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_tz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_tz.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_tz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_tz.c' object='libarchive/test/test-test_read_format_tz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_tz.obj `if test -f 'libarchive/test/test_read_format_tz.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_tz.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_tz.c'; fi` - -libarchive/test/test-test_read_format_ustar_filename.o: libarchive/test/test_read_format_ustar_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_ustar_filename.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_ustar_filename.Tpo -c -o libarchive/test/test-test_read_format_ustar_filename.o `test -f 'libarchive/test/test_read_format_ustar_filename.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_ustar_filename.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_ustar_filename.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_ustar_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_ustar_filename.c' object='libarchive/test/test-test_read_format_ustar_filename.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_ustar_filename.o `test -f 'libarchive/test/test_read_format_ustar_filename.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_ustar_filename.c - -libarchive/test/test-test_read_format_ustar_filename.obj: libarchive/test/test_read_format_ustar_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_ustar_filename.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_ustar_filename.Tpo -c -o libarchive/test/test-test_read_format_ustar_filename.obj `if test -f 'libarchive/test/test_read_format_ustar_filename.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_ustar_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_ustar_filename.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_ustar_filename.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_ustar_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_ustar_filename.c' object='libarchive/test/test-test_read_format_ustar_filename.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_ustar_filename.obj `if test -f 'libarchive/test/test_read_format_ustar_filename.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_ustar_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_ustar_filename.c'; fi` - -libarchive/test/test-test_read_format_warc.o: libarchive/test/test_read_format_warc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_warc.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_warc.Tpo -c -o libarchive/test/test-test_read_format_warc.o `test -f 'libarchive/test/test_read_format_warc.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_warc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_warc.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_warc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_warc.c' object='libarchive/test/test-test_read_format_warc.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_warc.o `test -f 'libarchive/test/test_read_format_warc.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_warc.c - -libarchive/test/test-test_read_format_warc.obj: libarchive/test/test_read_format_warc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_warc.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_warc.Tpo -c -o libarchive/test/test-test_read_format_warc.obj `if test -f 'libarchive/test/test_read_format_warc.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_warc.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_warc.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_warc.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_warc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_warc.c' object='libarchive/test/test-test_read_format_warc.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_warc.obj `if test -f 'libarchive/test/test_read_format_warc.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_warc.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_warc.c'; fi` - -libarchive/test/test-test_read_format_xar.o: libarchive/test/test_read_format_xar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_xar.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_xar.Tpo -c -o libarchive/test/test-test_read_format_xar.o `test -f 'libarchive/test/test_read_format_xar.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_xar.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_xar.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_xar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_xar.c' object='libarchive/test/test-test_read_format_xar.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_xar.o `test -f 'libarchive/test/test_read_format_xar.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_xar.c - -libarchive/test/test-test_read_format_xar.obj: libarchive/test/test_read_format_xar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_xar.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_xar.Tpo -c -o libarchive/test/test-test_read_format_xar.obj `if test -f 'libarchive/test/test_read_format_xar.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_xar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_xar.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_xar.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_xar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_xar.c' object='libarchive/test/test-test_read_format_xar.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_xar.obj `if test -f 'libarchive/test/test_read_format_xar.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_xar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_xar.c'; fi` - -libarchive/test/test-test_read_format_zip.o: libarchive/test/test_read_format_zip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip.Tpo -c -o libarchive/test/test-test_read_format_zip.o `test -f 'libarchive/test/test_read_format_zip.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip.c' object='libarchive/test/test-test_read_format_zip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip.o `test -f 'libarchive/test/test_read_format_zip.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip.c - -libarchive/test/test-test_read_format_zip.obj: libarchive/test/test_read_format_zip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip.Tpo -c -o libarchive/test/test-test_read_format_zip.obj `if test -f 'libarchive/test/test_read_format_zip.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip.c' object='libarchive/test/test-test_read_format_zip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip.obj `if test -f 'libarchive/test/test_read_format_zip.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip.c'; fi` - -libarchive/test/test-test_read_format_zip_7075_utf8_paths.o: libarchive/test/test_read_format_zip_7075_utf8_paths.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_7075_utf8_paths.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_7075_utf8_paths.Tpo -c -o libarchive/test/test-test_read_format_zip_7075_utf8_paths.o `test -f 'libarchive/test/test_read_format_zip_7075_utf8_paths.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_7075_utf8_paths.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_7075_utf8_paths.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_7075_utf8_paths.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_7075_utf8_paths.c' object='libarchive/test/test-test_read_format_zip_7075_utf8_paths.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_7075_utf8_paths.o `test -f 'libarchive/test/test_read_format_zip_7075_utf8_paths.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_7075_utf8_paths.c - -libarchive/test/test-test_read_format_zip_7075_utf8_paths.obj: libarchive/test/test_read_format_zip_7075_utf8_paths.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_7075_utf8_paths.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_7075_utf8_paths.Tpo -c -o libarchive/test/test-test_read_format_zip_7075_utf8_paths.obj `if test -f 'libarchive/test/test_read_format_zip_7075_utf8_paths.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_7075_utf8_paths.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_7075_utf8_paths.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_7075_utf8_paths.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_7075_utf8_paths.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_7075_utf8_paths.c' object='libarchive/test/test-test_read_format_zip_7075_utf8_paths.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_7075_utf8_paths.obj `if test -f 'libarchive/test/test_read_format_zip_7075_utf8_paths.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_7075_utf8_paths.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_7075_utf8_paths.c'; fi` - -libarchive/test/test-test_read_format_zip_comment_stored.o: libarchive/test/test_read_format_zip_comment_stored.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_comment_stored.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_comment_stored.Tpo -c -o libarchive/test/test-test_read_format_zip_comment_stored.o `test -f 'libarchive/test/test_read_format_zip_comment_stored.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_comment_stored.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_comment_stored.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_comment_stored.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_comment_stored.c' object='libarchive/test/test-test_read_format_zip_comment_stored.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_comment_stored.o `test -f 'libarchive/test/test_read_format_zip_comment_stored.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_comment_stored.c - -libarchive/test/test-test_read_format_zip_comment_stored.obj: libarchive/test/test_read_format_zip_comment_stored.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_comment_stored.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_comment_stored.Tpo -c -o libarchive/test/test-test_read_format_zip_comment_stored.obj `if test -f 'libarchive/test/test_read_format_zip_comment_stored.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_comment_stored.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_comment_stored.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_comment_stored.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_comment_stored.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_comment_stored.c' object='libarchive/test/test-test_read_format_zip_comment_stored.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_comment_stored.obj `if test -f 'libarchive/test/test_read_format_zip_comment_stored.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_comment_stored.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_comment_stored.c'; fi` - -libarchive/test/test-test_read_format_zip_encryption_data.o: libarchive/test/test_read_format_zip_encryption_data.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_encryption_data.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_data.Tpo -c -o libarchive/test/test-test_read_format_zip_encryption_data.o `test -f 'libarchive/test/test_read_format_zip_encryption_data.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_encryption_data.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_data.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_data.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_encryption_data.c' object='libarchive/test/test-test_read_format_zip_encryption_data.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_encryption_data.o `test -f 'libarchive/test/test_read_format_zip_encryption_data.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_encryption_data.c - -libarchive/test/test-test_read_format_zip_encryption_data.obj: libarchive/test/test_read_format_zip_encryption_data.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_encryption_data.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_data.Tpo -c -o libarchive/test/test-test_read_format_zip_encryption_data.obj `if test -f 'libarchive/test/test_read_format_zip_encryption_data.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_encryption_data.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_encryption_data.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_data.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_data.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_encryption_data.c' object='libarchive/test/test-test_read_format_zip_encryption_data.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_encryption_data.obj `if test -f 'libarchive/test/test_read_format_zip_encryption_data.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_encryption_data.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_encryption_data.c'; fi` - -libarchive/test/test-test_read_format_zip_encryption_partially.o: libarchive/test/test_read_format_zip_encryption_partially.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_encryption_partially.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_partially.Tpo -c -o libarchive/test/test-test_read_format_zip_encryption_partially.o `test -f 'libarchive/test/test_read_format_zip_encryption_partially.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_encryption_partially.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_partially.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_partially.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_encryption_partially.c' object='libarchive/test/test-test_read_format_zip_encryption_partially.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_encryption_partially.o `test -f 'libarchive/test/test_read_format_zip_encryption_partially.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_encryption_partially.c - -libarchive/test/test-test_read_format_zip_encryption_partially.obj: libarchive/test/test_read_format_zip_encryption_partially.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_encryption_partially.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_partially.Tpo -c -o libarchive/test/test-test_read_format_zip_encryption_partially.obj `if test -f 'libarchive/test/test_read_format_zip_encryption_partially.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_encryption_partially.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_encryption_partially.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_partially.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_partially.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_encryption_partially.c' object='libarchive/test/test-test_read_format_zip_encryption_partially.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_encryption_partially.obj `if test -f 'libarchive/test/test_read_format_zip_encryption_partially.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_encryption_partially.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_encryption_partially.c'; fi` - -libarchive/test/test-test_read_format_zip_encryption_header.o: libarchive/test/test_read_format_zip_encryption_header.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_encryption_header.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_header.Tpo -c -o libarchive/test/test-test_read_format_zip_encryption_header.o `test -f 'libarchive/test/test_read_format_zip_encryption_header.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_encryption_header.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_header.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_header.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_encryption_header.c' object='libarchive/test/test-test_read_format_zip_encryption_header.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_encryption_header.o `test -f 'libarchive/test/test_read_format_zip_encryption_header.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_encryption_header.c - -libarchive/test/test-test_read_format_zip_encryption_header.obj: libarchive/test/test_read_format_zip_encryption_header.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_encryption_header.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_header.Tpo -c -o libarchive/test/test-test_read_format_zip_encryption_header.obj `if test -f 'libarchive/test/test_read_format_zip_encryption_header.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_encryption_header.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_encryption_header.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_header.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_header.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_encryption_header.c' object='libarchive/test/test-test_read_format_zip_encryption_header.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_encryption_header.obj `if test -f 'libarchive/test/test_read_format_zip_encryption_header.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_encryption_header.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_encryption_header.c'; fi` - -libarchive/test/test-test_read_format_zip_extra_padding.o: libarchive/test/test_read_format_zip_extra_padding.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_extra_padding.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_extra_padding.Tpo -c -o libarchive/test/test-test_read_format_zip_extra_padding.o `test -f 'libarchive/test/test_read_format_zip_extra_padding.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_extra_padding.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_extra_padding.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_extra_padding.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_extra_padding.c' object='libarchive/test/test-test_read_format_zip_extra_padding.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_extra_padding.o `test -f 'libarchive/test/test_read_format_zip_extra_padding.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_extra_padding.c - -libarchive/test/test-test_read_format_zip_extra_padding.obj: libarchive/test/test_read_format_zip_extra_padding.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_extra_padding.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_extra_padding.Tpo -c -o libarchive/test/test-test_read_format_zip_extra_padding.obj `if test -f 'libarchive/test/test_read_format_zip_extra_padding.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_extra_padding.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_extra_padding.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_extra_padding.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_extra_padding.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_extra_padding.c' object='libarchive/test/test-test_read_format_zip_extra_padding.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_extra_padding.obj `if test -f 'libarchive/test/test_read_format_zip_extra_padding.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_extra_padding.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_extra_padding.c'; fi` - -libarchive/test/test-test_read_format_zip_filename.o: libarchive/test/test_read_format_zip_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_filename.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_filename.Tpo -c -o libarchive/test/test-test_read_format_zip_filename.o `test -f 'libarchive/test/test_read_format_zip_filename.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_filename.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_filename.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_filename.c' object='libarchive/test/test-test_read_format_zip_filename.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_filename.o `test -f 'libarchive/test/test_read_format_zip_filename.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_filename.c - -libarchive/test/test-test_read_format_zip_filename.obj: libarchive/test/test_read_format_zip_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_filename.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_filename.Tpo -c -o libarchive/test/test-test_read_format_zip_filename.obj `if test -f 'libarchive/test/test_read_format_zip_filename.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_filename.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_filename.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_filename.c' object='libarchive/test/test-test_read_format_zip_filename.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_filename.obj `if test -f 'libarchive/test/test_read_format_zip_filename.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_filename.c'; fi` - -libarchive/test/test-test_read_format_zip_high_compression.o: libarchive/test/test_read_format_zip_high_compression.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_high_compression.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_high_compression.Tpo -c -o libarchive/test/test-test_read_format_zip_high_compression.o `test -f 'libarchive/test/test_read_format_zip_high_compression.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_high_compression.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_high_compression.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_high_compression.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_high_compression.c' object='libarchive/test/test-test_read_format_zip_high_compression.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_high_compression.o `test -f 'libarchive/test/test_read_format_zip_high_compression.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_high_compression.c - -libarchive/test/test-test_read_format_zip_high_compression.obj: libarchive/test/test_read_format_zip_high_compression.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_high_compression.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_high_compression.Tpo -c -o libarchive/test/test-test_read_format_zip_high_compression.obj `if test -f 'libarchive/test/test_read_format_zip_high_compression.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_high_compression.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_high_compression.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_high_compression.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_high_compression.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_high_compression.c' object='libarchive/test/test-test_read_format_zip_high_compression.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_high_compression.obj `if test -f 'libarchive/test/test_read_format_zip_high_compression.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_high_compression.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_high_compression.c'; fi` - -libarchive/test/test-test_read_format_zip_jar.o: libarchive/test/test_read_format_zip_jar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_jar.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_jar.Tpo -c -o libarchive/test/test-test_read_format_zip_jar.o `test -f 'libarchive/test/test_read_format_zip_jar.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_jar.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_jar.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_jar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_jar.c' object='libarchive/test/test-test_read_format_zip_jar.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_jar.o `test -f 'libarchive/test/test_read_format_zip_jar.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_jar.c - -libarchive/test/test-test_read_format_zip_jar.obj: libarchive/test/test_read_format_zip_jar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_jar.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_jar.Tpo -c -o libarchive/test/test-test_read_format_zip_jar.obj `if test -f 'libarchive/test/test_read_format_zip_jar.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_jar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_jar.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_jar.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_jar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_jar.c' object='libarchive/test/test-test_read_format_zip_jar.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_jar.obj `if test -f 'libarchive/test/test_read_format_zip_jar.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_jar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_jar.c'; fi` - -libarchive/test/test-test_read_format_zip_mac_metadata.o: libarchive/test/test_read_format_zip_mac_metadata.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_mac_metadata.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_mac_metadata.Tpo -c -o libarchive/test/test-test_read_format_zip_mac_metadata.o `test -f 'libarchive/test/test_read_format_zip_mac_metadata.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_mac_metadata.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_mac_metadata.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_mac_metadata.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_mac_metadata.c' object='libarchive/test/test-test_read_format_zip_mac_metadata.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_mac_metadata.o `test -f 'libarchive/test/test_read_format_zip_mac_metadata.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_mac_metadata.c - -libarchive/test/test-test_read_format_zip_mac_metadata.obj: libarchive/test/test_read_format_zip_mac_metadata.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_mac_metadata.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_mac_metadata.Tpo -c -o libarchive/test/test-test_read_format_zip_mac_metadata.obj `if test -f 'libarchive/test/test_read_format_zip_mac_metadata.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_mac_metadata.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_mac_metadata.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_mac_metadata.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_mac_metadata.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_mac_metadata.c' object='libarchive/test/test-test_read_format_zip_mac_metadata.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_mac_metadata.obj `if test -f 'libarchive/test/test_read_format_zip_mac_metadata.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_mac_metadata.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_mac_metadata.c'; fi` - -libarchive/test/test-test_read_format_zip_malformed.o: libarchive/test/test_read_format_zip_malformed.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_malformed.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_malformed.Tpo -c -o libarchive/test/test-test_read_format_zip_malformed.o `test -f 'libarchive/test/test_read_format_zip_malformed.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_malformed.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_malformed.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_malformed.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_malformed.c' object='libarchive/test/test-test_read_format_zip_malformed.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_malformed.o `test -f 'libarchive/test/test_read_format_zip_malformed.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_malformed.c - -libarchive/test/test-test_read_format_zip_malformed.obj: libarchive/test/test_read_format_zip_malformed.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_malformed.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_malformed.Tpo -c -o libarchive/test/test-test_read_format_zip_malformed.obj `if test -f 'libarchive/test/test_read_format_zip_malformed.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_malformed.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_malformed.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_malformed.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_malformed.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_malformed.c' object='libarchive/test/test-test_read_format_zip_malformed.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_malformed.obj `if test -f 'libarchive/test/test_read_format_zip_malformed.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_malformed.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_malformed.c'; fi` - -libarchive/test/test-test_read_format_zip_msdos.o: libarchive/test/test_read_format_zip_msdos.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_msdos.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_msdos.Tpo -c -o libarchive/test/test-test_read_format_zip_msdos.o `test -f 'libarchive/test/test_read_format_zip_msdos.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_msdos.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_msdos.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_msdos.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_msdos.c' object='libarchive/test/test-test_read_format_zip_msdos.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_msdos.o `test -f 'libarchive/test/test_read_format_zip_msdos.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_msdos.c - -libarchive/test/test-test_read_format_zip_msdos.obj: libarchive/test/test_read_format_zip_msdos.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_msdos.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_msdos.Tpo -c -o libarchive/test/test-test_read_format_zip_msdos.obj `if test -f 'libarchive/test/test_read_format_zip_msdos.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_msdos.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_msdos.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_msdos.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_msdos.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_msdos.c' object='libarchive/test/test-test_read_format_zip_msdos.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_msdos.obj `if test -f 'libarchive/test/test_read_format_zip_msdos.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_msdos.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_msdos.c'; fi` - -libarchive/test/test-test_read_format_zip_nested.o: libarchive/test/test_read_format_zip_nested.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_nested.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_nested.Tpo -c -o libarchive/test/test-test_read_format_zip_nested.o `test -f 'libarchive/test/test_read_format_zip_nested.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_nested.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_nested.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_nested.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_nested.c' object='libarchive/test/test-test_read_format_zip_nested.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_nested.o `test -f 'libarchive/test/test_read_format_zip_nested.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_nested.c - -libarchive/test/test-test_read_format_zip_nested.obj: libarchive/test/test_read_format_zip_nested.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_nested.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_nested.Tpo -c -o libarchive/test/test-test_read_format_zip_nested.obj `if test -f 'libarchive/test/test_read_format_zip_nested.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_nested.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_nested.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_nested.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_nested.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_nested.c' object='libarchive/test/test-test_read_format_zip_nested.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_nested.obj `if test -f 'libarchive/test/test_read_format_zip_nested.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_nested.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_nested.c'; fi` - -libarchive/test/test-test_read_format_zip_nofiletype.o: libarchive/test/test_read_format_zip_nofiletype.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_nofiletype.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_nofiletype.Tpo -c -o libarchive/test/test-test_read_format_zip_nofiletype.o `test -f 'libarchive/test/test_read_format_zip_nofiletype.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_nofiletype.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_nofiletype.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_nofiletype.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_nofiletype.c' object='libarchive/test/test-test_read_format_zip_nofiletype.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_nofiletype.o `test -f 'libarchive/test/test_read_format_zip_nofiletype.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_nofiletype.c - -libarchive/test/test-test_read_format_zip_nofiletype.obj: libarchive/test/test_read_format_zip_nofiletype.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_nofiletype.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_nofiletype.Tpo -c -o libarchive/test/test-test_read_format_zip_nofiletype.obj `if test -f 'libarchive/test/test_read_format_zip_nofiletype.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_nofiletype.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_nofiletype.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_nofiletype.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_nofiletype.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_nofiletype.c' object='libarchive/test/test-test_read_format_zip_nofiletype.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_nofiletype.obj `if test -f 'libarchive/test/test_read_format_zip_nofiletype.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_nofiletype.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_nofiletype.c'; fi` - -libarchive/test/test-test_read_format_zip_padded.o: libarchive/test/test_read_format_zip_padded.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_padded.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_padded.Tpo -c -o libarchive/test/test-test_read_format_zip_padded.o `test -f 'libarchive/test/test_read_format_zip_padded.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_padded.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_padded.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_padded.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_padded.c' object='libarchive/test/test-test_read_format_zip_padded.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_padded.o `test -f 'libarchive/test/test_read_format_zip_padded.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_padded.c - -libarchive/test/test-test_read_format_zip_padded.obj: libarchive/test/test_read_format_zip_padded.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_padded.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_padded.Tpo -c -o libarchive/test/test-test_read_format_zip_padded.obj `if test -f 'libarchive/test/test_read_format_zip_padded.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_padded.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_padded.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_padded.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_padded.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_padded.c' object='libarchive/test/test-test_read_format_zip_padded.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_padded.obj `if test -f 'libarchive/test/test_read_format_zip_padded.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_padded.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_padded.c'; fi` - -libarchive/test/test-test_read_format_zip_sfx.o: libarchive/test/test_read_format_zip_sfx.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_sfx.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_sfx.Tpo -c -o libarchive/test/test-test_read_format_zip_sfx.o `test -f 'libarchive/test/test_read_format_zip_sfx.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_sfx.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_sfx.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_sfx.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_sfx.c' object='libarchive/test/test-test_read_format_zip_sfx.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_sfx.o `test -f 'libarchive/test/test_read_format_zip_sfx.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_sfx.c - -libarchive/test/test-test_read_format_zip_sfx.obj: libarchive/test/test_read_format_zip_sfx.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_sfx.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_sfx.Tpo -c -o libarchive/test/test-test_read_format_zip_sfx.obj `if test -f 'libarchive/test/test_read_format_zip_sfx.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_sfx.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_sfx.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_sfx.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_sfx.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_sfx.c' object='libarchive/test/test-test_read_format_zip_sfx.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_sfx.obj `if test -f 'libarchive/test/test_read_format_zip_sfx.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_sfx.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_sfx.c'; fi` - -libarchive/test/test-test_read_format_zip_traditional_encryption_data.o: libarchive/test/test_read_format_zip_traditional_encryption_data.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_traditional_encryption_data.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_traditional_encryption_data.Tpo -c -o libarchive/test/test-test_read_format_zip_traditional_encryption_data.o `test -f 'libarchive/test/test_read_format_zip_traditional_encryption_data.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_traditional_encryption_data.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_traditional_encryption_data.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_traditional_encryption_data.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_traditional_encryption_data.c' object='libarchive/test/test-test_read_format_zip_traditional_encryption_data.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_traditional_encryption_data.o `test -f 'libarchive/test/test_read_format_zip_traditional_encryption_data.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_traditional_encryption_data.c - -libarchive/test/test-test_read_format_zip_traditional_encryption_data.obj: libarchive/test/test_read_format_zip_traditional_encryption_data.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_traditional_encryption_data.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_traditional_encryption_data.Tpo -c -o libarchive/test/test-test_read_format_zip_traditional_encryption_data.obj `if test -f 'libarchive/test/test_read_format_zip_traditional_encryption_data.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_traditional_encryption_data.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_traditional_encryption_data.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_traditional_encryption_data.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_traditional_encryption_data.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_traditional_encryption_data.c' object='libarchive/test/test-test_read_format_zip_traditional_encryption_data.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_traditional_encryption_data.obj `if test -f 'libarchive/test/test_read_format_zip_traditional_encryption_data.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_traditional_encryption_data.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_traditional_encryption_data.c'; fi` - -libarchive/test/test-test_read_format_zip_winzip_aes.o: libarchive/test/test_read_format_zip_winzip_aes.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_winzip_aes.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_winzip_aes.Tpo -c -o libarchive/test/test-test_read_format_zip_winzip_aes.o `test -f 'libarchive/test/test_read_format_zip_winzip_aes.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_winzip_aes.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_winzip_aes.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_winzip_aes.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_winzip_aes.c' object='libarchive/test/test-test_read_format_zip_winzip_aes.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_winzip_aes.o `test -f 'libarchive/test/test_read_format_zip_winzip_aes.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_winzip_aes.c - -libarchive/test/test-test_read_format_zip_winzip_aes.obj: libarchive/test/test_read_format_zip_winzip_aes.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_winzip_aes.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_winzip_aes.Tpo -c -o libarchive/test/test-test_read_format_zip_winzip_aes.obj `if test -f 'libarchive/test/test_read_format_zip_winzip_aes.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_winzip_aes.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_winzip_aes.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_winzip_aes.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_winzip_aes.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_winzip_aes.c' object='libarchive/test/test-test_read_format_zip_winzip_aes.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_winzip_aes.obj `if test -f 'libarchive/test/test_read_format_zip_winzip_aes.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_winzip_aes.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_winzip_aes.c'; fi` - -libarchive/test/test-test_read_format_zip_winzip_aes_large.o: libarchive/test/test_read_format_zip_winzip_aes_large.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_winzip_aes_large.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_winzip_aes_large.Tpo -c -o libarchive/test/test-test_read_format_zip_winzip_aes_large.o `test -f 'libarchive/test/test_read_format_zip_winzip_aes_large.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_winzip_aes_large.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_winzip_aes_large.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_winzip_aes_large.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_winzip_aes_large.c' object='libarchive/test/test-test_read_format_zip_winzip_aes_large.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_winzip_aes_large.o `test -f 'libarchive/test/test_read_format_zip_winzip_aes_large.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_winzip_aes_large.c - -libarchive/test/test-test_read_format_zip_winzip_aes_large.obj: libarchive/test/test_read_format_zip_winzip_aes_large.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_winzip_aes_large.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_winzip_aes_large.Tpo -c -o libarchive/test/test-test_read_format_zip_winzip_aes_large.obj `if test -f 'libarchive/test/test_read_format_zip_winzip_aes_large.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_winzip_aes_large.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_winzip_aes_large.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_winzip_aes_large.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_winzip_aes_large.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_winzip_aes_large.c' object='libarchive/test/test-test_read_format_zip_winzip_aes_large.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_winzip_aes_large.obj `if test -f 'libarchive/test/test_read_format_zip_winzip_aes_large.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_winzip_aes_large.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_winzip_aes_large.c'; fi` - -libarchive/test/test-test_read_format_zip_zip64.o: libarchive/test/test_read_format_zip_zip64.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_zip64.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_zip64.Tpo -c -o libarchive/test/test-test_read_format_zip_zip64.o `test -f 'libarchive/test/test_read_format_zip_zip64.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_zip64.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_zip64.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_zip64.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_zip64.c' object='libarchive/test/test-test_read_format_zip_zip64.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_zip64.o `test -f 'libarchive/test/test_read_format_zip_zip64.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_zip64.c - -libarchive/test/test-test_read_format_zip_zip64.obj: libarchive/test/test_read_format_zip_zip64.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_zip64.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_zip64.Tpo -c -o libarchive/test/test-test_read_format_zip_zip64.obj `if test -f 'libarchive/test/test_read_format_zip_zip64.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_zip64.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_zip64.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_zip64.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_zip64.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_zip64.c' object='libarchive/test/test-test_read_format_zip_zip64.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_zip64.obj `if test -f 'libarchive/test/test_read_format_zip_zip64.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_zip64.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_zip64.c'; fi` - -libarchive/test/test-test_read_format_zip_with_invalid_traditional_eocd.o: libarchive/test/test_read_format_zip_with_invalid_traditional_eocd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_with_invalid_traditional_eocd.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_with_invalid_traditional_eocd.Tpo -c -o libarchive/test/test-test_read_format_zip_with_invalid_traditional_eocd.o `test -f 'libarchive/test/test_read_format_zip_with_invalid_traditional_eocd.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_with_invalid_traditional_eocd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_with_invalid_traditional_eocd.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_with_invalid_traditional_eocd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_with_invalid_traditional_eocd.c' object='libarchive/test/test-test_read_format_zip_with_invalid_traditional_eocd.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_with_invalid_traditional_eocd.o `test -f 'libarchive/test/test_read_format_zip_with_invalid_traditional_eocd.c' || echo '$(srcdir)/'`libarchive/test/test_read_format_zip_with_invalid_traditional_eocd.c - -libarchive/test/test-test_read_format_zip_with_invalid_traditional_eocd.obj: libarchive/test/test_read_format_zip_with_invalid_traditional_eocd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_format_zip_with_invalid_traditional_eocd.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_format_zip_with_invalid_traditional_eocd.Tpo -c -o libarchive/test/test-test_read_format_zip_with_invalid_traditional_eocd.obj `if test -f 'libarchive/test/test_read_format_zip_with_invalid_traditional_eocd.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_with_invalid_traditional_eocd.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_with_invalid_traditional_eocd.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_format_zip_with_invalid_traditional_eocd.Tpo libarchive/test/$(DEPDIR)/test-test_read_format_zip_with_invalid_traditional_eocd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_format_zip_with_invalid_traditional_eocd.c' object='libarchive/test/test-test_read_format_zip_with_invalid_traditional_eocd.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_format_zip_with_invalid_traditional_eocd.obj `if test -f 'libarchive/test/test_read_format_zip_with_invalid_traditional_eocd.c'; then $(CYGPATH_W) 'libarchive/test/test_read_format_zip_with_invalid_traditional_eocd.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_format_zip_with_invalid_traditional_eocd.c'; fi` - -libarchive/test/test-test_read_large.o: libarchive/test/test_read_large.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_large.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_large.Tpo -c -o libarchive/test/test-test_read_large.o `test -f 'libarchive/test/test_read_large.c' || echo '$(srcdir)/'`libarchive/test/test_read_large.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_large.Tpo libarchive/test/$(DEPDIR)/test-test_read_large.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_large.c' object='libarchive/test/test-test_read_large.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_large.o `test -f 'libarchive/test/test_read_large.c' || echo '$(srcdir)/'`libarchive/test/test_read_large.c - -libarchive/test/test-test_read_large.obj: libarchive/test/test_read_large.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_large.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_large.Tpo -c -o libarchive/test/test-test_read_large.obj `if test -f 'libarchive/test/test_read_large.c'; then $(CYGPATH_W) 'libarchive/test/test_read_large.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_large.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_large.Tpo libarchive/test/$(DEPDIR)/test-test_read_large.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_large.c' object='libarchive/test/test-test_read_large.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_large.obj `if test -f 'libarchive/test/test_read_large.c'; then $(CYGPATH_W) 'libarchive/test/test_read_large.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_large.c'; fi` - -libarchive/test/test-test_read_pax_xattr_rht_security_selinux.o: libarchive/test/test_read_pax_xattr_rht_security_selinux.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_pax_xattr_rht_security_selinux.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_pax_xattr_rht_security_selinux.Tpo -c -o libarchive/test/test-test_read_pax_xattr_rht_security_selinux.o `test -f 'libarchive/test/test_read_pax_xattr_rht_security_selinux.c' || echo '$(srcdir)/'`libarchive/test/test_read_pax_xattr_rht_security_selinux.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_pax_xattr_rht_security_selinux.Tpo libarchive/test/$(DEPDIR)/test-test_read_pax_xattr_rht_security_selinux.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_pax_xattr_rht_security_selinux.c' object='libarchive/test/test-test_read_pax_xattr_rht_security_selinux.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_pax_xattr_rht_security_selinux.o `test -f 'libarchive/test/test_read_pax_xattr_rht_security_selinux.c' || echo '$(srcdir)/'`libarchive/test/test_read_pax_xattr_rht_security_selinux.c - -libarchive/test/test-test_read_pax_xattr_rht_security_selinux.obj: libarchive/test/test_read_pax_xattr_rht_security_selinux.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_pax_xattr_rht_security_selinux.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_pax_xattr_rht_security_selinux.Tpo -c -o libarchive/test/test-test_read_pax_xattr_rht_security_selinux.obj `if test -f 'libarchive/test/test_read_pax_xattr_rht_security_selinux.c'; then $(CYGPATH_W) 'libarchive/test/test_read_pax_xattr_rht_security_selinux.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_pax_xattr_rht_security_selinux.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_pax_xattr_rht_security_selinux.Tpo libarchive/test/$(DEPDIR)/test-test_read_pax_xattr_rht_security_selinux.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_pax_xattr_rht_security_selinux.c' object='libarchive/test/test-test_read_pax_xattr_rht_security_selinux.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_pax_xattr_rht_security_selinux.obj `if test -f 'libarchive/test/test_read_pax_xattr_rht_security_selinux.c'; then $(CYGPATH_W) 'libarchive/test/test_read_pax_xattr_rht_security_selinux.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_pax_xattr_rht_security_selinux.c'; fi` - -libarchive/test/test-test_read_pax_xattr_schily.o: libarchive/test/test_read_pax_xattr_schily.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_pax_xattr_schily.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_pax_xattr_schily.Tpo -c -o libarchive/test/test-test_read_pax_xattr_schily.o `test -f 'libarchive/test/test_read_pax_xattr_schily.c' || echo '$(srcdir)/'`libarchive/test/test_read_pax_xattr_schily.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_pax_xattr_schily.Tpo libarchive/test/$(DEPDIR)/test-test_read_pax_xattr_schily.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_pax_xattr_schily.c' object='libarchive/test/test-test_read_pax_xattr_schily.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_pax_xattr_schily.o `test -f 'libarchive/test/test_read_pax_xattr_schily.c' || echo '$(srcdir)/'`libarchive/test/test_read_pax_xattr_schily.c - -libarchive/test/test-test_read_pax_xattr_schily.obj: libarchive/test/test_read_pax_xattr_schily.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_pax_xattr_schily.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_pax_xattr_schily.Tpo -c -o libarchive/test/test-test_read_pax_xattr_schily.obj `if test -f 'libarchive/test/test_read_pax_xattr_schily.c'; then $(CYGPATH_W) 'libarchive/test/test_read_pax_xattr_schily.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_pax_xattr_schily.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_pax_xattr_schily.Tpo libarchive/test/$(DEPDIR)/test-test_read_pax_xattr_schily.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_pax_xattr_schily.c' object='libarchive/test/test-test_read_pax_xattr_schily.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_pax_xattr_schily.obj `if test -f 'libarchive/test/test_read_pax_xattr_schily.c'; then $(CYGPATH_W) 'libarchive/test/test_read_pax_xattr_schily.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_pax_xattr_schily.c'; fi` - -libarchive/test/test-test_read_pax_truncated.o: libarchive/test/test_read_pax_truncated.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_pax_truncated.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_pax_truncated.Tpo -c -o libarchive/test/test-test_read_pax_truncated.o `test -f 'libarchive/test/test_read_pax_truncated.c' || echo '$(srcdir)/'`libarchive/test/test_read_pax_truncated.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_pax_truncated.Tpo libarchive/test/$(DEPDIR)/test-test_read_pax_truncated.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_pax_truncated.c' object='libarchive/test/test-test_read_pax_truncated.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_pax_truncated.o `test -f 'libarchive/test/test_read_pax_truncated.c' || echo '$(srcdir)/'`libarchive/test/test_read_pax_truncated.c - -libarchive/test/test-test_read_pax_truncated.obj: libarchive/test/test_read_pax_truncated.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_pax_truncated.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_pax_truncated.Tpo -c -o libarchive/test/test-test_read_pax_truncated.obj `if test -f 'libarchive/test/test_read_pax_truncated.c'; then $(CYGPATH_W) 'libarchive/test/test_read_pax_truncated.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_pax_truncated.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_pax_truncated.Tpo libarchive/test/$(DEPDIR)/test-test_read_pax_truncated.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_pax_truncated.c' object='libarchive/test/test-test_read_pax_truncated.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_pax_truncated.obj `if test -f 'libarchive/test/test_read_pax_truncated.c'; then $(CYGPATH_W) 'libarchive/test/test_read_pax_truncated.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_pax_truncated.c'; fi` - -libarchive/test/test-test_read_position.o: libarchive/test/test_read_position.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_position.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_position.Tpo -c -o libarchive/test/test-test_read_position.o `test -f 'libarchive/test/test_read_position.c' || echo '$(srcdir)/'`libarchive/test/test_read_position.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_position.Tpo libarchive/test/$(DEPDIR)/test-test_read_position.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_position.c' object='libarchive/test/test-test_read_position.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_position.o `test -f 'libarchive/test/test_read_position.c' || echo '$(srcdir)/'`libarchive/test/test_read_position.c - -libarchive/test/test-test_read_position.obj: libarchive/test/test_read_position.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_position.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_position.Tpo -c -o libarchive/test/test-test_read_position.obj `if test -f 'libarchive/test/test_read_position.c'; then $(CYGPATH_W) 'libarchive/test/test_read_position.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_position.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_position.Tpo libarchive/test/$(DEPDIR)/test-test_read_position.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_position.c' object='libarchive/test/test-test_read_position.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_position.obj `if test -f 'libarchive/test/test_read_position.c'; then $(CYGPATH_W) 'libarchive/test/test_read_position.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_position.c'; fi` - -libarchive/test/test-test_read_set_format.o: libarchive/test/test_read_set_format.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_set_format.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_set_format.Tpo -c -o libarchive/test/test-test_read_set_format.o `test -f 'libarchive/test/test_read_set_format.c' || echo '$(srcdir)/'`libarchive/test/test_read_set_format.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_set_format.Tpo libarchive/test/$(DEPDIR)/test-test_read_set_format.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_set_format.c' object='libarchive/test/test-test_read_set_format.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_set_format.o `test -f 'libarchive/test/test_read_set_format.c' || echo '$(srcdir)/'`libarchive/test/test_read_set_format.c - -libarchive/test/test-test_read_set_format.obj: libarchive/test/test_read_set_format.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_set_format.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_set_format.Tpo -c -o libarchive/test/test-test_read_set_format.obj `if test -f 'libarchive/test/test_read_set_format.c'; then $(CYGPATH_W) 'libarchive/test/test_read_set_format.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_set_format.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_set_format.Tpo libarchive/test/$(DEPDIR)/test-test_read_set_format.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_set_format.c' object='libarchive/test/test-test_read_set_format.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_set_format.obj `if test -f 'libarchive/test/test_read_set_format.c'; then $(CYGPATH_W) 'libarchive/test/test_read_set_format.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_set_format.c'; fi` - -libarchive/test/test-test_read_too_many_filters.o: libarchive/test/test_read_too_many_filters.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_too_many_filters.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_too_many_filters.Tpo -c -o libarchive/test/test-test_read_too_many_filters.o `test -f 'libarchive/test/test_read_too_many_filters.c' || echo '$(srcdir)/'`libarchive/test/test_read_too_many_filters.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_too_many_filters.Tpo libarchive/test/$(DEPDIR)/test-test_read_too_many_filters.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_too_many_filters.c' object='libarchive/test/test-test_read_too_many_filters.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_too_many_filters.o `test -f 'libarchive/test/test_read_too_many_filters.c' || echo '$(srcdir)/'`libarchive/test/test_read_too_many_filters.c - -libarchive/test/test-test_read_too_many_filters.obj: libarchive/test/test_read_too_many_filters.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_too_many_filters.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_too_many_filters.Tpo -c -o libarchive/test/test-test_read_too_many_filters.obj `if test -f 'libarchive/test/test_read_too_many_filters.c'; then $(CYGPATH_W) 'libarchive/test/test_read_too_many_filters.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_too_many_filters.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_too_many_filters.Tpo libarchive/test/$(DEPDIR)/test-test_read_too_many_filters.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_too_many_filters.c' object='libarchive/test/test-test_read_too_many_filters.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_too_many_filters.obj `if test -f 'libarchive/test/test_read_too_many_filters.c'; then $(CYGPATH_W) 'libarchive/test/test_read_too_many_filters.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_too_many_filters.c'; fi` - -libarchive/test/test-test_read_truncated.o: libarchive/test/test_read_truncated.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_truncated.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_truncated.Tpo -c -o libarchive/test/test-test_read_truncated.o `test -f 'libarchive/test/test_read_truncated.c' || echo '$(srcdir)/'`libarchive/test/test_read_truncated.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_truncated.Tpo libarchive/test/$(DEPDIR)/test-test_read_truncated.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_truncated.c' object='libarchive/test/test-test_read_truncated.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_truncated.o `test -f 'libarchive/test/test_read_truncated.c' || echo '$(srcdir)/'`libarchive/test/test_read_truncated.c - -libarchive/test/test-test_read_truncated.obj: libarchive/test/test_read_truncated.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_truncated.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_truncated.Tpo -c -o libarchive/test/test-test_read_truncated.obj `if test -f 'libarchive/test/test_read_truncated.c'; then $(CYGPATH_W) 'libarchive/test/test_read_truncated.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_truncated.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_truncated.Tpo libarchive/test/$(DEPDIR)/test-test_read_truncated.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_truncated.c' object='libarchive/test/test-test_read_truncated.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_truncated.obj `if test -f 'libarchive/test/test_read_truncated.c'; then $(CYGPATH_W) 'libarchive/test/test_read_truncated.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_truncated.c'; fi` - -libarchive/test/test-test_read_truncated_filter.o: libarchive/test/test_read_truncated_filter.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_truncated_filter.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_truncated_filter.Tpo -c -o libarchive/test/test-test_read_truncated_filter.o `test -f 'libarchive/test/test_read_truncated_filter.c' || echo '$(srcdir)/'`libarchive/test/test_read_truncated_filter.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_truncated_filter.Tpo libarchive/test/$(DEPDIR)/test-test_read_truncated_filter.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_truncated_filter.c' object='libarchive/test/test-test_read_truncated_filter.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_truncated_filter.o `test -f 'libarchive/test/test_read_truncated_filter.c' || echo '$(srcdir)/'`libarchive/test/test_read_truncated_filter.c - -libarchive/test/test-test_read_truncated_filter.obj: libarchive/test/test_read_truncated_filter.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_read_truncated_filter.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_read_truncated_filter.Tpo -c -o libarchive/test/test-test_read_truncated_filter.obj `if test -f 'libarchive/test/test_read_truncated_filter.c'; then $(CYGPATH_W) 'libarchive/test/test_read_truncated_filter.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_truncated_filter.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_read_truncated_filter.Tpo libarchive/test/$(DEPDIR)/test-test_read_truncated_filter.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_read_truncated_filter.c' object='libarchive/test/test-test_read_truncated_filter.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_read_truncated_filter.obj `if test -f 'libarchive/test/test_read_truncated_filter.c'; then $(CYGPATH_W) 'libarchive/test/test_read_truncated_filter.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_read_truncated_filter.c'; fi` - -libarchive/test/test-test_short_writes.o: libarchive/test/test_short_writes.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_short_writes.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_short_writes.Tpo -c -o libarchive/test/test-test_short_writes.o `test -f 'libarchive/test/test_short_writes.c' || echo '$(srcdir)/'`libarchive/test/test_short_writes.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_short_writes.Tpo libarchive/test/$(DEPDIR)/test-test_short_writes.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_short_writes.c' object='libarchive/test/test-test_short_writes.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_short_writes.o `test -f 'libarchive/test/test_short_writes.c' || echo '$(srcdir)/'`libarchive/test/test_short_writes.c - -libarchive/test/test-test_short_writes.obj: libarchive/test/test_short_writes.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_short_writes.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_short_writes.Tpo -c -o libarchive/test/test-test_short_writes.obj `if test -f 'libarchive/test/test_short_writes.c'; then $(CYGPATH_W) 'libarchive/test/test_short_writes.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_short_writes.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_short_writes.Tpo libarchive/test/$(DEPDIR)/test-test_short_writes.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_short_writes.c' object='libarchive/test/test-test_short_writes.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_short_writes.obj `if test -f 'libarchive/test/test_short_writes.c'; then $(CYGPATH_W) 'libarchive/test/test_short_writes.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_short_writes.c'; fi` - -libarchive/test/test-test_sparse_basic.o: libarchive/test/test_sparse_basic.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_sparse_basic.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_sparse_basic.Tpo -c -o libarchive/test/test-test_sparse_basic.o `test -f 'libarchive/test/test_sparse_basic.c' || echo '$(srcdir)/'`libarchive/test/test_sparse_basic.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_sparse_basic.Tpo libarchive/test/$(DEPDIR)/test-test_sparse_basic.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_sparse_basic.c' object='libarchive/test/test-test_sparse_basic.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_sparse_basic.o `test -f 'libarchive/test/test_sparse_basic.c' || echo '$(srcdir)/'`libarchive/test/test_sparse_basic.c - -libarchive/test/test-test_sparse_basic.obj: libarchive/test/test_sparse_basic.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_sparse_basic.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_sparse_basic.Tpo -c -o libarchive/test/test-test_sparse_basic.obj `if test -f 'libarchive/test/test_sparse_basic.c'; then $(CYGPATH_W) 'libarchive/test/test_sparse_basic.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_sparse_basic.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_sparse_basic.Tpo libarchive/test/$(DEPDIR)/test-test_sparse_basic.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_sparse_basic.c' object='libarchive/test/test-test_sparse_basic.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_sparse_basic.obj `if test -f 'libarchive/test/test_sparse_basic.c'; then $(CYGPATH_W) 'libarchive/test/test_sparse_basic.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_sparse_basic.c'; fi` - -libarchive/test/test-test_tar_filenames.o: libarchive/test/test_tar_filenames.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_tar_filenames.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_tar_filenames.Tpo -c -o libarchive/test/test-test_tar_filenames.o `test -f 'libarchive/test/test_tar_filenames.c' || echo '$(srcdir)/'`libarchive/test/test_tar_filenames.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_tar_filenames.Tpo libarchive/test/$(DEPDIR)/test-test_tar_filenames.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_tar_filenames.c' object='libarchive/test/test-test_tar_filenames.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_tar_filenames.o `test -f 'libarchive/test/test_tar_filenames.c' || echo '$(srcdir)/'`libarchive/test/test_tar_filenames.c - -libarchive/test/test-test_tar_filenames.obj: libarchive/test/test_tar_filenames.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_tar_filenames.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_tar_filenames.Tpo -c -o libarchive/test/test-test_tar_filenames.obj `if test -f 'libarchive/test/test_tar_filenames.c'; then $(CYGPATH_W) 'libarchive/test/test_tar_filenames.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_tar_filenames.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_tar_filenames.Tpo libarchive/test/$(DEPDIR)/test-test_tar_filenames.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_tar_filenames.c' object='libarchive/test/test-test_tar_filenames.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_tar_filenames.obj `if test -f 'libarchive/test/test_tar_filenames.c'; then $(CYGPATH_W) 'libarchive/test/test_tar_filenames.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_tar_filenames.c'; fi` - -libarchive/test/test-test_tar_large.o: libarchive/test/test_tar_large.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_tar_large.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_tar_large.Tpo -c -o libarchive/test/test-test_tar_large.o `test -f 'libarchive/test/test_tar_large.c' || echo '$(srcdir)/'`libarchive/test/test_tar_large.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_tar_large.Tpo libarchive/test/$(DEPDIR)/test-test_tar_large.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_tar_large.c' object='libarchive/test/test-test_tar_large.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_tar_large.o `test -f 'libarchive/test/test_tar_large.c' || echo '$(srcdir)/'`libarchive/test/test_tar_large.c - -libarchive/test/test-test_tar_large.obj: libarchive/test/test_tar_large.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_tar_large.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_tar_large.Tpo -c -o libarchive/test/test-test_tar_large.obj `if test -f 'libarchive/test/test_tar_large.c'; then $(CYGPATH_W) 'libarchive/test/test_tar_large.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_tar_large.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_tar_large.Tpo libarchive/test/$(DEPDIR)/test-test_tar_large.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_tar_large.c' object='libarchive/test/test-test_tar_large.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_tar_large.obj `if test -f 'libarchive/test/test_tar_large.c'; then $(CYGPATH_W) 'libarchive/test/test_tar_large.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_tar_large.c'; fi` - -libarchive/test/test-test_ustar_filenames.o: libarchive/test/test_ustar_filenames.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_ustar_filenames.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_ustar_filenames.Tpo -c -o libarchive/test/test-test_ustar_filenames.o `test -f 'libarchive/test/test_ustar_filenames.c' || echo '$(srcdir)/'`libarchive/test/test_ustar_filenames.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_ustar_filenames.Tpo libarchive/test/$(DEPDIR)/test-test_ustar_filenames.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_ustar_filenames.c' object='libarchive/test/test-test_ustar_filenames.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_ustar_filenames.o `test -f 'libarchive/test/test_ustar_filenames.c' || echo '$(srcdir)/'`libarchive/test/test_ustar_filenames.c - -libarchive/test/test-test_ustar_filenames.obj: libarchive/test/test_ustar_filenames.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_ustar_filenames.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_ustar_filenames.Tpo -c -o libarchive/test/test-test_ustar_filenames.obj `if test -f 'libarchive/test/test_ustar_filenames.c'; then $(CYGPATH_W) 'libarchive/test/test_ustar_filenames.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_ustar_filenames.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_ustar_filenames.Tpo libarchive/test/$(DEPDIR)/test-test_ustar_filenames.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_ustar_filenames.c' object='libarchive/test/test-test_ustar_filenames.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_ustar_filenames.obj `if test -f 'libarchive/test/test_ustar_filenames.c'; then $(CYGPATH_W) 'libarchive/test/test_ustar_filenames.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_ustar_filenames.c'; fi` - -libarchive/test/test-test_ustar_filename_encoding.o: libarchive/test/test_ustar_filename_encoding.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_ustar_filename_encoding.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_ustar_filename_encoding.Tpo -c -o libarchive/test/test-test_ustar_filename_encoding.o `test -f 'libarchive/test/test_ustar_filename_encoding.c' || echo '$(srcdir)/'`libarchive/test/test_ustar_filename_encoding.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_ustar_filename_encoding.Tpo libarchive/test/$(DEPDIR)/test-test_ustar_filename_encoding.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_ustar_filename_encoding.c' object='libarchive/test/test-test_ustar_filename_encoding.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_ustar_filename_encoding.o `test -f 'libarchive/test/test_ustar_filename_encoding.c' || echo '$(srcdir)/'`libarchive/test/test_ustar_filename_encoding.c - -libarchive/test/test-test_ustar_filename_encoding.obj: libarchive/test/test_ustar_filename_encoding.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_ustar_filename_encoding.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_ustar_filename_encoding.Tpo -c -o libarchive/test/test-test_ustar_filename_encoding.obj `if test -f 'libarchive/test/test_ustar_filename_encoding.c'; then $(CYGPATH_W) 'libarchive/test/test_ustar_filename_encoding.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_ustar_filename_encoding.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_ustar_filename_encoding.Tpo libarchive/test/$(DEPDIR)/test-test_ustar_filename_encoding.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_ustar_filename_encoding.c' object='libarchive/test/test-test_ustar_filename_encoding.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_ustar_filename_encoding.obj `if test -f 'libarchive/test/test_ustar_filename_encoding.c'; then $(CYGPATH_W) 'libarchive/test/test_ustar_filename_encoding.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_ustar_filename_encoding.c'; fi` - -libarchive/test/test-test_warn_missing_hardlink_target.o: libarchive/test/test_warn_missing_hardlink_target.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_warn_missing_hardlink_target.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_warn_missing_hardlink_target.Tpo -c -o libarchive/test/test-test_warn_missing_hardlink_target.o `test -f 'libarchive/test/test_warn_missing_hardlink_target.c' || echo '$(srcdir)/'`libarchive/test/test_warn_missing_hardlink_target.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_warn_missing_hardlink_target.Tpo libarchive/test/$(DEPDIR)/test-test_warn_missing_hardlink_target.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_warn_missing_hardlink_target.c' object='libarchive/test/test-test_warn_missing_hardlink_target.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_warn_missing_hardlink_target.o `test -f 'libarchive/test/test_warn_missing_hardlink_target.c' || echo '$(srcdir)/'`libarchive/test/test_warn_missing_hardlink_target.c - -libarchive/test/test-test_warn_missing_hardlink_target.obj: libarchive/test/test_warn_missing_hardlink_target.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_warn_missing_hardlink_target.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_warn_missing_hardlink_target.Tpo -c -o libarchive/test/test-test_warn_missing_hardlink_target.obj `if test -f 'libarchive/test/test_warn_missing_hardlink_target.c'; then $(CYGPATH_W) 'libarchive/test/test_warn_missing_hardlink_target.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_warn_missing_hardlink_target.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_warn_missing_hardlink_target.Tpo libarchive/test/$(DEPDIR)/test-test_warn_missing_hardlink_target.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_warn_missing_hardlink_target.c' object='libarchive/test/test-test_warn_missing_hardlink_target.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_warn_missing_hardlink_target.obj `if test -f 'libarchive/test/test_warn_missing_hardlink_target.c'; then $(CYGPATH_W) 'libarchive/test/test_warn_missing_hardlink_target.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_warn_missing_hardlink_target.c'; fi` - -libarchive/test/test-test_write_disk.o: libarchive/test/test_write_disk.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk.Tpo -c -o libarchive/test/test-test_write_disk.o `test -f 'libarchive/test/test_write_disk.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk.c' object='libarchive/test/test-test_write_disk.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk.o `test -f 'libarchive/test/test_write_disk.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk.c - -libarchive/test/test-test_write_disk.obj: libarchive/test/test_write_disk.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk.Tpo -c -o libarchive/test/test-test_write_disk.obj `if test -f 'libarchive/test/test_write_disk.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk.c' object='libarchive/test/test-test_write_disk.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk.obj `if test -f 'libarchive/test/test_write_disk.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk.c'; fi` - -libarchive/test/test-test_write_disk_appledouble.o: libarchive/test/test_write_disk_appledouble.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_appledouble.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_appledouble.Tpo -c -o libarchive/test/test-test_write_disk_appledouble.o `test -f 'libarchive/test/test_write_disk_appledouble.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_appledouble.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_appledouble.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_appledouble.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_appledouble.c' object='libarchive/test/test-test_write_disk_appledouble.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_appledouble.o `test -f 'libarchive/test/test_write_disk_appledouble.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_appledouble.c - -libarchive/test/test-test_write_disk_appledouble.obj: libarchive/test/test_write_disk_appledouble.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_appledouble.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_appledouble.Tpo -c -o libarchive/test/test-test_write_disk_appledouble.obj `if test -f 'libarchive/test/test_write_disk_appledouble.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_appledouble.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_appledouble.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_appledouble.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_appledouble.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_appledouble.c' object='libarchive/test/test-test_write_disk_appledouble.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_appledouble.obj `if test -f 'libarchive/test/test_write_disk_appledouble.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_appledouble.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_appledouble.c'; fi` - -libarchive/test/test-test_write_disk_failures.o: libarchive/test/test_write_disk_failures.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_failures.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_failures.Tpo -c -o libarchive/test/test-test_write_disk_failures.o `test -f 'libarchive/test/test_write_disk_failures.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_failures.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_failures.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_failures.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_failures.c' object='libarchive/test/test-test_write_disk_failures.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_failures.o `test -f 'libarchive/test/test_write_disk_failures.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_failures.c - -libarchive/test/test-test_write_disk_failures.obj: libarchive/test/test_write_disk_failures.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_failures.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_failures.Tpo -c -o libarchive/test/test-test_write_disk_failures.obj `if test -f 'libarchive/test/test_write_disk_failures.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_failures.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_failures.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_failures.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_failures.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_failures.c' object='libarchive/test/test-test_write_disk_failures.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_failures.obj `if test -f 'libarchive/test/test_write_disk_failures.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_failures.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_failures.c'; fi` - -libarchive/test/test-test_write_disk_fixup.o: libarchive/test/test_write_disk_fixup.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_fixup.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_fixup.Tpo -c -o libarchive/test/test-test_write_disk_fixup.o `test -f 'libarchive/test/test_write_disk_fixup.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_fixup.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_fixup.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_fixup.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_fixup.c' object='libarchive/test/test-test_write_disk_fixup.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_fixup.o `test -f 'libarchive/test/test_write_disk_fixup.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_fixup.c - -libarchive/test/test-test_write_disk_fixup.obj: libarchive/test/test_write_disk_fixup.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_fixup.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_fixup.Tpo -c -o libarchive/test/test-test_write_disk_fixup.obj `if test -f 'libarchive/test/test_write_disk_fixup.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_fixup.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_fixup.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_fixup.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_fixup.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_fixup.c' object='libarchive/test/test-test_write_disk_fixup.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_fixup.obj `if test -f 'libarchive/test/test_write_disk_fixup.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_fixup.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_fixup.c'; fi` - -libarchive/test/test-test_write_disk_hardlink.o: libarchive/test/test_write_disk_hardlink.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_hardlink.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_hardlink.Tpo -c -o libarchive/test/test-test_write_disk_hardlink.o `test -f 'libarchive/test/test_write_disk_hardlink.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_hardlink.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_hardlink.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_hardlink.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_hardlink.c' object='libarchive/test/test-test_write_disk_hardlink.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_hardlink.o `test -f 'libarchive/test/test_write_disk_hardlink.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_hardlink.c - -libarchive/test/test-test_write_disk_hardlink.obj: libarchive/test/test_write_disk_hardlink.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_hardlink.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_hardlink.Tpo -c -o libarchive/test/test-test_write_disk_hardlink.obj `if test -f 'libarchive/test/test_write_disk_hardlink.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_hardlink.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_hardlink.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_hardlink.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_hardlink.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_hardlink.c' object='libarchive/test/test-test_write_disk_hardlink.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_hardlink.obj `if test -f 'libarchive/test/test_write_disk_hardlink.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_hardlink.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_hardlink.c'; fi` - -libarchive/test/test-test_write_disk_hfs_compression.o: libarchive/test/test_write_disk_hfs_compression.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_hfs_compression.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_hfs_compression.Tpo -c -o libarchive/test/test-test_write_disk_hfs_compression.o `test -f 'libarchive/test/test_write_disk_hfs_compression.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_hfs_compression.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_hfs_compression.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_hfs_compression.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_hfs_compression.c' object='libarchive/test/test-test_write_disk_hfs_compression.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_hfs_compression.o `test -f 'libarchive/test/test_write_disk_hfs_compression.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_hfs_compression.c - -libarchive/test/test-test_write_disk_hfs_compression.obj: libarchive/test/test_write_disk_hfs_compression.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_hfs_compression.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_hfs_compression.Tpo -c -o libarchive/test/test-test_write_disk_hfs_compression.obj `if test -f 'libarchive/test/test_write_disk_hfs_compression.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_hfs_compression.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_hfs_compression.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_hfs_compression.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_hfs_compression.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_hfs_compression.c' object='libarchive/test/test-test_write_disk_hfs_compression.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_hfs_compression.obj `if test -f 'libarchive/test/test_write_disk_hfs_compression.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_hfs_compression.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_hfs_compression.c'; fi` - -libarchive/test/test-test_write_disk_lookup.o: libarchive/test/test_write_disk_lookup.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_lookup.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_lookup.Tpo -c -o libarchive/test/test-test_write_disk_lookup.o `test -f 'libarchive/test/test_write_disk_lookup.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_lookup.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_lookup.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_lookup.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_lookup.c' object='libarchive/test/test-test_write_disk_lookup.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_lookup.o `test -f 'libarchive/test/test_write_disk_lookup.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_lookup.c - -libarchive/test/test-test_write_disk_lookup.obj: libarchive/test/test_write_disk_lookup.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_lookup.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_lookup.Tpo -c -o libarchive/test/test-test_write_disk_lookup.obj `if test -f 'libarchive/test/test_write_disk_lookup.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_lookup.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_lookup.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_lookup.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_lookup.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_lookup.c' object='libarchive/test/test-test_write_disk_lookup.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_lookup.obj `if test -f 'libarchive/test/test_write_disk_lookup.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_lookup.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_lookup.c'; fi` - -libarchive/test/test-test_write_disk_mac_metadata.o: libarchive/test/test_write_disk_mac_metadata.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_mac_metadata.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_mac_metadata.Tpo -c -o libarchive/test/test-test_write_disk_mac_metadata.o `test -f 'libarchive/test/test_write_disk_mac_metadata.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_mac_metadata.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_mac_metadata.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_mac_metadata.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_mac_metadata.c' object='libarchive/test/test-test_write_disk_mac_metadata.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_mac_metadata.o `test -f 'libarchive/test/test_write_disk_mac_metadata.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_mac_metadata.c - -libarchive/test/test-test_write_disk_mac_metadata.obj: libarchive/test/test_write_disk_mac_metadata.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_mac_metadata.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_mac_metadata.Tpo -c -o libarchive/test/test-test_write_disk_mac_metadata.obj `if test -f 'libarchive/test/test_write_disk_mac_metadata.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_mac_metadata.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_mac_metadata.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_mac_metadata.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_mac_metadata.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_mac_metadata.c' object='libarchive/test/test-test_write_disk_mac_metadata.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_mac_metadata.obj `if test -f 'libarchive/test/test_write_disk_mac_metadata.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_mac_metadata.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_mac_metadata.c'; fi` - -libarchive/test/test-test_write_disk_no_hfs_compression.o: libarchive/test/test_write_disk_no_hfs_compression.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_no_hfs_compression.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_no_hfs_compression.Tpo -c -o libarchive/test/test-test_write_disk_no_hfs_compression.o `test -f 'libarchive/test/test_write_disk_no_hfs_compression.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_no_hfs_compression.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_no_hfs_compression.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_no_hfs_compression.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_no_hfs_compression.c' object='libarchive/test/test-test_write_disk_no_hfs_compression.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_no_hfs_compression.o `test -f 'libarchive/test/test_write_disk_no_hfs_compression.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_no_hfs_compression.c - -libarchive/test/test-test_write_disk_no_hfs_compression.obj: libarchive/test/test_write_disk_no_hfs_compression.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_no_hfs_compression.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_no_hfs_compression.Tpo -c -o libarchive/test/test-test_write_disk_no_hfs_compression.obj `if test -f 'libarchive/test/test_write_disk_no_hfs_compression.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_no_hfs_compression.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_no_hfs_compression.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_no_hfs_compression.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_no_hfs_compression.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_no_hfs_compression.c' object='libarchive/test/test-test_write_disk_no_hfs_compression.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_no_hfs_compression.obj `if test -f 'libarchive/test/test_write_disk_no_hfs_compression.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_no_hfs_compression.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_no_hfs_compression.c'; fi` - -libarchive/test/test-test_write_disk_perms.o: libarchive/test/test_write_disk_perms.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_perms.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_perms.Tpo -c -o libarchive/test/test-test_write_disk_perms.o `test -f 'libarchive/test/test_write_disk_perms.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_perms.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_perms.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_perms.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_perms.c' object='libarchive/test/test-test_write_disk_perms.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_perms.o `test -f 'libarchive/test/test_write_disk_perms.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_perms.c - -libarchive/test/test-test_write_disk_perms.obj: libarchive/test/test_write_disk_perms.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_perms.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_perms.Tpo -c -o libarchive/test/test-test_write_disk_perms.obj `if test -f 'libarchive/test/test_write_disk_perms.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_perms.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_perms.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_perms.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_perms.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_perms.c' object='libarchive/test/test-test_write_disk_perms.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_perms.obj `if test -f 'libarchive/test/test_write_disk_perms.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_perms.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_perms.c'; fi` - -libarchive/test/test-test_write_disk_secure.o: libarchive/test/test_write_disk_secure.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_secure.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_secure.Tpo -c -o libarchive/test/test-test_write_disk_secure.o `test -f 'libarchive/test/test_write_disk_secure.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_secure.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_secure.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_secure.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_secure.c' object='libarchive/test/test-test_write_disk_secure.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_secure.o `test -f 'libarchive/test/test_write_disk_secure.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_secure.c - -libarchive/test/test-test_write_disk_secure.obj: libarchive/test/test_write_disk_secure.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_secure.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_secure.Tpo -c -o libarchive/test/test-test_write_disk_secure.obj `if test -f 'libarchive/test/test_write_disk_secure.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_secure.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_secure.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_secure.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_secure.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_secure.c' object='libarchive/test/test-test_write_disk_secure.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_secure.obj `if test -f 'libarchive/test/test_write_disk_secure.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_secure.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_secure.c'; fi` - -libarchive/test/test-test_write_disk_secure744.o: libarchive/test/test_write_disk_secure744.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_secure744.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_secure744.Tpo -c -o libarchive/test/test-test_write_disk_secure744.o `test -f 'libarchive/test/test_write_disk_secure744.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_secure744.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_secure744.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_secure744.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_secure744.c' object='libarchive/test/test-test_write_disk_secure744.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_secure744.o `test -f 'libarchive/test/test_write_disk_secure744.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_secure744.c - -libarchive/test/test-test_write_disk_secure744.obj: libarchive/test/test_write_disk_secure744.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_secure744.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_secure744.Tpo -c -o libarchive/test/test-test_write_disk_secure744.obj `if test -f 'libarchive/test/test_write_disk_secure744.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_secure744.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_secure744.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_secure744.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_secure744.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_secure744.c' object='libarchive/test/test-test_write_disk_secure744.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_secure744.obj `if test -f 'libarchive/test/test_write_disk_secure744.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_secure744.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_secure744.c'; fi` - -libarchive/test/test-test_write_disk_secure745.o: libarchive/test/test_write_disk_secure745.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_secure745.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_secure745.Tpo -c -o libarchive/test/test-test_write_disk_secure745.o `test -f 'libarchive/test/test_write_disk_secure745.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_secure745.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_secure745.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_secure745.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_secure745.c' object='libarchive/test/test-test_write_disk_secure745.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_secure745.o `test -f 'libarchive/test/test_write_disk_secure745.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_secure745.c - -libarchive/test/test-test_write_disk_secure745.obj: libarchive/test/test_write_disk_secure745.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_secure745.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_secure745.Tpo -c -o libarchive/test/test-test_write_disk_secure745.obj `if test -f 'libarchive/test/test_write_disk_secure745.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_secure745.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_secure745.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_secure745.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_secure745.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_secure745.c' object='libarchive/test/test-test_write_disk_secure745.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_secure745.obj `if test -f 'libarchive/test/test_write_disk_secure745.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_secure745.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_secure745.c'; fi` - -libarchive/test/test-test_write_disk_secure746.o: libarchive/test/test_write_disk_secure746.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_secure746.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_secure746.Tpo -c -o libarchive/test/test-test_write_disk_secure746.o `test -f 'libarchive/test/test_write_disk_secure746.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_secure746.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_secure746.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_secure746.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_secure746.c' object='libarchive/test/test-test_write_disk_secure746.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_secure746.o `test -f 'libarchive/test/test_write_disk_secure746.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_secure746.c - -libarchive/test/test-test_write_disk_secure746.obj: libarchive/test/test_write_disk_secure746.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_secure746.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_secure746.Tpo -c -o libarchive/test/test-test_write_disk_secure746.obj `if test -f 'libarchive/test/test_write_disk_secure746.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_secure746.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_secure746.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_secure746.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_secure746.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_secure746.c' object='libarchive/test/test-test_write_disk_secure746.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_secure746.obj `if test -f 'libarchive/test/test_write_disk_secure746.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_secure746.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_secure746.c'; fi` - -libarchive/test/test-test_write_disk_sparse.o: libarchive/test/test_write_disk_sparse.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_sparse.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_sparse.Tpo -c -o libarchive/test/test-test_write_disk_sparse.o `test -f 'libarchive/test/test_write_disk_sparse.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_sparse.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_sparse.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_sparse.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_sparse.c' object='libarchive/test/test-test_write_disk_sparse.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_sparse.o `test -f 'libarchive/test/test_write_disk_sparse.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_sparse.c - -libarchive/test/test-test_write_disk_sparse.obj: libarchive/test/test_write_disk_sparse.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_sparse.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_sparse.Tpo -c -o libarchive/test/test-test_write_disk_sparse.obj `if test -f 'libarchive/test/test_write_disk_sparse.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_sparse.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_sparse.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_sparse.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_sparse.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_sparse.c' object='libarchive/test/test-test_write_disk_sparse.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_sparse.obj `if test -f 'libarchive/test/test_write_disk_sparse.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_sparse.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_sparse.c'; fi` - -libarchive/test/test-test_write_disk_symlink.o: libarchive/test/test_write_disk_symlink.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_symlink.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_symlink.Tpo -c -o libarchive/test/test-test_write_disk_symlink.o `test -f 'libarchive/test/test_write_disk_symlink.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_symlink.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_symlink.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_symlink.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_symlink.c' object='libarchive/test/test-test_write_disk_symlink.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_symlink.o `test -f 'libarchive/test/test_write_disk_symlink.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_symlink.c - -libarchive/test/test-test_write_disk_symlink.obj: libarchive/test/test_write_disk_symlink.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_symlink.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_symlink.Tpo -c -o libarchive/test/test-test_write_disk_symlink.obj `if test -f 'libarchive/test/test_write_disk_symlink.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_symlink.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_symlink.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_symlink.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_symlink.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_symlink.c' object='libarchive/test/test-test_write_disk_symlink.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_symlink.obj `if test -f 'libarchive/test/test_write_disk_symlink.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_symlink.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_symlink.c'; fi` - -libarchive/test/test-test_write_disk_times.o: libarchive/test/test_write_disk_times.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_times.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_times.Tpo -c -o libarchive/test/test-test_write_disk_times.o `test -f 'libarchive/test/test_write_disk_times.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_times.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_times.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_times.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_times.c' object='libarchive/test/test-test_write_disk_times.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_times.o `test -f 'libarchive/test/test_write_disk_times.c' || echo '$(srcdir)/'`libarchive/test/test_write_disk_times.c - -libarchive/test/test-test_write_disk_times.obj: libarchive/test/test_write_disk_times.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_disk_times.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_disk_times.Tpo -c -o libarchive/test/test-test_write_disk_times.obj `if test -f 'libarchive/test/test_write_disk_times.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_times.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_times.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_disk_times.Tpo libarchive/test/$(DEPDIR)/test-test_write_disk_times.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_disk_times.c' object='libarchive/test/test-test_write_disk_times.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_disk_times.obj `if test -f 'libarchive/test/test_write_disk_times.c'; then $(CYGPATH_W) 'libarchive/test/test_write_disk_times.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_disk_times.c'; fi` - -libarchive/test/test-test_write_filter_b64encode.o: libarchive/test/test_write_filter_b64encode.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_b64encode.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_b64encode.Tpo -c -o libarchive/test/test-test_write_filter_b64encode.o `test -f 'libarchive/test/test_write_filter_b64encode.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_b64encode.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_b64encode.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_b64encode.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_b64encode.c' object='libarchive/test/test-test_write_filter_b64encode.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_b64encode.o `test -f 'libarchive/test/test_write_filter_b64encode.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_b64encode.c - -libarchive/test/test-test_write_filter_b64encode.obj: libarchive/test/test_write_filter_b64encode.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_b64encode.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_b64encode.Tpo -c -o libarchive/test/test-test_write_filter_b64encode.obj `if test -f 'libarchive/test/test_write_filter_b64encode.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_b64encode.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_b64encode.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_b64encode.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_b64encode.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_b64encode.c' object='libarchive/test/test-test_write_filter_b64encode.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_b64encode.obj `if test -f 'libarchive/test/test_write_filter_b64encode.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_b64encode.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_b64encode.c'; fi` - -libarchive/test/test-test_write_filter_bzip2.o: libarchive/test/test_write_filter_bzip2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_bzip2.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_bzip2.Tpo -c -o libarchive/test/test-test_write_filter_bzip2.o `test -f 'libarchive/test/test_write_filter_bzip2.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_bzip2.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_bzip2.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_bzip2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_bzip2.c' object='libarchive/test/test-test_write_filter_bzip2.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_bzip2.o `test -f 'libarchive/test/test_write_filter_bzip2.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_bzip2.c - -libarchive/test/test-test_write_filter_bzip2.obj: libarchive/test/test_write_filter_bzip2.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_bzip2.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_bzip2.Tpo -c -o libarchive/test/test-test_write_filter_bzip2.obj `if test -f 'libarchive/test/test_write_filter_bzip2.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_bzip2.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_bzip2.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_bzip2.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_bzip2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_bzip2.c' object='libarchive/test/test-test_write_filter_bzip2.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_bzip2.obj `if test -f 'libarchive/test/test_write_filter_bzip2.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_bzip2.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_bzip2.c'; fi` - -libarchive/test/test-test_write_filter_compress.o: libarchive/test/test_write_filter_compress.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_compress.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_compress.Tpo -c -o libarchive/test/test-test_write_filter_compress.o `test -f 'libarchive/test/test_write_filter_compress.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_compress.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_compress.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_compress.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_compress.c' object='libarchive/test/test-test_write_filter_compress.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_compress.o `test -f 'libarchive/test/test_write_filter_compress.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_compress.c - -libarchive/test/test-test_write_filter_compress.obj: libarchive/test/test_write_filter_compress.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_compress.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_compress.Tpo -c -o libarchive/test/test-test_write_filter_compress.obj `if test -f 'libarchive/test/test_write_filter_compress.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_compress.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_compress.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_compress.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_compress.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_compress.c' object='libarchive/test/test-test_write_filter_compress.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_compress.obj `if test -f 'libarchive/test/test_write_filter_compress.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_compress.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_compress.c'; fi` - -libarchive/test/test-test_write_filter_gzip.o: libarchive/test/test_write_filter_gzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_gzip.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_gzip.Tpo -c -o libarchive/test/test-test_write_filter_gzip.o `test -f 'libarchive/test/test_write_filter_gzip.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_gzip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_gzip.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_gzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_gzip.c' object='libarchive/test/test-test_write_filter_gzip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_gzip.o `test -f 'libarchive/test/test_write_filter_gzip.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_gzip.c - -libarchive/test/test-test_write_filter_gzip.obj: libarchive/test/test_write_filter_gzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_gzip.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_gzip.Tpo -c -o libarchive/test/test-test_write_filter_gzip.obj `if test -f 'libarchive/test/test_write_filter_gzip.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_gzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_gzip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_gzip.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_gzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_gzip.c' object='libarchive/test/test-test_write_filter_gzip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_gzip.obj `if test -f 'libarchive/test/test_write_filter_gzip.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_gzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_gzip.c'; fi` - -libarchive/test/test-test_write_filter_gzip_timestamp.o: libarchive/test/test_write_filter_gzip_timestamp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_gzip_timestamp.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_gzip_timestamp.Tpo -c -o libarchive/test/test-test_write_filter_gzip_timestamp.o `test -f 'libarchive/test/test_write_filter_gzip_timestamp.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_gzip_timestamp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_gzip_timestamp.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_gzip_timestamp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_gzip_timestamp.c' object='libarchive/test/test-test_write_filter_gzip_timestamp.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_gzip_timestamp.o `test -f 'libarchive/test/test_write_filter_gzip_timestamp.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_gzip_timestamp.c - -libarchive/test/test-test_write_filter_gzip_timestamp.obj: libarchive/test/test_write_filter_gzip_timestamp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_gzip_timestamp.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_gzip_timestamp.Tpo -c -o libarchive/test/test-test_write_filter_gzip_timestamp.obj `if test -f 'libarchive/test/test_write_filter_gzip_timestamp.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_gzip_timestamp.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_gzip_timestamp.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_gzip_timestamp.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_gzip_timestamp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_gzip_timestamp.c' object='libarchive/test/test-test_write_filter_gzip_timestamp.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_gzip_timestamp.obj `if test -f 'libarchive/test/test_write_filter_gzip_timestamp.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_gzip_timestamp.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_gzip_timestamp.c'; fi` - -libarchive/test/test-test_write_filter_lrzip.o: libarchive/test/test_write_filter_lrzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_lrzip.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_lrzip.Tpo -c -o libarchive/test/test-test_write_filter_lrzip.o `test -f 'libarchive/test/test_write_filter_lrzip.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_lrzip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_lrzip.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_lrzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_lrzip.c' object='libarchive/test/test-test_write_filter_lrzip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_lrzip.o `test -f 'libarchive/test/test_write_filter_lrzip.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_lrzip.c - -libarchive/test/test-test_write_filter_lrzip.obj: libarchive/test/test_write_filter_lrzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_lrzip.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_lrzip.Tpo -c -o libarchive/test/test-test_write_filter_lrzip.obj `if test -f 'libarchive/test/test_write_filter_lrzip.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_lrzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_lrzip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_lrzip.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_lrzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_lrzip.c' object='libarchive/test/test-test_write_filter_lrzip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_lrzip.obj `if test -f 'libarchive/test/test_write_filter_lrzip.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_lrzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_lrzip.c'; fi` - -libarchive/test/test-test_write_filter_lz4.o: libarchive/test/test_write_filter_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_lz4.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_lz4.Tpo -c -o libarchive/test/test-test_write_filter_lz4.o `test -f 'libarchive/test/test_write_filter_lz4.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_lz4.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_lz4.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_lz4.c' object='libarchive/test/test-test_write_filter_lz4.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_lz4.o `test -f 'libarchive/test/test_write_filter_lz4.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_lz4.c - -libarchive/test/test-test_write_filter_lz4.obj: libarchive/test/test_write_filter_lz4.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_lz4.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_lz4.Tpo -c -o libarchive/test/test-test_write_filter_lz4.obj `if test -f 'libarchive/test/test_write_filter_lz4.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_lz4.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_lz4.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_lz4.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_lz4.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_lz4.c' object='libarchive/test/test-test_write_filter_lz4.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_lz4.obj `if test -f 'libarchive/test/test_write_filter_lz4.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_lz4.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_lz4.c'; fi` - -libarchive/test/test-test_write_filter_lzip.o: libarchive/test/test_write_filter_lzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_lzip.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_lzip.Tpo -c -o libarchive/test/test-test_write_filter_lzip.o `test -f 'libarchive/test/test_write_filter_lzip.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_lzip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_lzip.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_lzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_lzip.c' object='libarchive/test/test-test_write_filter_lzip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_lzip.o `test -f 'libarchive/test/test_write_filter_lzip.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_lzip.c - -libarchive/test/test-test_write_filter_lzip.obj: libarchive/test/test_write_filter_lzip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_lzip.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_lzip.Tpo -c -o libarchive/test/test-test_write_filter_lzip.obj `if test -f 'libarchive/test/test_write_filter_lzip.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_lzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_lzip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_lzip.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_lzip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_lzip.c' object='libarchive/test/test-test_write_filter_lzip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_lzip.obj `if test -f 'libarchive/test/test_write_filter_lzip.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_lzip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_lzip.c'; fi` - -libarchive/test/test-test_write_filter_lzma.o: libarchive/test/test_write_filter_lzma.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_lzma.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_lzma.Tpo -c -o libarchive/test/test-test_write_filter_lzma.o `test -f 'libarchive/test/test_write_filter_lzma.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_lzma.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_lzma.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_lzma.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_lzma.c' object='libarchive/test/test-test_write_filter_lzma.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_lzma.o `test -f 'libarchive/test/test_write_filter_lzma.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_lzma.c - -libarchive/test/test-test_write_filter_lzma.obj: libarchive/test/test_write_filter_lzma.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_lzma.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_lzma.Tpo -c -o libarchive/test/test-test_write_filter_lzma.obj `if test -f 'libarchive/test/test_write_filter_lzma.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_lzma.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_lzma.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_lzma.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_lzma.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_lzma.c' object='libarchive/test/test-test_write_filter_lzma.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_lzma.obj `if test -f 'libarchive/test/test_write_filter_lzma.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_lzma.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_lzma.c'; fi` - -libarchive/test/test-test_write_filter_lzop.o: libarchive/test/test_write_filter_lzop.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_lzop.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_lzop.Tpo -c -o libarchive/test/test-test_write_filter_lzop.o `test -f 'libarchive/test/test_write_filter_lzop.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_lzop.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_lzop.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_lzop.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_lzop.c' object='libarchive/test/test-test_write_filter_lzop.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_lzop.o `test -f 'libarchive/test/test_write_filter_lzop.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_lzop.c - -libarchive/test/test-test_write_filter_lzop.obj: libarchive/test/test_write_filter_lzop.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_lzop.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_lzop.Tpo -c -o libarchive/test/test-test_write_filter_lzop.obj `if test -f 'libarchive/test/test_write_filter_lzop.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_lzop.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_lzop.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_lzop.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_lzop.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_lzop.c' object='libarchive/test/test-test_write_filter_lzop.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_lzop.obj `if test -f 'libarchive/test/test_write_filter_lzop.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_lzop.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_lzop.c'; fi` - -libarchive/test/test-test_write_filter_program.o: libarchive/test/test_write_filter_program.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_program.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_program.Tpo -c -o libarchive/test/test-test_write_filter_program.o `test -f 'libarchive/test/test_write_filter_program.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_program.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_program.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_program.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_program.c' object='libarchive/test/test-test_write_filter_program.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_program.o `test -f 'libarchive/test/test_write_filter_program.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_program.c - -libarchive/test/test-test_write_filter_program.obj: libarchive/test/test_write_filter_program.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_program.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_program.Tpo -c -o libarchive/test/test-test_write_filter_program.obj `if test -f 'libarchive/test/test_write_filter_program.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_program.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_program.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_program.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_program.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_program.c' object='libarchive/test/test-test_write_filter_program.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_program.obj `if test -f 'libarchive/test/test_write_filter_program.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_program.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_program.c'; fi` - -libarchive/test/test-test_write_filter_uuencode.o: libarchive/test/test_write_filter_uuencode.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_uuencode.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_uuencode.Tpo -c -o libarchive/test/test-test_write_filter_uuencode.o `test -f 'libarchive/test/test_write_filter_uuencode.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_uuencode.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_uuencode.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_uuencode.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_uuencode.c' object='libarchive/test/test-test_write_filter_uuencode.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_uuencode.o `test -f 'libarchive/test/test_write_filter_uuencode.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_uuencode.c - -libarchive/test/test-test_write_filter_uuencode.obj: libarchive/test/test_write_filter_uuencode.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_uuencode.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_uuencode.Tpo -c -o libarchive/test/test-test_write_filter_uuencode.obj `if test -f 'libarchive/test/test_write_filter_uuencode.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_uuencode.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_uuencode.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_uuencode.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_uuencode.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_uuencode.c' object='libarchive/test/test-test_write_filter_uuencode.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_uuencode.obj `if test -f 'libarchive/test/test_write_filter_uuencode.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_uuencode.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_uuencode.c'; fi` - -libarchive/test/test-test_write_filter_xz.o: libarchive/test/test_write_filter_xz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_xz.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_xz.Tpo -c -o libarchive/test/test-test_write_filter_xz.o `test -f 'libarchive/test/test_write_filter_xz.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_xz.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_xz.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_xz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_xz.c' object='libarchive/test/test-test_write_filter_xz.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_xz.o `test -f 'libarchive/test/test_write_filter_xz.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_xz.c - -libarchive/test/test-test_write_filter_xz.obj: libarchive/test/test_write_filter_xz.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_xz.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_xz.Tpo -c -o libarchive/test/test-test_write_filter_xz.obj `if test -f 'libarchive/test/test_write_filter_xz.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_xz.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_xz.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_xz.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_xz.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_xz.c' object='libarchive/test/test-test_write_filter_xz.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_xz.obj `if test -f 'libarchive/test/test_write_filter_xz.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_xz.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_xz.c'; fi` - -libarchive/test/test-test_write_filter_zstd.o: libarchive/test/test_write_filter_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_zstd.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_zstd.Tpo -c -o libarchive/test/test-test_write_filter_zstd.o `test -f 'libarchive/test/test_write_filter_zstd.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_zstd.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_zstd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_zstd.c' object='libarchive/test/test-test_write_filter_zstd.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_zstd.o `test -f 'libarchive/test/test_write_filter_zstd.c' || echo '$(srcdir)/'`libarchive/test/test_write_filter_zstd.c - -libarchive/test/test-test_write_filter_zstd.obj: libarchive/test/test_write_filter_zstd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_filter_zstd.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_filter_zstd.Tpo -c -o libarchive/test/test-test_write_filter_zstd.obj `if test -f 'libarchive/test/test_write_filter_zstd.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_zstd.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_zstd.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_filter_zstd.Tpo libarchive/test/$(DEPDIR)/test-test_write_filter_zstd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_filter_zstd.c' object='libarchive/test/test-test_write_filter_zstd.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_filter_zstd.obj `if test -f 'libarchive/test/test_write_filter_zstd.c'; then $(CYGPATH_W) 'libarchive/test/test_write_filter_zstd.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_filter_zstd.c'; fi` - -libarchive/test/test-test_write_format_7zip.o: libarchive/test/test_write_format_7zip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_7zip.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_7zip.Tpo -c -o libarchive/test/test-test_write_format_7zip.o `test -f 'libarchive/test/test_write_format_7zip.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_7zip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_7zip.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_7zip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_7zip.c' object='libarchive/test/test-test_write_format_7zip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_7zip.o `test -f 'libarchive/test/test_write_format_7zip.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_7zip.c - -libarchive/test/test-test_write_format_7zip.obj: libarchive/test/test_write_format_7zip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_7zip.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_7zip.Tpo -c -o libarchive/test/test-test_write_format_7zip.obj `if test -f 'libarchive/test/test_write_format_7zip.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_7zip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_7zip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_7zip.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_7zip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_7zip.c' object='libarchive/test/test-test_write_format_7zip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_7zip.obj `if test -f 'libarchive/test/test_write_format_7zip.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_7zip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_7zip.c'; fi` - -libarchive/test/test-test_write_format_7zip_empty.o: libarchive/test/test_write_format_7zip_empty.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_7zip_empty.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_7zip_empty.Tpo -c -o libarchive/test/test-test_write_format_7zip_empty.o `test -f 'libarchive/test/test_write_format_7zip_empty.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_7zip_empty.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_7zip_empty.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_7zip_empty.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_7zip_empty.c' object='libarchive/test/test-test_write_format_7zip_empty.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_7zip_empty.o `test -f 'libarchive/test/test_write_format_7zip_empty.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_7zip_empty.c - -libarchive/test/test-test_write_format_7zip_empty.obj: libarchive/test/test_write_format_7zip_empty.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_7zip_empty.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_7zip_empty.Tpo -c -o libarchive/test/test-test_write_format_7zip_empty.obj `if test -f 'libarchive/test/test_write_format_7zip_empty.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_7zip_empty.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_7zip_empty.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_7zip_empty.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_7zip_empty.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_7zip_empty.c' object='libarchive/test/test-test_write_format_7zip_empty.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_7zip_empty.obj `if test -f 'libarchive/test/test_write_format_7zip_empty.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_7zip_empty.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_7zip_empty.c'; fi` - -libarchive/test/test-test_write_format_7zip_large.o: libarchive/test/test_write_format_7zip_large.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_7zip_large.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_7zip_large.Tpo -c -o libarchive/test/test-test_write_format_7zip_large.o `test -f 'libarchive/test/test_write_format_7zip_large.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_7zip_large.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_7zip_large.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_7zip_large.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_7zip_large.c' object='libarchive/test/test-test_write_format_7zip_large.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_7zip_large.o `test -f 'libarchive/test/test_write_format_7zip_large.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_7zip_large.c - -libarchive/test/test-test_write_format_7zip_large.obj: libarchive/test/test_write_format_7zip_large.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_7zip_large.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_7zip_large.Tpo -c -o libarchive/test/test-test_write_format_7zip_large.obj `if test -f 'libarchive/test/test_write_format_7zip_large.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_7zip_large.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_7zip_large.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_7zip_large.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_7zip_large.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_7zip_large.c' object='libarchive/test/test-test_write_format_7zip_large.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_7zip_large.obj `if test -f 'libarchive/test/test_write_format_7zip_large.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_7zip_large.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_7zip_large.c'; fi` - -libarchive/test/test-test_write_format_ar.o: libarchive/test/test_write_format_ar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_ar.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_ar.Tpo -c -o libarchive/test/test-test_write_format_ar.o `test -f 'libarchive/test/test_write_format_ar.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_ar.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_ar.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_ar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_ar.c' object='libarchive/test/test-test_write_format_ar.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_ar.o `test -f 'libarchive/test/test_write_format_ar.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_ar.c - -libarchive/test/test-test_write_format_ar.obj: libarchive/test/test_write_format_ar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_ar.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_ar.Tpo -c -o libarchive/test/test-test_write_format_ar.obj `if test -f 'libarchive/test/test_write_format_ar.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_ar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_ar.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_ar.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_ar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_ar.c' object='libarchive/test/test-test_write_format_ar.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_ar.obj `if test -f 'libarchive/test/test_write_format_ar.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_ar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_ar.c'; fi` - -libarchive/test/test-test_write_format_cpio.o: libarchive/test/test_write_format_cpio.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_cpio.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_cpio.Tpo -c -o libarchive/test/test-test_write_format_cpio.o `test -f 'libarchive/test/test_write_format_cpio.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_cpio.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_cpio.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_cpio.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_cpio.c' object='libarchive/test/test-test_write_format_cpio.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_cpio.o `test -f 'libarchive/test/test_write_format_cpio.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_cpio.c - -libarchive/test/test-test_write_format_cpio.obj: libarchive/test/test_write_format_cpio.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_cpio.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_cpio.Tpo -c -o libarchive/test/test-test_write_format_cpio.obj `if test -f 'libarchive/test/test_write_format_cpio.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_cpio.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_cpio.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_cpio.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_cpio.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_cpio.c' object='libarchive/test/test-test_write_format_cpio.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_cpio.obj `if test -f 'libarchive/test/test_write_format_cpio.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_cpio.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_cpio.c'; fi` - -libarchive/test/test-test_write_format_cpio_empty.o: libarchive/test/test_write_format_cpio_empty.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_cpio_empty.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_cpio_empty.Tpo -c -o libarchive/test/test-test_write_format_cpio_empty.o `test -f 'libarchive/test/test_write_format_cpio_empty.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_cpio_empty.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_cpio_empty.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_cpio_empty.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_cpio_empty.c' object='libarchive/test/test-test_write_format_cpio_empty.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_cpio_empty.o `test -f 'libarchive/test/test_write_format_cpio_empty.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_cpio_empty.c - -libarchive/test/test-test_write_format_cpio_empty.obj: libarchive/test/test_write_format_cpio_empty.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_cpio_empty.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_cpio_empty.Tpo -c -o libarchive/test/test-test_write_format_cpio_empty.obj `if test -f 'libarchive/test/test_write_format_cpio_empty.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_cpio_empty.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_cpio_empty.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_cpio_empty.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_cpio_empty.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_cpio_empty.c' object='libarchive/test/test-test_write_format_cpio_empty.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_cpio_empty.obj `if test -f 'libarchive/test/test_write_format_cpio_empty.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_cpio_empty.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_cpio_empty.c'; fi` - -libarchive/test/test-test_write_format_cpio_newc.o: libarchive/test/test_write_format_cpio_newc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_cpio_newc.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_cpio_newc.Tpo -c -o libarchive/test/test-test_write_format_cpio_newc.o `test -f 'libarchive/test/test_write_format_cpio_newc.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_cpio_newc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_cpio_newc.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_cpio_newc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_cpio_newc.c' object='libarchive/test/test-test_write_format_cpio_newc.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_cpio_newc.o `test -f 'libarchive/test/test_write_format_cpio_newc.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_cpio_newc.c - -libarchive/test/test-test_write_format_cpio_newc.obj: libarchive/test/test_write_format_cpio_newc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_cpio_newc.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_cpio_newc.Tpo -c -o libarchive/test/test-test_write_format_cpio_newc.obj `if test -f 'libarchive/test/test_write_format_cpio_newc.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_cpio_newc.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_cpio_newc.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_cpio_newc.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_cpio_newc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_cpio_newc.c' object='libarchive/test/test-test_write_format_cpio_newc.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_cpio_newc.obj `if test -f 'libarchive/test/test_write_format_cpio_newc.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_cpio_newc.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_cpio_newc.c'; fi` - -libarchive/test/test-test_write_format_cpio_odc.o: libarchive/test/test_write_format_cpio_odc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_cpio_odc.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_cpio_odc.Tpo -c -o libarchive/test/test-test_write_format_cpio_odc.o `test -f 'libarchive/test/test_write_format_cpio_odc.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_cpio_odc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_cpio_odc.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_cpio_odc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_cpio_odc.c' object='libarchive/test/test-test_write_format_cpio_odc.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_cpio_odc.o `test -f 'libarchive/test/test_write_format_cpio_odc.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_cpio_odc.c - -libarchive/test/test-test_write_format_cpio_odc.obj: libarchive/test/test_write_format_cpio_odc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_cpio_odc.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_cpio_odc.Tpo -c -o libarchive/test/test-test_write_format_cpio_odc.obj `if test -f 'libarchive/test/test_write_format_cpio_odc.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_cpio_odc.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_cpio_odc.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_cpio_odc.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_cpio_odc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_cpio_odc.c' object='libarchive/test/test-test_write_format_cpio_odc.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_cpio_odc.obj `if test -f 'libarchive/test/test_write_format_cpio_odc.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_cpio_odc.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_cpio_odc.c'; fi` - -libarchive/test/test-test_write_format_gnutar.o: libarchive/test/test_write_format_gnutar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_gnutar.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_gnutar.Tpo -c -o libarchive/test/test-test_write_format_gnutar.o `test -f 'libarchive/test/test_write_format_gnutar.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_gnutar.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_gnutar.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_gnutar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_gnutar.c' object='libarchive/test/test-test_write_format_gnutar.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_gnutar.o `test -f 'libarchive/test/test_write_format_gnutar.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_gnutar.c - -libarchive/test/test-test_write_format_gnutar.obj: libarchive/test/test_write_format_gnutar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_gnutar.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_gnutar.Tpo -c -o libarchive/test/test-test_write_format_gnutar.obj `if test -f 'libarchive/test/test_write_format_gnutar.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_gnutar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_gnutar.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_gnutar.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_gnutar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_gnutar.c' object='libarchive/test/test-test_write_format_gnutar.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_gnutar.obj `if test -f 'libarchive/test/test_write_format_gnutar.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_gnutar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_gnutar.c'; fi` - -libarchive/test/test-test_write_format_gnutar_filenames.o: libarchive/test/test_write_format_gnutar_filenames.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_gnutar_filenames.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_gnutar_filenames.Tpo -c -o libarchive/test/test-test_write_format_gnutar_filenames.o `test -f 'libarchive/test/test_write_format_gnutar_filenames.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_gnutar_filenames.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_gnutar_filenames.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_gnutar_filenames.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_gnutar_filenames.c' object='libarchive/test/test-test_write_format_gnutar_filenames.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_gnutar_filenames.o `test -f 'libarchive/test/test_write_format_gnutar_filenames.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_gnutar_filenames.c - -libarchive/test/test-test_write_format_gnutar_filenames.obj: libarchive/test/test_write_format_gnutar_filenames.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_gnutar_filenames.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_gnutar_filenames.Tpo -c -o libarchive/test/test-test_write_format_gnutar_filenames.obj `if test -f 'libarchive/test/test_write_format_gnutar_filenames.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_gnutar_filenames.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_gnutar_filenames.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_gnutar_filenames.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_gnutar_filenames.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_gnutar_filenames.c' object='libarchive/test/test-test_write_format_gnutar_filenames.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_gnutar_filenames.obj `if test -f 'libarchive/test/test_write_format_gnutar_filenames.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_gnutar_filenames.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_gnutar_filenames.c'; fi` - -libarchive/test/test-test_write_format_iso9660.o: libarchive/test/test_write_format_iso9660.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_iso9660.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_iso9660.Tpo -c -o libarchive/test/test-test_write_format_iso9660.o `test -f 'libarchive/test/test_write_format_iso9660.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_iso9660.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_iso9660.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_iso9660.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_iso9660.c' object='libarchive/test/test-test_write_format_iso9660.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_iso9660.o `test -f 'libarchive/test/test_write_format_iso9660.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_iso9660.c - -libarchive/test/test-test_write_format_iso9660.obj: libarchive/test/test_write_format_iso9660.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_iso9660.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_iso9660.Tpo -c -o libarchive/test/test-test_write_format_iso9660.obj `if test -f 'libarchive/test/test_write_format_iso9660.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_iso9660.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_iso9660.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_iso9660.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_iso9660.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_iso9660.c' object='libarchive/test/test-test_write_format_iso9660.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_iso9660.obj `if test -f 'libarchive/test/test_write_format_iso9660.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_iso9660.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_iso9660.c'; fi` - -libarchive/test/test-test_write_format_iso9660_boot.o: libarchive/test/test_write_format_iso9660_boot.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_iso9660_boot.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_boot.Tpo -c -o libarchive/test/test-test_write_format_iso9660_boot.o `test -f 'libarchive/test/test_write_format_iso9660_boot.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_iso9660_boot.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_boot.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_boot.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_iso9660_boot.c' object='libarchive/test/test-test_write_format_iso9660_boot.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_iso9660_boot.o `test -f 'libarchive/test/test_write_format_iso9660_boot.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_iso9660_boot.c - -libarchive/test/test-test_write_format_iso9660_boot.obj: libarchive/test/test_write_format_iso9660_boot.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_iso9660_boot.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_boot.Tpo -c -o libarchive/test/test-test_write_format_iso9660_boot.obj `if test -f 'libarchive/test/test_write_format_iso9660_boot.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_iso9660_boot.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_iso9660_boot.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_boot.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_boot.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_iso9660_boot.c' object='libarchive/test/test-test_write_format_iso9660_boot.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_iso9660_boot.obj `if test -f 'libarchive/test/test_write_format_iso9660_boot.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_iso9660_boot.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_iso9660_boot.c'; fi` - -libarchive/test/test-test_write_format_iso9660_empty.o: libarchive/test/test_write_format_iso9660_empty.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_iso9660_empty.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_empty.Tpo -c -o libarchive/test/test-test_write_format_iso9660_empty.o `test -f 'libarchive/test/test_write_format_iso9660_empty.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_iso9660_empty.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_empty.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_empty.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_iso9660_empty.c' object='libarchive/test/test-test_write_format_iso9660_empty.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_iso9660_empty.o `test -f 'libarchive/test/test_write_format_iso9660_empty.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_iso9660_empty.c - -libarchive/test/test-test_write_format_iso9660_empty.obj: libarchive/test/test_write_format_iso9660_empty.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_iso9660_empty.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_empty.Tpo -c -o libarchive/test/test-test_write_format_iso9660_empty.obj `if test -f 'libarchive/test/test_write_format_iso9660_empty.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_iso9660_empty.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_iso9660_empty.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_empty.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_empty.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_iso9660_empty.c' object='libarchive/test/test-test_write_format_iso9660_empty.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_iso9660_empty.obj `if test -f 'libarchive/test/test_write_format_iso9660_empty.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_iso9660_empty.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_iso9660_empty.c'; fi` - -libarchive/test/test-test_write_format_iso9660_filename.o: libarchive/test/test_write_format_iso9660_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_iso9660_filename.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_filename.Tpo -c -o libarchive/test/test-test_write_format_iso9660_filename.o `test -f 'libarchive/test/test_write_format_iso9660_filename.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_iso9660_filename.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_filename.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_iso9660_filename.c' object='libarchive/test/test-test_write_format_iso9660_filename.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_iso9660_filename.o `test -f 'libarchive/test/test_write_format_iso9660_filename.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_iso9660_filename.c - -libarchive/test/test-test_write_format_iso9660_filename.obj: libarchive/test/test_write_format_iso9660_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_iso9660_filename.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_filename.Tpo -c -o libarchive/test/test-test_write_format_iso9660_filename.obj `if test -f 'libarchive/test/test_write_format_iso9660_filename.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_iso9660_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_iso9660_filename.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_filename.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_iso9660_filename.c' object='libarchive/test/test-test_write_format_iso9660_filename.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_iso9660_filename.obj `if test -f 'libarchive/test/test_write_format_iso9660_filename.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_iso9660_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_iso9660_filename.c'; fi` - -libarchive/test/test-test_write_format_iso9660_zisofs.o: libarchive/test/test_write_format_iso9660_zisofs.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_iso9660_zisofs.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_zisofs.Tpo -c -o libarchive/test/test-test_write_format_iso9660_zisofs.o `test -f 'libarchive/test/test_write_format_iso9660_zisofs.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_iso9660_zisofs.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_zisofs.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_zisofs.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_iso9660_zisofs.c' object='libarchive/test/test-test_write_format_iso9660_zisofs.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_iso9660_zisofs.o `test -f 'libarchive/test/test_write_format_iso9660_zisofs.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_iso9660_zisofs.c - -libarchive/test/test-test_write_format_iso9660_zisofs.obj: libarchive/test/test_write_format_iso9660_zisofs.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_iso9660_zisofs.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_zisofs.Tpo -c -o libarchive/test/test-test_write_format_iso9660_zisofs.obj `if test -f 'libarchive/test/test_write_format_iso9660_zisofs.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_iso9660_zisofs.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_iso9660_zisofs.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_zisofs.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_zisofs.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_iso9660_zisofs.c' object='libarchive/test/test-test_write_format_iso9660_zisofs.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_iso9660_zisofs.obj `if test -f 'libarchive/test/test_write_format_iso9660_zisofs.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_iso9660_zisofs.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_iso9660_zisofs.c'; fi` - -libarchive/test/test-test_write_format_mtree.o: libarchive/test/test_write_format_mtree.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_mtree.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_mtree.Tpo -c -o libarchive/test/test-test_write_format_mtree.o `test -f 'libarchive/test/test_write_format_mtree.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_mtree.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_mtree.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_mtree.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_mtree.c' object='libarchive/test/test-test_write_format_mtree.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_mtree.o `test -f 'libarchive/test/test_write_format_mtree.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_mtree.c - -libarchive/test/test-test_write_format_mtree.obj: libarchive/test/test_write_format_mtree.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_mtree.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_mtree.Tpo -c -o libarchive/test/test-test_write_format_mtree.obj `if test -f 'libarchive/test/test_write_format_mtree.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_mtree.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_mtree.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_mtree.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_mtree.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_mtree.c' object='libarchive/test/test-test_write_format_mtree.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_mtree.obj `if test -f 'libarchive/test/test_write_format_mtree.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_mtree.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_mtree.c'; fi` - -libarchive/test/test-test_write_format_mtree_absolute_path.o: libarchive/test/test_write_format_mtree_absolute_path.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_mtree_absolute_path.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_mtree_absolute_path.Tpo -c -o libarchive/test/test-test_write_format_mtree_absolute_path.o `test -f 'libarchive/test/test_write_format_mtree_absolute_path.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_mtree_absolute_path.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_mtree_absolute_path.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_mtree_absolute_path.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_mtree_absolute_path.c' object='libarchive/test/test-test_write_format_mtree_absolute_path.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_mtree_absolute_path.o `test -f 'libarchive/test/test_write_format_mtree_absolute_path.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_mtree_absolute_path.c - -libarchive/test/test-test_write_format_mtree_absolute_path.obj: libarchive/test/test_write_format_mtree_absolute_path.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_mtree_absolute_path.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_mtree_absolute_path.Tpo -c -o libarchive/test/test-test_write_format_mtree_absolute_path.obj `if test -f 'libarchive/test/test_write_format_mtree_absolute_path.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_mtree_absolute_path.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_mtree_absolute_path.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_mtree_absolute_path.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_mtree_absolute_path.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_mtree_absolute_path.c' object='libarchive/test/test-test_write_format_mtree_absolute_path.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_mtree_absolute_path.obj `if test -f 'libarchive/test/test_write_format_mtree_absolute_path.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_mtree_absolute_path.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_mtree_absolute_path.c'; fi` - -libarchive/test/test-test_write_format_mtree_classic.o: libarchive/test/test_write_format_mtree_classic.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_mtree_classic.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_mtree_classic.Tpo -c -o libarchive/test/test-test_write_format_mtree_classic.o `test -f 'libarchive/test/test_write_format_mtree_classic.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_mtree_classic.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_mtree_classic.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_mtree_classic.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_mtree_classic.c' object='libarchive/test/test-test_write_format_mtree_classic.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_mtree_classic.o `test -f 'libarchive/test/test_write_format_mtree_classic.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_mtree_classic.c - -libarchive/test/test-test_write_format_mtree_classic.obj: libarchive/test/test_write_format_mtree_classic.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_mtree_classic.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_mtree_classic.Tpo -c -o libarchive/test/test-test_write_format_mtree_classic.obj `if test -f 'libarchive/test/test_write_format_mtree_classic.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_mtree_classic.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_mtree_classic.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_mtree_classic.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_mtree_classic.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_mtree_classic.c' object='libarchive/test/test-test_write_format_mtree_classic.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_mtree_classic.obj `if test -f 'libarchive/test/test_write_format_mtree_classic.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_mtree_classic.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_mtree_classic.c'; fi` - -libarchive/test/test-test_write_format_mtree_classic_indent.o: libarchive/test/test_write_format_mtree_classic_indent.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_mtree_classic_indent.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_mtree_classic_indent.Tpo -c -o libarchive/test/test-test_write_format_mtree_classic_indent.o `test -f 'libarchive/test/test_write_format_mtree_classic_indent.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_mtree_classic_indent.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_mtree_classic_indent.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_mtree_classic_indent.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_mtree_classic_indent.c' object='libarchive/test/test-test_write_format_mtree_classic_indent.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_mtree_classic_indent.o `test -f 'libarchive/test/test_write_format_mtree_classic_indent.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_mtree_classic_indent.c - -libarchive/test/test-test_write_format_mtree_classic_indent.obj: libarchive/test/test_write_format_mtree_classic_indent.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_mtree_classic_indent.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_mtree_classic_indent.Tpo -c -o libarchive/test/test-test_write_format_mtree_classic_indent.obj `if test -f 'libarchive/test/test_write_format_mtree_classic_indent.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_mtree_classic_indent.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_mtree_classic_indent.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_mtree_classic_indent.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_mtree_classic_indent.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_mtree_classic_indent.c' object='libarchive/test/test-test_write_format_mtree_classic_indent.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_mtree_classic_indent.obj `if test -f 'libarchive/test/test_write_format_mtree_classic_indent.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_mtree_classic_indent.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_mtree_classic_indent.c'; fi` - -libarchive/test/test-test_write_format_mtree_fflags.o: libarchive/test/test_write_format_mtree_fflags.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_mtree_fflags.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_mtree_fflags.Tpo -c -o libarchive/test/test-test_write_format_mtree_fflags.o `test -f 'libarchive/test/test_write_format_mtree_fflags.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_mtree_fflags.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_mtree_fflags.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_mtree_fflags.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_mtree_fflags.c' object='libarchive/test/test-test_write_format_mtree_fflags.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_mtree_fflags.o `test -f 'libarchive/test/test_write_format_mtree_fflags.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_mtree_fflags.c - -libarchive/test/test-test_write_format_mtree_fflags.obj: libarchive/test/test_write_format_mtree_fflags.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_mtree_fflags.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_mtree_fflags.Tpo -c -o libarchive/test/test-test_write_format_mtree_fflags.obj `if test -f 'libarchive/test/test_write_format_mtree_fflags.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_mtree_fflags.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_mtree_fflags.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_mtree_fflags.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_mtree_fflags.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_mtree_fflags.c' object='libarchive/test/test-test_write_format_mtree_fflags.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_mtree_fflags.obj `if test -f 'libarchive/test/test_write_format_mtree_fflags.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_mtree_fflags.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_mtree_fflags.c'; fi` - -libarchive/test/test-test_write_format_mtree_no_separator.o: libarchive/test/test_write_format_mtree_no_separator.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_mtree_no_separator.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_mtree_no_separator.Tpo -c -o libarchive/test/test-test_write_format_mtree_no_separator.o `test -f 'libarchive/test/test_write_format_mtree_no_separator.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_mtree_no_separator.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_mtree_no_separator.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_mtree_no_separator.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_mtree_no_separator.c' object='libarchive/test/test-test_write_format_mtree_no_separator.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_mtree_no_separator.o `test -f 'libarchive/test/test_write_format_mtree_no_separator.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_mtree_no_separator.c - -libarchive/test/test-test_write_format_mtree_no_separator.obj: libarchive/test/test_write_format_mtree_no_separator.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_mtree_no_separator.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_mtree_no_separator.Tpo -c -o libarchive/test/test-test_write_format_mtree_no_separator.obj `if test -f 'libarchive/test/test_write_format_mtree_no_separator.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_mtree_no_separator.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_mtree_no_separator.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_mtree_no_separator.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_mtree_no_separator.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_mtree_no_separator.c' object='libarchive/test/test-test_write_format_mtree_no_separator.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_mtree_no_separator.obj `if test -f 'libarchive/test/test_write_format_mtree_no_separator.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_mtree_no_separator.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_mtree_no_separator.c'; fi` - -libarchive/test/test-test_write_format_mtree_quoted_filename.o: libarchive/test/test_write_format_mtree_quoted_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_mtree_quoted_filename.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_mtree_quoted_filename.Tpo -c -o libarchive/test/test-test_write_format_mtree_quoted_filename.o `test -f 'libarchive/test/test_write_format_mtree_quoted_filename.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_mtree_quoted_filename.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_mtree_quoted_filename.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_mtree_quoted_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_mtree_quoted_filename.c' object='libarchive/test/test-test_write_format_mtree_quoted_filename.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_mtree_quoted_filename.o `test -f 'libarchive/test/test_write_format_mtree_quoted_filename.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_mtree_quoted_filename.c - -libarchive/test/test-test_write_format_mtree_quoted_filename.obj: libarchive/test/test_write_format_mtree_quoted_filename.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_mtree_quoted_filename.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_mtree_quoted_filename.Tpo -c -o libarchive/test/test-test_write_format_mtree_quoted_filename.obj `if test -f 'libarchive/test/test_write_format_mtree_quoted_filename.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_mtree_quoted_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_mtree_quoted_filename.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_mtree_quoted_filename.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_mtree_quoted_filename.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_mtree_quoted_filename.c' object='libarchive/test/test-test_write_format_mtree_quoted_filename.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_mtree_quoted_filename.obj `if test -f 'libarchive/test/test_write_format_mtree_quoted_filename.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_mtree_quoted_filename.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_mtree_quoted_filename.c'; fi` - -libarchive/test/test-test_write_format_pax.o: libarchive/test/test_write_format_pax.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_pax.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_pax.Tpo -c -o libarchive/test/test-test_write_format_pax.o `test -f 'libarchive/test/test_write_format_pax.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_pax.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_pax.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_pax.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_pax.c' object='libarchive/test/test-test_write_format_pax.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_pax.o `test -f 'libarchive/test/test_write_format_pax.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_pax.c - -libarchive/test/test-test_write_format_pax.obj: libarchive/test/test_write_format_pax.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_pax.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_pax.Tpo -c -o libarchive/test/test-test_write_format_pax.obj `if test -f 'libarchive/test/test_write_format_pax.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_pax.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_pax.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_pax.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_pax.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_pax.c' object='libarchive/test/test-test_write_format_pax.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_pax.obj `if test -f 'libarchive/test/test_write_format_pax.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_pax.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_pax.c'; fi` - -libarchive/test/test-test_write_format_raw.o: libarchive/test/test_write_format_raw.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_raw.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_raw.Tpo -c -o libarchive/test/test-test_write_format_raw.o `test -f 'libarchive/test/test_write_format_raw.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_raw.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_raw.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_raw.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_raw.c' object='libarchive/test/test-test_write_format_raw.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_raw.o `test -f 'libarchive/test/test_write_format_raw.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_raw.c - -libarchive/test/test-test_write_format_raw.obj: libarchive/test/test_write_format_raw.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_raw.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_raw.Tpo -c -o libarchive/test/test-test_write_format_raw.obj `if test -f 'libarchive/test/test_write_format_raw.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_raw.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_raw.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_raw.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_raw.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_raw.c' object='libarchive/test/test-test_write_format_raw.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_raw.obj `if test -f 'libarchive/test/test_write_format_raw.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_raw.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_raw.c'; fi` - -libarchive/test/test-test_write_format_raw_b64.o: libarchive/test/test_write_format_raw_b64.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_raw_b64.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_raw_b64.Tpo -c -o libarchive/test/test-test_write_format_raw_b64.o `test -f 'libarchive/test/test_write_format_raw_b64.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_raw_b64.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_raw_b64.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_raw_b64.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_raw_b64.c' object='libarchive/test/test-test_write_format_raw_b64.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_raw_b64.o `test -f 'libarchive/test/test_write_format_raw_b64.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_raw_b64.c - -libarchive/test/test-test_write_format_raw_b64.obj: libarchive/test/test_write_format_raw_b64.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_raw_b64.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_raw_b64.Tpo -c -o libarchive/test/test-test_write_format_raw_b64.obj `if test -f 'libarchive/test/test_write_format_raw_b64.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_raw_b64.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_raw_b64.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_raw_b64.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_raw_b64.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_raw_b64.c' object='libarchive/test/test-test_write_format_raw_b64.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_raw_b64.obj `if test -f 'libarchive/test/test_write_format_raw_b64.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_raw_b64.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_raw_b64.c'; fi` - -libarchive/test/test-test_write_format_shar_empty.o: libarchive/test/test_write_format_shar_empty.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_shar_empty.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_shar_empty.Tpo -c -o libarchive/test/test-test_write_format_shar_empty.o `test -f 'libarchive/test/test_write_format_shar_empty.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_shar_empty.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_shar_empty.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_shar_empty.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_shar_empty.c' object='libarchive/test/test-test_write_format_shar_empty.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_shar_empty.o `test -f 'libarchive/test/test_write_format_shar_empty.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_shar_empty.c - -libarchive/test/test-test_write_format_shar_empty.obj: libarchive/test/test_write_format_shar_empty.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_shar_empty.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_shar_empty.Tpo -c -o libarchive/test/test-test_write_format_shar_empty.obj `if test -f 'libarchive/test/test_write_format_shar_empty.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_shar_empty.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_shar_empty.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_shar_empty.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_shar_empty.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_shar_empty.c' object='libarchive/test/test-test_write_format_shar_empty.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_shar_empty.obj `if test -f 'libarchive/test/test_write_format_shar_empty.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_shar_empty.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_shar_empty.c'; fi` - -libarchive/test/test-test_write_format_tar.o: libarchive/test/test_write_format_tar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_tar.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_tar.Tpo -c -o libarchive/test/test-test_write_format_tar.o `test -f 'libarchive/test/test_write_format_tar.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_tar.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_tar.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_tar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_tar.c' object='libarchive/test/test-test_write_format_tar.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_tar.o `test -f 'libarchive/test/test_write_format_tar.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_tar.c - -libarchive/test/test-test_write_format_tar.obj: libarchive/test/test_write_format_tar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_tar.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_tar.Tpo -c -o libarchive/test/test-test_write_format_tar.obj `if test -f 'libarchive/test/test_write_format_tar.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_tar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_tar.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_tar.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_tar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_tar.c' object='libarchive/test/test-test_write_format_tar.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_tar.obj `if test -f 'libarchive/test/test_write_format_tar.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_tar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_tar.c'; fi` - -libarchive/test/test-test_write_format_tar_empty.o: libarchive/test/test_write_format_tar_empty.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_tar_empty.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_tar_empty.Tpo -c -o libarchive/test/test-test_write_format_tar_empty.o `test -f 'libarchive/test/test_write_format_tar_empty.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_tar_empty.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_tar_empty.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_tar_empty.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_tar_empty.c' object='libarchive/test/test-test_write_format_tar_empty.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_tar_empty.o `test -f 'libarchive/test/test_write_format_tar_empty.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_tar_empty.c - -libarchive/test/test-test_write_format_tar_empty.obj: libarchive/test/test_write_format_tar_empty.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_tar_empty.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_tar_empty.Tpo -c -o libarchive/test/test-test_write_format_tar_empty.obj `if test -f 'libarchive/test/test_write_format_tar_empty.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_tar_empty.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_tar_empty.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_tar_empty.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_tar_empty.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_tar_empty.c' object='libarchive/test/test-test_write_format_tar_empty.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_tar_empty.obj `if test -f 'libarchive/test/test_write_format_tar_empty.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_tar_empty.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_tar_empty.c'; fi` - -libarchive/test/test-test_write_format_tar_sparse.o: libarchive/test/test_write_format_tar_sparse.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_tar_sparse.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_tar_sparse.Tpo -c -o libarchive/test/test-test_write_format_tar_sparse.o `test -f 'libarchive/test/test_write_format_tar_sparse.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_tar_sparse.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_tar_sparse.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_tar_sparse.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_tar_sparse.c' object='libarchive/test/test-test_write_format_tar_sparse.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_tar_sparse.o `test -f 'libarchive/test/test_write_format_tar_sparse.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_tar_sparse.c - -libarchive/test/test-test_write_format_tar_sparse.obj: libarchive/test/test_write_format_tar_sparse.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_tar_sparse.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_tar_sparse.Tpo -c -o libarchive/test/test-test_write_format_tar_sparse.obj `if test -f 'libarchive/test/test_write_format_tar_sparse.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_tar_sparse.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_tar_sparse.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_tar_sparse.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_tar_sparse.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_tar_sparse.c' object='libarchive/test/test-test_write_format_tar_sparse.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_tar_sparse.obj `if test -f 'libarchive/test/test_write_format_tar_sparse.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_tar_sparse.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_tar_sparse.c'; fi` - -libarchive/test/test-test_write_format_tar_ustar.o: libarchive/test/test_write_format_tar_ustar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_tar_ustar.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_tar_ustar.Tpo -c -o libarchive/test/test-test_write_format_tar_ustar.o `test -f 'libarchive/test/test_write_format_tar_ustar.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_tar_ustar.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_tar_ustar.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_tar_ustar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_tar_ustar.c' object='libarchive/test/test-test_write_format_tar_ustar.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_tar_ustar.o `test -f 'libarchive/test/test_write_format_tar_ustar.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_tar_ustar.c - -libarchive/test/test-test_write_format_tar_ustar.obj: libarchive/test/test_write_format_tar_ustar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_tar_ustar.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_tar_ustar.Tpo -c -o libarchive/test/test-test_write_format_tar_ustar.obj `if test -f 'libarchive/test/test_write_format_tar_ustar.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_tar_ustar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_tar_ustar.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_tar_ustar.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_tar_ustar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_tar_ustar.c' object='libarchive/test/test-test_write_format_tar_ustar.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_tar_ustar.obj `if test -f 'libarchive/test/test_write_format_tar_ustar.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_tar_ustar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_tar_ustar.c'; fi` - -libarchive/test/test-test_write_format_tar_v7tar.o: libarchive/test/test_write_format_tar_v7tar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_tar_v7tar.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_tar_v7tar.Tpo -c -o libarchive/test/test-test_write_format_tar_v7tar.o `test -f 'libarchive/test/test_write_format_tar_v7tar.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_tar_v7tar.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_tar_v7tar.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_tar_v7tar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_tar_v7tar.c' object='libarchive/test/test-test_write_format_tar_v7tar.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_tar_v7tar.o `test -f 'libarchive/test/test_write_format_tar_v7tar.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_tar_v7tar.c - -libarchive/test/test-test_write_format_tar_v7tar.obj: libarchive/test/test_write_format_tar_v7tar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_tar_v7tar.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_tar_v7tar.Tpo -c -o libarchive/test/test-test_write_format_tar_v7tar.obj `if test -f 'libarchive/test/test_write_format_tar_v7tar.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_tar_v7tar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_tar_v7tar.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_tar_v7tar.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_tar_v7tar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_tar_v7tar.c' object='libarchive/test/test-test_write_format_tar_v7tar.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_tar_v7tar.obj `if test -f 'libarchive/test/test_write_format_tar_v7tar.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_tar_v7tar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_tar_v7tar.c'; fi` - -libarchive/test/test-test_write_format_warc.o: libarchive/test/test_write_format_warc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_warc.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_warc.Tpo -c -o libarchive/test/test-test_write_format_warc.o `test -f 'libarchive/test/test_write_format_warc.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_warc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_warc.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_warc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_warc.c' object='libarchive/test/test-test_write_format_warc.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_warc.o `test -f 'libarchive/test/test_write_format_warc.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_warc.c - -libarchive/test/test-test_write_format_warc.obj: libarchive/test/test_write_format_warc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_warc.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_warc.Tpo -c -o libarchive/test/test-test_write_format_warc.obj `if test -f 'libarchive/test/test_write_format_warc.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_warc.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_warc.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_warc.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_warc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_warc.c' object='libarchive/test/test-test_write_format_warc.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_warc.obj `if test -f 'libarchive/test/test_write_format_warc.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_warc.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_warc.c'; fi` - -libarchive/test/test-test_write_format_warc_empty.o: libarchive/test/test_write_format_warc_empty.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_warc_empty.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_warc_empty.Tpo -c -o libarchive/test/test-test_write_format_warc_empty.o `test -f 'libarchive/test/test_write_format_warc_empty.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_warc_empty.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_warc_empty.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_warc_empty.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_warc_empty.c' object='libarchive/test/test-test_write_format_warc_empty.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_warc_empty.o `test -f 'libarchive/test/test_write_format_warc_empty.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_warc_empty.c - -libarchive/test/test-test_write_format_warc_empty.obj: libarchive/test/test_write_format_warc_empty.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_warc_empty.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_warc_empty.Tpo -c -o libarchive/test/test-test_write_format_warc_empty.obj `if test -f 'libarchive/test/test_write_format_warc_empty.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_warc_empty.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_warc_empty.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_warc_empty.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_warc_empty.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_warc_empty.c' object='libarchive/test/test-test_write_format_warc_empty.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_warc_empty.obj `if test -f 'libarchive/test/test_write_format_warc_empty.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_warc_empty.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_warc_empty.c'; fi` - -libarchive/test/test-test_write_format_xar.o: libarchive/test/test_write_format_xar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_xar.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_xar.Tpo -c -o libarchive/test/test-test_write_format_xar.o `test -f 'libarchive/test/test_write_format_xar.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_xar.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_xar.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_xar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_xar.c' object='libarchive/test/test-test_write_format_xar.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_xar.o `test -f 'libarchive/test/test_write_format_xar.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_xar.c - -libarchive/test/test-test_write_format_xar.obj: libarchive/test/test_write_format_xar.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_xar.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_xar.Tpo -c -o libarchive/test/test-test_write_format_xar.obj `if test -f 'libarchive/test/test_write_format_xar.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_xar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_xar.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_xar.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_xar.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_xar.c' object='libarchive/test/test-test_write_format_xar.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_xar.obj `if test -f 'libarchive/test/test_write_format_xar.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_xar.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_xar.c'; fi` - -libarchive/test/test-test_write_format_xar_empty.o: libarchive/test/test_write_format_xar_empty.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_xar_empty.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_xar_empty.Tpo -c -o libarchive/test/test-test_write_format_xar_empty.o `test -f 'libarchive/test/test_write_format_xar_empty.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_xar_empty.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_xar_empty.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_xar_empty.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_xar_empty.c' object='libarchive/test/test-test_write_format_xar_empty.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_xar_empty.o `test -f 'libarchive/test/test_write_format_xar_empty.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_xar_empty.c - -libarchive/test/test-test_write_format_xar_empty.obj: libarchive/test/test_write_format_xar_empty.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_xar_empty.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_xar_empty.Tpo -c -o libarchive/test/test-test_write_format_xar_empty.obj `if test -f 'libarchive/test/test_write_format_xar_empty.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_xar_empty.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_xar_empty.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_xar_empty.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_xar_empty.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_xar_empty.c' object='libarchive/test/test-test_write_format_xar_empty.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_xar_empty.obj `if test -f 'libarchive/test/test_write_format_xar_empty.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_xar_empty.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_xar_empty.c'; fi` - -libarchive/test/test-test_write_format_zip.o: libarchive/test/test_write_format_zip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_zip.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_zip.Tpo -c -o libarchive/test/test-test_write_format_zip.o `test -f 'libarchive/test/test_write_format_zip.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_zip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_zip.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_zip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_zip.c' object='libarchive/test/test-test_write_format_zip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_zip.o `test -f 'libarchive/test/test_write_format_zip.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_zip.c - -libarchive/test/test-test_write_format_zip.obj: libarchive/test/test_write_format_zip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_zip.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_zip.Tpo -c -o libarchive/test/test-test_write_format_zip.obj `if test -f 'libarchive/test/test_write_format_zip.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_zip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_zip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_zip.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_zip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_zip.c' object='libarchive/test/test-test_write_format_zip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_zip.obj `if test -f 'libarchive/test/test_write_format_zip.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_zip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_zip.c'; fi` - -libarchive/test/test-test_write_format_zip_compression_store.o: libarchive/test/test_write_format_zip_compression_store.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_zip_compression_store.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_zip_compression_store.Tpo -c -o libarchive/test/test-test_write_format_zip_compression_store.o `test -f 'libarchive/test/test_write_format_zip_compression_store.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_zip_compression_store.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_zip_compression_store.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_zip_compression_store.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_zip_compression_store.c' object='libarchive/test/test-test_write_format_zip_compression_store.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_zip_compression_store.o `test -f 'libarchive/test/test_write_format_zip_compression_store.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_zip_compression_store.c - -libarchive/test/test-test_write_format_zip_compression_store.obj: libarchive/test/test_write_format_zip_compression_store.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_zip_compression_store.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_zip_compression_store.Tpo -c -o libarchive/test/test-test_write_format_zip_compression_store.obj `if test -f 'libarchive/test/test_write_format_zip_compression_store.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_zip_compression_store.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_zip_compression_store.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_zip_compression_store.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_zip_compression_store.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_zip_compression_store.c' object='libarchive/test/test-test_write_format_zip_compression_store.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_zip_compression_store.obj `if test -f 'libarchive/test/test_write_format_zip_compression_store.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_zip_compression_store.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_zip_compression_store.c'; fi` - -libarchive/test/test-test_write_format_zip_entry_size_unset.o: libarchive/test/test_write_format_zip_entry_size_unset.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_zip_entry_size_unset.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_zip_entry_size_unset.Tpo -c -o libarchive/test/test-test_write_format_zip_entry_size_unset.o `test -f 'libarchive/test/test_write_format_zip_entry_size_unset.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_zip_entry_size_unset.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_zip_entry_size_unset.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_zip_entry_size_unset.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_zip_entry_size_unset.c' object='libarchive/test/test-test_write_format_zip_entry_size_unset.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_zip_entry_size_unset.o `test -f 'libarchive/test/test_write_format_zip_entry_size_unset.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_zip_entry_size_unset.c - -libarchive/test/test-test_write_format_zip_entry_size_unset.obj: libarchive/test/test_write_format_zip_entry_size_unset.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_zip_entry_size_unset.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_zip_entry_size_unset.Tpo -c -o libarchive/test/test-test_write_format_zip_entry_size_unset.obj `if test -f 'libarchive/test/test_write_format_zip_entry_size_unset.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_zip_entry_size_unset.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_zip_entry_size_unset.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_zip_entry_size_unset.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_zip_entry_size_unset.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_zip_entry_size_unset.c' object='libarchive/test/test-test_write_format_zip_entry_size_unset.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_zip_entry_size_unset.obj `if test -f 'libarchive/test/test_write_format_zip_entry_size_unset.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_zip_entry_size_unset.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_zip_entry_size_unset.c'; fi` - -libarchive/test/test-test_write_format_zip_empty.o: libarchive/test/test_write_format_zip_empty.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_zip_empty.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_zip_empty.Tpo -c -o libarchive/test/test-test_write_format_zip_empty.o `test -f 'libarchive/test/test_write_format_zip_empty.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_zip_empty.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_zip_empty.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_zip_empty.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_zip_empty.c' object='libarchive/test/test-test_write_format_zip_empty.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_zip_empty.o `test -f 'libarchive/test/test_write_format_zip_empty.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_zip_empty.c - -libarchive/test/test-test_write_format_zip_empty.obj: libarchive/test/test_write_format_zip_empty.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_zip_empty.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_zip_empty.Tpo -c -o libarchive/test/test-test_write_format_zip_empty.obj `if test -f 'libarchive/test/test_write_format_zip_empty.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_zip_empty.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_zip_empty.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_zip_empty.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_zip_empty.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_zip_empty.c' object='libarchive/test/test-test_write_format_zip_empty.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_zip_empty.obj `if test -f 'libarchive/test/test_write_format_zip_empty.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_zip_empty.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_zip_empty.c'; fi` - -libarchive/test/test-test_write_format_zip_empty_zip64.o: libarchive/test/test_write_format_zip_empty_zip64.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_zip_empty_zip64.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_zip_empty_zip64.Tpo -c -o libarchive/test/test-test_write_format_zip_empty_zip64.o `test -f 'libarchive/test/test_write_format_zip_empty_zip64.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_zip_empty_zip64.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_zip_empty_zip64.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_zip_empty_zip64.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_zip_empty_zip64.c' object='libarchive/test/test-test_write_format_zip_empty_zip64.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_zip_empty_zip64.o `test -f 'libarchive/test/test_write_format_zip_empty_zip64.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_zip_empty_zip64.c - -libarchive/test/test-test_write_format_zip_empty_zip64.obj: libarchive/test/test_write_format_zip_empty_zip64.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_zip_empty_zip64.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_zip_empty_zip64.Tpo -c -o libarchive/test/test-test_write_format_zip_empty_zip64.obj `if test -f 'libarchive/test/test_write_format_zip_empty_zip64.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_zip_empty_zip64.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_zip_empty_zip64.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_zip_empty_zip64.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_zip_empty_zip64.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_zip_empty_zip64.c' object='libarchive/test/test-test_write_format_zip_empty_zip64.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_zip_empty_zip64.obj `if test -f 'libarchive/test/test_write_format_zip_empty_zip64.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_zip_empty_zip64.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_zip_empty_zip64.c'; fi` - -libarchive/test/test-test_write_format_zip_file.o: libarchive/test/test_write_format_zip_file.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_zip_file.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_zip_file.Tpo -c -o libarchive/test/test-test_write_format_zip_file.o `test -f 'libarchive/test/test_write_format_zip_file.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_zip_file.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_zip_file.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_zip_file.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_zip_file.c' object='libarchive/test/test-test_write_format_zip_file.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_zip_file.o `test -f 'libarchive/test/test_write_format_zip_file.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_zip_file.c - -libarchive/test/test-test_write_format_zip_file.obj: libarchive/test/test_write_format_zip_file.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_zip_file.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_zip_file.Tpo -c -o libarchive/test/test-test_write_format_zip_file.obj `if test -f 'libarchive/test/test_write_format_zip_file.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_zip_file.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_zip_file.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_zip_file.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_zip_file.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_zip_file.c' object='libarchive/test/test-test_write_format_zip_file.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_zip_file.obj `if test -f 'libarchive/test/test_write_format_zip_file.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_zip_file.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_zip_file.c'; fi` - -libarchive/test/test-test_write_format_zip_file_zip64.o: libarchive/test/test_write_format_zip_file_zip64.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_zip_file_zip64.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_zip_file_zip64.Tpo -c -o libarchive/test/test-test_write_format_zip_file_zip64.o `test -f 'libarchive/test/test_write_format_zip_file_zip64.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_zip_file_zip64.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_zip_file_zip64.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_zip_file_zip64.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_zip_file_zip64.c' object='libarchive/test/test-test_write_format_zip_file_zip64.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_zip_file_zip64.o `test -f 'libarchive/test/test_write_format_zip_file_zip64.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_zip_file_zip64.c - -libarchive/test/test-test_write_format_zip_file_zip64.obj: libarchive/test/test_write_format_zip_file_zip64.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_zip_file_zip64.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_zip_file_zip64.Tpo -c -o libarchive/test/test-test_write_format_zip_file_zip64.obj `if test -f 'libarchive/test/test_write_format_zip_file_zip64.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_zip_file_zip64.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_zip_file_zip64.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_zip_file_zip64.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_zip_file_zip64.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_zip_file_zip64.c' object='libarchive/test/test-test_write_format_zip_file_zip64.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_zip_file_zip64.obj `if test -f 'libarchive/test/test_write_format_zip_file_zip64.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_zip_file_zip64.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_zip_file_zip64.c'; fi` - -libarchive/test/test-test_write_format_zip_large.o: libarchive/test/test_write_format_zip_large.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_zip_large.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_zip_large.Tpo -c -o libarchive/test/test-test_write_format_zip_large.o `test -f 'libarchive/test/test_write_format_zip_large.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_zip_large.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_zip_large.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_zip_large.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_zip_large.c' object='libarchive/test/test-test_write_format_zip_large.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_zip_large.o `test -f 'libarchive/test/test_write_format_zip_large.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_zip_large.c - -libarchive/test/test-test_write_format_zip_large.obj: libarchive/test/test_write_format_zip_large.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_zip_large.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_zip_large.Tpo -c -o libarchive/test/test-test_write_format_zip_large.obj `if test -f 'libarchive/test/test_write_format_zip_large.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_zip_large.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_zip_large.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_zip_large.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_zip_large.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_zip_large.c' object='libarchive/test/test-test_write_format_zip_large.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_zip_large.obj `if test -f 'libarchive/test/test_write_format_zip_large.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_zip_large.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_zip_large.c'; fi` - -libarchive/test/test-test_write_format_zip_zip64.o: libarchive/test/test_write_format_zip_zip64.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_zip_zip64.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_zip_zip64.Tpo -c -o libarchive/test/test-test_write_format_zip_zip64.o `test -f 'libarchive/test/test_write_format_zip_zip64.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_zip_zip64.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_zip_zip64.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_zip_zip64.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_zip_zip64.c' object='libarchive/test/test-test_write_format_zip_zip64.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_zip_zip64.o `test -f 'libarchive/test/test_write_format_zip_zip64.c' || echo '$(srcdir)/'`libarchive/test/test_write_format_zip_zip64.c - -libarchive/test/test-test_write_format_zip_zip64.obj: libarchive/test/test_write_format_zip_zip64.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_format_zip_zip64.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_format_zip_zip64.Tpo -c -o libarchive/test/test-test_write_format_zip_zip64.obj `if test -f 'libarchive/test/test_write_format_zip_zip64.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_zip_zip64.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_zip_zip64.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_format_zip_zip64.Tpo libarchive/test/$(DEPDIR)/test-test_write_format_zip_zip64.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_format_zip_zip64.c' object='libarchive/test/test-test_write_format_zip_zip64.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_format_zip_zip64.obj `if test -f 'libarchive/test/test_write_format_zip_zip64.c'; then $(CYGPATH_W) 'libarchive/test/test_write_format_zip_zip64.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_format_zip_zip64.c'; fi` - -libarchive/test/test-test_write_open_memory.o: libarchive/test/test_write_open_memory.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_open_memory.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_open_memory.Tpo -c -o libarchive/test/test-test_write_open_memory.o `test -f 'libarchive/test/test_write_open_memory.c' || echo '$(srcdir)/'`libarchive/test/test_write_open_memory.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_open_memory.Tpo libarchive/test/$(DEPDIR)/test-test_write_open_memory.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_open_memory.c' object='libarchive/test/test-test_write_open_memory.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_open_memory.o `test -f 'libarchive/test/test_write_open_memory.c' || echo '$(srcdir)/'`libarchive/test/test_write_open_memory.c - -libarchive/test/test-test_write_open_memory.obj: libarchive/test/test_write_open_memory.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_open_memory.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_open_memory.Tpo -c -o libarchive/test/test-test_write_open_memory.obj `if test -f 'libarchive/test/test_write_open_memory.c'; then $(CYGPATH_W) 'libarchive/test/test_write_open_memory.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_open_memory.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_open_memory.Tpo libarchive/test/$(DEPDIR)/test-test_write_open_memory.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_open_memory.c' object='libarchive/test/test-test_write_open_memory.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_open_memory.obj `if test -f 'libarchive/test/test_write_open_memory.c'; then $(CYGPATH_W) 'libarchive/test/test_write_open_memory.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_open_memory.c'; fi` - -libarchive/test/test-test_write_read_format_zip.o: libarchive/test/test_write_read_format_zip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_read_format_zip.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_read_format_zip.Tpo -c -o libarchive/test/test-test_write_read_format_zip.o `test -f 'libarchive/test/test_write_read_format_zip.c' || echo '$(srcdir)/'`libarchive/test/test_write_read_format_zip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_read_format_zip.Tpo libarchive/test/$(DEPDIR)/test-test_write_read_format_zip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_read_format_zip.c' object='libarchive/test/test-test_write_read_format_zip.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_read_format_zip.o `test -f 'libarchive/test/test_write_read_format_zip.c' || echo '$(srcdir)/'`libarchive/test/test_write_read_format_zip.c - -libarchive/test/test-test_write_read_format_zip.obj: libarchive/test/test_write_read_format_zip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_write_read_format_zip.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_write_read_format_zip.Tpo -c -o libarchive/test/test-test_write_read_format_zip.obj `if test -f 'libarchive/test/test_write_read_format_zip.c'; then $(CYGPATH_W) 'libarchive/test/test_write_read_format_zip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_read_format_zip.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_write_read_format_zip.Tpo libarchive/test/$(DEPDIR)/test-test_write_read_format_zip.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_write_read_format_zip.c' object='libarchive/test/test-test_write_read_format_zip.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_write_read_format_zip.obj `if test -f 'libarchive/test/test_write_read_format_zip.c'; then $(CYGPATH_W) 'libarchive/test/test_write_read_format_zip.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_write_read_format_zip.c'; fi` - -libarchive/test/test-test_xattr_platform.o: libarchive/test/test_xattr_platform.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_xattr_platform.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_xattr_platform.Tpo -c -o libarchive/test/test-test_xattr_platform.o `test -f 'libarchive/test/test_xattr_platform.c' || echo '$(srcdir)/'`libarchive/test/test_xattr_platform.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_xattr_platform.Tpo libarchive/test/$(DEPDIR)/test-test_xattr_platform.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_xattr_platform.c' object='libarchive/test/test-test_xattr_platform.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_xattr_platform.o `test -f 'libarchive/test/test_xattr_platform.c' || echo '$(srcdir)/'`libarchive/test/test_xattr_platform.c - -libarchive/test/test-test_xattr_platform.obj: libarchive/test/test_xattr_platform.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_xattr_platform.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_xattr_platform.Tpo -c -o libarchive/test/test-test_xattr_platform.obj `if test -f 'libarchive/test/test_xattr_platform.c'; then $(CYGPATH_W) 'libarchive/test/test_xattr_platform.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_xattr_platform.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_xattr_platform.Tpo libarchive/test/$(DEPDIR)/test-test_xattr_platform.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_xattr_platform.c' object='libarchive/test/test-test_xattr_platform.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_xattr_platform.obj `if test -f 'libarchive/test/test_xattr_platform.c'; then $(CYGPATH_W) 'libarchive/test/test_xattr_platform.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_xattr_platform.c'; fi` - -libarchive/test/test-test_zip_filename_encoding.o: libarchive/test/test_zip_filename_encoding.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_zip_filename_encoding.o -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_zip_filename_encoding.Tpo -c -o libarchive/test/test-test_zip_filename_encoding.o `test -f 'libarchive/test/test_zip_filename_encoding.c' || echo '$(srcdir)/'`libarchive/test/test_zip_filename_encoding.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_zip_filename_encoding.Tpo libarchive/test/$(DEPDIR)/test-test_zip_filename_encoding.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_zip_filename_encoding.c' object='libarchive/test/test-test_zip_filename_encoding.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_zip_filename_encoding.o `test -f 'libarchive/test/test_zip_filename_encoding.c' || echo '$(srcdir)/'`libarchive/test/test_zip_filename_encoding.c - -libarchive/test/test-test_zip_filename_encoding.obj: libarchive/test/test_zip_filename_encoding.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libarchive/test/test-test_zip_filename_encoding.obj -MD -MP -MF libarchive/test/$(DEPDIR)/test-test_zip_filename_encoding.Tpo -c -o libarchive/test/test-test_zip_filename_encoding.obj `if test -f 'libarchive/test/test_zip_filename_encoding.c'; then $(CYGPATH_W) 'libarchive/test/test_zip_filename_encoding.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_zip_filename_encoding.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libarchive/test/$(DEPDIR)/test-test_zip_filename_encoding.Tpo libarchive/test/$(DEPDIR)/test-test_zip_filename_encoding.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libarchive/test/test_zip_filename_encoding.c' object='libarchive/test/test-test_zip_filename_encoding.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarchive_test_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libarchive/test/test-test_zip_filename_encoding.obj `if test -f 'libarchive/test/test_zip_filename_encoding.c'; then $(CYGPATH_W) 'libarchive/test/test_zip_filename_encoding.c'; else $(CYGPATH_W) '$(srcdir)/libarchive/test/test_zip_filename_encoding.c'; fi` - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -rm -rf libarchive/.libs libarchive/_libs - -rm -rf libarchive_fe/.libs libarchive_fe/_libs - -distclean-libtool: - -rm -f libtool config.lt -install-man1: $(man_MANS) - @$(NORMAL_INSTALL) - @list1=''; \ - list2='$(man_MANS)'; \ - test -n "$(man1dir)" \ - && test -n "`echo $$list1$$list2`" \ - || exit 0; \ - echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ - { for i in $$list1; do echo "$$i"; done; \ - if test -n "$$list2"; then \ - for i in $$list2; do echo "$$i"; done \ - | sed -n '/\.1[a-z]*$$/p'; \ - fi; \ - } | while read p; do \ - if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; echo "$$p"; \ - done | \ - sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ - sed 'N;N;s,\n, ,g' | { \ - list=; while read file base inst; do \ - if test "$$base" = "$$inst"; then list="$$list $$file"; else \ - echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ - $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ - fi; \ - done; \ - for i in $$list; do echo "$$i"; done | $(am__base_list) | \ - while read files; do \ - test -z "$$files" || { \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ - done; } - -uninstall-man1: - @$(NORMAL_UNINSTALL) - @list=''; test -n "$(man1dir)" || exit 0; \ - files=`{ for i in $$list; do echo "$$i"; done; \ - l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ - sed -n '/\.1[a-z]*$$/p'; \ - } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) -install-man3: $(man_MANS) - @$(NORMAL_INSTALL) - @list1=''; \ - list2='$(man_MANS)'; \ - test -n "$(man3dir)" \ - && test -n "`echo $$list1$$list2`" \ - || exit 0; \ - echo " $(MKDIR_P) '$(DESTDIR)$(man3dir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(man3dir)" || exit 1; \ - { for i in $$list1; do echo "$$i"; done; \ - if test -n "$$list2"; then \ - for i in $$list2; do echo "$$i"; done \ - | sed -n '/\.3[a-z]*$$/p'; \ - fi; \ - } | while read p; do \ - if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; echo "$$p"; \ - done | \ - sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ - sed 'N;N;s,\n, ,g' | { \ - list=; while read file base inst; do \ - if test "$$base" = "$$inst"; then list="$$list $$file"; else \ - echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \ - $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \ - fi; \ - done; \ - for i in $$list; do echo "$$i"; done | $(am__base_list) | \ - while read files; do \ - test -z "$$files" || { \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \ - done; } - -uninstall-man3: - @$(NORMAL_UNINSTALL) - @list=''; test -n "$(man3dir)" || exit 0; \ - files=`{ for i in $$list; do echo "$$i"; done; \ - l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ - sed -n '/\.3[a-z]*$$/p'; \ - } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir) -install-man5: $(man_MANS) - @$(NORMAL_INSTALL) - @list1=''; \ - list2='$(man_MANS)'; \ - test -n "$(man5dir)" \ - && test -n "`echo $$list1$$list2`" \ - || exit 0; \ - echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \ - { for i in $$list1; do echo "$$i"; done; \ - if test -n "$$list2"; then \ - for i in $$list2; do echo "$$i"; done \ - | sed -n '/\.5[a-z]*$$/p'; \ - fi; \ - } | while read p; do \ - if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; echo "$$p"; \ - done | \ - sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ - sed 'N;N;s,\n, ,g' | { \ - list=; while read file base inst; do \ - if test "$$base" = "$$inst"; then list="$$list $$file"; else \ - echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \ - $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \ - fi; \ - done; \ - for i in $$list; do echo "$$i"; done | $(am__base_list) | \ - while read files; do \ - test -z "$$files" || { \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \ - done; } - -uninstall-man5: - @$(NORMAL_UNINSTALL) - @list=''; test -n "$(man5dir)" || exit 0; \ - files=`{ for i in $$list; do echo "$$i"; done; \ - l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ - sed -n '/\.5[a-z]*$$/p'; \ - } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir) -install-pkgconfigDATA: $(pkgconfig_DATA) - @$(NORMAL_INSTALL) - @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ - done - -uninstall-pkgconfigDATA: - @$(NORMAL_UNINSTALL) - @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) -install-includeHEADERS: $(include_HEADERS) - @$(NORMAL_INSTALL) - @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ - $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ - done - -uninstall-includeHEADERS: - @$(NORMAL_UNINSTALL) - @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscope: cscope.files - test ! -s cscope.files \ - || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) -clean-cscope: - -rm -f cscope.files -cscope.files: clean-cscope cscopelist -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -rm -f cscope.out cscope.in.out cscope.po.out cscope.files - -# Recover from deleted '.trs' file; this should ensure that -# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create -# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells -# to avoid problems with "make -n". -.log.trs: - rm -f $< $@ - $(MAKE) $(AM_MAKEFLAGS) $< - -# Leading 'am--fnord' is there to ensure the list of targets does not -# expand to empty, as could happen e.g. with make check TESTS=''. -am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) -am--force-recheck: - @: - -$(TEST_SUITE_LOG): $(TEST_LOGS) - @$(am__set_TESTS_bases); \ - am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ - redo_bases=`for i in $$bases; do \ - am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ - done`; \ - if test -n "$$redo_bases"; then \ - redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ - redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ - if $(am__make_dryrun); then :; else \ - rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ - fi; \ - fi; \ - if test -n "$$am__remaking_logs"; then \ - echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ - "recursion detected" >&2; \ - elif test -n "$$redo_logs"; then \ - am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ - fi; \ - if $(am__make_dryrun); then :; else \ - st=0; \ - errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ - for i in $$redo_bases; do \ - test -f $$i.trs && test -r $$i.trs \ - || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ - test -f $$i.log && test -r $$i.log \ - || { echo "$$errmsg $$i.log" >&2; st=1; }; \ - done; \ - test $$st -eq 0 || exit 1; \ - fi - @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ - ws='[ ]'; \ - results=`for b in $$bases; do echo $$b.trs; done`; \ - test -n "$$results" || results=/dev/null; \ - all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ - pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ - fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ - skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ - xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ - xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ - error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ - if test `expr $$fail + $$xpass + $$error` -eq 0; then \ - success=true; \ - else \ - success=false; \ - fi; \ - br='==================='; br=$$br$$br$$br$$br; \ - result_count () \ - { \ - if test x"$$1" = x"--maybe-color"; then \ - maybe_colorize=yes; \ - elif test x"$$1" = x"--no-color"; then \ - maybe_colorize=no; \ - else \ - echo "$@: invalid 'result_count' usage" >&2; exit 4; \ - fi; \ - shift; \ - desc=$$1 count=$$2; \ - if test $$maybe_colorize = yes && test $$count -gt 0; then \ - color_start=$$3 color_end=$$std; \ - else \ - color_start= color_end=; \ - fi; \ - echo "$${color_start}# $$desc $$count$${color_end}"; \ - }; \ - create_testsuite_report () \ - { \ - result_count $$1 "TOTAL:" $$all "$$brg"; \ - result_count $$1 "PASS: " $$pass "$$grn"; \ - result_count $$1 "SKIP: " $$skip "$$blu"; \ - result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ - result_count $$1 "FAIL: " $$fail "$$red"; \ - result_count $$1 "XPASS:" $$xpass "$$red"; \ - result_count $$1 "ERROR:" $$error "$$mgn"; \ - }; \ - { \ - echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ - $(am__rst_title); \ - create_testsuite_report --no-color; \ - echo; \ - echo ".. contents:: :depth: 2"; \ - echo; \ - for b in $$bases; do echo $$b; done \ - | $(am__create_global_log); \ - } >$(TEST_SUITE_LOG).tmp || exit 1; \ - mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ - if $$success; then \ - col="$$grn"; \ - else \ - col="$$red"; \ - test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ - fi; \ - echo "$${col}$$br$${std}"; \ - echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ - echo "$${col}$$br$${std}"; \ - create_testsuite_report --maybe-color; \ - echo "$$col$$br$$std"; \ - if $$success; then :; else \ - echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ - if test -n "$(PACKAGE_BUGREPORT)"; then \ - echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ - fi; \ - echo "$$col$$br$$std"; \ - fi; \ - $$success || exit 1 - -check-TESTS: $(check_PROGRAMS) - @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list - @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list - @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) - @set +e; $(am__set_TESTS_bases); \ - log_list=`for i in $$bases; do echo $$i.log; done`; \ - trs_list=`for i in $$bases; do echo $$i.trs; done`; \ - log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ - $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ - exit $$?; -recheck: all $(check_PROGRAMS) - @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) - @set +e; $(am__set_TESTS_bases); \ - bases=`for i in $$bases; do echo $$i; done \ - | $(am__list_recheck_tests)` || exit 1; \ - log_list=`for i in $$bases; do echo $$i.log; done`; \ - log_list=`echo $$log_list`; \ - $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ - am__force_recheck=am--force-recheck \ - TEST_LOGS="$$log_list"; \ - exit $$? -libarchive_test.log: libarchive_test$(EXEEXT) - @p='libarchive_test$(EXEEXT)'; \ - b='libarchive_test'; \ - $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -bsdtar_test.log: bsdtar_test$(EXEEXT) - @p='bsdtar_test$(EXEEXT)'; \ - b='bsdtar_test'; \ - $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -bsdcpio_test.log: bsdcpio_test$(EXEEXT) - @p='bsdcpio_test$(EXEEXT)'; \ - b='bsdcpio_test'; \ - $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -bsdcat_test.log: bsdcat_test$(EXEEXT) - @p='bsdcat_test$(EXEEXT)'; \ - b='bsdcat_test'; \ - $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -bsdunzip_test.log: bsdunzip_test$(EXEEXT) - @p='bsdunzip_test$(EXEEXT)'; \ - b='bsdunzip_test'; \ - $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -.test.log: - @p='$<'; \ - $(am__set_b); \ - $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -@am__EXEEXT_TRUE@.test$(EXEEXT).log: -@am__EXEEXT_TRUE@ @p='$<'; \ -@am__EXEEXT_TRUE@ $(am__set_b); \ -@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ -@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ -@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ -@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) - $(am__remove_distdir) - test -d "$(distdir)" || mkdir "$(distdir)" - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$(top_distdir)" distdir="$(distdir)" \ - dist-hook - -test -n "$(am__skip_mode_fix)" \ - || find "$(distdir)" -type d ! -perm -755 \ - -exec chmod u+rwx,go+rx {} \; -o \ - ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ - || chmod -R a+r "$(distdir)" -dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz - $(am__post_remove_distdir) - -dist-bzip2: distdir - tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 - $(am__post_remove_distdir) - -dist-lzip: distdir - tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz - $(am__post_remove_distdir) -dist-xz: distdir - tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz - $(am__post_remove_distdir) - -dist-zstd: distdir - tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst - $(am__post_remove_distdir) - -dist-tarZ: distdir - @echo WARNING: "Support for distribution archives compressed with" \ - "legacy program 'compress' is deprecated." >&2 - @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__post_remove_distdir) - -dist-shar: distdir - @echo WARNING: "Support for shar distribution archives is" \ - "deprecated." >&2 - @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz - $(am__post_remove_distdir) -dist-zip: distdir - -rm -f $(distdir).zip - zip -rq $(distdir).zip $(distdir) - $(am__post_remove_distdir) - -dist dist-all: - $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' - $(am__post_remove_distdir) - -# This target untars the dist file and tries a VPATH configuration. Then -# it guarantees that the distribution is self-contained by making another -# tarfile. -distcheck: dist - case '$(DIST_ARCHIVES)' in \ - *.tar.gz*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ - *.tar.bz2*) \ - bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ - *.tar.lz*) \ - lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ - *.tar.xz*) \ - xz -dc $(distdir).tar.xz | $(am__untar) ;;\ - *.tar.Z*) \ - uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ - *.shar.gz*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ - *.zip*) \ - unzip $(distdir).zip ;;\ - *.tar.zst*) \ - zstd -dc $(distdir).tar.zst | $(am__untar) ;;\ - esac - chmod -R a-w $(distdir) - chmod u+w $(distdir) - mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst - chmod a-w $(distdir) - test -d $(distdir)/_build || exit 0; \ - dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ - && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ - && am__cwd=`pwd` \ - && $(am__cd) $(distdir)/_build/sub \ - && ../../configure \ - $(AM_DISTCHECK_CONFIGURE_FLAGS) \ - $(DISTCHECK_CONFIGURE_FLAGS) \ - --srcdir=../.. --prefix="$$dc_install_base" \ - && $(MAKE) $(AM_MAKEFLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \ - && $(MAKE) $(AM_MAKEFLAGS) check \ - && $(MAKE) $(AM_MAKEFLAGS) install \ - && $(MAKE) $(AM_MAKEFLAGS) installcheck \ - && $(MAKE) $(AM_MAKEFLAGS) uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ - distuninstallcheck \ - && chmod -R a-w "$$dc_install_base" \ - && ({ \ - (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ - distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ - } || { rm -rf "$$dc_destdir"; exit 1; }) \ - && rm -rf "$$dc_destdir" \ - && $(MAKE) $(AM_MAKEFLAGS) dist \ - && rm -rf $(DIST_ARCHIVES) \ - && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ - && cd "$$am__cwd" \ - || exit 1 - $(am__post_remove_distdir) - @(echo "$(distdir) archives ready for distribution: "; \ - list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ - sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' -distuninstallcheck: - @test -n '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: trying to run $@ with an empty' \ - '$$(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - $(am__cd) '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left after uninstall:" ; \ - if test -n "$(DESTDIR)"; then \ - echo " (check DESTDIR support)"; \ - fi ; \ - $(distuninstallcheck_listfiles) ; \ - exit 1; } >&2 -distcleancheck: distclean - @if test '$(srcdir)' = . ; then \ - echo "ERROR: distcleancheck can only run from a VPATH build" ; \ - exit 1 ; \ - fi - @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left in build directory after distclean:" ; \ - $(distcleancheck_listfiles) ; \ - exit 1; } >&2 -check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) - $(MAKE) $(AM_MAKEFLAGS) check-TESTS -check: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) check-am -all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) $(MANS) $(DATA) $(HEADERS) \ - config.h -install-binPROGRAMS: install-libLTLIBRARIES - -install-checkPROGRAMS: install-libLTLIBRARIES - -installdirs: - for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(includedir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) install-am -install-exec: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) - -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) - -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f cat/$(DEPDIR)/$(am__dirstamp) - -rm -f cat/$(am__dirstamp) - -rm -f cat/test/$(DEPDIR)/$(am__dirstamp) - -rm -f cat/test/$(am__dirstamp) - -rm -f cpio/$(DEPDIR)/$(am__dirstamp) - -rm -f cpio/$(am__dirstamp) - -rm -f cpio/test/$(DEPDIR)/$(am__dirstamp) - -rm -f cpio/test/$(am__dirstamp) - -rm -f libarchive/$(DEPDIR)/$(am__dirstamp) - -rm -f libarchive/$(am__dirstamp) - -rm -f libarchive/test/$(DEPDIR)/$(am__dirstamp) - -rm -f libarchive/test/$(am__dirstamp) - -rm -f libarchive_fe/$(DEPDIR)/$(am__dirstamp) - -rm -f libarchive_fe/$(am__dirstamp) - -rm -f tar/$(DEPDIR)/$(am__dirstamp) - -rm -f tar/$(am__dirstamp) - -rm -f tar/test/$(DEPDIR)/$(am__dirstamp) - -rm -f tar/test/$(am__dirstamp) - -rm -f test_utils/$(DEPDIR)/$(am__dirstamp) - -rm -f test_utils/$(am__dirstamp) - -rm -f unzip/$(DEPDIR)/$(am__dirstamp) - -rm -f unzip/$(am__dirstamp) - -rm -f unzip/test/$(DEPDIR)/$(am__dirstamp) - -rm -f unzip/test/$(am__dirstamp) - -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) -clean: clean-am - -clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ - clean-libLTLIBRARIES clean-libtool clean-noinstLTLIBRARIES \ - mostlyclean-am - -distclean: distclean-am - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -f cat/$(DEPDIR)/bsdcat-bsdcat.Po - -rm -f cat/$(DEPDIR)/bsdcat-cmdline.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_0.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_empty_gz.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_empty_lz4.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_empty_xz.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_empty_zstd.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_error.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_error_mixed.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_expand_Z.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_expand_bz2.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_expand_gz.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_expand_lz4.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_expand_mixed.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_expand_plain.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_expand_xz.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_expand_zstd.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_help.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_stdin.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_version.Po - -rm -f cpio/$(DEPDIR)/bsdcpio-cmdline.Po - -rm -f cpio/$(DEPDIR)/bsdcpio-cpio.Po - -rm -f cpio/$(DEPDIR)/bsdcpio-cpio_windows.Po - -rm -f cpio/$(DEPDIR)/bsdcpio_test-cmdline.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_0.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_basic.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_cmdline.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_Z.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_bz2.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_grz.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_gz.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lrz.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lz.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lz4.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lzma.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lzo.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_xz.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_zstd.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_format_newc.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_gcpio_compat.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_missing_file.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_0.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_B_upper.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_C_upper.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_J_upper.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_L_upper.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_Z_upper.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_a.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_b64encode.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_c.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_d.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_f.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_grzip.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_help.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_l.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lrzip.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lz4.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lzma.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lzop.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_m.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_passphrase.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_t.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_u.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_uuencode.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_version.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_xz.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_y.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_z.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_zstd.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_owner_parse.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_passthrough_dotdot.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_passthrough_reverse.Po - -rm -f libarchive/$(DEPDIR)/archive_acl.Plo - -rm -f libarchive/$(DEPDIR)/archive_blake2s_ref.Plo - -rm -f libarchive/$(DEPDIR)/archive_blake2sp_ref.Plo - -rm -f libarchive/$(DEPDIR)/archive_check_magic.Plo - -rm -f libarchive/$(DEPDIR)/archive_cmdline.Plo - -rm -f libarchive/$(DEPDIR)/archive_cryptor.Plo - -rm -f libarchive/$(DEPDIR)/archive_digest.Plo - -rm -f libarchive/$(DEPDIR)/archive_disk_acl_darwin.Plo - -rm -f libarchive/$(DEPDIR)/archive_disk_acl_freebsd.Plo - -rm -f libarchive/$(DEPDIR)/archive_disk_acl_linux.Plo - -rm -f libarchive/$(DEPDIR)/archive_disk_acl_sunos.Plo - -rm -f libarchive/$(DEPDIR)/archive_entry.Plo - -rm -f libarchive/$(DEPDIR)/archive_entry_copy_bhfi.Plo - -rm -f libarchive/$(DEPDIR)/archive_entry_copy_stat.Plo - -rm -f libarchive/$(DEPDIR)/archive_entry_link_resolver.Plo - -rm -f libarchive/$(DEPDIR)/archive_entry_sparse.Plo - -rm -f libarchive/$(DEPDIR)/archive_entry_stat.Plo - -rm -f libarchive/$(DEPDIR)/archive_entry_strmode.Plo - -rm -f libarchive/$(DEPDIR)/archive_entry_xattr.Plo - -rm -f libarchive/$(DEPDIR)/archive_getdate.Plo - -rm -f libarchive/$(DEPDIR)/archive_hmac.Plo - -rm -f libarchive/$(DEPDIR)/archive_match.Plo - -rm -f libarchive/$(DEPDIR)/archive_options.Plo - -rm -f libarchive/$(DEPDIR)/archive_pack_dev.Plo - -rm -f libarchive/$(DEPDIR)/archive_pathmatch.Plo - -rm -f libarchive/$(DEPDIR)/archive_ppmd7.Plo - -rm -f libarchive/$(DEPDIR)/archive_ppmd8.Plo - -rm -f libarchive/$(DEPDIR)/archive_random.Plo - -rm -f libarchive/$(DEPDIR)/archive_rb.Plo - -rm -f libarchive/$(DEPDIR)/archive_read.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_add_passphrase.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_append_filter.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_data_into_fd.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_disk_entry_from_file.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_disk_posix.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_disk_set_standard_lookup.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_disk_windows.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_extract.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_extract2.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_open_fd.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_open_file.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_open_filename.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_open_memory.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_set_format.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_set_options.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_all.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_by_code.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_bzip2.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_compress.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_grzip.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_gzip.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_lrzip.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_lz4.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_lzop.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_none.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_program.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_rpm.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_uu.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_xz.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_zstd.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_7zip.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_all.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_ar.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_by_code.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_cab.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_cpio.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_empty.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_iso9660.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_lha.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_mtree.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_rar.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_rar5.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_raw.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_tar.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_warc.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_xar.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_zip.Plo - -rm -f libarchive/$(DEPDIR)/archive_string.Plo - -rm -f libarchive/$(DEPDIR)/archive_string_sprintf.Plo - -rm -f libarchive/$(DEPDIR)/archive_util.Plo - -rm -f libarchive/$(DEPDIR)/archive_version_details.Plo - -rm -f libarchive/$(DEPDIR)/archive_virtual.Plo - -rm -f libarchive/$(DEPDIR)/archive_windows.Plo - -rm -f libarchive/$(DEPDIR)/archive_write.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_b64encode.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_by_name.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_bzip2.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_compress.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_grzip.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_gzip.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_lrzip.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_lz4.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_lzop.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_none.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_program.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_uuencode.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_xz.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_zstd.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_disk_posix.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_disk_set_standard_lookup.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_disk_windows.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_open_fd.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_open_file.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_open_filename.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_open_memory.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_7zip.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_ar.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_by_name.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_cpio.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_cpio_binary.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_cpio_newc.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_cpio_odc.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_filter_by_ext.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_gnutar.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_iso9660.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_mtree.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_pax.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_raw.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_shar.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_ustar.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_v7tar.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_warc.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_xar.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_zip.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_options.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_passphrase.Plo - -rm -f libarchive/$(DEPDIR)/filter_fork_posix.Plo - -rm -f libarchive/$(DEPDIR)/filter_fork_windows.Plo - -rm -f libarchive/$(DEPDIR)/test-archive_acl.Po - -rm -f libarchive/$(DEPDIR)/test-archive_blake2s_ref.Po - -rm -f libarchive/$(DEPDIR)/test-archive_blake2sp_ref.Po - -rm -f libarchive/$(DEPDIR)/test-archive_check_magic.Po - -rm -f libarchive/$(DEPDIR)/test-archive_cmdline.Po - -rm -f libarchive/$(DEPDIR)/test-archive_cryptor.Po - -rm -f libarchive/$(DEPDIR)/test-archive_digest.Po - -rm -f libarchive/$(DEPDIR)/test-archive_disk_acl_darwin.Po - -rm -f libarchive/$(DEPDIR)/test-archive_disk_acl_freebsd.Po - -rm -f libarchive/$(DEPDIR)/test-archive_disk_acl_linux.Po - -rm -f libarchive/$(DEPDIR)/test-archive_disk_acl_sunos.Po - -rm -f libarchive/$(DEPDIR)/test-archive_entry.Po - -rm -f libarchive/$(DEPDIR)/test-archive_entry_copy_bhfi.Po - -rm -f libarchive/$(DEPDIR)/test-archive_entry_copy_stat.Po - -rm -f libarchive/$(DEPDIR)/test-archive_entry_link_resolver.Po - -rm -f libarchive/$(DEPDIR)/test-archive_entry_sparse.Po - -rm -f libarchive/$(DEPDIR)/test-archive_entry_stat.Po - -rm -f libarchive/$(DEPDIR)/test-archive_entry_strmode.Po - -rm -f libarchive/$(DEPDIR)/test-archive_entry_xattr.Po - -rm -f libarchive/$(DEPDIR)/test-archive_getdate.Po - -rm -f libarchive/$(DEPDIR)/test-archive_hmac.Po - -rm -f libarchive/$(DEPDIR)/test-archive_match.Po - -rm -f libarchive/$(DEPDIR)/test-archive_options.Po - -rm -f libarchive/$(DEPDIR)/test-archive_pack_dev.Po - -rm -f libarchive/$(DEPDIR)/test-archive_pathmatch.Po - -rm -f libarchive/$(DEPDIR)/test-archive_ppmd7.Po - -rm -f libarchive/$(DEPDIR)/test-archive_ppmd8.Po - -rm -f libarchive/$(DEPDIR)/test-archive_random.Po - -rm -f libarchive/$(DEPDIR)/test-archive_rb.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_add_passphrase.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_append_filter.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_data_into_fd.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_disk_entry_from_file.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_disk_posix.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_disk_set_standard_lookup.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_disk_windows.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_extract.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_extract2.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_open_fd.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_open_file.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_open_filename.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_open_memory.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_set_format.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_set_options.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_all.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_by_code.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_bzip2.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_compress.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_grzip.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_gzip.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_lrzip.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_lz4.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_lzop.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_none.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_program.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_rpm.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_uu.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_xz.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_zstd.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_7zip.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_all.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_ar.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_by_code.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_cab.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_cpio.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_empty.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_iso9660.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_lha.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_mtree.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_rar.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_rar5.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_raw.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_tar.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_warc.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_xar.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_zip.Po - -rm -f libarchive/$(DEPDIR)/test-archive_string.Po - -rm -f libarchive/$(DEPDIR)/test-archive_string_sprintf.Po - -rm -f libarchive/$(DEPDIR)/test-archive_util.Po - -rm -f libarchive/$(DEPDIR)/test-archive_version_details.Po - -rm -f libarchive/$(DEPDIR)/test-archive_virtual.Po - -rm -f libarchive/$(DEPDIR)/test-archive_windows.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_b64encode.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_by_name.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_bzip2.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_compress.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_grzip.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_gzip.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_lrzip.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_lz4.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_lzop.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_none.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_program.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_uuencode.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_xz.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_zstd.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_disk_posix.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_disk_set_standard_lookup.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_disk_windows.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_open_fd.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_open_file.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_open_filename.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_open_memory.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_7zip.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_ar.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_by_name.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_cpio.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_binary.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_newc.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_odc.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_filter_by_ext.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_gnutar.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_iso9660.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_mtree.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_pax.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_raw.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_shar.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_ustar.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_v7tar.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_warc.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_xar.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_zip.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_options.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_passphrase.Po - -rm -f libarchive/$(DEPDIR)/test-filter_fork_posix.Po - -rm -f libarchive/$(DEPDIR)/test-filter_fork_windows.Po - -rm -f libarchive/$(DEPDIR)/test-xxhash.Po - -rm -f libarchive/$(DEPDIR)/xxhash.Plo - -rm -f libarchive/test/$(DEPDIR)/test-read_open_memory.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_acl_nfs4.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_acl_pax.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_acl_platform_nfs4.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_acl_platform_posix1e.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_acl_posix1e.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_acl_text.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_api_feature.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_clear_error.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_cmdline.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_digest.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_getdate.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_match_owner.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_match_path.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_match_time.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_pathmatch.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_read_add_passphrase.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice_open_fd.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice_open_filename.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_read_multiple_data_objects.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_read_next_header_empty.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_read_next_header_raw.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_read_open2.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_read_set_filter_option.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_read_set_format_option.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_read_set_option.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_read_set_options.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_read_support.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_set_error.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_string.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_string_conversion.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_write_add_filter_by_name.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_write_set_filter_option.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_by_name.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_filter_by_ext.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_option.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_write_set_option.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_write_set_options.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_write_set_passphrase.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_bad_fd.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_bzip2.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_cpio.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_gtar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_gzip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_lz4.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_lzip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_lzma.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_lzop.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_mac.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_perl_archive_tar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_plexus_archiver_tar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_solaris_pax_sparse.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_solaris_tar_acl.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_star_acl.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_tar_directory.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_tar_hardlink.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_uudecode.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_uudecode_large.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_xz.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_zip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_zstd.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_empty_write.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_entry.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_entry_strmode.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_extattr_freebsd.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_filter_count.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_fuzz.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_gnutar_filename_encoding.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_link_resolver.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_open_failure.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_open_fd.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_open_file.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_open_filename.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_pax_filename_encoding.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_pax_xattr_header.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_data_large.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_disk.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_disk_directory_traversals.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_disk_entry_from_file.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_extract.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_file_nonexistent.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_filter_compress.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_filter_grzip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_filter_lrzip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_filter_lzop.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_filter_lzop_multiple_parts.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_filter_program.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_filter_program_signature.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_filter_uudecode.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_filter_uudecode_raw.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_7zip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_data.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_header.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_partially.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_7zip_malformed.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_7zip_packinfo_digests.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_ar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cab.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cab_filename.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_afio.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_Z.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_be.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_bz2.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_gz.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_le.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_lzip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_lzma.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_xz.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_filename.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_odc.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_bzip2_rpm.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_gzip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_gzip_rpm.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4c_Z.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_empty.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_gtar_filename.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_gtar_gz.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_gtar_lzma.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_gtar_sparse.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_gtar_sparse_skip_entry.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_iso_Z.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_iso_multi_extent.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_iso_xorriso.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_bz2.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_long.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_rr.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_versioned.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_isorr_bz2.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_isorr_ce.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_isorr_new_bz2.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_isorr_rr_moved.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_isozisofs_bz2.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_lha.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_lha_bugfix_0.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_lha_filename.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_lha_filename_utf16.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_mtree.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_mtree_crash747.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_pax_bz2.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_rar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_rar5.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_data.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_header.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_partially.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_rar_filter.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_rar_invalid1.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_raw.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_tar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_tar_concatenated.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_filename.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_pax.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_with_gnulabel.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_tar_filename.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_tar_invalid_pax_size.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_tbz.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_tgz.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_tlz.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_txz.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_tz.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_ustar_filename.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_warc.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_xar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_7075_utf8_paths.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_comment_stored.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_data.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_header.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_partially.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_extra_padding.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_filename.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_high_compression.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_jar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_mac_metadata.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_malformed.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_msdos.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_nested.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_nofiletype.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_padded.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_sfx.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_traditional_encryption_data.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_winzip_aes.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_winzip_aes_large.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_with_invalid_traditional_eocd.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_zip64.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_large.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_pax_truncated.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_pax_xattr_rht_security_selinux.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_pax_xattr_schily.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_position.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_set_format.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_too_many_filters.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_truncated.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_truncated_filter.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_short_writes.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_sparse_basic.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_tar_filenames.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_tar_large.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_ustar_filename_encoding.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_ustar_filenames.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_warn_missing_hardlink_target.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_appledouble.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_failures.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_fixup.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_hardlink.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_hfs_compression.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_lookup.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_mac_metadata.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_no_hfs_compression.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_perms.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_secure.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_secure744.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_secure745.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_secure746.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_sparse.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_symlink.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_times.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_b64encode.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_bzip2.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_compress.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_gzip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_gzip_timestamp.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_lrzip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_lz4.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_lzip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_lzma.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_lzop.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_program.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_uuencode.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_xz.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_zstd.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_7zip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_7zip_empty.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_7zip_large.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_ar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_cpio.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_cpio_empty.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_cpio_newc.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_cpio_odc.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_gnutar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_gnutar_filenames.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_iso9660.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_boot.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_empty.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_filename.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_zisofs.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_mtree.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_mtree_absolute_path.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_mtree_classic.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_mtree_classic_indent.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_mtree_fflags.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_mtree_no_separator.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_mtree_quoted_filename.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_pax.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_raw.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_raw_b64.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_shar_empty.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_tar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_tar_empty.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_tar_sparse.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_tar_ustar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_tar_v7tar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_warc.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_warc_empty.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_xar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_xar_empty.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_zip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_zip_compression_store.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_zip_empty.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_zip_empty_zip64.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_zip_entry_size_unset.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_zip_file.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_zip_file_zip64.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_zip_large.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_zip_zip64.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_open_memory.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_read_format_zip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_xattr_platform.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_zip_filename_encoding.Po - -rm -f libarchive_fe/$(DEPDIR)/la-err.Plo - -rm -f libarchive_fe/$(DEPDIR)/la-line_reader.Plo - -rm -f libarchive_fe/$(DEPDIR)/la-passphrase.Plo - -rm -f tar/$(DEPDIR)/bsdtar-bsdtar.Po - -rm -f tar/$(DEPDIR)/bsdtar-bsdtar_windows.Po - -rm -f tar/$(DEPDIR)/bsdtar-cmdline.Po - -rm -f tar/$(DEPDIR)/bsdtar-creation_set.Po - -rm -f tar/$(DEPDIR)/bsdtar-read.Po - -rm -f tar/$(DEPDIR)/bsdtar-subst.Po - -rm -f tar/$(DEPDIR)/bsdtar-util.Po - -rm -f tar/$(DEPDIR)/bsdtar-write.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_0.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_basic.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_copy.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_empty_mtree.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_Z.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_bz2.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_grz.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_gz.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lrz.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lz.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lz4.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lzma.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lzo.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_xz.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_zstd.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_format_newc.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_help.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_leading_slash.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_missing_file.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_C_mtree.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_C_upper.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_H_upper.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_L_upper.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_O_upper.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_T_upper.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_U_upper.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_X_upper.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_a.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_acls.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_b.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_b64encode.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_exclude.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_exclude_vcs.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_fflags.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_gid_gname.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_grzip.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_ignore_zeros.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_j.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_k.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_keep_newer_files.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_lrzip.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_lz4.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_lzma.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_lzop.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_n.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_newer_than.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_nodump.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_older_than.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_passphrase.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_q.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_r.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_s.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_safe_writes.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_uid_uname.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_uuencode.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_xattrs.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_xz.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_z.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_zstd.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_patterns.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_print_longpath.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_stdio.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_strip_components.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_symlink_dir.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_version.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_windows.Po - -rm -f test_utils/$(DEPDIR)/bsdcat_test-test_main.Po - -rm -f test_utils/$(DEPDIR)/bsdcat_test-test_utils.Po - -rm -f test_utils/$(DEPDIR)/bsdcpio_test-test_main.Po - -rm -f test_utils/$(DEPDIR)/bsdcpio_test-test_utils.Po - -rm -f test_utils/$(DEPDIR)/bsdtar_test-test_main.Po - -rm -f test_utils/$(DEPDIR)/bsdtar_test-test_utils.Po - -rm -f test_utils/$(DEPDIR)/bsdunzip_test-test_main.Po - -rm -f test_utils/$(DEPDIR)/bsdunzip_test-test_utils.Po - -rm -f test_utils/$(DEPDIR)/libarchive_test-test_main.Po - -rm -f test_utils/$(DEPDIR)/libarchive_test-test_utils.Po - -rm -f unzip/$(DEPDIR)/bsdunzip-bsdunzip.Po - -rm -f unzip/$(DEPDIR)/bsdunzip-cmdline.Po - -rm -f unzip/$(DEPDIR)/bsdunzip-la_getline.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_0.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_C.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_L.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_P_encryption.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_Z1.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_basic.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_d.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_glob.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_j.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_n.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_not_exist.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_o.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_p.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_q.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_singlefile.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_t.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_t_bad.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_version.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_x.Po - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-hdr distclean-libtool distclean-local distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: install-includeHEADERS install-man \ - install-pkgconfigDATA - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: install-binPROGRAMS install-libLTLIBRARIES - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: install-man1 install-man3 install-man5 - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf $(top_srcdir)/autom4te.cache - -rm -f cat/$(DEPDIR)/bsdcat-bsdcat.Po - -rm -f cat/$(DEPDIR)/bsdcat-cmdline.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_0.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_empty_gz.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_empty_lz4.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_empty_xz.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_empty_zstd.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_error.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_error_mixed.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_expand_Z.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_expand_bz2.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_expand_gz.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_expand_lz4.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_expand_mixed.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_expand_plain.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_expand_xz.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_expand_zstd.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_help.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_stdin.Po - -rm -f cat/test/$(DEPDIR)/bsdcat_test-test_version.Po - -rm -f cpio/$(DEPDIR)/bsdcpio-cmdline.Po - -rm -f cpio/$(DEPDIR)/bsdcpio-cpio.Po - -rm -f cpio/$(DEPDIR)/bsdcpio-cpio_windows.Po - -rm -f cpio/$(DEPDIR)/bsdcpio_test-cmdline.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_0.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_basic.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_cmdline.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_Z.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_bz2.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_grz.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_gz.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lrz.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lz.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lz4.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lzma.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_lzo.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_xz.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_extract_cpio_zstd.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_format_newc.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_gcpio_compat.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_missing_file.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_0.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_B_upper.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_C_upper.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_J_upper.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_L_upper.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_Z_upper.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_a.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_b64encode.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_c.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_d.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_f.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_grzip.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_help.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_l.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lrzip.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lz4.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lzma.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_lzop.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_m.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_passphrase.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_t.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_u.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_uuencode.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_version.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_xz.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_y.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_z.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_option_zstd.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_owner_parse.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_passthrough_dotdot.Po - -rm -f cpio/test/$(DEPDIR)/bsdcpio_test-test_passthrough_reverse.Po - -rm -f libarchive/$(DEPDIR)/archive_acl.Plo - -rm -f libarchive/$(DEPDIR)/archive_blake2s_ref.Plo - -rm -f libarchive/$(DEPDIR)/archive_blake2sp_ref.Plo - -rm -f libarchive/$(DEPDIR)/archive_check_magic.Plo - -rm -f libarchive/$(DEPDIR)/archive_cmdline.Plo - -rm -f libarchive/$(DEPDIR)/archive_cryptor.Plo - -rm -f libarchive/$(DEPDIR)/archive_digest.Plo - -rm -f libarchive/$(DEPDIR)/archive_disk_acl_darwin.Plo - -rm -f libarchive/$(DEPDIR)/archive_disk_acl_freebsd.Plo - -rm -f libarchive/$(DEPDIR)/archive_disk_acl_linux.Plo - -rm -f libarchive/$(DEPDIR)/archive_disk_acl_sunos.Plo - -rm -f libarchive/$(DEPDIR)/archive_entry.Plo - -rm -f libarchive/$(DEPDIR)/archive_entry_copy_bhfi.Plo - -rm -f libarchive/$(DEPDIR)/archive_entry_copy_stat.Plo - -rm -f libarchive/$(DEPDIR)/archive_entry_link_resolver.Plo - -rm -f libarchive/$(DEPDIR)/archive_entry_sparse.Plo - -rm -f libarchive/$(DEPDIR)/archive_entry_stat.Plo - -rm -f libarchive/$(DEPDIR)/archive_entry_strmode.Plo - -rm -f libarchive/$(DEPDIR)/archive_entry_xattr.Plo - -rm -f libarchive/$(DEPDIR)/archive_getdate.Plo - -rm -f libarchive/$(DEPDIR)/archive_hmac.Plo - -rm -f libarchive/$(DEPDIR)/archive_match.Plo - -rm -f libarchive/$(DEPDIR)/archive_options.Plo - -rm -f libarchive/$(DEPDIR)/archive_pack_dev.Plo - -rm -f libarchive/$(DEPDIR)/archive_pathmatch.Plo - -rm -f libarchive/$(DEPDIR)/archive_ppmd7.Plo - -rm -f libarchive/$(DEPDIR)/archive_ppmd8.Plo - -rm -f libarchive/$(DEPDIR)/archive_random.Plo - -rm -f libarchive/$(DEPDIR)/archive_rb.Plo - -rm -f libarchive/$(DEPDIR)/archive_read.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_add_passphrase.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_append_filter.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_data_into_fd.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_disk_entry_from_file.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_disk_posix.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_disk_set_standard_lookup.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_disk_windows.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_extract.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_extract2.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_open_fd.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_open_file.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_open_filename.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_open_memory.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_set_format.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_set_options.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_all.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_by_code.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_bzip2.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_compress.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_grzip.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_gzip.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_lrzip.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_lz4.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_lzop.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_none.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_program.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_rpm.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_uu.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_xz.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_filter_zstd.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_7zip.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_all.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_ar.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_by_code.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_cab.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_cpio.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_empty.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_iso9660.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_lha.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_mtree.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_rar.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_rar5.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_raw.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_tar.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_warc.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_xar.Plo - -rm -f libarchive/$(DEPDIR)/archive_read_support_format_zip.Plo - -rm -f libarchive/$(DEPDIR)/archive_string.Plo - -rm -f libarchive/$(DEPDIR)/archive_string_sprintf.Plo - -rm -f libarchive/$(DEPDIR)/archive_util.Plo - -rm -f libarchive/$(DEPDIR)/archive_version_details.Plo - -rm -f libarchive/$(DEPDIR)/archive_virtual.Plo - -rm -f libarchive/$(DEPDIR)/archive_windows.Plo - -rm -f libarchive/$(DEPDIR)/archive_write.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_b64encode.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_by_name.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_bzip2.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_compress.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_grzip.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_gzip.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_lrzip.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_lz4.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_lzop.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_none.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_program.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_uuencode.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_xz.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_add_filter_zstd.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_disk_posix.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_disk_set_standard_lookup.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_disk_windows.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_open_fd.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_open_file.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_open_filename.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_open_memory.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_7zip.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_ar.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_by_name.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_cpio.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_cpio_binary.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_cpio_newc.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_cpio_odc.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_filter_by_ext.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_gnutar.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_iso9660.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_mtree.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_pax.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_raw.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_shar.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_ustar.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_v7tar.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_warc.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_xar.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_format_zip.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_options.Plo - -rm -f libarchive/$(DEPDIR)/archive_write_set_passphrase.Plo - -rm -f libarchive/$(DEPDIR)/filter_fork_posix.Plo - -rm -f libarchive/$(DEPDIR)/filter_fork_windows.Plo - -rm -f libarchive/$(DEPDIR)/test-archive_acl.Po - -rm -f libarchive/$(DEPDIR)/test-archive_blake2s_ref.Po - -rm -f libarchive/$(DEPDIR)/test-archive_blake2sp_ref.Po - -rm -f libarchive/$(DEPDIR)/test-archive_check_magic.Po - -rm -f libarchive/$(DEPDIR)/test-archive_cmdline.Po - -rm -f libarchive/$(DEPDIR)/test-archive_cryptor.Po - -rm -f libarchive/$(DEPDIR)/test-archive_digest.Po - -rm -f libarchive/$(DEPDIR)/test-archive_disk_acl_darwin.Po - -rm -f libarchive/$(DEPDIR)/test-archive_disk_acl_freebsd.Po - -rm -f libarchive/$(DEPDIR)/test-archive_disk_acl_linux.Po - -rm -f libarchive/$(DEPDIR)/test-archive_disk_acl_sunos.Po - -rm -f libarchive/$(DEPDIR)/test-archive_entry.Po - -rm -f libarchive/$(DEPDIR)/test-archive_entry_copy_bhfi.Po - -rm -f libarchive/$(DEPDIR)/test-archive_entry_copy_stat.Po - -rm -f libarchive/$(DEPDIR)/test-archive_entry_link_resolver.Po - -rm -f libarchive/$(DEPDIR)/test-archive_entry_sparse.Po - -rm -f libarchive/$(DEPDIR)/test-archive_entry_stat.Po - -rm -f libarchive/$(DEPDIR)/test-archive_entry_strmode.Po - -rm -f libarchive/$(DEPDIR)/test-archive_entry_xattr.Po - -rm -f libarchive/$(DEPDIR)/test-archive_getdate.Po - -rm -f libarchive/$(DEPDIR)/test-archive_hmac.Po - -rm -f libarchive/$(DEPDIR)/test-archive_match.Po - -rm -f libarchive/$(DEPDIR)/test-archive_options.Po - -rm -f libarchive/$(DEPDIR)/test-archive_pack_dev.Po - -rm -f libarchive/$(DEPDIR)/test-archive_pathmatch.Po - -rm -f libarchive/$(DEPDIR)/test-archive_ppmd7.Po - -rm -f libarchive/$(DEPDIR)/test-archive_ppmd8.Po - -rm -f libarchive/$(DEPDIR)/test-archive_random.Po - -rm -f libarchive/$(DEPDIR)/test-archive_rb.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_add_passphrase.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_append_filter.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_data_into_fd.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_disk_entry_from_file.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_disk_posix.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_disk_set_standard_lookup.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_disk_windows.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_extract.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_extract2.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_open_fd.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_open_file.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_open_filename.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_open_memory.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_set_format.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_set_options.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_all.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_by_code.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_bzip2.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_compress.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_grzip.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_gzip.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_lrzip.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_lz4.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_lzop.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_none.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_program.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_rpm.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_uu.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_xz.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_filter_zstd.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_7zip.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_all.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_ar.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_by_code.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_cab.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_cpio.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_empty.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_iso9660.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_lha.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_mtree.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_rar.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_rar5.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_raw.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_tar.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_warc.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_xar.Po - -rm -f libarchive/$(DEPDIR)/test-archive_read_support_format_zip.Po - -rm -f libarchive/$(DEPDIR)/test-archive_string.Po - -rm -f libarchive/$(DEPDIR)/test-archive_string_sprintf.Po - -rm -f libarchive/$(DEPDIR)/test-archive_util.Po - -rm -f libarchive/$(DEPDIR)/test-archive_version_details.Po - -rm -f libarchive/$(DEPDIR)/test-archive_virtual.Po - -rm -f libarchive/$(DEPDIR)/test-archive_windows.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_b64encode.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_by_name.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_bzip2.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_compress.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_grzip.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_gzip.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_lrzip.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_lz4.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_lzop.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_none.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_program.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_uuencode.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_xz.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_add_filter_zstd.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_disk_posix.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_disk_set_standard_lookup.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_disk_windows.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_open_fd.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_open_file.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_open_filename.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_open_memory.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_7zip.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_ar.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_by_name.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_cpio.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_binary.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_newc.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_cpio_odc.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_filter_by_ext.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_gnutar.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_iso9660.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_mtree.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_pax.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_raw.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_shar.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_ustar.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_v7tar.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_warc.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_xar.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_format_zip.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_options.Po - -rm -f libarchive/$(DEPDIR)/test-archive_write_set_passphrase.Po - -rm -f libarchive/$(DEPDIR)/test-filter_fork_posix.Po - -rm -f libarchive/$(DEPDIR)/test-filter_fork_windows.Po - -rm -f libarchive/$(DEPDIR)/test-xxhash.Po - -rm -f libarchive/$(DEPDIR)/xxhash.Plo - -rm -f libarchive/test/$(DEPDIR)/test-read_open_memory.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_acl_nfs4.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_acl_pax.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_acl_platform_nfs4.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_acl_platform_posix1e.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_acl_posix1e.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_acl_text.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_api_feature.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_clear_error.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_cmdline.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_digest.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_getdate.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_match_owner.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_match_path.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_match_time.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_pathmatch.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_read_add_passphrase.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice_open_fd.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_read_close_twice_open_filename.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_read_multiple_data_objects.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_read_next_header_empty.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_read_next_header_raw.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_read_open2.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_read_set_filter_option.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_read_set_format_option.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_read_set_option.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_read_set_options.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_read_support.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_set_error.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_string.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_string_conversion.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_write_add_filter_by_name.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_write_set_filter_option.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_by_name.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_filter_by_ext.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_write_set_format_option.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_write_set_option.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_write_set_options.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_archive_write_set_passphrase.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_bad_fd.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_bzip2.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_cpio.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_gtar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_gzip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_lz4.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_lzip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_lzma.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_lzop.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_mac.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_perl_archive_tar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_plexus_archiver_tar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_solaris_pax_sparse.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_solaris_tar_acl.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_star_acl.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_tar_directory.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_tar_hardlink.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_uudecode.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_uudecode_large.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_xz.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_zip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_compat_zstd.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_empty_write.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_entry.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_entry_strmode.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_extattr_freebsd.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_filter_count.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_fuzz.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_gnutar_filename_encoding.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_link_resolver.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_open_failure.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_open_fd.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_open_file.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_open_filename.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_pax_filename_encoding.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_pax_xattr_header.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_data_large.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_disk.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_disk_directory_traversals.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_disk_entry_from_file.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_extract.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_file_nonexistent.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_filter_compress.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_filter_grzip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_filter_lrzip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_filter_lzop.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_filter_lzop_multiple_parts.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_filter_program.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_filter_program_signature.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_filter_uudecode.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_filter_uudecode_raw.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_7zip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_data.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_header.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_7zip_encryption_partially.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_7zip_malformed.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_7zip_packinfo_digests.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_ar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cab.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cab_filename.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_afio.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_Z.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_be.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_bz2.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_gz.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_le.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_lzip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_lzma.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_bin_xz.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_filename.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_odc.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_bzip2_rpm.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_gzip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4_gzip_rpm.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_cpio_svr4c_Z.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_empty.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_gtar_filename.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_gtar_gz.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_gtar_lzma.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_gtar_sparse.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_gtar_sparse_skip_entry.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_iso_Z.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_iso_multi_extent.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_iso_xorriso.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_bz2.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_long.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_rr.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_isojoliet_versioned.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_isorr_bz2.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_isorr_ce.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_isorr_new_bz2.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_isorr_rr_moved.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_isozisofs_bz2.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_lha.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_lha_bugfix_0.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_lha_filename.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_lha_filename_utf16.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_mtree.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_mtree_crash747.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_pax_bz2.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_rar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_rar5.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_data.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_header.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_rar_encryption_partially.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_rar_filter.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_rar_invalid1.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_raw.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_tar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_tar_concatenated.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_filename.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_pax.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_tar_empty_with_gnulabel.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_tar_filename.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_tar_invalid_pax_size.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_tbz.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_tgz.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_tlz.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_txz.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_tz.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_ustar_filename.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_warc.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_xar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_7075_utf8_paths.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_comment_stored.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_data.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_header.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_encryption_partially.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_extra_padding.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_filename.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_high_compression.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_jar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_mac_metadata.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_malformed.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_msdos.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_nested.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_nofiletype.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_padded.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_sfx.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_traditional_encryption_data.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_winzip_aes.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_winzip_aes_large.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_with_invalid_traditional_eocd.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_format_zip_zip64.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_large.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_pax_truncated.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_pax_xattr_rht_security_selinux.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_pax_xattr_schily.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_position.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_set_format.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_too_many_filters.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_truncated.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_read_truncated_filter.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_short_writes.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_sparse_basic.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_tar_filenames.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_tar_large.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_ustar_filename_encoding.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_ustar_filenames.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_warn_missing_hardlink_target.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_appledouble.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_failures.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_fixup.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_hardlink.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_hfs_compression.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_lookup.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_mac_metadata.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_no_hfs_compression.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_perms.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_secure.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_secure744.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_secure745.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_secure746.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_sparse.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_symlink.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_disk_times.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_b64encode.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_bzip2.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_compress.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_gzip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_gzip_timestamp.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_lrzip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_lz4.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_lzip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_lzma.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_lzop.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_program.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_uuencode.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_xz.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_filter_zstd.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_7zip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_7zip_empty.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_7zip_large.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_ar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_cpio.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_cpio_empty.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_cpio_newc.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_cpio_odc.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_gnutar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_gnutar_filenames.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_iso9660.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_boot.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_empty.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_filename.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_iso9660_zisofs.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_mtree.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_mtree_absolute_path.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_mtree_classic.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_mtree_classic_indent.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_mtree_fflags.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_mtree_no_separator.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_mtree_quoted_filename.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_pax.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_raw.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_raw_b64.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_shar_empty.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_tar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_tar_empty.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_tar_sparse.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_tar_ustar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_tar_v7tar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_warc.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_warc_empty.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_xar.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_xar_empty.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_zip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_zip_compression_store.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_zip_empty.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_zip_empty_zip64.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_zip_entry_size_unset.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_zip_file.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_zip_file_zip64.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_zip_large.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_format_zip_zip64.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_open_memory.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_write_read_format_zip.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_xattr_platform.Po - -rm -f libarchive/test/$(DEPDIR)/test-test_zip_filename_encoding.Po - -rm -f libarchive_fe/$(DEPDIR)/la-err.Plo - -rm -f libarchive_fe/$(DEPDIR)/la-line_reader.Plo - -rm -f libarchive_fe/$(DEPDIR)/la-passphrase.Plo - -rm -f tar/$(DEPDIR)/bsdtar-bsdtar.Po - -rm -f tar/$(DEPDIR)/bsdtar-bsdtar_windows.Po - -rm -f tar/$(DEPDIR)/bsdtar-cmdline.Po - -rm -f tar/$(DEPDIR)/bsdtar-creation_set.Po - -rm -f tar/$(DEPDIR)/bsdtar-read.Po - -rm -f tar/$(DEPDIR)/bsdtar-subst.Po - -rm -f tar/$(DEPDIR)/bsdtar-util.Po - -rm -f tar/$(DEPDIR)/bsdtar-write.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_0.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_basic.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_copy.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_empty_mtree.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_Z.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_bz2.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_grz.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_gz.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lrz.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lz.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lz4.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lzma.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_lzo.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_xz.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_extract_tar_zstd.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_format_newc.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_help.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_leading_slash.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_missing_file.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_C_mtree.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_C_upper.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_H_upper.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_L_upper.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_O_upper.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_T_upper.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_U_upper.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_X_upper.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_a.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_acls.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_b.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_b64encode.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_exclude.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_exclude_vcs.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_fflags.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_gid_gname.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_grzip.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_ignore_zeros.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_j.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_k.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_keep_newer_files.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_lrzip.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_lz4.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_lzma.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_lzop.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_n.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_newer_than.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_nodump.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_older_than.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_passphrase.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_q.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_r.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_s.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_safe_writes.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_uid_uname.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_uuencode.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_xattrs.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_xz.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_z.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_option_zstd.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_patterns.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_print_longpath.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_stdio.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_strip_components.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_symlink_dir.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_version.Po - -rm -f tar/test/$(DEPDIR)/bsdtar_test-test_windows.Po - -rm -f test_utils/$(DEPDIR)/bsdcat_test-test_main.Po - -rm -f test_utils/$(DEPDIR)/bsdcat_test-test_utils.Po - -rm -f test_utils/$(DEPDIR)/bsdcpio_test-test_main.Po - -rm -f test_utils/$(DEPDIR)/bsdcpio_test-test_utils.Po - -rm -f test_utils/$(DEPDIR)/bsdtar_test-test_main.Po - -rm -f test_utils/$(DEPDIR)/bsdtar_test-test_utils.Po - -rm -f test_utils/$(DEPDIR)/bsdunzip_test-test_main.Po - -rm -f test_utils/$(DEPDIR)/bsdunzip_test-test_utils.Po - -rm -f test_utils/$(DEPDIR)/libarchive_test-test_main.Po - -rm -f test_utils/$(DEPDIR)/libarchive_test-test_utils.Po - -rm -f unzip/$(DEPDIR)/bsdunzip-bsdunzip.Po - -rm -f unzip/$(DEPDIR)/bsdunzip-cmdline.Po - -rm -f unzip/$(DEPDIR)/bsdunzip-la_getline.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_0.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_C.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_L.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_P_encryption.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_Z1.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_basic.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_d.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_glob.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_j.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_n.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_not_exist.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_o.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_p.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_q.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_singlefile.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_t.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_t_bad.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_version.Po - -rm -f unzip/test/$(DEPDIR)/bsdunzip_test-test_x.Po - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-binPROGRAMS uninstall-includeHEADERS \ - uninstall-libLTLIBRARIES uninstall-man uninstall-pkgconfigDATA - -uninstall-man: uninstall-man1 uninstall-man3 uninstall-man5 - -.MAKE: all check check-am install install-am install-exec \ - install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles am--refresh check \ - check-TESTS check-am clean clean-binPROGRAMS \ - clean-checkPROGRAMS clean-cscope clean-generic \ - clean-libLTLIBRARIES clean-libtool clean-noinstLTLIBRARIES \ - cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ - dist-gzip dist-hook dist-lzip dist-shar dist-tarZ dist-xz \ - dist-zip dist-zstd distcheck distclean distclean-compile \ - distclean-generic distclean-hdr distclean-libtool \ - distclean-local distclean-tags distcleancheck distdir \ - distuninstallcheck dvi dvi-am html html-am info info-am \ - install install-am install-binPROGRAMS install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am \ - install-includeHEADERS install-info install-info-am \ - install-libLTLIBRARIES install-man install-man1 install-man3 \ - install-man5 install-pdf install-pdf-am install-pkgconfigDATA \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - recheck tags tags-am uninstall uninstall-am \ - uninstall-binPROGRAMS uninstall-includeHEADERS \ - uninstall-libLTLIBRARIES uninstall-man uninstall-man1 \ - uninstall-man3 uninstall-man5 uninstall-pkgconfigDATA - -.PRECIOUS: Makefile - - -# a) Clean out some unneeded files and directories -# b) Collect all documentation and format it for distribution. -dist-hook: - rm -rf `find $(distdir) -name CVS -type d` - rm -rf `find $(distdir) -name .svn -type d` - rm -f `find $(distdir) -name '*~'` - rm -f `find $(distdir) -name '*.out'` - rm -f `find $(distdir) -name '*.core'` - -rm -f $(distdir)/*/Makefile $(distdir)/*/*/Makefile - cd $(distdir)/doc && /bin/sh update.sh - -distclean-local: - -rm -rf .ref - -rm -rf autom4te.cache/ - -rm -f *~ - -[ -f libarchive/Makefile ] && cd libarchive && make clean - -[ -f libarchive/test/Makefile ] && cd libarchive/test && make clean - -[ -f tar/Makefile ] && cd tar && make clean - -[ -f tar/test/Makefile ] && cd tar/test && make clean - -[ -f cpio/Makefile ] && cd cpio && make clean - -[ -f cpio/test/Makefile ] && cd cpio/test && make clean - -[ -f cat/Makefile ] && cd cat && make clean - -[ -f cat/test/Makefile ] && cd cat/test && make clean - -[ -f unzip/Makefile ] && cd unzip && make clean - -[ -f unzip/test/Makefile ] && cd unzip/test && make clean - -# The "list.h" file just lists all of the tests defined in all of the sources. -# Building it automatically provides a sanity-check on libarchive_test_SOURCES -# above. -libarchive/test/list.h: Makefile - $(MKDIR_P) libarchive/test - cat $(top_srcdir)/libarchive/test/test_*.c | grep '^DEFINE_TEST' > libarchive/test/list.h - -tar/test/list.h: Makefile - $(MKDIR_P) tar/test - cat $(top_srcdir)/tar/test/test_*.c | grep '^DEFINE_TEST' > tar/test/list.h - -cpio/test/list.h: Makefile - $(MKDIR_P) cpio/test - cat $(top_srcdir)/cpio/test/test_*.c | grep '^DEFINE_TEST' > cpio/test/list.h - -cat/test/list.h: Makefile - $(MKDIR_P) cat/test - cat $(top_srcdir)/cat/test/test_*.c | grep '^DEFINE_TEST' > cat/test/list.h - -unzip/test/list.h: Makefile - $(MKDIR_P) unzip/test - cat $(top_srcdir)/unzip/test/test_*.c | grep '^DEFINE_TEST' > unzip/test/list.h - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/thirdparty/libarchive/NEWS b/thirdparty/libarchive/NEWS deleted file mode 100644 index d3b0eb9ff..000000000 --- a/thirdparty/libarchive/NEWS +++ /dev/null @@ -1,757 +0,0 @@ -Sep 12, 2023: libarchive 3.7.2 released - -Jul 29, 2023: libarchive 3.7.1 released - -Jul 18, 2023: libarchive 3.7.0 released - -Jul 14, 2023: bsdunzip port from FreeBSD - -Dec 07, 2022: libarchive 3.6.2 released - -Apr 08, 2022: libarchive 3.6.1 released - -Feb 09, 2022: libarchive 3.6.0 released - -Feb 08, 2022: libarchive 3.5.3 released - -Aug 22, 2021: libarchive 3.5.2 released - -Dec 26, 2020: libarchive 3.5.1 released - -Dec 01, 2020: libarchive 3.5.0 released - -Oct 14, 2020: Support for system extended attributes - -May 20, 2020: libarchive 3.4.3 released - -Apr 30, 2020: Support for pzstd compressed files - -Apr 16, 2020: Support for RHT.security.selinux tar extended attribute - -Feb 11, 2020: libarchive 3.4.2 released - -Jan 23, 2020: Important fixes for writing XAR archives - -Jan 20, 2020: New tar option: --safe-writes (atomical file extraction) - -Jan 03, 2020: Support mbed TLS (PolarSSL) as optional crypto provider - -Dec 30, 2019: libarchive 3.4.1 released - -Dec 11, 2019: New pax write option "xattrhdr" - -Nov 17, 2019: Unicode filename support for reading lha/lzh archives - -Jun 11, 2019: libarchive 3.4.0 released - -May 18, 2019: Fixes for reading Android APK and JAR archives - -Apr 16, 2019: Support for non-recursive list and extract - -Apr 14, 2019: New tar option: --exclude-vcs - -Mar 27, 2019: Support for file and directory symlinks on Windows - -Mar 12, 2019: Important fixes for storing file attributes and flags - -Jan 20, 2019: Support for xz, lzma, ppmd8 and bzip2 decompression in ZIP files - -Oct 06, 2018: RAR 5.0 reader - -Sep 03, 2018: libarchive 3.3.3 released - -Jul 19, 2018: Avoid super-linear slowdown on malformed mtree files - -Jan 27, 2018: Many fixes for building with Visual Studio - -Oct 19, 2017: NO_OVERWRITE doesn't change existing directory attributes - -Aug 12, 2017: New support for Zstandard read and write filters - -Jul 09, 2017: libarchive 3.3.2 released - -Mar 16, 2017: NFSv4 ACL support for Linux (librichacl) - -Feb 26, 2017: libarchive 3.3.1 released - Security & Feature release - -Feb 19, 2017: libarchive 3.3.0 released - Security & Feature release - -Jan 29, 2017: Limited NFSv4 ACL support for Mac OS (Darwin) - -Jan 10, 2017: POSIX.1e and NFSv4 ACL support for Solaris and derivates - -Dec 27, 2016: NFSv4 ACL read and write support for pax - Deprecated functions: archive_entry_acl_text(), archive_entry_acl_text_w() - -Nov, 2016: libarchive is now being tested by the OSS-Fuzz project - -Oct 26, 2016: Remove liblzmadec support - -Oct 23, 2016: libarchive 3.2.2 released - Security release - -Jun 20, 2016: libarchive 3.2.1 released - This fixes a handful of security and other critical issues with 3.2.0 - -May 01, 2016: libarchive 3.2.0 released - -Apr 09, 2016: libarchive 3.1.901a released - Another test release in preparation for 3.2.0 - -Feb 13, 2016: libarchive 3.1.900a released - This is a test release in preparation for 3.2.0 - -Oct 21, 2015: Preliminary port to OSF - -Apr 11, 2015: libarchive's issue tracker is now hosted at GitHub. - https://github.com/libarchive/libarchive/issues - -Early 2015: Many fixes to crash and overflow bugs thanks to Hanno Boeck - -Oct 13, 2014: Zip encryption and decryption support - -Aug 13, 2014: Add support for lz4 compression. - -Jun 10, 2014: Add warc format support - -May 3, 2014: Add experimental Zip streaming extension - -Apr 6, 2014: Add bsdcat command-line tool - -Jan 12, 2014: Add Zip64 support - -Dec 1, 2013: Rewrite Zip write logic - -Jul 1, 2013: Add ability to detect encrypted entries for many formats - (This does not add the ability to *decrypt* those entries, however) - -Feb 23, 2013: "raw" write support added - -Feb 09, 2013: libarchive 3.1.2 released - -Jan 28, 2013: libarchive's new website moved to http://www.libarchive.org. - -Jan 13, 2013: libarchive 3.1.1 released - -Jan 13, 2013: libarchive 3.1.0 released - -Dec 07, 2012: Implement functions to manually set the format and filters used. - -Nov 11, 2012: Add support for __MACOSX directory in Zip archives, which resource - forks are stored in. - -Oct 20, 2012: Add support for writing v7 tar format. - -Oct 09, 2012: Add support for grzip compression. - -Oct 07, 2012: Introduce b64encode filter. -Oct 07, 2012: Introduce uuencode filter. - -Oct 06, 2012: Add support for lzop. - -Sep 27, 2012: Implement function used to seek within data blocks. - (Currently only supported for uncompressed RAR archives). - -Apr 22, 2012: Add basic archive read and write filter support for lrzip. - -Mar 27, 2012: libarchive 3.0.4 released - -Feb 05, 2012: libarchive development now hosted at GitHub. - http://libarchive.github.com/ -Feb 05, 2012: libarchive's issue tracker remains at Google Code. - http://code.google.com/p/libarchive/issues/list -Feb 05, 2012: libarchive's mailing lists remain at Google Groups. - -Dec 24, 2011: libarchive 3.0.2 released -Dec 23, 2011: Various fixes merged from FreeBSD -Dec 23, 2011: Symlink support in Zip reader and writer -Dec 23, 2011: Robustness fixes to 7Zip reader - -Nov 27, 2011: libarchive 3.0.1b released - -Nov 26, 2011: 7Zip reader -Nov 26, 2011: Small fixes to ISO and Zip to improve robustness with corrupted input -Nov 24, 2011: Improve streaming Zip reader's support for uncompressed entries -Nov 20, 2011: New seeking Zip reader supports SFX Zip archives -Nov 20, 2011: Build fixes on Windows - -Nov 13, 2011: libarchive 3.0.0a released - -Nov 06, 2011: Update shared-library version calculations for libarchive 3.x -Sep 04, 2011: Fix tar -s; follow GNU tar for controlling hardlink/symlink substitutions -Aug 18, 2011: Fix reading ISO images built by NetBSD's mkisofs -Aug 15, 2011: Old archive_read_support_compression_XXX functions are deprecated and - will disappear in libarchive 4.0. -Jun 26, 2011: RAR reader -Jun 16, 2011: Add tar:compat-2x option to emulate broken libarchive 2.x - handling of pax UTF-8 headers -Apr 25, 2011: Refactor read_open() into a collection of single-item setters; - support the old interfaces as wrappers -Apr 12, 2011: Split disk writer into separate POSIX and Windows implementations -Apr 10, 2011: Improvements to character translations on Windows. -Mar 30, 2011: More work to return errors instead of calling abort() -Mar 23, 2011: Add charset option to many writers to control MBCS filenames -Mar 17, 2011: Overhauled support for per-format extension options -Mar 17, 2011: Track character set used for mbcs strings, support - translating to/from user-specified locale -Mar 09, 2011: Recognize mtree files without requiring a signature -Mar 06, 2011: Use iconv to convert to/from Unicode instead of making bad - assumptions about the C90 character set translation functions -Feb 17, 2011: Fixes for AIX, TRU64, and other platforms -Dec 22, 2010: CAB reader -Dec 20, 2010: LHA/LZH reader -Jul 03, 2010: minitar example demonstrates archive_read_disk directory traversal -Jun 29, 2010: Many improvements to ISO reader compatibility -Jun 26, 2010: Use larger buffers when copy files into an archive -Jun 18, 2010: Reimplement Mac OS extensions in libarchive -Jun 09, 2010: archive_read_disk now supports traversals -May 28, 2010: XAR writer -May 16, 2010: Fix ^T handling; don't exit on interrupted reads and writes -May 09, 2010: Improved detection of platform-specific crypto support -May 04, 2010: lzip read and write filters -May 01, 2010: New options: tar --gid --gname --uid --uname -Apr 28, 2010: Use Red-black tree for ISO reader/writer to improve performance -Apr 17, 2010: Minimal writer for legacy GNU tar format -Mar 12, 2010: Don't dereference symlinks on Linux when reading ACLs. -Mar 06, 2010: Fix build when an older libarchive is already installed -Feb 28, 2010: Relax handling of state failures; misuse by clients now generally - results in a sticky ARCHIVE_FATAL rather than a visit to abort() -Feb 25, 2010: ISO writer -Feb 21, 2010: Split many man pages into smaller chunks. -Feb 21, 2010: Performance: Cheat on block sizes when reading archives from disk. -Feb 21, 2010: Use int64_t instead of off_t, dev_t, ino_t, uid_t, and gid_t -Feb 20, 2010: Document new ACL functions. -Feb 19, 2010: Support multiple write filters -Feb 07, 2010: Remove some legacy libarchive 1.x APIs -Feb 04, 2010: Read afio headers -Feb 02, 2010: Archive sparse files compatibly with GNU tar -Feb 01, 2010: Integrate Apple extensions for Mac OS extended attributes into bsdtar -Jan 31, 2010: Support cpio -V - -Feb 04, 2010: libarchive 2.8.0 released -Jan 17, 2010: Fix error handling for 'echo nonexistent | cpio -o' -Jan 17, 2010: Don't use futimes() on Cygwin - -Jan 02, 2010: libarchive 2.7.902a released (test release for 2.8) -Jan 02, 2010: Fix tar/test/test_windows on MinGW -Jan 02, 2010: Fix memory leaks in libarchive tests -Jan 01, 2010: Fix memory leak when filter startup fails - -Dec 27, 2009: libarchive 2.7.901a released (test release for 2.8) - -Aug 04, 2009: libarchive 2.7.1 released -Jul 20, 2009: Suppress bogus warning about unxz -Jul 19, 2009: Support Cygwin 1.7 -Jun 11, 2009: Support lzma/xz files compressed with larger buffer sizes. -May 24, 2009: Handle gzip files signed with OpenBSD "gzsig" program. -May 07, 2009: Avoid false failures when reading from pipe. - -Apr 16, 2009: libarchive 2.7.0 released - -Apr 10, 2009: libarchive 2.6.992a released -Apr 09, 2009: Fix SIGPIPE issue building with MSVC. -Apr 09, 2009: Fix several minor memory leaks in libarchive and libarchive_test - -Apr 08, 2009: libarchive 2.6.991a released -Apr 07, 2009: Additional tests added to bsdcpio_test - -Apr 01, 2009: libarchive 2.6.990a released -Apr 01, 2009: Use command-line gunzip, bunzip2, unxz, unlzma for - decompression if the library is built without suitable - libraries. The setup functions return ARCHIVE_WARN - in this case so clients can adapt if necessary. -Apr 01, 2009: Use getpw*_r and getgr*_r functions for thread-safety. -Mar 24, 2009: Add archive_read_next_header2(), which is up to 25% - more efficient for some clients; from Brian Harring. -Mar 22, 2009: PDF versions of manpages are now included in the distribution. -Mar, 2009: Major work to improve Cygwin build by Charles Wilson. -Feb/Mar, 2009: Major work on cmake build support, mostly by Michihiro NAKAJIMA. -Feb/Mar, 2009: Major work on Visual Studio support by Michihiro NAKAJIMA. - All tests now pass. -Feb 25, 2009: Fix Debian Bug #516577 -Feb 21, 2009: Yacc is no longer needed to build; date parser rewritten in C. -Jan/Feb, 2009: Mtree work by Michihiro. -Feb, 2009: Joliet support by Andreas Henriksson. -Jan/Feb, 2009: New options framework by Michihiro. -Feb, 2009: High-res timestamps on Tru64, AIX, and GNU Hurd, by Björn Jacke. -Jan 18, 2009: Extended attributes work on FreeBSD and Linux now with pax format. -Jan 07, 2009: New archive_read_disk_entry_from_file() knows about ACLs, - extended attributes, etc so that bsdtar and bsdcpio don't require - such system-specific knowledge. -Jan 03, 2009: Read filter system extensively refactored. In particular, - read filter pipelines are now built out automatically and individual - filters should be much easier to implement. Documentation on the - Googlecode Wiki explains how to implement new filters. -Dec 28, 2008: Many Windows/Visual Studio fixes from Michihiro NAKAJIMA. - -Dec 28, 2008: Main libarchive development moved from FreeBSD Perforce - server to Google Code. This should make it easier for more - people to participate in libarchive development. - -Dec 28, 2008: libarchive 2.6.0 released -Dec 25, 2008: libarchive 2.5.905a released -Dec 10, 2008: libarchive 2.5.904a released -Dec 04, 2008: libarchive 2.5.903a released -Nov 09, 2008: libarchive 2.5.902a released -Nov 08, 2008: libarchive 2.5.901a released -Nov 08, 2008: Start of pre-release testing for libarchive 2.6 - -Nov 07, 2008: Read filter refactor: The decompression routines just - consume and produce arbitrarily-sized blocks. The reblocking - from read_support_compression_none() has been pulled into the - read core. Also, the decompression bid now makes multiple - passes and stacks read filters. -Oct 21, 2008: bsdcpio: New command-line parser. -Oct 19, 2008: Internal read_ahead change: short reads are now an error -Oct 06, 2008: bsdtar: option parser no longer uses getopt_long(), - gives consistent option parsing on all platforms. -Sep 19, 2008: Jaakko Heinonen: shar utility built on libarchive -Sep 17, 2008: Pedro Giffuni: birthtime support -Sep 17, 2008: Miklos Vajna: lzma reader and test. Note: I still have - some concerns about the auto-detection (LZMA file format - doesn't support auto-detection well), so this is not yet - enabled under archive_read_support_compression_all(). For - now, you must call archive_read_support_compression_lzma() if - you want LZMA read support. -Sep 11, 2008: Ivailo Petrov: Many fixes to Windows build, new solution files -Jul 26, 2008: archive_entry now tracks which values have not been set. - This helps zip extraction (file size is often "unknown") and - time restores (tar usually doesn't know atime). -Jul 26, 2008: Joerg Sonnenberger: Performance improvements to shar writer -Jul 25, 2008: Joerg Sonnenberger: mtree write support - -Jul 02, 2008: libarchive 2.5.5 released - -Jul 02, 2008: libarchive 2.5.5b released -Jul 01, 2008: bsdcpio is being used by enough people, we can call it 1.0.0 now -Jun 20, 2008: bsdcpio: If a -l link fails with EXDEV, copy the file instead -Jun 19, 2008: bsdcpio: additional long options for better GNU cpio compat -Jun 15, 2008: Many small portability and bugfixes since 2.5.4b. - -May 25, 2008: libarchive 2.5.4b released -May 21, 2008: Joerg Sonnenberger: fix bsdtar hardlink handling for newc format - -May 21, 2008: More progress on Windows building. Thanks to "Scott" - for the Windows makefiles, thanks to Kees Zeelenberg for - code contributions. - -May 21, 2008: Fix a number of non-exploitable integer and buffer overflows, - thanks to David Remahl at Apple for pointing these out. - -May 21, 2008: Colin Percival: SIGINFO or SIGUSR1 to bsdtar prints progress info - -May 16, 2008: bsdtar's test harness no longer depends on file ordering. - This was causing spurious test failures on a lot of systems. - Thanks to Bernhard R. Link for the diagnosis. - -May 14, 2008: Joerg Sonnenberger: -s substitution support for bsdtar - -May 13, 2008: Joerg Sonnenberger: Many mtree improvements - -May 11, 2008: Joerg Sonnenberger: fix hardlink extraction when - hardlinks have different permissions from original file - -April 30, 2008: Primary libarchive work has been moved into the FreeBSD - project's Perforce repository: http://perforce.freebsd.org/ - The libarchive project can be browsed at - //depot/user/kientzle/libarchive-portable - Direct link: http://preview.tinyurl.com/46mdgr - -May 04, 2008: libarchive 2.5.3b released - * libarchive: Several fixes to link resolver to address bsdcpio crashes - * bsdcpio: -p hardlink handling fixes - * tar/pax: Ensure ustar dirnames end in '/'; be more careful about - measuring filenames when deciding what pathname fields to use - * libarchive: Mark which entry strings are set; be accurate about - distinguishing empty strings ("") from unset ones (NULL) - * tar: Don't crash reading entries with empty filenames - * libarchive_test, bsdtar_test, bsdcpio_test: Better defaults: - run all tests, delete temp dirs, summarize repeated failures - * -no-undefined to libtool for Cygwin - * libarchive_test: Skip large file tests on systems with 32-bit off_t - * iso9660: Don't bother trying to find the body of an empty file; - this works around strange behavior from some ISO9660 writers - * tar: allow -r -T to be used together - * tar: allow --format with -r or -u - * libarchive: Don't build archive.h - -May 04, 2008: Simplified building: archive.h is no longer constructed - This may require additional #if conditionals on some platforms. - -Mar 30, 2008: libarchive 2.5.1b released - -Mar 15, 2008: libarchive 2.5.0b released -Mar 15, 2008: bsdcpio now seems to correctly write hardlinks into newc, - ustar, and old cpio archives. Just a little more testing before - bsdcpio 1.0 becomes a reality. -Mar 15, 2008: I think the new linkify() interface is finally handling - all known hardlink strategies. -Mar 15, 2008: Mtree read fixes from Joerg Sonnenberger. -Mar 15, 2008: Many new bsdtar and bsdcpio options from Joerg Sonnenberger. -Mar 15, 2008: test harnesses no longer require uudecode; they - now have built-in decoding logic that decodes the reference - files as they are needed. - -Mar 14, 2008: libarchive 2.4.14 released; identical to 2.4.13 except for - a point fix for gname/uname mixup in pax format that was introduced - with the UTF-8 fixes. - -Feb 26, 2008: libarchive 2.4.13 released -Feb 25, 2008: Handle path, linkname, gname, or uname that can't be converted - to/from UTF-8. Implement "hdrcharset" attribute from SUS-2008. -Feb 25, 2008: Fix name clash on NetBSD. -Feb 18, 2008: Fix writing empty 'ar' archives, per Kai Wang -Feb 18, 2008: [bsdtar] Permit appending on block devices. -Feb 09, 2008: New "linkify" resolver to help with newc hardlink writing; - bsdcpio still needs to be converted to use this. -Feb 02, 2008: Windows compatibility fixes from Ivailo Petrov, Kees Zeelenberg -Jan 30, 2008: Ignore hardlink size for non-POSIX tar archives. - -Jan 22, 2008: libarchive 2.4.12 released -Jan 22, 2008: Fix bad padding when writing symlinks to newc cpio archives. -Jan 22, 2008: Verify bsdcpio_test by getting it to work against GNU cpio 2.9. - bsdcpio_test complains about missing options (-y and -z), format - of informational messages (--version, --help), and a minor formatting - issue in odc format output. After this update, bsdcpio_test uncovered - several more cosmetic issues in bsdcpio, all now fixed. -Jan 22, 2008: Experimental support for self-extracting Zip archives. -Jan 22, 2008: Extend hardlink restore strategy to work correctly with - hardlinks extracted from newc cpio files. (Which store the body - only with the last occurrence of a link.) - -Dec 30, 2007: libarchive 2.4.11 released -Dec 30, 2007: Fixed a compile error in bsdcpio on some systems. - -Dec 29, 2007: libarchive 2.4.10 released -Dec 29, 2007: bsdcpio 0.9.0 is ready for wider use. -Dec 29, 2007: Completed initial test harness for bsdcpio. - -Dec 22, 2007: libarchive 2.4.9 released -Dec 22, 2007: Implement the remaining options for bsdcpio: -a, -q, -L, -f, - pattern selection for -i and -it. - -Dec 13, 2007: libarchive 2.4.8 released -Dec 13, 2007: gzip and bzip2 compression now handle zero-byte writes correctly, - Thanks to Damien Golding for bringing this to my attention. - -Dec 12, 2007: libarchive 2.4.7 released - -Dec 10, 2007: libarchive 2.4.6 released -Dec 09, 2007: tar/test/test_copy.c verifies "tar -c | tar -x" copy pipeline -Dec 07, 2007: Fix a couple of minor memory leaks. - -Dec 04, 2007: libarchive 2.4.5 released -Dec 04, 2007: Fix cpio/test/test_write_odc by setting the umask first. - -Dec 03, 2007: libarchive 2.4.4 released -Dec 03, 2007: New configure options --disable-xattr and --disable-acl, - thanks to Samuli Suominen. - -Dec 03, 2007: libarchive 2.4.3 released -Dec 03, 2007: Thanks to Lapo Luchini for sending me a ZIP file that - libarchive couldn't handle. Fixed a bug in handling of - "length at end" flags in ZIP files. -Dec 03, 2007: Fixed bsdcpio -help, bsdtar -help tests. -Dec 02, 2007: First cut at real bsdtar test harness. - -Dec 02, 2007: libarchive 2.4.2 released - -Dec 02, 2007: libarchive 2.4.1 released -Dec 02, 2007: Minor fixes, rough cut of mdoc-to-man conversion for - man pages. - -Oct 30, 2007: libarchive 2.4.0 released -Oct 30, 2007: Minor compile fix thanks to Joerg Schilling. -Oct 30, 2007: Only run the format auction once at the beginning of the - archive. This is simpler and supports better error recovery. -Oct 29, 2007: Test support for very large entries in tar archives: - libarchive_test now exercises entries from 2GB up to 1TB. - -Oct 27, 2007: libarchive 2.3.5 released -Oct 27, 2007: Correct some unnecessary internal data copying in the - "compression none" reader and writer; this reduces user time - by up to 2/3 in some tests. (Thanks to Jan Psota for - publishing his performance test results to GNU tar's bug-tar - mailing list; those results pointed me towards this problem.) -Oct 27, 2007: Fix for skipping archive entries that are exactly - a multiple of 4G on 32-bit platforms. -Oct 25, 2007: Fix for reading very large (>8G) tar archives; this was - broken when I put in support for new GNU tar sparse formats. -Oct 20, 2007: Initial work on new pattern-matching code for cpio; I - hope this eventually replaces the code currently in bsdtar. - -Oct 08, 2007: libarchive 2.3.4 released -Oct 05, 2007: Continuing work on bsdcpio test suite. -Oct 05, 2007: New cpio.5 manpage, updates to "History" of bsdcpio.1 and - bsdtar.1 manpages. -Oct 05, 2007: Fix zip reader to immediately return EOF if you try - to read body of non-regular file. In particular, this fixes - bsdtar extraction of zip archives. - -Sep 30, 2007: libarchive 2.3.3 released -Sep 26, 2007: Rework Makefile.am so that the enable/disable options - actually do the right things. -Sep 26, 2007: cpio-odc and cpio-newc archives no longer write bodies - for non-regular files. -Sep 26, 2007: Test harness for bsdcpio is in place, needs more tests written. - This is much nicer than the ragtag collection of test scripts - that bsdtar has. - -Sep 20, 2007: libarchive 2.3.2 released -Sep 20, 2007: libarchive 2.3.1 broke bsdtar because the archive_write_data() - fix was implemented incorrectly. - -Sep 16, 2007: libarchive 2.3.1 released -Sep 16, 2007: Many fixes to bsdcpio 0.3: handle hardlinks with -p, recognize - block size on writing, fix a couple of segfaults. -Sep 16, 2007: Fixed return value from archive_write_data() when used - with archive_write_disk() to match the documentation and other - instances of this same function. -Sep 15, 2007: Add archive_entry_link_resolver, archive_entry_strmode - -Sep 11, 2007: libarchive 2.2.8 released -Sep 09, 2007: bsdcpio 0.2 supports most (not yet all) of the old POSIX spec. - -Sep 01, 2007: libarchive 2.2.7 released -Aug 31, 2007: Support for reading mtree files, including an mtree.5 manpage - (A little experimental still.) -Aug 18, 2007: Read gtar 1.17 --posix --sparse entries. -Aug 13, 2007: Refined suid/sgid restore handling; it is no longer - an error if suid/sgid bits are dropped when you request - perm restore but don't request owner restore. -Aug 06, 2007: Use --enable-bsdcpio if you want to try bsdcpio - -Aug 05, 2007: libarchive 2.2.6 released -Aug 05, 2007: New configure option --disable-bsdtar, thanks to Joerg - Sonnenberger. -Aug 05, 2007: Several bug fixes from FreeBSD CVS repo. - -Jul 13, 2007: libarchive 2.2.5 released - -Jul 12, 2007: libarchive 2.2.4 released -Jul 12, 2007: Thanks to Colin Percival's help in diagnosing and - fixing several critical security bugs. Details available at - http://security.freebsd.org/advisories/FreeBSD-SA-07:05.libarchive.asc - -May 26, 2007: libarchive 2.2.3 released -May 26, 2007: Fix memory leaks in ZIP reader and shar writer, add some - missing system headers to archive_entry.h, dead code cleanup - from Colin Percival, more tests for gzip/bzip2, fix an - EOF anomaly in bzip2 decompression. - -May 12, 2007: libarchive 2.2.2 released -May 12, 2007: Fix archive_write_disk permission restore by cloning - entry passed into write_header so that permission info is - still available at finish_entry time. (archive_read_extract() - worked okay because it held onto the passed-in entry, but - direct consumers of archive_write_disk would break). This - required fixing archive_entry_clone(), which now works and has - a reasonably complete test case. -May 10, 2007: Skeletal cpio implementation. - -May 06, 2007: libarchive 2.2.1 released -May 06, 2007: Flesh out a lot more of test_entry.c so as to catch - problems such as the device node breakage before releasing . -May 05, 2007: Fix a bad bug introduced in 2.1.9 that broke device - node entries in tar archives. -May 03, 2007: Move 'struct stat' out of archive_entry core as well. - This removes some portability headaches and fixes a bunch - of corner cases that arise when manipulating archives on - dissimilar systems. - -Apr 30, 2007: libarchive 2.1.10 released -Apr 31, 2007: Minor code cleanup. - -Apr 24, 2007: libarchive 2.1.9 released -Apr 24, 2007: Fix some recently-introduced problems with libraries - (Just let automake handle it and it all works much better.) - Finish isolating major()/minor()/makedev() in archive_entry.c. - -Apr 23, 2007: libarchive 2.1.8 released -Apr 23, 2007: Minor fixes found from building on MacOS X - -Apr 22, 2007: libarchive 2.1.7 released -Apr 22, 2007: Eliminated all uses of 'struct stat' from the - format readers/writers. This should improve portability; - 'struct stat' is now only used in archive_entry and in - code that actually touches the disk. - -Apr 17, 2007: libarchive 2.1.6 released - Libarchive now compiles and passes all tests on Interix. - -Apr 16, 2007: libarchive 2.1.5 released - -Apr 15, 2007: libarchive 2.1b2 released -Apr 15, 2007: New libarchive_internals.3 documentation of internal APIs. - Not complete, but should prove helpful. -Apr 15, 2007: Experimental "read_compress_program" and "write_compress_program" - for using libarchive with external compression. Not yet - well tested, and likely has portability issues. Feedback - appreciated. - -Apr 14, 2007: libarchive 2.0.31 released -Apr 14, 2007: More fixes for Interix, more 'ar' work - -Apr 14, 2007: libarchive 2.0.30 released -Apr 13, 2007: libarchive now enforces trailing '/' on dirs - written to tar archives - -Apr 11, 2007: libarchive 2.0.29 released -Apr 11, 2007: Make it easier to statically configure for different platforms. -Apr 11, 2007: Updated config.guess, config.sub, libtool - -Apr 06, 2007: libarchive 2.0.28 released -Apr 06, 2007: 'ar' format read/write support thanks to Kai Wang. - -Apr 01, 2007: libarchive 2.0.27 released -Mar 31, 2007: Several minor fixes from Colin Percival and Joerg Sonnenberger. - -Mar 12, 2007: libarchive 2.0.25 released -Mar 12, 2007: Fix broken --unlink flag. - -Mar 11, 2007: libarchive 2.0.24 released -Mar 10, 2007: Correct an ACL blunder that causes any ACL with an entry - that refers to a non-existent user or group to not be restored correctly. - The fix both makes the parser more tolerant (so that archives created - with the buggy ACLs can be read now) and corrects the ACL formatter. -Mar 10, 2007: More work on test portability to Linux. - -Mar 10, 2007: libarchive 2.0.22 released -Mar 10, 2007: Header cleanups; added linux/fs.h, removed - some unnecessary headers, added #include guards in bsdtar. - If you see any obvious compile failures from this, let me know. -Mar 10, 2007: Work on bsdtar test scripts: not yet robust enough - to enable as part of "make check", but getting better. -Mar 10, 2007: libarchive now returns ARCHIVE_FAILED when - a header write fails in a way that only affects this item. - Less bad than ARCHIVE_FATAL, but worse than ARCHIVE_WARN. - -Mar 07, 2007: libarchive 2.0.21 released -Mar 07, 2007: Add some ACL tests (only for the system-independent - portion of the ACL support for now). -Mar 07, 2007: tar's ability to read ACLs off disk got - turned off for FreeBSD; re-enable it. (ACL restores and - libarchive support for storing/reading ACLs from pax - archives was unaffected.) - -Mar 02, 2007: libarchive 2.0.20 released -Mar 2, 2007: It's not perfect, but it's pretty good. - Libarchive 2.0 is officially out of beta. - -Feb 28, 2007: libarchive 2.0b17 released -Feb 27, 2007: Make the GID restore checks more robust by checking - whether the current user has too few or too many privileges. - -Feb 26, 2007: libarchive 2.0b15 released -Feb 26, 2007: Don't lose symlinks when extracting from ISOs. - Thanks to Diego "Flameeyes" Pettenò for telling me about the - broken testcase on Gentoo that (finally!) led me to the cause - of this long-standing bug. - -Feb 26, 2007: libarchive 2.0b14 released -Feb 26, 2007: Fix a broken test on platforms that lack lchmod(). - -Feb 25, 2007: libarchive 2.0b13 released -Feb 25, 2007: Empty archives were being written as empty files, - without a proper end-of-archive marker. Fixed. - -Feb 23, 2007: libarchive 2.0b12 released -Feb 22, 2007: Basic security checks added: _EXTRACT_SECURE_NODOTDOT - and _EXTRACT_SECURE_SYMLINK. These checks used to be in bsdtar, - but they belong down in libarchive where they can be used by - other tools and where they can be better optimized. - -Feb 11, 2007: libarchive 2.0b11 released -Feb 10, 2007: Fixed a bunch of errors in libarchive's handling - of EXTRACT_PERM and EXTRACT_OWNER, especially relating - to SUID and SGID bits. - -Jan 31, 2007: libarchive 2.0b9 released -Jan 31, 2007: Added read support for "empty" archives as a - distinct archive format. Bsdtar uses this to handle, e.g., - "touch foo.tar; tar -rf foo.tar" - -Jan 22, 2007: libarchive 2.0b6 released -Jan 22, 2007: archive_write_disk API is now in place. It provides - a finer-grained interface than archive_read_extract. In particular, - you can use it to create objects on disk without having an archive - around (just feed it archive_entry objects describing what you - want to create), you can override the uname/gname-to-uid/gid lookups - (minitar uses this to avoid getpwXXX() and getgrXXX() bloat). - -Jan 09, 2007: libarchive 2.0a3 released -Jan 9, 2007: archive_extract is now much better; it handles the - most common cases with a minimal number of system calls. - Some features still need a lot of testing, especially corner - cases involving objects that already exist on disk. I expect - the next round of API overhaul will simplify building test cases. -Jan 9, 2007: a number of fixes thanks to Colin Percival, especially - corrections to the skip() framework and handling of large files. -Jan 9, 2007: Fixes for large ISOs. The code should correctly handle - very large ISOs with entries up to 4G. Thanks to Robert Sciuk - for pointing out these issues. - -Sep 05, 2006: libarchive 1.3.1 released -Sep 5, 2006: Bump version to 1.3 for new I/O wrappers. -Sep 4, 2006: New memory and FILE read/write wrappers. -Sep 4, 2006: libarchive test harness is now minimally functional; - it's located a few minor bugs in error-handling logic - -Aug 17, 2006: libarchive 1.2.54 released -Aug 17, 2006: Outline ABI changes for libarchive 2.0; these - are protected behind #ifdef's until I think I've found everything - that needs to change. -Aug 17, 2006: Fix error-handling in archive_read/write_close() - They weren't returning any errors before. -Aug 17, 2006: Fix recursive-add logic to not trigger if it's not set - Fixes a bug adding files when writing archive to pipe or when - using archive_write_open() directly. -Jul 2006: New "skip" handling improves performance extracting - single files from large uncompressed archives. - -Mar 21, 2006: 1.2.52 released -Mar 21, 2006: Fix -p on platforms that don't have platform-specific - extended attribute code. -Mar 20, 2006: Add NEWS file; fill in some older history from other - files. I'll try to keep this file up-to-date from now on. - -OLDER NEWS SUMMARIES - -Mar 19, 2006: libarchive 1.2.51 released -Mar 18, 2006: Many fixes to extended attribute support, including a redesign - of the storage format to simplify debugging. -Mar 12, 2006: Remove 'tp' support; it was a fun idea, but not worth - spending much time on. -Mar 11, 2006: Incorporated Jaakko Heinonen's still-experimental support - for extended attributes (Currently Linux-only.). -Mar 11, 2006: Reorganized distribution package: There is now one tar.gz - file that builds both libarchive and bsdtar. -Feb 13, 2006: Minor bug fixes: correctly read cpio device entries, write - Pax attribute entry names. -Nov 7, 2005: Experimental 'tp' format support in libarchive. Feedback - appreciated; this is not enabled by archive_read_support_format_all() - yet as I'm not quite content with the format detection heuristics. -Nov 7, 2005: Some more portability improvements thanks to Darin Broady, - minor bugfixes. -Oct 12, 2005: Use GNU libtool to build shared libraries on many systems. -Aug 9, 2005: Correctly detect that MacOS X does not have POSIX ACLs. -Apr 17, 2005: Kees Zeelenberg has ported libarchive and bsdtar to Windows: - http://gnuwin32.sourceforge.net/ -Apr 11, 2005: Extended Zip/Zip64 support thanks to Dan Nelson. -L/-h - fix from Jaakko Heinonen. -Mar 12, 2005: archive_read_extract can now handle very long - pathnames (I've tested with pathnames up to 1MB). -Mar 12, 2005: Marcus Geiger has written an article about libarchive - http://xsnil.antbear.org/2005/02/05/archive-mit-libarchive-verarbeiten/ - including examples of using it from Objective-C. His MoinX - http://moinx.antbear.org/ desktop Wiki uses - libarchive for archiving and restoring Wiki pages. -Jan 22, 2005: Preliminary ZIP extraction support, - new directory-walking code for bsdtar. -Jan 16, 2005: ISO9660 extraction code added; manpage corrections. -May 22, 2004: Many gtar-compatible long options have been added; almost - all FreeBSD ports extract correctly with bsdtar. -May 18, 2004: bsdtar can read Solaris, HP-UX, Unixware, star, gtar, - and pdtar archives. diff --git a/thirdparty/libarchive/README.md b/thirdparty/libarchive/README.md deleted file mode 100644 index 727ed4985..000000000 --- a/thirdparty/libarchive/README.md +++ /dev/null @@ -1,244 +0,0 @@ -# Welcome to libarchive! - -The libarchive project develops a portable, efficient C library that -can read and write streaming archives in a variety of formats. It -also includes implementations of the common `tar`, `cpio`, and `zcat` -command-line tools that use the libarchive library. - -## Questions? Issues? - -* https://www.libarchive.org is the home for ongoing - libarchive development, including documentation, - and links to the libarchive mailing lists. -* To report an issue, use the issue tracker at - https://github.com/libarchive/libarchive/issues -* To submit an enhancement to libarchive, please - submit a pull request via GitHub: https://github.com/libarchive/libarchive/pulls - -## Contents of the Distribution - -This distribution bundle includes the following major components: - -* **libarchive**: a library for reading and writing streaming archives -* **tar**: the 'bsdtar' program is a full-featured 'tar' implementation built on libarchive -* **cpio**: the 'bsdcpio' program is a different interface to essentially the same functionality -* **cat**: the 'bsdcat' program is a simple replacement tool for zcat, bzcat, xzcat, and such -* **unzip**: the 'bsdunzip' program is a simple replacement tool for Info-ZIP's unzip -* **examples**: Some small example programs that you may find useful. -* **examples/minitar**: a compact sample demonstrating use of libarchive. -* **contrib**: Various items sent to me by third parties; please contact the authors with any questions. - -The top-level directory contains the following information files: - -* **NEWS** - highlights of recent changes -* **COPYING** - what you can do with this -* **INSTALL** - installation instructions -* **README** - this file -* **CMakeLists.txt** - input for "cmake" build tool, see INSTALL -* **configure** - configuration script, see INSTALL for details. If your copy of the source lacks a `configure` script, you can try to construct it by running the script in `build/autogen.sh` (or use `cmake`). - -The following files in the top-level directory are used by the 'configure' script: - -* `Makefile.am`, `aclocal.m4`, `configure.ac` - used to build this distribution, only needed by maintainers -* `Makefile.in`, `config.h.in` - templates used by configure script - -## Documentation - -In addition to the informational articles and documentation -in the online [libarchive Wiki](https://github.com/libarchive/libarchive/wiki), -the distribution also includes a number of manual pages: - - * bsdtar.1 explains the use of the bsdtar program - * bsdcpio.1 explains the use of the bsdcpio program - * bsdcat.1 explains the use of the bsdcat program - * libarchive.3 gives an overview of the library as a whole - * archive_read.3, archive_write.3, archive_write_disk.3, and - archive_read_disk.3 provide detailed calling sequences for the read - and write APIs - * archive_entry.3 details the "struct archive_entry" utility class - * archive_internals.3 provides some insight into libarchive's - internal structure and operation. - * libarchive-formats.5 documents the file formats supported by the library - * cpio.5, mtree.5, and tar.5 provide detailed information about these - popular archive formats, including hard-to-find details about - modern cpio and tar variants. - -The manual pages above are provided in the 'doc' directory in -a number of different formats. - -You should also read the copious comments in `archive.h` and the -source code for the sample programs for more details. Please let us -know about any errors or omissions you find. - -## Supported Formats - -Currently, the library automatically detects and reads the following formats: - - * Old V7 tar archives - * POSIX ustar - * GNU tar format (including GNU long filenames, long link names, and sparse files) - * Solaris 9 extended tar format (including ACLs) - * POSIX pax interchange format - * POSIX octet-oriented cpio - * SVR4 ASCII cpio - * Binary cpio (big-endian or little-endian) - * PWB binary cpio - * ISO9660 CD-ROM images (with optional Rockridge or Joliet extensions) - * ZIP archives (with uncompressed or "deflate" compressed entries, including support for encrypted Zip archives) - * ZIPX archives (with support for bzip2, ppmd8, lzma and xz compressed entries) - * GNU and BSD 'ar' archives - * 'mtree' format - * 7-Zip archives (including archives that use zstandard compression) - * Microsoft CAB format - * LHA and LZH archives - * RAR and RAR 5.0 archives (with some limitations due to RAR's proprietary status) - * XAR archives - -The library also detects and handles any of the following before evaluating the archive: - - * uuencoded files - * files with RPM wrapper - * gzip compression - * bzip2 compression - * compress/LZW compression - * lzma, lzip, and xz compression - * lz4 compression - * lzop compression - * zstandard compression - -The library can create archives in any of the following formats: - - * POSIX ustar - * POSIX pax interchange format - * "restricted" pax format, which will create ustar archives except for - entries that require pax extensions (for long filenames, ACLs, etc). - * Old GNU tar format - * Old V7 tar format - * POSIX octet-oriented cpio - * SVR4 "newc" cpio - * Binary cpio (little-endian) - * PWB binary cpio - * shar archives - * ZIP archives (with uncompressed or "deflate" compressed entries) - * GNU and BSD 'ar' archives - * 'mtree' format - * ISO9660 format - * 7-Zip archives - * XAR archives - -When creating archives, the result can be filtered with any of the following: - - * uuencode - * gzip compression - * bzip2 compression - * compress/LZW compression - * lzma, lzip, and xz compression - * lz4 compression - * lzop compression - * zstandard compression - -## Notes about the Library Design - -The following notes address many of the most common -questions we are asked about libarchive: - -* This is a heavily stream-oriented system. That means that - it is optimized to read or write the archive in a single - pass from beginning to end. For example, this allows - libarchive to process archives too large to store on disk - by processing them on-the-fly as they are read from or - written to a network or tape drive. This also makes - libarchive useful for tools that need to produce - archives on-the-fly (such as webservers that provide - archived contents of a users account). - -* In-place modification and random access to the contents - of an archive are not directly supported. For some formats, - this is not an issue: For example, tar.gz archives are not - designed for random access. In some other cases, libarchive - can re-open an archive and scan it from the beginning quickly - enough to provide the needed abilities even without true - random access. Of course, some applications do require true - random access; those applications should consider alternatives - to libarchive. - -* The library is designed to be extended with new compression and - archive formats. The only requirement is that the format be - readable or writable as a stream and that each archive entry be - independent. There are articles on the libarchive Wiki explaining - how to extend libarchive. - -* On read, compression and format are always detected automatically. - -* The same API is used for all formats; it should be very - easy for software using libarchive to transparently handle - any of libarchive's archiving formats. - -* Libarchive's automatic support for decompression can be used - without archiving by explicitly selecting the "raw" and "empty" - formats. - -* I've attempted to minimize static link pollution. If you don't - explicitly invoke a particular feature (such as support for a - particular compression or format), it won't get pulled in to - statically-linked programs. In particular, if you don't explicitly - enable a particular compression or decompression support, you won't - need to link against the corresponding compression or decompression - libraries. This also reduces the size of statically-linked - binaries in environments where that matters. - -* The library is generally _thread safe_ depending on the platform: - it does not define any global variables of its own. However, some - platforms do not provide fully thread-safe versions of key C library - functions. On those platforms, libarchive will use the non-thread-safe - functions. Patches to improve this are of great interest to us. - -* The function `archive_write_disk_header()` is _not_ thread safe on - POSIX machines and could lead to security issue resulting in world - writeable directories. Thus it must be mutexed by the calling code. - This is due to calling `umask(oldumask = umask(0))`, which sets the - umask for the whole process to 0 for a short time frame. - In case other thread calls the same function in parallel, it might - get interrupted by it and cause the executable to use umask=0 for the - remaining execution. - This will then lead to implicitely created directories to have 777 - permissions without sticky bit. - -* In particular, libarchive's modules to read or write a directory - tree do use `chdir()` to optimize the directory traversals. This - can cause problems for programs that expect to do disk access from - multiple threads. Of course, those modules are completely - optional and you can use the rest of libarchive without them. - -* The library is _not_ thread aware, however. It does no locking - or thread management of any kind. If you create a libarchive - object and need to access it from multiple threads, you will - need to provide your own locking. - -* On read, the library accepts whatever blocks you hand it. - Your read callback is free to pass the library a byte at a time - or mmap the entire archive and give it to the library at once. - On write, the library always produces correctly-blocked output. - -* The object-style approach allows you to have multiple archive streams - open at once. bsdtar uses this in its "@archive" extension. - -* The archive itself is read/written using callback functions. - You can read an archive directly from an in-memory buffer or - write it to a socket, if you wish. There are some utility - functions to provide easy-to-use "open file," etc, capabilities. - -* The read/write APIs are designed to allow individual entries - to be read or written to any data source: You can create - a block of data in memory and add it to a tar archive without - first writing a temporary file. You can also read an entry from - an archive and write the data directly to a socket. If you want - to read/write entries to disk, there are convenience functions to - make this especially easy. - -* Note: The "pax interchange format" is a POSIX standard extended tar - format that should be used when the older _ustar_ format is not - appropriate. It has many advantages over other tar formats - (including the legacy GNU tar format) and is widely supported by - current tar implementations. - diff --git a/thirdparty/libarchive/aclocal.m4 b/thirdparty/libarchive/aclocal.m4 deleted file mode 100644 index 14646f746..000000000 --- a/thirdparty/libarchive/aclocal.m4 +++ /dev/null @@ -1,10527 +0,0 @@ -# generated automatically by aclocal 1.16.5 -*- Autoconf -*- - -# Copyright (C) 1996-2021 Free Software Foundation, Inc. - -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) -m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.71],, -[m4_warning([this file was generated for autoconf 2.71. -You have another version of autoconf. It may work, but is not guaranteed to. -If you have problems, you may need to regenerate the build system entirely. -To do so, use the procedure documented by the package, typically 'autoreconf'.])]) - -# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- -# -# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -m4_define([_LT_COPYING], [dnl -# Copyright (C) 2014 Free Software Foundation, Inc. -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -# GNU Libtool is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of of the License, or -# (at your option) any later version. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program or library that is built -# using GNU Libtool, you may include this file under the same -# distribution terms that you use for the rest of that program. -# -# GNU Libtool is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -]) - -# serial 58 LT_INIT - - -# LT_PREREQ(VERSION) -# ------------------ -# Complain and exit if this libtool version is less that VERSION. -m4_defun([LT_PREREQ], -[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, - [m4_default([$3], - [m4_fatal([Libtool version $1 or higher is required], - 63)])], - [$2])]) - - -# _LT_CHECK_BUILDDIR -# ------------------ -# Complain if the absolute build directory name contains unusual characters -m4_defun([_LT_CHECK_BUILDDIR], -[case `pwd` in - *\ * | *\ *) - AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; -esac -]) - - -# LT_INIT([OPTIONS]) -# ------------------ -AC_DEFUN([LT_INIT], -[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK -AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl -AC_BEFORE([$0], [LT_LANG])dnl -AC_BEFORE([$0], [LT_OUTPUT])dnl -AC_BEFORE([$0], [LTDL_INIT])dnl -m4_require([_LT_CHECK_BUILDDIR])dnl - -dnl Autoconf doesn't catch unexpanded LT_ macros by default: -m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl -m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl -dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 -dnl unless we require an AC_DEFUNed macro: -AC_REQUIRE([LTOPTIONS_VERSION])dnl -AC_REQUIRE([LTSUGAR_VERSION])dnl -AC_REQUIRE([LTVERSION_VERSION])dnl -AC_REQUIRE([LTOBSOLETE_VERSION])dnl -m4_require([_LT_PROG_LTMAIN])dnl - -_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) - -dnl Parse OPTIONS -_LT_SET_OPTIONS([$0], [$1]) - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS=$ltmain - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' -AC_SUBST(LIBTOOL)dnl - -_LT_SETUP - -# Only expand once: -m4_define([LT_INIT]) -])# LT_INIT - -# Old names: -AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) -AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_PROG_LIBTOOL], []) -dnl AC_DEFUN([AM_PROG_LIBTOOL], []) - - -# _LT_PREPARE_CC_BASENAME -# ----------------------- -m4_defun([_LT_PREPARE_CC_BASENAME], [ -# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. -func_cc_basename () -{ - for cc_temp in @S|@*""; do - case $cc_temp in - compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; - distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; - \-*) ;; - *) break;; - esac - done - func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` -} -])# _LT_PREPARE_CC_BASENAME - - -# _LT_CC_BASENAME(CC) -# ------------------- -# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, -# but that macro is also expanded into generated libtool script, which -# arranges for $SED and $ECHO to be set by different means. -m4_defun([_LT_CC_BASENAME], -[m4_require([_LT_PREPARE_CC_BASENAME])dnl -AC_REQUIRE([_LT_DECL_SED])dnl -AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl -func_cc_basename $1 -cc_basename=$func_cc_basename_result -]) - - -# _LT_FILEUTILS_DEFAULTS -# ---------------------- -# It is okay to use these file commands and assume they have been set -# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. -m4_defun([_LT_FILEUTILS_DEFAULTS], -[: ${CP="cp -f"} -: ${MV="mv -f"} -: ${RM="rm -f"} -])# _LT_FILEUTILS_DEFAULTS - - -# _LT_SETUP -# --------- -m4_defun([_LT_SETUP], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl -AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl - -_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl -dnl -_LT_DECL([], [host_alias], [0], [The host system])dnl -_LT_DECL([], [host], [0])dnl -_LT_DECL([], [host_os], [0])dnl -dnl -_LT_DECL([], [build_alias], [0], [The build system])dnl -_LT_DECL([], [build], [0])dnl -_LT_DECL([], [build_os], [0])dnl -dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([LT_PATH_LD])dnl -AC_REQUIRE([LT_PATH_NM])dnl -dnl -AC_REQUIRE([AC_PROG_LN_S])dnl -test -z "$LN_S" && LN_S="ln -s" -_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl -dnl -AC_REQUIRE([LT_CMD_MAX_LEN])dnl -_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl -_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl -dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_CHECK_SHELL_FEATURES])dnl -m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl -m4_require([_LT_CMD_RELOAD])dnl -m4_require([_LT_CHECK_MAGIC_METHOD])dnl -m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl -m4_require([_LT_CMD_OLD_ARCHIVE])dnl -m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl -m4_require([_LT_WITH_SYSROOT])dnl -m4_require([_LT_CMD_TRUNCATE])dnl - -_LT_CONFIG_LIBTOOL_INIT([ -# See if we are running on zsh, and set the options that allow our -# commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}"; then - setopt NO_GLOB_SUBST -fi -]) -if test -n "${ZSH_VERSION+set}"; then - setopt NO_GLOB_SUBST -fi - -_LT_CHECK_OBJDIR - -m4_require([_LT_TAG_COMPILER])dnl - -case $host_os in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test set != "${COLLECT_NAMES+set}"; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Global variables: -ofile=libtool -can_build_shared=yes - -# All known linkers require a '.a' archive for static linking (except MSVC, -# which needs '.lib'). -libext=a - -with_gnu_ld=$lt_cv_prog_gnu_ld - -old_CC=$CC -old_CFLAGS=$CFLAGS - -# Set sane defaults for various variables -test -z "$CC" && CC=cc -test -z "$LTCC" && LTCC=$CC -test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS -test -z "$LD" && LD=ld -test -z "$ac_objext" && ac_objext=o - -_LT_CC_BASENAME([$compiler]) - -# Only perform the check for file, if the check method requires it -test -z "$MAGIC_CMD" && MAGIC_CMD=file -case $deplibs_check_method in -file_magic*) - if test "$file_magic_cmd" = '$MAGIC_CMD'; then - _LT_PATH_MAGIC - fi - ;; -esac - -# Use C for the default configuration in the libtool script -LT_SUPPORTED_TAG([CC]) -_LT_LANG_C_CONFIG -_LT_LANG_DEFAULT_CONFIG -_LT_CONFIG_COMMANDS -])# _LT_SETUP - - -# _LT_PREPARE_SED_QUOTE_VARS -# -------------------------- -# Define a few sed substitution that help us do robust quoting. -m4_defun([_LT_PREPARE_SED_QUOTE_VARS], -[# Backslashify metacharacters that are still active within -# double-quoted strings. -sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\([["`\\]]\)/\\\1/g' - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Sed substitution to delay expansion of an escaped single quote. -delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' - -# Sed substitution to avoid accidental globbing in evaled expressions -no_glob_subst='s/\*/\\\*/g' -]) - -# _LT_PROG_LTMAIN -# --------------- -# Note that this code is called both from 'configure', and 'config.status' -# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, -# 'config.status' has no value for ac_aux_dir unless we are using Automake, -# so we pass a copy along to make sure it has a sensible value anyway. -m4_defun([_LT_PROG_LTMAIN], -[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl -_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) -ltmain=$ac_aux_dir/ltmain.sh -])# _LT_PROG_LTMAIN - - - -# So that we can recreate a full libtool script including additional -# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS -# in macros and then make a single call at the end using the 'libtool' -# label. - - -# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) -# ---------------------------------------- -# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. -m4_define([_LT_CONFIG_LIBTOOL_INIT], -[m4_ifval([$1], - [m4_append([_LT_OUTPUT_LIBTOOL_INIT], - [$1 -])])]) - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_INIT]) - - -# _LT_CONFIG_LIBTOOL([COMMANDS]) -# ------------------------------ -# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. -m4_define([_LT_CONFIG_LIBTOOL], -[m4_ifval([$1], - [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], - [$1 -])])]) - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) - - -# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) -# ----------------------------------------------------- -m4_defun([_LT_CONFIG_SAVE_COMMANDS], -[_LT_CONFIG_LIBTOOL([$1]) -_LT_CONFIG_LIBTOOL_INIT([$2]) -]) - - -# _LT_FORMAT_COMMENT([COMMENT]) -# ----------------------------- -# Add leading comment marks to the start of each line, and a trailing -# full-stop to the whole comment if one is not present already. -m4_define([_LT_FORMAT_COMMENT], -[m4_ifval([$1], [ -m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], - [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) -)]) - - - - - -# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) -# ------------------------------------------------------------------- -# CONFIGNAME is the name given to the value in the libtool script. -# VARNAME is the (base) name used in the configure script. -# VALUE may be 0, 1 or 2 for a computed quote escaped value based on -# VARNAME. Any other value will be used directly. -m4_define([_LT_DECL], -[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], - [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], - [m4_ifval([$1], [$1], [$2])]) - lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) - m4_ifval([$4], - [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) - lt_dict_add_subkey([lt_decl_dict], [$2], - [tagged?], [m4_ifval([$5], [yes], [no])])]) -]) - - -# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) -# -------------------------------------------------------- -m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) - - -# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) -# ------------------------------------------------ -m4_define([lt_decl_tag_varnames], -[_lt_decl_filter([tagged?], [yes], $@)]) - - -# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) -# --------------------------------------------------------- -m4_define([_lt_decl_filter], -[m4_case([$#], - [0], [m4_fatal([$0: too few arguments: $#])], - [1], [m4_fatal([$0: too few arguments: $#: $1])], - [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], - [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], - [lt_dict_filter([lt_decl_dict], $@)])[]dnl -]) - - -# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) -# -------------------------------------------------- -m4_define([lt_decl_quote_varnames], -[_lt_decl_filter([value], [1], $@)]) - - -# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) -# --------------------------------------------------- -m4_define([lt_decl_dquote_varnames], -[_lt_decl_filter([value], [2], $@)]) - - -# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) -# --------------------------------------------------- -m4_define([lt_decl_varnames_tagged], -[m4_assert([$# <= 2])dnl -_$0(m4_quote(m4_default([$1], [[, ]])), - m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), - m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) -m4_define([_lt_decl_varnames_tagged], -[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) - - -# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) -# ------------------------------------------------ -m4_define([lt_decl_all_varnames], -[_$0(m4_quote(m4_default([$1], [[, ]])), - m4_if([$2], [], - m4_quote(lt_decl_varnames), - m4_quote(m4_shift($@))))[]dnl -]) -m4_define([_lt_decl_all_varnames], -[lt_join($@, lt_decl_varnames_tagged([$1], - lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl -]) - - -# _LT_CONFIG_STATUS_DECLARE([VARNAME]) -# ------------------------------------ -# Quote a variable value, and forward it to 'config.status' so that its -# declaration there will have the same value as in 'configure'. VARNAME -# must have a single quote delimited value for this to work. -m4_define([_LT_CONFIG_STATUS_DECLARE], -[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) - - -# _LT_CONFIG_STATUS_DECLARATIONS -# ------------------------------ -# We delimit libtool config variables with single quotes, so when -# we write them to config.status, we have to be sure to quote all -# embedded single quotes properly. In configure, this macro expands -# each variable declared with _LT_DECL (and _LT_TAGDECL) into: -# -# ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' -m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], -[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), - [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) - - -# _LT_LIBTOOL_TAGS -# ---------------- -# Output comment and list of tags supported by the script -m4_defun([_LT_LIBTOOL_TAGS], -[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl -available_tags='_LT_TAGS'dnl -]) - - -# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) -# ----------------------------------- -# Extract the dictionary values for VARNAME (optionally with TAG) and -# expand to a commented shell variable setting: -# -# # Some comment about what VAR is for. -# visible_name=$lt_internal_name -m4_define([_LT_LIBTOOL_DECLARE], -[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], - [description])))[]dnl -m4_pushdef([_libtool_name], - m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl -m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), - [0], [_libtool_name=[$]$1], - [1], [_libtool_name=$lt_[]$1], - [2], [_libtool_name=$lt_[]$1], - [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl -m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl -]) - - -# _LT_LIBTOOL_CONFIG_VARS -# ----------------------- -# Produce commented declarations of non-tagged libtool config variables -# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' -# script. Tagged libtool config variables (even for the LIBTOOL CONFIG -# section) are produced by _LT_LIBTOOL_TAG_VARS. -m4_defun([_LT_LIBTOOL_CONFIG_VARS], -[m4_foreach([_lt_var], - m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), - [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) - - -# _LT_LIBTOOL_TAG_VARS(TAG) -# ------------------------- -m4_define([_LT_LIBTOOL_TAG_VARS], -[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), - [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) - - -# _LT_TAGVAR(VARNAME, [TAGNAME]) -# ------------------------------ -m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) - - -# _LT_CONFIG_COMMANDS -# ------------------- -# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of -# variables for single and double quote escaping we saved from calls -# to _LT_DECL, we can put quote escaped variables declarations -# into 'config.status', and then the shell code to quote escape them in -# for loops in 'config.status'. Finally, any additional code accumulated -# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. -m4_defun([_LT_CONFIG_COMMANDS], -[AC_PROVIDE_IFELSE([LT_OUTPUT], - dnl If the libtool generation code has been placed in $CONFIG_LT, - dnl instead of duplicating it all over again into config.status, - dnl then we will have config.status run $CONFIG_LT later, so it - dnl needs to know what name is stored there: - [AC_CONFIG_COMMANDS([libtool], - [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], - dnl If the libtool generation code is destined for config.status, - dnl expand the accumulated commands and init code now: - [AC_CONFIG_COMMANDS([libtool], - [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) -])#_LT_CONFIG_COMMANDS - - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], -[ - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -sed_quote_subst='$sed_quote_subst' -double_quote_subst='$double_quote_subst' -delay_variable_subst='$delay_variable_subst' -_LT_CONFIG_STATUS_DECLARATIONS -LTCC='$LTCC' -LTCFLAGS='$LTCFLAGS' -compiler='$compiler_DEFAULT' - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -\$[]1 -_LTECHO_EOF' -} - -# Quote evaled strings. -for var in lt_decl_all_varnames([[ \ -]], lt_decl_quote_varnames); do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -# Double-quote double-evaled strings. -for var in lt_decl_all_varnames([[ \ -]], lt_decl_dquote_varnames); do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -_LT_OUTPUT_LIBTOOL_INIT -]) - -# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) -# ------------------------------------ -# Generate a child script FILE with all initialization necessary to -# reuse the environment learned by the parent script, and make the -# file executable. If COMMENT is supplied, it is inserted after the -# '#!' sequence but before initialization text begins. After this -# macro, additional text can be appended to FILE to form the body of -# the child script. The macro ends with non-zero status if the -# file could not be fully written (such as if the disk is full). -m4_ifdef([AS_INIT_GENERATED], -[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], -[m4_defun([_LT_GENERATED_FILE_INIT], -[m4_require([AS_PREPARE])]dnl -[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl -[lt_write_fail=0 -cat >$1 <<_ASEOF || lt_write_fail=1 -#! $SHELL -# Generated by $as_me. -$2 -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$1 <<\_ASEOF || lt_write_fail=1 -AS_SHELL_SANITIZE -_AS_PREPARE -exec AS_MESSAGE_FD>&1 -_ASEOF -test 0 = "$lt_write_fail" && chmod +x $1[]dnl -m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT - -# LT_OUTPUT -# --------- -# This macro allows early generation of the libtool script (before -# AC_OUTPUT is called), incase it is used in configure for compilation -# tests. -AC_DEFUN([LT_OUTPUT], -[: ${CONFIG_LT=./config.lt} -AC_MSG_NOTICE([creating $CONFIG_LT]) -_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], -[# Run this file to recreate a libtool stub with the current configuration.]) - -cat >>"$CONFIG_LT" <<\_LTEOF -lt_cl_silent=false -exec AS_MESSAGE_LOG_FD>>config.log -{ - echo - AS_BOX([Running $as_me.]) -} >&AS_MESSAGE_LOG_FD - -lt_cl_help="\ -'$as_me' creates a local libtool stub from the current configuration, -for use in further configure time tests before the real libtool is -generated. - -Usage: $[0] [[OPTIONS]] - - -h, --help print this help, then exit - -V, --version print version number, then exit - -q, --quiet do not print progress messages - -d, --debug don't remove temporary files - -Report bugs to ." - -lt_cl_version="\ -m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl -m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) -configured by $[0], generated by m4_PACKAGE_STRING. - -Copyright (C) 2011 Free Software Foundation, Inc. -This config.lt script is free software; the Free Software Foundation -gives unlimited permision to copy, distribute and modify it." - -while test 0 != $[#] -do - case $[1] in - --version | --v* | -V ) - echo "$lt_cl_version"; exit 0 ;; - --help | --h* | -h ) - echo "$lt_cl_help"; exit 0 ;; - --debug | --d* | -d ) - debug=: ;; - --quiet | --q* | --silent | --s* | -q ) - lt_cl_silent=: ;; - - -*) AC_MSG_ERROR([unrecognized option: $[1] -Try '$[0] --help' for more information.]) ;; - - *) AC_MSG_ERROR([unrecognized argument: $[1] -Try '$[0] --help' for more information.]) ;; - esac - shift -done - -if $lt_cl_silent; then - exec AS_MESSAGE_FD>/dev/null -fi -_LTEOF - -cat >>"$CONFIG_LT" <<_LTEOF -_LT_OUTPUT_LIBTOOL_COMMANDS_INIT -_LTEOF - -cat >>"$CONFIG_LT" <<\_LTEOF -AC_MSG_NOTICE([creating $ofile]) -_LT_OUTPUT_LIBTOOL_COMMANDS -AS_EXIT(0) -_LTEOF -chmod +x "$CONFIG_LT" - -# configure is writing to config.log, but config.lt does its own redirection, -# appending to config.log, which fails on DOS, as config.log is still kept -# open by configure. Here we exec the FD to /dev/null, effectively closing -# config.log, so it can be properly (re)opened and appended to by config.lt. -lt_cl_success=: -test yes = "$silent" && - lt_config_lt_args="$lt_config_lt_args --quiet" -exec AS_MESSAGE_LOG_FD>/dev/null -$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false -exec AS_MESSAGE_LOG_FD>>config.log -$lt_cl_success || AS_EXIT(1) -])# LT_OUTPUT - - -# _LT_CONFIG(TAG) -# --------------- -# If TAG is the built-in tag, create an initial libtool script with a -# default configuration from the untagged config vars. Otherwise add code -# to config.status for appending the configuration named by TAG from the -# matching tagged config vars. -m4_defun([_LT_CONFIG], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -_LT_CONFIG_SAVE_COMMANDS([ - m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl - m4_if(_LT_TAG, [C], [ - # See if we are running on zsh, and set the options that allow our - # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}"; then - setopt NO_GLOB_SUBST - fi - - cfgfile=${ofile}T - trap "$RM \"$cfgfile\"; exit 1" 1 2 15 - $RM "$cfgfile" - - cat <<_LT_EOF >> "$cfgfile" -#! $SHELL -# Generated automatically by $as_me ($PACKAGE) $VERSION -# NOTE: Changes made to this file will be lost: look at ltmain.sh. - -# Provide generalized library-building support services. -# Written by Gordon Matzigkeit, 1996 - -_LT_COPYING -_LT_LIBTOOL_TAGS - -# Configured defaults for sys_lib_dlsearch_path munging. -: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} - -# ### BEGIN LIBTOOL CONFIG -_LT_LIBTOOL_CONFIG_VARS -_LT_LIBTOOL_TAG_VARS -# ### END LIBTOOL CONFIG - -_LT_EOF - - cat <<'_LT_EOF' >> "$cfgfile" - -# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE - -_LT_PREPARE_MUNGE_PATH_LIST -_LT_PREPARE_CC_BASENAME - -# ### END FUNCTIONS SHARED WITH CONFIGURE - -_LT_EOF - - case $host_os in - aix3*) - cat <<\_LT_EOF >> "$cfgfile" -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test set != "${COLLECT_NAMES+set}"; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -_LT_EOF - ;; - esac - - _LT_PROG_LTMAIN - - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - mv -f "$cfgfile" "$ofile" || - (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") - chmod +x "$ofile" -], -[cat <<_LT_EOF >> "$ofile" - -dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded -dnl in a comment (ie after a #). -# ### BEGIN LIBTOOL TAG CONFIG: $1 -_LT_LIBTOOL_TAG_VARS(_LT_TAG) -# ### END LIBTOOL TAG CONFIG: $1 -_LT_EOF -])dnl /m4_if -], -[m4_if([$1], [], [ - PACKAGE='$PACKAGE' - VERSION='$VERSION' - RM='$RM' - ofile='$ofile'], []) -])dnl /_LT_CONFIG_SAVE_COMMANDS -])# _LT_CONFIG - - -# LT_SUPPORTED_TAG(TAG) -# --------------------- -# Trace this macro to discover what tags are supported by the libtool -# --tag option, using: -# autoconf --trace 'LT_SUPPORTED_TAG:$1' -AC_DEFUN([LT_SUPPORTED_TAG], []) - - -# C support is built-in for now -m4_define([_LT_LANG_C_enabled], []) -m4_define([_LT_TAGS], []) - - -# LT_LANG(LANG) -# ------------- -# Enable libtool support for the given language if not already enabled. -AC_DEFUN([LT_LANG], -[AC_BEFORE([$0], [LT_OUTPUT])dnl -m4_case([$1], - [C], [_LT_LANG(C)], - [C++], [_LT_LANG(CXX)], - [Go], [_LT_LANG(GO)], - [Java], [_LT_LANG(GCJ)], - [Fortran 77], [_LT_LANG(F77)], - [Fortran], [_LT_LANG(FC)], - [Windows Resource], [_LT_LANG(RC)], - [m4_ifdef([_LT_LANG_]$1[_CONFIG], - [_LT_LANG($1)], - [m4_fatal([$0: unsupported language: "$1"])])])dnl -])# LT_LANG - - -# _LT_LANG(LANGNAME) -# ------------------ -m4_defun([_LT_LANG], -[m4_ifdef([_LT_LANG_]$1[_enabled], [], - [LT_SUPPORTED_TAG([$1])dnl - m4_append([_LT_TAGS], [$1 ])dnl - m4_define([_LT_LANG_]$1[_enabled], [])dnl - _LT_LANG_$1_CONFIG($1)])dnl -])# _LT_LANG - - -m4_ifndef([AC_PROG_GO], [ -# NOTE: This macro has been submitted for inclusion into # -# GNU Autoconf as AC_PROG_GO. When it is available in # -# a released version of Autoconf we should remove this # -# macro and use it instead. # -m4_defun([AC_PROG_GO], -[AC_LANG_PUSH(Go)dnl -AC_ARG_VAR([GOC], [Go compiler command])dnl -AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl -_AC_ARG_VAR_LDFLAGS()dnl -AC_CHECK_TOOL(GOC, gccgo) -if test -z "$GOC"; then - if test -n "$ac_tool_prefix"; then - AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) - fi -fi -if test -z "$GOC"; then - AC_CHECK_PROG(GOC, gccgo, gccgo, false) -fi -])#m4_defun -])#m4_ifndef - - -# _LT_LANG_DEFAULT_CONFIG -# ----------------------- -m4_defun([_LT_LANG_DEFAULT_CONFIG], -[AC_PROVIDE_IFELSE([AC_PROG_CXX], - [LT_LANG(CXX)], - [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) - -AC_PROVIDE_IFELSE([AC_PROG_F77], - [LT_LANG(F77)], - [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) - -AC_PROVIDE_IFELSE([AC_PROG_FC], - [LT_LANG(FC)], - [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) - -dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal -dnl pulling things in needlessly. -AC_PROVIDE_IFELSE([AC_PROG_GCJ], - [LT_LANG(GCJ)], - [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], - [LT_LANG(GCJ)], - [AC_PROVIDE_IFELSE([LT_PROG_GCJ], - [LT_LANG(GCJ)], - [m4_ifdef([AC_PROG_GCJ], - [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) - m4_ifdef([A][M_PROG_GCJ], - [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) - m4_ifdef([LT_PROG_GCJ], - [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) - -AC_PROVIDE_IFELSE([AC_PROG_GO], - [LT_LANG(GO)], - [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) - -AC_PROVIDE_IFELSE([LT_PROG_RC], - [LT_LANG(RC)], - [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) -])# _LT_LANG_DEFAULT_CONFIG - -# Obsolete macros: -AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) -AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) -AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) -AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) -AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_CXX], []) -dnl AC_DEFUN([AC_LIBTOOL_F77], []) -dnl AC_DEFUN([AC_LIBTOOL_FC], []) -dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) -dnl AC_DEFUN([AC_LIBTOOL_RC], []) - - -# _LT_TAG_COMPILER -# ---------------- -m4_defun([_LT_TAG_COMPILER], -[AC_REQUIRE([AC_PROG_CC])dnl - -_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl -_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl -_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl -_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC -])# _LT_TAG_COMPILER - - -# _LT_COMPILER_BOILERPLATE -# ------------------------ -# Check for compiler boilerplate output or warnings with -# the simple compiler test code. -m4_defun([_LT_COMPILER_BOILERPLATE], -[m4_require([_LT_DECL_SED])dnl -ac_outfile=conftest.$ac_objext -echo "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$RM conftest* -])# _LT_COMPILER_BOILERPLATE - - -# _LT_LINKER_BOILERPLATE -# ---------------------- -# Check for linker boilerplate output or warnings with -# the simple link test code. -m4_defun([_LT_LINKER_BOILERPLATE], -[m4_require([_LT_DECL_SED])dnl -ac_outfile=conftest.$ac_objext -echo "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$RM -r conftest* -])# _LT_LINKER_BOILERPLATE - -# _LT_REQUIRED_DARWIN_CHECKS -# ------------------------- -m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ - case $host_os in - rhapsody* | darwin*) - AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) - AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) - AC_CHECK_TOOL([LIPO], [lipo], [:]) - AC_CHECK_TOOL([OTOOL], [otool], [:]) - AC_CHECK_TOOL([OTOOL64], [otool64], [:]) - _LT_DECL([], [DSYMUTIL], [1], - [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) - _LT_DECL([], [NMEDIT], [1], - [Tool to change global to local symbols on Mac OS X]) - _LT_DECL([], [LIPO], [1], - [Tool to manipulate fat objects and archives on Mac OS X]) - _LT_DECL([], [OTOOL], [1], - [ldd/readelf like tool for Mach-O binaries on Mac OS X]) - _LT_DECL([], [OTOOL64], [1], - [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) - - AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], - [lt_cv_apple_cc_single_mod=no - if test -z "$LT_MULTI_MODULE"; then - # By default we will add the -single_module flag. You can override - # by either setting the environment variable LT_MULTI_MODULE - # non-empty at configure time, or by adding -multi_module to the - # link flags. - rm -rf libconftest.dylib* - echo "int foo(void){return 1;}" > conftest.c - echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ --dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD - $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ - -dynamiclib -Wl,-single_module conftest.c 2>conftest.err - _lt_result=$? - # If there is a non-empty error log, and "single_module" - # appears in it, assume the flag caused a linker warning - if test -s conftest.err && $GREP single_module conftest.err; then - cat conftest.err >&AS_MESSAGE_LOG_FD - # Otherwise, if the output was created with a 0 exit code from - # the compiler, it worked. - elif test -f libconftest.dylib && test 0 = "$_lt_result"; then - lt_cv_apple_cc_single_mod=yes - else - cat conftest.err >&AS_MESSAGE_LOG_FD - fi - rm -rf libconftest.dylib* - rm -f conftest.* - fi]) - - AC_CACHE_CHECK([for -exported_symbols_list linker flag], - [lt_cv_ld_exported_symbols_list], - [lt_cv_ld_exported_symbols_list=no - save_LDFLAGS=$LDFLAGS - echo "_main" > conftest.sym - LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" - AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], - [lt_cv_ld_exported_symbols_list=yes], - [lt_cv_ld_exported_symbols_list=no]) - LDFLAGS=$save_LDFLAGS - ]) - - AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], - [lt_cv_ld_force_load=no - cat > conftest.c << _LT_EOF -int forced_loaded() { return 2;} -_LT_EOF - echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD - $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD - echo "$AR cr libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD - $AR cr libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD - echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD - $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD - cat > conftest.c << _LT_EOF -int main() { return 0;} -_LT_EOF - echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD - $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err - _lt_result=$? - if test -s conftest.err && $GREP force_load conftest.err; then - cat conftest.err >&AS_MESSAGE_LOG_FD - elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then - lt_cv_ld_force_load=yes - else - cat conftest.err >&AS_MESSAGE_LOG_FD - fi - rm -f conftest.err libconftest.a conftest conftest.c - rm -rf conftest.dSYM - ]) - case $host_os in - rhapsody* | darwin1.[[012]]) - _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; - darwin1.*) - _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[[912]]*) - _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; - 10.[[012]][[,.]]*) - _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - 10.*|11.*) - _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; - esac - ;; - esac - if test yes = "$lt_cv_apple_cc_single_mod"; then - _lt_dar_single_mod='$single_module' - fi - if test yes = "$lt_cv_ld_exported_symbols_list"; then - _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' - else - _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' - fi - if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then - _lt_dsymutil='~$DSYMUTIL $lib || :' - else - _lt_dsymutil= - fi - ;; - esac -]) - - -# _LT_DARWIN_LINKER_FEATURES([TAG]) -# --------------------------------- -# Checks for linker and compiler features on darwin -m4_defun([_LT_DARWIN_LINKER_FEATURES], -[ - m4_require([_LT_REQUIRED_DARWIN_CHECKS]) - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_automatic, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - if test yes = "$lt_cv_ld_force_load"; then - _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' - m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], - [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) - else - _LT_TAGVAR(whole_archive_flag_spec, $1)='' - fi - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined - case $cc_basename in - ifort*|nagfor*) _lt_dar_can_shared=yes ;; - *) _lt_dar_can_shared=$GCC ;; - esac - if test yes = "$_lt_dar_can_shared"; then - output_verbose_link_cmd=func_echo_all - _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" - _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" - _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" - m4_if([$1], [CXX], -[ if test yes != "$lt_cv_apple_cc_single_mod"; then - _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" - fi -],[]) - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi -]) - -# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) -# ---------------------------------- -# Links a minimal program and checks the executable -# for the system default hardcoded library path. In most cases, -# this is /usr/lib:/lib, but when the MPI compilers are used -# the location of the communication and MPI libs are included too. -# If we don't find anything, use the default library path according -# to the aix ld manual. -# Store the results from the different compilers for each TAGNAME. -# Allow to override them for all tags through lt_cv_aix_libpath. -m4_defun([_LT_SYS_MODULE_PATH_AIX], -[m4_require([_LT_DECL_SED])dnl -if test set = "${lt_cv_aix_libpath+set}"; then - aix_libpath=$lt_cv_aix_libpath -else - AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], - [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ - lt_aix_libpath_sed='[ - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\([^ ]*\) *$/\1/ - p - } - }]' - _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - # Check for a 64-bit object if we didn't find anything. - if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then - _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - fi],[]) - if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then - _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib - fi - ]) - aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) -fi -])# _LT_SYS_MODULE_PATH_AIX - - -# _LT_SHELL_INIT(ARG) -# ------------------- -m4_define([_LT_SHELL_INIT], -[m4_divert_text([M4SH-INIT], [$1 -])])# _LT_SHELL_INIT - - - -# _LT_PROG_ECHO_BACKSLASH -# ----------------------- -# Find how we can fake an echo command that does not interpret backslash. -# In particular, with Autoconf 2.60 or later we add some code to the start -# of the generated configure script that will find a shell with a builtin -# printf (that we can use as an echo command). -m4_defun([_LT_PROG_ECHO_BACKSLASH], -[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO - -AC_MSG_CHECKING([how to print strings]) -# Test print first, because it will be a builtin if present. -if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ - test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='print -r --' -elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='printf %s\n' -else - # Use this function as a fallback that always works. - func_fallback_echo () - { - eval 'cat <<_LTECHO_EOF -$[]1 -_LTECHO_EOF' - } - ECHO='func_fallback_echo' -fi - -# func_echo_all arg... -# Invoke $ECHO with all args, space-separated. -func_echo_all () -{ - $ECHO "$*" -} - -case $ECHO in - printf*) AC_MSG_RESULT([printf]) ;; - print*) AC_MSG_RESULT([print -r]) ;; - *) AC_MSG_RESULT([cat]) ;; -esac - -m4_ifdef([_AS_DETECT_SUGGESTED], -[_AS_DETECT_SUGGESTED([ - test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( - ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' - ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO - ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO - PATH=/empty FPATH=/empty; export PATH FPATH - test "X`printf %s $ECHO`" = "X$ECHO" \ - || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) - -_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) -_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) -])# _LT_PROG_ECHO_BACKSLASH - - -# _LT_WITH_SYSROOT -# ---------------- -AC_DEFUN([_LT_WITH_SYSROOT], -[AC_MSG_CHECKING([for sysroot]) -AC_ARG_WITH([sysroot], -[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], - [Search for dependent libraries within DIR (or the compiler's sysroot - if not specified).])], -[], [with_sysroot=no]) - -dnl lt_sysroot will always be passed unquoted. We quote it here -dnl in case the user passed a directory name. -lt_sysroot= -case $with_sysroot in #( - yes) - if test yes = "$GCC"; then - lt_sysroot=`$CC --print-sysroot 2>/dev/null` - fi - ;; #( - /*) - lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` - ;; #( - no|'') - ;; #( - *) - AC_MSG_RESULT([$with_sysroot]) - AC_MSG_ERROR([The sysroot must be an absolute path.]) - ;; -esac - - AC_MSG_RESULT([${lt_sysroot:-no}]) -_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl -[dependent libraries, and where our libraries should be installed.])]) - -# _LT_ENABLE_LOCK -# --------------- -m4_defun([_LT_ENABLE_LOCK], -[AC_ARG_ENABLE([libtool-lock], - [AS_HELP_STRING([--disable-libtool-lock], - [avoid locking (might break parallel builds)])]) -test no = "$enable_libtool_lock" || enable_libtool_lock=yes - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case $host in -ia64-*-hpux*) - # Find out what ABI is being produced by ac_compile, and set mode - # options accordingly. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.$ac_objext` in - *ELF-32*) - HPUX_IA64_MODE=32 - ;; - *ELF-64*) - HPUX_IA64_MODE=64 - ;; - esac - fi - rm -rf conftest* - ;; -*-*-irix6*) - # Find out what ABI is being produced by ac_compile, and set linker - # options accordingly. - echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - if test yes = "$lt_cv_prog_gnu_ld"; then - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -melf32bsmip" - ;; - *N32*) - LD="${LD-ld} -melf32bmipn32" - ;; - *64-bit*) - LD="${LD-ld} -melf64bmip" - ;; - esac - else - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - fi - rm -rf conftest* - ;; - -mips64*-*linux*) - # Find out what ABI is being produced by ac_compile, and set linker - # options accordingly. - echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - emul=elf - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - emul="${emul}32" - ;; - *64-bit*) - emul="${emul}64" - ;; - esac - case `/usr/bin/file conftest.$ac_objext` in - *MSB*) - emul="${emul}btsmip" - ;; - *LSB*) - emul="${emul}ltsmip" - ;; - esac - case `/usr/bin/file conftest.$ac_objext` in - *N32*) - emul="${emul}n32" - ;; - esac - LD="${LD-ld} -m $emul" - fi - rm -rf conftest* - ;; - -x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ -s390*-*linux*|s390*-*tpf*|sparc*-*linux*) - # Find out what ABI is being produced by ac_compile, and set linker - # options accordingly. Note that the listed cases only cover the - # situations where additional linker options are needed (such as when - # doing 32-bit compilation for a host where ld defaults to 64-bit, or - # vice versa); the common cases where no linker options are needed do - # not appear in the list. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in - *32-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_i386_fbsd" - ;; - x86_64-*linux*) - case `/usr/bin/file conftest.o` in - *x86-64*) - LD="${LD-ld} -m elf32_x86_64" - ;; - *) - LD="${LD-ld} -m elf_i386" - ;; - esac - ;; - powerpc64le-*linux*) - LD="${LD-ld} -m elf32lppclinux" - ;; - powerpc64-*linux*) - LD="${LD-ld} -m elf32ppclinux" - ;; - s390x-*linux*) - LD="${LD-ld} -m elf_s390" - ;; - sparc64-*linux*) - LD="${LD-ld} -m elf32_sparc" - ;; - esac - ;; - *64-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_x86_64_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_x86_64" - ;; - powerpcle-*linux*) - LD="${LD-ld} -m elf64lppc" - ;; - powerpc-*linux*) - LD="${LD-ld} -m elf64ppc" - ;; - s390*-*linux*|s390*-*tpf*) - LD="${LD-ld} -m elf64_s390" - ;; - sparc*-*linux*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS=$CFLAGS - CFLAGS="$CFLAGS -belf" - AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, - [AC_LANG_PUSH(C) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) - AC_LANG_POP]) - if test yes != "$lt_cv_cc_needs_belf"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS=$SAVE_CFLAGS - fi - ;; -*-*solaris*) - # Find out what ABI is being produced by ac_compile, and set linker - # options accordingly. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in - *64-bit*) - case $lt_cv_prog_gnu_ld in - yes*) - case $host in - i?86-*-solaris*|x86_64-*-solaris*) - LD="${LD-ld} -m elf_x86_64" - ;; - sparc*-*-solaris*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - # GNU ld 2.21 introduced _sol2 emulations. Use them if available. - if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then - LD=${LD-ld}_sol2 - fi - ;; - *) - if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then - LD="${LD-ld} -64" - fi - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; -esac - -need_locks=$enable_libtool_lock -])# _LT_ENABLE_LOCK - - -# _LT_PROG_AR -# ----------- -m4_defun([_LT_PROG_AR], -[AC_CHECK_TOOLS(AR, [ar], false) -: ${AR=ar} -: ${AR_FLAGS=cr} -_LT_DECL([], [AR], [1], [The archiver]) -_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) - -AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], - [lt_cv_ar_at_file=no - AC_COMPILE_IFELSE([AC_LANG_PROGRAM], - [echo conftest.$ac_objext > conftest.lst - lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' - AC_TRY_EVAL([lt_ar_try]) - if test 0 -eq "$ac_status"; then - # Ensure the archiver fails upon bogus file names. - rm -f conftest.$ac_objext libconftest.a - AC_TRY_EVAL([lt_ar_try]) - if test 0 -ne "$ac_status"; then - lt_cv_ar_at_file=@ - fi - fi - rm -f conftest.* libconftest.a - ]) - ]) - -if test no = "$lt_cv_ar_at_file"; then - archiver_list_spec= -else - archiver_list_spec=$lt_cv_ar_at_file -fi -_LT_DECL([], [archiver_list_spec], [1], - [How to feed a file listing to the archiver]) -])# _LT_PROG_AR - - -# _LT_CMD_OLD_ARCHIVE -# ------------------- -m4_defun([_LT_CMD_OLD_ARCHIVE], -[_LT_PROG_AR - -AC_CHECK_TOOL(STRIP, strip, :) -test -z "$STRIP" && STRIP=: -_LT_DECL([], [STRIP], [1], [A symbol stripping program]) - -AC_CHECK_TOOL(RANLIB, ranlib, :) -test -z "$RANLIB" && RANLIB=: -_LT_DECL([], [RANLIB], [1], - [Commands used to install an old-style archive]) - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - case $host_os in - bitrig* | openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" - ;; - *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" - ;; - esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" -fi - -case $host_os in - darwin*) - lock_old_archive_extraction=yes ;; - *) - lock_old_archive_extraction=no ;; -esac -_LT_DECL([], [old_postinstall_cmds], [2]) -_LT_DECL([], [old_postuninstall_cmds], [2]) -_LT_TAGDECL([], [old_archive_cmds], [2], - [Commands used to build an old-style archive]) -_LT_DECL([], [lock_old_archive_extraction], [0], - [Whether to use a lock for old archive extraction]) -])# _LT_CMD_OLD_ARCHIVE - - -# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) -# ---------------------------------------------------------------- -# Check whether the given compiler option works -AC_DEFUN([_LT_COMPILER_OPTION], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_SED])dnl -AC_CACHE_CHECK([$1], [$2], - [$2=no - m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - $2=yes - fi - fi - $RM conftest* -]) - -if test yes = "[$]$2"; then - m4_if([$5], , :, [$5]) -else - m4_if([$6], , :, [$6]) -fi -])# _LT_COMPILER_OPTION - -# Old name: -AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) - - -# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [ACTION-SUCCESS], [ACTION-FAILURE]) -# ---------------------------------------------------- -# Check whether the given linker option works -AC_DEFUN([_LT_LINKER_OPTION], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_SED])dnl -AC_CACHE_CHECK([$1], [$2], - [$2=no - save_LDFLAGS=$LDFLAGS - LDFLAGS="$LDFLAGS $3" - echo "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&AS_MESSAGE_LOG_FD - $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - $2=yes - fi - else - $2=yes - fi - fi - $RM -r conftest* - LDFLAGS=$save_LDFLAGS -]) - -if test yes = "[$]$2"; then - m4_if([$4], , :, [$4]) -else - m4_if([$5], , :, [$5]) -fi -])# _LT_LINKER_OPTION - -# Old name: -AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) - - -# LT_CMD_MAX_LEN -#--------------- -AC_DEFUN([LT_CMD_MAX_LEN], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -# find the maximum length of command line arguments -AC_MSG_CHECKING([the maximum length of command line arguments]) -AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl - i=0 - teststring=ABCD - - case $build_os in - msdosdjgpp*) - # On DJGPP, this test can blow up pretty badly due to problems in libc - # (any single argument exceeding 2000 bytes causes a buffer overrun - # during glob expansion). Even if it were fixed, the result of this - # check would be larger than it should be. - lt_cv_sys_max_cmd_len=12288; # 12K is about right - ;; - - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. - # Libtool will interpret -1 as no limit whatsoever - lt_cv_sys_max_cmd_len=-1; - ;; - - cygwin* | mingw* | cegcc*) - # On Win9x/ME, this test blows up -- it succeeds, but takes - # about 5 minutes as the teststring grows exponentially. - # Worse, since 9x/ME are not pre-emptively multitasking, - # you end up with a "frozen" computer, even though with patience - # the test eventually succeeds (with a max line length of 256k). - # Instead, let's just punt: use the minimum linelength reported by - # all of the supported platforms: 8192 (on NT/2K/XP). - lt_cv_sys_max_cmd_len=8192; - ;; - - mint*) - # On MiNT this can take a long time and run out of memory. - lt_cv_sys_max_cmd_len=8192; - ;; - - amigaos*) - # On AmigaOS with pdksh, this test takes hours, literally. - # So we just punt and use a minimum line length of 8192. - lt_cv_sys_max_cmd_len=8192; - ;; - - bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) - # This has been around since 386BSD, at least. Likely further. - if test -x /sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` - elif test -x /usr/sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` - else - lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs - fi - # And add a safety zone - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - ;; - - interix*) - # We know the value 262144 and hardcode it with a safety zone (like BSD) - lt_cv_sys_max_cmd_len=196608 - ;; - - os2*) - # The test takes a long time on OS/2. - lt_cv_sys_max_cmd_len=8192 - ;; - - osf*) - # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure - # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not - # nice to cause kernel panics so lets avoid the loop below. - # First set a reasonable default. - lt_cv_sys_max_cmd_len=16384 - # - if test -x /sbin/sysconfig; then - case `/sbin/sysconfig -q proc exec_disable_arg_limit` in - *1*) lt_cv_sys_max_cmd_len=-1 ;; - esac - fi - ;; - sco3.2v5*) - lt_cv_sys_max_cmd_len=102400 - ;; - sysv5* | sco5v6* | sysv4.2uw2*) - kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` - if test -n "$kargmax"; then - lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` - else - lt_cv_sys_max_cmd_len=32768 - fi - ;; - *) - lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` - if test -n "$lt_cv_sys_max_cmd_len" && \ - test undefined != "$lt_cv_sys_max_cmd_len"; then - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - else - # Make teststring a little bigger before we do anything with it. - # a 1K string should be a reasonable start. - for i in 1 2 3 4 5 6 7 8; do - teststring=$teststring$teststring - done - SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} - # If test is not a shell built-in, we'll probably end up computing a - # maximum length that is only half of the actual maximum length, but - # we can't tell. - while { test X`env echo "$teststring$teststring" 2>/dev/null` \ - = "X$teststring$teststring"; } >/dev/null 2>&1 && - test 17 != "$i" # 1/2 MB should be enough - do - i=`expr $i + 1` - teststring=$teststring$teststring - done - # Only check the string length outside the loop. - lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` - teststring= - # Add a significant safety factor because C++ compilers can tack on - # massive amounts of additional arguments before passing them to the - # linker. It appears as though 1/2 is a usable value. - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` - fi - ;; - esac -]) -if test -n "$lt_cv_sys_max_cmd_len"; then - AC_MSG_RESULT($lt_cv_sys_max_cmd_len) -else - AC_MSG_RESULT(none) -fi -max_cmd_len=$lt_cv_sys_max_cmd_len -_LT_DECL([], [max_cmd_len], [0], - [What is the maximum length of a command?]) -])# LT_CMD_MAX_LEN - -# Old name: -AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) - - -# _LT_HEADER_DLFCN -# ---------------- -m4_defun([_LT_HEADER_DLFCN], -[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl -])# _LT_HEADER_DLFCN - - -# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, -# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) -# ---------------------------------------------------------------- -m4_defun([_LT_TRY_DLOPEN_SELF], -[m4_require([_LT_HEADER_DLFCN])dnl -if test yes = "$cross_compiling"; then : - [$4] -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF -[#line $LINENO "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -/* When -fvisibility=hidden is used, assume the code has been annotated - correspondingly for the symbols needed. */ -#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -int fnord () __attribute__((visibility("default"))); -#endif - -int fnord () { return 42; } -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else - { - if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - else puts (dlerror ()); - } - /* dlclose (self); */ - } - else - puts (dlerror ()); - - return status; -}] -_LT_EOF - if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then - (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) $1 ;; - x$lt_dlneed_uscore) $2 ;; - x$lt_dlunknown|x*) $3 ;; - esac - else : - # compilation failed - $3 - fi -fi -rm -fr conftest* -])# _LT_TRY_DLOPEN_SELF - - -# LT_SYS_DLOPEN_SELF -# ------------------ -AC_DEFUN([LT_SYS_DLOPEN_SELF], -[m4_require([_LT_HEADER_DLFCN])dnl -if test yes != "$enable_dlopen"; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen=load_add_on - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32* | cegcc*) - lt_cv_dlopen=LoadLibrary - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen=dlopen - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ - lt_cv_dlopen=dyld - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ]) - ;; - - tpf*) - # Don't try to run any link tests for TPF. We know it's impossible - # because TPF is a cross-compiler, and we know how we open DSOs. - lt_cv_dlopen=dlopen - lt_cv_dlopen_libs= - lt_cv_dlopen_self=no - ;; - - *) - AC_CHECK_FUNC([shl_load], - [lt_cv_dlopen=shl_load], - [AC_CHECK_LIB([dld], [shl_load], - [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], - [AC_CHECK_FUNC([dlopen], - [lt_cv_dlopen=dlopen], - [AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], - [AC_CHECK_LIB([svld], [dlopen], - [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], - [AC_CHECK_LIB([dld], [dld_link], - [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) - ]) - ]) - ]) - ]) - ]) - ;; - esac - - if test no = "$lt_cv_dlopen"; then - enable_dlopen=no - else - enable_dlopen=yes - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS=$CPPFLAGS - test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS=$LDFLAGS - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS=$LIBS - LIBS="$lt_cv_dlopen_libs $LIBS" - - AC_CACHE_CHECK([whether a program can dlopen itself], - lt_cv_dlopen_self, [dnl - _LT_TRY_DLOPEN_SELF( - lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, - lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) - ]) - - if test yes = "$lt_cv_dlopen_self"; then - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" - AC_CACHE_CHECK([whether a statically linked program can dlopen itself], - lt_cv_dlopen_self_static, [dnl - _LT_TRY_DLOPEN_SELF( - lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, - lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) - ]) - fi - - CPPFLAGS=$save_CPPFLAGS - LDFLAGS=$save_LDFLAGS - LIBS=$save_LIBS - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi -_LT_DECL([dlopen_support], [enable_dlopen], [0], - [Whether dlopen is supported]) -_LT_DECL([dlopen_self], [enable_dlopen_self], [0], - [Whether dlopen of programs is supported]) -_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], - [Whether dlopen of statically linked programs is supported]) -])# LT_SYS_DLOPEN_SELF - -# Old name: -AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) - - -# _LT_COMPILER_C_O([TAGNAME]) -# --------------------------- -# Check to see if options -c and -o are simultaneously supported by compiler. -# This macro does not hard code the compiler like AC_PROG_CC_C_O. -m4_defun([_LT_COMPILER_C_O], -[m4_require([_LT_DECL_SED])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_TAG_COMPILER])dnl -AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], - [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], - [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes - fi - fi - chmod u+w . 2>&AS_MESSAGE_LOG_FD - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* -]) -_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], - [Does compiler simultaneously support -c and -o options?]) -])# _LT_COMPILER_C_O - - -# _LT_COMPILER_FILE_LOCKS([TAGNAME]) -# ---------------------------------- -# Check to see if we can do hard links to lock some files if needed -m4_defun([_LT_COMPILER_FILE_LOCKS], -[m4_require([_LT_ENABLE_LOCK])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -_LT_COMPILER_C_O([$1]) - -hard_links=nottested -if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then - # do not overwrite the value of need_locks provided by the user - AC_MSG_CHECKING([if we can lock with hard links]) - hard_links=yes - $RM conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - AC_MSG_RESULT([$hard_links]) - if test no = "$hard_links"; then - AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) - need_locks=warn - fi -else - need_locks=no -fi -_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) -])# _LT_COMPILER_FILE_LOCKS - - -# _LT_CHECK_OBJDIR -# ---------------- -m4_defun([_LT_CHECK_OBJDIR], -[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], -[rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - lt_cv_objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - lt_cv_objdir=_libs -fi -rmdir .libs 2>/dev/null]) -objdir=$lt_cv_objdir -_LT_DECL([], [objdir], [0], - [The name of the directory that contains temporary libtool files])dnl -m4_pattern_allow([LT_OBJDIR])dnl -AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", - [Define to the sub-directory where libtool stores uninstalled libraries.]) -])# _LT_CHECK_OBJDIR - - -# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) -# -------------------------------------- -# Check hardcoding attributes. -m4_defun([_LT_LINKER_HARDCODE_LIBPATH], -[AC_MSG_CHECKING([how to hardcode library paths into programs]) -_LT_TAGVAR(hardcode_action, $1)= -if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || - test -n "$_LT_TAGVAR(runpath_var, $1)" || - test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then - - # We can hardcode non-existent directories. - if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && - test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then - # Linking always hardcodes the temporary library directory. - _LT_TAGVAR(hardcode_action, $1)=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - _LT_TAGVAR(hardcode_action, $1)=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - _LT_TAGVAR(hardcode_action, $1)=unsupported -fi -AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) - -if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || - test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then - # Fast installation is not supported - enable_fast_install=no -elif test yes = "$shlibpath_overrides_runpath" || - test no = "$enable_shared"; then - # Fast installation is not necessary - enable_fast_install=needless -fi -_LT_TAGDECL([], [hardcode_action], [0], - [How to hardcode a shared library path into an executable]) -])# _LT_LINKER_HARDCODE_LIBPATH - - -# _LT_CMD_STRIPLIB -# ---------------- -m4_defun([_LT_CMD_STRIPLIB], -[m4_require([_LT_DECL_EGREP]) -striplib= -old_striplib= -AC_MSG_CHECKING([whether stripping libraries is possible]) -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - AC_MSG_RESULT([yes]) -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP"; then - striplib="$STRIP -x" - old_striplib="$STRIP -S" - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - fi - ;; - *) - AC_MSG_RESULT([no]) - ;; - esac -fi -_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) -_LT_DECL([], [striplib], [1]) -])# _LT_CMD_STRIPLIB - - -# _LT_PREPARE_MUNGE_PATH_LIST -# --------------------------- -# Make sure func_munge_path_list() is defined correctly. -m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], -[[# func_munge_path_list VARIABLE PATH -# ----------------------------------- -# VARIABLE is name of variable containing _space_ separated list of -# directories to be munged by the contents of PATH, which is string -# having a format: -# "DIR[:DIR]:" -# string "DIR[ DIR]" will be prepended to VARIABLE -# ":DIR[:DIR]" -# string "DIR[ DIR]" will be appended to VARIABLE -# "DIRP[:DIRP]::[DIRA:]DIRA" -# string "DIRP[ DIRP]" will be prepended to VARIABLE and string -# "DIRA[ DIRA]" will be appended to VARIABLE -# "DIR[:DIR]" -# VARIABLE will be replaced by "DIR[ DIR]" -func_munge_path_list () -{ - case x@S|@2 in - x) - ;; - *:) - eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" - ;; - x:*) - eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" - ;; - *::*) - eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" - eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" - ;; - *) - eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" - ;; - esac -} -]])# _LT_PREPARE_PATH_LIST - - -# _LT_SYS_DYNAMIC_LINKER([TAG]) -# ----------------------------- -# PORTME Fill in your ld.so characteristics -m4_defun([_LT_SYS_DYNAMIC_LINKER], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_OBJDUMP])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_CHECK_SHELL_FEATURES])dnl -m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl -AC_MSG_CHECKING([dynamic linker characteristics]) -m4_if([$1], - [], [ -if test yes = "$GCC"; then - case $host_os in - darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; - *) lt_awk_arg='/^libraries:/' ;; - esac - case $host_os in - mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; - *) lt_sed_strip_eq='s|=/|/|g' ;; - esac - lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` - case $lt_search_path_spec in - *\;*) - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` - ;; - *) - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` - ;; - esac - # Ok, now we have the path, separated by spaces, we can step through it - # and add multilib dir if necessary... - lt_tmp_lt_search_path_spec= - lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` - # ...but if some path component already ends with the multilib dir we assume - # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). - case "$lt_multi_os_dir; $lt_search_path_spec " in - "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) - lt_multi_os_dir= - ;; - esac - for lt_sys_path in $lt_search_path_spec; do - if test -d "$lt_sys_path$lt_multi_os_dir"; then - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" - elif test -n "$lt_multi_os_dir"; then - test -d "$lt_sys_path" && \ - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" - fi - done - lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' -BEGIN {RS = " "; FS = "/|\n";} { - lt_foo = ""; - lt_count = 0; - for (lt_i = NF; lt_i > 0; lt_i--) { - if ($lt_i != "" && $lt_i != ".") { - if ($lt_i == "..") { - lt_count++; - } else { - if (lt_count == 0) { - lt_foo = "/" $lt_i lt_foo; - } else { - lt_count--; - } - } - } - } - if (lt_foo != "") { lt_freq[[lt_foo]]++; } - if (lt_freq[[lt_foo]] == 1) { print lt_foo; } -}'` - # AWK program above erroneously prepends '/' to C:/dos/paths - # for these hosts. - case $host_os in - mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ - $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; - esac - sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi]) -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=.so -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -AC_ARG_VAR([LT_SYS_LIBRARY_PATH], -[User-defined run-time library search path.]) - -case $host_os in -aix3*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname$release$shared_ext$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='$libname$release$shared_ext$major' - ;; - -aix[[4-9]]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test ia64 = "$host_cpu"; then - # AIX 5 supports IA64 - library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line '#! .'. This would cause the generated library to - # depend on '.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[[01]] | aix4.[[01]].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # Using Import Files as archive members, it is possible to support - # filename-based versioning of shared library archives on AIX. While - # this would work for both with and without runtime linking, it will - # prevent static linking of such archives. So we do filename-based - # shared library versioning with .so extension only, which is used - # when both runtime linking and shared linking is enabled. - # Unfortunately, runtime linking may impact performance, so we do - # not want this to be the default eventually. Also, we use the - # versioned .so libs for executables only if there is the -brtl - # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. - # To allow for filename-based versioning support, we need to create - # libNAME.so.V as an archive file, containing: - # *) an Import File, referring to the versioned filename of the - # archive as well as the shared archive member, telling the - # bitwidth (32 or 64) of that shared object, and providing the - # list of exported symbols of that shared object, eventually - # decorated with the 'weak' keyword - # *) the shared object with the F_LOADONLY flag set, to really avoid - # it being seen by the linker. - # At run time we better use the real file rather than another symlink, - # but for link time we create the symlink libNAME.so -> libNAME.so.V - - case $with_aix_soname,$aix_use_runtimelinking in - # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - aix,yes) # traditional libtool - dynamic_linker='AIX unversionable lib.so' - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - ;; - aix,no) # traditional AIX only - dynamic_linker='AIX lib.a[(]lib.so.V[)]' - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='$libname$release.a $libname.a' - soname_spec='$libname$release$shared_ext$major' - ;; - svr4,*) # full svr4 only - dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" - library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' - # We do not specify a path in Import Files, so LIBPATH fires. - shlibpath_overrides_runpath=yes - ;; - *,yes) # both, prefer svr4 - dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" - library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' - # unpreferred sharedlib libNAME.a needs extra handling - postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' - postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' - # We do not specify a path in Import Files, so LIBPATH fires. - shlibpath_overrides_runpath=yes - ;; - *,no) # both, prefer aix - dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" - library_names_spec='$libname$release.a $libname.a' - soname_spec='$libname$release$shared_ext$major' - # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling - postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' - postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' - ;; - esac - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - case $host_cpu in - powerpc) - # Since July 2007 AmigaOS4 officially supports .so libraries. - # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - ;; - m68k) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - esac - ;; - -beos*) - library_names_spec='$libname$shared_ext' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi[[45]]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32* | cegcc*) - version_type=windows - shrext_cmds=.dll - need_version=no - need_lib_prefix=no - - case $GCC,$cc_basename in - yes,*) - # gcc - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \$file`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' -m4_if([$1], [],[ - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) - ;; - mingw* | cegcc*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' - ;; - esac - dynamic_linker='Win32 ld.exe' - ;; - - *,cl*) - # Native MSVC - libname_spec='$name' - soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' - library_names_spec='$libname.dll.lib' - - case $build_os in - mingw*) - sys_lib_search_path_spec= - lt_save_ifs=$IFS - IFS=';' - for lt_path in $LIB - do - IFS=$lt_save_ifs - # Let DOS variable expansion print the short 8.3 style file name. - lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` - sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" - done - IFS=$lt_save_ifs - # Convert to MSYS style. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` - ;; - cygwin*) - # Convert to unix form, then to dos form, then back to unix form - # but this time dos style (no spaces!) so that the unix form looks - # like /cygdrive/c/PROGRA~1:/cygdr... - sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` - sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` - sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - ;; - *) - sys_lib_search_path_spec=$LIB - if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then - # It is most probably a Windows format PATH. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - # FIXME: find the short name or the path components, as spaces are - # common. (e.g. "Program Files" -> "PROGRA~1") - ;; - esac - - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \$file`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - dynamic_linker='Win32 link.exe' - ;; - - *) - # Assume MSVC wrapper - library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' - dynamic_linker='Win32 ld.exe' - ;; - esac - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' - soname_spec='$libname$release$major$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' -m4_if([$1], [],[ - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd* | dragonfly*) - # DragonFly does not have aout. When/if they implement a new - # versioning mechanism, adjust this. - if test -x /usr/bin/objformat; then - objformat=`/usr/bin/objformat` - else - case $host_os in - freebsd[[23]].*) objformat=aout ;; - *) objformat=elf ;; - esac - fi - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2.*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[[01]]* | freebsdelf3.[[01]]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ - freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - *) # from 4.6 on, and DragonFly - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - esac - ;; - -haiku*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - dynamic_linker="$host_os runtime_loader" - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LIBRARY_PATH - shlibpath_overrides_runpath=no - sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case $host_cpu in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - if test 32 = "$HPUX_IA64_MODE"; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - sys_lib_dlsearch_path_spec=/usr/lib/hpux32 - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - sys_lib_dlsearch_path_spec=/usr/lib/hpux64 - fi - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555, ... - postinstall_cmds='chmod 555 $lib' - # or fails outright, so override atomically: - install_override_mode=555 - ;; - -interix[[3-9]]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test yes = "$lt_cv_prog_gnu_ld"; then - version_type=linux # correct to gnu/linux during the next big refactor - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='$libname$release$shared_ext$major' - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" - sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -linux*android*) - version_type=none # Android doesn't support versioned libraries. - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext' - soname_spec='$libname$release$shared_ext' - finish_cmds= - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - dynamic_linker='Android linker' - # Don't embed -rpath directories since the linker doesn't support them. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - ;; - -# This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - - # Some binutils ld are patched to set DT_RUNPATH - AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], - [lt_cv_shlibpath_overrides_runpath=no - save_LDFLAGS=$LDFLAGS - save_libdir=$libdir - eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ - LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" - AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], - [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], - [lt_cv_shlibpath_overrides_runpath=yes])]) - LDFLAGS=$save_LDFLAGS - libdir=$save_libdir - ]) - shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath - - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Ideally, we could use ldconfig to report *all* directores which are - # searched for libraries, however this is still not possible. Aside from not - # being certain /sbin/ldconfig is available, command - # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, - # even though it is searched at run-time. Try to do the best guess by - # appending ld.so.conf contents (and includes) to the search path. - if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsdelf*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='NetBSD ld.elf_so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -*nto* | *qnx*) - version_type=qnx - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='ldqnx.so' - ;; - -openbsd* | bitrig*) - version_type=sunos - sys_lib_dlsearch_path_spec=/usr/lib - need_lib_prefix=no - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then - need_version=no - else - need_version=yes - fi - library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -os2*) - libname_spec='$name' - version_type=windows - shrext_cmds=.dll - need_version=no - need_lib_prefix=no - # OS/2 can only load a DLL with a base name of 8 characters or less. - soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; - v=$($ECHO $release$versuffix | tr -d .-); - n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); - $ECHO $n$v`$shared_ext' - library_names_spec='${libname}_dll.$libext' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=BEGINLIBPATH - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - postinstall_cmds='base_file=`basename \$file`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='$libname$release$shared_ext$major' - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - -rdos*) - dynamic_linker=no - ;; - -solaris*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test yes = "$with_gnu_ld"; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.3*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec; then - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' - soname_spec='$libname$shared_ext.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - version_type=sco - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - if test yes = "$with_gnu_ld"; then - sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' - else - sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' - case $host_os in - sco3.2v5*) - sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" - ;; - esac - fi - sys_lib_dlsearch_path_spec='/usr/lib' - ;; - -tpf*) - # TPF is a cross-target only. Preferred cross-host = GNU/Linux. - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -uts4*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -AC_MSG_RESULT([$dynamic_linker]) -test no = "$dynamic_linker" && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test yes = "$GCC"; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then - sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec -fi - -if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then - sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec -fi - -# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... -configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec - -# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code -func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" - -# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool -configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH - -_LT_DECL([], [variables_saved_for_relink], [1], - [Variables whose values should be saved in libtool wrapper scripts and - restored at link time]) -_LT_DECL([], [need_lib_prefix], [0], - [Do we need the "lib" prefix for modules?]) -_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) -_LT_DECL([], [version_type], [0], [Library versioning type]) -_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) -_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) -_LT_DECL([], [shlibpath_overrides_runpath], [0], - [Is shlibpath searched before the hard-coded library search path?]) -_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) -_LT_DECL([], [library_names_spec], [1], - [[List of archive names. First name is the real one, the rest are links. - The last name is the one that the linker finds with -lNAME]]) -_LT_DECL([], [soname_spec], [1], - [[The coded name of the library, if different from the real name]]) -_LT_DECL([], [install_override_mode], [1], - [Permission mode override for installation of shared libraries]) -_LT_DECL([], [postinstall_cmds], [2], - [Command to use after installation of a shared archive]) -_LT_DECL([], [postuninstall_cmds], [2], - [Command to use after uninstallation of a shared archive]) -_LT_DECL([], [finish_cmds], [2], - [Commands used to finish a libtool library installation in a directory]) -_LT_DECL([], [finish_eval], [1], - [[As "finish_cmds", except a single script fragment to be evaled but - not shown]]) -_LT_DECL([], [hardcode_into_libs], [0], - [Whether we should hardcode library paths into libraries]) -_LT_DECL([], [sys_lib_search_path_spec], [2], - [Compile-time system search path for libraries]) -_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], - [Detected run-time system search path for libraries]) -_LT_DECL([], [configure_time_lt_sys_library_path], [2], - [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) -])# _LT_SYS_DYNAMIC_LINKER - - -# _LT_PATH_TOOL_PREFIX(TOOL) -# -------------------------- -# find a file program that can recognize shared library -AC_DEFUN([_LT_PATH_TOOL_PREFIX], -[m4_require([_LT_DECL_EGREP])dnl -AC_MSG_CHECKING([for $1]) -AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, -[case $MAGIC_CMD in -[[\\/*] | ?:[\\/]*]) - lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD=$MAGIC_CMD - lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR -dnl $ac_dummy forces splitting on constant user-supplied paths. -dnl POSIX.2 word splitting is done only on the output of word expansions, -dnl not every word. This closes a longstanding sh security hole. - ac_dummy="m4_if([$2], , $PATH, [$2])" - for ac_dir in $ac_dummy; do - IFS=$lt_save_ifs - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$1"; then - lt_cv_path_MAGIC_CMD=$ac_dir/"$1" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD=$lt_cv_path_MAGIC_CMD - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<_LT_EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -_LT_EOF - fi ;; - esac - fi - break - fi - done - IFS=$lt_save_ifs - MAGIC_CMD=$lt_save_MAGIC_CMD - ;; -esac]) -MAGIC_CMD=$lt_cv_path_MAGIC_CMD -if test -n "$MAGIC_CMD"; then - AC_MSG_RESULT($MAGIC_CMD) -else - AC_MSG_RESULT(no) -fi -_LT_DECL([], [MAGIC_CMD], [0], - [Used to examine libraries when file_magic_cmd begins with "file"])dnl -])# _LT_PATH_TOOL_PREFIX - -# Old name: -AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) - - -# _LT_PATH_MAGIC -# -------------- -# find a file program that can recognize a shared library -m4_defun([_LT_PATH_MAGIC], -[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) -if test -z "$lt_cv_path_MAGIC_CMD"; then - if test -n "$ac_tool_prefix"; then - _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) - else - MAGIC_CMD=: - fi -fi -])# _LT_PATH_MAGIC - - -# LT_PATH_LD -# ---------- -# find the pathname to the GNU or non-GNU linker -AC_DEFUN([LT_PATH_LD], -[AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_PROG_ECHO_BACKSLASH])dnl - -AC_ARG_WITH([gnu-ld], - [AS_HELP_STRING([--with-gnu-ld], - [assume the C compiler uses GNU ld @<:@default=no@:>@])], - [test no = "$withval" || with_gnu_ld=yes], - [with_gnu_ld=no])dnl - -ac_prog=ld -if test yes = "$GCC"; then - # Check if gcc -print-prog-name=ld gives a path. - AC_MSG_CHECKING([for ld used by $CC]) - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return, which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [[\\/]]* | ?:[[\\/]]*) - re_direlt='/[[^/]][[^/]]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` - while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do - ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` - done - test -z "$LD" && LD=$ac_prog - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test yes = "$with_gnu_ld"; then - AC_MSG_CHECKING([for GNU ld]) -else - AC_MSG_CHECKING([for non-GNU ld]) -fi -AC_CACHE_VAL(lt_cv_path_LD, -[if test -z "$LD"; then - lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS=$lt_save_ifs - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD=$ac_dir/$ac_prog - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 &1 conftest.i -cat conftest.i conftest.i >conftest2.i -: ${lt_DD:=$DD} -AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], -[if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then - cmp -s conftest.i conftest.out \ - && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: -fi]) -rm -f conftest.i conftest2.i conftest.out]) -])# _LT_PATH_DD - - -# _LT_CMD_TRUNCATE -# ---------------- -# find command to truncate a binary pipe -m4_defun([_LT_CMD_TRUNCATE], -[m4_require([_LT_PATH_DD]) -AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], -[printf 0123456789abcdef0123456789abcdef >conftest.i -cat conftest.i conftest.i >conftest2.i -lt_cv_truncate_bin= -if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then - cmp -s conftest.i conftest.out \ - && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" -fi -rm -f conftest.i conftest2.i conftest.out -test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) -_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], - [Command to truncate a binary pipe]) -])# _LT_CMD_TRUNCATE - - -# _LT_CHECK_MAGIC_METHOD -# ---------------------- -# how to check for library dependencies -# -- PORTME fill in with the dynamic library characteristics -m4_defun([_LT_CHECK_MAGIC_METHOD], -[m4_require([_LT_DECL_EGREP]) -m4_require([_LT_DECL_OBJDUMP]) -AC_CACHE_CHECK([how to recognize dependent libraries], -lt_cv_deplibs_check_method, -[lt_cv_file_magic_cmd='$MAGIC_CMD' -lt_cv_file_magic_test_file= -lt_cv_deplibs_check_method='unknown' -# Need to set the preceding variable on all platforms that support -# interlibrary dependencies. -# 'none' -- dependencies not supported. -# 'unknown' -- same as none, but documents that we really don't know. -# 'pass_all' -- all dependencies passed with no checks. -# 'test_compile' -- check by making test program. -# 'file_magic [[regex]]' -- check by looking for files in library path -# that responds to the $file_magic_cmd with a given extended regex. -# If you have 'file' or equivalent on your system and you're not sure -# whether 'pass_all' will *always* work, you probably want this one. - -case $host_os in -aix[[4-9]]*) - lt_cv_deplibs_check_method=pass_all - ;; - -beos*) - lt_cv_deplibs_check_method=pass_all - ;; - -bsdi[[45]]*) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' - lt_cv_file_magic_cmd='/usr/bin/file -L' - lt_cv_file_magic_test_file=/shlib/libc.so - ;; - -cygwin*) - # func_win32_libid is a shell function defined in ltmain.sh - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - ;; - -mingw* | pw32*) - # Base MSYS/MinGW do not provide the 'file' command needed by - # func_win32_libid shell function, so use a weaker test based on 'objdump', - # unless we find 'file', for example because we are cross-compiling. - if ( file / ) >/dev/null 2>&1; then - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - else - # Keep this pattern in sync with the one in func_win32_libid. - lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' - lt_cv_file_magic_cmd='$OBJDUMP -f' - fi - ;; - -cegcc*) - # use the weaker test based on 'objdump'. See mingw*. - lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - ;; - -darwin* | rhapsody*) - lt_cv_deplibs_check_method=pass_all - ;; - -freebsd* | dragonfly*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - case $host_cpu in - i*86 ) - # Not sure whether the presence of OpenBSD here was a mistake. - # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - ;; - esac - else - lt_cv_deplibs_check_method=pass_all - fi - ;; - -haiku*) - lt_cv_deplibs_check_method=pass_all - ;; - -hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file - case $host_cpu in - ia64*) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' - lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so - ;; - hppa*64*) - [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] - lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl - ;; - *) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' - lt_cv_file_magic_test_file=/usr/lib/libc.sl - ;; - esac - ;; - -interix[[3-9]]*) - # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' - ;; - -irix5* | irix6* | nonstopux*) - case $LD in - *-32|*"-32 ") libmagic=32-bit;; - *-n32|*"-n32 ") libmagic=N32;; - *-64|*"-64 ") libmagic=64-bit;; - *) libmagic=never-match;; - esac - lt_cv_deplibs_check_method=pass_all - ;; - -# This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - -netbsd* | netbsdelf*-gnu) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' - fi - ;; - -newos6*) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libnls.so - ;; - -*nto* | *qnx*) - lt_cv_deplibs_check_method=pass_all - ;; - -openbsd* | bitrig*) - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' - fi - ;; - -osf3* | osf4* | osf5*) - lt_cv_deplibs_check_method=pass_all - ;; - -rdos*) - lt_cv_deplibs_check_method=pass_all - ;; - -solaris*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv4 | sysv4.3*) - case $host_vendor in - motorola) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - ncr) - lt_cv_deplibs_check_method=pass_all - ;; - sequent) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' - ;; - sni) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" - lt_cv_file_magic_test_file=/lib/libc.so - ;; - siemens) - lt_cv_deplibs_check_method=pass_all - ;; - pc) - lt_cv_deplibs_check_method=pass_all - ;; - esac - ;; - -tpf*) - lt_cv_deplibs_check_method=pass_all - ;; -os2*) - lt_cv_deplibs_check_method=pass_all - ;; -esac -]) - -file_magic_glob= -want_nocaseglob=no -if test "$build" = "$host"; then - case $host_os in - mingw* | pw32*) - if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then - want_nocaseglob=yes - else - file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` - fi - ;; - esac -fi - -file_magic_cmd=$lt_cv_file_magic_cmd -deplibs_check_method=$lt_cv_deplibs_check_method -test -z "$deplibs_check_method" && deplibs_check_method=unknown - -_LT_DECL([], [deplibs_check_method], [1], - [Method to check whether dependent libraries are shared objects]) -_LT_DECL([], [file_magic_cmd], [1], - [Command to use when deplibs_check_method = "file_magic"]) -_LT_DECL([], [file_magic_glob], [1], - [How to find potential files when deplibs_check_method = "file_magic"]) -_LT_DECL([], [want_nocaseglob], [1], - [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) -])# _LT_CHECK_MAGIC_METHOD - - -# LT_PATH_NM -# ---------- -# find the pathname to a BSD- or MS-compatible name lister -AC_DEFUN([LT_PATH_NM], -[AC_REQUIRE([AC_PROG_CC])dnl -AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, -[if test -n "$NM"; then - # Let the user override the test. - lt_cv_path_NM=$NM -else - lt_nm_to_check=${ac_tool_prefix}nm - if test -n "$ac_tool_prefix" && test "$build" = "$host"; then - lt_nm_to_check="$lt_nm_to_check nm" - fi - for lt_tmp_nm in $lt_nm_to_check; do - lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do - IFS=$lt_save_ifs - test -z "$ac_dir" && ac_dir=. - tmp_nm=$ac_dir/$lt_tmp_nm - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the 'sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty - case $build_os in - mingw*) lt_bad_file=conftest.nm/nofile ;; - *) lt_bad_file=/dev/null ;; - esac - case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in - *$lt_bad_file* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break 2 - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" - break 2 - ;; - *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - ;; - esac - ;; - esac - fi - done - IFS=$lt_save_ifs - done - : ${lt_cv_path_NM=no} -fi]) -if test no != "$lt_cv_path_NM"; then - NM=$lt_cv_path_NM -else - # Didn't find any BSD compatible name lister, look for dumpbin. - if test -n "$DUMPBIN"; then : - # Let the user override the test. - else - AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) - case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in - *COFF*) - DUMPBIN="$DUMPBIN -symbols -headers" - ;; - *) - DUMPBIN=: - ;; - esac - fi - AC_SUBST([DUMPBIN]) - if test : != "$DUMPBIN"; then - NM=$DUMPBIN - fi -fi -test -z "$NM" && NM=nm -AC_SUBST([NM]) -_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl - -AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], - [lt_cv_nm_interface="BSD nm" - echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$ac_compile" 2>conftest.err) - cat conftest.err >&AS_MESSAGE_LOG_FD - (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) - (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) - cat conftest.err >&AS_MESSAGE_LOG_FD - (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) - cat conftest.out >&AS_MESSAGE_LOG_FD - if $GREP 'External.*some_variable' conftest.out > /dev/null; then - lt_cv_nm_interface="MS dumpbin" - fi - rm -f conftest*]) -])# LT_PATH_NM - -# Old names: -AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) -AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_PROG_NM], []) -dnl AC_DEFUN([AC_PROG_NM], []) - -# _LT_CHECK_SHAREDLIB_FROM_LINKLIB -# -------------------------------- -# how to determine the name of the shared library -# associated with a specific link library. -# -- PORTME fill in with the dynamic library characteristics -m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], -[m4_require([_LT_DECL_EGREP]) -m4_require([_LT_DECL_OBJDUMP]) -m4_require([_LT_DECL_DLLTOOL]) -AC_CACHE_CHECK([how to associate runtime and link libraries], -lt_cv_sharedlib_from_linklib_cmd, -[lt_cv_sharedlib_from_linklib_cmd='unknown' - -case $host_os in -cygwin* | mingw* | pw32* | cegcc*) - # two different shell functions defined in ltmain.sh; - # decide which one to use based on capabilities of $DLLTOOL - case `$DLLTOOL --help 2>&1` in - *--identify-strict*) - lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib - ;; - *) - lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback - ;; - esac - ;; -*) - # fallback: assume linklib IS sharedlib - lt_cv_sharedlib_from_linklib_cmd=$ECHO - ;; -esac -]) -sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd -test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO - -_LT_DECL([], [sharedlib_from_linklib_cmd], [1], - [Command to associate shared and link libraries]) -])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB - - -# _LT_PATH_MANIFEST_TOOL -# ---------------------- -# locate the manifest tool -m4_defun([_LT_PATH_MANIFEST_TOOL], -[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) -test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt -AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], - [lt_cv_path_mainfest_tool=no - echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD - $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out - cat conftest.err >&AS_MESSAGE_LOG_FD - if $GREP 'Manifest Tool' conftest.out > /dev/null; then - lt_cv_path_mainfest_tool=yes - fi - rm -f conftest*]) -if test yes != "$lt_cv_path_mainfest_tool"; then - MANIFEST_TOOL=: -fi -_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl -])# _LT_PATH_MANIFEST_TOOL - - -# _LT_DLL_DEF_P([FILE]) -# --------------------- -# True iff FILE is a Windows DLL '.def' file. -# Keep in sync with func_dll_def_p in the libtool script -AC_DEFUN([_LT_DLL_DEF_P], -[dnl - test DEF = "`$SED -n dnl - -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace - -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments - -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl - -e q dnl Only consider the first "real" line - $1`" dnl -])# _LT_DLL_DEF_P - - -# LT_LIB_M -# -------- -# check for math library -AC_DEFUN([LT_LIB_M], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -LIBM= -case $host in -*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) - # These system don't have libm, or don't need it - ;; -*-ncr-sysv4.3*) - AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) - AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") - ;; -*) - AC_CHECK_LIB(m, cos, LIBM=-lm) - ;; -esac -AC_SUBST([LIBM]) -])# LT_LIB_M - -# Old name: -AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_CHECK_LIBM], []) - - -# _LT_COMPILER_NO_RTTI([TAGNAME]) -# ------------------------------- -m4_defun([_LT_COMPILER_NO_RTTI], -[m4_require([_LT_TAG_COMPILER])dnl - -_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= - -if test yes = "$GCC"; then - case $cc_basename in - nvcc*) - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; - *) - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; - esac - - _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], - lt_cv_prog_compiler_rtti_exceptions, - [-fno-rtti -fno-exceptions], [], - [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) -fi -_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], - [Compiler flag to turn off builtin functions]) -])# _LT_COMPILER_NO_RTTI - - -# _LT_CMD_GLOBAL_SYMBOLS -# ---------------------- -m4_defun([_LT_CMD_GLOBAL_SYMBOLS], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_PROG_AWK])dnl -AC_REQUIRE([LT_PATH_NM])dnl -AC_REQUIRE([LT_PATH_LD])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_TAG_COMPILER])dnl - -# Check for command to grab the raw symbol name followed by C symbol from nm. -AC_MSG_CHECKING([command to parse $NM output from $compiler object]) -AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], -[ -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[[BCDEGRST]]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' - -# Define system-specific variables. -case $host_os in -aix*) - symcode='[[BCDT]]' - ;; -cygwin* | mingw* | pw32* | cegcc*) - symcode='[[ABCDGISTW]]' - ;; -hpux*) - if test ia64 = "$host_cpu"; then - symcode='[[ABCDEGRST]]' - fi - ;; -irix* | nonstopux*) - symcode='[[BCDEGRST]]' - ;; -osf*) - symcode='[[BCDEGQRST]]' - ;; -solaris*) - symcode='[[BDRT]]' - ;; -sco3.2v5*) - symcode='[[DT]]' - ;; -sysv4.2uw2*) - symcode='[[DT]]' - ;; -sysv5* | sco5v6* | unixware* | OpenUNIX*) - symcode='[[ABDT]]' - ;; -sysv4) - symcode='[[DFNSTU]]' - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -case `$NM -V 2>&1` in -*GNU* | *'with BFD'*) - symcode='[[ABCDGIRSTW]]' ;; -esac - -if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Gets list of data symbols to import. - lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" - # Adjust the below global symbol transforms to fixup imported variables. - lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" - lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" - lt_c_name_lib_hook="\ - -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ - -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" -else - # Disable hooks by default. - lt_cv_sys_global_symbol_to_import= - lt_cdecl_hook= - lt_c_name_hook= - lt_c_name_lib_hook= -fi - -# Transform an extracted symbol line into a proper C declaration. -# Some systems (esp. on ia64) link data and code symbols differently, -# so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n"\ -$lt_cdecl_hook\ -" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ -" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" - -# Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ -$lt_c_name_hook\ -" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ -" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" - -# Transform an extracted symbol line into symbol name with lib prefix and -# symbol address. -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ -$lt_c_name_lib_hook\ -" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ -" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ -" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" - -# Handle CRLF in mingw tool chain -opt_cr= -case $build_os in -mingw*) - opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp - ;; -esac - -# Try without a prefix underscore, then with it. -for ac_symprfx in "" "_"; do - - # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. - symxfrm="\\1 $ac_symprfx\\2 \\2" - - # Write the raw and C identifiers. - if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Fake it for dumpbin and say T for any non-static function, - # D for any global variable and I for any imported variable. - # Also find C++ and __fastcall symbols from MSVC++, - # which start with @ or ?. - lt_cv_sys_global_symbol_pipe="$AWK ['"\ -" {last_section=section; section=\$ 3};"\ -" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ -" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ -" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ -" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ -" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ -" \$ 0!~/External *\|/{next};"\ -" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ -" {if(hide[section]) next};"\ -" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ -" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ -" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ -" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ -" ' prfx=^$ac_symprfx]" - else - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" - fi - lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" - - # Check to see that the pipe works correctly. - pipe_works=no - - rm -f conftest* - cat > conftest.$ac_ext <<_LT_EOF -#ifdef __cplusplus -extern "C" { -#endif -char nm_test_var; -void nm_test_func(void); -void nm_test_func(void){} -#ifdef __cplusplus -} -#endif -int main(){nm_test_var='a';nm_test_func();return(0);} -_LT_EOF - - if AC_TRY_EVAL(ac_compile); then - # Now try to grab the symbols. - nlist=conftest.nm - $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD - if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if $GREP ' nm_test_var$' "$nlist" >/dev/null; then - if $GREP ' nm_test_func$' "$nlist" >/dev/null; then - cat <<_LT_EOF > conftest.$ac_ext -/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE -/* DATA imports from DLLs on WIN32 can't be const, because runtime - relocations are performed -- see ld's documentation on pseudo-relocs. */ -# define LT@&t@_DLSYM_CONST -#elif defined __osf__ -/* This system does not cope well with relocations in const data. */ -# define LT@&t@_DLSYM_CONST -#else -# define LT@&t@_DLSYM_CONST const -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -_LT_EOF - # Now generate the symbol file. - eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' - - cat <<_LT_EOF >> conftest.$ac_ext - -/* The mapping between symbol names and symbols. */ -LT@&t@_DLSYM_CONST struct { - const char *name; - void *address; -} -lt__PROGRAM__LTX_preloaded_symbols[[]] = -{ - { "@PROGRAM@", (void *) 0 }, -_LT_EOF - $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext - cat <<\_LT_EOF >> conftest.$ac_ext - {0, (void *) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt__PROGRAM__LTX_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif -_LT_EOF - # Now try linking the two files. - mv conftest.$ac_objext conftstm.$ac_objext - lt_globsym_save_LIBS=$LIBS - lt_globsym_save_CFLAGS=$CFLAGS - LIBS=conftstm.$ac_objext - CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" - if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then - pipe_works=yes - fi - LIBS=$lt_globsym_save_LIBS - CFLAGS=$lt_globsym_save_CFLAGS - else - echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD - fi - else - echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD - cat conftest.$ac_ext >&5 - fi - rm -rf conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test yes = "$pipe_works"; then - break - else - lt_cv_sys_global_symbol_pipe= - fi -done -]) -if test -z "$lt_cv_sys_global_symbol_pipe"; then - lt_cv_sys_global_symbol_to_cdecl= -fi -if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then - AC_MSG_RESULT(failed) -else - AC_MSG_RESULT(ok) -fi - -# Response file support. -if test "$lt_cv_nm_interface" = "MS dumpbin"; then - nm_file_list_spec='@' -elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then - nm_file_list_spec='@' -fi - -_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], - [Take the output of nm and produce a listing of raw symbols and C names]) -_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], - [Transform the output of nm in a proper C declaration]) -_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], - [Transform the output of nm into a list of symbols to manually relocate]) -_LT_DECL([global_symbol_to_c_name_address], - [lt_cv_sys_global_symbol_to_c_name_address], [1], - [Transform the output of nm in a C name address pair]) -_LT_DECL([global_symbol_to_c_name_address_lib_prefix], - [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], - [Transform the output of nm in a C name address pair when lib prefix is needed]) -_LT_DECL([nm_interface], [lt_cv_nm_interface], [1], - [The name lister interface]) -_LT_DECL([], [nm_file_list_spec], [1], - [Specify filename containing input files for $NM]) -]) # _LT_CMD_GLOBAL_SYMBOLS - - -# _LT_COMPILER_PIC([TAGNAME]) -# --------------------------- -m4_defun([_LT_COMPILER_PIC], -[m4_require([_LT_TAG_COMPILER])dnl -_LT_TAGVAR(lt_prog_compiler_wl, $1)= -_LT_TAGVAR(lt_prog_compiler_pic, $1)= -_LT_TAGVAR(lt_prog_compiler_static, $1)= - -m4_if([$1], [CXX], [ - # C++ specific cases for pic, static, wl, etc. - if test yes = "$GXX"; then - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test ia64 = "$host_cpu"; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the '-m68020' flag to GCC prevents building anything better, - # like '-m68040'. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - case $host_os in - os2*) - _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' - ;; - esac - ;; - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - *djgpp*) - # DJGPP does not support shared libraries at all - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - haiku*) - # PIC is the default for Haiku. - # The "-static" flag exists, but is broken. - _LT_TAGVAR(lt_prog_compiler_static, $1)= - ;; - interix[[3-9]]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - else - case $host_os in - aix[[4-9]]*) - # All AIX code is PIC. - if test ia64 = "$host_cpu"; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - chorus*) - case $cc_basename in - cxch68*) - # Green Hills C++ Compiler - # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" - ;; - esac - ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - dgux*) - case $cc_basename in - ec++*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - ghcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - freebsd* | dragonfly*) - # FreeBSD uses GNU C++ - ;; - hpux9* | hpux10* | hpux11*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' - if test ia64 != "$host_cpu"; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - fi - ;; - aCC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - ;; - *) - ;; - esac - ;; - interix*) - # This is c89, which is MS Visual C++ (no shared libs) - # Anyone wants to do a port? - ;; - irix5* | irix6* | nonstopux*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - # CC pic flag -KPIC is the default. - ;; - *) - ;; - esac - ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - case $cc_basename in - KCC*) - # KAI C++ Compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - ecpc* ) - # old Intel C++ for x86_64, which still supported -KPIC. - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - icpc* ) - # Intel C++, used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - pgCC* | pgcpp*) - # Portland Group C++ compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - cxx*) - # Compaq C++ - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) - # IBM XL 8.0, 9.0 on PPC and BlueGene - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - esac - ;; - esac - ;; - lynxos*) - ;; - m88k*) - ;; - mvs*) - case $cc_basename in - cxx*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' - ;; - *) - ;; - esac - ;; - netbsd* | netbsdelf*-gnu) - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - ;; - RCC*) - # Rational C++ 2.4.1 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - cxx*) - # Digital/Compaq C++ - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - *) - ;; - esac - ;; - psos*) - ;; - solaris*) - case $cc_basename in - CC* | sunCC*) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - gcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - ;; - *) - ;; - esac - ;; - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - lcc*) - # Lucid - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - esac - ;; - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - *) - ;; - esac - ;; - vxworks*) - ;; - *) - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -], -[ - if test yes = "$GCC"; then - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test ia64 = "$host_cpu"; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the '-m68020' flag to GCC prevents building anything better, - # like '-m68040'. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - case $host_os in - os2*) - _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' - ;; - esac - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - - haiku*) - # PIC is the default for Haiku. - # The "-static" flag exists, but is broken. - _LT_TAGVAR(lt_prog_compiler_static, $1)= - ;; - - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - - interix[[3-9]]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - enable_shared=no - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - - case $cc_basename in - nvcc*) # Cuda Compiler Driver 2.2 - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' - if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" - fi - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - if test ia64 = "$host_cpu"; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - case $cc_basename in - nagfor*) - # NAG Fortran compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - esac - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - case $host_os in - os2*) - _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' - ;; - esac - ;; - - hpux9* | hpux10* | hpux11*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC (with -KPIC) is the default. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - case $cc_basename in - # old Intel for x86_64, which still supported -KPIC. - ecc*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - # flang / f18. f95 an alias for gfortran or flang on Debian - flang* | f18* | f95*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - # icc used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - icc* | ifort*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - # Lahey Fortran 8.1. - lf95*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' - _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' - ;; - nagfor*) - # NAG Fortran compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - tcc*) - # Fabrice Bellard et al's Tiny C Compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) - # Portland Group compilers (*not* the Pentium gcc compiler, - # which looks to be a dead project) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - ccc*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All Alpha code is PIC. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - xl* | bgxl* | bgf* | mpixl*) - # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) - # Sun Fortran 8.3 passes all unrecognized flags to the linker - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='' - ;; - *Sun\ F* | *Sun*Fortran*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - *Sun\ C*) - # Sun C 5.9 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - ;; - *Intel*\ [[CF]]*Compiler*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - *Portland\ Group*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - esac - ;; - esac - ;; - - newsos6) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - - osf3* | osf4* | osf5*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All OSF/1 code is PIC. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - rdos*) - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - solaris*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - case $cc_basename in - f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; - *) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; - esac - ;; - - sunos4*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - unicos*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - - uts4*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - *) - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -]) -case $host_os in - # For platforms that do not support PIC, -DPIC is meaningless: - *djgpp*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" - ;; -esac - -AC_CACHE_CHECK([for $compiler option to produce PIC], - [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], - [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) -_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then - _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], - [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], - [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], - [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in - "" | " "*) ;; - *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; - esac], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) -fi -_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], - [Additional compiler flags for building library objects]) - -_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], - [How to pass a linker flag through the compiler]) -# -# Check to make sure the static flag actually works. -# -wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" -_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], - _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), - $lt_tmp_static_flag, - [], - [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) -_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], - [Compiler flag to prevent dynamic linking]) -])# _LT_COMPILER_PIC - - -# _LT_LINKER_SHLIBS([TAGNAME]) -# ---------------------------- -# See if the linker supports building shared libraries. -m4_defun([_LT_LINKER_SHLIBS], -[AC_REQUIRE([LT_PATH_LD])dnl -AC_REQUIRE([LT_PATH_NM])dnl -m4_require([_LT_PATH_MANIFEST_TOOL])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl -m4_require([_LT_TAG_COMPILER])dnl -AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) -m4_if([$1], [CXX], [ - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] - case $host_os in - aix[[4-9]]*) - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to GNU nm, but means don't demangle to AIX nm. - # Without the "-l" option, or with the "-B" option, AIX nm treats - # weak defined symbols like other global defined symbols, whereas - # GNU nm marks them as "W". - # While the 'weak' keyword is ignored in the Export File, we need - # it in the Import File for the 'aix-soname' feature, so we have - # to replace the "-B" option with "-P" for AIX nm. - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' - else - _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' - fi - ;; - pw32*) - _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds - ;; - cygwin* | mingw* | cegcc*) - case $cc_basename in - cl*) - _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' - ;; - *) - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] - ;; - esac - ;; - linux* | k*bsd*-gnu | gnu*) - _LT_TAGVAR(link_all_deplibs, $1)=no - ;; - *) - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - ;; - esac -], [ - runpath_var= - _LT_TAGVAR(allow_undefined_flag, $1)= - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(archive_cmds, $1)= - _LT_TAGVAR(archive_expsym_cmds, $1)= - _LT_TAGVAR(compiler_needs_object, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - _LT_TAGVAR(export_dynamic_flag_spec, $1)= - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(hardcode_automatic, $1)=no - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(hardcode_libdir_separator, $1)= - _LT_TAGVAR(hardcode_minus_L, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_TAGVAR(inherit_rpath, $1)=no - _LT_TAGVAR(link_all_deplibs, $1)=unknown - _LT_TAGVAR(module_cmds, $1)= - _LT_TAGVAR(module_expsym_cmds, $1)= - _LT_TAGVAR(old_archive_from_new_cmds, $1)= - _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= - _LT_TAGVAR(thread_safe_flag_spec, $1)= - _LT_TAGVAR(whole_archive_flag_spec, $1)= - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - _LT_TAGVAR(include_expsyms, $1)= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ' (' and ')$', so one must not match beginning or - # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', - # as well as any symbol that contains 'd'. - _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - # Exclude shared library initialization/finalization symbols. -dnl Note also adjust exclude_expsyms for C++ above. - extract_expsyms_cmds= - - case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test yes != "$GCC"; then - with_gnu_ld=no - fi - ;; - interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) - with_gnu_ld=yes - ;; - openbsd* | bitrig*) - with_gnu_ld=no - ;; - linux* | k*bsd*-gnu | gnu*) - _LT_TAGVAR(link_all_deplibs, $1)=no - ;; - esac - - _LT_TAGVAR(ld_shlibs, $1)=yes - - # On some targets, GNU ld is compatible enough with the native linker - # that we're better off using the native interface for both. - lt_use_gnu_ld_interface=no - if test yes = "$with_gnu_ld"; then - case $host_os in - aix*) - # The AIX port of GNU ld has always aspired to compatibility - # with the native linker. However, as the warning in the GNU ld - # block says, versions before 2.19.5* couldn't really create working - # shared libraries, regardless of the interface used. - case `$LD -v 2>&1` in - *\ \(GNU\ Binutils\)\ 2.19.5*) ;; - *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; - *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; - *) - lt_use_gnu_ld_interface=yes - ;; - esac - ;; - *) - lt_use_gnu_ld_interface=yes - ;; - esac - fi - - if test yes = "$lt_use_gnu_ld_interface"; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='$wl' - - # Set some defaults for GNU ld with shared library support. These - # are reset later if shared libraries are not supported. Putting them - # here allows them to be overridden if necessary. - runpath_var=LD_RUN_PATH - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - supports_anon_versioning=no - case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in - *GNU\ gold*) supports_anon_versioning=yes ;; - *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - - # See if GNU ld supports shared libraries. - case $host_os in - aix[[3-9]]*) - # On AIX/PPC, the GNU linker is very broken - if test ia64 != "$host_cpu"; then - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: the GNU linker, at least up to release 2.19, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to install binutils -*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. -*** You will then need to restart the configuration process. - -_LT_EOF - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='' - ;; - m68k) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file, use it as - # is; otherwise, prepend EXPORTS... - _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - haiku*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - os2*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - shrext_cmds=.dll - _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ - $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ - $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ - $ECHO EXPORTS >> $output_objdir/$libname.def~ - emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ - $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ - emximp -o $lib $output_objdir/$libname.def' - _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ - $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ - $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ - $ECHO EXPORTS >> $output_objdir/$libname.def~ - prefix_cmds="$SED"~ - if test EXPORTS = "`$SED 1q $export_symbols`"; then - prefix_cmds="$prefix_cmds -e 1d"; - fi~ - prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ - cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ - $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ - emximp -o $lib $output_objdir/$libname.def' - _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - ;; - - interix[[3-9]]*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - - gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) - tmp_diet=no - if test linux-dietlibc = "$host_os"; then - case $cc_basename in - diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) - esac - fi - if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ - && test no = "$tmp_diet" - then - tmp_addflag=' $pic_flag' - tmp_sharedflag='-shared' - case $cc_basename,$host_cpu in - pgcc*) # Portland Group C compiler - _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' - tmp_addflag=' $pic_flag' - ;; - pgf77* | pgf90* | pgf95* | pgfortran*) - # Portland Group f77 and f90 compilers - _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' - tmp_addflag=' $pic_flag -Mnomain' ;; - ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 - tmp_addflag=' -i_dynamic' ;; - efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 - tmp_addflag=' -i_dynamic -nofor_main' ;; - ifc* | ifort*) # Intel Fortran compiler - tmp_addflag=' -nofor_main' ;; - lf95*) # Lahey Fortran 8.1 - _LT_TAGVAR(whole_archive_flag_spec, $1)= - tmp_sharedflag='--shared' ;; - nagfor*) # NAGFOR 5.3 - tmp_sharedflag='-Wl,-shared' ;; - xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) - tmp_sharedflag='-qmkshrobj' - tmp_addflag= ;; - nvcc*) # Cuda Compiler Driver 2.2 - _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - ;; - esac - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) # Sun C 5.9 - _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - tmp_sharedflag='-G' ;; - *Sun\ F*) # Sun Fortran 8.3 - tmp_sharedflag='-G' ;; - esac - _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - - if test yes = "$supports_anon_versioning"; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' - fi - - case $cc_basename in - tcc*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' - ;; - xlf* | bgf* | bgxlf* | mpixlf*) - # IBM XL Fortran 10.1 on PPC cannot create shared libs itself - _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' - _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' - if test yes = "$supports_anon_versioning"; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' - fi - ;; - esac - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - netbsd* | netbsdelf*-gnu) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris*) - if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) - case `$LD -v 2>&1` in - *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot -*** reliably create shared libraries on SCO systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.16.91.0.3 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - ;; - *) - # For security reasons, it is highly recommended that you always - # use absolute paths for naming shared libraries, and exclude the - # DT_RUNPATH tag from executables and libraries. But doing so - # requires that you compile everything twice, which is a pain. - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - sunos4*) - _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - - if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then - runpath_var= - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(export_dynamic_flag_spec, $1)= - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=yes - _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - _LT_TAGVAR(hardcode_direct, $1)=unsupported - fi - ;; - - aix[[4-9]]*) - if test ia64 = "$host_cpu"; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag= - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to GNU nm, but means don't demangle to AIX nm. - # Without the "-l" option, or with the "-B" option, AIX nm treats - # weak defined symbols like other global defined symbols, whereas - # GNU nm marks them as "W". - # While the 'weak' keyword is ignored in the Export File, we need - # it in the Import File for the 'aix-soname' feature, so we have - # to replace the "-B" option with "-P" for AIX nm. - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' - else - _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # have runtime linking enabled, and use it for executables. - # For shared libraries, we enable/disable runtime linking - # depending on the kind of the shared library created - - # when "with_aix_soname,aix_use_runtimelinking" is: - # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables - # "aix,yes" lib.so shared, rtl:yes, for executables - # lib.a static archive - # "both,no" lib.so.V(shr.o) shared, rtl:yes - # lib.a(lib.so.V) shared, rtl:no, for executables - # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables - # lib.a(lib.so.V) shared, rtl:no - # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables - # lib.a static archive - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) - for ld_flag in $LDFLAGS; do - if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then - aix_use_runtimelinking=yes - break - fi - done - if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then - # With aix-soname=svr4, we create the lib.so.V shared archives only, - # so we don't have lib.a shared libs to link our executables. - # We have to force runtime linking in this case. - aix_use_runtimelinking=yes - LDFLAGS="$LDFLAGS -Wl,-brtl" - fi - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_TAGVAR(archive_cmds, $1)='' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='$wl-f,' - case $with_aix_soname,$aix_use_runtimelinking in - aix,*) ;; # traditional, no import file - svr4,* | *,yes) # use import file - # The Import File defines what to hardcode. - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=no - ;; - esac - - if test yes = "$GCC"; then - case $host_os in aix4.[[012]]|aix4.[[012]].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`$CC -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - _LT_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)= - fi - ;; - esac - shared_flag='-shared' - if test yes = "$aix_use_runtimelinking"; then - shared_flag="$shared_flag "'$wl-G' - fi - # Need to ensure runtime linking is disabled for the traditional - # shared library, or the linker may eventually find shared libraries - # /with/ Import File - we do not want to mix them. - shared_flag_aix='-shared' - shared_flag_svr4='-shared $wl-G' - else - # not using gcc - if test ia64 = "$host_cpu"; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test yes = "$aix_use_runtimelinking"; then - shared_flag='$wl-G' - else - shared_flag='$wl-bM:SRE' - fi - shared_flag_aix='$wl-bM:SRE' - shared_flag_svr4='$wl-G' - fi - fi - - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - _LT_TAGVAR(always_export_symbols, $1)=yes - if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(allow_undefined_flag, $1)='-berok' - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag - else - if test ia64 = "$host_cpu"; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' - _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' - if test yes = "$with_gnu_ld"; then - # We only use this code for GNU lds that support --whole-archive. - _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' - else - # Exported symbols can be pulled into shared objects from archives - _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' - # -brtl affects multiple linker settings, -berok does not and is overridden later - compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' - if test svr4 != "$with_aix_soname"; then - # This is similar to how AIX traditionally builds its shared libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' - fi - if test aix != "$with_aix_soname"; then - _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' - else - # used by -dlpreopen to get the symbols - _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' - fi - _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' - fi - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='' - ;; - m68k) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - ;; - - bsdi[[45]]*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - case $cc_basename in - cl*) - # Native MSVC - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='@' - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=.dll - # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' - _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then - cp "$export_symbols" "$output_objdir/$soname.def"; - echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; - else - $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' - # The linker will not automatically build a static lib if we build a DLL. - # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' - # Don't use ranlib - _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' - _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile=$lt_outputfile.exe - lt_tool_outputfile=$lt_tool_outputfile.exe - ;; - esac~ - if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' - ;; - *) - # Assume MSVC wrapper - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=.dll - # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' - # FIXME: Should let the user specify the lib program. - _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - ;; - esac - ;; - - darwin* | rhapsody*) - _LT_DARWIN_LINKER_FEATURES($1) - ;; - - dgux*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2.*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - hpux9*) - if test yes = "$GCC"; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' - else - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_direct, $1)=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' - ;; - - hpux10*) - if test yes,no = "$GCC,$with_gnu_ld"; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - fi - if test no = "$with_gnu_ld"; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - fi - ;; - - hpux11*) - if test yes,no = "$GCC,$with_gnu_ld"; then - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - m4_if($1, [], [ - # Older versions of the 11.00 compiler do not understand -b yet - # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) - _LT_LINKER_OPTION([if $CC understands -b], - _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], - [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], - [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], - [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) - ;; - esac - fi - if test no = "$with_gnu_ld"; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - case $host_cpu in - hppa*64*|ia64*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - *) - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test yes = "$GCC"; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' - # Try to use the -exported_symbol ld option, if it does not - # work, assume that -exports_file does not work either and - # implicitly export all symbols. - # This should be the same for all languages, so no per-tag cache variable. - AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], - [lt_cv_irix_exported_symbol], - [save_LDFLAGS=$LDFLAGS - LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" - AC_LINK_IFELSE( - [AC_LANG_SOURCE( - [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], - [C++], [[int foo (void) { return 0; }]], - [Fortran 77], [[ - subroutine foo - end]], - [Fortran], [[ - subroutine foo - end]])])], - [lt_cv_irix_exported_symbol=yes], - [lt_cv_irix_exported_symbol=no]) - LDFLAGS=$save_LDFLAGS]) - if test yes = "$lt_cv_irix_exported_symbol"; then - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' - fi - _LT_TAGVAR(link_all_deplibs, $1)=no - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(inherit_rpath, $1)=yes - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - linux*) - case $cc_basename in - tcc*) - # Fabrice Bellard et al's Tiny C Compiler - _LT_TAGVAR(ld_shlibs, $1)=yes - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - netbsd* | netbsdelf*-gnu) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - newsos6) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *nto* | *qnx*) - ;; - - openbsd* | bitrig*) - if test -f /usr/libexec/ld.so; then - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' - fi - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - os2*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - shrext_cmds=.dll - _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ - $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ - $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ - $ECHO EXPORTS >> $output_objdir/$libname.def~ - emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ - $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ - emximp -o $lib $output_objdir/$libname.def' - _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ - $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ - $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ - $ECHO EXPORTS >> $output_objdir/$libname.def~ - prefix_cmds="$SED"~ - if test EXPORTS = "`$SED 1q $export_symbols`"; then - prefix_cmds="$prefix_cmds -e 1d"; - fi~ - prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ - cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ - $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ - emximp -o $lib $output_objdir/$libname.def' - _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - ;; - - osf3*) - if test yes = "$GCC"; then - _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' - else - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test yes = "$GCC"; then - _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' - else - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' - - # Both c and cxx compiler support -rpath directly - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - solaris*) - _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' - if test yes = "$GCC"; then - wlarc='$wl' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - else - case `$CC -V 2>&1` in - *"Compilers 5.0"*) - wlarc='' - _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' - ;; - *) - wlarc='$wl' - _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - ;; - esac - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands '-z linker_flag'. GCC discards it without '$wl', - # but is careful enough not to reorder. - # Supported since Solaris 2.6 (maybe 2.5.1?) - if test yes = "$GCC"; then - _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' - fi - ;; - esac - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - sunos4*) - if test sequent = "$host_vendor"; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4) - case $host_vendor in - sni) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' - _LT_TAGVAR(hardcode_direct, $1)=no - ;; - motorola) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4.3*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - _LT_TAGVAR(ld_shlibs, $1)=yes - fi - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var='LD_RUN_PATH' - - if test yes = "$GCC"; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We CANNOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' - runpath_var='LD_RUN_PATH' - - if test yes = "$GCC"; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - uts4*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *) - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - - if test sni = "$host_vendor"; then - case $host in - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' - ;; - esac - fi - fi -]) -AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) -test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no - -_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld - -_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl -_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl -_LT_DECL([], [extract_expsyms_cmds], [2], - [The commands to extract the exported symbol list from a shared archive]) - -# -# Do we need to explicitly link libc? -# -case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in -x|xyes) - # Assume -lc should be added - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - - if test yes,yes = "$GCC,$enable_shared"; then - case $_LT_TAGVAR(archive_cmds, $1) in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - AC_CACHE_CHECK([whether -lc should be explicitly linked in], - [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), - [$RM conftest* - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - if AC_TRY_EVAL(ac_compile) 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) - pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) - _LT_TAGVAR(allow_undefined_flag, $1)= - if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) - then - lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no - else - lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes - fi - _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $RM conftest* - ]) - _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) - ;; - esac - fi - ;; -esac - -_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], - [Whether or not to add -lc for building shared libraries]) -_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], - [enable_shared_with_static_runtimes], [0], - [Whether or not to disallow shared libs when runtime libs are static]) -_LT_TAGDECL([], [export_dynamic_flag_spec], [1], - [Compiler flag to allow reflexive dlopens]) -_LT_TAGDECL([], [whole_archive_flag_spec], [1], - [Compiler flag to generate shared objects directly from archives]) -_LT_TAGDECL([], [compiler_needs_object], [1], - [Whether the compiler copes with passing no objects directly]) -_LT_TAGDECL([], [old_archive_from_new_cmds], [2], - [Create an old-style archive from a shared archive]) -_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], - [Create a temporary old-style archive to link instead of a shared archive]) -_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) -_LT_TAGDECL([], [archive_expsym_cmds], [2]) -_LT_TAGDECL([], [module_cmds], [2], - [Commands used to build a loadable module if different from building - a shared archive.]) -_LT_TAGDECL([], [module_expsym_cmds], [2]) -_LT_TAGDECL([], [with_gnu_ld], [1], - [Whether we are building with GNU ld or not]) -_LT_TAGDECL([], [allow_undefined_flag], [1], - [Flag that allows shared libraries with undefined symbols to be built]) -_LT_TAGDECL([], [no_undefined_flag], [1], - [Flag that enforces no undefined symbols]) -_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], - [Flag to hardcode $libdir into a binary during linking. - This must work even if $libdir does not exist]) -_LT_TAGDECL([], [hardcode_libdir_separator], [1], - [Whether we need a single "-rpath" flag with a separated argument]) -_LT_TAGDECL([], [hardcode_direct], [0], - [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes - DIR into the resulting binary]) -_LT_TAGDECL([], [hardcode_direct_absolute], [0], - [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes - DIR into the resulting binary and the resulting library dependency is - "absolute", i.e impossible to change by setting $shlibpath_var if the - library is relocated]) -_LT_TAGDECL([], [hardcode_minus_L], [0], - [Set to "yes" if using the -LDIR flag during linking hardcodes DIR - into the resulting binary]) -_LT_TAGDECL([], [hardcode_shlibpath_var], [0], - [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR - into the resulting binary]) -_LT_TAGDECL([], [hardcode_automatic], [0], - [Set to "yes" if building a shared library automatically hardcodes DIR - into the library and all subsequent libraries and executables linked - against it]) -_LT_TAGDECL([], [inherit_rpath], [0], - [Set to yes if linker adds runtime paths of dependent libraries - to runtime path list]) -_LT_TAGDECL([], [link_all_deplibs], [0], - [Whether libtool must link a program against all its dependency libraries]) -_LT_TAGDECL([], [always_export_symbols], [0], - [Set to "yes" if exported symbols are required]) -_LT_TAGDECL([], [export_symbols_cmds], [2], - [The commands to list exported symbols]) -_LT_TAGDECL([], [exclude_expsyms], [1], - [Symbols that should not be listed in the preloaded symbols]) -_LT_TAGDECL([], [include_expsyms], [1], - [Symbols that must always be exported]) -_LT_TAGDECL([], [prelink_cmds], [2], - [Commands necessary for linking programs (against libraries) with templates]) -_LT_TAGDECL([], [postlink_cmds], [2], - [Commands necessary for finishing linking programs]) -_LT_TAGDECL([], [file_list_spec], [1], - [Specify filename containing input files]) -dnl FIXME: Not yet implemented -dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], -dnl [Compiler flag to generate thread safe objects]) -])# _LT_LINKER_SHLIBS - - -# _LT_LANG_C_CONFIG([TAG]) -# ------------------------ -# Ensure that the configuration variables for a C compiler are suitably -# defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to 'libtool'. -m4_defun([_LT_LANG_C_CONFIG], -[m4_require([_LT_DECL_EGREP])dnl -lt_save_CC=$CC -AC_LANG_PUSH(C) - -# Source file extension for C test sources. -ac_ext=c - -# Object file extension for compiled C test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}' - -_LT_TAG_COMPILER -# Save the default compiler, since it gets overwritten when the other -# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. -compiler_DEFAULT=$CC - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - LT_SYS_DLOPEN_SELF - _LT_CMD_STRIPLIB - - # Report what library types will actually be built - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test no = "$can_build_shared" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test yes = "$enable_shared" && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - - aix[[4-9]]*) - if test ia64 != "$host_cpu"; then - case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in - yes,aix,yes) ;; # shared object as lib.so file only - yes,svr4,*) ;; # shared object as lib.so archive member only - yes,*) enable_static=no ;; # shared object in lib.a archive as well - esac - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test yes = "$enable_shared" || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_CONFIG($1) -fi -AC_LANG_POP -CC=$lt_save_CC -])# _LT_LANG_C_CONFIG - - -# _LT_LANG_CXX_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for a C++ compiler are suitably -# defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to 'libtool'. -m4_defun([_LT_LANG_CXX_CONFIG], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_PATH_MANIFEST_TOOL])dnl -if test -n "$CXX" && ( test no != "$CXX" && - ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || - (test g++ != "$CXX"))); then - AC_PROG_CXXCPP -else - _lt_caught_CXX_error=yes -fi - -AC_LANG_PUSH(C++) -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(compiler_needs_object, $1)=no -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for C++ test sources. -ac_ext=cpp - -# Object file extension for compiled C++ test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the CXX compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test yes != "$_lt_caught_CXX_error"; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="int some_variable = 0;" - - # Code to be used in simple link tests - lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC=$CC - lt_save_CFLAGS=$CFLAGS - lt_save_LD=$LD - lt_save_GCC=$GCC - GCC=$GXX - lt_save_with_gnu_ld=$with_gnu_ld - lt_save_path_LD=$lt_cv_path_LD - if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then - lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx - else - $as_unset lt_cv_prog_gnu_ld - fi - if test -n "${lt_cv_path_LDCXX+set}"; then - lt_cv_path_LD=$lt_cv_path_LDCXX - else - $as_unset lt_cv_path_LD - fi - test -z "${LDCXX+set}" || LD=$LDCXX - CC=${CXX-"c++"} - CFLAGS=$CXXFLAGS - compiler=$CC - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - - if test -n "$compiler"; then - # We don't want -fno-exception when compiling C++ code, so set the - # no_builtin_flag separately - if test yes = "$GXX"; then - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' - else - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= - fi - - if test yes = "$GXX"; then - # Set up default GNU C++ configuration - - LT_PATH_LD - - # Check if GNU C++ uses GNU ld as the underlying linker, since the - # archiving commands below assume that GNU ld is being used. - if test yes = "$with_gnu_ld"; then - _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' - - # If archive_cmds runs LD, not CC, wlarc should be empty - # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to - # investigate it a little bit more. (MM) - wlarc='$wl' - - # ancient GNU ld didn't support --whole-archive et. al. - if eval "`$CC -print-prog-name=ld` --help 2>&1" | - $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - else - with_gnu_ld=no - wlarc= - - # A generic and very simple default shared library creation - # command for GNU C++ for the case where it uses the native - # linker, instead of GNU ld. If possible, this setting should - # overridden to take advantage of the native linker features on - # the platform it is being used on. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - fi - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' - - else - GXX=no - with_gnu_ld=no - wlarc= - fi - - # PORTME: fill in a description of your system's C++ link characteristics - AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) - _LT_TAGVAR(ld_shlibs, $1)=yes - case $host_os in - aix3*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aix[[4-9]]*) - if test ia64 = "$host_cpu"; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag= - else - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # have runtime linking enabled, and use it for executables. - # For shared libraries, we enable/disable runtime linking - # depending on the kind of the shared library created - - # when "with_aix_soname,aix_use_runtimelinking" is: - # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables - # "aix,yes" lib.so shared, rtl:yes, for executables - # lib.a static archive - # "both,no" lib.so.V(shr.o) shared, rtl:yes - # lib.a(lib.so.V) shared, rtl:no, for executables - # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables - # lib.a(lib.so.V) shared, rtl:no - # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables - # lib.a static archive - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) - for ld_flag in $LDFLAGS; do - case $ld_flag in - *-brtl*) - aix_use_runtimelinking=yes - break - ;; - esac - done - if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then - # With aix-soname=svr4, we create the lib.so.V shared archives only, - # so we don't have lib.a shared libs to link our executables. - # We have to force runtime linking in this case. - aix_use_runtimelinking=yes - LDFLAGS="$LDFLAGS -Wl,-brtl" - fi - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_TAGVAR(archive_cmds, $1)='' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='$wl-f,' - case $with_aix_soname,$aix_use_runtimelinking in - aix,*) ;; # no import file - svr4,* | *,yes) # use import file - # The Import File defines what to hardcode. - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=no - ;; - esac - - if test yes = "$GXX"; then - case $host_os in aix4.[[012]]|aix4.[[012]].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`$CC -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - _LT_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)= - fi - esac - shared_flag='-shared' - if test yes = "$aix_use_runtimelinking"; then - shared_flag=$shared_flag' $wl-G' - fi - # Need to ensure runtime linking is disabled for the traditional - # shared library, or the linker may eventually find shared libraries - # /with/ Import File - we do not want to mix them. - shared_flag_aix='-shared' - shared_flag_svr4='-shared $wl-G' - else - # not using gcc - if test ia64 = "$host_cpu"; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test yes = "$aix_use_runtimelinking"; then - shared_flag='$wl-G' - else - shared_flag='$wl-bM:SRE' - fi - shared_flag_aix='$wl-bM:SRE' - shared_flag_svr4='$wl-G' - fi - fi - - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to - # export. - _LT_TAGVAR(always_export_symbols, $1)=yes - if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - # The "-G" linker flag allows undefined symbols. - _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' - # Determine the default libpath from the value encoded in an empty - # executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" - - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag - else - if test ia64 = "$host_cpu"; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' - _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' - if test yes = "$with_gnu_ld"; then - # We only use this code for GNU lds that support --whole-archive. - _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' - else - # Exported symbols can be pulled into shared objects from archives - _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' - # -brtl affects multiple linker settings, -berok does not and is overridden later - compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' - if test svr4 != "$with_aix_soname"; then - # This is similar to how AIX traditionally builds its shared - # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. - _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' - fi - if test aix != "$with_aix_soname"; then - _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' - else - # used by -dlpreopen to get the symbols - _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' - fi - _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' - fi - fi - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - chorus*) - case $cc_basename in - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - cygwin* | mingw* | pw32* | cegcc*) - case $GXX,$cc_basename in - ,cl* | no,cl*) - # Native MSVC - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='@' - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=.dll - # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' - _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then - cp "$export_symbols" "$output_objdir/$soname.def"; - echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; - else - $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' - # The linker will not automatically build a static lib if we build a DLL. - # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - # Don't use ranlib - _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' - _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile=$lt_outputfile.exe - lt_tool_outputfile=$lt_tool_outputfile.exe - ;; - esac~ - func_to_tool_file "$lt_outputfile"~ - if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' - ;; - *) - # g++ - # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file, use it as - # is; otherwise, prepend EXPORTS... - _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - darwin* | rhapsody*) - _LT_DARWIN_LINKER_FEATURES($1) - ;; - - os2*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - shrext_cmds=.dll - _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ - $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ - $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ - $ECHO EXPORTS >> $output_objdir/$libname.def~ - emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ - $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ - emximp -o $lib $output_objdir/$libname.def' - _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ - $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ - $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ - $ECHO EXPORTS >> $output_objdir/$libname.def~ - prefix_cmds="$SED"~ - if test EXPORTS = "`$SED 1q $export_symbols`"; then - prefix_cmds="$prefix_cmds -e 1d"; - fi~ - prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ - cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ - $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ - emximp -o $lib $output_objdir/$libname.def' - _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - ;; - - dgux*) - case $cc_basename in - ec++*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - ghcx*) - # Green Hills C++ Compiler - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - freebsd2.*) - # C++ shared libraries reported to be fairly broken before - # switch to ELF - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - freebsd-elf*) - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - ;; - - freebsd* | dragonfly*) - # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF - # conventions - _LT_TAGVAR(ld_shlibs, $1)=yes - ;; - - haiku*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - hpux9*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aCC*) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - ;; - *) - if test yes = "$GXX"; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - hpux10*|hpux11*) - if test no = "$with_gnu_ld"; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - case $host_cpu in - hppa*64*|ia64*) - ;; - *) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' - ;; - esac - fi - case $host_cpu in - hppa*64*|ia64*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - *) - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - ;; - esac - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aCC*) - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - ;; - *) - if test yes = "$GXX"; then - if test no = "$with_gnu_ld"; then - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - fi - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - interix[[3-9]]*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - irix5* | irix6*) - case $cc_basename in - CC*) - # SGI C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' - - # Archives containing C++ object files must be created using - # "CC -ar", where "CC" is the IRIX C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' - ;; - *) - if test yes = "$GXX"; then - if test no = "$with_gnu_ld"; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' - fi - fi - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - esac - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(inherit_rpath, $1)=yes - ;; - - linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' - - # Archives containing C++ object files must be created using - # "CC -Bstatic", where "CC" is the KAI C++ compiler. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' - ;; - icpc* | ecpc* ) - # Intel C++ - with_gnu_ld=yes - # version 8.0 and above of icpc choke on multiply defined symbols - # if we add $predep_objects and $postdep_objects, however 7.1 and - # earlier do not add the objects themselves. - case `$CC -V 2>&1` in - *"Version 7."*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - ;; - *) # Version 8.0 or newer - tmp_idyn= - case $host_cpu in - ia64*) tmp_idyn=' -i_dynamic';; - esac - _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - ;; - esac - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' - ;; - pgCC* | pgcpp*) - # Portland Group C++ compiler - case `$CC -V` in - *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) - _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ - compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' - _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ - $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ - $RANLIB $oldlib' - _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - ;; - *) # Version 6 and above use weak symbols - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' - ;; - cxx*) - # Compaq C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' - - runpath_var=LD_RUN_PATH - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' - ;; - xl* | mpixl* | bgxl*) - # IBM XL 8.0 on PPC, with GNU ld - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' - _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - if test yes = "$supports_anon_versioning"; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' - fi - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - - # Not sure whether something based on - # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 - # would be better. - output_verbose_link_cmd='func_echo_all' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' - ;; - esac - ;; - esac - ;; - - lynxos*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - m88k*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - mvs*) - case $cc_basename in - cxx*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' - wlarc= - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - fi - # Workaround some broken pre-1.5 toolchains - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' - ;; - - *nto* | *qnx*) - _LT_TAGVAR(ld_shlibs, $1)=yes - ;; - - openbsd* | bitrig*) - if test -f /usr/libexec/ld.so; then - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' - _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' - fi - output_verbose_link_cmd=func_echo_all - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Archives containing C++ object files must be created using - # the KAI C++ compiler. - case $host in - osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; - *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; - esac - ;; - RCC*) - # Rational C++ 2.4.1 - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - cxx*) - case $host in - osf3*) - _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' - ;; - *) - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ - echo "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ - $RM $lib.exp' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - ;; - *) - if test yes,no = "$GXX,$with_gnu_ld"; then - _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' - case $host in - osf3*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' - - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - psos*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - lcc*) - # Lucid - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - solaris*) - case $cc_basename in - CC* | sunCC*) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_TAGVAR(archive_cmds_need_lc,$1)=yes - _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands '-z linker_flag'. - # Supported since Solaris 2.6 (maybe 2.5.1?) - _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' - ;; - esac - _LT_TAGVAR(link_all_deplibs, $1)=yes - - output_verbose_link_cmd='func_echo_all' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' - ;; - gcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' - - # The C++ compiler must be used to create the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' - ;; - *) - # GNU C++ compiler with Solaris linker - if test yes,no = "$GXX,$with_gnu_ld"; then - _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' - if $CC --version | $GREP -v '^2\.7' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' - else - # g++ 2.7 appears to require '-G' NOT '-shared' on this - # platform. - _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' - fi - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' - ;; - esac - fi - ;; - esac - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var='LD_RUN_PATH' - - case $cc_basename in - CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We CANNOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' - runpath_var='LD_RUN_PATH' - - case $cc_basename in - CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ - '"$_LT_TAGVAR(old_archive_cmds, $1)" - _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ - '"$_LT_TAGVAR(reload_cmds, $1)" - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - vxworks*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - - AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) - test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no - - _LT_TAGVAR(GCC, $1)=$GXX - _LT_TAGVAR(LD, $1)=$LD - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_SYS_HIDDEN_LIBDEPS($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - CC=$lt_save_CC - CFLAGS=$lt_save_CFLAGS - LDCXX=$LD - LD=$lt_save_LD - GCC=$lt_save_GCC - with_gnu_ld=$lt_save_with_gnu_ld - lt_cv_path_LDCXX=$lt_cv_path_LD - lt_cv_path_LD=$lt_save_path_LD - lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld - lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld -fi # test yes != "$_lt_caught_CXX_error" - -AC_LANG_POP -])# _LT_LANG_CXX_CONFIG - - -# _LT_FUNC_STRIPNAME_CNF -# ---------------------- -# func_stripname_cnf prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -# -# This function is identical to the (non-XSI) version of func_stripname, -# except this one can be used by m4 code that may be executed by configure, -# rather than the libtool script. -m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl -AC_REQUIRE([_LT_DECL_SED]) -AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) -func_stripname_cnf () -{ - case @S|@2 in - .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; - *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; - esac -} # func_stripname_cnf -])# _LT_FUNC_STRIPNAME_CNF - - -# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) -# --------------------------------- -# Figure out "hidden" library dependencies from verbose -# compiler output when linking a shared library. -# Parse the compiler output and extract the necessary -# objects, libraries and library flags. -m4_defun([_LT_SYS_HIDDEN_LIBDEPS], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl -# Dependencies to place before and after the object being linked: -_LT_TAGVAR(predep_objects, $1)= -_LT_TAGVAR(postdep_objects, $1)= -_LT_TAGVAR(predeps, $1)= -_LT_TAGVAR(postdeps, $1)= -_LT_TAGVAR(compiler_lib_search_path, $1)= - -dnl we can't use the lt_simple_compile_test_code here, -dnl because it contains code intended for an executable, -dnl not a library. It's possible we should let each -dnl tag define a new lt_????_link_test_code variable, -dnl but it's only used here... -m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF -int a; -void foo (void) { a = 0; } -_LT_EOF -], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF -class Foo -{ -public: - Foo (void) { a = 0; } -private: - int a; -}; -_LT_EOF -], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF - subroutine foo - implicit none - integer*4 a - a=0 - return - end -_LT_EOF -], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF - subroutine foo - implicit none - integer a - a=0 - return - end -_LT_EOF -], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF -public class foo { - private int a; - public void bar (void) { - a = 0; - } -}; -_LT_EOF -], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF -package foo -func foo() { -} -_LT_EOF -]) - -_lt_libdeps_save_CFLAGS=$CFLAGS -case "$CC $CFLAGS " in #( -*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; -*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; -*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; -esac - -dnl Parse the compiler output and extract the necessary -dnl objects, libraries and library flags. -if AC_TRY_EVAL(ac_compile); then - # Parse the compiler output and extract the necessary - # objects, libraries and library flags. - - # Sentinel used to keep track of whether or not we are before - # the conftest object file. - pre_test_object_deps_done=no - - for p in `eval "$output_verbose_link_cmd"`; do - case $prev$p in - - -L* | -R* | -l*) - # Some compilers place space between "-{L,R}" and the path. - # Remove the space. - if test x-L = "$p" || - test x-R = "$p"; then - prev=$p - continue - fi - - # Expand the sysroot to ease extracting the directories later. - if test -z "$prev"; then - case $p in - -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; - -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; - -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; - esac - fi - case $p in - =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; - esac - if test no = "$pre_test_object_deps_done"; then - case $prev in - -L | -R) - # Internal compiler library paths should come after those - # provided the user. The postdeps already come after the - # user supplied libs so there is no need to process them. - if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then - _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p - else - _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" - fi - ;; - # The "-l" case would never come before the object being - # linked, so don't bother handling this case. - esac - else - if test -z "$_LT_TAGVAR(postdeps, $1)"; then - _LT_TAGVAR(postdeps, $1)=$prev$p - else - _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" - fi - fi - prev= - ;; - - *.lto.$objext) ;; # Ignore GCC LTO objects - *.$objext) - # This assumes that the test object file only shows up - # once in the compiler output. - if test "$p" = "conftest.$objext"; then - pre_test_object_deps_done=yes - continue - fi - - if test no = "$pre_test_object_deps_done"; then - if test -z "$_LT_TAGVAR(predep_objects, $1)"; then - _LT_TAGVAR(predep_objects, $1)=$p - else - _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" - fi - else - if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then - _LT_TAGVAR(postdep_objects, $1)=$p - else - _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" - fi - fi - ;; - - *) ;; # Ignore the rest. - - esac - done - - # Clean up. - rm -f a.out a.exe -else - echo "libtool.m4: error: problem compiling $1 test program" -fi - -$RM -f confest.$objext -CFLAGS=$_lt_libdeps_save_CFLAGS - -# PORTME: override above test on systems where it is broken -m4_if([$1], [CXX], -[case $host_os in -interix[[3-9]]*) - # Interix 3.5 installs completely hosed .la files for C++, so rather than - # hack all around it, let's just trust "g++" to DTRT. - _LT_TAGVAR(predep_objects,$1)= - _LT_TAGVAR(postdep_objects,$1)= - _LT_TAGVAR(postdeps,$1)= - ;; -esac -]) - -case " $_LT_TAGVAR(postdeps, $1) " in -*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; -esac - _LT_TAGVAR(compiler_lib_search_dirs, $1)= -if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then - _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` -fi -_LT_TAGDECL([], [compiler_lib_search_dirs], [1], - [The directories searched by this compiler when creating a shared library]) -_LT_TAGDECL([], [predep_objects], [1], - [Dependencies to place before and after the objects being linked to - create a shared library]) -_LT_TAGDECL([], [postdep_objects], [1]) -_LT_TAGDECL([], [predeps], [1]) -_LT_TAGDECL([], [postdeps], [1]) -_LT_TAGDECL([], [compiler_lib_search_path], [1], - [The library search path used internally by the compiler when linking - a shared library]) -])# _LT_SYS_HIDDEN_LIBDEPS - - -# _LT_LANG_F77_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for a Fortran 77 compiler are -# suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to 'libtool'. -m4_defun([_LT_LANG_F77_CONFIG], -[AC_LANG_PUSH(Fortran 77) -if test -z "$F77" || test no = "$F77"; then - _lt_disable_F77=yes -fi - -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for f77 test sources. -ac_ext=f - -# Object file extension for compiled f77 test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the F77 compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test yes != "$_lt_disable_F77"; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="\ - subroutine t - return - end -" - - # Code to be used in simple link tests - lt_simple_link_test_code="\ - program t - end -" - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC=$CC - lt_save_GCC=$GCC - lt_save_CFLAGS=$CFLAGS - CC=${F77-"f77"} - CFLAGS=$FFLAGS - compiler=$CC - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - GCC=$G77 - if test -n "$compiler"; then - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test no = "$can_build_shared" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test yes = "$enable_shared" && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - aix[[4-9]]*) - if test ia64 != "$host_cpu"; then - case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in - yes,aix,yes) ;; # shared object as lib.so file only - yes,svr4,*) ;; # shared object as lib.so archive member only - yes,*) enable_static=no ;; # shared object in lib.a archive as well - esac - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test yes = "$enable_shared" || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_TAGVAR(GCC, $1)=$G77 - _LT_TAGVAR(LD, $1)=$LD - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - GCC=$lt_save_GCC - CC=$lt_save_CC - CFLAGS=$lt_save_CFLAGS -fi # test yes != "$_lt_disable_F77" - -AC_LANG_POP -])# _LT_LANG_F77_CONFIG - - -# _LT_LANG_FC_CONFIG([TAG]) -# ------------------------- -# Ensure that the configuration variables for a Fortran compiler are -# suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to 'libtool'. -m4_defun([_LT_LANG_FC_CONFIG], -[AC_LANG_PUSH(Fortran) - -if test -z "$FC" || test no = "$FC"; then - _lt_disable_FC=yes -fi - -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for fc test sources. -ac_ext=${ac_fc_srcext-f} - -# Object file extension for compiled fc test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the FC compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test yes != "$_lt_disable_FC"; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="\ - subroutine t - return - end -" - - # Code to be used in simple link tests - lt_simple_link_test_code="\ - program t - end -" - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC=$CC - lt_save_GCC=$GCC - lt_save_CFLAGS=$CFLAGS - CC=${FC-"f95"} - CFLAGS=$FCFLAGS - compiler=$CC - GCC=$ac_cv_fc_compiler_gnu - - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - - if test -n "$compiler"; then - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test no = "$can_build_shared" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test yes = "$enable_shared" && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - aix[[4-9]]*) - if test ia64 != "$host_cpu"; then - case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in - yes,aix,yes) ;; # shared object as lib.so file only - yes,svr4,*) ;; # shared object as lib.so archive member only - yes,*) enable_static=no ;; # shared object in lib.a archive as well - esac - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test yes = "$enable_shared" || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu - _LT_TAGVAR(LD, $1)=$LD - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_SYS_HIDDEN_LIBDEPS($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - GCC=$lt_save_GCC - CC=$lt_save_CC - CFLAGS=$lt_save_CFLAGS -fi # test yes != "$_lt_disable_FC" - -AC_LANG_POP -])# _LT_LANG_FC_CONFIG - - -# _LT_LANG_GCJ_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for the GNU Java Compiler compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to 'libtool'. -m4_defun([_LT_LANG_GCJ_CONFIG], -[AC_REQUIRE([LT_PROG_GCJ])dnl -AC_LANG_SAVE - -# Source file extension for Java test sources. -ac_ext=java - -# Object file extension for compiled Java test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="class foo {}" - -# Code to be used in simple link tests -lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC=$CC -lt_save_CFLAGS=$CFLAGS -lt_save_GCC=$GCC -GCC=yes -CC=${GCJ-"gcj"} -CFLAGS=$GCJFLAGS -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_TAGVAR(LD, $1)=$LD -_LT_CC_BASENAME([$compiler]) - -# GCJ did not exist at the time GCC didn't implicitly link libc in. -_LT_TAGVAR(archive_cmds_need_lc, $1)=no - -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds - -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) -fi - -AC_LANG_RESTORE - -GCC=$lt_save_GCC -CC=$lt_save_CC -CFLAGS=$lt_save_CFLAGS -])# _LT_LANG_GCJ_CONFIG - - -# _LT_LANG_GO_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for the GNU Go compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to 'libtool'. -m4_defun([_LT_LANG_GO_CONFIG], -[AC_REQUIRE([LT_PROG_GO])dnl -AC_LANG_SAVE - -# Source file extension for Go test sources. -ac_ext=go - -# Object file extension for compiled Go test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="package main; func main() { }" - -# Code to be used in simple link tests -lt_simple_link_test_code='package main; func main() { }' - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC=$CC -lt_save_CFLAGS=$CFLAGS -lt_save_GCC=$GCC -GCC=yes -CC=${GOC-"gccgo"} -CFLAGS=$GOFLAGS -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_TAGVAR(LD, $1)=$LD -_LT_CC_BASENAME([$compiler]) - -# Go did not exist at the time GCC didn't implicitly link libc in. -_LT_TAGVAR(archive_cmds_need_lc, $1)=no - -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds - -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) -fi - -AC_LANG_RESTORE - -GCC=$lt_save_GCC -CC=$lt_save_CC -CFLAGS=$lt_save_CFLAGS -])# _LT_LANG_GO_CONFIG - - -# _LT_LANG_RC_CONFIG([TAG]) -# ------------------------- -# Ensure that the configuration variables for the Windows resource compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to 'libtool'. -m4_defun([_LT_LANG_RC_CONFIG], -[AC_REQUIRE([LT_PROG_RC])dnl -AC_LANG_SAVE - -# Source file extension for RC test sources. -ac_ext=rc - -# Object file extension for compiled RC test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' - -# Code to be used in simple link tests -lt_simple_link_test_code=$lt_simple_compile_test_code - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC=$CC -lt_save_CFLAGS=$CFLAGS -lt_save_GCC=$GCC -GCC= -CC=${RC-"windres"} -CFLAGS= -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_CC_BASENAME([$compiler]) -_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes - -if test -n "$compiler"; then - : - _LT_CONFIG($1) -fi - -GCC=$lt_save_GCC -AC_LANG_RESTORE -CC=$lt_save_CC -CFLAGS=$lt_save_CFLAGS -])# _LT_LANG_RC_CONFIG - - -# LT_PROG_GCJ -# ----------- -AC_DEFUN([LT_PROG_GCJ], -[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], - [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], - [AC_CHECK_TOOL(GCJ, gcj,) - test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" - AC_SUBST(GCJFLAGS)])])[]dnl -]) - -# Old name: -AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_GCJ], []) - - -# LT_PROG_GO -# ---------- -AC_DEFUN([LT_PROG_GO], -[AC_CHECK_TOOL(GOC, gccgo,) -]) - - -# LT_PROG_RC -# ---------- -AC_DEFUN([LT_PROG_RC], -[AC_CHECK_TOOL(RC, windres,) -]) - -# Old name: -AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_RC], []) - - -# _LT_DECL_EGREP -# -------------- -# If we don't have a new enough Autoconf to choose the best grep -# available, choose the one first in the user's PATH. -m4_defun([_LT_DECL_EGREP], -[AC_REQUIRE([AC_PROG_EGREP])dnl -AC_REQUIRE([AC_PROG_FGREP])dnl -test -z "$GREP" && GREP=grep -_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) -_LT_DECL([], [EGREP], [1], [An ERE matcher]) -_LT_DECL([], [FGREP], [1], [A literal string matcher]) -dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too -AC_SUBST([GREP]) -]) - - -# _LT_DECL_OBJDUMP -# -------------- -# If we don't have a new enough Autoconf to choose the best objdump -# available, choose the one first in the user's PATH. -m4_defun([_LT_DECL_OBJDUMP], -[AC_CHECK_TOOL(OBJDUMP, objdump, false) -test -z "$OBJDUMP" && OBJDUMP=objdump -_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) -AC_SUBST([OBJDUMP]) -]) - -# _LT_DECL_DLLTOOL -# ---------------- -# Ensure DLLTOOL variable is set. -m4_defun([_LT_DECL_DLLTOOL], -[AC_CHECK_TOOL(DLLTOOL, dlltool, false) -test -z "$DLLTOOL" && DLLTOOL=dlltool -_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) -AC_SUBST([DLLTOOL]) -]) - -# _LT_DECL_SED -# ------------ -# Check for a fully-functional sed program, that truncates -# as few characters as possible. Prefer GNU sed if found. -m4_defun([_LT_DECL_SED], -[AC_PROG_SED -test -z "$SED" && SED=sed -Xsed="$SED -e 1s/^X//" -_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) -_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], - [Sed that helps us avoid accidentally triggering echo(1) options like -n]) -])# _LT_DECL_SED - -m4_ifndef([AC_PROG_SED], [ -# NOTE: This macro has been submitted for inclusion into # -# GNU Autoconf as AC_PROG_SED. When it is available in # -# a released version of Autoconf we should remove this # -# macro and use it instead. # - -m4_defun([AC_PROG_SED], -[AC_MSG_CHECKING([for a sed that does not truncate output]) -AC_CACHE_VAL(lt_cv_path_SED, -[# Loop through the user's path and test for sed and gsed. -# Then use that list of sed's as ones to test for truncation. -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for lt_ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then - lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" - fi - done - done -done -IFS=$as_save_IFS -lt_ac_max=0 -lt_ac_count=0 -# Add /usr/xpg4/bin/sed as it is typically found on Solaris -# along with /bin/sed that truncates output. -for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do - test ! -f "$lt_ac_sed" && continue - cat /dev/null > conftest.in - lt_ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >conftest.in - # Check for GNU sed and select it if it is found. - if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then - lt_cv_path_SED=$lt_ac_sed - break - fi - while true; do - cat conftest.in conftest.in >conftest.tmp - mv conftest.tmp conftest.in - cp conftest.in conftest.nl - echo >>conftest.nl - $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break - cmp -s conftest.out conftest.nl || break - # 10000 chars as input seems more than enough - test 10 -lt "$lt_ac_count" && break - lt_ac_count=`expr $lt_ac_count + 1` - if test "$lt_ac_count" -gt "$lt_ac_max"; then - lt_ac_max=$lt_ac_count - lt_cv_path_SED=$lt_ac_sed - fi - done -done -]) -SED=$lt_cv_path_SED -AC_SUBST([SED]) -AC_MSG_RESULT([$SED]) -])#AC_PROG_SED -])#m4_ifndef - -# Old name: -AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_SED], []) - - -# _LT_CHECK_SHELL_FEATURES -# ------------------------ -# Find out whether the shell is Bourne or XSI compatible, -# or has some other useful features. -m4_defun([_LT_CHECK_SHELL_FEATURES], -[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - lt_unset=unset -else - lt_unset=false -fi -_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl - -# test EBCDIC or ASCII -case `echo X|tr X '\101'` in - A) # ASCII based system - # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr - lt_SP2NL='tr \040 \012' - lt_NL2SP='tr \015\012 \040\040' - ;; - *) # EBCDIC based system - lt_SP2NL='tr \100 \n' - lt_NL2SP='tr \r\n \100\100' - ;; -esac -_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl -_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl -])# _LT_CHECK_SHELL_FEATURES - - -# _LT_PATH_CONVERSION_FUNCTIONS -# ----------------------------- -# Determine what file name conversion functions should be used by -# func_to_host_file (and, implicitly, by func_to_host_path). These are needed -# for certain cross-compile configurations and native mingw. -m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -AC_MSG_CHECKING([how to convert $build file names to $host format]) -AC_CACHE_VAL(lt_cv_to_host_file_cmd, -[case $host in - *-*-mingw* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 - ;; - *-*-cygwin* ) - lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 - ;; - * ) # otherwise, assume *nix - lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 - ;; - esac - ;; - *-*-cygwin* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin - ;; - *-*-cygwin* ) - lt_cv_to_host_file_cmd=func_convert_file_noop - ;; - * ) # otherwise, assume *nix - lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin - ;; - esac - ;; - * ) # unhandled hosts (and "normal" native builds) - lt_cv_to_host_file_cmd=func_convert_file_noop - ;; -esac -]) -to_host_file_cmd=$lt_cv_to_host_file_cmd -AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) -_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], - [0], [convert $build file names to $host format])dnl - -AC_MSG_CHECKING([how to convert $build file names to toolchain format]) -AC_CACHE_VAL(lt_cv_to_tool_file_cmd, -[#assume ordinary cross tools, or native build. -lt_cv_to_tool_file_cmd=func_convert_file_noop -case $host in - *-*-mingw* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 - ;; - esac - ;; -esac -]) -to_tool_file_cmd=$lt_cv_to_tool_file_cmd -AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) -_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], - [0], [convert $build files to toolchain format])dnl -])# _LT_PATH_CONVERSION_FUNCTIONS - -# Helper functions for option handling. -*- Autoconf -*- -# -# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software -# Foundation, Inc. -# Written by Gary V. Vaughan, 2004 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# serial 8 ltoptions.m4 - -# This is to help aclocal find these macros, as it can't see m4_define. -AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) - - -# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) -# ------------------------------------------ -m4_define([_LT_MANGLE_OPTION], -[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) - - -# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) -# --------------------------------------- -# Set option OPTION-NAME for macro MACRO-NAME, and if there is a -# matching handler defined, dispatch to it. Other OPTION-NAMEs are -# saved as a flag. -m4_define([_LT_SET_OPTION], -[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl -m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), - _LT_MANGLE_DEFUN([$1], [$2]), - [m4_warning([Unknown $1 option '$2'])])[]dnl -]) - - -# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) -# ------------------------------------------------------------ -# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. -m4_define([_LT_IF_OPTION], -[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) - - -# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) -# ------------------------------------------------------- -# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME -# are set. -m4_define([_LT_UNLESS_OPTIONS], -[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), - [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), - [m4_define([$0_found])])])[]dnl -m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 -])[]dnl -]) - - -# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) -# ---------------------------------------- -# OPTION-LIST is a space-separated list of Libtool options associated -# with MACRO-NAME. If any OPTION has a matching handler declared with -# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about -# the unknown option and exit. -m4_defun([_LT_SET_OPTIONS], -[# Set options -m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), - [_LT_SET_OPTION([$1], _LT_Option)]) - -m4_if([$1],[LT_INIT],[ - dnl - dnl Simply set some default values (i.e off) if boolean options were not - dnl specified: - _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no - ]) - _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no - ]) - dnl - dnl If no reference was made to various pairs of opposing options, then - dnl we run the default mode handler for the pair. For example, if neither - dnl 'shared' nor 'disable-shared' was passed, we enable building of shared - dnl archives by default: - _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) - _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) - _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) - _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], - [_LT_ENABLE_FAST_INSTALL]) - _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], - [_LT_WITH_AIX_SONAME([aix])]) - ]) -])# _LT_SET_OPTIONS - - - -# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) -# ----------------------------------------- -m4_define([_LT_MANGLE_DEFUN], -[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) - - -# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) -# ----------------------------------------------- -m4_define([LT_OPTION_DEFINE], -[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl -])# LT_OPTION_DEFINE - - -# dlopen -# ------ -LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes -]) - -AU_DEFUN([AC_LIBTOOL_DLOPEN], -[_LT_SET_OPTION([LT_INIT], [dlopen]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you -put the 'dlopen' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) - - -# win32-dll -# --------- -# Declare package support for building win32 dll's. -LT_OPTION_DEFINE([LT_INIT], [win32-dll], -[enable_win32_dll=yes - -case $host in -*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) - AC_CHECK_TOOL(AS, as, false) - AC_CHECK_TOOL(DLLTOOL, dlltool, false) - AC_CHECK_TOOL(OBJDUMP, objdump, false) - ;; -esac - -test -z "$AS" && AS=as -_LT_DECL([], [AS], [1], [Assembler program])dnl - -test -z "$DLLTOOL" && DLLTOOL=dlltool -_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl - -test -z "$OBJDUMP" && OBJDUMP=objdump -_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl -])# win32-dll - -AU_DEFUN([AC_LIBTOOL_WIN32_DLL], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -_LT_SET_OPTION([LT_INIT], [win32-dll]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you -put the 'win32-dll' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) - - -# _LT_ENABLE_SHARED([DEFAULT]) -# ---------------------------- -# implement the --enable-shared flag, and supports the 'shared' and -# 'disable-shared' LT_INIT options. -# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. -m4_define([_LT_ENABLE_SHARED], -[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl -AC_ARG_ENABLE([shared], - [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], - [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_shared=yes ;; - no) enable_shared=no ;; - *) - enable_shared=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, - for pkg in $enableval; do - IFS=$lt_save_ifs - if test "X$pkg" = "X$p"; then - enable_shared=yes - fi - done - IFS=$lt_save_ifs - ;; - esac], - [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) - - _LT_DECL([build_libtool_libs], [enable_shared], [0], - [Whether or not to build shared libraries]) -])# _LT_ENABLE_SHARED - -LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) -LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) - -# Old names: -AC_DEFUN([AC_ENABLE_SHARED], -[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) -]) - -AC_DEFUN([AC_DISABLE_SHARED], -[_LT_SET_OPTION([LT_INIT], [disable-shared]) -]) - -AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) -AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_ENABLE_SHARED], []) -dnl AC_DEFUN([AM_DISABLE_SHARED], []) - - - -# _LT_ENABLE_STATIC([DEFAULT]) -# ---------------------------- -# implement the --enable-static flag, and support the 'static' and -# 'disable-static' LT_INIT options. -# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. -m4_define([_LT_ENABLE_STATIC], -[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl -AC_ARG_ENABLE([static], - [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], - [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_static=yes ;; - no) enable_static=no ;; - *) - enable_static=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, - for pkg in $enableval; do - IFS=$lt_save_ifs - if test "X$pkg" = "X$p"; then - enable_static=yes - fi - done - IFS=$lt_save_ifs - ;; - esac], - [enable_static=]_LT_ENABLE_STATIC_DEFAULT) - - _LT_DECL([build_old_libs], [enable_static], [0], - [Whether or not to build static libraries]) -])# _LT_ENABLE_STATIC - -LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) -LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) - -# Old names: -AC_DEFUN([AC_ENABLE_STATIC], -[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) -]) - -AC_DEFUN([AC_DISABLE_STATIC], -[_LT_SET_OPTION([LT_INIT], [disable-static]) -]) - -AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) -AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_ENABLE_STATIC], []) -dnl AC_DEFUN([AM_DISABLE_STATIC], []) - - - -# _LT_ENABLE_FAST_INSTALL([DEFAULT]) -# ---------------------------------- -# implement the --enable-fast-install flag, and support the 'fast-install' -# and 'disable-fast-install' LT_INIT options. -# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. -m4_define([_LT_ENABLE_FAST_INSTALL], -[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl -AC_ARG_ENABLE([fast-install], - [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], - [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_fast_install=yes ;; - no) enable_fast_install=no ;; - *) - enable_fast_install=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, - for pkg in $enableval; do - IFS=$lt_save_ifs - if test "X$pkg" = "X$p"; then - enable_fast_install=yes - fi - done - IFS=$lt_save_ifs - ;; - esac], - [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) - -_LT_DECL([fast_install], [enable_fast_install], [0], - [Whether or not to optimize for fast installation])dnl -])# _LT_ENABLE_FAST_INSTALL - -LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) -LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) - -# Old names: -AU_DEFUN([AC_ENABLE_FAST_INSTALL], -[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you put -the 'fast-install' option into LT_INIT's first parameter.]) -]) - -AU_DEFUN([AC_DISABLE_FAST_INSTALL], -[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you put -the 'disable-fast-install' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) -dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) - - -# _LT_WITH_AIX_SONAME([DEFAULT]) -# ---------------------------------- -# implement the --with-aix-soname flag, and support the `aix-soname=aix' -# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT -# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. -m4_define([_LT_WITH_AIX_SONAME], -[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl -shared_archive_member_spec= -case $host,$enable_shared in -power*-*-aix[[5-9]]*,yes) - AC_MSG_CHECKING([which variant of shared library versioning to provide]) - AC_ARG_WITH([aix-soname], - [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], - [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], - [case $withval in - aix|svr4|both) - ;; - *) - AC_MSG_ERROR([Unknown argument to --with-aix-soname]) - ;; - esac - lt_cv_with_aix_soname=$with_aix_soname], - [AC_CACHE_VAL([lt_cv_with_aix_soname], - [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) - with_aix_soname=$lt_cv_with_aix_soname]) - AC_MSG_RESULT([$with_aix_soname]) - if test aix != "$with_aix_soname"; then - # For the AIX way of multilib, we name the shared archive member - # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', - # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. - # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, - # the AIX toolchain works better with OBJECT_MODE set (default 32). - if test 64 = "${OBJECT_MODE-32}"; then - shared_archive_member_spec=shr_64 - else - shared_archive_member_spec=shr - fi - fi - ;; -*) - with_aix_soname=aix - ;; -esac - -_LT_DECL([], [shared_archive_member_spec], [0], - [Shared archive member basename, for filename based shared library versioning on AIX])dnl -])# _LT_WITH_AIX_SONAME - -LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) -LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) -LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) - - -# _LT_WITH_PIC([MODE]) -# -------------------- -# implement the --with-pic flag, and support the 'pic-only' and 'no-pic' -# LT_INIT options. -# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. -m4_define([_LT_WITH_PIC], -[AC_ARG_WITH([pic], - [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], - [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], - [lt_p=${PACKAGE-default} - case $withval in - yes|no) pic_mode=$withval ;; - *) - pic_mode=default - # Look at the argument we got. We use all the common list separators. - lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, - for lt_pkg in $withval; do - IFS=$lt_save_ifs - if test "X$lt_pkg" = "X$lt_p"; then - pic_mode=yes - fi - done - IFS=$lt_save_ifs - ;; - esac], - [pic_mode=m4_default([$1], [default])]) - -_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl -])# _LT_WITH_PIC - -LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) -LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) - -# Old name: -AU_DEFUN([AC_LIBTOOL_PICMODE], -[_LT_SET_OPTION([LT_INIT], [pic-only]) -AC_DIAGNOSE([obsolete], -[$0: Remove this warning and the call to _LT_SET_OPTION when you -put the 'pic-only' option into LT_INIT's first parameter.]) -]) - -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) - - -m4_define([_LTDL_MODE], []) -LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], - [m4_define([_LTDL_MODE], [nonrecursive])]) -LT_OPTION_DEFINE([LTDL_INIT], [recursive], - [m4_define([_LTDL_MODE], [recursive])]) -LT_OPTION_DEFINE([LTDL_INIT], [subproject], - [m4_define([_LTDL_MODE], [subproject])]) - -m4_define([_LTDL_TYPE], []) -LT_OPTION_DEFINE([LTDL_INIT], [installable], - [m4_define([_LTDL_TYPE], [installable])]) -LT_OPTION_DEFINE([LTDL_INIT], [convenience], - [m4_define([_LTDL_TYPE], [convenience])]) - -# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- -# -# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software -# Foundation, Inc. -# Written by Gary V. Vaughan, 2004 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# serial 6 ltsugar.m4 - -# This is to help aclocal find these macros, as it can't see m4_define. -AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) - - -# lt_join(SEP, ARG1, [ARG2...]) -# ----------------------------- -# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their -# associated separator. -# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier -# versions in m4sugar had bugs. -m4_define([lt_join], -[m4_if([$#], [1], [], - [$#], [2], [[$2]], - [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) -m4_define([_lt_join], -[m4_if([$#$2], [2], [], - [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) - - -# lt_car(LIST) -# lt_cdr(LIST) -# ------------ -# Manipulate m4 lists. -# These macros are necessary as long as will still need to support -# Autoconf-2.59, which quotes differently. -m4_define([lt_car], [[$1]]) -m4_define([lt_cdr], -[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], - [$#], 1, [], - [m4_dquote(m4_shift($@))])]) -m4_define([lt_unquote], $1) - - -# lt_append(MACRO-NAME, STRING, [SEPARATOR]) -# ------------------------------------------ -# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. -# Note that neither SEPARATOR nor STRING are expanded; they are appended -# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). -# No SEPARATOR is output if MACRO-NAME was previously undefined (different -# than defined and empty). -# -# This macro is needed until we can rely on Autoconf 2.62, since earlier -# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. -m4_define([lt_append], -[m4_define([$1], - m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) - - - -# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) -# ---------------------------------------------------------- -# Produce a SEP delimited list of all paired combinations of elements of -# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list -# has the form PREFIXmINFIXSUFFIXn. -# Needed until we can rely on m4_combine added in Autoconf 2.62. -m4_define([lt_combine], -[m4_if(m4_eval([$# > 3]), [1], - [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl -[[m4_foreach([_Lt_prefix], [$2], - [m4_foreach([_Lt_suffix], - ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, - [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) - - -# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) -# ----------------------------------------------------------------------- -# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited -# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. -m4_define([lt_if_append_uniq], -[m4_ifdef([$1], - [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], - [lt_append([$1], [$2], [$3])$4], - [$5])], - [lt_append([$1], [$2], [$3])$4])]) - - -# lt_dict_add(DICT, KEY, VALUE) -# ----------------------------- -m4_define([lt_dict_add], -[m4_define([$1($2)], [$3])]) - - -# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) -# -------------------------------------------- -m4_define([lt_dict_add_subkey], -[m4_define([$1($2:$3)], [$4])]) - - -# lt_dict_fetch(DICT, KEY, [SUBKEY]) -# ---------------------------------- -m4_define([lt_dict_fetch], -[m4_ifval([$3], - m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), - m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) - - -# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) -# ----------------------------------------------------------------- -m4_define([lt_if_dict_fetch], -[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], - [$5], - [$6])]) - - -# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) -# -------------------------------------------------------------- -m4_define([lt_dict_filter], -[m4_if([$5], [], [], - [lt_join(m4_quote(m4_default([$4], [[, ]])), - lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), - [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl -]) - -# ltversion.m4 -- version numbers -*- Autoconf -*- -# -# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. -# Written by Scott James Remnant, 2004 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# @configure_input@ - -# serial 4179 ltversion.m4 -# This file is part of GNU Libtool - -m4_define([LT_PACKAGE_VERSION], [2.4.6]) -m4_define([LT_PACKAGE_REVISION], [2.4.6]) - -AC_DEFUN([LTVERSION_VERSION], -[macro_version='2.4.6' -macro_revision='2.4.6' -_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) -_LT_DECL(, macro_revision, 0) -]) - -# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- -# -# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software -# Foundation, Inc. -# Written by Scott James Remnant, 2004. -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. - -# serial 5 lt~obsolete.m4 - -# These exist entirely to fool aclocal when bootstrapping libtool. -# -# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), -# which have later been changed to m4_define as they aren't part of the -# exported API, or moved to Autoconf or Automake where they belong. -# -# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN -# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us -# using a macro with the same name in our local m4/libtool.m4 it'll -# pull the old libtool.m4 in (it doesn't see our shiny new m4_define -# and doesn't know about Autoconf macros at all.) -# -# So we provide this file, which has a silly filename so it's always -# included after everything else. This provides aclocal with the -# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything -# because those macros already exist, or will be overwritten later. -# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. -# -# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. -# Yes, that means every name once taken will need to remain here until -# we give up compatibility with versions before 1.7, at which point -# we need to keep only those names which we still refer to. - -# This is to help aclocal find these macros, as it can't see m4_define. -AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) - -m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) -m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) -m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) -m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) -m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) -m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) -m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) -m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) -m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) -m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) -m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) -m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) -m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) -m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) -m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) -m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) -m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) -m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) -m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) -m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) -m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) -m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) -m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) -m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) -m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) -m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) -m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) -m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) -m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) -m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) -m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) -m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) -m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) -m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) -m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) -m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) -m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) -m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) -m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) -m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) -m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) -m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) -m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) -m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) -m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) -m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) -m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) -m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) -m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) -m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) -m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) -m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) -m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) -m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) -m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) -m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) -m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) -m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) - -# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -# serial 12 (pkg-config-0.29.2) - -dnl Copyright © 2004 Scott James Remnant . -dnl Copyright © 2012-2015 Dan Nicholson -dnl -dnl This program is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 2 of the License, or -dnl (at your option) any later version. -dnl -dnl This program is distributed in the hope that it will be useful, but -dnl WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with this program; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -dnl 02111-1307, USA. -dnl -dnl As a special exception to the GNU General Public License, if you -dnl distribute this file as part of a program that contains a -dnl configuration script generated by Autoconf, you may include it under -dnl the same distribution terms that you use for the rest of that -dnl program. - -dnl PKG_PREREQ(MIN-VERSION) -dnl ----------------------- -dnl Since: 0.29 -dnl -dnl Verify that the version of the pkg-config macros are at least -dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's -dnl installed version of pkg-config, this checks the developer's version -dnl of pkg.m4 when generating configure. -dnl -dnl To ensure that this macro is defined, also add: -dnl m4_ifndef([PKG_PREREQ], -dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) -dnl -dnl See the "Since" comment for each macro you use to see what version -dnl of the macros you require. -m4_defun([PKG_PREREQ], -[m4_define([PKG_MACROS_VERSION], [0.29.2]) -m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, - [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) -])dnl PKG_PREREQ - -dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) -dnl ---------------------------------- -dnl Since: 0.16 -dnl -dnl Search for the pkg-config tool and set the PKG_CONFIG variable to -dnl first found in the path. Checks that the version of pkg-config found -dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is -dnl used since that's the first version where most current features of -dnl pkg-config existed. -AC_DEFUN([PKG_PROG_PKG_CONFIG], -[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) -m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) -m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) -AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) -AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) -AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) - -if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then - AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) -fi -if test -n "$PKG_CONFIG"; then - _pkg_min_version=m4_default([$1], [0.9.0]) - AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) - if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - PKG_CONFIG="" - fi -fi[]dnl -])dnl PKG_PROG_PKG_CONFIG - -dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -dnl ------------------------------------------------------------------- -dnl Since: 0.18 -dnl -dnl Check to see whether a particular set of modules exists. Similar to -dnl PKG_CHECK_MODULES(), but does not set variables or print errors. -dnl -dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) -dnl only at the first occurence in configure.ac, so if the first place -dnl it's called might be skipped (such as if it is within an "if", you -dnl have to call PKG_CHECK_EXISTS manually -AC_DEFUN([PKG_CHECK_EXISTS], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -if test -n "$PKG_CONFIG" && \ - AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then - m4_default([$2], [:]) -m4_ifvaln([$3], [else - $3])dnl -fi]) - -dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) -dnl --------------------------------------------- -dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting -dnl pkg_failed based on the result. -m4_define([_PKG_CONFIG], -[if test -n "$$1"; then - pkg_cv_[]$1="$$1" - elif test -n "$PKG_CONFIG"; then - PKG_CHECK_EXISTS([$3], - [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes ], - [pkg_failed=yes]) - else - pkg_failed=untried -fi[]dnl -])dnl _PKG_CONFIG - -dnl _PKG_SHORT_ERRORS_SUPPORTED -dnl --------------------------- -dnl Internal check to see if pkg-config supports short errors. -AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi[]dnl -])dnl _PKG_SHORT_ERRORS_SUPPORTED - - -dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], -dnl [ACTION-IF-NOT-FOUND]) -dnl -------------------------------------------------------------- -dnl Since: 0.4.0 -dnl -dnl Note that if there is a possibility the first call to -dnl PKG_CHECK_MODULES might not happen, you should be sure to include an -dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac -AC_DEFUN([PKG_CHECK_MODULES], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl -AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl - -pkg_failed=no -AC_MSG_CHECKING([for $2]) - -_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) -_PKG_CONFIG([$1][_LIBS], [libs], [$2]) - -m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS -and $1[]_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details.]) - -if test $pkg_failed = yes; then - AC_MSG_RESULT([no]) - _PKG_SHORT_ERRORS_SUPPORTED - if test $_pkg_short_errors_supported = yes; then - $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` - else - $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD - - m4_default([$4], [AC_MSG_ERROR( -[Package requirements ($2) were not met: - -$$1_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -_PKG_TEXT])[]dnl - ]) -elif test $pkg_failed = untried; then - AC_MSG_RESULT([no]) - m4_default([$4], [AC_MSG_FAILURE( -[The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -_PKG_TEXT - -To get pkg-config, see .])[]dnl - ]) -else - $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS - $1[]_LIBS=$pkg_cv_[]$1[]_LIBS - AC_MSG_RESULT([yes]) - $3 -fi[]dnl -])dnl PKG_CHECK_MODULES - - -dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], -dnl [ACTION-IF-NOT-FOUND]) -dnl --------------------------------------------------------------------- -dnl Since: 0.29 -dnl -dnl Checks for existence of MODULES and gathers its build flags with -dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags -dnl and VARIABLE-PREFIX_LIBS from --libs. -dnl -dnl Note that if there is a possibility the first call to -dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to -dnl include an explicit call to PKG_PROG_PKG_CONFIG in your -dnl configure.ac. -AC_DEFUN([PKG_CHECK_MODULES_STATIC], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -_save_PKG_CONFIG=$PKG_CONFIG -PKG_CONFIG="$PKG_CONFIG --static" -PKG_CHECK_MODULES($@) -PKG_CONFIG=$_save_PKG_CONFIG[]dnl -])dnl PKG_CHECK_MODULES_STATIC - - -dnl PKG_INSTALLDIR([DIRECTORY]) -dnl ------------------------- -dnl Since: 0.27 -dnl -dnl Substitutes the variable pkgconfigdir as the location where a module -dnl should install pkg-config .pc files. By default the directory is -dnl $libdir/pkgconfig, but the default can be changed by passing -dnl DIRECTORY. The user can override through the --with-pkgconfigdir -dnl parameter. -AC_DEFUN([PKG_INSTALLDIR], -[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) -m4_pushdef([pkg_description], - [pkg-config installation directory @<:@]pkg_default[@:>@]) -AC_ARG_WITH([pkgconfigdir], - [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, - [with_pkgconfigdir=]pkg_default) -AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) -m4_popdef([pkg_default]) -m4_popdef([pkg_description]) -])dnl PKG_INSTALLDIR - - -dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) -dnl -------------------------------- -dnl Since: 0.27 -dnl -dnl Substitutes the variable noarch_pkgconfigdir as the location where a -dnl module should install arch-independent pkg-config .pc files. By -dnl default the directory is $datadir/pkgconfig, but the default can be -dnl changed by passing DIRECTORY. The user can override through the -dnl --with-noarch-pkgconfigdir parameter. -AC_DEFUN([PKG_NOARCH_INSTALLDIR], -[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) -m4_pushdef([pkg_description], - [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) -AC_ARG_WITH([noarch-pkgconfigdir], - [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, - [with_noarch_pkgconfigdir=]pkg_default) -AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) -m4_popdef([pkg_default]) -m4_popdef([pkg_description]) -])dnl PKG_NOARCH_INSTALLDIR - - -dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, -dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -dnl ------------------------------------------- -dnl Since: 0.28 -dnl -dnl Retrieves the value of the pkg-config variable for the given module. -AC_DEFUN([PKG_CHECK_VAR], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl - -_PKG_CONFIG([$1], [variable="][$3]["], [$2]) -AS_VAR_COPY([$1], [pkg_cv_][$1]) - -AS_VAR_IF([$1], [""], [$5], [$4])dnl -])dnl PKG_CHECK_VAR - -# Copyright (C) 2002-2021 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_AUTOMAKE_VERSION(VERSION) -# ---------------------------- -# Automake X.Y traces this macro to ensure aclocal.m4 has been -# generated from the m4 files accompanying Automake X.Y. -# (This private macro should not be called outside this file.) -AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.16' -dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to -dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.16.5], [], - [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl -]) - -# _AM_AUTOCONF_VERSION(VERSION) -# ----------------------------- -# aclocal traces this macro to find the Autoconf version. -# This is a private macro too. Using m4_define simplifies -# the logic in aclocal, which can simply ignore this definition. -m4_define([_AM_AUTOCONF_VERSION], []) - -# AM_SET_CURRENT_AUTOMAKE_VERSION -# ------------------------------- -# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. -# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. -AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.16.5])dnl -m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) - -# AM_AUX_DIR_EXPAND -*- Autoconf -*- - -# Copyright (C) 2001-2021 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets -# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to -# '$srcdir', '$srcdir/..', or '$srcdir/../..'. -# -# Of course, Automake must honor this variable whenever it calls a -# tool from the auxiliary directory. The problem is that $srcdir (and -# therefore $ac_aux_dir as well) can be either absolute or relative, -# depending on how configure is run. This is pretty annoying, since -# it makes $ac_aux_dir quite unusable in subdirectories: in the top -# source directory, any form will work fine, but in subdirectories a -# relative path needs to be adjusted first. -# -# $ac_aux_dir/missing -# fails when called from a subdirectory if $ac_aux_dir is relative -# $top_srcdir/$ac_aux_dir/missing -# fails if $ac_aux_dir is absolute, -# fails when called from a subdirectory in a VPATH build with -# a relative $ac_aux_dir -# -# The reason of the latter failure is that $top_srcdir and $ac_aux_dir -# are both prefixed by $srcdir. In an in-source build this is usually -# harmless because $srcdir is '.', but things will broke when you -# start a VPATH build or use an absolute $srcdir. -# -# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, -# iff we strip the leading $srcdir from $ac_aux_dir. That would be: -# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` -# and then we would define $MISSING as -# MISSING="\${SHELL} $am_aux_dir/missing" -# This will work as long as MISSING is not called from configure, because -# unfortunately $(top_srcdir) has no meaning in configure. -# However there are other variables, like CC, which are often used in -# configure, and could therefore not use this "fixed" $ac_aux_dir. -# -# Another solution, used here, is to always expand $ac_aux_dir to an -# absolute PATH. The drawback is that using absolute paths prevent a -# configured tree to be moved without reconfiguration. - -AC_DEFUN([AM_AUX_DIR_EXPAND], -[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl -# Expand $ac_aux_dir to an absolute path. -am_aux_dir=`cd "$ac_aux_dir" && pwd` -]) - -# AM_CONDITIONAL -*- Autoconf -*- - -# Copyright (C) 1997-2021 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_CONDITIONAL(NAME, SHELL-CONDITION) -# ------------------------------------- -# Define a conditional. -AC_DEFUN([AM_CONDITIONAL], -[AC_PREREQ([2.52])dnl - m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], - [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl -AC_SUBST([$1_TRUE])dnl -AC_SUBST([$1_FALSE])dnl -_AM_SUBST_NOTMAKE([$1_TRUE])dnl -_AM_SUBST_NOTMAKE([$1_FALSE])dnl -m4_define([_AM_COND_VALUE_$1], [$2])dnl -if $2; then - $1_TRUE= - $1_FALSE='#' -else - $1_TRUE='#' - $1_FALSE= -fi -AC_CONFIG_COMMANDS_PRE( -[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then - AC_MSG_ERROR([[conditional "$1" was never defined. -Usually this means the macro was only invoked conditionally.]]) -fi])]) - -# Copyright (C) 1999-2021 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - - -# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be -# written in clear, in which case automake, when reading aclocal.m4, -# will think it sees a *use*, and therefore will trigger all it's -# C support machinery. Also note that it means that autoscan, seeing -# CC etc. in the Makefile, will ask for an AC_PROG_CC use... - - -# _AM_DEPENDENCIES(NAME) -# ---------------------- -# See how the compiler implements dependency checking. -# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". -# We try a few techniques and use that to set a single cache variable. -# -# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was -# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular -# dependency, and given that the user is not expected to run this macro, -# just rely on AC_PROG_CC. -AC_DEFUN([_AM_DEPENDENCIES], -[AC_REQUIRE([AM_SET_DEPDIR])dnl -AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl -AC_REQUIRE([AM_MAKE_INCLUDE])dnl -AC_REQUIRE([AM_DEP_TRACK])dnl - -m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], - [$1], [CXX], [depcc="$CXX" am_compiler_list=], - [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], - [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], - [$1], [UPC], [depcc="$UPC" am_compiler_list=], - [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], - [depcc="$$1" am_compiler_list=]) - -AC_CACHE_CHECK([dependency style of $depcc], - [am_cv_$1_dependencies_compiler_type], -[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named 'D' -- because '-MD' means "put the output - # in D". - rm -rf conftest.dir - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_$1_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` - fi - am__universal=false - m4_case([$1], [CC], - [case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac], - [CXX], - [case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac]) - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with - # Solaris 10 /bin/sh. - echo '/* dummy */' > sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with '-c' and '-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle '-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs. - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # After this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested. - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok '-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_$1_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_$1_dependencies_compiler_type=none -fi -]) -AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) -AM_CONDITIONAL([am__fastdep$1], [ - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) -]) - - -# AM_SET_DEPDIR -# ------------- -# Choose a directory name for dependency files. -# This macro is AC_REQUIREd in _AM_DEPENDENCIES. -AC_DEFUN([AM_SET_DEPDIR], -[AC_REQUIRE([AM_SET_LEADING_DOT])dnl -AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl -]) - - -# AM_DEP_TRACK -# ------------ -AC_DEFUN([AM_DEP_TRACK], -[AC_ARG_ENABLE([dependency-tracking], [dnl -AS_HELP_STRING( - [--enable-dependency-tracking], - [do not reject slow dependency extractors]) -AS_HELP_STRING( - [--disable-dependency-tracking], - [speeds up one-time build])]) -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' - am__nodep='_no' -fi -AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) -AC_SUBST([AMDEPBACKSLASH])dnl -_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl -AC_SUBST([am__nodep])dnl -_AM_SUBST_NOTMAKE([am__nodep])dnl -]) - -# Generate code to set up dependency tracking. -*- Autoconf -*- - -# Copyright (C) 1999-2021 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_OUTPUT_DEPENDENCY_COMMANDS -# ------------------------------ -AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], -[{ - # Older Autoconf quotes --file arguments for eval, but not when files - # are listed without --file. Let's play safe and only enable the eval - # if we detect the quoting. - # TODO: see whether this extra hack can be removed once we start - # requiring Autoconf 2.70 or later. - AS_CASE([$CONFIG_FILES], - [*\'*], [eval set x "$CONFIG_FILES"], - [*], [set x $CONFIG_FILES]) - shift - # Used to flag and report bootstrapping failures. - am_rc=0 - for am_mf - do - # Strip MF so we end up with the name of the file. - am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile which includes - # dependency-tracking related rules and includes. - # Grep'ing the whole file directly is not great: AIX grep has a line - # limit of 2048, but all sed's we know have understand at least 4000. - sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ - || continue - am_dirpart=`AS_DIRNAME(["$am_mf"])` - am_filepart=`AS_BASENAME(["$am_mf"])` - AM_RUN_LOG([cd "$am_dirpart" \ - && sed -e '/# am--include-marker/d' "$am_filepart" \ - | $MAKE -f - am--depfiles]) || am_rc=$? - done - if test $am_rc -ne 0; then - AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments - for automatic dependency tracking. If GNU make was not used, consider - re-running the configure script with MAKE="gmake" (or whatever is - necessary). You can also try re-running configure with the - '--disable-dependency-tracking' option to at least be able to build - the package (albeit without support for automatic dependency tracking).]) - fi - AS_UNSET([am_dirpart]) - AS_UNSET([am_filepart]) - AS_UNSET([am_mf]) - AS_UNSET([am_rc]) - rm -f conftest-deps.mk -} -])# _AM_OUTPUT_DEPENDENCY_COMMANDS - - -# AM_OUTPUT_DEPENDENCY_COMMANDS -# ----------------------------- -# This macro should only be invoked once -- use via AC_REQUIRE. -# -# This code is only required when automatic dependency tracking is enabled. -# This creates each '.Po' and '.Plo' makefile fragment that we'll need in -# order to bootstrap the dependency handling code. -AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], -[AC_CONFIG_COMMANDS([depfiles], - [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], - [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) - -# Do all the work for Automake. -*- Autoconf -*- - -# Copyright (C) 1996-2021 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This macro actually does too much. Some checks are only needed if -# your package does certain things. But this isn't really a big deal. - -dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. -m4_define([AC_PROG_CC], -m4_defn([AC_PROG_CC]) -[_AM_PROG_CC_C_O -]) - -# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) -# AM_INIT_AUTOMAKE([OPTIONS]) -# ----------------------------------------------- -# The call with PACKAGE and VERSION arguments is the old style -# call (pre autoconf-2.50), which is being phased out. PACKAGE -# and VERSION should now be passed to AC_INIT and removed from -# the call to AM_INIT_AUTOMAKE. -# We support both call styles for the transition. After -# the next Automake release, Autoconf can make the AC_INIT -# arguments mandatory, and then we can depend on a new Autoconf -# release and drop the old call support. -AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.65])dnl -m4_ifdef([_$0_ALREADY_INIT], - [m4_fatal([$0 expanded multiple times -]m4_defn([_$0_ALREADY_INIT]))], - [m4_define([_$0_ALREADY_INIT], m4_expansion_stack)])dnl -dnl Autoconf wants to disallow AM_ names. We explicitly allow -dnl the ones we care about. -m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl -AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl -AC_REQUIRE([AC_PROG_INSTALL])dnl -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi -AC_SUBST([CYGPATH_W]) - -# Define the identity of the package. -dnl Distinguish between old-style and new-style calls. -m4_ifval([$2], -[AC_DIAGNOSE([obsolete], - [$0: two- and three-arguments forms are deprecated.]) -m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl - AC_SUBST([PACKAGE], [$1])dnl - AC_SUBST([VERSION], [$2])], -[_AM_SET_OPTIONS([$1])dnl -dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. -m4_if( - m4_ifset([AC_PACKAGE_NAME], [ok]):m4_ifset([AC_PACKAGE_VERSION], [ok]), - [ok:ok],, - [m4_fatal([AC_INIT should be called with package and version arguments])])dnl - AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl - AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl - -_AM_IF_OPTION([no-define],, -[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) - AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl - -# Some tools Automake needs. -AC_REQUIRE([AM_SANITY_CHECK])dnl -AC_REQUIRE([AC_ARG_PROGRAM])dnl -AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) -AM_MISSING_PROG([AUTOCONF], [autoconf]) -AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) -AM_MISSING_PROG([AUTOHEADER], [autoheader]) -AM_MISSING_PROG([MAKEINFO], [makeinfo]) -AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl -AC_REQUIRE([AC_PROG_MKDIR_P])dnl -# For better backward compatibility. To be removed once Automake 1.9.x -# dies out for good. For more background, see: -# -# -AC_SUBST([mkdir_p], ['$(MKDIR_P)']) -# We need awk for the "check" target (and possibly the TAP driver). The -# system "awk" is bad on some platforms. -AC_REQUIRE([AC_PROG_AWK])dnl -AC_REQUIRE([AC_PROG_MAKE_SET])dnl -AC_REQUIRE([AM_SET_LEADING_DOT])dnl -_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], - [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], - [_AM_PROG_TAR([v7])])]) -_AM_IF_OPTION([no-dependencies],, -[AC_PROVIDE_IFELSE([AC_PROG_CC], - [_AM_DEPENDENCIES([CC])], - [m4_define([AC_PROG_CC], - m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_CXX], - [_AM_DEPENDENCIES([CXX])], - [m4_define([AC_PROG_CXX], - m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_OBJC], - [_AM_DEPENDENCIES([OBJC])], - [m4_define([AC_PROG_OBJC], - m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], - [_AM_DEPENDENCIES([OBJCXX])], - [m4_define([AC_PROG_OBJCXX], - m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl -]) -# Variables for tags utilities; see am/tags.am -if test -z "$CTAGS"; then - CTAGS=ctags -fi -AC_SUBST([CTAGS]) -if test -z "$ETAGS"; then - ETAGS=etags -fi -AC_SUBST([ETAGS]) -if test -z "$CSCOPE"; then - CSCOPE=cscope -fi -AC_SUBST([CSCOPE]) - -AC_REQUIRE([AM_SILENT_RULES])dnl -dnl The testsuite driver may need to know about EXEEXT, so add the -dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This -dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. -AC_CONFIG_COMMANDS_PRE(dnl -[m4_provide_if([_AM_COMPILER_EXEEXT], - [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl - -# POSIX will say in a future version that running "rm -f" with no argument -# is OK; and we want to be able to make that assumption in our Makefile -# recipes. So use an aggressive probe to check that the usage we want is -# actually supported "in the wild" to an acceptable degree. -# See automake bug#10828. -# To make any issue more visible, cause the running configure to be aborted -# by default if the 'rm' program in use doesn't match our expectations; the -# user can still override this though. -if rm -f && rm -fr && rm -rf; then : OK; else - cat >&2 <<'END' -Oops! - -Your 'rm' program seems unable to run without file operands specified -on the command line, even when the '-f' option is present. This is contrary -to the behaviour of most rm programs out there, and not conforming with -the upcoming POSIX standard: - -Please tell bug-automake@gnu.org about your system, including the value -of your $PATH and any error possibly output before this message. This -can help us improve future automake versions. - -END - if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then - echo 'Configuration will proceed anyway, since you have set the' >&2 - echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 - echo >&2 - else - cat >&2 <<'END' -Aborting the configuration process, to ensure you take notice of the issue. - -You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . - -If you want to complete the configuration process using your problematic -'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM -to "yes", and re-run configure. - -END - AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) - fi -fi -dnl The trailing newline in this macro's definition is deliberate, for -dnl backward compatibility and to allow trailing 'dnl'-style comments -dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. -]) - -dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not -dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further -dnl mangled by Autoconf and run in a shell conditional statement. -m4_define([_AC_COMPILER_EXEEXT], -m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) - -# When config.status generates a header, we must update the stamp-h file. -# This file resides in the same directory as the config header -# that is generated. The stamp files are numbered to have different names. - -# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the -# loop where config.status creates the headers, so we can generate -# our stamp files there. -AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], -[# Compute $1's index in $config_headers. -_am_arg=$1 -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $_am_arg | $_am_arg:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) - -# Copyright (C) 2001-2021 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_INSTALL_SH -# ------------------ -# Define $install_sh. -AC_DEFUN([AM_PROG_INSTALL_SH], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -if test x"${install_sh+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi -AC_SUBST([install_sh])]) - -# Copyright (C) 2003-2021 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# Check whether the underlying file-system supports filenames -# with a leading dot. For instance MS-DOS doesn't. -AC_DEFUN([AM_SET_LEADING_DOT], -[rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null -AC_SUBST([am__leading_dot])]) - -# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- -# From Jim Meyering - -# Copyright (C) 1996-2021 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_MAINTAINER_MODE([DEFAULT-MODE]) -# ---------------------------------- -# Control maintainer-specific portions of Makefiles. -# Default is to disable them, unless 'enable' is passed literally. -# For symmetry, 'disable' may be passed as well. Anyway, the user -# can override the default with the --enable/--disable switch. -AC_DEFUN([AM_MAINTAINER_MODE], -[m4_case(m4_default([$1], [disable]), - [enable], [m4_define([am_maintainer_other], [disable])], - [disable], [m4_define([am_maintainer_other], [enable])], - [m4_define([am_maintainer_other], [enable]) - m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) -AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) - dnl maintainer-mode's default is 'disable' unless 'enable' is passed - AC_ARG_ENABLE([maintainer-mode], - [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], - am_maintainer_other[ make rules and dependencies not useful - (and sometimes confusing) to the casual installer])], - [USE_MAINTAINER_MODE=$enableval], - [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) - AC_MSG_RESULT([$USE_MAINTAINER_MODE]) - AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) - MAINT=$MAINTAINER_MODE_TRUE - AC_SUBST([MAINT])dnl -] -) - -# Check to see how 'make' treats includes. -*- Autoconf -*- - -# Copyright (C) 2001-2021 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_MAKE_INCLUDE() -# ----------------- -# Check whether make has an 'include' directive that can support all -# the idioms we need for our automatic dependency tracking code. -AC_DEFUN([AM_MAKE_INCLUDE], -[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) -cat > confinc.mk << 'END' -am__doit: - @echo this is the am__doit target >confinc.out -.PHONY: am__doit -END -am__include="#" -am__quote= -# BSD make does it like this. -echo '.include "confinc.mk" # ignored' > confmf.BSD -# Other make implementations (GNU, Solaris 10, AIX) do it like this. -echo 'include confinc.mk # ignored' > confmf.GNU -_am_result=no -for s in GNU BSD; do - AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) - AS_CASE([$?:`cat confinc.out 2>/dev/null`], - ['0:this is the am__doit target'], - [AS_CASE([$s], - [BSD], [am__include='.include' am__quote='"'], - [am__include='include' am__quote=''])]) - if test "$am__include" != "#"; then - _am_result="yes ($s style)" - break - fi -done -rm -f confinc.* confmf.* -AC_MSG_RESULT([${_am_result}]) -AC_SUBST([am__include])]) -AC_SUBST([am__quote])]) - -# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- - -# Copyright (C) 1997-2021 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_MISSING_PROG(NAME, PROGRAM) -# ------------------------------ -AC_DEFUN([AM_MISSING_PROG], -[AC_REQUIRE([AM_MISSING_HAS_RUN]) -$1=${$1-"${am_missing_run}$2"} -AC_SUBST($1)]) - -# AM_MISSING_HAS_RUN -# ------------------ -# Define MISSING if not defined so far and test if it is modern enough. -# If it is, set am_missing_run to use it, otherwise, to nothing. -AC_DEFUN([AM_MISSING_HAS_RUN], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([missing])dnl -if test x"${MISSING+set}" != xset; then - MISSING="\${SHELL} '$am_aux_dir/missing'" -fi -# Use eval to expand $SHELL -if eval "$MISSING --is-lightweight"; then - am_missing_run="$MISSING " -else - am_missing_run= - AC_MSG_WARN(['missing' script is too old or missing]) -fi -]) - -# Helper functions for option handling. -*- Autoconf -*- - -# Copyright (C) 2001-2021 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_MANGLE_OPTION(NAME) -# ----------------------- -AC_DEFUN([_AM_MANGLE_OPTION], -[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) - -# _AM_SET_OPTION(NAME) -# -------------------- -# Set option NAME. Presently that only means defining a flag for this option. -AC_DEFUN([_AM_SET_OPTION], -[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) - -# _AM_SET_OPTIONS(OPTIONS) -# ------------------------ -# OPTIONS is a space-separated list of Automake options. -AC_DEFUN([_AM_SET_OPTIONS], -[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) - -# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) -# ------------------------------------------- -# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. -AC_DEFUN([_AM_IF_OPTION], -[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) - -# Copyright (C) 1999-2021 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_PROG_CC_C_O -# --------------- -# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC -# to automatically call this. -AC_DEFUN([_AM_PROG_CC_C_O], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([compile])dnl -AC_LANG_PUSH([C])dnl -AC_CACHE_CHECK( - [whether $CC understands -c and -o together], - [am_cv_prog_cc_c_o], - [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) - # Make sure it works both with $CC and with simple cc. - # Following AC_PROG_CC_C_O, we do the test twice because some - # compilers refuse to overwrite an existing .o file with -o, - # though they will create one. - am_cv_prog_cc_c_o=yes - for am_i in 1 2; do - if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ - && test -f conftest2.$ac_objext; then - : OK - else - am_cv_prog_cc_c_o=no - break - fi - done - rm -f core conftest* - unset am_i]) -if test "$am_cv_prog_cc_c_o" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi -AC_LANG_POP([C])]) - -# For backward compatibility. -AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) - -# Copyright (C) 2001-2021 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_RUN_LOG(COMMAND) -# ------------------- -# Run COMMAND, save the exit status in ac_status, and log it. -# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) -AC_DEFUN([AM_RUN_LOG], -[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD - ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - (exit $ac_status); }]) - -# Check to make sure that the build environment is sane. -*- Autoconf -*- - -# Copyright (C) 1996-2021 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_SANITY_CHECK -# --------------- -AC_DEFUN([AM_SANITY_CHECK], -[AC_MSG_CHECKING([whether build environment is sane]) -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[[\\\"\#\$\&\'\`$am_lf]]*) - AC_MSG_ERROR([unsafe absolute working directory name]);; -esac -case $srcdir in - *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) - AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; -esac - -# Do 'set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken - alias in your environment]) - fi - if test "$[2]" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done - test "$[2]" = conftest.file - ) -then - # Ok. - : -else - AC_MSG_ERROR([newly created file is older than distributed files! -Check your system clock]) -fi -AC_MSG_RESULT([yes]) -# If we didn't sleep, we still need to ensure time stamps of config.status and -# generated files are strictly newer. -am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & - am_sleep_pid=$! -fi -AC_CONFIG_COMMANDS_PRE( - [AC_MSG_CHECKING([that generated files are newer than configure]) - if test -n "$am_sleep_pid"; then - # Hide warnings about reused PIDs. - wait $am_sleep_pid 2>/dev/null - fi - AC_MSG_RESULT([done])]) -rm -f conftest.file -]) - -# Copyright (C) 2009-2021 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_SILENT_RULES([DEFAULT]) -# -------------------------- -# Enable less verbose build rules; with the default set to DEFAULT -# ("yes" being less verbose, "no" or empty being verbose). -AC_DEFUN([AM_SILENT_RULES], -[AC_ARG_ENABLE([silent-rules], [dnl -AS_HELP_STRING( - [--enable-silent-rules], - [less verbose build output (undo: "make V=1")]) -AS_HELP_STRING( - [--disable-silent-rules], - [verbose build output (undo: "make V=0")])dnl -]) -case $enable_silent_rules in @%:@ ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; -esac -dnl -dnl A few 'make' implementations (e.g., NonStop OS and NextStep) -dnl do not support nested variable expansions. -dnl See automake bug#9928 and bug#10237. -am_make=${MAKE-make} -AC_CACHE_CHECK([whether $am_make supports nested variables], - [am_cv_make_support_nested_variables], - [if AS_ECHO([['TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi]) -if test $am_cv_make_support_nested_variables = yes; then - dnl Using '$V' instead of '$(V)' breaks IRIX make. - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AC_SUBST([AM_V])dnl -AM_SUBST_NOTMAKE([AM_V])dnl -AC_SUBST([AM_DEFAULT_V])dnl -AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl -AC_SUBST([AM_DEFAULT_VERBOSITY])dnl -AM_BACKSLASH='\' -AC_SUBST([AM_BACKSLASH])dnl -_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl -]) - -# Copyright (C) 2001-2021 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_INSTALL_STRIP -# --------------------- -# One issue with vendor 'install' (even GNU) is that you can't -# specify the program used to strip binaries. This is especially -# annoying in cross-compiling environments, where the build's strip -# is unlikely to handle the host's binaries. -# Fortunately install-sh will honor a STRIPPROG variable, so we -# always use install-sh in "make install-strip", and initialize -# STRIPPROG with the value of the STRIP variable (set by the user). -AC_DEFUN([AM_PROG_INSTALL_STRIP], -[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -# Installed binaries are usually stripped using 'strip' when the user -# run "make install-strip". However 'strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the 'STRIP' environment variable to overrule this program. -dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. -if test "$cross_compiling" != no; then - AC_CHECK_TOOL([STRIP], [strip], :) -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" -AC_SUBST([INSTALL_STRIP_PROGRAM])]) - -# Copyright (C) 2006-2021 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_SUBST_NOTMAKE(VARIABLE) -# --------------------------- -# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. -# This macro is traced by Automake. -AC_DEFUN([_AM_SUBST_NOTMAKE]) - -# AM_SUBST_NOTMAKE(VARIABLE) -# -------------------------- -# Public sister of _AM_SUBST_NOTMAKE. -AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) - -# Check how to create a tarball. -*- Autoconf -*- - -# Copyright (C) 2004-2021 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_PROG_TAR(FORMAT) -# -------------------- -# Check how to create a tarball in format FORMAT. -# FORMAT should be one of 'v7', 'ustar', or 'pax'. -# -# Substitute a variable $(am__tar) that is a command -# writing to stdout a FORMAT-tarball containing the directory -# $tardir. -# tardir=directory && $(am__tar) > result.tar -# -# Substitute a variable $(am__untar) that extract such -# a tarball read from stdin. -# $(am__untar) < result.tar -# -AC_DEFUN([_AM_PROG_TAR], -[# Always define AMTAR for backward compatibility. Yes, it's still used -# in the wild :-( We should find a proper way to deprecate it ... -AC_SUBST([AMTAR], ['$${TAR-tar}']) - -# We'll loop over all known methods to create a tar archive until one works. -_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' - -m4_if([$1], [v7], - [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], - - [m4_case([$1], - [ustar], - [# The POSIX 1988 'ustar' format is defined with fixed-size fields. - # There is notably a 21 bits limit for the UID and the GID. In fact, - # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 - # and bug#13588). - am_max_uid=2097151 # 2^21 - 1 - am_max_gid=$am_max_uid - # The $UID and $GID variables are not portable, so we need to resort - # to the POSIX-mandated id(1) utility. Errors in the 'id' calls - # below are definitely unexpected, so allow the users to see them - # (that is, avoid stderr redirection). - am_uid=`id -u || echo unknown` - am_gid=`id -g || echo unknown` - AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) - if test $am_uid -le $am_max_uid; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - _am_tools=none - fi - AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) - if test $am_gid -le $am_max_gid; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - _am_tools=none - fi], - - [pax], - [], - - [m4_fatal([Unknown tar format])]) - - AC_MSG_CHECKING([how to create a $1 tar archive]) - - # Go ahead even if we have the value already cached. We do so because we - # need to set the values for the 'am__tar' and 'am__untar' variables. - _am_tools=${am_cv_prog_tar_$1-$_am_tools} - - for _am_tool in $_am_tools; do - case $_am_tool in - gnutar) - for _am_tar in tar gnutar gtar; do - AM_RUN_LOG([$_am_tar --version]) && break - done - am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' - am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' - am__untar="$_am_tar -xf -" - ;; - plaintar) - # Must skip GNU tar: if it does not support --format= it doesn't create - # ustar tarball either. - (tar --version) >/dev/null 2>&1 && continue - am__tar='tar chf - "$$tardir"' - am__tar_='tar chf - "$tardir"' - am__untar='tar xf -' - ;; - pax) - am__tar='pax -L -x $1 -w "$$tardir"' - am__tar_='pax -L -x $1 -w "$tardir"' - am__untar='pax -r' - ;; - cpio) - am__tar='find "$$tardir" -print | cpio -o -H $1 -L' - am__tar_='find "$tardir" -print | cpio -o -H $1 -L' - am__untar='cpio -i -H $1 -d' - ;; - none) - am__tar=false - am__tar_=false - am__untar=false - ;; - esac - - # If the value was cached, stop now. We just wanted to have am__tar - # and am__untar set. - test -n "${am_cv_prog_tar_$1}" && break - - # tar/untar a dummy directory, and stop if the command works. - rm -rf conftest.dir - mkdir conftest.dir - echo GrepMe > conftest.dir/file - AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) - rm -rf conftest.dir - if test -s conftest.tar; then - AM_RUN_LOG([$am__untar /dev/null 2>&1 && break - fi - done - rm -rf conftest.dir - - AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) - AC_MSG_RESULT([$am_cv_prog_tar_$1])]) - -AC_SUBST([am__tar]) -AC_SUBST([am__untar]) -]) # _AM_PROG_TAR - -m4_include([build/autoconf/ax_append_compile_flags.m4]) -m4_include([build/autoconf/ax_append_flag.m4]) -m4_include([build/autoconf/ax_check_compile_flag.m4]) -m4_include([build/autoconf/ax_require_defined.m4]) -m4_include([build/autoconf/check_stdcall_func.m4]) -m4_include([build/autoconf/iconv.m4]) -m4_include([build/autoconf/la_uid_t.m4]) -m4_include([build/autoconf/lib-ld.m4]) -m4_include([build/autoconf/lib-link.m4]) -m4_include([build/autoconf/lib-prefix.m4]) -m4_include([build/autoconf/m4_ax_compile_check_sizeof.m4]) diff --git a/thirdparty/libarchive/build/autoconf/ax_append_compile_flags.m4 b/thirdparty/libarchive/build/autoconf/ax_append_compile_flags.m4 deleted file mode 100644 index 2bb27ef2b..000000000 --- a/thirdparty/libarchive/build/autoconf/ax_append_compile_flags.m4 +++ /dev/null @@ -1,67 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_append_compile_flags.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_APPEND_COMPILE_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS], [INPUT]) -# -# DESCRIPTION -# -# For every FLAG1, FLAG2 it is checked whether the compiler works with the -# flag. If it does, the flag is added FLAGS-VARIABLE -# -# If FLAGS-VARIABLE is not specified, the current language's flags (e.g. -# CFLAGS) is used. During the check the flag is always added to the -# current language's flags. -# -# If EXTRA-FLAGS is defined, it is added to the current language's default -# flags (e.g. CFLAGS) when the check is done. The check is thus made with -# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to -# force the compiler to issue an error when a bad flag is given. -# -# INPUT gives an alternative input source to AC_COMPILE_IFELSE. -# -# NOTE: This macro depends on the AX_APPEND_FLAG and -# AX_CHECK_COMPILE_FLAG. Please keep this macro in sync with -# AX_APPEND_LINK_FLAGS. -# -# LICENSE -# -# Copyright (c) 2011 Maarten Bosmans -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 5 - -AC_DEFUN([AX_APPEND_COMPILE_FLAGS], -[AX_REQUIRE_DEFINED([AX_CHECK_COMPILE_FLAG]) -AX_REQUIRE_DEFINED([AX_APPEND_FLAG]) -for flag in $1; do - AX_CHECK_COMPILE_FLAG([$flag], [AX_APPEND_FLAG([$flag], [$2])], [], [$3], [$4]) -done -])dnl AX_APPEND_COMPILE_FLAGS diff --git a/thirdparty/libarchive/build/autoconf/ax_append_flag.m4 b/thirdparty/libarchive/build/autoconf/ax_append_flag.m4 deleted file mode 100644 index 08f2e07ec..000000000 --- a/thirdparty/libarchive/build/autoconf/ax_append_flag.m4 +++ /dev/null @@ -1,71 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_append_flag.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE]) -# -# DESCRIPTION -# -# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space -# added in between. -# -# If FLAGS-VARIABLE is not specified, the current language's flags (e.g. -# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains -# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly -# FLAG. -# -# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. -# -# LICENSE -# -# Copyright (c) 2008 Guido U. Draheim -# Copyright (c) 2011 Maarten Bosmans -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 6 - -AC_DEFUN([AX_APPEND_FLAG], -[dnl -AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF -AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])]) -AS_VAR_SET_IF(FLAGS,[ - AS_CASE([" AS_VAR_GET(FLAGS) "], - [*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])], - [ - AS_VAR_APPEND(FLAGS,[" $1"]) - AC_RUN_LOG([: FLAGS="$FLAGS"]) - ]) - ], - [ - AS_VAR_SET(FLAGS,[$1]) - AC_RUN_LOG([: FLAGS="$FLAGS"]) - ]) -AS_VAR_POPDEF([FLAGS])dnl -])dnl AX_APPEND_FLAG diff --git a/thirdparty/libarchive/build/autoconf/ax_check_compile_flag.m4 b/thirdparty/libarchive/build/autoconf/ax_check_compile_flag.m4 deleted file mode 100644 index ca3639715..000000000 --- a/thirdparty/libarchive/build/autoconf/ax_check_compile_flag.m4 +++ /dev/null @@ -1,74 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) -# -# DESCRIPTION -# -# Check whether the given FLAG works with the current language's compiler -# or gives an error. (Warnings, however, are ignored) -# -# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on -# success/failure. -# -# If EXTRA-FLAGS is defined, it is added to the current language's default -# flags (e.g. CFLAGS) when the check is done. The check is thus made with -# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to -# force the compiler to issue an error when a bad flag is given. -# -# INPUT gives an alternative input source to AC_COMPILE_IFELSE. -# -# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this -# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. -# -# LICENSE -# -# Copyright (c) 2008 Guido U. Draheim -# Copyright (c) 2011 Maarten Bosmans -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 4 - -AC_DEFUN([AX_CHECK_COMPILE_FLAG], -[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF -AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl -AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ - ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS - _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" - AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], - [AS_VAR_SET(CACHEVAR,[yes])], - [AS_VAR_SET(CACHEVAR,[no])]) - _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) -AS_VAR_IF(CACHEVAR,yes, - [m4_default([$2], :)], - [m4_default([$3], :)]) -AS_VAR_POPDEF([CACHEVAR])dnl -])dnl AX_CHECK_COMPILE_FLAGS diff --git a/thirdparty/libarchive/build/autoconf/ax_require_defined.m4 b/thirdparty/libarchive/build/autoconf/ax_require_defined.m4 deleted file mode 100644 index cae11112d..000000000 --- a/thirdparty/libarchive/build/autoconf/ax_require_defined.m4 +++ /dev/null @@ -1,37 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_require_defined.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_REQUIRE_DEFINED(MACRO) -# -# DESCRIPTION -# -# AX_REQUIRE_DEFINED is a simple helper for making sure other macros have -# been defined and thus are available for use. This avoids random issues -# where a macro isn't expanded. Instead the configure script emits a -# non-fatal: -# -# ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found -# -# It's like AC_REQUIRE except it doesn't expand the required macro. -# -# Here's an example: -# -# AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG]) -# -# LICENSE -# -# Copyright (c) 2014 Mike Frysinger -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 1 - -AC_DEFUN([AX_REQUIRE_DEFINED], [dnl - m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])]) -])dnl AX_REQUIRE_DEFINED diff --git a/thirdparty/libarchive/build/autoconf/check_stdcall_func.m4 b/thirdparty/libarchive/build/autoconf/check_stdcall_func.m4 deleted file mode 100644 index 926b046c5..000000000 --- a/thirdparty/libarchive/build/autoconf/check_stdcall_func.m4 +++ /dev/null @@ -1,51 +0,0 @@ -# AC_LANG_STDCALL_FUNC_LINK_TRY(FUNCTION, SIGNATURE) -# ------------------------------- -# Produce a source which links correctly iff the FUNCTION exists. -AC_DEFUN([AC_LANG_STDCALL_FUNC_LINK_TRY], -[_AC_LANG_DISPATCH([$0], _AC_LANG, $@)]) - -# AC_CHECK_STDCALL_FUNC(FUNCTION, SIGNATURE, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -# ----------------------------------------------------------------- -AC_DEFUN([AC_CHECK_STDCALL_FUNC], -[AS_VAR_PUSHDEF([ac_var], [ac_cv_func_$1])dnl -AC_CACHE_CHECK([for $1], ac_var, -[AC_LINK_IFELSE([AC_LANG_STDCALL_FUNC_LINK_TRY([$1],[$2])], - [AS_VAR_SET(ac_var, yes)], - [AS_VAR_SET(ac_var, no)])]) -AS_IF([test AS_VAR_GET(ac_var) = yes], [$3], [$4])dnl -AS_VAR_POPDEF([ac_var])dnl -])# AC_CHECK_FUNC - -# AC_LANG_STDCALL_FUNC_LINK_TRY(C)(FUNCTION, SIGNATURE) -# ---------------------------------- -# Don't include because on OSF/1 3.0 it includes -# which includes which contains a -# prototype for select. Similarly for bzero. -m4_define([AC_LANG_STDCALL_FUNC_LINK_TRY(C)], -[AC_LANG_PROGRAM( -[/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char __stdcall $1 ( $2 ) below. */ -#include -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char __stdcall $1 ( $2 ); -char (*f) ( $2 ); -], -[/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$1) || defined (__stub___$1) -choke me -#else -f = $1; -#endif -])]) - -# AC_LANG_STDCALL_FUNC_LINK_TRY(C++)(FUNCTION) -# ------------------------------------ -m4_copy([AC_LANG_STDCALL_FUNC_LINK_TRY(C)], [AC_LANG_STDCALL_FUNC_LINK_TRY(C++)]) - diff --git a/thirdparty/libarchive/build/autoconf/compile b/thirdparty/libarchive/build/autoconf/compile deleted file mode 100755 index df363c8fb..000000000 --- a/thirdparty/libarchive/build/autoconf/compile +++ /dev/null @@ -1,348 +0,0 @@ -#! /bin/sh -# Wrapper for compilers which do not understand '-c -o'. - -scriptversion=2018-03-07.03; # UTC - -# Copyright (C) 1999-2021 Free Software Foundation, Inc. -# Written by Tom Tromey . -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# This file is maintained in Automake, please report -# bugs to or send patches to -# . - -nl=' -' - -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent tools from complaining about whitespace usage. -IFS=" "" $nl" - -file_conv= - -# func_file_conv build_file lazy -# Convert a $build file to $host form and store it in $file -# Currently only supports Windows hosts. If the determined conversion -# type is listed in (the comma separated) LAZY, no conversion will -# take place. -func_file_conv () -{ - file=$1 - case $file in - / | /[!/]*) # absolute file, and not a UNC file - if test -z "$file_conv"; then - # lazily determine how to convert abs files - case `uname -s` in - MINGW*) - file_conv=mingw - ;; - CYGWIN* | MSYS*) - file_conv=cygwin - ;; - *) - file_conv=wine - ;; - esac - fi - case $file_conv/,$2, in - *,$file_conv,*) - ;; - mingw/*) - file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` - ;; - cygwin/* | msys/*) - file=`cygpath -m "$file" || echo "$file"` - ;; - wine/*) - file=`winepath -w "$file" || echo "$file"` - ;; - esac - ;; - esac -} - -# func_cl_dashL linkdir -# Make cl look for libraries in LINKDIR -func_cl_dashL () -{ - func_file_conv "$1" - if test -z "$lib_path"; then - lib_path=$file - else - lib_path="$lib_path;$file" - fi - linker_opts="$linker_opts -LIBPATH:$file" -} - -# func_cl_dashl library -# Do a library search-path lookup for cl -func_cl_dashl () -{ - lib=$1 - found=no - save_IFS=$IFS - IFS=';' - for dir in $lib_path $LIB - do - IFS=$save_IFS - if $shared && test -f "$dir/$lib.dll.lib"; then - found=yes - lib=$dir/$lib.dll.lib - break - fi - if test -f "$dir/$lib.lib"; then - found=yes - lib=$dir/$lib.lib - break - fi - if test -f "$dir/lib$lib.a"; then - found=yes - lib=$dir/lib$lib.a - break - fi - done - IFS=$save_IFS - - if test "$found" != yes; then - lib=$lib.lib - fi -} - -# func_cl_wrapper cl arg... -# Adjust compile command to suit cl -func_cl_wrapper () -{ - # Assume a capable shell - lib_path= - shared=: - linker_opts= - for arg - do - if test -n "$eat"; then - eat= - else - case $1 in - -o) - # configure might choose to run compile as 'compile cc -o foo foo.c'. - eat=1 - case $2 in - *.o | *.[oO][bB][jJ]) - func_file_conv "$2" - set x "$@" -Fo"$file" - shift - ;; - *) - func_file_conv "$2" - set x "$@" -Fe"$file" - shift - ;; - esac - ;; - -I) - eat=1 - func_file_conv "$2" mingw - set x "$@" -I"$file" - shift - ;; - -I*) - func_file_conv "${1#-I}" mingw - set x "$@" -I"$file" - shift - ;; - -l) - eat=1 - func_cl_dashl "$2" - set x "$@" "$lib" - shift - ;; - -l*) - func_cl_dashl "${1#-l}" - set x "$@" "$lib" - shift - ;; - -L) - eat=1 - func_cl_dashL "$2" - ;; - -L*) - func_cl_dashL "${1#-L}" - ;; - -static) - shared=false - ;; - -Wl,*) - arg=${1#-Wl,} - save_ifs="$IFS"; IFS=',' - for flag in $arg; do - IFS="$save_ifs" - linker_opts="$linker_opts $flag" - done - IFS="$save_ifs" - ;; - -Xlinker) - eat=1 - linker_opts="$linker_opts $2" - ;; - -*) - set x "$@" "$1" - shift - ;; - *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) - func_file_conv "$1" - set x "$@" -Tp"$file" - shift - ;; - *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) - func_file_conv "$1" mingw - set x "$@" "$file" - shift - ;; - *) - set x "$@" "$1" - shift - ;; - esac - fi - shift - done - if test -n "$linker_opts"; then - linker_opts="-link$linker_opts" - fi - exec "$@" $linker_opts - exit 1 -} - -eat= - -case $1 in - '') - echo "$0: No command. Try '$0 --help' for more information." 1>&2 - exit 1; - ;; - -h | --h*) - cat <<\EOF -Usage: compile [--help] [--version] PROGRAM [ARGS] - -Wrapper for compilers which do not understand '-c -o'. -Remove '-o dest.o' from ARGS, run PROGRAM with the remaining -arguments, and rename the output as expected. - -If you are trying to build a whole package this is not the -right script to run: please start by reading the file 'INSTALL'. - -Report bugs to . -EOF - exit $? - ;; - -v | --v*) - echo "compile $scriptversion" - exit $? - ;; - cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ - icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) - func_cl_wrapper "$@" # Doesn't return... - ;; -esac - -ofile= -cfile= - -for arg -do - if test -n "$eat"; then - eat= - else - case $1 in - -o) - # configure might choose to run compile as 'compile cc -o foo foo.c'. - # So we strip '-o arg' only if arg is an object. - eat=1 - case $2 in - *.o | *.obj) - ofile=$2 - ;; - *) - set x "$@" -o "$2" - shift - ;; - esac - ;; - *.c) - cfile=$1 - set x "$@" "$1" - shift - ;; - *) - set x "$@" "$1" - shift - ;; - esac - fi - shift -done - -if test -z "$ofile" || test -z "$cfile"; then - # If no '-o' option was seen then we might have been invoked from a - # pattern rule where we don't need one. That is ok -- this is a - # normal compilation that the losing compiler can handle. If no - # '.c' file was seen then we are probably linking. That is also - # ok. - exec "$@" -fi - -# Name of file we expect compiler to create. -cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` - -# Create the lock directory. -# Note: use '[/\\:.-]' here to ensure that we don't use the same name -# that we are using for the .o file. Also, base the name on the expected -# object file name, since that is what matters with a parallel build. -lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d -while true; do - if mkdir "$lockdir" >/dev/null 2>&1; then - break - fi - sleep 1 -done -# FIXME: race condition here if user kills between mkdir and trap. -trap "rmdir '$lockdir'; exit 1" 1 2 15 - -# Run the compile. -"$@" -ret=$? - -if test -f "$cofile"; then - test "$cofile" = "$ofile" || mv "$cofile" "$ofile" -elif test -f "${cofile}bj"; then - test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" -fi - -rmdir "$lockdir" -exit $ret - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC0" -# time-stamp-end: "; # UTC" -# End: diff --git a/thirdparty/libarchive/build/autoconf/config.guess b/thirdparty/libarchive/build/autoconf/config.guess deleted file mode 100755 index 7f76b6228..000000000 --- a/thirdparty/libarchive/build/autoconf/config.guess +++ /dev/null @@ -1,1754 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright 1992-2022 Free Software Foundation, Inc. - -# shellcheck disable=SC2006,SC2268 # see below for rationale - -timestamp='2022-01-09' - -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, see . -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that -# program. This Exception is an additional permission under section 7 -# of the GNU General Public License, version 3 ("GPLv3"). -# -# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. -# -# You can get the latest version of this script from: -# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess -# -# Please send patches to . - - -# The "shellcheck disable" line above the timestamp inhibits complaints -# about features and limitations of the classic Bourne shell that were -# superseded or lifted in POSIX. However, this script identifies a wide -# variety of pre-POSIX systems that do not have POSIX shells at all, and -# even some reasonably current systems (Solaris 10 as case-in-point) still -# have a pre-POSIX /bin/sh. - - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Options: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright 1992-2022 Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - -# Just in case it came from the environment. -GUESS= - -# CC_FOR_BUILD -- compiler used by this script. Note that the use of a -# compiler to aid in system detection is discouraged as it requires -# temporary files to be created and, as you can see below, it is a -# headache to deal with in a portable fashion. - -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -# Portable tmp directory creation inspired by the Autoconf team. - -tmp= -# shellcheck disable=SC2172 -trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 - -set_cc_for_build() { - # prevent multiple calls if $tmp is already set - test "$tmp" && return 0 - : "${TMPDIR=/tmp}" - # shellcheck disable=SC2039,SC3028 - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } - dummy=$tmp/dummy - case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in - ,,) echo "int x;" > "$dummy.c" - for driver in cc gcc c89 c99 ; do - if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then - CC_FOR_BUILD=$driver - break - fi - done - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; - esac -} - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if test -f /.attbin/uname ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -case $UNAME_SYSTEM in -Linux|GNU|GNU/*) - LIBC=unknown - - set_cc_for_build - cat <<-EOF > "$dummy.c" - #include - #if defined(__UCLIBC__) - LIBC=uclibc - #elif defined(__dietlibc__) - LIBC=dietlibc - #elif defined(__GLIBC__) - LIBC=gnu - #else - #include - /* First heuristic to detect musl libc. */ - #ifdef __DEFINED_va_list - LIBC=musl - #endif - #endif - EOF - cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` - eval "$cc_set_libc" - - # Second heuristic to detect musl libc. - if [ "$LIBC" = unknown ] && - command -v ldd >/dev/null && - ldd --version 2>&1 | grep -q ^musl; then - LIBC=musl - fi - - # If the system lacks a compiler, then just pick glibc. - # We could probably try harder. - if [ "$LIBC" = unknown ]; then - LIBC=gnu - fi - ;; -esac - -# Note: order is significant - the case branches are not exclusive. - -case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ - /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ - /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ - echo unknown)` - case $UNAME_MACHINE_ARCH in - aarch64eb) machine=aarch64_be-unknown ;; - armeb) machine=armeb-unknown ;; - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - sh5el) machine=sh5le-unknown ;; - earmv*) - arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` - endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` - machine=${arch}${endian}-unknown - ;; - *) machine=$UNAME_MACHINE_ARCH-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently (or will in the future) and ABI. - case $UNAME_MACHINE_ARCH in - earm*) - os=netbsdelf - ;; - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ELF__ - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # Determine ABI tags. - case $UNAME_MACHINE_ARCH in - earm*) - expr='s/^earmv[0-9]/-eabi/;s/eb$//' - abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` - ;; - esac - # The OS release - # Debian GNU/NetBSD machines have a different userland, and - # thus, need a distinct triplet. However, they do not need - # kernel version information, so it can be replaced with a - # suitable tag, in the style of linux-gnu. - case $UNAME_VERSION in - Debian*) - release='-gnu' - ;; - *) - release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` - ;; - esac - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - GUESS=$machine-${os}${release}${abi-} - ;; - *:Bitrig:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` - GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE - ;; - *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE - ;; - *:SecBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'` - GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE - ;; - *:LibertyBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` - GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE - ;; - *:MidnightBSD:*:*) - GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE - ;; - *:ekkoBSD:*:*) - GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE - ;; - *:SolidBSD:*:*) - GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE - ;; - *:OS108:*:*) - GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE - ;; - macppc:MirBSD:*:*) - GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE - ;; - *:MirBSD:*:*) - GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE - ;; - *:Sortix:*:*) - GUESS=$UNAME_MACHINE-unknown-sortix - ;; - *:Twizzler:*:*) - GUESS=$UNAME_MACHINE-unknown-twizzler - ;; - *:Redox:*:*) - GUESS=$UNAME_MACHINE-unknown-redox - ;; - mips:OSF1:*.*) - GUESS=mips-dec-osf1 - ;; - alpha:OSF1:*:*) - # Reset EXIT trap before exiting to avoid spurious non-zero exit code. - trap '' 0 - case $UNAME_RELEASE in - *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - ;; - *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` - ;; - esac - # According to Compaq, /usr/sbin/psrinfo has been available on - # OSF/1 and Tru64 systems produced since 1995. I hope that - # covers most systems running today. This code pipes the CPU - # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case $ALPHA_CPU_TYPE in - "EV4 (21064)") - UNAME_MACHINE=alpha ;; - "EV4.5 (21064)") - UNAME_MACHINE=alpha ;; - "LCA4 (21066/21068)") - UNAME_MACHINE=alpha ;; - "EV5 (21164)") - UNAME_MACHINE=alphaev5 ;; - "EV5.6 (21164A)") - UNAME_MACHINE=alphaev56 ;; - "EV5.6 (21164PC)") - UNAME_MACHINE=alphapca56 ;; - "EV5.7 (21164PC)") - UNAME_MACHINE=alphapca57 ;; - "EV6 (21264)") - UNAME_MACHINE=alphaev6 ;; - "EV6.7 (21264A)") - UNAME_MACHINE=alphaev67 ;; - "EV6.8CB (21264C)") - UNAME_MACHINE=alphaev68 ;; - "EV6.8AL (21264B)") - UNAME_MACHINE=alphaev68 ;; - "EV6.8CX (21264D)") - UNAME_MACHINE=alphaev68 ;; - "EV6.9A (21264/EV69A)") - UNAME_MACHINE=alphaev69 ;; - "EV7 (21364)") - UNAME_MACHINE=alphaev7 ;; - "EV7.9 (21364A)") - UNAME_MACHINE=alphaev79 ;; - esac - # A Pn.n version is a patched version. - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` - GUESS=$UNAME_MACHINE-dec-osf$OSF_REL - ;; - Amiga*:UNIX_System_V:4.0:*) - GUESS=m68k-unknown-sysv4 - ;; - *:[Aa]miga[Oo][Ss]:*:*) - GUESS=$UNAME_MACHINE-unknown-amigaos - ;; - *:[Mm]orph[Oo][Ss]:*:*) - GUESS=$UNAME_MACHINE-unknown-morphos - ;; - *:OS/390:*:*) - GUESS=i370-ibm-openedition - ;; - *:z/VM:*:*) - GUESS=s390-ibm-zvmoe - ;; - *:OS400:*:*) - GUESS=powerpc-ibm-os400 - ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - GUESS=arm-acorn-riscix$UNAME_RELEASE - ;; - arm*:riscos:*:*|arm*:RISCOS:*:*) - GUESS=arm-unknown-riscos - ;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - GUESS=hppa1.1-hitachi-hiuxmpp - ;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - case `(/bin/universe) 2>/dev/null` in - att) GUESS=pyramid-pyramid-sysv3 ;; - *) GUESS=pyramid-pyramid-bsd ;; - esac - ;; - NILE*:*:*:dcosx) - GUESS=pyramid-pyramid-svr4 - ;; - DRS?6000:unix:4.0:6*) - GUESS=sparc-icl-nx6 - ;; - DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in - sparc) GUESS=sparc-icl-nx7 ;; - esac - ;; - s390x:SunOS:*:*) - SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` - GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL - ;; - sun4H:SunOS:5.*:*) - SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` - GUESS=sparc-hal-solaris2$SUN_REL - ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` - GUESS=sparc-sun-solaris2$SUN_REL - ;; - i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - GUESS=i386-pc-auroraux$UNAME_RELEASE - ;; - i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - set_cc_for_build - SUN_ARCH=i386 - # If there is a compiler, see if it is configured for 64-bit objects. - # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. - # This test works for both compilers. - if test "$CC_FOR_BUILD" != no_compiler_found; then - if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - SUN_ARCH=x86_64 - fi - fi - SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` - GUESS=$SUN_ARCH-pc-solaris2$SUN_REL - ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` - GUESS=sparc-sun-solaris3$SUN_REL - ;; - sun4*:SunOS:*:*) - case `/usr/bin/arch -k` in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` - GUESS=sparc-sun-sunos$SUN_REL - ;; - sun3*:SunOS:*:*) - GUESS=m68k-sun-sunos$UNAME_RELEASE - ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 - case `/bin/arch` in - sun3) - GUESS=m68k-sun-sunos$UNAME_RELEASE - ;; - sun4) - GUESS=sparc-sun-sunos$UNAME_RELEASE - ;; - esac - ;; - aushp:SunOS:*:*) - GUESS=sparc-auspex-sunos$UNAME_RELEASE - ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - GUESS=m68k-atari-mint$UNAME_RELEASE - ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - GUESS=m68k-atari-mint$UNAME_RELEASE - ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - GUESS=m68k-atari-mint$UNAME_RELEASE - ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - GUESS=m68k-milan-mint$UNAME_RELEASE - ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - GUESS=m68k-hades-mint$UNAME_RELEASE - ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - GUESS=m68k-unknown-mint$UNAME_RELEASE - ;; - m68k:machten:*:*) - GUESS=m68k-apple-machten$UNAME_RELEASE - ;; - powerpc:machten:*:*) - GUESS=powerpc-apple-machten$UNAME_RELEASE - ;; - RISC*:Mach:*:*) - GUESS=mips-dec-mach_bsd4.3 - ;; - RISC*:ULTRIX:*:*) - GUESS=mips-dec-ultrix$UNAME_RELEASE - ;; - VAX*:ULTRIX*:*:*) - GUESS=vax-dec-ultrix$UNAME_RELEASE - ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - GUESS=clipper-intergraph-clix$UNAME_RELEASE - ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - set_cc_for_build - sed 's/^ //' << EOF > "$dummy.c" -#ifdef __cplusplus -#include /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD -o "$dummy" "$dummy.c" && - dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`"$dummy" "$dummyarg"` && - { echo "$SYSTEM_NAME"; exit; } - GUESS=mips-mips-riscos$UNAME_RELEASE - ;; - Motorola:PowerMAX_OS:*:*) - GUESS=powerpc-motorola-powermax - ;; - Motorola:*:4.3:PL8-*) - GUESS=powerpc-harris-powermax - ;; - Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - GUESS=powerpc-harris-powermax - ;; - Night_Hawk:Power_UNIX:*:*) - GUESS=powerpc-harris-powerunix - ;; - m88k:CX/UX:7*:*) - GUESS=m88k-harris-cxux7 - ;; - m88k:*:4*:R4*) - GUESS=m88k-motorola-sysv4 - ;; - m88k:*:3*:R3*) - GUESS=m88k-motorola-sysv3 - ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 - then - if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ - test "$TARGET_BINARY_INTERFACE"x = x - then - GUESS=m88k-dg-dgux$UNAME_RELEASE - else - GUESS=m88k-dg-dguxbcs$UNAME_RELEASE - fi - else - GUESS=i586-dg-dgux$UNAME_RELEASE - fi - ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - GUESS=m88k-dolphin-sysv3 - ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - GUESS=m88k-motorola-sysv3 - ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - GUESS=m88k-tektronix-sysv3 - ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - GUESS=m68k-tektronix-bsd - ;; - *:IRIX*:*:*) - IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'` - GUESS=mips-sgi-irix$IRIX_REL - ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id - ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - GUESS=i386-ibm-aix - ;; - ia64:AIX:*:*) - if test -x /usr/bin/oslevel ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=$UNAME_VERSION.$UNAME_RELEASE - fi - GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV - ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - set_cc_for_build - sed 's/^ //' << EOF > "$dummy.c" - #include - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` - then - GUESS=$SYSTEM_NAME - else - GUESS=rs6000-ibm-aix3.2.5 - fi - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - GUESS=rs6000-ibm-aix3.2.4 - else - GUESS=rs6000-ibm-aix3.2 - fi - ;; - *:AIX:*:[4567]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if test -x /usr/bin/lslpp ; then - IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \ - awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` - else - IBM_REV=$UNAME_VERSION.$UNAME_RELEASE - fi - GUESS=$IBM_ARCH-ibm-aix$IBM_REV - ;; - *:AIX:*:*) - GUESS=rs6000-ibm-aix - ;; - ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) - GUESS=romp-ibm-bsd4.4 - ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to - ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - GUESS=rs6000-bull-bosx - ;; - DPX/2?00:B.O.S.:*:*) - GUESS=m68k-bull-sysv3 - ;; - 9000/[34]??:4.3bsd:1.*:*) - GUESS=m68k-hp-bsd - ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - GUESS=m68k-hp-bsd4.4 - ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` - case $UNAME_MACHINE in - 9000/31?) HP_ARCH=m68000 ;; - 9000/[34]??) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - if test -x /usr/bin/getconf; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case $sc_cpu_version in - 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 - 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case $sc_kernel_bits in - 32) HP_ARCH=hppa2.0n ;; - 64) HP_ARCH=hppa2.0w ;; - '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 - esac ;; - esac - fi - if test "$HP_ARCH" = ""; then - set_cc_for_build - sed 's/^ //' << EOF > "$dummy.c" - - #define _HPUX_SOURCE - #include - #include - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` - test -z "$HP_ARCH" && HP_ARCH=hppa - fi ;; - esac - if test "$HP_ARCH" = hppa2.0w - then - set_cc_for_build - - # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating - # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler - # generating 64-bit code. GNU and HP use different nomenclature: - # - # $ CC_FOR_BUILD=cc ./config.guess - # => hppa2.0w-hp-hpux11.23 - # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess - # => hppa64-hp-hpux11.23 - - if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | - grep -q __LP64__ - then - HP_ARCH=hppa2.0w - else - HP_ARCH=hppa64 - fi - fi - GUESS=$HP_ARCH-hp-hpux$HPUX_REV - ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` - GUESS=ia64-hp-hpux$HPUX_REV - ;; - 3050*:HI-UX:*:*) - set_cc_for_build - sed 's/^ //' << EOF > "$dummy.c" - #include - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && - { echo "$SYSTEM_NAME"; exit; } - GUESS=unknown-hitachi-hiuxwe2 - ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) - GUESS=hppa1.1-hp-bsd - ;; - 9000/8??:4.3bsd:*:*) - GUESS=hppa1.0-hp-bsd - ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - GUESS=hppa1.0-hp-mpeix - ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) - GUESS=hppa1.1-hp-osf - ;; - hp8??:OSF1:*:*) - GUESS=hppa1.0-hp-osf - ;; - i*86:OSF1:*:*) - if test -x /usr/sbin/sysversion ; then - GUESS=$UNAME_MACHINE-unknown-osf1mk - else - GUESS=$UNAME_MACHINE-unknown-osf1 - fi - ;; - parisc*:Lites*:*:*) - GUESS=hppa1.1-hp-lites - ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - GUESS=c1-convex-bsd - ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - GUESS=c34-convex-bsd - ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - GUESS=c38-convex-bsd - ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - GUESS=c4-convex-bsd - ;; - CRAY*Y-MP:*:*:*) - CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` - GUESS=ymp-cray-unicos$CRAY_REL - ;; - CRAY*[A-Z]90:*:*:*) - echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*TS:*:*:*) - CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` - GUESS=t90-cray-unicos$CRAY_REL - ;; - CRAY*T3E:*:*:*) - CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` - GUESS=alphaev5-cray-unicosmk$CRAY_REL - ;; - CRAY*SV1:*:*:*) - CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` - GUESS=sv1-cray-unicos$CRAY_REL - ;; - *:UNICOS/mp:*:*) - CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` - GUESS=craynv-cray-unicosmp$CRAY_REL - ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` - FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` - GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} - ;; - 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` - GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} - ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE - ;; - sparc*:BSD/OS:*:*) - GUESS=sparc-unknown-bsdi$UNAME_RELEASE - ;; - *:BSD/OS:*:*) - GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE - ;; - arm:FreeBSD:*:*) - UNAME_PROCESSOR=`uname -p` - set_cc_for_build - if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_PCS_VFP - then - FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` - GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi - else - FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` - GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf - fi - ;; - *:FreeBSD:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` - case $UNAME_PROCESSOR in - amd64) - UNAME_PROCESSOR=x86_64 ;; - i386) - UNAME_PROCESSOR=i586 ;; - esac - FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` - GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL - ;; - i*:CYGWIN*:*) - GUESS=$UNAME_MACHINE-pc-cygwin - ;; - *:MINGW64*:*) - GUESS=$UNAME_MACHINE-pc-mingw64 - ;; - *:MINGW*:*) - GUESS=$UNAME_MACHINE-pc-mingw32 - ;; - *:MSYS*:*) - GUESS=$UNAME_MACHINE-pc-msys - ;; - i*:PW*:*) - GUESS=$UNAME_MACHINE-pc-pw32 - ;; - *:SerenityOS:*:*) - GUESS=$UNAME_MACHINE-pc-serenity - ;; - *:Interix*:*) - case $UNAME_MACHINE in - x86) - GUESS=i586-pc-interix$UNAME_RELEASE - ;; - authenticamd | genuineintel | EM64T) - GUESS=x86_64-unknown-interix$UNAME_RELEASE - ;; - IA64) - GUESS=ia64-unknown-interix$UNAME_RELEASE - ;; - esac ;; - i*:UWIN*:*) - GUESS=$UNAME_MACHINE-pc-uwin - ;; - amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - GUESS=x86_64-pc-cygwin - ;; - prep*:SunOS:5.*:*) - SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` - GUESS=powerpcle-unknown-solaris2$SUN_REL - ;; - *:GNU:*:*) - # the GNU system - GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'` - GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'` - GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL - ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland - GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"` - GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` - GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC - ;; - *:Minix:*:*) - GUESS=$UNAME_MACHINE-unknown-minix - ;; - aarch64:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - aarch64_be:Linux:*:*) - UNAME_MACHINE=aarch64_be - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC=gnulibc1 ; fi - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - arm*:Linux:*:*) - set_cc_for_build - if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_EABI__ - then - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - else - if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_PCS_VFP - then - GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi - else - GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf - fi - fi - ;; - avr32*:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - cris:Linux:*:*) - GUESS=$UNAME_MACHINE-axis-linux-$LIBC - ;; - crisv32:Linux:*:*) - GUESS=$UNAME_MACHINE-axis-linux-$LIBC - ;; - e2k:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - frv:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - hexagon:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - i*86:Linux:*:*) - GUESS=$UNAME_MACHINE-pc-linux-$LIBC - ;; - ia64:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - k1om:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - m32r*:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - m68*:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - mips:Linux:*:* | mips64:Linux:*:*) - set_cc_for_build - IS_GLIBC=0 - test x"${LIBC}" = xgnu && IS_GLIBC=1 - sed 's/^ //' << EOF > "$dummy.c" - #undef CPU - #undef mips - #undef mipsel - #undef mips64 - #undef mips64el - #if ${IS_GLIBC} && defined(_ABI64) - LIBCABI=gnuabi64 - #else - #if ${IS_GLIBC} && defined(_ABIN32) - LIBCABI=gnuabin32 - #else - LIBCABI=${LIBC} - #endif - #endif - - #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 - CPU=mipsisa64r6 - #else - #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 - CPU=mipsisa32r6 - #else - #if defined(__mips64) - CPU=mips64 - #else - CPU=mips - #endif - #endif - #endif - - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - MIPS_ENDIAN=el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - MIPS_ENDIAN= - #else - MIPS_ENDIAN= - #endif - #endif -EOF - cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'` - eval "$cc_set_vars" - test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } - ;; - mips64el:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - openrisc*:Linux:*:*) - GUESS=or1k-unknown-linux-$LIBC - ;; - or32:Linux:*:* | or1k*:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - padre:Linux:*:*) - GUESS=sparc-unknown-linux-$LIBC - ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - GUESS=hppa64-unknown-linux-$LIBC - ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;; - PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;; - *) GUESS=hppa-unknown-linux-$LIBC ;; - esac - ;; - ppc64:Linux:*:*) - GUESS=powerpc64-unknown-linux-$LIBC - ;; - ppc:Linux:*:*) - GUESS=powerpc-unknown-linux-$LIBC - ;; - ppc64le:Linux:*:*) - GUESS=powerpc64le-unknown-linux-$LIBC - ;; - ppcle:Linux:*:*) - GUESS=powerpcle-unknown-linux-$LIBC - ;; - riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - s390:Linux:*:* | s390x:Linux:*:*) - GUESS=$UNAME_MACHINE-ibm-linux-$LIBC - ;; - sh64*:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - sh*:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - tile*:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - vax:Linux:*:*) - GUESS=$UNAME_MACHINE-dec-linux-$LIBC - ;; - x86_64:Linux:*:*) - set_cc_for_build - LIBCABI=$LIBC - if test "$CC_FOR_BUILD" != no_compiler_found; then - if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_X32 >/dev/null - then - LIBCABI=${LIBC}x32 - fi - fi - GUESS=$UNAME_MACHINE-pc-linux-$LIBCABI - ;; - xtensa*:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC - ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - GUESS=i386-sequent-sysv4 - ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION - ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - GUESS=$UNAME_MACHINE-pc-os2-emx - ;; - i*86:XTS-300:*:STOP) - GUESS=$UNAME_MACHINE-unknown-stop - ;; - i*86:atheos:*:*) - GUESS=$UNAME_MACHINE-unknown-atheos - ;; - i*86:syllable:*:*) - GUESS=$UNAME_MACHINE-pc-syllable - ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - GUESS=i386-unknown-lynxos$UNAME_RELEASE - ;; - i*86:*DOS:*:*) - GUESS=$UNAME_MACHINE-pc-msdosdjgpp - ;; - i*86:*:4.*:*) - UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL - else - GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL - fi - ;; - i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` - (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL - else - GUESS=$UNAME_MACHINE-pc-sysv32 - fi - ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i586. - # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configure will decide that - # this is a cross-build. - GUESS=i586-pc-msdosdjgpp - ;; - Intel:Mach:3*:*) - GUESS=i386-pc-mach3 - ;; - paragon:*:*:*) - GUESS=i860-intel-osf1 - ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4 - fi - ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - GUESS=m68010-convergent-sysv - ;; - mc68k:UNIX:SYSTEM5:3.51m) - GUESS=m68k-convergent-sysv - ;; - M680?0:D-NIX:5.3:*) - GUESS=m68k-diab-dnix - ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; - NCR*:*:4.2:* | MPRAS*:*:4.2:*) - OS_REL='.3' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } - /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - GUESS=m68k-unknown-lynxos$UNAME_RELEASE - ;; - mc68030:UNIX_System_V:4.*:*) - GUESS=m68k-atari-sysv4 - ;; - TSUNAMI:LynxOS:2.*:*) - GUESS=sparc-unknown-lynxos$UNAME_RELEASE - ;; - rs6000:LynxOS:2.*:*) - GUESS=rs6000-unknown-lynxos$UNAME_RELEASE - ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - GUESS=powerpc-unknown-lynxos$UNAME_RELEASE - ;; - SM[BE]S:UNIX_SV:*:*) - GUESS=mips-dde-sysv$UNAME_RELEASE - ;; - RM*:ReliantUNIX-*:*:*) - GUESS=mips-sni-sysv4 - ;; - RM*:SINIX-*:*:*) - GUESS=mips-sni-sysv4 - ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - GUESS=$UNAME_MACHINE-sni-sysv4 - else - GUESS=ns32k-sni-sysv - fi - ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - GUESS=i586-unisys-sysv4 - ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes . - # How about differentiating between stratus architectures? -djm - GUESS=hppa1.1-stratus-sysv4 - ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - GUESS=i860-stratus-sysv4 - ;; - i*86:VOS:*:*) - # From Paul.Green@stratus.com. - GUESS=$UNAME_MACHINE-stratus-vos - ;; - *:VOS:*:*) - # From Paul.Green@stratus.com. - GUESS=hppa1.1-stratus-vos - ;; - mc68*:A/UX:*:*) - GUESS=m68k-apple-aux$UNAME_RELEASE - ;; - news*:NEWS-OS:6*:*) - GUESS=mips-sony-newsos6 - ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if test -d /usr/nec; then - GUESS=mips-nec-sysv$UNAME_RELEASE - else - GUESS=mips-unknown-sysv$UNAME_RELEASE - fi - ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - GUESS=powerpc-be-beos - ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - GUESS=powerpc-apple-beos - ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - GUESS=i586-pc-beos - ;; - BePC:Haiku:*:*) # Haiku running on Intel PC compatible. - GUESS=i586-pc-haiku - ;; - x86_64:Haiku:*:*) - GUESS=x86_64-unknown-haiku - ;; - SX-4:SUPER-UX:*:*) - GUESS=sx4-nec-superux$UNAME_RELEASE - ;; - SX-5:SUPER-UX:*:*) - GUESS=sx5-nec-superux$UNAME_RELEASE - ;; - SX-6:SUPER-UX:*:*) - GUESS=sx6-nec-superux$UNAME_RELEASE - ;; - SX-7:SUPER-UX:*:*) - GUESS=sx7-nec-superux$UNAME_RELEASE - ;; - SX-8:SUPER-UX:*:*) - GUESS=sx8-nec-superux$UNAME_RELEASE - ;; - SX-8R:SUPER-UX:*:*) - GUESS=sx8r-nec-superux$UNAME_RELEASE - ;; - SX-ACE:SUPER-UX:*:*) - GUESS=sxace-nec-superux$UNAME_RELEASE - ;; - Power*:Rhapsody:*:*) - GUESS=powerpc-apple-rhapsody$UNAME_RELEASE - ;; - *:Rhapsody:*:*) - GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE - ;; - arm64:Darwin:*:*) - GUESS=aarch64-apple-darwin$UNAME_RELEASE - ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` - case $UNAME_PROCESSOR in - unknown) UNAME_PROCESSOR=powerpc ;; - esac - if command -v xcode-select > /dev/null 2> /dev/null && \ - ! xcode-select --print-path > /dev/null 2> /dev/null ; then - # Avoid executing cc if there is no toolchain installed as - # cc will be a stub that puts up a graphical alert - # prompting the user to install developer tools. - CC_FOR_BUILD=no_compiler_found - else - set_cc_for_build - fi - if test "$CC_FOR_BUILD" != no_compiler_found; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - case $UNAME_PROCESSOR in - i386) UNAME_PROCESSOR=x86_64 ;; - powerpc) UNAME_PROCESSOR=powerpc64 ;; - esac - fi - # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc - if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_PPC >/dev/null - then - UNAME_PROCESSOR=powerpc - fi - elif test "$UNAME_PROCESSOR" = i386 ; then - # uname -m returns i386 or x86_64 - UNAME_PROCESSOR=$UNAME_MACHINE - fi - GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE - ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = x86; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE - ;; - *:QNX:*:4*) - GUESS=i386-pc-qnx - ;; - NEO-*:NONSTOP_KERNEL:*:*) - GUESS=neo-tandem-nsk$UNAME_RELEASE - ;; - NSE-*:NONSTOP_KERNEL:*:*) - GUESS=nse-tandem-nsk$UNAME_RELEASE - ;; - NSR-*:NONSTOP_KERNEL:*:*) - GUESS=nsr-tandem-nsk$UNAME_RELEASE - ;; - NSV-*:NONSTOP_KERNEL:*:*) - GUESS=nsv-tandem-nsk$UNAME_RELEASE - ;; - NSX-*:NONSTOP_KERNEL:*:*) - GUESS=nsx-tandem-nsk$UNAME_RELEASE - ;; - *:NonStop-UX:*:*) - GUESS=mips-compaq-nonstopux - ;; - BS2000:POSIX*:*:*) - GUESS=bs2000-siemens-sysv - ;; - DS/*:UNIX_System_V:*:*) - GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE - ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "${cputype-}" = 386; then - UNAME_MACHINE=i386 - elif test "x${cputype-}" != x; then - UNAME_MACHINE=$cputype - fi - GUESS=$UNAME_MACHINE-unknown-plan9 - ;; - *:TOPS-10:*:*) - GUESS=pdp10-unknown-tops10 - ;; - *:TENEX:*:*) - GUESS=pdp10-unknown-tenex - ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - GUESS=pdp10-dec-tops20 - ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - GUESS=pdp10-xkl-tops20 - ;; - *:TOPS-20:*:*) - GUESS=pdp10-unknown-tops20 - ;; - *:ITS:*:*) - GUESS=pdp10-unknown-its - ;; - SEI:*:*:SEIUX) - GUESS=mips-sei-seiux$UNAME_RELEASE - ;; - *:DragonFly:*:*) - DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` - GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL - ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case $UNAME_MACHINE in - A*) GUESS=alpha-dec-vms ;; - I*) GUESS=ia64-dec-vms ;; - V*) GUESS=vax-dec-vms ;; - esac ;; - *:XENIX:*:SysV) - GUESS=i386-pc-xenix - ;; - i*86:skyos:*:*) - SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'` - GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL - ;; - i*86:rdos:*:*) - GUESS=$UNAME_MACHINE-pc-rdos - ;; - i*86:Fiwix:*:*) - GUESS=$UNAME_MACHINE-pc-fiwix - ;; - *:AROS:*:*) - GUESS=$UNAME_MACHINE-unknown-aros - ;; - x86_64:VMkernel:*:*) - GUESS=$UNAME_MACHINE-unknown-esx - ;; - amd64:Isilon\ OneFS:*:*) - GUESS=x86_64-unknown-onefs - ;; - *:Unleashed:*:*) - GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE - ;; -esac - -# Do we have a guess based on uname results? -if test "x$GUESS" != x; then - echo "$GUESS" - exit -fi - -# No uname command or uname output not recognized. -set_cc_for_build -cat > "$dummy.c" < -#include -#endif -#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) -#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) -#include -#if defined(_SIZE_T_) || defined(SIGLOST) -#include -#endif -#endif -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); -#endif - -#if defined (vax) -#if !defined (ultrix) -#include -#if defined (BSD) -#if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -#else -#if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -#else - printf ("vax-dec-bsd\n"); exit (0); -#endif -#endif -#else - printf ("vax-dec-bsd\n"); exit (0); -#endif -#else -#if defined(_SIZE_T_) || defined(SIGLOST) - struct utsname un; - uname (&un); - printf ("vax-dec-ultrix%s\n", un.release); exit (0); -#else - printf ("vax-dec-ultrix\n"); exit (0); -#endif -#endif -#endif -#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) -#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) -#if defined(_SIZE_T_) || defined(SIGLOST) - struct utsname *un; - uname (&un); - printf ("mips-dec-ultrix%s\n", un.release); exit (0); -#else - printf ("mips-dec-ultrix\n"); exit (0); -#endif -#endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` && - { echo "$SYSTEM_NAME"; exit; } - -# Apollos put the system type in the environment. -test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } - -echo "$0: unable to guess system type" >&2 - -case $UNAME_MACHINE:$UNAME_SYSTEM in - mips:Linux | mips64:Linux) - # If we got here on MIPS GNU/Linux, output extra information. - cat >&2 <&2 <&2 </dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = "$UNAME_MACHINE" -UNAME_RELEASE = "$UNAME_RELEASE" -UNAME_SYSTEM = "$UNAME_SYSTEM" -UNAME_VERSION = "$UNAME_VERSION" -EOF -fi - -exit 1 - -# Local variables: -# eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/thirdparty/libarchive/build/autoconf/config.rpath b/thirdparty/libarchive/build/autoconf/config.rpath deleted file mode 100755 index 51cf442a2..000000000 --- a/thirdparty/libarchive/build/autoconf/config.rpath +++ /dev/null @@ -1,696 +0,0 @@ -#! /bin/sh -# -# NOTE: This file was brought from -# http://git.savannah.gnu.org/cgit/gnulib.git/plain/build-aux/config.rpath -# You should sometimes check if the file is updated and bring it to -# our trunk and copy this note to the top of that file. -# -# Output a system dependent set of variables, describing how to set the -# run time search path of shared libraries in an executable. -# -# Copyright 1996-2011 Free Software Foundation, Inc. -# Taken from GNU libtool, 2001 -# Originally by Gordon Matzigkeit , 1996 -# -# This file is free software; the Free Software Foundation gives -# unlimited permission to copy and/or distribute it, with or without -# modifications, as long as this notice is preserved. -# -# The first argument passed to this file is the canonical host specification, -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld -# should be set by the caller. -# -# The set of defined variables is at the end of this script. - -# Known limitations: -# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer -# than 256 bytes, otherwise the compiler driver will dump core. The only -# known workaround is to choose shorter directory names for the build -# directory and/or the installation directory. - -# All known linkers require a `.a' archive for static linking (except MSVC, -# which needs '.lib'). -libext=a -shrext=.so - -host="$1" -host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` -host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` -host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` - -# Code taken from libtool.m4's _LT_CC_BASENAME. - -for cc_temp in $CC""; do - case $cc_temp in - compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; - distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'` - -# Code taken from libtool.m4's _LT_COMPILER_PIC. - -wl= -if test "$GCC" = yes; then - wl='-Wl,' -else - case "$host_os" in - aix*) - wl='-Wl,' - ;; - mingw* | cygwin* | msys* | pw32* | os2* | cegcc*) - ;; - hpux9* | hpux10* | hpux11*) - wl='-Wl,' - ;; - irix5* | irix6* | nonstopux*) - wl='-Wl,' - ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) - case $cc_basename in - ecc*) - wl='-Wl,' - ;; - icc* | ifort*) - wl='-Wl,' - ;; - lf95*) - wl='-Wl,' - ;; - nagfor*) - wl='-Wl,-Wl,,' - ;; - pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) - wl='-Wl,' - ;; - ccc*) - wl='-Wl,' - ;; - xl* | bgxl* | bgf* | mpixl*) - wl='-Wl,' - ;; - como) - wl='-lopt=' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ F* | *Sun*Fortran*) - wl= - ;; - *Sun\ C*) - wl='-Wl,' - ;; - esac - ;; - esac - ;; - newsos6) - ;; - *nto* | *qnx*) - ;; - osf3* | osf4* | osf5*) - wl='-Wl,' - ;; - rdos*) - ;; - solaris*) - case $cc_basename in - f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) - wl='-Qoption ld ' - ;; - *) - wl='-Wl,' - ;; - esac - ;; - sunos4*) - wl='-Qoption ld ' - ;; - sysv4 | sysv4.2uw2* | sysv4.3*) - wl='-Wl,' - ;; - sysv4*MP*) - ;; - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - wl='-Wl,' - ;; - unicos*) - wl='-Wl,' - ;; - uts4*) - ;; - esac -fi - -# Code taken from libtool.m4's _LT_LINKER_SHLIBS. - -hardcode_libdir_flag_spec= -hardcode_libdir_separator= -hardcode_direct=no -hardcode_minus_L=no - -case "$host_os" in - cygwin* | msys* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) - with_gnu_ld=yes - ;; - openbsd*) - with_gnu_ld=no - ;; -esac - -ld_shlibs=yes -if test "$with_gnu_ld" = yes; then - # Set some defaults for GNU ld with shared library support. These - # are reset later if shared libraries are not supported. Putting them - # here allows them to be overridden if necessary. - # Unlike libtool, we use -rpath here, not --rpath, since the documented - # option of GNU ld is called -rpath, not --rpath. - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - case "$host_os" in - aix[3-9]*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - ld_shlibs=no - fi - ;; - amigaos*) - case "$host_cpu" in - powerpc) - ;; - m68k) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - ;; - esac - ;; - beos*) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - : - else - ld_shlibs=no - fi - ;; - cygwin* | msys* | mingw* | pw32* | cegcc*) - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec='-L$libdir' - if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - : - else - ld_shlibs=no - fi - ;; - haiku*) - ;; - interix[3-9]*) - hardcode_direct=no - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - ;; - gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - : - else - ld_shlibs=no - fi - ;; - netbsd*) - ;; - solaris*) - if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then - ld_shlibs=no - elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - : - else - ld_shlibs=no - fi - ;; - sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) - case `$LD -v 2>&1` in - *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) - ld_shlibs=no - ;; - *) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' - else - ld_shlibs=no - fi - ;; - esac - ;; - sunos4*) - hardcode_direct=yes - ;; - *) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - : - else - ld_shlibs=no - fi - ;; - esac - if test "$ld_shlibs" = no; then - hardcode_libdir_flag_spec= - fi -else - case "$host_os" in - aix3*) - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - hardcode_minus_L=yes - if test "$GCC" = yes; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - hardcode_direct=unsupported - fi - ;; - aix[4-9]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - else - aix_use_runtimelinking=no - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - ;; - esac - fi - hardcode_direct=yes - hardcode_libdir_separator=':' - if test "$GCC" = yes; then - case $host_os in aix4.[012]|aix4.[012].*) - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && \ - strings "$collect2name" | grep resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - hardcode_direct=unsupported - hardcode_minus_L=yes - hardcode_libdir_flag_spec='-L$libdir' - hardcode_libdir_separator= - fi - ;; - esac - fi - # Begin _LT_AC_SYS_LIBPATH_AIX. - echo 'int main () { return 0; }' > conftest.c - ${CC} ${LDFLAGS} conftest.c -o conftest - aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` - if test -z "$aix_libpath"; then - aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` - fi - if test -z "$aix_libpath"; then - aix_libpath="/usr/lib:/lib" - fi - rm -f conftest.c conftest - # End _LT_AC_SYS_LIBPATH_AIX. - if test "$aix_use_runtimelinking" = yes; then - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' - else - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - fi - fi - ;; - amigaos*) - case "$host_cpu" in - powerpc) - ;; - m68k) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - ;; - esac - ;; - bsdi[45]*) - ;; - cygwin* | msys* | mingw* | pw32* | cegcc*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec=' ' - libext=lib - ;; - darwin* | rhapsody*) - hardcode_direct=no - if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then - : - else - ld_shlibs=no - fi - ;; - dgux*) - hardcode_libdir_flag_spec='-L$libdir' - ;; - freebsd2.2*) - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - ;; - freebsd2*) - hardcode_direct=yes - hardcode_minus_L=yes - ;; - freebsd* | dragonfly*) - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - ;; - hpux9*) - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - ;; - hpux10*) - if test "$with_gnu_ld" = no; then - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - fi - ;; - hpux11*) - if test "$with_gnu_ld" = no; then - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - case $host_cpu in - hppa*64*|ia64*) - hardcode_direct=no - ;; - *) - hardcode_direct=yes - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - ;; - esac - fi - ;; - irix5* | irix6* | nonstopux*) - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - netbsd*) - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - ;; - newsos6) - hardcode_direct=yes - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - *nto* | *qnx*) - ;; - openbsd*) - if test -f /usr/libexec/ld.so; then - hardcode_direct=yes - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - else - case "$host_os" in - openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) - hardcode_libdir_flag_spec='-R$libdir' - ;; - *) - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - ;; - esac - fi - else - ld_shlibs=no - fi - ;; - os2*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - ;; - osf3*) - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - osf4* | osf5*) - if test "$GCC" = yes; then - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - else - # Both cc and cxx compiler support -rpath directly - hardcode_libdir_flag_spec='-rpath $libdir' - fi - hardcode_libdir_separator=: - ;; - solaris*) - hardcode_libdir_flag_spec='-R$libdir' - ;; - sunos4*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_direct=yes - hardcode_minus_L=yes - ;; - sysv4) - case $host_vendor in - sni) - hardcode_direct=yes # is this really true??? - ;; - siemens) - hardcode_direct=no - ;; - motorola) - hardcode_direct=no #Motorola manual says yes, but my tests say they lie - ;; - esac - ;; - sysv4.3*) - ;; - sysv4*MP*) - if test -d /usr/nec; then - ld_shlibs=yes - fi - ;; - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) - ;; - sysv5* | sco3.2v5* | sco5v6*) - hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' - hardcode_libdir_separator=':' - ;; - uts4*) - hardcode_libdir_flag_spec='-L$libdir' - ;; - *) - ld_shlibs=no - ;; - esac -fi - -# Check dynamic linker characteristics -# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER. -# Unlike libtool.m4, here we don't care about _all_ names of the library, but -# only about the one the linker finds when passed -lNAME. This is the last -# element of library_names_spec in libtool.m4, or possibly two of them if the -# linker has special search rules. -library_names_spec= # the last element of library_names_spec in libtool.m4 -libname_spec='lib$name' -case "$host_os" in - aix3*) - library_names_spec='$libname.a' - ;; - aix[4-9]*) - library_names_spec='$libname$shrext' - ;; - amigaos*) - case "$host_cpu" in - powerpc*) - library_names_spec='$libname$shrext' ;; - m68k) - library_names_spec='$libname.a' ;; - esac - ;; - beos*) - library_names_spec='$libname$shrext' - ;; - bsdi[45]*) - library_names_spec='$libname$shrext' - ;; - cygwin* | msys* | mingw* | pw32* | cegcc*) - shrext=.dll - library_names_spec='$libname.dll.a $libname.lib' - ;; - darwin* | rhapsody*) - shrext=.dylib - library_names_spec='$libname$shrext' - ;; - dgux*) - library_names_spec='$libname$shrext' - ;; - freebsd* | dragonfly*) - case "$host_os" in - freebsd[123]*) - library_names_spec='$libname$shrext$versuffix' ;; - *) - library_names_spec='$libname$shrext' ;; - esac - ;; - gnu*) - library_names_spec='$libname$shrext' - ;; - haiku*) - library_names_spec='$libname$shrext' - ;; - hpux9* | hpux10* | hpux11*) - case $host_cpu in - ia64*) - shrext=.so - ;; - hppa*64*) - shrext=.sl - ;; - *) - shrext=.sl - ;; - esac - library_names_spec='$libname$shrext' - ;; - interix[3-9]*) - library_names_spec='$libname$shrext' - ;; - irix5* | irix6* | nonstopux*) - library_names_spec='$libname$shrext' - case "$host_os" in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;; - *) libsuff= shlibsuff= ;; - esac - ;; - esac - ;; - linux*oldld* | linux*aout* | linux*coff*) - ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) - library_names_spec='$libname$shrext' - ;; - knetbsd*-gnu) - library_names_spec='$libname$shrext' - ;; - netbsd*) - library_names_spec='$libname$shrext' - ;; - newsos6) - library_names_spec='$libname$shrext' - ;; - *nto* | *qnx*) - library_names_spec='$libname$shrext' - ;; - openbsd*) - library_names_spec='$libname$shrext$versuffix' - ;; - os2*) - libname_spec='$name' - shrext=.dll - library_names_spec='$libname.a' - ;; - osf3* | osf4* | osf5*) - library_names_spec='$libname$shrext' - ;; - rdos*) - ;; - solaris*) - library_names_spec='$libname$shrext' - ;; - sunos4*) - library_names_spec='$libname$shrext$versuffix' - ;; - sysv4 | sysv4.3*) - library_names_spec='$libname$shrext' - ;; - sysv4*MP*) - library_names_spec='$libname$shrext' - ;; - sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - library_names_spec='$libname$shrext' - ;; - tpf*) - library_names_spec='$libname$shrext' - ;; - uts4*) - library_names_spec='$libname$shrext' - ;; -esac - -sed_quote_subst='s/\(["`$\\]\)/\\\1/g' -escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` -shlibext=`echo "$shrext" | sed -e 's,^\.,,'` -escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` -escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` -escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` - -LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that -# program. This Exception is an additional permission under section 7 -# of the GNU General Public License, version 3 ("GPLv3"). - - -# Please send patches to . -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# You can get the latest version of this script from: -# https://git.savannah.gnu.org/cgit/config.git/plain/config.sub - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -# The "shellcheck disable" line above the timestamp inhibits complaints -# about features and limitations of the classic Bourne shell that were -# superseded or lifted in POSIX. However, this script identifies a wide -# variety of pre-POSIX systems that do not have POSIX shells at all, and -# even some reasonably current systems (Solaris 10 as case-in-point) still -# have a pre-POSIX /bin/sh. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS - -Canonicalize a configuration name. - -Options: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.sub ($timestamp) - -Copyright 1992-2022 Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo "$1" - exit ;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -esac - -# Split fields of configuration type -# shellcheck disable=SC2162 -saved_IFS=$IFS -IFS="-" read field1 field2 field3 field4 <&2 - exit 1 - ;; - *-*-*-*) - basic_machine=$field1-$field2 - basic_os=$field3-$field4 - ;; - *-*-*) - # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two - # parts - maybe_os=$field2-$field3 - case $maybe_os in - nto-qnx* | linux-* | uclinux-uclibc* \ - | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ - | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ - | storm-chaos* | os2-emx* | rtmk-nova*) - basic_machine=$field1 - basic_os=$maybe_os - ;; - android-linux) - basic_machine=$field1-unknown - basic_os=linux-android - ;; - *) - basic_machine=$field1-$field2 - basic_os=$field3 - ;; - esac - ;; - *-*) - # A lone config we happen to match not fitting any pattern - case $field1-$field2 in - decstation-3100) - basic_machine=mips-dec - basic_os= - ;; - *-*) - # Second component is usually, but not always the OS - case $field2 in - # Prevent following clause from handling this valid os - sun*os*) - basic_machine=$field1 - basic_os=$field2 - ;; - zephyr*) - basic_machine=$field1-unknown - basic_os=$field2 - ;; - # Manufacturers - dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ - | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ - | unicom* | ibm* | next | hp | isi* | apollo | altos* \ - | convergent* | ncr* | news | 32* | 3600* | 3100* \ - | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ - | ultra | tti* | harris | dolphin | highlevel | gould \ - | cbm | ns | masscomp | apple | axis | knuth | cray \ - | microblaze* | sim | cisco \ - | oki | wec | wrs | winbond) - basic_machine=$field1-$field2 - basic_os= - ;; - *) - basic_machine=$field1 - basic_os=$field2 - ;; - esac - ;; - esac - ;; - *) - # Convert single-component short-hands not valid as part of - # multi-component configurations. - case $field1 in - 386bsd) - basic_machine=i386-pc - basic_os=bsd - ;; - a29khif) - basic_machine=a29k-amd - basic_os=udi - ;; - adobe68k) - basic_machine=m68010-adobe - basic_os=scout - ;; - alliant) - basic_machine=fx80-alliant - basic_os= - ;; - altos | altos3068) - basic_machine=m68k-altos - basic_os= - ;; - am29k) - basic_machine=a29k-none - basic_os=bsd - ;; - amdahl) - basic_machine=580-amdahl - basic_os=sysv - ;; - amiga) - basic_machine=m68k-unknown - basic_os= - ;; - amigaos | amigados) - basic_machine=m68k-unknown - basic_os=amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - basic_os=sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - basic_os=sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - basic_os=bsd - ;; - aros) - basic_machine=i386-pc - basic_os=aros - ;; - aux) - basic_machine=m68k-apple - basic_os=aux - ;; - balance) - basic_machine=ns32k-sequent - basic_os=dynix - ;; - blackfin) - basic_machine=bfin-unknown - basic_os=linux - ;; - cegcc) - basic_machine=arm-unknown - basic_os=cegcc - ;; - convex-c1) - basic_machine=c1-convex - basic_os=bsd - ;; - convex-c2) - basic_machine=c2-convex - basic_os=bsd - ;; - convex-c32) - basic_machine=c32-convex - basic_os=bsd - ;; - convex-c34) - basic_machine=c34-convex - basic_os=bsd - ;; - convex-c38) - basic_machine=c38-convex - basic_os=bsd - ;; - cray) - basic_machine=j90-cray - basic_os=unicos - ;; - crds | unos) - basic_machine=m68k-crds - basic_os= - ;; - da30) - basic_machine=m68k-da30 - basic_os= - ;; - decstation | pmax | pmin | dec3100 | decstatn) - basic_machine=mips-dec - basic_os= - ;; - delta88) - basic_machine=m88k-motorola - basic_os=sysv3 - ;; - dicos) - basic_machine=i686-pc - basic_os=dicos - ;; - djgpp) - basic_machine=i586-pc - basic_os=msdosdjgpp - ;; - ebmon29k) - basic_machine=a29k-amd - basic_os=ebmon - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - basic_os=ose - ;; - gmicro) - basic_machine=tron-gmicro - basic_os=sysv - ;; - go32) - basic_machine=i386-pc - basic_os=go32 - ;; - h8300hms) - basic_machine=h8300-hitachi - basic_os=hms - ;; - h8300xray) - basic_machine=h8300-hitachi - basic_os=xray - ;; - h8500hms) - basic_machine=h8500-hitachi - basic_os=hms - ;; - harris) - basic_machine=m88k-harris - basic_os=sysv3 - ;; - hp300 | hp300hpux) - basic_machine=m68k-hp - basic_os=hpux - ;; - hp300bsd) - basic_machine=m68k-hp - basic_os=bsd - ;; - hppaosf) - basic_machine=hppa1.1-hp - basic_os=osf - ;; - hppro) - basic_machine=hppa1.1-hp - basic_os=proelf - ;; - i386mach) - basic_machine=i386-mach - basic_os=mach - ;; - isi68 | isi) - basic_machine=m68k-isi - basic_os=sysv - ;; - m68knommu) - basic_machine=m68k-unknown - basic_os=linux - ;; - magnum | m3230) - basic_machine=mips-mips - basic_os=sysv - ;; - merlin) - basic_machine=ns32k-utek - basic_os=sysv - ;; - mingw64) - basic_machine=x86_64-pc - basic_os=mingw64 - ;; - mingw32) - basic_machine=i686-pc - basic_os=mingw32 - ;; - mingw32ce) - basic_machine=arm-unknown - basic_os=mingw32ce - ;; - monitor) - basic_machine=m68k-rom68k - basic_os=coff - ;; - morphos) - basic_machine=powerpc-unknown - basic_os=morphos - ;; - moxiebox) - basic_machine=moxie-unknown - basic_os=moxiebox - ;; - msdos) - basic_machine=i386-pc - basic_os=msdos - ;; - msys) - basic_machine=i686-pc - basic_os=msys - ;; - mvs) - basic_machine=i370-ibm - basic_os=mvs - ;; - nacl) - basic_machine=le32-unknown - basic_os=nacl - ;; - ncr3000) - basic_machine=i486-ncr - basic_os=sysv4 - ;; - netbsd386) - basic_machine=i386-pc - basic_os=netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - basic_os=linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - basic_os=newsos - ;; - news1000) - basic_machine=m68030-sony - basic_os=newsos - ;; - necv70) - basic_machine=v70-nec - basic_os=sysv - ;; - nh3000) - basic_machine=m68k-harris - basic_os=cxux - ;; - nh[45]000) - basic_machine=m88k-harris - basic_os=cxux - ;; - nindy960) - basic_machine=i960-intel - basic_os=nindy - ;; - mon960) - basic_machine=i960-intel - basic_os=mon960 - ;; - nonstopux) - basic_machine=mips-compaq - basic_os=nonstopux - ;; - os400) - basic_machine=powerpc-ibm - basic_os=os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - basic_os=ose - ;; - os68k) - basic_machine=m68k-none - basic_os=os68k - ;; - paragon) - basic_machine=i860-intel - basic_os=osf - ;; - parisc) - basic_machine=hppa-unknown - basic_os=linux - ;; - psp) - basic_machine=mipsallegrexel-sony - basic_os=psp - ;; - pw32) - basic_machine=i586-unknown - basic_os=pw32 - ;; - rdos | rdos64) - basic_machine=x86_64-pc - basic_os=rdos - ;; - rdos32) - basic_machine=i386-pc - basic_os=rdos - ;; - rom68k) - basic_machine=m68k-rom68k - basic_os=coff - ;; - sa29200) - basic_machine=a29k-amd - basic_os=udi - ;; - sei) - basic_machine=mips-sei - basic_os=seiux - ;; - sequent) - basic_machine=i386-sequent - basic_os= - ;; - sps7) - basic_machine=m68k-bull - basic_os=sysv2 - ;; - st2000) - basic_machine=m68k-tandem - basic_os= - ;; - stratus) - basic_machine=i860-stratus - basic_os=sysv4 - ;; - sun2) - basic_machine=m68000-sun - basic_os= - ;; - sun2os3) - basic_machine=m68000-sun - basic_os=sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - basic_os=sunos4 - ;; - sun3) - basic_machine=m68k-sun - basic_os= - ;; - sun3os3) - basic_machine=m68k-sun - basic_os=sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - basic_os=sunos4 - ;; - sun4) - basic_machine=sparc-sun - basic_os= - ;; - sun4os3) - basic_machine=sparc-sun - basic_os=sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - basic_os=sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - basic_os=solaris2 - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - basic_os= - ;; - sv1) - basic_machine=sv1-cray - basic_os=unicos - ;; - symmetry) - basic_machine=i386-sequent - basic_os=dynix - ;; - t3e) - basic_machine=alphaev5-cray - basic_os=unicos - ;; - t90) - basic_machine=t90-cray - basic_os=unicos - ;; - toad1) - basic_machine=pdp10-xkl - basic_os=tops20 - ;; - tpf) - basic_machine=s390x-ibm - basic_os=tpf - ;; - udi29k) - basic_machine=a29k-amd - basic_os=udi - ;; - ultra3) - basic_machine=a29k-nyu - basic_os=sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - basic_os=none - ;; - vaxv) - basic_machine=vax-dec - basic_os=sysv - ;; - vms) - basic_machine=vax-dec - basic_os=vms - ;; - vsta) - basic_machine=i386-pc - basic_os=vsta - ;; - vxworks960) - basic_machine=i960-wrs - basic_os=vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - basic_os=vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - basic_os=vxworks - ;; - xbox) - basic_machine=i686-pc - basic_os=mingw32 - ;; - ymp) - basic_machine=ymp-cray - basic_os=unicos - ;; - *) - basic_machine=$1 - basic_os= - ;; - esac - ;; -esac - -# Decode 1-component or ad-hoc basic machines -case $basic_machine in - # Here we handle the default manufacturer of certain CPU types. It is in - # some cases the only manufacturer, in others, it is the most popular. - w89k) - cpu=hppa1.1 - vendor=winbond - ;; - op50n) - cpu=hppa1.1 - vendor=oki - ;; - op60c) - cpu=hppa1.1 - vendor=oki - ;; - ibm*) - cpu=i370 - vendor=ibm - ;; - orion105) - cpu=clipper - vendor=highlevel - ;; - mac | mpw | mac-mpw) - cpu=m68k - vendor=apple - ;; - pmac | pmac-mpw) - cpu=powerpc - vendor=apple - ;; - - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - cpu=m68000 - vendor=att - ;; - 3b*) - cpu=we32k - vendor=att - ;; - bluegene*) - cpu=powerpc - vendor=ibm - basic_os=cnk - ;; - decsystem10* | dec10*) - cpu=pdp10 - vendor=dec - basic_os=tops10 - ;; - decsystem20* | dec20*) - cpu=pdp10 - vendor=dec - basic_os=tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - cpu=m68k - vendor=motorola - ;; - dpx2*) - cpu=m68k - vendor=bull - basic_os=sysv3 - ;; - encore | umax | mmax) - cpu=ns32k - vendor=encore - ;; - elxsi) - cpu=elxsi - vendor=elxsi - basic_os=${basic_os:-bsd} - ;; - fx2800) - cpu=i860 - vendor=alliant - ;; - genix) - cpu=ns32k - vendor=ns - ;; - h3050r* | hiux*) - cpu=hppa1.1 - vendor=hitachi - basic_os=hiuxwe2 - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - cpu=hppa1.0 - vendor=hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - cpu=m68000 - vendor=hp - ;; - hp9k3[2-9][0-9]) - cpu=m68k - vendor=hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - cpu=hppa1.0 - vendor=hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - cpu=hppa1.1 - vendor=hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - cpu=hppa1.1 - vendor=hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - cpu=hppa1.1 - vendor=hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - cpu=hppa1.1 - vendor=hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - cpu=hppa1.0 - vendor=hp - ;; - i*86v32) - cpu=`echo "$1" | sed -e 's/86.*/86/'` - vendor=pc - basic_os=sysv32 - ;; - i*86v4*) - cpu=`echo "$1" | sed -e 's/86.*/86/'` - vendor=pc - basic_os=sysv4 - ;; - i*86v) - cpu=`echo "$1" | sed -e 's/86.*/86/'` - vendor=pc - basic_os=sysv - ;; - i*86sol2) - cpu=`echo "$1" | sed -e 's/86.*/86/'` - vendor=pc - basic_os=solaris2 - ;; - j90 | j90-cray) - cpu=j90 - vendor=cray - basic_os=${basic_os:-unicos} - ;; - iris | iris4d) - cpu=mips - vendor=sgi - case $basic_os in - irix*) - ;; - *) - basic_os=irix4 - ;; - esac - ;; - miniframe) - cpu=m68000 - vendor=convergent - ;; - *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) - cpu=m68k - vendor=atari - basic_os=mint - ;; - news-3600 | risc-news) - cpu=mips - vendor=sony - basic_os=newsos - ;; - next | m*-next) - cpu=m68k - vendor=next - case $basic_os in - openstep*) - ;; - nextstep*) - ;; - ns2*) - basic_os=nextstep2 - ;; - *) - basic_os=nextstep3 - ;; - esac - ;; - np1) - cpu=np1 - vendor=gould - ;; - op50n-* | op60c-*) - cpu=hppa1.1 - vendor=oki - basic_os=proelf - ;; - pa-hitachi) - cpu=hppa1.1 - vendor=hitachi - basic_os=hiuxwe2 - ;; - pbd) - cpu=sparc - vendor=tti - ;; - pbb) - cpu=m68k - vendor=tti - ;; - pc532) - cpu=ns32k - vendor=pc532 - ;; - pn) - cpu=pn - vendor=gould - ;; - power) - cpu=power - vendor=ibm - ;; - ps2) - cpu=i386 - vendor=ibm - ;; - rm[46]00) - cpu=mips - vendor=siemens - ;; - rtpc | rtpc-*) - cpu=romp - vendor=ibm - ;; - sde) - cpu=mipsisa32 - vendor=sde - basic_os=${basic_os:-elf} - ;; - simso-wrs) - cpu=sparclite - vendor=wrs - basic_os=vxworks - ;; - tower | tower-32) - cpu=m68k - vendor=ncr - ;; - vpp*|vx|vx-*) - cpu=f301 - vendor=fujitsu - ;; - w65) - cpu=w65 - vendor=wdc - ;; - w89k-*) - cpu=hppa1.1 - vendor=winbond - basic_os=proelf - ;; - none) - cpu=none - vendor=none - ;; - leon|leon[3-9]) - cpu=sparc - vendor=$basic_machine - ;; - leon-*|leon[3-9]-*) - cpu=sparc - vendor=`echo "$basic_machine" | sed 's/-.*//'` - ;; - - *-*) - # shellcheck disable=SC2162 - saved_IFS=$IFS - IFS="-" read cpu vendor <&2 - exit 1 - ;; - esac - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $vendor in - digital*) - vendor=dec - ;; - commodore*) - vendor=cbm - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if test x$basic_os != x -then - -# First recognize some ad-hoc cases, or perhaps split kernel-os, or else just -# set os. -case $basic_os in - gnu/linux*) - kernel=linux - os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'` - ;; - os2-emx) - kernel=os2 - os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'` - ;; - nto-qnx*) - kernel=nto - os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'` - ;; - *-*) - # shellcheck disable=SC2162 - saved_IFS=$IFS - IFS="-" read kernel os <&2 - exit 1 - ;; -esac - -# As a final step for OS-related things, validate the OS-kernel combination -# (given a valid OS), if there is a kernel. -case $kernel-$os in - linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \ - | linux-musl* | linux-relibc* | linux-uclibc* ) - ;; - uclinux-uclibc* ) - ;; - -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* ) - # These are just libc implementations, not actual OSes, and thus - # require a kernel. - echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 - exit 1 - ;; - kfreebsd*-gnu* | kopensolaris*-gnu*) - ;; - vxworks-simlinux | vxworks-simwindows | vxworks-spe) - ;; - nto-qnx*) - ;; - os2-emx) - ;; - *-eabi* | *-gnueabi*) - ;; - -*) - # Blank kernel with real OS is always fine. - ;; - *-*) - echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 - exit 1 - ;; -esac - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -case $vendor in - unknown) - case $cpu-$os in - *-riscix*) - vendor=acorn - ;; - *-sunos*) - vendor=sun - ;; - *-cnk* | *-aix*) - vendor=ibm - ;; - *-beos*) - vendor=be - ;; - *-hpux*) - vendor=hp - ;; - *-mpeix*) - vendor=hp - ;; - *-hiux*) - vendor=hitachi - ;; - *-unos*) - vendor=crds - ;; - *-dgux*) - vendor=dg - ;; - *-luna*) - vendor=omron - ;; - *-genix*) - vendor=ns - ;; - *-clix*) - vendor=intergraph - ;; - *-mvs* | *-opened*) - vendor=ibm - ;; - *-os400*) - vendor=ibm - ;; - s390-* | s390x-*) - vendor=ibm - ;; - *-ptx*) - vendor=sequent - ;; - *-tpf*) - vendor=ibm - ;; - *-vxsim* | *-vxworks* | *-windiss*) - vendor=wrs - ;; - *-aux*) - vendor=apple - ;; - *-hms*) - vendor=hitachi - ;; - *-mpw* | *-macos*) - vendor=apple - ;; - *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) - vendor=atari - ;; - *-vos*) - vendor=stratus - ;; - esac - ;; -esac - -echo "$cpu-$vendor-${kernel:+$kernel-}$os" -exit - -# Local variables: -# eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/thirdparty/libarchive/build/autoconf/depcomp b/thirdparty/libarchive/build/autoconf/depcomp deleted file mode 100755 index 715e34311..000000000 --- a/thirdparty/libarchive/build/autoconf/depcomp +++ /dev/null @@ -1,791 +0,0 @@ -#! /bin/sh -# depcomp - compile a program generating dependencies as side-effects - -scriptversion=2018-03-07.03; # UTC - -# Copyright (C) 1999-2021 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Originally written by Alexandre Oliva . - -case $1 in - '') - echo "$0: No command. Try '$0 --help' for more information." 1>&2 - exit 1; - ;; - -h | --h*) - cat <<\EOF -Usage: depcomp [--help] [--version] PROGRAM [ARGS] - -Run PROGRAMS ARGS to compile a file, generating dependencies -as side-effects. - -Environment variables: - depmode Dependency tracking mode. - source Source file read by 'PROGRAMS ARGS'. - object Object file output by 'PROGRAMS ARGS'. - DEPDIR directory where to store dependencies. - depfile Dependency file to output. - tmpdepfile Temporary file to use when outputting dependencies. - libtool Whether libtool is used (yes/no). - -Report bugs to . -EOF - exit $? - ;; - -v | --v*) - echo "depcomp $scriptversion" - exit $? - ;; -esac - -# Get the directory component of the given path, and save it in the -# global variables '$dir'. Note that this directory component will -# be either empty or ending with a '/' character. This is deliberate. -set_dir_from () -{ - case $1 in - */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; - *) dir=;; - esac -} - -# Get the suffix-stripped basename of the given path, and save it the -# global variable '$base'. -set_base_from () -{ - base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` -} - -# If no dependency file was actually created by the compiler invocation, -# we still have to create a dummy depfile, to avoid errors with the -# Makefile "include basename.Plo" scheme. -make_dummy_depfile () -{ - echo "#dummy" > "$depfile" -} - -# Factor out some common post-processing of the generated depfile. -# Requires the auxiliary global variable '$tmpdepfile' to be set. -aix_post_process_depfile () -{ - # If the compiler actually managed to produce a dependency file, - # post-process it. - if test -f "$tmpdepfile"; then - # Each line is of the form 'foo.o: dependency.h'. - # Do two passes, one to just change these to - # $object: dependency.h - # and one to simply output - # dependency.h: - # which is needed to avoid the deleted-header problem. - { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" - sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" - } > "$depfile" - rm -f "$tmpdepfile" - else - make_dummy_depfile - fi -} - -# A tabulation character. -tab=' ' -# A newline character. -nl=' -' -# Character ranges might be problematic outside the C locale. -# These definitions help. -upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ -lower=abcdefghijklmnopqrstuvwxyz -digits=0123456789 -alpha=${upper}${lower} - -if test -z "$depmode" || test -z "$source" || test -z "$object"; then - echo "depcomp: Variables source, object and depmode must be set" 1>&2 - exit 1 -fi - -# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. -depfile=${depfile-`echo "$object" | - sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} -tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} - -rm -f "$tmpdepfile" - -# Avoid interferences from the environment. -gccflag= dashmflag= - -# Some modes work just like other modes, but use different flags. We -# parameterize here, but still list the modes in the big case below, -# to make depend.m4 easier to write. Note that we *cannot* use a case -# here, because this file can only contain one case statement. -if test "$depmode" = hp; then - # HP compiler uses -M and no extra arg. - gccflag=-M - depmode=gcc -fi - -if test "$depmode" = dashXmstdout; then - # This is just like dashmstdout with a different argument. - dashmflag=-xM - depmode=dashmstdout -fi - -cygpath_u="cygpath -u -f -" -if test "$depmode" = msvcmsys; then - # This is just like msvisualcpp but w/o cygpath translation. - # Just convert the backslash-escaped backslashes to single forward - # slashes to satisfy depend.m4 - cygpath_u='sed s,\\\\,/,g' - depmode=msvisualcpp -fi - -if test "$depmode" = msvc7msys; then - # This is just like msvc7 but w/o cygpath translation. - # Just convert the backslash-escaped backslashes to single forward - # slashes to satisfy depend.m4 - cygpath_u='sed s,\\\\,/,g' - depmode=msvc7 -fi - -if test "$depmode" = xlc; then - # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. - gccflag=-qmakedep=gcc,-MF - depmode=gcc -fi - -case "$depmode" in -gcc3) -## gcc 3 implements dependency tracking that does exactly what -## we want. Yay! Note: for some reason libtool 1.4 doesn't like -## it if -MD -MP comes after the -MF stuff. Hmm. -## Unfortunately, FreeBSD c89 acceptance of flags depends upon -## the command line argument order; so add the flags where they -## appear in depend2.am. Note that the slowdown incurred here -## affects only configure: in makefiles, %FASTDEP% shortcuts this. - for arg - do - case $arg in - -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; - *) set fnord "$@" "$arg" ;; - esac - shift # fnord - shift # $arg - done - "$@" - stat=$? - if test $stat -ne 0; then - rm -f "$tmpdepfile" - exit $stat - fi - mv "$tmpdepfile" "$depfile" - ;; - -gcc) -## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. -## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. -## (see the conditional assignment to $gccflag above). -## There are various ways to get dependency output from gcc. Here's -## why we pick this rather obscure method: -## - Don't want to use -MD because we'd like the dependencies to end -## up in a subdir. Having to rename by hand is ugly. -## (We might end up doing this anyway to support other compilers.) -## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like -## -MM, not -M (despite what the docs say). Also, it might not be -## supported by the other compilers which use the 'gcc' depmode. -## - Using -M directly means running the compiler twice (even worse -## than renaming). - if test -z "$gccflag"; then - gccflag=-MD, - fi - "$@" -Wp,"$gccflag$tmpdepfile" - stat=$? - if test $stat -ne 0; then - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - echo "$object : \\" > "$depfile" - # The second -e expression handles DOS-style file names with drive - # letters. - sed -e 's/^[^:]*: / /' \ - -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" -## This next piece of magic avoids the "deleted header file" problem. -## The problem is that when a header file which appears in a .P file -## is deleted, the dependency causes make to die (because there is -## typically no way to rebuild the header). We avoid this by adding -## dummy dependencies for each header file. Too bad gcc doesn't do -## this for us directly. -## Some versions of gcc put a space before the ':'. On the theory -## that the space means something, we add a space to the output as -## well. hp depmode also adds that space, but also prefixes the VPATH -## to the object. Take care to not repeat it in the output. -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - tr ' ' "$nl" < "$tmpdepfile" \ - | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ - | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -hp) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -sgi) - if test "$libtool" = yes; then - "$@" "-Wp,-MDupdate,$tmpdepfile" - else - "$@" -MDupdate "$tmpdepfile" - fi - stat=$? - if test $stat -ne 0; then - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - - if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files - echo "$object : \\" > "$depfile" - # Clip off the initial element (the dependent). Don't try to be - # clever and replace this with sed code, as IRIX sed won't handle - # lines with more than a fixed number of characters (4096 in - # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; - # the IRIX cc adds comments like '#:fec' to the end of the - # dependency line. - tr ' ' "$nl" < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ - | tr "$nl" ' ' >> "$depfile" - echo >> "$depfile" - # The second pass generates a dummy entry for each header file. - tr ' ' "$nl" < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ - >> "$depfile" - else - make_dummy_depfile - fi - rm -f "$tmpdepfile" - ;; - -xlc) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -aix) - # The C for AIX Compiler uses -M and outputs the dependencies - # in a .u file. In older versions, this file always lives in the - # current directory. Also, the AIX compiler puts '$object:' at the - # start of each line; $object doesn't have directory information. - # Version 6 uses the directory in both cases. - set_dir_from "$object" - set_base_from "$object" - if test "$libtool" = yes; then - tmpdepfile1=$dir$base.u - tmpdepfile2=$base.u - tmpdepfile3=$dir.libs/$base.u - "$@" -Wc,-M - else - tmpdepfile1=$dir$base.u - tmpdepfile2=$dir$base.u - tmpdepfile3=$dir$base.u - "$@" -M - fi - stat=$? - if test $stat -ne 0; then - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" - do - test -f "$tmpdepfile" && break - done - aix_post_process_depfile - ;; - -tcc) - # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 - # FIXME: That version still under development at the moment of writing. - # Make that this statement remains true also for stable, released - # versions. - # It will wrap lines (doesn't matter whether long or short) with a - # trailing '\', as in: - # - # foo.o : \ - # foo.c \ - # foo.h \ - # - # It will put a trailing '\' even on the last line, and will use leading - # spaces rather than leading tabs (at least since its commit 0394caf7 - # "Emit spaces for -MD"). - "$@" -MD -MF "$tmpdepfile" - stat=$? - if test $stat -ne 0; then - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. - # We have to change lines of the first kind to '$object: \'. - sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" - # And for each line of the second kind, we have to emit a 'dep.h:' - # dummy dependency, to avoid the deleted-header problem. - sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" - rm -f "$tmpdepfile" - ;; - -## The order of this option in the case statement is important, since the -## shell code in configure will try each of these formats in the order -## listed in this file. A plain '-MD' option would be understood by many -## compilers, so we must ensure this comes after the gcc and icc options. -pgcc) - # Portland's C compiler understands '-MD'. - # Will always output deps to 'file.d' where file is the root name of the - # source file under compilation, even if file resides in a subdirectory. - # The object file name does not affect the name of the '.d' file. - # pgcc 10.2 will output - # foo.o: sub/foo.c sub/foo.h - # and will wrap long lines using '\' : - # foo.o: sub/foo.c ... \ - # sub/foo.h ... \ - # ... - set_dir_from "$object" - # Use the source, not the object, to determine the base name, since - # that's sadly what pgcc will do too. - set_base_from "$source" - tmpdepfile=$base.d - - # For projects that build the same source file twice into different object - # files, the pgcc approach of using the *source* file root name can cause - # problems in parallel builds. Use a locking strategy to avoid stomping on - # the same $tmpdepfile. - lockdir=$base.d-lock - trap " - echo '$0: caught signal, cleaning up...' >&2 - rmdir '$lockdir' - exit 1 - " 1 2 13 15 - numtries=100 - i=$numtries - while test $i -gt 0; do - # mkdir is a portable test-and-set. - if mkdir "$lockdir" 2>/dev/null; then - # This process acquired the lock. - "$@" -MD - stat=$? - # Release the lock. - rmdir "$lockdir" - break - else - # If the lock is being held by a different process, wait - # until the winning process is done or we timeout. - while test -d "$lockdir" && test $i -gt 0; do - sleep 1 - i=`expr $i - 1` - done - fi - i=`expr $i - 1` - done - trap - 1 2 13 15 - if test $i -le 0; then - echo "$0: failed to acquire lock after $numtries attempts" >&2 - echo "$0: check lockdir '$lockdir'" >&2 - exit 1 - fi - - if test $stat -ne 0; then - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - # Each line is of the form `foo.o: dependent.h', - # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. - # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. - sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" - # Some versions of the HPUX 10.20 sed can't process this invocation - # correctly. Breaking it into two sed invocations is a workaround. - sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ - | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -hp2) - # The "hp" stanza above does not work with aCC (C++) and HP's ia64 - # compilers, which have integrated preprocessors. The correct option - # to use with these is +Maked; it writes dependencies to a file named - # 'foo.d', which lands next to the object file, wherever that - # happens to be. - # Much of this is similar to the tru64 case; see comments there. - set_dir_from "$object" - set_base_from "$object" - if test "$libtool" = yes; then - tmpdepfile1=$dir$base.d - tmpdepfile2=$dir.libs/$base.d - "$@" -Wc,+Maked - else - tmpdepfile1=$dir$base.d - tmpdepfile2=$dir$base.d - "$@" +Maked - fi - stat=$? - if test $stat -ne 0; then - rm -f "$tmpdepfile1" "$tmpdepfile2" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" - # Add 'dependent.h:' lines. - sed -ne '2,${ - s/^ *// - s/ \\*$// - s/$/:/ - p - }' "$tmpdepfile" >> "$depfile" - else - make_dummy_depfile - fi - rm -f "$tmpdepfile" "$tmpdepfile2" - ;; - -tru64) - # The Tru64 compiler uses -MD to generate dependencies as a side - # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. - # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put - # dependencies in 'foo.d' instead, so we check for that too. - # Subdirectories are respected. - set_dir_from "$object" - set_base_from "$object" - - if test "$libtool" = yes; then - # Libtool generates 2 separate objects for the 2 libraries. These - # two compilations output dependencies in $dir.libs/$base.o.d and - # in $dir$base.o.d. We have to check for both files, because - # one of the two compilations can be disabled. We should prefer - # $dir$base.o.d over $dir.libs/$base.o.d because the latter is - # automatically cleaned when .libs/ is deleted, while ignoring - # the former would cause a distcleancheck panic. - tmpdepfile1=$dir$base.o.d # libtool 1.5 - tmpdepfile2=$dir.libs/$base.o.d # Likewise. - tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 - "$@" -Wc,-MD - else - tmpdepfile1=$dir$base.d - tmpdepfile2=$dir$base.d - tmpdepfile3=$dir$base.d - "$@" -MD - fi - - stat=$? - if test $stat -ne 0; then - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" - do - test -f "$tmpdepfile" && break - done - # Same post-processing that is required for AIX mode. - aix_post_process_depfile - ;; - -msvc7) - if test "$libtool" = yes; then - showIncludes=-Wc,-showIncludes - else - showIncludes=-showIncludes - fi - "$@" $showIncludes > "$tmpdepfile" - stat=$? - grep -v '^Note: including file: ' "$tmpdepfile" - if test $stat -ne 0; then - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - echo "$object : \\" > "$depfile" - # The first sed program below extracts the file names and escapes - # backslashes for cygpath. The second sed program outputs the file - # name when reading, but also accumulates all include files in the - # hold buffer in order to output them again at the end. This only - # works with sed implementations that can handle large buffers. - sed < "$tmpdepfile" -n ' -/^Note: including file: *\(.*\)/ { - s//\1/ - s/\\/\\\\/g - p -}' | $cygpath_u | sort -u | sed -n ' -s/ /\\ /g -s/\(.*\)/'"$tab"'\1 \\/p -s/.\(.*\) \\/\1:/ -H -$ { - s/.*/'"$tab"'/ - G - p -}' >> "$depfile" - echo >> "$depfile" # make sure the fragment doesn't end with a backslash - rm -f "$tmpdepfile" - ;; - -msvc7msys) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -#nosideeffect) - # This comment above is used by automake to tell side-effect - # dependency tracking mechanisms from slower ones. - -dashmstdout) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout, regardless of -o. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test "X$1" != 'X--mode=compile'; do - shift - done - shift - fi - - # Remove '-o $object'. - IFS=" " - for arg - do - case $arg in - -o) - shift - ;; - $object) - shift - ;; - *) - set fnord "$@" "$arg" - shift # fnord - shift # $arg - ;; - esac - done - - test -z "$dashmflag" && dashmflag=-M - # Require at least two characters before searching for ':' - # in the target name. This is to cope with DOS-style filenames: - # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. - "$@" $dashmflag | - sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" - rm -f "$depfile" - cat < "$tmpdepfile" > "$depfile" - # Some versions of the HPUX 10.20 sed can't process this sed invocation - # correctly. Breaking it into two sed invocations is a workaround. - tr ' ' "$nl" < "$tmpdepfile" \ - | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ - | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -dashXmstdout) - # This case only exists to satisfy depend.m4. It is never actually - # run, as this mode is specially recognized in the preamble. - exit 1 - ;; - -makedepend) - "$@" || exit $? - # Remove any Libtool call - if test "$libtool" = yes; then - while test "X$1" != 'X--mode=compile'; do - shift - done - shift - fi - # X makedepend - shift - cleared=no eat=no - for arg - do - case $cleared in - no) - set ""; shift - cleared=yes ;; - esac - if test $eat = yes; then - eat=no - continue - fi - case "$arg" in - -D*|-I*) - set fnord "$@" "$arg"; shift ;; - # Strip any option that makedepend may not understand. Remove - # the object too, otherwise makedepend will parse it as a source file. - -arch) - eat=yes ;; - -*|$object) - ;; - *) - set fnord "$@" "$arg"; shift ;; - esac - done - obj_suffix=`echo "$object" | sed 's/^.*\././'` - touch "$tmpdepfile" - ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" - rm -f "$depfile" - # makedepend may prepend the VPATH from the source file name to the object. - # No need to regex-escape $object, excess matching of '.' is harmless. - sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" - # Some versions of the HPUX 10.20 sed can't process the last invocation - # correctly. Breaking it into two sed invocations is a workaround. - sed '1,2d' "$tmpdepfile" \ - | tr ' ' "$nl" \ - | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ - | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" "$tmpdepfile".bak - ;; - -cpp) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test "X$1" != 'X--mode=compile'; do - shift - done - shift - fi - - # Remove '-o $object'. - IFS=" " - for arg - do - case $arg in - -o) - shift - ;; - $object) - shift - ;; - *) - set fnord "$@" "$arg" - shift # fnord - shift # $arg - ;; - esac - done - - "$@" -E \ - | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ - -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ - | sed '$ s: \\$::' > "$tmpdepfile" - rm -f "$depfile" - echo "$object : \\" > "$depfile" - cat < "$tmpdepfile" >> "$depfile" - sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -msvisualcpp) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test "X$1" != 'X--mode=compile'; do - shift - done - shift - fi - - IFS=" " - for arg - do - case "$arg" in - -o) - shift - ;; - $object) - shift - ;; - "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") - set fnord "$@" - shift - shift - ;; - *) - set fnord "$@" "$arg" - shift - shift - ;; - esac - done - "$@" -E 2>/dev/null | - sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" - rm -f "$depfile" - echo "$object : \\" > "$depfile" - sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" - echo "$tab" >> "$depfile" - sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -msvcmsys) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -none) - exec "$@" - ;; - -*) - echo "Unknown depmode $depmode" 1>&2 - exit 1 - ;; -esac - -exit 0 - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC0" -# time-stamp-end: "; # UTC" -# End: diff --git a/thirdparty/libarchive/build/autoconf/iconv.m4 b/thirdparty/libarchive/build/autoconf/iconv.m4 deleted file mode 100644 index 4e3736315..000000000 --- a/thirdparty/libarchive/build/autoconf/iconv.m4 +++ /dev/null @@ -1,271 +0,0 @@ -# iconv.m4 serial 19 (gettext-0.18.2) -dnl Copyright (C) 2000-2002, 2007-2014 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. - -AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], -[ - dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - AC_REQUIRE([AC_LIB_RPATH]) - - dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV - dnl accordingly. - AC_LIB_LINKFLAGS_BODY([iconv]) -]) - -AC_DEFUN([AM_ICONV_LINK], -[ - dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and - dnl those with the standalone portable GNU libiconv installed). - AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles - - dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV - dnl accordingly. - AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) - - dnl Add $INCICONV to CPPFLAGS before performing the following checks, - dnl because if the user has installed libiconv and not disabled its use - dnl via --without-libiconv-prefix, he wants to use it. The first - dnl AC_LINK_IFELSE will then fail, the second AC_LINK_IFELSE will succeed. - am_save_CPPFLAGS="$CPPFLAGS" - AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) - - AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [ - am_cv_func_iconv="no, consider installing GNU libiconv" - am_cv_lib_iconv=no - AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[ -#include -#include - ]], - [[iconv_t cd = iconv_open("",""); - iconv(cd,NULL,NULL,NULL,NULL); - iconv_close(cd);]])], - [am_cv_func_iconv=yes]) - if test "$am_cv_func_iconv" != yes; then - am_save_LIBS="$LIBS" - LIBS="$LIBS $LIBICONV" - AC_LINK_IFELSE( - [AC_LANG_PROGRAM( - [[ -#include -#include - ]], - [[iconv_t cd = iconv_open("",""); - iconv(cd,NULL,NULL,NULL,NULL); - iconv_close(cd);]])], - [am_cv_lib_iconv=yes] - [am_cv_func_iconv=yes]) - LIBS="$am_save_LIBS" - fi - ]) - if test "$am_cv_func_iconv" = yes; then - AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [ - dnl This tests against bugs in AIX 5.1, AIX 6.1..7.1, HP-UX 11.11, - dnl Solaris 10. - am_save_LIBS="$LIBS" - if test $am_cv_lib_iconv = yes; then - LIBS="$LIBS $LIBICONV" - fi - am_cv_func_iconv_works=no - for ac_iconv_const in '' 'const'; do - AC_RUN_IFELSE( - [AC_LANG_PROGRAM( - [[ -#include -#include - -#ifndef ICONV_CONST -# define ICONV_CONST $ac_iconv_const -#endif - ]], - [[int result = 0; - /* Test against AIX 5.1 bug: Failures are not distinguishable from successful - returns. */ - { - iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); - if (cd_utf8_to_88591 != (iconv_t)(-1)) - { - static ICONV_CONST char input[] = "\342\202\254"; /* EURO SIGN */ - char buf[10]; - ICONV_CONST char *inptr = input; - size_t inbytesleft = strlen (input); - char *outptr = buf; - size_t outbytesleft = sizeof (buf); - size_t res = iconv (cd_utf8_to_88591, - &inptr, &inbytesleft, - &outptr, &outbytesleft); - if (res == 0) - result |= 1; - iconv_close (cd_utf8_to_88591); - } - } - /* Test against Solaris 10 bug: Failures are not distinguishable from - successful returns. */ - { - iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646"); - if (cd_ascii_to_88591 != (iconv_t)(-1)) - { - static ICONV_CONST char input[] = "\263"; - char buf[10]; - ICONV_CONST char *inptr = input; - size_t inbytesleft = strlen (input); - char *outptr = buf; - size_t outbytesleft = sizeof (buf); - size_t res = iconv (cd_ascii_to_88591, - &inptr, &inbytesleft, - &outptr, &outbytesleft); - if (res == 0) - result |= 2; - iconv_close (cd_ascii_to_88591); - } - } - /* Test against AIX 6.1..7.1 bug: Buffer overrun. */ - { - iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1"); - if (cd_88591_to_utf8 != (iconv_t)(-1)) - { - static ICONV_CONST char input[] = "\304"; - static char buf[2] = { (char)0xDE, (char)0xAD }; - ICONV_CONST char *inptr = input; - size_t inbytesleft = 1; - char *outptr = buf; - size_t outbytesleft = 1; - size_t res = iconv (cd_88591_to_utf8, - &inptr, &inbytesleft, - &outptr, &outbytesleft); - if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD) - result |= 4; - iconv_close (cd_88591_to_utf8); - } - } -#if 0 /* This bug could be worked around by the caller. */ - /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */ - { - iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591"); - if (cd_88591_to_utf8 != (iconv_t)(-1)) - { - static ICONV_CONST char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; - char buf[50]; - ICONV_CONST char *inptr = input; - size_t inbytesleft = strlen (input); - char *outptr = buf; - size_t outbytesleft = sizeof (buf); - size_t res = iconv (cd_88591_to_utf8, - &inptr, &inbytesleft, - &outptr, &outbytesleft); - if ((int)res > 0) - result |= 8; - iconv_close (cd_88591_to_utf8); - } - } -#endif - /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is - provided. */ - if (/* Try standardized names. */ - iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1) - /* Try IRIX, OSF/1 names. */ - && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1) - /* Try AIX names. */ - && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1) - /* Try HP-UX names. */ - && iconv_open ("utf8", "eucJP") == (iconv_t)(-1)) - result |= 16; - return result; -]])], - [am_cv_func_iconv_works=yes], , - [case "$host_os" in - aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; - *) am_cv_func_iconv_works="guessing yes" ;; - esac]) - test "$am_cv_func_iconv_works" = no || break - done - LIBS="$am_save_LIBS" - ]) - case "$am_cv_func_iconv_works" in - *no) am_func_iconv=no am_cv_lib_iconv=no ;; - *) am_func_iconv=yes ;; - esac - else - am_func_iconv=no am_cv_lib_iconv=no - fi - if test "$am_func_iconv" = yes; then - AC_DEFINE([HAVE_ICONV], [1], - [Define if you have the iconv() function and it works.]) - fi - if test "$am_cv_lib_iconv" = yes; then - AC_MSG_CHECKING([how to link with libiconv]) - AC_MSG_RESULT([$LIBICONV]) - else - dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV - dnl either. - CPPFLAGS="$am_save_CPPFLAGS" - LIBICONV= - LTLIBICONV= - fi - AC_SUBST([LIBICONV]) - AC_SUBST([LTLIBICONV]) -]) - -dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to -dnl avoid warnings like -dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required". -dnl This is tricky because of the way 'aclocal' is implemented: -dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN. -dnl Otherwise aclocal's initial scan pass would miss the macro definition. -dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions. -dnl Otherwise aclocal would emit many "Use of uninitialized value $1" -dnl warnings. -m4_define([gl_iconv_AC_DEFUN], - m4_version_prereq([2.64], - [[AC_DEFUN_ONCE( - [$1], [$2])]], - [m4_ifdef([gl_00GNULIB], - [[AC_DEFUN_ONCE( - [$1], [$2])]], - [[AC_DEFUN( - [$1], [$2])]])])) -gl_iconv_AC_DEFUN([AM_ICONV], -[ - AM_ICONV_LINK - if test "$am_cv_func_iconv" = yes; then - AC_MSG_CHECKING([for iconv declaration]) - AC_CACHE_VAL([am_cv_proto_iconv], [ - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[ -#include -#include -extern -#ifdef __cplusplus -"C" -#endif -#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) -size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); -#else -size_t iconv(); -#endif - ]], - [[]])], - [am_cv_proto_iconv_arg1=""], - [am_cv_proto_iconv_arg1="const"]) - am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) - am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` - AC_MSG_RESULT([ - $am_cv_proto_iconv]) - AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1], - [Define as const if the declaration of iconv() needs const.]) - dnl Also substitute ICONV_CONST in the gnulib generated . - m4_ifdef([gl_ICONV_H_DEFAULTS], - [AC_REQUIRE([gl_ICONV_H_DEFAULTS]) - if test -n "$am_cv_proto_iconv_arg1"; then - ICONV_CONST="const" - fi - ]) - fi -]) diff --git a/thirdparty/libarchive/build/autoconf/install-sh b/thirdparty/libarchive/build/autoconf/install-sh deleted file mode 100755 index ec298b537..000000000 --- a/thirdparty/libarchive/build/autoconf/install-sh +++ /dev/null @@ -1,541 +0,0 @@ -#!/bin/sh -# install - install a program, script, or datafile - -scriptversion=2020-11-14.01; # UTC - -# This originates from X11R5 (mit/util/scripts/install.sh), which was -# later released in X11R6 (xc/config/util/install.sh) with the -# following copyright and license. -# -# Copyright (C) 1994 X Consortium -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- -# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# Except as contained in this notice, the name of the X Consortium shall not -# be used in advertising or otherwise to promote the sale, use or other deal- -# ings in this Software without prior written authorization from the X Consor- -# tium. -# -# -# FSF changes to this file are in the public domain. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# 'make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. - -tab=' ' -nl=' -' -IFS=" $tab$nl" - -# Set DOITPROG to "echo" to test this script. - -doit=${DOITPROG-} -doit_exec=${doit:-exec} - -# Put in absolute file names if you don't have them in your path; -# or use environment vars. - -chgrpprog=${CHGRPPROG-chgrp} -chmodprog=${CHMODPROG-chmod} -chownprog=${CHOWNPROG-chown} -cmpprog=${CMPPROG-cmp} -cpprog=${CPPROG-cp} -mkdirprog=${MKDIRPROG-mkdir} -mvprog=${MVPROG-mv} -rmprog=${RMPROG-rm} -stripprog=${STRIPPROG-strip} - -posix_mkdir= - -# Desired mode of installed file. -mode=0755 - -# Create dirs (including intermediate dirs) using mode 755. -# This is like GNU 'install' as of coreutils 8.32 (2020). -mkdir_umask=22 - -backupsuffix= -chgrpcmd= -chmodcmd=$chmodprog -chowncmd= -mvcmd=$mvprog -rmcmd="$rmprog -f" -stripcmd= - -src= -dst= -dir_arg= -dst_arg= - -copy_on_change=false -is_target_a_directory=possibly - -usage="\ -Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE - or: $0 [OPTION]... SRCFILES... DIRECTORY - or: $0 [OPTION]... -t DIRECTORY SRCFILES... - or: $0 [OPTION]... -d DIRECTORIES... - -In the 1st form, copy SRCFILE to DSTFILE. -In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. -In the 4th, create DIRECTORIES. - -Options: - --help display this help and exit. - --version display version info and exit. - - -c (ignored) - -C install only if different (preserve data modification time) - -d create directories instead of installing files. - -g GROUP $chgrpprog installed files to GROUP. - -m MODE $chmodprog installed files to MODE. - -o USER $chownprog installed files to USER. - -p pass -p to $cpprog. - -s $stripprog installed files. - -S SUFFIX attempt to back up existing files, with suffix SUFFIX. - -t DIRECTORY install into DIRECTORY. - -T report an error if DSTFILE is a directory. - -Environment variables override the default commands: - CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG - RMPROG STRIPPROG - -By default, rm is invoked with -f; when overridden with RMPROG, -it's up to you to specify -f if you want it. - -If -S is not specified, no backups are attempted. - -Email bug reports to bug-automake@gnu.org. -Automake home page: https://www.gnu.org/software/automake/ -" - -while test $# -ne 0; do - case $1 in - -c) ;; - - -C) copy_on_change=true;; - - -d) dir_arg=true;; - - -g) chgrpcmd="$chgrpprog $2" - shift;; - - --help) echo "$usage"; exit $?;; - - -m) mode=$2 - case $mode in - *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) - echo "$0: invalid mode: $mode" >&2 - exit 1;; - esac - shift;; - - -o) chowncmd="$chownprog $2" - shift;; - - -p) cpprog="$cpprog -p";; - - -s) stripcmd=$stripprog;; - - -S) backupsuffix="$2" - shift;; - - -t) - is_target_a_directory=always - dst_arg=$2 - # Protect names problematic for 'test' and other utilities. - case $dst_arg in - -* | [=\(\)!]) dst_arg=./$dst_arg;; - esac - shift;; - - -T) is_target_a_directory=never;; - - --version) echo "$0 $scriptversion"; exit $?;; - - --) shift - break;; - - -*) echo "$0: invalid option: $1" >&2 - exit 1;; - - *) break;; - esac - shift -done - -# We allow the use of options -d and -T together, by making -d -# take the precedence; this is for compatibility with GNU install. - -if test -n "$dir_arg"; then - if test -n "$dst_arg"; then - echo "$0: target directory not allowed when installing a directory." >&2 - exit 1 - fi -fi - -if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then - # When -d is used, all remaining arguments are directories to create. - # When -t is used, the destination is already specified. - # Otherwise, the last argument is the destination. Remove it from $@. - for arg - do - if test -n "$dst_arg"; then - # $@ is not empty: it contains at least $arg. - set fnord "$@" "$dst_arg" - shift # fnord - fi - shift # arg - dst_arg=$arg - # Protect names problematic for 'test' and other utilities. - case $dst_arg in - -* | [=\(\)!]) dst_arg=./$dst_arg;; - esac - done -fi - -if test $# -eq 0; then - if test -z "$dir_arg"; then - echo "$0: no input file specified." >&2 - exit 1 - fi - # It's OK to call 'install-sh -d' without argument. - # This can happen when creating conditional directories. - exit 0 -fi - -if test -z "$dir_arg"; then - if test $# -gt 1 || test "$is_target_a_directory" = always; then - if test ! -d "$dst_arg"; then - echo "$0: $dst_arg: Is not a directory." >&2 - exit 1 - fi - fi -fi - -if test -z "$dir_arg"; then - do_exit='(exit $ret); exit $ret' - trap "ret=129; $do_exit" 1 - trap "ret=130; $do_exit" 2 - trap "ret=141; $do_exit" 13 - trap "ret=143; $do_exit" 15 - - # Set umask so as not to create temps with too-generous modes. - # However, 'strip' requires both read and write access to temps. - case $mode in - # Optimize common cases. - *644) cp_umask=133;; - *755) cp_umask=22;; - - *[0-7]) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw='% 200' - fi - cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; - *) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw=,u+rw - fi - cp_umask=$mode$u_plus_rw;; - esac -fi - -for src -do - # Protect names problematic for 'test' and other utilities. - case $src in - -* | [=\(\)!]) src=./$src;; - esac - - if test -n "$dir_arg"; then - dst=$src - dstdir=$dst - test -d "$dstdir" - dstdir_status=$? - # Don't chown directories that already exist. - if test $dstdir_status = 0; then - chowncmd="" - fi - else - - # Waiting for this to be detected by the "$cpprog $src $dsttmp" command - # might cause directories to be created, which would be especially bad - # if $src (and thus $dsttmp) contains '*'. - if test ! -f "$src" && test ! -d "$src"; then - echo "$0: $src does not exist." >&2 - exit 1 - fi - - if test -z "$dst_arg"; then - echo "$0: no destination specified." >&2 - exit 1 - fi - dst=$dst_arg - - # If destination is a directory, append the input filename. - if test -d "$dst"; then - if test "$is_target_a_directory" = never; then - echo "$0: $dst_arg: Is a directory" >&2 - exit 1 - fi - dstdir=$dst - dstbase=`basename "$src"` - case $dst in - */) dst=$dst$dstbase;; - *) dst=$dst/$dstbase;; - esac - dstdir_status=0 - else - dstdir=`dirname "$dst"` - test -d "$dstdir" - dstdir_status=$? - fi - fi - - case $dstdir in - */) dstdirslash=$dstdir;; - *) dstdirslash=$dstdir/;; - esac - - obsolete_mkdir_used=false - - if test $dstdir_status != 0; then - case $posix_mkdir in - '') - # With -d, create the new directory with the user-specified mode. - # Otherwise, rely on $mkdir_umask. - if test -n "$dir_arg"; then - mkdir_mode=-m$mode - else - mkdir_mode= - fi - - posix_mkdir=false - # The $RANDOM variable is not portable (e.g., dash). Use it - # here however when possible just to lower collision chance. - tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - - trap ' - ret=$? - rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null - exit $ret - ' 0 - - # Because "mkdir -p" follows existing symlinks and we likely work - # directly in world-writeable /tmp, make sure that the '$tmpdir' - # directory is successfully created first before we actually test - # 'mkdir -p'. - if (umask $mkdir_umask && - $mkdirprog $mkdir_mode "$tmpdir" && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 - then - if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. - # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writable bit of parent directory when it shouldn't. - # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - test_tmpdir="$tmpdir/a" - ls_ld_tmpdir=`ls -ld "$test_tmpdir"` - case $ls_ld_tmpdir in - d????-?r-*) different_mode=700;; - d????-?--*) different_mode=755;; - *) false;; - esac && - $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` - test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" - } - } - then posix_mkdir=: - fi - rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" - else - # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null - fi - trap '' 0;; - esac - - if - $posix_mkdir && ( - umask $mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" - ) - then : - else - - # mkdir does not conform to POSIX, - # or it failed possibly due to a race condition. Create the - # directory the slow way, step by step, checking for races as we go. - - case $dstdir in - /*) prefix='/';; - [-=\(\)!]*) prefix='./';; - *) prefix='';; - esac - - oIFS=$IFS - IFS=/ - set -f - set fnord $dstdir - shift - set +f - IFS=$oIFS - - prefixes= - - for d - do - test X"$d" = X && continue - - prefix=$prefix$d - if test -d "$prefix"; then - prefixes= - else - if $posix_mkdir; then - (umask $mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break - # Don't fail if two instances are running concurrently. - test -d "$prefix" || exit 1 - else - case $prefix in - *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; - *) qprefix=$prefix;; - esac - prefixes="$prefixes '$qprefix'" - fi - fi - prefix=$prefix/ - done - - if test -n "$prefixes"; then - # Don't fail if two instances are running concurrently. - (umask $mkdir_umask && - eval "\$doit_exec \$mkdirprog $prefixes") || - test -d "$dstdir" || exit 1 - obsolete_mkdir_used=true - fi - fi - fi - - if test -n "$dir_arg"; then - { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && - { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || - test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 - else - - # Make a couple of temp file names in the proper directory. - dsttmp=${dstdirslash}_inst.$$_ - rmtmp=${dstdirslash}_rm.$$_ - - # Trap to clean up those temp files at exit. - trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 - - # Copy the file name to the temp name. - (umask $cp_umask && - { test -z "$stripcmd" || { - # Create $dsttmp read-write so that cp doesn't create it read-only, - # which would cause strip to fail. - if test -z "$doit"; then - : >"$dsttmp" # No need to fork-exec 'touch'. - else - $doit touch "$dsttmp" - fi - } - } && - $doit_exec $cpprog "$src" "$dsttmp") && - - # and set any options; do chmod last to preserve setuid bits. - # - # If any of these fail, we abort the whole thing. If we want to - # ignore errors from any of these, just make sure not to ignore - # errors from the above "$doit $cpprog $src $dsttmp" command. - # - { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && - { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && - { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && - - # If -C, don't bother to copy if it wouldn't change the file. - if $copy_on_change && - old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && - new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && - set -f && - set X $old && old=:$2:$4:$5:$6 && - set X $new && new=:$2:$4:$5:$6 && - set +f && - test "$old" = "$new" && - $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 - then - rm -f "$dsttmp" - else - # If $backupsuffix is set, and the file being installed - # already exists, attempt a backup. Don't worry if it fails, - # e.g., if mv doesn't support -f. - if test -n "$backupsuffix" && test -f "$dst"; then - $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null - fi - - # Rename the file to the real destination. - $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || - - # The rename failed, perhaps because mv can't rename something else - # to itself, or perhaps because mv is so ancient that it does not - # support -f. - { - # Now remove or move aside any old file at destination location. - # We try this two ways since rm can't unlink itself on some - # systems and the destination file might be busy for other - # reasons. In this case, the final cleanup might fail but the new - # file should still install successfully. - { - test ! -f "$dst" || - $doit $rmcmd "$dst" 2>/dev/null || - { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && - { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } - } || - { echo "$0: cannot unlink or rename $dst" >&2 - (exit 1); exit 1 - } - } && - - # Now rename the file to the real destination. - $doit $mvcmd "$dsttmp" "$dst" - } - fi || exit 1 - - trap '' 0 - fi -done - -# Local variables: -# eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC0" -# time-stamp-end: "; # UTC" -# End: diff --git a/thirdparty/libarchive/build/autoconf/la_uid_t.m4 b/thirdparty/libarchive/build/autoconf/la_uid_t.m4 deleted file mode 100644 index 31eef5e96..000000000 --- a/thirdparty/libarchive/build/autoconf/la_uid_t.m4 +++ /dev/null @@ -1,20 +0,0 @@ -# la_TYPE_UID_T -# ------------- -AC_DEFUN([la_TYPE_UID_T], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_CACHE_CHECK(for uid_t in sys/types.h, la_cv_type_uid_t, -[AC_EGREP_HEADER(uid_t, sys/types.h, - la_cv_type_uid_t=yes, la_cv_type_uid_t=no)]) -if test $la_cv_type_uid_t = no; then - case $host in - *mingw*) def_uid_t=short ;; - *) def_uid_t=int ;; - esac - AC_DEFINE_UNQUOTED(uid_t, [$def_uid_t], - [Define to match typeof st_uid field of struct stat if doesn't define.]) - AC_DEFINE_UNQUOTED(gid_t, [$def_uid_t], - [Define to match typeof st_gid field of struct stat if doesn't define.]) -fi -]) -AU_ALIAS([AC_TYPE_UID_T], [la_TYPE_UID_T]) - diff --git a/thirdparty/libarchive/build/autoconf/lib-ld.m4 b/thirdparty/libarchive/build/autoconf/lib-ld.m4 deleted file mode 100644 index ae003f7c5..000000000 --- a/thirdparty/libarchive/build/autoconf/lib-ld.m4 +++ /dev/null @@ -1,109 +0,0 @@ -# lib-ld.m4 serial 5 (gettext-0.18.2) -dnl Copyright (C) 1996-2003, 2009-2011 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl Subroutines of libtool.m4, -dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision -dnl with libtool.m4. - -dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no. -AC_DEFUN([AC_LIB_PROG_LD_GNU], -[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], [acl_cv_prog_gnu_ld], -[# I'd rather use --version here, but apparently some GNU ld's only accept -v. -case `$LD -v 2>&1 /dev/null 2>&1 \ - && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ - || PATH_SEPARATOR=';' - } -fi -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - AC_MSG_CHECKING([for ld used by GCC]) - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [[\\/]* | [A-Za-z]:[\\/]*)] - [re_direlt='/[^/][^/]*/\.\./'] - # Canonicalize the path of ld - ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` - while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do - ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - AC_MSG_CHECKING([for GNU ld]) -else - AC_MSG_CHECKING([for non-GNU ld]) -fi -AC_CACHE_VAL([acl_cv_path_LD], -[if test -z "$LD"; then - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - acl_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some GNU ld's only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in - *GNU* | *'with BFD'*) - test "$with_gnu_ld" != no && break ;; - *) - test "$with_gnu_ld" != yes && break ;; - esac - fi - done - IFS="$ac_save_ifs" -else - acl_cv_path_LD="$LD" # Let the user override the test with a path. -fi]) -LD="$acl_cv_path_LD" -if test -n "$LD"; then - AC_MSG_RESULT([$LD]) -else - AC_MSG_RESULT([no]) -fi -test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) -AC_LIB_PROG_LD_GNU -]) diff --git a/thirdparty/libarchive/build/autoconf/lib-link.m4 b/thirdparty/libarchive/build/autoconf/lib-link.m4 deleted file mode 100644 index e7c9ba9d3..000000000 --- a/thirdparty/libarchive/build/autoconf/lib-link.m4 +++ /dev/null @@ -1,777 +0,0 @@ -# lib-link.m4 serial 26 (gettext-0.18.2) -dnl Copyright (C) 2001-2011 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. - -AC_PREREQ([2.54]) - -dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and -dnl the libraries corresponding to explicit and implicit dependencies. -dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and -dnl augments the CPPFLAGS variable. -dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname -dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem. -AC_DEFUN([AC_LIB_LINKFLAGS], -[ - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - AC_REQUIRE([AC_LIB_RPATH]) - pushdef([Name],[m4_translit([$1],[./+-], [____])]) - pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) - AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [ - AC_LIB_LINKFLAGS_BODY([$1], [$2]) - ac_cv_lib[]Name[]_libs="$LIB[]NAME" - ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME" - ac_cv_lib[]Name[]_cppflags="$INC[]NAME" - ac_cv_lib[]Name[]_prefix="$LIB[]NAME[]_PREFIX" - ]) - LIB[]NAME="$ac_cv_lib[]Name[]_libs" - LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs" - INC[]NAME="$ac_cv_lib[]Name[]_cppflags" - LIB[]NAME[]_PREFIX="$ac_cv_lib[]Name[]_prefix" - AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) - AC_SUBST([LIB]NAME) - AC_SUBST([LTLIB]NAME) - AC_SUBST([LIB]NAME[_PREFIX]) - dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the - dnl results of this search when this library appears as a dependency. - HAVE_LIB[]NAME=yes - popdef([NAME]) - popdef([Name]) -]) - -dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode, [missing-message]) -dnl searches for libname and the libraries corresponding to explicit and -dnl implicit dependencies, together with the specified include files and -dnl the ability to compile and link the specified testcode. The missing-message -dnl defaults to 'no' and may contain additional hints for the user. -dnl If found, it sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} -dnl and LTLIB${NAME} variables and augments the CPPFLAGS variable, and -dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs -dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty. -dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname -dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem. -AC_DEFUN([AC_LIB_HAVE_LINKFLAGS], -[ - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - AC_REQUIRE([AC_LIB_RPATH]) - pushdef([Name],[m4_translit([$1],[./+-], [____])]) - pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) - - dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME - dnl accordingly. - AC_LIB_LINKFLAGS_BODY([$1], [$2]) - - dnl Add $INC[]NAME to CPPFLAGS before performing the following checks, - dnl because if the user has installed lib[]Name and not disabled its use - dnl via --without-lib[]Name-prefix, he wants to use it. - ac_save_CPPFLAGS="$CPPFLAGS" - AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) - - AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [ - ac_save_LIBS="$LIBS" - dnl If $LIB[]NAME contains some -l options, add it to the end of LIBS, - dnl because these -l options might require -L options that are present in - dnl LIBS. -l options benefit only from the -L options listed before it. - dnl Otherwise, add it to the front of LIBS, because it may be a static - dnl library that depends on another static library that is present in LIBS. - dnl Static libraries benefit only from the static libraries listed after - dnl it. - case " $LIB[]NAME" in - *" -l"*) LIBS="$LIBS $LIB[]NAME" ;; - *) LIBS="$LIB[]NAME $LIBS" ;; - esac - AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[$3]], [[$4]])], - [ac_cv_lib[]Name=yes], - [ac_cv_lib[]Name='m4_if([$5], [], [no], [[$5]])']) - LIBS="$ac_save_LIBS" - ]) - if test "$ac_cv_lib[]Name" = yes; then - HAVE_LIB[]NAME=yes - AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the lib][$1 library.]) - AC_MSG_CHECKING([how to link with lib[]$1]) - AC_MSG_RESULT([$LIB[]NAME]) - else - HAVE_LIB[]NAME=no - dnl If $LIB[]NAME didn't lead to a usable library, we don't need - dnl $INC[]NAME either. - CPPFLAGS="$ac_save_CPPFLAGS" - LIB[]NAME= - LTLIB[]NAME= - LIB[]NAME[]_PREFIX= - fi - AC_SUBST([HAVE_LIB]NAME) - AC_SUBST([LIB]NAME) - AC_SUBST([LTLIB]NAME) - AC_SUBST([LIB]NAME[_PREFIX]) - popdef([NAME]) - popdef([Name]) -]) - -dnl Determine the platform dependent parameters needed to use rpath: -dnl acl_libext, -dnl acl_shlibext, -dnl acl_libname_spec, -dnl acl_library_names_spec, -dnl acl_hardcode_libdir_flag_spec, -dnl acl_hardcode_libdir_separator, -dnl acl_hardcode_direct, -dnl acl_hardcode_minus_L. -AC_DEFUN([AC_LIB_RPATH], -[ - dnl Tell automake >= 1.10 to complain if config.rpath is missing. - m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])]) - AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS - AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld - AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host - AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir - AC_CACHE_CHECK([for shared library run path origin], [acl_cv_rpath], [ - CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ - ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh - . ./conftest.sh - rm -f ./conftest.sh - acl_cv_rpath=done - ]) - wl="$acl_cv_wl" - acl_libext="$acl_cv_libext" - acl_shlibext="$acl_cv_shlibext" - acl_libname_spec="$acl_cv_libname_spec" - acl_library_names_spec="$acl_cv_library_names_spec" - acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" - acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" - acl_hardcode_direct="$acl_cv_hardcode_direct" - acl_hardcode_minus_L="$acl_cv_hardcode_minus_L" - dnl Determine whether the user wants rpath handling at all. - AC_ARG_ENABLE([rpath], - [ --disable-rpath do not hardcode runtime library paths], - :, enable_rpath=yes) -]) - -dnl AC_LIB_FROMPACKAGE(name, package) -dnl declares that libname comes from the given package. The configure file -dnl will then not have a --with-libname-prefix option but a -dnl --with-package-prefix option. Several libraries can come from the same -dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar -dnl macro call that searches for libname. -AC_DEFUN([AC_LIB_FROMPACKAGE], -[ - pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) - define([acl_frompackage_]NAME, [$2]) - popdef([NAME]) - pushdef([PACK],[$2]) - pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) - define([acl_libsinpackage_]PACKUP, - m4_ifdef([acl_libsinpackage_]PACKUP, [m4_defn([acl_libsinpackage_]PACKUP)[, ]],)[lib$1]) - popdef([PACKUP]) - popdef([PACK]) -]) - -dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and -dnl the libraries corresponding to explicit and implicit dependencies. -dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. -dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found -dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem. -AC_DEFUN([AC_LIB_LINKFLAGS_BODY], -[ - AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) - pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) - pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])]) - pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-], - [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) - pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])]) - dnl Autoconf >= 2.61 supports dots in --with options. - pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[m4_translit(PACK,[.],[_])],PACK)]) - dnl By default, look in $includedir and $libdir. - use_additional=yes - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - AC_ARG_WITH(P_A_C_K[-prefix], -[[ --with-]]P_A_C_K[[-prefix[=DIR] search for ]PACKLIBS[ in DIR/include and DIR/lib - --without-]]P_A_C_K[[-prefix don't search for ]PACKLIBS[ in includedir and libdir]], -[ - if test "X$withval" = "Xno"; then - use_additional=no - else - if test "X$withval" = "X"; then - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - else - additional_includedir="$withval/include" - additional_libdir="$withval/$acl_libdirstem" - if test "$acl_libdirstem2" != "$acl_libdirstem" \ - && ! test -d "$withval/$acl_libdirstem"; then - additional_libdir="$withval/$acl_libdirstem2" - fi - fi - fi -]) - dnl Search the library and its dependencies in $additional_libdir and - dnl $LDFLAGS. Using breadth-first-seach. - LIB[]NAME= - LTLIB[]NAME= - INC[]NAME= - LIB[]NAME[]_PREFIX= - dnl HAVE_LIB${NAME} is an indicator that LIB${NAME}, LTLIB${NAME} have been - dnl computed. So it has to be reset here. - HAVE_LIB[]NAME= - rpathdirs= - ltrpathdirs= - names_already_handled= - names_next_round='$1 $2' - while test -n "$names_next_round"; do - names_this_round="$names_next_round" - names_next_round= - for name in $names_this_round; do - already_handled= - for n in $names_already_handled; do - if test "$n" = "$name"; then - already_handled=yes - break - fi - done - if test -z "$already_handled"; then - names_already_handled="$names_already_handled $name" - dnl See if it was already located by an earlier AC_LIB_LINKFLAGS - dnl or AC_LIB_HAVE_LINKFLAGS call. - uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'` - eval value=\"\$HAVE_LIB$uppername\" - if test -n "$value"; then - if test "$value" = yes; then - eval value=\"\$LIB$uppername\" - test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" - eval value=\"\$LTLIB$uppername\" - test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" - else - dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined - dnl that this library doesn't exist. So just drop it. - : - fi - else - dnl Search the library lib$name in $additional_libdir and $LDFLAGS - dnl and the already constructed $LIBNAME/$LTLIBNAME. - found_dir= - found_la= - found_so= - found_a= - eval libname=\"$acl_libname_spec\" # typically: libname=lib$name - if test -n "$acl_shlibext"; then - shrext=".$acl_shlibext" # typically: shrext=.so - else - shrext= - fi - if test $use_additional = yes; then - dir="$additional_libdir" - dnl The same code as in the loop below: - dnl First look for a shared library. - if test -n "$acl_shlibext"; then - if test -f "$dir/$libname$shrext"; then - found_dir="$dir" - found_so="$dir/$libname$shrext" - else - if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then - ver=`(cd "$dir" && \ - for f in "$libname$shrext".*; do echo "$f"; done \ - | sed -e "s,^$libname$shrext\\\\.,," \ - | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ - | sed 1q ) 2>/dev/null` - if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then - found_dir="$dir" - found_so="$dir/$libname$shrext.$ver" - fi - else - eval library_names=\"$acl_library_names_spec\" - for f in $library_names; do - if test -f "$dir/$f"; then - found_dir="$dir" - found_so="$dir/$f" - break - fi - done - fi - fi - fi - dnl Then look for a static library. - if test "X$found_dir" = "X"; then - if test -f "$dir/$libname.$acl_libext"; then - found_dir="$dir" - found_a="$dir/$libname.$acl_libext" - fi - fi - if test "X$found_dir" != "X"; then - if test -f "$dir/$libname.la"; then - found_la="$dir/$libname.la" - fi - fi - fi - if test "X$found_dir" = "X"; then - for x in $LDFLAGS $LTLIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - case "$x" in - -L*) - dir=`echo "X$x" | sed -e 's/^X-L//'` - dnl First look for a shared library. - if test -n "$acl_shlibext"; then - if test -f "$dir/$libname$shrext"; then - found_dir="$dir" - found_so="$dir/$libname$shrext" - else - if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then - ver=`(cd "$dir" && \ - for f in "$libname$shrext".*; do echo "$f"; done \ - | sed -e "s,^$libname$shrext\\\\.,," \ - | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ - | sed 1q ) 2>/dev/null` - if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then - found_dir="$dir" - found_so="$dir/$libname$shrext.$ver" - fi - else - eval library_names=\"$acl_library_names_spec\" - for f in $library_names; do - if test -f "$dir/$f"; then - found_dir="$dir" - found_so="$dir/$f" - break - fi - done - fi - fi - fi - dnl Then look for a static library. - if test "X$found_dir" = "X"; then - if test -f "$dir/$libname.$acl_libext"; then - found_dir="$dir" - found_a="$dir/$libname.$acl_libext" - fi - fi - if test "X$found_dir" != "X"; then - if test -f "$dir/$libname.la"; then - found_la="$dir/$libname.la" - fi - fi - ;; - esac - if test "X$found_dir" != "X"; then - break - fi - done - fi - if test "X$found_dir" != "X"; then - dnl Found the library. - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" - if test "X$found_so" != "X"; then - dnl Linking with a shared library. We attempt to hardcode its - dnl directory into the executable's runpath, unless it's the - dnl standard /usr/lib. - if test "$enable_rpath" = no \ - || test "X$found_dir" = "X/usr/$acl_libdirstem" \ - || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then - dnl No hardcoding is needed. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - else - dnl Use an explicit option to hardcode DIR into the resulting - dnl binary. - dnl Potentially add DIR to ltrpathdirs. - dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $found_dir" - fi - dnl The hardcoding into $LIBNAME is system dependent. - if test "$acl_hardcode_direct" = yes; then - dnl Using DIR/libNAME.so during linking hardcodes DIR into the - dnl resulting binary. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - else - if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then - dnl Use an explicit option to hardcode DIR into the resulting - dnl binary. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - dnl Potentially add DIR to rpathdirs. - dnl The rpathdirs will be appended to $LIBNAME at the end. - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $found_dir" - fi - else - dnl Rely on "-L$found_dir". - dnl But don't add it if it's already contained in the LDFLAGS - dnl or the already constructed $LIBNAME - haveit= - for x in $LDFLAGS $LIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" - fi - if test "$acl_hardcode_minus_L" != no; then - dnl FIXME: Not sure whether we should use - dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" - dnl here. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" - else - dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH - dnl here, because this doesn't fit in flags passed to the - dnl compiler. So give up. No hardcoding. This affects only - dnl very old systems. - dnl FIXME: Not sure whether we should use - dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" - dnl here. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" - fi - fi - fi - fi - else - if test "X$found_a" != "X"; then - dnl Linking with a static library. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" - else - dnl We shouldn't come here, but anyway it's good to have a - dnl fallback. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" - fi - fi - dnl Assume the include files are nearby. - additional_includedir= - case "$found_dir" in - */$acl_libdirstem | */$acl_libdirstem/) - basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` - if test "$name" = '$1'; then - LIB[]NAME[]_PREFIX="$basedir" - fi - additional_includedir="$basedir/include" - ;; - */$acl_libdirstem2 | */$acl_libdirstem2/) - basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` - if test "$name" = '$1'; then - LIB[]NAME[]_PREFIX="$basedir" - fi - additional_includedir="$basedir/include" - ;; - esac - if test "X$additional_includedir" != "X"; then - dnl Potentially add $additional_includedir to $INCNAME. - dnl But don't add it - dnl 1. if it's the standard /usr/include, - dnl 2. if it's /usr/local/include and we are using GCC on Linux, - dnl 3. if it's already present in $CPPFLAGS or the already - dnl constructed $INCNAME, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_includedir" != "X/usr/include"; then - haveit= - if test "X$additional_includedir" = "X/usr/local/include"; then - if test -n "$GCC"; then - case $host_os in - linux* | gnu* | k*bsd*-gnu) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - for x in $CPPFLAGS $INC[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-I$additional_includedir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_includedir"; then - dnl Really add $additional_includedir to $INCNAME. - INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" - fi - fi - fi - fi - fi - dnl Look for dependencies. - if test -n "$found_la"; then - dnl Read the .la file. It defines the variables - dnl dlname, library_names, old_library, dependency_libs, current, - dnl age, revision, installed, dlopen, dlpreopen, libdir. - save_libdir="$libdir" - case "$found_la" in - */* | *\\*) . "$found_la" ;; - *) . "./$found_la" ;; - esac - libdir="$save_libdir" - dnl We use only dependency_libs. - for dep in $dependency_libs; do - case "$dep" in - -L*) - additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` - dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. - dnl But don't add it - dnl 1. if it's the standard /usr/lib, - dnl 2. if it's /usr/local/lib and we are using GCC on Linux, - dnl 3. if it's already present in $LDFLAGS or the already - dnl constructed $LIBNAME, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \ - && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then - haveit= - if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \ - || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then - if test -n "$GCC"; then - case $host_os in - linux* | gnu* | k*bsd*-gnu) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - haveit= - for x in $LDFLAGS $LIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - dnl Really add $additional_libdir to $LIBNAME. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" - fi - fi - haveit= - for x in $LDFLAGS $LTLIB[]NAME; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - dnl Really add $additional_libdir to $LTLIBNAME. - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" - fi - fi - fi - fi - ;; - -R*) - dir=`echo "X$dep" | sed -e 's/^X-R//'` - if test "$enable_rpath" != no; then - dnl Potentially add DIR to rpathdirs. - dnl The rpathdirs will be appended to $LIBNAME at the end. - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $dir" - fi - dnl Potentially add DIR to ltrpathdirs. - dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $dir" - fi - fi - ;; - -l*) - dnl Handle this in the next round. - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` - ;; - *.la) - dnl Handle this in the next round. Throw away the .la's - dnl directory; it is already contained in a preceding -L - dnl option. - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` - ;; - *) - dnl Most likely an immediate library name. - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" - ;; - esac - done - fi - else - dnl Didn't find the library; assume it is in the system directories - dnl known to the linker and runtime loader. (All the system - dnl directories known to the linker should also be known to the - dnl runtime loader, otherwise the system is severely misconfigured.) - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" - fi - fi - fi - done - done - if test "X$rpathdirs" != "X"; then - if test -n "$acl_hardcode_libdir_separator"; then - dnl Weird platform: only the last -rpath option counts, the user must - dnl pass all path elements in one option. We can arrange that for a - dnl single library, but not when more than one $LIBNAMEs are used. - alldirs= - for found_dir in $rpathdirs; do - alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" - done - dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl. - acl_save_libdir="$libdir" - libdir="$alldirs" - eval flag=\"$acl_hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" - else - dnl The -rpath options are cumulative. - for found_dir in $rpathdirs; do - acl_save_libdir="$libdir" - libdir="$found_dir" - eval flag=\"$acl_hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" - done - fi - fi - if test "X$ltrpathdirs" != "X"; then - dnl When using libtool, the option that works for both libraries and - dnl executables is -R. The -R options are cumulative. - for found_dir in $ltrpathdirs; do - LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" - done - fi - popdef([P_A_C_K]) - popdef([PACKLIBS]) - popdef([PACKUP]) - popdef([PACK]) - popdef([NAME]) -]) - -dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, -dnl unless already present in VAR. -dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes -dnl contains two or three consecutive elements that belong together. -AC_DEFUN([AC_LIB_APPENDTOVAR], -[ - for element in [$2]; do - haveit= - for x in $[$1]; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X$element"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - [$1]="${[$1]}${[$1]:+ }$element" - fi - done -]) - -dnl For those cases where a variable contains several -L and -l options -dnl referring to unknown libraries and directories, this macro determines the -dnl necessary additional linker options for the runtime path. -dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL]) -dnl sets LDADDVAR to linker options needed together with LIBSVALUE. -dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed, -dnl otherwise linking without libtool is assumed. -AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS], -[ - AC_REQUIRE([AC_LIB_RPATH]) - AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) - $1= - if test "$enable_rpath" != no; then - if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then - dnl Use an explicit option to hardcode directories into the resulting - dnl binary. - rpathdirs= - next= - for opt in $2; do - if test -n "$next"; then - dir="$next" - dnl No need to hardcode the standard /usr/lib. - if test "X$dir" != "X/usr/$acl_libdirstem" \ - && test "X$dir" != "X/usr/$acl_libdirstem2"; then - rpathdirs="$rpathdirs $dir" - fi - next= - else - case $opt in - -L) next=yes ;; - -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'` - dnl No need to hardcode the standard /usr/lib. - if test "X$dir" != "X/usr/$acl_libdirstem" \ - && test "X$dir" != "X/usr/$acl_libdirstem2"; then - rpathdirs="$rpathdirs $dir" - fi - next= ;; - *) next= ;; - esac - fi - done - if test "X$rpathdirs" != "X"; then - if test -n ""$3""; then - dnl libtool is used for linking. Use -R options. - for dir in $rpathdirs; do - $1="${$1}${$1:+ }-R$dir" - done - else - dnl The linker is used for linking directly. - if test -n "$acl_hardcode_libdir_separator"; then - dnl Weird platform: only the last -rpath option counts, the user - dnl must pass all path elements in one option. - alldirs= - for dir in $rpathdirs; do - alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir" - done - acl_save_libdir="$libdir" - libdir="$alldirs" - eval flag=\"$acl_hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - $1="$flag" - else - dnl The -rpath options are cumulative. - for dir in $rpathdirs; do - acl_save_libdir="$libdir" - libdir="$dir" - eval flag=\"$acl_hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - $1="${$1}${$1:+ }$flag" - done - fi - fi - fi - fi - fi - AC_SUBST([$1]) -]) diff --git a/thirdparty/libarchive/build/autoconf/lib-prefix.m4 b/thirdparty/libarchive/build/autoconf/lib-prefix.m4 deleted file mode 100644 index 7e5f0bde0..000000000 --- a/thirdparty/libarchive/build/autoconf/lib-prefix.m4 +++ /dev/null @@ -1,224 +0,0 @@ -# lib-prefix.m4 serial 7 (gettext-0.18) -dnl Copyright (C) 2001-2005, 2008-2011 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl From Bruno Haible. - -dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and -dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't -dnl require excessive bracketing. -ifdef([AC_HELP_STRING], -[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])], -[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])]) - -dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed -dnl to access previously installed libraries. The basic assumption is that -dnl a user will want packages to use other packages he previously installed -dnl with the same --prefix option. -dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate -dnl libraries, but is otherwise very convenient. -AC_DEFUN([AC_LIB_PREFIX], -[ - AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) - AC_REQUIRE([AC_PROG_CC]) - AC_REQUIRE([AC_CANONICAL_HOST]) - AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) - AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) - dnl By default, look in $includedir and $libdir. - use_additional=yes - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - AC_LIB_ARG_WITH([lib-prefix], -[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib - --without-lib-prefix don't search for libraries in includedir and libdir], -[ - if test "X$withval" = "Xno"; then - use_additional=no - else - if test "X$withval" = "X"; then - AC_LIB_WITH_FINAL_PREFIX([ - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - ]) - else - additional_includedir="$withval/include" - additional_libdir="$withval/$acl_libdirstem" - fi - fi -]) - if test $use_additional = yes; then - dnl Potentially add $additional_includedir to $CPPFLAGS. - dnl But don't add it - dnl 1. if it's the standard /usr/include, - dnl 2. if it's already present in $CPPFLAGS, - dnl 3. if it's /usr/local/include and we are using GCC on Linux, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_includedir" != "X/usr/include"; then - haveit= - for x in $CPPFLAGS; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-I$additional_includedir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test "X$additional_includedir" = "X/usr/local/include"; then - if test -n "$GCC"; then - case $host_os in - linux* | gnu* | k*bsd*-gnu) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - if test -d "$additional_includedir"; then - dnl Really add $additional_includedir to $CPPFLAGS. - CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" - fi - fi - fi - fi - dnl Potentially add $additional_libdir to $LDFLAGS. - dnl But don't add it - dnl 1. if it's the standard /usr/lib, - dnl 2. if it's already present in $LDFLAGS, - dnl 3. if it's /usr/local/lib and we are using GCC on Linux, - dnl 4. if it doesn't exist as a directory. - if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then - haveit= - for x in $LDFLAGS; do - AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then - if test -n "$GCC"; then - case $host_os in - linux*) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - dnl Really add $additional_libdir to $LDFLAGS. - LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" - fi - fi - fi - fi - fi -]) - -dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, -dnl acl_final_exec_prefix, containing the values to which $prefix and -dnl $exec_prefix will expand at the end of the configure script. -AC_DEFUN([AC_LIB_PREPARE_PREFIX], -[ - dnl Unfortunately, prefix and exec_prefix get only finally determined - dnl at the end of configure. - if test "X$prefix" = "XNONE"; then - acl_final_prefix="$ac_default_prefix" - else - acl_final_prefix="$prefix" - fi - if test "X$exec_prefix" = "XNONE"; then - acl_final_exec_prefix='${prefix}' - else - acl_final_exec_prefix="$exec_prefix" - fi - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" - prefix="$acl_save_prefix" -]) - -dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the -dnl variables prefix and exec_prefix bound to the values they will have -dnl at the end of the configure script. -AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], -[ - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - $1 - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" -]) - -dnl AC_LIB_PREPARE_MULTILIB creates -dnl - a variable acl_libdirstem, containing the basename of the libdir, either -dnl "lib" or "lib64" or "lib/64", -dnl - a variable acl_libdirstem2, as a secondary possible value for -dnl acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or -dnl "lib/amd64". -AC_DEFUN([AC_LIB_PREPARE_MULTILIB], -[ - dnl There is no formal standard regarding lib and lib64. - dnl On glibc systems, the current practice is that on a system supporting - dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under - dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine - dnl the compiler's default mode by looking at the compiler's library search - dnl path. If at least one of its elements ends in /lib64 or points to a - dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI. - dnl Otherwise we use the default, namely "lib". - dnl On Solaris systems, the current practice is that on a system supporting - dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under - dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or - dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib. - AC_REQUIRE([AC_CANONICAL_HOST]) - acl_libdirstem=lib - acl_libdirstem2= - case "$host_os" in - solaris*) - dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment - dnl . - dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link." - dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the - dnl symlink is missing, so we set acl_libdirstem2 too. - AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit], - [AC_EGREP_CPP([sixtyfour bits], [ -#ifdef _LP64 -sixtyfour bits -#endif - ], [gl_cv_solaris_64bit=yes], [gl_cv_solaris_64bit=no]) - ]) - if test $gl_cv_solaris_64bit = yes; then - acl_libdirstem=lib/64 - case "$host_cpu" in - sparc*) acl_libdirstem2=lib/sparcv9 ;; - i*86 | x86_64) acl_libdirstem2=lib/amd64 ;; - esac - fi - ;; - *) - searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` - if test -n "$searchpath"; then - acl_save_IFS="${IFS= }"; IFS=":" - for searchdir in $searchpath; do - if test -d "$searchdir"; then - case "$searchdir" in - */lib64/ | */lib64 ) acl_libdirstem=lib64 ;; - */../ | */.. ) - # Better ignore directories of this form. They are misleading. - ;; - *) searchdir=`cd "$searchdir" && pwd` - case "$searchdir" in - */lib64 ) acl_libdirstem=lib64 ;; - esac ;; - esac - fi - done - IFS="$acl_save_IFS" - fi - ;; - esac - test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" -]) diff --git a/thirdparty/libarchive/build/autoconf/ltmain.sh b/thirdparty/libarchive/build/autoconf/ltmain.sh deleted file mode 100755 index 540a92ab5..000000000 --- a/thirdparty/libarchive/build/autoconf/ltmain.sh +++ /dev/null @@ -1,11251 +0,0 @@ -#! /bin/sh -## DO NOT EDIT - This file generated from ./build-aux/ltmain.in -## by inline-source v2014-01-03.01 - -# libtool (GNU libtool) 2.4.6 -# Provide generalized library-building support services. -# Written by Gordon Matzigkeit , 1996 - -# Copyright (C) 1996-2015 Free Software Foundation, Inc. -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -# GNU Libtool is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# As a special exception to the GNU General Public License, -# if you distribute this file as part of a program or library that -# is built using GNU Libtool, you may include this file under the -# same distribution terms that you use for the rest of that program. -# -# GNU Libtool is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - - -PROGRAM=libtool -PACKAGE=libtool -VERSION="2.4.6 Debian-2.4.6-15build2" -package_revision=2.4.6 - - -## ------ ## -## Usage. ## -## ------ ## - -# Run './libtool --help' for help with using this script from the -# command line. - - -## ------------------------------- ## -## User overridable command paths. ## -## ------------------------------- ## - -# After configure completes, it has a better idea of some of the -# shell tools we need than the defaults used by the functions shared -# with bootstrap, so set those here where they can still be over- -# ridden by the user, but otherwise take precedence. - -: ${AUTOCONF="autoconf"} -: ${AUTOMAKE="automake"} - - -## -------------------------- ## -## Source external libraries. ## -## -------------------------- ## - -# Much of our low-level functionality needs to be sourced from external -# libraries, which are installed to $pkgauxdir. - -# Set a version string for this script. -scriptversion=2015-01-20.17; # UTC - -# General shell script boiler plate, and helper functions. -# Written by Gary V. Vaughan, 2004 - -# Copyright (C) 2004-2015 Free Software Foundation, Inc. -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. - -# As a special exception to the GNU General Public License, if you distribute -# this file as part of a program or library that is built using GNU Libtool, -# you may include this file under the same distribution terms that you use -# for the rest of that program. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Please report bugs or propose patches to gary@gnu.org. - - -## ------ ## -## Usage. ## -## ------ ## - -# Evaluate this file near the top of your script to gain access to -# the functions and variables defined here: -# -# . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh -# -# If you need to override any of the default environment variable -# settings, do that before evaluating this file. - - -## -------------------- ## -## Shell normalisation. ## -## -------------------- ## - -# Some shells need a little help to be as Bourne compatible as possible. -# Before doing anything else, make sure all that help has been provided! - -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac -fi - -# NLS nuisances: We save the old values in case they are required later. -_G_user_locale= -_G_safe_locale= -for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES -do - eval "if test set = \"\${$_G_var+set}\"; then - save_$_G_var=\$$_G_var - $_G_var=C - export $_G_var - _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" - _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" - fi" -done - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -# Make sure IFS has a sensible default -sp=' ' -nl=' -' -IFS="$sp $nl" - -# There are apparently some retarded systems that use ';' as a PATH separator! -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - - -## ------------------------- ## -## Locate command utilities. ## -## ------------------------- ## - - -# func_executable_p FILE -# ---------------------- -# Check that FILE is an executable regular file. -func_executable_p () -{ - test -f "$1" && test -x "$1" -} - - -# func_path_progs PROGS_LIST CHECK_FUNC [PATH] -# -------------------------------------------- -# Search for either a program that responds to --version with output -# containing "GNU", or else returned by CHECK_FUNC otherwise, by -# trying all the directories in PATH with each of the elements of -# PROGS_LIST. -# -# CHECK_FUNC should accept the path to a candidate program, and -# set $func_check_prog_result if it truncates its output less than -# $_G_path_prog_max characters. -func_path_progs () -{ - _G_progs_list=$1 - _G_check_func=$2 - _G_PATH=${3-"$PATH"} - - _G_path_prog_max=0 - _G_path_prog_found=false - _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} - for _G_dir in $_G_PATH; do - IFS=$_G_save_IFS - test -z "$_G_dir" && _G_dir=. - for _G_prog_name in $_G_progs_list; do - for _exeext in '' .EXE; do - _G_path_prog=$_G_dir/$_G_prog_name$_exeext - func_executable_p "$_G_path_prog" || continue - case `"$_G_path_prog" --version 2>&1` in - *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; - *) $_G_check_func $_G_path_prog - func_path_progs_result=$func_check_prog_result - ;; - esac - $_G_path_prog_found && break 3 - done - done - done - IFS=$_G_save_IFS - test -z "$func_path_progs_result" && { - echo "no acceptable sed could be found in \$PATH" >&2 - exit 1 - } -} - - -# We want to be able to use the functions in this file before configure -# has figured out where the best binaries are kept, which means we have -# to search for them ourselves - except when the results are already set -# where we skip the searches. - -# Unless the user overrides by setting SED, search the path for either GNU -# sed, or the sed that truncates its output the least. -test -z "$SED" && { - _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ - for _G_i in 1 2 3 4 5 6 7; do - _G_sed_script=$_G_sed_script$nl$_G_sed_script - done - echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed - _G_sed_script= - - func_check_prog_sed () - { - _G_path_prog=$1 - - _G_count=0 - printf 0123456789 >conftest.in - while : - do - cat conftest.in conftest.in >conftest.tmp - mv conftest.tmp conftest.in - cp conftest.in conftest.nl - echo '' >> conftest.nl - "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break - diff conftest.out conftest.nl >/dev/null 2>&1 || break - _G_count=`expr $_G_count + 1` - if test "$_G_count" -gt "$_G_path_prog_max"; then - # Best one so far, save it but keep looking for a better one - func_check_prog_result=$_G_path_prog - _G_path_prog_max=$_G_count - fi - # 10*(2^10) chars as input seems more than enough - test 10 -lt "$_G_count" && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out - } - - func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin - rm -f conftest.sed - SED=$func_path_progs_result -} - - -# Unless the user overrides by setting GREP, search the path for either GNU -# grep, or the grep that truncates its output the least. -test -z "$GREP" && { - func_check_prog_grep () - { - _G_path_prog=$1 - - _G_count=0 - _G_path_prog_max=0 - printf 0123456789 >conftest.in - while : - do - cat conftest.in conftest.in >conftest.tmp - mv conftest.tmp conftest.in - cp conftest.in conftest.nl - echo 'GREP' >> conftest.nl - "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break - diff conftest.out conftest.nl >/dev/null 2>&1 || break - _G_count=`expr $_G_count + 1` - if test "$_G_count" -gt "$_G_path_prog_max"; then - # Best one so far, save it but keep looking for a better one - func_check_prog_result=$_G_path_prog - _G_path_prog_max=$_G_count - fi - # 10*(2^10) chars as input seems more than enough - test 10 -lt "$_G_count" && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out - } - - func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin - GREP=$func_path_progs_result -} - - -## ------------------------------- ## -## User overridable command paths. ## -## ------------------------------- ## - -# All uppercase variable names are used for environment variables. These -# variables can be overridden by the user before calling a script that -# uses them if a suitable command of that name is not already available -# in the command search PATH. - -: ${CP="cp -f"} -: ${ECHO="printf %s\n"} -: ${EGREP="$GREP -E"} -: ${FGREP="$GREP -F"} -: ${LN_S="ln -s"} -: ${MAKE="make"} -: ${MKDIR="mkdir"} -: ${MV="mv -f"} -: ${RM="rm -f"} -: ${SHELL="${CONFIG_SHELL-/bin/sh}"} - - -## -------------------- ## -## Useful sed snippets. ## -## -------------------- ## - -sed_dirname='s|/[^/]*$||' -sed_basename='s|^.*/||' - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -sed_quote_subst='s|\([`"$\\]\)|\\\1|g' - -# Same as above, but do not quote variable references. -sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' - -# Sed substitution that turns a string into a regex matching for the -# string literally. -sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' - -# Sed substitution that converts a w32 file name or path -# that contains forward slashes, into one that contains -# (escaped) backslashes. A very naive implementation. -sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' - -# Re-'\' parameter expansions in output of sed_double_quote_subst that -# were '\'-ed in input to the same. If an odd number of '\' preceded a -# '$' in input to sed_double_quote_subst, that '$' was protected from -# expansion. Since each input '\' is now two '\'s, look for any number -# of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. -_G_bs='\\' -_G_bs2='\\\\' -_G_bs4='\\\\\\\\' -_G_dollar='\$' -sed_double_backslash="\ - s/$_G_bs4/&\\ -/g - s/^$_G_bs2$_G_dollar/$_G_bs&/ - s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g - s/\n//g" - - -## ----------------- ## -## Global variables. ## -## ----------------- ## - -# Except for the global variables explicitly listed below, the following -# functions in the '^func_' namespace, and the '^require_' namespace -# variables initialised in the 'Resource management' section, sourcing -# this file will not pollute your global namespace with anything -# else. There's no portable way to scope variables in Bourne shell -# though, so actually running these functions will sometimes place -# results into a variable named after the function, and often use -# temporary variables in the '^_G_' namespace. If you are careful to -# avoid using those namespaces casually in your sourcing script, things -# should continue to work as you expect. And, of course, you can freely -# overwrite any of the functions or variables defined here before -# calling anything to customize them. - -EXIT_SUCCESS=0 -EXIT_FAILURE=1 -EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. -EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. - -# Allow overriding, eg assuming that you follow the convention of -# putting '$debug_cmd' at the start of all your functions, you can get -# bash to show function call trace with: -# -# debug_cmd='echo "${FUNCNAME[0]} $*" >&2' bash your-script-name -debug_cmd=${debug_cmd-":"} -exit_cmd=: - -# By convention, finish your script with: -# -# exit $exit_status -# -# so that you can set exit_status to non-zero if you want to indicate -# something went wrong during execution without actually bailing out at -# the point of failure. -exit_status=$EXIT_SUCCESS - -# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh -# is ksh but when the shell is invoked as "sh" and the current value of -# the _XPG environment variable is not equal to 1 (one), the special -# positional parameter $0, within a function call, is the name of the -# function. -progpath=$0 - -# The name of this program. -progname=`$ECHO "$progpath" |$SED "$sed_basename"` - -# Make sure we have an absolute progpath for reexecution: -case $progpath in - [\\/]*|[A-Za-z]:\\*) ;; - *[\\/]*) - progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` - progdir=`cd "$progdir" && pwd` - progpath=$progdir/$progname - ;; - *) - _G_IFS=$IFS - IFS=${PATH_SEPARATOR-:} - for progdir in $PATH; do - IFS=$_G_IFS - test -x "$progdir/$progname" && break - done - IFS=$_G_IFS - test -n "$progdir" || progdir=`pwd` - progpath=$progdir/$progname - ;; -esac - - -## ----------------- ## -## Standard options. ## -## ----------------- ## - -# The following options affect the operation of the functions defined -# below, and should be set appropriately depending on run-time para- -# meters passed on the command line. - -opt_dry_run=false -opt_quiet=false -opt_verbose=false - -# Categories 'all' and 'none' are always available. Append any others -# you will pass as the first argument to func_warning from your own -# code. -warning_categories= - -# By default, display warnings according to 'opt_warning_types'. Set -# 'warning_func' to ':' to elide all warnings, or func_fatal_error to -# treat the next displayed warning as a fatal error. -warning_func=func_warn_and_continue - -# Set to 'all' to display all warnings, 'none' to suppress all -# warnings, or a space delimited list of some subset of -# 'warning_categories' to display only the listed warnings. -opt_warning_types=all - - -## -------------------- ## -## Resource management. ## -## -------------------- ## - -# This section contains definitions for functions that each ensure a -# particular resource (a file, or a non-empty configuration variable for -# example) is available, and if appropriate to extract default values -# from pertinent package files. Call them using their associated -# 'require_*' variable to ensure that they are executed, at most, once. -# -# It's entirely deliberate that calling these functions can set -# variables that don't obey the namespace limitations obeyed by the rest -# of this file, in order that that they be as useful as possible to -# callers. - - -# require_term_colors -# ------------------- -# Allow display of bold text on terminals that support it. -require_term_colors=func_require_term_colors -func_require_term_colors () -{ - $debug_cmd - - test -t 1 && { - # COLORTERM and USE_ANSI_COLORS environment variables take - # precedence, because most terminfo databases neglect to describe - # whether color sequences are supported. - test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} - - if test 1 = "$USE_ANSI_COLORS"; then - # Standard ANSI escape sequences - tc_reset='' - tc_bold=''; tc_standout='' - tc_red=''; tc_green='' - tc_blue=''; tc_cyan='' - else - # Otherwise trust the terminfo database after all. - test -n "`tput sgr0 2>/dev/null`" && { - tc_reset=`tput sgr0` - test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` - tc_standout=$tc_bold - test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` - test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` - test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` - test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` - test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` - } - fi - } - - require_term_colors=: -} - - -## ----------------- ## -## Function library. ## -## ----------------- ## - -# This section contains a variety of useful functions to call in your -# scripts. Take note of the portable wrappers for features provided by -# some modern shells, which will fall back to slower equivalents on -# less featureful shells. - - -# func_append VAR VALUE -# --------------------- -# Append VALUE onto the existing contents of VAR. - - # We should try to minimise forks, especially on Windows where they are - # unreasonably slow, so skip the feature probes when bash or zsh are - # being used: - if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then - : ${_G_HAVE_ARITH_OP="yes"} - : ${_G_HAVE_XSI_OPS="yes"} - # The += operator was introduced in bash 3.1 - case $BASH_VERSION in - [12].* | 3.0 | 3.0*) ;; - *) - : ${_G_HAVE_PLUSEQ_OP="yes"} - ;; - esac - fi - - # _G_HAVE_PLUSEQ_OP - # Can be empty, in which case the shell is probed, "yes" if += is - # useable or anything else if it does not work. - test -z "$_G_HAVE_PLUSEQ_OP" \ - && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ - && _G_HAVE_PLUSEQ_OP=yes - -if test yes = "$_G_HAVE_PLUSEQ_OP" -then - # This is an XSI compatible shell, allowing a faster implementation... - eval 'func_append () - { - $debug_cmd - - eval "$1+=\$2" - }' -else - # ...otherwise fall back to using expr, which is often a shell builtin. - func_append () - { - $debug_cmd - - eval "$1=\$$1\$2" - } -fi - - -# func_append_quoted VAR VALUE -# ---------------------------- -# Quote VALUE and append to the end of shell variable VAR, separated -# by a space. -if test yes = "$_G_HAVE_PLUSEQ_OP"; then - eval 'func_append_quoted () - { - $debug_cmd - - func_quote_for_eval "$2" - eval "$1+=\\ \$func_quote_for_eval_result" - }' -else - func_append_quoted () - { - $debug_cmd - - func_quote_for_eval "$2" - eval "$1=\$$1\\ \$func_quote_for_eval_result" - } -fi - - -# func_append_uniq VAR VALUE -# -------------------------- -# Append unique VALUE onto the existing contents of VAR, assuming -# entries are delimited by the first character of VALUE. For example: -# -# func_append_uniq options " --another-option option-argument" -# -# will only append to $options if " --another-option option-argument " -# is not already present somewhere in $options already (note spaces at -# each end implied by leading space in second argument). -func_append_uniq () -{ - $debug_cmd - - eval _G_current_value='`$ECHO $'$1'`' - _G_delim=`expr "$2" : '\(.\)'` - - case $_G_delim$_G_current_value$_G_delim in - *"$2$_G_delim"*) ;; - *) func_append "$@" ;; - esac -} - - -# func_arith TERM... -# ------------------ -# Set func_arith_result to the result of evaluating TERMs. - test -z "$_G_HAVE_ARITH_OP" \ - && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ - && _G_HAVE_ARITH_OP=yes - -if test yes = "$_G_HAVE_ARITH_OP"; then - eval 'func_arith () - { - $debug_cmd - - func_arith_result=$(( $* )) - }' -else - func_arith () - { - $debug_cmd - - func_arith_result=`expr "$@"` - } -fi - - -# func_basename FILE -# ------------------ -# Set func_basename_result to FILE with everything up to and including -# the last / stripped. -if test yes = "$_G_HAVE_XSI_OPS"; then - # If this shell supports suffix pattern removal, then use it to avoid - # forking. Hide the definitions single quotes in case the shell chokes - # on unsupported syntax... - _b='func_basename_result=${1##*/}' - _d='case $1 in - */*) func_dirname_result=${1%/*}$2 ;; - * ) func_dirname_result=$3 ;; - esac' - -else - # ...otherwise fall back to using sed. - _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' - _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` - if test "X$func_dirname_result" = "X$1"; then - func_dirname_result=$3 - else - func_append func_dirname_result "$2" - fi' -fi - -eval 'func_basename () -{ - $debug_cmd - - '"$_b"' -}' - - -# func_dirname FILE APPEND NONDIR_REPLACEMENT -# ------------------------------------------- -# Compute the dirname of FILE. If nonempty, add APPEND to the result, -# otherwise set result to NONDIR_REPLACEMENT. -eval 'func_dirname () -{ - $debug_cmd - - '"$_d"' -}' - - -# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT -# -------------------------------------------------------- -# Perform func_basename and func_dirname in a single function -# call: -# dirname: Compute the dirname of FILE. If nonempty, -# add APPEND to the result, otherwise set result -# to NONDIR_REPLACEMENT. -# value returned in "$func_dirname_result" -# basename: Compute filename of FILE. -# value retuned in "$func_basename_result" -# For efficiency, we do not delegate to the functions above but instead -# duplicate the functionality here. -eval 'func_dirname_and_basename () -{ - $debug_cmd - - '"$_b"' - '"$_d"' -}' - - -# func_echo ARG... -# ---------------- -# Echo program name prefixed message. -func_echo () -{ - $debug_cmd - - _G_message=$* - - func_echo_IFS=$IFS - IFS=$nl - for _G_line in $_G_message; do - IFS=$func_echo_IFS - $ECHO "$progname: $_G_line" - done - IFS=$func_echo_IFS -} - - -# func_echo_all ARG... -# -------------------- -# Invoke $ECHO with all args, space-separated. -func_echo_all () -{ - $ECHO "$*" -} - - -# func_echo_infix_1 INFIX ARG... -# ------------------------------ -# Echo program name, followed by INFIX on the first line, with any -# additional lines not showing INFIX. -func_echo_infix_1 () -{ - $debug_cmd - - $require_term_colors - - _G_infix=$1; shift - _G_indent=$_G_infix - _G_prefix="$progname: $_G_infix: " - _G_message=$* - - # Strip color escape sequences before counting printable length - for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" - do - test -n "$_G_tc" && { - _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` - _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` - } - done - _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes - - func_echo_infix_1_IFS=$IFS - IFS=$nl - for _G_line in $_G_message; do - IFS=$func_echo_infix_1_IFS - $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 - _G_prefix=$_G_indent - done - IFS=$func_echo_infix_1_IFS -} - - -# func_error ARG... -# ----------------- -# Echo program name prefixed message to standard error. -func_error () -{ - $debug_cmd - - $require_term_colors - - func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 -} - - -# func_fatal_error ARG... -# ----------------------- -# Echo program name prefixed message to standard error, and exit. -func_fatal_error () -{ - $debug_cmd - - func_error "$*" - exit $EXIT_FAILURE -} - - -# func_grep EXPRESSION FILENAME -# ----------------------------- -# Check whether EXPRESSION matches any line of FILENAME, without output. -func_grep () -{ - $debug_cmd - - $GREP "$1" "$2" >/dev/null 2>&1 -} - - -# func_len STRING -# --------------- -# Set func_len_result to the length of STRING. STRING may not -# start with a hyphen. - test -z "$_G_HAVE_XSI_OPS" \ - && (eval 'x=a/b/c; - test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ - && _G_HAVE_XSI_OPS=yes - -if test yes = "$_G_HAVE_XSI_OPS"; then - eval 'func_len () - { - $debug_cmd - - func_len_result=${#1} - }' -else - func_len () - { - $debug_cmd - - func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` - } -fi - - -# func_mkdir_p DIRECTORY-PATH -# --------------------------- -# Make sure the entire path to DIRECTORY-PATH is available. -func_mkdir_p () -{ - $debug_cmd - - _G_directory_path=$1 - _G_dir_list= - - if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then - - # Protect directory names starting with '-' - case $_G_directory_path in - -*) _G_directory_path=./$_G_directory_path ;; - esac - - # While some portion of DIR does not yet exist... - while test ! -d "$_G_directory_path"; do - # ...make a list in topmost first order. Use a colon delimited - # list incase some portion of path contains whitespace. - _G_dir_list=$_G_directory_path:$_G_dir_list - - # If the last portion added has no slash in it, the list is done - case $_G_directory_path in */*) ;; *) break ;; esac - - # ...otherwise throw away the child directory and loop - _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` - done - _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` - - func_mkdir_p_IFS=$IFS; IFS=: - for _G_dir in $_G_dir_list; do - IFS=$func_mkdir_p_IFS - # mkdir can fail with a 'File exist' error if two processes - # try to create one of the directories concurrently. Don't - # stop in that case! - $MKDIR "$_G_dir" 2>/dev/null || : - done - IFS=$func_mkdir_p_IFS - - # Bail out if we (or some other process) failed to create a directory. - test -d "$_G_directory_path" || \ - func_fatal_error "Failed to create '$1'" - fi -} - - -# func_mktempdir [BASENAME] -# ------------------------- -# Make a temporary directory that won't clash with other running -# libtool processes, and avoids race conditions if possible. If -# given, BASENAME is the basename for that directory. -func_mktempdir () -{ - $debug_cmd - - _G_template=${TMPDIR-/tmp}/${1-$progname} - - if test : = "$opt_dry_run"; then - # Return a directory name, but don't create it in dry-run mode - _G_tmpdir=$_G_template-$$ - else - - # If mktemp works, use that first and foremost - _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` - - if test ! -d "$_G_tmpdir"; then - # Failing that, at least try and use $RANDOM to avoid a race - _G_tmpdir=$_G_template-${RANDOM-0}$$ - - func_mktempdir_umask=`umask` - umask 0077 - $MKDIR "$_G_tmpdir" - umask $func_mktempdir_umask - fi - - # If we're not in dry-run mode, bomb out on failure - test -d "$_G_tmpdir" || \ - func_fatal_error "cannot create temporary directory '$_G_tmpdir'" - fi - - $ECHO "$_G_tmpdir" -} - - -# func_normal_abspath PATH -# ------------------------ -# Remove doubled-up and trailing slashes, "." path components, -# and cancel out any ".." path components in PATH after making -# it an absolute path. -func_normal_abspath () -{ - $debug_cmd - - # These SED scripts presuppose an absolute path with a trailing slash. - _G_pathcar='s|^/\([^/]*\).*$|\1|' - _G_pathcdr='s|^/[^/]*||' - _G_removedotparts=':dotsl - s|/\./|/|g - t dotsl - s|/\.$|/|' - _G_collapseslashes='s|/\{1,\}|/|g' - _G_finalslash='s|/*$|/|' - - # Start from root dir and reassemble the path. - func_normal_abspath_result= - func_normal_abspath_tpath=$1 - func_normal_abspath_altnamespace= - case $func_normal_abspath_tpath in - "") - # Empty path, that just means $cwd. - func_stripname '' '/' "`pwd`" - func_normal_abspath_result=$func_stripname_result - return - ;; - # The next three entries are used to spot a run of precisely - # two leading slashes without using negated character classes; - # we take advantage of case's first-match behaviour. - ///*) - # Unusual form of absolute path, do nothing. - ;; - //*) - # Not necessarily an ordinary path; POSIX reserves leading '//' - # and for example Cygwin uses it to access remote file shares - # over CIFS/SMB, so we conserve a leading double slash if found. - func_normal_abspath_altnamespace=/ - ;; - /*) - # Absolute path, do nothing. - ;; - *) - # Relative path, prepend $cwd. - func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath - ;; - esac - - # Cancel out all the simple stuff to save iterations. We also want - # the path to end with a slash for ease of parsing, so make sure - # there is one (and only one) here. - func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` - while :; do - # Processed it all yet? - if test / = "$func_normal_abspath_tpath"; then - # If we ascended to the root using ".." the result may be empty now. - if test -z "$func_normal_abspath_result"; then - func_normal_abspath_result=/ - fi - break - fi - func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$_G_pathcar"` - func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$_G_pathcdr"` - # Figure out what to do with it - case $func_normal_abspath_tcomponent in - "") - # Trailing empty path component, ignore it. - ;; - ..) - # Parent dir; strip last assembled component from result. - func_dirname "$func_normal_abspath_result" - func_normal_abspath_result=$func_dirname_result - ;; - *) - # Actual path component, append it. - func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" - ;; - esac - done - # Restore leading double-slash if one was found on entry. - func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result -} - - -# func_notquiet ARG... -# -------------------- -# Echo program name prefixed message only when not in quiet mode. -func_notquiet () -{ - $debug_cmd - - $opt_quiet || func_echo ${1+"$@"} - - # A bug in bash halts the script if the last line of a function - # fails when set -e is in force, so we need another command to - # work around that: - : -} - - -# func_relative_path SRCDIR DSTDIR -# -------------------------------- -# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. -func_relative_path () -{ - $debug_cmd - - func_relative_path_result= - func_normal_abspath "$1" - func_relative_path_tlibdir=$func_normal_abspath_result - func_normal_abspath "$2" - func_relative_path_tbindir=$func_normal_abspath_result - - # Ascend the tree starting from libdir - while :; do - # check if we have found a prefix of bindir - case $func_relative_path_tbindir in - $func_relative_path_tlibdir) - # found an exact match - func_relative_path_tcancelled= - break - ;; - $func_relative_path_tlibdir*) - # found a matching prefix - func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" - func_relative_path_tcancelled=$func_stripname_result - if test -z "$func_relative_path_result"; then - func_relative_path_result=. - fi - break - ;; - *) - func_dirname $func_relative_path_tlibdir - func_relative_path_tlibdir=$func_dirname_result - if test -z "$func_relative_path_tlibdir"; then - # Have to descend all the way to the root! - func_relative_path_result=../$func_relative_path_result - func_relative_path_tcancelled=$func_relative_path_tbindir - break - fi - func_relative_path_result=../$func_relative_path_result - ;; - esac - done - - # Now calculate path; take care to avoid doubling-up slashes. - func_stripname '' '/' "$func_relative_path_result" - func_relative_path_result=$func_stripname_result - func_stripname '/' '/' "$func_relative_path_tcancelled" - if test -n "$func_stripname_result"; then - func_append func_relative_path_result "/$func_stripname_result" - fi - - # Normalisation. If bindir is libdir, return '.' else relative path. - if test -n "$func_relative_path_result"; then - func_stripname './' '' "$func_relative_path_result" - func_relative_path_result=$func_stripname_result - fi - - test -n "$func_relative_path_result" || func_relative_path_result=. - - : -} - - -# func_quote_for_eval ARG... -# -------------------------- -# Aesthetically quote ARGs to be evaled later. -# This function returns two values: -# i) func_quote_for_eval_result -# double-quoted, suitable for a subsequent eval -# ii) func_quote_for_eval_unquoted_result -# has all characters that are still active within double -# quotes backslashified. -func_quote_for_eval () -{ - $debug_cmd - - func_quote_for_eval_unquoted_result= - func_quote_for_eval_result= - while test 0 -lt $#; do - case $1 in - *[\\\`\"\$]*) - _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; - *) - _G_unquoted_arg=$1 ;; - esac - if test -n "$func_quote_for_eval_unquoted_result"; then - func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" - else - func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" - fi - - case $_G_unquoted_arg in - # Double-quote args containing shell metacharacters to delay - # word splitting, command substitution and variable expansion - # for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - _G_quoted_arg=\"$_G_unquoted_arg\" - ;; - *) - _G_quoted_arg=$_G_unquoted_arg - ;; - esac - - if test -n "$func_quote_for_eval_result"; then - func_append func_quote_for_eval_result " $_G_quoted_arg" - else - func_append func_quote_for_eval_result "$_G_quoted_arg" - fi - shift - done -} - - -# func_quote_for_expand ARG -# ------------------------- -# Aesthetically quote ARG to be evaled later; same as above, -# but do not quote variable references. -func_quote_for_expand () -{ - $debug_cmd - - case $1 in - *[\\\`\"]*) - _G_arg=`$ECHO "$1" | $SED \ - -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; - *) - _G_arg=$1 ;; - esac - - case $_G_arg in - # Double-quote args containing shell metacharacters to delay - # word splitting and command substitution for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - _G_arg=\"$_G_arg\" - ;; - esac - - func_quote_for_expand_result=$_G_arg -} - - -# func_stripname PREFIX SUFFIX NAME -# --------------------------------- -# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -if test yes = "$_G_HAVE_XSI_OPS"; then - eval 'func_stripname () - { - $debug_cmd - - # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are - # positional parameters, so assign one to ordinary variable first. - func_stripname_result=$3 - func_stripname_result=${func_stripname_result#"$1"} - func_stripname_result=${func_stripname_result%"$2"} - }' -else - func_stripname () - { - $debug_cmd - - case $2 in - .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; - *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; - esac - } -fi - - -# func_show_eval CMD [FAIL_EXP] -# ----------------------------- -# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is -# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP -# is given, then evaluate it. -func_show_eval () -{ - $debug_cmd - - _G_cmd=$1 - _G_fail_exp=${2-':'} - - func_quote_for_expand "$_G_cmd" - eval "func_notquiet $func_quote_for_expand_result" - - $opt_dry_run || { - eval "$_G_cmd" - _G_status=$? - if test 0 -ne "$_G_status"; then - eval "(exit $_G_status); $_G_fail_exp" - fi - } -} - - -# func_show_eval_locale CMD [FAIL_EXP] -# ------------------------------------ -# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is -# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP -# is given, then evaluate it. Use the saved locale for evaluation. -func_show_eval_locale () -{ - $debug_cmd - - _G_cmd=$1 - _G_fail_exp=${2-':'} - - $opt_quiet || { - func_quote_for_expand "$_G_cmd" - eval "func_echo $func_quote_for_expand_result" - } - - $opt_dry_run || { - eval "$_G_user_locale - $_G_cmd" - _G_status=$? - eval "$_G_safe_locale" - if test 0 -ne "$_G_status"; then - eval "(exit $_G_status); $_G_fail_exp" - fi - } -} - - -# func_tr_sh -# ---------- -# Turn $1 into a string suitable for a shell variable name. -# Result is stored in $func_tr_sh_result. All characters -# not in the set a-zA-Z0-9_ are replaced with '_'. Further, -# if $1 begins with a digit, a '_' is prepended as well. -func_tr_sh () -{ - $debug_cmd - - case $1 in - [0-9]* | *[!a-zA-Z0-9_]*) - func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` - ;; - * ) - func_tr_sh_result=$1 - ;; - esac -} - - -# func_verbose ARG... -# ------------------- -# Echo program name prefixed message in verbose mode only. -func_verbose () -{ - $debug_cmd - - $opt_verbose && func_echo "$*" - - : -} - - -# func_warn_and_continue ARG... -# ----------------------------- -# Echo program name prefixed warning message to standard error. -func_warn_and_continue () -{ - $debug_cmd - - $require_term_colors - - func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 -} - - -# func_warning CATEGORY ARG... -# ---------------------------- -# Echo program name prefixed warning message to standard error. Warning -# messages can be filtered according to CATEGORY, where this function -# elides messages where CATEGORY is not listed in the global variable -# 'opt_warning_types'. -func_warning () -{ - $debug_cmd - - # CATEGORY must be in the warning_categories list! - case " $warning_categories " in - *" $1 "*) ;; - *) func_internal_error "invalid warning category '$1'" ;; - esac - - _G_category=$1 - shift - - case " $opt_warning_types " in - *" $_G_category "*) $warning_func ${1+"$@"} ;; - esac -} - - -# func_sort_ver VER1 VER2 -# ----------------------- -# 'sort -V' is not generally available. -# Note this deviates from the version comparison in automake -# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a -# but this should suffice as we won't be specifying old -# version formats or redundant trailing .0 in bootstrap.conf. -# If we did want full compatibility then we should probably -# use m4_version_compare from autoconf. -func_sort_ver () -{ - $debug_cmd - - printf '%s\n%s\n' "$1" "$2" \ - | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n -} - -# func_lt_ver PREV CURR -# --------------------- -# Return true if PREV and CURR are in the correct order according to -# func_sort_ver, otherwise false. Use it like this: -# -# func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." -func_lt_ver () -{ - $debug_cmd - - test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` -} - - -# Local variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" -# time-stamp-time-zone: "UTC" -# End: -#! /bin/sh - -# Set a version string for this script. -scriptversion=2015-10-07.11; # UTC - -# A portable, pluggable option parser for Bourne shell. -# Written by Gary V. Vaughan, 2010 - -# Copyright (C) 2010-2015 Free Software Foundation, Inc. -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Please report bugs or propose patches to gary@gnu.org. - - -## ------ ## -## Usage. ## -## ------ ## - -# This file is a library for parsing options in your shell scripts along -# with assorted other useful supporting features that you can make use -# of too. -# -# For the simplest scripts you might need only: -# -# #!/bin/sh -# . relative/path/to/funclib.sh -# . relative/path/to/options-parser -# scriptversion=1.0 -# func_options ${1+"$@"} -# eval set dummy "$func_options_result"; shift -# ...rest of your script... -# -# In order for the '--version' option to work, you will need to have a -# suitably formatted comment like the one at the top of this file -# starting with '# Written by ' and ending with '# warranty; '. -# -# For '-h' and '--help' to work, you will also need a one line -# description of your script's purpose in a comment directly above the -# '# Written by ' line, like the one at the top of this file. -# -# The default options also support '--debug', which will turn on shell -# execution tracing (see the comment above debug_cmd below for another -# use), and '--verbose' and the func_verbose function to allow your script -# to display verbose messages only when your user has specified -# '--verbose'. -# -# After sourcing this file, you can plug processing for additional -# options by amending the variables from the 'Configuration' section -# below, and following the instructions in the 'Option parsing' -# section further down. - -## -------------- ## -## Configuration. ## -## -------------- ## - -# You should override these variables in your script after sourcing this -# file so that they reflect the customisations you have added to the -# option parser. - -# The usage line for option parsing errors and the start of '-h' and -# '--help' output messages. You can embed shell variables for delayed -# expansion at the time the message is displayed, but you will need to -# quote other shell meta-characters carefully to prevent them being -# expanded when the contents are evaled. -usage='$progpath [OPTION]...' - -# Short help message in response to '-h' and '--help'. Add to this or -# override it after sourcing this library to reflect the full set of -# options your script accepts. -usage_message="\ - --debug enable verbose shell tracing - -W, --warnings=CATEGORY - report the warnings falling in CATEGORY [all] - -v, --verbose verbosely report processing - --version print version information and exit - -h, --help print short or long help message and exit -" - -# Additional text appended to 'usage_message' in response to '--help'. -long_help_message=" -Warning categories include: - 'all' show all warnings - 'none' turn off all the warnings - 'error' warnings are treated as fatal errors" - -# Help message printed before fatal option parsing errors. -fatal_help="Try '\$progname --help' for more information." - - - -## ------------------------- ## -## Hook function management. ## -## ------------------------- ## - -# This section contains functions for adding, removing, and running hooks -# to the main code. A hook is just a named list of of function, that can -# be run in order later on. - -# func_hookable FUNC_NAME -# ----------------------- -# Declare that FUNC_NAME will run hooks added with -# 'func_add_hook FUNC_NAME ...'. -func_hookable () -{ - $debug_cmd - - func_append hookable_fns " $1" -} - - -# func_add_hook FUNC_NAME HOOK_FUNC -# --------------------------------- -# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must -# first have been declared "hookable" by a call to 'func_hookable'. -func_add_hook () -{ - $debug_cmd - - case " $hookable_fns " in - *" $1 "*) ;; - *) func_fatal_error "'$1' does not accept hook functions." ;; - esac - - eval func_append ${1}_hooks '" $2"' -} - - -# func_remove_hook FUNC_NAME HOOK_FUNC -# ------------------------------------ -# Remove HOOK_FUNC from the list of functions called by FUNC_NAME. -func_remove_hook () -{ - $debug_cmd - - eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' -} - - -# func_run_hooks FUNC_NAME [ARG]... -# --------------------------------- -# Run all hook functions registered to FUNC_NAME. -# It is assumed that the list of hook functions contains nothing more -# than a whitespace-delimited list of legal shell function names, and -# no effort is wasted trying to catch shell meta-characters or preserve -# whitespace. -func_run_hooks () -{ - $debug_cmd - - _G_rc_run_hooks=false - - case " $hookable_fns " in - *" $1 "*) ;; - *) func_fatal_error "'$1' does not support hook funcions.n" ;; - esac - - eval _G_hook_fns=\$$1_hooks; shift - - for _G_hook in $_G_hook_fns; do - if eval $_G_hook '"$@"'; then - # store returned options list back into positional - # parameters for next 'cmd' execution. - eval _G_hook_result=\$${_G_hook}_result - eval set dummy "$_G_hook_result"; shift - _G_rc_run_hooks=: - fi - done - - $_G_rc_run_hooks && func_run_hooks_result=$_G_hook_result -} - - - -## --------------- ## -## Option parsing. ## -## --------------- ## - -# In order to add your own option parsing hooks, you must accept the -# full positional parameter list in your hook function, you may remove/edit -# any options that you action, and then pass back the remaining unprocessed -# options in '_result', escaped suitably for -# 'eval'. In this case you also must return $EXIT_SUCCESS to let the -# hook's caller know that it should pay attention to -# '_result'. Returning $EXIT_FAILURE signalizes that -# arguments are left untouched by the hook and therefore caller will ignore the -# result variable. -# -# Like this: -# -# my_options_prep () -# { -# $debug_cmd -# -# # Extend the existing usage message. -# usage_message=$usage_message' -# -s, --silent don'\''t print informational messages -# ' -# # No change in '$@' (ignored completely by this hook). There is -# # no need to do the equivalent (but slower) action: -# # func_quote_for_eval ${1+"$@"} -# # my_options_prep_result=$func_quote_for_eval_result -# false -# } -# func_add_hook func_options_prep my_options_prep -# -# -# my_silent_option () -# { -# $debug_cmd -# -# args_changed=false -# -# # Note that for efficiency, we parse as many options as we can -# # recognise in a loop before passing the remainder back to the -# # caller on the first unrecognised argument we encounter. -# while test $# -gt 0; do -# opt=$1; shift -# case $opt in -# --silent|-s) opt_silent=: -# args_changed=: -# ;; -# # Separate non-argument short options: -# -s*) func_split_short_opt "$_G_opt" -# set dummy "$func_split_short_opt_name" \ -# "-$func_split_short_opt_arg" ${1+"$@"} -# shift -# args_changed=: -# ;; -# *) # Make sure the first unrecognised option "$_G_opt" -# # is added back to "$@", we could need that later -# # if $args_changed is true. -# set dummy "$_G_opt" ${1+"$@"}; shift; break ;; -# esac -# done -# -# if $args_changed; then -# func_quote_for_eval ${1+"$@"} -# my_silent_option_result=$func_quote_for_eval_result -# fi -# -# $args_changed -# } -# func_add_hook func_parse_options my_silent_option -# -# -# my_option_validation () -# { -# $debug_cmd -# -# $opt_silent && $opt_verbose && func_fatal_help "\ -# '--silent' and '--verbose' options are mutually exclusive." -# -# false -# } -# func_add_hook func_validate_options my_option_validation -# -# You'll also need to manually amend $usage_message to reflect the extra -# options you parse. It's preferable to append if you can, so that -# multiple option parsing hooks can be added safely. - - -# func_options_finish [ARG]... -# ---------------------------- -# Finishing the option parse loop (call 'func_options' hooks ATM). -func_options_finish () -{ - $debug_cmd - - _G_func_options_finish_exit=false - if func_run_hooks func_options ${1+"$@"}; then - func_options_finish_result=$func_run_hooks_result - _G_func_options_finish_exit=: - fi - - $_G_func_options_finish_exit -} - - -# func_options [ARG]... -# --------------------- -# All the functions called inside func_options are hookable. See the -# individual implementations for details. -func_hookable func_options -func_options () -{ - $debug_cmd - - _G_rc_options=false - - for my_func in options_prep parse_options validate_options options_finish - do - if eval func_$my_func '${1+"$@"}'; then - eval _G_res_var='$'"func_${my_func}_result" - eval set dummy "$_G_res_var" ; shift - _G_rc_options=: - fi - done - - # Save modified positional parameters for caller. As a top-level - # options-parser function we always need to set the 'func_options_result' - # variable (regardless the $_G_rc_options value). - if $_G_rc_options; then - func_options_result=$_G_res_var - else - func_quote_for_eval ${1+"$@"} - func_options_result=$func_quote_for_eval_result - fi - - $_G_rc_options -} - - -# func_options_prep [ARG]... -# -------------------------- -# All initialisations required before starting the option parse loop. -# Note that when calling hook functions, we pass through the list of -# positional parameters. If a hook function modifies that list, and -# needs to propagate that back to rest of this script, then the complete -# modified list must be put in 'func_run_hooks_result' before -# returning $EXIT_SUCCESS (otherwise $EXIT_FAILURE is returned). -func_hookable func_options_prep -func_options_prep () -{ - $debug_cmd - - # Option defaults: - opt_verbose=false - opt_warning_types= - - _G_rc_options_prep=false - if func_run_hooks func_options_prep ${1+"$@"}; then - _G_rc_options_prep=: - # save modified positional parameters for caller - func_options_prep_result=$func_run_hooks_result - fi - - $_G_rc_options_prep -} - - -# func_parse_options [ARG]... -# --------------------------- -# The main option parsing loop. -func_hookable func_parse_options -func_parse_options () -{ - $debug_cmd - - func_parse_options_result= - - _G_rc_parse_options=false - # this just eases exit handling - while test $# -gt 0; do - # Defer to hook functions for initial option parsing, so they - # get priority in the event of reusing an option name. - if func_run_hooks func_parse_options ${1+"$@"}; then - eval set dummy "$func_run_hooks_result"; shift - _G_rc_parse_options=: - fi - - # Break out of the loop if we already parsed every option. - test $# -gt 0 || break - - _G_match_parse_options=: - _G_opt=$1 - shift - case $_G_opt in - --debug|-x) debug_cmd='set -x' - func_echo "enabling shell trace mode" - $debug_cmd - ;; - - --no-warnings|--no-warning|--no-warn) - set dummy --warnings none ${1+"$@"} - shift - ;; - - --warnings|--warning|-W) - if test $# = 0 && func_missing_arg $_G_opt; then - _G_rc_parse_options=: - break - fi - case " $warning_categories $1" in - *" $1 "*) - # trailing space prevents matching last $1 above - func_append_uniq opt_warning_types " $1" - ;; - *all) - opt_warning_types=$warning_categories - ;; - *none) - opt_warning_types=none - warning_func=: - ;; - *error) - opt_warning_types=$warning_categories - warning_func=func_fatal_error - ;; - *) - func_fatal_error \ - "unsupported warning category: '$1'" - ;; - esac - shift - ;; - - --verbose|-v) opt_verbose=: ;; - --version) func_version ;; - -\?|-h) func_usage ;; - --help) func_help ;; - - # Separate optargs to long options (plugins may need this): - --*=*) func_split_equals "$_G_opt" - set dummy "$func_split_equals_lhs" \ - "$func_split_equals_rhs" ${1+"$@"} - shift - ;; - - # Separate optargs to short options: - -W*) - func_split_short_opt "$_G_opt" - set dummy "$func_split_short_opt_name" \ - "$func_split_short_opt_arg" ${1+"$@"} - shift - ;; - - # Separate non-argument short options: - -\?*|-h*|-v*|-x*) - func_split_short_opt "$_G_opt" - set dummy "$func_split_short_opt_name" \ - "-$func_split_short_opt_arg" ${1+"$@"} - shift - ;; - - --) _G_rc_parse_options=: ; break ;; - -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; - *) set dummy "$_G_opt" ${1+"$@"}; shift - _G_match_parse_options=false - break - ;; - esac - - $_G_match_parse_options && _G_rc_parse_options=: - done - - - if $_G_rc_parse_options; then - # save modified positional parameters for caller - func_quote_for_eval ${1+"$@"} - func_parse_options_result=$func_quote_for_eval_result - fi - - $_G_rc_parse_options -} - - -# func_validate_options [ARG]... -# ------------------------------ -# Perform any sanity checks on option settings and/or unconsumed -# arguments. -func_hookable func_validate_options -func_validate_options () -{ - $debug_cmd - - _G_rc_validate_options=false - - # Display all warnings if -W was not given. - test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" - - if func_run_hooks func_validate_options ${1+"$@"}; then - # save modified positional parameters for caller - func_validate_options_result=$func_run_hooks_result - _G_rc_validate_options=: - fi - - # Bail if the options were screwed! - $exit_cmd $EXIT_FAILURE - - $_G_rc_validate_options -} - - - -## ----------------- ## -## Helper functions. ## -## ----------------- ## - -# This section contains the helper functions used by the rest of the -# hookable option parser framework in ascii-betical order. - - -# func_fatal_help ARG... -# ---------------------- -# Echo program name prefixed message to standard error, followed by -# a help hint, and exit. -func_fatal_help () -{ - $debug_cmd - - eval \$ECHO \""Usage: $usage"\" - eval \$ECHO \""$fatal_help"\" - func_error ${1+"$@"} - exit $EXIT_FAILURE -} - - -# func_help -# --------- -# Echo long help message to standard output and exit. -func_help () -{ - $debug_cmd - - func_usage_message - $ECHO "$long_help_message" - exit 0 -} - - -# func_missing_arg ARGNAME -# ------------------------ -# Echo program name prefixed message to standard error and set global -# exit_cmd. -func_missing_arg () -{ - $debug_cmd - - func_error "Missing argument for '$1'." - exit_cmd=exit -} - - -# func_split_equals STRING -# ------------------------ -# Set func_split_equals_lhs and func_split_equals_rhs shell variables after -# splitting STRING at the '=' sign. -test -z "$_G_HAVE_XSI_OPS" \ - && (eval 'x=a/b/c; - test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ - && _G_HAVE_XSI_OPS=yes - -if test yes = "$_G_HAVE_XSI_OPS" -then - # This is an XSI compatible shell, allowing a faster implementation... - eval 'func_split_equals () - { - $debug_cmd - - func_split_equals_lhs=${1%%=*} - func_split_equals_rhs=${1#*=} - test "x$func_split_equals_lhs" = "x$1" \ - && func_split_equals_rhs= - }' -else - # ...otherwise fall back to using expr, which is often a shell builtin. - func_split_equals () - { - $debug_cmd - - func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` - func_split_equals_rhs= - test "x$func_split_equals_lhs" = "x$1" \ - || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` - } -fi #func_split_equals - - -# func_split_short_opt SHORTOPT -# ----------------------------- -# Set func_split_short_opt_name and func_split_short_opt_arg shell -# variables after splitting SHORTOPT after the 2nd character. -if test yes = "$_G_HAVE_XSI_OPS" -then - # This is an XSI compatible shell, allowing a faster implementation... - eval 'func_split_short_opt () - { - $debug_cmd - - func_split_short_opt_arg=${1#??} - func_split_short_opt_name=${1%"$func_split_short_opt_arg"} - }' -else - # ...otherwise fall back to using expr, which is often a shell builtin. - func_split_short_opt () - { - $debug_cmd - - func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` - func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` - } -fi #func_split_short_opt - - -# func_usage -# ---------- -# Echo short help message to standard output and exit. -func_usage () -{ - $debug_cmd - - func_usage_message - $ECHO "Run '$progname --help |${PAGER-more}' for full usage" - exit 0 -} - - -# func_usage_message -# ------------------ -# Echo short help message to standard output. -func_usage_message () -{ - $debug_cmd - - eval \$ECHO \""Usage: $usage"\" - echo - $SED -n 's|^# || - /^Written by/{ - x;p;x - } - h - /^Written by/q' < "$progpath" - echo - eval \$ECHO \""$usage_message"\" -} - - -# func_version -# ------------ -# Echo version message to standard output and exit. -func_version () -{ - $debug_cmd - - printf '%s\n' "$progname $scriptversion" - $SED -n ' - /(C)/!b go - :more - /\./!{ - N - s|\n# | | - b more - } - :go - /^# Written by /,/# warranty; / { - s|^# || - s|^# *$|| - s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| - p - } - /^# Written by / { - s|^# || - p - } - /^warranty; /q' < "$progpath" - - exit $? -} - - -# Local variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" -# time-stamp-time-zone: "UTC" -# End: - -# Set a version string. -scriptversion='(GNU libtool) 2.4.6' - - -# func_echo ARG... -# ---------------- -# Libtool also displays the current mode in messages, so override -# funclib.sh func_echo with this custom definition. -func_echo () -{ - $debug_cmd - - _G_message=$* - - func_echo_IFS=$IFS - IFS=$nl - for _G_line in $_G_message; do - IFS=$func_echo_IFS - $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" - done - IFS=$func_echo_IFS -} - - -# func_warning ARG... -# ------------------- -# Libtool warnings are not categorized, so override funclib.sh -# func_warning with this simpler definition. -func_warning () -{ - $debug_cmd - - $warning_func ${1+"$@"} -} - - -## ---------------- ## -## Options parsing. ## -## ---------------- ## - -# Hook in the functions to make sure our own options are parsed during -# the option parsing loop. - -usage='$progpath [OPTION]... [MODE-ARG]...' - -# Short help message in response to '-h'. -usage_message="Options: - --config show all configuration variables - --debug enable verbose shell tracing - -n, --dry-run display commands without modifying any files - --features display basic configuration information and exit - --mode=MODE use operation mode MODE - --no-warnings equivalent to '-Wnone' - --preserve-dup-deps don't remove duplicate dependency libraries - --quiet, --silent don't print informational messages - --tag=TAG use configuration variables from tag TAG - -v, --verbose print more informational messages than default - --version print version information - -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] - -h, --help, --help-all print short, long, or detailed help message -" - -# Additional text appended to 'usage_message' in response to '--help'. -func_help () -{ - $debug_cmd - - func_usage_message - $ECHO "$long_help_message - -MODE must be one of the following: - - clean remove files from the build directory - compile compile a source file into a libtool object - execute automatically set library path, then run a program - finish complete the installation of libtool libraries - install install libraries or executables - link create a library or an executable - uninstall remove libraries from an installed directory - -MODE-ARGS vary depending on the MODE. When passed as first option, -'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. -Try '$progname --help --mode=MODE' for a more detailed description of MODE. - -When reporting a bug, please describe a test case to reproduce it and -include the following information: - - host-triplet: $host - shell: $SHELL - compiler: $LTCC - compiler flags: $LTCFLAGS - linker: $LD (gnu? $with_gnu_ld) - version: $progname $scriptversion Debian-2.4.6-15build2 - automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` - autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` - -Report bugs to . -GNU libtool home page: . -General help using GNU software: ." - exit 0 -} - - -# func_lo2o OBJECT-NAME -# --------------------- -# Transform OBJECT-NAME from a '.lo' suffix to the platform specific -# object suffix. - -lo2o=s/\\.lo\$/.$objext/ -o2lo=s/\\.$objext\$/.lo/ - -if test yes = "$_G_HAVE_XSI_OPS"; then - eval 'func_lo2o () - { - case $1 in - *.lo) func_lo2o_result=${1%.lo}.$objext ;; - * ) func_lo2o_result=$1 ;; - esac - }' - - # func_xform LIBOBJ-OR-SOURCE - # --------------------------- - # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) - # suffix to a '.lo' libtool-object suffix. - eval 'func_xform () - { - func_xform_result=${1%.*}.lo - }' -else - # ...otherwise fall back to using sed. - func_lo2o () - { - func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` - } - - func_xform () - { - func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` - } -fi - - -# func_fatal_configuration ARG... -# ------------------------------- -# Echo program name prefixed message to standard error, followed by -# a configuration failure hint, and exit. -func_fatal_configuration () -{ - func__fatal_error ${1+"$@"} \ - "See the $PACKAGE documentation for more information." \ - "Fatal configuration error." -} - - -# func_config -# ----------- -# Display the configuration for all the tags in this script. -func_config () -{ - re_begincf='^# ### BEGIN LIBTOOL' - re_endcf='^# ### END LIBTOOL' - - # Default configuration. - $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" - - # Now print the configurations for the tags. - for tagname in $taglist; do - $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" - done - - exit $? -} - - -# func_features -# ------------- -# Display the features supported by this script. -func_features () -{ - echo "host: $host" - if test yes = "$build_libtool_libs"; then - echo "enable shared libraries" - else - echo "disable shared libraries" - fi - if test yes = "$build_old_libs"; then - echo "enable static libraries" - else - echo "disable static libraries" - fi - - exit $? -} - - -# func_enable_tag TAGNAME -# ----------------------- -# Verify that TAGNAME is valid, and either flag an error and exit, or -# enable the TAGNAME tag. We also add TAGNAME to the global $taglist -# variable here. -func_enable_tag () -{ - # Global variable: - tagname=$1 - - re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" - re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" - sed_extractcf=/$re_begincf/,/$re_endcf/p - - # Validate tagname. - case $tagname in - *[!-_A-Za-z0-9,/]*) - func_fatal_error "invalid tag name: $tagname" - ;; - esac - - # Don't test for the "default" C tag, as we know it's - # there but not specially marked. - case $tagname in - CC) ;; - *) - if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then - taglist="$taglist $tagname" - - # Evaluate the configuration. Be careful to quote the path - # and the sed script, to avoid splitting on whitespace, but - # also don't use non-portable quotes within backquotes within - # quotes we have to do it in 2 steps: - extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` - eval "$extractedcf" - else - func_error "ignoring unknown tag $tagname" - fi - ;; - esac -} - - -# func_check_version_match -# ------------------------ -# Ensure that we are using m4 macros, and libtool script from the same -# release of libtool. -func_check_version_match () -{ - if test "$package_revision" != "$macro_revision"; then - if test "$VERSION" != "$macro_version"; then - if test -z "$macro_version"; then - cat >&2 <<_LT_EOF -$progname: Version mismatch error. This is $PACKAGE $VERSION, but the -$progname: definition of this LT_INIT comes from an older release. -$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION -$progname: and run autoconf again. -_LT_EOF - else - cat >&2 <<_LT_EOF -$progname: Version mismatch error. This is $PACKAGE $VERSION, but the -$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. -$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION -$progname: and run autoconf again. -_LT_EOF - fi - else - cat >&2 <<_LT_EOF -$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, -$progname: but the definition of this LT_INIT comes from revision $macro_revision. -$progname: You should recreate aclocal.m4 with macros from revision $package_revision -$progname: of $PACKAGE $VERSION and run autoconf again. -_LT_EOF - fi - - exit $EXIT_MISMATCH - fi -} - - -# libtool_options_prep [ARG]... -# ----------------------------- -# Preparation for options parsed by libtool. -libtool_options_prep () -{ - $debug_mode - - # Option defaults: - opt_config=false - opt_dlopen= - opt_dry_run=false - opt_help=false - opt_mode= - opt_preserve_dup_deps=false - opt_quiet=false - - nonopt= - preserve_args= - - _G_rc_lt_options_prep=: - - # Shorthand for --mode=foo, only valid as the first argument - case $1 in - clean|clea|cle|cl) - shift; set dummy --mode clean ${1+"$@"}; shift - ;; - compile|compil|compi|comp|com|co|c) - shift; set dummy --mode compile ${1+"$@"}; shift - ;; - execute|execut|execu|exec|exe|ex|e) - shift; set dummy --mode execute ${1+"$@"}; shift - ;; - finish|finis|fini|fin|fi|f) - shift; set dummy --mode finish ${1+"$@"}; shift - ;; - install|instal|insta|inst|ins|in|i) - shift; set dummy --mode install ${1+"$@"}; shift - ;; - link|lin|li|l) - shift; set dummy --mode link ${1+"$@"}; shift - ;; - uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) - shift; set dummy --mode uninstall ${1+"$@"}; shift - ;; - *) - _G_rc_lt_options_prep=false - ;; - esac - - if $_G_rc_lt_options_prep; then - # Pass back the list of options. - func_quote_for_eval ${1+"$@"} - libtool_options_prep_result=$func_quote_for_eval_result - fi - - $_G_rc_lt_options_prep -} -func_add_hook func_options_prep libtool_options_prep - - -# libtool_parse_options [ARG]... -# --------------------------------- -# Provide handling for libtool specific options. -libtool_parse_options () -{ - $debug_cmd - - _G_rc_lt_parse_options=false - - # Perform our own loop to consume as many options as possible in - # each iteration. - while test $# -gt 0; do - _G_match_lt_parse_options=: - _G_opt=$1 - shift - case $_G_opt in - --dry-run|--dryrun|-n) - opt_dry_run=: - ;; - - --config) func_config ;; - - --dlopen|-dlopen) - opt_dlopen="${opt_dlopen+$opt_dlopen -}$1" - shift - ;; - - --preserve-dup-deps) - opt_preserve_dup_deps=: ;; - - --features) func_features ;; - - --finish) set dummy --mode finish ${1+"$@"}; shift ;; - - --help) opt_help=: ;; - - --help-all) opt_help=': help-all' ;; - - --mode) test $# = 0 && func_missing_arg $_G_opt && break - opt_mode=$1 - case $1 in - # Valid mode arguments: - clean|compile|execute|finish|install|link|relink|uninstall) ;; - - # Catch anything else as an error - *) func_error "invalid argument for $_G_opt" - exit_cmd=exit - break - ;; - esac - shift - ;; - - --no-silent|--no-quiet) - opt_quiet=false - func_append preserve_args " $_G_opt" - ;; - - --no-warnings|--no-warning|--no-warn) - opt_warning=false - func_append preserve_args " $_G_opt" - ;; - - --no-verbose) - opt_verbose=false - func_append preserve_args " $_G_opt" - ;; - - --silent|--quiet) - opt_quiet=: - opt_verbose=false - func_append preserve_args " $_G_opt" - ;; - - --tag) test $# = 0 && func_missing_arg $_G_opt && break - opt_tag=$1 - func_append preserve_args " $_G_opt $1" - func_enable_tag "$1" - shift - ;; - - --verbose|-v) opt_quiet=false - opt_verbose=: - func_append preserve_args " $_G_opt" - ;; - - # An option not handled by this hook function: - *) set dummy "$_G_opt" ${1+"$@"} ; shift - _G_match_lt_parse_options=false - break - ;; - esac - $_G_match_lt_parse_options && _G_rc_lt_parse_options=: - done - - if $_G_rc_lt_parse_options; then - # save modified positional parameters for caller - func_quote_for_eval ${1+"$@"} - libtool_parse_options_result=$func_quote_for_eval_result - fi - - $_G_rc_lt_parse_options -} -func_add_hook func_parse_options libtool_parse_options - - - -# libtool_validate_options [ARG]... -# --------------------------------- -# Perform any sanity checks on option settings and/or unconsumed -# arguments. -libtool_validate_options () -{ - # save first non-option argument - if test 0 -lt $#; then - nonopt=$1 - shift - fi - - # preserve --debug - test : = "$debug_cmd" || func_append preserve_args " --debug" - - case $host in - # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 - # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 - *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) - # don't eliminate duplications in $postdeps and $predeps - opt_duplicate_compiler_generated_deps=: - ;; - *) - opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps - ;; - esac - - $opt_help || { - # Sanity checks first: - func_check_version_match - - test yes != "$build_libtool_libs" \ - && test yes != "$build_old_libs" \ - && func_fatal_configuration "not configured to build any kind of library" - - # Darwin sucks - eval std_shrext=\"$shrext_cmds\" - - # Only execute mode is allowed to have -dlopen flags. - if test -n "$opt_dlopen" && test execute != "$opt_mode"; then - func_error "unrecognized option '-dlopen'" - $ECHO "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # Change the help message to a mode-specific one. - generic_help=$help - help="Try '$progname --help --mode=$opt_mode' for more information." - } - - # Pass back the unparsed argument list - func_quote_for_eval ${1+"$@"} - libtool_validate_options_result=$func_quote_for_eval_result -} -func_add_hook func_validate_options libtool_validate_options - - -# Process options as early as possible so that --help and --version -# can return quickly. -func_options ${1+"$@"} -eval set dummy "$func_options_result"; shift - - - -## ----------- ## -## Main. ## -## ----------- ## - -magic='%%%MAGIC variable%%%' -magic_exe='%%%MAGIC EXE variable%%%' - -# Global variables. -extracted_archives= -extracted_serial=0 - -# If this variable is set in any of the actions, the command in it -# will be execed at the end. This prevents here-documents from being -# left over by shells. -exec_cmd= - - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -$1 -_LTECHO_EOF' -} - -# func_generated_by_libtool -# True iff stdin has been generated by Libtool. This function is only -# a basic sanity check; it will hardly flush out determined imposters. -func_generated_by_libtool_p () -{ - $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 -} - -# func_lalib_p file -# True iff FILE is a libtool '.la' library or '.lo' object file. -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_lalib_p () -{ - test -f "$1" && - $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p -} - -# func_lalib_unsafe_p file -# True iff FILE is a libtool '.la' library or '.lo' object file. -# This function implements the same check as func_lalib_p without -# resorting to external programs. To this end, it redirects stdin and -# closes it afterwards, without saving the original file descriptor. -# As a safety measure, use it only where a negative result would be -# fatal anyway. Works if 'file' does not exist. -func_lalib_unsafe_p () -{ - lalib_p=no - if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then - for lalib_p_l in 1 2 3 4 - do - read lalib_p_line - case $lalib_p_line in - \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; - esac - done - exec 0<&5 5<&- - fi - test yes = "$lalib_p" -} - -# func_ltwrapper_script_p file -# True iff FILE is a libtool wrapper script -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_ltwrapper_script_p () -{ - test -f "$1" && - $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p -} - -# func_ltwrapper_executable_p file -# True iff FILE is a libtool wrapper executable -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_ltwrapper_executable_p () -{ - func_ltwrapper_exec_suffix= - case $1 in - *.exe) ;; - *) func_ltwrapper_exec_suffix=.exe ;; - esac - $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 -} - -# func_ltwrapper_scriptname file -# Assumes file is an ltwrapper_executable -# uses $file to determine the appropriate filename for a -# temporary ltwrapper_script. -func_ltwrapper_scriptname () -{ - func_dirname_and_basename "$1" "" "." - func_stripname '' '.exe' "$func_basename_result" - func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper -} - -# func_ltwrapper_p file -# True iff FILE is a libtool wrapper script or wrapper executable -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_ltwrapper_p () -{ - func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" -} - - -# func_execute_cmds commands fail_cmd -# Execute tilde-delimited COMMANDS. -# If FAIL_CMD is given, eval that upon failure. -# FAIL_CMD may read-access the current command in variable CMD! -func_execute_cmds () -{ - $debug_cmd - - save_ifs=$IFS; IFS='~' - for cmd in $1; do - IFS=$sp$nl - eval cmd=\"$cmd\" - IFS=$save_ifs - func_show_eval "$cmd" "${2-:}" - done - IFS=$save_ifs -} - - -# func_source file -# Source FILE, adding directory component if necessary. -# Note that it is not necessary on cygwin/mingw to append a dot to -# FILE even if both FILE and FILE.exe exist: automatic-append-.exe -# behavior happens only for exec(3), not for open(2)! Also, sourcing -# 'FILE.' does not work on cygwin managed mounts. -func_source () -{ - $debug_cmd - - case $1 in - */* | *\\*) . "$1" ;; - *) . "./$1" ;; - esac -} - - -# func_resolve_sysroot PATH -# Replace a leading = in PATH with a sysroot. Store the result into -# func_resolve_sysroot_result -func_resolve_sysroot () -{ - func_resolve_sysroot_result=$1 - case $func_resolve_sysroot_result in - =*) - func_stripname '=' '' "$func_resolve_sysroot_result" - func_resolve_sysroot_result=$lt_sysroot$func_stripname_result - ;; - esac -} - -# func_replace_sysroot PATH -# If PATH begins with the sysroot, replace it with = and -# store the result into func_replace_sysroot_result. -func_replace_sysroot () -{ - case $lt_sysroot:$1 in - ?*:"$lt_sysroot"*) - func_stripname "$lt_sysroot" '' "$1" - func_replace_sysroot_result='='$func_stripname_result - ;; - *) - # Including no sysroot. - func_replace_sysroot_result=$1 - ;; - esac -} - -# func_infer_tag arg -# Infer tagged configuration to use if any are available and -# if one wasn't chosen via the "--tag" command line option. -# Only attempt this if the compiler in the base compile -# command doesn't match the default compiler. -# arg is usually of the form 'gcc ...' -func_infer_tag () -{ - $debug_cmd - - if test -n "$available_tags" && test -z "$tagname"; then - CC_quoted= - for arg in $CC; do - func_append_quoted CC_quoted "$arg" - done - CC_expanded=`func_echo_all $CC` - CC_quoted_expanded=`func_echo_all $CC_quoted` - case $@ in - # Blanks in the command may have been stripped by the calling shell, - # but not from the CC environment variable when configure was run. - " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ - " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; - # Blanks at the start of $base_compile will cause this to fail - # if we don't check for them as well. - *) - for z in $available_tags; do - if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then - # Evaluate the configuration. - eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" - CC_quoted= - for arg in $CC; do - # Double-quote args containing other shell metacharacters. - func_append_quoted CC_quoted "$arg" - done - CC_expanded=`func_echo_all $CC` - CC_quoted_expanded=`func_echo_all $CC_quoted` - case "$@ " in - " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ - " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) - # The compiler in the base compile command matches - # the one in the tagged configuration. - # Assume this is the tagged configuration we want. - tagname=$z - break - ;; - esac - fi - done - # If $tagname still isn't set, then no tagged configuration - # was found and let the user know that the "--tag" command - # line option must be used. - if test -z "$tagname"; then - func_echo "unable to infer tagged configuration" - func_fatal_error "specify a tag with '--tag'" -# else -# func_verbose "using $tagname tagged configuration" - fi - ;; - esac - fi -} - - - -# func_write_libtool_object output_name pic_name nonpic_name -# Create a libtool object file (analogous to a ".la" file), -# but don't create it if we're doing a dry run. -func_write_libtool_object () -{ - write_libobj=$1 - if test yes = "$build_libtool_libs"; then - write_lobj=\'$2\' - else - write_lobj=none - fi - - if test yes = "$build_old_libs"; then - write_oldobj=\'$3\' - else - write_oldobj=none - fi - - $opt_dry_run || { - cat >${write_libobj}T </dev/null` - if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then - func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | - $SED -e "$sed_naive_backslashify"` - else - func_convert_core_file_wine_to_w32_result= - fi - fi -} -# end: func_convert_core_file_wine_to_w32 - - -# func_convert_core_path_wine_to_w32 ARG -# Helper function used by path conversion functions when $build is *nix, and -# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly -# configured wine environment available, with the winepath program in $build's -# $PATH. Assumes ARG has no leading or trailing path separator characters. -# -# ARG is path to be converted from $build format to win32. -# Result is available in $func_convert_core_path_wine_to_w32_result. -# Unconvertible file (directory) names in ARG are skipped; if no directory names -# are convertible, then the result may be empty. -func_convert_core_path_wine_to_w32 () -{ - $debug_cmd - - # unfortunately, winepath doesn't convert paths, only file names - func_convert_core_path_wine_to_w32_result= - if test -n "$1"; then - oldIFS=$IFS - IFS=: - for func_convert_core_path_wine_to_w32_f in $1; do - IFS=$oldIFS - func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" - if test -n "$func_convert_core_file_wine_to_w32_result"; then - if test -z "$func_convert_core_path_wine_to_w32_result"; then - func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result - else - func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" - fi - fi - done - IFS=$oldIFS - fi -} -# end: func_convert_core_path_wine_to_w32 - - -# func_cygpath ARGS... -# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when -# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) -# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or -# (2), returns the Cygwin file name or path in func_cygpath_result (input -# file name or path is assumed to be in w32 format, as previously converted -# from $build's *nix or MSYS format). In case (3), returns the w32 file name -# or path in func_cygpath_result (input file name or path is assumed to be in -# Cygwin format). Returns an empty string on error. -# -# ARGS are passed to cygpath, with the last one being the file name or path to -# be converted. -# -# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH -# environment variable; do not put it in $PATH. -func_cygpath () -{ - $debug_cmd - - if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then - func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` - if test "$?" -ne 0; then - # on failure, ensure result is empty - func_cygpath_result= - fi - else - func_cygpath_result= - func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" - fi -} -#end: func_cygpath - - -# func_convert_core_msys_to_w32 ARG -# Convert file name or path ARG from MSYS format to w32 format. Return -# result in func_convert_core_msys_to_w32_result. -func_convert_core_msys_to_w32 () -{ - $debug_cmd - - # awkward: cmd appends spaces to result - func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | - $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` -} -#end: func_convert_core_msys_to_w32 - - -# func_convert_file_check ARG1 ARG2 -# Verify that ARG1 (a file name in $build format) was converted to $host -# format in ARG2. Otherwise, emit an error message, but continue (resetting -# func_to_host_file_result to ARG1). -func_convert_file_check () -{ - $debug_cmd - - if test -z "$2" && test -n "$1"; then - func_error "Could not determine host file name corresponding to" - func_error " '$1'" - func_error "Continuing, but uninstalled executables may not work." - # Fallback: - func_to_host_file_result=$1 - fi -} -# end func_convert_file_check - - -# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH -# Verify that FROM_PATH (a path in $build format) was converted to $host -# format in TO_PATH. Otherwise, emit an error message, but continue, resetting -# func_to_host_file_result to a simplistic fallback value (see below). -func_convert_path_check () -{ - $debug_cmd - - if test -z "$4" && test -n "$3"; then - func_error "Could not determine the host path corresponding to" - func_error " '$3'" - func_error "Continuing, but uninstalled executables may not work." - # Fallback. This is a deliberately simplistic "conversion" and - # should not be "improved". See libtool.info. - if test "x$1" != "x$2"; then - lt_replace_pathsep_chars="s|$1|$2|g" - func_to_host_path_result=`echo "$3" | - $SED -e "$lt_replace_pathsep_chars"` - else - func_to_host_path_result=$3 - fi - fi -} -# end func_convert_path_check - - -# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG -# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT -# and appending REPL if ORIG matches BACKPAT. -func_convert_path_front_back_pathsep () -{ - $debug_cmd - - case $4 in - $1 ) func_to_host_path_result=$3$func_to_host_path_result - ;; - esac - case $4 in - $2 ) func_append func_to_host_path_result "$3" - ;; - esac -} -# end func_convert_path_front_back_pathsep - - -################################################## -# $build to $host FILE NAME CONVERSION FUNCTIONS # -################################################## -# invoked via '$to_host_file_cmd ARG' -# -# In each case, ARG is the path to be converted from $build to $host format. -# Result will be available in $func_to_host_file_result. - - -# func_to_host_file ARG -# Converts the file name ARG from $build format to $host format. Return result -# in func_to_host_file_result. -func_to_host_file () -{ - $debug_cmd - - $to_host_file_cmd "$1" -} -# end func_to_host_file - - -# func_to_tool_file ARG LAZY -# converts the file name ARG from $build format to toolchain format. Return -# result in func_to_tool_file_result. If the conversion in use is listed -# in (the comma separated) LAZY, no conversion takes place. -func_to_tool_file () -{ - $debug_cmd - - case ,$2, in - *,"$to_tool_file_cmd",*) - func_to_tool_file_result=$1 - ;; - *) - $to_tool_file_cmd "$1" - func_to_tool_file_result=$func_to_host_file_result - ;; - esac -} -# end func_to_tool_file - - -# func_convert_file_noop ARG -# Copy ARG to func_to_host_file_result. -func_convert_file_noop () -{ - func_to_host_file_result=$1 -} -# end func_convert_file_noop - - -# func_convert_file_msys_to_w32 ARG -# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic -# conversion to w32 is not available inside the cwrapper. Returns result in -# func_to_host_file_result. -func_convert_file_msys_to_w32 () -{ - $debug_cmd - - func_to_host_file_result=$1 - if test -n "$1"; then - func_convert_core_msys_to_w32 "$1" - func_to_host_file_result=$func_convert_core_msys_to_w32_result - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_msys_to_w32 - - -# func_convert_file_cygwin_to_w32 ARG -# Convert file name ARG from Cygwin to w32 format. Returns result in -# func_to_host_file_result. -func_convert_file_cygwin_to_w32 () -{ - $debug_cmd - - func_to_host_file_result=$1 - if test -n "$1"; then - # because $build is cygwin, we call "the" cygpath in $PATH; no need to use - # LT_CYGPATH in this case. - func_to_host_file_result=`cygpath -m "$1"` - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_cygwin_to_w32 - - -# func_convert_file_nix_to_w32 ARG -# Convert file name ARG from *nix to w32 format. Requires a wine environment -# and a working winepath. Returns result in func_to_host_file_result. -func_convert_file_nix_to_w32 () -{ - $debug_cmd - - func_to_host_file_result=$1 - if test -n "$1"; then - func_convert_core_file_wine_to_w32 "$1" - func_to_host_file_result=$func_convert_core_file_wine_to_w32_result - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_nix_to_w32 - - -# func_convert_file_msys_to_cygwin ARG -# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. -# Returns result in func_to_host_file_result. -func_convert_file_msys_to_cygwin () -{ - $debug_cmd - - func_to_host_file_result=$1 - if test -n "$1"; then - func_convert_core_msys_to_w32 "$1" - func_cygpath -u "$func_convert_core_msys_to_w32_result" - func_to_host_file_result=$func_cygpath_result - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_msys_to_cygwin - - -# func_convert_file_nix_to_cygwin ARG -# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed -# in a wine environment, working winepath, and LT_CYGPATH set. Returns result -# in func_to_host_file_result. -func_convert_file_nix_to_cygwin () -{ - $debug_cmd - - func_to_host_file_result=$1 - if test -n "$1"; then - # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. - func_convert_core_file_wine_to_w32 "$1" - func_cygpath -u "$func_convert_core_file_wine_to_w32_result" - func_to_host_file_result=$func_cygpath_result - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_nix_to_cygwin - - -############################################# -# $build to $host PATH CONVERSION FUNCTIONS # -############################################# -# invoked via '$to_host_path_cmd ARG' -# -# In each case, ARG is the path to be converted from $build to $host format. -# The result will be available in $func_to_host_path_result. -# -# Path separators are also converted from $build format to $host format. If -# ARG begins or ends with a path separator character, it is preserved (but -# converted to $host format) on output. -# -# All path conversion functions are named using the following convention: -# file name conversion function : func_convert_file_X_to_Y () -# path conversion function : func_convert_path_X_to_Y () -# where, for any given $build/$host combination the 'X_to_Y' value is the -# same. If conversion functions are added for new $build/$host combinations, -# the two new functions must follow this pattern, or func_init_to_host_path_cmd -# will break. - - -# func_init_to_host_path_cmd -# Ensures that function "pointer" variable $to_host_path_cmd is set to the -# appropriate value, based on the value of $to_host_file_cmd. -to_host_path_cmd= -func_init_to_host_path_cmd () -{ - $debug_cmd - - if test -z "$to_host_path_cmd"; then - func_stripname 'func_convert_file_' '' "$to_host_file_cmd" - to_host_path_cmd=func_convert_path_$func_stripname_result - fi -} - - -# func_to_host_path ARG -# Converts the path ARG from $build format to $host format. Return result -# in func_to_host_path_result. -func_to_host_path () -{ - $debug_cmd - - func_init_to_host_path_cmd - $to_host_path_cmd "$1" -} -# end func_to_host_path - - -# func_convert_path_noop ARG -# Copy ARG to func_to_host_path_result. -func_convert_path_noop () -{ - func_to_host_path_result=$1 -} -# end func_convert_path_noop - - -# func_convert_path_msys_to_w32 ARG -# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic -# conversion to w32 is not available inside the cwrapper. Returns result in -# func_to_host_path_result. -func_convert_path_msys_to_w32 () -{ - $debug_cmd - - func_to_host_path_result=$1 - if test -n "$1"; then - # Remove leading and trailing path separator characters from ARG. MSYS - # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; - # and winepath ignores them completely. - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" - func_to_host_path_result=$func_convert_core_msys_to_w32_result - func_convert_path_check : ";" \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" - fi -} -# end func_convert_path_msys_to_w32 - - -# func_convert_path_cygwin_to_w32 ARG -# Convert path ARG from Cygwin to w32 format. Returns result in -# func_to_host_file_result. -func_convert_path_cygwin_to_w32 () -{ - $debug_cmd - - func_to_host_path_result=$1 - if test -n "$1"; then - # See func_convert_path_msys_to_w32: - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` - func_convert_path_check : ";" \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" - fi -} -# end func_convert_path_cygwin_to_w32 - - -# func_convert_path_nix_to_w32 ARG -# Convert path ARG from *nix to w32 format. Requires a wine environment and -# a working winepath. Returns result in func_to_host_file_result. -func_convert_path_nix_to_w32 () -{ - $debug_cmd - - func_to_host_path_result=$1 - if test -n "$1"; then - # See func_convert_path_msys_to_w32: - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" - func_to_host_path_result=$func_convert_core_path_wine_to_w32_result - func_convert_path_check : ";" \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" - fi -} -# end func_convert_path_nix_to_w32 - - -# func_convert_path_msys_to_cygwin ARG -# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. -# Returns result in func_to_host_file_result. -func_convert_path_msys_to_cygwin () -{ - $debug_cmd - - func_to_host_path_result=$1 - if test -n "$1"; then - # See func_convert_path_msys_to_w32: - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" - func_cygpath -u -p "$func_convert_core_msys_to_w32_result" - func_to_host_path_result=$func_cygpath_result - func_convert_path_check : : \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" : "$1" - fi -} -# end func_convert_path_msys_to_cygwin - - -# func_convert_path_nix_to_cygwin ARG -# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a -# a wine environment, working winepath, and LT_CYGPATH set. Returns result in -# func_to_host_file_result. -func_convert_path_nix_to_cygwin () -{ - $debug_cmd - - func_to_host_path_result=$1 - if test -n "$1"; then - # Remove leading and trailing path separator characters from - # ARG. msys behavior is inconsistent here, cygpath turns them - # into '.;' and ';.', and winepath ignores them completely. - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" - func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" - func_to_host_path_result=$func_cygpath_result - func_convert_path_check : : \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" : "$1" - fi -} -# end func_convert_path_nix_to_cygwin - - -# func_dll_def_p FILE -# True iff FILE is a Windows DLL '.def' file. -# Keep in sync with _LT_DLL_DEF_P in libtool.m4 -func_dll_def_p () -{ - $debug_cmd - - func_dll_def_p_tmp=`$SED -n \ - -e 's/^[ ]*//' \ - -e '/^\(;.*\)*$/d' \ - -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ - -e q \ - "$1"` - test DEF = "$func_dll_def_p_tmp" -} - - -# func_mode_compile arg... -func_mode_compile () -{ - $debug_cmd - - # Get the compilation command and the source file. - base_compile= - srcfile=$nonopt # always keep a non-empty value in "srcfile" - suppress_opt=yes - suppress_output= - arg_mode=normal - libobj= - later= - pie_flag= - - for arg - do - case $arg_mode in - arg ) - # do not "continue". Instead, add this to base_compile - lastarg=$arg - arg_mode=normal - ;; - - target ) - libobj=$arg - arg_mode=normal - continue - ;; - - normal ) - # Accept any command-line options. - case $arg in - -o) - test -n "$libobj" && \ - func_fatal_error "you cannot specify '-o' more than once" - arg_mode=target - continue - ;; - - -pie | -fpie | -fPIE) - func_append pie_flag " $arg" - continue - ;; - - -shared | -static | -prefer-pic | -prefer-non-pic) - func_append later " $arg" - continue - ;; - - -no-suppress) - suppress_opt=no - continue - ;; - - -Xcompiler) - arg_mode=arg # the next one goes into the "base_compile" arg list - continue # The current "srcfile" will either be retained or - ;; # replaced later. I would guess that would be a bug. - - -Wc,*) - func_stripname '-Wc,' '' "$arg" - args=$func_stripname_result - lastarg= - save_ifs=$IFS; IFS=, - for arg in $args; do - IFS=$save_ifs - func_append_quoted lastarg "$arg" - done - IFS=$save_ifs - func_stripname ' ' '' "$lastarg" - lastarg=$func_stripname_result - - # Add the arguments to base_compile. - func_append base_compile " $lastarg" - continue - ;; - - *) - # Accept the current argument as the source file. - # The previous "srcfile" becomes the current argument. - # - lastarg=$srcfile - srcfile=$arg - ;; - esac # case $arg - ;; - esac # case $arg_mode - - # Aesthetically quote the previous argument. - func_append_quoted base_compile "$lastarg" - done # for arg - - case $arg_mode in - arg) - func_fatal_error "you must specify an argument for -Xcompile" - ;; - target) - func_fatal_error "you must specify a target with '-o'" - ;; - *) - # Get the name of the library object. - test -z "$libobj" && { - func_basename "$srcfile" - libobj=$func_basename_result - } - ;; - esac - - # Recognize several different file suffixes. - # If the user specifies -o file.o, it is replaced with file.lo - case $libobj in - *.[cCFSifmso] | \ - *.ada | *.adb | *.ads | *.asm | \ - *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ - *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) - func_xform "$libobj" - libobj=$func_xform_result - ;; - esac - - case $libobj in - *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; - *) - func_fatal_error "cannot determine name of library object from '$libobj'" - ;; - esac - - func_infer_tag $base_compile - - for arg in $later; do - case $arg in - -shared) - test yes = "$build_libtool_libs" \ - || func_fatal_configuration "cannot build a shared library" - build_old_libs=no - continue - ;; - - -static) - build_libtool_libs=no - build_old_libs=yes - continue - ;; - - -prefer-pic) - pic_mode=yes - continue - ;; - - -prefer-non-pic) - pic_mode=no - continue - ;; - esac - done - - func_quote_for_eval "$libobj" - test "X$libobj" != "X$func_quote_for_eval_result" \ - && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ - && func_warning "libobj name '$libobj' may not contain shell special characters." - func_dirname_and_basename "$obj" "/" "" - objname=$func_basename_result - xdir=$func_dirname_result - lobj=$xdir$objdir/$objname - - test -z "$base_compile" && \ - func_fatal_help "you must specify a compilation command" - - # Delete any leftover library objects. - if test yes = "$build_old_libs"; then - removelist="$obj $lobj $libobj ${libobj}T" - else - removelist="$lobj $libobj ${libobj}T" - fi - - # On Cygwin there's no "real" PIC flag so we must build both object types - case $host_os in - cygwin* | mingw* | pw32* | os2* | cegcc*) - pic_mode=default - ;; - esac - if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then - # non-PIC code in shared libraries is not supported - pic_mode=default - fi - - # Calculate the filename of the output object if compiler does - # not support -o with -c - if test no = "$compiler_c_o"; then - output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext - lockfile=$output_obj.lock - else - output_obj= - need_locks=no - lockfile= - fi - - # Lock this critical section if it is needed - # We use this script file to make the link, it avoids creating a new file - if test yes = "$need_locks"; then - until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do - func_echo "Waiting for $lockfile to be removed" - sleep 2 - done - elif test warn = "$need_locks"; then - if test -f "$lockfile"; then - $ECHO "\ -*** ERROR, $lockfile exists and contains: -`cat $lockfile 2>/dev/null` - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support '-c' and '-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $opt_dry_run || $RM $removelist - exit $EXIT_FAILURE - fi - func_append removelist " $output_obj" - $ECHO "$srcfile" > "$lockfile" - fi - - $opt_dry_run || $RM $removelist - func_append removelist " $lockfile" - trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 - - func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 - srcfile=$func_to_tool_file_result - func_quote_for_eval "$srcfile" - qsrcfile=$func_quote_for_eval_result - - # Only build a PIC object if we are building libtool libraries. - if test yes = "$build_libtool_libs"; then - # Without this assignment, base_compile gets emptied. - fbsd_hideous_sh_bug=$base_compile - - if test no != "$pic_mode"; then - command="$base_compile $qsrcfile $pic_flag" - else - # Don't build PIC code - command="$base_compile $qsrcfile" - fi - - func_mkdir_p "$xdir$objdir" - - if test -z "$output_obj"; then - # Place PIC objects in $objdir - func_append command " -o $lobj" - fi - - func_show_eval_locale "$command" \ - 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' - - if test warn = "$need_locks" && - test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then - $ECHO "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support '-c' and '-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $opt_dry_run || $RM $removelist - exit $EXIT_FAILURE - fi - - # Just move the object if needed, then go on to compile the next one - if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then - func_show_eval '$MV "$output_obj" "$lobj"' \ - 'error=$?; $opt_dry_run || $RM $removelist; exit $error' - fi - - # Allow error messages only from the first compilation. - if test yes = "$suppress_opt"; then - suppress_output=' >/dev/null 2>&1' - fi - fi - - # Only build a position-dependent object if we build old libraries. - if test yes = "$build_old_libs"; then - if test yes != "$pic_mode"; then - # Don't build PIC code - command="$base_compile $qsrcfile$pie_flag" - else - command="$base_compile $qsrcfile $pic_flag" - fi - if test yes = "$compiler_c_o"; then - func_append command " -o $obj" - fi - - # Suppress compiler output if we already did a PIC compilation. - func_append command "$suppress_output" - func_show_eval_locale "$command" \ - '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' - - if test warn = "$need_locks" && - test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then - $ECHO "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support '-c' and '-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $opt_dry_run || $RM $removelist - exit $EXIT_FAILURE - fi - - # Just move the object if needed - if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then - func_show_eval '$MV "$output_obj" "$obj"' \ - 'error=$?; $opt_dry_run || $RM $removelist; exit $error' - fi - fi - - $opt_dry_run || { - func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" - - # Unlock the critical section if it was locked - if test no != "$need_locks"; then - removelist=$lockfile - $RM "$lockfile" - fi - } - - exit $EXIT_SUCCESS -} - -$opt_help || { - test compile = "$opt_mode" && func_mode_compile ${1+"$@"} -} - -func_mode_help () -{ - # We need to display help for each of the modes. - case $opt_mode in - "") - # Generic help is extracted from the usage comments - # at the start of this file. - func_help - ;; - - clean) - $ECHO \ -"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... - -Remove files from the build directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed -to RM. - -If FILE is a libtool library, object or program, all the files associated -with it are deleted. Otherwise, only FILE itself is deleted using RM." - ;; - - compile) - $ECHO \ -"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE - -Compile a source file into a libtool library object. - -This mode accepts the following additional options: - - -o OUTPUT-FILE set the output file name to OUTPUT-FILE - -no-suppress do not suppress compiler output for multiple passes - -prefer-pic try to build PIC objects only - -prefer-non-pic try to build non-PIC objects only - -shared do not build a '.o' file suitable for static linking - -static only build a '.o' file suitable for static linking - -Wc,FLAG pass FLAG directly to the compiler - -COMPILE-COMMAND is a command to be used in creating a 'standard' object file -from the given SOURCEFILE. - -The output file name is determined by removing the directory component from -SOURCEFILE, then substituting the C source code suffix '.c' with the -library object suffix, '.lo'." - ;; - - execute) - $ECHO \ -"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... - -Automatically set library path, then run a program. - -This mode accepts the following additional options: - - -dlopen FILE add the directory containing FILE to the library path - -This mode sets the library path environment variable according to '-dlopen' -flags. - -If any of the ARGS are libtool executable wrappers, then they are translated -into their corresponding uninstalled binary, and any of their required library -directories are added to the library path. - -Then, COMMAND is executed, with ARGS as arguments." - ;; - - finish) - $ECHO \ -"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... - -Complete the installation of libtool libraries. - -Each LIBDIR is a directory that contains libtool libraries. - -The commands that this mode executes may require superuser privileges. Use -the '--dry-run' option if you just want to see what would be executed." - ;; - - install) - $ECHO \ -"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... - -Install executables or libraries. - -INSTALL-COMMAND is the installation command. The first component should be -either the 'install' or 'cp' program. - -The following components of INSTALL-COMMAND are treated specially: - - -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation - -The rest of the components are interpreted as arguments to that command (only -BSD-compatible install options are recognized)." - ;; - - link) - $ECHO \ -"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... - -Link object files or libraries together to form another library, or to -create an executable program. - -LINK-COMMAND is a command using the C compiler that you would use to create -a program from several object files. - -The following components of LINK-COMMAND are treated specially: - - -all-static do not do any dynamic linking at all - -avoid-version do not add a version suffix if possible - -bindir BINDIR specify path to binaries directory (for systems where - libraries must be found in the PATH setting at runtime) - -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime - -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols - -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) - -export-symbols SYMFILE - try to export only the symbols listed in SYMFILE - -export-symbols-regex REGEX - try to export only the symbols matching REGEX - -LLIBDIR search LIBDIR for required installed libraries - -lNAME OUTPUT-FILE requires the installed library libNAME - -module build a library that can dlopened - -no-fast-install disable the fast-install mode - -no-install link a not-installable executable - -no-undefined declare that a library does not refer to external symbols - -o OUTPUT-FILE create OUTPUT-FILE from the specified objects - -objectlist FILE use a list of object files found in FILE to specify objects - -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) - -precious-files-regex REGEX - don't remove output files matching REGEX - -release RELEASE specify package release information - -rpath LIBDIR the created library will eventually be installed in LIBDIR - -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries - -shared only do dynamic linking of libtool libraries - -shrext SUFFIX override the standard shared library file extension - -static do not do any dynamic linking of uninstalled libtool libraries - -static-libtool-libs - do not do any dynamic linking of libtool libraries - -version-info CURRENT[:REVISION[:AGE]] - specify library version info [each variable defaults to 0] - -weak LIBNAME declare that the target provides the LIBNAME interface - -Wc,FLAG - -Xcompiler FLAG pass linker-specific FLAG directly to the compiler - -Wl,FLAG - -Xlinker FLAG pass linker-specific FLAG directly to the linker - -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) - -All other options (arguments beginning with '-') are ignored. - -Every other argument is treated as a filename. Files ending in '.la' are -treated as uninstalled libtool libraries, other files are standard or library -object files. - -If the OUTPUT-FILE ends in '.la', then a libtool library is created, -only library objects ('.lo' files) may be specified, and '-rpath' is -required, except when creating a convenience library. - -If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created -using 'ar' and 'ranlib', or on Windows using 'lib'. - -If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file -is created, otherwise an executable program is created." - ;; - - uninstall) - $ECHO \ -"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... - -Remove libraries from an installation directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed -to RM. - -If FILE is a libtool library, all the files associated with it are deleted. -Otherwise, only FILE itself is deleted using RM." - ;; - - *) - func_fatal_help "invalid operation mode '$opt_mode'" - ;; - esac - - echo - $ECHO "Try '$progname --help' for more information about other modes." -} - -# Now that we've collected a possible --mode arg, show help if necessary -if $opt_help; then - if test : = "$opt_help"; then - func_mode_help - else - { - func_help noexit - for opt_mode in compile link execute install finish uninstall clean; do - func_mode_help - done - } | $SED -n '1p; 2,$s/^Usage:/ or: /p' - { - func_help noexit - for opt_mode in compile link execute install finish uninstall clean; do - echo - func_mode_help - done - } | - $SED '1d - /^When reporting/,/^Report/{ - H - d - } - $x - /information about other modes/d - /more detailed .*MODE/d - s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' - fi - exit $? -fi - - -# func_mode_execute arg... -func_mode_execute () -{ - $debug_cmd - - # The first argument is the command name. - cmd=$nonopt - test -z "$cmd" && \ - func_fatal_help "you must specify a COMMAND" - - # Handle -dlopen flags immediately. - for file in $opt_dlopen; do - test -f "$file" \ - || func_fatal_help "'$file' is not a file" - - dir= - case $file in - *.la) - func_resolve_sysroot "$file" - file=$func_resolve_sysroot_result - - # Check to see that this really is a libtool archive. - func_lalib_unsafe_p "$file" \ - || func_fatal_help "'$lib' is not a valid libtool archive" - - # Read the libtool library. - dlname= - library_names= - func_source "$file" - - # Skip this library if it cannot be dlopened. - if test -z "$dlname"; then - # Warn if it was a shared library. - test -n "$library_names" && \ - func_warning "'$file' was not linked with '-export-dynamic'" - continue - fi - - func_dirname "$file" "" "." - dir=$func_dirname_result - - if test -f "$dir/$objdir/$dlname"; then - func_append dir "/$objdir" - else - if test ! -f "$dir/$dlname"; then - func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" - fi - fi - ;; - - *.lo) - # Just add the directory containing the .lo file. - func_dirname "$file" "" "." - dir=$func_dirname_result - ;; - - *) - func_warning "'-dlopen' is ignored for non-libtool libraries and objects" - continue - ;; - esac - - # Get the absolute pathname. - absdir=`cd "$dir" && pwd` - test -n "$absdir" && dir=$absdir - - # Now add the directory to shlibpath_var. - if eval "test -z \"\$$shlibpath_var\""; then - eval "$shlibpath_var=\"\$dir\"" - else - eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" - fi - done - - # This variable tells wrapper scripts just to set shlibpath_var - # rather than running their programs. - libtool_execute_magic=$magic - - # Check if any of the arguments is a wrapper script. - args= - for file - do - case $file in - -* | *.la | *.lo ) ;; - *) - # Do a test to see if this is really a libtool program. - if func_ltwrapper_script_p "$file"; then - func_source "$file" - # Transform arg to wrapped name. - file=$progdir/$program - elif func_ltwrapper_executable_p "$file"; then - func_ltwrapper_scriptname "$file" - func_source "$func_ltwrapper_scriptname_result" - # Transform arg to wrapped name. - file=$progdir/$program - fi - ;; - esac - # Quote arguments (to preserve shell metacharacters). - func_append_quoted args "$file" - done - - if $opt_dry_run; then - # Display what would be done. - if test -n "$shlibpath_var"; then - eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" - echo "export $shlibpath_var" - fi - $ECHO "$cmd$args" - exit $EXIT_SUCCESS - else - if test -n "$shlibpath_var"; then - # Export the shlibpath_var. - eval "export $shlibpath_var" - fi - - # Restore saved environment variables - for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES - do - eval "if test \"\${save_$lt_var+set}\" = set; then - $lt_var=\$save_$lt_var; export $lt_var - else - $lt_unset $lt_var - fi" - done - - # Now prepare to actually exec the command. - exec_cmd=\$cmd$args - fi -} - -test execute = "$opt_mode" && func_mode_execute ${1+"$@"} - - -# func_mode_finish arg... -func_mode_finish () -{ - $debug_cmd - - libs= - libdirs= - admincmds= - - for opt in "$nonopt" ${1+"$@"} - do - if test -d "$opt"; then - func_append libdirs " $opt" - - elif test -f "$opt"; then - if func_lalib_unsafe_p "$opt"; then - func_append libs " $opt" - else - func_warning "'$opt' is not a valid libtool archive" - fi - - else - func_fatal_error "invalid argument '$opt'" - fi - done - - if test -n "$libs"; then - if test -n "$lt_sysroot"; then - sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` - sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" - else - sysroot_cmd= - fi - - # Remove sysroot references - if $opt_dry_run; then - for lib in $libs; do - echo "removing references to $lt_sysroot and '=' prefixes from $lib" - done - else - tmpdir=`func_mktempdir` - for lib in $libs; do - $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ - > $tmpdir/tmp-la - mv -f $tmpdir/tmp-la $lib - done - ${RM}r "$tmpdir" - fi - fi - - if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then - for libdir in $libdirs; do - if test -n "$finish_cmds"; then - # Do each command in the finish commands. - func_execute_cmds "$finish_cmds" 'admincmds="$admincmds -'"$cmd"'"' - fi - if test -n "$finish_eval"; then - # Do the single finish_eval. - eval cmds=\"$finish_eval\" - $opt_dry_run || eval "$cmds" || func_append admincmds " - $cmds" - fi - done - fi - - # Exit here if they wanted silent mode. - $opt_quiet && exit $EXIT_SUCCESS - - if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then - echo "----------------------------------------------------------------------" - echo "Libraries have been installed in:" - for libdir in $libdirs; do - $ECHO " $libdir" - done - echo - echo "If you ever happen to want to link against installed libraries" - echo "in a given directory, LIBDIR, you must either use libtool, and" - echo "specify the full pathname of the library, or use the '-LLIBDIR'" - echo "flag during linking and do at least one of the following:" - if test -n "$shlibpath_var"; then - echo " - add LIBDIR to the '$shlibpath_var' environment variable" - echo " during execution" - fi - if test -n "$runpath_var"; then - echo " - add LIBDIR to the '$runpath_var' environment variable" - echo " during linking" - fi - if test -n "$hardcode_libdir_flag_spec"; then - libdir=LIBDIR - eval flag=\"$hardcode_libdir_flag_spec\" - - $ECHO " - use the '$flag' linker flag" - fi - if test -n "$admincmds"; then - $ECHO " - have your system administrator run these commands:$admincmds" - fi - if test -f /etc/ld.so.conf; then - echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" - fi - echo - - echo "See any operating system documentation about shared libraries for" - case $host in - solaris2.[6789]|solaris2.1[0-9]) - echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" - echo "pages." - ;; - *) - echo "more information, such as the ld(1) and ld.so(8) manual pages." - ;; - esac - echo "----------------------------------------------------------------------" - fi - exit $EXIT_SUCCESS -} - -test finish = "$opt_mode" && func_mode_finish ${1+"$@"} - - -# func_mode_install arg... -func_mode_install () -{ - $debug_cmd - - # There may be an optional sh(1) argument at the beginning of - # install_prog (especially on Windows NT). - if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || - # Allow the use of GNU shtool's install command. - case $nonopt in *shtool*) :;; *) false;; esac - then - # Aesthetically quote it. - func_quote_for_eval "$nonopt" - install_prog="$func_quote_for_eval_result " - arg=$1 - shift - else - install_prog= - arg=$nonopt - fi - - # The real first argument should be the name of the installation program. - # Aesthetically quote it. - func_quote_for_eval "$arg" - func_append install_prog "$func_quote_for_eval_result" - install_shared_prog=$install_prog - case " $install_prog " in - *[\\\ /]cp\ *) install_cp=: ;; - *) install_cp=false ;; - esac - - # We need to accept at least all the BSD install flags. - dest= - files= - opts= - prev= - install_type= - isdir=false - stripme= - no_mode=: - for arg - do - arg2= - if test -n "$dest"; then - func_append files " $dest" - dest=$arg - continue - fi - - case $arg in - -d) isdir=: ;; - -f) - if $install_cp; then :; else - prev=$arg - fi - ;; - -g | -m | -o) - prev=$arg - ;; - -s) - stripme=" -s" - continue - ;; - -*) - ;; - *) - # If the previous option needed an argument, then skip it. - if test -n "$prev"; then - if test X-m = "X$prev" && test -n "$install_override_mode"; then - arg2=$install_override_mode - no_mode=false - fi - prev= - else - dest=$arg - continue - fi - ;; - esac - - # Aesthetically quote the argument. - func_quote_for_eval "$arg" - func_append install_prog " $func_quote_for_eval_result" - if test -n "$arg2"; then - func_quote_for_eval "$arg2" - fi - func_append install_shared_prog " $func_quote_for_eval_result" - done - - test -z "$install_prog" && \ - func_fatal_help "you must specify an install program" - - test -n "$prev" && \ - func_fatal_help "the '$prev' option requires an argument" - - if test -n "$install_override_mode" && $no_mode; then - if $install_cp; then :; else - func_quote_for_eval "$install_override_mode" - func_append install_shared_prog " -m $func_quote_for_eval_result" - fi - fi - - if test -z "$files"; then - if test -z "$dest"; then - func_fatal_help "no file or destination specified" - else - func_fatal_help "you must specify a destination" - fi - fi - - # Strip any trailing slash from the destination. - func_stripname '' '/' "$dest" - dest=$func_stripname_result - - # Check to see that the destination is a directory. - test -d "$dest" && isdir=: - if $isdir; then - destdir=$dest - destname= - else - func_dirname_and_basename "$dest" "" "." - destdir=$func_dirname_result - destname=$func_basename_result - - # Not a directory, so check to see that there is only one file specified. - set dummy $files; shift - test "$#" -gt 1 && \ - func_fatal_help "'$dest' is not a directory" - fi - case $destdir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - for file in $files; do - case $file in - *.lo) ;; - *) - func_fatal_help "'$destdir' must be an absolute directory name" - ;; - esac - done - ;; - esac - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic=$magic - - staticlibs= - future_libdirs= - current_libdirs= - for file in $files; do - - # Do each installation. - case $file in - *.$libext) - # Do the static libraries later. - func_append staticlibs " $file" - ;; - - *.la) - func_resolve_sysroot "$file" - file=$func_resolve_sysroot_result - - # Check to see that this really is a libtool archive. - func_lalib_unsafe_p "$file" \ - || func_fatal_help "'$file' is not a valid libtool archive" - - library_names= - old_library= - relink_command= - func_source "$file" - - # Add the libdir to current_libdirs if it is the destination. - if test "X$destdir" = "X$libdir"; then - case "$current_libdirs " in - *" $libdir "*) ;; - *) func_append current_libdirs " $libdir" ;; - esac - else - # Note the libdir as a future libdir. - case "$future_libdirs " in - *" $libdir "*) ;; - *) func_append future_libdirs " $libdir" ;; - esac - fi - - func_dirname "$file" "/" "" - dir=$func_dirname_result - func_append dir "$objdir" - - if test -n "$relink_command"; then - # Determine the prefix the user has applied to our future dir. - inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` - - # Don't allow the user to place us outside of our expected - # location b/c this prevents finding dependent libraries that - # are installed to the same prefix. - # At present, this check doesn't affect windows .dll's that - # are installed into $libdir/../bin (currently, that works fine) - # but it's something to keep an eye on. - test "$inst_prefix_dir" = "$destdir" && \ - func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" - - if test -n "$inst_prefix_dir"; then - # Stick the inst_prefix_dir data into the link command. - relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` - else - relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` - fi - - func_warning "relinking '$file'" - func_show_eval "$relink_command" \ - 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' - fi - - # See the names of the shared library. - set dummy $library_names; shift - if test -n "$1"; then - realname=$1 - shift - - srcname=$realname - test -n "$relink_command" && srcname=${realname}T - - # Install the shared library and build the symlinks. - func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ - 'exit $?' - tstripme=$stripme - case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - case $realname in - *.dll.a) - tstripme= - ;; - esac - ;; - os2*) - case $realname in - *_dll.a) - tstripme= - ;; - esac - ;; - esac - if test -n "$tstripme" && test -n "$striplib"; then - func_show_eval "$striplib $destdir/$realname" 'exit $?' - fi - - if test "$#" -gt 0; then - # Delete the old symlinks, and create new ones. - # Try 'ln -sf' first, because the 'ln' binary might depend on - # the symlink we replace! Solaris /bin/ln does not understand -f, - # so we also need to try rm && ln -s. - for linkname - do - test "$linkname" != "$realname" \ - && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" - done - fi - - # Do each command in the postinstall commands. - lib=$destdir/$realname - func_execute_cmds "$postinstall_cmds" 'exit $?' - fi - - # Install the pseudo-library for information purposes. - func_basename "$file" - name=$func_basename_result - instname=$dir/${name}i - func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' - - # Maybe install the static library, too. - test -n "$old_library" && func_append staticlibs " $dir/$old_library" - ;; - - *.lo) - # Install (i.e. copy) a libtool object. - - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile=$destdir/$destname - else - func_basename "$file" - destfile=$func_basename_result - destfile=$destdir/$destfile - fi - - # Deduce the name of the destination old-style object file. - case $destfile in - *.lo) - func_lo2o "$destfile" - staticdest=$func_lo2o_result - ;; - *.$objext) - staticdest=$destfile - destfile= - ;; - *) - func_fatal_help "cannot copy a libtool object to '$destfile'" - ;; - esac - - # Install the libtool object if requested. - test -n "$destfile" && \ - func_show_eval "$install_prog $file $destfile" 'exit $?' - - # Install the old object if enabled. - if test yes = "$build_old_libs"; then - # Deduce the name of the old-style object file. - func_lo2o "$file" - staticobj=$func_lo2o_result - func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' - fi - exit $EXIT_SUCCESS - ;; - - *) - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile=$destdir/$destname - else - func_basename "$file" - destfile=$func_basename_result - destfile=$destdir/$destfile - fi - - # If the file is missing, and there is a .exe on the end, strip it - # because it is most likely a libtool script we actually want to - # install - stripped_ext= - case $file in - *.exe) - if test ! -f "$file"; then - func_stripname '' '.exe' "$file" - file=$func_stripname_result - stripped_ext=.exe - fi - ;; - esac - - # Do a test to see if this is really a libtool program. - case $host in - *cygwin* | *mingw*) - if func_ltwrapper_executable_p "$file"; then - func_ltwrapper_scriptname "$file" - wrapper=$func_ltwrapper_scriptname_result - else - func_stripname '' '.exe' "$file" - wrapper=$func_stripname_result - fi - ;; - *) - wrapper=$file - ;; - esac - if func_ltwrapper_script_p "$wrapper"; then - notinst_deplibs= - relink_command= - - func_source "$wrapper" - - # Check the variables that should have been set. - test -z "$generated_by_libtool_version" && \ - func_fatal_error "invalid libtool wrapper script '$wrapper'" - - finalize=: - for lib in $notinst_deplibs; do - # Check to see that each library is installed. - libdir= - if test -f "$lib"; then - func_source "$lib" - fi - libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` - if test -n "$libdir" && test ! -f "$libfile"; then - func_warning "'$lib' has not been installed in '$libdir'" - finalize=false - fi - done - - relink_command= - func_source "$wrapper" - - outputname= - if test no = "$fast_install" && test -n "$relink_command"; then - $opt_dry_run || { - if $finalize; then - tmpdir=`func_mktempdir` - func_basename "$file$stripped_ext" - file=$func_basename_result - outputname=$tmpdir/$file - # Replace the output file specification. - relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` - - $opt_quiet || { - func_quote_for_expand "$relink_command" - eval "func_echo $func_quote_for_expand_result" - } - if eval "$relink_command"; then : - else - func_error "error: relink '$file' with the above command before installing it" - $opt_dry_run || ${RM}r "$tmpdir" - continue - fi - file=$outputname - else - func_warning "cannot relink '$file'" - fi - } - else - # Install the binary that we compiled earlier. - file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` - fi - fi - - # remove .exe since cygwin /usr/bin/install will append another - # one anyway - case $install_prog,$host in - */usr/bin/install*,*cygwin*) - case $file:$destfile in - *.exe:*.exe) - # this is ok - ;; - *.exe:*) - destfile=$destfile.exe - ;; - *:*.exe) - func_stripname '' '.exe' "$destfile" - destfile=$func_stripname_result - ;; - esac - ;; - esac - func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' - $opt_dry_run || if test -n "$outputname"; then - ${RM}r "$tmpdir" - fi - ;; - esac - done - - for file in $staticlibs; do - func_basename "$file" - name=$func_basename_result - - # Set up the ranlib parameters. - oldlib=$destdir/$name - func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 - tool_oldlib=$func_to_tool_file_result - - func_show_eval "$install_prog \$file \$oldlib" 'exit $?' - - if test -n "$stripme" && test -n "$old_striplib"; then - func_show_eval "$old_striplib $tool_oldlib" 'exit $?' - fi - - # Do each command in the postinstall commands. - func_execute_cmds "$old_postinstall_cmds" 'exit $?' - done - - test -n "$future_libdirs" && \ - func_warning "remember to run '$progname --finish$future_libdirs'" - - if test -n "$current_libdirs"; then - # Maybe just do a dry run. - $opt_dry_run && current_libdirs=" -n$current_libdirs" - exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' - else - exit $EXIT_SUCCESS - fi -} - -test install = "$opt_mode" && func_mode_install ${1+"$@"} - - -# func_generate_dlsyms outputname originator pic_p -# Extract symbols from dlprefiles and create ${outputname}S.o with -# a dlpreopen symbol table. -func_generate_dlsyms () -{ - $debug_cmd - - my_outputname=$1 - my_originator=$2 - my_pic_p=${3-false} - my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` - my_dlsyms= - - if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then - if test -n "$NM" && test -n "$global_symbol_pipe"; then - my_dlsyms=${my_outputname}S.c - else - func_error "not configured to extract global symbols from dlpreopened files" - fi - fi - - if test -n "$my_dlsyms"; then - case $my_dlsyms in - "") ;; - *.c) - # Discover the nlist of each of the dlfiles. - nlist=$output_objdir/$my_outputname.nm - - func_show_eval "$RM $nlist ${nlist}S ${nlist}T" - - # Parse the name list into a source file. - func_verbose "creating $output_objdir/$my_dlsyms" - - $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ -/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ -/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ - -#ifdef __cplusplus -extern \"C\" { -#endif - -#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) -#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" -#endif - -/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE -/* DATA imports from DLLs on WIN32 can't be const, because runtime - relocations are performed -- see ld's documentation on pseudo-relocs. */ -# define LT_DLSYM_CONST -#elif defined __osf__ -/* This system does not cope well with relocations in const data. */ -# define LT_DLSYM_CONST -#else -# define LT_DLSYM_CONST const -#endif - -#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) - -/* External symbol declarations for the compiler. */\ -" - - if test yes = "$dlself"; then - func_verbose "generating symbol list for '$output'" - - $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" - - # Add our own program objects to the symbol list. - progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` - for progfile in $progfiles; do - func_to_tool_file "$progfile" func_convert_file_msys_to_w32 - func_verbose "extracting global C symbols from '$func_to_tool_file_result'" - $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" - done - - if test -n "$exclude_expsyms"; then - $opt_dry_run || { - eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' - eval '$MV "$nlist"T "$nlist"' - } - fi - - if test -n "$export_symbols_regex"; then - $opt_dry_run || { - eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' - eval '$MV "$nlist"T "$nlist"' - } - fi - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - export_symbols=$output_objdir/$outputname.exp - $opt_dry_run || { - $RM $export_symbols - eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' - case $host in - *cygwin* | *mingw* | *cegcc* ) - eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' - eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' - ;; - esac - } - else - $opt_dry_run || { - eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' - eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' - eval '$MV "$nlist"T "$nlist"' - case $host in - *cygwin* | *mingw* | *cegcc* ) - eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' - eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' - ;; - esac - } - fi - fi - - for dlprefile in $dlprefiles; do - func_verbose "extracting global C symbols from '$dlprefile'" - func_basename "$dlprefile" - name=$func_basename_result - case $host in - *cygwin* | *mingw* | *cegcc* ) - # if an import library, we need to obtain dlname - if func_win32_import_lib_p "$dlprefile"; then - func_tr_sh "$dlprefile" - eval "curr_lafile=\$libfile_$func_tr_sh_result" - dlprefile_dlbasename= - if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then - # Use subshell, to avoid clobbering current variable values - dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` - if test -n "$dlprefile_dlname"; then - func_basename "$dlprefile_dlname" - dlprefile_dlbasename=$func_basename_result - else - # no lafile. user explicitly requested -dlpreopen . - $sharedlib_from_linklib_cmd "$dlprefile" - dlprefile_dlbasename=$sharedlib_from_linklib_result - fi - fi - $opt_dry_run || { - if test -n "$dlprefile_dlbasename"; then - eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' - else - func_warning "Could not compute DLL name from $name" - eval '$ECHO ": $name " >> "$nlist"' - fi - func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 - eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | - $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" - } - else # not an import lib - $opt_dry_run || { - eval '$ECHO ": $name " >> "$nlist"' - func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 - eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" - } - fi - ;; - *) - $opt_dry_run || { - eval '$ECHO ": $name " >> "$nlist"' - func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 - eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" - } - ;; - esac - done - - $opt_dry_run || { - # Make sure we have at least an empty file. - test -f "$nlist" || : > "$nlist" - - if test -n "$exclude_expsyms"; then - $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T - $MV "$nlist"T "$nlist" - fi - - # Try sorting and uniquifying the output. - if $GREP -v "^: " < "$nlist" | - if sort -k 3 /dev/null 2>&1; then - sort -k 3 - else - sort +2 - fi | - uniq > "$nlist"S; then - : - else - $GREP -v "^: " < "$nlist" > "$nlist"S - fi - - if test -f "$nlist"S; then - eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' - else - echo '/* NONE */' >> "$output_objdir/$my_dlsyms" - fi - - func_show_eval '$RM "${nlist}I"' - if test -n "$global_symbol_to_import"; then - eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' - fi - - echo >> "$output_objdir/$my_dlsyms" "\ - -/* The mapping between symbol names and symbols. */ -typedef struct { - const char *name; - void *address; -} lt_dlsymlist; -extern LT_DLSYM_CONST lt_dlsymlist -lt_${my_prefix}_LTX_preloaded_symbols[];\ -" - - if test -s "$nlist"I; then - echo >> "$output_objdir/$my_dlsyms" "\ -static void lt_syminit(void) -{ - LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; - for (; symbol->name; ++symbol) - {" - $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" - echo >> "$output_objdir/$my_dlsyms" "\ - } -}" - fi - echo >> "$output_objdir/$my_dlsyms" "\ -LT_DLSYM_CONST lt_dlsymlist -lt_${my_prefix}_LTX_preloaded_symbols[] = -{ {\"$my_originator\", (void *) 0}," - - if test -s "$nlist"I; then - echo >> "$output_objdir/$my_dlsyms" "\ - {\"@INIT@\", (void *) <_syminit}," - fi - - case $need_lib_prefix in - no) - eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" - ;; - *) - eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" - ;; - esac - echo >> "$output_objdir/$my_dlsyms" "\ - {0, (void *) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt_${my_prefix}_LTX_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif\ -" - } # !$opt_dry_run - - pic_flag_for_symtable= - case "$compile_command " in - *" -static "*) ;; - *) - case $host in - # compiling the symbol table file with pic_flag works around - # a FreeBSD bug that causes programs to crash when -lm is - # linked before any other PIC object. But we must not use - # pic_flag when linking with -static. The problem exists in - # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. - *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) - pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; - *-*-hpux*) - pic_flag_for_symtable=" $pic_flag" ;; - *) - $my_pic_p && pic_flag_for_symtable=" $pic_flag" - ;; - esac - ;; - esac - symtab_cflags= - for arg in $LTCFLAGS; do - case $arg in - -pie | -fpie | -fPIE) ;; - *) func_append symtab_cflags " $arg" ;; - esac - done - - # Now compile the dynamic symbol file. - func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' - - # Clean up the generated files. - func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' - - # Transform the symbol file into the correct name. - symfileobj=$output_objdir/${my_outputname}S.$objext - case $host in - *cygwin* | *mingw* | *cegcc* ) - if test -f "$output_objdir/$my_outputname.def"; then - compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` - finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` - else - compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` - finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` - fi - ;; - *) - compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` - finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` - ;; - esac - ;; - *) - func_fatal_error "unknown suffix for '$my_dlsyms'" - ;; - esac - else - # We keep going just in case the user didn't refer to - # lt_preloaded_symbols. The linker will fail if global_symbol_pipe - # really was required. - - # Nullify the symbol file. - compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` - finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` - fi -} - -# func_cygming_gnu_implib_p ARG -# This predicate returns with zero status (TRUE) if -# ARG is a GNU/binutils-style import library. Returns -# with nonzero status (FALSE) otherwise. -func_cygming_gnu_implib_p () -{ - $debug_cmd - - func_to_tool_file "$1" func_convert_file_msys_to_w32 - func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` - test -n "$func_cygming_gnu_implib_tmp" -} - -# func_cygming_ms_implib_p ARG -# This predicate returns with zero status (TRUE) if -# ARG is an MS-style import library. Returns -# with nonzero status (FALSE) otherwise. -func_cygming_ms_implib_p () -{ - $debug_cmd - - func_to_tool_file "$1" func_convert_file_msys_to_w32 - func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` - test -n "$func_cygming_ms_implib_tmp" -} - -# func_win32_libid arg -# return the library type of file 'arg' -# -# Need a lot of goo to handle *both* DLLs and import libs -# Has to be a shell function in order to 'eat' the argument -# that is supplied when $file_magic_command is called. -# Despite the name, also deal with 64 bit binaries. -func_win32_libid () -{ - $debug_cmd - - win32_libid_type=unknown - win32_fileres=`file -L $1 2>/dev/null` - case $win32_fileres in - *ar\ archive\ import\ library*) # definitely import - win32_libid_type="x86 archive import" - ;; - *ar\ archive*) # could be an import, or static - # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. - if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | - $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then - case $nm_interface in - "MS dumpbin") - if func_cygming_ms_implib_p "$1" || - func_cygming_gnu_implib_p "$1" - then - win32_nmres=import - else - win32_nmres= - fi - ;; - *) - func_to_tool_file "$1" func_convert_file_msys_to_w32 - win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | - $SED -n -e ' - 1,100{ - / I /{ - s|.*|import| - p - q - } - }'` - ;; - esac - case $win32_nmres in - import*) win32_libid_type="x86 archive import";; - *) win32_libid_type="x86 archive static";; - esac - fi - ;; - *DLL*) - win32_libid_type="x86 DLL" - ;; - *executable*) # but shell scripts are "executable" too... - case $win32_fileres in - *MS\ Windows\ PE\ Intel*) - win32_libid_type="x86 DLL" - ;; - esac - ;; - esac - $ECHO "$win32_libid_type" -} - -# func_cygming_dll_for_implib ARG -# -# Platform-specific function to extract the -# name of the DLL associated with the specified -# import library ARG. -# Invoked by eval'ing the libtool variable -# $sharedlib_from_linklib_cmd -# Result is available in the variable -# $sharedlib_from_linklib_result -func_cygming_dll_for_implib () -{ - $debug_cmd - - sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` -} - -# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs -# -# The is the core of a fallback implementation of a -# platform-specific function to extract the name of the -# DLL associated with the specified import library LIBNAME. -# -# SECTION_NAME is either .idata$6 or .idata$7, depending -# on the platform and compiler that created the implib. -# -# Echos the name of the DLL associated with the -# specified import library. -func_cygming_dll_for_implib_fallback_core () -{ - $debug_cmd - - match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` - $OBJDUMP -s --section "$1" "$2" 2>/dev/null | - $SED '/^Contents of section '"$match_literal"':/{ - # Place marker at beginning of archive member dllname section - s/.*/====MARK====/ - p - d - } - # These lines can sometimes be longer than 43 characters, but - # are always uninteresting - /:[ ]*file format pe[i]\{,1\}-/d - /^In archive [^:]*:/d - # Ensure marker is printed - /^====MARK====/p - # Remove all lines with less than 43 characters - /^.\{43\}/!d - # From remaining lines, remove first 43 characters - s/^.\{43\}//' | - $SED -n ' - # Join marker and all lines until next marker into a single line - /^====MARK====/ b para - H - $ b para - b - :para - x - s/\n//g - # Remove the marker - s/^====MARK====// - # Remove trailing dots and whitespace - s/[\. \t]*$// - # Print - /./p' | - # we now have a list, one entry per line, of the stringified - # contents of the appropriate section of all members of the - # archive that possess that section. Heuristic: eliminate - # all those that have a first or second character that is - # a '.' (that is, objdump's representation of an unprintable - # character.) This should work for all archives with less than - # 0x302f exports -- but will fail for DLLs whose name actually - # begins with a literal '.' or a single character followed by - # a '.'. - # - # Of those that remain, print the first one. - $SED -e '/^\./d;/^.\./d;q' -} - -# func_cygming_dll_for_implib_fallback ARG -# Platform-specific function to extract the -# name of the DLL associated with the specified -# import library ARG. -# -# This fallback implementation is for use when $DLLTOOL -# does not support the --identify-strict option. -# Invoked by eval'ing the libtool variable -# $sharedlib_from_linklib_cmd -# Result is available in the variable -# $sharedlib_from_linklib_result -func_cygming_dll_for_implib_fallback () -{ - $debug_cmd - - if func_cygming_gnu_implib_p "$1"; then - # binutils import library - sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` - elif func_cygming_ms_implib_p "$1"; then - # ms-generated import library - sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` - else - # unknown - sharedlib_from_linklib_result= - fi -} - - -# func_extract_an_archive dir oldlib -func_extract_an_archive () -{ - $debug_cmd - - f_ex_an_ar_dir=$1; shift - f_ex_an_ar_oldlib=$1 - if test yes = "$lock_old_archive_extraction"; then - lockfile=$f_ex_an_ar_oldlib.lock - until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do - func_echo "Waiting for $lockfile to be removed" - sleep 2 - done - fi - func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ - 'stat=$?; rm -f "$lockfile"; exit $stat' - if test yes = "$lock_old_archive_extraction"; then - $opt_dry_run || rm -f "$lockfile" - fi - if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then - : - else - func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" - fi -} - - -# func_extract_archives gentop oldlib ... -func_extract_archives () -{ - $debug_cmd - - my_gentop=$1; shift - my_oldlibs=${1+"$@"} - my_oldobjs= - my_xlib= - my_xabs= - my_xdir= - - for my_xlib in $my_oldlibs; do - # Extract the objects. - case $my_xlib in - [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; - *) my_xabs=`pwd`"/$my_xlib" ;; - esac - func_basename "$my_xlib" - my_xlib=$func_basename_result - my_xlib_u=$my_xlib - while :; do - case " $extracted_archives " in - *" $my_xlib_u "*) - func_arith $extracted_serial + 1 - extracted_serial=$func_arith_result - my_xlib_u=lt$extracted_serial-$my_xlib ;; - *) break ;; - esac - done - extracted_archives="$extracted_archives $my_xlib_u" - my_xdir=$my_gentop/$my_xlib_u - - func_mkdir_p "$my_xdir" - - case $host in - *-darwin*) - func_verbose "Extracting $my_xabs" - # Do not bother doing anything if just a dry run - $opt_dry_run || { - darwin_orig_dir=`pwd` - cd $my_xdir || exit $? - darwin_archive=$my_xabs - darwin_curdir=`pwd` - func_basename "$darwin_archive" - darwin_base_archive=$func_basename_result - darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` - if test -n "$darwin_arches"; then - darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` - darwin_arch= - func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" - for darwin_arch in $darwin_arches; do - func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" - $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" - cd "unfat-$$/$darwin_base_archive-$darwin_arch" - func_extract_an_archive "`pwd`" "$darwin_base_archive" - cd "$darwin_curdir" - $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" - done # $darwin_arches - ## Okay now we've a bunch of thin objects, gotta fatten them up :) - darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` - darwin_file= - darwin_files= - for darwin_file in $darwin_filelist; do - darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` - $LIPO -create -output "$darwin_file" $darwin_files - done # $darwin_filelist - $RM -rf unfat-$$ - cd "$darwin_orig_dir" - else - cd $darwin_orig_dir - func_extract_an_archive "$my_xdir" "$my_xabs" - fi # $darwin_arches - } # !$opt_dry_run - ;; - *) - func_extract_an_archive "$my_xdir" "$my_xabs" - ;; - esac - my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` - done - - func_extract_archives_result=$my_oldobjs -} - - -# func_emit_wrapper [arg=no] -# -# Emit a libtool wrapper script on stdout. -# Don't directly open a file because we may want to -# incorporate the script contents within a cygwin/mingw -# wrapper executable. Must ONLY be called from within -# func_mode_link because it depends on a number of variables -# set therein. -# -# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR -# variable will take. If 'yes', then the emitted script -# will assume that the directory where it is stored is -# the $objdir directory. This is a cygwin/mingw-specific -# behavior. -func_emit_wrapper () -{ - func_emit_wrapper_arg1=${1-no} - - $ECHO "\ -#! $SHELL - -# $output - temporary wrapper script for $objdir/$outputname -# Generated by $PROGRAM (GNU $PACKAGE) $VERSION -# -# The $output program cannot be directly executed until all the libtool -# libraries that it depends on are installed. -# -# This wrapper script should never be moved out of the build directory. -# If it is, it will not operate correctly. - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -sed_quote_subst='$sed_quote_subst' - -# Be Bourne compatible -if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else - case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac -fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -relink_command=\"$relink_command\" - -# This environment variable determines our operation mode. -if test \"\$libtool_install_magic\" = \"$magic\"; then - # install mode needs the following variables: - generated_by_libtool_version='$macro_version' - notinst_deplibs='$notinst_deplibs' -else - # When we are sourced in execute mode, \$file and \$ECHO are already set. - if test \"\$libtool_execute_magic\" != \"$magic\"; then - file=\"\$0\"" - - qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` - $ECHO "\ - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -\$1 -_LTECHO_EOF' -} - ECHO=\"$qECHO\" - fi - -# Very basic option parsing. These options are (a) specific to -# the libtool wrapper, (b) are identical between the wrapper -# /script/ and the wrapper /executable/ that is used only on -# windows platforms, and (c) all begin with the string "--lt-" -# (application programs are unlikely to have options that match -# this pattern). -# -# There are only two supported options: --lt-debug and -# --lt-dump-script. There is, deliberately, no --lt-help. -# -# The first argument to this parsing function should be the -# script's $0 value, followed by "$@". -lt_option_debug= -func_parse_lt_options () -{ - lt_script_arg0=\$0 - shift - for lt_opt - do - case \"\$lt_opt\" in - --lt-debug) lt_option_debug=1 ;; - --lt-dump-script) - lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` - test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. - lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` - cat \"\$lt_dump_D/\$lt_dump_F\" - exit 0 - ;; - --lt-*) - \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 - exit 1 - ;; - esac - done - - # Print the debug banner immediately: - if test -n \"\$lt_option_debug\"; then - echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 - fi -} - -# Used when --lt-debug. Prints its arguments to stdout -# (redirection is the responsibility of the caller) -func_lt_dump_args () -{ - lt_dump_args_N=1; - for lt_arg - do - \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" - lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` - done -} - -# Core function for launching the target application -func_exec_program_core () -{ -" - case $host in - # Backslashes separate directories on plain windows - *-*-mingw | *-*-os2* | *-cegcc*) - $ECHO "\ - if test -n \"\$lt_option_debug\"; then - \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 - func_lt_dump_args \${1+\"\$@\"} 1>&2 - fi - exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} -" - ;; - - *) - $ECHO "\ - if test -n \"\$lt_option_debug\"; then - \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 - func_lt_dump_args \${1+\"\$@\"} 1>&2 - fi - exec \"\$progdir/\$program\" \${1+\"\$@\"} -" - ;; - esac - $ECHO "\ - \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 - exit 1 -} - -# A function to encapsulate launching the target application -# Strips options in the --lt-* namespace from \$@ and -# launches target application with the remaining arguments. -func_exec_program () -{ - case \" \$* \" in - *\\ --lt-*) - for lt_wr_arg - do - case \$lt_wr_arg in - --lt-*) ;; - *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; - esac - shift - done ;; - esac - func_exec_program_core \${1+\"\$@\"} -} - - # Parse options - func_parse_lt_options \"\$0\" \${1+\"\$@\"} - - # Find the directory that this script lives in. - thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` - test \"x\$thisdir\" = \"x\$file\" && thisdir=. - - # Follow symbolic links until we get to the real thisdir. - file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` - while test -n \"\$file\"; do - destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` - - # If there was a directory component, then change thisdir. - if test \"x\$destdir\" != \"x\$file\"; then - case \"\$destdir\" in - [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; - *) thisdir=\"\$thisdir/\$destdir\" ;; - esac - fi - - file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` - file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` - done - - # Usually 'no', except on cygwin/mingw when embedded into - # the cwrapper. - WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 - if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then - # special case for '.' - if test \"\$thisdir\" = \".\"; then - thisdir=\`pwd\` - fi - # remove .libs from thisdir - case \"\$thisdir\" in - *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; - $objdir ) thisdir=. ;; - esac - fi - - # Try to get the absolute directory name. - absdir=\`cd \"\$thisdir\" && pwd\` - test -n \"\$absdir\" && thisdir=\"\$absdir\" -" - - if test yes = "$fast_install"; then - $ECHO "\ - program=lt-'$outputname'$exeext - progdir=\"\$thisdir/$objdir\" - - if test ! -f \"\$progdir/\$program\" || - { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ - test \"X\$file\" != \"X\$progdir/\$program\"; }; then - - file=\"\$\$-\$program\" - - if test ! -d \"\$progdir\"; then - $MKDIR \"\$progdir\" - else - $RM \"\$progdir/\$file\" - fi" - - $ECHO "\ - - # relink executable if necessary - if test -n \"\$relink_command\"; then - if relink_command_output=\`eval \$relink_command 2>&1\`; then : - else - \$ECHO \"\$relink_command_output\" >&2 - $RM \"\$progdir/\$file\" - exit 1 - fi - fi - - $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || - { $RM \"\$progdir/\$program\"; - $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } - $RM \"\$progdir/\$file\" - fi" - else - $ECHO "\ - program='$outputname' - progdir=\"\$thisdir/$objdir\" -" - fi - - $ECHO "\ - - if test -f \"\$progdir/\$program\"; then" - - # fixup the dll searchpath if we need to. - # - # Fix the DLL searchpath if we need to. Do this before prepending - # to shlibpath, because on Windows, both are PATH and uninstalled - # libraries must come first. - if test -n "$dllsearchpath"; then - $ECHO "\ - # Add the dll search path components to the executable PATH - PATH=$dllsearchpath:\$PATH -" - fi - - # Export our shlibpath_var if we have one. - if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then - $ECHO "\ - # Add our own library path to $shlibpath_var - $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" - - # Some systems cannot cope with colon-terminated $shlibpath_var - # The second colon is a workaround for a bug in BeOS R4 sed - $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` - - export $shlibpath_var -" - fi - - $ECHO "\ - if test \"\$libtool_execute_magic\" != \"$magic\"; then - # Run the actual program with our arguments. - func_exec_program \${1+\"\$@\"} - fi - else - # The program doesn't exist. - \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 - \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 - \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 - exit 1 - fi -fi\ -" -} - - -# func_emit_cwrapperexe_src -# emit the source code for a wrapper executable on stdout -# Must ONLY be called from within func_mode_link because -# it depends on a number of variable set therein. -func_emit_cwrapperexe_src () -{ - cat < -#include -#ifdef _MSC_VER -# include -# include -# include -#else -# include -# include -# ifdef __CYGWIN__ -# include -# endif -#endif -#include -#include -#include -#include -#include -#include -#include -#include - -#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) - -/* declarations of non-ANSI functions */ -#if defined __MINGW32__ -# ifdef __STRICT_ANSI__ -int _putenv (const char *); -# endif -#elif defined __CYGWIN__ -# ifdef __STRICT_ANSI__ -char *realpath (const char *, char *); -int putenv (char *); -int setenv (const char *, const char *, int); -# endif -/* #elif defined other_platform || defined ... */ -#endif - -/* portability defines, excluding path handling macros */ -#if defined _MSC_VER -# define setmode _setmode -# define stat _stat -# define chmod _chmod -# define getcwd _getcwd -# define putenv _putenv -# define S_IXUSR _S_IEXEC -#elif defined __MINGW32__ -# define setmode _setmode -# define stat _stat -# define chmod _chmod -# define getcwd _getcwd -# define putenv _putenv -#elif defined __CYGWIN__ -# define HAVE_SETENV -# define FOPEN_WB "wb" -/* #elif defined other platforms ... */ -#endif - -#if defined PATH_MAX -# define LT_PATHMAX PATH_MAX -#elif defined MAXPATHLEN -# define LT_PATHMAX MAXPATHLEN -#else -# define LT_PATHMAX 1024 -#endif - -#ifndef S_IXOTH -# define S_IXOTH 0 -#endif -#ifndef S_IXGRP -# define S_IXGRP 0 -#endif - -/* path handling portability macros */ -#ifndef DIR_SEPARATOR -# define DIR_SEPARATOR '/' -# define PATH_SEPARATOR ':' -#endif - -#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ - defined __OS2__ -# define HAVE_DOS_BASED_FILE_SYSTEM -# define FOPEN_WB "wb" -# ifndef DIR_SEPARATOR_2 -# define DIR_SEPARATOR_2 '\\' -# endif -# ifndef PATH_SEPARATOR_2 -# define PATH_SEPARATOR_2 ';' -# endif -#endif - -#ifndef DIR_SEPARATOR_2 -# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) -#else /* DIR_SEPARATOR_2 */ -# define IS_DIR_SEPARATOR(ch) \ - (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) -#endif /* DIR_SEPARATOR_2 */ - -#ifndef PATH_SEPARATOR_2 -# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) -#else /* PATH_SEPARATOR_2 */ -# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) -#endif /* PATH_SEPARATOR_2 */ - -#ifndef FOPEN_WB -# define FOPEN_WB "w" -#endif -#ifndef _O_BINARY -# define _O_BINARY 0 -#endif - -#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) -#define XFREE(stale) do { \ - if (stale) { free (stale); stale = 0; } \ -} while (0) - -#if defined LT_DEBUGWRAPPER -static int lt_debug = 1; -#else -static int lt_debug = 0; -#endif - -const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ - -void *xmalloc (size_t num); -char *xstrdup (const char *string); -const char *base_name (const char *name); -char *find_executable (const char *wrapper); -char *chase_symlinks (const char *pathspec); -int make_executable (const char *path); -int check_executable (const char *path); -char *strendzap (char *str, const char *pat); -void lt_debugprintf (const char *file, int line, const char *fmt, ...); -void lt_fatal (const char *file, int line, const char *message, ...); -static const char *nonnull (const char *s); -static const char *nonempty (const char *s); -void lt_setenv (const char *name, const char *value); -char *lt_extend_str (const char *orig_value, const char *add, int to_end); -void lt_update_exe_path (const char *name, const char *value); -void lt_update_lib_path (const char *name, const char *value); -char **prepare_spawn (char **argv); -void lt_dump_script (FILE *f); -EOF - - cat <= 0) - && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) - return 1; - else - return 0; -} - -int -make_executable (const char *path) -{ - int rval = 0; - struct stat st; - - lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", - nonempty (path)); - if ((!path) || (!*path)) - return 0; - - if (stat (path, &st) >= 0) - { - rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); - } - return rval; -} - -/* Searches for the full path of the wrapper. Returns - newly allocated full path name if found, NULL otherwise - Does not chase symlinks, even on platforms that support them. -*/ -char * -find_executable (const char *wrapper) -{ - int has_slash = 0; - const char *p; - const char *p_next; - /* static buffer for getcwd */ - char tmp[LT_PATHMAX + 1]; - size_t tmp_len; - char *concat_name; - - lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", - nonempty (wrapper)); - - if ((wrapper == NULL) || (*wrapper == '\0')) - return NULL; - - /* Absolute path? */ -#if defined HAVE_DOS_BASED_FILE_SYSTEM - if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') - { - concat_name = xstrdup (wrapper); - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - } - else - { -#endif - if (IS_DIR_SEPARATOR (wrapper[0])) - { - concat_name = xstrdup (wrapper); - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - } -#if defined HAVE_DOS_BASED_FILE_SYSTEM - } -#endif - - for (p = wrapper; *p; p++) - if (*p == '/') - { - has_slash = 1; - break; - } - if (!has_slash) - { - /* no slashes; search PATH */ - const char *path = getenv ("PATH"); - if (path != NULL) - { - for (p = path; *p; p = p_next) - { - const char *q; - size_t p_len; - for (q = p; *q; q++) - if (IS_PATH_SEPARATOR (*q)) - break; - p_len = (size_t) (q - p); - p_next = (*q == '\0' ? q : q + 1); - if (p_len == 0) - { - /* empty path: current directory */ - if (getcwd (tmp, LT_PATHMAX) == NULL) - lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", - nonnull (strerror (errno))); - tmp_len = strlen (tmp); - concat_name = - XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); - memcpy (concat_name, tmp, tmp_len); - concat_name[tmp_len] = '/'; - strcpy (concat_name + tmp_len + 1, wrapper); - } - else - { - concat_name = - XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); - memcpy (concat_name, p, p_len); - concat_name[p_len] = '/'; - strcpy (concat_name + p_len + 1, wrapper); - } - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - } - } - /* not found in PATH; assume curdir */ - } - /* Relative path | not found in path: prepend cwd */ - if (getcwd (tmp, LT_PATHMAX) == NULL) - lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", - nonnull (strerror (errno))); - tmp_len = strlen (tmp); - concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); - memcpy (concat_name, tmp, tmp_len); - concat_name[tmp_len] = '/'; - strcpy (concat_name + tmp_len + 1, wrapper); - - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - return NULL; -} - -char * -chase_symlinks (const char *pathspec) -{ -#ifndef S_ISLNK - return xstrdup (pathspec); -#else - char buf[LT_PATHMAX]; - struct stat s; - char *tmp_pathspec = xstrdup (pathspec); - char *p; - int has_symlinks = 0; - while (strlen (tmp_pathspec) && !has_symlinks) - { - lt_debugprintf (__FILE__, __LINE__, - "checking path component for symlinks: %s\n", - tmp_pathspec); - if (lstat (tmp_pathspec, &s) == 0) - { - if (S_ISLNK (s.st_mode) != 0) - { - has_symlinks = 1; - break; - } - - /* search backwards for last DIR_SEPARATOR */ - p = tmp_pathspec + strlen (tmp_pathspec) - 1; - while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) - p--; - if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) - { - /* no more DIR_SEPARATORS left */ - break; - } - *p = '\0'; - } - else - { - lt_fatal (__FILE__, __LINE__, - "error accessing file \"%s\": %s", - tmp_pathspec, nonnull (strerror (errno))); - } - } - XFREE (tmp_pathspec); - - if (!has_symlinks) - { - return xstrdup (pathspec); - } - - tmp_pathspec = realpath (pathspec, buf); - if (tmp_pathspec == 0) - { - lt_fatal (__FILE__, __LINE__, - "could not follow symlinks for %s", pathspec); - } - return xstrdup (tmp_pathspec); -#endif -} - -char * -strendzap (char *str, const char *pat) -{ - size_t len, patlen; - - assert (str != NULL); - assert (pat != NULL); - - len = strlen (str); - patlen = strlen (pat); - - if (patlen <= len) - { - str += len - patlen; - if (STREQ (str, pat)) - *str = '\0'; - } - return str; -} - -void -lt_debugprintf (const char *file, int line, const char *fmt, ...) -{ - va_list args; - if (lt_debug) - { - (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); - va_start (args, fmt); - (void) vfprintf (stderr, fmt, args); - va_end (args); - } -} - -static void -lt_error_core (int exit_status, const char *file, - int line, const char *mode, - const char *message, va_list ap) -{ - fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); - vfprintf (stderr, message, ap); - fprintf (stderr, ".\n"); - - if (exit_status >= 0) - exit (exit_status); -} - -void -lt_fatal (const char *file, int line, const char *message, ...) -{ - va_list ap; - va_start (ap, message); - lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); - va_end (ap); -} - -static const char * -nonnull (const char *s) -{ - return s ? s : "(null)"; -} - -static const char * -nonempty (const char *s) -{ - return (s && !*s) ? "(empty)" : nonnull (s); -} - -void -lt_setenv (const char *name, const char *value) -{ - lt_debugprintf (__FILE__, __LINE__, - "(lt_setenv) setting '%s' to '%s'\n", - nonnull (name), nonnull (value)); - { -#ifdef HAVE_SETENV - /* always make a copy, for consistency with !HAVE_SETENV */ - char *str = xstrdup (value); - setenv (name, str, 1); -#else - size_t len = strlen (name) + 1 + strlen (value) + 1; - char *str = XMALLOC (char, len); - sprintf (str, "%s=%s", name, value); - if (putenv (str) != EXIT_SUCCESS) - { - XFREE (str); - } -#endif - } -} - -char * -lt_extend_str (const char *orig_value, const char *add, int to_end) -{ - char *new_value; - if (orig_value && *orig_value) - { - size_t orig_value_len = strlen (orig_value); - size_t add_len = strlen (add); - new_value = XMALLOC (char, add_len + orig_value_len + 1); - if (to_end) - { - strcpy (new_value, orig_value); - strcpy (new_value + orig_value_len, add); - } - else - { - strcpy (new_value, add); - strcpy (new_value + add_len, orig_value); - } - } - else - { - new_value = xstrdup (add); - } - return new_value; -} - -void -lt_update_exe_path (const char *name, const char *value) -{ - lt_debugprintf (__FILE__, __LINE__, - "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", - nonnull (name), nonnull (value)); - - if (name && *name && value && *value) - { - char *new_value = lt_extend_str (getenv (name), value, 0); - /* some systems can't cope with a ':'-terminated path #' */ - size_t len = strlen (new_value); - while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) - { - new_value[--len] = '\0'; - } - lt_setenv (name, new_value); - XFREE (new_value); - } -} - -void -lt_update_lib_path (const char *name, const char *value) -{ - lt_debugprintf (__FILE__, __LINE__, - "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", - nonnull (name), nonnull (value)); - - if (name && *name && value && *value) - { - char *new_value = lt_extend_str (getenv (name), value, 0); - lt_setenv (name, new_value); - XFREE (new_value); - } -} - -EOF - case $host_os in - mingw*) - cat <<"EOF" - -/* Prepares an argument vector before calling spawn(). - Note that spawn() does not by itself call the command interpreter - (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : - ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&v); - v.dwPlatformId == VER_PLATFORM_WIN32_NT; - }) ? "cmd.exe" : "command.com"). - Instead it simply concatenates the arguments, separated by ' ', and calls - CreateProcess(). We must quote the arguments since Win32 CreateProcess() - interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a - special way: - - Space and tab are interpreted as delimiters. They are not treated as - delimiters if they are surrounded by double quotes: "...". - - Unescaped double quotes are removed from the input. Their only effect is - that within double quotes, space and tab are treated like normal - characters. - - Backslashes not followed by double quotes are not special. - - But 2*n+1 backslashes followed by a double quote become - n backslashes followed by a double quote (n >= 0): - \" -> " - \\\" -> \" - \\\\\" -> \\" - */ -#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" -#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" -char ** -prepare_spawn (char **argv) -{ - size_t argc; - char **new_argv; - size_t i; - - /* Count number of arguments. */ - for (argc = 0; argv[argc] != NULL; argc++) - ; - - /* Allocate new argument vector. */ - new_argv = XMALLOC (char *, argc + 1); - - /* Put quoted arguments into the new argument vector. */ - for (i = 0; i < argc; i++) - { - const char *string = argv[i]; - - if (string[0] == '\0') - new_argv[i] = xstrdup ("\"\""); - else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) - { - int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); - size_t length; - unsigned int backslashes; - const char *s; - char *quoted_string; - char *p; - - length = 0; - backslashes = 0; - if (quote_around) - length++; - for (s = string; *s != '\0'; s++) - { - char c = *s; - if (c == '"') - length += backslashes + 1; - length++; - if (c == '\\') - backslashes++; - else - backslashes = 0; - } - if (quote_around) - length += backslashes + 1; - - quoted_string = XMALLOC (char, length + 1); - - p = quoted_string; - backslashes = 0; - if (quote_around) - *p++ = '"'; - for (s = string; *s != '\0'; s++) - { - char c = *s; - if (c == '"') - { - unsigned int j; - for (j = backslashes + 1; j > 0; j--) - *p++ = '\\'; - } - *p++ = c; - if (c == '\\') - backslashes++; - else - backslashes = 0; - } - if (quote_around) - { - unsigned int j; - for (j = backslashes; j > 0; j--) - *p++ = '\\'; - *p++ = '"'; - } - *p = '\0'; - - new_argv[i] = quoted_string; - } - else - new_argv[i] = (char *) string; - } - new_argv[argc] = NULL; - - return new_argv; -} -EOF - ;; - esac - - cat <<"EOF" -void lt_dump_script (FILE* f) -{ -EOF - func_emit_wrapper yes | - $SED -n -e ' -s/^\(.\{79\}\)\(..*\)/\1\ -\2/ -h -s/\([\\"]\)/\\\1/g -s/$/\\n/ -s/\([^\n]*\).*/ fputs ("\1", f);/p -g -D' - cat <<"EOF" -} -EOF -} -# end: func_emit_cwrapperexe_src - -# func_win32_import_lib_p ARG -# True if ARG is an import lib, as indicated by $file_magic_cmd -func_win32_import_lib_p () -{ - $debug_cmd - - case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in - *import*) : ;; - *) false ;; - esac -} - -# func_suncc_cstd_abi -# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! -# Several compiler flags select an ABI that is incompatible with the -# Cstd library. Avoid specifying it if any are in CXXFLAGS. -func_suncc_cstd_abi () -{ - $debug_cmd - - case " $compile_command " in - *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) - suncc_use_cstd_abi=no - ;; - *) - suncc_use_cstd_abi=yes - ;; - esac -} - -# func_mode_link arg... -func_mode_link () -{ - $debug_cmd - - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) - # It is impossible to link a dll without this setting, and - # we shouldn't force the makefile maintainer to figure out - # what system we are compiling for in order to pass an extra - # flag for every libtool invocation. - # allow_undefined=no - - # FIXME: Unfortunately, there are problems with the above when trying - # to make a dll that has undefined symbols, in which case not - # even a static library is built. For now, we need to specify - # -no-undefined on the libtool link line when we can be certain - # that all symbols are satisfied, otherwise we get a static library. - allow_undefined=yes - ;; - *) - allow_undefined=yes - ;; - esac - libtool_args=$nonopt - base_compile="$nonopt $@" - compile_command=$nonopt - finalize_command=$nonopt - - compile_rpath= - finalize_rpath= - compile_shlibpath= - finalize_shlibpath= - convenience= - old_convenience= - deplibs= - old_deplibs= - compiler_flags= - linker_flags= - dllsearchpath= - lib_search_path=`pwd` - inst_prefix_dir= - new_inherited_linker_flags= - - avoid_version=no - bindir= - dlfiles= - dlprefiles= - dlself=no - export_dynamic=no - export_symbols= - export_symbols_regex= - generated= - libobjs= - ltlibs= - module=no - no_install=no - objs= - os2dllname= - non_pic_objects= - precious_files_regex= - prefer_static_libs=no - preload=false - prev= - prevarg= - release= - rpath= - xrpath= - perm_rpath= - temp_rpath= - thread_safe=no - vinfo= - vinfo_number=no - weak_libs= - single_module=$wl-single_module - func_infer_tag $base_compile - - # We need to know -static, to get the right output filenames. - for arg - do - case $arg in - -shared) - test yes != "$build_libtool_libs" \ - && func_fatal_configuration "cannot build a shared library" - build_old_libs=no - break - ;; - -all-static | -static | -static-libtool-libs) - case $arg in - -all-static) - if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then - func_warning "complete static linking is impossible in this configuration" - fi - if test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - prefer_static_libs=yes - ;; - -static) - if test -z "$pic_flag" && test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - prefer_static_libs=built - ;; - -static-libtool-libs) - if test -z "$pic_flag" && test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - prefer_static_libs=yes - ;; - esac - build_libtool_libs=no - build_old_libs=yes - break - ;; - esac - done - - # See if our shared archives depend on static archives. - test -n "$old_archive_from_new_cmds" && build_old_libs=yes - - # Go through the arguments, transforming them on the way. - while test "$#" -gt 0; do - arg=$1 - shift - func_quote_for_eval "$arg" - qarg=$func_quote_for_eval_unquoted_result - func_append libtool_args " $func_quote_for_eval_result" - - # If the previous option needs an argument, assign it. - if test -n "$prev"; then - case $prev in - output) - func_append compile_command " @OUTPUT@" - func_append finalize_command " @OUTPUT@" - ;; - esac - - case $prev in - bindir) - bindir=$arg - prev= - continue - ;; - dlfiles|dlprefiles) - $preload || { - # Add the symbol object into the linking commands. - func_append compile_command " @SYMFILE@" - func_append finalize_command " @SYMFILE@" - preload=: - } - case $arg in - *.la | *.lo) ;; # We handle these cases below. - force) - if test no = "$dlself"; then - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - self) - if test dlprefiles = "$prev"; then - dlself=yes - elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then - dlself=yes - else - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - *) - if test dlfiles = "$prev"; then - func_append dlfiles " $arg" - else - func_append dlprefiles " $arg" - fi - prev= - continue - ;; - esac - ;; - expsyms) - export_symbols=$arg - test -f "$arg" \ - || func_fatal_error "symbol file '$arg' does not exist" - prev= - continue - ;; - expsyms_regex) - export_symbols_regex=$arg - prev= - continue - ;; - framework) - case $host in - *-*-darwin*) - case "$deplibs " in - *" $qarg.ltframework "*) ;; - *) func_append deplibs " $qarg.ltframework" # this is fixed later - ;; - esac - ;; - esac - prev= - continue - ;; - inst_prefix) - inst_prefix_dir=$arg - prev= - continue - ;; - mllvm) - # Clang does not use LLVM to link, so we can simply discard any - # '-mllvm $arg' options when doing the link step. - prev= - continue - ;; - objectlist) - if test -f "$arg"; then - save_arg=$arg - moreargs= - for fil in `cat "$save_arg"` - do -# func_append moreargs " $fil" - arg=$fil - # A libtool-controlled object. - - # Check to see that this really is a libtool object. - if func_lalib_unsafe_p "$arg"; then - pic_object= - non_pic_object= - - # Read the .lo file - func_source "$arg" - - if test -z "$pic_object" || - test -z "$non_pic_object" || - test none = "$pic_object" && - test none = "$non_pic_object"; then - func_fatal_error "cannot find name of object for '$arg'" - fi - - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir=$func_dirname_result - - if test none != "$pic_object"; then - # Prepend the subdirectory the object is found in. - pic_object=$xdir$pic_object - - if test dlfiles = "$prev"; then - if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then - func_append dlfiles " $pic_object" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - # CHECK ME: I think I busted this. -Ossama - if test dlprefiles = "$prev"; then - # Preload the old-style object. - func_append dlprefiles " $pic_object" - prev= - fi - - # A PIC object. - func_append libobjs " $pic_object" - arg=$pic_object - fi - - # Non-PIC object. - if test none != "$non_pic_object"; then - # Prepend the subdirectory the object is found in. - non_pic_object=$xdir$non_pic_object - - # A standard non-PIC object - func_append non_pic_objects " $non_pic_object" - if test -z "$pic_object" || test none = "$pic_object"; then - arg=$non_pic_object - fi - else - # If the PIC object exists, use it instead. - # $xdir was prepended to $pic_object above. - non_pic_object=$pic_object - func_append non_pic_objects " $non_pic_object" - fi - else - # Only an error if not doing a dry-run. - if $opt_dry_run; then - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir=$func_dirname_result - - func_lo2o "$arg" - pic_object=$xdir$objdir/$func_lo2o_result - non_pic_object=$xdir$func_lo2o_result - func_append libobjs " $pic_object" - func_append non_pic_objects " $non_pic_object" - else - func_fatal_error "'$arg' is not a valid libtool object" - fi - fi - done - else - func_fatal_error "link input file '$arg' does not exist" - fi - arg=$save_arg - prev= - continue - ;; - os2dllname) - os2dllname=$arg - prev= - continue - ;; - precious_regex) - precious_files_regex=$arg - prev= - continue - ;; - release) - release=-$arg - prev= - continue - ;; - rpath | xrpath) - # We need an absolute path. - case $arg in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - func_fatal_error "only absolute run-paths are allowed" - ;; - esac - if test rpath = "$prev"; then - case "$rpath " in - *" $arg "*) ;; - *) func_append rpath " $arg" ;; - esac - else - case "$xrpath " in - *" $arg "*) ;; - *) func_append xrpath " $arg" ;; - esac - fi - prev= - continue - ;; - shrext) - shrext_cmds=$arg - prev= - continue - ;; - weak) - func_append weak_libs " $arg" - prev= - continue - ;; - xcclinker) - func_append linker_flags " $qarg" - func_append compiler_flags " $qarg" - prev= - func_append compile_command " $qarg" - func_append finalize_command " $qarg" - continue - ;; - xcompiler) - func_append compiler_flags " $qarg" - prev= - func_append compile_command " $qarg" - func_append finalize_command " $qarg" - continue - ;; - xlinker) - func_append linker_flags " $qarg" - func_append compiler_flags " $wl$qarg" - prev= - func_append compile_command " $wl$qarg" - func_append finalize_command " $wl$qarg" - continue - ;; - *) - eval "$prev=\"\$arg\"" - prev= - continue - ;; - esac - fi # test -n "$prev" - - prevarg=$arg - - case $arg in - -all-static) - if test -n "$link_static_flag"; then - # See comment for -static flag below, for more details. - func_append compile_command " $link_static_flag" - func_append finalize_command " $link_static_flag" - fi - continue - ;; - - -allow-undefined) - # FIXME: remove this flag sometime in the future. - func_fatal_error "'-allow-undefined' must not be used because it is the default" - ;; - - -avoid-version) - avoid_version=yes - continue - ;; - - -bindir) - prev=bindir - continue - ;; - - -dlopen) - prev=dlfiles - continue - ;; - - -dlpreopen) - prev=dlprefiles - continue - ;; - - -export-dynamic) - export_dynamic=yes - continue - ;; - - -export-symbols | -export-symbols-regex) - if test -n "$export_symbols" || test -n "$export_symbols_regex"; then - func_fatal_error "more than one -exported-symbols argument is not allowed" - fi - if test X-export-symbols = "X$arg"; then - prev=expsyms - else - prev=expsyms_regex - fi - continue - ;; - - -framework) - prev=framework - continue - ;; - - -inst-prefix-dir) - prev=inst_prefix - continue - ;; - - # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* - # so, if we see these flags be careful not to treat them like -L - -L[A-Z][A-Z]*:*) - case $with_gcc/$host in - no/*-*-irix* | /*-*-irix*) - func_append compile_command " $arg" - func_append finalize_command " $arg" - ;; - esac - continue - ;; - - -L*) - func_stripname "-L" '' "$arg" - if test -z "$func_stripname_result"; then - if test "$#" -gt 0; then - func_fatal_error "require no space between '-L' and '$1'" - else - func_fatal_error "need path for '-L' option" - fi - fi - func_resolve_sysroot "$func_stripname_result" - dir=$func_resolve_sysroot_result - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - absdir=`cd "$dir" && pwd` - test -z "$absdir" && \ - func_fatal_error "cannot determine absolute directory name of '$dir'" - dir=$absdir - ;; - esac - case "$deplibs " in - *" -L$dir "* | *" $arg "*) - # Will only happen for absolute or sysroot arguments - ;; - *) - # Preserve sysroot, but never include relative directories - case $dir in - [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; - *) func_append deplibs " -L$dir" ;; - esac - func_append lib_search_path " $dir" - ;; - esac - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) - testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` - case :$dllsearchpath: in - *":$dir:"*) ;; - ::) dllsearchpath=$dir;; - *) func_append dllsearchpath ":$dir";; - esac - case :$dllsearchpath: in - *":$testbindir:"*) ;; - ::) dllsearchpath=$testbindir;; - *) func_append dllsearchpath ":$testbindir";; - esac - ;; - esac - continue - ;; - - -l*) - if test X-lc = "X$arg" || test X-lm = "X$arg"; then - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) - # These systems don't actually have a C or math library (as such) - continue - ;; - *-*-os2*) - # These systems don't actually have a C library (as such) - test X-lc = "X$arg" && continue - ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) - # Do not include libc due to us having libc/libc_r. - test X-lc = "X$arg" && continue - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C and math libraries are in the System framework - func_append deplibs " System.ltframework" - continue - ;; - *-*-sco3.2v5* | *-*-sco5v6*) - # Causes problems with __ctype - test X-lc = "X$arg" && continue - ;; - *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) - # Compiler inserts libc in the correct place for threads to work - test X-lc = "X$arg" && continue - ;; - esac - elif test X-lc_r = "X$arg"; then - case $host in - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) - # Do not include libc_r directly, use -pthread flag. - continue - ;; - esac - fi - func_append deplibs " $arg" - continue - ;; - - -mllvm) - prev=mllvm - continue - ;; - - -module) - module=yes - continue - ;; - - # Tru64 UNIX uses -model [arg] to determine the layout of C++ - # classes, name mangling, and exception handling. - # Darwin uses the -arch flag to determine output architecture. - -model|-arch|-isysroot|--sysroot) - func_append compiler_flags " $arg" - func_append compile_command " $arg" - func_append finalize_command " $arg" - prev=xcompiler - continue - ;; - - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ - |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) - func_append compiler_flags " $arg" - func_append compile_command " $arg" - func_append finalize_command " $arg" - case "$new_inherited_linker_flags " in - *" $arg "*) ;; - * ) func_append new_inherited_linker_flags " $arg" ;; - esac - continue - ;; - - -multi_module) - single_module=$wl-multi_module - continue - ;; - - -no-fast-install) - fast_install=no - continue - ;; - - -no-install) - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) - # The PATH hackery in wrapper scripts is required on Windows - # and Darwin in order for the loader to find any dlls it needs. - func_warning "'-no-install' is ignored for $host" - func_warning "assuming '-no-fast-install' instead" - fast_install=no - ;; - *) no_install=yes ;; - esac - continue - ;; - - -no-undefined) - allow_undefined=no - continue - ;; - - -objectlist) - prev=objectlist - continue - ;; - - -os2dllname) - prev=os2dllname - continue - ;; - - -o) prev=output ;; - - -precious-files-regex) - prev=precious_regex - continue - ;; - - -release) - prev=release - continue - ;; - - -rpath) - prev=rpath - continue - ;; - - -R) - prev=xrpath - continue - ;; - - -R*) - func_stripname '-R' '' "$arg" - dir=$func_stripname_result - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - =*) - func_stripname '=' '' "$dir" - dir=$lt_sysroot$func_stripname_result - ;; - *) - func_fatal_error "only absolute run-paths are allowed" - ;; - esac - case "$xrpath " in - *" $dir "*) ;; - *) func_append xrpath " $dir" ;; - esac - continue - ;; - - -shared) - # The effects of -shared are defined in a previous loop. - continue - ;; - - -shrext) - prev=shrext - continue - ;; - - -static | -static-libtool-libs) - # The effects of -static are defined in a previous loop. - # We used to do the same as -all-static on platforms that - # didn't have a PIC flag, but the assumption that the effects - # would be equivalent was wrong. It would break on at least - # Digital Unix and AIX. - continue - ;; - - -thread-safe) - thread_safe=yes - continue - ;; - - -version-info) - prev=vinfo - continue - ;; - - -version-number) - prev=vinfo - vinfo_number=yes - continue - ;; - - -weak) - prev=weak - continue - ;; - - -Wc,*) - func_stripname '-Wc,' '' "$arg" - args=$func_stripname_result - arg= - save_ifs=$IFS; IFS=, - for flag in $args; do - IFS=$save_ifs - func_quote_for_eval "$flag" - func_append arg " $func_quote_for_eval_result" - func_append compiler_flags " $func_quote_for_eval_result" - done - IFS=$save_ifs - func_stripname ' ' '' "$arg" - arg=$func_stripname_result - ;; - - -Wl,*) - func_stripname '-Wl,' '' "$arg" - args=$func_stripname_result - arg= - save_ifs=$IFS; IFS=, - for flag in $args; do - IFS=$save_ifs - func_quote_for_eval "$flag" - func_append arg " $wl$func_quote_for_eval_result" - func_append compiler_flags " $wl$func_quote_for_eval_result" - func_append linker_flags " $func_quote_for_eval_result" - done - IFS=$save_ifs - func_stripname ' ' '' "$arg" - arg=$func_stripname_result - ;; - - -Xcompiler) - prev=xcompiler - continue - ;; - - -Xlinker) - prev=xlinker - continue - ;; - - -XCClinker) - prev=xcclinker - continue - ;; - - # -msg_* for osf cc - -msg_*) - func_quote_for_eval "$arg" - arg=$func_quote_for_eval_result - ;; - - # Flags to be passed through unchanged, with rationale: - # -64, -mips[0-9] enable 64-bit mode for the SGI compiler - # -r[0-9][0-9]* specify processor for the SGI compiler - # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler - # +DA*, +DD* enable 64-bit mode for the HP compiler - # -q* compiler args for the IBM compiler - # -m*, -t[45]*, -txscale* architecture-specific flags for GCC - # -F/path path to uninstalled frameworks, gcc on darwin - # -p, -pg, --coverage, -fprofile-* profiling flags for GCC - # -fstack-protector* stack protector flags for GCC - # @file GCC response files - # -tp=* Portland pgcc target processor selection - # --sysroot=* for sysroot support - # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization - # -specs=* GCC specs files - # -stdlib=* select c++ std lib with clang - # -fsanitize=* Clang/GCC memory and address sanitizer - # -fuse-ld=* Linker select flags for GCC - # -static-* direct GCC to link specific libraries statically - # -fcilkplus Cilk Plus language extension features for C/C++ - -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ - -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ - -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \ - -specs=*|-fsanitize=*|-fuse-ld=*|-static-*|-fcilkplus) - func_quote_for_eval "$arg" - arg=$func_quote_for_eval_result - func_append compile_command " $arg" - func_append finalize_command " $arg" - func_append compiler_flags " $arg" - continue - ;; - - -Z*) - if test os2 = "`expr $host : '.*\(os2\)'`"; then - # OS/2 uses -Zxxx to specify OS/2-specific options - compiler_flags="$compiler_flags $arg" - func_append compile_command " $arg" - func_append finalize_command " $arg" - case $arg in - -Zlinker | -Zstack) - prev=xcompiler - ;; - esac - continue - else - # Otherwise treat like 'Some other compiler flag' below - func_quote_for_eval "$arg" - arg=$func_quote_for_eval_result - fi - ;; - - # Some other compiler flag. - -* | +*) - func_quote_for_eval "$arg" - arg=$func_quote_for_eval_result - ;; - - *.$objext) - # A standard object. - func_append objs " $arg" - ;; - - *.lo) - # A libtool-controlled object. - - # Check to see that this really is a libtool object. - if func_lalib_unsafe_p "$arg"; then - pic_object= - non_pic_object= - - # Read the .lo file - func_source "$arg" - - if test -z "$pic_object" || - test -z "$non_pic_object" || - test none = "$pic_object" && - test none = "$non_pic_object"; then - func_fatal_error "cannot find name of object for '$arg'" - fi - - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir=$func_dirname_result - - test none = "$pic_object" || { - # Prepend the subdirectory the object is found in. - pic_object=$xdir$pic_object - - if test dlfiles = "$prev"; then - if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then - func_append dlfiles " $pic_object" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - # CHECK ME: I think I busted this. -Ossama - if test dlprefiles = "$prev"; then - # Preload the old-style object. - func_append dlprefiles " $pic_object" - prev= - fi - - # A PIC object. - func_append libobjs " $pic_object" - arg=$pic_object - } - - # Non-PIC object. - if test none != "$non_pic_object"; then - # Prepend the subdirectory the object is found in. - non_pic_object=$xdir$non_pic_object - - # A standard non-PIC object - func_append non_pic_objects " $non_pic_object" - if test -z "$pic_object" || test none = "$pic_object"; then - arg=$non_pic_object - fi - else - # If the PIC object exists, use it instead. - # $xdir was prepended to $pic_object above. - non_pic_object=$pic_object - func_append non_pic_objects " $non_pic_object" - fi - else - # Only an error if not doing a dry-run. - if $opt_dry_run; then - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir=$func_dirname_result - - func_lo2o "$arg" - pic_object=$xdir$objdir/$func_lo2o_result - non_pic_object=$xdir$func_lo2o_result - func_append libobjs " $pic_object" - func_append non_pic_objects " $non_pic_object" - else - func_fatal_error "'$arg' is not a valid libtool object" - fi - fi - ;; - - *.$libext) - # An archive. - func_append deplibs " $arg" - func_append old_deplibs " $arg" - continue - ;; - - *.la) - # A libtool-controlled library. - - func_resolve_sysroot "$arg" - if test dlfiles = "$prev"; then - # This library was specified with -dlopen. - func_append dlfiles " $func_resolve_sysroot_result" - prev= - elif test dlprefiles = "$prev"; then - # The library was specified with -dlpreopen. - func_append dlprefiles " $func_resolve_sysroot_result" - prev= - else - func_append deplibs " $func_resolve_sysroot_result" - fi - continue - ;; - - # Some other compiler argument. - *) - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - func_quote_for_eval "$arg" - arg=$func_quote_for_eval_result - ;; - esac # arg - - # Now actually substitute the argument into the commands. - if test -n "$arg"; then - func_append compile_command " $arg" - func_append finalize_command " $arg" - fi - done # argument parsing loop - - test -n "$prev" && \ - func_fatal_help "the '$prevarg' option requires an argument" - - if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then - eval arg=\"$export_dynamic_flag_spec\" - func_append compile_command " $arg" - func_append finalize_command " $arg" - fi - - oldlibs= - # calculate the name of the file, without its directory - func_basename "$output" - outputname=$func_basename_result - libobjs_save=$libobjs - - if test -n "$shlibpath_var"; then - # get the directories listed in $shlibpath_var - eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` - else - shlib_search_path= - fi - eval sys_lib_search_path=\"$sys_lib_search_path_spec\" - eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" - - # Definition is injected by LT_CONFIG during libtool generation. - func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH" - - func_dirname "$output" "/" "" - output_objdir=$func_dirname_result$objdir - func_to_tool_file "$output_objdir/" - tool_output_objdir=$func_to_tool_file_result - # Create the object directory. - func_mkdir_p "$output_objdir" - - # Determine the type of output - case $output in - "") - func_fatal_help "you must specify an output file" - ;; - *.$libext) linkmode=oldlib ;; - *.lo | *.$objext) linkmode=obj ;; - *.la) linkmode=lib ;; - *) linkmode=prog ;; # Anything else should be a program. - esac - - specialdeplibs= - - libs= - # Find all interdependent deplibs by searching for libraries - # that are linked more than once (e.g. -la -lb -la) - for deplib in $deplibs; do - if $opt_preserve_dup_deps; then - case "$libs " in - *" $deplib "*) func_append specialdeplibs " $deplib" ;; - esac - fi - func_append libs " $deplib" - done - - if test lib = "$linkmode"; then - libs="$predeps $libs $compiler_lib_search_path $postdeps" - - # Compute libraries that are listed more than once in $predeps - # $postdeps and mark them as special (i.e., whose duplicates are - # not to be eliminated). - pre_post_deps= - if $opt_duplicate_compiler_generated_deps; then - for pre_post_dep in $predeps $postdeps; do - case "$pre_post_deps " in - *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; - esac - func_append pre_post_deps " $pre_post_dep" - done - fi - pre_post_deps= - fi - - deplibs= - newdependency_libs= - newlib_search_path= - need_relink=no # whether we're linking any uninstalled libtool libraries - notinst_deplibs= # not-installed libtool libraries - notinst_path= # paths that contain not-installed libtool libraries - - case $linkmode in - lib) - passes="conv dlpreopen link" - for file in $dlfiles $dlprefiles; do - case $file in - *.la) ;; - *) - func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" - ;; - esac - done - ;; - prog) - compile_deplibs= - finalize_deplibs= - alldeplibs=false - newdlfiles= - newdlprefiles= - passes="conv scan dlopen dlpreopen link" - ;; - *) passes="conv" - ;; - esac - - for pass in $passes; do - # The preopen pass in lib mode reverses $deplibs; put it back here - # so that -L comes before libs that need it for instance... - if test lib,link = "$linkmode,$pass"; then - ## FIXME: Find the place where the list is rebuilt in the wrong - ## order, and fix it there properly - tmp_deplibs= - for deplib in $deplibs; do - tmp_deplibs="$deplib $tmp_deplibs" - done - deplibs=$tmp_deplibs - fi - - if test lib,link = "$linkmode,$pass" || - test prog,scan = "$linkmode,$pass"; then - libs=$deplibs - deplibs= - fi - if test prog = "$linkmode"; then - case $pass in - dlopen) libs=$dlfiles ;; - dlpreopen) libs=$dlprefiles ;; - link) - libs="$deplibs %DEPLIBS%" - test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" - ;; - esac - fi - if test lib,dlpreopen = "$linkmode,$pass"; then - # Collect and forward deplibs of preopened libtool libs - for lib in $dlprefiles; do - # Ignore non-libtool-libs - dependency_libs= - func_resolve_sysroot "$lib" - case $lib in - *.la) func_source "$func_resolve_sysroot_result" ;; - esac - - # Collect preopened libtool deplibs, except any this library - # has declared as weak libs - for deplib in $dependency_libs; do - func_basename "$deplib" - deplib_base=$func_basename_result - case " $weak_libs " in - *" $deplib_base "*) ;; - *) func_append deplibs " $deplib" ;; - esac - done - done - libs=$dlprefiles - fi - if test dlopen = "$pass"; then - # Collect dlpreopened libraries - save_deplibs=$deplibs - deplibs= - fi - - for deplib in $libs; do - lib= - found=false - case $deplib in - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ - |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) - if test prog,link = "$linkmode,$pass"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - func_append compiler_flags " $deplib" - if test lib = "$linkmode"; then - case "$new_inherited_linker_flags " in - *" $deplib "*) ;; - * ) func_append new_inherited_linker_flags " $deplib" ;; - esac - fi - fi - continue - ;; - -l*) - if test lib != "$linkmode" && test prog != "$linkmode"; then - func_warning "'-l' is ignored for archives/objects" - continue - fi - func_stripname '-l' '' "$deplib" - name=$func_stripname_result - if test lib = "$linkmode"; then - searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" - else - searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" - fi - for searchdir in $searchdirs; do - for search_ext in .la $std_shrext .so .a; do - # Search the libtool library - lib=$searchdir/lib$name$search_ext - if test -f "$lib"; then - if test .la = "$search_ext"; then - found=: - else - found=false - fi - break 2 - fi - done - done - if $found; then - # deplib is a libtool library - # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, - # We need to do some special things here, and not later. - if test yes = "$allow_libtool_libs_with_static_runtimes"; then - case " $predeps $postdeps " in - *" $deplib "*) - if func_lalib_p "$lib"; then - library_names= - old_library= - func_source "$lib" - for l in $old_library $library_names; do - ll=$l - done - if test "X$ll" = "X$old_library"; then # only static version available - found=false - func_dirname "$lib" "" "." - ladir=$func_dirname_result - lib=$ladir/$old_library - if test prog,link = "$linkmode,$pass"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" - fi - continue - fi - fi - ;; - *) ;; - esac - fi - else - # deplib doesn't seem to be a libtool library - if test prog,link = "$linkmode,$pass"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" - fi - continue - fi - ;; # -l - *.ltframework) - if test prog,link = "$linkmode,$pass"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - if test lib = "$linkmode"; then - case "$new_inherited_linker_flags " in - *" $deplib "*) ;; - * ) func_append new_inherited_linker_flags " $deplib" ;; - esac - fi - fi - continue - ;; - -L*) - case $linkmode in - lib) - deplibs="$deplib $deplibs" - test conv = "$pass" && continue - newdependency_libs="$deplib $newdependency_libs" - func_stripname '-L' '' "$deplib" - func_resolve_sysroot "$func_stripname_result" - func_append newlib_search_path " $func_resolve_sysroot_result" - ;; - prog) - if test conv = "$pass"; then - deplibs="$deplib $deplibs" - continue - fi - if test scan = "$pass"; then - deplibs="$deplib $deplibs" - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - func_stripname '-L' '' "$deplib" - func_resolve_sysroot "$func_stripname_result" - func_append newlib_search_path " $func_resolve_sysroot_result" - ;; - *) - func_warning "'-L' is ignored for archives/objects" - ;; - esac # linkmode - continue - ;; # -L - -R*) - if test link = "$pass"; then - func_stripname '-R' '' "$deplib" - func_resolve_sysroot "$func_stripname_result" - dir=$func_resolve_sysroot_result - # Make sure the xrpath contains only unique directories. - case "$xrpath " in - *" $dir "*) ;; - *) func_append xrpath " $dir" ;; - esac - fi - deplibs="$deplib $deplibs" - continue - ;; - *.la) - func_resolve_sysroot "$deplib" - lib=$func_resolve_sysroot_result - ;; - *.$libext) - if test conv = "$pass"; then - deplibs="$deplib $deplibs" - continue - fi - case $linkmode in - lib) - # Linking convenience modules into shared libraries is allowed, - # but linking other static libraries is non-portable. - case " $dlpreconveniencelibs " in - *" $deplib "*) ;; - *) - valid_a_lib=false - case $deplibs_check_method in - match_pattern*) - set dummy $deplibs_check_method; shift - match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` - if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ - | $EGREP "$match_pattern_regex" > /dev/null; then - valid_a_lib=: - fi - ;; - pass_all) - valid_a_lib=: - ;; - esac - if $valid_a_lib; then - echo - $ECHO "*** Warning: Linking the shared library $output against the" - $ECHO "*** static library $deplib is not portable!" - deplibs="$deplib $deplibs" - else - echo - $ECHO "*** Warning: Trying to link with static lib archive $deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have" - echo "*** because the file extensions .$libext of this argument makes me believe" - echo "*** that it is just a static archive that I should not use here." - fi - ;; - esac - continue - ;; - prog) - if test link != "$pass"; then - deplibs="$deplib $deplibs" - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - continue - ;; - esac # linkmode - ;; # *.$libext - *.lo | *.$objext) - if test conv = "$pass"; then - deplibs="$deplib $deplibs" - elif test prog = "$linkmode"; then - if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then - # If there is no dlopen support or we're linking statically, - # we need to preload. - func_append newdlprefiles " $deplib" - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - func_append newdlfiles " $deplib" - fi - fi - continue - ;; - %DEPLIBS%) - alldeplibs=: - continue - ;; - esac # case $deplib - - $found || test -f "$lib" \ - || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" - - # Check to see that this really is a libtool archive. - func_lalib_unsafe_p "$lib" \ - || func_fatal_error "'$lib' is not a valid libtool archive" - - func_dirname "$lib" "" "." - ladir=$func_dirname_result - - dlname= - dlopen= - dlpreopen= - libdir= - library_names= - old_library= - inherited_linker_flags= - # If the library was installed with an old release of libtool, - # it will not redefine variables installed, or shouldnotlink - installed=yes - shouldnotlink=no - avoidtemprpath= - - - # Read the .la file - func_source "$lib" - - # Convert "-framework foo" to "foo.ltframework" - if test -n "$inherited_linker_flags"; then - tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` - for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do - case " $new_inherited_linker_flags " in - *" $tmp_inherited_linker_flag "*) ;; - *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; - esac - done - fi - dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - if test lib,link = "$linkmode,$pass" || - test prog,scan = "$linkmode,$pass" || - { test prog != "$linkmode" && test lib != "$linkmode"; }; then - test -n "$dlopen" && func_append dlfiles " $dlopen" - test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" - fi - - if test conv = "$pass"; then - # Only check for convenience libraries - deplibs="$lib $deplibs" - if test -z "$libdir"; then - if test -z "$old_library"; then - func_fatal_error "cannot find name of link library for '$lib'" - fi - # It is a libtool convenience library, so add in its objects. - func_append convenience " $ladir/$objdir/$old_library" - func_append old_convenience " $ladir/$objdir/$old_library" - tmp_libs= - for deplib in $dependency_libs; do - deplibs="$deplib $deplibs" - if $opt_preserve_dup_deps; then - case "$tmp_libs " in - *" $deplib "*) func_append specialdeplibs " $deplib" ;; - esac - fi - func_append tmp_libs " $deplib" - done - elif test prog != "$linkmode" && test lib != "$linkmode"; then - func_fatal_error "'$lib' is not a convenience library" - fi - continue - fi # $pass = conv - - - # Get the name of the library we link against. - linklib= - if test -n "$old_library" && - { test yes = "$prefer_static_libs" || - test built,no = "$prefer_static_libs,$installed"; }; then - linklib=$old_library - else - for l in $old_library $library_names; do - linklib=$l - done - fi - if test -z "$linklib"; then - func_fatal_error "cannot find name of link library for '$lib'" - fi - - # This library was specified with -dlopen. - if test dlopen = "$pass"; then - test -z "$libdir" \ - && func_fatal_error "cannot -dlopen a convenience library: '$lib'" - if test -z "$dlname" || - test yes != "$dlopen_support" || - test no = "$build_libtool_libs" - then - # If there is no dlname, no dlopen support or we're linking - # statically, we need to preload. We also need to preload any - # dependent libraries so libltdl's deplib preloader doesn't - # bomb out in the load deplibs phase. - func_append dlprefiles " $lib $dependency_libs" - else - func_append newdlfiles " $lib" - fi - continue - fi # $pass = dlopen - - # We need an absolute path. - case $ladir in - [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; - *) - abs_ladir=`cd "$ladir" && pwd` - if test -z "$abs_ladir"; then - func_warning "cannot determine absolute directory name of '$ladir'" - func_warning "passing it literally to the linker, although it might fail" - abs_ladir=$ladir - fi - ;; - esac - func_basename "$lib" - laname=$func_basename_result - - # Find the relevant object directory and library name. - if test yes = "$installed"; then - if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then - func_warning "library '$lib' was moved." - dir=$ladir - absdir=$abs_ladir - libdir=$abs_ladir - else - dir=$lt_sysroot$libdir - absdir=$lt_sysroot$libdir - fi - test yes = "$hardcode_automatic" && avoidtemprpath=yes - else - if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then - dir=$ladir - absdir=$abs_ladir - # Remove this search path later - func_append notinst_path " $abs_ladir" - else - dir=$ladir/$objdir - absdir=$abs_ladir/$objdir - # Remove this search path later - func_append notinst_path " $abs_ladir" - fi - fi # $installed = yes - func_stripname 'lib' '.la' "$laname" - name=$func_stripname_result - - # This library was specified with -dlpreopen. - if test dlpreopen = "$pass"; then - if test -z "$libdir" && test prog = "$linkmode"; then - func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" - fi - case $host in - # special handling for platforms with PE-DLLs. - *cygwin* | *mingw* | *cegcc* ) - # Linker will automatically link against shared library if both - # static and shared are present. Therefore, ensure we extract - # symbols from the import library if a shared library is present - # (otherwise, the dlopen module name will be incorrect). We do - # this by putting the import library name into $newdlprefiles. - # We recover the dlopen module name by 'saving' the la file - # name in a special purpose variable, and (later) extracting the - # dlname from the la file. - if test -n "$dlname"; then - func_tr_sh "$dir/$linklib" - eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" - func_append newdlprefiles " $dir/$linklib" - else - func_append newdlprefiles " $dir/$old_library" - # Keep a list of preopened convenience libraries to check - # that they are being used correctly in the link pass. - test -z "$libdir" && \ - func_append dlpreconveniencelibs " $dir/$old_library" - fi - ;; - * ) - # Prefer using a static library (so that no silly _DYNAMIC symbols - # are required to link). - if test -n "$old_library"; then - func_append newdlprefiles " $dir/$old_library" - # Keep a list of preopened convenience libraries to check - # that they are being used correctly in the link pass. - test -z "$libdir" && \ - func_append dlpreconveniencelibs " $dir/$old_library" - # Otherwise, use the dlname, so that lt_dlopen finds it. - elif test -n "$dlname"; then - func_append newdlprefiles " $dir/$dlname" - else - func_append newdlprefiles " $dir/$linklib" - fi - ;; - esac - fi # $pass = dlpreopen - - if test -z "$libdir"; then - # Link the convenience library - if test lib = "$linkmode"; then - deplibs="$dir/$old_library $deplibs" - elif test prog,link = "$linkmode,$pass"; then - compile_deplibs="$dir/$old_library $compile_deplibs" - finalize_deplibs="$dir/$old_library $finalize_deplibs" - else - deplibs="$lib $deplibs" # used for prog,scan pass - fi - continue - fi - - - if test prog = "$linkmode" && test link != "$pass"; then - func_append newlib_search_path " $ladir" - deplibs="$lib $deplibs" - - linkalldeplibs=false - if test no != "$link_all_deplibs" || test -z "$library_names" || - test no = "$build_libtool_libs"; then - linkalldeplibs=: - fi - - tmp_libs= - for deplib in $dependency_libs; do - case $deplib in - -L*) func_stripname '-L' '' "$deplib" - func_resolve_sysroot "$func_stripname_result" - func_append newlib_search_path " $func_resolve_sysroot_result" - ;; - esac - # Need to link against all dependency_libs? - if $linkalldeplibs; then - deplibs="$deplib $deplibs" - else - # Need to hardcode shared library paths - # or/and link against static libraries - newdependency_libs="$deplib $newdependency_libs" - fi - if $opt_preserve_dup_deps; then - case "$tmp_libs " in - *" $deplib "*) func_append specialdeplibs " $deplib" ;; - esac - fi - func_append tmp_libs " $deplib" - done # for deplib - continue - fi # $linkmode = prog... - - if test prog,link = "$linkmode,$pass"; then - if test -n "$library_names" && - { { test no = "$prefer_static_libs" || - test built,yes = "$prefer_static_libs,$installed"; } || - test -z "$old_library"; }; then - # We need to hardcode the library path - if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then - # Make sure the rpath contains only unique directories. - case $temp_rpath: in - *"$absdir:"*) ;; - *) func_append temp_rpath "$absdir:" ;; - esac - fi - - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) func_append compile_rpath " $absdir" ;; - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) func_append finalize_rpath " $libdir" ;; - esac - ;; - esac - fi # $linkmode,$pass = prog,link... - - if $alldeplibs && - { test pass_all = "$deplibs_check_method" || - { test yes = "$build_libtool_libs" && - test -n "$library_names"; }; }; then - # We only need to search for static libraries - continue - fi - fi - - link_static=no # Whether the deplib will be linked statically - use_static_libs=$prefer_static_libs - if test built = "$use_static_libs" && test yes = "$installed"; then - use_static_libs=no - fi - if test -n "$library_names" && - { test no = "$use_static_libs" || test -z "$old_library"; }; then - case $host in - *cygwin* | *mingw* | *cegcc* | *os2*) - # No point in relinking DLLs because paths are not encoded - func_append notinst_deplibs " $lib" - need_relink=no - ;; - *) - if test no = "$installed"; then - func_append notinst_deplibs " $lib" - need_relink=yes - fi - ;; - esac - # This is a shared library - - # Warn about portability, can't link against -module's on some - # systems (darwin). Don't bleat about dlopened modules though! - dlopenmodule= - for dlpremoduletest in $dlprefiles; do - if test "X$dlpremoduletest" = "X$lib"; then - dlopenmodule=$dlpremoduletest - break - fi - done - if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then - echo - if test prog = "$linkmode"; then - $ECHO "*** Warning: Linking the executable $output against the loadable module" - else - $ECHO "*** Warning: Linking the shared library $output against the loadable module" - fi - $ECHO "*** $linklib is not portable!" - fi - if test lib = "$linkmode" && - test yes = "$hardcode_into_libs"; then - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) func_append compile_rpath " $absdir" ;; - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) func_append finalize_rpath " $libdir" ;; - esac - ;; - esac - fi - - if test -n "$old_archive_from_expsyms_cmds"; then - # figure out the soname - set dummy $library_names - shift - realname=$1 - shift - libname=`eval "\\$ECHO \"$libname_spec\""` - # use dlname if we got it. it's perfectly good, no? - if test -n "$dlname"; then - soname=$dlname - elif test -n "$soname_spec"; then - # bleh windows - case $host in - *cygwin* | mingw* | *cegcc* | *os2*) - func_arith $current - $age - major=$func_arith_result - versuffix=-$major - ;; - esac - eval soname=\"$soname_spec\" - else - soname=$realname - fi - - # Make a new name for the extract_expsyms_cmds to use - soroot=$soname - func_basename "$soroot" - soname=$func_basename_result - func_stripname 'lib' '.dll' "$soname" - newlib=libimp-$func_stripname_result.a - - # If the library has no export list, then create one now - if test -f "$output_objdir/$soname-def"; then : - else - func_verbose "extracting exported symbol list from '$soname'" - func_execute_cmds "$extract_expsyms_cmds" 'exit $?' - fi - - # Create $newlib - if test -f "$output_objdir/$newlib"; then :; else - func_verbose "generating import library for '$soname'" - func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' - fi - # make sure the library variables are pointing to the new library - dir=$output_objdir - linklib=$newlib - fi # test -n "$old_archive_from_expsyms_cmds" - - if test prog = "$linkmode" || test relink != "$opt_mode"; then - add_shlibpath= - add_dir= - add= - lib_linked=yes - case $hardcode_action in - immediate | unsupported) - if test no = "$hardcode_direct"; then - add=$dir/$linklib - case $host in - *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; - *-*-sysv4*uw2*) add_dir=-L$dir ;; - *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ - *-*-unixware7*) add_dir=-L$dir ;; - *-*-darwin* ) - # if the lib is a (non-dlopened) module then we cannot - # link against it, someone is ignoring the earlier warnings - if /usr/bin/file -L $add 2> /dev/null | - $GREP ": [^:]* bundle" >/dev/null; then - if test "X$dlopenmodule" != "X$lib"; then - $ECHO "*** Warning: lib $linklib is a module, not a shared library" - if test -z "$old_library"; then - echo - echo "*** And there doesn't seem to be a static archive available" - echo "*** The link will probably fail, sorry" - else - add=$dir/$old_library - fi - elif test -n "$old_library"; then - add=$dir/$old_library - fi - fi - esac - elif test no = "$hardcode_minus_L"; then - case $host in - *-*-sunos*) add_shlibpath=$dir ;; - esac - add_dir=-L$dir - add=-l$name - elif test no = "$hardcode_shlibpath_var"; then - add_shlibpath=$dir - add=-l$name - else - lib_linked=no - fi - ;; - relink) - if test yes = "$hardcode_direct" && - test no = "$hardcode_direct_absolute"; then - add=$dir/$linklib - elif test yes = "$hardcode_minus_L"; then - add_dir=-L$absdir - # Try looking first in the location we're being installed to. - if test -n "$inst_prefix_dir"; then - case $libdir in - [\\/]*) - func_append add_dir " -L$inst_prefix_dir$libdir" - ;; - esac - fi - add=-l$name - elif test yes = "$hardcode_shlibpath_var"; then - add_shlibpath=$dir - add=-l$name - else - lib_linked=no - fi - ;; - *) lib_linked=no ;; - esac - - if test yes != "$lib_linked"; then - func_fatal_configuration "unsupported hardcode properties" - fi - - if test -n "$add_shlibpath"; then - case :$compile_shlibpath: in - *":$add_shlibpath:"*) ;; - *) func_append compile_shlibpath "$add_shlibpath:" ;; - esac - fi - if test prog = "$linkmode"; then - test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" - test -n "$add" && compile_deplibs="$add $compile_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - if test yes != "$hardcode_direct" && - test yes != "$hardcode_minus_L" && - test yes = "$hardcode_shlibpath_var"; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) func_append finalize_shlibpath "$libdir:" ;; - esac - fi - fi - fi - - if test prog = "$linkmode" || test relink = "$opt_mode"; then - add_shlibpath= - add_dir= - add= - # Finalize command for both is simple: just hardcode it. - if test yes = "$hardcode_direct" && - test no = "$hardcode_direct_absolute"; then - add=$libdir/$linklib - elif test yes = "$hardcode_minus_L"; then - add_dir=-L$libdir - add=-l$name - elif test yes = "$hardcode_shlibpath_var"; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) func_append finalize_shlibpath "$libdir:" ;; - esac - add=-l$name - elif test yes = "$hardcode_automatic"; then - if test -n "$inst_prefix_dir" && - test -f "$inst_prefix_dir$libdir/$linklib"; then - add=$inst_prefix_dir$libdir/$linklib - else - add=$libdir/$linklib - fi - else - # We cannot seem to hardcode it, guess we'll fake it. - add_dir=-L$libdir - # Try looking first in the location we're being installed to. - if test -n "$inst_prefix_dir"; then - case $libdir in - [\\/]*) - func_append add_dir " -L$inst_prefix_dir$libdir" - ;; - esac - fi - add=-l$name - fi - - if test prog = "$linkmode"; then - test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" - test -n "$add" && finalize_deplibs="$add $finalize_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - fi - fi - elif test prog = "$linkmode"; then - # Here we assume that one of hardcode_direct or hardcode_minus_L - # is not unsupported. This is valid on all known static and - # shared platforms. - if test unsupported != "$hardcode_direct"; then - test -n "$old_library" && linklib=$old_library - compile_deplibs="$dir/$linklib $compile_deplibs" - finalize_deplibs="$dir/$linklib $finalize_deplibs" - else - compile_deplibs="-l$name -L$dir $compile_deplibs" - finalize_deplibs="-l$name -L$dir $finalize_deplibs" - fi - elif test yes = "$build_libtool_libs"; then - # Not a shared library - if test pass_all != "$deplibs_check_method"; then - # We're trying link a shared library against a static one - # but the system doesn't support it. - - # Just print a warning and add the library to dependency_libs so - # that the program can be linked against the static library. - echo - $ECHO "*** Warning: This system cannot link to static lib archive $lib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have." - if test yes = "$module"; then - echo "*** But as you try to build a module library, libtool will still create " - echo "*** a static module, that should work as long as the dlopening application" - echo "*** is linked with the -dlopen flag to resolve symbols at runtime." - if test -z "$global_symbol_pipe"; then - echo - echo "*** However, this would only work if libtool was able to extract symbol" - echo "*** lists from a program, using 'nm' or equivalent, but libtool could" - echo "*** not find such a program. So, this module is probably useless." - echo "*** 'nm' from GNU binutils and a full rebuild may help." - fi - if test no = "$build_old_libs"; then - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - else - deplibs="$dir/$old_library $deplibs" - link_static=yes - fi - fi # link shared/static library? - - if test lib = "$linkmode"; then - if test -n "$dependency_libs" && - { test yes != "$hardcode_into_libs" || - test yes = "$build_old_libs" || - test yes = "$link_static"; }; then - # Extract -R from dependency_libs - temp_deplibs= - for libdir in $dependency_libs; do - case $libdir in - -R*) func_stripname '-R' '' "$libdir" - temp_xrpath=$func_stripname_result - case " $xrpath " in - *" $temp_xrpath "*) ;; - *) func_append xrpath " $temp_xrpath";; - esac;; - *) func_append temp_deplibs " $libdir";; - esac - done - dependency_libs=$temp_deplibs - fi - - func_append newlib_search_path " $absdir" - # Link against this library - test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" - # ... and its dependency_libs - tmp_libs= - for deplib in $dependency_libs; do - newdependency_libs="$deplib $newdependency_libs" - case $deplib in - -L*) func_stripname '-L' '' "$deplib" - func_resolve_sysroot "$func_stripname_result";; - *) func_resolve_sysroot "$deplib" ;; - esac - if $opt_preserve_dup_deps; then - case "$tmp_libs " in - *" $func_resolve_sysroot_result "*) - func_append specialdeplibs " $func_resolve_sysroot_result" ;; - esac - fi - func_append tmp_libs " $func_resolve_sysroot_result" - done - - if test no != "$link_all_deplibs"; then - # Add the search paths of all dependency libraries - for deplib in $dependency_libs; do - path= - case $deplib in - -L*) path=$deplib ;; - *.la) - func_resolve_sysroot "$deplib" - deplib=$func_resolve_sysroot_result - func_dirname "$deplib" "" "." - dir=$func_dirname_result - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; - *) - absdir=`cd "$dir" && pwd` - if test -z "$absdir"; then - func_warning "cannot determine absolute directory name of '$dir'" - absdir=$dir - fi - ;; - esac - if $GREP "^installed=no" $deplib > /dev/null; then - case $host in - *-*-darwin*) - depdepl= - eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` - if test -n "$deplibrary_names"; then - for tmp in $deplibrary_names; do - depdepl=$tmp - done - if test -f "$absdir/$objdir/$depdepl"; then - depdepl=$absdir/$objdir/$depdepl - darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` - if test -z "$darwin_install_name"; then - darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` - fi - func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" - func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" - path= - fi - fi - ;; - *) - path=-L$absdir/$objdir - ;; - esac - else - eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` - test -z "$libdir" && \ - func_fatal_error "'$deplib' is not a valid libtool archive" - test "$absdir" != "$libdir" && \ - func_warning "'$deplib' seems to be moved" - - path=-L$absdir - fi - ;; - esac - case " $deplibs " in - *" $path "*) ;; - *) deplibs="$path $deplibs" ;; - esac - done - fi # link_all_deplibs != no - fi # linkmode = lib - done # for deplib in $libs - if test link = "$pass"; then - if test prog = "$linkmode"; then - compile_deplibs="$new_inherited_linker_flags $compile_deplibs" - finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" - else - compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - fi - fi - dependency_libs=$newdependency_libs - if test dlpreopen = "$pass"; then - # Link the dlpreopened libraries before other libraries - for deplib in $save_deplibs; do - deplibs="$deplib $deplibs" - done - fi - if test dlopen != "$pass"; then - test conv = "$pass" || { - # Make sure lib_search_path contains only unique directories. - lib_search_path= - for dir in $newlib_search_path; do - case "$lib_search_path " in - *" $dir "*) ;; - *) func_append lib_search_path " $dir" ;; - esac - done - newlib_search_path= - } - - if test prog,link = "$linkmode,$pass"; then - vars="compile_deplibs finalize_deplibs" - else - vars=deplibs - fi - for var in $vars dependency_libs; do - # Add libraries to $var in reverse order - eval tmp_libs=\"\$$var\" - new_libs= - for deplib in $tmp_libs; do - # FIXME: Pedantically, this is the right thing to do, so - # that some nasty dependency loop isn't accidentally - # broken: - #new_libs="$deplib $new_libs" - # Pragmatically, this seems to cause very few problems in - # practice: - case $deplib in - -L*) new_libs="$deplib $new_libs" ;; - -R*) ;; - *) - # And here is the reason: when a library appears more - # than once as an explicit dependence of a library, or - # is implicitly linked in more than once by the - # compiler, it is considered special, and multiple - # occurrences thereof are not removed. Compare this - # with having the same library being listed as a - # dependency of multiple other libraries: in this case, - # we know (pedantically, we assume) the library does not - # need to be listed more than once, so we keep only the - # last copy. This is not always right, but it is rare - # enough that we require users that really mean to play - # such unportable linking tricks to link the library - # using -Wl,-lname, so that libtool does not consider it - # for duplicate removal. - case " $specialdeplibs " in - *" $deplib "*) new_libs="$deplib $new_libs" ;; - *) - case " $new_libs " in - *" $deplib "*) ;; - *) new_libs="$deplib $new_libs" ;; - esac - ;; - esac - ;; - esac - done - tmp_libs= - for deplib in $new_libs; do - case $deplib in - -L*) - case " $tmp_libs " in - *" $deplib "*) ;; - *) func_append tmp_libs " $deplib" ;; - esac - ;; - *) func_append tmp_libs " $deplib" ;; - esac - done - eval $var=\"$tmp_libs\" - done # for var - fi - - # Add Sun CC postdeps if required: - test CXX = "$tagname" && { - case $host_os in - linux*) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) # Sun C++ 5.9 - func_suncc_cstd_abi - - if test no != "$suncc_use_cstd_abi"; then - func_append postdeps ' -library=Cstd -library=Crun' - fi - ;; - esac - ;; - - solaris*) - func_cc_basename "$CC" - case $func_cc_basename_result in - CC* | sunCC*) - func_suncc_cstd_abi - - if test no != "$suncc_use_cstd_abi"; then - func_append postdeps ' -library=Cstd -library=Crun' - fi - ;; - esac - ;; - esac - } - - # Last step: remove runtime libs from dependency_libs - # (they stay in deplibs) - tmp_libs= - for i in $dependency_libs; do - case " $predeps $postdeps $compiler_lib_search_path " in - *" $i "*) - i= - ;; - esac - if test -n "$i"; then - func_append tmp_libs " $i" - fi - done - dependency_libs=$tmp_libs - done # for pass - if test prog = "$linkmode"; then - dlfiles=$newdlfiles - fi - if test prog = "$linkmode" || test lib = "$linkmode"; then - dlprefiles=$newdlprefiles - fi - - case $linkmode in - oldlib) - if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then - func_warning "'-dlopen' is ignored for archives" - fi - - case " $deplibs" in - *\ -l* | *\ -L*) - func_warning "'-l' and '-L' are ignored for archives" ;; - esac - - test -n "$rpath" && \ - func_warning "'-rpath' is ignored for archives" - - test -n "$xrpath" && \ - func_warning "'-R' is ignored for archives" - - test -n "$vinfo" && \ - func_warning "'-version-info/-version-number' is ignored for archives" - - test -n "$release" && \ - func_warning "'-release' is ignored for archives" - - test -n "$export_symbols$export_symbols_regex" && \ - func_warning "'-export-symbols' is ignored for archives" - - # Now set the variables for building old libraries. - build_libtool_libs=no - oldlibs=$output - func_append objs "$old_deplibs" - ;; - - lib) - # Make sure we only generate libraries of the form 'libNAME.la'. - case $outputname in - lib*) - func_stripname 'lib' '.la' "$outputname" - name=$func_stripname_result - eval shared_ext=\"$shrext_cmds\" - eval libname=\"$libname_spec\" - ;; - *) - test no = "$module" \ - && func_fatal_help "libtool library '$output' must begin with 'lib'" - - if test no != "$need_lib_prefix"; then - # Add the "lib" prefix for modules if required - func_stripname '' '.la' "$outputname" - name=$func_stripname_result - eval shared_ext=\"$shrext_cmds\" - eval libname=\"$libname_spec\" - else - func_stripname '' '.la' "$outputname" - libname=$func_stripname_result - fi - ;; - esac - - if test -n "$objs"; then - if test pass_all != "$deplibs_check_method"; then - func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" - else - echo - $ECHO "*** Warning: Linking the shared library $output against the non-libtool" - $ECHO "*** objects $objs is not portable!" - func_append libobjs " $objs" - fi - fi - - test no = "$dlself" \ - || func_warning "'-dlopen self' is ignored for libtool libraries" - - set dummy $rpath - shift - test 1 -lt "$#" \ - && func_warning "ignoring multiple '-rpath's for a libtool library" - - install_libdir=$1 - - oldlibs= - if test -z "$rpath"; then - if test yes = "$build_libtool_libs"; then - # Building a libtool convenience library. - # Some compilers have problems with a '.al' extension so - # convenience libraries should have the same extension an - # archive normally would. - oldlibs="$output_objdir/$libname.$libext $oldlibs" - build_libtool_libs=convenience - build_old_libs=yes - fi - - test -n "$vinfo" && \ - func_warning "'-version-info/-version-number' is ignored for convenience libraries" - - test -n "$release" && \ - func_warning "'-release' is ignored for convenience libraries" - else - - # Parse the version information argument. - save_ifs=$IFS; IFS=: - set dummy $vinfo 0 0 0 - shift - IFS=$save_ifs - - test -n "$7" && \ - func_fatal_help "too many parameters to '-version-info'" - - # convert absolute version numbers to libtool ages - # this retains compatibility with .la files and attempts - # to make the code below a bit more comprehensible - - case $vinfo_number in - yes) - number_major=$1 - number_minor=$2 - number_revision=$3 - # - # There are really only two kinds -- those that - # use the current revision as the major version - # and those that subtract age and use age as - # a minor version. But, then there is irix - # that has an extra 1 added just for fun - # - case $version_type in - # correct linux to gnu/linux during the next big refactor - darwin|freebsd-elf|linux|osf|windows|none) - func_arith $number_major + $number_minor - current=$func_arith_result - age=$number_minor - revision=$number_revision - ;; - freebsd-aout|qnx|sunos) - current=$number_major - revision=$number_minor - age=0 - ;; - irix|nonstopux) - func_arith $number_major + $number_minor - current=$func_arith_result - age=$number_minor - revision=$number_minor - lt_irix_increment=no - ;; - *) - func_fatal_configuration "$modename: unknown library version type '$version_type'" - ;; - esac - ;; - no) - current=$1 - revision=$2 - age=$3 - ;; - esac - - # Check that each of the things are valid numbers. - case $current in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - func_error "CURRENT '$current' must be a nonnegative integer" - func_fatal_error "'$vinfo' is not valid version information" - ;; - esac - - case $revision in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - func_error "REVISION '$revision' must be a nonnegative integer" - func_fatal_error "'$vinfo' is not valid version information" - ;; - esac - - case $age in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - func_error "AGE '$age' must be a nonnegative integer" - func_fatal_error "'$vinfo' is not valid version information" - ;; - esac - - if test "$age" -gt "$current"; then - func_error "AGE '$age' is greater than the current interface number '$current'" - func_fatal_error "'$vinfo' is not valid version information" - fi - - # Calculate the version variables. - major= - versuffix= - verstring= - case $version_type in - none) ;; - - darwin) - # Like Linux, but with the current version available in - # verstring for coding it into the library header - func_arith $current - $age - major=.$func_arith_result - versuffix=$major.$age.$revision - # Darwin ld doesn't like 0 for these options... - func_arith $current + 1 - minor_current=$func_arith_result - xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" - verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" - # On Darwin other compilers - case $CC in - nagfor*) - verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" - ;; - *) - verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" - ;; - esac - ;; - - freebsd-aout) - major=.$current - versuffix=.$current.$revision - ;; - - freebsd-elf) - func_arith $current - $age - major=.$func_arith_result - versuffix=$major.$age.$revision - ;; - - irix | nonstopux) - if test no = "$lt_irix_increment"; then - func_arith $current - $age - else - func_arith $current - $age + 1 - fi - major=$func_arith_result - - case $version_type in - nonstopux) verstring_prefix=nonstopux ;; - *) verstring_prefix=sgi ;; - esac - verstring=$verstring_prefix$major.$revision - - # Add in all the interfaces that we are compatible with. - loop=$revision - while test 0 -ne "$loop"; do - func_arith $revision - $loop - iface=$func_arith_result - func_arith $loop - 1 - loop=$func_arith_result - verstring=$verstring_prefix$major.$iface:$verstring - done - - # Before this point, $major must not contain '.'. - major=.$major - versuffix=$major.$revision - ;; - - linux) # correct to gnu/linux during the next big refactor - func_arith $current - $age - major=.$func_arith_result - versuffix=$major.$age.$revision - ;; - - osf) - func_arith $current - $age - major=.$func_arith_result - versuffix=.$current.$age.$revision - verstring=$current.$age.$revision - - # Add in all the interfaces that we are compatible with. - loop=$age - while test 0 -ne "$loop"; do - func_arith $current - $loop - iface=$func_arith_result - func_arith $loop - 1 - loop=$func_arith_result - verstring=$verstring:$iface.0 - done - - # Make executables depend on our current version. - func_append verstring ":$current.0" - ;; - - qnx) - major=.$current - versuffix=.$current - ;; - - sco) - major=.$current - versuffix=.$current - ;; - - sunos) - major=.$current - versuffix=.$current.$revision - ;; - - windows) - # Use '-' rather than '.', since we only want one - # extension on DOS 8.3 file systems. - func_arith $current - $age - major=$func_arith_result - versuffix=-$major - ;; - - *) - func_fatal_configuration "unknown library version type '$version_type'" - ;; - esac - - # Clear the version info if we defaulted, and they specified a release. - if test -z "$vinfo" && test -n "$release"; then - major= - case $version_type in - darwin) - # we can't check for "0.0" in archive_cmds due to quoting - # problems, so we reset it completely - verstring= - ;; - *) - verstring=0.0 - ;; - esac - if test no = "$need_version"; then - versuffix= - else - versuffix=.0.0 - fi - fi - - # Remove version info from name if versioning should be avoided - if test yes,no = "$avoid_version,$need_version"; then - major= - versuffix= - verstring= - fi - - # Check to see if the archive will have undefined symbols. - if test yes = "$allow_undefined"; then - if test unsupported = "$allow_undefined_flag"; then - if test yes = "$build_old_libs"; then - func_warning "undefined symbols not allowed in $host shared libraries; building static only" - build_libtool_libs=no - else - func_fatal_error "can't build $host shared library unless -no-undefined is specified" - fi - fi - else - # Don't allow undefined symbols. - allow_undefined_flag=$no_undefined_flag - fi - - fi - - func_generate_dlsyms "$libname" "$libname" : - func_append libobjs " $symfileobj" - test " " = "$libobjs" && libobjs= - - if test relink != "$opt_mode"; then - # Remove our outputs, but don't remove object files since they - # may have been created when compiling PIC objects. - removelist= - tempremovelist=`$ECHO "$output_objdir/*"` - for p in $tempremovelist; do - case $p in - *.$objext | *.gcno) - ;; - $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) - if test -n "$precious_files_regex"; then - if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 - then - continue - fi - fi - func_append removelist " $p" - ;; - *) ;; - esac - done - test -n "$removelist" && \ - func_show_eval "${RM}r \$removelist" - fi - - # Now set the variables for building old libraries. - if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then - func_append oldlibs " $output_objdir/$libname.$libext" - - # Transform .lo files to .o files. - oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` - fi - - # Eliminate all temporary directories. - #for path in $notinst_path; do - # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` - # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` - # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` - #done - - if test -n "$xrpath"; then - # If the user specified any rpath flags, then add them. - temp_xrpath= - for libdir in $xrpath; do - func_replace_sysroot "$libdir" - func_append temp_xrpath " -R$func_replace_sysroot_result" - case "$finalize_rpath " in - *" $libdir "*) ;; - *) func_append finalize_rpath " $libdir" ;; - esac - done - if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then - dependency_libs="$temp_xrpath $dependency_libs" - fi - fi - - # Make sure dlfiles contains only unique files that won't be dlpreopened - old_dlfiles=$dlfiles - dlfiles= - for lib in $old_dlfiles; do - case " $dlprefiles $dlfiles " in - *" $lib "*) ;; - *) func_append dlfiles " $lib" ;; - esac - done - - # Make sure dlprefiles contains only unique files - old_dlprefiles=$dlprefiles - dlprefiles= - for lib in $old_dlprefiles; do - case "$dlprefiles " in - *" $lib "*) ;; - *) func_append dlprefiles " $lib" ;; - esac - done - - if test yes = "$build_libtool_libs"; then - if test -n "$rpath"; then - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) - # these systems don't actually have a c library (as such)! - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C library is in the System framework - func_append deplibs " System.ltframework" - ;; - *-*-netbsd*) - # Don't link with libc until the a.out ld.so is fixed. - ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc due to us having libc/libc_r. - ;; - *-*-sco3.2v5* | *-*-sco5v6*) - # Causes problems with __ctype - ;; - *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) - # Compiler inserts libc in the correct place for threads to work - ;; - *) - # Add libc to deplibs on all other systems if necessary. - if test yes = "$build_libtool_need_lc"; then - func_append deplibs " -lc" - fi - ;; - esac - fi - - # Transform deplibs into only deplibs that can be linked in shared. - name_save=$name - libname_save=$libname - release_save=$release - versuffix_save=$versuffix - major_save=$major - # I'm not sure if I'm treating the release correctly. I think - # release should show up in the -l (ie -lgmp5) so we don't want to - # add it in twice. Is that correct? - release= - versuffix= - major= - newdeplibs= - droppeddeps=no - case $deplibs_check_method in - pass_all) - # Don't check for shared/static. Everything works. - # This might be a little naive. We might want to check - # whether the library exists or not. But this is on - # osf3 & osf4 and I'm not really sure... Just - # implementing what was already the behavior. - newdeplibs=$deplibs - ;; - test_compile) - # This code stresses the "libraries are programs" paradigm to its - # limits. Maybe even breaks it. We compile a program, linking it - # against the deplibs as a proxy for the library. Then we can check - # whether they linked in statically or dynamically with ldd. - $opt_dry_run || $RM conftest.c - cat > conftest.c </dev/null` - $nocaseglob - else - potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` - fi - for potent_lib in $potential_libs; do - # Follow soft links. - if ls -lLd "$potent_lib" 2>/dev/null | - $GREP " -> " >/dev/null; then - continue - fi - # The statement above tries to avoid entering an - # endless loop below, in case of cyclic links. - # We might still enter an endless loop, since a link - # loop can be closed while we follow links, - # but so what? - potlib=$potent_lib - while test -h "$potlib" 2>/dev/null; do - potliblink=`ls -ld $potlib | $SED 's/.* -> //'` - case $potliblink in - [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; - *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; - esac - done - if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | - $SED -e 10q | - $EGREP "$file_magic_regex" > /dev/null; then - func_append newdeplibs " $a_deplib" - a_deplib= - break 2 - fi - done - done - fi - if test -n "$a_deplib"; then - droppeddeps=yes - echo - $ECHO "*** Warning: linker path does not have real file for library $a_deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have" - echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib"; then - $ECHO "*** with $libname but no candidates were found. (...for file magic test)" - else - $ECHO "*** with $libname and none of the candidates passed a file format test" - $ECHO "*** using a file magic. Last file checked: $potlib" - fi - fi - ;; - *) - # Add a -L argument. - func_append newdeplibs " $a_deplib" - ;; - esac - done # Gone through all deplibs. - ;; - match_pattern*) - set dummy $deplibs_check_method; shift - match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` - for a_deplib in $deplibs; do - case $a_deplib in - -l*) - func_stripname -l '' "$a_deplib" - name=$func_stripname_result - if test yes = "$allow_libtool_libs_with_static_runtimes"; then - case " $predeps $postdeps " in - *" $a_deplib "*) - func_append newdeplibs " $a_deplib" - a_deplib= - ;; - esac - fi - if test -n "$a_deplib"; then - libname=`eval "\\$ECHO \"$libname_spec\""` - for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do - potential_libs=`ls $i/$libname[.-]* 2>/dev/null` - for potent_lib in $potential_libs; do - potlib=$potent_lib # see symlink-check above in file_magic test - if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ - $EGREP "$match_pattern_regex" > /dev/null; then - func_append newdeplibs " $a_deplib" - a_deplib= - break 2 - fi - done - done - fi - if test -n "$a_deplib"; then - droppeddeps=yes - echo - $ECHO "*** Warning: linker path does not have real file for library $a_deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have" - echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib"; then - $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" - else - $ECHO "*** with $libname and none of the candidates passed a file format test" - $ECHO "*** using a regex pattern. Last file checked: $potlib" - fi - fi - ;; - *) - # Add a -L argument. - func_append newdeplibs " $a_deplib" - ;; - esac - done # Gone through all deplibs. - ;; - none | unknown | *) - newdeplibs= - tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` - if test yes = "$allow_libtool_libs_with_static_runtimes"; then - for i in $predeps $postdeps; do - # can't use Xsed below, because $i might contain '/' - tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` - done - fi - case $tmp_deplibs in - *[!\ \ ]*) - echo - if test none = "$deplibs_check_method"; then - echo "*** Warning: inter-library dependencies are not supported in this platform." - else - echo "*** Warning: inter-library dependencies are not known to be supported." - fi - echo "*** All declared inter-library dependencies are being dropped." - droppeddeps=yes - ;; - esac - ;; - esac - versuffix=$versuffix_save - major=$major_save - release=$release_save - libname=$libname_save - name=$name_save - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library with the System framework - newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` - ;; - esac - - if test yes = "$droppeddeps"; then - if test yes = "$module"; then - echo - echo "*** Warning: libtool could not satisfy all declared inter-library" - $ECHO "*** dependencies of module $libname. Therefore, libtool will create" - echo "*** a static module, that should work as long as the dlopening" - echo "*** application is linked with the -dlopen flag." - if test -z "$global_symbol_pipe"; then - echo - echo "*** However, this would only work if libtool was able to extract symbol" - echo "*** lists from a program, using 'nm' or equivalent, but libtool could" - echo "*** not find such a program. So, this module is probably useless." - echo "*** 'nm' from GNU binutils and a full rebuild may help." - fi - if test no = "$build_old_libs"; then - oldlibs=$output_objdir/$libname.$libext - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - else - echo "*** The inter-library dependencies that have been dropped here will be" - echo "*** automatically added whenever a program is linked with this library" - echo "*** or is declared to -dlopen it." - - if test no = "$allow_undefined"; then - echo - echo "*** Since this library must not contain undefined symbols," - echo "*** because either the platform does not support them or" - echo "*** it was explicitly requested with -no-undefined," - echo "*** libtool will only create a static version of it." - if test no = "$build_old_libs"; then - oldlibs=$output_objdir/$libname.$libext - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - fi - fi - # Done checking deplibs! - deplibs=$newdeplibs - fi - # Time to change all our "foo.ltframework" stuff back to "-framework foo" - case $host in - *-*-darwin*) - newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - ;; - esac - - # move library search paths that coincide with paths to not yet - # installed libraries to the beginning of the library search list - new_libs= - for path in $notinst_path; do - case " $new_libs " in - *" -L$path/$objdir "*) ;; - *) - case " $deplibs " in - *" -L$path/$objdir "*) - func_append new_libs " -L$path/$objdir" ;; - esac - ;; - esac - done - for deplib in $deplibs; do - case $deplib in - -L*) - case " $new_libs " in - *" $deplib "*) ;; - *) func_append new_libs " $deplib" ;; - esac - ;; - *) func_append new_libs " $deplib" ;; - esac - done - deplibs=$new_libs - - # All the library-specific variables (install_libdir is set above). - library_names= - old_library= - dlname= - - # Test again, we may have decided not to build it any more - if test yes = "$build_libtool_libs"; then - # Remove $wl instances when linking with ld. - # FIXME: should test the right _cmds variable. - case $archive_cmds in - *\$LD\ *) wl= ;; - esac - if test yes = "$hardcode_into_libs"; then - # Hardcode the library paths - hardcode_libdirs= - dep_rpath= - rpath=$finalize_rpath - test relink = "$opt_mode" || rpath=$compile_rpath$rpath - for libdir in $rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - func_replace_sysroot "$libdir" - libdir=$func_replace_sysroot_result - if test -z "$hardcode_libdirs"; then - hardcode_libdirs=$libdir - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - func_append dep_rpath " $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) func_append perm_rpath " $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir=$hardcode_libdirs - eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" - fi - if test -n "$runpath_var" && test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - func_append rpath "$dir:" - done - eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" - fi - test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" - fi - - shlibpath=$finalize_shlibpath - test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath - if test -n "$shlibpath"; then - eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" - fi - - # Get the real and link names of the library. - eval shared_ext=\"$shrext_cmds\" - eval library_names=\"$library_names_spec\" - set dummy $library_names - shift - realname=$1 - shift - - if test -n "$soname_spec"; then - eval soname=\"$soname_spec\" - else - soname=$realname - fi - if test -z "$dlname"; then - dlname=$soname - fi - - lib=$output_objdir/$realname - linknames= - for link - do - func_append linknames " $link" - done - - # Use standard objects if they are pic - test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` - test "X$libobjs" = "X " && libobjs= - - delfiles= - if test -n "$export_symbols" && test -n "$include_expsyms"; then - $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" - export_symbols=$output_objdir/$libname.uexp - func_append delfiles " $export_symbols" - fi - - orig_export_symbols= - case $host_os in - cygwin* | mingw* | cegcc*) - if test -n "$export_symbols" && test -z "$export_symbols_regex"; then - # exporting using user supplied symfile - func_dll_def_p "$export_symbols" || { - # and it's NOT already a .def file. Must figure out - # which of the given symbols are data symbols and tag - # them as such. So, trigger use of export_symbols_cmds. - # export_symbols gets reassigned inside the "prepare - # the list of exported symbols" if statement, so the - # include_expsyms logic still works. - orig_export_symbols=$export_symbols - export_symbols= - always_export_symbols=yes - } - fi - ;; - esac - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then - func_verbose "generating symbol list for '$libname.la'" - export_symbols=$output_objdir/$libname.exp - $opt_dry_run || $RM $export_symbols - cmds=$export_symbols_cmds - save_ifs=$IFS; IFS='~' - for cmd1 in $cmds; do - IFS=$save_ifs - # Take the normal branch if the nm_file_list_spec branch - # doesn't work or if tool conversion is not needed. - case $nm_file_list_spec~$to_tool_file_cmd in - *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) - try_normal_branch=yes - eval cmd=\"$cmd1\" - func_len " $cmd" - len=$func_len_result - ;; - *) - try_normal_branch=no - ;; - esac - if test yes = "$try_normal_branch" \ - && { test "$len" -lt "$max_cmd_len" \ - || test "$max_cmd_len" -le -1; } - then - func_show_eval "$cmd" 'exit $?' - skipped_export=false - elif test -n "$nm_file_list_spec"; then - func_basename "$output" - output_la=$func_basename_result - save_libobjs=$libobjs - save_output=$output - output=$output_objdir/$output_la.nm - func_to_tool_file "$output" - libobjs=$nm_file_list_spec$func_to_tool_file_result - func_append delfiles " $output" - func_verbose "creating $NM input file list: $output" - for obj in $save_libobjs; do - func_to_tool_file "$obj" - $ECHO "$func_to_tool_file_result" - done > "$output" - eval cmd=\"$cmd1\" - func_show_eval "$cmd" 'exit $?' - output=$save_output - libobjs=$save_libobjs - skipped_export=false - else - # The command line is too long to execute in one step. - func_verbose "using reloadable object file for export list..." - skipped_export=: - # Break out early, otherwise skipped_export may be - # set to false by a later but shorter cmd. - break - fi - done - IFS=$save_ifs - if test -n "$export_symbols_regex" && test : != "$skipped_export"; then - func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' - func_show_eval '$MV "${export_symbols}T" "$export_symbols"' - fi - fi - fi - - if test -n "$export_symbols" && test -n "$include_expsyms"; then - tmp_export_symbols=$export_symbols - test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols - $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' - fi - - if test : != "$skipped_export" && test -n "$orig_export_symbols"; then - # The given exports_symbols file has to be filtered, so filter it. - func_verbose "filter symbol list for '$libname.la' to tag DATA exports" - # FIXME: $output_objdir/$libname.filter potentially contains lots of - # 's' commands, which not all seds can handle. GNU sed should be fine - # though. Also, the filter scales superlinearly with the number of - # global variables. join(1) would be nice here, but unfortunately - # isn't a blessed tool. - $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter - func_append delfiles " $export_symbols $output_objdir/$libname.filter" - export_symbols=$output_objdir/$libname.def - $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols - fi - - tmp_deplibs= - for test_deplib in $deplibs; do - case " $convenience " in - *" $test_deplib "*) ;; - *) - func_append tmp_deplibs " $test_deplib" - ;; - esac - done - deplibs=$tmp_deplibs - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec" && - test yes = "$compiler_needs_object" && - test -z "$libobjs"; then - # extract the archives, so we have objects to list. - # TODO: could optimize this to just extract one archive. - whole_archive_flag_spec= - fi - if test -n "$whole_archive_flag_spec"; then - save_libobjs=$libobjs - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - test "X$libobjs" = "X " && libobjs= - else - gentop=$output_objdir/${outputname}x - func_append generated " $gentop" - - func_extract_archives $gentop $convenience - func_append libobjs " $func_extract_archives_result" - test "X$libobjs" = "X " && libobjs= - fi - fi - - if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then - eval flag=\"$thread_safe_flag_spec\" - func_append linker_flags " $flag" - fi - - # Make a backup of the uninstalled library when relinking - if test relink = "$opt_mode"; then - $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? - fi - - # Do each of the archive commands. - if test yes = "$module" && test -n "$module_cmds"; then - if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then - eval test_cmds=\"$module_expsym_cmds\" - cmds=$module_expsym_cmds - else - eval test_cmds=\"$module_cmds\" - cmds=$module_cmds - fi - else - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - eval test_cmds=\"$archive_expsym_cmds\" - cmds=$archive_expsym_cmds - else - eval test_cmds=\"$archive_cmds\" - cmds=$archive_cmds - fi - fi - - if test : != "$skipped_export" && - func_len " $test_cmds" && - len=$func_len_result && - test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then - : - else - # The command line is too long to link in one step, link piecewise - # or, if using GNU ld and skipped_export is not :, use a linker - # script. - - # Save the value of $output and $libobjs because we want to - # use them later. If we have whole_archive_flag_spec, we - # want to use save_libobjs as it was before - # whole_archive_flag_spec was expanded, because we can't - # assume the linker understands whole_archive_flag_spec. - # This may have to be revisited, in case too many - # convenience libraries get linked in and end up exceeding - # the spec. - if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then - save_libobjs=$libobjs - fi - save_output=$output - func_basename "$output" - output_la=$func_basename_result - - # Clear the reloadable object creation command queue and - # initialize k to one. - test_cmds= - concat_cmds= - objlist= - last_robj= - k=1 - - if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then - output=$output_objdir/$output_la.lnkscript - func_verbose "creating GNU ld script: $output" - echo 'INPUT (' > $output - for obj in $save_libobjs - do - func_to_tool_file "$obj" - $ECHO "$func_to_tool_file_result" >> $output - done - echo ')' >> $output - func_append delfiles " $output" - func_to_tool_file "$output" - output=$func_to_tool_file_result - elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then - output=$output_objdir/$output_la.lnk - func_verbose "creating linker input file list: $output" - : > $output - set x $save_libobjs - shift - firstobj= - if test yes = "$compiler_needs_object"; then - firstobj="$1 " - shift - fi - for obj - do - func_to_tool_file "$obj" - $ECHO "$func_to_tool_file_result" >> $output - done - func_append delfiles " $output" - func_to_tool_file "$output" - output=$firstobj\"$file_list_spec$func_to_tool_file_result\" - else - if test -n "$save_libobjs"; then - func_verbose "creating reloadable object files..." - output=$output_objdir/$output_la-$k.$objext - eval test_cmds=\"$reload_cmds\" - func_len " $test_cmds" - len0=$func_len_result - len=$len0 - - # Loop over the list of objects to be linked. - for obj in $save_libobjs - do - func_len " $obj" - func_arith $len + $func_len_result - len=$func_arith_result - if test -z "$objlist" || - test "$len" -lt "$max_cmd_len"; then - func_append objlist " $obj" - else - # The command $test_cmds is almost too long, add a - # command to the queue. - if test 1 -eq "$k"; then - # The first file doesn't have a previous command to add. - reload_objs=$objlist - eval concat_cmds=\"$reload_cmds\" - else - # All subsequent reloadable object files will link in - # the last one created. - reload_objs="$objlist $last_robj" - eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" - fi - last_robj=$output_objdir/$output_la-$k.$objext - func_arith $k + 1 - k=$func_arith_result - output=$output_objdir/$output_la-$k.$objext - objlist=" $obj" - func_len " $last_robj" - func_arith $len0 + $func_len_result - len=$func_arith_result - fi - done - # Handle the remaining objects by creating one last - # reloadable object file. All subsequent reloadable object - # files will link in the last one created. - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - reload_objs="$objlist $last_robj" - eval concat_cmds=\"\$concat_cmds$reload_cmds\" - if test -n "$last_robj"; then - eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" - fi - func_append delfiles " $output" - - else - output= - fi - - ${skipped_export-false} && { - func_verbose "generating symbol list for '$libname.la'" - export_symbols=$output_objdir/$libname.exp - $opt_dry_run || $RM $export_symbols - libobjs=$output - # Append the command to create the export file. - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" - if test -n "$last_robj"; then - eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" - fi - } - - test -n "$save_libobjs" && - func_verbose "creating a temporary reloadable object file: $output" - - # Loop through the commands generated above and execute them. - save_ifs=$IFS; IFS='~' - for cmd in $concat_cmds; do - IFS=$save_ifs - $opt_quiet || { - func_quote_for_expand "$cmd" - eval "func_echo $func_quote_for_expand_result" - } - $opt_dry_run || eval "$cmd" || { - lt_exit=$? - - # Restore the uninstalled library and exit - if test relink = "$opt_mode"; then - ( cd "$output_objdir" && \ - $RM "${realname}T" && \ - $MV "${realname}U" "$realname" ) - fi - - exit $lt_exit - } - done - IFS=$save_ifs - - if test -n "$export_symbols_regex" && ${skipped_export-false}; then - func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' - func_show_eval '$MV "${export_symbols}T" "$export_symbols"' - fi - fi - - ${skipped_export-false} && { - if test -n "$export_symbols" && test -n "$include_expsyms"; then - tmp_export_symbols=$export_symbols - test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols - $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' - fi - - if test -n "$orig_export_symbols"; then - # The given exports_symbols file has to be filtered, so filter it. - func_verbose "filter symbol list for '$libname.la' to tag DATA exports" - # FIXME: $output_objdir/$libname.filter potentially contains lots of - # 's' commands, which not all seds can handle. GNU sed should be fine - # though. Also, the filter scales superlinearly with the number of - # global variables. join(1) would be nice here, but unfortunately - # isn't a blessed tool. - $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter - func_append delfiles " $export_symbols $output_objdir/$libname.filter" - export_symbols=$output_objdir/$libname.def - $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols - fi - } - - libobjs=$output - # Restore the value of output. - output=$save_output - - if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - test "X$libobjs" = "X " && libobjs= - fi - # Expand the library linking commands again to reset the - # value of $libobjs for piecewise linking. - - # Do each of the archive commands. - if test yes = "$module" && test -n "$module_cmds"; then - if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then - cmds=$module_expsym_cmds - else - cmds=$module_cmds - fi - else - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - cmds=$archive_expsym_cmds - else - cmds=$archive_cmds - fi - fi - fi - - if test -n "$delfiles"; then - # Append the command to remove temporary files to $cmds. - eval cmds=\"\$cmds~\$RM $delfiles\" - fi - - # Add any objects from preloaded convenience libraries - if test -n "$dlprefiles"; then - gentop=$output_objdir/${outputname}x - func_append generated " $gentop" - - func_extract_archives $gentop $dlprefiles - func_append libobjs " $func_extract_archives_result" - test "X$libobjs" = "X " && libobjs= - fi - - save_ifs=$IFS; IFS='~' - for cmd in $cmds; do - IFS=$sp$nl - eval cmd=\"$cmd\" - IFS=$save_ifs - $opt_quiet || { - func_quote_for_expand "$cmd" - eval "func_echo $func_quote_for_expand_result" - } - $opt_dry_run || eval "$cmd" || { - lt_exit=$? - - # Restore the uninstalled library and exit - if test relink = "$opt_mode"; then - ( cd "$output_objdir" && \ - $RM "${realname}T" && \ - $MV "${realname}U" "$realname" ) - fi - - exit $lt_exit - } - done - IFS=$save_ifs - - # Restore the uninstalled library and exit - if test relink = "$opt_mode"; then - $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? - - if test -n "$convenience"; then - if test -z "$whole_archive_flag_spec"; then - func_show_eval '${RM}r "$gentop"' - fi - fi - - exit $EXIT_SUCCESS - fi - - # Create links to the real library. - for linkname in $linknames; do - if test "$realname" != "$linkname"; then - func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' - fi - done - - # If -module or -export-dynamic was specified, set the dlname. - if test yes = "$module" || test yes = "$export_dynamic"; then - # On all known operating systems, these are identical. - dlname=$soname - fi - fi - ;; - - obj) - if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then - func_warning "'-dlopen' is ignored for objects" - fi - - case " $deplibs" in - *\ -l* | *\ -L*) - func_warning "'-l' and '-L' are ignored for objects" ;; - esac - - test -n "$rpath" && \ - func_warning "'-rpath' is ignored for objects" - - test -n "$xrpath" && \ - func_warning "'-R' is ignored for objects" - - test -n "$vinfo" && \ - func_warning "'-version-info' is ignored for objects" - - test -n "$release" && \ - func_warning "'-release' is ignored for objects" - - case $output in - *.lo) - test -n "$objs$old_deplibs" && \ - func_fatal_error "cannot build library object '$output' from non-libtool objects" - - libobj=$output - func_lo2o "$libobj" - obj=$func_lo2o_result - ;; - *) - libobj= - obj=$output - ;; - esac - - # Delete the old objects. - $opt_dry_run || $RM $obj $libobj - - # Objects from convenience libraries. This assumes - # single-version convenience libraries. Whenever we create - # different ones for PIC/non-PIC, this we'll have to duplicate - # the extraction. - reload_conv_objs= - gentop= - # if reload_cmds runs $LD directly, get rid of -Wl from - # whole_archive_flag_spec and hope we can get by with turning comma - # into space. - case $reload_cmds in - *\$LD[\ \$]*) wl= ;; - esac - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec"; then - eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" - test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` - reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags - else - gentop=$output_objdir/${obj}x - func_append generated " $gentop" - - func_extract_archives $gentop $convenience - reload_conv_objs="$reload_objs $func_extract_archives_result" - fi - fi - - # If we're not building shared, we need to use non_pic_objs - test yes = "$build_libtool_libs" || libobjs=$non_pic_objects - - # Create the old-style object. - reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs - - output=$obj - func_execute_cmds "$reload_cmds" 'exit $?' - - # Exit if we aren't doing a library object file. - if test -z "$libobj"; then - if test -n "$gentop"; then - func_show_eval '${RM}r "$gentop"' - fi - - exit $EXIT_SUCCESS - fi - - test yes = "$build_libtool_libs" || { - if test -n "$gentop"; then - func_show_eval '${RM}r "$gentop"' - fi - - # Create an invalid libtool object if no PIC, so that we don't - # accidentally link it into a program. - # $show "echo timestamp > $libobj" - # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? - exit $EXIT_SUCCESS - } - - if test -n "$pic_flag" || test default != "$pic_mode"; then - # Only do commands if we really have different PIC objects. - reload_objs="$libobjs $reload_conv_objs" - output=$libobj - func_execute_cmds "$reload_cmds" 'exit $?' - fi - - if test -n "$gentop"; then - func_show_eval '${RM}r "$gentop"' - fi - - exit $EXIT_SUCCESS - ;; - - prog) - case $host in - *cygwin*) func_stripname '' '.exe' "$output" - output=$func_stripname_result.exe;; - esac - test -n "$vinfo" && \ - func_warning "'-version-info' is ignored for programs" - - test -n "$release" && \ - func_warning "'-release' is ignored for programs" - - $preload \ - && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ - && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library is the System framework - compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` - finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` - ;; - esac - - case $host in - *-*-darwin*) - # Don't allow lazy linking, it breaks C++ global constructors - # But is supposedly fixed on 10.4 or later (yay!). - if test CXX = "$tagname"; then - case ${MACOSX_DEPLOYMENT_TARGET-10.0} in - 10.[0123]) - func_append compile_command " $wl-bind_at_load" - func_append finalize_command " $wl-bind_at_load" - ;; - esac - fi - # Time to change all our "foo.ltframework" stuff back to "-framework foo" - compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - ;; - esac - - - # move library search paths that coincide with paths to not yet - # installed libraries to the beginning of the library search list - new_libs= - for path in $notinst_path; do - case " $new_libs " in - *" -L$path/$objdir "*) ;; - *) - case " $compile_deplibs " in - *" -L$path/$objdir "*) - func_append new_libs " -L$path/$objdir" ;; - esac - ;; - esac - done - for deplib in $compile_deplibs; do - case $deplib in - -L*) - case " $new_libs " in - *" $deplib "*) ;; - *) func_append new_libs " $deplib" ;; - esac - ;; - *) func_append new_libs " $deplib" ;; - esac - done - compile_deplibs=$new_libs - - - func_append compile_command " $compile_deplibs" - func_append finalize_command " $finalize_deplibs" - - if test -n "$rpath$xrpath"; then - # If the user specified any rpath flags, then add them. - for libdir in $rpath $xrpath; do - # This is the magic to use -rpath. - case "$finalize_rpath " in - *" $libdir "*) ;; - *) func_append finalize_rpath " $libdir" ;; - esac - done - fi - - # Now hardcode the library paths - rpath= - hardcode_libdirs= - for libdir in $compile_rpath $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs=$libdir - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - func_append rpath " $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) func_append perm_rpath " $libdir" ;; - esac - fi - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) - testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` - case :$dllsearchpath: in - *":$libdir:"*) ;; - ::) dllsearchpath=$libdir;; - *) func_append dllsearchpath ":$libdir";; - esac - case :$dllsearchpath: in - *":$testbindir:"*) ;; - ::) dllsearchpath=$testbindir;; - *) func_append dllsearchpath ":$testbindir";; - esac - ;; - esac - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir=$hardcode_libdirs - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - compile_rpath=$rpath - - rpath= - hardcode_libdirs= - for libdir in $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs=$libdir - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - func_append rpath " $flag" - fi - elif test -n "$runpath_var"; then - case "$finalize_perm_rpath " in - *" $libdir "*) ;; - *) func_append finalize_perm_rpath " $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir=$hardcode_libdirs - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - finalize_rpath=$rpath - - if test -n "$libobjs" && test yes = "$build_old_libs"; then - # Transform all the library objects into standard objects. - compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` - finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` - fi - - func_generate_dlsyms "$outputname" "@PROGRAM@" false - - # template prelinking step - if test -n "$prelink_cmds"; then - func_execute_cmds "$prelink_cmds" 'exit $?' - fi - - wrappers_required=: - case $host in - *cegcc* | *mingw32ce*) - # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. - wrappers_required=false - ;; - *cygwin* | *mingw* ) - test yes = "$build_libtool_libs" || wrappers_required=false - ;; - *) - if test no = "$need_relink" || test yes != "$build_libtool_libs"; then - wrappers_required=false - fi - ;; - esac - $wrappers_required || { - # Replace the output file specification. - compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` - link_command=$compile_command$compile_rpath - - # We have no uninstalled library dependencies, so finalize right now. - exit_status=0 - func_show_eval "$link_command" 'exit_status=$?' - - if test -n "$postlink_cmds"; then - func_to_tool_file "$output" - postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` - func_execute_cmds "$postlink_cmds" 'exit $?' - fi - - # Delete the generated files. - if test -f "$output_objdir/${outputname}S.$objext"; then - func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' - fi - - exit $exit_status - } - - if test -n "$compile_shlibpath$finalize_shlibpath"; then - compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" - fi - if test -n "$finalize_shlibpath"; then - finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" - fi - - compile_var= - finalize_var= - if test -n "$runpath_var"; then - if test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - func_append rpath "$dir:" - done - compile_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - if test -n "$finalize_perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $finalize_perm_rpath; do - func_append rpath "$dir:" - done - finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - fi - - if test yes = "$no_install"; then - # We don't need to create a wrapper script. - link_command=$compile_var$compile_command$compile_rpath - # Replace the output file specification. - link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` - # Delete the old output file. - $opt_dry_run || $RM $output - # Link the executable and exit - func_show_eval "$link_command" 'exit $?' - - if test -n "$postlink_cmds"; then - func_to_tool_file "$output" - postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` - func_execute_cmds "$postlink_cmds" 'exit $?' - fi - - exit $EXIT_SUCCESS - fi - - case $hardcode_action,$fast_install in - relink,*) - # Fast installation is not supported - link_command=$compile_var$compile_command$compile_rpath - relink_command=$finalize_var$finalize_command$finalize_rpath - - func_warning "this platform does not like uninstalled shared libraries" - func_warning "'$output' will be relinked during installation" - ;; - *,yes) - link_command=$finalize_var$compile_command$finalize_rpath - relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` - ;; - *,no) - link_command=$compile_var$compile_command$compile_rpath - relink_command=$finalize_var$finalize_command$finalize_rpath - ;; - *,needless) - link_command=$finalize_var$compile_command$finalize_rpath - relink_command= - ;; - esac - - # Replace the output file specification. - link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` - - # Delete the old output files. - $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname - - func_show_eval "$link_command" 'exit $?' - - if test -n "$postlink_cmds"; then - func_to_tool_file "$output_objdir/$outputname" - postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` - func_execute_cmds "$postlink_cmds" 'exit $?' - fi - - # Now create the wrapper script. - func_verbose "creating $output" - - # Quote the relink command for shipping. - if test -n "$relink_command"; then - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - func_quote_for_eval "$var_value" - relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" - fi - done - relink_command="(cd `pwd`; $relink_command)" - relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` - fi - - # Only actually do things if not in dry run mode. - $opt_dry_run || { - # win32 will think the script is a binary if it has - # a .exe suffix, so we strip it off here. - case $output in - *.exe) func_stripname '' '.exe' "$output" - output=$func_stripname_result ;; - esac - # test for cygwin because mv fails w/o .exe extensions - case $host in - *cygwin*) - exeext=.exe - func_stripname '' '.exe' "$outputname" - outputname=$func_stripname_result ;; - *) exeext= ;; - esac - case $host in - *cygwin* | *mingw* ) - func_dirname_and_basename "$output" "" "." - output_name=$func_basename_result - output_path=$func_dirname_result - cwrappersource=$output_path/$objdir/lt-$output_name.c - cwrapper=$output_path/$output_name.exe - $RM $cwrappersource $cwrapper - trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 - - func_emit_cwrapperexe_src > $cwrappersource - - # The wrapper executable is built using the $host compiler, - # because it contains $host paths and files. If cross- - # compiling, it, like the target executable, must be - # executed on the $host or under an emulation environment. - $opt_dry_run || { - $LTCC $LTCFLAGS -o $cwrapper $cwrappersource - $STRIP $cwrapper - } - - # Now, create the wrapper script for func_source use: - func_ltwrapper_scriptname $cwrapper - $RM $func_ltwrapper_scriptname_result - trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 - $opt_dry_run || { - # note: this script will not be executed, so do not chmod. - if test "x$build" = "x$host"; then - $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result - else - func_emit_wrapper no > $func_ltwrapper_scriptname_result - fi - } - ;; - * ) - $RM $output - trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 - - func_emit_wrapper no > $output - chmod +x $output - ;; - esac - } - exit $EXIT_SUCCESS - ;; - esac - - # See if we need to build an old-fashioned archive. - for oldlib in $oldlibs; do - - case $build_libtool_libs in - convenience) - oldobjs="$libobjs_save $symfileobj" - addlibs=$convenience - build_libtool_libs=no - ;; - module) - oldobjs=$libobjs_save - addlibs=$old_convenience - build_libtool_libs=no - ;; - *) - oldobjs="$old_deplibs $non_pic_objects" - $preload && test -f "$symfileobj" \ - && func_append oldobjs " $symfileobj" - addlibs=$old_convenience - ;; - esac - - if test -n "$addlibs"; then - gentop=$output_objdir/${outputname}x - func_append generated " $gentop" - - func_extract_archives $gentop $addlibs - func_append oldobjs " $func_extract_archives_result" - fi - - # Do each command in the archive commands. - if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then - cmds=$old_archive_from_new_cmds - else - - # Add any objects from preloaded convenience libraries - if test -n "$dlprefiles"; then - gentop=$output_objdir/${outputname}x - func_append generated " $gentop" - - func_extract_archives $gentop $dlprefiles - func_append oldobjs " $func_extract_archives_result" - fi - - # POSIX demands no paths to be encoded in archives. We have - # to avoid creating archives with duplicate basenames if we - # might have to extract them afterwards, e.g., when creating a - # static archive out of a convenience library, or when linking - # the entirety of a libtool archive into another (currently - # not supported by libtool). - if (for obj in $oldobjs - do - func_basename "$obj" - $ECHO "$func_basename_result" - done | sort | sort -uc >/dev/null 2>&1); then - : - else - echo "copying selected object files to avoid basename conflicts..." - gentop=$output_objdir/${outputname}x - func_append generated " $gentop" - func_mkdir_p "$gentop" - save_oldobjs=$oldobjs - oldobjs= - counter=1 - for obj in $save_oldobjs - do - func_basename "$obj" - objbase=$func_basename_result - case " $oldobjs " in - " ") oldobjs=$obj ;; - *[\ /]"$objbase "*) - while :; do - # Make sure we don't pick an alternate name that also - # overlaps. - newobj=lt$counter-$objbase - func_arith $counter + 1 - counter=$func_arith_result - case " $oldobjs " in - *[\ /]"$newobj "*) ;; - *) if test ! -f "$gentop/$newobj"; then break; fi ;; - esac - done - func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" - func_append oldobjs " $gentop/$newobj" - ;; - *) func_append oldobjs " $obj" ;; - esac - done - fi - func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 - tool_oldlib=$func_to_tool_file_result - eval cmds=\"$old_archive_cmds\" - - func_len " $cmds" - len=$func_len_result - if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then - cmds=$old_archive_cmds - elif test -n "$archiver_list_spec"; then - func_verbose "using command file archive linking..." - for obj in $oldobjs - do - func_to_tool_file "$obj" - $ECHO "$func_to_tool_file_result" - done > $output_objdir/$libname.libcmd - func_to_tool_file "$output_objdir/$libname.libcmd" - oldobjs=" $archiver_list_spec$func_to_tool_file_result" - cmds=$old_archive_cmds - else - # the command line is too long to link in one step, link in parts - func_verbose "using piecewise archive linking..." - save_RANLIB=$RANLIB - RANLIB=: - objlist= - concat_cmds= - save_oldobjs=$oldobjs - oldobjs= - # Is there a better way of finding the last object in the list? - for obj in $save_oldobjs - do - last_oldobj=$obj - done - eval test_cmds=\"$old_archive_cmds\" - func_len " $test_cmds" - len0=$func_len_result - len=$len0 - for obj in $save_oldobjs - do - func_len " $obj" - func_arith $len + $func_len_result - len=$func_arith_result - func_append objlist " $obj" - if test "$len" -lt "$max_cmd_len"; then - : - else - # the above command should be used before it gets too long - oldobjs=$objlist - if test "$obj" = "$last_oldobj"; then - RANLIB=$save_RANLIB - fi - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" - objlist= - len=$len0 - fi - done - RANLIB=$save_RANLIB - oldobjs=$objlist - if test -z "$oldobjs"; then - eval cmds=\"\$concat_cmds\" - else - eval cmds=\"\$concat_cmds~\$old_archive_cmds\" - fi - fi - fi - func_execute_cmds "$cmds" 'exit $?' - done - - test -n "$generated" && \ - func_show_eval "${RM}r$generated" - - # Now create the libtool archive. - case $output in - *.la) - old_library= - test yes = "$build_old_libs" && old_library=$libname.$libext - func_verbose "creating $output" - - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - func_quote_for_eval "$var_value" - relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" - fi - done - # Quote the link command for shipping. - relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" - relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` - if test yes = "$hardcode_automatic"; then - relink_command= - fi - - # Only create the output if not a dry run. - $opt_dry_run || { - for installed in no yes; do - if test yes = "$installed"; then - if test -z "$install_libdir"; then - break - fi - output=$output_objdir/${outputname}i - # Replace all uninstalled libtool libraries with the installed ones - newdependency_libs= - for deplib in $dependency_libs; do - case $deplib in - *.la) - func_basename "$deplib" - name=$func_basename_result - func_resolve_sysroot "$deplib" - eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` - test -z "$libdir" && \ - func_fatal_error "'$deplib' is not a valid libtool archive" - func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" - ;; - -L*) - func_stripname -L '' "$deplib" - func_replace_sysroot "$func_stripname_result" - func_append newdependency_libs " -L$func_replace_sysroot_result" - ;; - -R*) - func_stripname -R '' "$deplib" - func_replace_sysroot "$func_stripname_result" - func_append newdependency_libs " -R$func_replace_sysroot_result" - ;; - *) func_append newdependency_libs " $deplib" ;; - esac - done - dependency_libs=$newdependency_libs - newdlfiles= - - for lib in $dlfiles; do - case $lib in - *.la) - func_basename "$lib" - name=$func_basename_result - eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - test -z "$libdir" && \ - func_fatal_error "'$lib' is not a valid libtool archive" - func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" - ;; - *) func_append newdlfiles " $lib" ;; - esac - done - dlfiles=$newdlfiles - newdlprefiles= - for lib in $dlprefiles; do - case $lib in - *.la) - # Only pass preopened files to the pseudo-archive (for - # eventual linking with the app. that links it) if we - # didn't already link the preopened objects directly into - # the library: - func_basename "$lib" - name=$func_basename_result - eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - test -z "$libdir" && \ - func_fatal_error "'$lib' is not a valid libtool archive" - func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" - ;; - esac - done - dlprefiles=$newdlprefiles - else - newdlfiles= - for lib in $dlfiles; do - case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; - *) abs=`pwd`"/$lib" ;; - esac - func_append newdlfiles " $abs" - done - dlfiles=$newdlfiles - newdlprefiles= - for lib in $dlprefiles; do - case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; - *) abs=`pwd`"/$lib" ;; - esac - func_append newdlprefiles " $abs" - done - dlprefiles=$newdlprefiles - fi - $RM $output - # place dlname in correct position for cygwin - # In fact, it would be nice if we could use this code for all target - # systems that can't hard-code library paths into their executables - # and that have no shared library path variable independent of PATH, - # but it turns out we can't easily determine that from inspecting - # libtool variables, so we have to hard-code the OSs to which it - # applies here; at the moment, that means platforms that use the PE - # object format with DLL files. See the long comment at the top of - # tests/bindir.at for full details. - tdlname=$dlname - case $host,$output,$installed,$module,$dlname in - *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) - # If a -bindir argument was supplied, place the dll there. - if test -n "$bindir"; then - func_relative_path "$install_libdir" "$bindir" - tdlname=$func_relative_path_result/$dlname - else - # Otherwise fall back on heuristic. - tdlname=../bin/$dlname - fi - ;; - esac - $ECHO > $output "\ -# $outputname - a libtool library file -# Generated by $PROGRAM (GNU $PACKAGE) $VERSION -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# The name that we can dlopen(3). -dlname='$tdlname' - -# Names of this library. -library_names='$library_names' - -# The name of the static archive. -old_library='$old_library' - -# Linker flags that cannot go in dependency_libs. -inherited_linker_flags='$new_inherited_linker_flags' - -# Libraries that this one depends upon. -dependency_libs='$dependency_libs' - -# Names of additional weak libraries provided by this library -weak_library_names='$weak_libs' - -# Version information for $libname. -current=$current -age=$age -revision=$revision - -# Is this an already installed library? -installed=$installed - -# Should we warn about portability when linking against -modules? -shouldnotlink=$module - -# Files to dlopen/dlpreopen -dlopen='$dlfiles' -dlpreopen='$dlprefiles' - -# Directory that this library needs to be installed in: -libdir='$install_libdir'" - if test no,yes = "$installed,$need_relink"; then - $ECHO >> $output "\ -relink_command=\"$relink_command\"" - fi - done - } - - # Do a symbolic link so that the libtool archive can be found in - # LD_LIBRARY_PATH before the program is installed. - func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' - ;; - esac - exit $EXIT_SUCCESS -} - -if test link = "$opt_mode" || test relink = "$opt_mode"; then - func_mode_link ${1+"$@"} -fi - - -# func_mode_uninstall arg... -func_mode_uninstall () -{ - $debug_cmd - - RM=$nonopt - files= - rmforce=false - exit_status=0 - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic=$magic - - for arg - do - case $arg in - -f) func_append RM " $arg"; rmforce=: ;; - -*) func_append RM " $arg" ;; - *) func_append files " $arg" ;; - esac - done - - test -z "$RM" && \ - func_fatal_help "you must specify an RM program" - - rmdirs= - - for file in $files; do - func_dirname "$file" "" "." - dir=$func_dirname_result - if test . = "$dir"; then - odir=$objdir - else - odir=$dir/$objdir - fi - func_basename "$file" - name=$func_basename_result - test uninstall = "$opt_mode" && odir=$dir - - # Remember odir for removal later, being careful to avoid duplicates - if test clean = "$opt_mode"; then - case " $rmdirs " in - *" $odir "*) ;; - *) func_append rmdirs " $odir" ;; - esac - fi - - # Don't error if the file doesn't exist and rm -f was used. - if { test -L "$file"; } >/dev/null 2>&1 || - { test -h "$file"; } >/dev/null 2>&1 || - test -f "$file"; then - : - elif test -d "$file"; then - exit_status=1 - continue - elif $rmforce; then - continue - fi - - rmfiles=$file - - case $name in - *.la) - # Possibly a libtool archive, so verify it. - if func_lalib_p "$file"; then - func_source $dir/$name - - # Delete the libtool libraries and symlinks. - for n in $library_names; do - func_append rmfiles " $odir/$n" - done - test -n "$old_library" && func_append rmfiles " $odir/$old_library" - - case $opt_mode in - clean) - case " $library_names " in - *" $dlname "*) ;; - *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; - esac - test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" - ;; - uninstall) - if test -n "$library_names"; then - # Do each command in the postuninstall commands. - func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' - fi - - if test -n "$old_library"; then - # Do each command in the old_postuninstall commands. - func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' - fi - # FIXME: should reinstall the best remaining shared library. - ;; - esac - fi - ;; - - *.lo) - # Possibly a libtool object, so verify it. - if func_lalib_p "$file"; then - - # Read the .lo file - func_source $dir/$name - - # Add PIC object to the list of files to remove. - if test -n "$pic_object" && test none != "$pic_object"; then - func_append rmfiles " $dir/$pic_object" - fi - - # Add non-PIC object to the list of files to remove. - if test -n "$non_pic_object" && test none != "$non_pic_object"; then - func_append rmfiles " $dir/$non_pic_object" - fi - fi - ;; - - *) - if test clean = "$opt_mode"; then - noexename=$name - case $file in - *.exe) - func_stripname '' '.exe' "$file" - file=$func_stripname_result - func_stripname '' '.exe' "$name" - noexename=$func_stripname_result - # $file with .exe has already been added to rmfiles, - # add $file without .exe - func_append rmfiles " $file" - ;; - esac - # Do a test to see if this is a libtool program. - if func_ltwrapper_p "$file"; then - if func_ltwrapper_executable_p "$file"; then - func_ltwrapper_scriptname "$file" - relink_command= - func_source $func_ltwrapper_scriptname_result - func_append rmfiles " $func_ltwrapper_scriptname_result" - else - relink_command= - func_source $dir/$noexename - fi - - # note $name still contains .exe if it was in $file originally - # as does the version of $file that was added into $rmfiles - func_append rmfiles " $odir/$name $odir/${name}S.$objext" - if test yes = "$fast_install" && test -n "$relink_command"; then - func_append rmfiles " $odir/lt-$name" - fi - if test "X$noexename" != "X$name"; then - func_append rmfiles " $odir/lt-$noexename.c" - fi - fi - fi - ;; - esac - func_show_eval "$RM $rmfiles" 'exit_status=1' - done - - # Try to remove the $objdir's in the directories where we deleted files - for dir in $rmdirs; do - if test -d "$dir"; then - func_show_eval "rmdir $dir >/dev/null 2>&1" - fi - done - - exit $exit_status -} - -if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then - func_mode_uninstall ${1+"$@"} -fi - -test -z "$opt_mode" && { - help=$generic_help - func_fatal_help "you must specify a MODE" -} - -test -z "$exec_cmd" && \ - func_fatal_help "invalid operation mode '$opt_mode'" - -if test -n "$exec_cmd"; then - eval exec "$exec_cmd" - exit $EXIT_FAILURE -fi - -exit $exit_status - - -# The TAGs below are defined such that we never get into a situation -# where we disable both kinds of libraries. Given conflicting -# choices, we go for a static library, that is the most portable, -# since we can't tell whether shared libraries were disabled because -# the user asked for that or because the platform doesn't support -# them. This is particularly important on AIX, because we don't -# support having both static and shared libraries enabled at the same -# time on that platform, so we default to a shared-only configuration. -# If a disable-shared tag is given, we'll fallback to a static-only -# configuration. But we'll never go from static-only to shared-only. - -# ### BEGIN LIBTOOL TAG CONFIG: disable-shared -build_libtool_libs=no -build_old_libs=yes -# ### END LIBTOOL TAG CONFIG: disable-shared - -# ### BEGIN LIBTOOL TAG CONFIG: disable-static -build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` -# ### END LIBTOOL TAG CONFIG: disable-static - -# Local Variables: -# mode:shell-script -# sh-indentation:2 -# End: diff --git a/thirdparty/libarchive/build/autoconf/m4_ax_compile_check_sizeof.m4 b/thirdparty/libarchive/build/autoconf/m4_ax_compile_check_sizeof.m4 deleted file mode 100644 index f834df634..000000000 --- a/thirdparty/libarchive/build/autoconf/m4_ax_compile_check_sizeof.m4 +++ /dev/null @@ -1,115 +0,0 @@ -# ============================================================================ -# https://www.gnu.org/software/autoconf-archive/ax_compile_check_sizeof.html -# ============================================================================ -# -# SYNOPSIS -# -# AX_COMPILE_CHECK_SIZEOF(TYPE [, HEADERS [, EXTRA_SIZES...]]) -# -# DESCRIPTION -# -# This macro checks for the size of TYPE using compile checks, not run -# checks. You can supply extra HEADERS to look into. the check will cycle -# through 1 2 4 8 16 and any EXTRA_SIZES the user supplies. If a match is -# found, it will #define SIZEOF_`TYPE' to that value. Otherwise it will -# emit a configure time error indicating the size of the type could not be -# determined. -# -# The trick is that C will not allow duplicate case labels. While this is -# valid C code: -# -# switch (0) case 0: case 1:; -# -# The following is not: -# -# switch (0) case 0: case 0:; -# -# Thus, the AC_COMPILE_IFELSE will fail if the currently tried size does -# not match. -# -# Here is an example skeleton configure.in script, demonstrating the -# macro's usage: -# -# AC_PROG_CC -# AC_CHECK_HEADERS(stddef.h unistd.h) -# AC_TYPE_SIZE_T -# AC_CHECK_TYPE(ssize_t, int) -# -# headers='#ifdef HAVE_STDDEF_H -# #include -# #endif -# #ifdef HAVE_UNISTD_H -# #include -# #endif -# ' -# -# AX_COMPILE_CHECK_SIZEOF(char) -# AX_COMPILE_CHECK_SIZEOF(short) -# AX_COMPILE_CHECK_SIZEOF(int) -# AX_COMPILE_CHECK_SIZEOF(long) -# AX_COMPILE_CHECK_SIZEOF(unsigned char *) -# AX_COMPILE_CHECK_SIZEOF(void *) -# AX_COMPILE_CHECK_SIZEOF(size_t, $headers) -# AX_COMPILE_CHECK_SIZEOF(ssize_t, $headers) -# AX_COMPILE_CHECK_SIZEOF(ptrdiff_t, $headers) -# AX_COMPILE_CHECK_SIZEOF(off_t, $headers) -# -# LICENSE -# -# Copyright (c) 2008 Kaveh Ghazi -# Copyright (c) 2017 Reini Urban -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 8 - -AU_ALIAS([AC_COMPILE_CHECK_SIZEOF], [AX_COMPILE_CHECK_SIZEOF]) -AC_DEFUN([AX_COMPILE_CHECK_SIZEOF], -[changequote(<<, >>)dnl -dnl The name to #define. -define(<>, translit(sizeof_$1, [a-z *], [A-Z_P]))dnl -dnl The cache variable name. -define(<>, translit(ac_cv_sizeof_$1, [ *], [_p]))dnl -changequote([, ])dnl -AC_MSG_CHECKING(size of $1) -AC_CACHE_VAL(AC_CV_NAME, -[for ac_size in 4 8 1 2 16 $3 ; do # List sizes in rough order of prevalence. - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -#include -$2 -]], [[switch (0) case 0: case (sizeof ($1) == $ac_size):;]])], [AC_CV_NAME=$ac_size]) - if test x$AC_CV_NAME != x ; then break; fi -done -]) -if test x$AC_CV_NAME = x ; then - AC_MSG_ERROR([cannot determine a size for $1]) -fi -AC_MSG_RESULT($AC_CV_NAME) -AC_DEFINE_UNQUOTED(AC_TYPE_NAME, $AC_CV_NAME, [The number of bytes in type $1]) -undefine([AC_TYPE_NAME])dnl -undefine([AC_CV_NAME])dnl -]) diff --git a/thirdparty/libarchive/build/autoconf/missing b/thirdparty/libarchive/build/autoconf/missing deleted file mode 100755 index 1fe1611f1..000000000 --- a/thirdparty/libarchive/build/autoconf/missing +++ /dev/null @@ -1,215 +0,0 @@ -#! /bin/sh -# Common wrapper for a few potentially missing GNU programs. - -scriptversion=2018-03-07.03; # UTC - -# Copyright (C) 1996-2021 Free Software Foundation, Inc. -# Originally written by Fran,cois Pinard , 1996. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -if test $# -eq 0; then - echo 1>&2 "Try '$0 --help' for more information" - exit 1 -fi - -case $1 in - - --is-lightweight) - # Used by our autoconf macros to check whether the available missing - # script is modern enough. - exit 0 - ;; - - --run) - # Back-compat with the calling convention used by older automake. - shift - ;; - - -h|--h|--he|--hel|--help) - echo "\ -$0 [OPTION]... PROGRAM [ARGUMENT]... - -Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due -to PROGRAM being missing or too old. - -Options: - -h, --help display this help and exit - -v, --version output version information and exit - -Supported PROGRAM values: - aclocal autoconf autoheader autom4te automake makeinfo - bison yacc flex lex help2man - -Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and -'g' are ignored when checking the name. - -Send bug reports to ." - exit $? - ;; - - -v|--v|--ve|--ver|--vers|--versi|--versio|--version) - echo "missing $scriptversion (GNU Automake)" - exit $? - ;; - - -*) - echo 1>&2 "$0: unknown '$1' option" - echo 1>&2 "Try '$0 --help' for more information" - exit 1 - ;; - -esac - -# Run the given program, remember its exit status. -"$@"; st=$? - -# If it succeeded, we are done. -test $st -eq 0 && exit 0 - -# Also exit now if we it failed (or wasn't found), and '--version' was -# passed; such an option is passed most likely to detect whether the -# program is present and works. -case $2 in --version|--help) exit $st;; esac - -# Exit code 63 means version mismatch. This often happens when the user -# tries to use an ancient version of a tool on a file that requires a -# minimum version. -if test $st -eq 63; then - msg="probably too old" -elif test $st -eq 127; then - # Program was missing. - msg="missing on your system" -else - # Program was found and executed, but failed. Give up. - exit $st -fi - -perl_URL=https://www.perl.org/ -flex_URL=https://github.com/westes/flex -gnu_software_URL=https://www.gnu.org/software - -program_details () -{ - case $1 in - aclocal|automake) - echo "The '$1' program is part of the GNU Automake package:" - echo "<$gnu_software_URL/automake>" - echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" - echo "<$gnu_software_URL/autoconf>" - echo "<$gnu_software_URL/m4/>" - echo "<$perl_URL>" - ;; - autoconf|autom4te|autoheader) - echo "The '$1' program is part of the GNU Autoconf package:" - echo "<$gnu_software_URL/autoconf/>" - echo "It also requires GNU m4 and Perl in order to run:" - echo "<$gnu_software_URL/m4/>" - echo "<$perl_URL>" - ;; - esac -} - -give_advice () -{ - # Normalize program name to check for. - normalized_program=`echo "$1" | sed ' - s/^gnu-//; t - s/^gnu//; t - s/^g//; t'` - - printf '%s\n' "'$1' is $msg." - - configure_deps="'configure.ac' or m4 files included by 'configure.ac'" - case $normalized_program in - autoconf*) - echo "You should only need it if you modified 'configure.ac'," - echo "or m4 files included by it." - program_details 'autoconf' - ;; - autoheader*) - echo "You should only need it if you modified 'acconfig.h' or" - echo "$configure_deps." - program_details 'autoheader' - ;; - automake*) - echo "You should only need it if you modified 'Makefile.am' or" - echo "$configure_deps." - program_details 'automake' - ;; - aclocal*) - echo "You should only need it if you modified 'acinclude.m4' or" - echo "$configure_deps." - program_details 'aclocal' - ;; - autom4te*) - echo "You might have modified some maintainer files that require" - echo "the 'autom4te' program to be rebuilt." - program_details 'autom4te' - ;; - bison*|yacc*) - echo "You should only need it if you modified a '.y' file." - echo "You may want to install the GNU Bison package:" - echo "<$gnu_software_URL/bison/>" - ;; - lex*|flex*) - echo "You should only need it if you modified a '.l' file." - echo "You may want to install the Fast Lexical Analyzer package:" - echo "<$flex_URL>" - ;; - help2man*) - echo "You should only need it if you modified a dependency" \ - "of a man page." - echo "You may want to install the GNU Help2man package:" - echo "<$gnu_software_URL/help2man/>" - ;; - makeinfo*) - echo "You should only need it if you modified a '.texi' file, or" - echo "any other file indirectly affecting the aspect of the manual." - echo "You might want to install the Texinfo package:" - echo "<$gnu_software_URL/texinfo/>" - echo "The spurious makeinfo call might also be the consequence of" - echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" - echo "want to install GNU make:" - echo "<$gnu_software_URL/make/>" - ;; - *) - echo "You might have modified some files without having the proper" - echo "tools for further handling them. Check the 'README' file, it" - echo "often tells you about the needed prerequisites for installing" - echo "this package. You may also peek at any GNU archive site, in" - echo "case some other package contains this missing '$1' program." - ;; - esac -} - -give_advice "$1" | sed -e '1s/^/WARNING: /' \ - -e '2,$s/^/ /' >&2 - -# Propagate the correct exit status (expected to be 127 for a program -# not found, 63 for a program that failed due to version mismatch). -exit $st - -# Local variables: -# eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC0" -# time-stamp-end: "; # UTC" -# End: diff --git a/thirdparty/libarchive/build/autoconf/test-driver b/thirdparty/libarchive/build/autoconf/test-driver deleted file mode 100755 index be73b80ad..000000000 --- a/thirdparty/libarchive/build/autoconf/test-driver +++ /dev/null @@ -1,153 +0,0 @@ -#! /bin/sh -# test-driver - basic testsuite driver script. - -scriptversion=2018-03-07.03; # UTC - -# Copyright (C) 2011-2021 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# This file is maintained in Automake, please report -# bugs to or send patches to -# . - -# Make unconditional expansion of undefined variables an error. This -# helps a lot in preventing typo-related bugs. -set -u - -usage_error () -{ - echo "$0: $*" >&2 - print_usage >&2 - exit 2 -} - -print_usage () -{ - cat <"$log_file" -"$@" >>"$log_file" 2>&1 -estatus=$? - -if test $enable_hard_errors = no && test $estatus -eq 99; then - tweaked_estatus=1 -else - tweaked_estatus=$estatus -fi - -case $tweaked_estatus:$expect_failure in - 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; - 0:*) col=$grn res=PASS recheck=no gcopy=no;; - 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; - 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; - *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; - *:*) col=$red res=FAIL recheck=yes gcopy=yes;; -esac - -# Report the test outcome and exit status in the logs, so that one can -# know whether the test passed or failed simply by looking at the '.log' -# file, without the need of also peaking into the corresponding '.trs' -# file (automake bug#11814). -echo "$res $test_name (exit status: $estatus)" >>"$log_file" - -# Report outcome to console. -echo "${col}${res}${std}: $test_name" - -# Register the test result, and other relevant metadata. -echo ":test-result: $res" > $trs_file -echo ":global-test-result: $res" >> $trs_file -echo ":recheck: $recheck" >> $trs_file -echo ":copy-in-global-log: $gcopy" >> $trs_file - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC0" -# time-stamp-end: "; # UTC" -# End: diff --git a/thirdparty/libarchive/build/autogen.sh b/thirdparty/libarchive/build/autogen.sh deleted file mode 100755 index e720e9b78..000000000 --- a/thirdparty/libarchive/build/autogen.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/bin/sh - -PATH=/usr/local/gnu-autotools/bin/:$PATH -export PATH - -# Start from one level above the build directory -if [ -f version ]; then - cd .. -fi - -if [ \! -f build/version ]; then - echo "Can't find source directory" - exit 1 -fi - -# BSD make's "OBJDIR" support freaks out the automake-generated -# Makefile. Effectively disable it. -export MAKEOBJDIRPREFIX=/junk - -# Start from the build directory, where the version file is located -if [ -f build/version ]; then - cd build -fi - -if [ \! -f version ]; then - echo "Can't find version file" - exit 1 -fi - -# Update the build number in the 'version' file. -# Separate number from additional alpha/beta/etc marker -MARKER=`cat version | sed 's/[0-9.]//g'` -# Bump the number -VN=`cat version | sed 's/[^0-9.]//g'` -# Build out the string. -VS="$(($VN/1000000)).$(( ($VN/1000)%1000 )).$(( $VN%1000 ))$MARKER" - -cd .. - -# Clean up the source dir as much as we can. -/bin/sh build/clean.sh - -# Substitute the versions into Libarchive's archive.h and archive_entry.h -perl -p -i -e "s/^(#define\tARCHIVE_VERSION_NUMBER).*/\$1 $VN/" libarchive/archive.h -perl -p -i -e "s/^(#define\tARCHIVE_VERSION_NUMBER).*/\$1 $VN/" libarchive/archive_entry.h -perl -p -i -e "s/^(#define\tARCHIVE_VERSION_ONLY_STRING).*/\$1 \"$VS\"/" libarchive/archive.h -# Substitute versions into configure.ac as well -perl -p -i -e 's/(m4_define\(\[LIBARCHIVE_VERSION_S\]),.*\)/$1,['"$VS"'])/' configure.ac -perl -p -i -e 's/(m4_define\(\[LIBARCHIVE_VERSION_N\]),.*\)/$1,['"$VN"'])/' configure.ac - -# Remove developer CFLAGS if a release build is being made -if [ -n "${MAKE_LIBARCHIVE_RELEASE}" ]; then - perl -p -i -e "s/^(DEV_CFLAGS.*)/# \$1/" Makefile.am - perl -p -i -e 's/CMAKE_BUILD_TYPE "[A-Za-z]*"/CMAKE_BUILD_TYPE "Release"/' CMakeLists.txt -fi - -set -xe -aclocal -I build/autoconf - -# Note: --automake flag needed only for libtoolize from -# libtool 1.5.x; in libtool 2.2.x it is a synonym for --quiet -case `uname` in -Darwin) glibtoolize --automake -c;; -*) libtoolize --automake -c;; -esac -autoconf -autoheader -automake -a -c diff --git a/thirdparty/libarchive/build/bump-version.sh b/thirdparty/libarchive/build/bump-version.sh deleted file mode 100755 index eec42354f..000000000 --- a/thirdparty/libarchive/build/bump-version.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh +v - -# Start from the build directory, where the version file is located -if [ -f build/version ]; then - cd build -fi - -if [ \! -f version ]; then - echo "Can't find version file" - exit 1 -fi - -# Update the build number in the 'version' file. -# Separate number from additional alpha/beta/etc marker -MARKER=`cat version | sed 's/[0-9.]//g'` -# Bump the number -VN=`cat version | sed 's/[^0-9.]//g'` -# Reassemble and write back out -VN=$(($VN + 1)) -rm -f version.old -mv version version.old -chmod +w version.old -echo $VN$MARKER > version -VS="$(($VN/1000000)).$(( ($VN/1000)%1000 )).$(( $VN%1000 ))$MARKER" -cd .. - -ANNOUNCE=`date +"%b %d, %Y:"`" libarchive $VS released" - -echo $ANNOUNCE - -# Add a version notice to NEWS -mv NEWS NEWS.bak -chmod +w NEWS.bak -echo $ANNOUNCE >> NEWS -echo >> NEWS -cat NEWS.bak >> NEWS diff --git a/thirdparty/libarchive/build/clean.sh b/thirdparty/libarchive/build/clean.sh deleted file mode 100755 index b669426cc..000000000 --- a/thirdparty/libarchive/build/clean.sh +++ /dev/null @@ -1,99 +0,0 @@ -#!/bin/sh - -# -# Attempt to remove as many generated files as we can. -# Ideally, a well-used development sandbox would look like -# a pristine checkout after running this script. -# - -if [ \! -f build/version ]; then - echo 'Must run the clean script from the top-level dir of the libarchive distribution' 1>&2 - exit 1 -fi - -# If we're on BSD, blow away the build dir under /usr/obj -rm -rf /usr/obj`pwd` - -# -# Try to clean up a bit more... -# - -find . -name '*.So' | xargs rm -f -find . -name '*.a' | xargs rm -f -find . -name '*.la' | xargs rm -f -find . -name '*.lo' | xargs rm -f -find . -name '*.o' | xargs rm -f -find . -name '*.orig' | xargs rm -f -find . -name '*.po' | xargs rm -f -find . -name '*.rej' | xargs rm -f -find . -name '*~' | xargs rm -f -find . -name '.depend' | xargs rm -f -find . -name '.deps' | xargs rm -rf -find . -name '.dirstamp' | xargs rm -f -find . -name '.libs' | xargs rm -rf -find . -name 'CMakeFiles' | xargs rm -rf -find . -name 'cmake_install.cmake' | xargs rm -f -find . -name 'CTestTestfile.cmake' | xargs rm -f - -rm -rf Testing -rm -rf autom4te.cache -rm -rf bin -rm -rf cmake.tmp -rm -rf libarchive/Testing - -rm -f CMakeCache.txt -rm -f DartConfiguration.tcl -rm -f Makefile -rm -f Makefile.in -rm -f aclocal.m4 -rm -f bsdcpio -rm -f bsdcpio_test -rm -f bsdtar -rm -f bsdtar_test -rm -f build/autoconf/compile -rm -f build/autoconf/config.guess -rm -f build/autoconf/config.sub -rm -f build/autoconf/depcomp -rm -f build/autoconf/install-sh -rm -f build/autoconf/libtool.m4 -rm -f build/autoconf/ltmain.sh -rm -f build/autoconf/ltoptions.m4 -rm -f build/autoconf/ltsugar.m4 -rm -f build/autoconf/ltversion.m4 -rm -f build/autoconf/lt~obsolete.m4 -rm -f build/autoconf/missing -rm -f build/autoconf/test-driver -rm -f build/pkgconfig/libarchive.pc -rm -f build/version.old -rm -f cat/test/list.h -rm -f config.h -rm -f config.h.in -rm -f config.log -rm -f config.status -rm -f configure -rm -f cpio/*.1.gz -rm -f cpio/Makefile -rm -f cpio/bsdcpio -rm -f cpio/test/Makefile -rm -f cpio/test/bsdcpio_test -rm -f cpio/test/list.h -rm -f doc/html/* -rm -f doc/man/* -rm -f doc/pdf/* -rm -f doc/text/* -rm -f doc/wiki/* -rm -f libarchive/*.[35].gz -rm -f libarchive/Makefile -rm -f libarchive/libarchive.so* -rm -f libarchive/test/Makefile -rm -f libarchive/test/libarchive_test -rm -f libarchive/test/list.h -rm -f libarchive_test -rm -f libtool -rm -f stamp-h1 -rm -f tar/*.1.gz -rm -f tar/Makefile -rm -f tar/bsdtar -rm -f tar/test/Makefile -rm -f tar/test/bsdtar_test -rm -f tar/test/list.h diff --git a/thirdparty/libarchive/build/cmake/CheckFileOffsetBits.c b/thirdparty/libarchive/build/cmake/CheckFileOffsetBits.c deleted file mode 100644 index d948fecf2..000000000 --- a/thirdparty/libarchive/build/cmake/CheckFileOffsetBits.c +++ /dev/null @@ -1,14 +0,0 @@ -#include - -#define KB ((off_t)1024) -#define MB ((off_t)1024 * KB) -#define GB ((off_t)1024 * MB) -#define TB ((off_t)1024 * GB) -int t2[(((64 * GB -1) % 671088649) == 268434537) - && (((TB - (64 * GB -1) + 255) % 1792151290) == 305159546)? 1: -1]; - -int main() -{ - ; - return 0; -} diff --git a/thirdparty/libarchive/build/cmake/CheckFileOffsetBits.cmake b/thirdparty/libarchive/build/cmake/CheckFileOffsetBits.cmake deleted file mode 100644 index b347c9366..000000000 --- a/thirdparty/libarchive/build/cmake/CheckFileOffsetBits.cmake +++ /dev/null @@ -1,44 +0,0 @@ -# - Check if _FILE_OFFSET_BITS macro needed for large files -# CHECK_FILE_OFFSET_BITS () -# -# The following variables may be set before calling this macro to -# modify the way the check is run: -# -# CMAKE_REQUIRED_FLAGS = string of compile command line flags -# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar) -# CMAKE_REQUIRED_INCLUDES = list of include directories -# Copyright (c) 2009, Michihiro NAKAJIMA -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - -#INCLUDE(CheckCXXSourceCompiles) - -GET_FILENAME_COMPONENT(_selfdir_CheckFileOffsetBits - "${CMAKE_CURRENT_LIST_FILE}" PATH) - -MACRO (CHECK_FILE_OFFSET_BITS) - IF(NOT DEFINED _FILE_OFFSET_BITS) - MESSAGE(STATUS "Checking _FILE_OFFSET_BITS for large files") - TRY_COMPILE(__WITHOUT_FILE_OFFSET_BITS_64 - ${CMAKE_CURRENT_BINARY_DIR} - ${_selfdir_CheckFileOffsetBits}/CheckFileOffsetBits.c - COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}) - IF(NOT __WITHOUT_FILE_OFFSET_BITS_64) - TRY_COMPILE(__WITH_FILE_OFFSET_BITS_64 - ${CMAKE_CURRENT_BINARY_DIR} - ${_selfdir_CheckFileOffsetBits}/CheckFileOffsetBits.c - COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} -D_FILE_OFFSET_BITS=64) - ENDIF(NOT __WITHOUT_FILE_OFFSET_BITS_64) - - IF(NOT __WITHOUT_FILE_OFFSET_BITS_64 AND __WITH_FILE_OFFSET_BITS_64) - SET(_FILE_OFFSET_BITS 64 CACHE INTERNAL "_FILE_OFFSET_BITS macro needed for large files") - MESSAGE(STATUS "Checking _FILE_OFFSET_BITS for large files - needed") - ELSE(NOT __WITHOUT_FILE_OFFSET_BITS_64 AND __WITH_FILE_OFFSET_BITS_64) - SET(_FILE_OFFSET_BITS "" CACHE INTERNAL "_FILE_OFFSET_BITS macro needed for large files") - MESSAGE(STATUS "Checking _FILE_OFFSET_BITS for large files - not needed") - ENDIF(NOT __WITHOUT_FILE_OFFSET_BITS_64 AND __WITH_FILE_OFFSET_BITS_64) - ENDIF(NOT DEFINED _FILE_OFFSET_BITS) - -ENDMACRO (CHECK_FILE_OFFSET_BITS) - diff --git a/thirdparty/libarchive/build/cmake/CheckFuncs.cmake b/thirdparty/libarchive/build/cmake/CheckFuncs.cmake deleted file mode 100644 index 0670df97f..000000000 --- a/thirdparty/libarchive/build/cmake/CheckFuncs.cmake +++ /dev/null @@ -1,49 +0,0 @@ -# Check if the system has the specified function; treat glibc "stub" -# functions as nonexistent: -# CHECK_FUNCTION_EXISTS_GLIBC (FUNCTION FUNCVAR) -# -# FUNCTION - the function(s) where the prototype should be declared -# FUNCVAR - variable to define if the function does exist -# -# In particular, this understands the glibc convention of -# defining macros __stub_XXXX or __stub___XXXX if the function -# does appear in the library but is merely a stub that does nothing. -# By detecting this case, we can select alternate behavior on -# platforms that don't support this functionality. -# -# The following variables may be set before calling this macro to -# modify the way the check is run: -# -# CMAKE_REQUIRED_FLAGS = string of compile command line flags -# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar) -# CMAKE_REQUIRED_INCLUDES = list of include directories -# Copyright (c) 2009, Michihiro NAKAJIMA -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - -INCLUDE(CheckFunctionExists) -GET_FILENAME_COMPONENT(_selfdir_CheckFunctionExistsGlibc - "${CMAKE_CURRENT_LIST_FILE}" PATH) - -MACRO (CHECK_FUNCTION_EXISTS_GLIBC _FUNC _FUNCVAR) - IF(NOT DEFINED ${_FUNCVAR}) - SET(CHECK_STUB_FUNC_1 "__stub_${_FUNC}") - SET(CHECK_STUB_FUNC_2 "__stub___${_FUNC}") - CONFIGURE_FILE( ${_selfdir_CheckFunctionExistsGlibc}/CheckFuncs_stub.c.in - ${CMAKE_CURRENT_BINARY_DIR}/cmake.tmp/CheckFuncs_stub.c IMMEDIATE) - TRY_COMPILE(__stub - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_BINARY_DIR}/cmake.tmp/CheckFuncs_stub.c - COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} - CMAKE_FLAGS - -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_INCLUDE_FILE_FLAGS} - "${CHECK_INCLUDE_FILE_C_INCLUDE_DIRS}") - IF (__stub) - SET("${_FUNCVAR}" "" CACHE INTERNAL "Have function ${_FUNC}") - ELSE (__stub) - CHECK_FUNCTION_EXISTS("${_FUNC}" "${_FUNCVAR}") - ENDIF (__stub) - ENDIF(NOT DEFINED ${_FUNCVAR}) -ENDMACRO (CHECK_FUNCTION_EXISTS_GLIBC) - diff --git a/thirdparty/libarchive/build/cmake/CheckFuncs_stub.c.in b/thirdparty/libarchive/build/cmake/CheckFuncs_stub.c.in deleted file mode 100644 index 50da414b5..000000000 --- a/thirdparty/libarchive/build/cmake/CheckFuncs_stub.c.in +++ /dev/null @@ -1,16 +0,0 @@ -#ifdef __STDC__ -#include -#else -#include -#endif - -int -main() -{ -#if defined ${CHECK_STUB_FUNC_1} || defined ${CHECK_STUB_FUNC_2} - return 0; -#else -this system have stub - return 0; -#endif -} diff --git a/thirdparty/libarchive/build/cmake/CheckHeaderDirent.cmake b/thirdparty/libarchive/build/cmake/CheckHeaderDirent.cmake deleted file mode 100644 index e9a7ea855..000000000 --- a/thirdparty/libarchive/build/cmake/CheckHeaderDirent.cmake +++ /dev/null @@ -1,32 +0,0 @@ -# - Check if the system has the specified type -# CHECK_HEADER_DIRENT (HEADER1 HEARDER2 ...) -# -# HEADER - the header(s) where the prototype should be declared -# -# The following variables may be set before calling this macro to -# modify the way the check is run: -# -# CMAKE_REQUIRED_FLAGS = string of compile command line flags -# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar) -# CMAKE_REQUIRED_INCLUDES = list of include directories -# Copyright (c) 2009, Michihiro NAKAJIMA -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - - -INCLUDE(CheckTypeExists) - -MACRO (CHECK_HEADER_DIRENT) - CHECK_TYPE_EXISTS("DIR *" dirent.h HAVE_DIRENT_H) - IF(NOT HAVE_DIRENT_H) - CHECK_TYPE_EXISTS("DIR *" sys/ndir.h HAVE_SYS_NDIR_H) - IF(NOT HAVE_SYS_NDIR_H) - CHECK_TYPE_EXISTS("DIR *" ndir.h HAVE_NDIR_H) - IF(NOT HAVE_NDIR_H) - CHECK_TYPE_EXISTS("DIR *" sys/dir.h HAVE_SYS_DIR_H) - ENDIF(NOT HAVE_NDIR_H) - ENDIF(NOT HAVE_SYS_NDIR_H) - ENDIF(NOT HAVE_DIRENT_H) -ENDMACRO (CHECK_HEADER_DIRENT) - diff --git a/thirdparty/libarchive/build/cmake/CheckTypeExists.cmake b/thirdparty/libarchive/build/cmake/CheckTypeExists.cmake deleted file mode 100644 index b05234fd8..000000000 --- a/thirdparty/libarchive/build/cmake/CheckTypeExists.cmake +++ /dev/null @@ -1,42 +0,0 @@ -# - Check if the system has the specified type -# CHECK_TYPE_EXISTS (TYPE HEADER VARIABLE) -# -# TYPE - the name of the type or struct or class you are interested in -# HEADER - the header(s) where the prototype should be declared -# VARIABLE - variable to store the result -# -# The following variables may be set before calling this macro to -# modify the way the check is run: -# -# CMAKE_REQUIRED_FLAGS = string of compile command line flags -# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar) -# CMAKE_REQUIRED_INCLUDES = list of include directories -# Copyright (c) 2009, Michihiro NAKAJIMA -# Copyright (c) 2006, Alexander Neundorf, -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. - - -INCLUDE(CheckCSourceCompiles) - -MACRO (CHECK_TYPE_EXISTS _TYPE _HEADER _RESULT) - SET(_INCLUDE_FILES) - FOREACH (it ${_HEADER}) - SET(_INCLUDE_FILES "${_INCLUDE_FILES}#include <${it}>\n") - ENDFOREACH (it) - - SET(_CHECK_TYPE_EXISTS_SOURCE_CODE " -${_INCLUDE_FILES} -int main() -{ - static ${_TYPE} tmp; - if (sizeof(tmp)) - return 0; - return 0; -} -") - CHECK_C_SOURCE_COMPILES("${_CHECK_TYPE_EXISTS_SOURCE_CODE}" ${_RESULT}) - -ENDMACRO (CHECK_TYPE_EXISTS) - diff --git a/thirdparty/libarchive/build/cmake/CreatePkgConfigFile.cmake b/thirdparty/libarchive/build/cmake/CreatePkgConfigFile.cmake deleted file mode 100644 index bc5a43f72..000000000 --- a/thirdparty/libarchive/build/cmake/CreatePkgConfigFile.cmake +++ /dev/null @@ -1,33 +0,0 @@ -# - Generate a libarchive.pc like autotools for pkg-config -# - -# Set the required variables (we use the same input file as autotools) -SET(prefix ${CMAKE_INSTALL_PREFIX}) -SET(exec_prefix \${prefix}) -SET(libdir \${exec_prefix}/lib) -SET(includedir \${prefix}/include) -# Now, this is not particularly pretty, nor is it terribly accurate... -# Loop over all our additional libs -FOREACH(mylib ${ADDITIONAL_LIBS}) - # Extract the filename from the absolute path - GET_FILENAME_COMPONENT(mylib_name ${mylib} NAME_WE) - # Strip the lib prefix - STRING(REGEX REPLACE "^lib" "" mylib_name ${mylib_name}) - # Append it to our LIBS string - SET(LIBS "${LIBS} -l${mylib_name}") -ENDFOREACH() -# libxml2 is easier, since it's already using pkg-config -FOREACH(mylib ${PC_LIBXML_STATIC_LDFLAGS}) - SET(LIBS "${LIBS} ${mylib}") -ENDFOREACH() -# FIXME: The order of the libraries doesn't take dependencies into account, -# thus there's a good chance it'll make some binutils versions unhappy... -# This only affects Libs.private (looked up for static builds) though. -CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/build/pkgconfig/libarchive.pc.in - ${CMAKE_CURRENT_BINARY_DIR}/build/pkgconfig/libarchive.pc - @ONLY) -# And install it, of course ;). -IF(ENABLE_INSTALL) - INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/build/pkgconfig/libarchive.pc - DESTINATION "lib/pkgconfig") -ENDIF() diff --git a/thirdparty/libarchive/build/cmake/FindLIBGCC.cmake b/thirdparty/libarchive/build/cmake/FindLIBGCC.cmake deleted file mode 100644 index 5883ff802..000000000 --- a/thirdparty/libarchive/build/cmake/FindLIBGCC.cmake +++ /dev/null @@ -1,22 +0,0 @@ -# - Find libgcc -# Find the libgcc library. -# -# LIBGCC_LIBRARIES - List of libraries when using libgcc -# LIBGCC_FOUND - True if libgcc found. - -IF (LIBGCC_LIBRARY) - # Already in cache, be silent - SET(LIBGCC_FIND_QUIETLY TRUE) -ENDIF (LIBGCC_LIBRARY) - -FIND_LIBRARY(LIBGCC_LIBRARY NAMES gcc libgcc) - -# handle the QUIETLY and REQUIRED arguments and set LIBGCC_FOUND to TRUE if -# all listed variables are TRUE -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBGCC DEFAULT_MSG LIBGCC_LIBRARY) - -IF(LIBGCC_FOUND) - SET(LIBGCC_LIBRARIES ${LIBGCC_LIBRARY}) - SET(HAVE_LIBGCC 1) -ENDIF(LIBGCC_FOUND) diff --git a/thirdparty/libarchive/build/cmake/FindMbedTLS.cmake b/thirdparty/libarchive/build/cmake/FindMbedTLS.cmake deleted file mode 100644 index aa40485c3..000000000 --- a/thirdparty/libarchive/build/cmake/FindMbedTLS.cmake +++ /dev/null @@ -1,13 +0,0 @@ -find_path(MBEDTLS_INCLUDE_DIRS mbedtls/ssl.h) - -find_library(MBEDTLS_LIBRARY mbedtls) -find_library(MBEDX509_LIBRARY mbedx509) -find_library(MBEDCRYPTO_LIBRARY mbedcrypto) - -set(MBEDTLS_LIBRARIES "${MBEDTLS_LIBRARY}" "${MBEDX509_LIBRARY}" "${MBEDCRYPTO_LIBRARY}") - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(MbedTLS DEFAULT_MSG - MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY) - -mark_as_advanced(MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY) diff --git a/thirdparty/libarchive/build/cmake/FindNettle.cmake b/thirdparty/libarchive/build/cmake/FindNettle.cmake deleted file mode 100644 index 54ec9f5d3..000000000 --- a/thirdparty/libarchive/build/cmake/FindNettle.cmake +++ /dev/null @@ -1,23 +0,0 @@ -# - Find Nettle -# Find the Nettle include directory and library -# -# NETTLE_INCLUDE_DIR - where to find , etc. -# NETTLE_LIBRARIES - List of libraries when using libnettle. -# NETTLE_FOUND - True if libnettle found. - -IF (NETTLE_INCLUDE_DIR) - # Already in cache, be silent - SET(NETTLE_FIND_QUIETLY TRUE) -ENDIF (NETTLE_INCLUDE_DIR) - -FIND_PATH(NETTLE_INCLUDE_DIR nettle/md5.h nettle/ripemd160.h nettle/sha.h) -FIND_LIBRARY(NETTLE_LIBRARY NAMES nettle libnettle) - -# handle the QUIETLY and REQUIRED arguments and set NETTLE_FOUND to TRUE if -# all listed variables are TRUE -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(NETTLE DEFAULT_MSG NETTLE_LIBRARY NETTLE_INCLUDE_DIR) - -IF(NETTLE_FOUND) - SET(NETTLE_LIBRARIES ${NETTLE_LIBRARY}) -ENDIF(NETTLE_FOUND) diff --git a/thirdparty/libarchive/build/cmake/FindPCREPOSIX.cmake b/thirdparty/libarchive/build/cmake/FindPCREPOSIX.cmake deleted file mode 100644 index 56cc17eac..000000000 --- a/thirdparty/libarchive/build/cmake/FindPCREPOSIX.cmake +++ /dev/null @@ -1,34 +0,0 @@ -# - Find pcreposix -# Find the native PCRE and PCREPOSIX include and libraries -# -# PCRE_INCLUDE_DIR - where to find pcreposix.h, etc. -# PCREPOSIX_LIBRARIES - List of libraries when using libpcreposix. -# PCRE_LIBRARIES - List of libraries when using libpcre. -# PCREPOSIX_FOUND - True if libpcreposix found. -# PCRE_FOUND - True if libpcre found. - -IF (PCRE_INCLUDE_DIR) - # Already in cache, be silent - SET(PCRE_FIND_QUIETLY TRUE) -ENDIF (PCRE_INCLUDE_DIR) - -FIND_PATH(PCRE_INCLUDE_DIR pcreposix.h) -FIND_LIBRARY(PCREPOSIX_LIBRARY NAMES pcreposix libpcreposix) -FIND_LIBRARY(PCRE_LIBRARY NAMES pcre libpcre) - -# handle the QUIETLY and REQUIRED arguments and set PCREPOSIX_FOUND to TRUE if -# all listed variables are TRUE -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCREPOSIX DEFAULT_MSG PCREPOSIX_LIBRARY PCRE_INCLUDE_DIR) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCRE DEFAULT_MSG PCRE_LIBRARY) - -IF(PCREPOSIX_FOUND) - SET(PCREPOSIX_LIBRARIES ${PCREPOSIX_LIBRARY}) - SET(HAVE_LIBPCREPOSIX 1) - SET(HAVE_PCREPOSIX_H 1) -ENDIF(PCREPOSIX_FOUND) - -IF(PCRE_FOUND) - SET(PCRE_LIBRARIES ${PCRE_LIBRARY}) - SET(HAVE_LIBPCRE 1) -ENDIF(PCRE_FOUND) diff --git a/thirdparty/libarchive/build/cmake/LibarchiveCodeCoverage.cmake b/thirdparty/libarchive/build/cmake/LibarchiveCodeCoverage.cmake deleted file mode 100644 index 297b886cc..000000000 --- a/thirdparty/libarchive/build/cmake/LibarchiveCodeCoverage.cmake +++ /dev/null @@ -1,68 +0,0 @@ -################################################################# -# Adds a build target called "coverage" for code coverage. -# -# This compiles the code using special GCC flags, run the tests, -# and then generates a nice HTML output. This new "coverage" make -# target will only be available if you build using GCC in Debug -# mode. If any of the required programs (lcov and genhtml) were -# not found, a FATAL_ERROR message is printed. -# -# If not already done, this code will set ENABLE_TEST to ON. -# -# To build the code coverage and open it in your browser do this: -# -# mkdir debug -# cd debug -# cmake -DCMAKE_BUILD_TYPE=Debug -DENABLE_COVERAGE=ON .. -# make -j4 -# make coverage -# xdg-open coverage/index.html -################################################################# - -# Find programs we need -FIND_PROGRAM(LCOV_EXECUTABLE lcov DOC "Full path to lcov executable") -FIND_PROGRAM(GENHTML_EXECUTABLE genhtml DOC "Full path to genhtml executable") -MARK_AS_ADVANCED(LCOV_EXECUTABLE GENHTML_EXECUTABLE) - -# Check, compiler, build types and programs are available -IF(NOT CMAKE_COMPILER_IS_GNUCC) -MESSAGE(FATAL_ERROR "Coverage can only be built on GCC") -ELSEIF(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") -MESSAGE(FATAL_ERROR "Coverage can only be built in Debug mode") -ELSEIF(NOT LCOV_EXECUTABLE) -MESSAGE(FATAL_ERROR "lcov executable not found") -ELSEIF(NOT GENHTML_EXECUTABLE) -MESSAGE(FATAL_ERROR "genhtml executable not found") -ENDIF(NOT CMAKE_COMPILER_IS_GNUCC) - -# Enable testing if not already done -SET(ENABLE_TEST ON) - -################################################################# -# Set special compiler and linker flags for test coverage -################################################################# -# 0. Enable debug: -g -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g") -# 1. Disable optimizations: -O0 -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0") -# 2. Enable all kind of warnings: -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -W") -# 3. Enable special coverage flag (HINT: --coverage is a synonym for -fprofile-arcs -ftest-coverage) -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage") -SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --coverage") -SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage") -################################################################# - -ADD_CUSTOM_TARGET(coverage -COMMAND ${CMAKE_COMMAND} -E echo "Beginning test coverage. Output is written to coverage.log." -COMMAND ${CMAKE_COMMAND} -E echo "COVERAGE-STEP-1/5: Reset all execution counts to zero" -COMMAND ${LCOV_EXECUTABLE} --directory . --zerocounters > coverage.log 2>&1 -COMMAND ${CMAKE_COMMAND} -E echo "COVERAGE-STEP-2/5: Run testrunner" -COMMAND ${CMAKE_CTEST_COMMAND} >> coverage.log 2>&1 -COMMAND ${CMAKE_COMMAND} -E echo "COVERAGE-STEP-3/5: Collect coverage data" -COMMAND ${LCOV_EXECUTABLE} --capture --directory . --output-file "./coverage.info" >> coverage.log 2>&1 -COMMAND ${CMAKE_COMMAND} -E echo "COVERAGE-STEP-4/5: Generate HTML from coverage data" -COMMAND ${GENHTML_EXECUTABLE} "coverage.info" --title="libarchive-${LIBARCHIVE_VERSION_STRING}" --show-details --legend --output-directory "./coverage" >> coverage.log 2>&1 -COMMAND ${CMAKE_COMMAND} -E echo "COVERAGE-STEP-5/5: Open test coverage HTML output in browser: xdg-open ./coverage/index.html" -COMMENT "Runs testrunner and generates coverage output (formats: .info and .html)") - diff --git a/thirdparty/libarchive/build/cmake/config.h.in b/thirdparty/libarchive/build/cmake/config.h.in deleted file mode 100644 index 71d54a4ce..000000000 --- a/thirdparty/libarchive/build/cmake/config.h.in +++ /dev/null @@ -1,1400 +0,0 @@ -/* config.h. Generated from build/cmake/config.h.in by cmake configure */ -#define __LIBARCHIVE_CONFIG_H_INCLUDED 1 - -/* - * Ensure we have C99-style int64_t, etc, all defined. - */ - -/* First, we need to know if the system has already defined them. */ -#cmakedefine HAVE_INT16_T -#cmakedefine HAVE_INT32_T -#cmakedefine HAVE_INT64_T -#cmakedefine HAVE_INTMAX_T - -#cmakedefine HAVE_UINT8_T -#cmakedefine HAVE_UINT16_T -#cmakedefine HAVE_UINT32_T -#cmakedefine HAVE_UINT64_T -#cmakedefine HAVE_UINTMAX_T - -/* We might have the types we want under other spellings. */ -#cmakedefine HAVE___INT64 -#cmakedefine HAVE_U_INT64_T -#cmakedefine HAVE_UNSIGNED___INT64 - -/* The sizes of various standard integer types. */ -@SIZEOF_SHORT_CODE@ -@SIZEOF_INT_CODE@ -@SIZEOF_LONG_CODE@ -@SIZEOF_LONG_LONG_CODE@ -@SIZEOF_UNSIGNED_SHORT_CODE@ -@SIZEOF_UNSIGNED_CODE@ -@SIZEOF_UNSIGNED_LONG_CODE@ -@SIZEOF_UNSIGNED_LONG_LONG_CODE@ - -/* - * If we lack int64_t, define it to the first of __int64, int, long, and long long - * that exists and is the right size. - */ -#if !defined(HAVE_INT64_T) && defined(HAVE___INT64) -typedef __int64 int64_t; -#define HAVE_INT64_T -#endif - -#if !defined(HAVE_INT64_T) && SIZEOF_INT == 8 -typedef int int64_t; -#define HAVE_INT64_T -#endif - -#if !defined(HAVE_INT64_T) && SIZEOF_LONG == 8 -typedef long int64_t; -#define HAVE_INT64_T -#endif - -#if !defined(HAVE_INT64_T) && SIZEOF_LONG_LONG == 8 -typedef long long int64_t; -#define HAVE_INT64_T -#endif - -#if !defined(HAVE_INT64_T) -#error No 64-bit integer type was found. -#endif - -/* - * Similarly for int32_t - */ -#if !defined(HAVE_INT32_T) && SIZEOF_INT == 4 -typedef int int32_t; -#define HAVE_INT32_T -#endif - -#if !defined(HAVE_INT32_T) && SIZEOF_LONG == 4 -typedef long int32_t; -#define HAVE_INT32_T -#endif - -#if !defined(HAVE_INT32_T) -#error No 32-bit integer type was found. -#endif - -/* - * Similarly for int16_t - */ -#if !defined(HAVE_INT16_T) && SIZEOF_INT == 2 -typedef int int16_t; -#define HAVE_INT16_T -#endif - -#if !defined(HAVE_INT16_T) && SIZEOF_SHORT == 2 -typedef short int16_t; -#define HAVE_INT16_T -#endif - -#if !defined(HAVE_INT16_T) -#error No 16-bit integer type was found. -#endif - -/* - * Similarly for uint64_t - */ -#if !defined(HAVE_UINT64_T) && defined(HAVE_UNSIGNED___INT64) -typedef unsigned __int64 uint64_t; -#define HAVE_UINT64_T -#endif - -#if !defined(HAVE_UINT64_T) && SIZEOF_UNSIGNED == 8 -typedef unsigned uint64_t; -#define HAVE_UINT64_T -#endif - -#if !defined(HAVE_UINT64_T) && SIZEOF_UNSIGNED_LONG == 8 -typedef unsigned long uint64_t; -#define HAVE_UINT64_T -#endif - -#if !defined(HAVE_UINT64_T) && SIZEOF_UNSIGNED_LONG_LONG == 8 -typedef unsigned long long uint64_t; -#define HAVE_UINT64_T -#endif - -#if !defined(HAVE_UINT64_T) -#error No 64-bit unsigned integer type was found. -#endif - - -/* - * Similarly for uint32_t - */ -#if !defined(HAVE_UINT32_T) && SIZEOF_UNSIGNED == 4 -typedef unsigned uint32_t; -#define HAVE_UINT32_T -#endif - -#if !defined(HAVE_UINT32_T) && SIZEOF_UNSIGNED_LONG == 4 -typedef unsigned long uint32_t; -#define HAVE_UINT32_T -#endif - -#if !defined(HAVE_UINT32_T) -#error No 32-bit unsigned integer type was found. -#endif - -/* - * Similarly for uint16_t - */ -#if !defined(HAVE_UINT16_T) && SIZEOF_UNSIGNED == 2 -typedef unsigned uint16_t; -#define HAVE_UINT16_T -#endif - -#if !defined(HAVE_UINT16_T) && SIZEOF_UNSIGNED_SHORT == 2 -typedef unsigned short uint16_t; -#define HAVE_UINT16_T -#endif - -#if !defined(HAVE_UINT16_T) -#error No 16-bit unsigned integer type was found. -#endif - -/* - * Similarly for uint8_t - */ -#if !defined(HAVE_UINT8_T) -typedef unsigned char uint8_t; -#define HAVE_UINT8_T -#endif - -#if !defined(HAVE_UINT8_T) -#error No 8-bit unsigned integer type was found. -#endif - -/* Define intmax_t and uintmax_t if they are not already defined. */ -#if !defined(HAVE_INTMAX_T) -typedef int64_t intmax_t; -#endif - -#if !defined(HAVE_UINTMAX_T) -typedef uint64_t uintmax_t; -#endif - -/* Define ZLIB_WINAPI if zlib was built on Visual Studio. */ -#cmakedefine ZLIB_WINAPI 1 - -/* Darwin ACL support */ -#cmakedefine ARCHIVE_ACL_DARWIN 1 - -/* FreeBSD ACL support */ -#cmakedefine ARCHIVE_ACL_FREEBSD 1 - -/* FreeBSD NFSv4 ACL support */ -#cmakedefine ARCHIVE_ACL_FREEBSD_NFS4 1 - -/* Linux POSIX.1e ACL support via libacl */ -#cmakedefine ARCHIVE_ACL_LIBACL 1 - -/* Linux NFSv4 ACL support via librichacl */ -#cmakedefine ARCHIVE_ACL_LIBRICHACL 1 - -/* Solaris ACL support */ -#cmakedefine ARCHIVE_ACL_SUNOS 1 - -/* Solaris NFSv4 ACL support */ -#cmakedefine ARCHIVE_ACL_SUNOS_NFS4 1 - -/* MD5 via ARCHIVE_CRYPTO_MD5_LIBC supported. */ -#cmakedefine ARCHIVE_CRYPTO_MD5_LIBC 1 - -/* MD5 via ARCHIVE_CRYPTO_MD5_LIBSYSTEM supported. */ -#cmakedefine ARCHIVE_CRYPTO_MD5_LIBSYSTEM 1 - -/* MD5 via ARCHIVE_CRYPTO_MD5_MBEDTLS supported. */ -#cmakedefine ARCHIVE_CRYPTO_MD5_MBEDTLS 1 - -/* MD5 via ARCHIVE_CRYPTO_MD5_NETTLE supported. */ -#cmakedefine ARCHIVE_CRYPTO_MD5_NETTLE 1 - -/* MD5 via ARCHIVE_CRYPTO_MD5_OPENSSL supported. */ -#cmakedefine ARCHIVE_CRYPTO_MD5_OPENSSL 1 - -/* MD5 via ARCHIVE_CRYPTO_MD5_WIN supported. */ -#cmakedefine ARCHIVE_CRYPTO_MD5_WIN 1 - -/* RMD160 via ARCHIVE_CRYPTO_RMD160_LIBC supported. */ -#cmakedefine ARCHIVE_CRYPTO_RMD160_LIBC 1 - -/* RMD160 via ARCHIVE_CRYPTO_RMD160_NETTLE supported. */ -#cmakedefine ARCHIVE_CRYPTO_RMD160_NETTLE 1 - -/* RMD160 via ARCHIVE_CRYPTO_RMD160_MBEDTLS supported. */ -#cmakedefine ARCHIVE_CRYPTO_RMD160_MBEDTLS 1 - -/* RMD160 via ARCHIVE_CRYPTO_RMD160_OPENSSL supported. */ -#cmakedefine ARCHIVE_CRYPTO_RMD160_OPENSSL 1 - -/* SHA1 via ARCHIVE_CRYPTO_SHA1_LIBC supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA1_LIBC 1 - -/* SHA1 via ARCHIVE_CRYPTO_SHA1_LIBSYSTEM supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA1_LIBSYSTEM 1 - -/* SHA1 via ARCHIVE_CRYPTO_SHA1_MBEDTLS supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA1_MBEDTLS 1 - -/* SHA1 via ARCHIVE_CRYPTO_SHA1_NETTLE supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA1_NETTLE 1 - -/* SHA1 via ARCHIVE_CRYPTO_SHA1_OPENSSL supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA1_OPENSSL 1 - -/* SHA1 via ARCHIVE_CRYPTO_SHA1_WIN supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA1_WIN 1 - -/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBC supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA256_LIBC 1 - -/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBC2 supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA256_LIBC2 1 - -/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBC3 supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA256_LIBC3 1 - -/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBSYSTEM supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA256_LIBSYSTEM 1 - -/* SHA256 via ARCHIVE_CRYPTO_SHA256_MBEDTLS supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA256_MBEDTLS 1 - -/* SHA256 via ARCHIVE_CRYPTO_SHA256_NETTLE supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA256_NETTLE 1 - -/* SHA256 via ARCHIVE_CRYPTO_SHA256_OPENSSL supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA256_OPENSSL 1 - -/* SHA256 via ARCHIVE_CRYPTO_SHA256_WIN supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA256_WIN 1 - -/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBC supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA384_LIBC 1 - -/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBC2 supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA384_LIBC2 1 - -/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBC3 supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA384_LIBC3 1 - -/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBSYSTEM supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA384_LIBSYSTEM 1 - -/* SHA384 via ARCHIVE_CRYPTO_SHA384_MBEDTLS supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA384_MBEDTLS 1 - -/* SHA384 via ARCHIVE_CRYPTO_SHA384_NETTLE supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA384_NETTLE 1 - -/* SHA384 via ARCHIVE_CRYPTO_SHA384_OPENSSL supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA384_OPENSSL 1 - -/* SHA384 via ARCHIVE_CRYPTO_SHA384_WIN supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA384_WIN 1 - -/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBC supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA512_LIBC 1 - -/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBC2 supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA512_LIBC2 1 - -/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBC3 supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA512_LIBC3 1 - -/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBSYSTEM supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA512_LIBSYSTEM 1 - -/* SHA512 via ARCHIVE_CRYPTO_SHA512_MBEDTLS supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA512_MBEDTLS 1 - -/* SHA512 via ARCHIVE_CRYPTO_SHA512_NETTLE supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA512_NETTLE 1 - -/* SHA512 via ARCHIVE_CRYPTO_SHA512_OPENSSL supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA512_OPENSSL 1 - -/* SHA512 via ARCHIVE_CRYPTO_SHA512_WIN supported. */ -#cmakedefine ARCHIVE_CRYPTO_SHA512_WIN 1 - -/* AIX xattr support */ -#cmakedefine ARCHIVE_XATTR_AIX 1 - -/* Darwin xattr support */ -#cmakedefine ARCHIVE_XATTR_DARWIN 1 - -/* FreeBSD xattr support */ -#cmakedefine ARCHIVE_XATTR_FREEBSD 1 - -/* Linux xattr support */ -#cmakedefine ARCHIVE_XATTR_LINUX 1 - -/* Version number of bsdcpio */ -#cmakedefine BSDCPIO_VERSION_STRING "@BSDCPIO_VERSION_STRING@" - -/* Version number of bsdtar */ -#cmakedefine BSDTAR_VERSION_STRING "@BSDTAR_VERSION_STRING@" - -/* Version number of bsdcat */ -#cmakedefine BSDCAT_VERSION_STRING "@BSDCAT_VERSION_STRING@" - -/* Version number of bsdunzip */ -#cmakedefine BSDUNZIP_VERSION_STRING "@BSDUNZIP_VERSION_STRING@" - -/* Define to 1 if you have the `acl_create_entry' function. */ -#cmakedefine HAVE_ACL_CREATE_ENTRY 1 - -/* Define to 1 if you have the `acl_get_fd_np' function. */ -#cmakedefine HAVE_ACL_GET_FD_NP 1 - -/* Define to 1 if you have the `acl_get_link' function. */ -#cmakedefine HAVE_ACL_GET_LINK 1 - -/* Define to 1 if you have the `acl_get_link_np' function. */ -#cmakedefine HAVE_ACL_GET_LINK_NP 1 - -/* Define to 1 if you have the `acl_get_perm' function. */ -#cmakedefine HAVE_ACL_GET_PERM 1 - -/* Define to 1 if you have the `acl_get_perm_np' function. */ -#cmakedefine HAVE_ACL_GET_PERM_NP 1 - -/* Define to 1 if you have the `acl_init' function. */ -#cmakedefine HAVE_ACL_INIT 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_ACL_LIBACL_H 1 - -/* Define to 1 if the system has the type `acl_permset_t'. */ -#cmakedefine HAVE_ACL_PERMSET_T 1 - -/* Define to 1 if you have the `acl_set_fd' function. */ -#cmakedefine HAVE_ACL_SET_FD 1 - -/* Define to 1 if you have the `acl_set_fd_np' function. */ -#cmakedefine HAVE_ACL_SET_FD_NP 1 - -/* Define to 1 if you have the `acl_set_file' function. */ -#cmakedefine HAVE_ACL_SET_FILE 1 - -/* Define to 1 if you have the `arc4random_buf' function. */ -#cmakedefine HAVE_ARC4RANDOM_BUF 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_ATTR_XATTR_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_BCRYPT_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_BSDXML_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_BZLIB_H 1 - -/* Define to 1 if you have the `chflags' function. */ -#cmakedefine HAVE_CHFLAGS 1 - -/* Define to 1 if you have the `chown' function. */ -#cmakedefine HAVE_CHOWN 1 - -/* Define to 1 if you have the `chroot' function. */ -#cmakedefine HAVE_CHROOT 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_COPYFILE_H 1 - -/* Define to 1 if you have the `ctime_r' function. */ -#cmakedefine HAVE_CTIME_R 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_CTYPE_H 1 - -/* Define to 1 if you have the `cygwin_conv_path' function. */ -#cmakedefine HAVE_CYGWIN_CONV_PATH 1 - -/* Define to 1 if you have the declaration of `ACE_GETACL', and to 0 if you - don't. */ -#cmakedefine HAVE_DECL_ACE_GETACL 1 - -/* Define to 1 if you have the declaration of `ACE_GETACLCNT', and to 0 if you - don't. */ -#cmakedefine HAVE_DECL_ACE_GETACLCNT 1 - -/* Define to 1 if you have the declaration of `ACE_SETACL', and to 0 if you - don't. */ -#cmakedefine HAVE_DECL_ACE_SETACL 1 - -/* Define to 1 if you have the declaration of `ACL_SYNCHRONIZE', and to 0 if - you don't. */ -#cmakedefine HAVE_DECL_ACL_SYNCHRONIZE 1 - -/* Define to 1 if you have the declaration of `ACL_TYPE_EXTENDED', and to 0 if - you don't. */ -#cmakedefine HAVE_DECL_ACL_TYPE_EXTENDED 1 - -/* Define to 1 if you have the declaration of `ACL_TYPE_NFS4', and to 0 if you - don't. */ -#cmakedefine HAVE_DECL_ACL_TYPE_NFS4 1 - -/* Define to 1 if you have the declaration of `ACL_USER', and to 0 if you - don't. */ -#cmakedefine HAVE_DECL_ACL_USER 1 - -/* Define to 1 if you have the declaration of `INT32_MAX', and to 0 if you - don't. */ -#cmakedefine HAVE_DECL_INT32_MAX 1 - -/* Define to 1 if you have the declaration of `INT32_MIN', and to 0 if you - don't. */ -#cmakedefine HAVE_DECL_INT32_MIN 1 - -/* Define to 1 if you have the declaration of `INT64_MAX', and to 0 if you - don't. */ -#cmakedefine HAVE_DECL_INT64_MAX 1 - -/* Define to 1 if you have the declaration of `INT64_MIN', and to 0 if you - don't. */ -#cmakedefine HAVE_DECL_INT64_MIN 1 - -/* Define to 1 if you have the declaration of `INTMAX_MAX', and to 0 if you - don't. */ -#cmakedefine HAVE_DECL_INTMAX_MAX 1 - -/* Define to 1 if you have the declaration of `INTMAX_MIN', and to 0 if you - don't. */ -#cmakedefine HAVE_DECL_INTMAX_MIN 1 - -/* Define to 1 if you have the declaration of `SETACL', and to 0 if you don't. - */ -#cmakedefine HAVE_DECL_SETACL 1 - -/* Define to 1 if you have the declaration of `SIZE_MAX', and to 0 if you - don't. */ -#cmakedefine HAVE_DECL_SIZE_MAX 1 - -/* Define to 1 if you have the declaration of `SSIZE_MAX', and to 0 if you - don't. */ -#cmakedefine HAVE_DECL_SSIZE_MAX 1 - -/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you - don't. */ -#cmakedefine HAVE_DECL_STRERROR_R 1 - -/* Define to 1 if you have the declaration of `UINT32_MAX', and to 0 if you - don't. */ -#cmakedefine HAVE_DECL_UINT32_MAX 1 - -/* Define to 1 if you have the declaration of `UINT64_MAX', and to 0 if you - don't. */ -#cmakedefine HAVE_DECL_UINT64_MAX 1 - -/* Define to 1 if you have the declaration of `UINTMAX_MAX', and to 0 if you - don't. */ -#cmakedefine HAVE_DECL_UINTMAX_MAX 1 - -/* Define to 1 if you have the declaration of `XATTR_NOFOLLOW', and to 0 if - you don't. */ -#cmakedefine HAVE_DECL_XATTR_NOFOLLOW 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_DIRECT_H 1 - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -#cmakedefine HAVE_DIRENT_H 1 - -/* Define to 1 if you have the `dirfd' function. */ -#cmakedefine HAVE_DIRFD 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_DLFCN_H 1 - -/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ -#cmakedefine HAVE_DOPRNT 1 - -/* Define to 1 if nl_langinfo supports D_MD_ORDER */ -#cmakedefine HAVE_D_MD_ORDER 1 - -/* A possible errno value for invalid file format errors */ -#cmakedefine HAVE_EFTYPE 1 - -/* A possible errno value for invalid file format errors */ -#cmakedefine HAVE_EILSEQ 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_ERRNO_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_EXPAT_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_EXT2FS_EXT2_FS_H 1 - -/* Define to 1 if you have the `extattr_get_file' function. */ -#cmakedefine HAVE_EXTATTR_GET_FILE 1 - -/* Define to 1 if you have the `extattr_list_file' function. */ -#cmakedefine HAVE_EXTATTR_LIST_FILE 1 - -/* Define to 1 if you have the `extattr_set_fd' function. */ -#cmakedefine HAVE_EXTATTR_SET_FD 1 - -/* Define to 1 if you have the `extattr_set_file' function. */ -#cmakedefine HAVE_EXTATTR_SET_FILE 1 - -/* Define to 1 if EXTATTR_NAMESPACE_USER is defined in sys/extattr.h. */ -#cmakedefine HAVE_DECL_EXTATTR_NAMESPACE_USER 1 - -/* Define to 1 if you have the declaration of `GETACL', and to 0 if you don't. - */ -#cmakedefine HAVE_DECL_GETACL 1 - -/* Define to 1 if you have the declaration of `GETACLCNT', and to 0 if you - don't. */ -#cmakedefine HAVE_DECL_GETACLCNT 1 - -/* Define to 1 if you have the `fchdir' function. */ -#cmakedefine HAVE_FCHDIR 1 - -/* Define to 1 if you have the `fchflags' function. */ -#cmakedefine HAVE_FCHFLAGS 1 - -/* Define to 1 if you have the `fchmod' function. */ -#cmakedefine HAVE_FCHMOD 1 - -/* Define to 1 if you have the `fchown' function. */ -#cmakedefine HAVE_FCHOWN 1 - -/* Define to 1 if you have the `fcntl' function. */ -#cmakedefine HAVE_FCNTL 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_FCNTL_H 1 - -/* Define to 1 if you have the `fdopendir' function. */ -#cmakedefine HAVE_FDOPENDIR 1 - -/* Define to 1 if you have the `fgetea' function. */ -#cmakedefine HAVE_FGETEA 1 - -/* Define to 1 if you have the `fgetxattr' function. */ -#cmakedefine HAVE_FGETXATTR 1 - -/* Define to 1 if you have the `flistea' function. */ -#cmakedefine HAVE_FLISTEA 1 - -/* Define to 1 if you have the `flistxattr' function. */ -#cmakedefine HAVE_FLISTXATTR 1 - -/* Define to 1 if you have the `fnmatch' function. */ -#cmakedefine HAVE_FNMATCH 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_FNMATCH_H 1 - -/* Define to 1 if you have the `fork' function. */ -#cmakedefine HAVE_FORK 1 - -/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ -#cmakedefine HAVE_FSEEKO 1 - -/* Define to 1 if you have the `fsetea' function. */ -#cmakedefine HAVE_FSETEA 1 - -/* Define to 1 if you have the `fsetxattr' function. */ -#cmakedefine HAVE_FSETXATTR 1 - -/* Define to 1 if you have the `fstat' function. */ -#cmakedefine HAVE_FSTAT 1 - -/* Define to 1 if you have the `fstatat' function. */ -#cmakedefine HAVE_FSTATAT 1 - -/* Define to 1 if you have the `fstatfs' function. */ -#cmakedefine HAVE_FSTATFS 1 - -/* Define to 1 if you have the `fstatvfs' function. */ -#cmakedefine HAVE_FSTATVFS 1 - -/* Define to 1 if you have the `ftruncate' function. */ -#cmakedefine HAVE_FTRUNCATE 1 - -/* Define to 1 if you have the `futimens' function. */ -#cmakedefine HAVE_FUTIMENS 1 - -/* Define to 1 if you have the `futimes' function. */ -#cmakedefine HAVE_FUTIMES 1 - -/* Define to 1 if you have the `futimesat' function. */ -#cmakedefine HAVE_FUTIMESAT 1 - -/* Define to 1 if you have the `getea' function. */ -#cmakedefine HAVE_GETEA 1 - -/* Define to 1 if you have the `geteuid' function. */ -#cmakedefine HAVE_GETEUID 1 - -/* Define to 1 if you have the `getgrgid_r' function. */ -#cmakedefine HAVE_GETGRGID_R 1 - -/* Define to 1 if you have the `getgrnam_r' function. */ -#cmakedefine HAVE_GETGRNAM_R 1 - -/* Define to 1 if you have the `getline' function. */ -#cmakedefine HAVE_GETLINE 1 - -/* Define to 1 if you have the `getpid' function. */ -#cmakedefine HAVE_GETPID 1 - -/* Define to 1 if you have the `getpwnam_r' function. */ -#cmakedefine HAVE_GETPWNAM_R 1 - -/* Define to 1 if you have the `getpwuid_r' function. */ -#cmakedefine HAVE_GETPWUID_R 1 - -/* Define to 1 if you have the `getvfsbyname' function. */ -#cmakedefine HAVE_GETVFSBYNAME 1 - -/* Define to 1 if you have the `getxattr' function. */ -#cmakedefine HAVE_GETXATTR 1 - -/* Define to 1 if you have the `gmtime_r' function. */ -#cmakedefine HAVE_GMTIME_R 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_GRP_H 1 - -/* Define to 1 if you have the `iconv' function. */ -#cmakedefine HAVE_ICONV 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_ICONV_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_IO_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LANGINFO_H 1 - -/* Define to 1 if you have the `lchflags' function. */ -#cmakedefine HAVE_LCHFLAGS 1 - -/* Define to 1 if you have the `lchmod' function. */ -#cmakedefine HAVE_LCHMOD 1 - -/* Define to 1 if you have the `lchown' function. */ -#cmakedefine HAVE_LCHOWN 1 - -/* Define to 1 if you have the `lgetea' function. */ -#cmakedefine HAVE_LGETEA 1 - -/* Define to 1 if you have the `lgetxattr' function. */ -#cmakedefine HAVE_LGETXATTR 1 - -/* Define to 1 if you have the `acl' library (-lacl). */ -#cmakedefine HAVE_LIBACL 1 - -/* Define to 1 if you have the `attr' library (-lattr). */ -#cmakedefine HAVE_LIBATTR 1 - -/* Define to 1 if you have the `bsdxml' library (-lbsdxml). */ -#cmakedefine HAVE_LIBBSDXML 1 - -/* Define to 1 if you have the `bz2' library (-lbz2). */ -#cmakedefine HAVE_LIBBZ2 1 - -/* Define to 1 if you have the `b2' library (-lb2). */ -#cmakedefine HAVE_LIBB2 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_BLAKE2_H 1 - -/* Define to 1 if you have the `charset' library (-lcharset). */ -#cmakedefine HAVE_LIBCHARSET 1 - -/* Define to 1 if you have the `crypto' library (-lcrypto). */ -#cmakedefine HAVE_LIBCRYPTO 1 - -/* Define to 1 if you have the `expat' library (-lexpat). */ -#cmakedefine HAVE_LIBEXPAT 1 - -/* Define to 1 if you have the `gcc' library (-lgcc). */ -#cmakedefine HAVE_LIBGCC 1 - -/* Define to 1 if you have the `lz4' library (-llz4). */ -#cmakedefine HAVE_LIBLZ4 1 - -/* Define to 1 if you have the `lzma' library (-llzma). */ -#cmakedefine HAVE_LIBLZMA 1 - -/* Define to 1 if you have the `lzmadec' library (-llzmadec). */ -#cmakedefine HAVE_LIBLZMADEC 1 - -/* Define to 1 if you have the `lzo2' library (-llzo2). */ -#cmakedefine HAVE_LIBLZO2 1 - -/* Define to 1 if you have the `mbedcrypto' library (-lmbedcrypto). */ -#cmakedefine HAVE_LIBMBEDCRYPTO 1 - -/* Define to 1 if you have the `nettle' library (-lnettle). */ -#cmakedefine HAVE_LIBNETTLE 1 - -/* Define to 1 if you have the `pcre' library (-lpcre). */ -#cmakedefine HAVE_LIBPCRE 1 - -/* Define to 1 if you have the `pcreposix' library (-lpcreposix). */ -#cmakedefine HAVE_LIBPCREPOSIX 1 - -/* Define to 1 if you have the `xml2' library (-lxml2). */ -#cmakedefine HAVE_LIBXML2 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LIBXML_XMLREADER_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LIBXML_XMLWRITER_H 1 - -/* Define to 1 if you have the `z' library (-lz). */ -#cmakedefine HAVE_LIBZ 1 - -/* Define to 1 if you have the `zstd' library (-lzstd). */ -#cmakedefine HAVE_LIBZSTD 1 - -/* Define to 1 if you have the `zstd' library (-lzstd) with compression - support. */ -#cmakedefine HAVE_LIBZSTD_COMPRESSOR 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LIMITS_H 1 - -/* Define to 1 if you have the `link' function. */ -#cmakedefine HAVE_LINK 1 - -/* Define to 1 if you have the `linkat' function. */ -#cmakedefine HAVE_LINKAT 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LINUX_FIEMAP_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LINUX_FS_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LINUX_MAGIC_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LINUX_TYPES_H 1 - -/* Define to 1 if you have the `listea' function. */ -#cmakedefine HAVE_LISTEA 1 - -/* Define to 1 if you have the `listxattr' function. */ -#cmakedefine HAVE_LISTXATTR 1 - -/* Define to 1 if you have the `llistea' function. */ -#cmakedefine HAVE_LLISTEA 1 - -/* Define to 1 if you have the `llistxattr' function. */ -#cmakedefine HAVE_LLISTXATTR 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LOCALCHARSET_H 1 - -/* Define to 1 if you have the `locale_charset' function. */ -#cmakedefine HAVE_LOCALE_CHARSET 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LOCALE_H 1 - -/* Define to 1 if you have the `localtime_r' function. */ -#cmakedefine HAVE_LOCALTIME_R 1 - -/* Define to 1 if the system has the type `long long int'. */ -#cmakedefine HAVE_LONG_LONG_INT 1 - -/* Define to 1 if you have the `lsetea' function. */ -#cmakedefine HAVE_LSETEA 1 - -/* Define to 1 if you have the `lsetxattr' function. */ -#cmakedefine HAVE_LSETXATTR 1 - -/* Define to 1 if you have the `lstat' function. */ -#cmakedefine HAVE_LSTAT 1 - -/* Define to 1 if `lstat' has the bug that it succeeds when given the - zero-length file name argument. */ -#cmakedefine HAVE_LSTAT_EMPTY_STRING_BUG 1 - -/* Define to 1 if you have the `lutimes' function. */ -#cmakedefine HAVE_LUTIMES 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LZ4HC_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LZ4_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LZMADEC_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LZMA_H 1 - -/* Define to 1 if you have a working `lzma_stream_encoder_mt' function. */ -#cmakedefine HAVE_LZMA_STREAM_ENCODER_MT 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LZO_LZO1X_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LZO_LZOCONF_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_MBEDTLS_AES_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_MBEDTLS_MD_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_MBEDTLS_PKCS5_H 1 - -/* Define to 1 if you have the `mbrtowc' function. */ -#cmakedefine HAVE_MBRTOWC 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_MEMBERSHIP_H 1 - -/* Define to 1 if you have the `memmove' function. */ -#cmakedefine HAVE_MEMMOVE 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_MEMORY_H 1 - -/* Define to 1 if you have the `mkdir' function. */ -#cmakedefine HAVE_MKDIR 1 - -/* Define to 1 if you have the `mkfifo' function. */ -#cmakedefine HAVE_MKFIFO 1 - -/* Define to 1 if you have the `mknod' function. */ -#cmakedefine HAVE_MKNOD 1 - -/* Define to 1 if you have the `mkstemp' function. */ -#cmakedefine HAVE_MKSTEMP 1 - -/* Define to 1 if you have the header file, and it defines `DIR'. */ -#cmakedefine HAVE_NDIR_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_NETTLE_AES_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_NETTLE_HMAC_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_NETTLE_MD5_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_NETTLE_PBKDF2_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_NETTLE_RIPEMD160_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_NETTLE_SHA_H 1 - -/* Define to 1 if you have the `nl_langinfo' function. */ -#cmakedefine HAVE_NL_LANGINFO 1 - -/* Define to 1 if you have the `openat' function. */ -#cmakedefine HAVE_OPENAT 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_OPENSSL_EVP_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_PATHS_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_PCREPOSIX_H 1 - -/* Define to 1 if you have the `pipe' function. */ -#cmakedefine HAVE_PIPE 1 - -/* Define to 1 if you have the `PKCS5_PBKDF2_HMAC_SHA1' function. */ -#cmakedefine HAVE_PKCS5_PBKDF2_HMAC_SHA1 1 - -/* Define to 1 if you have the `poll' function. */ -#cmakedefine HAVE_POLL 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_POLL_H 1 - -/* Define to 1 if you have the `posix_spawnp' function. */ -#cmakedefine HAVE_POSIX_SPAWNP 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_PROCESS_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_PTHREAD_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_PWD_H 1 - -/* Define to 1 if you have the `readdir_r' function. */ -#cmakedefine HAVE_READDIR_R 1 - -/* Define to 1 if you have the `readlink' function. */ -#cmakedefine HAVE_READLINK 1 - -/* Define to 1 if you have the `readlinkat' function. */ -#cmakedefine HAVE_READLINKAT 1 - -/* Define to 1 if you have the `readpassphrase' function. */ -#cmakedefine HAVE_READPASSPHRASE 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_READPASSPHRASE_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_REGEX_H 1 - -/* Define to 1 if you have the `select' function. */ -#cmakedefine HAVE_SELECT 1 - -/* Define to 1 if you have the `setenv' function. */ -#cmakedefine HAVE_SETENV 1 - -/* Define to 1 if you have the `setlocale' function. */ -#cmakedefine HAVE_SETLOCALE 1 - -/* Define to 1 if you have the `sigaction' function. */ -#cmakedefine HAVE_SIGACTION 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SIGNAL_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SPAWN_H 1 - -/* Define to 1 if you have the `statfs' function. */ -#cmakedefine HAVE_STATFS 1 - -/* Define to 1 if you have the `statvfs' function. */ -#cmakedefine HAVE_STATVFS 1 - -/* Define to 1 if `stat' has the bug that it succeeds when given the - zero-length file name argument. */ -#cmakedefine HAVE_STAT_EMPTY_STRING_BUG 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STDARG_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STDLIB_H 1 - -/* Define to 1 if you have the `strchr' function. */ -#cmakedefine HAVE_STRCHR 1 - -/* Define to 1 if you have the `strnlen' function. */ -#cmakedefine HAVE_STRNLEN 1 - -/* Define to 1 if you have the `strdup' function. */ -#cmakedefine HAVE_STRDUP 1 - -/* Define to 1 if you have the `strerror' function. */ -#cmakedefine HAVE_STRERROR 1 - -/* Define to 1 if you have the `strerror_r' function. */ -#cmakedefine HAVE_STRERROR_R 1 - -/* Define to 1 if you have the `strftime' function. */ -#cmakedefine HAVE_STRFTIME 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STRING_H 1 - -/* Define to 1 if you have the `strrchr' function. */ -#cmakedefine HAVE_STRRCHR 1 - -/* Define to 1 if the system has the type `struct statfs'. */ -#cmakedefine HAVE_STRUCT_STATFS 1 - -/* Define to 1 if `f_iosize' is a member of `struct statfs'. */ -#cmakedefine HAVE_STRUCT_STATFS_F_IOSIZE 1 - -/* Define to 1 if `f_namemax' is a member of `struct statfs'. */ -#cmakedefine HAVE_STRUCT_STATFS_F_NAMEMAX 1 - -/* Define to 1 if `f_iosize' is a member of `struct statvfs'. */ -#cmakedefine HAVE_STRUCT_STATVFS_F_IOSIZE 1 - -/* Define to 1 if `st_birthtime' is a member of `struct stat'. */ -#cmakedefine HAVE_STRUCT_STAT_ST_BIRTHTIME 1 - -/* Define to 1 if `st_birthtimespec.tv_nsec' is a member of `struct stat'. */ -#cmakedefine HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC 1 - -/* Define to 1 if `st_blksize' is a member of `struct stat'. */ -#cmakedefine HAVE_STRUCT_STAT_ST_BLKSIZE 1 - -/* Define to 1 if `st_flags' is a member of `struct stat'. */ -#cmakedefine HAVE_STRUCT_STAT_ST_FLAGS 1 - -/* Define to 1 if `st_mtimespec.tv_nsec' is a member of `struct stat'. */ -#cmakedefine HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC 1 - -/* Define to 1 if `st_mtime_n' is a member of `struct stat'. */ -#cmakedefine HAVE_STRUCT_STAT_ST_MTIME_N 1 - -/* Define to 1 if `st_mtime_usec' is a member of `struct stat'. */ -#cmakedefine HAVE_STRUCT_STAT_ST_MTIME_USEC 1 - -/* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */ -#cmakedefine HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 1 - -/* Define to 1 if `st_umtime' is a member of `struct stat'. */ -#cmakedefine HAVE_STRUCT_STAT_ST_UMTIME 1 - -/* Define to 1 if `tm_gmtoff' is a member of `struct tm'. */ -#cmakedefine HAVE_STRUCT_TM_TM_GMTOFF 1 - -/* Define to 1 if `__tm_gmtoff' is a member of `struct tm'. */ -#cmakedefine HAVE_STRUCT_TM___TM_GMTOFF 1 - -/* Define to 1 if you have `struct vfsconf'. */ -#cmakedefine HAVE_STRUCT_VFSCONF 1 - -/* Define to 1 if you have `struct xvfsconf'. */ -#cmakedefine HAVE_STRUCT_XVFSCONF 1 - -/* Define to 1 if you have the `symlink' function. */ -#cmakedefine HAVE_SYMLINK 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_ACL_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_CDEFS_H 1 - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -#cmakedefine HAVE_SYS_DIR_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_EA_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_EXTATTR_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_IOCTL_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_MKDEV_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_MOUNT_H 1 - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -#cmakedefine HAVE_SYS_NDIR_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_PARAM_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_POLL_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_QUEUE_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_RICHACL_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_SELECT_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_STATFS_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_STATVFS_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_STAT_H 1 - - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_SYSMACROS_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_TIME_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_UTIME_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_UTSNAME_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_VFS_H 1 - -/* Define to 1 if you have that is POSIX.1 compatible. */ -#cmakedefine HAVE_SYS_WAIT_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_XATTR_H 1 - -/* Define to 1 if you have the `timegm' function. */ -#cmakedefine HAVE_TIMEGM 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_TIME_H 1 - -/* Define to 1 if you have the `tzset' function. */ -#cmakedefine HAVE_TZSET 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_UNISTD_H 1 - -/* Define to 1 if you have the `unlinkat' function. */ -#cmakedefine HAVE_UNLINKAT 1 - -/* Define to 1 if you have the `unsetenv' function. */ -#cmakedefine HAVE_UNSETENV 1 - -/* Define to 1 if the system has the type `unsigned long long'. */ -#cmakedefine HAVE_UNSIGNED_LONG_LONG 1 - -/* Define to 1 if the system has the type `unsigned long long int'. */ -#cmakedefine HAVE_UNSIGNED_LONG_LONG_INT 1 - -/* Define to 1 if you have the `utime' function. */ -#cmakedefine HAVE_UTIME 1 - -/* Define to 1 if you have the `utimensat' function. */ -#cmakedefine HAVE_UTIMENSAT 1 - -/* Define to 1 if you have the `utimes' function. */ -#cmakedefine HAVE_UTIMES 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_UTIME_H 1 - -/* Define to 1 if you have the `vfork' function. */ -#cmakedefine HAVE_VFORK 1 - -/* Define to 1 if you have the `vprintf' function. */ -#cmakedefine HAVE_VPRINTF 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_WCHAR_H 1 - -/* Define to 1 if the system has the type `wchar_t'. */ -#cmakedefine HAVE_WCHAR_T 1 - -/* Define to 1 if you have the `wcrtomb' function. */ -#cmakedefine HAVE_WCRTOMB 1 - -/* Define to 1 if you have the `wcscmp' function. */ -#cmakedefine HAVE_WCSCMP 1 - -/* Define to 1 if you have the `wcscpy' function. */ -#cmakedefine HAVE_WCSCPY 1 - -/* Define to 1 if you have the `wcslen' function. */ -#cmakedefine HAVE_WCSLEN 1 - -/* Define to 1 if you have the `wctomb' function. */ -#cmakedefine HAVE_WCTOMB 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_WCTYPE_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_WINCRYPT_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_WINDOWS_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_WINIOCTL_H 1 - -/* Define to 1 if you have _CrtSetReportMode in */ -#cmakedefine HAVE__CrtSetReportMode 1 - -/* Define to 1 if you have the `wmemcmp' function. */ -#cmakedefine HAVE_WMEMCMP 1 - -/* Define to 1 if you have the `wmemcpy' function. */ -#cmakedefine HAVE_WMEMCPY 1 - -/* Define to 1 if you have the `wmemmove' function. */ -#cmakedefine HAVE_WMEMMOVE 1 - -/* Define to 1 if you have a working EXT2_IOC_GETFLAGS */ -#cmakedefine HAVE_WORKING_EXT2_IOC_GETFLAGS 1 - -/* Define to 1 if you have a working FS_IOC_GETFLAGS */ -#cmakedefine HAVE_WORKING_FS_IOC_GETFLAGS 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_ZLIB_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_ZSTD_H 1 - -/* Define to 1 if you have the `ctime_s' function. */ -#cmakedefine HAVE_CTIME_S 1 - -/* Define to 1 if you have the `_fseeki64' function. */ -#cmakedefine HAVE__FSEEKI64 1 - -/* Define to 1 if you have the `_get_timezone' function. */ -#cmakedefine HAVE__GET_TIMEZONE 1 - -/* Define to 1 if you have the `gmtime_s' function. */ -#cmakedefine HAVE_GMTIME_S 1 - -/* Define to 1 if you have the `localtime_s' function. */ -#cmakedefine HAVE_LOCALTIME_S 1 - -/* Define to 1 if you have the `_mkgmtime' function. */ -#cmakedefine HAVE__MKGMTIME 1 - -/* Define as const if the declaration of iconv() needs const. */ -#define ICONV_CONST @ICONV_CONST@ - -/* Version number of libarchive as a single integer */ -#cmakedefine LIBARCHIVE_VERSION_NUMBER "@LIBARCHIVE_VERSION_NUMBER@" - -/* Version number of libarchive */ -#cmakedefine LIBARCHIVE_VERSION_STRING "@LIBARCHIVE_VERSION_STRING@" - -/* Define to 1 if `lstat' dereferences a symlink specified with a trailing - slash. */ -#cmakedefine LSTAT_FOLLOWS_SLASHED_SYMLINK 1 - -/* Define to 1 if `major', `minor', and `makedev' are declared in . - */ -#cmakedefine MAJOR_IN_MKDEV 1 - -/* Define to 1 if `major', `minor', and `makedev' are declared in - . */ -#cmakedefine MAJOR_IN_SYSMACROS 1 - -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -#cmakedefine NO_MINUS_C_MINUS_O 1 - -/* The size of `wchar_t', as computed by sizeof. */ -#cmakedefine SIZEOF_WCHAR_T @SIZEOF_WCHAR_T@ - -/* Define to 1 if strerror_r returns char *. */ -#cmakedefine STRERROR_R_CHAR_P 1 - -/* Define to 1 if you can safely include both and . */ -#cmakedefine TIME_WITH_SYS_TIME 1 - -/* - * Some platform requires a macro to use extension functions. - */ -#cmakedefine SAFE_TO_DEFINE_EXTENSIONS 1 -#ifdef SAFE_TO_DEFINE_EXTENSIONS -/* Enable extensions on AIX 3, Interix. */ -#ifndef _ALL_SOURCE -# define _ALL_SOURCE 1 -#endif -/* Enable GNU extensions on systems that have them. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif -/* Enable threading extensions on Solaris. */ -#ifndef _POSIX_PTHREAD_SEMANTICS -# define _POSIX_PTHREAD_SEMANTICS 1 -#endif -/* Enable extensions on HP NonStop. */ -#ifndef _TANDEM_SOURCE -# define _TANDEM_SOURCE 1 -#endif -/* Enable general extensions on Solaris. */ -#ifndef __EXTENSIONS__ -# define __EXTENSIONS__ 1 -#endif -#endif /* SAFE_TO_DEFINE_EXTENSIONS */ - -/* Version number of package */ -#cmakedefine VERSION "@VERSION@" - -/* Number of bits in a file offset, on hosts where this is settable. */ -#cmakedefine _FILE_OFFSET_BITS @_FILE_OFFSET_BITS@ - -/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ -#cmakedefine _LARGEFILE_SOURCE 1 - -/* Define for large files, on AIX-style hosts. */ -#cmakedefine _LARGE_FILES @_LARGE_FILES@ - -/* Define to control Windows SDK version */ -#ifndef NTDDI_VERSION -#cmakedefine NTDDI_VERSION @NTDDI_VERSION@ -#endif // NTDDI_VERSION - -#ifndef _WIN32_WINNT -#cmakedefine _WIN32_WINNT @_WIN32_WINNT@ -#endif // _WIN32_WINNT - -#ifndef WINVER -#cmakedefine WINVER @WINVER@ -#endif // WINVER - -/* Define to empty if `const' does not conform to ANSI C. */ -#cmakedefine const @const@ - -/* Define to `int' if doesn't define. */ -#cmakedefine gid_t @gid_t@ - -/* Define to `unsigned long' if does not define. */ -#cmakedefine id_t @id_t@ - -/* Define to `int' if does not define. */ -#cmakedefine mode_t @mode_t@ - -/* Define to `long long' if does not define. */ -#cmakedefine off_t @off_t@ - -/* Define to `int' if doesn't define. */ -#cmakedefine pid_t @pid_t@ - -/* Define to `unsigned int' if does not define. */ -#cmakedefine size_t @size_t@ - -/* Define to `int' if does not define. */ -#cmakedefine ssize_t @ssize_t@ - -/* Define to `int' if doesn't define. */ -#cmakedefine uid_t @uid_t@ - -/* Define to `int' if does not define. */ -#cmakedefine intptr_t @intptr_t@ - -/* Define to `unsigned int' if does not define. */ -#cmakedefine uintptr_t @uintptr_t@ diff --git a/thirdparty/libarchive/build/pkgconfig/libarchive.pc.in b/thirdparty/libarchive/build/pkgconfig/libarchive.pc.in deleted file mode 100644 index 1f51e77f1..000000000 --- a/thirdparty/libarchive/build/pkgconfig/libarchive.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: libarchive -Description: library that can create and read several streaming archive formats -Version: @VERSION@ -Cflags: -I${includedir} -Cflags.private: -DLIBARCHIVE_STATIC -Libs: -L${libdir} -larchive -Libs.private: @LIBS@ -Requires.private: @LIBSREQUIRED@ diff --git a/thirdparty/libarchive/build/version b/thirdparty/libarchive/build/version deleted file mode 100644 index 414ae6d48..000000000 --- a/thirdparty/libarchive/build/version +++ /dev/null @@ -1 +0,0 @@ -3007002 diff --git a/thirdparty/libarchive/cat/CMakeLists.txt b/thirdparty/libarchive/cat/CMakeLists.txt deleted file mode 100644 index 4fe6354b3..000000000 --- a/thirdparty/libarchive/cat/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -############################################ -# -# How to build bsdcat -# -############################################ -IF(ENABLE_CAT) - - SET(bsdcat_SOURCES - bsdcat.c - bsdcat.h - bsdcat_platform.h - cmdline.c - ../libarchive_fe/err.c - ../libarchive_fe/err.h - ../libarchive_fe/lafe_platform.h - ) - INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libarchive_fe) - - # bsdcat documentation - SET(bsdcat_MANS bsdcat.1) - - # How to build bsdcat - ADD_EXECUTABLE(bsdcat ${bsdcat_SOURCES}) - IF(ENABLE_CAT_SHARED) - TARGET_LINK_LIBRARIES(bsdcat archive ${ADDITIONAL_LIBS}) - ELSE(ENABLE_CAT_SHARED) - TARGET_LINK_LIBRARIES(bsdcat archive_static ${ADDITIONAL_LIBS}) - SET_TARGET_PROPERTIES(bsdcat PROPERTIES COMPILE_DEFINITIONS - LIBARCHIVE_STATIC) - ENDIF(ENABLE_CAT_SHARED) - - # Installation rules - INSTALL(TARGETS bsdcat RUNTIME DESTINATION bin) - INSTALL_MAN(${bsdcat_MANS}) -ENDIF(ENABLE_CAT) - -add_subdirectory(test) diff --git a/thirdparty/libarchive/cat/bsdcat.1 b/thirdparty/libarchive/cat/bsdcat.1 deleted file mode 100644 index 036623e4e..000000000 --- a/thirdparty/libarchive/cat/bsdcat.1 +++ /dev/null @@ -1,61 +0,0 @@ -.\" Copyright (c) 2011-2014, Mike Kazantsev -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd March 1, 2014 -.Dt BSDCAT 1 -.Os -.Sh NAME -.Nm bsdcat -.Nd expand files to standard output -.Sh SYNOPSIS -.Nm -.Op options -.Op files -.Sh DESCRIPTION -.Nm -expands files to standard output. -.Sh OPTIONS -.Nm -typically takes a filename as an argument or reads standard input when used in a -pipe. -In both cases decompressed data it written to standard output. -.Sh EXAMPLES -To decompress a file: -.Pp -.Dl bsdcat example.txt.gz > example.txt -.Pp -To decompress standard input in a pipe: -.Pp -.Dl cat example.txt.gz | bsdcat > example.txt -.Pp -Both examples achieve the same results - a decompressed file by redirecting -output. -.Sh SEE ALSO -.Xr bzcat 1 , -.Xr uncompress 1 , -.Xr xzcat 1 , -.Xr zcat 1 , -.Xr libarchive-formats 5 diff --git a/thirdparty/libarchive/cat/bsdcat.c b/thirdparty/libarchive/cat/bsdcat.c deleted file mode 100644 index bdb9c40b9..000000000 --- a/thirdparty/libarchive/cat/bsdcat.c +++ /dev/null @@ -1,156 +0,0 @@ -/*- - * Copyright (c) 2011-2014, Mike Kazantsev - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "bsdcat_platform.h" -__FBSDID("$FreeBSD$"); - -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "bsdcat.h" -#include "err.h" - -#define BYTES_PER_BLOCK (20*512) - -static struct archive *a; -static struct archive_entry *ae; -static const char *bsdcat_current_path; -static int exit_status = 0; - - -void -usage(FILE *stream, int eval) -{ - const char *p; - p = lafe_getprogname(); - fprintf(stream, - "Usage: %s [-h] [--help] [--version] [--] [filenames...]\n", p); - exit(eval); -} - -static void -version(void) -{ - printf("bsdcat %s - %s \n", - BSDCAT_VERSION_STRING, - archive_version_details()); - exit(0); -} - -void -bsdcat_next(void) -{ - if (a != NULL) { - if (archive_read_close(a) != ARCHIVE_OK) - bsdcat_print_error(); - archive_read_free(a); - } - - a = archive_read_new(); - archive_read_support_filter_all(a); - archive_read_support_format_empty(a); - archive_read_support_format_raw(a); -} - -void -bsdcat_print_error(void) -{ - lafe_warnc(0, "%s: %s", - bsdcat_current_path, archive_error_string(a)); - exit_status = 1; -} - -void -bsdcat_read_to_stdout(const char* filename) -{ - int r; - - if (archive_read_open_filename(a, filename, BYTES_PER_BLOCK) - != ARCHIVE_OK) - bsdcat_print_error(); - else if (r = archive_read_next_header(a, &ae), - r != ARCHIVE_OK && r != ARCHIVE_EOF) - bsdcat_print_error(); - else if (r == ARCHIVE_EOF) - /* for empty payloads don't try and read data */ - ; - else if (archive_read_data_into_fd(a, 1) != ARCHIVE_OK) - bsdcat_print_error(); - if (archive_read_close(a) != ARCHIVE_OK) - bsdcat_print_error(); - archive_read_free(a); - a = NULL; -} - -int -main(int argc, char **argv) -{ - struct bsdcat *bsdcat, bsdcat_storage; - int c; - - bsdcat = &bsdcat_storage; - memset(bsdcat, 0, sizeof(*bsdcat)); - - lafe_setprogname(*argv, "bsdcat"); - - bsdcat->argv = argv; - bsdcat->argc = argc; - - while ((c = bsdcat_getopt(bsdcat)) != -1) { - switch (c) { - case 'h': - usage(stdout, 0); - break; - case OPTION_VERSION: - version(); - break; - default: - usage(stderr, 1); - } - } - - bsdcat_next(); - if (*bsdcat->argv == NULL) { - bsdcat_current_path = ""; - bsdcat_read_to_stdout(NULL); - } else { - while (*bsdcat->argv) { - bsdcat_current_path = *bsdcat->argv++; - bsdcat_read_to_stdout(bsdcat_current_path); - bsdcat_next(); - } - archive_read_free(a); /* Help valgrind & friends */ - } - - exit(exit_status); -} diff --git a/thirdparty/libarchive/cat/bsdcat.h b/thirdparty/libarchive/cat/bsdcat.h deleted file mode 100644 index 6467d6e3d..000000000 --- a/thirdparty/libarchive/cat/bsdcat.h +++ /dev/null @@ -1,61 +0,0 @@ -/*- - * Copyright (c) 2014, Mike Kazantsev - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#ifndef BSDCAT_H_INCLUDED -#define BSDCAT_H_INCLUDED - -#if defined(PLATFORM_CONFIG_H) -/* Use hand-built config.h in environments that need it. */ -#include PLATFORM_CONFIG_H -#else -/* Not having a config.h of some sort is a serious problem. */ -#include "config.h" -#endif - -#include -#include - -struct bsdcat { - /* Option parser state */ - int getopt_state; - char *getopt_word; - - /* Miscellaneous state information */ - int argc; - char **argv; - const char *argument; -}; - -enum { - OPTION_VERSION -}; - -int bsdcat_getopt(struct bsdcat *); -void usage(FILE *stream, int eval); -void bsdcat_next(void); -void bsdcat_print_error(void); -void bsdcat_read_to_stdout(const char* filename); - -#endif diff --git a/thirdparty/libarchive/cat/bsdcat_platform.h b/thirdparty/libarchive/cat/bsdcat_platform.h deleted file mode 100644 index 10b711322..000000000 --- a/thirdparty/libarchive/cat/bsdcat_platform.h +++ /dev/null @@ -1,75 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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/usr.bin/tar/bsdtar_platform.h,v 1.26 2008/12/06 07:37:14 kientzle Exp $ - */ - -/* - * This header is the first thing included in any of the bsdtar - * source files. As far as possible, platform-specific issues should - * be dealt with here and not within individual source files. - */ - -#ifndef BSDCAT_PLATFORM_H_INCLUDED -#define BSDCAT_PLATFORM_H_INCLUDED - -#if defined(PLATFORM_CONFIG_H) -/* Use hand-built config.h in environments that need it. */ -#include PLATFORM_CONFIG_H -#else -/* Not having a config.h of some sort is a serious problem. */ -#include "config.h" -#endif - -/* Get a real definition for __FBSDID if we can */ -#if HAVE_SYS_CDEFS_H -#include -#endif - -/* If not, define it so as to avoid dangling semicolons. */ -#ifndef __FBSDID -#define __FBSDID(a) struct _undefined_hack -#endif - -#ifdef HAVE_LIBARCHIVE -/* If we're using the platform libarchive, include system headers. */ -#include -#include -#else -/* Otherwise, include user headers. */ -#include "archive.h" -#include "archive_entry.h" -#endif - -/* How to mark functions that don't return. */ -/* This facilitates use of some newer static code analysis tools. */ -#undef __LA_DEAD -#if defined(__GNUC__) && (__GNUC__ > 2 || \ - (__GNUC__ == 2 && __GNUC_MINOR__ >= 5)) -#define __LA_DEAD __attribute__((__noreturn__)) -#else -#define __LA_DEAD -#endif - -#endif /* !BSDCAT_PLATFORM_H_INCLUDED */ diff --git a/thirdparty/libarchive/cat/cmdline.c b/thirdparty/libarchive/cat/cmdline.c deleted file mode 100644 index 3c4b7a8c4..000000000 --- a/thirdparty/libarchive/cat/cmdline.c +++ /dev/null @@ -1,283 +0,0 @@ -/*- - * Copyright (c) 2003-2008 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -/* - * Command line parser for bsdcat. - */ - -#include "bsdcat_platform.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "bsdcat.h" -#include "err.h" - -/* - * Short options for bsdcat. Please keep this sorted. - */ -static const char *short_options = "h"; - -/* - * Long options for bsdcat. Please keep this list sorted. - * - * The symbolic names for options that lack a short equivalent are - * defined in bsdcat.h. Also note that so far I've found no need - * to support optional arguments to long options. That would be - * a small change to the code below. - */ - -static const struct bsdcat_option { - const char *name; - int required; /* 1 if this option requires an argument. */ - int equivalent; /* Equivalent short option. */ -} bsdcat_longopts[] = { - { "help", 0, 'h' }, - { "version", 0, OPTION_VERSION }, - { NULL, 0, 0 } -}; - -/* - * This getopt implementation has two key features that common - * getopt_long() implementations lack. Apart from those, it's a - * straightforward option parser, considerably simplified by not - * needing to support the wealth of exotic getopt_long() features. It - * has, of course, been shamelessly tailored for bsdcat. (If you're - * looking for a generic getopt_long() implementation for your - * project, I recommend Gregory Pietsch's public domain getopt_long() - * implementation.) The two additional features are: - * - * Old-style tar arguments: The original tar implementation treated - * the first argument word as a list of single-character option - * letters. All arguments follow as separate words. For example, - * tar xbf 32 /dev/tape - * Here, the "xbf" is three option letters, "32" is the argument for - * "b" and "/dev/tape" is the argument for "f". We support this usage - * if the first command-line argument does not begin with '-'. We - * also allow regular short and long options to follow, e.g., - * tar xbf 32 /dev/tape -P --format=pax - * - * -W long options: There's an obscure GNU convention (only rarely - * supported even there) that allows "-W option=argument" as an - * alternative way to support long options. This was supported in - * early bsdtar as a way to access long options on platforms that did - * not support getopt_long() and is preserved here for backwards - * compatibility. (Of course, if I'd started with a custom - * command-line parser from the beginning, I would have had normal - * long option support on every platform so that hack wouldn't have - * been necessary. Oh, well. Some mistakes you just have to live - * with.) - * - * TODO: We should be able to use this to pull files and intermingled - * options (such as -C) from the command line in write mode. That - * will require a little rethinking of the argument handling in - * bsdcat.c. - * - * TODO: If we want to support arbitrary command-line options from -T - * input (as GNU tar does), we may need to extend this to handle option - * words from sources other than argv/argc. I'm not really sure if I - * like that feature of GNU tar, so it's certainly not a priority. - */ - -int -bsdcat_getopt(struct bsdcat *bsdcat) -{ - enum { state_start = 0, state_old_tar, state_next_word, - state_short, state_long }; - - const struct bsdcat_option *popt, *match = NULL, *match2 = NULL; - const char *p, *long_prefix = "--"; - size_t optlength; - int opt = '?'; - int required = 0; - - bsdcat->argument = NULL; - - /* First time through, initialize everything. */ - if (bsdcat->getopt_state == state_start) { - /* Skip program name. */ - ++bsdcat->argv; - --bsdcat->argc; - if (*bsdcat->argv == NULL) - return (-1); - /* Decide between "new style" and "old style" arguments. */ - bsdcat->getopt_state = state_next_word; - } - - /* - * We're ready to look at the next word in argv. - */ - if (bsdcat->getopt_state == state_next_word) { - /* No more arguments, so no more options. */ - if (bsdcat->argv[0] == NULL) - return (-1); - /* Doesn't start with '-', so no more options. */ - if (bsdcat->argv[0][0] != '-') - return (-1); - /* "--" marks end of options; consume it and return. */ - if (strcmp(bsdcat->argv[0], "--") == 0) { - ++bsdcat->argv; - --bsdcat->argc; - return (-1); - } - /* Get next word for parsing. */ - bsdcat->getopt_word = *bsdcat->argv++; - --bsdcat->argc; - if (bsdcat->getopt_word[1] == '-') { - /* Set up long option parser. */ - bsdcat->getopt_state = state_long; - bsdcat->getopt_word += 2; /* Skip leading '--' */ - } else { - /* Set up short option parser. */ - bsdcat->getopt_state = state_short; - ++bsdcat->getopt_word; /* Skip leading '-' */ - } - } - - /* - * We're parsing a group of POSIX-style single-character options. - */ - if (bsdcat->getopt_state == state_short) { - /* Peel next option off of a group of short options. */ - opt = *bsdcat->getopt_word++; - if (opt == '\0') { - /* End of this group; recurse to get next option. */ - bsdcat->getopt_state = state_next_word; - return bsdcat_getopt(bsdcat); - } - - /* Does this option take an argument? */ - p = strchr(short_options, opt); - if (p == NULL) - return ('?'); - if (p[1] == ':') - required = 1; - - /* If it takes an argument, parse that. */ - if (required) { - /* If arg is run-in, bsdcat->getopt_word already points to it. */ - if (bsdcat->getopt_word[0] == '\0') { - /* Otherwise, pick up the next word. */ - bsdcat->getopt_word = *bsdcat->argv; - if (bsdcat->getopt_word == NULL) { - lafe_warnc(0, - "Option -%c requires an argument", - opt); - return ('?'); - } - ++bsdcat->argv; - --bsdcat->argc; - } - if (opt == 'W') { - bsdcat->getopt_state = state_long; - long_prefix = "-W "; /* For clearer errors. */ - } else { - bsdcat->getopt_state = state_next_word; - bsdcat->argument = bsdcat->getopt_word; - } - } - } - - /* We're reading a long option, including -W long=arg convention. */ - if (bsdcat->getopt_state == state_long) { - /* After this long option, we'll be starting a new word. */ - bsdcat->getopt_state = state_next_word; - - /* Option name ends at '=' if there is one. */ - p = strchr(bsdcat->getopt_word, '='); - if (p != NULL) { - optlength = (size_t)(p - bsdcat->getopt_word); - bsdcat->argument = (char *)(uintptr_t)(p + 1); - } else { - optlength = strlen(bsdcat->getopt_word); - } - - /* Search the table for an unambiguous match. */ - for (popt = bsdcat_longopts; popt->name != NULL; popt++) { - /* Short-circuit if first chars don't match. */ - if (popt->name[0] != bsdcat->getopt_word[0]) - continue; - /* If option is a prefix of name in table, record it.*/ - if (strncmp(bsdcat->getopt_word, popt->name, optlength) == 0) { - match2 = match; /* Record up to two matches. */ - match = popt; - /* If it's an exact match, we're done. */ - if (strlen(popt->name) == optlength) { - match2 = NULL; /* Forget the others. */ - break; - } - } - } - - /* Fail if there wasn't a unique match. */ - if (match == NULL) { - lafe_warnc(0, - "Option %s%s is not supported", - long_prefix, bsdcat->getopt_word); - return ('?'); - } - if (match2 != NULL) { - lafe_warnc(0, - "Ambiguous option %s%s (matches --%s and --%s)", - long_prefix, bsdcat->getopt_word, match->name, match2->name); - return ('?'); - } - - /* We've found a unique match; does it need an argument? */ - if (match->required) { - /* Argument required: get next word if necessary. */ - if (bsdcat->argument == NULL) { - bsdcat->argument = *bsdcat->argv; - if (bsdcat->argument == NULL) { - lafe_warnc(0, - "Option %s%s requires an argument", - long_prefix, match->name); - return ('?'); - } - ++bsdcat->argv; - --bsdcat->argc; - } - } else { - /* Argument forbidden: fail if there is one. */ - if (bsdcat->argument != NULL) { - lafe_warnc(0, - "Option %s%s does not allow an argument", - long_prefix, match->name); - return ('?'); - } - } - return (match->equivalent); - } - - return (opt); -} diff --git a/thirdparty/libarchive/cat/test/CMakeLists.txt b/thirdparty/libarchive/cat/test/CMakeLists.txt deleted file mode 100644 index 72f4a1037..000000000 --- a/thirdparty/libarchive/cat/test/CMakeLists.txt +++ /dev/null @@ -1,80 +0,0 @@ -############################################ -# -# How to build bsdtar_test -# -############################################ -IF(ENABLE_CAT AND ENABLE_TEST) - SET(bsdcat_test_SOURCES - ../../test_utils/test_utils.c - ../../test_utils/test_main.c - test.h - test_0.c - test_empty_gz.c - test_empty_lz4.c - test_empty_xz.c - test_empty_zstd.c - test_error.c - test_error_mixed.c - test_expand_Z.c - test_expand_bz2.c - test_expand_gz.c - test_expand_lz4.c - test_expand_mixed.c - test_expand_plain.c - test_expand_xz.c - test_expand_zstd.c - test_help.c - test_stdin.c - test_version.c - ) - - # - # Register target - # - ADD_EXECUTABLE(bsdcat_test ${bsdcat_test_SOURCES}) - IF(ENABLE_ACL) - SET(TEST_ACL_LIBS "") - IF(HAVE_LIBACL) - LIST(APPEND TEST_ACL_LIBS ${ACL_LIBRARY}) - ENDIF(HAVE_LIBACL) - IF(HAVE_LIBRICHACL) - LIST(APPEND TEST_ACL_LIBS ${RICHACL_LIBRARY}) - ENDIF(HAVE_LIBRICHACL) - TARGET_LINK_LIBRARIES(bsdcat_test ${TEST_ACL_LIBS}) - ENDIF(ENABLE_ACL) - SET_PROPERTY(TARGET bsdcat_test PROPERTY COMPILE_DEFINITIONS LIST_H) - - # - # Generate list.h by grepping DEFINE_TEST() lines out of the C sources. - # - GENERATE_LIST_H(${CMAKE_CURRENT_BINARY_DIR}/list.h - ${CMAKE_CURRENT_LIST_FILE} ${bsdcat_test_SOURCES}) - SET_PROPERTY(DIRECTORY APPEND PROPERTY INCLUDE_DIRECTORIES - ${CMAKE_CURRENT_BINARY_DIR}) - - # list.h has a line DEFINE_TEST(testname) for every - # test. We can use that to define the tests for cmake by - # defining a DEFINE_TEST macro and reading list.h in. - MACRO (DEFINE_TEST _testname) - ADD_TEST( - NAME bsdcat_${_testname} - COMMAND bsdcat_test -vv - -p $ - -r ${CMAKE_CURRENT_SOURCE_DIR} - ${_testname}) - ENDMACRO (DEFINE_TEST _testname) - - INCLUDE(${CMAKE_CURRENT_BINARY_DIR}/list.h) - INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) - INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/test_utils) - INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/cat/test) - - # Experimental new test handling - ADD_CUSTOM_TARGET(run_bsdcat_test - COMMAND bsdcat_test -p $ - -r ${CMAKE_CURRENT_SOURCE_DIR} - -vv) - ADD_DEPENDENCIES(run_bsdcat_test bsdcat) - ADD_DEPENDENCIES(run_all_tests run_bsdcat_test) - -ENDIF(ENABLE_CAT AND ENABLE_TEST) diff --git a/thirdparty/libarchive/cat/test/list.h b/thirdparty/libarchive/cat/test/list.h deleted file mode 100644 index 524612228..000000000 --- a/thirdparty/libarchive/cat/test/list.h +++ /dev/null @@ -1,18 +0,0 @@ -DEFINE_TEST(test_0) -DEFINE_TEST(test_empty_gz) -DEFINE_TEST(test_empty_lz4) -DEFINE_TEST(test_empty_xz) -DEFINE_TEST(test_empty_zstd) -DEFINE_TEST(test_error) -DEFINE_TEST(test_error_mixed) -DEFINE_TEST(test_expand_bz2) -DEFINE_TEST(test_expand_gz) -DEFINE_TEST(test_expand_lz4) -DEFINE_TEST(test_expand_mixed) -DEFINE_TEST(test_expand_plain) -DEFINE_TEST(test_expand_xz) -DEFINE_TEST(test_expand_Z) -DEFINE_TEST(test_expand_zstd) -DEFINE_TEST(test_help) -DEFINE_TEST(test_stdin) -DEFINE_TEST(test_version) diff --git a/thirdparty/libarchive/cat/test/test.h b/thirdparty/libarchive/cat/test/test.h deleted file mode 100644 index 350bcad63..000000000 --- a/thirdparty/libarchive/cat/test/test.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2003-2006 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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$ - */ - -/* Every test program should #include "test.h" as the first thing. */ - -#define KNOWNREF "test_expand.Z.uu" -#define ENVBASE "BSDCAT" /* Prefix for environment variables. */ -#define PROGRAM "bsdcat" /* Name of program being tested. */ -#define PROGRAM_ALIAS "cat" /* Generic alias for program */ -#undef LIBRARY /* Not testing a library. */ -#undef EXTRA_DUMP /* How to dump extra data */ -#undef EXTRA_ERRNO /* How to dump errno */ -/* How to generate extra version info. */ -#define EXTRA_VERSION (systemf("%s --version", testprog) ? "" : "") - -#include "test_common.h" diff --git a/thirdparty/libarchive/cat/test/test_0.c b/thirdparty/libarchive/cat/test/test_0.c deleted file mode 100644 index c806c2435..000000000 --- a/thirdparty/libarchive/cat/test/test_0.c +++ /dev/null @@ -1,67 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -/* - * This first test does basic sanity checks on the environment. For - * most of these, we just exit on failure. - */ -#if !defined(_WIN32) || defined(__CYGWIN__) -#define DEV_NULL "/dev/null" -#else -#define DEV_NULL "NUL" -#endif - -DEFINE_TEST(test_0) -{ - struct stat st; - - failure("File %s does not exist?!", testprog); - if (!assertEqualInt(0, stat(testprogfile, &st))) { - fprintf(stderr, - "\nFile %s does not exist; aborting test.\n\n", - testprog); - exit(1); - } - - failure("%s is not executable?!", testprog); - if (!assert((st.st_mode & 0111) != 0)) { - fprintf(stderr, - "\nFile %s not executable; aborting test.\n\n", - testprog); - exit(1); - } - - /* - * Try to successfully run the program; this requires that - * we know some option that will succeed. - */ - if (0 != systemf("%s --version >" DEV_NULL, testprog)) { - failure("Unable to successfully run: %s --version\n", testprog); - assert(0); - } - - /* TODO: Ensure that our reference files are available. */ -} diff --git a/thirdparty/libarchive/cat/test/test_empty.gz.uu b/thirdparty/libarchive/cat/test/test_empty.gz.uu deleted file mode 100644 index 22b52308e..000000000 --- a/thirdparty/libarchive/cat/test/test_empty.gz.uu +++ /dev/null @@ -1,4 +0,0 @@ -begin 644 test_empty.gz -?'XL(""\MZE,``W1EG840`` -` -end diff --git a/thirdparty/libarchive/cat/test/test_empty_gz.c b/thirdparty/libarchive/cat/test/test_empty_gz.c deleted file mode 100644 index 6181f93b4..000000000 --- a/thirdparty/libarchive/cat/test/test_empty_gz.c +++ /dev/null @@ -1,41 +0,0 @@ -/*- - * Copyright (c) 2014 Sebastian Freundt - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -DEFINE_TEST(test_empty_gz) -{ - const char *reffile = "test_empty.gz"; - int f; - - extract_reference_file(reffile); - f = systemf("%s %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canGzip()) { - assertEqualInt(0, f); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - } else { - skipping("It seems gzip is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/cat/test/test_empty_lz4.c b/thirdparty/libarchive/cat/test/test_empty_lz4.c deleted file mode 100644 index 9d98e9cfd..000000000 --- a/thirdparty/libarchive/cat/test/test_empty_lz4.c +++ /dev/null @@ -1,41 +0,0 @@ -/*- - * Copyright (c) 2014 Sebastian Freundt - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -DEFINE_TEST(test_empty_lz4) -{ - const char *reffile = "test_empty.lz4"; - int f; - - extract_reference_file(reffile); - f = systemf("%s %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canLz4()) { - assertEqualInt(0, f); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - } else { - skipping("It seems lz4 is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/cat/test/test_empty_xz.c b/thirdparty/libarchive/cat/test/test_empty_xz.c deleted file mode 100644 index 368ffb574..000000000 --- a/thirdparty/libarchive/cat/test/test_empty_xz.c +++ /dev/null @@ -1,41 +0,0 @@ -/*- - * Copyright (c) 2014 Sebastian Freundt - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -DEFINE_TEST(test_empty_xz) -{ - const char *reffile = "test_empty.xz"; - int f; - - extract_reference_file(reffile); - f = systemf("%s %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canXz()) { - assertEqualInt(0, f); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - } else { - skipping("It seems xz is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/cat/test/test_empty_zstd.c b/thirdparty/libarchive/cat/test/test_empty_zstd.c deleted file mode 100644 index c2d5ea106..000000000 --- a/thirdparty/libarchive/cat/test/test_empty_zstd.c +++ /dev/null @@ -1,41 +0,0 @@ -/*- - * Copyright (c) 2017 Sean Purcell - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -DEFINE_TEST(test_empty_zstd) -{ - const char *reffile = "test_empty.zst"; - int f; - - extract_reference_file(reffile); - f = systemf("%s %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canZstd()) { - assertEqualInt(0, f); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - } else { - skipping("It seems zstd is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/cat/test/test_error.c b/thirdparty/libarchive/cat/test/test_error.c deleted file mode 100644 index 918af01be..000000000 --- a/thirdparty/libarchive/cat/test/test_error.c +++ /dev/null @@ -1,36 +0,0 @@ -/*- - * Copyright (c) 2014 Mike Kazantsev - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -DEFINE_TEST(test_error) -{ - const char *reffile = "test_expand.error"; - - assertFileNotExists(reffile); - assert(0 != systemf("%s %s >test.out 2>test.err", testprog, reffile)); - - assertEmptyFile("test.out"); - assertNonEmptyFile("test.err"); -} diff --git a/thirdparty/libarchive/cat/test/test_error_mixed.c b/thirdparty/libarchive/cat/test/test_error_mixed.c deleted file mode 100644 index 7d94fce46..000000000 --- a/thirdparty/libarchive/cat/test/test_error_mixed.c +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * Copyright (c) 2014 Mike Kazantsev - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -DEFINE_TEST(test_error_mixed) -{ - const char *reffile1 = "test_expand.plain"; - const char *reffile2 = "test_expand.error"; - const char *reffile3 = "test_expand.Z"; - - assertFileNotExists(reffile2); - extract_reference_file(reffile1); - extract_reference_file(reffile3); - assert(0 != systemf("%s %s %s %s >test.out 2>test.err", - testprog, reffile1, reffile2, reffile3)); - - assertTextFileContents( - "contents of test_expand.plain.\n" - "contents of test_expand.Z.\n", "test.out"); - assertNonEmptyFile("test.err"); -} diff --git a/thirdparty/libarchive/cat/test/test_expand.Z.uu b/thirdparty/libarchive/cat/test/test_expand.Z.uu deleted file mode 100644 index b65efc1a2..000000000 --- a/thirdparty/libarchive/cat/test/test_expand.Z.uu +++ /dev/null @@ -1,3 +0,0 @@ -begin 664 test_expand.Z -@'YV08]ZXH5-FX!P0;\R`(#B'SI."$<4/&A187"@` -end diff --git a/thirdparty/libarchive/cat/test/test_expand.bz2.uu b/thirdparty/libarchive/cat/test/test_expand.bz2.uu deleted file mode 100644 index 344c1cbaa..000000000 --- a/thirdparty/libarchive/cat/test/test_expand.bz2.uu +++ /dev/null @@ -1,5 +0,0 @@ -begin 664 test_expand.bz2 -M0EIH.3%!62936=[T@^L [__N000(!!(#!@\P+(, !@4 1 @$" (0 80$ -M(!D0 " 5%)D::#( #0]0 9J%1Z@>H :!B:&33(!"X";"%C@I$+32H/(0MXG -J,EA1G51 WG-"6JV7JKA;/&]$X 6MNH 8'N@3[\XCA_%W)%.%"0WO2#ZP -end diff --git a/thirdparty/libarchive/cat/test/test_expand.gz.uu b/thirdparty/libarchive/cat/test/test_expand.gz.uu deleted file mode 100644 index 528167c6f..000000000 --- a/thirdparty/libarchive/cat/test/test_expand.gz.uu +++ /dev/null @@ -1,4 +0,0 @@ -begin 664 test_expand.gz -M'XL("-UD1%,``V%S9`!+SL\K2C0N"@`````Y -#!E9+ -` -end diff --git a/thirdparty/libarchive/cat/test/test_expand.plain.uu b/thirdparty/libarchive/cat/test/test_expand.plain.uu deleted file mode 100644 index ab83c9cb4..000000000 --- a/thirdparty/libarchive/cat/test/test_expand.plain.uu +++ /dev/null @@ -1,3 +0,0 @@ -begin 664 test_expand.plain -?8V]N=&5N=',@;V8@=&5S=%]E>'!A;F0N<&QA:6XN"@ -end diff --git a/thirdparty/libarchive/cat/test/test_expand.xz.uu b/thirdparty/libarchive/cat/test/test_expand.xz.uu deleted file mode 100644 index 8a92980c0..000000000 --- a/thirdparty/libarchive/cat/test/test_expand.xz.uu +++ /dev/null @@ -1,4 +0,0 @@ -begin 664 test_expand.xz -M_3=Z6%H 3FUK1& @ A 18 !T+^6C 0 ;8V]N=&5N=',@;V8@=&5S=%]E -G>'!A;F0N>'HN"@!S;^LVAO^3[ !-!R3&JV/'[;S?0$ !%E: -end diff --git a/thirdparty/libarchive/cat/test/test_expand.zst.uu b/thirdparty/libarchive/cat/test/test_expand.zst.uu deleted file mode 100644 index 89c28b1bc..000000000 --- a/thirdparty/libarchive/cat/test/test_expand.zst.uu +++ /dev/null @@ -1,4 +0,0 @@ -begin 644 test_expand.zst -J*+4O_010Z0``8V]N=&5N=',@;V8@=&5S=%]E>'!A;F0N>G-T+@J;23#F -` -end diff --git a/thirdparty/libarchive/cat/test/test_expand_Z.c b/thirdparty/libarchive/cat/test/test_expand_Z.c deleted file mode 100644 index d48d4972e..000000000 --- a/thirdparty/libarchive/cat/test/test_expand_Z.c +++ /dev/null @@ -1,36 +0,0 @@ -/*- - * Copyright (c) 2014 Mike Kazantsev - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -DEFINE_TEST(test_expand_Z) -{ - const char *reffile = "test_expand.Z"; - - extract_reference_file(reffile); - assertEqualInt(0, systemf("%s %s >test.out 2>test.err", testprog, reffile)); - - assertTextFileContents("contents of test_expand.Z.\n", "test.out"); - assertEmptyFile("test.err"); -} diff --git a/thirdparty/libarchive/cat/test/test_expand_bz2.c b/thirdparty/libarchive/cat/test/test_expand_bz2.c deleted file mode 100644 index 82f074b34..000000000 --- a/thirdparty/libarchive/cat/test/test_expand_bz2.c +++ /dev/null @@ -1,42 +0,0 @@ -/*- - * Copyright (c) 2014 Mike Kazantsev - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -DEFINE_TEST(test_expand_bz2) -{ - const char *reffile = "test_expand.bz2"; - int f; - - extract_reference_file(reffile); - f = systemf("%s %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canBzip2()) { - assertEqualInt(0, f); - assertTextFileContents("contents of test_expand.bz2.\n", "test.out"); - assertEmptyFile("test.err"); - } else { - skipping("It seems bzip2 is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/cat/test/test_expand_gz.c b/thirdparty/libarchive/cat/test/test_expand_gz.c deleted file mode 100644 index 18b715c66..000000000 --- a/thirdparty/libarchive/cat/test/test_expand_gz.c +++ /dev/null @@ -1,42 +0,0 @@ -/*- - * Copyright (c) 2014 Mike Kazantsev - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -DEFINE_TEST(test_expand_gz) -{ - const char *reffile = "test_expand.gz"; - int f; - - extract_reference_file(reffile); - f = systemf("%s %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canGzip()) { - assertEqualInt(0, f); - assertTextFileContents("contents of test_expand.gz.\n", "test.out"); - assertEmptyFile("test.err"); - } else { - skipping("It seems gzip is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/cat/test/test_expand_lz4.c b/thirdparty/libarchive/cat/test/test_expand_lz4.c deleted file mode 100644 index 1b1d21064..000000000 --- a/thirdparty/libarchive/cat/test/test_expand_lz4.c +++ /dev/null @@ -1,42 +0,0 @@ -/*- - * Copyright (c) 2014 Mike Kazantsev - * Copyright (c) 2012, 2014 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -DEFINE_TEST(test_expand_lz4) -{ - const char *reffile = "test_expand.lz4"; - int f; - - extract_reference_file(reffile); - f = systemf("%s %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canLz4()) { - assertEqualInt(0, f); - assertTextFileContents("contents of test_expand.lz4.\n", "test.out"); - assertEmptyFile("test.err"); - } else { - skipping("It seems lz4 is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/cat/test/test_expand_mixed.c b/thirdparty/libarchive/cat/test/test_expand_mixed.c deleted file mode 100644 index fa2235719..000000000 --- a/thirdparty/libarchive/cat/test/test_expand_mixed.c +++ /dev/null @@ -1,41 +0,0 @@ -/*- - * Copyright (c) 2014 Mike Kazantsev - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -DEFINE_TEST(test_expand_mixed) -{ - const char *reffile1 = "test_expand.Z"; - const char *reffile2 = "test_expand.plain"; - - extract_reference_file(reffile1); - extract_reference_file(reffile2); - assertEqualInt(0, systemf("%s %s %s >test.out 2>test.err", - testprog, reffile1, reffile2)); - - assertTextFileContents( - "contents of test_expand.Z.\n" - "contents of test_expand.plain.\n", "test.out"); - assertEmptyFile("test.err"); -} diff --git a/thirdparty/libarchive/cat/test/test_expand_plain.c b/thirdparty/libarchive/cat/test/test_expand_plain.c deleted file mode 100644 index 8b2276982..000000000 --- a/thirdparty/libarchive/cat/test/test_expand_plain.c +++ /dev/null @@ -1,36 +0,0 @@ -/*- - * Copyright (c) 2014 Mike Kazantsev - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -DEFINE_TEST(test_expand_plain) -{ - const char *reffile = "test_expand.plain"; - - extract_reference_file(reffile); - assertEqualInt(0, systemf("%s %s >test.out 2>test.err", testprog, reffile)); - - assertTextFileContents("contents of test_expand.plain.\n", "test.out"); - assertEmptyFile("test.err"); -} diff --git a/thirdparty/libarchive/cat/test/test_expand_xz.c b/thirdparty/libarchive/cat/test/test_expand_xz.c deleted file mode 100644 index 99f87bf4c..000000000 --- a/thirdparty/libarchive/cat/test/test_expand_xz.c +++ /dev/null @@ -1,42 +0,0 @@ -/*- - * Copyright (c) 2014 Mike Kazantsev - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -DEFINE_TEST(test_expand_xz) -{ - const char *reffile = "test_expand.xz"; - int f; - - extract_reference_file(reffile); - f = systemf("%s %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canXz()) { - assertEqualInt(0, f); - assertTextFileContents("contents of test_expand.xz.\n", "test.out"); - assertEmptyFile("test.err"); - } else { - skipping("It seems xz is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/cat/test/test_expand_zstd.c b/thirdparty/libarchive/cat/test/test_expand_zstd.c deleted file mode 100644 index 23d918252..000000000 --- a/thirdparty/libarchive/cat/test/test_expand_zstd.c +++ /dev/null @@ -1,41 +0,0 @@ -/*- - * Copyright (c) 2017 Sean Purcell - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -DEFINE_TEST(test_expand_zstd) -{ - const char *reffile = "test_expand.zst"; - int f; - - extract_reference_file(reffile); - f = systemf("%s %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canZstd()) { - assertEqualInt(0, f); - assertTextFileContents("contents of test_expand.zst.\n", "test.out"); - assertEmptyFile("test.err"); - } else { - skipping("It seems zstd is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/cat/test/test_help.c b/thirdparty/libarchive/cat/test/test_help.c deleted file mode 100644 index 4ed47a076..000000000 --- a/thirdparty/libarchive/cat/test/test_help.c +++ /dev/null @@ -1,75 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -/* - * Test that "--help", "-h", and "-W help" options all work and - * generate reasonable output. - */ - -static int -in_first_line(const char *p, const char *substring) -{ - size_t l = strlen(substring); - - while (*p != '\0' && *p != '\n') { - if (memcmp(p, substring, l) == 0) - return (1); - ++p; - } - return (0); -} - -DEFINE_TEST(test_help) -{ - int r; - char *p; - size_t plen; - - /* Exercise --help option. */ - r = systemf("%s --help >help.stdout 2>help.stderr", testprog); - assertEqualInt(r, 0); - failure("--help should generate nothing to stderr."); - assertEmptyFile("help.stderr"); - /* Help message should start with name of program. */ - p = slurpfile(&plen, "help.stdout"); - failure("Help output should be long enough."); - assert(plen >= 6); - failure("First line of help output should contain 'bsdcat': %s", p); - assert(in_first_line(p, "bsdcat")); - /* - * TODO: Extend this check to further verify that --help output - * looks approximately right. - */ - free(p); - - /* -h option should generate the same output. */ - r = systemf("%s -h >h.stdout 2>h.stderr", testprog); - assertEqualInt(r, 0); - failure("-h should generate nothing to stderr."); - assertEmptyFile("h.stderr"); - failure("stdout should be same for -h and --help"); - assertEqualFile("h.stdout", "help.stdout"); -} diff --git a/thirdparty/libarchive/cat/test/test_stdin.c b/thirdparty/libarchive/cat/test/test_stdin.c deleted file mode 100644 index cea5eb0ec..000000000 --- a/thirdparty/libarchive/cat/test/test_stdin.c +++ /dev/null @@ -1,42 +0,0 @@ -/*- - * Copyright (c) 2017 Sean Purcell - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -#if !defined(_WIN32) || defined(__CYGWIN__) -#define DEV_NULL "/dev/null" -#else -#define DEV_NULL "NUL" -#endif - -DEFINE_TEST(test_stdin) -{ - int f; - - f = systemf("%s <%s >test.out 2>test.err", testprog, DEV_NULL); - assertEqualInt(0, f); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); -} - diff --git a/thirdparty/libarchive/cat/test/test_version.c b/thirdparty/libarchive/cat/test/test_version.c deleted file mode 100644 index 51a4fd4d9..000000000 --- a/thirdparty/libarchive/cat/test/test_version.c +++ /dev/null @@ -1,34 +0,0 @@ -/*- - * Copyright (c) 2003-2017 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -/* - * Test that --version option works and generates reasonable output. - */ - -DEFINE_TEST(test_version) -{ - assertVersion(testprog, "bsdcat"); -} diff --git a/thirdparty/libarchive/config.h.in b/thirdparty/libarchive/config.h.in deleted file mode 100644 index 6f3f9b989..000000000 --- a/thirdparty/libarchive/config.h.in +++ /dev/null @@ -1,1518 +0,0 @@ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Darwin ACL support */ -#undef ARCHIVE_ACL_DARWIN - -/* FreeBSD ACL support */ -#undef ARCHIVE_ACL_FREEBSD - -/* FreeBSD NFSv4 ACL support */ -#undef ARCHIVE_ACL_FREEBSD_NFS4 - -/* Linux POSIX.1e ACL support via libacl */ -#undef ARCHIVE_ACL_LIBACL - -/* Linux NFSv4 ACL support via librichacl */ -#undef ARCHIVE_ACL_LIBRICHACL - -/* Solaris ACL support */ -#undef ARCHIVE_ACL_SUNOS - -/* Solaris NFSv4 ACL support */ -#undef ARCHIVE_ACL_SUNOS_NFS4 - -/* MD5 via ARCHIVE_CRYPTO_MD5_LIBC supported. */ -#undef ARCHIVE_CRYPTO_MD5_LIBC - -/* MD5 via ARCHIVE_CRYPTO_MD5_LIBMD supported. */ -#undef ARCHIVE_CRYPTO_MD5_LIBMD - -/* MD5 via ARCHIVE_CRYPTO_MD5_LIBSYSTEM supported. */ -#undef ARCHIVE_CRYPTO_MD5_LIBSYSTEM - -/* MD5 via ARCHIVE_CRYPTO_MD5_MBEDTLS supported. */ -#undef ARCHIVE_CRYPTO_MD5_MBEDTLS - -/* MD5 via ARCHIVE_CRYPTO_MD5_NETTLE supported. */ -#undef ARCHIVE_CRYPTO_MD5_NETTLE - -/* MD5 via ARCHIVE_CRYPTO_MD5_OPENSSL supported. */ -#undef ARCHIVE_CRYPTO_MD5_OPENSSL - -/* MD5 via ARCHIVE_CRYPTO_MD5_WIN supported. */ -#undef ARCHIVE_CRYPTO_MD5_WIN - -/* RMD160 via ARCHIVE_CRYPTO_RMD160_LIBC supported. */ -#undef ARCHIVE_CRYPTO_RMD160_LIBC - -/* RMD160 via ARCHIVE_CRYPTO_RMD160_LIBMD supported. */ -#undef ARCHIVE_CRYPTO_RMD160_LIBMD - -/* RMD160 via ARCHIVE_CRYPTO_RMD160_MBEDTLS supported. */ -#undef ARCHIVE_CRYPTO_RMD160_MBEDTLS - -/* RMD160 via ARCHIVE_CRYPTO_RMD160_NETTLE supported. */ -#undef ARCHIVE_CRYPTO_RMD160_NETTLE - -/* RMD160 via ARCHIVE_CRYPTO_RMD160_OPENSSL supported. */ -#undef ARCHIVE_CRYPTO_RMD160_OPENSSL - -/* SHA1 via ARCHIVE_CRYPTO_SHA1_LIBC supported. */ -#undef ARCHIVE_CRYPTO_SHA1_LIBC - -/* SHA1 via ARCHIVE_CRYPTO_SHA1_LIBMD supported. */ -#undef ARCHIVE_CRYPTO_SHA1_LIBMD - -/* SHA1 via ARCHIVE_CRYPTO_SHA1_LIBSYSTEM supported. */ -#undef ARCHIVE_CRYPTO_SHA1_LIBSYSTEM - -/* SHA1 via ARCHIVE_CRYPTO_SHA1_MBEDTLS supported. */ -#undef ARCHIVE_CRYPTO_SHA1_MBEDTLS - -/* SHA1 via ARCHIVE_CRYPTO_SHA1_NETTLE supported. */ -#undef ARCHIVE_CRYPTO_SHA1_NETTLE - -/* SHA1 via ARCHIVE_CRYPTO_SHA1_OPENSSL supported. */ -#undef ARCHIVE_CRYPTO_SHA1_OPENSSL - -/* SHA1 via ARCHIVE_CRYPTO_SHA1_WIN supported. */ -#undef ARCHIVE_CRYPTO_SHA1_WIN - -/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBC supported. */ -#undef ARCHIVE_CRYPTO_SHA256_LIBC - -/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBC2 supported. */ -#undef ARCHIVE_CRYPTO_SHA256_LIBC2 - -/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBC3 supported. */ -#undef ARCHIVE_CRYPTO_SHA256_LIBC3 - -/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBMD supported. */ -#undef ARCHIVE_CRYPTO_SHA256_LIBMD - -/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBSYSTEM supported. */ -#undef ARCHIVE_CRYPTO_SHA256_LIBSYSTEM - -/* SHA256 via ARCHIVE_CRYPTO_SHA256_MBEDTLS supported. */ -#undef ARCHIVE_CRYPTO_SHA256_MBEDTLS - -/* SHA256 via ARCHIVE_CRYPTO_SHA256_NETTLE supported. */ -#undef ARCHIVE_CRYPTO_SHA256_NETTLE - -/* SHA256 via ARCHIVE_CRYPTO_SHA256_OPENSSL supported. */ -#undef ARCHIVE_CRYPTO_SHA256_OPENSSL - -/* SHA256 via ARCHIVE_CRYPTO_SHA256_WIN supported. */ -#undef ARCHIVE_CRYPTO_SHA256_WIN - -/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBC supported. */ -#undef ARCHIVE_CRYPTO_SHA384_LIBC - -/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBC2 supported. */ -#undef ARCHIVE_CRYPTO_SHA384_LIBC2 - -/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBC3 supported. */ -#undef ARCHIVE_CRYPTO_SHA384_LIBC3 - -/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBSYSTEM supported. */ -#undef ARCHIVE_CRYPTO_SHA384_LIBSYSTEM - -/* SHA384 via ARCHIVE_CRYPTO_SHA384_MBEDTLS supported. */ -#undef ARCHIVE_CRYPTO_SHA384_MBEDTLS - -/* SHA384 via ARCHIVE_CRYPTO_SHA384_NETTLE supported. */ -#undef ARCHIVE_CRYPTO_SHA384_NETTLE - -/* SHA384 via ARCHIVE_CRYPTO_SHA384_OPENSSL supported. */ -#undef ARCHIVE_CRYPTO_SHA384_OPENSSL - -/* SHA384 via ARCHIVE_CRYPTO_SHA384_WIN supported. */ -#undef ARCHIVE_CRYPTO_SHA384_WIN - -/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBC supported. */ -#undef ARCHIVE_CRYPTO_SHA512_LIBC - -/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBC2 supported. */ -#undef ARCHIVE_CRYPTO_SHA512_LIBC2 - -/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBC3 supported. */ -#undef ARCHIVE_CRYPTO_SHA512_LIBC3 - -/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBMD supported. */ -#undef ARCHIVE_CRYPTO_SHA512_LIBMD - -/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBSYSTEM supported. */ -#undef ARCHIVE_CRYPTO_SHA512_LIBSYSTEM - -/* SHA512 via ARCHIVE_CRYPTO_SHA512_MBEDTLS supported. */ -#undef ARCHIVE_CRYPTO_SHA512_MBEDTLS - -/* SHA512 via ARCHIVE_CRYPTO_SHA512_NETTLE supported. */ -#undef ARCHIVE_CRYPTO_SHA512_NETTLE - -/* SHA512 via ARCHIVE_CRYPTO_SHA512_OPENSSL supported. */ -#undef ARCHIVE_CRYPTO_SHA512_OPENSSL - -/* SHA512 via ARCHIVE_CRYPTO_SHA512_WIN supported. */ -#undef ARCHIVE_CRYPTO_SHA512_WIN - -/* AIX xattr support */ -#undef ARCHIVE_XATTR_AIX - -/* Darwin xattr support */ -#undef ARCHIVE_XATTR_DARWIN - -/* FreeBSD xattr support */ -#undef ARCHIVE_XATTR_FREEBSD - -/* Linux xattr support */ -#undef ARCHIVE_XATTR_LINUX - -/* Version number of bsdcat */ -#undef BSDCAT_VERSION_STRING - -/* Version number of bsdcpio */ -#undef BSDCPIO_VERSION_STRING - -/* Version number of bsdtar */ -#undef BSDTAR_VERSION_STRING - -/* Version number of bsdunzip */ -#undef BSDUNZIP_VERSION_STRING - -/* Define to 1 if the system has the type `ace_t'. */ -#undef HAVE_ACE_T - -/* Define to 1 if you have the `acl' function. */ -#undef HAVE_ACL - -/* Define to 1 if the system has the type `aclent_t'. */ -#undef HAVE_ACLENT_T - -/* Define to 1 if you have the `acl_add_flag_np' function. */ -#undef HAVE_ACL_ADD_FLAG_NP - -/* Define to 1 if you have the `acl_add_perm' function. */ -#undef HAVE_ACL_ADD_PERM - -/* Define to 1 if you have the `acl_clear_flags_np' function. */ -#undef HAVE_ACL_CLEAR_FLAGS_NP - -/* Define to 1 if you have the `acl_clear_perms' function. */ -#undef HAVE_ACL_CLEAR_PERMS - -/* Define to 1 if you have the `acl_create_entry' function. */ -#undef HAVE_ACL_CREATE_ENTRY - -/* Define to 1 if you have the `acl_delete_def_file' function. */ -#undef HAVE_ACL_DELETE_DEF_FILE - -/* Define to 1 if the system has the type `acl_entry_t'. */ -#undef HAVE_ACL_ENTRY_T - -/* Define to 1 if you have the `acl_free' function. */ -#undef HAVE_ACL_FREE - -/* Define to 1 if you have the `acl_get_brand_np' function. */ -#undef HAVE_ACL_GET_BRAND_NP - -/* Define to 1 if you have the `acl_get_entry' function. */ -#undef HAVE_ACL_GET_ENTRY - -/* Define to 1 if you have the `acl_get_entry_type_np' function. */ -#undef HAVE_ACL_GET_ENTRY_TYPE_NP - -/* Define to 1 if you have the `acl_get_fd' function. */ -#undef HAVE_ACL_GET_FD - -/* Define to 1 if you have the `acl_get_fd_np' function. */ -#undef HAVE_ACL_GET_FD_NP - -/* Define to 1 if you have the `acl_get_file' function. */ -#undef HAVE_ACL_GET_FILE - -/* Define to 1 if you have the `acl_get_flagset_np' function. */ -#undef HAVE_ACL_GET_FLAGSET_NP - -/* Define to 1 if you have the `acl_get_flag_np' function. */ -#undef HAVE_ACL_GET_FLAG_NP - -/* Define to 1 if you have the `acl_get_link_np' function. */ -#undef HAVE_ACL_GET_LINK_NP - -/* Define to 1 if you have the `acl_get_perm' function. */ -#undef HAVE_ACL_GET_PERM - -/* Define to 1 if you have the `acl_get_permset' function. */ -#undef HAVE_ACL_GET_PERMSET - -/* Define to 1 if you have the `acl_get_perm_np' function. */ -#undef HAVE_ACL_GET_PERM_NP - -/* Define to 1 if you have the `acl_get_qualifier' function. */ -#undef HAVE_ACL_GET_QUALIFIER - -/* Define to 1 if you have the `acl_get_tag_type' function. */ -#undef HAVE_ACL_GET_TAG_TYPE - -/* Define to 1 if you have the `acl_init' function. */ -#undef HAVE_ACL_INIT - -/* Define to 1 if you have the `acl_is_trivial_np' function. */ -#undef HAVE_ACL_IS_TRIVIAL_NP - -/* Define to 1 if you have the header file. */ -#undef HAVE_ACL_LIBACL_H - -/* Define to 1 if the system has the type `acl_permset_t'. */ -#undef HAVE_ACL_PERMSET_T - -/* Define to 1 if you have the `acl_set_entry_type_np' function. */ -#undef HAVE_ACL_SET_ENTRY_TYPE_NP - -/* Define to 1 if you have the `acl_set_fd' function. */ -#undef HAVE_ACL_SET_FD - -/* Define to 1 if you have the `acl_set_fd_np' function. */ -#undef HAVE_ACL_SET_FD_NP - -/* Define to 1 if you have the `acl_set_file' function. */ -#undef HAVE_ACL_SET_FILE - -/* Define to 1 if you have the `acl_set_link_np' function. */ -#undef HAVE_ACL_SET_LINK_NP - -/* Define to 1 if you have the `acl_set_qualifier' function. */ -#undef HAVE_ACL_SET_QUALIFIER - -/* Define to 1 if you have the `acl_set_tag_type' function. */ -#undef HAVE_ACL_SET_TAG_TYPE - -/* Define to 1 if the system has the type `acl_t'. */ -#undef HAVE_ACL_T - -/* Define to 1 if the system has the type `acl_tag_t'. */ -#undef HAVE_ACL_TAG_T - -/* Define to 1 if you have the `arc4random_buf' function. */ -#undef HAVE_ARC4RANDOM_BUF - -/* Define to 1 if you have the header file. */ -#undef HAVE_ATTR_XATTR_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_BCRYPT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_BLAKE2_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_BZLIB_H - -/* Define to 1 if you have the `chflags' function. */ -#undef HAVE_CHFLAGS - -/* Define to 1 if you have the `chown' function. */ -#undef HAVE_CHOWN - -/* Define to 1 if you have the `chroot' function. */ -#undef HAVE_CHROOT - -/* cmtime_s function */ -#undef HAVE_CMTIME_S - -/* Define to 1 if you have the header file. */ -#undef HAVE_COPYFILE_H - -/* Define to 1 if you have the `ctime_r' function. */ -#undef HAVE_CTIME_R - -/* Define to 1 if you have the header file. */ -#undef HAVE_CTYPE_H - -/* Define to 1 if you have the `cygwin_conv_path' function. */ -#undef HAVE_CYGWIN_CONV_PATH - -/* Define to 1 if you have the declaration of `ACE_GETACL', and to 0 if you - don't. */ -#undef HAVE_DECL_ACE_GETACL - -/* Define to 1 if you have the declaration of `ACE_GETACLCNT', and to 0 if you - don't. */ -#undef HAVE_DECL_ACE_GETACLCNT - -/* Define to 1 if you have the declaration of `ACE_SETACL', and to 0 if you - don't. */ -#undef HAVE_DECL_ACE_SETACL - -/* Define to 1 if you have the declaration of `ACL_SYNCHRONIZE', and to 0 if - you don't. */ -#undef HAVE_DECL_ACL_SYNCHRONIZE - -/* Define to 1 if you have the declaration of `ACL_TYPE_EXTENDED', and to 0 if - you don't. */ -#undef HAVE_DECL_ACL_TYPE_EXTENDED - -/* Define to 1 if you have the declaration of `ACL_TYPE_NFS4', and to 0 if you - don't. */ -#undef HAVE_DECL_ACL_TYPE_NFS4 - -/* Define to 1 if you have the declaration of `ACL_USER', and to 0 if you - don't. */ -#undef HAVE_DECL_ACL_USER - -/* Define to 1 if you have the declaration of `EXTATTR_NAMESPACE_USER', and to - 0 if you don't. */ -#undef HAVE_DECL_EXTATTR_NAMESPACE_USER - -/* Define to 1 if you have the declaration of `GETACL', and to 0 if you don't. - */ -#undef HAVE_DECL_GETACL - -/* Define to 1 if you have the declaration of `GETACLCNT', and to 0 if you - don't. */ -#undef HAVE_DECL_GETACLCNT - -/* Define to 1 if you have the declaration of `INT32_MAX', and to 0 if you - don't. */ -#undef HAVE_DECL_INT32_MAX - -/* Define to 1 if you have the declaration of `INT32_MIN', and to 0 if you - don't. */ -#undef HAVE_DECL_INT32_MIN - -/* Define to 1 if you have the declaration of `INT64_MAX', and to 0 if you - don't. */ -#undef HAVE_DECL_INT64_MAX - -/* Define to 1 if you have the declaration of `INT64_MIN', and to 0 if you - don't. */ -#undef HAVE_DECL_INT64_MIN - -/* Define to 1 if you have the declaration of `INTMAX_MAX', and to 0 if you - don't. */ -#undef HAVE_DECL_INTMAX_MAX - -/* Define to 1 if you have the declaration of `INTMAX_MIN', and to 0 if you - don't. */ -#undef HAVE_DECL_INTMAX_MIN - -/* Define to 1 if you have the declaration of `SETACL', and to 0 if you don't. - */ -#undef HAVE_DECL_SETACL - -/* Define to 1 if you have the declaration of `SIZE_MAX', and to 0 if you - don't. */ -#undef HAVE_DECL_SIZE_MAX - -/* Define to 1 if you have the declaration of `SSIZE_MAX', and to 0 if you - don't. */ -#undef HAVE_DECL_SSIZE_MAX - -/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you - don't. */ -#undef HAVE_DECL_STRERROR_R - -/* Define to 1 if you have the declaration of `UINT32_MAX', and to 0 if you - don't. */ -#undef HAVE_DECL_UINT32_MAX - -/* Define to 1 if you have the declaration of `UINT64_MAX', and to 0 if you - don't. */ -#undef HAVE_DECL_UINT64_MAX - -/* Define to 1 if you have the declaration of `UINTMAX_MAX', and to 0 if you - don't. */ -#undef HAVE_DECL_UINTMAX_MAX - -/* Define to 1 if you have the declaration of `XATTR_NOFOLLOW', and to 0 if - you don't. */ -#undef HAVE_DECL_XATTR_NOFOLLOW - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -#undef HAVE_DIRENT_H - -/* Define to 1 if you have a dirfd function or macro */ -#undef HAVE_DIRFD - -/* Define to 1 if you have the header file. */ -#undef HAVE_DLFCN_H - -/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ -#undef HAVE_DOPRNT - -/* Define to 1 if nl_langinfo supports D_MD_ORDER */ -#undef HAVE_D_MD_ORDER - -/* A possible errno value for invalid file format errors */ -#undef HAVE_EFTYPE - -/* A possible errno value for invalid file format errors */ -#undef HAVE_EILSEQ - -/* Define to 1 if you have the header file. */ -#undef HAVE_ERRNO_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_EXPAT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_EXT2FS_EXT2_FS_H - -/* Define to 1 if you have the `extattr_get_fd' function. */ -#undef HAVE_EXTATTR_GET_FD - -/* Define to 1 if you have the `extattr_get_file' function. */ -#undef HAVE_EXTATTR_GET_FILE - -/* Define to 1 if you have the `extattr_get_link' function. */ -#undef HAVE_EXTATTR_GET_LINK - -/* Define to 1 if you have the `extattr_list_fd' function. */ -#undef HAVE_EXTATTR_LIST_FD - -/* Define to 1 if you have the `extattr_list_file' function. */ -#undef HAVE_EXTATTR_LIST_FILE - -/* Define to 1 if you have the `extattr_list_link' function. */ -#undef HAVE_EXTATTR_LIST_LINK - -/* Define to 1 if you have the `extattr_set_fd' function. */ -#undef HAVE_EXTATTR_SET_FD - -/* Define to 1 if you have the `extattr_set_link' function. */ -#undef HAVE_EXTATTR_SET_LINK - -/* Define to 1 if you have the `facl' function. */ -#undef HAVE_FACL - -/* Define to 1 if you have the `fchdir' function. */ -#undef HAVE_FCHDIR - -/* Define to 1 if you have the `fchflags' function. */ -#undef HAVE_FCHFLAGS - -/* Define to 1 if you have the `fchmod' function. */ -#undef HAVE_FCHMOD - -/* Define to 1 if you have the `fchown' function. */ -#undef HAVE_FCHOWN - -/* Define to 1 if you have the `fcntl' function. */ -#undef HAVE_FCNTL - -/* Define to 1 if you have the header file. */ -#undef HAVE_FCNTL_H - -/* Define to 1 if you have the `fdopendir' function. */ -#undef HAVE_FDOPENDIR - -/* Define to 1 if you have the `fgetea' function. */ -#undef HAVE_FGETEA - -/* Define to 1 if you have the `fgetxattr' function. */ -#undef HAVE_FGETXATTR - -/* Define to 1 if you have the `flistea' function. */ -#undef HAVE_FLISTEA - -/* Define to 1 if you have the `flistxattr' function. */ -#undef HAVE_FLISTXATTR - -/* Define to 1 if you have the `fnmatch' function. */ -#undef HAVE_FNMATCH - -/* Define to 1 if you have the header file. */ -#undef HAVE_FNMATCH_H - -/* Define to 1 if you have the `fork' function. */ -#undef HAVE_FORK - -/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ -#undef HAVE_FSEEKO - -/* Define to 1 if you have the `fsetea' function. */ -#undef HAVE_FSETEA - -/* Define to 1 if you have the `fsetxattr' function. */ -#undef HAVE_FSETXATTR - -/* Define to 1 if you have the `fstat' function. */ -#undef HAVE_FSTAT - -/* Define to 1 if you have the `fstatat' function. */ -#undef HAVE_FSTATAT - -/* Define to 1 if you have the `fstatfs' function. */ -#undef HAVE_FSTATFS - -/* Define to 1 if you have the `fstatvfs' function. */ -#undef HAVE_FSTATVFS - -/* Define to 1 if you have the `ftruncate' function. */ -#undef HAVE_FTRUNCATE - -/* Define to 1 if you have the `futimens' function. */ -#undef HAVE_FUTIMENS - -/* Define to 1 if you have the `futimes' function. */ -#undef HAVE_FUTIMES - -/* Define to 1 if you have the `futimesat' function. */ -#undef HAVE_FUTIMESAT - -/* Define to 1 if you have the `getea' function. */ -#undef HAVE_GETEA - -/* Define to 1 if you have the `geteuid' function. */ -#undef HAVE_GETEUID - -/* Define to 1 if you have the `getgrgid_r' function. */ -#undef HAVE_GETGRGID_R - -/* Define to 1 if you have the `getgrnam_r' function. */ -#undef HAVE_GETGRNAM_R - -/* Define to 1 if you have the `getline' function. */ -#undef HAVE_GETLINE - -/* Define to 1 if you have the `getpid' function. */ -#undef HAVE_GETPID - -/* Define to 1 if you have the `getpwnam_r' function. */ -#undef HAVE_GETPWNAM_R - -/* Define to 1 if you have the `getpwuid_r' function. */ -#undef HAVE_GETPWUID_R - -/* Define to 1 if you have the `getvfsbyname' function. */ -#undef HAVE_GETVFSBYNAME - -/* Define to 1 if you have the `getxattr' function. */ -#undef HAVE_GETXATTR - -/* Define to 1 if you have the `gmtime_r' function. */ -#undef HAVE_GMTIME_R - -/* gmtime_s function */ -#undef HAVE_GMTIME_S - -/* Define to 1 if you have the header file. */ -#undef HAVE_GRP_H - -/* Define if you have the iconv() function and it works. */ -#undef HAVE_ICONV - -/* Define to 1 if you have the header file. */ -#undef HAVE_ICONV_H - -/* Define to 1 if the system has the type `intmax_t'. */ -#undef HAVE_INTMAX_T - -/* Define to 1 if you have the header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_IO_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_LANGINFO_H - -/* Define to 1 if you have the `lchflags' function. */ -#undef HAVE_LCHFLAGS - -/* Define to 1 if you have the `lchmod' function. */ -#undef HAVE_LCHMOD - -/* Define to 1 if you have the `lchown' function. */ -#undef HAVE_LCHOWN - -/* Define to 1 if you have the `lgetea' function. */ -#undef HAVE_LGETEA - -/* Define to 1 if you have the `lgetxattr' function. */ -#undef HAVE_LGETXATTR - -/* Define to 1 if you have the `acl' library (-lacl). */ -#undef HAVE_LIBACL - -/* Define to 1 if you have the `b2' library (-lb2). */ -#undef HAVE_LIBB2 - -/* Define to 1 if you have the `bz2' library (-lbz2). */ -#undef HAVE_LIBBZ2 - -/* Define to 1 if you have the `charset' library (-lcharset). */ -#undef HAVE_LIBCHARSET - -/* Define to 1 if you have the `crypto' library (-lcrypto). */ -#undef HAVE_LIBCRYPTO - -/* Define to 1 if you have the `expat' library (-lexpat). */ -#undef HAVE_LIBEXPAT - -/* Define to 1 if you have the `lz4' library (-llz4). */ -#undef HAVE_LIBLZ4 - -/* Define to 1 if you have the `lzma' library (-llzma). */ -#undef HAVE_LIBLZMA - -/* Define to 1 if you have the `lzo2' library (-llzo2). */ -#undef HAVE_LIBLZO2 - -/* Define to 1 if you have the `mbedcrypto' library (-lmbedcrypto). */ -#undef HAVE_LIBMBEDCRYPTO - -/* Define to 1 if you have the `md' library (-lmd). */ -#undef HAVE_LIBMD - -/* Define to 1 if you have the `nettle' library (-lnettle). */ -#undef HAVE_LIBNETTLE - -/* Define to 1 if you have the `pcre' library (-lpcre). */ -#undef HAVE_LIBPCRE - -/* Define to 1 if you have the `pcreposix' library (-lpcreposix). */ -#undef HAVE_LIBPCREPOSIX - -/* Define to 1 if you have the `regex' library (-lregex). */ -#undef HAVE_LIBREGEX - -/* Define to 1 if you have the `richacl' library (-lrichacl). */ -#undef HAVE_LIBRICHACL - -/* Define to 1 if you have the `xml2' library (-lxml2). */ -#undef HAVE_LIBXML2 - -/* Define to 1 if you have the header file. */ -#undef HAVE_LIBXML_XMLREADER_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_LIBXML_XMLWRITER_H - -/* Define to 1 if you have the `z' library (-lz). */ -#undef HAVE_LIBZ - -/* Define to 1 if you have the `zstd' library (-lzstd). */ -#undef HAVE_LIBZSTD - -/* Define to 1 if you have the `zstd' library (-lzstd) with compression - support. */ -#undef HAVE_LIBZSTD_COMPRESSOR - -/* Define to 1 if you have the header file. */ -#undef HAVE_LIMITS_H - -/* Define to 1 if you have the `link' function. */ -#undef HAVE_LINK - -/* Define to 1 if you have the `linkat' function. */ -#undef HAVE_LINKAT - -/* Define to 1 if you have the header file. */ -#undef HAVE_LINUX_FIEMAP_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_LINUX_FS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_LINUX_MAGIC_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_LINUX_TYPES_H - -/* Define to 1 if you have the `listea' function. */ -#undef HAVE_LISTEA - -/* Define to 1 if you have the `listxattr' function. */ -#undef HAVE_LISTXATTR - -/* Define to 1 if you have the `llistea' function. */ -#undef HAVE_LLISTEA - -/* Define to 1 if you have the `llistxattr' function. */ -#undef HAVE_LLISTXATTR - -/* Define to 1 if you have the header file. */ -#undef HAVE_LOCALCHARSET_H - -/* Define to 1 if you have the `locale_charset' function. */ -#undef HAVE_LOCALE_CHARSET - -/* Define to 1 if you have the header file. */ -#undef HAVE_LOCALE_H - -/* Define to 1 if you have the `localtime_r' function. */ -#undef HAVE_LOCALTIME_R - -/* localtime_s function */ -#undef HAVE_LOCALTIME_S - -/* Define to 1 if the system has the type `long long int'. */ -#undef HAVE_LONG_LONG_INT - -/* Define to 1 if you have the `lsetea' function. */ -#undef HAVE_LSETEA - -/* Define to 1 if you have the `lsetxattr' function. */ -#undef HAVE_LSETXATTR - -/* Define to 1 if you have the `lstat' function. */ -#undef HAVE_LSTAT - -/* Define to 1 if `lstat' has the bug that it succeeds when given the - zero-length file name argument. */ -#undef HAVE_LSTAT_EMPTY_STRING_BUG - -/* Define to 1 if you have the `lutimes' function. */ -#undef HAVE_LUTIMES - -/* Define to 1 if you have the header file. */ -#undef HAVE_LZ4HC_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_LZ4_H - -/* Define to 1 if you have the `LZMA_FILTER_ARM64' macro. */ -#undef HAVE_LZMA_FILTER_ARM64 - -/* Define to 1 if you have the header file. */ -#undef HAVE_LZMA_H - -/* Define to 1 if you have the `lzma_stream_encoder_mt' function. */ -#undef HAVE_LZMA_STREAM_ENCODER_MT - -/* Define to 1 if you have the header file. */ -#undef HAVE_LZO_LZO1X_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_LZO_LZOCONF_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_MBEDTLS_AES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_MBEDTLS_MD_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_MBEDTLS_PKCS5_H - -/* Define to 1 if you have the `mbrtowc' function. */ -#undef HAVE_MBRTOWC - -/* Define to 1 if you have the `mbr_gid_to_uuid' function. */ -#undef HAVE_MBR_GID_TO_UUID - -/* Define to 1 if you have the `mbr_uid_to_uuid' function. */ -#undef HAVE_MBR_UID_TO_UUID - -/* Define to 1 if you have the `mbr_uuid_to_id' function. */ -#undef HAVE_MBR_UUID_TO_ID - -/* Define to 1 if you have the header file. */ -#undef HAVE_MD5_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_MEMBERSHIP_H - -/* Define to 1 if you have the `memmove' function. */ -#undef HAVE_MEMMOVE - -/* Define to 1 if you have the `memset' function. */ -#undef HAVE_MEMSET - -/* Define to 1 if you have the header file. */ -#undef HAVE_MINIX_CONFIG_H - -/* Define to 1 if you have the `mkdir' function. */ -#undef HAVE_MKDIR - -/* Define to 1 if you have the `mkfifo' function. */ -#undef HAVE_MKFIFO - -/* Define to 1 if you have the `mknod' function. */ -#undef HAVE_MKNOD - -/* Define to 1 if you have the `mkstemp' function. */ -#undef HAVE_MKSTEMP - -/* Define to 1 if you have the header file, and it defines `DIR'. */ -#undef HAVE_NDIR_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_NETTLE_AES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_NETTLE_HMAC_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_NETTLE_MD5_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_NETTLE_PBKDF2_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_NETTLE_RIPEMD160_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_NETTLE_SHA_H - -/* Define to 1 if you have the `nl_langinfo' function. */ -#undef HAVE_NL_LANGINFO - -/* Define to 1 if you have the `openat' function. */ -#undef HAVE_OPENAT - -/* Define to 1 if you have the header file. */ -#undef HAVE_OPENSSL_EVP_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_PATHS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_PCREPOSIX_H - -/* Define to 1 if you have the `pipe' function. */ -#undef HAVE_PIPE - -/* Define to 1 if you have the `PKCS5_PBKDF2_HMAC_SHA1' function. */ -#undef HAVE_PKCS5_PBKDF2_HMAC_SHA1 - -/* Define to 1 if you have the `poll' function. */ -#undef HAVE_POLL - -/* Define to 1 if you have the header file. */ -#undef HAVE_POLL_H - -/* Define to 1 if you have the `posix_spawnp' function. */ -#undef HAVE_POSIX_SPAWNP - -/* Define to 1 if you have the header file. */ -#undef HAVE_PTHREAD_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_PWD_H - -/* Define to 1 if you have a POSIX compatible readdir_r */ -#undef HAVE_READDIR_R - -/* Define to 1 if you have the `readlink' function. */ -#undef HAVE_READLINK - -/* Define to 1 if you have the `readlinkat' function. */ -#undef HAVE_READLINKAT - -/* Define to 1 if you have the `readpassphrase' function. */ -#undef HAVE_READPASSPHRASE - -/* Define to 1 if you have the header file. */ -#undef HAVE_READPASSPHRASE_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_REGEX_H - -/* Define to 1 if you have the `richacl_alloc' function. */ -#undef HAVE_RICHACL_ALLOC - -/* Define to 1 if you have the `richacl_equiv_mode' function. */ -#undef HAVE_RICHACL_EQUIV_MODE - -/* Define to 1 if you have the `richacl_free' function. */ -#undef HAVE_RICHACL_FREE - -/* Define to 1 if you have the `richacl_get_fd' function. */ -#undef HAVE_RICHACL_GET_FD - -/* Define to 1 if you have the `richacl_get_file' function. */ -#undef HAVE_RICHACL_GET_FILE - -/* Define to 1 if you have the `richacl_set_fd' function. */ -#undef HAVE_RICHACL_SET_FD - -/* Define to 1 if you have the `richacl_set_file' function. */ -#undef HAVE_RICHACL_SET_FILE - -/* Define to 1 if you have the header file. */ -#undef HAVE_RIPEMD_H - -/* Define to 1 if you have the `select' function. */ -#undef HAVE_SELECT - -/* Define to 1 if you have the `setenv' function. */ -#undef HAVE_SETENV - -/* Define to 1 if you have the `setlocale' function. */ -#undef HAVE_SETLOCALE - -/* Define to 1 if you have the `setxattr' function. */ -#undef HAVE_SETXATTR - -/* Define to 1 if you have the header file. */ -#undef HAVE_SHA256_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SHA512_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SHA_H - -/* Define to 1 if you have the `sigaction' function. */ -#undef HAVE_SIGACTION - -/* Define to 1 if you have the header file. */ -#undef HAVE_SIGNAL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SPAWN_H - -/* Define to 1 if you have the `statfs' function. */ -#undef HAVE_STATFS - -/* Define to 1 if you have the `statvfs' function. */ -#undef HAVE_STATVFS - -/* Define to 1 if `stat' has the bug that it succeeds when given the - zero-length file name argument. */ -#undef HAVE_STAT_EMPTY_STRING_BUG - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDARG_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDIO_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the `strchr' function. */ -#undef HAVE_STRCHR - -/* Define to 1 if you have the `strdup' function. */ -#undef HAVE_STRDUP - -/* Define to 1 if you have the `strerror' function. */ -#undef HAVE_STRERROR - -/* Define if you have `strerror_r'. */ -#undef HAVE_STRERROR_R - -/* Define to 1 if you have the `strftime' function. */ -#undef HAVE_STRFTIME - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if you have the `strncpy_s' function. */ -#undef HAVE_STRNCPY_S - -/* Define to 1 if you have the `strnlen' function. */ -#undef HAVE_STRNLEN - -/* Define to 1 if you have the `strrchr' function. */ -#undef HAVE_STRRCHR - -/* Define to 1 if the system has the type `struct richace'. */ -#undef HAVE_STRUCT_RICHACE - -/* Define to 1 if the system has the type `struct richacl'. */ -#undef HAVE_STRUCT_RICHACL - -/* Define to 1 if the system has the type `struct statfs'. */ -#undef HAVE_STRUCT_STATFS - -/* Define to 1 if `f_iosize' is a member of `struct statfs'. */ -#undef HAVE_STRUCT_STATFS_F_IOSIZE - -/* Define to 1 if `f_namemax' is a member of `struct statfs'. */ -#undef HAVE_STRUCT_STATFS_F_NAMEMAX - -/* Define to 1 if `f_iosize' is a member of `struct statvfs'. */ -#undef HAVE_STRUCT_STATVFS_F_IOSIZE - -/* Define to 1 if `st_birthtime' is a member of `struct stat'. */ -#undef HAVE_STRUCT_STAT_ST_BIRTHTIME - -/* Define to 1 if `st_birthtimespec.tv_nsec' is a member of `struct stat'. */ -#undef HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC - -/* Define to 1 if `st_blksize' is a member of `struct stat'. */ -#undef HAVE_STRUCT_STAT_ST_BLKSIZE - -/* Define to 1 if `st_flags' is a member of `struct stat'. */ -#undef HAVE_STRUCT_STAT_ST_FLAGS - -/* Define to 1 if `st_mtimespec.tv_nsec' is a member of `struct stat'. */ -#undef HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC - -/* Define to 1 if `st_mtime_n' is a member of `struct stat'. */ -#undef HAVE_STRUCT_STAT_ST_MTIME_N - -/* Define to 1 if `st_mtime_usec' is a member of `struct stat'. */ -#undef HAVE_STRUCT_STAT_ST_MTIME_USEC - -/* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */ -#undef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC - -/* Define to 1 if `st_umtime' is a member of `struct stat'. */ -#undef HAVE_STRUCT_STAT_ST_UMTIME - -/* Define to 1 if `tm_gmtoff' is a member of `struct tm'. */ -#undef HAVE_STRUCT_TM_TM_GMTOFF - -/* Define to 1 if `__tm_gmtoff' is a member of `struct tm'. */ -#undef HAVE_STRUCT_TM___TM_GMTOFF - -/* Define to 1 if the system has the type `struct vfsconf'. */ -#undef HAVE_STRUCT_VFSCONF - -/* Define to 1 if the system has the type `struct xvfsconf'. */ -#undef HAVE_STRUCT_XVFSCONF - -/* Define to 1 if you have the `symlink' function. */ -#undef HAVE_SYMLINK - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_ACL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_CDEFS_H - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -#undef HAVE_SYS_DIR_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_EA_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_EXTATTR_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_IOCTL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_MKDEV_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_MOUNT_H - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -#undef HAVE_SYS_NDIR_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_PARAM_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_POLL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_QUEUE_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_RICHACL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_SELECT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_STATFS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_STATVFS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_SYSMACROS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TIME_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_UTIME_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_UTSNAME_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_VFS_H - -/* Define to 1 if you have that is POSIX.1 compatible. */ -#undef HAVE_SYS_WAIT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_XATTR_H - -/* Define to 1 if you have the `timegm' function. */ -#undef HAVE_TIMEGM - -/* Define to 1 if you have the header file. */ -#undef HAVE_TIME_H - -/* Define to 1 if you have the `tzset' function. */ -#undef HAVE_TZSET - -/* Define to 1 if the system has the type `uintmax_t'. */ -#undef HAVE_UINTMAX_T - -/* Define to 1 if you have the header file. */ -#undef HAVE_UNISTD_H - -/* Define to 1 if you have the `unlinkat' function. */ -#undef HAVE_UNLINKAT - -/* Define to 1 if you have the `unsetenv' function. */ -#undef HAVE_UNSETENV - -/* Define to 1 if the system has the type `unsigned long long'. */ -#undef HAVE_UNSIGNED_LONG_LONG - -/* Define to 1 if the system has the type `unsigned long long int'. */ -#undef HAVE_UNSIGNED_LONG_LONG_INT - -/* Define to 1 if you have the `utime' function. */ -#undef HAVE_UTIME - -/* Define to 1 if you have the `utimensat' function. */ -#undef HAVE_UTIMENSAT - -/* Define to 1 if you have the `utimes' function. */ -#undef HAVE_UTIMES - -/* Define to 1 if you have the header file. */ -#undef HAVE_UTIME_H - -/* Define to 1 if you have the `vfork' function. */ -#undef HAVE_VFORK - -/* Define to 1 if you have the `vprintf' function. */ -#undef HAVE_VPRINTF - -/* Define to 1 if you have the header file. */ -#undef HAVE_WCHAR_H - -/* Define to 1 if the system has the type `wchar_t'. */ -#undef HAVE_WCHAR_T - -/* Define to 1 if you have the `wcrtomb' function. */ -#undef HAVE_WCRTOMB - -/* Define to 1 if you have the `wcscmp' function. */ -#undef HAVE_WCSCMP - -/* Define to 1 if you have the `wcscpy' function. */ -#undef HAVE_WCSCPY - -/* Define to 1 if you have the `wcslen' function. */ -#undef HAVE_WCSLEN - -/* Define to 1 if you have the `wctomb' function. */ -#undef HAVE_WCTOMB - -/* Define to 1 if you have the header file. */ -#undef HAVE_WCTYPE_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_WINCRYPT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_WINDOWS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_WINIOCTL_H - -/* Define to 1 if you have the `wmemcmp' function. */ -#undef HAVE_WMEMCMP - -/* Define to 1 if you have the `wmemcpy' function. */ -#undef HAVE_WMEMCPY - -/* Define to 1 if you have the `wmemmove' function. */ -#undef HAVE_WMEMMOVE - -/* Define to 1 if you have a working EXT2_IOC_GETFLAGS */ -#undef HAVE_WORKING_EXT2_IOC_GETFLAGS - -/* Define to 1 if you have a working FS_IOC_GETFLAGS */ -#undef HAVE_WORKING_FS_IOC_GETFLAGS - -/* Define to 1 if you have the header file. */ -#undef HAVE_ZLIB_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_ZSTD_H - -/* Define to 1 if you have the `_fseeki64' function. */ -#undef HAVE__FSEEKI64 - -/* Define to 1 if you have the `_get_timezone' function. */ -#undef HAVE__GET_TIMEZONE - -/* _mkgmtime function */ -#undef HAVE__MKGMTIME - -/* Define as const if the declaration of iconv() needs const. */ -#undef ICONV_CONST - -/* Version number of libarchive as a single integer */ -#undef LIBARCHIVE_VERSION_NUMBER - -/* Version number of libarchive */ -#undef LIBARCHIVE_VERSION_STRING - -/* Define to 1 if `lstat' dereferences a symlink specified with a trailing - slash. */ -#undef LSTAT_FOLLOWS_SLASHED_SYMLINK - -/* Define to the sub-directory where libtool stores uninstalled libraries. */ -#undef LT_OBJDIR - -/* Define to 1 if `major', `minor', and `makedev' are declared in . - */ -#undef MAJOR_IN_MKDEV - -/* Define to 1 if `major', `minor', and `makedev' are declared in - . */ -#undef MAJOR_IN_SYSMACROS - -/* Define to '0x05020000' for Windows Server 2003 APIs. */ -#undef NTDDI_VERSION - -/* Name of package */ -#undef PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the home page for this package. */ -#undef PACKAGE_URL - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* Define to 1 if PCRE_STATIC needs to be defined. */ -#undef PCRE_STATIC - -/* The number of bytes in type int */ -#undef SIZEOF_INT - -/* The number of bytes in type long */ -#undef SIZEOF_LONG - -/* The size of `wchar_t', as computed by sizeof. */ -#undef SIZEOF_WCHAR_T - -/* Define to 1 if all of the C90 standard headers exist (not just the ones - required in a freestanding environment). This macro is provided for - backward compatibility; new code need not use it. */ -#undef STDC_HEADERS - -/* Define to 1 if strerror_r returns char *. */ -#undef STRERROR_R_CHAR_P - -/* Enable extensions on AIX 3, Interix. */ -#ifndef _ALL_SOURCE -# undef _ALL_SOURCE -#endif -/* Enable general extensions on macOS. */ -#ifndef _DARWIN_C_SOURCE -# undef _DARWIN_C_SOURCE -#endif -/* Enable general extensions on Solaris. */ -#ifndef __EXTENSIONS__ -# undef __EXTENSIONS__ -#endif -/* Enable GNU extensions on systems that have them. */ -#ifndef _GNU_SOURCE -# undef _GNU_SOURCE -#endif -/* Enable X/Open compliant socket functions that do not require linking - with -lxnet on HP-UX 11.11. */ -#ifndef _HPUX_ALT_XOPEN_SOCKET_API -# undef _HPUX_ALT_XOPEN_SOCKET_API -#endif -/* Identify the host operating system as Minix. - This macro does not affect the system headers' behavior. - A future release of Autoconf may stop defining this macro. */ -#ifndef _MINIX -# undef _MINIX -#endif -/* Enable general extensions on NetBSD. - Enable NetBSD compatibility extensions on Minix. */ -#ifndef _NETBSD_SOURCE -# undef _NETBSD_SOURCE -#endif -/* Enable OpenBSD compatibility extensions on NetBSD. - Oddly enough, this does nothing on OpenBSD. */ -#ifndef _OPENBSD_SOURCE -# undef _OPENBSD_SOURCE -#endif -/* Define to 1 if needed for POSIX-compatible behavior. */ -#ifndef _POSIX_SOURCE -# undef _POSIX_SOURCE -#endif -/* Define to 2 if needed for POSIX-compatible behavior. */ -#ifndef _POSIX_1_SOURCE -# undef _POSIX_1_SOURCE -#endif -/* Enable POSIX-compatible threading on Solaris. */ -#ifndef _POSIX_PTHREAD_SEMANTICS -# undef _POSIX_PTHREAD_SEMANTICS -#endif -/* Enable extensions specified by ISO/IEC TS 18661-5:2014. */ -#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__ -# undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__ -#endif -/* Enable extensions specified by ISO/IEC TS 18661-1:2014. */ -#ifndef __STDC_WANT_IEC_60559_BFP_EXT__ -# undef __STDC_WANT_IEC_60559_BFP_EXT__ -#endif -/* Enable extensions specified by ISO/IEC TS 18661-2:2015. */ -#ifndef __STDC_WANT_IEC_60559_DFP_EXT__ -# undef __STDC_WANT_IEC_60559_DFP_EXT__ -#endif -/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */ -#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__ -# undef __STDC_WANT_IEC_60559_FUNCS_EXT__ -#endif -/* Enable extensions specified by ISO/IEC TS 18661-3:2015. */ -#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__ -# undef __STDC_WANT_IEC_60559_TYPES_EXT__ -#endif -/* Enable extensions specified by ISO/IEC TR 24731-2:2010. */ -#ifndef __STDC_WANT_LIB_EXT2__ -# undef __STDC_WANT_LIB_EXT2__ -#endif -/* Enable extensions specified by ISO/IEC 24747:2009. */ -#ifndef __STDC_WANT_MATH_SPEC_FUNCS__ -# undef __STDC_WANT_MATH_SPEC_FUNCS__ -#endif -/* Enable extensions on HP NonStop. */ -#ifndef _TANDEM_SOURCE -# undef _TANDEM_SOURCE -#endif -/* Enable X/Open extensions. Define to 500 only if necessary - to make mbstate_t available. */ -#ifndef _XOPEN_SOURCE -# undef _XOPEN_SOURCE -#endif - - -/* Version number of package */ -#undef VERSION - -/* Define to '0x0502' for Windows Server 2003 APIs. */ -#undef WINVER - -/* Number of bits in a file offset, on hosts where this is settable. */ -#undef _FILE_OFFSET_BITS - -/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ -#undef _LARGEFILE_SOURCE - -/* Define for large files, on AIX-style hosts. */ -#undef _LARGE_FILES - -/* Define for Solaris 2.5.1 so the uint32_t typedef from , - , or is not used. If the typedef were allowed, the - #define below would cause a syntax error. */ -#undef _UINT32_T - -/* Define for Solaris 2.5.1 so the uint64_t typedef from , - , or is not used. If the typedef were allowed, the - #define below would cause a syntax error. */ -#undef _UINT64_T - -/* Define for Solaris 2.5.1 so the uint8_t typedef from , - , or is not used. If the typedef were allowed, the - #define below would cause a syntax error. */ -#undef _UINT8_T - -/* Define to '0x0502' for Windows Server 2003 APIs. */ -#undef _WIN32_WINNT - -/* Internal macro for sanity checks */ -#undef __LIBARCHIVE_CONFIG_H_INCLUDED - -/* Define to empty if `const' does not conform to ANSI C. */ -#undef const - -/* Define to match typeof st_gid field of struct stat if doesn't - define. */ -#undef gid_t - -/* Define to `unsigned long' if does not define. */ -#undef id_t - -/* Define to the type of a signed integer type of width exactly 16 bits if - such a type exists and the standard includes do not define it. */ -#undef int16_t - -/* Define to the type of a signed integer type of width exactly 32 bits if - such a type exists and the standard includes do not define it. */ -#undef int32_t - -/* Define to the type of a signed integer type of width exactly 64 bits if - such a type exists and the standard includes do not define it. */ -#undef int64_t - -/* Define to the widest signed integer type if and do - not define. */ -#undef intmax_t - -/* Define to `int' if does not define. */ -#undef mode_t - -/* Define to `long long' if does not define. */ -#undef off_t - -/* Define to `unsigned int' if does not define. */ -#undef size_t - -/* Define to match typeof st_uid field of struct stat if doesn't - define. */ -#undef uid_t - -/* Define to the type of an unsigned integer type of width exactly 16 bits if - such a type exists and the standard includes do not define it. */ -#undef uint16_t - -/* Define to the type of an unsigned integer type of width exactly 32 bits if - such a type exists and the standard includes do not define it. */ -#undef uint32_t - -/* Define to the type of an unsigned integer type of width exactly 64 bits if - such a type exists and the standard includes do not define it. */ -#undef uint64_t - -/* Define to the type of an unsigned integer type of width exactly 8 bits if - such a type exists and the standard includes do not define it. */ -#undef uint8_t - -/* Define to the widest unsigned integer type if and - do not define. */ -#undef uintmax_t - -/* Define to `unsigned int' if does not define. */ -#undef uintptr_t diff --git a/thirdparty/libarchive/configure b/thirdparty/libarchive/configure deleted file mode 100755 index 1024a0a7b..000000000 --- a/thirdparty/libarchive/configure +++ /dev/null @@ -1,25721 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for libarchive 3.7.2. -# -# Report bugs to . -# -# -# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, -# Inc. -# -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -as_nop=: -if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 -then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else $as_nop - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - - -# Reset variables that may have inherited troublesome values from -# the environment. - -# IFS needs to be set, to space, tab, and newline, in precisely that order. -# (If _AS_PATH_WALK were called with IFS unset, it would have the -# side effect of setting IFS to empty, thus disabling word splitting.) -# Quoting is to prevent editors from complaining about space-tab. -as_nl=' -' -export as_nl -IFS=" "" $as_nl" - -PS1='$ ' -PS2='> ' -PS4='+ ' - -# Ensure predictable behavior from utilities with locale-dependent output. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# We cannot yet rely on "unset" to work, but we need these variables -# to be unset--not just set to an empty or harmless value--now, to -# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct -# also avoids known problems related to "unset" and subshell syntax -# in other old shells (e.g. bash 2.01 and pdksh 5.2.14). -for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH -do eval test \${$as_var+y} \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done - -# Ensure that fds 0, 1, and 2 are open. -if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi -if (exec 3>&2) ; then :; else exec 2>/dev/null; fi - -# The user is always right. -if ${PATH_SEPARATOR+false} :; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - test -r "$as_dir$0" && as_myself=$as_dir$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - - -# Use a proper internal environment variable to ensure we don't fall - # into an infinite loop, continuously re-executing ourselves. - if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then - _as_can_reexec=no; export _as_can_reexec; - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 -exit 255 - fi - # We don't want this to propagate to other subprocesses. - { _as_can_reexec=; unset _as_can_reexec;} -if test "x$CONFIG_SHELL" = x; then - as_bourne_compatible="as_nop=: -if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 -then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else \$as_nop - case \`(set -o) 2>/dev/null\` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi -" - as_required="as_fn_return () { (exit \$1); } -as_fn_success () { as_fn_return 0; } -as_fn_failure () { as_fn_return 1; } -as_fn_ret_success () { return 0; } -as_fn_ret_failure () { return 1; } - -exitcode=0 -as_fn_success || { exitcode=1; echo as_fn_success failed.; } -as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } -as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } -as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } -if ( set x; as_fn_ret_success y && test x = \"\$1\" ) -then : - -else \$as_nop - exitcode=1; echo positional parameters were not saved. -fi -test x\$exitcode = x0 || exit 1 -blah=\$(echo \$(echo blah)) -test x\"\$blah\" = xblah || exit 1 -test -x / || exit 1" - as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO - as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO - eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && - test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 - - test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( - ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' - ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO - ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO - PATH=/empty FPATH=/empty; export PATH FPATH - test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ - || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 -test \$(( 1 + 1 )) = 2 || exit 1" - if (eval "$as_required") 2>/dev/null -then : - as_have_required=yes -else $as_nop - as_have_required=no -fi - if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null -then : - -else $as_nop - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_found=false -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - as_found=: - case $as_dir in #( - /*) - for as_base in sh bash ksh sh5; do - # Try only shells that exist, to save several forks. - as_shell=$as_dir$as_base - if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null -then : - CONFIG_SHELL=$as_shell as_have_required=yes - if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null -then : - break 2 -fi -fi - done;; - esac - as_found=false -done -IFS=$as_save_IFS -if $as_found -then : - -else $as_nop - if { test -f "$SHELL" || test -f "$SHELL.exe"; } && - as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null -then : - CONFIG_SHELL=$SHELL as_have_required=yes -fi -fi - - - if test "x$CONFIG_SHELL" != x -then : - export CONFIG_SHELL - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 -exit 255 -fi - - if test x$as_have_required = xno -then : - printf "%s\n" "$0: This script requires a shell more modern than all" - printf "%s\n" "$0: the shells that I found on your system." - if test ${ZSH_VERSION+y} ; then - printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" - printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." - else - printf "%s\n" "$0: Please tell bug-autoconf@gnu.org and -$0: libarchive-discuss@googlegroups.com about your system, -$0: including any error possibly output before this -$0: message. Then install a modern shell, or manually run -$0: the script under such a shell if you do have one." - fi - exit 1 -fi -fi -fi -SHELL=${CONFIG_SHELL-/bin/sh} -export SHELL -# Unset more variables known to interfere with behavior of common tools. -CLICOLOR_FORCE= GREP_OPTIONS= -unset CLICOLOR_FORCE GREP_OPTIONS - -## --------------------- ## -## M4sh Shell Functions. ## -## --------------------- ## -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset - - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit -# as_fn_nop -# --------- -# Do nothing but, unlike ":", preserve the value of $?. -as_fn_nop () -{ - return $? -} -as_nop=as_fn_nop - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -printf "%s\n" X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null -then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else $as_nop - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null -then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else $as_nop - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - -# as_fn_nop -# --------- -# Do nothing but, unlike ":", preserve the value of $?. -as_fn_nop () -{ - return $? -} -as_nop=as_fn_nop - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - printf "%s\n" "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -printf "%s\n" X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # If we had to re-execute with $CONFIG_SHELL, we're ensured to have - # already done that, so ensure we don't try to do so again and fall - # in an infinite loop. This has already happened in practice. - _as_can_reexec=no; export _as_can_reexec - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - - -# Determine whether it's possible to make 'echo' print without a newline. -# These variables are no longer used directly by Autoconf, but are AC_SUBSTed -# for compatibility with existing Makefiles. -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -# For backward compatibility with old third-party macros, we provide -# the shell variables $as_echo and $as_echo_n. New code should use -# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. -as_echo='printf %s\n' -as_echo_n='printf %s' - - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - -SHELL=${CONFIG_SHELL-/bin/sh} - - -test -n "$DJDIR" || exec 7<&0 &1 - -# Name of the host. -# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_clean_files= -ac_config_libobj_dir=. -LIBOBJS= -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= - -# Identity of this package. -PACKAGE_NAME='libarchive' -PACKAGE_TARNAME='libarchive' -PACKAGE_VERSION='3.7.2' -PACKAGE_STRING='libarchive 3.7.2' -PACKAGE_BUGREPORT='libarchive-discuss@googlegroups.com' -PACKAGE_URL='' - -ac_unique_file="libarchive" -# Factoring default headers for most tests. -ac_includes_default="\ -#include -#ifdef HAVE_STDIO_H -# include -#endif -#ifdef HAVE_STDLIB_H -# include -#endif -#ifdef HAVE_STRING_H -# include -#endif -#ifdef HAVE_INTTYPES_H -# include -#endif -#ifdef HAVE_STDINT_H -# include -#endif -#ifdef HAVE_STRINGS_H -# include -#endif -#ifdef HAVE_SYS_TYPES_H -# include -#endif -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef HAVE_UNISTD_H -# include -#endif" - -ac_header_c_list= -ac_func_c_list= -ac_subst_vars='am__EXEEXT_FALSE -am__EXEEXT_TRUE -LTLIBOBJS -LIBSREQUIRED -INC_FREEBSD_ACL_FALSE -INC_FREEBSD_ACL_TRUE -INC_DARWIN_ACL_FALSE -INC_DARWIN_ACL_TRUE -INC_SUNOS_ACL_FALSE -INC_SUNOS_ACL_TRUE -INC_LINUX_ACL_FALSE -INC_LINUX_ACL_TRUE -LIBOBJS -GC_SECTIONS -LIBXML2_PC_LIBS -LIBXML2_PC_CFLAGS -PKG_CONFIG_LIBDIR -PKG_CONFIG_PATH -PKG_CONFIG -LTLIBICONV -LIBICONV -INC_BLAKE2_FALSE -INC_BLAKE2_TRUE -STATIC_BSDUNZIP_FALSE -STATIC_BSDUNZIP_TRUE -BUILD_BSDUNZIP_FALSE -BUILD_BSDUNZIP_TRUE -STATIC_BSDCPIO_FALSE -STATIC_BSDCPIO_TRUE -BUILD_BSDCPIO_FALSE -BUILD_BSDCPIO_TRUE -STATIC_BSDCAT_FALSE -STATIC_BSDCAT_TRUE -BUILD_BSDCAT_FALSE -BUILD_BSDCAT_TRUE -STATIC_BSDTAR_FALSE -STATIC_BSDTAR_TRUE -BUILD_BSDTAR_FALSE -BUILD_BSDTAR_TRUE -LT_SYS_LIBRARY_PATH -OTOOL64 -OTOOL -LIPO -NMEDIT -DSYMUTIL -MANIFEST_TOOL -RANLIB -ac_ct_AR -AR -LN_S -NM -ac_ct_DUMPBIN -DUMPBIN -LD -FGREP -EGREP -GREP -SED -LIBTOOL -OBJDUMP -DLLTOOL -AS -CPP -am__fastdepCC_FALSE -am__fastdepCC_TRUE -CCDEPMODE -am__nodep -AMDEPBACKSLASH -AMDEP_FALSE -AMDEP_TRUE -am__include -DEPDIR -OBJEXT -EXEEXT -ac_ct_CC -CPPFLAGS -LDFLAGS -CFLAGS -CC -PLATFORMCPPFLAGS -INC_CYGWIN_FILES_FALSE -INC_CYGWIN_FILES_TRUE -INC_WINDOWS_FILES_FALSE -INC_WINDOWS_FILES_TRUE -host_os -host_vendor -host_cpu -host -build_os -build_vendor -build_cpu -build -LIBARCHIVE_VERSION_NUMBER -LIBARCHIVE_VERSION_STRING -BSDUNZIP_VERSION_STRING -BSDCAT_VERSION_STRING -BSDTAR_VERSION_STRING -BSDCPIO_VERSION_STRING -ARCHIVE_LIBTOOL_VERSION -MAINT -MAINTAINER_MODE_FALSE -MAINTAINER_MODE_TRUE -AM_BACKSLASH -AM_DEFAULT_VERBOSITY -AM_DEFAULT_V -AM_V -CSCOPE -ETAGS -CTAGS -am__untar -am__tar -AMTAR -am__leading_dot -SET_MAKE -AWK -mkdir_p -MKDIR_P -INSTALL_STRIP_PROGRAM -STRIP -install_sh -MAKEINFO -AUTOHEADER -AUTOMAKE -AUTOCONF -ACLOCAL -VERSION -PACKAGE -CYGPATH_W -am__isrc -INSTALL_DATA -INSTALL_SCRIPT -INSTALL_PROGRAM -target_alias -host_alias -build_alias -LIBS -ECHO_T -ECHO_N -ECHO_C -DEFS -mandir -localedir -libdir -psdir -pdfdir -dvidir -htmldir -infodir -docdir -oldincludedir -includedir -runstatedir -localstatedir -sharedstatedir -sysconfdir -datadir -datarootdir -libexecdir -sbindir -bindir -program_transform_name -prefix -exec_prefix -PACKAGE_URL -PACKAGE_BUGREPORT -PACKAGE_STRING -PACKAGE_VERSION -PACKAGE_TARNAME -PACKAGE_NAME -PATH_SEPARATOR -SHELL -am__quote' -ac_subst_files='' -ac_user_opts=' -enable_option_checking -enable_silent_rules -enable_maintainer_mode -enable_dependency_tracking -enable_shared -enable_static -with_pic -enable_fast_install -with_aix_soname -with_gnu_ld -with_sysroot -enable_libtool_lock -enable_bsdtar -enable_bsdcat -enable_bsdcpio -enable_bsdunzip -with_zlib -with_bz2lib -with_libb2 -with_iconv -enable_rpath -with_libiconv_prefix -with_lz4 -with_zstd -with_lzma -with_lzo2 -with_cng -with_mbedtls -with_nettle -with_openssl -with_xml2 -with_expat -enable_posix_regex_lib -enable_xattr -enable_acl -enable_largefile -' - ac_precious_vars='build_alias -host_alias -target_alias -CC -CFLAGS -LDFLAGS -LIBS -CPPFLAGS -CPP -LT_SYS_LIBRARY_PATH -PKG_CONFIG -PKG_CONFIG_PATH -PKG_CONFIG_LIBDIR -LIBXML2_PC_CFLAGS -LIBXML2_PC_LIBS' - - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -ac_unrecognized_opts= -ac_unrecognized_sep= -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -# (The list follows the same order as the GNU Coding Standards.) -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datarootdir='${prefix}/share' -datadir='${datarootdir}' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -runstatedir='${localstatedir}/run' -includedir='${prefix}/include' -oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' -infodir='${datarootdir}/info' -htmldir='${docdir}' -dvidir='${docdir}' -pdfdir='${docdir}' -psdir='${docdir}' -libdir='${exec_prefix}/lib' -localedir='${datarootdir}/locale' -mandir='${datarootdir}/man' - -ac_prev= -ac_dashdash= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval $ac_prev=\$ac_option - ac_prev= - continue - fi - - case $ac_option in - *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *=) ac_optarg= ;; - *) ac_optarg=yes ;; - esac - - case $ac_dashdash$ac_option in - --) - ac_dashdash=yes ;; - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=*) - datadir=$ac_optarg ;; - - -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ - | --dataroo | --dataro | --datar) - ac_prev=datarootdir ;; - -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ - | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) - datarootdir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: \`$ac_useropt'" - ac_useropt_orig=$ac_useropt - ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=no ;; - - -docdir | --docdir | --docdi | --doc | --do) - ac_prev=docdir ;; - -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) - docdir=$ac_optarg ;; - - -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) - ac_prev=dvidir ;; - -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) - dvidir=$ac_optarg ;; - - -enable-* | --enable-*) - ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: \`$ac_useropt'" - ac_useropt_orig=$ac_useropt - ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=\$ac_optarg ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) - ac_prev=htmldir ;; - -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ - | --ht=*) - htmldir=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localedir | --localedir | --localedi | --localed | --locale) - ac_prev=localedir ;; - -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) - localedir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst | --locals) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) - ac_prev=pdfdir ;; - -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) - pdfdir=$ac_optarg ;; - - -psdir | --psdir | --psdi | --psd | --ps) - ac_prev=psdir ;; - -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) - psdir=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -runstatedir | --runstatedir | --runstatedi | --runstated \ - | --runstate | --runstat | --runsta | --runst | --runs \ - | --run | --ru | --r) - ac_prev=runstatedir ;; - -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ - | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ - | --run=* | --ru=* | --r=*) - runstatedir=$ac_optarg ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: \`$ac_useropt'" - ac_useropt_orig=$ac_useropt - ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=\$ac_optarg ;; - - -without-* | --without-*) - ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: \`$ac_useropt'" - ac_useropt_orig=$ac_useropt - ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=no ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) as_fn_error $? "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information" - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - case $ac_envvar in #( - '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; - esac - eval $ac_envvar=\$ac_optarg - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2 - : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - as_fn_error $? "missing argument to $ac_option" -fi - -if test -n "$ac_unrecognized_opts"; then - case $enable_option_checking in - no) ;; - fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; - *) printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; - esac -fi - -# Check all directory arguments for consistency. -for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ - datadir sysconfdir sharedstatedir localstatedir includedir \ - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir runstatedir -do - eval ac_val=\$$ac_var - # Remove trailing slashes. - case $ac_val in - */ ) - ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` - eval $ac_var=\$ac_val;; - esac - # Be sure to have absolute directory names. - case $ac_val in - [\\/$]* | ?:[\\/]* ) continue;; - NONE | '' ) case $ac_var in *prefix ) continue;; esac;; - esac - as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -ac_pwd=`pwd` && test -n "$ac_pwd" && -ac_ls_di=`ls -di .` && -ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - as_fn_error $? "working directory cannot be determined" -test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - as_fn_error $? "pwd does not report name of working directory" - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then the parent directory. - ac_confdir=`$as_dirname -- "$as_myself" || -$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_myself" : 'X\(//\)[^/]' \| \ - X"$as_myself" : 'X\(//\)$' \| \ - X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || -printf "%s\n" X"$as_myself" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r "$srcdir/$ac_unique_file"; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r "$srcdir/$ac_unique_file"; then - test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" -fi -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" -ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" - pwd)` -# When building in place, set srcdir=. -if test "$ac_abs_confdir" = "$ac_pwd"; then - srcdir=. -fi -# Remove unnecessary trailing slashes from srcdir. -# Double slashes in file names in object file debugging info -# mess up M-x gdb in Emacs. -case $srcdir in -*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; -esac -for ac_var in $ac_precious_vars; do - eval ac_env_${ac_var}_set=\${${ac_var}+set} - eval ac_env_${ac_var}_value=\$${ac_var} - eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} - eval ac_cv_env_${ac_var}_value=\$${ac_var} -done - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures libarchive 3.7.2 to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking ...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --localedir=DIR locale-dependent data [DATAROOTDIR/locale] - --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/libarchive] - --htmldir=DIR html documentation [DOCDIR] - --dvidir=DIR dvi documentation [DOCDIR] - --pdfdir=DIR pdf documentation [DOCDIR] - --psdir=DIR ps documentation [DOCDIR] -_ACEOF - - cat <<\_ACEOF - -Program names: - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM run sed PROGRAM on installed program names - -System types: - --build=BUILD configure for building on BUILD [guessed] - --host=HOST cross-compile to build programs to run on HOST [BUILD] -_ACEOF -fi - -if test -n "$ac_init_help"; then - case $ac_init_help in - short | recursive ) echo "Configuration of libarchive 3.7.2:";; - esac - cat <<\_ACEOF - -Optional Features: - --disable-option-checking ignore unrecognized --enable/--with options - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-silent-rules less verbose build output (undo: "make V=1") - --disable-silent-rules verbose build output (undo: "make V=0") - --disable-maintainer-mode - disable make rules and dependencies not useful (and - sometimes confusing) to the casual installer - --enable-dependency-tracking - do not reject slow dependency extractors - --disable-dependency-tracking - speeds up one-time build - --enable-shared[=PKGS] build shared libraries [default=yes] - --enable-static[=PKGS] build static libraries [default=yes] - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) - --enable-bsdtar enable build of bsdtar (default) - --enable-bsdtar=static force static build of bsdtar - --enable-bsdtar=shared force dynamic build of bsdtar - --disable-bsdtar disable build of bsdtar - --enable-bsdcat enable build of bsdcat (default) - --enable-bsdcat=static force static build of bsdcat - --enable-bsdcat=shared force dynamic build of bsdcat - --disable-bsdcat disable build of bsdcat - --enable-bsdcpio enable build of bsdcpio (default) - --enable-bsdcpio=static static build of bsdcpio - --enable-bsdcpio=shared dynamic build of bsdcpio - --disable-bsdcpio disable build of bsdcpio - --enable-bsdunzip enable build of bsdunzip (default) - --enable-bsdunzip=static - force static build of bsdunzip - --enable-bsdunzip=shared - force dynamic build of bsdunzip - --disable-bsdunzip disable build of bsdunzip - --disable-rpath do not hardcode runtime library paths - --enable-posix-regex-lib - choose what library to use for POSIX regular - expression support (default: auto) - --enable-posix-regex-lib=libc - use libc POSIX regular expression support - --enable-posix-regex-lib=libregex - use libregex POSIX regular expression support - --enable-posix-regex-lib=libpcreposix - use libpcreposix POSIX regular expression support - --disable-posix-regex-lib - don't enable POSIX regular expression support - --disable-xattr Disable Extended Attributes support (default: check) - --disable-acl Disable ACL support (default: check) - --disable-largefile omit support for large files - -Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use - both] - --with-aix-soname=aix|svr4|both - shared library versioning (aka "SONAME") variant to - provide on AIX, [default=aix]. - --with-gnu-ld assume the C compiler uses GNU ld [default=no] - --with-sysroot[=DIR] Search for dependent libraries within DIR (or the - compiler's sysroot if not specified). - --without-zlib Don't build support for gzip through zlib - --without-bz2lib Don't build support for bzip2 through bz2lib - --without-libb2 Don't build support for BLAKE2 through libb2 - --without-iconv Don't try to link against iconv - --with-gnu-ld assume the C compiler uses GNU ld default=no - --with-libiconv-prefix[=DIR] search for libiconv in DIR/include and DIR/lib - --without-libiconv-prefix don't search for libiconv in includedir and libdir - --without-lz4 Don't build support for lz4 through liblz4 - --without-zstd Don't build support for zstd through libzstd - --without-lzma Don't build support for xz through lzma - --with-lzo2 Build with LZO support from liblzo2 - --without-cng Don't build support of CNG(Crypto Next Generation) - --with-mbedtls Build with crypto support from mbed TLS - --with-nettle Build with crypto support from Nettle - --without-openssl Don't build support for mtree and xar hashes through - openssl - --without-xml2 Don't build support for xar through libxml2 - --without-expat Don't build support for xar through expat - -Some influential environment variables: - CC C compiler command - CFLAGS C compiler flags - LDFLAGS linker flags, e.g. -L if you have libraries in a - nonstandard directory - LIBS libraries to pass to the linker, e.g. -l - CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if - you have headers in a nonstandard directory - CPP C preprocessor - LT_SYS_LIBRARY_PATH - User-defined run-time library search path. - PKG_CONFIG path to pkg-config utility - PKG_CONFIG_PATH - directories to add to pkg-config's search path - PKG_CONFIG_LIBDIR - path overriding pkg-config's built-in search path - LIBXML2_PC_CFLAGS - C compiler flags for LIBXML2_PC, overriding pkg-config - LIBXML2_PC_LIBS - linker flags for LIBXML2_PC, overriding pkg-config - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -Report bugs to . -_ACEOF -ac_status=$? -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d "$ac_dir" || - { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || - continue - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - cd "$ac_dir" || { ac_status=$?; continue; } - # Check for configure.gnu first; this name is used for a wrapper for - # Metaconfig's "Configure" on case-insensitive file systems. - if test -f "$ac_srcdir/configure.gnu"; then - echo && - $SHELL "$ac_srcdir/configure.gnu" --help=recursive - elif test -f "$ac_srcdir/configure"; then - echo && - $SHELL "$ac_srcdir/configure" --help=recursive - else - printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi || ac_status=$? - cd "$ac_pwd" || { ac_status=$?; break; } - done -fi - -test -n "$ac_init_help" && exit $ac_status -if $ac_init_version; then - cat <<\_ACEOF -libarchive configure 3.7.2 -generated by GNU Autoconf 2.71 - -Copyright (C) 2021 Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit -fi - -## ------------------------ ## -## Autoconf initialization. ## -## ------------------------ ## - -# ac_fn_c_try_compile LINENO -# -------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest.beam - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -printf "%s\n" "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext -then : - ac_retval=0 -else $as_nop - printf "%s\n" "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_compile - -# ac_fn_c_try_cpp LINENO -# ---------------------- -# Try to preprocess conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_cpp () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -printf "%s\n" "$ac_try_echo"; } >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } > conftest.i && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - } -then : - ac_retval=0 -else $as_nop - printf "%s\n" "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_cpp - -# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists and can be compiled using the include files in -# INCLUDES, setting the cache variable VAR accordingly. -ac_fn_c_check_header_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -printf %s "checking for $2... " >&6; } -if eval test \${$3+y} -then : - printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - eval "$3=yes" -else $as_nop - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -fi -eval ac_res=\$$3 - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -printf "%s\n" "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_compile - -# ac_fn_c_try_link LINENO -# ----------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_link () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -printf "%s\n" "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - test -x conftest$ac_exeext - } -then : - ac_retval=0 -else $as_nop - printf "%s\n" "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information - # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would - # interfere with the next link command; also delete a directory that is - # left behind by Apple's compiler. We do this before executing the actions. - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_link - -# ac_fn_c_check_func LINENO FUNC VAR -# ---------------------------------- -# Tests whether FUNC exists, setting the cache variable VAR accordingly -ac_fn_c_check_func () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -printf %s "checking for $2... " >&6; } -if eval test \${$3+y} -then : - printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -/* Define $2 to an innocuous variant, in case declares $2. - For example, HP-UX 11i declares gettimeofday. */ -#define $2 innocuous_$2 - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $2 (); below. */ - -#include -#undef $2 - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $2 (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$2 || defined __stub___$2 -choke me -#endif - -int -main (void) -{ -return $2 (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - eval "$3=yes" -else $as_nop - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -fi -eval ac_res=\$$3 - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -printf "%s\n" "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_func - -# ac_fn_c_try_run LINENO -# ---------------------- -# Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that -# executables *can* be run. -ac_fn_c_try_run () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -printf "%s\n" "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -printf "%s\n" "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; } -then : - ac_retval=0 -else $as_nop - printf "%s\n" "$as_me: program exited with status $ac_status" >&5 - printf "%s\n" "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=$ac_status -fi - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_run - -# ac_fn_c_check_type LINENO TYPE VAR INCLUDES -# ------------------------------------------- -# Tests whether TYPE exists after having included INCLUDES, setting cache -# variable VAR accordingly. -ac_fn_c_check_type () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -printf %s "checking for $2... " >&6; } -if eval test \${$3+y} -then : - printf %s "(cached) " >&6 -else $as_nop - eval "$3=no" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main (void) -{ -if (sizeof ($2)) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main (void) -{ -if (sizeof (($2))) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - -else $as_nop - eval "$3=yes" -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -fi -eval ac_res=\$$3 - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -printf "%s\n" "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_type - -# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES -# ---------------------------------------------------- -# Tries to find if the field MEMBER exists in type AGGR, after including -# INCLUDES, setting cache variable VAR accordingly. -ac_fn_c_check_member () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 -printf %s "checking for $2.$3... " >&6; } -if eval test \${$4+y} -then : - printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$5 -int -main (void) -{ -static $2 ac_aggr; -if (ac_aggr.$3) -return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - eval "$4=yes" -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$5 -int -main (void) -{ -static $2 ac_aggr; -if (sizeof ac_aggr.$3) -return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - eval "$4=yes" -else $as_nop - eval "$4=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -fi -eval ac_res=\$$4 - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -printf "%s\n" "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_member - -# ac_fn_c_find_intX_t LINENO BITS VAR -# ----------------------------------- -# Finds a signed integer type with width BITS, setting cache variable VAR -# accordingly. -ac_fn_c_find_intX_t () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5 -printf %s "checking for int$2_t... " >&6; } -if eval test \${$3+y} -then : - printf %s "(cached) " >&6 -else $as_nop - eval "$3=no" - # Order is important - never check a type that is potentially smaller - # than half of the expected target width. - for ac_type in int$2_t 'int' 'long int' \ - 'long long int' 'short int' 'signed char'; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default - enum { N = $2 / 2 - 1 }; -int -main (void) -{ -static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default - enum { N = $2 / 2 - 1 }; -int -main (void) -{ -static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1) - < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - -else $as_nop - case $ac_type in #( - int$2_t) : - eval "$3=yes" ;; #( - *) : - eval "$3=\$ac_type" ;; -esac -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - if eval test \"x\$"$3"\" = x"no" -then : - -else $as_nop - break -fi - done -fi -eval ac_res=\$$3 - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -printf "%s\n" "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_find_intX_t - -# ac_fn_c_find_uintX_t LINENO BITS VAR -# ------------------------------------ -# Finds an unsigned integer type with width BITS, setting cache variable VAR -# accordingly. -ac_fn_c_find_uintX_t () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5 -printf %s "checking for uint$2_t... " >&6; } -if eval test \${$3+y} -then : - printf %s "(cached) " >&6 -else $as_nop - eval "$3=no" - # Order is important - never check a type that is potentially smaller - # than half of the expected target width. - for ac_type in uint$2_t 'unsigned int' 'unsigned long int' \ - 'unsigned long long int' 'unsigned short int' 'unsigned char'; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -main (void) -{ -static int test_array [1 - 2 * !((($ac_type) -1 >> ($2 / 2 - 1)) >> ($2 / 2 - 1) == 3)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - case $ac_type in #( - uint$2_t) : - eval "$3=yes" ;; #( - *) : - eval "$3=\$ac_type" ;; -esac -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - if eval test \"x\$"$3"\" = x"no" -then : - -else $as_nop - break -fi - done -fi -eval ac_res=\$$3 - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -printf "%s\n" "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_find_uintX_t - -# ac_fn_check_decl LINENO SYMBOL VAR INCLUDES EXTRA-OPTIONS FLAG-VAR -# ------------------------------------------------------------------ -# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR -# accordingly. Pass EXTRA-OPTIONS to the compiler, using FLAG-VAR. -ac_fn_check_decl () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - as_decl_name=`echo $2|sed 's/ *(.*//'` - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 -printf %s "checking whether $as_decl_name is declared... " >&6; } -if eval test \${$3+y} -then : - printf %s "(cached) " >&6 -else $as_nop - as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` - eval ac_save_FLAGS=\$$6 - as_fn_append $6 " $5" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main (void) -{ -#ifndef $as_decl_name -#ifdef __cplusplus - (void) $as_decl_use; -#else - (void) $as_decl_name; -#endif -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - eval "$3=yes" -else $as_nop - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - eval $6=\$ac_save_FLAGS - -fi -eval ac_res=\$$3 - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -printf "%s\n" "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_check_decl - -# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES -# -------------------------------------------- -# Tries to find the compile-time value of EXPR in a program that includes -# INCLUDES, setting VAR accordingly. Returns whether the value could be -# computed -ac_fn_c_compute_int () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main (void) -{ -static int test_array [1 - 2 * !(($2) >= 0)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - ac_lo=0 ac_mid=0 - while :; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main (void) -{ -static int test_array [1 - 2 * !(($2) <= $ac_mid)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - ac_hi=$ac_mid; break -else $as_nop - as_fn_arith $ac_mid + 1 && ac_lo=$as_val - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - done -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main (void) -{ -static int test_array [1 - 2 * !(($2) < 0)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - ac_hi=-1 ac_mid=-1 - while :; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main (void) -{ -static int test_array [1 - 2 * !(($2) >= $ac_mid)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - ac_lo=$ac_mid; break -else $as_nop - as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - done -else $as_nop - ac_lo= ac_hi= -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main (void) -{ -static int test_array [1 - 2 * !(($2) <= $ac_mid)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - ac_hi=$ac_mid -else $as_nop - as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -done -case $ac_lo in #(( -?*) eval "$3=\$ac_lo"; ac_retval=0 ;; -'') ac_retval=1 ;; -esac - else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -static long int longval (void) { return $2; } -static unsigned long int ulongval (void) { return $2; } -#include -#include -int -main (void) -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - return 1; - if (($2) < 0) - { - long int i = longval (); - if (i != ($2)) - return 1; - fprintf (f, "%ld", i); - } - else - { - unsigned long int i = ulongval (); - if (i != ($2)) - return 1; - fprintf (f, "%lu", i); - } - /* Do not output a trailing newline, as this causes \r\n confusion - on some platforms. */ - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO" -then : - echo >>conftest.val; read $3 config.log <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by libarchive $as_me 3.7.2, which was -generated by GNU Autoconf 2.71. Invocation command line was - - $ $0$ac_configure_args_raw - -_ACEOF -exec 5>>config.log -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - printf "%s\n" "PATH: $as_dir" - done -IFS=$as_save_IFS - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *\'*) - ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; - 2) - as_fn_append ac_configure_args1 " '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - as_fn_append ac_configure_args " '$ac_arg'" - ;; - esac - done -done -{ ac_configure_args0=; unset ac_configure_args0;} -{ ac_configure_args1=; unset ac_configure_args1;} - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Use '\'' to represent an apostrophe within the trap. -# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. -trap 'exit_status=$? - # Sanitize IFS. - IFS=" "" $as_nl" - # Save into config.log some information that might help in debugging. - { - echo - - printf "%s\n" "## ---------------- ## -## Cache variables. ## -## ---------------- ##" - echo - # The following way of writing the cache mishandles newlines in values, -( - for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - (set) 2>&1 | - case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - sed -n \ - "s/'\''/'\''\\\\'\'''\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" - ;; #( - *) - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) - echo - - printf "%s\n" "## ----------------- ## -## Output variables. ## -## ----------------- ##" - echo - for ac_var in $ac_subst_vars - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - printf "%s\n" "$ac_var='\''$ac_val'\''" - done | sort - echo - - if test -n "$ac_subst_files"; then - printf "%s\n" "## ------------------- ## -## File substitutions. ## -## ------------------- ##" - echo - for ac_var in $ac_subst_files - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - printf "%s\n" "$ac_var='\''$ac_val'\''" - done | sort - echo - fi - - if test -s confdefs.h; then - printf "%s\n" "## ----------- ## -## confdefs.h. ## -## ----------- ##" - echo - cat confdefs.h - echo - fi - test "$ac_signal" != 0 && - printf "%s\n" "$as_me: caught signal $ac_signal" - printf "%s\n" "$as_me: exit $exit_status" - } >&5 - rm -f core *.core core.conftest.* && - rm -f -r conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status -' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -f -r conftest* confdefs.h - -printf "%s\n" "/* confdefs.h */" > confdefs.h - -# Predefined preprocessor variables. - -printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h - -printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h - -printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h - -printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h - -printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h - -printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h - - -# Let the site file select an alternate cache file if it wants to. -# Prefer an explicitly selected file to automatically selected ones. -if test -n "$CONFIG_SITE"; then - ac_site_files="$CONFIG_SITE" -elif test "x$prefix" != xNONE; then - ac_site_files="$prefix/share/config.site $prefix/etc/config.site" -else - ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" -fi - -for ac_site_file in $ac_site_files -do - case $ac_site_file in #( - */*) : - ;; #( - *) : - ac_site_file=./$ac_site_file ;; -esac - if test -f "$ac_site_file" && test -r "$ac_site_file"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 -printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" \ - || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5; } - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special files - # actually), so we avoid doing that. DJGPP emulates it as a regular file. - if test /dev/null != "$cache_file" && test -f "$cache_file"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 -printf "%s\n" "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . "$cache_file";; - *) . "./$cache_file";; - esac - fi -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 -printf "%s\n" "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Test code for whether the C compiler supports C89 (global declarations) -ac_c_conftest_c89_globals=' -/* Does the compiler advertise C89 conformance? - Do not test the value of __STDC__, because some compilers set it to 0 - while being otherwise adequately conformant. */ -#if !defined __STDC__ -# error "Compiler does not advertise C89 conformance" -#endif - -#include -#include -struct stat; -/* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */ -struct buf { int x; }; -struct buf * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not \xHH hex character constants. - These do not provoke an error unfortunately, instead are silently treated - as an "x". The following induces an error, until -std is added to get - proper ANSI mode. Curiously \x00 != x always comes out true, for an - array size at least. It is necessary to write \x00 == 0 to get something - that is true only with -std. */ -int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) '\''x'\'' -int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int), - int, int);' - -# Test code for whether the C compiler supports C89 (body of main). -ac_c_conftest_c89_main=' -ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]); -' - -# Test code for whether the C compiler supports C99 (global declarations) -ac_c_conftest_c99_globals=' -// Does the compiler advertise C99 conformance? -#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L -# error "Compiler does not advertise C99 conformance" -#endif - -#include -extern int puts (const char *); -extern int printf (const char *, ...); -extern int dprintf (int, const char *, ...); -extern void *malloc (size_t); - -// Check varargs macros. These examples are taken from C99 6.10.3.5. -// dprintf is used instead of fprintf to avoid needing to declare -// FILE and stderr. -#define debug(...) dprintf (2, __VA_ARGS__) -#define showlist(...) puts (#__VA_ARGS__) -#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) -static void -test_varargs_macros (void) -{ - int x = 1234; - int y = 5678; - debug ("Flag"); - debug ("X = %d\n", x); - showlist (The first, second, and third items.); - report (x>y, "x is %d but y is %d", x, y); -} - -// Check long long types. -#define BIG64 18446744073709551615ull -#define BIG32 4294967295ul -#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) -#if !BIG_OK - #error "your preprocessor is broken" -#endif -#if BIG_OK -#else - #error "your preprocessor is broken" -#endif -static long long int bignum = -9223372036854775807LL; -static unsigned long long int ubignum = BIG64; - -struct incomplete_array -{ - int datasize; - double data[]; -}; - -struct named_init { - int number; - const wchar_t *name; - double average; -}; - -typedef const char *ccp; - -static inline int -test_restrict (ccp restrict text) -{ - // See if C++-style comments work. - // Iterate through items via the restricted pointer. - // Also check for declarations in for loops. - for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i) - continue; - return 0; -} - -// Check varargs and va_copy. -static bool -test_varargs (const char *format, ...) -{ - va_list args; - va_start (args, format); - va_list args_copy; - va_copy (args_copy, args); - - const char *str = ""; - int number = 0; - float fnumber = 0; - - while (*format) - { - switch (*format++) - { - case '\''s'\'': // string - str = va_arg (args_copy, const char *); - break; - case '\''d'\'': // int - number = va_arg (args_copy, int); - break; - case '\''f'\'': // float - fnumber = va_arg (args_copy, double); - break; - default: - break; - } - } - va_end (args_copy); - va_end (args); - - return *str && number && fnumber; -} -' - -# Test code for whether the C compiler supports C99 (body of main). -ac_c_conftest_c99_main=' - // Check bool. - _Bool success = false; - success |= (argc != 0); - - // Check restrict. - if (test_restrict ("String literal") == 0) - success = true; - char *restrict newvar = "Another string"; - - // Check varargs. - success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234); - test_varargs_macros (); - - // Check flexible array members. - struct incomplete_array *ia = - malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); - ia->datasize = 10; - for (int i = 0; i < ia->datasize; ++i) - ia->data[i] = i * 1.234; - - // Check named initializers. - struct named_init ni = { - .number = 34, - .name = L"Test wide string", - .average = 543.34343, - }; - - ni.number = 58; - - int dynamic_array[ni.number]; - dynamic_array[0] = argv[0][0]; - dynamic_array[ni.number - 1] = 543; - - // work around unused variable warnings - ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\'' - || dynamic_array[ni.number - 1] != 543); -' - -# Test code for whether the C compiler supports C11 (global declarations) -ac_c_conftest_c11_globals=' -// Does the compiler advertise C11 conformance? -#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L -# error "Compiler does not advertise C11 conformance" -#endif - -// Check _Alignas. -char _Alignas (double) aligned_as_double; -char _Alignas (0) no_special_alignment; -extern char aligned_as_int; -char _Alignas (0) _Alignas (int) aligned_as_int; - -// Check _Alignof. -enum -{ - int_alignment = _Alignof (int), - int_array_alignment = _Alignof (int[100]), - char_alignment = _Alignof (char) -}; -_Static_assert (0 < -_Alignof (int), "_Alignof is signed"); - -// Check _Noreturn. -int _Noreturn does_not_return (void) { for (;;) continue; } - -// Check _Static_assert. -struct test_static_assert -{ - int x; - _Static_assert (sizeof (int) <= sizeof (long int), - "_Static_assert does not work in struct"); - long int y; -}; - -// Check UTF-8 literals. -#define u8 syntax error! -char const utf8_literal[] = u8"happens to be ASCII" "another string"; - -// Check duplicate typedefs. -typedef long *long_ptr; -typedef long int *long_ptr; -typedef long_ptr long_ptr; - -// Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. -struct anonymous -{ - union { - struct { int i; int j; }; - struct { int k; long int l; } w; - }; - int m; -} v1; -' - -# Test code for whether the C compiler supports C11 (body of main). -ac_c_conftest_c11_main=' - _Static_assert ((offsetof (struct anonymous, i) - == offsetof (struct anonymous, w.k)), - "Anonymous union alignment botch"); - v1.i = 2; - v1.w.k = 5; - ok |= v1.i != 5; -' - -# Test code for whether the C compiler supports C11 (complete). -ac_c_conftest_c11_program="${ac_c_conftest_c89_globals} -${ac_c_conftest_c99_globals} -${ac_c_conftest_c11_globals} - -int -main (int argc, char **argv) -{ - int ok = 0; - ${ac_c_conftest_c89_main} - ${ac_c_conftest_c99_main} - ${ac_c_conftest_c11_main} - return ok; -} -" - -# Test code for whether the C compiler supports C99 (complete). -ac_c_conftest_c99_program="${ac_c_conftest_c89_globals} -${ac_c_conftest_c99_globals} - -int -main (int argc, char **argv) -{ - int ok = 0; - ${ac_c_conftest_c89_main} - ${ac_c_conftest_c99_main} - return ok; -} -" - -# Test code for whether the C compiler supports C89 (complete). -ac_c_conftest_c89_program="${ac_c_conftest_c89_globals} - -int -main (int argc, char **argv) -{ - int ok = 0; - ${ac_c_conftest_c89_main} - return ok; -} -" - -as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H" -as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H" -as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H" -as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H" -as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H" -as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H" -as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H" -as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H" -as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H" -as_fn_append ac_header_c_list " wchar.h wchar_h HAVE_WCHAR_H" -as_fn_append ac_header_c_list " minix/config.h minix_config_h HAVE_MINIX_CONFIG_H" -as_fn_append ac_header_c_list " sys/time.h sys_time_h HAVE_SYS_TIME_H" -as_fn_append ac_func_c_list " vprintf HAVE_VPRINTF" - -# Auxiliary files required by this configure script. -ac_aux_files="config.rpath ltmain.sh compile config.guess config.sub missing install-sh" - -# Locations in which to look for auxiliary files. -ac_aux_dir_candidates="${srcdir}/build/autoconf" - -# Search for a directory containing all of the required auxiliary files, -# $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates. -# If we don't find one directory that contains all the files we need, -# we report the set of missing files from the *first* directory in -# $ac_aux_dir_candidates and give up. -ac_missing_aux_files="" -ac_first_candidate=: -printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5 -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_found=false -for as_dir in $ac_aux_dir_candidates -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - as_found=: - - printf "%s\n" "$as_me:${as_lineno-$LINENO}: trying $as_dir" >&5 - ac_aux_dir_found=yes - ac_install_sh= - for ac_aux in $ac_aux_files - do - # As a special case, if "install-sh" is required, that requirement - # can be satisfied by any of "install-sh", "install.sh", or "shtool", - # and $ac_install_sh is set appropriately for whichever one is found. - if test x"$ac_aux" = x"install-sh" - then - if test -f "${as_dir}install-sh"; then - printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install-sh found" >&5 - ac_install_sh="${as_dir}install-sh -c" - elif test -f "${as_dir}install.sh"; then - printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install.sh found" >&5 - ac_install_sh="${as_dir}install.sh -c" - elif test -f "${as_dir}shtool"; then - printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}shtool found" >&5 - ac_install_sh="${as_dir}shtool install -c" - else - ac_aux_dir_found=no - if $ac_first_candidate; then - ac_missing_aux_files="${ac_missing_aux_files} install-sh" - else - break - fi - fi - else - if test -f "${as_dir}${ac_aux}"; then - printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}${ac_aux} found" >&5 - else - ac_aux_dir_found=no - if $ac_first_candidate; then - ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}" - else - break - fi - fi - fi - done - if test "$ac_aux_dir_found" = yes; then - ac_aux_dir="$as_dir" - break - fi - ac_first_candidate=false - - as_found=false -done -IFS=$as_save_IFS -if $as_found -then : - -else $as_nop - as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5 -fi - - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -if test -f "${ac_aux_dir}config.guess"; then - ac_config_guess="$SHELL ${ac_aux_dir}config.guess" -fi -if test -f "${ac_aux_dir}config.sub"; then - ac_config_sub="$SHELL ${ac_aux_dir}config.sub" -fi -if test -f "$ac_aux_dir/configure"; then - ac_configure="$SHELL ${ac_aux_dir}configure" -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in $ac_precious_vars; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val=\$ac_cv_env_${ac_var}_value - eval ac_new_val=\$ac_env_${ac_var}_value - case $ac_old_set,$ac_new_set in - set,) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 -printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - # differences in whitespace do not lead to failure. - ac_old_val_w=`echo x $ac_old_val` - ac_new_val_w=`echo x $ac_new_val` - if test "$ac_old_val_w" != "$ac_new_val_w"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 -printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - ac_cache_corrupted=: - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 -printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} - eval $ac_var=\$ac_old_val - fi - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 -printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;} - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 -printf "%s\n" "$as_me: current value: \`$ac_new_val'" >&2;} - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) as_fn_append ac_configure_args " '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 -printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file' - and start over" "$LINENO" 5 -fi -## -------------------- ## -## Main body of script. ## -## -------------------- ## - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -# Make sure the srcdir contains "libarchive" directory - -# Use auxiliary subscripts from this subdirectory (cleans up root) - -# M4 scripts - -# Must follow AC_CONFIG macros above... -am__api_version='1.16' - - - - # Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -# Reject install programs that cannot install multiple files. -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 -printf %s "checking for a BSD-compatible install... " >&6; } -if test -z "$INSTALL"; then -if test ${ac_cv_path_install+y} -then : - printf %s "(cached) " >&6 -else $as_nop - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - # Account for fact that we put trailing slashes in our PATH walk. -case $as_dir in #(( - ./ | /[cC]/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext"; then - if test $ac_prog = install && - grep dspmsg "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - rm -rf conftest.one conftest.two conftest.dir - echo one > conftest.one - echo two > conftest.two - mkdir conftest.dir - if "$as_dir$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir/" && - test -s conftest.one && test -s conftest.two && - test -s conftest.dir/conftest.one && - test -s conftest.dir/conftest.two - then - ac_cv_path_install="$as_dir$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - fi - done - done - ;; -esac - - done -IFS=$as_save_IFS - -rm -rf conftest.one conftest.two conftest.dir - -fi - if test ${ac_cv_path_install+y}; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 -printf "%s\n" "$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 -printf %s "checking whether build environment is sane... " >&6; } -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[\\\"\#\$\&\'\`$am_lf]*) - as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; -esac -case $srcdir in - *[\\\"\#\$\&\'\`$am_lf\ \ ]*) - as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; -esac - -# Do 'set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - as_fn_error $? "ls -t appears to fail. Make sure there is not a broken - alias in your environment" "$LINENO" 5 - fi - if test "$2" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done - test "$2" = conftest.file - ) -then - # Ok. - : -else - as_fn_error $? "newly created file is older than distributed files! -Check your system clock" "$LINENO" 5 -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } -# If we didn't sleep, we still need to ensure time stamps of config.status and -# generated files are strictly newer. -am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & - am_sleep_pid=$! -fi - -rm -f conftest.file - -test "$program_prefix" != NONE && - program_transform_name="s&^&$program_prefix&;$program_transform_name" -# Use a double $ so make ignores it. -test "$program_suffix" != NONE && - program_transform_name="s&\$&$program_suffix&;$program_transform_name" -# Double any \ or $. -# By default was `s,x,x', remove it if useless. -ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' -program_transform_name=`printf "%s\n" "$program_transform_name" | sed "$ac_script"` - - -# Expand $ac_aux_dir to an absolute path. -am_aux_dir=`cd "$ac_aux_dir" && pwd` - - - if test x"${MISSING+set}" != xset; then - MISSING="\${SHELL} '$am_aux_dir/missing'" -fi -# Use eval to expand $SHELL -if eval "$MISSING --is-lightweight"; then - am_missing_run="$MISSING " -else - am_missing_run= - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 -printf "%s\n" "$as_me: WARNING: 'missing' script is too old or missing" >&2;} -fi - -if test x"${install_sh+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi - -# Installed binaries are usually stripped using 'strip' when the user -# run "make install-strip". However 'strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the 'STRIP' environment variable to overrule this program. -if test "$cross_compiling" != no; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_STRIP+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -printf "%s\n" "$STRIP" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_STRIP+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_STRIP="strip" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -printf "%s\n" "$ac_ct_STRIP" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" - - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a race-free mkdir -p" >&5 -printf %s "checking for a race-free mkdir -p... " >&6; } -if test -z "$MKDIR_P"; then - if test ${ac_cv_path_mkdir+y} -then : - printf %s "(cached) " >&6 -else $as_nop - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_prog in mkdir gmkdir; do - for ac_exec_ext in '' $ac_executable_extensions; do - as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext" || continue - case `"$as_dir$ac_prog$ac_exec_ext" --version 2>&1` in #( - 'mkdir ('*'coreutils) '* | \ - 'BusyBox '* | \ - 'mkdir (fileutils) '4.1*) - ac_cv_path_mkdir=$as_dir$ac_prog$ac_exec_ext - break 3;; - esac - done - done - done -IFS=$as_save_IFS - -fi - - test -d ./--version && rmdir ./--version - if test ${ac_cv_path_mkdir+y}; then - MKDIR_P="$ac_cv_path_mkdir -p" - else - # As a last resort, use the slow shell script. Don't cache a - # value for MKDIR_P within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - MKDIR_P="$ac_install_sh -d" - fi -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 -printf "%s\n" "$MKDIR_P" >&6; } - -for ac_prog in gawk mawk nawk awk -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_AWK+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$AWK"; then - ac_cv_prog_AWK="$AWK" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_AWK="$ac_prog" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AWK=$ac_cv_prog_AWK -if test -n "$AWK"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 -printf "%s\n" "$AWK" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - - test -n "$AWK" && break -done - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } -set x ${MAKE-make} -ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if eval test \${ac_cv_prog_make_${ac_make}_set+y} -then : - printf %s "(cached) " >&6 -else $as_nop - cat >conftest.make <<\_ACEOF -SHELL = /bin/sh -all: - @echo '@@@%%%=$(MAKE)=@@@%%%' -_ACEOF -# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. -case `${MAKE-make} -f conftest.make 2>/dev/null` in - *@@@%%%=?*=@@@%%%*) - eval ac_cv_prog_make_${ac_make}_set=yes;; - *) - eval ac_cv_prog_make_${ac_make}_set=no;; -esac -rm -f conftest.make -fi -if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - SET_MAKE= -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } - SET_MAKE="MAKE=${MAKE-make}" -fi - -rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null - -# Check whether --enable-silent-rules was given. -if test ${enable_silent_rules+y} -then : - enableval=$enable_silent_rules; -fi - -case $enable_silent_rules in # ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=1;; -esac -am_make=${MAKE-make} -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 -printf %s "checking whether $am_make supports nested variables... " >&6; } -if test ${am_cv_make_support_nested_variables+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if printf "%s\n" 'TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 -printf "%s\n" "$am_cv_make_support_nested_variables" >&6; } -if test $am_cv_make_support_nested_variables = yes; then - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AM_BACKSLASH='\' - -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - am__isrc=' -I$(srcdir)' - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi - - -# Define the identity of the package. - PACKAGE='libarchive' - VERSION='3.7.2' - - -printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h - - -printf "%s\n" "#define VERSION \"$VERSION\"" >>confdefs.h - -# Some tools Automake needs. - -ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} - - -AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} - - -AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} - - -AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} - - -MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} - -# For better backward compatibility. To be removed once Automake 1.9.x -# dies out for good. For more background, see: -# -# -mkdir_p='$(MKDIR_P)' - -# We need awk for the "check" target (and possibly the TAP driver). The -# system "awk" is bad on some platforms. -# Always define AMTAR for backward compatibility. Yes, it's still used -# in the wild :-( We should find a proper way to deprecate it ... -AMTAR='$${TAR-tar}' - - -# We'll loop over all known methods to create a tar archive until one works. -_am_tools='gnutar pax cpio none' - -am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' - - - - - -# Variables for tags utilities; see am/tags.am -if test -z "$CTAGS"; then - CTAGS=ctags -fi - -if test -z "$ETAGS"; then - ETAGS=etags -fi - -if test -z "$CSCOPE"; then - CSCOPE=cscope -fi - - - -# POSIX will say in a future version that running "rm -f" with no argument -# is OK; and we want to be able to make that assumption in our Makefile -# recipes. So use an aggressive probe to check that the usage we want is -# actually supported "in the wild" to an acceptable degree. -# See automake bug#10828. -# To make any issue more visible, cause the running configure to be aborted -# by default if the 'rm' program in use doesn't match our expectations; the -# user can still override this though. -if rm -f && rm -fr && rm -rf; then : OK; else - cat >&2 <<'END' -Oops! - -Your 'rm' program seems unable to run without file operands specified -on the command line, even when the '-f' option is present. This is contrary -to the behaviour of most rm programs out there, and not conforming with -the upcoming POSIX standard: - -Please tell bug-automake@gnu.org about your system, including the value -of your $PATH and any error possibly output before this message. This -can help us improve future automake versions. - -END - if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then - echo 'Configuration will proceed anyway, since you have set the' >&2 - echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 - echo >&2 - else - cat >&2 <<'END' -Aborting the configuration process, to ensure you take notice of the issue. - -You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . - -If you want to complete the configuration process using your problematic -'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM -to "yes", and re-run configure. - -END - as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 - fi -fi - - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 -printf %s "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } - # Check whether --enable-maintainer-mode was given. -if test ${enable_maintainer_mode+y} -then : - enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval -else $as_nop - USE_MAINTAINER_MODE=yes -fi - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 -printf "%s\n" "$USE_MAINTAINER_MODE" >&6; } - if test $USE_MAINTAINER_MODE = yes; then - MAINTAINER_MODE_TRUE= - MAINTAINER_MODE_FALSE='#' -else - MAINTAINER_MODE_TRUE='#' - MAINTAINER_MODE_FALSE= -fi - - MAINT=$MAINTAINER_MODE_TRUE - - -# Check whether --enable-silent-rules was given. -if test ${enable_silent_rules+y} -then : - enableval=$enable_silent_rules; -fi - -case $enable_silent_rules in # ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=0;; -esac -am_make=${MAKE-make} -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 -printf %s "checking whether $am_make supports nested variables... " >&6; } -if test ${am_cv_make_support_nested_variables+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if printf "%s\n" 'TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 -printf "%s\n" "$am_cv_make_support_nested_variables" >&6; } -if test $am_cv_make_support_nested_variables = yes; then - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AM_BACKSLASH='\' - - -# Libtool's "interface version" can be computed from the libarchive version. - -# Libtool interface version bumps on any API change, so increments -# whenever libarchive minor version does. -ARCHIVE_MINOR=$(( (3007002 / 1000) % 1000 )) -# Libarchive 2.7 == libtool interface 9 = 2 + 7 -# Libarchive 2.8 == libtool interface 10 = 2 + 8 -# Libarchive 2.9 == libtool interface 11 = 2 + 8 -# Libarchive 3.0 == libtool interface 12 -# Libarchive 3.1 == libtool interface 13 -ARCHIVE_INTERFACE=`echo $((13 + ${ARCHIVE_MINOR}))` -# Libarchive revision is bumped on any source change === libtool revision -ARCHIVE_REVISION=$(( 3007002 % 1000 )) -# Libarchive minor is bumped on any interface addition === libtool age -ARCHIVE_LIBTOOL_VERSION=$ARCHIVE_INTERFACE:$ARCHIVE_REVISION:$ARCHIVE_MINOR - -# Stick the version numbers into config.h - -printf "%s\n" "#define __LIBARCHIVE_CONFIG_H_INCLUDED 1" >>confdefs.h - - -printf "%s\n" "#define LIBARCHIVE_VERSION_STRING \"3.7.2\"" >>confdefs.h - - -printf "%s\n" "#define LIBARCHIVE_VERSION_NUMBER \"3007002\"" >>confdefs.h - - -printf "%s\n" "#define BSDCPIO_VERSION_STRING \"3.7.2\"" >>confdefs.h - - -printf "%s\n" "#define BSDTAR_VERSION_STRING \"3.7.2\"" >>confdefs.h - - -printf "%s\n" "#define BSDCAT_VERSION_STRING \"3.7.2\"" >>confdefs.h - - -printf "%s\n" "#define BSDUNZIP_VERSION_STRING \"3.7.2\"" >>confdefs.h - - -# The shell variables here must be the same as the AC_SUBST() variables -# below, but the shell variable names apparently cannot be the same as -# the m4 macro names above. Why? Ask autoconf. -BSDCPIO_VERSION_STRING=3.7.2 -BSDTAR_VERSION_STRING=3.7.2 -BSDCAT_VERSION_STRING=3.7.2 -BSDUNZIP_VERSION_STRING=3.7.2 -LIBARCHIVE_VERSION_STRING=3.7.2 -LIBARCHIVE_VERSION_NUMBER=3007002 - -# Substitute the above version numbers into the various files below. -# Yes, I believe this is the fourth time we define what are essentially -# the same symbols. Why? Ask autoconf. - - - - - - - - -ac_config_headers="$ac_config_headers config.h" - -ac_config_files="$ac_config_files Makefile" - -ac_config_files="$ac_config_files build/pkgconfig/libarchive.pc" - - -# Check for host type - - - # Make sure we can run config.sub. -$SHELL "${ac_aux_dir}config.sub" sun4 >/dev/null 2>&1 || - as_fn_error $? "cannot run $SHELL ${ac_aux_dir}config.sub" "$LINENO" 5 - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 -printf %s "checking build system type... " >&6; } -if test ${ac_cv_build+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_build_alias=$build_alias -test "x$ac_build_alias" = x && - ac_build_alias=`$SHELL "${ac_aux_dir}config.guess"` -test "x$ac_build_alias" = x && - as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 -ac_cv_build=`$SHELL "${ac_aux_dir}config.sub" $ac_build_alias` || - as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $ac_build_alias failed" "$LINENO" 5 - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 -printf "%s\n" "$ac_cv_build" >&6; } -case $ac_cv_build in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; -esac -build=$ac_cv_build -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_build -shift -build_cpu=$1 -build_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -build_os=$* -IFS=$ac_save_IFS -case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac - - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 -printf %s "checking host system type... " >&6; } -if test ${ac_cv_host+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test "x$host_alias" = x; then - ac_cv_host=$ac_cv_build -else - ac_cv_host=`$SHELL "${ac_aux_dir}config.sub" $host_alias` || - as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $host_alias failed" "$LINENO" 5 -fi - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 -printf "%s\n" "$ac_cv_host" >&6; } -case $ac_cv_host in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; -esac -host=$ac_cv_host -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_host -shift -host_cpu=$1 -host_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -host_os=$* -IFS=$ac_save_IFS -case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac - - - -inc_windows_files=no -inc_cygwin_files=no -case "$host_os" in - *mingw* ) inc_windows_files=yes ;; - *cygwin* | *msys*) inc_cygwin_files=yes ;; -esac - if test $inc_windows_files = yes; then - INC_WINDOWS_FILES_TRUE= - INC_WINDOWS_FILES_FALSE='#' -else - INC_WINDOWS_FILES_TRUE='#' - INC_WINDOWS_FILES_FALSE= -fi - - if test $inc_cygwin_files = yes; then - INC_CYGWIN_FILES_TRUE= - INC_CYGWIN_FILES_FALSE='#' -else - INC_CYGWIN_FILES_TRUE='#' - INC_CYGWIN_FILES_FALSE= -fi - - -PLATFORMCPPFLAGS= -case "$host_os" in - *mingw* ) PLATFORMCPPFLAGS=-D__USE_MINGW_ANSI_STDIO -D__MINGW_USE_VC2005_COMPAT ;; -esac - - -# Checks for programs. - - - - - - - - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_CC+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -printf "%s\n" "$CC" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_CC+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -printf "%s\n" "$ac_ct_CC" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_CC+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -printf "%s\n" "$CC" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_CC+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -printf "%s\n" "$CC" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_CC+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -printf "%s\n" "$CC" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_CC+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="$ac_prog" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -printf "%s\n" "$ac_ct_CC" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. -set dummy ${ac_tool_prefix}clang; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_CC+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}clang" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -printf "%s\n" "$CC" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "clang", so it can be a program name with args. -set dummy clang; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_CC+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="clang" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -printf "%s\n" "$ac_ct_CC" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -fi - - -test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } - -# Provide some information about the compiler. -printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion -version; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -printf "%s\n" "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main (void) -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 -printf %s "checking whether the C compiler works... " >&6; } -ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'` - -# The possible output files: -ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" - -ac_rmfiles= -for ac_file in $ac_files -do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - * ) ac_rmfiles="$ac_rmfiles $ac_file";; - esac -done -rm -f $ac_rmfiles - -if { { ac_try="$ac_link_default" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -printf "%s\n" "$ac_try_echo"; } >&5 - (eval "$ac_link_default") 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -then : - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' -# in a Makefile. We should not override ac_cv_exeext if it was cached, -# so that the user can short-circuit this test for compilers unknown to -# Autoconf. -for ac_file in $ac_files '' -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no; - then :; else - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - fi - # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' - # argument, so we may need to know it at that point already. - # Even if this section looks crufty: it has the advantage of - # actually working. - break;; - * ) - break;; - esac -done -test "$ac_cv_exeext" = no && ac_cv_exeext= - -else $as_nop - ac_file='' -fi -if test -z "$ac_file" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -printf "%s\n" "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "C compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5; } -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 -printf %s "checking for C compiler default output file name... " >&6; } -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 -printf "%s\n" "$ac_file" >&6; } -ac_exeext=$ac_cv_exeext - -rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 -printf %s "checking for suffix of executables... " >&6; } -if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -printf "%s\n" "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -then : - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - break;; - * ) break;; - esac -done -else $as_nop - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest conftest$ac_cv_exeext -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 -printf "%s\n" "$ac_cv_exeext" >&6; } - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main (void) -{ -FILE *f = fopen ("conftest.out", "w"); - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -ac_clean_files="$ac_clean_files conftest.out" -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 -printf %s "checking whether we are cross compiling... " >&6; } -if test "$cross_compiling" != yes; then - { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -printf "%s\n" "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if { ac_try='./conftest$ac_cv_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -printf "%s\n" "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5; } - fi - fi -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 -printf "%s\n" "$cross_compiling" >&6; } - -rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out -ac_clean_files=$ac_clean_files_save -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 -printf %s "checking for suffix of object files... " >&6; } -if test ${ac_cv_objext+y} -then : - printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main (void) -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -printf "%s\n" "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -then : - for ac_file in conftest.o conftest.obj conftest.*; do - test -f "$ac_file" || continue; - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else $as_nop - printf "%s\n" "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 -printf "%s\n" "$ac_cv_objext" >&6; } -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 -printf %s "checking whether the compiler supports GNU C... " >&6; } -if test ${ac_cv_c_compiler_gnu+y} -then : - printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main (void) -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - ac_compiler_gnu=yes -else $as_nop - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -if test $ac_compiler_gnu = yes; then - GCC=yes -else - GCC= -fi -ac_test_CFLAGS=${CFLAGS+y} -ac_save_CFLAGS=$CFLAGS -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -printf %s "checking whether $CC accepts -g... " >&6; } -if test ${ac_cv_prog_cc_g+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - ac_cv_prog_cc_g=yes -else $as_nop - CFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - -else $as_nop - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - ac_cv_prog_cc_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -printf "%s\n" "$ac_cv_prog_cc_g" >&6; } -if test $ac_test_CFLAGS; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -ac_prog_cc_stdc=no -if test x$ac_prog_cc_stdc = xno -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 -printf %s "checking for $CC option to enable C11 features... " >&6; } -if test ${ac_cv_prog_cc_c11+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_cv_prog_cc_c11=no -ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_c_conftest_c11_program -_ACEOF -for ac_arg in '' -std=gnu11 -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO" -then : - ac_cv_prog_cc_c11=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam - test "x$ac_cv_prog_cc_c11" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC -fi - -if test "x$ac_cv_prog_cc_c11" = xno -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -printf "%s\n" "unsupported" >&6; } -else $as_nop - if test "x$ac_cv_prog_cc_c11" = x -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -printf "%s\n" "none needed" >&6; } -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 -printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } - CC="$CC $ac_cv_prog_cc_c11" -fi - ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 - ac_prog_cc_stdc=c11 -fi -fi -if test x$ac_prog_cc_stdc = xno -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 -printf %s "checking for $CC option to enable C99 features... " >&6; } -if test ${ac_cv_prog_cc_c99+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_cv_prog_cc_c99=no -ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_c_conftest_c99_program -_ACEOF -for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO" -then : - ac_cv_prog_cc_c99=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam - test "x$ac_cv_prog_cc_c99" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC -fi - -if test "x$ac_cv_prog_cc_c99" = xno -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -printf "%s\n" "unsupported" >&6; } -else $as_nop - if test "x$ac_cv_prog_cc_c99" = x -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -printf "%s\n" "none needed" >&6; } -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 -printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } - CC="$CC $ac_cv_prog_cc_c99" -fi - ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 - ac_prog_cc_stdc=c99 -fi -fi -if test x$ac_prog_cc_stdc = xno -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 -printf %s "checking for $CC option to enable C89 features... " >&6; } -if test ${ac_cv_prog_cc_c89+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_c_conftest_c89_program -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO" -then : - ac_cv_prog_cc_c89=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC -fi - -if test "x$ac_cv_prog_cc_c89" = xno -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -printf "%s\n" "unsupported" >&6; } -else $as_nop - if test "x$ac_cv_prog_cc_c89" = x -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -printf "%s\n" "none needed" >&6; } -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } - CC="$CC $ac_cv_prog_cc_c89" -fi - ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 - ac_prog_cc_stdc=c89 -fi -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 -printf %s "checking whether $CC understands -c and -o together... " >&6; } -if test ${am_cv_prog_cc_c_o+y} -then : - printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main (void) -{ - - ; - return 0; -} -_ACEOF - # Make sure it works both with $CC and with simple cc. - # Following AC_PROG_CC_C_O, we do the test twice because some - # compilers refuse to overwrite an existing .o file with -o, - # though they will create one. - am_cv_prog_cc_c_o=yes - for am_i in 1 2; do - if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 - ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } \ - && test -f conftest2.$ac_objext; then - : OK - else - am_cv_prog_cc_c_o=no - break - fi - done - rm -f core conftest* - unset am_i -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 -printf "%s\n" "$am_cv_prog_cc_c_o" >&6; } -if test "$am_cv_prog_cc_c_o" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -DEPDIR="${am__leading_dot}deps" - -ac_config_commands="$ac_config_commands depfiles" - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 -printf %s "checking whether ${MAKE-make} supports the include directive... " >&6; } -cat > confinc.mk << 'END' -am__doit: - @echo this is the am__doit target >confinc.out -.PHONY: am__doit -END -am__include="#" -am__quote= -# BSD make does it like this. -echo '.include "confinc.mk" # ignored' > confmf.BSD -# Other make implementations (GNU, Solaris 10, AIX) do it like this. -echo 'include confinc.mk # ignored' > confmf.GNU -_am_result=no -for s in GNU BSD; do - { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 - (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - case $?:`cat confinc.out 2>/dev/null` in #( - '0:this is the am__doit target') : - case $s in #( - BSD) : - am__include='.include' am__quote='"' ;; #( - *) : - am__include='include' am__quote='' ;; -esac ;; #( - *) : - ;; -esac - if test "$am__include" != "#"; then - _am_result="yes ($s style)" - break - fi -done -rm -f confinc.* confmf.* -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 -printf "%s\n" "${_am_result}" >&6; } - -# Check whether --enable-dependency-tracking was given. -if test ${enable_dependency_tracking+y} -then : - enableval=$enable_dependency_tracking; -fi - -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' - am__nodep='_no' -fi - if test "x$enable_dependency_tracking" != xno; then - AMDEP_TRUE= - AMDEP_FALSE='#' -else - AMDEP_TRUE='#' - AMDEP_FALSE= -fi - - - -depcc="$CC" am_compiler_list= - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 -printf %s "checking dependency style of $depcc... " >&6; } -if test ${am_cv_CC_dependencies_compiler_type+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named 'D' -- because '-MD' means "put the output - # in D". - rm -rf conftest.dir - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CC_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - am__universal=false - case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with - # Solaris 10 /bin/sh. - echo '/* dummy */' > sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with '-c' and '-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle '-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs. - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # After this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested. - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok '-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CC_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CC_dependencies_compiler_type=none -fi - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 -printf "%s\n" "$am_cv_CC_dependencies_compiler_type" >&6; } -CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type - - if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then - am__fastdepCC_TRUE= - am__fastdepCC_FALSE='#' -else - am__fastdepCC_TRUE='#' - am__fastdepCC_FALSE= -fi - - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 -printf %s "checking how to run the C preprocessor... " >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if test ${ac_cv_prog_CPP+y} -then : - printf %s "(cached) " >&6 -else $as_nop - # Double quotes because $CC needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" cpp /lib/cpp - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO" -then : - -else $as_nop - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO" -then : - # Broken: success on invalid input. -continue -else $as_nop - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok -then : - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 -printf "%s\n" "$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO" -then : - -else $as_nop - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO" -then : - # Broken: success on invalid input. -continue -else $as_nop - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok -then : - -else $as_nop - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -ac_header= ac_cache= -for ac_item in $ac_header_c_list -do - if test $ac_cache; then - ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default" - if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then - printf "%s\n" "#define $ac_item 1" >> confdefs.h - fi - ac_header= ac_cache= - elif test $ac_header; then - ac_cache=$ac_item - else - ac_header=$ac_item - fi -done - - - - - - - - -if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes -then : - -printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h - -fi - - - - - - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 -printf %s "checking whether it is safe to define __EXTENSIONS__... " >&6; } -if test ${ac_cv_safe_to_define___extensions__+y} -then : - printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -# define __EXTENSIONS__ 1 - $ac_includes_default -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - ac_cv_safe_to_define___extensions__=yes -else $as_nop - ac_cv_safe_to_define___extensions__=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 -printf "%s\n" "$ac_cv_safe_to_define___extensions__" >&6; } - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether _XOPEN_SOURCE should be defined" >&5 -printf %s "checking whether _XOPEN_SOURCE should be defined... " >&6; } -if test ${ac_cv_should_define__xopen_source+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_cv_should_define__xopen_source=no - if test $ac_cv_header_wchar_h = yes -then : - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include - mbstate_t x; -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #define _XOPEN_SOURCE 500 - #include - mbstate_t x; -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - ac_cv_should_define__xopen_source=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -fi -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_should_define__xopen_source" >&5 -printf "%s\n" "$ac_cv_should_define__xopen_source" >&6; } - - printf "%s\n" "#define _ALL_SOURCE 1" >>confdefs.h - - printf "%s\n" "#define _DARWIN_C_SOURCE 1" >>confdefs.h - - printf "%s\n" "#define _GNU_SOURCE 1" >>confdefs.h - - printf "%s\n" "#define _HPUX_ALT_XOPEN_SOCKET_API 1" >>confdefs.h - - printf "%s\n" "#define _NETBSD_SOURCE 1" >>confdefs.h - - printf "%s\n" "#define _OPENBSD_SOURCE 1" >>confdefs.h - - printf "%s\n" "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h - - printf "%s\n" "#define __STDC_WANT_IEC_60559_ATTRIBS_EXT__ 1" >>confdefs.h - - printf "%s\n" "#define __STDC_WANT_IEC_60559_BFP_EXT__ 1" >>confdefs.h - - printf "%s\n" "#define __STDC_WANT_IEC_60559_DFP_EXT__ 1" >>confdefs.h - - printf "%s\n" "#define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1" >>confdefs.h - - printf "%s\n" "#define __STDC_WANT_IEC_60559_TYPES_EXT__ 1" >>confdefs.h - - printf "%s\n" "#define __STDC_WANT_LIB_EXT2__ 1" >>confdefs.h - - printf "%s\n" "#define __STDC_WANT_MATH_SPEC_FUNCS__ 1" >>confdefs.h - - printf "%s\n" "#define _TANDEM_SOURCE 1" >>confdefs.h - - if test $ac_cv_header_minix_config_h = yes -then : - MINIX=yes - printf "%s\n" "#define _MINIX 1" >>confdefs.h - - printf "%s\n" "#define _POSIX_SOURCE 1" >>confdefs.h - - printf "%s\n" "#define _POSIX_1_SOURCE 2" >>confdefs.h - -else $as_nop - MINIX= -fi - if test $ac_cv_safe_to_define___extensions__ = yes -then : - printf "%s\n" "#define __EXTENSIONS__ 1" >>confdefs.h - -fi - if test $ac_cv_should_define__xopen_source = yes -then : - printf "%s\n" "#define _XOPEN_SOURCE 500" >>confdefs.h - -fi - -enable_win32_dll=yes - -case $host in -*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. -set dummy ${ac_tool_prefix}as; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_AS+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$AS"; then - ac_cv_prog_AS="$AS" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_AS="${ac_tool_prefix}as" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AS=$ac_cv_prog_AS -if test -n "$AS"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 -printf "%s\n" "$AS" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_AS"; then - ac_ct_AS=$AS - # Extract the first word of "as", so it can be a program name with args. -set dummy as; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_AS+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_AS"; then - ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_AS="as" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_AS=$ac_cv_prog_ac_ct_AS -if test -n "$ac_ct_AS"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5 -printf "%s\n" "$ac_ct_AS" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - if test "x$ac_ct_AS" = x; then - AS="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - AS=$ac_ct_AS - fi -else - AS="$ac_cv_prog_AS" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. -set dummy ${ac_tool_prefix}dlltool; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_DLLTOOL+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$DLLTOOL"; then - ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -DLLTOOL=$ac_cv_prog_DLLTOOL -if test -n "$DLLTOOL"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 -printf "%s\n" "$DLLTOOL" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_DLLTOOL"; then - ac_ct_DLLTOOL=$DLLTOOL - # Extract the first word of "dlltool", so it can be a program name with args. -set dummy dlltool; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_DLLTOOL+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_DLLTOOL"; then - ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_DLLTOOL="dlltool" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL -if test -n "$ac_ct_DLLTOOL"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 -printf "%s\n" "$ac_ct_DLLTOOL" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - if test "x$ac_ct_DLLTOOL" = x; then - DLLTOOL="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - DLLTOOL=$ac_ct_DLLTOOL - fi -else - DLLTOOL="$ac_cv_prog_DLLTOOL" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. -set dummy ${ac_tool_prefix}objdump; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_OBJDUMP+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$OBJDUMP"; then - ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -OBJDUMP=$ac_cv_prog_OBJDUMP -if test -n "$OBJDUMP"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 -printf "%s\n" "$OBJDUMP" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OBJDUMP"; then - ac_ct_OBJDUMP=$OBJDUMP - # Extract the first word of "objdump", so it can be a program name with args. -set dummy objdump; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_OBJDUMP+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_OBJDUMP"; then - ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_OBJDUMP="objdump" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP -if test -n "$ac_ct_OBJDUMP"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 -printf "%s\n" "$ac_ct_OBJDUMP" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - if test "x$ac_ct_OBJDUMP" = x; then - OBJDUMP="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OBJDUMP=$ac_ct_OBJDUMP - fi -else - OBJDUMP="$ac_cv_prog_OBJDUMP" -fi - - ;; -esac - -test -z "$AS" && AS=as - - - - - -test -z "$DLLTOOL" && DLLTOOL=dlltool - - - - - -test -z "$OBJDUMP" && OBJDUMP=objdump - - - - - - - -case `pwd` in - *\ * | *\ *) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 -printf "%s\n" "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; -esac - - - -macro_version='2.4.6' -macro_revision='2.4.6' - - - - - - - - - - - - - - -ltmain=$ac_aux_dir/ltmain.sh - -# Backslashify metacharacters that are still active within -# double-quoted strings. -sed_quote_subst='s/\(["`$\\]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\(["`\\]\)/\\\1/g' - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Sed substitution to delay expansion of an escaped single quote. -delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' - -# Sed substitution to avoid accidental globbing in evaled expressions -no_glob_subst='s/\*/\\\*/g' - -ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 -printf %s "checking how to print strings... " >&6; } -# Test print first, because it will be a builtin if present. -if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ - test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='print -r --' -elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='printf %s\n' -else - # Use this function as a fallback that always works. - func_fallback_echo () - { - eval 'cat <<_LTECHO_EOF -$1 -_LTECHO_EOF' - } - ECHO='func_fallback_echo' -fi - -# func_echo_all arg... -# Invoke $ECHO with all args, space-separated. -func_echo_all () -{ - $ECHO "" -} - -case $ECHO in - printf*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: printf" >&5 -printf "%s\n" "printf" >&6; } ;; - print*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 -printf "%s\n" "print -r" >&6; } ;; - *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: cat" >&5 -printf "%s\n" "cat" >&6; } ;; -esac - - - - - - - - - - - - - - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 -printf %s "checking for a sed that does not truncate output... " >&6; } -if test ${ac_cv_path_SED+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ - for ac_i in 1 2 3 4 5 6 7; do - ac_script="$ac_script$as_nl$ac_script" - done - echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed - { ac_script=; unset ac_script;} - if test -z "$SED"; then - ac_path_SED_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_prog in sed gsed - do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_SED="$as_dir$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_SED" || continue -# Check for GNU ac_path_SED and select it if it is found. - # Check for GNU $ac_path_SED -case `"$ac_path_SED" --version 2>&1` in -*GNU*) - ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; -*) - ac_count=0 - printf %s 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - printf "%s\n" '' >> "conftest.nl" - "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_SED_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_SED="$ac_path_SED" - ac_path_SED_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_SED_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_SED"; then - as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 - fi -else - ac_cv_path_SED=$SED -fi - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 -printf "%s\n" "$ac_cv_path_SED" >&6; } - SED="$ac_cv_path_SED" - rm -f conftest.sed - -test -z "$SED" && SED=sed -Xsed="$SED -e 1s/^X//" - - - - - - - - - - - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 -printf %s "checking for grep that handles long lines and -e... " >&6; } -if test ${ac_cv_path_GREP+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -z "$GREP"; then - ac_path_GREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_prog in grep ggrep - do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_GREP" || continue -# Check for GNU ac_path_GREP and select it if it is found. - # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in -*GNU*) - ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; -*) - ac_count=0 - printf %s 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - printf "%s\n" 'GREP' >> "conftest.nl" - "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_GREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_GREP="$ac_path_GREP" - ac_path_GREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_GREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_GREP"; then - as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_GREP=$GREP -fi - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 -printf "%s\n" "$ac_cv_path_GREP" >&6; } - GREP="$ac_cv_path_GREP" - - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 -printf %s "checking for egrep... " >&6; } -if test ${ac_cv_path_EGREP+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 - then ac_cv_path_EGREP="$GREP -E" - else - if test -z "$EGREP"; then - ac_path_EGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_prog in egrep - do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_EGREP" || continue -# Check for GNU ac_path_EGREP and select it if it is found. - # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in -*GNU*) - ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; -*) - ac_count=0 - printf %s 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - printf "%s\n" 'EGREP' >> "conftest.nl" - "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_EGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_EGREP="$ac_path_EGREP" - ac_path_EGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_EGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_EGREP"; then - as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_EGREP=$EGREP -fi - - fi -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 -printf "%s\n" "$ac_cv_path_EGREP" >&6; } - EGREP="$ac_cv_path_EGREP" - - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 -printf %s "checking for fgrep... " >&6; } -if test ${ac_cv_path_FGREP+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 - then ac_cv_path_FGREP="$GREP -F" - else - if test -z "$FGREP"; then - ac_path_FGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_prog in fgrep - do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_FGREP="$as_dir$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_FGREP" || continue -# Check for GNU ac_path_FGREP and select it if it is found. - # Check for GNU $ac_path_FGREP -case `"$ac_path_FGREP" --version 2>&1` in -*GNU*) - ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; -*) - ac_count=0 - printf %s 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - printf "%s\n" 'FGREP' >> "conftest.nl" - "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_FGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_FGREP="$ac_path_FGREP" - ac_path_FGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_FGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_FGREP"; then - as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_FGREP=$FGREP -fi - - fi -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 -printf "%s\n" "$ac_cv_path_FGREP" >&6; } - FGREP="$ac_cv_path_FGREP" - - -test -z "$GREP" && GREP=grep - - - - - - - - - - - - - - - - - - - -# Check whether --with-gnu-ld was given. -if test ${with_gnu_ld+y} -then : - withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes -else $as_nop - with_gnu_ld=no -fi - -ac_prog=ld -if test yes = "$GCC"; then - # Check if gcc -print-prog-name=ld gives a path. - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 -printf %s "checking for ld used by $CC... " >&6; } - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return, which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [\\/]* | ?:[\\/]*) - re_direlt='/[^/][^/]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` - while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do - ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` - done - test -z "$LD" && LD=$ac_prog - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test yes = "$with_gnu_ld"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 -printf %s "checking for GNU ld... " >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 -printf %s "checking for non-GNU ld... " >&6; } -fi -if test ${lt_cv_path_LD+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -z "$LD"; then - lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS=$lt_save_ifs - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD=$ac_dir/$ac_prog - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 &5 -printf "%s\n" "$LD" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 -printf %s "checking if the linker ($LD) is GNU ld... " >&6; } -if test ${lt_cv_prog_gnu_ld+y} -then : - printf %s "(cached) " >&6 -else $as_nop - # I'd rather use --version here, but apparently some GNU lds only accept -v. -case `$LD -v 2>&1 &5 -printf "%s\n" "$lt_cv_prog_gnu_ld" >&6; } -with_gnu_ld=$lt_cv_prog_gnu_ld - - - - - - - - - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 -printf %s "checking for BSD- or MS-compatible name lister (nm)... " >&6; } -if test ${lt_cv_path_NM+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$NM"; then - # Let the user override the test. - lt_cv_path_NM=$NM -else - lt_nm_to_check=${ac_tool_prefix}nm - if test -n "$ac_tool_prefix" && test "$build" = "$host"; then - lt_nm_to_check="$lt_nm_to_check nm" - fi - for lt_tmp_nm in $lt_nm_to_check; do - lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do - IFS=$lt_save_ifs - test -z "$ac_dir" && ac_dir=. - tmp_nm=$ac_dir/$lt_tmp_nm - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the 'sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty - case $build_os in - mingw*) lt_bad_file=conftest.nm/nofile ;; - *) lt_bad_file=/dev/null ;; - esac - case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in - *$lt_bad_file* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break 2 - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" - break 2 - ;; - *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - ;; - esac - ;; - esac - fi - done - IFS=$lt_save_ifs - done - : ${lt_cv_path_NM=no} -fi -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 -printf "%s\n" "$lt_cv_path_NM" >&6; } -if test no != "$lt_cv_path_NM"; then - NM=$lt_cv_path_NM -else - # Didn't find any BSD compatible name lister, look for dumpbin. - if test -n "$DUMPBIN"; then : - # Let the user override the test. - else - if test -n "$ac_tool_prefix"; then - for ac_prog in dumpbin "link -dump" - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_DUMPBIN+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$DUMPBIN"; then - ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -DUMPBIN=$ac_cv_prog_DUMPBIN -if test -n "$DUMPBIN"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 -printf "%s\n" "$DUMPBIN" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - - test -n "$DUMPBIN" && break - done -fi -if test -z "$DUMPBIN"; then - ac_ct_DUMPBIN=$DUMPBIN - for ac_prog in dumpbin "link -dump" -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_DUMPBIN+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_DUMPBIN"; then - ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN -if test -n "$ac_ct_DUMPBIN"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 -printf "%s\n" "$ac_ct_DUMPBIN" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - - test -n "$ac_ct_DUMPBIN" && break -done - - if test "x$ac_ct_DUMPBIN" = x; then - DUMPBIN=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - DUMPBIN=$ac_ct_DUMPBIN - fi -fi - - case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in - *COFF*) - DUMPBIN="$DUMPBIN -symbols -headers" - ;; - *) - DUMPBIN=: - ;; - esac - fi - - if test : != "$DUMPBIN"; then - NM=$DUMPBIN - fi -fi -test -z "$NM" && NM=nm - - - - - - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 -printf %s "checking the name lister ($NM) interface... " >&6; } -if test ${lt_cv_nm_interface+y} -then : - printf %s "(cached) " >&6 -else $as_nop - lt_cv_nm_interface="BSD nm" - echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) - (eval "$ac_compile" 2>conftest.err) - cat conftest.err >&5 - (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) - (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) - cat conftest.err >&5 - (eval echo "\"\$as_me:$LINENO: output\"" >&5) - cat conftest.out >&5 - if $GREP 'External.*some_variable' conftest.out > /dev/null; then - lt_cv_nm_interface="MS dumpbin" - fi - rm -f conftest* -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 -printf "%s\n" "$lt_cv_nm_interface" >&6; } - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 -printf %s "checking whether ln -s works... " >&6; } -LN_S=$as_ln_s -if test "$LN_S" = "ln -s"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 -printf "%s\n" "no, using $LN_S" >&6; } -fi - -# find the maximum length of command line arguments -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 -printf %s "checking the maximum length of command line arguments... " >&6; } -if test ${lt_cv_sys_max_cmd_len+y} -then : - printf %s "(cached) " >&6 -else $as_nop - i=0 - teststring=ABCD - - case $build_os in - msdosdjgpp*) - # On DJGPP, this test can blow up pretty badly due to problems in libc - # (any single argument exceeding 2000 bytes causes a buffer overrun - # during glob expansion). Even if it were fixed, the result of this - # check would be larger than it should be. - lt_cv_sys_max_cmd_len=12288; # 12K is about right - ;; - - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. - # Libtool will interpret -1 as no limit whatsoever - lt_cv_sys_max_cmd_len=-1; - ;; - - cygwin* | mingw* | cegcc*) - # On Win9x/ME, this test blows up -- it succeeds, but takes - # about 5 minutes as the teststring grows exponentially. - # Worse, since 9x/ME are not pre-emptively multitasking, - # you end up with a "frozen" computer, even though with patience - # the test eventually succeeds (with a max line length of 256k). - # Instead, let's just punt: use the minimum linelength reported by - # all of the supported platforms: 8192 (on NT/2K/XP). - lt_cv_sys_max_cmd_len=8192; - ;; - - mint*) - # On MiNT this can take a long time and run out of memory. - lt_cv_sys_max_cmd_len=8192; - ;; - - amigaos*) - # On AmigaOS with pdksh, this test takes hours, literally. - # So we just punt and use a minimum line length of 8192. - lt_cv_sys_max_cmd_len=8192; - ;; - - bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) - # This has been around since 386BSD, at least. Likely further. - if test -x /sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` - elif test -x /usr/sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` - else - lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs - fi - # And add a safety zone - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - ;; - - interix*) - # We know the value 262144 and hardcode it with a safety zone (like BSD) - lt_cv_sys_max_cmd_len=196608 - ;; - - os2*) - # The test takes a long time on OS/2. - lt_cv_sys_max_cmd_len=8192 - ;; - - osf*) - # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure - # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not - # nice to cause kernel panics so lets avoid the loop below. - # First set a reasonable default. - lt_cv_sys_max_cmd_len=16384 - # - if test -x /sbin/sysconfig; then - case `/sbin/sysconfig -q proc exec_disable_arg_limit` in - *1*) lt_cv_sys_max_cmd_len=-1 ;; - esac - fi - ;; - sco3.2v5*) - lt_cv_sys_max_cmd_len=102400 - ;; - sysv5* | sco5v6* | sysv4.2uw2*) - kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` - if test -n "$kargmax"; then - lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` - else - lt_cv_sys_max_cmd_len=32768 - fi - ;; - *) - lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` - if test -n "$lt_cv_sys_max_cmd_len" && \ - test undefined != "$lt_cv_sys_max_cmd_len"; then - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - else - # Make teststring a little bigger before we do anything with it. - # a 1K string should be a reasonable start. - for i in 1 2 3 4 5 6 7 8; do - teststring=$teststring$teststring - done - SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} - # If test is not a shell built-in, we'll probably end up computing a - # maximum length that is only half of the actual maximum length, but - # we can't tell. - while { test X`env echo "$teststring$teststring" 2>/dev/null` \ - = "X$teststring$teststring"; } >/dev/null 2>&1 && - test 17 != "$i" # 1/2 MB should be enough - do - i=`expr $i + 1` - teststring=$teststring$teststring - done - # Only check the string length outside the loop. - lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` - teststring= - # Add a significant safety factor because C++ compilers can tack on - # massive amounts of additional arguments before passing them to the - # linker. It appears as though 1/2 is a usable value. - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` - fi - ;; - esac - -fi - -if test -n "$lt_cv_sys_max_cmd_len"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 -printf "%s\n" "$lt_cv_sys_max_cmd_len" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 -printf "%s\n" "none" >&6; } -fi -max_cmd_len=$lt_cv_sys_max_cmd_len - - - - - - -: ${CP="cp -f"} -: ${MV="mv -f"} -: ${RM="rm -f"} - -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - lt_unset=unset -else - lt_unset=false -fi - - - - - -# test EBCDIC or ASCII -case `echo X|tr X '\101'` in - A) # ASCII based system - # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr - lt_SP2NL='tr \040 \012' - lt_NL2SP='tr \015\012 \040\040' - ;; - *) # EBCDIC based system - lt_SP2NL='tr \100 \n' - lt_NL2SP='tr \r\n \100\100' - ;; -esac - - - - - - - - - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 -printf %s "checking how to convert $build file names to $host format... " >&6; } -if test ${lt_cv_to_host_file_cmd+y} -then : - printf %s "(cached) " >&6 -else $as_nop - case $host in - *-*-mingw* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 - ;; - *-*-cygwin* ) - lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 - ;; - * ) # otherwise, assume *nix - lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 - ;; - esac - ;; - *-*-cygwin* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin - ;; - *-*-cygwin* ) - lt_cv_to_host_file_cmd=func_convert_file_noop - ;; - * ) # otherwise, assume *nix - lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin - ;; - esac - ;; - * ) # unhandled hosts (and "normal" native builds) - lt_cv_to_host_file_cmd=func_convert_file_noop - ;; -esac - -fi - -to_host_file_cmd=$lt_cv_to_host_file_cmd -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 -printf "%s\n" "$lt_cv_to_host_file_cmd" >&6; } - - - - - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 -printf %s "checking how to convert $build file names to toolchain format... " >&6; } -if test ${lt_cv_to_tool_file_cmd+y} -then : - printf %s "(cached) " >&6 -else $as_nop - #assume ordinary cross tools, or native build. -lt_cv_to_tool_file_cmd=func_convert_file_noop -case $host in - *-*-mingw* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 - ;; - esac - ;; -esac - -fi - -to_tool_file_cmd=$lt_cv_to_tool_file_cmd -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 -printf "%s\n" "$lt_cv_to_tool_file_cmd" >&6; } - - - - - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 -printf %s "checking for $LD option to reload object files... " >&6; } -if test ${lt_cv_ld_reload_flag+y} -then : - printf %s "(cached) " >&6 -else $as_nop - lt_cv_ld_reload_flag='-r' -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 -printf "%s\n" "$lt_cv_ld_reload_flag" >&6; } -reload_flag=$lt_cv_ld_reload_flag -case $reload_flag in -"" | " "*) ;; -*) reload_flag=" $reload_flag" ;; -esac -reload_cmds='$LD$reload_flag -o $output$reload_objs' -case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - if test yes != "$GCC"; then - reload_cmds=false - fi - ;; - darwin*) - if test yes = "$GCC"; then - reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' - else - reload_cmds='$LD$reload_flag -o $output$reload_objs' - fi - ;; -esac - - - - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. -set dummy ${ac_tool_prefix}objdump; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_OBJDUMP+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$OBJDUMP"; then - ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -OBJDUMP=$ac_cv_prog_OBJDUMP -if test -n "$OBJDUMP"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 -printf "%s\n" "$OBJDUMP" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OBJDUMP"; then - ac_ct_OBJDUMP=$OBJDUMP - # Extract the first word of "objdump", so it can be a program name with args. -set dummy objdump; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_OBJDUMP+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_OBJDUMP"; then - ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_OBJDUMP="objdump" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP -if test -n "$ac_ct_OBJDUMP"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 -printf "%s\n" "$ac_ct_OBJDUMP" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - if test "x$ac_ct_OBJDUMP" = x; then - OBJDUMP="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OBJDUMP=$ac_ct_OBJDUMP - fi -else - OBJDUMP="$ac_cv_prog_OBJDUMP" -fi - -test -z "$OBJDUMP" && OBJDUMP=objdump - - - - - - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 -printf %s "checking how to recognize dependent libraries... " >&6; } -if test ${lt_cv_deplibs_check_method+y} -then : - printf %s "(cached) " >&6 -else $as_nop - lt_cv_file_magic_cmd='$MAGIC_CMD' -lt_cv_file_magic_test_file= -lt_cv_deplibs_check_method='unknown' -# Need to set the preceding variable on all platforms that support -# interlibrary dependencies. -# 'none' -- dependencies not supported. -# 'unknown' -- same as none, but documents that we really don't know. -# 'pass_all' -- all dependencies passed with no checks. -# 'test_compile' -- check by making test program. -# 'file_magic [[regex]]' -- check by looking for files in library path -# that responds to the $file_magic_cmd with a given extended regex. -# If you have 'file' or equivalent on your system and you're not sure -# whether 'pass_all' will *always* work, you probably want this one. - -case $host_os in -aix[4-9]*) - lt_cv_deplibs_check_method=pass_all - ;; - -beos*) - lt_cv_deplibs_check_method=pass_all - ;; - -bsdi[45]*) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' - lt_cv_file_magic_cmd='/usr/bin/file -L' - lt_cv_file_magic_test_file=/shlib/libc.so - ;; - -cygwin*) - # func_win32_libid is a shell function defined in ltmain.sh - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - ;; - -mingw* | pw32*) - # Base MSYS/MinGW do not provide the 'file' command needed by - # func_win32_libid shell function, so use a weaker test based on 'objdump', - # unless we find 'file', for example because we are cross-compiling. - if ( file / ) >/dev/null 2>&1; then - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - else - # Keep this pattern in sync with the one in func_win32_libid. - lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' - lt_cv_file_magic_cmd='$OBJDUMP -f' - fi - ;; - -cegcc*) - # use the weaker test based on 'objdump'. See mingw*. - lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - ;; - -darwin* | rhapsody*) - lt_cv_deplibs_check_method=pass_all - ;; - -freebsd* | dragonfly*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - case $host_cpu in - i*86 ) - # Not sure whether the presence of OpenBSD here was a mistake. - # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - ;; - esac - else - lt_cv_deplibs_check_method=pass_all - fi - ;; - -haiku*) - lt_cv_deplibs_check_method=pass_all - ;; - -hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file - case $host_cpu in - ia64*) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' - lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so - ;; - hppa*64*) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' - lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl - ;; - *) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' - lt_cv_file_magic_test_file=/usr/lib/libc.sl - ;; - esac - ;; - -interix[3-9]*) - # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' - ;; - -irix5* | irix6* | nonstopux*) - case $LD in - *-32|*"-32 ") libmagic=32-bit;; - *-n32|*"-n32 ") libmagic=N32;; - *-64|*"-64 ") libmagic=64-bit;; - *) libmagic=never-match;; - esac - lt_cv_deplibs_check_method=pass_all - ;; - -# This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - -netbsd* | netbsdelf*-gnu) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' - fi - ;; - -newos6*) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libnls.so - ;; - -*nto* | *qnx*) - lt_cv_deplibs_check_method=pass_all - ;; - -openbsd* | bitrig*) - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' - fi - ;; - -osf3* | osf4* | osf5*) - lt_cv_deplibs_check_method=pass_all - ;; - -rdos*) - lt_cv_deplibs_check_method=pass_all - ;; - -solaris*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv4 | sysv4.3*) - case $host_vendor in - motorola) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - ncr) - lt_cv_deplibs_check_method=pass_all - ;; - sequent) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' - ;; - sni) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" - lt_cv_file_magic_test_file=/lib/libc.so - ;; - siemens) - lt_cv_deplibs_check_method=pass_all - ;; - pc) - lt_cv_deplibs_check_method=pass_all - ;; - esac - ;; - -tpf*) - lt_cv_deplibs_check_method=pass_all - ;; -os2*) - lt_cv_deplibs_check_method=pass_all - ;; -esac - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 -printf "%s\n" "$lt_cv_deplibs_check_method" >&6; } - -file_magic_glob= -want_nocaseglob=no -if test "$build" = "$host"; then - case $host_os in - mingw* | pw32*) - if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then - want_nocaseglob=yes - else - file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` - fi - ;; - esac -fi - -file_magic_cmd=$lt_cv_file_magic_cmd -deplibs_check_method=$lt_cv_deplibs_check_method -test -z "$deplibs_check_method" && deplibs_check_method=unknown - - - - - - - - - - - - - - - - - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. -set dummy ${ac_tool_prefix}dlltool; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_DLLTOOL+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$DLLTOOL"; then - ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -DLLTOOL=$ac_cv_prog_DLLTOOL -if test -n "$DLLTOOL"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 -printf "%s\n" "$DLLTOOL" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_DLLTOOL"; then - ac_ct_DLLTOOL=$DLLTOOL - # Extract the first word of "dlltool", so it can be a program name with args. -set dummy dlltool; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_DLLTOOL+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_DLLTOOL"; then - ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_DLLTOOL="dlltool" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL -if test -n "$ac_ct_DLLTOOL"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 -printf "%s\n" "$ac_ct_DLLTOOL" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - if test "x$ac_ct_DLLTOOL" = x; then - DLLTOOL="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - DLLTOOL=$ac_ct_DLLTOOL - fi -else - DLLTOOL="$ac_cv_prog_DLLTOOL" -fi - -test -z "$DLLTOOL" && DLLTOOL=dlltool - - - - - - - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 -printf %s "checking how to associate runtime and link libraries... " >&6; } -if test ${lt_cv_sharedlib_from_linklib_cmd+y} -then : - printf %s "(cached) " >&6 -else $as_nop - lt_cv_sharedlib_from_linklib_cmd='unknown' - -case $host_os in -cygwin* | mingw* | pw32* | cegcc*) - # two different shell functions defined in ltmain.sh; - # decide which one to use based on capabilities of $DLLTOOL - case `$DLLTOOL --help 2>&1` in - *--identify-strict*) - lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib - ;; - *) - lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback - ;; - esac - ;; -*) - # fallback: assume linklib IS sharedlib - lt_cv_sharedlib_from_linklib_cmd=$ECHO - ;; -esac - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 -printf "%s\n" "$lt_cv_sharedlib_from_linklib_cmd" >&6; } -sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd -test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO - - - - - - - -if test -n "$ac_tool_prefix"; then - for ac_prog in ar - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_AR+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$AR"; then - ac_cv_prog_AR="$AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_AR="$ac_tool_prefix$ac_prog" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AR=$ac_cv_prog_AR -if test -n "$AR"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 -printf "%s\n" "$AR" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - - test -n "$AR" && break - done -fi -if test -z "$AR"; then - ac_ct_AR=$AR - for ac_prog in ar -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_AR+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_AR"; then - ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_AR="$ac_prog" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_AR=$ac_cv_prog_ac_ct_AR -if test -n "$ac_ct_AR"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 -printf "%s\n" "$ac_ct_AR" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - - test -n "$ac_ct_AR" && break -done - - if test "x$ac_ct_AR" = x; then - AR="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - AR=$ac_ct_AR - fi -fi - -: ${AR=ar} -: ${AR_FLAGS=cr} - - - - - - - - - - - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 -printf %s "checking for archiver @FILE support... " >&6; } -if test ${lt_cv_ar_at_file+y} -then : - printf %s "(cached) " >&6 -else $as_nop - lt_cv_ar_at_file=no - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - echo conftest.$ac_objext > conftest.lst - lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' - { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 - (eval $lt_ar_try) 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if test 0 -eq "$ac_status"; then - # Ensure the archiver fails upon bogus file names. - rm -f conftest.$ac_objext libconftest.a - { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 - (eval $lt_ar_try) 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if test 0 -ne "$ac_status"; then - lt_cv_ar_at_file=@ - fi - fi - rm -f conftest.* libconftest.a - -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 -printf "%s\n" "$lt_cv_ar_at_file" >&6; } - -if test no = "$lt_cv_ar_at_file"; then - archiver_list_spec= -else - archiver_list_spec=$lt_cv_ar_at_file -fi - - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_STRIP+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -printf "%s\n" "$STRIP" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_STRIP+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_STRIP="strip" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -printf "%s\n" "$ac_ct_STRIP" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - -test -z "$STRIP" && STRIP=: - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_RANLIB+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -RANLIB=$ac_cv_prog_RANLIB -if test -n "$RANLIB"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 -printf "%s\n" "$RANLIB" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_RANLIB+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_RANLIB="ranlib" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 -printf "%s\n" "$ac_ct_RANLIB" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - if test "x$ac_ct_RANLIB" = x; then - RANLIB=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - RANLIB=$ac_ct_RANLIB - fi -else - RANLIB="$ac_cv_prog_RANLIB" -fi - -test -z "$RANLIB" && RANLIB=: - - - - - - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - case $host_os in - bitrig* | openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" - ;; - *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" - ;; - esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" -fi - -case $host_os in - darwin*) - lock_old_archive_extraction=yes ;; - *) - lock_old_archive_extraction=no ;; -esac - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC - - -# Check for command to grab the raw symbol name followed by C symbol from nm. -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 -printf %s "checking command to parse $NM output from $compiler object... " >&6; } -if test ${lt_cv_sys_global_symbol_pipe+y} -then : - printf %s "(cached) " >&6 -else $as_nop - -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[BCDEGRST]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([_A-Za-z][_A-Za-z0-9]*\)' - -# Define system-specific variables. -case $host_os in -aix*) - symcode='[BCDT]' - ;; -cygwin* | mingw* | pw32* | cegcc*) - symcode='[ABCDGISTW]' - ;; -hpux*) - if test ia64 = "$host_cpu"; then - symcode='[ABCDEGRST]' - fi - ;; -irix* | nonstopux*) - symcode='[BCDEGRST]' - ;; -osf*) - symcode='[BCDEGQRST]' - ;; -solaris*) - symcode='[BDRT]' - ;; -sco3.2v5*) - symcode='[DT]' - ;; -sysv4.2uw2*) - symcode='[DT]' - ;; -sysv5* | sco5v6* | unixware* | OpenUNIX*) - symcode='[ABDT]' - ;; -sysv4) - symcode='[DFNSTU]' - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -case `$NM -V 2>&1` in -*GNU* | *'with BFD'*) - symcode='[ABCDGIRSTW]' ;; -esac - -if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Gets list of data symbols to import. - lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" - # Adjust the below global symbol transforms to fixup imported variables. - lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" - lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" - lt_c_name_lib_hook="\ - -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ - -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" -else - # Disable hooks by default. - lt_cv_sys_global_symbol_to_import= - lt_cdecl_hook= - lt_c_name_hook= - lt_c_name_lib_hook= -fi - -# Transform an extracted symbol line into a proper C declaration. -# Some systems (esp. on ia64) link data and code symbols differently, -# so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n"\ -$lt_cdecl_hook\ -" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ -" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" - -# Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ -$lt_c_name_hook\ -" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ -" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" - -# Transform an extracted symbol line into symbol name with lib prefix and -# symbol address. -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ -$lt_c_name_lib_hook\ -" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ -" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ -" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" - -# Handle CRLF in mingw tool chain -opt_cr= -case $build_os in -mingw*) - opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp - ;; -esac - -# Try without a prefix underscore, then with it. -for ac_symprfx in "" "_"; do - - # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. - symxfrm="\\1 $ac_symprfx\\2 \\2" - - # Write the raw and C identifiers. - if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Fake it for dumpbin and say T for any non-static function, - # D for any global variable and I for any imported variable. - # Also find C++ and __fastcall symbols from MSVC++, - # which start with @ or ?. - lt_cv_sys_global_symbol_pipe="$AWK '"\ -" {last_section=section; section=\$ 3};"\ -" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ -" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ -" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ -" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ -" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ -" \$ 0!~/External *\|/{next};"\ -" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ -" {if(hide[section]) next};"\ -" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ -" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ -" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ -" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ -" ' prfx=^$ac_symprfx" - else - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" - fi - lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" - - # Check to see that the pipe works correctly. - pipe_works=no - - rm -f conftest* - cat > conftest.$ac_ext <<_LT_EOF -#ifdef __cplusplus -extern "C" { -#endif -char nm_test_var; -void nm_test_func(void); -void nm_test_func(void){} -#ifdef __cplusplus -} -#endif -int main(){nm_test_var='a';nm_test_func();return(0);} -_LT_EOF - - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - # Now try to grab the symbols. - nlist=conftest.nm - $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5 - if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if $GREP ' nm_test_var$' "$nlist" >/dev/null; then - if $GREP ' nm_test_func$' "$nlist" >/dev/null; then - cat <<_LT_EOF > conftest.$ac_ext -/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE -/* DATA imports from DLLs on WIN32 can't be const, because runtime - relocations are performed -- see ld's documentation on pseudo-relocs. */ -# define LT_DLSYM_CONST -#elif defined __osf__ -/* This system does not cope well with relocations in const data. */ -# define LT_DLSYM_CONST -#else -# define LT_DLSYM_CONST const -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -_LT_EOF - # Now generate the symbol file. - eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' - - cat <<_LT_EOF >> conftest.$ac_ext - -/* The mapping between symbol names and symbols. */ -LT_DLSYM_CONST struct { - const char *name; - void *address; -} -lt__PROGRAM__LTX_preloaded_symbols[] = -{ - { "@PROGRAM@", (void *) 0 }, -_LT_EOF - $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext - cat <<\_LT_EOF >> conftest.$ac_ext - {0, (void *) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt__PROGRAM__LTX_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif -_LT_EOF - # Now try linking the two files. - mv conftest.$ac_objext conftstm.$ac_objext - lt_globsym_save_LIBS=$LIBS - lt_globsym_save_CFLAGS=$CFLAGS - LIBS=conftstm.$ac_objext - CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 - (eval $ac_link) 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest$ac_exeext; then - pipe_works=yes - fi - LIBS=$lt_globsym_save_LIBS - CFLAGS=$lt_globsym_save_CFLAGS - else - echo "cannot find nm_test_func in $nlist" >&5 - fi - else - echo "cannot find nm_test_var in $nlist" >&5 - fi - else - echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 - fi - else - echo "$progname: failed program was:" >&5 - cat conftest.$ac_ext >&5 - fi - rm -rf conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test yes = "$pipe_works"; then - break - else - lt_cv_sys_global_symbol_pipe= - fi -done - -fi - -if test -z "$lt_cv_sys_global_symbol_pipe"; then - lt_cv_sys_global_symbol_to_cdecl= -fi -if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: failed" >&5 -printf "%s\n" "failed" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ok" >&5 -printf "%s\n" "ok" >&6; } -fi - -# Response file support. -if test "$lt_cv_nm_interface" = "MS dumpbin"; then - nm_file_list_spec='@' -elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then - nm_file_list_spec='@' -fi - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 -printf %s "checking for sysroot... " >&6; } - -# Check whether --with-sysroot was given. -if test ${with_sysroot+y} -then : - withval=$with_sysroot; -else $as_nop - with_sysroot=no -fi - - -lt_sysroot= -case $with_sysroot in #( - yes) - if test yes = "$GCC"; then - lt_sysroot=`$CC --print-sysroot 2>/dev/null` - fi - ;; #( - /*) - lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` - ;; #( - no|'') - ;; #( - *) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 -printf "%s\n" "$with_sysroot" >&6; } - as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 - ;; -esac - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 -printf "%s\n" "${lt_sysroot:-no}" >&6; } - - - - - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 -printf %s "checking for a working dd... " >&6; } -if test ${ac_cv_path_lt_DD+y} -then : - printf %s "(cached) " >&6 -else $as_nop - printf 0123456789abcdef0123456789abcdef >conftest.i -cat conftest.i conftest.i >conftest2.i -: ${lt_DD:=$DD} -if test -z "$lt_DD"; then - ac_path_lt_DD_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_prog in dd - do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_lt_DD="$as_dir$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_lt_DD" || continue -if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then - cmp -s conftest.i conftest.out \ - && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: -fi - $ac_path_lt_DD_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_lt_DD"; then - : - fi -else - ac_cv_path_lt_DD=$lt_DD -fi - -rm -f conftest.i conftest2.i conftest.out -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 -printf "%s\n" "$ac_cv_path_lt_DD" >&6; } - - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 -printf %s "checking how to truncate binary pipes... " >&6; } -if test ${lt_cv_truncate_bin+y} -then : - printf %s "(cached) " >&6 -else $as_nop - printf 0123456789abcdef0123456789abcdef >conftest.i -cat conftest.i conftest.i >conftest2.i -lt_cv_truncate_bin= -if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then - cmp -s conftest.i conftest.out \ - && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" -fi -rm -f conftest.i conftest2.i conftest.out -test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 -printf "%s\n" "$lt_cv_truncate_bin" >&6; } - - - - - - - -# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. -func_cc_basename () -{ - for cc_temp in $*""; do - case $cc_temp in - compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; - distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; - \-*) ;; - *) break;; - esac - done - func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` -} - -# Check whether --enable-libtool-lock was given. -if test ${enable_libtool_lock+y} -then : - enableval=$enable_libtool_lock; -fi - -test no = "$enable_libtool_lock" || enable_libtool_lock=yes - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case $host in -ia64-*-hpux*) - # Find out what ABI is being produced by ac_compile, and set mode - # options accordingly. - echo 'int i;' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - case `/usr/bin/file conftest.$ac_objext` in - *ELF-32*) - HPUX_IA64_MODE=32 - ;; - *ELF-64*) - HPUX_IA64_MODE=64 - ;; - esac - fi - rm -rf conftest* - ;; -*-*-irix6*) - # Find out what ABI is being produced by ac_compile, and set linker - # options accordingly. - echo '#line '$LINENO' "configure"' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - if test yes = "$lt_cv_prog_gnu_ld"; then - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -melf32bsmip" - ;; - *N32*) - LD="${LD-ld} -melf32bmipn32" - ;; - *64-bit*) - LD="${LD-ld} -melf64bmip" - ;; - esac - else - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - fi - rm -rf conftest* - ;; - -mips64*-*linux*) - # Find out what ABI is being produced by ac_compile, and set linker - # options accordingly. - echo '#line '$LINENO' "configure"' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - emul=elf - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - emul="${emul}32" - ;; - *64-bit*) - emul="${emul}64" - ;; - esac - case `/usr/bin/file conftest.$ac_objext` in - *MSB*) - emul="${emul}btsmip" - ;; - *LSB*) - emul="${emul}ltsmip" - ;; - esac - case `/usr/bin/file conftest.$ac_objext` in - *N32*) - emul="${emul}n32" - ;; - esac - LD="${LD-ld} -m $emul" - fi - rm -rf conftest* - ;; - -x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ -s390*-*linux*|s390*-*tpf*|sparc*-*linux*) - # Find out what ABI is being produced by ac_compile, and set linker - # options accordingly. Note that the listed cases only cover the - # situations where additional linker options are needed (such as when - # doing 32-bit compilation for a host where ld defaults to 64-bit, or - # vice versa); the common cases where no linker options are needed do - # not appear in the list. - echo 'int i;' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - case `/usr/bin/file conftest.o` in - *32-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_i386_fbsd" - ;; - x86_64-*linux*) - case `/usr/bin/file conftest.o` in - *x86-64*) - LD="${LD-ld} -m elf32_x86_64" - ;; - *) - LD="${LD-ld} -m elf_i386" - ;; - esac - ;; - powerpc64le-*linux*) - LD="${LD-ld} -m elf32lppclinux" - ;; - powerpc64-*linux*) - LD="${LD-ld} -m elf32ppclinux" - ;; - s390x-*linux*) - LD="${LD-ld} -m elf_s390" - ;; - sparc64-*linux*) - LD="${LD-ld} -m elf32_sparc" - ;; - esac - ;; - *64-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_x86_64_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_x86_64" - ;; - powerpcle-*linux*) - LD="${LD-ld} -m elf64lppc" - ;; - powerpc-*linux*) - LD="${LD-ld} -m elf64ppc" - ;; - s390*-*linux*|s390*-*tpf*) - LD="${LD-ld} -m elf64_s390" - ;; - sparc*-*linux*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS=$CFLAGS - CFLAGS="$CFLAGS -belf" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 -printf %s "checking whether the C compiler needs -belf... " >&6; } -if test ${lt_cv_cc_needs_belf+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - lt_cv_cc_needs_belf=yes -else $as_nop - lt_cv_cc_needs_belf=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 -printf "%s\n" "$lt_cv_cc_needs_belf" >&6; } - if test yes != "$lt_cv_cc_needs_belf"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS=$SAVE_CFLAGS - fi - ;; -*-*solaris*) - # Find out what ABI is being produced by ac_compile, and set linker - # options accordingly. - echo 'int i;' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - case `/usr/bin/file conftest.o` in - *64-bit*) - case $lt_cv_prog_gnu_ld in - yes*) - case $host in - i?86-*-solaris*|x86_64-*-solaris*) - LD="${LD-ld} -m elf_x86_64" - ;; - sparc*-*-solaris*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - # GNU ld 2.21 introduced _sol2 emulations. Use them if available. - if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then - LD=${LD-ld}_sol2 - fi - ;; - *) - if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then - LD="${LD-ld} -64" - fi - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; -esac - -need_locks=$enable_libtool_lock - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. -set dummy ${ac_tool_prefix}mt; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_MANIFEST_TOOL+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$MANIFEST_TOOL"; then - ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL -if test -n "$MANIFEST_TOOL"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 -printf "%s\n" "$MANIFEST_TOOL" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_MANIFEST_TOOL"; then - ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL - # Extract the first word of "mt", so it can be a program name with args. -set dummy mt; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_MANIFEST_TOOL+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_MANIFEST_TOOL"; then - ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL -if test -n "$ac_ct_MANIFEST_TOOL"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 -printf "%s\n" "$ac_ct_MANIFEST_TOOL" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - if test "x$ac_ct_MANIFEST_TOOL" = x; then - MANIFEST_TOOL=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL - fi -else - MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" -fi - -test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 -printf %s "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } -if test ${lt_cv_path_mainfest_tool+y} -then : - printf %s "(cached) " >&6 -else $as_nop - lt_cv_path_mainfest_tool=no - echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 - $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out - cat conftest.err >&5 - if $GREP 'Manifest Tool' conftest.out > /dev/null; then - lt_cv_path_mainfest_tool=yes - fi - rm -f conftest* -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 -printf "%s\n" "$lt_cv_path_mainfest_tool" >&6; } -if test yes != "$lt_cv_path_mainfest_tool"; then - MANIFEST_TOOL=: -fi - - - - - - - case $host_os in - rhapsody* | darwin*) - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. -set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_DSYMUTIL+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$DSYMUTIL"; then - ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -DSYMUTIL=$ac_cv_prog_DSYMUTIL -if test -n "$DSYMUTIL"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 -printf "%s\n" "$DSYMUTIL" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_DSYMUTIL"; then - ac_ct_DSYMUTIL=$DSYMUTIL - # Extract the first word of "dsymutil", so it can be a program name with args. -set dummy dsymutil; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_DSYMUTIL+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_DSYMUTIL"; then - ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL -if test -n "$ac_ct_DSYMUTIL"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 -printf "%s\n" "$ac_ct_DSYMUTIL" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - if test "x$ac_ct_DSYMUTIL" = x; then - DSYMUTIL=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - DSYMUTIL=$ac_ct_DSYMUTIL - fi -else - DSYMUTIL="$ac_cv_prog_DSYMUTIL" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. -set dummy ${ac_tool_prefix}nmedit; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_NMEDIT+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$NMEDIT"; then - ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -NMEDIT=$ac_cv_prog_NMEDIT -if test -n "$NMEDIT"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 -printf "%s\n" "$NMEDIT" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_NMEDIT"; then - ac_ct_NMEDIT=$NMEDIT - # Extract the first word of "nmedit", so it can be a program name with args. -set dummy nmedit; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_NMEDIT+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_NMEDIT"; then - ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_NMEDIT="nmedit" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT -if test -n "$ac_ct_NMEDIT"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 -printf "%s\n" "$ac_ct_NMEDIT" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - if test "x$ac_ct_NMEDIT" = x; then - NMEDIT=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - NMEDIT=$ac_ct_NMEDIT - fi -else - NMEDIT="$ac_cv_prog_NMEDIT" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. -set dummy ${ac_tool_prefix}lipo; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_LIPO+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$LIPO"; then - ac_cv_prog_LIPO="$LIPO" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_LIPO="${ac_tool_prefix}lipo" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -LIPO=$ac_cv_prog_LIPO -if test -n "$LIPO"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 -printf "%s\n" "$LIPO" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_LIPO"; then - ac_ct_LIPO=$LIPO - # Extract the first word of "lipo", so it can be a program name with args. -set dummy lipo; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_LIPO+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_LIPO"; then - ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_LIPO="lipo" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO -if test -n "$ac_ct_LIPO"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 -printf "%s\n" "$ac_ct_LIPO" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - if test "x$ac_ct_LIPO" = x; then - LIPO=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - LIPO=$ac_ct_LIPO - fi -else - LIPO="$ac_cv_prog_LIPO" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. -set dummy ${ac_tool_prefix}otool; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_OTOOL+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$OTOOL"; then - ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_OTOOL="${ac_tool_prefix}otool" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -OTOOL=$ac_cv_prog_OTOOL -if test -n "$OTOOL"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 -printf "%s\n" "$OTOOL" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OTOOL"; then - ac_ct_OTOOL=$OTOOL - # Extract the first word of "otool", so it can be a program name with args. -set dummy otool; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_OTOOL+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_OTOOL"; then - ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_OTOOL="otool" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL -if test -n "$ac_ct_OTOOL"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 -printf "%s\n" "$ac_ct_OTOOL" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - if test "x$ac_ct_OTOOL" = x; then - OTOOL=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OTOOL=$ac_ct_OTOOL - fi -else - OTOOL="$ac_cv_prog_OTOOL" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. -set dummy ${ac_tool_prefix}otool64; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_OTOOL64+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$OTOOL64"; then - ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -OTOOL64=$ac_cv_prog_OTOOL64 -if test -n "$OTOOL64"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 -printf "%s\n" "$OTOOL64" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OTOOL64"; then - ac_ct_OTOOL64=$OTOOL64 - # Extract the first word of "otool64", so it can be a program name with args. -set dummy otool64; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_OTOOL64+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_OTOOL64"; then - ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_OTOOL64="otool64" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 -if test -n "$ac_ct_OTOOL64"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 -printf "%s\n" "$ac_ct_OTOOL64" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - if test "x$ac_ct_OTOOL64" = x; then - OTOOL64=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OTOOL64=$ac_ct_OTOOL64 - fi -else - OTOOL64="$ac_cv_prog_OTOOL64" -fi - - - - - - - - - - - - - - - - - - - - - - - - - - - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 -printf %s "checking for -single_module linker flag... " >&6; } -if test ${lt_cv_apple_cc_single_mod+y} -then : - printf %s "(cached) " >&6 -else $as_nop - lt_cv_apple_cc_single_mod=no - if test -z "$LT_MULTI_MODULE"; then - # By default we will add the -single_module flag. You can override - # by either setting the environment variable LT_MULTI_MODULE - # non-empty at configure time, or by adding -multi_module to the - # link flags. - rm -rf libconftest.dylib* - echo "int foo(void){return 1;}" > conftest.c - echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ --dynamiclib -Wl,-single_module conftest.c" >&5 - $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ - -dynamiclib -Wl,-single_module conftest.c 2>conftest.err - _lt_result=$? - # If there is a non-empty error log, and "single_module" - # appears in it, assume the flag caused a linker warning - if test -s conftest.err && $GREP single_module conftest.err; then - cat conftest.err >&5 - # Otherwise, if the output was created with a 0 exit code from - # the compiler, it worked. - elif test -f libconftest.dylib && test 0 = "$_lt_result"; then - lt_cv_apple_cc_single_mod=yes - else - cat conftest.err >&5 - fi - rm -rf libconftest.dylib* - rm -f conftest.* - fi -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 -printf "%s\n" "$lt_cv_apple_cc_single_mod" >&6; } - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 -printf %s "checking for -exported_symbols_list linker flag... " >&6; } -if test ${lt_cv_ld_exported_symbols_list+y} -then : - printf %s "(cached) " >&6 -else $as_nop - lt_cv_ld_exported_symbols_list=no - save_LDFLAGS=$LDFLAGS - echo "_main" > conftest.sym - LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - lt_cv_ld_exported_symbols_list=yes -else $as_nop - lt_cv_ld_exported_symbols_list=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS=$save_LDFLAGS - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 -printf "%s\n" "$lt_cv_ld_exported_symbols_list" >&6; } - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 -printf %s "checking for -force_load linker flag... " >&6; } -if test ${lt_cv_ld_force_load+y} -then : - printf %s "(cached) " >&6 -else $as_nop - lt_cv_ld_force_load=no - cat > conftest.c << _LT_EOF -int forced_loaded() { return 2;} -_LT_EOF - echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 - $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 - echo "$AR cr libconftest.a conftest.o" >&5 - $AR cr libconftest.a conftest.o 2>&5 - echo "$RANLIB libconftest.a" >&5 - $RANLIB libconftest.a 2>&5 - cat > conftest.c << _LT_EOF -int main() { return 0;} -_LT_EOF - echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 - $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err - _lt_result=$? - if test -s conftest.err && $GREP force_load conftest.err; then - cat conftest.err >&5 - elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then - lt_cv_ld_force_load=yes - else - cat conftest.err >&5 - fi - rm -f conftest.err libconftest.a conftest conftest.c - rm -rf conftest.dSYM - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 -printf "%s\n" "$lt_cv_ld_force_load" >&6; } - case $host_os in - rhapsody* | darwin1.[012]) - _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; - darwin1.*) - _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[912]*) - _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; - 10.[012][,.]*) - _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - 10.*|11.*) - _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; - esac - ;; - esac - if test yes = "$lt_cv_apple_cc_single_mod"; then - _lt_dar_single_mod='$single_module' - fi - if test yes = "$lt_cv_ld_exported_symbols_list"; then - _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' - else - _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' - fi - if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then - _lt_dsymutil='~$DSYMUTIL $lib || :' - else - _lt_dsymutil= - fi - ;; - esac - -# func_munge_path_list VARIABLE PATH -# ----------------------------------- -# VARIABLE is name of variable containing _space_ separated list of -# directories to be munged by the contents of PATH, which is string -# having a format: -# "DIR[:DIR]:" -# string "DIR[ DIR]" will be prepended to VARIABLE -# ":DIR[:DIR]" -# string "DIR[ DIR]" will be appended to VARIABLE -# "DIRP[:DIRP]::[DIRA:]DIRA" -# string "DIRP[ DIRP]" will be prepended to VARIABLE and string -# "DIRA[ DIRA]" will be appended to VARIABLE -# "DIR[:DIR]" -# VARIABLE will be replaced by "DIR[ DIR]" -func_munge_path_list () -{ - case x$2 in - x) - ;; - *:) - eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" - ;; - x:*) - eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" - ;; - *::*) - eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" - eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" - ;; - *) - eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" - ;; - esac -} - -ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default -" -if test "x$ac_cv_header_dlfcn_h" = xyes -then : - printf "%s\n" "#define HAVE_DLFCN_H 1" >>confdefs.h - -fi - - - - - -# Set options - - - - enable_dlopen=no - - - - # Check whether --enable-shared was given. -if test ${enable_shared+y} -then : - enableval=$enable_shared; p=${PACKAGE-default} - case $enableval in - yes) enable_shared=yes ;; - no) enable_shared=no ;; - *) - enable_shared=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, - for pkg in $enableval; do - IFS=$lt_save_ifs - if test "X$pkg" = "X$p"; then - enable_shared=yes - fi - done - IFS=$lt_save_ifs - ;; - esac -else $as_nop - enable_shared=yes -fi - - - - - - - - - - # Check whether --enable-static was given. -if test ${enable_static+y} -then : - enableval=$enable_static; p=${PACKAGE-default} - case $enableval in - yes) enable_static=yes ;; - no) enable_static=no ;; - *) - enable_static=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, - for pkg in $enableval; do - IFS=$lt_save_ifs - if test "X$pkg" = "X$p"; then - enable_static=yes - fi - done - IFS=$lt_save_ifs - ;; - esac -else $as_nop - enable_static=yes -fi - - - - - - - - - - -# Check whether --with-pic was given. -if test ${with_pic+y} -then : - withval=$with_pic; lt_p=${PACKAGE-default} - case $withval in - yes|no) pic_mode=$withval ;; - *) - pic_mode=default - # Look at the argument we got. We use all the common list separators. - lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, - for lt_pkg in $withval; do - IFS=$lt_save_ifs - if test "X$lt_pkg" = "X$lt_p"; then - pic_mode=yes - fi - done - IFS=$lt_save_ifs - ;; - esac -else $as_nop - pic_mode=default -fi - - - - - - - - - # Check whether --enable-fast-install was given. -if test ${enable_fast_install+y} -then : - enableval=$enable_fast_install; p=${PACKAGE-default} - case $enableval in - yes) enable_fast_install=yes ;; - no) enable_fast_install=no ;; - *) - enable_fast_install=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, - for pkg in $enableval; do - IFS=$lt_save_ifs - if test "X$pkg" = "X$p"; then - enable_fast_install=yes - fi - done - IFS=$lt_save_ifs - ;; - esac -else $as_nop - enable_fast_install=yes -fi - - - - - - - - - shared_archive_member_spec= -case $host,$enable_shared in -power*-*-aix[5-9]*,yes) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 -printf %s "checking which variant of shared library versioning to provide... " >&6; } - -# Check whether --with-aix-soname was given. -if test ${with_aix_soname+y} -then : - withval=$with_aix_soname; case $withval in - aix|svr4|both) - ;; - *) - as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 - ;; - esac - lt_cv_with_aix_soname=$with_aix_soname -else $as_nop - if test ${lt_cv_with_aix_soname+y} -then : - printf %s "(cached) " >&6 -else $as_nop - lt_cv_with_aix_soname=aix -fi - - with_aix_soname=$lt_cv_with_aix_soname -fi - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 -printf "%s\n" "$with_aix_soname" >&6; } - if test aix != "$with_aix_soname"; then - # For the AIX way of multilib, we name the shared archive member - # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', - # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. - # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, - # the AIX toolchain works better with OBJECT_MODE set (default 32). - if test 64 = "${OBJECT_MODE-32}"; then - shared_archive_member_spec=shr_64 - else - shared_archive_member_spec=shr - fi - fi - ;; -*) - with_aix_soname=aix - ;; -esac - - - - - - - - - - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS=$ltmain - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -test -z "$LN_S" && LN_S="ln -s" - - - - - - - - - - - - - - -if test -n "${ZSH_VERSION+set}"; then - setopt NO_GLOB_SUBST -fi - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 -printf %s "checking for objdir... " >&6; } -if test ${lt_cv_objdir+y} -then : - printf %s "(cached) " >&6 -else $as_nop - rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - lt_cv_objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - lt_cv_objdir=_libs -fi -rmdir .libs 2>/dev/null -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 -printf "%s\n" "$lt_cv_objdir" >&6; } -objdir=$lt_cv_objdir - - - - - -printf "%s\n" "#define LT_OBJDIR \"$lt_cv_objdir/\"" >>confdefs.h - - - - -case $host_os in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test set != "${COLLECT_NAMES+set}"; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Global variables: -ofile=libtool -can_build_shared=yes - -# All known linkers require a '.a' archive for static linking (except MSVC, -# which needs '.lib'). -libext=a - -with_gnu_ld=$lt_cv_prog_gnu_ld - -old_CC=$CC -old_CFLAGS=$CFLAGS - -# Set sane defaults for various variables -test -z "$CC" && CC=cc -test -z "$LTCC" && LTCC=$CC -test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS -test -z "$LD" && LD=ld -test -z "$ac_objext" && ac_objext=o - -func_cc_basename $compiler -cc_basename=$func_cc_basename_result - - -# Only perform the check for file, if the check method requires it -test -z "$MAGIC_CMD" && MAGIC_CMD=file -case $deplibs_check_method in -file_magic*) - if test "$file_magic_cmd" = '$MAGIC_CMD'; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 -printf %s "checking for ${ac_tool_prefix}file... " >&6; } -if test ${lt_cv_path_MAGIC_CMD+y} -then : - printf %s "(cached) " >&6 -else $as_nop - case $MAGIC_CMD in -[\\/*] | ?:[\\/]*) - lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD=$MAGIC_CMD - lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR - ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" - for ac_dir in $ac_dummy; do - IFS=$lt_save_ifs - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/${ac_tool_prefix}file"; then - lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD=$lt_cv_path_MAGIC_CMD - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<_LT_EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -_LT_EOF - fi ;; - esac - fi - break - fi - done - IFS=$lt_save_ifs - MAGIC_CMD=$lt_save_MAGIC_CMD - ;; -esac -fi - -MAGIC_CMD=$lt_cv_path_MAGIC_CMD -if test -n "$MAGIC_CMD"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 -printf "%s\n" "$MAGIC_CMD" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - - - - -if test -z "$lt_cv_path_MAGIC_CMD"; then - if test -n "$ac_tool_prefix"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for file" >&5 -printf %s "checking for file... " >&6; } -if test ${lt_cv_path_MAGIC_CMD+y} -then : - printf %s "(cached) " >&6 -else $as_nop - case $MAGIC_CMD in -[\\/*] | ?:[\\/]*) - lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD=$MAGIC_CMD - lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR - ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" - for ac_dir in $ac_dummy; do - IFS=$lt_save_ifs - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/file"; then - lt_cv_path_MAGIC_CMD=$ac_dir/"file" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD=$lt_cv_path_MAGIC_CMD - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<_LT_EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -_LT_EOF - fi ;; - esac - fi - break - fi - done - IFS=$lt_save_ifs - MAGIC_CMD=$lt_save_MAGIC_CMD - ;; -esac -fi - -MAGIC_CMD=$lt_cv_path_MAGIC_CMD -if test -n "$MAGIC_CMD"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 -printf "%s\n" "$MAGIC_CMD" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - - else - MAGIC_CMD=: - fi -fi - - fi - ;; -esac - -# Use C for the default configuration in the libtool script - -lt_save_CC=$CC -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -# Source file extension for C test sources. -ac_ext=c - -# Object file extension for compiled C test sources. -objext=o -objext=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}' - - - - - - - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC - -# Save the default compiler, since it gets overwritten when the other -# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. -compiler_DEFAULT=$CC - -# save warnings/boilerplate of simple test code -ac_outfile=conftest.$ac_objext -echo "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$RM conftest* - -ac_outfile=conftest.$ac_objext -echo "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$RM -r conftest* - - -if test -n "$compiler"; then - -lt_prog_compiler_no_builtin_flag= - -if test yes = "$GCC"; then - case $cc_basename in - nvcc*) - lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; - *) - lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; - esac - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 -printf %s "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } -if test ${lt_cv_prog_compiler_rtti_exceptions+y} -then : - printf %s "(cached) " >&6 -else $as_nop - lt_cv_prog_compiler_rtti_exceptions=no - ac_outfile=conftest.$ac_objext - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_rtti_exceptions=yes - fi - fi - $RM conftest* - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 -printf "%s\n" "$lt_cv_prog_compiler_rtti_exceptions" >&6; } - -if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then - lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" -else - : -fi - -fi - - - - - - - lt_prog_compiler_wl= -lt_prog_compiler_pic= -lt_prog_compiler_static= - - - if test yes = "$GCC"; then - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_static='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test ia64 = "$host_cpu"; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static='-Bstatic' - fi - lt_prog_compiler_pic='-fPIC' - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - lt_prog_compiler_pic='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the '-m68020' flag to GCC prevents building anything better, - # like '-m68040'. - lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - lt_prog_compiler_pic='-DDLL_EXPORT' - case $host_os in - os2*) - lt_prog_compiler_static='$wl-static' - ;; - esac - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - lt_prog_compiler_pic='-fno-common' - ;; - - haiku*) - # PIC is the default for Haiku. - # The "-static" flag exists, but is broken. - lt_prog_compiler_static= - ;; - - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic='-fPIC' - ;; - esac - ;; - - interix[3-9]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - lt_prog_compiler_can_build_shared=no - enable_shared=no - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - lt_prog_compiler_pic='-fPIC -shared' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - lt_prog_compiler_pic=-Kconform_pic - fi - ;; - - *) - lt_prog_compiler_pic='-fPIC' - ;; - esac - - case $cc_basename in - nvcc*) # Cuda Compiler Driver 2.2 - lt_prog_compiler_wl='-Xlinker ' - if test -n "$lt_prog_compiler_pic"; then - lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" - fi - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - lt_prog_compiler_wl='-Wl,' - if test ia64 = "$host_cpu"; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static='-Bstatic' - else - lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' - fi - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - lt_prog_compiler_pic='-fno-common' - case $cc_basename in - nagfor*) - # NAG Fortran compiler - lt_prog_compiler_wl='-Wl,-Wl,,' - lt_prog_compiler_pic='-PIC' - lt_prog_compiler_static='-Bstatic' - ;; - esac - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_prog_compiler_pic='-DDLL_EXPORT' - case $host_os in - os2*) - lt_prog_compiler_static='$wl-static' - ;; - esac - ;; - - hpux9* | hpux10* | hpux11*) - lt_prog_compiler_wl='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - lt_prog_compiler_static='$wl-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - lt_prog_compiler_wl='-Wl,' - # PIC (with -KPIC) is the default. - lt_prog_compiler_static='-non_shared' - ;; - - linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - case $cc_basename in - # old Intel for x86_64, which still supported -KPIC. - ecc*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-static' - ;; - # flang / f18. f95 an alias for gfortran or flang on Debian - flang* | f18* | f95*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fPIC' - lt_prog_compiler_static='-static' - ;; - # icc used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - icc* | ifort*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fPIC' - lt_prog_compiler_static='-static' - ;; - # Lahey Fortran 8.1. - lf95*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='--shared' - lt_prog_compiler_static='--static' - ;; - nagfor*) - # NAG Fortran compiler - lt_prog_compiler_wl='-Wl,-Wl,,' - lt_prog_compiler_pic='-PIC' - lt_prog_compiler_static='-Bstatic' - ;; - tcc*) - # Fabrice Bellard et al's Tiny C Compiler - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fPIC' - lt_prog_compiler_static='-static' - ;; - pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) - # Portland Group compilers (*not* the Pentium gcc compiler, - # which looks to be a dead project) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fpic' - lt_prog_compiler_static='-Bstatic' - ;; - ccc*) - lt_prog_compiler_wl='-Wl,' - # All Alpha code is PIC. - lt_prog_compiler_static='-non_shared' - ;; - xl* | bgxl* | bgf* | mpixl*) - # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-qpic' - lt_prog_compiler_static='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) - # Sun Fortran 8.3 passes all unrecognized flags to the linker - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - lt_prog_compiler_wl='' - ;; - *Sun\ F* | *Sun*Fortran*) - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - lt_prog_compiler_wl='-Qoption ld ' - ;; - *Sun\ C*) - # Sun C 5.9 - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - lt_prog_compiler_wl='-Wl,' - ;; - *Intel*\ [CF]*Compiler*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fPIC' - lt_prog_compiler_static='-static' - ;; - *Portland\ Group*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fpic' - lt_prog_compiler_static='-Bstatic' - ;; - esac - ;; - esac - ;; - - newsos6) - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - lt_prog_compiler_pic='-fPIC -shared' - ;; - - osf3* | osf4* | osf5*) - lt_prog_compiler_wl='-Wl,' - # All OSF/1 code is PIC. - lt_prog_compiler_static='-non_shared' - ;; - - rdos*) - lt_prog_compiler_static='-non_shared' - ;; - - solaris*) - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - case $cc_basename in - f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) - lt_prog_compiler_wl='-Qoption ld ';; - *) - lt_prog_compiler_wl='-Wl,';; - esac - ;; - - sunos4*) - lt_prog_compiler_wl='-Qoption ld ' - lt_prog_compiler_pic='-PIC' - lt_prog_compiler_static='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - lt_prog_compiler_pic='-Kconform_pic' - lt_prog_compiler_static='-Bstatic' - fi - ;; - - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - unicos*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_can_build_shared=no - ;; - - uts4*) - lt_prog_compiler_pic='-pic' - lt_prog_compiler_static='-Bstatic' - ;; - - *) - lt_prog_compiler_can_build_shared=no - ;; - esac - fi - -case $host_os in - # For platforms that do not support PIC, -DPIC is meaningless: - *djgpp*) - lt_prog_compiler_pic= - ;; - *) - lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" - ;; -esac - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 -printf %s "checking for $compiler option to produce PIC... " >&6; } -if test ${lt_cv_prog_compiler_pic+y} -then : - printf %s "(cached) " >&6 -else $as_nop - lt_cv_prog_compiler_pic=$lt_prog_compiler_pic -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 -printf "%s\n" "$lt_cv_prog_compiler_pic" >&6; } -lt_prog_compiler_pic=$lt_cv_prog_compiler_pic - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$lt_prog_compiler_pic"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 -printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } -if test ${lt_cv_prog_compiler_pic_works+y} -then : - printf %s "(cached) " >&6 -else $as_nop - lt_cv_prog_compiler_pic_works=no - ac_outfile=conftest.$ac_objext - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_pic_works=yes - fi - fi - $RM conftest* - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 -printf "%s\n" "$lt_cv_prog_compiler_pic_works" >&6; } - -if test yes = "$lt_cv_prog_compiler_pic_works"; then - case $lt_prog_compiler_pic in - "" | " "*) ;; - *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; - esac -else - lt_prog_compiler_pic= - lt_prog_compiler_can_build_shared=no -fi - -fi - - - - - - - - - - - -# -# Check to make sure the static flag actually works. -# -wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 -printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } -if test ${lt_cv_prog_compiler_static_works+y} -then : - printf %s "(cached) " >&6 -else $as_nop - lt_cv_prog_compiler_static_works=no - save_LDFLAGS=$LDFLAGS - LDFLAGS="$LDFLAGS $lt_tmp_static_flag" - echo "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&5 - $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_static_works=yes - fi - else - lt_cv_prog_compiler_static_works=yes - fi - fi - $RM -r conftest* - LDFLAGS=$save_LDFLAGS - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 -printf "%s\n" "$lt_cv_prog_compiler_static_works" >&6; } - -if test yes = "$lt_cv_prog_compiler_static_works"; then - : -else - lt_prog_compiler_static= -fi - - - - - - - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 -printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if test ${lt_cv_prog_compiler_c_o+y} -then : - printf %s "(cached) " >&6 -else $as_nop - lt_cv_prog_compiler_c_o=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - lt_cv_prog_compiler_c_o=yes - fi - fi - chmod u+w . 2>&5 - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 -printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } - - - - - - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 -printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if test ${lt_cv_prog_compiler_c_o+y} -then : - printf %s "(cached) " >&6 -else $as_nop - lt_cv_prog_compiler_c_o=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - lt_cv_prog_compiler_c_o=yes - fi - fi - chmod u+w . 2>&5 - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 -printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } - - - - -hard_links=nottested -if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then - # do not overwrite the value of need_locks provided by the user - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 -printf %s "checking if we can lock with hard links... " >&6; } - hard_links=yes - $RM conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 -printf "%s\n" "$hard_links" >&6; } - if test no = "$hard_links"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 -printf "%s\n" "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} - need_locks=warn - fi -else - need_locks=no -fi - - - - - - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 -printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } - - runpath_var= - allow_undefined_flag= - always_export_symbols=no - archive_cmds= - archive_expsym_cmds= - compiler_needs_object=no - enable_shared_with_static_runtimes=no - export_dynamic_flag_spec= - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - hardcode_automatic=no - hardcode_direct=no - hardcode_direct_absolute=no - hardcode_libdir_flag_spec= - hardcode_libdir_separator= - hardcode_minus_L=no - hardcode_shlibpath_var=unsupported - inherit_rpath=no - link_all_deplibs=unknown - module_cmds= - module_expsym_cmds= - old_archive_from_new_cmds= - old_archive_from_expsyms_cmds= - thread_safe_flag_spec= - whole_archive_flag_spec= - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - include_expsyms= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ' (' and ')$', so one must not match beginning or - # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', - # as well as any symbol that contains 'd'. - exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - # Exclude shared library initialization/finalization symbols. - extract_expsyms_cmds= - - case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test yes != "$GCC"; then - with_gnu_ld=no - fi - ;; - interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) - with_gnu_ld=yes - ;; - openbsd* | bitrig*) - with_gnu_ld=no - ;; - linux* | k*bsd*-gnu | gnu*) - link_all_deplibs=no - ;; - esac - - ld_shlibs=yes - - # On some targets, GNU ld is compatible enough with the native linker - # that we're better off using the native interface for both. - lt_use_gnu_ld_interface=no - if test yes = "$with_gnu_ld"; then - case $host_os in - aix*) - # The AIX port of GNU ld has always aspired to compatibility - # with the native linker. However, as the warning in the GNU ld - # block says, versions before 2.19.5* couldn't really create working - # shared libraries, regardless of the interface used. - case `$LD -v 2>&1` in - *\ \(GNU\ Binutils\)\ 2.19.5*) ;; - *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; - *\ \(GNU\ Binutils\)\ [3-9]*) ;; - *) - lt_use_gnu_ld_interface=yes - ;; - esac - ;; - *) - lt_use_gnu_ld_interface=yes - ;; - esac - fi - - if test yes = "$lt_use_gnu_ld_interface"; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='$wl' - - # Set some defaults for GNU ld with shared library support. These - # are reset later if shared libraries are not supported. Putting them - # here allows them to be overridden if necessary. - runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' - export_dynamic_flag_spec='$wl--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' - else - whole_archive_flag_spec= - fi - supports_anon_versioning=no - case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in - *GNU\ gold*) supports_anon_versioning=yes ;; - *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - - # See if GNU ld supports shared libraries. - case $host_os in - aix[3-9]*) - # On AIX/PPC, the GNU linker is very broken - if test ia64 != "$host_cpu"; then - ld_shlibs=no - cat <<_LT_EOF 1>&2 - -*** Warning: the GNU linker, at least up to release 2.19, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to install binutils -*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. -*** You will then need to restart the configuration process. - -_LT_EOF - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - archive_expsym_cmds='' - ;; - m68k) - archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - ;; - esac - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - allow_undefined_flag=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - else - ld_shlibs=no - fi - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, - # as there is no search path for DLLs. - hardcode_libdir_flag_spec='-L$libdir' - export_dynamic_flag_spec='$wl--export-all-symbols' - allow_undefined_flag=unsupported - always_export_symbols=no - enable_shared_with_static_runtimes=yes - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' - exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file, use it as - # is; otherwise, prepend EXPORTS... - archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - ld_shlibs=no - fi - ;; - - haiku*) - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - link_all_deplibs=yes - ;; - - os2*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - allow_undefined_flag=unsupported - shrext_cmds=.dll - archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ - $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ - $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ - $ECHO EXPORTS >> $output_objdir/$libname.def~ - emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ - $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ - emximp -o $lib $output_objdir/$libname.def' - archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ - $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ - $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ - $ECHO EXPORTS >> $output_objdir/$libname.def~ - prefix_cmds="$SED"~ - if test EXPORTS = "`$SED 1q $export_symbols`"; then - prefix_cmds="$prefix_cmds -e 1d"; - fi~ - prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ - cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ - $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ - emximp -o $lib $output_objdir/$libname.def' - old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' - enable_shared_with_static_runtimes=yes - ;; - - interix[3-9]*) - hardcode_direct=no - hardcode_shlibpath_var=no - hardcode_libdir_flag_spec='$wl-rpath,$libdir' - export_dynamic_flag_spec='$wl-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - - gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) - tmp_diet=no - if test linux-dietlibc = "$host_os"; then - case $cc_basename in - diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) - esac - fi - if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ - && test no = "$tmp_diet" - then - tmp_addflag=' $pic_flag' - tmp_sharedflag='-shared' - case $cc_basename,$host_cpu in - pgcc*) # Portland Group C compiler - whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' - tmp_addflag=' $pic_flag' - ;; - pgf77* | pgf90* | pgf95* | pgfortran*) - # Portland Group f77 and f90 compilers - whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' - tmp_addflag=' $pic_flag -Mnomain' ;; - ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 - tmp_addflag=' -i_dynamic' ;; - efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 - tmp_addflag=' -i_dynamic -nofor_main' ;; - ifc* | ifort*) # Intel Fortran compiler - tmp_addflag=' -nofor_main' ;; - lf95*) # Lahey Fortran 8.1 - whole_archive_flag_spec= - tmp_sharedflag='--shared' ;; - nagfor*) # NAGFOR 5.3 - tmp_sharedflag='-Wl,-shared' ;; - xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) - tmp_sharedflag='-qmkshrobj' - tmp_addflag= ;; - nvcc*) # Cuda Compiler Driver 2.2 - whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' - compiler_needs_object=yes - ;; - esac - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) # Sun C 5.9 - whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' - compiler_needs_object=yes - tmp_sharedflag='-G' ;; - *Sun\ F*) # Sun Fortran 8.3 - tmp_sharedflag='-G' ;; - esac - archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - - if test yes = "$supports_anon_versioning"; then - archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' - fi - - case $cc_basename in - tcc*) - export_dynamic_flag_spec='-rdynamic' - ;; - xlf* | bgf* | bgxlf* | mpixlf*) - # IBM XL Fortran 10.1 on PPC cannot create shared libs itself - whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' - hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' - archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' - if test yes = "$supports_anon_versioning"; then - archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' - fi - ;; - esac - else - ld_shlibs=no - fi - ;; - - netbsd* | netbsdelf*-gnu) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris*) - if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then - ld_shlibs=no - cat <<_LT_EOF 1>&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - - sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) - case `$LD -v 2>&1` in - *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) - ld_shlibs=no - cat <<_LT_EOF 1>&2 - -*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot -*** reliably create shared libraries on SCO systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.16.91.0.3 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - ;; - *) - # For security reasons, it is highly recommended that you always - # use absolute paths for naming shared libraries, and exclude the - # DT_RUNPATH tag from executables and libraries. But doing so - # requires that you compile everything twice, which is a pain. - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - esac - ;; - - sunos4*) - archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - *) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - esac - - if test no = "$ld_shlibs"; then - runpath_var= - hardcode_libdir_flag_spec= - export_dynamic_flag_spec= - whole_archive_flag_spec= - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - allow_undefined_flag=unsupported - always_export_symbols=yes - archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - hardcode_minus_L=yes - if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - hardcode_direct=unsupported - fi - ;; - - aix[4-9]*) - if test ia64 = "$host_cpu"; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag= - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to GNU nm, but means don't demangle to AIX nm. - # Without the "-l" option, or with the "-B" option, AIX nm treats - # weak defined symbols like other global defined symbols, whereas - # GNU nm marks them as "W". - # While the 'weak' keyword is ignored in the Export File, we need - # it in the Import File for the 'aix-soname' feature, so we have - # to replace the "-B" option with "-P" for AIX nm. - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' - else - export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # have runtime linking enabled, and use it for executables. - # For shared libraries, we enable/disable runtime linking - # depending on the kind of the shared library created - - # when "with_aix_soname,aix_use_runtimelinking" is: - # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables - # "aix,yes" lib.so shared, rtl:yes, for executables - # lib.a static archive - # "both,no" lib.so.V(shr.o) shared, rtl:yes - # lib.a(lib.so.V) shared, rtl:no, for executables - # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables - # lib.a(lib.so.V) shared, rtl:no - # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables - # lib.a static archive - case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) - for ld_flag in $LDFLAGS; do - if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then - aix_use_runtimelinking=yes - break - fi - done - if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then - # With aix-soname=svr4, we create the lib.so.V shared archives only, - # so we don't have lib.a shared libs to link our executables. - # We have to force runtime linking in this case. - aix_use_runtimelinking=yes - LDFLAGS="$LDFLAGS -Wl,-brtl" - fi - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - archive_cmds='' - hardcode_direct=yes - hardcode_direct_absolute=yes - hardcode_libdir_separator=':' - link_all_deplibs=yes - file_list_spec='$wl-f,' - case $with_aix_soname,$aix_use_runtimelinking in - aix,*) ;; # traditional, no import file - svr4,* | *,yes) # use import file - # The Import File defines what to hardcode. - hardcode_direct=no - hardcode_direct_absolute=no - ;; - esac - - if test yes = "$GCC"; then - case $host_os in aix4.[012]|aix4.[012].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`$CC -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - hardcode_direct=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - hardcode_minus_L=yes - hardcode_libdir_flag_spec='-L$libdir' - hardcode_libdir_separator= - fi - ;; - esac - shared_flag='-shared' - if test yes = "$aix_use_runtimelinking"; then - shared_flag="$shared_flag "'$wl-G' - fi - # Need to ensure runtime linking is disabled for the traditional - # shared library, or the linker may eventually find shared libraries - # /with/ Import File - we do not want to mix them. - shared_flag_aix='-shared' - shared_flag_svr4='-shared $wl-G' - else - # not using gcc - if test ia64 = "$host_cpu"; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test yes = "$aix_use_runtimelinking"; then - shared_flag='$wl-G' - else - shared_flag='$wl-bM:SRE' - fi - shared_flag_aix='$wl-bM:SRE' - shared_flag_svr4='$wl-G' - fi - fi - - export_dynamic_flag_spec='$wl-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - always_export_symbols=yes - if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - allow_undefined_flag='-berok' - # Determine the default libpath from the value encoded in an - # empty executable. - if test set = "${lt_cv_aix_libpath+set}"; then - aix_libpath=$lt_cv_aix_libpath -else - if test ${lt_cv_aix_libpath_+y} -then : - printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - - lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\([^ ]*\) *$/\1/ - p - } - }' - lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - # Check for a 64-bit object if we didn't find anything. - if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - fi -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_=/usr/lib:/lib - fi - -fi - - aix_libpath=$lt_cv_aix_libpath_ -fi - - hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" - archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag - else - if test ia64 = "$host_cpu"; then - hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' - allow_undefined_flag="-z nodefs" - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - if test set = "${lt_cv_aix_libpath+set}"; then - aix_libpath=$lt_cv_aix_libpath -else - if test ${lt_cv_aix_libpath_+y} -then : - printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - - lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\([^ ]*\) *$/\1/ - p - } - }' - lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - # Check for a 64-bit object if we didn't find anything. - if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - fi -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_=/usr/lib:/lib - fi - -fi - - aix_libpath=$lt_cv_aix_libpath_ -fi - - hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - no_undefined_flag=' $wl-bernotok' - allow_undefined_flag=' $wl-berok' - if test yes = "$with_gnu_ld"; then - # We only use this code for GNU lds that support --whole-archive. - whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' - else - # Exported symbols can be pulled into shared objects from archives - whole_archive_flag_spec='$convenience' - fi - archive_cmds_need_lc=yes - archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' - # -brtl affects multiple linker settings, -berok does not and is overridden later - compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' - if test svr4 != "$with_aix_soname"; then - # This is similar to how AIX traditionally builds its shared libraries. - archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' - fi - if test aix != "$with_aix_soname"; then - archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' - else - # used by -dlpreopen to get the symbols - archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' - fi - archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' - fi - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - archive_expsym_cmds='' - ;; - m68k) - archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - ;; - esac - ;; - - bsdi[45]*) - export_dynamic_flag_spec=-rdynamic - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - case $cc_basename in - cl*) - # Native MSVC - hardcode_libdir_flag_spec=' ' - allow_undefined_flag=unsupported - always_export_symbols=yes - file_list_spec='@' - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=.dll - # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' - archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then - cp "$export_symbols" "$output_objdir/$soname.def"; - echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; - else - $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' - # The linker will not automatically build a static lib if we build a DLL. - # _LT_TAGVAR(old_archive_from_new_cmds, )='true' - enable_shared_with_static_runtimes=yes - exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' - # Don't use ranlib - old_postinstall_cmds='chmod 644 $oldlib' - postlink_cmds='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile=$lt_outputfile.exe - lt_tool_outputfile=$lt_tool_outputfile.exe - ;; - esac~ - if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' - ;; - *) - # Assume MSVC wrapper - hardcode_libdir_flag_spec=' ' - allow_undefined_flag=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=.dll - # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - old_archive_from_new_cmds='true' - # FIXME: Should let the user specify the lib program. - old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' - enable_shared_with_static_runtimes=yes - ;; - esac - ;; - - darwin* | rhapsody*) - - - archive_cmds_need_lc=no - hardcode_direct=no - hardcode_automatic=yes - hardcode_shlibpath_var=unsupported - if test yes = "$lt_cv_ld_force_load"; then - whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' - - else - whole_archive_flag_spec='' - fi - link_all_deplibs=yes - allow_undefined_flag=$_lt_dar_allow_undefined - case $cc_basename in - ifort*|nagfor*) _lt_dar_can_shared=yes ;; - *) _lt_dar_can_shared=$GCC ;; - esac - if test yes = "$_lt_dar_can_shared"; then - output_verbose_link_cmd=func_echo_all - archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" - archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" - module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" - - else - ld_shlibs=no - fi - - ;; - - dgux*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2.*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - hpux9*) - if test yes = "$GCC"; then - archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' - else - archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' - fi - hardcode_libdir_flag_spec='$wl+b $wl$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - export_dynamic_flag_spec='$wl-E' - ;; - - hpux10*) - if test yes,no = "$GCC,$with_gnu_ld"; then - archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - fi - if test no = "$with_gnu_ld"; then - hardcode_libdir_flag_spec='$wl+b $wl$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - hardcode_direct_absolute=yes - export_dynamic_flag_spec='$wl-E' - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - fi - ;; - - hpux11*) - if test yes,no = "$GCC,$with_gnu_ld"; then - case $host_cpu in - hppa*64*) - archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case $host_cpu in - hppa*64*) - archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - - # Older versions of the 11.00 compiler do not understand -b yet - # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 -printf %s "checking if $CC understands -b... " >&6; } -if test ${lt_cv_prog_compiler__b+y} -then : - printf %s "(cached) " >&6 -else $as_nop - lt_cv_prog_compiler__b=no - save_LDFLAGS=$LDFLAGS - LDFLAGS="$LDFLAGS -b" - echo "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&5 - $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler__b=yes - fi - else - lt_cv_prog_compiler__b=yes - fi - fi - $RM -r conftest* - LDFLAGS=$save_LDFLAGS - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 -printf "%s\n" "$lt_cv_prog_compiler__b" >&6; } - -if test yes = "$lt_cv_prog_compiler__b"; then - archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' -else - archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' -fi - - ;; - esac - fi - if test no = "$with_gnu_ld"; then - hardcode_libdir_flag_spec='$wl+b $wl$libdir' - hardcode_libdir_separator=: - - case $host_cpu in - hppa*64*|ia64*) - hardcode_direct=no - hardcode_shlibpath_var=no - ;; - *) - hardcode_direct=yes - hardcode_direct_absolute=yes - export_dynamic_flag_spec='$wl-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test yes = "$GCC"; then - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' - # Try to use the -exported_symbol ld option, if it does not - # work, assume that -exports_file does not work either and - # implicitly export all symbols. - # This should be the same for all languages, so no per-tag cache variable. - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 -printf %s "checking whether the $host_os linker accepts -exported_symbol... " >&6; } -if test ${lt_cv_irix_exported_symbol+y} -then : - printf %s "(cached) " >&6 -else $as_nop - save_LDFLAGS=$LDFLAGS - LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -int foo (void) { return 0; } -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - lt_cv_irix_exported_symbol=yes -else $as_nop - lt_cv_irix_exported_symbol=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS=$save_LDFLAGS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 -printf "%s\n" "$lt_cv_irix_exported_symbol" >&6; } - if test yes = "$lt_cv_irix_exported_symbol"; then - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' - fi - link_all_deplibs=no - else - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' - fi - archive_cmds_need_lc='no' - hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' - hardcode_libdir_separator=: - inherit_rpath=yes - link_all_deplibs=yes - ;; - - linux*) - case $cc_basename in - tcc*) - # Fabrice Bellard et al's Tiny C Compiler - ld_shlibs=yes - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - netbsd* | netbsdelf*-gnu) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - newsos6) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' - hardcode_libdir_separator=: - hardcode_shlibpath_var=no - ;; - - *nto* | *qnx*) - ;; - - openbsd* | bitrig*) - if test -f /usr/libexec/ld.so; then - hardcode_direct=yes - hardcode_shlibpath_var=no - hardcode_direct_absolute=yes - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' - hardcode_libdir_flag_spec='$wl-rpath,$libdir' - export_dynamic_flag_spec='$wl-E' - else - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='$wl-rpath,$libdir' - fi - else - ld_shlibs=no - fi - ;; - - os2*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - allow_undefined_flag=unsupported - shrext_cmds=.dll - archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ - $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ - $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ - $ECHO EXPORTS >> $output_objdir/$libname.def~ - emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ - $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ - emximp -o $lib $output_objdir/$libname.def' - archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ - $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ - $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ - $ECHO EXPORTS >> $output_objdir/$libname.def~ - prefix_cmds="$SED"~ - if test EXPORTS = "`$SED 1q $export_symbols`"; then - prefix_cmds="$prefix_cmds -e 1d"; - fi~ - prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ - cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ - $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ - emximp -o $lib $output_objdir/$libname.def' - old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' - enable_shared_with_static_runtimes=yes - ;; - - osf3*) - if test yes = "$GCC"; then - allow_undefined_flag=' $wl-expect_unresolved $wl\*' - archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' - fi - archive_cmds_need_lc='no' - hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' - hardcode_libdir_separator=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test yes = "$GCC"; then - allow_undefined_flag=' $wl-expect_unresolved $wl\*' - archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' - hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' - archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' - - # Both c and cxx compiler support -rpath directly - hardcode_libdir_flag_spec='-rpath $libdir' - fi - archive_cmds_need_lc='no' - hardcode_libdir_separator=: - ;; - - solaris*) - no_undefined_flag=' -z defs' - if test yes = "$GCC"; then - wlarc='$wl' - archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - else - case `$CC -V 2>&1` in - *"Compilers 5.0"*) - wlarc='' - archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' - ;; - *) - wlarc='$wl' - archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - ;; - esac - fi - hardcode_libdir_flag_spec='-R$libdir' - hardcode_shlibpath_var=no - case $host_os in - solaris2.[0-5] | solaris2.[0-5].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands '-z linker_flag'. GCC discards it without '$wl', - # but is careful enough not to reorder. - # Supported since Solaris 2.6 (maybe 2.5.1?) - if test yes = "$GCC"; then - whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' - else - whole_archive_flag_spec='-z allextract$convenience -z defaultextract' - fi - ;; - esac - link_all_deplibs=yes - ;; - - sunos4*) - if test sequent = "$host_vendor"; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - hardcode_libdir_flag_spec='-L$libdir' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - sysv4) - case $host_vendor in - sni) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' - reload_cmds='$CC -r -o $output$reload_objs' - hardcode_direct=no - ;; - motorola) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var=no - ;; - - sysv4.3*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - export_dynamic_flag_spec='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ld_shlibs=yes - fi - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) - no_undefined_flag='$wl-z,text' - archive_cmds_need_lc=no - hardcode_shlibpath_var=no - runpath_var='LD_RUN_PATH' - - if test yes = "$GCC"; then - archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We CANNOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - no_undefined_flag='$wl-z,text' - allow_undefined_flag='$wl-z,nodefs' - archive_cmds_need_lc=no - hardcode_shlibpath_var=no - hardcode_libdir_flag_spec='$wl-R,$libdir' - hardcode_libdir_separator=':' - link_all_deplibs=yes - export_dynamic_flag_spec='$wl-Bexport' - runpath_var='LD_RUN_PATH' - - if test yes = "$GCC"; then - archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - uts4*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - *) - ld_shlibs=no - ;; - esac - - if test sni = "$host_vendor"; then - case $host in - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - export_dynamic_flag_spec='$wl-Blargedynsym' - ;; - esac - fi - fi - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 -printf "%s\n" "$ld_shlibs" >&6; } -test no = "$ld_shlibs" && can_build_shared=no - -with_gnu_ld=$with_gnu_ld - - - - - - - - - - - - - - - -# -# Do we need to explicitly link libc? -# -case "x$archive_cmds_need_lc" in -x|xyes) - # Assume -lc should be added - archive_cmds_need_lc=yes - - if test yes,yes = "$GCC,$enable_shared"; then - case $archive_cmds in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 -printf %s "checking whether -lc should be explicitly linked in... " >&6; } -if test ${lt_cv_archive_cmds_need_lc+y} -then : - printf %s "(cached) " >&6 -else $as_nop - $RM conftest* - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$lt_prog_compiler_wl - pic_flag=$lt_prog_compiler_pic - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$allow_undefined_flag - allow_undefined_flag= - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 - (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - then - lt_cv_archive_cmds_need_lc=no - else - lt_cv_archive_cmds_need_lc=yes - fi - allow_undefined_flag=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $RM conftest* - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 -printf "%s\n" "$lt_cv_archive_cmds_need_lc" >&6; } - archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc - ;; - esac - fi - ;; -esac - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 -printf %s "checking dynamic linker characteristics... " >&6; } - -if test yes = "$GCC"; then - case $host_os in - darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; - *) lt_awk_arg='/^libraries:/' ;; - esac - case $host_os in - mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; - *) lt_sed_strip_eq='s|=/|/|g' ;; - esac - lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` - case $lt_search_path_spec in - *\;*) - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` - ;; - *) - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` - ;; - esac - # Ok, now we have the path, separated by spaces, we can step through it - # and add multilib dir if necessary... - lt_tmp_lt_search_path_spec= - lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` - # ...but if some path component already ends with the multilib dir we assume - # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). - case "$lt_multi_os_dir; $lt_search_path_spec " in - "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) - lt_multi_os_dir= - ;; - esac - for lt_sys_path in $lt_search_path_spec; do - if test -d "$lt_sys_path$lt_multi_os_dir"; then - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" - elif test -n "$lt_multi_os_dir"; then - test -d "$lt_sys_path" && \ - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" - fi - done - lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' -BEGIN {RS = " "; FS = "/|\n";} { - lt_foo = ""; - lt_count = 0; - for (lt_i = NF; lt_i > 0; lt_i--) { - if ($lt_i != "" && $lt_i != ".") { - if ($lt_i == "..") { - lt_count++; - } else { - if (lt_count == 0) { - lt_foo = "/" $lt_i lt_foo; - } else { - lt_count--; - } - } - } - } - if (lt_foo != "") { lt_freq[lt_foo]++; } - if (lt_freq[lt_foo] == 1) { print lt_foo; } -}'` - # AWK program above erroneously prepends '/' to C:/dos/paths - # for these hosts. - case $host_os in - mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ - $SED 's|/\([A-Za-z]:\)|\1|g'` ;; - esac - sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=.so -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - - - -case $host_os in -aix3*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname$release$shared_ext$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='$libname$release$shared_ext$major' - ;; - -aix[4-9]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test ia64 = "$host_cpu"; then - # AIX 5 supports IA64 - library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line '#! .'. This would cause the generated library to - # depend on '.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[01] | aix4.[01].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # Using Import Files as archive members, it is possible to support - # filename-based versioning of shared library archives on AIX. While - # this would work for both with and without runtime linking, it will - # prevent static linking of such archives. So we do filename-based - # shared library versioning with .so extension only, which is used - # when both runtime linking and shared linking is enabled. - # Unfortunately, runtime linking may impact performance, so we do - # not want this to be the default eventually. Also, we use the - # versioned .so libs for executables only if there is the -brtl - # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. - # To allow for filename-based versioning support, we need to create - # libNAME.so.V as an archive file, containing: - # *) an Import File, referring to the versioned filename of the - # archive as well as the shared archive member, telling the - # bitwidth (32 or 64) of that shared object, and providing the - # list of exported symbols of that shared object, eventually - # decorated with the 'weak' keyword - # *) the shared object with the F_LOADONLY flag set, to really avoid - # it being seen by the linker. - # At run time we better use the real file rather than another symlink, - # but for link time we create the symlink libNAME.so -> libNAME.so.V - - case $with_aix_soname,$aix_use_runtimelinking in - # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - aix,yes) # traditional libtool - dynamic_linker='AIX unversionable lib.so' - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - ;; - aix,no) # traditional AIX only - dynamic_linker='AIX lib.a(lib.so.V)' - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='$libname$release.a $libname.a' - soname_spec='$libname$release$shared_ext$major' - ;; - svr4,*) # full svr4 only - dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" - library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' - # We do not specify a path in Import Files, so LIBPATH fires. - shlibpath_overrides_runpath=yes - ;; - *,yes) # both, prefer svr4 - dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" - library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' - # unpreferred sharedlib libNAME.a needs extra handling - postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' - postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' - # We do not specify a path in Import Files, so LIBPATH fires. - shlibpath_overrides_runpath=yes - ;; - *,no) # both, prefer aix - dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" - library_names_spec='$libname$release.a $libname.a' - soname_spec='$libname$release$shared_ext$major' - # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling - postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' - postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' - ;; - esac - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - case $host_cpu in - powerpc) - # Since July 2007 AmigaOS4 officially supports .so libraries. - # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - ;; - m68k) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - esac - ;; - -beos*) - library_names_spec='$libname$shared_ext' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi[45]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32* | cegcc*) - version_type=windows - shrext_cmds=.dll - need_version=no - need_lib_prefix=no - - case $GCC,$cc_basename in - yes,*) - # gcc - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \$file`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' - - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" - ;; - mingw* | cegcc*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' - ;; - esac - dynamic_linker='Win32 ld.exe' - ;; - - *,cl*) - # Native MSVC - libname_spec='$name' - soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' - library_names_spec='$libname.dll.lib' - - case $build_os in - mingw*) - sys_lib_search_path_spec= - lt_save_ifs=$IFS - IFS=';' - for lt_path in $LIB - do - IFS=$lt_save_ifs - # Let DOS variable expansion print the short 8.3 style file name. - lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` - sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" - done - IFS=$lt_save_ifs - # Convert to MSYS style. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` - ;; - cygwin*) - # Convert to unix form, then to dos form, then back to unix form - # but this time dos style (no spaces!) so that the unix form looks - # like /cygdrive/c/PROGRA~1:/cygdr... - sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` - sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` - sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - ;; - *) - sys_lib_search_path_spec=$LIB - if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then - # It is most probably a Windows format PATH. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - # FIXME: find the short name or the path components, as spaces are - # common. (e.g. "Program Files" -> "PROGRA~1") - ;; - esac - - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \$file`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - dynamic_linker='Win32 link.exe' - ;; - - *) - # Assume MSVC wrapper - library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' - dynamic_linker='Win32 ld.exe' - ;; - esac - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' - soname_spec='$libname$release$major$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' - - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd* | dragonfly*) - # DragonFly does not have aout. When/if they implement a new - # versioning mechanism, adjust this. - if test -x /usr/bin/objformat; then - objformat=`/usr/bin/objformat` - else - case $host_os in - freebsd[23].*) objformat=aout ;; - *) objformat=elf ;; - esac - fi - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2.*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[01]* | freebsdelf3.[01]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ - freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - *) # from 4.6 on, and DragonFly - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - esac - ;; - -haiku*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - dynamic_linker="$host_os runtime_loader" - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LIBRARY_PATH - shlibpath_overrides_runpath=no - sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case $host_cpu in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - if test 32 = "$HPUX_IA64_MODE"; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - sys_lib_dlsearch_path_spec=/usr/lib/hpux32 - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - sys_lib_dlsearch_path_spec=/usr/lib/hpux64 - fi - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555, ... - postinstall_cmds='chmod 555 $lib' - # or fails outright, so override atomically: - install_override_mode=555 - ;; - -interix[3-9]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test yes = "$lt_cv_prog_gnu_ld"; then - version_type=linux # correct to gnu/linux during the next big refactor - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='$libname$release$shared_ext$major' - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" - sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -linux*android*) - version_type=none # Android doesn't support versioned libraries. - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext' - soname_spec='$libname$release$shared_ext' - finish_cmds= - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - dynamic_linker='Android linker' - # Don't embed -rpath directories since the linker doesn't support them. - hardcode_libdir_flag_spec='-L$libdir' - ;; - -# This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - - # Some binutils ld are patched to set DT_RUNPATH - if test ${lt_cv_shlibpath_overrides_runpath+y} -then : - printf %s "(cached) " >&6 -else $as_nop - lt_cv_shlibpath_overrides_runpath=no - save_LDFLAGS=$LDFLAGS - save_libdir=$libdir - eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ - LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null -then : - lt_cv_shlibpath_overrides_runpath=yes -fi -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS=$save_LDFLAGS - libdir=$save_libdir - -fi - - shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath - - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Ideally, we could use ldconfig to report *all* directores which are - # searched for libraries, however this is still not possible. Aside from not - # being certain /sbin/ldconfig is available, command - # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, - # even though it is searched at run-time. Try to do the best guess by - # appending ld.so.conf contents (and includes) to the search path. - if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsdelf*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='NetBSD ld.elf_so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -*nto* | *qnx*) - version_type=qnx - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='ldqnx.so' - ;; - -openbsd* | bitrig*) - version_type=sunos - sys_lib_dlsearch_path_spec=/usr/lib - need_lib_prefix=no - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then - need_version=no - else - need_version=yes - fi - library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -os2*) - libname_spec='$name' - version_type=windows - shrext_cmds=.dll - need_version=no - need_lib_prefix=no - # OS/2 can only load a DLL with a base name of 8 characters or less. - soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; - v=$($ECHO $release$versuffix | tr -d .-); - n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); - $ECHO $n$v`$shared_ext' - library_names_spec='${libname}_dll.$libext' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=BEGINLIBPATH - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - postinstall_cmds='base_file=`basename \$file`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='$libname$release$shared_ext$major' - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - -rdos*) - dynamic_linker=no - ;; - -solaris*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test yes = "$with_gnu_ld"; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.3*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec; then - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' - soname_spec='$libname$shared_ext.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - version_type=sco - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - if test yes = "$with_gnu_ld"; then - sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' - else - sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' - case $host_os in - sco3.2v5*) - sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" - ;; - esac - fi - sys_lib_dlsearch_path_spec='/usr/lib' - ;; - -tpf*) - # TPF is a cross-target only. Preferred cross-host = GNU/Linux. - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -uts4*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' - soname_spec='$libname$release$shared_ext$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 -printf "%s\n" "$dynamic_linker" >&6; } -test no = "$dynamic_linker" && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test yes = "$GCC"; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then - sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec -fi - -if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then - sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec -fi - -# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... -configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec - -# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code -func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" - -# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool -configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 -printf %s "checking how to hardcode library paths into programs... " >&6; } -hardcode_action= -if test -n "$hardcode_libdir_flag_spec" || - test -n "$runpath_var" || - test yes = "$hardcode_automatic"; then - - # We can hardcode non-existent directories. - if test no != "$hardcode_direct" && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && - test no != "$hardcode_minus_L"; then - # Linking always hardcodes the temporary library directory. - hardcode_action=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - hardcode_action=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - hardcode_action=unsupported -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 -printf "%s\n" "$hardcode_action" >&6; } - -if test relink = "$hardcode_action" || - test yes = "$inherit_rpath"; then - # Fast installation is not supported - enable_fast_install=no -elif test yes = "$shlibpath_overrides_runpath" || - test no = "$enable_shared"; then - # Fast installation is not necessary - enable_fast_install=needless -fi - - - - - - - if test yes != "$enable_dlopen"; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen=load_add_on - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32* | cegcc*) - lt_cv_dlopen=LoadLibrary - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen=dlopen - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 -printf %s "checking for dlopen in -ldl... " >&6; } -if test ${ac_cv_lib_dl_dlopen+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main (void) -{ -return dlopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_dl_dlopen=yes -else $as_nop - ac_cv_lib_dl_dlopen=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 -printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes -then : - lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl -else $as_nop - - lt_cv_dlopen=dyld - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - -fi - - ;; - - tpf*) - # Don't try to run any link tests for TPF. We know it's impossible - # because TPF is a cross-compiler, and we know how we open DSOs. - lt_cv_dlopen=dlopen - lt_cv_dlopen_libs= - lt_cv_dlopen_self=no - ;; - - *) - ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" -if test "x$ac_cv_func_shl_load" = xyes -then : - lt_cv_dlopen=shl_load -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 -printf %s "checking for shl_load in -ldld... " >&6; } -if test ${ac_cv_lib_dld_shl_load+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char shl_load (); -int -main (void) -{ -return shl_load (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_dld_shl_load=yes -else $as_nop - ac_cv_lib_dld_shl_load=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 -printf "%s\n" "$ac_cv_lib_dld_shl_load" >&6; } -if test "x$ac_cv_lib_dld_shl_load" = xyes -then : - lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld -else $as_nop - ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" -if test "x$ac_cv_func_dlopen" = xyes -then : - lt_cv_dlopen=dlopen -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 -printf %s "checking for dlopen in -ldl... " >&6; } -if test ${ac_cv_lib_dl_dlopen+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main (void) -{ -return dlopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_dl_dlopen=yes -else $as_nop - ac_cv_lib_dl_dlopen=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 -printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes -then : - lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 -printf %s "checking for dlopen in -lsvld... " >&6; } -if test ${ac_cv_lib_svld_dlopen+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsvld $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char dlopen (); -int -main (void) -{ -return dlopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_svld_dlopen=yes -else $as_nop - ac_cv_lib_svld_dlopen=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 -printf "%s\n" "$ac_cv_lib_svld_dlopen" >&6; } -if test "x$ac_cv_lib_svld_dlopen" = xyes -then : - lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 -printf %s "checking for dld_link in -ldld... " >&6; } -if test ${ac_cv_lib_dld_dld_link+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char dld_link (); -int -main (void) -{ -return dld_link (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_dld_dld_link=yes -else $as_nop - ac_cv_lib_dld_dld_link=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 -printf "%s\n" "$ac_cv_lib_dld_dld_link" >&6; } -if test "x$ac_cv_lib_dld_dld_link" = xyes -then : - lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld -fi - - -fi - - -fi - - -fi - - -fi - - -fi - - ;; - esac - - if test no = "$lt_cv_dlopen"; then - enable_dlopen=no - else - enable_dlopen=yes - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS=$CPPFLAGS - test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS=$LDFLAGS - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS=$LIBS - LIBS="$lt_cv_dlopen_libs $LIBS" - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 -printf %s "checking whether a program can dlopen itself... " >&6; } -if test ${lt_cv_dlopen_self+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test yes = "$cross_compiling"; then : - lt_cv_dlopen_self=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF -#line $LINENO "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -/* When -fvisibility=hidden is used, assume the code has been annotated - correspondingly for the symbols needed. */ -#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -int fnord () __attribute__((visibility("default"))); -#endif - -int fnord () { return 42; } -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else - { - if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - else puts (dlerror ()); - } - /* dlclose (self); */ - } - else - puts (dlerror ()); - - return status; -} -_LT_EOF - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 - (eval $ac_link) 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then - (./conftest; exit; ) >&5 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; - x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self=no - fi -fi -rm -fr conftest* - - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 -printf "%s\n" "$lt_cv_dlopen_self" >&6; } - - if test yes = "$lt_cv_dlopen_self"; then - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 -printf %s "checking whether a statically linked program can dlopen itself... " >&6; } -if test ${lt_cv_dlopen_self_static+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test yes = "$cross_compiling"; then : - lt_cv_dlopen_self_static=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF -#line $LINENO "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -/* When -fvisibility=hidden is used, assume the code has been annotated - correspondingly for the symbols needed. */ -#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -int fnord () __attribute__((visibility("default"))); -#endif - -int fnord () { return 42; } -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else - { - if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - else puts (dlerror ()); - } - /* dlclose (self); */ - } - else - puts (dlerror ()); - - return status; -} -_LT_EOF - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 - (eval $ac_link) 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then - (./conftest; exit; ) >&5 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self_static=no - fi -fi -rm -fr conftest* - - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 -printf "%s\n" "$lt_cv_dlopen_self_static" >&6; } - fi - - CPPFLAGS=$save_CPPFLAGS - LDFLAGS=$save_LDFLAGS - LIBS=$save_LIBS - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi - - - - - - - - - - - - - - - - - -striplib= -old_striplib= -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 -printf %s "checking whether stripping libraries is possible... " >&6; } -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP"; then - striplib="$STRIP -x" - old_striplib="$STRIP -S" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } - fi - ;; - *) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } - ;; - esac -fi - - - - - - - - - - - - - # Report what library types will actually be built - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 -printf %s "checking if libtool supports shared libraries... " >&6; } - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 -printf "%s\n" "$can_build_shared" >&6; } - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 -printf %s "checking whether to build shared libraries... " >&6; } - test no = "$can_build_shared" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test yes = "$enable_shared" && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - - aix[4-9]*) - if test ia64 != "$host_cpu"; then - case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in - yes,aix,yes) ;; # shared object as lib.so file only - yes,svr4,*) ;; # shared object as lib.so archive member only - yes,*) enable_static=no ;; # shared object in lib.a archive as well - esac - fi - ;; - esac - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 -printf "%s\n" "$enable_shared" >&6; } - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 -printf %s "checking whether to build static libraries... " >&6; } - # Make sure either enable_shared or enable_static is yes. - test yes = "$enable_shared" || enable_static=yes - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 -printf "%s\n" "$enable_static" >&6; } - - - - -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -CC=$lt_save_CC - - - - - - - - - - - - - - - - ac_config_commands="$ac_config_commands libtool" - - - - -# Only expand once: - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_STRIP+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -printf "%s\n" "$STRIP" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_STRIP+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_STRIP="strip" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -printf "%s\n" "$ac_ct_STRIP" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - - - -# -# Options for building bsdtar. -# -# Default is to build bsdtar, but allow people to override that. -# -# Check whether --enable-bsdtar was given. -if test ${enable_bsdtar+y} -then : - enableval=$enable_bsdtar; -else $as_nop - enable_bsdtar=yes -fi - - -case "$enable_bsdtar" in -yes) - if test "$enable_static" = "no"; then - static_bsdtar=no - else - static_bsdtar=yes - fi - build_bsdtar=yes - ;; -dynamic|shared) - if test "$enable_shared" = "no"; then - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "Shared linking of bsdtar requires shared libarchive -See \`config.log' for more details" "$LINENO" 5; } - fi - build_bsdtar=yes - static_bsdtar=no - ;; -static) - build_bsdtar=yes - static_bsdtar=yes - ;; -no) - build_bsdtar=no - static_bsdtar=no - ;; -*) - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "Unsupported value for --enable-bsdtar -See \`config.log' for more details" "$LINENO" 5; } - ;; -esac - - if test "$build_bsdtar" = yes ; then - BUILD_BSDTAR_TRUE= - BUILD_BSDTAR_FALSE='#' -else - BUILD_BSDTAR_TRUE='#' - BUILD_BSDTAR_FALSE= -fi - - if test "$static_bsdtar" = yes ; then - STATIC_BSDTAR_TRUE= - STATIC_BSDTAR_FALSE='#' -else - STATIC_BSDTAR_TRUE='#' - STATIC_BSDTAR_FALSE= -fi - - -# -# Options for building bsdcat. -# -# Default is to build bsdcat, but allow people to override that. -# -# Check whether --enable-bsdcat was given. -if test ${enable_bsdcat+y} -then : - enableval=$enable_bsdcat; -else $as_nop - enable_bsdcat=yes -fi - - -case "$enable_bsdcat" in -yes) - if test "$enable_static" = "no"; then - static_bsdcat=no - else - static_bsdcat=yes - fi - build_bsdcat=yes - ;; -dynamic|shared) - if test "$enable_shared" = "no"; then - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "Shared linking of bsdcat requires shared libarchive -See \`config.log' for more details" "$LINENO" 5; } - fi - build_bsdcat=yes - static_bsdcat=no - ;; -static) - build_bsdcat=yes - static_bsdcat=yes - ;; -no) - build_bsdcat=no - static_bsdcat=no - ;; -*) - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "Unsupported value for --enable-bsdcat -See \`config.log' for more details" "$LINENO" 5; } - ;; -esac - - if test "$build_bsdcat" = yes ; then - BUILD_BSDCAT_TRUE= - BUILD_BSDCAT_FALSE='#' -else - BUILD_BSDCAT_TRUE='#' - BUILD_BSDCAT_FALSE= -fi - - if test "$static_bsdcat" = yes ; then - STATIC_BSDCAT_TRUE= - STATIC_BSDCAT_FALSE='#' -else - STATIC_BSDCAT_TRUE='#' - STATIC_BSDCAT_FALSE= -fi - - -# -# Options for building bsdcpio. -# -# Default is not to build bsdcpio, but that can be overridden. -# -# Check whether --enable-bsdcpio was given. -if test ${enable_bsdcpio+y} -then : - enableval=$enable_bsdcpio; -else $as_nop - enable_bsdcpio=yes -fi - - -case "$enable_bsdcpio" in -yes) - if test "$enable_static" = "no"; then - static_bsdcpio=no - else - static_bsdcpio=yes - fi - build_bsdcpio=yes - ;; -dynamic|shared) - if test "$enabled_shared" = "no"; then - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "Shared linking of bsdcpio requires shared libarchive -See \`config.log' for more details" "$LINENO" 5; } - fi - build_bsdcpio=yes - ;; -static) - build_bsdcpio=yes - static_bsdcpio=yes - ;; -no) - build_bsdcpio=no - static_bsdcpio=no - ;; -*) - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "Unsupported value for --enable-bsdcpio -See \`config.log' for more details" "$LINENO" 5; } - ;; -esac - - if test "$build_bsdcpio" = yes ; then - BUILD_BSDCPIO_TRUE= - BUILD_BSDCPIO_FALSE='#' -else - BUILD_BSDCPIO_TRUE='#' - BUILD_BSDCPIO_FALSE= -fi - - if test "$static_bsdcpio" = yes ; then - STATIC_BSDCPIO_TRUE= - STATIC_BSDCPIO_FALSE='#' -else - STATIC_BSDCPIO_TRUE='#' - STATIC_BSDCPIO_FALSE= -fi - - -# Set up defines needed before including any headers -case $host in - *mingw* | *cygwin* | *msys* ) - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef _WIN32_WINNT - # error _WIN32_WINNT already defined - #endif - -int -main (void) -{ -; - ; - return 0; -} - -_ACEOF -if ac_fn_c_try_cpp "$LINENO" -then : - - -printf "%s\n" "#define _WIN32_WINNT 0x0502" >>confdefs.h - - -printf "%s\n" "#define NTDDI_VERSION 0x05020000" >>confdefs.h - - -fi -rm -f conftest.err conftest.i conftest.$ac_ext - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef WINVER - # error WINVER already defined - #endif - -int -main (void) -{ -; - ; - return 0; -} - -_ACEOF -if ac_fn_c_try_cpp "$LINENO" -then : - - -printf "%s\n" "#define WINVER 0x0502" >>confdefs.h - - -fi -rm -f conftest.err conftest.i conftest.$ac_ext - ;; -esac - -# -# Options for building bsdunzip. -# -# Default is to build bsdunzip, but allow people to override that. -# Bsdunzip has not yet been ported for Windows -# -case "$host_os" in - *mingw* | *msys*) - enable_bsdunzip=no - ;; - *) - # Check whether --enable-bsdunzip was given. -if test ${enable_bsdunzip+y} -then : - enableval=$enable_bsdunzip; -else $as_nop - enable_bsdunzip=yes -fi - - ;; -esac - -case "$enable_bsdunzip" in -yes) - if test "$enable_static" = "no"; then - static_bsdunzip=no - else - static_bsdunzip=yes - fi - build_bsdunzip=yes - ;; -dynamic|shared) - if test "$enable_shared" = "no"; then - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "Shared linking of bsdunzip requires shared libarchive -See \`config.log' for more details" "$LINENO" 5; } - fi - build_bsdunzip=yes - static_bsdunzip=no - ;; -static) - build_bsdunzip=yes - static_bsdunzip=yes - ;; -no) - build_bsdunzip=no - static_bsdunzip=no - ;; -*) - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "Unsupported value for --enable-bsdunzip -See \`config.log' for more details" "$LINENO" 5; } - ;; -esac - - if test "$build_bsdunzip" = yes ; then - BUILD_BSDUNZIP_TRUE= - BUILD_BSDUNZIP_FALSE='#' -else - BUILD_BSDUNZIP_TRUE='#' - BUILD_BSDUNZIP_FALSE= -fi - - if test "$static_bsdunzip" = yes ; then - STATIC_BSDUNZIP_TRUE= - STATIC_BSDUNZIP_FALSE='#' -else - STATIC_BSDUNZIP_TRUE='#' - STATIC_BSDUNZIP_FALSE= -fi - - -# Checks for header files. -ac_header_dirent=no -for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do - as_ac_Header=`printf "%s\n" "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5 -printf %s "checking for $ac_hdr that defines DIR... " >&6; } -if eval test \${$as_ac_Header+y} -then : - printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include <$ac_hdr> - -int -main (void) -{ -if ((DIR *) 0) -return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - eval "$as_ac_Header=yes" -else $as_nop - eval "$as_ac_Header=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -fi -eval ac_res=\$$as_ac_Header - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -printf "%s\n" "$ac_res" >&6; } -if eval test \"x\$"$as_ac_Header"\" = x"yes" -then : - cat >>confdefs.h <<_ACEOF -#define `printf "%s\n" "HAVE_$ac_hdr" | $as_tr_cpp` 1 -_ACEOF - -ac_header_dirent=$ac_hdr; break -fi - -done -# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. -if test $ac_header_dirent = dirent.h; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 -printf %s "checking for library containing opendir... " >&6; } -if test ${ac_cv_search_opendir+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char opendir (); -int -main (void) -{ -return opendir (); - ; - return 0; -} -_ACEOF -for ac_lib in '' dir -do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO" -then : - ac_cv_search_opendir=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext - if test ${ac_cv_search_opendir+y} -then : - break -fi -done -if test ${ac_cv_search_opendir+y} -then : - -else $as_nop - ac_cv_search_opendir=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 -printf "%s\n" "$ac_cv_search_opendir" >&6; } -ac_res=$ac_cv_search_opendir -if test "$ac_res" != no -then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 -printf %s "checking for library containing opendir... " >&6; } -if test ${ac_cv_search_opendir+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char opendir (); -int -main (void) -{ -return opendir (); - ; - return 0; -} -_ACEOF -for ac_lib in '' x -do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO" -then : - ac_cv_search_opendir=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext - if test ${ac_cv_search_opendir+y} -then : - break -fi -done -if test ${ac_cv_search_opendir+y} -then : - -else $as_nop - ac_cv_search_opendir=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 -printf "%s\n" "$ac_cv_search_opendir" >&6; } -ac_res=$ac_cv_search_opendir -if test "$ac_res" != no -then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - -fi - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5 -printf %s "checking for sys/wait.h that is POSIX.1 compatible... " >&6; } -if test ${ac_cv_header_sys_wait_h+y} -then : - printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#ifndef WEXITSTATUS -# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) -#endif -#ifndef WIFEXITED -# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) -#endif - -int -main (void) -{ - int s; - wait (&s); - s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - ac_cv_header_sys_wait_h=yes -else $as_nop - ac_cv_header_sys_wait_h=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5 -printf "%s\n" "$ac_cv_header_sys_wait_h" >&6; } -if test $ac_cv_header_sys_wait_h = yes; then - -printf "%s\n" "#define HAVE_SYS_WAIT_H 1" >>confdefs.h - -fi - -ac_fn_c_check_header_compile "$LINENO" "acl/libacl.h" "ac_cv_header_acl_libacl_h" "$ac_includes_default" -if test "x$ac_cv_header_acl_libacl_h" = xyes -then : - printf "%s\n" "#define HAVE_ACL_LIBACL_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "attr/xattr.h" "ac_cv_header_attr_xattr_h" "$ac_includes_default" -if test "x$ac_cv_header_attr_xattr_h" = xyes -then : - printf "%s\n" "#define HAVE_ATTR_XATTR_H 1" >>confdefs.h - -fi - -ac_fn_c_check_header_compile "$LINENO" "copyfile.h" "ac_cv_header_copyfile_h" "$ac_includes_default" -if test "x$ac_cv_header_copyfile_h" = xyes -then : - printf "%s\n" "#define HAVE_COPYFILE_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "ctype.h" "ac_cv_header_ctype_h" "$ac_includes_default" -if test "x$ac_cv_header_ctype_h" = xyes -then : - printf "%s\n" "#define HAVE_CTYPE_H 1" >>confdefs.h - -fi - -ac_fn_c_check_header_compile "$LINENO" "errno.h" "ac_cv_header_errno_h" "$ac_includes_default" -if test "x$ac_cv_header_errno_h" = xyes -then : - printf "%s\n" "#define HAVE_ERRNO_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "ext2fs/ext2_fs.h" "ac_cv_header_ext2fs_ext2_fs_h" "$ac_includes_default" -if test "x$ac_cv_header_ext2fs_ext2_fs_h" = xyes -then : - printf "%s\n" "#define HAVE_EXT2FS_EXT2_FS_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "fcntl.h" "ac_cv_header_fcntl_h" "$ac_includes_default" -if test "x$ac_cv_header_fcntl_h" = xyes -then : - printf "%s\n" "#define HAVE_FCNTL_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "fnmatch.h" "ac_cv_header_fnmatch_h" "$ac_includes_default" -if test "x$ac_cv_header_fnmatch_h" = xyes -then : - printf "%s\n" "#define HAVE_FNMATCH_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "grp.h" "ac_cv_header_grp_h" "$ac_includes_default" -if test "x$ac_cv_header_grp_h" = xyes -then : - printf "%s\n" "#define HAVE_GRP_H 1" >>confdefs.h - -fi - - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether EXT2_IOC_GETFLAGS is usable" >&5 -printf %s "checking whether EXT2_IOC_GETFLAGS is usable... " >&6; } -if test ${ac_cv_have_decl_EXT2_IOC_GETFLAGS+y} -then : - printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -int -main (void) -{ -int x = EXT2_IOC_GETFLAGS - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - ac_cv_have_decl_EXT2_IOC_GETFLAGS=yes -else $as_nop - ac_cv_have_decl_EXT2_IOC_GETFLAGS=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_decl_EXT2_IOC_GETFLAGS" >&5 -printf "%s\n" "$ac_cv_have_decl_EXT2_IOC_GETFLAGS" >&6; } - -if test "x$ac_cv_have_decl_EXT2_IOC_GETFLAGS" = xyes -then : - -printf "%s\n" "#define HAVE_WORKING_EXT2_IOC_GETFLAGS 1" >>confdefs.h - -fi - -ac_fn_c_check_header_compile "$LINENO" "inttypes.h" "ac_cv_header_inttypes_h" "$ac_includes_default" -if test "x$ac_cv_header_inttypes_h" = xyes -then : - printf "%s\n" "#define HAVE_INTTYPES_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "io.h" "ac_cv_header_io_h" "$ac_includes_default" -if test "x$ac_cv_header_io_h" = xyes -then : - printf "%s\n" "#define HAVE_IO_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "langinfo.h" "ac_cv_header_langinfo_h" "$ac_includes_default" -if test "x$ac_cv_header_langinfo_h" = xyes -then : - printf "%s\n" "#define HAVE_LANGINFO_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "limits.h" "ac_cv_header_limits_h" "$ac_includes_default" -if test "x$ac_cv_header_limits_h" = xyes -then : - printf "%s\n" "#define HAVE_LIMITS_H 1" >>confdefs.h - -fi - -ac_fn_c_check_header_compile "$LINENO" "linux/fiemap.h" "ac_cv_header_linux_fiemap_h" "$ac_includes_default" -if test "x$ac_cv_header_linux_fiemap_h" = xyes -then : - printf "%s\n" "#define HAVE_LINUX_FIEMAP_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "linux/fs.h" "ac_cv_header_linux_fs_h" "$ac_includes_default" -if test "x$ac_cv_header_linux_fs_h" = xyes -then : - printf "%s\n" "#define HAVE_LINUX_FS_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "linux/magic.h" "ac_cv_header_linux_magic_h" "$ac_includes_default" -if test "x$ac_cv_header_linux_magic_h" = xyes -then : - printf "%s\n" "#define HAVE_LINUX_MAGIC_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "linux/types.h" "ac_cv_header_linux_types_h" "$ac_includes_default" -if test "x$ac_cv_header_linux_types_h" = xyes -then : - printf "%s\n" "#define HAVE_LINUX_TYPES_H 1" >>confdefs.h - -fi - - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether FS_IOC_GETFLAGS is usable" >&5 -printf %s "checking whether FS_IOC_GETFLAGS is usable... " >&6; } -if test ${ac_cv_have_decl_FS_IOC_GETFLAGS+y} -then : - printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -int -main (void) -{ -int x = FS_IOC_GETFLAGS - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - ac_cv_have_decl_FS_IOC_GETFLAGS=yes -else $as_nop - ac_cv_have_decl_FS_IOC_GETFLAGS=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_decl_FS_IOC_GETFLAGS" >&5 -printf "%s\n" "$ac_cv_have_decl_FS_IOC_GETFLAGS" >&6; } - -if test "x$ac_cv_have_decl_FS_IOC_GETFLAGS" = xyes -then : - -printf "%s\n" "#define HAVE_WORKING_FS_IOC_GETFLAGS 1" >>confdefs.h - -fi - -ac_fn_c_check_header_compile "$LINENO" "locale.h" "ac_cv_header_locale_h" "$ac_includes_default" -if test "x$ac_cv_header_locale_h" = xyes -then : - printf "%s\n" "#define HAVE_LOCALE_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "membership.h" "ac_cv_header_membership_h" "$ac_includes_default" -if test "x$ac_cv_header_membership_h" = xyes -then : - printf "%s\n" "#define HAVE_MEMBERSHIP_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "paths.h" "ac_cv_header_paths_h" "$ac_includes_default" -if test "x$ac_cv_header_paths_h" = xyes -then : - printf "%s\n" "#define HAVE_PATHS_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "poll.h" "ac_cv_header_poll_h" "$ac_includes_default" -if test "x$ac_cv_header_poll_h" = xyes -then : - printf "%s\n" "#define HAVE_POLL_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default" -if test "x$ac_cv_header_pthread_h" = xyes -then : - printf "%s\n" "#define HAVE_PTHREAD_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "pwd.h" "ac_cv_header_pwd_h" "$ac_includes_default" -if test "x$ac_cv_header_pwd_h" = xyes -then : - printf "%s\n" "#define HAVE_PWD_H 1" >>confdefs.h - -fi - -ac_fn_c_check_header_compile "$LINENO" "readpassphrase.h" "ac_cv_header_readpassphrase_h" "$ac_includes_default" -if test "x$ac_cv_header_readpassphrase_h" = xyes -then : - printf "%s\n" "#define HAVE_READPASSPHRASE_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "signal.h" "ac_cv_header_signal_h" "$ac_includes_default" -if test "x$ac_cv_header_signal_h" = xyes -then : - printf "%s\n" "#define HAVE_SIGNAL_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "spawn.h" "ac_cv_header_spawn_h" "$ac_includes_default" -if test "x$ac_cv_header_spawn_h" = xyes -then : - printf "%s\n" "#define HAVE_SPAWN_H 1" >>confdefs.h - -fi - -ac_fn_c_check_header_compile "$LINENO" "stdarg.h" "ac_cv_header_stdarg_h" "$ac_includes_default" -if test "x$ac_cv_header_stdarg_h" = xyes -then : - printf "%s\n" "#define HAVE_STDARG_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "stdint.h" "ac_cv_header_stdint_h" "$ac_includes_default" -if test "x$ac_cv_header_stdint_h" = xyes -then : - printf "%s\n" "#define HAVE_STDINT_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" -if test "x$ac_cv_header_stdlib_h" = xyes -then : - printf "%s\n" "#define HAVE_STDLIB_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "string.h" "ac_cv_header_string_h" "$ac_includes_default" -if test "x$ac_cv_header_string_h" = xyes -then : - printf "%s\n" "#define HAVE_STRING_H 1" >>confdefs.h - -fi - -ac_fn_c_check_header_compile "$LINENO" "sys/acl.h" "ac_cv_header_sys_acl_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_acl_h" = xyes -then : - printf "%s\n" "#define HAVE_SYS_ACL_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "sys/cdefs.h" "ac_cv_header_sys_cdefs_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_cdefs_h" = xyes -then : - printf "%s\n" "#define HAVE_SYS_CDEFS_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "sys/ea.h" "ac_cv_header_sys_ea_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_ea_h" = xyes -then : - printf "%s\n" "#define HAVE_SYS_EA_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "sys/extattr.h" "ac_cv_header_sys_extattr_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_extattr_h" = xyes -then : - printf "%s\n" "#define HAVE_SYS_EXTATTR_H 1" >>confdefs.h - -fi - -ac_fn_c_check_header_compile "$LINENO" "sys/ioctl.h" "ac_cv_header_sys_ioctl_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_ioctl_h" = xyes -then : - printf "%s\n" "#define HAVE_SYS_IOCTL_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "sys/mkdev.h" "ac_cv_header_sys_mkdev_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_mkdev_h" = xyes -then : - printf "%s\n" "#define HAVE_SYS_MKDEV_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "sys/mount.h" "ac_cv_header_sys_mount_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_mount_h" = xyes -then : - printf "%s\n" "#define HAVE_SYS_MOUNT_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "sys/queue.h" "ac_cv_header_sys_queue_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_queue_h" = xyes -then : - printf "%s\n" "#define HAVE_SYS_QUEUE_H 1" >>confdefs.h - -fi - -ac_fn_c_check_header_compile "$LINENO" "sys/param.h" "ac_cv_header_sys_param_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_param_h" = xyes -then : - printf "%s\n" "#define HAVE_SYS_PARAM_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "sys/poll.h" "ac_cv_header_sys_poll_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_poll_h" = xyes -then : - printf "%s\n" "#define HAVE_SYS_POLL_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "sys/richacl.h" "ac_cv_header_sys_richacl_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_richacl_h" = xyes -then : - printf "%s\n" "#define HAVE_SYS_RICHACL_H 1" >>confdefs.h - -fi - -ac_fn_c_check_header_compile "$LINENO" "sys/select.h" "ac_cv_header_sys_select_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_select_h" = xyes -then : - printf "%s\n" "#define HAVE_SYS_SELECT_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "sys/statfs.h" "ac_cv_header_sys_statfs_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_statfs_h" = xyes -then : - printf "%s\n" "#define HAVE_SYS_STATFS_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "sys/statvfs.h" "ac_cv_header_sys_statvfs_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_statvfs_h" = xyes -then : - printf "%s\n" "#define HAVE_SYS_STATVFS_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "sys/sysmacros.h" "ac_cv_header_sys_sysmacros_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_sysmacros_h" = xyes -then : - printf "%s\n" "#define HAVE_SYS_SYSMACROS_H 1" >>confdefs.h - -fi - -ac_fn_c_check_header_compile "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_time_h" = xyes -then : - printf "%s\n" "#define HAVE_SYS_TIME_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "sys/utime.h" "ac_cv_header_sys_utime_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_utime_h" = xyes -then : - printf "%s\n" "#define HAVE_SYS_UTIME_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "sys/utsname.h" "ac_cv_header_sys_utsname_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_utsname_h" = xyes -then : - printf "%s\n" "#define HAVE_SYS_UTSNAME_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "sys/vfs.h" "ac_cv_header_sys_vfs_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_vfs_h" = xyes -then : - printf "%s\n" "#define HAVE_SYS_VFS_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "sys/xattr.h" "ac_cv_header_sys_xattr_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_xattr_h" = xyes -then : - printf "%s\n" "#define HAVE_SYS_XATTR_H 1" >>confdefs.h - -fi - -ac_fn_c_check_header_compile "$LINENO" "time.h" "ac_cv_header_time_h" "$ac_includes_default" -if test "x$ac_cv_header_time_h" = xyes -then : - printf "%s\n" "#define HAVE_TIME_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default" -if test "x$ac_cv_header_unistd_h" = xyes -then : - printf "%s\n" "#define HAVE_UNISTD_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "utime.h" "ac_cv_header_utime_h" "$ac_includes_default" -if test "x$ac_cv_header_utime_h" = xyes -then : - printf "%s\n" "#define HAVE_UTIME_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "wchar.h" "ac_cv_header_wchar_h" "$ac_includes_default" -if test "x$ac_cv_header_wchar_h" = xyes -then : - printf "%s\n" "#define HAVE_WCHAR_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "wctype.h" "ac_cv_header_wctype_h" "$ac_includes_default" -if test "x$ac_cv_header_wctype_h" = xyes -then : - printf "%s\n" "#define HAVE_WCTYPE_H 1" >>confdefs.h - -fi - -ac_fn_c_check_header_compile "$LINENO" "windows.h" "ac_cv_header_windows_h" "$ac_includes_default" -if test "x$ac_cv_header_windows_h" = xyes -then : - printf "%s\n" "#define HAVE_WINDOWS_H 1" >>confdefs.h - -fi - -# check windows.h first; the other headers require it. -ac_fn_c_check_header_compile "$LINENO" "wincrypt.h" "ac_cv_header_wincrypt_h" "#ifdef HAVE_WINDOWS_H -# include -#endif - -" -if test "x$ac_cv_header_wincrypt_h" = xyes -then : - printf "%s\n" "#define HAVE_WINCRYPT_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "winioctl.h" "ac_cv_header_winioctl_h" "#ifdef HAVE_WINDOWS_H -# include -#endif - -" -if test "x$ac_cv_header_winioctl_h" = xyes -then : - printf "%s\n" "#define HAVE_WINIOCTL_H 1" >>confdefs.h - -fi - - -# Checks for libraries. - -# Check whether --with-zlib was given. -if test ${with_zlib+y} -then : - withval=$with_zlib; -fi - - -if test "x$with_zlib" != "xno"; then - ac_fn_c_check_header_compile "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" -if test "x$ac_cv_header_zlib_h" = xyes -then : - printf "%s\n" "#define HAVE_ZLIB_H 1" >>confdefs.h - -fi - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inflate in -lz" >&5 -printf %s "checking for inflate in -lz... " >&6; } -if test ${ac_cv_lib_z_inflate+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-lz $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char inflate (); -int -main (void) -{ -return inflate (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_z_inflate=yes -else $as_nop - ac_cv_lib_z_inflate=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_inflate" >&5 -printf "%s\n" "$ac_cv_lib_z_inflate" >&6; } -if test "x$ac_cv_lib_z_inflate" = xyes -then : - printf "%s\n" "#define HAVE_LIBZ 1" >>confdefs.h - - LIBS="-lz $LIBS" - -fi - -fi - - -# Check whether --with-bz2lib was given. -if test ${with_bz2lib+y} -then : - withval=$with_bz2lib; -fi - - -if test "x$with_bz2lib" != "xno"; then - ac_fn_c_check_header_compile "$LINENO" "bzlib.h" "ac_cv_header_bzlib_h" "$ac_includes_default" -if test "x$ac_cv_header_bzlib_h" = xyes -then : - printf "%s\n" "#define HAVE_BZLIB_H 1" >>confdefs.h - -fi - - case "$host_os" in - *mingw* | *cygwin* | *msys*) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BZ2_bzDecompressInit in -lbz2" >&5 -printf %s "checking for BZ2_bzDecompressInit in -lbz2... " >&6; } - old_LIBS="$LIBS" - LIBS="-lbz2 $LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - int main() { return BZ2_bzDecompressInit(NULL, 0, 0); } -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_bz2_BZ2_bzDecompressInit=yes -else $as_nop - ac_cv_lib_bz2_BZ2_bzDecompressInit=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - LIBS="$old_LIBS" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bz2_BZ2_bzDecompressInit" >&5 -printf "%s\n" "$ac_cv_lib_bz2_BZ2_bzDecompressInit" >&6; } - if test "x$ac_cv_lib_bz2_BZ2_bzDecompressInit" = xyes; then - -printf "%s\n" "#define HAVE_LIBBZ2 1" >>confdefs.h - - LIBS="-lbz2 $LIBS" - fi - ;; - *) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BZ2_bzDecompressInit in -lbz2" >&5 -printf %s "checking for BZ2_bzDecompressInit in -lbz2... " >&6; } -if test ${ac_cv_lib_bz2_BZ2_bzDecompressInit+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-lbz2 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char BZ2_bzDecompressInit (); -int -main (void) -{ -return BZ2_bzDecompressInit (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_bz2_BZ2_bzDecompressInit=yes -else $as_nop - ac_cv_lib_bz2_BZ2_bzDecompressInit=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bz2_BZ2_bzDecompressInit" >&5 -printf "%s\n" "$ac_cv_lib_bz2_BZ2_bzDecompressInit" >&6; } -if test "x$ac_cv_lib_bz2_BZ2_bzDecompressInit" = xyes -then : - printf "%s\n" "#define HAVE_LIBBZ2 1" >>confdefs.h - - LIBS="-lbz2 $LIBS" - -fi - - ;; - esac -fi - - -# Check whether --with-libb2 was given. -if test ${with_libb2+y} -then : - withval=$with_libb2; -fi - - -if test "x$with_libb2" != "xno"; then - ac_fn_c_check_header_compile "$LINENO" "blake2.h" "ac_cv_header_blake2_h" "$ac_includes_default" -if test "x$ac_cv_header_blake2_h" = xyes -then : - printf "%s\n" "#define HAVE_BLAKE2_H 1" >>confdefs.h - -fi - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for blake2sp_init in -lb2" >&5 -printf %s "checking for blake2sp_init in -lb2... " >&6; } -if test ${ac_cv_lib_b2_blake2sp_init+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-lb2 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char blake2sp_init (); -int -main (void) -{ -return blake2sp_init (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_b2_blake2sp_init=yes -else $as_nop - ac_cv_lib_b2_blake2sp_init=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_b2_blake2sp_init" >&5 -printf "%s\n" "$ac_cv_lib_b2_blake2sp_init" >&6; } -if test "x$ac_cv_lib_b2_blake2sp_init" = xyes -then : - printf "%s\n" "#define HAVE_LIBB2 1" >>confdefs.h - - LIBS="-lb2 $LIBS" - -fi - -fi - - if test "x$ac_cv_lib_b2_blake2sp_init" != "xyes"; then - INC_BLAKE2_TRUE= - INC_BLAKE2_FALSE='#' -else - INC_BLAKE2_TRUE='#' - INC_BLAKE2_FALSE= -fi - - - -# Check whether --with-iconv was given. -if test ${with_iconv+y} -then : - withval=$with_iconv; -fi - - -if test "x$with_iconv" != "xno"; then - - if test "X$prefix" = "XNONE"; then - acl_final_prefix="$ac_default_prefix" - else - acl_final_prefix="$prefix" - fi - if test "X$exec_prefix" = "XNONE"; then - acl_final_exec_prefix='${prefix}' - else - acl_final_exec_prefix="$exec_prefix" - fi - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" - prefix="$acl_save_prefix" - - -# Check whether --with-gnu-ld was given. -if test ${with_gnu_ld+y} -then : - withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes -else $as_nop - with_gnu_ld=no -fi - -# Prepare PATH_SEPARATOR. -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which - # contains only /bin. Note that ksh looks also at the FPATH variable, - # so we have to set that as well for the test. - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ - && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ - || PATH_SEPARATOR=';' - } -fi -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by GCC" >&5 -printf %s "checking for ld used by GCC... " >&6; } - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [\\/]* | [A-Za-z]:[\\/]*) - re_direlt='/[^/][^/]*/\.\./' - # Canonicalize the path of ld - ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` - while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do - ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 -printf %s "checking for GNU ld... " >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 -printf %s "checking for non-GNU ld... " >&6; } -fi -if test ${acl_cv_path_LD+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -z "$LD"; then - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - acl_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some GNU ld's only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in - *GNU* | *'with BFD'*) - test "$with_gnu_ld" != no && break ;; - *) - test "$with_gnu_ld" != yes && break ;; - esac - fi - done - IFS="$ac_save_ifs" -else - acl_cv_path_LD="$LD" # Let the user override the test with a path. -fi -fi - -LD="$acl_cv_path_LD" -if test -n "$LD"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 -printf "%s\n" "$LD" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 -printf %s "checking if the linker ($LD) is GNU ld... " >&6; } -if test ${acl_cv_prog_gnu_ld+y} -then : - printf %s "(cached) " >&6 -else $as_nop - # I'd rather use --version here, but apparently some GNU ld's only accept -v. -case `$LD -v 2>&1 &5 -printf "%s\n" "$acl_cv_prog_gnu_ld" >&6; } -with_gnu_ld=$acl_cv_prog_gnu_ld - - - - - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shared library run path origin" >&5 -printf %s "checking for shared library run path origin... " >&6; } -if test ${acl_cv_rpath+y} -then : - printf %s "(cached) " >&6 -else $as_nop - - CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ - ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh - . ./conftest.sh - rm -f ./conftest.sh - acl_cv_rpath=done - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $acl_cv_rpath" >&5 -printf "%s\n" "$acl_cv_rpath" >&6; } - wl="$acl_cv_wl" - acl_libext="$acl_cv_libext" - acl_shlibext="$acl_cv_shlibext" - acl_libname_spec="$acl_cv_libname_spec" - acl_library_names_spec="$acl_cv_library_names_spec" - acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" - acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" - acl_hardcode_direct="$acl_cv_hardcode_direct" - acl_hardcode_minus_L="$acl_cv_hardcode_minus_L" - # Check whether --enable-rpath was given. -if test ${enable_rpath+y} -then : - enableval=$enable_rpath; : -else $as_nop - enable_rpath=yes -fi - - - - - acl_libdirstem=lib - acl_libdirstem2= - case "$host_os" in - solaris*) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for 64-bit host" >&5 -printf %s "checking for 64-bit host... " >&6; } -if test ${gl_cv_solaris_64bit+y} -then : - printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#ifdef _LP64 -sixtyfour bits -#endif - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "sixtyfour bits" >/dev/null 2>&1 -then : - gl_cv_solaris_64bit=yes -else $as_nop - gl_cv_solaris_64bit=no -fi -rm -rf conftest* - - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $gl_cv_solaris_64bit" >&5 -printf "%s\n" "$gl_cv_solaris_64bit" >&6; } - if test $gl_cv_solaris_64bit = yes; then - acl_libdirstem=lib/64 - case "$host_cpu" in - sparc*) acl_libdirstem2=lib/sparcv9 ;; - i*86 | x86_64) acl_libdirstem2=lib/amd64 ;; - esac - fi - ;; - *) - searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` - if test -n "$searchpath"; then - acl_save_IFS="${IFS= }"; IFS=":" - for searchdir in $searchpath; do - if test -d "$searchdir"; then - case "$searchdir" in - */lib64/ | */lib64 ) acl_libdirstem=lib64 ;; - */../ | */.. ) - # Better ignore directories of this form. They are misleading. - ;; - *) searchdir=`cd "$searchdir" && pwd` - case "$searchdir" in - */lib64 ) acl_libdirstem=lib64 ;; - esac ;; - esac - fi - done - IFS="$acl_save_IFS" - fi - ;; - esac - test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" - - - - - - - - - - - - - use_additional=yes - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - -# Check whether --with-libiconv-prefix was given. -if test ${with_libiconv_prefix+y} -then : - withval=$with_libiconv_prefix; - if test "X$withval" = "Xno"; then - use_additional=no - else - if test "X$withval" = "X"; then - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - else - additional_includedir="$withval/include" - additional_libdir="$withval/$acl_libdirstem" - if test "$acl_libdirstem2" != "$acl_libdirstem" \ - && ! test -d "$withval/$acl_libdirstem"; then - additional_libdir="$withval/$acl_libdirstem2" - fi - fi - fi - -fi - - LIBICONV= - LTLIBICONV= - INCICONV= - LIBICONV_PREFIX= - HAVE_LIBICONV= - rpathdirs= - ltrpathdirs= - names_already_handled= - names_next_round='iconv ' - while test -n "$names_next_round"; do - names_this_round="$names_next_round" - names_next_round= - for name in $names_this_round; do - already_handled= - for n in $names_already_handled; do - if test "$n" = "$name"; then - already_handled=yes - break - fi - done - if test -z "$already_handled"; then - names_already_handled="$names_already_handled $name" - uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'` - eval value=\"\$HAVE_LIB$uppername\" - if test -n "$value"; then - if test "$value" = yes; then - eval value=\"\$LIB$uppername\" - test -z "$value" || LIBICONV="${LIBICONV}${LIBICONV:+ }$value" - eval value=\"\$LTLIB$uppername\" - test -z "$value" || LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$value" - else - : - fi - else - found_dir= - found_la= - found_so= - found_a= - eval libname=\"$acl_libname_spec\" # typically: libname=lib$name - if test -n "$acl_shlibext"; then - shrext=".$acl_shlibext" # typically: shrext=.so - else - shrext= - fi - if test $use_additional = yes; then - dir="$additional_libdir" - if test -n "$acl_shlibext"; then - if test -f "$dir/$libname$shrext"; then - found_dir="$dir" - found_so="$dir/$libname$shrext" - else - if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then - ver=`(cd "$dir" && \ - for f in "$libname$shrext".*; do echo "$f"; done \ - | sed -e "s,^$libname$shrext\\\\.,," \ - | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ - | sed 1q ) 2>/dev/null` - if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then - found_dir="$dir" - found_so="$dir/$libname$shrext.$ver" - fi - else - eval library_names=\"$acl_library_names_spec\" - for f in $library_names; do - if test -f "$dir/$f"; then - found_dir="$dir" - found_so="$dir/$f" - break - fi - done - fi - fi - fi - if test "X$found_dir" = "X"; then - if test -f "$dir/$libname.$acl_libext"; then - found_dir="$dir" - found_a="$dir/$libname.$acl_libext" - fi - fi - if test "X$found_dir" != "X"; then - if test -f "$dir/$libname.la"; then - found_la="$dir/$libname.la" - fi - fi - fi - if test "X$found_dir" = "X"; then - for x in $LDFLAGS $LTLIBICONV; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - case "$x" in - -L*) - dir=`echo "X$x" | sed -e 's/^X-L//'` - if test -n "$acl_shlibext"; then - if test -f "$dir/$libname$shrext"; then - found_dir="$dir" - found_so="$dir/$libname$shrext" - else - if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then - ver=`(cd "$dir" && \ - for f in "$libname$shrext".*; do echo "$f"; done \ - | sed -e "s,^$libname$shrext\\\\.,," \ - | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ - | sed 1q ) 2>/dev/null` - if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then - found_dir="$dir" - found_so="$dir/$libname$shrext.$ver" - fi - else - eval library_names=\"$acl_library_names_spec\" - for f in $library_names; do - if test -f "$dir/$f"; then - found_dir="$dir" - found_so="$dir/$f" - break - fi - done - fi - fi - fi - if test "X$found_dir" = "X"; then - if test -f "$dir/$libname.$acl_libext"; then - found_dir="$dir" - found_a="$dir/$libname.$acl_libext" - fi - fi - if test "X$found_dir" != "X"; then - if test -f "$dir/$libname.la"; then - found_la="$dir/$libname.la" - fi - fi - ;; - esac - if test "X$found_dir" != "X"; then - break - fi - done - fi - if test "X$found_dir" != "X"; then - LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$found_dir -l$name" - if test "X$found_so" != "X"; then - if test "$enable_rpath" = no \ - || test "X$found_dir" = "X/usr/$acl_libdirstem" \ - || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then - LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" - else - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $found_dir" - fi - if test "$acl_hardcode_direct" = yes; then - LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" - else - if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then - LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $found_dir" - fi - else - haveit= - for x in $LDFLAGS $LIBICONV; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - if test "X$x" = "X-L$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir" - fi - if test "$acl_hardcode_minus_L" != no; then - LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" - else - LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" - fi - fi - fi - fi - else - if test "X$found_a" != "X"; then - LIBICONV="${LIBICONV}${LIBICONV:+ }$found_a" - else - LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir -l$name" - fi - fi - additional_includedir= - case "$found_dir" in - */$acl_libdirstem | */$acl_libdirstem/) - basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` - if test "$name" = 'iconv'; then - LIBICONV_PREFIX="$basedir" - fi - additional_includedir="$basedir/include" - ;; - */$acl_libdirstem2 | */$acl_libdirstem2/) - basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` - if test "$name" = 'iconv'; then - LIBICONV_PREFIX="$basedir" - fi - additional_includedir="$basedir/include" - ;; - esac - if test "X$additional_includedir" != "X"; then - if test "X$additional_includedir" != "X/usr/include"; then - haveit= - if test "X$additional_includedir" = "X/usr/local/include"; then - if test -n "$GCC"; then - case $host_os in - linux* | gnu* | k*bsd*-gnu) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - for x in $CPPFLAGS $INCICONV; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - if test "X$x" = "X-I$additional_includedir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_includedir"; then - INCICONV="${INCICONV}${INCICONV:+ }-I$additional_includedir" - fi - fi - fi - fi - fi - if test -n "$found_la"; then - save_libdir="$libdir" - case "$found_la" in - */* | *\\*) . "$found_la" ;; - *) . "./$found_la" ;; - esac - libdir="$save_libdir" - for dep in $dependency_libs; do - case "$dep" in - -L*) - additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` - if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \ - && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then - haveit= - if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \ - || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then - if test -n "$GCC"; then - case $host_os in - linux* | gnu* | k*bsd*-gnu) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - haveit= - for x in $LDFLAGS $LIBICONV; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - LIBICONV="${LIBICONV}${LIBICONV:+ }-L$additional_libdir" - fi - fi - haveit= - for x in $LDFLAGS $LTLIBICONV; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$additional_libdir" - fi - fi - fi - fi - ;; - -R*) - dir=`echo "X$dep" | sed -e 's/^X-R//'` - if test "$enable_rpath" != no; then - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $dir" - fi - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $dir" - fi - fi - ;; - -l*) - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` - ;; - *.la) - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` - ;; - *) - LIBICONV="${LIBICONV}${LIBICONV:+ }$dep" - LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$dep" - ;; - esac - done - fi - else - LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" - LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-l$name" - fi - fi - fi - done - done - if test "X$rpathdirs" != "X"; then - if test -n "$acl_hardcode_libdir_separator"; then - alldirs= - for found_dir in $rpathdirs; do - alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" - done - acl_save_libdir="$libdir" - libdir="$alldirs" - eval flag=\"$acl_hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" - else - for found_dir in $rpathdirs; do - acl_save_libdir="$libdir" - libdir="$found_dir" - eval flag=\"$acl_hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" - done - fi - fi - if test "X$ltrpathdirs" != "X"; then - for found_dir in $ltrpathdirs; do - LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-R$found_dir" - done - fi - - - - - - - - - - - - - am_save_CPPFLAGS="$CPPFLAGS" - - for element in $INCICONV; do - haveit= - for x in $CPPFLAGS; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - if test "X$x" = "X$element"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" - fi - done - - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for iconv" >&5 -printf %s "checking for iconv... " >&6; } -if test ${am_cv_func_iconv+y} -then : - printf %s "(cached) " >&6 -else $as_nop - - am_cv_func_iconv="no, consider installing GNU libiconv" - am_cv_lib_iconv=no - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#include - -int -main (void) -{ -iconv_t cd = iconv_open("",""); - iconv(cd,NULL,NULL,NULL,NULL); - iconv_close(cd); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - am_cv_func_iconv=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - if test "$am_cv_func_iconv" != yes; then - am_save_LIBS="$LIBS" - LIBS="$LIBS $LIBICONV" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#include - -int -main (void) -{ -iconv_t cd = iconv_open("",""); - iconv(cd,NULL,NULL,NULL,NULL); - iconv_close(cd); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - am_cv_lib_iconv=yes - am_cv_func_iconv=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - LIBS="$am_save_LIBS" - fi - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv" >&5 -printf "%s\n" "$am_cv_func_iconv" >&6; } - if test "$am_cv_func_iconv" = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working iconv" >&5 -printf %s "checking for working iconv... " >&6; } -if test ${am_cv_func_iconv_works+y} -then : - printf %s "(cached) " >&6 -else $as_nop - - am_save_LIBS="$LIBS" - if test $am_cv_lib_iconv = yes; then - LIBS="$LIBS $LIBICONV" - fi - am_cv_func_iconv_works=no - for ac_iconv_const in '' 'const'; do - if test "$cross_compiling" = yes -then : - case "$host_os" in - aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; - *) am_cv_func_iconv_works="guessing yes" ;; - esac -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#include - -#ifndef ICONV_CONST -# define ICONV_CONST $ac_iconv_const -#endif - -int -main (void) -{ -int result = 0; - /* Test against AIX 5.1 bug: Failures are not distinguishable from successful - returns. */ - { - iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); - if (cd_utf8_to_88591 != (iconv_t)(-1)) - { - static ICONV_CONST char input[] = "\342\202\254"; /* EURO SIGN */ - char buf[10]; - ICONV_CONST char *inptr = input; - size_t inbytesleft = strlen (input); - char *outptr = buf; - size_t outbytesleft = sizeof (buf); - size_t res = iconv (cd_utf8_to_88591, - &inptr, &inbytesleft, - &outptr, &outbytesleft); - if (res == 0) - result |= 1; - iconv_close (cd_utf8_to_88591); - } - } - /* Test against Solaris 10 bug: Failures are not distinguishable from - successful returns. */ - { - iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646"); - if (cd_ascii_to_88591 != (iconv_t)(-1)) - { - static ICONV_CONST char input[] = "\263"; - char buf[10]; - ICONV_CONST char *inptr = input; - size_t inbytesleft = strlen (input); - char *outptr = buf; - size_t outbytesleft = sizeof (buf); - size_t res = iconv (cd_ascii_to_88591, - &inptr, &inbytesleft, - &outptr, &outbytesleft); - if (res == 0) - result |= 2; - iconv_close (cd_ascii_to_88591); - } - } - /* Test against AIX 6.1..7.1 bug: Buffer overrun. */ - { - iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1"); - if (cd_88591_to_utf8 != (iconv_t)(-1)) - { - static ICONV_CONST char input[] = "\304"; - static char buf[2] = { (char)0xDE, (char)0xAD }; - ICONV_CONST char *inptr = input; - size_t inbytesleft = 1; - char *outptr = buf; - size_t outbytesleft = 1; - size_t res = iconv (cd_88591_to_utf8, - &inptr, &inbytesleft, - &outptr, &outbytesleft); - if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD) - result |= 4; - iconv_close (cd_88591_to_utf8); - } - } -#if 0 /* This bug could be worked around by the caller. */ - /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */ - { - iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591"); - if (cd_88591_to_utf8 != (iconv_t)(-1)) - { - static ICONV_CONST char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; - char buf[50]; - ICONV_CONST char *inptr = input; - size_t inbytesleft = strlen (input); - char *outptr = buf; - size_t outbytesleft = sizeof (buf); - size_t res = iconv (cd_88591_to_utf8, - &inptr, &inbytesleft, - &outptr, &outbytesleft); - if ((int)res > 0) - result |= 8; - iconv_close (cd_88591_to_utf8); - } - } -#endif - /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is - provided. */ - if (/* Try standardized names. */ - iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1) - /* Try IRIX, OSF/1 names. */ - && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1) - /* Try AIX names. */ - && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1) - /* Try HP-UX names. */ - && iconv_open ("utf8", "eucJP") == (iconv_t)(-1)) - result |= 16; - return result; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO" -then : - am_cv_func_iconv_works=yes -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - - test "$am_cv_func_iconv_works" = no || break - done - LIBS="$am_save_LIBS" - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv_works" >&5 -printf "%s\n" "$am_cv_func_iconv_works" >&6; } - case "$am_cv_func_iconv_works" in - *no) am_func_iconv=no am_cv_lib_iconv=no ;; - *) am_func_iconv=yes ;; - esac - else - am_func_iconv=no am_cv_lib_iconv=no - fi - if test "$am_func_iconv" = yes; then - -printf "%s\n" "#define HAVE_ICONV 1" >>confdefs.h - - fi - if test "$am_cv_lib_iconv" = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to link with libiconv" >&5 -printf %s "checking how to link with libiconv... " >&6; } - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIBICONV" >&5 -printf "%s\n" "$LIBICONV" >&6; } - else - CPPFLAGS="$am_save_CPPFLAGS" - LIBICONV= - LTLIBICONV= - fi - - - - if test "$am_cv_func_iconv" = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for iconv declaration" >&5 -printf %s "checking for iconv declaration... " >&6; } - if test ${am_cv_proto_iconv+y} -then : - printf %s "(cached) " >&6 -else $as_nop - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#include -extern -#ifdef __cplusplus -"C" -#endif -#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) -size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); -#else -size_t iconv(); -#endif - -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - am_cv_proto_iconv_arg1="" -else $as_nop - am_cv_proto_iconv_arg1="const" -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);" -fi - - am_cv_proto_iconv=`echo "$am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: - $am_cv_proto_iconv" >&5 -printf "%s\n" " - $am_cv_proto_iconv" >&6; } - -printf "%s\n" "#define ICONV_CONST $am_cv_proto_iconv_arg1" >>confdefs.h - - - fi - - ac_fn_c_check_header_compile "$LINENO" "iconv.h" "ac_cv_header_iconv_h" "#include -" -if test "x$ac_cv_header_iconv_h" = xyes -then : - printf "%s\n" "#define HAVE_ICONV_H 1" >>confdefs.h - -fi - - if test "x$am_cv_func_iconv" = "xyes"; then - ac_fn_c_check_header_compile "$LINENO" "localcharset.h" "ac_cv_header_localcharset_h" "$ac_includes_default" -if test "x$ac_cv_header_localcharset_h" = xyes -then : - printf "%s\n" "#define HAVE_LOCALCHARSET_H 1" >>confdefs.h - -fi - - am_save_LIBS="$LIBS" - LIBS="${LIBS} ${LIBICONV}" - if test -n "$LIBICONV"; then - LIBSREQUIRED="$LIBSREQUIRED${LIBSREQUIRED:+ }iconv" - fi - ac_fn_c_check_func "$LINENO" "locale_charset" "ac_cv_func_locale_charset" -if test "x$ac_cv_func_locale_charset" = xyes -then : - printf "%s\n" "#define HAVE_LOCALE_CHARSET 1" >>confdefs.h - -fi - - LIBS="${am_save_LIBS}" - if test "x$ac_cv_func_locale_charset" != "xyes"; then - # If locale_charset() is not in libiconv, we have to find libcharset. - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for locale_charset in -lcharset" >&5 -printf %s "checking for locale_charset in -lcharset... " >&6; } -if test ${ac_cv_lib_charset_locale_charset+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-lcharset $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char locale_charset (); -int -main (void) -{ -return locale_charset (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_charset_locale_charset=yes -else $as_nop - ac_cv_lib_charset_locale_charset=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_charset_locale_charset" >&5 -printf "%s\n" "$ac_cv_lib_charset_locale_charset" >&6; } -if test "x$ac_cv_lib_charset_locale_charset" = xyes -then : - printf "%s\n" "#define HAVE_LIBCHARSET 1" >>confdefs.h - - LIBS="-lcharset $LIBS" - -fi - - fi - fi -fi - - -# Check whether --with-lz4 was given. -if test ${with_lz4+y} -then : - withval=$with_lz4; -fi - - -if test "x$with_lz4" != "xno"; then - ac_fn_c_check_header_compile "$LINENO" "lz4.h" "ac_cv_header_lz4_h" "$ac_includes_default" -if test "x$ac_cv_header_lz4_h" = xyes -then : - printf "%s\n" "#define HAVE_LZ4_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "lz4hc.h" "ac_cv_header_lz4hc_h" "$ac_includes_default" -if test "x$ac_cv_header_lz4hc_h" = xyes -then : - printf "%s\n" "#define HAVE_LZ4HC_H 1" >>confdefs.h - -fi - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for LZ4_decompress_safe in -llz4" >&5 -printf %s "checking for LZ4_decompress_safe in -llz4... " >&6; } -if test ${ac_cv_lib_lz4_LZ4_decompress_safe+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-llz4 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char LZ4_decompress_safe (); -int -main (void) -{ -return LZ4_decompress_safe (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_lz4_LZ4_decompress_safe=yes -else $as_nop - ac_cv_lib_lz4_LZ4_decompress_safe=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lz4_LZ4_decompress_safe" >&5 -printf "%s\n" "$ac_cv_lib_lz4_LZ4_decompress_safe" >&6; } -if test "x$ac_cv_lib_lz4_LZ4_decompress_safe" = xyes -then : - printf "%s\n" "#define HAVE_LIBLZ4 1" >>confdefs.h - - LIBS="-llz4 $LIBS" - -fi - -fi - - -# Check whether --with-zstd was given. -if test ${with_zstd+y} -then : - withval=$with_zstd; -fi - - -if test "x$with_zstd" != "xno"; then - ac_fn_c_check_header_compile "$LINENO" "zstd.h" "ac_cv_header_zstd_h" "$ac_includes_default" -if test "x$ac_cv_header_zstd_h" = xyes -then : - printf "%s\n" "#define HAVE_ZSTD_H 1" >>confdefs.h - -fi - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ZSTD_decompressStream in -lzstd" >&5 -printf %s "checking for ZSTD_decompressStream in -lzstd... " >&6; } -if test ${ac_cv_lib_zstd_ZSTD_decompressStream+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-lzstd $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char ZSTD_decompressStream (); -int -main (void) -{ -return ZSTD_decompressStream (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_zstd_ZSTD_decompressStream=yes -else $as_nop - ac_cv_lib_zstd_ZSTD_decompressStream=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_zstd_ZSTD_decompressStream" >&5 -printf "%s\n" "$ac_cv_lib_zstd_ZSTD_decompressStream" >&6; } -if test "x$ac_cv_lib_zstd_ZSTD_decompressStream" = xyes -then : - printf "%s\n" "#define HAVE_LIBZSTD 1" >>confdefs.h - - LIBS="-lzstd $LIBS" - -fi - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ZSTD_compressStream in -lzstd" >&5 -printf %s "checking for ZSTD_compressStream in -lzstd... " >&6; } -if test ${ac_cv_lib_zstd_ZSTD_compressStream+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-lzstd $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char ZSTD_compressStream (); -int -main (void) -{ -return ZSTD_compressStream (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_zstd_ZSTD_compressStream=yes -else $as_nop - ac_cv_lib_zstd_ZSTD_compressStream=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_zstd_ZSTD_compressStream" >&5 -printf "%s\n" "$ac_cv_lib_zstd_ZSTD_compressStream" >&6; } -if test "x$ac_cv_lib_zstd_ZSTD_compressStream" = xyes -then : - -printf "%s\n" "#define HAVE_LIBZSTD_COMPRESSOR 1" >>confdefs.h - -fi - -fi - - -# Check whether --with-lzma was given. -if test ${with_lzma+y} -then : - withval=$with_lzma; -fi - - -if test "x$with_lzma" != "xno"; then - ac_fn_c_check_header_compile "$LINENO" "lzma.h" "ac_cv_header_lzma_h" "$ac_includes_default" -if test "x$ac_cv_header_lzma_h" = xyes -then : - printf "%s\n" "#define HAVE_LZMA_H 1" >>confdefs.h - -fi - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for lzma_stream_decoder in -llzma" >&5 -printf %s "checking for lzma_stream_decoder in -llzma... " >&6; } -if test ${ac_cv_lib_lzma_lzma_stream_decoder+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-llzma $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char lzma_stream_decoder (); -int -main (void) -{ -return lzma_stream_decoder (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_lzma_lzma_stream_decoder=yes -else $as_nop - ac_cv_lib_lzma_lzma_stream_decoder=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lzma_lzma_stream_decoder" >&5 -printf "%s\n" "$ac_cv_lib_lzma_lzma_stream_decoder" >&6; } -if test "x$ac_cv_lib_lzma_lzma_stream_decoder" = xyes -then : - printf "%s\n" "#define HAVE_LIBLZMA 1" >>confdefs.h - - LIBS="-llzma $LIBS" - -fi - - # Some pre-release (but widely distributed) versions of liblzma - # included a disabled version of lzma_stream_encoder_mt that - # fools a naive AC_CHECK_LIB or AC_CHECK_FUNC, so we need - # to do something more complex here: - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we have multithread support in lzma" >&5 -printf %s "checking whether we have multithread support in lzma... " >&6; } -if test ${ac_cv_lzma_has_mt+y} -then : - printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include - #if LZMA_VERSION < 50020000 - #error unsupported - #endif -int -main (void) -{ -lzma_stream_encoder_mt(0, 0); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lzma_has_mt=yes -else $as_nop - ac_cv_lzma_has_mt=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lzma_has_mt" >&5 -printf "%s\n" "$ac_cv_lzma_has_mt" >&6; } - if test "x$ac_cv_lzma_has_mt" != xno; then - -printf "%s\n" "#define HAVE_LZMA_STREAM_ENCODER_MT 1" >>confdefs.h - - fi - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we have ARM64 filter support in lzma" >&5 -printf %s "checking whether we have ARM64 filter support in lzma... " >&6; } -if test ${ac_cv_lzma_has_arm64+y} -then : - printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include - #ifndef LZMA_FILTER_ARM64 - #error unsupported - #endif -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lzma_has_arm64=yes -else $as_nop - ac_cv_lzma_has_arm64=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lzma_has_arm64" >&5 -printf "%s\n" "$ac_cv_lzma_has_arm64" >&6; } - if test "x$ac_cv_lzma_has_arm64" != xno; then - -printf "%s\n" "#define HAVE_LZMA_FILTER_ARM64 1" >>confdefs.h - - fi -fi - - -# Check whether --with-lzo2 was given. -if test ${with_lzo2+y} -then : - withval=$with_lzo2; -fi - - -if test "x$with_lzo2" = "xyes"; then - ac_fn_c_check_header_compile "$LINENO" "lzo/lzoconf.h" "ac_cv_header_lzo_lzoconf_h" "$ac_includes_default" -if test "x$ac_cv_header_lzo_lzoconf_h" = xyes -then : - printf "%s\n" "#define HAVE_LZO_LZOCONF_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "lzo/lzo1x.h" "ac_cv_header_lzo_lzo1x_h" "$ac_includes_default" -if test "x$ac_cv_header_lzo_lzo1x_h" = xyes -then : - printf "%s\n" "#define HAVE_LZO_LZO1X_H 1" >>confdefs.h - -fi - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for lzo1x_decompress_safe in -llzo2" >&5 -printf %s "checking for lzo1x_decompress_safe in -llzo2... " >&6; } -if test ${ac_cv_lib_lzo2_lzo1x_decompress_safe+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-llzo2 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char lzo1x_decompress_safe (); -int -main (void) -{ -return lzo1x_decompress_safe (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_lzo2_lzo1x_decompress_safe=yes -else $as_nop - ac_cv_lib_lzo2_lzo1x_decompress_safe=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lzo2_lzo1x_decompress_safe" >&5 -printf "%s\n" "$ac_cv_lib_lzo2_lzo1x_decompress_safe" >&6; } -if test "x$ac_cv_lib_lzo2_lzo1x_decompress_safe" = xyes -then : - printf "%s\n" "#define HAVE_LIBLZO2 1" >>confdefs.h - - LIBS="-llzo2 $LIBS" - -fi - -fi - - -# Check whether --with-cng was given. -if test ${with_cng+y} -then : - withval=$with_cng; -fi - - - -# Check whether --with-mbedtls was given. -if test ${with_mbedtls+y} -then : - withval=$with_mbedtls; -fi - - -# Check whether --with-nettle was given. -if test ${with_nettle+y} -then : - withval=$with_nettle; -fi - - -# Check whether --with-openssl was given. -if test ${with_openssl+y} -then : - withval=$with_openssl; -fi - -case "$host_os" in - *darwin* ) with_openssl=no ;; -esac - - -# Check whether --with-xml2 was given. -if test ${with_xml2+y} -then : - withval=$with_xml2; -fi - - -# Check whether --with-expat was given. -if test ${with_expat+y} -then : - withval=$with_expat; -fi - - -if test "x$with_xml2" != "xno"; then - - - - - - - -if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. -set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_path_PKG_CONFIG+y} -then : - printf %s "(cached) " >&6 -else $as_nop - case $PKG_CONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_path_PKG_CONFIG="$as_dir$ac_word$ac_exec_ext" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -PKG_CONFIG=$ac_cv_path_PKG_CONFIG -if test -n "$PKG_CONFIG"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 -printf "%s\n" "$PKG_CONFIG" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - -fi -if test -z "$ac_cv_path_PKG_CONFIG"; then - ac_pt_PKG_CONFIG=$PKG_CONFIG - # Extract the first word of "pkg-config", so it can be a program name with args. -set dummy pkg-config; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_path_ac_pt_PKG_CONFIG+y} -then : - printf %s "(cached) " >&6 -else $as_nop - case $ac_pt_PKG_CONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_path_ac_pt_PKG_CONFIG="$as_dir$ac_word$ac_exec_ext" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG -if test -n "$ac_pt_PKG_CONFIG"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 -printf "%s\n" "$ac_pt_PKG_CONFIG" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - if test "x$ac_pt_PKG_CONFIG" = x; then - PKG_CONFIG="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - PKG_CONFIG=$ac_pt_PKG_CONFIG - fi -else - PKG_CONFIG="$ac_cv_path_PKG_CONFIG" -fi - -fi -if test -n "$PKG_CONFIG"; then - _pkg_min_version=0.9.0 - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 -printf %s "checking pkg-config is at least version $_pkg_min_version... " >&6; } - if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } - PKG_CONFIG="" - fi -fi - -pkg_failed=no -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libxml-2.0" >&5 -printf %s "checking for libxml-2.0... " >&6; } - -if test -n "$LIBXML2_PC_CFLAGS"; then - pkg_cv_LIBXML2_PC_CFLAGS="$LIBXML2_PC_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libxml-2.0\""; } >&5 - ($PKG_CONFIG --exists --print-errors "libxml-2.0") 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LIBXML2_PC_CFLAGS=`$PKG_CONFIG --cflags "libxml-2.0" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$LIBXML2_PC_LIBS"; then - pkg_cv_LIBXML2_PC_LIBS="$LIBXML2_PC_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libxml-2.0\""; } >&5 - ($PKG_CONFIG --exists --print-errors "libxml-2.0") 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LIBXML2_PC_LIBS=`$PKG_CONFIG --libs "libxml-2.0" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - LIBXML2_PC_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libxml-2.0" 2>&1` - else - LIBXML2_PC_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libxml-2.0" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$LIBXML2_PC_PKG_ERRORS" >&5 - - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for xmlInitParser in -lxml2" >&5 -printf %s "checking for xmlInitParser in -lxml2... " >&6; } -if test ${ac_cv_lib_xml2_xmlInitParser+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-lxml2 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char xmlInitParser (); -int -main (void) -{ -return xmlInitParser (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_xml2_xmlInitParser=yes -else $as_nop - ac_cv_lib_xml2_xmlInitParser=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xml2_xmlInitParser" >&5 -printf "%s\n" "$ac_cv_lib_xml2_xmlInitParser" >&6; } -if test "x$ac_cv_lib_xml2_xmlInitParser" = xyes -then : - printf "%s\n" "#define HAVE_LIBXML2 1" >>confdefs.h - - LIBS="-lxml2 $LIBS" - -fi - - -elif test $pkg_failed = untried; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for xmlInitParser in -lxml2" >&5 -printf %s "checking for xmlInitParser in -lxml2... " >&6; } -if test ${ac_cv_lib_xml2_xmlInitParser+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-lxml2 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char xmlInitParser (); -int -main (void) -{ -return xmlInitParser (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_xml2_xmlInitParser=yes -else $as_nop - ac_cv_lib_xml2_xmlInitParser=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xml2_xmlInitParser" >&5 -printf "%s\n" "$ac_cv_lib_xml2_xmlInitParser" >&6; } -if test "x$ac_cv_lib_xml2_xmlInitParser" = xyes -then : - printf "%s\n" "#define HAVE_LIBXML2 1" >>confdefs.h - - LIBS="-lxml2 $LIBS" - -fi - - -else - LIBXML2_PC_CFLAGS=$pkg_cv_LIBXML2_PC_CFLAGS - LIBXML2_PC_LIBS=$pkg_cv_LIBXML2_PC_LIBS - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - - CPPFLAGS="${CPPFLAGS} ${LIBXML2_PC_CFLAGS}" - LIBS="${LIBS} ${LIBXML2_PC_LIBS}" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for xmlInitParser in -lxml2" >&5 -printf %s "checking for xmlInitParser in -lxml2... " >&6; } -if test ${ac_cv_lib_xml2_xmlInitParser+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-lxml2 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char xmlInitParser (); -int -main (void) -{ -return xmlInitParser (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_xml2_xmlInitParser=yes -else $as_nop - ac_cv_lib_xml2_xmlInitParser=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xml2_xmlInitParser" >&5 -printf "%s\n" "$ac_cv_lib_xml2_xmlInitParser" >&6; } -if test "x$ac_cv_lib_xml2_xmlInitParser" = xyes -then : - true -else $as_nop - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "Missing xml2 library -See \`config.log' for more details" "$LINENO" 5; } -fi - - -fi - ac_fn_c_check_header_compile "$LINENO" "libxml/xmlreader.h" "ac_cv_header_libxml_xmlreader_h" "$ac_includes_default" -if test "x$ac_cv_header_libxml_xmlreader_h" = xyes -then : - printf "%s\n" "#define HAVE_LIBXML_XMLREADER_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "libxml/xmlwriter.h" "ac_cv_header_libxml_xmlwriter_h" "$ac_includes_default" -if test "x$ac_cv_header_libxml_xmlwriter_h" = xyes -then : - printf "%s\n" "#define HAVE_LIBXML_XMLWRITER_H 1" >>confdefs.h - -fi - -fi -if test "x$ac_cv_header_libxml_xmlreader_h" != "xyes"; then - if test "x$with_expat" != "xno"; then - ac_fn_c_check_header_compile "$LINENO" "expat.h" "ac_cv_header_expat_h" "$ac_includes_default" -if test "x$ac_cv_header_expat_h" = xyes -then : - printf "%s\n" "#define HAVE_EXPAT_H 1" >>confdefs.h - -fi - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for XML_ParserCreate in -lexpat" >&5 -printf %s "checking for XML_ParserCreate in -lexpat... " >&6; } -if test ${ac_cv_lib_expat_XML_ParserCreate+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-lexpat $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char XML_ParserCreate (); -int -main (void) -{ -return XML_ParserCreate (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_expat_XML_ParserCreate=yes -else $as_nop - ac_cv_lib_expat_XML_ParserCreate=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_expat_XML_ParserCreate" >&5 -printf "%s\n" "$ac_cv_lib_expat_XML_ParserCreate" >&6; } -if test "x$ac_cv_lib_expat_XML_ParserCreate" = xyes -then : - printf "%s\n" "#define HAVE_LIBEXPAT 1" >>confdefs.h - - LIBS="-lexpat $LIBS" - -fi - - fi -fi - -# Check whether --enable-posix-regex-lib was given. -if test ${enable_posix_regex_lib+y} -then : - enableval=$enable_posix_regex_lib; -else $as_nop - enable_posix_regex_lib=auto -fi - - -posix_regex_lib_found= -if test "$enable_posix_regex_lib" = "auto" || test "$enable_posix_regex_lib" = "libc" || test "$enable_posix_regex_lib" = "libregex"; then - ac_fn_c_check_header_compile "$LINENO" "regex.h" "ac_cv_header_regex_h" "$ac_includes_default" -if test "x$ac_cv_header_regex_h" = xyes -then : - printf "%s\n" "#define HAVE_REGEX_H 1" >>confdefs.h - -fi - - if test "x$ac_cv_header_regex_h" != "xno"; then - ac_fn_c_check_func "$LINENO" "regcomp" "ac_cv_func_regcomp" -if test "x$ac_cv_func_regcomp" = xyes -then : - -fi - - if test "x$ac_cv_func_regcomp" = xyes; then - posix_regex_lib_found=1 - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for regcomp in -lregex" >&5 -printf %s "checking for regcomp in -lregex... " >&6; } -if test ${ac_cv_lib_regex_regcomp+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-lregex $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char regcomp (); -int -main (void) -{ -return regcomp (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_regex_regcomp=yes -else $as_nop - ac_cv_lib_regex_regcomp=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_regex_regcomp" >&5 -printf "%s\n" "$ac_cv_lib_regex_regcomp" >&6; } -if test "x$ac_cv_lib_regex_regcomp" = xyes -then : - printf "%s\n" "#define HAVE_LIBREGEX 1" >>confdefs.h - - LIBS="-lregex $LIBS" - -fi - - if test "x$ac_cv_lib_regex_regcomp" = xyes; then - posix_regex_lib_found=1 - fi - fi - fi -fi -if test -z $posix_regex_lib_found && (test "$enable_posix_regex_lib" = "auto" || test "$enable_posix_regex_lib" = "libpcreposix"); then - ac_fn_c_check_header_compile "$LINENO" "pcreposix.h" "ac_cv_header_pcreposix_h" "$ac_includes_default" -if test "x$ac_cv_header_pcreposix_h" = xyes -then : - printf "%s\n" "#define HAVE_PCREPOSIX_H 1" >>confdefs.h - -fi - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for regcomp in -lpcreposix" >&5 -printf %s "checking for regcomp in -lpcreposix... " >&6; } -if test ${ac_cv_lib_pcreposix_regcomp+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-lpcreposix $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char regcomp (); -int -main (void) -{ -return regcomp (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_pcreposix_regcomp=yes -else $as_nop - ac_cv_lib_pcreposix_regcomp=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pcreposix_regcomp" >&5 -printf "%s\n" "$ac_cv_lib_pcreposix_regcomp" >&6; } -if test "x$ac_cv_lib_pcreposix_regcomp" = xyes -then : - printf "%s\n" "#define HAVE_LIBPCREPOSIX 1" >>confdefs.h - - LIBS="-lpcreposix $LIBS" - -fi - - if test "x$ac_cv_lib_pcreposix_regcomp" != xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: trying libpcreposix check again with libpcre" >&5 -printf "%s\n" "$as_me: trying libpcreposix check again with libpcre" >&6;} - unset ac_cv_lib_pcreposix_regcomp - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pcre_exec in -lpcre" >&5 -printf %s "checking for pcre_exec in -lpcre... " >&6; } -if test ${ac_cv_lib_pcre_pcre_exec+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-lpcre $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char pcre_exec (); -int -main (void) -{ -return pcre_exec (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_pcre_pcre_exec=yes -else $as_nop - ac_cv_lib_pcre_pcre_exec=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pcre_pcre_exec" >&5 -printf "%s\n" "$ac_cv_lib_pcre_pcre_exec" >&6; } -if test "x$ac_cv_lib_pcre_pcre_exec" = xyes -then : - printf "%s\n" "#define HAVE_LIBPCRE 1" >>confdefs.h - - LIBS="-lpcre $LIBS" - -fi - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for regcomp in -lpcreposix" >&5 -printf %s "checking for regcomp in -lpcreposix... " >&6; } -if test ${ac_cv_lib_pcreposix_regcomp+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-lpcreposix $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char regcomp (); -int -main (void) -{ -return regcomp (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_pcreposix_regcomp=yes -else $as_nop - ac_cv_lib_pcreposix_regcomp=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pcreposix_regcomp" >&5 -printf "%s\n" "$ac_cv_lib_pcreposix_regcomp" >&6; } -if test "x$ac_cv_lib_pcreposix_regcomp" = xyes -then : - printf "%s\n" "#define HAVE_LIBPCREPOSIX 1" >>confdefs.h - - LIBS="-lpcreposix $LIBS" - -fi - - if test "x$ac_cv_lib_pcre_pcre_exec" = xyes && test "x$ac_cv_lib_pcreposix_regcomp" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if PCRE_STATIC needs to be defined" >&5 -printf %s "checking if PCRE_STATIC needs to be defined... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - int main() { return regcomp(NULL, NULL, 0); } -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - without_pcre_static=yes -else $as_nop - without_pcre_static=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#define PCRE_STATIC - #include - int main() { return regcomp(NULL, NULL, 0); } -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - with_pcre_static=yes -else $as_nop - with_pcre_static=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - if test "x$without_pcre_static" != xyes && test "x$with_pcre_static" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - -printf "%s\n" "#define PCRE_STATIC 1" >>confdefs.h - - elif test "x$without_pcre_static" = xyes || test "x$with_pcre_static" = xyes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } - fi - posix_regex_lib_found=1 - fi - else - posix_regex_lib_found=1 - fi -fi - -# TODO: Give the user the option of using a pre-existing system -# libarchive. This will define HAVE_LIBARCHIVE which will cause -# bsdtar_platform.h to use #include <...> for the libarchive headers. -# Need to include Makefile.am magic to link against system -# -larchive in that case. -#AC_CHECK_LIB(archive,archive_version) - -# Checks for supported compiler flags - - - - -for flag in -Wall -Wformat -Wformat-security; do - as_CACHEVAR=`printf "%s\n" "ax_cv_check_cflags__$flag" | $as_tr_sh` -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5 -printf %s "checking whether C compiler accepts $flag... " >&6; } -if eval test \${$as_CACHEVAR+y} -then : - printf %s "(cached) " >&6 -else $as_nop - - ax_check_save_flags=$CFLAGS - CFLAGS="$CFLAGS $flag" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - eval "$as_CACHEVAR=yes" -else $as_nop - eval "$as_CACHEVAR=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - CFLAGS=$ax_check_save_flags -fi -eval ac_res=\$$as_CACHEVAR - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -printf "%s\n" "$ac_res" >&6; } -if eval test \"x\$"$as_CACHEVAR"\" = x"yes" -then : - -if test ${CFLAGS+y} -then : - - case " $CFLAGS " in #( - *" $flag "*) : - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5 - (: CFLAGS already contains $flag) 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } ;; #( - *) : - - as_fn_append CFLAGS " $flag" - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5 - (: CFLAGS="$CFLAGS") 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - ;; -esac - -else $as_nop - - CFLAGS=$flag - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5 - (: CFLAGS="$CFLAGS") 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - -fi - -else $as_nop - : -fi - -done - - -# Place the functions and data into separate sections, allowing the linker -# to garbage collect the unused ones. -save_LDFLAGS=$LDFLAGS -LDFLAGS="$LDFLAGS -Wl,--gc-sections" -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ld supports --gc-sections" >&5 -printf %s "checking whether ld supports --gc-sections... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -static char UnusedFunc() { return 5; } int main() { return 0;} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - GC_SECTIONS="-Wl,--gc-sections"; - - - - -for flag in -ffunction-sections -fdata-sections; do - as_CACHEVAR=`printf "%s\n" "ax_cv_check_cflags__$flag" | $as_tr_sh` -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5 -printf %s "checking whether C compiler accepts $flag... " >&6; } -if eval test \${$as_CACHEVAR+y} -then : - printf %s "(cached) " >&6 -else $as_nop - - ax_check_save_flags=$CFLAGS - CFLAGS="$CFLAGS $flag" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - eval "$as_CACHEVAR=yes" -else $as_nop - eval "$as_CACHEVAR=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - CFLAGS=$ax_check_save_flags -fi -eval ac_res=\$$as_CACHEVAR - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -printf "%s\n" "$ac_res" >&6; } -if eval test \"x\$"$as_CACHEVAR"\" = x"yes" -then : - -if test ${CFLAGS+y} -then : - - case " $CFLAGS " in #( - *" $flag "*) : - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5 - (: CFLAGS already contains $flag) 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } ;; #( - *) : - - as_fn_append CFLAGS " $flag" - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5 - (: CFLAGS="$CFLAGS") 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - ;; -esac - -else $as_nop - - CFLAGS=$flag - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5 - (: CFLAGS="$CFLAGS") 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - -fi - -else $as_nop - : -fi - -done - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } - GC_SECTIONS=""; -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LDFLAGS=$save_LDFLAGS - - - -# Checks for typedefs, structures, and compiler characteristics. -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 -printf %s "checking for an ANSI C-conforming const... " >&6; } -if test ${ac_cv_c_const+y} -then : - printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main (void) -{ - -#ifndef __cplusplus - /* Ultrix mips cc rejects this sort of thing. */ - typedef int charset[2]; - const charset cs = { 0, 0 }; - /* SunOS 4.1.1 cc rejects this. */ - char const *const *pcpcc; - char **ppc; - /* NEC SVR4.0.2 mips cc rejects this. */ - struct point {int x, y;}; - static struct point const zero = {0,0}; - /* IBM XL C 1.02.0.0 rejects this. - It does not let you subtract one const X* pointer from another in - an arm of an if-expression whose if-part is not a constant - expression */ - const char *g = "string"; - pcpcc = &g + (g ? g-g : 0); - /* HPUX 7.0 cc rejects these. */ - ++pcpcc; - ppc = (char**) pcpcc; - pcpcc = (char const *const *) ppc; - { /* SCO 3.2v4 cc rejects this sort of thing. */ - char tx; - char *t = &tx; - char const *s = 0 ? (char *) 0 : (char const *) 0; - - *t++ = 0; - if (s) return 0; - } - { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ - int x[] = {25, 17}; - const int *foo = &x[0]; - ++foo; - } - { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ - typedef const int *iptr; - iptr p = 0; - ++p; - } - { /* IBM XL C 1.02.0.0 rejects this sort of thing, saying - "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ - struct s { int j; const int *ap[3]; } bx; - struct s *b = &bx; b->j = 5; - } - { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ - const int foo = 10; - if (!foo) return 0; - } - return !cs[0] && !zero.x; -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - ac_cv_c_const=yes -else $as_nop - ac_cv_c_const=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 -printf "%s\n" "$ac_cv_c_const" >&6; } -if test $ac_cv_c_const = no; then - -printf "%s\n" "#define const /**/" >>confdefs.h - -fi - -# la_TYPE_UID_T defaults to "int", which is incorrect for MinGW -# and MSVC. Use a customized version. -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5 -printf %s "checking for uid_t in sys/types.h... " >&6; } -if test ${la_cv_type_uid_t+y} -then : - printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "uid_t" >/dev/null 2>&1 -then : - la_cv_type_uid_t=yes -else $as_nop - la_cv_type_uid_t=no -fi -rm -rf conftest* - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $la_cv_type_uid_t" >&5 -printf "%s\n" "$la_cv_type_uid_t" >&6; } -if test $la_cv_type_uid_t = no; then - case $host in - *mingw*) def_uid_t=short ;; - *) def_uid_t=int ;; - esac - -printf "%s\n" "#define uid_t $def_uid_t" >>confdefs.h - - -printf "%s\n" "#define gid_t $def_uid_t" >>confdefs.h - -fi - -ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default" -if test "x$ac_cv_type_mode_t" = xyes -then : - -else $as_nop - -printf "%s\n" "#define mode_t int" >>confdefs.h - -fi - -# AC_TYPE_OFF_T defaults to "long", which limits us to 4GB files on -# most systems... default to "long long" instead. -ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default" -if test "x$ac_cv_type_off_t" = xyes -then : - -else $as_nop - -printf "%s\n" "#define off_t long long" >>confdefs.h - -fi - -ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" -if test "x$ac_cv_type_size_t" = xyes -then : - -else $as_nop - -printf "%s\n" "#define size_t unsigned int" >>confdefs.h - -fi - -ac_fn_c_check_type "$LINENO" "id_t" "ac_cv_type_id_t" "$ac_includes_default" -if test "x$ac_cv_type_id_t" = xyes -then : - -else $as_nop - -printf "%s\n" "#define id_t unsigned long" >>confdefs.h - -fi - -ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default" -if test "x$ac_cv_type_uintptr_t" = xyes -then : - -else $as_nop - -printf "%s\n" "#define uintptr_t unsigned int" >>confdefs.h - -fi - - -# Check for tm_gmtoff in struct tm -ac_fn_c_check_member "$LINENO" "struct tm" "tm_gmtoff" "ac_cv_member_struct_tm_tm_gmtoff" " -#include - -" -if test "x$ac_cv_member_struct_tm_tm_gmtoff" = xyes -then : - -printf "%s\n" "#define HAVE_STRUCT_TM_TM_GMTOFF 1" >>confdefs.h - - -fi -ac_fn_c_check_member "$LINENO" "struct tm" "__tm_gmtoff" "ac_cv_member_struct_tm___tm_gmtoff" " -#include - -" -if test "x$ac_cv_member_struct_tm___tm_gmtoff" = xyes -then : - -printf "%s\n" "#define HAVE_STRUCT_TM___TM_GMTOFF 1" >>confdefs.h - - -fi - - -# Check for f_namemax in struct statfs -ac_fn_c_check_member "$LINENO" "struct statfs" "f_namemax" "ac_cv_member_struct_statfs_f_namemax" " -#include -#include - -" -if test "x$ac_cv_member_struct_statfs_f_namemax" = xyes -then : - -printf "%s\n" "#define HAVE_STRUCT_STATFS_F_NAMEMAX 1" >>confdefs.h - - -fi - - -# Check for f_iosize in struct statfs -ac_fn_c_check_member "$LINENO" "struct statfs" "f_iosize" "ac_cv_member_struct_statfs_f_iosize" " -#include -#include - -" -if test "x$ac_cv_member_struct_statfs_f_iosize" = xyes -then : - -printf "%s\n" "#define HAVE_STRUCT_STATFS_F_IOSIZE 1" >>confdefs.h - - -fi - - -# Check for f_iosize in struct statvfs -ac_fn_c_check_member "$LINENO" "struct statvfs" "f_iosize" "ac_cv_member_struct_statvfs_f_iosize" " -#include - -" -if test "x$ac_cv_member_struct_statvfs_f_iosize" = xyes -then : - -printf "%s\n" "#define HAVE_STRUCT_STATVFS_F_IOSIZE 1" >>confdefs.h - - -fi - - -# Check for birthtime in struct stat -ac_fn_c_check_member "$LINENO" "struct stat" "st_birthtime" "ac_cv_member_struct_stat_st_birthtime" "$ac_includes_default" -if test "x$ac_cv_member_struct_stat_st_birthtime" = xyes -then : - -printf "%s\n" "#define HAVE_STRUCT_STAT_ST_BIRTHTIME 1" >>confdefs.h - - -fi - - -# Check for high-resolution timestamps in struct stat -ac_fn_c_check_member "$LINENO" "struct stat" "st_birthtimespec.tv_nsec" "ac_cv_member_struct_stat_st_birthtimespec_tv_nsec" "$ac_includes_default" -if test "x$ac_cv_member_struct_stat_st_birthtimespec_tv_nsec" = xyes -then : - -printf "%s\n" "#define HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC 1" >>confdefs.h - - -fi - -ac_fn_c_check_member "$LINENO" "struct stat" "st_mtimespec.tv_nsec" "ac_cv_member_struct_stat_st_mtimespec_tv_nsec" "$ac_includes_default" -if test "x$ac_cv_member_struct_stat_st_mtimespec_tv_nsec" = xyes -then : - -printf "%s\n" "#define HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC 1" >>confdefs.h - - -fi - -ac_fn_c_check_member "$LINENO" "struct stat" "st_mtim.tv_nsec" "ac_cv_member_struct_stat_st_mtim_tv_nsec" "$ac_includes_default" -if test "x$ac_cv_member_struct_stat_st_mtim_tv_nsec" = xyes -then : - -printf "%s\n" "#define HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 1" >>confdefs.h - - -fi - -ac_fn_c_check_member "$LINENO" "struct stat" "st_mtime_n" "ac_cv_member_struct_stat_st_mtime_n" "$ac_includes_default" -if test "x$ac_cv_member_struct_stat_st_mtime_n" = xyes -then : - -printf "%s\n" "#define HAVE_STRUCT_STAT_ST_MTIME_N 1" >>confdefs.h - - -fi - # AIX -ac_fn_c_check_member "$LINENO" "struct stat" "st_umtime" "ac_cv_member_struct_stat_st_umtime" "$ac_includes_default" -if test "x$ac_cv_member_struct_stat_st_umtime" = xyes -then : - -printf "%s\n" "#define HAVE_STRUCT_STAT_ST_UMTIME 1" >>confdefs.h - - -fi - # Tru64 -ac_fn_c_check_member "$LINENO" "struct stat" "st_mtime_usec" "ac_cv_member_struct_stat_st_mtime_usec" "$ac_includes_default" -if test "x$ac_cv_member_struct_stat_st_mtime_usec" = xyes -then : - -printf "%s\n" "#define HAVE_STRUCT_STAT_ST_MTIME_USEC 1" >>confdefs.h - - -fi - # Hurd -# Check for block size support in struct stat -ac_fn_c_check_member "$LINENO" "struct stat" "st_blksize" "ac_cv_member_struct_stat_st_blksize" "$ac_includes_default" -if test "x$ac_cv_member_struct_stat_st_blksize" = xyes -then : - -printf "%s\n" "#define HAVE_STRUCT_STAT_ST_BLKSIZE 1" >>confdefs.h - - -fi - -# Check for st_flags in struct stat (BSD fflags) -ac_fn_c_check_member "$LINENO" "struct stat" "st_flags" "ac_cv_member_struct_stat_st_flags" "$ac_includes_default" -if test "x$ac_cv_member_struct_stat_st_flags" = xyes -then : - -printf "%s\n" "#define HAVE_STRUCT_STAT_ST_FLAGS 1" >>confdefs.h - - -fi - - -# If you have uintmax_t, we assume printf supports %ju -# If you have unsigned long long, we assume printf supports %llu -# TODO: Check for %ju and %llu support directly. -ac_fn_c_check_type "$LINENO" "uintmax_t" "ac_cv_type_uintmax_t" "$ac_includes_default" -if test "x$ac_cv_type_uintmax_t" = xyes -then : - -printf "%s\n" "#define HAVE_UINTMAX_T 1" >>confdefs.h - - -fi -ac_fn_c_check_type "$LINENO" "unsigned long long" "ac_cv_type_unsigned_long_long" "$ac_includes_default" -if test "x$ac_cv_type_unsigned_long_long" = xyes -then : - -printf "%s\n" "#define HAVE_UNSIGNED_LONG_LONG 1" >>confdefs.h - - -fi - - -# We use C99-style integer types -# Declare them if the local platform doesn't already do so. - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for unsigned long long int" >&5 -printf %s "checking for unsigned long long int... " >&6; } -if test ${ac_cv_type_unsigned_long_long_int+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_cv_type_unsigned_long_long_int=yes - case $ac_prog_cc_stdc in - no | c89) ;; - *) - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - /* For now, do not test the preprocessor; as of 2007 there are too many - implementations with broken preprocessors. Perhaps this can - be revisited in 2012. In the meantime, code should not expect - #if to work with literals wider than 32 bits. */ - /* Test literals. */ - long long int ll = 9223372036854775807ll; - long long int nll = -9223372036854775807LL; - unsigned long long int ull = 18446744073709551615ULL; - /* Test constant expressions. */ - typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll) - ? 1 : -1)]; - typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1 - ? 1 : -1)]; - int i = 63; -int -main (void) -{ -/* Test availability of runtime routines for shift and division. */ - long long int llmax = 9223372036854775807ll; - unsigned long long int ullmax = 18446744073709551615ull; - return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i) - | (llmax / ll) | (llmax % ll) - | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i) - | (ullmax / ull) | (ullmax % ull)); - ; - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - -else $as_nop - ac_cv_type_unsigned_long_long_int=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext;; - esac -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_unsigned_long_long_int" >&5 -printf "%s\n" "$ac_cv_type_unsigned_long_long_int" >&6; } - if test $ac_cv_type_unsigned_long_long_int = yes; then - -printf "%s\n" "#define HAVE_UNSIGNED_LONG_LONG_INT 1" >>confdefs.h - - fi - - - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for long long int" >&5 -printf %s "checking for long long int... " >&6; } -if test ${ac_cv_type_long_long_int+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_cv_type_long_long_int=yes - case $ac_prog_cc_stdc in - no | c89) ;; - *) - ac_cv_type_long_long_int=$ac_cv_type_unsigned_long_long_int - if test $ac_cv_type_long_long_int = yes; then - if test "$cross_compiling" = yes -then : - : -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - #ifndef LLONG_MAX - # define HALF \ - (1LL << (sizeof (long long int) * CHAR_BIT - 2)) - # define LLONG_MAX (HALF - 1 + HALF) - #endif -int -main (void) -{ -long long int n = 1; - int i; - for (i = 0; ; i++) - { - long long int m = n << i; - if (m >> i != n) - return 1; - if (LLONG_MAX / 2 < m) - break; - } - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO" -then : - -else $as_nop - ac_cv_type_long_long_int=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - - fi;; - esac -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_long_int" >&5 -printf "%s\n" "$ac_cv_type_long_long_int" >&6; } - if test $ac_cv_type_long_long_int = yes; then - -printf "%s\n" "#define HAVE_LONG_LONG_INT 1" >>confdefs.h - - fi - - - - ac_fn_c_check_type "$LINENO" "intmax_t" "ac_cv_type_intmax_t" "$ac_includes_default" -if test "x$ac_cv_type_intmax_t" = xyes -then : - -printf "%s\n" "#define HAVE_INTMAX_T 1" >>confdefs.h - -else $as_nop - test $ac_cv_type_long_long_int = yes \ - && ac_type='long long int' \ - || ac_type='long int' - -printf "%s\n" "#define intmax_t $ac_type" >>confdefs.h - -fi - - - - - ac_fn_c_check_type "$LINENO" "uintmax_t" "ac_cv_type_uintmax_t" "$ac_includes_default" -if test "x$ac_cv_type_uintmax_t" = xyes -then : - -printf "%s\n" "#define HAVE_UINTMAX_T 1" >>confdefs.h - -else $as_nop - test $ac_cv_type_unsigned_long_long_int = yes \ - && ac_type='unsigned long long int' \ - || ac_type='unsigned long int' - -printf "%s\n" "#define uintmax_t $ac_type" >>confdefs.h - -fi - - -ac_fn_c_find_intX_t "$LINENO" "64" "ac_cv_c_int64_t" -case $ac_cv_c_int64_t in #( - no|yes) ;; #( - *) - -printf "%s\n" "#define int64_t $ac_cv_c_int64_t" >>confdefs.h -;; -esac - -ac_fn_c_find_uintX_t "$LINENO" "64" "ac_cv_c_uint64_t" -case $ac_cv_c_uint64_t in #( - no|yes) ;; #( - *) - -printf "%s\n" "#define _UINT64_T 1" >>confdefs.h - - -printf "%s\n" "#define uint64_t $ac_cv_c_uint64_t" >>confdefs.h -;; - esac - -ac_fn_c_find_intX_t "$LINENO" "32" "ac_cv_c_int32_t" -case $ac_cv_c_int32_t in #( - no|yes) ;; #( - *) - -printf "%s\n" "#define int32_t $ac_cv_c_int32_t" >>confdefs.h -;; -esac - -ac_fn_c_find_uintX_t "$LINENO" "32" "ac_cv_c_uint32_t" -case $ac_cv_c_uint32_t in #( - no|yes) ;; #( - *) - -printf "%s\n" "#define _UINT32_T 1" >>confdefs.h - - -printf "%s\n" "#define uint32_t $ac_cv_c_uint32_t" >>confdefs.h -;; - esac - -ac_fn_c_find_intX_t "$LINENO" "16" "ac_cv_c_int16_t" -case $ac_cv_c_int16_t in #( - no|yes) ;; #( - *) - -printf "%s\n" "#define int16_t $ac_cv_c_int16_t" >>confdefs.h -;; -esac - -ac_fn_c_find_uintX_t "$LINENO" "16" "ac_cv_c_uint16_t" -case $ac_cv_c_uint16_t in #( - no|yes) ;; #( - *) - - -printf "%s\n" "#define uint16_t $ac_cv_c_uint16_t" >>confdefs.h -;; - esac - -ac_fn_c_find_uintX_t "$LINENO" "8" "ac_cv_c_uint8_t" -case $ac_cv_c_uint8_t in #( - no|yes) ;; #( - *) - -printf "%s\n" "#define _UINT8_T 1" >>confdefs.h - - -printf "%s\n" "#define uint8_t $ac_cv_c_uint8_t" >>confdefs.h -;; - esac - - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC options needed to detect all undeclared functions" >&5 -printf %s "checking for $CC options needed to detect all undeclared functions... " >&6; } -if test ${ac_cv_c_undeclared_builtin_options+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_save_CFLAGS=$CFLAGS - ac_cv_c_undeclared_builtin_options='cannot detect' - for ac_arg in '' -fno-builtin; do - CFLAGS="$ac_save_CFLAGS $ac_arg" - # This test program should *not* compile successfully. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main (void) -{ -(void) strchr; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - -else $as_nop - # This test program should compile successfully. - # No library function is consistently available on - # freestanding implementations, so test against a dummy - # declaration. Include always-available headers on the - # off chance that they somehow elicit warnings. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -#include -extern void ac_decl (int, char *); - -int -main (void) -{ -(void) ac_decl (0, (char *) 0); - (void) ac_decl; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - if test x"$ac_arg" = x -then : - ac_cv_c_undeclared_builtin_options='none needed' -else $as_nop - ac_cv_c_undeclared_builtin_options=$ac_arg -fi - break -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - done - CFLAGS=$ac_save_CFLAGS - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_undeclared_builtin_options" >&5 -printf "%s\n" "$ac_cv_c_undeclared_builtin_options" >&6; } - case $ac_cv_c_undeclared_builtin_options in #( - 'cannot detect') : - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot make $CC report undeclared builtins -See \`config.log' for more details" "$LINENO" 5; } ;; #( - 'none needed') : - ac_c_undeclared_builtin_options='' ;; #( - *) : - ac_c_undeclared_builtin_options=$ac_cv_c_undeclared_builtin_options ;; -esac - -ac_fn_check_decl "$LINENO" "SIZE_MAX" "ac_cv_have_decl_SIZE_MAX" "$ac_includes_default" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_SIZE_MAX" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 -fi -printf "%s\n" "#define HAVE_DECL_SIZE_MAX $ac_have_decl" >>confdefs.h -ac_fn_check_decl "$LINENO" "INT32_MAX" "ac_cv_have_decl_INT32_MAX" "$ac_includes_default" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_INT32_MAX" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 -fi -printf "%s\n" "#define HAVE_DECL_INT32_MAX $ac_have_decl" >>confdefs.h -ac_fn_check_decl "$LINENO" "INT32_MIN" "ac_cv_have_decl_INT32_MIN" "$ac_includes_default" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_INT32_MIN" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 -fi -printf "%s\n" "#define HAVE_DECL_INT32_MIN $ac_have_decl" >>confdefs.h - -ac_fn_check_decl "$LINENO" "INT64_MAX" "ac_cv_have_decl_INT64_MAX" "$ac_includes_default" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_INT64_MAX" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 -fi -printf "%s\n" "#define HAVE_DECL_INT64_MAX $ac_have_decl" >>confdefs.h -ac_fn_check_decl "$LINENO" "INT64_MIN" "ac_cv_have_decl_INT64_MIN" "$ac_includes_default" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_INT64_MIN" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 -fi -printf "%s\n" "#define HAVE_DECL_INT64_MIN $ac_have_decl" >>confdefs.h -ac_fn_check_decl "$LINENO" "UINT64_MAX" "ac_cv_have_decl_UINT64_MAX" "$ac_includes_default" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_UINT64_MAX" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 -fi -printf "%s\n" "#define HAVE_DECL_UINT64_MAX $ac_have_decl" >>confdefs.h -ac_fn_check_decl "$LINENO" "UINT32_MAX" "ac_cv_have_decl_UINT32_MAX" "$ac_includes_default" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_UINT32_MAX" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 -fi -printf "%s\n" "#define HAVE_DECL_UINT32_MAX $ac_have_decl" >>confdefs.h - -ac_fn_check_decl "$LINENO" "INTMAX_MAX" "ac_cv_have_decl_INTMAX_MAX" "$ac_includes_default" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_INTMAX_MAX" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 -fi -printf "%s\n" "#define HAVE_DECL_INTMAX_MAX $ac_have_decl" >>confdefs.h -ac_fn_check_decl "$LINENO" "INTMAX_MIN" "ac_cv_have_decl_INTMAX_MIN" "$ac_includes_default" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_INTMAX_MIN" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 -fi -printf "%s\n" "#define HAVE_DECL_INTMAX_MIN $ac_have_decl" >>confdefs.h -ac_fn_check_decl "$LINENO" "UINTMAX_MAX" "ac_cv_have_decl_UINTMAX_MAX" "$ac_includes_default" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_UINTMAX_MAX" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 -fi -printf "%s\n" "#define HAVE_DECL_UINTMAX_MAX $ac_have_decl" >>confdefs.h - - -ac_fn_check_decl "$LINENO" "SSIZE_MAX" "ac_cv_have_decl_SSIZE_MAX" "#include -" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_SSIZE_MAX" = xyes -then : - -printf "%s\n" "#define HAVE_DECL_SSIZE_MAX 1" >>confdefs.h - -fi - -ac_fn_check_decl "$LINENO" "EFTYPE" "ac_cv_have_decl_EFTYPE" "#include -" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_EFTYPE" = xyes -then : - -printf "%s\n" "#define HAVE_EFTYPE 1" >>confdefs.h - -fi -ac_fn_check_decl "$LINENO" "EILSEQ" "ac_cv_have_decl_EILSEQ" "#include -" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_EILSEQ" = xyes -then : - -printf "%s\n" "#define HAVE_EILSEQ 1" >>confdefs.h - -fi -ac_fn_c_check_type "$LINENO" "wchar_t" "ac_cv_type_wchar_t" "$ac_includes_default" -if test "x$ac_cv_type_wchar_t" = xyes -then : - -printf "%s\n" "#define HAVE_WCHAR_T 1" >>confdefs.h - # The cast to long int works around a bug in the HP C Compiler -# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -# This bug is HP SR number 8606223364. -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of wchar_t" >&5 -printf %s "checking size of wchar_t... " >&6; } -if test ${ac_cv_sizeof_wchar_t+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (wchar_t))" "ac_cv_sizeof_wchar_t" "$ac_includes_default" -then : - -else $as_nop - if test "$ac_cv_type_wchar_t" = yes; then - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (wchar_t) -See \`config.log' for more details" "$LINENO" 5; } - else - ac_cv_sizeof_wchar_t=0 - fi -fi - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_wchar_t" >&5 -printf "%s\n" "$ac_cv_sizeof_wchar_t" >&6; } - - - -printf "%s\n" "#define SIZEOF_WCHAR_T $ac_cv_sizeof_wchar_t" >>confdefs.h - - -fi - - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 -printf %s "checking size of int... " >&6; } -if test ${ac_cv_sizeof_int+y} -then : - printf %s "(cached) " >&6 -else $as_nop - for ac_size in 4 8 1 2 16 ; do # List sizes in rough order of prevalence. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include - - -int -main (void) -{ -switch (0) case 0: case (sizeof (int) == $ac_size):; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - ac_cv_sizeof_int=$ac_size -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - if test x$ac_cv_sizeof_int != x ; then break; fi -done - -fi - -if test x$ac_cv_sizeof_int = x ; then - as_fn_error $? "cannot determine a size for int" "$LINENO" 5 -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 -printf "%s\n" "$ac_cv_sizeof_int" >&6; } - -printf "%s\n" "#define SIZEOF_INT $ac_cv_sizeof_int" >>confdefs.h - - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 -printf %s "checking size of long... " >&6; } -if test ${ac_cv_sizeof_long+y} -then : - printf %s "(cached) " >&6 -else $as_nop - for ac_size in 4 8 1 2 16 ; do # List sizes in rough order of prevalence. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include - - -int -main (void) -{ -switch (0) case 0: case (sizeof (long) == $ac_size):; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - ac_cv_sizeof_long=$ac_size -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - if test x$ac_cv_sizeof_long != x ; then break; fi -done - -fi - -if test x$ac_cv_sizeof_long = x ; then - as_fn_error $? "cannot determine a size for long" "$LINENO" 5 -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 -printf "%s\n" "$ac_cv_sizeof_long" >&6; } - -printf "%s\n" "#define SIZEOF_LONG $ac_cv_sizeof_long" >>confdefs.h - - - - - - -# Checks for library functions. -if test $ac_cv_c_compiler_gnu = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC needs -traditional" >&5 -printf %s "checking whether $CC needs -traditional... " >&6; } -if test ${ac_cv_prog_gcc_traditional+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_pattern="Autoconf.*'x'" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -Autoconf TIOCGETP -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "$ac_pattern" >/dev/null 2>&1 -then : - ac_cv_prog_gcc_traditional=yes -else $as_nop - ac_cv_prog_gcc_traditional=no -fi -rm -rf conftest* - - - if test $ac_cv_prog_gcc_traditional = no; then - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -Autoconf TCGETA -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "$ac_pattern" >/dev/null 2>&1 -then : - ac_cv_prog_gcc_traditional=yes -fi -rm -rf conftest* - - fi -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_gcc_traditional" >&5 -printf "%s\n" "$ac_cv_prog_gcc_traditional" >&6; } - if test $ac_cv_prog_gcc_traditional = yes; then - CC="$CC -traditional" - fi -fi - - -ac_fn_c_check_header_compile "$LINENO" "sys/mkdev.h" "ac_cv_header_sys_mkdev_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_mkdev_h" = xyes -then : - -printf "%s\n" "#define MAJOR_IN_MKDEV 1" >>confdefs.h - -fi - -if test $ac_cv_header_sys_mkdev_h = no; then - ac_fn_c_check_header_compile "$LINENO" "sys/sysmacros.h" "ac_cv_header_sys_sysmacros_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_sysmacros_h" = xyes -then : - -printf "%s\n" "#define MAJOR_IN_SYSMACROS 1" >>confdefs.h - -fi - -fi - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE value needed for large files" >&5 -printf %s "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; } -if test ${ac_cv_sys_largefile_source+y} -then : - printf %s "(cached) " >&6 -else $as_nop - while :; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include /* for off_t */ - #include -int -main (void) -{ -int (*fp) (FILE *, off_t, int) = fseeko; - return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_sys_largefile_source=no; break -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#define _LARGEFILE_SOURCE 1 -#include /* for off_t */ - #include -int -main (void) -{ -int (*fp) (FILE *, off_t, int) = fseeko; - return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_sys_largefile_source=1; break -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - ac_cv_sys_largefile_source=unknown - break -done -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_source" >&5 -printf "%s\n" "$ac_cv_sys_largefile_source" >&6; } -case $ac_cv_sys_largefile_source in #( - no | unknown) ;; - *) -printf "%s\n" "#define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source" >>confdefs.h -;; -esac -rm -rf conftest* - -# We used to try defining _XOPEN_SOURCE=500 too, to work around a bug -# in glibc 2.1.3, but that breaks too many other things. -# If you want fseeko and ftello with glibc, upgrade to a fixed glibc. -if test $ac_cv_sys_largefile_source != unknown; then - -printf "%s\n" "#define HAVE_FSEEKO 1" >>confdefs.h - -fi - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working memcmp" >&5 -printf %s "checking for working memcmp... " >&6; } -if test ${ac_cv_func_memcmp_working+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test "$cross_compiling" = yes -then : - ac_cv_func_memcmp_working=no -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -main (void) -{ - - /* Some versions of memcmp are not 8-bit clean. */ - char c0 = '\100', c1 = '\200', c2 = '\201'; - if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0) - return 1; - - /* The Next x86 OpenStep bug shows up only when comparing 16 bytes - or more and with at least one buffer not starting on a 4-byte boundary. - William Lewis provided this test program. */ - { - char foo[21]; - char bar[21]; - int i; - for (i = 0; i < 4; i++) - { - char *a = foo + i; - char *b = bar + i; - strcpy (a, "--------01111111"); - strcpy (b, "--------10000000"); - if (memcmp (a, b, 16) >= 0) - return 1; - } - return 0; - } - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO" -then : - ac_cv_func_memcmp_working=yes -else $as_nop - ac_cv_func_memcmp_working=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_memcmp_working" >&5 -printf "%s\n" "$ac_cv_func_memcmp_working" >&6; } -test $ac_cv_func_memcmp_working = no && case " $LIBOBJS " in - *" memcmp.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS memcmp.$ac_objext" - ;; -esac - - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether lstat correctly handles trailing slash" >&5 -printf %s "checking whether lstat correctly handles trailing slash... " >&6; } -if test ${ac_cv_func_lstat_dereferences_slashed_symlink+y} -then : - printf %s "(cached) " >&6 -else $as_nop - rm -f conftest.sym conftest.file -echo >conftest.file -if test "$as_ln_s" = "ln -s" && ln -s conftest.file conftest.sym; then - if test "$cross_compiling" = yes -then : - case "$host_os" in # (( - # Guess yes on glibc systems. - *-gnu*) ac_cv_func_lstat_dereferences_slashed_symlink=yes ;; - # If we don't know, assume the worst. - *) ac_cv_func_lstat_dereferences_slashed_symlink=no ;; - esac -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -main (void) -{ -struct stat sbuf; - /* Linux will dereference the symlink and fail, as required by POSIX. - That is better in the sense that it means we will not - have to compile and use the lstat wrapper. */ - return lstat ("conftest.sym/", &sbuf) == 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO" -then : - ac_cv_func_lstat_dereferences_slashed_symlink=yes -else $as_nop - ac_cv_func_lstat_dereferences_slashed_symlink=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -else - # If the `ln -s' command failed, then we probably don't even - # have an lstat function. - ac_cv_func_lstat_dereferences_slashed_symlink=no -fi -rm -f conftest.sym conftest.file - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_lstat_dereferences_slashed_symlink" >&5 -printf "%s\n" "$ac_cv_func_lstat_dereferences_slashed_symlink" >&6; } - -test $ac_cv_func_lstat_dereferences_slashed_symlink = yes && - -printf "%s\n" "#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1" >>confdefs.h - - -if test "x$ac_cv_func_lstat_dereferences_slashed_symlink" = xno; then - case " $LIBOBJS " in - *" lstat.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS lstat.$ac_objext" - ;; -esac - -fi - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether lstat accepts an empty string" >&5 -printf %s "checking whether lstat accepts an empty string... " >&6; } -if test ${ac_cv_func_lstat_empty_string_bug+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test "$cross_compiling" = yes -then : - ac_cv_func_lstat_empty_string_bug=yes -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -main (void) -{ -struct stat sbuf; - return lstat ("", &sbuf) == 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO" -then : - ac_cv_func_lstat_empty_string_bug=no -else $as_nop - ac_cv_func_lstat_empty_string_bug=yes -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_lstat_empty_string_bug" >&5 -printf "%s\n" "$ac_cv_func_lstat_empty_string_bug" >&6; } -if test $ac_cv_func_lstat_empty_string_bug = yes; then - case " $LIBOBJS " in - *" lstat.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS lstat.$ac_objext" - ;; -esac - - -printf "%s\n" "#define HAVE_LSTAT_EMPTY_STRING_BUG 1" >>confdefs.h - -fi - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether stat accepts an empty string" >&5 -printf %s "checking whether stat accepts an empty string... " >&6; } -if test ${ac_cv_func_stat_empty_string_bug+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test "$cross_compiling" = yes -then : - ac_cv_func_stat_empty_string_bug=yes -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -main (void) -{ -struct stat sbuf; - return stat ("", &sbuf) == 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO" -then : - ac_cv_func_stat_empty_string_bug=no -else $as_nop - ac_cv_func_stat_empty_string_bug=yes -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_stat_empty_string_bug" >&5 -printf "%s\n" "$ac_cv_func_stat_empty_string_bug" >&6; } -if test $ac_cv_func_stat_empty_string_bug = yes; then - case " $LIBOBJS " in - *" stat.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS stat.$ac_objext" - ;; -esac - - -printf "%s\n" "#define HAVE_STAT_EMPTY_STRING_BUG 1" >>confdefs.h - -fi - -ac_fn_check_decl "$LINENO" "strerror_r" "ac_cv_have_decl_strerror_r" "$ac_includes_default" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_strerror_r" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 -fi -printf "%s\n" "#define HAVE_DECL_STRERROR_R $ac_have_decl" >>confdefs.h - - -if test $ac_cv_have_decl_strerror_r = yes; then - # For backward compatibility's sake, define HAVE_STRERROR_R. - # (We used to run AC_CHECK_FUNCS_ONCE for strerror_r, as well - # as AC_CHECK_DECLS_ONCE.) - -printf "%s\n" "#define HAVE_STRERROR_R 1" >>confdefs.h - -fi - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether strerror_r returns char *" >&5 -printf %s "checking whether strerror_r returns char *... " >&6; } -if test ${ac_cv_func_strerror_r_char_p+y} -then : - printf %s "(cached) " >&6 -else $as_nop - - ac_cv_func_strerror_r_char_p=no - if test $ac_cv_have_decl_strerror_r = yes; then - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main (void) -{ - - char buf[100]; - char x = *strerror_r (0, buf, sizeof buf); - char *p = strerror_r (0, buf, sizeof buf); - return !p || x; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - ac_cv_func_strerror_r_char_p=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - - fi - -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_strerror_r_char_p" >&5 -printf "%s\n" "$ac_cv_func_strerror_r_char_p" >&6; } -if test $ac_cv_func_strerror_r_char_p = yes; then - -printf "%s\n" "#define STRERROR_R_CHAR_P 1" >>confdefs.h - -fi - - - for ac_func in strftime -do : - ac_fn_c_check_func "$LINENO" "strftime" "ac_cv_func_strftime" -if test "x$ac_cv_func_strftime" = xyes -then : - printf "%s\n" "#define HAVE_STRFTIME 1" >>confdefs.h - -else $as_nop - # strftime is in -lintl on SCO UNIX. -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for strftime in -lintl" >&5 -printf %s "checking for strftime in -lintl... " >&6; } -if test ${ac_cv_lib_intl_strftime+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-lintl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char strftime (); -int -main (void) -{ -return strftime (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_intl_strftime=yes -else $as_nop - ac_cv_lib_intl_strftime=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_strftime" >&5 -printf "%s\n" "$ac_cv_lib_intl_strftime" >&6; } -if test "x$ac_cv_lib_intl_strftime" = xyes -then : - printf "%s\n" "#define HAVE_STRFTIME 1" >>confdefs.h - -LIBS="-lintl $LIBS" -fi - -fi - -done -ac_func= -for ac_item in $ac_func_c_list -do - if test $ac_func; then - ac_fn_c_check_func "$LINENO" $ac_func ac_cv_func_$ac_func - if eval test \"x\$ac_cv_func_$ac_func\" = xyes; then - echo "#define $ac_item 1" >> confdefs.h - fi - ac_func= - else - ac_func=$ac_item - fi -done - -if test "x$ac_cv_func_vprintf" = xno -then : - ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt" -if test "x$ac_cv_func__doprnt" = xyes -then : - -printf "%s\n" "#define HAVE_DOPRNT 1" >>confdefs.h - -fi - -fi -# check for: -# CreateHardLinkA(LPCSTR, LPCSTR, LPSECURITY_ATTRIBUTES) -# To avoid necessity for including windows.h or special forward declaration -# workarounds, we use 'void *' for 'struct SECURITY_ATTRIBUTES *' -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for CreateHardLinkA" >&5 -printf %s "checking for CreateHardLinkA... " >&6; } -if test ${ac_cv_func_CreateHardLinkA+y} -then : - printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char __stdcall CreateHardLinkA ( const char *, const char *, void * ) below. */ -#include -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char __stdcall CreateHardLinkA ( const char *, const char *, void * ); -char (*f) ( const char *, const char *, void * ); - -int -main (void) -{ -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_CreateHardLinkA) || defined (__stub___CreateHardLinkA) -choke me -#else -f = CreateHardLinkA; -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_func_CreateHardLinkA=yes -else $as_nop - ac_cv_func_CreateHardLinkA=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_CreateHardLinkA" >&5 -printf "%s\n" "$ac_cv_func_CreateHardLinkA" >&6; } -if test $ac_cv_func_CreateHardLinkA = yes -then : - -fi -ac_fn_c_check_func "$LINENO" "arc4random_buf" "ac_cv_func_arc4random_buf" -if test "x$ac_cv_func_arc4random_buf" = xyes -then : - printf "%s\n" "#define HAVE_ARC4RANDOM_BUF 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "chflags" "ac_cv_func_chflags" -if test "x$ac_cv_func_chflags" = xyes -then : - printf "%s\n" "#define HAVE_CHFLAGS 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "chown" "ac_cv_func_chown" -if test "x$ac_cv_func_chown" = xyes -then : - printf "%s\n" "#define HAVE_CHOWN 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "chroot" "ac_cv_func_chroot" -if test "x$ac_cv_func_chroot" = xyes -then : - printf "%s\n" "#define HAVE_CHROOT 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "ctime_r" "ac_cv_func_ctime_r" -if test "x$ac_cv_func_ctime_r" = xyes -then : - printf "%s\n" "#define HAVE_CTIME_R 1" >>confdefs.h - -fi - -ac_fn_c_check_func "$LINENO" "fchdir" "ac_cv_func_fchdir" -if test "x$ac_cv_func_fchdir" = xyes -then : - printf "%s\n" "#define HAVE_FCHDIR 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "fchflags" "ac_cv_func_fchflags" -if test "x$ac_cv_func_fchflags" = xyes -then : - printf "%s\n" "#define HAVE_FCHFLAGS 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "fchmod" "ac_cv_func_fchmod" -if test "x$ac_cv_func_fchmod" = xyes -then : - printf "%s\n" "#define HAVE_FCHMOD 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "fchown" "ac_cv_func_fchown" -if test "x$ac_cv_func_fchown" = xyes -then : - printf "%s\n" "#define HAVE_FCHOWN 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "fcntl" "ac_cv_func_fcntl" -if test "x$ac_cv_func_fcntl" = xyes -then : - printf "%s\n" "#define HAVE_FCNTL 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "fdopendir" "ac_cv_func_fdopendir" -if test "x$ac_cv_func_fdopendir" = xyes -then : - printf "%s\n" "#define HAVE_FDOPENDIR 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "fnmatch" "ac_cv_func_fnmatch" -if test "x$ac_cv_func_fnmatch" = xyes -then : - printf "%s\n" "#define HAVE_FNMATCH 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "fork" "ac_cv_func_fork" -if test "x$ac_cv_func_fork" = xyes -then : - printf "%s\n" "#define HAVE_FORK 1" >>confdefs.h - -fi - -ac_fn_c_check_func "$LINENO" "fstat" "ac_cv_func_fstat" -if test "x$ac_cv_func_fstat" = xyes -then : - printf "%s\n" "#define HAVE_FSTAT 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "fstatat" "ac_cv_func_fstatat" -if test "x$ac_cv_func_fstatat" = xyes -then : - printf "%s\n" "#define HAVE_FSTATAT 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "fstatfs" "ac_cv_func_fstatfs" -if test "x$ac_cv_func_fstatfs" = xyes -then : - printf "%s\n" "#define HAVE_FSTATFS 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "fstatvfs" "ac_cv_func_fstatvfs" -if test "x$ac_cv_func_fstatvfs" = xyes -then : - printf "%s\n" "#define HAVE_FSTATVFS 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "ftruncate" "ac_cv_func_ftruncate" -if test "x$ac_cv_func_ftruncate" = xyes -then : - printf "%s\n" "#define HAVE_FTRUNCATE 1" >>confdefs.h - -fi - -ac_fn_c_check_func "$LINENO" "futimens" "ac_cv_func_futimens" -if test "x$ac_cv_func_futimens" = xyes -then : - printf "%s\n" "#define HAVE_FUTIMENS 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "futimes" "ac_cv_func_futimes" -if test "x$ac_cv_func_futimes" = xyes -then : - printf "%s\n" "#define HAVE_FUTIMES 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "futimesat" "ac_cv_func_futimesat" -if test "x$ac_cv_func_futimesat" = xyes -then : - printf "%s\n" "#define HAVE_FUTIMESAT 1" >>confdefs.h - -fi - -ac_fn_c_check_func "$LINENO" "geteuid" "ac_cv_func_geteuid" -if test "x$ac_cv_func_geteuid" = xyes -then : - printf "%s\n" "#define HAVE_GETEUID 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "getline" "ac_cv_func_getline" -if test "x$ac_cv_func_getline" = xyes -then : - printf "%s\n" "#define HAVE_GETLINE 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "getpid" "ac_cv_func_getpid" -if test "x$ac_cv_func_getpid" = xyes -then : - printf "%s\n" "#define HAVE_GETPID 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "getgrgid_r" "ac_cv_func_getgrgid_r" -if test "x$ac_cv_func_getgrgid_r" = xyes -then : - printf "%s\n" "#define HAVE_GETGRGID_R 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "getgrnam_r" "ac_cv_func_getgrnam_r" -if test "x$ac_cv_func_getgrnam_r" = xyes -then : - printf "%s\n" "#define HAVE_GETGRNAM_R 1" >>confdefs.h - -fi - -ac_fn_c_check_func "$LINENO" "getpwnam_r" "ac_cv_func_getpwnam_r" -if test "x$ac_cv_func_getpwnam_r" = xyes -then : - printf "%s\n" "#define HAVE_GETPWNAM_R 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "getpwuid_r" "ac_cv_func_getpwuid_r" -if test "x$ac_cv_func_getpwuid_r" = xyes -then : - printf "%s\n" "#define HAVE_GETPWUID_R 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "getvfsbyname" "ac_cv_func_getvfsbyname" -if test "x$ac_cv_func_getvfsbyname" = xyes -then : - printf "%s\n" "#define HAVE_GETVFSBYNAME 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "gmtime_r" "ac_cv_func_gmtime_r" -if test "x$ac_cv_func_gmtime_r" = xyes -then : - printf "%s\n" "#define HAVE_GMTIME_R 1" >>confdefs.h - -fi - -ac_fn_c_check_func "$LINENO" "lchflags" "ac_cv_func_lchflags" -if test "x$ac_cv_func_lchflags" = xyes -then : - printf "%s\n" "#define HAVE_LCHFLAGS 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "lchmod" "ac_cv_func_lchmod" -if test "x$ac_cv_func_lchmod" = xyes -then : - printf "%s\n" "#define HAVE_LCHMOD 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "lchown" "ac_cv_func_lchown" -if test "x$ac_cv_func_lchown" = xyes -then : - printf "%s\n" "#define HAVE_LCHOWN 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "link" "ac_cv_func_link" -if test "x$ac_cv_func_link" = xyes -then : - printf "%s\n" "#define HAVE_LINK 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "linkat" "ac_cv_func_linkat" -if test "x$ac_cv_func_linkat" = xyes -then : - printf "%s\n" "#define HAVE_LINKAT 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "localtime_r" "ac_cv_func_localtime_r" -if test "x$ac_cv_func_localtime_r" = xyes -then : - printf "%s\n" "#define HAVE_LOCALTIME_R 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "lstat" "ac_cv_func_lstat" -if test "x$ac_cv_func_lstat" = xyes -then : - printf "%s\n" "#define HAVE_LSTAT 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "lutimes" "ac_cv_func_lutimes" -if test "x$ac_cv_func_lutimes" = xyes -then : - printf "%s\n" "#define HAVE_LUTIMES 1" >>confdefs.h - -fi - -ac_fn_c_check_func "$LINENO" "mbrtowc" "ac_cv_func_mbrtowc" -if test "x$ac_cv_func_mbrtowc" = xyes -then : - printf "%s\n" "#define HAVE_MBRTOWC 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "memmove" "ac_cv_func_memmove" -if test "x$ac_cv_func_memmove" = xyes -then : - printf "%s\n" "#define HAVE_MEMMOVE 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "memset" "ac_cv_func_memset" -if test "x$ac_cv_func_memset" = xyes -then : - printf "%s\n" "#define HAVE_MEMSET 1" >>confdefs.h - -fi - -ac_fn_c_check_func "$LINENO" "mkdir" "ac_cv_func_mkdir" -if test "x$ac_cv_func_mkdir" = xyes -then : - printf "%s\n" "#define HAVE_MKDIR 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "mkfifo" "ac_cv_func_mkfifo" -if test "x$ac_cv_func_mkfifo" = xyes -then : - printf "%s\n" "#define HAVE_MKFIFO 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "mknod" "ac_cv_func_mknod" -if test "x$ac_cv_func_mknod" = xyes -then : - printf "%s\n" "#define HAVE_MKNOD 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "mkstemp" "ac_cv_func_mkstemp" -if test "x$ac_cv_func_mkstemp" = xyes -then : - printf "%s\n" "#define HAVE_MKSTEMP 1" >>confdefs.h - -fi - -ac_fn_c_check_func "$LINENO" "nl_langinfo" "ac_cv_func_nl_langinfo" -if test "x$ac_cv_func_nl_langinfo" = xyes -then : - printf "%s\n" "#define HAVE_NL_LANGINFO 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "openat" "ac_cv_func_openat" -if test "x$ac_cv_func_openat" = xyes -then : - printf "%s\n" "#define HAVE_OPENAT 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "pipe" "ac_cv_func_pipe" -if test "x$ac_cv_func_pipe" = xyes -then : - printf "%s\n" "#define HAVE_PIPE 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "poll" "ac_cv_func_poll" -if test "x$ac_cv_func_poll" = xyes -then : - printf "%s\n" "#define HAVE_POLL 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "posix_spawnp" "ac_cv_func_posix_spawnp" -if test "x$ac_cv_func_posix_spawnp" = xyes -then : - printf "%s\n" "#define HAVE_POSIX_SPAWNP 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "readlink" "ac_cv_func_readlink" -if test "x$ac_cv_func_readlink" = xyes -then : - printf "%s\n" "#define HAVE_READLINK 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "readlinkat" "ac_cv_func_readlinkat" -if test "x$ac_cv_func_readlinkat" = xyes -then : - printf "%s\n" "#define HAVE_READLINKAT 1" >>confdefs.h - -fi - -ac_fn_c_check_func "$LINENO" "readpassphrase" "ac_cv_func_readpassphrase" -if test "x$ac_cv_func_readpassphrase" = xyes -then : - printf "%s\n" "#define HAVE_READPASSPHRASE 1" >>confdefs.h - -fi - -ac_fn_c_check_func "$LINENO" "select" "ac_cv_func_select" -if test "x$ac_cv_func_select" = xyes -then : - printf "%s\n" "#define HAVE_SELECT 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "setenv" "ac_cv_func_setenv" -if test "x$ac_cv_func_setenv" = xyes -then : - printf "%s\n" "#define HAVE_SETENV 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "setlocale" "ac_cv_func_setlocale" -if test "x$ac_cv_func_setlocale" = xyes -then : - printf "%s\n" "#define HAVE_SETLOCALE 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "sigaction" "ac_cv_func_sigaction" -if test "x$ac_cv_func_sigaction" = xyes -then : - printf "%s\n" "#define HAVE_SIGACTION 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "statfs" "ac_cv_func_statfs" -if test "x$ac_cv_func_statfs" = xyes -then : - printf "%s\n" "#define HAVE_STATFS 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "statvfs" "ac_cv_func_statvfs" -if test "x$ac_cv_func_statvfs" = xyes -then : - printf "%s\n" "#define HAVE_STATVFS 1" >>confdefs.h - -fi - -ac_fn_c_check_func "$LINENO" "strchr" "ac_cv_func_strchr" -if test "x$ac_cv_func_strchr" = xyes -then : - printf "%s\n" "#define HAVE_STRCHR 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "strdup" "ac_cv_func_strdup" -if test "x$ac_cv_func_strdup" = xyes -then : - printf "%s\n" "#define HAVE_STRDUP 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "strerror" "ac_cv_func_strerror" -if test "x$ac_cv_func_strerror" = xyes -then : - printf "%s\n" "#define HAVE_STRERROR 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "strncpy_s" "ac_cv_func_strncpy_s" -if test "x$ac_cv_func_strncpy_s" = xyes -then : - printf "%s\n" "#define HAVE_STRNCPY_S 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "strnlen" "ac_cv_func_strnlen" -if test "x$ac_cv_func_strnlen" = xyes -then : - printf "%s\n" "#define HAVE_STRNLEN 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "strrchr" "ac_cv_func_strrchr" -if test "x$ac_cv_func_strrchr" = xyes -then : - printf "%s\n" "#define HAVE_STRRCHR 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "symlink" "ac_cv_func_symlink" -if test "x$ac_cv_func_symlink" = xyes -then : - printf "%s\n" "#define HAVE_SYMLINK 1" >>confdefs.h - -fi - -ac_fn_c_check_func "$LINENO" "timegm" "ac_cv_func_timegm" -if test "x$ac_cv_func_timegm" = xyes -then : - printf "%s\n" "#define HAVE_TIMEGM 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "tzset" "ac_cv_func_tzset" -if test "x$ac_cv_func_tzset" = xyes -then : - printf "%s\n" "#define HAVE_TZSET 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "unlinkat" "ac_cv_func_unlinkat" -if test "x$ac_cv_func_unlinkat" = xyes -then : - printf "%s\n" "#define HAVE_UNLINKAT 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "unsetenv" "ac_cv_func_unsetenv" -if test "x$ac_cv_func_unsetenv" = xyes -then : - printf "%s\n" "#define HAVE_UNSETENV 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "utime" "ac_cv_func_utime" -if test "x$ac_cv_func_utime" = xyes -then : - printf "%s\n" "#define HAVE_UTIME 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "utimensat" "ac_cv_func_utimensat" -if test "x$ac_cv_func_utimensat" = xyes -then : - printf "%s\n" "#define HAVE_UTIMENSAT 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "utimes" "ac_cv_func_utimes" -if test "x$ac_cv_func_utimes" = xyes -then : - printf "%s\n" "#define HAVE_UTIMES 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "vfork" "ac_cv_func_vfork" -if test "x$ac_cv_func_vfork" = xyes -then : - printf "%s\n" "#define HAVE_VFORK 1" >>confdefs.h - -fi - -ac_fn_c_check_func "$LINENO" "wcrtomb" "ac_cv_func_wcrtomb" -if test "x$ac_cv_func_wcrtomb" = xyes -then : - printf "%s\n" "#define HAVE_WCRTOMB 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "wcscmp" "ac_cv_func_wcscmp" -if test "x$ac_cv_func_wcscmp" = xyes -then : - printf "%s\n" "#define HAVE_WCSCMP 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "wcscpy" "ac_cv_func_wcscpy" -if test "x$ac_cv_func_wcscpy" = xyes -then : - printf "%s\n" "#define HAVE_WCSCPY 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "wcslen" "ac_cv_func_wcslen" -if test "x$ac_cv_func_wcslen" = xyes -then : - printf "%s\n" "#define HAVE_WCSLEN 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "wctomb" "ac_cv_func_wctomb" -if test "x$ac_cv_func_wctomb" = xyes -then : - printf "%s\n" "#define HAVE_WCTOMB 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "wmemcmp" "ac_cv_func_wmemcmp" -if test "x$ac_cv_func_wmemcmp" = xyes -then : - printf "%s\n" "#define HAVE_WMEMCMP 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "wmemcpy" "ac_cv_func_wmemcpy" -if test "x$ac_cv_func_wmemcpy" = xyes -then : - printf "%s\n" "#define HAVE_WMEMCPY 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "wmemmove" "ac_cv_func_wmemmove" -if test "x$ac_cv_func_wmemmove" = xyes -then : - printf "%s\n" "#define HAVE_WMEMMOVE 1" >>confdefs.h - -fi - -ac_fn_c_check_func "$LINENO" "_fseeki64" "ac_cv_func__fseeki64" -if test "x$ac_cv_func__fseeki64" = xyes -then : - printf "%s\n" "#define HAVE__FSEEKI64 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "_get_timezone" "ac_cv_func__get_timezone" -if test "x$ac_cv_func__get_timezone" = xyes -then : - printf "%s\n" "#define HAVE__GET_TIMEZONE 1" >>confdefs.h - -fi - -ac_fn_check_decl "$LINENO" "cmtime_s" "ac_cv_have_decl_cmtime_s" "#include -" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_cmtime_s" = xyes -then : - -printf "%s\n" "#define HAVE_CMTIME_S 1" >>confdefs.h - -fi -ac_fn_check_decl "$LINENO" "gmtime_s" "ac_cv_have_decl_gmtime_s" "#include -" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_gmtime_s" = xyes -then : - -printf "%s\n" "#define HAVE_GMTIME_S 1" >>confdefs.h - -fi -ac_fn_c_check_type "$LINENO" "localtime_s" "ac_cv_type_localtime_s" "#include -" -if test "x$ac_cv_type_localtime_s" = xyes -then : - -printf "%s\n" "#define HAVE_LOCALTIME_S 1" >>confdefs.h - -fi - -ac_fn_check_decl "$LINENO" "_mkgmtime" "ac_cv_have_decl__mkgmtime" "#include -" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl__mkgmtime" = xyes -then : - -printf "%s\n" "#define HAVE__MKGMTIME 1" >>confdefs.h - -fi - -# detects cygwin-1.7, as opposed to older versions -ac_fn_c_check_func "$LINENO" "cygwin_conv_path" "ac_cv_func_cygwin_conv_path" -if test "x$ac_cv_func_cygwin_conv_path" = xyes -then : - printf "%s\n" "#define HAVE_CYGWIN_CONV_PATH 1" >>confdefs.h - -fi - - -# DragonFly uses vfsconf, FreeBSD xvfsconf. -ac_fn_c_check_type "$LINENO" "struct vfsconf" "ac_cv_type_struct_vfsconf" "#if HAVE_SYS_TYPES_H - #include - #endif - #include - -" -if test "x$ac_cv_type_struct_vfsconf" = xyes -then : - -printf "%s\n" "#define HAVE_STRUCT_VFSCONF 1" >>confdefs.h - - -fi - - -ac_fn_c_check_type "$LINENO" "struct xvfsconf" "ac_cv_type_struct_xvfsconf" "#if HAVE_SYS_TYPES_H - #include - #endif - #include - -" -if test "x$ac_cv_type_struct_xvfsconf" = xyes -then : - -printf "%s\n" "#define HAVE_STRUCT_XVFSCONF 1" >>confdefs.h - - -fi - - -ac_fn_c_check_type "$LINENO" "struct statfs" "ac_cv_type_struct_statfs" "#if HAVE_SYS_TYPES_H - #include - #endif - #include - -" -if test "x$ac_cv_type_struct_statfs" = xyes -then : - -printf "%s\n" "#define HAVE_STRUCT_STATFS 1" >>confdefs.h - - -fi - - -# There are several variants of readdir_r around; we only -# accept the POSIX-compliant version. -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main (void) -{ -DIR *dir; struct dirent e, *r; - return(readdir_r(dir, &e, &r)); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - -printf "%s\n" "#define HAVE_READDIR_R 1" >>confdefs.h - - -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -# dirfd can be either a function or a macro. -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - DIR *dir; -int -main (void) -{ -return(dirfd(dir)); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - -printf "%s\n" "#define HAVE_DIRFD 1" >>confdefs.h - - -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - -# FreeBSD's nl_langinfo supports an option to specify whether the -# current locale uses month/day or day/month ordering. It makes the -# output a little prettier... -ac_fn_check_decl "$LINENO" "D_MD_ORDER" "ac_cv_have_decl_D_MD_ORDER" "#if HAVE_LANGINFO_H -#include -#endif - -" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_D_MD_ORDER" = xyes -then : - -printf "%s\n" "#define HAVE_D_MD_ORDER 1" >>confdefs.h - -fi - -# Check for dirent.d_namlen field explicitly -# (This is a bit more straightforward than, if not quite as portable as, -# the recipe given by the autoconf maintainers.) -ac_fn_c_check_member "$LINENO" "struct dirent" "d_namlen" "ac_cv_member_struct_dirent_d_namlen" "#if HAVE_DIRENT_H -#include -#endif - -" -if test "x$ac_cv_member_struct_dirent_d_namlen" = xyes -then : - -fi - - -# Check for Extended Attributes support -# Check whether --enable-xattr was given. -if test ${enable_xattr+y} -then : - enableval=$enable_xattr; -fi - - -if test "x$enable_xattr" != "xno"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing setxattr" >&5 -printf %s "checking for library containing setxattr... " >&6; } -if test ${ac_cv_search_setxattr+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char setxattr (); -int -main (void) -{ -return setxattr (); - ; - return 0; -} -_ACEOF -for ac_lib in '' attr gnu -do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO" -then : - ac_cv_search_setxattr=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext - if test ${ac_cv_search_setxattr+y} -then : - break -fi -done -if test ${ac_cv_search_setxattr+y} -then : - -else $as_nop - ac_cv_search_setxattr=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_setxattr" >&5 -printf "%s\n" "$ac_cv_search_setxattr" >&6; } -ac_res=$ac_cv_search_setxattr -if test "$ac_res" != no -then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - - ac_fn_check_decl "$LINENO" "EXTATTR_NAMESPACE_USER" "ac_cv_have_decl_EXTATTR_NAMESPACE_USER" "#include -#include - -" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_EXTATTR_NAMESPACE_USER" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 -fi -printf "%s\n" "#define HAVE_DECL_EXTATTR_NAMESPACE_USER $ac_have_decl" >>confdefs.h - - ac_fn_check_decl "$LINENO" "XATTR_NOFOLLOW" "ac_cv_have_decl_XATTR_NOFOLLOW" "#include - -" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_XATTR_NOFOLLOW" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 -fi -printf "%s\n" "#define HAVE_DECL_XATTR_NOFOLLOW $ac_have_decl" >>confdefs.h - - if test "x$ac_cv_header_sys_xattr_h" = "xyes" \ - -a "x$ac_cv_have_decl_XATTR_NOFOLLOW" = "xyes"; then - # Darwin extended attributes support - if test ${ac_cv_archive_xattr_darwin+y} -then : - printf %s "(cached) " >&6 -else $as_nop - - for ac_func in fgetxattr flistxattr fsetxattr getxattr listxattr setxattr -do : - as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes" -then : - cat >>confdefs.h <<_ACEOF -#define `printf "%s\n" "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - ac_cv_archive_xattr_darwin=yes -else $as_nop - ac_cv_archive_xattr_darwin=no -fi - -done - - -fi - - elif test "x$ac_cv_header_sys_extattr_h" = "xyes" \ - -a "x$ac_cv_have_decl_EXTATTR_NAMESPACE_USER" = "xyes"; then - # FreeBSD extended attributes support - if test ${ac_cv_archive_xattr_freebsd+y} -then : - printf %s "(cached) " >&6 -else $as_nop - - for ac_func in extattr_get_fd extattr_get_file extattr_get_link extattr_list_fd extattr_list_file extattr_list_link extattr_set_fd extattr_set_link -do : - as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes" -then : - cat >>confdefs.h <<_ACEOF -#define `printf "%s\n" "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - ac_cv_archive_xattr_freebsd=yes -else $as_nop - ac_cv_archive_xattr_freebsd=no -fi - -done - - -fi - - elif test "x$ac_cv_header_sys_xattr_h" = "xyes" \ - -o "x$ac_cv_header_attr_xattr_h" = "xyes"; then - # Linux extended attributes support - if test ${ac_cv_archive_xattr_linux+y} -then : - printf %s "(cached) " >&6 -else $as_nop - - for ac_func in fgetxattr flistxattr fsetxattr getxattr lgetxattr listxattr llistxattr lsetxattr -do : - as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes" -then : - cat >>confdefs.h <<_ACEOF -#define `printf "%s\n" "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - ac_cv_archive_xattr_linux=yes -else $as_nop - ac_cv_archive_xattr_linux=no -fi - -done - - -fi - - elif test "x$ac_cv_header_sys_ea_h" = "xyes"; then - # AIX extended attributes support - if test ${ac_cv_archive_xattr_aix+y} -then : - printf %s "(cached) " >&6 -else $as_nop - - for ac_func in fgetea flistea fsetea getea lgetea listea llistea lsetea -do : - as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes" -then : - cat >>confdefs.h <<_ACEOF -#define `printf "%s\n" "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - ac_cv_archive_xattr_aix=yes -else $as_nop - ac_cv_archive_xattr_aix=no -fi - -done - - -fi - - fi - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for extended attributes support" >&5 -printf %s "checking for extended attributes support... " >&6; } - if test "x$ac_cv_archive_xattr_linux" = "xyes"; then - -printf "%s\n" "#define ARCHIVE_XATTR_LINUX 1" >>confdefs.h - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Linux" >&5 -printf "%s\n" "Linux" >&6; } - elif test "x$ac_cv_archive_xattr_darwin" = "xyes"; then - -printf "%s\n" "#define ARCHIVE_XATTR_DARWIN 1" >>confdefs.h - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Darwin" >&5 -printf "%s\n" "Darwin" >&6; } - elif test "x$ac_cv_archive_xattr_freebsd" = "xyes"; then - -printf "%s\n" "#define ARCHIVE_XATTR_FREEBSD 1" >>confdefs.h - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: FreeBSD" >&5 -printf "%s\n" "FreeBSD" >&6; } - elif test "x$ac_cv_archive_xattr_aix" = "xyes"; then - -printf "%s\n" "#define ARCHIVE_XATTR_AIX 1" >>confdefs.h - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: AIX" >&5 -printf "%s\n" "AIX" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 -printf "%s\n" "none" >&6; } - fi -fi - -# Check for ACL support -# -# The ACL support in libarchive is written against the POSIX1e draft, -# which was never officially approved and varies quite a bit across -# platforms. Worse, some systems have completely non-POSIX acl functions, -# which makes the following checks rather more complex than I would like. -# -# Check whether --enable-acl was given. -if test ${enable_acl+y} -then : - enableval=$enable_acl; -fi - - -if test "x$enable_acl" != "xno"; then - # Libacl - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for acl_get_file in -lacl" >&5 -printf %s "checking for acl_get_file in -lacl... " >&6; } -if test ${ac_cv_lib_acl_acl_get_file+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-lacl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char acl_get_file (); -int -main (void) -{ -return acl_get_file (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_acl_acl_get_file=yes -else $as_nop - ac_cv_lib_acl_acl_get_file=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_acl_acl_get_file" >&5 -printf "%s\n" "$ac_cv_lib_acl_acl_get_file" >&6; } -if test "x$ac_cv_lib_acl_acl_get_file" = xyes -then : - printf "%s\n" "#define HAVE_LIBACL 1" >>confdefs.h - - LIBS="-lacl $LIBS" - -fi - - - ac_fn_c_check_type "$LINENO" "acl_t" "ac_cv_type_acl_t" " - #if HAVE_SYS_TYPES_H - #include - #endif - #if HAVE_SYS_ACL_H - #include - #endif - -" -if test "x$ac_cv_type_acl_t" = xyes -then : - -printf "%s\n" "#define HAVE_ACL_T 1" >>confdefs.h - - -fi -ac_fn_c_check_type "$LINENO" "acl_entry_t" "ac_cv_type_acl_entry_t" " - #if HAVE_SYS_TYPES_H - #include - #endif - #if HAVE_SYS_ACL_H - #include - #endif - -" -if test "x$ac_cv_type_acl_entry_t" = xyes -then : - -printf "%s\n" "#define HAVE_ACL_ENTRY_T 1" >>confdefs.h - - -fi -ac_fn_c_check_type "$LINENO" "acl_permset_t" "ac_cv_type_acl_permset_t" " - #if HAVE_SYS_TYPES_H - #include - #endif - #if HAVE_SYS_ACL_H - #include - #endif - -" -if test "x$ac_cv_type_acl_permset_t" = xyes -then : - -printf "%s\n" "#define HAVE_ACL_PERMSET_T 1" >>confdefs.h - - -fi -ac_fn_c_check_type "$LINENO" "acl_tag_t" "ac_cv_type_acl_tag_t" " - #if HAVE_SYS_TYPES_H - #include - #endif - #if HAVE_SYS_ACL_H - #include - #endif - -" -if test "x$ac_cv_type_acl_tag_t" = xyes -then : - -printf "%s\n" "#define HAVE_ACL_TAG_T 1" >>confdefs.h - - -fi - - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for richacl_get_file in -lrichacl" >&5 -printf %s "checking for richacl_get_file in -lrichacl... " >&6; } -if test ${ac_cv_lib_richacl_richacl_get_file+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-lrichacl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char richacl_get_file (); -int -main (void) -{ -return richacl_get_file (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_richacl_richacl_get_file=yes -else $as_nop - ac_cv_lib_richacl_richacl_get_file=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_richacl_richacl_get_file" >&5 -printf "%s\n" "$ac_cv_lib_richacl_richacl_get_file" >&6; } -if test "x$ac_cv_lib_richacl_richacl_get_file" = xyes -then : - printf "%s\n" "#define HAVE_LIBRICHACL 1" >>confdefs.h - - LIBS="-lrichacl $LIBS" - -fi - - - ac_fn_c_check_type "$LINENO" "struct richace" "ac_cv_type_struct_richace" " - #if HAVE_SYS_RICHACL_H - #include - #endif - -" -if test "x$ac_cv_type_struct_richace" = xyes -then : - -printf "%s\n" "#define HAVE_STRUCT_RICHACE 1" >>confdefs.h - - -fi -ac_fn_c_check_type "$LINENO" "struct richacl" "ac_cv_type_struct_richacl" " - #if HAVE_SYS_RICHACL_H - #include - #endif - -" -if test "x$ac_cv_type_struct_richacl" = xyes -then : - -printf "%s\n" "#define HAVE_STRUCT_RICHACL 1" >>confdefs.h - - -fi - - - # Solaris and derivates ACLs - ac_fn_c_check_func "$LINENO" "acl" "ac_cv_func_acl" -if test "x$ac_cv_func_acl" = xyes -then : - printf "%s\n" "#define HAVE_ACL 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "facl" "ac_cv_func_facl" -if test "x$ac_cv_func_facl" = xyes -then : - printf "%s\n" "#define HAVE_FACL 1" >>confdefs.h - -fi - - - if test "x$ac_cv_lib_richacl_richacl_get_file" = "xyes" \ - -a "x$ac_cv_type_struct_richace" = "xyes" \ - -a "x$ac_cv_type_struct_richacl" = "xyes"; then - if test ${ac_cv_archive_acl_librichacl+y} -then : - printf %s "(cached) " >&6 -else $as_nop - - for ac_func in richacl_alloc richacl_equiv_mode richacl_free richacl_get_fd richacl_get_file richacl_set_fd richacl_set_file -do : - as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes" -then : - cat >>confdefs.h <<_ACEOF -#define `printf "%s\n" "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - ac_cv_archive_acl_librichacl=yes -else $as_nop - ac_cv_archive_acl_librichacl=no -fi - -done -fi - - fi - - if test "x$ac_cv_func_acl" = "xyes" \ - -a "x$ac_cv_func_facl" = "xyes"; then - ac_fn_c_check_type "$LINENO" "aclent_t" "ac_cv_type_aclent_t" "#include -" -if test "x$ac_cv_type_aclent_t" = xyes -then : - -printf "%s\n" "#define HAVE_ACLENT_T 1" >>confdefs.h - - -fi - - if test "x$ac_cv_type_aclent_t" = "xyes"; then - if test ${ac_cv_archive_acl_sunos+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_fn_check_decl "$LINENO" "GETACL" "ac_cv_have_decl_GETACL" "#include -" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_GETACL" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 -fi -printf "%s\n" "#define HAVE_DECL_GETACL $ac_have_decl" >>confdefs.h -if test $ac_have_decl = 1 -then : - ac_cv_archive_acl_sunos=yes -else $as_nop - ac_cv_archive_acl_sunos=no -fi -ac_fn_check_decl "$LINENO" "SETACL" "ac_cv_have_decl_SETACL" "#include -" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_SETACL" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 -fi -printf "%s\n" "#define HAVE_DECL_SETACL $ac_have_decl" >>confdefs.h -if test $ac_have_decl = 1 -then : - ac_cv_archive_acl_sunos=yes -else $as_nop - ac_cv_archive_acl_sunos=no -fi -ac_fn_check_decl "$LINENO" "GETACLCNT" "ac_cv_have_decl_GETACLCNT" "#include -" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_GETACLCNT" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 -fi -printf "%s\n" "#define HAVE_DECL_GETACLCNT $ac_have_decl" >>confdefs.h -if test $ac_have_decl = 1 -then : - ac_cv_archive_acl_sunos=yes -else $as_nop - ac_cv_archive_acl_sunos=no -fi - -fi - - ac_fn_c_check_type "$LINENO" "ace_t" "ac_cv_type_ace_t" "#include -" -if test "x$ac_cv_type_ace_t" = xyes -then : - -printf "%s\n" "#define HAVE_ACE_T 1" >>confdefs.h - - -fi - - if test "x$ac_cv_type_ace_t" = "xyes"; then - if test ${ac_cv_archive_acl_sunos_nfs4+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_fn_check_decl "$LINENO" "ACE_GETACL" "ac_cv_have_decl_ACE_GETACL" "#include -" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_ACE_GETACL" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 -fi -printf "%s\n" "#define HAVE_DECL_ACE_GETACL $ac_have_decl" >>confdefs.h -if test $ac_have_decl = 1 -then : - ac_cv_archive_acl_sunos_nfs4=yes -else $as_nop - ac_cv_archive_acl_sonos_nfs4=no -fi -ac_fn_check_decl "$LINENO" "ACE_SETACL" "ac_cv_have_decl_ACE_SETACL" "#include -" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_ACE_SETACL" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 -fi -printf "%s\n" "#define HAVE_DECL_ACE_SETACL $ac_have_decl" >>confdefs.h -if test $ac_have_decl = 1 -then : - ac_cv_archive_acl_sunos_nfs4=yes -else $as_nop - ac_cv_archive_acl_sonos_nfs4=no -fi -ac_fn_check_decl "$LINENO" "ACE_GETACLCNT" "ac_cv_have_decl_ACE_GETACLCNT" "#include -" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_ACE_GETACLCNT" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 -fi -printf "%s\n" "#define HAVE_DECL_ACE_GETACLCNT $ac_have_decl" >>confdefs.h -if test $ac_have_decl = 1 -then : - ac_cv_archive_acl_sunos_nfs4=yes -else $as_nop - ac_cv_archive_acl_sonos_nfs4=no -fi - -fi - - fi - fi - elif test "x$ac_cv_type_acl_t" = "xyes" \ - -a "x$ac_cv_type_acl_entry_t" = "xyes" \ - -a "x$ac_cv_type_acl_permset_t" = "xyes" \ - -a "x$ac_cv_type_acl_tag_t" = "xyes"; then - # POSIX.1e ACL functions - if test ${ac_cv_posix_acl_funcs+y} -then : - printf %s "(cached) " >&6 -else $as_nop - - for ac_func in acl_add_perm acl_clear_perms acl_create_entry acl_delete_def_file acl_free acl_get_entry acl_get_fd acl_get_file acl_get_permset acl_get_qualifier acl_get_tag_type acl_init acl_set_fd acl_set_file acl_set_qualifier acl_set_tag_type -do : - as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes" -then : - cat >>confdefs.h <<_ACEOF -#define `printf "%s\n" "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - ac_cv_posix_acl_funcs=yes -else $as_nop - ac_cv_posix_acl_funcs=no -fi - -done - -fi - - - ac_fn_c_check_func "$LINENO" "acl_get_perm" "ac_cv_func_acl_get_perm" -if test "x$ac_cv_func_acl_get_perm" = xyes -then : - printf "%s\n" "#define HAVE_ACL_GET_PERM 1" >>confdefs.h - -fi - - - if test "x$ac_cv_posix_acl_funcs" = "xyes" \ - -a "x$ac_cv_header_acl_libacl_h" = "xyes" \ - -a "x$ac_cv_lib_acl_acl_get_file" = "xyes" \ - -a "x$ac_cv_func_acl_get_perm"; then - if test ${ac_cv_archive_acl_libacl+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_cv_archive_acl_libacl=yes -fi - - -printf "%s\n" "#define ARCHIVE_ACL_LIBACL 1" >>confdefs.h - - else - # FreeBSD/Darwin - ac_fn_c_check_func "$LINENO" "acl_add_flag_np" "ac_cv_func_acl_add_flag_np" -if test "x$ac_cv_func_acl_add_flag_np" = xyes -then : - printf "%s\n" "#define HAVE_ACL_ADD_FLAG_NP 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "acl_clear_flags_np" "ac_cv_func_acl_clear_flags_np" -if test "x$ac_cv_func_acl_clear_flags_np" = xyes -then : - printf "%s\n" "#define HAVE_ACL_CLEAR_FLAGS_NP 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "acl_get_brand_np" "ac_cv_func_acl_get_brand_np" -if test "x$ac_cv_func_acl_get_brand_np" = xyes -then : - printf "%s\n" "#define HAVE_ACL_GET_BRAND_NP 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "acl_get_entry_type_np" "ac_cv_func_acl_get_entry_type_np" -if test "x$ac_cv_func_acl_get_entry_type_np" = xyes -then : - printf "%s\n" "#define HAVE_ACL_GET_ENTRY_TYPE_NP 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "acl_get_flag_np" "ac_cv_func_acl_get_flag_np" -if test "x$ac_cv_func_acl_get_flag_np" = xyes -then : - printf "%s\n" "#define HAVE_ACL_GET_FLAG_NP 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "acl_get_flagset_np" "ac_cv_func_acl_get_flagset_np" -if test "x$ac_cv_func_acl_get_flagset_np" = xyes -then : - printf "%s\n" "#define HAVE_ACL_GET_FLAGSET_NP 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "acl_get_fd_np" "ac_cv_func_acl_get_fd_np" -if test "x$ac_cv_func_acl_get_fd_np" = xyes -then : - printf "%s\n" "#define HAVE_ACL_GET_FD_NP 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "acl_get_link_np" "ac_cv_func_acl_get_link_np" -if test "x$ac_cv_func_acl_get_link_np" = xyes -then : - printf "%s\n" "#define HAVE_ACL_GET_LINK_NP 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "acl_get_perm_np" "ac_cv_func_acl_get_perm_np" -if test "x$ac_cv_func_acl_get_perm_np" = xyes -then : - printf "%s\n" "#define HAVE_ACL_GET_PERM_NP 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "acl_is_trivial_np" "ac_cv_func_acl_is_trivial_np" -if test "x$ac_cv_func_acl_is_trivial_np" = xyes -then : - printf "%s\n" "#define HAVE_ACL_IS_TRIVIAL_NP 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "acl_set_entry_type_np" "ac_cv_func_acl_set_entry_type_np" -if test "x$ac_cv_func_acl_set_entry_type_np" = xyes -then : - printf "%s\n" "#define HAVE_ACL_SET_ENTRY_TYPE_NP 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "acl_set_fd_np" "ac_cv_func_acl_set_fd_np" -if test "x$ac_cv_func_acl_set_fd_np" = xyes -then : - printf "%s\n" "#define HAVE_ACL_SET_FD_NP 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "acl_set_link_np" "ac_cv_func_acl_set_link_np" -if test "x$ac_cv_func_acl_set_link_np" = xyes -then : - printf "%s\n" "#define HAVE_ACL_SET_LINK_NP 1" >>confdefs.h - -fi - - - ac_fn_c_check_func "$LINENO" "mbr_uid_to_uuid" "ac_cv_func_mbr_uid_to_uuid" -if test "x$ac_cv_func_mbr_uid_to_uuid" = xyes -then : - printf "%s\n" "#define HAVE_MBR_UID_TO_UUID 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "mbr_uuid_to_id" "ac_cv_func_mbr_uuid_to_id" -if test "x$ac_cv_func_mbr_uuid_to_id" = xyes -then : - printf "%s\n" "#define HAVE_MBR_UUID_TO_ID 1" >>confdefs.h - -fi -ac_fn_c_check_func "$LINENO" "mbr_gid_to_uuid" "ac_cv_func_mbr_gid_to_uuid" -if test "x$ac_cv_func_mbr_gid_to_uuid" = xyes -then : - printf "%s\n" "#define HAVE_MBR_GID_TO_UUID 1" >>confdefs.h - -fi - - - ac_fn_check_decl "$LINENO" "ACL_TYPE_EXTENDED" "ac_cv_have_decl_ACL_TYPE_EXTENDED" "#include - #include -" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_ACL_TYPE_EXTENDED" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 -fi -printf "%s\n" "#define HAVE_DECL_ACL_TYPE_EXTENDED $ac_have_decl" >>confdefs.h -ac_fn_check_decl "$LINENO" "ACL_TYPE_NFS4" "ac_cv_have_decl_ACL_TYPE_NFS4" "#include - #include -" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_ACL_TYPE_NFS4" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 -fi -printf "%s\n" "#define HAVE_DECL_ACL_TYPE_NFS4 $ac_have_decl" >>confdefs.h -ac_fn_check_decl "$LINENO" "ACL_USER" "ac_cv_have_decl_ACL_USER" "#include - #include -" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_ACL_USER" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 -fi -printf "%s\n" "#define HAVE_DECL_ACL_USER $ac_have_decl" >>confdefs.h -ac_fn_check_decl "$LINENO" "ACL_SYNCHRONIZE" "ac_cv_have_decl_ACL_SYNCHRONIZE" "#include - #include -" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_ACL_SYNCHRONIZE" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 -fi -printf "%s\n" "#define HAVE_DECL_ACL_SYNCHRONIZE $ac_have_decl" >>confdefs.h - - if test "x$ac_cv_posix_acl_funcs" = "xyes" \ - -a "x$ac_cv_func_acl_get_fd_np" = "xyes" \ - -a "x$ac_cv_func_acl_get_perm" != "xyes" \ - -a "x$ac_cv_func_acl_get_perm_np" = "xyes" \ - -a "x$ac_cv_func_acl_set_fd_np" = "xyes"; then - if test "x$ac_cv_have_decl_ACL_USER" = "xyes"; then - if test ${ac_cv_archive_acl_freebsd+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_cv_archive_acl_freebsd=yes -fi - - if test "x$ac_cv_have_decl_ACL_TYPE_NFS4" = "xyes" \ - -a "x$ac_cv_func_acl_add_flag_np" = "xyes" \ - -a "x$ac_cv_func_acl_get_brand_np" = "xyes" \ - -a "x$ac_cv_func_acl_get_entry_type_np" = "xyes" \ - -a "x$ac_cv_func_acl_get_flagset_np" = "xyes" \ - -a "x$ac_cv_func_acl_set_entry_type_np" = "xyes"; then - if test ${ac_cv_archive_acl_freebsd_nfs4+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_cv_archive_acl_freebsd_nfs4=yes -fi - - fi - elif test "x$ac_cv_have_decl_ACL_TYPE_EXTENDED" = "xyes" \ - -a "x$ac_cv_func_acl_add_flag_np" = "xyes" \ - -a "x$ac_cv_func_acl_get_flagset_np" = "xyes" \ - -a "x$ac_cv_func_acl_get_link_np" = "xyes" \ - -a "x$ac_cv_func_acl_set_link_np" = "xyes" \ - -a "x$ac_cv_func_mbr_uid_to_uuid" = "xyes" \ - -a "x$ac_cv_func_mbr_uuid_to_id" = "xyes" \ - -a "x$ac_cv_func_mbr_gid_to_uuid" = "xyes"; then - if test ${ac_cv_archive_acl_darwin+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_cv_archive_acl_darwin=yes -fi - - fi - fi - fi - fi - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ACL support" >&5 -printf %s "checking for ACL support... " >&6; } - if test "x$ac_cv_archive_acl_libacl" = "xyes" \ - -a "x$ac_cv_archive_acl_librichacl" = "xyes"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: libacl (POSIX.1e) + librichacl (NFSv4)" >&5 -printf "%s\n" "libacl (POSIX.1e) + librichacl (NFSv4)" >&6; } - -printf "%s\n" "#define ARCHIVE_ACL_LIBACL 1" >>confdefs.h - - -printf "%s\n" "#define ARCHIVE_ACL_LIBRICHACL 1" >>confdefs.h - - elif test "x$ac_cv_archive_acl_libacl" = "xyes"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: libacl (POSIX.1e)" >&5 -printf "%s\n" "libacl (POSIX.1e)" >&6; } - -printf "%s\n" "#define ARCHIVE_ACL_LIBACL 1" >>confdefs.h - - elif test "x$ac_cv_archive_acl_librichacl" = "xyes"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: librichacl (NFSv4)" >&5 -printf "%s\n" "librichacl (NFSv4)" >&6; } - -printf "%s\n" "#define ARCHIVE_ACL_LIBRICHACL 1" >>confdefs.h - - elif test "x$ac_cv_archive_acl_darwin" = "xyes"; then - -printf "%s\n" "#define ARCHIVE_ACL_DARWIN 1" >>confdefs.h - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Darwin (limited NFSv4)" >&5 -printf "%s\n" "Darwin (limited NFSv4)" >&6; } - elif test "x$ac_cv_archive_acl_sunos" = "xyes"; then - -printf "%s\n" "#define ARCHIVE_ACL_SUNOS 1" >>confdefs.h - - if test "x$ac_cv_archive_acl_sunos_nfs4" = "xyes"; then - -printf "%s\n" "#define ARCHIVE_ACL_SUNOS_NFS4 1" >>confdefs.h - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Solaris (POSIX.1e and NFSv4)" >&5 -printf "%s\n" "Solaris (POSIX.1e and NFSv4)" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Solaris (POSIX.1e)" >&5 -printf "%s\n" "Solaris (POSIX.1e)" >&6; } - fi - elif test "x$ac_cv_archive_acl_freebsd" = "xyes"; then - -printf "%s\n" "#define ARCHIVE_ACL_FREEBSD 1" >>confdefs.h - - if test "x$ac_cv_archive_acl_freebsd_nfs4" = "xyes"; then - -printf "%s\n" "#define ARCHIVE_ACL_FREEBSD_NFS4 1" >>confdefs.h - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: FreeBSD (POSIX.1e and NFSv4)" >&5 -printf "%s\n" "FreeBSD (POSIX.1e and NFSv4)" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: FreeBSD (POSIX.1e)" >&5 -printf "%s\n" "FreeBSD (POSIX.1e)" >&6; } - fi - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 -printf "%s\n" "none" >&6; } - fi -fi - - - if test "x$ac_cv_archive_acl_libacl" = "xyes" \ - -o "x$ac_cv_archive_acl_librichacl" = "xyes"; then - INC_LINUX_ACL_TRUE= - INC_LINUX_ACL_FALSE='#' -else - INC_LINUX_ACL_TRUE='#' - INC_LINUX_ACL_FALSE= -fi - - if test "x$ac_cv_archive_acl_sunos" = "xyes"; then - INC_SUNOS_ACL_TRUE= - INC_SUNOS_ACL_FALSE='#' -else - INC_SUNOS_ACL_TRUE='#' - INC_SUNOS_ACL_FALSE= -fi - - if test "x$ac_cv_archive_acl_darwin" = "xyes"; then - INC_DARWIN_ACL_TRUE= - INC_DARWIN_ACL_FALSE='#' -else - INC_DARWIN_ACL_TRUE='#' - INC_DARWIN_ACL_FALSE= -fi - - if test "x$ac_cv_archive_acl_freebsd" = "xyes"; then - INC_FREEBSD_ACL_TRUE= - INC_FREEBSD_ACL_FALSE='#' -else - INC_FREEBSD_ACL_TRUE='#' - INC_FREEBSD_ACL_FALSE= -fi - - -# Additional requirements -# Check whether --enable-largefile was given. -if test ${enable_largefile+y} -then : - enableval=$enable_largefile; -fi - -if test "$enable_largefile" != no; then - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 -printf %s "checking for special C compiler options needed for large files... " >&6; } -if test ${ac_cv_sys_largefile_CC+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_cv_sys_largefile_CC=no - if test "$GCC" != yes; then - ac_save_CC=$CC - while :; do - # IRIX 6.2 and later do not support large files by default, - # so use the C compiler's -n32 option if that helps. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main (void) -{ - - ; - return 0; -} -_ACEOF - if ac_fn_c_try_compile "$LINENO" -then : - break -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam - CC="$CC -n32" - if ac_fn_c_try_compile "$LINENO" -then : - ac_cv_sys_largefile_CC=' -n32'; break -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam - break - done - CC=$ac_save_CC - rm -f conftest.$ac_ext - fi -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 -printf "%s\n" "$ac_cv_sys_largefile_CC" >&6; } - if test "$ac_cv_sys_largefile_CC" != no; then - CC=$CC$ac_cv_sys_largefile_CC - fi - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 -printf %s "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } -if test ${ac_cv_sys_file_offset_bits+y} -then : - printf %s "(cached) " >&6 -else $as_nop - while :; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - ac_cv_sys_file_offset_bits=no; break -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#define _FILE_OFFSET_BITS 64 -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - ac_cv_sys_file_offset_bits=64; break -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - ac_cv_sys_file_offset_bits=unknown - break -done -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 -printf "%s\n" "$ac_cv_sys_file_offset_bits" >&6; } -case $ac_cv_sys_file_offset_bits in #( - no | unknown) ;; - *) -printf "%s\n" "#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits" >>confdefs.h -;; -esac -rm -rf conftest* - if test $ac_cv_sys_file_offset_bits = unknown; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 -printf %s "checking for _LARGE_FILES value needed for large files... " >&6; } -if test ${ac_cv_sys_large_files+y} -then : - printf %s "(cached) " >&6 -else $as_nop - while :; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - ac_cv_sys_large_files=no; break -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#define _LARGE_FILES 1 -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - ac_cv_sys_large_files=1; break -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - ac_cv_sys_large_files=unknown - break -done -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 -printf "%s\n" "$ac_cv_sys_large_files" >&6; } -case $ac_cv_sys_large_files in #( - no | unknown) ;; - *) -printf "%s\n" "#define _LARGE_FILES $ac_cv_sys_large_files" >>confdefs.h -;; -esac -rm -rf conftest* - fi -fi - - - - - - -case "$host_os" in - *mingw* | *cygwin* | *msys*) - ;; - *) - - if test "$found_MD5" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_MD5_LIBC" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_MD5_LIBC... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_MD5_COMPILE_TEST -#define ARCHIVE_CRYPTO_MD5_LIBC -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_md5_ctx ctx; - archive_md5_init(&ctx); - archive_md5_update(&ctx, *argv, argc); - archive_md5_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_MD5=yes - found_LIBC=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_MD5_LIBC 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_MD5" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_MD5_LIBSYSTEM" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_MD5_LIBSYSTEM... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_MD5_COMPILE_TEST -#define ARCHIVE_CRYPTO_MD5_LIBSYSTEM -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_md5_ctx ctx; - archive_md5_init(&ctx); - archive_md5_update(&ctx, *argv, argc); - archive_md5_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_MD5=yes - found_LIBSYSTEM=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_MD5_LIBSYSTEM 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_RMD160" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_RMD160_LIBC" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_RMD160_LIBC... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_RMD160_COMPILE_TEST -#define ARCHIVE_CRYPTO_RMD160_LIBC -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_rmd160_ctx ctx; - archive_rmd160_init(&ctx); - archive_rmd160_update(&ctx, *argv, argc); - archive_rmd160_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_RMD160=yes - found_LIBC=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_RMD160_LIBC 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA1" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA1_LIBC" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA1_LIBC... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA1_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA1_LIBC -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha1_ctx ctx; - archive_sha1_init(&ctx); - archive_sha1_update(&ctx, *argv, argc); - archive_sha1_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA1=yes - found_LIBC=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA1_LIBC 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA1" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA1_LIBSYSTEM" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA1_LIBSYSTEM... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA1_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA1_LIBSYSTEM -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha1_ctx ctx; - archive_sha1_init(&ctx); - archive_sha1_update(&ctx, *argv, argc); - archive_sha1_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA1=yes - found_LIBSYSTEM=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA1_LIBSYSTEM 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA256" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA256_LIBC" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA256_LIBC... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA256_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA256_LIBC -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha256_ctx ctx; - archive_sha256_init(&ctx); - archive_sha256_update(&ctx, *argv, argc); - archive_sha256_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA256=yes - found_LIBC=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA256_LIBC 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA256" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA256_LIBC2" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA256_LIBC2... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA256_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA256_LIBC2 -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha256_ctx ctx; - archive_sha256_init(&ctx); - archive_sha256_update(&ctx, *argv, argc); - archive_sha256_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA256=yes - found_LIBC2=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA256_LIBC2 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA256" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA256_LIBC3" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA256_LIBC3... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA256_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA256_LIBC3 -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha256_ctx ctx; - archive_sha256_init(&ctx); - archive_sha256_update(&ctx, *argv, argc); - archive_sha256_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA256=yes - found_LIBC3=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA256_LIBC3 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA256" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA256_LIBSYSTEM" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA256_LIBSYSTEM... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA256_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA256_LIBSYSTEM -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha256_ctx ctx; - archive_sha256_init(&ctx); - archive_sha256_update(&ctx, *argv, argc); - archive_sha256_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA256=yes - found_LIBSYSTEM=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA256_LIBSYSTEM 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA384" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA384_LIBC" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA384_LIBC... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA384_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA384_LIBC -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha384_ctx ctx; - archive_sha384_init(&ctx); - archive_sha384_update(&ctx, *argv, argc); - archive_sha384_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA384=yes - found_LIBC=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA384_LIBC 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA384" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA384_LIBC2" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA384_LIBC2... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA384_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA384_LIBC2 -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha384_ctx ctx; - archive_sha384_init(&ctx); - archive_sha384_update(&ctx, *argv, argc); - archive_sha384_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA384=yes - found_LIBC2=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA384_LIBC2 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA384" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA384_LIBC3" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA384_LIBC3... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA384_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA384_LIBC3 -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha384_ctx ctx; - archive_sha384_init(&ctx); - archive_sha384_update(&ctx, *argv, argc); - archive_sha384_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA384=yes - found_LIBC3=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA384_LIBC3 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA384" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA384_LIBSYSTEM" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA384_LIBSYSTEM... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA384_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA384_LIBSYSTEM -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha384_ctx ctx; - archive_sha384_init(&ctx); - archive_sha384_update(&ctx, *argv, argc); - archive_sha384_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA384=yes - found_LIBSYSTEM=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA384_LIBSYSTEM 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA512" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA512_LIBC" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA512_LIBC... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA512_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA512_LIBC -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha512_ctx ctx; - archive_sha512_init(&ctx); - archive_sha512_update(&ctx, *argv, argc); - archive_sha512_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA512=yes - found_LIBC=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA512_LIBC 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA512" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA512_LIBC2" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA512_LIBC2... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA512_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA512_LIBC2 -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha512_ctx ctx; - archive_sha512_init(&ctx); - archive_sha512_update(&ctx, *argv, argc); - archive_sha512_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA512=yes - found_LIBC2=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA512_LIBC2 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA512" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA512_LIBC3" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA512_LIBC3... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA512_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA512_LIBC3 -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha512_ctx ctx; - archive_sha512_init(&ctx); - archive_sha512_update(&ctx, *argv, argc); - archive_sha512_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA512=yes - found_LIBC3=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA512_LIBC3 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA512" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA512_LIBSYSTEM" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA512_LIBSYSTEM... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA512_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA512_LIBSYSTEM -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha512_ctx ctx; - archive_sha512_init(&ctx); - archive_sha512_update(&ctx, *argv, argc); - archive_sha512_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA512=yes - found_LIBSYSTEM=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA512_LIBSYSTEM 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - ;; -esac - -if test "x$with_cng" != "xno"; then - for ac_header in bcrypt.h -do : - ac_fn_c_check_header_compile "$LINENO" "bcrypt.h" "ac_cv_header_bcrypt_h" "#ifdef HAVE_WINDOWS_H - # include - #endif - -" -if test "x$ac_cv_header_bcrypt_h" = xyes -then : - printf "%s\n" "#define HAVE_BCRYPT_H 1" >>confdefs.h - - LIBS="$LIBS -lbcrypt" - -fi - -done -fi - -if test "x$with_mbedtls" = "xyes"; then - ac_fn_c_check_header_compile "$LINENO" "mbedtls/aes.h" "ac_cv_header_mbedtls_aes_h" "$ac_includes_default" -if test "x$ac_cv_header_mbedtls_aes_h" = xyes -then : - printf "%s\n" "#define HAVE_MBEDTLS_AES_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "mbedtls/md.h" "ac_cv_header_mbedtls_md_h" "$ac_includes_default" -if test "x$ac_cv_header_mbedtls_md_h" = xyes -then : - printf "%s\n" "#define HAVE_MBEDTLS_MD_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "mbedtls/pkcs5.h" "ac_cv_header_mbedtls_pkcs5_h" "$ac_includes_default" -if test "x$ac_cv_header_mbedtls_pkcs5_h" = xyes -then : - printf "%s\n" "#define HAVE_MBEDTLS_PKCS5_H 1" >>confdefs.h - -fi - - saved_LIBS=$LIBS - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for mbedtls_sha1_init in -lmbedcrypto" >&5 -printf %s "checking for mbedtls_sha1_init in -lmbedcrypto... " >&6; } -if test ${ac_cv_lib_mbedcrypto_mbedtls_sha1_init+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-lmbedcrypto $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char mbedtls_sha1_init (); -int -main (void) -{ -return mbedtls_sha1_init (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_mbedcrypto_mbedtls_sha1_init=yes -else $as_nop - ac_cv_lib_mbedcrypto_mbedtls_sha1_init=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mbedcrypto_mbedtls_sha1_init" >&5 -printf "%s\n" "$ac_cv_lib_mbedcrypto_mbedtls_sha1_init" >&6; } -if test "x$ac_cv_lib_mbedcrypto_mbedtls_sha1_init" = xyes -then : - printf "%s\n" "#define HAVE_LIBMBEDCRYPTO 1" >>confdefs.h - - LIBS="-lmbedcrypto $LIBS" - -fi - - - if test "$found_MD5" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_MD5_MBEDTLS" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_MD5_MBEDTLS... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_MD5_COMPILE_TEST -#define ARCHIVE_CRYPTO_MD5_MBEDTLS -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_md5_ctx ctx; - archive_md5_init(&ctx); - archive_md5_update(&ctx, *argv, argc); - archive_md5_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_MD5=yes - found_MBEDTLS=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_MD5_MBEDTLS 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_RMD160" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_RMD160_MBEDTLS" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_RMD160_MBEDTLS... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_RMD160_COMPILE_TEST -#define ARCHIVE_CRYPTO_RMD160_MBEDTLS -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_rmd160_ctx ctx; - archive_rmd160_init(&ctx); - archive_rmd160_update(&ctx, *argv, argc); - archive_rmd160_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_RMD160=yes - found_MBEDTLS=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_RMD160_MBEDTLS 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA1" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA1_MBEDTLS" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA1_MBEDTLS... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA1_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA1_MBEDTLS -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha1_ctx ctx; - archive_sha1_init(&ctx); - archive_sha1_update(&ctx, *argv, argc); - archive_sha1_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA1=yes - found_MBEDTLS=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA1_MBEDTLS 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA256" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA256_MBEDTLS" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA256_MBEDTLS... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA256_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA256_MBEDTLS -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha256_ctx ctx; - archive_sha256_init(&ctx); - archive_sha256_update(&ctx, *argv, argc); - archive_sha256_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA256=yes - found_MBEDTLS=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA256_MBEDTLS 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA384" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA384_MBEDTLS" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA384_MBEDTLS... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA384_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA384_MBEDTLS -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha384_ctx ctx; - archive_sha384_init(&ctx); - archive_sha384_update(&ctx, *argv, argc); - archive_sha384_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA384=yes - found_MBEDTLS=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA384_MBEDTLS 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA512" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA512_MBEDTLS" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA512_MBEDTLS... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA512_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA512_MBEDTLS -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha512_ctx ctx; - archive_sha512_init(&ctx); - archive_sha512_update(&ctx, *argv, argc); - archive_sha512_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA512=yes - found_MBEDTLS=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA512_MBEDTLS 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - if test "x$found_MBEDTLS" != "xyes"; then - LIBS=$saved_LIBS - fi -fi - -if test "x$with_nettle" = "xyes"; then - ac_fn_c_check_header_compile "$LINENO" "nettle/md5.h" "ac_cv_header_nettle_md5_h" "$ac_includes_default" -if test "x$ac_cv_header_nettle_md5_h" = xyes -then : - printf "%s\n" "#define HAVE_NETTLE_MD5_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "nettle/ripemd160.h" "ac_cv_header_nettle_ripemd160_h" "$ac_includes_default" -if test "x$ac_cv_header_nettle_ripemd160_h" = xyes -then : - printf "%s\n" "#define HAVE_NETTLE_RIPEMD160_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "nettle/sha.h" "ac_cv_header_nettle_sha_h" "$ac_includes_default" -if test "x$ac_cv_header_nettle_sha_h" = xyes -then : - printf "%s\n" "#define HAVE_NETTLE_SHA_H 1" >>confdefs.h - -fi - - ac_fn_c_check_header_compile "$LINENO" "nettle/pbkdf2.h" "ac_cv_header_nettle_pbkdf2_h" "$ac_includes_default" -if test "x$ac_cv_header_nettle_pbkdf2_h" = xyes -then : - printf "%s\n" "#define HAVE_NETTLE_PBKDF2_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "nettle/aes.h" "ac_cv_header_nettle_aes_h" "$ac_includes_default" -if test "x$ac_cv_header_nettle_aes_h" = xyes -then : - printf "%s\n" "#define HAVE_NETTLE_AES_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "nettle/hmac.h" "ac_cv_header_nettle_hmac_h" "$ac_includes_default" -if test "x$ac_cv_header_nettle_hmac_h" = xyes -then : - printf "%s\n" "#define HAVE_NETTLE_HMAC_H 1" >>confdefs.h - -fi - - saved_LIBS=$LIBS - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for nettle_sha1_init in -lnettle" >&5 -printf %s "checking for nettle_sha1_init in -lnettle... " >&6; } -if test ${ac_cv_lib_nettle_nettle_sha1_init+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-lnettle $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char nettle_sha1_init (); -int -main (void) -{ -return nettle_sha1_init (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_nettle_nettle_sha1_init=yes -else $as_nop - ac_cv_lib_nettle_nettle_sha1_init=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nettle_nettle_sha1_init" >&5 -printf "%s\n" "$ac_cv_lib_nettle_nettle_sha1_init" >&6; } -if test "x$ac_cv_lib_nettle_nettle_sha1_init" = xyes -then : - printf "%s\n" "#define HAVE_LIBNETTLE 1" >>confdefs.h - - LIBS="-lnettle $LIBS" - -fi - - - if test "$found_MD5" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_MD5_NETTLE" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_MD5_NETTLE... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_MD5_COMPILE_TEST -#define ARCHIVE_CRYPTO_MD5_NETTLE -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_md5_ctx ctx; - archive_md5_init(&ctx); - archive_md5_update(&ctx, *argv, argc); - archive_md5_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_MD5=yes - found_NETTLE=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_MD5_NETTLE 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_RMD160" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_RMD160_NETTLE" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_RMD160_NETTLE... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_RMD160_COMPILE_TEST -#define ARCHIVE_CRYPTO_RMD160_NETTLE -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_rmd160_ctx ctx; - archive_rmd160_init(&ctx); - archive_rmd160_update(&ctx, *argv, argc); - archive_rmd160_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_RMD160=yes - found_NETTLE=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_RMD160_NETTLE 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA1" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA1_NETTLE" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA1_NETTLE... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA1_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA1_NETTLE -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha1_ctx ctx; - archive_sha1_init(&ctx); - archive_sha1_update(&ctx, *argv, argc); - archive_sha1_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA1=yes - found_NETTLE=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA1_NETTLE 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA256" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA256_NETTLE" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA256_NETTLE... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA256_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA256_NETTLE -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha256_ctx ctx; - archive_sha256_init(&ctx); - archive_sha256_update(&ctx, *argv, argc); - archive_sha256_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA256=yes - found_NETTLE=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA256_NETTLE 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA384" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA384_NETTLE" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA384_NETTLE... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA384_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA384_NETTLE -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha384_ctx ctx; - archive_sha384_init(&ctx); - archive_sha384_update(&ctx, *argv, argc); - archive_sha384_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA384=yes - found_NETTLE=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA384_NETTLE 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA512" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA512_NETTLE" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA512_NETTLE... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA512_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA512_NETTLE -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha512_ctx ctx; - archive_sha512_init(&ctx); - archive_sha512_update(&ctx, *argv, argc); - archive_sha512_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA512=yes - found_NETTLE=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA512_NETTLE 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - if test "x$found_NETTLE" != "xyes"; then - LIBS=$saved_LIBS - fi -fi - -if test "x$with_openssl" != "xno"; then - ac_fn_c_check_header_compile "$LINENO" "openssl/evp.h" "ac_cv_header_openssl_evp_h" "$ac_includes_default" -if test "x$ac_cv_header_openssl_evp_h" = xyes -then : - printf "%s\n" "#define HAVE_OPENSSL_EVP_H 1" >>confdefs.h - -fi - - saved_LIBS=$LIBS - LIBSREQUIRED="$LIBSREQUIRED${LIBSREQUIRED:+ }libcrypto" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for OPENSSL_config in -lcrypto" >&5 -printf %s "checking for OPENSSL_config in -lcrypto... " >&6; } -if test ${ac_cv_lib_crypto_OPENSSL_config+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-lcrypto $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char OPENSSL_config (); -int -main (void) -{ -return OPENSSL_config (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_crypto_OPENSSL_config=yes -else $as_nop - ac_cv_lib_crypto_OPENSSL_config=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_OPENSSL_config" >&5 -printf "%s\n" "$ac_cv_lib_crypto_OPENSSL_config" >&6; } -if test "x$ac_cv_lib_crypto_OPENSSL_config" = xyes -then : - printf "%s\n" "#define HAVE_LIBCRYPTO 1" >>confdefs.h - - LIBS="-lcrypto $LIBS" - -fi - - - if test "$found_MD5" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_MD5_OPENSSL" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_MD5_OPENSSL... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_MD5_COMPILE_TEST -#define ARCHIVE_CRYPTO_MD5_OPENSSL -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_md5_ctx ctx; - archive_md5_init(&ctx); - archive_md5_update(&ctx, *argv, argc); - archive_md5_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_MD5=yes - found_OPENSSL=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_MD5_OPENSSL 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_RMD160" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_RMD160_OPENSSL" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_RMD160_OPENSSL... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_RMD160_COMPILE_TEST -#define ARCHIVE_CRYPTO_RMD160_OPENSSL -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_rmd160_ctx ctx; - archive_rmd160_init(&ctx); - archive_rmd160_update(&ctx, *argv, argc); - archive_rmd160_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_RMD160=yes - found_OPENSSL=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_RMD160_OPENSSL 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA1" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA1_OPENSSL" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA1_OPENSSL... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA1_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA1_OPENSSL -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha1_ctx ctx; - archive_sha1_init(&ctx); - archive_sha1_update(&ctx, *argv, argc); - archive_sha1_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA1=yes - found_OPENSSL=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA1_OPENSSL 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA256" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA256_OPENSSL" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA256_OPENSSL... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA256_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA256_OPENSSL -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha256_ctx ctx; - archive_sha256_init(&ctx); - archive_sha256_update(&ctx, *argv, argc); - archive_sha256_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA256=yes - found_OPENSSL=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA256_OPENSSL 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA384" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA384_OPENSSL" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA384_OPENSSL... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA384_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA384_OPENSSL -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha384_ctx ctx; - archive_sha384_init(&ctx); - archive_sha384_update(&ctx, *argv, argc); - archive_sha384_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA384=yes - found_OPENSSL=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA384_OPENSSL 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA512" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA512_OPENSSL" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA512_OPENSSL... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA512_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA512_OPENSSL -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha512_ctx ctx; - archive_sha512_init(&ctx); - archive_sha512_update(&ctx, *argv, argc); - archive_sha512_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA512=yes - found_OPENSSL=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA512_OPENSSL 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - ac_fn_c_check_func "$LINENO" "PKCS5_PBKDF2_HMAC_SHA1" "ac_cv_func_PKCS5_PBKDF2_HMAC_SHA1" -if test "x$ac_cv_func_PKCS5_PBKDF2_HMAC_SHA1" = xyes -then : - printf "%s\n" "#define HAVE_PKCS5_PBKDF2_HMAC_SHA1 1" >>confdefs.h - -fi - -fi - - - -# Probe libmd AFTER OpenSSL/libcrypto. -# The two are incompatible and OpenSSL is more complete. -ac_fn_c_check_header_compile "$LINENO" "md5.h" "ac_cv_header_md5_h" "$ac_includes_default" -if test "x$ac_cv_header_md5_h" = xyes -then : - printf "%s\n" "#define HAVE_MD5_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "ripemd.h" "ac_cv_header_ripemd_h" "$ac_includes_default" -if test "x$ac_cv_header_ripemd_h" = xyes -then : - printf "%s\n" "#define HAVE_RIPEMD_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "sha.h" "ac_cv_header_sha_h" "$ac_includes_default" -if test "x$ac_cv_header_sha_h" = xyes -then : - printf "%s\n" "#define HAVE_SHA_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "sha256.h" "ac_cv_header_sha256_h" "$ac_includes_default" -if test "x$ac_cv_header_sha256_h" = xyes -then : - printf "%s\n" "#define HAVE_SHA256_H 1" >>confdefs.h - -fi -ac_fn_c_check_header_compile "$LINENO" "sha512.h" "ac_cv_header_sha512_h" "$ac_includes_default" -if test "x$ac_cv_header_sha512_h" = xyes -then : - printf "%s\n" "#define HAVE_SHA512_H 1" >>confdefs.h - -fi - -saved_LIBS=$LIBS -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for MD5Init in -lmd" >&5 -printf %s "checking for MD5Init in -lmd... " >&6; } -if test ${ac_cv_lib_md_MD5Init+y} -then : - printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS -LIBS="-lmd $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char MD5Init (); -int -main (void) -{ -return MD5Init (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - ac_cv_lib_md_MD5Init=yes -else $as_nop - ac_cv_lib_md_MD5Init=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_md_MD5Init" >&5 -printf "%s\n" "$ac_cv_lib_md_MD5Init" >&6; } -if test "x$ac_cv_lib_md_MD5Init" = xyes -then : - printf "%s\n" "#define HAVE_LIBMD 1" >>confdefs.h - - LIBS="-lmd $LIBS" - -fi - - - if test "$found_MD5" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_MD5_LIBMD" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_MD5_LIBMD... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_MD5_COMPILE_TEST -#define ARCHIVE_CRYPTO_MD5_LIBMD -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_md5_ctx ctx; - archive_md5_init(&ctx); - archive_md5_update(&ctx, *argv, argc); - archive_md5_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_MD5=yes - found_LIBMD=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_MD5_LIBMD 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_RMD160" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_RMD160_LIBMD" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_RMD160_LIBMD... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_RMD160_COMPILE_TEST -#define ARCHIVE_CRYPTO_RMD160_LIBMD -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_rmd160_ctx ctx; - archive_rmd160_init(&ctx); - archive_rmd160_update(&ctx, *argv, argc); - archive_rmd160_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_RMD160=yes - found_LIBMD=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_RMD160_LIBMD 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA1" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA1_LIBMD" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA1_LIBMD... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA1_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA1_LIBMD -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha1_ctx ctx; - archive_sha1_init(&ctx); - archive_sha1_update(&ctx, *argv, argc); - archive_sha1_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA1=yes - found_LIBMD=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA1_LIBMD 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA256" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA256_LIBMD" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA256_LIBMD... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA256_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA256_LIBMD -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha256_ctx ctx; - archive_sha256_init(&ctx); - archive_sha256_update(&ctx, *argv, argc); - archive_sha256_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA256=yes - found_LIBMD=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA256_LIBMD 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - - - if test "$found_SHA512" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA512_LIBMD" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA512_LIBMD... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA512_COMPILE_TEST -#define ARCHIVE_CRYPTO_SHA512_LIBMD -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_sha512_ctx ctx; - archive_sha512_init(&ctx); - archive_sha512_update(&ctx, *argv, argc); - archive_sha512_final(&ctx, NULL); - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA512=yes - found_LIBMD=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA512_LIBMD 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi - -if test "x$found_LIBMD" != "xyes"; then - LIBS=$saved_LIBS -fi - -case "$host_os" in - *mingw* | *cygwin* | *msys*) - - if test "$found_MD5" != yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_MD5_WIN" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_MD5_WIN... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_MD5_COMPILE_TEST -#include -#include - -int -main(int argc, char **argv) -{ - (void)argc; - (void)argv; - - return (CALG_MD5); -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_MD5=yes - found_WIN=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_MD5_WIN 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - fi - - - if test "$found_SHA1" != yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA1_WIN" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA1_WIN... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA1_COMPILE_TEST -#include -#include - -int -main(int argc, char **argv) -{ - (void)argc; - (void)argv; - - return (CALG_SHA1); -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA1=yes - found_WIN=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA1_WIN 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - fi - - - if test "$found_SHA256" != yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA256_WIN" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA256_WIN... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA256_COMPILE_TEST -#include -#include - -int -main(int argc, char **argv) -{ - (void)argc; - (void)argv; - - return (CALG_SHA_256); -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA256=yes - found_WIN=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA256_WIN 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - fi - - - if test "$found_SHA384" != yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA384_WIN" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA384_WIN... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA384_COMPILE_TEST -#include -#include - -int -main(int argc, char **argv) -{ - (void)argc; - (void)argv; - - return (CALG_SHA_384); -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA384=yes - found_WIN=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA384_WIN 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - fi - - - if test "$found_SHA512" != yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking support for ARCHIVE_CRYPTO_SHA512_WIN" >&5 -printf %s "checking support for ARCHIVE_CRYPTO_SHA512_WIN... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define ARCHIVE_SHA512_COMPILE_TEST -#include -#include - -int -main(int argc, char **argv) -{ - (void)argc; - (void)argv; - - return (CALG_SHA_512); -} - -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - found_SHA512=yes - found_WIN=yes - -printf "%s\n" "#define ARCHIVE_CRYPTO_SHA512_WIN 1" >>confdefs.h - - -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - fi - - ;; -esac - -saved_CFLAGS="$CFLAGS" -CFLAGS="$CFLAGS -fvisibility=hidden -Werror" -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports visibility annotations" >&5 -printf %s "checking whether compiler supports visibility annotations... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - int foo( void ) __attribute__((visibility("default"))); - -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO" -then : - CFLAGS="$saved_CFLAGS -fvisibility=hidden -D__LIBARCHIVE_ENABLE_VISIBILITY"; - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } -else $as_nop - CFLAGS="$saved_CFLAGS" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - -# Ensure test directories are present if building out-of-tree -ac_config_commands="$ac_config_commands mkdirs" - - -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes: double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \. - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - if test "x$cache_file" != "x/dev/null"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 -printf "%s\n" "$as_me: updating cache $cache_file" >&6;} - if test ! -f "$cache_file" || test -h "$cache_file"; then - cat confcache >"$cache_file" - else - case $cache_file in #( - */* | ?:*) - mv -f confcache "$cache_file"$$ && - mv -f "$cache_file"$$ "$cache_file" ;; #( - *) - mv -f confcache "$cache_file" ;; - esac - fi - fi - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 -printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;} - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -DEFS=-DHAVE_CONFIG_H - -ac_libobjs= -ac_ltlibobjs= -U= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"` - # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR - # will be set to the directory where LIBOBJS objects are built. - as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" - as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 -printf %s "checking that generated files are newer than configure... " >&6; } - if test -n "$am_sleep_pid"; then - # Hide warnings about reused PIDs. - wait $am_sleep_pid 2>/dev/null - fi - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: done" >&5 -printf "%s\n" "done" >&6; } - if test -n "$EXEEXT"; then - am__EXEEXT_TRUE= - am__EXEEXT_FALSE='#' -else - am__EXEEXT_TRUE='#' - am__EXEEXT_FALSE= -fi - -if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then - as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${INC_WINDOWS_FILES_TRUE}" && test -z "${INC_WINDOWS_FILES_FALSE}"; then - as_fn_error $? "conditional \"INC_WINDOWS_FILES\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${INC_CYGWIN_FILES_TRUE}" && test -z "${INC_CYGWIN_FILES_FALSE}"; then - as_fn_error $? "conditional \"INC_CYGWIN_FILES\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then - as_fn_error $? "conditional \"AMDEP\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then - as_fn_error $? "conditional \"am__fastdepCC\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${BUILD_BSDTAR_TRUE}" && test -z "${BUILD_BSDTAR_FALSE}"; then - as_fn_error $? "conditional \"BUILD_BSDTAR\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${STATIC_BSDTAR_TRUE}" && test -z "${STATIC_BSDTAR_FALSE}"; then - as_fn_error $? "conditional \"STATIC_BSDTAR\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${BUILD_BSDCAT_TRUE}" && test -z "${BUILD_BSDCAT_FALSE}"; then - as_fn_error $? "conditional \"BUILD_BSDCAT\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${STATIC_BSDCAT_TRUE}" && test -z "${STATIC_BSDCAT_FALSE}"; then - as_fn_error $? "conditional \"STATIC_BSDCAT\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${BUILD_BSDCPIO_TRUE}" && test -z "${BUILD_BSDCPIO_FALSE}"; then - as_fn_error $? "conditional \"BUILD_BSDCPIO\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${STATIC_BSDCPIO_TRUE}" && test -z "${STATIC_BSDCPIO_FALSE}"; then - as_fn_error $? "conditional \"STATIC_BSDCPIO\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${BUILD_BSDUNZIP_TRUE}" && test -z "${BUILD_BSDUNZIP_FALSE}"; then - as_fn_error $? "conditional \"BUILD_BSDUNZIP\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${STATIC_BSDUNZIP_TRUE}" && test -z "${STATIC_BSDUNZIP_FALSE}"; then - as_fn_error $? "conditional \"STATIC_BSDUNZIP\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${INC_BLAKE2_TRUE}" && test -z "${INC_BLAKE2_FALSE}"; then - as_fn_error $? "conditional \"INC_BLAKE2\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${INC_LINUX_ACL_TRUE}" && test -z "${INC_LINUX_ACL_FALSE}"; then - as_fn_error $? "conditional \"INC_LINUX_ACL\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${INC_SUNOS_ACL_TRUE}" && test -z "${INC_SUNOS_ACL_FALSE}"; then - as_fn_error $? "conditional \"INC_SUNOS_ACL\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${INC_DARWIN_ACL_TRUE}" && test -z "${INC_DARWIN_ACL_FALSE}"; then - as_fn_error $? "conditional \"INC_DARWIN_ACL\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${INC_FREEBSD_ACL_TRUE}" && test -z "${INC_FREEBSD_ACL_FALSE}"; then - as_fn_error $? "conditional \"INC_FREEBSD_ACL\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi - -: "${CONFIG_STATUS=./config.status}" -ac_write_fail=0 -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 -printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;} -as_write_fail=0 -cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false - -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -as_nop=: -if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 -then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else $as_nop - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - - -# Reset variables that may have inherited troublesome values from -# the environment. - -# IFS needs to be set, to space, tab, and newline, in precisely that order. -# (If _AS_PATH_WALK were called with IFS unset, it would have the -# side effect of setting IFS to empty, thus disabling word splitting.) -# Quoting is to prevent editors from complaining about space-tab. -as_nl=' -' -export as_nl -IFS=" "" $as_nl" - -PS1='$ ' -PS2='> ' -PS4='+ ' - -# Ensure predictable behavior from utilities with locale-dependent output. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# We cannot yet rely on "unset" to work, but we need these variables -# to be unset--not just set to an empty or harmless value--now, to -# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct -# also avoids known problems related to "unset" and subshell syntax -# in other old shells (e.g. bash 2.01 and pdksh 5.2.14). -for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH -do eval test \${$as_var+y} \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done - -# Ensure that fds 0, 1, and 2 are open. -if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi -if (exec 3>&2) ; then :; else exec 2>/dev/null; fi - -# The user is always right. -if ${PATH_SEPARATOR+false} :; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - test -r "$as_dir$0" && as_myself=$as_dir$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - printf "%s\n" "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - - - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset - -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null -then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else $as_nop - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null -then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else $as_nop - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -printf "%s\n" X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - - -# Determine whether it's possible to make 'echo' print without a newline. -# These variables are no longer used directly by Autoconf, but are AC_SUBSTed -# for compatibility with existing Makefiles. -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -# For backward compatibility with old third-party macros, we provide -# the shell variables $as_echo and $as_echo_n. New code should use -# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. -as_echo='printf %s\n' -as_echo_n='printf %s' - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -printf "%s\n" X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 -## ----------------------------------- ## -## Main body of $CONFIG_STATUS script. ## -## ----------------------------------- ## -_ASEOF -test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# Save the log message, to keep $0 and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" -This file was extended by libarchive $as_me 3.7.2, which was -generated by GNU Autoconf 2.71. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - -_ACEOF - -case $ac_config_files in *" -"*) set x $ac_config_files; shift; ac_config_files=$*;; -esac - -case $ac_config_headers in *" -"*) set x $ac_config_headers; shift; ac_config_headers=$*;; -esac - - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# Files that config.status was made for. -config_files="$ac_config_files" -config_headers="$ac_config_headers" -config_commands="$ac_config_commands" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -ac_cs_usage="\ -\`$as_me' instantiates files and other configuration actions -from templates according to the current configuration. Unless the files -and actions are specified as TAGs, all are instantiated by default. - -Usage: $0 [OPTION]... [TAG]... - - -h, --help print this help, then exit - -V, --version print version number and configuration settings, then exit - --config print configuration, then exit - -q, --quiet, --silent - do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - --header=FILE[:TEMPLATE] - instantiate the configuration header FILE - -Configuration files: -$config_files - -Configuration headers: -$config_headers - -Configuration commands: -$config_commands - -Report bugs to ." - -_ACEOF -ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` -ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_cs_config='$ac_cs_config_escaped' -ac_cs_version="\\ -libarchive config.status 3.7.2 -configured by $0, generated by GNU Autoconf 2.71, - with options \\"\$ac_cs_config\\" - -Copyright (C) 2021 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." - -ac_pwd='$ac_pwd' -srcdir='$srcdir' -INSTALL='$INSTALL' -MKDIR_P='$MKDIR_P' -AWK='$AWK' -test -n "\$AWK" || AWK=awk -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# The default lists apply if the user does not specify any file. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=?*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - --*=) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg= - ac_shift=: - ;; - *) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - printf "%s\n" "$ac_cs_version"; exit ;; - --config | --confi | --conf | --con | --co | --c ) - printf "%s\n" "$ac_cs_config"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - '') as_fn_error $? "missing file argument" ;; - esac - as_fn_append CONFIG_FILES " '$ac_optarg'" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - as_fn_append CONFIG_HEADERS " '$ac_optarg'" - ac_need_defaults=false;; - --he | --h) - # Conflict between --help and --header - as_fn_error $? "ambiguous option: \`$1' -Try \`$0 --help' for more information.";; - --help | --hel | -h ) - printf "%s\n" "$ac_cs_usage"; exit ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) as_fn_error $? "unrecognized option: \`$1' -Try \`$0 --help' for more information." ;; - - *) as_fn_append ac_config_targets " $1" - ac_need_defaults=false ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -if \$ac_cs_recheck; then - set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion - shift - \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6 - CONFIG_SHELL='$SHELL' - export CONFIG_SHELL - exec "\$@" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - printf "%s\n" "$ac_log" -} >&5 - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# -# INIT-COMMANDS -# -AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" - - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -sed_quote_subst='$sed_quote_subst' -double_quote_subst='$double_quote_subst' -delay_variable_subst='$delay_variable_subst' -AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' -DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' -OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' -macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' -macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' -enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' -enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' -pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' -enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' -shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' -SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' -ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' -PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' -host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' -host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' -host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' -build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' -build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' -build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' -SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' -Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' -GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' -EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' -FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' -LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' -NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' -LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' -max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' -ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' -exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' -lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' -lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' -lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' -lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' -lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' -reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' -reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' -deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' -file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' -file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' -want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' -sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' -AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' -AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' -archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' -STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' -RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' -old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' -old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' -old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' -lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' -CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' -CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' -compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' -GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' -lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' -nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' -lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' -lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' -objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' -MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' -lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' -need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' -MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' -DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' -NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' -LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' -OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' -OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' -libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' -shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' -extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' -archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' -enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' -export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' -whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' -compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' -old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' -old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' -archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' -archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' -module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' -module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' -with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' -allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' -no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' -hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' -hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' -hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' -hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' -hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' -hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' -hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' -inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' -link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' -always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' -export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' -exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' -include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' -prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' -postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' -file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' -variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' -need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' -need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' -version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' -runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' -shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' -shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' -libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' -library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' -soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' -install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' -postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' -postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' -finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' -finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' -hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' -sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' -configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' -configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' -hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' -enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' -enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' -enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' -old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' -striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' - -LTCC='$LTCC' -LTCFLAGS='$LTCFLAGS' -compiler='$compiler_DEFAULT' - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -\$1 -_LTECHO_EOF' -} - -# Quote evaled strings. -for var in AS \ -DLLTOOL \ -OBJDUMP \ -SHELL \ -ECHO \ -PATH_SEPARATOR \ -SED \ -GREP \ -EGREP \ -FGREP \ -LD \ -NM \ -LN_S \ -lt_SP2NL \ -lt_NL2SP \ -reload_flag \ -deplibs_check_method \ -file_magic_cmd \ -file_magic_glob \ -want_nocaseglob \ -sharedlib_from_linklib_cmd \ -AR \ -AR_FLAGS \ -archiver_list_spec \ -STRIP \ -RANLIB \ -CC \ -CFLAGS \ -compiler \ -lt_cv_sys_global_symbol_pipe \ -lt_cv_sys_global_symbol_to_cdecl \ -lt_cv_sys_global_symbol_to_import \ -lt_cv_sys_global_symbol_to_c_name_address \ -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ -lt_cv_nm_interface \ -nm_file_list_spec \ -lt_cv_truncate_bin \ -lt_prog_compiler_no_builtin_flag \ -lt_prog_compiler_pic \ -lt_prog_compiler_wl \ -lt_prog_compiler_static \ -lt_cv_prog_compiler_c_o \ -need_locks \ -MANIFEST_TOOL \ -DSYMUTIL \ -NMEDIT \ -LIPO \ -OTOOL \ -OTOOL64 \ -shrext_cmds \ -export_dynamic_flag_spec \ -whole_archive_flag_spec \ -compiler_needs_object \ -with_gnu_ld \ -allow_undefined_flag \ -no_undefined_flag \ -hardcode_libdir_flag_spec \ -hardcode_libdir_separator \ -exclude_expsyms \ -include_expsyms \ -file_list_spec \ -variables_saved_for_relink \ -libname_spec \ -library_names_spec \ -soname_spec \ -install_override_mode \ -finish_eval \ -old_striplib \ -striplib; do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -# Double-quote double-evaled strings. -for var in reload_cmds \ -old_postinstall_cmds \ -old_postuninstall_cmds \ -old_archive_cmds \ -extract_expsyms_cmds \ -old_archive_from_new_cmds \ -old_archive_from_expsyms_cmds \ -archive_cmds \ -archive_expsym_cmds \ -module_cmds \ -module_expsym_cmds \ -export_symbols_cmds \ -prelink_cmds \ -postlink_cmds \ -postinstall_cmds \ -postuninstall_cmds \ -finish_cmds \ -sys_lib_search_path_spec \ -configure_time_dlsearch_path \ -configure_time_lt_sys_library_path; do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -ac_aux_dir='$ac_aux_dir' - -# See if we are running on zsh, and set the options that allow our -# commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}"; then - setopt NO_GLOB_SUBST -fi - - - PACKAGE='$PACKAGE' - VERSION='$VERSION' - RM='$RM' - ofile='$ofile' - - - - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - -# Handling of arguments. -for ac_config_target in $ac_config_targets -do - case $ac_config_target in - "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; - "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "build/pkgconfig/libarchive.pc") CONFIG_FILES="$CONFIG_FILES build/pkgconfig/libarchive.pc" ;; - "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; - "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; - "mkdirs") CONFIG_COMMANDS="$CONFIG_COMMANDS mkdirs" ;; - - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; - esac -done - - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files - test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers - test ${CONFIG_COMMANDS+y} || CONFIG_COMMANDS=$config_commands -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. -$debug || -{ - tmp= ac_tmp= - trap 'exit_status=$? - : "${ac_tmp:=$tmp}" - { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status -' 0 - trap 'as_fn_exit 1' 1 2 13 15 -} -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -d "$tmp" -} || -{ - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 -ac_tmp=$tmp - -# Set up the scripts for CONFIG_FILES section. -# No need to generate them if there are no CONFIG_FILES. -# This happens for instance with `./config.status config.h'. -if test -n "$CONFIG_FILES"; then - - -ac_cr=`echo X | tr X '\015'` -# On cygwin, bash can eat \r inside `` if the user requested igncr. -# But we know of no other shell where ac_cr would be empty at this -# point, so we can use a bashism as a fallback. -if test "x$ac_cr" = x; then - eval ac_cr=\$\'\\r\' -fi -ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` -if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\\r' -else - ac_cs_awk_cr=$ac_cr -fi - -echo 'BEGIN {' >"$ac_tmp/subs1.awk" && -_ACEOF - - -{ - echo "cat >conf$$subs.awk <<_ACEOF" && - echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && - echo "_ACEOF" -} >conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - . ./conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - - ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` - if test $ac_delim_n = $ac_delim_num; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done -rm -f conf$$subs.sh - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && -_ACEOF -sed -n ' -h -s/^/S["/; s/!.*/"]=/ -p -g -s/^[^!]*!// -:repl -t repl -s/'"$ac_delim"'$// -t delim -:nl -h -s/\(.\{148\}\)..*/\1/ -t more1 -s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ -p -n -b repl -:more1 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t nl -:delim -h -s/\(.\{148\}\)..*/\1/ -t more2 -s/["\\]/\\&/g; s/^/"/; s/$/"/ -p -b -:more2 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t delim -' >$CONFIG_STATUS || ac_write_fail=1 -rm -f conf$$subs.awk -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACAWK -cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && - for (key in S) S_is_set[key] = 1 - FS = "" - -} -{ - line = $ 0 - nfields = split(line, field, "@") - substed = 0 - len = length(field[1]) - for (i = 2; i < nfields; i++) { - key = field[i] - keylen = length(key) - if (S_is_set[key]) { - value = S[key] - line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) - len += length(value) + length(field[++i]) - substed = 1 - } else - len += 1 + keylen - } - - print line -} - -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then - sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" -else - cat -fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ - || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 -_ACEOF - -# VPATH may cause trouble with some makes, so we remove sole $(srcdir), -# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ -h -s/// -s/^/:/ -s/[ ]*$/:/ -s/:\$(srcdir):/:/g -s/:\${srcdir}:/:/g -s/:@srcdir@:/:/g -s/^:*// -s/:*$// -x -s/\(=[ ]*\).*/\1/ -G -s/\n// -s/^[^=]*=[ ]*$// -}' -fi - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -fi # test -n "$CONFIG_FILES" - -# Set up the scripts for CONFIG_HEADERS section. -# No need to generate them if there are no CONFIG_HEADERS. -# This happens for instance with `./config.status Makefile'. -if test -n "$CONFIG_HEADERS"; then -cat >"$ac_tmp/defines.awk" <<\_ACAWK || -BEGIN { -_ACEOF - -# Transform confdefs.h into an awk script `defines.awk', embedded as -# here-document in config.status, that substitutes the proper values into -# config.h.in to produce config.h. - -# Create a delimiter string that does not exist in confdefs.h, to ease -# handling of long lines. -ac_delim='%!_!# ' -for ac_last_try in false false :; do - ac_tt=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_tt"; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done - -# For the awk script, D is an array of macro values keyed by name, -# likewise P contains macro parameters if any. Preserve backslash -# newline sequences. - -ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* -sed -n ' -s/.\{148\}/&'"$ac_delim"'/g -t rset -:rset -s/^[ ]*#[ ]*define[ ][ ]*/ / -t def -d -:def -s/\\$// -t bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3"/p -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p -d -:bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3\\\\\\n"\\/p -t cont -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p -t cont -d -:cont -n -s/.\{148\}/&'"$ac_delim"'/g -t clear -:clear -s/\\$// -t bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/"/p -d -:bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p -b cont -' >$CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - for (key in D) D_is_set[key] = 1 - FS = "" -} -/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { - line = \$ 0 - split(line, arg, " ") - if (arg[1] == "#") { - defundef = arg[2] - mac1 = arg[3] - } else { - defundef = substr(arg[1], 2) - mac1 = arg[2] - } - split(mac1, mac2, "(") #) - macro = mac2[1] - prefix = substr(line, 1, index(line, defundef) - 1) - if (D_is_set[macro]) { - # Preserve the white space surrounding the "#". - print prefix "define", macro P[macro] D[macro] - next - } else { - # Replace #undef with comments. This is necessary, for example, - # in the case of _POSIX_SOURCE, which is predefined and required - # on some systems where configure will not decide to define it. - if (defundef == "undef") { - print "/*", prefix defundef, macro, "*/" - next - } - } -} -{ print } -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 -fi # test -n "$CONFIG_HEADERS" - - -eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" -shift -for ac_tag -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift - - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$ac_tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; - esac - case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac - as_fn_append ac_file_inputs " '$ac_f'" - done - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input='Generated from '` - printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' - `' by configure.' - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 -printf "%s\n" "$as_me: creating $ac_file" >&6;} - fi - # Neutralize special characters interpreted by sed in replacement strings. - case $configure_input in #( - *\&* | *\|* | *\\* ) - ac_sed_conf_input=`printf "%s\n" "$configure_input" | - sed 's/[\\\\&|]/\\\\&/g'`;; #( - *) ac_sed_conf_input=$configure_input;; - esac - - case $ac_tag in - *:-:* | *:-) cat >"$ac_tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; - esac - ;; - esac - - ac_dir=`$as_dirname -- "$ac_file" || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -printf "%s\n" X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir="$ac_dir"; as_fn_mkdir_p - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; - esac - ac_MKDIR_P=$MKDIR_P - case $MKDIR_P in - [\\/$]* | ?:[\\/]* ) ;; - */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; - esac -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= -ac_sed_dataroot=' -/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p' -case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - ac_datarootdir_hack=' - s&@datadir@&$datadir&g - s&@docdir@&$docdir&g - s&@infodir@&$infodir&g - s&@localedir@&$localedir&g - s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; -esac -_ACEOF - -# Neutralize VPATH when `$srcdir' = `.'. -# Shell code in configure.ac might set extrasub. -# FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_sed_extra="$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s|@configure_input@|$ac_sed_conf_input|;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@top_build_prefix@&$ac_top_build_prefix&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -s&@INSTALL@&$ac_INSTALL&;t t -s&@MKDIR_P@&$ac_MKDIR_P&;t t -$ac_datarootdir_hack -" -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ - >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ - "$ac_tmp/out"`; test -z "$ac_out"; } && - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&5 -printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&2;} - - rm -f "$ac_tmp/stdin" - case $ac_file in - -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; - *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; - esac \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - ;; - :H) - # - # CONFIG_HEADER - # - if test x"$ac_file" != x-; then - { - printf "%s\n" "/* $configure_input */" >&1 \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" - } >"$ac_tmp/config.h" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 -printf "%s\n" "$as_me: $ac_file is unchanged" >&6;} - else - rm -f "$ac_file" - mv "$ac_tmp/config.h" "$ac_file" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - fi - else - printf "%s\n" "/* $configure_input */" >&1 \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ - || as_fn_error $? "could not create -" "$LINENO" 5 - fi -# Compute "$ac_file"'s index in $config_headers. -_am_arg="$ac_file" -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $_am_arg | $_am_arg:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || -$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$_am_arg" : 'X\(//\)[^/]' \| \ - X"$_am_arg" : 'X\(//\)$' \| \ - X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || -printf "%s\n" X"$_am_arg" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'`/stamp-h$_am_stamp_count - ;; - - :C) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 -printf "%s\n" "$as_me: executing $ac_file commands" >&6;} - ;; - esac - - - case $ac_file$ac_mode in - "depfiles":C) test x"$AMDEP_TRUE" != x"" || { - # Older Autoconf quotes --file arguments for eval, but not when files - # are listed without --file. Let's play safe and only enable the eval - # if we detect the quoting. - # TODO: see whether this extra hack can be removed once we start - # requiring Autoconf 2.70 or later. - case $CONFIG_FILES in #( - *\'*) : - eval set x "$CONFIG_FILES" ;; #( - *) : - set x $CONFIG_FILES ;; #( - *) : - ;; -esac - shift - # Used to flag and report bootstrapping failures. - am_rc=0 - for am_mf - do - # Strip MF so we end up with the name of the file. - am_mf=`printf "%s\n" "$am_mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile which includes - # dependency-tracking related rules and includes. - # Grep'ing the whole file directly is not great: AIX grep has a line - # limit of 2048, but all sed's we know have understand at least 4000. - sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ - || continue - am_dirpart=`$as_dirname -- "$am_mf" || -$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$am_mf" : 'X\(//\)[^/]' \| \ - X"$am_mf" : 'X\(//\)$' \| \ - X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || -printf "%s\n" X"$am_mf" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - am_filepart=`$as_basename -- "$am_mf" || -$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ - X"$am_mf" : 'X\(//\)$' \| \ - X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || -printf "%s\n" X/"$am_mf" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - { echo "$as_me:$LINENO: cd "$am_dirpart" \ - && sed -e '/# am--include-marker/d' "$am_filepart" \ - | $MAKE -f - am--depfiles" >&5 - (cd "$am_dirpart" \ - && sed -e '/# am--include-marker/d' "$am_filepart" \ - | $MAKE -f - am--depfiles) >&5 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } || am_rc=$? - done - if test $am_rc -ne 0; then - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "Something went wrong bootstrapping makefile fragments - for automatic dependency tracking. If GNU make was not used, consider - re-running the configure script with MAKE=\"gmake\" (or whatever is - necessary). You can also try re-running configure with the - '--disable-dependency-tracking' option to at least be able to build - the package (albeit without support for automatic dependency tracking). -See \`config.log' for more details" "$LINENO" 5; } - fi - { am_dirpart=; unset am_dirpart;} - { am_filepart=; unset am_filepart;} - { am_mf=; unset am_mf;} - { am_rc=; unset am_rc;} - rm -f conftest-deps.mk -} - ;; - "libtool":C) - - # See if we are running on zsh, and set the options that allow our - # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}"; then - setopt NO_GLOB_SUBST - fi - - cfgfile=${ofile}T - trap "$RM \"$cfgfile\"; exit 1" 1 2 15 - $RM "$cfgfile" - - cat <<_LT_EOF >> "$cfgfile" -#! $SHELL -# Generated automatically by $as_me ($PACKAGE) $VERSION -# NOTE: Changes made to this file will be lost: look at ltmain.sh. - -# Provide generalized library-building support services. -# Written by Gordon Matzigkeit, 1996 - -# Copyright (C) 2014 Free Software Foundation, Inc. -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -# GNU Libtool is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of of the License, or -# (at your option) any later version. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program or library that is built -# using GNU Libtool, you may include this file under the same -# distribution terms that you use for the rest of that program. -# -# GNU Libtool is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - - -# The names of the tagged configurations supported by this script. -available_tags='' - -# Configured defaults for sys_lib_dlsearch_path munging. -: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} - -# ### BEGIN LIBTOOL CONFIG - -# Assembler program. -AS=$lt_AS - -# DLL creation program. -DLLTOOL=$lt_DLLTOOL - -# Object dumper program. -OBJDUMP=$lt_OBJDUMP - -# Which release of libtool.m4 was used? -macro_version=$macro_version -macro_revision=$macro_revision - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# What type of objects to build. -pic_mode=$pic_mode - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# Shared archive member basename,for filename based shared library versioning on AIX. -shared_archive_member_spec=$shared_archive_member_spec - -# Shell to use when invoking shell scripts. -SHELL=$lt_SHELL - -# An echo program that protects backslashes. -ECHO=$lt_ECHO - -# The PATH separator for the build system. -PATH_SEPARATOR=$lt_PATH_SEPARATOR - -# The host system. -host_alias=$host_alias -host=$host -host_os=$host_os - -# The build system. -build_alias=$build_alias -build=$build -build_os=$build_os - -# A sed program that does not truncate output. -SED=$lt_SED - -# Sed that helps us avoid accidentally triggering echo(1) options like -n. -Xsed="\$SED -e 1s/^X//" - -# A grep program that handles long lines. -GREP=$lt_GREP - -# An ERE matcher. -EGREP=$lt_EGREP - -# A literal string matcher. -FGREP=$lt_FGREP - -# A BSD- or MS-compatible name lister. -NM=$lt_NM - -# Whether we need soft or hard links. -LN_S=$lt_LN_S - -# What is the maximum length of a command? -max_cmd_len=$max_cmd_len - -# Object file suffix (normally "o"). -objext=$ac_objext - -# Executable file suffix (normally ""). -exeext=$exeext - -# whether the shell understands "unset". -lt_unset=$lt_unset - -# turn spaces into newlines. -SP2NL=$lt_lt_SP2NL - -# turn newlines into spaces. -NL2SP=$lt_lt_NL2SP - -# convert \$build file names to \$host format. -to_host_file_cmd=$lt_cv_to_host_file_cmd - -# convert \$build files to toolchain format. -to_tool_file_cmd=$lt_cv_to_tool_file_cmd - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$lt_deplibs_check_method - -# Command to use when deplibs_check_method = "file_magic". -file_magic_cmd=$lt_file_magic_cmd - -# How to find potential files when deplibs_check_method = "file_magic". -file_magic_glob=$lt_file_magic_glob - -# Find potential files using nocaseglob when deplibs_check_method = "file_magic". -want_nocaseglob=$lt_want_nocaseglob - -# Command to associate shared and link libraries. -sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd - -# The archiver. -AR=$lt_AR - -# Flags to create an archive. -AR_FLAGS=$lt_AR_FLAGS - -# How to feed a file listing to the archiver. -archiver_list_spec=$lt_archiver_list_spec - -# A symbol stripping program. -STRIP=$lt_STRIP - -# Commands used to install an old-style archive. -RANLIB=$lt_RANLIB -old_postinstall_cmds=$lt_old_postinstall_cmds -old_postuninstall_cmds=$lt_old_postuninstall_cmds - -# Whether to use a lock for old archive extraction. -lock_old_archive_extraction=$lock_old_archive_extraction - -# A C compiler. -LTCC=$lt_CC - -# LTCC compiler flags. -LTCFLAGS=$lt_CFLAGS - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe - -# Transform the output of nm in a proper C declaration. -global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl - -# Transform the output of nm into a list of symbols to manually relocate. -global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import - -# Transform the output of nm in a C name address pair. -global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address - -# Transform the output of nm in a C name address pair when lib prefix is needed. -global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix - -# The name lister interface. -nm_interface=$lt_lt_cv_nm_interface - -# Specify filename containing input files for \$NM. -nm_file_list_spec=$lt_nm_file_list_spec - -# The root where to search for dependent libraries,and where our libraries should be installed. -lt_sysroot=$lt_sysroot - -# Command to truncate a binary pipe. -lt_truncate_bin=$lt_lt_cv_truncate_bin - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# Used to examine libraries when file_magic_cmd begins with "file". -MAGIC_CMD=$MAGIC_CMD - -# Must we lock files when doing compilation? -need_locks=$lt_need_locks - -# Manifest tool. -MANIFEST_TOOL=$lt_MANIFEST_TOOL - -# Tool to manipulate archived DWARF debug symbol files on Mac OS X. -DSYMUTIL=$lt_DSYMUTIL - -# Tool to change global to local symbols on Mac OS X. -NMEDIT=$lt_NMEDIT - -# Tool to manipulate fat objects and archives on Mac OS X. -LIPO=$lt_LIPO - -# ldd/readelf like tool for Mach-O binaries on Mac OS X. -OTOOL=$lt_OTOOL - -# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. -OTOOL64=$lt_OTOOL64 - -# Old archive suffix (normally "a"). -libext=$libext - -# Shared library suffix (normally ".so"). -shrext_cmds=$lt_shrext_cmds - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds=$lt_extract_expsyms_cmds - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at link time. -variables_saved_for_relink=$lt_variables_saved_for_relink - -# Do we need the "lib" prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Library versioning type. -version_type=$version_type - -# Shared library runtime path variable. -runpath_var=$runpath_var - -# Shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# Format of library name prefix. -libname_spec=$lt_libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME -library_names_spec=$lt_library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$lt_soname_spec - -# Permission mode override for installation of shared libraries. -install_override_mode=$lt_install_override_mode - -# Command to use after installation of a shared archive. -postinstall_cmds=$lt_postinstall_cmds - -# Command to use after uninstallation of a shared archive. -postuninstall_cmds=$lt_postuninstall_cmds - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$lt_finish_cmds - -# As "finish_cmds", except a single script fragment to be evaled but -# not shown. -finish_eval=$lt_finish_eval - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=$hardcode_into_libs - -# Compile-time system search path for libraries. -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec - -# Detected run-time system search path for libraries. -sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path - -# Explicit LT_SYS_LIBRARY_PATH set during ./configure time. -configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path - -# Whether dlopen is supported. -dlopen_support=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Commands to strip libraries. -old_striplib=$lt_old_striplib -striplib=$lt_striplib - - -# The linker used to build libraries. -LD=$lt_LD - -# How to create reloadable object files. -reload_flag=$lt_reload_flag -reload_cmds=$lt_reload_cmds - -# Commands used to build an old-style archive. -old_archive_cmds=$lt_old_archive_cmds - -# A language specific compiler. -CC=$lt_compiler - -# Is the compiler the GNU compiler? -with_gcc=$GCC - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag - -# Additional compiler flags for building library objects. -pic_flag=$lt_lt_prog_compiler_pic - -# How to pass a linker flag through the compiler. -wl=$lt_lt_prog_compiler_wl - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_lt_prog_compiler_static - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_lt_cv_prog_compiler_c_o - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$archive_cmds_need_lc - -# Whether or not to disallow shared libs when runtime libs are static. -allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_export_dynamic_flag_spec - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_whole_archive_flag_spec - -# Whether the compiler copes with passing no objects directly. -compiler_needs_object=$lt_compiler_needs_object - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_old_archive_from_new_cmds - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds - -# Commands used to build a shared archive. -archive_cmds=$lt_archive_cmds -archive_expsym_cmds=$lt_archive_expsym_cmds - -# Commands used to build a loadable module if different from building -# a shared archive. -module_cmds=$lt_module_cmds -module_expsym_cmds=$lt_module_expsym_cmds - -# Whether we are building with GNU ld or not. -with_gnu_ld=$lt_with_gnu_ld - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_allow_undefined_flag - -# Flag that enforces no undefined symbols. -no_undefined_flag=$lt_no_undefined_flag - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist -hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec - -# Whether we need a single "-rpath" flag with a separated argument. -hardcode_libdir_separator=$lt_hardcode_libdir_separator - -# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes -# DIR into the resulting binary. -hardcode_direct=$hardcode_direct - -# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes -# DIR into the resulting binary and the resulting library dependency is -# "absolute",i.e impossible to change by setting \$shlibpath_var if the -# library is relocated. -hardcode_direct_absolute=$hardcode_direct_absolute - -# Set to "yes" if using the -LDIR flag during linking hardcodes DIR -# into the resulting binary. -hardcode_minus_L=$hardcode_minus_L - -# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR -# into the resulting binary. -hardcode_shlibpath_var=$hardcode_shlibpath_var - -# Set to "yes" if building a shared library automatically hardcodes DIR -# into the library and all subsequent libraries and executables linked -# against it. -hardcode_automatic=$hardcode_automatic - -# Set to yes if linker adds runtime paths of dependent libraries -# to runtime path list. -inherit_rpath=$inherit_rpath - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$link_all_deplibs - -# Set to "yes" if exported symbols are required. -always_export_symbols=$always_export_symbols - -# The commands to list exported symbols. -export_symbols_cmds=$lt_export_symbols_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_exclude_expsyms - -# Symbols that must always be exported. -include_expsyms=$lt_include_expsyms - -# Commands necessary for linking programs (against libraries) with templates. -prelink_cmds=$lt_prelink_cmds - -# Commands necessary for finishing linking programs. -postlink_cmds=$lt_postlink_cmds - -# Specify filename containing input files. -file_list_spec=$lt_file_list_spec - -# How to hardcode a shared library path into an executable. -hardcode_action=$hardcode_action - -# ### END LIBTOOL CONFIG - -_LT_EOF - - cat <<'_LT_EOF' >> "$cfgfile" - -# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE - -# func_munge_path_list VARIABLE PATH -# ----------------------------------- -# VARIABLE is name of variable containing _space_ separated list of -# directories to be munged by the contents of PATH, which is string -# having a format: -# "DIR[:DIR]:" -# string "DIR[ DIR]" will be prepended to VARIABLE -# ":DIR[:DIR]" -# string "DIR[ DIR]" will be appended to VARIABLE -# "DIRP[:DIRP]::[DIRA:]DIRA" -# string "DIRP[ DIRP]" will be prepended to VARIABLE and string -# "DIRA[ DIRA]" will be appended to VARIABLE -# "DIR[:DIR]" -# VARIABLE will be replaced by "DIR[ DIR]" -func_munge_path_list () -{ - case x$2 in - x) - ;; - *:) - eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" - ;; - x:*) - eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" - ;; - *::*) - eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" - eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" - ;; - *) - eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" - ;; - esac -} - - -# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. -func_cc_basename () -{ - for cc_temp in $*""; do - case $cc_temp in - compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; - distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; - \-*) ;; - *) break;; - esac - done - func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` -} - - -# ### END FUNCTIONS SHARED WITH CONFIGURE - -_LT_EOF - - case $host_os in - aix3*) - cat <<\_LT_EOF >> "$cfgfile" -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test set != "${COLLECT_NAMES+set}"; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -_LT_EOF - ;; - esac - - - -ltmain=$ac_aux_dir/ltmain.sh - - - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - mv -f "$cfgfile" "$ofile" || - (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") - chmod +x "$ofile" - - ;; - "mkdirs":C) mkdir -p libarchive/test tar/test cat/test cpio/test ;; - - esac -done # for ac_tag - - -as_fn_exit 0 -_ACEOF -ac_clean_files=$ac_clean_files_save - -test $ac_write_fail = 0 || - as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || as_fn_exit 1 -fi -if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} -fi - - diff --git a/thirdparty/libarchive/configure.ac b/thirdparty/libarchive/configure.ac deleted file mode 100644 index 6c3c70438..000000000 --- a/thirdparty/libarchive/configure.ac +++ /dev/null @@ -1,1353 +0,0 @@ -dnl Process this file with autoconf to produce a configure script. - -dnl First, define all of the version numbers up front. -dnl In particular, this allows the version macro to be used in AC_INIT - -dnl These first two version numbers are updated automatically on each release. -m4_define([LIBARCHIVE_VERSION_S],[3.7.2]) -m4_define([LIBARCHIVE_VERSION_N],[3007002]) - -dnl bsdtar and bsdcpio versioning tracks libarchive -m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S()) -m4_define([BSDCPIO_VERSION_S],LIBARCHIVE_VERSION_S()) -m4_define([BSDCAT_VERSION_S],LIBARCHIVE_VERSION_S()) -m4_define([BSDUNZIP_VERSION_S],LIBARCHIVE_VERSION_S()) - -AC_PREREQ([2.71]) - -# -# Now starts the "real" configure script. -# - -AC_INIT([libarchive],[LIBARCHIVE_VERSION_S()],[libarchive-discuss@googlegroups.com]) -# Make sure the srcdir contains "libarchive" directory -AC_CONFIG_SRCDIR([libarchive]) -# Use auxiliary subscripts from this subdirectory (cleans up root) -AC_CONFIG_AUX_DIR([build/autoconf]) -# M4 scripts -AC_CONFIG_MACRO_DIR([build/autoconf]) -# Must follow AC_CONFIG macros above... -AM_INIT_AUTOMAKE([1.11 dist-xz dist-zip]) -AM_MAINTAINER_MODE([enable]) -m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) - -# Libtool's "interface version" can be computed from the libarchive version. - -# Libtool interface version bumps on any API change, so increments -# whenever libarchive minor version does. -ARCHIVE_MINOR=$(( (LIBARCHIVE_VERSION_N() / 1000) % 1000 )) -# Libarchive 2.7 == libtool interface 9 = 2 + 7 -# Libarchive 2.8 == libtool interface 10 = 2 + 8 -# Libarchive 2.9 == libtool interface 11 = 2 + 8 -# Libarchive 3.0 == libtool interface 12 -# Libarchive 3.1 == libtool interface 13 -ARCHIVE_INTERFACE=`echo $((13 + ${ARCHIVE_MINOR}))` -# Libarchive revision is bumped on any source change === libtool revision -ARCHIVE_REVISION=$(( LIBARCHIVE_VERSION_N() % 1000 )) -# Libarchive minor is bumped on any interface addition === libtool age -ARCHIVE_LIBTOOL_VERSION=$ARCHIVE_INTERFACE:$ARCHIVE_REVISION:$ARCHIVE_MINOR - -# Stick the version numbers into config.h -AC_DEFINE([__LIBARCHIVE_CONFIG_H_INCLUDED], [1], - [Internal macro for sanity checks]) -AC_DEFINE([LIBARCHIVE_VERSION_STRING],"LIBARCHIVE_VERSION_S()", - [Version number of libarchive]) -AC_DEFINE_UNQUOTED([LIBARCHIVE_VERSION_NUMBER],"LIBARCHIVE_VERSION_N()", - [Version number of libarchive as a single integer]) -AC_DEFINE([BSDCPIO_VERSION_STRING],"BSDCPIO_VERSION_S()", - [Version number of bsdcpio]) -AC_DEFINE([BSDTAR_VERSION_STRING],"BSDTAR_VERSION_S()", - [Version number of bsdtar]) -AC_DEFINE([BSDCAT_VERSION_STRING],"BSDTAR_VERSION_S()", - [Version number of bsdcat]) -AC_DEFINE([BSDUNZIP_VERSION_STRING],"BSDUNZIP_VERSION_S()", - [Version number of bsdunzip]) - -# The shell variables here must be the same as the AC_SUBST() variables -# below, but the shell variable names apparently cannot be the same as -# the m4 macro names above. Why? Ask autoconf. -BSDCPIO_VERSION_STRING=BSDCPIO_VERSION_S() -BSDTAR_VERSION_STRING=BSDTAR_VERSION_S() -BSDCAT_VERSION_STRING=BSDCAT_VERSION_S() -BSDUNZIP_VERSION_STRING=BSDUNZIP_VERSION_S() -LIBARCHIVE_VERSION_STRING=LIBARCHIVE_VERSION_S() -LIBARCHIVE_VERSION_NUMBER=LIBARCHIVE_VERSION_N() - -# Substitute the above version numbers into the various files below. -# Yes, I believe this is the fourth time we define what are essentially -# the same symbols. Why? Ask autoconf. -AC_SUBST(ARCHIVE_LIBTOOL_VERSION) -AC_SUBST(BSDCPIO_VERSION_STRING) -AC_SUBST(BSDTAR_VERSION_STRING) -AC_SUBST(BSDCAT_VERSION_STRING) -AC_SUBST(BSDUNZIP_VERSION_STRING) -AC_SUBST(LIBARCHIVE_VERSION_STRING) -AC_SUBST(LIBARCHIVE_VERSION_NUMBER) - -AC_CONFIG_HEADERS([config.h]) -AC_CONFIG_FILES([Makefile]) -AC_CONFIG_FILES([build/pkgconfig/libarchive.pc]) - -# Check for host type -AC_CANONICAL_HOST - -dnl Compilation on mingw and Cygwin needs special Makefile rules -inc_windows_files=no -inc_cygwin_files=no -case "$host_os" in - *mingw* ) inc_windows_files=yes ;; - *cygwin* | *msys*) inc_cygwin_files=yes ;; -esac -AM_CONDITIONAL([INC_WINDOWS_FILES], [test $inc_windows_files = yes]) -AM_CONDITIONAL([INC_CYGWIN_FILES], [test $inc_cygwin_files = yes]) - -dnl Defines that are required for specific platforms (e.g. -D_POSIX_SOURCE, etc) -PLATFORMCPPFLAGS= -case "$host_os" in - *mingw* ) PLATFORMCPPFLAGS=-D__USE_MINGW_ANSI_STDIO -D__MINGW_USE_VC2005_COMPAT ;; -esac -AC_SUBST(PLATFORMCPPFLAGS) - -# Checks for programs. -AC_PROG_CC -AM_PROG_CC_C_O -AC_PROG_CPP -AC_USE_SYSTEM_EXTENSIONS -AC_LIBTOOL_WIN32_DLL -AC_PROG_LIBTOOL -AC_CHECK_TOOL([STRIP],[strip]) -AC_PROG_MKDIR_P - -# -# Options for building bsdtar. -# -# Default is to build bsdtar, but allow people to override that. -# -AC_ARG_ENABLE([bsdtar], - [AS_HELP_STRING([--enable-bsdtar], [enable build of bsdtar (default)]) - AS_HELP_STRING([--enable-bsdtar=static], [force static build of bsdtar]) - AS_HELP_STRING([--enable-bsdtar=shared], [force dynamic build of bsdtar]) -AS_HELP_STRING([--disable-bsdtar], [disable build of bsdtar])], - [], [enable_bsdtar=yes]) - -case "$enable_bsdtar" in -yes) - if test "$enable_static" = "no"; then - static_bsdtar=no - else - static_bsdtar=yes - fi - build_bsdtar=yes - ;; -dynamic|shared) - if test "$enable_shared" = "no"; then - AC_MSG_FAILURE([Shared linking of bsdtar requires shared libarchive]) - fi - build_bsdtar=yes - static_bsdtar=no - ;; -static) - build_bsdtar=yes - static_bsdtar=yes - ;; -no) - build_bsdtar=no - static_bsdtar=no - ;; -*) - AC_MSG_FAILURE([Unsupported value for --enable-bsdtar]) - ;; -esac - -AM_CONDITIONAL([BUILD_BSDTAR], [ test "$build_bsdtar" = yes ]) -AM_CONDITIONAL([STATIC_BSDTAR], [ test "$static_bsdtar" = yes ]) - -# -# Options for building bsdcat. -# -# Default is to build bsdcat, but allow people to override that. -# -AC_ARG_ENABLE([bsdcat], - [AS_HELP_STRING([--enable-bsdcat], [enable build of bsdcat (default)]) - AS_HELP_STRING([--enable-bsdcat=static], [force static build of bsdcat]) - AS_HELP_STRING([--enable-bsdcat=shared], [force dynamic build of bsdcat]) -AS_HELP_STRING([--disable-bsdcat], [disable build of bsdcat])], - [], [enable_bsdcat=yes]) - -case "$enable_bsdcat" in -yes) - if test "$enable_static" = "no"; then - static_bsdcat=no - else - static_bsdcat=yes - fi - build_bsdcat=yes - ;; -dynamic|shared) - if test "$enable_shared" = "no"; then - AC_MSG_FAILURE([Shared linking of bsdcat requires shared libarchive]) - fi - build_bsdcat=yes - static_bsdcat=no - ;; -static) - build_bsdcat=yes - static_bsdcat=yes - ;; -no) - build_bsdcat=no - static_bsdcat=no - ;; -*) - AC_MSG_FAILURE([Unsupported value for --enable-bsdcat]) - ;; -esac - -AM_CONDITIONAL([BUILD_BSDCAT], [ test "$build_bsdcat" = yes ]) -AM_CONDITIONAL([STATIC_BSDCAT], [ test "$static_bsdcat" = yes ]) - -# -# Options for building bsdcpio. -# -# Default is not to build bsdcpio, but that can be overridden. -# -AC_ARG_ENABLE([bsdcpio], - [AS_HELP_STRING([--enable-bsdcpio], [enable build of bsdcpio (default)]) - AS_HELP_STRING([--enable-bsdcpio=static], [static build of bsdcpio]) - AS_HELP_STRING([--enable-bsdcpio=shared], [dynamic build of bsdcpio]) -AS_HELP_STRING([--disable-bsdcpio], [disable build of bsdcpio])], - [], [enable_bsdcpio=yes]) - -case "$enable_bsdcpio" in -yes) - if test "$enable_static" = "no"; then - static_bsdcpio=no - else - static_bsdcpio=yes - fi - build_bsdcpio=yes - ;; -dynamic|shared) - if test "$enabled_shared" = "no"; then - AC_MSG_FAILURE([Shared linking of bsdcpio requires shared libarchive]) - fi - build_bsdcpio=yes - ;; -static) - build_bsdcpio=yes - static_bsdcpio=yes - ;; -no) - build_bsdcpio=no - static_bsdcpio=no - ;; -*) - AC_MSG_FAILURE([Unsupported value for --enable-bsdcpio]) - ;; -esac - -AM_CONDITIONAL([BUILD_BSDCPIO], [ test "$build_bsdcpio" = yes ]) -AM_CONDITIONAL([STATIC_BSDCPIO], [ test "$static_bsdcpio" = yes ]) - -# Set up defines needed before including any headers -case $host in - *mingw* | *cygwin* | *msys* ) - AC_PREPROC_IFELSE([AC_LANG_PROGRAM( - [[#ifdef _WIN32_WINNT - # error _WIN32_WINNT already defined - #endif - ]],[[;]]) - ],[ - AC_DEFINE([_WIN32_WINNT], 0x0502, [Define to '0x0502' for Windows Server 2003 APIs.]) - AC_DEFINE([NTDDI_VERSION], 0x05020000, [Define to '0x05020000' for Windows Server 2003 APIs.]) - ]) - AC_PREPROC_IFELSE([AC_LANG_PROGRAM( - [[#ifdef WINVER - # error WINVER already defined - #endif - ]],[[;]]) - ],[ - AC_DEFINE([WINVER], 0x0502, [Define to '0x0502' for Windows Server 2003 APIs.]) - ]) - ;; -esac - -# -# Options for building bsdunzip. -# -# Default is to build bsdunzip, but allow people to override that. -# Bsdunzip has not yet been ported for Windows -# -case "$host_os" in - *mingw* | *msys*) - enable_bsdunzip=no - ;; - *) - AC_ARG_ENABLE([bsdunzip], - [AS_HELP_STRING([--enable-bsdunzip], [enable build of bsdunzip (default)]) - AS_HELP_STRING([--enable-bsdunzip=static], [force static build of bsdunzip]) - AS_HELP_STRING([--enable-bsdunzip=shared], [force dynamic build of bsdunzip]) - AS_HELP_STRING([--disable-bsdunzip], [disable build of bsdunzip])], - [], [enable_bsdunzip=yes]) - ;; -esac - -case "$enable_bsdunzip" in -yes) - if test "$enable_static" = "no"; then - static_bsdunzip=no - else - static_bsdunzip=yes - fi - build_bsdunzip=yes - ;; -dynamic|shared) - if test "$enable_shared" = "no"; then - AC_MSG_FAILURE([Shared linking of bsdunzip requires shared libarchive]) - fi - build_bsdunzip=yes - static_bsdunzip=no - ;; -static) - build_bsdunzip=yes - static_bsdunzip=yes - ;; -no) - build_bsdunzip=no - static_bsdunzip=no - ;; -*) - AC_MSG_FAILURE([Unsupported value for --enable-bsdunzip]) - ;; -esac - -AM_CONDITIONAL([BUILD_BSDUNZIP], [ test "$build_bsdunzip" = yes ]) -AM_CONDITIONAL([STATIC_BSDUNZIP], [ test "$static_bsdunzip" = yes ]) - -# Checks for header files. -AC_HEADER_DIRENT -AC_HEADER_SYS_WAIT -AC_CHECK_HEADERS([acl/libacl.h attr/xattr.h]) -AC_CHECK_HEADERS([copyfile.h ctype.h]) -AC_CHECK_HEADERS([errno.h ext2fs/ext2_fs.h fcntl.h fnmatch.h grp.h]) - -AC_CACHE_CHECK([whether EXT2_IOC_GETFLAGS is usable], - [ac_cv_have_decl_EXT2_IOC_GETFLAGS], - [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([@%:@include -@%:@include ], - [int x = EXT2_IOC_GETFLAGS])], - [AS_VAR_SET([ac_cv_have_decl_EXT2_IOC_GETFLAGS], [yes])], - [AS_VAR_SET([ac_cv_have_decl_EXT2_IOC_GETFLAGS], [no])])]) - -AS_VAR_IF([ac_cv_have_decl_EXT2_IOC_GETFLAGS], [yes], - [AC_DEFINE_UNQUOTED([HAVE_WORKING_EXT2_IOC_GETFLAGS], [1], - [Define to 1 if you have a working EXT2_IOC_GETFLAGS])]) - -AC_CHECK_HEADERS([inttypes.h io.h langinfo.h limits.h]) -AC_CHECK_HEADERS([linux/fiemap.h linux/fs.h linux/magic.h linux/types.h]) - -AC_CACHE_CHECK([whether FS_IOC_GETFLAGS is usable], - [ac_cv_have_decl_FS_IOC_GETFLAGS], - [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([@%:@include -@%:@include ], - [int x = FS_IOC_GETFLAGS])], - [AS_VAR_SET([ac_cv_have_decl_FS_IOC_GETFLAGS], [yes])], - [AS_VAR_SET([ac_cv_have_decl_FS_IOC_GETFLAGS], [no])])]) - -AS_VAR_IF([ac_cv_have_decl_FS_IOC_GETFLAGS], [yes], - [AC_DEFINE_UNQUOTED([HAVE_WORKING_FS_IOC_GETFLAGS], [1], - [Define to 1 if you have a working FS_IOC_GETFLAGS])]) - -AC_CHECK_HEADERS([locale.h membership.h paths.h poll.h pthread.h pwd.h]) -AC_CHECK_HEADERS([readpassphrase.h signal.h spawn.h]) -AC_CHECK_HEADERS([stdarg.h stdint.h stdlib.h string.h]) -AC_CHECK_HEADERS([sys/acl.h sys/cdefs.h sys/ea.h sys/extattr.h]) -AC_CHECK_HEADERS([sys/ioctl.h sys/mkdev.h sys/mount.h sys/queue.h]) -AC_CHECK_HEADERS([sys/param.h sys/poll.h sys/richacl.h]) -AC_CHECK_HEADERS([sys/select.h sys/statfs.h sys/statvfs.h sys/sysmacros.h]) -AC_CHECK_HEADERS([sys/time.h sys/utime.h sys/utsname.h sys/vfs.h sys/xattr.h]) -AC_CHECK_HEADERS([time.h unistd.h utime.h wchar.h wctype.h]) -AC_CHECK_HEADERS([windows.h]) -# check windows.h first; the other headers require it. -AC_CHECK_HEADERS([wincrypt.h winioctl.h],[],[], -[[#ifdef HAVE_WINDOWS_H -# include -#endif -]]) - -# Checks for libraries. -AC_ARG_WITH([zlib], - AS_HELP_STRING([--without-zlib], [Don't build support for gzip through zlib])) - -if test "x$with_zlib" != "xno"; then - AC_CHECK_HEADERS([zlib.h]) - AC_CHECK_LIB(z,inflate) -fi - -AC_ARG_WITH([bz2lib], - AS_HELP_STRING([--without-bz2lib], [Don't build support for bzip2 through bz2lib])) - -if test "x$with_bz2lib" != "xno"; then - AC_CHECK_HEADERS([bzlib.h]) - case "$host_os" in - *mingw* | *cygwin* | *msys*) - dnl AC_CHECK_LIB cannot be used on the Windows port of libbz2, therefore - dnl use AC_LINK_IFELSE. - AC_MSG_CHECKING([for BZ2_bzDecompressInit in -lbz2]) - old_LIBS="$LIBS" - LIBS="-lbz2 $LIBS" - AC_LINK_IFELSE( - [AC_LANG_SOURCE(#include - int main() { return BZ2_bzDecompressInit(NULL, 0, 0); })], - [ac_cv_lib_bz2_BZ2_bzDecompressInit=yes], - [ac_cv_lib_bz2_BZ2_bzDecompressInit=no]) - LIBS="$old_LIBS" - AC_MSG_RESULT($ac_cv_lib_bz2_BZ2_bzDecompressInit) - if test "x$ac_cv_lib_bz2_BZ2_bzDecompressInit" = xyes; then - AC_DEFINE([HAVE_LIBBZ2], [1], [Define to 1 if you have the `bz2' library (-lbz2).]) - LIBS="-lbz2 $LIBS" - fi - ;; - *) - AC_CHECK_LIB(bz2,BZ2_bzDecompressInit) - ;; - esac -fi - -AC_ARG_WITH([libb2], - AS_HELP_STRING([--without-libb2], [Don't build support for BLAKE2 through libb2])) - -if test "x$with_libb2" != "xno"; then - AC_CHECK_HEADERS([blake2.h]) - AC_CHECK_LIB(b2,blake2sp_init) -fi - -AM_CONDITIONAL([INC_BLAKE2], [test "x$ac_cv_lib_b2_blake2sp_init" != "xyes"]) - -AC_ARG_WITH([iconv], - AS_HELP_STRING([--without-iconv], [Don't try to link against iconv])) - -if test "x$with_iconv" != "xno"; then - AM_ICONV - AC_CHECK_HEADERS([iconv.h],[],[],[#include ]) - if test "x$am_cv_func_iconv" = "xyes"; then - AC_CHECK_HEADERS([localcharset.h]) - am_save_LIBS="$LIBS" - LIBS="${LIBS} ${LIBICONV}" - if test -n "$LIBICONV"; then - LIBSREQUIRED="$LIBSREQUIRED${LIBSREQUIRED:+ }iconv" - fi - AC_CHECK_FUNCS([locale_charset]) - LIBS="${am_save_LIBS}" - if test "x$ac_cv_func_locale_charset" != "xyes"; then - # If locale_charset() is not in libiconv, we have to find libcharset. - AC_CHECK_LIB(charset,locale_charset) - fi - fi -fi - -AC_ARG_WITH([lz4], - AS_HELP_STRING([--without-lz4], [Don't build support for lz4 through liblz4])) - -if test "x$with_lz4" != "xno"; then - AC_CHECK_HEADERS([lz4.h lz4hc.h]) - AC_CHECK_LIB(lz4,LZ4_decompress_safe) -fi - -AC_ARG_WITH([zstd], - AS_HELP_STRING([--without-zstd], [Don't build support for zstd through libzstd])) - -if test "x$with_zstd" != "xno"; then - AC_CHECK_HEADERS([zstd.h]) - AC_CHECK_LIB(zstd,ZSTD_decompressStream) - AC_CHECK_LIB(zstd,ZSTD_compressStream, - AC_DEFINE([HAVE_LIBZSTD_COMPRESSOR], [1], [Define to 1 if you have the `zstd' library (-lzstd) with compression support.])) -fi - -AC_ARG_WITH([lzma], - AS_HELP_STRING([--without-lzma], [Don't build support for xz through lzma])) - -if test "x$with_lzma" != "xno"; then - AC_CHECK_HEADERS([lzma.h]) - AC_CHECK_LIB(lzma,lzma_stream_decoder) - # Some pre-release (but widely distributed) versions of liblzma - # included a disabled version of lzma_stream_encoder_mt that - # fools a naive AC_CHECK_LIB or AC_CHECK_FUNC, so we need - # to do something more complex here: - AC_CACHE_CHECK( - [whether we have multithread support in lzma], - ac_cv_lzma_has_mt, - [AC_LINK_IFELSE([ - AC_LANG_PROGRAM([[#include ] - [#if LZMA_VERSION < 50020000] - [#error unsupported] - [#endif]], - [[lzma_stream_encoder_mt(0, 0);]])], - [ac_cv_lzma_has_mt=yes], [ac_cv_lzma_has_mt=no])]) - if test "x$ac_cv_lzma_has_mt" != xno; then - AC_DEFINE([HAVE_LZMA_STREAM_ENCODER_MT], [1], [Define to 1 if you have the `lzma_stream_encoder_mt' function.]) - fi - - AC_CACHE_CHECK( - [whether we have ARM64 filter support in lzma], - ac_cv_lzma_has_arm64, - [AC_LINK_IFELSE([ - AC_LANG_PROGRAM([[#include ] - [#ifndef LZMA_FILTER_ARM64] - [#error unsupported] - [#endif]])], - [ac_cv_lzma_has_arm64=yes], [ac_cv_lzma_has_arm64=no])]) - if test "x$ac_cv_lzma_has_arm64" != xno; then - AC_DEFINE([HAVE_LZMA_FILTER_ARM64], [1], [Define to 1 if you have the `LZMA_FILTER_ARM64' macro.]) - fi -fi - -AC_ARG_WITH([lzo2], - AS_HELP_STRING([--with-lzo2], [Build with LZO support from liblzo2])) - -if test "x$with_lzo2" = "xyes"; then - AC_CHECK_HEADERS([lzo/lzoconf.h lzo/lzo1x.h]) - AC_CHECK_LIB(lzo2,lzo1x_decompress_safe) -fi - -AC_ARG_WITH([cng], - AS_HELP_STRING([--without-cng], [Don't build support of CNG(Crypto Next Generation)])) - -AC_ARG_WITH([mbedtls], - AS_HELP_STRING([--with-mbedtls], [Build with crypto support from mbed TLS])) -AC_ARG_WITH([nettle], - AS_HELP_STRING([--with-nettle], [Build with crypto support from Nettle])) -AC_ARG_WITH([openssl], - AS_HELP_STRING([--without-openssl], [Don't build support for mtree and xar hashes through openssl])) -case "$host_os" in - *darwin* ) with_openssl=no ;; -esac - -AC_ARG_WITH([xml2], - AS_HELP_STRING([--without-xml2], [Don't build support for xar through libxml2])) -AC_ARG_WITH([expat], - AS_HELP_STRING([--without-expat], [Don't build support for xar through expat])) - -if test "x$with_xml2" != "xno"; then - PKG_PROG_PKG_CONFIG - PKG_CHECK_MODULES(LIBXML2_PC, [libxml-2.0], [ - CPPFLAGS="${CPPFLAGS} ${LIBXML2_PC_CFLAGS}" - LIBS="${LIBS} ${LIBXML2_PC_LIBS}" - AC_CHECK_LIB(xml2,xmlInitParser,[true],AC_MSG_FAILURE(Missing xml2 library)) - ], [ - AC_CHECK_LIB(xml2,xmlInitParser) - ]) - AC_CHECK_HEADERS([libxml/xmlreader.h libxml/xmlwriter.h]) -fi -if test "x$ac_cv_header_libxml_xmlreader_h" != "xyes"; then - if test "x$with_expat" != "xno"; then - AC_CHECK_HEADERS([expat.h]) - AC_CHECK_LIB(expat,XML_ParserCreate) - fi -fi - -AC_ARG_ENABLE([posix-regex-lib], - [AS_HELP_STRING([--enable-posix-regex-lib], - [choose what library to use for POSIX regular expression support (default: auto)]) - AS_HELP_STRING([--enable-posix-regex-lib=libc], [use libc POSIX regular expression support]) - AS_HELP_STRING([--enable-posix-regex-lib=libregex], [use libregex POSIX regular expression support]) - AS_HELP_STRING([--enable-posix-regex-lib=libpcreposix], [use libpcreposix POSIX regular expression support]) - AS_HELP_STRING([--disable-posix-regex-lib], [don't enable POSIX regular expression support])], - [], [enable_posix_regex_lib=auto]) - -posix_regex_lib_found= -if test "$enable_posix_regex_lib" = "auto" || test "$enable_posix_regex_lib" = "libc" || test "$enable_posix_regex_lib" = "libregex"; then - AC_CHECK_HEADERS([regex.h]) - if test "x$ac_cv_header_regex_h" != "xno"; then - AC_CHECK_FUNC(regcomp) - if test "x$ac_cv_func_regcomp" = xyes; then - posix_regex_lib_found=1 - else - AC_CHECK_LIB(regex,regcomp) - if test "x$ac_cv_lib_regex_regcomp" = xyes; then - posix_regex_lib_found=1 - fi - fi - fi -fi -if test -z $posix_regex_lib_found && (test "$enable_posix_regex_lib" = "auto" || test "$enable_posix_regex_lib" = "libpcreposix"); then - AC_CHECK_HEADERS([pcreposix.h]) - AC_CHECK_LIB(pcreposix,regcomp) - if test "x$ac_cv_lib_pcreposix_regcomp" != xyes; then - AC_MSG_NOTICE(trying libpcreposix check again with libpcre) - unset ac_cv_lib_pcreposix_regcomp - AC_CHECK_LIB(pcre,pcre_exec) - AC_CHECK_LIB(pcreposix,regcomp) - if test "x$ac_cv_lib_pcre_pcre_exec" = xyes && test "x$ac_cv_lib_pcreposix_regcomp" = xyes; then - AC_MSG_CHECKING(if PCRE_STATIC needs to be defined) - AC_LINK_IFELSE( - [AC_LANG_SOURCE(#include - int main() { return regcomp(NULL, NULL, 0); })], - [without_pcre_static=yes], - [without_pcre_static=no]) - AC_LINK_IFELSE( - [AC_LANG_SOURCE(#define PCRE_STATIC - #include - int main() { return regcomp(NULL, NULL, 0); })], - [with_pcre_static=yes], - [with_pcre_static=no]) - if test "x$without_pcre_static" != xyes && test "x$with_pcre_static" = xyes; then - AC_MSG_RESULT(yes) - AC_DEFINE([PCRE_STATIC], [1], [Define to 1 if PCRE_STATIC needs to be defined.]) - elif test "x$without_pcre_static" = xyes || test "x$with_pcre_static" = xyes; then - AC_MSG_RESULT(no) - fi - posix_regex_lib_found=1 - fi - else - posix_regex_lib_found=1 - fi -fi - -# TODO: Give the user the option of using a pre-existing system -# libarchive. This will define HAVE_LIBARCHIVE which will cause -# bsdtar_platform.h to use #include <...> for the libarchive headers. -# Need to include Makefile.am magic to link against system -# -larchive in that case. -#AC_CHECK_LIB(archive,archive_version) - -# Checks for supported compiler flags -AX_APPEND_COMPILE_FLAGS([-Wall -Wformat -Wformat-security]) - -# Place the functions and data into separate sections, allowing the linker -# to garbage collect the unused ones. -save_LDFLAGS=$LDFLAGS -LDFLAGS="$LDFLAGS -Wl,--gc-sections" -AC_MSG_CHECKING([whether ld supports --gc-sections]) -AC_LINK_IFELSE( - [AC_LANG_SOURCE([static char UnusedFunc() { return 5; } int main() { return 0;}])], - [AC_MSG_RESULT([yes]) - GC_SECTIONS="-Wl,--gc-sections"; - AX_APPEND_COMPILE_FLAGS([-ffunction-sections -fdata-sections])], - [AC_MSG_RESULT([no]) - GC_SECTIONS="";]) -LDFLAGS=$save_LDFLAGS - -AC_SUBST(GC_SECTIONS) - -# Checks for typedefs, structures, and compiler characteristics. -AC_C_CONST -# la_TYPE_UID_T defaults to "int", which is incorrect for MinGW -# and MSVC. Use a customized version. -la_TYPE_UID_T -AC_TYPE_MODE_T -# AC_TYPE_OFF_T defaults to "long", which limits us to 4GB files on -# most systems... default to "long long" instead. -AC_CHECK_TYPE(off_t, [long long]) -AC_TYPE_SIZE_T -AC_CHECK_TYPE(id_t, [unsigned long]) -AC_CHECK_TYPE(uintptr_t, [unsigned int]) - -# Check for tm_gmtoff in struct tm -AC_CHECK_MEMBERS([struct tm.tm_gmtoff, struct tm.__tm_gmtoff],,, -[ -#include -]) - -# Check for f_namemax in struct statfs -AC_CHECK_MEMBERS([struct statfs.f_namemax],,, -[ -#include -#include -]) - -# Check for f_iosize in struct statfs -AC_CHECK_MEMBERS([struct statfs.f_iosize],,, -[ -#include -#include -]) - -# Check for f_iosize in struct statvfs -AC_CHECK_MEMBERS([struct statvfs.f_iosize],,, -[ -#include -]) - -# Check for birthtime in struct stat -AC_CHECK_MEMBERS([struct stat.st_birthtime]) - -# Check for high-resolution timestamps in struct stat -AC_CHECK_MEMBERS([struct stat.st_birthtimespec.tv_nsec]) -AC_CHECK_MEMBERS([struct stat.st_mtimespec.tv_nsec]) -AC_CHECK_MEMBERS([struct stat.st_mtim.tv_nsec]) -AC_CHECK_MEMBERS([struct stat.st_mtime_n]) # AIX -AC_CHECK_MEMBERS([struct stat.st_umtime]) # Tru64 -AC_CHECK_MEMBERS([struct stat.st_mtime_usec]) # Hurd -# Check for block size support in struct stat -AC_CHECK_MEMBERS([struct stat.st_blksize]) -# Check for st_flags in struct stat (BSD fflags) -AC_CHECK_MEMBERS([struct stat.st_flags]) - -# If you have uintmax_t, we assume printf supports %ju -# If you have unsigned long long, we assume printf supports %llu -# TODO: Check for %ju and %llu support directly. -AC_CHECK_TYPES([uintmax_t, unsigned long long]) - -# We use C99-style integer types -# Declare them if the local platform doesn't already do so. -AC_TYPE_INTMAX_T -AC_TYPE_UINTMAX_T -AC_TYPE_INT64_T -AC_TYPE_UINT64_T -AC_TYPE_INT32_T -AC_TYPE_UINT32_T -AC_TYPE_INT16_T -AC_TYPE_UINT16_T -AC_TYPE_UINT8_T - -AC_CHECK_DECLS([SIZE_MAX, INT32_MAX, INT32_MIN]) -AC_CHECK_DECLS([INT64_MAX, INT64_MIN, UINT64_MAX, UINT32_MAX]) -AC_CHECK_DECLS([INTMAX_MAX, INTMAX_MIN, UINTMAX_MAX]) - -AC_CHECK_DECL([SSIZE_MAX], - [AC_DEFINE(HAVE_DECL_SSIZE_MAX, 1, [Define to 1 if you have the declaration of `SSIZE_MAX', and to 0 if you don't.])], - [], - [#include ]) - -AC_CHECK_DECL([EFTYPE], - [AC_DEFINE(HAVE_EFTYPE, 1, [A possible errno value for invalid file format errors])], - [], - [#include ]) -AC_CHECK_DECL([EILSEQ], - [AC_DEFINE(HAVE_EILSEQ, 1, [A possible errno value for invalid file format errors])], - [], - [#include ]) -AC_CHECK_TYPE([wchar_t], - [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_[]wchar_t), 1, [Define to 1 if the system has the type `wchar_t'.])dnl - AC_CHECK_SIZEOF([wchar_t])], - []) - -AX_COMPILE_CHECK_SIZEOF(int) -AX_COMPILE_CHECK_SIZEOF(long) - -AC_CHECK_HEADERS_ONCE([sys/time.h]) - -# Checks for library functions. -AC_PROG_GCC_TRADITIONAL -AC_HEADER_MAJOR -AC_FUNC_FSEEKO -AC_FUNC_MEMCMP -AC_FUNC_LSTAT -AC_FUNC_STAT -AC_FUNC_STRERROR_R -AC_FUNC_STRFTIME -AC_FUNC_VPRINTF -# check for: -# CreateHardLinkA(LPCSTR, LPCSTR, LPSECURITY_ATTRIBUTES) -# To avoid necessity for including windows.h or special forward declaration -# workarounds, we use 'void *' for 'struct SECURITY_ATTRIBUTES *' -AC_CHECK_STDCALL_FUNC([CreateHardLinkA],[const char *, const char *, void *]) -AC_CHECK_FUNCS([arc4random_buf chflags chown chroot ctime_r]) -AC_CHECK_FUNCS([fchdir fchflags fchmod fchown fcntl fdopendir fnmatch fork]) -AC_CHECK_FUNCS([fstat fstatat fstatfs fstatvfs ftruncate]) -AC_CHECK_FUNCS([futimens futimes futimesat]) -AC_CHECK_FUNCS([geteuid getline getpid getgrgid_r getgrnam_r]) -AC_CHECK_FUNCS([getpwnam_r getpwuid_r getvfsbyname gmtime_r]) -AC_CHECK_FUNCS([lchflags lchmod lchown link linkat localtime_r lstat lutimes]) -AC_CHECK_FUNCS([mbrtowc memmove memset]) -AC_CHECK_FUNCS([mkdir mkfifo mknod mkstemp]) -AC_CHECK_FUNCS([nl_langinfo openat pipe poll posix_spawnp readlink readlinkat]) -AC_CHECK_FUNCS([readpassphrase]) -AC_CHECK_FUNCS([select setenv setlocale sigaction statfs statvfs]) -AC_CHECK_FUNCS([strchr strdup strerror strncpy_s strnlen strrchr symlink]) -AC_CHECK_FUNCS([timegm tzset unlinkat unsetenv utime utimensat utimes vfork]) -AC_CHECK_FUNCS([wcrtomb wcscmp wcscpy wcslen wctomb wmemcmp wmemcpy wmemmove]) -AC_CHECK_FUNCS([_fseeki64 _get_timezone]) -AC_CHECK_DECL([cmtime_s], - [AC_DEFINE(HAVE_CMTIME_S, 1, [cmtime_s function])], - [], - [#include ]) -AC_CHECK_DECL([gmtime_s], - [AC_DEFINE(HAVE_GMTIME_S, 1, [gmtime_s function])], - [], - [#include ]) -AC_CHECK_TYPE([localtime_s], - [AC_DEFINE(HAVE_LOCALTIME_S, 1, [localtime_s function])], - [], - [#include ]) -AC_CHECK_DECL([_mkgmtime], - [AC_DEFINE(HAVE__MKGMTIME, 1, [_mkgmtime function])], - [], - [#include ]) - -# detects cygwin-1.7, as opposed to older versions -AC_CHECK_FUNCS([cygwin_conv_path]) - -# DragonFly uses vfsconf, FreeBSD xvfsconf. -AC_CHECK_TYPES(struct vfsconf,,, - [#if HAVE_SYS_TYPES_H - #include - #endif - #include - ]) - -AC_CHECK_TYPES(struct xvfsconf,,, - [#if HAVE_SYS_TYPES_H - #include - #endif - #include - ]) - -AC_CHECK_TYPES(struct statfs,,, - [#if HAVE_SYS_TYPES_H - #include - #endif - #include - ]) - -# There are several variants of readdir_r around; we only -# accept the POSIX-compliant version. -AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[#include ]], - [[DIR *dir; struct dirent e, *r; - return(readdir_r(dir, &e, &r));]])], - [AC_DEFINE(HAVE_READDIR_R,1,[Define to 1 if you have a POSIX compatible readdir_r])] -) -# dirfd can be either a function or a macro. -AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[#include - DIR *dir;]], - [[return(dirfd(dir));]])], - [AC_DEFINE(HAVE_DIRFD,1,[Define to 1 if you have a dirfd function or macro])] -) - -# FreeBSD's nl_langinfo supports an option to specify whether the -# current locale uses month/day or day/month ordering. It makes the -# output a little prettier... -AC_CHECK_DECL([D_MD_ORDER], -[AC_DEFINE(HAVE_D_MD_ORDER, 1, [Define to 1 if nl_langinfo supports D_MD_ORDER])], -[], -[#if HAVE_LANGINFO_H -#include -#endif -]) - -# Check for dirent.d_namlen field explicitly -# (This is a bit more straightforward than, if not quite as portable as, -# the recipe given by the autoconf maintainers.) -AC_CHECK_MEMBER(struct dirent.d_namlen,,, -[#if HAVE_DIRENT_H -#include -#endif -]) - -# Check for Extended Attributes support -AC_ARG_ENABLE([xattr], - AS_HELP_STRING([--disable-xattr], - [Disable Extended Attributes support (default: check)])) - -if test "x$enable_xattr" != "xno"; then - AC_SEARCH_LIBS([setxattr], [attr gnu]) - AC_CHECK_DECLS([EXTATTR_NAMESPACE_USER], [], [], [#include -#include -]) - AC_CHECK_DECLS([XATTR_NOFOLLOW], [], [], [#include -]) - if test "x$ac_cv_header_sys_xattr_h" = "xyes" \ - -a "x$ac_cv_have_decl_XATTR_NOFOLLOW" = "xyes"; then - # Darwin extended attributes support - AC_CACHE_VAL([ac_cv_archive_xattr_darwin], - [AC_CHECK_FUNCS(fgetxattr \ - flistxattr \ - fsetxattr \ - getxattr \ - listxattr \ - setxattr, - [ac_cv_archive_xattr_darwin=yes], - [ac_cv_archive_xattr_darwin=no], - [#include -]) - ] - ) - elif test "x$ac_cv_header_sys_extattr_h" = "xyes" \ - -a "x$ac_cv_have_decl_EXTATTR_NAMESPACE_USER" = "xyes"; then - # FreeBSD extended attributes support - AC_CACHE_VAL([ac_cv_archive_xattr_freebsd], - [AC_CHECK_FUNCS(extattr_get_fd \ - extattr_get_file \ - extattr_get_link \ - extattr_list_fd \ - extattr_list_file \ - extattr_list_link \ - extattr_set_fd \ - extattr_set_link, - [ac_cv_archive_xattr_freebsd=yes], - [ac_cv_archive_xattr_freebsd=no], - [#include -#include -]) - ] - ) - elif test "x$ac_cv_header_sys_xattr_h" = "xyes" \ - -o "x$ac_cv_header_attr_xattr_h" = "xyes"; then - # Linux extended attributes support - AC_CACHE_VAL([ac_cv_archive_xattr_linux], - [AC_CHECK_FUNCS(fgetxattr \ - flistxattr \ - fsetxattr \ - getxattr \ - lgetxattr \ - listxattr \ - llistxattr \ - lsetxattr, - [ac_cv_archive_xattr_linux=yes], - [ac_cv_archive_xattr_linux=no], - [#if HAVE_SYS_TYPES_H -#include -#endif -#if HAVE_SYS_XATTR_H -#include -#endif -#if HAVE_ATTR_XATTR_H -#include -#endif -]) - ] - ) - elif test "x$ac_cv_header_sys_ea_h" = "xyes"; then - # AIX extended attributes support - AC_CACHE_VAL([ac_cv_archive_xattr_aix], - [AC_CHECK_FUNCS(fgetea \ - flistea \ - fsetea \ - getea \ - lgetea \ - listea \ - llistea \ - lsetea, - [ac_cv_archive_xattr_aix=yes], - [ac_cv_archive_xattr_aix=no], - [#include -]) - ] - ) - fi - - AC_MSG_CHECKING([for extended attributes support]) - if test "x$ac_cv_archive_xattr_linux" = "xyes"; then - AC_DEFINE([ARCHIVE_XATTR_LINUX], [1], [Linux xattr support]) - AC_MSG_RESULT([Linux]) - elif test "x$ac_cv_archive_xattr_darwin" = "xyes"; then - AC_DEFINE([ARCHIVE_XATTR_DARWIN], [1], [Darwin xattr support]) - AC_MSG_RESULT([Darwin]) - elif test "x$ac_cv_archive_xattr_freebsd" = "xyes"; then - AC_DEFINE([ARCHIVE_XATTR_FREEBSD], [1], [FreeBSD xattr support]) - AC_MSG_RESULT([FreeBSD]) - elif test "x$ac_cv_archive_xattr_aix" = "xyes"; then - AC_DEFINE([ARCHIVE_XATTR_AIX], [1], [AIX xattr support]) - AC_MSG_RESULT([AIX]) - else - AC_MSG_RESULT([none]) - fi -fi - -# Check for ACL support -# -# The ACL support in libarchive is written against the POSIX1e draft, -# which was never officially approved and varies quite a bit across -# platforms. Worse, some systems have completely non-POSIX acl functions, -# which makes the following checks rather more complex than I would like. -# -AC_ARG_ENABLE([acl], - AS_HELP_STRING([--disable-acl], - [Disable ACL support (default: check)])) - -if test "x$enable_acl" != "xno"; then - # Libacl - AC_CHECK_LIB([acl], [acl_get_file]) - - AC_CHECK_TYPES([acl_t, acl_entry_t, acl_permset_t, acl_tag_t], [], [], [ - #if HAVE_SYS_TYPES_H - #include - #endif - #if HAVE_SYS_ACL_H - #include - #endif - ]) - - AC_CHECK_LIB([richacl], [richacl_get_file]) - - AC_CHECK_TYPES([[struct richace], [struct richacl]], [], [], [ - #if HAVE_SYS_RICHACL_H - #include - #endif - ]) - - # Solaris and derivates ACLs - AC_CHECK_FUNCS(acl facl) - - if test "x$ac_cv_lib_richacl_richacl_get_file" = "xyes" \ - -a "x$ac_cv_type_struct_richace" = "xyes" \ - -a "x$ac_cv_type_struct_richacl" = "xyes"; then - AC_CACHE_VAL([ac_cv_archive_acl_librichacl], - [AC_CHECK_FUNCS(richacl_alloc \ - richacl_equiv_mode \ - richacl_free \ - richacl_get_fd \ - richacl_get_file \ - richacl_set_fd \ - richacl_set_file, - [ac_cv_archive_acl_librichacl=yes], [ac_cv_archive_acl_librichacl=no], [#include ])]) - fi - - if test "x$ac_cv_func_acl" = "xyes" \ - -a "x$ac_cv_func_facl" = "xyes"; then - AC_CHECK_TYPES([aclent_t], [], [], [[#include ]]) - if test "x$ac_cv_type_aclent_t" = "xyes"; then - AC_CACHE_VAL([ac_cv_archive_acl_sunos], - [AC_CHECK_DECLS([GETACL, SETACL, GETACLCNT], - [ac_cv_archive_acl_sunos=yes], [ac_cv_archive_acl_sunos=no], - [#include ])]) - AC_CHECK_TYPES([ace_t], [], [], [[#include ]]) - if test "x$ac_cv_type_ace_t" = "xyes"; then - AC_CACHE_VAL([ac_cv_archive_acl_sunos_nfs4], - [AC_CHECK_DECLS([ACE_GETACL, ACE_SETACL, ACE_GETACLCNT], - [ac_cv_archive_acl_sunos_nfs4=yes], - [ac_cv_archive_acl_sonos_nfs4=no], - [#include ])]) - fi - fi - elif test "x$ac_cv_type_acl_t" = "xyes" \ - -a "x$ac_cv_type_acl_entry_t" = "xyes" \ - -a "x$ac_cv_type_acl_permset_t" = "xyes" \ - -a "x$ac_cv_type_acl_tag_t" = "xyes"; then - # POSIX.1e ACL functions - AC_CACHE_VAL([ac_cv_posix_acl_funcs], - [AC_CHECK_FUNCS(acl_add_perm \ - acl_clear_perms \ - acl_create_entry \ - acl_delete_def_file \ - acl_free \ - acl_get_entry \ - acl_get_fd \ - acl_get_file \ - acl_get_permset \ - acl_get_qualifier \ - acl_get_tag_type \ - acl_init \ - acl_set_fd \ - acl_set_file \ - acl_set_qualifier \ - acl_set_tag_type, - [ac_cv_posix_acl_funcs=yes], [ac_cv_posix_acl_funcs=no], - [#if HAVE_SYS_TYPES_H - #include - #endif - #if HAVE_SYS_ACL_H - #include - #endif - ]) - ]) - - AC_CHECK_FUNCS(acl_get_perm) - - if test "x$ac_cv_posix_acl_funcs" = "xyes" \ - -a "x$ac_cv_header_acl_libacl_h" = "xyes" \ - -a "x$ac_cv_lib_acl_acl_get_file" = "xyes" \ - -a "x$ac_cv_func_acl_get_perm"; then - AC_CACHE_VAL([ac_cv_archive_acl_libacl], - [ac_cv_archive_acl_libacl=yes]) - AC_DEFINE([ARCHIVE_ACL_LIBACL], [1], - [POSIX.1e ACL support via libacl]) - else - # FreeBSD/Darwin - AC_CHECK_FUNCS(acl_add_flag_np \ - acl_clear_flags_np \ - acl_get_brand_np \ - acl_get_entry_type_np \ - acl_get_flag_np \ - acl_get_flagset_np \ - acl_get_fd_np \ - acl_get_link_np \ - acl_get_perm_np \ - acl_is_trivial_np \ - acl_set_entry_type_np \ - acl_set_fd_np \ - acl_set_link_np,,, - [#include - #include ]) - - AC_CHECK_FUNCS(mbr_uid_to_uuid \ - mbr_uuid_to_id \ - mbr_gid_to_uuid,,, - [#include ]) - - AC_CHECK_DECLS([ACL_TYPE_EXTENDED, ACL_TYPE_NFS4, ACL_USER, - ACL_SYNCHRONIZE], [], [], - [#include - #include ]) - if test "x$ac_cv_posix_acl_funcs" = "xyes" \ - -a "x$ac_cv_func_acl_get_fd_np" = "xyes" \ - -a "x$ac_cv_func_acl_get_perm" != "xyes" \ - -a "x$ac_cv_func_acl_get_perm_np" = "xyes" \ - -a "x$ac_cv_func_acl_set_fd_np" = "xyes"; then - if test "x$ac_cv_have_decl_ACL_USER" = "xyes"; then - AC_CACHE_VAL([ac_cv_archive_acl_freebsd], - [ac_cv_archive_acl_freebsd=yes]) - if test "x$ac_cv_have_decl_ACL_TYPE_NFS4" = "xyes" \ - -a "x$ac_cv_func_acl_add_flag_np" = "xyes" \ - -a "x$ac_cv_func_acl_get_brand_np" = "xyes" \ - -a "x$ac_cv_func_acl_get_entry_type_np" = "xyes" \ - -a "x$ac_cv_func_acl_get_flagset_np" = "xyes" \ - -a "x$ac_cv_func_acl_set_entry_type_np" = "xyes"; then - AC_CACHE_VAL([ac_cv_archive_acl_freebsd_nfs4], - [ac_cv_archive_acl_freebsd_nfs4=yes]) - fi - elif test "x$ac_cv_have_decl_ACL_TYPE_EXTENDED" = "xyes" \ - -a "x$ac_cv_func_acl_add_flag_np" = "xyes" \ - -a "x$ac_cv_func_acl_get_flagset_np" = "xyes" \ - -a "x$ac_cv_func_acl_get_link_np" = "xyes" \ - -a "x$ac_cv_func_acl_set_link_np" = "xyes" \ - -a "x$ac_cv_func_mbr_uid_to_uuid" = "xyes" \ - -a "x$ac_cv_func_mbr_uuid_to_id" = "xyes" \ - -a "x$ac_cv_func_mbr_gid_to_uuid" = "xyes"; then - AC_CACHE_VAL([ac_cv_archive_acl_darwin], - [ac_cv_archive_acl_darwin=yes]) - fi - fi - fi - fi - AC_MSG_CHECKING([for ACL support]) - if test "x$ac_cv_archive_acl_libacl" = "xyes" \ - -a "x$ac_cv_archive_acl_librichacl" = "xyes"; then - AC_MSG_RESULT([libacl (POSIX.1e) + librichacl (NFSv4)]) - AC_DEFINE([ARCHIVE_ACL_LIBACL], [1], - [Linux POSIX.1e ACL support via libacl]) - AC_DEFINE([ARCHIVE_ACL_LIBRICHACL], [1], - [Linux NFSv4 ACL support via librichacl]) - elif test "x$ac_cv_archive_acl_libacl" = "xyes"; then - AC_MSG_RESULT([libacl (POSIX.1e)]) - AC_DEFINE([ARCHIVE_ACL_LIBACL], [1], - [Linux POSIX.1e ACL support via libacl]) - elif test "x$ac_cv_archive_acl_librichacl" = "xyes"; then - AC_MSG_RESULT([librichacl (NFSv4)]) - AC_DEFINE([ARCHIVE_ACL_LIBRICHACL], [1], - [Linux NFSv4 ACL support via librichacl]) - elif test "x$ac_cv_archive_acl_darwin" = "xyes"; then - AC_DEFINE([ARCHIVE_ACL_DARWIN], [1], [Darwin ACL support]) - AC_MSG_RESULT([Darwin (limited NFSv4)]) - elif test "x$ac_cv_archive_acl_sunos" = "xyes"; then - AC_DEFINE([ARCHIVE_ACL_SUNOS], [1], [Solaris ACL support]) - if test "x$ac_cv_archive_acl_sunos_nfs4" = "xyes"; then - AC_DEFINE([ARCHIVE_ACL_SUNOS_NFS4], [1], - [Solaris NFSv4 ACL support]) - AC_MSG_RESULT([Solaris (POSIX.1e and NFSv4)]) - else - AC_MSG_RESULT([Solaris (POSIX.1e)]) - fi - elif test "x$ac_cv_archive_acl_freebsd" = "xyes"; then - AC_DEFINE([ARCHIVE_ACL_FREEBSD], [1], [FreeBSD ACL support]) - if test "x$ac_cv_archive_acl_freebsd_nfs4" = "xyes"; then - AC_DEFINE([ARCHIVE_ACL_FREEBSD_NFS4], [1], - [FreeBSD NFSv4 ACL support]) - AC_MSG_RESULT([FreeBSD (POSIX.1e and NFSv4)]) - else - AC_MSG_RESULT([FreeBSD (POSIX.1e)]) - fi - else - AC_MSG_RESULT([none]) - fi -fi - - -AM_CONDITIONAL([INC_LINUX_ACL], - [test "x$ac_cv_archive_acl_libacl" = "xyes" \ - -o "x$ac_cv_archive_acl_librichacl" = "xyes"]) -AM_CONDITIONAL([INC_SUNOS_ACL], [test "x$ac_cv_archive_acl_sunos" = "xyes"]) -AM_CONDITIONAL([INC_DARWIN_ACL], - [test "x$ac_cv_archive_acl_darwin" = "xyes"]) -AM_CONDITIONAL([INC_FREEBSD_ACL], - [test "x$ac_cv_archive_acl_freebsd" = "xyes"]) - -# Additional requirements -AC_SYS_LARGEFILE - -dnl NOTE: Crypto checks must run last. -AC_DEFUN([CRYPTO_CHECK], [ - if test "$found_$1" != yes; then - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I. -I$srcdir -I$srcdir/libarchive" - touch "check_crypto_md.h" - AC_MSG_CHECKING([support for ARCHIVE_CRYPTO_$1_$2]) - AC_LINK_IFELSE([AC_LANG_SOURCE([ -#define ARCHIVE_$1_COMPILE_TEST -#define ARCHIVE_CRYPTO_$1_$2 -#define PLATFORM_CONFIG_H "check_crypto_md.h" - -$(cat "$srcdir/libarchive/archive_digest.c") - -int -main(int argc, char **argv) -{ - archive_$3_ctx ctx; - archive_$3_init(&ctx); - archive_$3_update(&ctx, *argv, argc); - archive_$3_final(&ctx, NULL); - return 0; -} -])], - [ AC_MSG_RESULT([yes]) - found_$1=yes - found_$2=yes - AC_DEFINE(ARCHIVE_CRYPTO_$1_$2, 1, [ $1 via ARCHIVE_CRYPTO_$1_$2 supported.]) - ], - [ AC_MSG_RESULT([no])]) - CPPFLAGS="$saved_CPPFLAGS" - rm "check_crypto_md.h" - fi -]) - -AC_DEFUN([CRYPTO_CHECK_WIN], [ - if test "$found_$1" != yes; then - AC_MSG_CHECKING([support for ARCHIVE_CRYPTO_$1_WIN]) - AC_LINK_IFELSE([AC_LANG_SOURCE([ -#define ARCHIVE_$1_COMPILE_TEST -#include -#include - -int -main(int argc, char **argv) -{ - (void)argc; - (void)argv; - - return ($2); -} -])], - [ AC_MSG_RESULT([yes]) - found_$1=yes - found_WIN=yes - AC_DEFINE(ARCHIVE_CRYPTO_$1_WIN, 1, [ $1 via ARCHIVE_CRYPTO_$1_WIN supported.]) - ], - [ AC_MSG_RESULT([no])]) - fi -]) - -case "$host_os" in - *mingw* | *cygwin* | *msys*) - ;; - *) - CRYPTO_CHECK(MD5, LIBC, md5) - CRYPTO_CHECK(MD5, LIBSYSTEM, md5) - CRYPTO_CHECK(RMD160, LIBC, rmd160) - CRYPTO_CHECK(SHA1, LIBC, sha1) - CRYPTO_CHECK(SHA1, LIBSYSTEM, sha1) - CRYPTO_CHECK(SHA256, LIBC, sha256) - CRYPTO_CHECK(SHA256, LIBC2, sha256) - CRYPTO_CHECK(SHA256, LIBC3, sha256) - CRYPTO_CHECK(SHA256, LIBSYSTEM, sha256) - CRYPTO_CHECK(SHA384, LIBC, sha384) - CRYPTO_CHECK(SHA384, LIBC2, sha384) - CRYPTO_CHECK(SHA384, LIBC3, sha384) - CRYPTO_CHECK(SHA384, LIBSYSTEM, sha384) - CRYPTO_CHECK(SHA512, LIBC, sha512) - CRYPTO_CHECK(SHA512, LIBC2, sha512) - CRYPTO_CHECK(SHA512, LIBC3, sha512) - CRYPTO_CHECK(SHA512, LIBSYSTEM, sha512) - ;; -esac - -if test "x$with_cng" != "xno"; then - AC_CHECK_HEADERS([bcrypt.h],[ - LIBS="$LIBS -lbcrypt" - ],[], - [[#ifdef HAVE_WINDOWS_H - # include - #endif - ]]) -fi - -if test "x$with_mbedtls" = "xyes"; then - AC_CHECK_HEADERS([mbedtls/aes.h mbedtls/md.h mbedtls/pkcs5.h]) - saved_LIBS=$LIBS - AC_CHECK_LIB(mbedcrypto,mbedtls_sha1_init) - CRYPTO_CHECK(MD5, MBEDTLS, md5) - CRYPTO_CHECK(RMD160, MBEDTLS, rmd160) - CRYPTO_CHECK(SHA1, MBEDTLS, sha1) - CRYPTO_CHECK(SHA256, MBEDTLS, sha256) - CRYPTO_CHECK(SHA384, MBEDTLS, sha384) - CRYPTO_CHECK(SHA512, MBEDTLS, sha512) - if test "x$found_MBEDTLS" != "xyes"; then - LIBS=$saved_LIBS - fi -fi - -if test "x$with_nettle" = "xyes"; then - AC_CHECK_HEADERS([nettle/md5.h nettle/ripemd160.h nettle/sha.h]) - AC_CHECK_HEADERS([nettle/pbkdf2.h nettle/aes.h nettle/hmac.h]) - saved_LIBS=$LIBS - AC_CHECK_LIB(nettle,nettle_sha1_init) - CRYPTO_CHECK(MD5, NETTLE, md5) - CRYPTO_CHECK(RMD160, NETTLE, rmd160) - CRYPTO_CHECK(SHA1, NETTLE, sha1) - CRYPTO_CHECK(SHA256, NETTLE, sha256) - CRYPTO_CHECK(SHA384, NETTLE, sha384) - CRYPTO_CHECK(SHA512, NETTLE, sha512) - if test "x$found_NETTLE" != "xyes"; then - LIBS=$saved_LIBS - fi -fi - -if test "x$with_openssl" != "xno"; then - AC_CHECK_HEADERS([openssl/evp.h]) - saved_LIBS=$LIBS - LIBSREQUIRED="$LIBSREQUIRED${LIBSREQUIRED:+ }libcrypto" - AC_CHECK_LIB(crypto,OPENSSL_config) - CRYPTO_CHECK(MD5, OPENSSL, md5) - CRYPTO_CHECK(RMD160, OPENSSL, rmd160) - CRYPTO_CHECK(SHA1, OPENSSL, sha1) - CRYPTO_CHECK(SHA256, OPENSSL, sha256) - CRYPTO_CHECK(SHA384, OPENSSL, sha384) - CRYPTO_CHECK(SHA512, OPENSSL, sha512) - AC_CHECK_FUNCS([PKCS5_PBKDF2_HMAC_SHA1]) -fi - -AC_SUBST(LIBSREQUIRED) - -# Probe libmd AFTER OpenSSL/libcrypto. -# The two are incompatible and OpenSSL is more complete. -AC_CHECK_HEADERS([md5.h ripemd.h sha.h sha256.h sha512.h]) -saved_LIBS=$LIBS -AC_CHECK_LIB(md,MD5Init) -CRYPTO_CHECK(MD5, LIBMD, md5) -CRYPTO_CHECK(RMD160, LIBMD, rmd160) -CRYPTO_CHECK(SHA1, LIBMD, sha1) -CRYPTO_CHECK(SHA256, LIBMD, sha256) -CRYPTO_CHECK(SHA512, LIBMD, sha512) -if test "x$found_LIBMD" != "xyes"; then - LIBS=$saved_LIBS -fi - -case "$host_os" in - *mingw* | *cygwin* | *msys*) - CRYPTO_CHECK_WIN(MD5, CALG_MD5) - CRYPTO_CHECK_WIN(SHA1, CALG_SHA1) - CRYPTO_CHECK_WIN(SHA256, CALG_SHA_256) - CRYPTO_CHECK_WIN(SHA384, CALG_SHA_384) - CRYPTO_CHECK_WIN(SHA512, CALG_SHA_512) - ;; -esac - -dnl Visibility annotations... -saved_CFLAGS="$CFLAGS" -CFLAGS="$CFLAGS -fvisibility=hidden -Werror" -AC_MSG_CHECKING(whether compiler supports visibility annotations) -AC_LINK_IFELSE([AC_LANG_PROGRAM([ - int foo( void ) __attribute__((visibility("default"))); - ])], - [CFLAGS="$saved_CFLAGS -fvisibility=hidden -D__LIBARCHIVE_ENABLE_VISIBILITY"; - AC_MSG_RESULT(yes)], - [CFLAGS="$saved_CFLAGS" - AC_MSG_RESULT(no)]) - -# Ensure test directories are present if building out-of-tree -AC_CONFIG_COMMANDS([mkdirs], - [mkdir -p libarchive/test tar/test cat/test cpio/test]) - -AC_OUTPUT diff --git a/thirdparty/libarchive/contrib/README b/thirdparty/libarchive/contrib/README deleted file mode 100644 index 8ad352a30..000000000 --- a/thirdparty/libarchive/contrib/README +++ /dev/null @@ -1,59 +0,0 @@ -Many people have graciously sent me configuration -files, small programs that use libarchive, and other -useful and interesting tidbits. - -I do not support or use any of these; but if you can use them, enjoy! - -====================================================================== - -From: Andre Stechert - -libarchive_autodetect-st_lib_archive.m4 - -M4 macros for use with autoconf to detect whether a suitable -version of libarchive is installed on this system. - - -====================================================================== - -libarchive.spec - -An RPM ".spec" file for building libarchive on most systems. -This apparently was originally developed by a group at pld-linux.org. -Several people have sent me different versions of this file. - -====================================================================== - -From: Robert Meier - -libarchive.1aix53.spec - -As above, for use on AIX5.3. - -====================================================================== - -psota-benchmark - -Some scripts used by Jan Psota in benchmarking -various tar implementations. - -I've edited his results slightly to correctly reflect that -bsdtar does not support a "compare" operation. - -====================================================================== - -shar - -A simple shar program written on top of libarchive. - -====================================================================== - -untar.c - -A very simple and very portable standalone program that can -extract basic ustar archives. -This does not use libarchive and so can be used to extract -the libarchive distribution on any system that has a C compiler -but does not have a tar program. - -====================================================================== diff --git a/thirdparty/libarchive/contrib/android/Android.mk b/thirdparty/libarchive/contrib/android/Android.mk deleted file mode 100644 index 3f7619d66..000000000 --- a/thirdparty/libarchive/contrib/android/Android.mk +++ /dev/null @@ -1,308 +0,0 @@ -# -# Copyright (C) 2014 Trevor Drake -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# - - -# A bit of a non-standard LOCAL_PATH declaration here -# The Android.mk lives below the top source directory -# but LOCAL_PATH needs to point to the top of the module -# source tree to maintain the integrity of the intermediates -# directories -LOCAL_PATH := $(subst /contrib/android,,$(call my-dir)) - -libarchive_target_config := contrib/android/config/android.h - -libarchive_src_files := libarchive/archive_acl.c \ - libarchive/archive_check_magic.c \ - libarchive/archive_cmdline.c \ - libarchive/archive_cryptor.c \ - libarchive/archive_digest.c \ - libarchive/archive_entry.c \ - libarchive/archive_entry_copy_stat.c \ - libarchive/archive_entry_link_resolver.c \ - libarchive/archive_entry_sparse.c \ - libarchive/archive_entry_stat.c \ - libarchive/archive_entry_strmode.c \ - libarchive/archive_entry_xattr.c \ - libarchive/archive_getdate.c \ - libarchive/archive_hmac.c \ - libarchive/archive_match.c \ - libarchive/archive_options.c \ - libarchive/archive_pack_dev.c \ - libarchive/archive_pathmatch.c \ - libarchive/archive_ppmd7.c \ - libarchive/archive_random.c \ - libarchive/archive_rb.c \ - libarchive/archive_read.c \ - libarchive/archive_read_add_passphrase.c \ - libarchive/archive_read_append_filter.c \ - libarchive/archive_read_data_into_fd.c \ - libarchive/archive_read_disk_entry_from_file.c \ - libarchive/archive_read_disk_posix.c \ - libarchive/archive_read_disk_set_standard_lookup.c \ - libarchive/archive_read_extract.c \ - libarchive/archive_read_extract2.c \ - libarchive/archive_read_open_fd.c \ - libarchive/archive_read_open_file.c \ - libarchive/archive_read_open_filename.c \ - libarchive/archive_read_open_memory.c \ - libarchive/archive_read_set_format.c \ - libarchive/archive_read_set_options.c \ - libarchive/archive_read_support_filter_all.c \ - libarchive/archive_read_support_filter_bzip2.c \ - libarchive/archive_read_support_filter_compress.c \ - libarchive/archive_read_support_filter_grzip.c \ - libarchive/archive_read_support_filter_gzip.c \ - libarchive/archive_read_support_filter_lrzip.c \ - libarchive/archive_read_support_filter_lz4.c \ - libarchive/archive_read_support_filter_lzop.c \ - libarchive/archive_read_support_filter_none.c \ - libarchive/archive_read_support_filter_program.c \ - libarchive/archive_read_support_filter_rpm.c \ - libarchive/archive_read_support_filter_uu.c \ - libarchive/archive_read_support_filter_xz.c \ - libarchive/archive_read_support_filter_zstd.c \ - libarchive/archive_read_support_format_7zip.c \ - libarchive/archive_read_support_format_all.c \ - libarchive/archive_read_support_format_ar.c \ - libarchive/archive_read_support_format_by_code.c \ - libarchive/archive_read_support_format_cab.c \ - libarchive/archive_read_support_format_cpio.c \ - libarchive/archive_read_support_format_empty.c \ - libarchive/archive_read_support_format_iso9660.c \ - libarchive/archive_read_support_format_lha.c \ - libarchive/archive_read_support_format_mtree.c \ - libarchive/archive_read_support_format_rar.c \ - libarchive/archive_read_support_format_raw.c \ - libarchive/archive_read_support_format_tar.c \ - libarchive/archive_read_support_format_warc.c \ - libarchive/archive_read_support_format_xar.c \ - libarchive/archive_read_support_format_zip.c \ - libarchive/archive_string.c \ - libarchive/archive_string_sprintf.c \ - libarchive/archive_util.c \ - libarchive/archive_version_details.c \ - libarchive/archive_virtual.c \ - libarchive/archive_write.c \ - libarchive/archive_write_disk_posix.c \ - libarchive/archive_write_disk_set_standard_lookup.c \ - libarchive/archive_write_open_fd.c \ - libarchive/archive_write_open_file.c \ - libarchive/archive_write_open_filename.c \ - libarchive/archive_write_open_memory.c \ - libarchive/archive_write_add_filter.c \ - libarchive/archive_write_add_filter_b64encode.c \ - libarchive/archive_write_add_filter_by_name.c \ - libarchive/archive_write_add_filter_bzip2.c \ - libarchive/archive_write_add_filter_compress.c \ - libarchive/archive_write_add_filter_grzip.c \ - libarchive/archive_write_add_filter_gzip.c \ - libarchive/archive_write_add_filter_lrzip.c \ - libarchive/archive_write_add_filter_lz4.c \ - libarchive/archive_write_add_filter_lzop.c \ - libarchive/archive_write_add_filter_none.c \ - libarchive/archive_write_add_filter_program.c \ - libarchive/archive_write_add_filter_uuencode.c \ - libarchive/archive_write_add_filter_xz.c \ - libarchive/archive_write_add_filter_zstd.c \ - libarchive/archive_write_set_format.c \ - libarchive/archive_write_set_format_7zip.c \ - libarchive/archive_write_set_format_ar.c \ - libarchive/archive_write_set_format_by_name.c \ - libarchive/archive_write_set_format_cpio.c \ - libarchive/archive_write_set_format_cpio_newc.c \ - libarchive/archive_write_set_format_iso9660.c \ - libarchive/archive_write_set_format_mtree.c \ - libarchive/archive_write_set_format_pax.c \ - libarchive/archive_write_set_format_raw.c \ - libarchive/archive_write_set_format_shar.c \ - libarchive/archive_write_set_format_ustar.c \ - libarchive/archive_write_set_format_v7tar.c \ - libarchive/archive_write_set_format_gnutar.c \ - libarchive/archive_write_set_format_warc.c \ - libarchive/archive_write_set_format_xar.c \ - libarchive/archive_write_set_format_zip.c \ - libarchive/archive_write_set_options.c \ - libarchive/archive_write_set_passphrase.c \ - libarchive/filter_fork_posix.c \ - libarchive/xxhash.c - -ifeq ($(HOST_OS),windows) -libarchive_host_src_files := \ - libarchive/archive_entry_copy_bhfi.c \ - libarchive/archive_read_disk_windows.c \ - libarchive/archive_write_disk_windows.c \ - libarchive/filter_fork_windows.c \ - libarchive/archive_windows.c -else -libarchive_host_src_files := -endif - -libarchive_fe_src_files := libarchive_fe/err.c \ - libarchive_fe/line_reader.c \ - libarchive_fe/passphrase.c - -bsdtar_src_files := tar/bsdtar.c \ - tar/bsdtar_windows.c \ - tar/cmdline.c \ - tar/creation_set.c \ - tar/read.c \ - tar/subst.c \ - tar/util.c \ - tar/write.c - -bsdcpio_src_files := cpio/cmdline.c \ - cpio/cpio.c - -bsdcat_src_files := cat/cmdline.c \ - cat/bsdcat.c - - -ifeq ($(HOST_OS),darwin) -$(warning Host : $(HOST_OS) Not Supported. Host Build Will Be Skipped ) -else -libarchive_host_config := contrib/android/config/$(HOST_OS)_host.h - -include $(CLEAR_VARS) -LOCAL_MODULE := libarchive -LOCAL_MODULE_TAGS := optional -LOCAL_SRC_FILES := $(libarchive_src_files) $(libarchive_host_src_files) -LOCAL_CFLAGS := -DPLATFORM_CONFIG_H=\"$(libarchive_host_config)\" -LOCAL_C_INCLUDES := $(LOCAL_PATH)/contrib/android/include -LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/libarchive -include $(BUILD_HOST_STATIC_LIBRARY) - -include $(CLEAR_VARS) -LOCAL_MODULE := libarchive -LOCAL_MODULE_TAGS := optional -LOCAL_CFLAGS := -DPLATFORM_CONFIG_H=\"$(libarchive_host_config)\" -LOCAL_SHARED_LIBRARIES := libz-host -LOCAL_WHOLE_STATIC_LIBRARIES := libarchive -LOCAL_C_INCLUDES := $(LOCAL_PATH)/contrib/android/include -LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/libarchive -include $(BUILD_HOST_SHARED_LIBRARY) - -include $(CLEAR_VARS) -LOCAL_MODULE := libarchive_fe -LOCAL_MODULE_TAGS := optional -LOCAL_CFLAGS := -DPLATFORM_CONFIG_H=\"$(libarchive_host_config)\" -LOCAL_SRC_FILES := $(libarchive_fe_src_files) -LOCAL_C_INCLUDES := $(LOCAL_PATH)/contrib/android/include -LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/libarchive_fe -include $(BUILD_HOST_STATIC_LIBRARY) - -endif - - -# Do not build target binaries if we are not targeting linux -# on the host -ifeq ($(HOST_OS),linux) - -include $(CLEAR_VARS) -LOCAL_MODULE := bsdtar -LOCAL_MODULE_TAGS := optional -LOCAL_CFLAGS := -DBSDTAR_VERSION_STRING=ARCHIVE_VERSION_ONLY_STRING -DPLATFORM_CONFIG_H=\"$(libarchive_host_config)\" -LOCAL_SHARED_LIBRARIES := libz-host -LOCAL_STATIC_LIBRARIES := libarchive libarchive_fe -LOCAL_SRC_FILES := $(bsdtar_src_files) -LOCAL_C_INCLUDES := $(LOCAL_PATH)/contrib/android/include -include $(BUILD_HOST_EXECUTABLE) - -include $(CLEAR_VARS) -LOCAL_MODULE := bsdcpio -LOCAL_MODULE_TAGS := optional -LOCAL_CFLAGS := -DBSDCPIO_VERSION_STRING=ARCHIVE_VERSION_ONLY_STRING -DPLATFORM_CONFIG_H=\"$(libarchive_host_config)\" -LOCAL_SHARED_LIBRARIES := libz-host -LOCAL_STATIC_LIBRARIES := libarchive libarchive_fe -LOCAL_SRC_FILES := $(bsdcpio_src_files) -LOCAL_C_INCLUDES := $(LOCAL_PATH)/contrib/android/include -include $(BUILD_HOST_EXECUTABLE) - -include $(CLEAR_VARS) -LOCAL_MODULE := bsdcat -LOCAL_MODULE_TAGS := optional -LOCAL_CFLAGS := -DBSDCAT_VERSION_STRING=ARCHIVE_VERSION_ONLY_STRING -DPLATFORM_CONFIG_H=\"$(libarchive_host_config)\" -LOCAL_SHARED_LIBRARIES := libz-host -LOCAL_STATIC_LIBRARIES := libarchive libarchive_fe -LOCAL_SRC_FILES := $(bsdcat_src_files) -LOCAL_C_INCLUDES := $(LOCAL_PATH)/contrib/android/include -include $(BUILD_HOST_EXECUTABLE) - - - -include $(CLEAR_VARS) -LOCAL_MODULE := libarchive -LOCAL_MODULE_TAGS := optional -LOCAL_SRC_FILES := $(libarchive_src_files) -LOCAL_STATIC_LIBRARIES := libz liblz4 -LOCAL_CFLAGS := -DPLATFORM_CONFIG_H=\"$(libarchive_target_config)\" -LOCAL_C_INCLUDES := $(LOCAL_PATH)/contrib/android/include -LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/libarchive -include $(BUILD_STATIC_LIBRARY) - - -include $(CLEAR_VARS) -LOCAL_MODULE := libarchive -LOCAL_MODULE_TAGS := optional -LOCAL_C_INCLUDES := -LOCAL_CFLAGS := -DPLATFORM_CONFIG_H=\"$(libarchive_target_config)\" -LOCAL_SHARED_LIBRARIES := libz -LOCAL_WHOLE_STATIC_LIBRARIES := libarchive -LOCAL_C_INCLUDES := $(LOCAL_PATH)/contrib/android/include -LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/libarchive -include $(BUILD_SHARED_LIBRARY) - -include $(CLEAR_VARS) -LOCAL_MODULE := libarchive_fe -LOCAL_MODULE_TAGS := optional -LOCAL_CFLAGS := -DPLATFORM_CONFIG_H=\"$(libarchive_target_config)\" -LOCAL_SRC_FILES := $(libarchive_fe_src_files) -LOCAL_C_INCLUDES := $(LOCAL_PATH)/contrib/android/include -LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/libarchive_fe -include $(BUILD_STATIC_LIBRARY) - - -include $(CLEAR_VARS) -LOCAL_MODULE := bsdtar -LOCAL_MODULE_TAGS := optional -LOCAL_CFLAGS := -DBSDTAR_VERSION_STRING=ARCHIVE_VERSION_ONLY_STRING -DPLATFORM_CONFIG_H=\"$(libarchive_target_config)\" -LOCAL_SHARED_LIBRARIES := libz -LOCAL_STATIC_LIBRARIES := libarchive libarchive_fe -LOCAL_SRC_FILES := $(bsdtar_src_files) -LOCAL_C_INCLUDES := $(LOCAL_PATH)/libarchive $(LOCAL_PATH)/libarchive_fe $(LOCAL_PATH)/contrib/android/include -include $(BUILD_EXECUTABLE) - -include $(CLEAR_VARS) -LOCAL_MODULE := bsdcpio -LOCAL_MODULE_TAGS := optional -LOCAL_CFLAGS := -DBSDCPIO_VERSION_STRING=ARCHIVE_VERSION_ONLY_STRING -DPLATFORM_CONFIG_H=\"$(libarchive_target_config)\" -LOCAL_SHARED_LIBRARIES := libz -LOCAL_STATIC_LIBRARIES := libarchive libarchive_fe -LOCAL_SRC_FILES := $(bsdcpio_src_files) -LOCAL_C_INCLUDES := $(LOCAL_PATH)/libarchive $(LOCAL_PATH)/libarchive_fe $(LOCAL_PATH)/contrib/android/include -include $(BUILD_EXECUTABLE) - -include $(CLEAR_VARS) -LOCAL_MODULE := bsdcat -LOCAL_MODULE_TAGS := optional -LOCAL_CFLAGS := -DBSDCAT_VERSION_STRING=ARCHIVE_VERSION_ONLY_STRING -DPLATFORM_CONFIG_H=\"$(libarchive_target_config)\" -LOCAL_SHARED_LIBRARIES := libz -LOCAL_STATIC_LIBRARIES := libarchive libarchive_fe -LOCAL_SRC_FILES := $(bsdcat_src_files) -LOCAL_C_INCLUDES := $(LOCAL_PATH)/libarchive $(LOCAL_PATH)/libarchive_fe $(LOCAL_PATH)/contrib/android/include -include $(BUILD_EXECUTABLE) - -endif diff --git a/thirdparty/libarchive/contrib/android/config/android.h b/thirdparty/libarchive/contrib/android/config/android.h deleted file mode 100644 index 0ccb20c4e..000000000 --- a/thirdparty/libarchive/contrib/android/config/android.h +++ /dev/null @@ -1,184 +0,0 @@ -/*- - * Copyright (c) 2014 Trevor Drake - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - * - */ -#ifndef ARCHIVE_PLATFORM_H_ANDROID_INCLUDED -#define ARCHIVE_PLATFORM_H_ANDROID_INCLUDED - -#include -#ifdef __ANDROID_API__ -#if __ANDROID_API__ > 20 -#define HAVE_FSTATVFS 1 -#define HAVE_STATVFS 1 -#define HAVE_TIMEGM 1 -#define HAVE_SYS_XATTR_H 1 -#define HAVE_LINUX_FIEMAP_H 1 -#define HAVE_SYS_STATVFS_H 1 -#endif -#endif - -#define HAVE_CHOWN 1 -#define HAVE_CHROOT 1 -#define HAVE_CTIME_R 1 -#define HAVE_CTYPE_H 1 -#define HAVE_DECL_EXTATTR_NAMESPACE_USER 0 -#define HAVE_DECL_INTMAX_MIN 1 -#define HAVE_DECL_INTMAX_MAX 1 -#define HAVE_DECL_INT64_MAX 1 -#define HAVE_DECL_INT64_MIN 1 -#define HAVE_DECL_SIZE_MAX 1 -#define HAVE_DECL_SSIZE_MAX 1 -#define HAVE_DECL_STRERROR_R 1 -#define HAVE_DECL_UINTMAX_MAX 1 -#define HAVE_DECL_UINT32_MAX 1 -#define HAVE_DECL_UINT64_MAX 1 -#define HAVE_DIRENT_H 1 -#define HAVE_DIRFD 1 -#define HAVE_DLFCN_H 1 -#define HAVE_EILSEQ 1 -#define HAVE_ERRNO_H 1 -#define HAVE_FCHDIR 1 -#define HAVE_FCHMOD 1 -#define HAVE_FCHOWN 1 -#define HAVE_FCNTL 1 -#define HAVE_FCNTL_H 1 -#define HAVE_FDOPENDIR 1 -#define HAVE_FGETXATTR 1 -#define HAVE_FLISTXATTR 1 -#define HAVE_FORK 1 -#define HAVE_FSEEKO 1 -#define HAVE_FSETXATTR 1 -#define HAVE_FSTAT 1 -#define HAVE_FSTATAT 1 -#define HAVE_FSTATFS 1 -#define HAVE_FTRUNCATE 1 -#define HAVE_GETEUID 1 -#define HAVE_GETPID 1 -#define HAVE_GETPWNAM_R 1 -#define HAVE_GETPWUID_R 1 -#define HAVE_GETXATTR 1 -#define HAVE_GMTIME_R 1 -#define HAVE_GRP_H 1 -#define HAVE_INTMAX_T 1 -#define HAVE_INTTYPES_H 1 -#define HAVE_LCHOWN 1 -#define HAVE_LGETXATTR 1 -#define HAVE_LIBLZMA 1 -#define HAVE_LIBZ 1 -#define HAVE_LIMITS_H 1 -#define HAVE_LINK 1 -#define HAVE_LINUX_FS_H 1 -#define HAVE_LINUX_MAGIC_H 1 -#define HAVE_LINUX_TYPES_H 1 -#define HAVE_LISTXATTR 1 -#define HAVE_LLISTXATTR 1 -#define HAVE_LOCALE_H 1 -#define HAVE_LOCALTIME_R 1 -#define HAVE_LONG_LONG_INT 1 -#define HAVE_LSETXATTR 1 -#define HAVE_LSTAT 1 -#define HAVE_MBRTOWC 1 -#define HAVE_MEMMOVE 1 -#define HAVE_MEMORY_H 1 -#define HAVE_MEMSET 1 -#define HAVE_MKDIR 1 -#define HAVE_MKFIFO 1 -#define HAVE_MKNOD 1 -#define HAVE_MKSTEMP 1 -#define HAVE_OPENAT 1 -#define HAVE_PATHS_H 1 -#define HAVE_PIPE 1 -#define HAVE_POLL 1 -#define HAVE_POLL_H 1 -#define HAVE_PTHREAD_H 1 -#define HAVE_PWD_H 1 -#define HAVE_READDIR_R 1 -#define HAVE_READLINK 1 -#define HAVE_READLINKAT 1 -#define HAVE_REGEX_H 1 -#define HAVE_SELECT 1 -#define HAVE_SETENV 1 -#define HAVE_SETLOCALE 1 -#define HAVE_SIGACTION 1 -#define HAVE_SIGNAL_H 1 -#define HAVE_STATFS 1 -#define HAVE_STDARG_H 1 -#define HAVE_STDINT_H 1 -#define HAVE_STDLIB_H 1 -#define HAVE_STRCHR 1 -#define HAVE_STRDUP 1 -#define HAVE_STRERROR 1 -#define HAVE_STRERROR_R 1 -#define HAVE_STRFTIME 1 -#define HAVE_STRINGS_H 1 -#define HAVE_STRING_H 1 -#define HAVE_STRRCHR 1 -#define HAVE_STRUCT_STAT_ST_BLKSIZE 1 -#define HAVE_STRUCT_STAT_ST_MTIME_NSEC 1 -#define HAVE_STRUCT_TM_TM_GMTOFF 1 -#define HAVE_SYMLINK 1 -#define HAVE_SYS_CDEFS_H 1 -#define HAVE_SYS_IOCTL_H 1 -#define HAVE_SYS_MOUNT_H 1 -#define HAVE_SYS_PARAM_H 1 -#define HAVE_SYS_POLL_H 1 -#define HAVE_SYS_SELECT_H 1 -#define HAVE_SYS_STATFS_H 1 -#define HAVE_SYS_STAT_H 1 -#define HAVE_SYS_TIME_H 1 -#define HAVE_SYS_TYPES_H 1 -#define HAVE_SYS_UTSNAME_H 1 -#define HAVE_SYS_VFS_H 1 -#define HAVE_SYS_WAIT_H 1 -#define HAVE_TIME_H 1 -#define HAVE_TZSET 1 -#define HAVE_UINTMAX_T 1 -#define HAVE_UNISTD_H 1 -#define HAVE_UNSETENV 1 -#define HAVE_UNSIGNED_LONG_LONG 1 -#define HAVE_UNSIGNED_LONG_LONG_INT 1 -#define HAVE_UTIME 1 -#define HAVE_UTIMENSAT 1 -#define HAVE_UTIMES 1 -#define HAVE_UTIME_H 1 -#define HAVE_VFORK 1 -#define HAVE_VPRINTF 1 -#define HAVE_WCHAR_H 1 -#define HAVE_WCHAR_T 1 -#define HAVE_WCRTOMB 1 -#define HAVE_WCSCMP 1 -#define HAVE_WCSCPY 1 -#define HAVE_WCSLEN 1 -#define HAVE_WCTOMB 1 -#define HAVE_WCTYPE_H 1 -#define HAVE_WMEMCMP 1 -#define HAVE_WMEMCPY 1 -#define HAVE_ARC4RANDOM_BUF 1 -#define HAVE_ZLIB_H 1 -#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1 -#define SIZEOF_WCHAR_T 4 -#define STDC_HEADERS 1 -#define STRERROR_R_CHAR_P 1 -#define HAVE_SYS_TIME_H 1 -#endif diff --git a/thirdparty/libarchive/contrib/android/config/linux_host.h b/thirdparty/libarchive/contrib/android/config/linux_host.h deleted file mode 100644 index 371c6cc48..000000000 --- a/thirdparty/libarchive/contrib/android/config/linux_host.h +++ /dev/null @@ -1,189 +0,0 @@ -/*- - * Copyright (c) 2014 Trevor Drake - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - * - */ -#ifndef ARCHIVE_PLATFORM_H_ANDROID_LINUX_HOST_INCLUDED -#define ARCHIVE_PLATFORM_H_ANDROID_LINUX_HOST_INCLUDED - -#define HAVE_CHOWN 1 -#define HAVE_CHROOT 1 -#define HAVE_CTIME_R 1 -#define HAVE_CTYPE_H 1 -#define HAVE_DECL_EXTATTR_NAMESPACE_USER 0 -#define HAVE_DECL_INT64_MAX 1 -#define HAVE_DECL_INT64_MIN 1 -#define HAVE_DECL_SIZE_MAX 1 -#define HAVE_DECL_SSIZE_MAX 1 -#define HAVE_DECL_STRERROR_R 1 -#define HAVE_DECL_UINT32_MAX 1 -#define HAVE_DECL_UINT64_MAX 1 -#define HAVE_DIRENT_H 1 -#define HAVE_DIRFD 1 -#define HAVE_DLFCN_H 1 -#define HAVE_EILSEQ 1 -#define HAVE_ERRNO_H 1 -#define HAVE_FCHDIR 1 -#define HAVE_FCHMOD 1 -#define HAVE_FCHOWN 1 -#define HAVE_FCNTL 1 -#define HAVE_FCNTL_H 1 -#define HAVE_FDOPENDIR 1 -#define HAVE_FGETXATTR 1 -#define HAVE_FLISTXATTR 1 -#define HAVE_FORK 1 -#define HAVE_FSEEKO 1 -#define HAVE_FSETXATTR 1 -#define HAVE_FSTAT 1 -#define HAVE_FSTATAT 1 -#define HAVE_FSTATFS 1 -#define HAVE_FSTATVFS 1 -#define HAVE_FTRUNCATE 1 -#define HAVE_FUTIMENS 1 -#define HAVE_FUTIMES 1 -#define HAVE_FUTIMESAT 1 -#define HAVE_GETEUID 1 -#define HAVE_GETGRGID_R 1 -#define HAVE_GETGRNAM_R 1 -#define HAVE_GETPID 1 -#define HAVE_GETPWNAM_R 1 -#define HAVE_GETPWUID_R 1 -#define HAVE_GETXATTR 1 -#define HAVE_GMTIME_R 1 -#define HAVE_GRP_H 1 -#define HAVE_ICONV 1 -#define HAVE_ICONV_H 1 -#define HAVE_INTMAX_T 1 -#define HAVE_INTTYPES_H 1 -#define HAVE_LANGINFO_H 1 -#define HAVE_LCHOWN 1 -#define HAVE_LGETXATTR 1 -#define HAVE_LIBLZMA 1 -#define HAVE_LIBZ 1 -#define HAVE_LIMITS_H 1 -#define HAVE_LINK 1 -#define HAVE_LINUX_FIEMAP_H 1 -#define HAVE_LINUX_FS_H 1 -#define HAVE_LINUX_MAGIC_H 1 -#define HAVE_LINUX_TYPES_H 1 -#define HAVE_LISTXATTR 1 -#define HAVE_LLISTXATTR 1 -#define HAVE_LOCALE_H 1 -#define HAVE_LOCALTIME_R 1 -#define HAVE_LONG_LONG_INT 1 -#define HAVE_LSETXATTR 1 -#define HAVE_LSTAT 1 -#define HAVE_LUTIMES 1 -#define HAVE_MBRTOWC 1 -#define HAVE_MEMMOVE 1 -#define HAVE_MEMORY_H 1 -#define HAVE_MEMSET 1 -#define HAVE_MKDIR 1 -#define HAVE_MKFIFO 1 -#define HAVE_MKNOD 1 -#define HAVE_MKSTEMP 1 -#define HAVE_NL_LANGINFO 1 -#define HAVE_OPENAT 1 -#define HAVE_PATHS_H 1 -#define HAVE_PIPE 1 -#define HAVE_POLL 1 -#define HAVE_POLL_H 1 -#define HAVE_POSIX_SPAWNP 1 -#define HAVE_PTHREAD_H 1 -#define HAVE_PWD_H 1 -#define HAVE_READDIR_R 1 -#define HAVE_READLINK 1 -#define HAVE_READLINKAT 1 -#define HAVE_REGEX_H 1 -#define HAVE_SELECT 1 -#define HAVE_SETENV 1 -#define HAVE_SETLOCALE 1 -#define HAVE_SIGACTION 1 -#define HAVE_SIGNAL_H 1 -#define HAVE_SPAWN_H 1 -#define HAVE_STATFS 1 -#define HAVE_STATVFS 1 -#define HAVE_STDARG_H 1 -#define HAVE_STDINT_H 1 -#define HAVE_STDLIB_H 1 -#define HAVE_STRCHR 1 -#define HAVE_STRDUP 1 -#define HAVE_STRERROR 1 -#define HAVE_STRERROR_R 1 -#define HAVE_STRFTIME 1 -#define HAVE_STRINGS_H 1 -#define HAVE_STRING_H 1 -#define HAVE_STRRCHR 1 -#define HAVE_STRUCT_STAT_ST_BLKSIZE 1 -#define HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 1 -#define HAVE_STRUCT_TM_TM_GMTOFF 1 -#define HAVE_SYMLINK 1 -#define HAVE_SYS_CDEFS_H 1 -#define HAVE_SYS_IOCTL_H 1 -#define HAVE_SYS_MOUNT_H 1 -#define HAVE_SYS_PARAM_H 1 -#define HAVE_SYS_POLL_H 1 -#define HAVE_SYS_SELECT_H 1 -#define HAVE_SYS_STATFS_H 1 -#define HAVE_SYS_STATVFS_H 1 -#define HAVE_SYS_STAT_H 1 -#define HAVE_SYS_TIME_H 1 -#define HAVE_SYS_TYPES_H 1 -#define HAVE_SYS_UTSNAME_H 1 -#define HAVE_SYS_VFS_H 1 -#define HAVE_SYS_WAIT_H 1 -#define HAVE_SYS_XATTR_H 1 -#define HAVE_TIMEGM 1 -#define HAVE_TIME_H 1 -#define HAVE_TZSET 1 -#define HAVE_UINTMAX_T 1 -#define HAVE_UNISTD_H 1 -#define HAVE_UNSETENV 1 -#define HAVE_UNSIGNED_LONG_LONG 1 -#define HAVE_UNSIGNED_LONG_LONG_INT 1 -#define HAVE_UTIME 1 -#define HAVE_UTIMENSAT 1 -#define HAVE_UTIMES 1 -#define HAVE_UTIME_H 1 -#define HAVE_VFORK 1 -#define HAVE_VPRINTF 1 -#define HAVE_WCHAR_H 1 -#define HAVE_WCHAR_T 1 -#define HAVE_WCRTOMB 1 -#define HAVE_WCSCMP 1 -#define HAVE_WCSCPY 1 -#define HAVE_WCSLEN 1 -#define HAVE_WCTOMB 1 -#define HAVE_WCTYPE_H 1 -#define HAVE_WMEMCMP 1 -#define HAVE_WMEMCPY 1 -#define HAVE_ZLIB_H 1 -#define ICONV_CONST -#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1 -#define SIZEOF_WCHAR_T 4 -#define STDC_HEADERS 1 -#define STRERROR_R_CHAR_P 1 -#define HAVE_SYS_TIME_H 1 -#define _GNU_SOURCE 1 - -#endif diff --git a/thirdparty/libarchive/contrib/android/config/windows_host.h b/thirdparty/libarchive/contrib/android/config/windows_host.h deleted file mode 100644 index 6550e5e82..000000000 --- a/thirdparty/libarchive/contrib/android/config/windows_host.h +++ /dev/null @@ -1,1059 +0,0 @@ -/* config.h. Generated from config.h.in by configure. */ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* MD5 via ARCHIVE_CRYPTO_MD5_LIBC supported. */ -/* #undef ARCHIVE_CRYPTO_MD5_LIBC */ - -/* MD5 via ARCHIVE_CRYPTO_MD5_LIBMD supported. */ -/* #undef ARCHIVE_CRYPTO_MD5_LIBMD */ - -/* MD5 via ARCHIVE_CRYPTO_MD5_LIBSYSTEM supported. */ -/* #undef ARCHIVE_CRYPTO_MD5_LIBSYSTEM */ - -/* MD5 via ARCHIVE_CRYPTO_MD5_NETTLE supported. */ -/* #undef ARCHIVE_CRYPTO_MD5_NETTLE */ - -/* MD5 via ARCHIVE_CRYPTO_MD5_OPENSSL supported. */ -/* #undef ARCHIVE_CRYPTO_MD5_OPENSSL */ - -/* MD5 via ARCHIVE_CRYPTO_MD5_WIN supported. */ -#define ARCHIVE_CRYPTO_MD5_WIN 1 - -/* RMD160 via ARCHIVE_CRYPTO_RMD160_LIBC supported. */ -/* #undef ARCHIVE_CRYPTO_RMD160_LIBC */ - -/* RMD160 via ARCHIVE_CRYPTO_RMD160_LIBMD supported. */ -/* #undef ARCHIVE_CRYPTO_RMD160_LIBMD */ - -/* RMD160 via ARCHIVE_CRYPTO_RMD160_NETTLE supported. */ -/* #undef ARCHIVE_CRYPTO_RMD160_NETTLE */ - -/* RMD160 via ARCHIVE_CRYPTO_RMD160_OPENSSL supported. */ -/* #undef ARCHIVE_CRYPTO_RMD160_OPENSSL */ - -/* SHA1 via ARCHIVE_CRYPTO_SHA1_LIBC supported. */ -/* #undef ARCHIVE_CRYPTO_SHA1_LIBC */ - -/* SHA1 via ARCHIVE_CRYPTO_SHA1_LIBMD supported. */ -/* #undef ARCHIVE_CRYPTO_SHA1_LIBMD */ - -/* SHA1 via ARCHIVE_CRYPTO_SHA1_LIBSYSTEM supported. */ -/* #undef ARCHIVE_CRYPTO_SHA1_LIBSYSTEM */ - -/* SHA1 via ARCHIVE_CRYPTO_SHA1_NETTLE supported. */ -/* #undef ARCHIVE_CRYPTO_SHA1_NETTLE */ - -/* SHA1 via ARCHIVE_CRYPTO_SHA1_OPENSSL supported. */ -/* #undef ARCHIVE_CRYPTO_SHA1_OPENSSL */ - -/* SHA1 via ARCHIVE_CRYPTO_SHA1_WIN supported. */ -#define ARCHIVE_CRYPTO_SHA1_WIN 1 - -/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBC supported. */ -/* #undef ARCHIVE_CRYPTO_SHA256_LIBC */ - -/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBC2 supported. */ -/* #undef ARCHIVE_CRYPTO_SHA256_LIBC2 */ - -/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBC3 supported. */ -/* #undef ARCHIVE_CRYPTO_SHA256_LIBC3 */ - -/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBMD supported. */ -/* #undef ARCHIVE_CRYPTO_SHA256_LIBMD */ - -/* SHA256 via ARCHIVE_CRYPTO_SHA256_LIBSYSTEM supported. */ -/* #undef ARCHIVE_CRYPTO_SHA256_LIBSYSTEM */ - -/* SHA256 via ARCHIVE_CRYPTO_SHA256_NETTLE supported. */ -/* #undef ARCHIVE_CRYPTO_SHA256_NETTLE */ - -/* SHA256 via ARCHIVE_CRYPTO_SHA256_OPENSSL supported. */ -/* #undef ARCHIVE_CRYPTO_SHA256_OPENSSL */ - -/* SHA256 via ARCHIVE_CRYPTO_SHA256_WIN supported. */ -#define ARCHIVE_CRYPTO_SHA256_WIN 1 - -/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBC supported. */ -/* #undef ARCHIVE_CRYPTO_SHA384_LIBC */ - -/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBC2 supported. */ -/* #undef ARCHIVE_CRYPTO_SHA384_LIBC2 */ - -/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBC3 supported. */ -/* #undef ARCHIVE_CRYPTO_SHA384_LIBC3 */ - -/* SHA384 via ARCHIVE_CRYPTO_SHA384_LIBSYSTEM supported. */ -/* #undef ARCHIVE_CRYPTO_SHA384_LIBSYSTEM */ - -/* SHA384 via ARCHIVE_CRYPTO_SHA384_NETTLE supported. */ -/* #undef ARCHIVE_CRYPTO_SHA384_NETTLE */ - -/* SHA384 via ARCHIVE_CRYPTO_SHA384_OPENSSL supported. */ -/* #undef ARCHIVE_CRYPTO_SHA384_OPENSSL */ - -/* SHA384 via ARCHIVE_CRYPTO_SHA384_WIN supported. */ -#define ARCHIVE_CRYPTO_SHA384_WIN 1 - -/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBC supported. */ -/* #undef ARCHIVE_CRYPTO_SHA512_LIBC */ - -/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBC2 supported. */ -/* #undef ARCHIVE_CRYPTO_SHA512_LIBC2 */ - -/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBC3 supported. */ -/* #undef ARCHIVE_CRYPTO_SHA512_LIBC3 */ - -/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBMD supported. */ -/* #undef ARCHIVE_CRYPTO_SHA512_LIBMD */ - -/* SHA512 via ARCHIVE_CRYPTO_SHA512_LIBSYSTEM supported. */ -/* #undef ARCHIVE_CRYPTO_SHA512_LIBSYSTEM */ - -/* SHA512 via ARCHIVE_CRYPTO_SHA512_NETTLE supported. */ -/* #undef ARCHIVE_CRYPTO_SHA512_NETTLE */ - -/* SHA512 via ARCHIVE_CRYPTO_SHA512_OPENSSL supported. */ -/* #undef ARCHIVE_CRYPTO_SHA512_OPENSSL */ - -/* SHA512 via ARCHIVE_CRYPTO_SHA512_WIN supported. */ -#define ARCHIVE_CRYPTO_SHA512_WIN 1 - -/* Define to 1 if you have the `acl_create_entry' function. */ -/* #undef HAVE_ACL_CREATE_ENTRY */ - -/* Define to 1 if you have the `acl_get_link' function. */ -/* #undef HAVE_ACL_GET_LINK */ - -/* Define to 1 if you have the `acl_get_link_np' function. */ -/* #undef HAVE_ACL_GET_LINK_NP */ - -/* Define to 1 if you have the `acl_get_perm' function. */ -/* #undef HAVE_ACL_GET_PERM */ - -/* Define to 1 if you have the `acl_get_perm_np' function. */ -/* #undef HAVE_ACL_GET_PERM_NP */ - -/* Define to 1 if you have the `acl_init' function. */ -/* #undef HAVE_ACL_INIT */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_ACL_LIBACL_H */ - -/* Define to 1 if the system has the type `acl_permset_t'. */ -/* #undef HAVE_ACL_PERMSET_T */ - -/* Define to 1 if you have the `acl_set_fd' function. */ -/* #undef HAVE_ACL_SET_FD */ - -/* Define to 1 if you have the `acl_set_fd_np' function. */ -/* #undef HAVE_ACL_SET_FD_NP */ - -/* Define to 1 if you have the `acl_set_file' function. */ -/* #undef HAVE_ACL_SET_FILE */ - -/* True for systems with POSIX ACL support */ -/* #undef HAVE_ACL_USER */ - -/* Define to 1 if you have the `arc4random_buf' function. */ -/* #undef HAVE_ARC4RANDOM_BUF */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_ATTR_XATTR_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_BCRYPT_H - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_BZLIB_H */ - -/* Define to 1 if you have the `chflags' function. */ -/* #undef HAVE_CHFLAGS */ - -/* Define to 1 if you have the `chown' function. */ -/* #undef HAVE_CHOWN */ - -/* Define to 1 if you have the `chroot' function. */ -/* #undef HAVE_CHROOT */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_COPYFILE_H */ - -/* Define to 1 if you have the `ctime_r' function. */ -/* #undef HAVE_CTIME_R */ - -/* Define to 1 if you have the header file. */ -#define HAVE_CTYPE_H 1 - -/* Define to 1 if you have the `cygwin_conv_path' function. */ -/* #undef HAVE_CYGWIN_CONV_PATH */ - -/* Define to 1 if you have the declaration of `EXTATTR_NAMESPACE_USER', and to - 0 if you don't. */ -#define HAVE_DECL_EXTATTR_NAMESPACE_USER 0 - -/* Define to 1 if you have the declaration of `INT64_MAX', and to 0 if you - don't. */ -#define HAVE_DECL_INT64_MAX 1 - -/* Define to 1 if you have the declaration of `INT64_MIN', and to 0 if you - don't. */ -#define HAVE_DECL_INT64_MIN 1 - -/* Define to 1 if you have the declaration of `SIZE_MAX', and to 0 if you - don't. */ -#define HAVE_DECL_SIZE_MAX 1 - -/* Define to 1 if you have the declaration of `SSIZE_MAX', and to 0 if you - don't. */ -#define HAVE_DECL_SSIZE_MAX 1 - -/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you - don't. */ -#define HAVE_DECL_STRERROR_R 0 - -/* Define to 1 if you have the declaration of `UINT32_MAX', and to 0 if you - don't. */ -#define HAVE_DECL_UINT32_MAX 1 - -/* Define to 1 if you have the declaration of `UINT64_MAX', and to 0 if you - don't. */ -#define HAVE_DECL_UINT64_MAX 1 - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -#define HAVE_DIRENT_H 1 - -/* Define to 1 if you have the `dirfd' function. */ -/* #undef HAVE_DIRFD */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_DLFCN_H */ - -/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ -/* #undef HAVE_DOPRNT */ - -/* Define to 1 if nl_langinfo supports D_MD_ORDER */ -/* #undef HAVE_D_MD_ORDER */ - -/* A possible errno value for invalid file format errors */ -/* #undef HAVE_EFTYPE */ - -/* A possible errno value for invalid file format errors */ -#define HAVE_EILSEQ 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_ERRNO_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_EXPAT_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_EXT2FS_EXT2_FS_H */ - -/* Define to 1 if you have the `extattr_get_file' function. */ -/* #undef HAVE_EXTATTR_GET_FILE */ - -/* Define to 1 if you have the `extattr_list_file' function. */ -/* #undef HAVE_EXTATTR_LIST_FILE */ - -/* Define to 1 if you have the `extattr_set_fd' function. */ -/* #undef HAVE_EXTATTR_SET_FD */ - -/* Define to 1 if you have the `extattr_set_file' function. */ -/* #undef HAVE_EXTATTR_SET_FILE */ - -/* Define to 1 if you have the `fchdir' function. */ -/* #undef HAVE_FCHDIR */ - -/* Define to 1 if you have the `fchflags' function. */ -/* #undef HAVE_FCHFLAGS */ - -/* Define to 1 if you have the `fchmod' function. */ -/* #undef HAVE_FCHMOD */ - -/* Define to 1 if you have the `fchown' function. */ -/* #undef HAVE_FCHOWN */ - -/* Define to 1 if you have the `fcntl' function. */ -/* #undef HAVE_FCNTL */ - -/* Define to 1 if you have the header file. */ -#define HAVE_FCNTL_H 1 - -/* Define to 1 if you have the `fdopendir' function. */ -/* #undef HAVE_FDOPENDIR */ - -/* Define to 1 if you have the `fgetea' function. */ -/* #undef HAVE_FGETEA */ - -/* Define to 1 if you have the `fgetxattr' function. */ -/* #undef HAVE_FGETXATTR */ - -/* Define to 1 if you have the `flistea' function. */ -/* #undef HAVE_FLISTEA */ - -/* Define to 1 if you have the `flistxattr' function. */ -/* #undef HAVE_FLISTXATTR */ - -/* Define to 1 if you have the `fork' function. */ -/* #undef HAVE_FORK */ - -/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ -#define HAVE_FSEEKO 1 - -/* Define to 1 if you have the `fsetea' function. */ -/* #undef HAVE_FSETEA */ - -/* Define to 1 if you have the `fsetxattr' function. */ -/* #undef HAVE_FSETXATTR */ - -/* Define to 1 if you have the `fstat' function. */ -#define HAVE_FSTAT 1 - -/* Define to 1 if you have the `fstatat' function. */ -/* #undef HAVE_FSTATAT */ - -/* Define to 1 if you have the `fstatfs' function. */ -/* #undef HAVE_FSTATFS */ - -/* Define to 1 if you have the `fstatvfs' function. */ -/* #undef HAVE_FSTATVFS */ - -/* Define to 1 if you have the `ftruncate' function. */ -#define HAVE_FTRUNCATE 1 - -/* Define to 1 if you have the `futimens' function. */ -/* #undef HAVE_FUTIMENS */ - -/* Define to 1 if you have the `futimes' function. */ -/* #undef HAVE_FUTIMES */ - -/* Define to 1 if you have the `futimesat' function. */ -/* #undef HAVE_FUTIMESAT */ - -/* Define to 1 if you have the `getea' function. */ -/* #undef HAVE_GETEA */ - -/* Define to 1 if you have the `geteuid' function. */ -/* #undef HAVE_GETEUID */ - -/* Define to 1 if you have the `getgrgid_r' function. */ -/* #undef HAVE_GETGRGID_R */ - -/* Define to 1 if you have the `getgrnam_r' function. */ -/* #undef HAVE_GETGRNAM_R */ - -/* Define to 1 if you have the `getpid' function. */ -#define HAVE_GETPID 1 - -/* Define to 1 if you have the `getpwnam_r' function. */ -/* #undef HAVE_GETPWNAM_R */ - -/* Define to 1 if you have the `getpwuid_r' function. */ -/* #undef HAVE_GETPWUID_R */ - -/* Define to 1 if you have the `getvfsbyname' function. */ -/* #undef HAVE_GETVFSBYNAME */ - -/* Define to 1 if you have the `getxattr' function. */ -/* #undef HAVE_GETXATTR */ - -/* Define to 1 if you have the `gmtime_r' function. */ -/* #undef HAVE_GMTIME_R */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_GRP_H */ - -/* Define if you have the iconv() function and it works. */ -/* #undef HAVE_ICONV */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_ICONV_H */ - -/* Define to 1 if the system has the type `intmax_t'. */ -#define HAVE_INTMAX_T 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_IO_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_LANGINFO_H */ - -/* Define to 1 if you have the `lchflags' function. */ -/* #undef HAVE_LCHFLAGS */ - -/* Define to 1 if you have the `lchmod' function. */ -/* #undef HAVE_LCHMOD */ - -/* Define to 1 if you have the `lchown' function. */ -/* #undef HAVE_LCHOWN */ - -/* Define to 1 if you have the `lgetea' function. */ -/* #undef HAVE_LGETEA */ - -/* Define to 1 if you have the `lgetxattr' function. */ -/* #undef HAVE_LGETXATTR */ - -/* Define to 1 if you have the `acl' library (-lacl). */ -/* #undef HAVE_LIBACL */ - -/* Define to 1 if you have the `attr' library (-lattr). */ -/* #undef HAVE_LIBATTR */ - -/* Define to 1 if you have the `bz2' library (-lbz2). */ -/* #undef HAVE_LIBBZ2 */ - -/* Define to 1 if you have the `charset' library (-lcharset). */ -/* #undef HAVE_LIBCHARSET */ - -/* Define to 1 if you have the `crypto' library (-lcrypto). */ -/* #undef HAVE_LIBCRYPTO */ - -/* Define to 1 if you have the `eay32' library (-leay32). */ -/* #undef HAVE_LIBEAY32 */ - -/* Define to 1 if you have the `eay64' library (-leay64). */ -/* #undef HAVE_LIBEAY64 */ - -/* Define to 1 if you have the `expat' library (-lexpat). */ -/* #undef HAVE_LIBEXPAT */ - -/* Define to 1 if you have the `lz4' library (-llz4). */ -/* #undef HAVE_LIBLZ4 */ - -/* Define to 1 if you have the `lzma' library (-llzma). */ -/* #undef HAVE_LIBLZMA */ - -/* Define to 1 if you have the `lzo2' library (-llzo2). */ -/* #undef HAVE_LIBLZO2 */ - -/* Define to 1 if you have the `md' library (-lmd). */ -/* #undef HAVE_LIBMD */ - -/* Define to 1 if you have the `nettle' library (-lnettle). */ -/* #undef HAVE_LIBNETTLE */ - -/* Define to 1 if you have the `pcre' library (-lpcre). */ -/* #undef HAVE_LIBPCRE */ - -/* Define to 1 if you have the `pcreposix' library (-lpcreposix). */ -/* #undef HAVE_LIBPCREPOSIX */ - -/* Define to 1 if you have the `regex' library (-lregex). */ -/* #undef HAVE_LIBREGEX */ - -/* Define to 1 if you have the `xml2' library (-lxml2). */ -/* #undef HAVE_LIBXML2 */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_LIBXML_XMLREADER_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_LIBXML_XMLWRITER_H */ - -/* Define to 1 if you have the `z' library (-lz). */ -/* #undef HAVE_LIBZ */ - -/* Define to 1 if you have the header file. */ -#define HAVE_LIMITS_H 1 - -/* Define to 1 if you have the `link' function. */ -/* #undef HAVE_LINK */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_LINUX_FIEMAP_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_LINUX_FS_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_LINUX_MAGIC_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_LINUX_TYPES_H */ - -/* Define to 1 if you have the `listea' function. */ -/* #undef HAVE_LISTEA */ - -/* Define to 1 if you have the `listxattr' function. */ -/* #undef HAVE_LISTXATTR */ - -/* Define to 1 if you have the `llistea' function. */ -/* #undef HAVE_LLISTEA */ - -/* Define to 1 if you have the `llistxattr' function. */ -/* #undef HAVE_LLISTXATTR */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_LOCALCHARSET_H */ - -/* Define to 1 if you have the `locale_charset' function. */ -/* #undef HAVE_LOCALE_CHARSET */ - -/* Define to 1 if you have the header file. */ -#define HAVE_LOCALE_H 1 - -/* Define to 1 if you have the `localtime_r' function. */ -/* #undef HAVE_LOCALTIME_R */ - -/* Define to 1 if the system has the type `long long int'. */ -#define HAVE_LONG_LONG_INT 1 - -/* Define to 1 if you have the `lsetea' function. */ -/* #undef HAVE_LSETEA */ - -/* Define to 1 if you have the `lsetxattr' function. */ -/* #undef HAVE_LSETXATTR */ - -/* Define to 1 if you have the `lstat' function. */ -/* #undef HAVE_LSTAT */ - -/* Define to 1 if `lstat' has the bug that it succeeds when given the - zero-length file name argument. */ -#define HAVE_LSTAT_EMPTY_STRING_BUG 1 - -/* Define to 1 if you have the `lutimes' function. */ -/* #undef HAVE_LUTIMES */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_LZ4HC_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_LZ4_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_LZMADEC_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_LZMA_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_LZO_LZO1X_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_LZO_LZOCONF_H */ - -/* Define to 1 if you have the `mbrtowc' function. */ -#define HAVE_MBRTOWC 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_MD5_H */ - -/* Define to 1 if you have the `memmove' function. */ -#define HAVE_MEMMOVE 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the `memset' function. */ -#define HAVE_MEMSET 1 - -/* Define to 1 if you have the `mkdir' function. */ -#define HAVE_MKDIR 1 - -/* Define to 1 if you have the `mkfifo' function. */ -/* #undef HAVE_MKFIFO */ - -/* Define to 1 if you have the `mknod' function. */ -/* #undef HAVE_MKNOD */ - -/* Define to 1 if you have the `mkstemp' function. */ -/* #undef HAVE_MKSTEMP */ - -/* Define to 1 if you have the header file, and it defines `DIR'. */ -/* #undef HAVE_NDIR_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_NETTLE_MD5_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_NETTLE_PBKDF2_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_NETTLE_RIPEMD160_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_NETTLE_SHA_H */ - -/* Define to 1 if you have the `nl_langinfo' function. */ -/* #undef HAVE_NL_LANGINFO */ - -/* Define to 1 if you have the `openat' function. */ -/* #undef HAVE_OPENAT */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_OPENSSL_EVP_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_PATHS_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_PCREPOSIX_H */ - -/* Define to 1 if you have the `pipe' function. */ -/* #undef HAVE_PIPE */ - -/* Define to 1 if you have the `PKCS5_PBKDF2_HMAC_SHA1' function. */ -/* #undef HAVE_PKCS5_PBKDF2_HMAC_SHA1 */ - -/* Define to 1 if you have the `poll' function. */ -/* #undef HAVE_POLL */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_POLL_H */ - -/* Define to 1 if you have the `posix_spawnp' function. */ -/* #undef HAVE_POSIX_SPAWNP */ - -/* Define to 1 if you have the header file. */ -#define HAVE_PTHREAD_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_PWD_H */ - -/* Define to 1 if you have a POSIX compatible readdir_r */ -#define HAVE_READDIR_R 1 - -/* Define to 1 if you have the `readlink' function. */ -/* #undef HAVE_READLINK */ - -/* Define to 1 if you have the `readlinkat' function. */ -/* #undef HAVE_READLINKAT */ - -/* Define to 1 if you have the `readpassphrase' function. */ -/* #undef HAVE_READPASSPHRASE */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_READPASSPHRASE_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_REGEX_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_RIPEMD_H */ - -/* Define to 1 if you have the `select' function. */ -/* #undef HAVE_SELECT */ - -/* Define to 1 if you have the `setenv' function. */ -/* #undef HAVE_SETENV */ - -/* Define to 1 if you have the `setlocale' function. */ -#define HAVE_SETLOCALE 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SHA256_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SHA512_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SHA_H */ - -/* Define to 1 if you have the `sigaction' function. */ -/* #undef HAVE_SIGACTION */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SIGNAL_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SPAWN_H */ - -/* Define to 1 if you have the `statfs' function. */ -/* #undef HAVE_STATFS */ - -/* Define to 1 if you have the `statvfs' function. */ -/* #undef HAVE_STATVFS */ - -/* Define to 1 if `stat' has the bug that it succeeds when given the - zero-length file name argument. */ -#define HAVE_STAT_EMPTY_STRING_BUG 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDARG_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the `strchr' function. */ -#define HAVE_STRCHR 1 - -/* Define to 1 if you have the `strdup' function. */ -#define HAVE_STRDUP 1 - -/* Define to 1 if you have the `strerror' function. */ -#define HAVE_STRERROR 1 - -/* Define to 1 if you have the `strerror_r' function. */ -/* #undef HAVE_STRERROR_R */ - -/* Define to 1 if you have the `strftime' function. */ -#define HAVE_STRFTIME 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the `strncpy_s' function. */ -#define HAVE_STRNCPY_S 1 - -/* Define to 1 if you have the `strrchr' function. */ -#define HAVE_STRRCHR 1 - -/* Define to 1 if `f_namemax' is a member of `struct statfs'. */ -/* #undef HAVE_STRUCT_STATFS_F_NAMEMAX */ - -/* Define to 1 if `f_iosize' is a member of `struct statvfs'. */ -/* #undef HAVE_STRUCT_STATVFS_F_IOSIZE */ - -/* Define to 1 if `st_birthtime' is a member of `struct stat'. */ -/* #undef HAVE_STRUCT_STAT_ST_BIRTHTIME */ - -/* Define to 1 if `st_birthtimespec.tv_nsec' is a member of `struct stat'. */ -/* #undef HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC */ - -/* Define to 1 if `st_blksize' is a member of `struct stat'. */ -/* #undef HAVE_STRUCT_STAT_ST_BLKSIZE */ - -/* Define to 1 if `st_flags' is a member of `struct stat'. */ -/* #undef HAVE_STRUCT_STAT_ST_FLAGS */ - -/* Define to 1 if `st_mtimespec.tv_nsec' is a member of `struct stat'. */ -/* #undef HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC */ - -/* Define to 1 if `st_mtime_n' is a member of `struct stat'. */ -/* #undef HAVE_STRUCT_STAT_ST_MTIME_N */ - -/* Define to 1 if `st_mtime_usec' is a member of `struct stat'. */ -/* #undef HAVE_STRUCT_STAT_ST_MTIME_USEC */ - -/* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */ -/* #undef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC */ - -/* Define to 1 if `st_umtime' is a member of `struct stat'. */ -/* #undef HAVE_STRUCT_STAT_ST_UMTIME */ - -/* Define to 1 if `tm_gmtoff' is a member of `struct tm'. */ -/* #undef HAVE_STRUCT_TM_TM_GMTOFF */ - -/* Define to 1 if `__tm_gmtoff' is a member of `struct tm'. */ -/* #undef HAVE_STRUCT_TM___TM_GMTOFF */ - -/* Define to 1 if you have the `symlink' function. */ -/* #undef HAVE_SYMLINK */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_ACL_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_CDEFS_H 1 - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -/* #undef HAVE_SYS_DIR_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_EA_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_EXTATTR_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_IOCTL_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_MKDEV_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_MOUNT_H */ - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -/* #undef HAVE_SYS_NDIR_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_PARAM_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_POLL_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_SELECT_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_STATFS_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_STATVFS_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TIME_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_UTIME_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_UTSNAME_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_VFS_H */ - -/* Define to 1 if you have that is POSIX.1 compatible. */ -/* #undef HAVE_SYS_WAIT_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_XATTR_H */ - -/* Define to 1 if you have the `timegm' function. */ -/* #undef HAVE_TIMEGM */ - -/* Define to 1 if you have the header file. */ -#define HAVE_TIME_H 1 - -/* Define to 1 if you have the `tzset' function. */ -#define HAVE_TZSET 1 - -/* Define to 1 if the system has the type `uintmax_t'. */ -#define HAVE_UINTMAX_T 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if you have the `unsetenv' function. */ -/* #undef HAVE_UNSETENV */ - -/* Define to 1 if the system has the type `unsigned long long'. */ -#define HAVE_UNSIGNED_LONG_LONG 1 - -/* Define to 1 if the system has the type `unsigned long long int'. */ -#define HAVE_UNSIGNED_LONG_LONG_INT 1 - -/* Define to 1 if you have the `utime' function. */ -#define HAVE_UTIME 1 - -/* Define to 1 if you have the `utimensat' function. */ -/* #undef HAVE_UTIMENSAT */ - -/* Define to 1 if you have the `utimes' function. */ -/* #undef HAVE_UTIMES */ - -/* Define to 1 if you have the header file. */ -#define HAVE_UTIME_H 1 - -/* Define to 1 if you have the `vfork' function. */ -/* #undef HAVE_VFORK */ - -/* Define to 1 if you have the `vprintf' function. */ -#define HAVE_VPRINTF 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_WCHAR_H 1 - -/* Define to 1 if the system has the type `wchar_t'. */ -#define HAVE_WCHAR_T 1 - -/* Define to 1 if you have the `wcrtomb' function. */ -#define HAVE_WCRTOMB 1 - -/* Define to 1 if you have the `wcscmp' function. */ -#define HAVE_WCSCMP 1 - -/* Define to 1 if you have the `wcscpy' function. */ -#define HAVE_WCSCPY 1 - -/* Define to 1 if you have the `wcslen' function. */ -#define HAVE_WCSLEN 1 - -/* Define to 1 if you have the `wctomb' function. */ -#define HAVE_WCTOMB 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_WCTYPE_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_WINCRYPT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_WINDOWS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_WINIOCTL_H 1 - -/* Define to 1 if you have the `wmemcmp' function. */ -#define HAVE_WMEMCMP 1 - -/* Define to 1 if you have the `wmemcpy' function. */ -#define HAVE_WMEMCPY 1 - -/* Define to 1 if you have a working EXT2_IOC_GETFLAGS */ -/* #undef HAVE_WORKING_EXT2_IOC_GETFLAGS */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_ZLIB_H */ - -/* Define to 1 if you have the `ctime_s' function. */ -#define HAVE_CTIME_S 1 - -/* Define to 1 if you have the `_fseeki64' function. */ -#define HAVE__FSEEKI64 1 - -/* Define to 1 if you have the `_get_timezone' function. */ -/* #undef HAVE__GET_TIMEZONE */ - -/* Define to 1 if you have the `localtime_s' function. */ -#define HAVE_LOCALTIME_S 1 - -/* Define to 1 if you have the `_mkgmtime' function. */ -/* #define HAVE__MKGMTIME 1 */ - -/* Define as const if the declaration of iconv() needs const. */ -/* #undef ICONV_CONST */ - -/* Define to 1 if `lstat' dereferences a symlink specified with a trailing - slash. */ -/* #undef LSTAT_FOLLOWS_SLASHED_SYMLINK */ - -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ - -/* Define to 1 if `major', `minor', and `makedev' are declared in . - */ -/* #undef MAJOR_IN_MKDEV */ - -/* Define to 1 if `major', `minor', and `makedev' are declared in - . */ -/* #undef MAJOR_IN_SYSMACROS */ - - -/* Define to 1 if PCRE_STATIC needs to be defined. */ -/* #undef PCRE_STATIC */ - -/* The size of `wchar_t', as computed by sizeof. */ -#define SIZEOF_WCHAR_T 2 - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define to 1 if strerror_r returns char *. */ -/* #undef STRERROR_R_CHAR_P */ - -/* Define to 1 if you can safely include both and . */ -#define HAVE_SYS_TIME_H 1 - - - -/* Define to '0x0500' for Windows 2000 APIs. */ -#define WINVER 0x0500 - -/* Number of bits in a file offset, on hosts where this is settable. */ -#define _FILE_OFFSET_BITS 64 - -/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ -/* #undef _LARGEFILE_SOURCE */ - -/* Define for large files, on AIX-style hosts. */ -/* #undef _LARGE_FILES */ - -/* Define to 1 if on MINIX. */ -/* #undef _MINIX */ - -/* Define to 2 if the system does not provide POSIX.1 features except with - this defined. */ -/* #undef _POSIX_1_SOURCE */ - -/* Define to 1 if you need to in order for `stat' and other things to work. */ -/* #undef _POSIX_SOURCE */ - -/* Define for Solaris 2.5.1 so the uint32_t typedef from , - , or is not used. If the typedef were allowed, the - #define below would cause a syntax error. */ -/* #undef _UINT32_T */ - -/* Define for Solaris 2.5.1 so the uint64_t typedef from , - , or is not used. If the typedef were allowed, the - #define below would cause a syntax error. */ -/* #undef _UINT64_T */ - -/* Define for Solaris 2.5.1 so the uint8_t typedef from , - , or is not used. If the typedef were allowed, the - #define below would cause a syntax error. */ -/* #undef _UINT8_T */ - -/* Define to '0x0500' for Windows 2000 APIs. */ -#define _WIN32_WINNT 0x0500 - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* Define to match typeof st_gid field of struct stat if doesn't - define. */ -#define gid_t short - -/* Define to `unsigned long' if does not define. */ -#define id_t unsigned long - -/* Define to the type of a signed integer type of width exactly 16 bits if - such a type exists and the standard includes do not define it. */ -/* #undef int16_t */ - -/* Define to the type of a signed integer type of width exactly 32 bits if - such a type exists and the standard includes do not define it. */ -/* #undef int32_t */ - -/* Define to the type of a signed integer type of width exactly 64 bits if - such a type exists and the standard includes do not define it. */ -/* #undef int64_t */ - -/* Define to the widest signed integer type if and do - not define. */ -/* #undef intmax_t */ - -/* Define to `int' if does not define. */ -/* #undef mode_t */ - -/* Define to `long long' if does not define. */ -/* #undef off_t */ - -/* Define to `unsigned int' if does not define. */ -/* #undef size_t */ - -/* Define to match typeof st_uid field of struct stat if doesn't - define. */ -#define uid_t short - -/* Define to the type of an unsigned integer type of width exactly 16 bits if - such a type exists and the standard includes do not define it. */ -/* #undef uint16_t */ - -/* Define to the type of an unsigned integer type of width exactly 32 bits if - such a type exists and the standard includes do not define it. */ -/* #undef uint32_t */ - -/* Define to the type of an unsigned integer type of width exactly 64 bits if - such a type exists and the standard includes do not define it. */ -/* #undef uint64_t */ - -/* Define to the type of an unsigned integer type of width exactly 8 bits if - such a type exists and the standard includes do not define it. */ -/* #undef uint8_t */ - -/* Define to the widest unsigned integer type if and - do not define. */ -/* #undef uintmax_t */ - -/* Define to `unsigned int' if does not define. */ -/* #undef uintptr_t */ diff --git a/thirdparty/libarchive/contrib/android/include/Bcrypt.h b/thirdparty/libarchive/contrib/android/include/Bcrypt.h deleted file mode 100644 index df2959902..000000000 --- a/thirdparty/libarchive/contrib/android/include/Bcrypt.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/thirdparty/libarchive/contrib/android/include/Windows.h b/thirdparty/libarchive/contrib/android/include/Windows.h deleted file mode 100644 index 776a87ce3..000000000 --- a/thirdparty/libarchive/contrib/android/include/Windows.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/thirdparty/libarchive/contrib/android/include/android_lf.h b/thirdparty/libarchive/contrib/android/include/android_lf.h deleted file mode 100644 index 3c5475e35..000000000 --- a/thirdparty/libarchive/contrib/android/include/android_lf.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Macros for file64 functions - * - * Android does not support the macro _FILE_OFFSET_BITS=64 - * As of android-21 it does however support many file64 functions -*/ - -#ifndef ARCHIVE_ANDROID_LF_H_INCLUDED -#define ARCHIVE_ANDROID_LF_H_INCLUDED - -#if __ANDROID_API__ > 20 - -#include -#include -#include -#include -#include -#include -#include - -//dirent.h -#define readdir_r readdir64_r -#define readdir readdir64 -#define dirent dirent64 -//fcntl.h -#define openat openat64 -#define open open64 -#define mkstemp mkstemp64 -//unistd.h -#define lseek lseek64 -#define ftruncate ftruncate64 -//sys/stat.h -#define fstatat fstatat64 -#define fstat fstat64 -#define lstat lstat64 -#define stat stat64 -//sys/statvfs.h -#define fstatvfs fstatvfs64 -#define statvfs statvfs64 -//sys/types.h -#define off_t off64_t -//sys/vfs.h -#define fstatfs fstatfs64 -#define statfs statfs64 -#endif - -#endif /* ARCHIVE_ANDROID_LF_H_INCLUDED */ diff --git a/thirdparty/libarchive/contrib/archivetest.c b/thirdparty/libarchive/contrib/archivetest.c deleted file mode 100644 index 794221fbb..000000000 --- a/thirdparty/libarchive/contrib/archivetest.c +++ /dev/null @@ -1,235 +0,0 @@ -/*- - * Copyright (c) 2019 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -/* - * Archivetest verifies reading archives with libarchive - * - * It may be used to reproduce failures in testcases discovered by OSS-Fuzz - * https://github.com/google/oss-fuzz/blob/master/projects/libarchive - */ - -#include -#include -#include -#include -#include -#include - -#if defined __MINGW32__ -#include -#endif - -static const char *errnostr(int e) -{ - char *estr; - switch(e) { - case ARCHIVE_EOF: - estr = "ARCHIVE_EOF"; - break; - case ARCHIVE_OK: - estr = "ARCHIVE_OK"; - break; - case ARCHIVE_WARN: - estr = "ARCHIVE_WARN"; - break; - case ARCHIVE_RETRY: - estr = "ARCHIVE_RETRY"; - break; - case ARCHIVE_FAILED: - estr = "ARCHIVE_FAILED"; - break; - case ARCHIVE_FATAL: - estr = "ARCHIVE_FATAL"; - break; - default: - estr = "Unknown"; - break; - } - return (estr); -} - -static void usage(const char *prog) -{ - fprintf(stderr, "Usage: %s [-f filename] [-h] [-q] [-s]\n", prog); -} - -static void printhelp() -{ - fprintf(stdout, "archivetest: verify reading archives with " - "libarchive\n\n" - "Options:\n" - " -f filename Filename to verify\n" - " -h Show this help\n" - " -q Quiet mode\n" - " -r Enforce raw archive format\n" - " -s Verify only headers (skip data)\n\n" - "If no filename is specified, data is read from standard input.\n" - "\n%s\n", archive_version_details()); -} - -static int v_print(int verbose, const char *format, ...) -{ - int r = 0; - - if (verbose) { - va_list args; - - va_start(args, format); - r = vfprintf(stdout, format, args); - va_end(args); - } - return (r); -} - -int main(int argc, char *argv[]) -{ - struct archive *a; - struct archive_entry *entry; - char *filename; - const char *p; - char buffer[4096]; - int c; - int v, skip_data, raw; - int r = ARCHIVE_OK; - int format_printed; - mode_t mode; - - filename = NULL; - skip_data = 0; - raw = 0; - v = 1; - - while ((c = getopt (argc, argv, "f:hrqs")) != -1) { - switch (c) { - case 'f': - filename = optarg; - break; - case 'h': - printhelp(); - exit(0); - case 'q': - v = 0; - break; - case 'r': - raw = 1; - break; - case 's': - skip_data = 1; - break; - case '?': - if (optopt == 'f') - fprintf(stderr, "Option -%c requires " - "an argument.\n", optopt); - else if (isprint(optopt)) - fprintf(stderr, "Unknown option '-%c'" - ".\n", optopt); - else - fprintf(stderr, "Unknown option " - "character '\\x%x'.\n", optopt); - usage(argv[0]); - exit(1); - break; - default: - exit(1); - } - } - - a = archive_read_new(); - - archive_read_support_filter_all(a); - if (raw) - archive_read_support_format_raw(a); - else - archive_read_support_format_all(a); - - v_print(v, "Data source: "); - - if (filename == NULL) { - v_print(v, "standard input\n"); - r = archive_read_open_fd(a, STDIN_FILENO, 4096); - } else { - v_print(v, "filename: %s\n", filename); - r = archive_read_open_filename(a, filename, 4096); - } - - if (r != ARCHIVE_OK) { - archive_read_free(a); - fprintf(stderr, "Invalid or unsupported data source\n"); - exit(1); - } - - format_printed = 0; - c = 1; - - while (1) { - r = archive_read_next_header(a, &entry); - if (r == ARCHIVE_FATAL) { - v_print(v, "Entry %d: fatal error reading " - "header\n", c); - break; - } - if (!format_printed) { - v_print(v, "Filter: %s\nFormat: %s\n", - archive_filter_name(a, 0), archive_format_name(a)); - format_printed = 1; - } - if (r == ARCHIVE_RETRY) - continue; - if (r == ARCHIVE_EOF) - break; - p = archive_entry_pathname(entry); - mode = archive_entry_mode(entry); - v_print(v, "Entry %d: %s, pathname", c, errnostr(r)); - if (p == NULL || p[0] == '\0') - v_print(v, " unreadable"); - else - v_print(v, ": %s", p); - v_print(v, ", mode: %o", mode); - v_print(v, ", data: "); - if (skip_data) { - v_print(v, "skipping"); - } else { - while ((r = archive_read_data(a, buffer, 4096)) > 0) - ; - if (r == ARCHIVE_FATAL) { - v_print(v, "ERROR\nError string: %s\n", - archive_error_string(a)); - break; - } - v_print(v, "OK"); - } - v_print(v, "\n"); - c++; - } - - v_print(v, "Last return code: %s (%d)\n", errnostr(r), r); - if (r == ARCHIVE_EOF || r == ARCHIVE_OK) { - archive_read_free(a); - exit(0); - } - v_print(v, "Error string: %s\n", archive_error_string(a)); - archive_read_free(a); - exit(2); -} diff --git a/thirdparty/libarchive/contrib/libarchive.1aix53.spec b/thirdparty/libarchive/contrib/libarchive.1aix53.spec deleted file mode 100644 index fe81d147e..000000000 --- a/thirdparty/libarchive/contrib/libarchive.1aix53.spec +++ /dev/null @@ -1,160 +0,0 @@ -# $LastChangedRevision$, $LastChangedDate$ -Summary: Library to create and read several different archive formats -Summary(pl): Biblioteka do tworzenia i odczytu ró¿nych formatów archiwów -Name: libarchive -Version: 2.0a3 -Release: 1aix53 -License: BSD -Group: Libraries -Source0: http://people.freebsd.org/~kientzle/libarchive/src/%{name}-%{version}.tar.gz -Patch: %{name}-0123457890.patch -URL: http://people.freebsd.org/~kientzle/libarchive/ -Requires: glibc -Requires: zlib -Requires: bzip2 -BuildRequires: gcc -BuildRequires: gcc-c++ -BuildRequires: gawk -BuildRequires: zlib-devel -BuildRequires: bzip2 -BuildRoot: %{_tmppath}/%{name}-%{version}-build - -%description -Libarchive is a programming library that can create and read several -different streaming archive formats, including most popular TAR -variants and several CPIO formats. It can also write SHAR archives. - -%description -l pl -Libarchive jest bibliotek± s³u¿ac± to tworzenia i odczytu wielu -ró¿nych strumieniowych formatów archiwów, w³±czaj±c w to popularne -odmiany TAR oraz wiele formatów CPIO. Biblioteka ta potrafi tak¿e -zapisywaæ archiwa SHAR. - -%package devel -Summary: Header files for libarchive library -Summary(pl): Pliki nag³ówkowe biblioteki libarchive -Group: Development/Libraries -Requires: %{name} = %{version}-%{release} - -%description devel -Header files for libarchive library. - -%description devel -l pl -Pliki nag³ówkowe biblioteki libarchive. - -%package static -Summary: Static libarchive library -Summary(pl): Statyczna biblioteka libarchive -Group: Development/Libraries -Requires: %{name}-devel = %{version}-%{release} - -%description static -Static libarchive library. - -%description static -l pl -Statyczna biblioteka libarchive. - -%package -n bsdtar -Summary: bsdtar - tar(1) implementation based on libarchive -Summary(pl): bsdtar - implementacja programu tar(1) oparta na libarchive -Group: Applications/Archiving -Requires: %{name} = %{version}-%{release} - -%description -n bsdtar -bsdtar - tar(1) implementation based on libarchive. - -%description -n bsdtar -l pl -bsdtar - implementacja programu tar(1), oparta na libarchive. - -%prep -%setup -q -%patch0 -p1 - -%build -# Specify paths to avoid use of vacpp -# -maix64 - required to use large files with aix-5.3 -# -static - required for interoperability without copying libraries -# -D_BSD - required to include definition of makedev -# -X64 - required to assemble 64-bit COFF files -mkdir -p %{buildroot} -PATH=/opt/freeware/libexec:/opt/freeware/bin:/usr/local/bin:/usr/bin:/etc:/usr/sbin:/usr/ucb:/usr/bin/X11:/sbin:. \ -CPATH=/opt/freeware/include:/usr/local/include \ -LIBPATH=/opt/freeware/lib:/usr/local/lib:/usr/share/lib \ -LD_LIBRARY_PATH=/opt/freeware/lib:/usr/local/lib:/usr/share/lib \ -CFLAGS="$RPM_OPT_FLAGS -maix64 -static -D_BSD" \ -CXXFLAGS="$RPM_OPT_FLAGS -maix64 -static -D_BSD" \ -AR="ar -X64" \ -./configure \ ---prefix=%{_prefix} \ ---libexecdir=%{_libexecdir} \ ---mandir=%{_mandir} \ ---infodir=%{_infodir} \ ---enable-shared=yes \ ---enable-static=yes \ -| tee %{buildroot}/config.log -make | tee %{buildroot}/make.log - -%install -[ "%buildroot" != "/" ] && [ -d %buildroot ] && rm -rf %buildroot; -make DESTDIR=%buildroot install -# original install builds, but does install bsdtar -cp .libs/%{name}.a %{buildroot}%{_libdir} -cp bsdtar %{buildroot}%{_bindir} -cp tar/bsdtar.1 %{buildroot}%{_mandir}/man1 - -%clean -rm -fr %buildroot - -%files -%defattr(644,root,root,755) -%{_libdir}/libarchive.a - -%files devel -%defattr(644,root,root,755) -%{_libdir}/libarchive.la -%{_includedir}/*.h -%doc %{_mandir}/man3/* -%doc %{_mandir}/man5/* - -%files -n bsdtar -%defattr(644,root,root,755) -%attr(755,root,root) %{_bindir}/bsdtar -%doc %{_mandir}/man1/bsdtar.1* - -%define date %(echo `LC_ALL="C" date +"%a %b %d %Y"`) -%changelog -* %{date} PLD Team -All persons listed below can be reached at @pld-linux.org - -$Log: libarchive.spec,v $ -Release 1aix53 2006/12/12 rm1023@dcx.com -- tweak for aix-5.3 -- added libarchive-0123457890.patch for "0123457890" error -- replaced libarchive-1.3.1.tar.gz with libarchive-2.0a3.tar.gz -- removed obsolete -CVE-2006-5680.patch and -man_progname.patch - -Revision 1.6 2006/11/15 10:41:28 qboosh -- BR: acl-devel,attr-devel -- devel deps - -Revision 1.5 2006/11/08 22:22:25 twittner -- up to 1.3.1 -- added BR: e2fsprogs-devel -- added -CVE-2006-5680.patch against entering an infinite -loop in corrupt archives -- added bsdtar package (bsdtar is included now in libarchive -sources) -- rel. 0.1 for testing - -Revision 1.4 2005/12/15 18:26:36 twittner -- up to 1.2.37 -- removed -shared.patch (no longer needed) - -Revision 1.3 2005/10/05 17:00:12 arekm -- up to 1.02.034 - -Revision 1.2 2005/07/27 20:17:21 qboosh -- typo - -Revision 1.1 2005/07/27 08:36:03 adamg -- new diff --git a/thirdparty/libarchive/contrib/libarchive.spec b/thirdparty/libarchive/contrib/libarchive.spec deleted file mode 100644 index 371ae647f..000000000 --- a/thirdparty/libarchive/contrib/libarchive.spec +++ /dev/null @@ -1,216 +0,0 @@ -Name: {{{ git_name }}} -Version: {{{ git_version lead=3 follow=5 }}} -Release: 1%{?dist} -Summary: A library for handling streaming archive formats - -License: BSD -URL: http://www.libarchive.org/ -Source: {{{ git_pack }}} - -VCS: {{{ git_vcs }}} - -BuildRequires: automake -BuildRequires: bison -BuildRequires: bzip2-devel -BuildRequires: e2fsprogs-devel -BuildRequires: gcc -BuildRequires: libacl-devel -BuildRequires: libattr-devel -BuildRequires: libtool -BuildRequires: libxml2-devel -BuildRequires: libzstd-devel -BuildRequires: lz4-devel -BuildRequires: lzo-devel -BuildRequires: openssl-devel -BuildRequires: sharutils -BuildRequires: xz-devel -BuildRequires: zlib-devel - -%description -Libarchive is a programming library that can create and read several different -streaming archive formats, including most popular tar variants, several cpio -formats, and both BSD and GNU ar variants. It can also write shar archives and -read ISO9660 CDROM images and ZIP archives. - - -%package devel -Summary: Development files for %{name} -Requires: %{name}%{?_isa} = %{version}-%{release} - -%description devel -The %{name}-devel package contains libraries and header files for -developing applications that use %{name}. - - -%package -n bsdtar -Summary: Manipulate tape archives -Requires: %{name}%{?_isa} = %{version}-%{release} - -%description -n bsdtar -The bsdtar package contains standalone bsdtar utility split off regular -libarchive packages. - - -%package -n bsdcpio -Summary: Copy files to and from archives -Requires: %{name}%{?_isa} = %{version}-%{release} - -%description -n bsdcpio -The bsdcpio package contains standalone bsdcpio utility split off regular -libarchive packages. - - -%package -n bsdcat -Summary: Expand files to standard output -Requires: %{name}%{?_isa} = %{version}-%{release} - -%description -n bsdcat -The bsdcat program typically takes a filename as an argument or reads standard -input when used in a pipe. In both cases decompressed data it written to -standard output. - - -%prep -{{{ git_setup_macro }}} -%autosetup -p1 - - -%build -build/autogen.sh -%configure --disable-static --without-nettle LT_SYS_LIBRARY_PATH=%_libdir -%make_build - - -%install -make install DESTDIR=$RPM_BUILD_ROOT -find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';' - -# rhbz#1294252 -replace () -{ - filename=$1 - file=`basename "$filename"` - binary=${file%%.*} - pattern=${binary##bsd} - - awk " - # replace the topic - /^.Dt ${pattern^^} 1/ { - print \".Dt ${binary^^} 1\"; - next; - } - # replace the first occurrence of \"$pattern\" by \"$binary\" - !stop && /^.Nm $pattern/ { - print \".Nm $binary\" ; - stop = 1 ; - next; - } - # print remaining lines - 1; - " "$filename" > "$filename.new" - mv "$filename".new "$filename" -} - -for manpage in bsdtar.1 bsdcpio.1 -do - installed_manpage=`find "$RPM_BUILD_ROOT" -name "$manpage"` - replace "$installed_manpage" -done - - -%check -%if %{with check} -logfiles () -{ - find -name '*_test.log' -or -name test-suite.log -} - -tempdirs () -{ - cat `logfiles` \ - | awk "match(\$0, /[^[:space:]]*`date -I`[^[:space:]]*/) { print substr(\$0, RSTART, RLENGTH); }" \ - | sort | uniq -} - -cat_logs () -{ - for i in `logfiles` - do - echo "=== $i ===" - cat "$i" - done -} - -run_testsuite () -{ - rc=0 - %make_build check -j1 || { - # error happened - try to extract in koji as much info as possible - cat_logs - - for i in `tempdirs`; do - if test -d "$i" ; then - find $i -printf "%p\n ~> a: %a\n ~> c: %c\n ~> t: %t\n ~> %s B\n" - cat $i/*.log - fi - done - return 1 - } - cat_logs -} - -# On a ppc/ppc64 is some race condition causing 'make check' fail on ppc -# when both 32 and 64 builds are done in parallel on the same machine in -# koji. Try to run once again if failed. -%ifarch ppc -run_testsuite || run_testsuite -%else -run_testsuite -%endif -%endif - - -%files -%{!?_licensedir:%global license %%doc} -%license COPYING -%doc NEWS README.md -%{_libdir}/libarchive.so.13* -%{_mandir}/*/cpio.* -%{_mandir}/*/mtree.* -%{_mandir}/*/tar.* - -%files devel -%{_includedir}/*.h -%{_mandir}/*/archive* -%{_mandir}/*/libarchive* -%{_libdir}/libarchive.so -%{_libdir}/pkgconfig/libarchive.pc - -%files -n bsdtar -%{!?_licensedir:%global license %%doc} -%license COPYING -%doc NEWS README.md -%{_bindir}/bsdtar -%{_mandir}/*/bsdtar* - -%files -n bsdcpio -%{!?_licensedir:%global license %%doc} -%license COPYING -%doc NEWS README.md -%{_bindir}/bsdcpio -%{_mandir}/*/bsdcpio* - -%files -n bsdcat -%{!?_licensedir:%global license %%doc} -%license COPYING -%doc NEWS README.md -%{_bindir}/bsdcat -%{_mandir}/*/bsdcat* - - - -%changelog -* Thu Mar 28 2019 Pavel Raiskup - 3.3.3-7 -- simplify libtool hacks - -{{ git_changelog }} diff --git a/thirdparty/libarchive/contrib/libarchive_autodetect-st_lib_archive.m4 b/thirdparty/libarchive/contrib/libarchive_autodetect-st_lib_archive.m4 deleted file mode 100644 index 4419e888f..000000000 --- a/thirdparty/libarchive/contrib/libarchive_autodetect-st_lib_archive.m4 +++ /dev/null @@ -1,154 +0,0 @@ -dnl -dnl @synopsis ST_LIB_ARCHIVE([ENABLED-DEFAULT]) -dnl -dnl This macro figures out what's necessary to link a program against an -dnl instance of the BSD libarchive package by Tim Kientzle. -dnl -dnl See http://people.freebsd.org/~kientzle/libarchive/ for more info. -dnl -dnl It exports and substitutes the variables LIBARCHIVE_LIBS, LIBARCHIVE_LDFLAGS, -dnl and LIBARCHIVE_CPPFLAGS to appropriate values for the identified instance of -dnl libarchive. The values are AC_SUBST'd, so a user could, for example, simply -dnl include @LIBARCHIVE_CPPFLAGS@ in the definition of AM_CPPFLAGS in a Makefile.am. -dnl -dnl ENABLED-DEFAULT is either "yes" or "no" and determines whether the default value -dnl is --with-libarchive or --without-libarchive. It is not possible to specify a -dnl default directory. More simply, any reasonable choice for a default should just -dnl go into the auto-detect list. -dnl -dnl The macro defines the symbol HAVE_LIBARCHIVE if the library is found. You -dnl should use autoheader to include a definition for this symbol in a config.h -dnl file. Sample usage in a C/C++ source is as follows: -dnl -dnl #ifdef HAVE_LIBARCHIVE -dnl #include -dnl #endif /* HAVE_LIBARCHIVE */ -dnl -dnl @category InstalledPackages -dnl @author Andre Stechert -dnl @version 2006-04-20 -dnl @license GPLWithACException - -AC_DEFUN([ST_LIB_ARCHIVE], -[ -# -# Handle input from the configurer and blend with the requirements from the maintainer. -# We go through the trouble of creating a second set of variables other than the with_foo -# variables in order to be sure that error/corner cases have been cleaned up. -# -# After this statement, three trusted variable are defined. -# -# st_lib_archive_ENABLED will be either "yes" or "no". its value determines whether -# or not we bother with the rest of the checks and whether or not we export a -# bunch of variables. -# -# st_lib_archive_LOCATION will be either "auto" or "defined". if it is "auto", then -# we try a bunch of standard locations. if it is "defined", then we just try the value -# provided in st_lib_archive_DIR. -# -# st_lib_archive_DIR will contain the string provided by the user, provided that it's -# actually a directory. -# -AC_MSG_CHECKING([if libarchive is wanted]) -AC_ARG_WITH([libarchive], - AS_HELP_STRING([--with-libarchive=DIR], [libarchive installation directory]), - [if test "x$with_libarchive" = "xno" ; then - st_lib_archive_ENABLED=no - elif test "x$with_libarchive" = "xyes" ; then - st_lib_archive_ENABLED=yes - st_lib_archive_LOCATION=auto - else - st_lib_archive_ENABLED=yes - st_lib_archive_LOCATION=defined - if test -d "$with_libarchive" ; then - st_lib_archive_DIR="$with_libarchive" - else - AC_MSG_ERROR([$with_libarchive is not a directory]) - fi - fi], - [if test "x$1" = "xno" ; then - st_lib_archive_ENABLED=no - elif test "x$1" = "xyes" ; then - st_lib_archive_ENABLED=yes - else - st_lib_archive_ENABLED=yes - fi]) - -if test "$st_lib_archive_ENABLED" = "yes" ; then - AC_MSG_RESULT([yes]) -# -# After this statement, one trusted variable is defined. -# -# st_lib_archive_LIB will be either "lib" or "lib64", depending on whether the configurer -# specified 32, 64. The default is "lib". -# - AC_MSG_CHECKING([whether to use lib or lib64]) - AC_ARG_WITH([libarchive-bits], - AS_HELP_STRING([--with-libarchive-bits=32/64], [if 64, look in /lib64 on hybrid systems]), - [if test "x$with_libarchive_bits" = "x32" ; then - st_lib_archive_LIB=lib - elif test "x$with_libarchive_bits" = "x64" ; then - st_lib_archive_LIB=lib64 - else - AC_MSG_ERROR([the argument must be either 32 or 64]) - fi], - [st_lib_archive_LIB=lib]) - AC_MSG_RESULT($st_lib_archive_LIB) -# -# Save the environment before verifying libarchive availability -# - st_lib_archive_SAVECPPFLAGS="$CPPFLAGS" - st_lib_archive_SAVELDFLAGS="$LDFLAGS" - AC_LANG_SAVE - AC_LANG_C - - if test "x$st_lib_archive_LOCATION" = "xdefined" ; then - CPPFLAGS="-I$st_lib_archive_DIR/include $st_lib_archive_SAVECPPFLAGS" - LDFLAGS="-L$st_lib_archive_DIR/$st_lib_archive_LIB $st_lib_archive_SAVELDFLAGS" - AC_CHECK_LIB(archive, archive_read_new, [st_lib_archive_found_lib=yes], [st_lib_archive_found_lib=no]) - AC_CHECK_HEADER(archive.h, [st_lib_archive_found_hdr=yes], [st_lib_archive_found_hdr=no]) - if test "x$st_lib_archive_found_lib" = "xyes" && test "x$st_lib_archive_found_hdr" = "xyes"; then - LIBARCHIVE_CPPFLAGS="-I$dir/include" - LIBARCHIVE_LDFLAGS="-L$dir/$st_lib_archive_LIB" - else - AC_MSG_ERROR([could not find libarchive in the requested location]) - fi - else - # - # These are the common install directories for Linux, FreeBSD, Solaris, and Mac. - # - for dir in /usr /usr/local /usr/sfw /opt/csw /opt/local /sw - do - if test -d "$dir" ; then - CPPFLAGS="-I$dir/include $st_lib_archive_SAVECPPFLAGS" - LDFLAGS="-L$dir/$st_lib_archive_LIB $st_lib_archive_SAVELDFLAGS" - AC_CHECK_LIB(archive, archive_read_new, [st_lib_archive_found_lib=yes], [st_lib_archive_found_lib=no]) - AC_CHECK_HEADER(archive.h, [st_lib_archive_found_hdr=yes], [st_lib_archive_found_hdr=no]) - if test "x$st_lib_archive_found_lib" = "xyes" && test "x$st_lib_archive_found_hdr" = "xyes"; then - LIBARCHIVE_CPPFLAGS="-I$dir/include" - LIBARCHIVE_LDFLAGS="-L$dir/$st_lib_archive_LIB" - break - fi - fi - done - fi - - if test "x$st_lib_archive_found_hdr" = "xyes" && test "x$st_lib_archive_found_lib" = "xyes" ; then - LIBARCHIVE_LIBS="-larchive" - AC_DEFINE([HAVE_LIBARCHIVE], [1], [Defined to 1 if libarchive is available for use.]) - AC_SUBST(LIBARCHIVE_LIBS) - AC_SUBST(LIBARCHIVE_CPPFLAGS) - AC_SUBST(LIBARCHIVE_LDFLAGS) - fi - -# -# Restore the environment now that we're done. -# - AC_LANG_RESTORE - CPPFLAGS="$st_lib_archive_SAVECPPFLAGS" - LDFLAGS="$st_lib_archive_SAVELDFLAGS" -else - AC_MSG_RESULT([no]) -fi -AM_CONDITIONAL(LIBARCHIVE, test "x$st_lib_archive_found_lib" = "xyes" && test "x$st_lib_archive_found_hdr" = "xyes") -]) diff --git a/thirdparty/libarchive/contrib/oss-fuzz/corpus.zip b/thirdparty/libarchive/contrib/oss-fuzz/corpus.zip deleted file mode 100644 index 4e9e24958..000000000 Binary files a/thirdparty/libarchive/contrib/oss-fuzz/corpus.zip and /dev/null differ diff --git a/thirdparty/libarchive/contrib/oss-fuzz/libarchive_fuzzer.cc b/thirdparty/libarchive/contrib/oss-fuzz/libarchive_fuzzer.cc deleted file mode 100644 index bc7f865b6..000000000 --- a/thirdparty/libarchive/contrib/oss-fuzz/libarchive_fuzzer.cc +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include -#include - -#include "archive.h" - -struct Buffer { - const uint8_t *buf; - size_t len; -}; - -ssize_t reader_callback(struct archive *a, void *client_data, - const void **block) { - Buffer *buffer = reinterpret_cast(client_data); - *block = buffer->buf; - ssize_t len = buffer->len; - buffer->len = 0; - return len; -} - -extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) { - int ret; - ssize_t r; - struct archive *a = archive_read_new(); - - archive_read_support_filter_all(a); - archive_read_support_format_all(a); - - Buffer buffer = {buf, len}; - archive_read_open(a, &buffer, NULL, reader_callback, NULL); - - std::vector data_buffer(getpagesize(), 0); - struct archive_entry *entry; - while(1) { - ret = archive_read_next_header(a, &entry); - if (ret == ARCHIVE_EOF || ret == ARCHIVE_FATAL) - break; - if (ret == ARCHIVE_RETRY) - continue; - while ((r = archive_read_data(a, data_buffer.data(), - data_buffer.size())) > 0) - ; - if (r == ARCHIVE_FATAL) - break; - } - - archive_read_free(a); - return 0; -} diff --git a/thirdparty/libarchive/contrib/oss-fuzz/oss-fuzz-build.sh b/thirdparty/libarchive/contrib/oss-fuzz/oss-fuzz-build.sh deleted file mode 100755 index 83d8470b1..000000000 --- a/thirdparty/libarchive/contrib/oss-fuzz/oss-fuzz-build.sh +++ /dev/null @@ -1,16 +0,0 @@ -# build the project -./build/autogen.sh -./configure -make -j$(nproc) all - -# build seed -cp $SRC/libarchive/contrib/oss-fuzz/corpus.zip\ - $OUT/libarchive_fuzzer_seed_corpus.zip - -# build fuzzer(s) -$CXX $CXXFLAGS -Ilibarchive \ - $SRC/libarchive/contrib/oss-fuzz/libarchive_fuzzer.cc \ - -o $OUT/libarchive_fuzzer $LIB_FUZZING_ENGINE \ - .libs/libarchive.a -Wl,-Bstatic -lbz2 -llzo2 \ - -lxml2 -llzma -lz -lcrypto -llz4 -licuuc \ - -licudata -Wl,-Bdynamic diff --git a/thirdparty/libarchive/contrib/psota-benchmark/results.txt b/thirdparty/libarchive/contrib/psota-benchmark/results.txt deleted file mode 100644 index 2d364c555..000000000 --- a/thirdparty/libarchive/contrib/psota-benchmark/results.txt +++ /dev/null @@ -1,136 +0,0 @@ -ODP: [Bug-tar] GNU tar, star and BSD tar speed comparison +new script - -Jan Psota -Thu, 25 Oct 2007 06:51:13 -0700 - -Latest TCP script at the bottom (3180 bytes). -4 tests: 64bit dual core Athlon tmpfs / disk (reiserfs) - 60MB/s, - 32bit Athlon tmpfs / disk (reiserfs) - 55MB/s -Both machines were idle -- used for testing only. -Tarball and extracted files were on different physical devices. -Test data: linux 2.6.22/3 kernel sources for memory operations, -for the other data average file size should bring enough info. - -2 x [...] processor means 1 processor with 2 cores (2 entries in cpuinfo). -Archive format is set to pax (Joerg). -Let's end with it. I only wanted to send You a new version of TCP script :-). - --- -Jan Psota - -TCP, version 2007-10-25 -Linux 2.6.22-suspend2-r2 / Gentoo Base System release 2.0.0_rc5 -2012MB of memory, 2 x AMD Athlon(tm) 64 X2 Dual Core Processor 4200+ 2211.348 -512 KB 4426.24 bmips -gcc (GCC) 4.2.2 (Gentoo 4.2.2 p1.0) -CFLAGS="-O2 -march=k8 -pipe" - -bsdtar: bsdtar 2.3.4 - libarchive 2.3.4 -gnutar: tar (GNU tar) 1.19 -star: star: star 1.5a85 (x86_64-unknown-linux-gnu) - -best time of 5 repetitions, - src=linux-2.6.23, 291M in 23867 files, avg 13KB/file, - archive=/tmp/tcp.tar, extract to /tmp/tcptmp -program operation real user system %CPU speed -bsdtar create 0.764 0.232 0.532 99.96 370308 KB/s -gnutar create 0.743 0.200 0.512 95.87 380775 KB/s -star create 0.587 0.040 0.820 100.00 441247 KB/s - -bsdtar list 0.164 0.096 0.068 99.84 1579341 KB/s -gnutar list 0.218 0.064 0.152 98.92 1188128 KB/s -star list 0.359 0.044 0.240 79.09 721481 KB/s - -bsdtar extract 0.733 0.200 0.504 96.02 353358 KB/s -gnutar extract 0.625 0.092 0.508 96.02 414419 KB/s -star extract 0.875 0.096 0.980 100.00 296013 KB/s - -bsdtar compare 0.001 0.000 0.000 0.00 259012000 KB/s -gnutar compare 0.719 0.288 0.400 95.66 360239 KB/s -star compare 0.695 0.224 0.636 100.00 372679 KB/s - -[...] -best time of 3 repetitions, - src=/home, 3.2G in 7447 files, avg 554KB/file, - archive=/var/tcp.tar, extract to /mnt/a/tcptmp -program operation real user system %CPU speed -bsdtar create 184.680 0.552 13.365 7.53 17958 KB/s -gnutar create 159.240 0.256 12.417 7.95 20827 KB/s -star create 181.779 0.140 14.789 8.21 18203 KB/s - -bsdtar list 0.053 0.032 0.016 91.41 62435471 KB/s -gnutar list 56.535 0.136 3.764 6.89 58531 KB/s -star list 56.652 0.080 5.236 9.38 58410 KB/s - -bsdtar extract 78.914 0.820 15.149 20.23 41932 KB/s -gnutar extract 78.480 0.196 14.197 18.33 42164 KB/s -star extract 79.439 0.132 12.973 16.49 41655 KB/s - -bsdtar compare 0.001 0.000 0.000 0.00 3309080000 KB/s -gnutar compare 61.771 3.464 8.905 20.02 53570 KB/s -star compare 57.561 1.728 9.897 20.19 57488 KB/s - - -Linux 2.6.22-suspend2-smp / Gentoo Base System release 2.0.0_rc5 -504MB of memory, 1 x AMD Athlon(tm) Processor 1500.033 256 KB 3002.55 bmips -gcc (GCC) 4.2.2 (Gentoo 4.2.2 p1.0) -CFLAGS="-O2 -march=athlon-xp -mfpmath=sse -frename-registers -pipe" - -bsdtar: bsdtar 2.3.4 - libarchive 2.3.4 -gnutar: tar (GNU tar) 1.19 -star: star: star 1.5a85 (i686-pc-linux-gnu) - -best time of 3 repetitions, - src=/usr/src/linux-2.6.22-suspend2/drivers, 119M in 5900 files, - avg 21KB/file, archive=/tmp/tcp.tar, extract to /tmp/tcptmp -program operation real user system %CPU speed -bsdtar create 1.329 0.192 1.132 99.63 89784 KB/s -gnutar create 1.223 0.124 1.092 99.46 97566 KB/s -star create 1.848 0.036 1.708 94.36 61372 KB/s - -bsdtar list 0.167 0.060 0.108 100.00 679137 KB/s -gnutar list 0.161 0.040 0.124 100.00 704447 KB/s -star list 0.859 0.044 0.716 88.51 132032 KB/s - -bsdtar extract 1.186 0.172 1.012 99.87 95629 KB/s -gnutar extract 1.064 0.056 1.004 99.63 106593 KB/s -star extract 1.920 0.088 1.724 94.40 59070 KB/s - -bsdtar compare 0.002 0.000 0.000 0.00 56708000 KB/s -gnutar compare 0.925 0.232 0.692 99.90 122611 KB/s -star compare 1.569 0.376 1.096 93.79 72285 KB/s - -[...] -best time of 3 repetitions, - src=/home/jasiu, 2.1G in 8416 files, avg 277KB/file, - archive=/home/j2/tcp.tar, extract to /mnt/a/tar/tcptmp -program operation real user system %CPU speed -bsdtar create 182.171 1.692 29.130 16.91 11584 KB/s -gnutar create 174.999 0.632 27.450 16.04 12059 KB/s -star create 180.004 0.360 41.795 23.41 11677 KB/s - -bsdtar list 0.214 0.076 0.136 99.04 9822294 KB/s -gnutar list 0.210 0.076 0.136 100.00 10009385 KB/s -star list 43.462 0.148 18.109 42.00 48363 KB/s - -bsdtar extract 94.912 4.476 31.574 37.98 22146 KB/s -gnutar extract 94.657 0.396 29.462 31.54 22206 KB/s -star extract 100.814 0.400 39.906 39.98 20849 KB/s - -bsdtar compare 0.003 0.000 0.004 100.00 700657000 KB/s -gnutar compare 80.174 3.932 20.365 30.30 26217 KB/s -star compare 73.911 8.341 27.670 48.72 28439 KB/s - -============================================================= - -Note by Tim Kientzle: The "bsdtar compare" results here are -invalid since bsdtar does not support that operation. -For the list numbers, note that libarchive automatically optimizes -list operations on uncompressed tar archives on disk by using lseek() -to skip over the bodies of entries. GNU tar added an option to -provide the same feature. - -The biggest problem with these tests is that they only -cover uncompressed archives stored on disk. The results for -compressed archives and/or archives stored on tape are -likely quite different. diff --git a/thirdparty/libarchive/contrib/psota-benchmark/tcp.sh b/thirdparty/libarchive/contrib/psota-benchmark/tcp.sh deleted file mode 100755 index 3f630732b..000000000 --- a/thirdparty/libarchive/contrib/psota-benchmark/tcp.sh +++ /dev/null @@ -1,110 +0,0 @@ -#!/bin/sh -# tar comparison program -# 2007-10-25 Jan Psota - -n=3 # number of repetitions -TAR="bsdtar gnutar star" # Tape archivers to compare -OPT=("" "--seek" "-no-fsync") -pax="--format=pax" # comment out for defaults -OPN=(create list extract compare) # operations -version="2007-10-25" -TIMEFORMAT=$'%R\t%U\t%S\t%P' -LC_ALL=C - -test $# -ge 2 || { - echo -e "usage:\t$0 source_dir where_to_place_archive -[where_to_extract_it] - -TCP, version $version -TCP stands for Tar Comparison Program here. -It currently compares: BSD tar (bsdtar), GNU tar (gnutar) and star in archive -creation, listing, extraction and archive-to-extracted comparison. -Tcp prints out best time of n=$n repetitions. - -Tcp creates temporary archive named tcp.tar with $pax and some native -(--seek/-no-fsync) options and extracts it to [\$3]/tcptmp/. -If unset, third argument defaults to [\$2]. -After normal exit tcp removes tarball and extracted files. -Tcp does not check filesystems destination directories are on for free space, -so make sure there is enough space (a bit more than source_dir uses) for both: -archive and extracted files. -Do not use white space in arguments. - Jan Psota, $version" - exit 0 -} -src=$1 -dst=$2/tcp.tar -dst_path=${3:-$2}/tcptmp -test -e $dst -o -e /tmp/tcp \ - && { echo "$dst or /tmp/tcp exists, exiting"; exit 1; } -mkdir $dst_path || exit 2 - -use_times () -{ - awk -F"\t" -vN=$n -vL="`du -k $dst`" -vOFS="\t" -vORS="" ' - { if (NF==4) { printf "\t%s\t%10.1d KB/s\n", $0, ($1+0>0 ? -(L+0)/($1+0) : 0) } }' \ - /tmp/tcp | sort | head -1 - > /tmp/tcp -} - -test -d $src || { echo "'$src' is not a directory"; exit 3; } - -# system information: type, release, memory, cpu(s), compiler and flags -echo -e "TCP, version $version\n"`uname -sr`" / "`head -1 /etc/*-release` -free -m | awk '/^Mem/ { printf "%dMB of memory, ", $2 }' -test -e /proc/cpuinfo \ - && awk -F: '/name|cache size|MHz|mips/ { if (!a) b=b $2 } - /^$/ { a++ } END { print a" x"b" bmips" }' /proc/cpuinfo -test -e /etc/gentoo-release \ - && gcc --version | head -1 && grep ^CFLAGS /etc/make.conf - -# tar versions -t= -echo -for tar in $TAR; do - if which $tar &> /dev/null; then - t="$t $tar"; - echo -ne "$tar:\t"; $tar --version | head -1; - fi -done - -TAR="$t" - -echo -e "\nbest time of $n repetitions,\n"\ -" src=$src, "\ -`du -sh $src | awk '{print $1}'`" in "`find $src | wc -l`" files, "\ -"avg "$((`du -sk $src | awk '{print $1}'`/`find $src -type f | wc -l`))"KB/file,\n"\ -" archive=$dst, extract to $dst_path" - -echo -e "program\toperation\treal\tuser\tsystem\t%CPU\t speed" -> /tmp/tcp -let op_num=0 -for op in "cf $dst $pax -C $src ." "tf $dst" "xf $dst -C $dst_path" \ - "f $dst -C $dst_path --diff"; do - let tar_num=0 - for tar in $TAR; do - echo -en "$tar\t${OPN[op_num]}\t" - for ((i=1; i<=$n; i++)); do - echo $op | grep -q ^cf && rm -f $dst - echo $op | grep -q ^xf && - { chmod -R u+w $dst_path - rm -rf $dst_path; mkdir $dst_path; } - sync - if echo $op | grep -q ^f; then # op == compare - time $tar $op ${OPT[$tar_num]} > /dev/null - else # op in (create | list | extract) - time $tar $op ${OPT[$tar_num]} > /dev/null \ - || break 3 - fi 2>> /tmp/tcp - done - use_times - let tar_num++ - done - let op_num++ - echo -done -rm -rf $dst_path $dst -echo -cat /tmp/tcp -rm -f /tmp/tcp diff --git a/thirdparty/libarchive/contrib/shar/shar.1 b/thirdparty/libarchive/contrib/shar/shar.1 deleted file mode 100644 index 31561978f..000000000 --- a/thirdparty/libarchive/contrib/shar/shar.1 +++ /dev/null @@ -1,131 +0,0 @@ -.\" Copyright (c) 1990, 1993 -.\" The Regents of the University of California. 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. -.\" 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. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. -.\" -.\" @(#)shar.1 8.1 (Berkeley) 6/6/93 -.\" $FreeBSD$ -.\" -.Dd April 17, 2008 -.Dt SHAR 1 -.Os -.Sh NAME -.Nm shar -.Nd create a shell archive of files -.Sh SYNOPSIS -.Nm -.Op Fl br -.Op Fl o Ar archive-file -.Ar -.Sh DESCRIPTION -The -.Nm -command writes a -.Xr sh 1 -shell script which will recreate the file hierarchy specified by the command -line operands. -.Pp -The -.Nm -command is normally used for distributing files by -.Xr ftp 1 -or -.Xr mail 1 . -.Pp -The following options are available: -.Bl -tag -width indent -.It Fl b -Use an alternative binary format. -Content of files will be uuencoded. -This option should be used to archive binary files correctly. -In this mode also file permissions will be stored to the archive. -uudecode(1) is needed to extract archives created with this option. -.It Fl o Ar archive-file -Redirect output to -.Ar archive-file . -.It Fl r -If -.Ar file -given on command line is a directory the entire subtree will be archived. -Symbolic links given on command line are followed. -Other symbolic links will be archived as such. -.El -.Sh EXAMPLES -To create a shell archive of the program -.Xr ls 1 -and mail it to Rick: -.Bd -literal -offset indent -cd ls -shar -r . \&| mail -s "ls source" rick -.Ed -.Pp -To recreate the program directory: -.Bd -literal -offset indent -mkdir ls -cd ls -\&... - -\&... -sh archive -.Ed -.Sh SEE ALSO -.Xr compress 1 , -.Xr mail 1 , -.Xr tar 1 , -.Xr uuencode 1 , -.Xr uuencode 5 -.Sh HISTORY -The -.Nm -command appeared in -.Bx 4.4 . -This is a re-implementation based on the libarchive(3) library. -.Sh BUGS -The -.Nm -command makes no provisions for hard links. -.Pp -Files containing magic characters or files without a newline ('\\n') as the -last character are not handled correctly with the default format. -Use the -.Fl b -option for binary files. -.Pp -It is easy to insert trojan horses into -.Nm -files. -It is strongly recommended that all shell archive files be examined -before running them through -.Xr sh 1 . -Archives produced using this implementation of -.Nm -may be easily examined with the command: -.Bd -literal -offset indent -egrep -v '^[X#]' shar.file -.Ed diff --git a/thirdparty/libarchive/contrib/shar/shar.c b/thirdparty/libarchive/contrib/shar/shar.c deleted file mode 100644 index 63161fc9e..000000000 --- a/thirdparty/libarchive/contrib/shar/shar.c +++ /dev/null @@ -1,314 +0,0 @@ -/*- - * Copyright (c) 2008 Jaakko Heinonen - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include -#ifdef __FBSDID -__FBSDID("$FreeBSD$"); -#endif - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "tree.h" - -/* command line options */ -static int b_opt; /* use alternative shar binary format */ -static int r_opt; /* recurse into subdirectories */ -static char *o_arg; /* output file name */ - -static void -usage(void) -{ - fprintf(stderr, "Usage: shar [-br] [-o filename] file ...\n"); - exit(EX_USAGE); -} - -/* - * Initialize archive structure and create a shar archive. - */ -static struct archive * -shar_create(void) -{ - struct archive *a; - - if ((a = archive_write_new()) == NULL) - errx(EXIT_FAILURE, "%s", archive_error_string(a)); - - if (b_opt) - archive_write_set_format_shar_dump(a); - else - archive_write_set_format_shar(a); - archive_write_set_compression_none(a); - - if (archive_write_open_filename(a, o_arg) != ARCHIVE_OK) - errx(EX_CANTCREAT, "%s", archive_error_string(a)); - - return (a); -} - -/* buffer for file data */ -static char buffer[32768]; - -/* - * Write file data to an archive entry. - */ -static int -shar_write_entry_data(struct archive *a, const int fd) -{ - ssize_t bytes_read, bytes_written; - - assert(a != NULL); - assert(fd >= 0); - - bytes_read = read(fd, buffer, sizeof(buffer)); - while (bytes_read != 0) { - if (bytes_read < 0) { - archive_set_error(a, errno, "Read failed"); - return (ARCHIVE_WARN); - } - bytes_written = archive_write_data(a, buffer, bytes_read); - if (bytes_written < 0) - return (ARCHIVE_WARN); - bytes_read = read(fd, buffer, sizeof(buffer)); - } - - return (ARCHIVE_OK); -} - -/* - * Write a file to the archive. We have special handling for symbolic links. - */ -static int -shar_write_entry(struct archive *a, const char *pathname, const char *accpath, - const struct stat *st) -{ - struct archive_entry *entry; - int fd = -1; - int ret = ARCHIVE_OK; - - assert(a != NULL); - assert(pathname != NULL); - assert(accpath != NULL); - assert(st != NULL); - - entry = archive_entry_new(); - - if (S_ISREG(st->st_mode) && st->st_size > 0) { - /* regular file */ - if ((fd = open(accpath, O_RDONLY)) == -1) { - warn("%s", accpath); - ret = ARCHIVE_WARN; - goto out; - } - } else if (S_ISLNK(st->st_mode)) { - /* symbolic link */ - char lnkbuff[PATH_MAX + 1]; - int lnklen; - if ((lnklen = readlink(accpath, lnkbuff, PATH_MAX)) == -1) { - warn("%s", accpath); - ret = ARCHIVE_WARN; - goto out; - } - lnkbuff[lnklen] = '\0'; - archive_entry_set_symlink(entry, lnkbuff); - } - archive_entry_copy_stat(entry, st); - archive_entry_set_pathname(entry, pathname); - if (!S_ISREG(st->st_mode) || st->st_size == 0) - archive_entry_set_size(entry, 0); - if (archive_write_header(a, entry) != ARCHIVE_OK) { - warnx("%s: %s", pathname, archive_error_string(a)); - ret = ARCHIVE_WARN; - goto out; - } - if (fd >= 0) { - if ((ret = shar_write_entry_data(a, fd)) != ARCHIVE_OK) - warnx("%s: %s", accpath, archive_error_string(a)); - } -out: - archive_entry_free(entry); - if (fd >= 0) - close(fd); - - return (ret); -} - -/* - * Write single path to the archive. The path can be a regular file, directory - * or device. Symbolic links are followed. - */ -static int -shar_write_path(struct archive *a, const char *pathname) -{ - struct stat st; - - assert(a != NULL); - assert(pathname != NULL); - - if ((stat(pathname, &st)) == -1) { - warn("%s", pathname); - return (ARCHIVE_WARN); - } - - return (shar_write_entry(a, pathname, pathname, &st)); -} - -/* - * Write tree to the archive. If pathname is a symbolic link it will be - * followed. Other symbolic links are stored as such to the archive. - */ -static int -shar_write_tree(struct archive *a, const char *pathname) -{ - struct tree *t; - const struct stat *lst, *st; - int error = 0; - int tree_ret; - int first; - - assert(a != NULL); - assert(pathname != NULL); - - t = tree_open(pathname); - for (first = 1; (tree_ret = tree_next(t)); first = 0) { - if (tree_ret == TREE_ERROR_DIR) { - warnx("%s: %s", tree_current_path(t), - strerror(tree_errno(t))); - error = 1; - continue; - } else if (tree_ret != TREE_REGULAR) - continue; - if ((lst = tree_current_lstat(t)) == NULL) { - warn("%s", tree_current_path(t)); - error = 1; - continue; - } - /* - * If the symlink was given on command line then - * follow it rather than write it as symlink. - */ - if (first && S_ISLNK(lst->st_mode)) { - if ((st = tree_current_stat(t)) == NULL) { - warn("%s", tree_current_path(t)); - error = 1; - continue; - } - } else - st = lst; - - if (shar_write_entry(a, tree_current_path(t), - tree_current_access_path(t), st) != ARCHIVE_OK) - error = 1; - - tree_descend(t); - } - - tree_close(t); - - return ((error != 0) ? ARCHIVE_WARN : ARCHIVE_OK); -} - -/* - * Create a shar archive and write files/trees into it. - */ -static int -shar_write(char **fn, size_t nfn) -{ - struct archive *a; - size_t i; - int error = 0; - - assert(fn != NULL); - assert(nfn > 0); - - a = shar_create(); - - for (i = 0; i < nfn; i++) { - if (r_opt) { - if (shar_write_tree(a, fn[i]) != ARCHIVE_OK) - error = 1; - } else { - if (shar_write_path(a, fn[i]) != ARCHIVE_OK) - error = 1; - } - } - - if (archive_write_free(a) != ARCHIVE_OK) - errx(EXIT_FAILURE, "%s", archive_error_string(a)); - - if (error != 0) - warnx("Error exit delayed from previous errors."); - - return (error); -} - -int -main(int argc, char **argv) -{ - int opt; - - while ((opt = getopt(argc, argv, "bro:")) != -1) { - switch (opt) { - case 'b': - b_opt = 1; - break; - case 'o': - o_arg = optarg; - break; - case 'r': - r_opt = 1; - break; - default: - usage(); - /* NOTREACHED */ - } - } - argc -= optind; - argv += optind; - - if(argc < 1) - usage(); - - if (shar_write(argv, argc) != 0) - exit(EXIT_FAILURE); - else - exit(EXIT_SUCCESS); - /* NOTREACHED */ -} - diff --git a/thirdparty/libarchive/contrib/shar/tree.c b/thirdparty/libarchive/contrib/shar/tree.c deleted file mode 100644 index a80d8366b..000000000 --- a/thirdparty/libarchive/contrib/shar/tree.c +++ /dev/null @@ -1,541 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -/*- - * This is a new directory-walking system that addresses a number - * of problems I've had with fts(3). In particular, it has no - * pathname-length limits (other than the size of 'int'), handles - * deep logical traversals, uses considerably less memory, and has - * an opaque interface (easier to modify in the future). - * - * Internally, it keeps a single list of "tree_entry" items that - * represent filesystem objects that require further attention. - * Non-directories are not kept in memory: they are pulled from - * readdir(), returned to the client, then freed as soon as possible. - * Any directory entry to be traversed gets pushed onto the stack. - * - * There is surprisingly little information that needs to be kept for - * each item on the stack. Just the name, depth (represented here as the - * string length of the parent directory's pathname), and some markers - * indicating how to get back to the parent (via chdir("..") for a - * regular dir or via fchdir(2) for a symlink). - */ -#include "tree_config.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_DIRENT_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif - -#include "tree.h" - -/* - * TODO: - * 1) Loop checking. - * 3) Arbitrary logical traversals by closing/reopening intermediate fds. - */ - -struct tree_entry { - struct tree_entry *next; - struct tree_entry *parent; - char *name; - size_t dirname_length; - dev_t dev; - ino_t ino; - int fd; - int flags; -}; - -/* Definitions for tree_entry.flags bitmap. */ -#define isDir 1 /* This entry is a regular directory. */ -#define isDirLink 2 /* This entry is a symbolic link to a directory. */ -#define needsPreVisit 4 /* This entry needs to be previsited. */ -#define needsPostVisit 8 /* This entry needs to be postvisited. */ - -/* - * Local data for this package. - */ -struct tree { - struct tree_entry *stack; - struct tree_entry *current; - DIR *d; - int initialDirFd; - int flags; - int visit_type; - int tree_errno; /* Error code from last failed operation. */ - - char *buff; - const char *basename; - size_t buff_length; - size_t path_length; - size_t dirname_length; - - int depth; - int openCount; - int maxOpenCount; - - struct stat lst; - struct stat st; -}; - -/* Definitions for tree.flags bitmap. */ -#define needsReturn 8 /* Marks first entry as not having been returned yet. */ -#define hasStat 16 /* The st entry is set. */ -#define hasLstat 32 /* The lst entry is set. */ - - -#ifdef HAVE_DIRENT_D_NAMLEN -/* BSD extension; avoids need for a strlen() call. */ -#define D_NAMELEN(dp) (dp)->d_namlen -#else -#define D_NAMELEN(dp) (strlen((dp)->d_name)) -#endif - -#if 0 -#include -void -tree_dump(struct tree *t, FILE *out) -{ - struct tree_entry *te; - - fprintf(out, "\tdepth: %d\n", t->depth); - fprintf(out, "\tbuff: %s\n", t->buff); - fprintf(out, "\tpwd: "); fflush(stdout); system("pwd"); - fprintf(out, "\taccess: %s\n", t->basename); - fprintf(out, "\tstack:\n"); - for (te = t->stack; te != NULL; te = te->next) { - fprintf(out, "\t\tte->name: %s%s%s\n", te->name, - te->flags & needsPreVisit ? "" : " *", - t->current == te ? " (current)" : ""); - } -} -#endif - -/* - * Add a directory path to the current stack. - */ -static void -tree_push(struct tree *t, const char *path) -{ - struct tree_entry *te; - - te = malloc(sizeof(*te)); - memset(te, 0, sizeof(*te)); - te->next = t->stack; - t->stack = te; - te->fd = -1; - te->name = strdup(path); - te->flags = needsPreVisit | needsPostVisit; - te->dirname_length = t->dirname_length; -} - -/* - * Append a name to the current path. - */ -static void -tree_append(struct tree *t, const char *name, size_t name_length) -{ - char *p; - - if (t->buff != NULL) - t->buff[t->dirname_length] = '\0'; - /* Strip trailing '/' from name, unless entire name is "/". */ - while (name_length > 1 && name[name_length - 1] == '/') - name_length--; - - /* Resize pathname buffer as needed. */ - while (name_length + 1 + t->dirname_length >= t->buff_length) { - t->buff_length *= 2; - if (t->buff_length < 1024) - t->buff_length = 1024; - t->buff = realloc(t->buff, t->buff_length); - } - p = t->buff + t->dirname_length; - t->path_length = t->dirname_length + name_length; - /* Add a separating '/' if it's needed. */ - if (t->dirname_length > 0 && p[-1] != '/') { - *p++ = '/'; - t->path_length ++; - } - strncpy(p, name, name_length); - p[name_length] = '\0'; - t->basename = p; -} - -/* - * Open a directory tree for traversal. - */ -struct tree * -tree_open(const char *path) -{ - struct tree *t; - - t = malloc(sizeof(*t)); - memset(t, 0, sizeof(*t)); - tree_append(t, path, strlen(path)); - t->initialDirFd = open(".", O_RDONLY); - /* - * During most of the traversal, items are set up and then - * returned immediately from tree_next(). That doesn't work - * for the very first entry, so we set a flag for this special - * case. - */ - t->flags = needsReturn; - return (t); -} - -/* - * We've finished a directory; ascend back to the parent. - */ -static void -tree_ascend(struct tree *t) -{ - struct tree_entry *te; - - te = t->stack; - t->depth--; - if (te->flags & isDirLink) { - fchdir(te->fd); - close(te->fd); - t->openCount--; - } else { - chdir(".."); - } -} - -/* - * Pop the working stack. - */ -static void -tree_pop(struct tree *t) -{ - struct tree_entry *te; - - t->buff[t->dirname_length] = '\0'; - if (t->stack == t->current && t->current != NULL) - t->current = t->current->parent; - te = t->stack; - t->stack = te->next; - t->dirname_length = te->dirname_length; - t->basename = t->buff + t->dirname_length; - /* Special case: starting dir doesn't skip leading '/'. */ - if (t->dirname_length > 0) - t->basename++; - free(te->name); - free(te); -} - -/* - * Get the next item in the tree traversal. - */ -int -tree_next(struct tree *t) -{ - struct dirent *de = NULL; - - /* Handle the startup case by returning the initial entry. */ - if (t->flags & needsReturn) { - t->flags &= ~needsReturn; - return (t->visit_type = TREE_REGULAR); - } - - while (t->stack != NULL) { - /* If there's an open dir, get the next entry from there. */ - while (t->d != NULL) { - de = readdir(t->d); - if (de == NULL) { - closedir(t->d); - t->d = NULL; - } else if (de->d_name[0] == '.' - && de->d_name[1] == '\0') { - /* Skip '.' */ - } else if (de->d_name[0] == '.' - && de->d_name[1] == '.' - && de->d_name[2] == '\0') { - /* Skip '..' */ - } else { - /* - * Append the path to the current path - * and return it. - */ - tree_append(t, de->d_name, D_NAMELEN(de)); - t->flags &= ~hasLstat; - t->flags &= ~hasStat; - return (t->visit_type = TREE_REGULAR); - } - } - - /* If the current dir needs to be visited, set it up. */ - if (t->stack->flags & needsPreVisit) { - t->current = t->stack; - tree_append(t, t->stack->name, strlen(t->stack->name)); - t->stack->flags &= ~needsPreVisit; - /* If it is a link, set up fd for the ascent. */ - if (t->stack->flags & isDirLink) { - t->stack->fd = open(".", O_RDONLY); - t->openCount++; - if (t->openCount > t->maxOpenCount) - t->maxOpenCount = t->openCount; - } - t->dirname_length = t->path_length; - if (chdir(t->stack->name) != 0) { - /* chdir() failed; return error */ - tree_pop(t); - t->tree_errno = errno; - return (t->visit_type = TREE_ERROR_DIR); - } - t->depth++; - t->d = opendir("."); - if (t->d == NULL) { - tree_ascend(t); /* Undo "chdir" */ - tree_pop(t); - t->tree_errno = errno; - return (t->visit_type = TREE_ERROR_DIR); - } - t->flags &= ~hasLstat; - t->flags &= ~hasStat; - t->basename = "."; - return (t->visit_type = TREE_POSTDESCENT); - } - - /* We've done everything necessary for the top stack entry. */ - if (t->stack->flags & needsPostVisit) { - tree_ascend(t); - tree_pop(t); - t->flags &= ~hasLstat; - t->flags &= ~hasStat; - return (t->visit_type = TREE_POSTASCENT); - } - } - return (t->visit_type = 0); -} - -/* - * Return error code. - */ -int -tree_errno(struct tree *t) -{ - return (t->tree_errno); -} - -/* - * Called by the client to mark the directory just returned from - * tree_next() as needing to be visited. - */ -void -tree_descend(struct tree *t) -{ - if (t->visit_type != TREE_REGULAR) - return; - - if (tree_current_is_physical_dir(t)) { - tree_push(t, t->basename); - t->stack->flags |= isDir; - } else if (tree_current_is_dir(t)) { - tree_push(t, t->basename); - t->stack->flags |= isDirLink; - } -} - -/* - * Get the stat() data for the entry just returned from tree_next(). - */ -const struct stat * -tree_current_stat(struct tree *t) -{ - if (!(t->flags & hasStat)) { - if (stat(t->basename, &t->st) != 0) - return NULL; - t->flags |= hasStat; - } - return (&t->st); -} - -/* - * Get the lstat() data for the entry just returned from tree_next(). - */ -const struct stat * -tree_current_lstat(struct tree *t) -{ - if (!(t->flags & hasLstat)) { - if (lstat(t->basename, &t->lst) != 0) - return NULL; - t->flags |= hasLstat; - } - return (&t->lst); -} - -/* - * Test whether current entry is a dir or link to a dir. - */ -int -tree_current_is_dir(struct tree *t) -{ - const struct stat *st; - - /* - * If we already have lstat() info, then try some - * cheap tests to determine if this is a dir. - */ - if (t->flags & hasLstat) { - /* If lstat() says it's a dir, it must be a dir. */ - if (S_ISDIR(tree_current_lstat(t)->st_mode)) - return 1; - /* Not a dir; might be a link to a dir. */ - /* If it's not a link, then it's not a link to a dir. */ - if (!S_ISLNK(tree_current_lstat(t)->st_mode)) - return 0; - /* - * It's a link, but we don't know what it's a link to, - * so we'll have to use stat(). - */ - } - - st = tree_current_stat(t); - /* If we can't stat it, it's not a dir. */ - if (st == NULL) - return 0; - /* Use the definitive test. Hopefully this is cached. */ - return (S_ISDIR(st->st_mode)); -} - -/* - * Test whether current entry is a physical directory. Usually, we - * already have at least one of stat() or lstat() in memory, so we - * use tricks to try to avoid an extra trip to the disk. - */ -int -tree_current_is_physical_dir(struct tree *t) -{ - const struct stat *st; - - /* - * If stat() says it isn't a dir, then it's not a dir. - * If stat() data is cached, this check is free, so do it first. - */ - if ((t->flags & hasStat) - && (!S_ISDIR(tree_current_stat(t)->st_mode))) - return 0; - - /* - * Either stat() said it was a dir (in which case, we have - * to determine whether it's really a link to a dir) or - * stat() info wasn't available. So we use lstat(), which - * hopefully is already cached. - */ - - st = tree_current_lstat(t); - /* If we can't stat it, it's not a dir. */ - if (st == NULL) - return 0; - /* Use the definitive test. Hopefully this is cached. */ - return (S_ISDIR(st->st_mode)); -} - -/* - * Test whether current entry is a symbolic link. - */ -int -tree_current_is_physical_link(struct tree *t) -{ - const struct stat *st = tree_current_lstat(t); - if (st == NULL) - return 0; - return (S_ISLNK(st->st_mode)); -} - -/* - * Return the access path for the entry just returned from tree_next(). - */ -const char * -tree_current_access_path(struct tree *t) -{ - return (t->basename); -} - -/* - * Return the full path for the entry just returned from tree_next(). - */ -const char * -tree_current_path(struct tree *t) -{ - return (t->buff); -} - -/* - * Return the length of the path for the entry just returned from tree_next(). - */ -size_t -tree_current_pathlen(struct tree *t) -{ - return (t->path_length); -} - -/* - * Return the nesting depth of the entry just returned from tree_next(). - */ -int -tree_current_depth(struct tree *t) -{ - return (t->depth); -} - -/* - * Terminate the traversal and release any resources. - */ -void -tree_close(struct tree *t) -{ - /* Release anything remaining in the stack. */ - while (t->stack != NULL) - tree_pop(t); - free(t->buff); - /* chdir() back to where we started. */ - if (t->initialDirFd >= 0) { - fchdir(t->initialDirFd); - close(t->initialDirFd); - t->initialDirFd = -1; - } - free(t); -} diff --git a/thirdparty/libarchive/contrib/shar/tree.h b/thirdparty/libarchive/contrib/shar/tree.h deleted file mode 100644 index ff38f5346..000000000 --- a/thirdparty/libarchive/contrib/shar/tree.h +++ /dev/null @@ -1,115 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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$ - */ - -/*- - * A set of routines for traversing directory trees. - * Similar in concept to the fts library, but with a few - * important differences: - * * Uses less memory. In particular, fts stores an entire directory - * in memory at a time. This package only keeps enough subdirectory - * information in memory to track the traversal. Information - * about non-directories is discarded as soon as possible. - * * Supports very deep logical traversals. The fts package - * uses "non-chdir" approach for logical traversals. This - * package does use a chdir approach for logical traversals - * and can therefore handle pathnames much longer than - * PATH_MAX. - * * Supports deep physical traversals "out of the box." - * Due to the memory optimizations above, there's no need to - * limit dir names to 32k. - */ - -#include -#include - -struct tree; - -/* Initiate/terminate a tree traversal. */ -struct tree *tree_open(const char * /* pathname */); -void tree_close(struct tree *); - -/* - * tree_next() returns Zero if there is no next entry, non-zero if there is. - * Note that directories are potentially visited three times. The first - * time as "regular" file. If tree_descend() is invoked at that time, - * the directory is added to a work list and will be visited two more - * times: once just after descending into the directory and again - * just after ascending back to the parent. - * - * TREE_ERROR is returned if the descent failed (because the - * directory couldn't be opened, for instance). This is returned - * instead of TREE_PREVISIT/TREE_POSTVISIT. - */ -#define TREE_REGULAR 1 -#define TREE_POSTDESCENT 2 -#define TREE_POSTASCENT 3 -#define TREE_ERROR_DIR -1 -int tree_next(struct tree *); - -int tree_errno(struct tree *); - -/* - * Request that current entry be visited. If you invoke it on every - * directory, you'll get a physical traversal. This is ignored if the - * current entry isn't a directory or a link to a directory. So, if - * you invoke this on every returned path, you'll get a full logical - * traversal. - */ -void tree_descend(struct tree *); - -/* - * Return information about the current entry. - */ - -int tree_current_depth(struct tree *); -/* - * The current full pathname, length of the full pathname, - * and a name that can be used to access the file. - * Because tree does use chdir extensively, the access path is - * almost never the same as the full current path. - */ -const char *tree_current_path(struct tree *); -size_t tree_current_pathlen(struct tree *); -const char *tree_current_access_path(struct tree *); -/* - * Request the lstat() or stat() data for the current path. Since the - * tree package needs to do some of this anyway, and caches the - * results, you should take advantage of it here if you need it rather - * than make a redundant stat() or lstat() call of your own. - */ -const struct stat *tree_current_stat(struct tree *); -const struct stat *tree_current_lstat(struct tree *); -/* The following tests may use mechanisms much faster than stat()/lstat(). */ -/* "is_physical_dir" is equivalent to S_ISDIR(tree_current_lstat()->st_mode) */ -int tree_current_is_physical_dir(struct tree *); -/* "is_physical_link" is equivalent to S_ISLNK(tree_current_lstat()->st_mode) */ -int tree_current_is_physical_link(struct tree *); -/* "is_dir" is equivalent to S_ISDIR(tree_current_stat()->st_mode) */ -int tree_current_is_dir(struct tree *); - -/* For testing/debugging: Dump the internal status to the given filehandle. */ -void tree_dump(struct tree *, FILE *); diff --git a/thirdparty/libarchive/contrib/shar/tree_config.h b/thirdparty/libarchive/contrib/shar/tree_config.h deleted file mode 100644 index 8dfd90baf..000000000 --- a/thirdparty/libarchive/contrib/shar/tree_config.h +++ /dev/null @@ -1,78 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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$ - */ -#ifndef TREE_CONFIG_H_INCLUDED -#define TREE_CONFIG_H_INCLUDED - -#if defined(PLATFORM_CONFIG_H) -/* - * Use hand-built config.h in environments that need it. - */ -#include PLATFORM_CONFIG_H -#elif defined(HAVE_CONFIG_H) -/* - * Most POSIX platforms use the 'configure' script to build config.h - */ -#include "../config.h" -#elif defined(__FreeBSD__) -/* - * Built-in definitions for FreeBSD. - */ -#define HAVE_DIRENT_D_NAMLEN 1 -#define HAVE_DIRENT_H 1 -#define HAVE_ERRNO_H 1 -#define HAVE_FCNTL_H 1 -#define HAVE_LIBARCHIVE 1 -#define HAVE_STDLIB_H 1 -#define HAVE_STRING_H 1 -#define HAVE_SYS_STAT_H 1 -#define HAVE_UNISTD_H 1 -#else -/* - * Warn if there's no platform configuration. - */ -#error Oops: No config.h and no built-in configuration in bsdtar_platform.h. -#endif /* !HAVE_CONFIG_H */ - -/* No non-FreeBSD platform will have __FBSDID, so just define it here. */ -#ifdef __FreeBSD__ -#include /* For __FBSDID */ -#else -/* Just leaving this macro replacement empty leads to a dangling semicolon. */ -#define __FBSDID(a) struct _undefined_hack -#endif - -#ifdef HAVE_LIBARCHIVE -/* If we're using the platform libarchive, include system headers. */ -#include -#include -#else -/* Otherwise, include user headers. */ -#include "archive.h" -#include "archive_entry.h" -#endif - -#endif /* !TREE_CONFIG_H_INCLUDED */ diff --git a/thirdparty/libarchive/contrib/untar.c b/thirdparty/libarchive/contrib/untar.c deleted file mode 100644 index db2511886..000000000 --- a/thirdparty/libarchive/contrib/untar.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * This file is in the public domain. Use it as you see fit. - */ - -/* - * "untar" is an extremely simple tar extractor: - * * A single C source file, so it should be easy to compile - * and run on any system with a C compiler. - * * Extremely portable standard C. The only non-ANSI function - * used is mkdir(). - * * Reads basic ustar tar archives. - * * Does not require libarchive or any other special library. - * - * To compile: cc -o untar untar.c - * - * Usage: untar - * - * In particular, this program should be sufficient to extract the - * distribution for libarchive, allowing people to bootstrap - * libarchive on systems that do not already have a tar program. - * - * To unpack libarchive-x.y.z.tar.gz: - * * gunzip libarchive-x.y.z.tar.gz - * * untar libarchive-x.y.z.tar - * - * Written by Tim Kientzle, March 2009. - * - * Released into the public domain. - */ - -/* These are all highly standard and portable headers. */ -#include -#include -#include - -/* This is for mkdir(); this may need to be changed for some platforms. */ -#include /* For mkdir() */ - -#if defined(_WIN32) && !defined(__CYGWIN__) -#define NUM_FORMAT "zu" -#include -#elif defined(__linux__) || defined(linux) || defined(__linux) -#define NUM_FORMAT "d" -#else -#define NUM_FORMAT "lu" -#endif /* defined(_WIN32) && !defined(__CYGWIN__) */ - -#define TO_STRING(x) #x -#define STR(x) TO_STRING(x) - -/* Parse an octal number, ignoring leading and trailing nonsense. */ -static int -parseoct(const char *p, size_t n) -{ - int i = 0; - - while ((*p < '0' || *p > '7') && n > 0) { - ++p; - --n; - } - while (*p >= '0' && *p <= '7' && n > 0) { - i *= 8; - i += *p - '0'; - ++p; - --n; - } - return (i); -} - -/* Returns true if this is 512 zero bytes. */ -static int -is_end_of_archive(const char *p) -{ - int n; - for (n = 511; n >= 0; --n) - if (p[n] != '\0') - return (0); - return (1); -} - -/* Create a directory, including parent directories as necessary. */ -static void -create_dir(char *pathname, int mode) -{ - char *p; - int r; - - /* Strip trailing '/' */ - if (pathname[strlen(pathname) - 1] == '/') - pathname[strlen(pathname) - 1] = '\0'; - - /* Try creating the directory. */ -#if defined(_WIN32) && !defined(__CYGWIN__) - r = _mkdir(pathname); -#else - r = mkdir(pathname, mode); -#endif - - if (r != 0) { - /* On failure, try creating parent directory. */ - p = strrchr(pathname, '/'); - if (p != NULL) { - *p = '\0'; - create_dir(pathname, 0755); - *p = '/'; -#if defined(_WIN32) && !defined(__CYGWIN__) - r = _mkdir(pathname); -#else - r = mkdir(pathname, mode); -#endif - } - } - if (r != 0) - fprintf(stderr, "Could not create directory %s\n", pathname); -} - -/* Create a file, including parent directory as necessary. */ -static FILE * -create_file(char *pathname, int mode) -{ - FILE *f; - f = fopen(pathname, "wb+"); - if (f == NULL) { - /* Try creating parent dir and then creating file. */ - char *p = strrchr(pathname, '/'); - if (p != NULL) { - *p = '\0'; - create_dir(pathname, 0755); - *p = '/'; - f = fopen(pathname, "wb+"); - } - } - return (f); -} - -/* Verify the tar checksum. */ -static int -verify_checksum(const char *p) -{ - int n, u = 0; - for (n = 0; n < 512; ++n) { - if (n < 148 || n > 155) - /* Standard tar checksum adds unsigned bytes. */ - u += ((unsigned char *)p)[n]; - else - u += 0x20; - - } - return (u == parseoct(p + 148, 8)); -} - -/* Extract a tar archive. */ -static void -untar(FILE *a, const char *path) -{ - enum { BUF_SIZE=512 }; - char buff[BUF_SIZE]; - FILE *f = NULL; - size_t bytes_read; - off_t filesize; - - printf("Extracting from %s\n", path); - for (;;) { - bytes_read = fread(buff, 1, BUF_SIZE, a); - if (bytes_read < BUF_SIZE) { - fprintf(stderr, - "Short read on %s: expected " STR(BUF_SIZE) ", got %"NUM_FORMAT"\n", - path, bytes_read); - return; - } - if (is_end_of_archive(buff)) { - printf("End of %s\n", path); - return; - } - if (!verify_checksum(buff)) { - fprintf(stderr, "Checksum failure\n"); - return; - } - filesize = parseoct(buff + 124, 12); - switch (buff[156]) { - case '1': - printf(" Ignoring hardlink %s\n", buff); - break; - case '2': - printf(" Ignoring symlink %s\n", buff); - break; - case '3': - printf(" Ignoring character device %s\n", buff); - break; - case '4': - printf(" Ignoring block device %s\n", buff); - break; - case '5': - printf(" Extracting dir %s\n", buff); - create_dir(buff, parseoct(buff + 100, 8)); - filesize = 0; - break; - case '6': - printf(" Ignoring FIFO %s\n", buff); - break; - default: - printf(" Extracting file %s\n", buff); - f = create_file(buff, parseoct(buff + 100, 8)); - break; - } - while (filesize > 0) { - bytes_read = fread(buff, 1, BUF_SIZE, a); - if (bytes_read < BUF_SIZE) { - fprintf(stderr, - "Short read on %s: Expected " STR(BUF_SIZE) ", got %"NUM_FORMAT"\n", - path, bytes_read); - return; - } - if (filesize < BUF_SIZE) - bytes_read = filesize; - if (f != NULL) { - if (fwrite(buff, 1, bytes_read, f) - != bytes_read) - { - fprintf(stderr, "Failed write\n"); - fclose(f); - f = NULL; - } - } - filesize -= (off_t)bytes_read; - } - if (f != NULL) { - fclose(f); - f = NULL; - } - } -} - -int -main(int argc, char **argv) -{ - FILE *a; - - ++argv; /* Skip program name */ - for ( ;*argv != NULL; ++argv) { - a = fopen(*argv, "rb"); - if (a == NULL) - fprintf(stderr, "Unable to open %s\n", *argv); - else { - untar(a, *argv); - fclose(a); - } - } - return (0); -} diff --git a/thirdparty/libarchive/cpio/CMakeLists.txt b/thirdparty/libarchive/cpio/CMakeLists.txt deleted file mode 100644 index 85fda7782..000000000 --- a/thirdparty/libarchive/cpio/CMakeLists.txt +++ /dev/null @@ -1,48 +0,0 @@ -############################################ -# -# How to build bsdcpio -# -############################################ -IF(ENABLE_CPIO) - - SET(bsdcpio_SOURCES - cmdline.c - cpio.c - cpio.h - cpio_platform.h - ../libarchive_fe/err.c - ../libarchive_fe/err.h - ../libarchive_fe/lafe_platform.h - ../libarchive_fe/line_reader.c - ../libarchive_fe/line_reader.h - ../libarchive_fe/passphrase.c - ../libarchive_fe/passphrase.h - ) - INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/test_utils) - INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libarchive_fe) - IF(WIN32 AND NOT CYGWIN) - LIST(APPEND bsdcpio_SOURCES cpio_windows.c) - LIST(APPEND bsdcpio_SOURCES cpio_windows.h) - ENDIF(WIN32 AND NOT CYGWIN) - - # bsdcpio documentation - SET(bsdcpio_MANS bsdcpio.1) - - # How to build bsdcpio - ADD_EXECUTABLE(bsdcpio ${bsdcpio_SOURCES}) - IF(ENABLE_CPIO_SHARED) - TARGET_LINK_LIBRARIES(bsdcpio archive ${ADDITIONAL_LIBS}) - ELSE(ENABLE_CPIO_SHARED) - TARGET_LINK_LIBRARIES(bsdcpio archive_static ${ADDITIONAL_LIBS}) - SET_TARGET_PROPERTIES(bsdcpio PROPERTIES COMPILE_DEFINITIONS - LIBARCHIVE_STATIC) - ENDIF(ENABLE_CPIO_SHARED) - - # Installation rules - INSTALL(TARGETS bsdcpio RUNTIME DESTINATION bin) - INSTALL_MAN(${bsdcpio_MANS}) - -ENDIF(ENABLE_CPIO) - -# Test suite -add_subdirectory(test) diff --git a/thirdparty/libarchive/cpio/bsdcpio.1 b/thirdparty/libarchive/cpio/bsdcpio.1 deleted file mode 100644 index 01b508e12..000000000 --- a/thirdparty/libarchive/cpio/bsdcpio.1 +++ /dev/null @@ -1,442 +0,0 @@ -.\" Copyright (c) 2003-2007 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd September 16, 2014 -.Dt CPIO 1 -.Os -.Sh NAME -.Nm cpio -.Nd copy files to and from archives -.Sh SYNOPSIS -.Nm -.Fl i -.Op Ar options -.Op Ar pattern ... -.Op Ar < archive -.Nm -.Fl o -.Op Ar options -.Ar < name-list -.Op Ar > archive -.Nm -.Fl p -.Op Ar options -.Ar dest-dir -.Ar < name-list -.Sh DESCRIPTION -.Nm -copies files between archives and directories. -This implementation can extract from tar, pax, cpio, zip, jar, ar, -and ISO 9660 cdrom images and can create tar, pax, cpio, ar, -and shar archives. -.Pp -The first option to -.Nm -is a mode indicator from the following list: -.Bl -tag -compact -width indent -.It Fl i -Input. -Read an archive from standard input (unless overridden) and extract the -contents to disk or (if the -.Fl t -option is specified) -list the contents to standard output. -If one or more file patterns are specified, only files matching -one of the patterns will be extracted. -.It Fl o -Output. -Read a list of filenames from standard input and produce a new archive -on standard output (unless overridden) containing the specified items. -.It Fl p -Pass-through. -Read a list of filenames from standard input and copy the files to the -specified directory. -.El -.Sh OPTIONS -Unless specifically stated otherwise, options are applicable in -all operating modes. -.Bl -tag -width indent -.It Fl 0 , Fl Fl null -Read filenames separated by NUL characters instead of newlines. -This is necessary if any of the filenames being read might contain newlines. -.It Fl 6 , Fl Fl pwb -When reading a binary format archive, assume it's the earlier one, -from the PWB variant of 6th Edition UNIX. -When writing a cpio archive, use the PWB format. -.It Fl 7 , Fl Fl binary -(o mode only) -When writing a cpio archive, use the (newer, non-PWB) binary format. -.It Fl A -(o mode only) -Append to the specified archive. -(Not yet implemented.) -.It Fl a -(o and p modes) -Reset access times on files after they are read. -.It Fl B -(o mode only) -Block output to records of 5120 bytes. -.It Fl C Ar size -(o mode only) -Block output to records of -.Ar size -bytes. -.It Fl c -(o mode only) -Use the old POSIX portable character format. -Equivalent to -.Fl Fl format Ar odc . -.It Fl d , Fl Fl make-directories -(i and p modes) -Create directories as necessary. -.It Fl E Ar file -(i mode only) -Read list of file name patterns from -.Ar file -to list and extract. -.It Fl F Ar file , Fl Fl file Ar file -Read archive from or write archive to -.Ar file . -.It Fl f Ar pattern -(i mode only) -Ignore files that match -.Ar pattern . -.It Fl H Ar format , Fl Fl format Ar format -(o mode only) -Produce the output archive in the specified format. -Supported formats include: -.Pp -.Bl -tag -width "iso9660" -compact -.It Ar cpio -Synonym for -.Ar odc . -.It Ar newc -The SVR4 portable cpio format. -.It Ar odc -The old POSIX.1 portable octet-oriented cpio format. -.It Ar pax -The POSIX.1 pax format, an extension of the ustar format. -.It Ar ustar -The POSIX.1 tar format. -.El -.Pp -The default format is -.Ar odc . -See -.Xr libarchive-formats 5 -for more complete information about the -formats currently supported by the underlying -.Xr libarchive 3 -library. -.It Fl h , Fl Fl help -Print usage information. -.It Fl I Ar file -Read archive from -.Ar file . -.It Fl i , Fl Fl extract -Input mode. -See above for description. -.It Fl Fl insecure -(i and p mode only) -Disable security checks during extraction or copying. -This allows extraction via symbolic links, absolute paths, -and path names containing -.Sq .. -in the name. -.It Fl J , Fl Fl xz -(o mode only) -Compress the file with xz-compatible compression before writing it. -In input mode, this option is ignored; xz compression is recognized -automatically on input. -.It Fl j -Synonym for -.Fl y . -.It Fl L -(o and p modes) -All symbolic links will be followed. -Normally, symbolic links are archived and copied as symbolic links. -With this option, the target of the link will be archived or copied instead. -.It Fl l , Fl Fl link -(p mode only) -Create links from the target directory to the original files, -instead of copying. -.It Fl Fl lrzip -(o mode only) -Compress the resulting archive with -.Xr lrzip 1 . -In input mode, this option is ignored. -.It Fl Fl lz4 -(o mode only) -Compress the archive with lz4-compatible compression before writing it. -In input mode, this option is ignored; lz4 compression is recognized -automatically on input. -.It Fl Fl zstd -(o mode only) -Compress the archive with zstd-compatible compression before writing it. -In input mode, this option is ignored; zstd compression is recognized -automatically on input. -.It Fl Fl lzma -(o mode only) -Compress the file with lzma-compatible compression before writing it. -In input mode, this option is ignored; lzma compression is recognized -automatically on input. -.It Fl Fl lzop -(o mode only) -Compress the resulting archive with -.Xr lzop 1 . -In input mode, this option is ignored. -.It Fl Fl passphrase Ar passphrase -The -.Pa passphrase -is used to extract or create an encrypted archive. -Currently, zip is only a format that -.Nm -can handle encrypted archives. -You shouldn't use this option unless you realize how insecure -use of this option is. -.It Fl m , Fl Fl preserve-modification-time -(i and p modes) -Set file modification time on created files to match -those in the source. -.It Fl n , Fl Fl numeric-uid-gid -(i mode, only with -.Fl t ) -Display numeric uid and gid. -By default, -.Nm -displays the user and group names when they are provided in the -archive, or looks up the user and group names in the system -password database. -.It Fl Fl no-preserve-owner -(i mode only) -Do not attempt to restore file ownership. -This is the default when run by non-root users. -.It Fl O Ar file -Write archive to -.Ar file . -.It Fl o , Fl Fl create -Output mode. -See above for description. -.It Fl p , Fl Fl pass-through -Pass-through mode. -See above for description. -.It Fl Fl preserve-owner -(i mode only) -Restore file ownership. -This is the default when run by the root user. -.It Fl Fl quiet -Suppress unnecessary messages. -.It Fl R Oo user Oc Ns Oo : Oc Ns Oo group Oc , Fl Fl owner Oo user Oc Ns Oo : Oc Ns Oo group Oc -Set the owner and/or group on files in the output. -If group is specified with no user -(for example, -.Fl R Ar :wheel ) -then the group will be set but not the user. -If the user is specified with a trailing colon and no group -(for example, -.Fl R Ar root: ) -then the group will be set to the user's default group. -If the user is specified with no trailing colon, then -the user will be set but not the group. -In -.Fl i -and -.Fl p -modes, this option can only be used by the super-user. -(For compatibility, a period can be used in place of the colon.) -.It Fl r -(All modes.) -Rename files interactively. -For each file, a prompt is written to -.Pa /dev/tty -containing the name of the file and a line is read from -.Pa /dev/tty . -If the line read is blank, the file is skipped. -If the line contains a single period, the file is processed normally. -Otherwise, the line is taken to be the new name of the file. -.It Fl t , Fl Fl list -(i mode only) -List the contents of the archive to stdout; -do not restore the contents to disk. -.It Fl u , Fl Fl unconditional -(i and p modes) -Unconditionally overwrite existing files. -Ordinarily, an older file will not overwrite a newer file on disk. -.It Fl V , Fl Fl dot -Print a dot to stderr for each file as it is processed. -Superseded by -.Fl v . -.It Fl v , Fl Fl verbose -Print the name of each file to stderr as it is processed. -With -.Fl t , -provide a detailed listing of each file. -.It Fl Fl version -Print the program version information and exit. -.It Fl y -(o mode only) -Compress the archive with bzip2-compatible compression before writing it. -In input mode, this option is ignored; -bzip2 compression is recognized automatically on input. -.It Fl Z -(o mode only) -Compress the archive with compress-compatible compression before writing it. -In input mode, this option is ignored; -compression is recognized automatically on input. -.It Fl z -(o mode only) -Compress the archive with gzip-compatible compression before writing it. -In input mode, this option is ignored; -gzip compression is recognized automatically on input. -.El -.Sh EXIT STATUS -.Ex -std -.Sh ENVIRONMENT -The following environment variables affect the execution of -.Nm : -.Bl -tag -width ".Ev BLOCKSIZE" -.It Ev LANG -The locale to use. -See -.Xr environ 7 -for more information. -.It Ev TZ -The timezone to use when displaying dates. -See -.Xr environ 7 -for more information. -.El -.Sh EXAMPLES -The -.Nm -command is traditionally used to copy file hierarchies in conjunction -with the -.Xr find 1 -command. -The first example here simply copies all files from -.Pa src -to -.Pa dest : -.Dl Nm find Pa src | Nm Fl pmud Pa dest -.Pp -By carefully selecting options to the -.Xr find 1 -command and combining it with other standard utilities, -it is possible to exercise very fine control over which files are copied. -This next example copies files from -.Pa src -to -.Pa dest -that are more than 2 days old and whose names match a particular pattern: -.Dl Nm find Pa src Fl mtime Ar +2 | Nm grep foo[bar] | Nm Fl pdmu Pa dest -.Pp -This example copies files from -.Pa src -to -.Pa dest -that are more than 2 days old and which contain the word -.Do foobar Dc : -.Dl Nm find Pa src Fl mtime Ar +2 | Nm xargs Nm grep -l foobar | Nm Fl pdmu Pa dest -.Sh COMPATIBILITY -The mode options i, o, and p and the options -a, B, c, d, f, l, m, r, t, u, and v comply with SUSv2. -.Pp -The old POSIX.1 standard specified that only -.Fl i , -.Fl o , -and -.Fl p -were interpreted as command-line options. -Each took a single argument of a list of modifier -characters. -For example, the standard syntax allows -.Fl imu -but does not support -.Fl miu -or -.Fl i Fl m Fl u , -since -.Ar m -and -.Ar u -are only modifiers to -.Fl i , -they are not command-line options in their own right. -The syntax supported by this implementation is backwards-compatible -with the standard. -For best compatibility, scripts should limit themselves to the -standard syntax. -.Sh SEE ALSO -.Xr bzip2 1 , -.Xr gzip 1 , -.Xr mt 1 , -.Xr pax 1 , -.Xr tar 1 , -.Xr libarchive 3 , -.Xr cpio 5 , -.Xr libarchive-formats 5 , -.Xr tar 5 -.Sh STANDARDS -There is no current POSIX standard for the cpio command; it appeared -in -.St -p1003.1-96 -but was dropped from -.St -p1003.1-2001 . -.Pp -The cpio, ustar, and pax interchange file formats are defined by -.St -p1003.1-2001 -for the pax command. -.Sh HISTORY -The original -.Nm cpio -and -.Nm find -utilities were written by Dick Haight -while working in AT&T's Unix Support Group. -They first appeared in 1977 in PWB/UNIX 1.0, the -.Dq Programmer's Work Bench -system developed for use within AT&T. -They were first released outside of AT&T as part of System III Unix in 1981. -As a result, -.Nm cpio -actually predates -.Nm tar , -even though it was not well-known outside of AT&T until some time later. -.Pp -This is a complete re-implementation based on the -.Xr libarchive 3 -library. -.Sh BUGS -The cpio archive format has several basic limitations: -It does not store user and group names, only numbers. -As a result, it cannot be reliably used to transfer -files between systems with dissimilar user and group numbering. -Older cpio formats limit the user and group numbers to -16 or 18 bits, which is insufficient for modern systems. -The cpio archive formats cannot support files over 4 gigabytes, -except for the -.Dq odc -variant, which can support files up to 8 gigabytes. diff --git a/thirdparty/libarchive/cpio/cmdline.c b/thirdparty/libarchive/cpio/cmdline.c deleted file mode 100644 index 2683524e4..000000000 --- a/thirdparty/libarchive/cpio/cmdline.c +++ /dev/null @@ -1,384 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - - -#include "cpio_platform.h" -__FBSDID("$FreeBSD: src/usr.bin/cpio/cmdline.c,v 1.5 2008/12/06 07:30:40 kientzle Exp $"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_GRP_H -#include -#endif -#ifdef HAVE_PWD_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "cpio.h" -#include "err.h" - -/* - * Short options for cpio. Please keep this sorted. - */ -static const char *short_options = "067AaBC:cdE:F:f:H:hI:iJjLlmnO:opR:rtuVvW:yZz"; - -/* - * Long options for cpio. Please keep this sorted. - */ -static const struct option { - const char *name; - int required; /* 1 if this option requires an argument */ - int equivalent; /* Equivalent short option. */ -} cpio_longopts[] = { - { "b64encode", 0, OPTION_B64ENCODE }, - { "binary", 0, '7' }, - { "create", 0, 'o' }, - { "dereference", 0, 'L' }, - { "dot", 0, 'V' }, - { "extract", 0, 'i' }, - { "file", 1, 'F' }, - { "format", 1, 'H' }, - { "grzip", 0, OPTION_GRZIP }, - { "help", 0, 'h' }, - { "insecure", 0, OPTION_INSECURE }, - { "link", 0, 'l' }, - { "list", 0, 't' }, - { "lrzip", 0, OPTION_LRZIP }, - { "lz4", 0, OPTION_LZ4 }, - { "lzma", 0, OPTION_LZMA }, - { "lzop", 0, OPTION_LZOP }, - { "make-directories", 0, 'd' }, - { "no-preserve-owner", 0, OPTION_NO_PRESERVE_OWNER }, - { "null", 0, '0' }, - { "numeric-uid-gid", 0, 'n' }, - { "owner", 1, 'R' }, - { "passphrase", 1, OPTION_PASSPHRASE }, - { "pass-through", 0, 'p' }, - { "preserve-modification-time", 0, 'm' }, - { "preserve-owner", 0, OPTION_PRESERVE_OWNER }, - { "pwb", 0, '6' }, - { "quiet", 0, OPTION_QUIET }, - { "unconditional", 0, 'u' }, - { "uuencode", 0, OPTION_UUENCODE }, - { "verbose", 0, 'v' }, - { "version", 0, OPTION_VERSION }, - { "xz", 0, 'J' }, - { "zstd", 0, OPTION_ZSTD }, - { NULL, 0, 0 } -}; - -/* - * I used to try to select platform-provided getopt() or - * getopt_long(), but that caused a lot of headaches. In particular, - * I couldn't consistently use long options in the test harness - * because not all platforms have getopt_long(). That in turn led to - * overuse of the -W hack in the test harness, which made it rough to - * run the test harness against GNU cpio. (I periodically run the - * test harness here against GNU cpio as a sanity-check. Yes, - * I've found a couple of bugs in GNU cpio that way.) - */ -int -cpio_getopt(struct cpio *cpio) -{ - enum { state_start = 0, state_next_word, state_short, state_long }; - static int state = state_start; - static char *opt_word; - - const struct option *popt, *match = NULL, *match2 = NULL; - const char *p, *long_prefix = "--"; - size_t optlength; - int opt = '?'; - int required = 0; - - cpio->argument = NULL; - - /* First time through, initialize everything. */ - if (state == state_start) { - /* Skip program name. */ - ++cpio->argv; - --cpio->argc; - state = state_next_word; - } - - /* - * We're ready to look at the next word in argv. - */ - if (state == state_next_word) { - /* No more arguments, so no more options. */ - if (cpio->argv[0] == NULL) - return (-1); - /* Doesn't start with '-', so no more options. */ - if (cpio->argv[0][0] != '-') - return (-1); - /* "--" marks end of options; consume it and return. */ - if (strcmp(cpio->argv[0], "--") == 0) { - ++cpio->argv; - --cpio->argc; - return (-1); - } - /* Get next word for parsing. */ - opt_word = *cpio->argv++; - --cpio->argc; - if (opt_word[1] == '-') { - /* Set up long option parser. */ - state = state_long; - opt_word += 2; /* Skip leading '--' */ - } else { - /* Set up short option parser. */ - state = state_short; - ++opt_word; /* Skip leading '-' */ - } - } - - /* - * We're parsing a group of POSIX-style single-character options. - */ - if (state == state_short) { - /* Peel next option off of a group of short options. */ - opt = *opt_word++; - if (opt == '\0') { - /* End of this group; recurse to get next option. */ - state = state_next_word; - return cpio_getopt(cpio); - } - - /* Does this option take an argument? */ - p = strchr(short_options, opt); - if (p == NULL) - return ('?'); - if (p[1] == ':') - required = 1; - - /* If it takes an argument, parse that. */ - if (required) { - /* If arg is run-in, opt_word already points to it. */ - if (opt_word[0] == '\0') { - /* Otherwise, pick up the next word. */ - opt_word = *cpio->argv; - if (opt_word == NULL) { - lafe_warnc(0, - "Option -%c requires an argument", - opt); - return ('?'); - } - ++cpio->argv; - --cpio->argc; - } - if (opt == 'W') { - state = state_long; - long_prefix = "-W "; /* For clearer errors. */ - } else { - state = state_next_word; - cpio->argument = opt_word; - } - } - } - - /* We're reading a long option, including -W long=arg convention. */ - if (state == state_long) { - /* After this long option, we'll be starting a new word. */ - state = state_next_word; - - /* Option name ends at '=' if there is one. */ - p = strchr(opt_word, '='); - if (p != NULL) { - optlength = (size_t)(p - opt_word); - cpio->argument = (char *)(uintptr_t)(p + 1); - } else { - optlength = strlen(opt_word); - } - - /* Search the table for an unambiguous match. */ - for (popt = cpio_longopts; popt->name != NULL; popt++) { - /* Short-circuit if first chars don't match. */ - if (popt->name[0] != opt_word[0]) - continue; - /* If option is a prefix of name in table, record it.*/ - if (strncmp(opt_word, popt->name, optlength) == 0) { - match2 = match; /* Record up to two matches. */ - match = popt; - /* If it's an exact match, we're done. */ - if (strlen(popt->name) == optlength) { - match2 = NULL; /* Forget the others. */ - break; - } - } - } - - /* Fail if there wasn't a unique match. */ - if (match == NULL) { - lafe_warnc(0, - "Option %s%s is not supported", - long_prefix, opt_word); - return ('?'); - } - if (match2 != NULL) { - lafe_warnc(0, - "Ambiguous option %s%s (matches --%s and --%s)", - long_prefix, opt_word, match->name, match2->name); - return ('?'); - } - - /* We've found a unique match; does it need an argument? */ - if (match->required) { - /* Argument required: get next word if necessary. */ - if (cpio->argument == NULL) { - cpio->argument = *cpio->argv; - if (cpio->argument == NULL) { - lafe_warnc(0, - "Option %s%s requires an argument", - long_prefix, match->name); - return ('?'); - } - ++cpio->argv; - --cpio->argc; - } - } else { - /* Argument forbidden: fail if there is one. */ - if (cpio->argument != NULL) { - lafe_warnc(0, - "Option %s%s does not allow an argument", - long_prefix, match->name); - return ('?'); - } - } - return (match->equivalent); - } - - return (opt); -} - - -/* - * Parse the argument to the -R or --owner flag. - * - * The format is one of the following: - * - Override user but not group - * : - Override both, group is user's default group - * : - Override user but not group - * : - Override both - * : - Override group but not user - * - * Where uid/gid are decimal representations and groupname/username - * are names to be looked up in system database. Note that we try - * to look up an argument as a name first, then try numeric parsing. - * - * A period can be used instead of the colon. - * - * Sets uid/gid return as appropriate, -1 indicates uid/gid not specified. - * TODO: If the spec uses uname/gname, then return those to the caller - * as well. If the spec provides uid/gid, just return names as NULL. - * - * Returns NULL if no error, otherwise returns error string for display. - * - */ -const char * -owner_parse(const char *spec, int *uid, int *gid) -{ - static char errbuff[128]; - const char *u, *ue, *g; - - *uid = -1; - *gid = -1; - - if (spec[0] == '\0') - return ("Invalid empty user/group spec"); - - /* - * Split spec into [user][:.][group] - * u -> first char of username, NULL if no username - * ue -> first char after username (colon, period, or \0) - * g -> first char of group name - */ - if (*spec == ':' || *spec == '.') { - /* If spec starts with ':' or '.', then just group. */ - ue = u = NULL; - g = spec + 1; - } else { - /* Otherwise, [user] or [user][:] or [user][:][group] */ - ue = u = spec; - while (*ue != ':' && *ue != '.' && *ue != '\0') - ++ue; - g = ue; - if (*g != '\0') /* Skip : or . to find first char of group. */ - ++g; - } - - if (u != NULL) { - /* Look up user: ue is first char after end of user. */ - char *user; - struct passwd *pwent; - - user = (char *)malloc(ue - u + 1); - if (user == NULL) - return ("Couldn't allocate memory"); - memcpy(user, u, ue - u); - user[ue - u] = '\0'; - if ((pwent = getpwnam(user)) != NULL) { - *uid = pwent->pw_uid; - if (*ue != '\0') - *gid = pwent->pw_gid; - } else { - char *end; - errno = 0; - *uid = (int)strtoul(user, &end, 10); - if (errno || *end != '\0') { - snprintf(errbuff, sizeof(errbuff), - "Couldn't lookup user ``%s''", user); - errbuff[sizeof(errbuff) - 1] = '\0'; - free(user); - return (errbuff); - } - } - free(user); - } - - if (*g != '\0') { - struct group *grp; - if ((grp = getgrnam(g)) != NULL) { - *gid = grp->gr_gid; - } else { - char *end; - errno = 0; - *gid = (int)strtoul(g, &end, 10); - if (errno || *end != '\0') { - snprintf(errbuff, sizeof(errbuff), - "Couldn't lookup group ``%s''", g); - errbuff[sizeof(errbuff) - 1] = '\0'; - return (errbuff); - } - } - } - return (NULL); -} diff --git a/thirdparty/libarchive/cpio/config_freebsd.h b/thirdparty/libarchive/cpio/config_freebsd.h deleted file mode 100644 index 00c4c737f..000000000 --- a/thirdparty/libarchive/cpio/config_freebsd.h +++ /dev/null @@ -1,56 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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/usr.bin/cpio/config_freebsd.h,v 1.3 2008/12/06 07:30:40 kientzle Exp $ - */ - -/* A hand-tooled configuration for FreeBSD. */ - -#include /* __FreeBSD_version */ - -#define HAVE_DIRENT_H 1 -#define HAVE_ERRNO_H 1 -#define HAVE_FCNTL_H 1 -#define HAVE_FUTIMES 1 -#define HAVE_GRP_H 1 -#define HAVE_LIBARCHIVE 1 -#define HAVE_LINK 1 -#define HAVE_LSTAT 1 -#define HAVE_LUTIMES 1 -#define HAVE_PWD_H 1 -#define HAVE_READLINK 1 -#define HAVE_STDARG_H 1 -#define HAVE_STDLIB_H 1 -#define HAVE_STRING_H 1 -#define HAVE_SYMLINK 1 -#define HAVE_SYS_CDEFS_H 1 -#define HAVE_SYS_STAT_H 1 -#define HAVE_SYS_TIME_H 1 -#define HAVE_TIME_H 1 -#define HAVE_UINTMAX_T 1 -#define HAVE_UNISTD_H 1 -#define HAVE_UNSIGNED_LONG_LONG 1 -#define HAVE_UTIME_H 1 -#define HAVE_UTIMES 1 - diff --git a/thirdparty/libarchive/cpio/cpio.c b/thirdparty/libarchive/cpio/cpio.c deleted file mode 100644 index b02a142f8..000000000 --- a/thirdparty/libarchive/cpio/cpio.c +++ /dev/null @@ -1,1513 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - - -#include "cpio_platform.h" -__FBSDID("$FreeBSD: src/usr.bin/cpio/cpio.c,v 1.15 2008/12/06 07:30:40 kientzle Exp $"); - -#include -#include -#include - -#ifdef HAVE_SYS_MKDEV_H -#include -#endif -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_SYS_TIME_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif -#ifdef HAVE_GRP_H -#include -#endif -#ifdef HAVE_LOCALE_H -#include -#endif -#ifdef HAVE_PWD_H -#include -#endif -#ifdef HAVE_SIGNAL_H -#include -#endif -#ifdef HAVE_STDARG_H -#include -#endif -#ifdef HAVE_STDINT_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_TIME_H -#include -#endif - -#include "cpio.h" -#include "err.h" -#include "line_reader.h" -#include "passphrase.h" - -/* Fixed size of uname/gname caches. */ -#define name_cache_size 101 - -#ifndef O_BINARY -#define O_BINARY 0 -#endif - -struct name_cache { - int probes; - int hits; - size_t size; - struct { - id_t id; - char *name; - } cache[name_cache_size]; -}; - -static int extract_data(struct archive *, struct archive *); -const char * cpio_i64toa(int64_t); -static const char *cpio_rename(const char *name); -static int entry_to_archive(struct cpio *, struct archive_entry *); -static int file_to_archive(struct cpio *, const char *); -static void free_cache(struct name_cache *cache); -static void list_item_verbose(struct cpio *, struct archive_entry *); -static void long_help(void) __LA_DEAD; -static const char *lookup_gname(struct cpio *, gid_t gid); -static int lookup_gname_helper(struct cpio *, - const char **name, id_t gid); -static const char *lookup_uname(struct cpio *, uid_t uid); -static int lookup_uname_helper(struct cpio *, - const char **name, id_t uid); -static void mode_in(struct cpio *) __LA_DEAD; -static void mode_list(struct cpio *) __LA_DEAD; -static void mode_out(struct cpio *); -static void mode_pass(struct cpio *, const char *); -static const char *remove_leading_slash(const char *); -static int restore_time(struct cpio *, struct archive_entry *, - const char *, int fd); -static void usage(void) __LA_DEAD; -static void version(void) __LA_DEAD; -static const char * passphrase_callback(struct archive *, void *); -static void passphrase_free(char *); - -int -main(int argc, char *argv[]) -{ - static char buff[16384]; - struct cpio _cpio; /* Allocated on stack. */ - struct cpio *cpio; - const char *errmsg; - char *tptr; - int uid, gid; - int opt, t; - - cpio = &_cpio; - memset(cpio, 0, sizeof(*cpio)); - cpio->buff = buff; - cpio->buff_size = sizeof(buff); - -#if defined(HAVE_SIGACTION) && defined(SIGPIPE) - { /* Ignore SIGPIPE signals. */ - struct sigaction sa; - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sa.sa_handler = SIG_IGN; - sigaction(SIGPIPE, &sa, NULL); - } -#endif - - /* Set lafe_progname before calling lafe_warnc. */ - lafe_setprogname(*argv, "bsdcpio"); - -#if HAVE_SETLOCALE - if (setlocale(LC_ALL, "") == NULL) - lafe_warnc(0, "Failed to set default locale"); -#endif - - cpio->uid_override = -1; - cpio->gid_override = -1; - cpio->argv = argv; - cpio->argc = argc; - cpio->mode = '\0'; - cpio->verbose = 0; - cpio->compress = '\0'; - cpio->extract_flags = ARCHIVE_EXTRACT_NO_AUTODIR; - cpio->extract_flags |= ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER; - cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_SYMLINKS; - cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_NODOTDOT; - cpio->extract_flags |= ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS; - cpio->extract_flags |= ARCHIVE_EXTRACT_PERM; - cpio->extract_flags |= ARCHIVE_EXTRACT_FFLAGS; - cpio->extract_flags |= ARCHIVE_EXTRACT_ACL; -#if !defined(_WIN32) && !defined(__CYGWIN__) - if (geteuid() == 0) - cpio->extract_flags |= ARCHIVE_EXTRACT_OWNER; -#endif - cpio->bytes_per_block = 512; - cpio->filename = NULL; - - cpio->matching = archive_match_new(); - if (cpio->matching == NULL) - lafe_errc(1, 0, "Out of memory"); - - while ((opt = cpio_getopt(cpio)) != -1) { - switch (opt) { - case '0': /* GNU convention: --null, -0 */ - cpio->option_null = 1; - break; - case '6': /* in/out: assume/create 6th edition (PWB) format */ - cpio->option_pwb = 1; - break; - case '7': /* out: create archive using 7th Edition binary format */ - cpio->format = "bin"; - break; - case 'A': /* NetBSD/OpenBSD */ - cpio->option_append = 1; - break; - case 'a': /* POSIX 1997 */ - cpio->option_atime_restore = 1; - break; - case 'B': /* POSIX 1997 */ - cpio->bytes_per_block = 5120; - break; - case OPTION_B64ENCODE: - cpio->add_filter = opt; - break; - case 'C': /* NetBSD/OpenBSD */ - errno = 0; - tptr = NULL; - t = (int)strtol(cpio->argument, &tptr, 10); - if (errno || t <= 0 || *(cpio->argument) == '\0' || - tptr == NULL || *tptr != '\0') { - lafe_errc(1, 0, "Invalid blocksize: %s", - cpio->argument); - } - cpio->bytes_per_block = t; - break; - case 'c': /* POSIX 1997 */ - cpio->format = "odc"; - break; - case 'd': /* POSIX 1997 */ - cpio->extract_flags &= ~ARCHIVE_EXTRACT_NO_AUTODIR; - break; - case 'E': /* NetBSD/OpenBSD */ - if (archive_match_include_pattern_from_file( - cpio->matching, cpio->argument, - cpio->option_null) != ARCHIVE_OK) - lafe_errc(1, 0, "Error : %s", - archive_error_string(cpio->matching)); - break; - case 'F': /* NetBSD/OpenBSD/GNU cpio */ - cpio->filename = cpio->argument; - break; - case 'f': /* POSIX 1997 */ - if (archive_match_exclude_pattern(cpio->matching, - cpio->argument) != ARCHIVE_OK) - lafe_errc(1, 0, "Error : %s", - archive_error_string(cpio->matching)); - break; - case OPTION_GRZIP: - cpio->compress = opt; - break; - case 'H': /* GNU cpio (also --format) */ - cpio->format = cpio->argument; - break; - case 'h': - long_help(); - break; - case 'I': /* NetBSD/OpenBSD */ - cpio->filename = cpio->argument; - break; - case 'i': /* POSIX 1997 */ - if (cpio->mode != '\0') - lafe_errc(1, 0, - "Cannot use both -i and -%c", cpio->mode); - cpio->mode = opt; - break; - case 'J': /* GNU tar, others */ - cpio->compress = opt; - break; - case 'j': /* GNU tar, others */ - cpio->compress = opt; - break; - case OPTION_INSECURE: - cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_SYMLINKS; - cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NODOTDOT; - cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS; - break; - case 'L': /* GNU cpio */ - cpio->option_follow_links = 1; - break; - case 'l': /* POSIX 1997 */ - cpio->option_link = 1; - break; - case OPTION_LRZIP: - case OPTION_LZ4: - case OPTION_LZMA: /* GNU tar, others */ - case OPTION_LZOP: /* GNU tar, others */ - case OPTION_ZSTD: - cpio->compress = opt; - break; - case 'm': /* POSIX 1997 */ - cpio->extract_flags |= ARCHIVE_EXTRACT_TIME; - break; - case 'n': /* GNU cpio */ - cpio->option_numeric_uid_gid = 1; - break; - case OPTION_NO_PRESERVE_OWNER: /* GNU cpio */ - cpio->extract_flags &= ~ARCHIVE_EXTRACT_OWNER; - break; - case 'O': /* GNU cpio */ - cpio->filename = cpio->argument; - break; - case 'o': /* POSIX 1997 */ - if (cpio->mode != '\0') - lafe_errc(1, 0, - "Cannot use both -o and -%c", cpio->mode); - cpio->mode = opt; - break; - case 'p': /* POSIX 1997 */ - if (cpio->mode != '\0') - lafe_errc(1, 0, - "Cannot use both -p and -%c", cpio->mode); - cpio->mode = opt; - cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NODOTDOT; - cpio->extract_flags &= ~ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS; - break; - case OPTION_PASSPHRASE: - cpio->passphrase = cpio->argument; - break; - case OPTION_PRESERVE_OWNER: - cpio->extract_flags |= ARCHIVE_EXTRACT_OWNER; - break; - case OPTION_QUIET: /* GNU cpio */ - cpio->quiet = 1; - break; - case 'R': /* GNU cpio, also --owner */ - /* TODO: owner_parse should return uname/gname - * also; use that to set [ug]name_override. */ - errmsg = owner_parse(cpio->argument, &uid, &gid); - if (errmsg) { - lafe_warnc(-1, "%s", errmsg); - usage(); - } - if (uid != -1) { - cpio->uid_override = uid; - cpio->uname_override = NULL; - } - if (gid != -1) { - cpio->gid_override = gid; - cpio->gname_override = NULL; - } - break; - case 'r': /* POSIX 1997 */ - cpio->option_rename = 1; - break; - case 't': /* POSIX 1997 */ - cpio->option_list = 1; - break; - case 'u': /* POSIX 1997 */ - cpio->extract_flags - &= ~ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER; - break; - case OPTION_UUENCODE: - cpio->add_filter = opt; - break; - case 'v': /* POSIX 1997 */ - cpio->verbose++; - break; - case 'V': /* GNU cpio */ - cpio->dot++; - break; - case OPTION_VERSION: /* GNU convention */ - version(); - break; -#if 0 - /* - * cpio_getopt() handles -W specially, so it's not - * available here. - */ - case 'W': /* Obscure, but useful GNU convention. */ - break; -#endif - case 'y': /* tar convention */ - cpio->compress = opt; - break; - case 'Z': /* tar convention */ - cpio->compress = opt; - break; - case 'z': /* tar convention */ - cpio->compress = opt; - break; - default: - usage(); - } - } - - /* - * Sanity-check args, error out on nonsensical combinations. - */ - /* -t implies -i if no mode was specified. */ - if (cpio->option_list && cpio->mode == '\0') - cpio->mode = 'i'; - /* -t requires -i */ - if (cpio->option_list && cpio->mode != 'i') - lafe_errc(1, 0, "Option -t requires -i"); - /* -n requires -it */ - if (cpio->option_numeric_uid_gid && !cpio->option_list) - lafe_errc(1, 0, "Option -n requires -it"); - /* Can only specify format when writing */ - if (cpio->format != NULL && cpio->mode != 'o') - lafe_errc(1, 0, "Option --format requires -o"); - /* -l requires -p */ - if (cpio->option_link && cpio->mode != 'p') - lafe_errc(1, 0, "Option -l requires -p"); - /* -v overrides -V */ - if (cpio->dot && cpio->verbose) - cpio->dot = 0; - /* TODO: Flag other nonsensical combinations. */ - - switch (cpio->mode) { - case 'o': - if (cpio->format == NULL) { - if (cpio->option_pwb) - cpio->format = "pwb"; - else - cpio->format = "cpio"; - } - mode_out(cpio); - break; - case 'i': - while (*cpio->argv != NULL) { - if (archive_match_include_pattern(cpio->matching, - *cpio->argv) != ARCHIVE_OK) - lafe_errc(1, 0, "Error : %s", - archive_error_string(cpio->matching)); - --cpio->argc; - ++cpio->argv; - } - if (cpio->option_list) - mode_list(cpio); - else - mode_in(cpio); - break; - case 'p': - if (*cpio->argv == NULL || **cpio->argv == '\0') - lafe_errc(1, 0, - "-p mode requires a target directory"); - mode_pass(cpio, *cpio->argv); - break; - default: - lafe_errc(1, 0, - "Must specify at least one of -i, -o, or -p"); - } - - archive_match_free(cpio->matching); - free_cache(cpio->gname_cache); - free_cache(cpio->uname_cache); - archive_read_close(cpio->archive_read_disk); - archive_read_free(cpio->archive_read_disk); - free(cpio->destdir); - passphrase_free(cpio->ppbuff); - return (cpio->return_value); -} - -static void -usage(void) -{ - const char *p; - - p = lafe_getprogname(); - - fprintf(stderr, "Brief Usage:\n"); - fprintf(stderr, " List: %s -it < archive\n", p); - fprintf(stderr, " Extract: %s -i < archive\n", p); - fprintf(stderr, " Create: %s -o < filenames > archive\n", p); - fprintf(stderr, " Help: %s --help\n", p); - exit(1); -} - -static const char *long_help_msg = - "First option must be a mode specifier:\n" - " -i Input -o Output -p Pass\n" - "Common Options:\n" - " -v Verbose filenames -V one dot per file\n" - "Create: %p -o [options] < [list of files] > [archive]\n" - " -J,-y,-z,--lzma Compress archive with xz/bzip2/gzip/lzma\n" - " --format {pwb|bin|odc|newc|ustar} Select archive format\n" - "List: %p -it < [archive]\n" - "Extract: %p -i [options] < [archive]\n"; - - -/* - * Note that the word 'bsdcpio' will always appear in the first line - * of output. - * - * In particular, /bin/sh scripts that need to test for the presence - * of bsdcpio can use the following template: - * - * if (cpio --help 2>&1 | grep bsdcpio >/dev/null 2>&1 ) then \ - * echo bsdcpio; else echo not bsdcpio; fi - */ -static void -long_help(void) -{ - const char *prog; - const char *p; - - prog = lafe_getprogname(); - - fflush(stderr); - - p = (strcmp(prog,"bsdcpio") != 0) ? "(bsdcpio)" : ""; - printf("%s%s: manipulate archive files\n", prog, p); - - for (p = long_help_msg; *p != '\0'; p++) { - if (*p == '%') { - if (p[1] == 'p') { - fputs(prog, stdout); - p++; - } else - putchar('%'); - } else - putchar(*p); - } - version(); -} - -static void -version(void) -{ - fprintf(stdout,"bsdcpio %s - %s \n", - BSDCPIO_VERSION_STRING, - archive_version_details()); - exit(0); -} - -static void -mode_out(struct cpio *cpio) -{ - struct archive_entry *entry, *spare; - struct lafe_line_reader *lr; - const char *p; - int r; - - if (cpio->option_append) - lafe_errc(1, 0, "Append mode not yet supported."); - - cpio->archive_read_disk = archive_read_disk_new(); - if (cpio->archive_read_disk == NULL) - lafe_errc(1, 0, "Failed to allocate archive object"); - if (cpio->option_follow_links) - archive_read_disk_set_symlink_logical(cpio->archive_read_disk); - else - archive_read_disk_set_symlink_physical(cpio->archive_read_disk); - archive_read_disk_set_standard_lookup(cpio->archive_read_disk); - - cpio->archive = archive_write_new(); - if (cpio->archive == NULL) - lafe_errc(1, 0, "Failed to allocate archive object"); - switch (cpio->compress) { - case OPTION_GRZIP: - r = archive_write_add_filter_grzip(cpio->archive); - break; - case 'J': - r = archive_write_add_filter_xz(cpio->archive); - break; - case OPTION_LRZIP: - r = archive_write_add_filter_lrzip(cpio->archive); - break; - case OPTION_LZ4: - r = archive_write_add_filter_lz4(cpio->archive); - break; - case OPTION_LZMA: - r = archive_write_add_filter_lzma(cpio->archive); - break; - case OPTION_LZOP: - r = archive_write_add_filter_lzop(cpio->archive); - break; - case OPTION_ZSTD: - r = archive_write_add_filter_zstd(cpio->archive); - break; - case 'j': case 'y': - r = archive_write_add_filter_bzip2(cpio->archive); - break; - case 'z': - r = archive_write_add_filter_gzip(cpio->archive); - break; - case 'Z': - r = archive_write_add_filter_compress(cpio->archive); - break; - default: - r = archive_write_add_filter_none(cpio->archive); - break; - } - if (r < ARCHIVE_WARN) - lafe_errc(1, 0, "Requested compression not available"); - switch (cpio->add_filter) { - case 0: - r = ARCHIVE_OK; - break; - case OPTION_B64ENCODE: - r = archive_write_add_filter_b64encode(cpio->archive); - break; - case OPTION_UUENCODE: - r = archive_write_add_filter_uuencode(cpio->archive); - break; - } - if (r < ARCHIVE_WARN) - lafe_errc(1, 0, "Requested filter not available"); - r = archive_write_set_format_by_name(cpio->archive, cpio->format); - if (r != ARCHIVE_OK) - lafe_errc(1, 0, "%s", archive_error_string(cpio->archive)); - archive_write_set_bytes_per_block(cpio->archive, cpio->bytes_per_block); - cpio->linkresolver = archive_entry_linkresolver_new(); - archive_entry_linkresolver_set_strategy(cpio->linkresolver, - archive_format(cpio->archive)); - if (cpio->passphrase != NULL) - r = archive_write_set_passphrase(cpio->archive, - cpio->passphrase); - else - r = archive_write_set_passphrase_callback(cpio->archive, cpio, - &passphrase_callback); - if (r != ARCHIVE_OK) - lafe_errc(1, 0, "%s", archive_error_string(cpio->archive)); - - /* - * The main loop: Copy each file into the output archive. - */ - r = archive_write_open_filename(cpio->archive, cpio->filename); - if (r != ARCHIVE_OK) - lafe_errc(1, 0, "%s", archive_error_string(cpio->archive)); - lr = lafe_line_reader("-", cpio->option_null); - while ((p = lafe_line_reader_next(lr)) != NULL) - file_to_archive(cpio, p); - lafe_line_reader_free(lr); - - /* - * The hardlink detection may have queued up a couple of entries - * that can now be flushed. - */ - entry = NULL; - archive_entry_linkify(cpio->linkresolver, &entry, &spare); - while (entry != NULL) { - entry_to_archive(cpio, entry); - archive_entry_free(entry); - entry = NULL; - archive_entry_linkify(cpio->linkresolver, &entry, &spare); - } - - r = archive_write_close(cpio->archive); - if (cpio->dot) - fprintf(stderr, "\n"); - if (r != ARCHIVE_OK) - lafe_errc(1, 0, "%s", archive_error_string(cpio->archive)); - - if (!cpio->quiet) { - int64_t blocks = - (archive_filter_bytes(cpio->archive, 0) + 511) - / 512; - fprintf(stderr, "%lu %s\n", (unsigned long)blocks, - blocks == 1 ? "block" : "blocks"); - } - archive_write_free(cpio->archive); - archive_entry_linkresolver_free(cpio->linkresolver); -} - -static const char * -remove_leading_slash(const char *p) -{ - const char *rp; - - /* Remove leading "//./" or "//?/" or "//?/UNC/" - * (absolute path prefixes used by Windows API) */ - if ((p[0] == '/' || p[0] == '\\') && - (p[1] == '/' || p[1] == '\\') && - (p[2] == '.' || p[2] == '?') && - (p[3] == '/' || p[3] == '\\')) - { - if (p[2] == '?' && - (p[4] == 'U' || p[4] == 'u') && - (p[5] == 'N' || p[5] == 'n') && - (p[6] == 'C' || p[6] == 'c') && - (p[7] == '/' || p[7] == '\\')) - p += 8; - else - p += 4; - } - do { - rp = p; - /* Remove leading drive letter from archives created - * on Windows. */ - if (((p[0] >= 'a' && p[0] <= 'z') || - (p[0] >= 'A' && p[0] <= 'Z')) && - p[1] == ':') { - p += 2; - } - /* Remove leading "/../", "//", etc. */ - while (p[0] == '/' || p[0] == '\\') { - if (p[1] == '.' && p[2] == '.' && - (p[3] == '/' || p[3] == '\\')) { - p += 3; /* Remove "/..", leave "/" - * for next pass. */ - } else - p += 1; /* Remove "/". */ - } - } while (rp != p); - return (p); -} - -/* - * This is used by both out mode (to copy objects from disk into - * an archive) and pass mode (to copy objects from disk to - * an archive_write_disk "archive"). - */ -static int -file_to_archive(struct cpio *cpio, const char *srcpath) -{ - const char *destpath; - struct archive_entry *entry, *spare; - size_t len; - int r; - - /* - * Create an archive_entry describing the source file. - * - */ - entry = archive_entry_new(); - if (entry == NULL) - lafe_errc(1, 0, "Couldn't allocate entry"); - archive_entry_copy_sourcepath(entry, srcpath); - r = archive_read_disk_entry_from_file(cpio->archive_read_disk, - entry, -1, NULL); - if (r < ARCHIVE_FAILED) - lafe_errc(1, 0, "%s", - archive_error_string(cpio->archive_read_disk)); - if (r < ARCHIVE_OK) - lafe_warnc(0, "%s", - archive_error_string(cpio->archive_read_disk)); - if (r <= ARCHIVE_FAILED) { - archive_entry_free(entry); - cpio->return_value = 1; - return (r); - } - - if (cpio->uid_override >= 0) { - archive_entry_set_uid(entry, cpio->uid_override); - archive_entry_set_uname(entry, cpio->uname_override); - } - if (cpio->gid_override >= 0) { - archive_entry_set_gid(entry, cpio->gid_override); - archive_entry_set_gname(entry, cpio->gname_override); - } - - /* - * Generate a destination path for this entry. - * "destination path" is the name to which it will be copied in - * pass mode or the name that will go into the archive in - * output mode. - */ - destpath = srcpath; - if (cpio->destdir) { - len = cpio->destdir_len + strlen(srcpath) + 8; - if (len >= cpio->pass_destpath_alloc) { - while (len >= cpio->pass_destpath_alloc) { - cpio->pass_destpath_alloc += 512; - cpio->pass_destpath_alloc *= 2; - } - free(cpio->pass_destpath); - cpio->pass_destpath = malloc(cpio->pass_destpath_alloc); - if (cpio->pass_destpath == NULL) - lafe_errc(1, ENOMEM, - "Can't allocate path buffer"); - } - strcpy(cpio->pass_destpath, cpio->destdir); - strcat(cpio->pass_destpath, remove_leading_slash(srcpath)); - destpath = cpio->pass_destpath; - } - if (cpio->option_rename) - destpath = cpio_rename(destpath); - if (destpath == NULL) { - archive_entry_free(entry); - return (0); - } - archive_entry_copy_pathname(entry, destpath); - - /* - * If we're trying to preserve hardlinks, match them here. - */ - spare = NULL; - if (cpio->linkresolver != NULL - && archive_entry_filetype(entry) != AE_IFDIR) { - archive_entry_linkify(cpio->linkresolver, &entry, &spare); - } - - if (entry != NULL) { - r = entry_to_archive(cpio, entry); - archive_entry_free(entry); - if (spare != NULL) { - if (r == 0) - r = entry_to_archive(cpio, spare); - archive_entry_free(spare); - } - } - return (r); -} - -static int -entry_to_archive(struct cpio *cpio, struct archive_entry *entry) -{ - const char *destpath = archive_entry_pathname(entry); - const char *srcpath = archive_entry_sourcepath(entry); - int fd = -1; - ssize_t bytes_read; - int r; - - /* Print out the destination name to the user. */ - if (cpio->verbose) - fprintf(stderr,"%s", destpath); - if (cpio->dot) - fprintf(stderr, "."); - - /* - * Option_link only makes sense in pass mode and for - * regular files. Also note: if a link operation fails - * because of cross-device restrictions, we'll fall back - * to copy mode for that entry. - * - * TODO: Test other cpio implementations to see if they - * hard-link anything other than regular files here. - */ - if (cpio->option_link - && archive_entry_filetype(entry) == AE_IFREG) - { - struct archive_entry *t; - /* Save the original entry in case we need it later. */ - t = archive_entry_clone(entry); - if (t == NULL) - lafe_errc(1, ENOMEM, "Can't create link"); - /* Note: link(2) doesn't create parent directories, - * so we use archive_write_header() instead as a - * convenience. */ - archive_entry_set_hardlink(t, srcpath); - /* This is a straight link that carries no data. */ - archive_entry_set_size(t, 0); - r = archive_write_header(cpio->archive, t); - archive_entry_free(t); - if (r != ARCHIVE_OK) - lafe_warnc(archive_errno(cpio->archive), - "%s", archive_error_string(cpio->archive)); - if (r == ARCHIVE_FATAL) - exit(1); -#ifdef EXDEV - if (r != ARCHIVE_OK && archive_errno(cpio->archive) == EXDEV) { - /* Cross-device link: Just fall through and use - * the original entry to copy the file over. */ - lafe_warnc(0, "Copying file instead"); - } else -#endif - return (0); - } - - /* - * Make sure we can open the file (if necessary) before - * trying to write the header. - */ - if (archive_entry_filetype(entry) == AE_IFREG) { - if (archive_entry_size(entry) > 0) { - fd = open(srcpath, O_RDONLY | O_BINARY); - if (fd < 0) { - lafe_warnc(errno, - "%s: could not open file", srcpath); - goto cleanup; - } - } - } else { - archive_entry_set_size(entry, 0); - } - - r = archive_write_header(cpio->archive, entry); - - if (r != ARCHIVE_OK) - lafe_warnc(archive_errno(cpio->archive), - "%s: %s", - srcpath, - archive_error_string(cpio->archive)); - - if (r == ARCHIVE_FATAL) - exit(1); - - if (r >= ARCHIVE_WARN && archive_entry_size(entry) > 0 && fd >= 0) { - bytes_read = read(fd, cpio->buff, (unsigned)cpio->buff_size); - while (bytes_read > 0) { - ssize_t bytes_write; - bytes_write = archive_write_data(cpio->archive, - cpio->buff, bytes_read); - if (bytes_write < 0) - lafe_errc(1, archive_errno(cpio->archive), - "%s", archive_error_string(cpio->archive)); - if (bytes_write < bytes_read) { - lafe_warnc(0, - "Truncated write; file may have " - "grown while being archived."); - } - bytes_read = read(fd, cpio->buff, - (unsigned)cpio->buff_size); - } - } - - fd = restore_time(cpio, entry, srcpath, fd); - -cleanup: - if (cpio->verbose) - fprintf(stderr,"\n"); - if (fd >= 0) - close(fd); - return (0); -} - -static int -restore_time(struct cpio *cpio, struct archive_entry *entry, - const char *name, int fd) -{ -#ifndef HAVE_UTIMES - static int warned = 0; - - (void)cpio; /* UNUSED */ - (void)entry; /* UNUSED */ - (void)name; /* UNUSED */ - - if (!warned) - lafe_warnc(0, "Can't restore access times on this platform"); - warned = 1; - return (fd); -#else -#if defined(_WIN32) && !defined(__CYGWIN__) - struct __timeval times[2]; -#else - struct timeval times[2]; -#endif - - if (!cpio->option_atime_restore) - return (fd); - - times[1].tv_sec = archive_entry_mtime(entry); - times[1].tv_usec = archive_entry_mtime_nsec(entry) / 1000; - - times[0].tv_sec = archive_entry_atime(entry); - times[0].tv_usec = archive_entry_atime_nsec(entry) / 1000; - -#if defined(HAVE_FUTIMES) && !defined(__CYGWIN__) - if (fd >= 0 && futimes(fd, times) == 0) - return (fd); -#endif - /* - * Some platform cannot restore access times if the file descriptor - * is still opened. - */ - if (fd >= 0) { - close(fd); - fd = -1; - } - -#ifdef HAVE_LUTIMES - if (lutimes(name, times) != 0) -#else - if ((AE_IFLNK != archive_entry_filetype(entry)) - && utimes(name, times) != 0) -#endif - lafe_warnc(errno, "Can't update time for %s", name); -#endif - return (fd); -} - - -static void -mode_in(struct cpio *cpio) -{ - struct archive *a; - struct archive_entry *entry; - struct archive *ext; - const char *destpath; - int r; - - ext = archive_write_disk_new(); - if (ext == NULL) - lafe_errc(1, 0, "Couldn't allocate restore object"); - r = archive_write_disk_set_options(ext, cpio->extract_flags); - if (r != ARCHIVE_OK) - lafe_errc(1, 0, "%s", archive_error_string(ext)); - a = archive_read_new(); - if (a == NULL) - lafe_errc(1, 0, "Couldn't allocate archive object"); - archive_read_support_filter_all(a); - archive_read_support_format_all(a); - if (cpio->option_pwb) - archive_read_set_options(a, "pwb"); - if (cpio->passphrase != NULL) - r = archive_read_add_passphrase(a, cpio->passphrase); - else - r = archive_read_set_passphrase_callback(a, cpio, - &passphrase_callback); - if (r != ARCHIVE_OK) - lafe_errc(1, 0, "%s", archive_error_string(a)); - - if (archive_read_open_filename(a, cpio->filename, - cpio->bytes_per_block)) - lafe_errc(1, archive_errno(a), - "%s", archive_error_string(a)); - for (;;) { - r = archive_read_next_header(a, &entry); - if (r == ARCHIVE_EOF) - break; - if (r != ARCHIVE_OK) { - lafe_errc(1, archive_errno(a), - "%s", archive_error_string(a)); - } - if (archive_match_path_excluded(cpio->matching, entry)) - continue; - if (cpio->option_rename) { - destpath = cpio_rename(archive_entry_pathname(entry)); - archive_entry_set_pathname(entry, destpath); - } else - destpath = archive_entry_pathname(entry); - if (destpath == NULL) - continue; - if (cpio->verbose) - fprintf(stderr, "%s\n", destpath); - if (cpio->dot) - fprintf(stderr, "."); - if (cpio->uid_override >= 0) - archive_entry_set_uid(entry, cpio->uid_override); - if (cpio->gid_override >= 0) - archive_entry_set_gid(entry, cpio->gid_override); - r = archive_write_header(ext, entry); - if (r != ARCHIVE_OK) { - fprintf(stderr, "%s: %s\n", - archive_entry_pathname(entry), - archive_error_string(ext)); - } else if (!archive_entry_size_is_set(entry) - || archive_entry_size(entry) > 0) { - r = extract_data(a, ext); - if (r != ARCHIVE_OK) - cpio->return_value = 1; - } - } - r = archive_read_close(a); - if (cpio->dot) - fprintf(stderr, "\n"); - if (r != ARCHIVE_OK) - lafe_errc(1, 0, "%s", archive_error_string(a)); - r = archive_write_close(ext); - if (r != ARCHIVE_OK) - lafe_errc(1, 0, "%s", archive_error_string(ext)); - if (!cpio->quiet) { - int64_t blocks = (archive_filter_bytes(a, 0) + 511) - / 512; - fprintf(stderr, "%lu %s\n", (unsigned long)blocks, - blocks == 1 ? "block" : "blocks"); - } - archive_read_free(a); - archive_write_free(ext); - exit(cpio->return_value); -} - -/* - * Exits if there's a fatal error. Returns ARCHIVE_OK - * if everything is kosher. - */ -static int -extract_data(struct archive *ar, struct archive *aw) -{ - int r; - size_t size; - const void *block; - int64_t offset; - - for (;;) { - r = archive_read_data_block(ar, &block, &size, &offset); - if (r == ARCHIVE_EOF) - return (ARCHIVE_OK); - if (r != ARCHIVE_OK) { - lafe_warnc(archive_errno(ar), - "%s", archive_error_string(ar)); - exit(1); - } - r = (int)archive_write_data_block(aw, block, size, offset); - if (r != ARCHIVE_OK) { - lafe_warnc(archive_errno(aw), - "%s", archive_error_string(aw)); - return (r); - } - } -} - -static void -mode_list(struct cpio *cpio) -{ - struct archive *a; - struct archive_entry *entry; - int r; - - a = archive_read_new(); - if (a == NULL) - lafe_errc(1, 0, "Couldn't allocate archive object"); - archive_read_support_filter_all(a); - archive_read_support_format_all(a); - if (cpio->option_pwb) - archive_read_set_options(a, "pwb"); - if (cpio->passphrase != NULL) - r = archive_read_add_passphrase(a, cpio->passphrase); - else - r = archive_read_set_passphrase_callback(a, cpio, - &passphrase_callback); - if (r != ARCHIVE_OK) - lafe_errc(1, 0, "%s", archive_error_string(a)); - - if (archive_read_open_filename(a, cpio->filename, - cpio->bytes_per_block)) - lafe_errc(1, archive_errno(a), - "%s", archive_error_string(a)); - for (;;) { - r = archive_read_next_header(a, &entry); - if (r == ARCHIVE_EOF) - break; - if (r != ARCHIVE_OK) { - lafe_errc(1, archive_errno(a), - "%s", archive_error_string(a)); - } - if (archive_match_path_excluded(cpio->matching, entry)) - continue; - if (cpio->verbose) - list_item_verbose(cpio, entry); - else - fprintf(stdout, "%s\n", archive_entry_pathname(entry)); - } - r = archive_read_close(a); - if (r != ARCHIVE_OK) - lafe_errc(1, 0, "%s", archive_error_string(a)); - if (!cpio->quiet) { - int64_t blocks = (archive_filter_bytes(a, 0) + 511) - / 512; - fprintf(stderr, "%lu %s\n", (unsigned long)blocks, - blocks == 1 ? "block" : "blocks"); - } - archive_read_free(a); - exit(0); -} - -/* - * Display information about the current file. - * - * The format here roughly duplicates the output of 'ls -l'. - * This is based on SUSv2, where 'tar tv' is documented as - * listing additional information in an "unspecified format," - * and 'pax -l' is documented as using the same format as 'ls -l'. - */ -static void -list_item_verbose(struct cpio *cpio, struct archive_entry *entry) -{ - char size[32]; - char date[32]; - char uids[22], gids[22]; - const char *uname, *gname; - FILE *out = stdout; - const char *fmt; - time_t mtime; - static time_t now; - struct tm *ltime; -#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S) - struct tm tmbuf; -#endif - - if (!now) - time(&now); - - if (cpio->option_numeric_uid_gid) { - /* Format numeric uid/gid for display. */ - strcpy(uids, cpio_i64toa(archive_entry_uid(entry))); - uname = uids; - strcpy(gids, cpio_i64toa(archive_entry_gid(entry))); - gname = gids; - } else { - /* Use uname if it's present, else lookup name from uid. */ - uname = archive_entry_uname(entry); - if (uname == NULL) - uname = lookup_uname(cpio, (uid_t)archive_entry_uid(entry)); - /* Use gname if it's present, else lookup name from gid. */ - gname = archive_entry_gname(entry); - if (gname == NULL) - gname = lookup_gname(cpio, (uid_t)archive_entry_gid(entry)); - } - - /* Print device number or file size. */ - if (archive_entry_filetype(entry) == AE_IFCHR - || archive_entry_filetype(entry) == AE_IFBLK) { - snprintf(size, sizeof(size), "%lu,%lu", - (unsigned long)archive_entry_rdevmajor(entry), - (unsigned long)archive_entry_rdevminor(entry)); - } else { - strcpy(size, cpio_i64toa(archive_entry_size(entry))); - } - - /* Format the time using 'ls -l' conventions. */ - mtime = archive_entry_mtime(entry); -#if defined(_WIN32) && !defined(__CYGWIN__) - /* Windows' strftime function does not support %e format. */ - if (mtime - now > 365*86400/2 - || mtime - now < -365*86400/2) - fmt = cpio->day_first ? "%d %b %Y" : "%b %d %Y"; - else - fmt = cpio->day_first ? "%d %b %H:%M" : "%b %d %H:%M"; -#else - if (mtime - now > 365*86400/2 - || mtime - now < -365*86400/2) - fmt = cpio->day_first ? "%e %b %Y" : "%b %e %Y"; - else - fmt = cpio->day_first ? "%e %b %H:%M" : "%b %e %H:%M"; -#endif -#if defined(HAVE_LOCALTIME_S) - ltime = localtime_s(&tmbuf, &mtime) ? NULL : &tmbuf; -#elif defined(HAVE_LOCALTIME_R) - ltime = localtime_r(&mtime, &tmbuf); -#else - ltime = localtime(&mtime); -#endif - if (ltime != NULL) - strftime(date, sizeof(date), fmt, ltime); - else - strcpy(date, "invalid mtime"); - - fprintf(out, "%s%3d %-8s %-8s %8s %12s %s", - archive_entry_strmode(entry), - archive_entry_nlink(entry), - uname, gname, size, date, - archive_entry_pathname(entry)); - - /* Extra information for links. */ - if (archive_entry_hardlink(entry)) /* Hard link */ - fprintf(out, " link to %s", archive_entry_hardlink(entry)); - else if (archive_entry_symlink(entry)) /* Symbolic link */ - fprintf(out, " -> %s", archive_entry_symlink(entry)); - fprintf(out, "\n"); -} - -static void -mode_pass(struct cpio *cpio, const char *destdir) -{ - struct lafe_line_reader *lr; - const char *p; - int r; - - /* Ensure target dir has a trailing '/' to simplify path surgery. */ - cpio->destdir_len = strlen(destdir); - cpio->destdir = malloc(cpio->destdir_len + 8); - memcpy(cpio->destdir, destdir, cpio->destdir_len); - if (cpio->destdir_len == 0 || destdir[cpio->destdir_len - 1] != '/') - cpio->destdir[cpio->destdir_len++] = '/'; - cpio->destdir[cpio->destdir_len] = '\0'; - - cpio->archive = archive_write_disk_new(); - if (cpio->archive == NULL) - lafe_errc(1, 0, "Failed to allocate archive object"); - r = archive_write_disk_set_options(cpio->archive, cpio->extract_flags); - if (r != ARCHIVE_OK) - lafe_errc(1, 0, "%s", archive_error_string(cpio->archive)); - cpio->linkresolver = archive_entry_linkresolver_new(); - archive_write_disk_set_standard_lookup(cpio->archive); - - cpio->archive_read_disk = archive_read_disk_new(); - if (cpio->archive_read_disk == NULL) - lafe_errc(1, 0, "Failed to allocate archive object"); - if (cpio->option_follow_links) - archive_read_disk_set_symlink_logical(cpio->archive_read_disk); - else - archive_read_disk_set_symlink_physical(cpio->archive_read_disk); - archive_read_disk_set_standard_lookup(cpio->archive_read_disk); - - lr = lafe_line_reader("-", cpio->option_null); - while ((p = lafe_line_reader_next(lr)) != NULL) - file_to_archive(cpio, p); - lafe_line_reader_free(lr); - - archive_entry_linkresolver_free(cpio->linkresolver); - r = archive_write_close(cpio->archive); - if (cpio->dot) - fprintf(stderr, "\n"); - if (r != ARCHIVE_OK) - lafe_errc(1, 0, "%s", archive_error_string(cpio->archive)); - - if (!cpio->quiet) { - int64_t blocks = - (archive_filter_bytes(cpio->archive, 0) + 511) - / 512; - fprintf(stderr, "%lu %s\n", (unsigned long)blocks, - blocks == 1 ? "block" : "blocks"); - } - - archive_write_free(cpio->archive); - free(cpio->pass_destpath); -} - -/* - * Prompt for a new name for this entry. Returns a pointer to the - * new name or NULL if the entry should not be copied. This - * implements the semantics defined in POSIX.1-1996, which specifies - * that an input of '.' means the name should be unchanged. GNU cpio - * treats '.' as a literal new name. - */ -static const char * -cpio_rename(const char *name) -{ - static char buff[1024]; - FILE *t; - char *p, *ret; -#if defined(_WIN32) && !defined(__CYGWIN__) - FILE *to; - - t = fopen("CONIN$", "r"); - if (t == NULL) - return (name); - to = fopen("CONOUT$", "w"); - if (to == NULL) { - fclose(t); - return (name); - } - fprintf(to, "%s (Enter/./(new name))? ", name); - fclose(to); -#else - t = fopen("/dev/tty", "r+"); - if (t == NULL) - return (name); - fprintf(t, "%s (Enter/./(new name))? ", name); - fflush(t); -#endif - - p = fgets(buff, sizeof(buff), t); - fclose(t); - if (p == NULL) - /* End-of-file is a blank line. */ - return (NULL); - - while (*p == ' ' || *p == '\t') - ++p; - if (*p == '\n' || *p == '\0') - /* Empty line. */ - return (NULL); - if (*p == '.' && p[1] == '\n') - /* Single period preserves original name. */ - return (name); - ret = p; - /* Trim the final newline. */ - while (*p != '\0' && *p != '\n') - ++p; - /* Overwrite the final \n with a null character. */ - *p = '\0'; - return (ret); -} - -static void -free_cache(struct name_cache *cache) -{ - size_t i; - - if (cache != NULL) { - for (i = 0; i < cache->size; i++) - free(cache->cache[i].name); - free(cache); - } -} - -/* - * Lookup uname/gname from uid/gid, return NULL if no match. - */ -static const char * -lookup_name(struct cpio *cpio, struct name_cache **name_cache_variable, - int (*lookup_fn)(struct cpio *, const char **, id_t), id_t id) -{ - char asnum[16]; - struct name_cache *cache; - const char *name; - int slot; - - - if (*name_cache_variable == NULL) { - *name_cache_variable = calloc(1, sizeof(struct name_cache)); - if (*name_cache_variable == NULL) - lafe_errc(1, ENOMEM, "No more memory"); - (*name_cache_variable)->size = name_cache_size; - } - - cache = *name_cache_variable; - cache->probes++; - - slot = id % cache->size; - if (cache->cache[slot].name != NULL) { - if (cache->cache[slot].id == id) { - cache->hits++; - return (cache->cache[slot].name); - } - free(cache->cache[slot].name); - cache->cache[slot].name = NULL; - } - - if (lookup_fn(cpio, &name, id)) { - /* If lookup failed, format it as a number. */ - snprintf(asnum, sizeof(asnum), "%u", (unsigned)id); - name = asnum; - } - - cache->cache[slot].name = strdup(name); - if (cache->cache[slot].name != NULL) { - cache->cache[slot].id = id; - return (cache->cache[slot].name); - } - - /* - * Conveniently, NULL marks an empty slot, so - * if the strdup() fails, we've just failed to - * cache it. No recovery necessary. - */ - return (NULL); -} - -static const char * -lookup_uname(struct cpio *cpio, uid_t uid) -{ - return (lookup_name(cpio, &cpio->uname_cache, - &lookup_uname_helper, (id_t)uid)); -} - -static int -lookup_uname_helper(struct cpio *cpio, const char **name, id_t id) -{ - struct passwd *pwent; - - (void)cpio; /* UNUSED */ - - errno = 0; - pwent = getpwuid((uid_t)id); - if (pwent == NULL) { - if (errno && errno != ENOENT) - lafe_warnc(errno, "getpwuid(%s) failed", - cpio_i64toa((int64_t)id)); - return 1; - } - - *name = pwent->pw_name; - return 0; -} - -static const char * -lookup_gname(struct cpio *cpio, gid_t gid) -{ - return (lookup_name(cpio, &cpio->gname_cache, - &lookup_gname_helper, (id_t)gid)); -} - -static int -lookup_gname_helper(struct cpio *cpio, const char **name, id_t id) -{ - struct group *grent; - - (void)cpio; /* UNUSED */ - - errno = 0; - grent = getgrgid((gid_t)id); - if (grent == NULL) { - if (errno && errno != ENOENT) - lafe_warnc(errno, "getgrgid(%s) failed", - cpio_i64toa((int64_t)id)); - return 1; - } - - *name = grent->gr_name; - return 0; -} - -/* - * It would be nice to just use printf() for formatting large numbers, - * but the compatibility problems are a big headache. Hence the - * following simple utility function. - */ -const char * -cpio_i64toa(int64_t n0) -{ - /* 2^64 =~ 1.8 * 10^19, so 20 decimal digits suffice. - * We also need 1 byte for '-' and 1 for '\0'. - */ - static char buff[22]; - int64_t n = n0 < 0 ? -n0 : n0; - char *p = buff + sizeof(buff); - - *--p = '\0'; - do { - *--p = '0' + (int)(n % 10); - n /= 10; - } while (n > 0); - if (n0 < 0) - *--p = '-'; - return p; -} - -#define PPBUFF_SIZE 1024 -static const char * -passphrase_callback(struct archive *a, void *_client_data) -{ - struct cpio *cpio = (struct cpio *)_client_data; - (void)a; /* UNUSED */ - - if (cpio->ppbuff == NULL) { - cpio->ppbuff = malloc(PPBUFF_SIZE); - if (cpio->ppbuff == NULL) - lafe_errc(1, errno, "Out of memory"); - } - return lafe_readpassphrase("Enter passphrase:", - cpio->ppbuff, PPBUFF_SIZE); -} - -static void -passphrase_free(char *ppbuff) -{ - if (ppbuff != NULL) { - memset(ppbuff, 0, PPBUFF_SIZE); - free(ppbuff); - } -} diff --git a/thirdparty/libarchive/cpio/cpio.h b/thirdparty/libarchive/cpio/cpio.h deleted file mode 100644 index a71b6649d..000000000 --- a/thirdparty/libarchive/cpio/cpio.h +++ /dev/null @@ -1,122 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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/usr.bin/cpio/cpio.h,v 1.7 2008/12/06 07:30:40 kientzle Exp $ - */ - -#ifndef CPIO_H_INCLUDED -#define CPIO_H_INCLUDED - -#include "cpio_platform.h" -#include - -/* - * The internal state for the "cpio" program. - * - * Keeping all of the state in a structure like this simplifies memory - * leak testing (at exit, anything left on the heap is suspect). A - * pointer to this structure is passed to most cpio internal - * functions. - */ -struct cpio { - /* Option parsing */ - const char *argument; - - /* Options */ - int add_filter; /* --uuencode */ - const char *filename; - int mode; /* -i -o -p */ - int compress; /* -j, -y, or -z */ - const char *format; /* -H format */ - int bytes_per_block; /* -b block_size */ - int verbose; /* -v */ - int dot; /* -V */ - int quiet; /* --quiet */ - int extract_flags; /* Flags for extract operation */ - const char *compress_program; - int option_append; /* -A, only relevant for -o */ - int option_atime_restore; /* -a */ - int option_follow_links; /* -L */ - int option_link; /* -l */ - int option_list; /* -t */ - char option_null; /* --null */ - int option_numeric_uid_gid; /* -n */ - int option_pwb; /* -6 */ - int option_rename; /* -r */ - char *destdir; - size_t destdir_len; - size_t pass_destpath_alloc; - char *pass_destpath; - int uid_override; - char *uname_override; - int gid_override; - char *gname_override; - int day_first; /* true if locale prefers day/mon */ - const char *passphrase; - - /* If >= 0, then close this when done. */ - int fd; - - /* Miscellaneous state information */ - struct archive *archive; - struct archive *archive_read_disk; - int argc; - char **argv; - int return_value; /* Value returned by main() */ - struct archive_entry_linkresolver *linkresolver; - - struct name_cache *uname_cache; - struct name_cache *gname_cache; - - /* Work data. */ - struct archive *matching; - char *buff; - size_t buff_size; - char *ppbuff; -}; - -const char *owner_parse(const char *, int *, int *); - - -/* Fake short equivalents for long options that otherwise lack them. */ -enum { - OPTION_B64ENCODE = 1, - OPTION_GRZIP, - OPTION_INSECURE, - OPTION_LRZIP, - OPTION_LZ4, - OPTION_LZMA, - OPTION_LZOP, - OPTION_PASSPHRASE, - OPTION_NO_PRESERVE_OWNER, - OPTION_PRESERVE_OWNER, - OPTION_QUIET, - OPTION_UUENCODE, - OPTION_VERSION, - OPTION_ZSTD, -}; - -int cpio_getopt(struct cpio *cpio); - -#endif diff --git a/thirdparty/libarchive/cpio/cpio_platform.h b/thirdparty/libarchive/cpio/cpio_platform.h deleted file mode 100644 index 58d2edbcd..000000000 --- a/thirdparty/libarchive/cpio/cpio_platform.h +++ /dev/null @@ -1,77 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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/usr.bin/cpio/cpio_platform.h,v 1.2 2008/12/06 07:15:42 kientzle Exp $ - */ - -/* - * This header is the first thing included in any of the cpio - * source files. As far as possible, platform-specific issues should - * be dealt with here and not within individual source files. - */ - -#ifndef CPIO_PLATFORM_H_INCLUDED -#define CPIO_PLATFORM_H_INCLUDED - -#if defined(PLATFORM_CONFIG_H) -/* Use hand-built config.h in environments that need it. */ -#include PLATFORM_CONFIG_H -#else -/* Read config.h or die trying. */ -#include "config.h" -#endif - -#if defined(_WIN32) && !defined(__CYGWIN__) -#include "cpio_windows.h" -#endif - -/* Get a real definition for __FBSDID if we can */ -#if HAVE_SYS_CDEFS_H -#include -#endif - -/* If not, define it so as to avoid dangling semicolons. */ -#ifndef __FBSDID -#define __FBSDID(a) struct _undefined_hack -#endif - -#ifdef HAVE_LIBARCHIVE -/* If we're using the platform libarchive, include system headers. */ -#include -#include -#else -/* Otherwise, include user headers. */ -#include "archive.h" -#include "archive_entry.h" -#endif - -/* How to mark functions that don't return. */ -#if defined(__GNUC__) && (__GNUC__ > 2 || \ - (__GNUC__ == 2 && __GNUC_MINOR__ >= 5)) -#define __LA_DEAD __attribute__((__noreturn__)) -#else -#define __LA_DEAD -#endif - -#endif /* !CPIO_PLATFORM_H_INCLUDED */ diff --git a/thirdparty/libarchive/cpio/cpio_windows.c b/thirdparty/libarchive/cpio/cpio_windows.c deleted file mode 100644 index 2809ca821..000000000 --- a/thirdparty/libarchive/cpio/cpio_windows.c +++ /dev/null @@ -1,355 +0,0 @@ -/*- - * Copyright (c) 2009 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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$ - */ - -#if defined(_WIN32) && !defined(__CYGWIN__) - -#include "cpio_platform.h" -#include -#include -#include -#include -#include -#ifdef HAVE_SYS_UTIME_H -#include -#endif -#include -#include -#include -#include -#include -#include - -#include "cpio.h" -#include "err.h" - -#define EPOC_TIME (116444736000000000ULL) - -static void cpio_dosmaperr(unsigned long); - -/* - * Prepend "\\?\" to the path name and convert it to unicode to permit - * an extended-length path for a maximum total path length of 32767 - * characters. - * see also http://msdn.microsoft.com/en-us/library/aa365247.aspx - */ -static wchar_t * -permissive_name(const char *name) -{ - wchar_t *wn, *wnp; - wchar_t *ws, *wsp; - DWORD l, len, slen, alloclen; - int unc; - - len = (DWORD)strlen(name); - wn = malloc((len + 1) * sizeof(wchar_t)); - if (wn == NULL) - return (NULL); - l = MultiByteToWideChar(CP_ACP, 0, name, len, wn, len); - if (l == 0) { - free(wn); - return (NULL); - } - wn[l] = L'\0'; - - /* Get a full path names */ - l = GetFullPathNameW(wn, 0, NULL, NULL); - if (l == 0) { - free(wn); - return (NULL); - } - wnp = malloc(l * sizeof(wchar_t)); - if (wnp == NULL) { - free(wn); - return (NULL); - } - len = GetFullPathNameW(wn, l, wnp, NULL); - free(wn); - wn = wnp; - - if (wnp[0] == L'\\' && wnp[1] == L'\\' && - wnp[2] == L'?' && wnp[3] == L'\\') - /* We have already permissive names. */ - return (wn); - - if (wnp[0] == L'\\' && wnp[1] == L'\\' && - wnp[2] == L'.' && wnp[3] == L'\\') { - /* Device names */ - if (((wnp[4] >= L'a' && wnp[4] <= L'z') || - (wnp[4] >= L'A' && wnp[4] <= L'Z')) && - wnp[5] == L':' && wnp[6] == L'\\') - wnp[2] = L'?';/* Not device names. */ - return (wn); - } - - unc = 0; - if (wnp[0] == L'\\' && wnp[1] == L'\\' && wnp[2] != L'\\') { - wchar_t *p = &wnp[2]; - - /* Skip server-name letters. */ - while (*p != L'\\' && *p != L'\0') - ++p; - if (*p == L'\\') { - wchar_t *rp = ++p; - /* Skip share-name letters. */ - while (*p != L'\\' && *p != L'\0') - ++p; - if (*p == L'\\' && p != rp) { - /* Now, match patterns such as - * "\\server-name\share-name\" */ - wnp += 2; - len -= 2; - unc = 1; - } - } - } - - alloclen = slen = 4 + (unc * 4) + len + 1; - ws = wsp = malloc(slen * sizeof(wchar_t)); - if (ws == NULL) { - free(wn); - return (NULL); - } - /* prepend "\\?\" */ - wcsncpy(wsp, L"\\\\?\\", 4); - wsp += 4; - slen -= 4; - if (unc) { - /* append "UNC\" ---> "\\?\UNC\" */ - wcsncpy(wsp, L"UNC\\", 4); - wsp += 4; - slen -= 4; - } - wcsncpy(wsp, wnp, slen); - free(wn); - ws[alloclen - 1] = L'\0'; - return (ws); -} - -static HANDLE -cpio_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode, - LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, - DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) -{ - wchar_t *wpath; - HANDLE handle; -# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */ - CREATEFILE2_EXTENDED_PARAMETERS createExParams; -#endif - -#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP) - handle = CreateFileA(path, dwDesiredAccess, dwShareMode, - lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, - hTemplateFile); - if (handle != INVALID_HANDLE_VALUE) - return (handle); - if (GetLastError() != ERROR_PATH_NOT_FOUND) - return (handle); -#endif - wpath = permissive_name(path); - if (wpath == NULL) - return INVALID_HANDLE_VALUE; -# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */ - ZeroMemory(&createExParams, sizeof(createExParams)); - createExParams.dwSize = sizeof(createExParams); - createExParams.dwFileAttributes = dwFlagsAndAttributes & 0xFFFF; - createExParams.dwFileFlags = dwFlagsAndAttributes & 0xFFF00000; - createExParams.dwSecurityQosFlags = dwFlagsAndAttributes & 0x000F0000; - createExParams.lpSecurityAttributes = lpSecurityAttributes; - createExParams.hTemplateFile = hTemplateFile; - handle = CreateFile2(wpath, dwDesiredAccess, dwShareMode, - dwCreationDisposition, &createExParams); -#else - handle = CreateFileW(wpath, dwDesiredAccess, dwShareMode, - lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, - hTemplateFile); -#endif - free(wpath); - return (handle); -} - -#define WINTIME(sec, usec) ((Int32x32To64(sec, 10000000) + EPOC_TIME) + (usec * 10)) -static int -__hutimes(HANDLE handle, const struct __timeval *times) -{ - ULARGE_INTEGER wintm; - FILETIME fatime, fmtime; - - wintm.QuadPart = WINTIME(times[0].tv_sec, times[0].tv_usec); - fatime.dwLowDateTime = wintm.LowPart; - fatime.dwHighDateTime = wintm.HighPart; - wintm.QuadPart = WINTIME(times[1].tv_sec, times[1].tv_usec); - fmtime.dwLowDateTime = wintm.LowPart; - fmtime.dwHighDateTime = wintm.HighPart; - if (SetFileTime(handle, NULL, &fatime, &fmtime) == 0) { - errno = EINVAL; - return (-1); - } - return (0); -} - -int -futimes(int fd, const struct __timeval *times) -{ - - return (__hutimes((HANDLE)_get_osfhandle(fd), times)); -} - -int -utimes(const char *name, const struct __timeval *times) -{ - int ret; - HANDLE handle; - - handle = cpio_CreateFile(name, GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, NULL); - if (handle == INVALID_HANDLE_VALUE) { - cpio_dosmaperr(GetLastError()); - return (-1); - } - ret = __hutimes(handle, times); - CloseHandle(handle); - return (ret); -} - -/* - * The following function was modified from PostgreSQL sources and is - * subject to the copyright below. - */ -/*------------------------------------------------------------------------- - * - * win32error.c - * Map win32 error codes to errno values - * - * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/port/win32error.c,v 1.4 2008/01/01 19:46:00 momjian Exp $ - * - *------------------------------------------------------------------------- - */ -/* -PostgreSQL Database Management System -(formerly known as Postgres, then as Postgres95) - -Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group - -Portions Copyright (c) 1994, The Regents of the University of California - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose, without fee, and without a written agreement -is hereby granted, provided that the above copyright notice and this -paragraph and the following two paragraphs appear in all copies. - -IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR -DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING -LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS -DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO -PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -*/ - -static const struct { - DWORD winerr; - int doserr; -} doserrors[] = -{ - { ERROR_INVALID_FUNCTION, EINVAL }, - { ERROR_FILE_NOT_FOUND, ENOENT }, - { ERROR_PATH_NOT_FOUND, ENOENT }, - { ERROR_TOO_MANY_OPEN_FILES, EMFILE }, - { ERROR_ACCESS_DENIED, EACCES }, - { ERROR_INVALID_HANDLE, EBADF }, - { ERROR_ARENA_TRASHED, ENOMEM }, - { ERROR_NOT_ENOUGH_MEMORY, ENOMEM }, - { ERROR_INVALID_BLOCK, ENOMEM }, - { ERROR_BAD_ENVIRONMENT, E2BIG }, - { ERROR_BAD_FORMAT, ENOEXEC }, - { ERROR_INVALID_ACCESS, EINVAL }, - { ERROR_INVALID_DATA, EINVAL }, - { ERROR_INVALID_DRIVE, ENOENT }, - { ERROR_CURRENT_DIRECTORY, EACCES }, - { ERROR_NOT_SAME_DEVICE, EXDEV }, - { ERROR_NO_MORE_FILES, ENOENT }, - { ERROR_LOCK_VIOLATION, EACCES }, - { ERROR_SHARING_VIOLATION, EACCES }, - { ERROR_BAD_NETPATH, ENOENT }, - { ERROR_NETWORK_ACCESS_DENIED, EACCES }, - { ERROR_BAD_NET_NAME, ENOENT }, - { ERROR_FILE_EXISTS, EEXIST }, - { ERROR_CANNOT_MAKE, EACCES }, - { ERROR_FAIL_I24, EACCES }, - { ERROR_INVALID_PARAMETER, EINVAL }, - { ERROR_NO_PROC_SLOTS, EAGAIN }, - { ERROR_DRIVE_LOCKED, EACCES }, - { ERROR_BROKEN_PIPE, EPIPE }, - { ERROR_DISK_FULL, ENOSPC }, - { ERROR_INVALID_TARGET_HANDLE, EBADF }, - { ERROR_INVALID_HANDLE, EINVAL }, - { ERROR_WAIT_NO_CHILDREN, ECHILD }, - { ERROR_CHILD_NOT_COMPLETE, ECHILD }, - { ERROR_DIRECT_ACCESS_HANDLE, EBADF }, - { ERROR_NEGATIVE_SEEK, EINVAL }, - { ERROR_SEEK_ON_DEVICE, EACCES }, - { ERROR_DIR_NOT_EMPTY, ENOTEMPTY }, - { ERROR_NOT_LOCKED, EACCES }, - { ERROR_BAD_PATHNAME, ENOENT }, - { ERROR_MAX_THRDS_REACHED, EAGAIN }, - { ERROR_LOCK_FAILED, EACCES }, - { ERROR_ALREADY_EXISTS, EEXIST }, - { ERROR_FILENAME_EXCED_RANGE, ENOENT }, - { ERROR_NESTING_NOT_ALLOWED, EAGAIN }, - { ERROR_NOT_ENOUGH_QUOTA, ENOMEM } -}; - -static void -cpio_dosmaperr(unsigned long e) -{ - int i; - - if (e == 0) { - errno = 0; - return; - } - - for (i = 0; i < (int)sizeof(doserrors); i++) { - if (doserrors[i].winerr == e) { - errno = doserrors[i].doserr; - return; - } - } - - /* fprintf(stderr, "unrecognized win32 error code: %lu", e); */ - errno = EINVAL; - return; -} -#endif diff --git a/thirdparty/libarchive/cpio/cpio_windows.h b/thirdparty/libarchive/cpio/cpio_windows.h deleted file mode 100644 index 970a63df6..000000000 --- a/thirdparty/libarchive/cpio/cpio_windows.h +++ /dev/null @@ -1,75 +0,0 @@ -/*- - * Copyright (c) 2009 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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$ - */ -#ifndef CPIO_WINDOWS_H -#define CPIO_WINDOWS_H 1 -#include - -#include -#include - -#define getgrgid(id) NULL -#define getgrnam(name) NULL -#define getpwnam(name) NULL -#define getpwuid(id) NULL - -#if defined(_MSC_VER) - #if _MSC_VER < 1900 - #define snprintf sprintf_s - #endif // _MSC_VER < 1900 -#define strdup _strdup -#define open _open -#define read _read -#define close _close -#endif - -struct passwd { - char *pw_name; - uid_t pw_uid; - gid_t pw_gid; -}; - -struct group { - char *gr_name; - gid_t gr_gid; -}; - -struct _timeval64i32 { - time_t tv_sec; - long tv_usec; -}; -#define __timeval _timeval64i32 - -extern int futimes(int fd, const struct __timeval *times); -#ifndef HAVE_FUTIMES -#define HAVE_FUTIMES 1 -#endif -extern int utimes(const char *name, const struct __timeval *times); -#ifndef HAVE_UTIMES -#define HAVE_UTIMES 1 -#endif - -#endif /* CPIO_WINDOWS_H */ diff --git a/thirdparty/libarchive/cpio/test/CMakeLists.txt b/thirdparty/libarchive/cpio/test/CMakeLists.txt deleted file mode 100644 index 2c3fbb0a8..000000000 --- a/thirdparty/libarchive/cpio/test/CMakeLists.txt +++ /dev/null @@ -1,112 +0,0 @@ -############################################ -# -# How to build bsdcpio_test -# -############################################ -IF(ENABLE_CPIO AND ENABLE_TEST) - SET(bsdcpio_test_SOURCES - ../cmdline.c - ../../libarchive_fe/err.c - ../../test_utils/test_utils.c - ../../test_utils/test_main.c - test.h - test_0.c - test_basic.c - test_cmdline.c - test_extract_cpio_Z.c - test_extract_cpio_bz2.c - test_extract_cpio_grz.c - test_extract_cpio_gz.c - test_extract_cpio_lrz.c - test_extract_cpio_lz.c - test_extract_cpio_lz4.c - test_extract_cpio_lzma.c - test_extract_cpio_lzo.c - test_extract_cpio_xz.c - test_extract_cpio_zstd.c - test_format_newc.c - test_gcpio_compat.c - test_missing_file.c - test_option_0.c - test_option_B_upper.c - test_option_C_upper.c - test_option_J_upper.c - test_option_L_upper.c - test_option_Z_upper.c - test_option_a.c - test_option_b64encode.c - test_option_c.c - test_option_d.c - test_option_f.c - test_option_grzip.c - test_option_help.c - test_option_l.c - test_option_lrzip.c - test_option_lz4.c - test_option_lzma.c - test_option_lzop.c - test_option_m.c - test_option_passphrase.c - test_option_t.c - test_option_u.c - test_option_uuencode.c - test_option_version.c - test_option_xz.c - test_option_y.c - test_option_z.c - test_option_zstd.c - test_owner_parse.c - test_passthrough_dotdot.c - test_passthrough_reverse.c - ) - - # - # Register target - # - ADD_EXECUTABLE(bsdcpio_test ${bsdcpio_test_SOURCES}) - IF(ENABLE_ACL) - SET(TEST_ACL_LIBS "") - IF(HAVE_LIBACL) - LIST(APPEND TEST_ACL_LIBS ${ACL_LIBRARY}) - ENDIF(HAVE_LIBACL) - IF(HAVE_LIBRICHACL) - LIST(APPEND TEST_ACL_LIBS ${RICHACL_LIBRARY}) - ENDIF(HAVE_LIBRICHACL) - TARGET_LINK_LIBRARIES(bsdcpio_test ${TEST_ACL_LIBS}) - ENDIF(ENABLE_ACL) - SET_PROPERTY(TARGET bsdcpio_test PROPERTY COMPILE_DEFINITIONS LIST_H) - - # - # Generate list.h by grepping DEFINE_TEST() lines out of the C sources. - # - GENERATE_LIST_H(${CMAKE_CURRENT_BINARY_DIR}/list.h - ${CMAKE_CURRENT_LIST_FILE} ${bsdcpio_test_SOURCES}) - SET_PROPERTY(DIRECTORY APPEND PROPERTY INCLUDE_DIRECTORIES - ${CMAKE_CURRENT_BINARY_DIR}) - - # list.h has a line DEFINE_TEST(testname) for every - # test. We can use that to define the tests for cmake by - # defining a DEFINE_TEST macro and reading list.h in. - MACRO (DEFINE_TEST _testname) - ADD_TEST( - NAME bsdcpio_${_testname} - COMMAND bsdcpio_test -vv - -p $ - -r ${CMAKE_CURRENT_SOURCE_DIR} - ${_testname}) - ENDMACRO (DEFINE_TEST _testname) - - INCLUDE(${CMAKE_CURRENT_BINARY_DIR}/list.h) - INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) - INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/test_utils) - INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/cpio/test) - - # Experimental new test handling - ADD_CUSTOM_TARGET(run_bsdcpio_test - COMMAND bsdcpio_test -p $ - -r ${CMAKE_CURRENT_SOURCE_DIR} - -vv) - ADD_DEPENDENCIES(run_bsdcpio_test bsdcpio) - ADD_DEPENDENCIES(run_all_tests run_bsdcpio_test) -ENDIF(ENABLE_CPIO AND ENABLE_TEST) - diff --git a/thirdparty/libarchive/cpio/test/list.h b/thirdparty/libarchive/cpio/test/list.h deleted file mode 100644 index 92f9ec82e..000000000 --- a/thirdparty/libarchive/cpio/test/list.h +++ /dev/null @@ -1,48 +0,0 @@ -DEFINE_TEST(test_0) -DEFINE_TEST(test_basic) -DEFINE_TEST(test_cmdline) -DEFINE_TEST(test_extract_cpio_bz2) -DEFINE_TEST(test_extract_cpio_grz) -DEFINE_TEST(test_extract_cpio_gz) -DEFINE_TEST(test_extract_cpio_lrz) -DEFINE_TEST(test_extract_cpio_lz4) -DEFINE_TEST(test_extract_cpio_lz) -DEFINE_TEST(test_extract_cpio_lzma) -DEFINE_TEST(test_extract_cpio_lzo) -DEFINE_TEST(test_extract_cpio_xz) -DEFINE_TEST(test_extract_cpio_Z) -DEFINE_TEST(test_extract_cpio_zstd) -DEFINE_TEST(test_format_newc) -DEFINE_TEST(test_gcpio_compat) -DEFINE_TEST(test_missing_file) -DEFINE_TEST(test_option_0) -DEFINE_TEST(test_option_a) -DEFINE_TEST(test_option_b64encode) -DEFINE_TEST(test_option_B_upper) -DEFINE_TEST(test_option_c) -DEFINE_TEST(test_option_C_upper) -DEFINE_TEST(test_option_d) -DEFINE_TEST(test_option_f) -DEFINE_TEST(test_option_grzip) -DEFINE_TEST(test_option_help) -DEFINE_TEST(test_option_J_upper) -DEFINE_TEST(test_option_l) -DEFINE_TEST(test_option_lrzip) -DEFINE_TEST(test_option_L_upper) -DEFINE_TEST(test_option_lz4) -DEFINE_TEST(test_option_lzma) -DEFINE_TEST(test_option_lzop) -DEFINE_TEST(test_option_m) -DEFINE_TEST(test_option_passphrase) -DEFINE_TEST(test_option_t) -DEFINE_TEST(test_option_u) -DEFINE_TEST(test_option_uuencode) -DEFINE_TEST(test_option_version) -DEFINE_TEST(test_option_xz) -DEFINE_TEST(test_option_y) -DEFINE_TEST(test_option_z) -DEFINE_TEST(test_option_zstd) -DEFINE_TEST(test_option_Z_upper) -DEFINE_TEST(test_owner_parse) -DEFINE_TEST(test_passthrough_dotdot) -DEFINE_TEST(test_passthrough_reverse) diff --git a/thirdparty/libarchive/cpio/test/test.h b/thirdparty/libarchive/cpio/test/test.h deleted file mode 100644 index 1dadf6889..000000000 --- a/thirdparty/libarchive/cpio/test/test.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2003-2017 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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$ - */ - -/* Every test program should #include "test.h" as the first thing. */ - -#define KNOWNREF "test_option_f.cpio.uu" -#define ENVBASE "BSDCPIO" /* Prefix for environment variables. */ -#define PROGRAM "bsdcpio" /* Name of program being tested. */ -#define PROGRAM_ALIAS "cpio" /* Generic alias for program */ -#undef LIBRARY /* Not testing a library. */ -#undef EXTRA_DUMP /* How to dump extra data */ -#undef EXTRA_ERRNO /* How to dump errno */ -/* How to generate extra version info. */ -#define EXTRA_VERSION (systemf("%s --version", testprog) ? "" : "") - -#include "test_common.h" diff --git a/thirdparty/libarchive/cpio/test/test_0.c b/thirdparty/libarchive/cpio/test/test_0.c deleted file mode 100644 index fa52def7e..000000000 --- a/thirdparty/libarchive/cpio/test/test_0.c +++ /dev/null @@ -1,75 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* - * This first test does basic sanity checks on the environment. For - * most of these, we just exit on failure. - */ -#if !defined(_WIN32) || defined(__CYGWIN__) -#define DEV_NULL "/dev/null" -#else -#define DEV_NULL "NUL" -#endif - -DEFINE_TEST(test_0) -{ - struct stat st; - - failure("File %s does not exist?!", testprogfile); - if (!assertEqualInt(0, stat(testprogfile, &st))) { - fprintf(stderr, - "\nFile %s does not exist; aborting test.\n\n", - testprog); - exit(1); - } - - failure("%s is not executable?!", testprogfile); - if (!assert((st.st_mode & 0111) != 0)) { - fprintf(stderr, - "\nFile %s not executable; aborting test.\n\n", - testprog); - exit(1); - } - - /* - * Try to successfully run the program; this requires that - * we know some option that will succeed. - */ - if (0 == systemf("%s --version >" DEV_NULL, testprog)) { - /* This worked. */ - } else if (0 == systemf("%s -W version >" DEV_NULL, testprog)) { - /* This worked. */ - } else { - failure("Unable to successfully run any of the following:\n" - " * %s --version\n" - " * %s -W version\n", - testprog, testprog); - assert(0); - } - - /* TODO: Ensure that our reference files are available. */ -} diff --git a/thirdparty/libarchive/cpio/test/test_basic.c b/thirdparty/libarchive/cpio/test/test_basic.c deleted file mode 100644 index 3d7d86a0e..000000000 --- a/thirdparty/libarchive/cpio/test/test_basic.c +++ /dev/null @@ -1,240 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/usr.bin/cpio/test/test_basic.c,v 1.4 2008/08/25 06:39:29 kientzle Exp $"); - -static void -verify_files(const char *msg) -{ - /* - * Verify unpacked files. - */ - - /* Regular file with 2 links. */ - failure("%s", msg); - assertIsReg("file", 0644); - failure("%s", msg); - assertFileSize("file", 10); - failure("%s", msg); - assertFileNLinks("file", 2); - - /* Another name for the same file. */ - failure("%s", msg); - assertIsHardlink("linkfile", "file"); - - /* Symlink */ - if (canSymlink()) - assertIsSymlink("symlink", "file", 0); - - /* Another file with 1 link and different permissions. */ - failure("%s", msg); - assertIsReg("file2", 0777); - failure("%s", msg); - assertFileSize("file2", 10); - failure("%s", msg); - assertFileNLinks("file2", 1); - - /* dir */ - assertIsDir("dir", 0775); -} - -static void -basic_cpio(const char *target, - const char *pack_options, - const char *unpack_options, - const char *se, const char *se2) -{ - int r; - - if (!assertMakeDir(target, 0775)) - return; - - /* Use the cpio program to create an archive. */ - r = systemf("%s -R 1000:1000 -o %s < filelist >%s/archive 2>%s/pack.err", - testprog, pack_options, target, target); - failure("Error invoking %s -o %s", testprog, pack_options); - assertEqualInt(r, 0); - - assertChdir(target); - - /* Verify stderr. */ - failure("Expected: %s, options=%s", se, pack_options); - assertTextFileContents(se, "pack.err"); - - /* - * Use cpio to unpack the archive into another directory. - */ - r = systemf("%s -i %s< archive >unpack.out 2>unpack.err", - testprog, unpack_options); - failure("Error invoking %s -i %s", testprog, unpack_options); - assertEqualInt(r, 0); - - /* Verify stderr. */ - failure("Error invoking %s -i %s in dir %s", testprog, unpack_options, target); - assertTextFileContents(se2, "unpack.err"); - - verify_files(pack_options); - - assertChdir(".."); -} - -static void -passthrough(const char *target) -{ - int r; - - if (!assertMakeDir(target, 0775)) - return; - - /* - * Use cpio passthrough mode to copy files to another directory. - */ - r = systemf("%s -p %s %s/stdout 2>%s/stderr", - testprog, target, target, target); - failure("Error invoking %s -p", testprog); - assertEqualInt(r, 0); - - assertChdir(target); - - /* Verify stderr. */ - failure("Error invoking %s -p in dir %s", - testprog, target); - assertTextFileContents("1 block\n", "stderr"); - - verify_files("passthrough"); - assertChdir(".."); -} - -DEFINE_TEST(test_basic) -{ - FILE *filelist; - const char *msg; - char result[1024]; - - assertUmask(0); - - /* - * Create an assortment of files on disk. - */ - filelist = fopen("filelist", "w"); - memset(result, 0, sizeof(result)); - - /* File with 10 bytes content. */ - assertMakeFile("file", 0644, "1234567890"); - fprintf(filelist, "file\n"); - if (is_LargeInode("file")) { - strncat(result, - "bsdcpio: file: large inode number truncated: ", - sizeof(result) - strlen(result) -1); - strncat(result, - strerror(ERANGE), - sizeof(result) - strlen(result) -1); - strncat(result, - "\n", - sizeof(result) - strlen(result) -1); - } - - /* hardlink to above file. */ - assertMakeHardlink("linkfile", "file"); - fprintf(filelist, "linkfile\n"); - if (is_LargeInode("linkfile")) { - strncat(result, - "bsdcpio: linkfile: large inode number truncated: ", - sizeof(result) - strlen(result) -1); - strncat(result, - strerror(ERANGE), - sizeof(result) - strlen(result) -1); - strncat(result, - "\n", - sizeof(result) - strlen(result) -1); - } - - /* Symlink to above file. */ - if (canSymlink()) { - assertMakeSymlink("symlink", "file", 0); - fprintf(filelist, "symlink\n"); - if (is_LargeInode("symlink")) { - strncat(result, - "bsdcpio: symlink: large inode number truncated: ", - sizeof(result) - strlen(result) -1); - strncat(result, - strerror(ERANGE), - sizeof(result) - strlen(result) -1); - strncat(result, - "\n", - sizeof(result) - strlen(result) -1); - } - } - - /* Another file with different permissions. */ - assertMakeFile("file2", 0777, "1234567890"); - fprintf(filelist, "file2\n"); - if (is_LargeInode("file2")) { - strncat(result, - "bsdcpio: file2: large inode number truncated: ", - sizeof(result) - strlen(result) -1); - strncat(result, - strerror(ERANGE), - sizeof(result) - strlen(result) -1); - strncat(result, - "\n", - sizeof(result) - strlen(result) -1); - } - - /* Directory. */ - assertMakeDir("dir", 0775); - fprintf(filelist, "dir\n"); - if (is_LargeInode("dir")) { - strncat(result, - "bsdcpio: dir: large inode number truncated: ", - sizeof(result) - strlen(result) -1); - strncat(result, - strerror(ERANGE), - sizeof(result) - strlen(result) -1); - strncat(result, - "\n", - sizeof(result) - strlen(result) -1); - } - strncat(result, "2 blocks\n", sizeof(result) - strlen(result) -1); - - /* All done. */ - fclose(filelist); - - assertUmask(022); - - /* Archive/dearchive with a variety of options. */ - msg = canSymlink() ? "2 blocks\n" : "1 block\n"; - basic_cpio("copy", "", "", msg, msg); - basic_cpio("copy_odc", "--format=odc", "", msg, msg); - basic_cpio("copy_newc", "-H newc", "", result, "2 blocks\n"); - basic_cpio("copy_cpio", "-H odc", "", msg, msg); - msg = "1 block\n"; - basic_cpio("copy_bin", "-H bin", "", msg, msg); - msg = canSymlink() ? "9 blocks\n" : "8 blocks\n"; - basic_cpio("copy_ustar", "-H ustar", "", msg, msg); - - /* Copy in one step using -p */ - passthrough("passthrough"); -} diff --git a/thirdparty/libarchive/cpio/test/test_cmdline.c b/thirdparty/libarchive/cpio/test/test_cmdline.c deleted file mode 100644 index 2dd7d651d..000000000 --- a/thirdparty/libarchive/cpio/test/test_cmdline.c +++ /dev/null @@ -1,107 +0,0 @@ -/*- - * Copyright (c) 2003-2009 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* - * Test the command-line parsing. - */ - -DEFINE_TEST(test_cmdline) -{ - FILE *f; - - /* Create an empty file. */ - f = fopen("empty", "wb"); - assert(f != NULL); - fclose(f); - - failure("-Q is an invalid option on every cpio program I know of"); - assert(0 != systemf("%s -i -Q 1.out 2>1.err", testprog)); - assertEmptyFile("1.out"); - - failure("-f requires an argument"); - assert(0 != systemf("%s -if 2.out 2>2.err", testprog)); - assertEmptyFile("2.out"); - - failure("-f requires an argument"); - assert(0 != systemf("%s -i -f 3.out 2>3.err", testprog)); - assertEmptyFile("3.out"); - - failure("--format requires an argument"); - assert(0 != systemf("%s -i --format 4.out 2>4.err", testprog)); - assertEmptyFile("4.out"); - - failure("--badopt is an invalid option"); - assert(0 != systemf("%s -i --badop 5.out 2>5.err", testprog)); - assertEmptyFile("5.out"); - - failure("--badopt is an invalid option"); - assert(0 != systemf("%s -i --badopt 6.out 2>6.err", testprog)); - assertEmptyFile("6.out"); - - failure("--n is ambiguous"); - assert(0 != systemf("%s -i --n 7.out 2>7.err", testprog)); - assertEmptyFile("7.out"); - - failure("--create forbids an argument"); - assert(0 != systemf("%s --create=arg 8.out 2>8.err", testprog)); - assertEmptyFile("8.out"); - - failure("-i with empty input should succeed"); - assert(0 == systemf("%s -i 9.out 2>9.err", testprog)); - assertEmptyFile("9.out"); - - failure("-o with empty input should succeed"); - assert(0 == systemf("%s -o 10.out 2>10.err", testprog)); - - failure("-i -p is nonsense"); - assert(0 != systemf("%s -i -p 11.out 2>11.err", testprog)); - assertEmptyFile("11.out"); - - failure("-p -i is nonsense"); - assert(0 != systemf("%s -p -i 12.out 2>12.err", testprog)); - assertEmptyFile("12.out"); - - failure("-i -o is nonsense"); - assert(0 != systemf("%s -i -o 13.out 2>13.err", testprog)); - assertEmptyFile("13.out"); - - failure("-o -i is nonsense"); - assert(0 != systemf("%s -o -i 14.out 2>14.err", testprog)); - assertEmptyFile("14.out"); - - failure("-o -p is nonsense"); - assert(0 != systemf("%s -o -p 15.out 2>15.err", testprog)); - assertEmptyFile("15.out"); - - failure("-p -o is nonsense"); - assert(0 != systemf("%s -p -o 16.out 2>16.err", testprog)); - assertEmptyFile("16.out"); - - failure("-p with empty input should fail"); - assert(0 != systemf("%s -p 17.out 2>17.err", testprog)); - assertEmptyFile("17.out"); -} diff --git a/thirdparty/libarchive/cpio/test/test_extract.cpio.Z.uu b/thirdparty/libarchive/cpio/test/test_extract.cpio.Z.uu deleted file mode 100644 index e520a3416..000000000 --- a/thirdparty/libarchive/cpio/test/test_extract.cpio.Z.uu +++ /dev/null @@ -1,7 +0,0 @@ -begin 664 test_extract.cpio.Z -M'YV0,&X$'`B#!@P8,0XJC)$0A@T;!A'>J+%PHL*%%P_&D`%CAHP;!F7,B*C0 -M1L:+(LVD85,F!H`Q;]S0*2-S#H@W9D"H9!G#A8*!`@46U)A11L.'$6-8U+CT -M8D.G'#V"A"&#!L6+)D\>3+FRC(R7,6?6O)ESIU>?0`EJ7/'D!4# -` -end diff --git a/thirdparty/libarchive/cpio/test/test_extract.cpio.bz2.uu b/thirdparty/libarchive/cpio/test/test_extract.cpio.bz2.uu deleted file mode 100644 index 228a95775..000000000 --- a/thirdparty/libarchive/cpio/test/test_extract.cpio.bz2.uu +++ /dev/null @@ -1,7 +0,0 @@ -begin 664 test_extract.cpio.bz2 -M0EIH.3%!629365?=.4@``#G_@G*0(`#@`7^`(B04``LEC```!"``E`E(>I,H -M::'J&@_4C3:@E$AD#0&@&@%"E;V/1!XIP>#C9T[41`4PQ1A`@S*4F&BD@B0T -MBA$$-:\/@BQGNKU1G@%#`G+N0R%$JTHG(XBRB%1$V8F4#F_IWT=S4+ERVL(? -40V!'@1L4+AO_B[DBG"A(*^Z0,#J&)3G"\^YE?X_' -M_K._F':0[`DL%IQ=<,Z-JH>V$S,?.[`&42C7]J^XQ@9OY!Z$!$^JLQPKZU[: -/!M,+.$MY:Y(HS<<]U`&` -` -end diff --git a/thirdparty/libarchive/cpio/test/test_extract.cpio.gz.uu b/thirdparty/libarchive/cpio/test/test_extract.cpio.gz.uu deleted file mode 100644 index 7ddccad64..000000000 --- a/thirdparty/libarchive/cpio/test/test_extract.cpio.gz.uu +++ /dev/null @@ -1,7 +0,0 @@ -begin 664 test_extract.cpio.gz -M'XL("`5X2FE=2K)"? -MI@`6T>,R0+?$B$A+3$RQ6F*$88D1PA*"P!"[J#$2)R3(T=/'-4A149%AF`,` -(305ZBP`"```` -` -end diff --git a/thirdparty/libarchive/cpio/test/test_extract.cpio.lrz.uu b/thirdparty/libarchive/cpio/test/test_extract.cpio.lrz.uu deleted file mode 100644 index 563f79710..000000000 --- a/thirdparty/libarchive/cpio/test/test_extract.cpio.lrz.uu +++ /dev/null @@ -1,8 +0,0 @@ -begin 664 test_extract.cpio.lrz -M3%):20`&``(``````````%T````!`0```@$`$`,`````#@`#`````"\``QH` -M&@````!W``$G`&4``#,``2(``0``#0$````U<-`Y!F$`MP$````8#=\$8#<1 -MR/BL39$D4M>["H7&@4%L/4*_(*VGB*YU>?RX.9]HL86'.A)H@Y;Z\^$?M^8_ -M!/-;62G.*7*A&A!_ENZ8$7]O-M7_.FTRC%BCGC95:6'9ZH3)QSCR4RX42P!` -/-E>/7"L[:OY"/A924S4$ -` -end diff --git a/thirdparty/libarchive/cpio/test/test_extract.cpio.lz.uu b/thirdparty/libarchive/cpio/test/test_extract.cpio.lz.uu deleted file mode 100644 index 67e41e92f..000000000 --- a/thirdparty/libarchive/cpio/test/test_extract.cpio.lz.uu +++ /dev/null @@ -1,6 +0,0 @@ -begin 664 test_extract.cpio.lz -M3%I)4`$,`!@-WP1@-Q'(^*Q-D212U[L*A<:!06P]0K\@K:>(KG5Y_+@YGVBQ -MA8;_>8N3MLP="$0SJ#QKYB?@8 -G]@'$$7\&W^T*+9?6B=?__M$G@$T%>HL``@```````($````````` -` -end diff --git a/thirdparty/libarchive/cpio/test/test_extract.cpio.lz4.uu b/thirdparty/libarchive/cpio/test/test_extract.cpio.lz4.uu deleted file mode 100644 index 0adc7bbcc..000000000 --- a/thirdparty/libarchive/cpio/test/test_extract.cpio.lz4.uu +++ /dev/null @@ -1,7 +0,0 @@ -begin 644 test_extract.cpio.lz4 -M!")-&&1PN9$````A,#<"`&`P-#`P,3`!`&`Q,3`P-C8/`#0W-3`&```)``$& -M`,$P,3(P,S(W-#`R,S01`!$V!@```@#Q!3(S9FEL93$`8V]N=&5N=',@;V8@ -M$@`A+@IC``AE`!\R90`4$#2#``YE`!TR90`6,F4`#P(`#@+H``P"`"["H7&@4%L/4*_(*VGB*YU -M>?RX.9]HL86'.A)H@Y;Z\^$?M^8_!/-;62G.*7*A&A!_HGF_WF+D[;.+!OW3 -:T_2I)V(;K[FNL#'W%T+L;ATS`A*3__[1Z``` -` -end diff --git a/thirdparty/libarchive/cpio/test/test_extract.cpio.lzo.uu b/thirdparty/libarchive/cpio/test/test_extract.cpio.lzo.uu deleted file mode 100644 index 8ce87c798..000000000 --- a/thirdparty/libarchive/cpio/test/test_extract.cpio.lzo.uu +++ /dev/null @@ -1,9 +0,0 @@ -begin 664 test_extract.cpio.lzo -MB4Q:3P`-"AH*$#`@8`E``04#```!``"!M%!R>-T`````$71E`$#-S4P,#`QE`!@`7`#"C`P,3(P,S(W-#`R,S2!`C:4`'````(R,V9I;&4Q -M`&-O;G1E;G1S(&]F((8"+@HOD0$R(`:1`31J$#`P+I$!,B^1`3(HD`%L$3L, -M`+P<+HH`,3,I1``(5%)!24Q%4B$A(0`@JP````$````````````````````` -*````$0`````````` -` -end diff --git a/thirdparty/libarchive/cpio/test/test_extract.cpio.xz.uu b/thirdparty/libarchive/cpio/test/test_extract.cpio.xz.uu deleted file mode 100644 index 5c593cfeb..000000000 --- a/thirdparty/libarchive/cpio/test/test_extract.cpio.xz.uu +++ /dev/null @@ -1,7 +0,0 @@ -begin 664 test_extract.cpio.xz -M_3=Z6%H```3FUK1&`@`A`18```!T+^6CX`'_`&%=`!@-WP1@-Q'(^*Q-D212 -MU[L*A<:!06P]0K\@K:>(KG5Y_+@YGVBQA8;_>8N3MLXL&_=/3]*DG8ANON:ZP,?<70NQN'3"CP@``````J9FA -=#1$]4L<``7V`!`````?M;4JQQ&?[`@`````$65H` -` -end diff --git a/thirdparty/libarchive/cpio/test/test_extract.cpio.zst.uu b/thirdparty/libarchive/cpio/test/test_extract.cpio.zst.uu deleted file mode 100644 index 5ec854b85..000000000 --- a/thirdparty/libarchive/cpio/test/test_extract.cpio.zst.uu +++ /dev/null @@ -1,6 +0,0 @@ -begin 644 test_extract.cpio.zst -M*+4O_01090,`,@41%X")&@#'G6T\K16_MR)#=DK)5:.1,2J0HY2"!(1!`!7R -M$(UB`2"*D41;J2UF&)<0!Y7X'TU<%W.\W^R]GO-WW^OO^QX0`%P<]30-!#U` -?!KD!`#XP,_`U4`HT3+RF:#!7Y\V@R)5"7P"^;WEUK@`` -` -end diff --git a/thirdparty/libarchive/cpio/test/test_extract_cpio_Z.c b/thirdparty/libarchive/cpio/test/test_extract_cpio_Z.c deleted file mode 100644 index f908fc5b8..000000000 --- a/thirdparty/libarchive/cpio/test/test_extract_cpio_Z.c +++ /dev/null @@ -1,42 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_extract_cpio_Z) -{ - const char *reffile = "test_extract.cpio.Z"; - - extract_reference_file(reffile); - assertEqualInt(0, systemf("%s -i < %s >test.out 2>test.err", - testprog, reffile)); - - assertFileExists("file1"); - assertTextFileContents("contents of file1.\n", "file1"); - assertFileExists("file2"); - assertTextFileContents("contents of file2.\n", "file2"); - assertEmptyFile("test.out"); - assertTextFileContents("1 block\n", "test.err"); -} diff --git a/thirdparty/libarchive/cpio/test/test_extract_cpio_bz2.c b/thirdparty/libarchive/cpio/test/test_extract_cpio_bz2.c deleted file mode 100644 index 9525e63ae..000000000 --- a/thirdparty/libarchive/cpio/test/test_extract_cpio_bz2.c +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_extract_cpio_bz2) -{ - const char *reffile = "test_extract.cpio.bz2"; - int f; - - extract_reference_file(reffile); - f = systemf("%s -it < %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canBzip2()) { - assertEqualInt(0, systemf("%s -i < %s >test.out 2>test.err", - testprog, reffile)); - - assertFileExists("file1"); - assertTextFileContents("contents of file1.\n", "file1"); - assertFileExists("file2"); - assertTextFileContents("contents of file2.\n", "file2"); - assertEmptyFile("test.out"); - assertTextFileContents("1 block\n", "test.err"); - } else { - skipping("It seems bzip2 is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/cpio/test/test_extract_cpio_grz.c b/thirdparty/libarchive/cpio/test/test_extract_cpio_grz.c deleted file mode 100644 index f1a080597..000000000 --- a/thirdparty/libarchive/cpio/test/test_extract_cpio_grz.c +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_extract_cpio_grz) -{ - const char *reffile = "test_extract.cpio.grz"; - int f; - - extract_reference_file(reffile); - f = systemf("%s -it < %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canGrzip()) { - assertEqualInt(0, systemf("%s -i < %s >test.out 2>test.err", - testprog, reffile)); - - assertFileExists("file1"); - assertTextFileContents("contents of file1.\n", "file1"); - assertFileExists("file2"); - assertTextFileContents("contents of file2.\n", "file2"); - assertEmptyFile("test.out"); - assertTextFileContents("1 block\n", "test.err"); - } else { - skipping("It seems grzip is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/cpio/test/test_extract_cpio_gz.c b/thirdparty/libarchive/cpio/test/test_extract_cpio_gz.c deleted file mode 100644 index 19cee510c..000000000 --- a/thirdparty/libarchive/cpio/test/test_extract_cpio_gz.c +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_extract_cpio_gz) -{ - const char *reffile = "test_extract.cpio.gz"; - int f; - - extract_reference_file(reffile); - f = systemf("%s -it < %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canGzip()) { - assertEqualInt(0, systemf("%s -i < %s >test.out 2>test.err", - testprog, reffile)); - - assertFileExists("file1"); - assertTextFileContents("contents of file1.\n", "file1"); - assertFileExists("file2"); - assertTextFileContents("contents of file2.\n", "file2"); - assertEmptyFile("test.out"); - assertTextFileContents("1 block\n", "test.err"); - } else { - skipping("It seems gzip is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/cpio/test/test_extract_cpio_lrz.c b/thirdparty/libarchive/cpio/test/test_extract_cpio_lrz.c deleted file mode 100644 index 67667585e..000000000 --- a/thirdparty/libarchive/cpio/test/test_extract_cpio_lrz.c +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_extract_cpio_lrz) -{ - const char *reffile = "test_extract.cpio.lrz"; - int f; - - extract_reference_file(reffile); - f = systemf("%s -it < %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canLrzip()) { - assertEqualInt(0, systemf("%s -i < %s >test.out 2>test.err", - testprog, reffile)); - - assertFileExists("file1"); - assertTextFileContents("contents of file1.\n", "file1"); - assertFileExists("file2"); - assertTextFileContents("contents of file2.\n", "file2"); - assertEmptyFile("test.out"); - assertTextFileContents("1 block\n", "test.err"); - } else { - skipping("It seems lrzip is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/cpio/test/test_extract_cpio_lz.c b/thirdparty/libarchive/cpio/test/test_extract_cpio_lz.c deleted file mode 100644 index 4454e7b19..000000000 --- a/thirdparty/libarchive/cpio/test/test_extract_cpio_lz.c +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_extract_cpio_lz) -{ - const char *reffile = "test_extract.cpio.lz"; - int f; - - extract_reference_file(reffile); - f = systemf("%s -it < %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canLzip()) { - assertEqualInt(0, systemf("%s -i < %s >test.out 2>test.err", - testprog, reffile)); - - assertFileExists("file1"); - assertTextFileContents("contents of file1.\n", "file1"); - assertFileExists("file2"); - assertTextFileContents("contents of file2.\n", "file2"); - assertEmptyFile("test.out"); - assertTextFileContents("1 block\n", "test.err"); - } else { - skipping("It seems lzip is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/cpio/test/test_extract_cpio_lz4.c b/thirdparty/libarchive/cpio/test/test_extract_cpio_lz4.c deleted file mode 100644 index c16247be2..000000000 --- a/thirdparty/libarchive/cpio/test/test_extract_cpio_lz4.c +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2012,2014 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_extract_cpio_lz4) -{ - const char *reffile = "test_extract.cpio.lz4"; - int f; - - extract_reference_file(reffile); - f = systemf("%s -it < %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canLz4()) { - assertEqualInt(0, systemf("%s -i < %s >test.out 2>test.err", - testprog, reffile)); - - assertFileExists("file1"); - assertTextFileContents("contents of file1.\n", "file1"); - assertFileExists("file2"); - assertTextFileContents("contents of file2.\n", "file2"); - assertEmptyFile("test.out"); - assertTextFileContents("1 block\n", "test.err"); - } else { - skipping("It seems lz4 is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/cpio/test/test_extract_cpio_lzma.c b/thirdparty/libarchive/cpio/test/test_extract_cpio_lzma.c deleted file mode 100644 index ae630d611..000000000 --- a/thirdparty/libarchive/cpio/test/test_extract_cpio_lzma.c +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_extract_cpio_lzma) -{ - const char *reffile = "test_extract.cpio.lzma"; - int f; - - extract_reference_file(reffile); - f = systemf("%s -it < %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canLzma()) { - assertEqualInt(0, systemf("%s -i < %s >test.out 2>test.err", - testprog, reffile)); - - assertFileExists("file1"); - assertTextFileContents("contents of file1.\n", "file1"); - assertFileExists("file2"); - assertTextFileContents("contents of file2.\n", "file2"); - assertEmptyFile("test.out"); - assertTextFileContents("1 block\n", "test.err"); - } else { - skipping("It seems lzma is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/cpio/test/test_extract_cpio_lzo.c b/thirdparty/libarchive/cpio/test/test_extract_cpio_lzo.c deleted file mode 100644 index 99476af95..000000000 --- a/thirdparty/libarchive/cpio/test/test_extract_cpio_lzo.c +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_extract_cpio_lzo) -{ - const char *reffile = "test_extract.cpio.lzo"; - int f; - - extract_reference_file(reffile); - f = systemf("%s -it < %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canLzop()) { - assertEqualInt(0, systemf("%s -i < %s >test.out 2>test.err", - testprog, reffile)); - - assertFileExists("file1"); - assertTextFileContents("contents of file1.\n", "file1"); - assertFileExists("file2"); - assertTextFileContents("contents of file2.\n", "file2"); - assertEmptyFile("test.out"); - assertTextFileContents("1 block\n", "test.err"); - } else { - skipping("It seems lzop is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/cpio/test/test_extract_cpio_xz.c b/thirdparty/libarchive/cpio/test/test_extract_cpio_xz.c deleted file mode 100644 index 60f1b5a9d..000000000 --- a/thirdparty/libarchive/cpio/test/test_extract_cpio_xz.c +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_extract_cpio_xz) -{ - const char *reffile = "test_extract.cpio.xz"; - int f; - - extract_reference_file(reffile); - f = systemf("%s -it < %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canXz()) { - assertEqualInt(0, systemf("%s -i < %s >test.out 2>test.err", - testprog, reffile)); - - assertFileExists("file1"); - assertTextFileContents("contents of file1.\n", "file1"); - assertFileExists("file2"); - assertTextFileContents("contents of file2.\n", "file2"); - assertEmptyFile("test.out"); - assertTextFileContents("1 block\n", "test.err"); - } else { - skipping("It seems xz is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/cpio/test/test_extract_cpio_zstd.c b/thirdparty/libarchive/cpio/test/test_extract_cpio_zstd.c deleted file mode 100644 index 289f33d05..000000000 --- a/thirdparty/libarchive/cpio/test/test_extract_cpio_zstd.c +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2017 Sean Purcell - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_extract_cpio_zstd) -{ - const char *reffile = "test_extract.cpio.zst"; - int f; - - extract_reference_file(reffile); - f = systemf("%s -it < %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canZstd()) { - assertEqualInt(0, systemf("%s -i < %s >test.out 2>test.err", - testprog, reffile)); - - assertFileExists("file1"); - assertTextFileContents("contents of file1.\n", "file1"); - assertFileExists("file2"); - assertTextFileContents("contents of file2.\n", "file2"); - assertEmptyFile("test.out"); - assertTextFileContents("1 block\n", "test.err"); - } else { - skipping("It seems zstd is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/cpio/test/test_format_newc.c b/thirdparty/libarchive/cpio/test/test_format_newc.c deleted file mode 100644 index 6e3b9e359..000000000 --- a/thirdparty/libarchive/cpio/test/test_format_newc.c +++ /dev/null @@ -1,358 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/usr.bin/cpio/test/test_format_newc.c,v 1.2 2008/08/22 02:09:10 kientzle Exp $"); - -/* Number of bytes needed to pad 'n' to multiple of 'block', assuming - * that 'block' is a power of two. This trick can be more easily - * remembered as -n & (block - 1), but many compilers quite reasonably - * warn about "-n" when n is an unsigned value. (~(n) + 1) is the - * same thing, but written in a way that won't offend anyone. */ -#define PAD(n, block) ((~(n) + 1) & ((block) - 1)) - -static int -is_hex(const char *p, size_t l) -{ - while (l > 0) { - if ((*p >= '0' && *p <= '9') - || (*p >= 'a' && *p <= 'f') - || (*p >= 'A' && *p <= 'F')) - { - --l; - ++p; - } else - return (0); - - } - return (1); -} - -/* Convert up to 8 hex characters to unsigned 32-bit decimal integer */ -static uint32_t -from_hex(const char *p, size_t l) -{ - uint32_t r = 0; - - while (l > 0) { - r *= 16; - if (*p >= 'a' && *p <= 'f') - r += *p + 10 - 'a'; - else if (*p >= 'A' && *p <= 'F') - r += *p + 10 - 'A'; - else - r += *p - '0'; - --l; - ++p; - } - return (r); -} - -#if !defined(_WIN32) || defined(__CYGWIN__) -static int -nlinks(const char *p) -{ - struct stat st; - assertEqualInt(0, stat(p, &st)); - return st.st_nlink; -} -#endif - -DEFINE_TEST(test_format_newc) -{ - FILE *list; - int r; - uint32_t devmajor, devminor, ino, gid, uid; - time_t t, t2, now; - char *p, *e; - size_t s; - uint64_t fs, ns; - char result[1024]; - - assertUmask(0); - -#if !defined(_WIN32) - uid = getuid(); -#endif - - /* - * Create an assortment of files. - * TODO: Extend this to cover more filetypes. - */ - list = fopen("list", "w"); - - /* "file1" */ - assertMakeFile("file1", 0644, "1234567890"); - fprintf(list, "file1\n"); - - /* "hardlink" */ - assertMakeHardlink("hardlink", "file1"); - fprintf(list, "hardlink\n"); - - /* Another hardlink, but this one won't be archived. */ - assertMakeHardlink("hardlink2", "file1"); - - /* "symlink" */ - if (canSymlink()) { - assertMakeSymlink("symlink", "file1", 0); - fprintf(list, "symlink\n"); - } - - /* "dir" */ - assertMakeDir("dir", 0775); - fprintf(list, "dir\n"); - - /* Setup result message. */ - memset(result, 0, sizeof(result)); - if (is_LargeInode("file1")) { - strncat(result, - "bsdcpio: file1: large inode number truncated: ", - sizeof(result) - strlen(result) -1); - strncat(result, strerror(ERANGE), - sizeof(result) - strlen(result) -1); - strncat(result, "\n", - sizeof(result) - strlen(result) -1); - } - if (canSymlink() && is_LargeInode("symlink")) { - strncat(result, - "bsdcpio: symlink: large inode number truncated: ", - sizeof(result) - strlen(result) -1); - strncat(result, strerror(ERANGE), - sizeof(result) - strlen(result) -1); - strncat(result, "\n", - sizeof(result) - strlen(result) -1); - } - if (is_LargeInode("dir")) { - strncat(result, - "bsdcpio: dir: large inode number truncated: ", - sizeof(result) - strlen(result) -1); - strncat(result, strerror(ERANGE), - sizeof(result) - strlen(result) -1); - strncat(result, "\n", - sizeof(result) - strlen(result) -1); - } - if (is_LargeInode("hardlink")) { - strncat(result, - "bsdcpio: hardlink: large inode number truncated: ", - sizeof(result) - strlen(result) -1); - strncat(result, strerror(ERANGE), - sizeof(result) - strlen(result) -1); - strncat(result, "\n", - sizeof(result) - strlen(result) -1); - } - - /* Record some facts about what we just created: */ - now = time(NULL); /* They were all created w/in last two seconds. */ - - /* Use the cpio program to create an archive. */ - fclose(list); - r = systemf("%s -o --format=newc newc.out 2>newc.err", - testprog); - if (!assertEqualInt(r, 0)) - return; - - /* Verify that nothing went to stderr. */ - if (canSymlink()) { - strncat(result, "2 blocks\n", sizeof(result) - strlen(result) -1); - } else { - strncat(result, "1 block\n", sizeof(result) - strlen(result) -1); - } - assertTextFileContents(result, "newc.err"); - - /* Verify that stdout is a well-formed cpio file in "newc" format. */ - p = slurpfile(&s, "newc.out"); - assertEqualInt(s, canSymlink() ? 1024 : 512); - e = p; - - /* - * Some of these assertions could be stronger, but it's - * a little tricky because they depend on the local environment. - */ - - /* First entry is "file1" */ - assert(is_hex(e, 110)); /* Entire header is octal digits. */ - assertEqualMem(e + 0, "070701", 6); /* Magic */ - ino = from_hex(e + 6, 8); /* ino */ -#if defined(_WIN32) && !defined(__CYGWIN__) - /* Group members bits and others bits do not work. */ - assertEqualInt(0x8180, from_hex(e + 14, 8) & 0xffc0); /* Mode */ -#else - assertEqualInt(0x81a4, from_hex(e + 14, 8)); /* Mode */ -#endif -#if defined(_WIN32) - uid = from_hex(e + 22, 8); -#else - assertEqualInt(from_hex(e + 22, 8), uid); /* uid */ -#endif - gid = from_hex(e + 30, 8); /* gid */ - assertEqualMem(e + 38, "00000003", 8); /* nlink */ - t = from_hex(e + 46, 8); /* mtime */ - failure("t=%#08jx now=%#08jx=%jd", (intmax_t)t, (intmax_t)now, - (intmax_t)now); - assert(t <= now); /* File wasn't created in future. */ - failure("t=%#08jx now - 2=%#08jx=%jd", (intmax_t)t, (intmax_t)now - 2, - (intmax_t)now - 2); - assert(t >= now - 2); /* File was created w/in last 2 secs. */ - failure("newc format stores body only with last appearance of a link\n" - " first appearance should be empty, so this file size\n" - " field should be zero"); - assertEqualInt(0, from_hex(e + 54, 8)); /* File size */ - fs = (uint64_t)from_hex(e + 54, 8); - fs += PAD(fs, 4); - devmajor = from_hex(e + 62, 8); /* devmajor */ - devminor = from_hex(e + 70, 8); /* devminor */ - assert(is_hex(e + 78, 8)); /* rdevmajor */ - assert(is_hex(e + 86, 8)); /* rdevminor */ - assertEqualMem(e + 94, "00000006", 8); /* Name size */ - ns = (uint64_t)from_hex(e + 94, 8); - ns += PAD(ns + 2, 4); - assertEqualInt(0, from_hex(e + 102, 8)); /* check field */ - assertEqualMem(e + 110, "file1\0", 6); /* Name contents */ - /* Since there's another link, no file contents here. */ - /* But add in file size so that an error here doesn't cascade. */ - e += 110 + fs + ns; - - if (canSymlink()) { - /* "symlink" pointing to "file1" */ - assert(is_hex(e, 110)); - assertEqualMem(e + 0, "070701", 6); /* Magic */ - assert(is_hex(e + 6, 8)); /* ino */ -#if defined(_WIN32) && !defined(CYGWIN) - /* Mode: Group members bits and others bits do not work. */ - assertEqualInt(0xa180, from_hex(e + 14, 8) & 0xffc0); -#else - assertEqualInt(0xa1ff, from_hex(e + 14, 8)); /* Mode */ -#endif - assertEqualInt(from_hex(e + 22, 8), uid); /* uid */ - assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */ - assertEqualMem(e + 38, "00000001", 8); /* nlink */ - t2 = from_hex(e + 46, 8); /* mtime */ - failure("First entry created at t=%#08jx this entry created" - " at t2=%#08jx", (intmax_t)t, (intmax_t)t2); - assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */ - assertEqualMem(e + 54, "00000005", 8); /* File size */ - fs = (uint64_t)from_hex(e + 54, 8); - fs += PAD(fs, 4); - assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */ - assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */ - assert(is_hex(e + 78, 8)); /* rdevmajor */ - assert(is_hex(e + 86, 8)); /* rdevminor */ - assertEqualMem(e + 94, "00000008", 8); /* Name size */ - ns = (uint64_t)from_hex(e + 94, 8); - ns += PAD(ns + 2, 4); - assertEqualInt(0, from_hex(e + 102, 8)); /* check field */ - assertEqualMem(e + 110, "symlink\0\0\0", 10); /* Name contents */ - assertEqualMem(e + 110 + ns, "file1\0\0\0", 8); /* symlink target */ - e += 110 + fs + ns; - } - - /* "dir" */ - assert(is_hex(e, 110)); - assertEqualMem(e + 0, "070701", 6); /* Magic */ - assert(is_hex(e + 6, 8)); /* ino */ -#if defined(_WIN32) && !defined(__CYGWIN__) - /* Group members bits and others bits do not work. */ - assertEqualInt(0x41c0, from_hex(e + 14, 8) & 0xffc0); /* Mode */ -#else - /* Mode: sgid bit sometimes propagates from parent dirs, ignore it. */ - assertEqualInt(040775, from_hex(e + 14, 8) & ~02000); -#endif - assertEqualInt(uid, from_hex(e + 22, 8)); /* uid */ - assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */ -#if !defined(_WIN32) || defined(__CYGWIN__) - assertEqualInt(nlinks("dir"), from_hex(e + 38, 8)); /* nlinks */ -#endif - t2 = from_hex(e + 46, 8); /* mtime */ - failure("First entry created at t=%#08jx this entry created at" - "t2=%#08jx", (intmax_t)t, (intmax_t)t2); - assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */ - assertEqualMem(e + 54, "00000000", 8); /* File size */ - fs = (uint64_t)from_hex(e + 54, 8); - fs += PAD(fs, 4); - assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */ - assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */ - assert(is_hex(e + 78, 8)); /* rdevmajor */ - assert(is_hex(e + 86, 8)); /* rdevminor */ - assertEqualMem(e + 94, "00000004", 8); /* Name size */ - ns = (uint64_t)from_hex(e + 94, 8); - ns += PAD(ns + 2, 4); - assertEqualInt(0, from_hex(e + 102, 8)); /* check field */ - assertEqualMem(e + 110, "dir\0\0\0", 6); /* Name contents */ - e += 110 + fs + ns; - - /* Hardlink identical to "file1" */ - /* Since we only wrote two of the three links to this - * file, this link should get deferred by the hardlink logic. */ - assert(is_hex(e, 110)); - assertEqualMem(e + 0, "070701", 6); /* Magic */ - failure("If these aren't the same, then the hardlink detection failed to match them."); - assertEqualInt(ino, from_hex(e + 6, 8)); /* ino */ -#if defined(_WIN32) && !defined(__CYGWIN__) - /* Group members bits and others bits do not work. */ - assertEqualInt(0x8180, from_hex(e + 14, 8) & 0xffc0); /* Mode */ -#else - assertEqualInt(0x81a4, from_hex(e + 14, 8)); /* Mode */ -#endif - assertEqualInt(from_hex(e + 22, 8), uid); /* uid */ - assertEqualInt(gid, from_hex(e + 30, 8)); /* gid */ - assertEqualMem(e + 38, "00000003", 8); /* nlink */ - t2 = from_hex(e + 46, 8); /* mtime */ - failure("First entry created at t=%#08jx this entry created at" - "t2=%#08jx", (intmax_t)t, (intmax_t)t2); - assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */ - assertEqualInt(10, from_hex(e + 54, 8)); /* File size */ - fs = (uint64_t)from_hex(e + 54, 8); - fs += PAD(fs, 4); - assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */ - assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */ - assert(is_hex(e + 78, 8)); /* rdevmajor */ - assert(is_hex(e + 86, 8)); /* rdevminor */ - assertEqualMem(e + 94, "00000009", 8); /* Name size */ - ns = (uint64_t)from_hex(e + 94, 8); - ns += PAD(ns + 2, 4); - assertEqualInt(0, from_hex(e + 102, 8)); /* check field */ - assertEqualMem(e + 110, "hardlink\0\0", 10); /* Name contents */ - assertEqualMem(e + 110 + ns, "1234567890\0\0", 12); /* File contents */ - e += 110 + ns + fs; - - /* Last entry is end-of-archive marker. */ - assert(is_hex(e, 110)); - assertEqualMem(e + 0, "070701", 6); /* Magic */ - assertEqualMem(e + 8, "00000000", 8); /* ino */ - assertEqualMem(e + 14, "00000000", 8); /* mode */ - assertEqualMem(e + 22, "00000000", 8); /* uid */ - assertEqualMem(e + 30, "00000000", 8); /* gid */ - assertEqualMem(e + 38, "00000001", 8); /* nlink */ - assertEqualMem(e + 46, "00000000", 8); /* mtime */ - assertEqualMem(e + 54, "00000000", 8); /* size */ - assertEqualMem(e + 62, "00000000", 8); /* devmajor */ - assertEqualMem(e + 70, "00000000", 8); /* devminor */ - assertEqualMem(e + 78, "00000000", 8); /* rdevmajor */ - assertEqualMem(e + 86, "00000000", 8); /* rdevminor */ - assertEqualInt(11, from_hex(e + 94, 8)); /* name size */ - assertEqualMem(e + 102, "00000000", 8); /* check field */ - assertEqualMem(e + 110, "TRAILER!!!\0\0", 12); /* Name */ - - free(p); -} diff --git a/thirdparty/libarchive/cpio/test/test_gcpio_compat.c b/thirdparty/libarchive/cpio/test/test_gcpio_compat.c deleted file mode 100644 index 9bb988990..000000000 --- a/thirdparty/libarchive/cpio/test/test_gcpio_compat.c +++ /dev/null @@ -1,108 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/usr.bin/cpio/test/test_gcpio_compat.c,v 1.2 2008/08/22 02:27:06 kientzle Exp $"); - -static void -unpack_test(const char *from, const char *options, const char *se) -{ - int r; - - /* Create a work dir named after the file we're unpacking. */ - assertMakeDir(from, 0775); - assertChdir(from); - - /* - * Use cpio to unpack the sample archive - */ - extract_reference_file(from); - r = systemf("%s -i %s < %s >unpack.out 2>unpack.err", - testprog, options, from); - failure("Error invoking %s -i %s < %s", - testprog, options, from); - assertEqualInt(r, 0); - - /* Verify that nothing went to stderr. */ - if (canSymlink()) { - failure("Error invoking %s -i %s < %s", - testprog, options, from); - assertTextFileContents(se, "unpack.err"); - } - - /* - * Verify unpacked files. - */ - - /* Regular file with 2 links. */ - assertIsReg("file", 0644); - failure("%s", from); - assertFileSize("file", 10); - assertFileSize("linkfile", 10); - failure("%s", from); - assertFileNLinks("file", 2); - - /* Another name for the same file. */ - failure("%s", from); - assertIsHardlink("linkfile", "file"); - assertFileSize("file", 10); - assertFileSize("linkfile", 10); - - /* Symlink */ - if (canSymlink()) - assertIsSymlink("symlink", "file", 0); - - /* dir */ - assertIsDir("dir", 0775); - - assertChdir(".."); -} - -DEFINE_TEST(test_gcpio_compat) -{ - assertUmask(0); - - /* Dearchive sample files with a variety of options. */ - if (canSymlink()) { - unpack_test("test_gcpio_compat_ref.bin", - "--no-preserve-owner", "1 block\n"); - unpack_test("test_gcpio_compat_ref.crc", - "--no-preserve-owner", "2 blocks\n"); - unpack_test("test_gcpio_compat_ref.newc", - "--no-preserve-owner", "2 blocks\n"); - /* gcpio-2.9 only reads 6 blocks here */ - unpack_test("test_gcpio_compat_ref.ustar", - "--no-preserve-owner", "7 blocks\n"); - } else { - unpack_test("test_gcpio_compat_ref_nosym.bin", - "--no-preserve-owner", "1 block\n"); - unpack_test("test_gcpio_compat_ref_nosym.crc", - "--no-preserve-owner", "2 blocks\n"); - unpack_test("test_gcpio_compat_ref_nosym.newc", - "--no-preserve-owner", "2 blocks\n"); - /* gcpio-2.9 only reads 6 blocks here */ - unpack_test("test_gcpio_compat_ref_nosym.ustar", - "--no-preserve-owner", "7 blocks\n"); - } -} diff --git a/thirdparty/libarchive/cpio/test/test_gcpio_compat_ref.bin.uu b/thirdparty/libarchive/cpio/test/test_gcpio_compat_ref.bin.uu deleted file mode 100644 index 745d8ab78..000000000 --- a/thirdparty/libarchive/cpio/test/test_gcpio_compat_ref.bin.uu +++ /dev/null @@ -1,16 +0,0 @@ -$FreeBSD$ -begin 644 test_gcpio_compat_ref.bin -MQW%9`*IWI('H`^@#`@````U'=YD%````"@!F:6QE```Q,C,T-38W.#D*QW%9 -M`*IWI('H`^@#`@````U'=YD)````"@!L:6YK9FEL90``,3(S-#4V-S@Y"L=Q -M60"K=^VAZ`/H`P$````-1X29"`````0`stdout1 2>stderr1", testprog); - assertEqualInt(r, 0); - assertTextFileContents("1 block\n", "stderr1"); - - assertMakeFile("filelist2", 0644, "file1\nfile2\nfile3\n"); - r = systemf("%s -o stdout2 2>stderr2", testprog); - assert(r != 0); - - assertMakeFile("filelist3", 0644, ""); - r = systemf("%s -o stdout3 2>stderr3", testprog); - assertEqualInt(r, 0); - assertTextFileContents("1 block\n", "stderr3"); - - assertMakeFile("filelist4", 0644, "file3\n"); - r = systemf("%s -o stdout4 2>stderr4", testprog); - assert(r != 0); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_0.c b/thirdparty/libarchive/cpio/test/test_option_0.c deleted file mode 100644 index bc4aecd2a..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_0.c +++ /dev/null @@ -1,92 +0,0 @@ -/*- - * Copyright (c) 2003-2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_0) -{ - FILE *filelist; - int r; - - assertUmask(0); - - /* Create a few files. */ - assertMakeFile("file1", 0644, "1234567890"); - assertMakeFile("file2", 0644, "1234567890"); - assertMakeFile("file3", 0644, "1234567890"); - assertMakeFile("file4", 0644, "1234567890"); - - /* Create a file list of filenames with varying end-of-line. */ - filelist = fopen("filelist", "wb"); - assertEqualInt(fwrite("file1\x0a", 1, 6, filelist), 6); - assertEqualInt(fwrite("file2\x0d", 1, 6, filelist), 6); - assertEqualInt(fwrite("file3\x0a\x0d", 1, 7, filelist), 7); - assertEqualInt(fwrite("file4", 1, 5, filelist), 5); - fclose(filelist); - - /* Create a file list of null-delimited names. */ - filelist = fopen("filelistNull", "wb"); - assertEqualInt(fwrite("file1\0", 1, 6, filelist), 6); - assertEqualInt(fwrite("file2\0", 1, 6, filelist), 6); - assertEqualInt(fwrite("file3\0", 1, 6, filelist), 6); - assertEqualInt(fwrite("file4", 1, 5, filelist), 5); - fclose(filelist); - - assertUmask(022); - - /* Pack up using the file list with text line endings. */ - r = systemf("%s -o < filelist > archive 2> stderr1.txt", testprog); - assertEqualInt(r, 0); - - /* Extract into a new dir. */ - assertMakeDir("copy", 0775); - assertChdir("copy"); - r = systemf("%s -i < ../archive > stdout3.txt 2> stderr3.txt", testprog); - assertEqualInt(r, 0); - - /* Verify the files. */ - assertIsReg("file1", 0644); - assertIsReg("file2", 0644); - assertIsReg("file3", 0644); - assertIsReg("file4", 0644); - - assertChdir(".."); - - /* Pack up using the file list with nulls. */ - r = systemf("%s -o0 < filelistNull > archiveNull 2> stderr2.txt", testprog); - assertEqualInt(r, 0); - - /* Extract into a new dir. */ - assertMakeDir("copyNull", 0775); - assertChdir("copyNull"); - r = systemf("%s -i < ../archiveNull > stdout4.txt 2> stderr4.txt", testprog); - assertEqualInt(r, 0); - - /* Verify the files. */ - assertIsReg("file1", 0644); - assertIsReg("file2", 0644); - assertIsReg("file3", 0644); - assertIsReg("file4", 0644); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_B_upper.c b/thirdparty/libarchive/cpio/test/test_option_B_upper.c deleted file mode 100644 index b040354b6..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_B_upper.c +++ /dev/null @@ -1,52 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - - -DEFINE_TEST(test_option_B_upper) -{ - struct stat st; - int r; - - /* - * Create a file on disk. - */ - assertMakeFile("file", 0644, NULL); - - /* Create an archive without -B; this should be 512 bytes. */ - r = systemf("echo file | %s -o > small.cpio 2>small.err", testprog); - assertEqualInt(r, 0); - assertTextFileContents("1 block\n", "small.err"); - assertEqualInt(0, stat("small.cpio", &st)); - assertEqualInt(512, st.st_size); - - /* Create an archive with -B; this should be 5120 bytes. */ - r = systemf("echo file | %s -oB > large.cpio 2>large.err", testprog); - assertEqualInt(r, 0); - assertTextFileContents("1 block\n", "large.err"); - assertEqualInt(0, stat("large.cpio", &st)); - assertEqualInt(5120, st.st_size); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_C_upper.c b/thirdparty/libarchive/cpio/test/test_option_C_upper.c deleted file mode 100644 index c8e63fd34..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_C_upper.c +++ /dev/null @@ -1,62 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - - -DEFINE_TEST(test_option_C_upper) -{ - int r; - - /* - * Create a file on disk. - */ - assertMakeFile("file", 0644, NULL); - - /* Create an archive without -C; this should be 512 bytes. */ - r = systemf("echo file | %s -o > small.cpio 2>small.err", testprog); - assertEqualInt(r, 0); - assertTextFileContents("1 block\n", "small.err"); - assertFileSize("small.cpio", 512); - - /* Create an archive with -C 513; this should be 513 bytes. */ - r = systemf("echo file | %s -o -C 513 > 513.cpio 2>513.err", - testprog); - assertEqualInt(r, 0); - assertTextFileContents("1 block\n", "513.err"); - assertFileSize("513.cpio", 513); - - /* Create an archive with -C 12345; this should be 12345 bytes. */ - r = systemf("echo file | %s -o -C12345 > 12345.cpio 2>12345.err", - testprog); - assertEqualInt(r, 0); - assertTextFileContents("1 block\n", "12345.err"); - assertFileSize("12345.cpio", 12345); - - /* Create an archive with invalid -C request */ - assert(0 != systemf("echo file | %s -o -C > bad.cpio 2>bad.err", - testprog)); - assertEmptyFile("bad.cpio"); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_J_upper.c b/thirdparty/libarchive/cpio/test/test_option_J_upper.c deleted file mode 100644 index e19d599e1..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_J_upper.c +++ /dev/null @@ -1,60 +0,0 @@ -/*- - * Copyright (c) 2003-2009 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_J_upper) -{ - char *p; - int r; - size_t s; - - /* Create a file. */ - assertMakeFile("f", 0644, "a"); - - /* Archive it with xz compression. */ - r = systemf("echo f | %s -o -J >archive.out 2>archive.err", - testprog); - p = slurpfile(&s, "archive.err"); - p[s] = '\0'; - if (r != 0) { - if (strstr(p, "compression not available") != NULL) { - skipping("This version of bsdcpio was compiled " - "without xz support"); - free(p); - return; - } - failure("-J option is broken"); - assertEqualInt(r, 0); - goto done; - } - free(p); - /* Check that the archive file has an xz signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 2); - assertEqualMem(p, "\3757zXZ", 5); -done: - free(p); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_L_upper.c b/thirdparty/libarchive/cpio/test/test_option_L_upper.c deleted file mode 100644 index cab41b61d..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_L_upper.c +++ /dev/null @@ -1,105 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/usr.bin/cpio/test/test_option_L.c,v 1.2 2008/08/24 06:21:00 kientzle Exp $"); - -/* This is a little pointless, as Windows doesn't support symlinks - * (except for the seriously crippled CreateSymbolicLink API) so these - * tests won't run on Windows. */ -#if defined(_WIN32) && !defined(__CYGWIN__) -#define CAT "type" -#define SEP "\\" -#else -#define CAT "cat" -#define SEP "/" -#endif - -DEFINE_TEST(test_option_L_upper) -{ - FILE *filelist; - int r; - - if (!canSymlink()) { - skipping("Symlink tests"); - return; - } - - filelist = fopen("filelist", "w"); - - /* Create a file and a symlink to the file. */ - assertMakeFile("file", 0644, "1234567890"); - fprintf(filelist, "file\n"); - - /* Symlink to above file. */ - assertMakeSymlink("symlink", "file", 0); - fprintf(filelist, "symlink\n"); - - fclose(filelist); - - r = systemf(CAT " filelist | %s -pd copy >copy.out 2>copy.err", testprog); - assertEqualInt(r, 0); - assertTextFileContents("1 block\n", "copy.err"); - - failure("Regular -p without -L should preserve symlinks."); - assertIsSymlink("copy/symlink", NULL, 0); - - r = systemf(CAT " filelist | %s -pd -L copy-L >copy-L.out 2>copy-L.err", testprog); - assertEqualInt(r, 0); - assertEmptyFile("copy-L.out"); - assertTextFileContents("1 block\n", "copy-L.err"); - failure("-pdL should dereference symlinks and turn them into files."); - assertIsReg("copy-L/symlink", -1); - - r = systemf(CAT " filelist | %s -o >archive.out 2>archive.err", testprog); - failure("Error invoking %s -o ", testprog); - assertEqualInt(r, 0); - assertTextFileContents("1 block\n", "archive.err"); - - assertMakeDir("unpack", 0755); - assertChdir("unpack"); - r = systemf(CAT " .." SEP "archive.out | %s -i >unpack.out 2>unpack.err", testprog); - - failure("Error invoking %s -i", testprog); - assertEqualInt(r, 0); - assertTextFileContents("1 block\n", "unpack.err"); - assertChdir(".."); - - assertIsSymlink("unpack/symlink", NULL, 0); - - r = systemf(CAT " filelist | %s -oL >archive-L.out 2>archive-L.err", testprog); - failure("Error invoking %s -oL", testprog); - assertEqualInt(r, 0); - assertTextFileContents("1 block\n", "archive-L.err"); - - assertMakeDir("unpack-L", 0755); - assertChdir("unpack-L"); - r = systemf(CAT " .." SEP "archive-L.out | %s -i >unpack-L.out 2>unpack-L.err", testprog); - - failure("Error invoking %s -i < archive-L.out", testprog); - assertEqualInt(r, 0); - assertTextFileContents("1 block\n", "unpack-L.err"); - assertChdir(".."); - assertIsReg("unpack-L/symlink", -1); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_Z_upper.c b/thirdparty/libarchive/cpio/test/test_option_Z_upper.c deleted file mode 100644 index ff388427e..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_Z_upper.c +++ /dev/null @@ -1,60 +0,0 @@ -/*- - * Copyright (c) 2003-2009 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_Z_upper) -{ - char *p; - int r; - size_t s; - - /* Create a file. */ - assertMakeFile("f", 0644, "a"); - - /* Archive it with compress compression. */ - r = systemf("echo f | %s -oZ >archive.out 2>archive.err", - testprog); - p = slurpfile(&s, "archive.err"); - p[s] = '\0'; - if (r != 0) { - if (strstr(p, "compression not available") != NULL) { - skipping("This version of bsdcpio was compiled " - "without compress support"); - free(p); - return; - } - failure("-Z option is broken"); - assertEqualInt(r, 0); - free(p); - return; - } - free(p); - /* Check that the archive file has a compress signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 2); - assertEqualMem(p, "\x1f\x9d", 2); - free(p); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_a.c b/thirdparty/libarchive/cpio/test/test_option_a.c deleted file mode 100644 index e96bdf3ca..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_a.c +++ /dev/null @@ -1,160 +0,0 @@ -/*- - * Copyright (c) 2003-2008 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -#if defined(HAVE_UTIME_H) -#include -#elif defined(HAVE_SYS_UTIME_H) -#include -#endif -__FBSDID("$FreeBSD: src/usr.bin/cpio/test/test_option_a.c,v 1.3 2008/08/24 06:21:00 kientzle Exp $"); - -static struct { - const char *name; - time_t atime_sec; -} files[] = { - { "f0", 0 }, - { "f1", 0 }, - { "f2", 0 }, - { "f3", 0 }, - { "f4", 0 }, - { "f5", 0 } -}; - -/* - * Create a bunch of test files and record their atimes. - * For the atime preserve/change tests, the files must have - * atimes in the past. We can accomplish this by explicitly invoking - * utime() on platforms that support it or by simply sleeping - * for a second after creating the files. (Creating all of the files - * at once means we only need to sleep once.) - */ -static void -test_create(void) -{ - struct stat st; - struct utimbuf times; - static const int numfiles = sizeof(files) / sizeof(files[0]); - int i; - - for (i = 0; i < numfiles; ++i) { - /* - * Note: Have to write at least one byte to the file. - * cpio doesn't bother reading the file if it's zero length, - * so the atime never gets changed in that case, which - * makes the tests below rather pointless. - */ - assertMakeFile(files[i].name, 0644, "a"); - - /* If utime() isn't supported on your platform, just - * #ifdef this section out. Most of the test below is - * still valid. */ - memset(×, 0, sizeof(times)); -#if defined(_WIN32) && !defined(CYGWIN) - times.actime = 86400; - times.modtime = 86400; -#else - times.actime = 1; - times.modtime = 3; -#endif - assertEqualInt(0, utime(files[i].name, ×)); - - /* Record whatever atime the file ended up with. */ - /* If utime() is available, this should be 1, but there's - * no harm in being careful. */ - assertEqualInt(0, stat(files[i].name, &st)); - files[i].atime_sec = st.st_atime; - } - - /* Wait until the atime on the last file is actually in the past. */ - sleepUntilAfter(files[numfiles - 1].atime_sec); -} - -DEFINE_TEST(test_option_a) -{ - struct stat st; - int r; - char *p; - - /* Create all of the test files. */ - test_create(); - - /* Sanity check; verify that atimes really do get modified. */ - p = slurpfile(NULL, "f0"); - assert(p != NULL); - free(p); - assertEqualInt(0, stat("f0", &st)); - if (st.st_atime == files[0].atime_sec) { - skipping("Cannot verify -a option\n" - " Your system appears to not support atime."); - } - else - { - /* - * If this disk is mounted noatime, then we can't - * verify correct operation without -a. - */ - - /* Copy the file without -a; should change the atime. */ - r = systemf("echo %s | %s -pd copy-no-a > copy-no-a.out 2>copy-no-a.err", files[1].name, testprog); - assertEqualInt(r, 0); - assertTextFileContents("1 block\n", "copy-no-a.err"); - assertEmptyFile("copy-no-a.out"); - assertEqualInt(0, stat(files[1].name, &st)); - failure("Copying file without -a should have changed atime."); - assert(st.st_atime != files[1].atime_sec); - - /* Archive the file without -a; should change the atime. */ - r = systemf("echo %s | %s -o > archive-no-a.out 2>archive-no-a.err", files[2].name, testprog); - assertEqualInt(r, 0); - assertTextFileContents("1 block\n", "copy-no-a.err"); - assertEqualInt(0, stat(files[2].name, &st)); - failure("Archiving file without -a should have changed atime."); - assert(st.st_atime != files[2].atime_sec); - } - - /* - * We can, of course, still verify that the atime is unchanged - * when using the -a option. - */ - - /* Copy the file with -a; should not change the atime. */ - r = systemf("echo %s | %s -pad copy-a > copy-a.out 2>copy-a.err", - files[3].name, testprog); - assertEqualInt(r, 0); - assertTextFileContents("1 block\n", "copy-a.err"); - assertEmptyFile("copy-a.out"); - assertEqualInt(0, stat(files[3].name, &st)); - failure("Copying file with -a should not have changed atime."); - assertEqualInt(st.st_atime, files[3].atime_sec); - - /* Archive the file with -a; should not change the atime. */ - r = systemf("echo %s | %s -oa > archive-a.out 2>archive-a.err", - files[4].name, testprog); - assertEqualInt(r, 0); - assertTextFileContents("1 block\n", "copy-a.err"); - assertEqualInt(0, stat(files[4].name, &st)); - failure("Archiving file with -a should not have changed atime."); - assertEqualInt(st.st_atime, files[4].atime_sec); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_b64encode.c b/thirdparty/libarchive/cpio/test/test_option_b64encode.c deleted file mode 100644 index 7c15a8230..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_b64encode.c +++ /dev/null @@ -1,56 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_b64encode) -{ - char *p; - size_t s; - - /* Create a file. */ - assertMakeFile("f", 0644, "a"); - - /* Archive it with compress compression and uuencode. */ - assertEqualInt(0, - systemf("echo f | %s -o -Z --b64encode >archive.out 2>archive.err", - testprog)); - /* Check that the archive file has an uuencode signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 2); - assertEqualMem(p, "begin-base64 644", 16); - free(p); - - /* Archive it with uuencode only. */ - assertEqualInt(0, - systemf("echo f | %s -o --b64encode >archive.out 2>archive.err", - testprog)); - /* Check that the archive file has an uuencode signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 2); - assertEqualMem(p, "begin-base64 644", 16); - free(p); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_c.c b/thirdparty/libarchive/cpio/test/test_option_c.c deleted file mode 100644 index dfa62c13b..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_c.c +++ /dev/null @@ -1,229 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -static int -is_octal(const char *p, size_t l) -{ - while (l > 0) { - if (*p < '0' || *p > '7') - return (0); - --l; - ++p; - } - return (1); -} - -static long long int -from_octal(const char *p, size_t l) -{ - long long int r = 0; - - while (l > 0) { - r *= 8; - r += *p - '0'; - --l; - ++p; - } - return (r); -} - -#if !defined(_WIN32) || defined(__CYGWIN__) -static int -nlinks(const char *p) -{ - struct stat st; - assertEqualInt(0, stat(p, &st)); - return st.st_nlink; -} -#endif - -DEFINE_TEST(test_option_c) -{ - FILE *filelist; - int r; - int uid = 1000; - int dev, ino, gid = 1000; - time_t t, now; - char *p, *e; - size_t s; - - assertUmask(0); - - /* - * Create an assortment of files. - * TODO: Extend this to cover more filetypes. - */ - filelist = fopen("filelist", "w"); - - /* "file" */ - assertMakeFile("file", 0644, "1234567890"); - fprintf(filelist, "file\n"); - - /* "symlink" */ - if (canSymlink()) { - assertMakeSymlink("symlink", "file", 0); - fprintf(filelist, "symlink\n"); - } - - /* "dir" */ - assertMakeDir("dir", 0775); - /* Record some facts about what we just created: */ - now = time(NULL); /* They were all created w/in last two seconds. */ - fprintf(filelist, "dir\n"); - - /* Use the cpio program to create an archive. */ - fclose(filelist); - r = systemf("%s -R 1000:1000 -oc basic.out 2>basic.err", testprog); - /* Verify that nothing went to stderr. */ - assertTextFileContents("1 block\n", "basic.err"); - - /* Assert that the program finished. */ - failure("%s -oc crashed", testprog); - if (!assertEqualInt(r, 0)) - return; - - /* Verify that stdout is a well-formed cpio file in "odc" format. */ - p = slurpfile(&s, "basic.out"); - assertEqualInt(s, 512); - e = p; - - /* - * Some of these assertions could be stronger, but it's - * a little tricky because they depend on the local environment. - */ - - /* First entry is "file" */ - assert(is_octal(e, 76)); /* Entire header is octal digits. */ - assertEqualMem(e + 0, "070707", 6); /* Magic */ - assert(is_octal(e + 6, 6)); /* dev */ - dev = from_octal(e + 6, 6); - assert(is_octal(e + 12, 6)); /* ino */ - ino = from_octal(e + 12, 6); -#if defined(_WIN32) && !defined(__CYGWIN__) - /* Group members bits and others bits do not work. */ - assertEqualMem(e + 18, "100666", 6); /* Mode */ -#else - assertEqualMem(e + 18, "100644", 6); /* Mode */ -#endif - if (uid < 0) - uid = from_octal(e + 24, 6); - assertEqualInt(from_octal(e + 24, 6), uid); /* uid */ - assert(is_octal(e + 30, 6)); /* gid */ - gid = from_octal(e + 30, 6); - assertEqualMem(e + 36, "000001", 6); /* nlink */ - failure("file entries should not have rdev set (dev field was 0%o)", - dev); - assertEqualMem(e + 42, "000000", 6); /* rdev */ - t = from_octal(e + 48, 11); /* mtime */ - assert(t <= now); /* File wasn't created in future. */ - assert(t >= now - 2); /* File was created w/in last 2 secs. */ - assertEqualMem(e + 59, "000005", 6); /* Name size */ - assertEqualMem(e + 65, "00000000012", 11); /* File size */ - assertEqualMem(e + 76, "file\0", 5); /* Name contents */ - assertEqualMem(e + 81, "1234567890", 10); /* File contents */ - e += 91; - - /* "symlink" pointing to "file" */ - if (canSymlink()) { - assert(is_octal(e, 76)); /* Entire header is octal digits. */ - assertEqualMem(e + 0, "070707", 6); /* Magic */ - assertEqualInt(dev, from_octal(e + 6, 6)); /* dev */ - assert(ino != from_octal(e + 12, 6)); /* ino */ -#if !defined(_WIN32) || defined(__CYGWIN__) - /* On Windows, symbolic link and group members bits and - * others bits do not work. */ - assertEqualMem(e + 18, "120777", 6); /* Mode */ -#endif - assertEqualInt(from_octal(e + 24, 6), uid); /* uid */ - assertEqualInt(gid, from_octal(e + 30, 6)); /* gid */ - assertEqualMem(e + 36, "000001", 6); /* nlink */ - failure("file entries should have rdev == 0 (dev was 0%llo)", - from_octal(e + 6, 6)); - assertEqualMem(e + 42, "000000", 6); /* rdev */ - t = from_octal(e + 48, 11); /* mtime */ - assert(t <= now); /* File wasn't created in future. */ - assert(t >= now - 2); /* File was created w/in last 2 secs. */ - assertEqualMem(e + 59, "000010", 6); /* Name size */ - assertEqualMem(e + 65, "00000000004", 11); /* File size */ - assertEqualMem(e + 76, "symlink\0", 8); /* Name contents */ - assertEqualMem(e + 84, "file", 4); /* Symlink target. */ - e += 88; - } - - /* "dir" */ - assert(is_octal(e, 76)); - assertEqualMem(e + 0, "070707", 6); /* Magic */ - /* Dev should be same as first entry. */ - assert(is_octal(e + 6, 6)); /* dev */ - assertEqualInt(dev, from_octal(e + 6, 6)); - /* Ino must be different from first entry. */ - assert(is_octal(e + 12, 6)); /* ino */ - assert(ino != from_octal(e + 12, 6)); -#if defined(_WIN32) && !defined(__CYGWIN__) - /* Group members bits and others bits do not work. */ - assertEqualMem(e + 18, "040777", 6); /* Mode */ -#else - /* Accept 042775 to accommodate systems where sgid bit propagates. */ - if (memcmp(e + 18, "042775", 6) != 0) - assertEqualMem(e + 18, "040775", 6); /* Mode */ -#endif - assertEqualInt(uid, from_octal(e + 24, 6)); /* uid */ - /* Gid should be same as first entry. */ - assert(is_octal(e + 30, 6)); /* gid */ - assertEqualInt(gid, from_octal(e + 30, 6)); - -#if !defined(_WIN32) || defined(__CYGWIN__) - assertEqualInt(nlinks("dir"), from_octal(e + 36, 6)); /* Nlink */ -#endif - - t = from_octal(e + 48, 11); /* mtime */ - assert(t <= now); /* File wasn't created in future. */ - assert(t >= now - 2); /* File was created w/in last 2 secs. */ - assertEqualMem(e + 59, "000004", 6); /* Name size */ - assertEqualMem(e + 65, "00000000000", 11); /* File size */ - assertEqualMem(e + 76, "dir\0", 4); /* name */ - e += 80; - - /* TODO: Verify other types of entries. */ - - /* Last entry is end-of-archive marker. */ - assert(is_octal(e, 76)); - assertEqualMem(e + 0, "070707", 6); /* Magic */ - assertEqualMem(e + 6, "000000", 6); /* dev */ - assertEqualMem(e + 12, "000000", 6); /* ino */ - assertEqualMem(e + 18, "000000", 6); /* Mode */ - assertEqualMem(e + 24, "000000", 6); /* uid */ - assertEqualMem(e + 30, "000000", 6); /* gid */ - assertEqualMem(e + 36, "000001", 6); /* Nlink */ - assertEqualMem(e + 42, "000000", 6); /* rdev */ - assertEqualMem(e + 48, "00000000000", 11); /* mtime */ - assertEqualMem(e + 59, "000013", 6); /* Name size */ - assertEqualMem(e + 65, "00000000000", 11); /* File size */ - assertEqualMem(e + 76, "TRAILER!!!\0", 11); /* Name */ - - free(p); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_d.c b/thirdparty/libarchive/cpio/test/test_option_d.c deleted file mode 100644 index 9ff145396..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_d.c +++ /dev/null @@ -1,64 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - - -DEFINE_TEST(test_option_d) -{ - int r; - - /* - * Create a file in a directory. - */ - assertMakeDir("dir", 0755); - assertMakeFile("dir/file", 0644, NULL); - - /* Create an archive. */ - r = systemf("echo dir/file | %s -o > archive.cpio 2>archive.err", testprog); - assertEqualInt(r, 0); - assertTextFileContents("1 block\n", "archive.err"); - assertFileSize("archive.cpio", 512); - - /* Dearchive without -d, this should fail. */ - assertMakeDir("without-d", 0755); - assertChdir("without-d"); - r = systemf("%s -i < ../archive.cpio >out 2>err", testprog); - assertEqualInt(r, 0); - assertEmptyFile("out"); - /* And the file should not be restored. */ - assertFileNotExists("dir/file"); - - /* Dearchive with -d, this should succeed. */ - assertChdir(".."); - assertMakeDir("with-d", 0755); - assertChdir("with-d"); - r = systemf("%s -id < ../archive.cpio >out 2>err", testprog); - assertEqualInt(r, 0); - assertEmptyFile("out"); - assertTextFileContents("1 block\n", "err"); - /* And the file should be restored. */ - assertFileExists("dir/file"); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_f.c b/thirdparty/libarchive/cpio/test/test_option_f.c deleted file mode 100644 index 784e08584..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_f.c +++ /dev/null @@ -1,76 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* - * Unpack the archive in a new dir. - */ -static void -unpack(const char *dirname, const char *option) -{ - int r; - - assertMakeDir(dirname, 0755); - assertChdir(dirname); - extract_reference_file("test_option_f.cpio"); - r = systemf("%s -i %s < test_option_f.cpio > copy-no-a.out 2>copy-no-a.err", testprog, option); - assertEqualInt(0, r); - assertChdir(".."); -} - -DEFINE_TEST(test_option_f) -{ - /* Calibrate: No -f option, so everything should be extracted. */ - unpack("t0", "--no-preserve-owner"); - assertFileExists("t0/a123"); - assertFileExists("t0/a234"); - assertFileExists("t0/b123"); - assertFileExists("t0/b234"); - - /* Don't extract 'a*' files. */ -#if defined(_WIN32) && !defined(__CYGWIN__) - /* Single quotes isn't used by command.exe. */ - unpack("t1", "--no-preserve-owner -f a*"); -#else - unpack("t1", "--no-preserve-owner -f 'a*'"); -#endif - assertFileNotExists("t1/a123"); - assertFileNotExists("t1/a234"); - assertFileExists("t1/b123"); - assertFileExists("t1/b234"); - - /* Don't extract 'b*' files. */ -#if defined(_WIN32) && !defined(__CYGWIN__) - /* Single quotes isn't used by command.exe. */ - unpack("t2", "--no-preserve-owner -f b*"); -#else - unpack("t2", "--no-preserve-owner -f 'b*'"); -#endif - assertFileExists("t2/a123"); - assertFileExists("t2/a234"); - assertFileNotExists("t2/b123"); - assertFileNotExists("t2/b234"); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_f.cpio.uu b/thirdparty/libarchive/cpio/test/test_option_f.cpio.uu deleted file mode 100644 index 42c63c396..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_f.cpio.uu +++ /dev/null @@ -1,16 +0,0 @@ -$FreeBSD$ -begin 644 test_option_f.cpio -M,#archive.out 2>archive.err", - testprog)); - p = slurpfile(&s, "archive.err"); - free(p); - /* Check that the archive file has an grzip signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 2); - assertEqualMem(p, "GRZipII\x00\x02\x04:)", 12); - free(p); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_help.c b/thirdparty/libarchive/cpio/test/test_option_help.c deleted file mode 100644 index 56234306f..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_help.c +++ /dev/null @@ -1,84 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* - * Test that "--help", "-h", and "-W help" options all work and - * generate reasonable output. - */ - -static int -in_first_line(const char *p, const char *substring) -{ - size_t l = strlen(substring); - - while (*p != '\0' && *p != '\n') { - if (memcmp(p, substring, l) == 0) - return (1); - ++p; - } - return (0); -} - -DEFINE_TEST(test_option_help) -{ - int r; - char *p; - size_t plen; - - /* Exercise --help option. */ - r = systemf("%s --help >help.stdout 2>help.stderr", testprog); - assertEqualInt(r, 0); - failure("--help should generate nothing to stderr."); - assertEmptyFile("help.stderr"); - /* Help message should start with name of program. */ - p = slurpfile(&plen, "help.stdout"); - failure("Help output should be long enough."); - assert(plen >= 7); - failure("First line of help output should contain string 'bsdcpio'"); - assert(in_first_line(p, "bsdcpio")); - /* - * TODO: Extend this check to further verify that --help output - * looks approximately right. - */ - free(p); - - /* -h option should generate the same output. */ - r = systemf("%s -h >h.stdout 2>h.stderr", testprog); - assertEqualInt(r, 0); - failure("-h should generate nothing to stderr."); - assertEmptyFile("h.stderr"); - failure("stdout should be same for -h and --help"); - assertEqualFile("h.stdout", "help.stdout"); - - /* -W help should be another synonym. */ - r = systemf("%s -W help >Whelp.stdout 2>Whelp.stderr", testprog); - assertEqualInt(r, 0); - failure("-W help should generate nothing to stderr."); - assertEmptyFile("Whelp.stderr"); - failure("stdout should be same for -W help and --help"); - assertEqualFile("Whelp.stdout", "help.stdout"); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_l.c b/thirdparty/libarchive/cpio/test/test_option_l.c deleted file mode 100644 index 5c76e688e..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_l.c +++ /dev/null @@ -1,50 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_l) -{ - int r; - - /* Create a file. */ - assertMakeFile("f", 0644, "a"); - - /* Copy the file to the "copy" dir. */ - r = systemf("echo f | %s -pd copy >copy.out 2>copy.err", - testprog); - assertEqualInt(r, 0); - - /* Check that the copy is a true copy and not a link. */ - assertIsNotHardlink("f", "copy/f"); - - /* Copy the file to the "link" dir with the -l option. */ - r = systemf("echo f | %s -pld link >link.out 2>link.err", - testprog); - assertEqualInt(r, 0); - - /* Check that this is a link and not a copy. */ - assertIsHardlink("f", "link/f"); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_lrzip.c b/thirdparty/libarchive/cpio/test/test_option_lrzip.c deleted file mode 100644 index 8d9c0d576..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_lrzip.c +++ /dev/null @@ -1,53 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_lrzip) -{ - char *p; - size_t s; - - if (!canLrzip()) { - skipping("lrzip is not supported on this platform"); - return; - } - - /* Create a file. */ - assertMakeFile("f", 0644, "a"); - - /* Archive it with lrzip compression. */ - assertEqualInt(0, - systemf("echo f | %s -o --lrzip >archive.out 2>archive.err", - testprog)); - p = slurpfile(&s, "archive.err"); - free(p); - /* Check that the archive file has an lzma signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 2); - assertEqualMem(p, "LRZI\x00", 5); - free(p); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_lz4.c b/thirdparty/libarchive/cpio/test/test_option_lz4.c deleted file mode 100644 index ebd376736..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_lz4.c +++ /dev/null @@ -1,88 +0,0 @@ -/*- - * Copyright (c) 2014 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_lz4) -{ - char *p; - int r; - size_t s; - - /* Create a file. */ - assertMakeFile("f", 0644, "a"); - - /* Archive it with lz4 compression. */ - r = systemf("echo f | %s -o --lz4 >archive.out 2>archive.err", - testprog); - p = slurpfile(&s, "archive.err"); - p[s] = '\0'; - if (r != 0) { - if (strstr(p, "compression not available") != NULL) { - skipping("This version of bsdcpio was compiled " - "without lz4 support"); - free(p); - return; - } - /* POSIX permits different handling of the spawnp - * system call used to launch the subsidiary - * program: */ - /* Some systems fail immediately to spawn the new process. */ - if (strstr(p, "Can't launch") != NULL && !canLz4()) { - skipping("This version of bsdcpio uses an external lz4 program " - "but no such program is available on this system."); - free(p); - return; - } - /* Some systems successfully spawn the new process, - * but fail to exec a program within that process. - * This results in failure at the first attempt to - * write. */ - if (strstr(p, "Can't write") != NULL && !canLz4()) { - skipping("This version of bsdcpio uses an external lz4 program " - "but no such program is available on this system."); - free(p); - return; - } - /* On some systems the error won't be detected until closing - time, by a 127 exit error returned by waitpid. */ - if (strstr(p, "Error closing") != NULL && !canLz4()) { - skipping("This version of bsdcpio uses an external lz4 program " - "but no such program is available on this system."); - free(p); - return; - } - failure("--lz4 option is broken: %s", p); - free(p); - assertEqualInt(r, 0); - return; - } - free(p); - /* Check that the archive file has an lz4 signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 2); - assertEqualMem(p, "\x04\x22\x4d\x18", 4); - free(p); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_lzma.c b/thirdparty/libarchive/cpio/test/test_option_lzma.c deleted file mode 100644 index b7cad3d1e..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_lzma.c +++ /dev/null @@ -1,60 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_lzma) -{ - char *p; - int r; - size_t s; - - /* Create a file. */ - assertMakeFile("f", 0644, "a"); - - /* Archive it with lzma compression. */ - r = systemf("echo f | %s -o --lzma >archive.out 2>archive.err", - testprog); - p = slurpfile(&s, "archive.err"); - p[s] = '\0'; - if (r != 0) { - if (strstr(p, "compression not available") != NULL) { - skipping("This version of bsdcpio was compiled " - "without lzma support"); - free(p); - return; - } - failure("--lzma option is broken"); - assertEqualInt(r, 0); - free(p); - return; - } - free(p); - /* Check that the archive file has an lzma signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 2); - assertEqualMem(p, "\x5d\00\00", 3); - free(p); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_lzop.c b/thirdparty/libarchive/cpio/test/test_option_lzop.c deleted file mode 100644 index aa40ef5b6..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_lzop.c +++ /dev/null @@ -1,57 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_lzop) -{ - char *p; - int r; - size_t s; - - /* Create a file. */ - assertMakeFile("f", 0644, "a"); - - /* Archive it with lzop compression. */ - r = systemf("echo f | %s -o --lzop >archive.out 2>archive.err", - testprog); - p = slurpfile(&s, "archive.err"); - free(p); - if (r != 0) { - if (!canLzop()) { - skipping("lzop is not supported on this platform"); - return; - } - failure("--lzop option is broken"); - assertEqualInt(r, 0); - return; - } - /* Check that the archive file has an lzma signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 2); - assertEqualMem(p, "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a", 9); - free(p); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_m.c b/thirdparty/libarchive/cpio/test/test_option_m.c deleted file mode 100644 index de880b288..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_m.c +++ /dev/null @@ -1,63 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - - -DEFINE_TEST(test_option_m) -{ - int r; - - /* - * The reference archive has one file with an mtime in 1970, 1 - * second after the start of the epoch. - */ - - /* Restored without -m, the result should have a current mtime. */ - assertMakeDir("without-m", 0755); - assertChdir("without-m"); - extract_reference_file("test_option_m.cpio"); - r = systemf("%s --no-preserve-owner -i < test_option_m.cpio >out 2>err", testprog); - assertEqualInt(r, 0); - assertEmptyFile("out"); - assertTextFileContents("1 block\n", "err"); - /* Should have been created within the last few seconds. */ - assertFileMtimeRecent("file"); - - /* With -m, it should have an mtime in 1970. */ - assertChdir(".."); - assertMakeDir("with-m", 0755); - assertChdir("with-m"); - extract_reference_file("test_option_m.cpio"); - r = systemf("%s --no-preserve-owner -im < test_option_m.cpio >out 2>err", testprog); - assertEqualInt(r, 0); - assertEmptyFile("out"); - assertTextFileContents("1 block\n", "err"); - /* - * mtime in reference archive is '1' == 1 second after - * midnight Jan 1, 1970 UTC. - */ - assertFileMtime("file", 1, 0); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_m.cpio.uu b/thirdparty/libarchive/cpio/test/test_option_m.cpio.uu deleted file mode 100644 index 3d2002355..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_m.cpio.uu +++ /dev/null @@ -1,16 +0,0 @@ -$FreeBSD$ -begin 644 test_option_m.cpio -M,#test.out 2>test.err", - testprog, reffile)); - - assertFileExists("file1"); - assertTextFileContents("contents of file1.\n", "file1"); - assertFileExists("file2"); - assertTextFileContents("contents of file2.\n", "file2"); - assertEmptyFile("test.out"); - assertTextFileContents("1 block\n", "test.err"); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_passphrase.zip.uu b/thirdparty/libarchive/cpio/test/test_option_passphrase.zip.uu deleted file mode 100644 index 021ae8585..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_passphrase.zip.uu +++ /dev/null @@ -1,12 +0,0 @@ -begin 644 test_option_passphrase.zip -M4$L#!`H`"0```#B91$7D$C4,'P```!,````%`!P`9FEL93%55`D``VS'+U0" -MQR]4=7@+``$$]0$```04````BHPD*"^*I04=XKI\_FQ*TE+#),TD7TTKSP/7 -MR6R35%!+!PCD$C4,'P```!,```!02P,$"@`)````09E$1;VL<`L``03U`0``!!0```!D#6Z\@CI8 -MV1GIJO5TISQF^I:7.;Y3<-G3$YOCL(C_4$L'"+VL -M`PH`"0```#B91$7D$C4,'P```!,````%`!@```````$```"D@0````!F:6QE -M,554!0`#;,`PH`"0```$&91$6]K',. -M'P```!,````%`!@```````$```"D@6X```!F:6QE,E54!0`#>< -#endif - -DEFINE_TEST(test_option_t) -{ - char *p; - int r; - time_t mtime; - char date[32]; - char date2[32]; - struct tm *tmptr; -#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S) - struct tm tmbuf; -#endif - - /* List reference archive, make sure the TOC is correct. */ - extract_reference_file("test_option_t.cpio"); - r = systemf("%s -it < test_option_t.cpio >it.out 2>it.err", testprog); - assertEqualInt(r, 0); - assertTextFileContents("1 block\n", "it.err"); - extract_reference_file("test_option_t.stdout"); - p = slurpfile(NULL, "test_option_t.stdout"); - assertTextFileContents(p, "it.out"); - free(p); - - /* We accept plain "-t" as a synonym for "-it" */ - r = systemf("%s -t < test_option_t.cpio >t.out 2>t.err", testprog); - assertEqualInt(r, 0); - assertTextFileContents("1 block\n", "t.err"); - extract_reference_file("test_option_t.stdout"); - p = slurpfile(NULL, "test_option_t.stdout"); - assertTextFileContents(p, "t.out"); - free(p); - - /* But "-ot" is an error. */ - assert(0 != systemf("%s -ot < test_option_t.cpio >ot.out 2>ot.err", - testprog)); - assertEmptyFile("ot.out"); - - /* List reference archive verbosely, make sure the TOC is correct. */ - r = systemf("%s -itv < test_option_t.cpio >tv.out 2>tv.err", testprog); - assertEqualInt(r, 0); - assertTextFileContents("1 block\n", "tv.err"); - extract_reference_file("test_option_tv.stdout"); - - /* This doesn't work because the usernames on different systems - * are different and cpio now looks up numeric UIDs on - * the local system. */ - /* assertEqualFile("tv.out", "test_option_tv.stdout"); */ - - /* List reference archive with numeric IDs, verify TOC is correct. */ - r = systemf("%s -itnv < test_option_t.cpio >itnv.out 2>itnv.err", - testprog); - assertEqualInt(r, 0); - assertTextFileContents("1 block\n", "itnv.err"); - p = slurpfile(NULL, "itnv.out"); - /* Since -n uses numeric UID/GID, this part should be the - * same on every system. */ - assertEqualMem(p, "-rw-r--r-- 1 1000 1000 0 ",42); - - /* Date varies depending on local timezone and locale. */ - mtime = 1; -#ifdef HAVE_LOCALE_H - setlocale(LC_ALL, ""); -#endif -#if defined(HAVE_LOCALTIME_S) - tmptr = localtime_s(&tmbuf, &mtime) ? NULL : &tmbuf; -#elif defined(HAVE_LOCALTIME_R) - tmptr = localtime_r(&mtime, &tmbuf); -#else - tmptr = localtime(&mtime); -#endif -#if defined(_WIN32) && !defined(__CYGWIN__) - strftime(date2, sizeof(date2)-1, "%b %d %Y", tmptr); - _snprintf(date, sizeof(date)-1, "%12.12s file", date2); -#else - strftime(date2, sizeof(date2)-1, "%b %e %Y", tmptr); - snprintf(date, sizeof(date)-1, "%12.12s file", date2); -#endif - assertEqualMem(p + 42, date, strlen(date)); - free(p); - - /* But "-n" without "-t" is an error. */ - assert(0 != systemf("%s -in < test_option_t.cpio >in.out 2>in.err", - testprog)); - assertEmptyFile("in.out"); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_t.cpio.uu b/thirdparty/libarchive/cpio/test/test_option_t.cpio.uu deleted file mode 100644 index 055fe747d..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_t.cpio.uu +++ /dev/null @@ -1,16 +0,0 @@ -$FreeBSD$ -begin 644 test_option_t.cpio -M,# -#elif defined(HAVE_SYS_UTIME_H) -#include -#endif -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_u) -{ - struct utimbuf times; - char *p; - size_t s; - int r; - - /* Create a file. */ - assertMakeFile("f", 0644, "a"); - - /* Copy the file to the "copy" dir. */ - r = systemf("echo f| %s -pd copy >copy.out 2>copy.err", - testprog); - assertEqualInt(r, 0); - - /* Check that the file contains only a single "a" */ - p = slurpfile(&s, "copy/f"); - assertEqualInt(s, 1); - assertEqualMem(p, "a", 1); - free(p); - - /* Recreate the file with a single "b" */ - assertMakeFile("f", 0644, "b"); - - /* Set the mtime to the distant past. */ - memset(×, 0, sizeof(times)); - times.actime = 1; - times.modtime = 3; - assertEqualInt(0, utime("f", ×)); - - /* Copy the file to the "copy" dir. */ - r = systemf("echo f| %s -pd copy >copy.out 2>copy.err", - testprog); - assertEqualInt(r, 0); - - /* Verify that the file hasn't changed (it wasn't overwritten) */ - p = slurpfile(&s, "copy/f"); - assertEqualInt(s, 1); - assertEqualMem(p, "a", 1); - free(p); - - /* Copy the file to the "copy" dir with -u (force) */ - r = systemf("echo f| %s -pud copy >copy.out 2>copy.err", - testprog); - assertEqualInt(r, 0); - - /* Verify that the file has changed (it was overwritten) */ - p = slurpfile(&s, "copy/f"); - assertEqualInt(s, 1); - assertEqualMem(p, "b", 1); - free(p); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_uuencode.c b/thirdparty/libarchive/cpio/test/test_option_uuencode.c deleted file mode 100644 index a42a0e030..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_uuencode.c +++ /dev/null @@ -1,56 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_uuencode) -{ - char *p; - size_t s; - - /* Create a file. */ - assertMakeFile("f", 0644, "a"); - - /* Archive it with compress compression and uuencode. */ - assertEqualInt(0, - systemf("echo f | %s -o -Z --uuencode >archive.out 2>archive.err", - testprog)); - /* Check that the archive file has an uuencode signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 2); - assertEqualMem(p, "begin 644", 9); - free(p); - - /* Archive it with uuencode only. */ - assertEqualInt(0, - systemf("echo f | %s -o --uuencode >archive.out 2>archive.err", - testprog)); - /* Check that the archive file has an uuencode signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 2); - assertEqualMem(p, "begin 644", 9); - free(p); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_version.c b/thirdparty/libarchive/cpio/test/test_option_version.c deleted file mode 100644 index 505db2712..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_version.c +++ /dev/null @@ -1,30 +0,0 @@ -/*- - * Copyright (c) 2003-2017 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -DEFINE_TEST(test_option_version) -{ - assertVersion(testprog, "bsdcpio"); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_xz.c b/thirdparty/libarchive/cpio/test/test_option_xz.c deleted file mode 100644 index f0d3b33d4..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_xz.c +++ /dev/null @@ -1,61 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_xz) -{ - char *p; - int r; - size_t s; - - /* Create a file. */ - assertMakeFile("f", 0644, "a"); - - /* Archive it with xz compression. */ - r = systemf("echo f | %s -o --xz >archive.out 2>archive.err", - testprog); - p = slurpfile(&s, "archive.err"); - p[s] = '\0'; - if (r != 0) { - if (strstr(p, "compression not available") != NULL) { - skipping("This version of bsdcpio was compiled " - "without xz support"); - free(p); - return; - } - free(p); - failure("--xz option is broken"); - assertEqualInt(r, 0); - return; - } - free(p); - /* Check that the archive file has an xz signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 2); - assertEqualMem(p, "\xFD\x37\x7A\x58\x5A\x00", 6); - free(p); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_y.c b/thirdparty/libarchive/cpio/test/test_option_y.c deleted file mode 100644 index 989b5f1aa..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_y.c +++ /dev/null @@ -1,57 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/usr.bin/cpio/test/test_option_y.c,v 1.2 2008/08/24 06:21:00 kientzle Exp $"); - -DEFINE_TEST(test_option_y) -{ - char *p; - int r; - size_t s; - - /* Create a file. */ - assertMakeFile("f", 0644, "a"); - - /* Archive it with bzip2 compression. */ - r = systemf("echo f | %s -oy >archive.out 2>archive.err", - testprog); - p = slurpfile(&s, "archive.err"); - free(p); - if (r != 0) { - if (!canBzip2()) { - skipping("bzip2 is not supported on this platform"); - return; - } - failure("-y option is broken"); - assertEqualInt(r, 0); - return; - } - assertTextFileContents("1 block\n", "archive.err"); - /* Check that the archive file has a bzip2 signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 2); - assertEqualMem(p, "BZh9", 4); - free(p); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_z.c b/thirdparty/libarchive/cpio/test/test_option_z.c deleted file mode 100644 index 803232d04..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_z.c +++ /dev/null @@ -1,56 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_z) -{ - char *p; - int r; - size_t s; - - /* Create a file. */ - assertMakeFile("f", 0644, "a"); - - /* Archive it with gzip compression. */ - r = systemf("echo f | %s -oz >archive.out 2>archive.err", - testprog); - p = slurpfile(&s, "archive.err"); - free(p); - if (r != 0) { - if (!canGzip()) { - skipping("gzip is not supported on this platform"); - return; - } - failure("-z option is broken"); - assertEqualInt(r, 0); - return; - } - /* Check that the archive file has a gzip signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 4); - assertEqualMem(p, "\x1f\x8b\x08\x00", 4); - free(p); -} diff --git a/thirdparty/libarchive/cpio/test/test_option_zstd.c b/thirdparty/libarchive/cpio/test/test_option_zstd.c deleted file mode 100644 index 29b8c78b9..000000000 --- a/thirdparty/libarchive/cpio/test/test_option_zstd.c +++ /dev/null @@ -1,85 +0,0 @@ -/*- - * Copyright (c) 2017 Sean Purcell - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_zstd) -{ - char *p; - int r; - size_t s; - - /* Create a file. */ - assertMakeFile("f", 0644, "a"); - - /* Archive it with zstd compression. */ - r = systemf("echo f | %s -o --zstd >archive.out 2>archive.err", - testprog); - p = slurpfile(&s, "archive.err"); - p[s] = '\0'; - if (r != 0) { - if (strstr(p, "Unsupported compression") != NULL) { - skipping("This version of bsdcpio was compiled " - "without zstd support"); - goto done; - } - /* POSIX permits different handling of the spawnp - * system call used to launch the subsidiary - * program: */ - /* Some systems fail immediately to spawn the new process. */ - if (strstr(p, "Can't launch") != NULL && !canZstd()) { - skipping("This version of bsdcpio uses an external zstd program " - "but no such program is available on this system."); - goto done; - } - /* Some systems successfully spawn the new process, - * but fail to exec a program within that process. - * This results in failure at the first attempt to - * write. */ - if (strstr(p, "Can't write") != NULL && !canZstd()) { - skipping("This version of bsdcpio uses an external zstd program " - "but no such program is available on this system."); - goto done; - } - /* On some systems the error won't be detected until closing - time, by a 127 exit error returned by waitpid. */ - if (strstr(p, "Error closing") != NULL && !canZstd()) { - skipping("This version of bsdcpio uses an external zstd program " - "but no such program is available on this system."); - return; - } - failure("--zstd option is broken: %s", p); - assertEqualInt(r, 0); - goto done; - } - free(p); - /* Check that the archive file has an zstd signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 2); - assertEqualMem(p, "\x28\xb5\x2f\xfd", 4); - -done: - free(p); -} diff --git a/thirdparty/libarchive/cpio/test/test_owner_parse.c b/thirdparty/libarchive/cpio/test/test_owner_parse.c deleted file mode 100644 index bef02da7b..000000000 --- a/thirdparty/libarchive/cpio/test/test_owner_parse.c +++ /dev/null @@ -1,121 +0,0 @@ -/*- - * Copyright (c) 2003-2009 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -#include "../cpio.h" -#include "err.h" - -#if !defined(_WIN32) -#define ROOT "root" -static const int root_uids[] = { 0 }; -static const int root_gids[] = { 0, 1 }; -#elif defined(__CYGWIN__) -/* On cygwin, the Administrator user most likely exists (unless - * it has been renamed or is in a non-English localization), but - * its primary group membership depends on how the user set up - * their /etc/passwd. Likely values are 513 (None), 545 (Users), - * or 544 (Administrators). Just check for one of those... - * TODO: Handle non-English localizations... e.g. French 'Administrateur' - * Use CreateWellKnownSID() and LookupAccountName()? - */ -#define ROOT "Administrator" -static const int root_uids[] = { 500 }; -static const int root_gids[] = { 513, 545, 544 }; -#endif - -#if defined(ROOT) -static int -int_in_list(int i, const int *l, size_t n) -{ - while (n-- > 0) - if (*l++ == i) - return (1); - failure("%d", i); - return (0); -} -#endif - -DEFINE_TEST(test_owner_parse) -{ -#if !defined(ROOT) - skipping("No uid/gid configuration for this OS"); -#else - int uid, gid; - - assert(NULL == owner_parse(ROOT, &uid, &gid)); - assert(int_in_list(uid, root_uids, - sizeof(root_uids)/sizeof(root_uids[0]))); - assertEqualInt(-1, gid); - - - assert(NULL == owner_parse(ROOT ":", &uid, &gid)); - assert(int_in_list(uid, root_uids, - sizeof(root_uids)/sizeof(root_uids[0]))); - assert(int_in_list(gid, root_gids, - sizeof(root_gids)/sizeof(root_gids[0]))); - - assert(NULL == owner_parse(ROOT ".", &uid, &gid)); - assert(int_in_list(uid, root_uids, - sizeof(root_uids)/sizeof(root_uids[0]))); - assert(int_in_list(gid, root_gids, - sizeof(root_gids)/sizeof(root_gids[0]))); - - assert(NULL == owner_parse("111", &uid, &gid)); - assertEqualInt(111, uid); - assertEqualInt(-1, gid); - - assert(NULL == owner_parse("112:", &uid, &gid)); - assertEqualInt(112, uid); - /* Can't assert gid, since we don't know gid for user #112. */ - - assert(NULL == owner_parse("113.", &uid, &gid)); - assertEqualInt(113, uid); - /* Can't assert gid, since we don't know gid for user #113. */ - - assert(NULL == owner_parse(":114", &uid, &gid)); - assertEqualInt(-1, uid); - assertEqualInt(114, gid); - - assert(NULL == owner_parse(".115", &uid, &gid)); - assertEqualInt(-1, uid); - assertEqualInt(115, gid); - - assert(NULL == owner_parse("116:117", &uid, &gid)); - assertEqualInt(116, uid); - assertEqualInt(117, gid); - - /* - * TODO: Lookup current user/group name, build strings and - * use those to verify username/groupname lookups for ordinary - * users. - */ - - assert(NULL != owner_parse(":nonexistentgroup", &uid, &gid)); - assert(NULL != owner_parse(ROOT ":nonexistentgroup", &uid, &gid)); - assert(NULL != - owner_parse("nonexistentuser:nonexistentgroup", &uid, &gid)); -#endif -} diff --git a/thirdparty/libarchive/cpio/test/test_passthrough_dotdot.c b/thirdparty/libarchive/cpio/test/test_passthrough_dotdot.c deleted file mode 100644 index bb04341a4..000000000 --- a/thirdparty/libarchive/cpio/test/test_passthrough_dotdot.c +++ /dev/null @@ -1,76 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/usr.bin/cpio/test/test_passthrough_dotdot.c,v 1.4 2008/08/24 06:21:00 kientzle Exp $"); - -/* - * Verify that "cpio -p .." works. - */ - -DEFINE_TEST(test_passthrough_dotdot) -{ - int r; - FILE *filelist; - - assertUmask(0); - - /* - * Create an assortment of files on disk. - */ - filelist = fopen("filelist", "w"); - - /* Directory. */ - assertMakeDir("dir", 0755); - assertChdir("dir"); - - fprintf(filelist, ".\n"); - - /* File with 10 bytes content. */ - assertMakeFile("file", 0642, "1234567890"); - fprintf(filelist, "file\n"); - - /* All done. */ - fclose(filelist); - - - /* - * Use cpio passthrough mode to copy files to another directory. - */ - r = systemf("%s -pdvm .. <../filelist >../stdout 2>../stderr", - testprog); - failure("Error invoking %s -pd ..", testprog); - assertEqualInt(r, 0); - - assertChdir(".."); - - /* Verify stderr and stdout. */ - assertTextFileContents("../.\n../file\n1 block\n", "stderr"); - assertEmptyFile("stdout"); - - /* Regular file. */ - assertIsReg("file", 0642); - assertFileSize("file", 10); - assertFileNLinks("file", 1); -} diff --git a/thirdparty/libarchive/cpio/test/test_passthrough_reverse.c b/thirdparty/libarchive/cpio/test/test_passthrough_reverse.c deleted file mode 100644 index 674e52bc0..000000000 --- a/thirdparty/libarchive/cpio/test/test_passthrough_reverse.c +++ /dev/null @@ -1,85 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/usr.bin/cpio/test/test_passthrough_reverse.c,v 1.2 2008/08/24 06:21:00 kientzle Exp $"); - -/* - * As reported by Bernd Walter: Some people are in the habit of - * using "find -d" to generate a list for cpio -p because that - * copies the top-level dir last, which preserves owner and mode - * information. That's not necessary for bsdcpio (libarchive defers - * restoring directory information), but bsdcpio should still generate - * the correct results with this usage. - */ - -DEFINE_TEST(test_passthrough_reverse) -{ - int r; - FILE *filelist; - - assertUmask(0); - - /* - * Create an assortment of files on disk. - */ - filelist = fopen("filelist", "w"); - - /* Directory. */ - assertMakeDir("dir", 0743); - - /* File with 10 bytes content. */ - assertMakeFile("dir/file", 0644, "1234567890"); - fprintf(filelist, "dir/file\n"); - - /* Write dir last. */ - fprintf(filelist, "dir\n"); - - /* All done. */ - fclose(filelist); - - - /* - * Use cpio passthrough mode to copy files to another directory. - */ - r = systemf("%s -pdvm out stdout 2>stderr", testprog); - failure("Error invoking %s -pd out", testprog); - assertEqualInt(r, 0); - - assertChdir("out"); - - /* Verify stderr and stdout. */ - assertTextFileContents("out/dir/file\nout/dir\n1 block\n", - "../stderr"); - assertEmptyFile("../stdout"); - - /* dir */ - assertIsDir("dir", 0743); - - - /* Regular file. */ - assertIsReg("dir/file", 0644); - assertFileSize("dir/file", 10); - assertFileNLinks("dir/file", 1); -} diff --git a/thirdparty/libarchive/doc/html/.ignore_me b/thirdparty/libarchive/doc/html/.ignore_me deleted file mode 100644 index d285484d4..000000000 --- a/thirdparty/libarchive/doc/html/.ignore_me +++ /dev/null @@ -1,2 +0,0 @@ -*** PLEASE DO NOT DELETE THIS FILE! *** -This file is used to track an otherwise empty directory in git. diff --git a/thirdparty/libarchive/doc/html/Makefile b/thirdparty/libarchive/doc/html/Makefile deleted file mode 100644 index 5fdc652f0..000000000 --- a/thirdparty/libarchive/doc/html/Makefile +++ /dev/null @@ -1,133 +0,0 @@ - -default: all - - -archive_entry.3.html: ../../libarchive/archive_entry.3 - groff -mdoc -T html ../../libarchive/archive_entry.3 > archive_entry.3.html - -archive_entry_acl.3.html: ../../libarchive/archive_entry_acl.3 - groff -mdoc -T html ../../libarchive/archive_entry_acl.3 > archive_entry_acl.3.html - -archive_entry_linkify.3.html: ../../libarchive/archive_entry_linkify.3 - groff -mdoc -T html ../../libarchive/archive_entry_linkify.3 > archive_entry_linkify.3.html - -archive_entry_misc.3.html: ../../libarchive/archive_entry_misc.3 - groff -mdoc -T html ../../libarchive/archive_entry_misc.3 > archive_entry_misc.3.html - -archive_entry_paths.3.html: ../../libarchive/archive_entry_paths.3 - groff -mdoc -T html ../../libarchive/archive_entry_paths.3 > archive_entry_paths.3.html - -archive_entry_perms.3.html: ../../libarchive/archive_entry_perms.3 - groff -mdoc -T html ../../libarchive/archive_entry_perms.3 > archive_entry_perms.3.html - -archive_entry_stat.3.html: ../../libarchive/archive_entry_stat.3 - groff -mdoc -T html ../../libarchive/archive_entry_stat.3 > archive_entry_stat.3.html - -archive_entry_time.3.html: ../../libarchive/archive_entry_time.3 - groff -mdoc -T html ../../libarchive/archive_entry_time.3 > archive_entry_time.3.html - -archive_read.3.html: ../../libarchive/archive_read.3 - groff -mdoc -T html ../../libarchive/archive_read.3 > archive_read.3.html - -archive_read_add_passphrase.3.html: ../../libarchive/archive_read_add_passphrase.3 - groff -mdoc -T html ../../libarchive/archive_read_add_passphrase.3 > archive_read_add_passphrase.3.html - -archive_read_data.3.html: ../../libarchive/archive_read_data.3 - groff -mdoc -T html ../../libarchive/archive_read_data.3 > archive_read_data.3.html - -archive_read_disk.3.html: ../../libarchive/archive_read_disk.3 - groff -mdoc -T html ../../libarchive/archive_read_disk.3 > archive_read_disk.3.html - -archive_read_extract.3.html: ../../libarchive/archive_read_extract.3 - groff -mdoc -T html ../../libarchive/archive_read_extract.3 > archive_read_extract.3.html - -archive_read_filter.3.html: ../../libarchive/archive_read_filter.3 - groff -mdoc -T html ../../libarchive/archive_read_filter.3 > archive_read_filter.3.html - -archive_read_format.3.html: ../../libarchive/archive_read_format.3 - groff -mdoc -T html ../../libarchive/archive_read_format.3 > archive_read_format.3.html - -archive_read_free.3.html: ../../libarchive/archive_read_free.3 - groff -mdoc -T html ../../libarchive/archive_read_free.3 > archive_read_free.3.html - -archive_read_header.3.html: ../../libarchive/archive_read_header.3 - groff -mdoc -T html ../../libarchive/archive_read_header.3 > archive_read_header.3.html - -archive_read_new.3.html: ../../libarchive/archive_read_new.3 - groff -mdoc -T html ../../libarchive/archive_read_new.3 > archive_read_new.3.html - -archive_read_open.3.html: ../../libarchive/archive_read_open.3 - groff -mdoc -T html ../../libarchive/archive_read_open.3 > archive_read_open.3.html - -archive_read_set_options.3.html: ../../libarchive/archive_read_set_options.3 - groff -mdoc -T html ../../libarchive/archive_read_set_options.3 > archive_read_set_options.3.html - -archive_util.3.html: ../../libarchive/archive_util.3 - groff -mdoc -T html ../../libarchive/archive_util.3 > archive_util.3.html - -archive_write.3.html: ../../libarchive/archive_write.3 - groff -mdoc -T html ../../libarchive/archive_write.3 > archive_write.3.html - -archive_write_blocksize.3.html: ../../libarchive/archive_write_blocksize.3 - groff -mdoc -T html ../../libarchive/archive_write_blocksize.3 > archive_write_blocksize.3.html - -archive_write_data.3.html: ../../libarchive/archive_write_data.3 - groff -mdoc -T html ../../libarchive/archive_write_data.3 > archive_write_data.3.html - -archive_write_disk.3.html: ../../libarchive/archive_write_disk.3 - groff -mdoc -T html ../../libarchive/archive_write_disk.3 > archive_write_disk.3.html - -archive_write_filter.3.html: ../../libarchive/archive_write_filter.3 - groff -mdoc -T html ../../libarchive/archive_write_filter.3 > archive_write_filter.3.html - -archive_write_finish_entry.3.html: ../../libarchive/archive_write_finish_entry.3 - groff -mdoc -T html ../../libarchive/archive_write_finish_entry.3 > archive_write_finish_entry.3.html - -archive_write_format.3.html: ../../libarchive/archive_write_format.3 - groff -mdoc -T html ../../libarchive/archive_write_format.3 > archive_write_format.3.html - -archive_write_free.3.html: ../../libarchive/archive_write_free.3 - groff -mdoc -T html ../../libarchive/archive_write_free.3 > archive_write_free.3.html - -archive_write_header.3.html: ../../libarchive/archive_write_header.3 - groff -mdoc -T html ../../libarchive/archive_write_header.3 > archive_write_header.3.html - -archive_write_new.3.html: ../../libarchive/archive_write_new.3 - groff -mdoc -T html ../../libarchive/archive_write_new.3 > archive_write_new.3.html - -archive_write_open.3.html: ../../libarchive/archive_write_open.3 - groff -mdoc -T html ../../libarchive/archive_write_open.3 > archive_write_open.3.html - -archive_write_set_options.3.html: ../../libarchive/archive_write_set_options.3 - groff -mdoc -T html ../../libarchive/archive_write_set_options.3 > archive_write_set_options.3.html - -archive_write_set_passphrase.3.html: ../../libarchive/archive_write_set_passphrase.3 - groff -mdoc -T html ../../libarchive/archive_write_set_passphrase.3 > archive_write_set_passphrase.3.html - -cpio.5.html: ../../libarchive/cpio.5 - groff -mdoc -T html ../../libarchive/cpio.5 > cpio.5.html - -libarchive.3.html: ../../libarchive/libarchive.3 - groff -mdoc -T html ../../libarchive/libarchive.3 > libarchive.3.html - -libarchive_changes.3.html: ../../libarchive/libarchive_changes.3 - groff -mdoc -T html ../../libarchive/libarchive_changes.3 > libarchive_changes.3.html - -libarchive-formats.5.html: ../../libarchive/libarchive-formats.5 - groff -mdoc -T html ../../libarchive/libarchive-formats.5 > libarchive-formats.5.html - -libarchive_internals.3.html: ../../libarchive/libarchive_internals.3 - groff -mdoc -T html ../../libarchive/libarchive_internals.3 > libarchive_internals.3.html - -mtree.5.html: ../../libarchive/mtree.5 - groff -mdoc -T html ../../libarchive/mtree.5 > mtree.5.html - -tar.5.html: ../../libarchive/tar.5 - groff -mdoc -T html ../../libarchive/tar.5 > tar.5.html - -bsdtar.1.html: ../../tar/bsdtar.1 - groff -mdoc -T html ../../tar/bsdtar.1 > bsdtar.1.html - -bsdcpio.1.html: ../../cpio/bsdcpio.1 - groff -mdoc -T html ../../cpio/bsdcpio.1 > bsdcpio.1.html -all: archive_entry.3.html archive_entry_acl.3.html archive_entry_linkify.3.html archive_entry_misc.3.html archive_entry_paths.3.html archive_entry_perms.3.html archive_entry_stat.3.html archive_entry_time.3.html archive_read.3.html archive_read_add_passphrase.3.html archive_read_data.3.html archive_read_disk.3.html archive_read_extract.3.html archive_read_filter.3.html archive_read_format.3.html archive_read_free.3.html archive_read_header.3.html archive_read_new.3.html archive_read_open.3.html archive_read_set_options.3.html archive_util.3.html archive_write.3.html archive_write_blocksize.3.html archive_write_data.3.html archive_write_disk.3.html archive_write_filter.3.html archive_write_finish_entry.3.html archive_write_format.3.html archive_write_free.3.html archive_write_header.3.html archive_write_new.3.html archive_write_open.3.html archive_write_set_options.3.html archive_write_set_passphrase.3.html cpio.5.html libarchive.3.html libarchive_changes.3.html libarchive-formats.5.html libarchive_internals.3.html mtree.5.html tar.5.html bsdtar.1.html bsdcpio.1.html diff --git a/thirdparty/libarchive/doc/html/archive_entry.3.html b/thirdparty/libarchive/doc/html/archive_entry.3.html deleted file mode 100644 index 29c2c5892..000000000 --- a/thirdparty/libarchive/doc/html/archive_entry.3.html +++ /dev/null @@ -1,187 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_ENTRY(3) BSD Library Functions Manual -ARCHIVE_ENTRY(3)

- -

NAME

- -

archive_entry_clear, -archive_entry_clone, archive_entry_free, -archive_entry_new — functions for managing -archive entry descriptions

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive_entry.h>

- -

struct -archive_entry *

- - -

archive_entry_clear(struct archive_entry *);

- -

struct -archive_entry *

- - -

archive_entry_clone(struct archive_entry *);

- -

void

- - -

archive_entry_free(struct archive_entry *);

- -

struct -archive_entry *

- - -

archive_entry_new(void);

- -

DESCRIPTION

- -

These functions create and -manipulate data objects that represent entries within an -archive. You can think of a struct archive_entry as a -heavy-duty version of struct stat: it includes everything -from struct stat plus associated pathname, textual group and -user names, etc. These objects are used by libarchive(3) to -represent the metadata associated with a particular entry in -an archive.

- -

Create and -Destroy
-There are functions to allocate, destroy, clear, and copy -archive_entry objects:

- -

archive_entry_clear()

- -

Erases the object, resetting -all internal fields to the same state as a newly-created -object. This is provided to allow you to quickly recycle -objects without thrashing the heap.

- -

archive_entry_clone()

- -

A deep copy operation; all text -fields are duplicated.

- -

archive_entry_free()

- -

Releases the struct -archive_entry object.

- -

archive_entry_new()

- -

Allocate and return a blank -struct archive_entry object.

- -

Function -groups
-Due to high number of functions, the accessor functions can -be found in man pages grouped by the purpose.

- -

archive_entry_acl(3)

- -

Access Control -List manipulation

- -

archive_entry_paths(3)

- -

Path name -manipulation

- -

archive_entry_perms(3)

- -

User, group and -mode manipulation

- -

archive_entry_stat(3)

- -

Functions not -in the other groups and copying to/from struct -stat.

- -

archive_entry_time(3)

- -

Time field -manipulation

- -

Most of the -functions set or read entries in an object. Such functions -have one of the following forms:

- -

archive_entry_set_XXXX()

- -

Stores the provided data in the -object. In particular, for strings, the pointer is stored, -not the referenced string.

- -

archive_entry_copy_XXXX()

- -

As above, except that the -referenced data is copied into the object.

- -

archive_entry_XXXX()

- -

Returns the specified data. In -the case of strings, a const-qualified pointer to the string -is returned.

- -

String data can be set or -accessed as wide character strings or normal char -strings. The functions that use wide character strings are -suffixed with _w. Note that these are different -representations of the same data: For example, if you store -a narrow string and read the corresponding wide string, the -object will transparently convert formats using the current -locale. Similarly, if you store a wide string and then store -a narrow string for the same data, the previously-set wide -string will be discarded in favor of the new data.

- -

SEE ALSO

- -

archive_entry_acl(3), -archive_entry_paths(3), archive_entry_perms(3), -archive_entry_time(3), libarchive(3)

- -

HISTORY

- -

The libarchive library -first appeared in FreeBSD 5.3.

- -

AUTHORS

- -

The libarchive library -was written by Tim Kientzle <kientzle@acm.org>.

- -

BSD -February 2, 2012 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_entry_acl.3.html b/thirdparty/libarchive/doc/html/archive_entry_acl.3.html deleted file mode 100644 index 6234b623f..000000000 --- a/thirdparty/libarchive/doc/html/archive_entry_acl.3.html +++ /dev/null @@ -1,570 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_ENTRY_ACL(3) BSD Library Functions Manual -ARCHIVE_ENTRY_ACL(3)

- -

NAME

- - -

archive_entry_acl_add_entry, -archive_entry_acl_add_entry_w, -archive_entry_acl_clear, -archive_entry_acl_count, -archive_entry_acl_from_text, -archive_entry_acl_from_text_w, -archive_entry_acl_next, -archive_entry_acl_reset, -archive_entry_acl_to_text, -archive_entry_acl_to_text_w, -archive_entry_acl_types — functions for -manipulating Access Control Lists in archive entry -descriptions

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive_entry.h>

- -

void

- - -

archive_entry_acl_add_entry(struct archive_entry *a, -int type, int permset, -int tag, int qualifier, -const char *name);

- -

void

- - -

archive_entry_acl_add_entry_w(struct archive_entry *a, -int type, int permset, -int tag, int qualifier, -const wchar_t *name);

- -

void

- - -

archive_entry_acl_clear(struct archive_entry *a);

- -

int

- - -

archive_entry_acl_count(struct archive_entry *a, -int type);

- -

int

- - -

archive_entry_acl_from_text(struct archive_entry *a, -const char *text, -int type);

- -

int

- - -

archive_entry_acl_from_text_w(struct archive_entry *a, -const wchar_t *text, -int type);

- -

int

- - -

archive_entry_acl_next(struct archive_entry *a, -int type, int *ret_type, -int *ret_permset, int *ret_tag, -int *ret_qual, -const char **ret_name);

- -

int

- - -

archive_entry_acl_reset(struct archive_entry *a, -int type);

- -

char -*

- - -

archive_entry_acl_to_text(struct archive_entry *a, -ssize_t *len_p, int flags);

- -

wchar_t -*

- - -

archive_entry_acl_to_text_w(struct archive_entry *a, -ssize_t *len_p, int flags);

- -

int

- - -

archive_entry_acl_types(struct archive_entry *a);

- -

DESCRIPTION

- -

The “Access Control Lists -(ACLs)” extend the standard Unix permission model. The -ACL interface of libarchive supports both POSIX.1e -and NFSv4 style ACLs. Use of ACLs is restricted by various -levels of ACL support in operating systems, file systems and -archive formats.

- -

POSIX.1e -Access Control Lists
-A POSIX.1e ACL consists of a number of independent entries. -Each entry specifies the permission set as a bitmask of -basic permissions. Valid permissions in the permset -are:

- -

ARCHIVE_ENTRY_ACL_READ (r)
-ARCHIVE_ENTRY_ACL_WRITE (w)
-ARCHIVE_ENTRY_ACL_EXECUTE (x)

- -

The permissions correspond to -the normal Unix permissions.

- -

The tag -specifies the principal to which the permission applies. -Valid values are:

- -

ARCHIVE_ENTRY_ACL_USER

- -

The user specified by the name -field.

- -

ARCHIVE_ENTRY_ACL_USER_OBJ

- -

The owner of the file.

- -

ARCHIVE_ENTRY_ACL_GROUP

- -

The group specified by the name -field.

- -

ARCHIVE_ENTRY_ACL_GROUP_OBJ

- -

The group which owns the -file.

- -

ARCHIVE_ENTRY_ACL_MASK

- -

The maximum permissions to be -obtained via group permissions.

- -

ARCHIVE_ENTRY_ACL_OTHER

- -

Any principal who is not the -file owner or a member of the owning group.

- -

The principals -ARCHIVE_ENTRY_ACL_USER_OBJ, ARCHIVE_ENTRY_ACL_GROUP_OBJ and -ARCHIVE_ENTRY_ACL_OTHER are equivalent to user, group and -other in the classic Unix permission model and specify -non-extended ACL entries.

- -

All files have -an access ACL (ARCHIVE_ENTRY_ACL_TYPE_ACCESS). This -specifies the permissions required for access to the file -itself. Directories have an additional ACL -(ARCHIVE_ENTRY_ACL_TYPE_DEFAULT), which controls the initial -access ACL for newly-created directory entries.

- -

NFSv4 Access -Control Lists
-A NFSv4 ACL consists of multiple individual entries called -Access Control Entries (ACEs).

- -

There are four -possible types of a NFSv4 ACE:

- -

ARCHIVE_ENTRY_ACL_TYPE_ALLOW

- -

Allow principal to perform -actions requiring given permissions.

- -

ARCHIVE_ENTRY_ACL_TYPE_DENY

- -

Prevent principal from -performing actions requiring given permissions.

- -

ARCHIVE_ENTRY_ACL_TYPE_AUDIT

- -

Log access attempts by -principal which require given permissions.

- -

ARCHIVE_ENTRY_ACL_TYPE_ALARM

- -

Trigger a system alarm on -access attempts by principal which require given -permissions.

- -

The tag -specifies the principal to which the permission applies. -Valid values are:

- -

ARCHIVE_ENTRY_ACL_USER

- -

The user specified by the name -field.

- -

ARCHIVE_ENTRY_ACL_USER_OBJ

- -

The owner of the file.

- -

ARCHIVE_ENTRY_ACL_GROUP

- -

The group specified by the name -field.

- -

ARCHIVE_ENTRY_ACL_GROUP_OBJ

- -

The group which owns the -file.

- -

ARCHIVE_ENTRY_ACL_EVERYONE

- -

Any principal who is not the -file owner or a member of the owning group.

- -

Entries with the -ARCHIVE_ENTRY_ACL_USER or ARCHIVE_ENTRY_ACL_GROUP tag store -the user and group name in the name string and -optionally the user or group ID in the qualifier -integer.

- -

NFSv4 ACE -permissions and flags are stored in the same permset -bitfield. Some permissions share the same constant and -permission character but have different effect on -directories than on files. The following ACE permissions are -supported:

- -

ARCHIVE_ENTRY_ACL_READ_DATA (r)

- -

Read data (file).

- -

ARCHIVE_ENTRY_ACL_LIST_DIRECTORY (r)

- -

List entries (directory).

- -

ARCHIVE_ENTRY_ACL_WRITE_DATA (w)

- -

Write data (file).

- -

ARCHIVE_ENTRY_ACL_ADD_FILE (w)

- -

Create files (directory).

- -

ARCHIVE_ENTRY_ACL_EXECUTE (x)

- -

Execute file or change into a -directory.

- -

ARCHIVE_ENTRY_ACL_APPEND_DATA (p)

- -

Append data (file).

- -

ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY (p)

- -

Create subdirectories -(directory).

- -

ARCHIVE_ENTRY_ACL_DELETE_CHILD (D)

- -

Remove files and subdirectories -inside a directory.

- -

ARCHIVE_ENTRY_ACL_DELETE (d)

- -

Remove file or directory.

- -

ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES (a)

- -

Read file or directory -attributes.

- -

ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES (A)

- -

Write file or directory -attributes.

- -

ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS (R)

- -

Read named file or directory -attributes.

- -

ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS (W)

- -

Write named file or directory -attributes.

- -

ARCHIVE_ENTRY_ACL_READ_ACL (c)

- -

Read file or directory ACL.

- -

ARCHIVE_ENTRY_ACL_WRITE_ACL (C)

- -

Write file or directory -ACL.

- -

ARCHIVE_ENTRY_ACL_WRITE_OWNER (o)

- -

Change owner of a file or -directory.

- -

ARCHIVE_ENTRY_ACL_SYNCHRONIZE (s)

- -

Use synchronous I/O.

- -

The following -NFSv4 ACL inheritance flags are supported:

- -

ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT (f)

- -

Inherit parent directory ACE to -files.

- -

ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT (d)

- -

Inherit parent directory ACE to -subdirectories.

- -

ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY (i)

- -

Only inherit, do not apply the -permission on the directory itself.

- -

ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT -(n)

- -

Do not propagate inherit flags. -Only first-level entries inherit ACLs.

- -

ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS (S)

- -

Trigger alarm or audit on -successful access.

- -

ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS (F)

- -

Trigger alarm or audit on -failed access.

- -

ARCHIVE_ENTRY_ACL_ENTRY_INHERITED (I)

- -

Mark that ACE was -inherited.

- -

Functions -
-archive_entry_acl_add_entry
() and -archive_entry_acl_add_entry_w() add a single ACL -entry. For the access ACL and non-extended principals, the -classic Unix permissions are updated. An archive entry -cannot contain both POSIX.1e and NFSv4 ACL entries.

- - -

archive_entry_acl_clear() -removes all ACL entries and resets the enumeration -pointer.

- - -

archive_entry_acl_count() -counts the ACL entries that have the given type mask. -type can be the bitwise-or of

- -

ARCHIVE_ENTRY_ACL_TYPE_ACCESS
-ARCHIVE_ENTRY_ACL_TYPE_DEFAULT

- -

for POSIX.1e -ACLs and

- -

ARCHIVE_ENTRY_ACL_TYPE_ALLOW
-ARCHIVE_ENTRY_ACL_TYPE_DENY
-ARCHIVE_ENTRY_ACL_TYPE_AUDIT
-ARCHIVE_ENTRY_ACL_TYPE_ALARM

- -

for NFSv4 ACLs. -For POSIX.1e ACLs if ARCHIVE_ENTRY_ACL_TYPE_ACCESS is -included and at least one extended ACL entry is found, the -three non-extended ACLs are added.

- - -

archive_entry_acl_from_text() -and archive_entry_acl_from_text_w() add new (or merge -with existing) ACL entries from (wide) text. The argument -type may take one of the following values:

- -

ARCHIVE_ENTRY_ACL_TYPE_ACCESS
-ARCHIVE_ENTRY_ACL_TYPE_DEFAULT
-ARCHIVE_ENTRY_ACL_TYPE_NFS4

- -

Supports all -formats that can be created with -archive_entry_acl_to_text() or respectively -archive_entry_acl_to_text_w(). Existing ACL entries -are preserved. To get a clean new ACL from text -archive_entry_acl_clear() must be called first. -Entries prefixed with “default:” are treated as -ARCHIVE_ENTRY_ACL_TYPE_DEFAULT unless type is -ARCHIVE_ENTRY_ACL_TYPE_NFS4. Invalid entries, non-parseable -ACL entries and entries beginning with the ’#’ -character (comments) are skipped.

- - -

archive_entry_acl_next() -return the next entry of the ACL list. This functions may -only be called after archive_entry_acl_reset() has -indicated the presence of extended ACL entries.

- - -

archive_entry_acl_reset() -prepare reading the list of ACL entries with -archive_entry_acl_next(). The function returns 0 if -no non-extended ACLs are found. In this case, the access -permissions should be obtained by archive_entry_mode(3) or -set using chmod(2). Otherwise, the function returns the same -value as archive_entry_acl_count().

- - -

archive_entry_acl_to_text() -and archive_entry_acl_to_text_w() convert the ACL -entries for the given type into a (wide) string of ACL -entries separated by newline. If the pointer len_p is -not NULL, then the function shall return the length of the -string (not including the NULL terminator) in the location -pointed to by len_p. The flag argument is a -bitwise-or.

- -

The following -flags are effective only on POSIX.1e ACL:

- -

ARCHIVE_ENTRY_ACL_TYPE_ACCESS

- -

Output access ACLs.

- -

ARCHIVE_ENTRY_ACL_TYPE_DEFAULT

- -

Output POSIX.1e default -ACLs.

- -

ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT

- -

Prefix each default ACL entry -with the word “default:”.

- -

ARCHIVE_ENTRY_ACL_STYLE_SOLARIS

- -

The mask and other ACLs don not -contain a double colon.

- -

The following -flags are effecive only on NFSv4 ACL:

- -

ARCHIVE_ENTRY_ACL_STYLE_COMPACT

- -

Do not output minus characters -for unset permissions and flags in NFSv4 ACL permission and -flag fields.

- -

The following -flags are effective on both POSIX.1e and NFSv4 ACL:

- -

ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID

- -

Add an additional -colon-separated field containing the user or group id.

- -

ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA

- -

Separate ACL entries with comma -instead of newline.

- -

If the archive -entry contains NFSv4 ACLs, all types of NFSv4 ACLs are -returned. It the entry contains POSIX.1e ACLs and none of -the flags ARCHIVE_ENTRY_ACL_TYPE_ACCESS or -ARCHIVE_ENTRY_ACL_TYPE_DEFAULT are specified, both access -and default entries are returned and default entries are -prefixed with “default:”.

- - -

archive_entry_acl_types() -get ACL entry types contained in an archive entry’s -ACL. As POSIX.1e and NFSv4 ACL entries cannot be mixed, this -function is a very efficient way to detect if an ACL already -contains POSIX.1e or NFSv4 ACL entries.

- -

RETURN VALUES

- - -

archive_entry_acl_count() -and archive_entry_acl_reset() returns the number of -ACL entries that match the given type mask. For POSIX.1e -ACLS if the type mask includes ARCHIVE_ENTRY_ACL_TYPE_ACCESS -and at least one extended ACL entry exists, the three -classic Unix permissions are counted.

- - -

archive_entry_acl_from_text() -and archive_entry_acl_from_text_w() return ARCHIVE_OK -if all entries were successfully parsed and ARCHIVE_WARN if -one or more entries were invalid or non-parseable.

- - -

archive_entry_acl_next() -returns ARCHIVE_OK on success, ARCHIVE_EOF if no more ACL -entries exist and ARCHIVE_WARN if -archive_entry_acl_reset() has not been called -first.

- - -

archive_entry_acl_to_text() -returns a string representing the ACL entries matching the -given type and flags on success or NULL on error.

- - -

archive_entry_acl_to_text_w() -returns a wide string representing the ACL entries matching -the given type and flags on success or NULL on error.

- - -

archive_entry_acl_types() -returns a bitmask of ACL entry types or 0 if archive entry -has no ACL entries.

- -

SEE ALSO

- -

archive_entry(3), -libarchive(3)

- -

BSD -February 15, 2017 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_entry_linkify.3.html b/thirdparty/libarchive/doc/html/archive_entry_linkify.3.html deleted file mode 100644 index 17fd27882..000000000 --- a/thirdparty/libarchive/doc/html/archive_entry_linkify.3.html +++ /dev/null @@ -1,212 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_ENTRY_LINKIFY(3) BSD Library Functions Manual -ARCHIVE_ENTRY_LINKIFY(3)

- -

NAME

- - -

archive_entry_linkresolver, -archive_entry_linkresolver_new, -archive_entry_linkresolver_set_strategy, -archive_entry_linkresolver_free, -archive_entry_linkify — hardlink resolver -functions

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive_entry.h>

- -

struct -archive_entry_linkresolver *

- - -

archive_entry_linkresolver_new(void);

- -

void

- - -

archive_entry_linkresolver_set_strategy(struct archive_entry_linkresolver *resolver, -int format);

- -

void

- - -

archive_entry_linkresolver_free(struct archive_entry_linkresolver *resolver);

- -

void

- - -

archive_entry_linkify(struct archive_entry_linkresolver *resolver, -struct archive_entry **entry, -struct archive_entry **sparse);

- -

DESCRIPTION

- -

Programs that want to create -archives have to deal with hardlinks. Hardlinks are handled -in different ways by the archive formats. The basic -strategies are:

- -

1.

- -

Ignore hardlinks and store the -body for each reference (old cpio, zip).

- -

2.

- -

Store the body the first time -an inode is seen (ustar, pax).

- -

3.

- -

Store the body the last time an -inode is seen (new cpio).

- -

The -archive_entry_linkresolver functions help by -providing a unified interface and handling the complexity -behind the scene.

- -

The -archive_entry_linkresolver functions assume that -archive_entry instances have valid nlinks, inode and -device values. The inode and device value is used to match -entries. The nlinks value is used to determined if all -references have been found and if the internal references -can be recycled.

- -

The -archive_entry_linkresolver_new() function allocates a -new link resolver. The instance can be freed using -archive_entry_linkresolver_free(). All deferred -entries are flushed and the internal storage is freed.

- -

The -archive_entry_linkresolver_set_strategy() function -selects the optimal hardlink strategy for the given format. -The format code can be obtained from archive_format(3). The -function can be called more than once, but it is recommended -to flush all deferred entries first.

- -

The -archive_entry_linkify() function is the core of -archive_entry_linkresolver. The entry() -argument points to the archive_entry that should be -written. Depending on the strategy one of the following -actions is taken:

- -

1.

- -

For the simple archive formats -*entry is left unmodified and *sparse is set -to NULL.

- -

2.

- -

For tar like archive formats, -*sparse is set to NULL. If *entry is NULL, no -action is taken. If the hardlink count of *entry is -larger than 1 and the file type is a regular file or -symbolic link, the internal list is searched for a matching -inode. If such an inode is found, the link count is -decremented and the file size of *entry is set to 0 -to notify that no body should be written. If no such inode -is found, a copy of the entry is added to the internal cache -with a link count reduced by one.

- -

3.

- -

For new cpio like archive -formats a value for *entry of NULL is used to flush -deferred entries. In that case *entry is set to an -arbitrary deferred entry and the entry itself is removed -from the internal list. If the internal list is empty, -*entry is set to NULL. In either case, *sparse -is set to NULL and the function returns. If the hardlink -count of *entry is one or the file type is a -directory or device, *sparse is set to NULL and no -further action is taken. Otherwise, the internal list is -searched for a matching inode. If such an inode is not -found, the entry is added to the internal list, both -*entry and *sparse are set to NULL and the -function returns. If such an inode is found, the link count -is decremented. If it remains larger than one, the existing -entry on the internal list is swapped with *entry -after retaining the link count. The existing entry is -returned in *entry. If the link count reached one, -the new entry is also removed from the internal list and -returned in *sparse. Otherwise *sparse is set -to NULL.

- -

The general -usage is therefore:

- -

1.

- -

For each new archive entry, -call archive_entry_linkify().

- -

2.

- -

Keep in mind that the entries -returned may have a size of 0 now.

- -

3.

- -

If *entry is not NULL, -archive it.

- -

4.

- -

If *sparse is not NULL, -archive it.

- -

5.

- -

After all entries have been -written to disk, call archive_entry_linkify() with -*entry set to NULL and archive the returned entry as -long as it is not NULL.

- -

RETURN VALUES

- - -

archive_entry_linkresolver_new() -returns NULL on malloc(3) failures.

- -

SEE ALSO

- -

archive_entry(3)

- -

BSD -February 2, 2012 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_entry_misc.3.html b/thirdparty/libarchive/doc/html/archive_entry_misc.3.html deleted file mode 100644 index 58f90e7e6..000000000 --- a/thirdparty/libarchive/doc/html/archive_entry_misc.3.html +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_ENTRY_MISC(3) BSD Library Functions Manual -ARCHIVE_ENTRY_MISC(3)

- -

NAME

- - -

archive_entry_symlink_type, -archive_entry_set_symlink_type — miscellaneous -functions for manipulating properties of archive_entry

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive_entry.h>

- -

int

- - -

archive_entry_symlink_type(struct archive_entry *a);

- -

void

- - -

archive_entry_set_symlink_type(struct archive_entry *a, -int);

- -

DESCRIPTION

- -

The function -archive_entry_symlink_type() returns and the function -archive_entry_set_symlink_type() sets the type of the -symbolic link stored in an archive entry. These functions -have special meaning on operating systems that support -multiple symbolic link types (e.g. Microsoft Windows).

- -

Supported values -are:

- -

AE_SYMLINK_TYPE_UNDEFINED

- -

Symbolic link -target type is not defined (default on unix systems)

- -

AE_SYMLINK_TYPE_FILE

- -

Symbolic link -points to a file

- -

AE_SYMLINK_TYPE_DIRECTORY

- -

Symbolic link -points to a directory

- -

SEE ALSO

- -

archive_entry(3), -archive_entry_paths(3), archive_entry_stat(3), -libarchive(3)

- -

BSD -April 15, 2019 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_entry_paths.3.html b/thirdparty/libarchive/doc/html/archive_entry_paths.3.html deleted file mode 100644 index 189dc507c..000000000 --- a/thirdparty/libarchive/doc/html/archive_entry_paths.3.html +++ /dev/null @@ -1,284 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_ENTRY_PATHS(3) BSD Library Functions Manual -ARCHIVE_ENTRY_PATHS(3)

- -

NAME

- -

archive_entry_hardlink, -archive_entry_hardlink_w, -archive_entry_set_hardlink, -archive_entry_copy_hardlink, -archive_entry_copy_hardlink_w, -archive_entry_update_hardlink_utf8, -archive_entry_set_link, -archive_entry_copy_link, -archive_entry_copy_link_w, -archive_entry_update_link_utf8, -archive_entry_pathname, -archive_entry_pathname_w, -archive_entry_set_pathname, -archive_entry_copy_pathname, -archive_entry_copy_pathname_w, -archive_entry_update_pathname_utf8, -archive_entry_sourcepath, -archive_entry_copy_sourcepath, -archive_entry_symlink, -archive_entry_symlink_w, -archive_entry_set_symlink, -archive_entry_copy_symlink, -archive_entry_copy_symlink_w, -archive_entry_update_symlink_utf8 — functions -for manipulating path names in archive entry -descriptions

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive_entry.h>

- -

const char -*

- - -

archive_entry_hardlink(struct archive_entry *a);

- -

const wchar_t -*

- - -

archive_entry_hardlink_w(struct archive_entry *a);

- -

void

- - -

archive_entry_set_hardlink(struct archive_entry *a, -const char *path);

- -

void

- - -

archive_entry_copy_hardlink(struct archive_entry *a, -const char *path);

- -

void

- - -

archive_entry_copy_hardlink_w(struct archive_entry *a, -const, wchar_t, *path");

- -

int

- - -

archive_entry_update_hardlink_utf8(struct archive_entry *a, -const char *path);

- -

void

- - -

archive_entry_set_link(struct archive_entry *a, -const char *path);

- -

void

- - -

archive_entry_copy_link(struct archive_entry *a, -const char *path);

- -

void

- - -

archive_entry_copy_link_w(struct archive_entry *a, -const wchar_t *path);

- -

int

- - -

archive_entry_update_link_utf8(struct archive_entry *a, -const char *path);

- -

const char -*

- - -

archive_entry_pathname(struct archive_entry *a);

- -

const wchar_t -*

- - -

archive_entry_pathname_w(struct archive_entry *a);

- -

void

- - -

archive_entry_set_pathname(struct archive_entry *a, -const char *path);

- -

void

- - -

archive_entry_copy_pathname(struct archive_entry *a, -const char *path);

- -

void

- - -

archive_entry_copy_pathname_w(struct archive_entry *a, -const wchar_t *path);

- -

int

- - -

archive_entry_update_pathname_utf8(struct archive_entry *a, -const char *path);

- -

const char -*

- - -

archive_entry_sourcepath(struct archive_entry *a);

- -

void

- - -

archive_entry_copy_sourcepath(struct archive_entry *a, -const char *path);

- -

const char -*

- - -

archive_entry_symlink(struct archive_entry *a);

- -

const wchar_t -*

- - -

archive_entry_symlink_w(struct archive_entry *a);

- -

void

- - -

archive_entry_set_symlink(struct archive_entry *a, -const char *path);

- -

void

- - -

archive_entry_copy_symlink(struct archive_entry *a, -const char *path);

- -

void

- - -

archive_entry_copy_symlink_w(struct archive_entry *a, -const wchar_t *path);

- -

int

- - -

archive_entry_update_symlink_utf8(struct archive_entry *a, -const char *path);

- -

DESCRIPTION

- -

Path names supported by -archive_entry(3):

- -

hardlink

- -

Destination of -the hardlink.

- -

link

- -

Update only. -For a symlink, update the destination. Otherwise, make the -entry a hardlink and alter the destination for that.

- -

pathname

- -

Path in the -archive

- -

sourcepath

- -

Path on the -disk for use by archive_read_disk(3).

- -

symlink

- -

Destination of -the symbolic link.

- -

Path names can -be provided in one of three different ways:

- -

char *

- -

Multibyte -strings in the current locale.

- -

wchar_t *

- -

Wide character -strings in the current locale. The accessor functions are -named XXX_w().

- -

UTF-8

- -

Unicode strings -encoded as UTF-8. These are convenience functions to update -both the multibyte and wide character strings at the same -time.

- -

The sourcepath -is a pure filesystem concept and never stored in an archive -directly.

- -

For that reason, -it is only available as multibyte string. The link path is a -convenience function for conditionally setting hardlink or -symlink destination. It doesn’t have a corresponding -get accessor function.

- - -

archive_entry_set_XXX() -is an alias for archive_entry_copy_XXX().

- -

SEE ALSO

- -

archive_entry(3), -libarchive(3)

- -

BSD -February 2, 2012 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_entry_perms.3.html b/thirdparty/libarchive/doc/html/archive_entry_perms.3.html deleted file mode 100644 index 3264852b9..000000000 --- a/thirdparty/libarchive/doc/html/archive_entry_perms.3.html +++ /dev/null @@ -1,315 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_ENTRY_PERMS(3) BSD Library Functions Manual -ARCHIVE_ENTRY_PERMS(3)

- -

NAME

- -

archive_entry_gid, -archive_entry_set_gid, archive_entry_uid, -archive_entry_set_uid, archive_entry_perm, -archive_entry_set_perm, archive_entry_strmode, -archive_entry_uname, archive_entry_uname_w, -archive_entry_set_uname, -archive_entry_copy_uname, -archive_entry_copy_uname_w, -archive_entry_update_uname_utf8, -archive_entry_gname, archive_entry_gname_w, -archive_entry_set_gname, -archive_entry_copy_gname, -archive_entry_copy_gname_w, -archive_entry_update_gname_utf8, -archive_entry_fflags, -archive_entry_fflags_text, -archive_entry_set_fflags, -archive_entry_copy_fflags_text, -archive_entry_copy_fflags_text_w — functions -for manipulating ownership and permissions in archive entry -descriptions

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive_entry.h>

- - -

gid_t

- - -

archive_entry_gid(struct archive_entry *a);

- -

void

- - -

archive_entry_set_gid(struct archive_entry *a, -gid_t gid);

- - -

uid_t

- - -

archive_entry_uid(struct archive_entry *a);

- -

void

- - -

archive_entry_set_uid(struct archive_entry *a, -uid_t uid);

- - -

mode_t

- - -

archive_entry_perm(struct archive_entry *a);

- -

void

- - -

archive_entry_set_perm(struct archive_entry *a, -mode_t mode);

- -

const char -*

- - -

archive_entry_strmode(struct archive_entry *a);

- -

const char -*

- - -

archive_entry_gname(struct archive_entry *a);

- -

const wchar_t -*

- - -

archive_entry_gname_w(struct archive_entry *a);

- -

void

- - -

archive_entry_set_gname(struct archive_entry *a, -const char *a);

- -

void

- - -

archive_entry_copy_gname(struct archive_entry *a, -const char *name);

- -

void

- - -

archive_entry_copy_gname_w(struct archive_entry *a, -const wchar_t *name);

- -

int

- - -

archive_entry_update_gname_utf8(struct archive_entry *a, -const char *name);

- -

const char -*

- - -

archive_entry_uname(struct archive_entry *a);

- -

const wchar_t -*

- - -

archive_entry_uname_w(struct archive_entry *a);

- -

void

- - -

archive_entry_set_uname(struct archive_entry *a, -const char *name);

- -

void

- - -

archive_entry_copy_uname(struct archive_entry *a, -const char *name);

- -

void

- - -

archive_entry_copy_uname_w(struct archive_entry *a, -const wchar_t *name);

- -

int

- - -

archive_entry_update_uname_utf8(struct archive_entry *a, -const char *name);

- -

void

- - -

archive_entry_fflags(struct archive_entry *a, -unsigned long *set_bits, -unsigned long *clear_bits);

- -

const char -*

- - -

archive_entry_fflags_text(struct archive_entry *a);

- -

void

- - -

archive_entry_set_fflags(struct archive_entry *a, -unsigned long set_bits, -unsigned long clear_bits);

- -

const char -*

- - -

archive_entry_copy_fflags_text(struct archive_entry *a, -const char *text);

- -

const wchar_t -*

- - -

archive_entry_copy_fflags_text_w(struct archive_entry *a, -const wchar_t *text);

- -

DESCRIPTION

- -

User id, group id and -mode
-The functions archive_entry_uid(), -archive_entry_gid(), and archive_entry_perm() -can be used to extract the user id, group id and permission -from the given entry. The corresponding functions -archive_entry_set_uid(), -archive_entry_set_gid(), and -archive_entry_set_perm() store the given user id, -group id and permission in the entry. The permission is also -set as a side effect of calling -archive_entry_set_mode().

- - -

archive_entry_strmode() -returns a string representation of the permission as used by -the long mode of ls(1).

- -

User and -group name
-User and group names can be provided in one of three -different ways:

- -

char *

- -

Multibyte -strings in the current locale.

- -

wchar_t *

- -

Wide character -strings in the current locale. The accessor functions are -named XXX_w().

- -

UTF-8

- -

Unicode strings -encoded as UTF-8. These are convenience functions to update -both the multibyte and wide character strings at the same -time.

- - -

archive_entry_set_XXX() -is an alias for archive_entry_copy_XXX().

- -

File -Flags
-File flags are transparently converted between a bitmap -representation and a textual format. For example, if you set -the bitmap and ask for text, the library will build a -canonical text format. However, if you set a text format and -request a text format, you will get back the same text, even -if it is ill-formed. If you need to canonicalize a textual -flags string, you should first set the text form, then -request the bitmap form, then use that to set the bitmap -form. Setting the bitmap format will clear the internal text -representation and force it to be reconstructed when you -next request the text form.

- -

The bitmap -format consists of two integers, one containing bits that -should be set, the other specifying bits that should be -cleared. Bits not mentioned in either bitmap will be -ignored. Usually, the bitmap of bits to be cleared will be -set to zero. In unusual circumstances, you can force a -fully-specified set of file flags by setting the bitmap of -flags to clear to the complement of the bitmap of flags to -set. (This differs from fflagstostr(3), which only includes -names for set bits.) Converting a bitmap to a textual string -is a platform-specific operation; bits that are not -meaningful on the current platform will be ignored.

- -

The canonical -text format is a comma-separated list of flag names. The -archive_entry_copy_fflags_text() and -archive_entry_copy_fflags_text_w() functions parse -the provided text and set the internal bitmap values. This -is a platform-specific operation; names that are not -meaningful on the current platform will be ignored. The -function returns a pointer to the start of the first name -that was not recognized, or NULL if every name was -recognized. Note that every name — including names -that follow an unrecognized name — will be evaluated, -and the bitmaps will be set to reflect every name that is -recognized. (In particular, this differs from -strtofflags(3), which stops parsing at the first -unrecognized name.)

- -

SEE ALSO

- -

archive_entry(3), -archive_entry_acl(3), archive_read_disk(3), -archive_write_disk(3), libarchive(3)

- -

BUGS

- -

The platform types uid_t -and gid_t are often 16 or 32 bit wide. In this case -it is possible that the ids can not be correctly restored -from archives and get truncated.

- -

BSD -February 2, 2012 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_entry_stat.3.html b/thirdparty/libarchive/doc/html/archive_entry_stat.3.html deleted file mode 100644 index 873a668b3..000000000 --- a/thirdparty/libarchive/doc/html/archive_entry_stat.3.html +++ /dev/null @@ -1,381 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_ENTRY_STAT(3) BSD Library Functions Manual -ARCHIVE_ENTRY_STAT(3)

- -

NAME

- -

archive_entry_stat, -archive_entry_copy_stat, -archive_entry_filetype, -archive_entry_set_filetype, -archive_entry_mode, archive_entry_set_mode, -archive_entry_size, archive_entry_size_is_set, -archive_entry_set_size, -archive_entry_unset_size, archive_entry_dev, -archive_entry_set_dev, -archive_entry_dev_is_set, -archive_entry_devmajor, -archive_entry_set_devmajor, -archive_entry_devminor, -archive_entry_set_devminor, archive_entry_ino, -archive_entry_set_ino, -archive_entry_ino_is_set, archive_entry_ino64, -archive_entry_set_ino64, archive_entry_nlink, -archive_entry_rdev, archive_entry_set_rdev, -archive_entry_rdevmajor, -archive_entry_set_rdevmajor, -archive_entry_rdevminor, -archive_entry_set_rdevminor — accessor -functions for manipulating archive entry descriptions

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive_entry.h>

- -

const struct -stat *

- - -

archive_entry_stat(struct archive_entry *a);

- -

void

- - -

archive_entry_copy_stat(struct archive_entry *a, -const struct stat *sb);

- - -

mode_t

- - -

archive_entry_filetype(struct archive_entry *a);

- -

void

- - -

archive_entry_set_filetype(struct archive_entry *a, -unsigned int type);

- - -

mode_t

- - -

archive_entry_mode(struct archive_entry *a);

- -

void

- - -

archive_entry_set_mode(struct archive_entry *a, -mode_t mode);

- - -

int64_t

- - -

archive_entry_size(struct archive_entry *a);

- -

int

- - -

archive_entry_size_is_set(struct archive_entry *a);

- -

void

- - -

archive_entry_set_size(struct archive_entry *a, -int64_t size);

- -

void

- - -

archive_entry_unset_size(struct archive_entry *a);

- - -

dev_t

- - -

archive_entry_dev(struct archive_entry *a);

- -

void

- - -

archive_entry_set_dev(struct archive_entry *a, -dev_t dev);

- -

int

- - -

archive_entry_dev_is_set(struct archive_entry *a);

- - -

dev_t

- - -

archive_entry_devmajor(struct archive_entry *a);

- -

void

- - -

archive_entry_set_devmajor(struct archive_entry *a, -dev_t major);

- - -

dev_t

- - -

archive_entry_devminor(struct archive_entry *a);

- -

void

- - -

archive_entry_set_devminor(struct archive_entry *a, -dev_t minor);

- - -

ino_t

- - -

archive_entry_ino(struct archive_entry *a);

- -

void

- - -

archive_entry_set_ino(struct archive_entry *a, -unsigned long ino);

- -

int

- - -

archive_entry_ino_is_set(struct archive_entry *a);

- - -

int64_t

- - -

archive_entry_ino64(struct archive_entry *a);

- -

void

- - -

archive_entry_set_ino64(struct archive_entry *a, -int64_t ino);

- -

unsigned -int

- - -

archive_entry_nlink(struct archive_entry *a);

- -

void

- - -

archive_entry_set_nlink(struct archive_entry *a, -unsigned int count);

- - -

dev_t

- - -

archive_entry_rdev(struct archive_entry *a);

- - -

dev_t

- - -

archive_entry_rdevmajor(struct archive_entry *a);

- - -

dev_t

- - -

archive_entry_rdevminor(struct archive_entry *a);

- -

void

- - -

archive_entry_set_rdev(struct archive_entry *a, -dev_t dev);

- -

void

- - -

archive_entry_set_rdevmajor(struct archive_entry *a, -dev_t major);

- -

void

- - -

archive_entry_set_rdevminor(struct archive_entry *a, -dev_t minor);

- -

DESCRIPTION

- -

Copying to and from -struct stat
-The function archive_entry_stat() converts the -various fields stored in the archive entry to the format -used by stat(2). The return value remains valid until either -archive_entry_clear() or archive_entry_free() -is called. It is not affected by calls to the set accessor -functions. It currently sets the following values in -struct stat: st_atime, st_ctime, -st_dev, st_gid, st_ino, st_mode, -st_mtime, st_nlink, st_rdev, -st_size, st_uid. In addition, -st_birthtime and high-precision information for -time-related fields will be included on platforms that -support it.

- -

The function -archive_entry_copy_stat() copies fields from the -platform’s struct stat. Fields not provided by -struct stat are unchanged.

- -

General -accessor functions
-The functions archive_entry_filetype() and -archive_entry_set_filetype() get respectively set the -filetype. The file type is one of the following -constants:

- -

AE_IFREG

- -

Regular -file

- -

AE_IFLNK

- -

Symbolic -link

- -

AE_IFSOCK

- -

Socket

- -

AE_IFCHR

- -

Character -device

- -

AE_IFBLK

- -

Block -device

- -

AE_IFDIR

- -

Directory

- -

AE_IFIFO

- -

Named pipe -(fifo)

- -

Not all file types are supported -by all platforms. The constants used by stat(2) may have -different numeric values from the corresponding constants -above.

- -

The functions -archive_entry_mode() and -archive_entry_set_mode() get/set a combination of -file type and permissions and provide the equivalent of -st_mode. Use of archive_entry_filetype() and -archive_entry_perm() for getting and -archive_entry_set_filetype() and -archive_entry_set_perm() for setting is -recommended.

- -

The function -archive_entry_size() returns the file size, if it has -been set, and 0 otherwise. archive_entry_size() can -be used to query that status. -archive_entry_set_size() and -archive_entry_unset_size() set and unset the size, -respectively.

- -

The number of -references (hardlinks) can be obtained by calling -archive_entry_nlink() and set with -archive_entry_set_nlink().

- -

Identifying -unique files
-The functions archive_entry_dev() and -archive_entry_ino64() are used by -archive_entry_linkify(3) to find hardlinks. The pair of -device and inode is supposed to identify hardlinked -files.

- -

The device major -and minor number can be obtained independently using -archive_entry_devmajor() and -archive_entry_devminor(). The device can be set -either via archive_entry_set_dev() or by the -combination of major and minor number using -archive_entry_set_devmajor() and -archive_entry_set_devminor().

- -

The inode number -can be obtained using archive_entry_ino(). This is a -legacy interface that uses the platform ino_t, which -may be very small. To set the inode number, -archive_entry_set_ino64() is the preferred -interface.

- -

Accessor -functions for block and character devices
-Block and character devices are characterised either using a -device number or a pair of major and minor number. The -combined device number can be obtained with -archive_device_rdev() and set with -archive_device_set_rdev(). The major and minor -numbers are accessed by archive_device_rdevmajor(), -archive_device_rdevminor() -archive_device_set_rdevmajor() and -archive_device_set_rdevminor().

- -

The process of -splitting the combined device number into major and minor -number and the reverse process of combing them differs -between platforms. Some archive formats use the combined -form, while other formats use the split form.

- -

SEE ALSO

- -

stat(2), archive_entry_acl(3), -archive_entry_perms(3), archive_entry_time(3), -libarchive(3)

- -

BSD -February 2, 2012 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_entry_time.3.html b/thirdparty/libarchive/doc/html/archive_entry_time.3.html deleted file mode 100644 index e1ebb8254..000000000 --- a/thirdparty/libarchive/doc/html/archive_entry_time.3.html +++ /dev/null @@ -1,205 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_ENTRY_TIME(3) BSD Library Functions Manual -ARCHIVE_ENTRY_TIME(3)

- -

NAME

- -

archive_entry_atime, -archive_entry_atime_nsec, -archive_entry_atime_is_set, -archive_entry_set_atime, -archive_entry_unset_atime, -archive_entry_birthtime, -archive_entry_birthtime_nsec, -archive_entry_birthtime_is_set, -archive_entry_set_birthtime, -archive_entry_unset_birthtime, -archive_entry_ctime, archive_entry_ctime_nsec, -archive_entry_ctime_is_set, -archive_entry_set_ctime, -archive_entry_unset_ctime, -archive_entry_mtime, archive_entry_mtime_nsec, -archive_entry_mtime_is_set, -archive_entry_set_mtime, -archive_entry_unset_mtime — functions for -manipulating times in archive entry descriptions

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive_entry.h>

- - -

time_t

- - -

archive_entry_atime(struct archive_entry *a);

- -

long

- - -

archive_entry_atime_nsec(struct archive_entry *a);

- -

int

- - -

archive_entry_atime_is_set(struct archive_entry *a);

- -

void

- - -

archive_entry_set_atime(struct archive_entry *a, -time_t sec, long nanosec);

- -

void

- - -

archive_entry_unset_atime(struct archive_entry *a);

- - -

time_t

- - -

archive_entry_birthtime(struct archive_entry *a);

- -

long

- - -

archive_entry_birthtime_nsec(struct archive_entry *a);

- -

int

- - -

archive_entry_birthtime_is_set(struct archive_entry *a);

- -

void

- - -

archive_entry_set_birthtime(struct archive_entry *a, -time_t sec, long nanosec);

- -

void

- - -

archive_entry_unset_birthtime(struct archive_entry *a);

- - -

time_t

- - -

archive_entry_ctime(struct archive_entry *a);

- -

long

- - -

archive_entry_ctime_nsec(struct archive_entry *a);

- -

int

- - -

archive_entry_ctime_is_set(struct archive_entry *a);

- -

void

- - -

archive_entry_set_ctime(struct archive_entry *a, -time_t sec, long nanosec);

- -

void

- - -

archive_entry_unset_ctime(struct archive_entry *a);

- - -

time_t

- - -

archive_entry_mtime(struct archive_entry *a);

- -

long

- - -

archive_entry_mtime_nsec(struct archive_entry *a);

- -

int

- - -

archive_entry_mtime_is_set(struct archive_entry *a);

- -

void

- - -

archive_entry_set_mtime(struct archive_entry *a, -time_t sec, long nanosec);

- -

void

- - -

archive_entry_unset_mtime(struct archive_entry *a);

- -

DESCRIPTION

- -

These functions create and -manipulate the time fields in an archive_entry. -Supported time fields are atime (access time), birthtime -(creation time), ctime (last time an inode property was -changed) and mtime (modification time).

- -

libarchive(3) -provides a high-resolution interface. The timestamps are -truncated automatically depending on the archive format (for -archiving) or the filesystem capabilities (for -restoring).

- -

All timestamp -fields are optional. The XXX_unset() functions can be -used to mark the corresponding field as missing. The current -state can be queried using XXX_is_set(). Unset time -fields have a second and nanosecond field of 0.

- -

SEE ALSO

- -

archive_entry(3), -libarchive(3)

- -

HISTORY

- -

The libarchive library -first appeared in FreeBSD 5.3.

- -

AUTHORS

- -

The libarchive library -was written by Tim Kientzle <kientzle@acm.org>.

- -

BSD -February 2, 2012 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_read.3.html b/thirdparty/libarchive/doc/html/archive_read.3.html deleted file mode 100644 index a5b33febf..000000000 --- a/thirdparty/libarchive/doc/html/archive_read.3.html +++ /dev/null @@ -1,233 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_READ(3) BSD Library Functions Manual -ARCHIVE_READ(3)

- -

NAME

- -

archive_read — -functions for reading streaming archives

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive.h>

- -

DESCRIPTION

- -

These functions provide a -complete API for reading streaming archives. The general -process is to first create the struct archive object, set -options, initialize the reader, iterate over the archive -headers and associated data, then close the archive and -release all resources.

- -

Create -archive object
-See archive_read_new(3).

- -

To read an -archive, you must first obtain an initialized struct archive -object from archive_read_new().

- -

Enable -filters and formats
-See archive_read_filter(3) and archive_read_format(3).

- -

You can then -modify this object for the desired operations with the -various archive_read_set_XXX() and -archive_read_support_XXX() functions. In particular, -you will need to invoke appropriate -archive_read_support_XXX() functions to enable the -corresponding compression and format support. Note that -these latter functions perform two distinct operations: they -cause the corresponding support code to be linked into your -program, and they enable the corresponding auto-detect code. -Unless you have specific constraints, you will generally -want to invoke archive_read_support_filter_all() and -archive_read_support_format_all() to enable -auto-detect for all formats and compression types currently -supported by the library.

- -

Set -options
-See archive_read_set_options(3).

- -

Open -archive
-See archive_read_open(3).

- -

Once you have -prepared the struct archive object, you call -archive_read_open() to actually open the archive and -prepare it for reading. There are several variants of this -function; the most basic expects you to provide pointers to -several functions that can provide blocks of bytes from the -archive. There are convenience forms that allow you to -specify a filename, file descriptor, FILE * object, -or a block of memory from which to read the archive data. -Note that the core library makes no assumptions about the -size of the blocks read; callback functions are free to read -whatever block size is most appropriate for the medium.

- -

Consume -archive
-See archive_read_header(3), archive_read_data(3) and -archive_read_extract(3).

- -

Each archive -entry consists of a header followed by a certain amount of -data. You can obtain the next header with -archive_read_next_header(), which returns a pointer -to an struct archive_entry structure with information about -the current archive element. If the entry is a regular file, -then the header will be followed by the file data. You can -use archive_read_data() (which works much like the -read(2) system call) to read this data from the archive, or -archive_read_data_block() which provides a slightly -more efficient interface. You may prefer to use the -higher-level archive_read_data_skip(), which reads -and discards the data for this entry, -archive_read_data_into_fd(), which copies the data to -the provided file descriptor, or -archive_read_extract(), which recreates the specified -entry on disk and copies data from the archive. In -particular, note that archive_read_extract() uses the -struct archive_entry structure that you provide it, which -may differ from the entry just read from the archive. In -particular, many applications will want to override the -pathname, file permissions, or ownership.

- -

Release -resources
-See archive_read_free(3).

- -

Once you have -finished reading data from the archive, you should call -archive_read_close() to close the archive, then call -archive_read_free() to release all resources, -including all memory allocated by the library.

- -

EXAMPLES

- -

The following illustrates basic -usage of the library. In this example, the callback -functions are simply wrappers around the standard open(2), -read(2), and close(2) system calls.

- -

void
-list_archive(const char *name)
-{
-struct mydata *mydata;
-struct archive *a;
-struct archive_entry *entry;

- -

mydata = -malloc(sizeof(struct mydata));
-a = archive_read_new();
-mydata->name = name;
-archive_read_support_filter_all(a);
-archive_read_support_format_all(a);
-archive_read_open(a, mydata, myopen, myread, myclose);
-while (archive_read_next_header(a, &entry) == -ARCHIVE_OK) {
-printf("%s\n",archive_entry_pathname(entry));
-archive_read_data_skip(a);
-}
-archive_read_free(a);
-free(mydata);
-}

- -

la_ssize_t
-myread(struct archive *a, void *client_data, const void -**buff)
-{
-struct mydata *mydata = client_data;

- -

*buff = -mydata->buff;
-return (read(mydata->fd, mydata->buff, 10240));
-}

- -

int
-myopen(struct archive *a, void *client_data)
-{
-struct mydata *mydata = client_data;

- -

mydata->fd = -open(mydata->name, O_RDONLY);
-return (mydata->fd >= 0 ? ARCHIVE_OK : ARCHIVE_FATAL); -
-}

- -

int
-myclose(struct archive *a, void *client_data)
-{
-struct mydata *mydata = client_data;

- -

if -(mydata->fd > 0)
-close(mydata->fd);
-return (ARCHIVE_OK);
-}

- -

SEE ALSO

- -

tar(1), archive_read_data(3), -archive_read_extract(3), archive_read_filter(3), -archive_read_format(3), archive_read_header(3), -archive_read_new(3), archive_read_open(3), -archive_read_set_options(3), archive_util(3), libarchive(3), -tar(5)

- -

HISTORY

- -

The libarchive library -first appeared in FreeBSD 5.3.

- -

AUTHORS

- -

The libarchive library -was written by Tim Kientzle <kientzle@acm.org>.

- -

BUGS

- -

Many traditional archiver -programs treat empty files as valid empty archives. For -example, many implementations of tar(1) allow you to append -entries to an empty file. Of course, it is impossible to -determine the format of an empty file by inspecting the -contents, so this library treats empty files as having a -special “empty” format.

- -

BSD -February 2, 2012 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_read_add_passphrase.3.html b/thirdparty/libarchive/doc/html/archive_read_add_passphrase.3.html deleted file mode 100644 index 7287edf0a..000000000 --- a/thirdparty/libarchive/doc/html/archive_read_add_passphrase.3.html +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_READ_ADD_PASS... BSD Library Functions Manual -ARCHIVE_READ_ADD_PASS...

- -

NAME

- - -

archive_read_add_passphrase, -archive_read_set_passphrase_callback — -functions for reading encrypted archives

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive.h>

- -

int

- - -

archive_read_add_passphrase(struct archive *, -const char *passphrase);

- -

int

- - -

archive_read_set_passphrase_callback(struct archive *, -void *client_data, -archive_passphrase_callback *);

- -

DESCRIPTION
-archive_read_add_passphrase
()

- -

Register passphrases for -reading an encryption archive. If passphrase is NULL -or empty, this function will do nothing and -ARCHIVE_FAILED will be returned. Otherwise, -ARCHIVE_OK will be returned.

- - -

archive_read_set_passphrase_callback()

- -

Register a callback function -that will be invoked to get a passphrase for decryption -after trying all the passphrases registered by the -archive_read_add_passphrase() function failed.

- -

SEE ALSO

- -

tar(1), archive_read(3), -archive_read_set_options(3), libarchive(3)

- -

BSD -September 14, 2014 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_read_data.3.html b/thirdparty/libarchive/doc/html/archive_read_data.3.html deleted file mode 100644 index 1bf9c1e95..000000000 --- a/thirdparty/libarchive/doc/html/archive_read_data.3.html +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_READ_DATA(3) BSD Library Functions Manual -ARCHIVE_READ_DATA(3)

- -

NAME

- -

archive_read_data, -archive_read_data_block, -archive_read_data_skip, -archive_read_data_into_fd — functions for -reading streaming archives

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive.h>

- - -

la_ssize_t

- - -

archive_read_data(struct archive *, -void *buff, size_t len);

- -

int

- - -

archive_read_data_block(struct archive *, -const void **buff, size_t *len, -off_t *offset);

- -

int

- - -

archive_read_data_skip(struct archive *);

- -

int

- - -

archive_read_data_into_fd(struct archive *, -int fd);

- -

DESCRIPTION
-archive_read_data
()

- -

Read data associated with the -header just read. Internally, this is a convenience function -that calls archive_read_data_block() and fills any -gaps with nulls so that callers see a single continuous -stream of data.

- -

archive_read_data_block()

- -

Return the next available block -of data for this entry. Unlike archive_read_data(), -the archive_read_data_block() function avoids copying -data and allows you to correctly handle sparse files, as -supported by some archive formats. The library guarantees -that offsets will increase and that blocks will not overlap. -Note that the blocks returned from this function can be much -larger than the block size read from disk, due to -compression and internal buffer optimizations.

- -

archive_read_data_skip()

- -

A convenience function that -repeatedly calls archive_read_data_block() to skip -all of the data for this archive entry. Note that this -function is invoked automatically by -archive_read_next_header2() if the previous entry was -not completely consumed.

- -

archive_read_data_into_fd()

- -

A convenience function that -repeatedly calls archive_read_data_block() to copy -the entire entry to the provided file descriptor.

- -

RETURN VALUES

- -

Most functions return zero on -success, non-zero on error. The possible return codes -include: ARCHIVE_OK (the operation succeeded), -ARCHIVE_WARN (the operation succeeded but a -non-critical error was encountered), ARCHIVE_EOF -(end-of-archive was encountered), ARCHIVE_RETRY (the -operation failed but can be retried), and -ARCHIVE_FATAL (there was a fatal error; the archive -should be closed immediately).

- - -

archive_read_data() -returns a count of bytes actually read or zero at the end of -the entry. On error, a value of ARCHIVE_FATAL, -ARCHIVE_WARN, or ARCHIVE_RETRY is -returned.

- -

ERRORS

- -

Detailed error codes and textual -descriptions are available from the archive_errno() -and archive_error_string() functions.

- -

SEE ALSO

- -

tar(1), archive_read(3), -archive_read_extract(3), archive_read_filter(3), -archive_read_format(3), archive_read_header(3), -archive_read_open(3), archive_read_set_options(3), -archive_util(3), libarchive(3), tar(5)

- -

BSD -February 2, 2012 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_read_disk.3.html b/thirdparty/libarchive/doc/html/archive_read_disk.3.html deleted file mode 100644 index dd827f38d..000000000 --- a/thirdparty/libarchive/doc/html/archive_read_disk.3.html +++ /dev/null @@ -1,518 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_READ_DISK(3) BSD Library Functions Manual -ARCHIVE_READ_DISK(3)

- -

NAME

- -

archive_read_disk_new, -archive_read_disk_open, -archive_read_disk_open_w, -archive_read_disk_set_behavior, -archive_read_disk_set_symlink_logical, -archive_read_disk_set_symlink_physical, -archive_read_disk_set_symlink_hybrid, -archive_read_disk_entry_from_file, -archive_read_disk_gname, -archive_read_disk_uname, -archive_read_disk_set_uname_lookup, -archive_read_disk_set_gname_lookup, -archive_read_disk_set_standard_lookup, -archive_read_disk_descend, -archive_read_disk_can_descend, -archive_read_disk_current_filesystem, -archive_read_disk_current_filesystem_is_synthetic, -archive_read_disk_current_filesystem_is_remote, -archive_read_disk_set_matching, -archive_read_disk_set_metadata_filter_callback, -— functions for reading objects from disk

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive.h>

- -

struct -archive *

- - -

archive_read_disk_new(void);

- -

int

- - -

archive_read_disk_open(struct archive *, -const char *);

- -

int

- - -

archive_read_disk_open_w(struct archive *, -const wchar_t *);

- -

int

- - -

archive_read_disk_set_behavior(struct archive *, -int);

- -

int

- - -

archive_read_disk_set_symlink_logical(struct archive *);

- -

int

- - -

archive_read_disk_set_symlink_physical(struct archive *);

- -

int

- - -

archive_read_disk_set_symlink_hybrid(struct archive *);

- -

const char -*

- - -

archive_read_disk_gname(struct archive *, -gid_t);

- -

const char -*

- - -

archive_read_disk_uname(struct archive *, -uid_t);

- -

int

- - -

archive_read_disk_set_gname_lookup(struct archive *, -void *, -const char *(*lookup)(void *, gid_t), -void (*cleanup)(void *));

- -

int

- - -

archive_read_disk_set_uname_lookup(struct archive *, -void *, -const char *(*lookup)(void *, uid_t), -void (*cleanup)(void *));

- -

int

- - -

archive_read_disk_set_standard_lookup(struct archive *);

- -

int

- - -

archive_read_disk_entry_from_file(struct archive *, -struct archive_entry *, int fd, -const struct stat *);

- -

int

- - -

archive_read_disk_descend(struct archive *);

- -

int

- - -

archive_read_disk_can_descend(struct archive *);

- -

int

- - -

archive_read_disk_current_filesystem(struct archive *);

- -

int

- - -

archive_read_disk_current_filesystem_is_synthetic(struct archive *);

- -

int

- - -

archive_read_disk_current_filesystem_is_remote(struct archive *);

- -

int

- - -

archive_read_disk_set_matching(struct archive *, -struct archive *, -void (*excluded_func)(struct archive *, void *, struct archive entry *), -void *);

- -

int

- - -

archive_read_disk_set_metadata_filter_callback(struct archive *, -int (*metadata_filter_func)(struct archive *, void*, struct archive_entry *), -void *);

- -

DESCRIPTION

- -

These functions provide an API -for reading information about objects on disk. In -particular, they provide an interface for populating struct -archive_entry objects.

- - -

archive_read_disk_new()

- -

Allocates and initializes a -struct archive object suitable for reading object -information from disk.

- - -

archive_read_disk_open()

- -

Opens the file or directory -from the given path and prepares the struct archive to read -it from disk.

- - -

archive_read_disk_open_w()

- -

Opens the file or directory -from the given path as a wide character string and prepares -the struct archive to read it from disk.

- - -

archive_read_disk_set_behavior()

- -

Configures various behavior -options when reading entries from disk. The flags field -consists of a bitwise OR of one or more of the following -values:

- -

ARCHIVE_READDISK_HONOR_NODUMP

- -

Skip files and directories with -the nodump file attribute (file flag) set. By default, the -nodump file attribute is ignored.

- -

ARCHIVE_READDISK_MAC_COPYFILE

- -

Mac OS X specific. Read -metadata (ACLs and extended attributes) with copyfile(3). By -default, metadata is read using copyfile(3).

- -

ARCHIVE_READDISK_NO_ACL

- -

Do not read Access Control -Lists. By default, ACLs are read from disk.

- -

ARCHIVE_READDISK_NO_FFLAGS

- -

Do not read file attributes -(file flags). By default, file attributes are read from -disk. See chattr(1) (Linux) or chflags(1) (FreeBSD, Mac OS -X) for more information on file attributes.

- -

ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS

- -

Do not traverse mount points. -By default, mount points are traversed.

- -

ARCHIVE_READDISK_NO_XATTR

- -

Do not read extended file -attributes (xattrs). By default, extended file attributes -are read from disk. See xattr(7) (Linux), xattr(2) (Mac OS -X), or getextattr(8) (FreeBSD) for more information on -extended file attributes.

- -

ARCHIVE_READDISK_RESTORE_ATIME

- -

Restore access time of -traversed files. By default, access time of traversed files -is not restored.

- -

ARCHIVE_READDISK_NO_SPARSE

- -

Do not read sparse file -information. By default, sparse file information is read -from disk.

- - -

archive_read_disk_set_symlink_logical(), -archive_read_disk_set_symlink_physical(), -archive_read_disk_set_symlink_hybrid()

- -

This sets the mode used for -handling symbolic links. The “logical” mode -follows all symbolic links. The “physical” mode -does not follow any symbolic links. The “hybrid” -mode currently behaves identically to the -“logical” mode.

- - -

archive_read_disk_gname(), -archive_read_disk_uname()

- -

Returns a user or group name -given a gid or uid value. By default, these always return a -NULL string.

- - -

archive_read_disk_set_gname_lookup(), -archive_read_disk_set_uname_lookup()

- -

These allow you to override the -functions used for user and group name lookups. You may also -provide a void * pointer to a private data structure and a -cleanup function for that data. The cleanup function will be -invoked when the struct archive object is destroyed or when -new lookup functions are registered.

- - -

archive_read_disk_set_standard_lookup()

- -

This convenience function -installs a standard set of user and group name lookup -functions. These functions use getpwuid(3) and getgrgid(3) -to convert ids to names, defaulting to NULL if the names -cannot be looked up. These functions also implement a simple -memory cache to reduce the number of calls to getpwuid(3) -and getgrgid(3).

- - -

archive_read_disk_entry_from_file()

- -

Populates a struct -archive_entry object with information about a particular -file. The archive_entry object must have already been -created with archive_entry_new(3) and at least one of the -source path or path fields must already be set. (If both are -set, the source path will be used.)

- -

Information is -read from disk using the path name from the struct -archive_entry object. If a file descriptor is provided, some -information will be obtained using that file descriptor, on -platforms that support the appropriate system calls.

- -

If a pointer to -a struct stat is provided, information from that structure -will be used instead of reading from the disk where -appropriate. This can provide performance benefits in -scenarios where struct stat information has already been -read from the disk as a side effect of some other operation. -(For example, directory traversal libraries often provide -this information.)

- -

Where -necessary, user and group ids are converted to user and -group names using the currently-registered lookup functions -above. This affects the file ownership fields and ACL values -in the struct archive_entry object.

- - -

archive_read_disk_descend()

- -

If the current entry can be -descended, this function will mark the directory as the next -entry for archive_read_header(3) to visit.

- - -

archive_read_disk_can_descend()

- -

Returns 1 if the current entry -is an unvisited directory and 0 otherwise.

- - -

archive_read_disk_current_filesystem()

- -

Returns the index of the most -recent filesystem entry that has been visited through -archive_read_disk

- - -

archive_read_disk_current_filesystem_is_synthetic()

- -

Returns 1 if the current -filesystem is a virtual filesystem. Returns 0 if the current -filesystem is not a virtual filesystem. Returns -1 if it is -unknown.

- - -

archive_read_disk_current_filesystem_is_remote()

- -

Returns 1 if the current -filesystem is a remote filesystem. Returns 0 if the current -filesystem is not a remote filesystem. Returns -1 if it is -unknown.

- - -

archive_read_disk_set_matching()

- -

Allows the caller to set struct -archive *_ma to compare each entry during -archive_read_header(3) calls. If matched based on calls to -archive_match_path_excluded, archive_match_time_excluded, or -archive_match_owner_excluded, then the callback function -specified by the _excluded_func parameter will execute. This -function will recieve data provided to the fourth parameter, -void *_client_data.

- - -

archive_read_disk_set_metadata_filter_callback()

- -

Allows the caller to set a -callback function during calls to archive_read_header(3) to -filter out metadata for each entry. The callback function -recieves the struct archive object, void* custom filter -data, and the struct archive_entry. If the callback function -returns an error, ARCHIVE_RETRY will be returned and the -entry will not be further processed.

- -

More information about the -struct archive object and the overall design of the -library can be found in the libarchive(3) overview.

- -

EXAMPLES

- -

The following illustrates basic -usage of the library by showing how to use it to copy an -item on disk into an archive.

- -

void
-file_to_archive(struct archive *a, const char *name)
-{
-char buff[8192];
-size_t bytes_read;
-struct archive *ard;
-struct archive_entry *entry;
-int fd;

- -

ard = -archive_read_disk_new();
-archive_read_disk_set_standard_lookup(ard);
-entry = archive_entry_new();
-fd = open(name, O_RDONLY);
-if (fd < 0)
-return;
-archive_entry_copy_pathname(entry, name);
-archive_read_disk_entry_from_file(ard, entry, fd, NULL); -
-archive_write_header(a, entry);
-while ((bytes_read = read(fd, buff, sizeof(buff))) > 0) -
-archive_write_data(a, buff, bytes_read);
-archive_write_finish_entry(a);
-archive_read_free(ard);
-archive_entry_free(entry);
-}

- -

RETURN VALUES

- -

Most functions return -ARCHIVE_OK (zero) on success, or one of several -negative error codes for errors. Specific error codes -include: ARCHIVE_RETRY for operations that might -succeed if retried, ARCHIVE_WARN for unusual -conditions that do not prevent further operations, and -ARCHIVE_FATAL for serious errors that make remaining -operations impossible.

- - -

archive_read_disk_new() -returns a pointer to a newly-allocated struct archive object -or NULL if the allocation failed for any reason.

- - -

archive_read_disk_gname() -and archive_read_disk_uname() return const char * -pointers to the textual name or NULL if the lookup failed -for any reason. The returned pointer points to internal -storage that may be reused on the next call to either of -these functions; callers should copy the string if they need -to continue accessing it.

- -

ERRORS

- -

Detailed error codes and textual -descriptions are available from the archive_errno() -and archive_error_string() functions.

- -

SEE ALSO

- -

tar(1), archive_read(3), -archive_util(3), archive_write(3), archive_write_disk(3), -libarchive(3)

- -

HISTORY

- -

The libarchive library -first appeared in FreeBSD 5.3. The -archive_read_disk interface was added to -libarchive 2.6 and first appeared in -FreeBSD 8.0.

- -

AUTHORS

- -

The libarchive library -was written by Tim Kientzle -<kientzle@FreeBSD.org>.

- -

BUGS

- -

The “standard” user -name and group name lookup functions are not the defaults -because getgrgid(3) and getpwuid(3) are sometimes too large -for particular applications. The current design allows the -application author to use a more compact implementation when -appropriate.

- -

The full list of -metadata read from disk by -archive_read_disk_entry_from_file() is necessarily -system-dependent.

- -

The -archive_read_disk_entry_from_file() function reads as -much information as it can from disk. Some method should be -provided to limit this so that clients who do not need ACLs, -for instance, can avoid the extra work needed to look up -such information.

- -

This API should -provide a set of methods for walking a directory tree. That -would make it a direct parallel of the archive_read(3) API. -When such methods are implemented, the “hybrid” -symbolic link mode will make sense.

- -

BSD -April 3, 2017 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_read_extract.3.html b/thirdparty/libarchive/doc/html/archive_read_extract.3.html deleted file mode 100644 index 02f343a64..000000000 --- a/thirdparty/libarchive/doc/html/archive_read_extract.3.html +++ /dev/null @@ -1,134 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_READ_EXTRACT(3) BSD Library Functions Manual -ARCHIVE_READ_EXTRACT(3)

- -

NAME

- -

archive_read_extract, -archive_read_extract2, -archive_read_extract_set_progress_callback — -functions for reading streaming archives

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive.h>

- -

int

- - -

archive_read_extract(struct archive *, -struct archive_entry *, -int flags);

- -

int

- - -

archive_read_extract2(struct archive *src, -struct archive_entry *, -struct archive *dest);

- -

void

- - -

archive_read_extract_set_progress_callback(struct archive *, -void (*func)(void *), -void *user_data);

- -

DESCRIPTION
-archive_read_extract
(), -archive_read_extract_set_skip_file()

- -

A convenience function that -wraps the corresponding archive_write_disk(3) interfaces. -The first call to archive_read_extract() creates a -restore object using archive_write_disk_new(3) and -archive_write_disk_set_standard_lookup(3), then -transparently invokes archive_write_disk_set_options(3), -archive_write_header(3), archive_write_data(3), and -archive_write_finish_entry(3) to create the entry on disk -and copy data into it. The flags argument is passed -unmodified to archive_write_disk_set_options(3).

- -

archive_read_extract2()

- -

This is another version of -archive_read_extract() that allows you to provide -your own restore object. In particular, this allows you to -override the standard lookup functions using -archive_write_disk_set_group_lookup(3), and -archive_write_disk_set_user_lookup(3). Note that -archive_read_extract2() does not accept a -flags argument; you should use -archive_write_disk_set_options() to set the restore -options yourself.

- -

archive_read_extract_set_progress_callback()

- -

Sets a pointer to a -user-defined callback that can be used for updating progress -displays during extraction. The progress function will be -invoked during the extraction of large regular files. The -progress function will be invoked with the pointer provided -to this call. Generally, the data pointed to should include -a reference to the archive object and the archive_entry -object so that various statistics can be retrieved for the -progress display.

- -

RETURN VALUES

- -

Most functions return zero on -success, non-zero on error. The possible return codes -include: ARCHIVE_OK (the operation succeeded), -ARCHIVE_WARN (the operation succeeded but a -non-critical error was encountered), ARCHIVE_EOF -(end-of-archive was encountered), ARCHIVE_RETRY (the -operation failed but can be retried), and -ARCHIVE_FATAL (there was a fatal error; the archive -should be closed immediately).

- -

ERRORS

- -

Detailed error codes and textual -descriptions are available from the archive_errno() -and archive_error_string() functions.

- -

SEE ALSO

- -

tar(1), archive_read(3), -archive_read_data(3), archive_read_filter(3), -archive_read_format(3), archive_read_open(3), -archive_read_set_options(3), archive_util(3), libarchive(3), -tar(5)

- -

BSD -February 2, 2012 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_read_filter.3.html b/thirdparty/libarchive/doc/html/archive_read_filter.3.html deleted file mode 100644 index b275bb8c0..000000000 --- a/thirdparty/libarchive/doc/html/archive_read_filter.3.html +++ /dev/null @@ -1,223 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_READ_FILTER(3) BSD Library Functions Manual -ARCHIVE_READ_FILTER(3)

- -

NAME

- - -

archive_read_support_filter_all, -archive_read_support_filter_bzip2, -archive_read_support_filter_compress, -archive_read_support_filter_gzip, -archive_read_support_filter_lz4, -archive_read_support_filter_lzma, -archive_read_support_filter_none, -archive_read_support_filter_rpm, -archive_read_support_filter_uu, -archive_read_support_filter_xz, -archive_read_support_filter_zstd, -archive_read_support_filter_program, -archive_read_support_filter_program_signature — -functions for reading streaming archives

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive.h>

- -

int

- - -

archive_read_support_filter_all(struct archive *);

- -

int

- - -

archive_read_support_filter_by_code(struct archive *, -int);

- -

int

- - -

archive_read_support_filter_bzip2(struct archive *);

- -

int

- - -

archive_read_support_filter_compress(struct archive *);

- -

int

- - -

archive_read_support_filter_grzip(struct archive *);

- -

int

- - -

archive_read_support_filter_gzip(struct archive *);

- -

int

- - -

archive_read_support_filter_lrzip(struct archive *);

- -

int

- - -

archive_read_support_filter_lz4(struct archive *);

- -

int

- - -

archive_read_support_filter_lzma(struct archive *);

- -

int

- - -

archive_read_support_filter_lzop(struct archive *);

- -

int

- - -

archive_read_support_filter_none(struct archive *);

- -

int

- - -

archive_read_support_filter_rpm(struct archive *);

- -

int

- - -

archive_read_support_filter_uu(struct archive *);

- -

int

- - -

archive_read_support_filter_xz(struct archive *);

- -

int

- - -

archive_read_support_filter_zstd(struct archive *);

- -

int

- - -

archive_read_support_filter_program(struct archive *, -const char *cmd);

- -

int

- - -

archive_read_support_filter_program_signature(struct archive *, -const char *cmd, -const void *signature, -size_t signature_length);

- -

DESCRIPTION
-archive_read_support_filter_bzip2
(), -archive_read_support_filter_compress(), -archive_read_support_filter_grzip(), -archive_read_support_filter_gzip(), -archive_read_support_filter_lrzip(), -archive_read_support_filter_lz4(), -archive_read_support_filter_lzma(), -archive_read_support_filter_lzop(), -archive_read_support_filter_none(), -archive_read_support_filter_rpm(), -archive_read_support_filter_uu(), -archive_read_support_filter_xz(), -archive_read_support_filter_zstd(),

- -

Enables auto-detection code and -decompression support for the specified compression. These -functions may fall back on external programs if an -appropriate library was not available at build time. -Decompression using an external program is usually slower -than decompression through built-in libraries. Note that -“none” is always enabled by default.

- -

archive_read_support_filter_all()

- -

Enables all available -decompression filters.

- -

archive_read_support_filter_by_code()

- -

Enables a single filter -specified by the filter code. This function does not work -with ARCHIVE_FILTER_PROGRAM. Note: In -statically-linked executables, this will cause your program -to include support for every filter. If executable size is a -concern, you may wish to avoid using this function.

- -

archive_read_support_filter_program()

- -

Data is fed through the -specified external program before being dearchived. Note -that this disables automatic detection of the compression -format, so it makes no sense to specify this in conjunction -with any other decompression option.

- - -

archive_read_support_filter_program_signature()

- -

This feeds data through the -specified external program but only if the initial bytes of -the data match the specified signature value.

- -

RETURN VALUES

- -

These functions return -ARCHIVE_OK if the compression is fully supported, -ARCHIVE_WARN if the compression is supported only -through an external program.

- - -

archive_read_support_filter_none() -always succeeds.

- -

ERRORS

- -

Detailed error codes and textual -descriptions are available from the archive_errno() -and archive_error_string() functions.

- -

SEE ALSO

- -

archive_read(3), -archive_read_data(3), archive_read_format(3), -archive_read_format(3), libarchive(3)

- -

BSD June 9, -2020 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_read_format.3.html b/thirdparty/libarchive/doc/html/archive_read_format.3.html deleted file mode 100644 index 0cf56172a..000000000 --- a/thirdparty/libarchive/doc/html/archive_read_format.3.html +++ /dev/null @@ -1,225 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_READ_FORMAT(3) BSD Library Functions Manual -ARCHIVE_READ_FORMAT(3)

- -

NAME

- - -

archive_read_support_format_7zip, -archive_read_support_format_all, -archive_read_support_format_ar, -archive_read_support_format_by_code, -archive_read_support_format_cab, -archive_read_support_format_cpio, -archive_read_support_format_empty, -archive_read_support_format_iso9660, -archive_read_support_format_lha, -archive_read_support_format_mtree, -archive_read_support_format_rar, -archive_read_support_format_raw, -archive_read_support_format_tar, -archive_read_support_format_xar, -archive_read_support_format_zip — functions for -reading streaming archives

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive.h>

- -

int

- - -

archive_read_support_format_7zip(struct archive *);

- -

int

- - -

archive_read_support_format_all(struct archive *);

- -

int

- - -

archive_read_support_format_ar(struct archive *);

- -

int

- - -

archive_read_support_format_by_code(struct archive *, -int);

- -

int

- - -

archive_read_support_format_cab(struct archive *);

- -

int

- - -

archive_read_support_format_cpio(struct archive *);

- -

int

- - -

archive_read_support_format_empty(struct archive *);

- -

int

- - -

archive_read_support_format_iso9660(struct archive *);

- -

int

- - -

archive_read_support_format_lha(struct archive *);

- -

int

- - -

archive_read_support_format_mtree(struct archive *);

- -

int

- - -

archive_read_support_format_rar(struct archive *);

- -

int

- - -

archive_read_support_format_raw(struct archive *);

- -

int

- - -

archive_read_support_format_tar(struct archive *);

- -

int

- - -

archive_read_support_format_xar(struct archive *);

- -

int

- - -

archive_read_support_format_zip(struct archive *);

- -

DESCRIPTION
-archive_read_support_format_7zip
(), -archive_read_support_format_ar(), -archive_read_support_format_cab(), -archive_read_support_format_cpio(), -archive_read_support_format_iso9660(), -archive_read_support_format_lha(), -archive_read_support_format_mtree(), -archive_read_support_format_rar(), -archive_read_support_format_raw(), -archive_read_support_format_tar(), -archive_read_support_format_xar(), -archive_read_support_format_zip()

- -

Enables support---including -auto-detection code---for the specified archive format. For -example, archive_read_support_format_tar() enables -support for a variety of standard tar formats, old-style -tar, ustar, pax interchange format, and many common -variants.

- -

archive_read_support_format_all()

- -

Enables support for all -available formats except the “raw” format (see -below).

- -

archive_read_support_format_by_code()

- -

Enables a single format -specified by the format code. This can be useful when -reading a single archive twice; use archive_format() -after reading the first time and pass the resulting code to -this function to selectively enable only the necessary -format support. Note: In statically-linked executables, this -will cause your program to include support for every format. -If executable size is a concern, you may wish to avoid using -this function.

- -

archive_read_support_format_empty()

- -

Enables support for treating -empty files as empty archives. Because empty files are valid -for several different formats, it is not possible to -accurately determine a format for an empty file based purely -on contents. So empty files are treated by libarchive as a -distinct format.

- -

archive_read_support_format_raw()

- -

The “raw” format -handler allows libarchive to be used to read arbitrary data. -It treats any data stream as an archive with a single entry. -The pathname of this entry is “data”; all other -entry fields are unset. This is not enabled by -archive_read_support_format_all() in order to avoid -erroneous handling of damaged archives.

- -

RETURN VALUES

- -

These functions return -ARCHIVE_OK on success, or ARCHIVE_FATAL.

- -

ERRORS

- -

Detailed error codes and textual -descriptions are available from the archive_errno() -and archive_error_string() functions.

- -

SEE ALSO

- -

tar(1), archive_read_data(3), -archive_read_filter(3), archive_read_set_options(3), -archive_util(3), libarchive(3), tar(5)

- -

BUGS

- -

Many traditional archiver -programs treat empty files as valid empty archives. For -example, many implementations of tar(1) allow you to append -entries to an empty file. Of course, it is impossible to -determine the format of an empty file by inspecting the -contents, so this library treats empty files as having a -special “empty” format.

- -

Using the -“raw” handler together with any other handler -will often work but can produce surprising results.

- -

BSD -February 2, 2012 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_read_free.3.html b/thirdparty/libarchive/doc/html/archive_read_free.3.html deleted file mode 100644 index 839d1883c..000000000 --- a/thirdparty/libarchive/doc/html/archive_read_free.3.html +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_READ_FREE(3) BSD Library Functions Manual -ARCHIVE_READ_FREE(3)

- -

NAME

- -

archive_read_close, -archive_read_finish, archive_read_free — -functions for reading streaming archives

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive.h>

- -

int

- - -

archive_read_close(struct archive *);

- -

int

- - -

archive_read_finish(struct archive *);

- -

int

- - -

archive_read_free(struct archive *);

- -

DESCRIPTION
-archive_read_close
()

- -

Complete the archive and invoke -the close callback.

- -

archive_read_finish()

- -

This is a deprecated synonym -for archive_read_free(). The new name was introduced -with libarchive 3.0. Applications that need to compile with -either libarchive 2 or libarchive 3 should continue to use -the archive_read_finish() name. Both names will be -supported until libarchive 4.0 is released, which is not -expected to occur earlier than 2013.

- -

archive_read_free()

- -

Invokes -archive_read_close() if it was not invoked manually, -then release all resources. Note: In libarchive 1.x, this -function was declared to return void, which made it -impossible to detect certain errors when -archive_read_close() was invoked implicitly from this -function. The declaration is corrected beginning with -libarchive 2.0.

- -

RETURN VALUES

- -

These functions return -ARCHIVE_OK on success, or ARCHIVE_FATAL.

- -

ERRORS

- -

Detailed error codes and textual -descriptions are available from the archive_errno() -and archive_error_string() functions.

- -

SEE ALSO

- -

archive_read_data(3), -archive_read_filter(3), archive_read_format(3), -archive_read_new(3), archive_read_open(3), -archive_read_set_options(3), archive_util(3), -libarchive(3)

- -

BSD -February 2, 2012 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_read_header.3.html b/thirdparty/libarchive/doc/html/archive_read_header.3.html deleted file mode 100644 index 2ec4a4849..000000000 --- a/thirdparty/libarchive/doc/html/archive_read_header.3.html +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_READ_HEADER(3) BSD Library Functions Manual -ARCHIVE_READ_HEADER(3)

- -

NAME

- - -

archive_read_next_header, -archive_read_next_header2 — functions for -reading streaming archives

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive.h>

- -

int

- - -

archive_read_next_header(struct archive *, -struct archive_entry **);

- -

int

- - -

archive_read_next_header2(struct archive *, -struct archive_entry *);

- -

DESCRIPTION
-archive_read_next_header
()

- -

Read the header for the next -entry and return a pointer to a struct archive_entry. This -is a convenience wrapper around -archive_read_next_header2() that reuses an internal -struct archive_entry object for each request.

- -

archive_read_next_header2()

- -

Read the header for the next -entry and populate the provided struct archive_entry.

- -

RETURN VALUES

- -

These functions return -ARCHIVE_OK (the operation succeeded), -ARCHIVE_WARN (the operation succeeded but a -non-critical error was encountered), ARCHIVE_EOF -(end-of-archive was encountered), ARCHIVE_RETRY (the -operation failed but can be retried), and -ARCHIVE_FATAL (there was a fatal error; the archive -should be closed immediately).

- -

ERRORS

- -

Detailed error codes and textual -descriptions are available from the archive_errno() -and archive_error_string() functions.

- -

SEE ALSO

- -

tar(1), archive_read(3), -archive_read_data(3), archive_read_extract(3), -archive_read_filter(3), archive_read_format(3), -archive_read_open(3), archive_read_set_options(3), -archive_util(3), libarchive(3), tar(5)

- -

BSD -February 2, 2012 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_read_new.3.html b/thirdparty/libarchive/doc/html/archive_read_new.3.html deleted file mode 100644 index c39962bac..000000000 --- a/thirdparty/libarchive/doc/html/archive_read_new.3.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_READ_NEW(3) BSD Library Functions Manual -ARCHIVE_READ_NEW(3)

- -

NAME

- -

archive_read_new — -functions for reading streaming archives

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive.h>

- -

struct -archive *

- - -

archive_read_new(void);

- -

DESCRIPTION

- -

Allocates and initializes a -struct archive object suitable for reading from an archive. -NULL is returned on error.

- -

A complete -description of the struct archive object can be found in the -overview manual page for libarchive(3).

- -

SEE ALSO

- -

tar(1), archive_read_data(3), -archive_read_filter(3), archive_read_format(3), -archive_read_set_options(3), archive_util(3), libarchive(3), -tar(5)

- -

BSD -February 2, 2012 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_read_open.3.html b/thirdparty/libarchive/doc/html/archive_read_open.3.html deleted file mode 100644 index b3b2e3a11..000000000 --- a/thirdparty/libarchive/doc/html/archive_read_open.3.html +++ /dev/null @@ -1,240 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_READ_OPEN(3) BSD Library Functions Manual -ARCHIVE_READ_OPEN(3)

- -

NAME

- -

archive_read_open, -archive_read_open2, archive_read_open_fd, -archive_read_open_FILE, -archive_read_open_filename, -archive_read_open_memory — functions for -reading streaming archives

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive.h>

- -

int

- - -

archive_read_open(struct archive *, -void *client_data, -archive_open_callback *, -archive_read_callback *, -archive_close_callback *);

- -

int

- - -

archive_read_open2(struct archive *, -void *client_data, -archive_open_callback *, -archive_read_callback *, -archive_skip_callback *, -archive_close_callback *);

- -

int

- - -

archive_read_open_FILE(struct archive *, -FILE *file);

- -

int

- - -

archive_read_open_fd(struct archive *, -int fd, size_t block_size);

- -

int

- - -

archive_read_open_filename(struct archive *, -const char *filename, -size_t block_size);

- -

int

- - -

archive_read_open_memory(struct archive *, -const void *buff, -size_t size);

- -

DESCRIPTION
-archive_read_open
()

- -

The same as -archive_read_open2(), except that the skip callback -is assumed to be NULL.

- -

archive_read_open2()

- -

Freeze the settings, open the -archive, and prepare for reading entries. This is the most -generic version of this call, which accepts four callback -functions. Most clients will want to use -archive_read_open_filename(), -archive_read_open_FILE(), -archive_read_open_fd(), or -archive_read_open_memory() instead. The library -invokes the client-provided functions to obtain raw bytes -from the archive.

- -

archive_read_open_FILE()

- -

Like -archive_read_open(), except that it accepts a FILE -* pointer. This function should not be used with tape -drives or other devices that require strict I/O -blocking.

- -

archive_read_open_fd()

- -

Like -archive_read_open(), except that it accepts a file -descriptor and block size rather than a set of function -pointers. Note that the file descriptor will not be -automatically closed at end-of-archive. This function is -safe for use with tape drives or other blocked devices.

- -

archive_read_open_file()

- -

This is a deprecated synonym -for archive_read_open_filename().

- -

archive_read_open_filename()

- -

Like -archive_read_open(), except that it accepts a simple -filename and a block size. A NULL filename represents -standard input. This function is safe for use with tape -drives or other blocked devices.

- -

archive_read_open_memory()

- -

Like -archive_read_open(), except that it accepts a pointer -and size of a block of memory containing the archive -data.

- -

A complete -description of the struct archive and struct archive_entry -objects can be found in the overview manual page for -libarchive(3).

- -

CLIENT CALLBACKS

- -

The callback functions must -match the following prototypes:

- -

typedef -la_ssize_t

- - -

archive_read_callback(struct archive *, -void *client_data, -const void **buffer)

- -

typedef -la_int64_t

- - -

archive_skip_callback(struct archive *, -void *client_data, -off_t request)

- -

typedef -int archive_open_callback(struct archive -*, void *client_data)

- -

typedef -int archive_close_callback(struct archive -*, void *client_data)

- -

The open -callback is invoked by archive_open(). It should -return ARCHIVE_OK if the underlying file or data -source is successfully opened. If the open fails, it should -call archive_set_error() to register an error code -and message and return ARCHIVE_FATAL.

- -

The read -callback is invoked whenever the library requires raw bytes -from the archive. The read callback should read data into a -buffer, set the const void **buffer argument to point to the -available data, and return a count of the number of bytes -available. The library will invoke the read callback again -only after it has consumed this data. The library imposes no -constraints on the size of the data blocks returned. On -end-of-file, the read callback should return zero. On error, -the read callback should invoke archive_set_error() -to register an error code and message and return -1.

- -

The skip -callback is invoked when the library wants to ignore a block -of data. The return value is the number of bytes actually -skipped, which may differ from the request. If the callback -cannot skip data, it should return zero. If the skip -callback is not provided (the function pointer is NULL ), -the library will invoke the read function instead and simply -discard the result. A skip callback can provide significant -performance gains when reading uncompressed archives from -slow disk drives or other media that can skip quickly.

- -

The close -callback is invoked by archive_close when the archive -processing is complete. The callback should return -ARCHIVE_OK on success. On failure, the callback -should invoke archive_set_error() to register an -error code and message and return ARCHIVE_FATAL.

- -

RETURN VALUES

- -

These functions return -ARCHIVE_OK on success, or ARCHIVE_FATAL.

- -

ERRORS

- -

Detailed error codes and textual -descriptions are available from the archive_errno() -and archive_error_string() functions.

- -

SEE ALSO

- -

tar(1), archive_read(3), -archive_read_data(3), archive_read_filter(3), -archive_read_format(3), archive_read_set_options(3), -archive_util(3), libarchive(3), tar(5)

- -

BSD -February 2, 2012 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_read_set_options.3.html b/thirdparty/libarchive/doc/html/archive_read_set_options.3.html deleted file mode 100644 index dfbf279a1..000000000 --- a/thirdparty/libarchive/doc/html/archive_read_set_options.3.html +++ /dev/null @@ -1,293 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_READ_OPTIONS(3) BSD Library Functions Manual -ARCHIVE_READ_OPTIONS(3)

- -

NAME

- - -

archive_read_set_filter_option, -archive_read_set_format_option, -archive_read_set_option, -archive_read_set_options — functions -controlling options for reading archives

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

int

- - -

archive_read_set_filter_option(struct archive *, -const char *module, -const char *option, -const char *value);

- -

int

- - -

archive_read_set_format_option(struct archive *, -const char *module, -const char *option, -const char *value);

- -

int

- - -

archive_read_set_option(struct archive *, -const char *module, -const char *option, -const char *value);

- -

int

- - -

archive_read_set_options(struct archive *, -const char *options);

- -

DESCRIPTION

- -

These functions provide a way -for libarchive clients to configure specific read -modules.

- - -

archive_read_set_filter_option(), -archive_read_set_format_option()

- -

Specifies an option that will -be passed to currently-registered filters (including -decompression filters) or format readers.

- -

If -option and value are both NULL, these -functions will do nothing and ARCHIVE_OK will be -returned. If option is NULL but value is not, -these functions will do nothing and ARCHIVE_FAILED -will be returned.

- -

If -module is not NULL, option and value -will be provided to the filter or reader named -module. The return value will be that of the module. -If there is no such module, ARCHIVE_FAILED will be -returned.

- -

If -module is NULL, option and value will -be provided to every registered module. If any module -returns ARCHIVE_FATAL, this value will be returned -immediately. Otherwise, ARCHIVE_OK will be returned -if any module accepts the option, and ARCHIVE_FAILED -in all other cases.

- - -

archive_read_set_option()

- -

Calls -archive_read_set_format_option(), then -archive_read_set_filter_option(). If either function -returns ARCHIVE_FATAL, ARCHIVE_FATAL will be -returned immediately. Otherwise, greater of the two values -will be returned.

- - -

archive_read_set_options()

- -

options is a -comma-separated list of options. If options is NULL -or empty, ARCHIVE_OK will be returned -immediately.

- -

Calls -archive_read_set_option() with each option in turn. -If any archive_read_set_option() call returns -ARCHIVE_FATAL, ARCHIVE_FATAL will be returned -immediately.

- -

Individual -options have one of the following forms:

- -

option=value

- -

The option/value pair will be -provided to every module. Modules that do not accept an -option with this name will ignore it.

- -

option

- -

The option will -be provided to every module with a value of -“1”.

- -

!option

- -

The option will be provided to -every module with a NULL value.

- -

module:option=value, module:option, -module:!option

- -

As above, but the corresponding -option and value will be provided only to modules whose name -matches module.

- -

OPTIONS
-Format cab
-hdrcharset

- -

The value is used as a -character set name that will be used when translating file -names.

- -

Format cpio
-compat-2x

- -

Libarchive 2.x incorrectly -encoded Unicode filenames on some platforms. This option -mimics the libarchive 2.x filename handling so that such -archives can be read correctly.

- -

hdrcharset

- -

The value is used as a -character set name that will be used when translating file -names.

- -

pwb

- -

When reading a -binary CPIO archive, assume that it is in the original PWB -cpio format, and handle file mode bits accordingly. The -default is to assume v7 format.

- -

Format iso9660
-joliet

- -

Support Joliet -extensions. Defaults to enabled, use !joliet to -disable.

- -

rockridge

- -

Support RockRidge extensions. -Defaults to enabled, use !rockridge to disable.

- -

Format lha
-hdrcharset

- -

The value is used as a -character set name that will be used when translating file -names.

- -

Format mtree
-checkfs

- -

Allow reading information -missing from the mtree from the file system. Disabled by -default.

- -

Format rar
-hdrcharset

- -

The value is used as a -character set name that will be used when translating file -names.

- -

Format tar
-compat-2x

- -

Libarchive 2.x incorrectly -encoded Unicode filenames on some platforms. This option -mimics the libarchive 2.x filename handling so that such -archives can be read correctly.

- -

hdrcharset

- -

The value is used as a -character set name that will be used when translating file -names.

- -

mac-ext

- -

Support Mac OS metadata -extension that records data in special files beginning with -a period and underscore. Defaults to enabled on Mac OS, -disabled on other platforms. Use !mac-ext to -disable.

- -

read_concatenated_archives

- -

Ignore zeroed blocks in the -archive, which occurs when multiple tar archives have been -concatenated together. Without this option, only the -contents of the first concatenated archive would be -read.

- -

Format zip
-compat-2x

- -

Libarchive 2.x incorrectly -encoded Unicode filenames on some platforms. This option -mimics the libarchive 2.x filename handling so that such -archives can be read correctly.

- -

hdrcharset

- -

The value is used as a -character set name that will be used when translating file -names.

- -

ignorecrc32

- -

Skip the CRC32 check. Mostly -used for testing.

- -

mac-ext

- -

Support Mac OS metadata -extension that records data in special files beginning with -a period and underscore. Defaults to enabled on Mac OS, -disabled on other platforms. Use !mac-ext to -disable.

- -

ERRORS

- -

Detailed error codes and textual -descriptions are available from the archive_errno() -and archive_error_string() functions.

- -

SEE ALSO

- -

tar(1), archive_read(3), -archive_write_set_options(3), libarchive(3)

- -

BSD -January 31, 2020 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_util.3.html b/thirdparty/libarchive/doc/html/archive_util.3.html deleted file mode 100644 index f1d82972d..000000000 --- a/thirdparty/libarchive/doc/html/archive_util.3.html +++ /dev/null @@ -1,284 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_UTIL(3) BSD Library Functions Manual -ARCHIVE_UTIL(3)

- -

NAME

- -

archive_clear_error, -archive_compression, archive_compression_name, -archive_copy_error, archive_errno, -archive_error_string, archive_file_count, -archive_filter_code, archive_filter_count, -archive_filter_name, archive_format, -archive_format_name, archive_position, -archive_set_error — libarchive utility -functions

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive.h>

- -

void

- - -

archive_clear_error(struct archive *);

- -

int

- - -

archive_compression(struct archive *);

- -

const char -*

- - -

archive_compression_name(struct archive *);

- -

void

- - -

archive_copy_error(struct archive *, -struct archive *);

- -

int

- - -

archive_errno(struct archive *);

- -

const char -*

- - -

archive_error_string(struct archive *);

- -

int

- - -

archive_file_count(struct archive *);

- -

int

- - -

archive_filter_code(struct archive *, -int);

- -

int

- - -

archive_filter_count(struct archive *, -int);

- -

const char -*

- - -

archive_filter_name(struct archive *, -int);

- -

int

- - -

archive_format(struct archive *);

- -

const char -*

- - -

archive_format_name(struct archive *);

- - -

int64_t

- - -

archive_position(struct archive *, -int);

- -

void

- - -

archive_set_error(struct archive *, -int error_code, -const char *fmt, ...);

- -

DESCRIPTION

- -

These functions provide access -to various information about the struct archive object used -in the libarchive(3) library.

- -

archive_clear_error()

- -

Clears any error information -left over from a previous call. Not generally used in client -code.

- -

archive_compression()

- -

Synonym for -archive_filter_code(a, 0).

- -

archive_compression_name()

- -

Synonym for -archive_filter_name(a, 0).

- -

archive_copy_error()

- -

Copies error information from -one archive to another.

- -

archive_errno()

- -

Returns a numeric error code -(see errno(2)) indicating the reason for the most recent -error return. Note that this can not be reliably used to -detect whether an error has occurred. It should be used only -after another libarchive function has returned an error -status.

- -

archive_error_string()

- -

Returns a textual error message -suitable for display. The error message here is usually more -specific than that obtained from passing the result of -archive_errno() to strerror(3).

- -

archive_file_count()

- -

Returns a count of the number -of files processed by this archive object. The count is -incremented by calls to archive_write_header(3) or -archive_read_next_header(3).

- -

archive_filter_code()

- -

Returns a numeric code -identifying the indicated filter. See -archive_filter_count() for details of the -numbering.

- -

archive_filter_count()

- -

Returns the number of filters -in the current pipeline. For read archive handles, these -filters are added automatically by the automatic format -detection. For write archive handles, these filters are -added by calls to the various -archive_write_add_filter_XXX() functions. Filters in -the resulting pipeline are numbered so that filter 0 is the -filter closest to the format handler. As a convenience, -functions that expect a filter number will accept -1 as a -synonym for the highest-numbered filter.

- -

For example, -when reading a uuencoded gzipped tar archive, there are -three filters: filter 0 is the gunzip filter, filter 1 is -the uudecode filter, and filter 2 is the pseudo-filter that -wraps the archive read functions. In this case, requesting -archive_position(a, -1) would be a -synonym for archive_position(a, 2) -which would return the number of bytes currently read from -the archive, while archive_position(a, -1) would return the number of bytes after uudecoding, -and archive_position(a, 0) would return -the number of bytes after decompression.

- -

archive_filter_name()

- -

Returns a textual name -identifying the indicated filter. See -archive_filter_count() for details of the -numbering.

- -

archive_format()

- -

Returns a numeric code -indicating the format of the current archive entry. This -value is set by a successful call to -archive_read_next_header(). Note that it is common -for this value to change from entry to entry. For example, a -tar archive might have several entries that utilize GNU tar -extensions and several entries that do not. These entries -will have different format codes.

- -

archive_format_name()

- -

A textual description of the -format of the current entry.

- -

archive_position()

- -

Returns the number of bytes -read from or written to the indicated filter. In particular, -archive_position(a, 0) returns the -number of bytes read or written by the format handler, while -archive_position(a, -1) returns the -number of bytes read or written to the archive. See -archive_filter_count() for details of the numbering -here.

- -

archive_set_error()

- -

Sets the numeric error code and -error description that will be returned by -archive_errno() and archive_error_string(). -This function should be used within I/O callbacks to set -system-specific error codes and error descriptions. This -function accepts a printf-like format string and arguments. -However, you should be careful to use only the following -printf format specifiers: “%c”, -“%d”, “%jd”, “%jo”, -“%ju”, “%jx”, “%ld”, -“%lo”, “%lu”, “%lx”, -“%o”, “%u”, “%s”, -“%x”, “%%”. Field-width specifiers -and other printf features are not uniformly supported and -should not be used.

- -

SEE ALSO

- -

archive_read(3), -archive_write(3), libarchive(3), printf(3)

- -

HISTORY

- -

The libarchive library -first appeared in FreeBSD 5.3.

- -

AUTHORS

- -

The libarchive library -was written by Tim Kientzle <kientzle@acm.org>.

- -

BSD -February 2, 2012 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_write.3.html b/thirdparty/libarchive/doc/html/archive_write.3.html deleted file mode 100644 index a1bc0fbce..000000000 --- a/thirdparty/libarchive/doc/html/archive_write.3.html +++ /dev/null @@ -1,290 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_WRITE(3) BSD Library Functions Manual -ARCHIVE_WRITE(3)

- -

NAME

- -

archive_write — -functions for creating archives

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive.h>

- -

DESCRIPTION

- -

These functions provide a -complete API for creating streaming archive files. The -general process is to first create the struct archive -object, set any desired options, initialize the archive, -append entries, then close the archive and release all -resources.

- -

Create -archive object
-See archive_write_new(3).

- -

To write an -archive, you must first obtain an initialized struct archive -object from archive_write_new().

- -

Enable -filters and formats, configure block size and padding -
-See archive_write_filter(3), archive_write_format(3) and -archive_write_blocksize(3).

- -

You can then -modify this object for the desired operations with the -various archive_write_set_XXX() functions. In -particular, you will need to invoke appropriate -archive_write_add_XXX() and -archive_write_set_XXX() functions to enable the -corresponding compression and format support.

- -

Set -options
-See archive_write_set_options(3).

- -

Open -archive
-See archive_write_open(3).

- -

Once you have -prepared the struct archive object, you call -archive_write_open() to actually open the archive and -prepare it for writing. There are several variants of this -function; the most basic expects you to provide pointers to -several functions that can provide blocks of bytes from the -archive. There are convenience forms that allow you to -specify a filename, file descriptor, FILE * object, -or a block of memory from which to write the archive -data.

- -

Produce -archive
-See archive_write_header(3) and archive_write_data(3).

- -

Individual -archive entries are written in a three-step process: You -first initialize a struct archive_entry structure with -information about the new entry. At a minimum, you should -set the pathname of the entry and provide a struct -stat with a valid st_mode field, which specifies -the type of object and st_size field, which specifies -the size of the data portion of the object.

- -

Release -resources
-See archive_write_free(3).

- -

After all -entries have been written, use the -archive_write_free() function to release all -resources.

- -

EXAMPLES

- -

The following sketch illustrates -basic usage of the library. In this example, the callback -functions are simply wrappers around the standard open(2), -write(2), and close(2) system calls.

- -

#ifdef -__linux__

- - - - - - - -
- - -

#define

- - -

_FILE_OFFSET_BITS 64

-
- -

#endif
-#include <sys/stat.h>
-#include <archive.h>
-#include <archive_entry.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>

- -

struct mydata { -
-const char *name;
-int fd;
-};

- -

int
-myopen(struct archive *a, void *client_data)
-{
-struct mydata *mydata = client_data;

- -

mydata->fd = -open(mydata->name, O_WRONLY | O_CREAT, 0644);
-if (mydata->fd >= 0)
-return (ARCHIVE_OK);
-else
-return (ARCHIVE_FATAL);
-}

- -

la_ssize_t
-mywrite(struct archive *a, void *client_data, const void -*buff, size_t n)
-{
-struct mydata *mydata = client_data;

- -

return -(write(mydata->fd, buff, n));
-}

- -

int
-myclose(struct archive *a, void *client_data)
-{
-struct mydata *mydata = client_data;

- -

if -(mydata->fd > 0)
-close(mydata->fd);
-return (0);
-}

- -

void
-write_archive(const char *outname, const char **filename) -
-{
-struct mydata *mydata = malloc(sizeof(struct mydata));
-struct archive *a;
-struct archive_entry *entry;
-struct stat st;
-char buff[8192];
-int len;
-int fd;

- -

a = -archive_write_new();
-mydata->name = outname;
-/* Set archive format and filter according to output file -extension.
-* If it fails, set default format. Platform depended -function.
-* See supported formats in -archive_write_set_format_filter_by_ext.c */
-if (archive_write_set_format_filter_by_ext(a, outname) != -ARCHIVE_OK) {
-archive_write_add_filter_gzip(a);
-archive_write_set_format_ustar(a);
-}
-archive_write_open(a, mydata, myopen, mywrite, myclose); -
-while (*filename) {
-stat(*filename, &st);
-entry = archive_entry_new();
-archive_entry_copy_stat(entry, &st);
-archive_entry_set_pathname(entry, *filename);
-archive_write_header(a, entry);
-if ((fd = open(*filename, O_RDONLY)) != -1) {
-len = read(fd, buff, sizeof(buff));
-while (len > 0) {
-archive_write_data(a, buff, len);
-len = read(fd, buff, sizeof(buff));
-}
-close(fd);
-}
-archive_entry_free(entry);
-filename++;
-}
-archive_write_free(a);
-}

- -

int main(int -argc, const char **argv)
-{
-const char *outname;
-argv++;
-outname = *argv++;
-write_archive(outname, argv);
-return 0;
-}

- -

SEE ALSO

- -

tar(1), -archive_write_set_options(3), libarchive(3), cpio(5), -mtree(5), tar(5)

- -

HISTORY

- -

The libarchive library -first appeared in FreeBSD 5.3.

- -

AUTHORS

- -

The libarchive library -was written by Tim Kientzle <kientzle@acm.org>.

- -

BUGS

- -

There are many peculiar bugs in -historic tar implementations that may cause certain programs -to reject archives written by this library. For example, -several historic implementations calculated header checksums -incorrectly and will thus reject valid archives; GNU tar -does not fully support pax interchange format; some old tar -implementations required specific field terminations.

- -

The default pax -interchange format eliminates most of the historic tar -limitations and provides a generic key/value attribute -facility for vendor-defined extensions. One oversight in -POSIX is the failure to provide a standard attribute for -large device numbers. This library uses -“SCHILY.devminor” and -“SCHILY.devmajor” for device numbers that exceed -the range supported by the backwards-compatible ustar -header. These keys are compatible with Joerg -Schilling’s star archiver. Other -implementations may not recognize these keys and will thus -be unable to correctly restore device nodes with large -device numbers from archives created by this library.

- -

BSD -February 2, 2012 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_write_blocksize.3.html b/thirdparty/libarchive/doc/html/archive_write_blocksize.3.html deleted file mode 100644 index b594a7f08..000000000 --- a/thirdparty/libarchive/doc/html/archive_write_blocksize.3.html +++ /dev/null @@ -1,141 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_WRITE_BLOCKSI... BSD Library Functions Manual -ARCHIVE_WRITE_BLOCKSI...

- -

NAME

- - -

archive_write_get_bytes_per_block, -archive_write_set_bytes_per_block, -archive_write_get_bytes_in_last_block, -archive_write_set_bytes_in_last_block — -functions for creating archives

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive.h>

- -

int

- - -

archive_write_get_bytes_per_block(struct archive *);

- -

int

- - -

archive_write_set_bytes_per_block(struct archive *, -int bytes_per_block);

- -

int

- - -

archive_write_get_bytes_in_last_block(struct archive *);

- -

int

- - -

archive_write_set_bytes_in_last_block(struct archive *, -int);

- -

DESCRIPTION
-archive_write_set_bytes_per_block
()

- -

Sets the block size used for -writing the archive data. Every call to the write callback -function, except possibly the last one, will use this value -for the length. The default is to use a block size of 10240 -bytes. Note that a block size of zero will suppress internal -blocking and cause writes to be sent directly to the write -callback as they occur.

- - -

archive_write_get_bytes_per_block()

- -

Retrieve the block size to be -used for writing. A value of -1 here indicates that the -library should use default values. A value of zero indicates -that internal blocking is suppressed.

- - -

archive_write_set_bytes_in_last_block()

- -

Sets the block size used for -writing the last block. If this value is zero, the last -block will be padded to the same size as the other blocks. -Otherwise, the final block will be padded to a multiple of -this size. In particular, setting it to 1 will cause the -final block to not be padded. For compressed output, any -padding generated by this option is applied only after the -compression. The uncompressed data is always unpadded. The -default is to pad the last block to the full block size -(note that archive_write_open_filename() will set -this based on the file type). Unlike the other -“set” functions, this function can be called -after the archive is opened.

- - -

archive_write_get_bytes_in_last_block()

- -

Retrieve the currently-set -value for last block size. A value of -1 here indicates that -the library should use default values.

- -

RETURN VALUES

- - -

archive_write_set_bytes_per_block() -and archive_write_set_bytes_in_last_block() return -ARCHIVE_OK on success, or ARCHIVE_FATAL.

- - -

archive_write_get_bytes_per_block() -and archive_write_get_bytes_in_last_block() return -currently configured block size (

- -

-1 indicates the default block size ), or -ARCHIVE_FATAL.

- -

ERRORS

- -

Detailed error codes and textual -descriptions are available from the archive_errno() -and archive_error_string() functions.

- -

SEE ALSO

- -

tar(1), -archive_write_set_options(3), libarchive(3), cpio(5), -mtree(5), tar(5)

- -

BSD -February 2, 2012 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_write_data.3.html b/thirdparty/libarchive/doc/html/archive_write_data.3.html deleted file mode 100644 index ae8041efe..000000000 --- a/thirdparty/libarchive/doc/html/archive_write_data.3.html +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_WRITE_DATA(3) BSD Library Functions Manual -ARCHIVE_WRITE_DATA(3)

- -

NAME

- -

archive_write_data, -archive_write_data_block — functions for -creating archives

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive.h>

- - -

la_ssize_t

- - -

archive_write_data(struct archive *, -const void *, size_t);

- - -

la_ssize_t

- - -

archive_write_data_block(struct archive *, -const void *, size_t size, -int64_t offset);

- -

DESCRIPTION
-archive_write_data
()

- -

Write data corresponding to the -header just written.

- - -

archive_write_data_block()

- -

Write data corresponding to the -header just written. This is like -archive_write_data() except that it performs a seek -on the file being written to the specified offset before -writing the data. This is useful when restoring sparse files -from archive formats that support sparse files. Returns -number of bytes written or -1 on error. (Note: This is -currently not supported for archive_write handles, only for -archive_write_disk handles.

- -

RETURN VALUES

- -

This function returns the number -of bytes actually written, or a negative error code on -error.

- -

ERRORS

- -

Detailed error codes and textual -descriptions are available from the archive_errno() -and archive_error_string() functions.

- -

BUGS

- -

In libarchive 3.x, this function -sometimes returns zero on success instead of returning the -number of bytes written. Specifically, this occurs when -writing to an archive_write_disk handle. Clients -should treat any value less than zero as an error and -consider any non-negative value as success.

- -

SEE ALSO

- -

tar(1), -archive_write_finish_entry(3), archive_write_set_options(3), -libarchive(3), cpio(5), mtree(5), tar(5)

- -

BSD -February 28, 2017 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_write_disk.3.html b/thirdparty/libarchive/doc/html/archive_write_disk.3.html deleted file mode 100644 index b6fccdf69..000000000 --- a/thirdparty/libarchive/doc/html/archive_write_disk.3.html +++ /dev/null @@ -1,376 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_WRITE_DISK(3) BSD Library Functions Manual -ARCHIVE_WRITE_DISK(3)

- -

NAME

- -

archive_write_disk_new, -archive_write_disk_set_options, -archive_write_disk_set_skip_file, -archive_write_disk_set_group_lookup, -archive_write_disk_set_standard_lookup, -archive_write_disk_set_user_lookup — functions -for creating objects on disk

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive.h>

- -

struct -archive *

- - -

archive_write_disk_new(void);

- -

int

- - -

archive_write_disk_set_options(struct archive *, -int flags);

- -

int

- - -

archive_write_disk_set_skip_file(struct archive *, -dev_t, ino_t);

- -

int

- - -

archive_write_disk_set_group_lookup(struct archive *, -void *, -gid_t (*)(void *, const char *gname, gid_t gid), -void (*cleanup)(void *));

- -

int

- - -

archive_write_disk_set_standard_lookup(struct archive *);

- -

int

- - -

archive_write_disk_set_user_lookup(struct archive *, -void *, -uid_t (*)(void *, const char *uname, uid_t uid), -void (*cleanup)(void *));

- -

DESCRIPTION

- -

These functions provide a -complete API for creating objects on disk from struct -archive_entry descriptions. They are most naturally used -when extracting objects from an archive using the -archive_read() interface. The general process is to -read struct archive_entry objects from an archive, then -write those objects to a struct archive object created using -the archive_write_disk() family functions. This -interface is deliberately very similar to the -archive_write() interface used to write objects to a -streaming archive.

- - -

archive_write_disk_new()

- -

Allocates and initializes a -struct archive object suitable for writing objects to -disk.

- - -

archive_write_disk_set_skip_file()

- -

Records the device and inode -numbers of a file that should not be overwritten. This is -typically used to ensure that an extraction process does not -overwrite the archive from which objects are being read. -This capability is technically unnecessary but can be a -significant performance optimization in practice.

- - -

archive_write_disk_set_options()

- -

The options field consists of a -bitwise OR of one or more of the following values:

- -

ARCHIVE_EXTRACT_ACL

- -

Attempt to restore Access -Control Lists. By default, extended ACLs are ignored.

- -

ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS

- -

Before removing a file system -object prior to replacing it, clear platform-specific file -flags which might prevent its removal.

- -

ARCHIVE_EXTRACT_FFLAGS

- -

Attempt to restore file -attributes (file flags). By default, file attributes are -ignored. See chattr(1) (Linux) or chflags(1) (FreeBSD, Mac -OS X) for more information on file attributes.

- -

ARCHIVE_EXTRACT_MAC_METADATA

- -

Mac OS X specific. Restore -metadata using copyfile(3). By default, copyfile(3) metadata -is ignored.

- -

ARCHIVE_EXTRACT_NO_OVERWRITE

- -

Existing files on disk will not -be overwritten. By default, existing regular files are -truncated and overwritten; existing directories will have -their permissions updated; other pre-existing objects are -unlinked and recreated from scratch.

- -

ARCHIVE_EXTRACT_OWNER

- -

The user and group IDs should -be set on the restored file. By default, the user and group -IDs are not restored.

- -

ARCHIVE_EXTRACT_PERM

- -

Full permissions (including -SGID, SUID, and sticky bits) should be restored exactly as -specified, without obeying the current umask. Note that SUID -and SGID bits can only be restored if the user and group ID -of the object on disk are correct. If -ARCHIVE_EXTRACT_OWNER is not specified, then SUID and -SGID bits will only be restored if the default user and -group IDs of newly-created objects on disk happen to match -those specified in the archive entry. By default, only basic -permissions are restored, and umask is obeyed.

- -

ARCHIVE_EXTRACT_SAFE_WRITES

- -

Extract files atomically, by -first creating a unique temporary file and then renaming it -to its required destination name. This avoids a race where -an application might see a partial file (or no file) during -extraction.

- -

ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS

- -

Refuse to extract an absolute -path. The default is to not refuse such paths.

- -

ARCHIVE_EXTRACT_SECURE_NODOTDOT

- -

Refuse to extract a path that -contains a .. element anywhere within it. The default -is to not refuse such paths. Note that paths ending in -.. always cause an error, regardless of this -flag.

- -

ARCHIVE_EXTRACT_SECURE_SYMLINKS

- -

Refuse to extract any object -whose final location would be altered by a symlink on disk. -This is intended to help guard against a variety of mischief -caused by archives that (deliberately or otherwise) extract -files outside of the current directory. The default is not -to perform this check. If ARCHIVE_EXTRACT_UNLINK is -specified together with this option, the library will remove -any intermediate symlinks it finds and return an error only -if such symlink could not be removed.

- -

ARCHIVE_EXTRACT_SPARSE

- -

Scan data for blocks of NUL -bytes and try to recreate them with holes. This results in -sparse files, independent of whether the archive format -supports or uses them.

- -

ARCHIVE_EXTRACT_TIME

- -

The timestamps (mtime, ctime, -and atime) should be restored. By default, they are ignored. -Note that restoring of atime is not currently supported.

- -

ARCHIVE_EXTRACT_UNLINK

- -

Existing files on disk will be -unlinked before any attempt to create them. In some cases, -this can prove to be a significant performance improvement. -By default, existing files are truncated and rewritten, but -the file is not recreated. In particular, the default -behavior does not break existing hard links.

- -

ARCHIVE_EXTRACT_XATTR

- -

Attempt to restore extended -file attributes. By default, they are ignored. See xattr(7) -(Linux), xattr(2) (Mac OS X), or getextattr(8) (FreeBSD) for -more information on extended file attributes.

- - -

archive_write_disk_set_group_lookup(), -archive_write_disk_set_user_lookup()

- -

The struct archive_entry -objects contain both names and ids that can be used to -identify users and groups. These names and ids describe the -ownership of the file itself and also appear in ACL lists. -By default, the library uses the ids and ignores the names, -but this can be overridden by registering user and group -lookup functions. To register, you must provide a lookup -function which accepts both a name and id and returns a -suitable id. You may also provide a void * pointer to a -private data structure and a cleanup function for that data. -The cleanup function will be invoked when the struct archive -object is destroyed.

- - -

archive_write_disk_set_standard_lookup()

- -

This convenience function -installs a standard set of user and group lookup functions. -These functions use getpwnam(3) and getgrnam(3) to convert -names to ids, defaulting to the ids if the names cannot be -looked up. These functions also implement a simple memory -cache to reduce the number of calls to getpwnam(3) and -getgrnam(3).

- -

More information about the -struct archive object and the overall design of the -library can be found in the libarchive(3) overview. Many of -these functions are also documented under -archive_write(3).

- -

RETURN VALUES

- -

Most functions return -ARCHIVE_OK (zero) on success, or one of several -non-zero error codes for errors. Specific error codes -include: ARCHIVE_RETRY for operations that might -succeed if retried, ARCHIVE_WARN for unusual -conditions that do not prevent further operations, and -ARCHIVE_FATAL for serious errors that make remaining -operations impossible.

- - -

archive_write_disk_new() -returns a pointer to a newly-allocated struct archive -object.

- - -

archive_write_data() -returns a count of the number of bytes actually written, or --1 on error.

- -

ERRORS

- -

Detailed error codes and textual -descriptions are available from the archive_errno() -and archive_error_string() functions.

- -

SEE ALSO

- -

tar(1), archive_read(3), -archive_write(3), libarchive(3)

- -

HISTORY

- -

The libarchive library -first appeared in FreeBSD 5.3. The -archive_write_disk interface was added to -libarchive 2.0 and first appeared in -FreeBSD 6.3.

- -

AUTHORS

- -

The libarchive library -was written by Tim Kientzle <kientzle@acm.org>.

- -

BUGS

- -

Directories are actually -extracted in two distinct phases. Directories are created -during archive_write_header(), but final permissions -are not set until archive_write_close(). This -separation is necessary to correctly handle borderline cases -such as a non-writable directory containing files, but can -cause unexpected results. In particular, directory -permissions are not fully restored until the archive is -closed. If you use chdir(2) to change the current directory -between calls to archive_read_extract() or before -calling archive_read_close(), you may confuse the -permission-setting logic with the result that directory -permissions are restored incorrectly.

- -

The library -attempts to create objects with filenames longer than -PATH_MAX by creating prefixes of the full path and -changing the current directory. Currently, this logic is -limited in scope; the fixup pass does not work correctly for -such objects and the symlink security check option disables -the support for very long pathnames.

- -

Restoring the -path aa/../bb does create each intermediate -directory. In particular, the directory aa is created -as well as the final object bb. In theory, this can -be exploited to create an entire directory hierarchy with a -single request. Of course, this does not work if the -ARCHIVE_EXTRACT_NODOTDOT option is specified.

- -

Implicit -directories are always created obeying the current umask. -Explicit objects are created obeying the current umask -unless ARCHIVE_EXTRACT_PERM is specified, in which -case they current umask is ignored.

- -

SGID and SUID -bits are restored only if the correct user and group could -be set. If ARCHIVE_EXTRACT_OWNER is not specified, -then no attempt is made to set the ownership. In this case, -SGID and SUID bits are restored only if the user and group -of the final object happen to match those specified in the -entry.

- -

The -“standard” user-id and group-id lookup functions -are not the defaults because getgrnam(3) and getpwnam(3) are -sometimes too large for particular applications. The current -design allows the application author to use a more compact -implementation when appropriate.

- -

There should be -a corresponding archive_read_disk interface that -walks a directory hierarchy and returns archive entry -objects.

- -

BSD -January 19, 2020 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_write_filter.3.html b/thirdparty/libarchive/doc/html/archive_write_filter.3.html deleted file mode 100644 index 61b36c18d..000000000 --- a/thirdparty/libarchive/doc/html/archive_write_filter.3.html +++ /dev/null @@ -1,193 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_WRITE_FILTER(3) BSD Library Functions Manual -ARCHIVE_WRITE_FILTER(3)

- -

NAME

- - -

archive_write_add_filter_b64encode, -archive_write_add_filter_by_name, -archive_write_add_filter_bzip2, -archive_write_add_filter_compress, -archive_write_add_filter_grzip, -archive_write_add_filter_gzip, -archive_write_add_filter_lrzip, -archive_write_add_filter_lz4, -archive_write_add_filter_lzip, -archive_write_add_filter_lzma, -archive_write_add_filter_lzop, -archive_write_add_filter_none, -archive_write_add_filter_program, -archive_write_add_filter_uuencode, -archive_write_add_filter_xz, -archive_write_add_filter_zstd — functions -enabling output filters

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive.h>

- -

int

- - -

archive_write_add_filter_b64encode(struct archive *);

- -

int

- - -

archive_write_add_filter_bzip2(struct archive *);

- -

int

- - -

archive_write_add_filter_compress(struct archive *);

- -

int

- - -

archive_write_add_filter_grzip(struct archive *);

- -

int

- - -

archive_write_add_filter_gzip(struct archive *);

- -

int

- - -

archive_write_add_filter_lrzip(struct archive *);

- -

int

- - -

archive_write_add_filter_lz4(struct archive *);

- -

int

- - -

archive_write_add_filter_lzip(struct archive *);

- -

int

- - -

archive_write_add_filter_lzma(struct archive *);

- -

int

- - -

archive_write_add_filter_lzop(struct archive *);

- -

int

- - -

archive_write_add_filter_none(struct archive *);

- -

int

- - -

archive_write_add_filter_program(struct archive *, -const char * cmd);

- -

int

- - -

archive_write_add_filter_uuencode(struct archive *);

- -

int

- - -

archive_write_add_filter_xz(struct archive *);

- -

int

- - -

archive_write_add_filter_zstd(struct archive *);

- -

DESCRIPTION
-archive_write_add_filter_bzip2
(), -archive_write_add_filter_compress(), -archive_write_add_filter_grzip(), -archive_write_add_filter_gzip(), -archive_write_add_filter_lrzip(), -archive_write_add_filter_lz4(), -archive_write_add_filter_lzip(), -archive_write_add_filter_lzma(), -archive_write_add_filter_lzop(), -archive_write_add_filter_xz(), -archive_write_add_filter_zstd(),

- -

The resulting archive will be -compressed as specified. Note that the compressed output is -always properly blocked.

- - -

archive_write_add_filter_b64encode(), -archive_write_add_filter_uuencode(),

- -

The output will be encoded as -specified. The encoded output is always properly -blocked.

- - -

archive_write_add_filter_none()

- -

This is never necessary. It is -provided only for backwards compatibility.

- - -

archive_write_add_filter_program()

- -

The archive will be fed into -the specified compression program. The output of that -program is blocked and written to the client write -callbacks.

- -

RETURN VALUES

- -

These functions return -ARCHIVE_OK on success, or ARCHIVE_FATAL.

- -

ERRORS

- -

Detailed error codes and textual -descriptions are available from the archive_errno() -and archive_error_string() functions.

- -

SEE ALSO

- -

tar(1), archive_write(3), -archive_write_format(3), archive_write_set_options(3), -libarchive(3), cpio(5), mtree(5), tar(5)

- -

BSD -August 14, 2014 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_write_finish_entry.3.html b/thirdparty/libarchive/doc/html/archive_write_finish_entry.3.html deleted file mode 100644 index 12540ae91..000000000 --- a/thirdparty/libarchive/doc/html/archive_write_finish_entry.3.html +++ /dev/null @@ -1,85 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_WRITE_FINISH_... BSD Library Functions Manual -ARCHIVE_WRITE_FINISH_...

- -

NAME

- - -

archive_write_finish_entry -— functions for creating archives

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive.h>

- -

int

- - -

archive_write_finish_entry(struct archive *);

- -

DESCRIPTION

- -

Close out the entry just -written. In particular, this writes out the final padding -required by some formats. Ordinarily, clients never need to -call this, as it is called automatically by -archive_write_header() and -archive_write_close() as needed. For -archive_write_disk handles, this flushes pending file -attribute changes like modification time.

- -

RETURN VALUES

- -

This function returns -ARCHIVE_OK on success, or one of several non-zero -error codes for errors. Specific error codes include: -ARCHIVE_RETRY for operations that might succeed if -retried, ARCHIVE_WARN for unusual conditions that do -not prevent further operations, and ARCHIVE_FATAL for -serious errors that make remaining operations -impossible.

- -

ERRORS

- -

Detailed error codes and textual -descriptions are available from the archive_errno() -and archive_error_string() functions.

- -

SEE ALSO

- -

tar(1), archive_write_data(3), -archive_write_set_options(3), libarchive(3), cpio(5), -mtree(5), tar(5)

- -

BSD -February 28, 2017 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_write_format.3.html b/thirdparty/libarchive/doc/html/archive_write_format.3.html deleted file mode 100644 index fe88f7c06..000000000 --- a/thirdparty/libarchive/doc/html/archive_write_format.3.html +++ /dev/null @@ -1,285 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_WRITE_FORMAT(3) BSD Library Functions Manual -ARCHIVE_WRITE_FORMAT(3)

- -

NAME

- - -

archive_write_set_format, -archive_write_set_format_7zip, -archive_write_set_format_ar, -archive_write_set_format_ar_bsd, -archive_write_set_format_ar_svr4, -archive_write_set_format_by_name, -archive_write_set_format_cpio, -archive_write_set_format_cpio_bin, -archive_write_set_format_cpio_newc, -archive_write_set_format_cpio_odc, -archive_write_set_format_cpio_pwb, -archive_write_set_format_filter_by_ext, -archive_write_set_format_filter_by_ext_def, -archive_write_set_format_gnutar, -archive_write_set_format_iso9660, -archive_write_set_format_mtree, -archive_write_set_format_mtree_classic, -archive_write_set_format_mtree_default, -archive_write_set_format_pax, -archive_write_set_format_pax_restricted, -archive_write_set_format_raw, -archive_write_set_format_shar, -archive_write_set_format_shar_dump, -archive_write_set_format_ustar, -archive_write_set_format_v7tar, -archive_write_set_format_warc, -archive_write_set_format_xar, -archive_write_set_format_zip — functions for -creating archives

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive.h>

- -

int

- - -

archive_write_set_format(struct archive *, -int code);

- -

int

- - -

archive_write_set_format_7zip(struct archive *);

- -

int

- - -

archive_write_set_format_ar(struct archive *);

- -

int

- - -

archive_write_set_format_ar_bsd(struct archive *);

- -

int

- - -

archive_write_set_format_ar_svr4(struct archive *);

- -

int

- - -

archive_write_set_format_by_name(struct archive *, -const char *name);

- -

int

- - -

archive_write_set_format_cpio(struct archive *);

- -

int

- - -

archive_write_set_format_cpio_bin(struct archive *);

- -

int

- - -

archive_write_set_format_cpio_newc(struct archive *);

- -

int

- - -

archive_write_set_format_cpio_odc(struct archive *);

- -

int

- - -

archive_write_set_format_cpio_pwb(struct archive *);

- -

int

- - -

archive_write_set_format_filter_by_ext(struct archive *, -const char *filename);

- -

int

- - -

archive_write_set_format_filter_by_ext_def(struct archive *, -const char *filename, -const char *def_ext);

- -

int

- - -

archive_write_set_format_gnutar(struct archive *);

- -

int

- - -

archive_write_set_format_iso9660(struct archive *);

- -

int

- - -

archive_write_set_format_mtree(struct archive *);

- -

int

- - -

archive_write_set_format_pax(struct archive *);

- -

int

- - -

archive_write_set_format_pax_restricted(struct archive *);

- -

int

- - -

archive_write_set_format_raw(struct archive *);

- -

int

- - -

archive_write_set_format_shar(struct archive *);

- -

int

- - -

archive_write_set_format_shar_dump(struct archive *);

- -

int

- - -

archive_write_set_format_ustar(struct archive *);

- -

int

- - -

archive_write_set_format_v7tar(struct archive *);

- -

int

- - -

archive_write_set_format_warc(struct archive *);

- -

int

- - -

archive_write_set_format_xar(struct archive *);

- -

int

- - -

archive_write_set_format_zip(struct archive *);

- -

DESCRIPTION

- -

These functions set the format -that will be used for the archive.

- -

The library can -write a variety of common archive formats.

- - -

archive_write_set_format()

- -

Sets the format based on the -format code (see archive.h for the full list of -format codes). In particular, this can be used in -conjunction with archive_format() to create a new -archive with the same format as an existing archive.

- - -

archive_write_set_format_by_name()

- -

Sets the corresponding format -based on the common name.

- - -

archive_write_set_format_filter_by_ext() -archive_write_set_format_filter_by_ext_def()

- -

Sets both filters and format -based on the output filename. Supported extensions: .7z, -.zip, .jar, .cpio, .iso, .a, .ar, .tar, .tgz, .tar.gz, -.tar.bz2, .tar.xz

- - -

archive_write_set_format_7zip() -archive_write_set_format_ar_bsd() -archive_write_set_format_ar_svr4() -archive_write_set_format_cpio() -archive_write_set_format_cpio_bin() -archive_write_set_format_cpio_newc() -archive_write_set_format_cpio_odc() -archive_write_set_format_cpio_pwb() -archive_write_set_format_gnutar() -archive_write_set_format_iso9660() -archive_write_set_format_mtree() -archive_write_set_format_mtree_classic() -archive_write_set_format_pax() -archive_write_set_format_pax_restricted() -archive_write_set_format_raw() -archive_write_set_format_shar() -archive_write_set_format_shar_dump() -archive_write_set_format_ustar() -archive_write_set_format_v7tar() -archive_write_set_format_warc() -archive_write_set_format_xar() -archive_write_set_format_zip()

- -

Set the format as specified. -More details on the formats supported by libarchive can be -found in the libarchive-formats(5) manual page.

- -

RETURN VALUES

- -

These functions return -ARCHIVE_OK on success, or ARCHIVE_FATAL.

- -

ERRORS

- -

Detailed error codes and textual -descriptions are available from the archive_errno() -and archive_error_string() functions.

- -

SEE ALSO

- -

tar(1), archive_write(3), -archive_write_set_options(3), libarchive(3), cpio(5), -libarchive-formats(5), mtree(5), tar(5)

- -

BSD -February 14, 2013 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_write_free.3.html b/thirdparty/libarchive/doc/html/archive_write_free.3.html deleted file mode 100644 index b8de8c53c..000000000 --- a/thirdparty/libarchive/doc/html/archive_write_free.3.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_WRITE_FREE(3) BSD Library Functions Manual -ARCHIVE_WRITE_FREE(3)

- -

NAME

- -

archive_write_fail, -archive_write_close, archive_write_finish, -archive_write_free — functions for creating -archives

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive.h>

- -

int

- - -

archive_write_fail(struct archive *);

- -

int

- - -

archive_write_close(struct archive *);

- -

int

- - -

archive_write_finish(struct archive *);

- -

int

- - -

archive_write_free(struct archive *);

- -

DESCRIPTION
-archive_write_fail
()

- -

Always returns -ARCHIVE_FATAL. This marks the archive object as being -unusable; after calling this function, the only call that -can succeed is archive_write_free() to release the -resources. This can be used to speed recovery when the -archive creation must be aborted. Note that the created -archive is likely to be malformed in this case;

- - -

archive_write_close()

- -

Complete the archive and invoke -the close callback.

- - -

archive_write_finish()

- -

This is a deprecated synonym -for archive_write_free().

- -

archive_write_free()

- -

Invokes -archive_write_close() if necessary, then releases all -resources. If you need detailed information about -archive_write_close() failures, you should be careful -to call it separately, as you cannot obtain error -information after archive_write_free() returns.

- -

RETURN VALUES

- -

These functions return -ARCHIVE_OK on success, or ARCHIVE_FATAL.

- -

ERRORS

- -

Detailed error codes and textual -descriptions are available from the archive_errno() -and archive_error_string() functions.

- -

SEE ALSO

- -

tar(1), -archive_write_set_options(3), libarchive(3), cpio(5), -mtree(5), tar(5)

- -

BSD -February 2, 2012 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_write_header.3.html b/thirdparty/libarchive/doc/html/archive_write_header.3.html deleted file mode 100644 index c1c2dcba5..000000000 --- a/thirdparty/libarchive/doc/html/archive_write_header.3.html +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_WRITE_HEADER(3) BSD Library Functions Manual -ARCHIVE_WRITE_HEADER(3)

- -

NAME

- -

archive_write_header -— functions for creating archives

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive.h>

- -

int

- - -

archive_write_header(struct archive *, -struct archive_entry *);

- -

DESCRIPTION

- -

Build and write a header using -the data in the provided struct archive_entry structure. See -archive_entry(3) for information on creating and populating -struct archive_entry objects.

- -

RETURN VALUES

- -

This function returns -ARCHIVE_OK on success, or one of the following on -error: ARCHIVE_RETRY for operations that might -succeed if retried, ARCHIVE_WARN for unusual -conditions that do not prevent further operations, and -ARCHIVE_FATAL for serious errors that make remaining -operations impossible.

- -

ERRORS

- -

Detailed error codes and textual -descriptions are available from the archive_errno() -and archive_error_string() functions.

- -

SEE ALSO

- -

tar(1), -archive_write_set_options(3), libarchive(3), cpio(5), -mtree(5), tar(5)

- -

BSD -February 2, 2012 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_write_new.3.html b/thirdparty/libarchive/doc/html/archive_write_new.3.html deleted file mode 100644 index 7a5c5b57c..000000000 --- a/thirdparty/libarchive/doc/html/archive_write_new.3.html +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_WRITE_NEW(3) BSD Library Functions Manual -ARCHIVE_WRITE_NEW(3)

- -

NAME

- -

archive_write_new — -functions for creating archives

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive.h>

- -

struct -archive *

- - -

archive_write_new(void);

- -

DESCRIPTION

- -

Allocates and initializes a -struct archive object suitable for writing a tar archive. -NULL is returned on error.

- -

A complete -description of the struct archive object can be found in the -overview manual page for libarchive(3).

- -

SEE ALSO

- -

tar(1), archive_write(3), -archive_write_set_options(3), libarchive(3), cpio(5), -mtree(5), tar(5)

- -

BSD -February 2, 2012 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_write_open.3.html b/thirdparty/libarchive/doc/html/archive_write_open.3.html deleted file mode 100644 index df01df657..000000000 --- a/thirdparty/libarchive/doc/html/archive_write_open.3.html +++ /dev/null @@ -1,269 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_WRITE_OPEN(3) BSD Library Functions Manual -ARCHIVE_WRITE_OPEN(3)

- -

NAME

- -

archive_write_open, -archive_write_open2, archive_write_open_fd, -archive_write_open_FILE, -archive_write_open_filename, -archive_write_open_memory — functions for -creating archives

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive.h>

- -

int

- - -

archive_write_open(struct archive *, -void *client_data, -archive_open_callback *, -archive_write_callback *, -archive_close_callback *);

- -

int

- - -

archive_write_open2(struct archive *, -void *client_data, -archive_open_callback *, -archive_write_callback *, -archive_close_callback *, -archive_free_callback *);

- -

int

- - -

archive_write_open_fd(struct archive *, -int fd);

- -

int

- - -

archive_write_open_FILE(struct archive *, -FILE *file);

- -

int

- - -

archive_write_open_filename(struct archive *, -const char *filename);

- -

int

- - -

archive_write_open_memory(struct archive *, -void *buffer, size_t bufferSize, -size_t *outUsed);

- -

DESCRIPTION
-archive_write_open
()

- -

Freeze the settings, open the -archive, and prepare for writing entries. This is the most -generic form of this function, which accepts pointers to -three callback functions which will be invoked by the -compression layer to write the constructed archive. This -does not alter the default archive padding.

- - -

archive_write_open2()

- -

Same as -archive_write_open() with an additional fourth free -callback. This function should be preferred to -archive_write_open().

- - -

archive_write_open_fd()

- -

A convenience form of -archive_write_open() that accepts a file descriptor. -The archive_write_open_fd() function is safe for use -with tape drives or other block-oriented devices.

- - -

archive_write_open_FILE()

- -

A convenience form of -archive_write_open() that accepts a FILE * -pointer. Note that archive_write_open_FILE() is not -safe for writing to tape drives or other devices that -require correct blocking.

- - -

archive_write_open_file()

- -

A deprecated synonym for -archive_write_open_filename().

- - -

archive_write_open_filename()

- -

A convenience form of -archive_write_open() that accepts a filename. A NULL -argument indicates that the output should be written to -standard output; an argument of “-” will open a -file with that name. If you have not invoked -archive_write_set_bytes_in_last_block(), then -archive_write_open_filename() will adjust the -last-block padding depending on the file: it will enable -padding when writing to standard output or to a character or -block device node, it will disable padding otherwise. You -can override this by manually invoking -archive_write_set_bytes_in_last_block() before -calling archive_write_open2(). The -archive_write_open_filename() function is safe for -use with tape drives or other block-oriented devices.

- - -

archive_write_open_memory()

- -

A convenience form of -archive_write_open2() that accepts a pointer to a -block of memory that will receive the archive. The final -size_t * argument points to a variable that will be -updated after each write to reflect how much of the buffer -is currently in use. You should be careful to ensure that -this variable remains allocated until after the archive is -closed. This function will disable padding unless you have -specifically set the block size.

- -

More information about the -struct archive object and the overall design of the -library can be found in the libarchive(3) overview.

- -

Note that the -convenience forms above vary in how they block the output. -See archive_write_blocksize(3) if you need to control the -block size used for writes or the end-of-file padding -behavior.

- -

CLIENT CALLBACKS

- -

To use this library, you will -need to define and register callback functions that will be -invoked to write data to the resulting archive. These -functions are registered by calling -archive_write_open2():

- -

typedef -int archive_open_callback(struct archive -*, void *client_data)

- -

The open -callback is invoked by archive_write_open(). It -should return ARCHIVE_OK if the underlying file or -data source is successfully opened. If the open fails, it -should call archive_set_error() to register an error -code and message and return ARCHIVE_FATAL. Please -note that if open fails, close is not called and resources -must be freed inside the open callback or with the free -callback.

- -

typedef -la_ssize_t

- - -

archive_write_callback(struct archive *, -void *client_data, -const void *buffer, -size_t length)

- -

The write -callback is invoked whenever the library needs to write raw -bytes to the archive. For correct blocking, each call to the -write callback function should translate into a single -write(2) system call. This is especially critical when -writing archives to tape drives. On success, the write -callback should return the number of bytes actually written. -On error, the callback should invoke -archive_set_error() to register an error code and -message and return -1.

- -

typedef -int archive_close_callback(struct archive -*, void *client_data)

- -

The close -callback is invoked by archive_close when the archive -processing is complete. If the open callback fails, the -close callback is not invoked. The callback should return -ARCHIVE_OK on success. On failure, the callback -should invoke archive_set_error() to register an -error code and message and return ARCHIVE_FATAL.

- -

typedef -int archive_free_callback(struct archive -*, void *client_data)

- -

The free -callback is always invoked on archive_free. The return code -of this callback is not processed.

- -

Note that if the -client-provided write callback function returns a non-zero -value, that error will be propagated back to the caller -through whatever API function resulted in that call, which -may include archive_write_header(), -archive_write_data(), archive_write_close(), -archive_write_finish(), or -archive_write_free(). The client callback can call -archive_set_error() to provide values that can then -be retrieved by archive_errno() and -archive_error_string().

- -

RETURN VALUES

- -

These functions return -ARCHIVE_OK on success, or ARCHIVE_FATAL.

- -

ERRORS

- -

Detailed error codes and textual -descriptions are available from the archive_errno() -and archive_error_string() functions.

- -

SEE ALSO

- -

tar(1), archive_write(3), -archive_write_blocksize(3), archive_write_filter(3), -archive_write_format(3), archive_write_new(3), -archive_write_set_options(3), libarchive(3), cpio(5), -mtree(5), tar(5)

- -

BSD -November 12, 2020 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_write_set_options.3.html b/thirdparty/libarchive/doc/html/archive_write_set_options.3.html deleted file mode 100644 index 21b6e037a..000000000 --- a/thirdparty/libarchive/doc/html/archive_write_set_options.3.html +++ /dev/null @@ -1,839 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_WRITE_OPTIONS(3) BSD Library Functions Manual -ARCHIVE_WRITE_OPTIONS(3)

- -

NAME

- - -

archive_write_set_filter_option, -archive_write_set_format_option, -archive_write_set_option, -archive_write_set_options — functions -controlling options for writing archives

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

int

- - -

archive_write_set_filter_option(struct archive *, -const char *module, -const char *option, -const char *value);

- -

int

- - -

archive_write_set_format_option(struct archive *, -const char *module, -const char *option, -const char *value);

- -

int

- - -

archive_write_set_option(struct archive *, -const char *module, -const char *option, -const char *value);

- -

int

- - -

archive_write_set_options(struct archive *, -const char *options);

- -

DESCRIPTION

- -

These functions provide a way -for libarchive clients to configure specific write -modules.

- - -

archive_write_set_filter_option(), -archive_write_set_format_option()

- -

Specifies an option that will -be passed to the currently-registered filters (including -decompression filters) or format readers.

- -

If -option and value are both NULL, these -functions will do nothing and ARCHIVE_OK will be -returned. If option is NULL but value is not, -these functions will do nothing and ARCHIVE_FAILED -will be returned.

- -

If -module is not NULL, option and value -will be provided to the filter or reader named -module. The return value will be either -ARCHIVE_OK if the option was successfully handled or -ARCHIVE_WARN if the option was unrecognized by the -module or could otherwise not be handled. If there is no -such module, ARCHIVE_FAILED will be returned.

- -

If -module is NULL, option and value will -be provided to every registered module. If any module -returns ARCHIVE_FATAL, this value will be returned -immediately. Otherwise, ARCHIVE_OK will be returned -if any module accepts the option, and ARCHIVE_FAILED -in all other cases.

- - -

archive_write_set_option()

- -

Calls -archive_write_set_format_option(), then -archive_write_set_filter_option(). If either function -returns ARCHIVE_FATAL, ARCHIVE_FATAL will be -returned immediately. Otherwise, the greater of the two -values will be returned.

- - -

archive_write_set_options()

- -

options is a -comma-separated list of options. If options is NULL -or empty, ARCHIVE_OK will be returned -immediately.

- -

Individual -options have one of the following forms:

- -

option=value

- -

The option/value pair will be -provided to every module. Modules that do not accept an -option with this name will ignore it.

- -

option

- -

The option will -be provided to every module with a value of -“1”.

- -

!option

- -

The option will be provided to -every module with a NULL value.

- -

module:option=value, module:option, -module:!option

- -

As above, but the corresponding -option and value will be provided only to modules whose name -matches module.

- -

OPTIONS
-Filter b64encode
-mode

- -

The value is -interpreted as octal digits specifying the file mode.

- -

name

- -

The value -specifies the file name.

- -

Filter bzip2
-compression-level

- -

The value is interpreted as a -decimal integer specifying the bzip2 compression level. -Supported values are from 1 to 9.

- -

Filter gzip
-compression-level

- -

The value is interpreted as a -decimal integer specifying the gzip compression level. -Supported values are from 0 to 9.

- -

timestamp

- -

Store timestamp. This is -enabled by default.

- -

Filter lrzip
-compression
=type

- -

Use type as compression -method. Supported values are “bzip2”, -“gzipi”, “lzo” (ultra fast), and -“zpaq” (best, extremely slow).

- -

compression-level

- -

The value is interpreted as a -decimal integer specifying the lrzip compression level. -Supported values are from 1 to 9.

- -

Filter lz4
-compression-level

- -

The value is interpreted as a -decimal integer specifying the lz4 compression level. -Supported values are from 0 to 9.

- -

stream-checksum

- -

Enable stream checksum. This is -enabled by default.

- -

block-checksum

- -

Enable block checksum. This is -disabled by default.

- -

block-size

- -

The value is interpreted as a -decimal integer specifying the lz4 compression block size. -Supported values are from 4 to 7 (default).

- -

block-dependence

- -

Use the previous block of the -block being compressed for a compression dictionary to -improve compression ratio. This is disabled by default.

- -

Filter lzop
-compression-level

- -

The value is interpreted as a -decimal integer specifying the lzop compression level. -Supported values are from 1 to 9.

- -

Filter uuencode
-mode

- -

The value is -interpreted as octal digits specifying the file mode.

- -

name

- -

The value -specifies the file name.

- -

Filter xz
-compression-level

- -

The value is interpreted as a -decimal integer specifying the compression level. Supported -values are from 0 to 9.

- -

threads

- -

The value is interpreted as a -decimal integer specifying the number of threads for -multi-threaded lzma compression. If supported, the default -value is read from lzma_cputhreads().

- -

Filter zstd
-compression-level

- -

The value is interpreted as a -decimal integer specifying the compression level. Supported -values depend on the library version, common values are from -1 to 22.

- -

long

- -

Enables long -distance matching. The value is interpreted as a decimal -integer specifying log2 window size in bytes. Values from 10 -to 30 for 32 bit, or 31 for 64 bit, are supported.

- -

threads

- -

The value is interpreted as a -decimal integer specifying the number of threads for -multi-threaded zstd compression. If set to 0, zstd will -attempt to detect and use the number of physical CPU -cores.

- -

Format 7zip
-compression

- -

The value is one of -“store”, “deflate”, -“bzip2”, “lzma1”, -“lzma2” or “ppmd” to indicate how -the following entries should be compressed. Note that this -setting is ignored for directories, symbolic links, and -other special entries.

- -

compression-level

- -

The value is interpreted as a -decimal integer specifying the compression level. Values -between 0 and 9 are supported. The interpretation of the -compression level depends on the chosen compression -method.

- -

Format bin
-hdrcharset

- -

The value is used as a -character set name that will be used when translating file -names.

- -

Format gnutar
-hdrcharset

- -

The value is used as a -character set name that will be used when translating file, -group and user names.

- -

Format iso9660 - volume metadata

- -

These options are used to set -standard ISO9660 metadata.

- -

abstract-file=filename

- -

The file with the specified -name will be identified in the ISO9660 metadata as holding -the abstract for this volume. Default: none.

- -

application-id=filename

- -

The file with the specified -name will be identified in the ISO9660 metadata as holding -the application identifier for this volume. Default: -none.

- -

biblio-file=filename

- -

The file with the specified -name will be identified in the ISO9660 metadata as holding -the bibliography for this volume. Default: none.

- -

copyright-file=filename

- -

The file with the specified -name will be identified in the ISO9660 metadata as holding -the copyright for this volume. Default: none.

- -

publisher=filename

- -

The file with the specified -name will be identified in the ISO9660 metadata as holding -the publisher information for this volume. Default: -none.

- -

volume-id=string

- -

The specified string will be -used as the Volume Identifier in the ISO9660 metadata. It is -limited to 32 bytes. Default: none.

- -

Format iso9660 - boot support

- -

These options are used to make -an ISO9660 image that can be directly booted on various -systems.

- -

boot=filename

- -

The file matching this name -will be used as the El Torito boot image file.

- -

boot-catalog=name

- -

The name that will be used for -the El Torito boot catalog. Default: boot.catalog

- -

boot-info-table

- -

The boot image file provided by -the boot=filename option will be edited with -appropriate boot information in bytes 8 through 64. Default: -disabled

- -

boot-load-seg=hexadecimal-number

- -

The load segment for a -no-emulation boot image.

- -

boot-load-size=decimal-number

- -

The number of -"virtual" 512-byte sectors to be loaded from a -no-emulation boot image. Some very old BIOSes can only load -very small images, setting this value to 4 will often allow -such BIOSes to load the first part of the boot image (which -will then need to be intelligent enough to load the rest of -itself). This should not be needed unless you are trying to -support systems with very old BIOSes. This defaults to the -full size of the image.

- -

boot-type=value

- -

Specifies the boot semantics -used by the El Torito boot image: If the value is -fd, then the boot image is assumed to be a bootable -floppy image. If the value is hd, then the -boot image is assumed to be a bootable hard disk image. If -the value is no-emulation, the boot image is -used without floppy or hard disk emulation. If the boot -image is exactly 1.2MB, 1.44MB, or 2.88MB, then the default -is fd, otherwise the default is -no-emulation.

- -

Format iso9660 - filename and size extensions

- -

Various extensions to the base -ISO9660 format.

- -

allow-ldots

- -

If enabled, allows filenames to -begin with a leading period. If disabled, filenames that -begin with a leading period will have that period replaced -by an underscore character in the standard ISO9660 -namespace. This does not impact names stored in the -Rockridge or Joliet extension area. Default: disabled.

- -

allow-lowercase

- -

If enabled, allows filenames to -contain lowercase characters. If disabled, filenames will be -forced to uppercase. This does not impact names stored in -the Rockridge or Joliet extension area. Default: -disabled.

- -

allow-multidot

- -

If enabled, allows filenames to -contain multiple period characters, in violation of the -ISO9660 specification. If disabled, additional periods will -be converted to underscore characters. This does not impact -names stored in the Rockridge or Joliet extension area. -Default: disabled.

- -

allow-period

- -

If enabled, allows filenames to -contain trailing period characters, in violation of the -ISO9660 specification. If disabled, trailing periods will be -converted to underscore characters. This does not impact -names stored in the Rockridge or Joliet extension area. -Default: disabled.

- -

allow-pvd-lowercase

- -

If enabled, the Primary Volume -Descriptor may contain lowercase ASCII characters, in -violation of the ISO9660 specification. If disabled, -characters will be converted to uppercase ASCII. Default: -disabled.

- -

allow-sharp-tilde

- -

If enabled, sharp and tilde -characters will be permitted in filenames, in violation if -the ISO9660 specification. If disabled, such characters will -be converted to underscore characters. Default: -disabled.

- -

allow-vernum

- -

If enabled, version numbers -will be included with files. If disabled, version numbers -will be suppressed, in violation of the ISO9660 standard. -This does not impact names stored in the Rockridge or Joliet -extension area. Default: enabled.

- -

iso-level

- -

This enables support for file -size and file name extensions in the core ISO9660 area. The -name extensions specified here do not affect the names -stored in the Rockridge or Joliet extension areas.

- -

iso-level=1

- -

The most compliant form of -ISO9660 image. Filenames are limited to 8.3 uppercase -format, directory names are limited to 8 uppercase -characters, files are limited to 4 GiB, the complete ISO9660 -image cannot exceed 4 GiB.

- -

iso-level=2

- -

Filenames are limited to 30 -uppercase characters with a 30-character extension, -directory names are limited to 30 characters, files are -limited to 4 GiB.

- -

iso-level=3

- -

As with iso-level=2, -except that files may exceed 4 GiB.

- -

iso-level=4

- -

As with iso-level=3, -except that filenames may be up to 193 characters and may -include arbitrary 8-bit characters.

- -

joliet

- - -

Microsoft’s -Joliet extensions store a completely separate set of -directory information about each file. In particular, this -information includes Unicode filenames of up to 255 -characters. Default: enabled.

- -

limit-depth

- -

If enabled, libarchive will use -directory relocation records to ensure that no pathname -exceeds the ISO9660 limit of 8 directory levels. If -disabled, no relocation will occur. Default: enabled.

- -

limit-dirs

- -

If enabled, libarchive will -cause an error if there are more than 65536 directories. If -disabled, there is no limit on the number of directories. -Default: enabled

- -

pad

- -

If enabled, 300 -kiB of zero bytes will be appended to the end of the -archive. Default: enabled

- -

relaxed-filenames

- -

If enabled, all 7-bit ASCII -characters are permitted in filenames (except lowercase -characters unless allow-lowercase is also specified). -This violates ISO9660 standards. This does not impact names -stored in the Rockridge or Joliet extension area. Default: -disabled.

- -

rockridge

- -

The Rockridge extensions store -an additional set of POSIX-style file information with each -file, including mtime, atime, ctime, permissions, and long -filenames with arbitrary 8-bit characters. These extensions -also support symbolic links and other POSIX file types. -Default: enabled.

- -

Format iso9660 - zisofs support

- -

The zisofs extensions permit -each file to be independently compressed using a -gzip-compatible compression. This can provide significant -size savings, but requires the reading system to have -support for these extensions. These extensions are disabled -by default.

- -

compression-level=number

- -

The compression level used by -the deflate compressor. Ranges from 0 (least effort) to 9 -(most effort). Default: 6

- -

zisofs

- -

Synonym for -zisofs=direct.

- -

zisofs=direct

- -

Compress each file in the -archive. Unlike zisofs=indirect, this is handled -entirely within libarchive and does not require a separate -utility. For best results, libarchive tests each file and -will store the file uncompressed if the compression does not -actually save any space. In particular, files under 2k will -never be compressed. Note that boot image files are never -compressed.

- -

zisofs=indirect

- -

Recognizes files that have -already been compressed with the mkzftree utility and -sets up the necessary file metadata so that readers will -correctly identify these as zisofs-compressed files.

- -

zisofs-exclude=filename

- -

Specifies a filename that -should not be compressed when using zisofs=direct. -This option can be provided multiple times to suppress -compression on many files.

- -

Format mtree
-cksum
, device, flags, gid, -gname, indent, link, md5, -mode, nlink, rmd160, sha1, -sha256, sha384, sha512, size, -time, uid, uname

- -

Enable a particular keyword in -the mtree output. Prefix with an exclamation mark to disable -the corresponding keyword. The default is equivalent to -“device, flags, gid, gname, link, mode, nlink, size, -time, type, uid, uname”.

- -

all

- -

Enables all of -the above keywords.

- -

use-set

- -

Enables generation of -/set lines that specify default values for the -following files and/or directories.

- -

indent

- -

XXX needs -explanation XXX

- -

Format newc
-hdrcharset

- -

The value is used as a -character set name that will be used when translating file -names.

- -

Format odc
-hdrcharset

- -

The value is used as a -character set name that will be used when translating file -names.

- -

Format pwb
-hdrcharset

- -

The value is used as a -character set name that will be used when translating file -names.

- -

Format pax
-hdrcharset

- -

The value is used as a -character set name that will be used when translating file, -group and user names. The value is one of -“BINARY” or “UTF-8”. With -“BINARY” there is no character conversion, with -“UTF-8” names are converted to UTF-8.

- -

xattrheader

- -

When storing extended -attributes, this option configures which headers should be -written. The value is one of “all”, -“LIBARCHIVE”, or “SCHILY”. By -default, both “LIBARCHIVE.xattr” and -“SCHILY.xattr” headers are written.

- -

Format ustar
-hdrcharset

- -

The value is used as a -character set name that will be used when translating file, -group and user names.

- -

Format v7tar
-hdrcharset

- -

The value is used as a -character set name that will be used when translating file, -group and user names.

- -

Format warc
-omit-warcinfo

- -

Set to “true” to -disable output of the warcinfo record.

- -

Format xar
-checksum
=type

- -

Use type as file -checksum method. Supported values are “none”, -“md5”, and “sha1” (default).

- -

compression=type

- -

Use type as compression -method. Supported values are “none”, -“bzip2”, “gzip” (default), -“lzma” and “xz”.

- -

compression_level

- -

The value is a decimal integer -from 1 to 9 specifying the compression level.

- -

toc-checksum=type

- -

Use type as table of -contents checksum method. Supported values are -“none”, “md5” and “sha1” -(default).

- -

Format zip
-compression

- -

The value is either -“store” or “deflate” to indicate how -the following entries should be compressed. Note that this -setting is ignored for directories, symbolic links, and -other special entries.

- -

compression-level

- -

The value is interpreted as a -decimal integer specifying the compression level. Values -between 0 and 9 are supported. A compression level of 0 -switches the compression method to “store”, -other values will enable “deflate” compression -with the given level.

- -

encryption

- -

Enable encryption using -traditional zip encryption.

- -

encryption=type

- -

Use type as encryption -type. Supported values are “zipcrypt” -(traditional zip encryption), “aes128” (WinZip -AES-128 encryption) and “aes256” (WinZip AES-256 -encryption).

- -

experimental

- -

This boolean option enables or -disables experimental Zip features that may not be -compatible with other Zip implementations.

- -

fakecrc32

- -

This boolean option disables -CRC calculations. All CRC fields are set to zero. It should -not be used except for testing purposes.

- -

hdrcharset

- -

The value is used as a -character set name that will be used when translating file -names.

- -

zip64

- -

Zip64 -extensions provide additional file size information for -entries larger than 4 GiB. They also provide extended file -offset and archive size information when archives exceed 4 -GiB. By default, the Zip writer selectively enables these -extensions only as needed. In particular, if the file size -is unknown, the Zip writer will include Zip64 extensions to -guard against the possibility that the file might be larger -than 4 GiB.

- -

Setting this -boolean option will force the writer to use Zip64 extensions -even for small files that would not otherwise require them. -This is primarily useful for testing.

- -

Disabling this -option with !zip64 will force the Zip writer to avoid -Zip64 extensions: It will reject files with size greater -than 4 GiB, it will reject any new entries once the total -archive size reaches 4 GiB, and it will not use Zip64 -extensions for files with unknown size. In particular, this -can improve compatibility when generating archives where the -entry sizes are not known in advance.

- -

EXAMPLES

- -

The following example creates an -archive write handle to create a gzip-compressed ISO9660 -format image. The two options here specify that the ISO9660 -archive will use kernel.img as the boot image for El -Torito booting, and that the gzip compressor should use the -maximum compression level.

- -

a = -archive_write_new();
-archive_write_add_filter_gzip(a);
-archive_write_set_format_iso9660(a);
-archive_write_set_options(a, -"boot=kernel.img,compression=9");
-archive_write_open_filename(a, filename, blocksize);

- -

ERRORS

- -

More detailed error codes and -textual descriptions are available from the -archive_errno() and archive_error_string() -functions.

- -

SEE ALSO

- -

tar(1), -archive_read_set_options(3), archive_write(3), -libarchive(3)

- -

HISTORY

- -

The libarchive library -first appeared in FreeBSD 5.3.

- -

AUTHORS

- -

The options support for -libarchive was originally implemented by Michihiro -NAKAJIMA.

- -

BUGS

- -

BSD January 31, 2020 -BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/archive_write_set_passphrase.3.html b/thirdparty/libarchive/doc/html/archive_write_set_passphrase.3.html deleted file mode 100644 index 352933757..000000000 --- a/thirdparty/libarchive/doc/html/archive_write_set_passphrase.3.html +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - - - - - - -
- - -

ARCHIVE_WRITE_SET_PAS... BSD Library Functions Manual -ARCHIVE_WRITE_SET_PAS...

- -

NAME

- - -

archive_write_set_passphrase, -archive_write_set_passphrase_callback — -functions for writing encrypted archives

- -

LIBRARY

- -

Streaming Archive Library -(libarchive, -larchive)

- -

SYNOPSIS

- -

#include -<archive.h>

- -

int

- - -

archive_write_set_passphrase(struct archive *, -const char *passphrase);

- -

int

- - -

archive_write_set_passphrase_callback(struct archive *, -void *client_data, -archive_passphrase_callback *);

- -

DESCRIPTION
-archive_write_set_passphrase
()

- -

Set a passphrase for writing an -encrypted archive. If passphrase is NULL or empty, -this function will do nothing and ARCHIVE_FAILED will -be returned. Otherwise, ARCHIVE_OK will be -returned.

- - -

archive_write_set_passphrase_callback()

- -

Register a callback function -that will be invoked to get a passphrase for encryption if -the passphrase was not set by the -archive_write_set_passphrase() function.

- -

SEE ALSO

- -

tar(1), archive_write(3), -archive_write_set_options(3), libarchive(3)

- -

BSD -September 21, 2014 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/bsdcpio.1.html b/thirdparty/libarchive/doc/html/bsdcpio.1.html deleted file mode 100644 index 31a6f06e1..000000000 --- a/thirdparty/libarchive/doc/html/bsdcpio.1.html +++ /dev/null @@ -1,521 +0,0 @@ - - - - - - - - - - - - - -
- - -

CPIO(1) BSD General Commands Manual CPIO(1)

- -

NAME

- -

cpio — copy files -to and from archives

- -

SYNOPSIS

- -

cpio -i [options] -[pattern ...] [< archive]
-cpio -o
[options] < name-list -[> archive]
-cpio -p
[options] dest-dir < -name-list

- -

DESCRIPTION

- -

cpio copies files between -archives and directories. This implementation can extract -from tar, pax, cpio, zip, jar, ar, and ISO 9660 cdrom images -and can create tar, pax, cpio, ar, and shar archives.

- -

The first option -to cpio is a mode indicator from the following -list:

- -

-i

- -

Input. Read an -archive from standard input (unless overridden) and extract -the contents to disk or (if the -t option is -specified) list the contents to standard output. If one or -more file patterns are specified, only files matching one of -the patterns will be extracted.

- -

-o

- -

Output. Read a -list of filenames from standard input and produce a new -archive on standard output (unless overridden) containing -the specified items.

- -

-p

- -

Pass-through. -Read a list of filenames from standard input and copy the -files to the specified directory.

- -

OPTIONS

- -

Unless specifically stated -otherwise, options are applicable in all operating -modes.

- -

-0, --null

- -

Read filenames separated by NUL -characters instead of newlines. This is necessary if any of -the filenames being read might contain newlines.

- -

-6, --pwb

- -

When reading a binary format -archive, assume it’s the earlier one, from the PWB -variant of 6th Edition UNIX. When writing a cpio archive, -use the PWB format.

- -

-7, --binary

- -

(o mode only) When writing a -cpio archive, use the (newer, non-PWB) binary format.

- -

-A

- -

(o mode only) -Append to the specified archive. (Not yet implemented.)

- -

-a

- -

(o and p modes) -Reset access times on files after they are read.

- -

-B

- -

(o mode only) -Block output to records of 5120 bytes.

- -

-C size

- -

(o mode only) Block output to -records of size bytes.

- -

-c

- -

(o mode only) -Use the old POSIX portable character format. Equivalent to ---format odc.

- -

-d, ---make-directories

- -

(i and p modes) Create -directories as necessary.

- -

-E file

- -

(i mode only) Read list of file -name patterns from file to list and extract.

- -

-F file, ---file file

- -

Read archive from or write -archive to file.

- -

-f pattern

- -

(i mode only) Ignore files that -match pattern.

- -

-H format, ---format format

- -

(o mode only) Produce the -output archive in the specified format. Supported formats -include:

- -

cpio

- -

Synonym for -odc.

- -

newc

- -

The SVR4 -portable cpio format.

- -

odc

- -

The old POSIX.1 -portable octet-oriented cpio format.

- -

pax

- -

The POSIX.1 pax -format, an extension of the ustar format.

- -

ustar

- -

The POSIX.1 tar -format.

- -

The default -format is odc. See libarchive-formats(5) for more -complete information about the formats currently supported -by the underlying libarchive(3) library.

- -

-h, --help

- -

Print usage information.

- -

-I file

- -

Read archive from -file.

- -

-i, --extract

- -

Input mode. See above for -description.

- -

--insecure

- -

(i and p mode only) Disable -security checks during extraction or copying. This allows -extraction via symbolic links, absolute paths, and path -names containing ’..’ in the name.

- -

-J, --xz

- -

(o mode only) Compress the file -with xz-compatible compression before writing it. In input -mode, this option is ignored; xz compression is recognized -automatically on input.

- -

-j

- -

Synonym for --y.

- -

-L

- -

(o and p modes) -All symbolic links will be followed. Normally, symbolic -links are archived and copied as symbolic links. With this -option, the target of the link will be archived or copied -instead.

- -

-l, --link

- -

(p mode only) Create links from -the target directory to the original files, instead of -copying.

- -

--lrzip

- -

(o mode only) Compress the -resulting archive with lrzip(1). In input mode, this option -is ignored.

- -

--lz4

- -

(o mode only) -Compress the archive with lz4-compatible compression before -writing it. In input mode, this option is ignored; lz4 -compression is recognized automatically on input.

- -

--zstd

- -

(o mode only) -Compress the archive with zstd-compatible compression before -writing it. In input mode, this option is ignored; zstd -compression is recognized automatically on input.

- -

--lzma

- -

(o mode only) -Compress the file with lzma-compatible compression before -writing it. In input mode, this option is ignored; lzma -compression is recognized automatically on input.

- -

--lzop

- -

(o mode only) -Compress the resulting archive with lzop(1). In input mode, -this option is ignored.

- -

--passphrase -passphrase

- -

The passphrase is used -to extract or create an encrypted archive. Currently, zip is -only a format that cpio can handle encrypted -archives. You shouldn’t use this option unless you -realize how insecure use of this option is.

- -

-m, ---preserve-modification-time

- -

(i and p modes) Set file -modification time on created files to match those in the -source.

- -

-n, ---numeric-uid-gid

- -

(i mode, only with -t) -Display numeric uid and gid. By default, cpio -displays the user and group names when they are provided in -the archive, or looks up the user and group names in the -system password database.

- -

--no-preserve-owner

- -

(i mode only) Do not attempt to -restore file ownership. This is the default when run by -non-root users.

- -

-O file

- -

Write archive to -file.

- -

-o, --create

- -

Output mode. See above for -description.

- -

-p, ---pass-through

- -

Pass-through mode. See above -for description.

- -

--preserve-owner

- -

(i mode only) Restore file -ownership. This is the default when run by the root -user.

- -

--quiet

- -

Suppress unnecessary -messages.

- -

-R [
-user][
-:][
-group], --owner [
-user][
-:][
-group]

- -

Set the owner and/or group on -files in the output. If group is specified with no user (for -example, -R :wheel) then the group will be set -but not the user. If the user is specified with a trailing -colon and no group (for example, -R root:) -then the group will be set to the user’s default -group. If the user is specified with no trailing colon, then -the user will be set but not the group. In -i and --p modes, this option can only be used by the -super-user. (For compatibility, a period can be used in -place of the colon.)

- -

-r

- -

(All modes.) -Rename files interactively. For each file, a prompt is -written to /dev/tty containing the name of the file -and a line is read from /dev/tty. If the line read is -blank, the file is skipped. If the line contains a single -period, the file is processed normally. Otherwise, the line -is taken to be the new name of the file.

- -

-t, --list

- -

(i mode only) List the contents -of the archive to stdout; do not restore the contents to -disk.

- -

-u, ---unconditional

- -

(i and p modes) Unconditionally -overwrite existing files. Ordinarily, an older file will not -overwrite a newer file on disk.

- -

-V, --dot

- -

Print a dot to stderr for each -file as it is processed. Superseded by -v.

- -

-v, --verbose

- -

Print the name of each file to -stderr as it is processed. With -t, provide a -detailed listing of each file.

- -

--version

- -

Print the program version -information and exit.

- -

-y

- -

(o mode only) -Compress the archive with bzip2-compatible compression -before writing it. In input mode, this option is ignored; -bzip2 compression is recognized automatically on input.

- -

-Z

- -

(o mode only) -Compress the archive with compress-compatible compression -before writing it. In input mode, this option is ignored; -compression is recognized automatically on input.

- -

-z

- -

(o mode only) -Compress the archive with gzip-compatible compression before -writing it. In input mode, this option is ignored; gzip -compression is recognized automatically on input.

- -

EXIT STATUS

- -

The cpio utility -exits 0 on success, and >0 if an error -occurs.

- -

ENVIRONMENT

- -

The following environment -variables affect the execution of cpio:

- -

LANG

- -

The locale to -use. See environ(7) for more information.

- -

TZ

- -

The timezone to -use when displaying dates. See environ(7) for more -information.

- -

EXAMPLES

- -

The cpio command is -traditionally used to copy file hierarchies in conjunction -with the find(1) command. The first example here simply -copies all files from src to dest:

- -

find src | -cpio -pmud dest

- -

By carefully -selecting options to the find(1) command and combining it -with other standard utilities, it is possible to exercise -very fine control over which files are copied. This next -example copies files from src to dest that are -more than 2 days old and whose names match a particular -pattern:

- -

find src --mtime +2 | grep foo[bar] | cpio --pdmu dest

- -

This example -copies files from src to dest that are more -than 2 days old and which contain the word “

- -

foobar ”:

- -

find src --mtime +2 | xargs grep -l foobar | -cpio -pdmu dest

- -

COMPATIBILITY

- -

The mode options i, o, and p and -the options a, B, c, d, f, l, m, r, t, u, and v comply with -SUSv2.

- -

The old POSIX.1 -standard specified that only -i, -o, and --p were interpreted as command-line options. Each -took a single argument of a list of modifier characters. For -example, the standard syntax allows -imu but does not -support -miu or -i -m -u, since m and -u are only modifiers to -i, they are not -command-line options in their own right. The syntax -supported by this implementation is backwards-compatible -with the standard. For best compatibility, scripts should -limit themselves to the standard syntax.

- -

SEE ALSO

- -

bzip2(1), gzip(1), mt(1), -pax(1), tar(1), libarchive(3), cpio(5), -libarchive-formats(5), tar(5)

- -

STANDARDS

- -

There is no current POSIX -standard for the cpio command; it appeared in ISO/IEC -9945-1:1996 (“POSIX.1”) but was dropped from -IEEE Std 1003.1-2001 (“POSIX.1”).

- -

The cpio, ustar, -and pax interchange file formats are defined by IEEE Std -1003.1-2001 (“POSIX.1”) for the pax command.

- -

HISTORY

- -

The original cpio and -find utilities were written by Dick Haight while -working in AT&T’s Unix Support Group. They first -appeared in 1977 in PWB/UNIX 1.0, the -“Programmer’s Work Bench” system developed -for use within AT&T. They were first released outside of -AT&T as part of System III Unix in 1981. As a result, -cpio actually predates tar, even though it was -not well-known outside of AT&T until some time -later.

- -

This is a -complete re-implementation based on the libarchive(3) -library.

- -

BUGS

- -

The cpio archive format has -several basic limitations: It does not store user and group -names, only numbers. As a result, it cannot be reliably used -to transfer files between systems with dissimilar user and -group numbering. Older cpio formats limit the user and group -numbers to 16 or 18 bits, which is insufficient for modern -systems. The cpio archive formats cannot support files over -4 gigabytes, except for the “odc” variant, which -can support files up to 8 gigabytes.

- -

BSD -September 16, 2014 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/bsdtar.1.html b/thirdparty/libarchive/doc/html/bsdtar.1.html deleted file mode 100644 index 776bd32db..000000000 --- a/thirdparty/libarchive/doc/html/bsdtar.1.html +++ /dev/null @@ -1,1427 +0,0 @@ - - - - - - - - - - - - - -
- - -

TAR(1) BSD General Commands Manual TAR(1)

- -

NAME

- -

tar — manipulate -tape archives

- -

SYNOPSIS

- -

tar -[bundled-flags 

- -

args ⟩ ] [⟨
-file
⟩  | ⟨
-pattern
⟩  ...]

- -

tar {-c} -[options] -[files directories]
-tar
{-r -u} -f -archive-file [options] -[files directories]
-tar
{-t -x} [options] -[patterns]

- -

DESCRIPTION

- -

tar creates and -manipulates streaming archive files. This implementation can -extract from tar, pax, cpio, zip, jar, ar, xar, rpm, 7-zip, -and ISO 9660 cdrom images and can create tar, pax, cpio, ar, -zip, 7-zip, and shar archives.

- -

The first -synopsis form shows a “bundled” option word. -This usage is provided for compatibility with historical -implementations. See COMPATIBILITY below for details.

- -

The other -synopsis forms show the preferred usage. The first option to -tar is a mode indicator from the following list:

- -

-c

- -

Create a new -archive containing the specified items. The long option form -is --create.

- -

-r

- -

Like -c, -but new entries are appended to the archive. Note that this -only works on uncompressed archives stored in regular files. -The -f option is required. The long option form is ---append.

- -

-t

- -

List archive -contents to stdout. The long option form is ---list.

- -

-u

- -

Like -r, -but new entries are added only if they have a modification -date newer than the corresponding entry in the archive. Note -that this only works on uncompressed archives stored in -regular files. The -f option is required. The long -form is --update.

- -

-x

- -

Extract to disk -from the archive. If a file with the same name appears more -than once in the archive, each copy will be extracted, with -later copies overwriting (replacing) earlier copies. The -long option form is --extract.

- -

In -c, --r, or -u mode, each specified file or -directory is added to the archive in the order specified on -the command line. By default, the contents of each directory -are also archived.

- -

In extract or -list mode, the entire command line is read and parsed before -the archive is opened. The pathnames or patterns on the -command line indicate which items in the archive should be -processed. Patterns are shell-style globbing patterns as -documented in tcsh(1).

- -

OPTIONS

- -

Unless specifically stated -otherwise, options are applicable in all operating -modes.

- -

@archive

- -

(c and r modes only) The -specified archive is opened and the entries in it will be -appended to the current archive. As a simple example,

- -

tar -c -f - -newfile @original.tar

- -

writes a new archive to -standard output containing a file newfile and all of -the entries from original.tar. In contrast,

- -

tar -c -f - newfile -original.tar

- -

creates a new archive with only -two entries. Similarly,

- -

tar -czf - ---format pax @-

- -

reads an archive from standard -input (whose format will be determined automatically) and -converts it into a gzip-compressed pax-format archive on -stdout. In this way, tar can be used to convert -archives from one format to another.

- -

-a, ---auto-compress

- -

(c mode only) Use the archive -suffix to decide a set of the format and the compressions. -As a simple example,

- -

tar -a -cf -archive.tgz source.c source.h

- -

creates a new archive with -restricted pax format and gzip compression,

- -

tar -a -cf -archive.tar.bz2.uu source.c source.h

- -

creates a new archive with -restricted pax format and bzip2 compression and uuencode -compression,

- -

tar -a -cf -archive.zip source.c source.h

- -

creates a new archive with zip -format,

- -

tar -a -jcf -archive.tgz source.c source.h

- -

ignores the “-j” -option, and creates a new archive with restricted pax format -and gzip compression,

- -

tar -a -jcf -archive.xxx source.c source.h

- -

if it is unknown suffix or no -suffix, creates a new archive with restricted pax format and -bzip2 compression.

- -

--acls

- -

(c, r, u, x -modes only) Archive or extract POSIX.1e or NFSv4 ACLs. This -is the reverse of --no-acls and the default behavior -in c, r, and u modes (except on Mac OS X) or if tar -is run in x mode as root. On Mac OS X this option translates -extended ACLs to NFSv4 ACLs. To store extended ACLs the ---mac-metadata option is preferred.

- -

-B, ---read-full-blocks

- -

Ignored for compatibility with -other tar(1) implementations.

- -

-b blocksize, ---block-size blocksize

- -

Specify the block size, in -512-byte records, for tape drive I/O. As a rule, this -argument is only needed when reading from or writing to tape -drives, and usually not even then as the default block size -of 20 records (10240 bytes) is very common.

- -

-C directory, ---cd directory, --directory -directory

- -

In c and r mode, this changes -the directory before adding the following files. In x mode, -change directories after opening the archive but before -extracting entries from the archive.

- -

--chroot

- -

(x mode only) chroot() -to the current directory after processing any -C -options and before extracting any files.

- - -

--clear-nochange-fflags

- -

(x mode only) Before removing -file system objects to replace them, clear platform-specific -file attributes or file flags that might prevent -removal.

- -

--exclude -pattern

- -

Do not process files or -directories that match the specified pattern. Note that -exclusions take precedence over patterns or filenames -specified on the command line.

- -

--exclude-vcs

- -

Do not process files or -directories internally used by the version control systems -’Arch’, ’Bazaar’, ’CVS’, -’Darcs’, ’Mercurial’, -’RCS’, ’SCCS’, ’SVN’ and -’git’.

- -

--fflags

- -

(c, r, u, x modes only) Archive -or extract platform-specific file attributes or file flags. -This is the reverse of --no-fflags and the default -behavior in c, r, and u modes or if tar is run in x -mode as root.

- -

--format -format

- -

(c, r, u mode only) Use the -specified format for the created archive. Supported formats -include “cpio”, “pax”, -“shar”, and “ustar”. Other formats -may also be supported; see libarchive-formats(5) for more -information about currently-supported formats. In r and u -modes, when extending an existing archive, the format -specified here must be compatible with the format of the -existing archive on disk.

- -

-f file, ---file file

- -

Read the archive from or write -the archive to the specified file. The filename can be -- for standard input or standard output. The default -varies by system; on FreeBSD, the default is -/dev/sa0; on Linux, the default is -/dev/st0.

- -

--gid id

- -

Use the provided group id -number. On extract, this overrides the group id in the -archive; the group name in the archive will be ignored. On -create, this overrides the group id read from disk; if ---gname is not also specified, the group name will be -set to match the group id.

- -

--gname name

- -

Use the provided group name. On -extract, this overrides the group name in the archive; if -the provided group name does not exist on the system, the -group id (from the archive or from the --gid option) -will be used instead. On create, this sets the group name -that will be stored in the archive; the name will not be -verified against the system group database.

- -

-H

- -

(c and r modes -only) Symbolic links named on the command line will be -followed; the target of the link will be archived, not the -link itself.

- -

-h

- -

(c and r modes -only) Synonym for -L.

- -

-I

- -

Synonym for --T.

- -

--help

- -

Show usage.

- -

--hfsCompression

- -

(x mode only) Mac OS X specific -(v10.6 or later). Compress extracted regular files with HFS+ -compression.

- -

--ignore-zeros

- -

An alias of --options -read_concatenated_archives for compatibility with GNU -tar.

- -

--include -pattern

- -

Process only files or -directories that match the specified pattern. Note that -exclusions specified with --exclude take precedence -over inclusions. If no inclusions are explicitly specified, -all entries are processed by default. The --include -option is especially useful when filtering archives. For -example, the command

- -

tar -c -f new.tar ---include=’*foo*’ @old.tgz

- -

creates a new archive -new.tar containing only the entries from -old.tgz containing the string ’foo’.

- -

-J, --xz

- -

(c mode only) Compress the -resulting archive with xz(1). In extract or list modes, this -option is ignored. Note that this tar implementation -recognizes XZ compression automatically when reading -archives.

- -

-j, --bzip, ---bzip2, --bunzip2

- -

(c mode only) Compress the -resulting archive with bzip2(1). In extract or list modes, -this option is ignored. Note that this tar -implementation recognizes bzip2 compression automatically -when reading archives.

- -

-k, ---keep-old-files

- -

(x mode only) Do not overwrite -existing files. In particular, if a file appears more than -once in an archive, later copies will not overwrite earlier -copies.

- -

--keep-newer-files

- -

(x mode only) Do not overwrite -existing files that are newer than the versions appearing in -the archive being extracted.

- -

-L, ---dereference

- -

(c and r modes only) All -symbolic links will be followed. Normally, symbolic links -are archived as such. With this option, the target of the -link will be archived instead.

- -

-l, ---check-links

- -

(c and r modes only) Issue a -warning message unless all links to each file are -archived.

- -

--lrzip

- -

(c mode only) Compress the -resulting archive with lrzip(1). In extract or list modes, -this option is ignored. Note that this tar -implementation recognizes lrzip compression automatically -when reading archives.

- -

--lz4

- -

(c mode only) -Compress the archive with lz4-compatible compression before -writing it. In extract or list modes, this option is -ignored. Note that this tar implementation recognizes -lz4 compression automatically when reading archives.

- -

--zstd

- -

(c mode only) -Compress the archive with zstd-compatible compression before -writing it. In extract or list modes, this option is -ignored. Note that this tar implementation recognizes -zstd compression automatically when reading archives.

- -

--lzma

- -

(c mode only) -Compress the resulting archive with the original LZMA -algorithm. In extract or list modes, this option is ignored. -Use of this option is discouraged and new archives should be -created with --xz instead. Note that this tar -implementation recognizes LZMA compression automatically -when reading archives.

- -

--lzop

- -

(c mode only) -Compress the resulting archive with lzop(1). In extract or -list modes, this option is ignored. Note that this -tar implementation recognizes LZO compression -automatically when reading archives.

- -

-m, ---modification-time

- -

(x mode only) Do not extract -modification time. By default, the modification time is set -to the time stored in the archive.

- -

--mac-metadata

- -

(c, r, u and x mode only) Mac -OS X specific. Archive or extract extended ACLs and extended -file attributes using copyfile(3) in AppleDouble format. -This is the reverse of --no-mac-metadata. and the -default behavior in c, r, and u modes or if tar is -run in x mode as root.

- -

-n, --norecurse, ---no-recursion

- -

Do not operate recursively on -the content of directories.

- -

--newer date

- -

(c, r, u modes only) Only -include files and directories newer than the specified date. -This compares ctime entries.

- -

--newer-mtime -date

- -

(c, r, u modes only) Like ---newer, except it compares mtime entries instead of -ctime entries.

- -

--newer-than -file

- -

(c, r, u modes only) Only -include files and directories newer than the specified file. -This compares ctime entries.

- -

--newer-mtime-than -file

- -

(c, r, u modes only) Like ---newer-than, except it compares mtime entries -instead of ctime entries.

- -

--nodump

- -

(c and r modes only) Honor the -nodump file flag by skipping this file.

- - -

--nopreserveHFSCompression

- -

(x mode only) Mac OS X specific -(v10.6 or later). Do not compress extracted regular files -which were compressed with HFS+ compression before archived. -By default, compress the regular files again with HFS+ -compression.

- -

--null

- -

(use with --I or -T) Filenames or patterns are separated -by null characters, not by newlines. This is often used to -read filenames output by the -print0 option to -find(1).

- -

--no-acls

- -

(c, r, u, x modes only) Do not -archive or extract POSIX.1e or NFSv4 ACLs. This is the -reverse of --acls and the default behavior if -tar is run as non-root in x mode (on Mac OS X as any -user in c, r, u and x modes).

- -

--no-fflags

- -

(c, r, u, x modes only) Do not -archive or extract file attributes or file flags. This is -the reverse of --fflags and the default behavior if -tar is run as non-root in x mode.

- -

--no-mac-metadata

- -

(x mode only) Mac OS X -specific. Do not archive or extract ACLs and extended file -attributes using copyfile(3) in AppleDouble format. This is -the reverse of --mac-metadata. and the default -behavior if tar is run as non-root in x mode.

- -

--no-read-sparse

- -

(c, r, u modes only) Do not -read sparse file information from disk. This is the reverse -of --read-sparse.

- -

--no-safe-writes

- -

(x mode only) Do not create -temporary files and use rename(2) to replace the original -ones. This is the reverse of --safe-writes.

- -

--no-same-owner

- -

(x mode only) Do not extract -owner and group IDs. This is the reverse of ---same-owner and the default behavior if tar -is run as non-root.

- - -

--no-same-permissions

- -

(x mode only) Do not extract -full permissions (SGID, SUID, sticky bit, file attributes or -file flags, extended file attributes and ACLs). This is the -reverse of -p and the default behavior if tar -is run as non-root.

- -

--no-xattrs

- -

(c, r, u, x modes only) Do not -archive or extract extended file attributes. This is the -reverse of --xattrs and the default behavior if -tar is run as non-root in x mode.

- -

--numeric-owner

- -

This is equivalent to ---uname "" --gname "". On -extract, it causes user and group names in the archive to be -ignored in favor of the numeric user and group ids. On -create, it causes user and group names to not be stored in -the archive.

- -

-O, ---to-stdout

- -

(x, t modes only) In extract -(-x) mode, files will be written to standard out rather than -being extracted to disk. In list (-t) mode, the file listing -will be written to stderr rather than the usual stdout.

- -

-o

- -

(x mode) Use -the user and group of the user running the program rather -than those specified in the archive. Note that this has no -significance unless -p is specified, and the program -is being run by the root user. In this case, the file modes -and flags from the archive will be restored, but ACLs or -owner information in the archive will be discarded.

- -

-o

- -

(c, r, u mode) -A synonym for --format ustar

- -

--older date

- -

(c, r, u modes only) Only -include files and directories older than the specified date. -This compares ctime entries.

- -

--older-mtime -date

- -

(c, r, u modes only) Like ---older, except it compares mtime entries instead of -ctime entries.

- -

--older-than -file

- -

(c, r, u modes only) Only -include files and directories older than the specified file. -This compares ctime entries.

- -

--older-mtime-than -file

- -

(c, r, u modes only) Like ---older-than, except it compares mtime entries -instead of ctime entries.

- -

--one-file-system

- -

(c, r, and u modes) Do not -cross mount points.

- -

--options -options

- -

Select optional behaviors for -particular modules. The argument is a text string containing -comma-separated keywords and values. These are passed to the -modules that handle particular formats to control how those -formats will behave. Each option has one of the following -forms:

- -

key=value

- -

The key will be set to the -specified value in every module that supports it. Modules -that do not support this key will ignore it.

- -

key

- -

The key will be -enabled in every module that supports it. This is equivalent -to key=1.

- -

!key

- -

The key will be -disabled in every module that supports it.

- -

module:key=value, module:key, -module:!key

- -

As above, but the corresponding -key and value will be provided only to modules whose name -matches module.

- -

The complete -list of supported modules and keys for create and append -modes is in archive_write_set_options(3) and for extract and -list modes in archive_read_set_options(3).

- -

Examples of -supported options:

- -

iso9660:joliet

- -

Support Joliet extensions. This -is enabled by default, use !joliet or -iso9660:!joliet to disable.

- -

iso9660:rockridge

- -

Support Rock Ridge extensions. -This is enabled by default, use !rockridge or -iso9660:!rockridge to disable.

- -

gzip:compression-level

- -

A decimal integer from 1 to 9 -specifying the gzip compression level.

- -

gzip:timestamp

- -

Store timestamp. This is -enabled by default, use !timestamp or -gzip:!timestamp to disable.

- -

lrzip:compression=type

- -

Use type as compression -method. Supported values are bzip2, gzip, lzo (ultra fast), -and zpaq (best, extremely slow).

- -

lrzip:compression-level

- -

A decimal integer from 1 to 9 -specifying the lrzip compression level.

- -

lz4:compression-level

- -

A decimal integer from 1 to 9 -specifying the lzop compression level.

- -

lz4:stream-checksum

- -

Enable stream checksum. This is -by default, use lz4:!stream-checksum to disable.

- -

lz4:block-checksum

- -

Enable block checksum (Disabled -by default).

- -

lz4:block-size

- -

A decimal integer from 4 to 7 -specifying the lz4 compression block size (7 is set by -default).

- -

lz4:block-dependence

- -

Use the previous block of the -block being compressed for a compression dictionary to -improve compression ratio.

- -

zstd:compression-level

- -

A decimal integer specifying -the zstd compression level. Supported values depend on the -library version, common values are from 1 to 22.

- -

zstd:threads

- -

Specify the number of worker -threads to use. Setting threads to a special value 0 makes -zstd(1) use as many threads as there are CPU cores on the -system.

- -

zstd:frame-per-file

- -

Start a new compression frame -at the beginning of each file in the archive.

- -

zstd:min-frame-size=N

- -

In combination with -zstd:frame-per-file, do not start a new compression -frame unless the current frame is at least N -bytes.

- -

zstd:max-frame-size=N

- -

Start a new compression frame -as soon as the current frame exceeds N bytes.

- -

lzop:compression-level

- -

A decimal integer from 1 to 9 -specifying the lzop compression level.

- -

xz:compression-level

- -

A decimal integer from 0 to 9 -specifying the xz compression level.

- -

xz:threads

- -

Specify the number of worker -threads to use. Setting threads to a special value 0 makes -xz(1) use as many threads as there are CPU cores on the -system.

- -

mtree:keyword

- -

The mtree writer module allows -you to specify which mtree keywords will be included in the -output. Supported keywords include: cksum, -device, flags, gid, gname, -indent, link, md5, mode, -nlink, rmd160, sha1, sha256, -sha384, sha512, size, time, -uid, uname. The default is equivalent to: -“device, flags, gid, gname, link, mode, nlink, size, -time, type, uid, uname”.

- -

mtree:all

- -

Enables all of the above -keywords. You can also use mtree:!all to disable all -keywords.

- -

mtree:use-set

- -

Enable generation of -/set lines in the output.

- -

mtree:indent

- -

Produce human-readable output -by indenting options and splitting lines to fit into 80 -columns.

- -

zip:compression=type

- -

Use type as compression -method. Supported values are store (uncompressed) and -deflate (gzip algorithm).

- -

zip:encryption

- -

Enable encryption using -traditional zip encryption.

- -

zip:encryption=type

- -

Use type as encryption -type. Supported values are zipcrypt (traditional zip -encryption), aes128 (WinZip AES-128 encryption) and aes256 -(WinZip AES-256 encryption).

- -

read_concatenated_archives

- -

Ignore zeroed blocks in the -archive, which occurs when multiple tar archives have been -concatenated together. Without this option, only the -contents of the first concatenated archive would be read. -This option is comparable to the -i, ---ignore-zeros option of GNU tar.

- -

If a provided option is not -supported by any module, that is a fatal error.

- -

-P, ---absolute-paths

- -

Preserve pathnames. By default, -absolute pathnames (those that begin with a / character) -have the leading slash removed both when creating archives -and extracting from them. Also, tar will refuse to -extract archive entries whose pathnames contain .. or -whose target directory would be altered by a symlink. This -option suppresses these behaviors.

- -

-p, --insecure, ---preserve-permissions

- -

(x mode only) Preserve file -permissions. Attempt to restore the full permissions, -including file modes, file attributes or file flags, -extended file attributes and ACLs, if available, for each -item extracted from the archive. This is the reverse of ---no-same-permissions and the default if tar -is being run as root. It can be partially overridden by also -specifying --no-acls, --no-fflags, ---no-mac-metadata or --no-xattrs.

- -

--passphrase -passphrase

- -

The passphrase is used -to extract or create an encrypted archive. Currently, zip is -the only supported format that supports encryption. You -shouldn’t use this option unless you realize how -insecure use of this option is.

- -

--posix

- -

(c, r, u mode only) Synonym for ---format pax

- -

-q, ---fast-read

- -

(x and t mode only) Extract or -list only the first archive entry that matches each pattern -or filename operand. Exit as soon as each specified pattern -or filename has been matched. By default, the archive is -always read to the very end, since there can be multiple -entries with the same name and, by convention, later entries -overwrite earlier entries. This option is provided as a -performance optimization.

- -

--read-sparse

- -

(c, r, u modes only) Read -sparse file information from disk. This is the reverse of ---no-read-sparse and the default behavior.

- -

-S

- -

(x mode only) -Extract files as sparse files. For every block on disk, -check first if it contains only NULL bytes and seek over it -otherwise. This works similar to the conv=sparse option of -dd.

- -

-s pattern

- -

Modify file or archive member -names according to pattern. The pattern has the -format /old/new/[ghHprRsS] where old is a -basic regular expression, new is the replacement -string of the matched part, and the optional trailing -letters modify how the replacement is handled. If old -is not matched, the pattern is skipped. Within new, ~ -is substituted with the match, \1 to \9 with the content of -the corresponding captured group. The optional trailing g -specifies that matching should continue after the matched -part and stop on the first unmatched pattern. The optional -trailing s specifies that the pattern applies to the value -of symbolic links. The optional trailing p specifies that -after a successful substitution the original path name and -the new path name should be printed to standard error. -Optional trailing H, R, or S characters suppress -substitutions for hardlink targets, regular filenames, or -symlink targets, respectively. Optional trailing h, r, or s -characters enable substitutions for hardlink targets, -regular filenames, or symlink targets, respectively. The -default is hrs which applies substitutions to all -names. In particular, it is never necessary to specify h, r, -or s.

- -

--safe-writes

- -

(x mode only) Extract files -atomically. By default tar unlinks the original file -with the same name as the extracted file (if it exists), and -then creates it immediately under the same name and writes -to it. For a short period of time, applications trying to -access the file might not find it, or see incomplete -results. If --safe-writes is enabled, tar -first creates a unique temporary file, then writes the new -contents to the temporary file, and finally renames the -temporary file to its final name atomically using rename(2). -This guarantees that an application accessing the file, will -either see the old contents or the new contents at all -times.

- -

--same-owner

- -

(x mode only) Extract owner and -group IDs. This is the reverse of --no-same-owner and -the default behavior if tar is run as root.

- -

--strip-components -count

- -

Remove the specified number of -leading path elements. Pathnames with fewer elements will be -silently skipped. Note that the pathname is edited after -checking inclusion/exclusion patterns but before security -checks.

- -

-T filename, ---files-from filename

- -

In x or t mode, tar will -read the list of names to be extracted from filename. -In c mode, tar will read names to be archived from -filename. The special name “-C” on a line -by itself will cause the current directory to be changed to -the directory specified on the following line. Names are -terminated by newlines unless --null is specified. -Note that --null also disables the special handling -of lines containing “-C”. Note: If you are -generating lists of files using find(1), you probably want -to use -n as well.

- -

--totals

- -

(c, r, u modes only) After -archiving all files, print a summary to stderr.

- -

-U, --unlink, ---unlink-first

- -

(x mode only) Unlink files -before creating them. This can be a minor performance -optimization if most files already exist, but can make -things slower if most files do not already exist. This flag -also causes tar to remove intervening directory -symlinks instead of reporting an error. See the SECURITY -section below for more details.

- -

--uid id

- -

Use the provided user id number -and ignore the user name from the archive. On create, if ---uname is not also specified, the user name will be -set to match the user id.

- -

--uname name

- -

Use the provided user name. On -extract, this overrides the user name in the archive; if the -provided user name does not exist on the system, it will be -ignored and the user id (from the archive or from the ---uid option) will be used instead. On create, this -sets the user name that will be stored in the archive; the -name is not verified against the system user database.

- -

--use-compress-program -program

- -

Pipe the input (in x or t mode) -or the output (in c mode) through program instead of -using the builtin compression support.

- -

-v, --verbose

- -

Produce verbose output. In -create and extract modes, tar will list each file -name as it is read from or written to the archive. In list -mode, tar will produce output similar to that of -ls(1). An additional -v option will also provide -ls-like details in create and extract mode.

- -

--version

- -

Print version of tar and -libarchive, and exit.

- -

-w, ---confirmation, --interactive

- -

Ask for confirmation for every -action.

- -

-X filename, ---exclude-from filename

- -

Read a list of exclusion -patterns from the specified file. See --exclude for -more information about the handling of exclusions.

- -

--xattrs

- -

(c, r, u, x modes only) Archive -or extract extended file attributes. This is the reverse of ---no-xattrs and the default behavior in c, r, and u -modes or if tar is run in x mode as root.

- -

-y

- -

(c mode only) -Compress the resulting archive with bzip2(1). In extract or -list modes, this option is ignored. Note that this -tar implementation recognizes bzip2 compression -automatically when reading archives.

- -

-Z, --compress, ---uncompress

- -

(c mode only) Compress the -resulting archive with compress(1). In extract or list -modes, this option is ignored. Note that this tar -implementation recognizes compress compression automatically -when reading archives.

- -

-z, --gunzip, ---gzip

- -

(c mode only) Compress the -resulting archive with gzip(1). In extract or list modes, -this option is ignored. Note that this tar -implementation recognizes gzip compression automatically -when reading archives.

- -

ENVIRONMENT

- -

The following environment -variables affect the execution of tar:

- -

TAR_READER_OPTIONS

- -

The default options for format -readers and compression readers. The --options option -overrides this.

- -

TAR_WRITER_OPTIONS

- -

The default options for format -writers and compression writers. The --options option -overrides this.

- -

LANG

- -

The locale to -use. See environ(7) for more information.

- -

TAPE

- -

The default -device. The -f option overrides this. Please see the -description of the -f option above for more -details.

- -

TZ

- -

The timezone to -use when displaying dates. See environ(7) for more -information.

- -

EXIT STATUS

- -

The tar utility -exits 0 on success, and >0 if an error -occurs.

- -

EXAMPLES

- -

The following creates a new -archive called file.tar.gz that contains two files -source.c and source.h:

- -

tar -czf file.tar.gz -source.c source.h

- -

To view a -detailed table of contents for this archive:

- -

tar -tvf -file.tar.gz

- -

To extract all -entries from the archive on the default tape drive:

- -

tar -x

- -

To examine the -contents of an ISO 9660 cdrom image:

- -

tar -tf -image.iso

- -

To move file -hierarchies, invoke tar as

- -

tar -cf - --C srcdir . | tar -xpf - --C destdir

- -

or more traditionally

- -

cd srcdir ; tar -cf - -. | (cd destdir ; tar -xpf -)

- -

In create mode, -the list of files and directories to be archived can also -include directory change instructions of the form --Cfoo/baz and archive inclusions of the form -@archive-file. For example, the command -line

- -

tar -c -f new.tar -foo1 @old.tgz -C/tmp -foo2

- -

will create a new archive -new.tar. tar will read the file foo1 -from the current directory and add it to the output archive. -It will then read each entry from old.tgz and add -those entries to the output archive. Finally, it will switch -to the /tmp directory and add foo2 to the -output archive.

- -

An input file in -mtree(5) format can be used to create an output archive with -arbitrary ownership, permissions, or names that differ from -existing data on disk:

- -

$ cat -input.mtree
-#mtree
-usr/bin uid=0 gid=0 mode=0755 type=dir
-usr/bin/ls uid=0 gid=0 mode=0755 type=file content=myls
-$ tar -cvf output.tar @input.mtree

- -

The ---newer and --newer-mtime switches accept a -variety of common date and time specifications, including -“12 Mar 2005 7:14:29pm”, “2005-03-12 -19:14”, “5 minutes ago”, and “19:14 -PST May 1”.

- -

The ---options argument can be used to control various -details of archive generation or reading. For example, you -can generate mtree output which only contains type, -time, and uid keywords:

- -

tar -cf file.tar ---format=mtree ---options=’!all,type,time,uid’ -dir

- -

or you can set the compression -level used by gzip or xz compression:

- -

tar -czf file.tar ---options=’compression-level=9’.

- -

For more details, see the -explanation of the archive_read_set_options() and -archive_write_set_options() API calls that are -described in archive_read(3) and archive_write(3).

- -

COMPATIBILITY

- -

The bundled-arguments format is -supported for compatibility with historic implementations. -It consists of an initial word (with no leading - character) -in which each character indicates an option. Arguments -follow as separate words. The order of the arguments must -match the order of the corresponding characters in the -bundled command word. For example,

- -

tar tbf 32 -file.tar

- -

specifies three flags t, -b, and f. The b and f flags both -require arguments, so there must be two additional items on -the command line. The 32 is the argument to the -b flag, and file.tar is the argument to the -f flag.

- -

The mode options -c, r, t, u, and x and the options b, f, l, m, o, v, and w -comply with SUSv2.

- -

For maximum -portability, scripts that invoke tar should use the -bundled-argument format above, should limit themselves to -the c, t, and x modes, and the -b, f, m, v, and w -options.

- -

Additional long -options are provided to improve compatibility with other tar -implementations.

- -

SECURITY

- -

Certain security issues are -common to many archiving programs, including tar. In -particular, carefully-crafted archives can request that -tar extract files to locations outside of the target -directory. This can potentially be used to cause unwitting -users to overwrite files they did not intend to overwrite. -If the archive is being extracted by the superuser, any file -on the system can potentially be overwritten. There are -three ways this can happen. Although tar has -mechanisms to protect against each one, savvy users should -be aware of the implications:

- -

- -

Archive entries can have -absolute pathnames. By default, tar removes the -leading / character from filenames before restoring -them to guard against this problem.

- -

- -

Archive entries can have -pathnames that include .. components. By default, -tar will not extract files containing .. -components in their pathname.

- -

- -

Archive entries can exploit -symbolic links to restore files to other directories. An -archive can restore a symbolic link to another directory, -then use that link to restore a file into that directory. To -guard against this, tar checks each extracted path -for symlinks. If the final path element is a symlink, it -will be removed and replaced with the archive entry. If --U is specified, any intermediate symlink will also -be unconditionally removed. If neither -U nor --P is specified, tar will refuse to extract -the entry.

- -

To protect yourself, you should -be wary of any archives that come from untrusted sources. -You should examine the contents of an archive with

- -

tar -tf -filename

- -

before extraction. You should -use the -k option to ensure that tar will not -overwrite any existing files or the -U option to -remove any pre-existing files. You should generally not -extract archives while running with super-user privileges. -Note that the -P option to tar disables the -security checks above and allows you to extract an archive -while preserving any absolute pathnames, .. -components, or symlinks to other directories.

- -

SEE ALSO

- -

bzip2(1), compress(1), cpio(1), -gzip(1), mt(1), pax(1), shar(1), xz(1), libarchive(3), -libarchive-formats(5), tar(5)

- -

STANDARDS

- -

There is no current POSIX -standard for the tar command; it appeared in ISO/IEC -9945-1:1996 (“POSIX.1”) but was dropped from -IEEE Std 1003.1-2001 (“POSIX.1”). The options -supported by this implementation were developed by surveying -a number of existing tar implementations as well as the old -POSIX specification for tar and the current POSIX -specification for pax.

- -

The ustar and -pax interchange file formats are defined by IEEE Std -1003.1-2001 (“POSIX.1”) for the pax command.

- -

HISTORY

- -

A tar command appeared in -Seventh Edition Unix, which was released in January, 1979. -There have been numerous other implementations, many of -which extended the file format. John Gilmore’s -pdtar public-domain implementation (circa November, -1987) was quite influential, and formed the basis of GNU -tar. GNU tar was included as the standard system tar in -FreeBSD beginning with FreeBSD 1.0.

- -

This is a -complete re-implementation based on the libarchive(3) -library. It was first released with FreeBSD 5.4 in May, -2005.

- -

BUGS

- -

This program follows ISO/IEC -9945-1:1996 (“POSIX.1”) for the definition of -the -l option. Note that GNU tar prior to version -1.15 treated -l as a synonym for the ---one-file-system option.

- -

The -C -dir option may differ from historic -implementations.

- -

All archive -output is written in correctly-sized blocks, even if the -output is being compressed. Whether or not the last output -block is padded to a full block size varies depending on the -format and the output device. For tar and cpio formats, the -last block of output is padded to a full block size if the -output is being written to standard output or to a character -or block device such as a tape drive. If the output is being -written to a regular file, the last block will not be -padded. Many compressors, including gzip(1) and bzip2(1), -complain about the null padding when decompressing an -archive created by tar, although they still extract -it correctly.

- -

The compression -and decompression is implemented internally, so there may be -insignificant differences between the compressed output -generated by

- -

tar -czf - -file

- -

and that generated by

- -

tar -cf - file | -gzip

- -

The default -should be to read and write archives to the standard I/O -paths, but tradition (and POSIX) dictates otherwise.

- -

The r and -u modes require that the archive be uncompressed and -located in a regular file on disk. Other archives can be -modified using c mode with the @archive-file -extension.

- -

To archive a -file called @foo or -foo you must specify it -as ./@foo or ./-foo, respectively.

- -

In create mode, -a leading ./ is always removed. A leading / is -stripped unless the -P option is specified.

- -

There needs to -be better support for file selection on both create and -extract.

- -

There is not yet -any support for multi-volume archives.

- -

Converting -between dissimilar archive formats (such as tar and cpio) -using the @- convention can cause hard link -information to be lost. (This is a consequence of the -incompatible ways that different archive formats store -hardlink information.)

- -

BSD -December 1, 2022 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/cpio.5.html b/thirdparty/libarchive/doc/html/cpio.5.html deleted file mode 100644 index 5d670c248..000000000 --- a/thirdparty/libarchive/doc/html/cpio.5.html +++ /dev/null @@ -1,482 +0,0 @@ - - - - - - - - - - - - - -
- - -

CPIO(5) BSD File Formats Manual CPIO(5)

- -

NAME

- -

cpio — format of -cpio archive files

- -

DESCRIPTION

- -

The cpio archive format -collects any number of files, directories, and other file -system objects (symbolic links, device nodes, etc.) into a -single stream of bytes.

- -

General -Format
-Each file system object in a cpio archive comprises a -header record with basic numeric metadata followed by the -full pathname of the entry and the file data. The header -record stores a series of integer values that generally -follow the fields in struct stat. (See stat(2) for -details.) The variants differ primarily in how they store -those integers (binary, octal, or hexadecimal). The header -is followed by the pathname of the entry (the length of the -pathname is stored in the header) and any file data. The end -of the archive is indicated by a special record with the -pathname “TRAILER!!!”.

- -

PWB -format
-The PWB binary cpio format is the original format, -when cpio was introduced as part of the Programmer’s -Work Bench system, a variant of 6th Edition UNIX. It stores -numbers as 2-byte and 4-byte binary values. Each entry -begins with a header in the following format:

- -

struct -header_pwb_cpio {
-short h_magic;
-short h_dev;
-short h_ino;
-short h_mode;
-short h_uid;
-short h_gid;
-short h_nlink;
-short h_majmin;
-long h_mtime;
-short h_namesize;
-long h_filesize;
-};

- -

The short -fields here are 16-bit integer values, while the long -fields are 32 bit integers. Since PWB UNIX, like the 6th -Edition UNIX it was based on, only ran on PDP-11 computers, -they are in PDP-endian format, which has little-endian -shorts, and big-endian longs. That is, the long integer -whose hexadecimal representation is 0x12345678 would be -stored in four successive bytes as 0x34, 0x12, 0x78, 0x56. -The fields are as follows:

- -

h_magic

- -

The integer value octal -070707.

- -

h_dev, h_ino

- -

The device and inode numbers -from the disk. These are used by programs that read -cpio archives to determine when two entries refer to -the same file. Programs that synthesize cpio archives -should be careful to set these to distinct values for each -entry.

- -

h_mode

- -

The mode -specifies both the regular permissions and the file type, -and it also holds a couple of bits that are irrelevant to -the cpio format, because the field is actually a raw copy of -the mode field in the inode representing the file. These are -the IALLOC flag, which shows that the inode entry is in use, -and the ILARG flag, which shows that the file it represents -is large enough to have indirect blocks pointers in the -inode. The mode is decoded as follows:

- -

0100000

- -

IALLOC flag - -irrelevant to cpio.

- -

0060000

- -

This masks the -file type bits.

- -

0040000

- -

File type value -for directories.

- -

0020000

- -

File type value -for character special devices.

- -

0060000

- -

File type value -for block special devices.

- -

0010000

- -

ILARG flag - -irrelevant to cpio.

- -

0004000

- -

SUID bit.

- -

0002000

- -

SGID bit.

- -

0001000

- -

Sticky bit.

- -

0000777

- -

The lower 9 -bits specify read/write/execute permissions for world, -group, and user following standard POSIX conventions.

- -

h_uid, h_gid

- -

The numeric user id and group -id of the owner.

- -

h_nlink

- -

The number of links to this -file. Directories always have a value of at least two here. -Note that hardlinked files include file data with every copy -in the archive.

- -

h_majmin

- -

For block special and character -special entries, this field contains the associated device -number, with the major number in the high byte, and the -minor number in the low byte. For all other entry types, it -should be set to zero by writers and ignored by readers.

- -

h_mtime

- -

Modification time of the file, -indicated as the number of seconds since the start of the -epoch, 00:00:00 UTC January 1, 1970.

- -

h_namesize

- -

The number of bytes in the -pathname that follows the header. This count includes the -trailing NUL byte.

- -

h_filesize

- -

The size of the file. Note that -this archive format is limited to 16 megabyte file sizes, -because PWB UNIX, like 6th Edition, only used an unsigned 24 -bit integer for the file size internally.

- -

The pathname -immediately follows the fixed header. If h_namesize -is odd, an additional NUL byte is added after the pathname. -The file data is then appended, again with an additional NUL -appended if needed to get the next header at an even -offset.

- -

Hardlinked files -are not given special treatment; the full file contents are -included with each copy of the file.

- -

New Binary -Format
-The new binary cpio format showed up when cpio was -adopted into late 7th Edition UNIX. It is exactly like the -PWB binary format, described above, except for three -changes:

- -

First, UNIX now -ran on more than one hardware type, so the endianness of 16 -bit integers must be determined by observing the magic -number at the start of the header. The 32 bit integers are -still always stored with the most significant word first, -though, so each of those two, in the struct shown above, was -stored as an array of two 16 bit integers, in the -traditional order. Those 16 bit integers, like all the -others in the struct, were accessed using a macro that byte -swapped them if necessary.

- -

Next, 7th -Edition had more file types to store, and the IALLOC and -ILARG flag bits were re-purposed to accommodate these. The -revised use of the various bits is as follows:

- -

0170000

- -

This masks the -file type bits.

- -

0140000

- -

File type value -for sockets.

- -

0120000

- -

File type value -for symbolic links. For symbolic links, the link body is -stored as file data.

- -

0100000

- -

File type value -for regular files.

- -

0060000

- -

File type value -for block special devices.

- -

0040000

- -

File type value -for directories.

- -

0020000

- -

File type value -for character special devices.

- -

0010000

- -

File type value -for named pipes or FIFOs.

- -

0004000

- -

SUID bit.

- -

0002000

- -

SGID bit.

- -

0001000

- -

Sticky bit.

- -

0000777

- -

The lower 9 -bits specify read/write/execute permissions for world, -group, and user following standard POSIX conventions.

- -

Finally, the -file size field now represents a signed 32 bit integer in -the underlying file system, so the maximum file size has -increased to 2 gigabytes.

- -

Note that there -is no obvious way to tell which of the two binary formats an -archive uses, other than to see which one makes more sense. -The typical error scenario is that a PWB format archive -unpacked as if it were in the new format will create named -sockets instead of directories, and then fail to unpack -files that should go in those directories. Running -bsdcpio -itv on an unknown archive will make it -obvious which it is: if it’s PWB format, directories -will be listed with an ’s’ instead of a -’d’ as the first character of the mode string, -and the larger files will have a ’?’ in that -position.

- -

Portable -ASCII Format
-Version 2 of the Single UNIX Specification -(“SUSv2”) standardized an ASCII variant that is -portable across all platforms. It is commonly known as the -“old character” format or as the -“odc” format. It stores the same numeric fields -as the old binary format, but represents them as 6-character -or 11-character octal values.

- -

struct -cpio_odc_header {
-char c_magic[6];
-char c_dev[6];
-char c_ino[6];
-char c_mode[6];
-char c_uid[6];
-char c_gid[6];
-char c_nlink[6];
-char c_rdev[6];
-char c_mtime[11];
-char c_namesize[6];
-char c_filesize[11];
-};

- -

The fields are -identical to those in the new binary format. The name and -file body follow the fixed header. Unlike the binary -formats, there is no additional padding after the pathname -or file contents. If the files being archived are themselves -entirely ASCII, then the resulting archive will be entirely -ASCII, except for the NUL byte that terminates the name -field.

- -

New ASCII -Format
-The "new" ASCII format uses 8-byte hexadecimal -fields for all numbers and separates device numbers into -separate fields for major and minor numbers.

- -

struct -cpio_newc_header {
-char c_magic[6];
-char c_ino[8];
-char c_mode[8];
-char c_uid[8];
-char c_gid[8];
-char c_nlink[8];
-char c_mtime[8];
-char c_filesize[8];
-char c_devmajor[8];
-char c_devminor[8];
-char c_rdevmajor[8];
-char c_rdevminor[8];
-char c_namesize[8];
-char c_check[8];
-};

- -

Except as -specified below, the fields here match those specified for -the new binary format above.

- -

magic

- -

The string -“070701”.

- -

check

- -

This field is -always set to zero by writers and ignored by readers. See -the next section for more details.

- -

The pathname is -followed by NUL bytes so that the total size of the fixed -header plus pathname is a multiple of four. Likewise, the -file data is padded to a multiple of four bytes. Note that -this format supports only 4 gigabyte files (unlike the older -ASCII format, which supports 8 gigabyte files).

- -

In this format, -hardlinked files are handled by setting the filesize to zero -for each entry except the first one that appears in the -archive.

- -

New CRC -Format
-The CRC format is identical to the new ASCII format -described in the previous section except that the magic -field is set to “070702” and the check -field is set to the sum of all bytes in the file data. This -sum is computed treating all bytes as unsigned values and -using unsigned arithmetic. Only the least-significant 32 -bits of the sum are stored.

- -

HP -variants
-The cpio implementation distributed with HPUX used -XXXX but stored device numbers differently XXX.

- -

Other -Extensions and Variants
-Sun Solaris uses additional file types to store extended -file data, including ACLs and extended attributes, as -special entries in cpio archives.

- -

XXX Others? -XXX

- -

SEE ALSO

- -

cpio(1), tar(5)

- -

STANDARDS

- -

The cpio utility is no -longer a part of POSIX or the Single Unix Standard. It last -appeared in Version 2 of the Single UNIX Specification -(“SUSv2”). It has been supplanted in subsequent -standards by pax(1). The portable ASCII format is currently -part of the specification for the pax(1) utility.

- -

HISTORY

- -

The original cpio utility was -written by Dick Haight while working in AT&T’s -Unix Support Group. It appeared in 1977 as part of PWB/UNIX -1.0, the “Programmer’s Work Bench” derived -from Version 6 AT&T UNIX that was used internally -at AT&T. Both the new binary and old character formats -were in use by 1980, according to the System III source -released by SCO under their “Ancient Unix” -license. The character format was adopted as part of IEEE -Std 1003.1-1988 (“POSIX.1”). XXX when did -"newc" appear? Who invented it? When did HP come -out with their variant? When did Sun introduce ACLs and -extended attributes? XXX

- -

BUGS

- -

The “CRC” format is -mis-named, as it uses a simple checksum and not a cyclic -redundancy check.

- -

The binary -formats are limited to 16 bits for user id, group id, -device, and inode numbers. They are limited to 16 megabyte -and 2 gigabyte file sizes for the older and newer variants, -respectively.

- -

The old ASCII -format is limited to 18 bits for the user id, group id, -device, and inode numbers. It is limited to 8 gigabyte file -sizes.

- -

The new ASCII -format is limited to 4 gigabyte file sizes.

- -

None of the cpio -formats store user or group names, which are essential when -moving files between systems with dissimilar user or group -numbering.

- -

Especially when -writing older cpio variants, it may be necessary to map -actual device/inode values to synthesized values that fit -the available fields. With very large filesystems, this may -be necessary even for the newer formats.

- -

BSD -December 23, 2011 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/libarchive-formats.5.html b/thirdparty/libarchive/doc/html/libarchive-formats.5.html deleted file mode 100644 index 32f5220b9..000000000 --- a/thirdparty/libarchive/doc/html/libarchive-formats.5.html +++ /dev/null @@ -1,503 +0,0 @@ - - - - - - - - - - - - - -
- - -

LIBARCHIVE-FORMATS(5) BSD File Formats Manual -LIBARCHIVE-FORMATS(5)

- -

NAME

- -

libarchive-formats -— archive formats supported by the libarchive -library

- -

DESCRIPTION

- -

The libarchive(3) library reads -and writes a variety of streaming archive formats. Generally -speaking, all of these archive formats consist of a series -of “entries”. Each entry stores a single file -system object, such as a file, directory, or symbolic -link.

- -

The following -provides a brief description of each format supported by -libarchive, with some information about recognized -extensions or limitations of the current library support. -Note that just because a format is supported by libarchive -does not imply that a program that uses libarchive will -support that format. Applications that use libarchive -specify which formats they wish to support, though many -programs do use libarchive convenience functions to enable -all supported formats.

- -

Tar -Formats
-The libarchive(3) library can read most tar archives. It can -write POSIX-standard “ustar” and “pax -interchange” formats as well as v7 tar format and a -subset of the legacy GNU tar format.

- -

All tar formats -store each entry in one or more 512-byte records. The first -record is used for file metadata, including filename, -timestamp, and mode information, and the file data is stored -in subsequent records. Later variants have extended this by -either appropriating undefined areas of the header record, -extending the header to multiple records, or by storing -special entries that modify the interpretation of subsequent -entries.

- -

gnutar

- -

The -libarchive(3) library can read most GNU-format tar archives. -It currently supports the most popular GNU extensions, -including modern long filename and linkname support, as well -as atime and ctime data. The libarchive library does not -support multi-volume archives, nor the old GNU long filename -format. It can read GNU sparse file entries, including the -new POSIX-based formats.

- -

The -libarchive(3) library can write GNU tar format, including -long filename and linkname support, as well as atime and -ctime data.

- -

pax

- -

The -libarchive(3) library can read and write POSIX-compliant pax -interchange format archives. Pax interchange format archives -are an extension of the older ustar format that adds a -separate entry with additional attributes stored as -key/value pairs immediately before each regular entry. The -presence of these additional entries is the only difference -between pax interchange format and the older ustar format. -The extended attributes are of unlimited length and are -stored as UTF-8 Unicode strings. Keywords defined in the -standard are in all lowercase; vendors are allowed to define -custom keys by preceding them with the vendor name in all -uppercase. When writing pax archives, libarchive uses many -of the SCHILY keys defined by Joerg Schilling’s -“star” archiver and a few LIBARCHIVE keys. The -libarchive library can read most of the SCHILY keys and most -of the GNU keys introduced by GNU tar. It silently ignores -any keywords that it does not understand.

- -

The pax -interchange format converts filenames to Unicode and stores -them using the UTF-8 encoding. Prior to libarchive 3.0, -libarchive erroneously assumed that the system -wide-character routines natively supported Unicode. This -caused it to mis-handle non-ASCII filenames on systems that -did not satisfy this assumption.

- -

restricted pax

- -

The libarchive library can also -write pax archives in which it attempts to suppress the -extended attributes entry whenever possible. The result will -be identical to a ustar archive unless the extended -attributes entry is required to store a long file name, long -linkname, extended ACL, file flags, or if any of the -standard ustar data (user name, group name, UID, GID, etc) -cannot be fully represented in the ustar header. In all -cases, the result can be dearchived by any program that can -read POSIX-compliant pax interchange format archives. -Programs that correctly read ustar format (see below) will -also be able to read this format; any extended attributes -will be extracted as separate files stored in -PaxHeader directories.

- -

ustar

- -

The libarchive -library can both read and write this format. This format has -the following limitations:

- -

- -

Device major and minor numbers -are limited to 21 bits. Nodes with larger numbers will not -be added to the archive.

- -

- -

Path names in the archive are -limited to 255 bytes. (Shorter if there is no / character in -exactly the right place.)

- -

- -

Symbolic links and hard links -are stored in the archive with the name of the referenced -file. This name is limited to 100 bytes.

- -

- -

Extended attributes, file -flags, and other extended security information cannot be -stored.

- -

- -

Archive entries are limited to -8 gigabytes in size.

- -

Note that the pax interchange -format has none of these restrictions. The ustar format is -old and widely supported. It is recommended when -compatibility is the primary concern.

- -

v7

- -

The libarchive -library can read and write the legacy v7 tar format. This -format has the following limitations:

- -

- -

Only regular files, -directories, and symbolic links can be archived. Block and -character device nodes, FIFOs, and sockets cannot be -archived.

- -

- -

Path names in the archive are -limited to 100 bytes.

- -

- -

Symbolic links and hard links -are stored in the archive with the name of the referenced -file. This name is limited to 100 bytes.

- -

- -

User and group information are -stored as numeric IDs; there is no provision for storing -user or group names.

- -

- -

Extended attributes, file -flags, and other extended security information cannot be -stored.

- -

- -

Archive entries are limited to -8 gigabytes in size.

- -

Generally, users should prefer -the ustar format for portability as the v7 tar format is -both less useful and less portable.

- -

The libarchive -library also reads a variety of commonly-used extensions to -the basic tar format. These extensions are recognized -automatically whenever they appear.

- -

Numeric extensions.

- -

The POSIX standards require -fixed-length numeric fields to be written with some -character position reserved for terminators. Libarchive -allows these fields to be written without terminator -characters. This extends the allowable range; in particular, -ustar archives with this extension can support entries up to -64 gigabytes in size. Libarchive also recognizes base-256 -values in most numeric fields. This essentially removes all -limitations on file size, modification time, and device -numbers.

- -

Solaris extensions

- -

Libarchive recognizes ACL and -extended attribute records written by Solaris tar.

- -

The first tar -program appeared in Seventh Edition Unix in 1979. The first -official standard for the tar file format was the -“ustar” (Unix Standard Tar) format defined by -POSIX in 1988. POSIX.1-2001 extended the ustar format to -create the “pax interchange” format.

- -

Cpio -Formats
-The libarchive library can read and write a number of common -cpio variants. A cpio archive stores each entry as a -fixed-size header followed by a variable-length filename and -variable-length data. Unlike the tar format, the cpio format -does only minimal padding of the header or file data. There -are several cpio variants, which differ primarily in how -they store the initial header: some store the values as -octal or hexadecimal numbers in ASCII, others as binary -values of varying byte order and length.

- -

binary

- -

The libarchive -library transparently reads both big-endian and -little-endian variants of the the two binary cpio formats; -the original one from PWB/UNIX, and the later, more widely -used, variant. This format used 32-bit binary values for -file size and mtime, and 16-bit binary values for the other -fields. The formats support only the file types present in -UNIX at the time of their creation. File sizes are limited -to 24 bits in the PWB format, because of the limits of the -file system, and to 31 bits in the newer binary format, -where signed 32 bit longs were used.

- -

odc

- -

This is the -POSIX standardized format, which is officially known as the -“cpio interchange format” or the -“octet-oriented cpio archive format” and -sometimes unofficially referred to as the “old -character format”. This format stores the header -contents as octal values in ASCII. It is standard, portable, -and immune from byte-order confusion. File sizes and mtime -are limited to 33 bits (8GB file size), other fields are -limited to 18 bits.

- -

SVR4/newc

- -

The libarchive library can read -both CRC and non-CRC variants of this format. The SVR4 -format uses eight-digit hexadecimal values for all header -fields. This limits file size to 4GB, and also limits the -mtime and other fields to 32 bits. The SVR4 format can -optionally include a CRC of the file contents, although -libarchive does not currently verify this CRC.

- -

Cpio first -appeared in PWB/UNIX 1.0, which was released within AT&T -in 1977. PWB/UNIX 1.0 formed the basis of System III Unix, -released outside of AT&T in 1981. This makes cpio older -than tar, although cpio was not included in Version 7 -AT&T Unix. As a result, the tar command became much -better known in universities and research groups that used -Version 7. The combination of the find and -cpio utilities provided very precise control over -file selection. Unfortunately, the format has many -limitations that make it unsuitable for widespread use. Only -the POSIX format permits files over 4GB, and its 18-bit -limit for most other fields makes it unsuitable for modern -systems. In addition, cpio formats only store numeric -UID/GID values (not usernames and group names), which can -make it very difficult to correctly transfer archives across -systems with dissimilar user numbering.

- -

Shar -Formats
-A “shell archive” is a shell script that, when -executed on a POSIX-compliant system, will recreate a -collection of file system objects. The libarchive library -can write two different kinds of shar archives:

- -

shar

- -

The traditional -shar format uses a limited set of POSIX commands, including -echo(1), mkdir(1), and sed(1). It is suitable for portably -archiving small collections of plain text files. However, it -is not generally well-suited for large archives (many -implementations of sh(1) have limits on the size of a -script) nor should it be used with non-text files.

- -

shardump

- -

This format is similar to shar -but encodes files using uuencode(1) so that the result will -be a plain text file regardless of the file contents. It -also includes additional shell commands that attempt to -reproduce as many file attributes as possible, including -owner, mode, and flags. The additional commands used to -restore file attributes make shardump archives less portable -than plain shar archives.

- -

ISO9660 -format
-Libarchive can read and extract from files containing -ISO9660-compliant CDROM images. In many cases, this can -remove the need to burn a physical CDROM just in order to -read the files contained in an ISO9660 image. It also avoids -security and complexity issues that come with virtual mounts -and loopback devices. Libarchive supports the most common -Rockridge extensions and has partial support for Joliet -extensions. If both extensions are present, the Joliet -extensions will be used and the Rockridge extensions will be -ignored. In particular, this can create problems with -hardlinks and symlinks, which are supported by Rockridge but -not by Joliet.

- -

Libarchive reads -ISO9660 images using a streaming strategy. This allows it to -read compressed images directly (decompressing on the fly) -and allows it to read images directly from network sockets, -pipes, and other non-seekable data sources. This strategy -works well for optimized ISO9660 images created by many -popular programs. Such programs collect all directory -information at the beginning of the ISO9660 image so it can -be read from a physical disk with a minimum of seeking. -However, not all ISO9660 images can be read in this -fashion.

- -

Libarchive can -also write ISO9660 images. Such images are fully optimized -with the directory information preceding all file data. This -is done by storing all file data to a temporary file while -collecting directory information in memory. When the image -is finished, libarchive writes out the directory structure -followed by the file data. The location used for the -temporary file can be changed by the usual environment -variables.

- -

Zip -format
-Libarchive can read and write zip format archives that have -uncompressed entries and entries compressed with the -“deflate” algorithm. Other zip compression -algorithms are not supported. It can extract jar archives, -archives that use Zip64 extensions and self-extracting zip -archives. Libarchive can use either of two different -strategies for reading Zip archives: a streaming strategy -which is fast and can handle extremely large archives, and a -seeking strategy which can correctly process self-extracting -Zip archives and archives with deleted members or other -in-place modifications.

- -

The streaming -reader processes Zip archives as they are read. It can read -archives of arbitrary size from tape or network sockets, and -can decode Zip archives that have been separately compressed -or encoded. However, self-extracting Zip archives and -archives with certain types of modifications cannot be -correctly handled. Such archives require that the reader -first process the Central Directory, which is ordinarily -located at the end of a Zip archive and is thus inaccessible -to the streaming reader. If the program using libarchive has -enabled seek support, then libarchive will use this to -processes the central directory first.

- -

In particular, -the seeking reader must be used to correctly handle -self-extracting archives. Such archives consist of a program -followed by a regular Zip archive. The streaming reader -cannot parse the initial program portion, but the seeking -reader starts by reading the Central Directory from the end -of the archive. Similarly, Zip archives that have been -modified in-place can have deleted entries or other garbage -data that can only be accurately detected by first reading -the Central Directory.

- -

Archive -(library) file format
-The Unix archive format (commonly created by the ar(1) -archiver) is a general-purpose format which is used almost -exclusively for object files to be read by the link editor -ld(1). The ar format has never been standardised. There are -two common variants: the GNU format derived from SVR4, and -the BSD format, which first appeared in 4.4BSD. The two -differ primarily in their handling of filenames longer than -15 characters: the GNU/SVR4 variant writes a filename table -at the beginning of the archive; the BSD format stores each -long filename in an extension area adjacent to the entry. -Libarchive can read both extensions, including archives that -may include both types of long filenames. Programs using -libarchive can write GNU/SVR4 format if they provide an -entry called // containing a filename table to be -written into the archive before any of the entries. Any -entries whose names are not in the filename table will be -written using BSD-style long filenames. This can cause -problems for programs such as GNU ld that do not support the -BSD-style long filenames.

- -

mtree -
-Libarchive can read and write files in mtree(5) format. This -format is not a true archive format, but rather a textual -description of a file hierarchy in which each line specifies -the name of a file and provides specific metadata about that -file. Libarchive can read all of the keywords supported by -both the NetBSD and FreeBSD versions of mtree(8), although -many of the keywords cannot currently be stored in an -archive_entry object. When writing, libarchive supports use -of the archive_write_set_options(3) interface to specify -which keywords should be included in the output. If -libarchive was compiled with access to suitable -cryptographic libraries (such as the OpenSSL libraries), it -can compute hash entries such as sha512 or md5 -from file data being written to the mtree writer.

- -

When reading an -mtree file, libarchive will locate the corresponding files -on disk using the contents keyword if present or the -regular filename. If it can locate and open the file on -disk, it will use that to fill in any metadata that is -missing from the mtree file and will read the file contents -and return those to the program using libarchive. If it -cannot locate and open the file on disk, libarchive will -return an error for any attempt to read the entry body.

- -

7-Zip -
-Libarchive can read and write 7-Zip format archives. TODO: -Need more information

- -

CAB
-Libarchive can read Microsoft Cabinet ( “CAB”) -format archives. TODO: Need more information.

- -

LHA
-TODO: Information about libarchive’s LHA support

- -

RAR
-Libarchive has limited support for reading RAR format -archives. Currently, libarchive can read RARv3 format -archives which have been either created uncompressed, or -compressed using any of the compression methods supported by -the RARv3 format. Libarchive can also read self-extracting -RAR archives.

- -

Warc
-Libarchive can read and write “web archives”. -TODO: Need more information

- -

XAR
-Libarchive can read and write the XAR format used by many -Apple tools. TODO: Need more information

- -

SEE ALSO

- -

ar(1), cpio(1), mkisofs(1), -shar(1), tar(1), zip(1), zlib(3), cpio(5), mtree(5), -tar(5)

- -

BSD -December 27, 2016 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/libarchive.3.html b/thirdparty/libarchive/doc/html/libarchive.3.html deleted file mode 100644 index f168edf2c..000000000 --- a/thirdparty/libarchive/doc/html/libarchive.3.html +++ /dev/null @@ -1,328 +0,0 @@ - - - - - - - - - - - - - -
- - -

LIBARCHIVE(3) BSD Library Functions Manual -LIBARCHIVE(3)

- -

NAME

- -

libarchive — -functions for reading and writing streaming archives

- -

OVERVIEW

- -

The libarchive library -provides a flexible interface for reading and writing -archives in various formats such as tar and cpio. -libarchive also supports reading and writing archives -compressed using various compression filters such as gzip -and bzip2. The library is inherently stream-oriented; -readers serially iterate through the archive, writers -serially add things to the archive. In particular, note that -there is currently no built-in support for random access nor -for in-place modification.

- -

When reading an -archive, the library automatically detects the format and -the compression. The library currently has read support -for:

- -

- -

old-style tar archives,

- -

- -

most variants of the POSIX -“ustar” format,

- -

- -

the POSIX “pax -interchange” format,

- -

- -

GNU-format tar archives,

- -

- -

most common cpio archive -formats,

- -

- -

7-Zip archives,

- -

- -

ar archives (including GNU/SysV -and BSD extensions),

- -

- -

Microsoft CAB archives,

- -

- -

ISO9660 CD images (including -RockRidge and Joliet extensions),

- -

- -

LHA archives,

- -

- -

mtree file tree -descriptions,

- -

- -

RAR and most RAR5 archives,

- -

- -

WARC archives,

- -

- -

XAR archives,

- -

- -

Zip archives.

- -

The library automatically -detects archives compressed with compress(1), bzip2(1), -grzip(1), gzip(1), lrzip(1), lz4(1), lzip(1), lzop(1), -xz(1), or zstd(1) and decompresses them transparently. -Decompression of some formats requires external decompressor -utilities. It can similarly detect and decode archives -processed with uuencode(1) or which have an rpm(1) -header.

- -

When writing an -archive, you can specify the compression to be used and the -format to use. The library can write

- -

- -

POSIX-standard -“ustar” archives,

- -

- -

POSIX “pax interchange -format” archives,

- -

- -

cpio archives,

- -

- -

7-Zip archives,

- -

- -

ar archives,

- -

- -

two different variants of shar -archives,

- -

- -

ISO9660 CD images,

- -

- -

mtree file tree -descriptions,

- -

- -

XAR archives,

- -

- -

Zip archive.

- -

Pax interchange format is an -extension of the tar archive format that eliminates -essentially all of the limitations of historic tar formats -in a standard fashion that is supported by POSIX-compliant -pax(1) implementations on many systems as well as several -newer implementations of tar(1). Note that the default write -format will suppress the pax extended attributes for most -entries; explicitly requesting pax format will enable those -attributes for all entries.

- -

The read and -write APIs are accessed through the -archive_read_XXX() functions and the -archive_write_XXX() functions, respectively, and -either can be used independently of the other.

- -

The rest of this -manual page provides an overview of the library operation. -More detailed information can be found in the individual -manual pages for each API or utility function.

- -

READING AN ARCHIVE

- -

See archive_read(3).

- -

WRITING AN ARCHIVE

- -

See archive_write(3).

- -

WRITING ENTRIES TO -DISK

- -

The archive_write_disk(3) API -allows you to write archive_entry(3) objects to disk using -the same API used by archive_write(3). The -archive_write_disk(3) API is used internally by -archive_read_extract(); using it directly can provide -greater control over how entries get written to disk. This -API also makes it possible to share code between -archive-to-archive copy and archive-to-disk extraction -operations.

- -

READING ENTRIES FROM -DISK

- -

The archive_read_disk(3) -supports for populating archive_entry(3) objects from -information in the filesystem. This includes the information -accessible from the stat(2) system call as well as ACLs, -extended attributes, and other metadata. The -archive_read_disk(3) API also supports iterating over -directory trees, which allows directories of files to be -read using an API compatible with the archive_read(3) -API.

- -

DESCRIPTION

- -

Detailed descriptions of each -function are provided by the corresponding manual pages.

- -

All of the -functions utilize an opaque struct archive datatype that -provides access to the archive contents.

- -

The struct -archive_entry structure contains a complete description of a -single archive entry. It uses an opaque interface that is -fully documented in archive_entry(3).

- -

Users familiar -with historic formats should be aware that the newer -variants have eliminated most restrictions on the length of -textual fields. Clients should not assume that filenames, -link names, user names, or group names are limited in -length. In particular, pax interchange format can easily -accommodate pathnames in arbitrary character sets that -exceed PATH_MAX.

- -

RETURN VALUES

- -

Most functions return -ARCHIVE_OK (zero) on success, non-zero on error. The -return value indicates the general severity of the error, -ranging from ARCHIVE_WARN, which indicates a minor -problem that should probably be reported to the user, to -ARCHIVE_FATAL, which indicates a serious problem that -will prevent any further operations on this archive. On -error, the archive_errno() function can be used to -retrieve a numeric error code (see errno(2)). The -archive_error_string() returns a textual error -message suitable for display.

- - -

archive_read_new() -and archive_write_new() return pointers to an -allocated and initialized struct archive object.

- - -

archive_read_data() -and archive_write_data() return a count of the number -of bytes actually read or written. A value of zero indicates -the end of the data for this entry. A negative value -indicates an error, in which case the archive_errno() -and archive_error_string() functions can be used to -obtain more information.

- -

ENVIRONMENT

- -

There are character set -conversions within the archive_entry(3) functions that are -impacted by the currently-selected locale.

- -

SEE ALSO

- -

tar(1), archive_entry(3), -archive_read(3), archive_util(3), archive_write(3), -tar(5)

- -

HISTORY

- -

The libarchive library -first appeared in FreeBSD 5.3.

- -

AUTHORS

- -

The libarchive library -was originally written by Tim Kientzle -<kientzle@acm.org>.

- -

BUGS

- -

Some archive formats support -information that is not supported by struct archive_entry. -Such information cannot be fully archived or restored using -this library. This includes, for example, comments, -character sets, or the arbitrary key/value pairs that can -appear in pax interchange format archives.

- -

Conversely, of -course, not all of the information that can be stored in an -struct archive_entry is supported by all formats. For -example, cpio formats do not support nanosecond timestamps; -old tar formats do not support large device numbers.

- -

The ISO9660 -reader cannot yet read all ISO9660 images; it should learn -how to seek.

- -

The AR writer -requires the client program to use two passes, unlike all -other libarchive writers.

- -

BSD -March 18, 2012 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/libarchive_changes.3.html b/thirdparty/libarchive/doc/html/libarchive_changes.3.html deleted file mode 100644 index 472ffd3f6..000000000 --- a/thirdparty/libarchive/doc/html/libarchive_changes.3.html +++ /dev/null @@ -1,464 +0,0 @@ - - - - - - - - - - - - - -
- - -

LIBARCHIVE_CHANGES(3) BSD Library Functions Manual -LIBARCHIVE_CHANGES(3)

- -

NAME

- -

libarchive_changes -— changes in libarchive interface

- -

CHANGES IN LIBARCHIVE -3

- -

This page describes user-visible -changes in libarchive3, and lists public functions and other -symbols changed, deprecated or removed in libarchive3, along -with their replacements if any.

- -

Multiple -Filters
-Libarchive2 permitted a single (input or output) filter -active on an archive. Libarchive3 extends this into a -variable-length stack. Where -archive_write_set_compression_XXX() would replace any -existing filter, archive_write_add_filter_XXX() -extends the write pipeline with another filter.

- -

Character Set -Handling
-Libarchive2 assumed that the local platform uses Unicode as -the native wchar_t encoding, which is true on Windows, -modern Linux, and a few other systems, but is certainly not -universal. As a result, pax format archives were written -incorrectly on some systems, since pax format requires UTF-8 -and libarchive 2 incorrectly assumed that wchar_t strings -can be easily converted to UTF-8.

- -

Libarchive3 uses -the standard iconv library to convert between character sets -and is introducing the notion of a “default character -set for the archive”. To support this, archive_entry -objects can now be bound to a particular archive when they -are created. The automatic character set conversions -performed by archive_entry objects when reading and writing -filenames, usernames, and other strings will now use an -appropriate default character set:

- -

If the -archive_entry object is bound to an archive, it will use the -default character set for that archive.

- -

The platform -default character encoding (as returned by -nl_langinfo(CHARSET)) will be used if nothing -else is specified.

- -

Libarchive3 also -introduces charset options to many of the archive readers -and writers to control the character set that will be used -for filenames written in those archives. When possible, this -will be set automatically based on information in the -archive itself. Combining this with the notion of a default -character set for the archive should allow you to configure -libarchive to read archives from other platforms and have -the filenames and other information transparently converted -to the character encoding suitable for your application.

- -

Prototype -Changes
-These changes break binary compatibility; libarchive3 has a -new shared library version to reflect these changes. The -library now uses portable wide types such as int64_t instead -of less-portable types such as off_t, gid_t, uid_t, and -ino_t.

- -

There are a few -cases where these changes will affect your source code:

- -

- -

In some cases, -libarchive’s wider types will introduce the -possibility of truncation: for example, on a system with a -16-bit uid_t, you risk having uid 65536 be truncated to uid -0, which can cause serious security problems.

- -

- -

Typedef function pointer types -will be incompatible. For example, if you define custom skip -callbacks, you may have to use code similar to the following -if you want to support building against libarchive2 and -libarchive3:

- -

#if -ARCHIVE_VERSION_NUMBER < 3000000
-typedef off_t myoff_t;
-#else
-typedef int64_t myoff_t;
-#endif

- -

myoff_t
-my_skip_function(struct archive *a, void *v, myoff_t o)
-{
-... implementation ...
-}

- -

Affected -functions:

- -


-archive_entry_gid
(), archive_entry_set_gid() -
-•
-archive_entry_uid
(), archive_entry_set_uid() -
-•
-archive_entry_ino
(), archive_entry_set_ino() -
-•
-archive_read_data_block
(), -archive_write_data_block()
-•
-archive_read_disk_gname
(), -archive_read_disk_uname()
-•
-archive_read_disk_set_gname_lookup
(), -archive_read_disk_set_group_lookup(), -archive_read_disk_set_uname_lookup(), -archive_read_disk_set_user_lookup()
-•

- - -

archive_skip_callback()

- -


-archive_read_extract_set_skip_file
(), -archive_write_disk_set_skip_file(), -archive_write_set_skip_file()
-•
-archive_write_disk_set_group_lookup
(), -archive_write_disk_set_user_lookup()

- -

Where these -functions or their arguments took or returned gid_t, ino_t, -off_t, or uid_t they now take or return int64_t or -equivalent.

- -

Deprecated -Symbols
-Symbols deprecated in libarchive3 will be removed in -libarchive4. These symbols, along with their replacements if -any, are listed below:

- - -

archive_position_compressed(), -archive_position_uncompressed()

- - -

archive_filter_bytes()

- - -

archive_compression()

- - -

archive_filter_code()

- - -

archive_compression_name()

- - -

archive_filter_name()

- -

archive_read_finish(), -archive_write_finish()

- -

archive_read_free(), -archive_write_free()

- - -

archive_read_open_file(), -archive_write_open_file()

- - -

archive_read_open_filename(), -archive_write_open_filename()

- - -

archive_read_support_compression_all()

- - -

archive_read_support_filter_all()

- - -

archive_read_support_compression_bzip2()

- - -

archive_read_support_filter_bzip2()

- - -

archive_read_support_compression_compress()

- - -

archive_read_support_filter_compress()

- - -

archive_read_support_compression_gzip()

- - -

archive_read_support_filter_gzip()

- - -

archive_read_support_compression_lzip()

- - -

archive_read_support_filter_lzip()

- - -

archive_read_support_compression_lzma()

- - -

archive_read_support_filter_lzma()

- - -

archive_read_support_compression_none()

- - -

archive_read_support_filter_none()

- - -

archive_read_support_compression_program()

- - -

archive_read_support_filter_program()

- - -

archive_read_support_compression_program_signature()

- - -

archive_read_support_filter_program_signature()

- - -

archive_read_support_compression_rpm()

- - -

archive_read_support_filter_rpm()

- - -

archive_read_support_compression_uu()

- - -

archive_read_support_filter_uu()

- - -

archive_read_support_compression_xz()

- - -

archive_read_support_filter_xz()

- - -

archive_write_set_compression_bzip2()

- - -

archive_write_add_filter_bzip2()

- - -

archive_write_set_compression_compress()

- - -

archive_write_add_filter_compress()

- - -

archive_write_set_compression_gzip()

- - -

archive_write_add_filter_gzip()

- - -

archive_write_set_compression_lzip()

- - -

archive_write_add_filter_lzip()

- - -

archive_write_set_compression_lzma()

- - -

archive_write_add_filter_lzma()

- - -

archive_write_set_compression_none()

- - -

archive_write_add_filter_none()

- - -

archive_write_set_compression_program()

- - -

archive_write_add_filter_program()

- - -

archive_write_set_compression_filter()

- - -

archive_write_add_filter_filter()

- -

Removed -Symbols
-These symbols, listed below along with their replacements if -any, were deprecated in libarchive2, and are not part of -libarchive3.

- - -

archive_api_feature()

- - -

archive_version_number()

- - -

archive_api_version()

- - -

archive_version_number()

- -

archive_version()

- - -

archive_version_string()

- - -

archive_version_stamp()

- - -

archive_version_number()

- - -

archive_read_set_filter_options()

- - -

archive_read_set_options() -or archive_read_set_filter_option()

- - -

archive_read_set_format_options()

- - -

archive_read_set_options() -or archive_read_set_format_option()

- - -

archive_write_set_filter_options()

- - -

archive_write_set_options() -or archive_write_set_filter_option()

- - -

archive_write_set_format_options()

- - -

archive_write_set_options() -or archive_write_set_format_option()

- -

ARCHIVE_API_FEATURE

- -

ARCHIVE_VERSION_NUMBER

- -

ARCHIVE_API_VERSION

- -

ARCHIVE_VERSION_NUMBER

- -

ARCHIVE_VERSION_STAMP

- -

ARCHIVE_VERSION_NUMBER

- -

ARCHIVE_LIBRARY_VERSION

- -

ARCHIVE_VERSION_STRING

- -

ARCHIVE_COMPRESSION_NONE

- -

ARCHIVE_FILTER_NONE

- -

ARCHIVE_COMPRESSION_GZIP

- -

ARCHIVE_FILTER_GZIP

- -

ARCHIVE_COMPRESSION_BZIP2

- -

ARCHIVE_FILTER_BZIP2

- - -

ARCHIVE_COMPRESSION_COMPRESS

- -

ARCHIVE_FILTER_COMPRESS

- -

ARCHIVE_COMPRESSION_PROGRAM

- -

ARCHIVE_FILTER_PROGRAM

- -

ARCHIVE_COMPRESSION_LZMA

- -

ARCHIVE_FILTER_LZMA

- -

ARCHIVE_COMPRESSION_XZ

- -

ARCHIVE_FILTER_XZ

- -

ARCHIVE_COMPRESSION_UU

- -

ARCHIVE_FILTER_UU

- -

ARCHIVE_COMPRESSION_RPM

- -

ARCHIVE_FILTER_RPM

- -

ARCHIVE_COMPRESSION_LZIP

- -

ARCHIVE_FILTER_LZIP

- -

ARCHIVE_BYTES_PER_RECORD

- -

512

- - -

ARCHIVE_DEFAULT_BYTES_PER_BLOCK

- -

10240

- -

SEE ALSO

- -

archive_read(3), -archive_read_filter(3), archive_read_format(3), -archive_read_set_options(3), archive_util(3), -archive_write(3), archive_write_filter(3), -archive_write_format(3), archive_write_set_options(3), -libarchive(3)

- -

BSD -December 23, 2011 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/libarchive_internals.3.html b/thirdparty/libarchive/doc/html/libarchive_internals.3.html deleted file mode 100644 index ddec98736..000000000 --- a/thirdparty/libarchive/doc/html/libarchive_internals.3.html +++ /dev/null @@ -1,374 +0,0 @@ - - - - - - - - - - - - - -
- - -

LIBARCHIVE_INTERNALS(3) BSD Library Functions Manual -LIBARCHIVE_INTERNALS(3)

- -

NAME

- -

libarchive_internals -— description of libarchive internal interfaces

- -

OVERVIEW

- -

The libarchive library -provides a flexible interface for reading and writing -streaming archive files such as tar and cpio. Internally, it -follows a modular layered design that should make it easy to -add new archive and compression formats.

- -

GENERAL ARCHITECTURE

- -

Externally, libarchive exposes -most operations through an opaque, object-style interface. -The archive_entry(3) objects store information about a -single filesystem object. The rest of the library provides -facilities to write archive_entry(3) objects to archive -files, read them from archive files, and write them to disk. -(There are plans to add a facility to read archive_entry(3) -objects from disk as well.)

- -

The read and -write APIs each have four layers: a public API layer, a -format layer that understands the archive file format, a -compression layer, and an I/O layer. The I/O layer is -completely exposed to clients who can replace it entirely -with their own functions.

- -

In order to -provide as much consistency as possible for clients, some -public functions are virtualized. Eventually, it should be -possible for clients to open an archive or disk writer, and -then use a single set of code to select and write entries, -regardless of the target.

- -

READ ARCHITECTURE

- -

From the outside, clients use -the archive_read(3) API to manipulate an archive -object to read entries and bodies from an archive stream. -Internally, the archive object is cast to an -archive_read object, which holds all read-specific -data. The API has four layers: The lowest layer is the I/O -layer. This layer can be overridden by clients, but most -clients use the packaged I/O callbacks provided, for -example, by archive_read_open_memory(3), and -archive_read_open_fd(3). The compression layer calls the I/O -layer to read bytes and decompresses them for the format -layer. The format layer unpacks a stream of uncompressed -bytes and creates archive_entry objects from the -incoming data. The API layer tracks overall state (for -example, it prevents clients from reading data before -reading a header) and invokes the format and compression -layer operations through registered function pointers. In -particular, the API layer drives the format-detection -process: When opening the archive, it reads an initial block -of data and offers it to each registered compression -handler. The one with the highest bid is initialized with -the first block. Similarly, the format handlers are polled -to see which handler is the best for each archive. (Prior to -2.4.0, the format bidders were invoked for each entry, but -this design hindered error recovery.)

- -

I/O Layer and -Client Callbacks
-The read API goes to some lengths to be nice to clients. As -a result, there are few restrictions on the behavior of the -client callbacks.

- -

The client read -callback is expected to provide a block of data on each -call. A zero-length return does indicate end of file, but -otherwise blocks may be as small as one byte or as large as -the entire file. In particular, blocks may be of different -sizes.

- -

The client skip -callback returns the number of bytes actually skipped, which -may be much smaller than the skip requested. The only -requirement is that the skip not be larger. In particular, -clients are allowed to return zero for any skip that they -don’t want to handle. The skip callback must never be -invoked with a negative value.

- -

Keep in mind -that not all clients are reading from disk: clients reading -from networks may provide different-sized blocks on every -request and cannot skip at all; advanced clients may use -mmap(2) to read the entire file into memory at once and -return the entire file to libarchive as a single block; -other clients may begin asynchronous I/O operations for the -next block on each request.

- - -

Decompresssion -Layer
-The decompression layer not only handles decompression, it -also buffers data so that the format handlers see a much -nicer I/O model. The decompression API is a two stage -peek/consume model. A read_ahead request specifies a minimum -read amount; the decompression layer must provide a pointer -to at least that much data. If more data is immediately -available, it should return more: the format layer handles -bulk data reads by asking for a minimum of one byte and then -copying as much data as is available.

- -

A subsequent -call to the consume() function advances the read -pointer. Note that data returned from a read_ahead() -call is guaranteed to remain in place until the next call to -read_ahead(). Intervening calls to consume() -should not cause the data to move.

- -

Skip requests -must always be handled exactly. Decompression handlers that -cannot seek forward should not register a skip handler; the -API layer fills in a generic skip handler that reads and -discards data.

- -

A decompression -handler has a specific lifecycle:

- -

Registration/Configuration

- -

When the client invokes the -public support function, the decompression handler invokes -the internal __archive_read_register_compression() -function to provide bid and initialization functions. This -function returns NULL on error or else a pointer to a -struct decompressor_t. This structure contains a -void * config slot that can be used for storing any -customization information.

- -

Bid

- -

The bid -function is invoked with a pointer and size of a block of -data. The decompressor can access its config data through -the decompressor element of the archive_read -object. The bid function is otherwise stateless. In -particular, it must not perform any I/O operations.

- -

The value -returned by the bid function indicates its suitability for -handling this data stream. A bid of zero will ensure that -this decompressor is never invoked. Return zero if magic -number checks fail. Otherwise, your initial implementation -should return the number of bits actually checked. For -example, if you verify two full bytes and three bits of -another byte, bid 19. Note that the initial block may be -very short; be careful to only inspect the data you are -given. (The current decompressors require two bytes for -correct bidding.)

- -

Initialize

- -

The winning bidder will have -its init function called. This function should initialize -the remaining slots of the struct decompressor_t -object pointed to by the decompressor element of the -archive_read object. In particular, it should -allocate any working data it needs in the data slot -of that structure. The init function is called with the -block of data that was used for tasting. At this point, the -decompressor is responsible for all I/O requests to the -client callbacks. The decompressor is free to read more data -as and when necessary.

- -

Satisfy I/O requests

- -

The format handler will invoke -the read_ahead, consume, and skip -functions as needed.

- -

Finish

- -

The finish -method is called only once when the archive is closed. It -should release anything stored in the data and -config slots of the decompressor object. It -should not invoke the client close callback.

- -

Format -Layer
-The read formats have a similar lifecycle to the -decompression handlers:

- -

Registration

- -

Allocate your private data and -initialize your pointers.

- -

Bid

- -

Formats bid by -invoking the read_ahead() decompression method but -not calling the consume() method. This allows each -bidder to look ahead in the input stream. Bidders should not -look further ahead than necessary, as long look aheads put -pressure on the decompression layer to buffer lots of data. -Most formats only require a few hundred bytes of look ahead; -look aheads of a few kilobytes are reasonable. (The ISO9660 -reader sometimes looks ahead by 48k, which should be -considered an upper limit.)

- -

Read header

- -

The header read is usually the -most complex part of any format. There are a few strategies -worth mentioning: For formats such as tar or cpio, reading -and parsing the header is straightforward since headers -alternate with data. For formats that store all header data -at the beginning of the file, the first header read request -may have to read all headers into memory and store that -data, sorted by the location of the file data. Subsequent -header read requests will skip forward to the beginning of -the file data and return the corresponding header.

- -

Read Data

- -

The read data interface -supports sparse files; this requires that each call return a -block of data specifying the file offset and size. This may -require you to carefully track the location so that you can -return accurate file offsets for each read. Remember that -the decompressor will return as much data as it has. -Generally, you will want to request one byte, examine the -return value to see how much data is available, and possibly -trim that to the amount you can use. You should invoke -consume for each block just before you return it.

- -

Skip All Data

- -

The skip data call should skip -over all file data and trailing padding. This is called -automatically by the API layer just before each header read. -It is also called in response to the client calling the -public data_skip() function.

- -

Cleanup

- -

On cleanup, the format should -release all of its allocated memory.

- -

API Layer -
-XXX to do XXX

- -

WRITE ARCHITECTURE

- -

The write API has a similar set -of four layers: an API layer, a format layer, a compression -layer, and an I/O layer. The registration here is much -simpler because only one format and one compression can be -registered at a time.

- -

I/O Layer and -Client Callbacks
-XXX To be written XXX

- -

Compression -Layer
-XXX To be written XXX

- -

Format -Layer
-XXX To be written XXX

- -

API Layer -
-XXX To be written XXX

- -

WRITE_DISK -ARCHITECTURE

- -

The write_disk API is intended -to look just like the write API to clients. Since it does -not handle multiple formats or compression, it is not -layered internally.

- -

GENERAL SERVICES

- -

The archive_read, -archive_write, and archive_write_disk objects -all contain an initial archive object which provides -common support for a set of standard services. (Recall that -ANSI/ISO C90 guarantees that you can cast freely between a -pointer to a structure and a pointer to the first element of -that structure.) The archive object has a magic value -that indicates which API this object is associated with, -slots for storing error information, and function pointers -for virtualized API functions.

- -

MISCELLANEOUS NOTES

- -

Connecting existing archiving -libraries into libarchive is generally quite difficult. In -particular, many existing libraries strongly assume that you -are reading from a file; they seek forwards and backwards as -necessary to locate various pieces of information. In -contrast, libarchive never seeks backwards in its input, -which sometimes requires very different approaches.

- -

For example, -libarchive’s ISO9660 support operates very differently -from most ISO9660 readers. The libarchive support utilizes a -work-queue design that keeps a list of known entries sorted -by their location in the input. Whenever libarchive’s -ISO9660 implementation is asked for the next header, checks -this list to find the next item on the disk. Directories are -parsed when they are encountered and new items are added to -the list. This design relies heavily on the ISO9660 image -being optimized so that directories always occur earlier on -the disk than the files they describe.

- -

Depending on the -specific format, such approaches may not be possible. The -ZIP format specification, for example, allows archivers to -store key information only at the end of the file. In -theory, it is possible to create ZIP archives that cannot be -read without seeking. Fortunately, such archives are very -rare, and libarchive can read most ZIP archives, though it -cannot always extract as much information as a dedicated ZIP -program.

- -

SEE ALSO

- -

archive_entry(3), -archive_read(3), archive_write(3), archive_write_disk(3), -libarchive(3)

- -

HISTORY

- -

The libarchive library -first appeared in FreeBSD 5.3.

- -

AUTHORS

- -

The libarchive library -was written by Tim Kientzle <kientzle@acm.org>.

- -

BSD -January 26, 2011 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/mtree.5.html b/thirdparty/libarchive/doc/html/mtree.5.html deleted file mode 100644 index 3b181c802..000000000 --- a/thirdparty/libarchive/doc/html/mtree.5.html +++ /dev/null @@ -1,378 +0,0 @@ - - - - - - - - - - - - - -
- - -

MTREE(5) BSD File Formats Manual MTREE(5)

- -

NAME

- -

mtree — format of -mtree dir hierarchy files

- -

DESCRIPTION

- -

The mtree format is a -textual format that describes a collection of filesystem -objects. Such files are typically used to create or verify -directory hierarchies.

- -

General -Format
-An mtree file consists of a series of lines, each -providing information about a single filesystem object. -Leading whitespace is always ignored.

- -

When encoding -file or pathnames, any backslash character or character -outside of the 95 printable ASCII characters must be encoded -as a backslash followed by three octal digits. When reading -mtree files, any appearance of a backslash followed by three -octal digits should be converted into the corresponding -character.

- -

Each line is -interpreted independently as one of the following types:

- -

Blank

- -

Blank lines are -ignored.

- -

Comment

- -

Lines beginning -with # are ignored.

- -

Special

- -

Lines beginning -with / are special commands that influence the -interpretation of later lines.

- -

Relative

- -

If the first -whitespace-delimited word has no / characters, it is -the name of a file in the current directory. Any relative -entry that describes a directory changes the current -directory.

- -

dot-dot

- -

As a special -case, a relative entry with the filename .. changes -the current directory to the parent directory. Options on -dot-dot entries are always ignored.

- -

Full

- -

If the first -whitespace-delimited word has a / character after the -first character, it is the pathname of a file relative to -the starting directory. There can be multiple full entries -describing the same file.

- -

Some tools that -process mtree files may require that multiple lines -describing the same file occur consecutively. It is not -permitted for the same file to be mentioned using both a -relative and a full file specification.

- -

Special -commands
-Two special commands are currently defined:

- -

/set

- -

This command -defines default values for one or more keywords. It is -followed on the same line by one or more -whitespace-separated keyword definitions. These definitions -apply to all following files that do not specify a value for -that keyword.

- -

/unset

- -

This command -removes any default value set by a previous /set -command. It is followed on the same line by one or more -keywords separated by whitespace.

- -

Keywords -
-After the filename, a full or relative entry consists of -zero or more whitespace-separated keyword definitions. Each -such definition consists of a key from the following list -immediately followed by an ’=’ sign and a value. -Software programs reading mtree files should warn about -unrecognized keywords.

- -

Currently -supported keywords are as follows:

- -

cksum

- -

The checksum of -the file using the default algorithm specified by the -cksum(1) utility.

- -

device

- -

The device -number for block or char file types. The value -must be one of the following forms:

- - -

format,major,minor[ -
-,subunit]

- -

A device with major, -minor and optional subunit fields. Their -meaning is specified by the operating’s system -format. See below for valid formats.

- -

number

- -

Opaque number (as stored on the -file system).

- -

The following -values for format are recognized: native, -386bsd, 4bsd, bsdos, freebsd, -hpux, isc, linux, netbsd, -osf1, sco, solaris, sunos, -svr3, svr4, and ultrix.

- -

See mknod(8) -for more details.

- -

contents

- -

The full -pathname of a file that holds the contents of this file.

- -

flags

- -

The file flags -as a symbolic name. See chflags(1) for information on these -names. If no flags are to be set the string -“none” may be used to override the current -default.

- -

gid

- -

The file group -as a numeric value.

- -

gname

- -

The file group -as a symbolic name.

- -

ignore

- -

Ignore any file -hierarchy below this file.

- -

inode

- -

The inode -number.

- -

link

- -

The target of -the symbolic link when type=link.

- -

md5

- -

The MD5 message -digest of the file.

- -

md5digest

- -

A synonym for -md5.

- -

mode

- -

The current -file’s permissions as a numeric (octal) or symbolic -value.

- -

nlink

- -

The number of -hard links the file is expected to have.

- -

nochange

- -

Make sure this -file or directory exists but otherwise ignore all -attributes.

- -

optional

- -

The file is -optional; do not complain about the file if it is not in the -file hierarchy.

- -

resdevice

- -

The -“resident” device number of the file, e.g. the -ID of the device that contains the file. Its format is the -same as the one for device.

- -

ripemd160digest

- -

The RIPEMD160 message digest of -the file.

- -

rmd160

- -

A synonym for -ripemd160digest.

- -

rmd160digest

- -

A synonym for -ripemd160digest.

- -

sha1

- -

The FIPS 160-1 -(“SHA-1”) message digest of the file.

- -

sha1digest

- -

A synonym for -sha1.

- -

sha256

- -

The FIPS 180-2 -(“SHA-256”) message digest of the file.

- -

sha256digest

- -

A synonym for -sha256.

- -

sha384

- -

The FIPS 180-2 -(“SHA-384”) message digest of the file.

- -

sha384digest

- -

A synonym for -sha384.

- -

sha512

- -

The FIPS 180-2 -(“SHA-512”) message digest of the file.

- -

sha512digest

- -

A synonym for -sha512.

- -

size

- -

The size, in -bytes, of the file.

- -

time

- -

The last -modification time of the file.

- -

type

- -

The type of the -file; may be set to any one of the following:

- -

block

- -

block special -device

- -

char

- -

character -special device

- -

dir

- -

directory

- -

fifo

- -

fifo

- -

file

- -

regular -file

- -

link

- -

symbolic -link

- -

socket

- -

socket

- -

uid

- -

The file owner -as a numeric value.

- -

uname

- -

The file owner -as a symbolic name.

- -

SEE ALSO

- -

cksum(1), find(1), mtree(8)

- -

HISTORY

- -

The mtree utility -appeared in 4.3BSD-Reno. The MD5 digest capability was added -in FreeBSD 2.1, in response to the widespread use of -programs which can spoof cksum(1). The SHA-1 and RIPEMD160 -digests were added in FreeBSD 4.0, as new attacks have -demonstrated weaknesses in MD5. The SHA-256 digest was added -in FreeBSD 6.0. Support for file flags was added in -FreeBSD 4.0, and mostly comes from NetBSD. The -“full” entry format was added by NetBSD.

- -

BSD -September 4, 2013 BSD

-
- - diff --git a/thirdparty/libarchive/doc/html/tar.5.html b/thirdparty/libarchive/doc/html/tar.5.html deleted file mode 100644 index d67128e74..000000000 --- a/thirdparty/libarchive/doc/html/tar.5.html +++ /dev/null @@ -1,1547 +0,0 @@ - - - - - - - - - - - - - -
- - -

TAR(5) BSD File Formats Manual TAR(5)

- -

NAME

- -

tar — format of -tape archive files

- -

DESCRIPTION

- -

The tar archive format -collects any number of files, directories, and other file -system objects (symbolic links, device nodes, etc.) into a -single stream of bytes. The format was originally designed -to be used with tape drives that operate with fixed-size -blocks, but is widely used as a general packaging -mechanism.

- -

General -Format
-A tar archive consists of a series of 512-byte -records. Each file system object requires a header record -which stores basic metadata (pathname, owner, permissions, -etc.) and zero or more records containing any file data. The -end of the archive is indicated by two records consisting -entirely of zero bytes.

- -

For -compatibility with tape drives that use fixed block sizes, -programs that read or write tar files always read or write a -fixed number of records with each I/O operation. These -“blocks” are always a multiple of the record -size. The maximum block size supported by early -implementations was 10240 bytes or 20 records. This is still -the default for most implementations although block sizes of -1MiB (2048 records) or larger are commonly used with modern -high-speed tape drives. (Note: the terms “block” -and “record” here are not entirely standard; -this document follows the convention established by John -Gilmore in documenting pdtar.)

- -

Old-Style -Archive Format
-The original tar archive format has been extended many times -to include additional information that various implementors -found necessary. This section describes the variant -implemented by the tar command included in Version 7 -AT&T UNIX, which seems to be the earliest widely-used -version of the tar program.

- -

The header -record for an old-style tar archive consists of the -following:

- -

struct -header_old_tar {

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -

char name[100];

-
- - -

char mode[8];

-
- - -

char uid[8];

-
- - -

char gid[8];

-
- - -

char size[12];

-
- - -

char mtime[12];

-
- - -

char checksum[8];

-
- - -

char linkflag[1];

-
- - -

char linkname[100];

-
- - -

char pad[255];

-
- -

};

- -

All unused bytes in the header -record are filled with nulls.

- -

name

- -

Pathname, -stored as a null-terminated string. Early tar -implementations only stored regular files (including -hardlinks to those files). One common early convention used -a trailing "/" character to indicate a directory -name, allowing directory permissions and owner information -to be archived and restored.

- -

mode

- -

File mode, -stored as an octal number in ASCII.

- -

uid, gid

- -

User id and group id of owner, -as octal numbers in ASCII.

- -

size

- -

Size of file, -as octal number in ASCII. For regular files only, this -indicates the amount of data that follows the header. In -particular, this field was ignored by early tar -implementations when extracting hardlinks. Modern writers -should always store a zero length for hardlink entries.

- -

mtime

- -

Modification -time of file, as an octal number in ASCII. This indicates -the number of seconds since the start of the epoch, 00:00:00 -UTC January 1, 1970. Note that negative values should be -avoided here, as they are handled inconsistently.

- -

checksum

- -

Header checksum, stored as an -octal number in ASCII. To compute the checksum, set the -checksum field to all spaces, then sum all bytes in the -header using unsigned arithmetic. This field should be -stored as six octal digits followed by a null and a space -character. Note that many early implementations of tar used -signed arithmetic for the checksum field, which can cause -interoperability problems when transferring archives between -systems. Modern robust readers compute the checksum both -ways and accept the header if either computation -matches.

- -

linkflag, -linkname

- -

In order to preserve hardlinks -and conserve tape, a file with multiple links is only -written to the archive the first time it is encountered. The -next time it is encountered, the linkflag is set to -an ASCII ’1’ and the linkname field holds -the first name under which this file appears. (Note that -regular files have a null value in the linkflag -field.)

- -

Early tar -implementations varied in how they terminated these fields. -The tar command in Version 7 AT&T UNIX used the -following conventions (this is also documented in early BSD -manpages): the pathname must be null-terminated; the mode, -uid, and gid fields must end in a space and a null byte; the -size and mtime fields must end in a space; the checksum is -terminated by a null and a space. Early implementations -filled the numeric fields with leading spaces. This seems to -have been common practice until the IEEE Std 1003.1-1988 -(“POSIX.1”) standard was released. For best -portability, modern implementations should fill the numeric -fields with leading zeros.

- -

Pre-POSIX -Archives
-An early draft of IEEE Std 1003.1-1988 -(“POSIX.1”) served as the basis for John -Gilmore’s pdtar program and many system -implementations from the late 1980s and early 1990s. These -archives generally follow the POSIX ustar format described -below with the following variations:

- -

- -

The magic value consists of the -five characters “ustar” followed by a space. The -version field contains a space character followed by a -null.

- -

- -

The numeric fields are -generally filled with leading spaces (not leading zeros as -recommended in the final standard).

- -

- -

The prefix field is often not -used, limiting pathnames to the 100 characters of old-style -archives.

- -

POSIX ustar -Archives
-IEEE Std 1003.1-1988 (“POSIX.1”) defined a -standard tar file format to be read and written by compliant -implementations of tar(1). This format is often called the -“ustar” format, after the magic value used in -the header. (The name is an acronym for “Unix Standard -TAR”.) It extends the historic format with new -fields:

- -

struct -header_posix_ustar {

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -

char name[100];

-
- - -

char mode[8];

-
- - -

char uid[8];

-
- - -

char gid[8];

-
- - -

char size[12];

-
- - -

char mtime[12];

-
- - -

char checksum[8];

-
- - -

char typeflag[1];

-
- - -

char linkname[100];

-
- - -

char magic[6];

-
- - -

char version[2];

-
- - -

char uname[32];

-
- - -

char gname[32];

-
- - -

char devmajor[8];

-
- - -

char devminor[8];

-
- - -

char prefix[155];

-
- - -

char pad[12];

-
- -

};

- -

typeflag

- -

Type of entry. POSIX extended -the earlier linkflag field with several new type -values:

- -

“0”

- -

Regular file. -NUL should be treated as a synonym, for compatibility -purposes.

- -

“1”

- -

Hard link.

- -

“2”

- -

Symbolic -link.

- -

“3”

- -

Character -device node.

- -

“4”

- -

Block device -node.

- -

“5”

- -

Directory.

- -

“6”

- -

FIFO node.

- -

“7”

- -

Reserved.

- -

Other

- -

A -POSIX-compliant implementation must treat any unrecognized -typeflag value as a regular file. In particular, writers -should ensure that all entries have a valid filename so that -they can be restored by readers that do not support the -corresponding extension. Uppercase letters "A" -through "Z" are reserved for custom extensions. -Note that sockets and whiteout entries are not -archivable.

- -

It is worth noting that the -size field, in particular, has different meanings -depending on the type. For regular files, of course, it -indicates the amount of data following the header. For -directories, it may be used to indicate the total size of -all files in the directory, for use by operating systems -that pre-allocate directory space. For all other types, it -should be set to zero by writers and ignored by readers.

- -

magic

- -

Contains the -magic value “ustar” followed by a NUL byte to -indicate that this is a POSIX standard archive. Full -compliance requires the uname and gname fields be properly -set.

- -

version

- -

Version. This should be -“00” (two copies of the ASCII digit zero) for -POSIX standard archives.

- -

uname, gname

- -

User and group names, as -null-terminated ASCII strings. These should be used in -preference to the uid/gid values when they are set and the -corresponding names exist on the system.

- -

devmajor, -devminor

- -

Major and minor numbers for -character device or block device entry.

- -

name, prefix

- -

If the pathname is too long to -fit in the 100 bytes provided by the standard format, it can -be split at any / character with the first portion -going into the prefix field. If the prefix field is not -empty, the reader will prepend the prefix value and a -/ character to the regular name field to obtain the -full pathname. The standard does not require a trailing -/ character on directory names, though most -implementations still include this for compatibility -reasons.

- -

Note that all -unused bytes must be set to NUL.

- -

Field -termination is specified slightly differently by POSIX than -by previous implementations. The magic, uname, -and gname fields must have a trailing NUL. The -pathname, linkname, and prefix fields -must have a trailing NUL unless they fill the entire field. -(In particular, it is possible to store a 256-character -pathname if it happens to have a / as the 156th -character.) POSIX requires numeric fields to be zero-padded -in the front, and requires them to be terminated with either -space or NUL characters.

- -

Currently, most -tar implementations comply with the ustar format, -occasionally extending it by adding new fields to the blank -area at the end of the header record.

- -

Numeric -Extensions
-There have been several attempts to extend the range of -sizes or times supported by modifying how numbers are stored -in the header.

- -

One obvious -extension to increase the size of files is to eliminate the -terminating characters from the various numeric fields. For -example, the standard only allows the size field to contain -11 octal digits, reserving the twelfth byte for a trailing -NUL character. Allowing 12 octal digits allows file sizes up -to 64 GB.

- -

Another -extension, utilized by GNU tar, star, and other newer -tar implementations, permits binary numbers in the -standard numeric fields. This is flagged by setting the high -bit of the first byte. The remainder of the field is treated -as a signed twos-complement value. This permits 95-bit -values for the length and time fields and 63-bit values for -the uid, gid, and device numbers. In particular, this -provides a consistent way to handle negative time values. -GNU tar supports this extension for the length, mtime, -ctime, and atime fields. Joerg Schilling’s star -program and the libarchive library support this extension -for all numeric fields. Note that this extension is largely -obsoleted by the extended attribute record provided by the -pax interchange format.

- -

Another early -GNU extension allowed base-64 values rather than octal. This -extension was short-lived and is no longer supported by any -implementation.

- -

Pax -Interchange Format
-There are many attributes that cannot be portably stored in -a POSIX ustar archive. IEEE Std 1003.1-2001 -(“POSIX.1”) defined a “pax interchange -format” that uses two new types of entries to hold -text-formatted metadata that applies to following entries. -Note that a pax interchange format archive is a ustar -archive in every respect. The new data is stored in -ustar-compatible archive entries that use the -“x” or “g” typeflag. In particular, -older implementations that do not fully support these -extensions will extract the metadata into regular files, -where the metadata can be examined as necessary.

- -

An entry in a -pax interchange format archive consists of one or two -standard ustar entries, each with its own header and data. -The first optional entry stores the extended attributes for -the following entry. This optional first entry has an -"x" typeflag and a size field that indicates the -total size of the extended attributes. The extended -attributes themselves are stored as a series of text-format -lines encoded in the portable UTF-8 encoding. Each line -consists of a decimal number, a space, a key string, an -equals sign, a value string, and a new line. The decimal -number indicates the length of the entire line, including -the initial length field and the trailing newline. An -example of such a field is:

- -

25 ctime=1084839148.1212\n

- -

Keys in all lowercase are -standard keys. Vendors can add their own keys by prefixing -them with an all uppercase vendor name and a period. Note -that, unlike the historic header, numeric values are stored -using decimal, not octal. A description of some common keys -follows:

- -

atime, ctime, -mtime

- -

File access, inode change, and -modification times. These fields can be negative or include -a decimal point and a fractional value.

- -

hdrcharset

- -

The character set used by the -pax extension values. By default, all textual values in the -pax extended attributes are assumed to be in UTF-8, -including pathnames, user names, and group names. In some -cases, it is not possible to translate local conventions -into UTF-8. If this key is present and the value is the -six-character ASCII string “BINARY”, then all -textual values are assumed to be in a platform-dependent -multi-byte encoding. Note that there are only two valid -values for this key: “BINARY” or -“ISO-IR 10646 2000 UTF-8”. No -other values are permitted by the standard, and the latter -value should generally not be used as it is the default when -this key is not specified. In particular, this flag should -not be used as a general mechanism to allow filenames to be -stored in arbitrary encodings.

- -

uname, uid, -gname, gid

- -

User name, group name, and -numeric UID and GID values. The user name and group name -stored here are encoded in UTF8 and can thus include -non-ASCII characters. The UID and GID fields can be of -arbitrary length.

- -

linkpath

- -

The full path of the linked-to -file. Note that this is encoded in UTF8 and can thus include -non-ASCII characters.

- -

path

- -

The full -pathname of the entry. Note that this is encoded in UTF8 and -can thus include non-ASCII characters.

- -

realtime.*, -security.*

- -

These keys are reserved and may -be used for future standardization.

- -

size

- -

The size of the -file. Note that there is no length limit on this field, -allowing conforming archives to store files much larger than -the historic 8GB limit.

- -

SCHILY.*

- -

Vendor-specific attributes used -by Joerg Schilling’s star implementation.

- -

SCHILY.acl.access, -SCHILY.acl.default, SCHILY.acl.ace

- -

Stores the access, default and -NFSv4 ACLs as textual strings in a format that is an -extension of the format specified by POSIX.1e draft 17. In -particular, each user or group access specification can -include an additional colon-separated field with the numeric -UID or GID. This allows ACLs to be restored on systems that -may not have complete user or group information available -(such as when NIS/YP or LDAP services are temporarily -unavailable).

- -

SCHILY.devminor, -SCHILY.devmajor

- -

The full minor and major -numbers for device nodes.

- -

SCHILY.fflags

- -

The file flags.

- -

SCHILY.realsize

- -

The full size of the file on -disk. XXX explain? XXX

- -

SCHILY.dev, -SCHILY.ino, SCHILY.nlinks

- -

The device number, inode -number, and link count for the entry. In particular, note -that a pax interchange format archive using Joerg -Schilling’s SCHILY.* extensions can store all -of the data from struct stat.

- -

LIBARCHIVE.*

- -

Vendor-specific attributes used -by the libarchive library and programs that use -it.

- - -

LIBARCHIVE.creationtime

- -

The time when the file was -created. (This should not be confused with the POSIX -“ctime” attribute, which refers to the time when -the file metadata was last changed.)

- - -

LIBARCHIVE.xattr.namespace.key

- -

Libarchive stores -POSIX.1e-style extended attributes using keys of this form. -The key value is URL-encoded: All non-ASCII -characters and the two special characters “=” -and “%” are encoded as “%” followed -by two uppercase hexadecimal digits. The value of this key -is the extended attribute value encoded in base 64. XXX -Detail the base-64 format here XXX

- -

VENDOR.*

- -

XXX document other -vendor-specific extensions XXX

- -

Any values -stored in an extended attribute override the corresponding -values in the regular tar header. Note that compliant -readers should ignore the regular fields when they are -overridden. This is important, as existing archivers are -known to store non-compliant values in the standard header -fields in this situation. There are no limits on length for -any of these fields. In particular, numeric fields can be -arbitrarily large. All text fields are encoded in UTF8. -Compliant writers should store only portable 7-bit ASCII -characters in the standard ustar header and use extended -attributes whenever a text value contains non-ASCII -characters.

- -

In addition to -the x entry described above, the pax interchange -format also supports a g entry. The g entry is -identical in format, but specifies attributes that serve as -defaults for all subsequent archive entries. The g -entry is not widely used.

- -

Besides the new -x and g entries, the pax interchange format -has a few other minor variations from the earlier ustar -format. The most troubling one is that hardlinks are -permitted to have data following them. This allows readers -to restore any hardlink to a file without having to rewind -the archive to find an earlier entry. However, it creates -complications for robust readers, as it is no longer clear -whether or not they should ignore the size field for -hardlink entries.

- -

GNU Tar -Archives
-The GNU tar program started with a pre-POSIX format similar -to that described earlier and has extended it using several -different mechanisms: It added new fields to the empty space -in the header (some of which was later used by POSIX for -conflicting purposes); it allowed the header to be continued -over multiple records; and it defined new entries that -modify following entries (similar in principle to the -x entry described above, but each GNU special entry -is single-purpose, unlike the general-purpose x -entry). As a result, GNU tar archives are not POSIX -compatible, although more lenient POSIX-compliant readers -can successfully extract most GNU tar archives.

- -

struct -header_gnu_tar {

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -

char name[100];

-
- - -

char mode[8];

-
- - -

char uid[8];

-
- - -

char gid[8];

-
- - -

char size[12];

-
- - -

char mtime[12];

-
- - -

char checksum[8];

-
- - -

char typeflag[1];

-
- - -

char linkname[100];

-
- - -

char magic[6];

-
- - -

char version[2];

-
- - -

char uname[32];

-
- - -

char gname[32];

-
- - -

char devmajor[8];

-
- - -

char devminor[8];

-
- - -

char atime[12];

-
- - -

char ctime[12];

-
- - -

char offset[12];

-
- - -

char longnames[4];

-
- - -

char unused[1];

-
- - -

struct {

-
- - - -

char offset[12];

-
- - - -

char numbytes[12];

-
- - -

} sparse[4];

-
- - -

char isextended[1];

-
- - -

char realsize[12];

-
- - -

char pad[17];

-
- -

};

- -

typeflag

- -

GNU tar uses the following -special entry types, in addition to those defined by -POSIX:

- -

7

- -

GNU tar treats -type "7" records identically to type "0" -records, except on one obscure RTOS where they are used to -indicate the pre-allocation of a contiguous file on -disk.

- -

D

- -

This indicates -a directory entry. Unlike the POSIX-standard "5" -typeflag, the header is followed by data records listing the -names of files in this directory. Each name is preceded by -an ASCII "Y" if the file is stored in this archive -or "N" if the file is not stored in this archive. -Each name is terminated with a null, and an extra null marks -the end of the name list. The purpose of this entry is to -support incremental backups; a program restoring from such -an archive may wish to delete files on disk that did not -exist in the directory when the archive was made.

- -

Note that the -"D" typeflag specifically violates POSIX, which -requires that unrecognized typeflags be restored as normal -files. In this case, restoring the "D" entry as a -file could interfere with subsequent creation of the -like-named directory.

- -

K

- -

The data for -this entry is a long linkname for the following regular -entry.

- -

L

- -

The data for -this entry is a long pathname for the following regular -entry.

- -

M

- -

This is a -continuation of the last file on the previous volume. GNU -multi-volume archives guarantee that each volume begins with -a valid entry header. To ensure this, a file may be split, -with part stored at the end of one volume, and part stored -at the beginning of the next volume. The "M" -typeflag indicates that this entry continues an existing -file. Such entries can only occur as the first or second -entry in an archive (the latter only if the first entry is a -volume label). The size field specifies the size of -this entry. The offset field at bytes 369-380 -specifies the offset where this file fragment begins. The -realsize field specifies the total size of the file -(which must equal size plus offset). When -extracting, GNU tar checks that the header file name is the -one it is expecting, that the header offset is in the -correct sequence, and that the sum of offset and size is -equal to realsize.

- -

N

- -

Type -"N" records are no longer generated by GNU tar. -They contained a list of files to be renamed or symlinked -after extraction; this was originally used to support long -names. The contents of this record are a text description of -the operations to be done, in the form “Rename %s to -%s\n” or “Symlink %s to %s\n”; in either -case, both filenames are escaped using K&R C syntax. Due -to security concerns, "N" records are now -generally ignored when reading archives.

- -

S

- -

This is a -“sparse” regular file. Sparse files are stored -as a series of fragments. The header contains a list of -fragment offset/length pairs. If more than four such entries -are required, the header is extended as necessary with -“extra” header extensions (an older format that -is no longer used), or “sparse” extensions.

- -

V

- -

The name -field should be interpreted as a tape/volume header name. -This entry should generally be ignored on extraction.

- -

magic

- -

The magic field -holds the five characters “ustar” followed by a -space. Note that POSIX ustar archives have a trailing -null.

- -

version

- -

The version field holds a space -character followed by a null. Note that POSIX ustar archives -use two copies of the ASCII digit “0”.

- -

atime, ctime

- -

The time the file was last -accessed and the time of last change of file information, -stored in octal as with mtime.

- -

longnames

- -

This field is apparently no -longer used.

- -

Sparse offset / -numbytes

- -

Each such structure specifies a -single fragment of a sparse file. The two fields store -values as octal numbers. The fragments are each padded to a -multiple of 512 bytes in the archive. On extraction, the -list of fragments is collected from the header (including -any extension headers), and the data is then read and -written to the file at appropriate offsets.

- -

isextended

- -

If this is set to non-zero, the -header will be followed by additional “sparse -header” records. Each such record contains information -about as many as 21 additional sparse blocks as shown -here:

- -

struct -gnu_sparse_header {

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -

struct {

-
- - - -

char offset[12];

-
- - - -

char numbytes[12];

-
- - -

} sparse[21];

-
- - -

char isextended[1];

-
- - -

char padding[7];

-
- -

};

- -

realsize

- -

A binary representation of the -file’s complete size, with a much larger range than -the POSIX file size. In particular, with M type -files, the current entry is only a portion of the file. In -that case, the POSIX size field will indicate the size of -this entry; the realsize field will indicate the -total size of the file.

- -

GNU tar pax -archives
-GNU tar 1.14 (XXX check this XXX) and later will write pax -interchange format archives when you specify the ---posix flag. This format follows the pax interchange -format closely, using some SCHILY tags and -introducing new keywords to store sparse file information. -There have been three iterations of the sparse file support, -referred to as “0.0”, “0.1”, and -“1.0”.

- -

GNU.sparse.numblocks, -GNU.sparse.offset, GNU.sparse.numbytes, -GNU.sparse.size

- -

The “0.0” format -used an initial GNU.sparse.numblocks attribute to -indicate the number of blocks in the file, a pair of -GNU.sparse.offset and GNU.sparse.numbytes to -indicate the offset and size of each block, and a single -GNU.sparse.size to indicate the full size of the -file. This is not the same as the size in the tar header -because the latter value does not include the size of any -holes. This format required that the order of attributes be -preserved and relied on readers accepting multiple -appearances of the same attribute names, which is not -officially permitted by the standards.

- -

GNU.sparse.map

- -

The “0.1” format -used a single attribute that stored a comma-separated list -of decimal numbers. Each pair of numbers indicated the -offset and size, respectively, of a block of data. This does -not work well if the archive is extracted by an archiver -that does not recognize this extension, since many pax -implementations simply discard unrecognized attributes.

- -

GNU.sparse.major, -GNU.sparse.minor, GNU.sparse.name, -GNU.sparse.realsize

- -

The “1.0” format -stores the sparse block map in one or more 512-byte blocks -prepended to the file data in the entry body. The pax -attributes indicate the existence of this map (via the -GNU.sparse.major and GNU.sparse.minor fields) -and the full size of the file. The GNU.sparse.name -holds the true name of the file. To avoid confusion, the -name stored in the regular tar header is a modified name so -that extraction errors will be apparent to users.

- -

Solaris -Tar
-XXX More Details Needed XXX

- -

Solaris tar -(beginning with SunOS XXX 5.7 ?? XXX) supports an -“extended” format that is fundamentally similar -to pax interchange format, with the following -differences:

- -

- -

Extended attributes are stored -in an entry whose type is X, not x, as used by -pax interchange format. The detailed format of this entry -appears to be the same as detailed above for the x -entry.

- -

- -

An additional A header -is used to store an ACL for the following regular entry. The -body of this entry contains a seven-digit octal number -followed by a zero byte, followed by the textual ACL -description. The octal value is the number of ACL entries -plus a constant that indicates the ACL type: 01000000 for -POSIX.1e ACLs and 03000000 for NFSv4 ACLs.

- -

AIX Tar -
-XXX More details needed XXX

- -

AIX Tar uses a -ustar-formatted header with the type A for storing -coded ACL information. Unlike the Solaris format, AIX tar -writes this header after the regular file body to which it -applies. The pathname in this header is either NFS4 -or AIXC to indicate the type of ACL stored. The -actual ACL is stored in platform-specific binary format.

- -

Mac OS X -Tar
-The tar distributed with Apple’s Mac OS X stores most -regular files as two separate files in the tar archive. The -two files have the same name except that the first one has -“._” prepended to the last path element. This -special file stores an AppleDouble-encoded binary blob with -additional metadata about the second file, including ACL, -extended attributes, and resources. To recreate the original -file on disk, each separate file can be extracted and the -Mac OS X copyfile() function can be used to unpack -the separate metadata file and apply it to th regular file. -Conversely, the same function provides a “pack” -option to encode the extended metadata from a file into a -separate file whose contents can then be put into a tar -archive.

- -

Note that the -Apple extended attributes interact badly with long -filenames. Since each file is stored with the full name, a -separate set of extensions needs to be included in the -archive for each one, doubling the overhead required for -files with long names.

- -

Summary of -tar type codes
-The following list is a condensed summary of the type codes -used in tar header records generated by different tar -implementations. More details about specific implementations -can be found above:

- -

NUL

- -

Early tar -programs stored a zero byte for regular files.

- -

0

- -

POSIX standard -type code for a regular file.

- -

1

- -

POSIX standard -type code for a hard link description.

- -

2

- -

POSIX standard -type code for a symbolic link description.

- -

3

- -

POSIX standard -type code for a character device node.

- -

4

- -

POSIX standard -type code for a block device node.

- -

5

- -

POSIX standard -type code for a directory.

- -

6

- -

POSIX standard -type code for a FIFO.

- -

7

- -

POSIX -reserved.

- -

7

- -

GNU tar used -for pre-allocated files on some systems.

- -

A

- -

Solaris tar ACL -description stored prior to a regular file header.

- -

A

- -

AIX tar ACL -description stored after the file body.

- -

D

- -

GNU tar -directory dump.

- -

K

- -

GNU tar long -linkname for the following header.

- -

L

- -

GNU tar long -pathname for the following header.

- -

M

- -

GNU tar -multivolume marker, indicating the file is a continuation of -a file from the previous volume.

- -

N

- -

GNU tar long -filename support. Deprecated.

- -

S

- -

GNU tar sparse -regular file.

- -

V

- -

GNU tar -tape/volume header name.

- -

X

- -

Solaris tar -general-purpose extension header.

- -

g

- -

POSIX pax -interchange format global extensions.

- -

x

- -

POSIX pax -interchange format per-file extensions.

- -

SEE ALSO

- -

ar(1), pax(1), tar(1)

- -

STANDARDS

- -

The tar utility is no -longer a part of POSIX or the Single Unix Standard. It last -appeared in Version 2 of the Single UNIX Specification -(“SUSv2”). It has been supplanted in subsequent -standards by pax(1). The ustar format is currently part of -the specification for the pax(1) utility. The pax -interchange file format is new with IEEE Std 1003.1-2001 -(“POSIX.1”).

- -

HISTORY

- -

A tar command appeared in -Seventh Edition Unix, which was released in January, 1979. -It replaced the tp program from Fourth Edition Unix -which in turn replaced the tap program from First -Edition Unix. John Gilmore’s pdtar -public-domain implementation (circa 1987) was highly -influential and formed the basis of GNU tar (circa -1988). Joerg Shilling’s star archiver is -another open-source (CDDL) archiver (originally developed -circa 1985) which features complete support for pax -interchange format.

- -

This -documentation was written as part of the libarchive -and bsdtar project by Tim Kientzle -<kientzle@FreeBSD.org>.

- -

BSD -December 27, 2016 BSD

-
- - diff --git a/thirdparty/libarchive/doc/man/.ignore_me b/thirdparty/libarchive/doc/man/.ignore_me deleted file mode 100644 index d285484d4..000000000 --- a/thirdparty/libarchive/doc/man/.ignore_me +++ /dev/null @@ -1,2 +0,0 @@ -*** PLEASE DO NOT DELETE THIS FILE! *** -This file is used to track an otherwise empty directory in git. diff --git a/thirdparty/libarchive/doc/man/Makefile b/thirdparty/libarchive/doc/man/Makefile deleted file mode 100644 index 82bac3b1e..000000000 --- a/thirdparty/libarchive/doc/man/Makefile +++ /dev/null @@ -1,133 +0,0 @@ - -default: all - - -archive_entry.3: ../mdoc2man.awk ../../libarchive/archive_entry.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_entry.3 > archive_entry.3 - -archive_entry_acl.3: ../mdoc2man.awk ../../libarchive/archive_entry_acl.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_entry_acl.3 > archive_entry_acl.3 - -archive_entry_linkify.3: ../mdoc2man.awk ../../libarchive/archive_entry_linkify.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_entry_linkify.3 > archive_entry_linkify.3 - -archive_entry_misc.3: ../mdoc2man.awk ../../libarchive/archive_entry_misc.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_entry_misc.3 > archive_entry_misc.3 - -archive_entry_paths.3: ../mdoc2man.awk ../../libarchive/archive_entry_paths.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_entry_paths.3 > archive_entry_paths.3 - -archive_entry_perms.3: ../mdoc2man.awk ../../libarchive/archive_entry_perms.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_entry_perms.3 > archive_entry_perms.3 - -archive_entry_stat.3: ../mdoc2man.awk ../../libarchive/archive_entry_stat.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_entry_stat.3 > archive_entry_stat.3 - -archive_entry_time.3: ../mdoc2man.awk ../../libarchive/archive_entry_time.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_entry_time.3 > archive_entry_time.3 - -archive_read.3: ../mdoc2man.awk ../../libarchive/archive_read.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_read.3 > archive_read.3 - -archive_read_add_passphrase.3: ../mdoc2man.awk ../../libarchive/archive_read_add_passphrase.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_read_add_passphrase.3 > archive_read_add_passphrase.3 - -archive_read_data.3: ../mdoc2man.awk ../../libarchive/archive_read_data.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_read_data.3 > archive_read_data.3 - -archive_read_disk.3: ../mdoc2man.awk ../../libarchive/archive_read_disk.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_read_disk.3 > archive_read_disk.3 - -archive_read_extract.3: ../mdoc2man.awk ../../libarchive/archive_read_extract.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_read_extract.3 > archive_read_extract.3 - -archive_read_filter.3: ../mdoc2man.awk ../../libarchive/archive_read_filter.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_read_filter.3 > archive_read_filter.3 - -archive_read_format.3: ../mdoc2man.awk ../../libarchive/archive_read_format.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_read_format.3 > archive_read_format.3 - -archive_read_free.3: ../mdoc2man.awk ../../libarchive/archive_read_free.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_read_free.3 > archive_read_free.3 - -archive_read_header.3: ../mdoc2man.awk ../../libarchive/archive_read_header.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_read_header.3 > archive_read_header.3 - -archive_read_new.3: ../mdoc2man.awk ../../libarchive/archive_read_new.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_read_new.3 > archive_read_new.3 - -archive_read_open.3: ../mdoc2man.awk ../../libarchive/archive_read_open.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_read_open.3 > archive_read_open.3 - -archive_read_set_options.3: ../mdoc2man.awk ../../libarchive/archive_read_set_options.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_read_set_options.3 > archive_read_set_options.3 - -archive_util.3: ../mdoc2man.awk ../../libarchive/archive_util.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_util.3 > archive_util.3 - -archive_write.3: ../mdoc2man.awk ../../libarchive/archive_write.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_write.3 > archive_write.3 - -archive_write_blocksize.3: ../mdoc2man.awk ../../libarchive/archive_write_blocksize.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_write_blocksize.3 > archive_write_blocksize.3 - -archive_write_data.3: ../mdoc2man.awk ../../libarchive/archive_write_data.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_write_data.3 > archive_write_data.3 - -archive_write_disk.3: ../mdoc2man.awk ../../libarchive/archive_write_disk.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_write_disk.3 > archive_write_disk.3 - -archive_write_filter.3: ../mdoc2man.awk ../../libarchive/archive_write_filter.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_write_filter.3 > archive_write_filter.3 - -archive_write_finish_entry.3: ../mdoc2man.awk ../../libarchive/archive_write_finish_entry.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_write_finish_entry.3 > archive_write_finish_entry.3 - -archive_write_format.3: ../mdoc2man.awk ../../libarchive/archive_write_format.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_write_format.3 > archive_write_format.3 - -archive_write_free.3: ../mdoc2man.awk ../../libarchive/archive_write_free.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_write_free.3 > archive_write_free.3 - -archive_write_header.3: ../mdoc2man.awk ../../libarchive/archive_write_header.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_write_header.3 > archive_write_header.3 - -archive_write_new.3: ../mdoc2man.awk ../../libarchive/archive_write_new.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_write_new.3 > archive_write_new.3 - -archive_write_open.3: ../mdoc2man.awk ../../libarchive/archive_write_open.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_write_open.3 > archive_write_open.3 - -archive_write_set_options.3: ../mdoc2man.awk ../../libarchive/archive_write_set_options.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_write_set_options.3 > archive_write_set_options.3 - -archive_write_set_passphrase.3: ../mdoc2man.awk ../../libarchive/archive_write_set_passphrase.3 - awk -f ../mdoc2man.awk < ../../libarchive/archive_write_set_passphrase.3 > archive_write_set_passphrase.3 - -cpio.5: ../mdoc2man.awk ../../libarchive/cpio.5 - awk -f ../mdoc2man.awk < ../../libarchive/cpio.5 > cpio.5 - -libarchive.3: ../mdoc2man.awk ../../libarchive/libarchive.3 - awk -f ../mdoc2man.awk < ../../libarchive/libarchive.3 > libarchive.3 - -libarchive_changes.3: ../mdoc2man.awk ../../libarchive/libarchive_changes.3 - awk -f ../mdoc2man.awk < ../../libarchive/libarchive_changes.3 > libarchive_changes.3 - -libarchive-formats.5: ../mdoc2man.awk ../../libarchive/libarchive-formats.5 - awk -f ../mdoc2man.awk < ../../libarchive/libarchive-formats.5 > libarchive-formats.5 - -libarchive_internals.3: ../mdoc2man.awk ../../libarchive/libarchive_internals.3 - awk -f ../mdoc2man.awk < ../../libarchive/libarchive_internals.3 > libarchive_internals.3 - -mtree.5: ../mdoc2man.awk ../../libarchive/mtree.5 - awk -f ../mdoc2man.awk < ../../libarchive/mtree.5 > mtree.5 - -tar.5: ../mdoc2man.awk ../../libarchive/tar.5 - awk -f ../mdoc2man.awk < ../../libarchive/tar.5 > tar.5 - -bsdtar.1: ../mdoc2man.awk ../../tar/bsdtar.1 - awk -f ../mdoc2man.awk < ../../tar/bsdtar.1 > bsdtar.1 - -bsdcpio.1: ../mdoc2man.awk ../../cpio/bsdcpio.1 - awk -f ../mdoc2man.awk < ../../cpio/bsdcpio.1 > bsdcpio.1 -all: archive_entry.3 archive_entry_acl.3 archive_entry_linkify.3 archive_entry_misc.3 archive_entry_paths.3 archive_entry_perms.3 archive_entry_stat.3 archive_entry_time.3 archive_read.3 archive_read_add_passphrase.3 archive_read_data.3 archive_read_disk.3 archive_read_extract.3 archive_read_filter.3 archive_read_format.3 archive_read_free.3 archive_read_header.3 archive_read_new.3 archive_read_open.3 archive_read_set_options.3 archive_util.3 archive_write.3 archive_write_blocksize.3 archive_write_data.3 archive_write_disk.3 archive_write_filter.3 archive_write_finish_entry.3 archive_write_format.3 archive_write_free.3 archive_write_header.3 archive_write_new.3 archive_write_open.3 archive_write_set_options.3 archive_write_set_passphrase.3 cpio.5 libarchive.3 libarchive_changes.3 libarchive-formats.5 libarchive_internals.3 mtree.5 tar.5 bsdtar.1 bsdcpio.1 diff --git a/thirdparty/libarchive/doc/man/archive_entry.3 b/thirdparty/libarchive/doc/man/archive_entry.3 deleted file mode 100644 index e6938a62f..000000000 --- a/thirdparty/libarchive/doc/man/archive_entry.3 +++ /dev/null @@ -1,143 +0,0 @@ -.TH ARCHIVE_ENTRY 3 "February 2, 2012" "" -.SH NAME -.ad l -\fB\%archive_entry_clear\fP, -\fB\%archive_entry_clone\fP, -\fB\%archive_entry_free\fP, -\fB\%archive_entry_new\fP -\- functions for managing archive entry descriptions -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIstruct archive_entry *\fP -.br -\fB\%archive_entry_clear\fP(\fI\%struct\ archive_entry\ *\fP); -.br -\fIstruct archive_entry *\fP -.br -\fB\%archive_entry_clone\fP(\fI\%struct\ archive_entry\ *\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_free\fP(\fI\%struct\ archive_entry\ *\fP); -.br -\fIstruct archive_entry *\fP -.br -\fB\%archive_entry_new\fP(\fI\%void\fP); -.SH DESCRIPTION -.ad l -These functions create and manipulate data objects that -represent entries within an archive. -You can think of a -Tn struct archive_entry -as a heavy-duty version of -Tn struct stat: -it includes everything from -Tn struct stat -plus associated pathname, textual group and user names, etc. -These objects are used by -\fBlibarchive\fP(3) -to represent the metadata associated with a particular -entry in an archive. -.SS Create and Destroy -There are functions to allocate, destroy, clear, and copy -\fIarchive_entry\fP -objects: -.RS 5 -.TP -\fB\%archive_entry_clear\fP() -Erases the object, resetting all internal fields to the -same state as a newly-created object. -This is provided to allow you to quickly recycle objects -without thrashing the heap. -.TP -\fB\%archive_entry_clone\fP() -A deep copy operation; all text fields are duplicated. -.TP -\fB\%archive_entry_free\fP() -Releases the -Tn struct archive_entry -object. -.TP -\fB\%archive_entry_new\fP() -Allocate and return a blank -Tn struct archive_entry -object. -.RE -.SS Function groups -Due to high number of functions, the accessor functions can be found in -man pages grouped by the purpose. -.RS 5 -.TP -\fBarchive_entry_acl\fP(3) -Access Control List manipulation -.TP -\fBarchive_entry_paths\fP(3) -Path name manipulation -.TP -\fBarchive_entry_perms\fP(3) -User, group and mode manipulation -.TP -\fBarchive_entry_stat\fP(3) -Functions not in the other groups and copying to/from -Vt struct stat. -.TP -\fBarchive_entry_time\fP(3) -Time field manipulation -.RE -.PP -Most of the functions set or read entries in an object. -Such functions have one of the following forms: -.RS 5 -.TP -\fB\%archive_entry_set_XXXX\fP() -Stores the provided data in the object. -In particular, for strings, the pointer is stored, -not the referenced string. -.TP -\fB\%archive_entry_copy_XXXX\fP() -As above, except that the referenced data is copied -into the object. -.TP -\fB\%archive_entry_XXXX\fP() -Returns the specified data. -In the case of strings, a const-qualified pointer to -the string is returned. -.RE -String data can be set or accessed as wide character strings -or normal -\fIchar\fP -strings. -The functions that use wide character strings are suffixed with -\fB_w\fP. -Note that these are different representations of the same data: -For example, if you store a narrow string and read the corresponding -wide string, the object will transparently convert formats -using the current locale. -Similarly, if you store a wide string and then store a -narrow string for the same data, the previously-set wide string will -be discarded in favor of the new data. -.SH SEE ALSO -.ad l -\fBarchive_entry_acl\fP(3), -\fBarchive_entry_paths\fP(3), -\fBarchive_entry_perms\fP(3), -\fBarchive_entry_time\fP(3), -\fBlibarchive\fP(3) -.SH HISTORY -.ad l -The -\fB\%libarchive\fP -library first appeared in -FreeBSD 5.3. -.SH AUTHORS -.ad l --nosplit -The -\fB\%libarchive\fP -library was written by -Tim Kientzle \% diff --git a/thirdparty/libarchive/doc/man/archive_entry_acl.3 b/thirdparty/libarchive/doc/man/archive_entry_acl.3 deleted file mode 100644 index 06a104a4f..000000000 --- a/thirdparty/libarchive/doc/man/archive_entry_acl.3 +++ /dev/null @@ -1,452 +0,0 @@ -.TH ARCHIVE_ENTRY_ACL 3 "February 15, 2017" "" -.SH NAME -.ad l -\fB\%archive_entry_acl_add_entry\fP, -\fB\%archive_entry_acl_add_entry_w\fP, -\fB\%archive_entry_acl_clear\fP, -\fB\%archive_entry_acl_count\fP, -\fB\%archive_entry_acl_from_text\fP, -\fB\%archive_entry_acl_from_text_w\fP, -\fB\%archive_entry_acl_next\fP, -\fB\%archive_entry_acl_reset\fP, -\fB\%archive_entry_acl_to_text\fP, -\fB\%archive_entry_acl_to_text_w\fP, -\fB\%archive_entry_acl_types\fP -\- functions for manipulating Access Control Lists in archive entry descriptions -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIvoid\fP -.br -\fB\%archive_entry_acl_add_entry\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%int\ type\fP, \fI\%int\ permset\fP, \fI\%int\ tag\fP, \fI\%int\ qualifier\fP, \fI\%const\ char\ *name\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_acl_add_entry_w\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%int\ type\fP, \fI\%int\ permset\fP, \fI\%int\ tag\fP, \fI\%int\ qualifier\fP, \fI\%const\ wchar_t\ *name\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_acl_clear\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIint\fP -.br -\fB\%archive_entry_acl_count\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%int\ type\fP); -.br -\fIint\fP -.br -\fB\%archive_entry_acl_from_text\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%const\ char\ *text\fP, \fI\%int\ type\fP); -.br -\fIint\fP -.br -\fB\%archive_entry_acl_from_text_w\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%const\ wchar_t\ *text\fP, \fI\%int\ type\fP); -.br -\fIint\fP -.br -\fB\%archive_entry_acl_next\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%int\ type\fP, \fI\%int\ *ret_type\fP, \fI\%int\ *ret_permset\fP, \fI\%int\ *ret_tag\fP, \fI\%int\ *ret_qual\fP, \fI\%const\ char\ **ret_name\fP); -.br -\fIint\fP -.br -\fB\%archive_entry_acl_reset\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%int\ type\fP); -.br -\fIchar *\fP -.br -\fB\%archive_entry_acl_to_text\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%ssize_t\ *len_p\fP, \fI\%int\ flags\fP); -.br -\fIwchar_t *\fP -.br -\fB\%archive_entry_acl_to_text_w\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%ssize_t\ *len_p\fP, \fI\%int\ flags\fP); -.br -\fIint\fP -.br -\fB\%archive_entry_acl_types\fP(\fI\%struct\ archive_entry\ *a\fP); -.SH DESCRIPTION -.ad l -The -``Access Control Lists (ACLs)'' -extend the standard Unix permission model. -The ACL interface of -\fB\%libarchive\fP -supports both POSIX.1e and NFSv4 style ACLs. -Use of ACLs is restricted by -various levels of ACL support in operating systems, file systems and archive -formats. -.SS POSIX.1e Access Control Lists -A POSIX.1e ACL consists of a number of independent entries. -Each entry specifies the permission set as a bitmask of basic permissions. -Valid permissions in the -are: -.RS 5 -.TP -.BR ARCHIVE_ENTRY_ACL_READ (.B r ) -.TP -.BR ARCHIVE_ENTRY_ACL_WRITE (.B w ) -.TP -.BR ARCHIVE_ENTRY_ACL_EXECUTE (.B x ) -.RE -The permissions correspond to the normal Unix permissions. -.PP -The -specifies the principal to which the permission applies. -Valid values are: -.RS 5 -It .BR ARCHIVE_ENTRY_ACL_USER -The user specified by the name field. -It .BR ARCHIVE_ENTRY_ACL_USER_OBJ -The owner of the file. -It .BR ARCHIVE_ENTRY_ACL_GROUP -The group specified by the name field. -It .BR ARCHIVE_ENTRY_ACL_GROUP_OBJ -The group which owns the file. -It .BR ARCHIVE_ENTRY_ACL_MASK -The maximum permissions to be obtained via group permissions. -It .BR ARCHIVE_ENTRY_ACL_OTHER -Any principal who is not the file owner or a member of the owning group. -.RE -.PP -The principals -.BR ARCHIVE_ENTRY_ACL_USER_OBJ, -.BR ARCHIVE_ENTRY_ACL_GROUP_OBJ -and -.BR ARCHIVE_ENTRY_ACL_OTHER -are equivalent to user, group and other in the classic Unix permission -model and specify non-extended ACL entries. -.PP -All files have an access ACL -(.BR ARCHIVE_ENTRY_ACL_TYPE_ACCESS.) -This specifies the permissions required for access to the file itself. -Directories have an additional ACL -(.BR ARCHIVE_ENTRY_ACL_TYPE_DEFAULT,) -which controls the initial access ACL for newly-created directory entries. -.SS NFSv4 Access Control Lists -A NFSv4 ACL consists of multiple individual entries called Access Control -Entries (ACEs). -.PP -There are four possible types of a NFSv4 ACE: -.RS 5 -It .BR ARCHIVE_ENTRY_ACL_TYPE_ALLOW -Allow principal to perform actions requiring given permissions. -It .BR ARCHIVE_ENTRY_ACL_TYPE_DENY -Prevent principal from performing actions requiring given permissions. -It .BR ARCHIVE_ENTRY_ACL_TYPE_AUDIT -Log access attempts by principal which require given permissions. -It .BR ARCHIVE_ENTRY_ACL_TYPE_ALARM -Trigger a system alarm on access attempts by principal which require given -permissions. -.RE -.PP -The -specifies the principal to which the permission applies. -Valid values are: -.RS 5 -It .BR ARCHIVE_ENTRY_ACL_USER -The user specified by the name field. -It .BR ARCHIVE_ENTRY_ACL_USER_OBJ -The owner of the file. -It .BR ARCHIVE_ENTRY_ACL_GROUP -The group specified by the name field. -It .BR ARCHIVE_ENTRY_ACL_GROUP_OBJ -The group which owns the file. -It .BR ARCHIVE_ENTRY_ACL_EVERYONE -Any principal who is not the file owner or a member of the owning group. -.RE -.PP -Entries with the -.BR ARCHIVE_ENTRY_ACL_USER -or -.BR ARCHIVE_ENTRY_ACL_GROUP -tag store the user and group name in the -string and optionally the user or group ID in the -integer. -.PP -NFSv4 ACE permissions and flags are stored in the same -bitfield. -Some permissions share the same constant and permission character -but have different effect on directories than on files. -The following ACE permissions are supported: -.RS 5 -.TP -.BR ARCHIVE_ENTRY_ACL_READ_DATA (.B r ) -Read data (file). -.TP -.BR ARCHIVE_ENTRY_ACL_LIST_DIRECTORY (.B r ) -List entries (directory). -.TP -ARCHIVE_ENTRY_ACL_WRITE_DATA (.B w ) -Write data (file). -.TP -ARCHIVE_ENTRY_ACL_ADD_FILE (.B w ) -Create files (directory). -.TP -.BR ARCHIVE_ENTRY_ACL_EXECUTE (.B x ) -Execute file or change into a directory. -.TP -.BR ARCHIVE_ENTRY_ACL_APPEND_DATA (.B p ) -Append data (file). -.TP -.BR ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY (.B p ) -Create subdirectories (directory). -.TP -.BR ARCHIVE_ENTRY_ACL_DELETE_CHILD (.B D ) -Remove files and subdirectories inside a directory. -.TP -.BR ARCHIVE_ENTRY_ACL_DELETE (.B d ) -Remove file or directory. -.TP -.BR ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES (.B a ) -Read file or directory attributes. -.TP -.BR ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES (.B A ) -Write file or directory attributes. -.TP -.BR ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS (.B R ) -Read named file or directory attributes. -.TP -.BR ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS (.B W ) -Write named file or directory attributes. -.TP -.BR ARCHIVE_ENTRY_ACL_READ_ACL (.B c ) -Read file or directory ACL. -.TP -.BR ARCHIVE_ENTRY_ACL_WRITE_ACL (.B C ) -Write file or directory ACL. -.TP -.BR ARCHIVE_ENTRY_ACL_WRITE_OWNER (.B o ) -Change owner of a file or directory. -.TP -.BR ARCHIVE_ENTRY_ACL_SYNCHRONIZE (.B s ) -Use synchronous I/O. -.RE -.PP -The following NFSv4 ACL inheritance flags are supported: -.RS 5 -.TP -.BR ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT (.B f ) -Inherit parent directory ACE to files. -.TP -.BR ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT (.B d ) -Inherit parent directory ACE to subdirectories. -.TP -.BR ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY (.B i ) -Only inherit, do not apply the permission on the directory itself. -.TP -.BR ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT (.B n ) -Do not propagate inherit flags. -Only first-level entries inherit ACLs. -.TP -.BR ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS (.B S ) -Trigger alarm or audit on successful access. -.TP -.BR ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS (.B F ) -Trigger alarm or audit on failed access. -.TP -.BR ARCHIVE_ENTRY_ACL_ENTRY_INHERITED (.B I ) -Mark that ACE was inherited. -.RE -.SS Functions -\fB\%archive_entry_acl_add_entry\fP() -and -\fB\%archive_entry_acl_add_entry_w\fP() -add a single ACL entry. -For the access ACL and non-extended principals, the classic Unix permissions -are updated. -An archive entry cannot contain both POSIX.1e and NFSv4 ACL entries. -.PP -\fB\%archive_entry_acl_clear\fP() -removes all ACL entries and resets the enumeration pointer. -.PP -\fB\%archive_entry_acl_count\fP() -counts the ACL entries that have the given type mask. -can be the bitwise-or of -.RS 5 -.TP -.BR ARCHIVE_ENTRY_ACL_TYPE_ACCESS -.TP -.BR ARCHIVE_ENTRY_ACL_TYPE_DEFAULT -.RE -for POSIX.1e ACLs and -.RS 5 -.TP -.BR ARCHIVE_ENTRY_ACL_TYPE_ALLOW -.TP -.BR ARCHIVE_ENTRY_ACL_TYPE_DENY -.TP -.BR ARCHIVE_ENTRY_ACL_TYPE_AUDIT -.TP -.BR ARCHIVE_ENTRY_ACL_TYPE_ALARM -.RE -for NFSv4 ACLs. -For POSIX.1e ACLs if -.BR ARCHIVE_ENTRY_ACL_TYPE_ACCESS -is included and at least one extended ACL entry is found, -the three non-extended ACLs are added. -.PP -\fB\%archive_entry_acl_from_text\fP() -and -\fB\%archive_entry_acl_from_text_w\fP() -add new -(or merge with existing) -ACL entries from -(wide) -text. -The argument -may take one of the following values: -.RS 5 -.TP -.BR ARCHIVE_ENTRY_ACL_TYPE_ACCESS -.TP -.BR ARCHIVE_ENTRY_ACL_TYPE_DEFAULT -.TP -.BR ARCHIVE_ENTRY_ACL_TYPE_NFS4 -.RE -Supports all formats that can be created with -\fB\%archive_entry_acl_to_text\fP() -or respectively -\fB\%archive_entry_acl_to_text_w\fP(). -Existing ACL entries are preserved. -To get a clean new ACL from text -\fB\%archive_entry_acl_clear\fP() -must be called first. -Entries prefixed with -``default:'' -are treated as -.BR ARCHIVE_ENTRY_ACL_TYPE_DEFAULT -unless -is -.BR ARCHIVE_ENTRY_ACL_TYPE_NFS4. -Invalid entries, non-parseable ACL entries and entries beginning with -the -Sq # -character -(comments) -are skipped. -.PP -\fB\%archive_entry_acl_next\fP() -return the next entry of the ACL list. -This functions may only be called after -\fB\%archive_entry_acl_reset\fP() -has indicated the presence of extended ACL entries. -.PP -\fB\%archive_entry_acl_reset\fP() -prepare reading the list of ACL entries with -\fB\%archive_entry_acl_next\fP(). -The function returns 0 if no non-extended ACLs are found. -In this case, the access permissions should be obtained by -\fBarchive_entry_mode\fP(3) -or set using -\fBchmod\fP(2). -Otherwise, the function returns the same value as -\fB\%archive_entry_acl_count\fP(). -.PP -\fB\%archive_entry_acl_to_text\fP() -and -\fB\%archive_entry_acl_to_text_w\fP() -convert the ACL entries for the given type into a -(wide) -string of ACL entries separated by newline. -If the pointer -is not NULL, then the function shall return the length of the string -(not including the NULL terminator) -in the location pointed to by -. -The -argument is a bitwise-or. -.PP -The following flags are effective only on POSIX.1e ACL: -.RS 5 -.TP -.BR ARCHIVE_ENTRY_ACL_TYPE_ACCESS -Output access ACLs. -.TP -.BR ARCHIVE_ENTRY_ACL_TYPE_DEFAULT -Output POSIX.1e default ACLs. -.TP -.BR ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT -Prefix each default ACL entry with the word -``default:''. -.TP -.BR ARCHIVE_ENTRY_ACL_STYLE_SOLARIS -The mask and other ACLs don not contain a double colon. -.RE -.PP -The following flags are effecive only on NFSv4 ACL: -.RS 5 -.TP -.BR ARCHIVE_ENTRY_ACL_STYLE_COMPACT -Do not output minus characters for unset permissions and flags in NFSv4 ACL -permission and flag fields. -.RE -.PP -The following flags are effective on both POSIX.1e and NFSv4 ACL: -.RS 5 -.TP -.BR ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID -Add an additional colon-separated field containing the user or group id. -.TP -.BR ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA -Separate ACL entries with comma instead of newline. -.RE -.PP -If the archive entry contains NFSv4 ACLs, all types of NFSv4 ACLs are returned. -It the entry contains POSIX.1e ACLs and none of the flags -.BR ARCHIVE_ENTRY_ACL_TYPE_ACCESS -or -.BR ARCHIVE_ENTRY_ACL_TYPE_DEFAULT -are specified, both access and default entries are returned and default entries -are prefixed with -``default:''. -.PP -\fB\%archive_entry_acl_types\fP() -get ACL entry types contained in an archive entry's ACL. -As POSIX.1e and NFSv4 -ACL entries cannot be mixed, this function is a very efficient way to detect if -an ACL already contains POSIX.1e or NFSv4 ACL entries. -.SH RETURN VALUES -.ad l -\fB\%archive_entry_acl_count\fP() -and -\fB\%archive_entry_acl_reset\fP() -returns the number of ACL entries that match the given type mask. -For POSIX.1e ACLS if the type mask includes -.BR ARCHIVE_ENTRY_ACL_TYPE_ACCESS -and at least one extended ACL entry exists, the three classic Unix -permissions are counted. -.PP -\fB\%archive_entry_acl_from_text\fP() -and -\fB\%archive_entry_acl_from_text_w\fP() -return -.BR ARCHIVE_OK -if all entries were successfully parsed and -.BR ARCHIVE_WARN -if one or more entries were invalid or non-parseable. -.PP -\fB\%archive_entry_acl_next\fP() -returns -.BR ARCHIVE_OK -on success, -.BR ARCHIVE_EOF -if no more ACL entries exist -and -.BR ARCHIVE_WARN -if -\fB\%archive_entry_acl_reset\fP() -has not been called first. -.PP -\fB\%archive_entry_acl_to_text\fP() -returns a string representing the ACL entries matching the given type and -flags on success or NULL on error. -.PP -\fB\%archive_entry_acl_to_text_w\fP() -returns a wide string representing the ACL entries matching the given type -and flags on success or NULL on error. -.PP -\fB\%archive_entry_acl_types\fP() -returns a bitmask of ACL entry types or 0 if archive entry has no ACL entries. -.SH SEE ALSO -.ad l -\fBarchive_entry\fP(3), -\fBlibarchive\fP(3) diff --git a/thirdparty/libarchive/doc/man/archive_entry_linkify.3 b/thirdparty/libarchive/doc/man/archive_entry_linkify.3 deleted file mode 100644 index c874ec3f7..000000000 --- a/thirdparty/libarchive/doc/man/archive_entry_linkify.3 +++ /dev/null @@ -1,203 +0,0 @@ -.TH ARCHIVE_ENTRY_LINKIFY 3 "February 2, 2012" "" -.SH NAME -.ad l -\fB\%archive_entry_linkresolver\fP, -\fB\%archive_entry_linkresolver_new\fP, -\fB\%archive_entry_linkresolver_set_strategy\fP, -\fB\%archive_entry_linkresolver_free\fP, -\fB\%archive_entry_linkify\fP -\- hardlink resolver functions -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIstruct archive_entry_linkresolver *\fP -.br -\fB\%archive_entry_linkresolver_new\fP(\fI\%void\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_linkresolver_set_strategy\fP(\fI\%struct\ archive_entry_linkresolver\ *resolver\fP, \fI\%int\ format\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_linkresolver_free\fP(\fI\%struct\ archive_entry_linkresolver\ *resolver\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_linkify\fP(\fI\%struct\ archive_entry_linkresolver\ *resolver\fP, \fI\%struct\ archive_entry\ **entry\fP, \fI\%struct\ archive_entry\ **sparse\fP); -.SH DESCRIPTION -.ad l -Programs that want to create archives have to deal with hardlinks. -Hardlinks are handled in different ways by the archive formats. -The basic strategies are: -.RS 5 -.IP 1. -Ignore hardlinks and store the body for each reference (old cpio, zip). -.IP 2. -Store the body the first time an inode is seen (ustar, pax). -.IP 3. -Store the body the last time an inode is seen (new cpio). -.RE -.PP -The -\fB\%archive_entry_linkresolver\fP -functions help by providing a unified interface and handling the complexity -behind the scene. -.PP -The -\fB\%archive_entry_linkresolver\fP -functions assume that -Vt archive_entry -instances have valid nlinks, inode and device values. -The inode and device value is used to match entries. -The nlinks value is used to determined if all references have been found and -if the internal references can be recycled. -.PP -The -\fB\%archive_entry_linkresolver_new\fP() -function allocates a new link resolver. -The instance can be freed using -\fB\%archive_entry_linkresolver_free\fP(). -All deferred entries are flushed and the internal storage is freed. -.PP -The -\fB\%archive_entry_linkresolver_set_strategy\fP() -function selects the optimal hardlink strategy for the given format. -The format code can be obtained from -\fBarchive_format\fP(3). -The function can be called more than once, but it is recommended to -flush all deferred entries first. -.PP -The -\fB\%archive_entry_linkify\fP() -function is the core of -\fB\%archive_entry_linkresolver\fP. -The -\fB\%entry\fP() -argument points to the -Vt archive_entry -that should be written. -Depending on the strategy one of the following actions is taken: -.RS 5 -.IP 1. -For the simple archive formats -\fI*entry\fP -is left unmodified and -\fI*sparse\fP -is set to -.BR NULL. -.IP 2. -For tar like archive formats, -\fI*sparse\fP -is set to -.BR NULL. -If -\fI*entry\fP -is -.BR NULL, -no action is taken. -If the hardlink count of -\fI*entry\fP -is larger than 1 and the file type is a regular file or symbolic link, -the internal list is searched for a matching inode. -If such an inode is found, the link count is decremented and the file size -of -\fI*entry\fP -is set to 0 to notify that no body should be written. -If no such inode is found, a copy of the entry is added to the internal cache -with a link count reduced by one. -.IP 3. -For new cpio like archive formats a value for -\fI*entry\fP -of -.BR NULL -is used to flush deferred entries. -In that case -\fI*entry\fP -is set to an arbitrary deferred entry and the entry itself is removed from the -internal list. -If the internal list is empty, -\fI*entry\fP -is set to -.BR NULL. -In either case, -\fI*sparse\fP -is set to -.BR NULL -and the function returns. -If the hardlink count of -\fI*entry\fP -is one or the file type is a directory or device, -\fI*sparse\fP -is set to -.BR NULL -and no further action is taken. -Otherwise, the internal list is searched for a matching inode. -If such an inode is not found, the entry is added to the internal list, -both -\fI*entry\fP -and -\fI*sparse\fP -are set to -.BR NULL -and the function returns. -If such an inode is found, the link count is decremented. -If it remains larger than one, the existing entry on the internal list -is swapped with -\fI*entry\fP -after retaining the link count. -The existing entry is returned in -\fI*entry\fP. -If the link count reached one, the new entry is also removed from the -internal list and returned in -\fI*sparse\fP. -Otherwise -\fI*sparse\fP -is set to -.BR NULL. -.RE -.PP -The general usage is therefore: -.RS 5 -.IP 1. -For each new archive entry, call -\fB\%archive_entry_linkify\fP(). -.IP 2. -Keep in mind that the entries returned may have a size of 0 now. -.IP 3. -If -\fI*entry\fP -is not -.BR NULL, -archive it. -.IP 4. -If -\fI*sparse\fP -is not -.BR NULL, -archive it. -.IP 5. -After all entries have been written to disk, call -\fB\%archive_entry_linkify\fP() -with -\fI*entry\fP -set to -.BR NULL -and archive the returned entry as long as it is not -.BR NULL. -.RE -.SH RETURN VALUES -.ad l -\fB\%archive_entry_linkresolver_new\fP() -returns -.BR NULL -on -\fBmalloc\fP(3) -failures. -.SH SEE ALSO -.ad l -\fBarchive_entry\fP(3) diff --git a/thirdparty/libarchive/doc/man/archive_entry_misc.3 b/thirdparty/libarchive/doc/man/archive_entry_misc.3 deleted file mode 100644 index 6ce320bde..000000000 --- a/thirdparty/libarchive/doc/man/archive_entry_misc.3 +++ /dev/null @@ -1,49 +0,0 @@ -.TH ARCHIVE_ENTRY_MISC 3 "April 15, 2019" "" -.SH NAME -.ad l -\fB\%archive_entry_symlink_type\fP, -\fB\%archive_entry_set_symlink_type\fP -\- miscellaneous functions for manipulating properties of archive_entry -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIint\fP -.br -\fB\%archive_entry_symlink_type\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_set_symlink_type\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%int\fP); -.SH DESCRIPTION -.ad l -The function -\fB\%archive_entry_symlink_type\fP() -returns and the function -\fB\%archive_entry_set_symlink_type\fP() -sets the type of the symbolic link stored in an archive entry. -These functions -have special meaning on operating systems that support multiple symbolic link -types (e.g. Microsoft Windows). -.PP -Supported values are: -.RS 5 -.TP -AE_SYMLINK_TYPE_UNDEFINED -Symbolic link target type is not defined (default on unix systems) -.TP -AE_SYMLINK_TYPE_FILE -Symbolic link points to a file -.TP -AE_SYMLINK_TYPE_DIRECTORY -Symbolic link points to a directory -.RE -.SH SEE ALSO -.ad l -\fBarchive_entry\fP(3), -\fBarchive_entry_paths\fP(3), -\fBarchive_entry_stat\fP(3), -\fBlibarchive\fP(3) diff --git a/thirdparty/libarchive/doc/man/archive_entry_paths.3 b/thirdparty/libarchive/doc/man/archive_entry_paths.3 deleted file mode 100644 index 3aa1c726b..000000000 --- a/thirdparty/libarchive/doc/man/archive_entry_paths.3 +++ /dev/null @@ -1,188 +0,0 @@ -.TH ARCHIVE_ENTRY_PATHS 3 "February 2, 2012" "" -.SH NAME -.ad l -\fB\%archive_entry_hardlink\fP, -\fB\%archive_entry_hardlink_w\fP, -\fB\%archive_entry_set_hardlink\fP, -\fB\%archive_entry_copy_hardlink\fP, -\fB\%archive_entry_copy_hardlink_w\fP, -\fB\%archive_entry_update_hardlink_utf8\fP, -\fB\%archive_entry_set_link\fP, -\fB\%archive_entry_copy_link\fP, -\fB\%archive_entry_copy_link_w\fP, -\fB\%archive_entry_update_link_utf8\fP, -\fB\%archive_entry_pathname\fP, -\fB\%archive_entry_pathname_w\fP, -\fB\%archive_entry_set_pathname\fP, -\fB\%archive_entry_copy_pathname\fP, -\fB\%archive_entry_copy_pathname_w\fP, -\fB\%archive_entry_update_pathname_utf8\fP, -\fB\%archive_entry_sourcepath\fP, -\fB\%archive_entry_copy_sourcepath\fP, -\fB\%archive_entry_symlink\fP, -\fB\%archive_entry_symlink_w\fP, -\fB\%archive_entry_set_symlink\fP, -\fB\%archive_entry_copy_symlink\fP, -\fB\%archive_entry_copy_symlink_w\fP, -\fB\%archive_entry_update_symlink_utf8\fP -\- functions for manipulating path names in archive entry descriptions -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIconst char *\fP -.br -\fB\%archive_entry_hardlink\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIconst wchar_t *\fP -.br -\fB\%archive_entry_hardlink_w\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_set_hardlink\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%const\ char\ *path\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_copy_hardlink\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%const\ char\ *path\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_copy_hardlink_w\fP(\fI\%struct\ archive_entry\ *a\ \fP, \fI\%const\fP, \fI\%wchar_t\fP, \fI\%*path"\fP); -.br -\fIint\fP -.br -\fB\%archive_entry_update_hardlink_utf8\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%const\ char\ *path\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_set_link\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%const\ char\ *path\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_copy_link\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%\ const\ char\ *path\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_copy_link_w\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%\ const\ wchar_t\ *path\fP); -.br -\fIint\fP -.br -\fB\%archive_entry_update_link_utf8\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%\ const\ char\ *path\fP); -.br -\fIconst char *\fP -.br -\fB\%archive_entry_pathname\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIconst wchar_t *\fP -.br -\fB\%archive_entry_pathname_w\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_set_pathname\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%const\ char\ *path\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_copy_pathname\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%const\ char\ *path\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_copy_pathname_w\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%const\ wchar_t\ *path\fP); -.br -\fIint\fP -.br -\fB\%archive_entry_update_pathname_utf8\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%const\ char\ *path\fP); -.br -\fIconst char *\fP -.br -\fB\%archive_entry_sourcepath\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_copy_sourcepath\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%const\ char\ *path\fP); -.br -\fIconst char *\fP -.br -\fB\%archive_entry_symlink\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIconst wchar_t *\fP -.br -\fB\%archive_entry_symlink_w\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_set_symlink\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%const\ char\ *path\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_copy_symlink\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%const\ char\ *path\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_copy_symlink_w\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%const\ wchar_t\ *path\fP); -.br -\fIint\fP -.br -\fB\%archive_entry_update_symlink_utf8\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%const\ char\ *path\fP); -.SH DESCRIPTION -.ad l -Path names supported by -\fBarchive_entry\fP(3): -.RS 5 -.TP -hardlink -Destination of the hardlink. -.TP -link -Update only. -For a symlink, update the destination. -Otherwise, make the entry a hardlink and alter -the destination for that. -.TP -pathname -Path in the archive -.TP -sourcepath -Path on the disk for use by -\fBarchive_read_disk\fP(3). -.TP -symlink -Destination of the symbolic link. -.RE -.PP -Path names can be provided in one of three different ways: -.RS 5 -.TP -char * -Multibyte strings in the current locale. -.TP -wchar_t * -Wide character strings in the current locale. -The accessor functions are named -\fB\%XXX_w\fP(). -.TP -UTF-8 -Unicode strings encoded as UTF-8. -These are convenience functions to update both the multibyte and wide -character strings at the same time. -.RE -.PP -The sourcepath is a pure filesystem concept and never stored in an -archive directly. -.PP -For that reason, it is only available as multibyte string. -The link path is a convenience function for conditionally setting -hardlink or symlink destination. -It doesn't have a corresponding get accessor function. -.PP -\fB\%archive_entry_set_XXX\fP() -is an alias for -\fB\%archive_entry_copy_XXX\fP(). -.SH SEE ALSO -.ad l -\fBarchive_entry\fP(3), -\fBlibarchive\fP(3) diff --git a/thirdparty/libarchive/doc/man/archive_entry_perms.3 b/thirdparty/libarchive/doc/man/archive_entry_perms.3 deleted file mode 100644 index 3660b5146..000000000 --- a/thirdparty/libarchive/doc/man/archive_entry_perms.3 +++ /dev/null @@ -1,231 +0,0 @@ -.TH ARCHIVE_ENTRY_PERMS 3 "February 2, 2012" "" -.SH NAME -.ad l -\fB\%archive_entry_gid\fP, -\fB\%archive_entry_set_gid\fP, -\fB\%archive_entry_uid\fP, -\fB\%archive_entry_set_uid\fP, -\fB\%archive_entry_perm\fP, -\fB\%archive_entry_set_perm\fP, -\fB\%archive_entry_strmode\fP, -\fB\%archive_entry_uname\fP, -\fB\%archive_entry_uname_w\fP, -\fB\%archive_entry_set_uname\fP, -\fB\%archive_entry_copy_uname\fP, -\fB\%archive_entry_copy_uname_w\fP, -\fB\%archive_entry_update_uname_utf8\fP, -\fB\%archive_entry_gname\fP, -\fB\%archive_entry_gname_w\fP, -\fB\%archive_entry_set_gname\fP, -\fB\%archive_entry_copy_gname\fP, -\fB\%archive_entry_copy_gname_w\fP, -\fB\%archive_entry_update_gname_utf8\fP, -\fB\%archive_entry_fflags\fP, -\fB\%archive_entry_fflags_text\fP, -\fB\%archive_entry_set_fflags\fP, -\fB\%archive_entry_copy_fflags_text\fP, -\fB\%archive_entry_copy_fflags_text_w\fP -\- functions for manipulating ownership and permissions in archive entry descriptions -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIgid_t\fP -.br -\fB\%archive_entry_gid\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_set_gid\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%gid_t\ gid\fP); -.br -\fIuid_t\fP -.br -\fB\%archive_entry_uid\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_set_uid\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%uid_t\ uid\fP); -.br -\fImode_t\fP -.br -\fB\%archive_entry_perm\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_set_perm\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%mode_t\ mode\fP); -.br -\fIconst char *\fP -.br -\fB\%archive_entry_strmode\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIconst char *\fP -.br -\fB\%archive_entry_gname\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIconst wchar_t *\fP -.br -\fB\%archive_entry_gname_w\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_set_gname\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%const\ char\ *a\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_copy_gname\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%const\ char\ *name\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_copy_gname_w\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%const\ wchar_t\ *name\fP); -.br -\fIint\fP -.br -\fB\%archive_entry_update_gname_utf8\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%const\ char\ *name\fP); -.br -\fIconst char *\fP -.br -\fB\%archive_entry_uname\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIconst wchar_t *\fP -.br -\fB\%archive_entry_uname_w\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_set_uname\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%const\ char\ *name\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_copy_uname\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%const\ char\ *name\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_copy_uname_w\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%const\ wchar_t\ *name\fP); -.br -\fIint\fP -.br -\fB\%archive_entry_update_uname_utf8\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%const\ char\ *name\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_fflags\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%unsigned\ long\ *set_bits\fP, \fI\%unsigned\ long\ *clear_bits\fP); -.br -\fIconst char *\fP -.br -\fB\%archive_entry_fflags_text\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_set_fflags\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%unsigned\ long\ set_bits\fP, \fI\%unsigned\ long\ clear_bits\fP); -.br -\fIconst char *\fP -.br -\fB\%archive_entry_copy_fflags_text\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%const\ char\ *text\fP); -.br -\fIconst wchar_t *\fP -.br -\fB\%archive_entry_copy_fflags_text_w\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%const\ wchar_t\ *text\fP); -.SH DESCRIPTION -.ad l -.SS User id, group id and mode -The functions -\fB\%archive_entry_uid\fP(), -\fB\%archive_entry_gid\fP(), -and -\fB\%archive_entry_perm\fP() -can be used to extract the user id, group id and permission from the given entry. -The corresponding functions -\fB\%archive_entry_set_uid\fP(), -\fB\%archive_entry_set_gid\fP(), -and -\fB\%archive_entry_set_perm\fP() -store the given user id, group id and permission in the entry. -The permission is also set as a side effect of calling -\fB\%archive_entry_set_mode\fP(). -.PP -\fB\%archive_entry_strmode\fP() -returns a string representation of the permission as used by the long mode of -\fBls\fP(1). -.SS User and group name -User and group names can be provided in one of three different ways: -.RS 5 -.TP -char * -Multibyte strings in the current locale. -.TP -wchar_t * -Wide character strings in the current locale. -The accessor functions are named -\fB\%XXX_w\fP(). -.TP -UTF-8 -Unicode strings encoded as UTF-8. -These are convenience functions to update both the multibyte and wide -character strings at the same time. -.RE -.PP -\fB\%archive_entry_set_XXX\fP() -is an alias for -\fB\%archive_entry_copy_XXX\fP(). -.SS File Flags -File flags are transparently converted between a bitmap -representation and a textual format. -For example, if you set the bitmap and ask for text, the library -will build a canonical text format. -However, if you set a text format and request a text format, -you will get back the same text, even if it is ill-formed. -If you need to canonicalize a textual flags string, you should first set the -text form, then request the bitmap form, then use that to set the bitmap form. -Setting the bitmap format will clear the internal text representation -and force it to be reconstructed when you next request the text form. -.PP -The bitmap format consists of two integers, one containing bits -that should be set, the other specifying bits that should be -cleared. -Bits not mentioned in either bitmap will be ignored. -Usually, the bitmap of bits to be cleared will be set to zero. -In unusual circumstances, you can force a fully-specified set -of file flags by setting the bitmap of flags to clear to the complement -of the bitmap of flags to set. -(This differs from -\fBfflagstostr\fP(3), -which only includes names for set bits.) -Converting a bitmap to a textual string is a platform-specific -operation; bits that are not meaningful on the current platform -will be ignored. -.PP -The canonical text format is a comma-separated list of flag names. -The -\fB\%archive_entry_copy_fflags_text\fP() -and -\fB\%archive_entry_copy_fflags_text_w\fP() -functions parse the provided text and set the internal bitmap values. -This is a platform-specific operation; names that are not meaningful -on the current platform will be ignored. -The function returns a pointer to the start of the first name that was not -recognized, or NULL if every name was recognized. -Note that every name \(em including names that follow an unrecognized -name \(em will be evaluated, and the bitmaps will be set to reflect -every name that is recognized. -(In particular, this differs from -\fBstrtofflags\fP(3), -which stops parsing at the first unrecognized name.) -.SH SEE ALSO -.ad l -\fBarchive_entry\fP(3), -\fBarchive_entry_acl\fP(3), -\fBarchive_read_disk\fP(3), -\fBarchive_write_disk\fP(3), -\fBlibarchive\fP(3) -.SH BUGS -.ad l -The platform types -Vt uid_t -and -Vt gid_t -are often 16 or 32 bit wide. -In this case it is possible that the ids can not be correctly restored -from archives and get truncated. diff --git a/thirdparty/libarchive/doc/man/archive_entry_stat.3 b/thirdparty/libarchive/doc/man/archive_entry_stat.3 deleted file mode 100644 index b482782bf..000000000 --- a/thirdparty/libarchive/doc/man/archive_entry_stat.3 +++ /dev/null @@ -1,320 +0,0 @@ -.TH ARCHIVE_ENTRY_STAT 3 "February 2, 2012" "" -.SH NAME -.ad l -\fB\%archive_entry_stat\fP, -\fB\%archive_entry_copy_stat\fP, -\fB\%archive_entry_filetype\fP, -\fB\%archive_entry_set_filetype\fP, -\fB\%archive_entry_mode\fP, -\fB\%archive_entry_set_mode\fP, -\fB\%archive_entry_size\fP, -\fB\%archive_entry_size_is_set\fP, -\fB\%archive_entry_set_size\fP, -\fB\%archive_entry_unset_size\fP, -\fB\%archive_entry_dev\fP, -\fB\%archive_entry_set_dev\fP, -\fB\%archive_entry_dev_is_set\fP, -\fB\%archive_entry_devmajor\fP, -\fB\%archive_entry_set_devmajor\fP, -\fB\%archive_entry_devminor\fP, -\fB\%archive_entry_set_devminor\fP, -\fB\%archive_entry_ino\fP, -\fB\%archive_entry_set_ino\fP, -\fB\%archive_entry_ino_is_set\fP, -\fB\%archive_entry_ino64\fP, -\fB\%archive_entry_set_ino64\fP, -\fB\%archive_entry_nlink\fP, -\fB\%archive_entry_rdev\fP, -\fB\%archive_entry_set_rdev\fP, -\fB\%archive_entry_rdevmajor\fP, -\fB\%archive_entry_set_rdevmajor\fP, -\fB\%archive_entry_rdevminor\fP, -\fB\%archive_entry_set_rdevminor\fP -\- accessor functions for manipulating archive entry descriptions -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIconst struct stat *\fP -.br -\fB\%archive_entry_stat\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_copy_stat\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%const\ struct\ stat\ *sb\fP); -.br -\fImode_t\fP -.br -\fB\%archive_entry_filetype\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_set_filetype\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%unsigned\ int\ type\fP); -.br -\fImode_t\fP -.br -\fB\%archive_entry_mode\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_set_mode\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%mode_t\ mode\fP); -.br -\fIint64_t\fP -.br -\fB\%archive_entry_size\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIint\fP -.br -\fB\%archive_entry_size_is_set\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_set_size\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%int64_t\ size\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_unset_size\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIdev_t\fP -.br -\fB\%archive_entry_dev\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_set_dev\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%dev_t\ dev\fP); -.br -\fIint\fP -.br -\fB\%archive_entry_dev_is_set\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIdev_t\fP -.br -\fB\%archive_entry_devmajor\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_set_devmajor\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%dev_t\ major\fP); -.br -\fIdev_t\fP -.br -\fB\%archive_entry_devminor\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_set_devminor\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%dev_t\ minor\fP); -.br -\fIino_t\fP -.br -\fB\%archive_entry_ino\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_set_ino\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%unsigned\ long\ ino\fP); -.br -\fIint\fP -.br -\fB\%archive_entry_ino_is_set\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIint64_t\fP -.br -\fB\%archive_entry_ino64\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_set_ino64\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%int64_t\ ino\fP); -.br -\fIunsigned int\fP -.br -\fB\%archive_entry_nlink\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_set_nlink\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%unsigned\ int\ count\fP); -.br -\fIdev_t\fP -.br -\fB\%archive_entry_rdev\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIdev_t\fP -.br -\fB\%archive_entry_rdevmajor\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIdev_t\fP -.br -\fB\%archive_entry_rdevminor\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_set_rdev\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%dev_t\ dev\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_set_rdevmajor\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%dev_t\ major\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_set_rdevminor\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%dev_t\ minor\fP); -.SH DESCRIPTION -.ad l -.SS Copying to and from Vt struct stat -The function -\fB\%archive_entry_stat\fP() -converts the various fields stored in the archive entry to the format -used by -\fBstat\fP(2). -The return value remains valid until either -\fB\%archive_entry_clear\fP() -or -\fB\%archive_entry_free\fP() -is called. -It is not affected by calls to the set accessor functions. -It currently sets the following values in -Vt struct stat: -Vt st_atime, -Vt st_ctime, -Vt st_dev, -Vt st_gid, -Vt st_ino, -Vt st_mode, -Vt st_mtime, -Vt st_nlink, -Vt st_rdev, -Vt st_size, -Vt st_uid. -In addition, -Vt st_birthtime -and high-precision information for time-related fields -will be included on platforms that support it. -.PP -The function -\fB\%archive_entry_copy_stat\fP() -copies fields from the platform's -Vt struct stat. -Fields not provided by -Vt struct stat -are unchanged. -.SS General accessor functions -The functions -\fB\%archive_entry_filetype\fP() -and -\fB\%archive_entry_set_filetype\fP() -get respectively set the filetype. -The file type is one of the following constants: -.RS 5 -.TP -AE_IFREG -Regular file -.TP -AE_IFLNK -Symbolic link -.TP -AE_IFSOCK -Socket -.TP -AE_IFCHR -Character device -.TP -AE_IFBLK -Block device -.TP -AE_IFDIR -Directory -.TP -AE_IFIFO -Named pipe (fifo) -.RE -Not all file types are supported by all platforms. -The constants used by -\fBstat\fP(2) -may have different numeric values from the -corresponding constants above. -.PP -The functions -\fB\%archive_entry_mode\fP() -and -\fB\%archive_entry_set_mode\fP() -get/set a combination of file type and permissions and provide the -equivalent of -\fIst_mode\fP. -Use of -\fB\%archive_entry_filetype\fP() -and -\fB\%archive_entry_perm\fP() -for getting and -\fB\%archive_entry_set_filetype\fP() -and -\fB\%archive_entry_set_perm\fP() -for setting is recommended. -.PP -The function -\fB\%archive_entry_size\fP() -returns the file size, if it has been set, and 0 otherwise. -\fB\%archive_entry_size\fP() -can be used to query that status. -\fB\%archive_entry_set_size\fP() -and -\fB\%archive_entry_unset_size\fP() -set and unset the size, respectively. -.PP -The number of references (hardlinks) can be obtained by calling -\fB\%archive_entry_nlink\fP() -and set with -\fB\%archive_entry_set_nlink\fP(). -.SS Identifying unique files -The functions -\fB\%archive_entry_dev\fP() -and -\fB\%archive_entry_ino64\fP() -are used by -\fBarchive_entry_linkify\fP(3) -to find hardlinks. -The pair of device and inode is supposed to identify hardlinked files. -.PP -The device major and minor number can be obtained independently using -\fB\%archive_entry_devmajor\fP() -and -\fB\%archive_entry_devminor\fP(). -The device can be set either via -\fB\%archive_entry_set_dev\fP() -or by the combination of major and minor number using -\fB\%archive_entry_set_devmajor\fP() -and -\fB\%archive_entry_set_devminor\fP(). -.PP -The inode number can be obtained using -\fB\%archive_entry_ino\fP(). -This is a legacy interface that uses the platform -Vt ino_t, -which may be very small. -To set the inode number, -\fB\%archive_entry_set_ino64\fP() -is the preferred interface. -.SS Accessor functions for block and character devices -Block and character devices are characterised either using a device number -or a pair of major and minor number. -The combined device number can be obtained with -\fB\%archive_device_rdev\fP() -and set with -\fB\%archive_device_set_rdev\fP(). -The major and minor numbers are accessed by -\fB\%archive_device_rdevmajor\fP(), -\fB\%archive_device_rdevminor\fP() -\fB\%archive_device_set_rdevmajor\fP() -and -\fB\%archive_device_set_rdevminor\fP(). -.PP -The process of splitting the combined device number into major and -minor number and the reverse process of combing them differs between -platforms. -Some archive formats use the combined form, while other formats use -the split form. -.SH SEE ALSO -.ad l -\fBstat\fP(2), -\fBarchive_entry_acl\fP(3), -\fBarchive_entry_perms\fP(3), -\fBarchive_entry_time\fP(3), -\fBlibarchive\fP(3) diff --git a/thirdparty/libarchive/doc/man/archive_entry_time.3 b/thirdparty/libarchive/doc/man/archive_entry_time.3 deleted file mode 100644 index 77f78f074..000000000 --- a/thirdparty/libarchive/doc/man/archive_entry_time.3 +++ /dev/null @@ -1,146 +0,0 @@ -.TH ARCHIVE_ENTRY_TIME 3 "February 2, 2012" "" -.SH NAME -.ad l -\fB\%archive_entry_atime\fP, -\fB\%archive_entry_atime_nsec\fP, -\fB\%archive_entry_atime_is_set\fP, -\fB\%archive_entry_set_atime\fP, -\fB\%archive_entry_unset_atime\fP, -\fB\%archive_entry_birthtime\fP, -\fB\%archive_entry_birthtime_nsec\fP, -\fB\%archive_entry_birthtime_is_set\fP, -\fB\%archive_entry_set_birthtime\fP, -\fB\%archive_entry_unset_birthtime\fP, -\fB\%archive_entry_ctime\fP, -\fB\%archive_entry_ctime_nsec\fP, -\fB\%archive_entry_ctime_is_set\fP, -\fB\%archive_entry_set_ctime\fP, -\fB\%archive_entry_unset_ctime\fP, -\fB\%archive_entry_mtime\fP, -\fB\%archive_entry_mtime_nsec\fP, -\fB\%archive_entry_mtime_is_set\fP, -\fB\%archive_entry_set_mtime\fP, -\fB\%archive_entry_unset_mtime\fP -\- functions for manipulating times in archive entry descriptions -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fItime_t\fP -.br -\fB\%archive_entry_atime\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIlong\fP -.br -\fB\%archive_entry_atime_nsec\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIint\fP -.br -\fB\%archive_entry_atime_is_set\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_set_atime\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%time_t\ sec\fP, \fI\%long\ nanosec\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_unset_atime\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fItime_t\fP -.br -\fB\%archive_entry_birthtime\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIlong\fP -.br -\fB\%archive_entry_birthtime_nsec\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIint\fP -.br -\fB\%archive_entry_birthtime_is_set\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_set_birthtime\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%time_t\ sec\fP, \fI\%long\ nanosec\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_unset_birthtime\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fItime_t\fP -.br -\fB\%archive_entry_ctime\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIlong\fP -.br -\fB\%archive_entry_ctime_nsec\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIint\fP -.br -\fB\%archive_entry_ctime_is_set\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_set_ctime\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%time_t\ sec\fP, \fI\%long\ nanosec\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_unset_ctime\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fItime_t\fP -.br -\fB\%archive_entry_mtime\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIlong\fP -.br -\fB\%archive_entry_mtime_nsec\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIint\fP -.br -\fB\%archive_entry_mtime_is_set\fP(\fI\%struct\ archive_entry\ *a\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_set_mtime\fP(\fI\%struct\ archive_entry\ *a\fP, \fI\%time_t\ sec\fP, \fI\%long\ nanosec\fP); -.br -\fIvoid\fP -.br -\fB\%archive_entry_unset_mtime\fP(\fI\%struct\ archive_entry\ *a\fP); -.SH DESCRIPTION -.ad l -These functions create and manipulate the time fields in an -Vt archive_entry. -Supported time fields are atime (access time), birthtime (creation time), -ctime (last time an inode property was changed) and mtime (modification time). -.PP -\fBlibarchive\fP(3) -provides a high-resolution interface. -The timestamps are truncated automatically depending on the archive format -(for archiving) or the filesystem capabilities (for restoring). -.PP -All timestamp fields are optional. -The -\fB\%XXX_unset\fP() -functions can be used to mark the corresponding field as missing. -The current state can be queried using -\fB\%XXX_is_set\fP(). -Unset time fields have a second and nanosecond field of 0. -.SH SEE ALSO -.ad l -\fBarchive_entry\fP(3), -\fBlibarchive\fP(3) -.SH HISTORY -.ad l -The -\fB\%libarchive\fP -library first appeared in -FreeBSD 5.3. -.SH AUTHORS -.ad l --nosplit -The -\fB\%libarchive\fP -library was written by -Tim Kientzle \% diff --git a/thirdparty/libarchive/doc/man/archive_read.3 b/thirdparty/libarchive/doc/man/archive_read.3 deleted file mode 100644 index 18fd3e4a8..000000000 --- a/thirdparty/libarchive/doc/man/archive_read.3 +++ /dev/null @@ -1,219 +0,0 @@ -.TH ARCHIVE_READ 3 "February 2, 2012" "" -.SH NAME -.ad l -\fB\%archive_read\fP -\- functions for reading streaming archives -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.SH DESCRIPTION -.ad l -These functions provide a complete API for reading streaming archives. -The general process is to first create the -Tn struct archive -object, set options, initialize the reader, iterate over the archive -headers and associated data, then close the archive and release all -resources. -.SS Create archive object -See -\fBarchive_read_new\fP(3). -.PP -To read an archive, you must first obtain an initialized -Tn struct archive -object from -\fB\%archive_read_new\fP(). -.SS Enable filters and formats -See -\fBarchive_read_filter\fP(3) -and -\fBarchive_read_format\fP(3). -.PP -You can then modify this object for the desired operations with the -various -\fB\%archive_read_set_XXX\fP() -and -\fB\%archive_read_support_XXX\fP() -functions. -In particular, you will need to invoke appropriate -\fB\%archive_read_support_XXX\fP() -functions to enable the corresponding compression and format -support. -Note that these latter functions perform two distinct operations: -they cause the corresponding support code to be linked into your -program, and they enable the corresponding auto-detect code. -Unless you have specific constraints, you will generally want -to invoke -\fB\%archive_read_support_filter_all\fP() -and -\fB\%archive_read_support_format_all\fP() -to enable auto-detect for all formats and compression types -currently supported by the library. -.SS Set options -See -\fBarchive_read_set_options\fP(3). -.SS Open archive -See -\fBarchive_read_open\fP(3). -.PP -Once you have prepared the -Tn struct archive -object, you call -\fB\%archive_read_open\fP() -to actually open the archive and prepare it for reading. -There are several variants of this function; -the most basic expects you to provide pointers to several -functions that can provide blocks of bytes from the archive. -There are convenience forms that allow you to -specify a filename, file descriptor, -\fIFILE *\fP -object, or a block of memory from which to read the archive data. -Note that the core library makes no assumptions about the -size of the blocks read; -callback functions are free to read whatever block size is -most appropriate for the medium. -.SS Consume archive -See -\fBarchive_read_header\fP(3), -\fBarchive_read_data\fP(3) -and -\fBarchive_read_extract\fP(3). -.PP -Each archive entry consists of a header followed by a certain -amount of data. -You can obtain the next header with -\fB\%archive_read_next_header\fP(), -which returns a pointer to an -Tn struct archive_entry -structure with information about the current archive element. -If the entry is a regular file, then the header will be followed -by the file data. -You can use -\fB\%archive_read_data\fP() -(which works much like the -\fBread\fP(2) -system call) -to read this data from the archive, or -\fB\%archive_read_data_block\fP() -which provides a slightly more efficient interface. -You may prefer to use the higher-level -\fB\%archive_read_data_skip\fP(), -which reads and discards the data for this entry, -\fB\%archive_read_data_into_fd\fP(), -which copies the data to the provided file descriptor, or -\fB\%archive_read_extract\fP(), -which recreates the specified entry on disk and copies data -from the archive. -In particular, note that -\fB\%archive_read_extract\fP() -uses the -Tn struct archive_entry -structure that you provide it, which may differ from the -entry just read from the archive. -In particular, many applications will want to override the -pathname, file permissions, or ownership. -.SS Release resources -See -\fBarchive_read_free\fP(3). -.PP -Once you have finished reading data from the archive, you -should call -\fB\%archive_read_close\fP() -to close the archive, then call -\fB\%archive_read_free\fP() -to release all resources, including all memory allocated by the library. -.SH EXAMPLES -.ad l -The following illustrates basic usage of the library. -In this example, -the callback functions are simply wrappers around the standard -\fBopen\fP(2), -\fBread\fP(2), -and -\fBclose\fP(2) -system calls. -.RS 4 -.nf -void -list_archive(const char *name) -{ - struct mydata *mydata; - struct archive *a; - struct archive_entry *entry; - mydata = malloc(sizeof(struct mydata)); - a = archive_read_new(); - mydata->name = name; - archive_read_support_filter_all(a); - archive_read_support_format_all(a); - archive_read_open(a, mydata, myopen, myread, myclose); - while (archive_read_next_header(a, &entry) == ARCHIVE_OK) { - printf("%s\en",archive_entry_pathname(entry)); - archive_read_data_skip(a); - } - archive_read_free(a); - free(mydata); -} -la_ssize_t -myread(struct archive *a, void *client_data, const void **buff) -{ - struct mydata *mydata = client_data; - *buff = mydata->buff; - return (read(mydata->fd, mydata->buff, 10240)); -} -int -myopen(struct archive *a, void *client_data) -{ - struct mydata *mydata = client_data; - mydata->fd = open(mydata->name, O_RDONLY); - return (mydata->fd >= 0 ? ARCHIVE_OK : ARCHIVE_FATAL); -} -int -myclose(struct archive *a, void *client_data) -{ - struct mydata *mydata = client_data; - if (mydata->fd > 0) - close(mydata->fd); - return (ARCHIVE_OK); -} -.RE -.SH SEE ALSO -.ad l -\fBtar\fP(1), -\fBarchive_read_data\fP(3), -\fBarchive_read_extract\fP(3), -\fBarchive_read_filter\fP(3), -\fBarchive_read_format\fP(3), -\fBarchive_read_header\fP(3), -\fBarchive_read_new\fP(3), -\fBarchive_read_open\fP(3), -\fBarchive_read_set_options\fP(3), -\fBarchive_util\fP(3), -\fBlibarchive\fP(3), -\fBtar\fP(5) -.SH HISTORY -.ad l -The -\fB\%libarchive\fP -library first appeared in -FreeBSD 5.3. -.SH AUTHORS -.ad l --nosplit -The -\fB\%libarchive\fP -library was written by -Tim Kientzle \% -.SH BUGS -.ad l -Many traditional archiver programs treat -empty files as valid empty archives. -For example, many implementations of -\fBtar\fP(1) -allow you to append entries to an empty file. -Of course, it is impossible to determine the format of an empty file -by inspecting the contents, so this library treats empty files as -having a special -``empty'' -format. diff --git a/thirdparty/libarchive/doc/man/archive_read_add_passphrase.3 b/thirdparty/libarchive/doc/man/archive_read_add_passphrase.3 deleted file mode 100644 index 054fa79e5..000000000 --- a/thirdparty/libarchive/doc/man/archive_read_add_passphrase.3 +++ /dev/null @@ -1,49 +0,0 @@ -.TH ARCHIVE_READ_ADD_PASSPHRASE 3 "September 14, 2014" "" -.SH NAME -.ad l -\fB\%archive_read_add_passphrase\fP, -\fB\%archive_read_set_passphrase_callback\fP -\- functions for reading encrypted archives -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIint\fP -.br -\fB\%archive_read_add_passphrase\fP(\fI\%struct\ archive\ *\fP, \fI\%const\ char\ *passphrase\fP); -.br -\fIint\fP -.br -\fB\%archive_read_set_passphrase_callback\fP(\fI\%struct\ archive\ *\fP, \fI\%void\ *client_data\fP, \fI\%archive_passphrase_callback\ *\fP); -.SH DESCRIPTION -.ad l -.RS 5 -.TP -\fB\%archive_read_add_passphrase\fP() -Register passphrases for reading an encryption archive. -If -\fIpassphrase\fP -is -.BR NULL -or empty, this function will do nothing and -\fBARCHIVE_FAILED\fP -will be returned. -Otherwise, -\fBARCHIVE_OK\fP -will be returned. -.TP -\fB\%archive_read_set_passphrase_callback\fP() -Register a callback function that will be invoked to get a passphrase -for decryption after trying all the passphrases registered by the -\fB\%archive_read_add_passphrase\fP() -function failed. -.RE -.SH SEE ALSO -.ad l -\fBtar\fP(1), -\fBarchive_read\fP(3), -\fBarchive_read_set_options\fP(3), -\fBlibarchive\fP(3) diff --git a/thirdparty/libarchive/doc/man/archive_read_data.3 b/thirdparty/libarchive/doc/man/archive_read_data.3 deleted file mode 100644 index c0e9bfa85..000000000 --- a/thirdparty/libarchive/doc/man/archive_read_data.3 +++ /dev/null @@ -1,112 +0,0 @@ -.TH ARCHIVE_READ_DATA 3 "February 2, 2012" "" -.SH NAME -.ad l -\fB\%archive_read_data\fP, -\fB\%archive_read_data_block\fP, -\fB\%archive_read_data_skip\fP, -\fB\%archive_read_data_into_fd\fP -\- functions for reading streaming archives -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIla_ssize_t\fP -.br -\fB\%archive_read_data\fP(\fI\%struct\ archive\ *\fP, \fI\%void\ *buff\fP, \fI\%size_t\ len\fP); -.br -\fIint\fP -.br -\fB\%archive_read_data_block\fP(\fI\%struct\ archive\ *\fP, \fI\%const\ void\ **buff\fP, \fI\%size_t\ *len\fP, \fI\%off_t\ *offset\fP); -.br -\fIint\fP -.br -\fB\%archive_read_data_skip\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_data_into_fd\fP(\fI\%struct\ archive\ *\fP, \fI\%int\ fd\fP); -.SH DESCRIPTION -.ad l -.RS 5 -.TP -\fB\%archive_read_data\fP() -Read data associated with the header just read. -Internally, this is a convenience function that calls -\fB\%archive_read_data_block\fP() -and fills any gaps with nulls so that callers see a single -continuous stream of data. -.TP -\fB\%archive_read_data_block\fP() -Return the next available block of data for this entry. -Unlike -\fB\%archive_read_data\fP(), -the -\fB\%archive_read_data_block\fP() -function avoids copying data and allows you to correctly handle -sparse files, as supported by some archive formats. -The library guarantees that offsets will increase and that blocks -will not overlap. -Note that the blocks returned from this function can be much larger -than the block size read from disk, due to compression -and internal buffer optimizations. -.TP -\fB\%archive_read_data_skip\fP() -A convenience function that repeatedly calls -\fB\%archive_read_data_block\fP() -to skip all of the data for this archive entry. -Note that this function is invoked automatically by -\fB\%archive_read_next_header2\fP() -if the previous entry was not completely consumed. -.TP -\fB\%archive_read_data_into_fd\fP() -A convenience function that repeatedly calls -\fB\%archive_read_data_block\fP() -to copy the entire entry to the provided file descriptor. -.RE -.SH RETURN VALUES -.ad l -Most functions return zero on success, non-zero on error. -The possible return codes include: -\fBARCHIVE_OK\fP -(the operation succeeded), -\fBARCHIVE_WARN\fP -(the operation succeeded but a non-critical error was encountered), -\fBARCHIVE_EOF\fP -(end-of-archive was encountered), -\fBARCHIVE_RETRY\fP -(the operation failed but can be retried), -and -\fBARCHIVE_FATAL\fP -(there was a fatal error; the archive should be closed immediately). -.PP -\fB\%archive_read_data\fP() -returns a count of bytes actually read or zero at the end of the entry. -On error, a value of -\fBARCHIVE_FATAL\fP, -\fBARCHIVE_WARN\fP, -or -\fBARCHIVE_RETRY\fP -is returned. -.SH ERRORS -.ad l -Detailed error codes and textual descriptions are available from the -\fB\%archive_errno\fP() -and -\fB\%archive_error_string\fP() -functions. -.SH SEE ALSO -.ad l -\fBtar\fP(1), -\fBarchive_read\fP(3), -\fBarchive_read_extract\fP(3), -\fBarchive_read_filter\fP(3), -\fBarchive_read_format\fP(3), -\fBarchive_read_header\fP(3), -\fBarchive_read_open\fP(3), -\fBarchive_read_set_options\fP(3), -\fBarchive_util\fP(3), -\fBlibarchive\fP(3), -\fBtar\fP(5) diff --git a/thirdparty/libarchive/doc/man/archive_read_disk.3 b/thirdparty/libarchive/doc/man/archive_read_disk.3 deleted file mode 100644 index 9d8931625..000000000 --- a/thirdparty/libarchive/doc/man/archive_read_disk.3 +++ /dev/null @@ -1,439 +0,0 @@ -.TH ARCHIVE_READ_DISK 3 "April 3, 2017" "" -.SH NAME -.ad l -\fB\%archive_read_disk_new\fP, -\fB\%archive_read_disk_open\fP, -\fB\%archive_read_disk_open_w\fP, -\fB\%archive_read_disk_set_behavior\fP, -\fB\%archive_read_disk_set_symlink_logical\fP, -\fB\%archive_read_disk_set_symlink_physical\fP, -\fB\%archive_read_disk_set_symlink_hybrid\fP, -\fB\%archive_read_disk_entry_from_file\fP, -\fB\%archive_read_disk_gname\fP, -\fB\%archive_read_disk_uname\fP, -\fB\%archive_read_disk_set_uname_lookup\fP, -\fB\%archive_read_disk_set_gname_lookup\fP, -\fB\%archive_read_disk_set_standard_lookup\fP, -\fB\%archive_read_disk_descend\fP, -\fB\%archive_read_disk_can_descend\fP, -\fB\%archive_read_disk_current_filesystem\fP, -\fB\%archive_read_disk_current_filesystem_is_synthetic\fP, -\fB\%archive_read_disk_current_filesystem_is_remote\fP, -\fB\%archive_read_disk_set_matching\fP, -\fB\%archive_read_disk_set_metadata_filter_callback\fP, -\- functions for reading objects from disk -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIstruct archive *\fP -.br -\fB\%archive_read_disk_new\fP(\fI\%void\fP); -.br -\fIint\fP -.br -\fB\%archive_read_disk_open\fP(\fI\%struct\ archive\ *\fP, \fI\%const\ char\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_disk_open_w\fP(\fI\%struct\ archive\ *\fP, \fI\%const\ wchar_t\ *\fP, \fI\%\fP); -.br -\fIint\fP -.br -\fB\%archive_read_disk_set_behavior\fP(\fI\%struct\ archive\ *\fP, \fI\%int\fP); -.br -\fIint\fP -.br -\fB\%archive_read_disk_set_symlink_logical\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_disk_set_symlink_physical\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_disk_set_symlink_hybrid\fP(\fI\%struct\ archive\ *\fP); -.br -\fIconst char *\fP -.br -\fB\%archive_read_disk_gname\fP(\fI\%struct\ archive\ *\fP, \fI\%gid_t\fP); -.br -\fIconst char *\fP -.br -\fB\%archive_read_disk_uname\fP(\fI\%struct\ archive\ *\fP, \fI\%uid_t\fP); -.br -\fIint\fP -.br -\fB\%archive_read_disk_set_gname_lookup\fP(\fI\%struct\ archive\ *\fP, \fI\%void\ *\fP, \fI\%const\ char\ *(*lookup)(void\ *,\ gid_t)\fP, \fI\%void\ (*cleanup)(void\ *)\fP); -.br -\fIint\fP -.br -\fB\%archive_read_disk_set_uname_lookup\fP(\fI\%struct\ archive\ *\fP, \fI\%void\ *\fP, \fI\%const\ char\ *(*lookup)(void\ *,\ uid_t)\fP, \fI\%void\ (*cleanup)(void\ *)\fP); -.br -\fIint\fP -.br -\fB\%archive_read_disk_set_standard_lookup\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_disk_entry_from_file\fP(\fI\%struct\ archive\ *\fP, \fI\%struct\ archive_entry\ *\fP, \fI\%int\ fd\fP, \fI\%const\ struct\ stat\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_disk_descend\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_disk_can_descend\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_disk_current_filesystem\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_disk_current_filesystem_is_synthetic\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_disk_current_filesystem_is_remote\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_disk_set_matching\fP(\fI\%struct\ archive\ *\fP, \fI\%struct\ archive\ *\fP, \fI\%void\ (*excluded_func)(struct\ archive\ *,\ void\ *,\ struct\ archive\ entry\ *)\fP, \fI\%void\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_disk_set_metadata_filter_callback\fP(\fI\%struct\ archive\ *\fP, \fI\%int\ (*metadata_filter_func)(struct\ archive\ *,\ void*,\ struct\ archive_entry\ *)\fP, \fI\%void\ *\fP); -.SH DESCRIPTION -.ad l -These functions provide an API for reading information about -objects on disk. -In particular, they provide an interface for populating -Tn struct archive_entry -objects. -.RS 5 -.TP -\fB\%archive_read_disk_new\fP() -Allocates and initializes a -Tn struct archive -object suitable for reading object information from disk. -.TP -\fB\%archive_read_disk_open\fP() -Opens the file or directory from the given path and prepares the -Tn struct archive -to read it from disk. -.TP -\fB\%archive_read_disk_open_w\fP() -Opens the file or directory from the given path as a wide character string and prepares the -Tn struct archive -to read it from disk. -.TP -\fB\%archive_read_disk_set_behavior\fP() -Configures various behavior options when reading entries from disk. -The flags field consists of a bitwise OR of one or more of the -following values: -.RS 5 -.TP -\fBARCHIVE_READDISK_HONOR_NODUMP\fP -Skip files and directories with the nodump file attribute (file flag) set. -By default, the nodump file attribute is ignored. -.TP -\fBARCHIVE_READDISK_MAC_COPYFILE\fP -Mac OS X specific. -Read metadata (ACLs and extended attributes) with -\fBcopyfile\fP(3). -By default, metadata is read using -\fBcopyfile\fP(3). -.TP -\fBARCHIVE_READDISK_NO_ACL\fP -Do not read Access Control Lists. -By default, ACLs are read from disk. -.TP -\fBARCHIVE_READDISK_NO_FFLAGS\fP -Do not read file attributes (file flags). -By default, file attributes are read from disk. -See -\fBchattr\fP(1) -(Linux) -or -\fBchflags\fP(1) -(FreeBSD, Mac OS X) -for more information on file attributes. -.TP -\fBARCHIVE_READDISK_NO_TRAVERSE_MOUNTS\fP -Do not traverse mount points. -By default, mount points are traversed. -.TP -\fBARCHIVE_READDISK_NO_XATTR\fP -Do not read extended file attributes (xattrs). -By default, extended file attributes are read from disk. -See -\fBxattr\fP(7) -(Linux,) -\fBxattr\fP(2) -(Mac OS X,) -or -\fBgetextattr\fP(8) -(FreeBSD) -for more information on extended file attributes. -.TP -\fBARCHIVE_READDISK_RESTORE_ATIME\fP -Restore access time of traversed files. -By default, access time of traversed files is not restored. -.TP -\fBARCHIVE_READDISK_NO_SPARSE\fP -Do not read sparse file information. -By default, sparse file information is read from disk. -.RE -.TP -\fB\%archive_read_disk_set_symlink_logical\fP(), -\fB\%archive_read_disk_set_symlink_physical\fP(), -\fB\%archive_read_disk_set_symlink_hybrid\fP() -This sets the mode used for handling symbolic links. -The -``logical'' -mode follows all symbolic links. -The -``physical'' -mode does not follow any symbolic links. -The -``hybrid'' -mode currently behaves identically to the -``logical'' -mode. -.TP -\fB\%archive_read_disk_gname\fP(), -\fB\%archive_read_disk_uname\fP() -Returns a user or group name given a gid or uid value. -By default, these always return a NULL string. -.TP -\fB\%archive_read_disk_set_gname_lookup\fP(), -\fB\%archive_read_disk_set_uname_lookup\fP() -These allow you to override the functions used for -user and group name lookups. -You may also provide a -Tn void * -pointer to a private data structure and a cleanup function for -that data. -The cleanup function will be invoked when the -Tn struct archive -object is destroyed or when new lookup functions are registered. -.TP -\fB\%archive_read_disk_set_standard_lookup\fP() -This convenience function installs a standard set of user -and group name lookup functions. -These functions use -\fBgetpwuid\fP(3) -and -\fBgetgrgid\fP(3) -to convert ids to names, defaulting to NULL if the names cannot -be looked up. -These functions also implement a simple memory cache to reduce -the number of calls to -\fBgetpwuid\fP(3) -and -\fBgetgrgid\fP(3). -.TP -\fB\%archive_read_disk_entry_from_file\fP() -Populates a -Tn struct archive_entry -object with information about a particular file. -The -Tn archive_entry -object must have already been created with -\fBarchive_entry_new\fP(3) -and at least one of the source path or path fields must already be set. -(If both are set, the source path will be used.) -.PP -Information is read from disk using the path name from the -Tn struct archive_entry -object. -If a file descriptor is provided, some information will be obtained using -that file descriptor, on platforms that support the appropriate -system calls. -.PP -If a pointer to a -Tn struct stat -is provided, information from that structure will be used instead -of reading from the disk where appropriate. -This can provide performance benefits in scenarios where -Tn struct stat -information has already been read from the disk as a side effect -of some other operation. -(For example, directory traversal libraries often provide this information.) -.PP -Where necessary, user and group ids are converted to user and group names -using the currently-registered lookup functions above. -This affects the file ownership fields and ACL values in the -Tn struct archive_entry -object. -.TP -\fB\%archive_read_disk_descend\fP() -If the current entry can be descended, this function will mark the directory as the next entry for -\fBarchive_read_header\fP(3) -to visit. -.TP -\fB\%archive_read_disk_can_descend\fP() -Returns 1 if the current entry is an unvisited directory and 0 otherwise. -.TP -\fB\%archive_read_disk_current_filesystem\fP() -Returns the index of the most recent filesystem entry that has been visited through archive_read_disk -.TP -\fB\%archive_read_disk_current_filesystem_is_synthetic\fP() -Returns 1 if the current filesystem is a virtual filesystem. Returns 0 if the current filesystem is not a virtual filesystem. Returns -1 if it is unknown. -.TP -\fB\%archive_read_disk_current_filesystem_is_remote\fP() -Returns 1 if the current filesystem is a remote filesystem. Returns 0 if the current filesystem is not a remote filesystem. Returns -1 if it is unknown. -.TP -\fB\%archive_read_disk_set_matching\fP() -Allows the caller to set -Tn struct archive -*_ma to compare each entry during -\fBarchive_read_header\fP(3) -calls. If matched based on calls to -Tn archive_match_path_excluded, -Tn archive_match_time_excluded, -or -Tn archive_match_owner_excluded, -then the callback function specified by the _excluded_func parameter will execute. This function will recieve data provided to the fourth parameter, void *_client_data. -.TP -\fB\%archive_read_disk_set_metadata_filter_callback\fP() -Allows the caller to set a callback function during calls to -\fBarchive_read_header\fP(3) -to filter out metadata for each entry. The callback function recieves the -Tn struct archive -object, void* custom filter data, and the -Tn struct archive_entry. -If the callback function returns an error, ARCHIVE_RETRY will be returned and the entry will not be further processed. -.RE -More information about the -\fIstruct\fP archive -object and the overall design of the library can be found in the -\fBlibarchive\fP(3) -overview. -.SH EXAMPLES -.ad l -The following illustrates basic usage of the library by -showing how to use it to copy an item on disk into an archive. -.RS 4 -.nf -void -file_to_archive(struct archive *a, const char *name) -{ - char buff[8192]; - size_t bytes_read; - struct archive *ard; - struct archive_entry *entry; - int fd; - ard = archive_read_disk_new(); - archive_read_disk_set_standard_lookup(ard); - entry = archive_entry_new(); - fd = open(name, O_RDONLY); - if (fd < 0) - return; - archive_entry_copy_pathname(entry, name); - archive_read_disk_entry_from_file(ard, entry, fd, NULL); - archive_write_header(a, entry); - while ((bytes_read = read(fd, buff, sizeof(buff))) > 0) - archive_write_data(a, buff, bytes_read); - archive_write_finish_entry(a); - archive_read_free(ard); - archive_entry_free(entry); -} -.RE -.SH RETURN VALUES -.ad l -Most functions return -\fBARCHIVE_OK\fP -(zero) on success, or one of several negative -error codes for errors. -Specific error codes include: -\fBARCHIVE_RETRY\fP -for operations that might succeed if retried, -\fBARCHIVE_WARN\fP -for unusual conditions that do not prevent further operations, and -\fBARCHIVE_FATAL\fP -for serious errors that make remaining operations impossible. -.PP -\fB\%archive_read_disk_new\fP() -returns a pointer to a newly-allocated -Tn struct archive -object or NULL if the allocation failed for any reason. -.PP -\fB\%archive_read_disk_gname\fP() -and -\fB\%archive_read_disk_uname\fP() -return -Tn const char * -pointers to the textual name or NULL if the lookup failed for any reason. -The returned pointer points to internal storage that -may be reused on the next call to either of these functions; -callers should copy the string if they need to continue accessing it. -.SH ERRORS -.ad l -Detailed error codes and textual descriptions are available from the -\fB\%archive_errno\fP() -and -\fB\%archive_error_string\fP() -functions. -.SH SEE ALSO -.ad l -\fBtar\fP(1), -\fBarchive_read\fP(3), -\fBarchive_util\fP(3), -\fBarchive_write\fP(3), -\fBarchive_write_disk\fP(3), -\fBlibarchive\fP(3) -.SH HISTORY -.ad l -The -\fB\%libarchive\fP -library first appeared in -FreeBSD 5.3. -The -\fB\%archive_read_disk\fP -interface was added to -\fB\%libarchive\fP 2.6 -and first appeared in -FreeBSD 8.0. -.SH AUTHORS -.ad l --nosplit -The -\fB\%libarchive\fP -library was written by -Tim Kientzle \% -.SH BUGS -.ad l -The -``standard'' -user name and group name lookup functions are not the defaults because -\fBgetgrgid\fP(3) -and -\fBgetpwuid\fP(3) -are sometimes too large for particular applications. -The current design allows the application author to use a more -compact implementation when appropriate. -.PP -The full list of metadata read from disk by -\fB\%archive_read_disk_entry_from_file\fP() -is necessarily system-dependent. -.PP -The -\fB\%archive_read_disk_entry_from_file\fP() -function reads as much information as it can from disk. -Some method should be provided to limit this so that clients who -do not need ACLs, for instance, can avoid the extra work needed -to look up such information. -.PP -This API should provide a set of methods for walking a directory tree. -That would make it a direct parallel of the -\fBarchive_read\fP(3) -API. -When such methods are implemented, the -``hybrid'' -symbolic link mode will make sense. diff --git a/thirdparty/libarchive/doc/man/archive_read_extract.3 b/thirdparty/libarchive/doc/man/archive_read_extract.3 deleted file mode 100644 index 1fb057bcf..000000000 --- a/thirdparty/libarchive/doc/man/archive_read_extract.3 +++ /dev/null @@ -1,112 +0,0 @@ -.TH ARCHIVE_READ_EXTRACT 3 "February 2, 2012" "" -.SH NAME -.ad l -\fB\%archive_read_extract\fP, -\fB\%archive_read_extract2\fP, -\fB\%archive_read_extract_set_progress_callback\fP -\- functions for reading streaming archives -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIint\fP -.br -\fB\%archive_read_extract\fP(\fI\%struct\ archive\ *\fP, \fI\%struct\ archive_entry\ *\fP, \fI\%int\ flags\fP); -.br -\fIint\fP -.br -\fB\%archive_read_extract2\fP(\fI\%struct\ archive\ *src\fP, \fI\%struct\ archive_entry\ *\fP, \fI\%struct\ archive\ *dest\fP); -.br -\fIvoid\fP -.br -\fB\%archive_read_extract_set_progress_callback\fP(\fI\%struct\ archive\ *\fP, \fI\%void\ (*func)(void\ *)\fP, \fI\%void\ *user_data\fP); -.SH DESCRIPTION -.ad l -.RS 5 -.TP -\fB\%archive_read_extract\fP(), \fB\%archive_read_extract_set_skip_file\fP() -A convenience function that wraps the corresponding -\fBarchive_write_disk\fP(3) -interfaces. -The first call to -\fB\%archive_read_extract\fP() -creates a restore object using -\fBarchive_write_disk_new\fP(3) -and -\fBarchive_write_disk_set_standard_lookup\fP(3), -then transparently invokes -\fBarchive_write_disk_set_options\fP(3), -\fBarchive_write_header\fP(3), -\fBarchive_write_data\fP(3), -and -\fBarchive_write_finish_entry\fP(3) -to create the entry on disk and copy data into it. -The -\fIflags\fP -argument is passed unmodified to -\fBarchive_write_disk_set_options\fP(3). -.TP -\fB\%archive_read_extract2\fP() -This is another version of -\fB\%archive_read_extract\fP() -that allows you to provide your own restore object. -In particular, this allows you to override the standard lookup functions -using -\fBarchive_write_disk_set_group_lookup\fP(3), -and -\fBarchive_write_disk_set_user_lookup\fP(3). -Note that -\fB\%archive_read_extract2\fP() -does not accept a -\fIflags\fP -argument; you should use -\fB\%archive_write_disk_set_options\fP() -to set the restore options yourself. -.TP -\fB\%archive_read_extract_set_progress_callback\fP() -Sets a pointer to a user-defined callback that can be used -for updating progress displays during extraction. -The progress function will be invoked during the extraction of large -regular files. -The progress function will be invoked with the pointer provided to this call. -Generally, the data pointed to should include a reference to the archive -object and the archive_entry object so that various statistics -can be retrieved for the progress display. -.RE -.SH RETURN VALUES -.ad l -Most functions return zero on success, non-zero on error. -The possible return codes include: -\fBARCHIVE_OK\fP -(the operation succeeded), -\fBARCHIVE_WARN\fP -(the operation succeeded but a non-critical error was encountered), -\fBARCHIVE_EOF\fP -(end-of-archive was encountered), -\fBARCHIVE_RETRY\fP -(the operation failed but can be retried), -and -\fBARCHIVE_FATAL\fP -(there was a fatal error; the archive should be closed immediately). -.SH ERRORS -.ad l -Detailed error codes and textual descriptions are available from the -\fB\%archive_errno\fP() -and -\fB\%archive_error_string\fP() -functions. -.SH SEE ALSO -.ad l -\fBtar\fP(1), -\fBarchive_read\fP(3), -\fBarchive_read_data\fP(3), -\fBarchive_read_filter\fP(3), -\fBarchive_read_format\fP(3), -\fBarchive_read_open\fP(3), -\fBarchive_read_set_options\fP(3), -\fBarchive_util\fP(3), -\fBlibarchive\fP(3), -\fBtar\fP(5) diff --git a/thirdparty/libarchive/doc/man/archive_read_filter.3 b/thirdparty/libarchive/doc/man/archive_read_filter.3 deleted file mode 100644 index afb27642d..000000000 --- a/thirdparty/libarchive/doc/man/archive_read_filter.3 +++ /dev/null @@ -1,165 +0,0 @@ -.TH ARCHIVE_READ_FILTER 3 "June 9, 2020" "" -.SH NAME -.ad l -\fB\%archive_read_support_filter_all\fP, -\fB\%archive_read_support_filter_bzip2\fP, -\fB\%archive_read_support_filter_compress\fP, -\fB\%archive_read_support_filter_gzip\fP, -\fB\%archive_read_support_filter_lz4\fP, -\fB\%archive_read_support_filter_lzma\fP, -\fB\%archive_read_support_filter_none\fP, -\fB\%archive_read_support_filter_rpm\fP, -\fB\%archive_read_support_filter_uu\fP, -\fB\%archive_read_support_filter_xz\fP, -\fB\%archive_read_support_filter_zstd\fP, -\fB\%archive_read_support_filter_program\fP, -\fB\%archive_read_support_filter_program_signature\fP -\- functions for reading streaming archives -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIint\fP -.br -\fB\%archive_read_support_filter_all\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_filter_by_code\fP(\fI\%struct\ archive\ *\fP, \fI\%int\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_filter_bzip2\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_filter_compress\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_filter_grzip\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_filter_gzip\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_filter_lrzip\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_filter_lz4\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_filter_lzma\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_filter_lzop\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_filter_none\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_filter_rpm\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_filter_uu\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_filter_xz\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_filter_zstd\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_filter_program\fP(\fI\%struct\ archive\ *\fP, \fI\%const\ char\ *cmd\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_filter_program_signature\fP(\fI\%struct\ archive\ *\fP, \fI\%const\ char\ *cmd\fP, \fI\%const\ void\ *signature\fP, \fI\%size_t\ signature_length\fP); -.SH DESCRIPTION -.ad l -.RS 5 -.TP -\fB\%archive_read_support_filter_bzip2\fP(), -\fB\%archive_read_support_filter_compress\fP(), -\fB\%archive_read_support_filter_grzip\fP(), -\fB\%archive_read_support_filter_gzip\fP(), -\fB\%archive_read_support_filter_lrzip\fP(), -\fB\%archive_read_support_filter_lz4\fP(), -\fB\%archive_read_support_filter_lzma\fP(), -\fB\%archive_read_support_filter_lzop\fP(), -\fB\%archive_read_support_filter_none\fP(), -\fB\%archive_read_support_filter_rpm\fP(), -\fB\%archive_read_support_filter_uu\fP(), -\fB\%archive_read_support_filter_xz\fP(), -\fB\%archive_read_support_filter_zstd\fP(), -Enables auto-detection code and decompression support for the -specified compression. -These functions may fall back on external programs if an appropriate -library was not available at build time. -Decompression using an external program is usually slower than -decompression through built-in libraries. -Note that -``none'' -is always enabled by default. -.TP -\fB\%archive_read_support_filter_all\fP() -Enables all available decompression filters. -.TP -\fB\%archive_read_support_filter_by_code\fP() -Enables a single filter specified by the filter code. -This function does not work with -\fBARCHIVE_FILTER_PROGRAM\fP. -Note: In statically-linked executables, this will cause -your program to include support for every filter. -If executable size is a concern, you may wish to avoid -using this function. -.TP -\fB\%archive_read_support_filter_program\fP() -Data is fed through the specified external program before being dearchived. -Note that this disables automatic detection of the compression format, -so it makes no sense to specify this in conjunction with any other -decompression option. -.TP -\fB\%archive_read_support_filter_program_signature\fP() -This feeds data through the specified external program -but only if the initial bytes of the data match the specified -signature value. -.RE -.SH RETURN VALUES -.ad l -These functions return -\fBARCHIVE_OK\fP -if the compression is fully supported, -\fBARCHIVE_WARN\fP -if the compression is supported only through an external program. -.PP -\fB\%archive_read_support_filter_none\fP() -always succeeds. -.SH ERRORS -.ad l -Detailed error codes and textual descriptions are available from the -\fB\%archive_errno\fP() -and -\fB\%archive_error_string\fP() -functions. -.SH SEE ALSO -.ad l -\fBarchive_read\fP(3), -\fBarchive_read_data\fP(3), -\fBarchive_read_format\fP(3), -\fBarchive_read_format\fP(3), -\fBlibarchive\fP(3) diff --git a/thirdparty/libarchive/doc/man/archive_read_format.3 b/thirdparty/libarchive/doc/man/archive_read_format.3 deleted file mode 100644 index 9bd564d21..000000000 --- a/thirdparty/libarchive/doc/man/archive_read_format.3 +++ /dev/null @@ -1,185 +0,0 @@ -.TH ARCHIVE_READ_FORMAT 3 "February 2, 2012" "" -.SH NAME -.ad l -\fB\%archive_read_support_format_7zip\fP, -\fB\%archive_read_support_format_all\fP, -\fB\%archive_read_support_format_ar\fP, -\fB\%archive_read_support_format_by_code\fP, -\fB\%archive_read_support_format_cab\fP, -\fB\%archive_read_support_format_cpio\fP, -\fB\%archive_read_support_format_empty\fP, -\fB\%archive_read_support_format_iso9660\fP, -\fB\%archive_read_support_format_lha\fP, -\fB\%archive_read_support_format_mtree\fP, -\fB\%archive_read_support_format_rar\fP, -\fB\%archive_read_support_format_raw\fP, -\fB\%archive_read_support_format_tar\fP, -\fB\%archive_read_support_format_xar\fP, -\fB\%archive_read_support_format_zip\fP -\- functions for reading streaming archives -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIint\fP -.br -\fB\%archive_read_support_format_7zip\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_format_all\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_format_ar\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_format_by_code\fP(\fI\%struct\ archive\ *\fP, \fI\%int\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_format_cab\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_format_cpio\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_format_empty\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_format_iso9660\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_format_lha\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_format_mtree\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_format_rar\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_format_raw\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_format_tar\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_format_xar\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_support_format_zip\fP(\fI\%struct\ archive\ *\fP); -.SH DESCRIPTION -.ad l -.RS 5 -.TP -\fB\%archive_read_support_format_7zip\fP(), -\fB\%archive_read_support_format_ar\fP(), -\fB\%archive_read_support_format_cab\fP(), -\fB\%archive_read_support_format_cpio\fP(), -\fB\%archive_read_support_format_iso9660\fP(), -\fB\%archive_read_support_format_lha\fP(), -\fB\%archive_read_support_format_mtree\fP(), -\fB\%archive_read_support_format_rar\fP(), -\fB\%archive_read_support_format_raw\fP(), -\fB\%archive_read_support_format_tar\fP(), -\fB\%archive_read_support_format_xar\fP(), -\fB\%archive_read_support_format_zip\fP() -Enables support---including auto-detection code---for the -specified archive format. -For example, -\fB\%archive_read_support_format_tar\fP() -enables support for a variety of standard tar formats, old-style tar, -ustar, pax interchange format, and many common variants. -.TP -\fB\%archive_read_support_format_all\fP() -Enables support for all available formats except the -``raw'' -format (see below). -.TP -\fB\%archive_read_support_format_by_code\fP() -Enables a single format specified by the format code. -This can be useful when reading a single archive twice; -use -\fB\%archive_format\fP() -after reading the first time and pass the resulting code -to this function to selectively enable only the necessary -format support. -Note: In statically-linked executables, this will cause -your program to include support for every format. -If executable size is a concern, you may wish to avoid -using this function. -.TP -\fB\%archive_read_support_format_empty\fP() -Enables support for treating empty files as empty archives. -Because empty files are valid for several different formats, -it is not possible to accurately determine a format for -an empty file based purely on contents. -So empty files are treated by libarchive as a distinct -format. -.TP -\fB\%archive_read_support_format_raw\fP() -The -``raw'' -format handler allows libarchive to be used to read arbitrary data. -It treats any data stream as an archive with a single entry. -The pathname of this entry is -``data ;'' -all other entry fields are unset. -This is not enabled by -\fB\%archive_read_support_format_all\fP() -in order to avoid erroneous handling of damaged archives. -.RE -.SH RETURN VALUES -.ad l -These functions return -\fBARCHIVE_OK\fP -on success, or -\fBARCHIVE_FATAL\fP. -.SH ERRORS -.ad l -Detailed error codes and textual descriptions are available from the -\fB\%archive_errno\fP() -and -\fB\%archive_error_string\fP() -functions. -.SH SEE ALSO -.ad l -\fBtar\fP(1), -\fBarchive_read_data\fP(3), -\fBarchive_read_filter\fP(3), -\fBarchive_read_set_options\fP(3), -\fBarchive_util\fP(3), -\fBlibarchive\fP(3), -\fBtar\fP(5) -.SH BUGS -.ad l -Many traditional archiver programs treat -empty files as valid empty archives. -For example, many implementations of -\fBtar\fP(1) -allow you to append entries to an empty file. -Of course, it is impossible to determine the format of an empty file -by inspecting the contents, so this library treats empty files as -having a special -``empty'' -format. -.PP -Using the -``raw'' -handler together with any other handler will often work -but can produce surprising results. diff --git a/thirdparty/libarchive/doc/man/archive_read_free.3 b/thirdparty/libarchive/doc/man/archive_read_free.3 deleted file mode 100644 index 559b205b7..000000000 --- a/thirdparty/libarchive/doc/man/archive_read_free.3 +++ /dev/null @@ -1,78 +0,0 @@ -.TH ARCHIVE_READ_FREE 3 "February 2, 2012" "" -.SH NAME -.ad l -\fB\%archive_read_close\fP, -\fB\%archive_read_finish\fP, -\fB\%archive_read_free\fP -\- functions for reading streaming archives -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIint\fP -.br -\fB\%archive_read_close\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_finish\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_free\fP(\fI\%struct\ archive\ *\fP); -.SH DESCRIPTION -.ad l -.RS 5 -.TP -\fB\%archive_read_close\fP() -Complete the archive and invoke the close callback. -.TP -\fB\%archive_read_finish\fP() -This is a deprecated synonym for -\fB\%archive_read_free\fP(). -The new name was introduced with libarchive 3.0. -Applications that need to compile with either libarchive 2 -or libarchive 3 should continue to use the -\fB\%archive_read_finish\fP() -name. -Both names will be supported until libarchive 4.0 is -released, which is not expected to occur earlier -than 2013. -.TP -\fB\%archive_read_free\fP() -Invokes -\fB\%archive_read_close\fP() -if it was not invoked manually, then release all resources. -Note: In libarchive 1.x, this function was declared to return -\fIvoid ,\fP -which made it impossible to detect certain errors when -\fB\%archive_read_close\fP() -was invoked implicitly from this function. -The declaration is corrected beginning with libarchive 2.0. -.RE -.SH RETURN VALUES -.ad l -These functions return -\fBARCHIVE_OK\fP -on success, or -\fBARCHIVE_FATAL\fP. -.SH ERRORS -.ad l -Detailed error codes and textual descriptions are available from the -\fB\%archive_errno\fP() -and -\fB\%archive_error_string\fP() -functions. -.SH SEE ALSO -.ad l -\fBarchive_read_data\fP(3), -\fBarchive_read_filter\fP(3), -\fBarchive_read_format\fP(3), -\fBarchive_read_new\fP(3), -\fBarchive_read_open\fP(3), -\fBarchive_read_set_options\fP(3), -\fBarchive_util\fP(3), -\fBlibarchive\fP(3) diff --git a/thirdparty/libarchive/doc/man/archive_read_header.3 b/thirdparty/libarchive/doc/man/archive_read_header.3 deleted file mode 100644 index f13c53abe..000000000 --- a/thirdparty/libarchive/doc/man/archive_read_header.3 +++ /dev/null @@ -1,72 +0,0 @@ -.TH ARCHIVE_READ_HEADER 3 "February 2, 2012" "" -.SH NAME -.ad l -\fB\%archive_read_next_header\fP, -\fB\%archive_read_next_header2\fP -\- functions for reading streaming archives -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIint\fP -.br -\fB\%archive_read_next_header\fP(\fI\%struct\ archive\ *\fP, \fI\%struct\ archive_entry\ **\fP); -.br -\fIint\fP -.br -\fB\%archive_read_next_header2\fP(\fI\%struct\ archive\ *\fP, \fI\%struct\ archive_entry\ *\fP); -.SH DESCRIPTION -.ad l -.RS 5 -.TP -\fB\%archive_read_next_header\fP() -Read the header for the next entry and return a pointer to -a -Tn struct archive_entry. -This is a convenience wrapper around -\fB\%archive_read_next_header2\fP() -that reuses an internal -Tn struct archive_entry -object for each request. -.TP -\fB\%archive_read_next_header2\fP() -Read the header for the next entry and populate the provided -Tn struct archive_entry. -.RE -.SH RETURN VALUES -.ad l -These functions return -\fBARCHIVE_OK\fP -(the operation succeeded), -\fBARCHIVE_WARN\fP -(the operation succeeded but a non-critical error was encountered), -\fBARCHIVE_EOF\fP -(end-of-archive was encountered), -\fBARCHIVE_RETRY\fP -(the operation failed but can be retried), -and -\fBARCHIVE_FATAL\fP -(there was a fatal error; the archive should be closed immediately). -.SH ERRORS -.ad l -Detailed error codes and textual descriptions are available from the -\fB\%archive_errno\fP() -and -\fB\%archive_error_string\fP() -functions. -.SH SEE ALSO -.ad l -\fBtar\fP(1), -\fBarchive_read\fP(3), -\fBarchive_read_data\fP(3), -\fBarchive_read_extract\fP(3), -\fBarchive_read_filter\fP(3), -\fBarchive_read_format\fP(3), -\fBarchive_read_open\fP(3), -\fBarchive_read_set_options\fP(3), -\fBarchive_util\fP(3), -\fBlibarchive\fP(3), -\fBtar\fP(5) diff --git a/thirdparty/libarchive/doc/man/archive_read_new.3 b/thirdparty/libarchive/doc/man/archive_read_new.3 deleted file mode 100644 index 8ad9a0980..000000000 --- a/thirdparty/libarchive/doc/man/archive_read_new.3 +++ /dev/null @@ -1,37 +0,0 @@ -.TH ARCHIVE_READ_NEW 3 "February 2, 2012" "" -.SH NAME -.ad l -\fB\%archive_read_new\fP -\- functions for reading streaming archives -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIstruct archive *\fP -.br -\fB\%archive_read_new\fP(\fI\%void\fP); -.SH DESCRIPTION -.ad l -Allocates and initializes a -Tn struct archive -object suitable for reading from an archive. -.BR NULL -is returned on error. -.PP -A complete description of the -Tn struct archive -object can be found in the overview manual page for -\fBlibarchive\fP(3). -.SH SEE ALSO -.ad l -\fBtar\fP(1), -\fBarchive_read_data\fP(3), -\fBarchive_read_filter\fP(3), -\fBarchive_read_format\fP(3), -\fBarchive_read_set_options\fP(3), -\fBarchive_util\fP(3), -\fBlibarchive\fP(3), -\fBtar\fP(5) diff --git a/thirdparty/libarchive/doc/man/archive_read_open.3 b/thirdparty/libarchive/doc/man/archive_read_open.3 deleted file mode 100644 index caf0b57c8..000000000 --- a/thirdparty/libarchive/doc/man/archive_read_open.3 +++ /dev/null @@ -1,205 +0,0 @@ -.TH ARCHIVE_READ_OPEN 3 "February 2, 2012" "" -.SH NAME -.ad l -\fB\%archive_read_open\fP, -\fB\%archive_read_open2\fP, -\fB\%archive_read_open_fd\fP, -\fB\%archive_read_open_FILE\fP, -\fB\%archive_read_open_filename\fP, -\fB\%archive_read_open_memory\fP -\- functions for reading streaming archives -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIint\fP -.br -\fB\%archive_read_open\fP(\fI\%struct\ archive\ *\fP, \fI\%void\ *client_data\fP, \fI\%archive_open_callback\ *\fP, \fI\%archive_read_callback\ *\fP, \fI\%archive_close_callback\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_open2\fP(\fI\%struct\ archive\ *\fP, \fI\%void\ *client_data\fP, \fI\%archive_open_callback\ *\fP, \fI\%archive_read_callback\ *\fP, \fI\%archive_skip_callback\ *\fP, \fI\%archive_close_callback\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_read_open_FILE\fP(\fI\%struct\ archive\ *\fP, \fI\%FILE\ *file\fP); -.br -\fIint\fP -.br -\fB\%archive_read_open_fd\fP(\fI\%struct\ archive\ *\fP, \fI\%int\ fd\fP, \fI\%size_t\ block_size\fP); -.br -\fIint\fP -.br -\fB\%archive_read_open_filename\fP(\fI\%struct\ archive\ *\fP, \fI\%const\ char\ *filename\fP, \fI\%size_t\ block_size\fP); -.br -\fIint\fP -.br -\fB\%archive_read_open_memory\fP(\fI\%struct\ archive\ *\fP, \fI\%const\ void\ *buff\fP, \fI\%size_t\ size\fP); -.SH DESCRIPTION -.ad l -.RS 5 -.TP -\fB\%archive_read_open\fP() -The same as -\fB\%archive_read_open2\fP(), -except that the skip callback is assumed to be -.BR NULL. -.TP -\fB\%archive_read_open2\fP() -Freeze the settings, open the archive, and prepare for reading entries. -This is the most generic version of this call, which accepts -four callback functions. -Most clients will want to use -\fB\%archive_read_open_filename\fP(), -\fB\%archive_read_open_FILE\fP(), -\fB\%archive_read_open_fd\fP(), -or -\fB\%archive_read_open_memory\fP() -instead. -The library invokes the client-provided functions to obtain -raw bytes from the archive. -.TP -\fB\%archive_read_open_FILE\fP() -Like -\fB\%archive_read_open\fP(), -except that it accepts a -\fIFILE *\fP -pointer. -This function should not be used with tape drives or other devices -that require strict I/O blocking. -.TP -\fB\%archive_read_open_fd\fP() -Like -\fB\%archive_read_open\fP(), -except that it accepts a file descriptor and block size rather than -a set of function pointers. -Note that the file descriptor will not be automatically closed at -end-of-archive. -This function is safe for use with tape drives or other blocked devices. -.TP -\fB\%archive_read_open_file\fP() -This is a deprecated synonym for -\fB\%archive_read_open_filename\fP(). -.TP -\fB\%archive_read_open_filename\fP() -Like -\fB\%archive_read_open\fP(), -except that it accepts a simple filename and a block size. -A NULL filename represents standard input. -This function is safe for use with tape drives or other blocked devices. -.TP -\fB\%archive_read_open_memory\fP() -Like -\fB\%archive_read_open\fP(), -except that it accepts a pointer and size of a block of -memory containing the archive data. -.RE -.PP -A complete description of the -Tn struct archive -and -Tn struct archive_entry -objects can be found in the overview manual page for -\fBlibarchive\fP(3). -.SH CLIENT CALLBACKS -.ad l -The callback functions must match the following prototypes: -.RS 5 -.IP -\fItypedef la_ssize_t\fP -\fB\%archive_read_callback\fP(\fI\%struct\ archive\ *\fP, \fI\%void\ *client_data\fP, \fI\%const\ void\ **buffer\fP) -.IP -\fItypedef la_int64_t\fP -\fB\%archive_skip_callback\fP(\fI\%struct\ archive\ *\fP, \fI\%void\ *client_data\fP, \fI\%off_t\ request\fP) -.IP -\fItypedef int\fP -\fB\%archive_open_callback\fP(\fI\%struct\ archive\ *\fP, \fI\%void\ *client_data\fP) -.IP -\fItypedef int\fP -\fB\%archive_close_callback\fP(\fI\%struct\ archive\ *\fP, \fI\%void\ *client_data\fP) -.RE -.PP -The open callback is invoked by -\fB\%archive_open\fP(). -It should return -\fBARCHIVE_OK\fP -if the underlying file or data source is successfully -opened. -If the open fails, it should call -\fB\%archive_set_error\fP() -to register an error code and message and return -\fBARCHIVE_FATAL\fP. -.PP -The read callback is invoked whenever the library -requires raw bytes from the archive. -The read callback should read data into a buffer, -set the -.RS 4 -const void **buffer -.RE -argument to point to the available data, and -return a count of the number of bytes available. -The library will invoke the read callback again -only after it has consumed this data. -The library imposes no constraints on the size -of the data blocks returned. -On end-of-file, the read callback should -return zero. -On error, the read callback should invoke -\fB\%archive_set_error\fP() -to register an error code and message and -return -1. -.PP -The skip callback is invoked when the -library wants to ignore a block of data. -The return value is the number of bytes actually -skipped, which may differ from the request. -If the callback cannot skip data, it should return -zero. -If the skip callback is not provided (the -function pointer is -.BR NULL ), -the library will invoke the read function -instead and simply discard the result. -A skip callback can provide significant -performance gains when reading uncompressed -archives from slow disk drives or other media -that can skip quickly. -.PP -The close callback is invoked by archive_close when -the archive processing is complete. -The callback should return -\fBARCHIVE_OK\fP -on success. -On failure, the callback should invoke -\fB\%archive_set_error\fP() -to register an error code and message and -return -\fBARCHIVE_FATAL\fP. -.SH RETURN VALUES -.ad l -These functions return -\fBARCHIVE_OK\fP -on success, or -\fBARCHIVE_FATAL\fP. -.SH ERRORS -.ad l -Detailed error codes and textual descriptions are available from the -\fB\%archive_errno\fP() -and -\fB\%archive_error_string\fP() -functions. -.SH SEE ALSO -.ad l -\fBtar\fP(1), -\fBarchive_read\fP(3), -\fBarchive_read_data\fP(3), -\fBarchive_read_filter\fP(3), -\fBarchive_read_format\fP(3), -\fBarchive_read_set_options\fP(3), -\fBarchive_util\fP(3), -\fBlibarchive\fP(3), -\fBtar\fP(5) diff --git a/thirdparty/libarchive/doc/man/archive_read_set_options.3 b/thirdparty/libarchive/doc/man/archive_read_set_options.3 deleted file mode 100644 index b44ae61c6..000000000 --- a/thirdparty/libarchive/doc/man/archive_read_set_options.3 +++ /dev/null @@ -1,281 +0,0 @@ -.TH ARCHIVE_READ_OPTIONS 3 "January 31, 2020" "" -.SH NAME -.ad l -\fB\%archive_read_set_filter_option\fP, -\fB\%archive_read_set_format_option\fP, -\fB\%archive_read_set_option\fP, -\fB\%archive_read_set_options\fP -\- functions controlling options for reading archives -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -.br -\fIint\fP -.br -\fB\%archive_read_set_filter_option\fP(\fI\%struct\ archive\ *\fP, \fI\%const\ char\ *module\fP, \fI\%const\ char\ *option\fP, \fI\%const\ char\ *value\fP); -.br -\fIint\fP -.br -\fB\%archive_read_set_format_option\fP(\fI\%struct\ archive\ *\fP, \fI\%const\ char\ *module\fP, \fI\%const\ char\ *option\fP, \fI\%const\ char\ *value\fP); -.br -\fIint\fP -.br -\fB\%archive_read_set_option\fP(\fI\%struct\ archive\ *\fP, \fI\%const\ char\ *module\fP, \fI\%const\ char\ *option\fP, \fI\%const\ char\ *value\fP); -.br -\fIint\fP -.br -\fB\%archive_read_set_options\fP(\fI\%struct\ archive\ *\fP, \fI\%const\ char\ *options\fP); -.SH DESCRIPTION -.ad l -These functions provide a way for libarchive clients to configure -specific read modules. -.RS 5 -.TP -\fB\%archive_read_set_filter_option\fP(), -\fB\%archive_read_set_format_option\fP() -Specifies an option that will be passed to currently-registered -filters (including decompression filters) or format readers. -.PP -If -\fIoption\fP -and -\fIvalue\fP -are both -.BR NULL, -these functions will do nothing and -\fBARCHIVE_OK\fP -will be returned. -If -\fIoption\fP -is -.BR NULL -but -\fIvalue\fP -is not, these functions will do nothing and -\fBARCHIVE_FAILED\fP -will be returned. -.PP -If -\fImodule\fP -is not -.BR NULL, -\fIoption\fP -and -\fIvalue\fP -will be provided to the filter or reader named -\fImodule\fP. -The return value will be that of the module. -If there is no such module, -\fBARCHIVE_FAILED\fP -will be returned. -.PP -If -\fImodule\fP -is -.BR NULL, -\fIoption\fP -and -\fIvalue\fP -will be provided to every registered module. -If any module returns -\fBARCHIVE_FATAL\fP, -this value will be returned immediately. -Otherwise, -\fBARCHIVE_OK\fP -will be returned if any module accepts the option, and -\fBARCHIVE_FAILED\fP -in all other cases. -.TP -\fB\%archive_read_set_option\fP() -Calls -\fB\%archive_read_set_format_option\fP(), -then -\fB\%archive_read_set_filter_option\fP(). -If either function returns -\fBARCHIVE_FATAL\fP, -\fBARCHIVE_FATAL\fP -will be returned -immediately. -Otherwise, greater of the two values will be returned. -.TP -\fB\%archive_read_set_options\fP() -\fIoptions\fP -is a comma-separated list of options. -If -\fIoptions\fP -is -.BR NULL -or empty, -\fBARCHIVE_OK\fP -will be returned immediately. -.PP -Calls -\fB\%archive_read_set_option\fP() -with each option in turn. -If any -\fB\%archive_read_set_option\fP() -call returns -\fBARCHIVE_FATAL\fP, -\fBARCHIVE_FATAL\fP -will be returned immediately. -.PP -Individual options have one of the following forms: -.RS 5 -.TP -\fIoption=value\fP -The option/value pair will be provided to every module. -Modules that do not accept an option with this name will ignore it. -.TP -\fIoption\fP -The option will be provided to every module with a value of -``1''. -.TP -\fI!option\fP -The option will be provided to every module with a NULL value. -.TP -\fImodule:option=value\fP, \fImodule:option\fP, \fImodule:!option\fP -As above, but the corresponding option and value will be provided -only to modules whose name matches -\fImodule\fP. -.RE -.RE -.SH OPTIONS -.ad l -.RS 5 -.TP -Format cab -.RS 5 -.TP -\fBhdrcharset\fP -The value is used as a character set name that will be -used when translating file names. -.RE -.TP -Format cpio -.RS 5 -.TP -\fBcompat-2x\fP -Libarchive 2.x incorrectly encoded Unicode filenames on -some platforms. -This option mimics the libarchive 2.x filename handling -so that such archives can be read correctly. -.TP -\fBhdrcharset\fP -The value is used as a character set name that will be -used when translating file names. -.TP -\fBpwb\fP -When reading a binary CPIO archive, assume that it is -in the original PWB cpio format, and handle file mode -bits accordingly. The default is to assume v7 format. -.RE -.TP -Format iso9660 -.RS 5 -.TP -\fBjoliet\fP -Support Joliet extensions. -Defaults to enabled, use -\fB!joliet\fP -to disable. -.TP -\fBrockridge\fP -Support RockRidge extensions. -Defaults to enabled, use -\fB!rockridge\fP -to disable. -.RE -.TP -Format lha -.RS 5 -.TP -\fBhdrcharset\fP -The value is used as a character set name that will be -used when translating file names. -.RE -.TP -Format mtree -.RS 5 -.TP -\fBcheckfs\fP -Allow reading information missing from the mtree from the file system. -Disabled by default. -.RE -.TP -Format rar -.RS 5 -.TP -\fBhdrcharset\fP -The value is used as a character set name that will be -used when translating file names. -.RE -.TP -Format tar -.RS 5 -.TP -\fBcompat-2x\fP -Libarchive 2.x incorrectly encoded Unicode filenames on -some platforms. -This option mimics the libarchive 2.x filename handling -so that such archives can be read correctly. -.TP -\fBhdrcharset\fP -The value is used as a character set name that will be -used when translating file names. -.TP -\fBmac-ext\fP -Support Mac OS metadata extension that records data in special -files beginning with a period and underscore. -Defaults to enabled on Mac OS, disabled on other platforms. -Use -\fB!mac-ext\fP -to disable. -.TP -\fBread_concatenated_archives\fP -Ignore zeroed blocks in the archive, which occurs when multiple tar archives -have been concatenated together. -Without this option, only the contents of -the first concatenated archive would be read. -.RE -.TP -Format zip -.RS 5 -.TP -\fBcompat-2x\fP -Libarchive 2.x incorrectly encoded Unicode filenames on -some platforms. -This option mimics the libarchive 2.x filename handling -so that such archives can be read correctly. -.TP -\fBhdrcharset\fP -The value is used as a character set name that will be -used when translating file names. -.TP -\fBignorecrc32\fP -Skip the CRC32 check. -Mostly used for testing. -.TP -\fBmac-ext\fP -Support Mac OS metadata extension that records data in special -files beginning with a period and underscore. -Defaults to enabled on Mac OS, disabled on other platforms. -Use -\fB!mac-ext\fP -to disable. -.RE -.RE -.SH ERRORS -.ad l -Detailed error codes and textual descriptions are available from the -\fB\%archive_errno\fP() -and -\fB\%archive_error_string\fP() -functions. -.SH SEE ALSO -.ad l -\fBtar\fP(1), -\fBarchive_read\fP(3), -\fBarchive_write_set_options\fP(3), -\fBlibarchive\fP(3) diff --git a/thirdparty/libarchive/doc/man/archive_util.3 b/thirdparty/libarchive/doc/man/archive_util.3 deleted file mode 100644 index 08b1c95ea..000000000 --- a/thirdparty/libarchive/doc/man/archive_util.3 +++ /dev/null @@ -1,240 +0,0 @@ -.TH ARCHIVE_UTIL 3 "February 2, 2012" "" -.SH NAME -.ad l -\fB\%archive_clear_error\fP, -\fB\%archive_compression\fP, -\fB\%archive_compression_name\fP, -\fB\%archive_copy_error\fP, -\fB\%archive_errno\fP, -\fB\%archive_error_string\fP, -\fB\%archive_file_count\fP, -\fB\%archive_filter_code\fP, -\fB\%archive_filter_count\fP, -\fB\%archive_filter_name\fP, -\fB\%archive_format\fP, -\fB\%archive_format_name\fP, -\fB\%archive_position\fP, -\fB\%archive_set_error\fP -\- libarchive utility functions -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIvoid\fP -.br -\fB\%archive_clear_error\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_compression\fP(\fI\%struct\ archive\ *\fP); -.br -\fIconst char *\fP -.br -\fB\%archive_compression_name\fP(\fI\%struct\ archive\ *\fP); -.br -\fIvoid\fP -.br -\fB\%archive_copy_error\fP(\fI\%struct\ archive\ *\fP, \fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_errno\fP(\fI\%struct\ archive\ *\fP); -.br -\fIconst char *\fP -.br -\fB\%archive_error_string\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_file_count\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_filter_code\fP(\fI\%struct\ archive\ *\fP, \fI\%int\fP); -.br -\fIint\fP -.br -\fB\%archive_filter_count\fP(\fI\%struct\ archive\ *\fP, \fI\%int\fP); -.br -\fIconst char *\fP -.br -\fB\%archive_filter_name\fP(\fI\%struct\ archive\ *\fP, \fI\%int\fP); -.br -\fIint\fP -.br -\fB\%archive_format\fP(\fI\%struct\ archive\ *\fP); -.br -\fIconst char *\fP -.br -\fB\%archive_format_name\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint64_t\fP -.br -\fB\%archive_position\fP(\fI\%struct\ archive\ *\fP, \fI\%int\fP); -.br -\fIvoid\fP -.br -\fB\%archive_set_error\fP(\fI\%struct\ archive\ *\fP, \fI\%int\ error_code\fP, \fI\%const\ char\ *fmt\fP, \fI\%...\fP); -.SH DESCRIPTION -.ad l -These functions provide access to various information about the -Tn struct archive -object used in the -\fBlibarchive\fP(3) -library. -.RS 5 -.TP -\fB\%archive_clear_error\fP() -Clears any error information left over from a previous call. -Not generally used in client code. -.TP -\fB\%archive_compression\fP() -Synonym for -\fB\%archive_filter_code\fP(\fI\%a\fP, \fI\%0\fP). -.TP -\fB\%archive_compression_name\fP() -Synonym for -\fB\%archive_filter_name\fP(\fI\%a\fP, \fI\%0\fP). -.TP -\fB\%archive_copy_error\fP() -Copies error information from one archive to another. -.TP -\fB\%archive_errno\fP() -Returns a numeric error code (see -\fBerrno\fP(2)) -indicating the reason for the most recent error return. -Note that this can not be reliably used to detect whether an -error has occurred. -It should be used only after another libarchive function -has returned an error status. -.TP -\fB\%archive_error_string\fP() -Returns a textual error message suitable for display. -The error message here is usually more specific than that -obtained from passing the result of -\fB\%archive_errno\fP() -to -\fBstrerror\fP(3). -.TP -\fB\%archive_file_count\fP() -Returns a count of the number of files processed by this archive object. -The count is incremented by calls to -\fBarchive_write_header\fP(3) -or -\fBarchive_read_next_header\fP(3). -.TP -\fB\%archive_filter_code\fP() -Returns a numeric code identifying the indicated filter. -See -\fB\%archive_filter_count\fP() -for details of the numbering. -.TP -\fB\%archive_filter_count\fP() -Returns the number of filters in the current pipeline. -For read archive handles, these filters are added automatically -by the automatic format detection. -For write archive handles, these filters are added by calls to the various -\fB\%archive_write_add_filter_XXX\fP() -functions. -Filters in the resulting pipeline are numbered so that filter 0 -is the filter closest to the format handler. -As a convenience, functions that expect a filter number will -accept -1 as a synonym for the highest-numbered filter. -.PP -For example, when reading a uuencoded gzipped tar archive, there -are three filters: -filter 0 is the gunzip filter, -filter 1 is the uudecode filter, -and filter 2 is the pseudo-filter that wraps the archive read functions. -In this case, requesting -\fB\%archive_position\fP(\fI\%a\fP, \fI\%-1\fP) -would be a synonym for -\fB\%archive_position\fP(\fI\%a\fP, \fI\%2\fP) -which would return the number of bytes currently read from the archive, while -\fB\%archive_position\fP(\fI\%a\fP, \fI\%1\fP) -would return the number of bytes after uudecoding, and -\fB\%archive_position\fP(\fI\%a\fP, \fI\%0\fP) -would return the number of bytes after decompression. -.TP -\fB\%archive_filter_name\fP() -Returns a textual name identifying the indicated filter. -See -\fB\%archive_filter_count\fP() -for details of the numbering. -.TP -\fB\%archive_format\fP() -Returns a numeric code indicating the format of the current -archive entry. -This value is set by a successful call to -\fB\%archive_read_next_header\fP(). -Note that it is common for this value to change from -entry to entry. -For example, a tar archive might have several entries that -utilize GNU tar extensions and several entries that do not. -These entries will have different format codes. -.TP -\fB\%archive_format_name\fP() -A textual description of the format of the current entry. -.TP -\fB\%archive_position\fP() -Returns the number of bytes read from or written to the indicated filter. -In particular, -\fB\%archive_position\fP(\fI\%a\fP, \fI\%0\fP) -returns the number of bytes read or written by the format handler, while -\fB\%archive_position\fP(\fI\%a\fP, \fI\%-1\fP) -returns the number of bytes read or written to the archive. -See -\fB\%archive_filter_count\fP() -for details of the numbering here. -.TP -\fB\%archive_set_error\fP() -Sets the numeric error code and error description that will be returned -by -\fB\%archive_errno\fP() -and -\fB\%archive_error_string\fP(). -This function should be used within I/O callbacks to set system-specific -error codes and error descriptions. -This function accepts a printf-like format string and arguments. -However, you should be careful to use only the following printf -format specifiers: -``%c'', -``%d'', -``%jd'', -``%jo'', -``%ju'', -``%jx'', -``%ld'', -``%lo'', -``%lu'', -``%lx'', -``%o'', -``%u'', -``%s'', -``%x'', -``%%''. -Field-width specifiers and other printf features are -not uniformly supported and should not be used. -.RE -.SH SEE ALSO -.ad l -\fBarchive_read\fP(3), -\fBarchive_write\fP(3), -\fBlibarchive\fP(3), -\fBprintf\fP(3) -.SH HISTORY -.ad l -The -\fB\%libarchive\fP -library first appeared in -FreeBSD 5.3. -.SH AUTHORS -.ad l --nosplit -The -\fB\%libarchive\fP -library was written by -Tim Kientzle \% diff --git a/thirdparty/libarchive/doc/man/archive_write.3 b/thirdparty/libarchive/doc/man/archive_write.3 deleted file mode 100644 index af64b7971..000000000 --- a/thirdparty/libarchive/doc/man/archive_write.3 +++ /dev/null @@ -1,233 +0,0 @@ -.TH ARCHIVE_WRITE 3 "February 2, 2012" "" -.SH NAME -.ad l -\fB\%archive_write\fP -\- functions for creating archives -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.SH DESCRIPTION -.ad l -These functions provide a complete API for creating streaming -archive files. -The general process is to first create the -Tn struct archive -object, set any desired options, initialize the archive, append entries, then -close the archive and release all resources. -.SS Create archive object -See -\fBarchive_write_new\fP(3). -.PP -To write an archive, you must first obtain an initialized -Tn struct archive -object from -\fB\%archive_write_new\fP(). -.SS Enable filters and formats, configure block size and padding -See -\fBarchive_write_filter\fP(3), -\fBarchive_write_format\fP(3) -and -\fBarchive_write_blocksize\fP(3). -.PP -You can then modify this object for the desired operations with the -various -\fB\%archive_write_set_XXX\fP() -functions. -In particular, you will need to invoke appropriate -\fB\%archive_write_add_XXX\fP() -and -\fB\%archive_write_set_XXX\fP() -functions to enable the corresponding compression and format -support. -.SS Set options -See -\fBarchive_write_set_options\fP(3). -.SS Open archive -See -\fBarchive_write_open\fP(3). -.PP -Once you have prepared the -Tn struct archive -object, you call -\fB\%archive_write_open\fP() -to actually open the archive and prepare it for writing. -There are several variants of this function; -the most basic expects you to provide pointers to several -functions that can provide blocks of bytes from the archive. -There are convenience forms that allow you to -specify a filename, file descriptor, -\fIFILE *\fP -object, or a block of memory from which to write the archive data. -.SS Produce archive -See -\fBarchive_write_header\fP(3) -and -\fBarchive_write_data\fP(3). -.PP -Individual archive entries are written in a three-step -process: -You first initialize a -Tn struct archive_entry -structure with information about the new entry. -At a minimum, you should set the pathname of the -entry and provide a -\fIstruct\fP stat -with a valid -\fIst_mode\fP -field, which specifies the type of object and -\fIst_size\fP -field, which specifies the size of the data portion of the object. -.SS Release resources -See -\fBarchive_write_free\fP(3). -.PP -After all entries have been written, use the -\fB\%archive_write_free\fP() -function to release all resources. -.SH EXAMPLES -.ad l -The following sketch illustrates basic usage of the library. -In this example, -the callback functions are simply wrappers around the standard -\fBopen\fP(2), -\fBwrite\fP(2), -and -\fBclose\fP(2) -system calls. -.RS 4 -.nf -#ifdef __linux__ -#define _FILE_OFFSET_BITS 64 -#endif -#include -#include -#include -#include -#include -#include -struct mydata { - const char *name; - int fd; -}; -int -myopen(struct archive *a, void *client_data) -{ - struct mydata *mydata = client_data; - mydata->fd = open(mydata->name, O_WRONLY | O_CREAT, 0644); - if (mydata->fd >= 0) - return (ARCHIVE_OK); - else - return (ARCHIVE_FATAL); -} -la_ssize_t -mywrite(struct archive *a, void *client_data, const void *buff, size_t n) -{ - struct mydata *mydata = client_data; - return (write(mydata->fd, buff, n)); -} -int -myclose(struct archive *a, void *client_data) -{ - struct mydata *mydata = client_data; - if (mydata->fd > 0) - close(mydata->fd); - return (0); -} -void -write_archive(const char *outname, const char **filename) -{ - struct mydata *mydata = malloc(sizeof(struct mydata)); - struct archive *a; - struct archive_entry *entry; - struct stat st; - char buff[8192]; - int len; - int fd; - a = archive_write_new(); - mydata->name = outname; - /* Set archive format and filter according to output file extension. - * If it fails, set default format. Platform depended function. - * See supported formats in archive_write_set_format_filter_by_ext.c */ - if (archive_write_set_format_filter_by_ext(a, outname) != ARCHIVE_OK) { - archive_write_add_filter_gzip(a); - archive_write_set_format_ustar(a); - } - archive_write_open(a, mydata, myopen, mywrite, myclose); - while (*filename) { - stat(*filename, &st); - entry = archive_entry_new(); - archive_entry_copy_stat(entry, &st); - archive_entry_set_pathname(entry, *filename); - archive_write_header(a, entry); - if ((fd = open(*filename, O_RDONLY)) != -1) { - len = read(fd, buff, sizeof(buff)); - while (len > 0) { - archive_write_data(a, buff, len); - len = read(fd, buff, sizeof(buff)); - } - close(fd); - } - archive_entry_free(entry); - filename++; - } - archive_write_free(a); -} -int main(int argc, const char **argv) -{ - const char *outname; - argv++; - outname = *argv++; - write_archive(outname, argv); - return 0; -} -.RE -.SH SEE ALSO -.ad l -\fBtar\fP(1), -\fBarchive_write_set_options\fP(3), -\fBlibarchive\fP(3), -\fBcpio\fP(5), -\fBmtree\fP(5), -\fBtar\fP(5) -.SH HISTORY -.ad l -The -\fB\%libarchive\fP -library first appeared in -FreeBSD 5.3. -.SH AUTHORS -.ad l --nosplit -The -\fB\%libarchive\fP -library was written by -Tim Kientzle \% -.SH BUGS -.ad l -There are many peculiar bugs in historic tar implementations that may cause -certain programs to reject archives written by this library. -For example, several historic implementations calculated header checksums -incorrectly and will thus reject valid archives; GNU tar does not fully support -pax interchange format; some old tar implementations required specific -field terminations. -.PP -The default pax interchange format eliminates most of the historic -tar limitations and provides a generic key/value attribute facility -for vendor-defined extensions. -One oversight in POSIX is the failure to provide a standard attribute -for large device numbers. -This library uses -``SCHILY.devminor'' -and -``SCHILY.devmajor'' -for device numbers that exceed the range supported by the backwards-compatible -ustar header. -These keys are compatible with Joerg Schilling's -\fB\%star\fP -archiver. -Other implementations may not recognize these keys and will thus be unable -to correctly restore device nodes with large device numbers from archives -created by this library. diff --git a/thirdparty/libarchive/doc/man/archive_write_blocksize.3 b/thirdparty/libarchive/doc/man/archive_write_blocksize.3 deleted file mode 100644 index 5502bbed3..000000000 --- a/thirdparty/libarchive/doc/man/archive_write_blocksize.3 +++ /dev/null @@ -1,104 +0,0 @@ -.TH ARCHIVE_WRITE_BLOCKSIZE 3 "February 2, 2012" "" -.SH NAME -.ad l -\fB\%archive_write_get_bytes_per_block\fP, -\fB\%archive_write_set_bytes_per_block\fP, -\fB\%archive_write_get_bytes_in_last_block\fP, -\fB\%archive_write_set_bytes_in_last_block\fP -\- functions for creating archives -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIint\fP -.br -\fB\%archive_write_get_bytes_per_block\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_bytes_per_block\fP(\fI\%struct\ archive\ *\fP, \fI\%int\ bytes_per_block\fP); -.br -\fIint\fP -.br -\fB\%archive_write_get_bytes_in_last_block\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_bytes_in_last_block\fP(\fI\%struct\ archive\ *\fP, \fI\%int\fP); -.SH DESCRIPTION -.ad l -.RS 5 -.TP -\fB\%archive_write_set_bytes_per_block\fP() -Sets the block size used for writing the archive data. -Every call to the write callback function, except possibly the last one, will -use this value for the length. -The default is to use a block size of 10240 bytes. -Note that a block size of zero will suppress internal blocking -and cause writes to be sent directly to the write callback as they occur. -.TP -\fB\%archive_write_get_bytes_per_block\fP() -Retrieve the block size to be used for writing. -A value of -1 here indicates that the library should use default values. -A value of zero indicates that internal blocking is suppressed. -.TP -\fB\%archive_write_set_bytes_in_last_block\fP() -Sets the block size used for writing the last block. -If this value is zero, the last block will be padded to the same size -as the other blocks. -Otherwise, the final block will be padded to a multiple of this size. -In particular, setting it to 1 will cause the final block to not be padded. -For compressed output, any padding generated by this option -is applied only after the compression. -The uncompressed data is always unpadded. -The default is to pad the last block to the full block size (note that -\fB\%archive_write_open_filename\fP() -will set this based on the file type). -Unlike the other -``set'' -functions, this function can be called after the archive is opened. -.TP -\fB\%archive_write_get_bytes_in_last_block\fP() -Retrieve the currently-set value for last block size. -A value of -1 here indicates that the library should use default values. -.RE -.SH RETURN VALUES -.ad l -\fB\%archive_write_set_bytes_per_block\fP() -and -\fB\%archive_write_set_bytes_in_last_block\fP() -return -\fBARCHIVE_OK\fP -on success, or -\fBARCHIVE_FATAL\fP. -.PP -\fB\%archive_write_get_bytes_per_block\fP() -and -\fB\%archive_write_get_bytes_in_last_block\fP() -return currently configured block size -Po -.RS 4 --1 -.RE -indicates the default block size -Pc, -or -\fBARCHIVE_FATAL\fP. -.SH ERRORS -.ad l -Detailed error codes and textual descriptions are available from the -\fB\%archive_errno\fP() -and -\fB\%archive_error_string\fP() -functions. -.SH SEE ALSO -.ad l -\fBtar\fP(1), -\fBarchive_write_set_options\fP(3), -\fBlibarchive\fP(3), -\fBcpio\fP(5), -\fBmtree\fP(5), -\fBtar\fP(5) diff --git a/thirdparty/libarchive/doc/man/archive_write_data.3 b/thirdparty/libarchive/doc/man/archive_write_data.3 deleted file mode 100644 index 060083e72..000000000 --- a/thirdparty/libarchive/doc/man/archive_write_data.3 +++ /dev/null @@ -1,71 +0,0 @@ -.TH ARCHIVE_WRITE_DATA 3 "February 28, 2017" "" -.SH NAME -.ad l -\fB\%archive_write_data\fP, -\fB\%archive_write_data_block\fP -\- functions for creating archives -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIla_ssize_t\fP -.br -\fB\%archive_write_data\fP(\fI\%struct\ archive\ *\fP, \fI\%const\ void\ *\fP, \fI\%size_t\fP); -.br -\fIla_ssize_t\fP -.br -\fB\%archive_write_data_block\fP(\fI\%struct\ archive\ *\fP, \fI\%const\ void\ *\fP, \fI\%size_t\ size\fP, \fI\%int64_t\ offset\fP); -.SH DESCRIPTION -.ad l -.RS 5 -.TP -\fB\%archive_write_data\fP() -Write data corresponding to the header just written. -.TP -\fB\%archive_write_data_block\fP() -Write data corresponding to the header just written. -This is like -\fB\%archive_write_data\fP() -except that it performs a seek on the file being -written to the specified offset before writing the data. -This is useful when restoring sparse files from archive -formats that support sparse files. -Returns number of bytes written or -1 on error. -(Note: This is currently not supported for -Tn archive_write -handles, only for -Tn archive_write_disk -handles. -.RE -.SH RETURN VALUES -.ad l -This function returns the number of bytes actually written, or -a negative error code on error. -.SH ERRORS -.ad l -Detailed error codes and textual descriptions are available from the -\fB\%archive_errno\fP() -and -\fB\%archive_error_string\fP() -functions. -.SH BUGS -.ad l -In libarchive 3.x, this function sometimes returns -zero on success instead of returning the number of bytes written. -Specifically, this occurs when writing to an -Vt archive_write_disk -handle. -Clients should treat any value less than zero as an error -and consider any non-negative value as success. -.SH SEE ALSO -.ad l -\fBtar\fP(1), -\fBarchive_write_finish_entry\fP(3), -\fBarchive_write_set_options\fP(3), -\fBlibarchive\fP(3), -\fBcpio\fP(5), -\fBmtree\fP(5), -\fBtar\fP(5) diff --git a/thirdparty/libarchive/doc/man/archive_write_disk.3 b/thirdparty/libarchive/doc/man/archive_write_disk.3 deleted file mode 100644 index fa13fe444..000000000 --- a/thirdparty/libarchive/doc/man/archive_write_disk.3 +++ /dev/null @@ -1,364 +0,0 @@ -.TH ARCHIVE_WRITE_DISK 3 "January 19, 2020" "" -.SH NAME -.ad l -\fB\%archive_write_disk_new\fP, -\fB\%archive_write_disk_set_options\fP, -\fB\%archive_write_disk_set_skip_file\fP, -\fB\%archive_write_disk_set_group_lookup\fP, -\fB\%archive_write_disk_set_standard_lookup\fP, -\fB\%archive_write_disk_set_user_lookup\fP -\- functions for creating objects on disk -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIstruct archive *\fP -.br -\fB\%archive_write_disk_new\fP(\fI\%void\fP); -.br -\fIint\fP -.br -\fB\%archive_write_disk_set_options\fP(\fI\%struct\ archive\ *\fP, \fI\%int\ flags\fP); -.br -\fIint\fP -.br -\fB\%archive_write_disk_set_skip_file\fP(\fI\%struct\ archive\ *\fP, \fI\%dev_t\fP, \fI\%ino_t\fP); -.br -\fIint\fP -.br -\fB\%archive_write_disk_set_group_lookup\fP(\fI\%struct\ archive\ *\fP, \fI\%void\ *\fP, \fI\%gid_t\ (*)(void\ *,\ const\ char\ *gname,\ gid_t\ gid)\fP, \fI\%void\ (*cleanup)(void\ *)\fP); -.br -\fIint\fP -.br -\fB\%archive_write_disk_set_standard_lookup\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_disk_set_user_lookup\fP(\fI\%struct\ archive\ *\fP, \fI\%void\ *\fP, \fI\%uid_t\ (*)(void\ *,\ const\ char\ *uname,\ uid_t\ uid)\fP, \fI\%void\ (*cleanup)(void\ *)\fP); -.SH DESCRIPTION -.ad l -These functions provide a complete API for creating objects on -disk from -Tn struct archive_entry -descriptions. -They are most naturally used when extracting objects from an archive -using the -\fB\%archive_read\fP() -interface. -The general process is to read -Tn struct archive_entry -objects from an archive, then write those objects to a -Tn struct archive -object created using the -\fB\%archive_write_disk\fP() -family functions. -This interface is deliberately very similar to the -\fB\%archive_write\fP() -interface used to write objects to a streaming archive. -.RS 5 -.TP -\fB\%archive_write_disk_new\fP() -Allocates and initializes a -Tn struct archive -object suitable for writing objects to disk. -.TP -\fB\%archive_write_disk_set_skip_file\fP() -Records the device and inode numbers of a file that should not be -overwritten. -This is typically used to ensure that an extraction process does not -overwrite the archive from which objects are being read. -This capability is technically unnecessary but can be a significant -performance optimization in practice. -.TP -\fB\%archive_write_disk_set_options\fP() -The options field consists of a bitwise OR of one or more of the -following values: -.RS 5 -.TP -\fBARCHIVE_EXTRACT_ACL\fP -Attempt to restore Access Control Lists. -By default, extended ACLs are ignored. -.TP -\fBARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS\fP -Before removing a file system object prior to replacing it, clear -platform-specific file flags which might prevent its removal. -.TP -\fBARCHIVE_EXTRACT_FFLAGS\fP -Attempt to restore file attributes (file flags). -By default, file attributes are ignored. -See -\fBchattr\fP(1) -(Linux) -or -\fBchflags\fP(1) -(FreeBSD, Mac OS X) -for more information on file attributes. -.TP -\fBARCHIVE_EXTRACT_MAC_METADATA\fP -Mac OS X specific. -Restore metadata using -\fBcopyfile\fP(3). -By default, -\fBcopyfile\fP(3) -metadata is ignored. -.TP -\fBARCHIVE_EXTRACT_NO_OVERWRITE\fP -Existing files on disk will not be overwritten. -By default, existing regular files are truncated and overwritten; -existing directories will have their permissions updated; -other pre-existing objects are unlinked and recreated from scratch. -.TP -\fBARCHIVE_EXTRACT_OWNER\fP -The user and group IDs should be set on the restored file. -By default, the user and group IDs are not restored. -.TP -\fBARCHIVE_EXTRACT_PERM\fP -Full permissions (including SGID, SUID, and sticky bits) should -be restored exactly as specified, without obeying the -current umask. -Note that SUID and SGID bits can only be restored if the -user and group ID of the object on disk are correct. -If -\fBARCHIVE_EXTRACT_OWNER\fP -is not specified, then SUID and SGID bits will only be restored -if the default user and group IDs of newly-created objects on disk -happen to match those specified in the archive entry. -By default, only basic permissions are restored, and umask is obeyed. -.TP -\fBARCHIVE_EXTRACT_SAFE_WRITES\fP -Extract files atomically, by first creating a unique temporary file and then -renaming it to its required destination name. -This avoids a race where an application might see a partial file (or no -file) during extraction. -.TP -\fBARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS\fP -Refuse to extract an absolute path. -The default is to not refuse such paths. -.TP -\fBARCHIVE_EXTRACT_SECURE_NODOTDOT\fP -Refuse to extract a path that contains a -\fI\& ..\fP -element anywhere within it. -The default is to not refuse such paths. -Note that paths ending in -\fI\& ..\fP -always cause an error, regardless of this flag. -.TP -\fBARCHIVE_EXTRACT_SECURE_SYMLINKS\fP -Refuse to extract any object whose final location would be altered -by a symlink on disk. -This is intended to help guard against a variety of mischief -caused by archives that (deliberately or otherwise) extract -files outside of the current directory. -The default is not to perform this check. -If -\fBARCHIVE_EXTRACT_UNLINK\fP -is specified together with this option, the library will -remove any intermediate symlinks it finds and return an -error only if such symlink could not be removed. -.TP -\fBARCHIVE_EXTRACT_SPARSE\fP -Scan data for blocks of NUL bytes and try to recreate them with holes. -This results in sparse files, independent of whether the archive format -supports or uses them. -.TP -\fBARCHIVE_EXTRACT_TIME\fP -The timestamps (mtime, ctime, and atime) should be restored. -By default, they are ignored. -Note that restoring of atime is not currently supported. -.TP -\fBARCHIVE_EXTRACT_UNLINK\fP -Existing files on disk will be unlinked before any attempt to -create them. -In some cases, this can prove to be a significant performance improvement. -By default, existing files are truncated and rewritten, but -the file is not recreated. -In particular, the default behavior does not break existing hard links. -.TP -\fBARCHIVE_EXTRACT_XATTR\fP -Attempt to restore extended file attributes. -By default, they are ignored. -See -\fBxattr\fP(7) -(Linux,) -\fBxattr\fP(2) -(Mac OS X,) -or -\fBgetextattr\fP(8) -(FreeBSD) -for more information on extended file attributes. -.RE -.TP -\fB\%archive_write_disk_set_group_lookup\fP(), -\fB\%archive_write_disk_set_user_lookup\fP() -The -Tn struct archive_entry -objects contain both names and ids that can be used to identify users -and groups. -These names and ids describe the ownership of the file itself and -also appear in ACL lists. -By default, the library uses the ids and ignores the names, but -this can be overridden by registering user and group lookup functions. -To register, you must provide a lookup function which -accepts both a name and id and returns a suitable id. -You may also provide a -Tn void * -pointer to a private data structure and a cleanup function for -that data. -The cleanup function will be invoked when the -Tn struct archive -object is destroyed. -.TP -\fB\%archive_write_disk_set_standard_lookup\fP() -This convenience function installs a standard set of user -and group lookup functions. -These functions use -\fBgetpwnam\fP(3) -and -\fBgetgrnam\fP(3) -to convert names to ids, defaulting to the ids if the names cannot -be looked up. -These functions also implement a simple memory cache to reduce -the number of calls to -\fBgetpwnam\fP(3) -and -\fBgetgrnam\fP(3). -.RE -More information about the -\fIstruct\fP archive -object and the overall design of the library can be found in the -\fBlibarchive\fP(3) -overview. -Many of these functions are also documented under -\fBarchive_write\fP(3). -.SH RETURN VALUES -.ad l -Most functions return -\fBARCHIVE_OK\fP -(zero) on success, or one of several non-zero -error codes for errors. -Specific error codes include: -\fBARCHIVE_RETRY\fP -for operations that might succeed if retried, -\fBARCHIVE_WARN\fP -for unusual conditions that do not prevent further operations, and -\fBARCHIVE_FATAL\fP -for serious errors that make remaining operations impossible. -.PP -\fB\%archive_write_disk_new\fP() -returns a pointer to a newly-allocated -Tn struct archive -object. -.PP -\fB\%archive_write_data\fP() -returns a count of the number of bytes actually written, -or -.RS 4 --1 -.RE -on error. -.SH ERRORS -.ad l -Detailed error codes and textual descriptions are available from the -\fB\%archive_errno\fP() -and -\fB\%archive_error_string\fP() -functions. -.SH SEE ALSO -.ad l -\fBtar\fP(1), -\fBarchive_read\fP(3), -\fBarchive_write\fP(3), -\fBlibarchive\fP(3) -.SH HISTORY -.ad l -The -\fB\%libarchive\fP -library first appeared in -FreeBSD 5.3. -The -\fB\%archive_write_disk\fP -interface was added to -\fB\%libarchive\fP 2.0 -and first appeared in -FreeBSD 6.3. -.SH AUTHORS -.ad l --nosplit -The -\fB\%libarchive\fP -library was written by -Tim Kientzle \% -.SH BUGS -.ad l -Directories are actually extracted in two distinct phases. -Directories are created during -\fB\%archive_write_header\fP(), -but final permissions are not set until -\fB\%archive_write_close\fP(). -This separation is necessary to correctly handle borderline -cases such as a non-writable directory containing -files, but can cause unexpected results. -In particular, directory permissions are not fully -restored until the archive is closed. -If you use -\fBchdir\fP(2) -to change the current directory between calls to -\fB\%archive_read_extract\fP() -or before calling -\fB\%archive_read_close\fP(), -you may confuse the permission-setting logic with -the result that directory permissions are restored -incorrectly. -.PP -The library attempts to create objects with filenames longer than -\fBPATH_MAX\fP -by creating prefixes of the full path and changing the current directory. -Currently, this logic is limited in scope; the fixup pass does -not work correctly for such objects and the symlink security check -option disables the support for very long pathnames. -.PP -Restoring the path -\fIaa/../bb\fP -does create each intermediate directory. -In particular, the directory -\fIaa\fP -is created as well as the final object -\fIbb\fP. -In theory, this can be exploited to create an entire directory hierarchy -with a single request. -Of course, this does not work if the -\fBARCHIVE_EXTRACT_NODOTDOT\fP -option is specified. -.PP -Implicit directories are always created obeying the current umask. -Explicit objects are created obeying the current umask unless -\fBARCHIVE_EXTRACT_PERM\fP -is specified, in which case they current umask is ignored. -.PP -SGID and SUID bits are restored only if the correct user and -group could be set. -If -\fBARCHIVE_EXTRACT_OWNER\fP -is not specified, then no attempt is made to set the ownership. -In this case, SGID and SUID bits are restored only if the -user and group of the final object happen to match those specified -in the entry. -.PP -The -``standard'' -user-id and group-id lookup functions are not the defaults because -\fBgetgrnam\fP(3) -and -\fBgetpwnam\fP(3) -are sometimes too large for particular applications. -The current design allows the application author to use a more -compact implementation when appropriate. -.PP -There should be a corresponding -\fB\%archive_read_disk\fP -interface that walks a directory hierarchy and returns archive -entry objects. diff --git a/thirdparty/libarchive/doc/man/archive_write_filter.3 b/thirdparty/libarchive/doc/man/archive_write_filter.3 deleted file mode 100644 index 65244edde..000000000 --- a/thirdparty/libarchive/doc/man/archive_write_filter.3 +++ /dev/null @@ -1,141 +0,0 @@ -.TH ARCHIVE_WRITE_FILTER 3 "August 14, 2014" "" -.SH NAME -.ad l -\fB\%archive_write_add_filter_b64encode\fP, -\fB\%archive_write_add_filter_by_name\fP, -\fB\%archive_write_add_filter_bzip2\fP, -\fB\%archive_write_add_filter_compress\fP, -\fB\%archive_write_add_filter_grzip\fP, -\fB\%archive_write_add_filter_gzip\fP, -\fB\%archive_write_add_filter_lrzip\fP, -\fB\%archive_write_add_filter_lz4\fP, -\fB\%archive_write_add_filter_lzip\fP, -\fB\%archive_write_add_filter_lzma\fP, -\fB\%archive_write_add_filter_lzop\fP, -\fB\%archive_write_add_filter_none\fP, -\fB\%archive_write_add_filter_program\fP, -\fB\%archive_write_add_filter_uuencode\fP, -\fB\%archive_write_add_filter_xz\fP, -\fB\%archive_write_add_filter_zstd\fP -\- functions enabling output filters -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIint\fP -.br -\fB\%archive_write_add_filter_b64encode\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_add_filter_bzip2\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_add_filter_compress\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_add_filter_grzip\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_add_filter_gzip\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_add_filter_lrzip\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_add_filter_lz4\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_add_filter_lzip\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_add_filter_lzma\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_add_filter_lzop\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_add_filter_none\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_add_filter_program\fP(\fI\%struct\ archive\ *\fP, \fI\%const\ char\ *\ cmd\fP); -.br -\fIint\fP -.br -\fB\%archive_write_add_filter_uuencode\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_add_filter_xz\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_add_filter_zstd\fP(\fI\%struct\ archive\ *\fP); -.SH DESCRIPTION -.ad l -.RS 5 -.TP -\fB\%archive_write_add_filter_bzip2\fP(), -\fB\%archive_write_add_filter_compress\fP(), -\fB\%archive_write_add_filter_grzip\fP(), -\fB\%archive_write_add_filter_gzip\fP(), -\fB\%archive_write_add_filter_lrzip\fP(), -\fB\%archive_write_add_filter_lz4\fP(), -\fB\%archive_write_add_filter_lzip\fP(), -\fB\%archive_write_add_filter_lzma\fP(), -\fB\%archive_write_add_filter_lzop\fP(), -\fB\%archive_write_add_filter_xz\fP(), -\fB\%archive_write_add_filter_zstd\fP(), -The resulting archive will be compressed as specified. -Note that the compressed output is always properly blocked. -.TP -\fB\%archive_write_add_filter_b64encode\fP(), -\fB\%archive_write_add_filter_uuencode\fP(), -The output will be encoded as specified. -The encoded output is always properly blocked. -.TP -\fB\%archive_write_add_filter_none\fP() -This is never necessary. -It is provided only for backwards compatibility. -.TP -\fB\%archive_write_add_filter_program\fP() -The archive will be fed into the specified compression program. -The output of that program is blocked and written to the client -write callbacks. -.RE -.SH RETURN VALUES -.ad l -These functions return -\fBARCHIVE_OK\fP -on success, or -\fBARCHIVE_FATAL\fP. -.SH ERRORS -.ad l -Detailed error codes and textual descriptions are available from the -\fB\%archive_errno\fP() -and -\fB\%archive_error_string\fP() -functions. -.SH SEE ALSO -.ad l -\fBtar\fP(1), -\fBarchive_write\fP(3), -\fBarchive_write_format\fP(3), -\fBarchive_write_set_options\fP(3), -\fBlibarchive\fP(3), -\fBcpio\fP(5), -\fBmtree\fP(5), -\fBtar\fP(5) diff --git a/thirdparty/libarchive/doc/man/archive_write_finish_entry.3 b/thirdparty/libarchive/doc/man/archive_write_finish_entry.3 deleted file mode 100644 index a8f7f7c49..000000000 --- a/thirdparty/libarchive/doc/man/archive_write_finish_entry.3 +++ /dev/null @@ -1,57 +0,0 @@ -.TH ARCHIVE_WRITE_FINISH_ENTRY 3 "February 28, 2017" "" -.SH NAME -.ad l -\fB\%archive_write_finish_entry\fP -\- functions for creating archives -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIint\fP -.br -\fB\%archive_write_finish_entry\fP(\fI\%struct\ archive\ *\fP); -.SH DESCRIPTION -.ad l -Close out the entry just written. -In particular, this writes out the final padding required by some formats. -Ordinarily, clients never need to call this, as it -is called automatically by -\fB\%archive_write_header\fP() -and -\fB\%archive_write_close\fP() -as needed. -For -Tn archive_write_disk -handles, this flushes pending file attribute changes like modification time. -.SH RETURN VALUES -.ad l -This function returns -\fBARCHIVE_OK\fP -on success, or one of several non-zero -error codes for errors. -Specific error codes include: -\fBARCHIVE_RETRY\fP -for operations that might succeed if retried, -\fBARCHIVE_WARN\fP -for unusual conditions that do not prevent further operations, and -\fBARCHIVE_FATAL\fP -for serious errors that make remaining operations impossible. -.SH ERRORS -.ad l -Detailed error codes and textual descriptions are available from the -\fB\%archive_errno\fP() -and -\fB\%archive_error_string\fP() -functions. -.SH SEE ALSO -.ad l -\fBtar\fP(1), -\fBarchive_write_data\fP(3), -\fBarchive_write_set_options\fP(3), -\fBlibarchive\fP(3), -\fBcpio\fP(5), -\fBmtree\fP(5), -\fBtar\fP(5) diff --git a/thirdparty/libarchive/doc/man/archive_write_format.3 b/thirdparty/libarchive/doc/man/archive_write_format.3 deleted file mode 100644 index 9f8c0b3a0..000000000 --- a/thirdparty/libarchive/doc/man/archive_write_format.3 +++ /dev/null @@ -1,215 +0,0 @@ -.TH ARCHIVE_WRITE_FORMAT 3 "February 14, 2013" "" -.SH NAME -.ad l -\fB\%archive_write_set_format\fP, -\fB\%archive_write_set_format_7zip\fP, -\fB\%archive_write_set_format_ar\fP, -\fB\%archive_write_set_format_ar_bsd\fP, -\fB\%archive_write_set_format_ar_svr4\fP, -\fB\%archive_write_set_format_by_name\fP, -\fB\%archive_write_set_format_cpio\fP, -\fB\%archive_write_set_format_cpio_bin\fP, -\fB\%archive_write_set_format_cpio_newc\fP, -\fB\%archive_write_set_format_cpio_odc\fP, -\fB\%archive_write_set_format_cpio_pwb\fP, -\fB\%archive_write_set_format_filter_by_ext\fP, -\fB\%archive_write_set_format_filter_by_ext_def\fP, -\fB\%archive_write_set_format_gnutar\fP, -\fB\%archive_write_set_format_iso9660\fP, -\fB\%archive_write_set_format_mtree\fP, -\fB\%archive_write_set_format_mtree_classic\fP, -\fB\%archive_write_set_format_mtree_default\fP, -\fB\%archive_write_set_format_pax\fP, -\fB\%archive_write_set_format_pax_restricted\fP, -\fB\%archive_write_set_format_raw\fP, -\fB\%archive_write_set_format_shar\fP, -\fB\%archive_write_set_format_shar_dump\fP, -\fB\%archive_write_set_format_ustar\fP, -\fB\%archive_write_set_format_v7tar\fP, -\fB\%archive_write_set_format_warc\fP, -\fB\%archive_write_set_format_xar\fP, -\fB\%archive_write_set_format_zip\fP -\- functions for creating archives -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIint\fP -.br -\fB\%archive_write_set_format\fP(\fI\%struct\ archive\ *\fP, \fI\%int\ code\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_format_7zip\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_format_ar\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_format_ar_bsd\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_format_ar_svr4\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_format_by_name\fP(\fI\%struct\ archive\ *\fP, \fI\%const\ char\ *name\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_format_cpio\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_format_cpio_bin\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_format_cpio_newc\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_format_cpio_odc\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_format_cpio_pwb\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_format_filter_by_ext\fP(\fI\%struct\ archive\ *\fP, \fI\%const\ char\ *filename\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_format_filter_by_ext_def\fP(\fI\%struct\ archive\ *\fP, \fI\%const\ char\ *filename\fP, \fI\%const\ char\ *def_ext\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_format_gnutar\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_format_iso9660\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_format_mtree\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_format_pax\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_format_pax_restricted\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_format_raw\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_format_shar\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_format_shar_dump\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_format_ustar\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_format_v7tar\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_format_warc\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_format_xar\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_format_zip\fP(\fI\%struct\ archive\ *\fP); -.SH DESCRIPTION -.ad l -These functions set the format that will be used for the archive. -.PP -The library can write a variety of common archive formats. -.RS 5 -.TP -\fB\%archive_write_set_format\fP() -Sets the format based on the format code (see -\fIarchive.h\fP -for the full list of format codes). -In particular, this can be used in conjunction with -\fB\%archive_format\fP() -to create a new archive with the same format as an existing archive. -.TP -\fB\%archive_write_set_format_by_name\fP() -Sets the corresponding format based on the common name. -.TP -\fB\%archive_write_set_format_filter_by_ext\fP() -\fB\%archive_write_set_format_filter_by_ext_def\fP() -Sets both filters and format based on the output filename. -Supported extensions: .7z, .zip, .jar, .cpio, .iso, .a, .ar, .tar, .tgz, .tar.gz, .tar.bz2, .tar.xz -.TP -\fB\%archive_write_set_format_7zip\fP() -\fB\%archive_write_set_format_ar_bsd\fP() -\fB\%archive_write_set_format_ar_svr4\fP() -\fB\%archive_write_set_format_cpio\fP() -\fB\%archive_write_set_format_cpio_bin\fP() -\fB\%archive_write_set_format_cpio_newc\fP() -\fB\%archive_write_set_format_cpio_odc\fP() -\fB\%archive_write_set_format_cpio_pwb\fP() -\fB\%archive_write_set_format_gnutar\fP() -\fB\%archive_write_set_format_iso9660\fP() -\fB\%archive_write_set_format_mtree\fP() -\fB\%archive_write_set_format_mtree_classic\fP() -\fB\%archive_write_set_format_pax\fP() -\fB\%archive_write_set_format_pax_restricted\fP() -\fB\%archive_write_set_format_raw\fP() -\fB\%archive_write_set_format_shar\fP() -\fB\%archive_write_set_format_shar_dump\fP() -\fB\%archive_write_set_format_ustar\fP() -\fB\%archive_write_set_format_v7tar\fP() -\fB\%archive_write_set_format_warc\fP() -\fB\%archive_write_set_format_xar\fP() -\fB\%archive_write_set_format_zip\fP() -Set the format as specified. -More details on the formats supported by libarchive can be found in the -\fBlibarchive-formats\fP(5) -manual page. -.RE -.SH RETURN VALUES -.ad l -These functions return -\fBARCHIVE_OK\fP -on success, or -\fBARCHIVE_FATAL\fP. -.SH ERRORS -.ad l -Detailed error codes and textual descriptions are available from the -\fB\%archive_errno\fP() -and -\fB\%archive_error_string\fP() -functions. -.SH SEE ALSO -.ad l -\fBtar\fP(1), -\fBarchive_write\fP(3), -\fBarchive_write_set_options\fP(3), -\fBlibarchive\fP(3), -\fBcpio\fP(5), -\fBlibarchive-formats\fP(5), -\fBmtree\fP(5), -\fBtar\fP(5) diff --git a/thirdparty/libarchive/doc/man/archive_write_free.3 b/thirdparty/libarchive/doc/man/archive_write_free.3 deleted file mode 100644 index efda9aaaa..000000000 --- a/thirdparty/libarchive/doc/man/archive_write_free.3 +++ /dev/null @@ -1,84 +0,0 @@ -.TH ARCHIVE_WRITE_FREE 3 "February 2, 2012" "" -.SH NAME -.ad l -\fB\%archive_write_fail\fP, -\fB\%archive_write_close\fP, -\fB\%archive_write_finish\fP, -\fB\%archive_write_free\fP -\- functions for creating archives -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIint\fP -.br -\fB\%archive_write_fail\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_close\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_finish\fP(\fI\%struct\ archive\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_free\fP(\fI\%struct\ archive\ *\fP); -.SH DESCRIPTION -.ad l -.RS 5 -.TP -\fB\%archive_write_fail\fP() -Always returns -\fBARCHIVE_FATAL\fP. -This marks the archive object as being unusable; -after calling this function, the only call that can succeed is -\fB\%archive_write_free\fP() -to release the resources. -This can be used to speed recovery when the archive creation -must be aborted. -Note that the created archive is likely to be malformed in this case; -.TP -\fB\%archive_write_close\fP() -Complete the archive and invoke the close callback. -.TP -\fB\%archive_write_finish\fP() -This is a deprecated synonym for -\fB\%archive_write_free\fP(). -.TP -\fB\%archive_write_free\fP() -Invokes -\fB\%archive_write_close\fP() -if necessary, then releases all resources. -If you need detailed information about -\fB\%archive_write_close\fP() -failures, you should be careful to call it separately, as -you cannot obtain error information after -\fB\%archive_write_free\fP() -returns. -.RE -.SH RETURN VALUES -.ad l -These functions return -\fBARCHIVE_OK\fP -on success, or -\fBARCHIVE_FATAL\fP. -.SH ERRORS -.ad l -Detailed error codes and textual descriptions are available from the -\fB\%archive_errno\fP() -and -\fB\%archive_error_string\fP() -functions. -.SH SEE ALSO -.ad l -\fBtar\fP(1), -\fBarchive_write_set_options\fP(3), -\fBlibarchive\fP(3), -\fBcpio\fP(5), -\fBmtree\fP(5), -\fBtar\fP(5) diff --git a/thirdparty/libarchive/doc/man/archive_write_header.3 b/thirdparty/libarchive/doc/man/archive_write_header.3 deleted file mode 100644 index 941ecef00..000000000 --- a/thirdparty/libarchive/doc/man/archive_write_header.3 +++ /dev/null @@ -1,51 +0,0 @@ -.TH ARCHIVE_WRITE_HEADER 3 "February 2, 2012" "" -.SH NAME -.ad l -\fB\%archive_write_header\fP -\- functions for creating archives -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIint\fP -.br -\fB\%archive_write_header\fP(\fI\%struct\ archive\ *\fP, \fI\%struct\ archive_entry\ *\fP); -.SH DESCRIPTION -.ad l -Build and write a header using the data in the provided -Tn struct archive_entry -structure. -See -\fBarchive_entry\fP(3) -for information on creating and populating -Tn struct archive_entry -objects. -.SH RETURN VALUES -.ad l -This function returns -\fBARCHIVE_OK\fP -on success, or one of the following on error: -\fBARCHIVE_RETRY\fP -for operations that might succeed if retried, -\fBARCHIVE_WARN\fP -for unusual conditions that do not prevent further operations, and -\fBARCHIVE_FATAL\fP -for serious errors that make remaining operations impossible. -.SH ERRORS -.ad l -Detailed error codes and textual descriptions are available from the -\fB\%archive_errno\fP() -and -\fB\%archive_error_string\fP() -functions. -.SH SEE ALSO -.ad l -\fBtar\fP(1), -\fBarchive_write_set_options\fP(3), -\fBlibarchive\fP(3), -\fBcpio\fP(5), -\fBmtree\fP(5), -\fBtar\fP(5) diff --git a/thirdparty/libarchive/doc/man/archive_write_new.3 b/thirdparty/libarchive/doc/man/archive_write_new.3 deleted file mode 100644 index c5969a3b2..000000000 --- a/thirdparty/libarchive/doc/man/archive_write_new.3 +++ /dev/null @@ -1,36 +0,0 @@ -.TH ARCHIVE_WRITE_NEW 3 "February 2, 2012" "" -.SH NAME -.ad l -\fB\%archive_write_new\fP -\- functions for creating archives -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIstruct archive *\fP -.br -\fB\%archive_write_new\fP(\fI\%void\fP); -.SH DESCRIPTION -.ad l -Allocates and initializes a -Tn struct archive -object suitable for writing a tar archive. -.BR NULL -is returned on error. -.PP -A complete description of the -Tn struct archive -object can be found in the overview manual page for -\fBlibarchive\fP(3). -.SH SEE ALSO -.ad l -\fBtar\fP(1), -\fBarchive_write\fP(3), -\fBarchive_write_set_options\fP(3), -\fBlibarchive\fP(3), -\fBcpio\fP(5), -\fBmtree\fP(5), -\fBtar\fP(5) diff --git a/thirdparty/libarchive/doc/man/archive_write_open.3 b/thirdparty/libarchive/doc/man/archive_write_open.3 deleted file mode 100644 index 9aeafc089..000000000 --- a/thirdparty/libarchive/doc/man/archive_write_open.3 +++ /dev/null @@ -1,244 +0,0 @@ -.TH ARCHIVE_WRITE_OPEN 3 "November 12, 2020" "" -.SH NAME -.ad l -\fB\%archive_write_open\fP, -\fB\%archive_write_open2\fP, -\fB\%archive_write_open_fd\fP, -\fB\%archive_write_open_FILE\fP, -\fB\%archive_write_open_filename\fP, -\fB\%archive_write_open_memory\fP -\- functions for creating archives -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIint\fP -.br -\fB\%archive_write_open\fP(\fI\%struct\ archive\ *\fP, \fI\%void\ *client_data\fP, \fI\%archive_open_callback\ *\fP, \fI\%archive_write_callback\ *\fP, \fI\%archive_close_callback\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_open2\fP(\fI\%struct\ archive\ *\fP, \fI\%void\ *client_data\fP, \fI\%archive_open_callback\ *\fP, \fI\%archive_write_callback\ *\fP, \fI\%archive_close_callback\ *\fP, \fI\%archive_free_callback\ *\fP); -.br -\fIint\fP -.br -\fB\%archive_write_open_fd\fP(\fI\%struct\ archive\ *\fP, \fI\%int\ fd\fP); -.br -\fIint\fP -.br -\fB\%archive_write_open_FILE\fP(\fI\%struct\ archive\ *\fP, \fI\%FILE\ *file\fP); -.br -\fIint\fP -.br -\fB\%archive_write_open_filename\fP(\fI\%struct\ archive\ *\fP, \fI\%const\ char\ *filename\fP); -.br -\fIint\fP -.br -\fB\%archive_write_open_memory\fP(\fI\%struct\ archive\ *\fP, \fI\%void\ *buffer\fP, \fI\%size_t\ bufferSize\fP, \fI\%size_t\ *outUsed\fP); -.SH DESCRIPTION -.ad l -.RS 5 -.TP -\fB\%archive_write_open\fP() -Freeze the settings, open the archive, and prepare for writing entries. -This is the most generic form of this function, which accepts -pointers to three callback functions which will be invoked by -the compression layer to write the constructed archive. -This does not alter the default archive padding. -.TP -\fB\%archive_write_open2\fP() -Same as -\fB\%archive_write_open\fP() -with an additional fourth free callback. This function should be preferred to -\fB\%archive_write_open\fP(). -.TP -\fB\%archive_write_open_fd\fP() -A convenience form of -\fB\%archive_write_open\fP() -that accepts a file descriptor. -The -\fB\%archive_write_open_fd\fP() -function is safe for use with tape drives or other -block-oriented devices. -.TP -\fB\%archive_write_open_FILE\fP() -A convenience form of -\fB\%archive_write_open\fP() -that accepts a -\fIFILE *\fP -pointer. -Note that -\fB\%archive_write_open_FILE\fP() -is not safe for writing to tape drives or other devices -that require correct blocking. -.TP -\fB\%archive_write_open_file\fP() -A deprecated synonym for -\fB\%archive_write_open_filename\fP(). -.TP -\fB\%archive_write_open_filename\fP() -A convenience form of -\fB\%archive_write_open\fP() -that accepts a filename. -A NULL argument indicates that the output should be written to standard output; -an argument of -``-'' -will open a file with that name. -If you have not invoked -\fB\%archive_write_set_bytes_in_last_block\fP(), -then -\fB\%archive_write_open_filename\fP() -will adjust the last-block padding depending on the file: -it will enable padding when writing to standard output or -to a character or block device node, it will disable padding otherwise. -You can override this by manually invoking -\fB\%archive_write_set_bytes_in_last_block\fP() -before calling -\fB\%archive_write_open2\fP(). -The -\fB\%archive_write_open_filename\fP() -function is safe for use with tape drives or other -block-oriented devices. -.TP -\fB\%archive_write_open_memory\fP() -A convenience form of -\fB\%archive_write_open2\fP() -that accepts a pointer to a block of memory that will receive -the archive. -The final -\fIsize_t *\fP -argument points to a variable that will be updated -after each write to reflect how much of the buffer -is currently in use. -You should be careful to ensure that this variable -remains allocated until after the archive is -closed. -This function will disable padding unless you -have specifically set the block size. -.RE -More information about the -\fIstruct\fP archive -object and the overall design of the library can be found in the -\fBlibarchive\fP(3) -overview. -.PP -Note that the convenience forms above vary in how -they block the output. -See -\fBarchive_write_blocksize\fP(3) -if you need to control the block size used for writes -or the end-of-file padding behavior. -.SH CLIENT CALLBACKS -.ad l -To use this library, you will need to define and register -callback functions that will be invoked to write data to the -resulting archive. -These functions are registered by calling -\fB\%archive_write_open2\fP(): -.RS 5 -.IP -\fItypedef int\fP -\fB\%archive_open_callback\fP(\fI\%struct\ archive\ *\fP, \fI\%void\ *client_data\fP) -.RE -.PP -The open callback is invoked by -\fB\%archive_write_open\fP(). -It should return -\fBARCHIVE_OK\fP -if the underlying file or data source is successfully -opened. -If the open fails, it should call -\fB\%archive_set_error\fP() -to register an error code and message and return -\fBARCHIVE_FATAL\fP. -Please note that if open fails, close is not called and resources must be -freed inside the open callback or with the free callback. -.RS 5 -.IP -\fItypedef la_ssize_t\fP -\fB\%archive_write_callback\fP(\fI\%struct\ archive\ *\fP, \fI\%void\ *client_data\fP, \fI\%const\ void\ *buffer\fP, \fI\%size_t\ length\fP) -.RE -.PP -The write callback is invoked whenever the library -needs to write raw bytes to the archive. -For correct blocking, each call to the write callback function -should translate into a single -\fBwrite\fP(2) -system call. -This is especially critical when writing archives to tape drives. -On success, the write callback should return the -number of bytes actually written. -On error, the callback should invoke -\fB\%archive_set_error\fP() -to register an error code and message and return -1. -.RS 5 -.IP -\fItypedef int\fP -\fB\%archive_close_callback\fP(\fI\%struct\ archive\ *\fP, \fI\%void\ *client_data\fP) -.RE -.PP -The close callback is invoked by archive_close when -the archive processing is complete. If the open callback fails, the close -callback is not invoked. -The callback should return -\fBARCHIVE_OK\fP -on success. -On failure, the callback should invoke -\fB\%archive_set_error\fP() -to register an error code and message and -return -\fBARCHIVE_FATAL\fP. -.RS 5 -.IP -\fItypedef int\fP -\fB\%archive_free_callback\fP(\fI\%struct\ archive\ *\fP, \fI\%void\ *client_data\fP) -.RE -.PP -The free callback is always invoked on archive_free. -The return code of this callback is not processed. -.PP -Note that if the client-provided write callback function -returns a non-zero value, that error will be propagated back to the caller -through whatever API function resulted in that call, which -may include -\fB\%archive_write_header\fP(), -\fB\%archive_write_data\fP(), -\fB\%archive_write_close\fP(), -\fB\%archive_write_finish\fP(), -or -\fB\%archive_write_free\fP(). -The client callback can call -\fB\%archive_set_error\fP() -to provide values that can then be retrieved by -\fB\%archive_errno\fP() -and -\fB\%archive_error_string\fP(). -.SH RETURN VALUES -.ad l -These functions return -\fBARCHIVE_OK\fP -on success, or -\fBARCHIVE_FATAL\fP. -.SH ERRORS -.ad l -Detailed error codes and textual descriptions are available from the -\fB\%archive_errno\fP() -and -\fB\%archive_error_string\fP() -functions. -.SH SEE ALSO -.ad l -\fBtar\fP(1), -\fBarchive_write\fP(3), -\fBarchive_write_blocksize\fP(3), -\fBarchive_write_filter\fP(3), -\fBarchive_write_format\fP(3), -\fBarchive_write_new\fP(3), -\fBarchive_write_set_options\fP(3), -\fBlibarchive\fP(3), -\fBcpio\fP(5), -\fBmtree\fP(5), -\fBtar\fP(5) diff --git a/thirdparty/libarchive/doc/man/archive_write_set_options.3 b/thirdparty/libarchive/doc/man/archive_write_set_options.3 deleted file mode 100644 index 15663dedb..000000000 --- a/thirdparty/libarchive/doc/man/archive_write_set_options.3 +++ /dev/null @@ -1,812 +0,0 @@ -.TH ARCHIVE_WRITE_OPTIONS 3 "January 31, 2020" "" -.SH NAME -.ad l -\fB\%archive_write_set_filter_option\fP, -\fB\%archive_write_set_format_option\fP, -\fB\%archive_write_set_option\fP, -\fB\%archive_write_set_options\fP -\- functions controlling options for writing archives -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -.br -\fIint\fP -.br -\fB\%archive_write_set_filter_option\fP(\fI\%struct\ archive\ *\fP, \fI\%const\ char\ *module\fP, \fI\%const\ char\ *option\fP, \fI\%const\ char\ *value\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_format_option\fP(\fI\%struct\ archive\ *\fP, \fI\%const\ char\ *module\fP, \fI\%const\ char\ *option\fP, \fI\%const\ char\ *value\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_option\fP(\fI\%struct\ archive\ *\fP, \fI\%const\ char\ *module\fP, \fI\%const\ char\ *option\fP, \fI\%const\ char\ *value\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_options\fP(\fI\%struct\ archive\ *\fP, \fI\%const\ char\ *options\fP); -.SH DESCRIPTION -.ad l -These functions provide a way for libarchive clients to configure -specific write modules. -.RS 5 -.TP -\fB\%archive_write_set_filter_option\fP(), -\fB\%archive_write_set_format_option\fP() -Specifies an option that will be passed to the currently-registered -filters (including decompression filters) or format readers. -.PP -If -\fIoption\fP -and -\fIvalue\fP -are both -.BR NULL, -these functions will do nothing and -\fBARCHIVE_OK\fP -will be returned. -If -\fIoption\fP -is -.BR NULL -but -\fIvalue\fP -is not, these functions will do nothing and -\fBARCHIVE_FAILED\fP -will be returned. -.PP -If -\fImodule\fP -is not -.BR NULL, -\fIoption\fP -and -\fIvalue\fP -will be provided to the filter or reader named -\fImodule\fP. -The return value will be either -\fBARCHIVE_OK\fP -if the option was successfully handled or -\fBARCHIVE_WARN\fP -if the option was unrecognized by the module or could otherwise -not be handled. -If there is no such module, -\fBARCHIVE_FAILED\fP -will be returned. -.PP -If -\fImodule\fP -is -.BR NULL, -\fIoption\fP -and -\fIvalue\fP -will be provided to every registered module. -If any module returns -\fBARCHIVE_FATAL\fP, -this value will be returned immediately. -Otherwise, -\fBARCHIVE_OK\fP -will be returned if any module accepts the option, and -\fBARCHIVE_FAILED\fP -in all other cases. -.TP -\fB\%archive_write_set_option\fP() -Calls -\fB\%archive_write_set_format_option\fP(), -then -\fB\%archive_write_set_filter_option\fP(). -If either function returns -\fBARCHIVE_FATAL\fP, -\fBARCHIVE_FATAL\fP -will be returned -immediately. -Otherwise, the greater of the two values will be returned. -.TP -\fB\%archive_write_set_options\fP() -\fIoptions\fP -is a comma-separated list of options. -If -\fIoptions\fP -is -.BR NULL -or empty, -\fBARCHIVE_OK\fP -will be returned immediately. -.PP -Individual options have one of the following forms: -.RS 5 -.TP -\fIoption=value\fP -The option/value pair will be provided to every module. -Modules that do not accept an option with this name will ignore it. -.TP -\fIoption\fP -The option will be provided to every module with a value of -``1''. -.TP -\fI!option\fP -The option will be provided to every module with a NULL value. -.TP -\fImodule:option=value\fP, \fImodule:option\fP, \fImodule:!option\fP -As above, but the corresponding option and value will be provided -only to modules whose name matches -\fImodule\fP. -.RE -.RE -.SH OPTIONS -.ad l -.RS 5 -.TP -Filter b64encode -.RS 5 -.TP -\fBmode\fP -The value is interpreted as octal digits specifying the file mode. -.TP -\fBname\fP -The value specifies the file name. -.RE -.TP -Filter bzip2 -.RS 5 -.TP -\fBcompression-level\fP -The value is interpreted as a decimal integer specifying the -bzip2 compression level. Supported values are from 1 to 9. -.RE -.TP -Filter gzip -.RS 5 -.TP -\fBcompression-level\fP -The value is interpreted as a decimal integer specifying the -gzip compression level. Supported values are from 0 to 9. -.TP -\fBtimestamp\fP -Store timestamp. This is enabled by default. -.RE -.TP -Filter lrzip -.RS 5 -.TP -\fBcompression\fP=\fItype\fP -Use -\fItype\fP -as compression method. -Supported values are -``bzip2'', -``gzipi'', -``lzo'' -(ultra fast,) -and -``zpaq'' -(best, extremely slow.) -.TP -\fBcompression-level\fP -The value is interpreted as a decimal integer specifying the -lrzip compression level. Supported values are from 1 to 9. -.RE -.TP -Filter lz4 -.RS 5 -.TP -\fBcompression-level\fP -The value is interpreted as a decimal integer specifying the -lz4 compression level. Supported values are from 0 to 9. -.TP -\fBstream-checksum\fP -Enable stream checksum. This is enabled by default. -.TP -\fBblock-checksum\fP -Enable block checksum. This is disabled by default. -.TP -\fBblock-size\fP -The value is interpreted as a decimal integer specifying the -lz4 compression block size. Supported values are from 4 to 7 -(default.) -.TP -\fBblock-dependence\fP -Use the previous block of the block being compressed for -a compression dictionary to improve compression ratio. -This is disabled by default. -.RE -.TP -Filter lzop -.RS 5 -.TP -\fBcompression-level\fP -The value is interpreted as a decimal integer specifying the -lzop compression level. Supported values are from 1 to 9. -.RE -.TP -Filter uuencode -.RS 5 -.TP -\fBmode\fP -The value is interpreted as octal digits specifying the file mode. -.TP -\fBname\fP -The value specifies the file name. -.RE -.TP -Filter xz -.RS 5 -.TP -\fBcompression-level\fP -The value is interpreted as a decimal integer specifying the -compression level. Supported values are from 0 to 9. -.TP -\fBthreads\fP -The value is interpreted as a decimal integer specifying the -number of threads for multi-threaded lzma compression. -If supported, the default value is read from -\fB\%lzma_cputhreads\fP(). -.RE -.TP -Filter zstd -.RS 5 -.TP -\fBcompression-level\fP -The value is interpreted as a decimal integer specifying the -compression level. Supported values depend on the library version, -common values are from 1 to 22. -.TP -\fBlong\fP -Enables long distance matching. The value is interpreted as a -decimal integer specifying log2 window size in bytes. Values from -10 to 30 for 32 bit, or 31 for 64 bit, are supported. -.TP -\fBthreads\fP -The value is interpreted as a decimal integer specifying the -number of threads for multi-threaded zstd compression. -If set to 0, zstd will attempt to detect and use the number -of physical CPU cores. -.RE -.TP -Format 7zip -.RS 5 -.TP -\fBcompression\fP -The value is one of -``store'', -``deflate'', -``bzip2'', -``lzma1'', -``lzma2'' -or -``ppmd'' -to indicate how the following entries should be compressed. -Note that this setting is ignored for directories, symbolic links, -and other special entries. -.TP -\fBcompression-level\fP -The value is interpreted as a decimal integer specifying the -compression level. -Values between 0 and 9 are supported. -The interpretation of the compression level depends on the chosen -compression method. -.RE -.TP -Format bin -.RS 5 -.TP -\fBhdrcharset\fP -The value is used as a character set name that will be -used when translating file names. -.RE -.TP -Format gnutar -.RS 5 -.TP -\fBhdrcharset\fP -The value is used as a character set name that will be -used when translating file, group and user names. -.RE -.TP -Format iso9660 - volume metadata -These options are used to set standard ISO9660 metadata. -.RS 5 -.TP -\fBabstract-file\fP=\fIfilename\fP -The file with the specified name will be identified in the ISO9660 metadata -as holding the abstract for this volume. -Default: none. -.TP -\fBapplication-id\fP=\fIfilename\fP -The file with the specified name will be identified in the ISO9660 metadata -as holding the application identifier for this volume. -Default: none. -.TP -\fBbiblio-file\fP=\fIfilename\fP -The file with the specified name will be identified in the ISO9660 metadata -as holding the bibliography for this volume. -Default: none. -.TP -\fBcopyright-file\fP=\fIfilename\fP -The file with the specified name will be identified in the ISO9660 metadata -as holding the copyright for this volume. -Default: none. -.TP -\fBpublisher\fP=\fIfilename\fP -The file with the specified name will be identified in the ISO9660 metadata -as holding the publisher information for this volume. -Default: none. -.TP -\fBvolume-id\fP=\fIstring\fP -The specified string will be used as the Volume Identifier in the ISO9660 metadata. -It is limited to 32 bytes. -Default: none. -.RE -.TP -Format iso9660 - boot support -These options are used to make an ISO9660 image that can be directly -booted on various systems. -.RS 5 -.TP -\fBboot\fP=\fIfilename\fP -The file matching this name will be used as the El Torito boot image file. -.TP -\fBboot-catalog\fP=\fIname\fP -The name that will be used for the El Torito boot catalog. -Default: -\fIboot.catalog\fP -.TP -\fBboot-info-table\fP -The boot image file provided by the -\fBboot\fP=\fIfilename\fP -option will be edited with appropriate boot information in bytes 8 through 64. -Default: disabled -.TP -\fBboot-load-seg\fP=\fIhexadecimal-number\fP -The load segment for a no-emulation boot image. -.TP -\fBboot-load-size\fP=\fIdecimal-number\fP -The number of "virtual" 512-byte sectors to be loaded from a no-emulation boot image. -Some very old BIOSes can only load very small images, setting this -value to 4 will often allow such BIOSes to load the first part of -the boot image (which will then need to be intelligent enough to -load the rest of itself). -This should not be needed unless you are trying to support systems with very old BIOSes. -This defaults to the full size of the image. -.TP -\fBboot-type\fP=\fIvalue\fP -Specifies the boot semantics used by the El Torito boot image: -If the -\fIvalue\fP -is -\fBfd\fP, -then the boot image is assumed to be a bootable floppy image. -If the -\fIvalue\fP -is -\fBhd\fP, -then the boot image is assumed to be a bootable hard disk image. -If the -\fIvalue\fP -is -\fBno-emulation\fP, -the boot image is used without floppy or hard disk emulation. -If the boot image is exactly 1.2MB, 1.44MB, or 2.88MB, then -the default is -\fBfd\fP, -otherwise the default is -\fBno-emulation\fP. -.RE -.TP -Format iso9660 - filename and size extensions -Various extensions to the base ISO9660 format. -.RS 5 -.TP -\fBallow-ldots\fP -If enabled, allows filenames to begin with a leading period. -If disabled, filenames that begin with a leading period will have -that period replaced by an underscore character in the standard ISO9660 -namespace. -This does not impact names stored in the Rockridge or Joliet extension area. -Default: disabled. -.TP -\fBallow-lowercase\fP -If enabled, allows filenames to contain lowercase characters. -If disabled, filenames will be forced to uppercase. -This does not impact names stored in the Rockridge or Joliet extension area. -Default: disabled. -.TP -\fBallow-multidot\fP -If enabled, allows filenames to contain multiple period characters, in violation of the ISO9660 specification. -If disabled, additional periods will be converted to underscore characters. -This does not impact names stored in the Rockridge or Joliet extension area. -Default: disabled. -.TP -\fBallow-period\fP -If enabled, allows filenames to contain trailing period characters, in violation of the ISO9660 specification. -If disabled, trailing periods will be converted to underscore characters. -This does not impact names stored in the Rockridge or Joliet extension area. -Default: disabled. -.TP -\fBallow-pvd-lowercase\fP -If enabled, the Primary Volume Descriptor may contain lowercase ASCII characters, in violation of the ISO9660 specification. -If disabled, characters will be converted to uppercase ASCII. -Default: disabled. -.TP -\fBallow-sharp-tilde\fP -If enabled, sharp and tilde characters will be permitted in filenames, in violation if the ISO9660 specification. -If disabled, such characters will be converted to underscore characters. -Default: disabled. -.TP -\fBallow-vernum\fP -If enabled, version numbers will be included with files. -If disabled, version numbers will be suppressed, in violation of the ISO9660 standard. -This does not impact names stored in the Rockridge or Joliet extension area. -Default: enabled. -.TP -\fBiso-level\fP -This enables support for file size and file name extensions in the -core ISO9660 area. -The name extensions specified here do not affect the names stored in the Rockridge or Joliet extension areas. -.RS 5 -.TP -\fBiso-level=1\fP -The most compliant form of ISO9660 image. -Filenames are limited to 8.3 uppercase format, -directory names are limited to 8 uppercase characters, -files are limited to 4 GiB, -the complete ISO9660 image cannot exceed 4 GiB. -.TP -\fBiso-level=2\fP -Filenames are limited to 30 uppercase characters with a 30-character extension, -directory names are limited to 30 characters, -files are limited to 4 GiB. -.TP -\fBiso-level=3\fP -As with -\fBiso-level=2\fP, -except that files may exceed 4 GiB. -.TP -\fBiso-level=4\fP -As with -\fBiso-level=3\fP, -except that filenames may be up to 193 characters -and may include arbitrary 8-bit characters. -.RE -.TP -\fBjoliet\fP -Microsoft's Joliet extensions store a completely separate set of directory information about each file. -In particular, this information includes Unicode filenames of up to 255 characters. -Default: enabled. -.TP -\fBlimit-depth\fP -If enabled, libarchive will use directory relocation records to ensure that -no pathname exceeds the ISO9660 limit of 8 directory levels. -If disabled, no relocation will occur. -Default: enabled. -.TP -\fBlimit-dirs\fP -If enabled, libarchive will cause an error if there are more than -65536 directories. -If disabled, there is no limit on the number of directories. -Default: enabled -.TP -\fBpad\fP -If enabled, 300 kiB of zero bytes will be appended to the end of the archive. -Default: enabled -.TP -\fBrelaxed-filenames\fP -If enabled, all 7-bit ASCII characters are permitted in filenames -(except lowercase characters unless -\fBallow-lowercase\fP -is also specified). -This violates ISO9660 standards. -This does not impact names stored in the Rockridge or Joliet extension area. -Default: disabled. -.TP -\fBrockridge\fP -The Rockridge extensions store an additional set of POSIX-style file -information with each file, including mtime, atime, ctime, permissions, -and long filenames with arbitrary 8-bit characters. -These extensions also support symbolic links and other POSIX file types. -Default: enabled. -.RE -.TP -Format iso9660 - zisofs support -The zisofs extensions permit each file to be independently compressed -using a gzip-compatible compression. -This can provide significant size savings, but requires the reading -system to have support for these extensions. -These extensions are disabled by default. -.RS 5 -.TP -\fBcompression-level\fP=number -The compression level used by the deflate compressor. -Ranges from 0 (least effort) to 9 (most effort). -Default: 6 -.TP -\fBzisofs\fP -Synonym for -\fBzisofs=direct\fP. -.TP -\fBzisofs=direct\fP -Compress each file in the archive. -Unlike -\fBzisofs=indirect\fP, -this is handled entirely within libarchive and does not require a -separate utility. -For best results, libarchive tests each file and will store -the file uncompressed if the compression does not actually save any space. -In particular, files under 2k will never be compressed. -Note that boot image files are never compressed. -.TP -\fBzisofs=indirect\fP -Recognizes files that have already been compressed with the -\fBmkzftree\fP -utility and sets up the necessary file metadata so that -readers will correctly identify these as zisofs-compressed files. -.TP -\fBzisofs-exclude\fP=\fIfilename\fP -Specifies a filename that should not be compressed when using -\fBzisofs=direct\fP. -This option can be provided multiple times to suppress compression -on many files. -.RE -.TP -Format mtree -.RS 5 -.TP -\fBcksum\fP, \fBdevice\fP, \fBflags\fP, \fBgid\fP, \fBgname\fP, \fBindent\fP, \fBlink\fP, \fBmd5\fP, \fBmode\fP, \fBnlink\fP, \fBrmd160\fP, \fBsha1\fP, \fBsha256\fP, \fBsha384\fP, \fBsha512\fP, \fBsize\fP, \fBtime\fP, \fBuid\fP, \fBuname\fP -Enable a particular keyword in the mtree output. -Prefix with an exclamation mark to disable the corresponding keyword. -The default is equivalent to -``device, flags, gid, gname, link, mode, nlink, size, time, type, uid, uname''. -.TP -\fBall\fP -Enables all of the above keywords. -.TP -\fBuse-set\fP -Enables generation of -\fB/set\fP -lines that specify default values for the following files and/or directories. -.TP -\fBindent\fP -XXX needs explanation XXX -.RE -.TP -Format newc -.RS 5 -.TP -\fBhdrcharset\fP -The value is used as a character set name that will be -used when translating file names. -.RE -.TP -Format odc -.RS 5 -.TP -\fBhdrcharset\fP -The value is used as a character set name that will be -used when translating file names. -.RE -.TP -Format pwb -.RS 5 -.TP -\fBhdrcharset\fP -The value is used as a character set name that will be -used when translating file names. -.RE -.TP -Format pax -.RS 5 -.TP -\fBhdrcharset\fP -The value is used as a character set name that will be -used when translating file, group and user names. -The value is one of -``BINARY'' -or -``UTF-8''. -With -``BINARY'' -there is no character conversion, with -``UTF-8'' -names are converted to UTF-8. -.TP -\fBxattrheader\fP -When storing extended attributes, this option configures which -headers should be written. The value is one of -``all'', -``LIBARCHIVE'', -or -``SCHILY''. -By default, both -``LIBARCHIVE.xattr'' -and -``SCHILY.xattr'' -headers are written. -.RE -.TP -Format ustar -.RS 5 -.TP -\fBhdrcharset\fP -The value is used as a character set name that will be -used when translating file, group and user names. -.RE -.TP -Format v7tar -.RS 5 -.TP -\fBhdrcharset\fP -The value is used as a character set name that will be -used when translating file, group and user names. -.RE -.TP -Format warc -.RS 5 -.TP -\fBomit-warcinfo\fP -Set to -``true'' -to disable output of the warcinfo record. -.RE -.TP -Format xar -.RS 5 -.TP -\fBchecksum\fP=\fItype\fP -Use -\fItype\fP -as file checksum method. -Supported values are -``none'', -``md5'', -and -``sha1'' -(default.) -.TP -\fBcompression\fP=\fItype\fP -Use -\fItype\fP -as compression method. -Supported values are -``none'', -``bzip2'', -``gzip'' -(default,) -``lzma'' -and -``xz''. -.TP -\fBcompression_level\fP -The value is a decimal integer from 1 to 9 specifying the compression level. -.TP -\fBtoc-checksum\fP=\fItype\fP -Use -\fItype\fP -as table of contents checksum method. -Supported values are -``none'', -``md5'' -and -``sha1'' -(default.) -.RE -.TP -Format zip -.RS 5 -.TP -\fBcompression\fP -The value is either -``store'' -or -``deflate'' -to indicate how the following entries should be compressed. -Note that this setting is ignored for directories, symbolic links, -and other special entries. -.TP -\fBcompression-level\fP -The value is interpreted as a decimal integer specifying the -compression level. -Values between 0 and 9 are supported. -A compression level of 0 switches the compression method to -``store'', -other values will enable -``deflate'' -compression with the given level. -.TP -\fBencryption\fP -Enable encryption using traditional zip encryption. -.TP -\fBencryption\fP=\fItype\fP -Use -\fItype\fP -as encryption type. -Supported values are -``zipcrypt'' -(traditional zip encryption,) -``aes128'' -(WinZip AES-128 encryption) -and -``aes256'' -(WinZip AES-256 encryption.) -.TP -\fBexperimental\fP -This boolean option enables or disables experimental Zip features -that may not be compatible with other Zip implementations. -.TP -\fBfakecrc32\fP -This boolean option disables CRC calculations. -All CRC fields are set to zero. -It should not be used except for testing purposes. -.TP -\fBhdrcharset\fP -The value is used as a character set name that will be -used when translating file names. -.TP -\fBzip64\fP -Zip64 extensions provide additional file size information -for entries larger than 4 GiB. -They also provide extended file offset and archive size information -when archives exceed 4 GiB. -By default, the Zip writer selectively enables these extensions only as needed. -In particular, if the file size is unknown, the Zip writer will -include Zip64 extensions to guard against the possibility that the -file might be larger than 4 GiB. -.PP -Setting this boolean option will force the writer to use Zip64 extensions -even for small files that would not otherwise require them. -This is primarily useful for testing. -.PP -Disabling this option with -\fB!zip64\fP -will force the Zip writer to avoid Zip64 extensions: -It will reject files with size greater than 4 GiB, -it will reject any new entries once the total archive size reaches 4 GiB, -and it will not use Zip64 extensions for files with unknown size. -In particular, this can improve compatibility when generating archives -where the entry sizes are not known in advance. -.RE -.RE -.SH EXAMPLES -.ad l -The following example creates an archive write handle to -create a gzip-compressed ISO9660 format image. -The two options here specify that the ISO9660 archive will use -\fIkernel.img\fP -as the boot image for El Torito booting, and that the gzip -compressor should use the maximum compression level. -.RS 4 -.nf -a = archive_write_new(); -archive_write_add_filter_gzip(a); -archive_write_set_format_iso9660(a); -archive_write_set_options(a, "boot=kernel.img,compression=9"); -archive_write_open_filename(a, filename, blocksize); -.RE -.SH ERRORS -.ad l -More detailed error codes and textual descriptions are available from the -\fB\%archive_errno\fP() -and -\fB\%archive_error_string\fP() -functions. -.SH SEE ALSO -.ad l -\fBtar\fP(1), -\fBarchive_read_set_options\fP(3), -\fBarchive_write\fP(3), -\fBlibarchive\fP(3) -.SH HISTORY -.ad l -The -\fB\%libarchive\fP -library first appeared in -FreeBSD 5.3. -.SH AUTHORS -.ad l --nosplit -The options support for libarchive was originally implemented by -Michihiro NAKAJIMA. -.SH BUGS -.ad l diff --git a/thirdparty/libarchive/doc/man/archive_write_set_passphrase.3 b/thirdparty/libarchive/doc/man/archive_write_set_passphrase.3 deleted file mode 100644 index 7e6741594..000000000 --- a/thirdparty/libarchive/doc/man/archive_write_set_passphrase.3 +++ /dev/null @@ -1,49 +0,0 @@ -.TH ARCHIVE_WRITE_SET_PASSPHRASE 3 "September 21, 2014" "" -.SH NAME -.ad l -\fB\%archive_write_set_passphrase\fP, -\fB\%archive_write_set_passphrase_callback\fP -\- functions for writing encrypted archives -.SH LIBRARY -.ad l -Streaming Archive Library (libarchive, -larchive) -.SH SYNOPSIS -.ad l -\fB#include \fP -.br -\fIint\fP -.br -\fB\%archive_write_set_passphrase\fP(\fI\%struct\ archive\ *\fP, \fI\%const\ char\ *passphrase\fP); -.br -\fIint\fP -.br -\fB\%archive_write_set_passphrase_callback\fP(\fI\%struct\ archive\ *\fP, \fI\%void\ *client_data\fP, \fI\%archive_passphrase_callback\ *\fP); -.SH DESCRIPTION -.ad l -.RS 5 -.TP -\fB\%archive_write_set_passphrase\fP() -Set a passphrase for writing an encrypted archive. -If -\fIpassphrase\fP -is -.BR NULL -or empty, this function will do nothing and -\fBARCHIVE_FAILED\fP -will be returned. -Otherwise, -\fBARCHIVE_OK\fP -will be returned. -.TP -\fB\%archive_write_set_passphrase_callback\fP() -Register a callback function that will be invoked to get a passphrase -for encryption if the passphrase was not set by the -\fB\%archive_write_set_passphrase\fP() -function. -.RE -.SH SEE ALSO -.ad l -\fBtar\fP(1), -\fBarchive_write\fP(3), -\fBarchive_write_set_options\fP(3), -\fBlibarchive\fP(3) diff --git a/thirdparty/libarchive/doc/man/bsdcpio.1 b/thirdparty/libarchive/doc/man/bsdcpio.1 deleted file mode 100644 index 81135e1a2..000000000 --- a/thirdparty/libarchive/doc/man/bsdcpio.1 +++ /dev/null @@ -1,490 +0,0 @@ -.TH CPIO 1 "September 16, 2014" "" -.SH NAME -.ad l -\fB\%cpio\fP -\- copy files to and from archives -.SH SYNOPSIS -.ad l -.br -\fB\%cpio\fP -\fB\-i\fP -[\fIoptions\fP] -[\fIpattern\fP ...] -[\fI<\fP archive] -.br -\fB\%cpio\fP -\fB\-o\fP -[\fIoptions\fP] -\fI<\fP name-list -[\fI>\fP archive] -.br -\fB\%cpio\fP -\fB\-p\fP -[\fIoptions\fP] -\fIdest-dir\fP -\fI<\fP name-list -.SH DESCRIPTION -.ad l -\fB\%cpio\fP -copies files between archives and directories. -This implementation can extract from tar, pax, cpio, zip, jar, ar, -and ISO 9660 cdrom images and can create tar, pax, cpio, ar, -and shar archives. -.PP -The first option to -\fB\%cpio\fP -is a mode indicator from the following list: -.RS 5 -.TP -\fB\-i\fP -Input. -Read an archive from standard input (unless overridden) and extract the -contents to disk or (if the -\fB\-t\fP -option is specified) -list the contents to standard output. -If one or more file patterns are specified, only files matching -one of the patterns will be extracted. -.TP -\fB\-o\fP -Output. -Read a list of filenames from standard input and produce a new archive -on standard output (unless overridden) containing the specified items. -.TP -\fB\-p\fP -Pass-through. -Read a list of filenames from standard input and copy the files to the -specified directory. -.RE -.SH OPTIONS -.ad l -Unless specifically stated otherwise, options are applicable in -all operating modes. -.RS 5 -.TP -\fB\-0\fP, \fB\-Fl\fP null -Read filenames separated by NUL characters instead of newlines. -This is necessary if any of the filenames being read might contain newlines. -.TP -\fB\-6\fP, \fB\-Fl\fP pwb -When reading a binary format archive, assume it's the earlier one, -from the PWB variant of 6th Edition UNIX. -When writing a cpio archive, use the PWB format. -.TP -\fB\-7\fP, \fB\-Fl\fP binary -(o mode only) -When writing a cpio archive, use the (newer, non-PWB) binary format. -.TP -\fB\-A\fP -(o mode only) -Append to the specified archive. -(Not yet implemented.) -.TP -\fB\-a\fP -(o and p modes) -Reset access times on files after they are read. -.TP -\fB\-B\fP -(o mode only) -Block output to records of 5120 bytes. -.TP -\fB\-C\fP \fIsize\fP -(o mode only) -Block output to records of -\fIsize\fP -bytes. -.TP -\fB\-c\fP -(o mode only) -Use the old POSIX portable character format. -Equivalent to -\fB\-Fl\fP format \fIodc\fP. -.TP -\fB\-d\fP, \fB\-Fl\fP make-directories -(i and p modes) -Create directories as necessary. -.TP -\fB\-E\fP \fIfile\fP -(i mode only) -Read list of file name patterns from -\fIfile\fP -to list and extract. -.TP -\fB\-F\fP \fIfile\fP, \fB\-Fl\fP file \fIfile\fP -Read archive from or write archive to -\fIfile\fP. -.TP -\fB\-f\fP \fIpattern\fP -(i mode only) -Ignore files that match -\fIpattern\fP. -.TP -\fB\-H\fP \fIformat\fP, \fB\-Fl\fP format \fIformat\fP -(o mode only) -Produce the output archive in the specified format. -Supported formats include: -.PP -.RS 5 -.TP -\fIcpio\fP -Synonym for -\fIodc\fP. -.TP -\fInewc\fP -The SVR4 portable cpio format. -.TP -\fIodc\fP -The old POSIX.1 portable octet-oriented cpio format. -.TP -\fIpax\fP -The POSIX.1 pax format, an extension of the ustar format. -.TP -\fIustar\fP -The POSIX.1 tar format. -.RE -.PP -The default format is -\fIodc\fP. -See -\fBlibarchive-formats\fP(5) -for more complete information about the -formats currently supported by the underlying -\fBlibarchive\fP(3) -library. -.TP -\fB\-h\fP, \fB\-Fl\fP help -Print usage information. -.TP -\fB\-I\fP \fIfile\fP -Read archive from -\fIfile\fP. -.TP -\fB\-i\fP, \fB\-Fl\fP extract -Input mode. -See above for description. -.TP -\fB\-Fl\fP insecure -(i and p mode only) -Disable security checks during extraction or copying. -This allows extraction via symbolic links, absolute paths, -and path names containing -Sq .. -in the name. -.TP -\fB\-J\fP, \fB\-Fl\fP xz -(o mode only) -Compress the file with xz-compatible compression before writing it. -In input mode, this option is ignored; xz compression is recognized -automatically on input. -.TP -\fB\-j\fP -Synonym for -\fB\-y\fP. -.TP -\fB\-L\fP -(o and p modes) -All symbolic links will be followed. -Normally, symbolic links are archived and copied as symbolic links. -With this option, the target of the link will be archived or copied instead. -.TP -\fB\-l\fP, \fB\-Fl\fP link -(p mode only) -Create links from the target directory to the original files, -instead of copying. -.TP -\fB\-Fl\fP lrzip -(o mode only) -Compress the resulting archive with -\fBlrzip\fP(1). -In input mode, this option is ignored. -.TP -\fB\-Fl\fP lz4 -(o mode only) -Compress the archive with lz4-compatible compression before writing it. -In input mode, this option is ignored; lz4 compression is recognized -automatically on input. -.TP -\fB\-Fl\fP zstd -(o mode only) -Compress the archive with zstd-compatible compression before writing it. -In input mode, this option is ignored; zstd compression is recognized -automatically on input. -.TP -\fB\-Fl\fP lzma -(o mode only) -Compress the file with lzma-compatible compression before writing it. -In input mode, this option is ignored; lzma compression is recognized -automatically on input. -.TP -\fB\-Fl\fP lzop -(o mode only) -Compress the resulting archive with -\fBlzop\fP(1). -In input mode, this option is ignored. -.TP -\fB\-Fl\fP passphrase \fIpassphrase\fP -The -\fIpassphrase\fP -is used to extract or create an encrypted archive. -Currently, zip is only a format that -\fB\%cpio\fP -can handle encrypted archives. -You shouldn't use this option unless you realize how insecure -use of this option is. -.TP -\fB\-m\fP, \fB\-Fl\fP preserve-modification-time -(i and p modes) -Set file modification time on created files to match -those in the source. -.TP -\fB\-n\fP, \fB\-Fl\fP numeric-uid-gid -(i mode, only with -\fB\-t\fP) -Display numeric uid and gid. -By default, -\fB\%cpio\fP -displays the user and group names when they are provided in the -archive, or looks up the user and group names in the system -password database. -.TP -\fB\-Fl\fP no-preserve-owner -(i mode only) -Do not attempt to restore file ownership. -This is the default when run by non-root users. -.TP -\fB\-O\fP \fIfile\fP -Write archive to -\fIfile\fP. -.TP -\fB\-o\fP, \fB\-Fl\fP create -Output mode. -See above for description. -.TP -\fB\-p\fP, \fB\-Fl\fP pass-through -Pass-through mode. -See above for description. -.TP -\fB\-Fl\fP preserve-owner -(i mode only) -Restore file ownership. -This is the default when run by the root user. -.TP -\fB\-Fl\fP quiet -Suppress unnecessary messages. -.TP -\fB\-R\fP [user] [:] [group], \fB\-Fl\fP owner [user] [:] [group] -Set the owner and/or group on files in the output. -If group is specified with no user -(for example, -\fB\-R\fP \fI:wheel\fP) -then the group will be set but not the user. -If the user is specified with a trailing colon and no group -(for example, -\fB\-R\fP \fIroot:\fP) -then the group will be set to the user's default group. -If the user is specified with no trailing colon, then -the user will be set but not the group. -In -\fB\-i\fP -and -\fB\-p\fP -modes, this option can only be used by the super-user. -(For compatibility, a period can be used in place of the colon.) -.TP -\fB\-r\fP -(All modes.) -Rename files interactively. -For each file, a prompt is written to -\fI/dev/tty\fP -containing the name of the file and a line is read from -\fI/dev/tty\fP. -If the line read is blank, the file is skipped. -If the line contains a single period, the file is processed normally. -Otherwise, the line is taken to be the new name of the file. -.TP -\fB\-t\fP, \fB\-Fl\fP list -(i mode only) -List the contents of the archive to stdout; -do not restore the contents to disk. -.TP -\fB\-u\fP, \fB\-Fl\fP unconditional -(i and p modes) -Unconditionally overwrite existing files. -Ordinarily, an older file will not overwrite a newer file on disk. -.TP -\fB\-V\fP, \fB\-Fl\fP dot -Print a dot to stderr for each file as it is processed. -Superseded by -\fB\-v\fP. -.TP -\fB\-v\fP, \fB\-Fl\fP verbose -Print the name of each file to stderr as it is processed. -With -\fB\-t\fP, -provide a detailed listing of each file. -.TP -\fB\-Fl\fP version -Print the program version information and exit. -.TP -\fB\-y\fP -(o mode only) -Compress the archive with bzip2-compatible compression before writing it. -In input mode, this option is ignored; -bzip2 compression is recognized automatically on input. -.TP -\fB\-Z\fP -(o mode only) -Compress the archive with compress-compatible compression before writing it. -In input mode, this option is ignored; -compression is recognized automatically on input. -.TP -\fB\-z\fP -(o mode only) -Compress the archive with gzip-compatible compression before writing it. -In input mode, this option is ignored; -gzip compression is recognized automatically on input. -.RE -.SH EXIT STATUS -.ad l -The \fBcpio\fP utility exits 0 on success, and >0 if an error occurs. -.SH ENVIRONMENT -.ad l -The following environment variables affect the execution of -\fB\%cpio\fP: -.RS 5 -.TP -.B LANG -The locale to use. -See -\fBenviron\fP(7) -for more information. -.TP -.B TZ -The timezone to use when displaying dates. -See -\fBenviron\fP(7) -for more information. -.RE -.SH EXAMPLES -.ad l -The -\fB\%cpio\fP -command is traditionally used to copy file hierarchies in conjunction -with the -\fBfind\fP(1) -command. -The first example here simply copies all files from -\fIsrc\fP -to -\fIdest\fP: -.RS 4 -\fB\%find\fP \fIsrc\fP | \fB\%cpio\fP \fB\-pmud\fP \fIdest\fP -.RE -.PP -By carefully selecting options to the -\fBfind\fP(1) -command and combining it with other standard utilities, -it is possible to exercise very fine control over which files are copied. -This next example copies files from -\fIsrc\fP -to -\fIdest\fP -that are more than 2 days old and whose names match a particular pattern: -.RS 4 -\fB\%find\fP \fIsrc\fP \fB\-mtime\fP \fI+2\fP | \fB\%grep\fP foo[bar] | \fB\%cpio\fP \fB\-pdmu\fP \fIdest\fP -.RE -.PP -This example copies files from -\fIsrc\fP -to -\fIdest\fP -that are more than 2 days old and which contain the word -``foobar'': -.RS 4 -\fB\%find\fP \fIsrc\fP \fB\-mtime\fP \fI+2\fP | \fB\%xargs\fP \fB\%grep\fP -l foobar | \fB\%cpio\fP \fB\-pdmu\fP \fIdest\fP -.RE -.SH COMPATIBILITY -.ad l -The mode options i, o, and p and the options -a, B, c, d, f, l, m, r, t, u, and v comply with SUSv2. -.PP -The old POSIX.1 standard specified that only -\fB\-i\fP, -\fB\-o\fP, -and -\fB\-p\fP -were interpreted as command-line options. -Each took a single argument of a list of modifier -characters. -For example, the standard syntax allows -\fB\-imu\fP -but does not support -\fB\-miu\fP -or -\fB\-i\fP \fB\-m\fP \fB\-u\fP, -since -\fIm\fP -and -\fIu\fP -are only modifiers to -\fB\-i\fP, -they are not command-line options in their own right. -The syntax supported by this implementation is backwards-compatible -with the standard. -For best compatibility, scripts should limit themselves to the -standard syntax. -.SH SEE ALSO -.ad l -\fBbzip2\fP(1), -\fBgzip\fP(1), -\fBmt\fP(1), -\fBpax\fP(1), -\fBtar\fP(1), -\fBlibarchive\fP(3), -\fBcpio\fP(5), -\fBlibarchive-formats\fP(5), -\fBtar\fP(5) -.SH STANDARDS -.ad l -There is no current POSIX standard for the cpio command; it appeared -in -ISO/IEC 9945-1:1996 (``POSIX.1'') -but was dropped from -IEEE Std 1003.1-2001 (``POSIX.1''). -.PP -The cpio, ustar, and pax interchange file formats are defined by -IEEE Std 1003.1-2001 (``POSIX.1'') -for the pax command. -.SH HISTORY -.ad l -The original -\fB\%cpio\fP -and -\fB\%find\fP -utilities were written by Dick Haight -while working in AT&T's Unix Support Group. -They first appeared in 1977 in PWB/UNIX 1.0, the -``Programmer's Work Bench'' -system developed for use within AT&T. -They were first released outside of AT&T as part of System III Unix in 1981. -As a result, -\fB\%cpio\fP -actually predates -\fB\%tar\fP, -even though it was not well-known outside of AT&T until some time later. -.PP -This is a complete re-implementation based on the -\fBlibarchive\fP(3) -library. -.SH BUGS -.ad l -The cpio archive format has several basic limitations: -It does not store user and group names, only numbers. -As a result, it cannot be reliably used to transfer -files between systems with dissimilar user and group numbering. -Older cpio formats limit the user and group numbers to -16 or 18 bits, which is insufficient for modern systems. -The cpio archive formats cannot support files over 4 gigabytes, -except for the -``odc'' -variant, which can support files up to 8 gigabytes. diff --git a/thirdparty/libarchive/doc/man/bsdtar.1 b/thirdparty/libarchive/doc/man/bsdtar.1 deleted file mode 100644 index 337dfa5c1..000000000 --- a/thirdparty/libarchive/doc/man/bsdtar.1 +++ /dev/null @@ -1,1515 +0,0 @@ -.TH TAR 1 "December 1, 2022" "" -.SH NAME -.ad l -\fB\%tar\fP -\- manipulate tape archives -.SH SYNOPSIS -.ad l -.br -\fB\%tar\fP -[\fIbundled-flags\fP ] -[<\fIfile\fP> | <\fIpattern\fP> ...] -.br -\fB\%tar\fP -{\fB\-c\fP} -[\fIoptions\fP] -[\fIfiles\fP | \fIdirectories\fP] -.br -\fB\%tar\fP -{\fB\-r\fP | \fB\-u\fP} -\fB\-f\fP \fIarchive-file\fP -[\fIoptions\fP] -[\fIfiles\fP | \fIdirectories\fP] -.br -\fB\%tar\fP -{\fB\-t\fP | \fB\-x\fP} -[\fIoptions\fP] -[\fIpatterns\fP] -.SH DESCRIPTION -.ad l -\fB\%tar\fP -creates and manipulates streaming archive files. -This implementation can extract from tar, pax, cpio, zip, jar, ar, xar, -rpm, 7-zip, and ISO 9660 cdrom images and can create tar, pax, cpio, ar, zip, -7-zip, and shar archives. -.PP -The first synopsis form shows a -``bundled'' -option word. -This usage is provided for compatibility with historical implementations. -See COMPATIBILITY below for details. -.PP -The other synopsis forms show the preferred usage. -The first option to -\fB\%tar\fP -is a mode indicator from the following list: -.RS 5 -.TP -\fB\-c\fP -Create a new archive containing the specified items. -The long option form is -\fB\-Fl\fP create. -.TP -\fB\-r\fP -Like -\fB\-c\fP, -but new entries are appended to the archive. -Note that this only works on uncompressed archives stored in regular files. -The -\fB\-f\fP -option is required. -The long option form is -\fB\-Fl\fP append. -.TP -\fB\-t\fP -List archive contents to stdout. -The long option form is -\fB\-Fl\fP list. -.TP -\fB\-u\fP -Like -\fB\-r\fP, -but new entries are added only if they have a modification date -newer than the corresponding entry in the archive. -Note that this only works on uncompressed archives stored in regular files. -The -\fB\-f\fP -option is required. -The long form is -\fB\-Fl\fP update. -.TP -\fB\-x\fP -Extract to disk from the archive. -If a file with the same name appears more than once in the archive, -each copy will be extracted, with later copies overwriting (replacing) -earlier copies. -The long option form is -\fB\-Fl\fP extract. -.RE -.PP -In -\fB\-c\fP, -\fB\-r\fP, -or -\fB\-u\fP -mode, each specified file or directory is added to the -archive in the order specified on the command line. -By default, the contents of each directory are also archived. -.PP -In extract or list mode, the entire command line -is read and parsed before the archive is opened. -The pathnames or patterns on the command line indicate -which items in the archive should be processed. -Patterns are shell-style globbing patterns as -documented in -\fBtcsh\fP(1). -.SH OPTIONS -.ad l -Unless specifically stated otherwise, options are applicable in -all operating modes. -.RS 5 -.TP -\fB@\fP \fIarchive\fP -(c and r modes only) -The specified archive is opened and the entries -in it will be appended to the current archive. -As a simple example, -.RS 4 -\fB\%tar\fP \fB\-c\fP \fB\-f\fP \fI-\fP \fInewfile\fP \fB@\fP \fIoriginal.tar\fP -.RE -writes a new archive to standard output containing a file -\fInewfile\fP -and all of the entries from -\fIoriginal.tar\fP. -In contrast, -.RS 4 -\fB\%tar\fP \fB\-c\fP \fB\-f\fP \fI-\fP \fInewfile\fP \fIoriginal.tar\fP -.RE -creates a new archive with only two entries. -Similarly, -.RS 4 -\fB\%tar\fP \fB\-czf\fP \fI-\fP \fB\-Fl\fP format \fBpax\fP \fB@\fP \fI-\fP -.RE -reads an archive from standard input (whose format will be determined -automatically) and converts it into a gzip-compressed -pax-format archive on stdout. -In this way, -\fB\%tar\fP -can be used to convert archives from one format to another. -.TP -\fB\-a\fP, \fB\-Fl\fP auto-compress -(c mode only) -Use the archive suffix to decide a set of the format and -the compressions. -As a simple example, -.RS 4 -\fB\%tar\fP \fB\-a\fP \fB\-cf\fP \fIarchive.tgz\fP source.c source.h -.RE -creates a new archive with restricted pax format and gzip compression, -.RS 4 -\fB\%tar\fP \fB\-a\fP \fB\-cf\fP \fIarchive.tar.bz2.uu\fP source.c source.h -.RE -creates a new archive with restricted pax format and bzip2 compression -and uuencode compression, -.RS 4 -\fB\%tar\fP \fB\-a\fP \fB\-cf\fP \fIarchive.zip\fP source.c source.h -.RE -creates a new archive with zip format, -.RS 4 -\fB\%tar\fP \fB\-a\fP \fB\-jcf\fP \fIarchive.tgz\fP source.c source.h -.RE -ignores the -``-j'' -option, and creates a new archive with restricted pax format -and gzip compression, -.RS 4 -\fB\%tar\fP \fB\-a\fP \fB\-jcf\fP \fIarchive.xxx\fP source.c source.h -.RE -if it is unknown suffix or no suffix, creates a new archive with -restricted pax format and bzip2 compression. -.TP -\fB\-Fl\fP acls -(c, r, u, x modes only) -Archive or extract POSIX.1e or NFSv4 ACLs. -This is the reverse of -\fB\-Fl\fP no-acls -and the default behavior in c, r, and u modes (except on Mac OS X) or if -\fB\%tar\fP -is run in x mode as root. -On Mac OS X this option translates extended ACLs to NFSv4 ACLs. -To store extended ACLs the -\fB\-Fl\fP mac-metadata -option is preferred. -.TP -\fB\-B\fP, \fB\-Fl\fP read-full-blocks -Ignored for compatibility with other -\fBtar\fP(1) -implementations. -.TP -\fB\-b\fP \fIblocksize\fP, \fB\-Fl\fP block-size \fIblocksize\fP -Specify the block size, in 512-byte records, for tape drive I/O. -As a rule, this argument is only needed when reading from or writing -to tape drives, and usually not even then as the default block size of -20 records (10240 bytes) is very common. -.TP -\fB\-C\fP \fIdirectory\fP, \fB\-Fl\fP cd \fIdirectory\fP, \fB\-Fl\fP directory \fIdirectory\fP -In c and r mode, this changes the directory before adding -the following files. -In x mode, change directories after opening the archive -but before extracting entries from the archive. -.TP -\fB\-Fl\fP chroot -(x mode only) -\fB\%chroot\fP() -to the current directory after processing any -\fB\-C\fP -options and before extracting any files. -.TP -\fB\-Fl\fP clear-nochange-fflags -(x mode only) -Before removing file system objects to replace them, clear platform-specific -file attributes or file flags that might prevent removal. -.TP -\fB\-Fl\fP exclude \fIpattern\fP -Do not process files or directories that match the -specified pattern. -Note that exclusions take precedence over patterns or filenames -specified on the command line. -.TP -\fB\-Fl\fP exclude-vcs -Do not process files or directories internally used by the -version control systems -Sq Arch, -Sq Bazaar, -Sq CVS, -Sq Darcs, -Sq Mercurial, -Sq RCS, -Sq SCCS, -Sq SVN -and -Sq git. -.TP -\fB\-Fl\fP fflags -(c, r, u, x modes only) -Archive or extract platform-specific file attributes or file flags. -This is the reverse of -\fB\-Fl\fP no-fflags -and the default behavior in c, r, and u modes or if -\fB\%tar\fP -is run in x mode as root. -.TP -\fB\-Fl\fP format \fIformat\fP -(c, r, u mode only) -Use the specified format for the created archive. -Supported formats include -``cpio'', -``pax'', -``shar'', -and -``ustar''. -Other formats may also be supported; see -\fBlibarchive-formats\fP(5) -for more information about currently-supported formats. -In r and u modes, when extending an existing archive, the format specified -here must be compatible with the format of the existing archive on disk. -.TP -\fB\-f\fP \fIfile\fP, \fB\-Fl\fP file \fIfile\fP -Read the archive from or write the archive to the specified file. -The filename can be -\fI-\fP -for standard input or standard output. -The default varies by system; -on -FreeBSD, -the default is -\fI/dev/sa0\fP; -on Linux, the default is -\fI/dev/st0\fP. -.TP -\fB\-Fl\fP gid \fIid\fP -Use the provided group id number. -On extract, this overrides the group id in the archive; -the group name in the archive will be ignored. -On create, this overrides the group id read from disk; -if -\fB\-Fl\fP gname -is not also specified, the group name will be set to -match the group id. -.TP -\fB\-Fl\fP gname \fIname\fP -Use the provided group name. -On extract, this overrides the group name in the archive; -if the provided group name does not exist on the system, -the group id -(from the archive or from the -\fB\-Fl\fP gid -option) -will be used instead. -On create, this sets the group name that will be stored -in the archive; -the name will not be verified against the system group database. -.TP -\fB\-H\fP -(c and r modes only) -Symbolic links named on the command line will be followed; the -target of the link will be archived, not the link itself. -.TP -\fB\-h\fP -(c and r modes only) -Synonym for -\fB\-L\fP. -.TP -\fB\-I\fP -Synonym for -\fB\-T\fP. -.TP -\fB\-Fl\fP help -Show usage. -.TP -\fB\-Fl\fP hfsCompression -(x mode only) -Mac OS X specific (v10.6 or later). Compress extracted regular files with HFS+ -compression. -.TP -\fB\-Fl\fP ignore-zeros -An alias of -\fB\-Fl\fP options \fBread_concatenated_archives\fP -for compatibility with GNU tar. -.TP -\fB\-Fl\fP include \fIpattern\fP -Process only files or directories that match the specified pattern. -Note that exclusions specified with -\fB\-Fl\fP exclude -take precedence over inclusions. -If no inclusions are explicitly specified, all entries are processed by -default. -The -\fB\-Fl\fP include -option is especially useful when filtering archives. -For example, the command -.RS 4 -\fB\%tar\fP \fB\-c\fP \fB\-f\fP \fInew.tar\fP \fB\-Fl\fP include='*foo*' \fB@\fP \fIold.tgz\fP -.RE -creates a new archive -\fInew.tar\fP -containing only the entries from -\fIold.tgz\fP -containing the string -Sq foo. -.TP -\fB\-J\fP, \fB\-Fl\fP xz -(c mode only) -Compress the resulting archive with -\fBxz\fP(1). -In extract or list modes, this option is ignored. -Note that this -\fB\%tar\fP -implementation recognizes XZ compression automatically when reading archives. -.TP -\fB\-j\fP, \fB\-Fl\fP bzip, \fB\-Fl\fP bzip2, \fB\-Fl\fP bunzip2 -(c mode only) -Compress the resulting archive with -\fBbzip2\fP(1). -In extract or list modes, this option is ignored. -Note that this -\fB\%tar\fP -implementation recognizes bzip2 compression automatically when reading -archives. -.TP -\fB\-k\fP, \fB\-Fl\fP keep-old-files -(x mode only) -Do not overwrite existing files. -In particular, if a file appears more than once in an archive, -later copies will not overwrite earlier copies. -.TP -\fB\-Fl\fP keep-newer-files -(x mode only) -Do not overwrite existing files that are newer than the -versions appearing in the archive being extracted. -.TP -\fB\-L\fP, \fB\-Fl\fP dereference -(c and r modes only) -All symbolic links will be followed. -Normally, symbolic links are archived as such. -With this option, the target of the link will be archived instead. -.TP -\fB\-l\fP, \fB\-Fl\fP check-links -(c and r modes only) -Issue a warning message unless all links to each file are archived. -.TP -\fB\-Fl\fP lrzip -(c mode only) -Compress the resulting archive with -\fBlrzip\fP(1). -In extract or list modes, this option is ignored. -Note that this -\fB\%tar\fP -implementation recognizes lrzip compression automatically when reading -archives. -.TP -\fB\-Fl\fP lz4 -(c mode only) -Compress the archive with lz4-compatible compression before writing it. -In extract or list modes, this option is ignored. -Note that this -\fB\%tar\fP -implementation recognizes lz4 compression automatically when reading archives. -.TP -\fB\-Fl\fP zstd -(c mode only) -Compress the archive with zstd-compatible compression before writing it. -In extract or list modes, this option is ignored. -Note that this -\fB\%tar\fP -implementation recognizes zstd compression automatically when reading archives. -.TP -\fB\-Fl\fP lzma -(c mode only) Compress the resulting archive with the original LZMA algorithm. -In extract or list modes, this option is ignored. -Use of this option is discouraged and new archives should be created with -\fB\-Fl\fP xz -instead. -Note that this -\fB\%tar\fP -implementation recognizes LZMA compression automatically when reading archives. -.TP -\fB\-Fl\fP lzop -(c mode only) -Compress the resulting archive with -\fBlzop\fP(1). -In extract or list modes, this option is ignored. -Note that this -\fB\%tar\fP -implementation recognizes LZO compression automatically when reading archives. -.TP -\fB\-m\fP, \fB\-Fl\fP modification-time -(x mode only) -Do not extract modification time. -By default, the modification time is set to the time stored in the archive. -.TP -\fB\-Fl\fP mac-metadata -(c, r, u and x mode only) -Mac OS X specific. -Archive or extract extended ACLs and extended file -attributes using -\fBcopyfile\fP(3) -in AppleDouble format. -This is the reverse of -\fB\-Fl\fP no-mac-metadata. -and the default behavior in c, r, and u modes or if -\fB\%tar\fP -is run in x mode as root. -.TP -\fB\-n\fP, \fB\-Fl\fP norecurse, \fB\-Fl\fP no-recursion -Do not operate recursively on the content of directories. -.TP -\fB\-Fl\fP newer \fIdate\fP -(c, r, u modes only) -Only include files and directories newer than the specified date. -This compares ctime entries. -.TP -\fB\-Fl\fP newer-mtime \fIdate\fP -(c, r, u modes only) -Like -\fB\-Fl\fP newer, -except it compares mtime entries instead of ctime entries. -.TP -\fB\-Fl\fP newer-than \fIfile\fP -(c, r, u modes only) -Only include files and directories newer than the specified file. -This compares ctime entries. -.TP -\fB\-Fl\fP newer-mtime-than \fIfile\fP -(c, r, u modes only) -Like -\fB\-Fl\fP newer-than, -except it compares mtime entries instead of ctime entries. -.TP -\fB\-Fl\fP nodump -(c and r modes only) -Honor the nodump file flag by skipping this file. -.TP -\fB\-Fl\fP nopreserveHFSCompression -(x mode only) -Mac OS X specific (v10.6 or later). Do not compress extracted regular files -which were compressed with HFS+ compression before archived. -By default, compress the regular files again with HFS+ compression. -.TP -\fB\-Fl\fP null -(use with -\fB\-I\fP -or -\fB\-T\fP) -Filenames or patterns are separated by null characters, -not by newlines. -This is often used to read filenames output by the -\fB\-print0\fP -option to -\fBfind\fP(1). -.TP -\fB\-Fl\fP no-acls -(c, r, u, x modes only) -Do not archive or extract POSIX.1e or NFSv4 ACLs. -This is the reverse of -\fB\-Fl\fP acls -and the default behavior if -\fB\%tar\fP -is run as non-root in x mode (on Mac OS X as any user in c, r, u and x modes). -.TP -\fB\-Fl\fP no-fflags -(c, r, u, x modes only) -Do not archive or extract file attributes or file flags. -This is the reverse of -\fB\-Fl\fP fflags -and the default behavior if -\fB\%tar\fP -is run as non-root in x mode. -.TP -\fB\-Fl\fP no-mac-metadata -(x mode only) -Mac OS X specific. -Do not archive or extract ACLs and extended file attributes -using -\fBcopyfile\fP(3) -in AppleDouble format. -This is the reverse of -\fB\-Fl\fP mac-metadata. -and the default behavior if -\fB\%tar\fP -is run as non-root in x mode. -.TP -\fB\-Fl\fP no-read-sparse -(c, r, u modes only) -Do not read sparse file information from disk. -This is the reverse of -\fB\-Fl\fP read-sparse. -.TP -\fB\-Fl\fP no-safe-writes -(x mode only) -Do not create temporary files and use -\fBrename\fP(2) -to replace the original ones. -This is the reverse of -\fB\-Fl\fP safe-writes. -.TP -\fB\-Fl\fP no-same-owner -(x mode only) -Do not extract owner and group IDs. -This is the reverse of -\fB\-Fl\fP same-owner -and the default behavior if -\fB\%tar\fP -is run as non-root. -.TP -\fB\-Fl\fP no-same-permissions -(x mode only) -Do not extract full permissions (SGID, SUID, sticky bit, -file attributes or file flags, extended file attributes and ACLs). -This is the reverse of -\fB\-p\fP -and the default behavior if -\fB\%tar\fP -is run as non-root. -.TP -\fB\-Fl\fP no-xattrs -(c, r, u, x modes only) -Do not archive or extract extended file attributes. -This is the reverse of -\fB\-Fl\fP xattrs -and the default behavior if -\fB\%tar\fP -is run as non-root in x mode. -.TP -\fB\-Fl\fP numeric-owner -This is equivalent to -\fB\-Fl\fP uname -Qq -\fB\-Fl\fP gname -Qq. -On extract, it causes user and group names in the archive -to be ignored in favor of the numeric user and group ids. -On create, it causes user and group names to not be stored -in the archive. -.TP -\fB\-O\fP, \fB\-Fl\fP to-stdout -(x, t modes only) -In extract (-x) mode, files will be written to standard out rather than -being extracted to disk. -In list (-t) mode, the file listing will be written to stderr rather than -the usual stdout. -.TP -\fB\-o\fP -(x mode) -Use the user and group of the user running the program rather -than those specified in the archive. -Note that this has no significance unless -\fB\-p\fP -is specified, and the program is being run by the root user. -In this case, the file modes and flags from -the archive will be restored, but ACLs or owner information in -the archive will be discarded. -.TP -\fB\-o\fP -(c, r, u mode) -A synonym for -\fB\-Fl\fP format \fIustar\fP -.TP -\fB\-Fl\fP older \fIdate\fP -(c, r, u modes only) -Only include files and directories older than the specified date. -This compares ctime entries. -.TP -\fB\-Fl\fP older-mtime \fIdate\fP -(c, r, u modes only) -Like -\fB\-Fl\fP older, -except it compares mtime entries instead of ctime entries. -.TP -\fB\-Fl\fP older-than \fIfile\fP -(c, r, u modes only) -Only include files and directories older than the specified file. -This compares ctime entries. -.TP -\fB\-Fl\fP older-mtime-than \fIfile\fP -(c, r, u modes only) -Like -\fB\-Fl\fP older-than, -except it compares mtime entries instead of ctime entries. -.TP -\fB\-Fl\fP one-file-system -(c, r, and u modes) -Do not cross mount points. -.TP -\fB\-Fl\fP options \fIoptions\fP -Select optional behaviors for particular modules. -The argument is a text string containing comma-separated -keywords and values. -These are passed to the modules that handle particular -formats to control how those formats will behave. -Each option has one of the following forms: -.RS 5 -.TP -\fIkey=value\fP -The key will be set to the specified value in every module that supports it. -Modules that do not support this key will ignore it. -.TP -\fIkey\fP -The key will be enabled in every module that supports it. -This is equivalent to -\fIkey\fP \fB=1\fP. -.TP -\fI!key\fP -The key will be disabled in every module that supports it. -.TP -\fImodule:key=value\fP, \fImodule:key\fP, \fImodule:!key\fP -As above, but the corresponding key and value will be provided -only to modules whose name matches -\fImodule\fP. -.RE -.PP -The complete list of supported modules and keys -for create and append modes is in -\fBarchive_write_set_options\fP(3) -and for extract and list modes in -\fBarchive_read_set_options\fP(3). -.PP -Examples of supported options: -.RS 5 -.TP -\fBiso9660:joliet\fP -Support Joliet extensions. -This is enabled by default, use -\fB!joliet\fP -or -\fBiso9660:!joliet\fP -to disable. -.TP -\fBiso9660:rockridge\fP -Support Rock Ridge extensions. -This is enabled by default, use -\fB!rockridge\fP -or -\fBiso9660:!rockridge\fP -to disable. -.TP -\fBgzip:compression-level\fP -A decimal integer from 1 to 9 specifying the gzip compression level. -.TP -\fBgzip:timestamp\fP -Store timestamp. -This is enabled by default, use -\fB!timestamp\fP -or -\fBgzip:!timestamp\fP -to disable. -.TP -\fBlrzip:compression\fP=\fItype\fP -Use -\fItype\fP -as compression method. -Supported values are bzip2, gzip, lzo (ultra fast), -and zpaq (best, extremely slow). -.TP -\fBlrzip:compression-level\fP -A decimal integer from 1 to 9 specifying the lrzip compression level. -.TP -\fBlz4:compression-level\fP -A decimal integer from 1 to 9 specifying the lzop compression level. -.TP -\fBlz4:stream-checksum\fP -Enable stream checksum. -This is by default, use -\fBlz4:!stream-checksum\fP -to disable. -.TP -\fBlz4:block-checksum\fP -Enable block checksum (Disabled by default). -.TP -\fBlz4:block-size\fP -A decimal integer from 4 to 7 specifying the lz4 compression block size -(7 is set by default). -.TP -\fBlz4:block-dependence\fP -Use the previous block of the block being compressed for -a compression dictionary to improve compression ratio. -.TP -\fBzstd:compression-level\fP -A decimal integer specifying the zstd compression level. Supported values depend -on the library version, common values are from 1 to 22. -.TP -\fBzstd:threads\fP -Specify the number of worker threads to use. -Setting threads to a special value 0 makes -\fBzstd\fP(1) -use as many threads as there are CPU cores on the system. -.TP -\fBzstd:frame-per-file\fP -Start a new compression frame at the beginning of each file in the -archive. -.TP -\fBzstd:min-frame-size\fP=\fIN\fP -In combination with -\fBzstd:frame-per-file\fP, -do not start a new compression frame unless the current frame is at least -\fIN\fP -bytes. -.TP -\fBzstd:max-frame-size\fP=\fIN\fP -Start a new compression frame as soon as the current frame exceeds -\fIN\fP -bytes. -.TP -\fBlzop:compression-level\fP -A decimal integer from 1 to 9 specifying the lzop compression level. -.TP -\fBxz:compression-level\fP -A decimal integer from 0 to 9 specifying the xz compression level. -.TP -\fBxz:threads\fP -Specify the number of worker threads to use. -Setting threads to a special value 0 makes -\fBxz\fP(1) -use as many threads as there are CPU cores on the system. -.TP -\fBmtree:\fP \fIkeyword\fP -The mtree writer module allows you to specify which mtree keywords -will be included in the output. -Supported keywords include: -\fBcksum\fP, \fBdevice\fP, \fBflags\fP, \fBgid\fP, \fBgname\fP, \fBindent\fP, -\fBlink\fP, \fBmd5\fP, \fBmode\fP, \fBnlink\fP, \fBrmd160\fP, \fBsha1\fP, \fBsha256\fP, -\fBsha384\fP, \fBsha512\fP, \fBsize\fP, \fBtime\fP, \fBuid\fP, \fBuname\fP. -The default is equivalent to: -``device, flags, gid, gname, link, mode, nlink, size, time, type, uid, uname''. -.TP -\fBmtree:all\fP -Enables all of the above keywords. -You can also use -\fBmtree:!all\fP -to disable all keywords. -.TP -\fBmtree:use-set\fP -Enable generation of -\fB/set\fP -lines in the output. -.TP -\fBmtree:indent\fP -Produce human-readable output by indenting options and splitting lines -to fit into 80 columns. -.TP -\fBzip:compression\fP=\fItype\fP -Use -\fItype\fP -as compression method. -Supported values are store (uncompressed) and deflate (gzip algorithm). -.TP -\fBzip:encryption\fP -Enable encryption using traditional zip encryption. -.TP -\fBzip:encryption\fP=\fItype\fP -Use -\fItype\fP -as encryption type. -Supported values are zipcrypt (traditional zip encryption), -aes128 (WinZip AES-128 encryption) and aes256 (WinZip AES-256 encryption). -.TP -\fBread_concatenated_archives\fP -Ignore zeroed blocks in the archive, which occurs when multiple tar archives -have been concatenated together. -Without this option, only the contents of -the first concatenated archive would be read. -This option is comparable to the -\fB\-i\fP, \fB\-Fl\fP ignore-zeros -option of GNU tar. -.RE -If a provided option is not supported by any module, that -is a fatal error. -.TP -\fB\-P\fP, \fB\-Fl\fP absolute-paths -Preserve pathnames. -By default, absolute pathnames (those that begin with a / -character) have the leading slash removed both when creating archives -and extracting from them. -Also, -\fB\%tar\fP -will refuse to extract archive entries whose pathnames contain -\fI\& ..\fP -or whose target directory would be altered by a symlink. -This option suppresses these behaviors. -.TP -\fB\-p\fP, \fB\-Fl\fP insecure, \fB\-Fl\fP preserve-permissions -(x mode only) -Preserve file permissions. -Attempt to restore the full permissions, including file modes, file attributes -or file flags, extended file attributes and ACLs, if available, for each item -extracted from the archive. -This is the reverse of -\fB\-Fl\fP no-same-permissions -and the default if -\fB\%tar\fP -is being run as root. -It can be partially overridden by also specifying -\fB\-Fl\fP no-acls, -\fB\-Fl\fP no-fflags, -\fB\-Fl\fP no-mac-metadata -or -\fB\-Fl\fP no-xattrs. -.TP -\fB\-Fl\fP passphrase \fIpassphrase\fP -The -\fIpassphrase\fP -is used to extract or create an encrypted archive. -Currently, zip is the only supported format that supports encryption. -You shouldn't use this option unless you realize how insecure -use of this option is. -.TP -\fB\-Fl\fP posix -(c, r, u mode only) -Synonym for -\fB\-Fl\fP format \fIpax\fP -.TP -\fB\-q\fP, \fB\-Fl\fP fast-read -(x and t mode only) -Extract or list only the first archive entry that matches each pattern -or filename operand. -Exit as soon as each specified pattern or filename has been matched. -By default, the archive is always read to the very end, since -there can be multiple entries with the same name and, by convention, -later entries overwrite earlier entries. -This option is provided as a performance optimization. -.TP -\fB\-Fl\fP read-sparse -(c, r, u modes only) -Read sparse file information from disk. -This is the reverse of -\fB\-Fl\fP no-read-sparse -and the default behavior. -.TP -\fB\-S\fP -(x mode only) -Extract files as sparse files. -For every block on disk, check first if it contains only NULL bytes and seek -over it otherwise. -This works similar to the conv=sparse option of dd. -.TP -\fB\-s\fP \fIpattern\fP -Modify file or archive member names according to -\fIpattern\fP. -The pattern has the format -\fI/old/new/\fP [ghHprRsS] -where -\fIold\fP -is a basic regular expression, -\fInew\fP -is the replacement string of the matched part, -and the optional trailing letters modify -how the replacement is handled. -If -\fIold\fP -is not matched, the pattern is skipped. -Within -\fInew\fP, -~ is substituted with the match, \e1 to \e9 with the content of -the corresponding captured group. -The optional trailing g specifies that matching should continue -after the matched part and stop on the first unmatched pattern. -The optional trailing s specifies that the pattern applies to the value -of symbolic links. -The optional trailing p specifies that after a successful substitution -the original path name and the new path name should be printed to -standard error. -Optional trailing H, R, or S characters suppress substitutions -for hardlink targets, regular filenames, or symlink targets, -respectively. -Optional trailing h, r, or s characters enable substitutions -for hardlink targets, regular filenames, or symlink targets, -respectively. -The default is -\fIhrs\fP -which applies substitutions to all names. -In particular, it is never necessary to specify h, r, or s. -.TP -\fB\-Fl\fP safe-writes -(x mode only) -Extract files atomically. -By default -\fB\%tar\fP -unlinks the original file with the same name as the extracted file (if it -exists), and then creates it immediately under the same name and writes to -it. -For a short period of time, applications trying to access the file might -not find it, or see incomplete results. -If -\fB\-Fl\fP safe-writes -is enabled, -\fB\%tar\fP -first creates a unique temporary file, then writes the new contents to -the temporary file, and finally renames the temporary file to its final -name atomically using -\fBrename\fP(2). -This guarantees that an application accessing the file, will either see -the old contents or the new contents at all times. -.TP -\fB\-Fl\fP same-owner -(x mode only) -Extract owner and group IDs. -This is the reverse of -\fB\-Fl\fP no-same-owner -and the default behavior if -\fB\%tar\fP -is run as root. -.TP -\fB\-Fl\fP strip-components \fIcount\fP -Remove the specified number of leading path elements. -Pathnames with fewer elements will be silently skipped. -Note that the pathname is edited after checking inclusion/exclusion patterns -but before security checks. -.TP -\fB\-T\fP \fIfilename\fP, \fB\-Fl\fP files-from \fIfilename\fP -In x or t mode, -\fB\%tar\fP -will read the list of names to be extracted from -\fIfilename\fP. -In c mode, -\fB\%tar\fP -will read names to be archived from -\fIfilename\fP. -The special name -``-C'' -on a line by itself will cause the current directory to be changed to -the directory specified on the following line. -Names are terminated by newlines unless -\fB\-Fl\fP null -is specified. -Note that -\fB\-Fl\fP null -also disables the special handling of lines containing -``-C''. -Note: If you are generating lists of files using -\fBfind\fP(1), -you probably want to use -\fB\-n\fP -as well. -.TP -\fB\-Fl\fP totals -(c, r, u modes only) -After archiving all files, print a summary to stderr. -.TP -\fB\-U\fP, \fB\-Fl\fP unlink, \fB\-Fl\fP unlink-first -(x mode only) -Unlink files before creating them. -This can be a minor performance optimization if most files -already exist, but can make things slower if most files -do not already exist. -This flag also causes -\fB\%tar\fP -to remove intervening directory symlinks instead of -reporting an error. -See the SECURITY section below for more details. -.TP -\fB\-Fl\fP uid \fIid\fP -Use the provided user id number and ignore the user -name from the archive. -On create, if -\fB\-Fl\fP uname -is not also specified, the user name will be set to -match the user id. -.TP -\fB\-Fl\fP uname \fIname\fP -Use the provided user name. -On extract, this overrides the user name in the archive; -if the provided user name does not exist on the system, -it will be ignored and the user id -(from the archive or from the -\fB\-Fl\fP uid -option) -will be used instead. -On create, this sets the user name that will be stored -in the archive; -the name is not verified against the system user database. -.TP -\fB\-Fl\fP use-compress-program \fIprogram\fP -Pipe the input (in x or t mode) or the output (in c mode) through -\fIprogram\fP -instead of using the builtin compression support. -.TP -\fB\-v\fP, \fB\-Fl\fP verbose -Produce verbose output. -In create and extract modes, -\fB\%tar\fP -will list each file name as it is read from or written to -the archive. -In list mode, -\fB\%tar\fP -will produce output similar to that of -\fBls\fP(1). -An additional -\fB\-v\fP -option will also provide ls-like details in create and extract mode. -.TP -\fB\-Fl\fP version -Print version of -\fB\%tar\fP -and -\fB\%libarchive\fP, -and exit. -.TP -\fB\-w\fP, \fB\-Fl\fP confirmation, \fB\-Fl\fP interactive -Ask for confirmation for every action. -.TP -\fB\-X\fP \fIfilename\fP, \fB\-Fl\fP exclude-from \fIfilename\fP -Read a list of exclusion patterns from the specified file. -See -\fB\-Fl\fP exclude -for more information about the handling of exclusions. -.TP -\fB\-Fl\fP xattrs -(c, r, u, x modes only) -Archive or extract extended file attributes. -This is the reverse of -\fB\-Fl\fP no-xattrs -and the default behavior in c, r, and u modes or if -\fB\%tar\fP -is run in x mode as root. -.TP -\fB\-y\fP -(c mode only) -Compress the resulting archive with -\fBbzip2\fP(1). -In extract or list modes, this option is ignored. -Note that this -\fB\%tar\fP -implementation recognizes bzip2 compression automatically when reading -archives. -.TP -\fB\-Z\fP, \fB\-Fl\fP compress, \fB\-Fl\fP uncompress -(c mode only) -Compress the resulting archive with -\fBcompress\fP(1). -In extract or list modes, this option is ignored. -Note that this -\fB\%tar\fP -implementation recognizes compress compression automatically when reading -archives. -.TP -\fB\-z\fP, \fB\-Fl\fP gunzip, \fB\-Fl\fP gzip -(c mode only) -Compress the resulting archive with -\fBgzip\fP(1). -In extract or list modes, this option is ignored. -Note that this -\fB\%tar\fP -implementation recognizes gzip compression automatically when reading -archives. -.RE -.SH ENVIRONMENT -.ad l -The following environment variables affect the execution of -\fB\%tar\fP: -.RS 5 -.TP -.B TAR_READER_OPTIONS -The default options for format readers and compression readers. -The -\fB\-Fl\fP options -option overrides this. -.TP -.B TAR_WRITER_OPTIONS -The default options for format writers and compression writers. -The -\fB\-Fl\fP options -option overrides this. -.TP -.B LANG -The locale to use. -See -\fBenviron\fP(7) -for more information. -.TP -.B TAPE -The default device. -The -\fB\-f\fP -option overrides this. -Please see the description of the -\fB\-f\fP -option above for more details. -.TP -.B TZ -The timezone to use when displaying dates. -See -\fBenviron\fP(7) -for more information. -.RE -.SH EXIT STATUS -.ad l -The \fBtar\fP utility exits 0 on success, and >0 if an error occurs. -.SH EXAMPLES -.ad l -The following creates a new archive -called -\fIfile.tar.gz\fP -that contains two files -\fIsource.c\fP -and -\fIsource.h\fP: -.RS 4 -\fB\%tar\fP \fB\-czf\fP \fIfile.tar.gz\fP \fIsource.c\fP \fIsource.h\fP -.RE -.PP -To view a detailed table of contents for this -archive: -.RS 4 -\fB\%tar\fP \fB\-tvf\fP \fIfile.tar.gz\fP -.RE -.PP -To extract all entries from the archive on -the default tape drive: -.RS 4 -\fB\%tar\fP \fB\-x\fP -.RE -.PP -To examine the contents of an ISO 9660 cdrom image: -.RS 4 -\fB\%tar\fP \fB\-tf\fP \fIimage.iso\fP -.RE -.PP -To move file hierarchies, invoke -\fB\%tar\fP -as -.RS 4 -\fB\%tar\fP \fB\-cf\fP \fI-\fP \fB\-C\fP \fIsrcdir\fP \&. | \fB\%tar\fP \fB\-xpf\fP \fI-\fP \fB\-C\fP \fIdestdir\fP -.RE -or more traditionally -.RS 4 -cd srcdir \&; \fB\%tar\fP \fB\-cf\fP \fI-\fP \&. | (cd destdir \&; \fB\%tar\fP \fB\-xpf\fP \fI-\fP) -.RE -.PP -In create mode, the list of files and directories to be archived -can also include directory change instructions of the form -\fB-C\fP \fIfoo/baz\fP -and archive inclusions of the form -\fB@\fP \fIarchive-file\fP. -For example, the command line -.RS 4 -\fB\%tar\fP \fB\-c\fP \fB\-f\fP \fInew.tar\fP \fIfoo1\fP \fB@\fP \fIold.tgz\fP \fB-C\fP \fI/tmp\fP \fIfoo2\fP -.RE -will create a new archive -\fInew.tar\fP. -\fB\%tar\fP -will read the file -\fIfoo1\fP -from the current directory and add it to the output archive. -It will then read each entry from -\fIold.tgz\fP -and add those entries to the output archive. -Finally, it will switch to the -\fI/tmp\fP -directory and add -\fIfoo2\fP -to the output archive. -.PP -An input file in -\fBmtree\fP(5) -format can be used to create an output archive with arbitrary ownership, -permissions, or names that differ from existing data on disk: -.RS 4 -.nf -$ cat input.mtree -#mtree -usr/bin uid=0 gid=0 mode=0755 type=dir -usr/bin/ls uid=0 gid=0 mode=0755 type=file content=myls -$ tar -cvf output.tar @input.mtree -.RE -.PP -The -\fB\-Fl\fP newer -and -\fB\-Fl\fP newer-mtime -switches accept a variety of common date and time specifications, including -``12 Mar 2005 7:14:29pm'', -``2005-03-12 19:14'', -``5 minutes ago'', -and -``19:14 PST May 1''. -.PP -The -\fB\-Fl\fP options -argument can be used to control various details of archive generation -or reading. -For example, you can generate mtree output which only contains -\fBtype\fP, \fBtime\fP, -and -\fBuid\fP -keywords: -.RS 4 -\fB\%tar\fP \fB\-cf\fP \fIfile.tar\fP \fB\-Fl\fP format=mtree \fB\-Fl\fP options='!all,type,time,uid' \fIdir\fP -.RE -or you can set the compression level used by gzip or xz compression: -.RS 4 -\fB\%tar\fP \fB\-czf\fP \fIfile.tar\fP \fB\-Fl\fP options='compression-level=9'. -.RE -For more details, see the explanation of the -\fB\%archive_read_set_options\fP() -and -\fB\%archive_write_set_options\fP() -API calls that are described in -\fBarchive_read\fP(3) -and -\fBarchive_write\fP(3). -.SH COMPATIBILITY -.ad l -The bundled-arguments format is supported for compatibility -with historic implementations. -It consists of an initial word (with no leading - character) in which -each character indicates an option. -Arguments follow as separate words. -The order of the arguments must match the order -of the corresponding characters in the bundled command word. -For example, -.RS 4 -\fB\%tar\fP \fBtbf\fP 32 \fIfile.tar\fP -.RE -specifies three flags -\fBt\fP, -\fBb\fP, -and -\fBf\fP. -The -\fBb\fP -and -\fBf\fP -flags both require arguments, -so there must be two additional items -on the command line. -The -\fI32\fP -is the argument to the -\fBb\fP -flag, and -\fIfile.tar\fP -is the argument to the -\fBf\fP -flag. -.PP -The mode options c, r, t, u, and x and the options -b, f, l, m, o, v, and w comply with SUSv2. -.PP -For maximum portability, scripts that invoke -\fB\%tar\fP -should use the bundled-argument format above, should limit -themselves to the -\fBc\fP, -\fBt\fP, -and -\fBx\fP -modes, and the -\fBb\fP, -\fBf\fP, -\fBm\fP, -\fBv\fP, -and -\fBw\fP -options. -.PP -Additional long options are provided to improve compatibility with other -tar implementations. -.SH SECURITY -.ad l -Certain security issues are common to many archiving programs, including -\fB\%tar\fP. -In particular, carefully-crafted archives can request that -\fB\%tar\fP -extract files to locations outside of the target directory. -This can potentially be used to cause unwitting users to overwrite -files they did not intend to overwrite. -If the archive is being extracted by the superuser, any file -on the system can potentially be overwritten. -There are three ways this can happen. -Although -\fB\%tar\fP -has mechanisms to protect against each one, -savvy users should be aware of the implications: -.RS 5 -.IP \(bu -Archive entries can have absolute pathnames. -By default, -\fB\%tar\fP -removes the leading -\fI/\fP -character from filenames before restoring them to guard against this problem. -.IP \(bu -Archive entries can have pathnames that include -\fI\& ..\fP -components. -By default, -\fB\%tar\fP -will not extract files containing -\fI\& ..\fP -components in their pathname. -.IP \(bu -Archive entries can exploit symbolic links to restore -files to other directories. -An archive can restore a symbolic link to another directory, -then use that link to restore a file into that directory. -To guard against this, -\fB\%tar\fP -checks each extracted path for symlinks. -If the final path element is a symlink, it will be removed -and replaced with the archive entry. -If -\fB\-U\fP -is specified, any intermediate symlink will also be unconditionally removed. -If neither -\fB\-U\fP -nor -\fB\-P\fP -is specified, -\fB\%tar\fP -will refuse to extract the entry. -.RE -To protect yourself, you should be wary of any archives that -come from untrusted sources. -You should examine the contents of an archive with -.RS 4 -\fB\%tar\fP \fB\-tf\fP \fIfilename\fP -.RE -before extraction. -You should use the -\fB\-k\fP -option to ensure that -\fB\%tar\fP -will not overwrite any existing files or the -\fB\-U\fP -option to remove any pre-existing files. -You should generally not extract archives while running with super-user -privileges. -Note that the -\fB\-P\fP -option to -\fB\%tar\fP -disables the security checks above and allows you to extract -an archive while preserving any absolute pathnames, -\fI\& ..\fP -components, or symlinks to other directories. -.SH SEE ALSO -.ad l -\fBbzip2\fP(1), -\fBcompress\fP(1), -\fBcpio\fP(1), -\fBgzip\fP(1), -\fBmt\fP(1), -\fBpax\fP(1), -\fBshar\fP(1), -\fBxz\fP(1), -\fBlibarchive\fP(3), -\fBlibarchive-formats\fP(5), -\fBtar\fP(5) -.SH STANDARDS -.ad l -There is no current POSIX standard for the tar command; it appeared -in -ISO/IEC 9945-1:1996 (``POSIX.1'') -but was dropped from -IEEE Std 1003.1-2001 (``POSIX.1''). -The options supported by this implementation were developed by surveying a -number of existing tar implementations as well as the old POSIX specification -for tar and the current POSIX specification for pax. -.PP -The ustar and pax interchange file formats are defined by -IEEE Std 1003.1-2001 (``POSIX.1'') -for the pax command. -.SH HISTORY -.ad l -A -\fB\%tar\fP -command appeared in Seventh Edition Unix, which was released in January, 1979. -There have been numerous other implementations, -many of which extended the file format. -John Gilmore's -\fB\%pdtar\fP -public-domain implementation (circa November, 1987) -was quite influential, and formed the basis of GNU tar. -GNU tar was included as the standard system tar -in -FreeBSD -beginning with -FreeBSD 1.0. -.PP -This is a complete re-implementation based on the -\fBlibarchive\fP(3) -library. -It was first released with -FreeBSD 5.4 -in May, 2005. -.SH BUGS -.ad l -This program follows -ISO/IEC 9945-1:1996 (``POSIX.1'') -for the definition of the -\fB\-l\fP -option. -Note that GNU tar prior to version 1.15 treated -\fB\-l\fP -as a synonym for the -\fB\-Fl\fP one-file-system -option. -.PP -The -\fB\-C\fP \fIdir\fP -option may differ from historic implementations. -.PP -All archive output is written in correctly-sized blocks, even -if the output is being compressed. -Whether or not the last output block is padded to a full -block size varies depending on the format and the -output device. -For tar and cpio formats, the last block of output is padded -to a full block size if the output is being -written to standard output or to a character or block device such as -a tape drive. -If the output is being written to a regular file, the last block -will not be padded. -Many compressors, including -\fBgzip\fP(1) -and -\fBbzip2\fP(1), -complain about the null padding when decompressing an archive created by -\fB\%tar\fP, -although they still extract it correctly. -.PP -The compression and decompression is implemented internally, so -there may be insignificant differences between the compressed output -generated by -.RS 4 -\fB\%tar\fP \fB\-czf\fP \fI-\fP file -.RE -and that generated by -.RS 4 -\fB\%tar\fP \fB\-cf\fP \fI-\fP file | \fB\%gzip\fP -.RE -.PP -The default should be to read and write archives to the standard I/O paths, -but tradition (and POSIX) dictates otherwise. -.PP -The -\fBr\fP -and -\fBu\fP -modes require that the archive be uncompressed -and located in a regular file on disk. -Other archives can be modified using -\fBc\fP -mode with the -\fI@archive-file\fP -extension. -.PP -To archive a file called -\fI@foo\fP -or -\fI-foo\fP -you must specify it as -\fI\& ./@foo\fP -or -\fI\& ./-foo\fP, -respectively. -.PP -In create mode, a leading -\fI\& ./\fP -is always removed. -A leading -\fI/\fP -is stripped unless the -\fB\-P\fP -option is specified. -.PP -There needs to be better support for file selection on both create -and extract. -.PP -There is not yet any support for multi-volume archives. -.PP -Converting between dissimilar archive formats (such as tar and cpio) using the -\fB@\fP \fI-\fP -convention can cause hard link information to be lost. -(This is a consequence of the incompatible ways that different archive -formats store hardlink information.) diff --git a/thirdparty/libarchive/doc/man/cpio.5 b/thirdparty/libarchive/doc/man/cpio.5 deleted file mode 100644 index f049dadb0..000000000 --- a/thirdparty/libarchive/doc/man/cpio.5 +++ /dev/null @@ -1,405 +0,0 @@ -.TH CPIO 5 "December 23, 2011" "" -.SH NAME -.ad l -\fB\%cpio\fP -\- format of cpio archive files -.SH DESCRIPTION -.ad l -The -\fB\%cpio\fP -archive format collects any number of files, directories, and other -file system objects (symbolic links, device nodes, etc.) into a single -stream of bytes. -.SS General Format -Each file system object in a -\fB\%cpio\fP -archive comprises a header record with basic numeric metadata -followed by the full pathname of the entry and the file data. -The header record stores a series of integer values that generally -follow the fields in -\fIstruct\fP stat. -(See -\fBstat\fP(2) -for details.) -The variants differ primarily in how they store those integers -(binary, octal, or hexadecimal). -The header is followed by the pathname of the -entry (the length of the pathname is stored in the header) -and any file data. -The end of the archive is indicated by a special record with -the pathname -``TRAILER!!!''. -.SS PWB format -The PWB binary -\fB\%cpio\fP -format is the original format, when cpio was introduced as part of the -Programmer's Work Bench system, a variant of 6th Edition UNIX. It -stores numbers as 2-byte and 4-byte binary values. -Each entry begins with a header in the following format: -.PP -.RS 4 -.nf -struct header_pwb_cpio { - short h_magic; - short h_dev; - short h_ino; - short h_mode; - short h_uid; - short h_gid; - short h_nlink; - short h_majmin; - long h_mtime; - short h_namesize; - long h_filesize; -}; -.RE -.PP -The -\fIshort\fP -fields here are 16-bit integer values, while the -\fIlong\fP -fields are 32 bit integers. Since PWB UNIX, like the 6th Edition UNIX -it was based on, only ran on PDP-11 computers, they -are in PDP-endian format, which has little-endian shorts, and -big-endian longs. That is, the long integer whose hexadecimal -representation is 0x12345678 would be stored in four successive bytes -as 0x34, 0x12, 0x78, 0x56. -The fields are as follows: -.RS 5 -.TP -\fIh_magic\fP -The integer value octal 070707. -.TP -\fIh_dev\fP, \fIh_ino\fP -The device and inode numbers from the disk. -These are used by programs that read -\fB\%cpio\fP -archives to determine when two entries refer to the same file. -Programs that synthesize -\fB\%cpio\fP -archives should be careful to set these to distinct values for each entry. -.TP -\fIh_mode\fP -The mode specifies both the regular permissions and the file type, and -it also holds a couple of bits that are irrelevant to the cpio format, -because the field is actually a raw copy of the mode field in the inode -representing the file. These are the IALLOC flag, which shows that -the inode entry is in use, and the ILARG flag, which shows that the -file it represents is large enough to have indirect blocks pointers in -the inode. -The mode is decoded as follows: -.PP -.RS 5 -.TP -0100000 -IALLOC flag - irrelevant to cpio. -.TP -0060000 -This masks the file type bits. -.TP -0040000 -File type value for directories. -.TP -0020000 -File type value for character special devices. -.TP -0060000 -File type value for block special devices. -.TP -0010000 -ILARG flag - irrelevant to cpio. -.TP -0004000 -SUID bit. -.TP -0002000 -SGID bit. -.TP -0001000 -Sticky bit. -.TP -0000777 -The lower 9 bits specify read/write/execute permissions -for world, group, and user following standard POSIX conventions. -.RE -.TP -\fIh_uid\fP, \fIh_gid\fP -The numeric user id and group id of the owner. -.TP -\fIh_nlink\fP -The number of links to this file. -Directories always have a value of at least two here. -Note that hardlinked files include file data with every copy in the archive. -.TP -\fIh_majmin\fP -For block special and character special entries, -this field contains the associated device number, with the major -number in the high byte, and the minor number in the low byte. -For all other entry types, it should be set to zero by writers -and ignored by readers. -.TP -\fIh_mtime\fP -Modification time of the file, indicated as the number -of seconds since the start of the epoch, -00:00:00 UTC January 1, 1970. -.TP -\fIh_namesize\fP -The number of bytes in the pathname that follows the header. -This count includes the trailing NUL byte. -.TP -\fIh_filesize\fP -The size of the file. Note that this archive format is limited to 16 -megabyte file sizes, because PWB UNIX, like 6th Edition, only used -an unsigned 24 bit integer for the file size internally. -.RE -.PP -The pathname immediately follows the fixed header. -If -\fBh_namesize\fP -is odd, an additional NUL byte is added after the pathname. -The file data is then appended, again with an additional NUL -appended if needed to get the next header at an even offset. -.PP -Hardlinked files are not given special treatment; -the full file contents are included with each copy of the -file. -.SS New Binary Format -The new binary -\fB\%cpio\fP -format showed up when cpio was adopted into late 7th Edition UNIX. -It is exactly like the PWB binary format, described above, except for -three changes: -.PP -First, UNIX now ran on more than one hardware type, so the endianness -of 16 bit integers must be determined by observing the magic number at -the start of the header. The 32 bit integers are still always stored -with the most significant word first, though, so each of those two, in -the struct shown above, was stored as an array of two 16 bit integers, -in the traditional order. Those 16 bit integers, like all the others -in the struct, were accessed using a macro that byte swapped them if -necessary. -.PP -Next, 7th Edition had more file types to store, and the IALLOC and ILARG -flag bits were re-purposed to accommodate these. The revised use of the -various bits is as follows: -.PP -.RS 5 -.TP -0170000 -This masks the file type bits. -.TP -0140000 -File type value for sockets. -.TP -0120000 -File type value for symbolic links. -For symbolic links, the link body is stored as file data. -.TP -0100000 -File type value for regular files. -.TP -0060000 -File type value for block special devices. -.TP -0040000 -File type value for directories. -.TP -0020000 -File type value for character special devices. -.TP -0010000 -File type value for named pipes or FIFOs. -.TP -0004000 -SUID bit. -.TP -0002000 -SGID bit. -.TP -0001000 -Sticky bit. -.TP -0000777 -The lower 9 bits specify read/write/execute permissions -for world, group, and user following standard POSIX conventions. -.RE -.PP -Finally, the file size field now represents a signed 32 bit integer in -the underlying file system, so the maximum file size has increased to -2 gigabytes. -.PP -Note that there is no obvious way to tell which of the two binary -formats an archive uses, other than to see which one makes more -sense. The typical error scenario is that a PWB format archive -unpacked as if it were in the new format will create named sockets -instead of directories, and then fail to unpack files that should -go in those directories. Running -\fIbsdcpio\fP -itv -on an unknown archive will make it obvious which it is: if it's -PWB format, directories will be listed with an 's' instead of -a 'd' as the first character of the mode string, and the larger -files will have a '?' in that position. -.SS Portable ASCII Format -Version 2 of the Single UNIX Specification (``SUSv2'') -standardized an ASCII variant that is portable across all -platforms. -It is commonly known as the -``old character'' -format or as the -``odc'' -format. -It stores the same numeric fields as the old binary format, but -represents them as 6-character or 11-character octal values. -.PP -.RS 4 -.nf -struct cpio_odc_header { - char c_magic[6]; - char c_dev[6]; - char c_ino[6]; - char c_mode[6]; - char c_uid[6]; - char c_gid[6]; - char c_nlink[6]; - char c_rdev[6]; - char c_mtime[11]; - char c_namesize[6]; - char c_filesize[11]; -}; -.RE -.PP -The fields are identical to those in the new binary format. -The name and file body follow the fixed header. -Unlike the binary formats, there is no additional padding -after the pathname or file contents. -If the files being archived are themselves entirely ASCII, then -the resulting archive will be entirely ASCII, except for the -NUL byte that terminates the name field. -.SS New ASCII Format -The "new" ASCII format uses 8-byte hexadecimal fields for -all numbers and separates device numbers into separate fields -for major and minor numbers. -.PP -.RS 4 -.nf -struct cpio_newc_header { - char c_magic[6]; - char c_ino[8]; - char c_mode[8]; - char c_uid[8]; - char c_gid[8]; - char c_nlink[8]; - char c_mtime[8]; - char c_filesize[8]; - char c_devmajor[8]; - char c_devminor[8]; - char c_rdevmajor[8]; - char c_rdevminor[8]; - char c_namesize[8]; - char c_check[8]; -}; -.RE -.PP -Except as specified below, the fields here match those specified -for the new binary format above. -.RS 5 -.TP -\fImagic\fP -The string -``070701''. -.TP -\fIcheck\fP -This field is always set to zero by writers and ignored by readers. -See the next section for more details. -.RE -.PP -The pathname is followed by NUL bytes so that the total size -of the fixed header plus pathname is a multiple of four. -Likewise, the file data is padded to a multiple of four bytes. -Note that this format supports only 4 gigabyte files (unlike the -older ASCII format, which supports 8 gigabyte files). -.PP -In this format, hardlinked files are handled by setting the -filesize to zero for each entry except the first one that -appears in the archive. -.SS New CRC Format -The CRC format is identical to the new ASCII format described -in the previous section except that the magic field is set -to -``070702'' -and the -\fIcheck\fP -field is set to the sum of all bytes in the file data. -This sum is computed treating all bytes as unsigned values -and using unsigned arithmetic. -Only the least-significant 32 bits of the sum are stored. -.SS HP variants -The -\fB\%cpio\fP -implementation distributed with HPUX used XXXX but stored -device numbers differently XXX. -.SS Other Extensions and Variants -Sun Solaris uses additional file types to store extended file -data, including ACLs and extended attributes, as special -entries in cpio archives. -.PP -XXX Others? XXX -.SH SEE ALSO -.ad l -\fBcpio\fP(1), -\fBtar\fP(5) -.SH STANDARDS -.ad l -The -\fB\%cpio\fP -utility is no longer a part of POSIX or the Single Unix Standard. -It last appeared in -Version 2 of the Single UNIX Specification (``SUSv2''). -It has been supplanted in subsequent standards by -\fBpax\fP(1). -The portable ASCII format is currently part of the specification for the -\fBpax\fP(1) -utility. -.SH HISTORY -.ad l -The original cpio utility was written by Dick Haight -while working in AT&T's Unix Support Group. -It appeared in 1977 as part of PWB/UNIX 1.0, the -``Programmer's Work Bench'' -derived from -At v6 -that was used internally at AT&T. -Both the new binary and old character formats were in use -by 1980, according to the System III source released -by SCO under their -``Ancient Unix'' -license. -The character format was adopted as part of -IEEE Std 1003.1-1988 (``POSIX.1''). -XXX when did "newc" appear? Who invented it? When did HP come out with their variant? When did Sun introduce ACLs and extended attributes? XXX -.SH BUGS -.ad l -The -``CRC'' -format is mis-named, as it uses a simple checksum and -not a cyclic redundancy check. -.PP -The binary formats are limited to 16 bits for user id, group id, -device, and inode numbers. They are limited to 16 megabyte and 2 -gigabyte file sizes for the older and newer variants, respectively. -.PP -The old ASCII format is limited to 18 bits for -the user id, group id, device, and inode numbers. -It is limited to 8 gigabyte file sizes. -.PP -The new ASCII format is limited to 4 gigabyte file sizes. -.PP -None of the cpio formats store user or group names, -which are essential when moving files between systems with -dissimilar user or group numbering. -.PP -Especially when writing older cpio variants, it may be necessary -to map actual device/inode values to synthesized values that -fit the available fields. -With very large filesystems, this may be necessary even for -the newer formats. diff --git a/thirdparty/libarchive/doc/man/libarchive-formats.5 b/thirdparty/libarchive/doc/man/libarchive-formats.5 deleted file mode 100644 index 2d5d1913a..000000000 --- a/thirdparty/libarchive/doc/man/libarchive-formats.5 +++ /dev/null @@ -1,451 +0,0 @@ -.TH LIBARCHIVE-FORMATS 5 "December 27, 2016" "" -.SH NAME -.ad l -\fB\%libarchive-formats\fP -\- archive formats supported by the libarchive library -.SH DESCRIPTION -.ad l -The -\fBlibarchive\fP(3) -library reads and writes a variety of streaming archive formats. -Generally speaking, all of these archive formats consist of a series of -``entries''. -Each entry stores a single file system object, such as a file, directory, -or symbolic link. -.PP -The following provides a brief description of each format supported -by libarchive, with some information about recognized extensions or -limitations of the current library support. -Note that just because a format is supported by libarchive does not -imply that a program that uses libarchive will support that format. -Applications that use libarchive specify which formats they wish -to support, though many programs do use libarchive convenience -functions to enable all supported formats. -.SS Tar Formats -The -\fBlibarchive\fP(3) -library can read most tar archives. -It can write POSIX-standard -``ustar'' -and -``pax interchange'' -formats as well as v7 tar format and a subset of the legacy GNU tar format. -.PP -All tar formats store each entry in one or more 512-byte records. -The first record is used for file metadata, including filename, -timestamp, and mode information, and the file data is stored in -subsequent records. -Later variants have extended this by either appropriating undefined -areas of the header record, extending the header to multiple records, -or by storing special entries that modify the interpretation of -subsequent entries. -.RS 5 -.TP -\fBgnutar\fP -The -\fBlibarchive\fP(3) -library can read most GNU-format tar archives. -It currently supports the most popular GNU extensions, including -modern long filename and linkname support, as well as atime and ctime data. -The libarchive library does not support multi-volume -archives, nor the old GNU long filename format. -It can read GNU sparse file entries, including the new POSIX-based -formats. -.PP -The -\fBlibarchive\fP(3) -library can write GNU tar format, including long filename -and linkname support, as well as atime and ctime data. -.TP -\fBpax\fP -The -\fBlibarchive\fP(3) -library can read and write POSIX-compliant pax interchange format -archives. -Pax interchange format archives are an extension of the older ustar -format that adds a separate entry with additional attributes stored -as key/value pairs immediately before each regular entry. -The presence of these additional entries is the only difference between -pax interchange format and the older ustar format. -The extended attributes are of unlimited length and are stored -as UTF-8 Unicode strings. -Keywords defined in the standard are in all lowercase; vendors are allowed -to define custom keys by preceding them with the vendor name in all uppercase. -When writing pax archives, libarchive uses many of the SCHILY keys -defined by Joerg Schilling's -``star'' -archiver and a few LIBARCHIVE keys. -The libarchive library can read most of the SCHILY keys -and most of the GNU keys introduced by GNU tar. -It silently ignores any keywords that it does not understand. -.PP -The pax interchange format converts filenames to Unicode -and stores them using the UTF-8 encoding. -Prior to libarchive 3.0, libarchive erroneously assumed -that the system wide-character routines natively supported -Unicode. -This caused it to mis-handle non-ASCII filenames on systems -that did not satisfy this assumption. -.TP -\fBrestricted\fP pax -The libarchive library can also write pax archives in which it -attempts to suppress the extended attributes entry whenever -possible. -The result will be identical to a ustar archive unless the -extended attributes entry is required to store a long file -name, long linkname, extended ACL, file flags, or if any of the standard -ustar data (user name, group name, UID, GID, etc) cannot be fully -represented in the ustar header. -In all cases, the result can be dearchived by any program that -can read POSIX-compliant pax interchange format archives. -Programs that correctly read ustar format (see below) will also be -able to read this format; any extended attributes will be extracted as -separate files stored in -\fIPaxHeader\fP -directories. -.TP -\fBustar\fP -The libarchive library can both read and write this format. -This format has the following limitations: -.RS 5 -.IP \(bu -Device major and minor numbers are limited to 21 bits. -Nodes with larger numbers will not be added to the archive. -.IP \(bu -Path names in the archive are limited to 255 bytes. -(Shorter if there is no / character in exactly the right place.) -.IP \(bu -Symbolic links and hard links are stored in the archive with -the name of the referenced file. -This name is limited to 100 bytes. -.IP \(bu -Extended attributes, file flags, and other extended -security information cannot be stored. -.IP \(bu -Archive entries are limited to 8 gigabytes in size. -.RE -Note that the pax interchange format has none of these restrictions. -The ustar format is old and widely supported. -It is recommended when compatibility is the primary concern. -.TP -\fBv7\fP -The libarchive library can read and write the legacy v7 tar format. -This format has the following limitations: -.RS 5 -.IP \(bu -Only regular files, directories, and symbolic links can be archived. -Block and character device nodes, FIFOs, and sockets cannot be archived. -.IP \(bu -Path names in the archive are limited to 100 bytes. -.IP \(bu -Symbolic links and hard links are stored in the archive with -the name of the referenced file. -This name is limited to 100 bytes. -.IP \(bu -User and group information are stored as numeric IDs; there -is no provision for storing user or group names. -.IP \(bu -Extended attributes, file flags, and other extended -security information cannot be stored. -.IP \(bu -Archive entries are limited to 8 gigabytes in size. -.RE -Generally, users should prefer the ustar format for portability -as the v7 tar format is both less useful and less portable. -.RE -.PP -The libarchive library also reads a variety of commonly-used extensions to -the basic tar format. -These extensions are recognized automatically whenever they appear. -.RS 5 -.TP -Numeric extensions. -The POSIX standards require fixed-length numeric fields to be written with -some character position reserved for terminators. -Libarchive allows these fields to be written without terminator characters. -This extends the allowable range; in particular, ustar archives with this -extension can support entries up to 64 gigabytes in size. -Libarchive also recognizes base-256 values in most numeric fields. -This essentially removes all limitations on file size, modification time, -and device numbers. -.TP -Solaris extensions -Libarchive recognizes ACL and extended attribute records written -by Solaris tar. -.RE -.PP -The first tar program appeared in Seventh Edition Unix in 1979. -The first official standard for the tar file format was the -``ustar'' -(Unix Standard Tar) format defined by POSIX in 1988. -POSIX.1-2001 extended the ustar format to create the -``pax interchange'' -format. -.SS Cpio Formats -The libarchive library can read and write a number of common cpio -variants. A cpio archive stores each entry as a fixed-size header -followed by a variable-length filename and variable-length data. -Unlike the tar format, the cpio format does only minimal padding of -the header or file data. There are several cpio variants, which -differ primarily in how they store the initial header: some store the -values as octal or hexadecimal numbers in ASCII, others as binary -values of varying byte order and length. -.RS 5 -.TP -\fBbinary\fP -The libarchive library transparently reads both big-endian and -little-endian variants of the the two binary cpio formats; the -original one from PWB/UNIX, and the later, more widely used, variant. -This format used 32-bit binary values for file size and mtime, and -16-bit binary values for the other fields. The formats support only -the file types present in UNIX at the time of their creation. File -sizes are limited to 24 bits in the PWB format, because of the limits -of the file system, and to 31 bits in the newer binary format, where -signed 32 bit longs were used. -.TP -\fBodc\fP -This is the POSIX standardized format, which is officially known as the -``cpio interchange format'' -or the -``octet-oriented cpio archive format'' -and sometimes unofficially referred to as the -``old character format''. -This format stores the header contents as octal values in ASCII. -It is standard, portable, and immune from byte-order confusion. -File sizes and mtime are limited to 33 bits (8GB file size), -other fields are limited to 18 bits. -.TP -\fBSVR4/newc\fP -The libarchive library can read both CRC and non-CRC variants of -this format. -The SVR4 format uses eight-digit hexadecimal values for -all header fields. -This limits file size to 4GB, and also limits the mtime and -other fields to 32 bits. -The SVR4 format can optionally include a CRC of the file -contents, although libarchive does not currently verify this CRC. -.RE -.PP -Cpio first appeared in PWB/UNIX 1.0, which was released within -AT&T in 1977. -PWB/UNIX 1.0 formed the basis of System III Unix, released outside -of AT&T in 1981. -This makes cpio older than tar, although cpio was not included -in Version 7 AT&T Unix. -As a result, the tar command became much better known in universities -and research groups that used Version 7. -The combination of the -\fB\%find\fP -and -\fB\%cpio\fP -utilities provided very precise control over file selection. -Unfortunately, the format has many limitations that make it unsuitable -for widespread use. -Only the POSIX format permits files over 4GB, and its 18-bit -limit for most other fields makes it unsuitable for modern systems. -In addition, cpio formats only store numeric UID/GID values (not -usernames and group names), which can make it very difficult to correctly -transfer archives across systems with dissimilar user numbering. -.SS Shar Formats -A -``shell archive'' -is a shell script that, when executed on a POSIX-compliant -system, will recreate a collection of file system objects. -The libarchive library can write two different kinds of shar archives: -.RS 5 -.TP -\fBshar\fP -The traditional shar format uses a limited set of POSIX -commands, including -\fBecho\fP(1), -\fBmkdir\fP(1), -and -\fBsed\fP(1). -It is suitable for portably archiving small collections of plain text files. -However, it is not generally well-suited for large archives -(many implementations of -\fBsh\fP(1) -have limits on the size of a script) nor should it be used with non-text files. -.TP -\fBshardump\fP -This format is similar to shar but encodes files using -\fBuuencode\fP(1) -so that the result will be a plain text file regardless of the file contents. -It also includes additional shell commands that attempt to reproduce as -many file attributes as possible, including owner, mode, and flags. -The additional commands used to restore file attributes make -shardump archives less portable than plain shar archives. -.RE -.SS ISO9660 format -Libarchive can read and extract from files containing ISO9660-compliant -CDROM images. -In many cases, this can remove the need to burn a physical CDROM -just in order to read the files contained in an ISO9660 image. -It also avoids security and complexity issues that come with -virtual mounts and loopback devices. -Libarchive supports the most common Rockridge extensions and has partial -support for Joliet extensions. -If both extensions are present, the Joliet extensions will be -used and the Rockridge extensions will be ignored. -In particular, this can create problems with hardlinks and symlinks, -which are supported by Rockridge but not by Joliet. -.PP -Libarchive reads ISO9660 images using a streaming strategy. -This allows it to read compressed images directly -(decompressing on the fly) and allows it to read images -directly from network sockets, pipes, and other non-seekable -data sources. -This strategy works well for optimized ISO9660 images created -by many popular programs. -Such programs collect all directory information at the beginning -of the ISO9660 image so it can be read from a physical disk -with a minimum of seeking. -However, not all ISO9660 images can be read in this fashion. -.PP -Libarchive can also write ISO9660 images. -Such images are fully optimized with the directory information -preceding all file data. -This is done by storing all file data to a temporary file -while collecting directory information in memory. -When the image is finished, libarchive writes out the -directory structure followed by the file data. -The location used for the temporary file can be changed -by the usual environment variables. -.SS Zip format -Libarchive can read and write zip format archives that have -uncompressed entries and entries compressed with the -``deflate'' -algorithm. -Other zip compression algorithms are not supported. -It can extract jar archives, archives that use Zip64 extensions and -self-extracting zip archives. -Libarchive can use either of two different strategies for -reading Zip archives: -a streaming strategy which is fast and can handle extremely -large archives, and a seeking strategy which can correctly -process self-extracting Zip archives and archives with -deleted members or other in-place modifications. -.PP -The streaming reader processes Zip archives as they are read. -It can read archives of arbitrary size from tape or -network sockets, and can decode Zip archives that have -been separately compressed or encoded. -However, self-extracting Zip archives and archives with -certain types of modifications cannot be correctly -handled. -Such archives require that the reader first process the -Central Directory, which is ordinarily located -at the end of a Zip archive and is thus inaccessible -to the streaming reader. -If the program using libarchive has enabled seek support, then -libarchive will use this to processes the central directory first. -.PP -In particular, the seeking reader must be used to -correctly handle self-extracting archives. -Such archives consist of a program followed by a regular -Zip archive. -The streaming reader cannot parse the initial program -portion, but the seeking reader starts by reading the -Central Directory from the end of the archive. -Similarly, Zip archives that have been modified in-place -can have deleted entries or other garbage data that -can only be accurately detected by first reading the -Central Directory. -.SS Archive (library) file format -The Unix archive format (commonly created by the -\fBar\fP(1) -archiver) is a general-purpose format which is -used almost exclusively for object files to be -read by the link editor -\fBld\fP(1). -The ar format has never been standardised. -There are two common variants: -the GNU format derived from SVR4, -and the BSD format, which first appeared in 4.4BSD. -The two differ primarily in their handling of filenames -longer than 15 characters: -the GNU/SVR4 variant writes a filename table at the beginning of the archive; -the BSD format stores each long filename in an extension -area adjacent to the entry. -Libarchive can read both extensions, -including archives that may include both types of long filenames. -Programs using libarchive can write GNU/SVR4 format -if they provide an entry called -\fI//\fP -containing a filename table to be written into the archive -before any of the entries. -Any entries whose names are not in the filename table -will be written using BSD-style long filenames. -This can cause problems for programs such as -GNU ld that do not support the BSD-style long filenames. -.SS mtree -Libarchive can read and write files in -\fBmtree\fP(5) -format. -This format is not a true archive format, but rather a textual description -of a file hierarchy in which each line specifies the name of a file and -provides specific metadata about that file. -Libarchive can read all of the keywords supported by both -the NetBSD and FreeBSD versions of -\fBmtree\fP(8), -although many of the keywords cannot currently be stored in an -Tn archive_entry -object. -When writing, libarchive supports use of the -\fBarchive_write_set_options\fP(3) -interface to specify which keywords should be included in the -output. -If libarchive was compiled with access to suitable -cryptographic libraries (such as the OpenSSL libraries), -it can compute hash entries such as -\fBsha512\fP -or -\fBmd5\fP -from file data being written to the mtree writer. -.PP -When reading an mtree file, libarchive will locate the corresponding -files on disk using the -\fBcontents\fP -keyword if present or the regular filename. -If it can locate and open the file on disk, it will use that -to fill in any metadata that is missing from the mtree file -and will read the file contents and return those to the program -using libarchive. -If it cannot locate and open the file on disk, libarchive -will return an error for any attempt to read the entry -body. -.SS 7-Zip -Libarchive can read and write 7-Zip format archives. -TODO: Need more information -.SS CAB -Libarchive can read Microsoft Cabinet ( -``CAB )'' -format archives. -TODO: Need more information. -.SS LHA -TODO: Information about libarchive's LHA support -.SS RAR -Libarchive has limited support for reading RAR format archives. -Currently, libarchive can read RARv3 format archives -which have been either created uncompressed, or compressed using -any of the compression methods supported by the RARv3 format. -Libarchive can also read self-extracting RAR archives. -.SS Warc -Libarchive can read and write -``web archives''. -TODO: Need more information -.SS XAR -Libarchive can read and write the XAR format used by many Apple tools. -TODO: Need more information -.SH SEE ALSO -.ad l -\fBar\fP(1), -\fBcpio\fP(1), -\fBmkisofs\fP(1), -\fBshar\fP(1), -\fBtar\fP(1), -\fBzip\fP(1), -\fBzlib\fP(3), -\fBcpio\fP(5), -\fBmtree\fP(5), -\fBtar\fP(5) diff --git a/thirdparty/libarchive/doc/man/libarchive.3 b/thirdparty/libarchive/doc/man/libarchive.3 deleted file mode 100644 index 5e9fe7944..000000000 --- a/thirdparty/libarchive/doc/man/libarchive.3 +++ /dev/null @@ -1,281 +0,0 @@ -.TH LIBARCHIVE 3 "March 18, 2012" "" -.SH NAME -.ad l -\fB\%libarchive\fP -\- functions for reading and writing streaming archives -.SH OVERVIEW -.ad l -The -\fB\%libarchive\fP -library provides a flexible interface for reading and writing -archives in various formats such as tar and cpio. -\fB\%libarchive\fP -also supports reading and writing archives compressed using -various compression filters such as gzip and bzip2. -The library is inherently stream-oriented; readers serially iterate through -the archive, writers serially add things to the archive. -In particular, note that there is currently no built-in support for -random access nor for in-place modification. -.PP -When reading an archive, the library automatically detects the -format and the compression. -The library currently has read support for: -.RS 5 -.IP \(bu -old-style tar archives, -.IP \(bu -most variants of the POSIX -``ustar'' -format, -.IP \(bu -the POSIX -``pax interchange'' -format, -.IP \(bu -GNU-format tar archives, -.IP \(bu -most common cpio archive formats, -.IP \(bu -7-Zip archives, -.IP \(bu -ar archives (including GNU/SysV and BSD extensions), -.IP \(bu -Microsoft CAB archives, -.IP \(bu -ISO9660 CD images (including RockRidge and Joliet extensions), -.IP \(bu -LHA archives, -.IP \(bu -mtree file tree descriptions, -.IP \(bu -RAR and most RAR5 archives, -.IP \(bu -WARC archives, -.IP \(bu -XAR archives, -.IP \(bu -Zip archives. -.RE -The library automatically detects archives compressed with -\fBcompress\fP(1), -\fBbzip2\fP(1), -\fBgrzip\fP(1), -\fBgzip\fP(1), -\fBlrzip\fP(1), -\fBlz4\fP(1), -\fBlzip\fP(1), -\fBlzop\fP(1), -\fBxz\fP(1), -or -\fBzstd\fP(1) -and decompresses them transparently. Decompression of some formats -requires external decompressor utilities. -It can similarly detect and decode archives processed with -\fBuuencode\fP(1) -or which have an -\fBrpm\fP(1) -header. -.PP -When writing an archive, you can specify the compression -to be used and the format to use. -The library can write -.RS 5 -.IP \(bu -POSIX-standard -``ustar'' -archives, -.IP \(bu -POSIX -``pax interchange format'' -archives, -.IP \(bu -cpio archives, -.IP \(bu -7-Zip archives, -.IP \(bu -ar archives, -.IP \(bu -two different variants of shar archives, -.IP \(bu -ISO9660 CD images, -.IP \(bu -mtree file tree descriptions, -.IP \(bu -XAR archives, -.IP \(bu -Zip archive. -.RE -Pax interchange format is an extension of the tar archive format that -eliminates essentially all of the limitations of historic tar formats -in a standard fashion that is supported -by POSIX-compliant -\fBpax\fP(1) -implementations on many systems as well as several newer implementations of -\fBtar\fP(1). -Note that the default write format will suppress the pax extended -attributes for most entries; explicitly requesting pax format will -enable those attributes for all entries. -.PP -The read and write APIs are accessed through the -\fB\%archive_read_XXX\fP() -functions and the -\fB\%archive_write_XXX\fP() -functions, respectively, and either can be used independently -of the other. -.PP -The rest of this manual page provides an overview of the library -operation. -More detailed information can be found in the individual manual -pages for each API or utility function. -.SH READING AN ARCHIVE -.ad l -See -\fBarchive_read\fP(3). -.SH WRITING AN ARCHIVE -.ad l -See -\fBarchive_write\fP(3). -.SH WRITING ENTRIES TO DISK -.ad l -The -\fBarchive_write_disk\fP(3) -API allows you to write -\fBarchive_entry\fP(3) -objects to disk using the same API used by -\fBarchive_write\fP(3). -The -\fBarchive_write_disk\fP(3) -API is used internally by -\fB\%archive_read_extract\fP(\fI\%;\fP) -using it directly can provide greater control over how entries -get written to disk. -This API also makes it possible to share code between -archive-to-archive copy and archive-to-disk extraction -operations. -.SH READING ENTRIES FROM DISK -.ad l -The -\fBarchive_read_disk\fP(3) -supports for populating -\fBarchive_entry\fP(3) -objects from information in the filesystem. -This includes the information accessible from the -\fBstat\fP(2) -system call as well as ACLs, extended attributes, -and other metadata. -The -\fBarchive_read_disk\fP(3) -API also supports iterating over directory trees, -which allows directories of files to be read using -an API compatible with -the -\fBarchive_read\fP(3) -API. -.SH DESCRIPTION -.ad l -Detailed descriptions of each function are provided by the -corresponding manual pages. -.PP -All of the functions utilize an opaque -Tn struct archive -datatype that provides access to the archive contents. -.PP -The -Tn struct archive_entry -structure contains a complete description of a single archive -entry. -It uses an opaque interface that is fully documented in -\fBarchive_entry\fP(3). -.PP -Users familiar with historic formats should be aware that the newer -variants have eliminated most restrictions on the length of textual fields. -Clients should not assume that filenames, link names, user names, or -group names are limited in length. -In particular, pax interchange format can easily accommodate pathnames -in arbitrary character sets that exceed -\fIPATH_MAX\fP. -.SH RETURN VALUES -.ad l -Most functions return -\fBARCHIVE_OK\fP -(zero) on success, non-zero on error. -The return value indicates the general severity of the error, ranging -from -\fBARCHIVE_WARN\fP, -which indicates a minor problem that should probably be reported -to the user, to -\fBARCHIVE_FATAL\fP, -which indicates a serious problem that will prevent any further -operations on this archive. -On error, the -\fB\%archive_errno\fP() -function can be used to retrieve a numeric error code (see -\fBerrno\fP(2)). -The -\fB\%archive_error_string\fP() -returns a textual error message suitable for display. -.PP -\fB\%archive_read_new\fP() -and -\fB\%archive_write_new\fP() -return pointers to an allocated and initialized -Tn struct archive -object. -.PP -\fB\%archive_read_data\fP() -and -\fB\%archive_write_data\fP() -return a count of the number of bytes actually read or written. -A value of zero indicates the end of the data for this entry. -A negative value indicates an error, in which case the -\fB\%archive_errno\fP() -and -\fB\%archive_error_string\fP() -functions can be used to obtain more information. -.SH ENVIRONMENT -.ad l -There are character set conversions within the -\fBarchive_entry\fP(3) -functions that are impacted by the currently-selected locale. -.SH SEE ALSO -.ad l -\fBtar\fP(1), -\fBarchive_entry\fP(3), -\fBarchive_read\fP(3), -\fBarchive_util\fP(3), -\fBarchive_write\fP(3), -\fBtar\fP(5) -.SH HISTORY -.ad l -The -\fB\%libarchive\fP -library first appeared in -FreeBSD 5.3. -.SH AUTHORS -.ad l --nosplit -The -\fB\%libarchive\fP -library was originally written by -Tim Kientzle \% -.SH BUGS -.ad l -Some archive formats support information that is not supported by -Tn struct archive_entry. -Such information cannot be fully archived or restored using this library. -This includes, for example, comments, character sets, -or the arbitrary key/value pairs that can appear in -pax interchange format archives. -.PP -Conversely, of course, not all of the information that can be -stored in an -Tn struct archive_entry -is supported by all formats. -For example, cpio formats do not support nanosecond timestamps; -old tar formats do not support large device numbers. -.PP -The ISO9660 reader cannot yet read all ISO9660 images; -it should learn how to seek. -.PP -The AR writer requires the client program to use -two passes, unlike all other libarchive writers. diff --git a/thirdparty/libarchive/doc/man/libarchive_changes.3 b/thirdparty/libarchive/doc/man/libarchive_changes.3 deleted file mode 100644 index a1e233071..000000000 --- a/thirdparty/libarchive/doc/man/libarchive_changes.3 +++ /dev/null @@ -1,340 +0,0 @@ -.TH LIBARCHIVE_CHANGES 3 "December 23, 2011" "" -.SH NAME -.ad l -\fB\%libarchive_changes\fP -\- changes in libarchive interface -.SH CHANGES IN LIBARCHIVE 3 -.ad l -This page describes user-visible changes in libarchive3, and lists -public functions and other symbols changed, deprecated or removed -in libarchive3, along with their replacements if any. -.SS Multiple Filters -Libarchive2 permitted a single (input or output) filter active -on an archive. -Libarchive3 extends this into a variable-length stack. -Where -\fB\%archive_write_set_compression_XXX\fP() -would replace any existing filter, -\fB\%archive_write_add_filter_XXX\fP() -extends the write pipeline with another filter. -.SS Character Set Handling -Libarchive2 assumed that the local platform uses -Tn Unicode -as the native -Tn wchar_t -encoding, which is true on -Tn Windows, -modern -Tn Linux, -and a few other systems, but is certainly not universal. -As a result, pax format archives were written incorrectly on some -systems, since pax format requires -Tn UTF-8 -and libarchive 2 incorrectly -assumed that -Tn wchar_t -strings can be easily converted to -Tn UTF-8. -.PP -Libarchive3 uses the standard iconv library to convert between character -sets and is introducing the notion of a -``default character set for the archive''. -To support this, -Tn archive_entry -objects can now be bound to a particular archive when they are created. -The automatic character set conversions performed by -Tn archive_entry -objects when reading and writing filenames, usernames, and other strings -will now use an appropriate default character set: -.PP -If the -Tn archive_entry -object is bound to an archive, it will use the -default character set for that archive. -.PP -The platform default character encoding (as returned by -\fB\%nl_langinfo\fP(\fI\%CHARSET\fP, \fI\%)\fP) -will be used if nothing else is specified. -.PP -Libarchive3 also introduces charset options to many of the archive -readers and writers to control the character set that will be used for -filenames written in those archives. -When possible, this will be set automatically based on information in -the archive itself. -Combining this with the notion of a default character set for the -archive should allow you to configure libarchive to read archives from -other platforms and have the filenames and other information -transparently converted to the character encoding suitable for your -application. -.SS Prototype Changes -These changes break binary compatibility; libarchive3 has a new shared -library version to reflect these changes. -The library now uses portable wide types such as -Tn int64_t -instead of less-portable types such as -Tn off_t, -Tn gid_t, -Tn uid_t, -and -Tn ino_t. -.PP -There are a few cases where these changes will affect your source code: -.RS 5 -.IP \(bu -In some cases, libarchive's wider types will introduce the possibility -of truncation: for example, on a system with a 16-bit -Tn uid_t, you risk having uid -.RS 4 -65536 -.RE -be truncated to uid -.RS 4 -0, -.RE -which can cause serious security problems. -.IP \(bu -Typedef function pointer types will be incompatible. -For example, if you define custom skip callbacks, you may have to use -code similar to the following if you want to support building against -libarchive2 and libarchive3: -.RS 4 -.nf -#if ARCHIVE_VERSION_NUMBER < 3000000 -typedef off_t myoff_t; -#else -typedef int64_t myoff_t; -#endif -myoff_t -my_skip_function(struct archive *a, void *v, myoff_t o) -{ - ... implementation ... -} -.RE -.RE -.PP -Affected functions: -.PP -.RS 5 -.IP \(bu -\fB\%archive_entry_gid\fP(), -\fB\%archive_entry_set_gid\fP() -.IP \(bu -\fB\%archive_entry_uid\fP(), -\fB\%archive_entry_set_uid\fP() -.IP \(bu -\fB\%archive_entry_ino\fP(), -\fB\%archive_entry_set_ino\fP() -.IP \(bu -\fB\%archive_read_data_block\fP(), -\fB\%archive_write_data_block\fP() -.IP \(bu -\fB\%archive_read_disk_gname\fP(), -\fB\%archive_read_disk_uname\fP() -.IP \(bu -\fB\%archive_read_disk_set_gname_lookup\fP(), -\fB\%archive_read_disk_set_group_lookup\fP(), -\fB\%archive_read_disk_set_uname_lookup\fP(), -\fB\%archive_read_disk_set_user_lookup\fP() -.IP \(bu -\fB\%archive_skip_callback\fP() -.IP \(bu -\fB\%archive_read_extract_set_skip_file\fP(), -\fB\%archive_write_disk_set_skip_file\fP(), -\fB\%archive_write_set_skip_file\fP() -.IP \(bu -\fB\%archive_write_disk_set_group_lookup\fP(), -\fB\%archive_write_disk_set_user_lookup\fP() -.RE -.PP -Where these functions or their arguments took or returned -Tn gid_t, -Tn ino_t, -Tn off_t, -or -Tn uid_t -they now take or return -Tn int64_t -or equivalent. -.SS Deprecated Symbols -Symbols deprecated in libarchive3 will be removed in libarchive4. -These symbols, along with their replacements if any, are listed below: -.RS 5 -.TP -\fB\%archive_position_compressed\fP(), \fB\%archive_position_uncompressed\fP() -\fB\%archive_filter_bytes\fP() -.TP -\fB\%archive_compression\fP() -\fB\%archive_filter_code\fP() -.TP -\fB\%archive_compression_name\fP() -\fB\%archive_filter_name\fP() -.TP -\fB\%archive_read_finish\fP(), \fB\%archive_write_finish\fP() -\fB\%archive_read_free\fP(), -\fB\%archive_write_free\fP() -.TP -\fB\%archive_read_open_file\fP(), \fB\%archive_write_open_file\fP() -\fB\%archive_read_open_filename\fP(), -\fB\%archive_write_open_filename\fP() -.TP -\fB\%archive_read_support_compression_all\fP() -\fB\%archive_read_support_filter_all\fP() -.TP -\fB\%archive_read_support_compression_bzip2\fP() -\fB\%archive_read_support_filter_bzip2\fP() -.TP -\fB\%archive_read_support_compression_compress\fP() -\fB\%archive_read_support_filter_compress\fP() -.TP -\fB\%archive_read_support_compression_gzip\fP() -\fB\%archive_read_support_filter_gzip\fP() -.TP -\fB\%archive_read_support_compression_lzip\fP() -\fB\%archive_read_support_filter_lzip\fP() -.TP -\fB\%archive_read_support_compression_lzma\fP() -\fB\%archive_read_support_filter_lzma\fP() -.TP -\fB\%archive_read_support_compression_none\fP() -\fB\%archive_read_support_filter_none\fP() -.TP -\fB\%archive_read_support_compression_program\fP() -\fB\%archive_read_support_filter_program\fP() -.TP -\fB\%archive_read_support_compression_program_signature\fP() -\fB\%archive_read_support_filter_program_signature\fP() -.TP -\fB\%archive_read_support_compression_rpm\fP() -\fB\%archive_read_support_filter_rpm\fP() -.TP -\fB\%archive_read_support_compression_uu\fP() -\fB\%archive_read_support_filter_uu\fP() -.TP -\fB\%archive_read_support_compression_xz\fP() -\fB\%archive_read_support_filter_xz\fP() -.TP -\fB\%archive_write_set_compression_bzip2\fP() -\fB\%archive_write_add_filter_bzip2\fP() -.TP -\fB\%archive_write_set_compression_compress\fP() -\fB\%archive_write_add_filter_compress\fP() -.TP -\fB\%archive_write_set_compression_gzip\fP() -\fB\%archive_write_add_filter_gzip\fP() -.TP -\fB\%archive_write_set_compression_lzip\fP() -\fB\%archive_write_add_filter_lzip\fP() -.TP -\fB\%archive_write_set_compression_lzma\fP() -\fB\%archive_write_add_filter_lzma\fP() -.TP -\fB\%archive_write_set_compression_none\fP() -\fB\%archive_write_add_filter_none\fP() -.TP -\fB\%archive_write_set_compression_program\fP() -\fB\%archive_write_add_filter_program\fP() -.TP -\fB\%archive_write_set_compression_filter\fP() -\fB\%archive_write_add_filter_filter\fP() -.RE -.SS Removed Symbols -These symbols, listed below along with their replacements if any, -were deprecated in libarchive2, and are not part of libarchive3. -.RS 5 -.TP -\fB\%archive_api_feature\fP() -\fB\%archive_version_number\fP() -.TP -\fB\%archive_api_version\fP() -\fB\%archive_version_number\fP() -.TP -\fB\%archive_version\fP() -\fB\%archive_version_string\fP() -.TP -\fB\%archive_version_stamp\fP() -\fB\%archive_version_number\fP() -.TP -\fB\%archive_read_set_filter_options\fP() -\fB\%archive_read_set_options\fP() -or -\fB\%archive_read_set_filter_option\fP() -.TP -\fB\%archive_read_set_format_options\fP() -\fB\%archive_read_set_options\fP() -or -\fB\%archive_read_set_format_option\fP() -.TP -\fB\%archive_write_set_filter_options\fP() -\fB\%archive_write_set_options\fP() -or -\fB\%archive_write_set_filter_option\fP() -.TP -\fB\%archive_write_set_format_options\fP() -\fB\%archive_write_set_options\fP() -or -\fB\%archive_write_set_format_option\fP() -.TP -.BR ARCHIVE_API_FEATURE -.BR ARCHIVE_VERSION_NUMBER -.TP -.BR ARCHIVE_API_VERSION -.BR ARCHIVE_VERSION_NUMBER -.TP -.BR ARCHIVE_VERSION_STAMP -.BR ARCHIVE_VERSION_NUMBER -.TP -.BR ARCHIVE_LIBRARY_VERSION -.BR ARCHIVE_VERSION_STRING -.TP -.BR ARCHIVE_COMPRESSION_NONE -.BR ARCHIVE_FILTER_NONE -.TP -.BR ARCHIVE_COMPRESSION_GZIP -.BR ARCHIVE_FILTER_GZIP -.TP -.BR ARCHIVE_COMPRESSION_BZIP2 -.BR ARCHIVE_FILTER_BZIP2 -.TP -.BR ARCHIVE_COMPRESSION_COMPRESS -.BR ARCHIVE_FILTER_COMPRESS -.TP -.BR ARCHIVE_COMPRESSION_PROGRAM -.BR ARCHIVE_FILTER_PROGRAM -.TP -.BR ARCHIVE_COMPRESSION_LZMA -.BR ARCHIVE_FILTER_LZMA -.TP -.BR ARCHIVE_COMPRESSION_XZ -.BR ARCHIVE_FILTER_XZ -.TP -.BR ARCHIVE_COMPRESSION_UU -.BR ARCHIVE_FILTER_UU -.TP -.BR ARCHIVE_COMPRESSION_RPM -.BR ARCHIVE_FILTER_RPM -.TP -.BR ARCHIVE_COMPRESSION_LZIP -.BR ARCHIVE_FILTER_LZIP -.TP -.BR ARCHIVE_BYTES_PER_RECORD -.RS 4 -512 -.RE -.TP -.BR ARCHIVE_DEFAULT_BYTES_PER_BLOCK -.RS 4 -10240 -.RE -.RE -.SH SEE ALSO -.ad l -\fBarchive_read\fP(3), -\fBarchive_read_filter\fP(3), -\fBarchive_read_format\fP(3), -\fBarchive_read_set_options\fP(3), -\fBarchive_util\fP(3), -\fBarchive_write\fP(3), -\fBarchive_write_filter\fP(3), -\fBarchive_write_format\fP(3), -\fBarchive_write_set_options\fP(3), -\fBlibarchive\fP(3) diff --git a/thirdparty/libarchive/doc/man/libarchive_internals.3 b/thirdparty/libarchive/doc/man/libarchive_internals.3 deleted file mode 100644 index 05337ad92..000000000 --- a/thirdparty/libarchive/doc/man/libarchive_internals.3 +++ /dev/null @@ -1,359 +0,0 @@ -.TH LIBARCHIVE_INTERNALS 3 "January 26, 2011" "" -.SH NAME -.ad l -\fB\%libarchive_internals\fP -\- description of libarchive internal interfaces -.SH OVERVIEW -.ad l -The -\fB\%libarchive\fP -library provides a flexible interface for reading and writing -streaming archive files such as tar and cpio. -Internally, it follows a modular layered design that should -make it easy to add new archive and compression formats. -.SH GENERAL ARCHITECTURE -.ad l -Externally, libarchive exposes most operations through an -opaque, object-style interface. -The -\fBarchive_entry\fP(3) -objects store information about a single filesystem object. -The rest of the library provides facilities to write -\fBarchive_entry\fP(3) -objects to archive files, -read them from archive files, -and write them to disk. -(There are plans to add a facility to read -\fBarchive_entry\fP(3) -objects from disk as well.) -.PP -The read and write APIs each have four layers: a public API -layer, a format layer that understands the archive file format, -a compression layer, and an I/O layer. -The I/O layer is completely exposed to clients who can replace -it entirely with their own functions. -.PP -In order to provide as much consistency as possible for clients, -some public functions are virtualized. -Eventually, it should be possible for clients to open -an archive or disk writer, and then use a single set of -code to select and write entries, regardless of the target. -.SH READ ARCHITECTURE -.ad l -From the outside, clients use the -\fBarchive_read\fP(3) -API to manipulate an -\fB\%archive\fP -object to read entries and bodies from an archive stream. -Internally, the -\fB\%archive\fP -object is cast to an -\fB\%archive_read\fP -object, which holds all read-specific data. -The API has four layers: -The lowest layer is the I/O layer. -This layer can be overridden by clients, but most clients use -the packaged I/O callbacks provided, for example, by -\fBarchive_read_open_memory\fP(3), -and -\fBarchive_read_open_fd\fP(3). -The compression layer calls the I/O layer to -read bytes and decompresses them for the format layer. -The format layer unpacks a stream of uncompressed bytes and -creates -\fB\%archive_entry\fP -objects from the incoming data. -The API layer tracks overall state -(for example, it prevents clients from reading data before reading a header) -and invokes the format and compression layer operations -through registered function pointers. -In particular, the API layer drives the format-detection process: -When opening the archive, it reads an initial block of data -and offers it to each registered compression handler. -The one with the highest bid is initialized with the first block. -Similarly, the format handlers are polled to see which handler -is the best for each archive. -(Prior to 2.4.0, the format bidders were invoked for each -entry, but this design hindered error recovery.) -.SS I/O Layer and Client Callbacks -The read API goes to some lengths to be nice to clients. -As a result, there are few restrictions on the behavior of -the client callbacks. -.PP -The client read callback is expected to provide a block -of data on each call. -A zero-length return does indicate end of file, but otherwise -blocks may be as small as one byte or as large as the entire file. -In particular, blocks may be of different sizes. -.PP -The client skip callback returns the number of bytes actually -skipped, which may be much smaller than the skip requested. -The only requirement is that the skip not be larger. -In particular, clients are allowed to return zero for any -skip that they don't want to handle. -The skip callback must never be invoked with a negative value. -.PP -Keep in mind that not all clients are reading from disk: -clients reading from networks may provide different-sized -blocks on every request and cannot skip at all; -advanced clients may use -\fBmmap\fP(2) -to read the entire file into memory at once and return the -entire file to libarchive as a single block; -other clients may begin asynchronous I/O operations for the -next block on each request. -.SS Decompresssion Layer -The decompression layer not only handles decompression, -it also buffers data so that the format handlers see a -much nicer I/O model. -The decompression API is a two stage peek/consume model. -A read_ahead request specifies a minimum read amount; -the decompression layer must provide a pointer to at least -that much data. -If more data is immediately available, it should return more: -the format layer handles bulk data reads by asking for a minimum -of one byte and then copying as much data as is available. -.PP -A subsequent call to the -\fB\%consume\fP() -function advances the read pointer. -Note that data returned from a -\fB\%read_ahead\fP() -call is guaranteed to remain in place until -the next call to -\fB\%read_ahead\fP(). -Intervening calls to -\fB\%consume\fP() -should not cause the data to move. -.PP -Skip requests must always be handled exactly. -Decompression handlers that cannot seek forward should -not register a skip handler; -the API layer fills in a generic skip handler that reads and discards data. -.PP -A decompression handler has a specific lifecycle: -.RS 5 -.TP -Registration/Configuration -When the client invokes the public support function, -the decompression handler invokes the internal -\fB\%__archive_read_register_compression\fP() -function to provide bid and initialization functions. -This function returns -\fBNULL\fP -on error or else a pointer to a -\fBstruct\fP decompressor_t. -This structure contains a -\fIvoid\fP * config -slot that can be used for storing any customization information. -.TP -Bid -The bid function is invoked with a pointer and size of a block of data. -The decompressor can access its config data -through the -\fIdecompressor\fP -element of the -\fBarchive_read\fP -object. -The bid function is otherwise stateless. -In particular, it must not perform any I/O operations. -.PP -The value returned by the bid function indicates its suitability -for handling this data stream. -A bid of zero will ensure that this decompressor is never invoked. -Return zero if magic number checks fail. -Otherwise, your initial implementation should return the number of bits -actually checked. -For example, if you verify two full bytes and three bits of another -byte, bid 19. -Note that the initial block may be very short; -be careful to only inspect the data you are given. -(The current decompressors require two bytes for correct bidding.) -.TP -Initialize -The winning bidder will have its init function called. -This function should initialize the remaining slots of the -\fIstruct\fP decompressor_t -object pointed to by the -\fIdecompressor\fP -element of the -\fIarchive_read\fP -object. -In particular, it should allocate any working data it needs -in the -\fIdata\fP -slot of that structure. -The init function is called with the block of data that -was used for tasting. -At this point, the decompressor is responsible for all I/O -requests to the client callbacks. -The decompressor is free to read more data as and when -necessary. -.TP -Satisfy I/O requests -The format handler will invoke the -\fIread_ahead\fP, -\fIconsume\fP, -and -\fIskip\fP -functions as needed. -.TP -Finish -The finish method is called only once when the archive is closed. -It should release anything stored in the -\fIdata\fP -and -\fIconfig\fP -slots of the -\fIdecompressor\fP -object. -It should not invoke the client close callback. -.RE -.SS Format Layer -The read formats have a similar lifecycle to the decompression handlers: -.RS 5 -.TP -Registration -Allocate your private data and initialize your pointers. -.TP -Bid -Formats bid by invoking the -\fB\%read_ahead\fP() -decompression method but not calling the -\fB\%consume\fP() -method. -This allows each bidder to look ahead in the input stream. -Bidders should not look further ahead than necessary, as long -look aheads put pressure on the decompression layer to buffer -lots of data. -Most formats only require a few hundred bytes of look ahead; -look aheads of a few kilobytes are reasonable. -(The ISO9660 reader sometimes looks ahead by 48k, which -should be considered an upper limit.) -.TP -Read header -The header read is usually the most complex part of any format. -There are a few strategies worth mentioning: -For formats such as tar or cpio, reading and parsing the header is -straightforward since headers alternate with data. -For formats that store all header data at the beginning of the file, -the first header read request may have to read all headers into -memory and store that data, sorted by the location of the file -data. -Subsequent header read requests will skip forward to the -beginning of the file data and return the corresponding header. -.TP -Read Data -The read data interface supports sparse files; this requires that -each call return a block of data specifying the file offset and -size. -This may require you to carefully track the location so that you -can return accurate file offsets for each read. -Remember that the decompressor will return as much data as it has. -Generally, you will want to request one byte, -examine the return value to see how much data is available, and -possibly trim that to the amount you can use. -You should invoke consume for each block just before you return it. -.TP -Skip All Data -The skip data call should skip over all file data and trailing padding. -This is called automatically by the API layer just before each -header read. -It is also called in response to the client calling the public -\fB\%data_skip\fP() -function. -.TP -Cleanup -On cleanup, the format should release all of its allocated memory. -.RE -.SS API Layer -XXX to do XXX -.SH WRITE ARCHITECTURE -.ad l -The write API has a similar set of four layers: -an API layer, a format layer, a compression layer, and an I/O layer. -The registration here is much simpler because only -one format and one compression can be registered at a time. -.SS I/O Layer and Client Callbacks -XXX To be written XXX -.SS Compression Layer -XXX To be written XXX -.SS Format Layer -XXX To be written XXX -.SS API Layer -XXX To be written XXX -.SH WRITE_DISK ARCHITECTURE -.ad l -The write_disk API is intended to look just like the write API -to clients. -Since it does not handle multiple formats or compression, it -is not layered internally. -.SH GENERAL SERVICES -.ad l -The -\fB\%archive_read\fP, -\fB\%archive_write\fP, -and -\fB\%archive_write_disk\fP -objects all contain an initial -\fB\%archive\fP -object which provides common support for a set of standard services. -(Recall that ANSI/ISO C90 guarantees that you can cast freely between -a pointer to a structure and a pointer to the first element of that -structure.) -The -\fB\%archive\fP -object has a magic value that indicates which API this object -is associated with, -slots for storing error information, -and function pointers for virtualized API functions. -.SH MISCELLANEOUS NOTES -.ad l -Connecting existing archiving libraries into libarchive is generally -quite difficult. -In particular, many existing libraries strongly assume that you -are reading from a file; they seek forwards and backwards as necessary -to locate various pieces of information. -In contrast, libarchive never seeks backwards in its input, which -sometimes requires very different approaches. -.PP -For example, libarchive's ISO9660 support operates very differently -from most ISO9660 readers. -The libarchive support utilizes a work-queue design that -keeps a list of known entries sorted by their location in the input. -Whenever libarchive's ISO9660 implementation is asked for the next -header, checks this list to find the next item on the disk. -Directories are parsed when they are encountered and new -items are added to the list. -This design relies heavily on the ISO9660 image being optimized so that -directories always occur earlier on the disk than the files they -describe. -.PP -Depending on the specific format, such approaches may not be possible. -The ZIP format specification, for example, allows archivers to store -key information only at the end of the file. -In theory, it is possible to create ZIP archives that cannot -be read without seeking. -Fortunately, such archives are very rare, and libarchive can read -most ZIP archives, though it cannot always extract as much information -as a dedicated ZIP program. -.SH SEE ALSO -.ad l -\fBarchive_entry\fP(3), -\fBarchive_read\fP(3), -\fBarchive_write\fP(3), -\fBarchive_write_disk\fP(3), -\fBlibarchive\fP(3) -.SH HISTORY -.ad l -The -\fB\%libarchive\fP -library first appeared in -FreeBSD 5.3. -.SH AUTHORS -.ad l --nosplit -The -\fB\%libarchive\fP -library was written by -Tim Kientzle \% diff --git a/thirdparty/libarchive/doc/man/mtree.5 b/thirdparty/libarchive/doc/man/mtree.5 deleted file mode 100644 index 8e3330988..000000000 --- a/thirdparty/libarchive/doc/man/mtree.5 +++ /dev/null @@ -1,345 +0,0 @@ -.TH MTREE 5 "September 4, 2013" "" -.SH NAME -.ad l -\fB\%mtree\fP -\- format of mtree dir hierarchy files -.SH DESCRIPTION -.ad l -The -\fB\%mtree\fP -format is a textual format that describes a collection of filesystem objects. -Such files are typically used to create or verify directory hierarchies. -.SS General Format -An -\fB\%mtree\fP -file consists of a series of lines, each providing information -about a single filesystem object. -Leading whitespace is always ignored. -.PP -When encoding file or pathnames, any backslash character or -character outside of the 95 printable ASCII characters must be -encoded as a backslash followed by three -octal digits. -When reading mtree files, any appearance of a backslash -followed by three octal digits should be converted into the -corresponding character. -.PP -Each line is interpreted independently as one of the following types: -.RS 5 -.TP -Blank -Blank lines are ignored. -.TP -Comment -Lines beginning with -\fB#\fP -are ignored. -.TP -Special -Lines beginning with -\fB/\fP -are special commands that influence -the interpretation of later lines. -.TP -Relative -If the first whitespace-delimited word has no -\fB/\fP -characters, -it is the name of a file in the current directory. -Any relative entry that describes a directory changes the -current directory. -.TP -dot-dot -As a special case, a relative entry with the filename -\fI\& ..\fP -changes the current directory to the parent directory. -Options on dot-dot entries are always ignored. -.TP -Full -If the first whitespace-delimited word has a -\fB/\fP -character after -the first character, it is the pathname of a file relative to the -starting directory. -There can be multiple full entries describing the same file. -.RE -.PP -Some tools that process -\fB\%mtree\fP -files may require that multiple lines describing the same file -occur consecutively. -It is not permitted for the same file to be mentioned using -both a relative and a full file specification. -.SS Special commands -Two special commands are currently defined: -.RS 5 -.TP -\fB/set\fP -This command defines default values for one or more keywords. -It is followed on the same line by one or more whitespace-separated -keyword definitions. -These definitions apply to all following files that do not specify -a value for that keyword. -.TP -\fB/unset\fP -This command removes any default value set by a previous -\fB/set\fP -command. -It is followed on the same line by one or more keywords -separated by whitespace. -.RE -.SS Keywords -After the filename, a full or relative entry consists of zero -or more whitespace-separated keyword definitions. -Each such definition consists of a key from the following -list immediately followed by an '=' sign -and a value. -Software programs reading mtree files should warn about -unrecognized keywords. -.PP -Currently supported keywords are as follows: -.RS 5 -.TP -\fBcksum\fP -The checksum of the file using the default algorithm specified by -the -\fBcksum\fP(1) -utility. -.TP -\fBdevice\fP -The device number for -.B block -or -.B char -file types. -The value must be one of the following forms: -.RS 5 -.TP -\fIformat\fP, \fImajor\fP, \fIminor\fP Bo, \fIsubunit\fP Bc -A device with -\fImajor\fP, minor -and optional -\fIsubunit\fP -fields. -Their meaning is specified by the operating's system -\fIformat\fP. -See below for valid formats. -.TP -\fInumber\fP -Opaque number (as stored on the file system). -.RE -.PP -The following values for -\fIformat\fP -are recognized: -.B native , -.B 386bsd , -.B 4bsd , -.B bsdos , -.B freebsd , -.B hpux , -.B isc , -.B linux , -.B netbsd , -.B osf1 , -.B sco , -.B solaris , -.B sunos , -.B svr3 , -.B svr4 , -and -.B ultrix . -.PP -See -\fBmknod\fP(8) -for more details. -.TP -\fBcontents\fP -The full pathname of a file that holds the contents of this file. -.TP -\fBflags\fP -The file flags as a symbolic name. -See -\fBchflags\fP(1) -for information on these names. -If no flags are to be set the string -``none'' -may be used to override the current default. -.TP -\fBgid\fP -The file group as a numeric value. -.TP -\fBgname\fP -The file group as a symbolic name. -.TP -\fBignore\fP -Ignore any file hierarchy below this file. -.TP -\fBinode\fP -The inode number. -.TP -\fBlink\fP -The target of the symbolic link when type=link. -.TP -\fBmd5\fP -The MD5 message digest of the file. -.TP -\fBmd5digest\fP -A synonym for -\fBmd5\fP. -.TP -\fBmode\fP -The current file's permissions as a numeric (octal) or symbolic -value. -.TP -\fBnlink\fP -The number of hard links the file is expected to have. -.TP -\fBnochange\fP -Make sure this file or directory exists but otherwise ignore all attributes. -.TP -\fBoptional\fP -The file is optional; do not complain about the file if it is not in -the file hierarchy. -.TP -\fBresdevice\fP -The -``resident'' -device number of the file, e.g. the ID of the device that -contains the file. -Its format is the same as the one for -\fBdevice\fP. -.TP -\fBripemd160digest\fP -The -Tn RIPEMD160 -message digest of the file. -.TP -\fBrmd160\fP -A synonym for -\fBripemd160digest\fP. -.TP -\fBrmd160digest\fP -A synonym for -\fBripemd160digest\fP. -.TP -\fBsha1\fP -The -Tn FIPS -160-1 -(``Tn SHA-1'') -message digest of the file. -.TP -\fBsha1digest\fP -A synonym for -\fBsha1\fP. -.TP -\fBsha256\fP -The -Tn FIPS -180-2 -(``Tn SHA-256'') -message digest of the file. -.TP -\fBsha256digest\fP -A synonym for -\fBsha256\fP. -.TP -\fBsha384\fP -The -Tn FIPS -180-2 -(``Tn SHA-384'') -message digest of the file. -.TP -\fBsha384digest\fP -A synonym for -\fBsha384\fP. -.TP -\fBsha512\fP -The -Tn FIPS -180-2 -(``Tn SHA-512'') -message digest of the file. -.TP -\fBsha512digest\fP -A synonym for -\fBsha512\fP. -.TP -\fBsize\fP -The size, in bytes, of the file. -.TP -\fBtime\fP -The last modification time of the file. -.TP -\fBtype\fP -The type of the file; may be set to any one of the following: -.PP -.RS 5 -.TP -\fBblock\fP -block special device -.TP -\fBchar\fP -character special device -.TP -\fBdir\fP -directory -.TP -\fBfifo\fP -fifo -.TP -\fBfile\fP -regular file -.TP -\fBlink\fP -symbolic link -.TP -\fBsocket\fP -socket -.RE -.TP -\fBuid\fP -The file owner as a numeric value. -.TP -\fBuname\fP -The file owner as a symbolic name. -.RE -.SH SEE ALSO -.ad l -\fBcksum\fP(1), -\fBfind\fP(1), -\fBmtree\fP(8) -.SH HISTORY -.ad l -The -\fB\%mtree\fP -utility appeared in -Bx 4.3 Reno. -The -Tn MD5 -digest capability was added in -FreeBSD 2.1, -in response to the widespread use of programs which can spoof -\fBcksum\fP(1). -The -Tn SHA-1 -and -Tn RIPEMD160 -digests were added in -FreeBSD 4.0, -as new attacks have demonstrated weaknesses in -Tn MD5. -The -Tn SHA-256 -digest was added in -FreeBSD 6.0. -Support for file flags was added in -FreeBSD 4.0, -and mostly comes from -NetBSD. -The -``full'' -entry format was added by -NetBSD. diff --git a/thirdparty/libarchive/doc/man/tar.5 b/thirdparty/libarchive/doc/man/tar.5 deleted file mode 100644 index e8fed3e6b..000000000 --- a/thirdparty/libarchive/doc/man/tar.5 +++ /dev/null @@ -1,1011 +0,0 @@ -.TH TAR 5 "December 27, 2016" "" -.SH NAME -.ad l -\fB\%tar\fP -\- format of tape archive files -.SH DESCRIPTION -.ad l -The -\fB\%tar\fP -archive format collects any number of files, directories, and other -file system objects (symbolic links, device nodes, etc.) into a single -stream of bytes. -The format was originally designed to be used with -tape drives that operate with fixed-size blocks, but is widely used as -a general packaging mechanism. -.SS General Format -A -\fB\%tar\fP -archive consists of a series of 512-byte records. -Each file system object requires a header record which stores basic metadata -(pathname, owner, permissions, etc.) and zero or more records containing any -file data. -The end of the archive is indicated by two records consisting -entirely of zero bytes. -.PP -For compatibility with tape drives that use fixed block sizes, -programs that read or write tar files always read or write a fixed -number of records with each I/O operation. -These -``blocks'' -are always a multiple of the record size. -The maximum block size supported by early -implementations was 10240 bytes or 20 records. -This is still the default for most implementations -although block sizes of 1MiB (2048 records) or larger are -commonly used with modern high-speed tape drives. -(Note: the terms -``block'' -and -``record'' -here are not entirely standard; this document follows the -convention established by John Gilmore in documenting -\fB\%pdtar\fP.) -.SS Old-Style Archive Format -The original tar archive format has been extended many times to -include additional information that various implementors found -necessary. -This section describes the variant implemented by the tar command -included in -At v7, -which seems to be the earliest widely-used version of the tar program. -.PP -The header record for an old-style -\fB\%tar\fP -archive consists of the following: -.RS 4 -.nf -struct header_old_tar { - char name[100]; - char mode[8]; - char uid[8]; - char gid[8]; - char size[12]; - char mtime[12]; - char checksum[8]; - char linkflag[1]; - char linkname[100]; - char pad[255]; -}; -.RE -All unused bytes in the header record are filled with nulls. -.RS 5 -.TP -\fIname\fP -Pathname, stored as a null-terminated string. -Early tar implementations only stored regular files (including -hardlinks to those files). -One common early convention used a trailing "/" character to indicate -a directory name, allowing directory permissions and owner information -to be archived and restored. -.TP -\fImode\fP -File mode, stored as an octal number in ASCII. -.TP -\fIuid\fP, \fIgid\fP -User id and group id of owner, as octal numbers in ASCII. -.TP -\fIsize\fP -Size of file, as octal number in ASCII. -For regular files only, this indicates the amount of data -that follows the header. -In particular, this field was ignored by early tar implementations -when extracting hardlinks. -Modern writers should always store a zero length for hardlink entries. -.TP -\fImtime\fP -Modification time of file, as an octal number in ASCII. -This indicates the number of seconds since the start of the epoch, -00:00:00 UTC January 1, 1970. -Note that negative values should be avoided -here, as they are handled inconsistently. -.TP -\fIchecksum\fP -Header checksum, stored as an octal number in ASCII. -To compute the checksum, set the checksum field to all spaces, -then sum all bytes in the header using unsigned arithmetic. -This field should be stored as six octal digits followed by a null and a space -character. -Note that many early implementations of tar used signed arithmetic -for the checksum field, which can cause interoperability problems -when transferring archives between systems. -Modern robust readers compute the checksum both ways and accept the -header if either computation matches. -.TP -\fIlinkflag\fP, \fIlinkname\fP -In order to preserve hardlinks and conserve tape, a file -with multiple links is only written to the archive the first -time it is encountered. -The next time it is encountered, the -\fIlinkflag\fP -is set to an ASCII -Sq 1 -and the -\fIlinkname\fP -field holds the first name under which this file appears. -(Note that regular files have a null value in the -\fIlinkflag\fP -field.) -.RE -.PP -Early tar implementations varied in how they terminated these fields. -The tar command in -At v7 -used the following conventions (this is also documented in early BSD manpages): -the pathname must be null-terminated; -the mode, uid, and gid fields must end in a space and a null byte; -the size and mtime fields must end in a space; -the checksum is terminated by a null and a space. -Early implementations filled the numeric fields with leading spaces. -This seems to have been common practice until the -IEEE Std 1003.1-1988 (``POSIX.1'') -standard was released. -For best portability, modern implementations should fill the numeric -fields with leading zeros. -.SS Pre-POSIX Archives -An early draft of -IEEE Std 1003.1-1988 (``POSIX.1'') -served as the basis for John Gilmore's -\fB\%pdtar\fP -program and many system implementations from the late 1980s -and early 1990s. -These archives generally follow the POSIX ustar -format described below with the following variations: -.RS 5 -.IP \(bu -The magic value consists of the five characters -``ustar'' -followed by a space. -The version field contains a space character followed by a null. -.IP \(bu -The numeric fields are generally filled with leading spaces -(not leading zeros as recommended in the final standard). -.IP \(bu -The prefix field is often not used, limiting pathnames to -the 100 characters of old-style archives. -.RE -.SS POSIX ustar Archives -IEEE Std 1003.1-1988 (``POSIX.1'') -defined a standard tar file format to be read and written -by compliant implementations of -\fBtar\fP(1). -This format is often called the -``ustar'' -format, after the magic value used -in the header. -(The name is an acronym for -``Unix Standard TAR''.) -It extends the historic format with new fields: -.RS 4 -.nf -struct header_posix_ustar { - char name[100]; - char mode[8]; - char uid[8]; - char gid[8]; - char size[12]; - char mtime[12]; - char checksum[8]; - char typeflag[1]; - char linkname[100]; - char magic[6]; - char version[2]; - char uname[32]; - char gname[32]; - char devmajor[8]; - char devminor[8]; - char prefix[155]; - char pad[12]; -}; -.RE -.RS 5 -.TP -\fItypeflag\fP -Type of entry. -POSIX extended the earlier -\fIlinkflag\fP -field with several new type values: -.RS 5 -.TP -``0'' -Regular file. -NUL should be treated as a synonym, for compatibility purposes. -.TP -``1'' -Hard link. -.TP -``2'' -Symbolic link. -.TP -``3'' -Character device node. -.TP -``4'' -Block device node. -.TP -``5'' -Directory. -.TP -``6'' -FIFO node. -.TP -``7'' -Reserved. -.TP -Other -A POSIX-compliant implementation must treat any unrecognized typeflag value -as a regular file. -In particular, writers should ensure that all entries -have a valid filename so that they can be restored by readers that do not -support the corresponding extension. -Uppercase letters "A" through "Z" are reserved for custom extensions. -Note that sockets and whiteout entries are not archivable. -.RE -It is worth noting that the -\fIsize\fP -field, in particular, has different meanings depending on the type. -For regular files, of course, it indicates the amount of data -following the header. -For directories, it may be used to indicate the total size of all -files in the directory, for use by operating systems that pre-allocate -directory space. -For all other types, it should be set to zero by writers and ignored -by readers. -.TP -\fImagic\fP -Contains the magic value -``ustar'' -followed by a NUL byte to indicate that this is a POSIX standard archive. -Full compliance requires the uname and gname fields be properly set. -.TP -\fIversion\fP -Version. -This should be -``00'' -(two copies of the ASCII digit zero) for POSIX standard archives. -.TP -\fIuname\fP, \fIgname\fP -User and group names, as null-terminated ASCII strings. -These should be used in preference to the uid/gid values -when they are set and the corresponding names exist on -the system. -.TP -\fIdevmajor\fP, \fIdevminor\fP -Major and minor numbers for character device or block device entry. -.TP -\fIname\fP, \fIprefix\fP -If the pathname is too long to fit in the 100 bytes provided by the standard -format, it can be split at any -\fI/\fP -character with the first portion going into the prefix field. -If the prefix field is not empty, the reader will prepend -the prefix value and a -\fI/\fP -character to the regular name field to obtain the full pathname. -The standard does not require a trailing -\fI/\fP -character on directory names, though most implementations still -include this for compatibility reasons. -.RE -.PP -Note that all unused bytes must be set to -.BR NUL. -.PP -Field termination is specified slightly differently by POSIX -than by previous implementations. -The -\fImagic\fP, -\fIuname\fP, -and -\fIgname\fP -fields must have a trailing -.BR NUL. -The -\fIpathname\fP, -\fIlinkname\fP, -and -\fIprefix\fP -fields must have a trailing -.BR NUL -unless they fill the entire field. -(In particular, it is possible to store a 256-character pathname if it -happens to have a -\fI/\fP -as the 156th character.) -POSIX requires numeric fields to be zero-padded in the front, and requires -them to be terminated with either space or -.BR NUL -characters. -.PP -Currently, most tar implementations comply with the ustar -format, occasionally extending it by adding new fields to the -blank area at the end of the header record. -.SS Numeric Extensions -There have been several attempts to extend the range of sizes -or times supported by modifying how numbers are stored in the -header. -.PP -One obvious extension to increase the size of files is to -eliminate the terminating characters from the various -numeric fields. -For example, the standard only allows the size field to contain -11 octal digits, reserving the twelfth byte for a trailing -NUL character. -Allowing 12 octal digits allows file sizes up to 64 GB. -.PP -Another extension, utilized by GNU tar, star, and other newer -\fB\%tar\fP -implementations, permits binary numbers in the standard numeric fields. -This is flagged by setting the high bit of the first byte. -The remainder of the field is treated as a signed twos-complement -value. -This permits 95-bit values for the length and time fields -and 63-bit values for the uid, gid, and device numbers. -In particular, this provides a consistent way to handle -negative time values. -GNU tar supports this extension for the -length, mtime, ctime, and atime fields. -Joerg Schilling's star program and the libarchive library support -this extension for all numeric fields. -Note that this extension is largely obsoleted by the extended -attribute record provided by the pax interchange format. -.PP -Another early GNU extension allowed base-64 values rather than octal. -This extension was short-lived and is no longer supported by any -implementation. -.SS Pax Interchange Format -There are many attributes that cannot be portably stored in a -POSIX ustar archive. -IEEE Std 1003.1-2001 (``POSIX.1'') -defined a -``pax interchange format'' -that uses two new types of entries to hold text-formatted -metadata that applies to following entries. -Note that a pax interchange format archive is a ustar archive in every -respect. -The new data is stored in ustar-compatible archive entries that use the -``x'' -or -``g'' -typeflag. -In particular, older implementations that do not fully support these -extensions will extract the metadata into regular files, where the -metadata can be examined as necessary. -.PP -An entry in a pax interchange format archive consists of one or -two standard ustar entries, each with its own header and data. -The first optional entry stores the extended attributes -for the following entry. -This optional first entry has an "x" typeflag and a size field that -indicates the total size of the extended attributes. -The extended attributes themselves are stored as a series of text-format -lines encoded in the portable UTF-8 encoding. -Each line consists of a decimal number, a space, a key string, an equals -sign, a value string, and a new line. -The decimal number indicates the length of the entire line, including the -initial length field and the trailing newline. -An example of such a field is: -.RS 4 -25 ctime=1084839148.1212\en -.RE -Keys in all lowercase are standard keys. -Vendors can add their own keys by prefixing them with an all uppercase -vendor name and a period. -Note that, unlike the historic header, numeric values are stored using -decimal, not octal. -A description of some common keys follows: -.RS 5 -.TP -\fBatime\fP, \fBctime\fP, \fBmtime\fP -File access, inode change, and modification times. -These fields can be negative or include a decimal point and a fractional value. -.TP -\fBhdrcharset\fP -The character set used by the pax extension values. -By default, all textual values in the pax extended attributes -are assumed to be in UTF-8, including pathnames, user names, -and group names. -In some cases, it is not possible to translate local -conventions into UTF-8. -If this key is present and the value is the six-character ASCII string -``BINARY'', -then all textual values are assumed to be in a platform-dependent -multi-byte encoding. -Note that there are only two valid values for this key: -``BINARY'' -or -``ISO-IR\ 10646\ 2000\ UTF-8''. -No other values are permitted by the standard, and -the latter value should generally not be used as it is the -default when this key is not specified. -In particular, this flag should not be used as a general -mechanism to allow filenames to be stored in arbitrary -encodings. -.TP -\fBuname\fP, \fBuid\fP, \fBgname\fP, \fBgid\fP -User name, group name, and numeric UID and GID values. -The user name and group name stored here are encoded in UTF8 -and can thus include non-ASCII characters. -The UID and GID fields can be of arbitrary length. -.TP -\fBlinkpath\fP -The full path of the linked-to file. -Note that this is encoded in UTF8 and can thus include non-ASCII characters. -.TP -\fBpath\fP -The full pathname of the entry. -Note that this is encoded in UTF8 and can thus include non-ASCII characters. -.TP -\fBrealtime.*\fP, \fBsecurity.*\fP -These keys are reserved and may be used for future standardization. -.TP -\fBsize\fP -The size of the file. -Note that there is no length limit on this field, allowing conforming -archives to store files much larger than the historic 8GB limit. -.TP -\fBSCHILY.*\fP -Vendor-specific attributes used by Joerg Schilling's -\fB\%star\fP -implementation. -.TP -\fBSCHILY.acl.access\fP, \fBSCHILY.acl.default\fP, \fBSCHILY.acl.ace\fP -Stores the access, default and NFSv4 ACLs as textual strings in a format -that is an extension of the format specified by POSIX.1e draft 17. -In particular, each user or group access specification can include -an additional colon-separated field with the numeric UID or GID. -This allows ACLs to be restored on systems that may not have complete -user or group information available (such as when NIS/YP or LDAP services -are temporarily unavailable). -.TP -\fBSCHILY.devminor\fP, \fBSCHILY.devmajor\fP -The full minor and major numbers for device nodes. -.TP -\fBSCHILY.fflags\fP -The file flags. -.TP -\fBSCHILY.realsize\fP -The full size of the file on disk. -XXX explain? XXX -.TP -\fBSCHILY.dev\fP, \fBSCHILY.ino\fP, \fBSCHILY.nlinks\fP -The device number, inode number, and link count for the entry. -In particular, note that a pax interchange format archive using Joerg -Schilling's -\fBSCHILY.*\fP -extensions can store all of the data from -\fIstruct\fP stat. -.TP -\fBLIBARCHIVE.*\fP -Vendor-specific attributes used by the -\fB\%libarchive\fP -library and programs that use it. -.TP -\fBLIBARCHIVE.creationtime\fP -The time when the file was created. -(This should not be confused with the POSIX -``ctime'' -attribute, which refers to the time when the file -metadata was last changed.) -.TP -\fBLIBARCHIVE.xattr\fP. \fInamespace\fP. \fIkey\fP -Libarchive stores POSIX.1e-style extended attributes using -keys of this form. -The -\fIkey\fP -value is URL-encoded: -All non-ASCII characters and the two special characters -``='' -and -``%'' -are encoded as -``%'' -followed by two uppercase hexadecimal digits. -The value of this key is the extended attribute value -encoded in base 64. -XXX Detail the base-64 format here XXX -.TP -\fBVENDOR.*\fP -XXX document other vendor-specific extensions XXX -.RE -.PP -Any values stored in an extended attribute override the corresponding -values in the regular tar header. -Note that compliant readers should ignore the regular fields when they -are overridden. -This is important, as existing archivers are known to store non-compliant -values in the standard header fields in this situation. -There are no limits on length for any of these fields. -In particular, numeric fields can be arbitrarily large. -All text fields are encoded in UTF8. -Compliant writers should store only portable 7-bit ASCII characters in -the standard ustar header and use extended -attributes whenever a text value contains non-ASCII characters. -.PP -In addition to the -\fBx\fP -entry described above, the pax interchange format -also supports a -\fBg\fP -entry. -The -\fBg\fP -entry is identical in format, but specifies attributes that serve as -defaults for all subsequent archive entries. -The -\fBg\fP -entry is not widely used. -.PP -Besides the new -\fBx\fP -and -\fBg\fP -entries, the pax interchange format has a few other minor variations -from the earlier ustar format. -The most troubling one is that hardlinks are permitted to have -data following them. -This allows readers to restore any hardlink to a file without -having to rewind the archive to find an earlier entry. -However, it creates complications for robust readers, as it is no longer -clear whether or not they should ignore the size field for hardlink entries. -.SS GNU Tar Archives -The GNU tar program started with a pre-POSIX format similar to that -described earlier and has extended it using several different mechanisms: -It added new fields to the empty space in the header (some of which was later -used by POSIX for conflicting purposes); -it allowed the header to be continued over multiple records; -and it defined new entries that modify following entries -(similar in principle to the -\fBx\fP -entry described above, but each GNU special entry is single-purpose, -unlike the general-purpose -\fBx\fP -entry). -As a result, GNU tar archives are not POSIX compatible, although -more lenient POSIX-compliant readers can successfully extract most -GNU tar archives. -.RS 4 -.nf -struct header_gnu_tar { - char name[100]; - char mode[8]; - char uid[8]; - char gid[8]; - char size[12]; - char mtime[12]; - char checksum[8]; - char typeflag[1]; - char linkname[100]; - char magic[6]; - char version[2]; - char uname[32]; - char gname[32]; - char devmajor[8]; - char devminor[8]; - char atime[12]; - char ctime[12]; - char offset[12]; - char longnames[4]; - char unused[1]; - struct { - char offset[12]; - char numbytes[12]; - } sparse[4]; - char isextended[1]; - char realsize[12]; - char pad[17]; -}; -.RE -.RS 5 -.TP -\fItypeflag\fP -GNU tar uses the following special entry types, in addition to -those defined by POSIX: -.RS 5 -.TP -7 -GNU tar treats type "7" records identically to type "0" records, -except on one obscure RTOS where they are used to indicate the -pre-allocation of a contiguous file on disk. -.TP -D -This indicates a directory entry. -Unlike the POSIX-standard "5" -typeflag, the header is followed by data records listing the names -of files in this directory. -Each name is preceded by an ASCII "Y" -if the file is stored in this archive or "N" if the file is not -stored in this archive. -Each name is terminated with a null, and -an extra null marks the end of the name list. -The purpose of this -entry is to support incremental backups; a program restoring from -such an archive may wish to delete files on disk that did not exist -in the directory when the archive was made. -.PP -Note that the "D" typeflag specifically violates POSIX, which requires -that unrecognized typeflags be restored as normal files. -In this case, restoring the "D" entry as a file could interfere -with subsequent creation of the like-named directory. -.TP -K -The data for this entry is a long linkname for the following regular entry. -.TP -L -The data for this entry is a long pathname for the following regular entry. -.TP -M -This is a continuation of the last file on the previous volume. -GNU multi-volume archives guarantee that each volume begins with a valid -entry header. -To ensure this, a file may be split, with part stored at the end of one volume, -and part stored at the beginning of the next volume. -The "M" typeflag indicates that this entry continues an existing file. -Such entries can only occur as the first or second entry -in an archive (the latter only if the first entry is a volume label). -The -\fIsize\fP -field specifies the size of this entry. -The -\fIoffset\fP -field at bytes 369-380 specifies the offset where this file fragment -begins. -The -\fIrealsize\fP -field specifies the total size of the file (which must equal -\fIsize\fP -plus -\fIoffset\fP). -When extracting, GNU tar checks that the header file name is the one it is -expecting, that the header offset is in the correct sequence, and that -the sum of offset and size is equal to realsize. -.TP -N -Type "N" records are no longer generated by GNU tar. -They contained a -list of files to be renamed or symlinked after extraction; this was -originally used to support long names. -The contents of this record -are a text description of the operations to be done, in the form -``Rename %s to %s\en'' -or -``Symlink %s to %s\en ;'' -in either case, both -filenames are escaped using K&R C syntax. -Due to security concerns, "N" records are now generally ignored -when reading archives. -.TP -S -This is a -``sparse'' -regular file. -Sparse files are stored as a series of fragments. -The header contains a list of fragment offset/length pairs. -If more than four such entries are required, the header is -extended as necessary with -``extra'' -header extensions (an older format that is no longer used), or -``sparse'' -extensions. -.TP -V -The -\fIname\fP -field should be interpreted as a tape/volume header name. -This entry should generally be ignored on extraction. -.RE -.TP -\fImagic\fP -The magic field holds the five characters -``ustar'' -followed by a space. -Note that POSIX ustar archives have a trailing null. -.TP -\fIversion\fP -The version field holds a space character followed by a null. -Note that POSIX ustar archives use two copies of the ASCII digit -``0''. -.TP -\fIatime\fP, \fIctime\fP -The time the file was last accessed and the time of -last change of file information, stored in octal as with -\fImtime\fP. -.TP -\fIlongnames\fP -This field is apparently no longer used. -.TP -Sparse \fIoffset\fP / \fInumbytes\fP -Each such structure specifies a single fragment of a sparse -file. -The two fields store values as octal numbers. -The fragments are each padded to a multiple of 512 bytes -in the archive. -On extraction, the list of fragments is collected from the -header (including any extension headers), and the data -is then read and written to the file at appropriate offsets. -.TP -\fIisextended\fP -If this is set to non-zero, the header will be followed by additional -``sparse header'' -records. -Each such record contains information about as many as 21 additional -sparse blocks as shown here: -.RS 4 -.nf -struct gnu_sparse_header { - struct { - char offset[12]; - char numbytes[12]; - } sparse[21]; - char isextended[1]; - char padding[7]; -}; -.RE -.TP -\fIrealsize\fP -A binary representation of the file's complete size, with a much larger range -than the POSIX file size. -In particular, with -\fBM\fP -type files, the current entry is only a portion of the file. -In that case, the POSIX size field will indicate the size of this -entry; the -\fIrealsize\fP -field will indicate the total size of the file. -.RE -.SS GNU tar pax archives -GNU tar 1.14 (XXX check this XXX) and later will write -pax interchange format archives when you specify the -\fB\--posix\fP -flag. -This format follows the pax interchange format closely, -using some -\fBSCHILY\fP -tags and introducing new keywords to store sparse file information. -There have been three iterations of the sparse file support, referred to -as -``0.0'', -``0.1'', -and -``1.0''. -.RS 5 -.TP -\fBGNU.sparse.numblocks\fP, \fBGNU.sparse.offset\fP, \fBGNU.sparse.numbytes\fP, \fBGNU.sparse.size\fP -The -``0.0'' -format used an initial -\fBGNU.sparse.numblocks\fP -attribute to indicate the number of blocks in the file, a pair of -\fBGNU.sparse.offset\fP -and -\fBGNU.sparse.numbytes\fP -to indicate the offset and size of each block, -and a single -\fBGNU.sparse.size\fP -to indicate the full size of the file. -This is not the same as the size in the tar header because the -latter value does not include the size of any holes. -This format required that the order of attributes be preserved and -relied on readers accepting multiple appearances of the same attribute -names, which is not officially permitted by the standards. -.TP -\fBGNU.sparse.map\fP -The -``0.1'' -format used a single attribute that stored a comma-separated -list of decimal numbers. -Each pair of numbers indicated the offset and size, respectively, -of a block of data. -This does not work well if the archive is extracted by an archiver -that does not recognize this extension, since many pax implementations -simply discard unrecognized attributes. -.TP -\fBGNU.sparse.major\fP, \fBGNU.sparse.minor\fP, \fBGNU.sparse.name\fP, \fBGNU.sparse.realsize\fP -The -``1.0'' -format stores the sparse block map in one or more 512-byte blocks -prepended to the file data in the entry body. -The pax attributes indicate the existence of this map -(via the -\fBGNU.sparse.major\fP -and -\fBGNU.sparse.minor\fP -fields) -and the full size of the file. -The -\fBGNU.sparse.name\fP -holds the true name of the file. -To avoid confusion, the name stored in the regular tar header -is a modified name so that extraction errors will be apparent -to users. -.RE -.SS Solaris Tar -XXX More Details Needed XXX -.PP -Solaris tar (beginning with SunOS XXX 5.7 ?? XXX) supports an -``extended'' -format that is fundamentally similar to pax interchange format, -with the following differences: -.RS 5 -.IP \(bu -Extended attributes are stored in an entry whose type is -\fBX\fP, -not -\fBx\fP, -as used by pax interchange format. -The detailed format of this entry appears to be the same -as detailed above for the -\fBx\fP -entry. -.IP \(bu -An additional -\fBA\fP -header is used to store an ACL for the following regular entry. -The body of this entry contains a seven-digit octal number -followed by a zero byte, followed by the -textual ACL description. -The octal value is the number of ACL entries -plus a constant that indicates the ACL type: 01000000 -for POSIX.1e ACLs and 03000000 for NFSv4 ACLs. -.RE -.SS AIX Tar -XXX More details needed XXX -.PP -AIX Tar uses a ustar-formatted header with the type -\fBA\fP -for storing coded ACL information. -Unlike the Solaris format, AIX tar writes this header after the -regular file body to which it applies. -The pathname in this header is either -\fBNFS4\fP -or -\fBAIXC\fP -to indicate the type of ACL stored. -The actual ACL is stored in platform-specific binary format. -.SS Mac OS X Tar -The tar distributed with Apple's Mac OS X stores most regular files -as two separate files in the tar archive. -The two files have the same name except that the first -one has -``._'' -prepended to the last path element. -This special file stores an AppleDouble-encoded -binary blob with additional metadata about the second file, -including ACL, extended attributes, and resources. -To recreate the original file on disk, each -separate file can be extracted and the Mac OS X -\fB\%copyfile\fP() -function can be used to unpack the separate -metadata file and apply it to th regular file. -Conversely, the same function provides a -``pack'' -option to encode the extended metadata from -a file into a separate file whose contents -can then be put into a tar archive. -.PP -Note that the Apple extended attributes interact -badly with long filenames. -Since each file is stored with the full name, -a separate set of extensions needs to be included -in the archive for each one, doubling the overhead -required for files with long names. -.SS Summary of tar type codes -The following list is a condensed summary of the type codes -used in tar header records generated by different tar implementations. -More details about specific implementations can be found above: -.RS 5 -.TP -NUL -Early tar programs stored a zero byte for regular files. -.TP -\fB0\fP -POSIX standard type code for a regular file. -.TP -\fB1\fP -POSIX standard type code for a hard link description. -.TP -\fB2\fP -POSIX standard type code for a symbolic link description. -.TP -\fB3\fP -POSIX standard type code for a character device node. -.TP -\fB4\fP -POSIX standard type code for a block device node. -.TP -\fB5\fP -POSIX standard type code for a directory. -.TP -\fB6\fP -POSIX standard type code for a FIFO. -.TP -\fB7\fP -POSIX reserved. -.TP -\fB7\fP -GNU tar used for pre-allocated files on some systems. -.TP -\fBA\fP -Solaris tar ACL description stored prior to a regular file header. -.TP -\fBA\fP -AIX tar ACL description stored after the file body. -.TP -\fBD\fP -GNU tar directory dump. -.TP -\fBK\fP -GNU tar long linkname for the following header. -.TP -\fBL\fP -GNU tar long pathname for the following header. -.TP -\fBM\fP -GNU tar multivolume marker, indicating the file is a continuation of a file from the previous volume. -.TP -\fBN\fP -GNU tar long filename support. -Deprecated. -.TP -\fBS\fP -GNU tar sparse regular file. -.TP -\fBV\fP -GNU tar tape/volume header name. -.TP -\fBX\fP -Solaris tar general-purpose extension header. -.TP -\fBg\fP -POSIX pax interchange format global extensions. -.TP -\fBx\fP -POSIX pax interchange format per-file extensions. -.RE -.SH SEE ALSO -.ad l -\fBar\fP(1), -\fBpax\fP(1), -\fBtar\fP(1) -.SH STANDARDS -.ad l -The -\fB\%tar\fP -utility is no longer a part of POSIX or the Single Unix Standard. -It last appeared in -Version 2 of the Single UNIX Specification (``SUSv2''). -It has been supplanted in subsequent standards by -\fBpax\fP(1). -The ustar format is currently part of the specification for the -\fBpax\fP(1) -utility. -The pax interchange file format is new with -IEEE Std 1003.1-2001 (``POSIX.1''). -.SH HISTORY -.ad l -A -\fB\%tar\fP -command appeared in Seventh Edition Unix, which was released in January, 1979. -It replaced the -\fB\%tp\fP -program from Fourth Edition Unix which in turn replaced the -\fB\%tap\fP -program from First Edition Unix. -John Gilmore's -\fB\%pdtar\fP -public-domain implementation (circa 1987) was highly influential -and formed the basis of -\fB\%GNU\fP tar -(circa 1988). -Joerg Shilling's -\fB\%star\fP -archiver is another open-source (CDDL) archiver (originally developed -circa 1985) which features complete support for pax interchange -format. -.PP -This documentation was written as part of the -\fB\%libarchive\fP -and -\fB\%bsdtar\fP -project by -Tim Kientzle \% diff --git a/thirdparty/libarchive/doc/mdoc2man.awk b/thirdparty/libarchive/doc/mdoc2man.awk deleted file mode 100755 index 726f628c0..000000000 --- a/thirdparty/libarchive/doc/mdoc2man.awk +++ /dev/null @@ -1,391 +0,0 @@ -#!/usr/bin/awk -# -# Copyright (c) 2003 Peter Stuge -# -# Permission to use, copy, modify, and distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -# Dramatically overhauled by Tim Kientzle. This version almost -# handles library-style pages with Fn, Ft, etc commands. Still -# a lot of problems... - -BEGIN { - displaylines = 0 - trailer = "" - out = "" - sep = "" - nextsep = " " -} - -# Add a word with appropriate preceding whitespace -# Maintain a short queue of the expected upcoming word separators. -function add(str) { - out=out sep str - sep = nextsep - nextsep = " " -} - -# Add a word with no following whitespace -# Use for opening punctuation such as '(' -function addopen(str) { - add(str) - sep = "" -} - -# Add a word with no preceding whitespace -# Use for closing punctuation such as ')' or '.' -function addclose(str) { - sep = "" - add(str) -} - -# Add a word with no space before or after -# Use for separating punctuation such as '=' -function addpunct(str) { - sep = "" - add(str) - sep = "" -} - -# Emit the current line so far -function endline() { - addclose(trailer) - trailer = "" - if(length(out) > 0) { - print out - out="" - } - if(displaylines > 0) { - displaylines = displaylines - 1 - if (displaylines == 0) - dispend() - } - # First word on next line has no preceding whitespace - sep = "" -} - -function linecmd(cmd) { - endline() - add(cmd) - endline() -} - -function breakline() { - linecmd(".br") -} - -# Start an indented display -function dispstart() { - linecmd(".RS 4") -} - -# End an indented display -function dispend() { - linecmd(".RE") -} - -# Collect rest of input line -function wtail() { - retval="" - while(w 0) { - sub("^[ \t]*", "", l) - if (match(l, "^\"")) { - l = substr(l, 2) - o = index(l, "\"") - if (o > 0) { - w = substr(l, 1, o-1) - l = substr(l, o+1) - dest[n++] = w - } else { - dest[n++] = l - l = "" - } - } else { - o = match(l, "[ \t]") - if (o > 0) { - w = substr(l, 1, o-1) - l = substr(l, o+1) - dest[n++] = w - } else { - dest[n++] = l - l = "" - } - } - } - return n-1 -} - -! /^\./ { - out = $0 - endline() - next -} - -/^\.\\"/ { next } - -{ - sub("^\\.","") - nwords=splitwords($0, words) - # TODO: Instead of iterating 'w' over the array, have a separate - # function that returns 'next word' and use that. This will allow - # proper handling of double-quoted arguments as well. - for(w=1;w<=nwords;w++) { - if(match(words[w],"^Li$")) { # Literal; rest of line is unformatted - dispstart() - displaylines = 1 - } else if(match(words[w],"^Dl$")) { # Display literal - dispstart() - displaylines = 1 - } else if(match(words[w],"^Bd$")) { # Begin display - if(match(words[w+1],"-literal")) { - dispstart() - linecmd(".nf") - displaylines=10000 - w=nwords - } - } else if(match(words[w],"^Ed$")) { # End display - displaylines = 0 - dispend() - } else if(match(words[w],"^Ns$")) { # Suppress space after next word - nextsep = "" - } else if(match(words[w],"^No$")) { # Normal text - add(words[++w]) - } else if(match(words[w],"^Dq$")) { # Quote - addopen("``") - add(words[++w]) - while(w") - } else if(match(words[w],"^Dd$")) { - date=wtail() - next - } else if(match(words[w],"^Dt$")) { - id=wtail() - next - } else if(match(words[w],"^Ox$")) { - add("OpenBSD") - } else if(match(words[w],"^Fx$")) { - add("FreeBSD") - } else if(match(words[w],"^Nx$")) { - add("NetBSD") - } else if(match(words[w],"^St$")) { - if (match(words[w+1], "^-p1003.1$")) { - w++ - add("IEEE Std 1003.1 (``POSIX.1'')") - } else if(match(words[w+1], "^-p1003.1-96$")) { - w++ - add("ISO/IEC 9945-1:1996 (``POSIX.1'')") - } else if(match(words[w+1], "^-p1003.1-88$")) { - w++ - add("IEEE Std 1003.1-1988 (``POSIX.1'')") - } else if(match(words[w+1], "^-p1003.1-2001$")) { - w++ - add("IEEE Std 1003.1-2001 (``POSIX.1'')") - } else if(match(words[w+1], "^-susv2$")) { - w++ - add("Version 2 of the Single UNIX Specification (``SUSv2'')") - } - } else if(match(words[w],"^Ex$")) { - if (match(words[w+1], "^-std$")) { - w++ - add("The \\fB" name "\\fP utility exits 0 on success, and >0 if an error occurs.") - } - } else if(match(words[w],"^Os$")) { - add(".TH " id " \"" date "\" \"" wtail() "\"") - } else if(match(words[w],"^Sh$")) { - section=wtail() - add(".SH " section) - linecmd(".ad l") - } else if(match(words[w],"^Xr$")) { - add("\\fB" words[++w] "\\fP(" words[++w] ")" words[++w]) - } else if(match(words[w],"^Nm$")) { - if(match(section,"SYNOPSIS")) - breakline() - if(w >= nwords) - n=name - else if (match(words[w+1], "^[A-Z][a-z]$")) - n=name - else if (match(words[w+1], "^[.,;:]$")) - n=name - else { - n=words[++w] - if(!length(name)) - name=n - } - if(!length(n)) - n=name - add("\\fB\\%" n "\\fP") - } else if(match(words[w],"^Nd$")) { - add("\\- " wtail()) - } else if(match(words[w],"^Fl$")) { - add("\\fB\\-" words[++w] "\\fP") - } else if(match(words[w],"^Ar$")) { - addopen("\\fI") - if(w==nwords) - add("file ...\\fP") - else - add(words[++w] "\\fP") - } else if(match(words[w],"^Cm$")) { - add("\\fB" words[++w] "\\fP") - } else if(match(words[w],"^Op$")) { - addopen("[") - option=1 - trailer="]" trailer - } else if(match(words[w],"^Pp$")) { - linecmd(".PP") - } else if(match(words[w],"^An$")) { - endline() - } else if(match(words[w],"^Ss$")) { - add(".SS") - } else if(match(words[w],"^Ft$")) { - if (match(section, "SYNOPSIS")) { - breakline() - } - add("\\fI" wtail() "\\fP") - if (match(section, "SYNOPSIS")) { - breakline() - } - } else if(match(words[w],"^Fn$")) { - ++w - F = "\\fB\\%" words[w] "\\fP(" - Fsep = "" - while(w\\fP") - } else if(match(words[w],"^Pa$")) { - addopen("\\fI") - w++ - if(match(words[w],"^\\.")) - add("\\&") - add(words[w] "\\fP") - } else if(match(words[w],"^Dv$")) { - add(".BR") - } else if(match(words[w],"^Em|Ev$")) { - add(".IR") - } else if(match(words[w],"^Pq$")) { - addopen("(") - trailer=")" trailer - } else if(match(words[w],"^Aq$")) { - addopen("\\%<") - trailer=">" trailer - } else if(match(words[w],"^Brq$")) { - addopen("{") - trailer="}" trailer - } else if(match(words[w],"^S[xy]$")) { - add(".B " wtail()) - } else if(match(words[w],"^Ic$")) { - add("\\fB") - trailer="\\fP" trailer - } else if(match(words[w],"^Bl$")) { - oldoptlist=optlist - linecmd(".RS 5") - if(match(words[w+1],"-bullet")) - optlist=1 - else if(match(words[w+1],"-enum")) { - optlist=2 - enum=0 - } else if(match(words[w+1],"-tag")) - optlist=3 - else if(match(words[w+1],"-item")) - optlist=4 - else if(match(words[w+1],"-bullet")) - optlist=1 - w=nwords - } else if(match(words[w],"^El$")) { - linecmd(".RE") - optlist=oldoptlist - } else if(match(words[w],"^It$")&&optlist) { - if(optlist==1) - add(".IP \\(bu") - else if(optlist==2) - add(".IP " ++enum ".") - else if(optlist==3) { - add(".TP") - endline() - if(match(words[w+1],"^Pa$|^Ev$")) { - add(".B") - w++ - } - } else if(optlist==4) - add(".IP") - } else if(match(words[w],"^Xo$")) { - # TODO: Figure out how to handle this - } else if(match(words[w],"^Xc$")) { - # TODO: Figure out how to handle this - } else if(match(words[w],"^[=]$")) { - addpunct(words[w]) - } else if(match(words[w],"^[[{(]$")) { - addopen(words[w]) - } else if(match(words[w],"^[\\])}.,;:]$")) { - addclose(words[w]) - } else { - add(words[w]) - } - } - if(match(out,"^\\.[^a-zA-Z]")) - sub("^\\.","",out) - endline() -} diff --git a/thirdparty/libarchive/doc/mdoc2wiki.awk b/thirdparty/libarchive/doc/mdoc2wiki.awk deleted file mode 100755 index eb89ba090..000000000 --- a/thirdparty/libarchive/doc/mdoc2wiki.awk +++ /dev/null @@ -1,488 +0,0 @@ -#!/usr/bin/awk -# -# Copyright (c) 2003 Peter Stuge -# -# Permission to use, copy, modify, and distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -# Dramatically overhauled by Tim Kientzle. This version almost -# handles library-style pages with Fn, Ft, etc commands. Still -# a lot of problems... - -BEGIN { - displaylines = 0 - listdepth = 0 - trailer = "" - out = "" - sep = "" - nextsep = " " - spaces = " " - - NORMAL_STATE = 0 - PRETAG_STATE = 1 - STATE = NORMAL_STATE -} - -# Add a word with appropriate preceding whitespace -# Maintain a short queue of the expected upcoming word separators. -function add(str) { - out=out sep str - sep = nextsep - nextsep = " " -} - -# Add a word with no following whitespace -# Use for opening punctuation such as '(' -function addopen(str) { - add(str) - sep = "" -} - -# Add a word with no preceding whitespace -# Use for closing punctuation such as ')' or '.' -function addclose(str) { - sep = "" - add(str) -} - -# Add a word with no space before or after -# Use for separating punctuation such as '=' -function addpunct(str) { - sep = "" - add(str) - sep = "" -} - -# Emit the current line so far -function endline() { - addclose(trailer) - trailer = "" - if(length(out) > 0) { - if (STATE == PRETAG_STATE) { - print out - } else { - print out " " - } - out="" - } - if(displaylines > 0) { - displaylines = displaylines - 1 - if (displaylines == 0) - dispend() - } - # First word on next line has no preceding whitespace - sep = "" -} - -function linecmd(cmd) { - endline() - add(cmd) - endline() -} - -function breakline() { - linecmd("
") -} - -function crossref(name, sect, other) { - if (name == "cpio" && sect == 1) { - n = "ManPageBsdcpio1" - } else if (name == "cpio" && sect == 5) { - n = "ManPageCpio5" - } else if (name == "mtree" && sect == 5) { - n = "ManPageMtree5" - } else if (name == "tar" && sect == 1) { - n = "ManPageBsdtar1" - } else if (name == "tar" && sect == 5) { - n = "ManPageTar5" - } else if (!match(name, "^archive") && !match(name, "^libarchive")) { - n = name "(" sect ")|http://www.freebsd.org/cgi/man.cgi?query=" name "&sektion=" sect - } else { - n = "ManPage" - numbits = split(name, namebits, "[_-]") - for (i = 1; i <= numbits; ++i) { - p = namebits[i] - n = n toupper(substr(p, 0, 1)) substr(p, 2) - } - n = n sect - } - n = "[[" n "]]" - if (length other > 0) - n = n other - return n -} - -# Start an indented display -function dispstart() { - endline() - print "```text" -} - -# End an indented display -function dispend() { - endline() - print "```" -} - -# Collect rest of input line -function wtail() { - retval="" - while(w 0) { - sub("^[ \t]*", "", l) - if (match(l, "^\"")) { - l = substr(l, 2) - o = index(l, "\"") - if (o > 0) { - w = substr(l, 1, o-1) - l = substr(l, o+1) - dest[n++] = w - } else { - dest[n++] = l - l = "" - } - } else { - o = match(l, "[ \t]") - if (o > 0) { - w = substr(l, 1, o-1) - l = substr(l, o+1) - dest[n++] = w - } else { - dest[n++] = l - l = "" - } - } - } - return n-1 -} - -! /^\./ { - out = $0 - endline() - next -} - -/^\.\\"/ { next } - -{ - gsub("\\\\e", "\\") - sub("^\\.","") - nwords=splitwords($0, words) - # TODO: Instead of iterating 'w' over the array, have a separate - # function that returns 'next word' and use that. This will allow - # proper handling of double-quoted arguments as well. - for(w=1;w<=nwords;w++) { - if(match(words[w],"^Li$")) { # Literal; rest of line is unformatted - dispstart() - displaylines = 1 - } else if(match(words[w],"^Dl$")) { # Display literal - dispstart() - displaylines = 1 - } else if(match(words[w],"^Bd$")) { # Begin display - STATE = PRETAG_STATE - if(match(words[w+1],"-literal")) { - dispstart() - displaylines=10000 - w=nwords - } - } else if(match(words[w],"^Ed$")) { # End display - displaylines = 0 - dispend() - STATE = NORMAL_STATE - } else if(match(words[w],"^Ns$")) { # Suppress space before next word - sep="" - } else if(match(words[w],"^No$")) { # Normal text - add(words[++w]) - } else if(match(words[w],"^Dq$")) { # Quote - addopen("\"") - add(words[++w]) - while(w[") - } else if(match(words[w],"^Oc$")) { - addclose("]") - } else if(match(words[w],"^Ao$")) { - addopen("<") - } else if(match(words[w],"^Ac$")) { - addclose(">") - } else if(match(words[w],"^Dd$")) { - date=wtail() - next - } else if(match(words[w],"^Dt$")) { - id=words[++w] "(" words[++w] ")" - next - } else if(match(words[w],"^Ox$")) { - add("OpenBSD") - } else if(match(words[w],"^Fx$")) { - add("FreeBSD") - } else if(match(words[w],"^Bx$")) { - add("BSD") - } else if(match(words[w],"^Nx$")) { - add("NetBSD") - } else if(match(words[w],"^St$")) { - if (match(words[w+1], "^-p1003.1$")) { - w++ - add("IEEE Std 1003.1 (``POSIX.1'')") - } else if(match(words[w+1], "^-p1003.1-96$")) { - w++ - add("ISO/IEC 9945-1:1996 (``POSIX.1'')") - } else if(match(words[w+1], "^-p1003.1-88$")) { - w++ - add("IEEE Std 1003.1-1988 (``POSIX.1'')") - } else if(match(words[w+1], "^-p1003.1-2001$")) { - w++ - add("IEEE Std 1003.1-2001 (``POSIX.1'')") - } else if(match(words[w+1], "^-susv2$")) { - w++ - add("Version 2 of the Single UNIX Specification (``SUSv2'')") - } - } else if(match(words[w],"^Ex$")) { - if (match(words[w+1], "^-std$")) { - w++ - add("The '''" name "''' utility exits 0 on success, and >0 if an error occurs.") - } - } else if(match(words[w],"^Os$")) { - add(id " manual page") - } else if(match(words[w],"^Sh$")) { - section=wtail() - linecmd("== " section " ==") - } else if(match(words[w],"^Xr$")) { - add(crossref(words[w+1], words[w+2], words[w+3])) - w = w + 3 - } else if(match(words[w],"^Nm$")) { - if(match(section,"SYNOPSIS")) - breakline() - if(w >= nwords) - n=name - else if (match(words[w+1], "^[A-Z][a-z]$")) - n=name - else if (match(words[w+1], "^[.,;:]$")) - n=name - else { - n=words[++w] - if(!length(name)) - name=n - } - if(!length(n)) - n=name - if (displaylines == 0) - add("'''" n "'''") - else - add(n) - } else if(match(words[w],"^Nd$")) { - add("- " wtail()) - } else if(match(words[w],"^Fl$")) { - addopen("-") - } else if(match(words[w],"^Ar$")) { - if(w==nwords) - add("''file ...''") - else { - ++w - gsub("<", "\\<", words[w]) - if (displaylines > 0) - add(words[w]) - else - add("''" words[w] "''") - } - } else if(match(words[w],"^Cm$")) { - ++w - if (displaylines == 0) { - add("'''" words[w] "'''") - } else - add(words[w]) - } else if(match(words[w],"^Op$")) { - addopen("[") - option=1 - trailer="]" trailer - } else if(match(words[w],"^Pp$")) { - ++w - endline() - print "" - } else if(match(words[w],"^An$")) { - if (match(words[w+1],"-nosplit")) - ++w - endline() - } else if(match(words[w],"^Ss$")) { - add("===") - trailer="===" - } else if(match(words[w],"^Ft$")) { - if (match(section, "SYNOPSIS")) { - breakline() - } - l = wtail() - add("''" l "''") - if (match(section, "SYNOPSIS")) { - breakline() - } - } else if(match(words[w],"^Fn$")) { - ++w - F = "'''" words[w] "'''(" - Fsep = "" - while(w#include <" words[w] ">'''") - } else if(match(words[w],"^Pa$")) { - w++ -# if(match(words[w],"^\\.")) -# add("\\&") - if (displaylines == 0) - add("''" words[w] "''") - else - add(words[w]) - } else if(match(words[w],"^Dv$")) { - linecmd() - } else if(match(words[w],"^Em|Ev$")) { - add(".IR") - } else if(match(words[w],"^Pq$")) { - addopen("(") - trailer=")" trailer - } else if(match(words[w],"^Aq$")) { - addopen(" <") - trailer=">" trailer - } else if(match(words[w],"^Brq$")) { - addopen("{") - trailer="}" trailer - } else if(match(words[w],"^S[xy]$")) { - add(".B " wtail()) - } else if(match(words[w],"^Tn$")) { - n=wtail() - add("'''" n "'''") - } else if(match(words[w],"^Ic$")) { - add("''") - trailer="''" trailer - } else if(match(words[w],"^Bl$")) { - ++listdepth - listnext[listdepth]="" - if(match(words[w+1],"-bullet")) { - optlist[listdepth]=1 - addopen("
    ") - listclose[listdepth]="
" - } else if(match(words[w+1],"-enum")) { - optlist[listdepth]=2 - enum=0 - addopen("
    ") - listclose[listdepth]="
" - } else if(match(words[w+1],"-tag")) { - optlist[listdepth]=3 - addopen("
") - listclose[listdepth]="
" - } else if(match(words[w+1],"-item")) { - optlist[listdepth]=4 - addopen("
    ") - listclose[listdepth]="
" - } - w=nwords - } else if(match(words[w],"^El$")) { - addclose(listnext[listdepth]) - addclose(listclose[listdepth]) - listclose[listdepth]="" - listdepth-- - } else if(match(words[w],"^It$")) { - addclose(listnext[listdepth]) - if(optlist[listdepth]==1) { - addpunct("
  • ") - listnext[listdepth] = "
  • " - } else if(optlist[listdepth]==2) { - addpunct("
  • ") - listnext[listdepth] = "
  • " - } else if(optlist[listdepth]==3) { - addpunct("
    ") - listnext[listdepth] = "
    " - if(match(words[w+1],"^Xo$")) { - # Suppress trailer - w++ - } else if(match(words[w+1],"^Pa$|^Ev$")) { - addopen("'''") - w++ - add(words[++w] "'''") - trailer = listnext[listdepth] "
    " trailer - listnext[listdepth] = "
    " - } else { - trailer = listnext[listdepth] "
    " trailer - listnext[listdepth] = "
    " - } - } else if(optlist[listdepth]==4) { - addpunct("
  • ") - listnext[listdepth] = "
  • " - } - } else if(match(words[w], "^Vt$")) { - w++ - add("''" words[w] "''") - } else if(match(words[w],"^Xo$")) { - # TODO: Figure out how to handle this - } else if(match(words[w],"^Xc$")) { - # TODO: Figure out how to handle this - if (optlist[listdepth] == 3) { - addclose(listnext[listdepth]) - addopen("
    ") - listnext[listdepth] = "
    " - } - } else if(match(words[w],"^[=]$")) { - addpunct(words[w]) - } else if(match(words[w],"^[[{(]$")) { - addopen(words[w]) - } else if(match(words[w],"^[\\])}.,;:]$")) { - addclose(words[w]) - } else { - sub("\\\\&", "", words[w]) - add(words[w]) - } - } - if(match(out,"^\\.[^a-zA-Z]")) - sub("^\\.","",out) - endline() -} diff --git a/thirdparty/libarchive/doc/pdf/.ignore_me b/thirdparty/libarchive/doc/pdf/.ignore_me deleted file mode 100644 index d285484d4..000000000 --- a/thirdparty/libarchive/doc/pdf/.ignore_me +++ /dev/null @@ -1,2 +0,0 @@ -*** PLEASE DO NOT DELETE THIS FILE! *** -This file is used to track an otherwise empty directory in git. diff --git a/thirdparty/libarchive/doc/pdf/Makefile b/thirdparty/libarchive/doc/pdf/Makefile deleted file mode 100644 index 48a53116b..000000000 --- a/thirdparty/libarchive/doc/pdf/Makefile +++ /dev/null @@ -1,133 +0,0 @@ - -default: all - - -archive_entry.3.pdf: ../../libarchive/archive_entry.3 - groff -mdoc -T ps ../../libarchive/archive_entry.3 | ps2pdf - - > archive_entry.3.pdf - -archive_entry_acl.3.pdf: ../../libarchive/archive_entry_acl.3 - groff -mdoc -T ps ../../libarchive/archive_entry_acl.3 | ps2pdf - - > archive_entry_acl.3.pdf - -archive_entry_linkify.3.pdf: ../../libarchive/archive_entry_linkify.3 - groff -mdoc -T ps ../../libarchive/archive_entry_linkify.3 | ps2pdf - - > archive_entry_linkify.3.pdf - -archive_entry_misc.3.pdf: ../../libarchive/archive_entry_misc.3 - groff -mdoc -T ps ../../libarchive/archive_entry_misc.3 | ps2pdf - - > archive_entry_misc.3.pdf - -archive_entry_paths.3.pdf: ../../libarchive/archive_entry_paths.3 - groff -mdoc -T ps ../../libarchive/archive_entry_paths.3 | ps2pdf - - > archive_entry_paths.3.pdf - -archive_entry_perms.3.pdf: ../../libarchive/archive_entry_perms.3 - groff -mdoc -T ps ../../libarchive/archive_entry_perms.3 | ps2pdf - - > archive_entry_perms.3.pdf - -archive_entry_stat.3.pdf: ../../libarchive/archive_entry_stat.3 - groff -mdoc -T ps ../../libarchive/archive_entry_stat.3 | ps2pdf - - > archive_entry_stat.3.pdf - -archive_entry_time.3.pdf: ../../libarchive/archive_entry_time.3 - groff -mdoc -T ps ../../libarchive/archive_entry_time.3 | ps2pdf - - > archive_entry_time.3.pdf - -archive_read.3.pdf: ../../libarchive/archive_read.3 - groff -mdoc -T ps ../../libarchive/archive_read.3 | ps2pdf - - > archive_read.3.pdf - -archive_read_add_passphrase.3.pdf: ../../libarchive/archive_read_add_passphrase.3 - groff -mdoc -T ps ../../libarchive/archive_read_add_passphrase.3 | ps2pdf - - > archive_read_add_passphrase.3.pdf - -archive_read_data.3.pdf: ../../libarchive/archive_read_data.3 - groff -mdoc -T ps ../../libarchive/archive_read_data.3 | ps2pdf - - > archive_read_data.3.pdf - -archive_read_disk.3.pdf: ../../libarchive/archive_read_disk.3 - groff -mdoc -T ps ../../libarchive/archive_read_disk.3 | ps2pdf - - > archive_read_disk.3.pdf - -archive_read_extract.3.pdf: ../../libarchive/archive_read_extract.3 - groff -mdoc -T ps ../../libarchive/archive_read_extract.3 | ps2pdf - - > archive_read_extract.3.pdf - -archive_read_filter.3.pdf: ../../libarchive/archive_read_filter.3 - groff -mdoc -T ps ../../libarchive/archive_read_filter.3 | ps2pdf - - > archive_read_filter.3.pdf - -archive_read_format.3.pdf: ../../libarchive/archive_read_format.3 - groff -mdoc -T ps ../../libarchive/archive_read_format.3 | ps2pdf - - > archive_read_format.3.pdf - -archive_read_free.3.pdf: ../../libarchive/archive_read_free.3 - groff -mdoc -T ps ../../libarchive/archive_read_free.3 | ps2pdf - - > archive_read_free.3.pdf - -archive_read_header.3.pdf: ../../libarchive/archive_read_header.3 - groff -mdoc -T ps ../../libarchive/archive_read_header.3 | ps2pdf - - > archive_read_header.3.pdf - -archive_read_new.3.pdf: ../../libarchive/archive_read_new.3 - groff -mdoc -T ps ../../libarchive/archive_read_new.3 | ps2pdf - - > archive_read_new.3.pdf - -archive_read_open.3.pdf: ../../libarchive/archive_read_open.3 - groff -mdoc -T ps ../../libarchive/archive_read_open.3 | ps2pdf - - > archive_read_open.3.pdf - -archive_read_set_options.3.pdf: ../../libarchive/archive_read_set_options.3 - groff -mdoc -T ps ../../libarchive/archive_read_set_options.3 | ps2pdf - - > archive_read_set_options.3.pdf - -archive_util.3.pdf: ../../libarchive/archive_util.3 - groff -mdoc -T ps ../../libarchive/archive_util.3 | ps2pdf - - > archive_util.3.pdf - -archive_write.3.pdf: ../../libarchive/archive_write.3 - groff -mdoc -T ps ../../libarchive/archive_write.3 | ps2pdf - - > archive_write.3.pdf - -archive_write_blocksize.3.pdf: ../../libarchive/archive_write_blocksize.3 - groff -mdoc -T ps ../../libarchive/archive_write_blocksize.3 | ps2pdf - - > archive_write_blocksize.3.pdf - -archive_write_data.3.pdf: ../../libarchive/archive_write_data.3 - groff -mdoc -T ps ../../libarchive/archive_write_data.3 | ps2pdf - - > archive_write_data.3.pdf - -archive_write_disk.3.pdf: ../../libarchive/archive_write_disk.3 - groff -mdoc -T ps ../../libarchive/archive_write_disk.3 | ps2pdf - - > archive_write_disk.3.pdf - -archive_write_filter.3.pdf: ../../libarchive/archive_write_filter.3 - groff -mdoc -T ps ../../libarchive/archive_write_filter.3 | ps2pdf - - > archive_write_filter.3.pdf - -archive_write_finish_entry.3.pdf: ../../libarchive/archive_write_finish_entry.3 - groff -mdoc -T ps ../../libarchive/archive_write_finish_entry.3 | ps2pdf - - > archive_write_finish_entry.3.pdf - -archive_write_format.3.pdf: ../../libarchive/archive_write_format.3 - groff -mdoc -T ps ../../libarchive/archive_write_format.3 | ps2pdf - - > archive_write_format.3.pdf - -archive_write_free.3.pdf: ../../libarchive/archive_write_free.3 - groff -mdoc -T ps ../../libarchive/archive_write_free.3 | ps2pdf - - > archive_write_free.3.pdf - -archive_write_header.3.pdf: ../../libarchive/archive_write_header.3 - groff -mdoc -T ps ../../libarchive/archive_write_header.3 | ps2pdf - - > archive_write_header.3.pdf - -archive_write_new.3.pdf: ../../libarchive/archive_write_new.3 - groff -mdoc -T ps ../../libarchive/archive_write_new.3 | ps2pdf - - > archive_write_new.3.pdf - -archive_write_open.3.pdf: ../../libarchive/archive_write_open.3 - groff -mdoc -T ps ../../libarchive/archive_write_open.3 | ps2pdf - - > archive_write_open.3.pdf - -archive_write_set_options.3.pdf: ../../libarchive/archive_write_set_options.3 - groff -mdoc -T ps ../../libarchive/archive_write_set_options.3 | ps2pdf - - > archive_write_set_options.3.pdf - -archive_write_set_passphrase.3.pdf: ../../libarchive/archive_write_set_passphrase.3 - groff -mdoc -T ps ../../libarchive/archive_write_set_passphrase.3 | ps2pdf - - > archive_write_set_passphrase.3.pdf - -cpio.5.pdf: ../../libarchive/cpio.5 - groff -mdoc -T ps ../../libarchive/cpio.5 | ps2pdf - - > cpio.5.pdf - -libarchive.3.pdf: ../../libarchive/libarchive.3 - groff -mdoc -T ps ../../libarchive/libarchive.3 | ps2pdf - - > libarchive.3.pdf - -libarchive_changes.3.pdf: ../../libarchive/libarchive_changes.3 - groff -mdoc -T ps ../../libarchive/libarchive_changes.3 | ps2pdf - - > libarchive_changes.3.pdf - -libarchive-formats.5.pdf: ../../libarchive/libarchive-formats.5 - groff -mdoc -T ps ../../libarchive/libarchive-formats.5 | ps2pdf - - > libarchive-formats.5.pdf - -libarchive_internals.3.pdf: ../../libarchive/libarchive_internals.3 - groff -mdoc -T ps ../../libarchive/libarchive_internals.3 | ps2pdf - - > libarchive_internals.3.pdf - -mtree.5.pdf: ../../libarchive/mtree.5 - groff -mdoc -T ps ../../libarchive/mtree.5 | ps2pdf - - > mtree.5.pdf - -tar.5.pdf: ../../libarchive/tar.5 - groff -mdoc -T ps ../../libarchive/tar.5 | ps2pdf - - > tar.5.pdf - -bsdtar.1.pdf: ../../tar/bsdtar.1 - groff -mdoc -T ps ../../tar/bsdtar.1 | ps2pdf - - > bsdtar.1.pdf - -bsdcpio.1.pdf: ../../cpio/bsdcpio.1 - groff -mdoc -T ps ../../cpio/bsdcpio.1 | ps2pdf - - > bsdcpio.1.pdf -all: archive_entry.3.pdf archive_entry_acl.3.pdf archive_entry_linkify.3.pdf archive_entry_misc.3.pdf archive_entry_paths.3.pdf archive_entry_perms.3.pdf archive_entry_stat.3.pdf archive_entry_time.3.pdf archive_read.3.pdf archive_read_add_passphrase.3.pdf archive_read_data.3.pdf archive_read_disk.3.pdf archive_read_extract.3.pdf archive_read_filter.3.pdf archive_read_format.3.pdf archive_read_free.3.pdf archive_read_header.3.pdf archive_read_new.3.pdf archive_read_open.3.pdf archive_read_set_options.3.pdf archive_util.3.pdf archive_write.3.pdf archive_write_blocksize.3.pdf archive_write_data.3.pdf archive_write_disk.3.pdf archive_write_filter.3.pdf archive_write_finish_entry.3.pdf archive_write_format.3.pdf archive_write_free.3.pdf archive_write_header.3.pdf archive_write_new.3.pdf archive_write_open.3.pdf archive_write_set_options.3.pdf archive_write_set_passphrase.3.pdf cpio.5.pdf libarchive.3.pdf libarchive_changes.3.pdf libarchive-formats.5.pdf libarchive_internals.3.pdf mtree.5.pdf tar.5.pdf bsdtar.1.pdf bsdcpio.1.pdf diff --git a/thirdparty/libarchive/doc/pdf/archive_entry.3.pdf b/thirdparty/libarchive/doc/pdf/archive_entry.3.pdf deleted file mode 100644 index 77957c0bb..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_entry.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cc2a52f8f73c7e28acc8b596bbf2bc368fb7070d1543a3190ed91d833706d235 -size 28595 diff --git a/thirdparty/libarchive/doc/pdf/archive_entry_acl.3.pdf b/thirdparty/libarchive/doc/pdf/archive_entry_acl.3.pdf deleted file mode 100644 index 86cef7b1b..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_entry_acl.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f438de9fb55ae8fe31a95bf4ed56471798ef55991ffab0a54b2cd97e962636ad -size 37978 diff --git a/thirdparty/libarchive/doc/pdf/archive_entry_linkify.3.pdf b/thirdparty/libarchive/doc/pdf/archive_entry_linkify.3.pdf deleted file mode 100644 index eb5dcb907..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_entry_linkify.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d2acf2f897e6ab52b7fbd64a646513d2aab03f83d5b42c79b0f67c4b1e615ccc -size 27889 diff --git a/thirdparty/libarchive/doc/pdf/archive_entry_misc.3.pdf b/thirdparty/libarchive/doc/pdf/archive_entry_misc.3.pdf deleted file mode 100644 index c202b26d5..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_entry_misc.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ff0daf412a05ba00616b311e5ef78d6285554ccb1bea9bd22b2273b2111580af -size 21415 diff --git a/thirdparty/libarchive/doc/pdf/archive_entry_paths.3.pdf b/thirdparty/libarchive/doc/pdf/archive_entry_paths.3.pdf deleted file mode 100644 index 174818e43..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_entry_paths.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b77bdcf7874d9855b07a0cb7d2a844159ec9e42ecf916f7fe79016d036aaae40 -size 24684 diff --git a/thirdparty/libarchive/doc/pdf/archive_entry_perms.3.pdf b/thirdparty/libarchive/doc/pdf/archive_entry_perms.3.pdf deleted file mode 100644 index 5bb5dc095..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_entry_perms.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:20122e70a73c12bee616d41ee499e48263648983d9d1c56a45e2e2ce594a9e9d -size 29273 diff --git a/thirdparty/libarchive/doc/pdf/archive_entry_stat.3.pdf b/thirdparty/libarchive/doc/pdf/archive_entry_stat.3.pdf deleted file mode 100644 index 9f2b68af3..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_entry_stat.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8493a65ce2c60e270a2aa17dbfde11d3ed835955a024bf9cbd0bb56aa9fcdf66 -size 32743 diff --git a/thirdparty/libarchive/doc/pdf/archive_entry_time.3.pdf b/thirdparty/libarchive/doc/pdf/archive_entry_time.3.pdf deleted file mode 100644 index 16a4aab88..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_entry_time.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:38c3feec364ad4a0aad1eded50ee71644066557b9c70d31200c1476202544b20 -size 22964 diff --git a/thirdparty/libarchive/doc/pdf/archive_read.3.pdf b/thirdparty/libarchive/doc/pdf/archive_read.3.pdf deleted file mode 100644 index 4dea09b9b..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_read.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1d60a2fadac9a4b9d919771a9e40d7fe42d239f1d2d6027bb8cd19a98c71d137 -size 32415 diff --git a/thirdparty/libarchive/doc/pdf/archive_read_add_passphrase.3.pdf b/thirdparty/libarchive/doc/pdf/archive_read_add_passphrase.3.pdf deleted file mode 100644 index 3548a9d4a..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_read_add_passphrase.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c56f7eedc3faa92063e55c31ad6840827ae2bec84163aa8038ab7c730d19c08b -size 21911 diff --git a/thirdparty/libarchive/doc/pdf/archive_read_data.3.pdf b/thirdparty/libarchive/doc/pdf/archive_read_data.3.pdf deleted file mode 100644 index e6b5b6002..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_read_data.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e254a744d36e653b559b30cce957882939526b1d5edb8ef8bb2fff3d9904cd65 -size 25861 diff --git a/thirdparty/libarchive/doc/pdf/archive_read_disk.3.pdf b/thirdparty/libarchive/doc/pdf/archive_read_disk.3.pdf deleted file mode 100644 index 692be956f..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_read_disk.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:241362b3f3853e9d53e51c793e1aa5da2f6ab36546b7d07f54b2b10c71094dd2 -size 43353 diff --git a/thirdparty/libarchive/doc/pdf/archive_read_extract.3.pdf b/thirdparty/libarchive/doc/pdf/archive_read_extract.3.pdf deleted file mode 100644 index 8f74f1499..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_read_extract.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e06d02c7ffaad498f33952c8db0737c7264892bc5ea56c053d5218b343f70cd5 -size 28161 diff --git a/thirdparty/libarchive/doc/pdf/archive_read_filter.3.pdf b/thirdparty/libarchive/doc/pdf/archive_read_filter.3.pdf deleted file mode 100644 index 48cd49e84..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_read_filter.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:237efb5fc19b1f84f9a26c1b20e3dee0cf762d0b12e7964d8a724d7a82898a89 -size 25796 diff --git a/thirdparty/libarchive/doc/pdf/archive_read_format.3.pdf b/thirdparty/libarchive/doc/pdf/archive_read_format.3.pdf deleted file mode 100644 index 479f9002d..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_read_format.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2c311bbb71d31e976b03ab1379ca0f72a0e2c52d8072459cc60a2b45ecbc0632 -size 26763 diff --git a/thirdparty/libarchive/doc/pdf/archive_read_free.3.pdf b/thirdparty/libarchive/doc/pdf/archive_read_free.3.pdf deleted file mode 100644 index 7578dd4eb..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_read_free.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:56c0d0f650d4517f208ab7368c832abb51454bbb7289d37a3c5fef24fa89201b -size 22494 diff --git a/thirdparty/libarchive/doc/pdf/archive_read_header.3.pdf b/thirdparty/libarchive/doc/pdf/archive_read_header.3.pdf deleted file mode 100644 index 3f29edb2e..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_read_header.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0e622da692a1eaf008b4f2a7df0cbbbf6da636c95a4c9c2dbb2053b0ae3761ae -size 22670 diff --git a/thirdparty/libarchive/doc/pdf/archive_read_new.3.pdf b/thirdparty/libarchive/doc/pdf/archive_read_new.3.pdf deleted file mode 100644 index f4a7eb193..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_read_new.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e1a0f02593d8b08f57a9d5e03835a0f47ea33b2f4ac94f3cf951684f78580fd2 -size 19896 diff --git a/thirdparty/libarchive/doc/pdf/archive_read_open.3.pdf b/thirdparty/libarchive/doc/pdf/archive_read_open.3.pdf deleted file mode 100644 index 478c00acb..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_read_open.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:772d356baeada267501d61a8dc66101a10d8e1516dc2df11c95cf03719e1c2c9 -size 29728 diff --git a/thirdparty/libarchive/doc/pdf/archive_read_set_options.3.pdf b/thirdparty/libarchive/doc/pdf/archive_read_set_options.3.pdf deleted file mode 100644 index e2706d66f..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_read_set_options.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9c85d0dd464917fa46b643fa67eab74173ef985dcb7734c8c24d52237a71a36b -size 28436 diff --git a/thirdparty/libarchive/doc/pdf/archive_util.3.pdf b/thirdparty/libarchive/doc/pdf/archive_util.3.pdf deleted file mode 100644 index 086b3cf17..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_util.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e9e48359e69ac69acceef6b71f9af2a4eac1cab801af1567dce1ffe77f7de970 -size 28528 diff --git a/thirdparty/libarchive/doc/pdf/archive_write.3.pdf b/thirdparty/libarchive/doc/pdf/archive_write.3.pdf deleted file mode 100644 index 6a1dc5397..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_write.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:abb200b7b90bae0856fab0bcedaf4eb60828d9fc9e7e9146043765b51d527686 -size 37262 diff --git a/thirdparty/libarchive/doc/pdf/archive_write_blocksize.3.pdf b/thirdparty/libarchive/doc/pdf/archive_write_blocksize.3.pdf deleted file mode 100644 index e3e853d91..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_write_blocksize.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8a18b5301373c62ac0c894db7b29865e60259fcaef03ccc19e5f596c11ad1435 -size 25551 diff --git a/thirdparty/libarchive/doc/pdf/archive_write_data.3.pdf b/thirdparty/libarchive/doc/pdf/archive_write_data.3.pdf deleted file mode 100644 index 1424392c2..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_write_data.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4aa4115cb60fc7743067038e0c2f48744fa53e417d1358f2cb278dad0f3ff693 -size 22835 diff --git a/thirdparty/libarchive/doc/pdf/archive_write_disk.3.pdf b/thirdparty/libarchive/doc/pdf/archive_write_disk.3.pdf deleted file mode 100644 index a37e129c7..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_write_disk.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:021271f436c2bf312214d7a991c0aebf229921cdca33f5331902e25d81d4f71a -size 40007 diff --git a/thirdparty/libarchive/doc/pdf/archive_write_filter.3.pdf b/thirdparty/libarchive/doc/pdf/archive_write_filter.3.pdf deleted file mode 100644 index 7e829cd65..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_write_filter.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8f09c878ef5c55608a1d8553a351017207a3688664f51c7ec0000e5c263148ea -size 24619 diff --git a/thirdparty/libarchive/doc/pdf/archive_write_finish_entry.3.pdf b/thirdparty/libarchive/doc/pdf/archive_write_finish_entry.3.pdf deleted file mode 100644 index 599b9714c..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_write_finish_entry.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ab0c2808e5f01dd8c2ba4ce6bbf08b36789b864276774f8cdf3944d57a58b7b8 -size 23532 diff --git a/thirdparty/libarchive/doc/pdf/archive_write_format.3.pdf b/thirdparty/libarchive/doc/pdf/archive_write_format.3.pdf deleted file mode 100644 index 88eae3c6b..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_write_format.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2b2c6439a16a5aec77eab306114899155825e36c6df5d594f8178f5d02471433 -size 26907 diff --git a/thirdparty/libarchive/doc/pdf/archive_write_free.3.pdf b/thirdparty/libarchive/doc/pdf/archive_write_free.3.pdf deleted file mode 100644 index a9cef75c7..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_write_free.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0d082ce2aecd080ecd45a363adfdac9f6e81a7831e9d740194af99c72ce93438 -size 22322 diff --git a/thirdparty/libarchive/doc/pdf/archive_write_header.3.pdf b/thirdparty/libarchive/doc/pdf/archive_write_header.3.pdf deleted file mode 100644 index 716bda896..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_write_header.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f13508f69f5aecb8af0bf93fbd41f5d7503861e6cdd48891e3530d60dbac870c -size 22189 diff --git a/thirdparty/libarchive/doc/pdf/archive_write_new.3.pdf b/thirdparty/libarchive/doc/pdf/archive_write_new.3.pdf deleted file mode 100644 index 92d2ae376..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_write_new.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:21d7227d2cd0aa1afebaef9beb4934a654f7974cb024a5ddaa2d9ba9eee3afc6 -size 19877 diff --git a/thirdparty/libarchive/doc/pdf/archive_write_open.3.pdf b/thirdparty/libarchive/doc/pdf/archive_write_open.3.pdf deleted file mode 100644 index 2dd366ccc..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_write_open.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:603b70b2f7540c4e2ad4558ee10bd4b97b9dc4b7593072d85f2579b61c93dbf0 -size 33473 diff --git a/thirdparty/libarchive/doc/pdf/archive_write_set_options.3.pdf b/thirdparty/libarchive/doc/pdf/archive_write_set_options.3.pdf deleted file mode 100644 index 1c0fffc21..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_write_set_options.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b8c45c8997912ee51221a61b650e164a5510f26170346e22448a44222a3d6d1c -size 46684 diff --git a/thirdparty/libarchive/doc/pdf/archive_write_set_passphrase.3.pdf b/thirdparty/libarchive/doc/pdf/archive_write_set_passphrase.3.pdf deleted file mode 100644 index 929df6846..000000000 --- a/thirdparty/libarchive/doc/pdf/archive_write_set_passphrase.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1ac033f331a52c692283e376d7a2f69e70b52636e100ae7e8e043cf0bd20c6c4 -size 22154 diff --git a/thirdparty/libarchive/doc/pdf/bsdcpio.1.pdf b/thirdparty/libarchive/doc/pdf/bsdcpio.1.pdf deleted file mode 100644 index f24ef461b..000000000 --- a/thirdparty/libarchive/doc/pdf/bsdcpio.1.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:312afa2c92ee3215e4f094cac2692da2127601c08c7f0c3a01b81674f7388de2 -size 38873 diff --git a/thirdparty/libarchive/doc/pdf/bsdtar.1.pdf b/thirdparty/libarchive/doc/pdf/bsdtar.1.pdf deleted file mode 100644 index d1dfe829c..000000000 --- a/thirdparty/libarchive/doc/pdf/bsdtar.1.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:da6e4ec3281f2e51c54753538770841cbe225e22ab60f74f63977ce9268d5758 -size 73684 diff --git a/thirdparty/libarchive/doc/pdf/cpio.5.pdf b/thirdparty/libarchive/doc/pdf/cpio.5.pdf deleted file mode 100644 index ecb85e6a5..000000000 --- a/thirdparty/libarchive/doc/pdf/cpio.5.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:145af7ef3fcbbc47a9cb5815baea1387cb1e16851fcc4387b2ec77cc314453cd -size 39336 diff --git a/thirdparty/libarchive/doc/pdf/libarchive-formats.5.pdf b/thirdparty/libarchive/doc/pdf/libarchive-formats.5.pdf deleted file mode 100644 index 480c22ac1..000000000 --- a/thirdparty/libarchive/doc/pdf/libarchive-formats.5.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d6e6ebf92b3c5905bb9c52e2b5f458608c68a2cb281c706841f728c2a7c8219a -size 42277 diff --git a/thirdparty/libarchive/doc/pdf/libarchive.3.pdf b/thirdparty/libarchive/doc/pdf/libarchive.3.pdf deleted file mode 100644 index abc172ece..000000000 --- a/thirdparty/libarchive/doc/pdf/libarchive.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2e3b8b05c34a573e655f06918a6daa686c3a3cdbcafbecbae961dd67e4411ef6 -size 31386 diff --git a/thirdparty/libarchive/doc/pdf/libarchive_changes.3.pdf b/thirdparty/libarchive/doc/pdf/libarchive_changes.3.pdf deleted file mode 100644 index 9766077e1..000000000 --- a/thirdparty/libarchive/doc/pdf/libarchive_changes.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:59093fff54def28063279d43c40d4e6a959b6686441606b027842a50290a0b78 -size 35087 diff --git a/thirdparty/libarchive/doc/pdf/libarchive_internals.3.pdf b/thirdparty/libarchive/doc/pdf/libarchive_internals.3.pdf deleted file mode 100644 index 7480daa0a..000000000 --- a/thirdparty/libarchive/doc/pdf/libarchive_internals.3.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0fd1278c344bc74f0f7bb1eb01ba094e2d309236f3ee98c780879b5db9028027 -size 39375 diff --git a/thirdparty/libarchive/doc/pdf/mtree.5.pdf b/thirdparty/libarchive/doc/pdf/mtree.5.pdf deleted file mode 100644 index 601b120a6..000000000 --- a/thirdparty/libarchive/doc/pdf/mtree.5.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b4b3dbfd2c09dc461e36fa15b656121b104690ef3377000955751cd96c620523 -size 32055 diff --git a/thirdparty/libarchive/doc/pdf/tar.5.pdf b/thirdparty/libarchive/doc/pdf/tar.5.pdf deleted file mode 100644 index 713ba1a44..000000000 --- a/thirdparty/libarchive/doc/pdf/tar.5.pdf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ce7ec68ff561e0bec2a51d0b02fd09f9c7c17892bba02b7f99d124e2735996c1 -size 68229 diff --git a/thirdparty/libarchive/doc/text/.ignore_me b/thirdparty/libarchive/doc/text/.ignore_me deleted file mode 100644 index d285484d4..000000000 --- a/thirdparty/libarchive/doc/text/.ignore_me +++ /dev/null @@ -1,2 +0,0 @@ -*** PLEASE DO NOT DELETE THIS FILE! *** -This file is used to track an otherwise empty directory in git. diff --git a/thirdparty/libarchive/doc/text/Makefile b/thirdparty/libarchive/doc/text/Makefile deleted file mode 100644 index d533e84ad..000000000 --- a/thirdparty/libarchive/doc/text/Makefile +++ /dev/null @@ -1,133 +0,0 @@ - -default: all - - -archive_entry.3.txt: ../../libarchive/archive_entry.3 - nroff -mdoc ../../libarchive/archive_entry.3 | col -b > archive_entry.3.txt - -archive_entry_acl.3.txt: ../../libarchive/archive_entry_acl.3 - nroff -mdoc ../../libarchive/archive_entry_acl.3 | col -b > archive_entry_acl.3.txt - -archive_entry_linkify.3.txt: ../../libarchive/archive_entry_linkify.3 - nroff -mdoc ../../libarchive/archive_entry_linkify.3 | col -b > archive_entry_linkify.3.txt - -archive_entry_misc.3.txt: ../../libarchive/archive_entry_misc.3 - nroff -mdoc ../../libarchive/archive_entry_misc.3 | col -b > archive_entry_misc.3.txt - -archive_entry_paths.3.txt: ../../libarchive/archive_entry_paths.3 - nroff -mdoc ../../libarchive/archive_entry_paths.3 | col -b > archive_entry_paths.3.txt - -archive_entry_perms.3.txt: ../../libarchive/archive_entry_perms.3 - nroff -mdoc ../../libarchive/archive_entry_perms.3 | col -b > archive_entry_perms.3.txt - -archive_entry_stat.3.txt: ../../libarchive/archive_entry_stat.3 - nroff -mdoc ../../libarchive/archive_entry_stat.3 | col -b > archive_entry_stat.3.txt - -archive_entry_time.3.txt: ../../libarchive/archive_entry_time.3 - nroff -mdoc ../../libarchive/archive_entry_time.3 | col -b > archive_entry_time.3.txt - -archive_read.3.txt: ../../libarchive/archive_read.3 - nroff -mdoc ../../libarchive/archive_read.3 | col -b > archive_read.3.txt - -archive_read_add_passphrase.3.txt: ../../libarchive/archive_read_add_passphrase.3 - nroff -mdoc ../../libarchive/archive_read_add_passphrase.3 | col -b > archive_read_add_passphrase.3.txt - -archive_read_data.3.txt: ../../libarchive/archive_read_data.3 - nroff -mdoc ../../libarchive/archive_read_data.3 | col -b > archive_read_data.3.txt - -archive_read_disk.3.txt: ../../libarchive/archive_read_disk.3 - nroff -mdoc ../../libarchive/archive_read_disk.3 | col -b > archive_read_disk.3.txt - -archive_read_extract.3.txt: ../../libarchive/archive_read_extract.3 - nroff -mdoc ../../libarchive/archive_read_extract.3 | col -b > archive_read_extract.3.txt - -archive_read_filter.3.txt: ../../libarchive/archive_read_filter.3 - nroff -mdoc ../../libarchive/archive_read_filter.3 | col -b > archive_read_filter.3.txt - -archive_read_format.3.txt: ../../libarchive/archive_read_format.3 - nroff -mdoc ../../libarchive/archive_read_format.3 | col -b > archive_read_format.3.txt - -archive_read_free.3.txt: ../../libarchive/archive_read_free.3 - nroff -mdoc ../../libarchive/archive_read_free.3 | col -b > archive_read_free.3.txt - -archive_read_header.3.txt: ../../libarchive/archive_read_header.3 - nroff -mdoc ../../libarchive/archive_read_header.3 | col -b > archive_read_header.3.txt - -archive_read_new.3.txt: ../../libarchive/archive_read_new.3 - nroff -mdoc ../../libarchive/archive_read_new.3 | col -b > archive_read_new.3.txt - -archive_read_open.3.txt: ../../libarchive/archive_read_open.3 - nroff -mdoc ../../libarchive/archive_read_open.3 | col -b > archive_read_open.3.txt - -archive_read_set_options.3.txt: ../../libarchive/archive_read_set_options.3 - nroff -mdoc ../../libarchive/archive_read_set_options.3 | col -b > archive_read_set_options.3.txt - -archive_util.3.txt: ../../libarchive/archive_util.3 - nroff -mdoc ../../libarchive/archive_util.3 | col -b > archive_util.3.txt - -archive_write.3.txt: ../../libarchive/archive_write.3 - nroff -mdoc ../../libarchive/archive_write.3 | col -b > archive_write.3.txt - -archive_write_blocksize.3.txt: ../../libarchive/archive_write_blocksize.3 - nroff -mdoc ../../libarchive/archive_write_blocksize.3 | col -b > archive_write_blocksize.3.txt - -archive_write_data.3.txt: ../../libarchive/archive_write_data.3 - nroff -mdoc ../../libarchive/archive_write_data.3 | col -b > archive_write_data.3.txt - -archive_write_disk.3.txt: ../../libarchive/archive_write_disk.3 - nroff -mdoc ../../libarchive/archive_write_disk.3 | col -b > archive_write_disk.3.txt - -archive_write_filter.3.txt: ../../libarchive/archive_write_filter.3 - nroff -mdoc ../../libarchive/archive_write_filter.3 | col -b > archive_write_filter.3.txt - -archive_write_finish_entry.3.txt: ../../libarchive/archive_write_finish_entry.3 - nroff -mdoc ../../libarchive/archive_write_finish_entry.3 | col -b > archive_write_finish_entry.3.txt - -archive_write_format.3.txt: ../../libarchive/archive_write_format.3 - nroff -mdoc ../../libarchive/archive_write_format.3 | col -b > archive_write_format.3.txt - -archive_write_free.3.txt: ../../libarchive/archive_write_free.3 - nroff -mdoc ../../libarchive/archive_write_free.3 | col -b > archive_write_free.3.txt - -archive_write_header.3.txt: ../../libarchive/archive_write_header.3 - nroff -mdoc ../../libarchive/archive_write_header.3 | col -b > archive_write_header.3.txt - -archive_write_new.3.txt: ../../libarchive/archive_write_new.3 - nroff -mdoc ../../libarchive/archive_write_new.3 | col -b > archive_write_new.3.txt - -archive_write_open.3.txt: ../../libarchive/archive_write_open.3 - nroff -mdoc ../../libarchive/archive_write_open.3 | col -b > archive_write_open.3.txt - -archive_write_set_options.3.txt: ../../libarchive/archive_write_set_options.3 - nroff -mdoc ../../libarchive/archive_write_set_options.3 | col -b > archive_write_set_options.3.txt - -archive_write_set_passphrase.3.txt: ../../libarchive/archive_write_set_passphrase.3 - nroff -mdoc ../../libarchive/archive_write_set_passphrase.3 | col -b > archive_write_set_passphrase.3.txt - -cpio.5.txt: ../../libarchive/cpio.5 - nroff -mdoc ../../libarchive/cpio.5 | col -b > cpio.5.txt - -libarchive.3.txt: ../../libarchive/libarchive.3 - nroff -mdoc ../../libarchive/libarchive.3 | col -b > libarchive.3.txt - -libarchive_changes.3.txt: ../../libarchive/libarchive_changes.3 - nroff -mdoc ../../libarchive/libarchive_changes.3 | col -b > libarchive_changes.3.txt - -libarchive-formats.5.txt: ../../libarchive/libarchive-formats.5 - nroff -mdoc ../../libarchive/libarchive-formats.5 | col -b > libarchive-formats.5.txt - -libarchive_internals.3.txt: ../../libarchive/libarchive_internals.3 - nroff -mdoc ../../libarchive/libarchive_internals.3 | col -b > libarchive_internals.3.txt - -mtree.5.txt: ../../libarchive/mtree.5 - nroff -mdoc ../../libarchive/mtree.5 | col -b > mtree.5.txt - -tar.5.txt: ../../libarchive/tar.5 - nroff -mdoc ../../libarchive/tar.5 | col -b > tar.5.txt - -bsdtar.1.txt: ../../tar/bsdtar.1 - nroff -mdoc ../../tar/bsdtar.1 | col -b > bsdtar.1.txt - -bsdcpio.1.txt: ../../cpio/bsdcpio.1 - nroff -mdoc ../../cpio/bsdcpio.1 | col -b > bsdcpio.1.txt -all: archive_entry.3.txt archive_entry_acl.3.txt archive_entry_linkify.3.txt archive_entry_misc.3.txt archive_entry_paths.3.txt archive_entry_perms.3.txt archive_entry_stat.3.txt archive_entry_time.3.txt archive_read.3.txt archive_read_add_passphrase.3.txt archive_read_data.3.txt archive_read_disk.3.txt archive_read_extract.3.txt archive_read_filter.3.txt archive_read_format.3.txt archive_read_free.3.txt archive_read_header.3.txt archive_read_new.3.txt archive_read_open.3.txt archive_read_set_options.3.txt archive_util.3.txt archive_write.3.txt archive_write_blocksize.3.txt archive_write_data.3.txt archive_write_disk.3.txt archive_write_filter.3.txt archive_write_finish_entry.3.txt archive_write_format.3.txt archive_write_free.3.txt archive_write_header.3.txt archive_write_new.3.txt archive_write_open.3.txt archive_write_set_options.3.txt archive_write_set_passphrase.3.txt cpio.5.txt libarchive.3.txt libarchive_changes.3.txt libarchive-formats.5.txt libarchive_internals.3.txt mtree.5.txt tar.5.txt bsdtar.1.txt bsdcpio.1.txt diff --git a/thirdparty/libarchive/doc/text/archive_entry.3.txt b/thirdparty/libarchive/doc/text/archive_entry.3.txt deleted file mode 100644 index a23182691..000000000 --- a/thirdparty/libarchive/doc/text/archive_entry.3.txt +++ /dev/null @@ -1,92 +0,0 @@ -ARCHIVE_ENTRY(3) BSD Library Functions Manual ARCHIVE_ENTRY(3) - -NAME - archive_entry_clear, archive_entry_clone, archive_entry_free, - archive_entry_new — functions for managing archive entry descriptions - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - struct archive_entry * - archive_entry_clear(struct archive_entry *); - - struct archive_entry * - archive_entry_clone(struct archive_entry *); - - void - archive_entry_free(struct archive_entry *); - - struct archive_entry * - archive_entry_new(void); - -DESCRIPTION - These functions create and manipulate data objects that represent entries - within an archive. You can think of a struct archive_entry as a heavy- - duty version of struct stat: it includes everything from struct stat plus - associated pathname, textual group and user names, etc. These objects - are used by libarchive(3) to represent the metadata associated with a - particular entry in an archive. - - Create and Destroy - There are functions to allocate, destroy, clear, and copy archive_entry - objects: - archive_entry_clear() - Erases the object, resetting all internal fields to the same - state as a newly-created object. This is provided to allow you - to quickly recycle objects without thrashing the heap. - archive_entry_clone() - A deep copy operation; all text fields are duplicated. - archive_entry_free() - Releases the struct archive_entry object. - archive_entry_new() - Allocate and return a blank struct archive_entry object. - - Function groups - Due to high number of functions, the accessor functions can be found in - man pages grouped by the purpose. - - archive_entry_acl(3) Access Control List manipulation - - archive_entry_paths(3) Path name manipulation - - archive_entry_perms(3) User, group and mode manipulation - - archive_entry_stat(3) Functions not in the other groups and copying - to/from struct stat. - - archive_entry_time(3) Time field manipulation - - Most of the functions set or read entries in an object. Such functions - have one of the following forms: - archive_entry_set_XXXX() - Stores the provided data in the object. In particular, for - strings, the pointer is stored, not the referenced string. - archive_entry_copy_XXXX() - As above, except that the referenced data is copied into the ob†- ject. - archive_entry_XXXX() - Returns the specified data. In the case of strings, a const- - qualified pointer to the string is returned. - String data can be set or accessed as wide character strings or normal - char strings. The functions that use wide character strings are suffixed - with _w. Note that these are different representations of the same data: - For example, if you store a narrow string and read the corresponding wide - string, the object will transparently convert formats using the current - locale. Similarly, if you store a wide string and then store a narrow - string for the same data, the previously-set wide string will be dis†- carded in favor of the new data. - -SEE ALSO - archive_entry_acl(3), archive_entry_paths(3), archive_entry_perms(3), - archive_entry_time(3), libarchive(3) - -HISTORY - The libarchive library first appeared in FreeBSD 5.3. - -AUTHORS - The libarchive library was written by Tim Kientzle . - -BSD February 2, 2012 BSD diff --git a/thirdparty/libarchive/doc/text/archive_entry_acl.3.txt b/thirdparty/libarchive/doc/text/archive_entry_acl.3.txt deleted file mode 100644 index 563a23dff..000000000 --- a/thirdparty/libarchive/doc/text/archive_entry_acl.3.txt +++ /dev/null @@ -1,290 +0,0 @@ -ARCHIVE_ENTRY_ACL(3) BSD Library Functions Manual ARCHIVE_ENTRY_ACL(3) - -NAME - archive_entry_acl_add_entry, archive_entry_acl_add_entry_w, - archive_entry_acl_clear, archive_entry_acl_count, - archive_entry_acl_from_text, archive_entry_acl_from_text_w, - archive_entry_acl_next, archive_entry_acl_reset, - archive_entry_acl_to_text, archive_entry_acl_to_text_w, - archive_entry_acl_types — functions for manipulating Access Control Lists - in archive entry descriptions - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - void - archive_entry_acl_add_entry(struct archive_entry *a, int type, - int permset, int tag, int qualifier, const char *name); - - void - archive_entry_acl_add_entry_w(struct archive_entry *a, int type, - int permset, int tag, int qualifier, const wchar_t *name); - - void - archive_entry_acl_clear(struct archive_entry *a); - - int - archive_entry_acl_count(struct archive_entry *a, int type); - - int - archive_entry_acl_from_text(struct archive_entry *a, const char *text, - int type); - - int - archive_entry_acl_from_text_w(struct archive_entry *a, - const wchar_t *text, int type); - - int - archive_entry_acl_next(struct archive_entry *a, int type, int *ret_type, - int *ret_permset, int *ret_tag, int *ret_qual, - const char **ret_name); - - int - archive_entry_acl_reset(struct archive_entry *a, int type); - - char * - archive_entry_acl_to_text(struct archive_entry *a, ssize_t *len_p, - int flags); - - wchar_t * - archive_entry_acl_to_text_w(struct archive_entry *a, ssize_t *len_p, - int flags); - - int - archive_entry_acl_types(struct archive_entry *a); - -DESCRIPTION - The “Access Control Lists (ACLs)†extend the standard Unix permission - model. The ACL interface of libarchive supports both POSIX.1e and NFSv4 - style ACLs. Use of ACLs is restricted by various levels of ACL support - in operating systems, file systems and archive formats. - - POSIX.1e Access Control Lists - A POSIX.1e ACL consists of a number of independent entries. Each entry - specifies the permission set as a bitmask of basic permissions. Valid - permissions in the permset are: - ARCHIVE_ENTRY_ACL_READ (r) - ARCHIVE_ENTRY_ACL_WRITE (w) - ARCHIVE_ENTRY_ACL_EXECUTE (x) - The permissions correspond to the normal Unix permissions. - - The tag specifies the principal to which the permission applies. Valid - values are: - ARCHIVE_ENTRY_ACL_USER The user specified by the name field. - ARCHIVE_ENTRY_ACL_USER_OBJ The owner of the file. - ARCHIVE_ENTRY_ACL_GROUP The group specified by the name field. - ARCHIVE_ENTRY_ACL_GROUP_OBJ The group which owns the file. - ARCHIVE_ENTRY_ACL_MASK The maximum permissions to be obtained - via group permissions. - ARCHIVE_ENTRY_ACL_OTHER Any principal who is not the file - owner or a member of the owning group. - - The principals ARCHIVE_ENTRY_ACL_USER_OBJ, ARCHIVE_ENTRY_ACL_GROUP_OBJ - and ARCHIVE_ENTRY_ACL_OTHER are equivalent to user, group and other in - the classic Unix permission model and specify non-extended ACL entries. - - All files have an access ACL (ARCHIVE_ENTRY_ACL_TYPE_ACCESS). This spec†- ifies the permissions required for access to the file itself. Directo†- ries have an additional ACL (ARCHIVE_ENTRY_ACL_TYPE_DEFAULT), which con†- trols the initial access ACL for newly-created directory entries. - - NFSv4 Access Control Lists - A NFSv4 ACL consists of multiple individual entries called Access Control - Entries (ACEs). - - There are four possible types of a NFSv4 ACE: - ARCHIVE_ENTRY_ACL_TYPE_ALLOW Allow principal to perform actions re†- quiring given permissions. - ARCHIVE_ENTRY_ACL_TYPE_DENY Prevent principal from performing ac†- tions requiring given permissions. - ARCHIVE_ENTRY_ACL_TYPE_AUDIT Log access attempts by principal which - require given permissions. - ARCHIVE_ENTRY_ACL_TYPE_ALARM Trigger a system alarm on access at†- tempts by principal which require - given permissions. - - The tag specifies the principal to which the permission applies. Valid - values are: - ARCHIVE_ENTRY_ACL_USER The user specified by the name field. - ARCHIVE_ENTRY_ACL_USER_OBJ The owner of the file. - ARCHIVE_ENTRY_ACL_GROUP The group specified by the name field. - ARCHIVE_ENTRY_ACL_GROUP_OBJ The group which owns the file. - ARCHIVE_ENTRY_ACL_EVERYONE Any principal who is not the file - owner or a member of the owning group. - - Entries with the ARCHIVE_ENTRY_ACL_USER or ARCHIVE_ENTRY_ACL_GROUP tag - store the user and group name in the name string and optionally the user - or group ID in the qualifier integer. - - NFSv4 ACE permissions and flags are stored in the same permset bitfield. - Some permissions share the same constant and permission character but - have different effect on directories than on files. The following ACE - permissions are supported: - ARCHIVE_ENTRY_ACL_READ_DATA (r) - Read data (file). - ARCHIVE_ENTRY_ACL_LIST_DIRECTORY (r) - List entries (directory). - ARCHIVE_ENTRY_ACL_WRITE_DATA (w) - Write data (file). - ARCHIVE_ENTRY_ACL_ADD_FILE (w) - Create files (directory). - ARCHIVE_ENTRY_ACL_EXECUTE (x) - Execute file or change into a directory. - ARCHIVE_ENTRY_ACL_APPEND_DATA (p) - Append data (file). - ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY (p) - Create subdirectories (directory). - ARCHIVE_ENTRY_ACL_DELETE_CHILD (D) - Remove files and subdirectories inside a directory. - ARCHIVE_ENTRY_ACL_DELETE (d) - Remove file or directory. - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES (a) - Read file or directory attributes. - ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES (A) - Write file or directory attributes. - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS (R) - Read named file or directory attributes. - ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS (W) - Write named file or directory attributes. - ARCHIVE_ENTRY_ACL_READ_ACL (c) - Read file or directory ACL. - ARCHIVE_ENTRY_ACL_WRITE_ACL (C) - Write file or directory ACL. - ARCHIVE_ENTRY_ACL_WRITE_OWNER (o) - Change owner of a file or directory. - ARCHIVE_ENTRY_ACL_SYNCHRONIZE (s) - Use synchronous I/O. - - The following NFSv4 ACL inheritance flags are supported: - ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT (f) - Inherit parent directory ACE to files. - ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT (d) - Inherit parent directory ACE to subdirectories. - ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY (i) - Only inherit, do not apply the permission on the directory - itself. - ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT (n) - Do not propagate inherit flags. Only first-level entries - inherit ACLs. - ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS (S) - Trigger alarm or audit on successful access. - ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS (F) - Trigger alarm or audit on failed access. - ARCHIVE_ENTRY_ACL_ENTRY_INHERITED (I) - Mark that ACE was inherited. - - Functions - archive_entry_acl_add_entry() and archive_entry_acl_add_entry_w() add a - single ACL entry. For the access ACL and non-extended principals, the - classic Unix permissions are updated. An archive entry cannot contain - both POSIX.1e and NFSv4 ACL entries. - - archive_entry_acl_clear() removes all ACL entries and resets the enumera†- tion pointer. - - archive_entry_acl_count() counts the ACL entries that have the given type - mask. type can be the bitwise-or of - ARCHIVE_ENTRY_ACL_TYPE_ACCESS - ARCHIVE_ENTRY_ACL_TYPE_DEFAULT - for POSIX.1e ACLs and - ARCHIVE_ENTRY_ACL_TYPE_ALLOW - ARCHIVE_ENTRY_ACL_TYPE_DENY - ARCHIVE_ENTRY_ACL_TYPE_AUDIT - ARCHIVE_ENTRY_ACL_TYPE_ALARM - for NFSv4 ACLs. For POSIX.1e ACLs if ARCHIVE_ENTRY_ACL_TYPE_ACCESS is - included and at least one extended ACL entry is found, the three non-ex†- tended ACLs are added. - - archive_entry_acl_from_text() and archive_entry_acl_from_text_w() add new - (or merge with existing) ACL entries from (wide) text. The argument type - may take one of the following values: - ARCHIVE_ENTRY_ACL_TYPE_ACCESS - ARCHIVE_ENTRY_ACL_TYPE_DEFAULT - ARCHIVE_ENTRY_ACL_TYPE_NFS4 - Supports all formats that can be created with archive_entry_acl_to_text() - or respectively archive_entry_acl_to_text_w(). Existing ACL entries are - preserved. To get a clean new ACL from text archive_entry_acl_clear() - must be called first. Entries prefixed with “default:†are treated as - ARCHIVE_ENTRY_ACL_TYPE_DEFAULT unless type is - ARCHIVE_ENTRY_ACL_TYPE_NFS4. Invalid entries, non-parseable ACL entries - and entries beginning with the ‘#’ character (comments) are skipped. - - archive_entry_acl_next() return the next entry of the ACL list. This - functions may only be called after archive_entry_acl_reset() has indi†- cated the presence of extended ACL entries. - - archive_entry_acl_reset() prepare reading the list of ACL entries with - archive_entry_acl_next(). The function returns 0 if no non-extended ACLs - are found. In this case, the access permissions should be obtained by - archive_entry_mode(3) or set using chmod(2). Otherwise, the function re†- turns the same value as archive_entry_acl_count(). - - archive_entry_acl_to_text() and archive_entry_acl_to_text_w() convert the - ACL entries for the given type into a (wide) string of ACL entries sepa†- rated by newline. If the pointer len_p is not NULL, then the function - shall return the length of the string (not including the NULL terminator) - in the location pointed to by len_p. The flag argument is a bitwise-or. - - The following flags are effective only on POSIX.1e ACL: - ARCHIVE_ENTRY_ACL_TYPE_ACCESS - Output access ACLs. - ARCHIVE_ENTRY_ACL_TYPE_DEFAULT - Output POSIX.1e default ACLs. - ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT - Prefix each default ACL entry with the word “default:â€. - ARCHIVE_ENTRY_ACL_STYLE_SOLARIS - The mask and other ACLs don not contain a double colon. - - The following flags are effecive only on NFSv4 ACL: - ARCHIVE_ENTRY_ACL_STYLE_COMPACT - Do not output minus characters for unset permissions and - flags in NFSv4 ACL permission and flag fields. - - The following flags are effective on both POSIX.1e and NFSv4 ACL: - ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID - Add an additional colon-separated field containing the user - or group id. - ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA - Separate ACL entries with comma instead of newline. - - If the archive entry contains NFSv4 ACLs, all types of NFSv4 ACLs are re†- turned. It the entry contains POSIX.1e ACLs and none of the flags - ARCHIVE_ENTRY_ACL_TYPE_ACCESS or ARCHIVE_ENTRY_ACL_TYPE_DEFAULT are spec†- ified, both access and default entries are returned and default entries - are prefixed with “default:â€. - - archive_entry_acl_types() get ACL entry types contained in an archive en†- try's ACL. As POSIX.1e and NFSv4 ACL entries cannot be mixed, this func†- tion is a very efficient way to detect if an ACL already contains - POSIX.1e or NFSv4 ACL entries. - -RETURN VALUES - archive_entry_acl_count() and archive_entry_acl_reset() returns the num†- ber of ACL entries that match the given type mask. For POSIX.1e ACLS if - the type mask includes ARCHIVE_ENTRY_ACL_TYPE_ACCESS and at least one ex†- tended ACL entry exists, the three classic Unix permissions are counted. - - archive_entry_acl_from_text() and archive_entry_acl_from_text_w() return - ARCHIVE_OK if all entries were successfully parsed and ARCHIVE_WARN if - one or more entries were invalid or non-parseable. - - archive_entry_acl_next() returns ARCHIVE_OK on success, ARCHIVE_EOF if no - more ACL entries exist and ARCHIVE_WARN if archive_entry_acl_reset() has - not been called first. - - archive_entry_acl_to_text() returns a string representing the ACL entries - matching the given type and flags on success or NULL on error. - - archive_entry_acl_to_text_w() returns a wide string representing the ACL - entries matching the given type and flags on success or NULL on error. - - archive_entry_acl_types() returns a bitmask of ACL entry types or 0 if - archive entry has no ACL entries. - -SEE ALSO - archive_entry(3), libarchive(3) - -BSD February 15, 2017 BSD diff --git a/thirdparty/libarchive/doc/text/archive_entry_linkify.3.txt b/thirdparty/libarchive/doc/text/archive_entry_linkify.3.txt deleted file mode 100644 index a67576b12..000000000 --- a/thirdparty/libarchive/doc/text/archive_entry_linkify.3.txt +++ /dev/null @@ -1,113 +0,0 @@ -ARCHIVE_ENTRY_LINKIFY(3) BSD Library Functions Manual ARCHIVE_ENTRY_LINKIFY(3) - -NAME - archive_entry_linkresolver, archive_entry_linkresolver_new, - archive_entry_linkresolver_set_strategy, archive_entry_linkresolver_free, - archive_entry_linkify — hardlink resolver functions - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - struct archive_entry_linkresolver * - archive_entry_linkresolver_new(void); - - void - archive_entry_linkresolver_set_strategy(struct archive_entry_linkresolver *resolver, - int format); - - void - archive_entry_linkresolver_free(struct archive_entry_linkresolver *resolver); - - void - archive_entry_linkify(struct archive_entry_linkresolver *resolver, - struct archive_entry **entry, struct archive_entry **sparse); - -DESCRIPTION - Programs that want to create archives have to deal with hardlinks. - Hardlinks are handled in different ways by the archive formats. The ba†- sic strategies are: - - 1. Ignore hardlinks and store the body for each reference (old cpio, - zip). - - 2. Store the body the first time an inode is seen (ustar, pax). - - 3. Store the body the last time an inode is seen (new cpio). - - The archive_entry_linkresolver functions help by providing a unified in†- terface and handling the complexity behind the scene. - - The archive_entry_linkresolver functions assume that archive_entry in†- stances have valid nlinks, inode and device values. The inode and device - value is used to match entries. The nlinks value is used to determined - if all references have been found and if the internal references can be - recycled. - - The archive_entry_linkresolver_new() function allocates a new link re†- solver. The instance can be freed using - archive_entry_linkresolver_free(). All deferred entries are flushed and - the internal storage is freed. - - The archive_entry_linkresolver_set_strategy() function selects the opti†- mal hardlink strategy for the given format. The format code can be ob†- tained from archive_format(3). The function can be called more than - once, but it is recommended to flush all deferred entries first. - - The archive_entry_linkify() function is the core of - archive_entry_linkresolver. The entry() argument points to the - archive_entry that should be written. Depending on the strategy one of - the following actions is taken: - - 1. For the simple archive formats *entry is left unmodified and *sparse - is set to NULL. - - 2. For tar like archive formats, *sparse is set to NULL. If *entry is - NULL, no action is taken. If the hardlink count of *entry is larger - than 1 and the file type is a regular file or symbolic link, the in†- ternal list is searched for a matching inode. If such an inode is - found, the link count is decremented and the file size of *entry is - set to 0 to notify that no body should be written. If no such inode - is found, a copy of the entry is added to the internal cache with a - link count reduced by one. - - 3. For new cpio like archive formats a value for *entry of NULL is used - to flush deferred entries. In that case *entry is set to an arbi†- trary deferred entry and the entry itself is removed from the inter†- nal list. If the internal list is empty, *entry is set to NULL. In - either case, *sparse is set to NULL and the function returns. If - the hardlink count of *entry is one or the file type is a directory - or device, *sparse is set to NULL and no further action is taken. - Otherwise, the internal list is searched for a matching inode. If - such an inode is not found, the entry is added to the internal list, - both *entry and *sparse are set to NULL and the function returns. - If such an inode is found, the link count is decremented. If it re†- mains larger than one, the existing entry on the internal list is - swapped with *entry after retaining the link count. The existing - entry is returned in *entry. If the link count reached one, the new - entry is also removed from the internal list and returned in - *sparse. Otherwise *sparse is set to NULL. - - The general usage is therefore: - - 1. For each new archive entry, call archive_entry_linkify(). - - 2. Keep in mind that the entries returned may have a size of 0 now. - - 3. If *entry is not NULL, archive it. - - 4. If *sparse is not NULL, archive it. - - 5. After all entries have been written to disk, call - archive_entry_linkify() with *entry set to NULL and archive the re†- turned entry as long as it is not NULL. - -RETURN VALUES - archive_entry_linkresolver_new() returns NULL on malloc(3) failures. - -SEE ALSO - archive_entry(3) - -BSD February 2, 2012 BSD diff --git a/thirdparty/libarchive/doc/text/archive_entry_misc.3.txt b/thirdparty/libarchive/doc/text/archive_entry_misc.3.txt deleted file mode 100644 index 77fd7fa2e..000000000 --- a/thirdparty/libarchive/doc/text/archive_entry_misc.3.txt +++ /dev/null @@ -1,36 +0,0 @@ -ARCHIVE_ENTRY_MISC(3) BSD Library Functions Manual ARCHIVE_ENTRY_MISC(3) - -NAME - archive_entry_symlink_type, archive_entry_set_symlink_type — miscella†- neous functions for manipulating properties of archive_entry - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - int - archive_entry_symlink_type(struct archive_entry *a); - - void - archive_entry_set_symlink_type(struct archive_entry *a, int); - -DESCRIPTION - The function archive_entry_symlink_type() returns and the function - archive_entry_set_symlink_type() sets the type of the symbolic link - stored in an archive entry. These functions have special meaning on op†- erating systems that support multiple symbolic link types (e.g. Microsoft - Windows). - - Supported values are: - AE_SYMLINK_TYPE_UNDEFINED Symbolic link target type is not defined (de†- fault on unix systems) - AE_SYMLINK_TYPE_FILE Symbolic link points to a file - AE_SYMLINK_TYPE_DIRECTORY Symbolic link points to a directory - -SEE ALSO - archive_entry(3), archive_entry_paths(3), archive_entry_stat(3), - libarchive(3) - -BSD April 15, 2019 BSD diff --git a/thirdparty/libarchive/doc/text/archive_entry_paths.3.txt b/thirdparty/libarchive/doc/text/archive_entry_paths.3.txt deleted file mode 100644 index e4f0716fa..000000000 --- a/thirdparty/libarchive/doc/text/archive_entry_paths.3.txt +++ /dev/null @@ -1,136 +0,0 @@ -ARCHIVE_ENTRY_PATHS(3) BSD Library Functions Manual ARCHIVE_ENTRY_PATHS(3) - -NAME - archive_entry_hardlink, archive_entry_hardlink_w, - archive_entry_set_hardlink, archive_entry_copy_hardlink, - archive_entry_copy_hardlink_w, archive_entry_update_hardlink_utf8, - archive_entry_set_link, archive_entry_copy_link, - archive_entry_copy_link_w, archive_entry_update_link_utf8, - archive_entry_pathname, archive_entry_pathname_w, - archive_entry_set_pathname, archive_entry_copy_pathname, - archive_entry_copy_pathname_w, archive_entry_update_pathname_utf8, - archive_entry_sourcepath, archive_entry_copy_sourcepath, - archive_entry_symlink, archive_entry_symlink_w, - archive_entry_set_symlink, archive_entry_copy_symlink, - archive_entry_copy_symlink_w, archive_entry_update_symlink_utf8 — func†- tions for manipulating path names in archive entry descriptions - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - const char * - archive_entry_hardlink(struct archive_entry *a); - - const wchar_t * - archive_entry_hardlink_w(struct archive_entry *a); - - void - archive_entry_set_hardlink(struct archive_entry *a, const char *path); - - void - archive_entry_copy_hardlink(struct archive_entry *a, const char *path); - - void - archive_entry_copy_hardlink_w(struct archive_entry *a, const, wchar_t, - *path"); - - int - archive_entry_update_hardlink_utf8(struct archive_entry *a, - const char *path); - - void - archive_entry_set_link(struct archive_entry *a, const char *path); - - void - archive_entry_copy_link(struct archive_entry *a, const char *path); - - void - archive_entry_copy_link_w(struct archive_entry *a, const wchar_t *path); - - int - archive_entry_update_link_utf8(struct archive_entry *a, - const char *path); - - const char * - archive_entry_pathname(struct archive_entry *a); - - const wchar_t * - archive_entry_pathname_w(struct archive_entry *a); - - void - archive_entry_set_pathname(struct archive_entry *a, const char *path); - - void - archive_entry_copy_pathname(struct archive_entry *a, const char *path); - - void - archive_entry_copy_pathname_w(struct archive_entry *a, - const wchar_t *path); - - int - archive_entry_update_pathname_utf8(struct archive_entry *a, - const char *path); - - const char * - archive_entry_sourcepath(struct archive_entry *a); - - void - archive_entry_copy_sourcepath(struct archive_entry *a, const char *path); - - const char * - archive_entry_symlink(struct archive_entry *a); - - const wchar_t * - archive_entry_symlink_w(struct archive_entry *a); - - void - archive_entry_set_symlink(struct archive_entry *a, const char *path); - - void - archive_entry_copy_symlink(struct archive_entry *a, const char *path); - - void - archive_entry_copy_symlink_w(struct archive_entry *a, - const wchar_t *path); - - int - archive_entry_update_symlink_utf8(struct archive_entry *a, - const char *path); - -DESCRIPTION - Path names supported by archive_entry(3): - hardlink Destination of the hardlink. - link Update only. For a symlink, update the destination. Other†- wise, make the entry a hardlink and alter the destination for - that. - pathname Path in the archive - sourcepath Path on the disk for use by archive_read_disk(3). - symlink Destination of the symbolic link. - - Path names can be provided in one of three different ways: - - char * Multibyte strings in the current locale. - - wchar_t * Wide character strings in the current locale. The accessor - functions are named XXX_w(). - - UTF-8 Unicode strings encoded as UTF-8. These are convenience func†- tions to update both the multibyte and wide character strings - at the same time. - - The sourcepath is a pure filesystem concept and never stored in an ar†- chive directly. - - For that reason, it is only available as multibyte string. The link path - is a convenience function for conditionally setting hardlink or symlink - destination. It doesn't have a corresponding get accessor function. - - archive_entry_set_XXX() is an alias for archive_entry_copy_XXX(). - -SEE ALSO - archive_entry(3), libarchive(3) - -BSD February 2, 2012 BSD diff --git a/thirdparty/libarchive/doc/text/archive_entry_perms.3.txt b/thirdparty/libarchive/doc/text/archive_entry_perms.3.txt deleted file mode 100644 index 1f50b2c2c..000000000 --- a/thirdparty/libarchive/doc/text/archive_entry_perms.3.txt +++ /dev/null @@ -1,169 +0,0 @@ -ARCHIVE_ENTRY_PERMS(3) BSD Library Functions Manual ARCHIVE_ENTRY_PERMS(3) - -NAME - archive_entry_gid, archive_entry_set_gid, archive_entry_uid, - archive_entry_set_uid, archive_entry_perm, archive_entry_set_perm, - archive_entry_strmode, archive_entry_uname, archive_entry_uname_w, - archive_entry_set_uname, archive_entry_copy_uname, - archive_entry_copy_uname_w, archive_entry_update_uname_utf8, - archive_entry_gname, archive_entry_gname_w, archive_entry_set_gname, - archive_entry_copy_gname, archive_entry_copy_gname_w, - archive_entry_update_gname_utf8, archive_entry_fflags, - archive_entry_fflags_text, archive_entry_set_fflags, - archive_entry_copy_fflags_text, archive_entry_copy_fflags_text_w — func†- tions for manipulating ownership and permissions in archive entry de†- scriptions - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - gid_t - archive_entry_gid(struct archive_entry *a); - - void - archive_entry_set_gid(struct archive_entry *a, gid_t gid); - - uid_t - archive_entry_uid(struct archive_entry *a); - - void - archive_entry_set_uid(struct archive_entry *a, uid_t uid); - - mode_t - archive_entry_perm(struct archive_entry *a); - - void - archive_entry_set_perm(struct archive_entry *a, mode_t mode); - - const char * - archive_entry_strmode(struct archive_entry *a); - - const char * - archive_entry_gname(struct archive_entry *a); - - const wchar_t * - archive_entry_gname_w(struct archive_entry *a); - - void - archive_entry_set_gname(struct archive_entry *a, const char *a); - - void - archive_entry_copy_gname(struct archive_entry *a, const char *name); - - void - archive_entry_copy_gname_w(struct archive_entry *a, const wchar_t *name); - - int - archive_entry_update_gname_utf8(struct archive_entry *a, - const char *name); - - const char * - archive_entry_uname(struct archive_entry *a); - - const wchar_t * - archive_entry_uname_w(struct archive_entry *a); - - void - archive_entry_set_uname(struct archive_entry *a, const char *name); - - void - archive_entry_copy_uname(struct archive_entry *a, const char *name); - - void - archive_entry_copy_uname_w(struct archive_entry *a, const wchar_t *name); - - int - archive_entry_update_uname_utf8(struct archive_entry *a, - const char *name); - - void - archive_entry_fflags(struct archive_entry *a, unsigned long *set_bits, - unsigned long *clear_bits); - - const char * - archive_entry_fflags_text(struct archive_entry *a); - - void - archive_entry_set_fflags(struct archive_entry *a, unsigned long set_bits, - unsigned long clear_bits); - - const char * - archive_entry_copy_fflags_text(struct archive_entry *a, - const char *text); - - const wchar_t * - archive_entry_copy_fflags_text_w(struct archive_entry *a, - const wchar_t *text); - -DESCRIPTION - User id, group id and mode - The functions archive_entry_uid(), archive_entry_gid(), and - archive_entry_perm() can be used to extract the user id, group id and - permission from the given entry. The corresponding functions - archive_entry_set_uid(), archive_entry_set_gid(), and - archive_entry_set_perm() store the given user id, group id and permission - in the entry. The permission is also set as a side effect of calling - archive_entry_set_mode(). - - archive_entry_strmode() returns a string representation of the permission - as used by the long mode of ls(1). - - User and group name - User and group names can be provided in one of three different ways: - - char * Multibyte strings in the current locale. - - wchar_t * Wide character strings in the current locale. The accessor - functions are named XXX_w(). - - UTF-8 Unicode strings encoded as UTF-8. These are convenience func†- tions to update both the multibyte and wide character strings - at the same time. - - archive_entry_set_XXX() is an alias for archive_entry_copy_XXX(). - - File Flags - File flags are transparently converted between a bitmap representation - and a textual format. For example, if you set the bitmap and ask for - text, the library will build a canonical text format. However, if you - set a text format and request a text format, you will get back the same - text, even if it is ill-formed. If you need to canonicalize a textual - flags string, you should first set the text form, then request the bitmap - form, then use that to set the bitmap form. Setting the bitmap format - will clear the internal text representation and force it to be recon†- structed when you next request the text form. - - The bitmap format consists of two integers, one containing bits that - should be set, the other specifying bits that should be cleared. Bits - not mentioned in either bitmap will be ignored. Usually, the bitmap of - bits to be cleared will be set to zero. In unusual circumstances, you - can force a fully-specified set of file flags by setting the bitmap of - flags to clear to the complement of the bitmap of flags to set. (This - differs from fflagstostr(3), which only includes names for set bits.) - Converting a bitmap to a textual string is a platform-specific operation; - bits that are not meaningful on the current platform will be ignored. - - The canonical text format is a comma-separated list of flag names. The - archive_entry_copy_fflags_text() and archive_entry_copy_fflags_text_w() - functions parse the provided text and set the internal bitmap values. - This is a platform-specific operation; names that are not meaningful on - the current platform will be ignored. The function returns a pointer to - the start of the first name that was not recognized, or NULL if every - name was recognized. Note that every name — including names that follow - an unrecognized name — will be evaluated, and the bitmaps will be set to - reflect every name that is recognized. (In particular, this differs from - strtofflags(3), which stops parsing at the first unrecognized name.) - -SEE ALSO - archive_entry(3), archive_entry_acl(3), archive_read_disk(3), - archive_write_disk(3), libarchive(3) - -BUGS - The platform types uid_t and gid_t are often 16 or 32 bit wide. In this - case it is possible that the ids can not be correctly restored from ar†- chives and get truncated. - -BSD February 2, 2012 BSD diff --git a/thirdparty/libarchive/doc/text/archive_entry_stat.3.txt b/thirdparty/libarchive/doc/text/archive_entry_stat.3.txt deleted file mode 100644 index d20fd0254..000000000 --- a/thirdparty/libarchive/doc/text/archive_entry_stat.3.txt +++ /dev/null @@ -1,189 +0,0 @@ -ARCHIVE_ENTRY_STAT(3) BSD Library Functions Manual ARCHIVE_ENTRY_STAT(3) - -NAME - archive_entry_stat, archive_entry_copy_stat, archive_entry_filetype, - archive_entry_set_filetype, archive_entry_mode, archive_entry_set_mode, - archive_entry_size, archive_entry_size_is_set, archive_entry_set_size, - archive_entry_unset_size, archive_entry_dev, archive_entry_set_dev, - archive_entry_dev_is_set, archive_entry_devmajor, - archive_entry_set_devmajor, archive_entry_devminor, - archive_entry_set_devminor, archive_entry_ino, archive_entry_set_ino, - archive_entry_ino_is_set, archive_entry_ino64, archive_entry_set_ino64, - archive_entry_nlink, archive_entry_rdev, archive_entry_set_rdev, - archive_entry_rdevmajor, archive_entry_set_rdevmajor, - archive_entry_rdevminor, archive_entry_set_rdevminor — accessor functions - for manipulating archive entry descriptions - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - const struct stat * - archive_entry_stat(struct archive_entry *a); - - void - archive_entry_copy_stat(struct archive_entry *a, const struct stat *sb); - - mode_t - archive_entry_filetype(struct archive_entry *a); - - void - archive_entry_set_filetype(struct archive_entry *a, unsigned int type); - - mode_t - archive_entry_mode(struct archive_entry *a); - - void - archive_entry_set_mode(struct archive_entry *a, mode_t mode); - - int64_t - archive_entry_size(struct archive_entry *a); - - int - archive_entry_size_is_set(struct archive_entry *a); - - void - archive_entry_set_size(struct archive_entry *a, int64_t size); - - void - archive_entry_unset_size(struct archive_entry *a); - - dev_t - archive_entry_dev(struct archive_entry *a); - - void - archive_entry_set_dev(struct archive_entry *a, dev_t dev); - - int - archive_entry_dev_is_set(struct archive_entry *a); - - dev_t - archive_entry_devmajor(struct archive_entry *a); - - void - archive_entry_set_devmajor(struct archive_entry *a, dev_t major); - - dev_t - archive_entry_devminor(struct archive_entry *a); - - void - archive_entry_set_devminor(struct archive_entry *a, dev_t minor); - - ino_t - archive_entry_ino(struct archive_entry *a); - - void - archive_entry_set_ino(struct archive_entry *a, unsigned long ino); - - int - archive_entry_ino_is_set(struct archive_entry *a); - - int64_t - archive_entry_ino64(struct archive_entry *a); - - void - archive_entry_set_ino64(struct archive_entry *a, int64_t ino); - - unsigned int - archive_entry_nlink(struct archive_entry *a); - - void - archive_entry_set_nlink(struct archive_entry *a, unsigned int count); - - dev_t - archive_entry_rdev(struct archive_entry *a); - - dev_t - archive_entry_rdevmajor(struct archive_entry *a); - - dev_t - archive_entry_rdevminor(struct archive_entry *a); - - void - archive_entry_set_rdev(struct archive_entry *a, dev_t dev); - - void - archive_entry_set_rdevmajor(struct archive_entry *a, dev_t major); - - void - archive_entry_set_rdevminor(struct archive_entry *a, dev_t minor); - -DESCRIPTION - Copying to and from struct stat - The function archive_entry_stat() converts the various fields stored in - the archive entry to the format used by stat(2). The return value re†- mains valid until either archive_entry_clear() or archive_entry_free() is - called. It is not affected by calls to the set accessor functions. It - currently sets the following values in struct stat: st_atime, st_ctime, - st_dev, st_gid, st_ino, st_mode, st_mtime, st_nlink, st_rdev, st_size, - st_uid. In addition, st_birthtime and high-precision information for - time-related fields will be included on platforms that support it. - - The function archive_entry_copy_stat() copies fields from the platform's - struct stat. Fields not provided by struct stat are unchanged. - - General accessor functions - The functions archive_entry_filetype() and archive_entry_set_filetype() - get respectively set the filetype. The file type is one of the following - constants: - AE_IFREG Regular file - AE_IFLNK Symbolic link - AE_IFSOCK Socket - AE_IFCHR Character device - AE_IFBLK Block device - AE_IFDIR Directory - AE_IFIFO Named pipe (fifo) - Not all file types are supported by all platforms. The constants used by - stat(2) may have different numeric values from the corresponding con†- stants above. - - The functions archive_entry_mode() and archive_entry_set_mode() get/set a - combination of file type and permissions and provide the equivalent of - st_mode. Use of archive_entry_filetype() and archive_entry_perm() for - getting and archive_entry_set_filetype() and archive_entry_set_perm() for - setting is recommended. - - The function archive_entry_size() returns the file size, if it has been - set, and 0 otherwise. archive_entry_size() can be used to query that - status. archive_entry_set_size() and archive_entry_unset_size() set and - unset the size, respectively. - - The number of references (hardlinks) can be obtained by calling - archive_entry_nlink() and set with archive_entry_set_nlink(). - - Identifying unique files - The functions archive_entry_dev() and archive_entry_ino64() are used by - archive_entry_linkify(3) to find hardlinks. The pair of device and inode - is supposed to identify hardlinked files. - - The device major and minor number can be obtained independently using - archive_entry_devmajor() and archive_entry_devminor(). The device can be - set either via archive_entry_set_dev() or by the combination of major and - minor number using archive_entry_set_devmajor() and - archive_entry_set_devminor(). - - The inode number can be obtained using archive_entry_ino(). This is a - legacy interface that uses the platform ino_t, which may be very small. - To set the inode number, archive_entry_set_ino64() is the preferred in†- terface. - - Accessor functions for block and character devices - Block and character devices are characterised either using a device num†- ber or a pair of major and minor number. The combined device number can - be obtained with archive_device_rdev() and set with - archive_device_set_rdev(). The major and minor numbers are accessed by - archive_device_rdevmajor(), archive_device_rdevminor() - archive_device_set_rdevmajor() and archive_device_set_rdevminor(). - - The process of splitting the combined device number into major and minor - number and the reverse process of combing them differs between platforms. - Some archive formats use the combined form, while other formats use the - split form. - -SEE ALSO - stat(2), archive_entry_acl(3), archive_entry_perms(3), - archive_entry_time(3), libarchive(3) - -BSD February 2, 2012 BSD diff --git a/thirdparty/libarchive/doc/text/archive_entry_time.3.txt b/thirdparty/libarchive/doc/text/archive_entry_time.3.txt deleted file mode 100644 index 2ab6bbb02..000000000 --- a/thirdparty/libarchive/doc/text/archive_entry_time.3.txt +++ /dev/null @@ -1,110 +0,0 @@ -ARCHIVE_ENTRY_TIME(3) BSD Library Functions Manual ARCHIVE_ENTRY_TIME(3) - -NAME - archive_entry_atime, archive_entry_atime_nsec, - archive_entry_atime_is_set, archive_entry_set_atime, - archive_entry_unset_atime, archive_entry_birthtime, - archive_entry_birthtime_nsec, archive_entry_birthtime_is_set, - archive_entry_set_birthtime, archive_entry_unset_birthtime, - archive_entry_ctime, archive_entry_ctime_nsec, - archive_entry_ctime_is_set, archive_entry_set_ctime, - archive_entry_unset_ctime, archive_entry_mtime, archive_entry_mtime_nsec, - archive_entry_mtime_is_set, archive_entry_set_mtime, - archive_entry_unset_mtime — functions for manipulating times in archive - entry descriptions - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - time_t - archive_entry_atime(struct archive_entry *a); - - long - archive_entry_atime_nsec(struct archive_entry *a); - - int - archive_entry_atime_is_set(struct archive_entry *a); - - void - archive_entry_set_atime(struct archive_entry *a, time_t sec, - long nanosec); - - void - archive_entry_unset_atime(struct archive_entry *a); - - time_t - archive_entry_birthtime(struct archive_entry *a); - - long - archive_entry_birthtime_nsec(struct archive_entry *a); - - int - archive_entry_birthtime_is_set(struct archive_entry *a); - - void - archive_entry_set_birthtime(struct archive_entry *a, time_t sec, - long nanosec); - - void - archive_entry_unset_birthtime(struct archive_entry *a); - - time_t - archive_entry_ctime(struct archive_entry *a); - - long - archive_entry_ctime_nsec(struct archive_entry *a); - - int - archive_entry_ctime_is_set(struct archive_entry *a); - - void - archive_entry_set_ctime(struct archive_entry *a, time_t sec, - long nanosec); - - void - archive_entry_unset_ctime(struct archive_entry *a); - - time_t - archive_entry_mtime(struct archive_entry *a); - - long - archive_entry_mtime_nsec(struct archive_entry *a); - - int - archive_entry_mtime_is_set(struct archive_entry *a); - - void - archive_entry_set_mtime(struct archive_entry *a, time_t sec, - long nanosec); - - void - archive_entry_unset_mtime(struct archive_entry *a); - -DESCRIPTION - These functions create and manipulate the time fields in an - archive_entry. Supported time fields are atime (access time), birthtime - (creation time), ctime (last time an inode property was changed) and - mtime (modification time). - - libarchive(3) provides a high-resolution interface. The timestamps are - truncated automatically depending on the archive format (for archiving) - or the filesystem capabilities (for restoring). - - All timestamp fields are optional. The XXX_unset() functions can be used - to mark the corresponding field as missing. The current state can be - queried using XXX_is_set(). Unset time fields have a second and nanosec†- ond field of 0. - -SEE ALSO - archive_entry(3), libarchive(3) - -HISTORY - The libarchive library first appeared in FreeBSD 5.3. - -AUTHORS - The libarchive library was written by Tim Kientzle . - -BSD February 2, 2012 BSD diff --git a/thirdparty/libarchive/doc/text/archive_read.3.txt b/thirdparty/libarchive/doc/text/archive_read.3.txt deleted file mode 100644 index f5f33d30a..000000000 --- a/thirdparty/libarchive/doc/text/archive_read.3.txt +++ /dev/null @@ -1,156 +0,0 @@ -ARCHIVE_READ(3) BSD Library Functions Manual ARCHIVE_READ(3) - -NAME - archive_read — functions for reading streaming archives - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - -DESCRIPTION - These functions provide a complete API for reading streaming archives. - The general process is to first create the struct archive object, set op†- tions, initialize the reader, iterate over the archive headers and asso†- ciated data, then close the archive and release all resources. - - Create archive object - See archive_read_new(3). - - To read an archive, you must first obtain an initialized struct archive - object from archive_read_new(). - - Enable filters and formats - See archive_read_filter(3) and archive_read_format(3). - - You can then modify this object for the desired operations with the vari†- ous archive_read_set_XXX() and archive_read_support_XXX() functions. In - particular, you will need to invoke appropriate - archive_read_support_XXX() functions to enable the corresponding compres†- sion and format support. Note that these latter functions perform two - distinct operations: they cause the corresponding support code to be - linked into your program, and they enable the corresponding auto-detect - code. Unless you have specific constraints, you will generally want to - invoke archive_read_support_filter_all() and - archive_read_support_format_all() to enable auto-detect for all formats - and compression types currently supported by the library. - - Set options - See archive_read_set_options(3). - - Open archive - See archive_read_open(3). - - Once you have prepared the struct archive object, you call - archive_read_open() to actually open the archive and prepare it for read†- ing. There are several variants of this function; the most basic expects - you to provide pointers to several functions that can provide blocks of - bytes from the archive. There are convenience forms that allow you to - specify a filename, file descriptor, FILE * object, or a block of memory - from which to read the archive data. Note that the core library makes no - assumptions about the size of the blocks read; callback functions are - free to read whatever block size is most appropriate for the medium. - - Consume archive - See archive_read_header(3), archive_read_data(3) and - archive_read_extract(3). - - Each archive entry consists of a header followed by a certain amount of - data. You can obtain the next header with archive_read_next_header(), - which returns a pointer to an struct archive_entry structure with infor†- mation about the current archive element. If the entry is a regular - file, then the header will be followed by the file data. You can use - archive_read_data() (which works much like the read(2) system call) to - read this data from the archive, or archive_read_data_block() which pro†- vides a slightly more efficient interface. You may prefer to use the - higher-level archive_read_data_skip(), which reads and discards the data - for this entry, archive_read_data_into_fd(), which copies the data to the - provided file descriptor, or archive_read_extract(), which recreates the - specified entry on disk and copies data from the archive. In particular, - note that archive_read_extract() uses the struct archive_entry structure - that you provide it, which may differ from the entry just read from the - archive. In particular, many applications will want to override the - pathname, file permissions, or ownership. - - Release resources - See archive_read_free(3). - - Once you have finished reading data from the archive, you should call - archive_read_close() to close the archive, then call archive_read_free() - to release all resources, including all memory allocated by the library. - -EXAMPLES - The following illustrates basic usage of the library. In this example, - the callback functions are simply wrappers around the standard open(2), - read(2), and close(2) system calls. - - void - list_archive(const char *name) - { - struct mydata *mydata; - struct archive *a; - struct archive_entry *entry; - - mydata = malloc(sizeof(struct mydata)); - a = archive_read_new(); - mydata->name = name; - archive_read_support_filter_all(a); - archive_read_support_format_all(a); - archive_read_open(a, mydata, myopen, myread, myclose); - while (archive_read_next_header(a, &entry) == ARCHIVE_OK) { - printf("%s\n",archive_entry_pathname(entry)); - archive_read_data_skip(a); - } - archive_read_free(a); - free(mydata); - } - - la_ssize_t - myread(struct archive *a, void *client_data, const void **buff) - { - struct mydata *mydata = client_data; - - *buff = mydata->buff; - return (read(mydata->fd, mydata->buff, 10240)); - } - - int - myopen(struct archive *a, void *client_data) - { - struct mydata *mydata = client_data; - - mydata->fd = open(mydata->name, O_RDONLY); - return (mydata->fd >= 0 ? ARCHIVE_OK : ARCHIVE_FATAL); - } - - int - myclose(struct archive *a, void *client_data) - { - struct mydata *mydata = client_data; - - if (mydata->fd > 0) - close(mydata->fd); - return (ARCHIVE_OK); - } - -SEE ALSO - tar(1), archive_read_data(3), archive_read_extract(3), - archive_read_filter(3), archive_read_format(3), archive_read_header(3), - archive_read_new(3), archive_read_open(3), archive_read_set_options(3), - archive_util(3), libarchive(3), tar(5) - -HISTORY - The libarchive library first appeared in FreeBSD 5.3. - -AUTHORS - The libarchive library was written by Tim Kientzle . - -BUGS - Many traditional archiver programs treat empty files as valid empty ar†- chives. For example, many implementations of tar(1) allow you to append - entries to an empty file. Of course, it is impossible to determine the - format of an empty file by inspecting the contents, so this library - treats empty files as having a special “empty†format. - -BSD February 2, 2012 BSD diff --git a/thirdparty/libarchive/doc/text/archive_read_add_passphrase.3.txt b/thirdparty/libarchive/doc/text/archive_read_add_passphrase.3.txt deleted file mode 100644 index f3075b726..000000000 --- a/thirdparty/libarchive/doc/text/archive_read_add_passphrase.3.txt +++ /dev/null @@ -1,35 +0,0 @@ -ARCHIVE_READ_ADD_PASS... BSD Library Functions Manual ARCHIVE_READ_ADD_PASS... - -NAME - archive_read_add_passphrase, archive_read_set_passphrase_callback — func†- tions for reading encrypted archives - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - int - archive_read_add_passphrase(struct archive *, const char *passphrase); - - int - archive_read_set_passphrase_callback(struct archive *, void *client_data, - archive_passphrase_callback *); - -DESCRIPTION - archive_read_add_passphrase() - Register passphrases for reading an encryption archive. If - passphrase is NULL or empty, this function will do nothing and - ARCHIVE_FAILED will be returned. Otherwise, ARCHIVE_OK will be - returned. - - archive_read_set_passphrase_callback() - Register a callback function that will be invoked to get a - passphrase for decryption after trying all the passphrases regis†- tered by the archive_read_add_passphrase() function failed. - -SEE ALSO - tar(1), archive_read(3), archive_read_set_options(3), libarchive(3) - -BSD September 14, 2014 BSD diff --git a/thirdparty/libarchive/doc/text/archive_read_data.3.txt b/thirdparty/libarchive/doc/text/archive_read_data.3.txt deleted file mode 100644 index 14603ed12..000000000 --- a/thirdparty/libarchive/doc/text/archive_read_data.3.txt +++ /dev/null @@ -1,73 +0,0 @@ -ARCHIVE_READ_DATA(3) BSD Library Functions Manual ARCHIVE_READ_DATA(3) - -NAME - archive_read_data, archive_read_data_block, archive_read_data_skip, - archive_read_data_into_fd — functions for reading streaming archives - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - la_ssize_t - archive_read_data(struct archive *, void *buff, size_t len); - - int - archive_read_data_block(struct archive *, const void **buff, size_t *len, - off_t *offset); - - int - archive_read_data_skip(struct archive *); - - int - archive_read_data_into_fd(struct archive *, int fd); - -DESCRIPTION - archive_read_data() - Read data associated with the header just read. Internally, this - is a convenience function that calls archive_read_data_block() - and fills any gaps with nulls so that callers see a single con†- tinuous stream of data. - archive_read_data_block() - Return the next available block of data for this entry. Unlike - archive_read_data(), the archive_read_data_block() function - avoids copying data and allows you to correctly handle sparse - files, as supported by some archive formats. The library guaran†- tees that offsets will increase and that blocks will not overlap. - Note that the blocks returned from this function can be much - larger than the block size read from disk, due to compression and - internal buffer optimizations. - archive_read_data_skip() - A convenience function that repeatedly calls - archive_read_data_block() to skip all of the data for this ar†- chive entry. Note that this function is invoked automatically by - archive_read_next_header2() if the previous entry was not com†- pletely consumed. - archive_read_data_into_fd() - A convenience function that repeatedly calls - archive_read_data_block() to copy the entire entry to the pro†- vided file descriptor. - -RETURN VALUES - Most functions return zero on success, non-zero on error. The possible - return codes include: ARCHIVE_OK (the operation succeeded), ARCHIVE_WARN - (the operation succeeded but a non-critical error was encountered), - ARCHIVE_EOF (end-of-archive was encountered), ARCHIVE_RETRY (the opera†- tion failed but can be retried), and ARCHIVE_FATAL (there was a fatal er†- ror; the archive should be closed immediately). - - archive_read_data() returns a count of bytes actually read or zero at the - end of the entry. On error, a value of ARCHIVE_FATAL, ARCHIVE_WARN, or - ARCHIVE_RETRY is returned. - -ERRORS - Detailed error codes and textual descriptions are available from the - archive_errno() and archive_error_string() functions. - -SEE ALSO - tar(1), archive_read(3), archive_read_extract(3), archive_read_filter(3), - archive_read_format(3), archive_read_header(3), archive_read_open(3), - archive_read_set_options(3), archive_util(3), libarchive(3), tar(5) - -BSD February 2, 2012 BSD diff --git a/thirdparty/libarchive/doc/text/archive_read_disk.3.txt b/thirdparty/libarchive/doc/text/archive_read_disk.3.txt deleted file mode 100644 index 3600d9d26..000000000 --- a/thirdparty/libarchive/doc/text/archive_read_disk.3.txt +++ /dev/null @@ -1,320 +0,0 @@ -ARCHIVE_READ_DISK(3) BSD Library Functions Manual ARCHIVE_READ_DISK(3) - -NAME - archive_read_disk_new, archive_read_disk_open, archive_read_disk_open_w, - archive_read_disk_set_behavior, archive_read_disk_set_symlink_logical, - archive_read_disk_set_symlink_physical, - archive_read_disk_set_symlink_hybrid, archive_read_disk_entry_from_file, - archive_read_disk_gname, archive_read_disk_uname, - archive_read_disk_set_uname_lookup, archive_read_disk_set_gname_lookup, - archive_read_disk_set_standard_lookup, archive_read_disk_descend, - archive_read_disk_can_descend, archive_read_disk_current_filesystem, - archive_read_disk_current_filesystem_is_synthetic, - archive_read_disk_current_filesystem_is_remote, - archive_read_disk_set_matching, - archive_read_disk_set_metadata_filter_callback, — functions for reading - objects from disk - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - struct archive * - archive_read_disk_new(void); - - int - archive_read_disk_open(struct archive *, const char *); - - int - archive_read_disk_open_w(struct archive *, const wchar_t *); - - int - archive_read_disk_set_behavior(struct archive *, int); - - int - archive_read_disk_set_symlink_logical(struct archive *); - - int - archive_read_disk_set_symlink_physical(struct archive *); - - int - archive_read_disk_set_symlink_hybrid(struct archive *); - - const char * - archive_read_disk_gname(struct archive *, gid_t); - - const char * - archive_read_disk_uname(struct archive *, uid_t); - - int - archive_read_disk_set_gname_lookup(struct archive *, void *, - const char *(*lookup)(void *, gid_t), void (*cleanup)(void *)); - - int - archive_read_disk_set_uname_lookup(struct archive *, void *, - const char *(*lookup)(void *, uid_t), void (*cleanup)(void *)); - - int - archive_read_disk_set_standard_lookup(struct archive *); - - int - archive_read_disk_entry_from_file(struct archive *, - struct archive_entry *, int fd, const struct stat *); - - int - archive_read_disk_descend(struct archive *); - - int - archive_read_disk_can_descend(struct archive *); - - int - archive_read_disk_current_filesystem(struct archive *); - - int - archive_read_disk_current_filesystem_is_synthetic(struct archive *); - - int - archive_read_disk_current_filesystem_is_remote(struct archive *); - - int - archive_read_disk_set_matching(struct archive *, struct archive *, - void (*excluded_func)(struct archive *, void *, struct archive entry *), - void *); - - int - archive_read_disk_set_metadata_filter_callback(struct archive *, - int (*metadata_filter_func)(struct archive *, void*, struct archive_entry *), - void *); - -DESCRIPTION - These functions provide an API for reading information about objects on - disk. In particular, they provide an interface for populating struct - archive_entry objects. - - archive_read_disk_new() - Allocates and initializes a struct archive object suitable for - reading object information from disk. - - archive_read_disk_open() - Opens the file or directory from the given path and prepares the - struct archive to read it from disk. - - archive_read_disk_open_w() - Opens the file or directory from the given path as a wide charac†- ter string and prepares the struct archive to read it from disk. - - archive_read_disk_set_behavior() - Configures various behavior options when reading entries from - disk. The flags field consists of a bitwise OR of one or more of - the following values: - ARCHIVE_READDISK_HONOR_NODUMP - Skip files and directories with the nodump file attribute - (file flag) set. By default, the nodump file attribute - is ignored. - ARCHIVE_READDISK_MAC_COPYFILE - Mac OS X specific. Read metadata (ACLs and extended at†- tributes) with copyfile(3). By default, metadata is read - using copyfile(3). - ARCHIVE_READDISK_NO_ACL - Do not read Access Control Lists. By default, ACLs are - read from disk. - ARCHIVE_READDISK_NO_FFLAGS - Do not read file attributes (file flags). By default, - file attributes are read from disk. See chattr(1) - (Linux) or chflags(1) (FreeBSD, Mac OS X) for more infor†- mation on file attributes. - ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS - Do not traverse mount points. By default, mount points - are traversed. - ARCHIVE_READDISK_NO_XATTR - Do not read extended file attributes (xattrs). By de†- fault, extended file attributes are read from disk. See - xattr(7) (Linux), xattr(2) (Mac OS X), or getextattr(8) - (FreeBSD) for more information on extended file at†- tributes. - ARCHIVE_READDISK_RESTORE_ATIME - Restore access time of traversed files. By default, ac†- cess time of traversed files is not restored. - ARCHIVE_READDISK_NO_SPARSE - Do not read sparse file information. By default, sparse - file information is read from disk. - - archive_read_disk_set_symlink_logical(), - archive_read_disk_set_symlink_physical(), - archive_read_disk_set_symlink_hybrid() - This sets the mode used for handling symbolic links. The - “logical†mode follows all symbolic links. The “physical†mode - does not follow any symbolic links. The “hybrid†mode currently - behaves identically to the “logical†mode. - - archive_read_disk_gname(), archive_read_disk_uname() - Returns a user or group name given a gid or uid value. By de†- fault, these always return a NULL string. - - archive_read_disk_set_gname_lookup(), - archive_read_disk_set_uname_lookup() - These allow you to override the functions used for user and group - name lookups. You may also provide a void * pointer to a private - data structure and a cleanup function for that data. The cleanup - function will be invoked when the struct archive object is de†- stroyed or when new lookup functions are registered. - - archive_read_disk_set_standard_lookup() - This convenience function installs a standard set of user and - group name lookup functions. These functions use getpwuid(3) and - getgrgid(3) to convert ids to names, defaulting to NULL if the - names cannot be looked up. These functions also implement a sim†- ple memory cache to reduce the number of calls to getpwuid(3) and - getgrgid(3). - - archive_read_disk_entry_from_file() - Populates a struct archive_entry object with information about a - particular file. The archive_entry object must have already been - created with archive_entry_new(3) and at least one of the source - path or path fields must already be set. (If both are set, the - source path will be used.) - - Information is read from disk using the path name from the struct - archive_entry object. If a file descriptor is provided, some in†- formation will be obtained using that file descriptor, on plat†- forms that support the appropriate system calls. - - If a pointer to a struct stat is provided, information from that - structure will be used instead of reading from the disk where ap†- propriate. This can provide performance benefits in scenarios - where struct stat information has already been read from the disk - as a side effect of some other operation. (For example, direc†- tory traversal libraries often provide this information.) - - Where necessary, user and group ids are converted to user and - group names using the currently-registered lookup functions - above. This affects the file ownership fields and ACL values in - the struct archive_entry object. - - archive_read_disk_descend() - If the current entry can be descended, this function will mark - the directory as the next entry for archive_read_header(3) to - visit. - - archive_read_disk_can_descend() - Returns 1 if the current entry is an unvisited directory and 0 - otherwise. - - archive_read_disk_current_filesystem() - Returns the index of the most recent filesystem entry that has - been visited through archive_read_disk - - archive_read_disk_current_filesystem_is_synthetic() - Returns 1 if the current filesystem is a virtual filesystem. Re†- turns 0 if the current filesystem is not a virtual filesystem. - Returns -1 if it is unknown. - - archive_read_disk_current_filesystem_is_remote() - Returns 1 if the current filesystem is a remote filesystem. Re†- turns 0 if the current filesystem is not a remote filesystem. Re†- turns -1 if it is unknown. - - archive_read_disk_set_matching() - Allows the caller to set struct archive *_ma to compare each en†- try during archive_read_header(3) calls. If matched based on - calls to archive_match_path_excluded, - archive_match_time_excluded, or archive_match_owner_excluded, - then the callback function specified by the _excluded_func param†- eter will execute. This function will recieve data provided to - the fourth parameter, void *_client_data. - - archive_read_disk_set_metadata_filter_callback() - Allows the caller to set a callback function during calls to - archive_read_header(3) to filter out metadata for each entry. The - callback function recieves the struct archive object, void* cus†- tom filter data, and the struct archive_entry. If the callback - function returns an error, ARCHIVE_RETRY will be returned and the - entry will not be further processed. - More information about the struct archive object and the overall design - of the library can be found in the libarchive(3) overview. - -EXAMPLES - The following illustrates basic usage of the library by showing how to - use it to copy an item on disk into an archive. - - void - file_to_archive(struct archive *a, const char *name) - { - char buff[8192]; - size_t bytes_read; - struct archive *ard; - struct archive_entry *entry; - int fd; - - ard = archive_read_disk_new(); - archive_read_disk_set_standard_lookup(ard); - entry = archive_entry_new(); - fd = open(name, O_RDONLY); - if (fd < 0) - return; - archive_entry_copy_pathname(entry, name); - archive_read_disk_entry_from_file(ard, entry, fd, NULL); - archive_write_header(a, entry); - while ((bytes_read = read(fd, buff, sizeof(buff))) > 0) - archive_write_data(a, buff, bytes_read); - archive_write_finish_entry(a); - archive_read_free(ard); - archive_entry_free(entry); - } - -RETURN VALUES - Most functions return ARCHIVE_OK (zero) on success, or one of several - negative error codes for errors. Specific error codes include: - ARCHIVE_RETRY for operations that might succeed if retried, ARCHIVE_WARN - for unusual conditions that do not prevent further operations, and - ARCHIVE_FATAL for serious errors that make remaining operations impossi†- ble. - - archive_read_disk_new() returns a pointer to a newly-allocated struct - archive object or NULL if the allocation failed for any reason. - - archive_read_disk_gname() and archive_read_disk_uname() return const char - * pointers to the textual name or NULL if the lookup failed for any rea†- son. The returned pointer points to internal storage that may be reused - on the next call to either of these functions; callers should copy the - string if they need to continue accessing it. - -ERRORS - Detailed error codes and textual descriptions are available from the - archive_errno() and archive_error_string() functions. - -SEE ALSO - tar(1), archive_read(3), archive_util(3), archive_write(3), - archive_write_disk(3), libarchive(3) - -HISTORY - The libarchive library first appeared in FreeBSD 5.3. The - archive_read_disk interface was added to libarchive 2.6 and first ap†- peared in FreeBSD 8.0. - -AUTHORS - The libarchive library was written by Tim Kientzle - . - -BUGS - The “standard†user name and group name lookup functions are not the de†- faults because getgrgid(3) and getpwuid(3) are sometimes too large for - particular applications. The current design allows the application au†- thor to use a more compact implementation when appropriate. - - The full list of metadata read from disk by - archive_read_disk_entry_from_file() is necessarily system-dependent. - - The archive_read_disk_entry_from_file() function reads as much informa†- tion as it can from disk. Some method should be provided to limit this - so that clients who do not need ACLs, for instance, can avoid the extra - work needed to look up such information. - - This API should provide a set of methods for walking a directory tree. - That would make it a direct parallel of the archive_read(3) API. When - such methods are implemented, the “hybrid†symbolic link mode will make - sense. - -BSD April 3, 2017 BSD diff --git a/thirdparty/libarchive/doc/text/archive_read_extract.3.txt b/thirdparty/libarchive/doc/text/archive_read_extract.3.txt deleted file mode 100644 index db60036e3..000000000 --- a/thirdparty/libarchive/doc/text/archive_read_extract.3.txt +++ /dev/null @@ -1,73 +0,0 @@ -ARCHIVE_READ_EXTRACT(3) BSD Library Functions Manual ARCHIVE_READ_EXTRACT(3) - -NAME - archive_read_extract, archive_read_extract2, - archive_read_extract_set_progress_callback — functions for reading - streaming archives - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - int - archive_read_extract(struct archive *, struct archive_entry *, - int flags); - - int - archive_read_extract2(struct archive *src, struct archive_entry *, - struct archive *dest); - - void - archive_read_extract_set_progress_callback(struct archive *, - void (*func)(void *), void *user_data); - -DESCRIPTION - archive_read_extract(), archive_read_extract_set_skip_file() - A convenience function that wraps the corresponding - archive_write_disk(3) interfaces. The first call to - archive_read_extract() creates a restore object using - archive_write_disk_new(3) and - archive_write_disk_set_standard_lookup(3), then transparently in†- vokes archive_write_disk_set_options(3), archive_write_header(3), - archive_write_data(3), and archive_write_finish_entry(3) to cre†- ate the entry on disk and copy data into it. The flags argument - is passed unmodified to archive_write_disk_set_options(3). - archive_read_extract2() - This is another version of archive_read_extract() that allows you - to provide your own restore object. In particular, this allows - you to override the standard lookup functions using - archive_write_disk_set_group_lookup(3), and - archive_write_disk_set_user_lookup(3). Note that - archive_read_extract2() does not accept a flags argument; you - should use archive_write_disk_set_options() to set the restore - options yourself. - archive_read_extract_set_progress_callback() - Sets a pointer to a user-defined callback that can be used for - updating progress displays during extraction. The progress func†- tion will be invoked during the extraction of large regular - files. The progress function will be invoked with the pointer - provided to this call. Generally, the data pointed to should in†- clude a reference to the archive object and the archive_entry ob†- ject so that various statistics can be retrieved for the progress - display. - -RETURN VALUES - Most functions return zero on success, non-zero on error. The possible - return codes include: ARCHIVE_OK (the operation succeeded), ARCHIVE_WARN - (the operation succeeded but a non-critical error was encountered), - ARCHIVE_EOF (end-of-archive was encountered), ARCHIVE_RETRY (the opera†- tion failed but can be retried), and ARCHIVE_FATAL (there was a fatal er†- ror; the archive should be closed immediately). - -ERRORS - Detailed error codes and textual descriptions are available from the - archive_errno() and archive_error_string() functions. - -SEE ALSO - tar(1), archive_read(3), archive_read_data(3), archive_read_filter(3), - archive_read_format(3), archive_read_open(3), - archive_read_set_options(3), archive_util(3), libarchive(3), tar(5) - -BSD February 2, 2012 BSD diff --git a/thirdparty/libarchive/doc/text/archive_read_filter.3.txt b/thirdparty/libarchive/doc/text/archive_read_filter.3.txt deleted file mode 100644 index 01b6c9712..000000000 --- a/thirdparty/libarchive/doc/text/archive_read_filter.3.txt +++ /dev/null @@ -1,124 +0,0 @@ -ARCHIVE_READ_FILTER(3) BSD Library Functions Manual ARCHIVE_READ_FILTER(3) - -NAME - archive_read_support_filter_all, archive_read_support_filter_bzip2, - archive_read_support_filter_compress, archive_read_support_filter_gzip, - archive_read_support_filter_lz4, archive_read_support_filter_lzma, - archive_read_support_filter_none, archive_read_support_filter_rpm, - archive_read_support_filter_uu, archive_read_support_filter_xz, - archive_read_support_filter_zstd, archive_read_support_filter_program, - archive_read_support_filter_program_signature — functions for reading - streaming archives - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - int - archive_read_support_filter_all(struct archive *); - - int - archive_read_support_filter_by_code(struct archive *, int); - - int - archive_read_support_filter_bzip2(struct archive *); - - int - archive_read_support_filter_compress(struct archive *); - - int - archive_read_support_filter_grzip(struct archive *); - - int - archive_read_support_filter_gzip(struct archive *); - - int - archive_read_support_filter_lrzip(struct archive *); - - int - archive_read_support_filter_lz4(struct archive *); - - int - archive_read_support_filter_lzma(struct archive *); - - int - archive_read_support_filter_lzop(struct archive *); - - int - archive_read_support_filter_none(struct archive *); - - int - archive_read_support_filter_rpm(struct archive *); - - int - archive_read_support_filter_uu(struct archive *); - - int - archive_read_support_filter_xz(struct archive *); - - int - archive_read_support_filter_zstd(struct archive *); - - int - archive_read_support_filter_program(struct archive *, const char *cmd); - - int - archive_read_support_filter_program_signature(struct archive *, - const char *cmd, const void *signature, size_t signature_length); - -DESCRIPTION - archive_read_support_filter_bzip2(), - archive_read_support_filter_compress(), - archive_read_support_filter_grzip(), - archive_read_support_filter_gzip(), - archive_read_support_filter_lrzip(), - archive_read_support_filter_lz4(), - archive_read_support_filter_lzma(), - archive_read_support_filter_lzop(), - archive_read_support_filter_none(), - archive_read_support_filter_rpm(), - archive_read_support_filter_uu(), - archive_read_support_filter_xz(), - archive_read_support_filter_zstd(), - Enables auto-detection code and decompression support for the - specified compression. These functions may fall back on external - programs if an appropriate library was not available at build - time. Decompression using an external program is usually slower - than decompression through built-in libraries. Note that “none†- is always enabled by default. - archive_read_support_filter_all() - Enables all available decompression filters. - archive_read_support_filter_by_code() - Enables a single filter specified by the filter code. This func†- tion does not work with ARCHIVE_FILTER_PROGRAM. Note: In stati†- cally-linked executables, this will cause your program to include - support for every filter. If executable size is a concern, you - may wish to avoid using this function. - archive_read_support_filter_program() - Data is fed through the specified external program before being - dearchived. Note that this disables automatic detection of the - compression format, so it makes no sense to specify this in con†- junction with any other decompression option. - archive_read_support_filter_program_signature() - This feeds data through the specified external program but only - if the initial bytes of the data match the specified signature - value. - -RETURN VALUES - These functions return ARCHIVE_OK if the compression is fully supported, - ARCHIVE_WARN if the compression is supported only through an external - program. - - archive_read_support_filter_none() always succeeds. - -ERRORS - Detailed error codes and textual descriptions are available from the - archive_errno() and archive_error_string() functions. - -SEE ALSO - archive_read(3), archive_read_data(3), archive_read_format(3), - archive_read_format(3), libarchive(3) - -BSD June 9, 2020 BSD diff --git a/thirdparty/libarchive/doc/text/archive_read_format.3.txt b/thirdparty/libarchive/doc/text/archive_read_format.3.txt deleted file mode 100644 index 934c00555..000000000 --- a/thirdparty/libarchive/doc/text/archive_read_format.3.txt +++ /dev/null @@ -1,129 +0,0 @@ -ARCHIVE_READ_FORMAT(3) BSD Library Functions Manual ARCHIVE_READ_FORMAT(3) - -NAME - archive_read_support_format_7zip, archive_read_support_format_all, - archive_read_support_format_ar, archive_read_support_format_by_code, - archive_read_support_format_cab, archive_read_support_format_cpio, - archive_read_support_format_empty, archive_read_support_format_iso9660, - archive_read_support_format_lha, archive_read_support_format_mtree, - archive_read_support_format_rar, archive_read_support_format_raw, - archive_read_support_format_tar, archive_read_support_format_xar, - archive_read_support_format_zip — functions for reading streaming ar†- chives - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - int - archive_read_support_format_7zip(struct archive *); - - int - archive_read_support_format_all(struct archive *); - - int - archive_read_support_format_ar(struct archive *); - - int - archive_read_support_format_by_code(struct archive *, int); - - int - archive_read_support_format_cab(struct archive *); - - int - archive_read_support_format_cpio(struct archive *); - - int - archive_read_support_format_empty(struct archive *); - - int - archive_read_support_format_iso9660(struct archive *); - - int - archive_read_support_format_lha(struct archive *); - - int - archive_read_support_format_mtree(struct archive *); - - int - archive_read_support_format_rar(struct archive *); - - int - archive_read_support_format_raw(struct archive *); - - int - archive_read_support_format_tar(struct archive *); - - int - archive_read_support_format_xar(struct archive *); - - int - archive_read_support_format_zip(struct archive *); - -DESCRIPTION - archive_read_support_format_7zip(), archive_read_support_format_ar(), - archive_read_support_format_cab(), - archive_read_support_format_cpio(), - archive_read_support_format_iso9660(), - archive_read_support_format_lha(), - archive_read_support_format_mtree(), - archive_read_support_format_rar(), - archive_read_support_format_raw(), - archive_read_support_format_tar(), - archive_read_support_format_xar(), - archive_read_support_format_zip() - Enables support---including auto-detection code---for the speci†- fied archive format. For example, - archive_read_support_format_tar() enables support for a variety - of standard tar formats, old-style tar, ustar, pax interchange - format, and many common variants. - archive_read_support_format_all() - Enables support for all available formats except the “raw†format - (see below). - archive_read_support_format_by_code() - Enables a single format specified by the format code. This can - be useful when reading a single archive twice; use - archive_format() after reading the first time and pass the re†- sulting code to this function to selectively enable only the nec†- essary format support. Note: In statically-linked executables, - this will cause your program to include support for every format. - If executable size is a concern, you may wish to avoid using this - function. - archive_read_support_format_empty() - Enables support for treating empty files as empty archives. Be†- cause empty files are valid for several different formats, it is - not possible to accurately determine a format for an empty file - based purely on contents. So empty files are treated by - libarchive as a distinct format. - archive_read_support_format_raw() - The “raw†format handler allows libarchive to be used to read ar†- bitrary data. It treats any data stream as an archive with a - single entry. The pathname of this entry is “dataâ€; all other - entry fields are unset. This is not enabled by - archive_read_support_format_all() in order to avoid erroneous - handling of damaged archives. - -RETURN VALUES - These functions return ARCHIVE_OK on success, or ARCHIVE_FATAL. - -ERRORS - Detailed error codes and textual descriptions are available from the - archive_errno() and archive_error_string() functions. - -SEE ALSO - tar(1), archive_read_data(3), archive_read_filter(3), - archive_read_set_options(3), archive_util(3), libarchive(3), tar(5) - -BUGS - Many traditional archiver programs treat empty files as valid empty ar†- chives. For example, many implementations of tar(1) allow you to append - entries to an empty file. Of course, it is impossible to determine the - format of an empty file by inspecting the contents, so this library - treats empty files as having a special “empty†format. - - Using the “raw†handler together with any other handler will often work - but can produce surprising results. - -BSD February 2, 2012 BSD diff --git a/thirdparty/libarchive/doc/text/archive_read_free.3.txt b/thirdparty/libarchive/doc/text/archive_read_free.3.txt deleted file mode 100644 index f0f66a723..000000000 --- a/thirdparty/libarchive/doc/text/archive_read_free.3.txt +++ /dev/null @@ -1,52 +0,0 @@ -ARCHIVE_READ_FREE(3) BSD Library Functions Manual ARCHIVE_READ_FREE(3) - -NAME - archive_read_close, archive_read_finish, archive_read_free — functions - for reading streaming archives - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - int - archive_read_close(struct archive *); - - int - archive_read_finish(struct archive *); - - int - archive_read_free(struct archive *); - -DESCRIPTION - archive_read_close() - Complete the archive and invoke the close callback. - archive_read_finish() - This is a deprecated synonym for archive_read_free(). The new - name was introduced with libarchive 3.0. Applications that need - to compile with either libarchive 2 or libarchive 3 should con†- tinue to use the archive_read_finish() name. Both names will be - supported until libarchive 4.0 is released, which is not expected - to occur earlier than 2013. - archive_read_free() - Invokes archive_read_close() if it was not invoked manually, then - release all resources. Note: In libarchive 1.x, this function - was declared to return void, which made it impossible to detect - certain errors when archive_read_close() was invoked implicitly - from this function. The declaration is corrected beginning with - libarchive 2.0. - -RETURN VALUES - These functions return ARCHIVE_OK on success, or ARCHIVE_FATAL. - -ERRORS - Detailed error codes and textual descriptions are available from the - archive_errno() and archive_error_string() functions. - -SEE ALSO - archive_read_data(3), archive_read_filter(3), archive_read_format(3), - archive_read_new(3), archive_read_open(3), archive_read_set_options(3), - archive_util(3), libarchive(3) - -BSD February 2, 2012 BSD diff --git a/thirdparty/libarchive/doc/text/archive_read_header.3.txt b/thirdparty/libarchive/doc/text/archive_read_header.3.txt deleted file mode 100644 index 6a2794620..000000000 --- a/thirdparty/libarchive/doc/text/archive_read_header.3.txt +++ /dev/null @@ -1,45 +0,0 @@ -ARCHIVE_READ_HEADER(3) BSD Library Functions Manual ARCHIVE_READ_HEADER(3) - -NAME - archive_read_next_header, archive_read_next_header2 — functions for read†- ing streaming archives - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - int - archive_read_next_header(struct archive *, struct archive_entry **); - - int - archive_read_next_header2(struct archive *, struct archive_entry *); - -DESCRIPTION - archive_read_next_header() - Read the header for the next entry and return a pointer to a - struct archive_entry. This is a convenience wrapper around - archive_read_next_header2() that reuses an internal struct - archive_entry object for each request. - archive_read_next_header2() - Read the header for the next entry and populate the provided - struct archive_entry. - -RETURN VALUES - These functions return ARCHIVE_OK (the operation succeeded), ARCHIVE_WARN - (the operation succeeded but a non-critical error was encountered), - ARCHIVE_EOF (end-of-archive was encountered), ARCHIVE_RETRY (the opera†- tion failed but can be retried), and ARCHIVE_FATAL (there was a fatal er†- ror; the archive should be closed immediately). - -ERRORS - Detailed error codes and textual descriptions are available from the - archive_errno() and archive_error_string() functions. - -SEE ALSO - tar(1), archive_read(3), archive_read_data(3), archive_read_extract(3), - archive_read_filter(3), archive_read_format(3), archive_read_open(3), - archive_read_set_options(3), archive_util(3), libarchive(3), tar(5) - -BSD February 2, 2012 BSD diff --git a/thirdparty/libarchive/doc/text/archive_read_new.3.txt b/thirdparty/libarchive/doc/text/archive_read_new.3.txt deleted file mode 100644 index e799af858..000000000 --- a/thirdparty/libarchive/doc/text/archive_read_new.3.txt +++ /dev/null @@ -1,27 +0,0 @@ -ARCHIVE_READ_NEW(3) BSD Library Functions Manual ARCHIVE_READ_NEW(3) - -NAME - archive_read_new — functions for reading streaming archives - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - struct archive * - archive_read_new(void); - -DESCRIPTION - Allocates and initializes a struct archive object suitable for reading - from an archive. NULL is returned on error. - - A complete description of the struct archive object can be found in the - overview manual page for libarchive(3). - -SEE ALSO - tar(1), archive_read_data(3), archive_read_filter(3), - archive_read_format(3), archive_read_set_options(3), archive_util(3), - libarchive(3), tar(5) - -BSD February 2, 2012 BSD diff --git a/thirdparty/libarchive/doc/text/archive_read_open.3.txt b/thirdparty/libarchive/doc/text/archive_read_open.3.txt deleted file mode 100644 index 1288da69d..000000000 --- a/thirdparty/libarchive/doc/text/archive_read_open.3.txt +++ /dev/null @@ -1,130 +0,0 @@ -ARCHIVE_READ_OPEN(3) BSD Library Functions Manual ARCHIVE_READ_OPEN(3) - -NAME - archive_read_open, archive_read_open2, archive_read_open_fd, - archive_read_open_FILE, archive_read_open_filename, - archive_read_open_memory — functions for reading streaming archives - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - int - archive_read_open(struct archive *, void *client_data, - archive_open_callback *, archive_read_callback *, - archive_close_callback *); - - int - archive_read_open2(struct archive *, void *client_data, - archive_open_callback *, archive_read_callback *, - archive_skip_callback *, archive_close_callback *); - - int - archive_read_open_FILE(struct archive *, FILE *file); - - int - archive_read_open_fd(struct archive *, int fd, size_t block_size); - - int - archive_read_open_filename(struct archive *, const char *filename, - size_t block_size); - - int - archive_read_open_memory(struct archive *, const void *buff, - size_t size); - -DESCRIPTION - archive_read_open() - The same as archive_read_open2(), except that the skip callback - is assumed to be NULL. - archive_read_open2() - Freeze the settings, open the archive, and prepare for reading - entries. This is the most generic version of this call, which - accepts four callback functions. Most clients will want to use - archive_read_open_filename(), archive_read_open_FILE(), - archive_read_open_fd(), or archive_read_open_memory() instead. - The library invokes the client-provided functions to obtain raw - bytes from the archive. - archive_read_open_FILE() - Like archive_read_open(), except that it accepts a FILE * - pointer. This function should not be used with tape drives or - other devices that require strict I/O blocking. - archive_read_open_fd() - Like archive_read_open(), except that it accepts a file descrip†- tor and block size rather than a set of function pointers. Note - that the file descriptor will not be automatically closed at end- - of-archive. This function is safe for use with tape drives or - other blocked devices. - archive_read_open_file() - This is a deprecated synonym for archive_read_open_filename(). - archive_read_open_filename() - Like archive_read_open(), except that it accepts a simple file†- name and a block size. A NULL filename represents standard in†- put. This function is safe for use with tape drives or other - blocked devices. - archive_read_open_memory() - Like archive_read_open(), except that it accepts a pointer and - size of a block of memory containing the archive data. - - A complete description of the struct archive and struct archive_entry ob†- jects can be found in the overview manual page for libarchive(3). - -CLIENT CALLBACKS - The callback functions must match the following prototypes: - - typedef la_ssize_t archive_read_callback(struct archive *, - void *client_data, const void **buffer) - - typedef la_int64_t archive_skip_callback(struct archive *, - void *client_data, off_t request) - - typedef int archive_open_callback(struct archive *, void - *client_data) - - typedef int archive_close_callback(struct archive *, void - *client_data) - - The open callback is invoked by archive_open(). It should return - ARCHIVE_OK if the underlying file or data source is successfully opened. - If the open fails, it should call archive_set_error() to register an er†- ror code and message and return ARCHIVE_FATAL. - - The read callback is invoked whenever the library requires raw bytes from - the archive. The read callback should read data into a buffer, set the - const void **buffer argument to point to the available data, and return a - count of the number of bytes available. The library will invoke the read - callback again only after it has consumed this data. The library imposes - no constraints on the size of the data blocks returned. On end-of-file, - the read callback should return zero. On error, the read callback should - invoke archive_set_error() to register an error code and message and re†- turn -1. - - The skip callback is invoked when the library wants to ignore a block of - data. The return value is the number of bytes actually skipped, which - may differ from the request. If the callback cannot skip data, it should - return zero. If the skip callback is not provided (the function pointer - is NULL ), the library will invoke the read function instead and simply - discard the result. A skip callback can provide significant performance - gains when reading uncompressed archives from slow disk drives or other - media that can skip quickly. - - The close callback is invoked by archive_close when the archive process†- ing is complete. The callback should return ARCHIVE_OK on success. On - failure, the callback should invoke archive_set_error() to register an - error code and message and return ARCHIVE_FATAL. - -RETURN VALUES - These functions return ARCHIVE_OK on success, or ARCHIVE_FATAL. - -ERRORS - Detailed error codes and textual descriptions are available from the - archive_errno() and archive_error_string() functions. - -SEE ALSO - tar(1), archive_read(3), archive_read_data(3), archive_read_filter(3), - archive_read_format(3), archive_read_set_options(3), archive_util(3), - libarchive(3), tar(5) - -BSD February 2, 2012 BSD diff --git a/thirdparty/libarchive/doc/text/archive_read_set_options.3.txt b/thirdparty/libarchive/doc/text/archive_read_set_options.3.txt deleted file mode 100644 index 3d1bc0234..000000000 --- a/thirdparty/libarchive/doc/text/archive_read_set_options.3.txt +++ /dev/null @@ -1,157 +0,0 @@ -ARCHIVE_READ_OPTIONS(3) BSD Library Functions Manual ARCHIVE_READ_OPTIONS(3) - -NAME - archive_read_set_filter_option, archive_read_set_format_option, - archive_read_set_option, archive_read_set_options — functions controlling - options for reading archives - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - int - archive_read_set_filter_option(struct archive *, const char *module, - const char *option, const char *value); - - int - archive_read_set_format_option(struct archive *, const char *module, - const char *option, const char *value); - - int - archive_read_set_option(struct archive *, const char *module, - const char *option, const char *value); - - int - archive_read_set_options(struct archive *, const char *options); - -DESCRIPTION - These functions provide a way for libarchive clients to configure spe†- cific read modules. - - archive_read_set_filter_option(), archive_read_set_format_option() - Specifies an option that will be passed to currently-registered - filters (including decompression filters) or format readers. - - If option and value are both NULL, these functions will do noth†- ing and ARCHIVE_OK will be returned. If option is NULL but value - is not, these functions will do nothing and ARCHIVE_FAILED will - be returned. - - If module is not NULL, option and value will be provided to the - filter or reader named module. The return value will be that of - the module. If there is no such module, ARCHIVE_FAILED will be - returned. - - If module is NULL, option and value will be provided to every - registered module. If any module returns ARCHIVE_FATAL, this - value will be returned immediately. Otherwise, ARCHIVE_OK will - be returned if any module accepts the option, and ARCHIVE_FAILED - in all other cases. - - archive_read_set_option() - Calls archive_read_set_format_option(), then - archive_read_set_filter_option(). If either function returns - ARCHIVE_FATAL, ARCHIVE_FATAL will be returned immediately. Oth†- erwise, greater of the two values will be returned. - - archive_read_set_options() - options is a comma-separated list of options. If options is NULL - or empty, ARCHIVE_OK will be returned immediately. - - Calls archive_read_set_option() with each option in turn. If any - archive_read_set_option() call returns ARCHIVE_FATAL, - ARCHIVE_FATAL will be returned immediately. - - Individual options have one of the following forms: - option=value - The option/value pair will be provided to every module. - Modules that do not accept an option with this name will - ignore it. - option The option will be provided to every module with a value - of “1â€. - !option - The option will be provided to every module with a NULL - value. - module:option=value, module:option, module:!option - As above, but the corresponding option and value will be - provided only to modules whose name matches module. - -OPTIONS - Format cab - hdrcharset - The value is used as a character set name that will be - used when translating file names. - Format cpio - compat-2x - Libarchive 2.x incorrectly encoded Unicode filenames on - some platforms. This option mimics the libarchive 2.x - filename handling so that such archives can be read cor†- rectly. - hdrcharset - The value is used as a character set name that will be - used when translating file names. - pwb When reading a binary CPIO archive, assume that it is in - the original PWB cpio format, and handle file mode bits - accordingly. The default is to assume v7 format. - Format iso9660 - joliet Support Joliet extensions. Defaults to enabled, use - !joliet to disable. - rockridge - Support RockRidge extensions. Defaults to enabled, use - !rockridge to disable. - Format lha - hdrcharset - The value is used as a character set name that will be - used when translating file names. - Format mtree - checkfs - Allow reading information missing from the mtree from the - file system. Disabled by default. - Format rar - hdrcharset - The value is used as a character set name that will be - used when translating file names. - Format tar - compat-2x - Libarchive 2.x incorrectly encoded Unicode filenames on - some platforms. This option mimics the libarchive 2.x - filename handling so that such archives can be read cor†- rectly. - hdrcharset - The value is used as a character set name that will be - used when translating file names. - mac-ext - Support Mac OS metadata extension that records data in - special files beginning with a period and underscore. - Defaults to enabled on Mac OS, disabled on other plat†- forms. Use !mac-ext to disable. - read_concatenated_archives - Ignore zeroed blocks in the archive, which occurs when - multiple tar archives have been concatenated together. - Without this option, only the contents of the first con†- catenated archive would be read. - Format zip - compat-2x - Libarchive 2.x incorrectly encoded Unicode filenames on - some platforms. This option mimics the libarchive 2.x - filename handling so that such archives can be read cor†- rectly. - hdrcharset - The value is used as a character set name that will be - used when translating file names. - ignorecrc32 - Skip the CRC32 check. Mostly used for testing. - mac-ext - Support Mac OS metadata extension that records data in - special files beginning with a period and underscore. - Defaults to enabled on Mac OS, disabled on other plat†- forms. Use !mac-ext to disable. - -ERRORS - Detailed error codes and textual descriptions are available from the - archive_errno() and archive_error_string() functions. - -SEE ALSO - tar(1), archive_read(3), archive_write_set_options(3), libarchive(3) - -BSD January 31, 2020 BSD diff --git a/thirdparty/libarchive/doc/text/archive_util.3.txt b/thirdparty/libarchive/doc/text/archive_util.3.txt deleted file mode 100644 index 01910d747..000000000 --- a/thirdparty/libarchive/doc/text/archive_util.3.txt +++ /dev/null @@ -1,150 +0,0 @@ -ARCHIVE_UTIL(3) BSD Library Functions Manual ARCHIVE_UTIL(3) - -NAME - archive_clear_error, archive_compression, archive_compression_name, - archive_copy_error, archive_errno, archive_error_string, - archive_file_count, archive_filter_code, archive_filter_count, - archive_filter_name, archive_format, archive_format_name, - archive_position, archive_set_error — libarchive utility functions - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - void - archive_clear_error(struct archive *); - - int - archive_compression(struct archive *); - - const char * - archive_compression_name(struct archive *); - - void - archive_copy_error(struct archive *, struct archive *); - - int - archive_errno(struct archive *); - - const char * - archive_error_string(struct archive *); - - int - archive_file_count(struct archive *); - - int - archive_filter_code(struct archive *, int); - - int - archive_filter_count(struct archive *, int); - - const char * - archive_filter_name(struct archive *, int); - - int - archive_format(struct archive *); - - const char * - archive_format_name(struct archive *); - - int64_t - archive_position(struct archive *, int); - - void - archive_set_error(struct archive *, int error_code, const char *fmt, - ...); - -DESCRIPTION - These functions provide access to various information about the struct - archive object used in the libarchive(3) library. - archive_clear_error() - Clears any error information left over from a previous call. Not - generally used in client code. - archive_compression() - Synonym for archive_filter_code(a, 0). - archive_compression_name() - Synonym for archive_filter_name(a, 0). - archive_copy_error() - Copies error information from one archive to another. - archive_errno() - Returns a numeric error code (see errno(2)) indicating the reason - for the most recent error return. Note that this can not be re†- liably used to detect whether an error has occurred. It should - be used only after another libarchive function has returned an - error status. - archive_error_string() - Returns a textual error message suitable for display. The error - message here is usually more specific than that obtained from - passing the result of archive_errno() to strerror(3). - archive_file_count() - Returns a count of the number of files processed by this archive - object. The count is incremented by calls to - archive_write_header(3) or archive_read_next_header(3). - archive_filter_code() - Returns a numeric code identifying the indicated filter. See - archive_filter_count() for details of the numbering. - archive_filter_count() - Returns the number of filters in the current pipeline. For read - archive handles, these filters are added automatically by the au†- tomatic format detection. For write archive handles, these fil†- ters are added by calls to the various - archive_write_add_filter_XXX() functions. Filters in the result†- ing pipeline are numbered so that filter 0 is the filter closest - to the format handler. As a convenience, functions that expect a - filter number will accept -1 as a synonym for the highest-num†- bered filter. - - For example, when reading a uuencoded gzipped tar archive, there - are three filters: filter 0 is the gunzip filter, filter 1 is the - uudecode filter, and filter 2 is the pseudo-filter that wraps the - archive read functions. In this case, requesting - archive_position(a, -1) would be a synonym for - archive_position(a, 2) which would return the number of bytes - currently read from the archive, while archive_position(a, 1) - would return the number of bytes after uudecoding, and - archive_position(a, 0) would return the number of bytes after de†- compression. - archive_filter_name() - Returns a textual name identifying the indicated filter. See - archive_filter_count() for details of the numbering. - archive_format() - Returns a numeric code indicating the format of the current ar†- chive entry. This value is set by a successful call to - archive_read_next_header(). Note that it is common for this - value to change from entry to entry. For example, a tar archive - might have several entries that utilize GNU tar extensions and - several entries that do not. These entries will have different - format codes. - archive_format_name() - A textual description of the format of the current entry. - archive_position() - Returns the number of bytes read from or written to the indicated - filter. In particular, archive_position(a, 0) returns the number - of bytes read or written by the format handler, while - archive_position(a, -1) returns the number of bytes read or writ†- ten to the archive. See archive_filter_count() for details of - the numbering here. - archive_set_error() - Sets the numeric error code and error description that will be - returned by archive_errno() and archive_error_string(). This - function should be used within I/O callbacks to set system-spe†- cific error codes and error descriptions. This function accepts - a printf-like format string and arguments. However, you should - be careful to use only the following printf format specifiers: - “%câ€, “%dâ€, “%jdâ€, “%joâ€, “%juâ€, “%jxâ€, “%ldâ€, “%loâ€, “%luâ€, - “%lxâ€, “%oâ€, “%uâ€, “%sâ€, “%xâ€, “%%â€. Field-width specifiers and - other printf features are not uniformly supported and should not - be used. - -SEE ALSO - archive_read(3), archive_write(3), libarchive(3), printf(3) - -HISTORY - The libarchive library first appeared in FreeBSD 5.3. - -AUTHORS - The libarchive library was written by Tim Kientzle . - -BSD February 2, 2012 BSD diff --git a/thirdparty/libarchive/doc/text/archive_write.3.txt b/thirdparty/libarchive/doc/text/archive_write.3.txt deleted file mode 100644 index 7e54288dc..000000000 --- a/thirdparty/libarchive/doc/text/archive_write.3.txt +++ /dev/null @@ -1,192 +0,0 @@ -ARCHIVE_WRITE(3) BSD Library Functions Manual ARCHIVE_WRITE(3) - -NAME - archive_write — functions for creating archives - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - -DESCRIPTION - These functions provide a complete API for creating streaming archive - files. The general process is to first create the struct archive object, - set any desired options, initialize the archive, append entries, then - close the archive and release all resources. - - Create archive object - See archive_write_new(3). - - To write an archive, you must first obtain an initialized struct archive - object from archive_write_new(). - - Enable filters and formats, configure block size and padding - See archive_write_filter(3), archive_write_format(3) and - archive_write_blocksize(3). - - You can then modify this object for the desired operations with the vari†- ous archive_write_set_XXX() functions. In particular, you will need to - invoke appropriate archive_write_add_XXX() and archive_write_set_XXX() - functions to enable the corresponding compression and format support. - - Set options - See archive_write_set_options(3). - - Open archive - See archive_write_open(3). - - Once you have prepared the struct archive object, you call - archive_write_open() to actually open the archive and prepare it for - writing. There are several variants of this function; the most basic ex†- pects you to provide pointers to several functions that can provide - blocks of bytes from the archive. There are convenience forms that allow - you to specify a filename, file descriptor, FILE * object, or a block of - memory from which to write the archive data. - - Produce archive - See archive_write_header(3) and archive_write_data(3). - - Individual archive entries are written in a three-step process: You first - initialize a struct archive_entry structure with information about the - new entry. At a minimum, you should set the pathname of the entry and - provide a struct stat with a valid st_mode field, which specifies the - type of object and st_size field, which specifies the size of the data - portion of the object. - - Release resources - See archive_write_free(3). - - After all entries have been written, use the archive_write_free() func†- tion to release all resources. - -EXAMPLES - The following sketch illustrates basic usage of the library. In this ex†- ample, the callback functions are simply wrappers around the standard - open(2), write(2), and close(2) system calls. - - #ifdef __linux__ - #define _FILE_OFFSET_BITS 64 - #endif - #include - #include - #include - #include - #include - #include - - struct mydata { - const char *name; - int fd; - }; - - int - myopen(struct archive *a, void *client_data) - { - struct mydata *mydata = client_data; - - mydata->fd = open(mydata->name, O_WRONLY | O_CREAT, 0644); - if (mydata->fd >= 0) - return (ARCHIVE_OK); - else - return (ARCHIVE_FATAL); - } - - la_ssize_t - mywrite(struct archive *a, void *client_data, const void *buff, size_t n) - { - struct mydata *mydata = client_data; - - return (write(mydata->fd, buff, n)); - } - - int - myclose(struct archive *a, void *client_data) - { - struct mydata *mydata = client_data; - - if (mydata->fd > 0) - close(mydata->fd); - return (0); - } - - void - write_archive(const char *outname, const char **filename) - { - struct mydata *mydata = malloc(sizeof(struct mydata)); - struct archive *a; - struct archive_entry *entry; - struct stat st; - char buff[8192]; - int len; - int fd; - - a = archive_write_new(); - mydata->name = outname; - /* Set archive format and filter according to output file extension. - * If it fails, set default format. Platform depended function. - * See supported formats in archive_write_set_format_filter_by_ext.c */ - if (archive_write_set_format_filter_by_ext(a, outname) != ARCHIVE_OK) { - archive_write_add_filter_gzip(a); - archive_write_set_format_ustar(a); - } - archive_write_open(a, mydata, myopen, mywrite, myclose); - while (*filename) { - stat(*filename, &st); - entry = archive_entry_new(); - archive_entry_copy_stat(entry, &st); - archive_entry_set_pathname(entry, *filename); - archive_write_header(a, entry); - if ((fd = open(*filename, O_RDONLY)) != -1) { - len = read(fd, buff, sizeof(buff)); - while (len > 0) { - archive_write_data(a, buff, len); - len = read(fd, buff, sizeof(buff)); - } - close(fd); - } - archive_entry_free(entry); - filename++; - } - archive_write_free(a); - } - - int main(int argc, const char **argv) - { - const char *outname; - argv++; - outname = *argv++; - write_archive(outname, argv); - return 0; - } - -SEE ALSO - tar(1), archive_write_set_options(3), libarchive(3), cpio(5), mtree(5), - tar(5) - -HISTORY - The libarchive library first appeared in FreeBSD 5.3. - -AUTHORS - The libarchive library was written by Tim Kientzle . - -BUGS - There are many peculiar bugs in historic tar implementations that may - cause certain programs to reject archives written by this library. For - example, several historic implementations calculated header checksums in†- correctly and will thus reject valid archives; GNU tar does not fully - support pax interchange format; some old tar implementations required - specific field terminations. - - The default pax interchange format eliminates most of the historic tar - limitations and provides a generic key/value attribute facility for ven†- dor-defined extensions. One oversight in POSIX is the failure to provide - a standard attribute for large device numbers. This library uses - “SCHILY.devminor†and “SCHILY.devmajor†for device numbers that exceed - the range supported by the backwards-compatible ustar header. These keys - are compatible with Joerg Schilling's star archiver. Other implementa†- tions may not recognize these keys and will thus be unable to correctly - restore device nodes with large device numbers from archives created by - this library. - -BSD February 2, 2012 BSD diff --git a/thirdparty/libarchive/doc/text/archive_write_blocksize.3.txt b/thirdparty/libarchive/doc/text/archive_write_blocksize.3.txt deleted file mode 100644 index ed38c909f..000000000 --- a/thirdparty/libarchive/doc/text/archive_write_blocksize.3.txt +++ /dev/null @@ -1,74 +0,0 @@ -ARCHIVE_WRITE_BLOCKSI... BSD Library Functions Manual ARCHIVE_WRITE_BLOCKSI... - -NAME - archive_write_get_bytes_per_block, archive_write_set_bytes_per_block, - archive_write_get_bytes_in_last_block, - archive_write_set_bytes_in_last_block — functions for creating archives - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - int - archive_write_get_bytes_per_block(struct archive *); - - int - archive_write_set_bytes_per_block(struct archive *, int bytes_per_block); - - int - archive_write_get_bytes_in_last_block(struct archive *); - - int - archive_write_set_bytes_in_last_block(struct archive *, int); - -DESCRIPTION - archive_write_set_bytes_per_block() - Sets the block size used for writing the archive data. Every - call to the write callback function, except possibly the last - one, will use this value for the length. The default is to use a - block size of 10240 bytes. Note that a block size of zero will - suppress internal blocking and cause writes to be sent directly - to the write callback as they occur. - - archive_write_get_bytes_per_block() - Retrieve the block size to be used for writing. A value of -1 - here indicates that the library should use default values. A - value of zero indicates that internal blocking is suppressed. - - archive_write_set_bytes_in_last_block() - Sets the block size used for writing the last block. If this - value is zero, the last block will be padded to the same size as - the other blocks. Otherwise, the final block will be padded to a - multiple of this size. In particular, setting it to 1 will cause - the final block to not be padded. For compressed output, any - padding generated by this option is applied only after the com†- pression. The uncompressed data is always unpadded. The default - is to pad the last block to the full block size (note that - archive_write_open_filename() will set this based on the file - type). Unlike the other “set†functions, this function can be - called after the archive is opened. - - archive_write_get_bytes_in_last_block() - Retrieve the currently-set value for last block size. A value of - -1 here indicates that the library should use default values. - -RETURN VALUES - archive_write_set_bytes_per_block() and - archive_write_set_bytes_in_last_block() return ARCHIVE_OK on success, or - ARCHIVE_FATAL. - - archive_write_get_bytes_per_block() and - archive_write_get_bytes_in_last_block() return currently configured block - size (-1 indicates the default block size), or ARCHIVE_FATAL. - -ERRORS - Detailed error codes and textual descriptions are available from the - archive_errno() and archive_error_string() functions. - -SEE ALSO - tar(1), archive_write_set_options(3), libarchive(3), cpio(5), mtree(5), - tar(5) - -BSD February 2, 2012 BSD diff --git a/thirdparty/libarchive/doc/text/archive_write_data.3.txt b/thirdparty/libarchive/doc/text/archive_write_data.3.txt deleted file mode 100644 index a863390b2..000000000 --- a/thirdparty/libarchive/doc/text/archive_write_data.3.txt +++ /dev/null @@ -1,52 +0,0 @@ -ARCHIVE_WRITE_DATA(3) BSD Library Functions Manual ARCHIVE_WRITE_DATA(3) - -NAME - archive_write_data, archive_write_data_block — functions for creating ar†- chives - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - la_ssize_t - archive_write_data(struct archive *, const void *, size_t); - - la_ssize_t - archive_write_data_block(struct archive *, const void *, size_t size, - int64_t offset); - -DESCRIPTION - archive_write_data() - Write data corresponding to the header just written. - - archive_write_data_block() - Write data corresponding to the header just written. This is - like archive_write_data() except that it performs a seek on the - file being written to the specified offset before writing the - data. This is useful when restoring sparse files from archive - formats that support sparse files. Returns number of bytes writ†- ten or -1 on error. (Note: This is currently not supported for - archive_write handles, only for archive_write_disk handles. - -RETURN VALUES - This function returns the number of bytes actually written, or a negative - error code on error. - -ERRORS - Detailed error codes and textual descriptions are available from the - archive_errno() and archive_error_string() functions. - -BUGS - In libarchive 3.x, this function sometimes returns zero on success in†- stead of returning the number of bytes written. Specifically, this oc†- curs when writing to an archive_write_disk handle. Clients should treat - any value less than zero as an error and consider any non-negative value - as success. - -SEE ALSO - tar(1), archive_write_finish_entry(3), archive_write_set_options(3), - libarchive(3), cpio(5), mtree(5), tar(5) - -BSD February 28, 2017 BSD diff --git a/thirdparty/libarchive/doc/text/archive_write_disk.3.txt b/thirdparty/libarchive/doc/text/archive_write_disk.3.txt deleted file mode 100644 index 6716274e3..000000000 --- a/thirdparty/libarchive/doc/text/archive_write_disk.3.txt +++ /dev/null @@ -1,238 +0,0 @@ -ARCHIVE_WRITE_DISK(3) BSD Library Functions Manual ARCHIVE_WRITE_DISK(3) - -NAME - archive_write_disk_new, archive_write_disk_set_options, - archive_write_disk_set_skip_file, archive_write_disk_set_group_lookup, - archive_write_disk_set_standard_lookup, - archive_write_disk_set_user_lookup — functions for creating objects on - disk - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - struct archive * - archive_write_disk_new(void); - - int - archive_write_disk_set_options(struct archive *, int flags); - - int - archive_write_disk_set_skip_file(struct archive *, dev_t, ino_t); - - int - archive_write_disk_set_group_lookup(struct archive *, void *, - gid_t (*)(void *, const char *gname, gid_t gid), - void (*cleanup)(void *)); - - int - archive_write_disk_set_standard_lookup(struct archive *); - - int - archive_write_disk_set_user_lookup(struct archive *, void *, - uid_t (*)(void *, const char *uname, uid_t uid), - void (*cleanup)(void *)); - -DESCRIPTION - These functions provide a complete API for creating objects on disk from - struct archive_entry descriptions. They are most naturally used when ex†- tracting objects from an archive using the archive_read() interface. The - general process is to read struct archive_entry objects from an archive, - then write those objects to a struct archive object created using the - archive_write_disk() family functions. This interface is deliberately - very similar to the archive_write() interface used to write objects to a - streaming archive. - - archive_write_disk_new() - Allocates and initializes a struct archive object suitable for - writing objects to disk. - - archive_write_disk_set_skip_file() - Records the device and inode numbers of a file that should not be - overwritten. This is typically used to ensure that an extraction - process does not overwrite the archive from which objects are be†- ing read. This capability is technically unnecessary but can be - a significant performance optimization in practice. - - archive_write_disk_set_options() - The options field consists of a bitwise OR of one or more of the - following values: - ARCHIVE_EXTRACT_ACL - Attempt to restore Access Control Lists. By default, ex†- tended ACLs are ignored. - ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS - Before removing a file system object prior to replacing - it, clear platform-specific file flags which might pre†- vent its removal. - ARCHIVE_EXTRACT_FFLAGS - Attempt to restore file attributes (file flags). By de†- fault, file attributes are ignored. See chattr(1) - (Linux) or chflags(1) (FreeBSD, Mac OS X) for more infor†- mation on file attributes. - ARCHIVE_EXTRACT_MAC_METADATA - Mac OS X specific. Restore metadata using copyfile(3). - By default, copyfile(3) metadata is ignored. - ARCHIVE_EXTRACT_NO_OVERWRITE - Existing files on disk will not be overwritten. By de†- fault, existing regular files are truncated and overwrit†- ten; existing directories will have their permissions up†- dated; other pre-existing objects are unlinked and recre†- ated from scratch. - ARCHIVE_EXTRACT_OWNER - The user and group IDs should be set on the restored - file. By default, the user and group IDs are not re†- stored. - ARCHIVE_EXTRACT_PERM - Full permissions (including SGID, SUID, and sticky bits) - should be restored exactly as specified, without obeying - the current umask. Note that SUID and SGID bits can only - be restored if the user and group ID of the object on - disk are correct. If ARCHIVE_EXTRACT_OWNER is not speci†- fied, then SUID and SGID bits will only be restored if - the default user and group IDs of newly-created objects - on disk happen to match those specified in the archive - entry. By default, only basic permissions are restored, - and umask is obeyed. - ARCHIVE_EXTRACT_SAFE_WRITES - Extract files atomically, by first creating a unique tem†- porary file and then renaming it to its required destina†- tion name. This avoids a race where an application might - see a partial file (or no file) during extraction. - ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS - Refuse to extract an absolute path. The default is to - not refuse such paths. - ARCHIVE_EXTRACT_SECURE_NODOTDOT - Refuse to extract a path that contains a .. element any†- where within it. The default is to not refuse such - paths. Note that paths ending in .. always cause an er†- ror, regardless of this flag. - ARCHIVE_EXTRACT_SECURE_SYMLINKS - Refuse to extract any object whose final location would - be altered by a symlink on disk. This is intended to - help guard against a variety of mischief caused by ar†- chives that (deliberately or otherwise) extract files - outside of the current directory. The default is not to - perform this check. If ARCHIVE_EXTRACT_UNLINK is speci†- fied together with this option, the library will remove - any intermediate symlinks it finds and return an error - only if such symlink could not be removed. - ARCHIVE_EXTRACT_SPARSE - Scan data for blocks of NUL bytes and try to recreate - them with holes. This results in sparse files, indepen†- dent of whether the archive format supports or uses them. - ARCHIVE_EXTRACT_TIME - The timestamps (mtime, ctime, and atime) should be re†- stored. By default, they are ignored. Note that restor†- ing of atime is not currently supported. - ARCHIVE_EXTRACT_UNLINK - Existing files on disk will be unlinked before any at†- tempt to create them. In some cases, this can prove to - be a significant performance improvement. By default, - existing files are truncated and rewritten, but the file - is not recreated. In particular, the default behavior - does not break existing hard links. - ARCHIVE_EXTRACT_XATTR - Attempt to restore extended file attributes. By default, - they are ignored. See xattr(7) (Linux), xattr(2) (Mac OS - X), or getextattr(8) (FreeBSD) for more information on - extended file attributes. - - archive_write_disk_set_group_lookup(), - archive_write_disk_set_user_lookup() - The struct archive_entry objects contain both names and ids that - can be used to identify users and groups. These names and ids - describe the ownership of the file itself and also appear in ACL - lists. By default, the library uses the ids and ignores the - names, but this can be overridden by registering user and group - lookup functions. To register, you must provide a lookup func†- tion which accepts both a name and id and returns a suitable id. - You may also provide a void * pointer to a private data structure - and a cleanup function for that data. The cleanup function will - be invoked when the struct archive object is destroyed. - - archive_write_disk_set_standard_lookup() - This convenience function installs a standard set of user and - group lookup functions. These functions use getpwnam(3) and - getgrnam(3) to convert names to ids, defaulting to the ids if the - names cannot be looked up. These functions also implement a sim†- ple memory cache to reduce the number of calls to getpwnam(3) and - getgrnam(3). - More information about the struct archive object and the overall design - of the library can be found in the libarchive(3) overview. Many of these - functions are also documented under archive_write(3). - -RETURN VALUES - Most functions return ARCHIVE_OK (zero) on success, or one of several - non-zero error codes for errors. Specific error codes include: - ARCHIVE_RETRY for operations that might succeed if retried, ARCHIVE_WARN - for unusual conditions that do not prevent further operations, and - ARCHIVE_FATAL for serious errors that make remaining operations impossi†- ble. - - archive_write_disk_new() returns a pointer to a newly-allocated struct - archive object. - - archive_write_data() returns a count of the number of bytes actually - written, or -1 on error. - -ERRORS - Detailed error codes and textual descriptions are available from the - archive_errno() and archive_error_string() functions. - -SEE ALSO - tar(1), archive_read(3), archive_write(3), libarchive(3) - -HISTORY - The libarchive library first appeared in FreeBSD 5.3. The - archive_write_disk interface was added to libarchive 2.0 and first ap†- peared in FreeBSD 6.3. - -AUTHORS - The libarchive library was written by Tim Kientzle . - -BUGS - Directories are actually extracted in two distinct phases. Directories - are created during archive_write_header(), but final permissions are not - set until archive_write_close(). This separation is necessary to cor†- rectly handle borderline cases such as a non-writable directory contain†- ing files, but can cause unexpected results. In particular, directory - permissions are not fully restored until the archive is closed. If you - use chdir(2) to change the current directory between calls to - archive_read_extract() or before calling archive_read_close(), you may - confuse the permission-setting logic with the result that directory per†- missions are restored incorrectly. - - The library attempts to create objects with filenames longer than - PATH_MAX by creating prefixes of the full path and changing the current - directory. Currently, this logic is limited in scope; the fixup pass - does not work correctly for such objects and the symlink security check - option disables the support for very long pathnames. - - Restoring the path aa/../bb does create each intermediate directory. In - particular, the directory aa is created as well as the final object bb. - In theory, this can be exploited to create an entire directory hierarchy - with a single request. Of course, this does not work if the - ARCHIVE_EXTRACT_NODOTDOT option is specified. - - Implicit directories are always created obeying the current umask. Ex†- plicit objects are created obeying the current umask unless - ARCHIVE_EXTRACT_PERM is specified, in which case they current umask is - ignored. - - SGID and SUID bits are restored only if the correct user and group could - be set. If ARCHIVE_EXTRACT_OWNER is not specified, then no attempt is - made to set the ownership. In this case, SGID and SUID bits are restored - only if the user and group of the final object happen to match those - specified in the entry. - - The “standard†user-id and group-id lookup functions are not the defaults - because getgrnam(3) and getpwnam(3) are sometimes too large for particu†- lar applications. The current design allows the application author to - use a more compact implementation when appropriate. - - There should be a corresponding archive_read_disk interface that walks a - directory hierarchy and returns archive entry objects. - -BSD January 19, 2020 BSD diff --git a/thirdparty/libarchive/doc/text/archive_write_filter.3.txt b/thirdparty/libarchive/doc/text/archive_write_filter.3.txt deleted file mode 100644 index 60e02d1ea..000000000 --- a/thirdparty/libarchive/doc/text/archive_write_filter.3.txt +++ /dev/null @@ -1,101 +0,0 @@ -ARCHIVE_WRITE_FILTER(3) BSD Library Functions Manual ARCHIVE_WRITE_FILTER(3) - -NAME - archive_write_add_filter_b64encode, archive_write_add_filter_by_name, - archive_write_add_filter_bzip2, archive_write_add_filter_compress, - archive_write_add_filter_grzip, archive_write_add_filter_gzip, - archive_write_add_filter_lrzip, archive_write_add_filter_lz4, - archive_write_add_filter_lzip, archive_write_add_filter_lzma, - archive_write_add_filter_lzop, archive_write_add_filter_none, - archive_write_add_filter_program, archive_write_add_filter_uuencode, - archive_write_add_filter_xz, archive_write_add_filter_zstd — functions - enabling output filters - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - int - archive_write_add_filter_b64encode(struct archive *); - - int - archive_write_add_filter_bzip2(struct archive *); - - int - archive_write_add_filter_compress(struct archive *); - - int - archive_write_add_filter_grzip(struct archive *); - - int - archive_write_add_filter_gzip(struct archive *); - - int - archive_write_add_filter_lrzip(struct archive *); - - int - archive_write_add_filter_lz4(struct archive *); - - int - archive_write_add_filter_lzip(struct archive *); - - int - archive_write_add_filter_lzma(struct archive *); - - int - archive_write_add_filter_lzop(struct archive *); - - int - archive_write_add_filter_none(struct archive *); - - int - archive_write_add_filter_program(struct archive *, const char * cmd); - - int - archive_write_add_filter_uuencode(struct archive *); - - int - archive_write_add_filter_xz(struct archive *); - - int - archive_write_add_filter_zstd(struct archive *); - -DESCRIPTION - archive_write_add_filter_bzip2(), archive_write_add_filter_compress(), - archive_write_add_filter_grzip(), - archive_write_add_filter_gzip(), - archive_write_add_filter_lrzip(), archive_write_add_filter_lz4(), - archive_write_add_filter_lzip(), archive_write_add_filter_lzma(), - archive_write_add_filter_lzop(), archive_write_add_filter_xz(), - archive_write_add_filter_zstd(), - The resulting archive will be compressed as specified. Note that - the compressed output is always properly blocked. - - archive_write_add_filter_b64encode(), - archive_write_add_filter_uuencode(), - The output will be encoded as specified. The encoded output is - always properly blocked. - - archive_write_add_filter_none() - This is never necessary. It is provided only for backwards com†- patibility. - - archive_write_add_filter_program() - The archive will be fed into the specified compression program. - The output of that program is blocked and written to the client - write callbacks. - -RETURN VALUES - These functions return ARCHIVE_OK on success, or ARCHIVE_FATAL. - -ERRORS - Detailed error codes and textual descriptions are available from the - archive_errno() and archive_error_string() functions. - -SEE ALSO - tar(1), archive_write(3), archive_write_format(3), - archive_write_set_options(3), libarchive(3), cpio(5), mtree(5), tar(5) - -BSD August 14, 2014 BSD diff --git a/thirdparty/libarchive/doc/text/archive_write_finish_entry.3.txt b/thirdparty/libarchive/doc/text/archive_write_finish_entry.3.txt deleted file mode 100644 index 399e2e45b..000000000 --- a/thirdparty/libarchive/doc/text/archive_write_finish_entry.3.txt +++ /dev/null @@ -1,37 +0,0 @@ -ARCHIVE_WRITE_FINISH_... BSD Library Functions Manual ARCHIVE_WRITE_FINISH_... - -NAME - archive_write_finish_entry — functions for creating archives - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - int - archive_write_finish_entry(struct archive *); - -DESCRIPTION - Close out the entry just written. In particular, this writes out the fi†- nal padding required by some formats. Ordinarily, clients never need to - call this, as it is called automatically by archive_write_header() and - archive_write_close() as needed. For archive_write_disk handles, this - flushes pending file attribute changes like modification time. - -RETURN VALUES - This function returns ARCHIVE_OK on success, or one of several non-zero - error codes for errors. Specific error codes include: ARCHIVE_RETRY for - operations that might succeed if retried, ARCHIVE_WARN for unusual condi†- tions that do not prevent further operations, and ARCHIVE_FATAL for seri†- ous errors that make remaining operations impossible. - -ERRORS - Detailed error codes and textual descriptions are available from the - archive_errno() and archive_error_string() functions. - -SEE ALSO - tar(1), archive_write_data(3), archive_write_set_options(3), - libarchive(3), cpio(5), mtree(5), tar(5) - -BSD February 28, 2017 BSD diff --git a/thirdparty/libarchive/doc/text/archive_write_format.3.txt b/thirdparty/libarchive/doc/text/archive_write_format.3.txt deleted file mode 100644 index 747d4d496..000000000 --- a/thirdparty/libarchive/doc/text/archive_write_format.3.txt +++ /dev/null @@ -1,160 +0,0 @@ -ARCHIVE_WRITE_FORMAT(3) BSD Library Functions Manual ARCHIVE_WRITE_FORMAT(3) - -NAME - archive_write_set_format, archive_write_set_format_7zip, - archive_write_set_format_ar, archive_write_set_format_ar_bsd, - archive_write_set_format_ar_svr4, archive_write_set_format_by_name, - archive_write_set_format_cpio, archive_write_set_format_cpio_bin, - archive_write_set_format_cpio_newc, archive_write_set_format_cpio_odc, - archive_write_set_format_cpio_pwb, - archive_write_set_format_filter_by_ext, - archive_write_set_format_filter_by_ext_def, - archive_write_set_format_gnutar, archive_write_set_format_iso9660, - archive_write_set_format_mtree, archive_write_set_format_mtree_classic, - archive_write_set_format_mtree_default, archive_write_set_format_pax, - archive_write_set_format_pax_restricted, archive_write_set_format_raw, - archive_write_set_format_shar, archive_write_set_format_shar_dump, - archive_write_set_format_ustar, archive_write_set_format_v7tar, - archive_write_set_format_warc, archive_write_set_format_xar, - archive_write_set_format_zip — functions for creating archives - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - int - archive_write_set_format(struct archive *, int code); - - int - archive_write_set_format_7zip(struct archive *); - - int - archive_write_set_format_ar(struct archive *); - - int - archive_write_set_format_ar_bsd(struct archive *); - - int - archive_write_set_format_ar_svr4(struct archive *); - - int - archive_write_set_format_by_name(struct archive *, const char *name); - - int - archive_write_set_format_cpio(struct archive *); - - int - archive_write_set_format_cpio_bin(struct archive *); - - int - archive_write_set_format_cpio_newc(struct archive *); - - int - archive_write_set_format_cpio_odc(struct archive *); - - int - archive_write_set_format_cpio_pwb(struct archive *); - - int - archive_write_set_format_filter_by_ext(struct archive *, - const char *filename); - - int - archive_write_set_format_filter_by_ext_def(struct archive *, - const char *filename, const char *def_ext); - - int - archive_write_set_format_gnutar(struct archive *); - - int - archive_write_set_format_iso9660(struct archive *); - - int - archive_write_set_format_mtree(struct archive *); - - int - archive_write_set_format_pax(struct archive *); - - int - archive_write_set_format_pax_restricted(struct archive *); - - int - archive_write_set_format_raw(struct archive *); - - int - archive_write_set_format_shar(struct archive *); - - int - archive_write_set_format_shar_dump(struct archive *); - - int - archive_write_set_format_ustar(struct archive *); - - int - archive_write_set_format_v7tar(struct archive *); - - int - archive_write_set_format_warc(struct archive *); - - int - archive_write_set_format_xar(struct archive *); - - int - archive_write_set_format_zip(struct archive *); - -DESCRIPTION - These functions set the format that will be used for the archive. - - The library can write a variety of common archive formats. - - archive_write_set_format() - Sets the format based on the format code (see archive.h for the - full list of format codes). In particular, this can be used in - conjunction with archive_format() to create a new archive with - the same format as an existing archive. - - archive_write_set_format_by_name() - Sets the corresponding format based on the common name. - - archive_write_set_format_filter_by_ext() - archive_write_set_format_filter_by_ext_def() - Sets both filters and format based on the output filename. Sup†- ported extensions: .7z, .zip, .jar, .cpio, .iso, .a, .ar, .tar, - .tgz, .tar.gz, .tar.bz2, .tar.xz - - archive_write_set_format_7zip() archive_write_set_format_ar_bsd() - archive_write_set_format_ar_svr4() - archive_write_set_format_cpio() - archive_write_set_format_cpio_bin() - archive_write_set_format_cpio_newc() - archive_write_set_format_cpio_odc() - archive_write_set_format_cpio_pwb() - archive_write_set_format_gnutar() - archive_write_set_format_iso9660() - archive_write_set_format_mtree() - archive_write_set_format_mtree_classic() - archive_write_set_format_pax() - archive_write_set_format_pax_restricted() - archive_write_set_format_raw() archive_write_set_format_shar() - archive_write_set_format_shar_dump() - archive_write_set_format_ustar() archive_write_set_format_v7tar() - archive_write_set_format_warc() archive_write_set_format_xar() - archive_write_set_format_zip() - Set the format as specified. More details on the formats sup†- ported by libarchive can be found in the libarchive-formats(5) - manual page. - -RETURN VALUES - These functions return ARCHIVE_OK on success, or ARCHIVE_FATAL. - -ERRORS - Detailed error codes and textual descriptions are available from the - archive_errno() and archive_error_string() functions. - -SEE ALSO - tar(1), archive_write(3), archive_write_set_options(3), libarchive(3), - cpio(5), libarchive-formats(5), mtree(5), tar(5) - -BSD February 14, 2013 BSD diff --git a/thirdparty/libarchive/doc/text/archive_write_free.3.txt b/thirdparty/libarchive/doc/text/archive_write_free.3.txt deleted file mode 100644 index 38415eb69..000000000 --- a/thirdparty/libarchive/doc/text/archive_write_free.3.txt +++ /dev/null @@ -1,58 +0,0 @@ -ARCHIVE_WRITE_FREE(3) BSD Library Functions Manual ARCHIVE_WRITE_FREE(3) - -NAME - archive_write_fail, archive_write_close, archive_write_finish, - archive_write_free — functions for creating archives - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - int - archive_write_fail(struct archive *); - - int - archive_write_close(struct archive *); - - int - archive_write_finish(struct archive *); - - int - archive_write_free(struct archive *); - -DESCRIPTION - archive_write_fail() - Always returns ARCHIVE_FATAL. This marks the archive object as - being unusable; after calling this function, the only call that - can succeed is archive_write_free() to release the resources. - This can be used to speed recovery when the archive creation must - be aborted. Note that the created archive is likely to be mal†- formed in this case; - - archive_write_close() - Complete the archive and invoke the close callback. - - archive_write_finish() - This is a deprecated synonym for archive_write_free(). - - archive_write_free() - Invokes archive_write_close() if necessary, then releases all re†- sources. If you need detailed information about - archive_write_close() failures, you should be careful to call it - separately, as you cannot obtain error information after - archive_write_free() returns. - -RETURN VALUES - These functions return ARCHIVE_OK on success, or ARCHIVE_FATAL. - -ERRORS - Detailed error codes and textual descriptions are available from the - archive_errno() and archive_error_string() functions. - -SEE ALSO - tar(1), archive_write_set_options(3), libarchive(3), cpio(5), mtree(5), - tar(5) - -BSD February 2, 2012 BSD diff --git a/thirdparty/libarchive/doc/text/archive_write_header.3.txt b/thirdparty/libarchive/doc/text/archive_write_header.3.txt deleted file mode 100644 index 418594149..000000000 --- a/thirdparty/libarchive/doc/text/archive_write_header.3.txt +++ /dev/null @@ -1,35 +0,0 @@ -ARCHIVE_WRITE_HEADER(3) BSD Library Functions Manual ARCHIVE_WRITE_HEADER(3) - -NAME - archive_write_header — functions for creating archives - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - int - archive_write_header(struct archive *, struct archive_entry *); - -DESCRIPTION - Build and write a header using the data in the provided struct - archive_entry structure. See archive_entry(3) for information on creat†- ing and populating struct archive_entry objects. - -RETURN VALUES - This function returns ARCHIVE_OK on success, or one of the following on - error: ARCHIVE_RETRY for operations that might succeed if retried, - ARCHIVE_WARN for unusual conditions that do not prevent further opera†- tions, and ARCHIVE_FATAL for serious errors that make remaining opera†- tions impossible. - -ERRORS - Detailed error codes and textual descriptions are available from the - archive_errno() and archive_error_string() functions. - -SEE ALSO - tar(1), archive_write_set_options(3), libarchive(3), cpio(5), mtree(5), - tar(5) - -BSD February 2, 2012 BSD diff --git a/thirdparty/libarchive/doc/text/archive_write_new.3.txt b/thirdparty/libarchive/doc/text/archive_write_new.3.txt deleted file mode 100644 index 355d075e8..000000000 --- a/thirdparty/libarchive/doc/text/archive_write_new.3.txt +++ /dev/null @@ -1,26 +0,0 @@ -ARCHIVE_WRITE_NEW(3) BSD Library Functions Manual ARCHIVE_WRITE_NEW(3) - -NAME - archive_write_new — functions for creating archives - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - struct archive * - archive_write_new(void); - -DESCRIPTION - Allocates and initializes a struct archive object suitable for writing a - tar archive. NULL is returned on error. - - A complete description of the struct archive object can be found in the - overview manual page for libarchive(3). - -SEE ALSO - tar(1), archive_write(3), archive_write_set_options(3), libarchive(3), - cpio(5), mtree(5), tar(5) - -BSD February 2, 2012 BSD diff --git a/thirdparty/libarchive/doc/text/archive_write_open.3.txt b/thirdparty/libarchive/doc/text/archive_write_open.3.txt deleted file mode 100644 index 03019b061..000000000 --- a/thirdparty/libarchive/doc/text/archive_write_open.3.txt +++ /dev/null @@ -1,155 +0,0 @@ -ARCHIVE_WRITE_OPEN(3) BSD Library Functions Manual ARCHIVE_WRITE_OPEN(3) - -NAME - archive_write_open, archive_write_open2, archive_write_open_fd, - archive_write_open_FILE, archive_write_open_filename, - archive_write_open_memory — functions for creating archives - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - int - archive_write_open(struct archive *, void *client_data, - archive_open_callback *, archive_write_callback *, - archive_close_callback *); - - int - archive_write_open2(struct archive *, void *client_data, - archive_open_callback *, archive_write_callback *, - archive_close_callback *, archive_free_callback *); - - int - archive_write_open_fd(struct archive *, int fd); - - int - archive_write_open_FILE(struct archive *, FILE *file); - - int - archive_write_open_filename(struct archive *, const char *filename); - - int - archive_write_open_memory(struct archive *, void *buffer, - size_t bufferSize, size_t *outUsed); - -DESCRIPTION - archive_write_open() - Freeze the settings, open the archive, and prepare for writing - entries. This is the most generic form of this function, which - accepts pointers to three callback functions which will be in†- voked by the compression layer to write the constructed archive. - This does not alter the default archive padding. - - archive_write_open2() - Same as archive_write_open() with an additional fourth free call†- back. This function should be preferred to archive_write_open(). - - archive_write_open_fd() - A convenience form of archive_write_open() that accepts a file - descriptor. The archive_write_open_fd() function is safe for use - with tape drives or other block-oriented devices. - - archive_write_open_FILE() - A convenience form of archive_write_open() that accepts a FILE * - pointer. Note that archive_write_open_FILE() is not safe for - writing to tape drives or other devices that require correct - blocking. - - archive_write_open_file() - A deprecated synonym for archive_write_open_filename(). - - archive_write_open_filename() - A convenience form of archive_write_open() that accepts a file†- name. A NULL argument indicates that the output should be writ†- ten to standard output; an argument of “-†will open a file with - that name. If you have not invoked - archive_write_set_bytes_in_last_block(), then - archive_write_open_filename() will adjust the last-block padding - depending on the file: it will enable padding when writing to - standard output or to a character or block device node, it will - disable padding otherwise. You can override this by manually in†- voking archive_write_set_bytes_in_last_block() before calling - archive_write_open2(). The archive_write_open_filename() func†- tion is safe for use with tape drives or other block-oriented de†- vices. - - archive_write_open_memory() - A convenience form of archive_write_open2() that accepts a - pointer to a block of memory that will receive the archive. The - final size_t * argument points to a variable that will be updated - after each write to reflect how much of the buffer is currently - in use. You should be careful to ensure that this variable re†- mains allocated until after the archive is closed. This function - will disable padding unless you have specifically set the block - size. - More information about the struct archive object and the overall design - of the library can be found in the libarchive(3) overview. - - Note that the convenience forms above vary in how they block the output. - See archive_write_blocksize(3) if you need to control the block size used - for writes or the end-of-file padding behavior. - -CLIENT CALLBACKS - To use this library, you will need to define and register callback func†- tions that will be invoked to write data to the resulting archive. These - functions are registered by calling archive_write_open2(): - - typedef int archive_open_callback(struct archive *, void - *client_data) - - The open callback is invoked by archive_write_open(). It should return - ARCHIVE_OK if the underlying file or data source is successfully opened. - If the open fails, it should call archive_set_error() to register an er†- ror code and message and return ARCHIVE_FATAL. Please note that if open - fails, close is not called and resources must be freed inside the open - callback or with the free callback. - - typedef la_ssize_t archive_write_callback(struct archive *, - void *client_data, const void *buffer, size_t length) - - The write callback is invoked whenever the library needs to write raw - bytes to the archive. For correct blocking, each call to the write call†- back function should translate into a single write(2) system call. This - is especially critical when writing archives to tape drives. On success, - the write callback should return the number of bytes actually written. - On error, the callback should invoke archive_set_error() to register an - error code and message and return -1. - - typedef int archive_close_callback(struct archive *, void - *client_data) - - The close callback is invoked by archive_close when the archive process†- ing is complete. If the open callback fails, the close callback is not - invoked. The callback should return ARCHIVE_OK on success. On failure, - the callback should invoke archive_set_error() to register an error code - and message and return ARCHIVE_FATAL. - - typedef int archive_free_callback(struct archive *, void - *client_data) - - The free callback is always invoked on archive_free. The return code of - this callback is not processed. - - Note that if the client-provided write callback function returns a non- - zero value, that error will be propagated back to the caller through - whatever API function resulted in that call, which may include - archive_write_header(), archive_write_data(), archive_write_close(), - archive_write_finish(), or archive_write_free(). The client callback can - call archive_set_error() to provide values that can then be retrieved by - archive_errno() and archive_error_string(). - -RETURN VALUES - These functions return ARCHIVE_OK on success, or ARCHIVE_FATAL. - -ERRORS - Detailed error codes and textual descriptions are available from the - archive_errno() and archive_error_string() functions. - -SEE ALSO - tar(1), archive_write(3), archive_write_blocksize(3), - archive_write_filter(3), archive_write_format(3), archive_write_new(3), - archive_write_set_options(3), libarchive(3), cpio(5), mtree(5), tar(5) - -BSD November 12, 2020 BSD diff --git a/thirdparty/libarchive/doc/text/archive_write_set_options.3.txt b/thirdparty/libarchive/doc/text/archive_write_set_options.3.txt deleted file mode 100644 index 7a50e4ba2..000000000 --- a/thirdparty/libarchive/doc/text/archive_write_set_options.3.txt +++ /dev/null @@ -1,501 +0,0 @@ -ARCHIVE_WRITE_OPTIONS(3) BSD Library Functions Manual ARCHIVE_WRITE_OPTIONS(3) - -NAME - archive_write_set_filter_option, archive_write_set_format_option, - archive_write_set_option, archive_write_set_options — functions control†- ling options for writing archives - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - int - archive_write_set_filter_option(struct archive *, const char *module, - const char *option, const char *value); - - int - archive_write_set_format_option(struct archive *, const char *module, - const char *option, const char *value); - - int - archive_write_set_option(struct archive *, const char *module, - const char *option, const char *value); - - int - archive_write_set_options(struct archive *, const char *options); - -DESCRIPTION - These functions provide a way for libarchive clients to configure spe†- cific write modules. - - archive_write_set_filter_option(), archive_write_set_format_option() - Specifies an option that will be passed to the currently-regis†- tered filters (including decompression filters) or format read†- ers. - - If option and value are both NULL, these functions will do noth†- ing and ARCHIVE_OK will be returned. If option is NULL but value - is not, these functions will do nothing and ARCHIVE_FAILED will - be returned. - - If module is not NULL, option and value will be provided to the - filter or reader named module. The return value will be either - ARCHIVE_OK if the option was successfully handled or ARCHIVE_WARN - if the option was unrecognized by the module or could otherwise - not be handled. If there is no such module, ARCHIVE_FAILED will - be returned. - - If module is NULL, option and value will be provided to every - registered module. If any module returns ARCHIVE_FATAL, this - value will be returned immediately. Otherwise, ARCHIVE_OK will - be returned if any module accepts the option, and ARCHIVE_FAILED - in all other cases. - - archive_write_set_option() - Calls archive_write_set_format_option(), then - archive_write_set_filter_option(). If either function returns - ARCHIVE_FATAL, ARCHIVE_FATAL will be returned immediately. Oth†- erwise, the greater of the two values will be returned. - - archive_write_set_options() - options is a comma-separated list of options. If options is NULL - or empty, ARCHIVE_OK will be returned immediately. - - Individual options have one of the following forms: - option=value - The option/value pair will be provided to every module. - Modules that do not accept an option with this name will - ignore it. - option The option will be provided to every module with a value - of “1â€. - !option - The option will be provided to every module with a NULL - value. - module:option=value, module:option, module:!option - As above, but the corresponding option and value will be - provided only to modules whose name matches module. - -OPTIONS - Filter b64encode - mode The value is interpreted as octal digits specifying the - file mode. - name The value specifies the file name. - Filter bzip2 - compression-level - The value is interpreted as a decimal integer specifying - the bzip2 compression level. Supported values are from 1 - to 9. - Filter gzip - compression-level - The value is interpreted as a decimal integer specifying - the gzip compression level. Supported values are from 0 - to 9. - timestamp - Store timestamp. This is enabled by default. - Filter lrzip - compression=type - Use type as compression method. Supported values are - “bzip2â€, “gzipiâ€, “lzo†(ultra fast), and “zpaq†(best, - extremely slow). - compression-level - The value is interpreted as a decimal integer specifying - the lrzip compression level. Supported values are from 1 - to 9. - Filter lz4 - compression-level - The value is interpreted as a decimal integer specifying - the lz4 compression level. Supported values are from 0 to - 9. - stream-checksum - Enable stream checksum. This is enabled by default. - block-checksum - Enable block checksum. This is disabled by default. - block-size - The value is interpreted as a decimal integer specifying - the lz4 compression block size. Supported values are from - 4 to 7 (default). - block-dependence - Use the previous block of the block being compressed for - a compression dictionary to improve compression ratio. - This is disabled by default. - Filter lzop - compression-level - The value is interpreted as a decimal integer specifying - the lzop compression level. Supported values are from 1 - to 9. - Filter uuencode - mode The value is interpreted as octal digits specifying the - file mode. - name The value specifies the file name. - Filter xz - compression-level - The value is interpreted as a decimal integer specifying - the compression level. Supported values are from 0 to 9. - threads - The value is interpreted as a decimal integer specifying - the number of threads for multi-threaded lzma compres†- sion. If supported, the default value is read from - lzma_cputhreads(). - Filter zstd - compression-level - The value is interpreted as a decimal integer specifying - the compression level. Supported values depend on the li†- brary version, common values are from 1 to 22. - long Enables long distance matching. The value is interpreted - as a decimal integer specifying log2 window size in - bytes. Values from 10 to 30 for 32 bit, or 31 for 64 bit, - are supported. - threads - The value is interpreted as a decimal integer specifying - the number of threads for multi-threaded zstd compres†- sion. If set to 0, zstd will attempt to detect and use - the number of physical CPU cores. - Format 7zip - compression - The value is one of “storeâ€, “deflateâ€, “bzip2â€, “lzma1â€, - “lzma2†or “ppmd†to indicate how the following entries - should be compressed. Note that this setting is ignored - for directories, symbolic links, and other special en†- tries. - compression-level - The value is interpreted as a decimal integer specifying - the compression level. Values between 0 and 9 are sup†- ported. The interpretation of the compression level de†- pends on the chosen compression method. - Format bin - hdrcharset - The value is used as a character set name that will be - used when translating file names. - Format gnutar - hdrcharset - The value is used as a character set name that will be - used when translating file, group and user names. - Format iso9660 - volume metadata - These options are used to set standard ISO9660 metadata. - abstract-file=filename - The file with the specified name will be identified in - the ISO9660 metadata as holding the abstract for this - volume. Default: none. - application-id=filename - The file with the specified name will be identified in - the ISO9660 metadata as holding the application identi†- fier for this volume. Default: none. - biblio-file=filename - The file with the specified name will be identified in - the ISO9660 metadata as holding the bibliography for this - volume. Default: none. - copyright-file=filename - The file with the specified name will be identified in - the ISO9660 metadata as holding the copyright for this - volume. Default: none. - publisher=filename - The file with the specified name will be identified in - the ISO9660 metadata as holding the publisher information - for this volume. Default: none. - volume-id=string - The specified string will be used as the Volume Identi†- fier in the ISO9660 metadata. It is limited to 32 bytes. - Default: none. - Format iso9660 - boot support - These options are used to make an ISO9660 image that can be di†- rectly booted on various systems. - boot=filename - The file matching this name will be used as the El Torito - boot image file. - boot-catalog=name - The name that will be used for the El Torito boot cata†- log. Default: boot.catalog - boot-info-table - The boot image file provided by the boot=filename option - will be edited with appropriate boot information in bytes - 8 through 64. Default: disabled - boot-load-seg=hexadecimal-number - The load segment for a no-emulation boot image. - boot-load-size=decimal-number - The number of "virtual" 512-byte sectors to be loaded - from a no-emulation boot image. Some very old BIOSes can - only load very small images, setting this value to 4 will - often allow such BIOSes to load the first part of the - boot image (which will then need to be intelligent enough - to load the rest of itself). This should not be needed - unless you are trying to support systems with very old - BIOSes. This defaults to the full size of the image. - boot-type=value - Specifies the boot semantics used by the El Torito boot - image: If the value is fd, then the boot image is assumed - to be a bootable floppy image. If the value is hd, then - the boot image is assumed to be a bootable hard disk im†- age. If the value is no-emulation, the boot image is - used without floppy or hard disk emulation. If the boot - image is exactly 1.2MB, 1.44MB, or 2.88MB, then the de†- fault is fd, otherwise the default is no-emulation. - Format iso9660 - filename and size extensions - Various extensions to the base ISO9660 format. - allow-ldots - If enabled, allows filenames to begin with a leading pe†- riod. If disabled, filenames that begin with a leading - period will have that period replaced by an underscore - character in the standard ISO9660 namespace. This does - not impact names stored in the Rockridge or Joliet exten†- sion area. Default: disabled. - allow-lowercase - If enabled, allows filenames to contain lowercase charac†- ters. If disabled, filenames will be forced to upper†- case. This does not impact names stored in the Rockridge - or Joliet extension area. Default: disabled. - allow-multidot - If enabled, allows filenames to contain multiple period - characters, in violation of the ISO9660 specification. - If disabled, additional periods will be converted to un†- derscore characters. This does not impact names stored - in the Rockridge or Joliet extension area. Default: dis†- abled. - allow-period - If enabled, allows filenames to contain trailing period - characters, in violation of the ISO9660 specification. - If disabled, trailing periods will be converted to under†- score characters. This does not impact names stored in - the Rockridge or Joliet extension area. Default: dis†- abled. - allow-pvd-lowercase - If enabled, the Primary Volume Descriptor may contain - lowercase ASCII characters, in violation of the ISO9660 - specification. If disabled, characters will be converted - to uppercase ASCII. Default: disabled. - allow-sharp-tilde - If enabled, sharp and tilde characters will be permitted - in filenames, in violation if the ISO9660 specification. - If disabled, such characters will be converted to under†- score characters. Default: disabled. - allow-vernum - If enabled, version numbers will be included with files. - If disabled, version numbers will be suppressed, in vio†- lation of the ISO9660 standard. This does not impact - names stored in the Rockridge or Joliet extension area. - Default: enabled. - iso-level - This enables support for file size and file name exten†- sions in the core ISO9660 area. The name extensions - specified here do not affect the names stored in the - Rockridge or Joliet extension areas. - iso-level=1 - The most compliant form of ISO9660 image. File†- names are limited to 8.3 uppercase format, direc†- tory names are limited to 8 uppercase characters, - files are limited to 4 GiB, the complete ISO9660 - image cannot exceed 4 GiB. - iso-level=2 - Filenames are limited to 30 uppercase characters - with a 30-character extension, directory names - are limited to 30 characters, files are limited - to 4 GiB. - iso-level=3 - As with iso-level=2, except that files may exceed - 4 GiB. - iso-level=4 - As with iso-level=3, except that filenames may be - up to 193 characters and may include arbitrary - 8-bit characters. - joliet Microsoft's Joliet extensions store a completely separate - set of directory information about each file. In partic†- ular, this information includes Unicode filenames of up - to 255 characters. Default: enabled. - limit-depth - If enabled, libarchive will use directory relocation - records to ensure that no pathname exceeds the ISO9660 - limit of 8 directory levels. If disabled, no relocation - will occur. Default: enabled. - limit-dirs - If enabled, libarchive will cause an error if there are - more than 65536 directories. If disabled, there is no - limit on the number of directories. Default: enabled - pad If enabled, 300 kiB of zero bytes will be appended to the - end of the archive. Default: enabled - relaxed-filenames - If enabled, all 7-bit ASCII characters are permitted in - filenames (except lowercase characters unless - allow-lowercase is also specified). This violates - ISO9660 standards. This does not impact names stored in - the Rockridge or Joliet extension area. Default: dis†- abled. - rockridge - The Rockridge extensions store an additional set of - POSIX-style file information with each file, including - mtime, atime, ctime, permissions, and long filenames with - arbitrary 8-bit characters. These extensions also sup†- port symbolic links and other POSIX file types. Default: - enabled. - Format iso9660 - zisofs support - The zisofs extensions permit each file to be independently com†- pressed using a gzip-compatible compression. This can provide - significant size savings, but requires the reading system to have - support for these extensions. These extensions are disabled by - default. - compression-level=number - The compression level used by the deflate compressor. - Ranges from 0 (least effort) to 9 (most effort). De†- fault: 6 - zisofs Synonym for zisofs=direct. - zisofs=direct - Compress each file in the archive. Unlike - zisofs=indirect, this is handled entirely within - libarchive and does not require a separate utility. For - best results, libarchive tests each file and will store - the file uncompressed if the compression does not actu†- ally save any space. In particular, files under 2k will - never be compressed. Note that boot image files are - never compressed. - zisofs=indirect - Recognizes files that have already been compressed with - the mkzftree utility and sets up the necessary file meta†- data so that readers will correctly identify these as - zisofs-compressed files. - zisofs-exclude=filename - Specifies a filename that should not be compressed when - using zisofs=direct. This option can be provided multi†- ple times to suppress compression on many files. - Format mtree - cksum, device, flags, gid, gname, indent, link, md5, mode, nlink, - rmd160, sha1, sha256, sha384, sha512, size, time, uid, - uname - Enable a particular keyword in the mtree output. Prefix - with an exclamation mark to disable the corresponding - keyword. The default is equivalent to “device, flags, - gid, gname, link, mode, nlink, size, time, type, uid, - unameâ€. - all Enables all of the above keywords. - use-set - Enables generation of /set lines that specify default - values for the following files and/or directories. - indent XXX needs explanation XXX - Format newc - hdrcharset - The value is used as a character set name that will be - used when translating file names. - Format odc - hdrcharset - The value is used as a character set name that will be - used when translating file names. - Format pwb - hdrcharset - The value is used as a character set name that will be - used when translating file names. - Format pax - hdrcharset - The value is used as a character set name that will be - used when translating file, group and user names. The - value is one of “BINARY†or “UTF-8â€. With “BINARY†there - is no character conversion, with “UTF-8†names are con†- verted to UTF-8. - xattrheader - When storing extended attributes, this option configures - which headers should be written. The value is one of - “allâ€, “LIBARCHIVEâ€, or “SCHILYâ€. By default, both - “LIBARCHIVE.xattr†and “SCHILY.xattr†headers are writ†- ten. - Format ustar - hdrcharset - The value is used as a character set name that will be - used when translating file, group and user names. - Format v7tar - hdrcharset - The value is used as a character set name that will be - used when translating file, group and user names. - Format warc - omit-warcinfo - Set to “true†to disable output of the warcinfo record. - Format xar - checksum=type - Use type as file checksum method. Supported values are - “noneâ€, “md5â€, and “sha1†(default). - compression=type - Use type as compression method. Supported values are - “noneâ€, “bzip2â€, “gzip†(default), “lzma†and “xzâ€. - compression_level - The value is a decimal integer from 1 to 9 specifying the - compression level. - toc-checksum=type - Use type as table of contents checksum method. Supported - values are “noneâ€, “md5†and “sha1†(default). - Format zip - compression - The value is either “store†or “deflate†to indicate how - the following entries should be compressed. Note that - this setting is ignored for directories, symbolic links, - and other special entries. - compression-level - The value is interpreted as a decimal integer specifying - the compression level. Values between 0 and 9 are sup†- ported. A compression level of 0 switches the compres†- sion method to “storeâ€, other values will enable - “deflate†compression with the given level. - encryption - Enable encryption using traditional zip encryption. - encryption=type - Use type as encryption type. Supported values are - “zipcrypt†(traditional zip encryption), “aes128†(WinZip - AES-128 encryption) and “aes256†(WinZip AES-256 - encryption). - experimental - This boolean option enables or disables experimental Zip - features that may not be compatible with other Zip imple†- mentations. - fakecrc32 - This boolean option disables CRC calculations. All CRC - fields are set to zero. It should not be used except for - testing purposes. - hdrcharset - The value is used as a character set name that will be - used when translating file names. - zip64 Zip64 extensions provide additional file size information - for entries larger than 4 GiB. They also provide ex†- tended file offset and archive size information when ar†- chives exceed 4 GiB. By default, the Zip writer selec†- tively enables these extensions only as needed. In par†- ticular, if the file size is unknown, the Zip writer will - include Zip64 extensions to guard against the possibility - that the file might be larger than 4 GiB. - - Setting this boolean option will force the writer to use - Zip64 extensions even for small files that would not oth†- erwise require them. This is primarily useful for test†- ing. - - Disabling this option with !zip64 will force the Zip - writer to avoid Zip64 extensions: It will reject files - with size greater than 4 GiB, it will reject any new en†- tries once the total archive size reaches 4 GiB, and it - will not use Zip64 extensions for files with unknown - size. In particular, this can improve compatibility when - generating archives where the entry sizes are not known - in advance. - -EXAMPLES - The following example creates an archive write handle to create a gzip- - compressed ISO9660 format image. The two options here specify that the - ISO9660 archive will use kernel.img as the boot image for El Torito boot†- ing, and that the gzip compressor should use the maximum compression - level. - - a = archive_write_new(); - archive_write_add_filter_gzip(a); - archive_write_set_format_iso9660(a); - archive_write_set_options(a, "boot=kernel.img,compression=9"); - archive_write_open_filename(a, filename, blocksize); - -ERRORS - More detailed error codes and textual descriptions are available from the - archive_errno() and archive_error_string() functions. - -SEE ALSO - tar(1), archive_read_set_options(3), archive_write(3), libarchive(3) - -HISTORY - The libarchive library first appeared in FreeBSD 5.3. - -AUTHORS - The options support for libarchive was originally implemented by - Michihiro NAKAJIMA. - -BUGS -BSD January 31, 2020 BSD diff --git a/thirdparty/libarchive/doc/text/archive_write_set_passphrase.3.txt b/thirdparty/libarchive/doc/text/archive_write_set_passphrase.3.txt deleted file mode 100644 index 2aa3ec153..000000000 --- a/thirdparty/libarchive/doc/text/archive_write_set_passphrase.3.txt +++ /dev/null @@ -1,35 +0,0 @@ -ARCHIVE_WRITE_SET_PAS... BSD Library Functions Manual ARCHIVE_WRITE_SET_PAS... - -NAME - archive_write_set_passphrase, archive_write_set_passphrase_callback — - functions for writing encrypted archives - -LIBRARY - Streaming Archive Library (libarchive, -larchive) - -SYNOPSIS - #include - - int - archive_write_set_passphrase(struct archive *, const char *passphrase); - - int - archive_write_set_passphrase_callback(struct archive *, - void *client_data, archive_passphrase_callback *); - -DESCRIPTION - archive_write_set_passphrase() - Set a passphrase for writing an encrypted archive. If passphrase - is NULL or empty, this function will do nothing and - ARCHIVE_FAILED will be returned. Otherwise, ARCHIVE_OK will be - returned. - - archive_write_set_passphrase_callback() - Register a callback function that will be invoked to get a - passphrase for encryption if the passphrase was not set by the - archive_write_set_passphrase() function. - -SEE ALSO - tar(1), archive_write(3), archive_write_set_options(3), libarchive(3) - -BSD September 21, 2014 BSD diff --git a/thirdparty/libarchive/doc/text/bsdcpio.1.txt b/thirdparty/libarchive/doc/text/bsdcpio.1.txt deleted file mode 100644 index d7eb8863d..000000000 --- a/thirdparty/libarchive/doc/text/bsdcpio.1.txt +++ /dev/null @@ -1,293 +0,0 @@ -CPIO(1) BSD General Commands Manual CPIO(1) - -NAME - cpio — copy files to and from archives - -SYNOPSIS - cpio -i [options] [pattern ...] [< archive] - cpio -o [options] < name-list [> archive] - cpio -p [options] dest-dir < name-list - -DESCRIPTION - cpio copies files between archives and directories. This implementation - can extract from tar, pax, cpio, zip, jar, ar, and ISO 9660 cdrom images - and can create tar, pax, cpio, ar, and shar archives. - - The first option to cpio is a mode indicator from the following list: - -i Input. Read an archive from standard input (unless overridden) - and extract the contents to disk or (if the -t option is speci†- fied) list the contents to standard output. If one or more file - patterns are specified, only files matching one of the patterns - will be extracted. - -o Output. Read a list of filenames from standard input and produce - a new archive on standard output (unless overridden) containing - the specified items. - -p Pass-through. Read a list of filenames from standard input and - copy the files to the specified directory. - -OPTIONS - Unless specifically stated otherwise, options are applicable in all oper†- ating modes. - - -0, --null - Read filenames separated by NUL characters instead of newlines. - This is necessary if any of the filenames being read might con†- tain newlines. - - -6, --pwb - When reading a binary format archive, assume it's the earlier - one, from the PWB variant of 6th Edition UNIX. When writing a - cpio archive, use the PWB format. - - -7, --binary - (o mode only) When writing a cpio archive, use the (newer, non- - PWB) binary format. - - -A (o mode only) Append to the specified archive. (Not yet imple†- mented.) - - -a (o and p modes) Reset access times on files after they are read. - - -B (o mode only) Block output to records of 5120 bytes. - - -C size - (o mode only) Block output to records of size bytes. - - -c (o mode only) Use the old POSIX portable character format. - Equivalent to --format odc. - - -d, --make-directories - (i and p modes) Create directories as necessary. - - -E file - (i mode only) Read list of file name patterns from file to list - and extract. - - -F file, --file file - Read archive from or write archive to file. - - -f pattern - (i mode only) Ignore files that match pattern. - - -H format, --format format - (o mode only) Produce the output archive in the specified format. - Supported formats include: - - cpio Synonym for odc. - newc The SVR4 portable cpio format. - odc The old POSIX.1 portable octet-oriented cpio format. - pax The POSIX.1 pax format, an extension of the ustar for†- mat. - ustar The POSIX.1 tar format. - - The default format is odc. See libarchive-formats(5) for more - complete information about the formats currently supported by the - underlying libarchive(3) library. - - -h, --help - Print usage information. - - -I file - Read archive from file. - - -i, --extract - Input mode. See above for description. - - --insecure - (i and p mode only) Disable security checks during extraction or - copying. This allows extraction via symbolic links, absolute - paths, and path names containing ‘..’ in the name. - - -J, --xz - (o mode only) Compress the file with xz-compatible compression - before writing it. In input mode, this option is ignored; xz - compression is recognized automatically on input. - - -j Synonym for -y. - - -L (o and p modes) All symbolic links will be followed. Normally, - symbolic links are archived and copied as symbolic links. With - this option, the target of the link will be archived or copied - instead. - - -l, --link - (p mode only) Create links from the target directory to the orig†- inal files, instead of copying. - - --lrzip - (o mode only) Compress the resulting archive with lrzip(1). In - input mode, this option is ignored. - - --lz4 (o mode only) Compress the archive with lz4-compatible compres†- sion before writing it. In input mode, this option is ignored; - lz4 compression is recognized automatically on input. - - --zstd (o mode only) Compress the archive with zstd-compatible compres†- sion before writing it. In input mode, this option is ignored; - zstd compression is recognized automatically on input. - - --lzma (o mode only) Compress the file with lzma-compatible compression - before writing it. In input mode, this option is ignored; lzma - compression is recognized automatically on input. - - --lzop (o mode only) Compress the resulting archive with lzop(1). In - input mode, this option is ignored. - - --passphrase passphrase - The passphrase is used to extract or create an encrypted archive. - Currently, zip is only a format that cpio can handle encrypted - archives. You shouldn't use this option unless you realize how - insecure use of this option is. - - -m, --preserve-modification-time - (i and p modes) Set file modification time on created files to - match those in the source. - - -n, --numeric-uid-gid - (i mode, only with -t) Display numeric uid and gid. By default, - cpio displays the user and group names when they are provided in - the archive, or looks up the user and group names in the system - password database. - - --no-preserve-owner - (i mode only) Do not attempt to restore file ownership. This is - the default when run by non-root users. - - -O file - Write archive to file. - - -o, --create - Output mode. See above for description. - - -p, --pass-through - Pass-through mode. See above for description. - - --preserve-owner - (i mode only) Restore file ownership. This is the default when - run by the root user. - - --quiet - Suppress unnecessary messages. - - -R [user][:][group], --owner [user][:][group] - Set the owner and/or group on files in the output. If group is - specified with no user (for example, -R :wheel) then the group - will be set but not the user. If the user is specified with a - trailing colon and no group (for example, -R root:) then the - group will be set to the user's default group. If the user is - specified with no trailing colon, then the user will be set but - not the group. In -i and -p modes, this option can only be used - by the super-user. (For compatibility, a period can be used in - place of the colon.) - - -r (All modes.) Rename files interactively. For each file, a - prompt is written to /dev/tty containing the name of the file and - a line is read from /dev/tty. If the line read is blank, the - file is skipped. If the line contains a single period, the file - is processed normally. Otherwise, the line is taken to be the - new name of the file. - - -t, --list - (i mode only) List the contents of the archive to stdout; do not - restore the contents to disk. - - -u, --unconditional - (i and p modes) Unconditionally overwrite existing files. Ordi†- narily, an older file will not overwrite a newer file on disk. - - -V, --dot - Print a dot to stderr for each file as it is processed. Super†- seded by -v. - - -v, --verbose - Print the name of each file to stderr as it is processed. With - -t, provide a detailed listing of each file. - - --version - Print the program version information and exit. - - -y (o mode only) Compress the archive with bzip2-compatible compres†- sion before writing it. In input mode, this option is ignored; - bzip2 compression is recognized automatically on input. - - -Z (o mode only) Compress the archive with compress-compatible com†- pression before writing it. In input mode, this option is ig†- nored; compression is recognized automatically on input. - - -z (o mode only) Compress the archive with gzip-compatible compres†- sion before writing it. In input mode, this option is ignored; - gzip compression is recognized automatically on input. - -EXIT STATUS - The cpio utility exits 0 on success, and >0 if an error occurs. - -ENVIRONMENT - The following environment variables affect the execution of cpio: - - LANG The locale to use. See environ(7) for more information. - - TZ The timezone to use when displaying dates. See environ(7) for - more information. - -EXAMPLES - The cpio command is traditionally used to copy file hierarchies in con†- junction with the find(1) command. The first example here simply copies - all files from src to dest: - find src | cpio -pmud dest - - By carefully selecting options to the find(1) command and combining it - with other standard utilities, it is possible to exercise very fine con†- trol over which files are copied. This next example copies files from - src to dest that are more than 2 days old and whose names match a partic†- ular pattern: - find src -mtime +2 | grep foo[bar] | cpio -pdmu dest - - This example copies files from src to dest that are more than 2 days old - and which contain the word “foobarâ€: - find src -mtime +2 | xargs grep -l foobar | cpio -pdmu dest - -COMPATIBILITY - The mode options i, o, and p and the options a, B, c, d, f, l, m, r, t, - u, and v comply with SUSv2. - - The old POSIX.1 standard specified that only -i, -o, and -p were inter†- preted as command-line options. Each took a single argument of a list of - modifier characters. For example, the standard syntax allows -imu but - does not support -miu or -i -m -u, since m and u are only modifiers to - -i, they are not command-line options in their own right. The syntax - supported by this implementation is backwards-compatible with the stan†- dard. For best compatibility, scripts should limit themselves to the - standard syntax. - -SEE ALSO - bzip2(1), gzip(1), mt(1), pax(1), tar(1), libarchive(3), cpio(5), - libarchive-formats(5), tar(5) - -STANDARDS - There is no current POSIX standard for the cpio command; it appeared in - ISO/IEC 9945-1:1996 (“POSIX.1â€) but was dropped from IEEE Std 1003.1-2001 - (“POSIX.1â€). - - The cpio, ustar, and pax interchange file formats are defined by IEEE Std - 1003.1-2001 (“POSIX.1â€) for the pax command. - -HISTORY - The original cpio and find utilities were written by Dick Haight while - working in AT&T's Unix Support Group. They first appeared in 1977 in - PWB/UNIX 1.0, the “Programmer's Work Bench†system developed for use - within AT&T. They were first released outside of AT&T as part of System - III Unix in 1981. As a result, cpio actually predates tar, even though - it was not well-known outside of AT&T until some time later. - - This is a complete re-implementation based on the libarchive(3) library. - -BUGS - The cpio archive format has several basic limitations: It does not store - user and group names, only numbers. As a result, it cannot be reliably - used to transfer files between systems with dissimilar user and group - numbering. Older cpio formats limit the user and group numbers to 16 or - 18 bits, which is insufficient for modern systems. The cpio archive for†- mats cannot support files over 4 gigabytes, except for the “odc†variant, - which can support files up to 8 gigabytes. - -BSD September 16, 2014 BSD diff --git a/thirdparty/libarchive/doc/text/bsdtar.1.txt b/thirdparty/libarchive/doc/text/bsdtar.1.txt deleted file mode 100644 index 4a363f794..000000000 --- a/thirdparty/libarchive/doc/text/bsdtar.1.txt +++ /dev/null @@ -1,866 +0,0 @@ -TAR(1) BSD General Commands Manual TAR(1) - -NAME - tar — manipulate tape archives - -SYNOPSIS - tar [bundled-flags ⟨args⟩] [⟨file⟩ | ⟨pattern⟩ ...] - tar {-c} [options] [files | directories] - tar {-r | -u} -f archive-file [options] [files | directories] - tar {-t | -x} [options] [patterns] - -DESCRIPTION - tar creates and manipulates streaming archive files. This implementation - can extract from tar, pax, cpio, zip, jar, ar, xar, rpm, 7-zip, and ISO - 9660 cdrom images and can create tar, pax, cpio, ar, zip, 7-zip, and shar - archives. - - The first synopsis form shows a “bundled†option word. This usage is - provided for compatibility with historical implementations. See COMPATI†- BILITY below for details. - - The other synopsis forms show the preferred usage. The first option to - tar is a mode indicator from the following list: - -c Create a new archive containing the specified items. The long - option form is --create. - -r Like -c, but new entries are appended to the archive. Note that - this only works on uncompressed archives stored in regular files. - The -f option is required. The long option form is --append. - -t List archive contents to stdout. The long option form is --list. - -u Like -r, but new entries are added only if they have a modifica†- tion date newer than the corresponding entry in the archive. - Note that this only works on uncompressed archives stored in reg†- ular files. The -f option is required. The long form is - --update. - -x Extract to disk from the archive. If a file with the same name - appears more than once in the archive, each copy will be ex†- tracted, with later copies overwriting (replacing) earlier - copies. The long option form is --extract. - - In -c, -r, or -u mode, each specified file or directory is added to the - archive in the order specified on the command line. By default, the con†- tents of each directory are also archived. - - In extract or list mode, the entire command line is read and parsed be†- fore the archive is opened. The pathnames or patterns on the command - line indicate which items in the archive should be processed. Patterns - are shell-style globbing patterns as documented in tcsh(1). - -OPTIONS - Unless specifically stated otherwise, options are applicable in all oper†- ating modes. - - @archive - (c and r modes only) The specified archive is opened and the en†- tries in it will be appended to the current archive. As a simple - example, - tar -c -f - newfile @original.tar - writes a new archive to standard output containing a file newfile - and all of the entries from original.tar. In contrast, - tar -c -f - newfile original.tar - creates a new archive with only two entries. Similarly, - tar -czf - --format pax @- - reads an archive from standard input (whose format will be deter†- mined automatically) and converts it into a gzip-compressed pax- - format archive on stdout. In this way, tar can be used to con†- vert archives from one format to another. - - -a, --auto-compress - (c mode only) Use the archive suffix to decide a set of the for†- mat and the compressions. As a simple example, - tar -a -cf archive.tgz source.c source.h - creates a new archive with restricted pax format and gzip com†- pression, - tar -a -cf archive.tar.bz2.uu source.c source.h - creates a new archive with restricted pax format and bzip2 com†- pression and uuencode compression, - tar -a -cf archive.zip source.c source.h - creates a new archive with zip format, - tar -a -jcf archive.tgz source.c source.h - ignores the “-j†option, and creates a new archive with re†- stricted pax format and gzip compression, - tar -a -jcf archive.xxx source.c source.h - if it is unknown suffix or no suffix, creates a new archive with - restricted pax format and bzip2 compression. - - --acls (c, r, u, x modes only) Archive or extract POSIX.1e or NFSv4 - ACLs. This is the reverse of --no-acls and the default behavior - in c, r, and u modes (except on Mac OS X) or if tar is run in x - mode as root. On Mac OS X this option translates extended ACLs - to NFSv4 ACLs. To store extended ACLs the --mac-metadata option - is preferred. - - -B, --read-full-blocks - Ignored for compatibility with other tar(1) implementations. - - -b blocksize, --block-size blocksize - Specify the block size, in 512-byte records, for tape drive I/O. - As a rule, this argument is only needed when reading from or - writing to tape drives, and usually not even then as the default - block size of 20 records (10240 bytes) is very common. - - -C directory, --cd directory, --directory directory - In c and r mode, this changes the directory before adding the - following files. In x mode, change directories after opening the - archive but before extracting entries from the archive. - - --chroot - (x mode only) chroot() to the current directory after processing - any -C options and before extracting any files. - - --clear-nochange-fflags - (x mode only) Before removing file system objects to replace - them, clear platform-specific file attributes or file flags that - might prevent removal. - - --exclude pattern - Do not process files or directories that match the specified pat†- tern. Note that exclusions take precedence over patterns or - filenames specified on the command line. - - --exclude-vcs - Do not process files or directories internally used by the ver†- sion control systems ‘Arch’, ‘Bazaar’, ‘CVS’, ‘Darcs’, - ‘Mercurial’, ‘RCS’, ‘SCCS’, ‘SVN’ and ‘git’. - - --fflags - (c, r, u, x modes only) Archive or extract platform-specific file - attributes or file flags. This is the reverse of --no-fflags and - the default behavior in c, r, and u modes or if tar is run in x - mode as root. - - --format format - (c, r, u mode only) Use the specified format for the created ar†- chive. Supported formats include “cpioâ€, “paxâ€, “sharâ€, and - “ustarâ€. Other formats may also be supported; see - libarchive-formats(5) for more information about currently-sup†- ported formats. In r and u modes, when extending an existing ar†- chive, the format specified here must be compatible with the for†- mat of the existing archive on disk. - - -f file, --file file - Read the archive from or write the archive to the specified file. - The filename can be - for standard input or standard output. The - default varies by system; on FreeBSD, the default is /dev/sa0; on - Linux, the default is /dev/st0. - - --gid id - Use the provided group id number. On extract, this overrides the - group id in the archive; the group name in the archive will be - ignored. On create, this overrides the group id read from disk; - if --gname is not also specified, the group name will be set to - match the group id. - - --gname name - Use the provided group name. On extract, this overrides the - group name in the archive; if the provided group name does not - exist on the system, the group id (from the archive or from the - --gid option) will be used instead. On create, this sets the - group name that will be stored in the archive; the name will not - be verified against the system group database. - - -H (c and r modes only) Symbolic links named on the command line - will be followed; the target of the link will be archived, not - the link itself. - - -h (c and r modes only) Synonym for -L. - - -I Synonym for -T. - - --help Show usage. - - --hfsCompression - (x mode only) Mac OS X specific (v10.6 or later). Compress ex†- tracted regular files with HFS+ compression. - - --ignore-zeros - An alias of --options read_concatenated_archives for compatibil†- ity with GNU tar. - - --include pattern - Process only files or directories that match the specified pat†- tern. Note that exclusions specified with --exclude take prece†- dence over inclusions. If no inclusions are explicitly speci†- fied, all entries are processed by default. The --include option - is especially useful when filtering archives. For example, the - command - tar -c -f new.tar --include='*foo*' @old.tgz - creates a new archive new.tar containing only the entries from - old.tgz containing the string ‘foo’. - - -J, --xz - (c mode only) Compress the resulting archive with xz(1). In ex†- tract or list modes, this option is ignored. Note that this tar - implementation recognizes XZ compression automatically when read†- ing archives. - - -j, --bzip, --bzip2, --bunzip2 - (c mode only) Compress the resulting archive with bzip2(1). In - extract or list modes, this option is ignored. Note that this - tar implementation recognizes bzip2 compression automatically - when reading archives. - - -k, --keep-old-files - (x mode only) Do not overwrite existing files. In particular, if - a file appears more than once in an archive, later copies will - not overwrite earlier copies. - - --keep-newer-files - (x mode only) Do not overwrite existing files that are newer than - the versions appearing in the archive being extracted. - - -L, --dereference - (c and r modes only) All symbolic links will be followed. Nor†- mally, symbolic links are archived as such. With this option, - the target of the link will be archived instead. - - -l, --check-links - (c and r modes only) Issue a warning message unless all links to - each file are archived. - - --lrzip - (c mode only) Compress the resulting archive with lrzip(1). In - extract or list modes, this option is ignored. Note that this - tar implementation recognizes lrzip compression automatically - when reading archives. - - --lz4 (c mode only) Compress the archive with lz4-compatible compres†- sion before writing it. In extract or list modes, this option is - ignored. Note that this tar implementation recognizes lz4 com†- pression automatically when reading archives. - - --zstd (c mode only) Compress the archive with zstd-compatible compres†- sion before writing it. In extract or list modes, this option is - ignored. Note that this tar implementation recognizes zstd com†- pression automatically when reading archives. - - --lzma (c mode only) Compress the resulting archive with the original - LZMA algorithm. In extract or list modes, this option is ig†- nored. Use of this option is discouraged and new archives should - be created with --xz instead. Note that this tar implementation - recognizes LZMA compression automatically when reading archives. - - --lzop (c mode only) Compress the resulting archive with lzop(1). In - extract or list modes, this option is ignored. Note that this - tar implementation recognizes LZO compression automatically when - reading archives. - - -m, --modification-time - (x mode only) Do not extract modification time. By default, the - modification time is set to the time stored in the archive. - - --mac-metadata - (c, r, u and x mode only) Mac OS X specific. Archive or extract - extended ACLs and extended file attributes using copyfile(3) in - AppleDouble format. This is the reverse of --no-mac-metadata. - and the default behavior in c, r, and u modes or if tar is run in - x mode as root. - - -n, --norecurse, --no-recursion - Do not operate recursively on the content of directories. - - --newer date - (c, r, u modes only) Only include files and directories newer - than the specified date. This compares ctime entries. - - --newer-mtime date - (c, r, u modes only) Like --newer, except it compares mtime en†- tries instead of ctime entries. - - --newer-than file - (c, r, u modes only) Only include files and directories newer - than the specified file. This compares ctime entries. - - --newer-mtime-than file - (c, r, u modes only) Like --newer-than, except it compares mtime - entries instead of ctime entries. - - --nodump - (c and r modes only) Honor the nodump file flag by skipping this - file. - - --nopreserveHFSCompression - (x mode only) Mac OS X specific (v10.6 or later). Do not compress - extracted regular files which were compressed with HFS+ compres†- sion before archived. By default, compress the regular files - again with HFS+ compression. - - --null (use with -I or -T) Filenames or patterns are separated by null - characters, not by newlines. This is often used to read file†- names output by the -print0 option to find(1). - - --no-acls - (c, r, u, x modes only) Do not archive or extract POSIX.1e or - NFSv4 ACLs. This is the reverse of --acls and the default behav†- ior if tar is run as non-root in x mode (on Mac OS X as any user - in c, r, u and x modes). - - --no-fflags - (c, r, u, x modes only) Do not archive or extract file attributes - or file flags. This is the reverse of --fflags and the default - behavior if tar is run as non-root in x mode. - - --no-mac-metadata - (x mode only) Mac OS X specific. Do not archive or extract ACLs - and extended file attributes using copyfile(3) in AppleDouble - format. This is the reverse of --mac-metadata. and the default - behavior if tar is run as non-root in x mode. - - --no-read-sparse - (c, r, u modes only) Do not read sparse file information from - disk. This is the reverse of --read-sparse. - - --no-safe-writes - (x mode only) Do not create temporary files and use rename(2) to - replace the original ones. This is the reverse of --safe-writes. - - --no-same-owner - (x mode only) Do not extract owner and group IDs. This is the - reverse of --same-owner and the default behavior if tar is run as - non-root. - - --no-same-permissions - (x mode only) Do not extract full permissions (SGID, SUID, sticky - bit, file attributes or file flags, extended file attributes and - ACLs). This is the reverse of -p and the default behavior if tar - is run as non-root. - - --no-xattrs - (c, r, u, x modes only) Do not archive or extract extended file - attributes. This is the reverse of --xattrs and the default be†- havior if tar is run as non-root in x mode. - - --numeric-owner - This is equivalent to --uname "" --gname "". On extract, it - causes user and group names in the archive to be ignored in favor - of the numeric user and group ids. On create, it causes user and - group names to not be stored in the archive. - - -O, --to-stdout - (x, t modes only) In extract (-x) mode, files will be written to - standard out rather than being extracted to disk. In list (-t) - mode, the file listing will be written to stderr rather than the - usual stdout. - - -o (x mode) Use the user and group of the user running the program - rather than those specified in the archive. Note that this has - no significance unless -p is specified, and the program is being - run by the root user. In this case, the file modes and flags - from the archive will be restored, but ACLs or owner information - in the archive will be discarded. - - -o (c, r, u mode) A synonym for --format ustar - - --older date - (c, r, u modes only) Only include files and directories older - than the specified date. This compares ctime entries. - - --older-mtime date - (c, r, u modes only) Like --older, except it compares mtime en†- tries instead of ctime entries. - - --older-than file - (c, r, u modes only) Only include files and directories older - than the specified file. This compares ctime entries. - - --older-mtime-than file - (c, r, u modes only) Like --older-than, except it compares mtime - entries instead of ctime entries. - - --one-file-system - (c, r, and u modes) Do not cross mount points. - - --options options - Select optional behaviors for particular modules. The argument - is a text string containing comma-separated keywords and values. - These are passed to the modules that handle particular formats to - control how those formats will behave. Each option has one of - the following forms: - key=value - The key will be set to the specified value in every mod†- ule that supports it. Modules that do not support this - key will ignore it. - key The key will be enabled in every module that supports it. - This is equivalent to key=1. - !key The key will be disabled in every module that supports - it. - module:key=value, module:key, module:!key - As above, but the corresponding key and value will be - provided only to modules whose name matches module. - - The complete list of supported modules and keys for create and - append modes is in archive_write_set_options(3) and for extract - and list modes in archive_read_set_options(3). - - Examples of supported options: - iso9660:joliet - Support Joliet extensions. This is enabled by default, - use !joliet or iso9660:!joliet to disable. - iso9660:rockridge - Support Rock Ridge extensions. This is enabled by de†- fault, use !rockridge or iso9660:!rockridge to disable. - gzip:compression-level - A decimal integer from 1 to 9 specifying the gzip com†- pression level. - gzip:timestamp - Store timestamp. This is enabled by default, use - !timestamp or gzip:!timestamp to disable. - lrzip:compression=type - Use type as compression method. Supported values are - bzip2, gzip, lzo (ultra fast), and zpaq (best, extremely - slow). - lrzip:compression-level - A decimal integer from 1 to 9 specifying the lrzip com†- pression level. - lz4:compression-level - A decimal integer from 1 to 9 specifying the lzop com†- pression level. - lz4:stream-checksum - Enable stream checksum. This is by default, use - lz4:!stream-checksum to disable. - lz4:block-checksum - Enable block checksum (Disabled by default). - lz4:block-size - A decimal integer from 4 to 7 specifying the lz4 compres†- sion block size (7 is set by default). - lz4:block-dependence - Use the previous block of the block being compressed for - a compression dictionary to improve compression ratio. - zstd:compression-level - A decimal integer specifying the zstd compression level. - Supported values depend on the library version, common - values are from 1 to 22. - zstd:threads - Specify the number of worker threads to use. Setting - threads to a special value 0 makes zstd(1) use as many - threads as there are CPU cores on the system. - zstd:frame-per-file - Start a new compression frame at the beginning of each - file in the archive. - zstd:min-frame-size=N - In combination with zstd:frame-per-file, do not start a - new compression frame unless the current frame is at - least N bytes. - zstd:max-frame-size=N - Start a new compression frame as soon as the current - frame exceeds N bytes. - lzop:compression-level - A decimal integer from 1 to 9 specifying the lzop com†- pression level. - xz:compression-level - A decimal integer from 0 to 9 specifying the xz compres†- sion level. - xz:threads - Specify the number of worker threads to use. Setting - threads to a special value 0 makes xz(1) use as many - threads as there are CPU cores on the system. - mtree:keyword - The mtree writer module allows you to specify which mtree - keywords will be included in the output. Supported key†- words include: cksum, device, flags, gid, gname, indent, - link, md5, mode, nlink, rmd160, sha1, sha256, sha384, - sha512, size, time, uid, uname. The default is equiva†- lent to: “device, flags, gid, gname, link, mode, nlink, - size, time, type, uid, unameâ€. - mtree:all - Enables all of the above keywords. You can also use - mtree:!all to disable all keywords. - mtree:use-set - Enable generation of /set lines in the output. - mtree:indent - Produce human-readable output by indenting options and - splitting lines to fit into 80 columns. - zip:compression=type - Use type as compression method. Supported values are - store (uncompressed) and deflate (gzip algorithm). - zip:encryption - Enable encryption using traditional zip encryption. - zip:encryption=type - Use type as encryption type. Supported values are - zipcrypt (traditional zip encryption), aes128 (WinZip - AES-128 encryption) and aes256 (WinZip AES-256 encryp†- tion). - read_concatenated_archives - Ignore zeroed blocks in the archive, which occurs when - multiple tar archives have been concatenated together. - Without this option, only the contents of the first con†- catenated archive would be read. This option is compara†- ble to the -i, --ignore-zeros option of GNU tar. - If a provided option is not supported by any module, that is a - fatal error. - - -P, --absolute-paths - Preserve pathnames. By default, absolute pathnames (those that - begin with a / character) have the leading slash removed both - when creating archives and extracting from them. Also, tar will - refuse to extract archive entries whose pathnames contain .. or - whose target directory would be altered by a symlink. This op†- tion suppresses these behaviors. - - -p, --insecure, --preserve-permissions - (x mode only) Preserve file permissions. Attempt to restore the - full permissions, including file modes, file attributes or file - flags, extended file attributes and ACLs, if available, for each - item extracted from the archive. This is the reverse of - --no-same-permissions and the default if tar is being run as - root. It can be partially overridden by also specifying - --no-acls, --no-fflags, --no-mac-metadata or --no-xattrs. - - --passphrase passphrase - The passphrase is used to extract or create an encrypted archive. - Currently, zip is the only supported format that supports encryp†- tion. You shouldn't use this option unless you realize how inse†- cure use of this option is. - - --posix - (c, r, u mode only) Synonym for --format pax - - -q, --fast-read - (x and t mode only) Extract or list only the first archive entry - that matches each pattern or filename operand. Exit as soon as - each specified pattern or filename has been matched. By default, - the archive is always read to the very end, since there can be - multiple entries with the same name and, by convention, later en†- tries overwrite earlier entries. This option is provided as a - performance optimization. - - --read-sparse - (c, r, u modes only) Read sparse file information from disk. - This is the reverse of --no-read-sparse and the default behavior. - - -S (x mode only) Extract files as sparse files. For every block on - disk, check first if it contains only NULL bytes and seek over it - otherwise. This works similar to the conv=sparse option of dd. - - -s pattern - Modify file or archive member names according to pattern. The - pattern has the format /old/new/[ghHprRsS] where old is a basic - regular expression, new is the replacement string of the matched - part, and the optional trailing letters modify how the replace†- ment is handled. If old is not matched, the pattern is skipped. - Within new, ~ is substituted with the match, \1 to \9 with the - content of the corresponding captured group. The optional trail†- ing g specifies that matching should continue after the matched - part and stop on the first unmatched pattern. The optional - trailing s specifies that the pattern applies to the value of - symbolic links. The optional trailing p specifies that after a - successful substitution the original path name and the new path - name should be printed to standard error. Optional trailing H, - R, or S characters suppress substitutions for hardlink targets, - regular filenames, or symlink targets, respectively. Optional - trailing h, r, or s characters enable substitutions for hardlink - targets, regular filenames, or symlink targets, respectively. - The default is hrs which applies substitutions to all names. In - particular, it is never necessary to specify h, r, or s. - - --safe-writes - (x mode only) Extract files atomically. By default tar unlinks - the original file with the same name as the extracted file (if it - exists), and then creates it immediately under the same name and - writes to it. For a short period of time, applications trying to - access the file might not find it, or see incomplete results. If - --safe-writes is enabled, tar first creates a unique temporary - file, then writes the new contents to the temporary file, and fi†- nally renames the temporary file to its final name atomically us†- ing rename(2). This guarantees that an application accessing the - file, will either see the old contents or the new contents at all - times. - - --same-owner - (x mode only) Extract owner and group IDs. This is the reverse - of --no-same-owner and the default behavior if tar is run as - root. - - --strip-components count - Remove the specified number of leading path elements. Pathnames - with fewer elements will be silently skipped. Note that the - pathname is edited after checking inclusion/exclusion patterns - but before security checks. - - -T filename, --files-from filename - In x or t mode, tar will read the list of names to be extracted - from filename. In c mode, tar will read names to be archived - from filename. The special name “-C†on a line by itself will - cause the current directory to be changed to the directory speci†- fied on the following line. Names are terminated by newlines un†- less --null is specified. Note that --null also disables the - special handling of lines containing “-Câ€. Note: If you are - generating lists of files using find(1), you probably want to use - -n as well. - - --totals - (c, r, u modes only) After archiving all files, print a summary - to stderr. - - -U, --unlink, --unlink-first - (x mode only) Unlink files before creating them. This can be a - minor performance optimization if most files already exist, but - can make things slower if most files do not already exist. This - flag also causes tar to remove intervening directory symlinks in†- stead of reporting an error. See the SECURITY section below for - more details. - - --uid id - Use the provided user id number and ignore the user name from the - archive. On create, if --uname is not also specified, the user - name will be set to match the user id. - - --uname name - Use the provided user name. On extract, this overrides the user - name in the archive; if the provided user name does not exist on - the system, it will be ignored and the user id (from the archive - or from the --uid option) will be used instead. On create, this - sets the user name that will be stored in the archive; the name - is not verified against the system user database. - - --use-compress-program program - Pipe the input (in x or t mode) or the output (in c mode) through - program instead of using the builtin compression support. - - -v, --verbose - Produce verbose output. In create and extract modes, tar will - list each file name as it is read from or written to the archive. - In list mode, tar will produce output similar to that of ls(1). - An additional -v option will also provide ls-like details in cre†- ate and extract mode. - - --version - Print version of tar and libarchive, and exit. - - -w, --confirmation, --interactive - Ask for confirmation for every action. - - -X filename, --exclude-from filename - Read a list of exclusion patterns from the specified file. See - --exclude for more information about the handling of exclusions. - - --xattrs - (c, r, u, x modes only) Archive or extract extended file at†- tributes. This is the reverse of --no-xattrs and the default be†- havior in c, r, and u modes or if tar is run in x mode as root. - - -y (c mode only) Compress the resulting archive with bzip2(1). In - extract or list modes, this option is ignored. Note that this - tar implementation recognizes bzip2 compression automatically - when reading archives. - - -Z, --compress, --uncompress - (c mode only) Compress the resulting archive with compress(1). - In extract or list modes, this option is ignored. Note that this - tar implementation recognizes compress compression automatically - when reading archives. - - -z, --gunzip, --gzip - (c mode only) Compress the resulting archive with gzip(1). In - extract or list modes, this option is ignored. Note that this - tar implementation recognizes gzip compression automatically when - reading archives. - -ENVIRONMENT - The following environment variables affect the execution of tar: - - TAR_READER_OPTIONS - The default options for format readers and compression readers. - The --options option overrides this. - - TAR_WRITER_OPTIONS - The default options for format writers and compression writers. - The --options option overrides this. - - LANG The locale to use. See environ(7) for more information. - - TAPE The default device. The -f option overrides this. Please see - the description of the -f option above for more details. - - TZ The timezone to use when displaying dates. See environ(7) for - more information. - -EXIT STATUS - The tar utility exits 0 on success, and >0 if an error occurs. - -EXAMPLES - The following creates a new archive called file.tar.gz that contains two - files source.c and source.h: - tar -czf file.tar.gz source.c source.h - - To view a detailed table of contents for this archive: - tar -tvf file.tar.gz - - To extract all entries from the archive on the default tape drive: - tar -x - - To examine the contents of an ISO 9660 cdrom image: - tar -tf image.iso - - To move file hierarchies, invoke tar as - tar -cf - -C srcdir . | tar -xpf - -C destdir - or more traditionally - cd srcdir ; tar -cf - . | (cd destdir ; tar -xpf -) - - In create mode, the list of files and directories to be archived can also - include directory change instructions of the form -Cfoo/baz and archive - inclusions of the form @archive-file. For example, the command line - tar -c -f new.tar foo1 @old.tgz -C/tmp foo2 - will create a new archive new.tar. tar will read the file foo1 from the - current directory and add it to the output archive. It will then read - each entry from old.tgz and add those entries to the output archive. Fi†- nally, it will switch to the /tmp directory and add foo2 to the output - archive. - - An input file in mtree(5) format can be used to create an output archive - with arbitrary ownership, permissions, or names that differ from existing - data on disk: - - $ cat input.mtree - #mtree - usr/bin uid=0 gid=0 mode=0755 type=dir - usr/bin/ls uid=0 gid=0 mode=0755 type=file content=myls - $ tar -cvf output.tar @input.mtree - - The --newer and --newer-mtime switches accept a variety of common date - and time specifications, including “12 Mar 2005 7:14:29pmâ€, “2005-03-12 - 19:14â€, “5 minutes agoâ€, and “19:14 PST May 1â€. - - The --options argument can be used to control various details of archive - generation or reading. For example, you can generate mtree output which - only contains type, time, and uid keywords: - tar -cf file.tar --format=mtree --options='!all,type,time,uid' dir - or you can set the compression level used by gzip or xz compression: - tar -czf file.tar --options='compression-level=9'. - For more details, see the explanation of the archive_read_set_options() - and archive_write_set_options() API calls that are described in - archive_read(3) and archive_write(3). - -COMPATIBILITY - The bundled-arguments format is supported for compatibility with historic - implementations. It consists of an initial word (with no leading - char†- acter) in which each character indicates an option. Arguments follow as - separate words. The order of the arguments must match the order of the - corresponding characters in the bundled command word. For example, - tar tbf 32 file.tar - specifies three flags t, b, and f. The b and f flags both require argu†- ments, so there must be two additional items on the command line. The 32 - is the argument to the b flag, and file.tar is the argument to the f - flag. - - The mode options c, r, t, u, and x and the options b, f, l, m, o, v, and - w comply with SUSv2. - - For maximum portability, scripts that invoke tar should use the bundled- - argument format above, should limit themselves to the c, t, and x modes, - and the b, f, m, v, and w options. - - Additional long options are provided to improve compatibility with other - tar implementations. - -SECURITY - Certain security issues are common to many archiving programs, including - tar. In particular, carefully-crafted archives can request that tar ex†- tract files to locations outside of the target directory. This can po†- tentially be used to cause unwitting users to overwrite files they did - not intend to overwrite. If the archive is being extracted by the supe†- ruser, any file on the system can potentially be overwritten. There are - three ways this can happen. Although tar has mechanisms to protect - against each one, savvy users should be aware of the implications: - - • Archive entries can have absolute pathnames. By default, tar re†- moves the leading / character from filenames before restoring - them to guard against this problem. - - • Archive entries can have pathnames that include .. components. - By default, tar will not extract files containing .. components - in their pathname. - - • Archive entries can exploit symbolic links to restore files to - other directories. An archive can restore a symbolic link to an†- other directory, then use that link to restore a file into that - directory. To guard against this, tar checks each extracted path - for symlinks. If the final path element is a symlink, it will be - removed and replaced with the archive entry. If -U is specified, - any intermediate symlink will also be unconditionally removed. - If neither -U nor -P is specified, tar will refuse to extract the - entry. - To protect yourself, you should be wary of any archives that come from - untrusted sources. You should examine the contents of an archive with - tar -tf filename - before extraction. You should use the -k option to ensure that tar will - not overwrite any existing files or the -U option to remove any pre-ex†- isting files. You should generally not extract archives while running - with super-user privileges. Note that the -P option to tar disables the - security checks above and allows you to extract an archive while preserv†- ing any absolute pathnames, .. components, or symlinks to other directo†- ries. - -SEE ALSO - bzip2(1), compress(1), cpio(1), gzip(1), mt(1), pax(1), shar(1), xz(1), - libarchive(3), libarchive-formats(5), tar(5) - -STANDARDS - There is no current POSIX standard for the tar command; it appeared in - ISO/IEC 9945-1:1996 (“POSIX.1â€) but was dropped from IEEE Std 1003.1-2001 - (“POSIX.1â€). The options supported by this implementation were developed - by surveying a number of existing tar implementations as well as the old - POSIX specification for tar and the current POSIX specification for pax. - - The ustar and pax interchange file formats are defined by IEEE Std - 1003.1-2001 (“POSIX.1â€) for the pax command. - -HISTORY - A tar command appeared in Seventh Edition Unix, which was released in - January, 1979. There have been numerous other implementations, many of - which extended the file format. John Gilmore's pdtar public-domain im†- plementation (circa November, 1987) was quite influential, and formed the - basis of GNU tar. GNU tar was included as the standard system tar in - FreeBSD beginning with FreeBSD 1.0. - - This is a complete re-implementation based on the libarchive(3) library. - It was first released with FreeBSD 5.4 in May, 2005. - -BUGS - This program follows ISO/IEC 9945-1:1996 (“POSIX.1â€) for the definition - of the -l option. Note that GNU tar prior to version 1.15 treated -l as - a synonym for the --one-file-system option. - - The -C dir option may differ from historic implementations. - - All archive output is written in correctly-sized blocks, even if the out†- put is being compressed. Whether or not the last output block is padded - to a full block size varies depending on the format and the output de†- vice. For tar and cpio formats, the last block of output is padded to a - full block size if the output is being written to standard output or to a - character or block device such as a tape drive. If the output is being - written to a regular file, the last block will not be padded. Many com†- pressors, including gzip(1) and bzip2(1), complain about the null padding - when decompressing an archive created by tar, although they still extract - it correctly. - - The compression and decompression is implemented internally, so there may - be insignificant differences between the compressed output generated by - tar -czf - file - and that generated by - tar -cf - file | gzip - - The default should be to read and write archives to the standard I/O - paths, but tradition (and POSIX) dictates otherwise. - - The r and u modes require that the archive be uncompressed and located in - a regular file on disk. Other archives can be modified using c mode with - the @archive-file extension. - - To archive a file called @foo or -foo you must specify it as ./@foo or - ./-foo, respectively. - - In create mode, a leading ./ is always removed. A leading / is stripped - unless the -P option is specified. - - There needs to be better support for file selection on both create and - extract. - - There is not yet any support for multi-volume archives. - - Converting between dissimilar archive formats (such as tar and cpio) us†- ing the @- convention can cause hard link information to be lost. (This - is a consequence of the incompatible ways that different archive formats - store hardlink information.) - -BSD December 1, 2022 BSD diff --git a/thirdparty/libarchive/doc/text/cpio.5.txt b/thirdparty/libarchive/doc/text/cpio.5.txt deleted file mode 100644 index bf4d6777b..000000000 --- a/thirdparty/libarchive/doc/text/cpio.5.txt +++ /dev/null @@ -1,292 +0,0 @@ -CPIO(5) BSD File Formats Manual CPIO(5) - -NAME - cpio — format of cpio archive files - -DESCRIPTION - The cpio archive format collects any number of files, directories, and - other file system objects (symbolic links, device nodes, etc.) into a - single stream of bytes. - - General Format - Each file system object in a cpio archive comprises a header record with - basic numeric metadata followed by the full pathname of the entry and the - file data. The header record stores a series of integer values that gen†- erally follow the fields in struct stat. (See stat(2) for details.) The - variants differ primarily in how they store those integers (binary, oc†- tal, or hexadecimal). The header is followed by the pathname of the en†- try (the length of the pathname is stored in the header) and any file - data. The end of the archive is indicated by a special record with the - pathname “TRAILER!!!â€. - - PWB format - The PWB binary cpio format is the original format, when cpio was intro†- duced as part of the Programmer's Work Bench system, a variant of 6th - Edition UNIX. It stores numbers as 2-byte and 4-byte binary values. - Each entry begins with a header in the following format: - - struct header_pwb_cpio { - short h_magic; - short h_dev; - short h_ino; - short h_mode; - short h_uid; - short h_gid; - short h_nlink; - short h_majmin; - long h_mtime; - short h_namesize; - long h_filesize; - }; - - The short fields here are 16-bit integer values, while the long fields - are 32 bit integers. Since PWB UNIX, like the 6th Edition UNIX it was - based on, only ran on PDP-11 computers, they are in PDP-endian format, - which has little-endian shorts, and big-endian longs. That is, the long - integer whose hexadecimal representation is 0x12345678 would be stored in - four successive bytes as 0x34, 0x12, 0x78, 0x56. The fields are as fol†- lows: - - h_magic - The integer value octal 070707. - - h_dev, h_ino - The device and inode numbers from the disk. These are used by - programs that read cpio archives to determine when two entries - refer to the same file. Programs that synthesize cpio archives - should be careful to set these to distinct values for each entry. - - h_mode The mode specifies both the regular permissions and the file - type, and it also holds a couple of bits that are irrelevant to - the cpio format, because the field is actually a raw copy of the - mode field in the inode representing the file. These are the - IALLOC flag, which shows that the inode entry is in use, and the - ILARG flag, which shows that the file it represents is large - enough to have indirect blocks pointers in the inode. The mode - is decoded as follows: - - 0100000 IALLOC flag - irrelevant to cpio. - 0060000 This masks the file type bits. - 0040000 File type value for directories. - 0020000 File type value for character special devices. - 0060000 File type value for block special devices. - 0010000 ILARG flag - irrelevant to cpio. - 0004000 SUID bit. - 0002000 SGID bit. - 0001000 Sticky bit. - 0000777 The lower 9 bits specify read/write/execute permissions - for world, group, and user following standard POSIX con†- ventions. - - h_uid, h_gid - The numeric user id and group id of the owner. - - h_nlink - The number of links to this file. Directories always have a - value of at least two here. Note that hardlinked files include - file data with every copy in the archive. - - h_majmin - For block special and character special entries, this field con†- tains the associated device number, with the major number in the - high byte, and the minor number in the low byte. For all other - entry types, it should be set to zero by writers and ignored by - readers. - - h_mtime - Modification time of the file, indicated as the number of seconds - since the start of the epoch, 00:00:00 UTC January 1, 1970. - - h_namesize - The number of bytes in the pathname that follows the header. - This count includes the trailing NUL byte. - - h_filesize - The size of the file. Note that this archive format is limited - to 16 megabyte file sizes, because PWB UNIX, like 6th Edition, - only used an unsigned 24 bit integer for the file size inter†- nally. - - The pathname immediately follows the fixed header. If h_namesize is odd, - an additional NUL byte is added after the pathname. The file data is - then appended, again with an additional NUL appended if needed to get the - next header at an even offset. - - Hardlinked files are not given special treatment; the full file contents - are included with each copy of the file. - - New Binary Format - The new binary cpio format showed up when cpio was adopted into late 7th - Edition UNIX. It is exactly like the PWB binary format, described above, - except for three changes: - - First, UNIX now ran on more than one hardware type, so the endianness of - 16 bit integers must be determined by observing the magic number at the - start of the header. The 32 bit integers are still always stored with - the most significant word first, though, so each of those two, in the - struct shown above, was stored as an array of two 16 bit integers, in the - traditional order. Those 16 bit integers, like all the others in the - struct, were accessed using a macro that byte swapped them if necessary. - - Next, 7th Edition had more file types to store, and the IALLOC and ILARG - flag bits were re-purposed to accommodate these. The revised use of the - various bits is as follows: - - 0170000 This masks the file type bits. - 0140000 File type value for sockets. - 0120000 File type value for symbolic links. For symbolic links, the - link body is stored as file data. - 0100000 File type value for regular files. - 0060000 File type value for block special devices. - 0040000 File type value for directories. - 0020000 File type value for character special devices. - 0010000 File type value for named pipes or FIFOs. - 0004000 SUID bit. - 0002000 SGID bit. - 0001000 Sticky bit. - 0000777 The lower 9 bits specify read/write/execute permissions for - world, group, and user following standard POSIX conventions. - - Finally, the file size field now represents a signed 32 bit integer in - the underlying file system, so the maximum file size has increased to 2 - gigabytes. - - Note that there is no obvious way to tell which of the two binary formats - an archive uses, other than to see which one makes more sense. The typi†- cal error scenario is that a PWB format archive unpacked as if it were in - the new format will create named sockets instead of directories, and then - fail to unpack files that should go in those directories. Running - bsdcpio -itv on an unknown archive will make it obvious which it is: if - it's PWB format, directories will be listed with an 's' instead of a 'd' - as the first character of the mode string, and the larger files will have - a '?' in that position. - - Portable ASCII Format - Version 2 of the Single UNIX Specification (“SUSv2â€) standardized an - ASCII variant that is portable across all platforms. It is commonly - known as the “old character†format or as the “odc†format. It stores - the same numeric fields as the old binary format, but represents them as - 6-character or 11-character octal values. - - struct cpio_odc_header { - char c_magic[6]; - char c_dev[6]; - char c_ino[6]; - char c_mode[6]; - char c_uid[6]; - char c_gid[6]; - char c_nlink[6]; - char c_rdev[6]; - char c_mtime[11]; - char c_namesize[6]; - char c_filesize[11]; - }; - - The fields are identical to those in the new binary format. The name and - file body follow the fixed header. Unlike the binary formats, there is - no additional padding after the pathname or file contents. If the files - being archived are themselves entirely ASCII, then the resulting archive - will be entirely ASCII, except for the NUL byte that terminates the name - field. - - New ASCII Format - The "new" ASCII format uses 8-byte hexadecimal fields for all numbers and - separates device numbers into separate fields for major and minor num†- bers. - - struct cpio_newc_header { - char c_magic[6]; - char c_ino[8]; - char c_mode[8]; - char c_uid[8]; - char c_gid[8]; - char c_nlink[8]; - char c_mtime[8]; - char c_filesize[8]; - char c_devmajor[8]; - char c_devminor[8]; - char c_rdevmajor[8]; - char c_rdevminor[8]; - char c_namesize[8]; - char c_check[8]; - }; - - Except as specified below, the fields here match those specified for the - new binary format above. - - magic The string “070701â€. - - check This field is always set to zero by writers and ignored by read†- ers. See the next section for more details. - - The pathname is followed by NUL bytes so that the total size of the fixed - header plus pathname is a multiple of four. Likewise, the file data is - padded to a multiple of four bytes. Note that this format supports only - 4 gigabyte files (unlike the older ASCII format, which supports 8 giga†- byte files). - - In this format, hardlinked files are handled by setting the filesize to - zero for each entry except the first one that appears in the archive. - - New CRC Format - The CRC format is identical to the new ASCII format described in the pre†- vious section except that the magic field is set to “070702†and the - check field is set to the sum of all bytes in the file data. This sum is - computed treating all bytes as unsigned values and using unsigned arith†- metic. Only the least-significant 32 bits of the sum are stored. - - HP variants - The cpio implementation distributed with HPUX used XXXX but stored device - numbers differently XXX. - - Other Extensions and Variants - Sun Solaris uses additional file types to store extended file data, in†- cluding ACLs and extended attributes, as special entries in cpio ar†- chives. - - XXX Others? XXX - -SEE ALSO - cpio(1), tar(5) - -STANDARDS - The cpio utility is no longer a part of POSIX or the Single Unix Stan†- dard. It last appeared in Version 2 of the Single UNIX Specification - (“SUSv2â€). It has been supplanted in subsequent standards by pax(1). - The portable ASCII format is currently part of the specification for the - pax(1) utility. - -HISTORY - The original cpio utility was written by Dick Haight while working in - AT&T's Unix Support Group. It appeared in 1977 as part of PWB/UNIX 1.0, - the “Programmer's Work Bench†derived from Version 6 AT&T UNIX that was - used internally at AT&T. Both the new binary and old character formats - were in use by 1980, according to the System III source released by SCO - under their “Ancient Unix†license. The character format was adopted as - part of IEEE Std 1003.1-1988 (“POSIX.1â€). XXX when did "newc" appear? - Who invented it? When did HP come out with their variant? When did Sun - introduce ACLs and extended attributes? XXX - -BUGS - The “CRC†format is mis-named, as it uses a simple checksum and not a - cyclic redundancy check. - - The binary formats are limited to 16 bits for user id, group id, device, - and inode numbers. They are limited to 16 megabyte and 2 gigabyte file - sizes for the older and newer variants, respectively. - - The old ASCII format is limited to 18 bits for the user id, group id, de†- vice, and inode numbers. It is limited to 8 gigabyte file sizes. - - The new ASCII format is limited to 4 gigabyte file sizes. - - None of the cpio formats store user or group names, which are essential - when moving files between systems with dissimilar user or group number†- ing. - - Especially when writing older cpio variants, it may be necessary to map - actual device/inode values to synthesized values that fit the available - fields. With very large filesystems, this may be necessary even for the - newer formats. - -BSD December 23, 2011 BSD diff --git a/thirdparty/libarchive/doc/text/libarchive-formats.5.txt b/thirdparty/libarchive/doc/text/libarchive-formats.5.txt deleted file mode 100644 index 36f136b5a..000000000 --- a/thirdparty/libarchive/doc/text/libarchive-formats.5.txt +++ /dev/null @@ -1,335 +0,0 @@ -LIBARCHIVE-FORMATS(5) BSD File Formats Manual LIBARCHIVE-FORMATS(5) - -NAME - libarchive-formats — archive formats supported by the libarchive library - -DESCRIPTION - The libarchive(3) library reads and writes a variety of streaming archive - formats. Generally speaking, all of these archive formats consist of a - series of “entriesâ€. Each entry stores a single file system object, such - as a file, directory, or symbolic link. - - The following provides a brief description of each format supported by - libarchive, with some information about recognized extensions or limita†- tions of the current library support. Note that just because a format is - supported by libarchive does not imply that a program that uses - libarchive will support that format. Applications that use libarchive - specify which formats they wish to support, though many programs do use - libarchive convenience functions to enable all supported formats. - - Tar Formats - The libarchive(3) library can read most tar archives. It can write - POSIX-standard “ustar†and “pax interchange†formats as well as v7 tar - format and a subset of the legacy GNU tar format. - - All tar formats store each entry in one or more 512-byte records. The - first record is used for file metadata, including filename, timestamp, - and mode information, and the file data is stored in subsequent records. - Later variants have extended this by either appropriating undefined areas - of the header record, extending the header to multiple records, or by - storing special entries that modify the interpretation of subsequent en†- tries. - - gnutar The libarchive(3) library can read most GNU-format tar archives. - It currently supports the most popular GNU extensions, including - modern long filename and linkname support, as well as atime and - ctime data. The libarchive library does not support multi-volume - archives, nor the old GNU long filename format. It can read GNU - sparse file entries, including the new POSIX-based formats. - - The libarchive(3) library can write GNU tar format, including - long filename and linkname support, as well as atime and ctime - data. - - pax The libarchive(3) library can read and write POSIX-compliant pax - interchange format archives. Pax interchange format archives are - an extension of the older ustar format that adds a separate entry - with additional attributes stored as key/value pairs immediately - before each regular entry. The presence of these additional en†- tries is the only difference between pax interchange format and - the older ustar format. The extended attributes are of unlimited - length and are stored as UTF-8 Unicode strings. Keywords defined - in the standard are in all lowercase; vendors are allowed to de†- fine custom keys by preceding them with the vendor name in all - uppercase. When writing pax archives, libarchive uses many of - the SCHILY keys defined by Joerg Schilling's “star†archiver and - a few LIBARCHIVE keys. The libarchive library can read most of - the SCHILY keys and most of the GNU keys introduced by GNU tar. - It silently ignores any keywords that it does not understand. - - The pax interchange format converts filenames to Unicode and - stores them using the UTF-8 encoding. Prior to libarchive 3.0, - libarchive erroneously assumed that the system wide-character - routines natively supported Unicode. This caused it to mis-han†- dle non-ASCII filenames on systems that did not satisfy this as†- sumption. - - restricted pax - The libarchive library can also write pax archives in which it - attempts to suppress the extended attributes entry whenever pos†- sible. The result will be identical to a ustar archive unless - the extended attributes entry is required to store a long file - name, long linkname, extended ACL, file flags, or if any of the - standard ustar data (user name, group name, UID, GID, etc) cannot - be fully represented in the ustar header. In all cases, the re†- sult can be dearchived by any program that can read POSIX-compli†- ant pax interchange format archives. Programs that correctly - read ustar format (see below) will also be able to read this for†- mat; any extended attributes will be extracted as separate files - stored in PaxHeader directories. - - ustar The libarchive library can both read and write this format. This - format has the following limitations: - • Device major and minor numbers are limited to 21 bits. Nodes - with larger numbers will not be added to the archive. - • Path names in the archive are limited to 255 bytes. (Shorter - if there is no / character in exactly the right place.) - • Symbolic links and hard links are stored in the archive with - the name of the referenced file. This name is limited to 100 - bytes. - • Extended attributes, file flags, and other extended security - information cannot be stored. - • Archive entries are limited to 8 gigabytes in size. - Note that the pax interchange format has none of these restric†- tions. The ustar format is old and widely supported. It is rec†- ommended when compatibility is the primary concern. - - v7 The libarchive library can read and write the legacy v7 tar for†- mat. This format has the following limitations: - • Only regular files, directories, and symbolic links can be - archived. Block and character device nodes, FIFOs, and sock†- ets cannot be archived. - • Path names in the archive are limited to 100 bytes. - • Symbolic links and hard links are stored in the archive with - the name of the referenced file. This name is limited to 100 - bytes. - • User and group information are stored as numeric IDs; there - is no provision for storing user or group names. - • Extended attributes, file flags, and other extended security - information cannot be stored. - • Archive entries are limited to 8 gigabytes in size. - Generally, users should prefer the ustar format for portability - as the v7 tar format is both less useful and less portable. - - The libarchive library also reads a variety of commonly-used extensions - to the basic tar format. These extensions are recognized automatically - whenever they appear. - - Numeric extensions. - The POSIX standards require fixed-length numeric fields to be - written with some character position reserved for terminators. - Libarchive allows these fields to be written without terminator - characters. This extends the allowable range; in particular, us†- tar archives with this extension can support entries up to 64 gi†- gabytes in size. Libarchive also recognizes base-256 values in - most numeric fields. This essentially removes all limitations on - file size, modification time, and device numbers. - - Solaris extensions - Libarchive recognizes ACL and extended attribute records written - by Solaris tar. - - The first tar program appeared in Seventh Edition Unix in 1979. The - first official standard for the tar file format was the “ustar†(Unix - Standard Tar) format defined by POSIX in 1988. POSIX.1-2001 extended the - ustar format to create the “pax interchange†format. - - Cpio Formats - The libarchive library can read and write a number of common cpio vari†- ants. A cpio archive stores each entry as a fixed-size header followed - by a variable-length filename and variable-length data. Unlike the tar - format, the cpio format does only minimal padding of the header or file - data. There are several cpio variants, which differ primarily in how - they store the initial header: some store the values as octal or hexadec†- imal numbers in ASCII, others as binary values of varying byte order and - length. - - binary The libarchive library transparently reads both big-endian and - little-endian variants of the the two binary cpio formats; the - original one from PWB/UNIX, and the later, more widely used, - variant. This format used 32-bit binary values for file size and - mtime, and 16-bit binary values for the other fields. The for†- mats support only the file types present in UNIX at the time of - their creation. File sizes are limited to 24 bits in the PWB - format, because of the limits of the file system, and to 31 bits - in the newer binary format, where signed 32 bit longs were used. - - odc This is the POSIX standardized format, which is officially known - as the “cpio interchange format†or the “octet-oriented cpio - archive format†and sometimes unofficially referred to as the - “old character formatâ€. This format stores the header contents - as octal values in ASCII. It is standard, portable, and immune - from byte-order confusion. File sizes and mtime are limited to - 33 bits (8GB file size), other fields are limited to 18 bits. - - SVR4/newc - The libarchive library can read both CRC and non-CRC variants of - this format. The SVR4 format uses eight-digit hexadecimal values - for all header fields. This limits file size to 4GB, and also - limits the mtime and other fields to 32 bits. The SVR4 format - can optionally include a CRC of the file contents, although - libarchive does not currently verify this CRC. - - Cpio first appeared in PWB/UNIX 1.0, which was released within AT&T in - 1977. PWB/UNIX 1.0 formed the basis of System III Unix, released outside - of AT&T in 1981. This makes cpio older than tar, although cpio was not - included in Version 7 AT&T Unix. As a result, the tar command became - much better known in universities and research groups that used Version - 7. The combination of the find and cpio utilities provided very precise - control over file selection. Unfortunately, the format has many limita†- tions that make it unsuitable for widespread use. Only the POSIX format - permits files over 4GB, and its 18-bit limit for most other fields makes - it unsuitable for modern systems. In addition, cpio formats only store - numeric UID/GID values (not usernames and group names), which can make it - very difficult to correctly transfer archives across systems with dissim†- ilar user numbering. - - Shar Formats - A “shell archive†is a shell script that, when executed on a POSIX-com†- pliant system, will recreate a collection of file system objects. The - libarchive library can write two different kinds of shar archives: - - shar The traditional shar format uses a limited set of POSIX commands, - including echo(1), mkdir(1), and sed(1). It is suitable for - portably archiving small collections of plain text files. How†- ever, it is not generally well-suited for large archives (many - implementations of sh(1) have limits on the size of a script) nor - should it be used with non-text files. - - shardump - This format is similar to shar but encodes files using - uuencode(1) so that the result will be a plain text file regard†- less of the file contents. It also includes additional shell - commands that attempt to reproduce as many file attributes as - possible, including owner, mode, and flags. The additional com†- mands used to restore file attributes make shardump archives less - portable than plain shar archives. - - ISO9660 format - Libarchive can read and extract from files containing ISO9660-compliant - CDROM images. In many cases, this can remove the need to burn a physical - CDROM just in order to read the files contained in an ISO9660 image. It - also avoids security and complexity issues that come with virtual mounts - and loopback devices. Libarchive supports the most common Rockridge ex†- tensions and has partial support for Joliet extensions. If both exten†- sions are present, the Joliet extensions will be used and the Rockridge - extensions will be ignored. In particular, this can create problems with - hardlinks and symlinks, which are supported by Rockridge but not by - Joliet. - - Libarchive reads ISO9660 images using a streaming strategy. This allows - it to read compressed images directly (decompressing on the fly) and al†- lows it to read images directly from network sockets, pipes, and other - non-seekable data sources. This strategy works well for optimized - ISO9660 images created by many popular programs. Such programs collect - all directory information at the beginning of the ISO9660 image so it can - be read from a physical disk with a minimum of seeking. However, not all - ISO9660 images can be read in this fashion. - - Libarchive can also write ISO9660 images. Such images are fully opti†- mized with the directory information preceding all file data. This is - done by storing all file data to a temporary file while collecting direc†- tory information in memory. When the image is finished, libarchive - writes out the directory structure followed by the file data. The loca†- tion used for the temporary file can be changed by the usual environment - variables. - - Zip format - Libarchive can read and write zip format archives that have uncompressed - entries and entries compressed with the “deflate†algorithm. Other zip - compression algorithms are not supported. It can extract jar archives, - archives that use Zip64 extensions and self-extracting zip archives. - Libarchive can use either of two different strategies for reading Zip ar†- chives: a streaming strategy which is fast and can handle extremely large - archives, and a seeking strategy which can correctly process self-ex†- tracting Zip archives and archives with deleted members or other in-place - modifications. - - The streaming reader processes Zip archives as they are read. It can - read archives of arbitrary size from tape or network sockets, and can de†- code Zip archives that have been separately compressed or encoded. How†- ever, self-extracting Zip archives and archives with certain types of - modifications cannot be correctly handled. Such archives require that - the reader first process the Central Directory, which is ordinarily lo†- cated at the end of a Zip archive and is thus inaccessible to the stream†- ing reader. If the program using libarchive has enabled seek support, - then libarchive will use this to processes the central directory first. - - In particular, the seeking reader must be used to correctly handle self- - extracting archives. Such archives consist of a program followed by a - regular Zip archive. The streaming reader cannot parse the initial pro†- gram portion, but the seeking reader starts by reading the Central Direc†- tory from the end of the archive. Similarly, Zip archives that have been - modified in-place can have deleted entries or other garbage data that can - only be accurately detected by first reading the Central Directory. - - Archive (library) file format - The Unix archive format (commonly created by the ar(1) archiver) is a - general-purpose format which is used almost exclusively for object files - to be read by the link editor ld(1). The ar format has never been stan†- dardised. There are two common variants: the GNU format derived from - SVR4, and the BSD format, which first appeared in 4.4BSD. The two differ - primarily in their handling of filenames longer than 15 characters: the - GNU/SVR4 variant writes a filename table at the beginning of the archive; - the BSD format stores each long filename in an extension area adjacent to - the entry. Libarchive can read both extensions, including archives that - may include both types of long filenames. Programs using libarchive can - write GNU/SVR4 format if they provide an entry called // containing a - filename table to be written into the archive before any of the entries. - Any entries whose names are not in the filename table will be written us†- ing BSD-style long filenames. This can cause problems for programs such - as GNU ld that do not support the BSD-style long filenames. - - mtree - Libarchive can read and write files in mtree(5) format. This format is - not a true archive format, but rather a textual description of a file hi†- erarchy in which each line specifies the name of a file and provides spe†- cific metadata about that file. Libarchive can read all of the keywords - supported by both the NetBSD and FreeBSD versions of mtree(8), although - many of the keywords cannot currently be stored in an archive_entry ob†- ject. When writing, libarchive supports use of the - archive_write_set_options(3) interface to specify which keywords should - be included in the output. If libarchive was compiled with access to - suitable cryptographic libraries (such as the OpenSSL libraries), it can - compute hash entries such as sha512 or md5 from file data being written - to the mtree writer. - - When reading an mtree file, libarchive will locate the corresponding - files on disk using the contents keyword if present or the regular file†- name. If it can locate and open the file on disk, it will use that to - fill in any metadata that is missing from the mtree file and will read - the file contents and return those to the program using libarchive. If - it cannot locate and open the file on disk, libarchive will return an er†- ror for any attempt to read the entry body. - - 7-Zip - Libarchive can read and write 7-Zip format archives. TODO: Need more in†- formation - - CAB - Libarchive can read Microsoft Cabinet ( “CABâ€) format archives. TODO: - Need more information. - - LHA - TODO: Information about libarchive's LHA support - - RAR - Libarchive has limited support for reading RAR format archives. Cur†- rently, libarchive can read RARv3 format archives which have been either - created uncompressed, or compressed using any of the compression methods - supported by the RARv3 format. Libarchive can also read self-extracting - RAR archives. - - Warc - Libarchive can read and write “web archivesâ€. TODO: Need more informa†- tion - - XAR - Libarchive can read and write the XAR format used by many Apple tools. - TODO: Need more information - -SEE ALSO - ar(1), cpio(1), mkisofs(1), shar(1), tar(1), zip(1), zlib(3), cpio(5), - mtree(5), tar(5) - -BSD December 27, 2016 BSD diff --git a/thirdparty/libarchive/doc/text/libarchive.3.txt b/thirdparty/libarchive/doc/text/libarchive.3.txt deleted file mode 100644 index 9cf869e13..000000000 --- a/thirdparty/libarchive/doc/text/libarchive.3.txt +++ /dev/null @@ -1,160 +0,0 @@ -LIBARCHIVE(3) BSD Library Functions Manual LIBARCHIVE(3) - -NAME - libarchive — functions for reading and writing streaming archives - -OVERVIEW - The libarchive library provides a flexible interface for reading and - writing archives in various formats such as tar and cpio. libarchive - also supports reading and writing archives compressed using various com†- pression filters such as gzip and bzip2. The library is inherently - stream-oriented; readers serially iterate through the archive, writers - serially add things to the archive. In particular, note that there is - currently no built-in support for random access nor for in-place modifi†- cation. - - When reading an archive, the library automatically detects the format and - the compression. The library currently has read support for: - • old-style tar archives, - • most variants of the POSIX “ustar†format, - • the POSIX “pax interchange†format, - • GNU-format tar archives, - • most common cpio archive formats, - • 7-Zip archives, - • ar archives (including GNU/SysV and BSD extensions), - • Microsoft CAB archives, - • ISO9660 CD images (including RockRidge and Joliet extensions), - • LHA archives, - • mtree file tree descriptions, - • RAR and most RAR5 archives, - • WARC archives, - • XAR archives, - • Zip archives. - The library automatically detects archives compressed with compress(1), - bzip2(1), grzip(1), gzip(1), lrzip(1), lz4(1), lzip(1), lzop(1), xz(1), - or zstd(1) and decompresses them transparently. Decompression of some - formats requires external decompressor utilities. It can similarly de†- tect and decode archives processed with uuencode(1) or which have an - rpm(1) header. - - When writing an archive, you can specify the compression to be used and - the format to use. The library can write - • POSIX-standard “ustar†archives, - • POSIX “pax interchange format†archives, - • cpio archives, - • 7-Zip archives, - • ar archives, - • two different variants of shar archives, - • ISO9660 CD images, - • mtree file tree descriptions, - • XAR archives, - • Zip archive. - Pax interchange format is an extension of the tar archive format that - eliminates essentially all of the limitations of historic tar formats in - a standard fashion that is supported by POSIX-compliant pax(1) implemen†- tations on many systems as well as several newer implementations of - tar(1). Note that the default write format will suppress the pax ex†- tended attributes for most entries; explicitly requesting pax format will - enable those attributes for all entries. - - The read and write APIs are accessed through the archive_read_XXX() func†- tions and the archive_write_XXX() functions, respectively, and either can - be used independently of the other. - - The rest of this manual page provides an overview of the library opera†- tion. More detailed information can be found in the individual manual - pages for each API or utility function. - -READING AN ARCHIVE - See archive_read(3). - -WRITING AN ARCHIVE - See archive_write(3). - -WRITING ENTRIES TO DISK - The archive_write_disk(3) API allows you to write archive_entry(3) ob†- jects to disk using the same API used by archive_write(3). The - archive_write_disk(3) API is used internally by archive_read_extract(); - using it directly can provide greater control over how entries get writ†- ten to disk. This API also makes it possible to share code between ar†- chive-to-archive copy and archive-to-disk extraction operations. - -READING ENTRIES FROM DISK - The archive_read_disk(3) supports for populating archive_entry(3) objects - from information in the filesystem. This includes the information acces†- sible from the stat(2) system call as well as ACLs, extended attributes, - and other metadata. The archive_read_disk(3) API also supports iterating - over directory trees, which allows directories of files to be read using - an API compatible with the archive_read(3) API. - -DESCRIPTION - Detailed descriptions of each function are provided by the corresponding - manual pages. - - All of the functions utilize an opaque struct archive datatype that pro†- vides access to the archive contents. - - The struct archive_entry structure contains a complete description of a - single archive entry. It uses an opaque interface that is fully docu†- mented in archive_entry(3). - - Users familiar with historic formats should be aware that the newer vari†- ants have eliminated most restrictions on the length of textual fields. - Clients should not assume that filenames, link names, user names, or - group names are limited in length. In particular, pax interchange format - can easily accommodate pathnames in arbitrary character sets that exceed - PATH_MAX. - -RETURN VALUES - Most functions return ARCHIVE_OK (zero) on success, non-zero on error. - The return value indicates the general severity of the error, ranging - from ARCHIVE_WARN, which indicates a minor problem that should probably - be reported to the user, to ARCHIVE_FATAL, which indicates a serious - problem that will prevent any further operations on this archive. On er†- ror, the archive_errno() function can be used to retrieve a numeric error - code (see errno(2)). The archive_error_string() returns a textual error - message suitable for display. - - archive_read_new() and archive_write_new() return pointers to an allo†- cated and initialized struct archive object. - - archive_read_data() and archive_write_data() return a count of the number - of bytes actually read or written. A value of zero indicates the end of - the data for this entry. A negative value indicates an error, in which - case the archive_errno() and archive_error_string() functions can be used - to obtain more information. - -ENVIRONMENT - There are character set conversions within the archive_entry(3) functions - that are impacted by the currently-selected locale. - -SEE ALSO - tar(1), archive_entry(3), archive_read(3), archive_util(3), - archive_write(3), tar(5) - -HISTORY - The libarchive library first appeared in FreeBSD 5.3. - -AUTHORS - The libarchive library was originally written by Tim Kientzle - . - -BUGS - Some archive formats support information that is not supported by struct - archive_entry. Such information cannot be fully archived or restored us†- ing this library. This includes, for example, comments, character sets, - or the arbitrary key/value pairs that can appear in pax interchange for†- mat archives. - - Conversely, of course, not all of the information that can be stored in - an struct archive_entry is supported by all formats. For example, cpio - formats do not support nanosecond timestamps; old tar formats do not sup†- port large device numbers. - - The ISO9660 reader cannot yet read all ISO9660 images; it should learn - how to seek. - - The AR writer requires the client program to use two passes, unlike all - other libarchive writers. - -BSD March 18, 2012 BSD diff --git a/thirdparty/libarchive/doc/text/libarchive_changes.3.txt b/thirdparty/libarchive/doc/text/libarchive_changes.3.txt deleted file mode 100644 index fff1b3e78..000000000 --- a/thirdparty/libarchive/doc/text/libarchive_changes.3.txt +++ /dev/null @@ -1,260 +0,0 @@ -LIBARCHIVE_CHANGES(3) BSD Library Functions Manual LIBARCHIVE_CHANGES(3) - -NAME - libarchive_changes — changes in libarchive interface - -CHANGES IN LIBARCHIVE 3 - This page describes user-visible changes in libarchive3, and lists public - functions and other symbols changed, deprecated or removed in - libarchive3, along with their replacements if any. - - Multiple Filters - Libarchive2 permitted a single (input or output) filter active on an ar†- chive. Libarchive3 extends this into a variable-length stack. Where - archive_write_set_compression_XXX() would replace any existing filter, - archive_write_add_filter_XXX() extends the write pipeline with another - filter. - - Character Set Handling - Libarchive2 assumed that the local platform uses Unicode as the native - wchar_t encoding, which is true on Windows, modern Linux, and a few other - systems, but is certainly not universal. As a result, pax format ar†- chives were written incorrectly on some systems, since pax format re†- quires UTF-8 and libarchive 2 incorrectly assumed that wchar_t strings - can be easily converted to UTF-8. - - Libarchive3 uses the standard iconv library to convert between character - sets and is introducing the notion of a “default character set for the - archiveâ€. To support this, archive_entry objects can now be bound to a - particular archive when they are created. The automatic character set - conversions performed by archive_entry objects when reading and writing - filenames, usernames, and other strings will now use an appropriate de†- fault character set: - - If the archive_entry object is bound to an archive, it will use the de†- fault character set for that archive. - - The platform default character encoding (as returned by - nl_langinfo(CHARSET)) will be used if nothing else is specified. - - Libarchive3 also introduces charset options to many of the archive read†- ers and writers to control the character set that will be used for file†- names written in those archives. When possible, this will be set auto†- matically based on information in the archive itself. Combining this - with the notion of a default character set for the archive should allow - you to configure libarchive to read archives from other platforms and - have the filenames and other information transparently converted to the - character encoding suitable for your application. - - Prototype Changes - These changes break binary compatibility; libarchive3 has a new shared - library version to reflect these changes. The library now uses portable - wide types such as int64_t instead of less-portable types such as off_t, - gid_t, uid_t, and ino_t. - - There are a few cases where these changes will affect your source code: - - • In some cases, libarchive's wider types will introduce the possibil†- ity of truncation: for example, on a system with a 16-bit uid_t, you - risk having uid 65536 be truncated to uid 0, which can cause serious - security problems. - - • Typedef function pointer types will be incompatible. For example, - if you define custom skip callbacks, you may have to use code simi†- lar to the following if you want to support building against - libarchive2 and libarchive3: - - #if ARCHIVE_VERSION_NUMBER < 3000000 - typedef off_t myoff_t; - #else - typedef int64_t myoff_t; - #endif - - myoff_t - my_skip_function(struct archive *a, void *v, myoff_t o) - { - ... implementation ... - } - - Affected functions: - - • archive_entry_gid(), archive_entry_set_gid() - • archive_entry_uid(), archive_entry_set_uid() - • archive_entry_ino(), archive_entry_set_ino() - • archive_read_data_block(), archive_write_data_block() - • archive_read_disk_gname(), archive_read_disk_uname() - • archive_read_disk_set_gname_lookup(), - archive_read_disk_set_group_lookup(), - archive_read_disk_set_uname_lookup(), - archive_read_disk_set_user_lookup() - • archive_skip_callback() - • archive_read_extract_set_skip_file(), - archive_write_disk_set_skip_file(), archive_write_set_skip_file() - • archive_write_disk_set_group_lookup(), - archive_write_disk_set_user_lookup() - - Where these functions or their arguments took or returned gid_t, ino_t, - off_t, or uid_t they now take or return int64_t or equivalent. - - Deprecated Symbols - Symbols deprecated in libarchive3 will be removed in libarchive4. These - symbols, along with their replacements if any, are listed below: - - archive_position_compressed(), archive_position_uncompressed() - archive_filter_bytes() - - archive_compression() - archive_filter_code() - - archive_compression_name() - archive_filter_name() - - archive_read_finish(), archive_write_finish() - archive_read_free(), archive_write_free() - - archive_read_open_file(), archive_write_open_file() - archive_read_open_filename(), archive_write_open_filename() - - archive_read_support_compression_all() - archive_read_support_filter_all() - - archive_read_support_compression_bzip2() - archive_read_support_filter_bzip2() - - archive_read_support_compression_compress() - archive_read_support_filter_compress() - - archive_read_support_compression_gzip() - archive_read_support_filter_gzip() - - archive_read_support_compression_lzip() - archive_read_support_filter_lzip() - - archive_read_support_compression_lzma() - archive_read_support_filter_lzma() - - archive_read_support_compression_none() - archive_read_support_filter_none() - - archive_read_support_compression_program() - archive_read_support_filter_program() - - archive_read_support_compression_program_signature() - archive_read_support_filter_program_signature() - - archive_read_support_compression_rpm() - archive_read_support_filter_rpm() - - archive_read_support_compression_uu() - archive_read_support_filter_uu() - - archive_read_support_compression_xz() - archive_read_support_filter_xz() - - archive_write_set_compression_bzip2() - archive_write_add_filter_bzip2() - - archive_write_set_compression_compress() - archive_write_add_filter_compress() - - archive_write_set_compression_gzip() - archive_write_add_filter_gzip() - - archive_write_set_compression_lzip() - archive_write_add_filter_lzip() - - archive_write_set_compression_lzma() - archive_write_add_filter_lzma() - - archive_write_set_compression_none() - archive_write_add_filter_none() - - archive_write_set_compression_program() - archive_write_add_filter_program() - - archive_write_set_compression_filter() - archive_write_add_filter_filter() - - Removed Symbols - These symbols, listed below along with their replacements if any, were - deprecated in libarchive2, and are not part of libarchive3. - - archive_api_feature() - archive_version_number() - - archive_api_version() - archive_version_number() - - archive_version() - archive_version_string() - - archive_version_stamp() - archive_version_number() - - archive_read_set_filter_options() - archive_read_set_options() or archive_read_set_filter_option() - - archive_read_set_format_options() - archive_read_set_options() or archive_read_set_format_option() - - archive_write_set_filter_options() - archive_write_set_options() or archive_write_set_filter_option() - - archive_write_set_format_options() - archive_write_set_options() or archive_write_set_format_option() - - ARCHIVE_API_FEATURE - ARCHIVE_VERSION_NUMBER - - ARCHIVE_API_VERSION - ARCHIVE_VERSION_NUMBER - - ARCHIVE_VERSION_STAMP - ARCHIVE_VERSION_NUMBER - - ARCHIVE_LIBRARY_VERSION - ARCHIVE_VERSION_STRING - - ARCHIVE_COMPRESSION_NONE - ARCHIVE_FILTER_NONE - - ARCHIVE_COMPRESSION_GZIP - ARCHIVE_FILTER_GZIP - - ARCHIVE_COMPRESSION_BZIP2 - ARCHIVE_FILTER_BZIP2 - - ARCHIVE_COMPRESSION_COMPRESS - ARCHIVE_FILTER_COMPRESS - - ARCHIVE_COMPRESSION_PROGRAM - ARCHIVE_FILTER_PROGRAM - - ARCHIVE_COMPRESSION_LZMA - ARCHIVE_FILTER_LZMA - - ARCHIVE_COMPRESSION_XZ - ARCHIVE_FILTER_XZ - - ARCHIVE_COMPRESSION_UU - ARCHIVE_FILTER_UU - - ARCHIVE_COMPRESSION_RPM - ARCHIVE_FILTER_RPM - - ARCHIVE_COMPRESSION_LZIP - ARCHIVE_FILTER_LZIP - - ARCHIVE_BYTES_PER_RECORD - 512 - - ARCHIVE_DEFAULT_BYTES_PER_BLOCK - 10240 - -SEE ALSO - archive_read(3), archive_read_filter(3), archive_read_format(3), - archive_read_set_options(3), archive_util(3), archive_write(3), - archive_write_filter(3), archive_write_format(3), - archive_write_set_options(3), libarchive(3) - -BSD December 23, 2011 BSD diff --git a/thirdparty/libarchive/doc/text/libarchive_internals.3.txt b/thirdparty/libarchive/doc/text/libarchive_internals.3.txt deleted file mode 100644 index 38ba442a5..000000000 --- a/thirdparty/libarchive/doc/text/libarchive_internals.3.txt +++ /dev/null @@ -1,247 +0,0 @@ -LIBARCHIVE_INTERNALS(3) BSD Library Functions Manual LIBARCHIVE_INTERNALS(3) - -NAME - libarchive_internals — description of libarchive internal interfaces - -OVERVIEW - The libarchive library provides a flexible interface for reading and - writing streaming archive files such as tar and cpio. Internally, it - follows a modular layered design that should make it easy to add new ar†- chive and compression formats. - -GENERAL ARCHITECTURE - Externally, libarchive exposes most operations through an opaque, object- - style interface. The archive_entry(3) objects store information about a - single filesystem object. The rest of the library provides facilities to - write archive_entry(3) objects to archive files, read them from archive - files, and write them to disk. (There are plans to add a facility to - read archive_entry(3) objects from disk as well.) - - The read and write APIs each have four layers: a public API layer, a for†- mat layer that understands the archive file format, a compression layer, - and an I/O layer. The I/O layer is completely exposed to clients who can - replace it entirely with their own functions. - - In order to provide as much consistency as possible for clients, some - public functions are virtualized. Eventually, it should be possible for - clients to open an archive or disk writer, and then use a single set of - code to select and write entries, regardless of the target. - -READ ARCHITECTURE - From the outside, clients use the archive_read(3) API to manipulate an - archive object to read entries and bodies from an archive stream. Inter†- nally, the archive object is cast to an archive_read object, which holds - all read-specific data. The API has four layers: The lowest layer is the - I/O layer. This layer can be overridden by clients, but most clients use - the packaged I/O callbacks provided, for example, by - archive_read_open_memory(3), and archive_read_open_fd(3). The compres†- sion layer calls the I/O layer to read bytes and decompresses them for - the format layer. The format layer unpacks a stream of uncompressed - bytes and creates archive_entry objects from the incoming data. The API - layer tracks overall state (for example, it prevents clients from reading - data before reading a header) and invokes the format and compression - layer operations through registered function pointers. In particular, - the API layer drives the format-detection process: When opening the ar†- chive, it reads an initial block of data and offers it to each registered - compression handler. The one with the highest bid is initialized with - the first block. Similarly, the format handlers are polled to see which - handler is the best for each archive. (Prior to 2.4.0, the format bid†- ders were invoked for each entry, but this design hindered error recov†- ery.) - - I/O Layer and Client Callbacks - The read API goes to some lengths to be nice to clients. As a result, - there are few restrictions on the behavior of the client callbacks. - - The client read callback is expected to provide a block of data on each - call. A zero-length return does indicate end of file, but otherwise - blocks may be as small as one byte or as large as the entire file. In - particular, blocks may be of different sizes. - - The client skip callback returns the number of bytes actually skipped, - which may be much smaller than the skip requested. The only requirement - is that the skip not be larger. In particular, clients are allowed to - return zero for any skip that they don't want to handle. The skip call†- back must never be invoked with a negative value. - - Keep in mind that not all clients are reading from disk: clients reading - from networks may provide different-sized blocks on every request and - cannot skip at all; advanced clients may use mmap(2) to read the entire - file into memory at once and return the entire file to libarchive as a - single block; other clients may begin asynchronous I/O operations for the - next block on each request. - - Decompresssion Layer - The decompression layer not only handles decompression, it also buffers - data so that the format handlers see a much nicer I/O model. The decom†- pression API is a two stage peek/consume model. A read_ahead request - specifies a minimum read amount; the decompression layer must provide a - pointer to at least that much data. If more data is immediately avail†- able, it should return more: the format layer handles bulk data reads by - asking for a minimum of one byte and then copying as much data as is - available. - - A subsequent call to the consume() function advances the read pointer. - Note that data returned from a read_ahead() call is guaranteed to remain - in place until the next call to read_ahead(). Intervening calls to - consume() should not cause the data to move. - - Skip requests must always be handled exactly. Decompression handlers - that cannot seek forward should not register a skip handler; the API - layer fills in a generic skip handler that reads and discards data. - - A decompression handler has a specific lifecycle: - Registration/Configuration - When the client invokes the public support function, the decom†- pression handler invokes the internal - __archive_read_register_compression() function to provide bid and - initialization functions. This function returns NULL on error or - else a pointer to a struct decompressor_t. This structure con†- tains a void * config slot that can be used for storing any cus†- tomization information. - Bid The bid function is invoked with a pointer and size of a block of - data. The decompressor can access its config data through the - decompressor element of the archive_read object. The bid func†- tion is otherwise stateless. In particular, it must not perform - any I/O operations. - - The value returned by the bid function indicates its suitability - for handling this data stream. A bid of zero will ensure that - this decompressor is never invoked. Return zero if magic number - checks fail. Otherwise, your initial implementation should re†- turn the number of bits actually checked. For example, if you - verify two full bytes and three bits of another byte, bid 19. - Note that the initial block may be very short; be careful to only - inspect the data you are given. (The current decompressors re†- quire two bytes for correct bidding.) - Initialize - The winning bidder will have its init function called. This - function should initialize the remaining slots of the struct - decompressor_t object pointed to by the decompressor element of - the archive_read object. In particular, it should allocate any - working data it needs in the data slot of that structure. The - init function is called with the block of data that was used for - tasting. At this point, the decompressor is responsible for all - I/O requests to the client callbacks. The decompressor is free - to read more data as and when necessary. - Satisfy I/O requests - The format handler will invoke the read_ahead, consume, and skip - functions as needed. - Finish The finish method is called only once when the archive is closed. - It should release anything stored in the data and config slots of - the decompressor object. It should not invoke the client close - callback. - - Format Layer - The read formats have a similar lifecycle to the decompression handlers: - Registration - Allocate your private data and initialize your pointers. - Bid Formats bid by invoking the read_ahead() decompression method but - not calling the consume() method. This allows each bidder to - look ahead in the input stream. Bidders should not look further - ahead than necessary, as long look aheads put pressure on the de†- compression layer to buffer lots of data. Most formats only re†- quire a few hundred bytes of look ahead; look aheads of a few - kilobytes are reasonable. (The ISO9660 reader sometimes looks - ahead by 48k, which should be considered an upper limit.) - Read header - The header read is usually the most complex part of any format. - There are a few strategies worth mentioning: For formats such as - tar or cpio, reading and parsing the header is straightforward - since headers alternate with data. For formats that store all - header data at the beginning of the file, the first header read - request may have to read all headers into memory and store that - data, sorted by the location of the file data. Subsequent header - read requests will skip forward to the beginning of the file data - and return the corresponding header. - Read Data - The read data interface supports sparse files; this requires that - each call return a block of data specifying the file offset and - size. This may require you to carefully track the location so - that you can return accurate file offsets for each read. Remem†- ber that the decompressor will return as much data as it has. - Generally, you will want to request one byte, examine the return - value to see how much data is available, and possibly trim that - to the amount you can use. You should invoke consume for each - block just before you return it. - Skip All Data - The skip data call should skip over all file data and trailing - padding. This is called automatically by the API layer just be†- fore each header read. It is also called in response to the - client calling the public data_skip() function. - Cleanup - On cleanup, the format should release all of its allocated mem†- ory. - - API Layer - XXX to do XXX - -WRITE ARCHITECTURE - The write API has a similar set of four layers: an API layer, a format - layer, a compression layer, and an I/O layer. The registration here is - much simpler because only one format and one compression can be regis†- tered at a time. - - I/O Layer and Client Callbacks - XXX To be written XXX - - Compression Layer - XXX To be written XXX - - Format Layer - XXX To be written XXX - - API Layer - XXX To be written XXX - -WRITE_DISK ARCHITECTURE - The write_disk API is intended to look just like the write API to - clients. Since it does not handle multiple formats or compression, it is - not layered internally. - -GENERAL SERVICES - The archive_read, archive_write, and archive_write_disk objects all con†- tain an initial archive object which provides common support for a set of - standard services. (Recall that ANSI/ISO C90 guarantees that you can - cast freely between a pointer to a structure and a pointer to the first - element of that structure.) The archive object has a magic value that - indicates which API this object is associated with, slots for storing er†- ror information, and function pointers for virtualized API functions. - -MISCELLANEOUS NOTES - Connecting existing archiving libraries into libarchive is generally - quite difficult. In particular, many existing libraries strongly assume - that you are reading from a file; they seek forwards and backwards as - necessary to locate various pieces of information. In contrast, - libarchive never seeks backwards in its input, which sometimes requires - very different approaches. - - For example, libarchive's ISO9660 support operates very differently from - most ISO9660 readers. The libarchive support utilizes a work-queue de†- sign that keeps a list of known entries sorted by their location in the - input. Whenever libarchive's ISO9660 implementation is asked for the - next header, checks this list to find the next item on the disk. Direc†- tories are parsed when they are encountered and new items are added to - the list. This design relies heavily on the ISO9660 image being opti†- mized so that directories always occur earlier on the disk than the files - they describe. - - Depending on the specific format, such approaches may not be possible. - The ZIP format specification, for example, allows archivers to store key - information only at the end of the file. In theory, it is possible to - create ZIP archives that cannot be read without seeking. Fortunately, - such archives are very rare, and libarchive can read most ZIP archives, - though it cannot always extract as much information as a dedicated ZIP - program. - -SEE ALSO - archive_entry(3), archive_read(3), archive_write(3), - archive_write_disk(3), libarchive(3) - -HISTORY - The libarchive library first appeared in FreeBSD 5.3. - -AUTHORS - The libarchive library was written by Tim Kientzle . - -BSD January 26, 2011 BSD diff --git a/thirdparty/libarchive/doc/text/mtree.5.txt b/thirdparty/libarchive/doc/text/mtree.5.txt deleted file mode 100644 index c916e3071..000000000 --- a/thirdparty/libarchive/doc/text/mtree.5.txt +++ /dev/null @@ -1,184 +0,0 @@ -MTREE(5) BSD File Formats Manual MTREE(5) - -NAME - mtree — format of mtree dir hierarchy files - -DESCRIPTION - The mtree format is a textual format that describes a collection of - filesystem objects. Such files are typically used to create or verify - directory hierarchies. - - General Format - An mtree file consists of a series of lines, each providing information - about a single filesystem object. Leading whitespace is always ignored. - - When encoding file or pathnames, any backslash character or character - outside of the 95 printable ASCII characters must be encoded as a back†- slash followed by three octal digits. When reading mtree files, any ap†- pearance of a backslash followed by three octal digits should be con†- verted into the corresponding character. - - Each line is interpreted independently as one of the following types: - - Blank Blank lines are ignored. - - Comment Lines beginning with # are ignored. - - Special Lines beginning with / are special commands that influence - the interpretation of later lines. - - Relative If the first whitespace-delimited word has no / characters, - it is the name of a file in the current directory. Any rela†- tive entry that describes a directory changes the current di†- rectory. - - dot-dot As a special case, a relative entry with the filename .. - changes the current directory to the parent directory. Op†- tions on dot-dot entries are always ignored. - - Full If the first whitespace-delimited word has a / character af†- ter the first character, it is the pathname of a file rela†- tive to the starting directory. There can be multiple full - entries describing the same file. - - Some tools that process mtree files may require that multiple lines de†- scribing the same file occur consecutively. It is not permitted for the - same file to be mentioned using both a relative and a full file specifi†- cation. - - Special commands - Two special commands are currently defined: - - /set This command defines default values for one or more keywords. - It is followed on the same line by one or more whitespace- - separated keyword definitions. These definitions apply to - all following files that do not specify a value for that key†- word. - - /unset This command removes any default value set by a previous /set - command. It is followed on the same line by one or more key†- words separated by whitespace. - - Keywords - After the filename, a full or relative entry consists of zero or more - whitespace-separated keyword definitions. Each such definition consists - of a key from the following list immediately followed by an '=' sign and - a value. Software programs reading mtree files should warn about unrec†- ognized keywords. - - Currently supported keywords are as follows: - - cksum The checksum of the file using the default algorithm speci†- fied by the cksum(1) utility. - - device The device number for block or char file types. The value - must be one of the following forms: - - format,major,minor[,subunit] - A device with major, minor and optional subunit fields. - Their meaning is specified by the operating's system - format. See below for valid formats. - - number - Opaque number (as stored on the file system). - - The following values for format are recognized: native, - 386bsd, 4bsd, bsdos, freebsd, hpux, isc, linux, netbsd, osf1, - sco, solaris, sunos, svr3, svr4, and ultrix. - - See mknod(8) for more details. - - contents The full pathname of a file that holds the contents of this - file. - - flags The file flags as a symbolic name. See chflags(1) for infor†- mation on these names. If no flags are to be set the string - “none†may be used to override the current default. - - gid The file group as a numeric value. - - gname The file group as a symbolic name. - - ignore Ignore any file hierarchy below this file. - - inode The inode number. - - link The target of the symbolic link when type=link. - - md5 The MD5 message digest of the file. - - md5digest A synonym for md5. - - mode The current file's permissions as a numeric (octal) or sym†- bolic value. - - nlink The number of hard links the file is expected to have. - - nochange Make sure this file or directory exists but otherwise ignore - all attributes. - - optional The file is optional; do not complain about the file if it is - not in the file hierarchy. - - resdevice The “resident†device number of the file, e.g. the ID of the - device that contains the file. Its format is the same as the - one for device. - - ripemd160digest - The RIPEMD160 message digest of the file. - - rmd160 A synonym for ripemd160digest. - - rmd160digest - A synonym for ripemd160digest. - - sha1 The FIPS 160-1 (“SHA-1â€) message digest of the file. - - sha1digest A synonym for sha1. - - sha256 The FIPS 180-2 (“SHA-256â€) message digest of the file. - - sha256digest - A synonym for sha256. - - sha384 The FIPS 180-2 (“SHA-384â€) message digest of the file. - - sha384digest - A synonym for sha384. - - sha512 The FIPS 180-2 (“SHA-512â€) message digest of the file. - - sha512digest - A synonym for sha512. - - size The size, in bytes, of the file. - - time The last modification time of the file. - - type The type of the file; may be set to any one of the following: - - block block special device - char character special device - dir directory - fifo fifo - file regular file - link symbolic link - socket socket - - uid The file owner as a numeric value. - - uname The file owner as a symbolic name. - -SEE ALSO - cksum(1), find(1), mtree(8) - -HISTORY - The mtree utility appeared in 4.3BSD-Reno. The MD5 digest capability was - added in FreeBSD 2.1, in response to the widespread use of programs which - can spoof cksum(1). The SHA-1 and RIPEMD160 digests were added in - FreeBSD 4.0, as new attacks have demonstrated weaknesses in MD5. The - SHA-256 digest was added in FreeBSD 6.0. Support for file flags was - added in FreeBSD 4.0, and mostly comes from NetBSD. The “full†entry - format was added by NetBSD. - -BSD September 4, 2013 BSD diff --git a/thirdparty/libarchive/doc/text/tar.5.txt b/thirdparty/libarchive/doc/text/tar.5.txt deleted file mode 100644 index 00697240b..000000000 --- a/thirdparty/libarchive/doc/text/tar.5.txt +++ /dev/null @@ -1,674 +0,0 @@ -TAR(5) BSD File Formats Manual TAR(5) - -NAME - tar — format of tape archive files - -DESCRIPTION - The tar archive format collects any number of files, directories, and - other file system objects (symbolic links, device nodes, etc.) into a - single stream of bytes. The format was originally designed to be used - with tape drives that operate with fixed-size blocks, but is widely used - as a general packaging mechanism. - - General Format - A tar archive consists of a series of 512-byte records. Each file system - object requires a header record which stores basic metadata (pathname, - owner, permissions, etc.) and zero or more records containing any file - data. The end of the archive is indicated by two records consisting en†- tirely of zero bytes. - - For compatibility with tape drives that use fixed block sizes, programs - that read or write tar files always read or write a fixed number of - records with each I/O operation. These “blocks†are always a multiple of - the record size. The maximum block size supported by early implementa†- tions was 10240 bytes or 20 records. This is still the default for most - implementations although block sizes of 1MiB (2048 records) or larger are - commonly used with modern high-speed tape drives. (Note: the terms - “block†and “record†here are not entirely standard; this document fol†- lows the convention established by John Gilmore in documenting pdtar.) - - Old-Style Archive Format - The original tar archive format has been extended many times to include - additional information that various implementors found necessary. This - section describes the variant implemented by the tar command included in - Version 7 AT&T UNIX, which seems to be the earliest widely-used version - of the tar program. - - The header record for an old-style tar archive consists of the following: - - struct header_old_tar { - char name[100]; - char mode[8]; - char uid[8]; - char gid[8]; - char size[12]; - char mtime[12]; - char checksum[8]; - char linkflag[1]; - char linkname[100]; - char pad[255]; - }; - All unused bytes in the header record are filled with nulls. - - name Pathname, stored as a null-terminated string. Early tar imple†- mentations only stored regular files (including hardlinks to - those files). One common early convention used a trailing "/" - character to indicate a directory name, allowing directory per†- missions and owner information to be archived and restored. - - mode File mode, stored as an octal number in ASCII. - - uid, gid - User id and group id of owner, as octal numbers in ASCII. - - size Size of file, as octal number in ASCII. For regular files only, - this indicates the amount of data that follows the header. In - particular, this field was ignored by early tar implementations - when extracting hardlinks. Modern writers should always store a - zero length for hardlink entries. - - mtime Modification time of file, as an octal number in ASCII. This in†- dicates the number of seconds since the start of the epoch, - 00:00:00 UTC January 1, 1970. Note that negative values should - be avoided here, as they are handled inconsistently. - - checksum - Header checksum, stored as an octal number in ASCII. To compute - the checksum, set the checksum field to all spaces, then sum all - bytes in the header using unsigned arithmetic. This field should - be stored as six octal digits followed by a null and a space - character. Note that many early implementations of tar used - signed arithmetic for the checksum field, which can cause inter†- operability problems when transferring archives between systems. - Modern robust readers compute the checksum both ways and accept - the header if either computation matches. - - linkflag, linkname - In order to preserve hardlinks and conserve tape, a file with - multiple links is only written to the archive the first time it - is encountered. The next time it is encountered, the linkflag is - set to an ASCII ‘1’ and the linkname field holds the first name - under which this file appears. (Note that regular files have a - null value in the linkflag field.) - - Early tar implementations varied in how they terminated these fields. - The tar command in Version 7 AT&T UNIX used the following conventions - (this is also documented in early BSD manpages): the pathname must be - null-terminated; the mode, uid, and gid fields must end in a space and a - null byte; the size and mtime fields must end in a space; the checksum is - terminated by a null and a space. Early implementations filled the nu†- meric fields with leading spaces. This seems to have been common prac†- tice until the IEEE Std 1003.1-1988 (“POSIX.1â€) standard was released. - For best portability, modern implementations should fill the numeric - fields with leading zeros. - - Pre-POSIX Archives - An early draft of IEEE Std 1003.1-1988 (“POSIX.1â€) served as the basis - for John Gilmore's pdtar program and many system implementations from the - late 1980s and early 1990s. These archives generally follow the POSIX - ustar format described below with the following variations: - • The magic value consists of the five characters “ustar†followed - by a space. The version field contains a space character fol†- lowed by a null. - • The numeric fields are generally filled with leading spaces (not - leading zeros as recommended in the final standard). - • The prefix field is often not used, limiting pathnames to the 100 - characters of old-style archives. - - POSIX ustar Archives - IEEE Std 1003.1-1988 (“POSIX.1â€) defined a standard tar file format to be - read and written by compliant implementations of tar(1). This format is - often called the “ustar†format, after the magic value used in the - header. (The name is an acronym for “Unix Standard TARâ€.) It extends - the historic format with new fields: - - struct header_posix_ustar { - char name[100]; - char mode[8]; - char uid[8]; - char gid[8]; - char size[12]; - char mtime[12]; - char checksum[8]; - char typeflag[1]; - char linkname[100]; - char magic[6]; - char version[2]; - char uname[32]; - char gname[32]; - char devmajor[8]; - char devminor[8]; - char prefix[155]; - char pad[12]; - }; - - typeflag - Type of entry. POSIX extended the earlier linkflag field with - several new type values: - “0†Regular file. NUL should be treated as a synonym, for - compatibility purposes. - “1†Hard link. - “2†Symbolic link. - “3†Character device node. - “4†Block device node. - “5†Directory. - “6†FIFO node. - “7†Reserved. - Other A POSIX-compliant implementation must treat any unrecog†- nized typeflag value as a regular file. In particular, - writers should ensure that all entries have a valid file†- name so that they can be restored by readers that do not - support the corresponding extension. Uppercase letters - "A" through "Z" are reserved for custom extensions. Note - that sockets and whiteout entries are not archivable. - It is worth noting that the size field, in particular, has dif†- ferent meanings depending on the type. For regular files, of - course, it indicates the amount of data following the header. - For directories, it may be used to indicate the total size of all - files in the directory, for use by operating systems that pre-al†- locate directory space. For all other types, it should be set to - zero by writers and ignored by readers. - - magic Contains the magic value “ustar†followed by a NUL byte to indi†- cate that this is a POSIX standard archive. Full compliance re†- quires the uname and gname fields be properly set. - - version - Version. This should be “00†(two copies of the ASCII digit - zero) for POSIX standard archives. - - uname, gname - User and group names, as null-terminated ASCII strings. These - should be used in preference to the uid/gid values when they are - set and the corresponding names exist on the system. - - devmajor, devminor - Major and minor numbers for character device or block device en†- try. - - name, prefix - If the pathname is too long to fit in the 100 bytes provided by - the standard format, it can be split at any / character with the - first portion going into the prefix field. If the prefix field - is not empty, the reader will prepend the prefix value and a / - character to the regular name field to obtain the full pathname. - The standard does not require a trailing / character on directory - names, though most implementations still include this for compat†- ibility reasons. - - Note that all unused bytes must be set to NUL. - - Field termination is specified slightly differently by POSIX than by pre†- vious implementations. The magic, uname, and gname fields must have a - trailing NUL. The pathname, linkname, and prefix fields must have a - trailing NUL unless they fill the entire field. (In particular, it is - possible to store a 256-character pathname if it happens to have a / as - the 156th character.) POSIX requires numeric fields to be zero-padded in - the front, and requires them to be terminated with either space or NUL - characters. - - Currently, most tar implementations comply with the ustar format, occa†- sionally extending it by adding new fields to the blank area at the end - of the header record. - - Numeric Extensions - There have been several attempts to extend the range of sizes or times - supported by modifying how numbers are stored in the header. - - One obvious extension to increase the size of files is to eliminate the - terminating characters from the various numeric fields. For example, the - standard only allows the size field to contain 11 octal digits, reserving - the twelfth byte for a trailing NUL character. Allowing 12 octal digits - allows file sizes up to 64 GB. - - Another extension, utilized by GNU tar, star, and other newer tar imple†- mentations, permits binary numbers in the standard numeric fields. This - is flagged by setting the high bit of the first byte. The remainder of - the field is treated as a signed twos-complement value. This permits - 95-bit values for the length and time fields and 63-bit values for the - uid, gid, and device numbers. In particular, this provides a consistent - way to handle negative time values. GNU tar supports this extension for - the length, mtime, ctime, and atime fields. Joerg Schilling's star pro†- gram and the libarchive library support this extension for all numeric - fields. Note that this extension is largely obsoleted by the extended - attribute record provided by the pax interchange format. - - Another early GNU extension allowed base-64 values rather than octal. - This extension was short-lived and is no longer supported by any imple†- mentation. - - Pax Interchange Format - There are many attributes that cannot be portably stored in a POSIX ustar - archive. IEEE Std 1003.1-2001 (“POSIX.1â€) defined a “pax interchange - format†that uses two new types of entries to hold text-formatted meta†- data that applies to following entries. Note that a pax interchange for†- mat archive is a ustar archive in every respect. The new data is stored - in ustar-compatible archive entries that use the “x†or “g†typeflag. In - particular, older implementations that do not fully support these exten†- sions will extract the metadata into regular files, where the metadata - can be examined as necessary. - - An entry in a pax interchange format archive consists of one or two stan†- dard ustar entries, each with its own header and data. The first op†- tional entry stores the extended attributes for the following entry. - This optional first entry has an "x" typeflag and a size field that indi†- cates the total size of the extended attributes. The extended attributes - themselves are stored as a series of text-format lines encoded in the - portable UTF-8 encoding. Each line consists of a decimal number, a - space, a key string, an equals sign, a value string, and a new line. The - decimal number indicates the length of the entire line, including the - initial length field and the trailing newline. An example of such a - field is: - 25 ctime=1084839148.1212\n - Keys in all lowercase are standard keys. Vendors can add their own keys - by prefixing them with an all uppercase vendor name and a period. Note - that, unlike the historic header, numeric values are stored using deci†- mal, not octal. A description of some common keys follows: - - atime, ctime, mtime - File access, inode change, and modification times. These fields - can be negative or include a decimal point and a fractional - value. - - hdrcharset - The character set used by the pax extension values. By default, - all textual values in the pax extended attributes are assumed to - be in UTF-8, including pathnames, user names, and group names. - In some cases, it is not possible to translate local conventions - into UTF-8. If this key is present and the value is the six- - character ASCII string “BINARYâ€, then all textual values are as†- sumed to be in a platform-dependent multi-byte encoding. Note - that there are only two valid values for this key: “BINARY†or - “ISO-IR 10646 2000 UTF-8â€. No other values are permitted by the - standard, and the latter value should generally not be used as it - is the default when this key is not specified. In particular, - this flag should not be used as a general mechanism to allow - filenames to be stored in arbitrary encodings. - - uname, uid, gname, gid - User name, group name, and numeric UID and GID values. The user - name and group name stored here are encoded in UTF8 and can thus - include non-ASCII characters. The UID and GID fields can be of - arbitrary length. - - linkpath - The full path of the linked-to file. Note that this is encoded - in UTF8 and can thus include non-ASCII characters. - - path The full pathname of the entry. Note that this is encoded in - UTF8 and can thus include non-ASCII characters. - - realtime.*, security.* - These keys are reserved and may be used for future standardiza†- tion. - - size The size of the file. Note that there is no length limit on this - field, allowing conforming archives to store files much larger - than the historic 8GB limit. - - SCHILY.* - Vendor-specific attributes used by Joerg Schilling's star imple†- mentation. - - SCHILY.acl.access, SCHILY.acl.default, SCHILY.acl.ace - Stores the access, default and NFSv4 ACLs as textual strings in a - format that is an extension of the format specified by POSIX.1e - draft 17. In particular, each user or group access specification - can include an additional colon-separated field with the numeric - UID or GID. This allows ACLs to be restored on systems that may - not have complete user or group information available (such as - when NIS/YP or LDAP services are temporarily unavailable). - - SCHILY.devminor, SCHILY.devmajor - The full minor and major numbers for device nodes. - - SCHILY.fflags - The file flags. - - SCHILY.realsize - The full size of the file on disk. XXX explain? XXX - - SCHILY.dev, SCHILY.ino, SCHILY.nlinks - The device number, inode number, and link count for the entry. - In particular, note that a pax interchange format archive using - Joerg Schilling's SCHILY.* extensions can store all of the data - from struct stat. - - LIBARCHIVE.* - Vendor-specific attributes used by the libarchive library and - programs that use it. - - LIBARCHIVE.creationtime - The time when the file was created. (This should not be confused - with the POSIX “ctime†attribute, which refers to the time when - the file metadata was last changed.) - - LIBARCHIVE.xattr.namespace.key - Libarchive stores POSIX.1e-style extended attributes using keys - of this form. The key value is URL-encoded: All non-ASCII char†- acters and the two special characters “=†and “%†are encoded as - “%†followed by two uppercase hexadecimal digits. The value of - this key is the extended attribute value encoded in base 64. XXX - Detail the base-64 format here XXX - - VENDOR.* - XXX document other vendor-specific extensions XXX - - Any values stored in an extended attribute override the corresponding - values in the regular tar header. Note that compliant readers should ig†- nore the regular fields when they are overridden. This is important, as - existing archivers are known to store non-compliant values in the stan†- dard header fields in this situation. There are no limits on length for - any of these fields. In particular, numeric fields can be arbitrarily - large. All text fields are encoded in UTF8. Compliant writers should - store only portable 7-bit ASCII characters in the standard ustar header - and use extended attributes whenever a text value contains non-ASCII - characters. - - In addition to the x entry described above, the pax interchange format - also supports a g entry. The g entry is identical in format, but speci†- fies attributes that serve as defaults for all subsequent archive en†- tries. The g entry is not widely used. - - Besides the new x and g entries, the pax interchange format has a few - other minor variations from the earlier ustar format. The most troubling - one is that hardlinks are permitted to have data following them. This - allows readers to restore any hardlink to a file without having to rewind - the archive to find an earlier entry. However, it creates complications - for robust readers, as it is no longer clear whether or not they should - ignore the size field for hardlink entries. - - GNU Tar Archives - The GNU tar program started with a pre-POSIX format similar to that de†- scribed earlier and has extended it using several different mechanisms: - It added new fields to the empty space in the header (some of which was - later used by POSIX for conflicting purposes); it allowed the header to - be continued over multiple records; and it defined new entries that mod†- ify following entries (similar in principle to the x entry described - above, but each GNU special entry is single-purpose, unlike the general- - purpose x entry). As a result, GNU tar archives are not POSIX compati†- ble, although more lenient POSIX-compliant readers can successfully ex†- tract most GNU tar archives. - - struct header_gnu_tar { - char name[100]; - char mode[8]; - char uid[8]; - char gid[8]; - char size[12]; - char mtime[12]; - char checksum[8]; - char typeflag[1]; - char linkname[100]; - char magic[6]; - char version[2]; - char uname[32]; - char gname[32]; - char devmajor[8]; - char devminor[8]; - char atime[12]; - char ctime[12]; - char offset[12]; - char longnames[4]; - char unused[1]; - struct { - char offset[12]; - char numbytes[12]; - } sparse[4]; - char isextended[1]; - char realsize[12]; - char pad[17]; - }; - - typeflag - GNU tar uses the following special entry types, in addition to - those defined by POSIX: - - 7 GNU tar treats type "7" records identically to type "0" - records, except on one obscure RTOS where they are used - to indicate the pre-allocation of a contiguous file on - disk. - - D This indicates a directory entry. Unlike the POSIX-stan†- dard "5" typeflag, the header is followed by data records - listing the names of files in this directory. Each name - is preceded by an ASCII "Y" if the file is stored in this - archive or "N" if the file is not stored in this archive. - Each name is terminated with a null, and an extra null - marks the end of the name list. The purpose of this en†- try is to support incremental backups; a program restor†- ing from such an archive may wish to delete files on disk - that did not exist in the directory when the archive was - made. - - Note that the "D" typeflag specifically violates POSIX, - which requires that unrecognized typeflags be restored as - normal files. In this case, restoring the "D" entry as a - file could interfere with subsequent creation of the - like-named directory. - - K The data for this entry is a long linkname for the fol†- lowing regular entry. - - L The data for this entry is a long pathname for the fol†- lowing regular entry. - - M This is a continuation of the last file on the previous - volume. GNU multi-volume archives guarantee that each - volume begins with a valid entry header. To ensure this, - a file may be split, with part stored at the end of one - volume, and part stored at the beginning of the next vol†- ume. The "M" typeflag indicates that this entry contin†- ues an existing file. Such entries can only occur as the - first or second entry in an archive (the latter only if - the first entry is a volume label). The size field spec†- ifies the size of this entry. The offset field at bytes - 369-380 specifies the offset where this file fragment be†- gins. The realsize field specifies the total size of the - file (which must equal size plus offset). When extract†- ing, GNU tar checks that the header file name is the one - it is expecting, that the header offset is in the correct - sequence, and that the sum of offset and size is equal to - realsize. - - N Type "N" records are no longer generated by GNU tar. - They contained a list of files to be renamed or symlinked - after extraction; this was originally used to support - long names. The contents of this record are a text de†- scription of the operations to be done, in the form - “Rename %s to %s\n†or “Symlink %s to %s\nâ€; in either - case, both filenames are escaped using K&R C syntax. Due - to security concerns, "N" records are now generally ig†- nored when reading archives. - - S This is a “sparse†regular file. Sparse files are stored - as a series of fragments. The header contains a list of - fragment offset/length pairs. If more than four such en†- tries are required, the header is extended as necessary - with “extra†header extensions (an older format that is - no longer used), or “sparse†extensions. - - V The name field should be interpreted as a tape/volume - header name. This entry should generally be ignored on - extraction. - - magic The magic field holds the five characters “ustar†followed by a - space. Note that POSIX ustar archives have a trailing null. - - version - The version field holds a space character followed by a null. - Note that POSIX ustar archives use two copies of the ASCII digit - “0â€. - - atime, ctime - The time the file was last accessed and the time of last change - of file information, stored in octal as with mtime. - - longnames - This field is apparently no longer used. - - Sparse offset / numbytes - Each such structure specifies a single fragment of a sparse file. - The two fields store values as octal numbers. The fragments are - each padded to a multiple of 512 bytes in the archive. On ex†- traction, the list of fragments is collected from the header (in†- cluding any extension headers), and the data is then read and - written to the file at appropriate offsets. - - isextended - If this is set to non-zero, the header will be followed by addi†- tional “sparse header†records. Each such record contains infor†- mation about as many as 21 additional sparse blocks as shown - here: - - struct gnu_sparse_header { - struct { - char offset[12]; - char numbytes[12]; - } sparse[21]; - char isextended[1]; - char padding[7]; - }; - - realsize - A binary representation of the file's complete size, with a much - larger range than the POSIX file size. In particular, with M - type files, the current entry is only a portion of the file. In - that case, the POSIX size field will indicate the size of this - entry; the realsize field will indicate the total size of the - file. - - GNU tar pax archives - GNU tar 1.14 (XXX check this XXX) and later will write pax interchange - format archives when you specify the --posix flag. This format follows - the pax interchange format closely, using some SCHILY tags and introduc†- ing new keywords to store sparse file information. There have been three - iterations of the sparse file support, referred to as “0.0â€, “0.1â€, and - “1.0â€. - - GNU.sparse.numblocks, GNU.sparse.offset, GNU.sparse.numbytes, - GNU.sparse.size - The “0.0†format used an initial GNU.sparse.numblocks attribute - to indicate the number of blocks in the file, a pair of - GNU.sparse.offset and GNU.sparse.numbytes to indicate the offset - and size of each block, and a single GNU.sparse.size to indicate - the full size of the file. This is not the same as the size in - the tar header because the latter value does not include the size - of any holes. This format required that the order of attributes - be preserved and relied on readers accepting multiple appearances - of the same attribute names, which is not officially permitted by - the standards. - - GNU.sparse.map - The “0.1†format used a single attribute that stored a comma-sep†- arated list of decimal numbers. Each pair of numbers indicated - the offset and size, respectively, of a block of data. This does - not work well if the archive is extracted by an archiver that - does not recognize this extension, since many pax implementations - simply discard unrecognized attributes. - - GNU.sparse.major, GNU.sparse.minor, GNU.sparse.name, GNU.sparse.realsize - The “1.0†format stores the sparse block map in one or more - 512-byte blocks prepended to the file data in the entry body. - The pax attributes indicate the existence of this map (via the - GNU.sparse.major and GNU.sparse.minor fields) and the full size - of the file. The GNU.sparse.name holds the true name of the - file. To avoid confusion, the name stored in the regular tar - header is a modified name so that extraction errors will be ap†- parent to users. - - Solaris Tar - XXX More Details Needed XXX - - Solaris tar (beginning with SunOS XXX 5.7 ?? XXX) supports an “extended†- format that is fundamentally similar to pax interchange format, with the - following differences: - • Extended attributes are stored in an entry whose type is X, not - x, as used by pax interchange format. The detailed format of - this entry appears to be the same as detailed above for the x en†- try. - • An additional A header is used to store an ACL for the following - regular entry. The body of this entry contains a seven-digit oc†- tal number followed by a zero byte, followed by the textual ACL - description. The octal value is the number of ACL entries plus a - constant that indicates the ACL type: 01000000 for POSIX.1e ACLs - and 03000000 for NFSv4 ACLs. - - AIX Tar - XXX More details needed XXX - - AIX Tar uses a ustar-formatted header with the type A for storing coded - ACL information. Unlike the Solaris format, AIX tar writes this header - after the regular file body to which it applies. The pathname in this - header is either NFS4 or AIXC to indicate the type of ACL stored. The - actual ACL is stored in platform-specific binary format. - - Mac OS X Tar - The tar distributed with Apple's Mac OS X stores most regular files as - two separate files in the tar archive. The two files have the same name - except that the first one has “._†prepended to the last path element. - This special file stores an AppleDouble-encoded binary blob with addi†- tional metadata about the second file, including ACL, extended at†- tributes, and resources. To recreate the original file on disk, each - separate file can be extracted and the Mac OS X copyfile() function can - be used to unpack the separate metadata file and apply it to th regular - file. Conversely, the same function provides a “pack†option to encode - the extended metadata from a file into a separate file whose contents can - then be put into a tar archive. - - Note that the Apple extended attributes interact badly with long file†- names. Since each file is stored with the full name, a separate set of - extensions needs to be included in the archive for each one, doubling the - overhead required for files with long names. - - Summary of tar type codes - The following list is a condensed summary of the type codes used in tar - header records generated by different tar implementations. More details - about specific implementations can be found above: - NUL Early tar programs stored a zero byte for regular files. - 0 POSIX standard type code for a regular file. - 1 POSIX standard type code for a hard link description. - 2 POSIX standard type code for a symbolic link description. - 3 POSIX standard type code for a character device node. - 4 POSIX standard type code for a block device node. - 5 POSIX standard type code for a directory. - 6 POSIX standard type code for a FIFO. - 7 POSIX reserved. - 7 GNU tar used for pre-allocated files on some systems. - A Solaris tar ACL description stored prior to a regular file header. - A AIX tar ACL description stored after the file body. - D GNU tar directory dump. - K GNU tar long linkname for the following header. - L GNU tar long pathname for the following header. - M GNU tar multivolume marker, indicating the file is a continuation of - a file from the previous volume. - N GNU tar long filename support. Deprecated. - S GNU tar sparse regular file. - V GNU tar tape/volume header name. - X Solaris tar general-purpose extension header. - g POSIX pax interchange format global extensions. - x POSIX pax interchange format per-file extensions. - -SEE ALSO - ar(1), pax(1), tar(1) - -STANDARDS - The tar utility is no longer a part of POSIX or the Single Unix Standard. - It last appeared in Version 2 of the Single UNIX Specification (“SUSv2â€). - It has been supplanted in subsequent standards by pax(1). The ustar for†- mat is currently part of the specification for the pax(1) utility. The - pax interchange file format is new with IEEE Std 1003.1-2001 (“POSIX.1â€). - -HISTORY - A tar command appeared in Seventh Edition Unix, which was released in - January, 1979. It replaced the tp program from Fourth Edition Unix which - in turn replaced the tap program from First Edition Unix. John Gilmore's - pdtar public-domain implementation (circa 1987) was highly influential - and formed the basis of GNU tar (circa 1988). Joerg Shilling's star - archiver is another open-source (CDDL) archiver (originally developed - circa 1985) which features complete support for pax interchange format. - - This documentation was written as part of the libarchive and bsdtar - project by Tim Kientzle . - -BSD December 27, 2016 BSD diff --git a/thirdparty/libarchive/doc/update.sh b/thirdparty/libarchive/doc/update.sh deleted file mode 100755 index 1038da133..000000000 --- a/thirdparty/libarchive/doc/update.sh +++ /dev/null @@ -1,119 +0,0 @@ -#!/bin/sh - -set -e - -# -# Simple script to repopulate the 'doc' tree from -# the mdoc man pages stored in each project. -# - -# Collect list of man pages, relative to my subdirs -test -d man || mkdir man -cd man -MANPAGES=`for d in libarchive tar cpio;do ls ../../$d/*.[135];done | grep -v '\.so\.'` -cd .. - -# Build Makefile in 'man' directory -cd man -chmod +w . -rm -f *.[135] Makefile -echo > Makefile -echo "default: all" >>Makefile -echo >>Makefile -all="all:" -for f in $MANPAGES; do - outname="`basename $f`" - echo >> Makefile - echo $outname: ../mdoc2man.awk $f >> Makefile - echo " awk -f ../mdoc2man.awk < $f > $outname" >> Makefile - all="$all $outname" -done -echo $all >>Makefile -cd .. - -# Rebuild Makefile in 'text' directory -test -d text || mkdir text -cd text -chmod +w . -rm -f *.txt Makefile -echo > Makefile -echo "default: all" >>Makefile -echo >>Makefile -all="all:" -for f in $MANPAGES; do - outname="`basename $f`.txt" - echo >> Makefile - echo $outname: $f >> Makefile - echo " nroff -mdoc $f | col -b > $outname" >> Makefile - all="$all $outname" -done -echo $all >>Makefile -cd .. - -# Rebuild Makefile in 'pdf' directory -test -d pdf || mkdir pdf -cd pdf -chmod +w . -rm -f *.pdf Makefile -echo > Makefile -echo "default: all" >>Makefile -echo >>Makefile -all="all:" -for f in $MANPAGES; do - outname="`basename $f`.pdf" - echo >> Makefile - echo $outname: $f >> Makefile - echo " groff -mdoc -T ps $f | ps2pdf - - > $outname" >> Makefile - all="$all $outname" -done -echo $all >>Makefile -cd .. - -# Build Makefile in 'html' directory -test -d html || mkdir html -cd html -chmod +w . -rm -f *.html Makefile -echo > Makefile -echo "default: all" >>Makefile -echo >>Makefile -all="all:" -for f in $MANPAGES; do - outname="`basename $f`.html" - echo >> Makefile - echo $outname: $f >> Makefile - echo " groff -mdoc -T html $f > $outname" >> Makefile - all="$all $outname" -done -echo $all >>Makefile -cd .. - -# Build Makefile in 'wiki' directory -test -d wiki || mkdir wiki -cd wiki -chmod +w . -rm -f *.wiki Makefile -echo > Makefile -echo "default: all" >>Makefile -echo >>Makefile -all="all:" -for f in $MANPAGES; do - outname="`basename $f | awk '{ac=split($0,a,"[_.-]");o="ManPage";for(w=0;w<=ac;++w){o=o toupper(substr(a[w],1,1)) substr(a[w],2)};print o}'`.wiki" - echo >> Makefile - echo $outname: ../mdoc2wiki.awk $f >> Makefile - echo " awk -f ../mdoc2wiki.awk < $f > $outname" >> Makefile - all="$all $outname" -done -echo $all >>Makefile -cd .. - -# Convert all of the manpages to -man format -(cd man && make) -# Format all of the manpages to text -(cd text && make) -# Format all of the manpages to PDF -(cd pdf && make) -# Format all of the manpages to HTML -(cd html && make) -# Format all of the manpages to wiki syntax -(cd wiki && make) diff --git a/thirdparty/libarchive/doc/wiki/.ignore_me b/thirdparty/libarchive/doc/wiki/.ignore_me deleted file mode 100644 index d285484d4..000000000 --- a/thirdparty/libarchive/doc/wiki/.ignore_me +++ /dev/null @@ -1,2 +0,0 @@ -*** PLEASE DO NOT DELETE THIS FILE! *** -This file is used to track an otherwise empty directory in git. diff --git a/thirdparty/libarchive/doc/wiki/Makefile b/thirdparty/libarchive/doc/wiki/Makefile deleted file mode 100644 index 206afa130..000000000 --- a/thirdparty/libarchive/doc/wiki/Makefile +++ /dev/null @@ -1,133 +0,0 @@ - -default: all - - -ManPageArchiveEntry3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_entry.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_entry.3 > ManPageArchiveEntry3.wiki - -ManPageArchiveEntryAcl3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_entry_acl.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_entry_acl.3 > ManPageArchiveEntryAcl3.wiki - -ManPageArchiveEntryLinkify3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_entry_linkify.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_entry_linkify.3 > ManPageArchiveEntryLinkify3.wiki - -ManPageArchiveEntryMisc3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_entry_misc.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_entry_misc.3 > ManPageArchiveEntryMisc3.wiki - -ManPageArchiveEntryPaths3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_entry_paths.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_entry_paths.3 > ManPageArchiveEntryPaths3.wiki - -ManPageArchiveEntryPerms3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_entry_perms.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_entry_perms.3 > ManPageArchiveEntryPerms3.wiki - -ManPageArchiveEntryStat3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_entry_stat.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_entry_stat.3 > ManPageArchiveEntryStat3.wiki - -ManPageArchiveEntryTime3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_entry_time.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_entry_time.3 > ManPageArchiveEntryTime3.wiki - -ManPageArchiveRead3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_read.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_read.3 > ManPageArchiveRead3.wiki - -ManPageArchiveReadAddPassphrase3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_read_add_passphrase.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_read_add_passphrase.3 > ManPageArchiveReadAddPassphrase3.wiki - -ManPageArchiveReadData3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_read_data.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_read_data.3 > ManPageArchiveReadData3.wiki - -ManPageArchiveReadDisk3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_read_disk.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_read_disk.3 > ManPageArchiveReadDisk3.wiki - -ManPageArchiveReadExtract3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_read_extract.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_read_extract.3 > ManPageArchiveReadExtract3.wiki - -ManPageArchiveReadFilter3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_read_filter.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_read_filter.3 > ManPageArchiveReadFilter3.wiki - -ManPageArchiveReadFormat3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_read_format.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_read_format.3 > ManPageArchiveReadFormat3.wiki - -ManPageArchiveReadFree3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_read_free.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_read_free.3 > ManPageArchiveReadFree3.wiki - -ManPageArchiveReadHeader3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_read_header.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_read_header.3 > ManPageArchiveReadHeader3.wiki - -ManPageArchiveReadNew3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_read_new.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_read_new.3 > ManPageArchiveReadNew3.wiki - -ManPageArchiveReadOpen3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_read_open.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_read_open.3 > ManPageArchiveReadOpen3.wiki - -ManPageArchiveReadSetOptions3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_read_set_options.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_read_set_options.3 > ManPageArchiveReadSetOptions3.wiki - -ManPageArchiveUtil3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_util.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_util.3 > ManPageArchiveUtil3.wiki - -ManPageArchiveWrite3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_write.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_write.3 > ManPageArchiveWrite3.wiki - -ManPageArchiveWriteBlocksize3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_write_blocksize.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_write_blocksize.3 > ManPageArchiveWriteBlocksize3.wiki - -ManPageArchiveWriteData3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_write_data.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_write_data.3 > ManPageArchiveWriteData3.wiki - -ManPageArchiveWriteDisk3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_write_disk.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_write_disk.3 > ManPageArchiveWriteDisk3.wiki - -ManPageArchiveWriteFilter3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_write_filter.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_write_filter.3 > ManPageArchiveWriteFilter3.wiki - -ManPageArchiveWriteFinishEntry3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_write_finish_entry.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_write_finish_entry.3 > ManPageArchiveWriteFinishEntry3.wiki - -ManPageArchiveWriteFormat3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_write_format.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_write_format.3 > ManPageArchiveWriteFormat3.wiki - -ManPageArchiveWriteFree3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_write_free.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_write_free.3 > ManPageArchiveWriteFree3.wiki - -ManPageArchiveWriteHeader3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_write_header.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_write_header.3 > ManPageArchiveWriteHeader3.wiki - -ManPageArchiveWriteNew3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_write_new.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_write_new.3 > ManPageArchiveWriteNew3.wiki - -ManPageArchiveWriteOpen3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_write_open.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_write_open.3 > ManPageArchiveWriteOpen3.wiki - -ManPageArchiveWriteSetOptions3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_write_set_options.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_write_set_options.3 > ManPageArchiveWriteSetOptions3.wiki - -ManPageArchiveWriteSetPassphrase3.wiki: ../mdoc2wiki.awk ../../libarchive/archive_write_set_passphrase.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/archive_write_set_passphrase.3 > ManPageArchiveWriteSetPassphrase3.wiki - -ManPageCpio5.wiki: ../mdoc2wiki.awk ../../libarchive/cpio.5 - awk -f ../mdoc2wiki.awk < ../../libarchive/cpio.5 > ManPageCpio5.wiki - -ManPageLibarchive3.wiki: ../mdoc2wiki.awk ../../libarchive/libarchive.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/libarchive.3 > ManPageLibarchive3.wiki - -ManPageLibarchiveChanges3.wiki: ../mdoc2wiki.awk ../../libarchive/libarchive_changes.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/libarchive_changes.3 > ManPageLibarchiveChanges3.wiki - -ManPageLibarchiveFormats5.wiki: ../mdoc2wiki.awk ../../libarchive/libarchive-formats.5 - awk -f ../mdoc2wiki.awk < ../../libarchive/libarchive-formats.5 > ManPageLibarchiveFormats5.wiki - -ManPageLibarchiveInternals3.wiki: ../mdoc2wiki.awk ../../libarchive/libarchive_internals.3 - awk -f ../mdoc2wiki.awk < ../../libarchive/libarchive_internals.3 > ManPageLibarchiveInternals3.wiki - -ManPageMtree5.wiki: ../mdoc2wiki.awk ../../libarchive/mtree.5 - awk -f ../mdoc2wiki.awk < ../../libarchive/mtree.5 > ManPageMtree5.wiki - -ManPageTar5.wiki: ../mdoc2wiki.awk ../../libarchive/tar.5 - awk -f ../mdoc2wiki.awk < ../../libarchive/tar.5 > ManPageTar5.wiki - -ManPageBsdtar1.wiki: ../mdoc2wiki.awk ../../tar/bsdtar.1 - awk -f ../mdoc2wiki.awk < ../../tar/bsdtar.1 > ManPageBsdtar1.wiki - -ManPageBsdcpio1.wiki: ../mdoc2wiki.awk ../../cpio/bsdcpio.1 - awk -f ../mdoc2wiki.awk < ../../cpio/bsdcpio.1 > ManPageBsdcpio1.wiki -all: ManPageArchiveEntry3.wiki ManPageArchiveEntryAcl3.wiki ManPageArchiveEntryLinkify3.wiki ManPageArchiveEntryMisc3.wiki ManPageArchiveEntryPaths3.wiki ManPageArchiveEntryPerms3.wiki ManPageArchiveEntryStat3.wiki ManPageArchiveEntryTime3.wiki ManPageArchiveRead3.wiki ManPageArchiveReadAddPassphrase3.wiki ManPageArchiveReadData3.wiki ManPageArchiveReadDisk3.wiki ManPageArchiveReadExtract3.wiki ManPageArchiveReadFilter3.wiki ManPageArchiveReadFormat3.wiki ManPageArchiveReadFree3.wiki ManPageArchiveReadHeader3.wiki ManPageArchiveReadNew3.wiki ManPageArchiveReadOpen3.wiki ManPageArchiveReadSetOptions3.wiki ManPageArchiveUtil3.wiki ManPageArchiveWrite3.wiki ManPageArchiveWriteBlocksize3.wiki ManPageArchiveWriteData3.wiki ManPageArchiveWriteDisk3.wiki ManPageArchiveWriteFilter3.wiki ManPageArchiveWriteFinishEntry3.wiki ManPageArchiveWriteFormat3.wiki ManPageArchiveWriteFree3.wiki ManPageArchiveWriteHeader3.wiki ManPageArchiveWriteNew3.wiki ManPageArchiveWriteOpen3.wiki ManPageArchiveWriteSetOptions3.wiki ManPageArchiveWriteSetPassphrase3.wiki ManPageCpio5.wiki ManPageLibarchive3.wiki ManPageLibarchiveChanges3.wiki ManPageLibarchiveFormats5.wiki ManPageLibarchiveInternals3.wiki ManPageMtree5.wiki ManPageTar5.wiki ManPageBsdtar1.wiki ManPageBsdcpio1.wiki diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveEntry3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveEntry3.wiki deleted file mode 100644 index 7df9e529e..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveEntry3.wiki +++ /dev/null @@ -1,123 +0,0 @@ -ARCHIVE_ENTRY(3) manual page -== NAME == -'''archive_entry_clear''', -'''archive_entry_clone''', -'''archive_entry_free''', -'''archive_entry_new''' -- functions for managing archive entry descriptions -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''struct archive_entry *'' -
    -'''archive_entry_clear'''(''struct archive_entry *''); -
    -''struct archive_entry *'' -
    -'''archive_entry_clone'''(''struct archive_entry *''); -
    -''void'' -
    -'''archive_entry_free'''(''struct archive_entry *''); -
    -''struct archive_entry *'' -
    -'''archive_entry_new'''(''void''); -== DESCRIPTION == -These functions create and manipulate data objects that -represent entries within an archive. -You can think of a -'''struct archive_entry''' -as a heavy-duty version of -'''struct stat :''' -it includes everything from -'''struct stat''' -plus associated pathname, textual group and user names, etc. -These objects are used by -[[ManPageLibarchive3]] -to represent the metadata associated with a particular -entry in an archive. -=== Create and Destroy=== -There are functions to allocate, destroy, clear, and copy -''archive_entry'' -objects: -
    -
    '''archive_entry_clear'''()
    -Erases the object, resetting all internal fields to the -same state as a newly-created object. -This is provided to allow you to quickly recycle objects -without thrashing the heap. -
    '''archive_entry_clone'''()
    -A deep copy operation; all text fields are duplicated. -
    '''archive_entry_free'''()
    -Releases the -'''struct archive_entry''' -object. -
    '''archive_entry_new'''()
    -Allocate and return a blank -'''struct archive_entry''' -object. -
    -=== Function groups=== -Due to high number of functions, the accessor functions can be found in -man pages grouped by the purpose. -
    -
    [[ManPageArchiveEntryAcl3]]
    -Access Control List manipulation -
    [[ManPageArchiveEntryPaths3]]
    -Path name manipulation -
    [[ManPageArchiveEntryPerms3]]
    -User, group and mode manipulation -
    [[ManPageArchiveEntryStat3]]
    -Functions not in the other groups and copying to/from -''struct'' stat. -
    [[ManPageArchiveEntryTime3]]
    -Time field manipulation -
    - -Most of the functions set or read entries in an object. -Such functions have one of the following forms: -
    -
    '''archive_entry_set_XXXX'''()
    -Stores the provided data in the object. -In particular, for strings, the pointer is stored, -not the referenced string. -
    '''archive_entry_copy_XXXX'''()
    -As above, except that the referenced data is copied -into the object. -
    '''archive_entry_XXXX'''()
    -Returns the specified data. -In the case of strings, a const-qualified pointer to -the string is returned. -
    -String data can be set or accessed as wide character strings -or normal -''char'' -strings. -The functions that use wide character strings are suffixed with -'''_w'''. -Note that these are different representations of the same data: -For example, if you store a narrow string and read the corresponding -wide string, the object will transparently convert formats -using the current locale. -Similarly, if you store a wide string and then store a -narrow string for the same data, the previously-set wide string will -be discarded in favor of the new data. -== SEE ALSO == -[[ManPageArchiveEntryAcl3]], -[[ManPageArchiveEntryPaths3]], -[[ManPageArchiveEntryPerms3]], -[[ManPageArchiveEntryTime3]], -[[ManPageLibarchive3]] -== HISTORY == -The -'''libarchive''' -library first appeared in -FreeBSD 5.3. -== AUTHORS == -The -'''libarchive''' -library was written by -Tim Kientzle <kientzle@acm.org.> diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveEntryAcl3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveEntryAcl3.wiki deleted file mode 100644 index d4de6202f..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveEntryAcl3.wiki +++ /dev/null @@ -1,458 +0,0 @@ -ARCHIVE_ENTRY_ACL(3) manual page -== NAME == -'''archive_entry_acl_add_entry''', -'''archive_entry_acl_add_entry_w''', -'''archive_entry_acl_clear''', -'''archive_entry_acl_count''', -'''archive_entry_acl_from_text''', -'''archive_entry_acl_from_text_w''', -'''archive_entry_acl_next''', -'''archive_entry_acl_reset''', -'''archive_entry_acl_to_text''', -'''archive_entry_acl_to_text_w''', -'''archive_entry_acl_types''' -- functions for manipulating Access Control Lists in archive entry descriptions -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''void'' -
    -'''archive_entry_acl_add_entry'''(''struct archive_entry *a'', ''int type'', ''int permset'', ''int tag'', ''int qualifier'', ''const char *name''); -
    -''void'' -
    -'''archive_entry_acl_add_entry_w'''(''struct archive_entry *a'', ''int type'', ''int permset'', ''int tag'', ''int qualifier'', ''const wchar_t *name''); -
    -''void'' -
    -'''archive_entry_acl_clear'''(''struct archive_entry *a''); -
    -''int'' -
    -'''archive_entry_acl_count'''(''struct archive_entry *a'', ''int type''); -
    -''int'' -
    -'''archive_entry_acl_from_text'''(''struct archive_entry *a'', ''const char *text'', ''int type''); -
    -''int'' -
    -'''archive_entry_acl_from_text_w'''(''struct archive_entry *a'', ''const wchar_t *text'', ''int type''); -
    -''int'' -
    -'''archive_entry_acl_next'''(''struct archive_entry *a'', ''int type'', ''int *ret_type'', ''int *ret_permset'', ''int *ret_tag'', ''int *ret_qual'', ''const char **ret_name''); -
    -''int'' -
    -'''archive_entry_acl_reset'''(''struct archive_entry *a'', ''int type''); -
    -''char *'' -
    -'''archive_entry_acl_to_text'''(''struct archive_entry *a'', ''ssize_t *len_p'', ''int flags''); -
    -''wchar_t *'' -
    -'''archive_entry_acl_to_text_w'''(''struct archive_entry *a'', ''ssize_t *len_p'', ''int flags''); -
    -''int'' -
    -'''archive_entry_acl_types'''(''struct archive_entry *a''); -== DESCRIPTION == -The -"Access Control Lists (ACLs)" -extend the standard Unix permission model. -The ACL interface of -'''libarchive''' -supports both POSIX.1e and NFSv4 style ACLs. -Use of ACLs is restricted by -various levels of ACL support in operating systems, file systems and archive -formats. -=== POSIX.1e Access Control Lists=== -A POSIX.1e ACL consists of a number of independent entries. -Each entry specifies the permission set as a bitmask of basic permissions. -Valid permissions in the -are: -
    -
    -ARCHIVE_ENTRY_ACL_READ (.B r ) -
    -ARCHIVE_ENTRY_ACL_WRITE (.B w ) -
    -ARCHIVE_ENTRY_ACL_EXECUTE (.B x ) -
    -The permissions correspond to the normal Unix permissions. - -The -specifies the principal to which the permission applies. -Valid values are: -
    -ARCHIVE_ENTRY_ACL_USER -The user specified by the name field. -
    -ARCHIVE_ENTRY_ACL_USER_OBJ -The owner of the file. -
    -ARCHIVE_ENTRY_ACL_GROUP -The group specified by the name field. -
    -ARCHIVE_ENTRY_ACL_GROUP_OBJ -The group which owns the file. -
    -ARCHIVE_ENTRY_ACL_MASK -The maximum permissions to be obtained via group permissions. -
    -ARCHIVE_ENTRY_ACL_OTHER -Any principal who is not the file owner or a member of the owning group. -
    - -The principals -ARCHIVE_ENTRY_ACL_USER_OBJ, -ARCHIVE_ENTRY_ACL_GROUP_OBJ -and -ARCHIVE_ENTRY_ACL_OTHER -are equivalent to user, group and other in the classic Unix permission -model and specify non-extended ACL entries. - -All files have an access ACL -() -ARCHIVE_ENTRY_ACL_TYPE_ACCESS. -This specifies the permissions required for access to the file itself. -Directories have an additional ACL -() -ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, -which controls the initial access ACL for newly-created directory entries. -=== NFSv4 Access Control Lists=== -A NFSv4 ACL consists of multiple individual entries called Access Control -Entries (ACEs). - -There are four possible types of a NFSv4 ACE: -
    -ARCHIVE_ENTRY_ACL_TYPE_ALLOW -Allow principal to perform actions requiring given permissions. -
    -ARCHIVE_ENTRY_ACL_TYPE_DENY -Prevent principal from performing actions requiring given permissions. -
    -ARCHIVE_ENTRY_ACL_TYPE_AUDIT -Log access attempts by principal which require given permissions. -
    -ARCHIVE_ENTRY_ACL_TYPE_ALARM -Trigger a system alarm on access attempts by principal which require given -permissions. -
    - -The -specifies the principal to which the permission applies. -Valid values are: -
    -ARCHIVE_ENTRY_ACL_USER -The user specified by the name field. -
    -ARCHIVE_ENTRY_ACL_USER_OBJ -The owner of the file. -
    -ARCHIVE_ENTRY_ACL_GROUP -The group specified by the name field. -
    -ARCHIVE_ENTRY_ACL_GROUP_OBJ -The group which owns the file. -
    -ARCHIVE_ENTRY_ACL_EVERYONE -Any principal who is not the file owner or a member of the owning group. -
    - -Entries with the -ARCHIVE_ENTRY_ACL_USER -or -ARCHIVE_ENTRY_ACL_GROUP -tag store the user and group name in the -string and optionally the user or group ID in the -integer. - -NFSv4 ACE permissions and flags are stored in the same -bitfield. -Some permissions share the same constant and permission character -but have different effect on directories than on files. -The following ACE permissions are supported: -
    -
    -ARCHIVE_ENTRY_ACL_READ_DATA (.B r ) -Read data (file). -
    -ARCHIVE_ENTRY_ACL_LIST_DIRECTORY (.B r ) -List entries (directory). -
    ARCHIVE_ENTRY_ACL_WRITE_DATA (.B w )
    -Write data (file). -
    ARCHIVE_ENTRY_ACL_ADD_FILE (.B w )
    -Create files (directory). -
    -ARCHIVE_ENTRY_ACL_EXECUTE (.B x ) -Execute file or change into a directory. -
    -ARCHIVE_ENTRY_ACL_APPEND_DATA (.B p ) -Append data (file). -
    -ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY (.B p ) -Create subdirectories (directory). -
    -ARCHIVE_ENTRY_ACL_DELETE_CHILD (.B D ) -Remove files and subdirectories inside a directory. -
    -ARCHIVE_ENTRY_ACL_DELETE (.B d ) -Remove file or directory. -
    -ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES (.B a ) -Read file or directory attributes. -
    -ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES (.B A ) -Write file or directory attributes. -
    -ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS (.B R ) -Read named file or directory attributes. -
    -ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS (.B W ) -Write named file or directory attributes. -
    -ARCHIVE_ENTRY_ACL_READ_ACL (.B c ) -Read file or directory ACL. -
    -ARCHIVE_ENTRY_ACL_WRITE_ACL (.B C ) -Write file or directory ACL. -
    -ARCHIVE_ENTRY_ACL_WRITE_OWNER (.B o ) -Change owner of a file or directory. -
    -ARCHIVE_ENTRY_ACL_SYNCHRONIZE (.B s ) -Use synchronous I/O. -
    - -The following NFSv4 ACL inheritance flags are supported: -
    -
    -ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT (.B f ) -Inherit parent directory ACE to files. -
    -ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT (.B d ) -Inherit parent directory ACE to subdirectories. -
    -ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY (.B i ) -Only inherit, do not apply the permission on the directory itself. -
    -ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT (.B n ) -Do not propagate inherit flags. -Only first-level entries inherit ACLs. -
    -ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS (.B S ) -Trigger alarm or audit on successful access. -
    -ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS (.B F ) -Trigger alarm or audit on failed access. -
    -ARCHIVE_ENTRY_ACL_ENTRY_INHERITED (.B I ) -Mark that ACE was inherited. -
    -=== Functions=== -'''archive_entry_acl_add_entry'''() -and -'''archive_entry_acl_add_entry_w'''() -add a single ACL entry. -For the access ACL and non-extended principals, the classic Unix permissions -are updated. -An archive entry cannot contain both POSIX.1e and NFSv4 ACL entries. - -'''archive_entry_acl_clear'''() -removes all ACL entries and resets the enumeration pointer. - -'''archive_entry_acl_count'''() -counts the ACL entries that have the given type mask. -can be the bitwise-or of -
    -
    -ARCHIVE_ENTRY_ACL_TYPE_ACCESS -
    -ARCHIVE_ENTRY_ACL_TYPE_DEFAULT -
    -for POSIX.1e ACLs and -
    -
    -ARCHIVE_ENTRY_ACL_TYPE_ALLOW -
    -ARCHIVE_ENTRY_ACL_TYPE_DENY -
    -ARCHIVE_ENTRY_ACL_TYPE_AUDIT -
    -ARCHIVE_ENTRY_ACL_TYPE_ALARM -
    -for NFSv4 ACLs. -For POSIX.1e ACLs if -ARCHIVE_ENTRY_ACL_TYPE_ACCESS -is included and at least one extended ACL entry is found, -the three non-extended ACLs are added. - -'''archive_entry_acl_from_text'''() -and -'''archive_entry_acl_from_text_w'''() -add new -(or merge with existing) -ACL entries from -(wide) -text. -The argument -may take one of the following values: -
    -
    -ARCHIVE_ENTRY_ACL_TYPE_ACCESS -
    -ARCHIVE_ENTRY_ACL_TYPE_DEFAULT -
    -ARCHIVE_ENTRY_ACL_TYPE_NFS4 -
    -Supports all formats that can be created with -'''archive_entry_acl_to_text'''() -or respectively -'''archive_entry_acl_to_text_w'''(). -Existing ACL entries are preserved. -To get a clean new ACL from text -'''archive_entry_acl_clear'''() -must be called first. -Entries prefixed with -"default:" -are treated as -ARCHIVE_ENTRY_ACL_TYPE_DEFAULT -unless -is -ARCHIVE_ENTRY_ACL_TYPE_NFS4. -Invalid entries, non-parseable ACL entries and entries beginning with -the -Sq # -character -(comments) -are skipped. - -'''archive_entry_acl_next'''() -return the next entry of the ACL list. -This functions may only be called after -'''archive_entry_acl_reset'''() -has indicated the presence of extended ACL entries. - -'''archive_entry_acl_reset'''() -prepare reading the list of ACL entries with -'''archive_entry_acl_next'''(). -The function returns 0 if no non-extended ACLs are found. -In this case, the access permissions should be obtained by -[[ManPageArchiveEntryMode3]] -or set using -[[chmod(2)|http://www.freebsd.org/cgi/man.cgi?query=chmod&sektion=2]]. -Otherwise, the function returns the same value as -'''archive_entry_acl_count'''(). - -'''archive_entry_acl_to_text'''() -and -'''archive_entry_acl_to_text_w'''() -convert the ACL entries for the given type into a -(wide) -string of ACL entries separated by newline. -If the pointer -is not NULL, then the function shall return the length of the string -(not including the NULL terminator) -in the location pointed to by -. -The -argument is a bitwise-or. - -The following flags are effective only on POSIX.1e ACL: -
    -
    -ARCHIVE_ENTRY_ACL_TYPE_ACCESS -Output access ACLs. -
    -ARCHIVE_ENTRY_ACL_TYPE_DEFAULT -Output POSIX.1e default ACLs. -
    -ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT -Prefix each default ACL entry with the word -"default:". -
    -ARCHIVE_ENTRY_ACL_STYLE_SOLARIS -The mask and other ACLs don not contain a double colon. -
    - -The following flags are effecive only on NFSv4 ACL: -
    -
    -ARCHIVE_ENTRY_ACL_STYLE_COMPACT -Do not output minus characters for unset permissions and flags in NFSv4 ACL -permission and flag fields. -
    - -The following flags are effective on both POSIX.1e and NFSv4 ACL: -
    -
    -ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID -Add an additional colon-separated field containing the user or group id. -
    -ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA -Separate ACL entries with comma instead of newline. -
    - -If the archive entry contains NFSv4 ACLs, all types of NFSv4 ACLs are returned. -It the entry contains POSIX.1e ACLs and none of the flags -ARCHIVE_ENTRY_ACL_TYPE_ACCESS -or -ARCHIVE_ENTRY_ACL_TYPE_DEFAULT -are specified, both access and default entries are returned and default entries -are prefixed with -"default:". - -'''archive_entry_acl_types'''() -get ACL entry types contained in an archive entry's ACL. -As POSIX.1e and NFSv4 -ACL entries cannot be mixed, this function is a very efficient way to detect if -an ACL already contains POSIX.1e or NFSv4 ACL entries. -== RETURN VALUES == -'''archive_entry_acl_count'''() -and -'''archive_entry_acl_reset'''() -returns the number of ACL entries that match the given type mask. -For POSIX.1e ACLS if the type mask includes -ARCHIVE_ENTRY_ACL_TYPE_ACCESS -and at least one extended ACL entry exists, the three classic Unix -permissions are counted. - -'''archive_entry_acl_from_text'''() -and -'''archive_entry_acl_from_text_w'''() -return -ARCHIVE_OK -if all entries were successfully parsed and -ARCHIVE_WARN -if one or more entries were invalid or non-parseable. - -'''archive_entry_acl_next'''() -returns -ARCHIVE_OK -on success, -ARCHIVE_EOF -if no more ACL entries exist -and -ARCHIVE_WARN -if -'''archive_entry_acl_reset'''() -has not been called first. - -'''archive_entry_acl_to_text'''() -returns a string representing the ACL entries matching the given type and -flags on success or NULL on error. - -'''archive_entry_acl_to_text_w'''() -returns a wide string representing the ACL entries matching the given type -and flags on success or NULL on error. - -'''archive_entry_acl_types'''() -returns a bitmask of ACL entry types or 0 if archive entry has no ACL entries. -== SEE ALSO == -[[ManPageArchiveEntry3]], -[[ManPageLibarchive3]] diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveEntryLinkify3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveEntryLinkify3.wiki deleted file mode 100644 index a94b398c9..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveEntryLinkify3.wiki +++ /dev/null @@ -1,197 +0,0 @@ -ARCHIVE_ENTRY_LINKIFY(3) manual page -== NAME == -'''archive_entry_linkresolver''', -'''archive_entry_linkresolver_new''', -'''archive_entry_linkresolver_set_strategy''', -'''archive_entry_linkresolver_free''', -'''archive_entry_linkify''' -- hardlink resolver functions -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''struct archive_entry_linkresolver *'' -
    -'''archive_entry_linkresolver_new'''(''void''); -
    -''void'' -
    -'''archive_entry_linkresolver_set_strategy'''(''struct archive_entry_linkresolver *resolver'', ''int format''); -
    -''void'' -
    -'''archive_entry_linkresolver_free'''(''struct archive_entry_linkresolver *resolver''); -
    -''void'' -
    -'''archive_entry_linkify'''(''struct archive_entry_linkresolver *resolver'', ''struct archive_entry **entry'', ''struct archive_entry **sparse''); -== DESCRIPTION == -Programs that want to create archives have to deal with hardlinks. -Hardlinks are handled in different ways by the archive formats. -The basic strategies are: -
      -
    1. -Ignore hardlinks and store the body for each reference (old cpio, zip). -
    2. -Store the body the first time an inode is seen (ustar, pax). -
    3. -Store the body the last time an inode is seen (new cpio). -
    - -The -'''archive_entry_linkresolver''' -functions help by providing a unified interface and handling the complexity -behind the scene. - -The -'''archive_entry_linkresolver''' -functions assume that -''archive_entry'' -instances have valid nlinks, inode and device values. -The inode and device value is used to match entries. -The nlinks value is used to determined if all references have been found and -if the internal references can be recycled. - -The -'''archive_entry_linkresolver_new'''() -function allocates a new link resolver. -The instance can be freed using -'''archive_entry_linkresolver_free'''(). -All deferred entries are flushed and the internal storage is freed. - -The -'''archive_entry_linkresolver_set_strategy'''() -function selects the optimal hardlink strategy for the given format. -The format code can be obtained from -[[ManPageArchiveFormat3]]. -The function can be called more than once, but it is recommended to -flush all deferred entries first. - -The -'''archive_entry_linkify'''() -function is the core of -'''archive_entry_linkresolver'''. -The -'''entry'''() -argument points to the -''archive_entry'' -that should be written. -Depending on the strategy one of the following actions is taken: -
      -
    1. -For the simple archive formats -''*entry'' -is left unmodified and -''*sparse'' -is set to -NULL. -
    2. -For tar like archive formats, -''*sparse'' -is set to -NULL. -If -''*entry'' -is -NULL, -no action is taken. -If the hardlink count of -''*entry'' -is larger than 1 and the file type is a regular file or symbolic link, -the internal list is searched for a matching inode. -If such an inode is found, the link count is decremented and the file size -of -''*entry'' -is set to 0 to notify that no body should be written. -If no such inode is found, a copy of the entry is added to the internal cache -with a link count reduced by one. -
    3. -For new cpio like archive formats a value for -''*entry'' -of -NULL -is used to flush deferred entries. -In that case -''*entry'' -is set to an arbitrary deferred entry and the entry itself is removed from the -internal list. -If the internal list is empty, -''*entry'' -is set to -NULL. -In either case, -''*sparse'' -is set to -NULL -and the function returns. -If the hardlink count of -''*entry'' -is one or the file type is a directory or device, -''*sparse'' -is set to -NULL -and no further action is taken. -Otherwise, the internal list is searched for a matching inode. -If such an inode is not found, the entry is added to the internal list, -both -''*entry'' -and -''*sparse'' -are set to -NULL -and the function returns. -If such an inode is found, the link count is decremented. -If it remains larger than one, the existing entry on the internal list -is swapped with -''*entry'' -after retaining the link count. -The existing entry is returned in -''*entry''. -If the link count reached one, the new entry is also removed from the -internal list and returned in -''*sparse''. -Otherwise -''*sparse'' -is set to -NULL. -
    - -The general usage is therefore: -
      -
    1. -For each new archive entry, call -'''archive_entry_linkify'''(). -
    2. -Keep in mind that the entries returned may have a size of 0 now. -
    3. -If -''*entry'' -is not -NULL, -archive it. -
    4. -If -''*sparse'' -is not -NULL, -archive it. -
    5. -After all entries have been written to disk, call -'''archive_entry_linkify'''() -with -''*entry'' -set to -NULL -and archive the returned entry as long as it is not -NULL. -
    -== RETURN VALUES == -'''archive_entry_linkresolver_new'''() -returns -NULL -on -[[malloc(3)|http://www.freebsd.org/cgi/man.cgi?query=malloc&sektion=3]] -failures. -== SEE ALSO == -[[ManPageArchiveEntry3]] diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveEntryMisc3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveEntryMisc3.wiki deleted file mode 100644 index 624adc869..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveEntryMisc3.wiki +++ /dev/null @@ -1,41 +0,0 @@ -ARCHIVE_ENTRY_MISC(3) manual page -== NAME == -'''archive_entry_symlink_type''', -'''archive_entry_set_symlink_type''' -- miscellaneous functions for manipulating properties of archive_entry -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''int'' -
    -'''archive_entry_symlink_type'''(''struct archive_entry *a''); -
    -''void'' -
    -'''archive_entry_set_symlink_type'''(''struct archive_entry *a'', ''int''); -== DESCRIPTION == -The function -'''archive_entry_symlink_type'''() -returns and the function -'''archive_entry_set_symlink_type'''() -sets the type of the symbolic link stored in an archive entry. -These functions -have special meaning on operating systems that support multiple symbolic link -types (e.g. Microsoft Windows). - -Supported values are: -
    -
    AE_SYMLINK_TYPE_UNDEFINED
    -Symbolic link target type is not defined (default on unix systems) -
    AE_SYMLINK_TYPE_FILE
    -Symbolic link points to a file -
    AE_SYMLINK_TYPE_DIRECTORY
    -Symbolic link points to a directory -
    -== SEE ALSO == -[[ManPageArchiveEntry3]], -[[ManPageArchiveEntryPaths3]], -[[ManPageArchiveEntryStat3]], -[[ManPageLibarchive3]] diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveEntryPaths3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveEntryPaths3.wiki deleted file mode 100644 index 32a9a0447..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveEntryPaths3.wiki +++ /dev/null @@ -1,175 +0,0 @@ -ARCHIVE_ENTRY_PATHS(3) manual page -== NAME == -'''archive_entry_hardlink''', -'''archive_entry_hardlink_w''', -'''archive_entry_set_hardlink''', -'''archive_entry_copy_hardlink''', -'''archive_entry_copy_hardlink_w''', -'''archive_entry_update_hardlink_utf8''', -'''archive_entry_set_link''', -'''archive_entry_copy_link''', -'''archive_entry_copy_link_w''', -'''archive_entry_update_link_utf8''', -'''archive_entry_pathname''', -'''archive_entry_pathname_w''', -'''archive_entry_set_pathname''', -'''archive_entry_copy_pathname''', -'''archive_entry_copy_pathname_w''', -'''archive_entry_update_pathname_utf8''', -'''archive_entry_sourcepath''', -'''archive_entry_copy_sourcepath''', -'''archive_entry_symlink''', -'''archive_entry_symlink_w''', -'''archive_entry_set_symlink''', -'''archive_entry_copy_symlink''', -'''archive_entry_copy_symlink_w''', -'''archive_entry_update_symlink_utf8''' -- functions for manipulating path names in archive entry descriptions -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''const char *'' -
    -'''archive_entry_hardlink'''(''struct archive_entry *a''); -
    -''const wchar_t *'' -
    -'''archive_entry_hardlink_w'''(''struct archive_entry *a''); -
    -''void'' -
    -'''archive_entry_set_hardlink'''(''struct archive_entry *a'', ''const char *path''); -
    -''void'' -
    -'''archive_entry_copy_hardlink'''(''struct archive_entry *a'', ''const char *path''); -
    -''void'' -
    -'''archive_entry_copy_hardlink_w'''(''struct archive_entry *a '', ''const'', ''wchar_t'', ''*path"''); -
    -''int'' -
    -'''archive_entry_update_hardlink_utf8'''(''struct archive_entry *a'', ''const char *path''); -
    -''void'' -
    -'''archive_entry_set_link'''(''struct archive_entry *a'', ''const char *path''); -
    -''void'' -
    -'''archive_entry_copy_link'''(''struct archive_entry *a'', '' const char *path''); -
    -''void'' -
    -'''archive_entry_copy_link_w'''(''struct archive_entry *a'', '' const wchar_t *path''); -
    -''int'' -
    -'''archive_entry_update_link_utf8'''(''struct archive_entry *a'', '' const char *path''); -
    -''const char *'' -
    -'''archive_entry_pathname'''(''struct archive_entry *a''); -
    -''const wchar_t *'' -
    -'''archive_entry_pathname_w'''(''struct archive_entry *a''); -
    -''void'' -
    -'''archive_entry_set_pathname'''(''struct archive_entry *a'', ''const char *path''); -
    -''void'' -
    -'''archive_entry_copy_pathname'''(''struct archive_entry *a'', ''const char *path''); -
    -''void'' -
    -'''archive_entry_copy_pathname_w'''(''struct archive_entry *a'', ''const wchar_t *path''); -
    -''int'' -
    -'''archive_entry_update_pathname_utf8'''(''struct archive_entry *a'', ''const char *path''); -
    -''const char *'' -
    -'''archive_entry_sourcepath'''(''struct archive_entry *a''); -
    -''void'' -
    -'''archive_entry_copy_sourcepath'''(''struct archive_entry *a'', ''const char *path''); -
    -''const char *'' -
    -'''archive_entry_symlink'''(''struct archive_entry *a''); -
    -''const wchar_t *'' -
    -'''archive_entry_symlink_w'''(''struct archive_entry *a''); -
    -''void'' -
    -'''archive_entry_set_symlink'''(''struct archive_entry *a'', ''const char *path''); -
    -''void'' -
    -'''archive_entry_copy_symlink'''(''struct archive_entry *a'', ''const char *path''); -
    -''void'' -
    -'''archive_entry_copy_symlink_w'''(''struct archive_entry *a'', ''const wchar_t *path''); -
    -''int'' -
    -'''archive_entry_update_symlink_utf8'''(''struct archive_entry *a'', ''const char *path''); -== DESCRIPTION == -Path names supported by -[[ManPageArchiveEntry3]]: -
    -
    hardlink
    -Destination of the hardlink. -
    link
    -Update only. -For a symlink, update the destination. -Otherwise, make the entry a hardlink and alter -the destination for that. -
    pathname
    -Path in the archive -
    sourcepath
    -Path on the disk for use by -[[ManPageArchiveReadDisk3]]. -
    symlink
    -Destination of the symbolic link. -
    - -Path names can be provided in one of three different ways: -
    -
    char *
    -Multibyte strings in the current locale. -
    wchar_t *
    -Wide character strings in the current locale. -The accessor functions are named -'''XXX_w'''(). -
    UTF-8
    -Unicode strings encoded as UTF-8. -These are convenience functions to update both the multibyte and wide -character strings at the same time. -
    - -The sourcepath is a pure filesystem concept and never stored in an -archive directly. - -For that reason, it is only available as multibyte string. -The link path is a convenience function for conditionally setting -hardlink or symlink destination. -It doesn't have a corresponding get accessor function. - -'''archive_entry_set_XXX'''() -is an alias for -'''archive_entry_copy_XXX'''(). -== SEE ALSO == -[[ManPageArchiveEntry3]], -[[ManPageLibarchive3]] diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveEntryPerms3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveEntryPerms3.wiki deleted file mode 100644 index 27802c2aa..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveEntryPerms3.wiki +++ /dev/null @@ -1,222 +0,0 @@ -ARCHIVE_ENTRY_PERMS(3) manual page -== NAME == -'''archive_entry_gid''', -'''archive_entry_set_gid''', -'''archive_entry_uid''', -'''archive_entry_set_uid''', -'''archive_entry_perm''', -'''archive_entry_set_perm''', -'''archive_entry_strmode''', -'''archive_entry_uname''', -'''archive_entry_uname_w''', -'''archive_entry_set_uname''', -'''archive_entry_copy_uname''', -'''archive_entry_copy_uname_w''', -'''archive_entry_update_uname_utf8''', -'''archive_entry_gname''', -'''archive_entry_gname_w''', -'''archive_entry_set_gname''', -'''archive_entry_copy_gname''', -'''archive_entry_copy_gname_w''', -'''archive_entry_update_gname_utf8''', -'''archive_entry_fflags''', -'''archive_entry_fflags_text''', -'''archive_entry_set_fflags''', -'''archive_entry_copy_fflags_text''', -'''archive_entry_copy_fflags_text_w''' -- functions for manipulating ownership and permissions in archive entry descriptions -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''gid_t'' -
    -'''archive_entry_gid'''(''struct archive_entry *a''); -
    -''void'' -
    -'''archive_entry_set_gid'''(''struct archive_entry *a'', ''gid_t gid''); -
    -''uid_t'' -
    -'''archive_entry_uid'''(''struct archive_entry *a''); -
    -''void'' -
    -'''archive_entry_set_uid'''(''struct archive_entry *a'', ''uid_t uid''); -
    -''mode_t'' -
    -'''archive_entry_perm'''(''struct archive_entry *a''); -
    -''void'' -
    -'''archive_entry_set_perm'''(''struct archive_entry *a'', ''mode_t mode''); -
    -''const char *'' -
    -'''archive_entry_strmode'''(''struct archive_entry *a''); -
    -''const char *'' -
    -'''archive_entry_gname'''(''struct archive_entry *a''); -
    -''const wchar_t *'' -
    -'''archive_entry_gname_w'''(''struct archive_entry *a''); -
    -''void'' -
    -'''archive_entry_set_gname'''(''struct archive_entry *a'', ''const char *a''); -
    -''void'' -
    -'''archive_entry_copy_gname'''(''struct archive_entry *a'', ''const char *name''); -
    -''void'' -
    -'''archive_entry_copy_gname_w'''(''struct archive_entry *a'', ''const wchar_t *name''); -
    -''int'' -
    -'''archive_entry_update_gname_utf8'''(''struct archive_entry *a'', ''const char *name''); -
    -''const char *'' -
    -'''archive_entry_uname'''(''struct archive_entry *a''); -
    -''const wchar_t *'' -
    -'''archive_entry_uname_w'''(''struct archive_entry *a''); -
    -''void'' -
    -'''archive_entry_set_uname'''(''struct archive_entry *a'', ''const char *name''); -
    -''void'' -
    -'''archive_entry_copy_uname'''(''struct archive_entry *a'', ''const char *name''); -
    -''void'' -
    -'''archive_entry_copy_uname_w'''(''struct archive_entry *a'', ''const wchar_t *name''); -
    -''int'' -
    -'''archive_entry_update_uname_utf8'''(''struct archive_entry *a'', ''const char *name''); -
    -''void'' -
    -'''archive_entry_fflags'''(''struct archive_entry *a'', ''unsigned long *set_bits'', ''unsigned long *clear_bits''); -
    -''const char *'' -
    -'''archive_entry_fflags_text'''(''struct archive_entry *a''); -
    -''void'' -
    -'''archive_entry_set_fflags'''(''struct archive_entry *a'', ''unsigned long set_bits'', ''unsigned long clear_bits''); -
    -''const char *'' -
    -'''archive_entry_copy_fflags_text'''(''struct archive_entry *a'', ''const char *text''); -
    -''const wchar_t *'' -
    -'''archive_entry_copy_fflags_text_w'''(''struct archive_entry *a'', ''const wchar_t *text''); -== DESCRIPTION == -=== User id, group id and mode=== -The functions -'''archive_entry_uid'''(), -'''archive_entry_gid'''(), -and -'''archive_entry_perm'''() -can be used to extract the user id, group id and permission from the given entry. -The corresponding functions -'''archive_entry_set_uid'''(), -'''archive_entry_set_gid'''(), -and -'''archive_entry_set_perm'''() -store the given user id, group id and permission in the entry. -The permission is also set as a side effect of calling -'''archive_entry_set_mode'''(). - -'''archive_entry_strmode'''() -returns a string representation of the permission as used by the long mode of -[[ls(1)|http://www.freebsd.org/cgi/man.cgi?query=ls&sektion=1]]. -=== User and group name=== -User and group names can be provided in one of three different ways: -
    -
    char *
    -Multibyte strings in the current locale. -
    wchar_t *
    -Wide character strings in the current locale. -The accessor functions are named -'''XXX_w'''(). -
    UTF-8
    -Unicode strings encoded as UTF-8. -These are convenience functions to update both the multibyte and wide -character strings at the same time. -
    - -'''archive_entry_set_XXX'''() -is an alias for -'''archive_entry_copy_XXX'''(). -=== File Flags=== -File flags are transparently converted between a bitmap -representation and a textual format. -For example, if you set the bitmap and ask for text, the library -will build a canonical text format. -However, if you set a text format and request a text format, -you will get back the same text, even if it is ill-formed. -If you need to canonicalize a textual flags string, you should first set the -text form, then request the bitmap form, then use that to set the bitmap form. -Setting the bitmap format will clear the internal text representation -and force it to be reconstructed when you next request the text form. - -The bitmap format consists of two integers, one containing bits -that should be set, the other specifying bits that should be -cleared. -Bits not mentioned in either bitmap will be ignored. -Usually, the bitmap of bits to be cleared will be set to zero. -In unusual circumstances, you can force a fully-specified set -of file flags by setting the bitmap of flags to clear to the complement -of the bitmap of flags to set. -(This differs from -[[fflagstostr(3)|http://www.freebsd.org/cgi/man.cgi?query=fflagstostr&sektion=3]], -which only includes names for set bits.) -Converting a bitmap to a textual string is a platform-specific -operation; bits that are not meaningful on the current platform -will be ignored. - -The canonical text format is a comma-separated list of flag names. -The -'''archive_entry_copy_fflags_text'''() -and -'''archive_entry_copy_fflags_text_w'''() -functions parse the provided text and set the internal bitmap values. -This is a platform-specific operation; names that are not meaningful -on the current platform will be ignored. -The function returns a pointer to the start of the first name that was not -recognized, or NULL if every name was recognized. -Note that every name \(em including names that follow an unrecognized -name \(em will be evaluated, and the bitmaps will be set to reflect -every name that is recognized. -(In particular, this differs from -[[strtofflags(3)|http://www.freebsd.org/cgi/man.cgi?query=strtofflags&sektion=3]], -which stops parsing at the first unrecognized name.) -== SEE ALSO == -[[ManPageArchiveEntry3]], -[[ManPageArchiveEntryAcl3]], -[[ManPageArchiveReadDisk3]], -[[ManPageArchiveWriteDisk3]], -[[ManPageLibarchive3]] -== BUGS == -The platform types -''uid_t'' -and -''gid_t'' -are often 16 or 32 bit wide. -In this case it is possible that the ids can not be correctly restored -from archives and get truncated. diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveEntryStat3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveEntryStat3.wiki deleted file mode 100644 index 881b70726..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveEntryStat3.wiki +++ /dev/null @@ -1,308 +0,0 @@ -ARCHIVE_ENTRY_STAT(3) manual page -== NAME == -'''archive_entry_stat''', -'''archive_entry_copy_stat''', -'''archive_entry_filetype''', -'''archive_entry_set_filetype''', -'''archive_entry_mode''', -'''archive_entry_set_mode''', -'''archive_entry_size''', -'''archive_entry_size_is_set''', -'''archive_entry_set_size''', -'''archive_entry_unset_size''', -'''archive_entry_dev''', -'''archive_entry_set_dev''', -'''archive_entry_dev_is_set''', -'''archive_entry_devmajor''', -'''archive_entry_set_devmajor''', -'''archive_entry_devminor''', -'''archive_entry_set_devminor''', -'''archive_entry_ino''', -'''archive_entry_set_ino''', -'''archive_entry_ino_is_set''', -'''archive_entry_ino64''', -'''archive_entry_set_ino64''', -'''archive_entry_nlink''', -'''archive_entry_rdev''', -'''archive_entry_set_rdev''', -'''archive_entry_rdevmajor''', -'''archive_entry_set_rdevmajor''', -'''archive_entry_rdevminor''', -'''archive_entry_set_rdevminor''' -- accessor functions for manipulating archive entry descriptions -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''const struct stat *'' -
    -'''archive_entry_stat'''(''struct archive_entry *a''); -
    -''void'' -
    -'''archive_entry_copy_stat'''(''struct archive_entry *a'', ''const struct stat *sb''); -
    -''mode_t'' -
    -'''archive_entry_filetype'''(''struct archive_entry *a''); -
    -''void'' -
    -'''archive_entry_set_filetype'''(''struct archive_entry *a'', ''unsigned int type''); -
    -''mode_t'' -
    -'''archive_entry_mode'''(''struct archive_entry *a''); -
    -''void'' -
    -'''archive_entry_set_mode'''(''struct archive_entry *a'', ''mode_t mode''); -
    -''int64_t'' -
    -'''archive_entry_size'''(''struct archive_entry *a''); -
    -''int'' -
    -'''archive_entry_size_is_set'''(''struct archive_entry *a''); -
    -''void'' -
    -'''archive_entry_set_size'''(''struct archive_entry *a'', ''int64_t size''); -
    -''void'' -
    -'''archive_entry_unset_size'''(''struct archive_entry *a''); -
    -''dev_t'' -
    -'''archive_entry_dev'''(''struct archive_entry *a''); -
    -''void'' -
    -'''archive_entry_set_dev'''(''struct archive_entry *a'', ''dev_t dev''); -
    -''int'' -
    -'''archive_entry_dev_is_set'''(''struct archive_entry *a''); -
    -''dev_t'' -
    -'''archive_entry_devmajor'''(''struct archive_entry *a''); -
    -''void'' -
    -'''archive_entry_set_devmajor'''(''struct archive_entry *a'', ''dev_t major''); -
    -''dev_t'' -
    -'''archive_entry_devminor'''(''struct archive_entry *a''); -
    -''void'' -
    -'''archive_entry_set_devminor'''(''struct archive_entry *a'', ''dev_t minor''); -
    -''ino_t'' -
    -'''archive_entry_ino'''(''struct archive_entry *a''); -
    -''void'' -
    -'''archive_entry_set_ino'''(''struct archive_entry *a'', ''unsigned long ino''); -
    -''int'' -
    -'''archive_entry_ino_is_set'''(''struct archive_entry *a''); -
    -''int64_t'' -
    -'''archive_entry_ino64'''(''struct archive_entry *a''); -
    -''void'' -
    -'''archive_entry_set_ino64'''(''struct archive_entry *a'', ''int64_t ino''); -
    -''unsigned int'' -
    -'''archive_entry_nlink'''(''struct archive_entry *a''); -
    -''void'' -
    -'''archive_entry_set_nlink'''(''struct archive_entry *a'', ''unsigned int count''); -
    -''dev_t'' -
    -'''archive_entry_rdev'''(''struct archive_entry *a''); -
    -''dev_t'' -
    -'''archive_entry_rdevmajor'''(''struct archive_entry *a''); -
    -''dev_t'' -
    -'''archive_entry_rdevminor'''(''struct archive_entry *a''); -
    -''void'' -
    -'''archive_entry_set_rdev'''(''struct archive_entry *a'', ''dev_t dev''); -
    -''void'' -
    -'''archive_entry_set_rdevmajor'''(''struct archive_entry *a'', ''dev_t major''); -
    -''void'' -
    -'''archive_entry_set_rdevminor'''(''struct archive_entry *a'', ''dev_t minor''); -== DESCRIPTION == -=== Copying to and from ''struct'' stat=== -The function -'''archive_entry_stat'''() -converts the various fields stored in the archive entry to the format -used by -[[stat(2)|http://www.freebsd.org/cgi/man.cgi?query=stat&sektion=2]]. -The return value remains valid until either -'''archive_entry_clear'''() -or -'''archive_entry_free'''() -is called. -It is not affected by calls to the set accessor functions. -It currently sets the following values in -''struct'' stat: -''st_atime'', -''st_ctime'', -''st_dev'', -''st_gid'', -''st_ino'', -''st_mode'', -''st_mtime'', -''st_nlink'', -''st_rdev'', -''st_size'', -''st_uid''. -In addition, -''st_birthtime'' -and high-precision information for time-related fields -will be included on platforms that support it. - -The function -'''archive_entry_copy_stat'''() -copies fields from the platform's -''struct'' stat. -Fields not provided by -''struct'' stat -are unchanged. -=== General accessor functions=== -The functions -'''archive_entry_filetype'''() -and -'''archive_entry_set_filetype'''() -get respectively set the filetype. -The file type is one of the following constants: -
    -
    AE_IFREG
    -Regular file -
    AE_IFLNK
    -Symbolic link -
    AE_IFSOCK
    -Socket -
    AE_IFCHR
    -Character device -
    AE_IFBLK
    -Block device -
    AE_IFDIR
    -Directory -
    AE_IFIFO
    -Named pipe (fifo) -
    -Not all file types are supported by all platforms. -The constants used by -[[stat(2)|http://www.freebsd.org/cgi/man.cgi?query=stat&sektion=2]] -may have different numeric values from the -corresponding constants above. - -The functions -'''archive_entry_mode'''() -and -'''archive_entry_set_mode'''() -get/set a combination of file type and permissions and provide the -equivalent of -''st_mode''. -Use of -'''archive_entry_filetype'''() -and -'''archive_entry_perm'''() -for getting and -'''archive_entry_set_filetype'''() -and -'''archive_entry_set_perm'''() -for setting is recommended. - -The function -'''archive_entry_size'''() -returns the file size, if it has been set, and 0 otherwise. -'''archive_entry_size'''() -can be used to query that status. -'''archive_entry_set_size'''() -and -'''archive_entry_unset_size'''() -set and unset the size, respectively. - -The number of references (hardlinks) can be obtained by calling -'''archive_entry_nlink'''() -and set with -'''archive_entry_set_nlink'''(). -=== Identifying unique files=== -The functions -'''archive_entry_dev'''() -and -'''archive_entry_ino64'''() -are used by -[[ManPageArchiveEntryLinkify3]] -to find hardlinks. -The pair of device and inode is supposed to identify hardlinked files. - -The device major and minor number can be obtained independently using -'''archive_entry_devmajor'''() -and -'''archive_entry_devminor'''(). -The device can be set either via -'''archive_entry_set_dev'''() -or by the combination of major and minor number using -'''archive_entry_set_devmajor'''() -and -'''archive_entry_set_devminor'''(). - -The inode number can be obtained using -'''archive_entry_ino'''(). -This is a legacy interface that uses the platform -''ino_t'', -which may be very small. -To set the inode number, -'''archive_entry_set_ino64'''() -is the preferred interface. -=== Accessor functions for block and character devices=== -Block and character devices are characterised either using a device number -or a pair of major and minor number. -The combined device number can be obtained with -'''archive_device_rdev'''() -and set with -'''archive_device_set_rdev'''(). -The major and minor numbers are accessed by -'''archive_device_rdevmajor'''(), -'''archive_device_rdevminor'''() -'''archive_device_set_rdevmajor'''() -and -'''archive_device_set_rdevminor'''(). - -The process of splitting the combined device number into major and -minor number and the reverse process of combing them differs between -platforms. -Some archive formats use the combined form, while other formats use -the split form. -== SEE ALSO == -[[stat(2)|http://www.freebsd.org/cgi/man.cgi?query=stat&sektion=2]], -[[ManPageArchiveEntryAcl3]], -[[ManPageArchiveEntryPerms3]], -[[ManPageArchiveEntryTime3]], -[[ManPageLibarchive3]] diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveEntryTime3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveEntryTime3.wiki deleted file mode 100644 index 004093a13..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveEntryTime3.wiki +++ /dev/null @@ -1,138 +0,0 @@ -ARCHIVE_ENTRY_TIME(3) manual page -== NAME == -'''archive_entry_atime''', -'''archive_entry_atime_nsec''', -'''archive_entry_atime_is_set''', -'''archive_entry_set_atime''', -'''archive_entry_unset_atime''', -'''archive_entry_birthtime''', -'''archive_entry_birthtime_nsec''', -'''archive_entry_birthtime_is_set''', -'''archive_entry_set_birthtime''', -'''archive_entry_unset_birthtime''', -'''archive_entry_ctime''', -'''archive_entry_ctime_nsec''', -'''archive_entry_ctime_is_set''', -'''archive_entry_set_ctime''', -'''archive_entry_unset_ctime''', -'''archive_entry_mtime''', -'''archive_entry_mtime_nsec''', -'''archive_entry_mtime_is_set''', -'''archive_entry_set_mtime''', -'''archive_entry_unset_mtime''' -- functions for manipulating times in archive entry descriptions -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''time_t'' -
    -'''archive_entry_atime'''(''struct archive_entry *a''); -
    -''long'' -
    -'''archive_entry_atime_nsec'''(''struct archive_entry *a''); -
    -''int'' -
    -'''archive_entry_atime_is_set'''(''struct archive_entry *a''); -
    -''void'' -
    -'''archive_entry_set_atime'''(''struct archive_entry *a'', ''time_t sec'', ''long nanosec''); -
    -''void'' -
    -'''archive_entry_unset_atime'''(''struct archive_entry *a''); -
    -''time_t'' -
    -'''archive_entry_birthtime'''(''struct archive_entry *a''); -
    -''long'' -
    -'''archive_entry_birthtime_nsec'''(''struct archive_entry *a''); -
    -''int'' -
    -'''archive_entry_birthtime_is_set'''(''struct archive_entry *a''); -
    -''void'' -
    -'''archive_entry_set_birthtime'''(''struct archive_entry *a'', ''time_t sec'', ''long nanosec''); -
    -''void'' -
    -'''archive_entry_unset_birthtime'''(''struct archive_entry *a''); -
    -''time_t'' -
    -'''archive_entry_ctime'''(''struct archive_entry *a''); -
    -''long'' -
    -'''archive_entry_ctime_nsec'''(''struct archive_entry *a''); -
    -''int'' -
    -'''archive_entry_ctime_is_set'''(''struct archive_entry *a''); -
    -''void'' -
    -'''archive_entry_set_ctime'''(''struct archive_entry *a'', ''time_t sec'', ''long nanosec''); -
    -''void'' -
    -'''archive_entry_unset_ctime'''(''struct archive_entry *a''); -
    -''time_t'' -
    -'''archive_entry_mtime'''(''struct archive_entry *a''); -
    -''long'' -
    -'''archive_entry_mtime_nsec'''(''struct archive_entry *a''); -
    -''int'' -
    -'''archive_entry_mtime_is_set'''(''struct archive_entry *a''); -
    -''void'' -
    -'''archive_entry_set_mtime'''(''struct archive_entry *a'', ''time_t sec'', ''long nanosec''); -
    -''void'' -
    -'''archive_entry_unset_mtime'''(''struct archive_entry *a''); -== DESCRIPTION == -These functions create and manipulate the time fields in an -''archive_entry''. -Supported time fields are atime (access time), birthtime (creation time), -ctime (last time an inode property was changed) and mtime (modification time). - -[[ManPageLibarchive3]] -provides a high-resolution interface. -The timestamps are truncated automatically depending on the archive format -(for archiving) or the filesystem capabilities (for restoring). - -All timestamp fields are optional. -The -'''XXX_unset'''() -functions can be used to mark the corresponding field as missing. -The current state can be queried using -'''XXX_is_set'''(). -Unset time fields have a second and nanosecond field of 0. -== SEE ALSO == -[[ManPageArchiveEntry3]], -[[ManPageLibarchive3]] -== HISTORY == -The -'''libarchive''' -library first appeared in -FreeBSD 5.3. -== AUTHORS == -The -'''libarchive''' -library was written by -Tim Kientzle <kientzle@acm.org.> diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveRead3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveRead3.wiki deleted file mode 100644 index ca26570d1..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveRead3.wiki +++ /dev/null @@ -1,208 +0,0 @@ -ARCHIVE_READ(3) manual page -== NAME == -'''archive_read''' -- functions for reading streaming archives -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -== DESCRIPTION == -These functions provide a complete API for reading streaming archives. -The general process is to first create the -'''struct archive''' -object, set options, initialize the reader, iterate over the archive -headers and associated data, then close the archive and release all -resources. -=== Create archive object=== -See -[[ManPageArchiveReadNew3]]. - -To read an archive, you must first obtain an initialized -'''struct archive''' -object from -'''archive_read_new'''(). -=== Enable filters and formats=== -See -[[ManPageArchiveReadFilter3]] -and -[[ManPageArchiveReadFormat3]]. - -You can then modify this object for the desired operations with the -various -'''archive_read_set_XXX'''() -and -'''archive_read_support_XXX'''() -functions. -In particular, you will need to invoke appropriate -'''archive_read_support_XXX'''() -functions to enable the corresponding compression and format -support. -Note that these latter functions perform two distinct operations: -they cause the corresponding support code to be linked into your -program, and they enable the corresponding auto-detect code. -Unless you have specific constraints, you will generally want -to invoke -'''archive_read_support_filter_all'''() -and -'''archive_read_support_format_all'''() -to enable auto-detect for all formats and compression types -currently supported by the library. -=== Set options=== -See -[[ManPageArchiveReadSetOptions3]]. -=== Open archive=== -See -[[ManPageArchiveReadOpen3]]. - -Once you have prepared the -'''struct archive''' -object, you call -'''archive_read_open'''() -to actually open the archive and prepare it for reading. -There are several variants of this function; -the most basic expects you to provide pointers to several -functions that can provide blocks of bytes from the archive. -There are convenience forms that allow you to -specify a filename, file descriptor, -''FILE *'' -object, or a block of memory from which to read the archive data. -Note that the core library makes no assumptions about the -size of the blocks read; -callback functions are free to read whatever block size is -most appropriate for the medium. -=== Consume archive=== -See -[[ManPageArchiveReadHeader3]], -[[ManPageArchiveReadData3]] -and -[[ManPageArchiveReadExtract3]]. - -Each archive entry consists of a header followed by a certain -amount of data. -You can obtain the next header with -'''archive_read_next_header'''(), -which returns a pointer to an -'''struct archive_entry''' -structure with information about the current archive element. -If the entry is a regular file, then the header will be followed -by the file data. -You can use -'''archive_read_data'''() -(which works much like the -[[read(2)|http://www.freebsd.org/cgi/man.cgi?query=read&sektion=2]] -system call) -to read this data from the archive, or -'''archive_read_data_block'''() -which provides a slightly more efficient interface. -You may prefer to use the higher-level -'''archive_read_data_skip'''(), -which reads and discards the data for this entry, -'''archive_read_data_into_fd'''(), -which copies the data to the provided file descriptor, or -'''archive_read_extract'''(), -which recreates the specified entry on disk and copies data -from the archive. -In particular, note that -'''archive_read_extract'''() -uses the -'''struct archive_entry''' -structure that you provide it, which may differ from the -entry just read from the archive. -In particular, many applications will want to override the -pathname, file permissions, or ownership. -=== Release resources=== -See -[[ManPageArchiveReadFree3]]. - -Once you have finished reading data from the archive, you -should call -'''archive_read_close'''() -to close the archive, then call -'''archive_read_free'''() -to release all resources, including all memory allocated by the library. -== EXAMPLES == -The following illustrates basic usage of the library. -In this example, -the callback functions are simply wrappers around the standard -[[open(2)|http://www.freebsd.org/cgi/man.cgi?query=open&sektion=2]], -[[read(2)|http://www.freebsd.org/cgi/man.cgi?query=read&sektion=2]], -and -[[close(2)|http://www.freebsd.org/cgi/man.cgi?query=close&sektion=2]] -system calls. -```text -void -list_archive(const char *name) -{ - struct mydata *mydata; - struct archive *a; - struct archive_entry *entry; - mydata = malloc(sizeof(struct mydata)); - a = archive_read_new(); - mydata->name = name; - archive_read_support_filter_all(a); - archive_read_support_format_all(a); - archive_read_open(a, mydata, myopen, myread, myclose); - while (archive_read_next_header(a, &entry) == ARCHIVE_OK) { - printf("%s\en",archive_entry_pathname(entry)); - archive_read_data_skip(a); - } - archive_read_free(a); - free(mydata); -} -la_ssize_t -myread(struct archive *a, void *client_data, const void **buff) -{ - struct mydata *mydata = client_data; - *buff = mydata->buff; - return (read(mydata->fd, mydata->buff, 10240)); -} -int -myopen(struct archive *a, void *client_data) -{ - struct mydata *mydata = client_data; - mydata->fd = open(mydata->name, O_RDONLY); - return (mydata->fd >= 0 ? ARCHIVE_OK : ARCHIVE_FATAL); -} -int -myclose(struct archive *a, void *client_data) -{ - struct mydata *mydata = client_data; - if (mydata->fd > 0) - close(mydata->fd); - return (ARCHIVE_OK); -} -``` -== SEE ALSO == -[[ManPageBsdtar1]], -[[ManPageArchiveReadData3]], -[[ManPageArchiveReadExtract3]], -[[ManPageArchiveReadFilter3]], -[[ManPageArchiveReadFormat3]], -[[ManPageArchiveReadHeader3]], -[[ManPageArchiveReadNew3]], -[[ManPageArchiveReadOpen3]], -[[ManPageArchiveReadSetOptions3]], -[[ManPageArchiveUtil3]], -[[ManPageLibarchive3]], -[[ManPageTar5]] -== HISTORY == -The -'''libarchive''' -library first appeared in -FreeBSD 5.3. -== AUTHORS == -The -'''libarchive''' -library was written by -Tim Kientzle <kientzle@acm.org.> -== BUGS == -Many traditional archiver programs treat -empty files as valid empty archives. -For example, many implementations of -[[ManPageBsdtar1]] -allow you to append entries to an empty file. -Of course, it is impossible to determine the format of an empty file -by inspecting the contents, so this library treats empty files as -having a special -"empty" -format. diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveReadAddPassphrase3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveReadAddPassphrase3.wiki deleted file mode 100644 index 3cb9cd3ba..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveReadAddPassphrase3.wiki +++ /dev/null @@ -1,42 +0,0 @@ -ARCHIVE_READ_ADD_PASSPHRASE(3) manual page -== NAME == -'''archive_read_add_passphrase''', -'''archive_read_set_passphrase_callback''' -- functions for reading encrypted archives -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''int'' -
    -'''archive_read_add_passphrase'''(''struct archive *'', ''const char *passphrase''); -
    -''int'' -
    -'''archive_read_set_passphrase_callback'''(''struct archive *'', ''void *client_data'', ''archive_passphrase_callback *''); -== DESCRIPTION == -
    -
    '''archive_read_add_passphrase'''()
    -Register passphrases for reading an encryption archive. -If -''passphrase'' -is -NULL -or empty, this function will do nothing and -'''ARCHIVE_FAILED''' -will be returned. -Otherwise, -'''ARCHIVE_OK''' -will be returned. -
    '''archive_read_set_passphrase_callback'''()
    -Register a callback function that will be invoked to get a passphrase -for decryption after trying all the passphrases registered by the -'''archive_read_add_passphrase'''() -function failed. -
    -== SEE ALSO == -[[ManPageBsdtar1]], -[[ManPageArchiveRead3]], -[[ManPageArchiveReadSetOptions3]], -[[ManPageLibarchive3]] diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveReadData3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveReadData3.wiki deleted file mode 100644 index baa2f9987..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveReadData3.wiki +++ /dev/null @@ -1,101 +0,0 @@ -ARCHIVE_READ_DATA(3) manual page -== NAME == -'''archive_read_data''', -'''archive_read_data_block''', -'''archive_read_data_skip''', -'''archive_read_data_into_fd''' -- functions for reading streaming archives -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''la_ssize_t'' -
    -'''archive_read_data'''(''struct archive *'', ''void *buff'', ''size_t len''); -
    -''int'' -
    -'''archive_read_data_block'''(''struct archive *'', ''const void **buff'', ''size_t *len'', ''off_t *offset''); -
    -''int'' -
    -'''archive_read_data_skip'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_data_into_fd'''(''struct archive *'', ''int fd''); -== DESCRIPTION == -
    -
    '''archive_read_data'''()
    -Read data associated with the header just read. -Internally, this is a convenience function that calls -'''archive_read_data_block'''() -and fills any gaps with nulls so that callers see a single -continuous stream of data. -
    '''archive_read_data_block'''()
    -Return the next available block of data for this entry. -Unlike -'''archive_read_data'''(), -the -'''archive_read_data_block'''() -function avoids copying data and allows you to correctly handle -sparse files, as supported by some archive formats. -The library guarantees that offsets will increase and that blocks -will not overlap. -Note that the blocks returned from this function can be much larger -than the block size read from disk, due to compression -and internal buffer optimizations. -
    '''archive_read_data_skip'''()
    -A convenience function that repeatedly calls -'''archive_read_data_block'''() -to skip all of the data for this archive entry. -Note that this function is invoked automatically by -'''archive_read_next_header2'''() -if the previous entry was not completely consumed. -
    '''archive_read_data_into_fd'''()
    -A convenience function that repeatedly calls -'''archive_read_data_block'''() -to copy the entire entry to the provided file descriptor. -
    -== RETURN VALUES == -Most functions return zero on success, non-zero on error. -The possible return codes include: -'''ARCHIVE_OK''' -(the operation succeeded), -'''ARCHIVE_WARN''' -(the operation succeeded but a non-critical error was encountered), -'''ARCHIVE_EOF''' -(end-of-archive was encountered), -'''ARCHIVE_RETRY''' -(the operation failed but can be retried), -and -'''ARCHIVE_FATAL''' -(there was a fatal error; the archive should be closed immediately). - -'''archive_read_data'''() -returns a count of bytes actually read or zero at the end of the entry. -On error, a value of -'''ARCHIVE_FATAL''', -'''ARCHIVE_WARN''', -or -'''ARCHIVE_RETRY''' -is returned. -== ERRORS == -Detailed error codes and textual descriptions are available from the -'''archive_errno'''() -and -'''archive_error_string'''() -functions. -== SEE ALSO == -[[ManPageBsdtar1]], -[[ManPageArchiveRead3]], -[[ManPageArchiveReadExtract3]], -[[ManPageArchiveReadFilter3]], -[[ManPageArchiveReadFormat3]], -[[ManPageArchiveReadHeader3]], -[[ManPageArchiveReadOpen3]], -[[ManPageArchiveReadSetOptions3]], -[[ManPageArchiveUtil3]], -[[ManPageLibarchive3]], -[[ManPageTar5]] diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveReadDisk3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveReadDisk3.wiki deleted file mode 100644 index eec92b28d..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveReadDisk3.wiki +++ /dev/null @@ -1,408 +0,0 @@ -ARCHIVE_READ_DISK(3) manual page -== NAME == -'''archive_read_disk_new''', -'''archive_read_disk_open''', -'''archive_read_disk_open_w''', -'''archive_read_disk_set_behavior''', -'''archive_read_disk_set_symlink_logical''', -'''archive_read_disk_set_symlink_physical''', -'''archive_read_disk_set_symlink_hybrid''', -'''archive_read_disk_entry_from_file''', -'''archive_read_disk_gname''', -'''archive_read_disk_uname''', -'''archive_read_disk_set_uname_lookup''', -'''archive_read_disk_set_gname_lookup''', -'''archive_read_disk_set_standard_lookup''', -'''archive_read_disk_descend''', -'''archive_read_disk_can_descend''', -'''archive_read_disk_current_filesystem''', -'''archive_read_disk_current_filesystem_is_synthetic''', -'''archive_read_disk_current_filesystem_is_remote''', -'''archive_read_disk_set_matching''', -'''archive_read_disk_set_metadata_filter_callback''', -- functions for reading objects from disk -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''struct archive *'' -
    -'''archive_read_disk_new'''(''void''); -
    -''int'' -
    -'''archive_read_disk_open'''(''struct archive *'', ''const char *''); -
    -''int'' -
    -'''archive_read_disk_open_w'''(''struct archive *'', ''const wchar_t *'', ''''); -
    -''int'' -
    -'''archive_read_disk_set_behavior'''(''struct archive *'', ''int''); -
    -''int'' -
    -'''archive_read_disk_set_symlink_logical'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_disk_set_symlink_physical'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_disk_set_symlink_hybrid'''(''struct archive *''); -
    -''const char *'' -
    -'''archive_read_disk_gname'''(''struct archive *'', ''gid_t''); -
    -''const char *'' -
    -'''archive_read_disk_uname'''(''struct archive *'', ''uid_t''); -
    -''int'' -
    -'''archive_read_disk_set_gname_lookup'''(''struct archive *'', ''void *'', ''const char *(*lookup)(void *, gid_t)'', ''void (*cleanup)(void *)''); -
    -''int'' -
    -'''archive_read_disk_set_uname_lookup'''(''struct archive *'', ''void *'', ''const char *(*lookup)(void *, uid_t)'', ''void (*cleanup)(void *)''); -
    -''int'' -
    -'''archive_read_disk_set_standard_lookup'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_disk_entry_from_file'''(''struct archive *'', ''struct archive_entry *'', ''int fd'', ''const struct stat *''); -
    -''int'' -
    -'''archive_read_disk_descend'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_disk_can_descend'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_disk_current_filesystem'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_disk_current_filesystem_is_synthetic'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_disk_current_filesystem_is_remote'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_disk_set_matching'''(''struct archive *'', ''struct archive *'', ''void (*excluded_func)(struct archive *, void *, struct archive entry *)'', ''void *''); -
    -''int'' -
    -'''archive_read_disk_set_metadata_filter_callback'''(''struct archive *'', ''int (*metadata_filter_func)(struct archive *, void*, struct archive_entry *)'', ''void *''); -== DESCRIPTION == -These functions provide an API for reading information about -objects on disk. -In particular, they provide an interface for populating -'''struct archive_entry''' -objects. -
    -
    '''archive_read_disk_new'''()
    -Allocates and initializes a -'''struct archive''' -object suitable for reading object information from disk. -
    '''archive_read_disk_open'''()
    -Opens the file or directory from the given path and prepares the -'''struct archive''' -to read it from disk. -
    '''archive_read_disk_open_w'''()
    -Opens the file or directory from the given path as a wide character string and prepares the -'''struct archive''' -to read it from disk. -
    '''archive_read_disk_set_behavior'''()
    -Configures various behavior options when reading entries from disk. -The flags field consists of a bitwise OR of one or more of the -following values: -
    -
    '''ARCHIVE_READDISK_HONOR_NODUMP'''
    -Skip files and directories with the nodump file attribute (file flag) set. -By default, the nodump file attribute is ignored. -
    '''ARCHIVE_READDISK_MAC_COPYFILE'''
    -Mac OS X specific. -Read metadata (ACLs and extended attributes) with -[[copyfile(3)|http://www.freebsd.org/cgi/man.cgi?query=copyfile&sektion=3]]. -By default, metadata is read using -[[copyfile(3)|http://www.freebsd.org/cgi/man.cgi?query=copyfile&sektion=3]]. -
    '''ARCHIVE_READDISK_NO_ACL'''
    -Do not read Access Control Lists. -By default, ACLs are read from disk. -
    '''ARCHIVE_READDISK_NO_FFLAGS'''
    -Do not read file attributes (file flags). -By default, file attributes are read from disk. -See -[[chattr(1)|http://www.freebsd.org/cgi/man.cgi?query=chattr&sektion=1]] -(Linux) -or -[[chflags(1)|http://www.freebsd.org/cgi/man.cgi?query=chflags&sektion=1]] -(FreeBSD, Mac OS X) -for more information on file attributes. -
    '''ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS'''
    -Do not traverse mount points. -By default, mount points are traversed. -
    '''ARCHIVE_READDISK_NO_XATTR'''
    -Do not read extended file attributes (xattrs). -By default, extended file attributes are read from disk. -See -[[xattr(7)|http://www.freebsd.org/cgi/man.cgi?query=xattr&sektion=7]] -(Linux,) -[[xattr(2)|http://www.freebsd.org/cgi/man.cgi?query=xattr&sektion=2]] -(Mac OS X,) -or -[[getextattr(8)|http://www.freebsd.org/cgi/man.cgi?query=getextattr&sektion=8]] -(FreeBSD) -for more information on extended file attributes. -
    '''ARCHIVE_READDISK_RESTORE_ATIME'''
    -Restore access time of traversed files. -By default, access time of traversed files is not restored. -
    '''ARCHIVE_READDISK_NO_SPARSE'''
    -Do not read sparse file information. -By default, sparse file information is read from disk. -
    -
    -'''archive_read_disk_set_symlink_logical'''(), -'''archive_read_disk_set_symlink_physical'''(), -'''archive_read_disk_set_symlink_hybrid'''() -
    -This sets the mode used for handling symbolic links. -The -"logical" -mode follows all symbolic links. -The -"physical" -mode does not follow any symbolic links. -The -"hybrid" -mode currently behaves identically to the -"logical" -mode. -
    -'''archive_read_disk_gname'''(), -'''archive_read_disk_uname'''() -
    -Returns a user or group name given a gid or uid value. -By default, these always return a NULL string. -
    -'''archive_read_disk_set_gname_lookup'''(), -'''archive_read_disk_set_uname_lookup'''() -
    -These allow you to override the functions used for -user and group name lookups. -You may also provide a -'''void *''' -pointer to a private data structure and a cleanup function for -that data. -The cleanup function will be invoked when the -'''struct archive''' -object is destroyed or when new lookup functions are registered. -
    '''archive_read_disk_set_standard_lookup'''()
    -This convenience function installs a standard set of user -and group name lookup functions. -These functions use -[[getpwuid(3)|http://www.freebsd.org/cgi/man.cgi?query=getpwuid&sektion=3]] -and -[[getgrgid(3)|http://www.freebsd.org/cgi/man.cgi?query=getgrgid&sektion=3]] -to convert ids to names, defaulting to NULL if the names cannot -be looked up. -These functions also implement a simple memory cache to reduce -the number of calls to -[[getpwuid(3)|http://www.freebsd.org/cgi/man.cgi?query=getpwuid&sektion=3]] -and -[[getgrgid(3)|http://www.freebsd.org/cgi/man.cgi?query=getgrgid&sektion=3]]. -
    '''archive_read_disk_entry_from_file'''()
    -Populates a -'''struct archive_entry''' -object with information about a particular file. -The -'''archive_entry''' -object must have already been created with -[[ManPageArchiveEntryNew3]] -and at least one of the source path or path fields must already be set. -(If both are set, the source path will be used.) - -Information is read from disk using the path name from the -'''struct archive_entry''' -object. -If a file descriptor is provided, some information will be obtained using -that file descriptor, on platforms that support the appropriate -system calls. - -If a pointer to a -'''struct stat''' -is provided, information from that structure will be used instead -of reading from the disk where appropriate. -This can provide performance benefits in scenarios where -'''struct stat''' -information has already been read from the disk as a side effect -of some other operation. -(For example, directory traversal libraries often provide this information.) - -Where necessary, user and group ids are converted to user and group names -using the currently-registered lookup functions above. -This affects the file ownership fields and ACL values in the -'''struct archive_entry''' -object. -
    '''archive_read_disk_descend'''()
    -If the current entry can be descended, this function will mark the directory as the next entry for -[[ManPageArchiveReadHeader3]] -to visit. -
    '''archive_read_disk_can_descend'''()
    -Returns 1 if the current entry is an unvisited directory and 0 otherwise. -
    '''archive_read_disk_current_filesystem'''()
    -Returns the index of the most recent filesystem entry that has been visited through archive_read_disk -
    '''archive_read_disk_current_filesystem_is_synthetic'''()
    -Returns 1 if the current filesystem is a virtual filesystem. Returns 0 if the current filesystem is not a virtual filesystem. Returns -1 if it is unknown. -
    '''archive_read_disk_current_filesystem_is_remote'''()
    -Returns 1 if the current filesystem is a remote filesystem. Returns 0 if the current filesystem is not a remote filesystem. Returns -1 if it is unknown. -
    '''archive_read_disk_set_matching'''()
    -Allows the caller to set -'''struct archive''' -*_ma to compare each entry during -[[ManPageArchiveReadHeader3]] -calls. If matched based on calls to -'''archive_match_path_excluded ,''' -'''archive_match_time_excluded ,''' -or -'''archive_match_owner_excluded ,''' -then the callback function specified by the _excluded_func parameter will execute. This function will recieve data provided to the fourth parameter, void *_client_data. -
    '''archive_read_disk_set_metadata_filter_callback'''()
    -Allows the caller to set a callback function during calls to -[[ManPageArchiveReadHeader3]] -to filter out metadata for each entry. The callback function recieves the -'''struct archive''' -object, void* custom filter data, and the -'''struct archive_entry .''' -If the callback function returns an error, ARCHIVE_RETRY will be returned and the entry will not be further processed. -
    -More information about the -''struct'' archive -object and the overall design of the library can be found in the -[[ManPageLibarchive3]] -overview. -== EXAMPLES == -The following illustrates basic usage of the library by -showing how to use it to copy an item on disk into an archive. -```text -void -file_to_archive(struct archive *a, const char *name) -{ - char buff[8192]; - size_t bytes_read; - struct archive *ard; - struct archive_entry *entry; - int fd; - ard = archive_read_disk_new(); - archive_read_disk_set_standard_lookup(ard); - entry = archive_entry_new(); - fd = open(name, O_RDONLY); - if (fd < 0) - return; - archive_entry_copy_pathname(entry, name); - archive_read_disk_entry_from_file(ard, entry, fd, NULL); - archive_write_header(a, entry); - while ((bytes_read = read(fd, buff, sizeof(buff))) > 0) - archive_write_data(a, buff, bytes_read); - archive_write_finish_entry(a); - archive_read_free(ard); - archive_entry_free(entry); -} -``` -== RETURN VALUES == -Most functions return -'''ARCHIVE_OK''' -(zero) on success, or one of several negative -error codes for errors. -Specific error codes include: -'''ARCHIVE_RETRY''' -for operations that might succeed if retried, -'''ARCHIVE_WARN''' -for unusual conditions that do not prevent further operations, and -'''ARCHIVE_FATAL''' -for serious errors that make remaining operations impossible. - -'''archive_read_disk_new'''() -returns a pointer to a newly-allocated -'''struct archive''' -object or NULL if the allocation failed for any reason. - -'''archive_read_disk_gname'''() -and -'''archive_read_disk_uname'''() -return -'''const char *''' -pointers to the textual name or NULL if the lookup failed for any reason. -The returned pointer points to internal storage that -may be reused on the next call to either of these functions; -callers should copy the string if they need to continue accessing it. -== ERRORS == -Detailed error codes and textual descriptions are available from the -'''archive_errno'''() -and -'''archive_error_string'''() -functions. -== SEE ALSO == -[[ManPageBsdtar1]], -[[ManPageArchiveRead3]], -[[ManPageArchiveUtil3]], -[[ManPageArchiveWrite3]], -[[ManPageArchiveWriteDisk3]], -[[ManPageLibarchive3]] -== HISTORY == -The -'''libarchive''' -library first appeared in -FreeBSD 5.3. -The -'''archive_read_disk''' -interface was added to -'''libarchive''' 2.6 -and first appeared in -FreeBSD 8.0. -== AUTHORS == -The -'''libarchive''' -library was written by -Tim Kientzle <kientzle@FreeBSD.org.> -== BUGS == -The -"standard" -user name and group name lookup functions are not the defaults because -[[getgrgid(3)|http://www.freebsd.org/cgi/man.cgi?query=getgrgid&sektion=3]] -and -[[getpwuid(3)|http://www.freebsd.org/cgi/man.cgi?query=getpwuid&sektion=3]] -are sometimes too large for particular applications. -The current design allows the application author to use a more -compact implementation when appropriate. - -The full list of metadata read from disk by -'''archive_read_disk_entry_from_file'''() -is necessarily system-dependent. - -The -'''archive_read_disk_entry_from_file'''() -function reads as much information as it can from disk. -Some method should be provided to limit this so that clients who -do not need ACLs, for instance, can avoid the extra work needed -to look up such information. - -This API should provide a set of methods for walking a directory tree. -That would make it a direct parallel of the -[[ManPageArchiveRead3]] -API. -When such methods are implemented, the -"hybrid" -symbolic link mode will make sense. diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveReadExtract3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveReadExtract3.wiki deleted file mode 100644 index 9cd9dec36..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveReadExtract3.wiki +++ /dev/null @@ -1,102 +0,0 @@ -ARCHIVE_READ_EXTRACT(3) manual page -== NAME == -'''archive_read_extract''', -'''archive_read_extract2''', -'''archive_read_extract_set_progress_callback''' -- functions for reading streaming archives -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''int'' -
    -'''archive_read_extract'''(''struct archive *'', ''struct archive_entry *'', ''int flags''); -
    -''int'' -
    -'''archive_read_extract2'''(''struct archive *src'', ''struct archive_entry *'', ''struct archive *dest''); -
    -''void'' -
    -'''archive_read_extract_set_progress_callback'''(''struct archive *'', ''void (*func)(void *)'', ''void *user_data''); -== DESCRIPTION == -
    -
    '''archive_read_extract'''(), '''archive_read_extract_set_skip_file'''()
    -A convenience function that wraps the corresponding -[[ManPageArchiveWriteDisk3]] -interfaces. -The first call to -'''archive_read_extract'''() -creates a restore object using -[[ManPageArchiveWriteDiskNew3]] -and -[[ManPageArchiveWriteDiskSetStandardLookup3]], -then transparently invokes -[[ManPageArchiveWriteDiskSetOptions3]], -[[ManPageArchiveWriteHeader3]], -[[ManPageArchiveWriteData3]], -and -[[ManPageArchiveWriteFinishEntry3]] -to create the entry on disk and copy data into it. -The -''flags'' -argument is passed unmodified to -[[ManPageArchiveWriteDiskSetOptions3]]. -
    '''archive_read_extract2'''()
    -This is another version of -'''archive_read_extract'''() -that allows you to provide your own restore object. -In particular, this allows you to override the standard lookup functions -using -[[ManPageArchiveWriteDiskSetGroupLookup3]], -and -[[ManPageArchiveWriteDiskSetUserLookup3]]. -Note that -'''archive_read_extract2'''() -does not accept a -''flags'' -argument; you should use -'''archive_write_disk_set_options'''() -to set the restore options yourself. -
    '''archive_read_extract_set_progress_callback'''()
    -Sets a pointer to a user-defined callback that can be used -for updating progress displays during extraction. -The progress function will be invoked during the extraction of large -regular files. -The progress function will be invoked with the pointer provided to this call. -Generally, the data pointed to should include a reference to the archive -object and the archive_entry object so that various statistics -can be retrieved for the progress display. -
    -== RETURN VALUES == -Most functions return zero on success, non-zero on error. -The possible return codes include: -'''ARCHIVE_OK''' -(the operation succeeded), -'''ARCHIVE_WARN''' -(the operation succeeded but a non-critical error was encountered), -'''ARCHIVE_EOF''' -(end-of-archive was encountered), -'''ARCHIVE_RETRY''' -(the operation failed but can be retried), -and -'''ARCHIVE_FATAL''' -(there was a fatal error; the archive should be closed immediately). -== ERRORS == -Detailed error codes and textual descriptions are available from the -'''archive_errno'''() -and -'''archive_error_string'''() -functions. -== SEE ALSO == -[[ManPageBsdtar1]], -[[ManPageArchiveRead3]], -[[ManPageArchiveReadData3]], -[[ManPageArchiveReadFilter3]], -[[ManPageArchiveReadFormat3]], -[[ManPageArchiveReadOpen3]], -[[ManPageArchiveReadSetOptions3]], -[[ManPageArchiveUtil3]], -[[ManPageLibarchive3]], -[[ManPageTar5]] diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveReadFilter3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveReadFilter3.wiki deleted file mode 100644 index 84c85c365..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveReadFilter3.wiki +++ /dev/null @@ -1,155 +0,0 @@ -ARCHIVE_READ_FILTER(3) manual page -== NAME == -'''archive_read_support_filter_all''', -'''archive_read_support_filter_bzip2''', -'''archive_read_support_filter_compress''', -'''archive_read_support_filter_gzip''', -'''archive_read_support_filter_lz4''', -'''archive_read_support_filter_lzma''', -'''archive_read_support_filter_none''', -'''archive_read_support_filter_rpm''', -'''archive_read_support_filter_uu''', -'''archive_read_support_filter_xz''', -'''archive_read_support_filter_zstd''', -'''archive_read_support_filter_program''', -'''archive_read_support_filter_program_signature''' -- functions for reading streaming archives -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''int'' -
    -'''archive_read_support_filter_all'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_support_filter_by_code'''(''struct archive *'', ''int''); -
    -''int'' -
    -'''archive_read_support_filter_bzip2'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_support_filter_compress'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_support_filter_grzip'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_support_filter_gzip'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_support_filter_lrzip'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_support_filter_lz4'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_support_filter_lzma'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_support_filter_lzop'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_support_filter_none'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_support_filter_rpm'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_support_filter_uu'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_support_filter_xz'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_support_filter_zstd'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_support_filter_program'''(''struct archive *'', ''const char *cmd''); -
    -''int'' -
    -'''archive_read_support_filter_program_signature'''(''struct archive *'', ''const char *cmd'', ''const void *signature'', ''size_t signature_length''); -== DESCRIPTION == -
    -
    -'''archive_read_support_filter_bzip2'''(), -'''archive_read_support_filter_compress'''(), -'''archive_read_support_filter_grzip'''(), -'''archive_read_support_filter_gzip'''(), -'''archive_read_support_filter_lrzip'''(), -'''archive_read_support_filter_lz4'''(), -'''archive_read_support_filter_lzma'''(), -'''archive_read_support_filter_lzop'''(), -'''archive_read_support_filter_none'''(), -'''archive_read_support_filter_rpm'''(), -'''archive_read_support_filter_uu'''(), -'''archive_read_support_filter_xz'''(), -'''archive_read_support_filter_zstd'''(), -
    -Enables auto-detection code and decompression support for the -specified compression. -These functions may fall back on external programs if an appropriate -library was not available at build time. -Decompression using an external program is usually slower than -decompression through built-in libraries. -Note that -"none" -is always enabled by default. -
    '''archive_read_support_filter_all'''()
    -Enables all available decompression filters. -
    '''archive_read_support_filter_by_code'''()
    -Enables a single filter specified by the filter code. -This function does not work with -'''ARCHIVE_FILTER_PROGRAM'''. -Note: In statically-linked executables, this will cause -your program to include support for every filter. -If executable size is a concern, you may wish to avoid -using this function. -
    '''archive_read_support_filter_program'''()
    -Data is fed through the specified external program before being dearchived. -Note that this disables automatic detection of the compression format, -so it makes no sense to specify this in conjunction with any other -decompression option. -
    '''archive_read_support_filter_program_signature'''()
    -This feeds data through the specified external program -but only if the initial bytes of the data match the specified -signature value. -
    -== RETURN VALUES == -These functions return -'''ARCHIVE_OK''' -if the compression is fully supported, -'''ARCHIVE_WARN''' -if the compression is supported only through an external program. - -'''archive_read_support_filter_none'''() -always succeeds. -== ERRORS == -Detailed error codes and textual descriptions are available from the -'''archive_errno'''() -and -'''archive_error_string'''() -functions. -== SEE ALSO == -[[ManPageArchiveRead3]], -[[ManPageArchiveReadData3]], -[[ManPageArchiveReadFormat3]], -[[ManPageArchiveReadFormat3]], -[[ManPageLibarchive3]] diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveReadFormat3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveReadFormat3.wiki deleted file mode 100644 index f6289fa55..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveReadFormat3.wiki +++ /dev/null @@ -1,174 +0,0 @@ -ARCHIVE_READ_FORMAT(3) manual page -== NAME == -'''archive_read_support_format_7zip''', -'''archive_read_support_format_all''', -'''archive_read_support_format_ar''', -'''archive_read_support_format_by_code''', -'''archive_read_support_format_cab''', -'''archive_read_support_format_cpio''', -'''archive_read_support_format_empty''', -'''archive_read_support_format_iso9660''', -'''archive_read_support_format_lha''', -'''archive_read_support_format_mtree''', -'''archive_read_support_format_rar''', -'''archive_read_support_format_raw''', -'''archive_read_support_format_tar''', -'''archive_read_support_format_xar''', -'''archive_read_support_format_zip''' -- functions for reading streaming archives -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''int'' -
    -'''archive_read_support_format_7zip'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_support_format_all'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_support_format_ar'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_support_format_by_code'''(''struct archive *'', ''int''); -
    -''int'' -
    -'''archive_read_support_format_cab'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_support_format_cpio'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_support_format_empty'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_support_format_iso9660'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_support_format_lha'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_support_format_mtree'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_support_format_rar'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_support_format_raw'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_support_format_tar'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_support_format_xar'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_support_format_zip'''(''struct archive *''); -== DESCRIPTION == -
    -
    -'''archive_read_support_format_7zip'''(), -'''archive_read_support_format_ar'''(), -'''archive_read_support_format_cab'''(), -'''archive_read_support_format_cpio'''(), -'''archive_read_support_format_iso9660'''(), -'''archive_read_support_format_lha'''(), -'''archive_read_support_format_mtree'''(), -'''archive_read_support_format_rar'''(), -'''archive_read_support_format_raw'''(), -'''archive_read_support_format_tar'''(), -'''archive_read_support_format_xar'''(), -'''archive_read_support_format_zip'''() -
    -Enables support---including auto-detection code---for the -specified archive format. -For example, -'''archive_read_support_format_tar'''() -enables support for a variety of standard tar formats, old-style tar, -ustar, pax interchange format, and many common variants. -
    '''archive_read_support_format_all'''()
    -Enables support for all available formats except the -"raw" -format (see below). -
    '''archive_read_support_format_by_code'''()
    -Enables a single format specified by the format code. -This can be useful when reading a single archive twice; -use -'''archive_format'''() -after reading the first time and pass the resulting code -to this function to selectively enable only the necessary -format support. -Note: In statically-linked executables, this will cause -your program to include support for every format. -If executable size is a concern, you may wish to avoid -using this function. -
    '''archive_read_support_format_empty'''()
    -Enables support for treating empty files as empty archives. -Because empty files are valid for several different formats, -it is not possible to accurately determine a format for -an empty file based purely on contents. -So empty files are treated by libarchive as a distinct -format. -
    '''archive_read_support_format_raw'''()
    -The -"raw" -format handler allows libarchive to be used to read arbitrary data. -It treats any data stream as an archive with a single entry. -The pathname of this entry is -"data ;" -all other entry fields are unset. -This is not enabled by -'''archive_read_support_format_all'''() -in order to avoid erroneous handling of damaged archives. -
    -== RETURN VALUES == -These functions return -'''ARCHIVE_OK''' -on success, or -'''ARCHIVE_FATAL'''. -== ERRORS == -Detailed error codes and textual descriptions are available from the -'''archive_errno'''() -and -'''archive_error_string'''() -functions. -== SEE ALSO == -[[ManPageBsdtar1]], -[[ManPageArchiveReadData3]], -[[ManPageArchiveReadFilter3]], -[[ManPageArchiveReadSetOptions3]], -[[ManPageArchiveUtil3]], -[[ManPageLibarchive3]], -[[ManPageTar5]] -== BUGS == -Many traditional archiver programs treat -empty files as valid empty archives. -For example, many implementations of -[[ManPageBsdtar1]] -allow you to append entries to an empty file. -Of course, it is impossible to determine the format of an empty file -by inspecting the contents, so this library treats empty files as -having a special -"empty" -format. - -Using the -"raw" -handler together with any other handler will often work -but can produce surprising results. diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveReadFree3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveReadFree3.wiki deleted file mode 100644 index 852ea6f73..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveReadFree3.wiki +++ /dev/null @@ -1,68 +0,0 @@ -ARCHIVE_READ_FREE(3) manual page -== NAME == -'''archive_read_close''', -'''archive_read_finish''', -'''archive_read_free''' -- functions for reading streaming archives -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''int'' -
    -'''archive_read_close'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_finish'''(''struct archive *''); -
    -''int'' -
    -'''archive_read_free'''(''struct archive *''); -== DESCRIPTION == -
    -
    '''archive_read_close'''()
    -Complete the archive and invoke the close callback. -
    '''archive_read_finish'''()
    -This is a deprecated synonym for -'''archive_read_free'''(). -The new name was introduced with libarchive 3.0. -Applications that need to compile with either libarchive 2 -or libarchive 3 should continue to use the -'''archive_read_finish'''() -name. -Both names will be supported until libarchive 4.0 is -released, which is not expected to occur earlier -than 2013. -
    '''archive_read_free'''()
    -Invokes -'''archive_read_close'''() -if it was not invoked manually, then release all resources. -Note: In libarchive 1.x, this function was declared to return -''void ,'' -which made it impossible to detect certain errors when -'''archive_read_close'''() -was invoked implicitly from this function. -The declaration is corrected beginning with libarchive 2.0. -
    -== RETURN VALUES == -These functions return -'''ARCHIVE_OK''' -on success, or -'''ARCHIVE_FATAL'''. -== ERRORS == -Detailed error codes and textual descriptions are available from the -'''archive_errno'''() -and -'''archive_error_string'''() -functions. -== SEE ALSO == -[[ManPageArchiveReadData3]], -[[ManPageArchiveReadFilter3]], -[[ManPageArchiveReadFormat3]], -[[ManPageArchiveReadNew3]], -[[ManPageArchiveReadOpen3]], -[[ManPageArchiveReadSetOptions3]], -[[ManPageArchiveUtil3]], -[[ManPageLibarchive3]] diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveReadHeader3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveReadHeader3.wiki deleted file mode 100644 index 212d6a787..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveReadHeader3.wiki +++ /dev/null @@ -1,63 +0,0 @@ -ARCHIVE_READ_HEADER(3) manual page -== NAME == -'''archive_read_next_header''', -'''archive_read_next_header2''' -- functions for reading streaming archives -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''int'' -
    -'''archive_read_next_header'''(''struct archive *'', ''struct archive_entry **''); -
    -''int'' -
    -'''archive_read_next_header2'''(''struct archive *'', ''struct archive_entry *''); -== DESCRIPTION == -
    -
    '''archive_read_next_header'''()
    -Read the header for the next entry and return a pointer to -a -'''struct archive_entry .''' -This is a convenience wrapper around -'''archive_read_next_header2'''() -that reuses an internal -'''struct archive_entry''' -object for each request. -
    '''archive_read_next_header2'''()
    -Read the header for the next entry and populate the provided -'''struct archive_entry .''' -
    -== RETURN VALUES == -These functions return -'''ARCHIVE_OK''' -(the operation succeeded), -'''ARCHIVE_WARN''' -(the operation succeeded but a non-critical error was encountered), -'''ARCHIVE_EOF''' -(end-of-archive was encountered), -'''ARCHIVE_RETRY''' -(the operation failed but can be retried), -and -'''ARCHIVE_FATAL''' -(there was a fatal error; the archive should be closed immediately). -== ERRORS == -Detailed error codes and textual descriptions are available from the -'''archive_errno'''() -and -'''archive_error_string'''() -functions. -== SEE ALSO == -[[ManPageBsdtar1]], -[[ManPageArchiveRead3]], -[[ManPageArchiveReadData3]], -[[ManPageArchiveReadExtract3]], -[[ManPageArchiveReadFilter3]], -[[ManPageArchiveReadFormat3]], -[[ManPageArchiveReadOpen3]], -[[ManPageArchiveReadSetOptions3]], -[[ManPageArchiveUtil3]], -[[ManPageLibarchive3]], -[[ManPageTar5]] diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveReadNew3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveReadNew3.wiki deleted file mode 100644 index 7b312be74..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveReadNew3.wiki +++ /dev/null @@ -1,32 +0,0 @@ -ARCHIVE_READ_NEW(3) manual page -== NAME == -'''archive_read_new''' -- functions for reading streaming archives -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''struct archive *'' -
    -'''archive_read_new'''(''void''); -== DESCRIPTION == -Allocates and initializes a -'''struct archive''' -object suitable for reading from an archive. -NULL -is returned on error. - -A complete description of the -'''struct archive''' -object can be found in the overview manual page for -[[ManPageLibarchive3]]. -== SEE ALSO == -[[ManPageBsdtar1]], -[[ManPageArchiveReadData3]], -[[ManPageArchiveReadFilter3]], -[[ManPageArchiveReadFormat3]], -[[ManPageArchiveReadSetOptions3]], -[[ManPageArchiveUtil3]], -[[ManPageLibarchive3]], -[[ManPageTar5]] diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveReadOpen3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveReadOpen3.wiki deleted file mode 100644 index 3accc5dff..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveReadOpen3.wiki +++ /dev/null @@ -1,190 +0,0 @@ -ARCHIVE_READ_OPEN(3) manual page -== NAME == -'''archive_read_open''', -'''archive_read_open2''', -'''archive_read_open_fd''', -'''archive_read_open_FILE''', -'''archive_read_open_filename''', -'''archive_read_open_memory''' -- functions for reading streaming archives -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''int'' -
    -'''archive_read_open'''(''struct archive *'', ''void *client_data'', ''archive_open_callback *'', ''archive_read_callback *'', ''archive_close_callback *''); -
    -''int'' -
    -'''archive_read_open2'''(''struct archive *'', ''void *client_data'', ''archive_open_callback *'', ''archive_read_callback *'', ''archive_skip_callback *'', ''archive_close_callback *''); -
    -''int'' -
    -'''archive_read_open_FILE'''(''struct archive *'', ''FILE *file''); -
    -''int'' -
    -'''archive_read_open_fd'''(''struct archive *'', ''int fd'', ''size_t block_size''); -
    -''int'' -
    -'''archive_read_open_filename'''(''struct archive *'', ''const char *filename'', ''size_t block_size''); -
    -''int'' -
    -'''archive_read_open_memory'''(''struct archive *'', ''const void *buff'', ''size_t size''); -== DESCRIPTION == -
    -
    '''archive_read_open'''()
    -The same as -'''archive_read_open2'''(), -except that the skip callback is assumed to be -NULL. -
    '''archive_read_open2'''()
    -Freeze the settings, open the archive, and prepare for reading entries. -This is the most generic version of this call, which accepts -four callback functions. -Most clients will want to use -'''archive_read_open_filename'''(), -'''archive_read_open_FILE'''(), -'''archive_read_open_fd'''(), -or -'''archive_read_open_memory'''() -instead. -The library invokes the client-provided functions to obtain -raw bytes from the archive. -
    '''archive_read_open_FILE'''()
    -Like -'''archive_read_open'''(), -except that it accepts a -''FILE *'' -pointer. -This function should not be used with tape drives or other devices -that require strict I/O blocking. -
    '''archive_read_open_fd'''()
    -Like -'''archive_read_open'''(), -except that it accepts a file descriptor and block size rather than -a set of function pointers. -Note that the file descriptor will not be automatically closed at -end-of-archive. -This function is safe for use with tape drives or other blocked devices. -
    '''archive_read_open_file'''()
    -This is a deprecated synonym for -'''archive_read_open_filename'''(). -
    '''archive_read_open_filename'''()
    -Like -'''archive_read_open'''(), -except that it accepts a simple filename and a block size. -A NULL filename represents standard input. -This function is safe for use with tape drives or other blocked devices. -
    '''archive_read_open_memory'''()
    -Like -'''archive_read_open'''(), -except that it accepts a pointer and size of a block of -memory containing the archive data. -
    - -A complete description of the -'''struct archive''' -and -'''struct archive_entry''' -objects can be found in the overview manual page for -[[ManPageLibarchive3]]. -== CLIENT CALLBACKS == -The callback functions must match the following prototypes: -
      -
    • -''typedef la_ssize_t'' -'''archive_read_callback'''(''struct archive *'', ''void *client_data'', ''const void **buffer'') -
    • -''typedef la_int64_t'' -'''archive_skip_callback'''(''struct archive *'', ''void *client_data'', ''off_t request'') -
    • -''typedef int'' -'''archive_open_callback'''(''struct archive *'', ''void *client_data'') -
    • -''typedef int'' -'''archive_close_callback'''(''struct archive *'', ''void *client_data'') -
    - -The open callback is invoked by -'''archive_open'''(). -It should return -'''ARCHIVE_OK''' -if the underlying file or data source is successfully -opened. -If the open fails, it should call -'''archive_set_error'''() -to register an error code and message and return -'''ARCHIVE_FATAL'''. - -The read callback is invoked whenever the library -requires raw bytes from the archive. -The read callback should read data into a buffer, -set the -```text -const void **buffer -``` -argument to point to the available data, and -return a count of the number of bytes available. -The library will invoke the read callback again -only after it has consumed this data. -The library imposes no constraints on the size -of the data blocks returned. -On end-of-file, the read callback should -return zero. -On error, the read callback should invoke -'''archive_set_error'''() -to register an error code and message and -return -1. - -The skip callback is invoked when the -library wants to ignore a block of data. -The return value is the number of bytes actually -skipped, which may differ from the request. -If the callback cannot skip data, it should return -zero. -If the skip callback is not provided (the -function pointer is -NULL ), -the library will invoke the read function -instead and simply discard the result. -A skip callback can provide significant -performance gains when reading uncompressed -archives from slow disk drives or other media -that can skip quickly. - -The close callback is invoked by archive_close when -the archive processing is complete. -The callback should return -'''ARCHIVE_OK''' -on success. -On failure, the callback should invoke -'''archive_set_error'''() -to register an error code and message and -return -'''ARCHIVE_FATAL'''. -== RETURN VALUES == -These functions return -'''ARCHIVE_OK''' -on success, or -'''ARCHIVE_FATAL'''. -== ERRORS == -Detailed error codes and textual descriptions are available from the -'''archive_errno'''() -and -'''archive_error_string'''() -functions. -== SEE ALSO == -[[ManPageBsdtar1]], -[[ManPageArchiveRead3]], -[[ManPageArchiveReadData3]], -[[ManPageArchiveReadFilter3]], -[[ManPageArchiveReadFormat3]], -[[ManPageArchiveReadSetOptions3]], -[[ManPageArchiveUtil3]], -[[ManPageLibarchive3]], -[[ManPageTar5]] diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveReadSetOptions3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveReadSetOptions3.wiki deleted file mode 100644 index 4431e1955..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveReadSetOptions3.wiki +++ /dev/null @@ -1,248 +0,0 @@ -ARCHIVE_READ_OPTIONS(3) manual page -== NAME == -'''archive_read_set_filter_option''', -'''archive_read_set_format_option''', -'''archive_read_set_option''', -'''archive_read_set_options''' -- functions controlling options for reading archives -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -
    -''int'' -
    -'''archive_read_set_filter_option'''(''struct archive *'', ''const char *module'', ''const char *option'', ''const char *value''); -
    -''int'' -
    -'''archive_read_set_format_option'''(''struct archive *'', ''const char *module'', ''const char *option'', ''const char *value''); -
    -''int'' -
    -'''archive_read_set_option'''(''struct archive *'', ''const char *module'', ''const char *option'', ''const char *value''); -
    -''int'' -
    -'''archive_read_set_options'''(''struct archive *'', ''const char *options''); -== DESCRIPTION == -These functions provide a way for libarchive clients to configure -specific read modules. -
    -
    -'''archive_read_set_filter_option'''(), -'''archive_read_set_format_option'''() -
    -Specifies an option that will be passed to currently-registered -filters (including decompression filters) or format readers. - -If -''option'' -and -''value'' -are both -NULL, -these functions will do nothing and -'''ARCHIVE_OK''' -will be returned. -If -''option'' -is -NULL -but -''value'' -is not, these functions will do nothing and -'''ARCHIVE_FAILED''' -will be returned. - -If -''module'' -is not -NULL, -''option'' -and -''value'' -will be provided to the filter or reader named -''module''. -The return value will be that of the module. -If there is no such module, -'''ARCHIVE_FAILED''' -will be returned. - -If -''module'' -is -NULL, -''option'' -and -''value'' -will be provided to every registered module. -If any module returns -'''ARCHIVE_FATAL''', -this value will be returned immediately. -Otherwise, -'''ARCHIVE_OK''' -will be returned if any module accepts the option, and -'''ARCHIVE_FAILED''' -in all other cases. -
    -'''archive_read_set_option'''() -
    -Calls -'''archive_read_set_format_option'''(), -then -'''archive_read_set_filter_option'''(). -If either function returns -'''ARCHIVE_FATAL''', -'''ARCHIVE_FATAL''' -will be returned -immediately. -Otherwise, greater of the two values will be returned. -
    -'''archive_read_set_options'''() -
    -''options'' -is a comma-separated list of options. -If -''options'' -is -NULL -or empty, -'''ARCHIVE_OK''' -will be returned immediately. - -Calls -'''archive_read_set_option'''() -with each option in turn. -If any -'''archive_read_set_option'''() -call returns -'''ARCHIVE_FATAL''', -'''ARCHIVE_FATAL''' -will be returned immediately. - -Individual options have one of the following forms: -
    -
    ''option=value''
    -The option/value pair will be provided to every module. -Modules that do not accept an option with this name will ignore it. -
    ''option''
    -The option will be provided to every module with a value of -"1". -
    ''!option''
    -The option will be provided to every module with a NULL value. -
    ''module:option=value'', ''module:option'', ''module:!option''
    -As above, but the corresponding option and value will be provided -only to modules whose name matches -''module''. -
    -
    -== OPTIONS == -
    -
    Format cab
    -
    -
    '''hdrcharset'''
    -The value is used as a character set name that will be -used when translating file names. -
    -
    Format cpio
    -
    -
    '''compat-2x'''
    -Libarchive 2.x incorrectly encoded Unicode filenames on -some platforms. -This option mimics the libarchive 2.x filename handling -so that such archives can be read correctly. -
    '''hdrcharset'''
    -The value is used as a character set name that will be -used when translating file names. -
    '''pwb'''
    -When reading a binary CPIO archive, assume that it is -in the original PWB cpio format, and handle file mode -bits accordingly. The default is to assume v7 format. -
    -
    Format iso9660
    -
    -
    '''joliet'''
    -Support Joliet extensions. -Defaults to enabled, use -'''!joliet''' -to disable. -
    '''rockridge'''
    -Support RockRidge extensions. -Defaults to enabled, use -'''!rockridge''' -to disable. -
    -
    Format lha
    -
    -
    '''hdrcharset'''
    -The value is used as a character set name that will be -used when translating file names. -
    -
    Format mtree
    -
    -
    '''checkfs'''
    -Allow reading information missing from the mtree from the file system. -Disabled by default. -
    -
    Format rar
    -
    -
    '''hdrcharset'''
    -The value is used as a character set name that will be -used when translating file names. -
    -
    Format tar
    -
    -
    '''compat-2x'''
    -Libarchive 2.x incorrectly encoded Unicode filenames on -some platforms. -This option mimics the libarchive 2.x filename handling -so that such archives can be read correctly. -
    '''hdrcharset'''
    -The value is used as a character set name that will be -used when translating file names. -
    '''mac-ext'''
    -Support Mac OS metadata extension that records data in special -files beginning with a period and underscore. -Defaults to enabled on Mac OS, disabled on other platforms. -Use -'''!mac-ext''' -to disable. -
    '''read_concatenated_archives'''
    -Ignore zeroed blocks in the archive, which occurs when multiple tar archives -have been concatenated together. -Without this option, only the contents of -the first concatenated archive would be read. -
    -
    Format zip
    -
    -
    '''compat-2x'''
    -Libarchive 2.x incorrectly encoded Unicode filenames on -some platforms. -This option mimics the libarchive 2.x filename handling -so that such archives can be read correctly. -
    '''hdrcharset'''
    -The value is used as a character set name that will be -used when translating file names. -
    '''ignorecrc32'''
    -Skip the CRC32 check. -Mostly used for testing. -
    '''mac-ext'''
    -Support Mac OS metadata extension that records data in special -files beginning with a period and underscore. -Defaults to enabled on Mac OS, disabled on other platforms. -Use -'''!mac-ext''' -to disable. -
    -
    -== ERRORS == -Detailed error codes and textual descriptions are available from the -'''archive_errno'''() -and -'''archive_error_string'''() -functions. -== SEE ALSO == -[[ManPageBsdtar1]], -[[ManPageArchiveRead3]], -[[ManPageArchiveWriteSetOptions3]], -[[ManPageLibarchive3]] diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveUtil3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveUtil3.wiki deleted file mode 100644 index a2b6376b3..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveUtil3.wiki +++ /dev/null @@ -1,218 +0,0 @@ -ARCHIVE_UTIL(3) manual page -== NAME == -'''archive_clear_error''', -'''archive_compression''', -'''archive_compression_name''', -'''archive_copy_error''', -'''archive_errno''', -'''archive_error_string''', -'''archive_file_count''', -'''archive_filter_code''', -'''archive_filter_count''', -'''archive_filter_name''', -'''archive_format''', -'''archive_format_name''', -'''archive_position''', -'''archive_set_error''' -- libarchive utility functions -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''void'' -
    -'''archive_clear_error'''(''struct archive *''); -
    -''int'' -
    -'''archive_compression'''(''struct archive *''); -
    -''const char *'' -
    -'''archive_compression_name'''(''struct archive *''); -
    -''void'' -
    -'''archive_copy_error'''(''struct archive *'', ''struct archive *''); -
    -''int'' -
    -'''archive_errno'''(''struct archive *''); -
    -''const char *'' -
    -'''archive_error_string'''(''struct archive *''); -
    -''int'' -
    -'''archive_file_count'''(''struct archive *''); -
    -''int'' -
    -'''archive_filter_code'''(''struct archive *'', ''int''); -
    -''int'' -
    -'''archive_filter_count'''(''struct archive *'', ''int''); -
    -''const char *'' -
    -'''archive_filter_name'''(''struct archive *'', ''int''); -
    -''int'' -
    -'''archive_format'''(''struct archive *''); -
    -''const char *'' -
    -'''archive_format_name'''(''struct archive *''); -
    -''int64_t'' -
    -'''archive_position'''(''struct archive *'', ''int''); -
    -''void'' -
    -'''archive_set_error'''(''struct archive *'', ''int error_code'', ''const char *fmt'', ''...''); -== DESCRIPTION == -These functions provide access to various information about the -'''struct archive''' -object used in the -[[ManPageLibarchive3]] -library. -
    -
    '''archive_clear_error'''()
    -Clears any error information left over from a previous call. -Not generally used in client code. -
    '''archive_compression'''()
    -Synonym for -'''archive_filter_code'''(''a'', ''0''). -
    '''archive_compression_name'''()
    -Synonym for -'''archive_filter_name'''(''a'', ''0''). -
    '''archive_copy_error'''()
    -Copies error information from one archive to another. -
    '''archive_errno'''()
    -Returns a numeric error code (see -[[errno(2)|http://www.freebsd.org/cgi/man.cgi?query=errno&sektion=2]]) -indicating the reason for the most recent error return. -Note that this can not be reliably used to detect whether an -error has occurred. -It should be used only after another libarchive function -has returned an error status. -
    '''archive_error_string'''()
    -Returns a textual error message suitable for display. -The error message here is usually more specific than that -obtained from passing the result of -'''archive_errno'''() -to -[[strerror(3)|http://www.freebsd.org/cgi/man.cgi?query=strerror&sektion=3]]. -
    '''archive_file_count'''()
    -Returns a count of the number of files processed by this archive object. -The count is incremented by calls to -[[ManPageArchiveWriteHeader3]] -or -[[ManPageArchiveReadNextHeader3]]. -
    '''archive_filter_code'''()
    -Returns a numeric code identifying the indicated filter. -See -'''archive_filter_count'''() -for details of the numbering. -
    '''archive_filter_count'''()
    -Returns the number of filters in the current pipeline. -For read archive handles, these filters are added automatically -by the automatic format detection. -For write archive handles, these filters are added by calls to the various -'''archive_write_add_filter_XXX'''() -functions. -Filters in the resulting pipeline are numbered so that filter 0 -is the filter closest to the format handler. -As a convenience, functions that expect a filter number will -accept -1 as a synonym for the highest-numbered filter. - -For example, when reading a uuencoded gzipped tar archive, there -are three filters: -filter 0 is the gunzip filter, -filter 1 is the uudecode filter, -and filter 2 is the pseudo-filter that wraps the archive read functions. -In this case, requesting -'''archive_position'''(''a'', ''-1'') -would be a synonym for -'''archive_position'''(''a'', ''2'') -which would return the number of bytes currently read from the archive, while -'''archive_position'''(''a'', ''1'') -would return the number of bytes after uudecoding, and -'''archive_position'''(''a'', ''0'') -would return the number of bytes after decompression. -
    '''archive_filter_name'''()
    -Returns a textual name identifying the indicated filter. -See -'''archive_filter_count'''() -for details of the numbering. -
    '''archive_format'''()
    -Returns a numeric code indicating the format of the current -archive entry. -This value is set by a successful call to -'''archive_read_next_header'''(). -Note that it is common for this value to change from -entry to entry. -For example, a tar archive might have several entries that -utilize GNU tar extensions and several entries that do not. -These entries will have different format codes. -
    '''archive_format_name'''()
    -A textual description of the format of the current entry. -
    '''archive_position'''()
    -Returns the number of bytes read from or written to the indicated filter. -In particular, -'''archive_position'''(''a'', ''0'') -returns the number of bytes read or written by the format handler, while -'''archive_position'''(''a'', ''-1'') -returns the number of bytes read or written to the archive. -See -'''archive_filter_count'''() -for details of the numbering here. -
    '''archive_set_error'''()
    -Sets the numeric error code and error description that will be returned -by -'''archive_errno'''() -and -'''archive_error_string'''(). -This function should be used within I/O callbacks to set system-specific -error codes and error descriptions. -This function accepts a printf-like format string and arguments. -However, you should be careful to use only the following printf -format specifiers: -"%c", -"%d", -"%jd", -"%jo", -"%ju", -"%jx", -"%ld", -"%lo", -"%lu", -"%lx", -"%o", -"%u", -"%s", -"%x", -"%%". -Field-width specifiers and other printf features are -not uniformly supported and should not be used. -
    -== SEE ALSO == -[[ManPageArchiveRead3]], -[[ManPageArchiveWrite3]], -[[ManPageLibarchive3]], -[[printf(3)|http://www.freebsd.org/cgi/man.cgi?query=printf&sektion=3]] -== HISTORY == -The -'''libarchive''' -library first appeared in -FreeBSD 5.3. -== AUTHORS == -The -'''libarchive''' -library was written by -Tim Kientzle <kientzle@acm.org.> diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveWrite3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveWrite3.wiki deleted file mode 100644 index efcd74a85..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveWrite3.wiki +++ /dev/null @@ -1,222 +0,0 @@ -ARCHIVE_WRITE(3) manual page -== NAME == -'''archive_write''' -- functions for creating archives -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -== DESCRIPTION == -These functions provide a complete API for creating streaming -archive files. -The general process is to first create the -'''struct archive''' -object, set any desired options, initialize the archive, append entries, then -close the archive and release all resources. -=== Create archive object=== -See -[[ManPageArchiveWriteNew3]]. - -To write an archive, you must first obtain an initialized -'''struct archive''' -object from -'''archive_write_new'''(). -=== Enable filters and formats, configure block size and padding=== -See -[[ManPageArchiveWriteFilter3]], -[[ManPageArchiveWriteFormat3]] -and -[[ManPageArchiveWriteBlocksize3]]. - -You can then modify this object for the desired operations with the -various -'''archive_write_set_XXX'''() -functions. -In particular, you will need to invoke appropriate -'''archive_write_add_XXX'''() -and -'''archive_write_set_XXX'''() -functions to enable the corresponding compression and format -support. -=== Set options=== -See -[[ManPageArchiveWriteSetOptions3]]. -=== Open archive=== -See -[[ManPageArchiveWriteOpen3]]. - -Once you have prepared the -'''struct archive''' -object, you call -'''archive_write_open'''() -to actually open the archive and prepare it for writing. -There are several variants of this function; -the most basic expects you to provide pointers to several -functions that can provide blocks of bytes from the archive. -There are convenience forms that allow you to -specify a filename, file descriptor, -''FILE *'' -object, or a block of memory from which to write the archive data. -=== Produce archive=== -See -[[ManPageArchiveWriteHeader3]] -and -[[ManPageArchiveWriteData3]]. - -Individual archive entries are written in a three-step -process: -You first initialize a -'''struct archive_entry''' -structure with information about the new entry. -At a minimum, you should set the pathname of the -entry and provide a -''struct'' stat -with a valid -''st_mode'' -field, which specifies the type of object and -''st_size'' -field, which specifies the size of the data portion of the object. -=== Release resources=== -See -[[ManPageArchiveWriteFree3]]. - -After all entries have been written, use the -'''archive_write_free'''() -function to release all resources. -== EXAMPLES == -The following sketch illustrates basic usage of the library. -In this example, -the callback functions are simply wrappers around the standard -[[open(2)|http://www.freebsd.org/cgi/man.cgi?query=open&sektion=2]], -[[write(2)|http://www.freebsd.org/cgi/man.cgi?query=write&sektion=2]], -and -[[close(2)|http://www.freebsd.org/cgi/man.cgi?query=close&sektion=2]] -system calls. -```text -#ifdef __linux__ -#define _FILE_OFFSET_BITS 64 -#endif -#include -#include -#include -#include -#include -#include -struct mydata { - const char *name; - int fd; -}; -int -myopen(struct archive *a, void *client_data) -{ - struct mydata *mydata = client_data; - mydata->fd = open(mydata->name, O_WRONLY | O_CREAT, 0644); - if (mydata->fd >= 0) - return (ARCHIVE_OK); - else - return (ARCHIVE_FATAL); -} -la_ssize_t -mywrite(struct archive *a, void *client_data, const void *buff, size_t n) -{ - struct mydata *mydata = client_data; - return (write(mydata->fd, buff, n)); -} -int -myclose(struct archive *a, void *client_data) -{ - struct mydata *mydata = client_data; - if (mydata->fd > 0) - close(mydata->fd); - return (0); -} -void -write_archive(const char *outname, const char **filename) -{ - struct mydata *mydata = malloc(sizeof(struct mydata)); - struct archive *a; - struct archive_entry *entry; - struct stat st; - char buff[8192]; - int len; - int fd; - a = archive_write_new(); - mydata->name = outname; - /* Set archive format and filter according to output file extension. - * If it fails, set default format. Platform depended function. - * See supported formats in archive_write_set_format_filter_by_ext.c */ - if (archive_write_set_format_filter_by_ext(a, outname) != ARCHIVE_OK) { - archive_write_add_filter_gzip(a); - archive_write_set_format_ustar(a); - } - archive_write_open(a, mydata, myopen, mywrite, myclose); - while (*filename) { - stat(*filename, &st); - entry = archive_entry_new(); - archive_entry_copy_stat(entry, &st); - archive_entry_set_pathname(entry, *filename); - archive_write_header(a, entry); - if ((fd = open(*filename, O_RDONLY)) != -1) { - len = read(fd, buff, sizeof(buff)); - while (len > 0) { - archive_write_data(a, buff, len); - len = read(fd, buff, sizeof(buff)); - } - close(fd); - } - archive_entry_free(entry); - filename++; - } - archive_write_free(a); -} -int main(int argc, const char **argv) -{ - const char *outname; - argv++; - outname = *argv++; - write_archive(outname, argv); - return 0; -} -``` -== SEE ALSO == -[[ManPageBsdtar1]], -[[ManPageArchiveWriteSetOptions3]], -[[ManPageLibarchive3]], -[[ManPageCpio5]], -[[ManPageMtree5]], -[[ManPageTar5]] -== HISTORY == -The -'''libarchive''' -library first appeared in -FreeBSD 5.3. -== AUTHORS == -The -'''libarchive''' -library was written by -Tim Kientzle <kientzle@acm.org.> -== BUGS == -There are many peculiar bugs in historic tar implementations that may cause -certain programs to reject archives written by this library. -For example, several historic implementations calculated header checksums -incorrectly and will thus reject valid archives; GNU tar does not fully support -pax interchange format; some old tar implementations required specific -field terminations. - -The default pax interchange format eliminates most of the historic -tar limitations and provides a generic key/value attribute facility -for vendor-defined extensions. -One oversight in POSIX is the failure to provide a standard attribute -for large device numbers. -This library uses -"SCHILY.devminor" -and -"SCHILY.devmajor" -for device numbers that exceed the range supported by the backwards-compatible -ustar header. -These keys are compatible with Joerg Schilling's -'''star''' -archiver. -Other implementations may not recognize these keys and will thus be unable -to correctly restore device nodes with large device numbers from archives -created by this library. diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteBlocksize3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteBlocksize3.wiki deleted file mode 100644 index eddc34c39..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteBlocksize3.wiki +++ /dev/null @@ -1,93 +0,0 @@ -ARCHIVE_WRITE_BLOCKSIZE(3) manual page -== NAME == -'''archive_write_get_bytes_per_block''', -'''archive_write_set_bytes_per_block''', -'''archive_write_get_bytes_in_last_block''', -'''archive_write_set_bytes_in_last_block''' -- functions for creating archives -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''int'' -
    -'''archive_write_get_bytes_per_block'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_set_bytes_per_block'''(''struct archive *'', ''int bytes_per_block''); -
    -''int'' -
    -'''archive_write_get_bytes_in_last_block'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_set_bytes_in_last_block'''(''struct archive *'', ''int''); -== DESCRIPTION == -
    -
    '''archive_write_set_bytes_per_block'''()
    -Sets the block size used for writing the archive data. -Every call to the write callback function, except possibly the last one, will -use this value for the length. -The default is to use a block size of 10240 bytes. -Note that a block size of zero will suppress internal blocking -and cause writes to be sent directly to the write callback as they occur. -
    '''archive_write_get_bytes_per_block'''()
    -Retrieve the block size to be used for writing. -A value of -1 here indicates that the library should use default values. -A value of zero indicates that internal blocking is suppressed. -
    '''archive_write_set_bytes_in_last_block'''()
    -Sets the block size used for writing the last block. -If this value is zero, the last block will be padded to the same size -as the other blocks. -Otherwise, the final block will be padded to a multiple of this size. -In particular, setting it to 1 will cause the final block to not be padded. -For compressed output, any padding generated by this option -is applied only after the compression. -The uncompressed data is always unpadded. -The default is to pad the last block to the full block size (note that -'''archive_write_open_filename'''() -will set this based on the file type). -Unlike the other -"set" -functions, this function can be called after the archive is opened. -
    '''archive_write_get_bytes_in_last_block'''()
    -Retrieve the currently-set value for last block size. -A value of -1 here indicates that the library should use default values. -
    -== RETURN VALUES == -'''archive_write_set_bytes_per_block'''() -and -'''archive_write_set_bytes_in_last_block'''() -return -'''ARCHIVE_OK''' -on success, or -'''ARCHIVE_FATAL'''. - -'''archive_write_get_bytes_per_block'''() -and -'''archive_write_get_bytes_in_last_block'''() -return currently configured block size -Po -```text --1 -``` -indicates the default block size -Pc, -or -'''ARCHIVE_FATAL'''. -== ERRORS == -Detailed error codes and textual descriptions are available from the -'''archive_errno'''() -and -'''archive_error_string'''() -functions. -== SEE ALSO == -[[ManPageBsdtar1]], -[[ManPageArchiveWriteSetOptions3]], -[[ManPageLibarchive3]], -[[ManPageCpio5]], -[[ManPageMtree5]], -[[ManPageTar5]] diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteData3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteData3.wiki deleted file mode 100644 index 31d4598e7..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteData3.wiki +++ /dev/null @@ -1,61 +0,0 @@ -ARCHIVE_WRITE_DATA(3) manual page -== NAME == -'''archive_write_data''', -'''archive_write_data_block''' -- functions for creating archives -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''la_ssize_t'' -
    -'''archive_write_data'''(''struct archive *'', ''const void *'', ''size_t''); -
    -''la_ssize_t'' -
    -'''archive_write_data_block'''(''struct archive *'', ''const void *'', ''size_t size'', ''int64_t offset''); -== DESCRIPTION == -
    -
    '''archive_write_data'''()
    -Write data corresponding to the header just written. -
    '''archive_write_data_block'''()
    -Write data corresponding to the header just written. -This is like -'''archive_write_data'''() -except that it performs a seek on the file being -written to the specified offset before writing the data. -This is useful when restoring sparse files from archive -formats that support sparse files. -Returns number of bytes written or -1 on error. -(Note: This is currently not supported for -'''archive_write''' -handles, only for -'''archive_write_disk''' -handles. -
    -== RETURN VALUES == -This function returns the number of bytes actually written, or -a negative error code on error. -== ERRORS == -Detailed error codes and textual descriptions are available from the -'''archive_errno'''() -and -'''archive_error_string'''() -functions. -== BUGS == -In libarchive 3.x, this function sometimes returns -zero on success instead of returning the number of bytes written. -Specifically, this occurs when writing to an -''archive_write_disk'' -handle. -Clients should treat any value less than zero as an error -and consider any non-negative value as success. -== SEE ALSO == -[[ManPageBsdtar1]], -[[ManPageArchiveWriteFinishEntry3]], -[[ManPageArchiveWriteSetOptions3]], -[[ManPageLibarchive3]], -[[ManPageCpio5]], -[[ManPageMtree5]], -[[ManPageTar5]] diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteDisk3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteDisk3.wiki deleted file mode 100644 index e208be755..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteDisk3.wiki +++ /dev/null @@ -1,335 +0,0 @@ -ARCHIVE_WRITE_DISK(3) manual page -== NAME == -'''archive_write_disk_new''', -'''archive_write_disk_set_options''', -'''archive_write_disk_set_skip_file''', -'''archive_write_disk_set_group_lookup''', -'''archive_write_disk_set_standard_lookup''', -'''archive_write_disk_set_user_lookup''' -- functions for creating objects on disk -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''struct archive *'' -
    -'''archive_write_disk_new'''(''void''); -
    -''int'' -
    -'''archive_write_disk_set_options'''(''struct archive *'', ''int flags''); -
    -''int'' -
    -'''archive_write_disk_set_skip_file'''(''struct archive *'', ''dev_t'', ''ino_t''); -
    -''int'' -
    -'''archive_write_disk_set_group_lookup'''(''struct archive *'', ''void *'', ''gid_t (*)(void *, const char *gname, gid_t gid)'', ''void (*cleanup)(void *)''); -
    -''int'' -
    -'''archive_write_disk_set_standard_lookup'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_disk_set_user_lookup'''(''struct archive *'', ''void *'', ''uid_t (*)(void *, const char *uname, uid_t uid)'', ''void (*cleanup)(void *)''); -== DESCRIPTION == -These functions provide a complete API for creating objects on -disk from -'''struct archive_entry''' -descriptions. -They are most naturally used when extracting objects from an archive -using the -'''archive_read'''() -interface. -The general process is to read -'''struct archive_entry''' -objects from an archive, then write those objects to a -'''struct archive''' -object created using the -'''archive_write_disk'''() -family functions. -This interface is deliberately very similar to the -'''archive_write'''() -interface used to write objects to a streaming archive. -
    -
    '''archive_write_disk_new'''()
    -Allocates and initializes a -'''struct archive''' -object suitable for writing objects to disk. -
    '''archive_write_disk_set_skip_file'''()
    -Records the device and inode numbers of a file that should not be -overwritten. -This is typically used to ensure that an extraction process does not -overwrite the archive from which objects are being read. -This capability is technically unnecessary but can be a significant -performance optimization in practice. -
    '''archive_write_disk_set_options'''()
    -The options field consists of a bitwise OR of one or more of the -following values: -
    -
    '''ARCHIVE_EXTRACT_ACL'''
    -Attempt to restore Access Control Lists. -By default, extended ACLs are ignored. -
    '''ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS'''
    -Before removing a file system object prior to replacing it, clear -platform-specific file flags which might prevent its removal. -
    '''ARCHIVE_EXTRACT_FFLAGS'''
    -Attempt to restore file attributes (file flags). -By default, file attributes are ignored. -See -[[chattr(1)|http://www.freebsd.org/cgi/man.cgi?query=chattr&sektion=1]] -(Linux) -or -[[chflags(1)|http://www.freebsd.org/cgi/man.cgi?query=chflags&sektion=1]] -(FreeBSD, Mac OS X) -for more information on file attributes. -
    '''ARCHIVE_EXTRACT_MAC_METADATA'''
    -Mac OS X specific. -Restore metadata using -[[copyfile(3)|http://www.freebsd.org/cgi/man.cgi?query=copyfile&sektion=3]]. -By default, -[[copyfile(3)|http://www.freebsd.org/cgi/man.cgi?query=copyfile&sektion=3]] -metadata is ignored. -
    '''ARCHIVE_EXTRACT_NO_OVERWRITE'''
    -Existing files on disk will not be overwritten. -By default, existing regular files are truncated and overwritten; -existing directories will have their permissions updated; -other pre-existing objects are unlinked and recreated from scratch. -
    '''ARCHIVE_EXTRACT_OWNER'''
    -The user and group IDs should be set on the restored file. -By default, the user and group IDs are not restored. -
    '''ARCHIVE_EXTRACT_PERM'''
    -Full permissions (including SGID, SUID, and sticky bits) should -be restored exactly as specified, without obeying the -current umask. -Note that SUID and SGID bits can only be restored if the -user and group ID of the object on disk are correct. -If -'''ARCHIVE_EXTRACT_OWNER''' -is not specified, then SUID and SGID bits will only be restored -if the default user and group IDs of newly-created objects on disk -happen to match those specified in the archive entry. -By default, only basic permissions are restored, and umask is obeyed. -
    '''ARCHIVE_EXTRACT_SAFE_WRITES'''
    -Extract files atomically, by first creating a unique temporary file and then -renaming it to its required destination name. -This avoids a race where an application might see a partial file (or no -file) during extraction. -
    '''ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS'''
    -Refuse to extract an absolute path. -The default is to not refuse such paths. -
    '''ARCHIVE_EXTRACT_SECURE_NODOTDOT'''
    -Refuse to extract a path that contains a -''..'' -element anywhere within it. -The default is to not refuse such paths. -Note that paths ending in -''..'' -always cause an error, regardless of this flag. -
    '''ARCHIVE_EXTRACT_SECURE_SYMLINKS'''
    -Refuse to extract any object whose final location would be altered -by a symlink on disk. -This is intended to help guard against a variety of mischief -caused by archives that (deliberately or otherwise) extract -files outside of the current directory. -The default is not to perform this check. -If -'''ARCHIVE_EXTRACT_UNLINK''' -is specified together with this option, the library will -remove any intermediate symlinks it finds and return an -error only if such symlink could not be removed. -
    '''ARCHIVE_EXTRACT_SPARSE'''
    -Scan data for blocks of NUL bytes and try to recreate them with holes. -This results in sparse files, independent of whether the archive format -supports or uses them. -
    '''ARCHIVE_EXTRACT_TIME'''
    -The timestamps (mtime, ctime, and atime) should be restored. -By default, they are ignored. -Note that restoring of atime is not currently supported. -
    '''ARCHIVE_EXTRACT_UNLINK'''
    -Existing files on disk will be unlinked before any attempt to -create them. -In some cases, this can prove to be a significant performance improvement. -By default, existing files are truncated and rewritten, but -the file is not recreated. -In particular, the default behavior does not break existing hard links. -
    '''ARCHIVE_EXTRACT_XATTR'''
    -Attempt to restore extended file attributes. -By default, they are ignored. -See -[[xattr(7)|http://www.freebsd.org/cgi/man.cgi?query=xattr&sektion=7]] -(Linux,) -[[xattr(2)|http://www.freebsd.org/cgi/man.cgi?query=xattr&sektion=2]] -(Mac OS X,) -or -[[getextattr(8)|http://www.freebsd.org/cgi/man.cgi?query=getextattr&sektion=8]] -(FreeBSD) -for more information on extended file attributes. -
    -
    -'''archive_write_disk_set_group_lookup'''(), -'''archive_write_disk_set_user_lookup'''() -
    -The -'''struct archive_entry''' -objects contain both names and ids that can be used to identify users -and groups. -These names and ids describe the ownership of the file itself and -also appear in ACL lists. -By default, the library uses the ids and ignores the names, but -this can be overridden by registering user and group lookup functions. -To register, you must provide a lookup function which -accepts both a name and id and returns a suitable id. -You may also provide a -'''void *''' -pointer to a private data structure and a cleanup function for -that data. -The cleanup function will be invoked when the -'''struct archive''' -object is destroyed. -
    '''archive_write_disk_set_standard_lookup'''()
    -This convenience function installs a standard set of user -and group lookup functions. -These functions use -[[getpwnam(3)|http://www.freebsd.org/cgi/man.cgi?query=getpwnam&sektion=3]] -and -[[getgrnam(3)|http://www.freebsd.org/cgi/man.cgi?query=getgrnam&sektion=3]] -to convert names to ids, defaulting to the ids if the names cannot -be looked up. -These functions also implement a simple memory cache to reduce -the number of calls to -[[getpwnam(3)|http://www.freebsd.org/cgi/man.cgi?query=getpwnam&sektion=3]] -and -[[getgrnam(3)|http://www.freebsd.org/cgi/man.cgi?query=getgrnam&sektion=3]]. -
    -More information about the -''struct'' archive -object and the overall design of the library can be found in the -[[ManPageLibarchive3]] -overview. -Many of these functions are also documented under -[[ManPageArchiveWrite3]]. -== RETURN VALUES == -Most functions return -'''ARCHIVE_OK''' -(zero) on success, or one of several non-zero -error codes for errors. -Specific error codes include: -'''ARCHIVE_RETRY''' -for operations that might succeed if retried, -'''ARCHIVE_WARN''' -for unusual conditions that do not prevent further operations, and -'''ARCHIVE_FATAL''' -for serious errors that make remaining operations impossible. - -'''archive_write_disk_new'''() -returns a pointer to a newly-allocated -'''struct archive''' -object. - -'''archive_write_data'''() -returns a count of the number of bytes actually written, -or -```text --1 -``` -on error. -== ERRORS == -Detailed error codes and textual descriptions are available from the -'''archive_errno'''() -and -'''archive_error_string'''() -functions. -== SEE ALSO == -[[ManPageBsdtar1]], -[[ManPageArchiveRead3]], -[[ManPageArchiveWrite3]], -[[ManPageLibarchive3]] -== HISTORY == -The -'''libarchive''' -library first appeared in -FreeBSD 5.3. -The -'''archive_write_disk''' -interface was added to -'''libarchive''' 2.0 -and first appeared in -FreeBSD 6.3. -== AUTHORS == -The -'''libarchive''' -library was written by -Tim Kientzle <kientzle@acm.org.> -== BUGS == -Directories are actually extracted in two distinct phases. -Directories are created during -'''archive_write_header'''(), -but final permissions are not set until -'''archive_write_close'''(). -This separation is necessary to correctly handle borderline -cases such as a non-writable directory containing -files, but can cause unexpected results. -In particular, directory permissions are not fully -restored until the archive is closed. -If you use -[[chdir(2)|http://www.freebsd.org/cgi/man.cgi?query=chdir&sektion=2]] -to change the current directory between calls to -'''archive_read_extract'''() -or before calling -'''archive_read_close'''(), -you may confuse the permission-setting logic with -the result that directory permissions are restored -incorrectly. - -The library attempts to create objects with filenames longer than -'''PATH_MAX''' -by creating prefixes of the full path and changing the current directory. -Currently, this logic is limited in scope; the fixup pass does -not work correctly for such objects and the symlink security check -option disables the support for very long pathnames. - -Restoring the path -''aa/../bb'' -does create each intermediate directory. -In particular, the directory -''aa'' -is created as well as the final object -''bb''. -In theory, this can be exploited to create an entire directory hierarchy -with a single request. -Of course, this does not work if the -'''ARCHIVE_EXTRACT_NODOTDOT''' -option is specified. - -Implicit directories are always created obeying the current umask. -Explicit objects are created obeying the current umask unless -'''ARCHIVE_EXTRACT_PERM''' -is specified, in which case they current umask is ignored. - -SGID and SUID bits are restored only if the correct user and -group could be set. -If -'''ARCHIVE_EXTRACT_OWNER''' -is not specified, then no attempt is made to set the ownership. -In this case, SGID and SUID bits are restored only if the -user and group of the final object happen to match those specified -in the entry. - -The -"standard" -user-id and group-id lookup functions are not the defaults because -[[getgrnam(3)|http://www.freebsd.org/cgi/man.cgi?query=getgrnam&sektion=3]] -and -[[getpwnam(3)|http://www.freebsd.org/cgi/man.cgi?query=getpwnam&sektion=3]] -are sometimes too large for particular applications. -The current design allows the application author to use a more -compact implementation when appropriate. - -There should be a corresponding -'''archive_read_disk''' -interface that walks a directory hierarchy and returns archive -entry objects. diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteFilter3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteFilter3.wiki deleted file mode 100644 index bf6cf3a70..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteFilter3.wiki +++ /dev/null @@ -1,134 +0,0 @@ -ARCHIVE_WRITE_FILTER(3) manual page -== NAME == -'''archive_write_add_filter_b64encode''', -'''archive_write_add_filter_by_name''', -'''archive_write_add_filter_bzip2''', -'''archive_write_add_filter_compress''', -'''archive_write_add_filter_grzip''', -'''archive_write_add_filter_gzip''', -'''archive_write_add_filter_lrzip''', -'''archive_write_add_filter_lz4''', -'''archive_write_add_filter_lzip''', -'''archive_write_add_filter_lzma''', -'''archive_write_add_filter_lzop''', -'''archive_write_add_filter_none''', -'''archive_write_add_filter_program''', -'''archive_write_add_filter_uuencode''', -'''archive_write_add_filter_xz''', -'''archive_write_add_filter_zstd''' -- functions enabling output filters -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''int'' -
    -'''archive_write_add_filter_b64encode'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_add_filter_bzip2'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_add_filter_compress'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_add_filter_grzip'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_add_filter_gzip'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_add_filter_lrzip'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_add_filter_lz4'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_add_filter_lzip'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_add_filter_lzma'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_add_filter_lzop'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_add_filter_none'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_add_filter_program'''(''struct archive *'', ''const char * cmd''); -
    -''int'' -
    -'''archive_write_add_filter_uuencode'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_add_filter_xz'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_add_filter_zstd'''(''struct archive *''); -== DESCRIPTION == -
    -
    -'''archive_write_add_filter_bzip2'''(), -'''archive_write_add_filter_compress'''(), -'''archive_write_add_filter_grzip'''(), -'''archive_write_add_filter_gzip'''(), -'''archive_write_add_filter_lrzip'''(), -'''archive_write_add_filter_lz4'''(), -'''archive_write_add_filter_lzip'''(), -'''archive_write_add_filter_lzma'''(), -'''archive_write_add_filter_lzop'''(), -'''archive_write_add_filter_xz'''(), -'''archive_write_add_filter_zstd'''(), -
    -The resulting archive will be compressed as specified. -Note that the compressed output is always properly blocked. -
    -'''archive_write_add_filter_b64encode'''(), -'''archive_write_add_filter_uuencode'''(), -
    -The output will be encoded as specified. -The encoded output is always properly blocked. -
    '''archive_write_add_filter_none'''()
    -This is never necessary. -It is provided only for backwards compatibility. -
    '''archive_write_add_filter_program'''()
    -The archive will be fed into the specified compression program. -The output of that program is blocked and written to the client -write callbacks. -
    -== RETURN VALUES == -These functions return -'''ARCHIVE_OK''' -on success, or -'''ARCHIVE_FATAL'''. -== ERRORS == -Detailed error codes and textual descriptions are available from the -'''archive_errno'''() -and -'''archive_error_string'''() -functions. -== SEE ALSO == -[[ManPageBsdtar1]], -[[ManPageArchiveWrite3]], -[[ManPageArchiveWriteFormat3]], -[[ManPageArchiveWriteSetOptions3]], -[[ManPageLibarchive3]], -[[ManPageCpio5]], -[[ManPageMtree5]], -[[ManPageTar5]] diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteFinishEntry3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteFinishEntry3.wiki deleted file mode 100644 index bf6e6a178..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteFinishEntry3.wiki +++ /dev/null @@ -1,50 +0,0 @@ -ARCHIVE_WRITE_FINISH_ENTRY(3) manual page -== NAME == -'''archive_write_finish_entry''' -- functions for creating archives -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''int'' -
    -'''archive_write_finish_entry'''(''struct archive *''); -== DESCRIPTION == -Close out the entry just written. -In particular, this writes out the final padding required by some formats. -Ordinarily, clients never need to call this, as it -is called automatically by -'''archive_write_header'''() -and -'''archive_write_close'''() -as needed. -For -'''archive_write_disk''' -handles, this flushes pending file attribute changes like modification time. -== RETURN VALUES == -This function returns -'''ARCHIVE_OK''' -on success, or one of several non-zero -error codes for errors. -Specific error codes include: -'''ARCHIVE_RETRY''' -for operations that might succeed if retried, -'''ARCHIVE_WARN''' -for unusual conditions that do not prevent further operations, and -'''ARCHIVE_FATAL''' -for serious errors that make remaining operations impossible. -== ERRORS == -Detailed error codes and textual descriptions are available from the -'''archive_errno'''() -and -'''archive_error_string'''() -functions. -== SEE ALSO == -[[ManPageBsdtar1]], -[[ManPageArchiveWriteData3]], -[[ManPageArchiveWriteSetOptions3]], -[[ManPageLibarchive3]], -[[ManPageCpio5]], -[[ManPageMtree5]], -[[ManPageTar5]] diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteFormat3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteFormat3.wiki deleted file mode 100644 index b5423b18c..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteFormat3.wiki +++ /dev/null @@ -1,208 +0,0 @@ -ARCHIVE_WRITE_FORMAT(3) manual page -== NAME == -'''archive_write_set_format''', -'''archive_write_set_format_7zip''', -'''archive_write_set_format_ar''', -'''archive_write_set_format_ar_bsd''', -'''archive_write_set_format_ar_svr4''', -'''archive_write_set_format_by_name''', -'''archive_write_set_format_cpio''', -'''archive_write_set_format_cpio_bin''', -'''archive_write_set_format_cpio_newc''', -'''archive_write_set_format_cpio_odc''', -'''archive_write_set_format_cpio_pwb''', -'''archive_write_set_format_filter_by_ext''', -'''archive_write_set_format_filter_by_ext_def''', -'''archive_write_set_format_gnutar''', -'''archive_write_set_format_iso9660''', -'''archive_write_set_format_mtree''', -'''archive_write_set_format_mtree_classic''', -'''archive_write_set_format_mtree_default''', -'''archive_write_set_format_pax''', -'''archive_write_set_format_pax_restricted''', -'''archive_write_set_format_raw''', -'''archive_write_set_format_shar''', -'''archive_write_set_format_shar_dump''', -'''archive_write_set_format_ustar''', -'''archive_write_set_format_v7tar''', -'''archive_write_set_format_warc''', -'''archive_write_set_format_xar''', -'''archive_write_set_format_zip''' -- functions for creating archives -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''int'' -
    -'''archive_write_set_format'''(''struct archive *'', ''int code''); -
    -''int'' -
    -'''archive_write_set_format_7zip'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_set_format_ar'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_set_format_ar_bsd'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_set_format_ar_svr4'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_set_format_by_name'''(''struct archive *'', ''const char *name''); -
    -''int'' -
    -'''archive_write_set_format_cpio'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_set_format_cpio_bin'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_set_format_cpio_newc'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_set_format_cpio_odc'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_set_format_cpio_pwb'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_set_format_filter_by_ext'''(''struct archive *'', ''const char *filename''); -
    -''int'' -
    -'''archive_write_set_format_filter_by_ext_def'''(''struct archive *'', ''const char *filename'', ''const char *def_ext''); -
    -''int'' -
    -'''archive_write_set_format_gnutar'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_set_format_iso9660'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_set_format_mtree'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_set_format_pax'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_set_format_pax_restricted'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_set_format_raw'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_set_format_shar'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_set_format_shar_dump'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_set_format_ustar'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_set_format_v7tar'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_set_format_warc'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_set_format_xar'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_set_format_zip'''(''struct archive *''); -== DESCRIPTION == -These functions set the format that will be used for the archive. - -The library can write a variety of common archive formats. -
    -
    '''archive_write_set_format'''()
    -Sets the format based on the format code (see -''archive.h'' -for the full list of format codes). -In particular, this can be used in conjunction with -'''archive_format'''() -to create a new archive with the same format as an existing archive. -
    '''archive_write_set_format_by_name'''()
    -Sets the corresponding format based on the common name. -
    -'''archive_write_set_format_filter_by_ext'''() -'''archive_write_set_format_filter_by_ext_def'''() -
    -Sets both filters and format based on the output filename. -Supported extensions: .7z, .zip, .jar, .cpio, .iso, .a, .ar, .tar, .tgz, .tar.gz, .tar.bz2, .tar.xz -
    -'''archive_write_set_format_7zip'''() -'''archive_write_set_format_ar_bsd'''() -'''archive_write_set_format_ar_svr4'''() -'''archive_write_set_format_cpio'''() -'''archive_write_set_format_cpio_bin'''() -'''archive_write_set_format_cpio_newc'''() -'''archive_write_set_format_cpio_odc'''() -'''archive_write_set_format_cpio_pwb'''() -'''archive_write_set_format_gnutar'''() -'''archive_write_set_format_iso9660'''() -'''archive_write_set_format_mtree'''() -'''archive_write_set_format_mtree_classic'''() -'''archive_write_set_format_pax'''() -'''archive_write_set_format_pax_restricted'''() -'''archive_write_set_format_raw'''() -'''archive_write_set_format_shar'''() -'''archive_write_set_format_shar_dump'''() -'''archive_write_set_format_ustar'''() -'''archive_write_set_format_v7tar'''() -'''archive_write_set_format_warc'''() -'''archive_write_set_format_xar'''() -'''archive_write_set_format_zip'''() -
    -Set the format as specified. -More details on the formats supported by libarchive can be found in the -[[ManPageLibarchiveFormats5]] -manual page. -
    -== RETURN VALUES == -These functions return -'''ARCHIVE_OK''' -on success, or -'''ARCHIVE_FATAL'''. -== ERRORS == -Detailed error codes and textual descriptions are available from the -'''archive_errno'''() -and -'''archive_error_string'''() -functions. -== SEE ALSO == -[[ManPageBsdtar1]], -[[ManPageArchiveWrite3]], -[[ManPageArchiveWriteSetOptions3]], -[[ManPageLibarchive3]], -[[ManPageCpio5]], -[[ManPageLibarchiveFormats5]], -[[ManPageMtree5]], -[[ManPageTar5]] diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteFree3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteFree3.wiki deleted file mode 100644 index 0e5c4bed1..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteFree3.wiki +++ /dev/null @@ -1,73 +0,0 @@ -ARCHIVE_WRITE_FREE(3) manual page -== NAME == -'''archive_write_fail''', -'''archive_write_close''', -'''archive_write_finish''', -'''archive_write_free''' -- functions for creating archives -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''int'' -
    -'''archive_write_fail'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_close'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_finish'''(''struct archive *''); -
    -''int'' -
    -'''archive_write_free'''(''struct archive *''); -== DESCRIPTION == -
    -
    '''archive_write_fail'''()
    -Always returns -'''ARCHIVE_FATAL'''. -This marks the archive object as being unusable; -after calling this function, the only call that can succeed is -'''archive_write_free'''() -to release the resources. -This can be used to speed recovery when the archive creation -must be aborted. -Note that the created archive is likely to be malformed in this case; -
    '''archive_write_close'''()
    -Complete the archive and invoke the close callback. -
    '''archive_write_finish'''()
    -This is a deprecated synonym for -'''archive_write_free'''(). -
    '''archive_write_free'''()
    -Invokes -'''archive_write_close'''() -if necessary, then releases all resources. -If you need detailed information about -'''archive_write_close'''() -failures, you should be careful to call it separately, as -you cannot obtain error information after -'''archive_write_free'''() -returns. -
    -== RETURN VALUES == -These functions return -'''ARCHIVE_OK''' -on success, or -'''ARCHIVE_FATAL'''. -== ERRORS == -Detailed error codes and textual descriptions are available from the -'''archive_errno'''() -and -'''archive_error_string'''() -functions. -== SEE ALSO == -[[ManPageBsdtar1]], -[[ManPageArchiveWriteSetOptions3]], -[[ManPageLibarchive3]], -[[ManPageCpio5]], -[[ManPageMtree5]], -[[ManPageTar5]] diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteHeader3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteHeader3.wiki deleted file mode 100644 index a2389cd18..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteHeader3.wiki +++ /dev/null @@ -1,44 +0,0 @@ -ARCHIVE_WRITE_HEADER(3) manual page -== NAME == -'''archive_write_header''' -- functions for creating archives -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''int'' -
    -'''archive_write_header'''(''struct archive *'', ''struct archive_entry *''); -== DESCRIPTION == -Build and write a header using the data in the provided -'''struct archive_entry''' -structure. -See -[[ManPageArchiveEntry3]] -for information on creating and populating -'''struct archive_entry''' -objects. -== RETURN VALUES == -This function returns -'''ARCHIVE_OK''' -on success, or one of the following on error: -'''ARCHIVE_RETRY''' -for operations that might succeed if retried, -'''ARCHIVE_WARN''' -for unusual conditions that do not prevent further operations, and -'''ARCHIVE_FATAL''' -for serious errors that make remaining operations impossible. -== ERRORS == -Detailed error codes and textual descriptions are available from the -'''archive_errno'''() -and -'''archive_error_string'''() -functions. -== SEE ALSO == -[[ManPageBsdtar1]], -[[ManPageArchiveWriteSetOptions3]], -[[ManPageLibarchive3]], -[[ManPageCpio5]], -[[ManPageMtree5]], -[[ManPageTar5]] diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteNew3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteNew3.wiki deleted file mode 100644 index da0d45b1c..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteNew3.wiki +++ /dev/null @@ -1,31 +0,0 @@ -ARCHIVE_WRITE_NEW(3) manual page -== NAME == -'''archive_write_new''' -- functions for creating archives -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''struct archive *'' -
    -'''archive_write_new'''(''void''); -== DESCRIPTION == -Allocates and initializes a -'''struct archive''' -object suitable for writing a tar archive. -NULL -is returned on error. - -A complete description of the -'''struct archive''' -object can be found in the overview manual page for -[[ManPageLibarchive3]]. -== SEE ALSO == -[[ManPageBsdtar1]], -[[ManPageArchiveWrite3]], -[[ManPageArchiveWriteSetOptions3]], -[[ManPageLibarchive3]], -[[ManPageCpio5]], -[[ManPageMtree5]], -[[ManPageTar5]] diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteOpen3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteOpen3.wiki deleted file mode 100644 index 092683cb1..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteOpen3.wiki +++ /dev/null @@ -1,229 +0,0 @@ -ARCHIVE_WRITE_OPEN(3) manual page -== NAME == -'''archive_write_open''', -'''archive_write_open2''', -'''archive_write_open_fd''', -'''archive_write_open_FILE''', -'''archive_write_open_filename''', -'''archive_write_open_memory''' -- functions for creating archives -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''int'' -
    -'''archive_write_open'''(''struct archive *'', ''void *client_data'', ''archive_open_callback *'', ''archive_write_callback *'', ''archive_close_callback *''); -
    -''int'' -
    -'''archive_write_open2'''(''struct archive *'', ''void *client_data'', ''archive_open_callback *'', ''archive_write_callback *'', ''archive_close_callback *'', ''archive_free_callback *''); -
    -''int'' -
    -'''archive_write_open_fd'''(''struct archive *'', ''int fd''); -
    -''int'' -
    -'''archive_write_open_FILE'''(''struct archive *'', ''FILE *file''); -
    -''int'' -
    -'''archive_write_open_filename'''(''struct archive *'', ''const char *filename''); -
    -''int'' -
    -'''archive_write_open_memory'''(''struct archive *'', ''void *buffer'', ''size_t bufferSize'', ''size_t *outUsed''); -== DESCRIPTION == -
    -
    '''archive_write_open'''()
    -Freeze the settings, open the archive, and prepare for writing entries. -This is the most generic form of this function, which accepts -pointers to three callback functions which will be invoked by -the compression layer to write the constructed archive. -This does not alter the default archive padding. -
    '''archive_write_open2'''()
    -Same as -'''archive_write_open'''() -with an additional fourth free callback. This function should be preferred to -'''archive_write_open'''(). -
    '''archive_write_open_fd'''()
    -A convenience form of -'''archive_write_open'''() -that accepts a file descriptor. -The -'''archive_write_open_fd'''() -function is safe for use with tape drives or other -block-oriented devices. -
    '''archive_write_open_FILE'''()
    -A convenience form of -'''archive_write_open'''() -that accepts a -''FILE *'' -pointer. -Note that -'''archive_write_open_FILE'''() -is not safe for writing to tape drives or other devices -that require correct blocking. -
    '''archive_write_open_file'''()
    -A deprecated synonym for -'''archive_write_open_filename'''(). -
    '''archive_write_open_filename'''()
    -A convenience form of -'''archive_write_open'''() -that accepts a filename. -A NULL argument indicates that the output should be written to standard output; -an argument of -"-" -will open a file with that name. -If you have not invoked -'''archive_write_set_bytes_in_last_block'''(), -then -'''archive_write_open_filename'''() -will adjust the last-block padding depending on the file: -it will enable padding when writing to standard output or -to a character or block device node, it will disable padding otherwise. -You can override this by manually invoking -'''archive_write_set_bytes_in_last_block'''() -before calling -'''archive_write_open2'''(). -The -'''archive_write_open_filename'''() -function is safe for use with tape drives or other -block-oriented devices. -
    '''archive_write_open_memory'''()
    -A convenience form of -'''archive_write_open2'''() -that accepts a pointer to a block of memory that will receive -the archive. -The final -''size_t *'' -argument points to a variable that will be updated -after each write to reflect how much of the buffer -is currently in use. -You should be careful to ensure that this variable -remains allocated until after the archive is -closed. -This function will disable padding unless you -have specifically set the block size. -
    -More information about the -''struct'' archive -object and the overall design of the library can be found in the -[[ManPageLibarchive3]] -overview. - -Note that the convenience forms above vary in how -they block the output. -See -[[ManPageArchiveWriteBlocksize3]] -if you need to control the block size used for writes -or the end-of-file padding behavior. -== CLIENT CALLBACKS == -To use this library, you will need to define and register -callback functions that will be invoked to write data to the -resulting archive. -These functions are registered by calling -'''archive_write_open2'''(): -
      -
    • -''typedef int'' -'''archive_open_callback'''(''struct archive *'', ''void *client_data'') -
    - -The open callback is invoked by -'''archive_write_open'''(). -It should return -'''ARCHIVE_OK''' -if the underlying file or data source is successfully -opened. -If the open fails, it should call -'''archive_set_error'''() -to register an error code and message and return -'''ARCHIVE_FATAL'''. -Please note that if open fails, close is not called and resources must be -freed inside the open callback or with the free callback. -
      -
    • -''typedef la_ssize_t'' -'''archive_write_callback'''(''struct archive *'', ''void *client_data'', ''const void *buffer'', ''size_t length'') -
    - -The write callback is invoked whenever the library -needs to write raw bytes to the archive. -For correct blocking, each call to the write callback function -should translate into a single -[[write(2)|http://www.freebsd.org/cgi/man.cgi?query=write&sektion=2]] -system call. -This is especially critical when writing archives to tape drives. -On success, the write callback should return the -number of bytes actually written. -On error, the callback should invoke -'''archive_set_error'''() -to register an error code and message and return -1. -
      -
    • -''typedef int'' -'''archive_close_callback'''(''struct archive *'', ''void *client_data'') -
    - -The close callback is invoked by archive_close when -the archive processing is complete. If the open callback fails, the close -callback is not invoked. -The callback should return -'''ARCHIVE_OK''' -on success. -On failure, the callback should invoke -'''archive_set_error'''() -to register an error code and message and -return -'''ARCHIVE_FATAL'''. -
      -
    • -''typedef int'' -'''archive_free_callback'''(''struct archive *'', ''void *client_data'') -
    - -The free callback is always invoked on archive_free. -The return code of this callback is not processed. - -Note that if the client-provided write callback function -returns a non-zero value, that error will be propagated back to the caller -through whatever API function resulted in that call, which -may include -'''archive_write_header'''(), -'''archive_write_data'''(), -'''archive_write_close'''(), -'''archive_write_finish'''(), -or -'''archive_write_free'''(). -The client callback can call -'''archive_set_error'''() -to provide values that can then be retrieved by -'''archive_errno'''() -and -'''archive_error_string'''(). -== RETURN VALUES == -These functions return -'''ARCHIVE_OK''' -on success, or -'''ARCHIVE_FATAL'''. -== ERRORS == -Detailed error codes and textual descriptions are available from the -'''archive_errno'''() -and -'''archive_error_string'''() -functions. -== SEE ALSO == -[[ManPageBsdtar1]], -[[ManPageArchiveWrite3]], -[[ManPageArchiveWriteBlocksize3]], -[[ManPageArchiveWriteFilter3]], -[[ManPageArchiveWriteFormat3]], -[[ManPageArchiveWriteNew3]], -[[ManPageArchiveWriteSetOptions3]], -[[ManPageLibarchive3]], -[[ManPageCpio5]], -[[ManPageMtree5]], -[[ManPageTar5]] diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteSetOptions3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteSetOptions3.wiki deleted file mode 100644 index d67c3d0f8..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteSetOptions3.wiki +++ /dev/null @@ -1,685 +0,0 @@ -ARCHIVE_WRITE_OPTIONS(3) manual page -== NAME == -'''archive_write_set_filter_option''', -'''archive_write_set_format_option''', -'''archive_write_set_option''', -'''archive_write_set_options''' -- functions controlling options for writing archives -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -
    -''int'' -
    -'''archive_write_set_filter_option'''(''struct archive *'', ''const char *module'', ''const char *option'', ''const char *value''); -
    -''int'' -
    -'''archive_write_set_format_option'''(''struct archive *'', ''const char *module'', ''const char *option'', ''const char *value''); -
    -''int'' -
    -'''archive_write_set_option'''(''struct archive *'', ''const char *module'', ''const char *option'', ''const char *value''); -
    -''int'' -
    -'''archive_write_set_options'''(''struct archive *'', ''const char *options''); -== DESCRIPTION == -These functions provide a way for libarchive clients to configure -specific write modules. -
    -
    -'''archive_write_set_filter_option'''(), -'''archive_write_set_format_option'''() -
    -Specifies an option that will be passed to the currently-registered -filters (including decompression filters) or format readers. - -If -''option'' -and -''value'' -are both -NULL, -these functions will do nothing and -'''ARCHIVE_OK''' -will be returned. -If -''option'' -is -NULL -but -''value'' -is not, these functions will do nothing and -'''ARCHIVE_FAILED''' -will be returned. - -If -''module'' -is not -NULL, -''option'' -and -''value'' -will be provided to the filter or reader named -''module''. -The return value will be either -'''ARCHIVE_OK''' -if the option was successfully handled or -'''ARCHIVE_WARN''' -if the option was unrecognized by the module or could otherwise -not be handled. -If there is no such module, -'''ARCHIVE_FAILED''' -will be returned. - -If -''module'' -is -NULL, -''option'' -and -''value'' -will be provided to every registered module. -If any module returns -'''ARCHIVE_FATAL''', -this value will be returned immediately. -Otherwise, -'''ARCHIVE_OK''' -will be returned if any module accepts the option, and -'''ARCHIVE_FAILED''' -in all other cases. -
    '''archive_write_set_option'''()
    -Calls -'''archive_write_set_format_option'''(), -then -'''archive_write_set_filter_option'''(). -If either function returns -'''ARCHIVE_FATAL''', -'''ARCHIVE_FATAL''' -will be returned -immediately. -Otherwise, the greater of the two values will be returned. -
    '''archive_write_set_options'''()
    -''options'' -is a comma-separated list of options. -If -''options'' -is -NULL -or empty, -'''ARCHIVE_OK''' -will be returned immediately. - -Individual options have one of the following forms: -
    -
    ''option=value''
    -The option/value pair will be provided to every module. -Modules that do not accept an option with this name will ignore it. -
    ''option''
    -The option will be provided to every module with a value of -"1". -
    ''!option''
    -The option will be provided to every module with a NULL value. -
    ''module:option=value'', ''module:option'', ''module:!option''
    -As above, but the corresponding option and value will be provided -only to modules whose name matches -''module''. -
    -
    -== OPTIONS == -
    -
    Filter b64encode
    -
    -
    '''mode'''
    -The value is interpreted as octal digits specifying the file mode. -
    '''name'''
    -The value specifies the file name. -
    -
    Filter bzip2
    -
    -
    '''compression-level'''
    -The value is interpreted as a decimal integer specifying the -bzip2 compression level. Supported values are from 1 to 9. -
    -
    Filter gzip
    -
    -
    '''compression-level'''
    -The value is interpreted as a decimal integer specifying the -gzip compression level. Supported values are from 0 to 9. -
    '''timestamp'''
    -Store timestamp. This is enabled by default. -
    -
    Filter lrzip
    -
    -
    '''compression'''=''type''
    -Use -''type'' -as compression method. -Supported values are -"bzip2", -"gzipi", -"lzo" -(ultra fast,) -and -"zpaq" -(best, extremely slow.) -
    '''compression-level'''
    -The value is interpreted as a decimal integer specifying the -lrzip compression level. Supported values are from 1 to 9. -
    -
    Filter lz4
    -
    -
    '''compression-level'''
    -The value is interpreted as a decimal integer specifying the -lz4 compression level. Supported values are from 0 to 9. -
    '''stream-checksum'''
    -Enable stream checksum. This is enabled by default. -
    '''block-checksum'''
    -Enable block checksum. This is disabled by default. -
    '''block-size'''
    -The value is interpreted as a decimal integer specifying the -lz4 compression block size. Supported values are from 4 to 7 -(default.) -
    '''block-dependence'''
    -Use the previous block of the block being compressed for -a compression dictionary to improve compression ratio. -This is disabled by default. -
    -
    Filter lzop
    -
    -
    '''compression-level'''
    -The value is interpreted as a decimal integer specifying the -lzop compression level. Supported values are from 1 to 9. -
    -
    Filter uuencode
    -
    -
    '''mode'''
    -The value is interpreted as octal digits specifying the file mode. -
    '''name'''
    -The value specifies the file name. -
    -
    Filter xz
    -
    -
    '''compression-level'''
    -The value is interpreted as a decimal integer specifying the -compression level. Supported values are from 0 to 9. -
    '''threads'''
    -The value is interpreted as a decimal integer specifying the -number of threads for multi-threaded lzma compression. -If supported, the default value is read from -'''lzma_cputhreads'''(). -
    -
    Filter zstd
    -
    -
    '''compression-level'''
    -The value is interpreted as a decimal integer specifying the -compression level. Supported values depend on the library version, -common values are from 1 to 22. -
    '''long'''
    -Enables long distance matching. The value is interpreted as a -decimal integer specifying log2 window size in bytes. Values from -10 to 30 for 32 bit, or 31 for 64 bit, are supported. -
    '''threads'''
    -The value is interpreted as a decimal integer specifying the -number of threads for multi-threaded zstd compression. -If set to 0, zstd will attempt to detect and use the number -of physical CPU cores. -
    -
    Format 7zip
    -
    -
    '''compression'''
    -The value is one of -"store", -"deflate", -"bzip2", -"lzma1", -"lzma2" -or -"ppmd" -to indicate how the following entries should be compressed. -Note that this setting is ignored for directories, symbolic links, -and other special entries. -
    '''compression-level'''
    -The value is interpreted as a decimal integer specifying the -compression level. -Values between 0 and 9 are supported. -The interpretation of the compression level depends on the chosen -compression method. -
    -
    Format bin
    -
    -
    '''hdrcharset'''
    -The value is used as a character set name that will be -used when translating file names. -
    -
    Format gnutar
    -
    -
    '''hdrcharset'''
    -The value is used as a character set name that will be -used when translating file, group and user names. -
    -
    Format iso9660 - volume metadata
    -These options are used to set standard ISO9660 metadata. -
    -
    '''abstract-file'''=''filename''
    -The file with the specified name will be identified in the ISO9660 metadata -as holding the abstract for this volume. -Default: none. -
    '''application-id'''=''filename''
    -The file with the specified name will be identified in the ISO9660 metadata -as holding the application identifier for this volume. -Default: none. -
    '''biblio-file'''=''filename''
    -The file with the specified name will be identified in the ISO9660 metadata -as holding the bibliography for this volume. -Default: none. -
    '''copyright-file'''=''filename''
    -The file with the specified name will be identified in the ISO9660 metadata -as holding the copyright for this volume. -Default: none. -
    '''publisher'''=''filename''
    -The file with the specified name will be identified in the ISO9660 metadata -as holding the publisher information for this volume. -Default: none. -
    '''volume-id'''=''string''
    -The specified string will be used as the Volume Identifier in the ISO9660 metadata. -It is limited to 32 bytes. -Default: none. -
    -
    Format iso9660 - boot support
    -These options are used to make an ISO9660 image that can be directly -booted on various systems. -
    -
    '''boot'''=''filename''
    -The file matching this name will be used as the El Torito boot image file. -
    '''boot-catalog'''=''name''
    -The name that will be used for the El Torito boot catalog. -Default: -''boot.catalog'' -
    '''boot-info-table'''
    -The boot image file provided by the -'''boot'''=''filename'' -option will be edited with appropriate boot information in bytes 8 through 64. -Default: disabled -
    '''boot-load-seg'''=''hexadecimal-number''
    -The load segment for a no-emulation boot image. -
    '''boot-load-size'''=''decimal-number''
    -The number of "virtual" 512-byte sectors to be loaded from a no-emulation boot image. -Some very old BIOSes can only load very small images, setting this -value to 4 will often allow such BIOSes to load the first part of -the boot image (which will then need to be intelligent enough to -load the rest of itself). -This should not be needed unless you are trying to support systems with very old BIOSes. -This defaults to the full size of the image. -
    '''boot-type'''=''value''
    -Specifies the boot semantics used by the El Torito boot image: -If the -''value'' -is -'''fd''', -then the boot image is assumed to be a bootable floppy image. -If the -''value'' -is -'''hd''', -then the boot image is assumed to be a bootable hard disk image. -If the -''value'' -is -'''no-emulation''', -the boot image is used without floppy or hard disk emulation. -If the boot image is exactly 1.2MB, 1.44MB, or 2.88MB, then -the default is -'''fd''', -otherwise the default is -'''no-emulation'''. -
    -
    Format iso9660 - filename and size extensions
    -Various extensions to the base ISO9660 format. -
    -
    '''allow-ldots'''
    -If enabled, allows filenames to begin with a leading period. -If disabled, filenames that begin with a leading period will have -that period replaced by an underscore character in the standard ISO9660 -namespace. -This does not impact names stored in the Rockridge or Joliet extension area. -Default: disabled. -
    '''allow-lowercase'''
    -If enabled, allows filenames to contain lowercase characters. -If disabled, filenames will be forced to uppercase. -This does not impact names stored in the Rockridge or Joliet extension area. -Default: disabled. -
    '''allow-multidot'''
    -If enabled, allows filenames to contain multiple period characters, in violation of the ISO9660 specification. -If disabled, additional periods will be converted to underscore characters. -This does not impact names stored in the Rockridge or Joliet extension area. -Default: disabled. -
    '''allow-period'''
    -If enabled, allows filenames to contain trailing period characters, in violation of the ISO9660 specification. -If disabled, trailing periods will be converted to underscore characters. -This does not impact names stored in the Rockridge or Joliet extension area. -Default: disabled. -
    '''allow-pvd-lowercase'''
    -If enabled, the Primary Volume Descriptor may contain lowercase ASCII characters, in violation of the ISO9660 specification. -If disabled, characters will be converted to uppercase ASCII. -Default: disabled. -
    '''allow-sharp-tilde'''
    -If enabled, sharp and tilde characters will be permitted in filenames, in violation if the ISO9660 specification. -If disabled, such characters will be converted to underscore characters. -Default: disabled. -
    '''allow-vernum'''
    -If enabled, version numbers will be included with files. -If disabled, version numbers will be suppressed, in violation of the ISO9660 standard. -This does not impact names stored in the Rockridge or Joliet extension area. -Default: enabled. -
    '''iso-level'''
    -This enables support for file size and file name extensions in the -core ISO9660 area. -The name extensions specified here do not affect the names stored in the Rockridge or Joliet extension areas. -
    -
    '''iso-level=1'''
    -The most compliant form of ISO9660 image. -Filenames are limited to 8.3 uppercase format, -directory names are limited to 8 uppercase characters, -files are limited to 4 GiB, -the complete ISO9660 image cannot exceed 4 GiB. -
    '''iso-level=2'''
    -Filenames are limited to 30 uppercase characters with a 30-character extension, -directory names are limited to 30 characters, -files are limited to 4 GiB. -
    '''iso-level=3'''
    -As with -'''iso-level=2''', -except that files may exceed 4 GiB. -
    '''iso-level=4'''
    -As with -'''iso-level=3''', -except that filenames may be up to 193 characters -and may include arbitrary 8-bit characters. -
    -
    '''joliet'''
    -Microsoft's Joliet extensions store a completely separate set of directory information about each file. -In particular, this information includes Unicode filenames of up to 255 characters. -Default: enabled. -
    '''limit-depth'''
    -If enabled, libarchive will use directory relocation records to ensure that -no pathname exceeds the ISO9660 limit of 8 directory levels. -If disabled, no relocation will occur. -Default: enabled. -
    '''limit-dirs'''
    -If enabled, libarchive will cause an error if there are more than -65536 directories. -If disabled, there is no limit on the number of directories. -Default: enabled -
    '''pad'''
    -If enabled, 300 kiB of zero bytes will be appended to the end of the archive. -Default: enabled -
    '''relaxed-filenames'''
    -If enabled, all 7-bit ASCII characters are permitted in filenames -(except lowercase characters unless -'''allow-lowercase''' -is also specified). -This violates ISO9660 standards. -This does not impact names stored in the Rockridge or Joliet extension area. -Default: disabled. -
    '''rockridge'''
    -The Rockridge extensions store an additional set of POSIX-style file -information with each file, including mtime, atime, ctime, permissions, -and long filenames with arbitrary 8-bit characters. -These extensions also support symbolic links and other POSIX file types. -Default: enabled. -
    -
    Format iso9660 - zisofs support
    -The zisofs extensions permit each file to be independently compressed -using a gzip-compatible compression. -This can provide significant size savings, but requires the reading -system to have support for these extensions. -These extensions are disabled by default. -
    -
    '''compression-level'''=number
    -The compression level used by the deflate compressor. -Ranges from 0 (least effort) to 9 (most effort). -Default: 6 -
    '''zisofs'''
    -Synonym for -'''zisofs=direct'''. -
    '''zisofs=direct'''
    -Compress each file in the archive. -Unlike -'''zisofs=indirect''', -this is handled entirely within libarchive and does not require a -separate utility. -For best results, libarchive tests each file and will store -the file uncompressed if the compression does not actually save any space. -In particular, files under 2k will never be compressed. -Note that boot image files are never compressed. -
    '''zisofs=indirect'''
    -Recognizes files that have already been compressed with the -'''mkzftree''' -utility and sets up the necessary file metadata so that -readers will correctly identify these as zisofs-compressed files. -
    '''zisofs-exclude'''=''filename''
    -Specifies a filename that should not be compressed when using -'''zisofs=direct'''. -This option can be provided multiple times to suppress compression -on many files. -
    -
    Format mtree
    -
    -
    '''cksum''', '''device''', '''flags''', '''gid''', '''gname''', '''indent''', '''link''', '''md5''', '''mode''', '''nlink''', '''rmd160''', '''sha1''', '''sha256''', '''sha384''', '''sha512''', '''size''', '''time''', '''uid''', '''uname'''
    -Enable a particular keyword in the mtree output. -Prefix with an exclamation mark to disable the corresponding keyword. -The default is equivalent to -"device, flags, gid, gname, link, mode, nlink, size, time, type, uid, uname". -
    '''all'''
    -Enables all of the above keywords. -
    '''use-set'''
    -Enables generation of -'''/set''' -lines that specify default values for the following files and/or directories. -
    '''indent'''
    -XXX needs explanation XXX -
    -
    Format newc
    -
    -
    '''hdrcharset'''
    -The value is used as a character set name that will be -used when translating file names. -
    -
    Format odc
    -
    -
    '''hdrcharset'''
    -The value is used as a character set name that will be -used when translating file names. -
    -
    Format pwb
    -
    -
    '''hdrcharset'''
    -The value is used as a character set name that will be -used when translating file names. -
    -
    Format pax
    -
    -
    '''hdrcharset'''
    -The value is used as a character set name that will be -used when translating file, group and user names. -The value is one of -"BINARY" -or -"UTF-8". -With -"BINARY" -there is no character conversion, with -"UTF-8" -names are converted to UTF-8. -
    '''xattrheader'''
    -When storing extended attributes, this option configures which -headers should be written. The value is one of -"all", -"LIBARCHIVE", -or -"SCHILY". -By default, both -"LIBARCHIVE.xattr" -and -"SCHILY.xattr" -headers are written. -
    -
    Format ustar
    -
    -
    '''hdrcharset'''
    -The value is used as a character set name that will be -used when translating file, group and user names. -
    -
    Format v7tar
    -
    -
    '''hdrcharset'''
    -The value is used as a character set name that will be -used when translating file, group and user names. -
    -
    Format warc
    -
    -
    '''omit-warcinfo'''
    -Set to -"true" -to disable output of the warcinfo record. -
    -
    Format xar
    -
    -
    '''checksum'''=''type''
    -Use -''type'' -as file checksum method. -Supported values are -"none", -"md5", -and -"sha1" -(default.) -
    '''compression'''=''type''
    -Use -''type'' -as compression method. -Supported values are -"none", -"bzip2", -"gzip" -(default,) -"lzma" -and -"xz". -
    '''compression_level'''
    -The value is a decimal integer from 1 to 9 specifying the compression level. -
    '''toc-checksum'''=''type''
    -Use -''type'' -as table of contents checksum method. -Supported values are -"none", -"md5" -and -"sha1" -(default.) -
    -
    Format zip
    -
    -
    '''compression'''
    -The value is either -"store" -or -"deflate" -to indicate how the following entries should be compressed. -Note that this setting is ignored for directories, symbolic links, -and other special entries. -
    '''compression-level'''
    -The value is interpreted as a decimal integer specifying the -compression level. -Values between 0 and 9 are supported. -A compression level of 0 switches the compression method to -"store", -other values will enable -"deflate" -compression with the given level. -
    '''encryption'''
    -Enable encryption using traditional zip encryption. -
    '''encryption'''=''type''
    -Use -''type'' -as encryption type. -Supported values are -"zipcrypt" -(traditional zip encryption,) -"aes128" -(WinZip AES-128 encryption) -and -"aes256" -(WinZip AES-256 encryption.) -
    '''experimental'''
    -This boolean option enables or disables experimental Zip features -that may not be compatible with other Zip implementations. -
    '''fakecrc32'''
    -This boolean option disables CRC calculations. -All CRC fields are set to zero. -It should not be used except for testing purposes. -
    '''hdrcharset'''
    -The value is used as a character set name that will be -used when translating file names. -
    '''zip64'''
    -Zip64 extensions provide additional file size information -for entries larger than 4 GiB. -They also provide extended file offset and archive size information -when archives exceed 4 GiB. -By default, the Zip writer selectively enables these extensions only as needed. -In particular, if the file size is unknown, the Zip writer will -include Zip64 extensions to guard against the possibility that the -file might be larger than 4 GiB. - -Setting this boolean option will force the writer to use Zip64 extensions -even for small files that would not otherwise require them. -This is primarily useful for testing. - -Disabling this option with -'''!zip64''' -will force the Zip writer to avoid Zip64 extensions: -It will reject files with size greater than 4 GiB, -it will reject any new entries once the total archive size reaches 4 GiB, -and it will not use Zip64 extensions for files with unknown size. -In particular, this can improve compatibility when generating archives -where the entry sizes are not known in advance. -
    -
    -== EXAMPLES == -The following example creates an archive write handle to -create a gzip-compressed ISO9660 format image. -The two options here specify that the ISO9660 archive will use -''kernel.img'' -as the boot image for El Torito booting, and that the gzip -compressor should use the maximum compression level. -```text -a = archive_write_new(); -archive_write_add_filter_gzip(a); -archive_write_set_format_iso9660(a); -archive_write_set_options(a, "boot=kernel.img,compression=9"); -archive_write_open_filename(a, filename, blocksize); -``` -== ERRORS == -More detailed error codes and textual descriptions are available from the -'''archive_errno'''() -and -'''archive_error_string'''() -functions. -== SEE ALSO == -[[ManPageBsdtar1]], -[[ManPageArchiveReadSetOptions3]], -[[ManPageArchiveWrite3]], -[[ManPageLibarchive3]] -== HISTORY == -The -'''libarchive''' -library first appeared in -FreeBSD 5.3. -== AUTHORS == -The options support for libarchive was originally implemented by -Michihiro NAKAJIMA. -== BUGS == diff --git a/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteSetPassphrase3.wiki b/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteSetPassphrase3.wiki deleted file mode 100644 index fea416ea5..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageArchiveWriteSetPassphrase3.wiki +++ /dev/null @@ -1,42 +0,0 @@ -ARCHIVE_WRITE_SET_PASSPHRASE(3) manual page -== NAME == -'''archive_write_set_passphrase''', -'''archive_write_set_passphrase_callback''' -- functions for writing encrypted archives -== LIBRARY == -Streaming Archive Library (libarchive, -larchive) -== SYNOPSIS == -'''#include ''' -
    -''int'' -
    -'''archive_write_set_passphrase'''(''struct archive *'', ''const char *passphrase''); -
    -''int'' -
    -'''archive_write_set_passphrase_callback'''(''struct archive *'', ''void *client_data'', ''archive_passphrase_callback *''); -== DESCRIPTION == -
    -
    '''archive_write_set_passphrase'''()
    -Set a passphrase for writing an encrypted archive. -If -''passphrase'' -is -NULL -or empty, this function will do nothing and -'''ARCHIVE_FAILED''' -will be returned. -Otherwise, -'''ARCHIVE_OK''' -will be returned. -
    '''archive_write_set_passphrase_callback'''()
    -Register a callback function that will be invoked to get a passphrase -for encryption if the passphrase was not set by the -'''archive_write_set_passphrase'''() -function. -
    -== SEE ALSO == -[[ManPageBsdtar1]], -[[ManPageArchiveWrite3]], -[[ManPageArchiveWriteSetOptions3]], -[[ManPageLibarchive3]] diff --git a/thirdparty/libarchive/doc/wiki/ManPageBsdcpio1.wiki b/thirdparty/libarchive/doc/wiki/ManPageBsdcpio1.wiki deleted file mode 100644 index fc7647ed5..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageBsdcpio1.wiki +++ /dev/null @@ -1,423 +0,0 @@ -CPIO(1) manual page -== NAME == -'''cpio''' -- copy files to and from archives -== SYNOPSIS == -
    -'''cpio''' --i -[''options''] -[''pattern'' ...] -[''<'' archive] -
    -'''cpio''' --o -[''options''] -''<'' name-list -[''>'' archive] -
    -'''cpio''' --p -[''options''] -''dest-dir'' -''<'' name-list -== DESCRIPTION == -'''cpio''' -copies files between archives and directories. -This implementation can extract from tar, pax, cpio, zip, jar, ar, -and ISO 9660 cdrom images and can create tar, pax, cpio, ar, -and shar archives. - -The first option to -'''cpio''' -is a mode indicator from the following list: -
    -
    -i
    -Input. -Read an archive from standard input (unless overridden) and extract the -contents to disk or (if the --t -option is specified) -list the contents to standard output. -If one or more file patterns are specified, only files matching -one of the patterns will be extracted. -
    -o
    -Output. -Read a list of filenames from standard input and produce a new archive -on standard output (unless overridden) containing the specified items. -
    -p
    -Pass-through. -Read a list of filenames from standard input and copy the files to the -specified directory. -
    -== OPTIONS == -Unless specifically stated otherwise, options are applicable in -all operating modes. -
    -
    -0, --null
    -Read filenames separated by NUL characters instead of newlines. -This is necessary if any of the filenames being read might contain newlines. -
    -6, --pwb
    -When reading a binary format archive, assume it's the earlier one, -from the PWB variant of 6th Edition UNIX. -When writing a cpio archive, use the PWB format. -
    -7, --binary
    -(o mode only) -When writing a cpio archive, use the (newer, non-PWB) binary format. -
    -A
    -(o mode only) -Append to the specified archive. -(Not yet implemented.) -
    -a
    -(o and p modes) -Reset access times on files after they are read. -
    -B
    -(o mode only) -Block output to records of 5120 bytes. -
    -C ''size''
    -(o mode only) -Block output to records of -''size'' -bytes. -
    -c
    -(o mode only) -Use the old POSIX portable character format. -Equivalent to ---format ''odc''. -
    -d, --make-directories
    -(i and p modes) -Create directories as necessary. -
    -E ''file''
    -(i mode only) -Read list of file name patterns from -''file'' -to list and extract. -
    -F ''file'', --file ''file''
    -Read archive from or write archive to -''file''. -
    -f ''pattern''
    -(i mode only) -Ignore files that match -''pattern''. -
    -H ''format'', --format ''format''
    -(o mode only) -Produce the output archive in the specified format. -Supported formats include: - -
    -
    ''cpio''
    -Synonym for -''odc''. -
    ''newc''
    -The SVR4 portable cpio format. -
    ''odc''
    -The old POSIX.1 portable octet-oriented cpio format. -
    ''pax''
    -The POSIX.1 pax format, an extension of the ustar format. -
    ''ustar''
    -The POSIX.1 tar format. -
    - -The default format is -''odc''. -See -[[ManPageLibarchiveFormats5]] -for more complete information about the -formats currently supported by the underlying -[[ManPageLibarchive3]] -library. -
    -h, --help
    -Print usage information. -
    -I ''file''
    -Read archive from -''file''. -
    -i, --extract
    -Input mode. -See above for description. -
    --insecure
    -(i and p mode only) -Disable security checks during extraction or copying. -This allows extraction via symbolic links, absolute paths, -and path names containing -Sq .. -in the name. -
    -J, --xz
    -(o mode only) -Compress the file with xz-compatible compression before writing it. -In input mode, this option is ignored; xz compression is recognized -automatically on input. -
    -j
    -Synonym for --y. -
    -L
    -(o and p modes) -All symbolic links will be followed. -Normally, symbolic links are archived and copied as symbolic links. -With this option, the target of the link will be archived or copied instead. -
    -l, --link
    -(p mode only) -Create links from the target directory to the original files, -instead of copying. -
    --lrzip
    -(o mode only) -Compress the resulting archive with -[[lrzip(1)|http://www.freebsd.org/cgi/man.cgi?query=lrzip&sektion=1]]. -In input mode, this option is ignored. -
    --lz4
    -(o mode only) -Compress the archive with lz4-compatible compression before writing it. -In input mode, this option is ignored; lz4 compression is recognized -automatically on input. -
    --zstd
    -(o mode only) -Compress the archive with zstd-compatible compression before writing it. -In input mode, this option is ignored; zstd compression is recognized -automatically on input. -
    --lzma
    -(o mode only) -Compress the file with lzma-compatible compression before writing it. -In input mode, this option is ignored; lzma compression is recognized -automatically on input. -
    --lzop
    -(o mode only) -Compress the resulting archive with -[[lzop(1)|http://www.freebsd.org/cgi/man.cgi?query=lzop&sektion=1]]. -In input mode, this option is ignored. -
    --passphrase ''passphrase''
    -The -''passphrase'' -is used to extract or create an encrypted archive. -Currently, zip is only a format that -'''cpio''' -can handle encrypted archives. -You shouldn't use this option unless you realize how insecure -use of this option is. -
    -m, --preserve-modification-time
    -(i and p modes) -Set file modification time on created files to match -those in the source. -
    -n, --numeric-uid-gid
    -(i mode, only with --t) -Display numeric uid and gid. -By default, -'''cpio''' -displays the user and group names when they are provided in the -archive, or looks up the user and group names in the system -password database. -
    --no-preserve-owner
    -(i mode only) -Do not attempt to restore file ownership. -This is the default when run by non-root users. -
    -O ''file''
    -Write archive to -''file''. -
    -o, --create
    -Output mode. -See above for description. -
    -p, --pass-through
    -Pass-through mode. -See above for description. -
    --preserve-owner
    -(i mode only) -Restore file ownership. -This is the default when run by the root user. -
    --quiet
    -Suppress unnecessary messages. -
    -R [user][:][group], --owner [user][:][group]
    -Set the owner and/or group on files in the output. -If group is specified with no user -(for example, --R '':wheel'') -then the group will be set but not the user. -If the user is specified with a trailing colon and no group -(for example, --R ''root:'') -then the group will be set to the user's default group. -If the user is specified with no trailing colon, then -the user will be set but not the group. -In --i -and --p -modes, this option can only be used by the super-user. -(For compatibility, a period can be used in place of the colon.) -
    -r
    -(All modes.) -Rename files interactively. -For each file, a prompt is written to -''/dev/tty'' -containing the name of the file and a line is read from -''/dev/tty''. -If the line read is blank, the file is skipped. -If the line contains a single period, the file is processed normally. -Otherwise, the line is taken to be the new name of the file. -
    -t, --list
    -(i mode only) -List the contents of the archive to stdout; -do not restore the contents to disk. -
    -u, --unconditional
    -(i and p modes) -Unconditionally overwrite existing files. -Ordinarily, an older file will not overwrite a newer file on disk. -
    -V, --dot
    -Print a dot to stderr for each file as it is processed. -Superseded by --v. -
    -v, --verbose
    -Print the name of each file to stderr as it is processed. -With --t, -provide a detailed listing of each file. -
    --version
    -Print the program version information and exit. -
    -y
    -(o mode only) -Compress the archive with bzip2-compatible compression before writing it. -In input mode, this option is ignored; -bzip2 compression is recognized automatically on input. -
    -Z
    -(o mode only) -Compress the archive with compress-compatible compression before writing it. -In input mode, this option is ignored; -compression is recognized automatically on input. -
    -z
    -(o mode only) -Compress the archive with gzip-compatible compression before writing it. -In input mode, this option is ignored; -gzip compression is recognized automatically on input. -
    -== EXIT STATUS == -The '''cpio''' utility exits 0 on success, and >0 if an error occurs. -== ENVIRONMENT == -The following environment variables affect the execution of -'''cpio''': -
    -
    '''LANG'''
    -The locale to use. -See -[[environ(7)|http://www.freebsd.org/cgi/man.cgi?query=environ&sektion=7]] -for more information. -
    '''TZ'''
    -The timezone to use when displaying dates. -See -[[environ(7)|http://www.freebsd.org/cgi/man.cgi?query=environ&sektion=7]] -for more information. -
    -== EXAMPLES == -The -'''cpio''' -command is traditionally used to copy file hierarchies in conjunction -with the -[[find(1)|http://www.freebsd.org/cgi/man.cgi?query=find&sektion=1]] -command. -The first example here simply copies all files from -''src'' -to -''dest'': -```text -find src | cpio -pmud dest -``` - -By carefully selecting options to the -[[find(1)|http://www.freebsd.org/cgi/man.cgi?query=find&sektion=1]] -command and combining it with other standard utilities, -it is possible to exercise very fine control over which files are copied. -This next example copies files from -''src'' -to -''dest'' -that are more than 2 days old and whose names match a particular pattern: -```text -find src -mtime +2 | grep foo[bar] | cpio -pdmu dest -``` - -This example copies files from -''src'' -to -''dest'' -that are more than 2 days old and which contain the word -"foobar": -```text -find src -mtime +2 | xargs grep -l foobar | cpio -pdmu dest -``` -== COMPATIBILITY == -The mode options i, o, and p and the options -a, B, c, d, f, l, m, r, t, u, and v comply with SUSv2. - -The old POSIX.1 standard specified that only --i, --o, -and --p -were interpreted as command-line options. -Each took a single argument of a list of modifier -characters. -For example, the standard syntax allows --imu -but does not support --miu -or --i -m -u, -since -''m'' -and -''u'' -are only modifiers to --i, -they are not command-line options in their own right. -The syntax supported by this implementation is backwards-compatible -with the standard. -For best compatibility, scripts should limit themselves to the -standard syntax. -== SEE ALSO == -[[bzip2(1)|http://www.freebsd.org/cgi/man.cgi?query=bzip2&sektion=1]], -[[gzip(1)|http://www.freebsd.org/cgi/man.cgi?query=gzip&sektion=1]], -[[mt(1)|http://www.freebsd.org/cgi/man.cgi?query=mt&sektion=1]], -[[pax(1)|http://www.freebsd.org/cgi/man.cgi?query=pax&sektion=1]], -[[ManPageBsdtar1]], -[[ManPageLibarchive3]], -[[ManPageCpio5]], -[[ManPageLibarchiveFormats5]], -[[ManPageTar5]] -== STANDARDS == -There is no current POSIX standard for the cpio command; it appeared -in -ISO/IEC 9945-1:1996 (``POSIX.1'') -but was dropped from -IEEE Std 1003.1-2001 (``POSIX.1''). - -The cpio, ustar, and pax interchange file formats are defined by -IEEE Std 1003.1-2001 (``POSIX.1'') -for the pax command. -== HISTORY == -The original -'''cpio''' -and -'''find''' -utilities were written by Dick Haight -while working in AT&T's Unix Support Group. -They first appeared in 1977 in PWB/UNIX 1.0, the -"Programmer's Work Bench" -system developed for use within AT&T. -They were first released outside of AT&T as part of System III Unix in 1981. -As a result, -'''cpio''' -actually predates -'''tar''', -even though it was not well-known outside of AT&T until some time later. - -This is a complete re-implementation based on the -[[ManPageLibarchive3]] -library. -== BUGS == -The cpio archive format has several basic limitations: -It does not store user and group names, only numbers. -As a result, it cannot be reliably used to transfer -files between systems with dissimilar user and group numbering. -Older cpio formats limit the user and group numbers to -16 or 18 bits, which is insufficient for modern systems. -The cpio archive formats cannot support files over 4 gigabytes, -except for the -"odc" -variant, which can support files up to 8 gigabytes. diff --git a/thirdparty/libarchive/doc/wiki/ManPageBsdtar1.wiki b/thirdparty/libarchive/doc/wiki/ManPageBsdtar1.wiki deleted file mode 100644 index b94653731..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageBsdtar1.wiki +++ /dev/null @@ -1,1374 +0,0 @@ -TAR(1) manual page -== NAME == -'''tar''' -- manipulate tape archives -== SYNOPSIS == -
    -'''tar''' -[''bundled-flags'' <args>] -[<''file''> | <''pattern''> ...] -
    -'''tar''' -{-c} -[''options''] -[''files'' | ''directories''] -
    -'''tar''' -{-r | -u} --f ''archive-file'' -[''options''] -[''files'' | ''directories''] -
    -'''tar''' -{-t | -x} -[''options''] -[''patterns''] -== DESCRIPTION == -'''tar''' -creates and manipulates streaming archive files. -This implementation can extract from tar, pax, cpio, zip, jar, ar, xar, -rpm, 7-zip, and ISO 9660 cdrom images and can create tar, pax, cpio, ar, zip, -7-zip, and shar archives. - -The first synopsis form shows a -"bundled" -option word. -This usage is provided for compatibility with historical implementations. -See COMPATIBILITY below for details. - -The other synopsis forms show the preferred usage. -The first option to -'''tar''' -is a mode indicator from the following list: -
    -
    -c
    -Create a new archive containing the specified items. -The long option form is ---create. -
    -r
    -Like --c, -but new entries are appended to the archive. -Note that this only works on uncompressed archives stored in regular files. -The --f -option is required. -The long option form is ---append. -
    -t
    -List archive contents to stdout. -The long option form is ---list. -
    -u
    -Like --r, -but new entries are added only if they have a modification date -newer than the corresponding entry in the archive. -Note that this only works on uncompressed archives stored in regular files. -The --f -option is required. -The long form is ---update. -
    -x
    -Extract to disk from the archive. -If a file with the same name appears more than once in the archive, -each copy will be extracted, with later copies overwriting (replacing) -earlier copies. -The long option form is ---extract. -
    - -In --c, --r, -or --u -mode, each specified file or directory is added to the -archive in the order specified on the command line. -By default, the contents of each directory are also archived. - -In extract or list mode, the entire command line -is read and parsed before the archive is opened. -The pathnames or patterns on the command line indicate -which items in the archive should be processed. -Patterns are shell-style globbing patterns as -documented in -[[tcsh(1)|http://www.freebsd.org/cgi/man.cgi?query=tcsh&sektion=1]]. -== OPTIONS == -Unless specifically stated otherwise, options are applicable in -all operating modes. -
    -
    '''@'''''archive''
    -(c and r modes only) -The specified archive is opened and the entries -in it will be appended to the current archive. -As a simple example, -```text -tar -c -f - newfile @original.tar -``` -writes a new archive to standard output containing a file -''newfile'' -and all of the entries from -''original.tar''. -In contrast, -```text -tar -c -f - newfile original.tar -``` -creates a new archive with only two entries. -Similarly, -```text -tar -czf - --format pax @- -``` -reads an archive from standard input (whose format will be determined -automatically) and converts it into a gzip-compressed -pax-format archive on stdout. -In this way, -'''tar''' -can be used to convert archives from one format to another. -
    -a, --auto-compress
    -(c mode only) -Use the archive suffix to decide a set of the format and -the compressions. -As a simple example, -```text -tar -a -cf archive.tgz source.c source.h -``` -creates a new archive with restricted pax format and gzip compression, -```text -tar -a -cf archive.tar.bz2.uu source.c source.h -``` -creates a new archive with restricted pax format and bzip2 compression -and uuencode compression, -```text -tar -a -cf archive.zip source.c source.h -``` -creates a new archive with zip format, -```text -tar -a -jcf archive.tgz source.c source.h -``` -ignores the -"-j" -option, and creates a new archive with restricted pax format -and gzip compression, -```text -tar -a -jcf archive.xxx source.c source.h -``` -if it is unknown suffix or no suffix, creates a new archive with -restricted pax format and bzip2 compression. -
    --acls
    -(c, r, u, x modes only) -Archive or extract POSIX.1e or NFSv4 ACLs. -This is the reverse of ---no-acls -and the default behavior in c, r, and u modes (except on Mac OS X) or if -'''tar''' -is run in x mode as root. -On Mac OS X this option translates extended ACLs to NFSv4 ACLs. -To store extended ACLs the ---mac-metadata -option is preferred. -
    -B, --read-full-blocks
    -Ignored for compatibility with other -[[ManPageBsdtar1]] -implementations. -
    -b ''blocksize'', --block-size ''blocksize''
    -Specify the block size, in 512-byte records, for tape drive I/O. -As a rule, this argument is only needed when reading from or writing -to tape drives, and usually not even then as the default block size of -20 records (10240 bytes) is very common. -
    -C ''directory'', --cd ''directory'', --directory ''directory''
    -In c and r mode, this changes the directory before adding -the following files. -In x mode, change directories after opening the archive -but before extracting entries from the archive. -
    --chroot
    -(x mode only) -'''chroot'''() -to the current directory after processing any --C -options and before extracting any files. -
    --clear-nochange-fflags
    -(x mode only) -Before removing file system objects to replace them, clear platform-specific -file attributes or file flags that might prevent removal. -
    --exclude ''pattern''
    -Do not process files or directories that match the -specified pattern. -Note that exclusions take precedence over patterns or filenames -specified on the command line. -
    --exclude-vcs
    -Do not process files or directories internally used by the -version control systems -Sq Arch, -Sq Bazaar, -Sq CVS, -Sq Darcs, -Sq Mercurial, -Sq RCS, -Sq SCCS, -Sq SVN -and -Sq git. -
    --fflags
    -(c, r, u, x modes only) -Archive or extract platform-specific file attributes or file flags. -This is the reverse of ---no-fflags -and the default behavior in c, r, and u modes or if -'''tar''' -is run in x mode as root. -
    --format ''format''
    -(c, r, u mode only) -Use the specified format for the created archive. -Supported formats include -"cpio", -"pax", -"shar", -and -"ustar". -Other formats may also be supported; see -[[ManPageLibarchiveFormats5]] -for more information about currently-supported formats. -In r and u modes, when extending an existing archive, the format specified -here must be compatible with the format of the existing archive on disk. -
    -f ''file'', --file ''file''
    -Read the archive from or write the archive to the specified file. -The filename can be -''-'' -for standard input or standard output. -The default varies by system; -on -FreeBSD, -the default is -''/dev/sa0''; -on Linux, the default is -''/dev/st0''. -
    --gid ''id''
    -Use the provided group id number. -On extract, this overrides the group id in the archive; -the group name in the archive will be ignored. -On create, this overrides the group id read from disk; -if ---gname -is not also specified, the group name will be set to -match the group id. -
    --gname ''name''
    -Use the provided group name. -On extract, this overrides the group name in the archive; -if the provided group name does not exist on the system, -the group id -(from the archive or from the ---gid -option) -will be used instead. -On create, this sets the group name that will be stored -in the archive; -the name will not be verified against the system group database. -
    -H
    -(c and r modes only) -Symbolic links named on the command line will be followed; the -target of the link will be archived, not the link itself. -
    -h
    -(c and r modes only) -Synonym for --L. -
    -I
    -Synonym for --T. -
    --help
    -Show usage. -
    --hfsCompression
    -(x mode only) -Mac OS X specific (v10.6 or later). Compress extracted regular files with HFS+ -compression. -
    --ignore-zeros
    -An alias of ---options '''read_concatenated_archives''' -for compatibility with GNU tar. -
    --include ''pattern''
    -Process only files or directories that match the specified pattern. -Note that exclusions specified with ---exclude -take precedence over inclusions. -If no inclusions are explicitly specified, all entries are processed by -default. -The ---include -option is especially useful when filtering archives. -For example, the command -```text -tar -c -f new.tar --include='*foo*' @old.tgz -``` -creates a new archive -''new.tar'' -containing only the entries from -''old.tgz'' -containing the string -Sq foo. -
    -J, --xz
    -(c mode only) -Compress the resulting archive with -[[xz(1)|http://www.freebsd.org/cgi/man.cgi?query=xz&sektion=1]]. -In extract or list modes, this option is ignored. -Note that this -'''tar''' -implementation recognizes XZ compression automatically when reading archives. -
    -j, --bzip, --bzip2, --bunzip2
    -(c mode only) -Compress the resulting archive with -[[bzip2(1)|http://www.freebsd.org/cgi/man.cgi?query=bzip2&sektion=1]]. -In extract or list modes, this option is ignored. -Note that this -'''tar''' -implementation recognizes bzip2 compression automatically when reading -archives. -
    -k, --keep-old-files
    -(x mode only) -Do not overwrite existing files. -In particular, if a file appears more than once in an archive, -later copies will not overwrite earlier copies. -
    --keep-newer-files
    -(x mode only) -Do not overwrite existing files that are newer than the -versions appearing in the archive being extracted. -
    -L, --dereference
    -(c and r modes only) -All symbolic links will be followed. -Normally, symbolic links are archived as such. -With this option, the target of the link will be archived instead. -
    -l, --check-links
    -(c and r modes only) -Issue a warning message unless all links to each file are archived. -
    --lrzip
    -(c mode only) -Compress the resulting archive with -[[lrzip(1)|http://www.freebsd.org/cgi/man.cgi?query=lrzip&sektion=1]]. -In extract or list modes, this option is ignored. -Note that this -'''tar''' -implementation recognizes lrzip compression automatically when reading -archives. -
    --lz4
    -(c mode only) -Compress the archive with lz4-compatible compression before writing it. -In extract or list modes, this option is ignored. -Note that this -'''tar''' -implementation recognizes lz4 compression automatically when reading archives. -
    --zstd
    -(c mode only) -Compress the archive with zstd-compatible compression before writing it. -In extract or list modes, this option is ignored. -Note that this -'''tar''' -implementation recognizes zstd compression automatically when reading archives. -
    --lzma
    -(c mode only) Compress the resulting archive with the original LZMA algorithm. -In extract or list modes, this option is ignored. -Use of this option is discouraged and new archives should be created with ---xz -instead. -Note that this -'''tar''' -implementation recognizes LZMA compression automatically when reading archives. -
    --lzop
    -(c mode only) -Compress the resulting archive with -[[lzop(1)|http://www.freebsd.org/cgi/man.cgi?query=lzop&sektion=1]]. -In extract or list modes, this option is ignored. -Note that this -'''tar''' -implementation recognizes LZO compression automatically when reading archives. -
    -m, --modification-time
    -(x mode only) -Do not extract modification time. -By default, the modification time is set to the time stored in the archive. -
    --mac-metadata
    -(c, r, u and x mode only) -Mac OS X specific. -Archive or extract extended ACLs and extended file -attributes using -[[copyfile(3)|http://www.freebsd.org/cgi/man.cgi?query=copyfile&sektion=3]] -in AppleDouble format. -This is the reverse of ---no-mac-metadata. -and the default behavior in c, r, and u modes or if -'''tar''' -is run in x mode as root. -
    -n, --norecurse, --no-recursion
    -Do not operate recursively on the content of directories. -
    --newer ''date''
    -(c, r, u modes only) -Only include files and directories newer than the specified date. -This compares ctime entries. -
    --newer-mtime ''date''
    -(c, r, u modes only) -Like ---newer, -except it compares mtime entries instead of ctime entries. -
    --newer-than ''file''
    -(c, r, u modes only) -Only include files and directories newer than the specified file. -This compares ctime entries. -
    --newer-mtime-than ''file''
    -(c, r, u modes only) -Like ---newer-than, -except it compares mtime entries instead of ctime entries. -
    --nodump
    -(c and r modes only) -Honor the nodump file flag by skipping this file. -
    --nopreserveHFSCompression
    -(x mode only) -Mac OS X specific (v10.6 or later). Do not compress extracted regular files -which were compressed with HFS+ compression before archived. -By default, compress the regular files again with HFS+ compression. -
    --null
    -(use with --I -or --T) -Filenames or patterns are separated by null characters, -not by newlines. -This is often used to read filenames output by the --print0 -option to -[[find(1)|http://www.freebsd.org/cgi/man.cgi?query=find&sektion=1]]. -
    --no-acls
    -(c, r, u, x modes only) -Do not archive or extract POSIX.1e or NFSv4 ACLs. -This is the reverse of ---acls -and the default behavior if -'''tar''' -is run as non-root in x mode (on Mac OS X as any user in c, r, u and x modes). -
    --no-fflags
    -(c, r, u, x modes only) -Do not archive or extract file attributes or file flags. -This is the reverse of ---fflags -and the default behavior if -'''tar''' -is run as non-root in x mode. -
    --no-mac-metadata
    -(x mode only) -Mac OS X specific. -Do not archive or extract ACLs and extended file attributes -using -[[copyfile(3)|http://www.freebsd.org/cgi/man.cgi?query=copyfile&sektion=3]] -in AppleDouble format. -This is the reverse of ---mac-metadata. -and the default behavior if -'''tar''' -is run as non-root in x mode. -
    --no-read-sparse
    -(c, r, u modes only) -Do not read sparse file information from disk. -This is the reverse of ---read-sparse. -
    --no-safe-writes
    -(x mode only) -Do not create temporary files and use -[[rename(2)|http://www.freebsd.org/cgi/man.cgi?query=rename&sektion=2]] -to replace the original ones. -This is the reverse of ---safe-writes. -
    --no-same-owner
    -(x mode only) -Do not extract owner and group IDs. -This is the reverse of ---same-owner -and the default behavior if -'''tar''' -is run as non-root. -
    --no-same-permissions
    -(x mode only) -Do not extract full permissions (SGID, SUID, sticky bit, -file attributes or file flags, extended file attributes and ACLs). -This is the reverse of --p -and the default behavior if -'''tar''' -is run as non-root. -
    --no-xattrs
    -(c, r, u, x modes only) -Do not archive or extract extended file attributes. -This is the reverse of ---xattrs -and the default behavior if -'''tar''' -is run as non-root in x mode. -
    --numeric-owner
    -This is equivalent to ---uname -Qq ---gname -Qq. -On extract, it causes user and group names in the archive -to be ignored in favor of the numeric user and group ids. -On create, it causes user and group names to not be stored -in the archive. -
    -O, --to-stdout
    -(x, t modes only) -In extract (-x) mode, files will be written to standard out rather than -being extracted to disk. -In list (-t) mode, the file listing will be written to stderr rather than -the usual stdout. -
    -o
    -(x mode) -Use the user and group of the user running the program rather -than those specified in the archive. -Note that this has no significance unless --p -is specified, and the program is being run by the root user. -In this case, the file modes and flags from -the archive will be restored, but ACLs or owner information in -the archive will be discarded. -
    -o
    -(c, r, u mode) -A synonym for ---format ''ustar'' -
    --older ''date''
    -(c, r, u modes only) -Only include files and directories older than the specified date. -This compares ctime entries. -
    --older-mtime ''date''
    -(c, r, u modes only) -Like ---older, -except it compares mtime entries instead of ctime entries. -
    --older-than ''file''
    -(c, r, u modes only) -Only include files and directories older than the specified file. -This compares ctime entries. -
    --older-mtime-than ''file''
    -(c, r, u modes only) -Like ---older-than, -except it compares mtime entries instead of ctime entries. -
    --one-file-system
    -(c, r, and u modes) -Do not cross mount points. -
    --options ''options''
    -Select optional behaviors for particular modules. -The argument is a text string containing comma-separated -keywords and values. -These are passed to the modules that handle particular -formats to control how those formats will behave. -Each option has one of the following forms: -
    -
    ''key=value''
    -The key will be set to the specified value in every module that supports it. -Modules that do not support this key will ignore it. -
    ''key''
    -The key will be enabled in every module that supports it. -This is equivalent to -''key'''''=1'''. -
    ''!key''
    -The key will be disabled in every module that supports it. -
    ''module:key=value'', ''module:key'', ''module:!key''
    -As above, but the corresponding key and value will be provided -only to modules whose name matches -''module''. -
    - -The complete list of supported modules and keys -for create and append modes is in -[[ManPageArchiveWriteSetOptions3]] -and for extract and list modes in -[[ManPageArchiveReadSetOptions3]]. - -Examples of supported options: -
    -
    '''iso9660:joliet'''
    -Support Joliet extensions. -This is enabled by default, use -'''!joliet''' -or -'''iso9660:!joliet''' -to disable. -
    '''iso9660:rockridge'''
    -Support Rock Ridge extensions. -This is enabled by default, use -'''!rockridge''' -or -'''iso9660:!rockridge''' -to disable. -
    '''gzip:compression-level'''
    -A decimal integer from 1 to 9 specifying the gzip compression level. -
    '''gzip:timestamp'''
    -Store timestamp. -This is enabled by default, use -'''!timestamp''' -or -'''gzip:!timestamp''' -to disable. -
    '''lrzip:compression'''=''type''
    -Use -''type'' -as compression method. -Supported values are bzip2, gzip, lzo (ultra fast), -and zpaq (best, extremely slow). -
    '''lrzip:compression-level'''
    -A decimal integer from 1 to 9 specifying the lrzip compression level. -
    '''lz4:compression-level'''
    -A decimal integer from 1 to 9 specifying the lzop compression level. -
    '''lz4:stream-checksum'''
    -Enable stream checksum. -This is by default, use -'''lz4:!stream-checksum''' -to disable. -
    '''lz4:block-checksum'''
    -Enable block checksum (Disabled by default). -
    '''lz4:block-size'''
    -A decimal integer from 4 to 7 specifying the lz4 compression block size -(7 is set by default). -
    '''lz4:block-dependence'''
    -Use the previous block of the block being compressed for -a compression dictionary to improve compression ratio. -
    '''zstd:compression-level'''
    -A decimal integer specifying the zstd compression level. Supported values depend -on the library version, common values are from 1 to 22. -
    '''zstd:threads'''
    -Specify the number of worker threads to use. -Setting threads to a special value 0 makes -[[zstd(1)|http://www.freebsd.org/cgi/man.cgi?query=zstd&sektion=1]] -use as many threads as there are CPU cores on the system. -
    '''zstd:frame-per-file'''
    -Start a new compression frame at the beginning of each file in the -archive. -
    '''zstd:min-frame-size'''=''N''
    -In combination with -'''zstd:frame-per-file''', -do not start a new compression frame unless the current frame is at least -''N'' -bytes. -
    '''zstd:max-frame-size'''=''N''
    -Start a new compression frame as soon as the current frame exceeds -''N'' -bytes. -
    '''lzop:compression-level'''
    -A decimal integer from 1 to 9 specifying the lzop compression level. -
    '''xz:compression-level'''
    -A decimal integer from 0 to 9 specifying the xz compression level. -
    '''xz:threads'''
    -Specify the number of worker threads to use. -Setting threads to a special value 0 makes -[[xz(1)|http://www.freebsd.org/cgi/man.cgi?query=xz&sektion=1]] -use as many threads as there are CPU cores on the system. -
    '''mtree:'''''keyword''
    -The mtree writer module allows you to specify which mtree keywords -will be included in the output. -Supported keywords include: -'''cksum''', '''device''', '''flags''', '''gid''', '''gname''', '''indent''', -'''link''', '''md5''', '''mode''', '''nlink''', '''rmd160''', '''sha1''', '''sha256''', -'''sha384''', '''sha512''', '''size''', '''time''', '''uid''', '''uname'''. -The default is equivalent to: -"device, flags, gid, gname, link, mode, nlink, size, time, type, uid, uname". -
    '''mtree:all'''
    -Enables all of the above keywords. -You can also use -'''mtree:!all''' -to disable all keywords. -
    '''mtree:use-set'''
    -Enable generation of -'''/set''' -lines in the output. -
    '''mtree:indent'''
    -Produce human-readable output by indenting options and splitting lines -to fit into 80 columns. -
    '''zip:compression'''=''type''
    -Use -''type'' -as compression method. -Supported values are store (uncompressed) and deflate (gzip algorithm). -
    '''zip:encryption'''
    -Enable encryption using traditional zip encryption. -
    '''zip:encryption'''=''type''
    -Use -''type'' -as encryption type. -Supported values are zipcrypt (traditional zip encryption), -aes128 (WinZip AES-128 encryption) and aes256 (WinZip AES-256 encryption). -
    '''read_concatenated_archives'''
    -Ignore zeroed blocks in the archive, which occurs when multiple tar archives -have been concatenated together. -Without this option, only the contents of -the first concatenated archive would be read. -This option is comparable to the --i, --ignore-zeros -option of GNU tar. -
    -If a provided option is not supported by any module, that -is a fatal error. -
    -P, --absolute-paths
    -Preserve pathnames. -By default, absolute pathnames (those that begin with a / -character) have the leading slash removed both when creating archives -and extracting from them. -Also, -'''tar''' -will refuse to extract archive entries whose pathnames contain -''..'' -or whose target directory would be altered by a symlink. -This option suppresses these behaviors. -
    -p, --insecure, --preserve-permissions
    -(x mode only) -Preserve file permissions. -Attempt to restore the full permissions, including file modes, file attributes -or file flags, extended file attributes and ACLs, if available, for each item -extracted from the archive. -This is the reverse of ---no-same-permissions -and the default if -'''tar''' -is being run as root. -It can be partially overridden by also specifying ---no-acls, ---no-fflags, ---no-mac-metadata -or ---no-xattrs. -
    --passphrase ''passphrase''
    -The -''passphrase'' -is used to extract or create an encrypted archive. -Currently, zip is the only supported format that supports encryption. -You shouldn't use this option unless you realize how insecure -use of this option is. -
    --posix
    -(c, r, u mode only) -Synonym for ---format ''pax'' -
    -q, --fast-read
    -(x and t mode only) -Extract or list only the first archive entry that matches each pattern -or filename operand. -Exit as soon as each specified pattern or filename has been matched. -By default, the archive is always read to the very end, since -there can be multiple entries with the same name and, by convention, -later entries overwrite earlier entries. -This option is provided as a performance optimization. -
    --read-sparse
    -(c, r, u modes only) -Read sparse file information from disk. -This is the reverse of ---no-read-sparse -and the default behavior. -
    -S
    -(x mode only) -Extract files as sparse files. -For every block on disk, check first if it contains only NULL bytes and seek -over it otherwise. -This works similar to the conv=sparse option of dd. -
    -s ''pattern''
    -Modify file or archive member names according to -''pattern''. -The pattern has the format -''/old/new/''[ghHprRsS] -where -''old'' -is a basic regular expression, -''new'' -is the replacement string of the matched part, -and the optional trailing letters modify -how the replacement is handled. -If -''old'' -is not matched, the pattern is skipped. -Within -''new'', -~ is substituted with the match, \e1 to \e9 with the content of -the corresponding captured group. -The optional trailing g specifies that matching should continue -after the matched part and stop on the first unmatched pattern. -The optional trailing s specifies that the pattern applies to the value -of symbolic links. -The optional trailing p specifies that after a successful substitution -the original path name and the new path name should be printed to -standard error. -Optional trailing H, R, or S characters suppress substitutions -for hardlink targets, regular filenames, or symlink targets, -respectively. -Optional trailing h, r, or s characters enable substitutions -for hardlink targets, regular filenames, or symlink targets, -respectively. -The default is -''hrs'' -which applies substitutions to all names. -In particular, it is never necessary to specify h, r, or s. -
    --safe-writes
    -(x mode only) -Extract files atomically. -By default -'''tar''' -unlinks the original file with the same name as the extracted file (if it -exists), and then creates it immediately under the same name and writes to -it. -For a short period of time, applications trying to access the file might -not find it, or see incomplete results. -If ---safe-writes -is enabled, -'''tar''' -first creates a unique temporary file, then writes the new contents to -the temporary file, and finally renames the temporary file to its final -name atomically using -[[rename(2)|http://www.freebsd.org/cgi/man.cgi?query=rename&sektion=2]]. -This guarantees that an application accessing the file, will either see -the old contents or the new contents at all times. -
    --same-owner
    -(x mode only) -Extract owner and group IDs. -This is the reverse of ---no-same-owner -and the default behavior if -'''tar''' -is run as root. -
    --strip-components ''count''
    -Remove the specified number of leading path elements. -Pathnames with fewer elements will be silently skipped. -Note that the pathname is edited after checking inclusion/exclusion patterns -but before security checks. -
    -T ''filename'', --files-from ''filename''
    -In x or t mode, -'''tar''' -will read the list of names to be extracted from -''filename''. -In c mode, -'''tar''' -will read names to be archived from -''filename''. -The special name -"-C" -on a line by itself will cause the current directory to be changed to -the directory specified on the following line. -Names are terminated by newlines unless ---null -is specified. -Note that ---null -also disables the special handling of lines containing -"-C". -Note: If you are generating lists of files using -[[find(1)|http://www.freebsd.org/cgi/man.cgi?query=find&sektion=1]], -you probably want to use --n -as well. -
    --totals
    -(c, r, u modes only) -After archiving all files, print a summary to stderr. -
    -U, --unlink, --unlink-first
    -(x mode only) -Unlink files before creating them. -This can be a minor performance optimization if most files -already exist, but can make things slower if most files -do not already exist. -This flag also causes -'''tar''' -to remove intervening directory symlinks instead of -reporting an error. -See the SECURITY section below for more details. -
    --uid ''id''
    -Use the provided user id number and ignore the user -name from the archive. -On create, if ---uname -is not also specified, the user name will be set to -match the user id. -
    --uname ''name''
    -Use the provided user name. -On extract, this overrides the user name in the archive; -if the provided user name does not exist on the system, -it will be ignored and the user id -(from the archive or from the ---uid -option) -will be used instead. -On create, this sets the user name that will be stored -in the archive; -the name is not verified against the system user database. -
    --use-compress-program ''program''
    -Pipe the input (in x or t mode) or the output (in c mode) through -''program'' -instead of using the builtin compression support. -
    -v, --verbose
    -Produce verbose output. -In create and extract modes, -'''tar''' -will list each file name as it is read from or written to -the archive. -In list mode, -'''tar''' -will produce output similar to that of -[[ls(1)|http://www.freebsd.org/cgi/man.cgi?query=ls&sektion=1]]. -An additional --v -option will also provide ls-like details in create and extract mode. -
    --version
    -Print version of -'''tar''' -and -'''libarchive''', -and exit. -
    -w, --confirmation, --interactive
    -Ask for confirmation for every action. -
    -X ''filename'', --exclude-from ''filename''
    -Read a list of exclusion patterns from the specified file. -See ---exclude -for more information about the handling of exclusions. -
    --xattrs
    -(c, r, u, x modes only) -Archive or extract extended file attributes. -This is the reverse of ---no-xattrs -and the default behavior in c, r, and u modes or if -'''tar''' -is run in x mode as root. -
    -y
    -(c mode only) -Compress the resulting archive with -[[bzip2(1)|http://www.freebsd.org/cgi/man.cgi?query=bzip2&sektion=1]]. -In extract or list modes, this option is ignored. -Note that this -'''tar''' -implementation recognizes bzip2 compression automatically when reading -archives. -
    -Z, --compress, --uncompress
    -(c mode only) -Compress the resulting archive with -[[compress(1)|http://www.freebsd.org/cgi/man.cgi?query=compress&sektion=1]]. -In extract or list modes, this option is ignored. -Note that this -'''tar''' -implementation recognizes compress compression automatically when reading -archives. -
    -z, --gunzip, --gzip
    -(c mode only) -Compress the resulting archive with -[[gzip(1)|http://www.freebsd.org/cgi/man.cgi?query=gzip&sektion=1]]. -In extract or list modes, this option is ignored. -Note that this -'''tar''' -implementation recognizes gzip compression automatically when reading -archives. -
    -== ENVIRONMENT == -The following environment variables affect the execution of -'''tar''': -
    -
    '''TAR_READER_OPTIONS'''
    -The default options for format readers and compression readers. -The ---options -option overrides this. -
    '''TAR_WRITER_OPTIONS'''
    -The default options for format writers and compression writers. -The ---options -option overrides this. -
    '''LANG'''
    -The locale to use. -See -[[environ(7)|http://www.freebsd.org/cgi/man.cgi?query=environ&sektion=7]] -for more information. -
    '''TAPE'''
    -The default device. -The --f -option overrides this. -Please see the description of the --f -option above for more details. -
    '''TZ'''
    -The timezone to use when displaying dates. -See -[[environ(7)|http://www.freebsd.org/cgi/man.cgi?query=environ&sektion=7]] -for more information. -
    -== EXIT STATUS == -The '''tar''' utility exits 0 on success, and >0 if an error occurs. -== EXAMPLES == -The following creates a new archive -called -''file.tar.gz'' -that contains two files -''source.c'' -and -''source.h'': -```text -tar -czf file.tar.gz source.c source.h -``` - -To view a detailed table of contents for this -archive: -```text -tar -tvf file.tar.gz -``` - -To extract all entries from the archive on -the default tape drive: -```text -tar -x -``` - -To examine the contents of an ISO 9660 cdrom image: -```text -tar -tf image.iso -``` - -To move file hierarchies, invoke -'''tar''' -as -```text -tar -cf - -C srcdir . | tar -xpf - -C destdir -``` -or more traditionally -```text -cd srcdir ; tar -cf - . | (cd destdir ; tar -xpf -) -``` - -In create mode, the list of files and directories to be archived -can also include directory change instructions of the form -'''-C'''''foo/baz'' -and archive inclusions of the form -'''@'''''archive-file''. -For example, the command line -```text -tar -c -f new.tar foo1 @old.tgz -C/tmp foo2 -``` -will create a new archive -''new.tar''. -'''tar''' -will read the file -''foo1'' -from the current directory and add it to the output archive. -It will then read each entry from -''old.tgz'' -and add those entries to the output archive. -Finally, it will switch to the -''/tmp'' -directory and add -''foo2'' -to the output archive. - -An input file in -[[ManPageMtree5]] -format can be used to create an output archive with arbitrary ownership, -permissions, or names that differ from existing data on disk: -```text -$ cat input.mtree -#mtree -usr/bin uid=0 gid=0 mode=0755 type=dir -usr/bin/ls uid=0 gid=0 mode=0755 type=file content=myls -$ tar -cvf output.tar @input.mtree -``` - -The ---newer -and ---newer-mtime -switches accept a variety of common date and time specifications, including -"12 Mar 2005 7:14:29pm", -"2005-03-12 19:14", -"5 minutes ago", -and -"19:14 PST May 1". - -The ---options -argument can be used to control various details of archive generation -or reading. -For example, you can generate mtree output which only contains -'''type''', '''time''', -and -'''uid''' -keywords: -```text -tar -cf file.tar --format=mtree --options='!all,type,time,uid' dir -``` -or you can set the compression level used by gzip or xz compression: -```text -tar -czf file.tar --options='compression-level=9'. -``` -For more details, see the explanation of the -'''archive_read_set_options'''() -and -'''archive_write_set_options'''() -API calls that are described in -[[ManPageArchiveRead3]] -and -[[ManPageArchiveWrite3]]. -== COMPATIBILITY == -The bundled-arguments format is supported for compatibility -with historic implementations. -It consists of an initial word (with no leading - character) in which -each character indicates an option. -Arguments follow as separate words. -The order of the arguments must match the order -of the corresponding characters in the bundled command word. -For example, -```text -tar tbf 32 file.tar -``` -specifies three flags -'''t''', -'''b''', -and -'''f'''. -The -'''b''' -and -'''f''' -flags both require arguments, -so there must be two additional items -on the command line. -The -''32'' -is the argument to the -'''b''' -flag, and -''file.tar'' -is the argument to the -'''f''' -flag. - -The mode options c, r, t, u, and x and the options -b, f, l, m, o, v, and w comply with SUSv2. - -For maximum portability, scripts that invoke -'''tar''' -should use the bundled-argument format above, should limit -themselves to the -'''c''', -'''t''', -and -'''x''' -modes, and the -'''b''', -'''f''', -'''m''', -'''v''', -and -'''w''' -options. - -Additional long options are provided to improve compatibility with other -tar implementations. -== SECURITY == -Certain security issues are common to many archiving programs, including -'''tar'''. -In particular, carefully-crafted archives can request that -'''tar''' -extract files to locations outside of the target directory. -This can potentially be used to cause unwitting users to overwrite -files they did not intend to overwrite. -If the archive is being extracted by the superuser, any file -on the system can potentially be overwritten. -There are three ways this can happen. -Although -'''tar''' -has mechanisms to protect against each one, -savvy users should be aware of the implications: -
      -
    • -Archive entries can have absolute pathnames. -By default, -'''tar''' -removes the leading -''/'' -character from filenames before restoring them to guard against this problem. -
    • -Archive entries can have pathnames that include -''..'' -components. -By default, -'''tar''' -will not extract files containing -''..'' -components in their pathname. -
    • -Archive entries can exploit symbolic links to restore -files to other directories. -An archive can restore a symbolic link to another directory, -then use that link to restore a file into that directory. -To guard against this, -'''tar''' -checks each extracted path for symlinks. -If the final path element is a symlink, it will be removed -and replaced with the archive entry. -If --U -is specified, any intermediate symlink will also be unconditionally removed. -If neither --U -nor --P -is specified, -'''tar''' -will refuse to extract the entry. -
    -To protect yourself, you should be wary of any archives that -come from untrusted sources. -You should examine the contents of an archive with -```text -tar -tf filename -``` -before extraction. -You should use the --k -option to ensure that -'''tar''' -will not overwrite any existing files or the --U -option to remove any pre-existing files. -You should generally not extract archives while running with super-user -privileges. -Note that the --P -option to -'''tar''' -disables the security checks above and allows you to extract -an archive while preserving any absolute pathnames, -''..'' -components, or symlinks to other directories. -== SEE ALSO == -[[bzip2(1)|http://www.freebsd.org/cgi/man.cgi?query=bzip2&sektion=1]], -[[compress(1)|http://www.freebsd.org/cgi/man.cgi?query=compress&sektion=1]], -[[ManPageBsdcpio1]], -[[gzip(1)|http://www.freebsd.org/cgi/man.cgi?query=gzip&sektion=1]], -[[mt(1)|http://www.freebsd.org/cgi/man.cgi?query=mt&sektion=1]], -[[pax(1)|http://www.freebsd.org/cgi/man.cgi?query=pax&sektion=1]], -[[shar(1)|http://www.freebsd.org/cgi/man.cgi?query=shar&sektion=1]], -[[xz(1)|http://www.freebsd.org/cgi/man.cgi?query=xz&sektion=1]], -[[ManPageLibarchive3]], -[[ManPageLibarchiveFormats5]], -[[ManPageTar5]] -== STANDARDS == -There is no current POSIX standard for the tar command; it appeared -in -ISO/IEC 9945-1:1996 (``POSIX.1'') -but was dropped from -IEEE Std 1003.1-2001 (``POSIX.1''). -The options supported by this implementation were developed by surveying a -number of existing tar implementations as well as the old POSIX specification -for tar and the current POSIX specification for pax. - -The ustar and pax interchange file formats are defined by -IEEE Std 1003.1-2001 (``POSIX.1'') -for the pax command. -== HISTORY == -A -'''tar''' -command appeared in Seventh Edition Unix, which was released in January, 1979. -There have been numerous other implementations, -many of which extended the file format. -John Gilmore's -'''pdtar''' -public-domain implementation (circa November, 1987) -was quite influential, and formed the basis of GNU tar. -GNU tar was included as the standard system tar -in -FreeBSD -beginning with -FreeBSD 1.0. - -This is a complete re-implementation based on the -[[ManPageLibarchive3]] -library. -It was first released with -FreeBSD 5.4 -in May, 2005. -== BUGS == -This program follows -ISO/IEC 9945-1:1996 (``POSIX.1'') -for the definition of the --l -option. -Note that GNU tar prior to version 1.15 treated --l -as a synonym for the ---one-file-system -option. - -The --C ''dir'' -option may differ from historic implementations. - -All archive output is written in correctly-sized blocks, even -if the output is being compressed. -Whether or not the last output block is padded to a full -block size varies depending on the format and the -output device. -For tar and cpio formats, the last block of output is padded -to a full block size if the output is being -written to standard output or to a character or block device such as -a tape drive. -If the output is being written to a regular file, the last block -will not be padded. -Many compressors, including -[[gzip(1)|http://www.freebsd.org/cgi/man.cgi?query=gzip&sektion=1]] -and -[[bzip2(1)|http://www.freebsd.org/cgi/man.cgi?query=bzip2&sektion=1]], -complain about the null padding when decompressing an archive created by -'''tar''', -although they still extract it correctly. - -The compression and decompression is implemented internally, so -there may be insignificant differences between the compressed output -generated by -```text -tar -czf - file -``` -and that generated by -```text -tar -cf - file | gzip -``` - -The default should be to read and write archives to the standard I/O paths, -but tradition (and POSIX) dictates otherwise. - -The -'''r''' -and -'''u''' -modes require that the archive be uncompressed -and located in a regular file on disk. -Other archives can be modified using -'''c''' -mode with the -''@archive-file'' -extension. - -To archive a file called -''@foo'' -or -''-foo'' -you must specify it as -''./@foo'' -or -''./-foo'', -respectively. - -In create mode, a leading -''./'' -is always removed. -A leading -''/'' -is stripped unless the --P -option is specified. - -There needs to be better support for file selection on both create -and extract. - -There is not yet any support for multi-volume archives. - -Converting between dissimilar archive formats (such as tar and cpio) using the -'''@'''''-'' -convention can cause hard link information to be lost. -(This is a consequence of the incompatible ways that different archive -formats store hardlink information.) diff --git a/thirdparty/libarchive/doc/wiki/ManPageCpio5.wiki b/thirdparty/libarchive/doc/wiki/ManPageCpio5.wiki deleted file mode 100644 index a15d3c59f..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageCpio5.wiki +++ /dev/null @@ -1,363 +0,0 @@ -CPIO(5) manual page -== NAME == -'''cpio''' -- format of cpio archive files -== DESCRIPTION == -The -'''cpio''' -archive format collects any number of files, directories, and other -file system objects (symbolic links, device nodes, etc.) into a single -stream of bytes. -=== General Format=== -Each file system object in a -'''cpio''' -archive comprises a header record with basic numeric metadata -followed by the full pathname of the entry and the file data. -The header record stores a series of integer values that generally -follow the fields in -''struct'' stat. -(See -[[stat(2)|http://www.freebsd.org/cgi/man.cgi?query=stat&sektion=2]] -for details.) -The variants differ primarily in how they store those integers -(binary, octal, or hexadecimal). -The header is followed by the pathname of the -entry (the length of the pathname is stored in the header) -and any file data. -The end of the archive is indicated by a special record with -the pathname -"TRAILER!!!". -=== PWB format=== -The PWB binary -'''cpio''' -format is the original format, when cpio was introduced as part of the -Programmer's Work Bench system, a variant of 6th Edition UNIX. It -stores numbers as 2-byte and 4-byte binary values. -Each entry begins with a header in the following format: - -```text -struct header_pwb_cpio { - short h_magic; - short h_dev; - short h_ino; - short h_mode; - short h_uid; - short h_gid; - short h_nlink; - short h_majmin; - long h_mtime; - short h_namesize; - long h_filesize; -}; -``` - -The -''short'' -fields here are 16-bit integer values, while the -''long'' -fields are 32 bit integers. Since PWB UNIX, like the 6th Edition UNIX -it was based on, only ran on PDP-11 computers, they -are in PDP-endian format, which has little-endian shorts, and -big-endian longs. That is, the long integer whose hexadecimal -representation is 0x12345678 would be stored in four successive bytes -as 0x34, 0x12, 0x78, 0x56. -The fields are as follows: -
    -
    ''h_magic''
    -The integer value octal 070707. -
    ''h_dev'', ''h_ino''
    -The device and inode numbers from the disk. -These are used by programs that read -'''cpio''' -archives to determine when two entries refer to the same file. -Programs that synthesize -'''cpio''' -archives should be careful to set these to distinct values for each entry. -
    ''h_mode''
    -The mode specifies both the regular permissions and the file type, and -it also holds a couple of bits that are irrelevant to the cpio format, -because the field is actually a raw copy of the mode field in the inode -representing the file. These are the IALLOC flag, which shows that -the inode entry is in use, and the ILARG flag, which shows that the -file it represents is large enough to have indirect blocks pointers in -the inode. -The mode is decoded as follows: - -
    -
    0100000
    -IALLOC flag - irrelevant to cpio. -
    0060000
    -This masks the file type bits. -
    0040000
    -File type value for directories. -
    0020000
    -File type value for character special devices. -
    0060000
    -File type value for block special devices. -
    0010000
    -ILARG flag - irrelevant to cpio. -
    0004000
    -SUID bit. -
    0002000
    -SGID bit. -
    0001000
    -Sticky bit. -
    0000777
    -The lower 9 bits specify read/write/execute permissions -for world, group, and user following standard POSIX conventions. -
    -
    ''h_uid'', ''h_gid''
    -The numeric user id and group id of the owner. -
    ''h_nlink''
    -The number of links to this file. -Directories always have a value of at least two here. -Note that hardlinked files include file data with every copy in the archive. -
    ''h_majmin''
    -For block special and character special entries, -this field contains the associated device number, with the major -number in the high byte, and the minor number in the low byte. -For all other entry types, it should be set to zero by writers -and ignored by readers. -
    ''h_mtime''
    -Modification time of the file, indicated as the number -of seconds since the start of the epoch, -00:00:00 UTC January 1, 1970. -
    ''h_namesize''
    -The number of bytes in the pathname that follows the header. -This count includes the trailing NUL byte. -
    ''h_filesize''
    -The size of the file. Note that this archive format is limited to 16 -megabyte file sizes, because PWB UNIX, like 6th Edition, only used -an unsigned 24 bit integer for the file size internally. -
    - -The pathname immediately follows the fixed header. -If -'''h_namesize''' -is odd, an additional NUL byte is added after the pathname. -The file data is then appended, again with an additional NUL -appended if needed to get the next header at an even offset. - -Hardlinked files are not given special treatment; -the full file contents are included with each copy of the -file. -=== New Binary Format=== -The new binary -'''cpio''' -format showed up when cpio was adopted into late 7th Edition UNIX. -It is exactly like the PWB binary format, described above, except for -three changes: - -First, UNIX now ran on more than one hardware type, so the endianness -of 16 bit integers must be determined by observing the magic number at -the start of the header. The 32 bit integers are still always stored -with the most significant word first, though, so each of those two, in -the struct shown above, was stored as an array of two 16 bit integers, -in the traditional order. Those 16 bit integers, like all the others -in the struct, were accessed using a macro that byte swapped them if -necessary. - -Next, 7th Edition had more file types to store, and the IALLOC and ILARG -flag bits were re-purposed to accommodate these. The revised use of the -various bits is as follows: - -
    -
    0170000
    -This masks the file type bits. -
    0140000
    -File type value for sockets. -
    0120000
    -File type value for symbolic links. -For symbolic links, the link body is stored as file data. -
    0100000
    -File type value for regular files. -
    0060000
    -File type value for block special devices. -
    0040000
    -File type value for directories. -
    0020000
    -File type value for character special devices. -
    0010000
    -File type value for named pipes or FIFOs. -
    0004000
    -SUID bit. -
    0002000
    -SGID bit. -
    0001000
    -Sticky bit. -
    0000777
    -The lower 9 bits specify read/write/execute permissions -for world, group, and user following standard POSIX conventions. -
    - -Finally, the file size field now represents a signed 32 bit integer in -the underlying file system, so the maximum file size has increased to -2 gigabytes. - -Note that there is no obvious way to tell which of the two binary -formats an archive uses, other than to see which one makes more -sense. The typical error scenario is that a PWB format archive -unpacked as if it were in the new format will create named sockets -instead of directories, and then fail to unpack files that should -go in those directories. Running -''bsdcpio'' -itv -on an unknown archive will make it obvious which it is: if it's -PWB format, directories will be listed with an 's' instead of -a 'd' as the first character of the mode string, and the larger -files will have a '?' in that position. -=== Portable ASCII Format=== -Version 2 of the Single UNIX Specification (``SUSv2'') -standardized an ASCII variant that is portable across all -platforms. -It is commonly known as the -"old character" -format or as the -"odc" -format. -It stores the same numeric fields as the old binary format, but -represents them as 6-character or 11-character octal values. - -```text -struct cpio_odc_header { - char c_magic[6]; - char c_dev[6]; - char c_ino[6]; - char c_mode[6]; - char c_uid[6]; - char c_gid[6]; - char c_nlink[6]; - char c_rdev[6]; - char c_mtime[11]; - char c_namesize[6]; - char c_filesize[11]; -}; -``` - -The fields are identical to those in the new binary format. -The name and file body follow the fixed header. -Unlike the binary formats, there is no additional padding -after the pathname or file contents. -If the files being archived are themselves entirely ASCII, then -the resulting archive will be entirely ASCII, except for the -NUL byte that terminates the name field. -=== New ASCII Format=== -The "new" ASCII format uses 8-byte hexadecimal fields for -all numbers and separates device numbers into separate fields -for major and minor numbers. - -```text -struct cpio_newc_header { - char c_magic[6]; - char c_ino[8]; - char c_mode[8]; - char c_uid[8]; - char c_gid[8]; - char c_nlink[8]; - char c_mtime[8]; - char c_filesize[8]; - char c_devmajor[8]; - char c_devminor[8]; - char c_rdevmajor[8]; - char c_rdevminor[8]; - char c_namesize[8]; - char c_check[8]; -}; -``` - -Except as specified below, the fields here match those specified -for the new binary format above. -
    -
    ''magic''
    -The string -"070701". -
    ''check''
    -This field is always set to zero by writers and ignored by readers. -See the next section for more details. -
    - -The pathname is followed by NUL bytes so that the total size -of the fixed header plus pathname is a multiple of four. -Likewise, the file data is padded to a multiple of four bytes. -Note that this format supports only 4 gigabyte files (unlike the -older ASCII format, which supports 8 gigabyte files). - -In this format, hardlinked files are handled by setting the -filesize to zero for each entry except the first one that -appears in the archive. -=== New CRC Format=== -The CRC format is identical to the new ASCII format described -in the previous section except that the magic field is set -to -"070702" -and the -''check'' -field is set to the sum of all bytes in the file data. -This sum is computed treating all bytes as unsigned values -and using unsigned arithmetic. -Only the least-significant 32 bits of the sum are stored. -=== HP variants=== -The -'''cpio''' -implementation distributed with HPUX used XXXX but stored -device numbers differently XXX. -=== Other Extensions and Variants=== -Sun Solaris uses additional file types to store extended file -data, including ACLs and extended attributes, as special -entries in cpio archives. - -XXX Others? XXX -== SEE ALSO == -[[ManPageBsdcpio1]], -[[ManPageTar5]] -== STANDARDS == -The -'''cpio''' -utility is no longer a part of POSIX or the Single Unix Standard. -It last appeared in -Version 2 of the Single UNIX Specification (``SUSv2''). -It has been supplanted in subsequent standards by -[[pax(1)|http://www.freebsd.org/cgi/man.cgi?query=pax&sektion=1]]. -The portable ASCII format is currently part of the specification for the -[[pax(1)|http://www.freebsd.org/cgi/man.cgi?query=pax&sektion=1]] -utility. -== HISTORY == -The original cpio utility was written by Dick Haight -while working in AT&T's Unix Support Group. -It appeared in 1977 as part of PWB/UNIX 1.0, the -"Programmer's Work Bench" -derived from -At v6 -that was used internally at AT&T. -Both the new binary and old character formats were in use -by 1980, according to the System III source released -by SCO under their -"Ancient Unix" -license. -The character format was adopted as part of -IEEE Std 1003.1-1988 (``POSIX.1''). -XXX when did "newc" appear? Who invented it? When did HP come out with their variant? When did Sun introduce ACLs and extended attributes? XXX -== BUGS == -The -"CRC" -format is mis-named, as it uses a simple checksum and -not a cyclic redundancy check. - -The binary formats are limited to 16 bits for user id, group id, -device, and inode numbers. They are limited to 16 megabyte and 2 -gigabyte file sizes for the older and newer variants, respectively. - -The old ASCII format is limited to 18 bits for -the user id, group id, device, and inode numbers. -It is limited to 8 gigabyte file sizes. - -The new ASCII format is limited to 4 gigabyte file sizes. - -None of the cpio formats store user or group names, -which are essential when moving files between systems with -dissimilar user or group numbering. - -Especially when writing older cpio variants, it may be necessary -to map actual device/inode values to synthesized values that -fit the available fields. -With very large filesystems, this may be necessary even for -the newer formats. diff --git a/thirdparty/libarchive/doc/wiki/ManPageLibarchive3.wiki b/thirdparty/libarchive/doc/wiki/ManPageLibarchive3.wiki deleted file mode 100644 index fa79427aa..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageLibarchive3.wiki +++ /dev/null @@ -1,267 +0,0 @@ -LIBARCHIVE(3) manual page -== NAME == -'''libarchive''' -- functions for reading and writing streaming archives -== OVERVIEW == -The -'''libarchive''' -library provides a flexible interface for reading and writing -archives in various formats such as tar and cpio. -'''libarchive''' -also supports reading and writing archives compressed using -various compression filters such as gzip and bzip2. -The library is inherently stream-oriented; readers serially iterate through -the archive, writers serially add things to the archive. -In particular, note that there is currently no built-in support for -random access nor for in-place modification. - -When reading an archive, the library automatically detects the -format and the compression. -The library currently has read support for: -
      -
    • -old-style tar archives, -
    • -most variants of the POSIX -"ustar" -format, -
    • -the POSIX -"pax interchange" -format, -
    • -GNU-format tar archives, -
    • -most common cpio archive formats, -
    • -7-Zip archives, -
    • -ar archives (including GNU/SysV and BSD extensions), -
    • -Microsoft CAB archives, -
    • -ISO9660 CD images (including RockRidge and Joliet extensions), -
    • -LHA archives, -
    • -mtree file tree descriptions, -
    • -RAR and most RAR5 archives, -
    • -WARC archives, -
    • -XAR archives, -
    • -Zip archives. -
    -The library automatically detects archives compressed with -[[compress(1)|http://www.freebsd.org/cgi/man.cgi?query=compress&sektion=1]], -[[bzip2(1)|http://www.freebsd.org/cgi/man.cgi?query=bzip2&sektion=1]], -[[grzip(1)|http://www.freebsd.org/cgi/man.cgi?query=grzip&sektion=1]], -[[gzip(1)|http://www.freebsd.org/cgi/man.cgi?query=gzip&sektion=1]], -[[lrzip(1)|http://www.freebsd.org/cgi/man.cgi?query=lrzip&sektion=1]], -[[lz4(1)|http://www.freebsd.org/cgi/man.cgi?query=lz4&sektion=1]], -[[lzip(1)|http://www.freebsd.org/cgi/man.cgi?query=lzip&sektion=1]], -[[lzop(1)|http://www.freebsd.org/cgi/man.cgi?query=lzop&sektion=1]], -[[xz(1)|http://www.freebsd.org/cgi/man.cgi?query=xz&sektion=1]], -or -[[zstd(1)|http://www.freebsd.org/cgi/man.cgi?query=zstd&sektion=1]] -and decompresses them transparently. Decompression of some formats -requires external decompressor utilities. -It can similarly detect and decode archives processed with -[[uuencode(1)|http://www.freebsd.org/cgi/man.cgi?query=uuencode&sektion=1]] -or which have an -[[rpm(1)|http://www.freebsd.org/cgi/man.cgi?query=rpm&sektion=1]] -header. - -When writing an archive, you can specify the compression -to be used and the format to use. -The library can write -
      -
    • -POSIX-standard -"ustar" -archives, -
    • -POSIX -"pax interchange format" -archives, -
    • -cpio archives, -
    • -7-Zip archives, -
    • -ar archives, -
    • -two different variants of shar archives, -
    • -ISO9660 CD images, -
    • -mtree file tree descriptions, -
    • -XAR archives, -
    • -Zip archive. -
    -Pax interchange format is an extension of the tar archive format that -eliminates essentially all of the limitations of historic tar formats -in a standard fashion that is supported -by POSIX-compliant -[[pax(1)|http://www.freebsd.org/cgi/man.cgi?query=pax&sektion=1]] -implementations on many systems as well as several newer implementations of -[[ManPageBsdtar1]]. -Note that the default write format will suppress the pax extended -attributes for most entries; explicitly requesting pax format will -enable those attributes for all entries. - -The read and write APIs are accessed through the -'''archive_read_XXX'''() -functions and the -'''archive_write_XXX'''() -functions, respectively, and either can be used independently -of the other. - -The rest of this manual page provides an overview of the library -operation. -More detailed information can be found in the individual manual -pages for each API or utility function. -== READING AN ARCHIVE == -See -[[ManPageArchiveRead3]]. -== WRITING AN ARCHIVE == -See -[[ManPageArchiveWrite3]]. -== WRITING ENTRIES TO DISK == -The -[[ManPageArchiveWriteDisk3]] -API allows you to write -[[ManPageArchiveEntry3]] -objects to disk using the same API used by -[[ManPageArchiveWrite3]]. -The -[[ManPageArchiveWriteDisk3]] -API is used internally by -'''archive_read_extract'''('';'') -using it directly can provide greater control over how entries -get written to disk. -This API also makes it possible to share code between -archive-to-archive copy and archive-to-disk extraction -operations. -== READING ENTRIES FROM DISK == -The -[[ManPageArchiveReadDisk3]] -supports for populating -[[ManPageArchiveEntry3]] -objects from information in the filesystem. -This includes the information accessible from the -[[stat(2)|http://www.freebsd.org/cgi/man.cgi?query=stat&sektion=2]] -system call as well as ACLs, extended attributes, -and other metadata. -The -[[ManPageArchiveReadDisk3]] -API also supports iterating over directory trees, -which allows directories of files to be read using -an API compatible with -the -[[ManPageArchiveRead3]] -API. -== DESCRIPTION == -Detailed descriptions of each function are provided by the -corresponding manual pages. - -All of the functions utilize an opaque -'''struct archive''' -datatype that provides access to the archive contents. - -The -'''struct archive_entry''' -structure contains a complete description of a single archive -entry. -It uses an opaque interface that is fully documented in -[[ManPageArchiveEntry3]]. - -Users familiar with historic formats should be aware that the newer -variants have eliminated most restrictions on the length of textual fields. -Clients should not assume that filenames, link names, user names, or -group names are limited in length. -In particular, pax interchange format can easily accommodate pathnames -in arbitrary character sets that exceed -''PATH_MAX''. -== RETURN VALUES == -Most functions return -'''ARCHIVE_OK''' -(zero) on success, non-zero on error. -The return value indicates the general severity of the error, ranging -from -'''ARCHIVE_WARN''', -which indicates a minor problem that should probably be reported -to the user, to -'''ARCHIVE_FATAL''', -which indicates a serious problem that will prevent any further -operations on this archive. -On error, the -'''archive_errno'''() -function can be used to retrieve a numeric error code (see -[[errno(2)|http://www.freebsd.org/cgi/man.cgi?query=errno&sektion=2]]). -The -'''archive_error_string'''() -returns a textual error message suitable for display. - -'''archive_read_new'''() -and -'''archive_write_new'''() -return pointers to an allocated and initialized -'''struct archive''' -object. - -'''archive_read_data'''() -and -'''archive_write_data'''() -return a count of the number of bytes actually read or written. -A value of zero indicates the end of the data for this entry. -A negative value indicates an error, in which case the -'''archive_errno'''() -and -'''archive_error_string'''() -functions can be used to obtain more information. -== ENVIRONMENT == -There are character set conversions within the -[[ManPageArchiveEntry3]] -functions that are impacted by the currently-selected locale. -== SEE ALSO == -[[ManPageBsdtar1]], -[[ManPageArchiveEntry3]], -[[ManPageArchiveRead3]], -[[ManPageArchiveUtil3]], -[[ManPageArchiveWrite3]], -[[ManPageTar5]] -== HISTORY == -The -'''libarchive''' -library first appeared in -FreeBSD 5.3. -== AUTHORS == -The -'''libarchive''' -library was originally written by -Tim Kientzle <kientzle@acm.org.> -== BUGS == -Some archive formats support information that is not supported by -'''struct archive_entry .''' -Such information cannot be fully archived or restored using this library. -This includes, for example, comments, character sets, -or the arbitrary key/value pairs that can appear in -pax interchange format archives. - -Conversely, of course, not all of the information that can be -stored in an -'''struct archive_entry''' -is supported by all formats. -For example, cpio formats do not support nanosecond timestamps; -old tar formats do not support large device numbers. - -The ISO9660 reader cannot yet read all ISO9660 images; -it should learn how to seek. - -The AR writer requires the client program to use -two passes, unlike all other libarchive writers. diff --git a/thirdparty/libarchive/doc/wiki/ManPageLibarchiveChanges3.wiki b/thirdparty/libarchive/doc/wiki/ManPageLibarchiveChanges3.wiki deleted file mode 100644 index 2f851d5b6..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageLibarchiveChanges3.wiki +++ /dev/null @@ -1,303 +0,0 @@ -LIBARCHIVE_CHANGES(3) manual page -== NAME == -'''libarchive_changes''' -- changes in libarchive interface -== CHANGES IN LIBARCHIVE 3 == -This page describes user-visible changes in libarchive3, and lists -public functions and other symbols changed, deprecated or removed -in libarchive3, along with their replacements if any. -=== Multiple Filters=== -Libarchive2 permitted a single (input or output) filter active -on an archive. -Libarchive3 extends this into a variable-length stack. -Where -'''archive_write_set_compression_XXX'''() -would replace any existing filter, -'''archive_write_add_filter_XXX'''() -extends the write pipeline with another filter. -=== Character Set Handling=== -Libarchive2 assumed that the local platform uses -'''Unicode''' -as the native -'''wchar_t''' -encoding, which is true on -'''Windows ,''' -modern -'''Linux ,''' -and a few other systems, but is certainly not universal. -As a result, pax format archives were written incorrectly on some -systems, since pax format requires -'''UTF-8''' -and libarchive 2 incorrectly -assumed that -'''wchar_t''' -strings can be easily converted to -'''UTF-8 .''' - -Libarchive3 uses the standard iconv library to convert between character -sets and is introducing the notion of a -"default character set for the archive". -To support this, -'''archive_entry''' -objects can now be bound to a particular archive when they are created. -The automatic character set conversions performed by -'''archive_entry''' -objects when reading and writing filenames, usernames, and other strings -will now use an appropriate default character set: - -If the -'''archive_entry''' -object is bound to an archive, it will use the -default character set for that archive. - -The platform default character encoding (as returned by -'''nl_langinfo'''(''CHARSET'', '')'') -will be used if nothing else is specified. - -Libarchive3 also introduces charset options to many of the archive -readers and writers to control the character set that will be used for -filenames written in those archives. -When possible, this will be set automatically based on information in -the archive itself. -Combining this with the notion of a default character set for the -archive should allow you to configure libarchive to read archives from -other platforms and have the filenames and other information -transparently converted to the character encoding suitable for your -application. -=== Prototype Changes=== -These changes break binary compatibility; libarchive3 has a new shared -library version to reflect these changes. -The library now uses portable wide types such as -'''int64_t''' -instead of less-portable types such as -'''off_t ,''' -'''gid_t ,''' -'''uid_t ,''' -and -'''ino_t .''' - -There are a few cases where these changes will affect your source code: -
      -
    • -In some cases, libarchive's wider types will introduce the possibility -of truncation: for example, on a system with a 16-bit -'''uid_t , you risk having uid''' -```text -65536 -``` -be truncated to uid -```text -0, -``` -which can cause serious security problems. -
    • -Typedef function pointer types will be incompatible. -For example, if you define custom skip callbacks, you may have to use -code similar to the following if you want to support building against -libarchive2 and libarchive3: -```text -#if ARCHIVE_VERSION_NUMBER < 3000000 -typedef off_t myoff_t; -#else -typedef int64_t myoff_t; -#endif -myoff_t -my_skip_function(struct archive *a, void *v, myoff_t o) -{ - ... implementation ... -} -``` -
    - -Affected functions: - -
      -
    • -'''archive_entry_gid'''(), -'''archive_entry_set_gid'''() -
    • -'''archive_entry_uid'''(), -'''archive_entry_set_uid'''() -
    • -'''archive_entry_ino'''(), -'''archive_entry_set_ino'''() -
    • -'''archive_read_data_block'''(), -'''archive_write_data_block'''() -
    • -'''archive_read_disk_gname'''(), -'''archive_read_disk_uname'''() -
    • -'''archive_read_disk_set_gname_lookup'''(), -'''archive_read_disk_set_group_lookup'''(), -'''archive_read_disk_set_uname_lookup'''(), -'''archive_read_disk_set_user_lookup'''() -
    • -'''archive_skip_callback'''() -
    • -'''archive_read_extract_set_skip_file'''(), -'''archive_write_disk_set_skip_file'''(), -'''archive_write_set_skip_file'''() -
    • -'''archive_write_disk_set_group_lookup'''(), -'''archive_write_disk_set_user_lookup'''() -
    - -Where these functions or their arguments took or returned -'''gid_t ,''' -'''ino_t ,''' -'''off_t ,''' -or -'''uid_t''' -they now take or return -'''int64_t''' -or equivalent. -=== Deprecated Symbols=== -Symbols deprecated in libarchive3 will be removed in libarchive4. -These symbols, along with their replacements if any, are listed below: -
    -
    '''archive_position_compressed'''(), '''archive_position_uncompressed'''()
    -'''archive_filter_bytes'''() -
    '''archive_compression'''()
    -'''archive_filter_code'''() -
    '''archive_compression_name'''()
    -'''archive_filter_name'''() -
    '''archive_read_finish'''(), '''archive_write_finish'''()
    -'''archive_read_free'''(), -'''archive_write_free'''() -
    '''archive_read_open_file'''(), '''archive_write_open_file'''()
    -'''archive_read_open_filename'''(), -'''archive_write_open_filename'''() -
    '''archive_read_support_compression_all'''()
    -'''archive_read_support_filter_all'''() -
    '''archive_read_support_compression_bzip2'''()
    -'''archive_read_support_filter_bzip2'''() -
    '''archive_read_support_compression_compress'''()
    -'''archive_read_support_filter_compress'''() -
    '''archive_read_support_compression_gzip'''()
    -'''archive_read_support_filter_gzip'''() -
    '''archive_read_support_compression_lzip'''()
    -'''archive_read_support_filter_lzip'''() -
    '''archive_read_support_compression_lzma'''()
    -'''archive_read_support_filter_lzma'''() -
    '''archive_read_support_compression_none'''()
    -'''archive_read_support_filter_none'''() -
    '''archive_read_support_compression_program'''()
    -'''archive_read_support_filter_program'''() -
    '''archive_read_support_compression_program_signature'''()
    -'''archive_read_support_filter_program_signature'''() -
    '''archive_read_support_compression_rpm'''()
    -'''archive_read_support_filter_rpm'''() -
    '''archive_read_support_compression_uu'''()
    -'''archive_read_support_filter_uu'''() -
    '''archive_read_support_compression_xz'''()
    -'''archive_read_support_filter_xz'''() -
    '''archive_write_set_compression_bzip2'''()
    -'''archive_write_add_filter_bzip2'''() -
    '''archive_write_set_compression_compress'''()
    -'''archive_write_add_filter_compress'''() -
    '''archive_write_set_compression_gzip'''()
    -'''archive_write_add_filter_gzip'''() -
    '''archive_write_set_compression_lzip'''()
    -'''archive_write_add_filter_lzip'''() -
    '''archive_write_set_compression_lzma'''()
    -'''archive_write_add_filter_lzma'''() -
    '''archive_write_set_compression_none'''()
    -'''archive_write_add_filter_none'''() -
    '''archive_write_set_compression_program'''()
    -'''archive_write_add_filter_program'''() -
    '''archive_write_set_compression_filter'''()
    -'''archive_write_add_filter_filter'''() -
    -=== Removed Symbols=== -These symbols, listed below along with their replacements if any, -were deprecated in libarchive2, and are not part of libarchive3. -
    -
    '''archive_api_feature'''()
    -'''archive_version_number'''() -
    '''archive_api_version'''()
    -'''archive_version_number'''() -
    '''archive_version'''()
    -'''archive_version_string'''() -
    '''archive_version_stamp'''()
    -'''archive_version_number'''() -
    '''archive_read_set_filter_options'''()
    -'''archive_read_set_options'''() -or -'''archive_read_set_filter_option'''() -
    '''archive_read_set_format_options'''()
    -'''archive_read_set_options'''() -or -'''archive_read_set_format_option'''() -
    '''archive_write_set_filter_options'''()
    -'''archive_write_set_options'''() -or -'''archive_write_set_filter_option'''() -
    '''archive_write_set_format_options'''()
    -'''archive_write_set_options'''() -or -'''archive_write_set_format_option'''() -
    -ARCHIVE_API_FEATURE -ARCHIVE_VERSION_NUMBER -
    -ARCHIVE_API_VERSION -ARCHIVE_VERSION_NUMBER -
    -ARCHIVE_VERSION_STAMP -ARCHIVE_VERSION_NUMBER -
    -ARCHIVE_LIBRARY_VERSION -ARCHIVE_VERSION_STRING -
    -ARCHIVE_COMPRESSION_NONE -ARCHIVE_FILTER_NONE -
    -ARCHIVE_COMPRESSION_GZIP -ARCHIVE_FILTER_GZIP -
    -ARCHIVE_COMPRESSION_BZIP2 -ARCHIVE_FILTER_BZIP2 -
    -ARCHIVE_COMPRESSION_COMPRESS -ARCHIVE_FILTER_COMPRESS -
    -ARCHIVE_COMPRESSION_PROGRAM -ARCHIVE_FILTER_PROGRAM -
    -ARCHIVE_COMPRESSION_LZMA -ARCHIVE_FILTER_LZMA -
    -ARCHIVE_COMPRESSION_XZ -ARCHIVE_FILTER_XZ -
    -ARCHIVE_COMPRESSION_UU -ARCHIVE_FILTER_UU -
    -ARCHIVE_COMPRESSION_RPM -ARCHIVE_FILTER_RPM -
    -ARCHIVE_COMPRESSION_LZIP -ARCHIVE_FILTER_LZIP -
    -ARCHIVE_BYTES_PER_RECORD -```text -512 -``` -
    -ARCHIVE_DEFAULT_BYTES_PER_BLOCK -```text -10240 -``` -
    -== SEE ALSO == -[[ManPageArchiveRead3]], -[[ManPageArchiveReadFilter3]], -[[ManPageArchiveReadFormat3]], -[[ManPageArchiveReadSetOptions3]], -[[ManPageArchiveUtil3]], -[[ManPageArchiveWrite3]], -[[ManPageArchiveWriteFilter3]], -[[ManPageArchiveWriteFormat3]], -[[ManPageArchiveWriteSetOptions3]], -[[ManPageLibarchive3]] diff --git a/thirdparty/libarchive/doc/wiki/ManPageLibarchiveFormats5.wiki b/thirdparty/libarchive/doc/wiki/ManPageLibarchiveFormats5.wiki deleted file mode 100644 index 5414eba13..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageLibarchiveFormats5.wiki +++ /dev/null @@ -1,436 +0,0 @@ -LIBARCHIVE-FORMATS(5) manual page -== NAME == -'''libarchive-formats''' -- archive formats supported by the libarchive library -== DESCRIPTION == -The -[[ManPageLibarchive3]] -library reads and writes a variety of streaming archive formats. -Generally speaking, all of these archive formats consist of a series of -"entries". -Each entry stores a single file system object, such as a file, directory, -or symbolic link. - -The following provides a brief description of each format supported -by libarchive, with some information about recognized extensions or -limitations of the current library support. -Note that just because a format is supported by libarchive does not -imply that a program that uses libarchive will support that format. -Applications that use libarchive specify which formats they wish -to support, though many programs do use libarchive convenience -functions to enable all supported formats. -=== Tar Formats=== -The -[[ManPageLibarchive3]] -library can read most tar archives. -It can write POSIX-standard -"ustar" -and -"pax interchange" -formats as well as v7 tar format and a subset of the legacy GNU tar format. - -All tar formats store each entry in one or more 512-byte records. -The first record is used for file metadata, including filename, -timestamp, and mode information, and the file data is stored in -subsequent records. -Later variants have extended this by either appropriating undefined -areas of the header record, extending the header to multiple records, -or by storing special entries that modify the interpretation of -subsequent entries. -
    -
    '''gnutar'''
    -The -[[ManPageLibarchive3]] -library can read most GNU-format tar archives. -It currently supports the most popular GNU extensions, including -modern long filename and linkname support, as well as atime and ctime data. -The libarchive library does not support multi-volume -archives, nor the old GNU long filename format. -It can read GNU sparse file entries, including the new POSIX-based -formats. - -The -[[ManPageLibarchive3]] -library can write GNU tar format, including long filename -and linkname support, as well as atime and ctime data. -
    '''pax'''
    -The -[[ManPageLibarchive3]] -library can read and write POSIX-compliant pax interchange format -archives. -Pax interchange format archives are an extension of the older ustar -format that adds a separate entry with additional attributes stored -as key/value pairs immediately before each regular entry. -The presence of these additional entries is the only difference between -pax interchange format and the older ustar format. -The extended attributes are of unlimited length and are stored -as UTF-8 Unicode strings. -Keywords defined in the standard are in all lowercase; vendors are allowed -to define custom keys by preceding them with the vendor name in all uppercase. -When writing pax archives, libarchive uses many of the SCHILY keys -defined by Joerg Schilling's -"star" -archiver and a few LIBARCHIVE keys. -The libarchive library can read most of the SCHILY keys -and most of the GNU keys introduced by GNU tar. -It silently ignores any keywords that it does not understand. - -The pax interchange format converts filenames to Unicode -and stores them using the UTF-8 encoding. -Prior to libarchive 3.0, libarchive erroneously assumed -that the system wide-character routines natively supported -Unicode. -This caused it to mis-handle non-ASCII filenames on systems -that did not satisfy this assumption. -
    '''restricted''' pax
    -The libarchive library can also write pax archives in which it -attempts to suppress the extended attributes entry whenever -possible. -The result will be identical to a ustar archive unless the -extended attributes entry is required to store a long file -name, long linkname, extended ACL, file flags, or if any of the standard -ustar data (user name, group name, UID, GID, etc) cannot be fully -represented in the ustar header. -In all cases, the result can be dearchived by any program that -can read POSIX-compliant pax interchange format archives. -Programs that correctly read ustar format (see below) will also be -able to read this format; any extended attributes will be extracted as -separate files stored in -''PaxHeader'' -directories. -
    '''ustar'''
    -The libarchive library can both read and write this format. -This format has the following limitations: -
      -
    • -Device major and minor numbers are limited to 21 bits. -Nodes with larger numbers will not be added to the archive. -
    • -Path names in the archive are limited to 255 bytes. -(Shorter if there is no / character in exactly the right place.) -
    • -Symbolic links and hard links are stored in the archive with -the name of the referenced file. -This name is limited to 100 bytes. -
    • -Extended attributes, file flags, and other extended -security information cannot be stored. -
    • -Archive entries are limited to 8 gigabytes in size. -
    -Note that the pax interchange format has none of these restrictions. -The ustar format is old and widely supported. -It is recommended when compatibility is the primary concern. -
    '''v7'''
    -The libarchive library can read and write the legacy v7 tar format. -This format has the following limitations: -
      -
    • -Only regular files, directories, and symbolic links can be archived. -Block and character device nodes, FIFOs, and sockets cannot be archived. -
    • -Path names in the archive are limited to 100 bytes. -
    • -Symbolic links and hard links are stored in the archive with -the name of the referenced file. -This name is limited to 100 bytes. -
    • -User and group information are stored as numeric IDs; there -is no provision for storing user or group names. -
    • -Extended attributes, file flags, and other extended -security information cannot be stored. -
    • -Archive entries are limited to 8 gigabytes in size. -
    -Generally, users should prefer the ustar format for portability -as the v7 tar format is both less useful and less portable. -
    - -The libarchive library also reads a variety of commonly-used extensions to -the basic tar format. -These extensions are recognized automatically whenever they appear. -
    -
    Numeric extensions.
    -The POSIX standards require fixed-length numeric fields to be written with -some character position reserved for terminators. -Libarchive allows these fields to be written without terminator characters. -This extends the allowable range; in particular, ustar archives with this -extension can support entries up to 64 gigabytes in size. -Libarchive also recognizes base-256 values in most numeric fields. -This essentially removes all limitations on file size, modification time, -and device numbers. -
    Solaris extensions
    -Libarchive recognizes ACL and extended attribute records written -by Solaris tar. -
    - -The first tar program appeared in Seventh Edition Unix in 1979. -The first official standard for the tar file format was the -"ustar" -(Unix Standard Tar) format defined by POSIX in 1988. -POSIX.1-2001 extended the ustar format to create the -"pax interchange" -format. -=== Cpio Formats=== -The libarchive library can read and write a number of common cpio -variants. A cpio archive stores each entry as a fixed-size header -followed by a variable-length filename and variable-length data. -Unlike the tar format, the cpio format does only minimal padding of -the header or file data. There are several cpio variants, which -differ primarily in how they store the initial header: some store the -values as octal or hexadecimal numbers in ASCII, others as binary -values of varying byte order and length. -
    -
    '''binary'''
    -The libarchive library transparently reads both big-endian and -little-endian variants of the the two binary cpio formats; the -original one from PWB/UNIX, and the later, more widely used, variant. -This format used 32-bit binary values for file size and mtime, and -16-bit binary values for the other fields. The formats support only -the file types present in UNIX at the time of their creation. File -sizes are limited to 24 bits in the PWB format, because of the limits -of the file system, and to 31 bits in the newer binary format, where -signed 32 bit longs were used. -
    '''odc'''
    -This is the POSIX standardized format, which is officially known as the -"cpio interchange format" -or the -"octet-oriented cpio archive format" -and sometimes unofficially referred to as the -"old character format". -This format stores the header contents as octal values in ASCII. -It is standard, portable, and immune from byte-order confusion. -File sizes and mtime are limited to 33 bits (8GB file size), -other fields are limited to 18 bits. -
    '''SVR4/newc'''
    -The libarchive library can read both CRC and non-CRC variants of -this format. -The SVR4 format uses eight-digit hexadecimal values for -all header fields. -This limits file size to 4GB, and also limits the mtime and -other fields to 32 bits. -The SVR4 format can optionally include a CRC of the file -contents, although libarchive does not currently verify this CRC. -
    - -Cpio first appeared in PWB/UNIX 1.0, which was released within -AT&T in 1977. -PWB/UNIX 1.0 formed the basis of System III Unix, released outside -of AT&T in 1981. -This makes cpio older than tar, although cpio was not included -in Version 7 AT&T Unix. -As a result, the tar command became much better known in universities -and research groups that used Version 7. -The combination of the -'''find''' -and -'''cpio''' -utilities provided very precise control over file selection. -Unfortunately, the format has many limitations that make it unsuitable -for widespread use. -Only the POSIX format permits files over 4GB, and its 18-bit -limit for most other fields makes it unsuitable for modern systems. -In addition, cpio formats only store numeric UID/GID values (not -usernames and group names), which can make it very difficult to correctly -transfer archives across systems with dissimilar user numbering. -=== Shar Formats=== -A -"shell archive" -is a shell script that, when executed on a POSIX-compliant -system, will recreate a collection of file system objects. -The libarchive library can write two different kinds of shar archives: -
    -
    '''shar'''
    -The traditional shar format uses a limited set of POSIX -commands, including -[[echo(1)|http://www.freebsd.org/cgi/man.cgi?query=echo&sektion=1]], -[[mkdir(1)|http://www.freebsd.org/cgi/man.cgi?query=mkdir&sektion=1]], -and -[[sed(1)|http://www.freebsd.org/cgi/man.cgi?query=sed&sektion=1]]. -It is suitable for portably archiving small collections of plain text files. -However, it is not generally well-suited for large archives -(many implementations of -[[sh(1)|http://www.freebsd.org/cgi/man.cgi?query=sh&sektion=1]] -have limits on the size of a script) nor should it be used with non-text files. -
    '''shardump'''
    -This format is similar to shar but encodes files using -[[uuencode(1)|http://www.freebsd.org/cgi/man.cgi?query=uuencode&sektion=1]] -so that the result will be a plain text file regardless of the file contents. -It also includes additional shell commands that attempt to reproduce as -many file attributes as possible, including owner, mode, and flags. -The additional commands used to restore file attributes make -shardump archives less portable than plain shar archives. -
    -=== ISO9660 format=== -Libarchive can read and extract from files containing ISO9660-compliant -CDROM images. -In many cases, this can remove the need to burn a physical CDROM -just in order to read the files contained in an ISO9660 image. -It also avoids security and complexity issues that come with -virtual mounts and loopback devices. -Libarchive supports the most common Rockridge extensions and has partial -support for Joliet extensions. -If both extensions are present, the Joliet extensions will be -used and the Rockridge extensions will be ignored. -In particular, this can create problems with hardlinks and symlinks, -which are supported by Rockridge but not by Joliet. - -Libarchive reads ISO9660 images using a streaming strategy. -This allows it to read compressed images directly -(decompressing on the fly) and allows it to read images -directly from network sockets, pipes, and other non-seekable -data sources. -This strategy works well for optimized ISO9660 images created -by many popular programs. -Such programs collect all directory information at the beginning -of the ISO9660 image so it can be read from a physical disk -with a minimum of seeking. -However, not all ISO9660 images can be read in this fashion. - -Libarchive can also write ISO9660 images. -Such images are fully optimized with the directory information -preceding all file data. -This is done by storing all file data to a temporary file -while collecting directory information in memory. -When the image is finished, libarchive writes out the -directory structure followed by the file data. -The location used for the temporary file can be changed -by the usual environment variables. -=== Zip format=== -Libarchive can read and write zip format archives that have -uncompressed entries and entries compressed with the -"deflate" -algorithm. -Other zip compression algorithms are not supported. -It can extract jar archives, archives that use Zip64 extensions and -self-extracting zip archives. -Libarchive can use either of two different strategies for -reading Zip archives: -a streaming strategy which is fast and can handle extremely -large archives, and a seeking strategy which can correctly -process self-extracting Zip archives and archives with -deleted members or other in-place modifications. - -The streaming reader processes Zip archives as they are read. -It can read archives of arbitrary size from tape or -network sockets, and can decode Zip archives that have -been separately compressed or encoded. -However, self-extracting Zip archives and archives with -certain types of modifications cannot be correctly -handled. -Such archives require that the reader first process the -Central Directory, which is ordinarily located -at the end of a Zip archive and is thus inaccessible -to the streaming reader. -If the program using libarchive has enabled seek support, then -libarchive will use this to processes the central directory first. - -In particular, the seeking reader must be used to -correctly handle self-extracting archives. -Such archives consist of a program followed by a regular -Zip archive. -The streaming reader cannot parse the initial program -portion, but the seeking reader starts by reading the -Central Directory from the end of the archive. -Similarly, Zip archives that have been modified in-place -can have deleted entries or other garbage data that -can only be accurately detected by first reading the -Central Directory. -=== Archive (library) file format=== -The Unix archive format (commonly created by the -[[ar(1)|http://www.freebsd.org/cgi/man.cgi?query=ar&sektion=1]] -archiver) is a general-purpose format which is -used almost exclusively for object files to be -read by the link editor -[[ld(1)|http://www.freebsd.org/cgi/man.cgi?query=ld&sektion=1]]. -The ar format has never been standardised. -There are two common variants: -the GNU format derived from SVR4, -and the BSD format, which first appeared in 4.4BSD. -The two differ primarily in their handling of filenames -longer than 15 characters: -the GNU/SVR4 variant writes a filename table at the beginning of the archive; -the BSD format stores each long filename in an extension -area adjacent to the entry. -Libarchive can read both extensions, -including archives that may include both types of long filenames. -Programs using libarchive can write GNU/SVR4 format -if they provide an entry called -''//'' -containing a filename table to be written into the archive -before any of the entries. -Any entries whose names are not in the filename table -will be written using BSD-style long filenames. -This can cause problems for programs such as -GNU ld that do not support the BSD-style long filenames. -=== mtree=== -Libarchive can read and write files in -[[ManPageMtree5]] -format. -This format is not a true archive format, but rather a textual description -of a file hierarchy in which each line specifies the name of a file and -provides specific metadata about that file. -Libarchive can read all of the keywords supported by both -the NetBSD and FreeBSD versions of -[[mtree(8)|http://www.freebsd.org/cgi/man.cgi?query=mtree&sektion=8]], -although many of the keywords cannot currently be stored in an -'''archive_entry''' -object. -When writing, libarchive supports use of the -[[ManPageArchiveWriteSetOptions3]] -interface to specify which keywords should be included in the -output. -If libarchive was compiled with access to suitable -cryptographic libraries (such as the OpenSSL libraries), -it can compute hash entries such as -'''sha512''' -or -'''md5''' -from file data being written to the mtree writer. - -When reading an mtree file, libarchive will locate the corresponding -files on disk using the -'''contents''' -keyword if present or the regular filename. -If it can locate and open the file on disk, it will use that -to fill in any metadata that is missing from the mtree file -and will read the file contents and return those to the program -using libarchive. -If it cannot locate and open the file on disk, libarchive -will return an error for any attempt to read the entry -body. -=== 7-Zip=== -Libarchive can read and write 7-Zip format archives. -TODO: Need more information -=== CAB=== -Libarchive can read Microsoft Cabinet ( -"CAB )" -format archives. -TODO: Need more information. -=== LHA=== -TODO: Information about libarchive's LHA support -=== RAR=== -Libarchive has limited support for reading RAR format archives. -Currently, libarchive can read RARv3 format archives -which have been either created uncompressed, or compressed using -any of the compression methods supported by the RARv3 format. -Libarchive can also read self-extracting RAR archives. -=== Warc=== -Libarchive can read and write -"web archives". -TODO: Need more information -=== XAR=== -Libarchive can read and write the XAR format used by many Apple tools. -TODO: Need more information -== SEE ALSO == -[[ar(1)|http://www.freebsd.org/cgi/man.cgi?query=ar&sektion=1]], -[[ManPageBsdcpio1]], -[[mkisofs(1)|http://www.freebsd.org/cgi/man.cgi?query=mkisofs&sektion=1]], -[[shar(1)|http://www.freebsd.org/cgi/man.cgi?query=shar&sektion=1]], -[[ManPageBsdtar1]], -[[zip(1)|http://www.freebsd.org/cgi/man.cgi?query=zip&sektion=1]], -[[zlib(3)|http://www.freebsd.org/cgi/man.cgi?query=zlib&sektion=3]], -[[ManPageCpio5]], -[[ManPageMtree5]], -[[ManPageTar5]] diff --git a/thirdparty/libarchive/doc/wiki/ManPageLibarchiveInternals3.wiki b/thirdparty/libarchive/doc/wiki/ManPageLibarchiveInternals3.wiki deleted file mode 100644 index 086762f73..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageLibarchiveInternals3.wiki +++ /dev/null @@ -1,336 +0,0 @@ -LIBARCHIVE_INTERNALS(3) manual page -== NAME == -'''libarchive_internals''' -- description of libarchive internal interfaces -== OVERVIEW == -The -'''libarchive''' -library provides a flexible interface for reading and writing -streaming archive files such as tar and cpio. -Internally, it follows a modular layered design that should -make it easy to add new archive and compression formats. -== GENERAL ARCHITECTURE == -Externally, libarchive exposes most operations through an -opaque, object-style interface. -The -[[ManPageArchiveEntry3]] -objects store information about a single filesystem object. -The rest of the library provides facilities to write -[[ManPageArchiveEntry3]] -objects to archive files, -read them from archive files, -and write them to disk. -(There are plans to add a facility to read -[[ManPageArchiveEntry3]] -objects from disk as well.) - -The read and write APIs each have four layers: a public API -layer, a format layer that understands the archive file format, -a compression layer, and an I/O layer. -The I/O layer is completely exposed to clients who can replace -it entirely with their own functions. - -In order to provide as much consistency as possible for clients, -some public functions are virtualized. -Eventually, it should be possible for clients to open -an archive or disk writer, and then use a single set of -code to select and write entries, regardless of the target. -== READ ARCHITECTURE == -From the outside, clients use the -[[ManPageArchiveRead3]] -API to manipulate an -'''archive''' -object to read entries and bodies from an archive stream. -Internally, the -'''archive''' -object is cast to an -'''archive_read''' -object, which holds all read-specific data. -The API has four layers: -The lowest layer is the I/O layer. -This layer can be overridden by clients, but most clients use -the packaged I/O callbacks provided, for example, by -[[ManPageArchiveReadOpenMemory3]], -and -[[ManPageArchiveReadOpenFd3]]. -The compression layer calls the I/O layer to -read bytes and decompresses them for the format layer. -The format layer unpacks a stream of uncompressed bytes and -creates -'''archive_entry''' -objects from the incoming data. -The API layer tracks overall state -(for example, it prevents clients from reading data before reading a header) -and invokes the format and compression layer operations -through registered function pointers. -In particular, the API layer drives the format-detection process: -When opening the archive, it reads an initial block of data -and offers it to each registered compression handler. -The one with the highest bid is initialized with the first block. -Similarly, the format handlers are polled to see which handler -is the best for each archive. -(Prior to 2.4.0, the format bidders were invoked for each -entry, but this design hindered error recovery.) -=== I/O Layer and Client Callbacks=== -The read API goes to some lengths to be nice to clients. -As a result, there are few restrictions on the behavior of -the client callbacks. - -The client read callback is expected to provide a block -of data on each call. -A zero-length return does indicate end of file, but otherwise -blocks may be as small as one byte or as large as the entire file. -In particular, blocks may be of different sizes. - -The client skip callback returns the number of bytes actually -skipped, which may be much smaller than the skip requested. -The only requirement is that the skip not be larger. -In particular, clients are allowed to return zero for any -skip that they don't want to handle. -The skip callback must never be invoked with a negative value. - -Keep in mind that not all clients are reading from disk: -clients reading from networks may provide different-sized -blocks on every request and cannot skip at all; -advanced clients may use -[[mmap(2)|http://www.freebsd.org/cgi/man.cgi?query=mmap&sektion=2]] -to read the entire file into memory at once and return the -entire file to libarchive as a single block; -other clients may begin asynchronous I/O operations for the -next block on each request. -=== Decompresssion Layer=== -The decompression layer not only handles decompression, -it also buffers data so that the format handlers see a -much nicer I/O model. -The decompression API is a two stage peek/consume model. -A read_ahead request specifies a minimum read amount; -the decompression layer must provide a pointer to at least -that much data. -If more data is immediately available, it should return more: -the format layer handles bulk data reads by asking for a minimum -of one byte and then copying as much data as is available. - -A subsequent call to the -'''consume'''() -function advances the read pointer. -Note that data returned from a -'''read_ahead'''() -call is guaranteed to remain in place until -the next call to -'''read_ahead'''(). -Intervening calls to -'''consume'''() -should not cause the data to move. - -Skip requests must always be handled exactly. -Decompression handlers that cannot seek forward should -not register a skip handler; -the API layer fills in a generic skip handler that reads and discards data. - -A decompression handler has a specific lifecycle: -
    -
    Registration/Configuration
    -When the client invokes the public support function, -the decompression handler invokes the internal -'''__archive_read_register_compression'''() -function to provide bid and initialization functions. -This function returns -'''NULL''' -on error or else a pointer to a -'''struct''' decompressor_t. -This structure contains a -''void'' * config -slot that can be used for storing any customization information. -
    Bid
    -The bid function is invoked with a pointer and size of a block of data. -The decompressor can access its config data -through the -''decompressor'' -element of the -'''archive_read''' -object. -The bid function is otherwise stateless. -In particular, it must not perform any I/O operations. - -The value returned by the bid function indicates its suitability -for handling this data stream. -A bid of zero will ensure that this decompressor is never invoked. -Return zero if magic number checks fail. -Otherwise, your initial implementation should return the number of bits -actually checked. -For example, if you verify two full bytes and three bits of another -byte, bid 19. -Note that the initial block may be very short; -be careful to only inspect the data you are given. -(The current decompressors require two bytes for correct bidding.) -
    Initialize
    -The winning bidder will have its init function called. -This function should initialize the remaining slots of the -''struct'' decompressor_t -object pointed to by the -''decompressor'' -element of the -''archive_read'' -object. -In particular, it should allocate any working data it needs -in the -''data'' -slot of that structure. -The init function is called with the block of data that -was used for tasting. -At this point, the decompressor is responsible for all I/O -requests to the client callbacks. -The decompressor is free to read more data as and when -necessary. -
    Satisfy I/O requests
    -The format handler will invoke the -''read_ahead'', -''consume'', -and -''skip'' -functions as needed. -
    Finish
    -The finish method is called only once when the archive is closed. -It should release anything stored in the -''data'' -and -''config'' -slots of the -''decompressor'' -object. -It should not invoke the client close callback. -
    -=== Format Layer=== -The read formats have a similar lifecycle to the decompression handlers: -
    -
    Registration
    -Allocate your private data and initialize your pointers. -
    Bid
    -Formats bid by invoking the -'''read_ahead'''() -decompression method but not calling the -'''consume'''() -method. -This allows each bidder to look ahead in the input stream. -Bidders should not look further ahead than necessary, as long -look aheads put pressure on the decompression layer to buffer -lots of data. -Most formats only require a few hundred bytes of look ahead; -look aheads of a few kilobytes are reasonable. -(The ISO9660 reader sometimes looks ahead by 48k, which -should be considered an upper limit.) -
    Read header
    -The header read is usually the most complex part of any format. -There are a few strategies worth mentioning: -For formats such as tar or cpio, reading and parsing the header is -straightforward since headers alternate with data. -For formats that store all header data at the beginning of the file, -the first header read request may have to read all headers into -memory and store that data, sorted by the location of the file -data. -Subsequent header read requests will skip forward to the -beginning of the file data and return the corresponding header. -
    Read Data
    -The read data interface supports sparse files; this requires that -each call return a block of data specifying the file offset and -size. -This may require you to carefully track the location so that you -can return accurate file offsets for each read. -Remember that the decompressor will return as much data as it has. -Generally, you will want to request one byte, -examine the return value to see how much data is available, and -possibly trim that to the amount you can use. -You should invoke consume for each block just before you return it. -
    Skip All Data
    -The skip data call should skip over all file data and trailing padding. -This is called automatically by the API layer just before each -header read. -It is also called in response to the client calling the public -'''data_skip'''() -function. -
    Cleanup
    -On cleanup, the format should release all of its allocated memory. -
    -=== API Layer=== -XXX to do XXX -== WRITE ARCHITECTURE == -The write API has a similar set of four layers: -an API layer, a format layer, a compression layer, and an I/O layer. -The registration here is much simpler because only -one format and one compression can be registered at a time. -=== I/O Layer and Client Callbacks=== -XXX To be written XXX -=== Compression Layer=== -XXX To be written XXX -=== Format Layer=== -XXX To be written XXX -=== API Layer=== -XXX To be written XXX -== WRITE_DISK ARCHITECTURE == -The write_disk API is intended to look just like the write API -to clients. -Since it does not handle multiple formats or compression, it -is not layered internally. -== GENERAL SERVICES == -The -'''archive_read''', -'''archive_write''', -and -'''archive_write_disk''' -objects all contain an initial -'''archive''' -object which provides common support for a set of standard services. -(Recall that ANSI/ISO C90 guarantees that you can cast freely between -a pointer to a structure and a pointer to the first element of that -structure.) -The -'''archive''' -object has a magic value that indicates which API this object -is associated with, -slots for storing error information, -and function pointers for virtualized API functions. -== MISCELLANEOUS NOTES == -Connecting existing archiving libraries into libarchive is generally -quite difficult. -In particular, many existing libraries strongly assume that you -are reading from a file; they seek forwards and backwards as necessary -to locate various pieces of information. -In contrast, libarchive never seeks backwards in its input, which -sometimes requires very different approaches. - -For example, libarchive's ISO9660 support operates very differently -from most ISO9660 readers. -The libarchive support utilizes a work-queue design that -keeps a list of known entries sorted by their location in the input. -Whenever libarchive's ISO9660 implementation is asked for the next -header, checks this list to find the next item on the disk. -Directories are parsed when they are encountered and new -items are added to the list. -This design relies heavily on the ISO9660 image being optimized so that -directories always occur earlier on the disk than the files they -describe. - -Depending on the specific format, such approaches may not be possible. -The ZIP format specification, for example, allows archivers to store -key information only at the end of the file. -In theory, it is possible to create ZIP archives that cannot -be read without seeking. -Fortunately, such archives are very rare, and libarchive can read -most ZIP archives, though it cannot always extract as much information -as a dedicated ZIP program. -== SEE ALSO == -[[ManPageArchiveEntry3]], -[[ManPageArchiveRead3]], -[[ManPageArchiveWrite3]], -[[ManPageArchiveWriteDisk3]], -[[ManPageLibarchive3]] -== HISTORY == -The -'''libarchive''' -library first appeared in -FreeBSD 5.3. -== AUTHORS == -The -'''libarchive''' -library was written by -Tim Kientzle <kientzle@acm.org.> diff --git a/thirdparty/libarchive/doc/wiki/ManPageMtree5.wiki b/thirdparty/libarchive/doc/wiki/ManPageMtree5.wiki deleted file mode 100644 index c761e910e..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageMtree5.wiki +++ /dev/null @@ -1,292 +0,0 @@ -MTREE(5) manual page -== NAME == -'''mtree''' -- format of mtree dir hierarchy files -== DESCRIPTION == -The -'''mtree''' -format is a textual format that describes a collection of filesystem objects. -Such files are typically used to create or verify directory hierarchies. -=== General Format=== -An -'''mtree''' -file consists of a series of lines, each providing information -about a single filesystem object. -Leading whitespace is always ignored. - -When encoding file or pathnames, any backslash character or -character outside of the 95 printable ASCII characters must be -encoded as a backslash followed by three -octal digits. -When reading mtree files, any appearance of a backslash -followed by three octal digits should be converted into the -corresponding character. - -Each line is interpreted independently as one of the following types: -
    -
    Blank
    -Blank lines are ignored. -
    Comment
    -Lines beginning with -'''#''' -are ignored. -
    Special
    -Lines beginning with -'''/''' -are special commands that influence -the interpretation of later lines. -
    Relative
    -If the first whitespace-delimited word has no -'''/''' -characters, -it is the name of a file in the current directory. -Any relative entry that describes a directory changes the -current directory. -
    dot-dot
    -As a special case, a relative entry with the filename -''..'' -changes the current directory to the parent directory. -Options on dot-dot entries are always ignored. -
    Full
    -If the first whitespace-delimited word has a -'''/''' -character after -the first character, it is the pathname of a file relative to the -starting directory. -There can be multiple full entries describing the same file. -
    - -Some tools that process -'''mtree''' -files may require that multiple lines describing the same file -occur consecutively. -It is not permitted for the same file to be mentioned using -both a relative and a full file specification. -=== Special commands=== -Two special commands are currently defined: -
    -
    '''/set'''
    -This command defines default values for one or more keywords. -It is followed on the same line by one or more whitespace-separated -keyword definitions. -These definitions apply to all following files that do not specify -a value for that keyword. -
    '''/unset'''
    -This command removes any default value set by a previous -'''/set''' -command. -It is followed on the same line by one or more keywords -separated by whitespace. -
    -=== Keywords=== -After the filename, a full or relative entry consists of zero -or more whitespace-separated keyword definitions. -Each such definition consists of a key from the following -list immediately followed by an '=' sign -and a value. -Software programs reading mtree files should warn about -unrecognized keywords. - -Currently supported keywords are as follows: -
    -
    '''cksum'''
    -The checksum of the file using the default algorithm specified by -the -[[cksum(1)|http://www.freebsd.org/cgi/man.cgi?query=cksum&sektion=1]] -utility. -
    '''device'''
    -The device number for -.B block -or -.B char -file types. -The value must be one of the following forms: -
    -
    ''format'',''major'',''minor''Bo,''subunit'' Bc
    -A device with -''major'', minor -and optional -''subunit'' -fields. -Their meaning is specified by the operating's system -''format''. -See below for valid formats. -
    ''number''
    -Opaque number (as stored on the file system). -
    - -The following values for -''format'' -are recognized: -.B native , -.B 386bsd , -.B 4bsd , -.B bsdos , -.B freebsd , -.B hpux , -.B isc , -.B linux , -.B netbsd , -.B osf1 , -.B sco , -.B solaris , -.B sunos , -.B svr3 , -.B svr4 , -and -.B ultrix . - -See -[[mknod(8)|http://www.freebsd.org/cgi/man.cgi?query=mknod&sektion=8]] -for more details. -
    '''contents'''
    -The full pathname of a file that holds the contents of this file. -
    '''flags'''
    -The file flags as a symbolic name. -See -[[chflags(1)|http://www.freebsd.org/cgi/man.cgi?query=chflags&sektion=1]] -for information on these names. -If no flags are to be set the string -"none" -may be used to override the current default. -
    '''gid'''
    -The file group as a numeric value. -
    '''gname'''
    -The file group as a symbolic name. -
    '''ignore'''
    -Ignore any file hierarchy below this file. -
    '''inode'''
    -The inode number. -
    '''link'''
    -The target of the symbolic link when type=link. -
    '''md5'''
    -The MD5 message digest of the file. -
    '''md5digest'''
    -A synonym for -'''md5'''. -
    '''mode'''
    -The current file's permissions as a numeric (octal) or symbolic -value. -
    '''nlink'''
    -The number of hard links the file is expected to have. -
    '''nochange'''
    -Make sure this file or directory exists but otherwise ignore all attributes. -
    '''optional'''
    -The file is optional; do not complain about the file if it is not in -the file hierarchy. -
    '''resdevice'''
    -The -"resident" -device number of the file, e.g. the ID of the device that -contains the file. -Its format is the same as the one for -'''device'''. -
    '''ripemd160digest'''
    -The -'''RIPEMD160''' -message digest of the file. -
    '''rmd160'''
    -A synonym for -'''ripemd160digest'''. -
    '''rmd160digest'''
    -A synonym for -'''ripemd160digest'''. -
    '''sha1'''
    -The -'''FIPS''' -160-1 -("Tn SHA-1") -message digest of the file. -
    '''sha1digest'''
    -A synonym for -'''sha1'''. -
    '''sha256'''
    -The -'''FIPS''' -180-2 -("Tn SHA-256") -message digest of the file. -
    '''sha256digest'''
    -A synonym for -'''sha256'''. -
    '''sha384'''
    -The -'''FIPS''' -180-2 -("Tn SHA-384") -message digest of the file. -
    '''sha384digest'''
    -A synonym for -'''sha384'''. -
    '''sha512'''
    -The -'''FIPS''' -180-2 -("Tn SHA-512") -message digest of the file. -
    '''sha512digest'''
    -A synonym for -'''sha512'''. -
    '''size'''
    -The size, in bytes, of the file. -
    '''time'''
    -The last modification time of the file. -
    '''type'''
    -The type of the file; may be set to any one of the following: - -
    -
    '''block'''
    -block special device -
    '''char'''
    -character special device -
    '''dir'''
    -directory -
    '''fifo'''
    -fifo -
    '''file'''
    -regular file -
    '''link'''
    -symbolic link -
    '''socket'''
    -socket -
    -
    '''uid'''
    -The file owner as a numeric value. -
    '''uname'''
    -The file owner as a symbolic name. -
    -== SEE ALSO == -[[cksum(1)|http://www.freebsd.org/cgi/man.cgi?query=cksum&sektion=1]], -[[find(1)|http://www.freebsd.org/cgi/man.cgi?query=find&sektion=1]], -[[mtree(8)|http://www.freebsd.org/cgi/man.cgi?query=mtree&sektion=8]] -== HISTORY == -The -'''mtree''' -utility appeared in -BSD 4.3 Reno. -The -'''MD5''' -digest capability was added in -FreeBSD 2.1, -in response to the widespread use of programs which can spoof -[[cksum(1)|http://www.freebsd.org/cgi/man.cgi?query=cksum&sektion=1]]. -The -'''SHA-1''' -and -'''RIPEMD160''' -digests were added in -FreeBSD 4.0, -as new attacks have demonstrated weaknesses in -'''MD5 .''' -The -'''SHA-256''' -digest was added in -FreeBSD 6.0. -Support for file flags was added in -FreeBSD 4.0, -and mostly comes from -NetBSD. -The -"full" -entry format was added by -NetBSD. diff --git a/thirdparty/libarchive/doc/wiki/ManPageTar5.wiki b/thirdparty/libarchive/doc/wiki/ManPageTar5.wiki deleted file mode 100644 index c705a2669..000000000 --- a/thirdparty/libarchive/doc/wiki/ManPageTar5.wiki +++ /dev/null @@ -1,922 +0,0 @@ -TAR(5) manual page -== NAME == -'''tar''' -- format of tape archive files -== DESCRIPTION == -The -'''tar''' -archive format collects any number of files, directories, and other -file system objects (symbolic links, device nodes, etc.) into a single -stream of bytes. -The format was originally designed to be used with -tape drives that operate with fixed-size blocks, but is widely used as -a general packaging mechanism. -=== General Format=== -A -'''tar''' -archive consists of a series of 512-byte records. -Each file system object requires a header record which stores basic metadata -(pathname, owner, permissions, etc.) and zero or more records containing any -file data. -The end of the archive is indicated by two records consisting -entirely of zero bytes. - -For compatibility with tape drives that use fixed block sizes, -programs that read or write tar files always read or write a fixed -number of records with each I/O operation. -These -"blocks" -are always a multiple of the record size. -The maximum block size supported by early -implementations was 10240 bytes or 20 records. -This is still the default for most implementations -although block sizes of 1MiB (2048 records) or larger are -commonly used with modern high-speed tape drives. -(Note: the terms -"block" -and -"record" -here are not entirely standard; this document follows the -convention established by John Gilmore in documenting -'''pdtar'''.) -=== Old-Style Archive Format=== -The original tar archive format has been extended many times to -include additional information that various implementors found -necessary. -This section describes the variant implemented by the tar command -included in -At v7, -which seems to be the earliest widely-used version of the tar program. - -The header record for an old-style -'''tar''' -archive consists of the following: -```text -struct header_old_tar { - char name[100]; - char mode[8]; - char uid[8]; - char gid[8]; - char size[12]; - char mtime[12]; - char checksum[8]; - char linkflag[1]; - char linkname[100]; - char pad[255]; -}; -``` -All unused bytes in the header record are filled with nulls. -
    -
    ''name''
    -Pathname, stored as a null-terminated string. -Early tar implementations only stored regular files (including -hardlinks to those files). -One common early convention used a trailing "/" character to indicate -a directory name, allowing directory permissions and owner information -to be archived and restored. -
    ''mode''
    -File mode, stored as an octal number in ASCII. -
    ''uid'', ''gid''
    -User id and group id of owner, as octal numbers in ASCII. -
    ''size''
    -Size of file, as octal number in ASCII. -For regular files only, this indicates the amount of data -that follows the header. -In particular, this field was ignored by early tar implementations -when extracting hardlinks. -Modern writers should always store a zero length for hardlink entries. -
    ''mtime''
    -Modification time of file, as an octal number in ASCII. -This indicates the number of seconds since the start of the epoch, -00:00:00 UTC January 1, 1970. -Note that negative values should be avoided -here, as they are handled inconsistently. -
    ''checksum''
    -Header checksum, stored as an octal number in ASCII. -To compute the checksum, set the checksum field to all spaces, -then sum all bytes in the header using unsigned arithmetic. -This field should be stored as six octal digits followed by a null and a space -character. -Note that many early implementations of tar used signed arithmetic -for the checksum field, which can cause interoperability problems -when transferring archives between systems. -Modern robust readers compute the checksum both ways and accept the -header if either computation matches. -
    ''linkflag'', ''linkname''
    -In order to preserve hardlinks and conserve tape, a file -with multiple links is only written to the archive the first -time it is encountered. -The next time it is encountered, the -''linkflag'' -is set to an ASCII -Sq 1 -and the -''linkname'' -field holds the first name under which this file appears. -(Note that regular files have a null value in the -''linkflag'' -field.) -
    - -Early tar implementations varied in how they terminated these fields. -The tar command in -At v7 -used the following conventions (this is also documented in early BSD manpages): -the pathname must be null-terminated; -the mode, uid, and gid fields must end in a space and a null byte; -the size and mtime fields must end in a space; -the checksum is terminated by a null and a space. -Early implementations filled the numeric fields with leading spaces. -This seems to have been common practice until the -IEEE Std 1003.1-1988 (``POSIX.1'') -standard was released. -For best portability, modern implementations should fill the numeric -fields with leading zeros. -=== Pre-POSIX Archives=== -An early draft of -IEEE Std 1003.1-1988 (``POSIX.1'') -served as the basis for John Gilmore's -'''pdtar''' -program and many system implementations from the late 1980s -and early 1990s. -These archives generally follow the POSIX ustar -format described below with the following variations: -
      -
    • -The magic value consists of the five characters -"ustar" -followed by a space. -The version field contains a space character followed by a null. -
    • -The numeric fields are generally filled with leading spaces -(not leading zeros as recommended in the final standard). -
    • -The prefix field is often not used, limiting pathnames to -the 100 characters of old-style archives. -
    -=== POSIX ustar Archives=== -IEEE Std 1003.1-1988 (``POSIX.1'') -defined a standard tar file format to be read and written -by compliant implementations of -[[ManPageBsdtar1]]. -This format is often called the -"ustar" -format, after the magic value used -in the header. -(The name is an acronym for -"Unix Standard TAR".) -It extends the historic format with new fields: -```text -struct header_posix_ustar { - char name[100]; - char mode[8]; - char uid[8]; - char gid[8]; - char size[12]; - char mtime[12]; - char checksum[8]; - char typeflag[1]; - char linkname[100]; - char magic[6]; - char version[2]; - char uname[32]; - char gname[32]; - char devmajor[8]; - char devminor[8]; - char prefix[155]; - char pad[12]; -}; -``` -
    -
    ''typeflag''
    -Type of entry. -POSIX extended the earlier -''linkflag'' -field with several new type values: -
    -
    "0"
    -Regular file. -NUL should be treated as a synonym, for compatibility purposes. -
    "1"
    -Hard link. -
    "2"
    -Symbolic link. -
    "3"
    -Character device node. -
    "4"
    -Block device node. -
    "5"
    -Directory. -
    "6"
    -FIFO node. -
    "7"
    -Reserved. -
    Other
    -A POSIX-compliant implementation must treat any unrecognized typeflag value -as a regular file. -In particular, writers should ensure that all entries -have a valid filename so that they can be restored by readers that do not -support the corresponding extension. -Uppercase letters "A" through "Z" are reserved for custom extensions. -Note that sockets and whiteout entries are not archivable. -
    -It is worth noting that the -''size'' -field, in particular, has different meanings depending on the type. -For regular files, of course, it indicates the amount of data -following the header. -For directories, it may be used to indicate the total size of all -files in the directory, for use by operating systems that pre-allocate -directory space. -For all other types, it should be set to zero by writers and ignored -by readers. -
    ''magic''
    -Contains the magic value -"ustar" -followed by a NUL byte to indicate that this is a POSIX standard archive. -Full compliance requires the uname and gname fields be properly set. -
    ''version''
    -Version. -This should be -"00" -(two copies of the ASCII digit zero) for POSIX standard archives. -
    ''uname'', ''gname''
    -User and group names, as null-terminated ASCII strings. -These should be used in preference to the uid/gid values -when they are set and the corresponding names exist on -the system. -
    ''devmajor'', ''devminor''
    -Major and minor numbers for character device or block device entry. -
    ''name'', ''prefix''
    -If the pathname is too long to fit in the 100 bytes provided by the standard -format, it can be split at any -''/'' -character with the first portion going into the prefix field. -If the prefix field is not empty, the reader will prepend -the prefix value and a -''/'' -character to the regular name field to obtain the full pathname. -The standard does not require a trailing -''/'' -character on directory names, though most implementations still -include this for compatibility reasons. -
    - -Note that all unused bytes must be set to -NUL. - -Field termination is specified slightly differently by POSIX -than by previous implementations. -The -''magic'', -''uname'', -and -''gname'' -fields must have a trailing -NUL. -The -''pathname'', -''linkname'', -and -''prefix'' -fields must have a trailing -NUL -unless they fill the entire field. -(In particular, it is possible to store a 256-character pathname if it -happens to have a -''/'' -as the 156th character.) -POSIX requires numeric fields to be zero-padded in the front, and requires -them to be terminated with either space or -NUL -characters. - -Currently, most tar implementations comply with the ustar -format, occasionally extending it by adding new fields to the -blank area at the end of the header record. -=== Numeric Extensions=== -There have been several attempts to extend the range of sizes -or times supported by modifying how numbers are stored in the -header. - -One obvious extension to increase the size of files is to -eliminate the terminating characters from the various -numeric fields. -For example, the standard only allows the size field to contain -11 octal digits, reserving the twelfth byte for a trailing -NUL character. -Allowing 12 octal digits allows file sizes up to 64 GB. - -Another extension, utilized by GNU tar, star, and other newer -'''tar''' -implementations, permits binary numbers in the standard numeric fields. -This is flagged by setting the high bit of the first byte. -The remainder of the field is treated as a signed twos-complement -value. -This permits 95-bit values for the length and time fields -and 63-bit values for the uid, gid, and device numbers. -In particular, this provides a consistent way to handle -negative time values. -GNU tar supports this extension for the -length, mtime, ctime, and atime fields. -Joerg Schilling's star program and the libarchive library support -this extension for all numeric fields. -Note that this extension is largely obsoleted by the extended -attribute record provided by the pax interchange format. - -Another early GNU extension allowed base-64 values rather than octal. -This extension was short-lived and is no longer supported by any -implementation. -=== Pax Interchange Format=== -There are many attributes that cannot be portably stored in a -POSIX ustar archive. -IEEE Std 1003.1-2001 (``POSIX.1'') -defined a -"pax interchange format" -that uses two new types of entries to hold text-formatted -metadata that applies to following entries. -Note that a pax interchange format archive is a ustar archive in every -respect. -The new data is stored in ustar-compatible archive entries that use the -"x" -or -"g" -typeflag. -In particular, older implementations that do not fully support these -extensions will extract the metadata into regular files, where the -metadata can be examined as necessary. - -An entry in a pax interchange format archive consists of one or -two standard ustar entries, each with its own header and data. -The first optional entry stores the extended attributes -for the following entry. -This optional first entry has an "x" typeflag and a size field that -indicates the total size of the extended attributes. -The extended attributes themselves are stored as a series of text-format -lines encoded in the portable UTF-8 encoding. -Each line consists of a decimal number, a space, a key string, an equals -sign, a value string, and a new line. -The decimal number indicates the length of the entire line, including the -initial length field and the trailing newline. -An example of such a field is: -```text -25 ctime=1084839148.1212\n -``` -Keys in all lowercase are standard keys. -Vendors can add their own keys by prefixing them with an all uppercase -vendor name and a period. -Note that, unlike the historic header, numeric values are stored using -decimal, not octal. -A description of some common keys follows: -
    -
    '''atime''', '''ctime''', '''mtime'''
    -File access, inode change, and modification times. -These fields can be negative or include a decimal point and a fractional value. -
    '''hdrcharset'''
    -The character set used by the pax extension values. -By default, all textual values in the pax extended attributes -are assumed to be in UTF-8, including pathnames, user names, -and group names. -In some cases, it is not possible to translate local -conventions into UTF-8. -If this key is present and the value is the six-character ASCII string -"BINARY", -then all textual values are assumed to be in a platform-dependent -multi-byte encoding. -Note that there are only two valid values for this key: -"BINARY" -or -"ISO-IR\ 10646\ 2000\ UTF-8". -No other values are permitted by the standard, and -the latter value should generally not be used as it is the -default when this key is not specified. -In particular, this flag should not be used as a general -mechanism to allow filenames to be stored in arbitrary -encodings. -
    '''uname''', '''uid''', '''gname''', '''gid'''
    -User name, group name, and numeric UID and GID values. -The user name and group name stored here are encoded in UTF8 -and can thus include non-ASCII characters. -The UID and GID fields can be of arbitrary length. -
    '''linkpath'''
    -The full path of the linked-to file. -Note that this is encoded in UTF8 and can thus include non-ASCII characters. -
    '''path'''
    -The full pathname of the entry. -Note that this is encoded in UTF8 and can thus include non-ASCII characters. -
    '''realtime.*''', '''security.*'''
    -These keys are reserved and may be used for future standardization. -
    '''size'''
    -The size of the file. -Note that there is no length limit on this field, allowing conforming -archives to store files much larger than the historic 8GB limit. -
    '''SCHILY.*'''
    -Vendor-specific attributes used by Joerg Schilling's -'''star''' -implementation. -
    '''SCHILY.acl.access''', '''SCHILY.acl.default''', '''SCHILY.acl.ace'''
    -Stores the access, default and NFSv4 ACLs as textual strings in a format -that is an extension of the format specified by POSIX.1e draft 17. -In particular, each user or group access specification can include -an additional colon-separated field with the numeric UID or GID. -This allows ACLs to be restored on systems that may not have complete -user or group information available (such as when NIS/YP or LDAP services -are temporarily unavailable). -
    '''SCHILY.devminor''', '''SCHILY.devmajor'''
    -The full minor and major numbers for device nodes. -
    '''SCHILY.fflags'''
    -The file flags. -
    '''SCHILY.realsize'''
    -The full size of the file on disk. -XXX explain? XXX -
    '''SCHILY.dev''', '''SCHILY.ino''', '''SCHILY.nlinks'''
    -The device number, inode number, and link count for the entry. -In particular, note that a pax interchange format archive using Joerg -Schilling's -'''SCHILY.*''' -extensions can store all of the data from -''struct'' stat. -
    '''LIBARCHIVE.*'''
    -Vendor-specific attributes used by the -'''libarchive''' -library and programs that use it. -
    '''LIBARCHIVE.creationtime'''
    -The time when the file was created. -(This should not be confused with the POSIX -"ctime" -attribute, which refers to the time when the file -metadata was last changed.) -
    '''LIBARCHIVE.xattr'''.''namespace''.''key''
    -Libarchive stores POSIX.1e-style extended attributes using -keys of this form. -The -''key'' -value is URL-encoded: -All non-ASCII characters and the two special characters -"=" -and -"%" -are encoded as -"%" -followed by two uppercase hexadecimal digits. -The value of this key is the extended attribute value -encoded in base 64. -XXX Detail the base-64 format here XXX -
    '''VENDOR.*'''
    -XXX document other vendor-specific extensions XXX -
    - -Any values stored in an extended attribute override the corresponding -values in the regular tar header. -Note that compliant readers should ignore the regular fields when they -are overridden. -This is important, as existing archivers are known to store non-compliant -values in the standard header fields in this situation. -There are no limits on length for any of these fields. -In particular, numeric fields can be arbitrarily large. -All text fields are encoded in UTF8. -Compliant writers should store only portable 7-bit ASCII characters in -the standard ustar header and use extended -attributes whenever a text value contains non-ASCII characters. - -In addition to the -'''x''' -entry described above, the pax interchange format -also supports a -'''g''' -entry. -The -'''g''' -entry is identical in format, but specifies attributes that serve as -defaults for all subsequent archive entries. -The -'''g''' -entry is not widely used. - -Besides the new -'''x''' -and -'''g''' -entries, the pax interchange format has a few other minor variations -from the earlier ustar format. -The most troubling one is that hardlinks are permitted to have -data following them. -This allows readers to restore any hardlink to a file without -having to rewind the archive to find an earlier entry. -However, it creates complications for robust readers, as it is no longer -clear whether or not they should ignore the size field for hardlink entries. -=== GNU Tar Archives=== -The GNU tar program started with a pre-POSIX format similar to that -described earlier and has extended it using several different mechanisms: -It added new fields to the empty space in the header (some of which was later -used by POSIX for conflicting purposes); -it allowed the header to be continued over multiple records; -and it defined new entries that modify following entries -(similar in principle to the -'''x''' -entry described above, but each GNU special entry is single-purpose, -unlike the general-purpose -'''x''' -entry). -As a result, GNU tar archives are not POSIX compatible, although -more lenient POSIX-compliant readers can successfully extract most -GNU tar archives. -```text -struct header_gnu_tar { - char name[100]; - char mode[8]; - char uid[8]; - char gid[8]; - char size[12]; - char mtime[12]; - char checksum[8]; - char typeflag[1]; - char linkname[100]; - char magic[6]; - char version[2]; - char uname[32]; - char gname[32]; - char devmajor[8]; - char devminor[8]; - char atime[12]; - char ctime[12]; - char offset[12]; - char longnames[4]; - char unused[1]; - struct { - char offset[12]; - char numbytes[12]; - } sparse[4]; - char isextended[1]; - char realsize[12]; - char pad[17]; -}; -``` -
    -
    ''typeflag''
    -GNU tar uses the following special entry types, in addition to -those defined by POSIX: -
    -
    7
    -GNU tar treats type "7" records identically to type "0" records, -except on one obscure RTOS where they are used to indicate the -pre-allocation of a contiguous file on disk. -
    D
    -This indicates a directory entry. -Unlike the POSIX-standard "5" -typeflag, the header is followed by data records listing the names -of files in this directory. -Each name is preceded by an ASCII "Y" -if the file is stored in this archive or "N" if the file is not -stored in this archive. -Each name is terminated with a null, and -an extra null marks the end of the name list. -The purpose of this -entry is to support incremental backups; a program restoring from -such an archive may wish to delete files on disk that did not exist -in the directory when the archive was made. - -Note that the "D" typeflag specifically violates POSIX, which requires -that unrecognized typeflags be restored as normal files. -In this case, restoring the "D" entry as a file could interfere -with subsequent creation of the like-named directory. -
    K
    -The data for this entry is a long linkname for the following regular entry. -
    L
    -The data for this entry is a long pathname for the following regular entry. -
    M
    -This is a continuation of the last file on the previous volume. -GNU multi-volume archives guarantee that each volume begins with a valid -entry header. -To ensure this, a file may be split, with part stored at the end of one volume, -and part stored at the beginning of the next volume. -The "M" typeflag indicates that this entry continues an existing file. -Such entries can only occur as the first or second entry -in an archive (the latter only if the first entry is a volume label). -The -''size'' -field specifies the size of this entry. -The -''offset'' -field at bytes 369-380 specifies the offset where this file fragment -begins. -The -''realsize'' -field specifies the total size of the file (which must equal -''size'' -plus -''offset''). -When extracting, GNU tar checks that the header file name is the one it is -expecting, that the header offset is in the correct sequence, and that -the sum of offset and size is equal to realsize. -
    N
    -Type "N" records are no longer generated by GNU tar. -They contained a -list of files to be renamed or symlinked after extraction; this was -originally used to support long names. -The contents of this record -are a text description of the operations to be done, in the form -"Rename %s to %s\n" -or -"Symlink %s to %s\n ;" -in either case, both -filenames are escaped using K&R C syntax. -Due to security concerns, "N" records are now generally ignored -when reading archives. -
    S
    -This is a -"sparse" -regular file. -Sparse files are stored as a series of fragments. -The header contains a list of fragment offset/length pairs. -If more than four such entries are required, the header is -extended as necessary with -"extra" -header extensions (an older format that is no longer used), or -"sparse" -extensions. -
    V
    -The -''name'' -field should be interpreted as a tape/volume header name. -This entry should generally be ignored on extraction. -
    -
    ''magic''
    -The magic field holds the five characters -"ustar" -followed by a space. -Note that POSIX ustar archives have a trailing null. -
    ''version''
    -The version field holds a space character followed by a null. -Note that POSIX ustar archives use two copies of the ASCII digit -"0". -
    ''atime'', ''ctime''
    -The time the file was last accessed and the time of -last change of file information, stored in octal as with -''mtime''. -
    ''longnames''
    -This field is apparently no longer used. -
    Sparse ''offset'' / ''numbytes''
    -Each such structure specifies a single fragment of a sparse -file. -The two fields store values as octal numbers. -The fragments are each padded to a multiple of 512 bytes -in the archive. -On extraction, the list of fragments is collected from the -header (including any extension headers), and the data -is then read and written to the file at appropriate offsets. -
    ''isextended''
    -If this is set to non-zero, the header will be followed by additional -"sparse header" -records. -Each such record contains information about as many as 21 additional -sparse blocks as shown here: -```text -struct gnu_sparse_header { - struct { - char offset[12]; - char numbytes[12]; - } sparse[21]; - char isextended[1]; - char padding[7]; -}; -``` -
    ''realsize''
    -A binary representation of the file's complete size, with a much larger range -than the POSIX file size. -In particular, with -'''M''' -type files, the current entry is only a portion of the file. -In that case, the POSIX size field will indicate the size of this -entry; the -''realsize'' -field will indicate the total size of the file. -
    -=== GNU tar pax archives=== -GNU tar 1.14 (XXX check this XXX) and later will write -pax interchange format archives when you specify the ---posix -flag. -This format follows the pax interchange format closely, -using some -'''SCHILY''' -tags and introducing new keywords to store sparse file information. -There have been three iterations of the sparse file support, referred to -as -"0.0", -"0.1", -and -"1.0". -
    -
    '''GNU.sparse.numblocks''', '''GNU.sparse.offset''', '''GNU.sparse.numbytes''', '''GNU.sparse.size'''
    -The -"0.0" -format used an initial -'''GNU.sparse.numblocks''' -attribute to indicate the number of blocks in the file, a pair of -'''GNU.sparse.offset''' -and -'''GNU.sparse.numbytes''' -to indicate the offset and size of each block, -and a single -'''GNU.sparse.size''' -to indicate the full size of the file. -This is not the same as the size in the tar header because the -latter value does not include the size of any holes. -This format required that the order of attributes be preserved and -relied on readers accepting multiple appearances of the same attribute -names, which is not officially permitted by the standards. -
    '''GNU.sparse.map'''
    -The -"0.1" -format used a single attribute that stored a comma-separated -list of decimal numbers. -Each pair of numbers indicated the offset and size, respectively, -of a block of data. -This does not work well if the archive is extracted by an archiver -that does not recognize this extension, since many pax implementations -simply discard unrecognized attributes. -
    '''GNU.sparse.major''', '''GNU.sparse.minor''', '''GNU.sparse.name''', '''GNU.sparse.realsize'''
    -The -"1.0" -format stores the sparse block map in one or more 512-byte blocks -prepended to the file data in the entry body. -The pax attributes indicate the existence of this map -(via the -'''GNU.sparse.major''' -and -'''GNU.sparse.minor''' -fields) -and the full size of the file. -The -'''GNU.sparse.name''' -holds the true name of the file. -To avoid confusion, the name stored in the regular tar header -is a modified name so that extraction errors will be apparent -to users. -
    -=== Solaris Tar=== -XXX More Details Needed XXX - -Solaris tar (beginning with SunOS XXX 5.7 ?? XXX) supports an -"extended" -format that is fundamentally similar to pax interchange format, -with the following differences: -
      -
    • -Extended attributes are stored in an entry whose type is -'''X''', -not -'''x''', -as used by pax interchange format. -The detailed format of this entry appears to be the same -as detailed above for the -'''x''' -entry. -
    • -An additional -'''A''' -header is used to store an ACL for the following regular entry. -The body of this entry contains a seven-digit octal number -followed by a zero byte, followed by the -textual ACL description. -The octal value is the number of ACL entries -plus a constant that indicates the ACL type: 01000000 -for POSIX.1e ACLs and 03000000 for NFSv4 ACLs. -
    -=== AIX Tar=== -XXX More details needed XXX - -AIX Tar uses a ustar-formatted header with the type -'''A''' -for storing coded ACL information. -Unlike the Solaris format, AIX tar writes this header after the -regular file body to which it applies. -The pathname in this header is either -'''NFS4''' -or -'''AIXC''' -to indicate the type of ACL stored. -The actual ACL is stored in platform-specific binary format. -=== Mac OS X Tar=== -The tar distributed with Apple's Mac OS X stores most regular files -as two separate files in the tar archive. -The two files have the same name except that the first -one has -"._" -prepended to the last path element. -This special file stores an AppleDouble-encoded -binary blob with additional metadata about the second file, -including ACL, extended attributes, and resources. -To recreate the original file on disk, each -separate file can be extracted and the Mac OS X -'''copyfile'''() -function can be used to unpack the separate -metadata file and apply it to th regular file. -Conversely, the same function provides a -"pack" -option to encode the extended metadata from -a file into a separate file whose contents -can then be put into a tar archive. - -Note that the Apple extended attributes interact -badly with long filenames. -Since each file is stored with the full name, -a separate set of extensions needs to be included -in the archive for each one, doubling the overhead -required for files with long names. -=== Summary of tar type codes=== -The following list is a condensed summary of the type codes -used in tar header records generated by different tar implementations. -More details about specific implementations can be found above: -
    -
    NUL
    -Early tar programs stored a zero byte for regular files. -
    '''0'''
    -POSIX standard type code for a regular file. -
    '''1'''
    -POSIX standard type code for a hard link description. -
    '''2'''
    -POSIX standard type code for a symbolic link description. -
    '''3'''
    -POSIX standard type code for a character device node. -
    '''4'''
    -POSIX standard type code for a block device node. -
    '''5'''
    -POSIX standard type code for a directory. -
    '''6'''
    -POSIX standard type code for a FIFO. -
    '''7'''
    -POSIX reserved. -
    '''7'''
    -GNU tar used for pre-allocated files on some systems. -
    '''A'''
    -Solaris tar ACL description stored prior to a regular file header. -
    '''A'''
    -AIX tar ACL description stored after the file body. -
    '''D'''
    -GNU tar directory dump. -
    '''K'''
    -GNU tar long linkname for the following header. -
    '''L'''
    -GNU tar long pathname for the following header. -
    '''M'''
    -GNU tar multivolume marker, indicating the file is a continuation of a file from the previous volume. -
    '''N'''
    -GNU tar long filename support. -Deprecated. -
    '''S'''
    -GNU tar sparse regular file. -
    '''V'''
    -GNU tar tape/volume header name. -
    '''X'''
    -Solaris tar general-purpose extension header. -
    '''g'''
    -POSIX pax interchange format global extensions. -
    '''x'''
    -POSIX pax interchange format per-file extensions. -
    -== SEE ALSO == -[[ar(1)|http://www.freebsd.org/cgi/man.cgi?query=ar&sektion=1]], -[[pax(1)|http://www.freebsd.org/cgi/man.cgi?query=pax&sektion=1]], -[[ManPageBsdtar1]] -== STANDARDS == -The -'''tar''' -utility is no longer a part of POSIX or the Single Unix Standard. -It last appeared in -Version 2 of the Single UNIX Specification (``SUSv2''). -It has been supplanted in subsequent standards by -[[pax(1)|http://www.freebsd.org/cgi/man.cgi?query=pax&sektion=1]]. -The ustar format is currently part of the specification for the -[[pax(1)|http://www.freebsd.org/cgi/man.cgi?query=pax&sektion=1]] -utility. -The pax interchange file format is new with -IEEE Std 1003.1-2001 (``POSIX.1''). -== HISTORY == -A -'''tar''' -command appeared in Seventh Edition Unix, which was released in January, 1979. -It replaced the -'''tp''' -program from Fourth Edition Unix which in turn replaced the -'''tap''' -program from First Edition Unix. -John Gilmore's -'''pdtar''' -public-domain implementation (circa 1987) was highly influential -and formed the basis of -'''GNU''' tar -(circa 1988). -Joerg Shilling's -'''star''' -archiver is another open-source (CDDL) archiver (originally developed -circa 1985) which features complete support for pax interchange -format. - -This documentation was written as part of the -'''libarchive''' -and -'''bsdtar''' -project by -Tim Kientzle <kientzle@FreeBSD.org.> diff --git a/thirdparty/libarchive/examples/minitar/README b/thirdparty/libarchive/examples/minitar/README deleted file mode 100644 index 83f646cdb..000000000 --- a/thirdparty/libarchive/examples/minitar/README +++ /dev/null @@ -1,12 +0,0 @@ -"minitar" is a minimal example of a program that uses libarchive to -read/write various archive formats. It's a more ambitious version of -'untar.c' that includes compile-time options to enable/disable various -features, including non-tar formats, archive creation, and automatic -decompression support. - -I use this as a test bed to check for "link pollution," ensuring that -a program using libarchive does not pull in unnecessary code. - -The "minitar" program is also a good starting point for anyone who -wants to use libarchive for their own purposes, as it demonstrates -basic usage of the library. diff --git a/thirdparty/libarchive/examples/minitar/minitar.c b/thirdparty/libarchive/examples/minitar/minitar.c deleted file mode 100644 index 881f94b2d..000000000 --- a/thirdparty/libarchive/examples/minitar/minitar.c +++ /dev/null @@ -1,471 +0,0 @@ -/*- - * This file is in the public domain. - * Do with it as you will. - */ - -/*- - * This is a compact "tar" program whose primary goal is small size. - * Statically linked, it can be very small indeed. This serves a number - * of goals: - * o a testbed for libarchive (to check for link pollution), - * o a useful tool for space-constrained systems (boot floppies, etc), - * o a place to experiment with new implementation ideas for bsdtar, - * o a small program to demonstrate libarchive usage. - * - * Use the following macros to suppress features: - * NO_BZIP2 - Implies NO_BZIP2_CREATE and NO_BZIP2_EXTRACT - * NO_BZIP2_CREATE - Suppress bzip2 compression support. - * NO_BZIP2_EXTRACT - Suppress bzip2 auto-detection and decompression. - * NO_COMPRESS - Implies NO_COMPRESS_CREATE and NO_COMPRESS_EXTRACT - * NO_COMPRESS_CREATE - Suppress compress(1) compression support - * NO_COMPRESS_EXTRACT - Suppress compress(1) auto-detect and decompression. - * NO_CREATE - Suppress all archive creation support. - * NO_CPIO_EXTRACT - Suppress auto-detect and dearchiving of cpio archives. - * NO_GZIP - Implies NO_GZIP_CREATE and NO_GZIP_EXTRACT - * NO_GZIP_CREATE - Suppress gzip compression support. - * NO_GZIP_EXTRACT - Suppress gzip auto-detection and decompression. - * NO_LOOKUP - Try to avoid getpw/getgr routines, which can be very large - * NO_TAR_EXTRACT - Suppress tar extraction - * - * With all of the above macros defined (except NO_TAR_EXTRACT), you - * get a very small program that can recognize and extract essentially - * any uncompressed tar archive. On FreeBSD 5.1, this minimal program - * is under 64k, statically linked, which compares rather favorably to - * main(){printf("hello, world");} - * which is over 60k statically linked on the same operating system. - * Without any of the above macros, you get a static executable of - * about 180k with a lot of very sophisticated modern features. - * Obviously, it's trivial to add support for ISO, Zip, mtree, - * lzma/xz, etc. Just fill in the appropriate setup calls. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* - * NO_CREATE implies NO_BZIP2_CREATE and NO_GZIP_CREATE and NO_COMPRESS_CREATE. - */ -#ifdef NO_CREATE -#undef NO_BZIP2_CREATE -#define NO_BZIP2_CREATE -#undef NO_COMPRESS_CREATE -#define NO_COMPRESS_CREATE -#undef NO_GZIP_CREATE -#define NO_GZIP_CREATE -#endif - -/* - * The combination of NO_BZIP2_CREATE and NO_BZIP2_EXTRACT is - * equivalent to NO_BZIP2. - */ -#ifdef NO_BZIP2_CREATE -#ifdef NO_BZIP2_EXTRACT -#undef NO_BZIP2 -#define NO_BZIP2 -#endif -#endif - -#ifdef NO_BZIP2 -#undef NO_BZIP2_EXTRACT -#define NO_BZIP2_EXTRACT -#undef NO_BZIP2_CREATE -#define NO_BZIP2_CREATE -#endif - -/* - * The combination of NO_COMPRESS_CREATE and NO_COMPRESS_EXTRACT is - * equivalent to NO_COMPRESS. - */ -#ifdef NO_COMPRESS_CREATE -#ifdef NO_COMPRESS_EXTRACT -#undef NO_COMPRESS -#define NO_COMPRESS -#endif -#endif - -#ifdef NO_COMPRESS -#undef NO_COMPRESS_EXTRACT -#define NO_COMPRESS_EXTRACT -#undef NO_COMPRESS_CREATE -#define NO_COMPRESS_CREATE -#endif - -/* - * The combination of NO_GZIP_CREATE and NO_GZIP_EXTRACT is - * equivalent to NO_GZIP. - */ -#ifdef NO_GZIP_CREATE -#ifdef NO_GZIP_EXTRACT -#undef NO_GZIP -#define NO_GZIP -#endif -#endif - -#ifdef NO_GZIP -#undef NO_GZIP_EXTRACT -#define NO_GZIP_EXTRACT -#undef NO_GZIP_CREATE -#define NO_GZIP_CREATE -#endif - -#ifndef NO_CREATE -static void create(const char *filename, int compress, const char **argv); -#endif -static void errmsg(const char *); -static void extract(const char *filename, int do_extract, int flags); -static int copy_data(struct archive *, struct archive *); -static void msg(const char *); -static void usage(void); - -static int verbose = 0; - -int -main(int argc, const char **argv) -{ - const char *filename = NULL; - int compress, flags, mode, opt; - - (void)argc; - mode = 'x'; - verbose = 0; - compress = '\0'; - flags = ARCHIVE_EXTRACT_TIME; - - /* Among other sins, getopt(3) pulls in printf(3). */ - while (*++argv != NULL && **argv == '-') { - const char *p = *argv + 1; - - while ((opt = *p++) != '\0') { - switch (opt) { -#ifndef NO_CREATE - case 'c': - mode = opt; - break; -#endif - case 'f': - if (*p != '\0') - filename = p; - else - filename = *++argv; - p += strlen(p); - break; -#ifndef NO_BZIP2_CREATE - case 'j': - compress = opt; - break; -#endif - case 'p': - flags |= ARCHIVE_EXTRACT_PERM; - flags |= ARCHIVE_EXTRACT_ACL; - flags |= ARCHIVE_EXTRACT_FFLAGS; - break; - case 't': - mode = opt; - break; - case 'v': - verbose++; - break; - case 'x': - mode = opt; - break; -#ifndef NO_BZIP2_CREATE - case 'y': - compress = opt; - break; -#endif -#ifndef NO_COMPRESS_CREATE - case 'Z': - compress = opt; - break; -#endif -#ifndef NO_GZIP_CREATE - case 'z': - compress = opt; - break; -#endif - default: - usage(); - } - } - } - - switch (mode) { -#ifndef NO_CREATE - case 'c': - create(filename, compress, argv); - break; -#endif - case 't': - extract(filename, 0, flags); - break; - case 'x': - extract(filename, 1, flags); - break; - } - - return (0); -} - - -#ifndef NO_CREATE -static char buff[16384]; - -static void -create(const char *filename, int compress, const char **argv) -{ - struct archive *a; - struct archive_entry *entry; - ssize_t len; - int fd; - - a = archive_write_new(); - switch (compress) { -#ifndef NO_BZIP2_CREATE - case 'j': case 'y': - archive_write_add_filter_bzip2(a); - break; -#endif -#ifndef NO_COMPRESS_CREATE - case 'Z': - archive_write_add_filter_compress(a); - break; -#endif -#ifndef NO_GZIP_CREATE - case 'z': - archive_write_add_filter_gzip(a); - break; -#endif - default: - archive_write_add_filter_none(a); - break; - } - archive_write_set_format_ustar(a); - if (filename != NULL && strcmp(filename, "-") == 0) - filename = NULL; - archive_write_open_filename(a, filename); - - while (*argv != NULL) { - struct archive *disk = archive_read_disk_new(); -#ifndef NO_LOOKUP - archive_read_disk_set_standard_lookup(disk); -#endif - int r; - - r = archive_read_disk_open(disk, *argv); - if (r != ARCHIVE_OK) { - errmsg(archive_error_string(disk)); - errmsg("\n"); - exit(1); - } - - for (;;) { - int needcr = 0; - - entry = archive_entry_new(); - r = archive_read_next_header2(disk, entry); - if (r == ARCHIVE_EOF) - break; - if (r != ARCHIVE_OK) { - errmsg(archive_error_string(disk)); - errmsg("\n"); - exit(1); - } - archive_read_disk_descend(disk); - if (verbose) { - msg("a "); - msg(archive_entry_pathname(entry)); - needcr = 1; - } - r = archive_write_header(a, entry); - if (r < ARCHIVE_OK) { - errmsg(": "); - errmsg(archive_error_string(a)); - needcr = 1; - } - if (r == ARCHIVE_FATAL) - exit(1); - if (r > ARCHIVE_FAILED) { -#if 0 - /* Ideally, we would be able to use - * the same code to copy a body from - * an archive_read_disk to an - * archive_write that we use for - * copying data from an archive_read - * to an archive_write_disk. - * Unfortunately, this doesn't quite - * work yet. */ - copy_data(disk, a); -#else - /* For now, we use a simpler loop to copy data - * into the target archive. */ - fd = open(archive_entry_sourcepath(entry), O_RDONLY); - len = read(fd, buff, sizeof(buff)); - while (len > 0) { - archive_write_data(a, buff, len); - len = read(fd, buff, sizeof(buff)); - } - close(fd); -#endif - } - archive_entry_free(entry); - if (needcr) - msg("\n"); - } - archive_read_close(disk); - archive_read_free(disk); - argv++; - } - archive_write_close(a); - archive_write_free(a); -} -#endif - -static void -extract(const char *filename, int do_extract, int flags) -{ - struct archive *a; - struct archive *ext; - struct archive_entry *entry; - int r; - - a = archive_read_new(); - ext = archive_write_disk_new(); - archive_write_disk_set_options(ext, flags); -#ifndef NO_BZIP2_EXTRACT - archive_read_support_filter_bzip2(a); -#endif -#ifndef NO_GZIP_EXTRACT - archive_read_support_filter_gzip(a); -#endif -#ifndef NO_COMPRESS_EXTRACT - archive_read_support_filter_compress(a); -#endif -#ifndef NO_TAR_EXTRACT - archive_read_support_format_tar(a); -#endif -#ifndef NO_CPIO_EXTRACT - archive_read_support_format_cpio(a); -#endif -#ifndef NO_LOOKUP - archive_write_disk_set_standard_lookup(ext); -#endif - if (filename != NULL && strcmp(filename, "-") == 0) - filename = NULL; - if ((r = archive_read_open_filename(a, filename, 10240))) { - errmsg(archive_error_string(a)); - errmsg("\n"); - exit(r); - } - for (;;) { - int needcr = 0; - r = archive_read_next_header(a, &entry); - if (r == ARCHIVE_EOF) - break; - if (r != ARCHIVE_OK) { - errmsg(archive_error_string(a)); - errmsg("\n"); - exit(1); - } - if (verbose && do_extract) - msg("x "); - if (verbose || !do_extract) { - msg(archive_entry_pathname(entry)); - msg(" "); - needcr = 1; - } - if (do_extract) { - r = archive_write_header(ext, entry); - if (r != ARCHIVE_OK) { - errmsg(archive_error_string(a)); - needcr = 1; - } - else { - r = copy_data(a, ext); - if (r != ARCHIVE_OK) - needcr = 1; - } - } - if (needcr) - msg("\n"); - } - archive_read_close(a); - archive_read_free(a); - - archive_write_close(ext); - archive_write_free(ext); - exit(0); -} - -static int -copy_data(struct archive *ar, struct archive *aw) -{ - int r; - const void *buff; - size_t size; - int64_t offset; - - for (;;) { - r = archive_read_data_block(ar, &buff, &size, &offset); - if (r == ARCHIVE_EOF) - return (ARCHIVE_OK); - if (r != ARCHIVE_OK) { - errmsg(archive_error_string(ar)); - return (r); - } - r = archive_write_data_block(aw, buff, size, offset); - if (r != ARCHIVE_OK) { - errmsg(archive_error_string(ar)); - return (r); - } - } -} - -static void -msg(const char *m) -{ - write(1, m, strlen(m)); -} - -static void -errmsg(const char *m) -{ - if (m == NULL) { - m = "Error: No error description provided.\n"; - } - write(2, m, strlen(m)); -} - -static void -usage(void) -{ -/* Many program options depend on compile options. */ - const char *m = "Usage: minitar [-" -#ifndef NO_CREATE - "c" -#endif -#ifndef NO_BZIP2 - "j" -#endif - "tvx" -#ifndef NO_BZIP2 - "y" -#endif -#ifndef NO_COMPRESS - "Z" -#endif -#ifndef NO_GZIP - "z" -#endif - "] [-f file] [file]\n"; - - errmsg(m); - exit(1); -} diff --git a/thirdparty/libarchive/examples/tarfilter.c b/thirdparty/libarchive/examples/tarfilter.c deleted file mode 100644 index 0d323e1cb..000000000 --- a/thirdparty/libarchive/examples/tarfilter.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * This file is in the public domain. - * - * Feel free to use it as you wish. - */ - -/* - * This example program reads an archive from stdin (which can be in - * any format recognized by libarchive) and writes certain entries to - * an uncompressed ustar archive on stdout. This is a template for - * many kinds of archive manipulation: converting formats, resetting - * ownership, inserting entries, removing entries, etc. - * - * To compile: - * gcc -Wall -o tarfilter tarfilter.c -larchive -lz -lbz2 - */ - -#include -#include -#include -#include -#include -#include - -static void -die(char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - fprintf(stderr, "\n"); - exit(1); -} - -int -main(int argc, char **argv) -{ - char buff[8192]; - ssize_t len; - int r; - mode_t m; - struct archive *ina; - struct archive *outa; - struct archive_entry *entry; - - /* Read an archive from stdin, with automatic format detection. */ - ina = archive_read_new(); - if (ina == NULL) - die("Couldn't create archive reader."); - if (archive_read_support_filter_all(ina) != ARCHIVE_OK) - die("Couldn't enable decompression"); - if (archive_read_support_format_all(ina) != ARCHIVE_OK) - die("Couldn't enable read formats"); - if (archive_read_open_fd(ina, 0, 10240) != ARCHIVE_OK) - die("Couldn't open input archive"); - - /* Write an uncompressed ustar archive to stdout. */ - outa = archive_write_new(); - if (outa == NULL) - die("Couldn't create archive writer."); - if (archive_write_set_compression_none(outa) != ARCHIVE_OK) - die("Couldn't enable compression"); - if (archive_write_set_format_ustar(outa) != ARCHIVE_OK) - die("Couldn't set output format"); - if (archive_write_open_fd(outa, 1) != ARCHIVE_OK) - die("Couldn't open output archive"); - - /* Examine each entry in the input archive. */ - while ((r = archive_read_next_header(ina, &entry)) == ARCHIVE_OK) { - fprintf(stderr, "%s: ", archive_entry_pathname(entry)); - - /* Skip anything that isn't a regular file. */ - if (!S_ISREG(archive_entry_mode(entry))) { - fprintf(stderr, "skipped\n"); - continue; - } - - /* Make everything owned by root/wheel. */ - archive_entry_set_uid(entry, 0); - archive_entry_set_uname(entry, "root"); - archive_entry_set_gid(entry, 0); - archive_entry_set_gname(entry, "wheel"); - - /* Make everything permission 0744, strip SUID, etc. */ - m = archive_entry_mode(entry); - archive_entry_set_mode(entry, (m & ~07777) | 0744); - - /* Copy input entries to output archive. */ - if (archive_write_header(outa, entry) != ARCHIVE_OK) - die("Error writing output archive"); - if (archive_entry_size(entry) > 0) { - len = archive_read_data(ina, buff, sizeof(buff)); - while (len > 0) { - if (archive_write_data(outa, buff, len) != len) - die("Error writing output archive"); - len = archive_read_data(ina, buff, sizeof(buff)); - } - if (len < 0) - die("Error reading input archive"); - } - fprintf(stderr, "copied\n"); - } - if (r != ARCHIVE_EOF) - die("Error reading archive"); - /* Close the archives. */ - if (archive_read_free(ina) != ARCHIVE_OK) - die("Error closing input archive"); - if (archive_write_free(outa) != ARCHIVE_OK) - die("Error closing output archive"); - return (0); -} diff --git a/thirdparty/libarchive/examples/untar.c b/thirdparty/libarchive/examples/untar.c deleted file mode 100644 index dab75d2ed..000000000 --- a/thirdparty/libarchive/examples/untar.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * This file is in the public domain. - * Use it as you wish. - */ - -/* - * This is a compact tar extraction program using libarchive whose - * primary goal is small executable size. Statically linked, it can - * be very small, depending in large part on how cleanly factored your - * system libraries are. Note that this uses the standard libarchive, - * without any special recompilation. The only functional concession - * is that this program uses the uid/gid from the archive instead of - * doing uname/gname lookups. (Add a call to - * archive_write_disk_set_standard_lookup() to enable uname/gname - * lookups, but be aware that this can add 500k or more to a static - * executable, depending on the system libraries, since user/group - * lookups frequently pull in password, YP/LDAP, networking, and DNS - * resolver libraries.) - * - * To build: - * $ gcc -static -Wall -o untar untar.c -larchive - * $ strip untar - * - * NOTE: On some systems, you may need to add additional flags - * to ensure that untar.c is compiled the same way as libarchive - * was compiled. In particular, Linux users will probably - * have to add -D_FILE_OFFSET_BITS=64 to the command line above. - * - * For fun, statically compile the following simple hello.c program - * using the same flags as for untar and compare the size: - * - * #include - * int main(int argc, char **argv) { - * printf("hello, world\n"); - * return(0); - * } - * - * You may be even more surprised by the compiled size of true.c listed here: - * - * int main(int argc, char **argv) { - * return (0); - * } - * - * On a slightly customized FreeBSD 5 system that I used around - * 2005, hello above compiled to 89k compared to untar of 69k. So at - * that time, libarchive's tar reader and extract-to-disk routines - * compiled to less code than printf(). - * - * On my FreeBSD development system today (August, 2009): - * hello: 195024 bytes - * true: 194912 bytes - * untar: 259924 bytes - */ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -static void errmsg(const char *); -static void extract(const char *filename, int do_extract, int flags); -static void fail(const char *, const char *, int); -static int copy_data(struct archive *, struct archive *); -static void msg(const char *); -static void usage(void); -static void warn(const char *, const char *); - -static int verbose = 0; - -int -main(int argc, const char **argv) -{ - const char *filename = NULL; - int compress, flags, mode, opt; - - (void)argc; - mode = 'x'; - verbose = 0; - compress = '\0'; - flags = ARCHIVE_EXTRACT_TIME; - - /* Among other sins, getopt(3) pulls in printf(3). */ - while (*++argv != NULL && **argv == '-') { - const char *p = *argv + 1; - - while ((opt = *p++) != '\0') { - switch (opt) { - case 'f': - if (*p != '\0') - filename = p; - else - filename = *++argv; - p += strlen(p); - break; - case 'p': - flags |= ARCHIVE_EXTRACT_PERM; - flags |= ARCHIVE_EXTRACT_ACL; - flags |= ARCHIVE_EXTRACT_FFLAGS; - break; - case 't': - mode = opt; - break; - case 'v': - verbose++; - break; - case 'x': - mode = opt; - break; - default: - usage(); - } - } - } - - switch (mode) { - case 't': - extract(filename, 0, flags); - break; - case 'x': - extract(filename, 1, flags); - break; - } - - return (0); -} - - -static void -extract(const char *filename, int do_extract, int flags) -{ - struct archive *a; - struct archive *ext; - struct archive_entry *entry; - int r; - - a = archive_read_new(); - ext = archive_write_disk_new(); - archive_write_disk_set_options(ext, flags); - /* - * Note: archive_write_disk_set_standard_lookup() is useful - * here, but it requires library routines that can add 500k or - * more to a static executable. - */ - archive_read_support_format_tar(a); - /* - * On my system, enabling other archive formats adds 20k-30k - * each. Enabling gzip decompression adds about 20k. - * Enabling bzip2 is more expensive because the libbz2 library - * isn't very well factored. - */ - if (filename != NULL && strcmp(filename, "-") == 0) - filename = NULL; - if ((r = archive_read_open_filename(a, filename, 10240))) - fail("archive_read_open_filename()", - archive_error_string(a), r); - for (;;) { - r = archive_read_next_header(a, &entry); - if (r == ARCHIVE_EOF) - break; - if (r != ARCHIVE_OK) - fail("archive_read_next_header()", - archive_error_string(a), 1); - if (verbose && do_extract) - msg("x "); - if (verbose || !do_extract) - msg(archive_entry_pathname(entry)); - if (do_extract) { - r = archive_write_header(ext, entry); - if (r != ARCHIVE_OK) - warn("archive_write_header()", - archive_error_string(ext)); - else { - copy_data(a, ext); - r = archive_write_finish_entry(ext); - if (r != ARCHIVE_OK) - fail("archive_write_finish_entry()", - archive_error_string(ext), 1); - } - - } - if (verbose || !do_extract) - msg("\n"); - } - archive_read_close(a); - archive_read_free(a); - - archive_write_close(ext); - archive_write_free(ext); - exit(0); -} - -static int -copy_data(struct archive *ar, struct archive *aw) -{ - int r; - const void *buff; - size_t size; -#if ARCHIVE_VERSION_NUMBER >= 3000000 - int64_t offset; -#else - off_t offset; -#endif - - for (;;) { - r = archive_read_data_block(ar, &buff, &size, &offset); - if (r == ARCHIVE_EOF) - return (ARCHIVE_OK); - if (r != ARCHIVE_OK) - return (r); - r = archive_write_data_block(aw, buff, size, offset); - if (r != ARCHIVE_OK) { - warn("archive_write_data_block()", - archive_error_string(aw)); - return (r); - } - } -} - -/* - * These reporting functions use low-level I/O; on some systems, this - * is a significant code reduction. Of course, on many server and - * desktop operating systems, malloc() and even crt rely on printf(), - * which in turn pulls in most of the rest of stdio, so this is not an - * optimization at all there. (If you're going to pay 100k or more - * for printf() anyway, you may as well use it!) - */ -static void -msg(const char *m) -{ - write(1, m, strlen(m)); -} - -static void -errmsg(const char *m) -{ - write(2, m, strlen(m)); -} - -static void -warn(const char *f, const char *m) -{ - errmsg(f); - errmsg(" failed: "); - errmsg(m); - errmsg("\n"); -} - -static void -fail(const char *f, const char *m, int r) -{ - warn(f, m); - exit(r); -} - -static void -usage(void) -{ - const char *m = "Usage: untar [-tvx] [-f file] [file]\n"; - errmsg(m); - exit(1); -} diff --git a/thirdparty/libarchive/libarchive/CMakeLists.txt b/thirdparty/libarchive/libarchive/CMakeLists.txt deleted file mode 100644 index f7fdfb68a..000000000 --- a/thirdparty/libarchive/libarchive/CMakeLists.txt +++ /dev/null @@ -1,279 +0,0 @@ - -############################################ -# -# How to build libarchive -# -############################################ - -if (ANDROID) - include_directories(${PROJECT_SOURCE_DIR}/contrib/android/include) -endif() - -# Public headers -SET(include_HEADERS - archive.h - archive_entry.h -) - -# Sources and private headers -SET(libarchive_SOURCES - archive_acl.c - archive_acl_private.h - archive_check_magic.c - archive_cmdline.c - archive_cmdline_private.h - archive_crc32.h - archive_cryptor.c - archive_cryptor_private.h - archive_digest.c - archive_digest_private.h - archive_endian.h - archive_entry.c - archive_entry.h - archive_entry_copy_stat.c - archive_entry_link_resolver.c - archive_entry_locale.h - archive_entry_private.h - archive_entry_sparse.c - archive_entry_stat.c - archive_entry_strmode.c - archive_entry_xattr.c - archive_getdate.c - archive_getdate.h - archive_hmac.c - archive_hmac_private.h - archive_match.c - archive_openssl_evp_private.h - archive_openssl_hmac_private.h - archive_options.c - archive_options_private.h - archive_pack_dev.h - archive_pack_dev.c - archive_pathmatch.c - archive_pathmatch.h - archive_platform.h - archive_platform_acl.h - archive_platform_xattr.h - archive_ppmd_private.h - archive_ppmd8.c - archive_ppmd8_private.h - archive_ppmd7.c - archive_ppmd7_private.h - archive_private.h - archive_random.c - archive_random_private.h - archive_rb.c - archive_rb.h - archive_read.c - archive_read_add_passphrase.c - archive_read_append_filter.c - archive_read_data_into_fd.c - archive_read_disk_entry_from_file.c - archive_read_disk_posix.c - archive_read_disk_private.h - archive_read_disk_set_standard_lookup.c - archive_read_extract.c - archive_read_extract2.c - archive_read_open_fd.c - archive_read_open_file.c - archive_read_open_filename.c - archive_read_open_memory.c - archive_read_private.h - archive_read_set_format.c - archive_read_set_options.c - archive_read_support_filter_all.c - archive_read_support_filter_by_code.c - archive_read_support_filter_bzip2.c - archive_read_support_filter_compress.c - archive_read_support_filter_gzip.c - archive_read_support_filter_grzip.c - archive_read_support_filter_lrzip.c - archive_read_support_filter_lz4.c - archive_read_support_filter_lzop.c - archive_read_support_filter_none.c - archive_read_support_filter_program.c - archive_read_support_filter_rpm.c - archive_read_support_filter_uu.c - archive_read_support_filter_xz.c - archive_read_support_filter_zstd.c - archive_read_support_format_7zip.c - archive_read_support_format_all.c - archive_read_support_format_ar.c - archive_read_support_format_by_code.c - archive_read_support_format_cab.c - archive_read_support_format_cpio.c - archive_read_support_format_empty.c - archive_read_support_format_iso9660.c - archive_read_support_format_lha.c - archive_read_support_format_mtree.c - archive_read_support_format_rar.c - archive_read_support_format_rar5.c - archive_read_support_format_raw.c - archive_read_support_format_tar.c - archive_read_support_format_warc.c - archive_read_support_format_xar.c - archive_read_support_format_zip.c - archive_string.c - archive_string.h - archive_string_composition.h - archive_string_sprintf.c - archive_util.c - archive_version_details.c - archive_virtual.c - archive_write.c - archive_write_disk_posix.c - archive_write_disk_private.h - archive_write_disk_set_standard_lookup.c - archive_write_private.h - archive_write_open_fd.c - archive_write_open_file.c - archive_write_open_filename.c - archive_write_open_memory.c - archive_write_add_filter.c - archive_write_add_filter_b64encode.c - archive_write_add_filter_by_name.c - archive_write_add_filter_bzip2.c - archive_write_add_filter_compress.c - archive_write_add_filter_grzip.c - archive_write_add_filter_gzip.c - archive_write_add_filter_lrzip.c - archive_write_add_filter_lz4.c - archive_write_add_filter_lzop.c - archive_write_add_filter_none.c - archive_write_add_filter_program.c - archive_write_add_filter_uuencode.c - archive_write_add_filter_xz.c - archive_write_add_filter_zstd.c - archive_write_set_format.c - archive_write_set_format_7zip.c - archive_write_set_format_ar.c - archive_write_set_format_by_name.c - archive_write_set_format_cpio.c - archive_write_set_format_cpio_binary.c - archive_write_set_format_cpio_newc.c - archive_write_set_format_cpio_odc.c - archive_write_set_format_filter_by_ext.c - archive_write_set_format_gnutar.c - archive_write_set_format_iso9660.c - archive_write_set_format_mtree.c - archive_write_set_format_pax.c - archive_write_set_format_private.h - archive_write_set_format_raw.c - archive_write_set_format_shar.c - archive_write_set_format_ustar.c - archive_write_set_format_v7tar.c - archive_write_set_format_warc.c - archive_write_set_format_xar.c - archive_write_set_format_zip.c - archive_write_set_options.c - archive_write_set_passphrase.c - archive_xxhash.h - filter_fork_posix.c - filter_fork.h - xxhash.c -) - -# Man pages -SET(libarchive_MANS - archive_entry.3 - archive_entry_acl.3 - archive_entry_linkify.3 - archive_entry_misc.3 - archive_entry_paths.3 - archive_entry_perms.3 - archive_entry_stat.3 - archive_entry_time.3 - archive_read.3 - archive_read_add_passphrase.3 - archive_read_data.3 - archive_read_disk.3 - archive_read_extract.3 - archive_read_filter.3 - archive_read_format.3 - archive_read_free.3 - archive_read_header.3 - archive_read_new.3 - archive_read_open.3 - archive_read_set_options.3 - archive_util.3 - archive_write.3 - archive_write_blocksize.3 - archive_write_data.3 - archive_write_disk.3 - archive_write_filter.3 - archive_write_finish_entry.3 - archive_write_format.3 - archive_write_free.3 - archive_write_header.3 - archive_write_new.3 - archive_write_open.3 - archive_write_set_options.3 - archive_write_set_passphrase.3 - cpio.5 - libarchive.3 - libarchive_changes.3 - libarchive_internals.3 - libarchive-formats.5 - mtree.5 - tar.5 -) - -IF(WIN32 AND NOT CYGWIN) - LIST(APPEND libarchive_SOURCES archive_entry_copy_bhfi.c) - LIST(APPEND libarchive_SOURCES archive_read_disk_windows.c) - LIST(APPEND libarchive_SOURCES archive_windows.c) - LIST(APPEND libarchive_SOURCES archive_windows.h) - LIST(APPEND libarchive_SOURCES archive_write_disk_windows.c) - LIST(APPEND libarchive_SOURCES filter_fork_windows.c) -ENDIF(WIN32 AND NOT CYGWIN) - -IF(ARCHIVE_BLAKE2) - LIST(APPEND libarchive_SOURCES archive_blake2sp_ref.c) - LIST(APPEND libarchive_SOURCES archive_blake2s_ref.c) -ENDIF(ARCHIVE_BLAKE2) - -IF(ARCHIVE_ACL_DARWIN) - LIST(APPEND libarchive_SOURCES archive_disk_acl_darwin.c) -ELSEIF(ARCHIVE_ACL_FREEBSD) - LIST(APPEND libarchive_SOURCES archive_disk_acl_freebsd.c) -ELSEIF(ARCHIVE_ACL_LIBACL) - LIST(APPEND libarchive_SOURCES archive_disk_acl_linux.c) -ELSEIF(ARCHIVE_ACL_SUNOS) - LIST(APPEND libarchive_SOURCES archive_disk_acl_sunos.c) -ENDIF() - -# Libarchive is a shared library -IF(BUILD_SHARED_LIBS) - ADD_LIBRARY(archive SHARED ${libarchive_SOURCES} ${include_HEADERS}) - TARGET_INCLUDE_DIRECTORIES(archive PUBLIC .) - TARGET_LINK_LIBRARIES(archive ${ADDITIONAL_LIBS}) - SET_TARGET_PROPERTIES(archive PROPERTIES SOVERSION ${SOVERSION}) -ENDIF(BUILD_SHARED_LIBS) - -# archive_static is a static library -ADD_LIBRARY(archive_static STATIC ${libarchive_SOURCES} ${include_HEADERS}) -TARGET_LINK_LIBRARIES(archive_static ${ADDITIONAL_LIBS}) -SET_TARGET_PROPERTIES(archive_static PROPERTIES COMPILE_DEFINITIONS - LIBARCHIVE_STATIC) -# On Posix systems, libarchive.so and libarchive.a can co-exist. -IF(NOT WIN32 OR CYGWIN OR NOT BUILD_SHARED_LIBS) - SET_TARGET_PROPERTIES(archive_static PROPERTIES OUTPUT_NAME archive) -ENDIF(NOT WIN32 OR CYGWIN OR NOT BUILD_SHARED_LIBS) - -IF(ENABLE_INSTALL) - # How to install the libraries - IF(BUILD_SHARED_LIBS) - INSTALL(TARGETS archive - RUNTIME DESTINATION bin - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib) - ENDIF(BUILD_SHARED_LIBS) - INSTALL(TARGETS archive_static - RUNTIME DESTINATION bin - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib) - INSTALL_MAN(${libarchive_MANS}) - INSTALL(FILES ${include_HEADERS} DESTINATION include) -ENDIF() - -add_subdirectory(test) diff --git a/thirdparty/libarchive/libarchive/archive.h b/thirdparty/libarchive/libarchive/archive.h deleted file mode 100644 index a18b81fc2..000000000 --- a/thirdparty/libarchive/libarchive/archive.h +++ /dev/null @@ -1,1212 +0,0 @@ -/*- - * Copyright (c) 2003-2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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/libarchive/archive.h.in,v 1.50 2008/05/26 17:00:22 kientzle Exp $ - */ - -#ifndef ARCHIVE_H_INCLUDED -#define ARCHIVE_H_INCLUDED - -/* - * The version number is expressed as a single integer that makes it - * easy to compare versions at build time: for version a.b.c, the - * version number is printf("%d%03d%03d",a,b,c). For example, if you - * know your application requires version 2.12.108 or later, you can - * assert that ARCHIVE_VERSION_NUMBER >= 2012108. - */ -/* Note: Compiler will complain if this does not match archive_entry.h! */ -#define ARCHIVE_VERSION_NUMBER 3007002 - -#include -#include /* for wchar_t */ -#include /* For FILE * */ -#include /* For time_t */ - -/* - * Note: archive.h is for use outside of libarchive; the configuration - * headers (config.h, archive_platform.h, etc.) are purely internal. - * Do NOT use HAVE_XXX configuration macros to control the behavior of - * this header! If you must conditionalize, use predefined compiler and/or - * platform macros. - */ -#if defined(__BORLANDC__) && __BORLANDC__ >= 0x560 -# include -#elif !defined(__WATCOMC__) && !defined(_MSC_VER) && !defined(__INTERIX) && !defined(__BORLANDC__) && !defined(_SCO_DS) && !defined(__osf__) && !defined(__CLANG_INTTYPES_H) -# include -#endif - -/* Get appropriate definitions of 64-bit integer */ -#if !defined(__LA_INT64_T_DEFINED) -/* Older code relied on the __LA_INT64_T macro; after 4.0 we'll switch to the typedef exclusively. */ -# if ARCHIVE_VERSION_NUMBER < 4000000 -#define __LA_INT64_T la_int64_t -# endif -#define __LA_INT64_T_DEFINED -# if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__) -typedef __int64 la_int64_t; -# else -# include /* ssize_t */ -# if defined(_SCO_DS) || defined(__osf__) -typedef long long la_int64_t; -# else -typedef int64_t la_int64_t; -# endif -# endif -#endif - -/* The la_ssize_t should match the type used in 'struct stat' */ -#if !defined(__LA_SSIZE_T_DEFINED) -/* Older code relied on the __LA_SSIZE_T macro; after 4.0 we'll switch to the typedef exclusively. */ -# if ARCHIVE_VERSION_NUMBER < 4000000 -#define __LA_SSIZE_T la_ssize_t -# endif -#define __LA_SSIZE_T_DEFINED -# if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__) -# if defined(_SSIZE_T_DEFINED) || defined(_SSIZE_T_) -typedef ssize_t la_ssize_t; -# elif defined(_WIN64) -typedef __int64 la_ssize_t; -# else -typedef long la_ssize_t; -# endif -# else -# include /* ssize_t */ -typedef ssize_t la_ssize_t; -# endif -#endif - -/* Large file support for Android */ -#if defined(__LIBARCHIVE_BUILD) && defined(__ANDROID__) -#include "android_lf.h" -#endif - -/* - * On Windows, define LIBARCHIVE_STATIC if you're building or using a - * .lib. The default here assumes you're building a DLL. Only - * libarchive source should ever define __LIBARCHIVE_BUILD. - */ -#if ((defined __WIN32__) || (defined _WIN32) || defined(__CYGWIN__)) && (!defined LIBARCHIVE_STATIC) -# ifdef __LIBARCHIVE_BUILD -# ifdef __GNUC__ -# define __LA_DECL __attribute__((dllexport)) extern -# else -# define __LA_DECL __declspec(dllexport) -# endif -# else -# ifdef __GNUC__ -# define __LA_DECL -# else -# define __LA_DECL __declspec(dllimport) -# endif -# endif -#elif defined __LIBARCHIVE_ENABLE_VISIBILITY -# define __LA_DECL __attribute__((visibility("default"))) -#else -/* Static libraries or non-Windows needs no special declaration. */ -# define __LA_DECL -#endif - -#if defined(__GNUC__) && __GNUC__ >= 3 && !defined(__MINGW32__) -#define __LA_PRINTF(fmtarg, firstvararg) \ - __attribute__((__format__ (__printf__, fmtarg, firstvararg))) -#else -#define __LA_PRINTF(fmtarg, firstvararg) /* nothing */ -#endif - -#if defined(__GNUC__) && __GNUC__ >= 3 && __GNUC_MINOR__ >= 1 -# define __LA_DEPRECATED __attribute__((deprecated)) -#else -# define __LA_DEPRECATED -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * The version number is provided as both a macro and a function. - * The macro identifies the installed header; the function identifies - * the library version (which may not be the same if you're using a - * dynamically-linked version of the library). Of course, if the - * header and library are very different, you should expect some - * strangeness. Don't do that. - */ -__LA_DECL int archive_version_number(void); - -/* - * Textual name/version of the library, useful for version displays. - */ -#define ARCHIVE_VERSION_ONLY_STRING "3.7.2" -#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING -__LA_DECL const char * archive_version_string(void); - -/* - * Detailed textual name/version of the library and its dependencies. - * This has the form: - * "libarchive x.y.z zlib/a.b.c liblzma/d.e.f ... etc ..." - * the list of libraries described here will vary depending on how - * libarchive was compiled. - */ -__LA_DECL const char * archive_version_details(void); - -/* - * Returns NULL if libarchive was compiled without the associated library. - * Otherwise, returns the version number that libarchive was compiled - * against. - */ -__LA_DECL const char * archive_zlib_version(void); -__LA_DECL const char * archive_liblzma_version(void); -__LA_DECL const char * archive_bzlib_version(void); -__LA_DECL const char * archive_liblz4_version(void); -__LA_DECL const char * archive_libzstd_version(void); - -/* Declare our basic types. */ -struct archive; -struct archive_entry; - -/* - * Error codes: Use archive_errno() and archive_error_string() - * to retrieve details. Unless specified otherwise, all functions - * that return 'int' use these codes. - */ -#define ARCHIVE_EOF 1 /* Found end of archive. */ -#define ARCHIVE_OK 0 /* Operation was successful. */ -#define ARCHIVE_RETRY (-10) /* Retry might succeed. */ -#define ARCHIVE_WARN (-20) /* Partial success. */ -/* For example, if write_header "fails", then you can't push data. */ -#define ARCHIVE_FAILED (-25) /* Current operation cannot complete. */ -/* But if write_header is "fatal," then this archive is dead and useless. */ -#define ARCHIVE_FATAL (-30) /* No more operations are possible. */ - -/* - * As far as possible, archive_errno returns standard platform errno codes. - * Of course, the details vary by platform, so the actual definitions - * here are stored in "archive_platform.h". The symbols are listed here - * for reference; as a rule, clients should not need to know the exact - * platform-dependent error code. - */ -/* Unrecognized or invalid file format. */ -/* #define ARCHIVE_ERRNO_FILE_FORMAT */ -/* Illegal usage of the library. */ -/* #define ARCHIVE_ERRNO_PROGRAMMER_ERROR */ -/* Unknown or unclassified error. */ -/* #define ARCHIVE_ERRNO_MISC */ - -/* - * Callbacks are invoked to automatically read/skip/write/open/close the - * archive. You can provide your own for complex tasks (like breaking - * archives across multiple tapes) or use standard ones built into the - * library. - */ - -/* Returns pointer and size of next block of data from archive. */ -typedef la_ssize_t archive_read_callback(struct archive *, - void *_client_data, const void **_buffer); - -/* Skips at most request bytes from archive and returns the skipped amount. - * This may skip fewer bytes than requested; it may even skip zero bytes. - * If you do skip fewer bytes than requested, libarchive will invoke your - * read callback and discard data as necessary to make up the full skip. - */ -typedef la_int64_t archive_skip_callback(struct archive *, - void *_client_data, la_int64_t request); - -/* Seeks to specified location in the file and returns the position. - * Whence values are SEEK_SET, SEEK_CUR, SEEK_END from stdio.h. - * Return ARCHIVE_FATAL if the seek fails for any reason. - */ -typedef la_int64_t archive_seek_callback(struct archive *, - void *_client_data, la_int64_t offset, int whence); - -/* Returns size actually written, zero on EOF, -1 on error. */ -typedef la_ssize_t archive_write_callback(struct archive *, - void *_client_data, - const void *_buffer, size_t _length); - -typedef int archive_open_callback(struct archive *, void *_client_data); - -typedef int archive_close_callback(struct archive *, void *_client_data); - -typedef int archive_free_callback(struct archive *, void *_client_data); - -/* Switches from one client data object to the next/prev client data object. - * This is useful for reading from different data blocks such as a set of files - * that make up one large file. - */ -typedef int archive_switch_callback(struct archive *, void *_client_data1, - void *_client_data2); - -/* - * Returns a passphrase used for encryption or decryption, NULL on nothing - * to do and give it up. - */ -typedef const char *archive_passphrase_callback(struct archive *, - void *_client_data); - -/* - * Codes to identify various stream filters. - */ -#define ARCHIVE_FILTER_NONE 0 -#define ARCHIVE_FILTER_GZIP 1 -#define ARCHIVE_FILTER_BZIP2 2 -#define ARCHIVE_FILTER_COMPRESS 3 -#define ARCHIVE_FILTER_PROGRAM 4 -#define ARCHIVE_FILTER_LZMA 5 -#define ARCHIVE_FILTER_XZ 6 -#define ARCHIVE_FILTER_UU 7 -#define ARCHIVE_FILTER_RPM 8 -#define ARCHIVE_FILTER_LZIP 9 -#define ARCHIVE_FILTER_LRZIP 10 -#define ARCHIVE_FILTER_LZOP 11 -#define ARCHIVE_FILTER_GRZIP 12 -#define ARCHIVE_FILTER_LZ4 13 -#define ARCHIVE_FILTER_ZSTD 14 - -#if ARCHIVE_VERSION_NUMBER < 4000000 -#define ARCHIVE_COMPRESSION_NONE ARCHIVE_FILTER_NONE -#define ARCHIVE_COMPRESSION_GZIP ARCHIVE_FILTER_GZIP -#define ARCHIVE_COMPRESSION_BZIP2 ARCHIVE_FILTER_BZIP2 -#define ARCHIVE_COMPRESSION_COMPRESS ARCHIVE_FILTER_COMPRESS -#define ARCHIVE_COMPRESSION_PROGRAM ARCHIVE_FILTER_PROGRAM -#define ARCHIVE_COMPRESSION_LZMA ARCHIVE_FILTER_LZMA -#define ARCHIVE_COMPRESSION_XZ ARCHIVE_FILTER_XZ -#define ARCHIVE_COMPRESSION_UU ARCHIVE_FILTER_UU -#define ARCHIVE_COMPRESSION_RPM ARCHIVE_FILTER_RPM -#define ARCHIVE_COMPRESSION_LZIP ARCHIVE_FILTER_LZIP -#define ARCHIVE_COMPRESSION_LRZIP ARCHIVE_FILTER_LRZIP -#endif - -/* - * Codes returned by archive_format. - * - * Top 16 bits identifies the format family (e.g., "tar"); lower - * 16 bits indicate the variant. This is updated by read_next_header. - * Note that the lower 16 bits will often vary from entry to entry. - * In some cases, this variation occurs as libarchive learns more about - * the archive (for example, later entries might utilize extensions that - * weren't necessary earlier in the archive; in this case, libarchive - * will change the format code to indicate the extended format that - * was used). In other cases, it's because different tools have - * modified the archive and so different parts of the archive - * actually have slightly different formats. (Both tar and cpio store - * format codes in each entry, so it is quite possible for each - * entry to be in a different format.) - */ -#define ARCHIVE_FORMAT_BASE_MASK 0xff0000 -#define ARCHIVE_FORMAT_CPIO 0x10000 -#define ARCHIVE_FORMAT_CPIO_POSIX (ARCHIVE_FORMAT_CPIO | 1) -#define ARCHIVE_FORMAT_CPIO_BIN_LE (ARCHIVE_FORMAT_CPIO | 2) -#define ARCHIVE_FORMAT_CPIO_BIN_BE (ARCHIVE_FORMAT_CPIO | 3) -#define ARCHIVE_FORMAT_CPIO_SVR4_NOCRC (ARCHIVE_FORMAT_CPIO | 4) -#define ARCHIVE_FORMAT_CPIO_SVR4_CRC (ARCHIVE_FORMAT_CPIO | 5) -#define ARCHIVE_FORMAT_CPIO_AFIO_LARGE (ARCHIVE_FORMAT_CPIO | 6) -#define ARCHIVE_FORMAT_CPIO_PWB (ARCHIVE_FORMAT_CPIO | 7) -#define ARCHIVE_FORMAT_SHAR 0x20000 -#define ARCHIVE_FORMAT_SHAR_BASE (ARCHIVE_FORMAT_SHAR | 1) -#define ARCHIVE_FORMAT_SHAR_DUMP (ARCHIVE_FORMAT_SHAR | 2) -#define ARCHIVE_FORMAT_TAR 0x30000 -#define ARCHIVE_FORMAT_TAR_USTAR (ARCHIVE_FORMAT_TAR | 1) -#define ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE (ARCHIVE_FORMAT_TAR | 2) -#define ARCHIVE_FORMAT_TAR_PAX_RESTRICTED (ARCHIVE_FORMAT_TAR | 3) -#define ARCHIVE_FORMAT_TAR_GNUTAR (ARCHIVE_FORMAT_TAR | 4) -#define ARCHIVE_FORMAT_ISO9660 0x40000 -#define ARCHIVE_FORMAT_ISO9660_ROCKRIDGE (ARCHIVE_FORMAT_ISO9660 | 1) -#define ARCHIVE_FORMAT_ZIP 0x50000 -#define ARCHIVE_FORMAT_EMPTY 0x60000 -#define ARCHIVE_FORMAT_AR 0x70000 -#define ARCHIVE_FORMAT_AR_GNU (ARCHIVE_FORMAT_AR | 1) -#define ARCHIVE_FORMAT_AR_BSD (ARCHIVE_FORMAT_AR | 2) -#define ARCHIVE_FORMAT_MTREE 0x80000 -#define ARCHIVE_FORMAT_RAW 0x90000 -#define ARCHIVE_FORMAT_XAR 0xA0000 -#define ARCHIVE_FORMAT_LHA 0xB0000 -#define ARCHIVE_FORMAT_CAB 0xC0000 -#define ARCHIVE_FORMAT_RAR 0xD0000 -#define ARCHIVE_FORMAT_7ZIP 0xE0000 -#define ARCHIVE_FORMAT_WARC 0xF0000 -#define ARCHIVE_FORMAT_RAR_V5 0x100000 - -/* - * Codes returned by archive_read_format_capabilities(). - * - * This list can be extended with values between 0 and 0xffff. - * The original purpose of this list was to let different archive - * format readers expose their general capabilities in terms of - * encryption. - */ -#define ARCHIVE_READ_FORMAT_CAPS_NONE (0) /* no special capabilities */ -#define ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA (1<<0) /* reader can detect encrypted data */ -#define ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA (1<<1) /* reader can detect encryptable metadata (pathname, mtime, etc.) */ - -/* - * Codes returned by archive_read_has_encrypted_entries(). - * - * In case the archive does not support encryption detection at all - * ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED is returned. If the reader - * for some other reason (e.g. not enough bytes read) cannot say if - * there are encrypted entries, ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW - * is returned. - */ -#define ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED -2 -#define ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW -1 - -/*- - * Basic outline for reading an archive: - * 1) Ask archive_read_new for an archive reader object. - * 2) Update any global properties as appropriate. - * In particular, you'll certainly want to call appropriate - * archive_read_support_XXX functions. - * 3) Call archive_read_open_XXX to open the archive - * 4) Repeatedly call archive_read_next_header to get information about - * successive archive entries. Call archive_read_data to extract - * data for entries of interest. - * 5) Call archive_read_free to end processing. - */ -__LA_DECL struct archive *archive_read_new(void); - -/* - * The archive_read_support_XXX calls enable auto-detect for this - * archive handle. They also link in the necessary support code. - * For example, if you don't want bzlib linked in, don't invoke - * support_compression_bzip2(). The "all" functions provide the - * obvious shorthand. - */ - -#if ARCHIVE_VERSION_NUMBER < 4000000 -__LA_DECL int archive_read_support_compression_all(struct archive *) - __LA_DEPRECATED; -__LA_DECL int archive_read_support_compression_bzip2(struct archive *) - __LA_DEPRECATED; -__LA_DECL int archive_read_support_compression_compress(struct archive *) - __LA_DEPRECATED; -__LA_DECL int archive_read_support_compression_gzip(struct archive *) - __LA_DEPRECATED; -__LA_DECL int archive_read_support_compression_lzip(struct archive *) - __LA_DEPRECATED; -__LA_DECL int archive_read_support_compression_lzma(struct archive *) - __LA_DEPRECATED; -__LA_DECL int archive_read_support_compression_none(struct archive *) - __LA_DEPRECATED; -__LA_DECL int archive_read_support_compression_program(struct archive *, - const char *command) __LA_DEPRECATED; -__LA_DECL int archive_read_support_compression_program_signature - (struct archive *, const char *, - const void * /* match */, size_t) __LA_DEPRECATED; - -__LA_DECL int archive_read_support_compression_rpm(struct archive *) - __LA_DEPRECATED; -__LA_DECL int archive_read_support_compression_uu(struct archive *) - __LA_DEPRECATED; -__LA_DECL int archive_read_support_compression_xz(struct archive *) - __LA_DEPRECATED; -#endif - -__LA_DECL int archive_read_support_filter_all(struct archive *); -__LA_DECL int archive_read_support_filter_by_code(struct archive *, int); -__LA_DECL int archive_read_support_filter_bzip2(struct archive *); -__LA_DECL int archive_read_support_filter_compress(struct archive *); -__LA_DECL int archive_read_support_filter_gzip(struct archive *); -__LA_DECL int archive_read_support_filter_grzip(struct archive *); -__LA_DECL int archive_read_support_filter_lrzip(struct archive *); -__LA_DECL int archive_read_support_filter_lz4(struct archive *); -__LA_DECL int archive_read_support_filter_lzip(struct archive *); -__LA_DECL int archive_read_support_filter_lzma(struct archive *); -__LA_DECL int archive_read_support_filter_lzop(struct archive *); -__LA_DECL int archive_read_support_filter_none(struct archive *); -__LA_DECL int archive_read_support_filter_program(struct archive *, - const char *command); -__LA_DECL int archive_read_support_filter_program_signature - (struct archive *, const char * /* cmd */, - const void * /* match */, size_t); -__LA_DECL int archive_read_support_filter_rpm(struct archive *); -__LA_DECL int archive_read_support_filter_uu(struct archive *); -__LA_DECL int archive_read_support_filter_xz(struct archive *); -__LA_DECL int archive_read_support_filter_zstd(struct archive *); - -__LA_DECL int archive_read_support_format_7zip(struct archive *); -__LA_DECL int archive_read_support_format_all(struct archive *); -__LA_DECL int archive_read_support_format_ar(struct archive *); -__LA_DECL int archive_read_support_format_by_code(struct archive *, int); -__LA_DECL int archive_read_support_format_cab(struct archive *); -__LA_DECL int archive_read_support_format_cpio(struct archive *); -__LA_DECL int archive_read_support_format_empty(struct archive *); -__LA_DECL int archive_read_support_format_gnutar(struct archive *); -__LA_DECL int archive_read_support_format_iso9660(struct archive *); -__LA_DECL int archive_read_support_format_lha(struct archive *); -__LA_DECL int archive_read_support_format_mtree(struct archive *); -__LA_DECL int archive_read_support_format_rar(struct archive *); -__LA_DECL int archive_read_support_format_rar5(struct archive *); -__LA_DECL int archive_read_support_format_raw(struct archive *); -__LA_DECL int archive_read_support_format_tar(struct archive *); -__LA_DECL int archive_read_support_format_warc(struct archive *); -__LA_DECL int archive_read_support_format_xar(struct archive *); -/* archive_read_support_format_zip() enables both streamable and seekable - * zip readers. */ -__LA_DECL int archive_read_support_format_zip(struct archive *); -/* Reads Zip archives as stream from beginning to end. Doesn't - * correctly handle SFX ZIP files or ZIP archives that have been modified - * in-place. */ -__LA_DECL int archive_read_support_format_zip_streamable(struct archive *); -/* Reads starting from central directory; requires seekable input. */ -__LA_DECL int archive_read_support_format_zip_seekable(struct archive *); - -/* Functions to manually set the format and filters to be used. This is - * useful to bypass the bidding process when the format and filters to use - * is known in advance. - */ -__LA_DECL int archive_read_set_format(struct archive *, int); -__LA_DECL int archive_read_append_filter(struct archive *, int); -__LA_DECL int archive_read_append_filter_program(struct archive *, - const char *); -__LA_DECL int archive_read_append_filter_program_signature - (struct archive *, const char *, const void * /* match */, size_t); - -/* Set various callbacks. */ -__LA_DECL int archive_read_set_open_callback(struct archive *, - archive_open_callback *); -__LA_DECL int archive_read_set_read_callback(struct archive *, - archive_read_callback *); -__LA_DECL int archive_read_set_seek_callback(struct archive *, - archive_seek_callback *); -__LA_DECL int archive_read_set_skip_callback(struct archive *, - archive_skip_callback *); -__LA_DECL int archive_read_set_close_callback(struct archive *, - archive_close_callback *); -/* Callback used to switch between one data object to the next */ -__LA_DECL int archive_read_set_switch_callback(struct archive *, - archive_switch_callback *); - -/* This sets the first data object. */ -__LA_DECL int archive_read_set_callback_data(struct archive *, void *); -/* This sets data object at specified index */ -__LA_DECL int archive_read_set_callback_data2(struct archive *, void *, - unsigned int); -/* This adds a data object at the specified index. */ -__LA_DECL int archive_read_add_callback_data(struct archive *, void *, - unsigned int); -/* This appends a data object to the end of list */ -__LA_DECL int archive_read_append_callback_data(struct archive *, void *); -/* This prepends a data object to the beginning of list */ -__LA_DECL int archive_read_prepend_callback_data(struct archive *, void *); - -/* Opening freezes the callbacks. */ -__LA_DECL int archive_read_open1(struct archive *); - -/* Convenience wrappers around the above. */ -__LA_DECL int archive_read_open(struct archive *, void *_client_data, - archive_open_callback *, archive_read_callback *, - archive_close_callback *); -__LA_DECL int archive_read_open2(struct archive *, void *_client_data, - archive_open_callback *, archive_read_callback *, - archive_skip_callback *, archive_close_callback *); - -/* - * A variety of shortcuts that invoke archive_read_open() with - * canned callbacks suitable for common situations. The ones that - * accept a block size handle tape blocking correctly. - */ -/* Use this if you know the filename. Note: NULL indicates stdin. */ -__LA_DECL int archive_read_open_filename(struct archive *, - const char *_filename, size_t _block_size); -/* Use this for reading multivolume files by filenames. - * NOTE: Must be NULL terminated. Sorting is NOT done. */ -__LA_DECL int archive_read_open_filenames(struct archive *, - const char **_filenames, size_t _block_size); -__LA_DECL int archive_read_open_filename_w(struct archive *, - const wchar_t *_filename, size_t _block_size); -/* archive_read_open_file() is a deprecated synonym for ..._open_filename(). */ -__LA_DECL int archive_read_open_file(struct archive *, - const char *_filename, size_t _block_size) __LA_DEPRECATED; -/* Read an archive that's stored in memory. */ -__LA_DECL int archive_read_open_memory(struct archive *, - const void * buff, size_t size); -/* A more involved version that is only used for internal testing. */ -__LA_DECL int archive_read_open_memory2(struct archive *a, const void *buff, - size_t size, size_t read_size); -/* Read an archive that's already open, using the file descriptor. */ -__LA_DECL int archive_read_open_fd(struct archive *, int _fd, - size_t _block_size); -/* Read an archive that's already open, using a FILE *. */ -/* Note: DO NOT use this with tape drives. */ -__LA_DECL int archive_read_open_FILE(struct archive *, FILE *_file); - -/* Parses and returns next entry header. */ -__LA_DECL int archive_read_next_header(struct archive *, - struct archive_entry **); - -/* Parses and returns next entry header using the archive_entry passed in */ -__LA_DECL int archive_read_next_header2(struct archive *, - struct archive_entry *); - -/* - * Retrieve the byte offset in UNCOMPRESSED data where last-read - * header started. - */ -__LA_DECL la_int64_t archive_read_header_position(struct archive *); - -/* - * Returns 1 if the archive contains at least one encrypted entry. - * If the archive format not support encryption at all - * ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED is returned. - * If for any other reason (e.g. not enough data read so far) - * we cannot say whether there are encrypted entries, then - * ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW is returned. - * In general, this function will return values below zero when the - * reader is uncertain or totally incapable of encryption support. - * When this function returns 0 you can be sure that the reader - * supports encryption detection but no encrypted entries have - * been found yet. - * - * NOTE: If the metadata/header of an archive is also encrypted, you - * cannot rely on the number of encrypted entries. That is why this - * function does not return the number of encrypted entries but# - * just shows that there are some. - */ -__LA_DECL int archive_read_has_encrypted_entries(struct archive *); - -/* - * Returns a bitmask of capabilities that are supported by the archive format reader. - * If the reader has no special capabilities, ARCHIVE_READ_FORMAT_CAPS_NONE is returned. - */ -__LA_DECL int archive_read_format_capabilities(struct archive *); - -/* Read data from the body of an entry. Similar to read(2). */ -__LA_DECL la_ssize_t archive_read_data(struct archive *, - void *, size_t); - -/* Seek within the body of an entry. Similar to lseek(2). */ -__LA_DECL la_int64_t archive_seek_data(struct archive *, la_int64_t, int); - -/* - * A zero-copy version of archive_read_data that also exposes the file offset - * of each returned block. Note that the client has no way to specify - * the desired size of the block. The API does guarantee that offsets will - * be strictly increasing and that returned blocks will not overlap. - */ -__LA_DECL int archive_read_data_block(struct archive *a, - const void **buff, size_t *size, la_int64_t *offset); - -/*- - * Some convenience functions that are built on archive_read_data: - * 'skip': skips entire entry - * 'into_buffer': writes data into memory buffer that you provide - * 'into_fd': writes data to specified filedes - */ -__LA_DECL int archive_read_data_skip(struct archive *); -__LA_DECL int archive_read_data_into_fd(struct archive *, int fd); - -/* - * Set read options. - */ -/* Apply option to the format only. */ -__LA_DECL int archive_read_set_format_option(struct archive *_a, - const char *m, const char *o, - const char *v); -/* Apply option to the filter only. */ -__LA_DECL int archive_read_set_filter_option(struct archive *_a, - const char *m, const char *o, - const char *v); -/* Apply option to both the format and the filter. */ -__LA_DECL int archive_read_set_option(struct archive *_a, - const char *m, const char *o, - const char *v); -/* Apply option string to both the format and the filter. */ -__LA_DECL int archive_read_set_options(struct archive *_a, - const char *opts); - -/* - * Add a decryption passphrase. - */ -__LA_DECL int archive_read_add_passphrase(struct archive *, const char *); -__LA_DECL int archive_read_set_passphrase_callback(struct archive *, - void *client_data, archive_passphrase_callback *); - - -/*- - * Convenience function to recreate the current entry (whose header - * has just been read) on disk. - * - * This does quite a bit more than just copy data to disk. It also: - * - Creates intermediate directories as required. - * - Manages directory permissions: non-writable directories will - * be initially created with write permission enabled; when the - * archive is closed, dir permissions are edited to the values specified - * in the archive. - * - Checks hardlinks: hardlinks will not be extracted unless the - * linked-to file was also extracted within the same session. (TODO) - */ - -/* The "flags" argument selects optional behavior, 'OR' the flags you want. */ - -/* Default: Do not try to set owner/group. */ -#define ARCHIVE_EXTRACT_OWNER (0x0001) -/* Default: Do obey umask, do not restore SUID/SGID/SVTX bits. */ -#define ARCHIVE_EXTRACT_PERM (0x0002) -/* Default: Do not restore mtime/atime. */ -#define ARCHIVE_EXTRACT_TIME (0x0004) -/* Default: Replace existing files. */ -#define ARCHIVE_EXTRACT_NO_OVERWRITE (0x0008) -/* Default: Try create first, unlink only if create fails with EEXIST. */ -#define ARCHIVE_EXTRACT_UNLINK (0x0010) -/* Default: Do not restore ACLs. */ -#define ARCHIVE_EXTRACT_ACL (0x0020) -/* Default: Do not restore fflags. */ -#define ARCHIVE_EXTRACT_FFLAGS (0x0040) -/* Default: Do not restore xattrs. */ -#define ARCHIVE_EXTRACT_XATTR (0x0080) -/* Default: Do not try to guard against extracts redirected by symlinks. */ -/* Note: With ARCHIVE_EXTRACT_UNLINK, will remove any intermediate symlink. */ -#define ARCHIVE_EXTRACT_SECURE_SYMLINKS (0x0100) -/* Default: Do not reject entries with '..' as path elements. */ -#define ARCHIVE_EXTRACT_SECURE_NODOTDOT (0x0200) -/* Default: Create parent directories as needed. */ -#define ARCHIVE_EXTRACT_NO_AUTODIR (0x0400) -/* Default: Overwrite files, even if one on disk is newer. */ -#define ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER (0x0800) -/* Detect blocks of 0 and write holes instead. */ -#define ARCHIVE_EXTRACT_SPARSE (0x1000) -/* Default: Do not restore Mac extended metadata. */ -/* This has no effect except on Mac OS. */ -#define ARCHIVE_EXTRACT_MAC_METADATA (0x2000) -/* Default: Use HFS+ compression if it was compressed. */ -/* This has no effect except on Mac OS v10.6 or later. */ -#define ARCHIVE_EXTRACT_NO_HFS_COMPRESSION (0x4000) -/* Default: Do not use HFS+ compression if it was not compressed. */ -/* This has no effect except on Mac OS v10.6 or later. */ -#define ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED (0x8000) -/* Default: Do not reject entries with absolute paths */ -#define ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS (0x10000) -/* Default: Do not clear no-change flags when unlinking object */ -#define ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS (0x20000) -/* Default: Do not extract atomically (using rename) */ -#define ARCHIVE_EXTRACT_SAFE_WRITES (0x40000) - -__LA_DECL int archive_read_extract(struct archive *, struct archive_entry *, - int flags); -__LA_DECL int archive_read_extract2(struct archive *, struct archive_entry *, - struct archive * /* dest */); -__LA_DECL void archive_read_extract_set_progress_callback(struct archive *, - void (*_progress_func)(void *), void *_user_data); - -/* Record the dev/ino of a file that will not be written. This is - * generally set to the dev/ino of the archive being read. */ -__LA_DECL void archive_read_extract_set_skip_file(struct archive *, - la_int64_t, la_int64_t); - -/* Close the file and release most resources. */ -__LA_DECL int archive_read_close(struct archive *); -/* Release all resources and destroy the object. */ -/* Note that archive_read_free will call archive_read_close for you. */ -__LA_DECL int archive_read_free(struct archive *); -#if ARCHIVE_VERSION_NUMBER < 4000000 -/* Synonym for archive_read_free() for backwards compatibility. */ -__LA_DECL int archive_read_finish(struct archive *) __LA_DEPRECATED; -#endif - -/*- - * To create an archive: - * 1) Ask archive_write_new for an archive writer object. - * 2) Set any global properties. In particular, you should set - * the compression and format to use. - * 3) Call archive_write_open to open the file (most people - * will use archive_write_open_file or archive_write_open_fd, - * which provide convenient canned I/O callbacks for you). - * 4) For each entry: - * - construct an appropriate struct archive_entry structure - * - archive_write_header to write the header - * - archive_write_data to write the entry data - * 5) archive_write_close to close the output - * 6) archive_write_free to cleanup the writer and release resources - */ -__LA_DECL struct archive *archive_write_new(void); -__LA_DECL int archive_write_set_bytes_per_block(struct archive *, - int bytes_per_block); -__LA_DECL int archive_write_get_bytes_per_block(struct archive *); -/* XXX This is badly misnamed; suggestions appreciated. XXX */ -__LA_DECL int archive_write_set_bytes_in_last_block(struct archive *, - int bytes_in_last_block); -__LA_DECL int archive_write_get_bytes_in_last_block(struct archive *); - -/* The dev/ino of a file that won't be archived. This is used - * to avoid recursively adding an archive to itself. */ -__LA_DECL int archive_write_set_skip_file(struct archive *, - la_int64_t, la_int64_t); - -#if ARCHIVE_VERSION_NUMBER < 4000000 -__LA_DECL int archive_write_set_compression_bzip2(struct archive *) - __LA_DEPRECATED; -__LA_DECL int archive_write_set_compression_compress(struct archive *) - __LA_DEPRECATED; -__LA_DECL int archive_write_set_compression_gzip(struct archive *) - __LA_DEPRECATED; -__LA_DECL int archive_write_set_compression_lzip(struct archive *) - __LA_DEPRECATED; -__LA_DECL int archive_write_set_compression_lzma(struct archive *) - __LA_DEPRECATED; -__LA_DECL int archive_write_set_compression_none(struct archive *) - __LA_DEPRECATED; -__LA_DECL int archive_write_set_compression_program(struct archive *, - const char *cmd) __LA_DEPRECATED; -__LA_DECL int archive_write_set_compression_xz(struct archive *) - __LA_DEPRECATED; -#endif - -/* A convenience function to set the filter based on the code. */ -__LA_DECL int archive_write_add_filter(struct archive *, int filter_code); -__LA_DECL int archive_write_add_filter_by_name(struct archive *, - const char *name); -__LA_DECL int archive_write_add_filter_b64encode(struct archive *); -__LA_DECL int archive_write_add_filter_bzip2(struct archive *); -__LA_DECL int archive_write_add_filter_compress(struct archive *); -__LA_DECL int archive_write_add_filter_grzip(struct archive *); -__LA_DECL int archive_write_add_filter_gzip(struct archive *); -__LA_DECL int archive_write_add_filter_lrzip(struct archive *); -__LA_DECL int archive_write_add_filter_lz4(struct archive *); -__LA_DECL int archive_write_add_filter_lzip(struct archive *); -__LA_DECL int archive_write_add_filter_lzma(struct archive *); -__LA_DECL int archive_write_add_filter_lzop(struct archive *); -__LA_DECL int archive_write_add_filter_none(struct archive *); -__LA_DECL int archive_write_add_filter_program(struct archive *, - const char *cmd); -__LA_DECL int archive_write_add_filter_uuencode(struct archive *); -__LA_DECL int archive_write_add_filter_xz(struct archive *); -__LA_DECL int archive_write_add_filter_zstd(struct archive *); - - -/* A convenience function to set the format based on the code or name. */ -__LA_DECL int archive_write_set_format(struct archive *, int format_code); -__LA_DECL int archive_write_set_format_by_name(struct archive *, - const char *name); -/* To minimize link pollution, use one or more of the following. */ -__LA_DECL int archive_write_set_format_7zip(struct archive *); -__LA_DECL int archive_write_set_format_ar_bsd(struct archive *); -__LA_DECL int archive_write_set_format_ar_svr4(struct archive *); -__LA_DECL int archive_write_set_format_cpio(struct archive *); -__LA_DECL int archive_write_set_format_cpio_bin(struct archive *); -__LA_DECL int archive_write_set_format_cpio_newc(struct archive *); -__LA_DECL int archive_write_set_format_cpio_odc(struct archive *); -__LA_DECL int archive_write_set_format_cpio_pwb(struct archive *); -__LA_DECL int archive_write_set_format_gnutar(struct archive *); -__LA_DECL int archive_write_set_format_iso9660(struct archive *); -__LA_DECL int archive_write_set_format_mtree(struct archive *); -__LA_DECL int archive_write_set_format_mtree_classic(struct archive *); -/* TODO: int archive_write_set_format_old_tar(struct archive *); */ -__LA_DECL int archive_write_set_format_pax(struct archive *); -__LA_DECL int archive_write_set_format_pax_restricted(struct archive *); -__LA_DECL int archive_write_set_format_raw(struct archive *); -__LA_DECL int archive_write_set_format_shar(struct archive *); -__LA_DECL int archive_write_set_format_shar_dump(struct archive *); -__LA_DECL int archive_write_set_format_ustar(struct archive *); -__LA_DECL int archive_write_set_format_v7tar(struct archive *); -__LA_DECL int archive_write_set_format_warc(struct archive *); -__LA_DECL int archive_write_set_format_xar(struct archive *); -__LA_DECL int archive_write_set_format_zip(struct archive *); -__LA_DECL int archive_write_set_format_filter_by_ext(struct archive *a, const char *filename); -__LA_DECL int archive_write_set_format_filter_by_ext_def(struct archive *a, const char *filename, const char * def_ext); -__LA_DECL int archive_write_zip_set_compression_deflate(struct archive *); -__LA_DECL int archive_write_zip_set_compression_store(struct archive *); -/* Deprecated; use archive_write_open2 instead */ -__LA_DECL int archive_write_open(struct archive *, void *, - archive_open_callback *, archive_write_callback *, - archive_close_callback *); -__LA_DECL int archive_write_open2(struct archive *, void *, - archive_open_callback *, archive_write_callback *, - archive_close_callback *, archive_free_callback *); -__LA_DECL int archive_write_open_fd(struct archive *, int _fd); -__LA_DECL int archive_write_open_filename(struct archive *, const char *_file); -__LA_DECL int archive_write_open_filename_w(struct archive *, - const wchar_t *_file); -/* A deprecated synonym for archive_write_open_filename() */ -__LA_DECL int archive_write_open_file(struct archive *, const char *_file) - __LA_DEPRECATED; -__LA_DECL int archive_write_open_FILE(struct archive *, FILE *); -/* _buffSize is the size of the buffer, _used refers to a variable that - * will be updated after each write into the buffer. */ -__LA_DECL int archive_write_open_memory(struct archive *, - void *_buffer, size_t _buffSize, size_t *_used); - -/* - * Note that the library will truncate writes beyond the size provided - * to archive_write_header or pad if the provided data is short. - */ -__LA_DECL int archive_write_header(struct archive *, - struct archive_entry *); -__LA_DECL la_ssize_t archive_write_data(struct archive *, - const void *, size_t); - -/* This interface is currently only available for archive_write_disk handles. */ -__LA_DECL la_ssize_t archive_write_data_block(struct archive *, - const void *, size_t, la_int64_t); - -__LA_DECL int archive_write_finish_entry(struct archive *); -__LA_DECL int archive_write_close(struct archive *); -/* Marks the archive as FATAL so that a subsequent free() operation - * won't try to close() cleanly. Provides a fast abort capability - * when the client discovers that things have gone wrong. */ -__LA_DECL int archive_write_fail(struct archive *); -/* This can fail if the archive wasn't already closed, in which case - * archive_write_free() will implicitly call archive_write_close(). */ -__LA_DECL int archive_write_free(struct archive *); -#if ARCHIVE_VERSION_NUMBER < 4000000 -/* Synonym for archive_write_free() for backwards compatibility. */ -__LA_DECL int archive_write_finish(struct archive *) __LA_DEPRECATED; -#endif - -/* - * Set write options. - */ -/* Apply option to the format only. */ -__LA_DECL int archive_write_set_format_option(struct archive *_a, - const char *m, const char *o, - const char *v); -/* Apply option to the filter only. */ -__LA_DECL int archive_write_set_filter_option(struct archive *_a, - const char *m, const char *o, - const char *v); -/* Apply option to both the format and the filter. */ -__LA_DECL int archive_write_set_option(struct archive *_a, - const char *m, const char *o, - const char *v); -/* Apply option string to both the format and the filter. */ -__LA_DECL int archive_write_set_options(struct archive *_a, - const char *opts); - -/* - * Set a encryption passphrase. - */ -__LA_DECL int archive_write_set_passphrase(struct archive *_a, const char *p); -__LA_DECL int archive_write_set_passphrase_callback(struct archive *, - void *client_data, archive_passphrase_callback *); - -/*- - * ARCHIVE_WRITE_DISK API - * - * To create objects on disk: - * 1) Ask archive_write_disk_new for a new archive_write_disk object. - * 2) Set any global properties. In particular, you probably - * want to set the options. - * 3) For each entry: - * - construct an appropriate struct archive_entry structure - * - archive_write_header to create the file/dir/etc on disk - * - archive_write_data to write the entry data - * 4) archive_write_free to cleanup the writer and release resources - * - * In particular, you can use this in conjunction with archive_read() - * to pull entries out of an archive and create them on disk. - */ -__LA_DECL struct archive *archive_write_disk_new(void); -/* This file will not be overwritten. */ -__LA_DECL int archive_write_disk_set_skip_file(struct archive *, - la_int64_t, la_int64_t); -/* Set flags to control how the next item gets created. - * This accepts a bitmask of ARCHIVE_EXTRACT_XXX flags defined above. */ -__LA_DECL int archive_write_disk_set_options(struct archive *, - int flags); -/* - * The lookup functions are given uname/uid (or gname/gid) pairs and - * return a uid (gid) suitable for this system. These are used for - * restoring ownership and for setting ACLs. The default functions - * are naive, they just return the uid/gid. These are small, so reasonable - * for applications that don't need to preserve ownership; they - * are probably also appropriate for applications that are doing - * same-system backup and restore. - */ -/* - * The "standard" lookup functions use common system calls to lookup - * the uname/gname, falling back to the uid/gid if the names can't be - * found. They cache lookups and are reasonably fast, but can be very - * large, so they are not used unless you ask for them. In - * particular, these match the specifications of POSIX "pax" and old - * POSIX "tar". - */ -__LA_DECL int archive_write_disk_set_standard_lookup(struct archive *); -/* - * If neither the default (naive) nor the standard (big) functions suit - * your needs, you can write your own and register them. Be sure to - * include a cleanup function if you have allocated private data. - */ -__LA_DECL int archive_write_disk_set_group_lookup(struct archive *, - void * /* private_data */, - la_int64_t (*)(void *, const char *, la_int64_t), - void (* /* cleanup */)(void *)); -__LA_DECL int archive_write_disk_set_user_lookup(struct archive *, - void * /* private_data */, - la_int64_t (*)(void *, const char *, la_int64_t), - void (* /* cleanup */)(void *)); -__LA_DECL la_int64_t archive_write_disk_gid(struct archive *, const char *, la_int64_t); -__LA_DECL la_int64_t archive_write_disk_uid(struct archive *, const char *, la_int64_t); - -/* - * ARCHIVE_READ_DISK API - * - * This is still evolving and somewhat experimental. - */ -__LA_DECL struct archive *archive_read_disk_new(void); -/* The names for symlink modes here correspond to an old BSD - * command-line argument convention: -L, -P, -H */ -/* Follow all symlinks. */ -__LA_DECL int archive_read_disk_set_symlink_logical(struct archive *); -/* Follow no symlinks. */ -__LA_DECL int archive_read_disk_set_symlink_physical(struct archive *); -/* Follow symlink initially, then not. */ -__LA_DECL int archive_read_disk_set_symlink_hybrid(struct archive *); -/* TODO: Handle Linux stat32/stat64 ugliness. */ -__LA_DECL int archive_read_disk_entry_from_file(struct archive *, - struct archive_entry *, int /* fd */, const struct stat *); -/* Look up gname for gid or uname for uid. */ -/* Default implementations are very, very stupid. */ -__LA_DECL const char *archive_read_disk_gname(struct archive *, la_int64_t); -__LA_DECL const char *archive_read_disk_uname(struct archive *, la_int64_t); -/* "Standard" implementation uses getpwuid_r, getgrgid_r and caches the - * results for performance. */ -__LA_DECL int archive_read_disk_set_standard_lookup(struct archive *); -/* You can install your own lookups if you like. */ -__LA_DECL int archive_read_disk_set_gname_lookup(struct archive *, - void * /* private_data */, - const char *(* /* lookup_fn */)(void *, la_int64_t), - void (* /* cleanup_fn */)(void *)); -__LA_DECL int archive_read_disk_set_uname_lookup(struct archive *, - void * /* private_data */, - const char *(* /* lookup_fn */)(void *, la_int64_t), - void (* /* cleanup_fn */)(void *)); -/* Start traversal. */ -__LA_DECL int archive_read_disk_open(struct archive *, const char *); -__LA_DECL int archive_read_disk_open_w(struct archive *, const wchar_t *); -/* - * Request that current entry be visited. If you invoke it on every - * directory, you'll get a physical traversal. This is ignored if the - * current entry isn't a directory or a link to a directory. So, if - * you invoke this on every returned path, you'll get a full logical - * traversal. - */ -__LA_DECL int archive_read_disk_descend(struct archive *); -__LA_DECL int archive_read_disk_can_descend(struct archive *); -__LA_DECL int archive_read_disk_current_filesystem(struct archive *); -__LA_DECL int archive_read_disk_current_filesystem_is_synthetic(struct archive *); -__LA_DECL int archive_read_disk_current_filesystem_is_remote(struct archive *); -/* Request that the access time of the entry visited by traversal be restored. */ -__LA_DECL int archive_read_disk_set_atime_restored(struct archive *); -/* - * Set behavior. The "flags" argument selects optional behavior. - */ -/* Request that the access time of the entry visited by traversal be restored. - * This is the same as archive_read_disk_set_atime_restored. */ -#define ARCHIVE_READDISK_RESTORE_ATIME (0x0001) -/* Default: Do not skip an entry which has nodump flags. */ -#define ARCHIVE_READDISK_HONOR_NODUMP (0x0002) -/* Default: Skip a mac resource fork file whose prefix is "._" because of - * using copyfile. */ -#define ARCHIVE_READDISK_MAC_COPYFILE (0x0004) -/* Default: Traverse mount points. */ -#define ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS (0x0008) -/* Default: Xattrs are read from disk. */ -#define ARCHIVE_READDISK_NO_XATTR (0x0010) -/* Default: ACLs are read from disk. */ -#define ARCHIVE_READDISK_NO_ACL (0x0020) -/* Default: File flags are read from disk. */ -#define ARCHIVE_READDISK_NO_FFLAGS (0x0040) -/* Default: Sparse file information is read from disk. */ -#define ARCHIVE_READDISK_NO_SPARSE (0x0080) - -__LA_DECL int archive_read_disk_set_behavior(struct archive *, - int flags); - -/* - * Set archive_match object that will be used in archive_read_disk to - * know whether an entry should be skipped. The callback function - * _excluded_func will be invoked when an entry is skipped by the result - * of archive_match. - */ -__LA_DECL int archive_read_disk_set_matching(struct archive *, - struct archive *_matching, void (*_excluded_func) - (struct archive *, void *, struct archive_entry *), - void *_client_data); -__LA_DECL int archive_read_disk_set_metadata_filter_callback(struct archive *, - int (*_metadata_filter_func)(struct archive *, void *, - struct archive_entry *), void *_client_data); - -/* Simplified cleanup interface; - * This calls archive_read_free() or archive_write_free() as needed. */ -__LA_DECL int archive_free(struct archive *); - -/* - * Accessor functions to read/set various information in - * the struct archive object: - */ - -/* Number of filters in the current filter pipeline. */ -/* Filter #0 is the one closest to the format, -1 is a synonym for the - * last filter, which is always the pseudo-filter that wraps the - * client callbacks. */ -__LA_DECL int archive_filter_count(struct archive *); -__LA_DECL la_int64_t archive_filter_bytes(struct archive *, int); -__LA_DECL int archive_filter_code(struct archive *, int); -__LA_DECL const char * archive_filter_name(struct archive *, int); - -#if ARCHIVE_VERSION_NUMBER < 4000000 -/* These don't properly handle multiple filters, so are deprecated and - * will eventually be removed. */ -/* As of libarchive 3.0, this is an alias for archive_filter_bytes(a, -1); */ -__LA_DECL la_int64_t archive_position_compressed(struct archive *) - __LA_DEPRECATED; -/* As of libarchive 3.0, this is an alias for archive_filter_bytes(a, 0); */ -__LA_DECL la_int64_t archive_position_uncompressed(struct archive *) - __LA_DEPRECATED; -/* As of libarchive 3.0, this is an alias for archive_filter_name(a, 0); */ -__LA_DECL const char *archive_compression_name(struct archive *) - __LA_DEPRECATED; -/* As of libarchive 3.0, this is an alias for archive_filter_code(a, 0); */ -__LA_DECL int archive_compression(struct archive *) - __LA_DEPRECATED; -#endif - -__LA_DECL int archive_errno(struct archive *); -__LA_DECL const char *archive_error_string(struct archive *); -__LA_DECL const char *archive_format_name(struct archive *); -__LA_DECL int archive_format(struct archive *); -__LA_DECL void archive_clear_error(struct archive *); -__LA_DECL void archive_set_error(struct archive *, int _err, - const char *fmt, ...) __LA_PRINTF(3, 4); -__LA_DECL void archive_copy_error(struct archive *dest, - struct archive *src); -__LA_DECL int archive_file_count(struct archive *); - -/* - * ARCHIVE_MATCH API - */ -__LA_DECL struct archive *archive_match_new(void); -__LA_DECL int archive_match_free(struct archive *); - -/* - * Test if archive_entry is excluded. - * This is a convenience function. This is the same as calling all - * archive_match_path_excluded, archive_match_time_excluded - * and archive_match_owner_excluded. - */ -__LA_DECL int archive_match_excluded(struct archive *, - struct archive_entry *); - -/* - * Test if pathname is excluded. The conditions are set by following functions. - */ -__LA_DECL int archive_match_path_excluded(struct archive *, - struct archive_entry *); -/* Control recursive inclusion of directory content when directory is included. Default on. */ -__LA_DECL int archive_match_set_inclusion_recursion(struct archive *, int); -/* Add exclusion pathname pattern. */ -__LA_DECL int archive_match_exclude_pattern(struct archive *, const char *); -__LA_DECL int archive_match_exclude_pattern_w(struct archive *, - const wchar_t *); -/* Add exclusion pathname pattern from file. */ -__LA_DECL int archive_match_exclude_pattern_from_file(struct archive *, - const char *, int _nullSeparator); -__LA_DECL int archive_match_exclude_pattern_from_file_w(struct archive *, - const wchar_t *, int _nullSeparator); -/* Add inclusion pathname pattern. */ -__LA_DECL int archive_match_include_pattern(struct archive *, const char *); -__LA_DECL int archive_match_include_pattern_w(struct archive *, - const wchar_t *); -/* Add inclusion pathname pattern from file. */ -__LA_DECL int archive_match_include_pattern_from_file(struct archive *, - const char *, int _nullSeparator); -__LA_DECL int archive_match_include_pattern_from_file_w(struct archive *, - const wchar_t *, int _nullSeparator); -/* - * How to get statistic information for inclusion patterns. - */ -/* Return the amount number of unmatched inclusion patterns. */ -__LA_DECL int archive_match_path_unmatched_inclusions(struct archive *); -/* Return the pattern of unmatched inclusion with ARCHIVE_OK. - * Return ARCHIVE_EOF if there is no inclusion pattern. */ -__LA_DECL int archive_match_path_unmatched_inclusions_next( - struct archive *, const char **); -__LA_DECL int archive_match_path_unmatched_inclusions_next_w( - struct archive *, const wchar_t **); - -/* - * Test if a file is excluded by its time stamp. - * The conditions are set by following functions. - */ -__LA_DECL int archive_match_time_excluded(struct archive *, - struct archive_entry *); - -/* - * Flags to tell a matching type of time stamps. These are used for - * following functions. - */ -/* Time flag: mtime to be tested. */ -#define ARCHIVE_MATCH_MTIME (0x0100) -/* Time flag: ctime to be tested. */ -#define ARCHIVE_MATCH_CTIME (0x0200) -/* Comparison flag: Match the time if it is newer than. */ -#define ARCHIVE_MATCH_NEWER (0x0001) -/* Comparison flag: Match the time if it is older than. */ -#define ARCHIVE_MATCH_OLDER (0x0002) -/* Comparison flag: Match the time if it is equal to. */ -#define ARCHIVE_MATCH_EQUAL (0x0010) -/* Set inclusion time. */ -__LA_DECL int archive_match_include_time(struct archive *, int _flag, - time_t _sec, long _nsec); -/* Set inclusion time by a date string. */ -__LA_DECL int archive_match_include_date(struct archive *, int _flag, - const char *_datestr); -__LA_DECL int archive_match_include_date_w(struct archive *, int _flag, - const wchar_t *_datestr); -/* Set inclusion time by a particular file. */ -__LA_DECL int archive_match_include_file_time(struct archive *, - int _flag, const char *_pathname); -__LA_DECL int archive_match_include_file_time_w(struct archive *, - int _flag, const wchar_t *_pathname); -/* Add exclusion entry. */ -__LA_DECL int archive_match_exclude_entry(struct archive *, - int _flag, struct archive_entry *); - -/* - * Test if a file is excluded by its uid ,gid, uname or gname. - * The conditions are set by following functions. - */ -__LA_DECL int archive_match_owner_excluded(struct archive *, - struct archive_entry *); -/* Add inclusion uid, gid, uname and gname. */ -__LA_DECL int archive_match_include_uid(struct archive *, la_int64_t); -__LA_DECL int archive_match_include_gid(struct archive *, la_int64_t); -__LA_DECL int archive_match_include_uname(struct archive *, const char *); -__LA_DECL int archive_match_include_uname_w(struct archive *, - const wchar_t *); -__LA_DECL int archive_match_include_gname(struct archive *, const char *); -__LA_DECL int archive_match_include_gname_w(struct archive *, - const wchar_t *); - -/* Utility functions */ -/* Convenience function to sort a NULL terminated list of strings */ -__LA_DECL int archive_utility_string_sort(char **); - -#ifdef __cplusplus -} -#endif - -/* These are meaningless outside of this header. */ -#undef __LA_DECL - -#endif /* !ARCHIVE_H_INCLUDED */ diff --git a/thirdparty/libarchive/libarchive/archive_acl.c b/thirdparty/libarchive/libarchive/archive_acl.c deleted file mode 100644 index ead7e36e4..000000000 --- a/thirdparty/libarchive/libarchive/archive_acl.c +++ /dev/null @@ -1,2097 +0,0 @@ -/*- - * Copyright (c) 2003-2010 Tim Kientzle - * Copyright (c) 2016 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_LIMITS_H -#include -#endif -#ifdef HAVE_WCHAR_H -#include -#endif - -#include "archive_acl_private.h" -#include "archive_entry.h" -#include "archive_private.h" - -#undef max -#define max(a, b) ((a)>(b)?(a):(b)) - -#ifndef HAVE_WMEMCMP -/* Good enough for simple equality testing, but not for sorting. */ -#define wmemcmp(a,b,i) memcmp((a), (b), (i) * sizeof(wchar_t)) -#endif - -static int acl_special(struct archive_acl *acl, - int type, int permset, int tag); -static struct archive_acl_entry *acl_new_entry(struct archive_acl *acl, - int type, int permset, int tag, int id); -static int archive_acl_add_entry_len_l(struct archive_acl *acl, - int type, int permset, int tag, int id, const char *name, - size_t len, struct archive_string_conv *sc); -static int archive_acl_text_want_type(struct archive_acl *acl, int flags); -static ssize_t archive_acl_text_len(struct archive_acl *acl, int want_type, - int flags, int wide, struct archive *a, - struct archive_string_conv *sc); -static int isint_w(const wchar_t *start, const wchar_t *end, int *result); -static int ismode_w(const wchar_t *start, const wchar_t *end, int *result); -static int is_nfs4_flags_w(const wchar_t *start, const wchar_t *end, - int *result); -static int is_nfs4_perms_w(const wchar_t *start, const wchar_t *end, - int *result); -static void next_field_w(const wchar_t **wp, const wchar_t **start, - const wchar_t **end, wchar_t *sep); -static void append_entry_w(wchar_t **wp, const wchar_t *prefix, int type, - int tag, int flags, const wchar_t *wname, int perm, int id); -static void append_id_w(wchar_t **wp, int id); -static int isint(const char *start, const char *end, int *result); -static int ismode(const char *start, const char *end, int *result); -static int is_nfs4_flags(const char *start, const char *end, - int *result); -static int is_nfs4_perms(const char *start, const char *end, - int *result); -static void next_field(const char **p, const char **start, - const char **end, char *sep); -static void append_entry(char **p, const char *prefix, int type, - int tag, int flags, const char *name, int perm, int id); -static void append_id(char **p, int id); - -static const struct { - const int perm; - const char c; - const wchar_t wc; -} nfsv4_acl_perm_map[] = { - { ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, 'r', - L'r' }, - { ARCHIVE_ENTRY_ACL_WRITE_DATA | ARCHIVE_ENTRY_ACL_ADD_FILE, 'w', - L'w' }, - { ARCHIVE_ENTRY_ACL_EXECUTE, 'x', L'x' }, - { ARCHIVE_ENTRY_ACL_APPEND_DATA | ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, - 'p', L'p' }, - { ARCHIVE_ENTRY_ACL_DELETE, 'd', L'd' }, - { ARCHIVE_ENTRY_ACL_DELETE_CHILD, 'D', L'D' }, - { ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, 'a', L'a' }, - { ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, 'A', L'A' }, - { ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, 'R', L'R' }, - { ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, 'W', L'W' }, - { ARCHIVE_ENTRY_ACL_READ_ACL, 'c', L'c' }, - { ARCHIVE_ENTRY_ACL_WRITE_ACL, 'C', L'C' }, - { ARCHIVE_ENTRY_ACL_WRITE_OWNER, 'o', L'o' }, - { ARCHIVE_ENTRY_ACL_SYNCHRONIZE, 's', L's' } -}; - -static const int nfsv4_acl_perm_map_size = (int)(sizeof(nfsv4_acl_perm_map) / - sizeof(nfsv4_acl_perm_map[0])); - -static const struct { - const int perm; - const char c; - const wchar_t wc; -} nfsv4_acl_flag_map[] = { - { ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, 'f', L'f' }, - { ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, 'd', L'd' }, - { ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, 'i', L'i' }, - { ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, 'n', L'n' }, - { ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, 'S', L'S' }, - { ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, 'F', L'F' }, - { ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, 'I', L'I' } -}; - -static const int nfsv4_acl_flag_map_size = (int)(sizeof(nfsv4_acl_flag_map) / - sizeof(nfsv4_acl_flag_map[0])); - -void -archive_acl_clear(struct archive_acl *acl) -{ - struct archive_acl_entry *ap; - - while (acl->acl_head != NULL) { - ap = acl->acl_head->next; - archive_mstring_clean(&acl->acl_head->name); - free(acl->acl_head); - acl->acl_head = ap; - } - free(acl->acl_text_w); - acl->acl_text_w = NULL; - free(acl->acl_text); - acl->acl_text = NULL; - acl->acl_p = NULL; - acl->acl_types = 0; - acl->acl_state = 0; /* Not counting. */ -} - -void -archive_acl_copy(struct archive_acl *dest, struct archive_acl *src) -{ - struct archive_acl_entry *ap, *ap2; - - archive_acl_clear(dest); - - dest->mode = src->mode; - ap = src->acl_head; - while (ap != NULL) { - ap2 = acl_new_entry(dest, - ap->type, ap->permset, ap->tag, ap->id); - if (ap2 != NULL) - archive_mstring_copy(&ap2->name, &ap->name); - ap = ap->next; - } -} - -int -archive_acl_add_entry(struct archive_acl *acl, - int type, int permset, int tag, int id, const char *name) -{ - struct archive_acl_entry *ap; - - if (acl_special(acl, type, permset, tag) == 0) - return ARCHIVE_OK; - ap = acl_new_entry(acl, type, permset, tag, id); - if (ap == NULL) { - /* XXX Error XXX */ - return ARCHIVE_FAILED; - } - if (name != NULL && *name != '\0') - archive_mstring_copy_mbs(&ap->name, name); - else - archive_mstring_clean(&ap->name); - return ARCHIVE_OK; -} - -int -archive_acl_add_entry_w_len(struct archive_acl *acl, - int type, int permset, int tag, int id, const wchar_t *name, size_t len) -{ - struct archive_acl_entry *ap; - - if (acl_special(acl, type, permset, tag) == 0) - return ARCHIVE_OK; - ap = acl_new_entry(acl, type, permset, tag, id); - if (ap == NULL) { - /* XXX Error XXX */ - return ARCHIVE_FAILED; - } - if (name != NULL && *name != L'\0' && len > 0) - archive_mstring_copy_wcs_len(&ap->name, name, len); - else - archive_mstring_clean(&ap->name); - return ARCHIVE_OK; -} - -static int -archive_acl_add_entry_len_l(struct archive_acl *acl, - int type, int permset, int tag, int id, const char *name, size_t len, - struct archive_string_conv *sc) -{ - struct archive_acl_entry *ap; - int r; - - if (acl_special(acl, type, permset, tag) == 0) - return ARCHIVE_OK; - ap = acl_new_entry(acl, type, permset, tag, id); - if (ap == NULL) { - /* XXX Error XXX */ - return ARCHIVE_FAILED; - } - if (name != NULL && *name != '\0' && len > 0) { - r = archive_mstring_copy_mbs_len_l(&ap->name, name, len, sc); - } else { - r = 0; - archive_mstring_clean(&ap->name); - } - if (r == 0) - return (ARCHIVE_OK); - else if (errno == ENOMEM) - return (ARCHIVE_FATAL); - else - return (ARCHIVE_WARN); -} - -/* - * If this ACL entry is part of the standard POSIX permissions set, - * store the permissions in the stat structure and return zero. - */ -static int -acl_special(struct archive_acl *acl, int type, int permset, int tag) -{ - if (type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS - && ((permset & ~007) == 0)) { - switch (tag) { - case ARCHIVE_ENTRY_ACL_USER_OBJ: - acl->mode &= ~0700; - acl->mode |= (permset & 7) << 6; - return (0); - case ARCHIVE_ENTRY_ACL_GROUP_OBJ: - acl->mode &= ~0070; - acl->mode |= (permset & 7) << 3; - return (0); - case ARCHIVE_ENTRY_ACL_OTHER: - acl->mode &= ~0007; - acl->mode |= permset & 7; - return (0); - } - } - return (1); -} - -/* - * Allocate and populate a new ACL entry with everything but the - * name. - */ -static struct archive_acl_entry * -acl_new_entry(struct archive_acl *acl, - int type, int permset, int tag, int id) -{ - struct archive_acl_entry *ap, *aq; - - /* Type argument must be a valid NFS4 or POSIX.1e type. - * The type must agree with anything already set and - * the permset must be compatible. */ - if (type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - if (acl->acl_types & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - return (NULL); - } - if (permset & - ~(ARCHIVE_ENTRY_ACL_PERMS_NFS4 - | ARCHIVE_ENTRY_ACL_INHERITANCE_NFS4)) { - return (NULL); - } - } else if (type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) { - if (acl->acl_types & ~ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) { - return (NULL); - } - if (permset & ~ARCHIVE_ENTRY_ACL_PERMS_POSIX1E) { - return (NULL); - } - } else { - return (NULL); - } - - /* Verify the tag is valid and compatible with NFS4 or POSIX.1e. */ - switch (tag) { - case ARCHIVE_ENTRY_ACL_USER: - case ARCHIVE_ENTRY_ACL_USER_OBJ: - case ARCHIVE_ENTRY_ACL_GROUP: - case ARCHIVE_ENTRY_ACL_GROUP_OBJ: - /* Tags valid in both NFS4 and POSIX.1e */ - break; - case ARCHIVE_ENTRY_ACL_MASK: - case ARCHIVE_ENTRY_ACL_OTHER: - /* Tags valid only in POSIX.1e. */ - if (type & ~ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) { - return (NULL); - } - break; - case ARCHIVE_ENTRY_ACL_EVERYONE: - /* Tags valid only in NFS4. */ - if (type & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - return (NULL); - } - break; - default: - /* No other values are valid. */ - return (NULL); - } - - free(acl->acl_text_w); - acl->acl_text_w = NULL; - free(acl->acl_text); - acl->acl_text = NULL; - - /* - * If there's a matching entry already in the list, overwrite it. - * NFSv4 entries may be repeated and are not overwritten. - * - * TODO: compare names of no id is provided (needs more rework) - */ - ap = acl->acl_head; - aq = NULL; - while (ap != NULL) { - if (((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) == 0) && - ap->type == type && ap->tag == tag && ap->id == id) { - if (id != -1 || (tag != ARCHIVE_ENTRY_ACL_USER && - tag != ARCHIVE_ENTRY_ACL_GROUP)) { - ap->permset = permset; - return (ap); - } - } - aq = ap; - ap = ap->next; - } - - /* Add a new entry to the end of the list. */ - ap = (struct archive_acl_entry *)calloc(1, sizeof(*ap)); - if (ap == NULL) - return (NULL); - if (aq == NULL) - acl->acl_head = ap; - else - aq->next = ap; - ap->type = type; - ap->tag = tag; - ap->id = id; - ap->permset = permset; - acl->acl_types |= type; - return (ap); -} - -/* - * Return a count of entries matching "want_type". - */ -int -archive_acl_count(struct archive_acl *acl, int want_type) -{ - int count; - struct archive_acl_entry *ap; - - count = 0; - ap = acl->acl_head; - while (ap != NULL) { - if ((ap->type & want_type) != 0) - count++; - ap = ap->next; - } - - if (count > 0 && ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0)) - count += 3; - return (count); -} - -/* - * Return a bitmask of stored ACL types in an ACL list - */ -int -archive_acl_types(struct archive_acl *acl) -{ - return (acl->acl_types); -} - -/* - * Prepare for reading entries from the ACL data. Returns a count - * of entries matching "want_type", or zero if there are no - * non-extended ACL entries of that type. - */ -int -archive_acl_reset(struct archive_acl *acl, int want_type) -{ - int count, cutoff; - - count = archive_acl_count(acl, want_type); - - /* - * If the only entries are the three standard ones, - * then don't return any ACL data. (In this case, - * client can just use chmod(2) to set permissions.) - */ - if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) - cutoff = 3; - else - cutoff = 0; - - if (count > cutoff) - acl->acl_state = ARCHIVE_ENTRY_ACL_USER_OBJ; - else - acl->acl_state = 0; - acl->acl_p = acl->acl_head; - return (count); -} - - -/* - * Return the next ACL entry in the list. Fake entries for the - * standard permissions and include them in the returned list. - */ -int -archive_acl_next(struct archive *a, struct archive_acl *acl, int want_type, - int *type, int *permset, int *tag, int *id, const char **name) -{ - *name = NULL; - *id = -1; - - /* - * The acl_state is either zero (no entries available), -1 - * (reading from list), or an entry type (retrieve that type - * from ae_stat.aest_mode). - */ - if (acl->acl_state == 0) - return (ARCHIVE_WARN); - - /* The first three access entries are special. */ - if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) { - switch (acl->acl_state) { - case ARCHIVE_ENTRY_ACL_USER_OBJ: - *permset = (acl->mode >> 6) & 7; - *type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS; - *tag = ARCHIVE_ENTRY_ACL_USER_OBJ; - acl->acl_state = ARCHIVE_ENTRY_ACL_GROUP_OBJ; - return (ARCHIVE_OK); - case ARCHIVE_ENTRY_ACL_GROUP_OBJ: - *permset = (acl->mode >> 3) & 7; - *type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS; - *tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ; - acl->acl_state = ARCHIVE_ENTRY_ACL_OTHER; - return (ARCHIVE_OK); - case ARCHIVE_ENTRY_ACL_OTHER: - *permset = acl->mode & 7; - *type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS; - *tag = ARCHIVE_ENTRY_ACL_OTHER; - acl->acl_state = -1; - acl->acl_p = acl->acl_head; - return (ARCHIVE_OK); - default: - break; - } - } - - while (acl->acl_p != NULL && (acl->acl_p->type & want_type) == 0) - acl->acl_p = acl->acl_p->next; - if (acl->acl_p == NULL) { - acl->acl_state = 0; - *type = 0; - *permset = 0; - *tag = 0; - *id = -1; - *name = NULL; - return (ARCHIVE_EOF); /* End of ACL entries. */ - } - *type = acl->acl_p->type; - *permset = acl->acl_p->permset; - *tag = acl->acl_p->tag; - *id = acl->acl_p->id; - if (archive_mstring_get_mbs(a, &acl->acl_p->name, name) != 0) { - if (errno == ENOMEM) - return (ARCHIVE_FATAL); - *name = NULL; - } - acl->acl_p = acl->acl_p->next; - return (ARCHIVE_OK); -} - -/* - * Determine what type of ACL do we want - */ -static int -archive_acl_text_want_type(struct archive_acl *acl, int flags) -{ - int want_type; - - /* Check if ACL is NFSv4 */ - if ((acl->acl_types & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) { - /* NFSv4 should never mix with POSIX.1e */ - if ((acl->acl_types & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) - return (0); - else - return (ARCHIVE_ENTRY_ACL_TYPE_NFS4); - } - - /* Now deal with POSIX.1e ACLs */ - - want_type = 0; - if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) - want_type |= ARCHIVE_ENTRY_ACL_TYPE_ACCESS; - if ((flags & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0) - want_type |= ARCHIVE_ENTRY_ACL_TYPE_DEFAULT; - - /* By default we want both access and default ACLs */ - if (want_type == 0) - return (ARCHIVE_ENTRY_ACL_TYPE_POSIX1E); - - return (want_type); -} - -/* - * Calculate ACL text string length - */ -static ssize_t -archive_acl_text_len(struct archive_acl *acl, int want_type, int flags, - int wide, struct archive *a, struct archive_string_conv *sc) { - struct archive_acl_entry *ap; - const char *name; - const wchar_t *wname; - int count, idlen, tmp, r; - ssize_t length; - size_t len; - - count = 0; - length = 0; - for (ap = acl->acl_head; ap != NULL; ap = ap->next) { - if ((ap->type & want_type) == 0) - continue; - /* - * Filemode-mapping ACL entries are stored exclusively in - * ap->mode so they should not be in the list - */ - if ((ap->type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS) - && (ap->tag == ARCHIVE_ENTRY_ACL_USER_OBJ - || ap->tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ - || ap->tag == ARCHIVE_ENTRY_ACL_OTHER)) - continue; - count++; - if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0 - && (ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0) - length += 8; /* "default:" */ - switch (ap->tag) { - case ARCHIVE_ENTRY_ACL_USER_OBJ: - if (want_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - length += 6; /* "owner@" */ - break; - } - /* FALLTHROUGH */ - case ARCHIVE_ENTRY_ACL_USER: - case ARCHIVE_ENTRY_ACL_MASK: - length += 4; /* "user", "mask" */ - break; - case ARCHIVE_ENTRY_ACL_GROUP_OBJ: - if (want_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - length += 6; /* "group@" */ - break; - } - /* FALLTHROUGH */ - case ARCHIVE_ENTRY_ACL_GROUP: - case ARCHIVE_ENTRY_ACL_OTHER: - length += 5; /* "group", "other" */ - break; - case ARCHIVE_ENTRY_ACL_EVERYONE: - length += 9; /* "everyone@" */ - break; - } - length += 1; /* colon after tag */ - if (ap->tag == ARCHIVE_ENTRY_ACL_USER || - ap->tag == ARCHIVE_ENTRY_ACL_GROUP) { - if (wide) { - r = archive_mstring_get_wcs(a, &ap->name, - &wname); - if (r == 0 && wname != NULL) - length += wcslen(wname); - else if (r < 0 && errno == ENOMEM) - return (0); - else - length += sizeof(uid_t) * 3 + 1; - } else { - r = archive_mstring_get_mbs_l(a, &ap->name, &name, - &len, sc); - if (r != 0) - return (0); - if (len > 0 && name != NULL) - length += len; - else - length += sizeof(uid_t) * 3 + 1; - } - length += 1; /* colon after user or group name */ - } else if (want_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4) - length += 1; /* 2nd colon empty user,group or other */ - - if (((flags & ARCHIVE_ENTRY_ACL_STYLE_SOLARIS) != 0) - && ((want_type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) - && (ap->tag == ARCHIVE_ENTRY_ACL_OTHER - || ap->tag == ARCHIVE_ENTRY_ACL_MASK)) { - /* Solaris has no colon after other: and mask: */ - length = length - 1; - } - - if (want_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - /* rwxpdDaARWcCos:fdinSFI:deny */ - length += 27; - if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_DENY) == 0) - length += 1; /* allow, alarm, audit */ - } else - length += 3; /* rwx */ - - if ((ap->tag == ARCHIVE_ENTRY_ACL_USER || - ap->tag == ARCHIVE_ENTRY_ACL_GROUP) && - (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID) != 0) { - length += 1; /* colon */ - /* ID digit count */ - idlen = 1; - tmp = ap->id; - while (tmp > 9) { - tmp = tmp / 10; - idlen++; - } - length += idlen; - } - length ++; /* entry separator */ - } - - /* Add filemode-mapping access entries to the length */ - if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) { - if ((flags & ARCHIVE_ENTRY_ACL_STYLE_SOLARIS) != 0) { - /* "user::rwx\ngroup::rwx\nother:rwx\n" */ - length += 31; - } else { - /* "user::rwx\ngroup::rwx\nother::rwx\n" */ - length += 32; - } - } else if (count == 0) - return (0); - - /* The terminating character is included in count */ - return (length); -} - -/* - * Generate a wide text version of the ACL. The flags parameter controls - * the type and style of the generated ACL. - */ -wchar_t * -archive_acl_to_text_w(struct archive_acl *acl, ssize_t *text_len, int flags, - struct archive *a) -{ - int count; - ssize_t length; - size_t len; - const wchar_t *wname; - const wchar_t *prefix; - wchar_t separator; - struct archive_acl_entry *ap; - int id, r, want_type; - wchar_t *wp, *ws; - - want_type = archive_acl_text_want_type(acl, flags); - - /* Both NFSv4 and POSIX.1 types found */ - if (want_type == 0) - return (NULL); - - if (want_type == ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) - flags |= ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT; - - length = archive_acl_text_len(acl, want_type, flags, 1, a, NULL); - - if (length == 0) - return (NULL); - - if (flags & ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA) - separator = L','; - else - separator = L'\n'; - - /* Now, allocate the string and actually populate it. */ - wp = ws = (wchar_t *)malloc(length * sizeof(wchar_t)); - if (wp == NULL) { - if (errno == ENOMEM) - __archive_errx(1, "No memory"); - return (NULL); - } - count = 0; - - if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) { - append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - ARCHIVE_ENTRY_ACL_USER_OBJ, flags, NULL, - acl->mode & 0700, -1); - *wp++ = separator; - append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, flags, NULL, - acl->mode & 0070, -1); - *wp++ = separator; - append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - ARCHIVE_ENTRY_ACL_OTHER, flags, NULL, - acl->mode & 0007, -1); - count += 3; - } - - for (ap = acl->acl_head; ap != NULL; ap = ap->next) { - if ((ap->type & want_type) == 0) - continue; - /* - * Filemode-mapping ACL entries are stored exclusively in - * ap->mode so they should not be in the list - */ - if ((ap->type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS) - && (ap->tag == ARCHIVE_ENTRY_ACL_USER_OBJ - || ap->tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ - || ap->tag == ARCHIVE_ENTRY_ACL_OTHER)) - continue; - if (ap->type == ARCHIVE_ENTRY_ACL_TYPE_DEFAULT && - (flags & ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT) != 0) - prefix = L"default:"; - else - prefix = NULL; - r = archive_mstring_get_wcs(a, &ap->name, &wname); - if (r == 0) { - if (count > 0) - *wp++ = separator; - if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID) - id = ap->id; - else - id = -1; - append_entry_w(&wp, prefix, ap->type, ap->tag, flags, - wname, ap->permset, id); - count++; - } else if (r < 0 && errno == ENOMEM) { - free(ws); - return (NULL); - } - } - - /* Add terminating character */ - *wp++ = L'\0'; - - len = wcslen(ws); - - if ((ssize_t)len > (length - 1)) - __archive_errx(1, "Buffer overrun"); - - if (text_len != NULL) - *text_len = len; - - return (ws); -} - -static void -append_id_w(wchar_t **wp, int id) -{ - if (id < 0) - id = 0; - if (id > 9) - append_id_w(wp, id / 10); - *(*wp)++ = L"0123456789"[id % 10]; -} - -static void -append_entry_w(wchar_t **wp, const wchar_t *prefix, int type, - int tag, int flags, const wchar_t *wname, int perm, int id) -{ - int i; - - if (prefix != NULL) { - wcscpy(*wp, prefix); - *wp += wcslen(*wp); - } - switch (tag) { - case ARCHIVE_ENTRY_ACL_USER_OBJ: - wname = NULL; - id = -1; - if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) { - wcscpy(*wp, L"owner@"); - break; - } - /* FALLTHROUGH */ - case ARCHIVE_ENTRY_ACL_USER: - wcscpy(*wp, L"user"); - break; - case ARCHIVE_ENTRY_ACL_GROUP_OBJ: - wname = NULL; - id = -1; - if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) { - wcscpy(*wp, L"group@"); - break; - } - /* FALLTHROUGH */ - case ARCHIVE_ENTRY_ACL_GROUP: - wcscpy(*wp, L"group"); - break; - case ARCHIVE_ENTRY_ACL_MASK: - wcscpy(*wp, L"mask"); - wname = NULL; - id = -1; - break; - case ARCHIVE_ENTRY_ACL_OTHER: - wcscpy(*wp, L"other"); - wname = NULL; - id = -1; - break; - case ARCHIVE_ENTRY_ACL_EVERYONE: - wcscpy(*wp, L"everyone@"); - wname = NULL; - id = -1; - break; - } - *wp += wcslen(*wp); - *(*wp)++ = L':'; - if (((type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) || - tag == ARCHIVE_ENTRY_ACL_USER || - tag == ARCHIVE_ENTRY_ACL_GROUP) { - if (wname != NULL) { - wcscpy(*wp, wname); - *wp += wcslen(*wp); - } else if (tag == ARCHIVE_ENTRY_ACL_USER - || tag == ARCHIVE_ENTRY_ACL_GROUP) { - append_id_w(wp, id); - if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) == 0) - id = -1; - } - /* Solaris style has no second colon after other and mask */ - if (((flags & ARCHIVE_ENTRY_ACL_STYLE_SOLARIS) == 0) - || (tag != ARCHIVE_ENTRY_ACL_OTHER - && tag != ARCHIVE_ENTRY_ACL_MASK)) - *(*wp)++ = L':'; - } - if ((type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) { - /* POSIX.1e ACL perms */ - *(*wp)++ = (perm & 0444) ? L'r' : L'-'; - *(*wp)++ = (perm & 0222) ? L'w' : L'-'; - *(*wp)++ = (perm & 0111) ? L'x' : L'-'; - } else { - /* NFSv4 ACL perms */ - for (i = 0; i < nfsv4_acl_perm_map_size; i++) { - if (perm & nfsv4_acl_perm_map[i].perm) - *(*wp)++ = nfsv4_acl_perm_map[i].wc; - else if ((flags & ARCHIVE_ENTRY_ACL_STYLE_COMPACT) == 0) - *(*wp)++ = L'-'; - } - *(*wp)++ = L':'; - for (i = 0; i < nfsv4_acl_flag_map_size; i++) { - if (perm & nfsv4_acl_flag_map[i].perm) - *(*wp)++ = nfsv4_acl_flag_map[i].wc; - else if ((flags & ARCHIVE_ENTRY_ACL_STYLE_COMPACT) == 0) - *(*wp)++ = L'-'; - } - *(*wp)++ = L':'; - switch (type) { - case ARCHIVE_ENTRY_ACL_TYPE_ALLOW: - wcscpy(*wp, L"allow"); - break; - case ARCHIVE_ENTRY_ACL_TYPE_DENY: - wcscpy(*wp, L"deny"); - break; - case ARCHIVE_ENTRY_ACL_TYPE_AUDIT: - wcscpy(*wp, L"audit"); - break; - case ARCHIVE_ENTRY_ACL_TYPE_ALARM: - wcscpy(*wp, L"alarm"); - break; - default: - break; - } - *wp += wcslen(*wp); - } - if (id != -1) { - *(*wp)++ = L':'; - append_id_w(wp, id); - } -} - -/* - * Generate a text version of the ACL. The flags parameter controls - * the type and style of the generated ACL. - */ -char * -archive_acl_to_text_l(struct archive_acl *acl, ssize_t *text_len, int flags, - struct archive_string_conv *sc) -{ - int count; - ssize_t length; - size_t len; - const char *name; - const char *prefix; - char separator; - struct archive_acl_entry *ap; - int id, r, want_type; - char *p, *s; - - want_type = archive_acl_text_want_type(acl, flags); - - /* Both NFSv4 and POSIX.1 types found */ - if (want_type == 0) - return (NULL); - - if (want_type == ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) - flags |= ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT; - - length = archive_acl_text_len(acl, want_type, flags, 0, NULL, sc); - - if (length == 0) - return (NULL); - - if (flags & ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA) - separator = ','; - else - separator = '\n'; - - /* Now, allocate the string and actually populate it. */ - p = s = (char *)malloc(length * sizeof(char)); - if (p == NULL) { - if (errno == ENOMEM) - __archive_errx(1, "No memory"); - return (NULL); - } - count = 0; - - if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) { - append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - ARCHIVE_ENTRY_ACL_USER_OBJ, flags, NULL, - acl->mode & 0700, -1); - *p++ = separator; - append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, flags, NULL, - acl->mode & 0070, -1); - *p++ = separator; - append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - ARCHIVE_ENTRY_ACL_OTHER, flags, NULL, - acl->mode & 0007, -1); - count += 3; - } - - for (ap = acl->acl_head; ap != NULL; ap = ap->next) { - if ((ap->type & want_type) == 0) - continue; - /* - * Filemode-mapping ACL entries are stored exclusively in - * ap->mode so they should not be in the list - */ - if ((ap->type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS) - && (ap->tag == ARCHIVE_ENTRY_ACL_USER_OBJ - || ap->tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ - || ap->tag == ARCHIVE_ENTRY_ACL_OTHER)) - continue; - if (ap->type == ARCHIVE_ENTRY_ACL_TYPE_DEFAULT && - (flags & ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT) != 0) - prefix = "default:"; - else - prefix = NULL; - r = archive_mstring_get_mbs_l( - NULL, &ap->name, &name, &len, sc); - if (r != 0) { - free(s); - return (NULL); - } - if (count > 0) - *p++ = separator; - if (name == NULL || - (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)) { - id = ap->id; - } else { - id = -1; - } - append_entry(&p, prefix, ap->type, ap->tag, flags, name, - ap->permset, id); - count++; - } - - /* Add terminating character */ - *p++ = '\0'; - - len = strlen(s); - - if ((ssize_t)len > (length - 1)) - __archive_errx(1, "Buffer overrun"); - - if (text_len != NULL) - *text_len = len; - - return (s); -} - -static void -append_id(char **p, int id) -{ - if (id < 0) - id = 0; - if (id > 9) - append_id(p, id / 10); - *(*p)++ = "0123456789"[id % 10]; -} - -static void -append_entry(char **p, const char *prefix, int type, - int tag, int flags, const char *name, int perm, int id) -{ - int i; - - if (prefix != NULL) { - strcpy(*p, prefix); - *p += strlen(*p); - } - switch (tag) { - case ARCHIVE_ENTRY_ACL_USER_OBJ: - name = NULL; - id = -1; - if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) { - strcpy(*p, "owner@"); - break; - } - /* FALLTHROUGH */ - case ARCHIVE_ENTRY_ACL_USER: - strcpy(*p, "user"); - break; - case ARCHIVE_ENTRY_ACL_GROUP_OBJ: - name = NULL; - id = -1; - if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) { - strcpy(*p, "group@"); - break; - } - /* FALLTHROUGH */ - case ARCHIVE_ENTRY_ACL_GROUP: - strcpy(*p, "group"); - break; - case ARCHIVE_ENTRY_ACL_MASK: - strcpy(*p, "mask"); - name = NULL; - id = -1; - break; - case ARCHIVE_ENTRY_ACL_OTHER: - strcpy(*p, "other"); - name = NULL; - id = -1; - break; - case ARCHIVE_ENTRY_ACL_EVERYONE: - strcpy(*p, "everyone@"); - name = NULL; - id = -1; - break; - } - *p += strlen(*p); - *(*p)++ = ':'; - if (((type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) || - tag == ARCHIVE_ENTRY_ACL_USER || - tag == ARCHIVE_ENTRY_ACL_GROUP) { - if (name != NULL) { - strcpy(*p, name); - *p += strlen(*p); - } else if (tag == ARCHIVE_ENTRY_ACL_USER - || tag == ARCHIVE_ENTRY_ACL_GROUP) { - append_id(p, id); - if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) == 0) - id = -1; - } - /* Solaris style has no second colon after other and mask */ - if (((flags & ARCHIVE_ENTRY_ACL_STYLE_SOLARIS) == 0) - || (tag != ARCHIVE_ENTRY_ACL_OTHER - && tag != ARCHIVE_ENTRY_ACL_MASK)) - *(*p)++ = ':'; - } - if ((type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) { - /* POSIX.1e ACL perms */ - *(*p)++ = (perm & 0444) ? 'r' : '-'; - *(*p)++ = (perm & 0222) ? 'w' : '-'; - *(*p)++ = (perm & 0111) ? 'x' : '-'; - } else { - /* NFSv4 ACL perms */ - for (i = 0; i < nfsv4_acl_perm_map_size; i++) { - if (perm & nfsv4_acl_perm_map[i].perm) - *(*p)++ = nfsv4_acl_perm_map[i].c; - else if ((flags & ARCHIVE_ENTRY_ACL_STYLE_COMPACT) == 0) - *(*p)++ = '-'; - } - *(*p)++ = ':'; - for (i = 0; i < nfsv4_acl_flag_map_size; i++) { - if (perm & nfsv4_acl_flag_map[i].perm) - *(*p)++ = nfsv4_acl_flag_map[i].c; - else if ((flags & ARCHIVE_ENTRY_ACL_STYLE_COMPACT) == 0) - *(*p)++ = '-'; - } - *(*p)++ = ':'; - switch (type) { - case ARCHIVE_ENTRY_ACL_TYPE_ALLOW: - strcpy(*p, "allow"); - break; - case ARCHIVE_ENTRY_ACL_TYPE_DENY: - strcpy(*p, "deny"); - break; - case ARCHIVE_ENTRY_ACL_TYPE_AUDIT: - strcpy(*p, "audit"); - break; - case ARCHIVE_ENTRY_ACL_TYPE_ALARM: - strcpy(*p, "alarm"); - break; - } - *p += strlen(*p); - } - if (id != -1) { - *(*p)++ = ':'; - append_id(p, id); - } -} - -/* - * Parse a wide ACL text string. - * - * The want_type argument may be one of the following: - * ARCHIVE_ENTRY_ACL_TYPE_ACCESS - text is a POSIX.1e ACL of type ACCESS - * ARCHIVE_ENTRY_ACL_TYPE_DEFAULT - text is a POSIX.1e ACL of type DEFAULT - * ARCHIVE_ENTRY_ACL_TYPE_NFS4 - text is as a NFSv4 ACL - * - * POSIX.1e ACL entries prefixed with "default:" are treated as - * ARCHIVE_ENTRY_ACL_TYPE_DEFAULT unless type is ARCHIVE_ENTRY_ACL_TYPE_NFS4 - */ -int -archive_acl_from_text_w(struct archive_acl *acl, const wchar_t *text, - int want_type) -{ - struct { - const wchar_t *start; - const wchar_t *end; - } field[6], name; - - const wchar_t *s, *st; - - int numfields, fields, n, r, sol, ret; - int type, types, tag, permset, id; - size_t len; - wchar_t sep; - - ret = ARCHIVE_OK; - types = 0; - - switch (want_type) { - case ARCHIVE_ENTRY_ACL_TYPE_POSIX1E: - want_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS; - __LA_FALLTHROUGH; - case ARCHIVE_ENTRY_ACL_TYPE_ACCESS: - case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT: - numfields = 5; - break; - case ARCHIVE_ENTRY_ACL_TYPE_NFS4: - numfields = 6; - break; - default: - return (ARCHIVE_FATAL); - } - - while (text != NULL && *text != L'\0') { - /* - * Parse the fields out of the next entry, - * advance 'text' to start of next entry. - */ - fields = 0; - do { - const wchar_t *start, *end; - next_field_w(&text, &start, &end, &sep); - if (fields < numfields) { - field[fields].start = start; - field[fields].end = end; - } - ++fields; - } while (sep == L':'); - - /* Set remaining fields to blank. */ - for (n = fields; n < numfields; ++n) - field[n].start = field[n].end = NULL; - - if (field[0].start != NULL && *(field[0].start) == L'#') { - /* Comment, skip entry */ - continue; - } - - n = 0; - sol = 0; - id = -1; - permset = 0; - name.start = name.end = NULL; - - if (want_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - /* POSIX.1e ACLs */ - /* - * Default keyword "default:user::rwx" - * if found, we have one more field - * - * We also support old Solaris extension: - * "defaultuser::rwx" is the default ACL corresponding - * to "user::rwx", etc. valid only for first field - */ - s = field[0].start; - len = field[0].end - field[0].start; - if (*s == L'd' && (len == 1 || (len >= 7 - && wmemcmp((s + 1), L"efault", 6) == 0))) { - type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT; - if (len > 7) - field[0].start += 7; - else - n = 1; - } else - type = want_type; - - /* Check for a numeric ID in field n+1 or n+3. */ - isint_w(field[n + 1].start, field[n + 1].end, &id); - /* Field n+3 is optional. */ - if (id == -1 && fields > n+3) - isint_w(field[n + 3].start, field[n + 3].end, - &id); - - tag = 0; - s = field[n].start; - st = field[n].start + 1; - len = field[n].end - field[n].start; - - switch (*s) { - case L'u': - if (len == 1 || (len == 4 - && wmemcmp(st, L"ser", 3) == 0)) - tag = ARCHIVE_ENTRY_ACL_USER_OBJ; - break; - case L'g': - if (len == 1 || (len == 5 - && wmemcmp(st, L"roup", 4) == 0)) - tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ; - break; - case L'o': - if (len == 1 || (len == 5 - && wmemcmp(st, L"ther", 4) == 0)) - tag = ARCHIVE_ENTRY_ACL_OTHER; - break; - case L'm': - if (len == 1 || (len == 4 - && wmemcmp(st, L"ask", 3) == 0)) - tag = ARCHIVE_ENTRY_ACL_MASK; - break; - default: - break; - } - - switch (tag) { - case ARCHIVE_ENTRY_ACL_OTHER: - case ARCHIVE_ENTRY_ACL_MASK: - if (fields == (n + 2) - && field[n + 1].start < field[n + 1].end - && ismode_w(field[n + 1].start, - field[n + 1].end, &permset)) { - /* This is Solaris-style "other:rwx" */ - sol = 1; - } else if (fields == (n + 3) && - field[n + 1].start < field[n + 1].end) { - /* Invalid mask or other field */ - ret = ARCHIVE_WARN; - continue; - } - break; - case ARCHIVE_ENTRY_ACL_USER_OBJ: - case ARCHIVE_ENTRY_ACL_GROUP_OBJ: - if (id != -1 || - field[n + 1].start < field[n + 1].end) { - name = field[n + 1]; - if (tag == ARCHIVE_ENTRY_ACL_USER_OBJ) - tag = ARCHIVE_ENTRY_ACL_USER; - else - tag = ARCHIVE_ENTRY_ACL_GROUP; - } - break; - default: - /* Invalid tag, skip entry */ - ret = ARCHIVE_WARN; - continue; - } - - /* - * Without "default:" we expect mode in field 2 - * Exception: Solaris other and mask fields - */ - if (permset == 0 && !ismode_w(field[n + 2 - sol].start, - field[n + 2 - sol].end, &permset)) { - /* Invalid mode, skip entry */ - ret = ARCHIVE_WARN; - continue; - } - } else { - /* NFS4 ACLs */ - s = field[0].start; - len = field[0].end - field[0].start; - tag = 0; - - switch (len) { - case 4: - if (wmemcmp(s, L"user", 4) == 0) - tag = ARCHIVE_ENTRY_ACL_USER; - break; - case 5: - if (wmemcmp(s, L"group", 5) == 0) - tag = ARCHIVE_ENTRY_ACL_GROUP; - break; - case 6: - if (wmemcmp(s, L"owner@", 6) == 0) - tag = ARCHIVE_ENTRY_ACL_USER_OBJ; - else if (wmemcmp(s, L"group@", len) == 0) - tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ; - break; - case 9: - if (wmemcmp(s, L"everyone@", 9) == 0) - tag = ARCHIVE_ENTRY_ACL_EVERYONE; - default: - break; - } - - if (tag == 0) { - /* Invalid tag, skip entry */ - ret = ARCHIVE_WARN; - continue; - } else if (tag == ARCHIVE_ENTRY_ACL_USER || - tag == ARCHIVE_ENTRY_ACL_GROUP) { - n = 1; - name = field[1]; - isint_w(name.start, name.end, &id); - } else - n = 0; - - if (!is_nfs4_perms_w(field[1 + n].start, - field[1 + n].end, &permset)) { - /* Invalid NFSv4 perms, skip entry */ - ret = ARCHIVE_WARN; - continue; - } - if (!is_nfs4_flags_w(field[2 + n].start, - field[2 + n].end, &permset)) { - /* Invalid NFSv4 flags, skip entry */ - ret = ARCHIVE_WARN; - continue; - } - s = field[3 + n].start; - len = field[3 + n].end - field[3 + n].start; - type = 0; - if (len == 4) { - if (wmemcmp(s, L"deny", 4) == 0) - type = ARCHIVE_ENTRY_ACL_TYPE_DENY; - } else if (len == 5) { - if (wmemcmp(s, L"allow", 5) == 0) - type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW; - else if (wmemcmp(s, L"audit", 5) == 0) - type = ARCHIVE_ENTRY_ACL_TYPE_AUDIT; - else if (wmemcmp(s, L"alarm", 5) == 0) - type = ARCHIVE_ENTRY_ACL_TYPE_ALARM; - } - if (type == 0) { - /* Invalid entry type, skip entry */ - ret = ARCHIVE_WARN; - continue; - } - isint_w(field[4 + n].start, field[4 + n].end, &id); - } - - /* Add entry to the internal list. */ - r = archive_acl_add_entry_w_len(acl, type, permset, - tag, id, name.start, name.end - name.start); - if (r < ARCHIVE_WARN) - return (r); - if (r != ARCHIVE_OK) - ret = ARCHIVE_WARN; - types |= type; - } - - /* Reset ACL */ - archive_acl_reset(acl, types); - - return (ret); -} - -/* - * Parse a string to a positive decimal integer. Returns true if - * the string is non-empty and consists only of decimal digits, - * false otherwise. - */ -static int -isint_w(const wchar_t *start, const wchar_t *end, int *result) -{ - int n = 0; - if (start >= end) - return (0); - while (start < end) { - if (*start < L'0' || *start > L'9') - return (0); - if (n > (INT_MAX / 10) || - (n == INT_MAX / 10 && (*start - L'0') > INT_MAX % 10)) { - n = INT_MAX; - } else { - n *= 10; - n += *start - L'0'; - } - start++; - } - *result = n; - return (1); -} - -/* - * Parse a string as a mode field. Returns true if - * the string is non-empty and consists only of mode characters, - * false otherwise. - */ -static int -ismode_w(const wchar_t *start, const wchar_t *end, int *permset) -{ - const wchar_t *p; - - if (start >= end) - return (0); - p = start; - *permset = 0; - while (p < end) { - switch (*p++) { - case L'r': case L'R': - *permset |= ARCHIVE_ENTRY_ACL_READ; - break; - case L'w': case L'W': - *permset |= ARCHIVE_ENTRY_ACL_WRITE; - break; - case L'x': case L'X': - *permset |= ARCHIVE_ENTRY_ACL_EXECUTE; - break; - case L'-': - break; - default: - return (0); - } - } - return (1); -} - -/* - * Parse a string as a NFS4 ACL permission field. - * Returns true if the string is non-empty and consists only of NFS4 ACL - * permission characters, false otherwise - */ -static int -is_nfs4_perms_w(const wchar_t *start, const wchar_t *end, int *permset) -{ - const wchar_t *p = start; - - while (p < end) { - switch (*p++) { - case L'r': - *permset |= ARCHIVE_ENTRY_ACL_READ_DATA; - break; - case L'w': - *permset |= ARCHIVE_ENTRY_ACL_WRITE_DATA; - break; - case L'x': - *permset |= ARCHIVE_ENTRY_ACL_EXECUTE; - break; - case L'p': - *permset |= ARCHIVE_ENTRY_ACL_APPEND_DATA; - break; - case L'D': - *permset |= ARCHIVE_ENTRY_ACL_DELETE_CHILD; - break; - case L'd': - *permset |= ARCHIVE_ENTRY_ACL_DELETE; - break; - case L'a': - *permset |= ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES; - break; - case L'A': - *permset |= ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES; - break; - case L'R': - *permset |= ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS; - break; - case L'W': - *permset |= ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS; - break; - case L'c': - *permset |= ARCHIVE_ENTRY_ACL_READ_ACL; - break; - case L'C': - *permset |= ARCHIVE_ENTRY_ACL_WRITE_ACL; - break; - case L'o': - *permset |= ARCHIVE_ENTRY_ACL_WRITE_OWNER; - break; - case L's': - *permset |= ARCHIVE_ENTRY_ACL_SYNCHRONIZE; - break; - case L'-': - break; - default: - return(0); - } - } - return (1); -} - -/* - * Parse a string as a NFS4 ACL flags field. - * Returns true if the string is non-empty and consists only of NFS4 ACL - * flag characters, false otherwise - */ -static int -is_nfs4_flags_w(const wchar_t *start, const wchar_t *end, int *permset) -{ - const wchar_t *p = start; - - while (p < end) { - switch(*p++) { - case L'f': - *permset |= ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT; - break; - case L'd': - *permset |= ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT; - break; - case L'i': - *permset |= ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY; - break; - case L'n': - *permset |= - ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT; - break; - case L'S': - *permset |= ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS; - break; - case L'F': - *permset |= ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS; - break; - case L'I': - *permset |= ARCHIVE_ENTRY_ACL_ENTRY_INHERITED; - break; - case L'-': - break; - default: - return (0); - } - } - return (1); -} - -/* - * Match "[:whitespace:]*(.*)[:whitespace:]*[:,\n]". *wp is updated - * to point to just after the separator. *start points to the first - * character of the matched text and *end just after the last - * character of the matched identifier. In particular *end - *start - * is the length of the field body, not including leading or trailing - * whitespace. - */ -static void -next_field_w(const wchar_t **wp, const wchar_t **start, - const wchar_t **end, wchar_t *sep) -{ - /* Skip leading whitespace to find start of field. */ - while (**wp == L' ' || **wp == L'\t' || **wp == L'\n') { - (*wp)++; - } - *start = *wp; - - /* Scan for the separator. */ - while (**wp != L'\0' && **wp != L',' && **wp != L':' && - **wp != L'\n' && **wp != L'#') { - (*wp)++; - } - *sep = **wp; - - /* Locate end of field, trim trailing whitespace if necessary */ - if (*wp == *start) { - *end = *wp; - } else { - *end = *wp - 1; - while (**end == L' ' || **end == L'\t' || **end == L'\n') { - (*end)--; - } - (*end)++; - } - - /* Handle in-field comments */ - if (*sep == L'#') { - while (**wp != L'\0' && **wp != L',' && **wp != L'\n') { - (*wp)++; - } - *sep = **wp; - } - - /* Adjust scanner location. */ - if (**wp != L'\0') - (*wp)++; -} - -/* - * Parse an ACL text string. - * - * The want_type argument may be one of the following: - * ARCHIVE_ENTRY_ACL_TYPE_ACCESS - text is a POSIX.1e ACL of type ACCESS - * ARCHIVE_ENTRY_ACL_TYPE_DEFAULT - text is a POSIX.1e ACL of type DEFAULT - * ARCHIVE_ENTRY_ACL_TYPE_NFS4 - text is as a NFSv4 ACL - * - * POSIX.1e ACL entries prefixed with "default:" are treated as - * ARCHIVE_ENTRY_ACL_TYPE_DEFAULT unless type is ARCHIVE_ENTRY_ACL_TYPE_NFS4 - */ -int -archive_acl_from_text_l(struct archive_acl *acl, const char *text, - int want_type, struct archive_string_conv *sc) -{ - struct { - const char *start; - const char *end; - } field[6], name; - - const char *s, *st; - int numfields, fields, n, r, sol, ret; - int type, types, tag, permset, id; - size_t len; - char sep; - - switch (want_type) { - case ARCHIVE_ENTRY_ACL_TYPE_POSIX1E: - want_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS; - __LA_FALLTHROUGH; - case ARCHIVE_ENTRY_ACL_TYPE_ACCESS: - case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT: - numfields = 5; - break; - case ARCHIVE_ENTRY_ACL_TYPE_NFS4: - numfields = 6; - break; - default: - return (ARCHIVE_FATAL); - } - - ret = ARCHIVE_OK; - types = 0; - - while (text != NULL && *text != '\0') { - /* - * Parse the fields out of the next entry, - * advance 'text' to start of next entry. - */ - fields = 0; - do { - const char *start, *end; - next_field(&text, &start, &end, &sep); - if (fields < numfields) { - field[fields].start = start; - field[fields].end = end; - } - ++fields; - } while (sep == ':'); - - /* Set remaining fields to blank. */ - for (n = fields; n < numfields; ++n) - field[n].start = field[n].end = NULL; - - if (field[0].start != NULL && *(field[0].start) == '#') { - /* Comment, skip entry */ - continue; - } - - n = 0; - sol = 0; - id = -1; - permset = 0; - name.start = name.end = NULL; - - if (want_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - /* POSIX.1e ACLs */ - /* - * Default keyword "default:user::rwx" - * if found, we have one more field - * - * We also support old Solaris extension: - * "defaultuser::rwx" is the default ACL corresponding - * to "user::rwx", etc. valid only for first field - */ - s = field[0].start; - len = field[0].end - field[0].start; - if (*s == 'd' && (len == 1 || (len >= 7 - && memcmp((s + 1), "efault", 6) == 0))) { - type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT; - if (len > 7) - field[0].start += 7; - else - n = 1; - } else - type = want_type; - - /* Check for a numeric ID in field n+1 or n+3. */ - isint(field[n + 1].start, field[n + 1].end, &id); - /* Field n+3 is optional. */ - if (id == -1 && fields > (n + 3)) - isint(field[n + 3].start, field[n + 3].end, - &id); - - tag = 0; - s = field[n].start; - st = field[n].start + 1; - len = field[n].end - field[n].start; - - if (len == 0) { - ret = ARCHIVE_WARN; - continue; - } - - switch (*s) { - case 'u': - if (len == 1 || (len == 4 - && memcmp(st, "ser", 3) == 0)) - tag = ARCHIVE_ENTRY_ACL_USER_OBJ; - break; - case 'g': - if (len == 1 || (len == 5 - && memcmp(st, "roup", 4) == 0)) - tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ; - break; - case 'o': - if (len == 1 || (len == 5 - && memcmp(st, "ther", 4) == 0)) - tag = ARCHIVE_ENTRY_ACL_OTHER; - break; - case 'm': - if (len == 1 || (len == 4 - && memcmp(st, "ask", 3) == 0)) - tag = ARCHIVE_ENTRY_ACL_MASK; - break; - default: - break; - } - - switch (tag) { - case ARCHIVE_ENTRY_ACL_OTHER: - case ARCHIVE_ENTRY_ACL_MASK: - if (fields == (n + 2) - && field[n + 1].start < field[n + 1].end - && ismode(field[n + 1].start, - field[n + 1].end, &permset)) { - /* This is Solaris-style "other:rwx" */ - sol = 1; - } else if (fields == (n + 3) && - field[n + 1].start < field[n + 1].end) { - /* Invalid mask or other field */ - ret = ARCHIVE_WARN; - continue; - } - break; - case ARCHIVE_ENTRY_ACL_USER_OBJ: - case ARCHIVE_ENTRY_ACL_GROUP_OBJ: - if (id != -1 || - field[n + 1].start < field[n + 1].end) { - name = field[n + 1]; - if (tag == ARCHIVE_ENTRY_ACL_USER_OBJ) - tag = ARCHIVE_ENTRY_ACL_USER; - else - tag = ARCHIVE_ENTRY_ACL_GROUP; - } - break; - default: - /* Invalid tag, skip entry */ - ret = ARCHIVE_WARN; - continue; - } - - /* - * Without "default:" we expect mode in field 3 - * Exception: Solaris other and mask fields - */ - if (permset == 0 && !ismode(field[n + 2 - sol].start, - field[n + 2 - sol].end, &permset)) { - /* Invalid mode, skip entry */ - ret = ARCHIVE_WARN; - continue; - } - } else { - /* NFS4 ACLs */ - s = field[0].start; - len = field[0].end - field[0].start; - tag = 0; - - switch (len) { - case 4: - if (memcmp(s, "user", 4) == 0) - tag = ARCHIVE_ENTRY_ACL_USER; - break; - case 5: - if (memcmp(s, "group", 5) == 0) - tag = ARCHIVE_ENTRY_ACL_GROUP; - break; - case 6: - if (memcmp(s, "owner@", 6) == 0) - tag = ARCHIVE_ENTRY_ACL_USER_OBJ; - else if (memcmp(s, "group@", 6) == 0) - tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ; - break; - case 9: - if (memcmp(s, "everyone@", 9) == 0) - tag = ARCHIVE_ENTRY_ACL_EVERYONE; - break; - default: - break; - } - - if (tag == 0) { - /* Invalid tag, skip entry */ - ret = ARCHIVE_WARN; - continue; - } else if (tag == ARCHIVE_ENTRY_ACL_USER || - tag == ARCHIVE_ENTRY_ACL_GROUP) { - n = 1; - name = field[1]; - isint(name.start, name.end, &id); - } else - n = 0; - - if (!is_nfs4_perms(field[1 + n].start, - field[1 + n].end, &permset)) { - /* Invalid NFSv4 perms, skip entry */ - ret = ARCHIVE_WARN; - continue; - } - if (!is_nfs4_flags(field[2 + n].start, - field[2 + n].end, &permset)) { - /* Invalid NFSv4 flags, skip entry */ - ret = ARCHIVE_WARN; - continue; - } - s = field[3 + n].start; - len = field[3 + n].end - field[3 + n].start; - type = 0; - if (len == 4) { - if (memcmp(s, "deny", 4) == 0) - type = ARCHIVE_ENTRY_ACL_TYPE_DENY; - } else if (len == 5) { - if (memcmp(s, "allow", 5) == 0) - type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW; - else if (memcmp(s, "audit", 5) == 0) - type = ARCHIVE_ENTRY_ACL_TYPE_AUDIT; - else if (memcmp(s, "alarm", 5) == 0) - type = ARCHIVE_ENTRY_ACL_TYPE_ALARM; - } - if (type == 0) { - /* Invalid entry type, skip entry */ - ret = ARCHIVE_WARN; - continue; - } - isint(field[4 + n].start, field[4 + n].end, - &id); - } - - /* Add entry to the internal list. */ - r = archive_acl_add_entry_len_l(acl, type, permset, - tag, id, name.start, name.end - name.start, sc); - if (r < ARCHIVE_WARN) - return (r); - if (r != ARCHIVE_OK) - ret = ARCHIVE_WARN; - types |= type; - } - - /* Reset ACL */ - archive_acl_reset(acl, types); - - return (ret); -} - -/* - * Parse a string to a positive decimal integer. Returns true if - * the string is non-empty and consists only of decimal digits, - * false otherwise. - */ -static int -isint(const char *start, const char *end, int *result) -{ - int n = 0; - if (start >= end) - return (0); - while (start < end) { - if (*start < '0' || *start > '9') - return (0); - if (n > (INT_MAX / 10) || - (n == INT_MAX / 10 && (*start - '0') > INT_MAX % 10)) { - n = INT_MAX; - } else { - n *= 10; - n += *start - '0'; - } - start++; - } - *result = n; - return (1); -} - -/* - * Parse a string as a mode field. Returns true if - * the string is non-empty and consists only of mode characters, - * false otherwise. - */ -static int -ismode(const char *start, const char *end, int *permset) -{ - const char *p; - - if (start >= end) - return (0); - p = start; - *permset = 0; - while (p < end) { - switch (*p++) { - case 'r': case 'R': - *permset |= ARCHIVE_ENTRY_ACL_READ; - break; - case 'w': case 'W': - *permset |= ARCHIVE_ENTRY_ACL_WRITE; - break; - case 'x': case 'X': - *permset |= ARCHIVE_ENTRY_ACL_EXECUTE; - break; - case '-': - break; - default: - return (0); - } - } - return (1); -} - -/* - * Parse a string as a NFS4 ACL permission field. - * Returns true if the string is non-empty and consists only of NFS4 ACL - * permission characters, false otherwise - */ -static int -is_nfs4_perms(const char *start, const char *end, int *permset) -{ - const char *p = start; - - while (p < end) { - switch (*p++) { - case 'r': - *permset |= ARCHIVE_ENTRY_ACL_READ_DATA; - break; - case 'w': - *permset |= ARCHIVE_ENTRY_ACL_WRITE_DATA; - break; - case 'x': - *permset |= ARCHIVE_ENTRY_ACL_EXECUTE; - break; - case 'p': - *permset |= ARCHIVE_ENTRY_ACL_APPEND_DATA; - break; - case 'D': - *permset |= ARCHIVE_ENTRY_ACL_DELETE_CHILD; - break; - case 'd': - *permset |= ARCHIVE_ENTRY_ACL_DELETE; - break; - case 'a': - *permset |= ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES; - break; - case 'A': - *permset |= ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES; - break; - case 'R': - *permset |= ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS; - break; - case 'W': - *permset |= ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS; - break; - case 'c': - *permset |= ARCHIVE_ENTRY_ACL_READ_ACL; - break; - case 'C': - *permset |= ARCHIVE_ENTRY_ACL_WRITE_ACL; - break; - case 'o': - *permset |= ARCHIVE_ENTRY_ACL_WRITE_OWNER; - break; - case 's': - *permset |= ARCHIVE_ENTRY_ACL_SYNCHRONIZE; - break; - case '-': - break; - default: - return(0); - } - } - return (1); -} - -/* - * Parse a string as a NFS4 ACL flags field. - * Returns true if the string is non-empty and consists only of NFS4 ACL - * flag characters, false otherwise - */ -static int -is_nfs4_flags(const char *start, const char *end, int *permset) -{ - const char *p = start; - - while (p < end) { - switch(*p++) { - case 'f': - *permset |= ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT; - break; - case 'd': - *permset |= ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT; - break; - case 'i': - *permset |= ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY; - break; - case 'n': - *permset |= - ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT; - break; - case 'S': - *permset |= ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS; - break; - case 'F': - *permset |= ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS; - break; - case 'I': - *permset |= ARCHIVE_ENTRY_ACL_ENTRY_INHERITED; - break; - case '-': - break; - default: - return (0); - } - } - return (1); -} - -/* - * Match "[:whitespace:]*(.*)[:whitespace:]*[:,\n]". *wp is updated - * to point to just after the separator. *start points to the first - * character of the matched text and *end just after the last - * character of the matched identifier. In particular *end - *start - * is the length of the field body, not including leading or trailing - * whitespace. - */ -static void -next_field(const char **p, const char **start, - const char **end, char *sep) -{ - /* Skip leading whitespace to find start of field. */ - while (**p == ' ' || **p == '\t' || **p == '\n') { - (*p)++; - } - *start = *p; - - /* Scan for the separator. */ - while (**p != '\0' && **p != ',' && **p != ':' && **p != '\n' && - **p != '#') { - (*p)++; - } - *sep = **p; - - /* Locate end of field, trim trailing whitespace if necessary */ - if (*p == *start) { - *end = *p; - } else { - *end = *p - 1; - while (**end == ' ' || **end == '\t' || **end == '\n') { - (*end)--; - } - (*end)++; - } - - /* Handle in-field comments */ - if (*sep == '#') { - while (**p != '\0' && **p != ',' && **p != '\n') { - (*p)++; - } - *sep = **p; - } - - /* Adjust scanner location. */ - if (**p != '\0') - (*p)++; -} diff --git a/thirdparty/libarchive/libarchive/archive_acl_private.h b/thirdparty/libarchive/libarchive/archive_acl_private.h deleted file mode 100644 index af108162c..000000000 --- a/thirdparty/libarchive/libarchive/archive_acl_private.h +++ /dev/null @@ -1,83 +0,0 @@ -/*- - * Copyright (c) 2003-2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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$ - */ - -#ifndef ARCHIVE_ACL_PRIVATE_H_INCLUDED -#define ARCHIVE_ACL_PRIVATE_H_INCLUDED - -#ifndef __LIBARCHIVE_BUILD -#error This header is only to be used internally to libarchive. -#endif - -#include "archive_string.h" - -struct archive_acl_entry { - struct archive_acl_entry *next; - int type; /* E.g., access or default */ - int tag; /* E.g., user/group/other/mask */ - int permset; /* r/w/x bits */ - int id; /* uid/gid for user/group */ - struct archive_mstring name; /* uname/gname */ -}; - -struct archive_acl { - mode_t mode; - struct archive_acl_entry *acl_head; - struct archive_acl_entry *acl_p; - int acl_state; /* See acl_next for details. */ - wchar_t *acl_text_w; - char *acl_text; - int acl_types; -}; - -void archive_acl_clear(struct archive_acl *); -void archive_acl_copy(struct archive_acl *, struct archive_acl *); -int archive_acl_count(struct archive_acl *, int); -int archive_acl_types(struct archive_acl *); -int archive_acl_reset(struct archive_acl *, int); -int archive_acl_next(struct archive *, struct archive_acl *, int, - int *, int *, int *, int *, const char **); - -int archive_acl_add_entry(struct archive_acl *, int, int, int, int, const char *); -int archive_acl_add_entry_w_len(struct archive_acl *, - int, int, int, int, const wchar_t *, size_t); -int archive_acl_add_entry_len(struct archive_acl *, - int, int, int, int, const char *, size_t); - -wchar_t *archive_acl_to_text_w(struct archive_acl *, ssize_t *, int, - struct archive *); -char *archive_acl_to_text_l(struct archive_acl *, ssize_t *, int, - struct archive_string_conv *); - -/* - * ACL text parser. - */ -int archive_acl_from_text_w(struct archive_acl *, const wchar_t * /* wtext */, - int /* type */); -int archive_acl_from_text_l(struct archive_acl *, const char * /* text */, - int /* type */, struct archive_string_conv *); - -#endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */ diff --git a/thirdparty/libarchive/libarchive/archive_blake2.h b/thirdparty/libarchive/libarchive/archive_blake2.h deleted file mode 100644 index 8f6b5e922..000000000 --- a/thirdparty/libarchive/libarchive/archive_blake2.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - BLAKE2 reference source code package - reference C implementations - - Copyright 2012, Samuel Neves . You may use this under the - terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at - your option. The terms of these licenses can be found at: - - - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - - OpenSSL license : https://www.openssl.org/source/license.html - - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 - - More information about the BLAKE2 hash function can be found at - https://blake2.net. -*/ - -#ifndef ARCHIVE_BLAKE2_H -#define ARCHIVE_BLAKE2_H - -#include -#include - -#if defined(_MSC_VER) -#define BLAKE2_PACKED(x) __pragma(pack(push, 1)) x __pragma(pack(pop)) -#elif defined(__GNUC__) -#define BLAKE2_PACKED(x) x __attribute__((packed)) -#else -#define BLAKE2_PACKED(x) _Pragma("pack 1") x _Pragma("pack 0") -#endif - -#if defined(__cplusplus) -extern "C" { -#endif - - enum blake2s_constant - { - BLAKE2S_BLOCKBYTES = 64, - BLAKE2S_OUTBYTES = 32, - BLAKE2S_KEYBYTES = 32, - BLAKE2S_SALTBYTES = 8, - BLAKE2S_PERSONALBYTES = 8 - }; - - enum blake2b_constant - { - BLAKE2B_BLOCKBYTES = 128, - BLAKE2B_OUTBYTES = 64, - BLAKE2B_KEYBYTES = 64, - BLAKE2B_SALTBYTES = 16, - BLAKE2B_PERSONALBYTES = 16 - }; - - typedef struct blake2s_state__ - { - uint32_t h[8]; - uint32_t t[2]; - uint32_t f[2]; - uint8_t buf[BLAKE2S_BLOCKBYTES]; - size_t buflen; - size_t outlen; - uint8_t last_node; - } blake2s_state; - - typedef struct blake2b_state__ - { - uint64_t h[8]; - uint64_t t[2]; - uint64_t f[2]; - uint8_t buf[BLAKE2B_BLOCKBYTES]; - size_t buflen; - size_t outlen; - uint8_t last_node; - } blake2b_state; - - typedef struct blake2sp_state__ - { - blake2s_state S[8][1]; - blake2s_state R[1]; - uint8_t buf[8 * BLAKE2S_BLOCKBYTES]; - size_t buflen; - size_t outlen; - } blake2sp_state; - - typedef struct blake2bp_state__ - { - blake2b_state S[4][1]; - blake2b_state R[1]; - uint8_t buf[4 * BLAKE2B_BLOCKBYTES]; - size_t buflen; - size_t outlen; - } blake2bp_state; - - BLAKE2_PACKED(struct blake2s_param__ - { - uint8_t digest_length; /* 1 */ - uint8_t key_length; /* 2 */ - uint8_t fanout; /* 3 */ - uint8_t depth; /* 4 */ - uint32_t leaf_length; /* 8 */ - uint32_t node_offset; /* 12 */ - uint16_t xof_length; /* 14 */ - uint8_t node_depth; /* 15 */ - uint8_t inner_length; /* 16 */ - /* uint8_t reserved[0]; */ - uint8_t salt[BLAKE2S_SALTBYTES]; /* 24 */ - uint8_t personal[BLAKE2S_PERSONALBYTES]; /* 32 */ - }); - - typedef struct blake2s_param__ blake2s_param; - - BLAKE2_PACKED(struct blake2b_param__ - { - uint8_t digest_length; /* 1 */ - uint8_t key_length; /* 2 */ - uint8_t fanout; /* 3 */ - uint8_t depth; /* 4 */ - uint32_t leaf_length; /* 8 */ - uint32_t node_offset; /* 12 */ - uint32_t xof_length; /* 16 */ - uint8_t node_depth; /* 17 */ - uint8_t inner_length; /* 18 */ - uint8_t reserved[14]; /* 32 */ - uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ - uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ - }); - - typedef struct blake2b_param__ blake2b_param; - - typedef struct blake2xs_state__ - { - blake2s_state S[1]; - blake2s_param P[1]; - } blake2xs_state; - - typedef struct blake2xb_state__ - { - blake2b_state S[1]; - blake2b_param P[1]; - } blake2xb_state; - - /* Padded structs result in a compile-time error */ - enum { - BLAKE2_DUMMY_1 = 1/(sizeof(blake2s_param) == BLAKE2S_OUTBYTES), - BLAKE2_DUMMY_2 = 1/(sizeof(blake2b_param) == BLAKE2B_OUTBYTES) - }; - - /* Streaming API */ - int blake2s_init( blake2s_state *S, size_t outlen ); - int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2s_init_param( blake2s_state *S, const blake2s_param *P ); - int blake2s_update( blake2s_state *S, const void *in, size_t inlen ); - int blake2s_final( blake2s_state *S, void *out, size_t outlen ); - - int blake2b_init( blake2b_state *S, size_t outlen ); - int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2b_init_param( blake2b_state *S, const blake2b_param *P ); - int blake2b_update( blake2b_state *S, const void *in, size_t inlen ); - int blake2b_final( blake2b_state *S, void *out, size_t outlen ); - - int blake2sp_init( blake2sp_state *S, size_t outlen ); - int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2sp_update( blake2sp_state *S, const void *in, size_t inlen ); - int blake2sp_final( blake2sp_state *S, void *out, size_t outlen ); - - int blake2bp_init( blake2bp_state *S, size_t outlen ); - int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen ); - int blake2bp_update( blake2bp_state *S, const void *in, size_t inlen ); - int blake2bp_final( blake2bp_state *S, void *out, size_t outlen ); - - /* Variable output length API */ - int blake2xs_init( blake2xs_state *S, const size_t outlen ); - int blake2xs_init_key( blake2xs_state *S, const size_t outlen, const void *key, size_t keylen ); - int blake2xs_update( blake2xs_state *S, const void *in, size_t inlen ); - int blake2xs_final(blake2xs_state *S, void *out, size_t outlen); - - int blake2xb_init( blake2xb_state *S, const size_t outlen ); - int blake2xb_init_key( blake2xb_state *S, const size_t outlen, const void *key, size_t keylen ); - int blake2xb_update( blake2xb_state *S, const void *in, size_t inlen ); - int blake2xb_final(blake2xb_state *S, void *out, size_t outlen); - - /* Simple API */ - int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); - int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); - - int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); - int blake2bp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); - - int blake2xs( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); - int blake2xb( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); - - /* This is simply an alias for blake2b */ - int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); - -#if defined(__cplusplus) -} -#endif - -#endif diff --git a/thirdparty/libarchive/libarchive/archive_blake2_impl.h b/thirdparty/libarchive/libarchive/archive_blake2_impl.h deleted file mode 100644 index eb8619ca7..000000000 --- a/thirdparty/libarchive/libarchive/archive_blake2_impl.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - BLAKE2 reference source code package - reference C implementations - - Copyright 2012, Samuel Neves . You may use this under the - terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at - your option. The terms of these licenses can be found at: - - - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - - OpenSSL license : https://www.openssl.org/source/license.html - - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 - - More information about the BLAKE2 hash function can be found at - https://blake2.net. -*/ - -#ifndef ARCHIVE_BLAKE2_IMPL_H -#define ARCHIVE_BLAKE2_IMPL_H - -#include -#include - -#if !defined(__cplusplus) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) - #if defined(_MSC_VER) - #define BLAKE2_INLINE __inline - #elif defined(__GNUC__) - #define BLAKE2_INLINE __inline__ - #else - #define BLAKE2_INLINE - #endif -#else - #define BLAKE2_INLINE inline -#endif - -static BLAKE2_INLINE uint32_t load32( const void *src ) -{ -#if defined(NATIVE_LITTLE_ENDIAN) - uint32_t w; - memcpy(&w, src, sizeof w); - return w; -#else - const uint8_t *p = ( const uint8_t * )src; - return (( uint32_t )( p[0] ) << 0) | - (( uint32_t )( p[1] ) << 8) | - (( uint32_t )( p[2] ) << 16) | - (( uint32_t )( p[3] ) << 24) ; -#endif -} - -static BLAKE2_INLINE uint64_t load64( const void *src ) -{ -#if defined(NATIVE_LITTLE_ENDIAN) - uint64_t w; - memcpy(&w, src, sizeof w); - return w; -#else - const uint8_t *p = ( const uint8_t * )src; - return (( uint64_t )( p[0] ) << 0) | - (( uint64_t )( p[1] ) << 8) | - (( uint64_t )( p[2] ) << 16) | - (( uint64_t )( p[3] ) << 24) | - (( uint64_t )( p[4] ) << 32) | - (( uint64_t )( p[5] ) << 40) | - (( uint64_t )( p[6] ) << 48) | - (( uint64_t )( p[7] ) << 56) ; -#endif -} - -static BLAKE2_INLINE uint16_t load16( const void *src ) -{ -#if defined(NATIVE_LITTLE_ENDIAN) - uint16_t w; - memcpy(&w, src, sizeof w); - return w; -#else - const uint8_t *p = ( const uint8_t * )src; - return ( uint16_t )((( uint32_t )( p[0] ) << 0) | - (( uint32_t )( p[1] ) << 8)); -#endif -} - -static BLAKE2_INLINE void store16( void *dst, uint16_t w ) -{ -#if defined(NATIVE_LITTLE_ENDIAN) - memcpy(dst, &w, sizeof w); -#else - uint8_t *p = ( uint8_t * )dst; - *p++ = ( uint8_t )w; w >>= 8; - *p++ = ( uint8_t )w; -#endif -} - -static BLAKE2_INLINE void store32( void *dst, uint32_t w ) -{ -#if defined(NATIVE_LITTLE_ENDIAN) - memcpy(dst, &w, sizeof w); -#else - uint8_t *p = ( uint8_t * )dst; - p[0] = (uint8_t)(w >> 0); - p[1] = (uint8_t)(w >> 8); - p[2] = (uint8_t)(w >> 16); - p[3] = (uint8_t)(w >> 24); -#endif -} - -static BLAKE2_INLINE void store64( void *dst, uint64_t w ) -{ -#if defined(NATIVE_LITTLE_ENDIAN) - memcpy(dst, &w, sizeof w); -#else - uint8_t *p = ( uint8_t * )dst; - p[0] = (uint8_t)(w >> 0); - p[1] = (uint8_t)(w >> 8); - p[2] = (uint8_t)(w >> 16); - p[3] = (uint8_t)(w >> 24); - p[4] = (uint8_t)(w >> 32); - p[5] = (uint8_t)(w >> 40); - p[6] = (uint8_t)(w >> 48); - p[7] = (uint8_t)(w >> 56); -#endif -} - -static BLAKE2_INLINE uint64_t load48( const void *src ) -{ - const uint8_t *p = ( const uint8_t * )src; - return (( uint64_t )( p[0] ) << 0) | - (( uint64_t )( p[1] ) << 8) | - (( uint64_t )( p[2] ) << 16) | - (( uint64_t )( p[3] ) << 24) | - (( uint64_t )( p[4] ) << 32) | - (( uint64_t )( p[5] ) << 40) ; -} - -static BLAKE2_INLINE void store48( void *dst, uint64_t w ) -{ - uint8_t *p = ( uint8_t * )dst; - p[0] = (uint8_t)(w >> 0); - p[1] = (uint8_t)(w >> 8); - p[2] = (uint8_t)(w >> 16); - p[3] = (uint8_t)(w >> 24); - p[4] = (uint8_t)(w >> 32); - p[5] = (uint8_t)(w >> 40); -} - -static BLAKE2_INLINE uint32_t rotr32( const uint32_t w, const unsigned c ) -{ - return ( w >> c ) | ( w << ( 32 - c ) ); -} - -static BLAKE2_INLINE uint64_t rotr64( const uint64_t w, const unsigned c ) -{ - return ( w >> c ) | ( w << ( 64 - c ) ); -} - -/* prevents compiler optimizing out memset() */ -static BLAKE2_INLINE void secure_zero_memory(void *v, size_t n) -{ - static void *(__LA_LIBC_CC *const volatile memset_v)(void *, int, size_t) = &memset; - memset_v(v, 0, n); -} - -#endif diff --git a/thirdparty/libarchive/libarchive/archive_blake2s_ref.c b/thirdparty/libarchive/libarchive/archive_blake2s_ref.c deleted file mode 100644 index 93d328118..000000000 --- a/thirdparty/libarchive/libarchive/archive_blake2s_ref.c +++ /dev/null @@ -1,369 +0,0 @@ -/* - BLAKE2 reference source code package - reference C implementations - - Copyright 2012, Samuel Neves . You may use this under the - terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at - your option. The terms of these licenses can be found at: - - - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - - OpenSSL license : https://www.openssl.org/source/license.html - - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 - - More information about the BLAKE2 hash function can be found at - https://blake2.net. -*/ - -#include "archive_platform.h" - -#include -#include -#include - -#include "archive_blake2.h" -#include "archive_blake2_impl.h" - -static const uint32_t blake2s_IV[8] = -{ - 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, - 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL -}; - -static const uint8_t blake2s_sigma[10][16] = -{ - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , - { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , - { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , - { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , - { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , - { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , - { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , - { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , - { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , - { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , -}; - -static void blake2s_set_lastnode( blake2s_state *S ) -{ - S->f[1] = (uint32_t)-1; -} - -/* Some helper functions, not necessarily useful */ -static int blake2s_is_lastblock( const blake2s_state *S ) -{ - return S->f[0] != 0; -} - -static void blake2s_set_lastblock( blake2s_state *S ) -{ - if( S->last_node ) blake2s_set_lastnode( S ); - - S->f[0] = (uint32_t)-1; -} - -static void blake2s_increment_counter( blake2s_state *S, const uint32_t inc ) -{ - S->t[0] += inc; - S->t[1] += ( S->t[0] < inc ); -} - -static void blake2s_init0( blake2s_state *S ) -{ - size_t i; - memset( S, 0, sizeof( blake2s_state ) ); - - for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i]; -} - -/* init2 xors IV with input parameter block */ -int blake2s_init_param( blake2s_state *S, const blake2s_param *P ) -{ - const unsigned char *p = ( const unsigned char * )( P ); - size_t i; - - blake2s_init0( S ); - - /* IV XOR ParamBlock */ - for( i = 0; i < 8; ++i ) - S->h[i] ^= load32( &p[i * 4] ); - - S->outlen = P->digest_length; - return 0; -} - - -/* Sequential blake2s initialization */ -int blake2s_init( blake2s_state *S, size_t outlen ) -{ - blake2s_param P[1]; - - /* Move interval verification here? */ - if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; - - P->digest_length = (uint8_t)outlen; - P->key_length = 0; - P->fanout = 1; - P->depth = 1; - store32( &P->leaf_length, 0 ); - store32( &P->node_offset, 0 ); - store16( &P->xof_length, 0 ); - P->node_depth = 0; - P->inner_length = 0; - /* memset(P->reserved, 0, sizeof(P->reserved) ); */ - memset( P->salt, 0, sizeof( P->salt ) ); - memset( P->personal, 0, sizeof( P->personal ) ); - return blake2s_init_param( S, P ); -} - -int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ) -{ - blake2s_param P[1]; - - if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; - - if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1; - - P->digest_length = (uint8_t)outlen; - P->key_length = (uint8_t)keylen; - P->fanout = 1; - P->depth = 1; - store32( &P->leaf_length, 0 ); - store32( &P->node_offset, 0 ); - store16( &P->xof_length, 0 ); - P->node_depth = 0; - P->inner_length = 0; - /* memset(P->reserved, 0, sizeof(P->reserved) ); */ - memset( P->salt, 0, sizeof( P->salt ) ); - memset( P->personal, 0, sizeof( P->personal ) ); - - if( blake2s_init_param( S, P ) < 0 ) return -1; - - { - uint8_t block[BLAKE2S_BLOCKBYTES]; - memset( block, 0, BLAKE2S_BLOCKBYTES ); - memcpy( block, key, keylen ); - blake2s_update( S, block, BLAKE2S_BLOCKBYTES ); - secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ - } - return 0; -} - -#define G(r,i,a,b,c,d) \ - do { \ - a = a + b + m[blake2s_sigma[r][2*i+0]]; \ - d = rotr32(d ^ a, 16); \ - c = c + d; \ - b = rotr32(b ^ c, 12); \ - a = a + b + m[blake2s_sigma[r][2*i+1]]; \ - d = rotr32(d ^ a, 8); \ - c = c + d; \ - b = rotr32(b ^ c, 7); \ - } while(0) - -#define ROUND(r) \ - do { \ - G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ - G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ - G(r,2,v[ 2],v[ 6],v[10],v[14]); \ - G(r,3,v[ 3],v[ 7],v[11],v[15]); \ - G(r,4,v[ 0],v[ 5],v[10],v[15]); \ - G(r,5,v[ 1],v[ 6],v[11],v[12]); \ - G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ - G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ - } while(0) - -static void blake2s_compress( blake2s_state *S, const uint8_t in[BLAKE2S_BLOCKBYTES] ) -{ - uint32_t m[16]; - uint32_t v[16]; - size_t i; - - for( i = 0; i < 16; ++i ) { - m[i] = load32( in + i * sizeof( m[i] ) ); - } - - for( i = 0; i < 8; ++i ) { - v[i] = S->h[i]; - } - - v[ 8] = blake2s_IV[0]; - v[ 9] = blake2s_IV[1]; - v[10] = blake2s_IV[2]; - v[11] = blake2s_IV[3]; - v[12] = S->t[0] ^ blake2s_IV[4]; - v[13] = S->t[1] ^ blake2s_IV[5]; - v[14] = S->f[0] ^ blake2s_IV[6]; - v[15] = S->f[1] ^ blake2s_IV[7]; - - ROUND( 0 ); - ROUND( 1 ); - ROUND( 2 ); - ROUND( 3 ); - ROUND( 4 ); - ROUND( 5 ); - ROUND( 6 ); - ROUND( 7 ); - ROUND( 8 ); - ROUND( 9 ); - - for( i = 0; i < 8; ++i ) { - S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; - } -} - -#undef G -#undef ROUND - -int blake2s_update( blake2s_state *S, const void *pin, size_t inlen ) -{ - const unsigned char * in = (const unsigned char *)pin; - if( inlen > 0 ) - { - size_t left = S->buflen; - size_t fill = BLAKE2S_BLOCKBYTES - left; - if( inlen > fill ) - { - S->buflen = 0; - memcpy( S->buf + left, in, fill ); /* Fill buffer */ - blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); - blake2s_compress( S, S->buf ); /* Compress */ - in += fill; inlen -= fill; - while(inlen > BLAKE2S_BLOCKBYTES) { - blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES); - blake2s_compress( S, in ); - in += BLAKE2S_BLOCKBYTES; - inlen -= BLAKE2S_BLOCKBYTES; - } - } - memcpy( S->buf + S->buflen, in, inlen ); - S->buflen += inlen; - } - return 0; -} - -int blake2s_final( blake2s_state *S, void *out, size_t outlen ) -{ - uint8_t buffer[BLAKE2S_OUTBYTES] = {0}; - size_t i; - - if( out == NULL || outlen < S->outlen ) - return -1; - - if( blake2s_is_lastblock( S ) ) - return -1; - - blake2s_increment_counter( S, ( uint32_t )S->buflen ); - blake2s_set_lastblock( S ); - memset( S->buf + S->buflen, 0, BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */ - blake2s_compress( S, S->buf ); - - for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ - store32( buffer + sizeof( S->h[i] ) * i, S->h[i] ); - - memcpy( out, buffer, outlen ); - secure_zero_memory(buffer, sizeof(buffer)); - return 0; -} - -int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) -{ - blake2s_state S[1]; - - /* Verify parameters */ - if ( NULL == in && inlen > 0 ) return -1; - - if ( NULL == out ) return -1; - - if ( NULL == key && keylen > 0) return -1; - - if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; - - if( keylen > BLAKE2S_KEYBYTES ) return -1; - - if( keylen > 0 ) - { - if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1; - } - else - { - if( blake2s_init( S, outlen ) < 0 ) return -1; - } - - blake2s_update( S, ( const uint8_t * )in, inlen ); - blake2s_final( S, out, outlen ); - return 0; -} - -#if defined(SUPERCOP) -int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) -{ - return blake2s( out, BLAKE2S_OUTBYTES, in, inlen, NULL, 0 ); -} -#endif - -#if defined(BLAKE2S_SELFTEST) -#include -#include "blake2-kat.h" -int main( void ) -{ - uint8_t key[BLAKE2S_KEYBYTES]; - uint8_t buf[BLAKE2_KAT_LENGTH]; - size_t i, step; - - for( i = 0; i < BLAKE2S_KEYBYTES; ++i ) - key[i] = ( uint8_t )i; - - for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) - buf[i] = ( uint8_t )i; - - /* Test simple API */ - for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) - { - uint8_t hash[BLAKE2S_OUTBYTES]; - blake2s( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES ); - - if( 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) ) - { - goto fail; - } - } - - /* Test streaming API */ - for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) { - for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) { - uint8_t hash[BLAKE2S_OUTBYTES]; - blake2s_state S; - uint8_t * p = buf; - size_t mlen = i; - int err = 0; - - if( (err = blake2s_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) { - goto fail; - } - - while (mlen >= step) { - if ( (err = blake2s_update(&S, p, step)) < 0 ) { - goto fail; - } - mlen -= step; - p += step; - } - if ( (err = blake2s_update(&S, p, mlen)) < 0) { - goto fail; - } - if ( (err = blake2s_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) { - goto fail; - } - - if (0 != memcmp(hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES)) { - goto fail; - } - } - } - - puts( "ok" ); - return 0; -fail: - puts("error"); - return -1; -} -#endif diff --git a/thirdparty/libarchive/libarchive/archive_blake2sp_ref.c b/thirdparty/libarchive/libarchive/archive_blake2sp_ref.c deleted file mode 100644 index b913a4db6..000000000 --- a/thirdparty/libarchive/libarchive/archive_blake2sp_ref.c +++ /dev/null @@ -1,361 +0,0 @@ -/* - BLAKE2 reference source code package - reference C implementations - - Copyright 2012, Samuel Neves . You may use this under the - terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at - your option. The terms of these licenses can be found at: - - - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - - OpenSSL license : https://www.openssl.org/source/license.html - - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 - - More information about the BLAKE2 hash function can be found at - https://blake2.net. -*/ - -#include "archive_platform.h" - -#include -#include -#include - -#if defined(_OPENMP) -#include -#endif - -#include "archive_blake2.h" -#include "archive_blake2_impl.h" - -#define PARALLELISM_DEGREE 8 - -/* - blake2sp_init_param defaults to setting the expecting output length - from the digest_length parameter block field. - - In some cases, however, we do not want this, as the output length - of these instances is given by inner_length instead. -*/ -static int blake2sp_init_leaf_param( blake2s_state *S, const blake2s_param *P ) -{ - int err = blake2s_init_param(S, P); - S->outlen = P->inner_length; - return err; -} - -static int blake2sp_init_leaf( blake2s_state *S, size_t outlen, size_t keylen, uint32_t offset ) -{ - blake2s_param P[1]; - P->digest_length = (uint8_t)outlen; - P->key_length = (uint8_t)keylen; - P->fanout = PARALLELISM_DEGREE; - P->depth = 2; - store32( &P->leaf_length, 0 ); - store32( &P->node_offset, offset ); - store16( &P->xof_length, 0 ); - P->node_depth = 0; - P->inner_length = BLAKE2S_OUTBYTES; - memset( P->salt, 0, sizeof( P->salt ) ); - memset( P->personal, 0, sizeof( P->personal ) ); - return blake2sp_init_leaf_param( S, P ); -} - -static int blake2sp_init_root( blake2s_state *S, size_t outlen, size_t keylen ) -{ - blake2s_param P[1]; - P->digest_length = (uint8_t)outlen; - P->key_length = (uint8_t)keylen; - P->fanout = PARALLELISM_DEGREE; - P->depth = 2; - store32( &P->leaf_length, 0 ); - store32( &P->node_offset, 0 ); - store16( &P->xof_length, 0 ); - P->node_depth = 1; - P->inner_length = BLAKE2S_OUTBYTES; - memset( P->salt, 0, sizeof( P->salt ) ); - memset( P->personal, 0, sizeof( P->personal ) ); - return blake2s_init_param( S, P ); -} - - -int blake2sp_init( blake2sp_state *S, size_t outlen ) -{ - size_t i; - - if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; - - memset( S->buf, 0, sizeof( S->buf ) ); - S->buflen = 0; - S->outlen = outlen; - - if( blake2sp_init_root( S->R, outlen, 0 ) < 0 ) - return -1; - - for( i = 0; i < PARALLELISM_DEGREE; ++i ) - if( blake2sp_init_leaf( S->S[i], outlen, 0, (uint32_t)i ) < 0 ) return -1; - - S->R->last_node = 1; - S->S[PARALLELISM_DEGREE - 1]->last_node = 1; - return 0; -} - -int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen ) -{ - size_t i; - - if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; - - if( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1; - - memset( S->buf, 0, sizeof( S->buf ) ); - S->buflen = 0; - S->outlen = outlen; - - if( blake2sp_init_root( S->R, outlen, keylen ) < 0 ) - return -1; - - for( i = 0; i < PARALLELISM_DEGREE; ++i ) - if( blake2sp_init_leaf( S->S[i], outlen, keylen, (uint32_t)i ) < 0 ) return -1; - - S->R->last_node = 1; - S->S[PARALLELISM_DEGREE - 1]->last_node = 1; - { - uint8_t block[BLAKE2S_BLOCKBYTES]; - memset( block, 0, BLAKE2S_BLOCKBYTES ); - memcpy( block, key, keylen ); - - for( i = 0; i < PARALLELISM_DEGREE; ++i ) - blake2s_update( S->S[i], block, BLAKE2S_BLOCKBYTES ); - - secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ - } - return 0; -} - - -int blake2sp_update( blake2sp_state *S, const void *pin, size_t inlen ) -{ - const unsigned char * in = (const unsigned char *)pin; - size_t left = S->buflen; - size_t fill = sizeof( S->buf ) - left; - size_t i; - - if( left && inlen >= fill ) - { - memcpy( S->buf + left, in, fill ); - - for( i = 0; i < PARALLELISM_DEGREE; ++i ) - blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); - - in += fill; - inlen -= fill; - left = 0; - } - -#if defined(_OPENMP) - #pragma omp parallel shared(S), num_threads(PARALLELISM_DEGREE) -#else - for( i = 0; i < PARALLELISM_DEGREE; ++i ) -#endif - { -#if defined(_OPENMP) - size_t i = omp_get_thread_num(); -#endif - size_t inlen__ = inlen; - const unsigned char *in__ = ( const unsigned char * )in; - in__ += i * BLAKE2S_BLOCKBYTES; - - while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ) - { - blake2s_update( S->S[i], in__, BLAKE2S_BLOCKBYTES ); - in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; - inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; - } - } - - in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ); - inlen %= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; - - if( inlen > 0 ) - memcpy( S->buf + left, in, inlen ); - - S->buflen = left + inlen; - return 0; -} - - -int blake2sp_final( blake2sp_state *S, void *out, size_t outlen ) -{ - uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES]; - size_t i; - - if(out == NULL || outlen < S->outlen) { - return -1; - } - - for( i = 0; i < PARALLELISM_DEGREE; ++i ) - { - if( S->buflen > i * BLAKE2S_BLOCKBYTES ) - { - size_t left = S->buflen - i * BLAKE2S_BLOCKBYTES; - - if( left > BLAKE2S_BLOCKBYTES ) left = BLAKE2S_BLOCKBYTES; - - blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, left ); - } - - blake2s_final( S->S[i], hash[i], BLAKE2S_OUTBYTES ); - } - - for( i = 0; i < PARALLELISM_DEGREE; ++i ) - blake2s_update( S->R, hash[i], BLAKE2S_OUTBYTES ); - - return blake2s_final( S->R, out, S->outlen ); -} - - -int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) -{ - uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES]; - blake2s_state S[PARALLELISM_DEGREE][1]; - blake2s_state FS[1]; - size_t i; - - /* Verify parameters */ - if ( NULL == in && inlen > 0 ) return -1; - - if ( NULL == out ) return -1; - - if ( NULL == key && keylen > 0) return -1; - - if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; - - if( keylen > BLAKE2S_KEYBYTES ) return -1; - - for( i = 0; i < PARALLELISM_DEGREE; ++i ) - if( blake2sp_init_leaf( S[i], outlen, keylen, (uint32_t)i ) < 0 ) return -1; - - S[PARALLELISM_DEGREE - 1]->last_node = 1; /* mark last node */ - - if( keylen > 0 ) - { - uint8_t block[BLAKE2S_BLOCKBYTES]; - memset( block, 0, BLAKE2S_BLOCKBYTES ); - memcpy( block, key, keylen ); - - for( i = 0; i < PARALLELISM_DEGREE; ++i ) - blake2s_update( S[i], block, BLAKE2S_BLOCKBYTES ); - - secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ - } - -#if defined(_OPENMP) - #pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE) -#else - - for( i = 0; i < PARALLELISM_DEGREE; ++i ) -#endif - { -#if defined(_OPENMP) - size_t i = omp_get_thread_num(); -#endif - size_t inlen__ = inlen; - const unsigned char *in__ = ( const unsigned char * )in; - in__ += i * BLAKE2S_BLOCKBYTES; - - while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ) - { - blake2s_update( S[i], in__, BLAKE2S_BLOCKBYTES ); - in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; - inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; - } - - if( inlen__ > i * BLAKE2S_BLOCKBYTES ) - { - const size_t left = inlen__ - i * BLAKE2S_BLOCKBYTES; - const size_t len = left <= BLAKE2S_BLOCKBYTES ? left : BLAKE2S_BLOCKBYTES; - blake2s_update( S[i], in__, len ); - } - - blake2s_final( S[i], hash[i], BLAKE2S_OUTBYTES ); - } - - if( blake2sp_init_root( FS, outlen, keylen ) < 0 ) - return -1; - - FS->last_node = 1; - - for( i = 0; i < PARALLELISM_DEGREE; ++i ) - blake2s_update( FS, hash[i], BLAKE2S_OUTBYTES ); - - return blake2s_final( FS, out, outlen ); -} - - - -#if defined(BLAKE2SP_SELFTEST) -#include -#include "blake2-kat.h" -int main( void ) -{ - uint8_t key[BLAKE2S_KEYBYTES]; - uint8_t buf[BLAKE2_KAT_LENGTH]; - size_t i, step; - - for( i = 0; i < BLAKE2S_KEYBYTES; ++i ) - key[i] = ( uint8_t )i; - - for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) - buf[i] = ( uint8_t )i; - - /* Test simple API */ - for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) - { - uint8_t hash[BLAKE2S_OUTBYTES]; - blake2sp( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES ); - - if( 0 != memcmp( hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES ) ) - { - goto fail; - } - } - - /* Test streaming API */ - for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) { - for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) { - uint8_t hash[BLAKE2S_OUTBYTES]; - blake2sp_state S; - uint8_t * p = buf; - size_t mlen = i; - int err = 0; - - if( (err = blake2sp_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) { - goto fail; - } - - while (mlen >= step) { - if ( (err = blake2sp_update(&S, p, step)) < 0 ) { - goto fail; - } - mlen -= step; - p += step; - } - if ( (err = blake2sp_update(&S, p, mlen)) < 0) { - goto fail; - } - if ( (err = blake2sp_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) { - goto fail; - } - - if (0 != memcmp(hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES)) { - goto fail; - } - } - } - - puts( "ok" ); - return 0; -fail: - puts("error"); - return -1; -} -#endif diff --git a/thirdparty/libarchive/libarchive/archive_check_magic.c b/thirdparty/libarchive/libarchive/archive_check_magic.c deleted file mode 100644 index 1f40072f8..000000000 --- a/thirdparty/libarchive/libarchive/archive_check_magic.c +++ /dev/null @@ -1,175 +0,0 @@ -/*- - * Copyright (c) 2003-2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_check_magic.c 201089 2009-12-28 02:20:23Z kientzle $"); - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#if defined(_WIN32) && !defined(__CYGWIN__) -#include -#include -#endif - -#include "archive_private.h" - -static void -errmsg(const char *m) -{ - size_t s = strlen(m); - ssize_t written; - - while (s > 0) { - written = write(2, m, s); - if (written <= 0) - return; - m += written; - s -= written; - } -} - -static __LA_DEAD void -diediedie(void) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG) - /* Cause a breakpoint exception */ - DebugBreak(); -#endif - abort(); /* Terminate the program abnormally. */ -} - -static const char * -state_name(unsigned s) -{ - switch (s) { - case ARCHIVE_STATE_NEW: return ("new"); - case ARCHIVE_STATE_HEADER: return ("header"); - case ARCHIVE_STATE_DATA: return ("data"); - case ARCHIVE_STATE_EOF: return ("eof"); - case ARCHIVE_STATE_CLOSED: return ("closed"); - case ARCHIVE_STATE_FATAL: return ("fatal"); - default: return ("??"); - } -} - -static const char * -archive_handle_type_name(unsigned m) -{ - switch (m) { - case ARCHIVE_WRITE_MAGIC: return ("archive_write"); - case ARCHIVE_READ_MAGIC: return ("archive_read"); - case ARCHIVE_WRITE_DISK_MAGIC: return ("archive_write_disk"); - case ARCHIVE_READ_DISK_MAGIC: return ("archive_read_disk"); - case ARCHIVE_MATCH_MAGIC: return ("archive_match"); - default: return NULL; - } -} - - -static char * -write_all_states(char *buff, unsigned int states) -{ - unsigned int lowbit; - - buff[0] = '\0'; - - /* A trick for computing the lowest set bit. */ - while ((lowbit = states & (1 + ~states)) != 0) { - states &= ~lowbit; /* Clear the low bit. */ - strcat(buff, state_name(lowbit)); - if (states != 0) - strcat(buff, "/"); - } - return buff; -} - -/* - * Check magic value and current state. - * Magic value mismatches are fatal and result in calls to abort(). - * State mismatches return ARCHIVE_FATAL. - * Otherwise, returns ARCHIVE_OK. - * - * This is designed to catch serious programming errors that violate - * the libarchive API. - */ -int -__archive_check_magic(struct archive *a, unsigned int magic, - unsigned int state, const char *function) -{ - char states1[64]; - char states2[64]; - const char *handle_type; - - /* - * If this isn't some form of archive handle, - * then the library user has screwed up so bad that - * we don't even have a reliable way to report an error. - */ - handle_type = archive_handle_type_name(a->magic); - - if (!handle_type) { - errmsg("PROGRAMMER ERROR: Function "); - errmsg(function); - errmsg(" invoked with invalid archive handle.\n"); - diediedie(); - } - - if (a->magic != magic) { - archive_set_error(a, -1, - "PROGRAMMER ERROR: Function '%s' invoked" - " on '%s' archive object, which is not supported.", - function, - handle_type); - a->state = ARCHIVE_STATE_FATAL; - return (ARCHIVE_FATAL); - } - - if ((a->state & state) == 0) { - /* If we're already FATAL, don't overwrite the error. */ - if (a->state != ARCHIVE_STATE_FATAL) - archive_set_error(a, -1, - "INTERNAL ERROR: Function '%s' invoked with" - " archive structure in state '%s'," - " should be in state '%s'", - function, - write_all_states(states1, a->state), - write_all_states(states2, state)); - a->state = ARCHIVE_STATE_FATAL; - return (ARCHIVE_FATAL); - } - return ARCHIVE_OK; -} diff --git a/thirdparty/libarchive/libarchive/archive_cmdline.c b/thirdparty/libarchive/libarchive/archive_cmdline.c deleted file mode 100644 index 5c519cd17..000000000 --- a/thirdparty/libarchive/libarchive/archive_cmdline.c +++ /dev/null @@ -1,227 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_STRING_H -# include -#endif -#ifdef HAVE_STDLIB_H -# include -#endif - -#include "archive.h" -#include "archive_cmdline_private.h" -#include "archive_string.h" - -static int cmdline_set_path(struct archive_cmdline *, const char *); -static int cmdline_add_arg(struct archive_cmdline *, const char *); - -static ssize_t -extract_quotation(struct archive_string *as, const char *p) -{ - const char *s; - - for (s = p + 1; *s;) { - if (*s == '\\') { - if (s[1] != '\0') { - archive_strappend_char(as, s[1]); - s += 2; - } else - s++; - } else if (*s == '"') - break; - else { - archive_strappend_char(as, s[0]); - s++; - } - } - if (*s != '"') - return (ARCHIVE_FAILED);/* Invalid sequence. */ - return ((ssize_t)(s + 1 - p)); -} - -static ssize_t -get_argument(struct archive_string *as, const char *p) -{ - const char *s = p; - - archive_string_empty(as); - - /* Skip beginning space characters. */ - while (*s != '\0' && *s == ' ') - s++; - /* Copy non-space characters. */ - while (*s != '\0' && *s != ' ') { - if (*s == '\\') { - if (s[1] != '\0') { - archive_strappend_char(as, s[1]); - s += 2; - } else { - s++;/* Ignore this character.*/ - break; - } - } else if (*s == '"') { - ssize_t q = extract_quotation(as, s); - if (q < 0) - return (ARCHIVE_FAILED);/* Invalid sequence. */ - s += q; - } else { - archive_strappend_char(as, s[0]); - s++; - } - } - return ((ssize_t)(s - p)); -} - -/* - * Set up command line arguments. - * Returns ARCHIVE_OK if everything okey. - * Returns ARCHIVE_FAILED if there is a lack of the `"' terminator or an - * empty command line. - * Returns ARCHIVE_FATAL if no memory. - */ -int -__archive_cmdline_parse(struct archive_cmdline *data, const char *cmd) -{ - struct archive_string as; - const char *p; - ssize_t al; - int r; - - archive_string_init(&as); - - /* Get first argument as a command path. */ - al = get_argument(&as, cmd); - if (al < 0) { - r = ARCHIVE_FAILED;/* Invalid sequence. */ - goto exit_function; - } - if (archive_strlen(&as) == 0) { - r = ARCHIVE_FAILED;/* An empty command path. */ - goto exit_function; - } - r = cmdline_set_path(data, as.s); - if (r != ARCHIVE_OK) - goto exit_function; - p = strrchr(as.s, '/'); - if (p == NULL) - p = as.s; - else - p++; - r = cmdline_add_arg(data, p); - if (r != ARCHIVE_OK) - goto exit_function; - cmd += al; - - for (;;) { - al = get_argument(&as, cmd); - if (al < 0) { - r = ARCHIVE_FAILED;/* Invalid sequence. */ - goto exit_function; - } - if (al == 0) - break; - cmd += al; - if (archive_strlen(&as) == 0 && *cmd == '\0') - break; - r = cmdline_add_arg(data, as.s); - if (r != ARCHIVE_OK) - goto exit_function; - } - r = ARCHIVE_OK; -exit_function: - archive_string_free(&as); - return (r); -} - -/* - * Set the program path. - */ -static int -cmdline_set_path(struct archive_cmdline *data, const char *path) -{ - char *newptr; - - newptr = realloc(data->path, strlen(path) + 1); - if (newptr == NULL) - return (ARCHIVE_FATAL); - data->path = newptr; - strcpy(data->path, path); - return (ARCHIVE_OK); -} - -/* - * Add a argument for the program. - */ -static int -cmdline_add_arg(struct archive_cmdline *data, const char *arg) -{ - char **newargv; - - if (data->path == NULL) - return (ARCHIVE_FAILED); - - newargv = realloc(data->argv, (data->argc + 2) * sizeof(char *)); - if (newargv == NULL) - return (ARCHIVE_FATAL); - data->argv = newargv; - data->argv[data->argc] = strdup(arg); - if (data->argv[data->argc] == NULL) - return (ARCHIVE_FATAL); - /* Set the terminator of argv. */ - data->argv[++data->argc] = NULL; - return (ARCHIVE_OK); -} - -struct archive_cmdline * -__archive_cmdline_allocate(void) -{ - return (struct archive_cmdline *) - calloc(1, sizeof(struct archive_cmdline)); -} - -/* - * Release the resources. - */ -int -__archive_cmdline_free(struct archive_cmdline *data) -{ - - if (data) { - free(data->path); - if (data->argv != NULL) { - int i; - for (i = 0; data->argv[i] != NULL; i++) - free(data->argv[i]); - free(data->argv); - } - free(data); - } - return (ARCHIVE_OK); -} - diff --git a/thirdparty/libarchive/libarchive/archive_cmdline_private.h b/thirdparty/libarchive/libarchive/archive_cmdline_private.h deleted file mode 100644 index 57a19494f..000000000 --- a/thirdparty/libarchive/libarchive/archive_cmdline_private.h +++ /dev/null @@ -1,47 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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$ - */ - -#ifndef ARCHIVE_CMDLINE_PRIVATE_H -#define ARCHIVE_CMDLINE_PRIVATE_H - -#ifndef __LIBARCHIVE_BUILD -#ifndef __LIBARCHIVE_TEST -#error This header is only to be used internally to libarchive. -#endif -#endif - -struct archive_cmdline { - char *path; - char **argv; - int argc; -}; - -struct archive_cmdline *__archive_cmdline_allocate(void); -int __archive_cmdline_parse(struct archive_cmdline *, const char *); -int __archive_cmdline_free(struct archive_cmdline *); - -#endif diff --git a/thirdparty/libarchive/libarchive/archive_crc32.h b/thirdparty/libarchive/libarchive/archive_crc32.h deleted file mode 100644 index 4f1aed305..000000000 --- a/thirdparty/libarchive/libarchive/archive_crc32.h +++ /dev/null @@ -1,83 +0,0 @@ -/*- - * Copyright (c) 2009 Joerg Sonnenberger - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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: head/lib/libarchive/archive_crc32.h 201102 2009-12-28 03:11:36Z kientzle $ - */ - -#ifndef ARCHIVE_CRC32_H -#define ARCHIVE_CRC32_H - -#ifndef __LIBARCHIVE_BUILD -#error This header is only to be used internally to libarchive. -#endif - -/* - * When zlib is unavailable, we should still be able to validate - * uncompressed zip archives. That requires us to be able to compute - * the CRC32 check value. This is a drop-in compatible replacement - * for crc32() from zlib. It's slower than the zlib implementation, - * but still pretty fast: This runs about 300MB/s on my 3GHz P4 - * compared to about 800MB/s for the zlib implementation. - */ -static unsigned long -crc32(unsigned long crc, const void *_p, size_t len) -{ - unsigned long crc2, b, i; - const unsigned char *p = _p; - static volatile int crc_tbl_inited = 0; - static unsigned long crc_tbl[256]; - - if (!crc_tbl_inited) { - for (b = 0; b < 256; ++b) { - crc2 = b; - for (i = 8; i > 0; --i) { - if (crc2 & 1) - crc2 = (crc2 >> 1) ^ 0xedb88320UL; - else - crc2 = (crc2 >> 1); - } - crc_tbl[b] = crc2; - } - crc_tbl_inited = 1; - } - - crc = crc ^ 0xffffffffUL; - /* A use of this loop is about 20% - 30% faster than - * no use version in any optimization option of gcc. */ - for (;len >= 8; len -= 8) { - crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8); - crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8); - crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8); - crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8); - crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8); - crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8); - crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8); - crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8); - } - while (len--) - crc = crc_tbl[(crc ^ *p++) & 0xff] ^ (crc >> 8); - return (crc ^ 0xffffffffUL); -} - -#endif diff --git a/thirdparty/libarchive/libarchive/archive_cryptor.c b/thirdparty/libarchive/libarchive/archive_cryptor.c deleted file mode 100644 index 112baf161..000000000 --- a/thirdparty/libarchive/libarchive/archive_cryptor.c +++ /dev/null @@ -1,534 +0,0 @@ -/*- -* Copyright (c) 2014 Michihiro NAKAJIMA -* 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. -* 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. -* -* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. -*/ - -#include "archive_platform.h" - -#ifdef HAVE_STRING_H -#include -#endif -#include "archive.h" -#include "archive_cryptor_private.h" - -/* - * On systems that do not support any recognized crypto libraries, - * this file will normally define no usable symbols. - * - * But some compilers and linkers choke on empty object files, so - * define a public symbol that will always exist. This could - * be removed someday if this file gains another always-present - * symbol definition. - */ -int __libarchive_cryptor_build_hack(void) { - return 0; -} - -#ifdef ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto - -static int -pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt, - size_t salt_len, unsigned rounds, uint8_t *derived_key, - size_t derived_key_len) -{ - CCKeyDerivationPBKDF(kCCPBKDF2, (const char *)pw, - pw_len, salt, salt_len, kCCPRFHmacAlgSHA1, rounds, - derived_key, derived_key_len); - return 0; -} - -#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) -#ifdef _MSC_VER -#pragma comment(lib, "Bcrypt.lib") -#endif - -static int -pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt, - size_t salt_len, unsigned rounds, uint8_t *derived_key, - size_t derived_key_len) -{ - NTSTATUS status; - BCRYPT_ALG_HANDLE hAlg; - - status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA1_ALGORITHM, - MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG); - if (!BCRYPT_SUCCESS(status)) - return -1; - - status = BCryptDeriveKeyPBKDF2(hAlg, - (PUCHAR)(uintptr_t)pw, (ULONG)pw_len, - (PUCHAR)(uintptr_t)salt, (ULONG)salt_len, rounds, - (PUCHAR)derived_key, (ULONG)derived_key_len, 0); - - BCryptCloseAlgorithmProvider(hAlg, 0); - - return (BCRYPT_SUCCESS(status)) ? 0: -1; -} - -#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_PKCS5_H) - -static int -pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt, - size_t salt_len, unsigned rounds, uint8_t *derived_key, - size_t derived_key_len) -{ - mbedtls_md_context_t ctx; - const mbedtls_md_info_t *info; - int ret; - - mbedtls_md_init(&ctx); - info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); - if (info == NULL) { - mbedtls_md_free(&ctx); - return (-1); - } - ret = mbedtls_md_setup(&ctx, info, 1); - if (ret != 0) { - mbedtls_md_free(&ctx); - return (-1); - } - ret = mbedtls_pkcs5_pbkdf2_hmac(&ctx, (const unsigned char *)pw, - pw_len, salt, salt_len, rounds, derived_key_len, derived_key); - - mbedtls_md_free(&ctx); - return (ret); -} - -#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_PBKDF2_H) - -static int -pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt, - size_t salt_len, unsigned rounds, uint8_t *derived_key, - size_t derived_key_len) { - pbkdf2_hmac_sha1((unsigned)pw_len, (const uint8_t *)pw, rounds, - salt_len, salt, derived_key_len, derived_key); - return 0; -} - -#elif defined(HAVE_LIBCRYPTO) && defined(HAVE_PKCS5_PBKDF2_HMAC_SHA1) - -static int -pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt, - size_t salt_len, unsigned rounds, uint8_t *derived_key, - size_t derived_key_len) { - - PKCS5_PBKDF2_HMAC_SHA1(pw, pw_len, salt, salt_len, rounds, - derived_key_len, derived_key); - return 0; -} - -#else - -/* Stub */ -static int -pbkdf2_sha1(const char *pw, size_t pw_len, const uint8_t *salt, - size_t salt_len, unsigned rounds, uint8_t *derived_key, - size_t derived_key_len) { - (void)pw; /* UNUSED */ - (void)pw_len; /* UNUSED */ - (void)salt; /* UNUSED */ - (void)salt_len; /* UNUSED */ - (void)rounds; /* UNUSED */ - (void)derived_key; /* UNUSED */ - (void)derived_key_len; /* UNUSED */ - return -1; /* UNSUPPORTED */ -} - -#endif - -#ifdef ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto -# if MAC_OS_X_VERSION_MAX_ALLOWED < 1090 -# define kCCAlgorithmAES kCCAlgorithmAES128 -# endif - -static int -aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len) -{ - CCCryptorStatus r; - - ctx->key_len = key_len; - memcpy(ctx->key, key, key_len); - memset(ctx->nonce, 0, sizeof(ctx->nonce)); - ctx->encr_pos = AES_BLOCK_SIZE; - r = CCCryptorCreateWithMode(kCCEncrypt, kCCModeECB, kCCAlgorithmAES, - ccNoPadding, NULL, key, key_len, NULL, 0, 0, 0, &ctx->ctx); - return (r == kCCSuccess)? 0: -1; -} - -static int -aes_ctr_encrypt_counter(archive_crypto_ctx *ctx) -{ - CCCryptorRef ref = ctx->ctx; - CCCryptorStatus r; - - r = CCCryptorReset(ref, NULL); - if (r != kCCSuccess && r != kCCUnimplemented) - return -1; - r = CCCryptorUpdate(ref, ctx->nonce, AES_BLOCK_SIZE, ctx->encr_buf, - AES_BLOCK_SIZE, NULL); - return (r == kCCSuccess)? 0: -1; -} - -static int -aes_ctr_release(archive_crypto_ctx *ctx) -{ - memset(ctx->key, 0, ctx->key_len); - memset(ctx->nonce, 0, sizeof(ctx->nonce)); - return 0; -} - -#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) - -static int -aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len) -{ - BCRYPT_ALG_HANDLE hAlg; - BCRYPT_KEY_HANDLE hKey; - DWORD keyObj_len, aes_key_len; - PBYTE keyObj; - ULONG result; - NTSTATUS status; - BCRYPT_KEY_LENGTHS_STRUCT key_lengths; - - ctx->hAlg = NULL; - ctx->hKey = NULL; - ctx->keyObj = NULL; - switch (key_len) { - case 16: aes_key_len = 128; break; - case 24: aes_key_len = 192; break; - case 32: aes_key_len = 256; break; - default: return -1; - } - status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_AES_ALGORITHM, - MS_PRIMITIVE_PROVIDER, 0); - if (!BCRYPT_SUCCESS(status)) - return -1; - status = BCryptGetProperty(hAlg, BCRYPT_KEY_LENGTHS, (PUCHAR)&key_lengths, - sizeof(key_lengths), &result, 0); - if (!BCRYPT_SUCCESS(status)) { - BCryptCloseAlgorithmProvider(hAlg, 0); - return -1; - } - if (key_lengths.dwMinLength > aes_key_len - || key_lengths.dwMaxLength < aes_key_len) { - BCryptCloseAlgorithmProvider(hAlg, 0); - return -1; - } - status = BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH, (PUCHAR)&keyObj_len, - sizeof(keyObj_len), &result, 0); - if (!BCRYPT_SUCCESS(status)) { - BCryptCloseAlgorithmProvider(hAlg, 0); - return -1; - } - keyObj = (PBYTE)HeapAlloc(GetProcessHeap(), 0, keyObj_len); - if (keyObj == NULL) { - BCryptCloseAlgorithmProvider(hAlg, 0); - return -1; - } - status = BCryptSetProperty(hAlg, BCRYPT_CHAINING_MODE, - (PUCHAR)BCRYPT_CHAIN_MODE_ECB, sizeof(BCRYPT_CHAIN_MODE_ECB), 0); - if (!BCRYPT_SUCCESS(status)) { - BCryptCloseAlgorithmProvider(hAlg, 0); - HeapFree(GetProcessHeap(), 0, keyObj); - return -1; - } - status = BCryptGenerateSymmetricKey(hAlg, &hKey, - keyObj, keyObj_len, - (PUCHAR)(uintptr_t)key, (ULONG)key_len, 0); - if (!BCRYPT_SUCCESS(status)) { - BCryptCloseAlgorithmProvider(hAlg, 0); - HeapFree(GetProcessHeap(), 0, keyObj); - return -1; - } - - ctx->hAlg = hAlg; - ctx->hKey = hKey; - ctx->keyObj = keyObj; - ctx->keyObj_len = keyObj_len; - ctx->encr_pos = AES_BLOCK_SIZE; - - return 0; -} - -static int -aes_ctr_encrypt_counter(archive_crypto_ctx *ctx) -{ - NTSTATUS status; - ULONG result; - - status = BCryptEncrypt(ctx->hKey, (PUCHAR)ctx->nonce, AES_BLOCK_SIZE, - NULL, NULL, 0, (PUCHAR)ctx->encr_buf, AES_BLOCK_SIZE, - &result, 0); - return BCRYPT_SUCCESS(status) ? 0 : -1; -} - -static int -aes_ctr_release(archive_crypto_ctx *ctx) -{ - - if (ctx->hAlg != NULL) { - BCryptCloseAlgorithmProvider(ctx->hAlg, 0); - ctx->hAlg = NULL; - BCryptDestroyKey(ctx->hKey); - ctx->hKey = NULL; - HeapFree(GetProcessHeap(), 0, ctx->keyObj); - ctx->keyObj = NULL; - } - memset(ctx, 0, sizeof(*ctx)); - return 0; -} - -#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_AES_H) - -static int -aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len) -{ - mbedtls_aes_init(&ctx->ctx); - ctx->key_len = key_len; - memcpy(ctx->key, key, key_len); - memset(ctx->nonce, 0, sizeof(ctx->nonce)); - ctx->encr_pos = AES_BLOCK_SIZE; - return 0; -} - -static int -aes_ctr_encrypt_counter(archive_crypto_ctx *ctx) -{ - if (mbedtls_aes_setkey_enc(&ctx->ctx, ctx->key, - ctx->key_len * 8) != 0) - return (-1); - if (mbedtls_aes_crypt_ecb(&ctx->ctx, MBEDTLS_AES_ENCRYPT, ctx->nonce, - ctx->encr_buf) != 0) - return (-1); - return 0; -} - -static int -aes_ctr_release(archive_crypto_ctx *ctx) -{ - mbedtls_aes_free(&ctx->ctx); - memset(ctx, 0, sizeof(*ctx)); - return 0; -} - -#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_AES_H) - -static int -aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len) -{ - ctx->key_len = key_len; - memcpy(ctx->key, key, key_len); - memset(ctx->nonce, 0, sizeof(ctx->nonce)); - ctx->encr_pos = AES_BLOCK_SIZE; - memset(&ctx->ctx, 0, sizeof(ctx->ctx)); - return 0; -} - -static int -aes_ctr_encrypt_counter(archive_crypto_ctx *ctx) -{ -#if NETTLE_VERSION_MAJOR < 3 - aes_set_encrypt_key(&ctx->ctx, ctx->key_len, ctx->key); - aes_encrypt(&ctx->ctx, AES_BLOCK_SIZE, ctx->encr_buf, ctx->nonce); -#else - switch(ctx->key_len) { - case AES128_KEY_SIZE: - aes128_set_encrypt_key(&ctx->ctx.c128, ctx->key); - aes128_encrypt(&ctx->ctx.c128, AES_BLOCK_SIZE, ctx->encr_buf, - ctx->nonce); - break; - case AES192_KEY_SIZE: - aes192_set_encrypt_key(&ctx->ctx.c192, ctx->key); - aes192_encrypt(&ctx->ctx.c192, AES_BLOCK_SIZE, ctx->encr_buf, - ctx->nonce); - break; - case AES256_KEY_SIZE: - aes256_set_encrypt_key(&ctx->ctx.c256, ctx->key); - aes256_encrypt(&ctx->ctx.c256, AES_BLOCK_SIZE, ctx->encr_buf, - ctx->nonce); - break; - default: - return -1; - break; - } -#endif - return 0; -} - -static int -aes_ctr_release(archive_crypto_ctx *ctx) -{ - memset(ctx, 0, sizeof(*ctx)); - return 0; -} - -#elif defined(HAVE_LIBCRYPTO) - -static int -aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len) -{ - if ((ctx->ctx = EVP_CIPHER_CTX_new()) == NULL) - return -1; - - switch (key_len) { - case 16: ctx->type = EVP_aes_128_ecb(); break; - case 24: ctx->type = EVP_aes_192_ecb(); break; - case 32: ctx->type = EVP_aes_256_ecb(); break; - default: ctx->type = NULL; return -1; - } - - ctx->key_len = key_len; - memcpy(ctx->key, key, key_len); - memset(ctx->nonce, 0, sizeof(ctx->nonce)); - ctx->encr_pos = AES_BLOCK_SIZE; - return 0; -} - -static int -aes_ctr_encrypt_counter(archive_crypto_ctx *ctx) -{ - int outl = 0; - int r; - - r = EVP_EncryptInit_ex(ctx->ctx, ctx->type, NULL, ctx->key, NULL); - if (r == 0) - return -1; - r = EVP_EncryptUpdate(ctx->ctx, ctx->encr_buf, &outl, ctx->nonce, - AES_BLOCK_SIZE); - if (r == 0 || outl != AES_BLOCK_SIZE) - return -1; - return 0; -} - -static int -aes_ctr_release(archive_crypto_ctx *ctx) -{ - EVP_CIPHER_CTX_free(ctx->ctx); - memset(ctx->key, 0, ctx->key_len); - memset(ctx->nonce, 0, sizeof(ctx->nonce)); - return 0; -} - -#else - -#define ARCHIVE_CRYPTOR_STUB -/* Stub */ -static int -aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len) -{ - (void)ctx; /* UNUSED */ - (void)key; /* UNUSED */ - (void)key_len; /* UNUSED */ - return -1; -} - -static int -aes_ctr_encrypt_counter(archive_crypto_ctx *ctx) -{ - (void)ctx; /* UNUSED */ - return -1; -} - -static int -aes_ctr_release(archive_crypto_ctx *ctx) -{ - (void)ctx; /* UNUSED */ - return 0; -} - -#endif - -#ifdef ARCHIVE_CRYPTOR_STUB -static int -aes_ctr_update(archive_crypto_ctx *ctx, const uint8_t * const in, - size_t in_len, uint8_t * const out, size_t *out_len) -{ - (void)ctx; /* UNUSED */ - (void)in; /* UNUSED */ - (void)in_len; /* UNUSED */ - (void)out; /* UNUSED */ - (void)out_len; /* UNUSED */ - aes_ctr_encrypt_counter(ctx); /* UNUSED */ /* Fix unused function warning */ - return -1; -} - -#else -static void -aes_ctr_increase_counter(archive_crypto_ctx *ctx) -{ - uint8_t *const nonce = ctx->nonce; - int j; - - for (j = 0; j < 8; j++) { - if (++nonce[j]) - break; - } -} - -static int -aes_ctr_update(archive_crypto_ctx *ctx, const uint8_t * const in, - size_t in_len, uint8_t * const out, size_t *out_len) -{ - uint8_t *const ebuf = ctx->encr_buf; - unsigned pos = ctx->encr_pos; - unsigned max = (unsigned)((in_len < *out_len)? in_len: *out_len); - unsigned i; - - for (i = 0; i < max; ) { - if (pos == AES_BLOCK_SIZE) { - aes_ctr_increase_counter(ctx); - if (aes_ctr_encrypt_counter(ctx) != 0) - return -1; - while (max -i >= AES_BLOCK_SIZE) { - for (pos = 0; pos < AES_BLOCK_SIZE; pos++) - out[i+pos] = in[i+pos] ^ ebuf[pos]; - i += AES_BLOCK_SIZE; - aes_ctr_increase_counter(ctx); - if (aes_ctr_encrypt_counter(ctx) != 0) - return -1; - } - pos = 0; - if (i >= max) - break; - } - out[i] = in[i] ^ ebuf[pos++]; - i++; - } - ctx->encr_pos = pos; - *out_len = i; - - return 0; -} -#endif /* ARCHIVE_CRYPTOR_STUB */ - - -const struct archive_cryptor __archive_cryptor = -{ - &pbkdf2_sha1, - &aes_ctr_init, - &aes_ctr_update, - &aes_ctr_release, - &aes_ctr_init, - &aes_ctr_update, - &aes_ctr_release, -}; diff --git a/thirdparty/libarchive/libarchive/archive_cryptor_private.h b/thirdparty/libarchive/libarchive/archive_cryptor_private.h deleted file mode 100644 index 16b6d16ff..000000000 --- a/thirdparty/libarchive/libarchive/archive_cryptor_private.h +++ /dev/null @@ -1,188 +0,0 @@ -/*- -* Copyright (c) 2014 Michihiro NAKAJIMA -* 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. -* 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. -* -* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. -*/ - -#ifndef ARCHIVE_CRYPTOR_PRIVATE_H_INCLUDED -#define ARCHIVE_CRYPTOR_PRIVATE_H_INCLUDED - -#ifndef __LIBARCHIVE_BUILD -#error This header is only to be used internally to libarchive. -#endif -/* - * On systems that do not support any recognized crypto libraries, - * the archive_cryptor.c file will normally define no usable symbols. - * - * But some compilers and linkers choke on empty object files, so - * define a public symbol that will always exist. This could - * be removed someday if this file gains another always-present - * symbol definition. - */ -int __libarchive_cryptor_build_hack(void); - -#ifdef __APPLE__ -# include -# if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080 -# define ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto -# endif -#endif - -#ifdef ARCHIVE_CRYPTOR_USE_Apple_CommonCrypto -#include -#include -#define AES_BLOCK_SIZE 16 -#define AES_MAX_KEY_SIZE kCCKeySizeAES256 - -typedef struct { - CCCryptorRef ctx; - uint8_t key[AES_MAX_KEY_SIZE]; - unsigned key_len; - uint8_t nonce[AES_BLOCK_SIZE]; - uint8_t encr_buf[AES_BLOCK_SIZE]; - unsigned encr_pos; -} archive_crypto_ctx; - -#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) -#include - -/* Common in other bcrypt implementations, but missing from VS2008. */ -#ifndef BCRYPT_SUCCESS -#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS) -#endif - -#define AES_MAX_KEY_SIZE 32 -#define AES_BLOCK_SIZE 16 -typedef struct { - BCRYPT_ALG_HANDLE hAlg; - BCRYPT_KEY_HANDLE hKey; - PBYTE keyObj; - DWORD keyObj_len; - uint8_t nonce[AES_BLOCK_SIZE]; - uint8_t encr_buf[AES_BLOCK_SIZE]; - unsigned encr_pos; -} archive_crypto_ctx; - -#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_AES_H) -#include -#include -#include - -#define AES_MAX_KEY_SIZE 32 -#define AES_BLOCK_SIZE 16 - -typedef struct { - mbedtls_aes_context ctx; - uint8_t key[AES_MAX_KEY_SIZE]; - unsigned key_len; - uint8_t nonce[AES_BLOCK_SIZE]; - uint8_t encr_buf[AES_BLOCK_SIZE]; - unsigned encr_pos; -} archive_crypto_ctx; - -#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_AES_H) -#if defined(HAVE_NETTLE_PBKDF2_H) -#include -#endif -#include -#include - -typedef struct { -#if NETTLE_VERSION_MAJOR < 3 - struct aes_ctx ctx; -#else - union { - struct aes128_ctx c128; - struct aes192_ctx c192; - struct aes256_ctx c256; - } ctx; -#endif - uint8_t key[AES_MAX_KEY_SIZE]; - unsigned key_len; - uint8_t nonce[AES_BLOCK_SIZE]; - uint8_t encr_buf[AES_BLOCK_SIZE]; - unsigned encr_pos; -} archive_crypto_ctx; - -#elif defined(HAVE_LIBCRYPTO) -#include "archive_openssl_evp_private.h" -#define AES_BLOCK_SIZE 16 -#define AES_MAX_KEY_SIZE 32 - -typedef struct { - EVP_CIPHER_CTX *ctx; - const EVP_CIPHER *type; - uint8_t key[AES_MAX_KEY_SIZE]; - unsigned key_len; - uint8_t nonce[AES_BLOCK_SIZE]; - uint8_t encr_buf[AES_BLOCK_SIZE]; - unsigned encr_pos; -} archive_crypto_ctx; - -#else - -#define AES_BLOCK_SIZE 16 -#define AES_MAX_KEY_SIZE 32 -typedef int archive_crypto_ctx; - -#endif - -/* defines */ -#define archive_pbkdf2_sha1(pw, pw_len, salt, salt_len, rounds, dk, dk_len)\ - __archive_cryptor.pbkdf2sha1(pw, pw_len, salt, salt_len, rounds, dk, dk_len) - -#define archive_decrypto_aes_ctr_init(ctx, key, key_len) \ - __archive_cryptor.decrypto_aes_ctr_init(ctx, key, key_len) -#define archive_decrypto_aes_ctr_update(ctx, in, in_len, out, out_len) \ - __archive_cryptor.decrypto_aes_ctr_update(ctx, in, in_len, out, out_len) -#define archive_decrypto_aes_ctr_release(ctx) \ - __archive_cryptor.decrypto_aes_ctr_release(ctx) - -#define archive_encrypto_aes_ctr_init(ctx, key, key_len) \ - __archive_cryptor.encrypto_aes_ctr_init(ctx, key, key_len) -#define archive_encrypto_aes_ctr_update(ctx, in, in_len, out, out_len) \ - __archive_cryptor.encrypto_aes_ctr_update(ctx, in, in_len, out, out_len) -#define archive_encrypto_aes_ctr_release(ctx) \ - __archive_cryptor.encrypto_aes_ctr_release(ctx) - -/* Minimal interface to cryptographic functionality for internal use in - * libarchive */ -struct archive_cryptor -{ - /* PKCS5 PBKDF2 HMAC-SHA1 */ - int (*pbkdf2sha1)(const char *pw, size_t pw_len, const uint8_t *salt, - size_t salt_len, unsigned rounds, uint8_t *derived_key, - size_t derived_key_len); - /* AES CTR mode(little endian version) */ - int (*decrypto_aes_ctr_init)(archive_crypto_ctx *, const uint8_t *, size_t); - int (*decrypto_aes_ctr_update)(archive_crypto_ctx *, const uint8_t *, - size_t, uint8_t *, size_t *); - int (*decrypto_aes_ctr_release)(archive_crypto_ctx *); - int (*encrypto_aes_ctr_init)(archive_crypto_ctx *, const uint8_t *, size_t); - int (*encrypto_aes_ctr_update)(archive_crypto_ctx *, const uint8_t *, - size_t, uint8_t *, size_t *); - int (*encrypto_aes_ctr_release)(archive_crypto_ctx *); -}; - -extern const struct archive_cryptor __archive_cryptor; - -#endif diff --git a/thirdparty/libarchive/libarchive/archive_digest.c b/thirdparty/libarchive/libarchive/archive_digest.c deleted file mode 100644 index 3776831b2..000000000 --- a/thirdparty/libarchive/libarchive/archive_digest.c +++ /dev/null @@ -1,1565 +0,0 @@ -/*- -* Copyright (c) 2003-2007 Tim Kientzle -* Copyright (c) 2011 Andres Mejia -* Copyright (c) 2011 Michihiro NAKAJIMA -* 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. -* 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. -* -* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. -*/ - -#include "archive_platform.h" - -#include "archive.h" -#include "archive_digest_private.h" - -/* In particular, force the configure probe to break if it tries - * to test a combination of OpenSSL and libmd. */ -#if defined(ARCHIVE_CRYPTO_OPENSSL) && defined(ARCHIVE_CRYPTO_LIBMD) -#error Cannot use both OpenSSL and libmd. -#endif - -/* Common in other bcrypt implementations, but missing from VS2008. */ -#ifndef BCRYPT_SUCCESS -#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS) -#endif - -/* - * Message digest functions for Windows platform. - */ -#if defined(ARCHIVE_CRYPTO_MD5_WIN) ||\ - defined(ARCHIVE_CRYPTO_SHA1_WIN) ||\ - defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\ - defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\ - defined(ARCHIVE_CRYPTO_SHA512_WIN) - -/* - * Initialize a Message digest. - */ -#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA -static int -win_crypto_init(Digest_CTX *ctx, const WCHAR *algo) -{ - NTSTATUS status; - ctx->valid = 0; - - status = BCryptOpenAlgorithmProvider(&ctx->hAlg, algo, NULL, 0); - if (!BCRYPT_SUCCESS(status)) - return (ARCHIVE_FAILED); - status = BCryptCreateHash(ctx->hAlg, &ctx->hHash, NULL, 0, NULL, 0, 0); - if (!BCRYPT_SUCCESS(status)) { - BCryptCloseAlgorithmProvider(ctx->hAlg, 0); - return (ARCHIVE_FAILED); - } - - ctx->valid = 1; - return (ARCHIVE_OK); -} -#else -static int -win_crypto_init(Digest_CTX *ctx, DWORD prov, ALG_ID algId) -{ - - ctx->valid = 0; - if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL, - prov, CRYPT_VERIFYCONTEXT)) { - if (GetLastError() != (DWORD)NTE_BAD_KEYSET) - return (ARCHIVE_FAILED); - if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL, - prov, CRYPT_NEWKEYSET)) - return (ARCHIVE_FAILED); - } - - if (!CryptCreateHash(ctx->cryptProv, algId, 0, 0, &ctx->hash)) { - CryptReleaseContext(ctx->cryptProv, 0); - return (ARCHIVE_FAILED); - } - - ctx->valid = 1; - return (ARCHIVE_OK); -} -#endif - -/* - * Update a Message digest. - */ -static int -win_crypto_Update(Digest_CTX *ctx, const unsigned char *buf, size_t len) -{ - - if (!ctx->valid) - return (ARCHIVE_FAILED); - -#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA - BCryptHashData(ctx->hHash, - (PUCHAR)(uintptr_t)buf, - (ULONG)len, 0); -#else - CryptHashData(ctx->hash, - (unsigned char *)(uintptr_t)buf, - (DWORD)len, 0); -#endif - return (ARCHIVE_OK); -} - -static int -win_crypto_Final(unsigned char *buf, size_t bufsize, Digest_CTX *ctx) -{ -#if !(defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA) - DWORD siglen = (DWORD)bufsize; -#endif - - if (!ctx->valid) - return (ARCHIVE_FAILED); - -#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA - BCryptFinishHash(ctx->hHash, buf, (ULONG)bufsize, 0); - BCryptDestroyHash(ctx->hHash); - BCryptCloseAlgorithmProvider(ctx->hAlg, 0); -#else - CryptGetHashParam(ctx->hash, HP_HASHVAL, buf, &siglen, 0); - CryptDestroyHash(ctx->hash); - CryptReleaseContext(ctx->cryptProv, 0); -#endif - ctx->valid = 0; - return (ARCHIVE_OK); -} - -#endif /* defined(ARCHIVE_CRYPTO_*_WIN) */ - - -/* MD5 implementations */ -#if defined(ARCHIVE_CRYPTO_MD5_LIBC) - -static int -__archive_md5init(archive_md5_ctx *ctx) -{ - MD5Init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_md5update(archive_md5_ctx *ctx, const void *indata, - size_t insize) -{ - MD5Update(ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_md5final(archive_md5_ctx *ctx, void *md) -{ - MD5Final(md, ctx); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_MD5_LIBMD) - -static int -__archive_md5init(archive_md5_ctx *ctx) -{ - MD5Init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_md5update(archive_md5_ctx *ctx, const void *indata, - size_t insize) -{ - MD5Update(ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_md5final(archive_md5_ctx *ctx, void *md) -{ - MD5Final(md, ctx); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM) - -static int -__archive_md5init(archive_md5_ctx *ctx) -{ - CC_MD5_Init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_md5update(archive_md5_ctx *ctx, const void *indata, - size_t insize) -{ - CC_MD5_Update(ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_md5final(archive_md5_ctx *ctx, void *md) -{ - CC_MD5_Final(md, ctx); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_MD5_MBEDTLS) - -static int -__archive_md5init(archive_md5_ctx *ctx) -{ - mbedtls_md5_init(ctx); - if (mbedtls_md5_starts_ret(ctx) == 0) - return (ARCHIVE_OK); - else - return (ARCHIVE_FATAL); -} - -static int -__archive_md5update(archive_md5_ctx *ctx, const void *indata, - size_t insize) -{ - if (mbedtls_md5_update_ret(ctx, indata, insize) == 0) - return (ARCHIVE_OK); - else - return (ARCHIVE_FATAL); -} - -static int -__archive_md5final(archive_md5_ctx *ctx, void *md) -{ - if (mbedtls_md5_finish_ret(ctx, md) == 0) { - mbedtls_md5_free(ctx); - return (ARCHIVE_OK); - } else { - mbedtls_md5_free(ctx); - return (ARCHIVE_FATAL); - } -} - -#elif defined(ARCHIVE_CRYPTO_MD5_NETTLE) - -static int -__archive_md5init(archive_md5_ctx *ctx) -{ - md5_init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_md5update(archive_md5_ctx *ctx, const void *indata, - size_t insize) -{ - md5_update(ctx, insize, indata); - return (ARCHIVE_OK); -} - -static int -__archive_md5final(archive_md5_ctx *ctx, void *md) -{ - md5_digest(ctx, MD5_DIGEST_SIZE, md); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_MD5_OPENSSL) - -static int -__archive_md5init(archive_md5_ctx *ctx) -{ - if ((*ctx = EVP_MD_CTX_new()) == NULL) - return (ARCHIVE_FAILED); - if (!EVP_DigestInit(*ctx, EVP_md5())) - return (ARCHIVE_FAILED); - return (ARCHIVE_OK); -} - -static int -__archive_md5update(archive_md5_ctx *ctx, const void *indata, - size_t insize) -{ - EVP_DigestUpdate(*ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_md5final(archive_md5_ctx *ctx, void *md) -{ - /* HACK: archive_write_set_format_xar.c is finalizing empty contexts, so - * this is meant to cope with that. Real fix is probably to fix - * archive_write_set_format_xar.c - */ - if (*ctx) { - EVP_DigestFinal(*ctx, md, NULL); - EVP_MD_CTX_free(*ctx); - *ctx = NULL; - } - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_MD5_WIN) - -static int -__archive_md5init(archive_md5_ctx *ctx) -{ -#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA - return (win_crypto_init(ctx, BCRYPT_MD5_ALGORITHM)); -#else - return (win_crypto_init(ctx, PROV_RSA_FULL, CALG_MD5)); -#endif -} - -static int -__archive_md5update(archive_md5_ctx *ctx, const void *indata, - size_t insize) -{ - return (win_crypto_Update(ctx, indata, insize)); -} - -static int -__archive_md5final(archive_md5_ctx *ctx, void *md) -{ - return (win_crypto_Final(md, 16, ctx)); -} - -#else - -static int -__archive_md5init(archive_md5_ctx *ctx) -{ - (void)ctx; /* UNUSED */ - return (ARCHIVE_FAILED); -} - -static int -__archive_md5update(archive_md5_ctx *ctx, const void *indata, - size_t insize) -{ - (void)ctx; /* UNUSED */ - (void)indata; /* UNUSED */ - (void)insize; /* UNUSED */ - return (ARCHIVE_FAILED); -} - -static int -__archive_md5final(archive_md5_ctx *ctx, void *md) -{ - (void)ctx; /* UNUSED */ - (void)md; /* UNUSED */ - return (ARCHIVE_FAILED); -} - -#endif - -/* RIPEMD160 implementations */ -#if defined(ARCHIVE_CRYPTO_RMD160_LIBC) - -static int -__archive_ripemd160init(archive_rmd160_ctx *ctx) -{ - RMD160Init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_ripemd160update(archive_rmd160_ctx *ctx, const void *indata, - size_t insize) -{ - RMD160Update(ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_ripemd160final(archive_rmd160_ctx *ctx, void *md) -{ - RMD160Final(md, ctx); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_RMD160_LIBMD) - -static int -__archive_ripemd160init(archive_rmd160_ctx *ctx) -{ - RIPEMD160_Init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_ripemd160update(archive_rmd160_ctx *ctx, const void *indata, - size_t insize) -{ - RIPEMD160_Update(ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_ripemd160final(archive_rmd160_ctx *ctx, void *md) -{ - RIPEMD160_Final(md, ctx); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS) - -static int -__archive_ripemd160init(archive_rmd160_ctx *ctx) -{ - mbedtls_ripemd160_init(ctx); - if (mbedtls_ripemd160_starts_ret(ctx) == 0) - return (ARCHIVE_OK); - else - return (ARCHIVE_FATAL); -} - -static int -__archive_ripemd160update(archive_rmd160_ctx *ctx, const void *indata, - size_t insize) -{ - if (mbedtls_ripemd160_update_ret(ctx, indata, insize) == 0) - return (ARCHIVE_OK); - else - return (ARCHIVE_FATAL); -} - -static int -__archive_ripemd160final(archive_rmd160_ctx *ctx, void *md) -{ - if (mbedtls_ripemd160_finish_ret(ctx, md) == 0) { - mbedtls_ripemd160_free(ctx); - return (ARCHIVE_OK); - } else { - mbedtls_ripemd160_free(ctx); - return (ARCHIVE_FATAL); - } -} - -#elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE) - -static int -__archive_ripemd160init(archive_rmd160_ctx *ctx) -{ - ripemd160_init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_ripemd160update(archive_rmd160_ctx *ctx, const void *indata, - size_t insize) -{ - ripemd160_update(ctx, insize, indata); - return (ARCHIVE_OK); -} - -static int -__archive_ripemd160final(archive_rmd160_ctx *ctx, void *md) -{ - ripemd160_digest(ctx, RIPEMD160_DIGEST_SIZE, md); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_RMD160_OPENSSL) - -static int -__archive_ripemd160init(archive_rmd160_ctx *ctx) -{ - if ((*ctx = EVP_MD_CTX_new()) == NULL) - return (ARCHIVE_FAILED); - if (!EVP_DigestInit(*ctx, EVP_ripemd160())) - return (ARCHIVE_FAILED); - return (ARCHIVE_OK); -} - -static int -__archive_ripemd160update(archive_rmd160_ctx *ctx, const void *indata, - size_t insize) -{ - EVP_DigestUpdate(*ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_ripemd160final(archive_rmd160_ctx *ctx, void *md) -{ - if (*ctx) { - EVP_DigestFinal(*ctx, md, NULL); - EVP_MD_CTX_free(*ctx); - *ctx = NULL; - } - return (ARCHIVE_OK); -} - -#else - -static int -__archive_ripemd160init(archive_rmd160_ctx *ctx) -{ - (void)ctx; /* UNUSED */ - return (ARCHIVE_FAILED); -} - -static int -__archive_ripemd160update(archive_rmd160_ctx *ctx, const void *indata, - size_t insize) -{ - (void)ctx; /* UNUSED */ - (void)indata; /* UNUSED */ - (void)insize; /* UNUSED */ - return (ARCHIVE_FAILED); -} - -static int -__archive_ripemd160final(archive_rmd160_ctx *ctx, void *md) -{ - (void)ctx; /* UNUSED */ - (void)md; /* UNUSED */ - return (ARCHIVE_FAILED); -} - -#endif - -/* SHA1 implementations */ -#if defined(ARCHIVE_CRYPTO_SHA1_LIBC) - -static int -__archive_sha1init(archive_sha1_ctx *ctx) -{ - SHA1Init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_sha1update(archive_sha1_ctx *ctx, const void *indata, - size_t insize) -{ - SHA1Update(ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_sha1final(archive_sha1_ctx *ctx, void *md) -{ - SHA1Final(md, ctx); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_SHA1_LIBMD) - -static int -__archive_sha1init(archive_sha1_ctx *ctx) -{ - SHA1_Init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_sha1update(archive_sha1_ctx *ctx, const void *indata, - size_t insize) -{ - SHA1_Update(ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_sha1final(archive_sha1_ctx *ctx, void *md) -{ - SHA1_Final(md, ctx); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM) - -static int -__archive_sha1init(archive_sha1_ctx *ctx) -{ - CC_SHA1_Init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_sha1update(archive_sha1_ctx *ctx, const void *indata, - size_t insize) -{ - CC_SHA1_Update(ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_sha1final(archive_sha1_ctx *ctx, void *md) -{ - CC_SHA1_Final(md, ctx); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS) - -static int -__archive_sha1init(archive_sha1_ctx *ctx) -{ - mbedtls_sha1_init(ctx); - if (mbedtls_sha1_starts_ret(ctx) == 0) - return (ARCHIVE_OK); - else - return (ARCHIVE_FATAL); -} - -static int -__archive_sha1update(archive_sha1_ctx *ctx, const void *indata, - size_t insize) -{ - if (mbedtls_sha1_update_ret(ctx, indata, insize) == 0) - return (ARCHIVE_OK); - else - return (ARCHIVE_FATAL); -} - -static int -__archive_sha1final(archive_sha1_ctx *ctx, void *md) -{ - if (mbedtls_sha1_finish_ret(ctx, md) == 0) { - mbedtls_sha1_free(ctx); - return (ARCHIVE_OK); - } else { - mbedtls_sha1_free(ctx); - return (ARCHIVE_FATAL); - } -} - -#elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE) - -static int -__archive_sha1init(archive_sha1_ctx *ctx) -{ - sha1_init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_sha1update(archive_sha1_ctx *ctx, const void *indata, - size_t insize) -{ - sha1_update(ctx, insize, indata); - return (ARCHIVE_OK); -} - -static int -__archive_sha1final(archive_sha1_ctx *ctx, void *md) -{ - sha1_digest(ctx, SHA1_DIGEST_SIZE, md); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_SHA1_OPENSSL) - -static int -__archive_sha1init(archive_sha1_ctx *ctx) -{ - if ((*ctx = EVP_MD_CTX_new()) == NULL) - return (ARCHIVE_FAILED); - if (!EVP_DigestInit(*ctx, EVP_sha1())) - return (ARCHIVE_FAILED); - return (ARCHIVE_OK); -} - -static int -__archive_sha1update(archive_sha1_ctx *ctx, const void *indata, - size_t insize) -{ - EVP_DigestUpdate(*ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_sha1final(archive_sha1_ctx *ctx, void *md) -{ - /* HACK: archive_write_set_format_xar.c is finalizing empty contexts, so - * this is meant to cope with that. Real fix is probably to fix - * archive_write_set_format_xar.c - */ - if (*ctx) { - EVP_DigestFinal(*ctx, md, NULL); - EVP_MD_CTX_free(*ctx); - *ctx = NULL; - } - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_SHA1_WIN) - -static int -__archive_sha1init(archive_sha1_ctx *ctx) -{ -#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA - return (win_crypto_init(ctx, BCRYPT_SHA1_ALGORITHM)); -#else - return (win_crypto_init(ctx, PROV_RSA_FULL, CALG_SHA1)); -#endif -} - -static int -__archive_sha1update(archive_sha1_ctx *ctx, const void *indata, - size_t insize) -{ - return (win_crypto_Update(ctx, indata, insize)); -} - -static int -__archive_sha1final(archive_sha1_ctx *ctx, void *md) -{ - return (win_crypto_Final(md, 20, ctx)); -} - -#else - -static int -__archive_sha1init(archive_sha1_ctx *ctx) -{ - (void)ctx; /* UNUSED */ - return (ARCHIVE_FAILED); -} - -static int -__archive_sha1update(archive_sha1_ctx *ctx, const void *indata, - size_t insize) -{ - (void)ctx; /* UNUSED */ - (void)indata; /* UNUSED */ - (void)insize; /* UNUSED */ - return (ARCHIVE_FAILED); -} - -static int -__archive_sha1final(archive_sha1_ctx *ctx, void *md) -{ - (void)ctx; /* UNUSED */ - (void)md; /* UNUSED */ - return (ARCHIVE_FAILED); -} - -#endif - -/* SHA256 implementations */ -#if defined(ARCHIVE_CRYPTO_SHA256_LIBC) - -static int -__archive_sha256init(archive_sha256_ctx *ctx) -{ - SHA256_Init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_sha256update(archive_sha256_ctx *ctx, const void *indata, - size_t insize) -{ - SHA256_Update(ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_sha256final(archive_sha256_ctx *ctx, void *md) -{ - SHA256_Final(md, ctx); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC2) - -static int -__archive_sha256init(archive_sha256_ctx *ctx) -{ - SHA256Init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_sha256update(archive_sha256_ctx *ctx, const void *indata, - size_t insize) -{ - SHA256Update(ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_sha256final(archive_sha256_ctx *ctx, void *md) -{ - SHA256Final(md, ctx); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC3) - -static int -__archive_sha256init(archive_sha256_ctx *ctx) -{ - SHA256Init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_sha256update(archive_sha256_ctx *ctx, const void *indata, - size_t insize) -{ - SHA256Update(ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_sha256final(archive_sha256_ctx *ctx, void *md) -{ - SHA256Final(md, ctx); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_SHA256_LIBMD) - -static int -__archive_sha256init(archive_sha256_ctx *ctx) -{ - SHA256_Init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_sha256update(archive_sha256_ctx *ctx, const void *indata, - size_t insize) -{ - SHA256_Update(ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_sha256final(archive_sha256_ctx *ctx, void *md) -{ - SHA256_Final(md, ctx); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM) - -static int -__archive_sha256init(archive_sha256_ctx *ctx) -{ - CC_SHA256_Init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_sha256update(archive_sha256_ctx *ctx, const void *indata, - size_t insize) -{ - CC_SHA256_Update(ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_sha256final(archive_sha256_ctx *ctx, void *md) -{ - CC_SHA256_Final(md, ctx); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS) - -static int -__archive_sha256init(archive_sha256_ctx *ctx) -{ - mbedtls_sha256_init(ctx); - if (mbedtls_sha256_starts_ret(ctx, 0) == 0) - return (ARCHIVE_OK); - else - return (ARCHIVE_FATAL); -} - -static int -__archive_sha256update(archive_sha256_ctx *ctx, const void *indata, - size_t insize) -{ - if (mbedtls_sha256_update_ret(ctx, indata, insize) == 0) - return (ARCHIVE_OK); - else - return (ARCHIVE_FATAL); -} - -static int -__archive_sha256final(archive_sha256_ctx *ctx, void *md) -{ - if (mbedtls_sha256_finish_ret(ctx, md) == 0) { - mbedtls_sha256_free(ctx); - return (ARCHIVE_OK); - } else { - mbedtls_sha256_free(ctx); - return (ARCHIVE_FATAL); - } -} - -#elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE) - -static int -__archive_sha256init(archive_sha256_ctx *ctx) -{ - sha256_init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_sha256update(archive_sha256_ctx *ctx, const void *indata, - size_t insize) -{ - sha256_update(ctx, insize, indata); - return (ARCHIVE_OK); -} - -static int -__archive_sha256final(archive_sha256_ctx *ctx, void *md) -{ - sha256_digest(ctx, SHA256_DIGEST_SIZE, md); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_SHA256_OPENSSL) - -static int -__archive_sha256init(archive_sha256_ctx *ctx) -{ - if ((*ctx = EVP_MD_CTX_new()) == NULL) - return (ARCHIVE_FAILED); - if (!EVP_DigestInit(*ctx, EVP_sha256())) - return (ARCHIVE_FAILED); - return (ARCHIVE_OK); -} - -static int -__archive_sha256update(archive_sha256_ctx *ctx, const void *indata, - size_t insize) -{ - EVP_DigestUpdate(*ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_sha256final(archive_sha256_ctx *ctx, void *md) -{ - if (*ctx) { - EVP_DigestFinal(*ctx, md, NULL); - EVP_MD_CTX_free(*ctx); - *ctx = NULL; - } - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_SHA256_WIN) - -static int -__archive_sha256init(archive_sha256_ctx *ctx) -{ -#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA - return (win_crypto_init(ctx, BCRYPT_SHA256_ALGORITHM)); -#else - return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_256)); -#endif -} - -static int -__archive_sha256update(archive_sha256_ctx *ctx, const void *indata, - size_t insize) -{ - return (win_crypto_Update(ctx, indata, insize)); -} - -static int -__archive_sha256final(archive_sha256_ctx *ctx, void *md) -{ - return (win_crypto_Final(md, 32, ctx)); -} - -#else - -static int -__archive_sha256init(archive_sha256_ctx *ctx) -{ - (void)ctx; /* UNUSED */ - return (ARCHIVE_FAILED); -} - -static int -__archive_sha256update(archive_sha256_ctx *ctx, const void *indata, - size_t insize) -{ - (void)ctx; /* UNUSED */ - (void)indata; /* UNUSED */ - (void)insize; /* UNUSED */ - return (ARCHIVE_FAILED); -} - -static int -__archive_sha256final(archive_sha256_ctx *ctx, void *md) -{ - (void)ctx; /* UNUSED */ - (void)md; /* UNUSED */ - return (ARCHIVE_FAILED); -} - -#endif - -/* SHA384 implementations */ -#if defined(ARCHIVE_CRYPTO_SHA384_LIBC) - -static int -__archive_sha384init(archive_sha384_ctx *ctx) -{ - SHA384_Init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_sha384update(archive_sha384_ctx *ctx, const void *indata, - size_t insize) -{ - SHA384_Update(ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_sha384final(archive_sha384_ctx *ctx, void *md) -{ - SHA384_Final(md, ctx); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC2) - -static int -__archive_sha384init(archive_sha384_ctx *ctx) -{ - SHA384Init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_sha384update(archive_sha384_ctx *ctx, const void *indata, - size_t insize) -{ - SHA384Update(ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_sha384final(archive_sha384_ctx *ctx, void *md) -{ - SHA384Final(md, ctx); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC3) - -static int -__archive_sha384init(archive_sha384_ctx *ctx) -{ - SHA384Init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_sha384update(archive_sha384_ctx *ctx, const void *indata, - size_t insize) -{ - SHA384Update(ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_sha384final(archive_sha384_ctx *ctx, void *md) -{ - SHA384Final(md, ctx); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM) - -static int -__archive_sha384init(archive_sha384_ctx *ctx) -{ - CC_SHA384_Init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_sha384update(archive_sha384_ctx *ctx, const void *indata, - size_t insize) -{ - CC_SHA384_Update(ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_sha384final(archive_sha384_ctx *ctx, void *md) -{ - CC_SHA384_Final(md, ctx); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS) - -static int -__archive_sha384init(archive_sha384_ctx *ctx) -{ - mbedtls_sha512_init(ctx); - if (mbedtls_sha512_starts_ret(ctx, 1) == 0) - return (ARCHIVE_OK); - else - return (ARCHIVE_FATAL); -} - -static int -__archive_sha384update(archive_sha384_ctx *ctx, const void *indata, - size_t insize) -{ - if (mbedtls_sha512_update_ret(ctx, indata, insize) == 0) - return (ARCHIVE_OK); - else - return (ARCHIVE_FATAL); -} - -static int -__archive_sha384final(archive_sha384_ctx *ctx, void *md) -{ - if (mbedtls_sha512_finish_ret(ctx, md) == 0) { - mbedtls_sha512_free(ctx); - return (ARCHIVE_OK); - } else { - mbedtls_sha512_free(ctx); - return (ARCHIVE_FATAL); - } -} - -#elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE) - -static int -__archive_sha384init(archive_sha384_ctx *ctx) -{ - sha384_init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_sha384update(archive_sha384_ctx *ctx, const void *indata, - size_t insize) -{ - sha384_update(ctx, insize, indata); - return (ARCHIVE_OK); -} - -static int -__archive_sha384final(archive_sha384_ctx *ctx, void *md) -{ - sha384_digest(ctx, SHA384_DIGEST_SIZE, md); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_SHA384_OPENSSL) - -static int -__archive_sha384init(archive_sha384_ctx *ctx) -{ - if ((*ctx = EVP_MD_CTX_new()) == NULL) - return (ARCHIVE_FAILED); - if (!EVP_DigestInit(*ctx, EVP_sha384())) - return (ARCHIVE_FAILED); - return (ARCHIVE_OK); -} - -static int -__archive_sha384update(archive_sha384_ctx *ctx, const void *indata, - size_t insize) -{ - EVP_DigestUpdate(*ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_sha384final(archive_sha384_ctx *ctx, void *md) -{ - if (*ctx) { - EVP_DigestFinal(*ctx, md, NULL); - EVP_MD_CTX_free(*ctx); - *ctx = NULL; - } - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_SHA384_WIN) - -static int -__archive_sha384init(archive_sha384_ctx *ctx) -{ -#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA - return (win_crypto_init(ctx, BCRYPT_SHA384_ALGORITHM)); -#else - return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_384)); -#endif -} - -static int -__archive_sha384update(archive_sha384_ctx *ctx, const void *indata, - size_t insize) -{ - return (win_crypto_Update(ctx, indata, insize)); -} - -static int -__archive_sha384final(archive_sha384_ctx *ctx, void *md) -{ - return (win_crypto_Final(md, 48, ctx)); -} - -#else - -static int -__archive_sha384init(archive_sha384_ctx *ctx) -{ - (void)ctx; /* UNUSED */ - return (ARCHIVE_FAILED); -} - -static int -__archive_sha384update(archive_sha384_ctx *ctx, const void *indata, - size_t insize) -{ - (void)ctx; /* UNUSED */ - (void)indata; /* UNUSED */ - (void)insize; /* UNUSED */ - return (ARCHIVE_FAILED); -} - -static int -__archive_sha384final(archive_sha384_ctx *ctx, void *md) -{ - (void)ctx; /* UNUSED */ - (void)md; /* UNUSED */ - return (ARCHIVE_FAILED); -} - -#endif - -/* SHA512 implementations */ -#if defined(ARCHIVE_CRYPTO_SHA512_LIBC) - -static int -__archive_sha512init(archive_sha512_ctx *ctx) -{ - SHA512_Init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_sha512update(archive_sha512_ctx *ctx, const void *indata, - size_t insize) -{ - SHA512_Update(ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_sha512final(archive_sha512_ctx *ctx, void *md) -{ - SHA512_Final(md, ctx); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC2) - -static int -__archive_sha512init(archive_sha512_ctx *ctx) -{ - SHA512Init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_sha512update(archive_sha512_ctx *ctx, const void *indata, - size_t insize) -{ - SHA512Update(ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_sha512final(archive_sha512_ctx *ctx, void *md) -{ - SHA512Final(md, ctx); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC3) - -static int -__archive_sha512init(archive_sha512_ctx *ctx) -{ - SHA512Init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_sha512update(archive_sha512_ctx *ctx, const void *indata, - size_t insize) -{ - SHA512Update(ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_sha512final(archive_sha512_ctx *ctx, void *md) -{ - SHA512Final(md, ctx); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_SHA512_LIBMD) - -static int -__archive_sha512init(archive_sha512_ctx *ctx) -{ - SHA512_Init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_sha512update(archive_sha512_ctx *ctx, const void *indata, - size_t insize) -{ - SHA512_Update(ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_sha512final(archive_sha512_ctx *ctx, void *md) -{ - SHA512_Final(md, ctx); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM) - -static int -__archive_sha512init(archive_sha512_ctx *ctx) -{ - CC_SHA512_Init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_sha512update(archive_sha512_ctx *ctx, const void *indata, - size_t insize) -{ - CC_SHA512_Update(ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_sha512final(archive_sha512_ctx *ctx, void *md) -{ - CC_SHA512_Final(md, ctx); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS) - -static int -__archive_sha512init(archive_sha512_ctx *ctx) -{ - mbedtls_sha512_init(ctx); - if (mbedtls_sha512_starts_ret(ctx, 0) == 0) - return (ARCHIVE_OK); - else - return (ARCHIVE_FATAL); -} - -static int -__archive_sha512update(archive_sha512_ctx *ctx, const void *indata, - size_t insize) -{ - if (mbedtls_sha512_update_ret(ctx, indata, insize) == 0) - return (ARCHIVE_OK); - else - return (ARCHIVE_FATAL); -} - -static int -__archive_sha512final(archive_sha512_ctx *ctx, void *md) -{ - if (mbedtls_sha512_finish_ret(ctx, md) == 0) { - mbedtls_sha512_free(ctx); - return (ARCHIVE_OK); - } else { - mbedtls_sha512_free(ctx); - return (ARCHIVE_FATAL); - } -} - -#elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE) - -static int -__archive_sha512init(archive_sha512_ctx *ctx) -{ - sha512_init(ctx); - return (ARCHIVE_OK); -} - -static int -__archive_sha512update(archive_sha512_ctx *ctx, const void *indata, - size_t insize) -{ - sha512_update(ctx, insize, indata); - return (ARCHIVE_OK); -} - -static int -__archive_sha512final(archive_sha512_ctx *ctx, void *md) -{ - sha512_digest(ctx, SHA512_DIGEST_SIZE, md); - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_SHA512_OPENSSL) - -static int -__archive_sha512init(archive_sha512_ctx *ctx) -{ - if ((*ctx = EVP_MD_CTX_new()) == NULL) - return (ARCHIVE_FAILED); - if (!EVP_DigestInit(*ctx, EVP_sha512())) - return (ARCHIVE_FAILED); - return (ARCHIVE_OK); -} - -static int -__archive_sha512update(archive_sha512_ctx *ctx, const void *indata, - size_t insize) -{ - EVP_DigestUpdate(*ctx, indata, insize); - return (ARCHIVE_OK); -} - -static int -__archive_sha512final(archive_sha512_ctx *ctx, void *md) -{ - if (*ctx) { - EVP_DigestFinal(*ctx, md, NULL); - EVP_MD_CTX_free(*ctx); - *ctx = NULL; - } - return (ARCHIVE_OK); -} - -#elif defined(ARCHIVE_CRYPTO_SHA512_WIN) - -static int -__archive_sha512init(archive_sha512_ctx *ctx) -{ -#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA - return (win_crypto_init(ctx, BCRYPT_SHA512_ALGORITHM)); -#else - return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_512)); -#endif -} - -static int -__archive_sha512update(archive_sha512_ctx *ctx, const void *indata, - size_t insize) -{ - return (win_crypto_Update(ctx, indata, insize)); -} - -static int -__archive_sha512final(archive_sha512_ctx *ctx, void *md) -{ - return (win_crypto_Final(md, 64, ctx)); -} - -#else - -static int -__archive_sha512init(archive_sha512_ctx *ctx) -{ - (void)ctx; /* UNUSED */ - return (ARCHIVE_FAILED); -} - -static int -__archive_sha512update(archive_sha512_ctx *ctx, const void *indata, - size_t insize) -{ - (void)ctx; /* UNUSED */ - (void)indata; /* UNUSED */ - (void)insize; /* UNUSED */ - return (ARCHIVE_FAILED); -} - -static int -__archive_sha512final(archive_sha512_ctx *ctx, void *md) -{ - (void)ctx; /* UNUSED */ - (void)md; /* UNUSED */ - return (ARCHIVE_FAILED); -} - -#endif - -/* NOTE: Message Digest functions are set based on availability and by the - * following order of preference. - * 1. libc - * 2. libc2 - * 3. libc3 - * 4. libSystem - * 5. Nettle - * 6. OpenSSL - * 7. libmd - * 8. Windows API - */ -const struct archive_digest __archive_digest = -{ -/* MD5 */ - &__archive_md5init, - &__archive_md5update, - &__archive_md5final, - -/* RIPEMD160 */ - &__archive_ripemd160init, - &__archive_ripemd160update, - &__archive_ripemd160final, - -/* SHA1 */ - &__archive_sha1init, - &__archive_sha1update, - &__archive_sha1final, - -/* SHA256 */ - &__archive_sha256init, - &__archive_sha256update, - &__archive_sha256final, - -/* SHA384 */ - &__archive_sha384init, - &__archive_sha384update, - &__archive_sha384final, - -/* SHA512 */ - &__archive_sha512init, - &__archive_sha512update, - &__archive_sha512final -}; diff --git a/thirdparty/libarchive/libarchive/archive_digest_private.h b/thirdparty/libarchive/libarchive/archive_digest_private.h deleted file mode 100644 index 339b4edca..000000000 --- a/thirdparty/libarchive/libarchive/archive_digest_private.h +++ /dev/null @@ -1,426 +0,0 @@ -/*- -* Copyright (c) 2003-2007 Tim Kientzle -* Copyright (c) 2011 Andres Mejia -* 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. -* 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. -* -* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. -*/ - -#ifndef ARCHIVE_DIGEST_PRIVATE_H_INCLUDED -#define ARCHIVE_DIGEST_PRIVATE_H_INCLUDED - -#ifndef __LIBARCHIVE_BUILD -#error This header is only to be used internally to libarchive. -#endif -#ifndef __LIBARCHIVE_CONFIG_H_INCLUDED -#error "Should have include config.h first!" -#endif - -/* - * Crypto support in various Operating Systems: - * - * NetBSD: - * - MD5 and SHA1 in libc: without _ after algorithm name - * - SHA2 in libc: with _ after algorithm name - * - * OpenBSD: - * - MD5, SHA1 and SHA2 in libc: without _ after algorithm name - * - OpenBSD 4.4 and earlier have SHA2 in libc with _ after algorithm name - * - * DragonFly and FreeBSD: - * - MD5 libmd: without _ after algorithm name - * - SHA1, SHA256 and SHA512 in libmd: with _ after algorithm name - * - * Mac OS X (10.4 and later): - * - MD5, SHA1 and SHA2 in libSystem: with CC_ prefix and _ after algorithm name - * - * OpenSSL: - * - MD5, SHA1 and SHA2 in libcrypto: with _ after algorithm name - * - * Windows: - * - MD5, SHA1 and SHA2 in archive_crypto.c using Windows crypto API - */ - -/* libc crypto headers */ -#if defined(ARCHIVE_CRYPTO_MD5_LIBC) -#include -#endif -#if defined(ARCHIVE_CRYPTO_RMD160_LIBC) -#include -#endif -#if defined(ARCHIVE_CRYPTO_SHA1_LIBC) -#include -#endif -#if defined(ARCHIVE_CRYPTO_SHA256_LIBC) ||\ - defined(ARCHIVE_CRYPTO_SHA256_LIBC2) ||\ - defined(ARCHIVE_CRYPTO_SHA256_LIBC3) ||\ - defined(ARCHIVE_CRYPTO_SHA384_LIBC) ||\ - defined(ARCHIVE_CRYPTO_SHA384_LIBC2) ||\ - defined(ARCHIVE_CRYPTO_SHA384_LIBC3) ||\ - defined(ARCHIVE_CRYPTO_SHA512_LIBC) ||\ - defined(ARCHIVE_CRYPTO_SHA512_LIBC2) ||\ - defined(ARCHIVE_CRYPTO_SHA512_LIBC3) -#include -#endif - -/* libmd crypto headers */ -#if defined(ARCHIVE_CRYPTO_MD5_LIBMD) ||\ - defined(ARCHIVE_CRYPTO_RMD160_LIBMD) ||\ - defined(ARCHIVE_CRYPTO_SHA1_LIBMD) ||\ - defined(ARCHIVE_CRYPTO_SHA256_LIBMD) ||\ - defined(ARCHIVE_CRYPTO_SHA512_LIBMD) -#define ARCHIVE_CRYPTO_LIBMD 1 -#endif - -#if defined(ARCHIVE_CRYPTO_MD5_LIBMD) -#include -#endif -#if defined(ARCHIVE_CRYPTO_RMD160_LIBMD) -#include -#endif -#if defined(ARCHIVE_CRYPTO_SHA1_LIBMD) -#include -#endif -#if defined(ARCHIVE_CRYPTO_SHA256_LIBMD) -#include -#endif -#if defined(ARCHIVE_CRYPTO_SHA512_LIBMD) -#include -#endif - -/* libSystem crypto headers */ -#if defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM) ||\ - defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM) ||\ - defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM) ||\ - defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM) ||\ - defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM) -#include -#endif - -/* mbed TLS crypto headers */ -#if defined(ARCHIVE_CRYPTO_MD5_MBEDTLS) -#include -#endif -#if defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS) -#include -#endif -#if defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS) -#include -#endif -#if defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS) -#include -#endif -#if defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS) ||\ - defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS) -#include -#endif - -/* Nettle crypto headers */ -#if defined(ARCHIVE_CRYPTO_MD5_NETTLE) -#include -#endif -#if defined(ARCHIVE_CRYPTO_RMD160_NETTLE) -#include -#endif -#if defined(ARCHIVE_CRYPTO_SHA1_NETTLE) ||\ - defined(ARCHIVE_CRYPTO_SHA256_NETTLE) ||\ - defined(ARCHIVE_CRYPTO_SHA384_NETTLE) ||\ - defined(ARCHIVE_CRYPTO_SHA512_NETTLE) -#include -#endif - -/* OpenSSL crypto headers */ -#if defined(ARCHIVE_CRYPTO_MD5_OPENSSL) ||\ - defined(ARCHIVE_CRYPTO_RMD160_OPENSSL) ||\ - defined(ARCHIVE_CRYPTO_SHA1_OPENSSL) ||\ - defined(ARCHIVE_CRYPTO_SHA256_OPENSSL) ||\ - defined(ARCHIVE_CRYPTO_SHA384_OPENSSL) ||\ - defined(ARCHIVE_CRYPTO_SHA512_OPENSSL) -#define ARCHIVE_CRYPTO_OPENSSL 1 -#include "archive_openssl_evp_private.h" -#endif - -/* Windows crypto headers */ -#if defined(ARCHIVE_CRYPTO_MD5_WIN) ||\ - defined(ARCHIVE_CRYPTO_SHA1_WIN) ||\ - defined(ARCHIVE_CRYPTO_SHA256_WIN) ||\ - defined(ARCHIVE_CRYPTO_SHA384_WIN) ||\ - defined(ARCHIVE_CRYPTO_SHA512_WIN) -#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA -/* don't use bcrypt when XP needs to be supported */ -#include -typedef struct { - int valid; - BCRYPT_ALG_HANDLE hAlg; - BCRYPT_HASH_HANDLE hHash; -} Digest_CTX; -#else -#include -#include -typedef struct { - int valid; - HCRYPTPROV cryptProv; - HCRYPTHASH hash; -} Digest_CTX; -#endif -#endif - -/* typedefs */ -#if defined(ARCHIVE_CRYPTO_MD5_LIBC) -typedef MD5_CTX archive_md5_ctx; -#elif defined(ARCHIVE_CRYPTO_MD5_LIBMD) -typedef MD5_CTX archive_md5_ctx; -#elif defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM) -typedef CC_MD5_CTX archive_md5_ctx; -#elif defined(ARCHIVE_CRYPTO_MD5_MBEDTLS) -typedef mbedtls_md5_context archive_md5_ctx; -#elif defined(ARCHIVE_CRYPTO_MD5_NETTLE) -typedef struct md5_ctx archive_md5_ctx; -#elif defined(ARCHIVE_CRYPTO_MD5_OPENSSL) -typedef EVP_MD_CTX *archive_md5_ctx; -#elif defined(ARCHIVE_CRYPTO_MD5_WIN) -typedef Digest_CTX archive_md5_ctx; -#else -typedef unsigned char archive_md5_ctx; -#endif - -#if defined(ARCHIVE_CRYPTO_RMD160_LIBC) -typedef RMD160_CTX archive_rmd160_ctx; -#elif defined(ARCHIVE_CRYPTO_RMD160_LIBMD) -typedef RIPEMD160_CTX archive_rmd160_ctx; -#elif defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS) -typedef mbedtls_ripemd160_context archive_rmd160_ctx; -#elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE) -typedef struct ripemd160_ctx archive_rmd160_ctx; -#elif defined(ARCHIVE_CRYPTO_RMD160_OPENSSL) -typedef EVP_MD_CTX *archive_rmd160_ctx; -#else -typedef unsigned char archive_rmd160_ctx; -#endif - -#if defined(ARCHIVE_CRYPTO_SHA1_LIBC) -typedef SHA1_CTX archive_sha1_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA1_LIBMD) -typedef SHA1_CTX archive_sha1_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM) -typedef CC_SHA1_CTX archive_sha1_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS) -typedef mbedtls_sha1_context archive_sha1_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE) -typedef struct sha1_ctx archive_sha1_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA1_OPENSSL) -typedef EVP_MD_CTX *archive_sha1_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA1_WIN) -typedef Digest_CTX archive_sha1_ctx; -#else -typedef unsigned char archive_sha1_ctx; -#endif - -#if defined(ARCHIVE_CRYPTO_SHA256_LIBC) -typedef SHA256_CTX archive_sha256_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC2) -typedef SHA256_CTX archive_sha256_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC3) -typedef SHA2_CTX archive_sha256_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA256_LIBMD) -typedef SHA256_CTX archive_sha256_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM) -typedef CC_SHA256_CTX archive_sha256_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS) -typedef mbedtls_sha256_context archive_sha256_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE) -typedef struct sha256_ctx archive_sha256_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA256_OPENSSL) -typedef EVP_MD_CTX *archive_sha256_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA256_WIN) -typedef Digest_CTX archive_sha256_ctx; -#else -typedef unsigned char archive_sha256_ctx; -#endif - -#if defined(ARCHIVE_CRYPTO_SHA384_LIBC) -typedef SHA384_CTX archive_sha384_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC2) -typedef SHA384_CTX archive_sha384_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC3) -typedef SHA2_CTX archive_sha384_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM) -typedef CC_SHA512_CTX archive_sha384_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS) -typedef mbedtls_sha512_context archive_sha384_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE) -typedef struct sha384_ctx archive_sha384_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA384_OPENSSL) -typedef EVP_MD_CTX *archive_sha384_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA384_WIN) -typedef Digest_CTX archive_sha384_ctx; -#else -typedef unsigned char archive_sha384_ctx; -#endif - -#if defined(ARCHIVE_CRYPTO_SHA512_LIBC) -typedef SHA512_CTX archive_sha512_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC2) -typedef SHA512_CTX archive_sha512_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC3) -typedef SHA2_CTX archive_sha512_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA512_LIBMD) -typedef SHA512_CTX archive_sha512_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM) -typedef CC_SHA512_CTX archive_sha512_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS) -typedef mbedtls_sha512_context archive_sha512_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE) -typedef struct sha512_ctx archive_sha512_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA512_OPENSSL) -typedef EVP_MD_CTX *archive_sha512_ctx; -#elif defined(ARCHIVE_CRYPTO_SHA512_WIN) -typedef Digest_CTX archive_sha512_ctx; -#else -typedef unsigned char archive_sha512_ctx; -#endif - -/* defines */ -#if defined(ARCHIVE_CRYPTO_MD5_LIBC) ||\ - defined(ARCHIVE_CRYPTO_MD5_LIBMD) || \ - defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM) ||\ - defined(ARCHIVE_CRYPTO_MD5_MBEDTLS) ||\ - defined(ARCHIVE_CRYPTO_MD5_NETTLE) ||\ - defined(ARCHIVE_CRYPTO_MD5_OPENSSL) ||\ - defined(ARCHIVE_CRYPTO_MD5_WIN) -#define ARCHIVE_HAS_MD5 -#endif -#define archive_md5_init(ctx)\ - __archive_digest.md5init(ctx) -#define archive_md5_final(ctx, md)\ - __archive_digest.md5final(ctx, md) -#define archive_md5_update(ctx, buf, n)\ - __archive_digest.md5update(ctx, buf, n) - -#if defined(ARCHIVE_CRYPTO_RMD160_LIBC) ||\ - defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS) ||\ - defined(ARCHIVE_CRYPTO_RMD160_NETTLE) ||\ - defined(ARCHIVE_CRYPTO_RMD160_OPENSSL) -#define ARCHIVE_HAS_RMD160 -#endif -#define archive_rmd160_init(ctx)\ - __archive_digest.rmd160init(ctx) -#define archive_rmd160_final(ctx, md)\ - __archive_digest.rmd160final(ctx, md) -#define archive_rmd160_update(ctx, buf, n)\ - __archive_digest.rmd160update(ctx, buf, n) - -#if defined(ARCHIVE_CRYPTO_SHA1_LIBC) ||\ - defined(ARCHIVE_CRYPTO_SHA1_LIBMD) || \ - defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM) ||\ - defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS) ||\ - defined(ARCHIVE_CRYPTO_SHA1_NETTLE) ||\ - defined(ARCHIVE_CRYPTO_SHA1_OPENSSL) ||\ - defined(ARCHIVE_CRYPTO_SHA1_WIN) -#define ARCHIVE_HAS_SHA1 -#endif -#define archive_sha1_init(ctx)\ - __archive_digest.sha1init(ctx) -#define archive_sha1_final(ctx, md)\ - __archive_digest.sha1final(ctx, md) -#define archive_sha1_update(ctx, buf, n)\ - __archive_digest.sha1update(ctx, buf, n) - -#if defined(ARCHIVE_CRYPTO_SHA256_LIBC) ||\ - defined(ARCHIVE_CRYPTO_SHA256_LIBC2) ||\ - defined(ARCHIVE_CRYPTO_SHA256_LIBC3) ||\ - defined(ARCHIVE_CRYPTO_SHA256_LIBMD) ||\ - defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM) ||\ - defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS) ||\ - defined(ARCHIVE_CRYPTO_SHA256_NETTLE) ||\ - defined(ARCHIVE_CRYPTO_SHA256_OPENSSL) ||\ - defined(ARCHIVE_CRYPTO_SHA256_WIN) -#define ARCHIVE_HAS_SHA256 -#endif -#define archive_sha256_init(ctx)\ - __archive_digest.sha256init(ctx) -#define archive_sha256_final(ctx, md)\ - __archive_digest.sha256final(ctx, md) -#define archive_sha256_update(ctx, buf, n)\ - __archive_digest.sha256update(ctx, buf, n) - -#if defined(ARCHIVE_CRYPTO_SHA384_LIBC) ||\ - defined(ARCHIVE_CRYPTO_SHA384_LIBC2) ||\ - defined(ARCHIVE_CRYPTO_SHA384_LIBC3) ||\ - defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM) ||\ - defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS) ||\ - defined(ARCHIVE_CRYPTO_SHA384_NETTLE) ||\ - defined(ARCHIVE_CRYPTO_SHA384_OPENSSL) ||\ - defined(ARCHIVE_CRYPTO_SHA384_WIN) -#define ARCHIVE_HAS_SHA384 -#endif -#define archive_sha384_init(ctx)\ - __archive_digest.sha384init(ctx) -#define archive_sha384_final(ctx, md)\ - __archive_digest.sha384final(ctx, md) -#define archive_sha384_update(ctx, buf, n)\ - __archive_digest.sha384update(ctx, buf, n) - -#if defined(ARCHIVE_CRYPTO_SHA512_LIBC) ||\ - defined(ARCHIVE_CRYPTO_SHA512_LIBC2) ||\ - defined(ARCHIVE_CRYPTO_SHA512_LIBC3) ||\ - defined(ARCHIVE_CRYPTO_SHA512_LIBMD) ||\ - defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM) ||\ - defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS) ||\ - defined(ARCHIVE_CRYPTO_SHA512_NETTLE) ||\ - defined(ARCHIVE_CRYPTO_SHA512_OPENSSL) ||\ - defined(ARCHIVE_CRYPTO_SHA512_WIN) -#define ARCHIVE_HAS_SHA512 -#endif -#define archive_sha512_init(ctx)\ - __archive_digest.sha512init(ctx) -#define archive_sha512_final(ctx, md)\ - __archive_digest.sha512final(ctx, md) -#define archive_sha512_update(ctx, buf, n)\ - __archive_digest.sha512update(ctx, buf, n) - -/* Minimal interface to digest functionality for internal use in libarchive */ -struct archive_digest -{ - /* Message Digest */ - int (*md5init)(archive_md5_ctx *ctx); - int (*md5update)(archive_md5_ctx *, const void *, size_t); - int (*md5final)(archive_md5_ctx *, void *); - int (*rmd160init)(archive_rmd160_ctx *); - int (*rmd160update)(archive_rmd160_ctx *, const void *, size_t); - int (*rmd160final)(archive_rmd160_ctx *, void *); - int (*sha1init)(archive_sha1_ctx *); - int (*sha1update)(archive_sha1_ctx *, const void *, size_t); - int (*sha1final)(archive_sha1_ctx *, void *); - int (*sha256init)(archive_sha256_ctx *); - int (*sha256update)(archive_sha256_ctx *, const void *, size_t); - int (*sha256final)(archive_sha256_ctx *, void *); - int (*sha384init)(archive_sha384_ctx *); - int (*sha384update)(archive_sha384_ctx *, const void *, size_t); - int (*sha384final)(archive_sha384_ctx *, void *); - int (*sha512init)(archive_sha512_ctx *); - int (*sha512update)(archive_sha512_ctx *, const void *, size_t); - int (*sha512final)(archive_sha512_ctx *, void *); -}; - -extern const struct archive_digest __archive_digest; - -#endif diff --git a/thirdparty/libarchive/libarchive/archive_disk_acl_darwin.c b/thirdparty/libarchive/libarchive/archive_disk_acl_darwin.c deleted file mode 100644 index 48ad01651..000000000 --- a/thirdparty/libarchive/libarchive/archive_disk_acl_darwin.c +++ /dev/null @@ -1,559 +0,0 @@ -/*- - * Copyright (c) 2017 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -#if ARCHIVE_ACL_DARWIN - -#ifdef HAVE_FCNTL_H -#include -#endif -#if HAVE_ERRNO_H -#include -#endif -#if HAVE_MEMBERSHIP_H -#include -#endif -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_ACL_H -#define _ACL_PRIVATE /* For debugging */ -#include -#endif - -#include "archive_entry.h" -#include "archive_private.h" -#include "archive_read_disk_private.h" -#include "archive_write_disk_private.h" - -typedef struct { - const int a_perm; /* Libarchive permission or flag */ - const int p_perm; /* Platform permission or flag */ -} acl_perm_map_t; - -static const acl_perm_map_t acl_nfs4_perm_map[] = { - {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA}, - {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY}, - {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE}, - {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE}, - {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE}, - {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY}, - {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD}, - {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_EXTATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_EXTATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_SECURITY}, - {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_SECURITY}, - {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_CHANGE_OWNER}, -#if HAVE_DECL_ACL_SYNCHRONIZE - {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE} -#endif -}; - -static const int acl_nfs4_perm_map_size = - (int)(sizeof(acl_nfs4_perm_map)/sizeof(acl_nfs4_perm_map[0])); - -static const acl_perm_map_t acl_nfs4_flag_map[] = { - {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}, - {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT}, - {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT}, - {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_LIMIT_INHERIT}, - {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_ONLY_INHERIT} -}; - -static const int acl_nfs4_flag_map_size = - (int)(sizeof(acl_nfs4_flag_map)/sizeof(acl_nfs4_flag_map[0])); - -static int translate_guid(struct archive *a, acl_entry_t acl_entry, - int *ae_id, int *ae_tag, const char **ae_name) -{ - void *q; - uid_t ugid; - int r, idtype; - - q = acl_get_qualifier(acl_entry); - if (q == NULL) - return (1); - r = mbr_uuid_to_id((const unsigned char *)q, &ugid, &idtype); - if (r != 0) { - acl_free(q); - return (1); - } - if (idtype == ID_TYPE_UID) { - *ae_tag = ARCHIVE_ENTRY_ACL_USER; - *ae_id = ugid; - *ae_name = archive_read_disk_uname(a, *ae_id); - } else if (idtype == ID_TYPE_GID) { - *ae_tag = ARCHIVE_ENTRY_ACL_GROUP; - *ae_id = ugid; - *ae_name = archive_read_disk_gname(a, *ae_id); - } else - r = 1; - - acl_free(q); - return (r); -} - -static void -add_trivial_nfs4_acl(struct archive_entry *entry) -{ - mode_t mode; - int i; - const int rperm = ARCHIVE_ENTRY_ACL_READ_DATA; - const int wperm = ARCHIVE_ENTRY_ACL_WRITE_DATA | - ARCHIVE_ENTRY_ACL_APPEND_DATA; - const int eperm = ARCHIVE_ENTRY_ACL_EXECUTE; - const int pubset = ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE; - const int ownset = pubset | ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_WRITE_ACL | - ARCHIVE_ENTRY_ACL_WRITE_OWNER; - - struct { - const int type; - const int tag; - int permset; - } tacl_entry[] = { - {ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_USER_OBJ, 0}, - {ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_USER_OBJ, 0}, - {ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0}, - {ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_USER_OBJ, ownset}, - {ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_GROUP_OBJ, pubset}, - {ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EVERYONE, pubset} - }; - - mode = archive_entry_mode(entry); - - /* Permissions for everyone@ */ - if (mode & 0004) - tacl_entry[5].permset |= rperm; - if (mode & 0002) - tacl_entry[5].permset |= wperm; - if (mode & 0001) - tacl_entry[5].permset |= eperm; - - /* Permissions for group@ */ - if (mode & 0040) - tacl_entry[4].permset |= rperm; - else if (mode & 0004) - tacl_entry[2].permset |= rperm; - if (mode & 0020) - tacl_entry[4].permset |= wperm; - else if (mode & 0002) - tacl_entry[2].permset |= wperm; - if (mode & 0010) - tacl_entry[4].permset |= eperm; - else if (mode & 0001) - tacl_entry[2].permset |= eperm; - - /* Permissions for owner@ */ - if (mode & 0400) { - tacl_entry[3].permset |= rperm; - if (!(mode & 0040) && (mode & 0004)) - tacl_entry[0].permset |= rperm; - } else if ((mode & 0040) || (mode & 0004)) - tacl_entry[1].permset |= rperm; - if (mode & 0200) { - tacl_entry[3].permset |= wperm; - if (!(mode & 0020) && (mode & 0002)) - tacl_entry[0].permset |= wperm; - } else if ((mode & 0020) || (mode & 0002)) - tacl_entry[1].permset |= wperm; - if (mode & 0100) { - tacl_entry[3].permset |= eperm; - if (!(mode & 0010) && (mode & 0001)) - tacl_entry[0].permset |= eperm; - } else if ((mode & 0010) || (mode & 0001)) - tacl_entry[1].permset |= eperm; - - for (i = 0; i < 6; i++) { - if (tacl_entry[i].permset != 0) { - archive_entry_acl_add_entry(entry, - tacl_entry[i].type, tacl_entry[i].permset, - tacl_entry[i].tag, -1, NULL); - } - } - - return; -} - -static int -translate_acl(struct archive_read_disk *a, - struct archive_entry *entry, acl_t acl) -{ - acl_tag_t acl_tag; - acl_flagset_t acl_flagset; - acl_entry_t acl_entry; - acl_permset_t acl_permset; - int i, entry_acl_type; - int r, s, ae_id, ae_tag, ae_perm; - const char *ae_name; - - s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry); - if (s == -1) { - archive_set_error(&a->archive, errno, - "Failed to get first ACL entry"); - return (ARCHIVE_WARN); - } - - while (s == 0) { - ae_id = -1; - ae_name = NULL; - ae_perm = 0; - - if (acl_get_tag_type(acl_entry, &acl_tag) != 0) { - archive_set_error(&a->archive, errno, - "Failed to get ACL tag type"); - return (ARCHIVE_WARN); - } - switch (acl_tag) { - case ACL_EXTENDED_ALLOW: - entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW; - r = translate_guid(&a->archive, acl_entry, - &ae_id, &ae_tag, &ae_name); - break; - case ACL_EXTENDED_DENY: - entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY; - r = translate_guid(&a->archive, acl_entry, - &ae_id, &ae_tag, &ae_name); - break; - default: - /* Skip types that libarchive can't support. */ - s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry); - continue; - } - - /* Skip if translate_guid() above failed */ - if (r != 0) { - s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry); - continue; - } - - /* - * Libarchive stores "flag" (NFSv4 inheritance bits) - * in the ae_perm bitmap. - * - * acl_get_flagset_np() fails with non-NFSv4 ACLs - */ - if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) { - archive_set_error(&a->archive, errno, - "Failed to get flagset from a NFSv4 ACL entry"); - return (ARCHIVE_WARN); - } - for (i = 0; i < acl_nfs4_flag_map_size; ++i) { - r = acl_get_flag_np(acl_flagset, - acl_nfs4_flag_map[i].p_perm); - if (r == -1) { - archive_set_error(&a->archive, errno, - "Failed to check flag in a NFSv4 " - "ACL flagset"); - return (ARCHIVE_WARN); - } else if (r) - ae_perm |= acl_nfs4_flag_map[i].a_perm; - } - - if (acl_get_permset(acl_entry, &acl_permset) != 0) { - archive_set_error(&a->archive, errno, - "Failed to get ACL permission set"); - return (ARCHIVE_WARN); - } - - for (i = 0; i < acl_nfs4_perm_map_size; ++i) { - /* - * acl_get_perm() is spelled differently on different - * platforms; see above. - */ - r = acl_get_perm_np(acl_permset, - acl_nfs4_perm_map[i].p_perm); - if (r == -1) { - archive_set_error(&a->archive, errno, - "Failed to check permission in an ACL " - "permission set"); - return (ARCHIVE_WARN); - } else if (r) - ae_perm |= acl_nfs4_perm_map[i].a_perm; - } - -#if !HAVE_DECL_ACL_SYNCHRONIZE - /* On Mac OS X without ACL_SYNCHRONIZE assume it is set */ - ae_perm |= ARCHIVE_ENTRY_ACL_SYNCHRONIZE; -#endif - - archive_entry_acl_add_entry(entry, entry_acl_type, - ae_perm, ae_tag, - ae_id, ae_name); - - s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry); - } - return (ARCHIVE_OK); -} - -static int -set_acl(struct archive *a, int fd, const char *name, - struct archive_acl *abstract_acl, - int ae_requested_type, const char *tname) -{ - acl_t acl; - acl_entry_t acl_entry; - acl_permset_t acl_permset; - acl_flagset_t acl_flagset; - int ret; - int ae_type, ae_permset, ae_tag, ae_id; - uuid_t ae_uuid; - uid_t ae_uid; - gid_t ae_gid; - const char *ae_name; - int entries; - int i; - - ret = ARCHIVE_OK; - entries = archive_acl_reset(abstract_acl, ae_requested_type); - if (entries == 0) - return (ARCHIVE_OK); - - if (ae_requested_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - errno = ENOENT; - archive_set_error(a, errno, "Unsupported ACL type"); - return (ARCHIVE_FAILED); - } - - acl = acl_init(entries); - if (acl == (acl_t)NULL) { - archive_set_error(a, errno, - "Failed to initialize ACL working storage"); - return (ARCHIVE_FAILED); - } - - while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type, - &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) { - /* - * Mac OS doesn't support NFSv4 ACLs for - * owner@, group@ and everyone@. - * We skip any of these ACLs found. - */ - if (ae_tag == ARCHIVE_ENTRY_ACL_USER_OBJ || - ae_tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ || - ae_tag == ARCHIVE_ENTRY_ACL_EVERYONE) - continue; - - if (acl_create_entry(&acl, &acl_entry) != 0) { - archive_set_error(a, errno, - "Failed to create a new ACL entry"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - - switch (ae_type) { - case ARCHIVE_ENTRY_ACL_TYPE_ALLOW: - acl_set_tag_type(acl_entry, ACL_EXTENDED_ALLOW); - break; - case ARCHIVE_ENTRY_ACL_TYPE_DENY: - acl_set_tag_type(acl_entry, ACL_EXTENDED_DENY); - break; - default: - /* We don't support any other types on MacOS */ - continue; - } - - switch (ae_tag) { - case ARCHIVE_ENTRY_ACL_USER: - ae_uid = archive_write_disk_uid(a, ae_name, ae_id); - if (mbr_uid_to_uuid(ae_uid, ae_uuid) != 0) - continue; - if (acl_set_qualifier(acl_entry, &ae_uuid) != 0) - continue; - break; - case ARCHIVE_ENTRY_ACL_GROUP: - ae_gid = archive_write_disk_gid(a, ae_name, ae_id); - if (mbr_gid_to_uuid(ae_gid, ae_uuid) != 0) - continue; - if (acl_set_qualifier(acl_entry, &ae_uuid) != 0) - continue; - break; - default: - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Unsupported ACL tag"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - - if (acl_get_permset(acl_entry, &acl_permset) != 0) { - archive_set_error(a, errno, - "Failed to get ACL permission set"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - if (acl_clear_perms(acl_permset) != 0) { - archive_set_error(a, errno, - "Failed to clear ACL permissions"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - - for (i = 0; i < acl_nfs4_perm_map_size; ++i) { - if (ae_permset & acl_nfs4_perm_map[i].a_perm) { - if (acl_add_perm(acl_permset, - acl_nfs4_perm_map[i].p_perm) != 0) { - archive_set_error(a, errno, - "Failed to add ACL permission"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - } - } - - /* - * acl_get_flagset_np() fails with non-NFSv4 ACLs - */ - if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) { - archive_set_error(a, errno, - "Failed to get flagset from an NFSv4 ACL entry"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - if (acl_clear_flags_np(acl_flagset) != 0) { - archive_set_error(a, errno, - "Failed to clear flags from an NFSv4 ACL flagset"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - - for (i = 0; i < acl_nfs4_flag_map_size; ++i) { - if (ae_permset & acl_nfs4_flag_map[i].a_perm) { - if (acl_add_flag_np(acl_flagset, - acl_nfs4_flag_map[i].p_perm) != 0) { - archive_set_error(a, errno, - "Failed to add flag to " - "NFSv4 ACL flagset"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - } - } - } - - if (fd >= 0) { - if (acl_set_fd_np(fd, acl, ACL_TYPE_EXTENDED) == 0) - ret = ARCHIVE_OK; - else { - if (errno == EOPNOTSUPP) { - /* Filesystem doesn't support ACLs */ - ret = ARCHIVE_OK; - } else { - archive_set_error(a, errno, - "Failed to set acl on fd: %s", tname); - ret = ARCHIVE_WARN; - } - } - } else if (acl_set_link_np(name, ACL_TYPE_EXTENDED, acl) != 0) { - if (errno == EOPNOTSUPP) { - /* Filesystem doesn't support ACLs */ - ret = ARCHIVE_OK; - } else { - archive_set_error(a, errno, "Failed to set acl: %s", - tname); - ret = ARCHIVE_WARN; - } - } -exit_free: - acl_free(acl); - return (ret); -} - -int -archive_read_disk_entry_setup_acls(struct archive_read_disk *a, - struct archive_entry *entry, int *fd) -{ - const char *accpath; - acl_t acl; - int r; - - accpath = NULL; - - if (*fd < 0) { - accpath = archive_read_disk_entry_setup_path(a, entry, fd); - if (accpath == NULL) - return (ARCHIVE_WARN); - } - - archive_entry_acl_clear(entry); - - acl = NULL; - - if (*fd >= 0) - acl = acl_get_fd_np(*fd, ACL_TYPE_EXTENDED); - else if (!a->follow_symlinks) - acl = acl_get_link_np(accpath, ACL_TYPE_EXTENDED); - else - acl = acl_get_file(accpath, ACL_TYPE_EXTENDED); - - if (acl != NULL) { - r = translate_acl(a, entry, acl); - acl_free(acl); - acl = NULL; - - if (r != ARCHIVE_OK) { - archive_set_error(&a->archive, errno, - "Couldn't translate NFSv4 ACLs"); - } - - /* - * Because Mac OS doesn't support owner@, group@ and everyone@ - * ACLs we need to add NFSv4 ACLs mirroring the file mode to - * the archive entry. Otherwise extraction on non-Mac platforms - * would lead to an invalid file mode. - */ - if ((archive_entry_acl_types(entry) & - ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) - add_trivial_nfs4_acl(entry); - - return (r); - } - return (ARCHIVE_OK); -} - -int -archive_write_disk_set_acls(struct archive *a, int fd, const char *name, - struct archive_acl *abstract_acl, __LA_MODE_T mode) -{ - int ret = ARCHIVE_OK; - - (void)mode; /* UNUSED */ - - if ((archive_acl_types(abstract_acl) & - ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) { - ret = set_acl(a, fd, name, abstract_acl, - ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4"); - } - return (ret); -} -#endif /* ARCHIVE_ACL_DARWIN */ diff --git a/thirdparty/libarchive/libarchive/archive_disk_acl_freebsd.c b/thirdparty/libarchive/libarchive/archive_disk_acl_freebsd.c deleted file mode 100644 index ed4e7a789..000000000 --- a/thirdparty/libarchive/libarchive/archive_disk_acl_freebsd.c +++ /dev/null @@ -1,712 +0,0 @@ -/*- - * Copyright (c) 2003-2009 Tim Kientzle - * Copyright (c) 2010-2012 Michihiro NAKAJIMA - * Copyright (c) 2017 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -#if ARCHIVE_ACL_FREEBSD - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_ACL_H -#define _ACL_PRIVATE /* For debugging */ -#include -#endif - -#include "archive_entry.h" -#include "archive_private.h" -#include "archive_read_disk_private.h" -#include "archive_write_disk_private.h" - -typedef struct { - const int a_perm; /* Libarchive permission or flag */ - const int p_perm; /* Platform permission or flag */ -} acl_perm_map_t; - -static const acl_perm_map_t acl_posix_perm_map[] = { - {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE}, - {ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE}, - {ARCHIVE_ENTRY_ACL_READ, ACL_READ}, -}; - -static const int acl_posix_perm_map_size = - (int)(sizeof(acl_posix_perm_map)/sizeof(acl_posix_perm_map[0])); - -#if ARCHIVE_ACL_FREEBSD_NFS4 -static const acl_perm_map_t acl_nfs4_perm_map[] = { - {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE}, - {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA}, - {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY}, - {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE}, - {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY}, - {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS}, - {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS}, - {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD}, - {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE}, - {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL}, - {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL}, - {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER}, - {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE} -}; - -static const int acl_nfs4_perm_map_size = - (int)(sizeof(acl_nfs4_perm_map)/sizeof(acl_nfs4_perm_map[0])); - -static const acl_perm_map_t acl_nfs4_flag_map[] = { - {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT}, - {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT}, - {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT}, - {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY}, - {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS}, - {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS}, -#ifdef ACL_ENTRY_INHERITED - {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED} -#endif -}; - -static const int acl_nfs4_flag_map_size = - (int)(sizeof(acl_nfs4_flag_map)/sizeof(acl_nfs4_flag_map[0])); -#endif /* ARCHIVE_ACL_FREEBSD_NFS4 */ - -static int -translate_acl(struct archive_read_disk *a, - struct archive_entry *entry, acl_t acl, int default_entry_acl_type) -{ -#if ARCHIVE_ACL_FREEBSD_NFS4 - int brand; - acl_flagset_t acl_flagset; - acl_entry_type_t acl_type; -#endif - acl_tag_t acl_tag; - acl_entry_t acl_entry; - acl_permset_t acl_permset; - int i, entry_acl_type, perm_map_size; - const acl_perm_map_t *perm_map; - int r, s, ae_id, ae_tag, ae_perm; - void *q; - const char *ae_name; - -#if ARCHIVE_ACL_FREEBSD_NFS4 - // FreeBSD "brands" ACLs as POSIX.1e or NFSv4 - // Make sure the "brand" on this ACL is consistent - // with the default_entry_acl_type bits provided. - if (acl_get_brand_np(acl, &brand) != 0) { - archive_set_error(&a->archive, errno, - "Failed to read ACL brand"); - return (ARCHIVE_WARN); - } - switch (brand) { - case ACL_BRAND_POSIX: - switch (default_entry_acl_type) { - case ARCHIVE_ENTRY_ACL_TYPE_ACCESS: - case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT: - break; - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Invalid ACL entry type for POSIX.1e ACL"); - return (ARCHIVE_WARN); - } - break; - case ACL_BRAND_NFS4: - if (default_entry_acl_type & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Invalid ACL entry type for NFSv4 ACL"); - return (ARCHIVE_WARN); - } - break; - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Unknown ACL brand"); - return (ARCHIVE_WARN); - } -#endif - - s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry); - if (s == -1) { - archive_set_error(&a->archive, errno, - "Failed to get first ACL entry"); - return (ARCHIVE_WARN); - } - - while (s == 1) { - ae_id = -1; - ae_name = NULL; - ae_perm = 0; - - if (acl_get_tag_type(acl_entry, &acl_tag) != 0) { - archive_set_error(&a->archive, errno, - "Failed to get ACL tag type"); - return (ARCHIVE_WARN); - } - switch (acl_tag) { - case ACL_USER: - q = acl_get_qualifier(acl_entry); - if (q != NULL) { - ae_id = (int)*(uid_t *)q; - acl_free(q); - ae_name = archive_read_disk_uname(&a->archive, - ae_id); - } - ae_tag = ARCHIVE_ENTRY_ACL_USER; - break; - case ACL_GROUP: - q = acl_get_qualifier(acl_entry); - if (q != NULL) { - ae_id = (int)*(gid_t *)q; - acl_free(q); - ae_name = archive_read_disk_gname(&a->archive, - ae_id); - } - ae_tag = ARCHIVE_ENTRY_ACL_GROUP; - break; - case ACL_MASK: - ae_tag = ARCHIVE_ENTRY_ACL_MASK; - break; - case ACL_USER_OBJ: - ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ; - break; - case ACL_GROUP_OBJ: - ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ; - break; - case ACL_OTHER: - ae_tag = ARCHIVE_ENTRY_ACL_OTHER; - break; -#if ARCHIVE_ACL_FREEBSD_NFS4 - case ACL_EVERYONE: - ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE; - break; -#endif - default: - /* Skip types that libarchive can't support. */ - s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry); - continue; - } - - // XXX acl_type maps to allow/deny/audit/YYYY bits - entry_acl_type = default_entry_acl_type; - -#if ARCHIVE_ACL_FREEBSD_NFS4 - if (default_entry_acl_type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - /* - * acl_get_entry_type_np() fails with non-NFSv4 ACLs - */ - if (acl_get_entry_type_np(acl_entry, &acl_type) != 0) { - archive_set_error(&a->archive, errno, "Failed " - "to get ACL type from a NFSv4 ACL entry"); - return (ARCHIVE_WARN); - } - switch (acl_type) { - case ACL_ENTRY_TYPE_ALLOW: - entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW; - break; - case ACL_ENTRY_TYPE_DENY: - entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY; - break; - case ACL_ENTRY_TYPE_AUDIT: - entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_AUDIT; - break; - case ACL_ENTRY_TYPE_ALARM: - entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALARM; - break; - default: - archive_set_error(&a->archive, errno, - "Invalid NFSv4 ACL entry type"); - return (ARCHIVE_WARN); - } - - /* - * Libarchive stores "flag" (NFSv4 inheritance bits) - * in the ae_perm bitmap. - * - * acl_get_flagset_np() fails with non-NFSv4 ACLs - */ - if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) { - archive_set_error(&a->archive, errno, - "Failed to get flagset from a NFSv4 " - "ACL entry"); - return (ARCHIVE_WARN); - } - for (i = 0; i < acl_nfs4_flag_map_size; ++i) { - r = acl_get_flag_np(acl_flagset, - acl_nfs4_flag_map[i].p_perm); - if (r == -1) { - archive_set_error(&a->archive, errno, - "Failed to check flag in a NFSv4 " - "ACL flagset"); - return (ARCHIVE_WARN); - } else if (r) - ae_perm |= acl_nfs4_flag_map[i].a_perm; - } - } -#endif - - if (acl_get_permset(acl_entry, &acl_permset) != 0) { - archive_set_error(&a->archive, errno, - "Failed to get ACL permission set"); - return (ARCHIVE_WARN); - } - -#if ARCHIVE_ACL_FREEBSD_NFS4 - if (default_entry_acl_type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - perm_map_size = acl_nfs4_perm_map_size; - perm_map = acl_nfs4_perm_map; - } else { -#endif - perm_map_size = acl_posix_perm_map_size; - perm_map = acl_posix_perm_map; -#if ARCHIVE_ACL_FREEBSD_NFS4 - } -#endif - - for (i = 0; i < perm_map_size; ++i) { - r = acl_get_perm_np(acl_permset, perm_map[i].p_perm); - if (r == -1) { - archive_set_error(&a->archive, errno, - "Failed to check permission in an ACL " - "permission set"); - return (ARCHIVE_WARN); - } else if (r) - ae_perm |= perm_map[i].a_perm; - } - - archive_entry_acl_add_entry(entry, entry_acl_type, - ae_perm, ae_tag, - ae_id, ae_name); - - s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry); - if (s == -1) { - archive_set_error(&a->archive, errno, - "Failed to get next ACL entry"); - return (ARCHIVE_WARN); - } - } - return (ARCHIVE_OK); -} - -static int -set_acl(struct archive *a, int fd, const char *name, - struct archive_acl *abstract_acl, __LA_MODE_T mode, - int ae_requested_type, const char *tname) -{ - int acl_type = 0; - acl_t acl; - acl_entry_t acl_entry; - acl_permset_t acl_permset; -#if ARCHIVE_ACL_FREEBSD_NFS4 - acl_flagset_t acl_flagset; - int r; -#endif - int ret; - int ae_type, ae_permset, ae_tag, ae_id; - int perm_map_size; - const acl_perm_map_t *perm_map; - uid_t ae_uid; - gid_t ae_gid; - const char *ae_name; - int entries; - int i; - - ret = ARCHIVE_OK; - entries = archive_acl_reset(abstract_acl, ae_requested_type); - if (entries == 0) - return (ARCHIVE_OK); - - - switch (ae_requested_type) { - case ARCHIVE_ENTRY_ACL_TYPE_ACCESS: - acl_type = ACL_TYPE_ACCESS; - break; - case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT: - acl_type = ACL_TYPE_DEFAULT; - break; -#if ARCHIVE_ACL_FREEBSD_NFS4 - case ARCHIVE_ENTRY_ACL_TYPE_NFS4: - acl_type = ACL_TYPE_NFS4; - break; -#endif - default: - errno = ENOENT; - archive_set_error(a, errno, "Unsupported ACL type"); - return (ARCHIVE_FAILED); - } - - if (acl_type == ACL_TYPE_DEFAULT && !S_ISDIR(mode)) { - errno = EINVAL; - archive_set_error(a, errno, - "Cannot set default ACL on non-directory"); - return (ARCHIVE_WARN); - } - - acl = acl_init(entries); - if (acl == (acl_t)NULL) { - archive_set_error(a, errno, - "Failed to initialize ACL working storage"); - return (ARCHIVE_FAILED); - } - - while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type, - &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) { - if (acl_create_entry(&acl, &acl_entry) != 0) { - archive_set_error(a, errno, - "Failed to create a new ACL entry"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - switch (ae_tag) { - case ARCHIVE_ENTRY_ACL_USER: - ae_uid = archive_write_disk_uid(a, ae_name, ae_id); - acl_set_tag_type(acl_entry, ACL_USER); - acl_set_qualifier(acl_entry, &ae_uid); - break; - case ARCHIVE_ENTRY_ACL_GROUP: - ae_gid = archive_write_disk_gid(a, ae_name, ae_id); - acl_set_tag_type(acl_entry, ACL_GROUP); - acl_set_qualifier(acl_entry, &ae_gid); - break; - case ARCHIVE_ENTRY_ACL_USER_OBJ: - acl_set_tag_type(acl_entry, ACL_USER_OBJ); - break; - case ARCHIVE_ENTRY_ACL_GROUP_OBJ: - acl_set_tag_type(acl_entry, ACL_GROUP_OBJ); - break; - case ARCHIVE_ENTRY_ACL_MASK: - acl_set_tag_type(acl_entry, ACL_MASK); - break; - case ARCHIVE_ENTRY_ACL_OTHER: - acl_set_tag_type(acl_entry, ACL_OTHER); - break; -#if ARCHIVE_ACL_FREEBSD_NFS4 - case ARCHIVE_ENTRY_ACL_EVERYONE: - acl_set_tag_type(acl_entry, ACL_EVERYONE); - break; -#endif - default: - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Unsupported ACL tag"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - -#if ARCHIVE_ACL_FREEBSD_NFS4 - r = 0; - switch (ae_type) { - case ARCHIVE_ENTRY_ACL_TYPE_ALLOW: - r = acl_set_entry_type_np(acl_entry, - ACL_ENTRY_TYPE_ALLOW); - break; - case ARCHIVE_ENTRY_ACL_TYPE_DENY: - r = acl_set_entry_type_np(acl_entry, - ACL_ENTRY_TYPE_DENY); - break; - case ARCHIVE_ENTRY_ACL_TYPE_AUDIT: - r = acl_set_entry_type_np(acl_entry, - ACL_ENTRY_TYPE_AUDIT); - break; - case ARCHIVE_ENTRY_ACL_TYPE_ALARM: - r = acl_set_entry_type_np(acl_entry, - ACL_ENTRY_TYPE_ALARM); - break; - case ARCHIVE_ENTRY_ACL_TYPE_ACCESS: - case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT: - // These don't translate directly into the system ACL. - break; - default: - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Unsupported ACL entry type"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - - if (r != 0) { - archive_set_error(a, errno, - "Failed to set ACL entry type"); - ret = ARCHIVE_FAILED; - goto exit_free; - } -#endif - - if (acl_get_permset(acl_entry, &acl_permset) != 0) { - archive_set_error(a, errno, - "Failed to get ACL permission set"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - if (acl_clear_perms(acl_permset) != 0) { - archive_set_error(a, errno, - "Failed to clear ACL permissions"); - ret = ARCHIVE_FAILED; - goto exit_free; - } -#if ARCHIVE_ACL_FREEBSD_NFS4 - if (ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - perm_map_size = acl_nfs4_perm_map_size; - perm_map = acl_nfs4_perm_map; - } else { -#endif - perm_map_size = acl_posix_perm_map_size; - perm_map = acl_posix_perm_map; -#if ARCHIVE_ACL_FREEBSD_NFS4 - } -#endif - - for (i = 0; i < perm_map_size; ++i) { - if (ae_permset & perm_map[i].a_perm) { - if (acl_add_perm(acl_permset, - perm_map[i].p_perm) != 0) { - archive_set_error(a, errno, - "Failed to add ACL permission"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - } - } - -#if ARCHIVE_ACL_FREEBSD_NFS4 - if (ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - /* - * acl_get_flagset_np() fails with non-NFSv4 ACLs - */ - if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) { - archive_set_error(a, errno, - "Failed to get flagset from an NFSv4 " - "ACL entry"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - if (acl_clear_flags_np(acl_flagset) != 0) { - archive_set_error(a, errno, - "Failed to clear flags from an NFSv4 " - "ACL flagset"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - for (i = 0; i < acl_nfs4_flag_map_size; ++i) { - if (ae_permset & acl_nfs4_flag_map[i].a_perm) { - if (acl_add_flag_np(acl_flagset, - acl_nfs4_flag_map[i].p_perm) != 0) { - archive_set_error(a, errno, - "Failed to add flag to " - "NFSv4 ACL flagset"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - } - } - } -#endif - } - - /* Try restoring the ACL through 'fd' if we can. */ - if (fd >= 0) { - if (acl_set_fd_np(fd, acl, acl_type) == 0) - ret = ARCHIVE_OK; - else { - if (errno == EOPNOTSUPP) { - /* Filesystem doesn't support ACLs */ - ret = ARCHIVE_OK; - } else { - archive_set_error(a, errno, - "Failed to set acl on fd: %s", tname); - ret = ARCHIVE_WARN; - } - } - } -#if HAVE_ACL_SET_LINK_NP - else if (acl_set_link_np(name, acl_type, acl) != 0) -#else - /* FreeBSD older than 8.0 */ - else if (S_ISLNK(mode)) { - /* acl_set_file() follows symbolic links, skip */ - ret = ARCHIVE_OK; - } else if (acl_set_file(name, acl_type, acl) != 0) -#endif - { - if (errno == EOPNOTSUPP) { - /* Filesystem doesn't support ACLs */ - ret = ARCHIVE_OK; - } else { - archive_set_error(a, errno, "Failed to set acl: %s", - tname); - ret = ARCHIVE_WARN; - } - } -exit_free: - acl_free(acl); - return (ret); -} - -int -archive_read_disk_entry_setup_acls(struct archive_read_disk *a, - struct archive_entry *entry, int *fd) -{ - const char *accpath; - acl_t acl; - int r; - - accpath = NULL; - - if (*fd < 0) { - accpath = archive_read_disk_entry_setup_path(a, entry, fd); - if (accpath == NULL) - return (ARCHIVE_WARN); - } - - archive_entry_acl_clear(entry); - - acl = NULL; - -#if ARCHIVE_ACL_FREEBSD_NFS4 - /* Try NFSv4 ACL first. */ - if (*fd >= 0) - acl = acl_get_fd_np(*fd, ACL_TYPE_NFS4); - else if (!a->follow_symlinks) - acl = acl_get_link_np(accpath, ACL_TYPE_NFS4); - else - acl = acl_get_file(accpath, ACL_TYPE_NFS4); - - /* Ignore "trivial" ACLs that just mirror the file mode. */ - if (acl != NULL && acl_is_trivial_np(acl, &r) == 0 && r == 1) { - acl_free(acl); - acl = NULL; - return (ARCHIVE_OK); - } - - if (acl != NULL) { - r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4); - acl_free(acl); - acl = NULL; - - if (r != ARCHIVE_OK) { - archive_set_error(&a->archive, errno, - "Couldn't translate NFSv4 ACLs"); - } - - return (r); - } -#endif - - /* Retrieve access ACL from file. */ - if (*fd >= 0) - acl = acl_get_fd_np(*fd, ACL_TYPE_ACCESS); -#if HAVE_ACL_GET_LINK_NP - else if (!a->follow_symlinks) - acl = acl_get_link_np(accpath, ACL_TYPE_ACCESS); -#else - else if ((!a->follow_symlinks) - && (archive_entry_filetype(entry) == AE_IFLNK)) - /* We can't get the ACL of a symlink, so we assume it can't - have one. */ - acl = NULL; -#endif - else - acl = acl_get_file(accpath, ACL_TYPE_ACCESS); - -#if HAVE_ACL_IS_TRIVIAL_NP - /* Ignore "trivial" ACLs that just mirror the file mode. */ - if (acl != NULL && acl_is_trivial_np(acl, &r) == 0 && r == 1) { - acl_free(acl); - acl = NULL; - } -#endif - - if (acl != NULL) { - r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_ACCESS); - acl_free(acl); - acl = NULL; - - if (r != ARCHIVE_OK) { - archive_set_error(&a->archive, errno, - "Couldn't translate access ACLs"); - return (r); - } - } - - /* Only directories can have default ACLs. */ - if (S_ISDIR(archive_entry_mode(entry))) { - if (*fd >= 0) - acl = acl_get_fd_np(*fd, ACL_TYPE_DEFAULT); - else - acl = acl_get_file(accpath, ACL_TYPE_DEFAULT); - if (acl != NULL) { - r = translate_acl(a, entry, acl, - ARCHIVE_ENTRY_ACL_TYPE_DEFAULT); - acl_free(acl); - if (r != ARCHIVE_OK) { - archive_set_error(&a->archive, errno, - "Couldn't translate default ACLs"); - return (r); - } - } - } - return (ARCHIVE_OK); -} - -int -archive_write_disk_set_acls(struct archive *a, int fd, const char *name, - struct archive_acl *abstract_acl, __LA_MODE_T mode) -{ - int ret = ARCHIVE_OK; - - (void)mode; /* UNUSED */ - - if ((archive_acl_types(abstract_acl) - & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) { - if ((archive_acl_types(abstract_acl) - & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) { - ret = set_acl(a, fd, name, abstract_acl, mode, - ARCHIVE_ENTRY_ACL_TYPE_ACCESS, "access"); - if (ret != ARCHIVE_OK) - return (ret); - } - if ((archive_acl_types(abstract_acl) - & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0) - ret = set_acl(a, fd, name, abstract_acl, mode, - ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default"); - - /* Simultaneous POSIX.1e and NFSv4 is not supported */ - return (ret); - } -#if ARCHIVE_ACL_FREEBSD_NFS4 - else if ((archive_acl_types(abstract_acl) & - ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) { - ret = set_acl(a, fd, name, abstract_acl, mode, - ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4"); - } -#endif - return (ret); -} -#endif /* ARCHIVE_ACL_FREEBSD */ diff --git a/thirdparty/libarchive/libarchive/archive_disk_acl_linux.c b/thirdparty/libarchive/libarchive/archive_disk_acl_linux.c deleted file mode 100644 index 31d270535..000000000 --- a/thirdparty/libarchive/libarchive/archive_disk_acl_linux.c +++ /dev/null @@ -1,760 +0,0 @@ -/*- - * Copyright (c) 2003-2009 Tim Kientzle - * Copyright (c) 2010-2012 Michihiro NAKAJIMA - * Copyright (c) 2017 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -#if ARCHIVE_ACL_LIBACL || ARCHIVE_ACL_LIBRICHACL - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif -#if HAVE_ACL_LIBACL_H -#include -#endif -#ifdef HAVE_SYS_ACL_H -#include -#endif -#ifdef HAVE_SYS_RICHACL_H -#include -#endif - -#include "archive_entry.h" -#include "archive_private.h" -#include "archive_read_disk_private.h" -#include "archive_write_disk_private.h" - -typedef struct { - const int a_perm; /* Libarchive permission or flag */ - const int p_perm; /* Platform permission or flag */ -} acl_perm_map_t; - -#if ARCHIVE_ACL_LIBACL -static const acl_perm_map_t acl_posix_perm_map[] = { - {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE}, - {ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE}, - {ARCHIVE_ENTRY_ACL_READ, ACL_READ}, -}; - -static const int acl_posix_perm_map_size = - (int)(sizeof(acl_posix_perm_map)/sizeof(acl_posix_perm_map[0])); -#endif /* ARCHIVE_ACL_LIBACL */ - -#if ARCHIVE_ACL_LIBRICHACL -static const acl_perm_map_t acl_nfs4_perm_map[] = { - {ARCHIVE_ENTRY_ACL_EXECUTE, RICHACE_EXECUTE}, - {ARCHIVE_ENTRY_ACL_READ_DATA, RICHACE_READ_DATA}, - {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, RICHACE_LIST_DIRECTORY}, - {ARCHIVE_ENTRY_ACL_WRITE_DATA, RICHACE_WRITE_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_FILE, RICHACE_ADD_FILE}, - {ARCHIVE_ENTRY_ACL_APPEND_DATA, RICHACE_APPEND_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, RICHACE_ADD_SUBDIRECTORY}, - {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, RICHACE_READ_NAMED_ATTRS}, - {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, RICHACE_WRITE_NAMED_ATTRS}, - {ARCHIVE_ENTRY_ACL_DELETE_CHILD, RICHACE_DELETE_CHILD}, - {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, RICHACE_READ_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, RICHACE_WRITE_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_DELETE, RICHACE_DELETE}, - {ARCHIVE_ENTRY_ACL_READ_ACL, RICHACE_READ_ACL}, - {ARCHIVE_ENTRY_ACL_WRITE_ACL, RICHACE_WRITE_ACL}, - {ARCHIVE_ENTRY_ACL_WRITE_OWNER, RICHACE_WRITE_OWNER}, - {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, RICHACE_SYNCHRONIZE} -}; - -static const int acl_nfs4_perm_map_size = - (int)(sizeof(acl_nfs4_perm_map)/sizeof(acl_nfs4_perm_map[0])); - -static const acl_perm_map_t acl_nfs4_flag_map[] = { - {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, RICHACE_FILE_INHERIT_ACE}, - {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, RICHACE_DIRECTORY_INHERIT_ACE}, - {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, RICHACE_NO_PROPAGATE_INHERIT_ACE}, - {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, RICHACE_INHERIT_ONLY_ACE}, - {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, RICHACE_INHERITED_ACE} -}; - -static const int acl_nfs4_flag_map_size = - (int)(sizeof(acl_nfs4_flag_map)/sizeof(acl_nfs4_flag_map[0])); -#endif /* ARCHIVE_ACL_LIBRICHACL */ - -#if ARCHIVE_ACL_LIBACL -/* - * Translate POSIX.1e ACLs into libarchive internal structure - */ -static int -translate_acl(struct archive_read_disk *a, - struct archive_entry *entry, acl_t acl, int default_entry_acl_type) -{ - acl_tag_t acl_tag; - acl_entry_t acl_entry; - acl_permset_t acl_permset; - int i, entry_acl_type; - int r, s, ae_id, ae_tag, ae_perm; - void *q; - const char *ae_name; - - s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry); - if (s == -1) { - archive_set_error(&a->archive, errno, - "Failed to get first ACL entry"); - return (ARCHIVE_WARN); - } - - while (s == 1) { - ae_id = -1; - ae_name = NULL; - ae_perm = 0; - - if (acl_get_tag_type(acl_entry, &acl_tag) != 0) { - archive_set_error(&a->archive, errno, - "Failed to get ACL tag type"); - return (ARCHIVE_WARN); - } - switch (acl_tag) { - case ACL_USER: - q = acl_get_qualifier(acl_entry); - if (q != NULL) { - ae_id = (int)*(uid_t *)q; - acl_free(q); - ae_name = archive_read_disk_uname(&a->archive, - ae_id); - } - ae_tag = ARCHIVE_ENTRY_ACL_USER; - break; - case ACL_GROUP: - q = acl_get_qualifier(acl_entry); - if (q != NULL) { - ae_id = (int)*(gid_t *)q; - acl_free(q); - ae_name = archive_read_disk_gname(&a->archive, - ae_id); - } - ae_tag = ARCHIVE_ENTRY_ACL_GROUP; - break; - case ACL_MASK: - ae_tag = ARCHIVE_ENTRY_ACL_MASK; - break; - case ACL_USER_OBJ: - ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ; - break; - case ACL_GROUP_OBJ: - ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ; - break; - case ACL_OTHER: - ae_tag = ARCHIVE_ENTRY_ACL_OTHER; - break; - default: - /* Skip types that libarchive can't support. */ - s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry); - continue; - } - - // XXX acl_type maps to allow/deny/audit/YYYY bits - entry_acl_type = default_entry_acl_type; - - if (acl_get_permset(acl_entry, &acl_permset) != 0) { - archive_set_error(&a->archive, errno, - "Failed to get ACL permission set"); - return (ARCHIVE_WARN); - } - - for (i = 0; i < acl_posix_perm_map_size; ++i) { - r = acl_get_perm(acl_permset, - acl_posix_perm_map[i].p_perm); - if (r == -1) { - archive_set_error(&a->archive, errno, - "Failed to check permission in an ACL " - "permission set"); - return (ARCHIVE_WARN); - } else if (r) - ae_perm |= acl_posix_perm_map[i].a_perm; - } - - archive_entry_acl_add_entry(entry, entry_acl_type, - ae_perm, ae_tag, - ae_id, ae_name); - - s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry); - if (s == -1) { - archive_set_error(&a->archive, errno, - "Failed to get next ACL entry"); - return (ARCHIVE_WARN); - } - } - return (ARCHIVE_OK); -} -#endif /* ARCHIVE_ACL_LIBACL */ - -#if ARCHIVE_ACL_LIBRICHACL -/* - * Translate RichACL into libarchive internal ACL - */ -static int -translate_richacl(struct archive_read_disk *a, struct archive_entry *entry, - struct richacl *richacl) -{ - int ae_id, ae_tag, ae_perm; - int entry_acl_type, i; - const char *ae_name; - - struct richace *richace; - - richacl_for_each_entry(richace, richacl) { - ae_name = NULL; - ae_tag = 0; - ae_perm = 0; - ae_id = -1; - - switch (richace->e_type) { - case RICHACE_ACCESS_ALLOWED_ACE_TYPE: - entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW; - break; - case RICHACE_ACCESS_DENIED_ACE_TYPE: - entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY; - break; - default: /* Unknown entry type, skip */ - continue; - } - - /* Unsupported */ - if (richace->e_flags & RICHACE_UNMAPPED_WHO) - continue; - - if (richace->e_flags & RICHACE_SPECIAL_WHO) { - switch (richace->e_id) { - case RICHACE_OWNER_SPECIAL_ID: - ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ; - break; - case RICHACE_GROUP_SPECIAL_ID: - ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ; - break; - case RICHACE_EVERYONE_SPECIAL_ID: - ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE; - break; - default: /* Unknown special ID type */ - continue; - } - } else { - ae_id = richace->e_id; - if (richace->e_flags & RICHACE_IDENTIFIER_GROUP) { - ae_tag = ARCHIVE_ENTRY_ACL_GROUP; - ae_name = archive_read_disk_gname(&a->archive, - (gid_t)(richace->e_id)); - } else { - ae_tag = ARCHIVE_ENTRY_ACL_USER; - ae_name = archive_read_disk_uname(&a->archive, - (uid_t)(richace->e_id)); - } - } - for (i = 0; i < acl_nfs4_flag_map_size; ++i) { - if ((richace->e_flags & - acl_nfs4_flag_map[i].p_perm) != 0) - ae_perm |= acl_nfs4_flag_map[i].a_perm; - } - for (i = 0; i < acl_nfs4_perm_map_size; ++i) { - if ((richace->e_mask & - acl_nfs4_perm_map[i].p_perm) != 0) - ae_perm |= - acl_nfs4_perm_map[i].a_perm; - } - - archive_entry_acl_add_entry(entry, entry_acl_type, - ae_perm, ae_tag, ae_id, ae_name); - } - return (ARCHIVE_OK); -} -#endif /* ARCHIVE_ACL_LIBRICHACL */ - -#if ARCHIVE_ACL_LIBRICHACL -static int -_richacl_mode_to_mask(short mode) -{ - int mask = 0; - - if (mode & S_IROTH) - mask |= RICHACE_POSIX_MODE_READ; - if (mode & S_IWOTH) - mask |= RICHACE_POSIX_MODE_WRITE; - if (mode & S_IXOTH) - mask |= RICHACE_POSIX_MODE_EXEC; - - return (mask); -} - -static void -_richacl_mode_to_masks(struct richacl *richacl, __LA_MODE_T mode) -{ - richacl->a_owner_mask = _richacl_mode_to_mask((mode & 0700) >> 6); - richacl->a_group_mask = _richacl_mode_to_mask((mode & 0070) >> 3); - richacl->a_other_mask = _richacl_mode_to_mask(mode & 0007); -} -#endif /* ARCHIVE_ACL_LIBRICHACL */ - -#if ARCHIVE_ACL_LIBRICHACL -static int -set_richacl(struct archive *a, int fd, const char *name, - struct archive_acl *abstract_acl, __LA_MODE_T mode, - int ae_requested_type, const char *tname) -{ - int ae_type, ae_permset, ae_tag, ae_id; - uid_t ae_uid; - gid_t ae_gid; - const char *ae_name; - int entries; - int i; - int ret; - int e = 0; - struct richacl *richacl = NULL; - struct richace *richace; - - ret = ARCHIVE_OK; - entries = archive_acl_reset(abstract_acl, ae_requested_type); - if (entries == 0) - return (ARCHIVE_OK); - - if (ae_requested_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - errno = ENOENT; - archive_set_error(a, errno, "Unsupported ACL type"); - return (ARCHIVE_FAILED); - } - - if (S_ISLNK(mode)) { - /* Linux does not support RichACLs on symbolic links */ - return (ARCHIVE_OK); - } - - richacl = richacl_alloc(entries); - if (richacl == NULL) { - archive_set_error(a, errno, - "Failed to initialize RichACL working storage"); - return (ARCHIVE_FAILED); - } - - e = 0; - - while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type, - &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) { - richace = &(richacl->a_entries[e]); - - richace->e_flags = 0; - richace->e_mask = 0; - - switch (ae_tag) { - case ARCHIVE_ENTRY_ACL_USER: - ae_uid = archive_write_disk_uid(a, ae_name, ae_id); - richace->e_id = ae_uid; - break; - case ARCHIVE_ENTRY_ACL_GROUP: - ae_gid = archive_write_disk_gid(a, ae_name, ae_id); - richace->e_id = ae_gid; - richace->e_flags |= RICHACE_IDENTIFIER_GROUP; - break; - case ARCHIVE_ENTRY_ACL_USER_OBJ: - richace->e_flags |= RICHACE_SPECIAL_WHO; - richace->e_id = RICHACE_OWNER_SPECIAL_ID; - break; - case ARCHIVE_ENTRY_ACL_GROUP_OBJ: - richace->e_flags |= RICHACE_SPECIAL_WHO; - richace->e_id = RICHACE_GROUP_SPECIAL_ID; - break; - case ARCHIVE_ENTRY_ACL_EVERYONE: - richace->e_flags |= RICHACE_SPECIAL_WHO; - richace->e_id = RICHACE_EVERYONE_SPECIAL_ID; - break; - default: - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Unsupported ACL tag"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - - switch (ae_type) { - case ARCHIVE_ENTRY_ACL_TYPE_ALLOW: - richace->e_type = - RICHACE_ACCESS_ALLOWED_ACE_TYPE; - break; - case ARCHIVE_ENTRY_ACL_TYPE_DENY: - richace->e_type = - RICHACE_ACCESS_DENIED_ACE_TYPE; - break; - case ARCHIVE_ENTRY_ACL_TYPE_AUDIT: - case ARCHIVE_ENTRY_ACL_TYPE_ALARM: - break; - default: - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Unsupported ACL entry type"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - - for (i = 0; i < acl_nfs4_perm_map_size; ++i) { - if (ae_permset & acl_nfs4_perm_map[i].a_perm) - richace->e_mask |= acl_nfs4_perm_map[i].p_perm; - } - - for (i = 0; i < acl_nfs4_flag_map_size; ++i) { - if (ae_permset & - acl_nfs4_flag_map[i].a_perm) - richace->e_flags |= acl_nfs4_flag_map[i].p_perm; - } - e++; - } - - /* Fill RichACL masks */ - _richacl_mode_to_masks(richacl, mode); - - if (fd >= 0) { - if (richacl_set_fd(fd, richacl) == 0) - ret = ARCHIVE_OK; - else { - if (errno == EOPNOTSUPP) { - /* Filesystem doesn't support ACLs */ - ret = ARCHIVE_OK; - } else { - archive_set_error(a, errno, - "Failed to set richacl on fd: %s", tname); - ret = ARCHIVE_WARN; - } - } - } else if (richacl_set_file(name, richacl) != 0) { - if (errno == EOPNOTSUPP) { - /* Filesystem doesn't support ACLs */ - ret = ARCHIVE_OK; - } else { - archive_set_error(a, errno, "Failed to set richacl: %s", - tname); - ret = ARCHIVE_WARN; - } - } -exit_free: - richacl_free(richacl); - return (ret); -} -#endif /* ARCHIVE_ACL_RICHACL */ - -#if ARCHIVE_ACL_LIBACL -static int -set_acl(struct archive *a, int fd, const char *name, - struct archive_acl *abstract_acl, __LA_MODE_T mode, - int ae_requested_type, const char *tname) -{ - int acl_type = 0; - int ae_type, ae_permset, ae_tag, ae_id; - uid_t ae_uid; - gid_t ae_gid; - const char *ae_name; - int entries; - int i; - int ret; - acl_t acl = NULL; - acl_entry_t acl_entry; - acl_permset_t acl_permset; - - ret = ARCHIVE_OK; - entries = archive_acl_reset(abstract_acl, ae_requested_type); - if (entries == 0) - return (ARCHIVE_OK); - - switch (ae_requested_type) { - case ARCHIVE_ENTRY_ACL_TYPE_ACCESS: - acl_type = ACL_TYPE_ACCESS; - break; - case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT: - acl_type = ACL_TYPE_DEFAULT; - break; - default: - errno = ENOENT; - archive_set_error(a, errno, "Unsupported ACL type"); - return (ARCHIVE_FAILED); - } - - if (S_ISLNK(mode)) { - /* Linux does not support ACLs on symbolic links */ - return (ARCHIVE_OK); - } - - if (acl_type == ACL_TYPE_DEFAULT && !S_ISDIR(mode)) { - errno = EINVAL; - archive_set_error(a, errno, - "Cannot set default ACL on non-directory"); - return (ARCHIVE_WARN); - } - - acl = acl_init(entries); - if (acl == (acl_t)NULL) { - archive_set_error(a, errno, - "Failed to initialize ACL working storage"); - return (ARCHIVE_FAILED); - } - - while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type, - &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) { - - if (acl_create_entry(&acl, &acl_entry) != 0) { - archive_set_error(a, errno, - "Failed to create a new ACL entry"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - - switch (ae_tag) { - case ARCHIVE_ENTRY_ACL_USER: - ae_uid = archive_write_disk_uid(a, ae_name, ae_id); - acl_set_tag_type(acl_entry, ACL_USER); - acl_set_qualifier(acl_entry, &ae_uid); - break; - case ARCHIVE_ENTRY_ACL_GROUP: - ae_gid = archive_write_disk_gid(a, ae_name, ae_id); - acl_set_tag_type(acl_entry, ACL_GROUP); - acl_set_qualifier(acl_entry, &ae_gid); - break; - case ARCHIVE_ENTRY_ACL_USER_OBJ: - acl_set_tag_type(acl_entry, ACL_USER_OBJ); - break; - case ARCHIVE_ENTRY_ACL_GROUP_OBJ: - acl_set_tag_type(acl_entry, ACL_GROUP_OBJ); - break; - case ARCHIVE_ENTRY_ACL_MASK: - acl_set_tag_type(acl_entry, ACL_MASK); - break; - case ARCHIVE_ENTRY_ACL_OTHER: - acl_set_tag_type(acl_entry, ACL_OTHER); - break; - default: - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Unsupported ACL tag"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - - if (acl_get_permset(acl_entry, &acl_permset) != 0) { - archive_set_error(a, errno, - "Failed to get ACL permission set"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - if (acl_clear_perms(acl_permset) != 0) { - archive_set_error(a, errno, - "Failed to clear ACL permissions"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - - for (i = 0; i < acl_posix_perm_map_size; ++i) { - if (ae_permset & acl_posix_perm_map[i].a_perm) { - if (acl_add_perm(acl_permset, - acl_posix_perm_map[i].p_perm) != 0) { - archive_set_error(a, errno, - "Failed to add ACL permission"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - } - } - - } - - if (fd >= 0 && ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS) { - if (acl_set_fd(fd, acl) == 0) - ret = ARCHIVE_OK; - else { - if (errno == EOPNOTSUPP) { - /* Filesystem doesn't support ACLs */ - ret = ARCHIVE_OK; - } else { - archive_set_error(a, errno, - "Failed to set acl on fd: %s", tname); - ret = ARCHIVE_WARN; - } - } - } else if (acl_set_file(name, acl_type, acl) != 0) { - if (errno == EOPNOTSUPP) { - /* Filesystem doesn't support ACLs */ - ret = ARCHIVE_OK; - } else { - archive_set_error(a, errno, "Failed to set acl: %s", - tname); - ret = ARCHIVE_WARN; - } - } -exit_free: - acl_free(acl); - return (ret); -} -#endif /* ARCHIVE_ACL_LIBACL */ - -int -archive_read_disk_entry_setup_acls(struct archive_read_disk *a, - struct archive_entry *entry, int *fd) -{ - const char *accpath; - int r; -#if ARCHIVE_ACL_LIBACL - acl_t acl; -#endif -#if ARCHIVE_ACL_LIBRICHACL - struct richacl *richacl; - mode_t mode; -#endif - - accpath = NULL; - r = ARCHIVE_OK; - - /* For default ACLs we need reachable accpath */ - if (*fd < 0 || S_ISDIR(archive_entry_mode(entry))) { - accpath = archive_read_disk_entry_setup_path(a, entry, fd); - if (accpath == NULL) - return (ARCHIVE_WARN); - } - - archive_entry_acl_clear(entry); - -#if ARCHIVE_ACL_LIBACL - acl = NULL; -#endif -#if ARCHIVE_ACL_LIBRICHACL - richacl = NULL; -#endif - -#if ARCHIVE_ACL_LIBRICHACL - /* Try NFSv4 ACL first. */ - if (*fd >= 0) - richacl = richacl_get_fd(*fd); - else if ((!a->follow_symlinks) - && (archive_entry_filetype(entry) == AE_IFLNK)) - /* We can't get the ACL of a symlink, so we assume it can't - have one */ - richacl = NULL; - else - richacl = richacl_get_file(accpath); - - /* Ignore "trivial" ACLs that just mirror the file mode. */ - if (richacl != NULL) { - mode = archive_entry_mode(entry); - if (richacl_equiv_mode(richacl, &mode) == 0) { - richacl_free(richacl); - richacl = NULL; - return (ARCHIVE_OK); - } - } - - if (richacl != NULL) { - r = translate_richacl(a, entry, richacl); - richacl_free(richacl); - richacl = NULL; - - if (r != ARCHIVE_OK) { - archive_set_error(&a->archive, errno, - "Couldn't translate NFSv4 ACLs"); - } - - return (r); - } -#endif /* ARCHIVE_ACL_LIBRICHACL */ - -#if ARCHIVE_ACL_LIBACL - /* Retrieve access ACL from file. */ - if (*fd >= 0) - acl = acl_get_fd(*fd); - else if ((!a->follow_symlinks) - && (archive_entry_filetype(entry) == AE_IFLNK)) - /* We can't get the ACL of a symlink, so we assume it can't - have one. */ - acl = NULL; - else - acl = acl_get_file(accpath, ACL_TYPE_ACCESS); - - if (acl != NULL) { - r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_ACCESS); - acl_free(acl); - acl = NULL; - - if (r != ARCHIVE_OK) { - archive_set_error(&a->archive, errno, - "Couldn't translate access ACLs"); - return (r); - } - } - - /* Only directories can have default ACLs. */ - if (S_ISDIR(archive_entry_mode(entry))) { - acl = acl_get_file(accpath, ACL_TYPE_DEFAULT); - if (acl != NULL) { - r = translate_acl(a, entry, acl, - ARCHIVE_ENTRY_ACL_TYPE_DEFAULT); - acl_free(acl); - if (r != ARCHIVE_OK) { - archive_set_error(&a->archive, errno, - "Couldn't translate default ACLs"); - return (r); - } - } - } -#endif /* ARCHIVE_ACL_LIBACL */ - return (r); -} - -int -archive_write_disk_set_acls(struct archive *a, int fd, const char *name, - struct archive_acl *abstract_acl, __LA_MODE_T mode) -{ - int ret = ARCHIVE_OK; - -#if !ARCHIVE_ACL_LIBRICHACL - (void)mode; /* UNUSED */ -#endif - -#if ARCHIVE_ACL_LIBRICHACL - if ((archive_acl_types(abstract_acl) - & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) { - ret = set_richacl(a, fd, name, abstract_acl, mode, - ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4"); - } -#if ARCHIVE_ACL_LIBACL - else -#endif -#endif /* ARCHIVE_ACL_LIBRICHACL */ -#if ARCHIVE_ACL_LIBACL - if ((archive_acl_types(abstract_acl) - & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) { - if ((archive_acl_types(abstract_acl) - & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) { - ret = set_acl(a, fd, name, abstract_acl, mode, - ARCHIVE_ENTRY_ACL_TYPE_ACCESS, "access"); - if (ret != ARCHIVE_OK) - return (ret); - } - if ((archive_acl_types(abstract_acl) - & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0) - ret = set_acl(a, fd, name, abstract_acl, mode, - ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default"); - } -#endif /* ARCHIVE_ACL_LIBACL */ - return (ret); -} -#endif /* ARCHIVE_ACL_LIBACL || ARCHIVE_ACL_LIBRICHACL */ diff --git a/thirdparty/libarchive/libarchive/archive_disk_acl_sunos.c b/thirdparty/libarchive/libarchive/archive_disk_acl_sunos.c deleted file mode 100644 index 0ef3ad52e..000000000 --- a/thirdparty/libarchive/libarchive/archive_disk_acl_sunos.c +++ /dev/null @@ -1,824 +0,0 @@ -/*- - * Copyright (c) 2017 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -#if ARCHIVE_ACL_SUNOS - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_ACL_H -#define _ACL_PRIVATE /* For debugging */ -#include -#endif - -#include "archive_entry.h" -#include "archive_private.h" -#include "archive_read_disk_private.h" -#include "archive_write_disk_private.h" - -typedef struct { - const int a_perm; /* Libarchive permission or flag */ - const int p_perm; /* Platform permission or flag */ -} acl_perm_map_t; - -static const acl_perm_map_t acl_posix_perm_map[] = { - {ARCHIVE_ENTRY_ACL_EXECUTE, S_IXOTH }, - {ARCHIVE_ENTRY_ACL_WRITE, S_IWOTH }, - {ARCHIVE_ENTRY_ACL_READ, S_IROTH } -}; - -static const int acl_posix_perm_map_size = - (int)(sizeof(acl_posix_perm_map)/sizeof(acl_posix_perm_map[0])); - -#if ARCHIVE_ACL_SUNOS_NFS4 -static const acl_perm_map_t acl_nfs4_perm_map[] = { - {ARCHIVE_ENTRY_ACL_EXECUTE, ACE_EXECUTE}, - {ARCHIVE_ENTRY_ACL_READ_DATA, ACE_READ_DATA}, - {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACE_LIST_DIRECTORY}, - {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACE_WRITE_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_FILE, ACE_ADD_FILE}, - {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACE_APPEND_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACE_ADD_SUBDIRECTORY}, - {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACE_READ_NAMED_ATTRS}, - {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACE_WRITE_NAMED_ATTRS}, - {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACE_DELETE_CHILD}, - {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACE_READ_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACE_WRITE_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_DELETE, ACE_DELETE}, - {ARCHIVE_ENTRY_ACL_READ_ACL, ACE_READ_ACL}, - {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACE_WRITE_ACL}, - {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACE_WRITE_OWNER}, - {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACE_SYNCHRONIZE} -}; - -static const int acl_nfs4_perm_map_size = - (int)(sizeof(acl_nfs4_perm_map)/sizeof(acl_nfs4_perm_map[0])); - -static const acl_perm_map_t acl_nfs4_flag_map[] = { - {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE}, - {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACE_DIRECTORY_INHERIT_ACE}, - {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACE_NO_PROPAGATE_INHERIT_ACE}, - {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACE_INHERIT_ONLY_ACE}, - {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACE_SUCCESSFUL_ACCESS_ACE_FLAG}, - {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACE_FAILED_ACCESS_ACE_FLAG}, -#ifdef ACE_INHERITED_ACE - {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE} -#endif -}; - -const int acl_nfs4_flag_map_size = - (int)(sizeof(acl_nfs4_flag_map)/sizeof(acl_nfs4_flag_map[0])); - -#endif /* ARCHIVE_ACL_SUNOS_NFS4 */ - -static void * -sunacl_get(int cmd, int *aclcnt, int fd, const char *path) -{ - int cnt, cntcmd; - size_t size; - void *aclp; - - if (cmd == GETACL) { - cntcmd = GETACLCNT; - size = sizeof(aclent_t); - } -#if ARCHIVE_ACL_SUNOS_NFS4 - else if (cmd == ACE_GETACL) { - cntcmd = ACE_GETACLCNT; - size = sizeof(ace_t); - } -#endif - else { - errno = EINVAL; - *aclcnt = -1; - return (NULL); - } - - aclp = NULL; - cnt = -2; - - while (cnt == -2 || (cnt == -1 && errno == ENOSPC)) { - if (path != NULL) - cnt = acl(path, cntcmd, 0, NULL); - else - cnt = facl(fd, cntcmd, 0, NULL); - - if (cnt > 0) { - if (aclp == NULL) - aclp = malloc(cnt * size); - else - aclp = realloc(NULL, cnt * size); - if (aclp != NULL) { - if (path != NULL) - cnt = acl(path, cmd, cnt, aclp); - else - cnt = facl(fd, cmd, cnt, aclp); - } - } else { - free(aclp); - aclp = NULL; - break; - } - } - - *aclcnt = cnt; - return (aclp); -} - -/* - * Check if acl is trivial - * This is a FreeBSD acl_is_trivial_np() implementation for Solaris - */ -static int -sun_acl_is_trivial(void *aclp, int aclcnt, mode_t mode, int is_nfs4, - int is_dir, int *trivialp) -{ -#if ARCHIVE_ACL_SUNOS_NFS4 - int i, p; - const uint32_t rperm = ACE_READ_DATA; - const uint32_t wperm = ACE_WRITE_DATA | ACE_APPEND_DATA; - const uint32_t eperm = ACE_EXECUTE; - const uint32_t pubset = ACE_READ_ATTRIBUTES | ACE_READ_NAMED_ATTRS | - ACE_READ_ACL | ACE_SYNCHRONIZE; - const uint32_t ownset = pubset | ACE_WRITE_ATTRIBUTES | - ACE_WRITE_NAMED_ATTRS | ACE_WRITE_ACL | ACE_WRITE_OWNER; - - ace_t *ace; - ace_t tace[6]; -#endif - - if (aclp == NULL || trivialp == NULL) - return (-1); - - *trivialp = 0; - - /* - * POSIX.1e ACLs marked with ACL_IS_TRIVIAL are compatible with - * FreeBSD acl_is_trivial_np(). On Solaris they have 4 entries, - * including mask. - */ - if (!is_nfs4) { - if (aclcnt == 4) - *trivialp = 1; - return (0); - } - -#if ARCHIVE_ACL_SUNOS_NFS4 - /* - * Continue with checking NFSv4 ACLs - * - * Create list of trivial ace's to be compared - */ - - /* owner@ allow pre */ - tace[0].a_flags = ACE_OWNER; - tace[0].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE; - tace[0].a_access_mask = 0; - - /* owner@ deny */ - tace[1].a_flags = ACE_OWNER; - tace[1].a_type = ACE_ACCESS_DENIED_ACE_TYPE; - tace[1].a_access_mask = 0; - - /* group@ deny */ - tace[2].a_flags = ACE_GROUP | ACE_IDENTIFIER_GROUP; - tace[2].a_type = ACE_ACCESS_DENIED_ACE_TYPE; - tace[2].a_access_mask = 0; - - /* owner@ allow */ - tace[3].a_flags = ACE_OWNER; - tace[3].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE; - tace[3].a_access_mask = ownset; - - /* group@ allow */ - tace[4].a_flags = ACE_GROUP | ACE_IDENTIFIER_GROUP; - tace[4].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE; - tace[4].a_access_mask = pubset; - - /* everyone@ allow */ - tace[5].a_flags = ACE_EVERYONE; - tace[5].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE; - tace[5].a_access_mask = pubset; - - /* Permissions for everyone@ */ - if (mode & 0004) - tace[5].a_access_mask |= rperm; - if (mode & 0002) - tace[5].a_access_mask |= wperm; - if (mode & 0001) - tace[5].a_access_mask |= eperm; - - /* Permissions for group@ */ - if (mode & 0040) - tace[4].a_access_mask |= rperm; - else if (mode & 0004) - tace[2].a_access_mask |= rperm; - if (mode & 0020) - tace[4].a_access_mask |= wperm; - else if (mode & 0002) - tace[2].a_access_mask |= wperm; - if (mode & 0010) - tace[4].a_access_mask |= eperm; - else if (mode & 0001) - tace[2].a_access_mask |= eperm; - - /* Permissions for owner@ */ - if (mode & 0400) { - tace[3].a_access_mask |= rperm; - if (!(mode & 0040) && (mode & 0004)) - tace[0].a_access_mask |= rperm; - } else if ((mode & 0040) || (mode & 0004)) - tace[1].a_access_mask |= rperm; - if (mode & 0200) { - tace[3].a_access_mask |= wperm; - if (!(mode & 0020) && (mode & 0002)) - tace[0].a_access_mask |= wperm; - } else if ((mode & 0020) || (mode & 0002)) - tace[1].a_access_mask |= wperm; - if (mode & 0100) { - tace[3].a_access_mask |= eperm; - if (!(mode & 0010) && (mode & 0001)) - tace[0].a_access_mask |= eperm; - } else if ((mode & 0010) || (mode & 0001)) - tace[1].a_access_mask |= eperm; - - /* Check if the acl count matches */ - p = 3; - for (i = 0; i < 3; i++) { - if (tace[i].a_access_mask != 0) - p++; - } - if (aclcnt != p) - return (0); - - p = 0; - for (i = 0; i < 6; i++) { - if (tace[i].a_access_mask != 0) { - ace = &((ace_t *)aclp)[p]; - /* - * Illumos added ACE_DELETE_CHILD to write perms for - * directories. We have to check against that, too. - */ - if (ace->a_flags != tace[i].a_flags || - ace->a_type != tace[i].a_type || - (ace->a_access_mask != tace[i].a_access_mask && - (!is_dir || (tace[i].a_access_mask & wperm) == 0 || - ace->a_access_mask != - (tace[i].a_access_mask | ACE_DELETE_CHILD)))) - return (0); - p++; - } - } - - *trivialp = 1; -#else /* !ARCHIVE_ACL_SUNOS_NFS4 */ - (void)is_dir; /* UNUSED */ - (void)aclp; /* UNUSED */ -#endif /* !ARCHIVE_ACL_SUNOS_NFS4 */ - return (0); -} - -/* - * Translate Solaris POSIX.1e and NFSv4 ACLs into libarchive internal ACL - */ -static int -translate_acl(struct archive_read_disk *a, - struct archive_entry *entry, void *aclp, int aclcnt, - int default_entry_acl_type) -{ - int e, i; - int ae_id, ae_tag, ae_perm; - int entry_acl_type; - const char *ae_name; - aclent_t *aclent; -#if ARCHIVE_ACL_SUNOS_NFS4 - ace_t *ace; -#endif - - if (aclcnt <= 0) - return (ARCHIVE_OK); - - for (e = 0; e < aclcnt; e++) { - ae_name = NULL; - ae_tag = 0; - ae_perm = 0; - -#if ARCHIVE_ACL_SUNOS_NFS4 - if (default_entry_acl_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - ace = &((ace_t *)aclp)[e]; - ae_id = ace->a_who; - - switch(ace->a_type) { - case ACE_ACCESS_ALLOWED_ACE_TYPE: - entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW; - break; - case ACE_ACCESS_DENIED_ACE_TYPE: - entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY; - break; - case ACE_SYSTEM_AUDIT_ACE_TYPE: - entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS; - break; - case ACE_SYSTEM_ALARM_ACE_TYPE: - entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALARM; - break; - default: - /* Unknown entry type, skip */ - continue; - } - - if ((ace->a_flags & ACE_OWNER) != 0) - ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ; - else if ((ace->a_flags & ACE_GROUP) != 0) - ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ; - else if ((ace->a_flags & ACE_EVERYONE) != 0) - ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE; - else if ((ace->a_flags & ACE_IDENTIFIER_GROUP) != 0) { - ae_tag = ARCHIVE_ENTRY_ACL_GROUP; - ae_name = archive_read_disk_gname(&a->archive, - ae_id); - } else { - ae_tag = ARCHIVE_ENTRY_ACL_USER; - ae_name = archive_read_disk_uname(&a->archive, - ae_id); - } - - for (i = 0; i < acl_nfs4_flag_map_size; ++i) { - if ((ace->a_flags & - acl_nfs4_flag_map[i].p_perm) != 0) - ae_perm |= acl_nfs4_flag_map[i].a_perm; - } - - for (i = 0; i < acl_nfs4_perm_map_size; ++i) { - if ((ace->a_access_mask & - acl_nfs4_perm_map[i].p_perm) != 0) - ae_perm |= acl_nfs4_perm_map[i].a_perm; - } - } else -#endif /* ARCHIVE_ACL_SUNOS_NFS4 */ - if (default_entry_acl_type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS) { - aclent = &((aclent_t *)aclp)[e]; - if ((aclent->a_type & ACL_DEFAULT) != 0) - entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT; - else - entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS; - ae_id = aclent->a_id; - - switch(aclent->a_type) { - case DEF_USER: - case USER: - ae_name = archive_read_disk_uname(&a->archive, - ae_id); - ae_tag = ARCHIVE_ENTRY_ACL_USER; - break; - case DEF_GROUP: - case GROUP: - ae_name = archive_read_disk_gname(&a->archive, - ae_id); - ae_tag = ARCHIVE_ENTRY_ACL_GROUP; - break; - case DEF_CLASS_OBJ: - case CLASS_OBJ: - ae_tag = ARCHIVE_ENTRY_ACL_MASK; - break; - case DEF_USER_OBJ: - case USER_OBJ: - ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ; - break; - case DEF_GROUP_OBJ: - case GROUP_OBJ: - ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ; - break; - case DEF_OTHER_OBJ: - case OTHER_OBJ: - ae_tag = ARCHIVE_ENTRY_ACL_OTHER; - break; - default: - /* Unknown tag type, skip */ - continue; - } - - for (i = 0; i < acl_posix_perm_map_size; ++i) { - if ((aclent->a_perm & - acl_posix_perm_map[i].p_perm) != 0) - ae_perm |= acl_posix_perm_map[i].a_perm; - } - } else - return (ARCHIVE_WARN); - - archive_entry_acl_add_entry(entry, entry_acl_type, - ae_perm, ae_tag, ae_id, ae_name); - } - return (ARCHIVE_OK); -} - -static int -set_acl(struct archive *a, int fd, const char *name, - struct archive_acl *abstract_acl, __LA_MODE_T mode, - int ae_requested_type, const char *tname) -{ - aclent_t *aclent; -#if ARCHIVE_ACL_SUNOS_NFS4 - ace_t *ace; -#endif - int cmd, e, r; - void *aclp; - int ret; - int ae_type, ae_permset, ae_tag, ae_id; - int perm_map_size; - const acl_perm_map_t *perm_map; - uid_t ae_uid; - gid_t ae_gid; - const char *ae_name; - int entries; - int i; - - ret = ARCHIVE_OK; - entries = archive_acl_reset(abstract_acl, ae_requested_type); - if (entries == 0) - return (ARCHIVE_OK); - - switch (ae_requested_type) { - case ARCHIVE_ENTRY_ACL_TYPE_POSIX1E: - cmd = SETACL; - aclp = malloc(entries * sizeof(aclent_t)); - break; -#if ARCHIVE_ACL_SUNOS_NFS4 - case ARCHIVE_ENTRY_ACL_TYPE_NFS4: - cmd = ACE_SETACL; - aclp = malloc(entries * sizeof(ace_t)); - - break; -#endif - default: - errno = ENOENT; - archive_set_error(a, errno, "Unsupported ACL type"); - return (ARCHIVE_FAILED); - } - - if (aclp == NULL) { - archive_set_error(a, errno, - "Can't allocate memory for acl buffer"); - return (ARCHIVE_FAILED); - } - - if (S_ISLNK(mode)) { - /* Skip ACLs on symbolic links */ - ret = ARCHIVE_OK; - goto exit_free; - } - - e = 0; - - while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type, - &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) { - aclent = NULL; -#if ARCHIVE_ACL_SUNOS_NFS4 - ace = NULL; -#endif - if (cmd == SETACL) { - aclent = &((aclent_t *)aclp)[e]; - aclent->a_id = -1; - aclent->a_type = 0; - aclent->a_perm = 0; - } -#if ARCHIVE_ACL_SUNOS_NFS4 - else { /* cmd == ACE_SETACL */ - ace = &((ace_t *)aclp)[e]; - ace->a_who = -1; - ace->a_access_mask = 0; - ace->a_flags = 0; - } -#endif /* ARCHIVE_ACL_SUNOS_NFS4 */ - - switch (ae_tag) { - case ARCHIVE_ENTRY_ACL_USER: - ae_uid = archive_write_disk_uid(a, ae_name, ae_id); - if (aclent != NULL) { - aclent->a_id = ae_uid; - aclent->a_type |= USER; - } -#if ARCHIVE_ACL_SUNOS_NFS4 - else { - ace->a_who = ae_uid; - } -#endif - break; - case ARCHIVE_ENTRY_ACL_GROUP: - ae_gid = archive_write_disk_gid(a, ae_name, ae_id); - if (aclent != NULL) { - aclent->a_id = ae_gid; - aclent->a_type |= GROUP; - } -#if ARCHIVE_ACL_SUNOS_NFS4 - else { - ace->a_who = ae_gid; - ace->a_flags |= ACE_IDENTIFIER_GROUP; - } -#endif - break; - case ARCHIVE_ENTRY_ACL_USER_OBJ: - if (aclent != NULL) - aclent->a_type |= USER_OBJ; -#if ARCHIVE_ACL_SUNOS_NFS4 - else { - ace->a_flags |= ACE_OWNER; - } -#endif - break; - case ARCHIVE_ENTRY_ACL_GROUP_OBJ: - if (aclent != NULL) - aclent->a_type |= GROUP_OBJ; -#if ARCHIVE_ACL_SUNOS_NFS4 - else { - ace->a_flags |= ACE_GROUP; - ace->a_flags |= ACE_IDENTIFIER_GROUP; - } -#endif - break; - case ARCHIVE_ENTRY_ACL_MASK: - if (aclent != NULL) - aclent->a_type |= CLASS_OBJ; - break; - case ARCHIVE_ENTRY_ACL_OTHER: - if (aclent != NULL) - aclent->a_type |= OTHER_OBJ; - break; -#if ARCHIVE_ACL_SUNOS_NFS4 - case ARCHIVE_ENTRY_ACL_EVERYONE: - if (ace != NULL) - ace->a_flags |= ACE_EVERYONE; - break; -#endif - default: - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Unsupported ACL tag"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - - r = 0; - switch (ae_type) { -#if ARCHIVE_ACL_SUNOS_NFS4 - case ARCHIVE_ENTRY_ACL_TYPE_ALLOW: - if (ace != NULL) - ace->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE; - else - r = -1; - break; - case ARCHIVE_ENTRY_ACL_TYPE_DENY: - if (ace != NULL) - ace->a_type = ACE_ACCESS_DENIED_ACE_TYPE; - else - r = -1; - break; - case ARCHIVE_ENTRY_ACL_TYPE_AUDIT: - if (ace != NULL) - ace->a_type = ACE_SYSTEM_AUDIT_ACE_TYPE; - else - r = -1; - break; - case ARCHIVE_ENTRY_ACL_TYPE_ALARM: - if (ace != NULL) - ace->a_type = ACE_SYSTEM_ALARM_ACE_TYPE; - else - r = -1; - break; -#endif - case ARCHIVE_ENTRY_ACL_TYPE_ACCESS: - if (aclent == NULL) - r = -1; - break; - case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT: - if (aclent != NULL) - aclent->a_type |= ACL_DEFAULT; - else - r = -1; - break; - default: - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Unsupported ACL entry type"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - - if (r != 0) { - errno = EINVAL; - archive_set_error(a, errno, - "Failed to set ACL entry type"); - ret = ARCHIVE_FAILED; - goto exit_free; - } - -#if ARCHIVE_ACL_SUNOS_NFS4 - if (ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - perm_map_size = acl_nfs4_perm_map_size; - perm_map = acl_nfs4_perm_map; - } else { -#endif - perm_map_size = acl_posix_perm_map_size; - perm_map = acl_posix_perm_map; -#if ARCHIVE_ACL_SUNOS_NFS4 - } -#endif - for (i = 0; i < perm_map_size; ++i) { - if (ae_permset & perm_map[i].a_perm) { -#if ARCHIVE_ACL_SUNOS_NFS4 - if (ae_requested_type == - ARCHIVE_ENTRY_ACL_TYPE_NFS4) - ace->a_access_mask |= - perm_map[i].p_perm; - else -#endif - aclent->a_perm |= perm_map[i].p_perm; - } - } - -#if ARCHIVE_ACL_SUNOS_NFS4 - if (ae_requested_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) { - for (i = 0; i < acl_nfs4_flag_map_size; ++i) { - if (ae_permset & acl_nfs4_flag_map[i].a_perm) { - ace->a_flags |= - acl_nfs4_flag_map[i].p_perm; - } - } - } -#endif - e++; - } - - /* Try restoring the ACL through 'fd' if we can. */ - if (fd >= 0) { - if (facl(fd, cmd, entries, aclp) == 0) - ret = ARCHIVE_OK; - else { - if (errno == EOPNOTSUPP) { - /* Filesystem doesn't support ACLs */ - ret = ARCHIVE_OK; - } else { - archive_set_error(a, errno, - "Failed to set acl on fd: %s", tname); - ret = ARCHIVE_WARN; - } - } - } else if (acl(name, cmd, entries, aclp) != 0) { - if (errno == EOPNOTSUPP) { - /* Filesystem doesn't support ACLs */ - ret = ARCHIVE_OK; - } else { - archive_set_error(a, errno, "Failed to set acl: %s", - tname); - ret = ARCHIVE_WARN; - } - } -exit_free: - free(aclp); - return (ret); -} - -int -archive_read_disk_entry_setup_acls(struct archive_read_disk *a, - struct archive_entry *entry, int *fd) -{ - const char *accpath; - void *aclp; - int aclcnt; - int r; - - accpath = NULL; - - if (*fd < 0) { - accpath = archive_read_disk_entry_setup_path(a, entry, fd); - if (accpath == NULL) - return (ARCHIVE_WARN); - } - - archive_entry_acl_clear(entry); - - aclp = NULL; - -#if ARCHIVE_ACL_SUNOS_NFS4 - if (*fd >= 0) - aclp = sunacl_get(ACE_GETACL, &aclcnt, *fd, NULL); - else if ((!a->follow_symlinks) - && (archive_entry_filetype(entry) == AE_IFLNK)) - /* We can't get the ACL of a symlink, so we assume it can't - have one. */ - aclp = NULL; - else - aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, accpath); - - if (aclp != NULL && sun_acl_is_trivial(aclp, aclcnt, - archive_entry_mode(entry), 1, S_ISDIR(archive_entry_mode(entry)), - &r) == 0 && r == 1) { - free(aclp); - aclp = NULL; - return (ARCHIVE_OK); - } - - if (aclp != NULL) { - r = translate_acl(a, entry, aclp, aclcnt, - ARCHIVE_ENTRY_ACL_TYPE_NFS4); - free(aclp); - aclp = NULL; - - if (r != ARCHIVE_OK) { - archive_set_error(&a->archive, errno, - "Couldn't translate NFSv4 ACLs"); - } - return (r); - } -#endif /* ARCHIVE_ACL_SUNOS_NFS4 */ - - /* Retrieve POSIX.1e ACLs from file. */ - if (*fd >= 0) - aclp = sunacl_get(GETACL, &aclcnt, *fd, NULL); - else if ((!a->follow_symlinks) - && (archive_entry_filetype(entry) == AE_IFLNK)) - /* We can't get the ACL of a symlink, so we assume it can't - have one. */ - aclp = NULL; - else - aclp = sunacl_get(GETACL, &aclcnt, 0, accpath); - - /* Ignore "trivial" ACLs that just mirror the file mode. */ - if (aclp != NULL && sun_acl_is_trivial(aclp, aclcnt, - archive_entry_mode(entry), 0, S_ISDIR(archive_entry_mode(entry)), - &r) == 0 && r == 1) { - free(aclp); - aclp = NULL; - } - - if (aclp != NULL) - { - r = translate_acl(a, entry, aclp, aclcnt, - ARCHIVE_ENTRY_ACL_TYPE_ACCESS); - free(aclp); - aclp = NULL; - - if (r != ARCHIVE_OK) { - archive_set_error(&a->archive, errno, - "Couldn't translate access ACLs"); - return (r); - } - } - - return (ARCHIVE_OK); -} - -int -archive_write_disk_set_acls(struct archive *a, int fd, const char *name, - struct archive_acl *abstract_acl, __LA_MODE_T mode) -{ - int ret = ARCHIVE_OK; - - (void)mode; /* UNUSED */ - - if ((archive_acl_types(abstract_acl) - & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) { - /* Solaris writes POSIX.1e access and default ACLs together */ - ret = set_acl(a, fd, name, abstract_acl, mode, - ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, "posix1e"); - - /* Simultaneous POSIX.1e and NFSv4 is not supported */ - return (ret); - } -#if ARCHIVE_ACL_SUNOS_NFS4 - else if ((archive_acl_types(abstract_acl) & - ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) { - ret = set_acl(a, fd, name, abstract_acl, mode, - ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4"); - } -#endif - return (ret); -} -#endif /* ARCHIVE_ACL_SUNOS */ diff --git a/thirdparty/libarchive/libarchive/archive_endian.h b/thirdparty/libarchive/libarchive/archive_endian.h deleted file mode 100644 index e6d3f2ce5..000000000 --- a/thirdparty/libarchive/libarchive/archive_endian.h +++ /dev/null @@ -1,195 +0,0 @@ -/*- - * Copyright (c) 2002 Thomas Moestl - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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: head/lib/libarchive/archive_endian.h 201085 2009-12-28 02:17:15Z kientzle $ - * - * Borrowed from FreeBSD's - */ - -#ifndef ARCHIVE_ENDIAN_H_INCLUDED -#define ARCHIVE_ENDIAN_H_INCLUDED - -/* Note: This is a purely internal header! */ -/* Do not use this outside of libarchive internal code! */ - -#ifndef __LIBARCHIVE_BUILD -#error This header is only to be used internally to libarchive. -#endif - -/* - * Disabling inline keyword for compilers known to choke on it: - * - Watcom C++ in C code. (For any version?) - * - SGI MIPSpro - * - Microsoft Visual C++ 6.0 (supposedly newer versions too) - * - IBM VisualAge 6 (XL v6) - * - Sun WorkShop C (SunPro) before 5.9 - */ -#if defined(__WATCOMC__) || defined(__sgi) || defined(__hpux) || defined(__BORLANDC__) -#define inline -#elif defined(__IBMC__) && __IBMC__ < 700 -#define inline -#elif defined(__SUNPRO_C) && __SUNPRO_C < 0x590 -#define inline -#elif defined(_MSC_VER) || defined(__osf__) -#define inline __inline -#endif - -/* Alignment-agnostic encode/decode bytestream to/from little/big endian. */ - -static inline uint16_t -archive_be16dec(const void *pp) -{ - unsigned char const *p = (unsigned char const *)pp; - - /* Store into unsigned temporaries before left shifting, to avoid - promotion to signed int and then left shifting into the sign bit, - which is undefined behaviour. */ - unsigned int p1 = p[1]; - unsigned int p0 = p[0]; - - return ((p0 << 8) | p1); -} - -static inline uint32_t -archive_be32dec(const void *pp) -{ - unsigned char const *p = (unsigned char const *)pp; - - /* Store into unsigned temporaries before left shifting, to avoid - promotion to signed int and then left shifting into the sign bit, - which is undefined behaviour. */ - unsigned int p3 = p[3]; - unsigned int p2 = p[2]; - unsigned int p1 = p[1]; - unsigned int p0 = p[0]; - - return ((p0 << 24) | (p1 << 16) | (p2 << 8) | p3); -} - -static inline uint64_t -archive_be64dec(const void *pp) -{ - unsigned char const *p = (unsigned char const *)pp; - - return (((uint64_t)archive_be32dec(p) << 32) | archive_be32dec(p + 4)); -} - -static inline uint16_t -archive_le16dec(const void *pp) -{ - unsigned char const *p = (unsigned char const *)pp; - - /* Store into unsigned temporaries before left shifting, to avoid - promotion to signed int and then left shifting into the sign bit, - which is undefined behaviour. */ - unsigned int p1 = p[1]; - unsigned int p0 = p[0]; - - return ((p1 << 8) | p0); -} - -static inline uint32_t -archive_le32dec(const void *pp) -{ - unsigned char const *p = (unsigned char const *)pp; - - /* Store into unsigned temporaries before left shifting, to avoid - promotion to signed int and then left shifting into the sign bit, - which is undefined behaviour. */ - unsigned int p3 = p[3]; - unsigned int p2 = p[2]; - unsigned int p1 = p[1]; - unsigned int p0 = p[0]; - - return ((p3 << 24) | (p2 << 16) | (p1 << 8) | p0); -} - -static inline uint64_t -archive_le64dec(const void *pp) -{ - unsigned char const *p = (unsigned char const *)pp; - - return (((uint64_t)archive_le32dec(p + 4) << 32) | archive_le32dec(p)); -} - -static inline void -archive_be16enc(void *pp, uint16_t u) -{ - unsigned char *p = (unsigned char *)pp; - - p[0] = (u >> 8) & 0xff; - p[1] = u & 0xff; -} - -static inline void -archive_be32enc(void *pp, uint32_t u) -{ - unsigned char *p = (unsigned char *)pp; - - p[0] = (u >> 24) & 0xff; - p[1] = (u >> 16) & 0xff; - p[2] = (u >> 8) & 0xff; - p[3] = u & 0xff; -} - -static inline void -archive_be64enc(void *pp, uint64_t u) -{ - unsigned char *p = (unsigned char *)pp; - - archive_be32enc(p, (uint32_t)(u >> 32)); - archive_be32enc(p + 4, (uint32_t)(u & 0xffffffff)); -} - -static inline void -archive_le16enc(void *pp, uint16_t u) -{ - unsigned char *p = (unsigned char *)pp; - - p[0] = u & 0xff; - p[1] = (u >> 8) & 0xff; -} - -static inline void -archive_le32enc(void *pp, uint32_t u) -{ - unsigned char *p = (unsigned char *)pp; - - p[0] = u & 0xff; - p[1] = (u >> 8) & 0xff; - p[2] = (u >> 16) & 0xff; - p[3] = (u >> 24) & 0xff; -} - -static inline void -archive_le64enc(void *pp, uint64_t u) -{ - unsigned char *p = (unsigned char *)pp; - - archive_le32enc(p, (uint32_t)(u & 0xffffffff)); - archive_le32enc(p + 4, (uint32_t)(u >> 32)); -} - -#endif diff --git a/thirdparty/libarchive/libarchive/archive_entry.3 b/thirdparty/libarchive/libarchive/archive_entry.3 deleted file mode 100644 index 2f62a4be2..000000000 --- a/thirdparty/libarchive/libarchive/archive_entry.3 +++ /dev/null @@ -1,149 +0,0 @@ -.\" Copyright (c) 2003-2007 Tim Kientzle -.\" Copyright (c) 2010 Joerg Sonnenberger -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd February 2, 2012 -.Dt ARCHIVE_ENTRY 3 -.Os -.Sh NAME -.Nm archive_entry_clear , -.Nm archive_entry_clone , -.Nm archive_entry_free , -.Nm archive_entry_new -.Nd functions for managing archive entry descriptions -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive_entry.h -.Ft "struct archive_entry *" -.Fn archive_entry_clear "struct archive_entry *" -.Ft struct archive_entry * -.Fn archive_entry_clone "struct archive_entry *" -.Ft void -.Fn archive_entry_free "struct archive_entry *" -.Ft struct archive_entry * -.Fn archive_entry_new "void" -.Sh DESCRIPTION -These functions create and manipulate data objects that -represent entries within an archive. -You can think of a -.Tn struct archive_entry -as a heavy-duty version of -.Tn struct stat : -it includes everything from -.Tn struct stat -plus associated pathname, textual group and user names, etc. -These objects are used by -.Xr libarchive 3 -to represent the metadata associated with a particular -entry in an archive. -.Ss Create and Destroy -There are functions to allocate, destroy, clear, and copy -.Va archive_entry -objects: -.Bl -tag -compact -width indent -.It Fn archive_entry_clear -Erases the object, resetting all internal fields to the -same state as a newly-created object. -This is provided to allow you to quickly recycle objects -without thrashing the heap. -.It Fn archive_entry_clone -A deep copy operation; all text fields are duplicated. -.It Fn archive_entry_free -Releases the -.Tn struct archive_entry -object. -.It Fn archive_entry_new -Allocate and return a blank -.Tn struct archive_entry -object. -.El -.Ss Function groups -Due to high number of functions, the accessor functions can be found in -man pages grouped by the purpose. -.Bl -tag -width ".Xr archive_entry_perms 3" -.It Xr archive_entry_acl 3 -Access Control List manipulation -.It Xr archive_entry_paths 3 -Path name manipulation -.It Xr archive_entry_perms 3 -User, group and mode manipulation -.It Xr archive_entry_stat 3 -Functions not in the other groups and copying to/from -.Vt struct stat . -.It Xr archive_entry_time 3 -Time field manipulation -.El -.Pp -Most of the functions set or read entries in an object. -Such functions have one of the following forms: -.Bl -tag -compact -width indent -.It Fn archive_entry_set_XXXX -Stores the provided data in the object. -In particular, for strings, the pointer is stored, -not the referenced string. -.It Fn archive_entry_copy_XXXX -As above, except that the referenced data is copied -into the object. -.It Fn archive_entry_XXXX -Returns the specified data. -In the case of strings, a const-qualified pointer to -the string is returned. -.El -String data can be set or accessed as wide character strings -or normal -.Va char -strings. -The functions that use wide character strings are suffixed with -.Cm _w . -Note that these are different representations of the same data: -For example, if you store a narrow string and read the corresponding -wide string, the object will transparently convert formats -using the current locale. -Similarly, if you store a wide string and then store a -narrow string for the same data, the previously-set wide string will -be discarded in favor of the new data. -.\" .Sh EXAMPLE -.\" .Sh RETURN VALUES -.\" .Sh ERRORS -.Sh SEE ALSO -.Xr archive_entry_acl 3 , -.Xr archive_entry_paths 3 , -.Xr archive_entry_perms 3 , -.Xr archive_entry_time 3 , -.Xr libarchive 3 -.Sh HISTORY -The -.Nm libarchive -library first appeared in -.Fx 5.3 . -.Sh AUTHORS -.An -nosplit -The -.Nm libarchive -library was written by -.An Tim Kientzle Aq kientzle@acm.org . -.\" .Sh BUGS diff --git a/thirdparty/libarchive/libarchive/archive_entry.c b/thirdparty/libarchive/libarchive/archive_entry.c deleted file mode 100644 index ae6dc3336..000000000 --- a/thirdparty/libarchive/libarchive/archive_entry.c +++ /dev/null @@ -1,2149 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2016 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry.c 201096 2009-12-28 02:41:27Z kientzle $"); - -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#if MAJOR_IN_MKDEV -#include -#define HAVE_MAJOR -#elif MAJOR_IN_SYSMACROS -#include -#define HAVE_MAJOR -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_LIMITS_H -#include -#endif -#ifdef HAVE_LINUX_FS_H -#include /* for Linux file flags */ -#endif -/* - * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h. - * As the include guards don't agree, the order of include is important. - */ -#ifdef HAVE_LINUX_EXT2_FS_H -#include /* for Linux file flags */ -#endif -#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__) -#include /* for Linux file flags */ -#endif -#include -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_WCHAR_H -#include -#endif - -#include "archive.h" -#include "archive_acl_private.h" -#include "archive_entry.h" -#include "archive_entry_locale.h" -#include "archive_private.h" -#include "archive_entry_private.h" - -#if !defined(HAVE_MAJOR) && !defined(major) -/* Replacement for major/minor/makedev. */ -#define major(x) ((int)(0x00ff & ((x) >> 8))) -#define minor(x) ((int)(0xffff00ff & (x))) -#define makedev(maj,min) ((0xff00 & ((maj)<<8)) | (0xffff00ff & (min))) -#endif - -/* Play games to come up with a suitable makedev() definition. */ -#ifdef __QNXNTO__ -/* QNX. */ -#include -#define ae_makedev(maj, min) makedev(ND_LOCAL_NODE, (maj), (min)) -#elif defined makedev -/* There's a "makedev" macro. */ -#define ae_makedev(maj, min) makedev((maj), (min)) -#elif defined mkdev || ((defined _WIN32 || defined __WIN32__) && !defined(__CYGWIN__)) -/* Windows. */ -#define ae_makedev(maj, min) mkdev((maj), (min)) -#else -/* There's a "makedev" function. */ -#define ae_makedev(maj, min) makedev((maj), (min)) -#endif - -/* - * This adjustment is needed to support the following idiom for adding - * 1000ns to the stored time: - * archive_entry_set_atime(archive_entry_atime(), - * archive_entry_atime_nsec() + 1000) - * The additional if() here compensates for ambiguity in the C standard, - * which permits two possible interpretations of a % b when a is negative. - */ -#define FIX_NS(t,ns) \ - do { \ - t += ns / 1000000000; \ - ns %= 1000000000; \ - if (ns < 0) { --t; ns += 1000000000; } \ - } while (0) - -static char * ae_fflagstostr(unsigned long bitset, unsigned long bitclear); -static const wchar_t *ae_wcstofflags(const wchar_t *stringp, - unsigned long *setp, unsigned long *clrp); -static const char *ae_strtofflags(const char *stringp, - unsigned long *setp, unsigned long *clrp); - -#ifndef HAVE_WCSCPY -static wchar_t * wcscpy(wchar_t *s1, const wchar_t *s2) -{ - wchar_t *dest = s1; - while ((*s1 = *s2) != L'\0') - ++s1, ++s2; - return dest; -} -#endif -#ifndef HAVE_WCSLEN -static size_t wcslen(const wchar_t *s) -{ - const wchar_t *p = s; - while (*p != L'\0') - ++p; - return p - s; -} -#endif -#ifndef HAVE_WMEMCMP -/* Good enough for simple equality testing, but not for sorting. */ -#define wmemcmp(a,b,i) memcmp((a), (b), (i) * sizeof(wchar_t)) -#endif - -/**************************************************************************** - * - * Public Interface - * - ****************************************************************************/ - -struct archive_entry * -archive_entry_clear(struct archive_entry *entry) -{ - if (entry == NULL) - return (NULL); - archive_mstring_clean(&entry->ae_fflags_text); - archive_mstring_clean(&entry->ae_gname); - archive_mstring_clean(&entry->ae_hardlink); - archive_mstring_clean(&entry->ae_pathname); - archive_mstring_clean(&entry->ae_sourcepath); - archive_mstring_clean(&entry->ae_symlink); - archive_mstring_clean(&entry->ae_uname); - archive_entry_copy_mac_metadata(entry, NULL, 0); - archive_acl_clear(&entry->acl); - archive_entry_xattr_clear(entry); - archive_entry_sparse_clear(entry); - free(entry->stat); - entry->ae_symlink_type = AE_SYMLINK_TYPE_UNDEFINED; - memset(entry, 0, sizeof(*entry)); - return entry; -} - -struct archive_entry * -archive_entry_clone(struct archive_entry *entry) -{ - struct archive_entry *entry2; - struct ae_xattr *xp; - struct ae_sparse *sp; - size_t s; - const void *p; - - /* Allocate new structure and copy over all of the fields. */ - /* TODO: Should we copy the archive over? Or require a new archive - * as an argument? */ - entry2 = archive_entry_new2(entry->archive); - if (entry2 == NULL) - return (NULL); - entry2->ae_stat = entry->ae_stat; - entry2->ae_fflags_set = entry->ae_fflags_set; - entry2->ae_fflags_clear = entry->ae_fflags_clear; - - /* TODO: XXX If clone can have a different archive, what do we do here if - * character sets are different? XXX */ - archive_mstring_copy(&entry2->ae_fflags_text, &entry->ae_fflags_text); - archive_mstring_copy(&entry2->ae_gname, &entry->ae_gname); - archive_mstring_copy(&entry2->ae_hardlink, &entry->ae_hardlink); - archive_mstring_copy(&entry2->ae_pathname, &entry->ae_pathname); - archive_mstring_copy(&entry2->ae_sourcepath, &entry->ae_sourcepath); - archive_mstring_copy(&entry2->ae_symlink, &entry->ae_symlink); - entry2->ae_set = entry->ae_set; - archive_mstring_copy(&entry2->ae_uname, &entry->ae_uname); - - /* Copy symlink type */ - entry2->ae_symlink_type = entry->ae_symlink_type; - - /* Copy encryption status */ - entry2->encryption = entry->encryption; - - /* Copy digests */ -#define copy_digest(_e2, _e, _t) \ - memcpy(_e2->digest._t, _e->digest._t, sizeof(_e2->digest._t)) - - copy_digest(entry2, entry, md5); - copy_digest(entry2, entry, rmd160); - copy_digest(entry2, entry, sha1); - copy_digest(entry2, entry, sha256); - copy_digest(entry2, entry, sha384); - copy_digest(entry2, entry, sha512); - -#undef copy_digest - - /* Copy ACL data over. */ - archive_acl_copy(&entry2->acl, &entry->acl); - - /* Copy Mac OS metadata. */ - p = archive_entry_mac_metadata(entry, &s); - archive_entry_copy_mac_metadata(entry2, p, s); - - /* Copy xattr data over. */ - xp = entry->xattr_head; - while (xp != NULL) { - archive_entry_xattr_add_entry(entry2, - xp->name, xp->value, xp->size); - xp = xp->next; - } - - /* Copy sparse data over. */ - sp = entry->sparse_head; - while (sp != NULL) { - archive_entry_sparse_add_entry(entry2, - sp->offset, sp->length); - sp = sp->next; - } - - return (entry2); -} - -void -archive_entry_free(struct archive_entry *entry) -{ - archive_entry_clear(entry); - free(entry); -} - -struct archive_entry * -archive_entry_new(void) -{ - return archive_entry_new2(NULL); -} - -struct archive_entry * -archive_entry_new2(struct archive *a) -{ - struct archive_entry *entry; - - entry = (struct archive_entry *)calloc(1, sizeof(*entry)); - if (entry == NULL) - return (NULL); - entry->archive = a; - entry->ae_symlink_type = AE_SYMLINK_TYPE_UNDEFINED; - return (entry); -} - -/* - * Functions for reading fields from an archive_entry. - */ - -time_t -archive_entry_atime(struct archive_entry *entry) -{ - return (entry->ae_stat.aest_atime); -} - -long -archive_entry_atime_nsec(struct archive_entry *entry) -{ - return (entry->ae_stat.aest_atime_nsec); -} - -int -archive_entry_atime_is_set(struct archive_entry *entry) -{ - return (entry->ae_set & AE_SET_ATIME); -} - -time_t -archive_entry_birthtime(struct archive_entry *entry) -{ - return (entry->ae_stat.aest_birthtime); -} - -long -archive_entry_birthtime_nsec(struct archive_entry *entry) -{ - return (entry->ae_stat.aest_birthtime_nsec); -} - -int -archive_entry_birthtime_is_set(struct archive_entry *entry) -{ - return (entry->ae_set & AE_SET_BIRTHTIME); -} - -time_t -archive_entry_ctime(struct archive_entry *entry) -{ - return (entry->ae_stat.aest_ctime); -} - -int -archive_entry_ctime_is_set(struct archive_entry *entry) -{ - return (entry->ae_set & AE_SET_CTIME); -} - -long -archive_entry_ctime_nsec(struct archive_entry *entry) -{ - return (entry->ae_stat.aest_ctime_nsec); -} - -dev_t -archive_entry_dev(struct archive_entry *entry) -{ - if (entry->ae_stat.aest_dev_is_broken_down) - return ae_makedev(entry->ae_stat.aest_devmajor, - entry->ae_stat.aest_devminor); - else - return (entry->ae_stat.aest_dev); -} - -int -archive_entry_dev_is_set(struct archive_entry *entry) -{ - return (entry->ae_set & AE_SET_DEV); -} - -dev_t -archive_entry_devmajor(struct archive_entry *entry) -{ - if (entry->ae_stat.aest_dev_is_broken_down) - return (entry->ae_stat.aest_devmajor); - else - return major(entry->ae_stat.aest_dev); -} - -dev_t -archive_entry_devminor(struct archive_entry *entry) -{ - if (entry->ae_stat.aest_dev_is_broken_down) - return (entry->ae_stat.aest_devminor); - else - return minor(entry->ae_stat.aest_dev); -} - -__LA_MODE_T -archive_entry_filetype(struct archive_entry *entry) -{ - return (AE_IFMT & entry->acl.mode); -} - -void -archive_entry_fflags(struct archive_entry *entry, - unsigned long *set, unsigned long *clear) -{ - *set = entry->ae_fflags_set; - *clear = entry->ae_fflags_clear; -} - -/* - * Note: if text was provided, this just returns that text. If you - * really need the text to be rebuilt in a canonical form, set the - * text, ask for the bitmaps, then set the bitmaps. (Setting the - * bitmaps clears any stored text.) This design is deliberate: if - * we're editing archives, we don't want to discard flags just because - * they aren't supported on the current system. The bitmap<->text - * conversions are platform-specific (see below). - */ -const char * -archive_entry_fflags_text(struct archive_entry *entry) -{ - const char *f; - char *p; - - if (archive_mstring_get_mbs(entry->archive, - &entry->ae_fflags_text, &f) == 0) { - if (f != NULL) - return (f); - } else if (errno == ENOMEM) - __archive_errx(1, "No memory"); - - if (entry->ae_fflags_set == 0 && entry->ae_fflags_clear == 0) - return (NULL); - - p = ae_fflagstostr(entry->ae_fflags_set, entry->ae_fflags_clear); - if (p == NULL) - return (NULL); - - archive_mstring_copy_mbs(&entry->ae_fflags_text, p); - free(p); - if (archive_mstring_get_mbs(entry->archive, - &entry->ae_fflags_text, &f) == 0) - return (f); - if (errno == ENOMEM) - __archive_errx(1, "No memory"); - return (NULL); -} - -la_int64_t -archive_entry_gid(struct archive_entry *entry) -{ - return (entry->ae_stat.aest_gid); -} - -const char * -archive_entry_gname(struct archive_entry *entry) -{ - const char *p; - if (archive_mstring_get_mbs(entry->archive, &entry->ae_gname, &p) == 0) - return (p); - if (errno == ENOMEM) - __archive_errx(1, "No memory"); - return (NULL); -} - -const char * -archive_entry_gname_utf8(struct archive_entry *entry) -{ - const char *p; - if (archive_mstring_get_utf8(entry->archive, &entry->ae_gname, &p) == 0) - return (p); - if (errno == ENOMEM) - __archive_errx(1, "No memory"); - return (NULL); -} - - -const wchar_t * -archive_entry_gname_w(struct archive_entry *entry) -{ - const wchar_t *p; - if (archive_mstring_get_wcs(entry->archive, &entry->ae_gname, &p) == 0) - return (p); - if (errno == ENOMEM) - __archive_errx(1, "No memory"); - return (NULL); -} - -int -_archive_entry_gname_l(struct archive_entry *entry, - const char **p, size_t *len, struct archive_string_conv *sc) -{ - return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_gname, p, len, sc)); -} - -const char * -archive_entry_hardlink(struct archive_entry *entry) -{ - const char *p; - if ((entry->ae_set & AE_SET_HARDLINK) == 0) - return (NULL); - if (archive_mstring_get_mbs( - entry->archive, &entry->ae_hardlink, &p) == 0) - return (p); - if (errno == ENOMEM) - __archive_errx(1, "No memory"); - return (NULL); -} - -const char * -archive_entry_hardlink_utf8(struct archive_entry *entry) -{ - const char *p; - if ((entry->ae_set & AE_SET_HARDLINK) == 0) - return (NULL); - if (archive_mstring_get_utf8( - entry->archive, &entry->ae_hardlink, &p) == 0) - return (p); - if (errno == ENOMEM) - __archive_errx(1, "No memory"); - return (NULL); -} - -const wchar_t * -archive_entry_hardlink_w(struct archive_entry *entry) -{ - const wchar_t *p; - if ((entry->ae_set & AE_SET_HARDLINK) == 0) - return (NULL); - if (archive_mstring_get_wcs( - entry->archive, &entry->ae_hardlink, &p) == 0) - return (p); - if (errno == ENOMEM) - __archive_errx(1, "No memory"); - return (NULL); -} - -int -_archive_entry_hardlink_l(struct archive_entry *entry, - const char **p, size_t *len, struct archive_string_conv *sc) -{ - if ((entry->ae_set & AE_SET_HARDLINK) == 0) { - *p = NULL; - *len = 0; - return (0); - } - return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_hardlink, p, len, sc)); -} - -la_int64_t -archive_entry_ino(struct archive_entry *entry) -{ - return (entry->ae_stat.aest_ino); -} - -int -archive_entry_ino_is_set(struct archive_entry *entry) -{ - return (entry->ae_set & AE_SET_INO); -} - -la_int64_t -archive_entry_ino64(struct archive_entry *entry) -{ - return (entry->ae_stat.aest_ino); -} - -__LA_MODE_T -archive_entry_mode(struct archive_entry *entry) -{ - return (entry->acl.mode); -} - -time_t -archive_entry_mtime(struct archive_entry *entry) -{ - return (entry->ae_stat.aest_mtime); -} - -long -archive_entry_mtime_nsec(struct archive_entry *entry) -{ - return (entry->ae_stat.aest_mtime_nsec); -} - -int -archive_entry_mtime_is_set(struct archive_entry *entry) -{ - return (entry->ae_set & AE_SET_MTIME); -} - -unsigned int -archive_entry_nlink(struct archive_entry *entry) -{ - return (entry->ae_stat.aest_nlink); -} - -/* Instead, our caller could have chosen a specific encoding - * (archive_mstring_get_mbs, archive_mstring_get_utf8, - * archive_mstring_get_wcs). So we should try multiple - * encodings. Try mbs first because of history, even though - * utf8 might be better for pathname portability. - * Also omit wcs because of type mismatch (char * versus wchar *) - */ -const char * -archive_entry_pathname(struct archive_entry *entry) -{ - const char *p; - if (archive_mstring_get_mbs( - entry->archive, &entry->ae_pathname, &p) == 0) - return (p); -#if HAVE_EILSEQ /*{*/ - if (errno == EILSEQ) { - if (archive_mstring_get_utf8( - entry->archive, &entry->ae_pathname, &p) == 0) - return (p); - } -#endif /*}*/ - if (errno == ENOMEM) - __archive_errx(1, "No memory"); - return (NULL); -} - -const char * -archive_entry_pathname_utf8(struct archive_entry *entry) -{ - const char *p; - if (archive_mstring_get_utf8( - entry->archive, &entry->ae_pathname, &p) == 0) - return (p); - if (errno == ENOMEM) - __archive_errx(1, "No memory"); - return (NULL); -} - -const wchar_t * -archive_entry_pathname_w(struct archive_entry *entry) -{ - const wchar_t *p; - if (archive_mstring_get_wcs( - entry->archive, &entry->ae_pathname, &p) == 0) - return (p); - if (errno == ENOMEM) - __archive_errx(1, "No memory"); - return (NULL); -} - -int -_archive_entry_pathname_l(struct archive_entry *entry, - const char **p, size_t *len, struct archive_string_conv *sc) -{ - return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_pathname, p, len, sc)); -} - -__LA_MODE_T -archive_entry_perm(struct archive_entry *entry) -{ - return (~AE_IFMT & entry->acl.mode); -} - -dev_t -archive_entry_rdev(struct archive_entry *entry) -{ - if (entry->ae_stat.aest_rdev_is_broken_down) - return ae_makedev(entry->ae_stat.aest_rdevmajor, - entry->ae_stat.aest_rdevminor); - else - return (entry->ae_stat.aest_rdev); -} - -dev_t -archive_entry_rdevmajor(struct archive_entry *entry) -{ - if (entry->ae_stat.aest_rdev_is_broken_down) - return (entry->ae_stat.aest_rdevmajor); - else - return major(entry->ae_stat.aest_rdev); -} - -dev_t -archive_entry_rdevminor(struct archive_entry *entry) -{ - if (entry->ae_stat.aest_rdev_is_broken_down) - return (entry->ae_stat.aest_rdevminor); - else - return minor(entry->ae_stat.aest_rdev); -} - -la_int64_t -archive_entry_size(struct archive_entry *entry) -{ - return (entry->ae_stat.aest_size); -} - -int -archive_entry_size_is_set(struct archive_entry *entry) -{ - return (entry->ae_set & AE_SET_SIZE); -} - -const char * -archive_entry_sourcepath(struct archive_entry *entry) -{ - const char *p; - if (archive_mstring_get_mbs( - entry->archive, &entry->ae_sourcepath, &p) == 0) - return (p); - if (errno == ENOMEM) - __archive_errx(1, "No memory"); - return (NULL); -} - -const wchar_t * -archive_entry_sourcepath_w(struct archive_entry *entry) -{ - const wchar_t *p; - if (archive_mstring_get_wcs( - entry->archive, &entry->ae_sourcepath, &p) == 0) - return (p); - return (NULL); -} - -const char * -archive_entry_symlink(struct archive_entry *entry) -{ - const char *p; - if ((entry->ae_set & AE_SET_SYMLINK) == 0) - return (NULL); - if (archive_mstring_get_mbs( - entry->archive, &entry->ae_symlink, &p) == 0) - return (p); - if (errno == ENOMEM) - __archive_errx(1, "No memory"); - return (NULL); -} - -int -archive_entry_symlink_type(struct archive_entry *entry) -{ - return (entry->ae_symlink_type); -} - -const char * -archive_entry_symlink_utf8(struct archive_entry *entry) -{ - const char *p; - if ((entry->ae_set & AE_SET_SYMLINK) == 0) - return (NULL); - if (archive_mstring_get_utf8( - entry->archive, &entry->ae_symlink, &p) == 0) - return (p); - if (errno == ENOMEM) - __archive_errx(1, "No memory"); - return (NULL); -} - -const wchar_t * -archive_entry_symlink_w(struct archive_entry *entry) -{ - const wchar_t *p; - if ((entry->ae_set & AE_SET_SYMLINK) == 0) - return (NULL); - if (archive_mstring_get_wcs( - entry->archive, &entry->ae_symlink, &p) == 0) - return (p); - if (errno == ENOMEM) - __archive_errx(1, "No memory"); - return (NULL); -} - -int -_archive_entry_symlink_l(struct archive_entry *entry, - const char **p, size_t *len, struct archive_string_conv *sc) -{ - if ((entry->ae_set & AE_SET_SYMLINK) == 0) { - *p = NULL; - *len = 0; - return (0); - } - return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_symlink, p, len, sc)); -} - -la_int64_t -archive_entry_uid(struct archive_entry *entry) -{ - return (entry->ae_stat.aest_uid); -} - -const char * -archive_entry_uname(struct archive_entry *entry) -{ - const char *p; - if (archive_mstring_get_mbs(entry->archive, &entry->ae_uname, &p) == 0) - return (p); - if (errno == ENOMEM) - __archive_errx(1, "No memory"); - return (NULL); -} - -const char * -archive_entry_uname_utf8(struct archive_entry *entry) -{ - const char *p; - if (archive_mstring_get_utf8(entry->archive, &entry->ae_uname, &p) == 0) - return (p); - if (errno == ENOMEM) - __archive_errx(1, "No memory"); - return (NULL); -} - -const wchar_t * -archive_entry_uname_w(struct archive_entry *entry) -{ - const wchar_t *p; - if (archive_mstring_get_wcs(entry->archive, &entry->ae_uname, &p) == 0) - return (p); - if (errno == ENOMEM) - __archive_errx(1, "No memory"); - return (NULL); -} - -int -_archive_entry_uname_l(struct archive_entry *entry, - const char **p, size_t *len, struct archive_string_conv *sc) -{ - return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_uname, p, len, sc)); -} - -int -archive_entry_is_data_encrypted(struct archive_entry *entry) -{ - return ((entry->encryption & AE_ENCRYPTION_DATA) == AE_ENCRYPTION_DATA); -} - -int -archive_entry_is_metadata_encrypted(struct archive_entry *entry) -{ - return ((entry->encryption & AE_ENCRYPTION_METADATA) == AE_ENCRYPTION_METADATA); -} - -int -archive_entry_is_encrypted(struct archive_entry *entry) -{ - return (entry->encryption & (AE_ENCRYPTION_DATA|AE_ENCRYPTION_METADATA)); -} - -/* - * Functions to set archive_entry properties. - */ - -void -archive_entry_set_filetype(struct archive_entry *entry, unsigned int type) -{ - entry->stat_valid = 0; - entry->acl.mode &= ~AE_IFMT; - entry->acl.mode |= AE_IFMT & type; -} - -void -archive_entry_set_fflags(struct archive_entry *entry, - unsigned long set, unsigned long clear) -{ - archive_mstring_clean(&entry->ae_fflags_text); - entry->ae_fflags_set = set; - entry->ae_fflags_clear = clear; -} - -const char * -archive_entry_copy_fflags_text(struct archive_entry *entry, - const char *flags) -{ - archive_mstring_copy_mbs(&entry->ae_fflags_text, flags); - return (ae_strtofflags(flags, - &entry->ae_fflags_set, &entry->ae_fflags_clear)); -} - -const wchar_t * -archive_entry_copy_fflags_text_w(struct archive_entry *entry, - const wchar_t *flags) -{ - archive_mstring_copy_wcs(&entry->ae_fflags_text, flags); - return (ae_wcstofflags(flags, - &entry->ae_fflags_set, &entry->ae_fflags_clear)); -} - -void -archive_entry_set_gid(struct archive_entry *entry, la_int64_t g) -{ - entry->stat_valid = 0; - entry->ae_stat.aest_gid = g; -} - -void -archive_entry_set_gname(struct archive_entry *entry, const char *name) -{ - archive_mstring_copy_mbs(&entry->ae_gname, name); -} - -void -archive_entry_set_gname_utf8(struct archive_entry *entry, const char *name) -{ - archive_mstring_copy_utf8(&entry->ae_gname, name); -} - -void -archive_entry_copy_gname(struct archive_entry *entry, const char *name) -{ - archive_mstring_copy_mbs(&entry->ae_gname, name); -} - -void -archive_entry_copy_gname_w(struct archive_entry *entry, const wchar_t *name) -{ - archive_mstring_copy_wcs(&entry->ae_gname, name); -} - -int -archive_entry_update_gname_utf8(struct archive_entry *entry, const char *name) -{ - if (archive_mstring_update_utf8(entry->archive, - &entry->ae_gname, name) == 0) - return (1); - if (errno == ENOMEM) - __archive_errx(1, "No memory"); - return (0); -} - -int -_archive_entry_copy_gname_l(struct archive_entry *entry, - const char *name, size_t len, struct archive_string_conv *sc) -{ - return (archive_mstring_copy_mbs_len_l(&entry->ae_gname, name, len, sc)); -} - -void -archive_entry_set_ino(struct archive_entry *entry, la_int64_t ino) -{ - entry->stat_valid = 0; - entry->ae_set |= AE_SET_INO; - entry->ae_stat.aest_ino = ino; -} - -void -archive_entry_set_ino64(struct archive_entry *entry, la_int64_t ino) -{ - entry->stat_valid = 0; - entry->ae_set |= AE_SET_INO; - entry->ae_stat.aest_ino = ino; -} - -void -archive_entry_set_hardlink(struct archive_entry *entry, const char *target) -{ - archive_mstring_copy_mbs(&entry->ae_hardlink, target); - if (target != NULL) - entry->ae_set |= AE_SET_HARDLINK; - else - entry->ae_set &= ~AE_SET_HARDLINK; -} - -void -archive_entry_set_hardlink_utf8(struct archive_entry *entry, const char *target) -{ - archive_mstring_copy_utf8(&entry->ae_hardlink, target); - if (target != NULL) - entry->ae_set |= AE_SET_HARDLINK; - else - entry->ae_set &= ~AE_SET_HARDLINK; -} - -void -archive_entry_copy_hardlink(struct archive_entry *entry, const char *target) -{ - archive_mstring_copy_mbs(&entry->ae_hardlink, target); - if (target != NULL) - entry->ae_set |= AE_SET_HARDLINK; - else - entry->ae_set &= ~AE_SET_HARDLINK; -} - -void -archive_entry_copy_hardlink_w(struct archive_entry *entry, const wchar_t *target) -{ - archive_mstring_copy_wcs(&entry->ae_hardlink, target); - if (target != NULL) - entry->ae_set |= AE_SET_HARDLINK; - else - entry->ae_set &= ~AE_SET_HARDLINK; -} - -int -archive_entry_update_hardlink_utf8(struct archive_entry *entry, const char *target) -{ - if (target != NULL) - entry->ae_set |= AE_SET_HARDLINK; - else - entry->ae_set &= ~AE_SET_HARDLINK; - if (archive_mstring_update_utf8(entry->archive, - &entry->ae_hardlink, target) == 0) - return (1); - if (errno == ENOMEM) - __archive_errx(1, "No memory"); - return (0); -} - -int -_archive_entry_copy_hardlink_l(struct archive_entry *entry, - const char *target, size_t len, struct archive_string_conv *sc) -{ - int r; - - r = archive_mstring_copy_mbs_len_l(&entry->ae_hardlink, - target, len, sc); - if (target != NULL && r == 0) - entry->ae_set |= AE_SET_HARDLINK; - else - entry->ae_set &= ~AE_SET_HARDLINK; - return (r); -} - -void -archive_entry_set_atime(struct archive_entry *entry, time_t t, long ns) -{ - FIX_NS(t, ns); - entry->stat_valid = 0; - entry->ae_set |= AE_SET_ATIME; - entry->ae_stat.aest_atime = t; - entry->ae_stat.aest_atime_nsec = ns; -} - -void -archive_entry_unset_atime(struct archive_entry *entry) -{ - archive_entry_set_atime(entry, 0, 0); - entry->ae_set &= ~AE_SET_ATIME; -} - -void -archive_entry_set_birthtime(struct archive_entry *entry, time_t t, long ns) -{ - FIX_NS(t, ns); - entry->stat_valid = 0; - entry->ae_set |= AE_SET_BIRTHTIME; - entry->ae_stat.aest_birthtime = t; - entry->ae_stat.aest_birthtime_nsec = ns; -} - -void -archive_entry_unset_birthtime(struct archive_entry *entry) -{ - archive_entry_set_birthtime(entry, 0, 0); - entry->ae_set &= ~AE_SET_BIRTHTIME; -} - -void -archive_entry_set_ctime(struct archive_entry *entry, time_t t, long ns) -{ - FIX_NS(t, ns); - entry->stat_valid = 0; - entry->ae_set |= AE_SET_CTIME; - entry->ae_stat.aest_ctime = t; - entry->ae_stat.aest_ctime_nsec = ns; -} - -void -archive_entry_unset_ctime(struct archive_entry *entry) -{ - archive_entry_set_ctime(entry, 0, 0); - entry->ae_set &= ~AE_SET_CTIME; -} - -void -archive_entry_set_dev(struct archive_entry *entry, dev_t d) -{ - entry->stat_valid = 0; - entry->ae_set |= AE_SET_DEV; - entry->ae_stat.aest_dev_is_broken_down = 0; - entry->ae_stat.aest_dev = d; -} - -void -archive_entry_set_devmajor(struct archive_entry *entry, dev_t m) -{ - entry->stat_valid = 0; - entry->ae_set |= AE_SET_DEV; - entry->ae_stat.aest_dev_is_broken_down = 1; - entry->ae_stat.aest_devmajor = m; -} - -void -archive_entry_set_devminor(struct archive_entry *entry, dev_t m) -{ - entry->stat_valid = 0; - entry->ae_set |= AE_SET_DEV; - entry->ae_stat.aest_dev_is_broken_down = 1; - entry->ae_stat.aest_devminor = m; -} - -/* Set symlink if symlink is already set, else set hardlink. */ -void -archive_entry_set_link(struct archive_entry *entry, const char *target) -{ - if (entry->ae_set & AE_SET_SYMLINK) - archive_mstring_copy_mbs(&entry->ae_symlink, target); - else - archive_mstring_copy_mbs(&entry->ae_hardlink, target); -} - -void -archive_entry_set_link_utf8(struct archive_entry *entry, const char *target) -{ - if (entry->ae_set & AE_SET_SYMLINK) - archive_mstring_copy_utf8(&entry->ae_symlink, target); - else - archive_mstring_copy_utf8(&entry->ae_hardlink, target); -} - -/* Set symlink if symlink is already set, else set hardlink. */ -void -archive_entry_copy_link(struct archive_entry *entry, const char *target) -{ - if (entry->ae_set & AE_SET_SYMLINK) - archive_mstring_copy_mbs(&entry->ae_symlink, target); - else - archive_mstring_copy_mbs(&entry->ae_hardlink, target); -} - -/* Set symlink if symlink is already set, else set hardlink. */ -void -archive_entry_copy_link_w(struct archive_entry *entry, const wchar_t *target) -{ - if (entry->ae_set & AE_SET_SYMLINK) - archive_mstring_copy_wcs(&entry->ae_symlink, target); - else - archive_mstring_copy_wcs(&entry->ae_hardlink, target); -} - -int -archive_entry_update_link_utf8(struct archive_entry *entry, const char *target) -{ - int r; - if (entry->ae_set & AE_SET_SYMLINK) - r = archive_mstring_update_utf8(entry->archive, - &entry->ae_symlink, target); - else - r = archive_mstring_update_utf8(entry->archive, - &entry->ae_hardlink, target); - if (r == 0) - return (1); - if (errno == ENOMEM) - __archive_errx(1, "No memory"); - return (0); -} - -int -_archive_entry_copy_link_l(struct archive_entry *entry, - const char *target, size_t len, struct archive_string_conv *sc) -{ - int r; - - if (entry->ae_set & AE_SET_SYMLINK) - r = archive_mstring_copy_mbs_len_l(&entry->ae_symlink, - target, len, sc); - else - r = archive_mstring_copy_mbs_len_l(&entry->ae_hardlink, - target, len, sc); - return (r); -} - -void -archive_entry_set_mode(struct archive_entry *entry, mode_t m) -{ - entry->stat_valid = 0; - entry->acl.mode = m; -} - -void -archive_entry_set_mtime(struct archive_entry *entry, time_t t, long ns) -{ - FIX_NS(t, ns); - entry->stat_valid = 0; - entry->ae_set |= AE_SET_MTIME; - entry->ae_stat.aest_mtime = t; - entry->ae_stat.aest_mtime_nsec = ns; -} - -void -archive_entry_unset_mtime(struct archive_entry *entry) -{ - archive_entry_set_mtime(entry, 0, 0); - entry->ae_set &= ~AE_SET_MTIME; -} - -void -archive_entry_set_nlink(struct archive_entry *entry, unsigned int nlink) -{ - entry->stat_valid = 0; - entry->ae_stat.aest_nlink = nlink; -} - -void -archive_entry_set_pathname(struct archive_entry *entry, const char *name) -{ - archive_mstring_copy_mbs(&entry->ae_pathname, name); -} - -void -archive_entry_set_pathname_utf8(struct archive_entry *entry, const char *name) -{ - archive_mstring_copy_utf8(&entry->ae_pathname, name); -} - -void -archive_entry_copy_pathname(struct archive_entry *entry, const char *name) -{ - archive_mstring_copy_mbs(&entry->ae_pathname, name); -} - -void -archive_entry_copy_pathname_w(struct archive_entry *entry, const wchar_t *name) -{ - archive_mstring_copy_wcs(&entry->ae_pathname, name); -} - -int -archive_entry_update_pathname_utf8(struct archive_entry *entry, const char *name) -{ - if (archive_mstring_update_utf8(entry->archive, - &entry->ae_pathname, name) == 0) - return (1); - if (errno == ENOMEM) - __archive_errx(1, "No memory"); - return (0); -} - -int -_archive_entry_copy_pathname_l(struct archive_entry *entry, - const char *name, size_t len, struct archive_string_conv *sc) -{ - return (archive_mstring_copy_mbs_len_l(&entry->ae_pathname, - name, len, sc)); -} - -void -archive_entry_set_perm(struct archive_entry *entry, mode_t p) -{ - entry->stat_valid = 0; - entry->acl.mode &= AE_IFMT; - entry->acl.mode |= ~AE_IFMT & p; -} - -void -archive_entry_set_rdev(struct archive_entry *entry, dev_t m) -{ - entry->stat_valid = 0; - entry->ae_stat.aest_rdev = m; - entry->ae_stat.aest_rdev_is_broken_down = 0; -} - -void -archive_entry_set_rdevmajor(struct archive_entry *entry, dev_t m) -{ - entry->stat_valid = 0; - entry->ae_stat.aest_rdev_is_broken_down = 1; - entry->ae_stat.aest_rdevmajor = m; -} - -void -archive_entry_set_rdevminor(struct archive_entry *entry, dev_t m) -{ - entry->stat_valid = 0; - entry->ae_stat.aest_rdev_is_broken_down = 1; - entry->ae_stat.aest_rdevminor = m; -} - -void -archive_entry_set_size(struct archive_entry *entry, la_int64_t s) -{ - entry->stat_valid = 0; - entry->ae_stat.aest_size = s; - entry->ae_set |= AE_SET_SIZE; -} - -void -archive_entry_unset_size(struct archive_entry *entry) -{ - archive_entry_set_size(entry, 0); - entry->ae_set &= ~AE_SET_SIZE; -} - -void -archive_entry_copy_sourcepath(struct archive_entry *entry, const char *path) -{ - archive_mstring_copy_mbs(&entry->ae_sourcepath, path); -} - -void -archive_entry_copy_sourcepath_w(struct archive_entry *entry, const wchar_t *path) -{ - archive_mstring_copy_wcs(&entry->ae_sourcepath, path); -} - -void -archive_entry_set_symlink(struct archive_entry *entry, const char *linkname) -{ - archive_mstring_copy_mbs(&entry->ae_symlink, linkname); - if (linkname != NULL) - entry->ae_set |= AE_SET_SYMLINK; - else - entry->ae_set &= ~AE_SET_SYMLINK; -} - -void -archive_entry_set_symlink_type(struct archive_entry *entry, int type) -{ - entry->ae_symlink_type = type; -} - -void -archive_entry_set_symlink_utf8(struct archive_entry *entry, const char *linkname) -{ - archive_mstring_copy_utf8(&entry->ae_symlink, linkname); - if (linkname != NULL) - entry->ae_set |= AE_SET_SYMLINK; - else - entry->ae_set &= ~AE_SET_SYMLINK; -} - -void -archive_entry_copy_symlink(struct archive_entry *entry, const char *linkname) -{ - archive_mstring_copy_mbs(&entry->ae_symlink, linkname); - if (linkname != NULL) - entry->ae_set |= AE_SET_SYMLINK; - else - entry->ae_set &= ~AE_SET_SYMLINK; -} - -void -archive_entry_copy_symlink_w(struct archive_entry *entry, const wchar_t *linkname) -{ - archive_mstring_copy_wcs(&entry->ae_symlink, linkname); - if (linkname != NULL) - entry->ae_set |= AE_SET_SYMLINK; - else - entry->ae_set &= ~AE_SET_SYMLINK; -} - -int -archive_entry_update_symlink_utf8(struct archive_entry *entry, const char *linkname) -{ - if (linkname != NULL) - entry->ae_set |= AE_SET_SYMLINK; - else - entry->ae_set &= ~AE_SET_SYMLINK; - if (archive_mstring_update_utf8(entry->archive, - &entry->ae_symlink, linkname) == 0) - return (1); - if (errno == ENOMEM) - __archive_errx(1, "No memory"); - return (0); -} - -int -_archive_entry_copy_symlink_l(struct archive_entry *entry, - const char *linkname, size_t len, struct archive_string_conv *sc) -{ - int r; - - r = archive_mstring_copy_mbs_len_l(&entry->ae_symlink, - linkname, len, sc); - if (linkname != NULL && r == 0) - entry->ae_set |= AE_SET_SYMLINK; - else - entry->ae_set &= ~AE_SET_SYMLINK; - return (r); -} - -void -archive_entry_set_uid(struct archive_entry *entry, la_int64_t u) -{ - entry->stat_valid = 0; - entry->ae_stat.aest_uid = u; -} - -void -archive_entry_set_uname(struct archive_entry *entry, const char *name) -{ - archive_mstring_copy_mbs(&entry->ae_uname, name); -} - -void -archive_entry_set_uname_utf8(struct archive_entry *entry, const char *name) -{ - archive_mstring_copy_utf8(&entry->ae_uname, name); -} - -void -archive_entry_copy_uname(struct archive_entry *entry, const char *name) -{ - archive_mstring_copy_mbs(&entry->ae_uname, name); -} - -void -archive_entry_copy_uname_w(struct archive_entry *entry, const wchar_t *name) -{ - archive_mstring_copy_wcs(&entry->ae_uname, name); -} - -int -archive_entry_update_uname_utf8(struct archive_entry *entry, const char *name) -{ - if (archive_mstring_update_utf8(entry->archive, - &entry->ae_uname, name) == 0) - return (1); - if (errno == ENOMEM) - __archive_errx(1, "No memory"); - return (0); -} - -void -archive_entry_set_is_data_encrypted(struct archive_entry *entry, char is_encrypted) -{ - if (is_encrypted) { - entry->encryption |= AE_ENCRYPTION_DATA; - } else { - entry->encryption &= ~AE_ENCRYPTION_DATA; - } -} - -void -archive_entry_set_is_metadata_encrypted(struct archive_entry *entry, char is_encrypted) -{ - if (is_encrypted) { - entry->encryption |= AE_ENCRYPTION_METADATA; - } else { - entry->encryption &= ~AE_ENCRYPTION_METADATA; - } -} - -int -_archive_entry_copy_uname_l(struct archive_entry *entry, - const char *name, size_t len, struct archive_string_conv *sc) -{ - return (archive_mstring_copy_mbs_len_l(&entry->ae_uname, - name, len, sc)); -} - -const void * -archive_entry_mac_metadata(struct archive_entry *entry, size_t *s) -{ - *s = entry->mac_metadata_size; - return entry->mac_metadata; -} - -void -archive_entry_copy_mac_metadata(struct archive_entry *entry, - const void *p, size_t s) -{ - free(entry->mac_metadata); - if (p == NULL || s == 0) { - entry->mac_metadata = NULL; - entry->mac_metadata_size = 0; - } else { - entry->mac_metadata_size = s; - entry->mac_metadata = malloc(s); - if (entry->mac_metadata == NULL) - abort(); - memcpy(entry->mac_metadata, p, s); - } -} - -/* Digest handling */ -const unsigned char * -archive_entry_digest(struct archive_entry *entry, int type) -{ - switch (type) { - case ARCHIVE_ENTRY_DIGEST_MD5: - return entry->digest.md5; - case ARCHIVE_ENTRY_DIGEST_RMD160: - return entry->digest.rmd160; - case ARCHIVE_ENTRY_DIGEST_SHA1: - return entry->digest.sha1; - case ARCHIVE_ENTRY_DIGEST_SHA256: - return entry->digest.sha256; - case ARCHIVE_ENTRY_DIGEST_SHA384: - return entry->digest.sha384; - case ARCHIVE_ENTRY_DIGEST_SHA512: - return entry->digest.sha512; - default: - return NULL; - } -} - -int -archive_entry_set_digest(struct archive_entry *entry, int type, - const unsigned char *digest) -{ -#define copy_digest(_e, _t, _d)\ - memcpy(_e->digest._t, _d, sizeof(_e->digest._t)) - - switch (type) { - case ARCHIVE_ENTRY_DIGEST_MD5: - copy_digest(entry, md5, digest); - break; - case ARCHIVE_ENTRY_DIGEST_RMD160: - copy_digest(entry, rmd160, digest); - break; - case ARCHIVE_ENTRY_DIGEST_SHA1: - copy_digest(entry, sha1, digest); - break; - case ARCHIVE_ENTRY_DIGEST_SHA256: - copy_digest(entry, sha256, digest); - break; - case ARCHIVE_ENTRY_DIGEST_SHA384: - copy_digest(entry, sha384, digest); - break; - case ARCHIVE_ENTRY_DIGEST_SHA512: - copy_digest(entry, sha512, digest); - break; - default: - return ARCHIVE_WARN; - } - - return ARCHIVE_OK; -#undef copy_digest -} - -/* - * ACL management. The following would, of course, be a lot simpler - * if: 1) the last draft of POSIX.1e were a really thorough and - * complete standard that addressed the needs of ACL archiving and 2) - * everyone followed it faithfully. Alas, neither is true, so the - * following is a lot more complex than might seem necessary to the - * uninitiated. - */ - -struct archive_acl * -archive_entry_acl(struct archive_entry *entry) -{ - return &entry->acl; -} - -void -archive_entry_acl_clear(struct archive_entry *entry) -{ - archive_acl_clear(&entry->acl); -} - -/* - * Add a single ACL entry to the internal list of ACL data. - */ -int -archive_entry_acl_add_entry(struct archive_entry *entry, - int type, int permset, int tag, int id, const char *name) -{ - return archive_acl_add_entry(&entry->acl, type, permset, tag, id, name); -} - -/* - * As above, but with a wide-character name. - */ -int -archive_entry_acl_add_entry_w(struct archive_entry *entry, - int type, int permset, int tag, int id, const wchar_t *name) -{ - return archive_acl_add_entry_w_len(&entry->acl, - type, permset, tag, id, name, wcslen(name)); -} - -/* - * Return a bitmask of ACL types in an archive entry ACL list - */ -int -archive_entry_acl_types(struct archive_entry *entry) -{ - return (archive_acl_types(&entry->acl)); -} - -/* - * Return a count of entries matching "want_type". - */ -int -archive_entry_acl_count(struct archive_entry *entry, int want_type) -{ - return archive_acl_count(&entry->acl, want_type); -} - -/* - * Prepare for reading entries from the ACL data. Returns a count - * of entries matching "want_type", or zero if there are no - * non-extended ACL entries of that type. - */ -int -archive_entry_acl_reset(struct archive_entry *entry, int want_type) -{ - return archive_acl_reset(&entry->acl, want_type); -} - -/* - * Return the next ACL entry in the list. Fake entries for the - * standard permissions and include them in the returned list. - */ -int -archive_entry_acl_next(struct archive_entry *entry, int want_type, int *type, - int *permset, int *tag, int *id, const char **name) -{ - int r; - r = archive_acl_next(entry->archive, &entry->acl, want_type, type, - permset, tag, id, name); - if (r == ARCHIVE_FATAL && errno == ENOMEM) - __archive_errx(1, "No memory"); - return (r); -} - -/* - * Generate a text version of the ACL. The flags parameter controls - * the style of the generated ACL. - */ -wchar_t * -archive_entry_acl_to_text_w(struct archive_entry *entry, la_ssize_t *len, - int flags) -{ - return (archive_acl_to_text_w(&entry->acl, len, flags, - entry->archive)); -} - -char * -archive_entry_acl_to_text(struct archive_entry *entry, la_ssize_t *len, - int flags) -{ - return (archive_acl_to_text_l(&entry->acl, len, flags, NULL)); -} - -char * -_archive_entry_acl_to_text_l(struct archive_entry *entry, ssize_t *len, - int flags, struct archive_string_conv *sc) -{ - return (archive_acl_to_text_l(&entry->acl, len, flags, sc)); -} - -/* - * ACL text parser. - */ -int -archive_entry_acl_from_text_w(struct archive_entry *entry, - const wchar_t *wtext, int type) -{ - return (archive_acl_from_text_w(&entry->acl, wtext, type)); -} - -int -archive_entry_acl_from_text(struct archive_entry *entry, - const char *text, int type) -{ - return (archive_acl_from_text_l(&entry->acl, text, type, NULL)); -} - -int -_archive_entry_acl_from_text_l(struct archive_entry *entry, const char *text, - int type, struct archive_string_conv *sc) -{ - return (archive_acl_from_text_l(&entry->acl, text, type, sc)); -} - -/* Deprecated */ -static int -archive_entry_acl_text_compat(int *flags) -{ - if ((*flags & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) == 0) - return (1); - - /* ABI compat with old ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID */ - if ((*flags & OLD_ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID) != 0) - *flags |= ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID; - - /* ABI compat with old ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT */ - if ((*flags & OLD_ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT) != 0) - *flags |= ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT; - - *flags |= ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA; - - return (0); -} - -/* Deprecated */ -const wchar_t * -archive_entry_acl_text_w(struct archive_entry *entry, int flags) -{ - free(entry->acl.acl_text_w); - entry->acl.acl_text_w = NULL; - if (archive_entry_acl_text_compat(&flags) == 0) - entry->acl.acl_text_w = archive_acl_to_text_w(&entry->acl, - NULL, flags, entry->archive); - return (entry->acl.acl_text_w); -} - -/* Deprecated */ -const char * -archive_entry_acl_text(struct archive_entry *entry, int flags) -{ - free(entry->acl.acl_text); - entry->acl.acl_text = NULL; - if (archive_entry_acl_text_compat(&flags) == 0) - entry->acl.acl_text = archive_acl_to_text_l(&entry->acl, NULL, - flags, NULL); - - return (entry->acl.acl_text); -} - -/* Deprecated */ -int -_archive_entry_acl_text_l(struct archive_entry *entry, int flags, - const char **acl_text, size_t *len, struct archive_string_conv *sc) -{ - free(entry->acl.acl_text); - entry->acl.acl_text = NULL; - - if (archive_entry_acl_text_compat(&flags) == 0) - entry->acl.acl_text = archive_acl_to_text_l(&entry->acl, - (ssize_t *)len, flags, sc); - - *acl_text = entry->acl.acl_text; - - return (0); -} - -/* - * Following code is modified from UC Berkeley sources, and - * is subject to the following copyright notice. - */ - -/*- - * Copyright (c) 1993 - * The Regents of the University of California. 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. - * 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. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. - */ - -/* - * Supported file flags on FreeBSD and Mac OS: - * sappnd,sappend SF_APPEND - * arch,archived SF_ARCHIVED - * schg,schange,simmutable SF_IMMUTABLE - * sunlnk,sunlink SF_NOUNLINK (FreeBSD only) - * uappnd,uappend UF_APPEND - * compressed UF_COMPRESSED (Mac OS only) - * hidden,uhidden UF_HIDDEN - * uchg,uchange,uimmutable UF_IMMUTABLE - * nodump UF_NODUMP - * uunlnk,uunlink UF_NOUNLINK (FreeBSD only) - * offline,uoffline UF_OFFLINE (FreeBSD only) - * opaque UF_OPAQUE - * rdonly,urdonly,readonly UF_READONLY (FreeBSD only) - * reparse,ureparse UF_REPARSE (FreeBSD only) - * sparse,usparse UF_SPARSE (FreeBSD only) - * system,usystem UF_SYSTEM (FreeBSD only) - * - * See chflags(2) for more information - * - * Supported file attributes on Linux: - * a append only FS_APPEND_FL sappnd - * A no atime updates FS_NOATIME_FL atime - * c compress FS_COMPR_FL compress - * C no copy on write FS_NOCOW_FL cow - * d no dump FS_NODUMP_FL dump - * D synchronous directory updates FS_DIRSYNC_FL dirsync - * i immutable FS_IMMUTABLE_FL schg - * j data journalling FS_JOURNAL_DATA_FL journal - * P project hierarchy FS_PROJINHERIT_FL projinherit - * s secure deletion FS_SECRM_FL securedeletion - * S synchronous updates FS_SYNC_FL sync - * t no tail-merging FS_NOTAIL_FL tail - * T top of directory hierarchy FS_TOPDIR_FL topdir - * u undeletable FS_UNRM_FL undel - * - * See ioctl_iflags(2) for more information - * - * Equivalent file flags supported on FreeBSD / Mac OS and Linux: - * SF_APPEND FS_APPEND_FL sappnd - * SF_IMMUTABLE FS_IMMUTABLE_FL schg - * UF_NODUMP FS_NODUMP_FL nodump - */ - -static const struct flag { - const char *name; - const wchar_t *wname; - unsigned long set; - unsigned long clear; -} fileflags[] = { - /* Preferred (shorter) names per flag first, all prefixed by "no" */ -#ifdef SF_APPEND - { "nosappnd", L"nosappnd", SF_APPEND, 0}, - { "nosappend", L"nosappend", SF_APPEND, 0}, -#endif -#if defined(FS_APPEND_FL) /* 'a' */ - { "nosappnd", L"nosappnd", FS_APPEND_FL, 0}, - { "nosappend", L"nosappend", FS_APPEND_FL, 0}, -#elif defined(EXT2_APPEND_FL) /* 'a' */ - { "nosappnd", L"nosappnd", EXT2_APPEND_FL, 0}, - { "nosappend", L"nosappend", EXT2_APPEND_FL, 0}, -#endif -#ifdef SF_ARCHIVED - { "noarch", L"noarch", SF_ARCHIVED, 0}, - { "noarchived", L"noarchived", SF_ARCHIVED, 0}, -#endif -#ifdef SF_IMMUTABLE - { "noschg", L"noschg", SF_IMMUTABLE, 0}, - { "noschange", L"noschange", SF_IMMUTABLE, 0}, - { "nosimmutable", L"nosimmutable", SF_IMMUTABLE, 0}, -#endif -#if defined(FS_IMMUTABLE_FL) /* 'i' */ - { "noschg", L"noschg", FS_IMMUTABLE_FL, 0}, - { "noschange", L"noschange", FS_IMMUTABLE_FL, 0}, - { "nosimmutable", L"nosimmutable", FS_IMMUTABLE_FL, 0}, -#elif defined(EXT2_IMMUTABLE_FL) /* 'i' */ - { "noschg", L"noschg", EXT2_IMMUTABLE_FL, 0}, - { "noschange", L"noschange", EXT2_IMMUTABLE_FL, 0}, - { "nosimmutable", L"nosimmutable", EXT2_IMMUTABLE_FL, 0}, -#endif -#ifdef SF_NOUNLINK - { "nosunlnk", L"nosunlnk", SF_NOUNLINK, 0}, - { "nosunlink", L"nosunlink", SF_NOUNLINK, 0}, -#endif -#ifdef UF_APPEND - { "nouappnd", L"nouappnd", UF_APPEND, 0}, - { "nouappend", L"nouappend", UF_APPEND, 0}, -#endif -#ifdef UF_IMMUTABLE - { "nouchg", L"nouchg", UF_IMMUTABLE, 0}, - { "nouchange", L"nouchange", UF_IMMUTABLE, 0}, - { "nouimmutable", L"nouimmutable", UF_IMMUTABLE, 0}, -#endif -#ifdef UF_NODUMP - { "nodump", L"nodump", 0, UF_NODUMP}, -#endif -#if defined(FS_NODUMP_FL) /* 'd' */ - { "nodump", L"nodump", 0, FS_NODUMP_FL}, -#elif defined(EXT2_NODUMP_FL) - { "nodump", L"nodump", 0, EXT2_NODUMP_FL}, -#endif -#ifdef UF_OPAQUE - { "noopaque", L"noopaque", UF_OPAQUE, 0}, -#endif -#ifdef UF_NOUNLINK - { "nouunlnk", L"nouunlnk", UF_NOUNLINK, 0}, - { "nouunlink", L"nouunlink", UF_NOUNLINK, 0}, -#endif -#ifdef UF_COMPRESSED - /* Mac OS */ - { "nocompressed", L"nocompressed", UF_COMPRESSED, 0}, -#endif -#ifdef UF_HIDDEN - { "nohidden", L"nohidden", UF_HIDDEN, 0}, - { "nouhidden", L"nouhidden", UF_HIDDEN, 0}, -#endif -#ifdef FILE_ATTRIBUTE_HIDDEN - { "nohidden", L"nohidden", FILE_ATTRIBUTE_HIDDEN, 0}, - { "nouhidden", L"nouhidden", FILE_ATTRIBUTE_HIDDEN, 0}, -#endif -#ifdef UF_OFFLINE - { "nooffline", L"nooffline", UF_OFFLINE, 0}, - { "nouoffline", L"nouoffline", UF_OFFLINE, 0}, -#endif -#ifdef UF_READONLY - { "nordonly", L"nordonly", UF_READONLY, 0}, - { "nourdonly", L"nourdonly", UF_READONLY, 0}, - { "noreadonly", L"noreadonly", UF_READONLY, 0}, -#endif -#ifdef FILE_ATTRIBUTE_READONLY - { "nordonly", L"nordonly", FILE_ATTRIBUTE_READONLY, 0}, - { "nourdonly", L"nourdonly", FILE_ATTRIBUTE_READONLY, 0}, - { "noreadonly", L"noreadonly", FILE_ATTRIBUTE_READONLY, 0}, -#endif -#ifdef UF_SPARSE - { "nosparse", L"nosparse", UF_SPARSE, 0}, - { "nousparse", L"nousparse", UF_SPARSE, 0}, -#endif -#ifdef UF_REPARSE - { "noreparse", L"noreparse", UF_REPARSE, 0}, - { "noureparse", L"noureparse", UF_REPARSE, 0}, -#endif -#ifdef UF_SYSTEM - { "nosystem", L"nosystem", UF_SYSTEM, 0}, - { "nousystem", L"nousystem", UF_SYSTEM, 0}, -#endif -#ifdef FILE_ATTRIBUTE_SYSTEM - { "nosystem", L"nosystem", FILE_ATTRIBUTE_SYSTEM, 0}, - { "nousystem", L"nousystem", FILE_ATTRIBUTE_SYSTEM, 0}, -#endif -#if defined(FS_UNRM_FL) /* 'u' */ - { "noundel", L"noundel", FS_UNRM_FL, 0}, -#elif defined(EXT2_UNRM_FL) - { "noundel", L"noundel", EXT2_UNRM_FL, 0}, -#endif - -#if defined(FS_COMPR_FL) /* 'c' */ - { "nocompress", L"nocompress", FS_COMPR_FL, 0}, -#elif defined(EXT2_COMPR_FL) - { "nocompress", L"nocompress", EXT2_COMPR_FL, 0}, -#endif - -#if defined(FS_NOATIME_FL) /* 'A' */ - { "noatime", L"noatime", 0, FS_NOATIME_FL}, -#elif defined(EXT2_NOATIME_FL) - { "noatime", L"noatime", 0, EXT2_NOATIME_FL}, -#endif -#if defined(FS_DIRSYNC_FL) /* 'D' */ - { "nodirsync", L"nodirsync", FS_DIRSYNC_FL, 0}, -#elif defined(EXT2_DIRSYNC_FL) - { "nodirsync", L"nodirsync", EXT2_DIRSYNC_FL, 0}, -#endif -#if defined(FS_JOURNAL_DATA_FL) /* 'j' */ - { "nojournal-data",L"nojournal-data", FS_JOURNAL_DATA_FL, 0}, - { "nojournal", L"nojournal", FS_JOURNAL_DATA_FL, 0}, -#elif defined(EXT3_JOURNAL_DATA_FL) - { "nojournal-data",L"nojournal-data", EXT3_JOURNAL_DATA_FL, 0}, - { "nojournal", L"nojournal", EXT3_JOURNAL_DATA_FL, 0}, -#endif -#if defined(FS_SECRM_FL) /* 's' */ - { "nosecdel", L"nosecdel", FS_SECRM_FL, 0}, - { "nosecuredeletion",L"nosecuredeletion",FS_SECRM_FL, 0}, -#elif defined(EXT2_SECRM_FL) - { "nosecdel", L"nosecdel", EXT2_SECRM_FL, 0}, - { "nosecuredeletion",L"nosecuredeletion",EXT2_SECRM_FL, 0}, -#endif -#if defined(FS_SYNC_FL) /* 'S' */ - { "nosync", L"nosync", FS_SYNC_FL, 0}, -#elif defined(EXT2_SYNC_FL) - { "nosync", L"nosync", EXT2_SYNC_FL, 0}, -#endif -#if defined(FS_NOTAIL_FL) /* 't' */ - { "notail", L"notail", 0, FS_NOTAIL_FL}, -#elif defined(EXT2_NOTAIL_FL) - { "notail", L"notail", 0, EXT2_NOTAIL_FL}, -#endif -#if defined(FS_TOPDIR_FL) /* 'T' */ - { "notopdir", L"notopdir", FS_TOPDIR_FL, 0}, -#elif defined(EXT2_TOPDIR_FL) - { "notopdir", L"notopdir", EXT2_TOPDIR_FL, 0}, -#endif -#ifdef FS_NOCOW_FL /* 'C' */ - { "nocow", L"nocow", 0, FS_NOCOW_FL}, -#endif -#ifdef FS_PROJINHERIT_FL /* 'P' */ - { "noprojinherit",L"noprojinherit", FS_PROJINHERIT_FL, 0}, -#endif - { NULL, NULL, 0, 0} -}; - -/* - * fflagstostr -- - * Convert file flags to a comma-separated string. If no flags - * are set, return the empty string. - */ -static char * -ae_fflagstostr(unsigned long bitset, unsigned long bitclear) -{ - char *string, *dp; - const char *sp; - unsigned long bits; - const struct flag *flag; - size_t length; - - bits = bitset | bitclear; - length = 0; - for (flag = fileflags; flag->name != NULL; flag++) - if (bits & (flag->set | flag->clear)) { - length += strlen(flag->name) + 1; - bits &= ~(flag->set | flag->clear); - } - - if (length == 0) - return (NULL); - string = (char *)malloc(length); - if (string == NULL) - return (NULL); - - dp = string; - for (flag = fileflags; flag->name != NULL; flag++) { - if (bitset & flag->set || bitclear & flag->clear) { - sp = flag->name + 2; - } else if (bitset & flag->clear || bitclear & flag->set) { - sp = flag->name; - } else - continue; - bitset &= ~(flag->set | flag->clear); - bitclear &= ~(flag->set | flag->clear); - if (dp > string) - *dp++ = ','; - while ((*dp++ = *sp++) != '\0') - ; - dp--; - } - - *dp = '\0'; - return (string); -} - -/* - * strtofflags -- - * Take string of arguments and return file flags. This - * version works a little differently than strtofflags(3). - * In particular, it always tests every token, skipping any - * unrecognized tokens. It returns a pointer to the first - * unrecognized token, or NULL if every token was recognized. - * This version is also const-correct and does not modify the - * provided string. - */ -static const char * -ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp) -{ - const char *start, *end; - const struct flag *flag; - unsigned long set, clear; - const char *failed; - - set = clear = 0; - start = s; - failed = NULL; - /* Find start of first token. */ - while (*start == '\t' || *start == ' ' || *start == ',') - start++; - while (*start != '\0') { - size_t length; - /* Locate end of token. */ - end = start; - while (*end != '\0' && *end != '\t' && - *end != ' ' && *end != ',') - end++; - length = end - start; - for (flag = fileflags; flag->name != NULL; flag++) { - size_t flag_length = strlen(flag->name); - if (length == flag_length - && memcmp(start, flag->name, length) == 0) { - /* Matched "noXXXX", so reverse the sense. */ - clear |= flag->set; - set |= flag->clear; - break; - } else if (length == flag_length - 2 - && memcmp(start, flag->name + 2, length) == 0) { - /* Matched "XXXX", so don't reverse. */ - set |= flag->set; - clear |= flag->clear; - break; - } - } - /* Ignore unknown flag names. */ - if (flag->name == NULL && failed == NULL) - failed = start; - - /* Find start of next token. */ - start = end; - while (*start == '\t' || *start == ' ' || *start == ',') - start++; - - } - - if (setp) - *setp = set; - if (clrp) - *clrp = clear; - - /* Return location of first failure. */ - return (failed); -} - -/* - * wcstofflags -- - * Take string of arguments and return file flags. This - * version works a little differently than strtofflags(3). - * In particular, it always tests every token, skipping any - * unrecognized tokens. It returns a pointer to the first - * unrecognized token, or NULL if every token was recognized. - * This version is also const-correct and does not modify the - * provided string. - */ -static const wchar_t * -ae_wcstofflags(const wchar_t *s, unsigned long *setp, unsigned long *clrp) -{ - const wchar_t *start, *end; - const struct flag *flag; - unsigned long set, clear; - const wchar_t *failed; - - set = clear = 0; - start = s; - failed = NULL; - /* Find start of first token. */ - while (*start == L'\t' || *start == L' ' || *start == L',') - start++; - while (*start != L'\0') { - size_t length; - /* Locate end of token. */ - end = start; - while (*end != L'\0' && *end != L'\t' && - *end != L' ' && *end != L',') - end++; - length = end - start; - for (flag = fileflags; flag->wname != NULL; flag++) { - size_t flag_length = wcslen(flag->wname); - if (length == flag_length - && wmemcmp(start, flag->wname, length) == 0) { - /* Matched "noXXXX", so reverse the sense. */ - clear |= flag->set; - set |= flag->clear; - break; - } else if (length == flag_length - 2 - && wmemcmp(start, flag->wname + 2, length) == 0) { - /* Matched "XXXX", so don't reverse. */ - set |= flag->set; - clear |= flag->clear; - break; - } - } - /* Ignore unknown flag names. */ - if (flag->wname == NULL && failed == NULL) - failed = start; - - /* Find start of next token. */ - start = end; - while (*start == L'\t' || *start == L' ' || *start == L',') - start++; - - } - - if (setp) - *setp = set; - if (clrp) - *clrp = clear; - - /* Return location of first failure. */ - return (failed); -} - - -#ifdef TEST -#include -int -main(int argc, char **argv) -{ - struct archive_entry *entry = archive_entry_new(); - unsigned long set, clear; - const wchar_t *remainder; - - remainder = archive_entry_copy_fflags_text_w(entry, L"nosappnd dump archive,,,,,,,"); - archive_entry_fflags(entry, &set, &clear); - - wprintf(L"set=0x%lX clear=0x%lX remainder='%ls'\n", set, clear, remainder); - - wprintf(L"new flags='%s'\n", archive_entry_fflags_text(entry)); - return (0); -} -#endif diff --git a/thirdparty/libarchive/libarchive/archive_entry.h b/thirdparty/libarchive/libarchive/archive_entry.h deleted file mode 100644 index e4c0ab344..000000000 --- a/thirdparty/libarchive/libarchive/archive_entry.h +++ /dev/null @@ -1,723 +0,0 @@ -/*- - * Copyright (c) 2003-2008 Tim Kientzle - * Copyright (c) 2016 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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: head/lib/libarchive/archive_entry.h 201096 2009-12-28 02:41:27Z kientzle $ - */ - -#ifndef ARCHIVE_ENTRY_H_INCLUDED -#define ARCHIVE_ENTRY_H_INCLUDED - -/* Note: Compiler will complain if this does not match archive.h! */ -#define ARCHIVE_VERSION_NUMBER 3007002 - -/* - * Note: archive_entry.h is for use outside of libarchive; the - * configuration headers (config.h, archive_platform.h, etc.) are - * purely internal. Do NOT use HAVE_XXX configuration macros to - * control the behavior of this header! If you must conditionalize, - * use predefined compiler and/or platform macros. - */ - -#include -#include /* for wchar_t */ -#include -#include - -#if defined(_WIN32) && !defined(__CYGWIN__) -#include -#endif - -/* Get a suitable 64-bit integer type. */ -#if !defined(__LA_INT64_T_DEFINED) -# if ARCHIVE_VERSION_NUMBER < 4000000 -#define __LA_INT64_T la_int64_t -# endif -#define __LA_INT64_T_DEFINED -# if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__) -typedef __int64 la_int64_t; -# else -#include -# if defined(_SCO_DS) || defined(__osf__) -typedef long long la_int64_t; -# else -typedef int64_t la_int64_t; -# endif -# endif -#endif - -/* The la_ssize_t should match the type used in 'struct stat' */ -#if !defined(__LA_SSIZE_T_DEFINED) -/* Older code relied on the __LA_SSIZE_T macro; after 4.0 we'll switch to the typedef exclusively. */ -# if ARCHIVE_VERSION_NUMBER < 4000000 -#define __LA_SSIZE_T la_ssize_t -# endif -#define __LA_SSIZE_T_DEFINED -# if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__) -# if defined(_SSIZE_T_DEFINED) || defined(_SSIZE_T_) -typedef ssize_t la_ssize_t; -# elif defined(_WIN64) -typedef __int64 la_ssize_t; -# else -typedef long la_ssize_t; -# endif -# else -# include /* ssize_t */ -typedef ssize_t la_ssize_t; -# endif -#endif - -/* Get a suitable definition for mode_t */ -#if ARCHIVE_VERSION_NUMBER >= 3999000 -/* Switch to plain 'int' for libarchive 4.0. It's less broken than 'mode_t' */ -# define __LA_MODE_T int -#elif defined(_WIN32) && !defined(__CYGWIN__) && !defined(__BORLANDC__) && !defined(__WATCOMC__) -# define __LA_MODE_T unsigned short -#else -# define __LA_MODE_T mode_t -#endif - -/* Large file support for Android */ -#if defined(__LIBARCHIVE_BUILD) && defined(__ANDROID__) -#include "android_lf.h" -#endif - -/* - * On Windows, define LIBARCHIVE_STATIC if you're building or using a - * .lib. The default here assumes you're building a DLL. Only - * libarchive source should ever define __LIBARCHIVE_BUILD. - */ -#if ((defined __WIN32__) || (defined _WIN32) || defined(__CYGWIN__)) && (!defined LIBARCHIVE_STATIC) -# ifdef __LIBARCHIVE_BUILD -# ifdef __GNUC__ -# define __LA_DECL __attribute__((dllexport)) extern -# else -# define __LA_DECL __declspec(dllexport) -# endif -# else -# ifdef __GNUC__ -# define __LA_DECL -# else -# define __LA_DECL __declspec(dllimport) -# endif -# endif -#elif defined __LIBARCHIVE_ENABLE_VISIBILITY -# define __LA_DECL __attribute__((visibility("default"))) -#else -/* Static libraries on all platforms and shared libraries on non-Windows. */ -# define __LA_DECL -#endif - -#if defined(__GNUC__) && __GNUC__ >= 3 && __GNUC_MINOR__ >= 1 -# define __LA_DEPRECATED __attribute__((deprecated)) -#else -# define __LA_DEPRECATED -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Description of an archive entry. - * - * You can think of this as "struct stat" with some text fields added in. - * - * TODO: Add "comment", "charset", and possibly other entries that are - * supported by "pax interchange" format. However, GNU, ustar, cpio, - * and other variants don't support these features, so they're not an - * excruciatingly high priority right now. - * - * TODO: "pax interchange" format allows essentially arbitrary - * key/value attributes to be attached to any entry. Supporting - * such extensions may make this library useful for special - * applications (e.g., a package manager could attach special - * package-management attributes to each entry). - */ -struct archive; -struct archive_entry; - -/* - * File-type constants. These are returned from archive_entry_filetype() - * and passed to archive_entry_set_filetype(). - * - * These values match S_XXX defines on every platform I've checked, - * including Windows, AIX, Linux, Solaris, and BSD. They're - * (re)defined here because platforms generally don't define the ones - * they don't support. For example, Windows doesn't define S_IFLNK or - * S_IFBLK. Instead of having a mass of conditional logic and system - * checks to define any S_XXX values that aren't supported locally, - * I've just defined a new set of such constants so that - * libarchive-based applications can manipulate and identify archive - * entries properly even if the hosting platform can't store them on - * disk. - * - * These values are also used directly within some portable formats, - * such as cpio. If you find a platform that varies from these, the - * correct solution is to leave these alone and translate from these - * portable values to platform-native values when entries are read from - * or written to disk. - */ -/* - * In libarchive 4.0, we can drop the casts here. - * They're needed to work around Borland C's broken mode_t. - */ -#define AE_IFMT ((__LA_MODE_T)0170000) -#define AE_IFREG ((__LA_MODE_T)0100000) -#define AE_IFLNK ((__LA_MODE_T)0120000) -#define AE_IFSOCK ((__LA_MODE_T)0140000) -#define AE_IFCHR ((__LA_MODE_T)0020000) -#define AE_IFBLK ((__LA_MODE_T)0060000) -#define AE_IFDIR ((__LA_MODE_T)0040000) -#define AE_IFIFO ((__LA_MODE_T)0010000) - -/* - * Symlink types - */ -#define AE_SYMLINK_TYPE_UNDEFINED 0 -#define AE_SYMLINK_TYPE_FILE 1 -#define AE_SYMLINK_TYPE_DIRECTORY 2 - -/* - * Basic object manipulation - */ - -__LA_DECL struct archive_entry *archive_entry_clear(struct archive_entry *); -/* The 'clone' function does a deep copy; all of the strings are copied too. */ -__LA_DECL struct archive_entry *archive_entry_clone(struct archive_entry *); -__LA_DECL void archive_entry_free(struct archive_entry *); -__LA_DECL struct archive_entry *archive_entry_new(void); - -/* - * This form of archive_entry_new2() will pull character-set - * conversion information from the specified archive handle. The - * older archive_entry_new(void) form is equivalent to calling - * archive_entry_new2(NULL) and will result in the use of an internal - * default character-set conversion. - */ -__LA_DECL struct archive_entry *archive_entry_new2(struct archive *); - -/* - * Retrieve fields from an archive_entry. - * - * There are a number of implicit conversions among these fields. For - * example, if a regular string field is set and you read the _w wide - * character field, the entry will implicitly convert narrow-to-wide - * using the current locale. Similarly, dev values are automatically - * updated when you write devmajor or devminor and vice versa. - * - * In addition, fields can be "set" or "unset." Unset string fields - * return NULL, non-string fields have _is_set() functions to test - * whether they've been set. You can "unset" a string field by - * assigning NULL; non-string fields have _unset() functions to - * unset them. - * - * Note: There is one ambiguity in the above; string fields will - * also return NULL when implicit character set conversions fail. - * This is usually what you want. - */ -__LA_DECL time_t archive_entry_atime(struct archive_entry *); -__LA_DECL long archive_entry_atime_nsec(struct archive_entry *); -__LA_DECL int archive_entry_atime_is_set(struct archive_entry *); -__LA_DECL time_t archive_entry_birthtime(struct archive_entry *); -__LA_DECL long archive_entry_birthtime_nsec(struct archive_entry *); -__LA_DECL int archive_entry_birthtime_is_set(struct archive_entry *); -__LA_DECL time_t archive_entry_ctime(struct archive_entry *); -__LA_DECL long archive_entry_ctime_nsec(struct archive_entry *); -__LA_DECL int archive_entry_ctime_is_set(struct archive_entry *); -__LA_DECL dev_t archive_entry_dev(struct archive_entry *); -__LA_DECL int archive_entry_dev_is_set(struct archive_entry *); -__LA_DECL dev_t archive_entry_devmajor(struct archive_entry *); -__LA_DECL dev_t archive_entry_devminor(struct archive_entry *); -__LA_DECL __LA_MODE_T archive_entry_filetype(struct archive_entry *); -__LA_DECL void archive_entry_fflags(struct archive_entry *, - unsigned long * /* set */, - unsigned long * /* clear */); -__LA_DECL const char *archive_entry_fflags_text(struct archive_entry *); -__LA_DECL la_int64_t archive_entry_gid(struct archive_entry *); -__LA_DECL const char *archive_entry_gname(struct archive_entry *); -__LA_DECL const char *archive_entry_gname_utf8(struct archive_entry *); -__LA_DECL const wchar_t *archive_entry_gname_w(struct archive_entry *); -__LA_DECL const char *archive_entry_hardlink(struct archive_entry *); -__LA_DECL const char *archive_entry_hardlink_utf8(struct archive_entry *); -__LA_DECL const wchar_t *archive_entry_hardlink_w(struct archive_entry *); -__LA_DECL la_int64_t archive_entry_ino(struct archive_entry *); -__LA_DECL la_int64_t archive_entry_ino64(struct archive_entry *); -__LA_DECL int archive_entry_ino_is_set(struct archive_entry *); -__LA_DECL __LA_MODE_T archive_entry_mode(struct archive_entry *); -__LA_DECL time_t archive_entry_mtime(struct archive_entry *); -__LA_DECL long archive_entry_mtime_nsec(struct archive_entry *); -__LA_DECL int archive_entry_mtime_is_set(struct archive_entry *); -__LA_DECL unsigned int archive_entry_nlink(struct archive_entry *); -__LA_DECL const char *archive_entry_pathname(struct archive_entry *); -__LA_DECL const char *archive_entry_pathname_utf8(struct archive_entry *); -__LA_DECL const wchar_t *archive_entry_pathname_w(struct archive_entry *); -__LA_DECL __LA_MODE_T archive_entry_perm(struct archive_entry *); -__LA_DECL dev_t archive_entry_rdev(struct archive_entry *); -__LA_DECL dev_t archive_entry_rdevmajor(struct archive_entry *); -__LA_DECL dev_t archive_entry_rdevminor(struct archive_entry *); -__LA_DECL const char *archive_entry_sourcepath(struct archive_entry *); -__LA_DECL const wchar_t *archive_entry_sourcepath_w(struct archive_entry *); -__LA_DECL la_int64_t archive_entry_size(struct archive_entry *); -__LA_DECL int archive_entry_size_is_set(struct archive_entry *); -__LA_DECL const char *archive_entry_strmode(struct archive_entry *); -__LA_DECL const char *archive_entry_symlink(struct archive_entry *); -__LA_DECL const char *archive_entry_symlink_utf8(struct archive_entry *); -__LA_DECL int archive_entry_symlink_type(struct archive_entry *); -__LA_DECL const wchar_t *archive_entry_symlink_w(struct archive_entry *); -__LA_DECL la_int64_t archive_entry_uid(struct archive_entry *); -__LA_DECL const char *archive_entry_uname(struct archive_entry *); -__LA_DECL const char *archive_entry_uname_utf8(struct archive_entry *); -__LA_DECL const wchar_t *archive_entry_uname_w(struct archive_entry *); -__LA_DECL int archive_entry_is_data_encrypted(struct archive_entry *); -__LA_DECL int archive_entry_is_metadata_encrypted(struct archive_entry *); -__LA_DECL int archive_entry_is_encrypted(struct archive_entry *); - -/* - * Set fields in an archive_entry. - * - * Note: Before libarchive 2.4, there were 'set' and 'copy' versions - * of the string setters. 'copy' copied the actual string, 'set' just - * stored the pointer. In libarchive 2.4 and later, strings are - * always copied. - */ - -__LA_DECL void archive_entry_set_atime(struct archive_entry *, time_t, long); -__LA_DECL void archive_entry_unset_atime(struct archive_entry *); -#if defined(_WIN32) && !defined(__CYGWIN__) -__LA_DECL void archive_entry_copy_bhfi(struct archive_entry *, BY_HANDLE_FILE_INFORMATION *); -#endif -__LA_DECL void archive_entry_set_birthtime(struct archive_entry *, time_t, long); -__LA_DECL void archive_entry_unset_birthtime(struct archive_entry *); -__LA_DECL void archive_entry_set_ctime(struct archive_entry *, time_t, long); -__LA_DECL void archive_entry_unset_ctime(struct archive_entry *); -__LA_DECL void archive_entry_set_dev(struct archive_entry *, dev_t); -__LA_DECL void archive_entry_set_devmajor(struct archive_entry *, dev_t); -__LA_DECL void archive_entry_set_devminor(struct archive_entry *, dev_t); -__LA_DECL void archive_entry_set_filetype(struct archive_entry *, unsigned int); -__LA_DECL void archive_entry_set_fflags(struct archive_entry *, - unsigned long /* set */, unsigned long /* clear */); -/* Returns pointer to start of first invalid token, or NULL if none. */ -/* Note that all recognized tokens are processed, regardless. */ -__LA_DECL const char *archive_entry_copy_fflags_text(struct archive_entry *, - const char *); -__LA_DECL const wchar_t *archive_entry_copy_fflags_text_w(struct archive_entry *, - const wchar_t *); -__LA_DECL void archive_entry_set_gid(struct archive_entry *, la_int64_t); -__LA_DECL void archive_entry_set_gname(struct archive_entry *, const char *); -__LA_DECL void archive_entry_set_gname_utf8(struct archive_entry *, const char *); -__LA_DECL void archive_entry_copy_gname(struct archive_entry *, const char *); -__LA_DECL void archive_entry_copy_gname_w(struct archive_entry *, const wchar_t *); -__LA_DECL int archive_entry_update_gname_utf8(struct archive_entry *, const char *); -__LA_DECL void archive_entry_set_hardlink(struct archive_entry *, const char *); -__LA_DECL void archive_entry_set_hardlink_utf8(struct archive_entry *, const char *); -__LA_DECL void archive_entry_copy_hardlink(struct archive_entry *, const char *); -__LA_DECL void archive_entry_copy_hardlink_w(struct archive_entry *, const wchar_t *); -__LA_DECL int archive_entry_update_hardlink_utf8(struct archive_entry *, const char *); -__LA_DECL void archive_entry_set_ino(struct archive_entry *, la_int64_t); -__LA_DECL void archive_entry_set_ino64(struct archive_entry *, la_int64_t); -__LA_DECL void archive_entry_set_link(struct archive_entry *, const char *); -__LA_DECL void archive_entry_set_link_utf8(struct archive_entry *, const char *); -__LA_DECL void archive_entry_copy_link(struct archive_entry *, const char *); -__LA_DECL void archive_entry_copy_link_w(struct archive_entry *, const wchar_t *); -__LA_DECL int archive_entry_update_link_utf8(struct archive_entry *, const char *); -__LA_DECL void archive_entry_set_mode(struct archive_entry *, __LA_MODE_T); -__LA_DECL void archive_entry_set_mtime(struct archive_entry *, time_t, long); -__LA_DECL void archive_entry_unset_mtime(struct archive_entry *); -__LA_DECL void archive_entry_set_nlink(struct archive_entry *, unsigned int); -__LA_DECL void archive_entry_set_pathname(struct archive_entry *, const char *); -__LA_DECL void archive_entry_set_pathname_utf8(struct archive_entry *, const char *); -__LA_DECL void archive_entry_copy_pathname(struct archive_entry *, const char *); -__LA_DECL void archive_entry_copy_pathname_w(struct archive_entry *, const wchar_t *); -__LA_DECL int archive_entry_update_pathname_utf8(struct archive_entry *, const char *); -__LA_DECL void archive_entry_set_perm(struct archive_entry *, __LA_MODE_T); -__LA_DECL void archive_entry_set_rdev(struct archive_entry *, dev_t); -__LA_DECL void archive_entry_set_rdevmajor(struct archive_entry *, dev_t); -__LA_DECL void archive_entry_set_rdevminor(struct archive_entry *, dev_t); -__LA_DECL void archive_entry_set_size(struct archive_entry *, la_int64_t); -__LA_DECL void archive_entry_unset_size(struct archive_entry *); -__LA_DECL void archive_entry_copy_sourcepath(struct archive_entry *, const char *); -__LA_DECL void archive_entry_copy_sourcepath_w(struct archive_entry *, const wchar_t *); -__LA_DECL void archive_entry_set_symlink(struct archive_entry *, const char *); -__LA_DECL void archive_entry_set_symlink_type(struct archive_entry *, int); -__LA_DECL void archive_entry_set_symlink_utf8(struct archive_entry *, const char *); -__LA_DECL void archive_entry_copy_symlink(struct archive_entry *, const char *); -__LA_DECL void archive_entry_copy_symlink_w(struct archive_entry *, const wchar_t *); -__LA_DECL int archive_entry_update_symlink_utf8(struct archive_entry *, const char *); -__LA_DECL void archive_entry_set_uid(struct archive_entry *, la_int64_t); -__LA_DECL void archive_entry_set_uname(struct archive_entry *, const char *); -__LA_DECL void archive_entry_set_uname_utf8(struct archive_entry *, const char *); -__LA_DECL void archive_entry_copy_uname(struct archive_entry *, const char *); -__LA_DECL void archive_entry_copy_uname_w(struct archive_entry *, const wchar_t *); -__LA_DECL int archive_entry_update_uname_utf8(struct archive_entry *, const char *); -__LA_DECL void archive_entry_set_is_data_encrypted(struct archive_entry *, char is_encrypted); -__LA_DECL void archive_entry_set_is_metadata_encrypted(struct archive_entry *, char is_encrypted); -/* - * Routines to bulk copy fields to/from a platform-native "struct - * stat." Libarchive used to just store a struct stat inside of each - * archive_entry object, but this created issues when trying to - * manipulate archives on systems different than the ones they were - * created on. - * - * TODO: On Linux and other LFS systems, provide both stat32 and - * stat64 versions of these functions and all of the macro glue so - * that archive_entry_stat is magically defined to - * archive_entry_stat32 or archive_entry_stat64 as appropriate. - */ -__LA_DECL const struct stat *archive_entry_stat(struct archive_entry *); -__LA_DECL void archive_entry_copy_stat(struct archive_entry *, const struct stat *); - -/* - * Storage for Mac OS-specific AppleDouble metadata information. - * Apple-format tar files store a separate binary blob containing - * encoded metadata with ACL, extended attributes, etc. - * This provides a place to store that blob. - */ - -__LA_DECL const void * archive_entry_mac_metadata(struct archive_entry *, size_t *); -__LA_DECL void archive_entry_copy_mac_metadata(struct archive_entry *, const void *, size_t); - -/* - * Digest routine. This is used to query the raw hex digest for the - * given entry. The type of digest is provided as an argument. - */ -#define ARCHIVE_ENTRY_DIGEST_MD5 0x00000001 -#define ARCHIVE_ENTRY_DIGEST_RMD160 0x00000002 -#define ARCHIVE_ENTRY_DIGEST_SHA1 0x00000003 -#define ARCHIVE_ENTRY_DIGEST_SHA256 0x00000004 -#define ARCHIVE_ENTRY_DIGEST_SHA384 0x00000005 -#define ARCHIVE_ENTRY_DIGEST_SHA512 0x00000006 - -__LA_DECL const unsigned char * archive_entry_digest(struct archive_entry *, int /* type */); - -/* - * ACL routines. This used to simply store and return text-format ACL - * strings, but that proved insufficient for a number of reasons: - * = clients need control over uname/uid and gname/gid mappings - * = there are many different ACL text formats - * = would like to be able to read/convert archives containing ACLs - * on platforms that lack ACL libraries - * - * This last point, in particular, forces me to implement a reasonably - * complete set of ACL support routines. - */ - -/* - * Permission bits. - */ -#define ARCHIVE_ENTRY_ACL_EXECUTE 0x00000001 -#define ARCHIVE_ENTRY_ACL_WRITE 0x00000002 -#define ARCHIVE_ENTRY_ACL_READ 0x00000004 -#define ARCHIVE_ENTRY_ACL_READ_DATA 0x00000008 -#define ARCHIVE_ENTRY_ACL_LIST_DIRECTORY 0x00000008 -#define ARCHIVE_ENTRY_ACL_WRITE_DATA 0x00000010 -#define ARCHIVE_ENTRY_ACL_ADD_FILE 0x00000010 -#define ARCHIVE_ENTRY_ACL_APPEND_DATA 0x00000020 -#define ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY 0x00000020 -#define ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS 0x00000040 -#define ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS 0x00000080 -#define ARCHIVE_ENTRY_ACL_DELETE_CHILD 0x00000100 -#define ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES 0x00000200 -#define ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES 0x00000400 -#define ARCHIVE_ENTRY_ACL_DELETE 0x00000800 -#define ARCHIVE_ENTRY_ACL_READ_ACL 0x00001000 -#define ARCHIVE_ENTRY_ACL_WRITE_ACL 0x00002000 -#define ARCHIVE_ENTRY_ACL_WRITE_OWNER 0x00004000 -#define ARCHIVE_ENTRY_ACL_SYNCHRONIZE 0x00008000 - -#define ARCHIVE_ENTRY_ACL_PERMS_POSIX1E \ - (ARCHIVE_ENTRY_ACL_EXECUTE \ - | ARCHIVE_ENTRY_ACL_WRITE \ - | ARCHIVE_ENTRY_ACL_READ) - -#define ARCHIVE_ENTRY_ACL_PERMS_NFS4 \ - (ARCHIVE_ENTRY_ACL_EXECUTE \ - | ARCHIVE_ENTRY_ACL_READ_DATA \ - | ARCHIVE_ENTRY_ACL_LIST_DIRECTORY \ - | ARCHIVE_ENTRY_ACL_WRITE_DATA \ - | ARCHIVE_ENTRY_ACL_ADD_FILE \ - | ARCHIVE_ENTRY_ACL_APPEND_DATA \ - | ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY \ - | ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS \ - | ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS \ - | ARCHIVE_ENTRY_ACL_DELETE_CHILD \ - | ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES \ - | ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES \ - | ARCHIVE_ENTRY_ACL_DELETE \ - | ARCHIVE_ENTRY_ACL_READ_ACL \ - | ARCHIVE_ENTRY_ACL_WRITE_ACL \ - | ARCHIVE_ENTRY_ACL_WRITE_OWNER \ - | ARCHIVE_ENTRY_ACL_SYNCHRONIZE) - -/* - * Inheritance values (NFS4 ACLs only); included in permset. - */ -#define ARCHIVE_ENTRY_ACL_ENTRY_INHERITED 0x01000000 -#define ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT 0x02000000 -#define ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT 0x04000000 -#define ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT 0x08000000 -#define ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY 0x10000000 -#define ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS 0x20000000 -#define ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS 0x40000000 - -#define ARCHIVE_ENTRY_ACL_INHERITANCE_NFS4 \ - (ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT \ - | ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT \ - | ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT \ - | ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY \ - | ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS \ - | ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS \ - | ARCHIVE_ENTRY_ACL_ENTRY_INHERITED) - -/* We need to be able to specify combinations of these. */ -#define ARCHIVE_ENTRY_ACL_TYPE_ACCESS 0x00000100 /* POSIX.1e only */ -#define ARCHIVE_ENTRY_ACL_TYPE_DEFAULT 0x00000200 /* POSIX.1e only */ -#define ARCHIVE_ENTRY_ACL_TYPE_ALLOW 0x00000400 /* NFS4 only */ -#define ARCHIVE_ENTRY_ACL_TYPE_DENY 0x00000800 /* NFS4 only */ -#define ARCHIVE_ENTRY_ACL_TYPE_AUDIT 0x00001000 /* NFS4 only */ -#define ARCHIVE_ENTRY_ACL_TYPE_ALARM 0x00002000 /* NFS4 only */ -#define ARCHIVE_ENTRY_ACL_TYPE_POSIX1E (ARCHIVE_ENTRY_ACL_TYPE_ACCESS \ - | ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) -#define ARCHIVE_ENTRY_ACL_TYPE_NFS4 (ARCHIVE_ENTRY_ACL_TYPE_ALLOW \ - | ARCHIVE_ENTRY_ACL_TYPE_DENY \ - | ARCHIVE_ENTRY_ACL_TYPE_AUDIT \ - | ARCHIVE_ENTRY_ACL_TYPE_ALARM) - -/* Tag values mimic POSIX.1e */ -#define ARCHIVE_ENTRY_ACL_USER 10001 /* Specified user. */ -#define ARCHIVE_ENTRY_ACL_USER_OBJ 10002 /* User who owns the file. */ -#define ARCHIVE_ENTRY_ACL_GROUP 10003 /* Specified group. */ -#define ARCHIVE_ENTRY_ACL_GROUP_OBJ 10004 /* Group who owns the file. */ -#define ARCHIVE_ENTRY_ACL_MASK 10005 /* Modify group access (POSIX.1e only) */ -#define ARCHIVE_ENTRY_ACL_OTHER 10006 /* Public (POSIX.1e only) */ -#define ARCHIVE_ENTRY_ACL_EVERYONE 10107 /* Everyone (NFS4 only) */ - -/* - * Set the ACL by clearing it and adding entries one at a time. - * Unlike the POSIX.1e ACL routines, you must specify the type - * (access/default) for each entry. Internally, the ACL data is just - * a soup of entries. API calls here allow you to retrieve just the - * entries of interest. This design (which goes against the spirit of - * POSIX.1e) is useful for handling archive formats that combine - * default and access information in a single ACL list. - */ -__LA_DECL void archive_entry_acl_clear(struct archive_entry *); -__LA_DECL int archive_entry_acl_add_entry(struct archive_entry *, - int /* type */, int /* permset */, int /* tag */, - int /* qual */, const char * /* name */); -__LA_DECL int archive_entry_acl_add_entry_w(struct archive_entry *, - int /* type */, int /* permset */, int /* tag */, - int /* qual */, const wchar_t * /* name */); - -/* - * To retrieve the ACL, first "reset", then repeatedly ask for the - * "next" entry. The want_type parameter allows you to request only - * certain types of entries. - */ -__LA_DECL int archive_entry_acl_reset(struct archive_entry *, int /* want_type */); -__LA_DECL int archive_entry_acl_next(struct archive_entry *, int /* want_type */, - int * /* type */, int * /* permset */, int * /* tag */, - int * /* qual */, const char ** /* name */); - -/* - * Construct a text-format ACL. The flags argument is a bitmask that - * can include any of the following: - * - * Flags only for archive entries with POSIX.1e ACL: - * ARCHIVE_ENTRY_ACL_TYPE_ACCESS - Include POSIX.1e "access" entries. - * ARCHIVE_ENTRY_ACL_TYPE_DEFAULT - Include POSIX.1e "default" entries. - * ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT - Include "default:" before each - * default ACL entry. - * ARCHIVE_ENTRY_ACL_STYLE_SOLARIS - Output only one colon after "other" and - * "mask" entries. - * - * Flags only for archive entries with NFSv4 ACL: - * ARCHIVE_ENTRY_ACL_STYLE_COMPACT - Do not output the minus character for - * unset permissions and flags in NFSv4 ACL permission and flag fields - * - * Flags for for archive entries with POSIX.1e ACL or NFSv4 ACL: - * ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID - Include extra numeric ID field in - * each ACL entry. - * ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA - Separate entries with comma - * instead of newline. - */ -#define ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID 0x00000001 -#define ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT 0x00000002 -#define ARCHIVE_ENTRY_ACL_STYLE_SOLARIS 0x00000004 -#define ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA 0x00000008 -#define ARCHIVE_ENTRY_ACL_STYLE_COMPACT 0x00000010 - -__LA_DECL wchar_t *archive_entry_acl_to_text_w(struct archive_entry *, - la_ssize_t * /* len */, int /* flags */); -__LA_DECL char *archive_entry_acl_to_text(struct archive_entry *, - la_ssize_t * /* len */, int /* flags */); -__LA_DECL int archive_entry_acl_from_text_w(struct archive_entry *, - const wchar_t * /* wtext */, int /* type */); -__LA_DECL int archive_entry_acl_from_text(struct archive_entry *, - const char * /* text */, int /* type */); - -/* Deprecated constants */ -#define OLD_ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID 1024 -#define OLD_ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT 2048 - -/* Deprecated functions */ -__LA_DECL const wchar_t *archive_entry_acl_text_w(struct archive_entry *, - int /* flags */) __LA_DEPRECATED; -__LA_DECL const char *archive_entry_acl_text(struct archive_entry *, - int /* flags */) __LA_DEPRECATED; - -/* Return bitmask of ACL types in an archive entry */ -__LA_DECL int archive_entry_acl_types(struct archive_entry *); - -/* Return a count of entries matching 'want_type' */ -__LA_DECL int archive_entry_acl_count(struct archive_entry *, int /* want_type */); - -/* Return an opaque ACL object. */ -/* There's not yet anything clients can actually do with this... */ -struct archive_acl; -__LA_DECL struct archive_acl *archive_entry_acl(struct archive_entry *); - -/* - * extended attributes - */ - -__LA_DECL void archive_entry_xattr_clear(struct archive_entry *); -__LA_DECL void archive_entry_xattr_add_entry(struct archive_entry *, - const char * /* name */, const void * /* value */, - size_t /* size */); - -/* - * To retrieve the xattr list, first "reset", then repeatedly ask for the - * "next" entry. - */ - -__LA_DECL int archive_entry_xattr_count(struct archive_entry *); -__LA_DECL int archive_entry_xattr_reset(struct archive_entry *); -__LA_DECL int archive_entry_xattr_next(struct archive_entry *, - const char ** /* name */, const void ** /* value */, size_t *); - -/* - * sparse - */ - -__LA_DECL void archive_entry_sparse_clear(struct archive_entry *); -__LA_DECL void archive_entry_sparse_add_entry(struct archive_entry *, - la_int64_t /* offset */, la_int64_t /* length */); - -/* - * To retrieve the xattr list, first "reset", then repeatedly ask for the - * "next" entry. - */ - -__LA_DECL int archive_entry_sparse_count(struct archive_entry *); -__LA_DECL int archive_entry_sparse_reset(struct archive_entry *); -__LA_DECL int archive_entry_sparse_next(struct archive_entry *, - la_int64_t * /* offset */, la_int64_t * /* length */); - -/* - * Utility to match up hardlinks. - * - * The 'struct archive_entry_linkresolver' is a cache of archive entries - * for files with multiple links. Here's how to use it: - * 1. Create a lookup object with archive_entry_linkresolver_new() - * 2. Tell it the archive format you're using. - * 3. Hand each archive_entry to archive_entry_linkify(). - * That function will return 0, 1, or 2 entries that should - * be written. - * 4. Call archive_entry_linkify(resolver, NULL) until - * no more entries are returned. - * 5. Call archive_entry_linkresolver_free(resolver) to free resources. - * - * The entries returned have their hardlink and size fields updated - * appropriately. If an entry is passed in that does not refer to - * a file with multiple links, it is returned unchanged. The intention - * is that you should be able to simply filter all entries through - * this machine. - * - * To make things more efficient, be sure that each entry has a valid - * nlinks value. The hardlink cache uses this to track when all links - * have been found. If the nlinks value is zero, it will keep every - * name in the cache indefinitely, which can use a lot of memory. - * - * Note that archive_entry_size() is reset to zero if the file - * body should not be written to the archive. Pay attention! - */ -struct archive_entry_linkresolver; - -/* - * There are three different strategies for marking hardlinks. - * The descriptions below name them after the best-known - * formats that rely on each strategy: - * - * "Old cpio" is the simplest, it always returns any entry unmodified. - * As far as I know, only cpio formats use this. Old cpio archives - * store every link with the full body; the onus is on the dearchiver - * to detect and properly link the files as they are restored. - * "tar" is also pretty simple; it caches a copy the first time it sees - * any link. Subsequent appearances are modified to be hardlink - * references to the first one without any body. Used by all tar - * formats, although the newest tar formats permit the "old cpio" strategy - * as well. This strategy is very simple for the dearchiver, - * and reasonably straightforward for the archiver. - * "new cpio" is trickier. It stores the body only with the last - * occurrence. The complication is that we might not - * see every link to a particular file in a single session, so - * there's no easy way to know when we've seen the last occurrence. - * The solution here is to queue one link until we see the next. - * At the end of the session, you can enumerate any remaining - * entries by calling archive_entry_linkify(NULL) and store those - * bodies. If you have a file with three links l1, l2, and l3, - * you'll get the following behavior if you see all three links: - * linkify(l1) => NULL (the resolver stores l1 internally) - * linkify(l2) => l1 (resolver stores l2, you write l1) - * linkify(l3) => l2, l3 (all links seen, you can write both). - * If you only see l1 and l2, you'll get this behavior: - * linkify(l1) => NULL - * linkify(l2) => l1 - * linkify(NULL) => l2 (at end, you retrieve remaining links) - * As the name suggests, this strategy is used by newer cpio variants. - * It's noticeably more complex for the archiver, slightly more complex - * for the dearchiver than the tar strategy, but makes it straightforward - * to restore a file using any link by simply continuing to scan until - * you see a link that is stored with a body. In contrast, the tar - * strategy requires you to rescan the archive from the beginning to - * correctly extract an arbitrary link. - */ - -__LA_DECL struct archive_entry_linkresolver *archive_entry_linkresolver_new(void); -__LA_DECL void archive_entry_linkresolver_set_strategy( - struct archive_entry_linkresolver *, int /* format_code */); -__LA_DECL void archive_entry_linkresolver_free(struct archive_entry_linkresolver *); -__LA_DECL void archive_entry_linkify(struct archive_entry_linkresolver *, - struct archive_entry **, struct archive_entry **); -__LA_DECL struct archive_entry *archive_entry_partial_links( - struct archive_entry_linkresolver *res, unsigned int *links); -#ifdef __cplusplus -} -#endif - -/* This is meaningless outside of this header. */ -#undef __LA_DECL - -#endif /* !ARCHIVE_ENTRY_H_INCLUDED */ diff --git a/thirdparty/libarchive/libarchive/archive_entry_acl.3 b/thirdparty/libarchive/libarchive/archive_entry_acl.3 deleted file mode 100644 index 50dd642c2..000000000 --- a/thirdparty/libarchive/libarchive/archive_entry_acl.3 +++ /dev/null @@ -1,458 +0,0 @@ -.\" Copyright (c) 2010 Joerg Sonnenberger -.\" Copyright (c) 2016 Martin Matuska -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. -.\" -.Dd February 15, 2017 -.Dt ARCHIVE_ENTRY_ACL 3 -.Os -.Sh NAME -.Nm archive_entry_acl_add_entry , -.Nm archive_entry_acl_add_entry_w , -.Nm archive_entry_acl_clear , -.Nm archive_entry_acl_count , -.Nm archive_entry_acl_from_text , -.Nm archive_entry_acl_from_text_w , -.Nm archive_entry_acl_next , -.Nm archive_entry_acl_reset , -.Nm archive_entry_acl_to_text , -.Nm archive_entry_acl_to_text_w , -.Nm archive_entry_acl_types -.Nd functions for manipulating Access Control Lists in archive entry descriptions -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive_entry.h -.Ft void -.Fo archive_entry_acl_add_entry -.Fa "struct archive_entry *a" -.Fa "int type" -.Fa "int permset" -.Fa "int tag" -.Fa "int qualifier" -.Fa "const char *name" -.Fc -.Ft void -.Fo archive_entry_acl_add_entry_w -.Fa "struct archive_entry *a" -.Fa "int type" -.Fa "int permset" -.Fa "int tag" -.Fa "int qualifier" -.Fa "const wchar_t *name" -.Fc -.Ft void -.Fn archive_entry_acl_clear "struct archive_entry *a" -.Ft int -.Fn archive_entry_acl_count "struct archive_entry *a" "int type" -.Ft int -.Fo archive_entry_acl_from_text -.Fa "struct archive_entry *a" -.Fa "const char *text" -.Fa "int type" -.Fc -.Ft int -.Fo archive_entry_acl_from_text_w -.Fa "struct archive_entry *a" -.Fa "const wchar_t *text" -.Fa "int type" -.Fc -.Ft int -.Fo archive_entry_acl_next -.Fa "struct archive_entry *a" -.Fa "int type" -.Fa "int *ret_type" -.Fa "int *ret_permset" -.Fa "int *ret_tag" -.Fa "int *ret_qual" -.Fa "const char **ret_name" -.Fc -.Ft int -.Fn archive_entry_acl_reset "struct archive_entry *a" "int type" -.Ft char * -.Fo archive_entry_acl_to_text -.Fa "struct archive_entry *a" -.Fa "ssize_t *len_p" -.Fa "int flags" -.Fc -.Ft wchar_t * -.Fo archive_entry_acl_to_text_w -.Fa "struct archive_entry *a" -.Fa "ssize_t *len_p" -.Fa "int flags" -.Fc -.Ft int -.Fn archive_entry_acl_types "struct archive_entry *a" -.\" enum? -.Sh DESCRIPTION -The -.Dq Access Control Lists (ACLs) -extend the standard Unix permission model. -The ACL interface of -.Nm libarchive -supports both POSIX.1e and NFSv4 style ACLs. -Use of ACLs is restricted by -various levels of ACL support in operating systems, file systems and archive -formats. -.Ss POSIX.1e Access Control Lists -A POSIX.1e ACL consists of a number of independent entries. -Each entry specifies the permission set as a bitmask of basic permissions. -Valid permissions in the -.Fa permset -are: -.Bl -tag -offset indent -compact -width "ARCHIVE_ENTRY_ACL_EXECUTE" -.It Dv ARCHIVE_ENTRY_ACL_READ ( Sy r ) -.It Dv ARCHIVE_ENTRY_ACL_WRITE ( Sy w ) -.It Dv ARCHIVE_ENTRY_ACL_EXECUTE ( Sy x ) -.El -The permissions correspond to the normal Unix permissions. -.Pp -The -.Fa tag -specifies the principal to which the permission applies. -Valid values are: -.Bl -hang -offset indent -compact -width "ARCHIVE_ENTRY_ACL_GROUP_OBJ" -.It Dv ARCHIVE_ENTRY_ACL_USER -The user specified by the name field. -.It Dv ARCHIVE_ENTRY_ACL_USER_OBJ -The owner of the file. -.It Dv ARCHIVE_ENTRY_ACL_GROUP -The group specified by the name field. -.It Dv ARCHIVE_ENTRY_ACL_GROUP_OBJ -The group which owns the file. -.It Dv ARCHIVE_ENTRY_ACL_MASK -The maximum permissions to be obtained via group permissions. -.It Dv ARCHIVE_ENTRY_ACL_OTHER -Any principal who is not the file owner or a member of the owning group. -.El -.Pp -The principals -.Dv ARCHIVE_ENTRY_ACL_USER_OBJ , -.Dv ARCHIVE_ENTRY_ACL_GROUP_OBJ -and -.Dv ARCHIVE_ENTRY_ACL_OTHER -are equivalent to user, group and other in the classic Unix permission -model and specify non-extended ACL entries. -.Pp -All files have an access ACL -.Pq Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS . -This specifies the permissions required for access to the file itself. -Directories have an additional ACL -.Pq Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT , -which controls the initial access ACL for newly-created directory entries. -.Ss NFSv4 Access Control Lists -A NFSv4 ACL consists of multiple individual entries called Access Control -Entries (ACEs). -.Pp -There are four possible types of a NFSv4 ACE: -.Bl -hang -offset indent -compact -width "ARCHIVE_ENTRY_ACL_TYE_ALLOW" -.It Dv ARCHIVE_ENTRY_ACL_TYPE_ALLOW -Allow principal to perform actions requiring given permissions. -.It Dv ARCHIVE_ENTRY_ACL_TYPE_DENY -Prevent principal from performing actions requiring given permissions. -.It Dv ARCHIVE_ENTRY_ACL_TYPE_AUDIT -Log access attempts by principal which require given permissions. -.It Dv ARCHIVE_ENTRY_ACL_TYPE_ALARM -Trigger a system alarm on access attempts by principal which require given -permissions. -.El -.Pp -The -.Fa tag -specifies the principal to which the permission applies. -Valid values are: -.Bl -hang -offset indent -compact -width "ARCHIVE_ENTRY_ACL_GROUP_OBJ" -.It Dv ARCHIVE_ENTRY_ACL_USER -The user specified by the name field. -.It Dv ARCHIVE_ENTRY_ACL_USER_OBJ -The owner of the file. -.It Dv ARCHIVE_ENTRY_ACL_GROUP -The group specified by the name field. -.It Dv ARCHIVE_ENTRY_ACL_GROUP_OBJ -The group which owns the file. -.It Dv ARCHIVE_ENTRY_ACL_EVERYONE -Any principal who is not the file owner or a member of the owning group. -.El -.Pp -Entries with the -.Dv ARCHIVE_ENTRY_ACL_USER -or -.Dv ARCHIVE_ENTRY_ACL_GROUP -tag store the user and group name in the -.Fa name -string and optionally the user or group ID in the -.Fa qualifier -integer. -.Pp -NFSv4 ACE permissions and flags are stored in the same -.Fa permset -bitfield. -Some permissions share the same constant and permission character -but have different effect on directories than on files. -The following ACE permissions are supported: -.Bl -tag -offset indent -compact -width ARCHIV -.It Dv ARCHIVE_ENTRY_ACL_READ_DATA ( Sy r ) -Read data (file). -.It Dv ARCHIVE_ENTRY_ACL_LIST_DIRECTORY ( Sy r ) -List entries (directory). -.It ARCHIVE_ENTRY_ACL_WRITE_DATA ( Sy w ) -Write data (file). -.It ARCHIVE_ENTRY_ACL_ADD_FILE ( Sy w ) -Create files (directory). -.It Dv ARCHIVE_ENTRY_ACL_EXECUTE ( Sy x ) -Execute file or change into a directory. -.It Dv ARCHIVE_ENTRY_ACL_APPEND_DATA ( Sy p ) -Append data (file). -.It Dv ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY ( Sy p ) -Create subdirectories (directory). -.It Dv ARCHIVE_ENTRY_ACL_DELETE_CHILD ( Sy D ) -Remove files and subdirectories inside a directory. -.It Dv ARCHIVE_ENTRY_ACL_DELETE ( Sy d ) -Remove file or directory. -.It Dv ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES ( Sy a ) -Read file or directory attributes. -.It Dv ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES ( Sy A ) -Write file or directory attributes. -.It Dv ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS ( Sy R ) -Read named file or directory attributes. -.It Dv ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS ( Sy W ) -Write named file or directory attributes. -.It Dv ARCHIVE_ENTRY_ACL_READ_ACL ( Sy c ) -Read file or directory ACL. -.It Dv ARCHIVE_ENTRY_ACL_WRITE_ACL ( Sy C ) -Write file or directory ACL. -.It Dv ARCHIVE_ENTRY_ACL_WRITE_OWNER ( Sy o ) -Change owner of a file or directory. -.It Dv ARCHIVE_ENTRY_ACL_SYNCHRONIZE ( Sy s ) -Use synchronous I/O. -.El -.Pp -The following NFSv4 ACL inheritance flags are supported: -.Bl -tag -offset indent -compact -width ARCHIV -.It Dv ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT ( Sy f ) -Inherit parent directory ACE to files. -.It Dv ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT ( Sy d ) -Inherit parent directory ACE to subdirectories. -.It Dv ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY ( Sy i ) -Only inherit, do not apply the permission on the directory itself. -.It Dv ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT ( Sy n ) -Do not propagate inherit flags. -Only first-level entries inherit ACLs. -.It Dv ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS ( Sy S ) -Trigger alarm or audit on successful access. -.It Dv ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS ( Sy F ) -Trigger alarm or audit on failed access. -.It Dv ARCHIVE_ENTRY_ACL_ENTRY_INHERITED ( Sy I ) -Mark that ACE was inherited. -.El -.Ss Functions -.Fn archive_entry_acl_add_entry -and -.Fn archive_entry_acl_add_entry_w -add a single ACL entry. -For the access ACL and non-extended principals, the classic Unix permissions -are updated. -An archive entry cannot contain both POSIX.1e and NFSv4 ACL entries. -.Pp -.Fn archive_entry_acl_clear -removes all ACL entries and resets the enumeration pointer. -.Pp -.Fn archive_entry_acl_count -counts the ACL entries that have the given type mask. -.Fa type -can be the bitwise-or of -.Bl -tag -offset indent -compact -width "ARCHIVE_ENTRY_ACL_TYPE_DEFAULT" -.It Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS -.It Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT -.El -for POSIX.1e ACLs and -.Bl -tag -offset indent -compact -width "ARCHIVE_ENTRY_ACL_TYPE_ALLOW" -.It Dv ARCHIVE_ENTRY_ACL_TYPE_ALLOW -.It Dv ARCHIVE_ENTRY_ACL_TYPE_DENY -.It Dv ARCHIVE_ENTRY_ACL_TYPE_AUDIT -.It Dv ARCHIVE_ENTRY_ACL_TYPE_ALARM -.El -for NFSv4 ACLs. -For POSIX.1e ACLs if -.Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS -is included and at least one extended ACL entry is found, -the three non-extended ACLs are added. -.Pp -.Fn archive_entry_acl_from_text -and -.Fn archive_entry_acl_from_text_w -add new -.Pq or merge with existing -ACL entries from -.Pq wide -text. -The argument -.Fa type -may take one of the following values: -.Bl -tag -offset indent -compact -width "ARCHIVE_ENTRY_ACL_TYPE_DEFAULT" -.It Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS -.It Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT -.It Dv ARCHIVE_ENTRY_ACL_TYPE_NFS4 -.El -Supports all formats that can be created with -.Fn archive_entry_acl_to_text -or respectively -.Fn archive_entry_acl_to_text_w . -Existing ACL entries are preserved. -To get a clean new ACL from text -.Fn archive_entry_acl_clear -must be called first. -Entries prefixed with -.Dq default: -are treated as -.Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT -unless -.Fa type -is -.Dv ARCHIVE_ENTRY_ACL_TYPE_NFS4 . -Invalid entries, non-parseable ACL entries and entries beginning with -the -.Sq # -character -.Pq comments -are skipped. -.Pp -.Fn archive_entry_acl_next -return the next entry of the ACL list. -This functions may only be called after -.Fn archive_entry_acl_reset -has indicated the presence of extended ACL entries. -.Pp -.Fn archive_entry_acl_reset -prepare reading the list of ACL entries with -.Fn archive_entry_acl_next . -The function returns 0 if no non-extended ACLs are found. -In this case, the access permissions should be obtained by -.Xr archive_entry_mode 3 -or set using -.Xr chmod 2 . -Otherwise, the function returns the same value as -.Fn archive_entry_acl_count . -.Pp -.Fn archive_entry_acl_to_text -and -.Fn archive_entry_acl_to_text_w -convert the ACL entries for the given type into a -.Pq wide -string of ACL entries separated by newline. -If the pointer -.Fa len_p -is not NULL, then the function shall return the length of the string -.Pq not including the NULL terminator -in the location pointed to by -.Fa len_p . -The -.Fa flag -argument is a bitwise-or. -.Pp -The following flags are effective only on POSIX.1e ACL: -.Bl -tag -offset indent -compact -width ARCHIV -.It Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS -Output access ACLs. -.It Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT -Output POSIX.1e default ACLs. -.It Dv ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT -Prefix each default ACL entry with the word -.Dq default: . -.It Dv ARCHIVE_ENTRY_ACL_STYLE_SOLARIS -The mask and other ACLs don not contain a double colon. -.El -.Pp -The following flags are effecive only on NFSv4 ACL: -.Bl -tag -offset indent -compact -width ARCHIV -.It Dv ARCHIVE_ENTRY_ACL_STYLE_COMPACT -Do not output minus characters for unset permissions and flags in NFSv4 ACL -permission and flag fields. -.El -.Pp -The following flags are effective on both POSIX.1e and NFSv4 ACL: -.Bl -tag -offset indent -compact -width ARCHIV -.It Dv ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID -Add an additional colon-separated field containing the user or group id. -.It Dv ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA -Separate ACL entries with comma instead of newline. -.El -.Pp -If the archive entry contains NFSv4 ACLs, all types of NFSv4 ACLs are returned. -It the entry contains POSIX.1e ACLs and none of the flags -.Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS -or -.Dv ARCHIVE_ENTRY_ACL_TYPE_DEFAULT -are specified, both access and default entries are returned and default entries -are prefixed with -.Dq default: . -.Pp -.Fn archive_entry_acl_types -get ACL entry types contained in an archive entry's ACL. -As POSIX.1e and NFSv4 -ACL entries cannot be mixed, this function is a very efficient way to detect if -an ACL already contains POSIX.1e or NFSv4 ACL entries. -.Sh RETURN VALUES -.Fn archive_entry_acl_count -and -.Fn archive_entry_acl_reset -returns the number of ACL entries that match the given type mask. -For POSIX.1e ACLS if the type mask includes -.Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS -and at least one extended ACL entry exists, the three classic Unix -permissions are counted. -.Pp -.Fn archive_entry_acl_from_text -and -.Fn archive_entry_acl_from_text_w -return -.Dv ARCHIVE_OK -if all entries were successfully parsed and -.Dv ARCHIVE_WARN -if one or more entries were invalid or non-parseable. -.Pp -.Fn archive_entry_acl_next -returns -.Dv ARCHIVE_OK -on success, -.Dv ARCHIVE_EOF -if no more ACL entries exist -and -.Dv ARCHIVE_WARN -if -.Fn archive_entry_acl_reset -has not been called first. -.Pp -.Fn archive_entry_acl_to_text -returns a string representing the ACL entries matching the given type and -flags on success or NULL on error. -.Pp -.Fn archive_entry_acl_to_text_w -returns a wide string representing the ACL entries matching the given type -and flags on success or NULL on error. -.Pp -.Fn archive_entry_acl_types -returns a bitmask of ACL entry types or 0 if archive entry has no ACL entries. -.Sh SEE ALSO -.Xr archive_entry 3 , -.Xr libarchive 3 diff --git a/thirdparty/libarchive/libarchive/archive_entry_copy_bhfi.c b/thirdparty/libarchive/libarchive/archive_entry_copy_bhfi.c deleted file mode 100644 index 77bf38e45..000000000 --- a/thirdparty/libarchive/libarchive/archive_entry_copy_bhfi.c +++ /dev/null @@ -1,75 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#include "archive_private.h" -#include "archive_entry.h" - -#if defined(_WIN32) && !defined(__CYGWIN__) - -#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000) - -__inline static void -fileTimeToUtc(const FILETIME *filetime, time_t *t, long *ns) -{ - ULARGE_INTEGER utc; - - utc.HighPart = filetime->dwHighDateTime; - utc.LowPart = filetime->dwLowDateTime; - if (utc.QuadPart >= EPOC_TIME) { - utc.QuadPart -= EPOC_TIME; - *t = (time_t)(utc.QuadPart / 10000000); /* milli seconds base */ - *ns = (long)(utc.QuadPart % 10000000) * 100;/* nano seconds base */ - } else { - *t = 0; - *ns = 0; - } -} - -void -archive_entry_copy_bhfi(struct archive_entry *entry, - BY_HANDLE_FILE_INFORMATION *bhfi) -{ - time_t secs; - long nsecs; - - fileTimeToUtc(&bhfi->ftLastAccessTime, &secs, &nsecs); - archive_entry_set_atime(entry, secs, nsecs); - fileTimeToUtc(&bhfi->ftLastWriteTime, &secs, &nsecs); - archive_entry_set_mtime(entry, secs, nsecs); - fileTimeToUtc(&bhfi->ftCreationTime, &secs, &nsecs); - archive_entry_set_birthtime(entry, secs, nsecs); - archive_entry_set_ctime(entry, secs, nsecs); - archive_entry_set_dev(entry, bhfi->dwVolumeSerialNumber); - archive_entry_set_ino64(entry, (((int64_t)bhfi->nFileIndexHigh) << 32) - + bhfi->nFileIndexLow); - archive_entry_set_nlink(entry, bhfi->nNumberOfLinks); - archive_entry_set_size(entry, (((int64_t)bhfi->nFileSizeHigh) << 32) - + bhfi->nFileSizeLow); - /* archive_entry_set_mode(entry, st->st_mode); */ -} -#endif diff --git a/thirdparty/libarchive/libarchive/archive_entry_copy_stat.c b/thirdparty/libarchive/libarchive/archive_entry_copy_stat.c deleted file mode 100644 index ac83868e8..000000000 --- a/thirdparty/libarchive/libarchive/archive_entry_copy_stat.c +++ /dev/null @@ -1,83 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_copy_stat.c 189466 2009-03-07 00:52:02Z kientzle $"); - -#ifdef HAVE_SYS_STAT_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" - -void -archive_entry_copy_stat(struct archive_entry *entry, const struct stat *st) -{ -#if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC - archive_entry_set_atime(entry, st->st_atime, st->st_atimespec.tv_nsec); - archive_entry_set_ctime(entry, st->st_ctime, st->st_ctimespec.tv_nsec); - archive_entry_set_mtime(entry, st->st_mtime, st->st_mtimespec.tv_nsec); -#elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC - archive_entry_set_atime(entry, st->st_atime, st->st_atim.tv_nsec); - archive_entry_set_ctime(entry, st->st_ctime, st->st_ctim.tv_nsec); - archive_entry_set_mtime(entry, st->st_mtime, st->st_mtim.tv_nsec); -#elif HAVE_STRUCT_STAT_ST_MTIME_NSEC - archive_entry_set_atime(entry, st->st_atime, st->st_atime_nsec); - archive_entry_set_ctime(entry, st->st_ctime, st->st_ctime_nsec); - archive_entry_set_mtime(entry, st->st_mtime, st->st_mtime_nsec); -#elif HAVE_STRUCT_STAT_ST_MTIME_N - archive_entry_set_atime(entry, st->st_atime, st->st_atime_n); - archive_entry_set_ctime(entry, st->st_ctime, st->st_ctime_n); - archive_entry_set_mtime(entry, st->st_mtime, st->st_mtime_n); -#elif HAVE_STRUCT_STAT_ST_UMTIME - archive_entry_set_atime(entry, st->st_atime, st->st_uatime * 1000); - archive_entry_set_ctime(entry, st->st_ctime, st->st_uctime * 1000); - archive_entry_set_mtime(entry, st->st_mtime, st->st_umtime * 1000); -#elif HAVE_STRUCT_STAT_ST_MTIME_USEC - archive_entry_set_atime(entry, st->st_atime, st->st_atime_usec * 1000); - archive_entry_set_ctime(entry, st->st_ctime, st->st_ctime_usec * 1000); - archive_entry_set_mtime(entry, st->st_mtime, st->st_mtime_usec * 1000); -#else - archive_entry_set_atime(entry, st->st_atime, 0); - archive_entry_set_ctime(entry, st->st_ctime, 0); - archive_entry_set_mtime(entry, st->st_mtime, 0); -#endif -#if HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC - archive_entry_set_birthtime(entry, st->st_birthtime, st->st_birthtimespec.tv_nsec); -#elif HAVE_STRUCT_STAT_ST_BIRTHTIME - archive_entry_set_birthtime(entry, st->st_birthtime, 0); -#else - archive_entry_unset_birthtime(entry); -#endif - archive_entry_set_dev(entry, st->st_dev); - archive_entry_set_gid(entry, st->st_gid); - archive_entry_set_uid(entry, st->st_uid); - archive_entry_set_ino(entry, st->st_ino); - archive_entry_set_nlink(entry, st->st_nlink); - archive_entry_set_rdev(entry, st->st_rdev); - archive_entry_set_size(entry, st->st_size); - archive_entry_set_mode(entry, st->st_mode); -} diff --git a/thirdparty/libarchive/libarchive/archive_entry_link_resolver.c b/thirdparty/libarchive/libarchive/archive_entry_link_resolver.c deleted file mode 100644 index c7d59497a..000000000 --- a/thirdparty/libarchive/libarchive/archive_entry_link_resolver.c +++ /dev/null @@ -1,447 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_link_resolver.c 201100 2009-12-28 03:05:31Z kientzle $"); - -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" - -/* - * This is mostly a pretty straightforward hash table implementation. - * The only interesting bit is the different strategies used to - * match up links. These strategies match those used by various - * archiving formats: - * tar - content stored with first link, remainder refer back to it. - * This requires us to match each subsequent link up with the - * first appearance. - * cpio - Old cpio just stored body with each link, match-ups were - * implicit. This is trivial. - * new cpio - New cpio only stores body with last link, match-ups - * are implicit. This is actually quite tricky; see the notes - * below. - */ - -/* Users pass us a format code, we translate that into a strategy here. */ -#define ARCHIVE_ENTRY_LINKIFY_LIKE_TAR 0 -#define ARCHIVE_ENTRY_LINKIFY_LIKE_MTREE 1 -#define ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO 2 -#define ARCHIVE_ENTRY_LINKIFY_LIKE_NEW_CPIO 3 - -/* Initial size of link cache. */ -#define links_cache_initial_size 1024 - -struct links_entry { - struct links_entry *next; - struct links_entry *previous; - struct archive_entry *canonical; - struct archive_entry *entry; - size_t hash; - unsigned int links; /* # links not yet seen */ -}; - -struct archive_entry_linkresolver { - struct links_entry **buckets; - struct links_entry *spare; - unsigned long number_entries; - size_t number_buckets; - int strategy; -}; - -#define NEXT_ENTRY_DEFERRED 1 -#define NEXT_ENTRY_PARTIAL 2 -#define NEXT_ENTRY_ALL (NEXT_ENTRY_DEFERRED | NEXT_ENTRY_PARTIAL) - -static struct links_entry *find_entry(struct archive_entry_linkresolver *, - struct archive_entry *); -static void grow_hash(struct archive_entry_linkresolver *); -static struct links_entry *insert_entry(struct archive_entry_linkresolver *, - struct archive_entry *); -static struct links_entry *next_entry(struct archive_entry_linkresolver *, - int); - -struct archive_entry_linkresolver * -archive_entry_linkresolver_new(void) -{ - struct archive_entry_linkresolver *res; - - /* Check for positive power-of-two */ - if (links_cache_initial_size == 0 || - (links_cache_initial_size & (links_cache_initial_size - 1)) != 0) - return (NULL); - - res = calloc(1, sizeof(struct archive_entry_linkresolver)); - if (res == NULL) - return (NULL); - res->number_buckets = links_cache_initial_size; - res->buckets = calloc(res->number_buckets, sizeof(res->buckets[0])); - if (res->buckets == NULL) { - free(res); - return (NULL); - } - return (res); -} - -void -archive_entry_linkresolver_set_strategy(struct archive_entry_linkresolver *res, - int fmt) -{ - int fmtbase = fmt & ARCHIVE_FORMAT_BASE_MASK; - - switch (fmtbase) { - case ARCHIVE_FORMAT_7ZIP: - case ARCHIVE_FORMAT_AR: - case ARCHIVE_FORMAT_ZIP: - res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO; - break; - case ARCHIVE_FORMAT_CPIO: - switch (fmt) { - case ARCHIVE_FORMAT_CPIO_SVR4_NOCRC: - case ARCHIVE_FORMAT_CPIO_SVR4_CRC: - res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_NEW_CPIO; - break; - default: - res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO; - break; - } - break; - case ARCHIVE_FORMAT_MTREE: - res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_MTREE; - break; - case ARCHIVE_FORMAT_ISO9660: - case ARCHIVE_FORMAT_SHAR: - case ARCHIVE_FORMAT_TAR: - case ARCHIVE_FORMAT_XAR: - res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_TAR; - break; - default: - res->strategy = ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO; - break; - } -} - -void -archive_entry_linkresolver_free(struct archive_entry_linkresolver *res) -{ - struct links_entry *le; - - if (res == NULL) - return; - - while ((le = next_entry(res, NEXT_ENTRY_ALL)) != NULL) - archive_entry_free(le->entry); - free(res->buckets); - free(res); -} - -void -archive_entry_linkify(struct archive_entry_linkresolver *res, - struct archive_entry **e, struct archive_entry **f) -{ - struct links_entry *le; - struct archive_entry *t; - - *f = NULL; /* Default: Don't return a second entry. */ - - if (*e == NULL) { - le = next_entry(res, NEXT_ENTRY_DEFERRED); - if (le != NULL) { - *e = le->entry; - le->entry = NULL; - } - return; - } - - /* If it has only one link, then we're done. */ - if (archive_entry_nlink(*e) == 1) - return; - /* Directories, devices never have hardlinks. */ - if (archive_entry_filetype(*e) == AE_IFDIR - || archive_entry_filetype(*e) == AE_IFBLK - || archive_entry_filetype(*e) == AE_IFCHR) - return; - - switch (res->strategy) { - case ARCHIVE_ENTRY_LINKIFY_LIKE_TAR: - le = find_entry(res, *e); - if (le != NULL) { - archive_entry_unset_size(*e); - archive_entry_copy_hardlink(*e, - archive_entry_pathname(le->canonical)); - } else - insert_entry(res, *e); - return; - case ARCHIVE_ENTRY_LINKIFY_LIKE_MTREE: - le = find_entry(res, *e); - if (le != NULL) { - archive_entry_copy_hardlink(*e, - archive_entry_pathname(le->canonical)); - } else - insert_entry(res, *e); - return; - case ARCHIVE_ENTRY_LINKIFY_LIKE_OLD_CPIO: - /* This one is trivial. */ - return; - case ARCHIVE_ENTRY_LINKIFY_LIKE_NEW_CPIO: - le = find_entry(res, *e); - if (le != NULL) { - /* - * Put the new entry in le, return the - * old entry from le. - */ - t = *e; - *e = le->entry; - le->entry = t; - /* Make the old entry into a hardlink. */ - archive_entry_unset_size(*e); - archive_entry_copy_hardlink(*e, - archive_entry_pathname(le->canonical)); - /* If we ran out of links, return the - * final entry as well. */ - if (le->links == 0) { - *f = le->entry; - le->entry = NULL; - } - } else { - /* - * If we haven't seen it, tuck it away - * for future use. - */ - le = insert_entry(res, *e); - if (le == NULL) - /* XXX We should return an error code XXX */ - return; - le->entry = *e; - *e = NULL; - } - return; - default: - break; - } - return; -} - -static struct links_entry * -find_entry(struct archive_entry_linkresolver *res, - struct archive_entry *entry) -{ - struct links_entry *le; - size_t hash, bucket; - dev_t dev; - int64_t ino; - - /* Free a held entry. */ - if (res->spare != NULL) { - archive_entry_free(res->spare->canonical); - archive_entry_free(res->spare->entry); - free(res->spare); - res->spare = NULL; - } - - dev = archive_entry_dev(entry); - ino = archive_entry_ino64(entry); - hash = (size_t)(dev ^ ino); - - /* Try to locate this entry in the links cache. */ - bucket = hash & (res->number_buckets - 1); - for (le = res->buckets[bucket]; le != NULL; le = le->next) { - if (le->hash == hash - && dev == archive_entry_dev(le->canonical) - && ino == archive_entry_ino64(le->canonical)) { - /* - * Decrement link count each time and release - * the entry if it hits zero. This saves - * memory and is necessary for detecting - * missed links. - */ - --le->links; - if (le->links > 0) - return (le); - /* Remove it from this hash bucket. */ - if (le->previous != NULL) - le->previous->next = le->next; - if (le->next != NULL) - le->next->previous = le->previous; - if (res->buckets[bucket] == le) - res->buckets[bucket] = le->next; - res->number_entries--; - /* Defer freeing this entry. */ - res->spare = le; - return (le); - } - } - return (NULL); -} - -static struct links_entry * -next_entry(struct archive_entry_linkresolver *res, int mode) -{ - struct links_entry *le; - size_t bucket; - - /* Free a held entry. */ - if (res->spare != NULL) { - archive_entry_free(res->spare->canonical); - archive_entry_free(res->spare->entry); - free(res->spare); - res->spare = NULL; - } - - /* Look for next non-empty bucket in the links cache. */ - for (bucket = 0; bucket < res->number_buckets; bucket++) { - for (le = res->buckets[bucket]; le != NULL; le = le->next) { - if (le->entry != NULL && - (mode & NEXT_ENTRY_DEFERRED) == 0) - continue; - if (le->entry == NULL && - (mode & NEXT_ENTRY_PARTIAL) == 0) - continue; - /* Remove it from this hash bucket. */ - if (le->next != NULL) - le->next->previous = le->previous; - if (le->previous != NULL) - le->previous->next = le->next; - else - res->buckets[bucket] = le->next; - res->number_entries--; - /* Defer freeing this entry. */ - res->spare = le; - return (le); - } - } - return (NULL); -} - -static struct links_entry * -insert_entry(struct archive_entry_linkresolver *res, - struct archive_entry *entry) -{ - struct links_entry *le; - size_t hash, bucket; - - /* Add this entry to the links cache. */ - le = calloc(1, sizeof(struct links_entry)); - if (le == NULL) - return (NULL); - le->canonical = archive_entry_clone(entry); - - /* If the links cache is getting too full, enlarge the hash table. */ - if (res->number_entries > res->number_buckets * 2) - grow_hash(res); - - hash = (size_t)(archive_entry_dev(entry) ^ archive_entry_ino64(entry)); - bucket = hash & (res->number_buckets - 1); - - /* If we could allocate the entry, record it. */ - if (res->buckets[bucket] != NULL) - res->buckets[bucket]->previous = le; - res->number_entries++; - le->next = res->buckets[bucket]; - le->previous = NULL; - res->buckets[bucket] = le; - le->hash = hash; - le->links = archive_entry_nlink(entry) - 1; - return (le); -} - -static void -grow_hash(struct archive_entry_linkresolver *res) -{ - struct links_entry *le, **new_buckets; - size_t new_size; - size_t i, bucket; - - /* Try to enlarge the bucket list. */ - new_size = res->number_buckets * 2; - if (new_size < res->number_buckets) - return; - new_buckets = calloc(new_size, sizeof(struct links_entry *)); - - if (new_buckets == NULL) - return; - - for (i = 0; i < res->number_buckets; i++) { - while (res->buckets[i] != NULL) { - /* Remove entry from old bucket. */ - le = res->buckets[i]; - res->buckets[i] = le->next; - - /* Add entry to new bucket. */ - bucket = le->hash & (new_size - 1); - - if (new_buckets[bucket] != NULL) - new_buckets[bucket]->previous = le; - le->next = new_buckets[bucket]; - le->previous = NULL; - new_buckets[bucket] = le; - } - } - free(res->buckets); - res->buckets = new_buckets; - res->number_buckets = new_size; -} - -struct archive_entry * -archive_entry_partial_links(struct archive_entry_linkresolver *res, - unsigned int *links) -{ - struct archive_entry *e; - struct links_entry *le; - - /* Free a held entry. */ - if (res->spare != NULL) { - archive_entry_free(res->spare->canonical); - archive_entry_free(res->spare->entry); - free(res->spare); - res->spare = NULL; - } - - le = next_entry(res, NEXT_ENTRY_PARTIAL); - if (le != NULL) { - e = le->canonical; - if (links != NULL) - *links = le->links; - le->canonical = NULL; - } else { - e = NULL; - if (links != NULL) - *links = 0; - } - return (e); -} diff --git a/thirdparty/libarchive/libarchive/archive_entry_linkify.3 b/thirdparty/libarchive/libarchive/archive_entry_linkify.3 deleted file mode 100644 index 8c19fddb6..000000000 --- a/thirdparty/libarchive/libarchive/archive_entry_linkify.3 +++ /dev/null @@ -1,224 +0,0 @@ -.\" Copyright (c) 2010 Joerg Sonnenberger -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. -.\" -.Dd February 2, 2012 -.Dt ARCHIVE_ENTRY_LINKIFY 3 -.Os -.Sh NAME -.Nm archive_entry_linkresolver , -.Nm archive_entry_linkresolver_new , -.Nm archive_entry_linkresolver_set_strategy , -.Nm archive_entry_linkresolver_free , -.Nm archive_entry_linkify -.Nd hardlink resolver functions -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive_entry.h -.Ft struct archive_entry_linkresolver * -.Fn archive_entry_linkresolver_new void -.Ft void -.Fo archive_entry_linkresolver_set_strategy -.Fa "struct archive_entry_linkresolver *resolver" -.Fa "int format" -.Fc -.Ft void -.Fo archive_entry_linkresolver_free -.Fa "struct archive_entry_linkresolver *resolver" -.Fc -.Ft void -.Fo archive_entry_linkify -.Fa "struct archive_entry_linkresolver *resolver" -.Fa "struct archive_entry **entry" -.Fa "struct archive_entry **sparse" -.Fc -.Sh DESCRIPTION -Programs that want to create archives have to deal with hardlinks. -Hardlinks are handled in different ways by the archive formats. -The basic strategies are: -.Bl -enum -.It -Ignore hardlinks and store the body for each reference (old cpio, zip). -.It -Store the body the first time an inode is seen (ustar, pax). -.It -Store the body the last time an inode is seen (new cpio). -.El -.Pp -The -.Nm -functions help by providing a unified interface and handling the complexity -behind the scene. -.Pp -The -.Nm -functions assume that -.Vt archive_entry -instances have valid nlinks, inode and device values. -The inode and device value is used to match entries. -The nlinks value is used to determined if all references have been found and -if the internal references can be recycled. -.Pp -The -.Fn archive_entry_linkresolver_new -function allocates a new link resolver. -The instance can be freed using -.Fn archive_entry_linkresolver_free . -All deferred entries are flushed and the internal storage is freed. -.Pp -The -.Fn archive_entry_linkresolver_set_strategy -function selects the optimal hardlink strategy for the given format. -The format code can be obtained from -.Xr archive_format 3 . -The function can be called more than once, but it is recommended to -flush all deferred entries first. -.Pp -The -.Fn archive_entry_linkify -function is the core of -.Nm . -The -.Fn entry -argument points to the -.Vt archive_entry -that should be written. -Depending on the strategy one of the following actions is taken: -.Bl -enum -.It -For the simple archive formats -.Va *entry -is left unmodified and -.Va *sparse -is set to -.Dv NULL . -.It -For tar like archive formats, -.Va *sparse -is set to -.Dv NULL . -If -.Va *entry -is -.Dv NULL , -no action is taken. -If the hardlink count of -.Va *entry -is larger than 1 and the file type is a regular file or symbolic link, -the internal list is searched for a matching inode. -If such an inode is found, the link count is decremented and the file size -of -.Va *entry -is set to 0 to notify that no body should be written. -If no such inode is found, a copy of the entry is added to the internal cache -with a link count reduced by one. -.It -For new cpio like archive formats a value for -.Va *entry -of -.Dv NULL -is used to flush deferred entries. -In that case -.Va *entry -is set to an arbitrary deferred entry and the entry itself is removed from the -internal list. -If the internal list is empty, -.Va *entry -is set to -.Dv NULL . -In either case, -.Va *sparse -is set to -.Dv NULL -and the function returns. -If the hardlink count of -.Va *entry -is one or the file type is a directory or device, -.Va *sparse -is set to -.Dv NULL -and no further action is taken. -Otherwise, the internal list is searched for a matching inode. -If such an inode is not found, the entry is added to the internal list, -both -.Va *entry -and -.Va *sparse -are set to -.Dv NULL -and the function returns. -If such an inode is found, the link count is decremented. -If it remains larger than one, the existing entry on the internal list -is swapped with -.Va *entry -after retaining the link count. -The existing entry is returned in -.Va *entry . -If the link count reached one, the new entry is also removed from the -internal list and returned in -.Va *sparse . -Otherwise -.Va *sparse -is set to -.Dv NULL . -.El -.Pp -The general usage is therefore: -.Bl -enum -.It -For each new archive entry, call -.Fn archive_entry_linkify . -.It -Keep in mind that the entries returned may have a size of 0 now. -.It -If -.Va *entry -is not -.Dv NULL , -archive it. -.It -If -.Va *sparse -is not -.Dv NULL , -archive it. -.It -After all entries have been written to disk, call -.Fn archive_entry_linkify -with -.Va *entry -set to -.Dv NULL -and archive the returned entry as long as it is not -.Dv NULL . -.El -.Sh RETURN VALUES -.Fn archive_entry_linkresolver_new -returns -.Dv NULL -on -.Xr malloc 3 -failures. -.Sh SEE ALSO -.Xr archive_entry 3 diff --git a/thirdparty/libarchive/libarchive/archive_entry_locale.h b/thirdparty/libarchive/libarchive/archive_entry_locale.h deleted file mode 100644 index 803c0368b..000000000 --- a/thirdparty/libarchive/libarchive/archive_entry_locale.h +++ /dev/null @@ -1,92 +0,0 @@ -/*- - * Copyright (c) 2011 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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$ - */ - -#ifndef ARCHIVE_ENTRY_LOCALE_H_INCLUDED -#define ARCHIVE_ENTRY_LOCALE_H_INCLUDED - -#ifndef __LIBARCHIVE_BUILD -#error This header is only to be used internally to libarchive. -#endif - -struct archive_entry; -struct archive_string_conv; - -/* - * Utility functions to set and get entry attributes by translating - * character-set. These are designed for use in format readers and writers. - * - * The return code and interface of these are quite different from other - * functions for archive_entry defined in archive_entry.h. - * Common return code are: - * Return 0 if the string conversion succeeded. - * Return -1 if the string conversion failed. - */ - -#define archive_entry_gname_l _archive_entry_gname_l -int _archive_entry_gname_l(struct archive_entry *, - const char **, size_t *, struct archive_string_conv *); -#define archive_entry_hardlink_l _archive_entry_hardlink_l -int _archive_entry_hardlink_l(struct archive_entry *, - const char **, size_t *, struct archive_string_conv *); -#define archive_entry_pathname_l _archive_entry_pathname_l -int _archive_entry_pathname_l(struct archive_entry *, - const char **, size_t *, struct archive_string_conv *); -#define archive_entry_symlink_l _archive_entry_symlink_l -int _archive_entry_symlink_l(struct archive_entry *, - const char **, size_t *, struct archive_string_conv *); -#define archive_entry_uname_l _archive_entry_uname_l -int _archive_entry_uname_l(struct archive_entry *, - const char **, size_t *, struct archive_string_conv *); -#define archive_entry_acl_text_l _archive_entry_acl_text_l -int _archive_entry_acl_text_l(struct archive_entry *, int, -const char **, size_t *, struct archive_string_conv *) __LA_DEPRECATED; -#define archive_entry_acl_to_text_l _archive_entry_acl_to_text_l -char *_archive_entry_acl_to_text_l(struct archive_entry *, ssize_t *, int, - struct archive_string_conv *); -#define archive_entry_acl_from_text_l _archive_entry_acl_from_text_l -int _archive_entry_acl_from_text_l(struct archive_entry *, const char* text, - int type, struct archive_string_conv *); -#define archive_entry_copy_gname_l _archive_entry_copy_gname_l -int _archive_entry_copy_gname_l(struct archive_entry *, - const char *, size_t, struct archive_string_conv *); -#define archive_entry_copy_hardlink_l _archive_entry_copy_hardlink_l -int _archive_entry_copy_hardlink_l(struct archive_entry *, - const char *, size_t, struct archive_string_conv *); -#define archive_entry_copy_link_l _archive_entry_copy_link_l -int _archive_entry_copy_link_l(struct archive_entry *, - const char *, size_t, struct archive_string_conv *); -#define archive_entry_copy_pathname_l _archive_entry_copy_pathname_l -int _archive_entry_copy_pathname_l(struct archive_entry *, - const char *, size_t, struct archive_string_conv *); -#define archive_entry_copy_symlink_l _archive_entry_copy_symlink_l -int _archive_entry_copy_symlink_l(struct archive_entry *, - const char *, size_t, struct archive_string_conv *); -#define archive_entry_copy_uname_l _archive_entry_copy_uname_l -int _archive_entry_copy_uname_l(struct archive_entry *, - const char *, size_t, struct archive_string_conv *); - -#endif /* ARCHIVE_ENTRY_LOCALE_H_INCLUDED */ diff --git a/thirdparty/libarchive/libarchive/archive_entry_misc.3 b/thirdparty/libarchive/libarchive/archive_entry_misc.3 deleted file mode 100644 index dfab7ddb5..000000000 --- a/thirdparty/libarchive/libarchive/archive_entry_misc.3 +++ /dev/null @@ -1,63 +0,0 @@ -.\" Copyright (c) 2019 Martin Matuska -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. -.\" -.Dd April 15, 2019 -.Dt ARCHIVE_ENTRY_MISC 3 -.Os -.Sh NAME -.Nm archive_entry_symlink_type , -.Nm archive_entry_set_symlink_type -.Nd miscellaneous functions for manipulating properties of archive_entry -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive_entry.h -.Ft int -.Fn archive_entry_symlink_type "struct archive_entry *a" -.Ft void -.Fn archive_entry_set_symlink_type "struct archive_entry *a" "int" -.Sh DESCRIPTION -The function -.Fn archive_entry_symlink_type -returns and the function -.Fn archive_entry_set_symlink_type -sets the type of the symbolic link stored in an archive entry. -These functions -have special meaning on operating systems that support multiple symbolic link -types (e.g. Microsoft Windows). -.Pp -Supported values are: -.Bl -tag -width "AE_SYMLINK_TYPE_DIRECTORY" -compact -.It AE_SYMLINK_TYPE_UNDEFINED -Symbolic link target type is not defined (default on unix systems) -.It AE_SYMLINK_TYPE_FILE -Symbolic link points to a file -.It AE_SYMLINK_TYPE_DIRECTORY -Symbolic link points to a directory -.El -.Sh SEE ALSO -.Xr archive_entry 3 , -.Xr archive_entry_paths 3 , -.Xr archive_entry_stat 3 , -.Xr libarchive 3 diff --git a/thirdparty/libarchive/libarchive/archive_entry_paths.3 b/thirdparty/libarchive/libarchive/archive_entry_paths.3 deleted file mode 100644 index 0f849c9eb..000000000 --- a/thirdparty/libarchive/libarchive/archive_entry_paths.3 +++ /dev/null @@ -1,153 +0,0 @@ -.\" Copyright (c) 2010 Joerg Sonnenberger -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. -.\" -.Dd February 2, 2012 -.Dt ARCHIVE_ENTRY_PATHS 3 -.Os -.Sh NAME -.Nm archive_entry_hardlink , -.Nm archive_entry_hardlink_w , -.Nm archive_entry_set_hardlink , -.Nm archive_entry_copy_hardlink , -.Nm archive_entry_copy_hardlink_w , -.Nm archive_entry_update_hardlink_utf8 , -.Nm archive_entry_set_link , -.Nm archive_entry_copy_link , -.Nm archive_entry_copy_link_w , -.Nm archive_entry_update_link_utf8 , -.Nm archive_entry_pathname , -.Nm archive_entry_pathname_w , -.Nm archive_entry_set_pathname , -.Nm archive_entry_copy_pathname , -.Nm archive_entry_copy_pathname_w , -.Nm archive_entry_update_pathname_utf8 , -.Nm archive_entry_sourcepath , -.Nm archive_entry_copy_sourcepath , -.Nm archive_entry_symlink , -.Nm archive_entry_symlink_w , -.Nm archive_entry_set_symlink , -.Nm archive_entry_copy_symlink , -.Nm archive_entry_copy_symlink_w , -.Nm archive_entry_update_symlink_utf8 -.Nd functions for manipulating path names in archive entry descriptions -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive_entry.h -.Ft const char * -.Fn archive_entry_hardlink "struct archive_entry *a" -.Ft const wchar_t * -.Fn archive_entry_hardlink_w "struct archive_entry *a" -.Ft void -.Fn archive_entry_set_hardlink "struct archive_entry *a" "const char *path" -.Ft void -.Fn archive_entry_copy_hardlink "struct archive_entry *a" "const char *path" -.Ft void -.Fn archive_entry_copy_hardlink_w "struct archive_entry *a "const wchar_t *path" -.Ft int -.Fn archive_entry_update_hardlink_utf8 "struct archive_entry *a" "const char *path" -.Ft void -.Fn archive_entry_set_link "struct archive_entry *a" "const char *path" -.Ft void -.Fn archive_entry_copy_link "struct archive_entry *a" " const char *path" -.Ft void -.Fn archive_entry_copy_link_w "struct archive_entry *a" " const wchar_t *path" -.Ft int -.Fn archive_entry_update_link_utf8 "struct archive_entry *a" " const char *path" -.Ft const char * -.Fn archive_entry_pathname "struct archive_entry *a" -.Ft const wchar_t * -.Fn archive_entry_pathname_w "struct archive_entry *a" -.Ft void -.Fn archive_entry_set_pathname "struct archive_entry *a" "const char *path" -.Ft void -.Fn archive_entry_copy_pathname "struct archive_entry *a" "const char *path" -.Ft void -.Fn archive_entry_copy_pathname_w "struct archive_entry *a" "const wchar_t *path" -.Ft int -.Fn archive_entry_update_pathname_utf8 "struct archive_entry *a" "const char *path" -.Ft const char * -.Fn archive_entry_sourcepath "struct archive_entry *a" -.Ft void -.Fn archive_entry_copy_sourcepath "struct archive_entry *a" "const char *path" -.Ft const char * -.Fn archive_entry_symlink "struct archive_entry *a" -.Ft const wchar_t * -.Fn archive_entry_symlink_w "struct archive_entry *a" -.Ft void -.Fn archive_entry_set_symlink "struct archive_entry *a" "const char *path" -.Ft void -.Fn archive_entry_copy_symlink "struct archive_entry *a" "const char *path" -.Ft void -.Fn archive_entry_copy_symlink_w "struct archive_entry *a" "const wchar_t *path" -.Ft int -.Fn archive_entry_update_symlink_utf8 "struct archive_entry *a" "const char *path" -.Sh DESCRIPTION -Path names supported by -.Xr archive_entry 3 : -.Bl -tag -width "sourcepath" -compact -.It hardlink -Destination of the hardlink. -.It link -Update only. -For a symlink, update the destination. -Otherwise, make the entry a hardlink and alter -the destination for that. -.It pathname -Path in the archive -.It sourcepath -Path on the disk for use by -.Xr archive_read_disk 3 . -.It symlink -Destination of the symbolic link. -.El -.Pp -Path names can be provided in one of three different ways: -.Bl -tag -width "wchar_t *" -.It char * -Multibyte strings in the current locale. -.It wchar_t * -Wide character strings in the current locale. -The accessor functions are named -.Fn XXX_w . -.It UTF-8 -Unicode strings encoded as UTF-8. -These are convenience functions to update both the multibyte and wide -character strings at the same time. -.El -.Pp -The sourcepath is a pure filesystem concept and never stored in an -archive directly. -.Pp -For that reason, it is only available as multibyte string. -The link path is a convenience function for conditionally setting -hardlink or symlink destination. -It doesn't have a corresponding get accessor function. -.Pp -.Fn archive_entry_set_XXX -is an alias for -.Fn archive_entry_copy_XXX . -.Sh SEE ALSO -.Xr archive_entry 3 , -.Xr libarchive 3 diff --git a/thirdparty/libarchive/libarchive/archive_entry_perms.3 b/thirdparty/libarchive/libarchive/archive_entry_perms.3 deleted file mode 100644 index 0291b7b49..000000000 --- a/thirdparty/libarchive/libarchive/archive_entry_perms.3 +++ /dev/null @@ -1,209 +0,0 @@ -.\" Copyright (c) 2003-2007 Tim Kientzle -.\" Copyright (c) 2010 Joerg Sonnenberger -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. -.\" -.Dd February 2, 2012 -.Dt ARCHIVE_ENTRY_PERMS 3 -.Os -.Sh NAME -.Nm archive_entry_gid , -.Nm archive_entry_set_gid , -.Nm archive_entry_uid , -.Nm archive_entry_set_uid , -.Nm archive_entry_perm , -.Nm archive_entry_set_perm , -.Nm archive_entry_strmode , -.Nm archive_entry_uname , -.Nm archive_entry_uname_w , -.Nm archive_entry_set_uname , -.Nm archive_entry_copy_uname , -.Nm archive_entry_copy_uname_w , -.Nm archive_entry_update_uname_utf8 , -.Nm archive_entry_gname , -.Nm archive_entry_gname_w , -.Nm archive_entry_set_gname , -.Nm archive_entry_copy_gname , -.Nm archive_entry_copy_gname_w , -.Nm archive_entry_update_gname_utf8 , -.Nm archive_entry_fflags , -.Nm archive_entry_fflags_text , -.Nm archive_entry_set_fflags , -.Nm archive_entry_copy_fflags_text , -.Nm archive_entry_copy_fflags_text_w -.Nd functions for manipulating ownership and permissions in archive entry descriptions -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive_entry.h -.Ft gid_t -.Fn archive_entry_gid "struct archive_entry *a" -.Ft void -.Fn archive_entry_set_gid "struct archive_entry *a" "gid_t gid" -.Ft uid_t -.Fn archive_entry_uid "struct archive_entry *a" -.Ft void -.Fn archive_entry_set_uid "struct archive_entry *a" "uid_t uid" -.Ft mode_t -.Fn archive_entry_perm "struct archive_entry *a" -.Ft void -.Fn archive_entry_set_perm "struct archive_entry *a" "mode_t mode" -.Ft const char * -.Fn archive_entry_strmode "struct archive_entry *a" -.Ft const char * -.Fn archive_entry_gname "struct archive_entry *a" -.Ft const wchar_t * -.Fn archive_entry_gname_w "struct archive_entry *a" -.Ft void -.Fn archive_entry_set_gname "struct archive_entry *a" "const char *a" -.Ft void -.Fn archive_entry_copy_gname "struct archive_entry *a" "const char *name" -.Ft void -.Fn archive_entry_copy_gname_w "struct archive_entry *a" "const wchar_t *name" -.Ft int -.Fn archive_entry_update_gname_utf8 "struct archive_entry *a" "const char *name" -.Ft const char * -.Fn archive_entry_uname "struct archive_entry *a" -.Ft const wchar_t * -.Fn archive_entry_uname_w "struct archive_entry *a" -.Ft void -.Fn archive_entry_set_uname "struct archive_entry *a" "const char *name" -.Ft void -.Fn archive_entry_copy_uname "struct archive_entry *a" "const char *name" -.Ft void -.Fn archive_entry_copy_uname_w "struct archive_entry *a" "const wchar_t *name" -.Ft int -.Fn archive_entry_update_uname_utf8 "struct archive_entry *a" "const char *name" -.Ft void -.Fo archive_entry_fflags -.Fa "struct archive_entry *a" -.Fa "unsigned long *set_bits" -.Fa "unsigned long *clear_bits" -.Fc -.Ft const char * -.Fn archive_entry_fflags_text "struct archive_entry *a" -.Ft void -.Fo archive_entry_set_fflags -.Fa "struct archive_entry *a" -.Fa "unsigned long set_bits" -.Fa "unsigned long clear_bits" -.Fc -.Ft const char * -.Fn archive_entry_copy_fflags_text "struct archive_entry *a" "const char *text" -.Ft const wchar_t * -.Fn archive_entry_copy_fflags_text_w "struct archive_entry *a" "const wchar_t *text" -.Sh DESCRIPTION -.Ss User id, group id and mode -The functions -.Fn archive_entry_uid , -.Fn archive_entry_gid , -and -.Fn archive_entry_perm -can be used to extract the user id, group id and permission from the given entry. -The corresponding functions -.Fn archive_entry_set_uid , -.Fn archive_entry_set_gid , -and -.Fn archive_entry_set_perm -store the given user id, group id and permission in the entry. -The permission is also set as a side effect of calling -.Fn archive_entry_set_mode . -.Pp -.Fn archive_entry_strmode -returns a string representation of the permission as used by the long mode of -.Xr ls 1 . -.Ss User and group name -User and group names can be provided in one of three different ways: -.Bl -tag -width "wchar_t *" -.It char * -Multibyte strings in the current locale. -.It wchar_t * -Wide character strings in the current locale. -The accessor functions are named -.Fn XXX_w . -.It UTF-8 -Unicode strings encoded as UTF-8. -These are convenience functions to update both the multibyte and wide -character strings at the same time. -.El -.Pp -.Fn archive_entry_set_XXX -is an alias for -.Fn archive_entry_copy_XXX . -.Ss File Flags -File flags are transparently converted between a bitmap -representation and a textual format. -For example, if you set the bitmap and ask for text, the library -will build a canonical text format. -However, if you set a text format and request a text format, -you will get back the same text, even if it is ill-formed. -If you need to canonicalize a textual flags string, you should first set the -text form, then request the bitmap form, then use that to set the bitmap form. -Setting the bitmap format will clear the internal text representation -and force it to be reconstructed when you next request the text form. -.Pp -The bitmap format consists of two integers, one containing bits -that should be set, the other specifying bits that should be -cleared. -Bits not mentioned in either bitmap will be ignored. -Usually, the bitmap of bits to be cleared will be set to zero. -In unusual circumstances, you can force a fully-specified set -of file flags by setting the bitmap of flags to clear to the complement -of the bitmap of flags to set. -(This differs from -.Xr fflagstostr 3 , -which only includes names for set bits.) -Converting a bitmap to a textual string is a platform-specific -operation; bits that are not meaningful on the current platform -will be ignored. -.Pp -The canonical text format is a comma-separated list of flag names. -The -.Fn archive_entry_copy_fflags_text -and -.Fn archive_entry_copy_fflags_text_w -functions parse the provided text and set the internal bitmap values. -This is a platform-specific operation; names that are not meaningful -on the current platform will be ignored. -The function returns a pointer to the start of the first name that was not -recognized, or NULL if every name was recognized. -Note that every name \(em including names that follow an unrecognized -name \(em will be evaluated, and the bitmaps will be set to reflect -every name that is recognized. -(In particular, this differs from -.Xr strtofflags 3 , -which stops parsing at the first unrecognized name.) -.Sh SEE ALSO -.Xr archive_entry 3 , -.Xr archive_entry_acl 3 , -.Xr archive_read_disk 3 , -.Xr archive_write_disk 3 , -.Xr libarchive 3 -.Sh BUGS -The platform types -.Vt uid_t -and -.Vt gid_t -are often 16 or 32 bit wide. -In this case it is possible that the ids can not be correctly restored -from archives and get truncated. diff --git a/thirdparty/libarchive/libarchive/archive_entry_private.h b/thirdparty/libarchive/libarchive/archive_entry_private.h deleted file mode 100644 index cf4deb24e..000000000 --- a/thirdparty/libarchive/libarchive/archive_entry_private.h +++ /dev/null @@ -1,200 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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: head/lib/libarchive/archive_entry_private.h 201096 2009-12-28 02:41:27Z kientzle $ - */ - -#ifndef ARCHIVE_ENTRY_PRIVATE_H_INCLUDED -#define ARCHIVE_ENTRY_PRIVATE_H_INCLUDED - -#ifndef __LIBARCHIVE_BUILD -#error This header is only to be used internally to libarchive. -#endif - -#include "archive_acl_private.h" -#include "archive_string.h" - -struct ae_xattr { - struct ae_xattr *next; - - char *name; - void *value; - size_t size; -}; - -struct ae_sparse { - struct ae_sparse *next; - - int64_t offset; - int64_t length; -}; - -struct ae_digest { - unsigned char md5[16]; - unsigned char rmd160[20]; - unsigned char sha1[20]; - unsigned char sha256[32]; - unsigned char sha384[48]; - unsigned char sha512[64]; -}; - -/* - * Description of an archive entry. - * - * Basically, this is a "struct stat" with a few text fields added in. - * - * TODO: Add "comment", "charset", and possibly other entries - * that are supported by "pax interchange" format. However, GNU, ustar, - * cpio, and other variants don't support these features, so they're not an - * excruciatingly high priority right now. - * - * TODO: "pax interchange" format allows essentially arbitrary - * key/value attributes to be attached to any entry. Supporting - * such extensions may make this library useful for special - * applications (e.g., a package manager could attach special - * package-management attributes to each entry). There are tricky - * API issues involved, so this is not going to happen until - * there's a real demand for it. - * - * TODO: Design a good API for handling sparse files. - */ -struct archive_entry { - struct archive *archive; - - /* - * Note that ae_stat.st_mode & AE_IFMT can be 0! - * - * This occurs when the actual file type of the object is not - * in the archive. For example, 'tar' archives store - * hardlinks without marking the type of the underlying - * object. - */ - - /* - * We have a "struct aest" for holding file metadata rather than just - * a "struct stat" because on some platforms the "struct stat" has - * fields which are too narrow to hold the range of possible values; - * we don't want to lose information if we read an archive and write - * out another (e.g., in "tar -cf new.tar @old.tar"). - * - * The "stat" pointer points to some form of platform-specific struct - * stat; it is declared as a void * rather than a struct stat * as - * some platforms have multiple varieties of stat structures. - */ - void *stat; - int stat_valid; /* Set to 0 whenever a field in aest changes. */ - - struct aest { - int64_t aest_atime; - uint32_t aest_atime_nsec; - int64_t aest_ctime; - uint32_t aest_ctime_nsec; - int64_t aest_mtime; - uint32_t aest_mtime_nsec; - int64_t aest_birthtime; - uint32_t aest_birthtime_nsec; - int64_t aest_gid; - int64_t aest_ino; - uint32_t aest_nlink; - uint64_t aest_size; - int64_t aest_uid; - /* - * Because converting between device codes and - * major/minor values is platform-specific and - * inherently a bit risky, we only do that conversion - * lazily. That way, we will do a better job of - * preserving information in those cases where no - * conversion is actually required. - */ - int aest_dev_is_broken_down; - dev_t aest_dev; - dev_t aest_devmajor; - dev_t aest_devminor; - int aest_rdev_is_broken_down; - dev_t aest_rdev; - dev_t aest_rdevmajor; - dev_t aest_rdevminor; - } ae_stat; - - int ae_set; /* bitmap of fields that are currently set */ -#define AE_SET_HARDLINK 1 -#define AE_SET_SYMLINK 2 -#define AE_SET_ATIME 4 -#define AE_SET_CTIME 8 -#define AE_SET_MTIME 16 -#define AE_SET_BIRTHTIME 32 -#define AE_SET_SIZE 64 -#define AE_SET_INO 128 -#define AE_SET_DEV 256 - - /* - * Use aes here so that we get transparent mbs<->wcs conversions. - */ - struct archive_mstring ae_fflags_text; /* Text fflags per fflagstostr(3) */ - unsigned long ae_fflags_set; /* Bitmap fflags */ - unsigned long ae_fflags_clear; - struct archive_mstring ae_gname; /* Name of owning group */ - struct archive_mstring ae_hardlink; /* Name of target for hardlink */ - struct archive_mstring ae_pathname; /* Name of entry */ - struct archive_mstring ae_symlink; /* symlink contents */ - struct archive_mstring ae_uname; /* Name of owner */ - - /* Not used within libarchive; useful for some clients. */ - struct archive_mstring ae_sourcepath; /* Path this entry is sourced from. */ - -#define AE_ENCRYPTION_NONE 0 -#define AE_ENCRYPTION_DATA 1 -#define AE_ENCRYPTION_METADATA 2 - char encryption; - - void *mac_metadata; - size_t mac_metadata_size; - - /* Digest support. */ - struct ae_digest digest; - - /* ACL support. */ - struct archive_acl acl; - - /* extattr support. */ - struct ae_xattr *xattr_head; - struct ae_xattr *xattr_p; - - /* sparse support. */ - struct ae_sparse *sparse_head; - struct ae_sparse *sparse_tail; - struct ae_sparse *sparse_p; - - /* Miscellaneous. */ - char strmode[12]; - - /* Symlink type support */ - int ae_symlink_type; -}; - -int -archive_entry_set_digest(struct archive_entry *entry, int type, - const unsigned char *digest); - -#endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */ diff --git a/thirdparty/libarchive/libarchive/archive_entry_sparse.c b/thirdparty/libarchive/libarchive/archive_entry_sparse.c deleted file mode 100644 index 74917b37b..000000000 --- a/thirdparty/libarchive/libarchive/archive_entry_sparse.c +++ /dev/null @@ -1,156 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2010-2011 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#include "archive.h" -#include "archive_entry.h" -#include "archive_private.h" -#include "archive_entry_private.h" - -/* - * sparse handling - */ - -void -archive_entry_sparse_clear(struct archive_entry *entry) -{ - struct ae_sparse *sp; - - while (entry->sparse_head != NULL) { - sp = entry->sparse_head->next; - free(entry->sparse_head); - entry->sparse_head = sp; - } - entry->sparse_tail = NULL; -} - -void -archive_entry_sparse_add_entry(struct archive_entry *entry, - la_int64_t offset, la_int64_t length) -{ - struct ae_sparse *sp; - - if (offset < 0 || length < 0) - /* Invalid value */ - return; - if (offset > INT64_MAX - length || - offset + length > archive_entry_size(entry)) - /* A value of "length" parameter is too large. */ - return; - if ((sp = entry->sparse_tail) != NULL) { - if (sp->offset + sp->length > offset) - /* Invalid value. */ - return; - if (sp->offset + sp->length == offset) { - if (sp->offset + sp->length + length < 0) - /* A value of "length" parameter is - * too large. */ - return; - /* Expand existing sparse block size. */ - sp->length += length; - return; - } - } - - if ((sp = (struct ae_sparse *)malloc(sizeof(*sp))) == NULL) - /* XXX Error XXX */ - return; - - sp->offset = offset; - sp->length = length; - sp->next = NULL; - - if (entry->sparse_head == NULL) - entry->sparse_head = entry->sparse_tail = sp; - else { - /* Add a new sparse block to the tail of list. */ - if (entry->sparse_tail != NULL) - entry->sparse_tail->next = sp; - entry->sparse_tail = sp; - } -} - - -/* - * returns number of the sparse entries - */ -int -archive_entry_sparse_count(struct archive_entry *entry) -{ - struct ae_sparse *sp; - int count = 0; - - for (sp = entry->sparse_head; sp != NULL; sp = sp->next) - count++; - - /* - * Sanity check if this entry is exactly sparse. - * If amount of sparse blocks is just one and it indicates the whole - * file data, we should remove it and return zero. - */ - if (count == 1) { - sp = entry->sparse_head; - if (sp->offset == 0 && - sp->length >= archive_entry_size(entry)) { - count = 0; - archive_entry_sparse_clear(entry); - } - } - - return (count); -} - -int -archive_entry_sparse_reset(struct archive_entry * entry) -{ - entry->sparse_p = entry->sparse_head; - - return archive_entry_sparse_count(entry); -} - -int -archive_entry_sparse_next(struct archive_entry * entry, - la_int64_t *offset, la_int64_t *length) -{ - if (entry->sparse_p) { - *offset = entry->sparse_p->offset; - *length = entry->sparse_p->length; - - entry->sparse_p = entry->sparse_p->next; - - return (ARCHIVE_OK); - } else { - *offset = 0; - *length = 0; - return (ARCHIVE_WARN); - } -} - -/* - * end of sparse handling - */ diff --git a/thirdparty/libarchive/libarchive/archive_entry_stat.3 b/thirdparty/libarchive/libarchive/archive_entry_stat.3 deleted file mode 100644 index 29a53f756..000000000 --- a/thirdparty/libarchive/libarchive/archive_entry_stat.3 +++ /dev/null @@ -1,274 +0,0 @@ -.\" Copyright (c) 2010 Joerg Sonnenberger -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. -.\" -.Dd February 2, 2012 -.Dt ARCHIVE_ENTRY_STAT 3 -.Os -.Sh NAME -.Nm archive_entry_stat , -.Nm archive_entry_copy_stat , -.Nm archive_entry_filetype , -.Nm archive_entry_set_filetype , -.Nm archive_entry_mode , -.Nm archive_entry_set_mode , -.Nm archive_entry_size , -.Nm archive_entry_size_is_set , -.Nm archive_entry_set_size , -.Nm archive_entry_unset_size , -.Nm archive_entry_dev , -.Nm archive_entry_set_dev , -.Nm archive_entry_dev_is_set , -.Nm archive_entry_devmajor , -.Nm archive_entry_set_devmajor , -.Nm archive_entry_devminor , -.Nm archive_entry_set_devminor , -.Nm archive_entry_ino , -.Nm archive_entry_set_ino , -.Nm archive_entry_ino_is_set , -.Nm archive_entry_ino64 , -.Nm archive_entry_set_ino64 , -.Nm archive_entry_nlink , -.Nm archive_entry_rdev , -.Nm archive_entry_set_rdev , -.Nm archive_entry_rdevmajor , -.Nm archive_entry_set_rdevmajor , -.Nm archive_entry_rdevminor , -.Nm archive_entry_set_rdevminor -.Nd accessor functions for manipulating archive entry descriptions -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive_entry.h -.Ft const struct stat * -.Fn archive_entry_stat "struct archive_entry *a" -.Ft void -.Fn archive_entry_copy_stat "struct archive_entry *a" "const struct stat *sb" -.Ft mode_t -.Fn archive_entry_filetype "struct archive_entry *a" -.Ft void -.Fn archive_entry_set_filetype "struct archive_entry *a" "unsigned int type" -.Ft mode_t -.Fn archive_entry_mode "struct archive_entry *a" -.Ft void -.Fn archive_entry_set_mode "struct archive_entry *a" "mode_t mode" -.Ft int64_t -.Fn archive_entry_size "struct archive_entry *a" -.Ft int -.Fn archive_entry_size_is_set "struct archive_entry *a" -.Ft void -.Fn archive_entry_set_size "struct archive_entry *a" "int64_t size" -.Ft void -.Fn archive_entry_unset_size "struct archive_entry *a" -.Ft dev_t -.Fn archive_entry_dev "struct archive_entry *a" -.Ft void -.Fn archive_entry_set_dev "struct archive_entry *a" "dev_t dev" -.Ft int -.Fn archive_entry_dev_is_set "struct archive_entry *a" -.Ft dev_t -.Fn archive_entry_devmajor "struct archive_entry *a" -.Ft void -.Fn archive_entry_set_devmajor "struct archive_entry *a" "dev_t major" -.Ft dev_t -.Fn archive_entry_devminor "struct archive_entry *a" -.Ft void -.Fn archive_entry_set_devminor "struct archive_entry *a" "dev_t minor" -.Ft ino_t -.Fn archive_entry_ino "struct archive_entry *a" -.Ft void -.Fn archive_entry_set_ino "struct archive_entry *a" "unsigned long ino" -.Ft int -.Fn archive_entry_ino_is_set "struct archive_entry *a" -.Ft int64_t -.Fn archive_entry_ino64 "struct archive_entry *a" -.Ft void -.Fn archive_entry_set_ino64 "struct archive_entry *a" "int64_t ino" -.Ft unsigned int -.Fn archive_entry_nlink "struct archive_entry *a" -.Ft void -.Fn archive_entry_set_nlink "struct archive_entry *a" "unsigned int count" -.Ft dev_t -.Fn archive_entry_rdev "struct archive_entry *a" -.Ft dev_t -.Fn archive_entry_rdevmajor "struct archive_entry *a" -.Ft dev_t -.Fn archive_entry_rdevminor "struct archive_entry *a" -.Ft void -.Fn archive_entry_set_rdev "struct archive_entry *a" "dev_t dev" -.Ft void -.Fn archive_entry_set_rdevmajor "struct archive_entry *a" "dev_t major" -.Ft void -.Fn archive_entry_set_rdevminor "struct archive_entry *a" "dev_t minor" -.Sh DESCRIPTION -.Ss Copying to and from Vt struct stat -The function -.Fn archive_entry_stat -converts the various fields stored in the archive entry to the format -used by -.Xr stat 2 . -The return value remains valid until either -.Fn archive_entry_clear -or -.Fn archive_entry_free -is called. -It is not affected by calls to the set accessor functions. -It currently sets the following values in -.Vt struct stat : -.Vt st_atime , -.Vt st_ctime , -.Vt st_dev , -.Vt st_gid , -.Vt st_ino , -.Vt st_mode , -.Vt st_mtime , -.Vt st_nlink , -.Vt st_rdev , -.Vt st_size , -.Vt st_uid . -In addition, -.Vt st_birthtime -and high-precision information for time-related fields -will be included on platforms that support it. -.Pp -The function -.Fn archive_entry_copy_stat -copies fields from the platform's -.Vt struct stat . -Fields not provided by -.Vt struct stat -are unchanged. -.Ss General accessor functions -The functions -.Fn archive_entry_filetype -and -.Fn archive_entry_set_filetype -get respectively set the filetype. -The file type is one of the following constants: -.Bl -tag -width "AE_IFSOCK" -compact -offset indent -.It AE_IFREG -Regular file -.It AE_IFLNK -Symbolic link -.It AE_IFSOCK -Socket -.It AE_IFCHR -Character device -.It AE_IFBLK -Block device -.It AE_IFDIR -Directory -.It AE_IFIFO -Named pipe (fifo) -.El -Not all file types are supported by all platforms. -The constants used by -.Xr stat 2 -may have different numeric values from the -corresponding constants above. -.Pp -The functions -.Fn archive_entry_mode -and -.Fn archive_entry_set_mode -get/set a combination of file type and permissions and provide the -equivalent of -.Va st_mode . -Use of -.Fn archive_entry_filetype -and -.Fn archive_entry_perm -for getting and -.Fn archive_entry_set_filetype -and -.Fn archive_entry_set_perm -for setting is recommended. -.Pp -The function -.Fn archive_entry_size -returns the file size, if it has been set, and 0 otherwise. -.Fn archive_entry_size -can be used to query that status. -.Fn archive_entry_set_size -and -.Fn archive_entry_unset_size -set and unset the size, respectively. -.Pp -The number of references (hardlinks) can be obtained by calling -.Fn archive_entry_nlink -and set with -.Fn archive_entry_set_nlink . -.Ss Identifying unique files -The functions -.Fn archive_entry_dev -and -.Fn archive_entry_ino64 -are used by -.Xr archive_entry_linkify 3 -to find hardlinks. -The pair of device and inode is supposed to identify hardlinked files. -.Pp -The device major and minor number can be obtained independently using -.Fn archive_entry_devmajor -and -.Fn archive_entry_devminor . -The device can be set either via -.Fn archive_entry_set_dev -or by the combination of major and minor number using -.Fn archive_entry_set_devmajor -and -.Fn archive_entry_set_devminor . -.Pp -The inode number can be obtained using -.Fn archive_entry_ino . -This is a legacy interface that uses the platform -.Vt ino_t , -which may be very small. -To set the inode number, -.Fn archive_entry_set_ino64 -is the preferred interface. -.Ss Accessor functions for block and character devices -Block and character devices are characterised either using a device number -or a pair of major and minor number. -The combined device number can be obtained with -.Fn archive_device_rdev -and set with -.Fn archive_device_set_rdev . -The major and minor numbers are accessed by -.Fn archive_device_rdevmajor , -.Fn archive_device_rdevminor -.Fn archive_device_set_rdevmajor -and -.Fn archive_device_set_rdevminor . -.Pp -The process of splitting the combined device number into major and -minor number and the reverse process of combing them differs between -platforms. -Some archive formats use the combined form, while other formats use -the split form. -.Sh SEE ALSO -.Xr stat 2 , -.Xr archive_entry_acl 3 , -.Xr archive_entry_perms 3 , -.Xr archive_entry_time 3 , -.Xr libarchive 3 diff --git a/thirdparty/libarchive/libarchive/archive_entry_stat.c b/thirdparty/libarchive/libarchive/archive_entry_stat.c deleted file mode 100644 index 71a407b1f..000000000 --- a/thirdparty/libarchive/libarchive/archive_entry_stat.c +++ /dev/null @@ -1,118 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_stat.c 201100 2009-12-28 03:05:31Z kientzle $"); - -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif - -#include "archive_entry.h" -#include "archive_entry_private.h" - -const struct stat * -archive_entry_stat(struct archive_entry *entry) -{ - struct stat *st; - if (entry->stat == NULL) { - entry->stat = calloc(1, sizeof(*st)); - if (entry->stat == NULL) - return (NULL); - entry->stat_valid = 0; - } - - /* - * If none of the underlying fields have been changed, we - * don't need to regenerate. In theory, we could use a bitmap - * here to flag only those items that have changed, but the - * extra complexity probably isn't worth it. It will be very - * rare for anyone to change just one field then request a new - * stat structure. - */ - if (entry->stat_valid) - return (entry->stat); - - st = entry->stat; - /* - * Use the public interfaces to extract items, so that - * the appropriate conversions get invoked. - */ - st->st_atime = archive_entry_atime(entry); -#if HAVE_STRUCT_STAT_ST_BIRTHTIME - st->st_birthtime = archive_entry_birthtime(entry); -#endif - st->st_ctime = archive_entry_ctime(entry); - st->st_mtime = archive_entry_mtime(entry); - st->st_dev = archive_entry_dev(entry); - st->st_gid = (gid_t)archive_entry_gid(entry); - st->st_uid = (uid_t)archive_entry_uid(entry); - st->st_ino = (ino_t)archive_entry_ino64(entry); - st->st_nlink = archive_entry_nlink(entry); - st->st_rdev = archive_entry_rdev(entry); - st->st_size = (off_t)archive_entry_size(entry); - st->st_mode = archive_entry_mode(entry); - - /* - * On systems that support high-res timestamps, copy that - * information into struct stat. - */ -#if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC - st->st_atimespec.tv_nsec = archive_entry_atime_nsec(entry); - st->st_ctimespec.tv_nsec = archive_entry_ctime_nsec(entry); - st->st_mtimespec.tv_nsec = archive_entry_mtime_nsec(entry); -#elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC - st->st_atim.tv_nsec = archive_entry_atime_nsec(entry); - st->st_ctim.tv_nsec = archive_entry_ctime_nsec(entry); - st->st_mtim.tv_nsec = archive_entry_mtime_nsec(entry); -#elif HAVE_STRUCT_STAT_ST_MTIME_N - st->st_atime_n = archive_entry_atime_nsec(entry); - st->st_ctime_n = archive_entry_ctime_nsec(entry); - st->st_mtime_n = archive_entry_mtime_nsec(entry); -#elif HAVE_STRUCT_STAT_ST_UMTIME - st->st_uatime = archive_entry_atime_nsec(entry) / 1000; - st->st_uctime = archive_entry_ctime_nsec(entry) / 1000; - st->st_umtime = archive_entry_mtime_nsec(entry) / 1000; -#elif HAVE_STRUCT_STAT_ST_MTIME_USEC - st->st_atime_usec = archive_entry_atime_nsec(entry) / 1000; - st->st_ctime_usec = archive_entry_ctime_nsec(entry) / 1000; - st->st_mtime_usec = archive_entry_mtime_nsec(entry) / 1000; -#endif -#if HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC - st->st_birthtimespec.tv_nsec = archive_entry_birthtime_nsec(entry); -#endif - - /* - * TODO: On Linux, store 32 or 64 here depending on whether - * the cached stat structure is a stat32 or a stat64. This - * will allow us to support both variants interchangeably. - */ - entry->stat_valid = 1; - - return (st); -} diff --git a/thirdparty/libarchive/libarchive/archive_entry_strmode.c b/thirdparty/libarchive/libarchive/archive_entry_strmode.c deleted file mode 100644 index af2517a32..000000000 --- a/thirdparty/libarchive/libarchive/archive_entry_strmode.c +++ /dev/null @@ -1,87 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_entry_strmode.c,v 1.4 2008/06/15 05:14:01 kientzle Exp $"); - -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "archive_entry.h" -#include "archive_entry_private.h" - -const char * -archive_entry_strmode(struct archive_entry *entry) -{ - static const mode_t permbits[] = - { 0400, 0200, 0100, 0040, 0020, 0010, 0004, 0002, 0001 }; - char *bp = entry->strmode; - mode_t mode; - int i; - - /* Fill in a default string, then selectively override. */ - strcpy(bp, "?rwxrwxrwx "); - - mode = archive_entry_mode(entry); - switch (archive_entry_filetype(entry)) { - case AE_IFREG: bp[0] = '-'; break; - case AE_IFBLK: bp[0] = 'b'; break; - case AE_IFCHR: bp[0] = 'c'; break; - case AE_IFDIR: bp[0] = 'd'; break; - case AE_IFLNK: bp[0] = 'l'; break; - case AE_IFSOCK: bp[0] = 's'; break; - case AE_IFIFO: bp[0] = 'p'; break; - default: - if (archive_entry_hardlink(entry) != NULL) { - bp[0] = 'h'; - break; - } - } - - for (i = 0; i < 9; i++) - if (!(mode & permbits[i])) - bp[i+1] = '-'; - - if (mode & S_ISUID) { - if (mode & 0100) bp[3] = 's'; - else bp[3] = 'S'; - } - if (mode & S_ISGID) { - if (mode & 0010) bp[6] = 's'; - else bp[6] = 'S'; - } - if (mode & S_ISVTX) { - if (mode & 0001) bp[9] = 't'; - else bp[9] = 'T'; - } - if (archive_entry_acl_types(entry) != 0) - bp[10] = '+'; - - return (bp); -} diff --git a/thirdparty/libarchive/libarchive/archive_entry_time.3 b/thirdparty/libarchive/libarchive/archive_entry_time.3 deleted file mode 100644 index d0563eaef..000000000 --- a/thirdparty/libarchive/libarchive/archive_entry_time.3 +++ /dev/null @@ -1,129 +0,0 @@ -.\" Copyright (c) 2003-2007 Tim Kientzle -.\" Copyright (c) 2010 Joerg Sonnenberger -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd February 2, 2012 -.Dt ARCHIVE_ENTRY_TIME 3 -.Os -.Sh NAME -.Nm archive_entry_atime , -.Nm archive_entry_atime_nsec , -.Nm archive_entry_atime_is_set , -.Nm archive_entry_set_atime , -.Nm archive_entry_unset_atime , -.Nm archive_entry_birthtime , -.Nm archive_entry_birthtime_nsec , -.Nm archive_entry_birthtime_is_set , -.Nm archive_entry_set_birthtime , -.Nm archive_entry_unset_birthtime , -.Nm archive_entry_ctime , -.Nm archive_entry_ctime_nsec , -.Nm archive_entry_ctime_is_set , -.Nm archive_entry_set_ctime , -.Nm archive_entry_unset_ctime , -.Nm archive_entry_mtime , -.Nm archive_entry_mtime_nsec , -.Nm archive_entry_mtime_is_set , -.Nm archive_entry_set_mtime , -.Nm archive_entry_unset_mtime -.Nd functions for manipulating times in archive entry descriptions -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive_entry.h -.Ft time_t -.Fn archive_entry_atime "struct archive_entry *a" -.Ft long -.Fn archive_entry_atime_nsec "struct archive_entry *a" -.Ft int -.Fn archive_entry_atime_is_set "struct archive_entry *a" -.Ft void -.Fn archive_entry_set_atime "struct archive_entry *a" "time_t sec" "long nanosec" -.Ft void -.Fn archive_entry_unset_atime "struct archive_entry *a" -.Ft time_t -.Fn archive_entry_birthtime "struct archive_entry *a" -.Ft long -.Fn archive_entry_birthtime_nsec "struct archive_entry *a" -.Ft int -.Fn archive_entry_birthtime_is_set "struct archive_entry *a" -.Ft void -.Fn archive_entry_set_birthtime "struct archive_entry *a" "time_t sec" "long nanosec" -.Ft void -.Fn archive_entry_unset_birthtime "struct archive_entry *a" -.Ft time_t -.Fn archive_entry_ctime "struct archive_entry *a" -.Ft long -.Fn archive_entry_ctime_nsec "struct archive_entry *a" -.Ft int -.Fn archive_entry_ctime_is_set "struct archive_entry *a" -.Ft void -.Fn archive_entry_set_ctime "struct archive_entry *a" "time_t sec" "long nanosec" -.Ft void -.Fn archive_entry_unset_ctime "struct archive_entry *a" -.Ft time_t -.Fn archive_entry_mtime "struct archive_entry *a" -.Ft long -.Fn archive_entry_mtime_nsec "struct archive_entry *a" -.Ft int -.Fn archive_entry_mtime_is_set "struct archive_entry *a" -.Ft void -.Fn archive_entry_set_mtime "struct archive_entry *a" "time_t sec" "long nanosec" -.Ft void -.Fn archive_entry_unset_mtime "struct archive_entry *a" -.Sh DESCRIPTION -These functions create and manipulate the time fields in an -.Vt archive_entry . -Supported time fields are atime (access time), birthtime (creation time), -ctime (last time an inode property was changed) and mtime (modification time). -.Pp -.Xr libarchive 3 -provides a high-resolution interface. -The timestamps are truncated automatically depending on the archive format -(for archiving) or the filesystem capabilities (for restoring). -.Pp -All timestamp fields are optional. -The -.Fn XXX_unset -functions can be used to mark the corresponding field as missing. -The current state can be queried using -.Fn XXX_is_set . -Unset time fields have a second and nanosecond field of 0. -.Sh SEE ALSO -.Xr archive_entry 3 , -.Xr libarchive 3 -.Sh HISTORY -The -.Nm libarchive -library first appeared in -.Fx 5.3 . -.Sh AUTHORS -.An -nosplit -The -.Nm libarchive -library was written by -.An Tim Kientzle Aq kientzle@acm.org . -.\" .Sh BUGS diff --git a/thirdparty/libarchive/libarchive/archive_entry_xattr.c b/thirdparty/libarchive/libarchive/archive_entry_xattr.c deleted file mode 100644 index 5fe726b99..000000000 --- a/thirdparty/libarchive/libarchive/archive_entry_xattr.c +++ /dev/null @@ -1,156 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_entry_xattr.c 201096 2009-12-28 02:41:27Z kientzle $"); - -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_LIMITS_H -#include -#endif -#ifdef HAVE_LINUX_FS_H -#include /* for Linux file flags */ -#endif -/* - * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h. - * As the include guards don't agree, the order of include is important. - */ -#ifdef HAVE_LINUX_EXT2_FS_H -#include /* for Linux file flags */ -#endif -#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__) -#include /* for Linux file flags */ -#endif -#include -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_WCHAR_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" -#include "archive_private.h" -#include "archive_entry_private.h" - -/* - * extended attribute handling - */ - -void -archive_entry_xattr_clear(struct archive_entry *entry) -{ - struct ae_xattr *xp; - - while (entry->xattr_head != NULL) { - xp = entry->xattr_head->next; - free(entry->xattr_head->name); - free(entry->xattr_head->value); - free(entry->xattr_head); - entry->xattr_head = xp; - } - - entry->xattr_head = NULL; -} - -void -archive_entry_xattr_add_entry(struct archive_entry *entry, - const char *name, const void *value, size_t size) -{ - struct ae_xattr *xp; - - if ((xp = (struct ae_xattr *)malloc(sizeof(struct ae_xattr))) == NULL) - __archive_errx(1, "Out of memory"); - - if ((xp->name = strdup(name)) == NULL) - __archive_errx(1, "Out of memory"); - - if ((xp->value = malloc(size)) != NULL) { - memcpy(xp->value, value, size); - xp->size = size; - } else - xp->size = 0; - - xp->next = entry->xattr_head; - entry->xattr_head = xp; -} - - -/* - * returns number of the extended attribute entries - */ -int -archive_entry_xattr_count(struct archive_entry *entry) -{ - struct ae_xattr *xp; - int count = 0; - - for (xp = entry->xattr_head; xp != NULL; xp = xp->next) - count++; - - return count; -} - -int -archive_entry_xattr_reset(struct archive_entry * entry) -{ - entry->xattr_p = entry->xattr_head; - - return archive_entry_xattr_count(entry); -} - -int -archive_entry_xattr_next(struct archive_entry * entry, - const char **name, const void **value, size_t *size) -{ - if (entry->xattr_p) { - *name = entry->xattr_p->name; - *value = entry->xattr_p->value; - *size = entry->xattr_p->size; - - entry->xattr_p = entry->xattr_p->next; - - return (ARCHIVE_OK); - } else { - *name = NULL; - *value = NULL; - *size = (size_t)0; - return (ARCHIVE_WARN); - } -} - -/* - * end of xattr handling - */ diff --git a/thirdparty/libarchive/libarchive/archive_getdate.c b/thirdparty/libarchive/libarchive/archive_getdate.c deleted file mode 100644 index 20ab1b158..000000000 --- a/thirdparty/libarchive/libarchive/archive_getdate.c +++ /dev/null @@ -1,1104 +0,0 @@ -/* - * This code is in the public domain and has no copyright. - * - * This is a plain C recursive-descent translation of an old - * public-domain YACC grammar that has been used for parsing dates in - * very many open-source projects. - * - * Since the original authors were generous enough to donate their - * work to the public domain, I feel compelled to match their - * generosity. - * - * Tim Kientzle, February 2009. - */ - -/* - * Header comment from original getdate.y: - */ - -/* -** Originally written by Steven M. Bellovin while -** at the University of North Carolina at Chapel Hill. Later tweaked by -** a couple of people on Usenet. Completely overhauled by Rich $alz -** and Jim Berets in August, 1990; -** -** This grammar has 10 shift/reduce conflicts. -** -** This code is in the public domain and has no copyright. -*/ - -#include "archive_platform.h" -#ifdef __FreeBSD__ -#include -__FBSDID("$FreeBSD$"); -#endif - -#include -#include -#include -#include -#include - -#define __LIBARCHIVE_BUILD 1 -#include "archive_getdate.h" - -/* Basic time units. */ -#define EPOCH 1970 -#define MINUTE (60L) -#define HOUR (60L * MINUTE) -#define DAY (24L * HOUR) - -/* Daylight-savings mode: on, off, or not yet known. */ -enum DSTMODE { DSTon, DSToff, DSTmaybe }; -/* Meridian: am or pm. */ -enum { tAM, tPM }; -/* Token types returned by nexttoken() */ -enum { tAGO = 260, tDAY, tDAYZONE, tAMPM, tMONTH, tMONTH_UNIT, tSEC_UNIT, - tUNUMBER, tZONE, tDST }; -struct token { int token; time_t value; }; - -/* - * Parser state. - */ -struct gdstate { - struct token *tokenp; /* Pointer to next token. */ - /* HaveXxxx counts how many of this kind of phrase we've seen; - * it's a fatal error to have more than one time, zone, day, - * or date phrase. */ - int HaveYear; - int HaveMonth; - int HaveDay; - int HaveWeekDay; /* Day of week */ - int HaveTime; /* Hour/minute/second */ - int HaveZone; /* timezone and/or DST info */ - int HaveRel; /* time offset; we can have more than one */ - /* Absolute time values. */ - time_t Timezone; /* Seconds offset from GMT */ - time_t Day; - time_t Hour; - time_t Minutes; - time_t Month; - time_t Seconds; - time_t Year; - /* DST selection */ - enum DSTMODE DSTmode; - /* Day of week accounting, e.g., "3rd Tuesday" */ - time_t DayOrdinal; /* "3" in "3rd Tuesday" */ - time_t DayNumber; /* "Tuesday" in "3rd Tuesday" */ - /* Relative time values: hour/day/week offsets are measured in - * seconds, month/year are counted in months. */ - time_t RelMonth; - time_t RelSeconds; -}; - -/* - * A series of functions that recognize certain common time phrases. - * Each function returns 1 if it managed to make sense of some of the - * tokens, zero otherwise. - */ - -/* - * hour:minute or hour:minute:second with optional AM, PM, or numeric - * timezone offset - */ -static int -timephrase(struct gdstate *gds) -{ - if (gds->tokenp[0].token == tUNUMBER - && gds->tokenp[1].token == ':' - && gds->tokenp[2].token == tUNUMBER - && gds->tokenp[3].token == ':' - && gds->tokenp[4].token == tUNUMBER) { - /* "12:14:18" or "22:08:07" */ - ++gds->HaveTime; - gds->Hour = gds->tokenp[0].value; - gds->Minutes = gds->tokenp[2].value; - gds->Seconds = gds->tokenp[4].value; - gds->tokenp += 5; - } - else if (gds->tokenp[0].token == tUNUMBER - && gds->tokenp[1].token == ':' - && gds->tokenp[2].token == tUNUMBER) { - /* "12:14" or "22:08" */ - ++gds->HaveTime; - gds->Hour = gds->tokenp[0].value; - gds->Minutes = gds->tokenp[2].value; - gds->Seconds = 0; - gds->tokenp += 3; - } - else if (gds->tokenp[0].token == tUNUMBER - && gds->tokenp[1].token == tAMPM) { - /* "7" is a time if it's followed by "am" or "pm" */ - ++gds->HaveTime; - gds->Hour = gds->tokenp[0].value; - gds->Minutes = gds->Seconds = 0; - /* We'll handle the AM/PM below. */ - gds->tokenp += 1; - } else { - /* We can't handle this. */ - return 0; - } - - if (gds->tokenp[0].token == tAMPM) { - /* "7:12pm", "12:20:13am" */ - if (gds->Hour == 12) - gds->Hour = 0; - if (gds->tokenp[0].value == tPM) - gds->Hour += 12; - gds->tokenp += 1; - } - if (gds->tokenp[0].token == '+' - && gds->tokenp[1].token == tUNUMBER) { - /* "7:14+0700" */ - gds->HaveZone++; - gds->DSTmode = DSToff; - gds->Timezone = - ((gds->tokenp[1].value / 100) * HOUR - + (gds->tokenp[1].value % 100) * MINUTE); - gds->tokenp += 2; - } - if (gds->tokenp[0].token == '-' - && gds->tokenp[1].token == tUNUMBER) { - /* "19:14:12-0530" */ - gds->HaveZone++; - gds->DSTmode = DSToff; - gds->Timezone = + ((gds->tokenp[1].value / 100) * HOUR - + (gds->tokenp[1].value % 100) * MINUTE); - gds->tokenp += 2; - } - return 1; -} - -/* - * Timezone name, possibly including DST. - */ -static int -zonephrase(struct gdstate *gds) -{ - if (gds->tokenp[0].token == tZONE - && gds->tokenp[1].token == tDST) { - gds->HaveZone++; - gds->Timezone = gds->tokenp[0].value; - gds->DSTmode = DSTon; - gds->tokenp += 1; - return 1; - } - - if (gds->tokenp[0].token == tZONE) { - gds->HaveZone++; - gds->Timezone = gds->tokenp[0].value; - gds->DSTmode = DSToff; - gds->tokenp += 1; - return 1; - } - - if (gds->tokenp[0].token == tDAYZONE) { - gds->HaveZone++; - gds->Timezone = gds->tokenp[0].value; - gds->DSTmode = DSTon; - gds->tokenp += 1; - return 1; - } - return 0; -} - -/* - * Year/month/day in various combinations. - */ -static int -datephrase(struct gdstate *gds) -{ - if (gds->tokenp[0].token == tUNUMBER - && gds->tokenp[1].token == '/' - && gds->tokenp[2].token == tUNUMBER - && gds->tokenp[3].token == '/' - && gds->tokenp[4].token == tUNUMBER) { - gds->HaveYear++; - gds->HaveMonth++; - gds->HaveDay++; - if (gds->tokenp[0].value >= 13) { - /* First number is big: 2004/01/29, 99/02/17 */ - gds->Year = gds->tokenp[0].value; - gds->Month = gds->tokenp[2].value; - gds->Day = gds->tokenp[4].value; - } else if ((gds->tokenp[4].value >= 13) - || (gds->tokenp[2].value >= 13)) { - /* Last number is big: 01/07/98 */ - /* Middle number is big: 01/29/04 */ - gds->Month = gds->tokenp[0].value; - gds->Day = gds->tokenp[2].value; - gds->Year = gds->tokenp[4].value; - } else { - /* No significant clues: 02/03/04 */ - gds->Month = gds->tokenp[0].value; - gds->Day = gds->tokenp[2].value; - gds->Year = gds->tokenp[4].value; - } - gds->tokenp += 5; - return 1; - } - - if (gds->tokenp[0].token == tUNUMBER - && gds->tokenp[1].token == '/' - && gds->tokenp[2].token == tUNUMBER) { - /* "1/15" */ - gds->HaveMonth++; - gds->HaveDay++; - gds->Month = gds->tokenp[0].value; - gds->Day = gds->tokenp[2].value; - gds->tokenp += 3; - return 1; - } - - if (gds->tokenp[0].token == tUNUMBER - && gds->tokenp[1].token == '-' - && gds->tokenp[2].token == tUNUMBER - && gds->tokenp[3].token == '-' - && gds->tokenp[4].token == tUNUMBER) { - /* ISO 8601 format. yyyy-mm-dd. */ - gds->HaveYear++; - gds->HaveMonth++; - gds->HaveDay++; - gds->Year = gds->tokenp[0].value; - gds->Month = gds->tokenp[2].value; - gds->Day = gds->tokenp[4].value; - gds->tokenp += 5; - return 1; - } - - if (gds->tokenp[0].token == tUNUMBER - && gds->tokenp[1].token == '-' - && gds->tokenp[2].token == tMONTH - && gds->tokenp[3].token == '-' - && gds->tokenp[4].token == tUNUMBER) { - gds->HaveYear++; - gds->HaveMonth++; - gds->HaveDay++; - if (gds->tokenp[0].value > 31) { - /* e.g. 1992-Jun-17 */ - gds->Year = gds->tokenp[0].value; - gds->Month = gds->tokenp[2].value; - gds->Day = gds->tokenp[4].value; - } else { - /* e.g. 17-JUN-1992. */ - gds->Day = gds->tokenp[0].value; - gds->Month = gds->tokenp[2].value; - gds->Year = gds->tokenp[4].value; - } - gds->tokenp += 5; - return 1; - } - - if (gds->tokenp[0].token == tMONTH - && gds->tokenp[1].token == tUNUMBER - && gds->tokenp[2].token == ',' - && gds->tokenp[3].token == tUNUMBER) { - /* "June 17, 2001" */ - gds->HaveYear++; - gds->HaveMonth++; - gds->HaveDay++; - gds->Month = gds->tokenp[0].value; - gds->Day = gds->tokenp[1].value; - gds->Year = gds->tokenp[3].value; - gds->tokenp += 4; - return 1; - } - - if (gds->tokenp[0].token == tMONTH - && gds->tokenp[1].token == tUNUMBER) { - /* "May 3" */ - gds->HaveMonth++; - gds->HaveDay++; - gds->Month = gds->tokenp[0].value; - gds->Day = gds->tokenp[1].value; - gds->tokenp += 2; - return 1; - } - - if (gds->tokenp[0].token == tUNUMBER - && gds->tokenp[1].token == tMONTH - && gds->tokenp[2].token == tUNUMBER) { - /* "12 Sept 1997" */ - gds->HaveYear++; - gds->HaveMonth++; - gds->HaveDay++; - gds->Day = gds->tokenp[0].value; - gds->Month = gds->tokenp[1].value; - gds->Year = gds->tokenp[2].value; - gds->tokenp += 3; - return 1; - } - - if (gds->tokenp[0].token == tUNUMBER - && gds->tokenp[1].token == tMONTH) { - /* "12 Sept" */ - gds->HaveMonth++; - gds->HaveDay++; - gds->Day = gds->tokenp[0].value; - gds->Month = gds->tokenp[1].value; - gds->tokenp += 2; - return 1; - } - - return 0; -} - -/* - * Relative time phrase: "tomorrow", "yesterday", "+1 hour", etc. - */ -static int -relunitphrase(struct gdstate *gds) -{ - if (gds->tokenp[0].token == '-' - && gds->tokenp[1].token == tUNUMBER - && gds->tokenp[2].token == tSEC_UNIT) { - /* "-3 hours" */ - gds->HaveRel++; - gds->RelSeconds -= gds->tokenp[1].value * gds->tokenp[2].value; - gds->tokenp += 3; - return 1; - } - if (gds->tokenp[0].token == '+' - && gds->tokenp[1].token == tUNUMBER - && gds->tokenp[2].token == tSEC_UNIT) { - /* "+1 minute" */ - gds->HaveRel++; - gds->RelSeconds += gds->tokenp[1].value * gds->tokenp[2].value; - gds->tokenp += 3; - return 1; - } - if (gds->tokenp[0].token == tUNUMBER - && gds->tokenp[1].token == tSEC_UNIT) { - /* "1 day" */ - gds->HaveRel++; - gds->RelSeconds += gds->tokenp[0].value * gds->tokenp[1].value; - gds->tokenp += 2; - return 1; - } - if (gds->tokenp[0].token == '-' - && gds->tokenp[1].token == tUNUMBER - && gds->tokenp[2].token == tMONTH_UNIT) { - /* "-3 months" */ - gds->HaveRel++; - gds->RelMonth -= gds->tokenp[1].value * gds->tokenp[2].value; - gds->tokenp += 3; - return 1; - } - if (gds->tokenp[0].token == '+' - && gds->tokenp[1].token == tUNUMBER - && gds->tokenp[2].token == tMONTH_UNIT) { - /* "+5 years" */ - gds->HaveRel++; - gds->RelMonth += gds->tokenp[1].value * gds->tokenp[2].value; - gds->tokenp += 3; - return 1; - } - if (gds->tokenp[0].token == tUNUMBER - && gds->tokenp[1].token == tMONTH_UNIT) { - /* "2 years" */ - gds->HaveRel++; - gds->RelMonth += gds->tokenp[0].value * gds->tokenp[1].value; - gds->tokenp += 2; - return 1; - } - if (gds->tokenp[0].token == tSEC_UNIT) { - /* "now", "tomorrow" */ - gds->HaveRel++; - gds->RelSeconds += gds->tokenp[0].value; - gds->tokenp += 1; - return 1; - } - if (gds->tokenp[0].token == tMONTH_UNIT) { - /* "month" */ - gds->HaveRel++; - gds->RelMonth += gds->tokenp[0].value; - gds->tokenp += 1; - return 1; - } - return 0; -} - -/* - * Day of the week specification. - */ -static int -dayphrase(struct gdstate *gds) -{ - if (gds->tokenp[0].token == tDAY) { - /* "tues", "wednesday," */ - gds->HaveWeekDay++; - gds->DayOrdinal = 1; - gds->DayNumber = gds->tokenp[0].value; - gds->tokenp += 1; - if (gds->tokenp[0].token == ',') - gds->tokenp += 1; - return 1; - } - if (gds->tokenp[0].token == tUNUMBER - && gds->tokenp[1].token == tDAY) { - /* "second tues" "3 wed" */ - gds->HaveWeekDay++; - gds->DayOrdinal = gds->tokenp[0].value; - gds->DayNumber = gds->tokenp[1].value; - gds->tokenp += 2; - return 1; - } - return 0; -} - -/* - * Try to match a phrase using one of the above functions. - * This layer also deals with a couple of generic issues. - */ -static int -phrase(struct gdstate *gds) -{ - if (timephrase(gds)) - return 1; - if (zonephrase(gds)) - return 1; - if (datephrase(gds)) - return 1; - if (dayphrase(gds)) - return 1; - if (relunitphrase(gds)) { - if (gds->tokenp[0].token == tAGO) { - gds->RelSeconds = -gds->RelSeconds; - gds->RelMonth = -gds->RelMonth; - gds->tokenp += 1; - } - return 1; - } - - /* Bare numbers sometimes have meaning. */ - if (gds->tokenp[0].token == tUNUMBER) { - if (gds->HaveTime && !gds->HaveYear && !gds->HaveRel) { - gds->HaveYear++; - gds->Year = gds->tokenp[0].value; - gds->tokenp += 1; - return 1; - } - - if(gds->tokenp[0].value > 10000) { - /* "20040301" */ - gds->HaveYear++; - gds->HaveMonth++; - gds->HaveDay++; - gds->Day= (gds->tokenp[0].value)%100; - gds->Month= (gds->tokenp[0].value/100)%100; - gds->Year = gds->tokenp[0].value/10000; - gds->tokenp += 1; - return 1; - } - - if (gds->tokenp[0].value < 24) { - gds->HaveTime++; - gds->Hour = gds->tokenp[0].value; - gds->Minutes = 0; - gds->Seconds = 0; - gds->tokenp += 1; - return 1; - } - - if ((gds->tokenp[0].value / 100 < 24) - && (gds->tokenp[0].value % 100 < 60)) { - /* "513" is same as "5:13" */ - gds->Hour = gds->tokenp[0].value / 100; - gds->Minutes = gds->tokenp[0].value % 100; - gds->Seconds = 0; - gds->tokenp += 1; - return 1; - } - } - - return 0; -} - -/* - * A dictionary of time words. - */ -static struct LEXICON { - size_t abbrev; - const char *name; - int type; - time_t value; -} const TimeWords[] = { - /* am/pm */ - { 0, "am", tAMPM, tAM }, - { 0, "pm", tAMPM, tPM }, - - /* Month names. */ - { 3, "january", tMONTH, 1 }, - { 3, "february", tMONTH, 2 }, - { 3, "march", tMONTH, 3 }, - { 3, "april", tMONTH, 4 }, - { 3, "may", tMONTH, 5 }, - { 3, "june", tMONTH, 6 }, - { 3, "july", tMONTH, 7 }, - { 3, "august", tMONTH, 8 }, - { 3, "september", tMONTH, 9 }, - { 3, "october", tMONTH, 10 }, - { 3, "november", tMONTH, 11 }, - { 3, "december", tMONTH, 12 }, - - /* Days of the week. */ - { 2, "sunday", tDAY, 0 }, - { 3, "monday", tDAY, 1 }, - { 2, "tuesday", tDAY, 2 }, - { 3, "wednesday", tDAY, 3 }, - { 2, "thursday", tDAY, 4 }, - { 2, "friday", tDAY, 5 }, - { 2, "saturday", tDAY, 6 }, - - /* Timezones: Offsets are in seconds. */ - { 0, "gmt", tZONE, 0*HOUR }, /* Greenwich Mean */ - { 0, "ut", tZONE, 0*HOUR }, /* Universal (Coordinated) */ - { 0, "utc", tZONE, 0*HOUR }, - { 0, "wet", tZONE, 0*HOUR }, /* Western European */ - { 0, "bst", tDAYZONE, 0*HOUR }, /* British Summer */ - { 0, "wat", tZONE, 1*HOUR }, /* West Africa */ - { 0, "at", tZONE, 2*HOUR }, /* Azores */ - /* { 0, "bst", tZONE, 3*HOUR }, */ /* Brazil Standard: Conflict */ - /* { 0, "gst", tZONE, 3*HOUR }, */ /* Greenland Standard: Conflict*/ - { 0, "nft", tZONE, 3*HOUR+30*MINUTE }, /* Newfoundland */ - { 0, "nst", tZONE, 3*HOUR+30*MINUTE }, /* Newfoundland Standard */ - { 0, "ndt", tDAYZONE, 3*HOUR+30*MINUTE }, /* Newfoundland Daylight */ - { 0, "ast", tZONE, 4*HOUR }, /* Atlantic Standard */ - { 0, "adt", tDAYZONE, 4*HOUR }, /* Atlantic Daylight */ - { 0, "est", tZONE, 5*HOUR }, /* Eastern Standard */ - { 0, "edt", tDAYZONE, 5*HOUR }, /* Eastern Daylight */ - { 0, "cst", tZONE, 6*HOUR }, /* Central Standard */ - { 0, "cdt", tDAYZONE, 6*HOUR }, /* Central Daylight */ - { 0, "mst", tZONE, 7*HOUR }, /* Mountain Standard */ - { 0, "mdt", tDAYZONE, 7*HOUR }, /* Mountain Daylight */ - { 0, "pst", tZONE, 8*HOUR }, /* Pacific Standard */ - { 0, "pdt", tDAYZONE, 8*HOUR }, /* Pacific Daylight */ - { 0, "yst", tZONE, 9*HOUR }, /* Yukon Standard */ - { 0, "ydt", tDAYZONE, 9*HOUR }, /* Yukon Daylight */ - { 0, "hst", tZONE, 10*HOUR }, /* Hawaii Standard */ - { 0, "hdt", tDAYZONE, 10*HOUR }, /* Hawaii Daylight */ - { 0, "cat", tZONE, 10*HOUR }, /* Central Alaska */ - { 0, "ahst", tZONE, 10*HOUR }, /* Alaska-Hawaii Standard */ - { 0, "nt", tZONE, 11*HOUR }, /* Nome */ - { 0, "idlw", tZONE, 12*HOUR }, /* Intl Date Line West */ - { 0, "cet", tZONE, -1*HOUR }, /* Central European */ - { 0, "met", tZONE, -1*HOUR }, /* Middle European */ - { 0, "mewt", tZONE, -1*HOUR }, /* Middle European Winter */ - { 0, "mest", tDAYZONE, -1*HOUR }, /* Middle European Summer */ - { 0, "swt", tZONE, -1*HOUR }, /* Swedish Winter */ - { 0, "sst", tDAYZONE, -1*HOUR }, /* Swedish Summer */ - { 0, "fwt", tZONE, -1*HOUR }, /* French Winter */ - { 0, "fst", tDAYZONE, -1*HOUR }, /* French Summer */ - { 0, "eet", tZONE, -2*HOUR }, /* Eastern Eur, USSR Zone 1 */ - { 0, "bt", tZONE, -3*HOUR }, /* Baghdad, USSR Zone 2 */ - { 0, "it", tZONE, -3*HOUR-30*MINUTE },/* Iran */ - { 0, "zp4", tZONE, -4*HOUR }, /* USSR Zone 3 */ - { 0, "zp5", tZONE, -5*HOUR }, /* USSR Zone 4 */ - { 0, "ist", tZONE, -5*HOUR-30*MINUTE },/* Indian Standard */ - { 0, "zp6", tZONE, -6*HOUR }, /* USSR Zone 5 */ - /* { 0, "nst", tZONE, -6.5*HOUR }, */ /* North Sumatra: Conflict */ - /* { 0, "sst", tZONE, -7*HOUR }, */ /* So Sumatra, USSR 6: Conflict */ - { 0, "wast", tZONE, -7*HOUR }, /* West Australian Standard */ - { 0, "wadt", tDAYZONE, -7*HOUR }, /* West Australian Daylight */ - { 0, "jt", tZONE, -7*HOUR-30*MINUTE },/* Java (3pm in Cronusland!)*/ - { 0, "cct", tZONE, -8*HOUR }, /* China Coast, USSR Zone 7 */ - { 0, "jst", tZONE, -9*HOUR }, /* Japan Std, USSR Zone 8 */ - { 0, "cast", tZONE, -9*HOUR-30*MINUTE },/* Ctrl Australian Std */ - { 0, "cadt", tDAYZONE, -9*HOUR-30*MINUTE },/* Ctrl Australian Daylt */ - { 0, "east", tZONE, -10*HOUR }, /* Eastern Australian Std */ - { 0, "eadt", tDAYZONE, -10*HOUR }, /* Eastern Australian Daylt */ - { 0, "gst", tZONE, -10*HOUR }, /* Guam Std, USSR Zone 9 */ - { 0, "nzt", tZONE, -12*HOUR }, /* New Zealand */ - { 0, "nzst", tZONE, -12*HOUR }, /* New Zealand Standard */ - { 0, "nzdt", tDAYZONE, -12*HOUR }, /* New Zealand Daylight */ - { 0, "idle", tZONE, -12*HOUR }, /* Intl Date Line East */ - - { 0, "dst", tDST, 0 }, - - /* Time units. */ - { 4, "years", tMONTH_UNIT, 12 }, - { 5, "months", tMONTH_UNIT, 1 }, - { 9, "fortnights", tSEC_UNIT, 14 * DAY }, - { 4, "weeks", tSEC_UNIT, 7 * DAY }, - { 3, "days", tSEC_UNIT, DAY }, - { 4, "hours", tSEC_UNIT, HOUR }, - { 3, "minutes", tSEC_UNIT, MINUTE }, - { 3, "seconds", tSEC_UNIT, 1 }, - - /* Relative-time words. */ - { 0, "tomorrow", tSEC_UNIT, DAY }, - { 0, "yesterday", tSEC_UNIT, -DAY }, - { 0, "today", tSEC_UNIT, 0 }, - { 0, "now", tSEC_UNIT, 0 }, - { 0, "last", tUNUMBER, -1 }, - { 0, "this", tSEC_UNIT, 0 }, - { 0, "next", tUNUMBER, 2 }, - { 0, "first", tUNUMBER, 1 }, - { 0, "1st", tUNUMBER, 1 }, -/* { 0, "second", tUNUMBER, 2 }, */ - { 0, "2nd", tUNUMBER, 2 }, - { 0, "third", tUNUMBER, 3 }, - { 0, "3rd", tUNUMBER, 3 }, - { 0, "fourth", tUNUMBER, 4 }, - { 0, "4th", tUNUMBER, 4 }, - { 0, "fifth", tUNUMBER, 5 }, - { 0, "5th", tUNUMBER, 5 }, - { 0, "sixth", tUNUMBER, 6 }, - { 0, "seventh", tUNUMBER, 7 }, - { 0, "eighth", tUNUMBER, 8 }, - { 0, "ninth", tUNUMBER, 9 }, - { 0, "tenth", tUNUMBER, 10 }, - { 0, "eleventh", tUNUMBER, 11 }, - { 0, "twelfth", tUNUMBER, 12 }, - { 0, "ago", tAGO, 1 }, - - /* Military timezones. */ - { 0, "a", tZONE, 1*HOUR }, - { 0, "b", tZONE, 2*HOUR }, - { 0, "c", tZONE, 3*HOUR }, - { 0, "d", tZONE, 4*HOUR }, - { 0, "e", tZONE, 5*HOUR }, - { 0, "f", tZONE, 6*HOUR }, - { 0, "g", tZONE, 7*HOUR }, - { 0, "h", tZONE, 8*HOUR }, - { 0, "i", tZONE, 9*HOUR }, - { 0, "k", tZONE, 10*HOUR }, - { 0, "l", tZONE, 11*HOUR }, - { 0, "m", tZONE, 12*HOUR }, - { 0, "n", tZONE, -1*HOUR }, - { 0, "o", tZONE, -2*HOUR }, - { 0, "p", tZONE, -3*HOUR }, - { 0, "q", tZONE, -4*HOUR }, - { 0, "r", tZONE, -5*HOUR }, - { 0, "s", tZONE, -6*HOUR }, - { 0, "t", tZONE, -7*HOUR }, - { 0, "u", tZONE, -8*HOUR }, - { 0, "v", tZONE, -9*HOUR }, - { 0, "w", tZONE, -10*HOUR }, - { 0, "x", tZONE, -11*HOUR }, - { 0, "y", tZONE, -12*HOUR }, - { 0, "z", tZONE, 0*HOUR }, - - /* End of table. */ - { 0, NULL, 0, 0 } -}; - -/* - * Year is either: - * = A number from 0 to 99, which means a year from 1970 to 2069, or - * = The actual year (>=100). - */ -static time_t -Convert(time_t Month, time_t Day, time_t Year, - time_t Hours, time_t Minutes, time_t Seconds, - time_t Timezone, enum DSTMODE DSTmode) -{ - signed char DaysInMonth[12] = { - 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 - }; - time_t Julian; - int i; - struct tm *ltime; -#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S) - struct tm tmbuf; -#endif - - if (Year < 69) - Year += 2000; - else if (Year < 100) - Year += 1900; - DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0) - ? 29 : 28; - /* Checking for 2038 bogusly assumes that time_t is 32 bits. But - I'm too lazy to try to check for time_t overflow in another way. */ - if (Year < EPOCH || Year >= 2038 - || Month < 1 || Month > 12 - /* Lint fluff: "conversion from long may lose accuracy" */ - || Day < 1 || Day > DaysInMonth[(int)--Month] - || Hours < 0 || Hours > 23 - || Minutes < 0 || Minutes > 59 - || Seconds < 0 || Seconds > 59) - return -1; - - Julian = Day - 1; - for (i = 0; i < Month; i++) - Julian += DaysInMonth[i]; - for (i = EPOCH; i < Year; i++) - Julian += 365 + (i % 4 == 0); - Julian *= DAY; - Julian += Timezone; - Julian += Hours * HOUR + Minutes * MINUTE + Seconds; -#if defined(HAVE_LOCALTIME_S) - ltime = localtime_s(&tmbuf, &Julian) ? NULL : &tmbuf; -#elif defined(HAVE_LOCALTIME_R) - ltime = localtime_r(&Julian, &tmbuf); -#else - ltime = localtime(&Julian); -#endif - if (DSTmode == DSTon - || (DSTmode == DSTmaybe && ltime->tm_isdst)) - Julian -= HOUR; - return Julian; -} - -static time_t -DSTcorrect(time_t Start, time_t Future) -{ - time_t StartDay; - time_t FutureDay; - struct tm *ltime; -#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S) - struct tm tmbuf; -#endif -#if defined(HAVE_LOCALTIME_S) - ltime = localtime_s(&tmbuf, &Start) ? NULL : &tmbuf; -#elif defined(HAVE_LOCALTIME_R) - ltime = localtime_r(&Start, &tmbuf); -#else - ltime = localtime(&Start); -#endif - StartDay = (ltime->tm_hour + 1) % 24; -#if defined(HAVE_LOCALTIME_S) - ltime = localtime_s(&tmbuf, &Future) ? NULL : &tmbuf; -#elif defined(HAVE_LOCALTIME_R) - ltime = localtime_r(&Future, &tmbuf); -#else - ltime = localtime(&Future); -#endif - FutureDay = (ltime->tm_hour + 1) % 24; - return (Future - Start) + (StartDay - FutureDay) * HOUR; -} - - -static time_t -RelativeDate(time_t Start, time_t zone, int dstmode, - time_t DayOrdinal, time_t DayNumber) -{ - struct tm *tm; - time_t t, now; -#if defined(HAVE_GMTIME_R) || defined(HAVE_GMTIME_S) - struct tm tmbuf; -#endif - - t = Start - zone; -#if defined(HAVE_GMTIME_S) - tm = gmtime_s(&tmbuf, &t) ? NULL : &tmbuf; -#elif defined(HAVE_GMTIME_R) - tm = gmtime_r(&t, &tmbuf); -#else - tm = gmtime(&t); -#endif - now = Start; - now += DAY * ((DayNumber - tm->tm_wday + 7) % 7); - now += 7 * DAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1); - if (dstmode == DSTmaybe) - return DSTcorrect(Start, now); - return now - Start; -} - - -static time_t -RelativeMonth(time_t Start, time_t Timezone, time_t RelMonth) -{ - struct tm *tm; - time_t Month; - time_t Year; -#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S) - struct tm tmbuf; -#endif - - if (RelMonth == 0) - return 0; -#if defined(HAVE_LOCALTIME_S) - tm = localtime_s(&tmbuf, &Start) ? NULL : &tmbuf; -#elif defined(HAVE_LOCALTIME_R) - tm = localtime_r(&Start, &tmbuf); -#else - tm = localtime(&Start); -#endif - Month = 12 * (tm->tm_year + 1900) + tm->tm_mon + RelMonth; - Year = Month / 12; - Month = Month % 12 + 1; - return DSTcorrect(Start, - Convert(Month, (time_t)tm->tm_mday, Year, - (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec, - Timezone, DSTmaybe)); -} - -/* - * Tokenizer. - */ -static int -nexttoken(const char **in, time_t *value) -{ - char c; - char buff[64]; - - for ( ; ; ) { - while (isspace((unsigned char)**in)) - ++*in; - - /* Skip parenthesized comments. */ - if (**in == '(') { - int Count = 0; - do { - c = *(*in)++; - if (c == '\0') - return c; - if (c == '(') - Count++; - else if (c == ')') - Count--; - } while (Count > 0); - continue; - } - - /* Try the next token in the word table first. */ - /* This allows us to match "2nd", for example. */ - { - const char *src = *in; - const struct LEXICON *tp; - unsigned i = 0; - - /* Force to lowercase and strip '.' characters. */ - while (*src != '\0' - && (isalnum((unsigned char)*src) || *src == '.') - && i < sizeof(buff)-1) { - if (*src != '.') { - if (isupper((unsigned char)*src)) - buff[i++] = tolower((unsigned char)*src); - else - buff[i++] = *src; - } - src++; - } - buff[i] = '\0'; - - /* - * Find the first match. If the word can be - * abbreviated, make sure we match at least - * the minimum abbreviation. - */ - for (tp = TimeWords; tp->name; tp++) { - size_t abbrev = tp->abbrev; - if (abbrev == 0) - abbrev = strlen(tp->name); - if (strlen(buff) >= abbrev - && strncmp(tp->name, buff, strlen(buff)) - == 0) { - /* Skip over token. */ - *in = src; - /* Return the match. */ - *value = tp->value; - return tp->type; - } - } - } - - /* - * Not in the word table, maybe it's a number. Note: - * Because '-' and '+' have other special meanings, I - * don't deal with signed numbers here. - */ - if (isdigit((unsigned char)(c = **in))) { - for (*value = 0; isdigit((unsigned char)(c = *(*in)++)); ) - *value = 10 * *value + c - '0'; - (*in)--; - return (tUNUMBER); - } - - return *(*in)++; - } -} - -#define TM_YEAR_ORIGIN 1900 - -/* Yield A - B, measured in seconds. */ -static long -difftm (struct tm *a, struct tm *b) -{ - int ay = a->tm_year + (TM_YEAR_ORIGIN - 1); - int by = b->tm_year + (TM_YEAR_ORIGIN - 1); - int days = ( - /* difference in day of year */ - a->tm_yday - b->tm_yday - /* + intervening leap days */ - + ((ay >> 2) - (by >> 2)) - - (ay/100 - by/100) - + ((ay/100 >> 2) - (by/100 >> 2)) - /* + difference in years * 365 */ - + (long)(ay-by) * 365 - ); - return (days * DAY + (a->tm_hour - b->tm_hour) * HOUR - + (a->tm_min - b->tm_min) * MINUTE - + (a->tm_sec - b->tm_sec)); -} - -/* - * - * The public function. - * - * TODO: tokens[] array should be dynamically sized. - */ -time_t -__archive_get_date(time_t now, const char *p) -{ - struct token tokens[256]; - struct gdstate _gds; - struct token *lasttoken; - struct gdstate *gds; - struct tm local, *tm; - struct tm gmt, *gmt_ptr; - time_t Start; - time_t tod; - long tzone; - - /* Clear out the parsed token array. */ - memset(tokens, 0, sizeof(tokens)); - /* Initialize the parser state. */ - memset(&_gds, 0, sizeof(_gds)); - gds = &_gds; - - /* Look up the current time. */ -#if defined(HAVE_LOCALTIME_S) - tm = localtime_s(&local, &now) ? NULL : &local; -#elif defined(HAVE_LOCALTIME_R) - tm = localtime_r(&now, &local); -#else - memset(&local, 0, sizeof(local)); - tm = localtime(&now); -#endif - if (tm == NULL) - return -1; -#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S) - local = *tm; -#endif - - /* Look up UTC if we can and use that to determine the current - * timezone offset. */ -#if defined(HAVE_GMTIME_S) - gmt_ptr = gmtime_s(&gmt, &now) ? NULL : &gmt; -#elif defined(HAVE_GMTIME_R) - gmt_ptr = gmtime_r(&now, &gmt); -#else - memset(&gmt, 0, sizeof(gmt)); - gmt_ptr = gmtime(&now); - if (gmt_ptr != NULL) { - /* Copy, in case localtime and gmtime use the same buffer. */ - gmt = *gmt_ptr; - } -#endif - if (gmt_ptr != NULL) - tzone = difftm (&gmt, &local); - else - /* This system doesn't understand timezones; fake it. */ - tzone = 0; - if(local.tm_isdst) - tzone += HOUR; - - /* Tokenize the input string. */ - lasttoken = tokens; - while ((lasttoken->token = nexttoken(&p, &lasttoken->value)) != 0) { - ++lasttoken; - if (lasttoken > tokens + 255) - return -1; - } - gds->tokenp = tokens; - - /* Match phrases until we run out of input tokens. */ - while (gds->tokenp < lasttoken) { - if (!phrase(gds)) - return -1; - } - - /* Use current local timezone if none was specified. */ - if (!gds->HaveZone) { - gds->Timezone = tzone; - gds->DSTmode = DSTmaybe; - } - - /* If a timezone was specified, use that for generating the default - * time components instead of the local timezone. */ - if (gds->HaveZone && gmt_ptr != NULL) { - now -= gds->Timezone; -#if defined(HAVE_GMTIME_S) - gmt_ptr = gmtime_s(&gmt, &now) ? NULL : &gmt; -#elif defined(HAVE_GMTIME_R) - gmt_ptr = gmtime_r(&now, &gmt); -#else - gmt_ptr = gmtime(&now); -#endif - if (gmt_ptr != NULL) - local = *gmt_ptr; - now += gds->Timezone; - } - - if (!gds->HaveYear) - gds->Year = local.tm_year + 1900; - if (!gds->HaveMonth) - gds->Month = local.tm_mon + 1; - if (!gds->HaveDay) - gds->Day = local.tm_mday; - /* Note: No default for hour/min/sec; a specifier that just - * gives date always refers to 00:00 on that date. */ - - /* If we saw more than one time, timezone, weekday, year, month, - * or day, then give up. */ - if (gds->HaveTime > 1 || gds->HaveZone > 1 || gds->HaveWeekDay > 1 - || gds->HaveYear > 1 || gds->HaveMonth > 1 || gds->HaveDay > 1) - return -1; - - /* Compute an absolute time based on whatever absolute information - * we collected. */ - if (gds->HaveYear || gds->HaveMonth || gds->HaveDay - || gds->HaveTime || gds->HaveWeekDay) { - Start = Convert(gds->Month, gds->Day, gds->Year, - gds->Hour, gds->Minutes, gds->Seconds, - gds->Timezone, gds->DSTmode); - if (Start < 0) - return -1; - } else { - Start = now; - if (!gds->HaveRel) - Start -= local.tm_hour * HOUR + local.tm_min * MINUTE - + local.tm_sec; - } - - /* Add the relative offset. */ - Start += gds->RelSeconds; - Start += RelativeMonth(Start, gds->Timezone, gds->RelMonth); - - /* Adjust for day-of-week offsets. */ - if (gds->HaveWeekDay - && !(gds->HaveYear || gds->HaveMonth || gds->HaveDay)) { - tod = RelativeDate(Start, gds->Timezone, - gds->DSTmode, gds->DayOrdinal, gds->DayNumber); - Start += tod; - } - - /* -1 is an error indicator, so return 0 instead of -1 if - * that's the actual time. */ - return Start == -1 ? 0 : Start; -} - - -#if defined(TEST) - -/* ARGSUSED */ -int -main(int argc, char **argv) -{ - time_t d; - time_t now = time(NULL); - - while (*++argv != NULL) { - (void)printf("Input: %s\n", *argv); - d = get_date(now, *argv); - if (d == -1) - (void)printf("Bad format - couldn't convert.\n"); - else - (void)printf("Output: %s\n", ctime(&d)); - } - exit(0); - /* NOTREACHED */ -} -#endif /* defined(TEST) */ diff --git a/thirdparty/libarchive/libarchive/archive_getdate.h b/thirdparty/libarchive/libarchive/archive_getdate.h deleted file mode 100644 index 900a8f692..000000000 --- a/thirdparty/libarchive/libarchive/archive_getdate.h +++ /dev/null @@ -1,39 +0,0 @@ -/*- - * Copyright (c) 2003-2015 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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$ - */ - -#ifndef ARCHIVE_GETDATE_H_INCLUDED -#define ARCHIVE_GETDATE_H_INCLUDED - -#ifndef __LIBARCHIVE_BUILD -#error This header is only to be used internally to libarchive. -#endif - -#include - -time_t __archive_get_date(time_t now, const char *); - -#endif diff --git a/thirdparty/libarchive/libarchive/archive_hmac.c b/thirdparty/libarchive/libarchive/archive_hmac.c deleted file mode 100644 index edb3bf5ab..000000000 --- a/thirdparty/libarchive/libarchive/archive_hmac.c +++ /dev/null @@ -1,339 +0,0 @@ -/*- -* Copyright (c) 2014 Michihiro NAKAJIMA -* 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. -* 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. -* -* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. -*/ - -#include "archive_platform.h" - -#ifdef HAVE_STRING_H -#include -#endif -#include "archive.h" -#include "archive_hmac_private.h" - -/* - * On systems that do not support any recognized crypto libraries, - * the archive_hmac.c file is expected to define no usable symbols. - * - * But some compilers and linkers choke on empty object files, so - * define a public symbol that will always exist. This could - * be removed someday if this file gains another always-present - * symbol definition. - */ -int __libarchive_hmac_build_hack(void) { - return 0; -} - - -#ifdef ARCHIVE_HMAC_USE_Apple_CommonCrypto - -static int -__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) -{ - CCHmacInit(ctx, kCCHmacAlgSHA1, key, key_len); - return 0; -} - -static void -__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data, - size_t data_len) -{ - CCHmacUpdate(ctx, data, data_len); -} - -static void -__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len) -{ - CCHmacFinal(ctx, out); - *out_len = 20; -} - -static void -__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx) -{ - memset(ctx, 0, sizeof(*ctx)); -} - -#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) - -#ifndef BCRYPT_HASH_REUSABLE_FLAG -# define BCRYPT_HASH_REUSABLE_FLAG 0x00000020 -#endif - -static int -__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) -{ -#ifdef __GNUC__ -#pragma GCC diagnostic ignored "-Wcast-qual" -#endif - BCRYPT_ALG_HANDLE hAlg; - BCRYPT_HASH_HANDLE hHash; - DWORD hash_len; - PBYTE hash; - ULONG result; - NTSTATUS status; - - ctx->hAlg = NULL; - status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA1_ALGORITHM, - MS_PRIMITIVE_PROVIDER, BCRYPT_ALG_HANDLE_HMAC_FLAG); - if (!BCRYPT_SUCCESS(status)) - return -1; - status = BCryptGetProperty(hAlg, BCRYPT_HASH_LENGTH, (PUCHAR)&hash_len, - sizeof(hash_len), &result, 0); - if (!BCRYPT_SUCCESS(status)) { - BCryptCloseAlgorithmProvider(hAlg, 0); - return -1; - } - hash = (PBYTE)HeapAlloc(GetProcessHeap(), 0, hash_len); - if (hash == NULL) { - BCryptCloseAlgorithmProvider(hAlg, 0); - return -1; - } - status = BCryptCreateHash(hAlg, &hHash, NULL, 0, - (PUCHAR)key, (ULONG)key_len, BCRYPT_HASH_REUSABLE_FLAG); - if (!BCRYPT_SUCCESS(status)) { - BCryptCloseAlgorithmProvider(hAlg, 0); - HeapFree(GetProcessHeap(), 0, hash); - return -1; - } - - ctx->hAlg = hAlg; - ctx->hHash = hHash; - ctx->hash_len = hash_len; - ctx->hash = hash; - - return 0; -} - -static void -__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data, - size_t data_len) -{ - BCryptHashData(ctx->hHash, (PUCHAR)(uintptr_t)data, (ULONG)data_len, 0); -} - -static void -__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len) -{ - BCryptFinishHash(ctx->hHash, ctx->hash, ctx->hash_len, 0); - if (ctx->hash_len == *out_len) - memcpy(out, ctx->hash, *out_len); -} - -static void -__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx) -{ - if (ctx->hAlg != NULL) { - BCryptCloseAlgorithmProvider(ctx->hAlg, 0); - HeapFree(GetProcessHeap(), 0, ctx->hash); - ctx->hAlg = NULL; - } -} - -#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_MD_H) - -static int -__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) -{ - const mbedtls_md_info_t *info; - int ret; - - mbedtls_md_init(ctx); - info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); - if (info == NULL) { - mbedtls_md_free(ctx); - return (-1); - } - ret = mbedtls_md_setup(ctx, info, 1); - if (ret != 0) { - mbedtls_md_free(ctx); - return (-1); - } - ret = mbedtls_md_hmac_starts(ctx, key, key_len); - if (ret != 0) { - mbedtls_md_free(ctx); - return (-1); - } - return 0; -} - -static void -__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data, - size_t data_len) -{ - mbedtls_md_hmac_update(ctx, data, data_len); -} - -static void __hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len) -{ - (void)out_len; /* UNUSED */ - - mbedtls_md_hmac_finish(ctx, out); -} - -static void __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx) -{ - mbedtls_md_free(ctx); - memset(ctx, 0, sizeof(*ctx)); -} - -#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_HMAC_H) - -static int -__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) -{ - hmac_sha1_set_key(ctx, key_len, key); - return 0; -} - -static void -__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data, - size_t data_len) -{ - hmac_sha1_update(ctx, data_len, data); -} - -static void -__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len) -{ - hmac_sha1_digest(ctx, (unsigned)*out_len, out); -} - -static void -__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx) -{ - memset(ctx, 0, sizeof(*ctx)); -} - -#elif defined(HAVE_LIBCRYPTO) - -static int -__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) -{ -#if OPENSSL_VERSION_NUMBER >= 0x30000000L - EVP_MAC *mac; - - char sha1[] = "SHA1"; - OSSL_PARAM params[] = { - OSSL_PARAM_utf8_string("digest", sha1, sizeof(sha1) - 1), - OSSL_PARAM_END - }; - - mac = EVP_MAC_fetch(NULL, "HMAC", NULL); - *ctx = EVP_MAC_CTX_new(mac); - EVP_MAC_free(mac); - if (*ctx == NULL) - return -1; - - EVP_MAC_init(*ctx, key, key_len, params); -#else - *ctx = HMAC_CTX_new(); - if (*ctx == NULL) - return -1; - HMAC_Init_ex(*ctx, key, key_len, EVP_sha1(), NULL); -#endif - return 0; -} - -static void -__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data, - size_t data_len) -{ -#if OPENSSL_VERSION_NUMBER >= 0x30000000L - EVP_MAC_update(*ctx, data, data_len); -#else - HMAC_Update(*ctx, data, data_len); -#endif -} - -static void -__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len) -{ -#if OPENSSL_VERSION_NUMBER >= 0x30000000L - size_t len = *out_len; -#else - unsigned int len = (unsigned int)*out_len; -#endif - -#if OPENSSL_VERSION_NUMBER >= 0x30000000L - EVP_MAC_final(*ctx, out, &len, *out_len); -#else - HMAC_Final(*ctx, out, &len); -#endif - *out_len = len; -} - -static void -__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx) -{ -#if OPENSSL_VERSION_NUMBER >= 0x30000000L - EVP_MAC_CTX_free(*ctx); -#else - HMAC_CTX_free(*ctx); -#endif - *ctx = NULL; -} - -#else - -/* Stub */ -static int -__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len) -{ - (void)ctx;/* UNUSED */ - (void)key;/* UNUSED */ - (void)key_len;/* UNUSED */ - return -1; -} - -static void -__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data, - size_t data_len) -{ - (void)ctx;/* UNUSED */ - (void)data;/* UNUSED */ - (void)data_len;/* UNUSED */ -} - -static void -__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len) -{ - (void)ctx;/* UNUSED */ - (void)out;/* UNUSED */ - (void)out_len;/* UNUSED */ -} - -static void -__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx) -{ - (void)ctx;/* UNUSED */ -} - -#endif - -const struct archive_hmac __archive_hmac = { - &__hmac_sha1_init, - &__hmac_sha1_update, - &__hmac_sha1_final, - &__hmac_sha1_cleanup, -}; diff --git a/thirdparty/libarchive/libarchive/archive_hmac_private.h b/thirdparty/libarchive/libarchive/archive_hmac_private.h deleted file mode 100644 index d0fda7f96..000000000 --- a/thirdparty/libarchive/libarchive/archive_hmac_private.h +++ /dev/null @@ -1,119 +0,0 @@ -/*- -* Copyright (c) 2014 Michihiro NAKAJIMA -* 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. -* 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. -* -* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. -*/ - -#ifndef ARCHIVE_HMAC_PRIVATE_H_INCLUDED -#define ARCHIVE_HMAC_PRIVATE_H_INCLUDED - -#ifndef __LIBARCHIVE_BUILD -#error This header is only to be used internally to libarchive. -#endif -/* - * On systems that do not support any recognized crypto libraries, - * the archive_hmac.c file is expected to define no usable symbols. - * - * But some compilers and linkers choke on empty object files, so - * define a public symbol that will always exist. This could - * be removed someday if this file gains another always-present - * symbol definition. - */ -int __libarchive_hmac_build_hack(void); - -#ifdef __APPLE__ -# include -# if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 -# define ARCHIVE_HMAC_USE_Apple_CommonCrypto -# endif -#endif - -#ifdef ARCHIVE_HMAC_USE_Apple_CommonCrypto -#include - -typedef CCHmacContext archive_hmac_sha1_ctx; - -#elif defined(_WIN32) && !defined(__CYGWIN__) && defined(HAVE_BCRYPT_H) -#include - -typedef struct { - BCRYPT_ALG_HANDLE hAlg; - BCRYPT_HASH_HANDLE hHash; - DWORD hash_len; - PBYTE hash; - -} archive_hmac_sha1_ctx; - -#elif defined(HAVE_LIBMBEDCRYPTO) && defined(HAVE_MBEDTLS_MD_H) -#include - -typedef mbedtls_md_context_t archive_hmac_sha1_ctx; - -#elif defined(HAVE_LIBNETTLE) && defined(HAVE_NETTLE_HMAC_H) -#include - -typedef struct hmac_sha1_ctx archive_hmac_sha1_ctx; - -#elif defined(HAVE_LIBCRYPTO) -#include -#include -#if OPENSSL_VERSION_NUMBER >= 0x30000000L -#include - -typedef EVP_MAC_CTX *archive_hmac_sha1_ctx; - -#else -#include "archive_openssl_hmac_private.h" - -typedef HMAC_CTX* archive_hmac_sha1_ctx; -#endif - -#else - -typedef int archive_hmac_sha1_ctx; - -#endif - - -/* HMAC */ -#define archive_hmac_sha1_init(ctx, key, key_len)\ - __archive_hmac.__hmac_sha1_init(ctx, key, key_len) -#define archive_hmac_sha1_update(ctx, data, data_len)\ - __archive_hmac.__hmac_sha1_update(ctx, data, data_len) -#define archive_hmac_sha1_final(ctx, out, out_len)\ - __archive_hmac.__hmac_sha1_final(ctx, out, out_len) -#define archive_hmac_sha1_cleanup(ctx)\ - __archive_hmac.__hmac_sha1_cleanup(ctx) - - -struct archive_hmac { - /* HMAC */ - int (*__hmac_sha1_init)(archive_hmac_sha1_ctx *, const uint8_t *, - size_t); - void (*__hmac_sha1_update)(archive_hmac_sha1_ctx *, const uint8_t *, - size_t); - void (*__hmac_sha1_final)(archive_hmac_sha1_ctx *, uint8_t *, size_t *); - void (*__hmac_sha1_cleanup)(archive_hmac_sha1_ctx *); -}; - -extern const struct archive_hmac __archive_hmac; -#endif /* ARCHIVE_HMAC_PRIVATE_H_INCLUDED */ diff --git a/thirdparty/libarchive/libarchive/archive_match.c b/thirdparty/libarchive/libarchive/archive_match.c deleted file mode 100644 index 04747b1f6..000000000 --- a/thirdparty/libarchive/libarchive/archive_match.c +++ /dev/null @@ -1,1875 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "archive.h" -#include "archive_private.h" -#include "archive_entry.h" -#include "archive_getdate.h" -#include "archive_pathmatch.h" -#include "archive_rb.h" -#include "archive_string.h" - -struct match { - struct match *next; - int matches; - struct archive_mstring pattern; -}; - -struct match_list { - struct match *first; - struct match **last; - int count; - int unmatched_count; - struct match *unmatched_next; - int unmatched_eof; -}; - -struct match_file { - struct archive_rb_node node; - struct match_file *next; - struct archive_mstring pathname; - int flag; - time_t mtime_sec; - long mtime_nsec; - time_t ctime_sec; - long ctime_nsec; -}; - -struct entry_list { - struct match_file *first; - struct match_file **last; - int count; -}; - -struct id_array { - size_t size;/* Allocated size */ - size_t count; - int64_t *ids; -}; - -#define PATTERN_IS_SET 1 -#define TIME_IS_SET 2 -#define ID_IS_SET 4 - -struct archive_match { - struct archive archive; - - /* exclusion/inclusion set flag. */ - int setflag; - - /* Recursively include directory content? */ - int recursive_include; - - /* - * Matching filename patterns. - */ - struct match_list exclusions; - struct match_list inclusions; - - /* - * Matching time stamps. - */ - time_t now; - int newer_mtime_filter; - time_t newer_mtime_sec; - long newer_mtime_nsec; - int newer_ctime_filter; - time_t newer_ctime_sec; - long newer_ctime_nsec; - int older_mtime_filter; - time_t older_mtime_sec; - long older_mtime_nsec; - int older_ctime_filter; - time_t older_ctime_sec; - long older_ctime_nsec; - /* - * Matching time stamps with its filename. - */ - struct archive_rb_tree exclusion_tree; - struct entry_list exclusion_entry_list; - - /* - * Matching file owners. - */ - struct id_array inclusion_uids; - struct id_array inclusion_gids; - struct match_list inclusion_unames; - struct match_list inclusion_gnames; -}; - -static int add_pattern_from_file(struct archive_match *, - struct match_list *, int, const void *, int); -static int add_entry(struct archive_match *, int, - struct archive_entry *); -static int add_owner_id(struct archive_match *, struct id_array *, - int64_t); -static int add_owner_name(struct archive_match *, struct match_list *, - int, const void *); -static int add_pattern_mbs(struct archive_match *, struct match_list *, - const char *); -static int add_pattern_wcs(struct archive_match *, struct match_list *, - const wchar_t *); -static int cmp_key_mbs(const struct archive_rb_node *, const void *); -static int cmp_key_wcs(const struct archive_rb_node *, const void *); -static int cmp_node_mbs(const struct archive_rb_node *, - const struct archive_rb_node *); -static int cmp_node_wcs(const struct archive_rb_node *, - const struct archive_rb_node *); -static void entry_list_add(struct entry_list *, struct match_file *); -static void entry_list_free(struct entry_list *); -static void entry_list_init(struct entry_list *); -static int error_nomem(struct archive_match *); -static void match_list_add(struct match_list *, struct match *); -static void match_list_free(struct match_list *); -static void match_list_init(struct match_list *); -static int match_list_unmatched_inclusions_next(struct archive_match *, - struct match_list *, int, const void **); -static int match_owner_id(struct id_array *, int64_t); -#if !defined(_WIN32) || defined(__CYGWIN__) -static int match_owner_name_mbs(struct archive_match *, - struct match_list *, const char *); -#else -static int match_owner_name_wcs(struct archive_match *, - struct match_list *, const wchar_t *); -#endif -static int match_path_exclusion(struct archive_match *, - struct match *, int, const void *); -static int match_path_inclusion(struct archive_match *, - struct match *, int, const void *); -static int owner_excluded(struct archive_match *, - struct archive_entry *); -static int path_excluded(struct archive_match *, int, const void *); -static int set_timefilter(struct archive_match *, int, time_t, long, - time_t, long); -static int set_timefilter_pathname_mbs(struct archive_match *, - int, const char *); -static int set_timefilter_pathname_wcs(struct archive_match *, - int, const wchar_t *); -static int set_timefilter_date(struct archive_match *, int, const char *); -static int set_timefilter_date_w(struct archive_match *, int, - const wchar_t *); -static int time_excluded(struct archive_match *, - struct archive_entry *); -static int validate_time_flag(struct archive *, int, const char *); - -#define get_date __archive_get_date - -static const struct archive_rb_tree_ops rb_ops_mbs = { - cmp_node_mbs, cmp_key_mbs -}; - -static const struct archive_rb_tree_ops rb_ops_wcs = { - cmp_node_wcs, cmp_key_wcs -}; - -/* - * The matching logic here needs to be re-thought. I started out to - * try to mimic gtar's matching logic, but it's not entirely - * consistent. In particular 'tar -t' and 'tar -x' interpret patterns - * on the command line as anchored, but --exclude doesn't. - */ - -static int -error_nomem(struct archive_match *a) -{ - archive_set_error(&(a->archive), ENOMEM, "No memory"); - a->archive.state = ARCHIVE_STATE_FATAL; - return (ARCHIVE_FATAL); -} - -/* - * Create an ARCHIVE_MATCH object. - */ -struct archive * -archive_match_new(void) -{ - struct archive_match *a; - - a = (struct archive_match *)calloc(1, sizeof(*a)); - if (a == NULL) - return (NULL); - a->archive.magic = ARCHIVE_MATCH_MAGIC; - a->archive.state = ARCHIVE_STATE_NEW; - a->recursive_include = 1; - match_list_init(&(a->inclusions)); - match_list_init(&(a->exclusions)); - __archive_rb_tree_init(&(a->exclusion_tree), &rb_ops_mbs); - entry_list_init(&(a->exclusion_entry_list)); - match_list_init(&(a->inclusion_unames)); - match_list_init(&(a->inclusion_gnames)); - time(&a->now); - return (&(a->archive)); -} - -/* - * Free an ARCHIVE_MATCH object. - */ -int -archive_match_free(struct archive *_a) -{ - struct archive_match *a; - - if (_a == NULL) - return (ARCHIVE_OK); - archive_check_magic(_a, ARCHIVE_MATCH_MAGIC, - ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_match_free"); - a = (struct archive_match *)_a; - match_list_free(&(a->inclusions)); - match_list_free(&(a->exclusions)); - entry_list_free(&(a->exclusion_entry_list)); - free(a->inclusion_uids.ids); - free(a->inclusion_gids.ids); - match_list_free(&(a->inclusion_unames)); - match_list_free(&(a->inclusion_gnames)); - free(a); - return (ARCHIVE_OK); -} - -/* - * Convenience function to perform all exclusion tests. - * - * Returns 1 if archive entry is excluded. - * Returns 0 if archive entry is not excluded. - * Returns <0 if something error happened. - */ -int -archive_match_excluded(struct archive *_a, struct archive_entry *entry) -{ - struct archive_match *a; - int r; - - archive_check_magic(_a, ARCHIVE_MATCH_MAGIC, - ARCHIVE_STATE_NEW, "archive_match_excluded_ae"); - - a = (struct archive_match *)_a; - if (entry == NULL) { - archive_set_error(&(a->archive), EINVAL, "entry is NULL"); - return (ARCHIVE_FAILED); - } - - r = 0; - if (a->setflag & PATTERN_IS_SET) { -#if defined(_WIN32) && !defined(__CYGWIN__) - r = path_excluded(a, 0, archive_entry_pathname_w(entry)); -#else - r = path_excluded(a, 1, archive_entry_pathname(entry)); -#endif - if (r != 0) - return (r); - } - - if (a->setflag & TIME_IS_SET) { - r = time_excluded(a, entry); - if (r != 0) - return (r); - } - - if (a->setflag & ID_IS_SET) - r = owner_excluded(a, entry); - return (r); -} - -/* - * Utility functions to manage exclusion/inclusion patterns - */ - -int -archive_match_exclude_pattern(struct archive *_a, const char *pattern) -{ - struct archive_match *a; - int r; - - archive_check_magic(_a, ARCHIVE_MATCH_MAGIC, - ARCHIVE_STATE_NEW, "archive_match_exclude_pattern"); - a = (struct archive_match *)_a; - - if (pattern == NULL || *pattern == '\0') { - archive_set_error(&(a->archive), EINVAL, "pattern is empty"); - return (ARCHIVE_FAILED); - } - if ((r = add_pattern_mbs(a, &(a->exclusions), pattern)) != ARCHIVE_OK) - return (r); - return (ARCHIVE_OK); -} - -int -archive_match_exclude_pattern_w(struct archive *_a, const wchar_t *pattern) -{ - struct archive_match *a; - int r; - - archive_check_magic(_a, ARCHIVE_MATCH_MAGIC, - ARCHIVE_STATE_NEW, "archive_match_exclude_pattern_w"); - a = (struct archive_match *)_a; - - if (pattern == NULL || *pattern == L'\0') { - archive_set_error(&(a->archive), EINVAL, "pattern is empty"); - return (ARCHIVE_FAILED); - } - if ((r = add_pattern_wcs(a, &(a->exclusions), pattern)) != ARCHIVE_OK) - return (r); - return (ARCHIVE_OK); -} - -int -archive_match_exclude_pattern_from_file(struct archive *_a, - const char *pathname, int nullSeparator) -{ - struct archive_match *a; - - archive_check_magic(_a, ARCHIVE_MATCH_MAGIC, - ARCHIVE_STATE_NEW, "archive_match_exclude_pattern_from_file"); - a = (struct archive_match *)_a; - - return add_pattern_from_file(a, &(a->exclusions), 1, pathname, - nullSeparator); -} - -int -archive_match_exclude_pattern_from_file_w(struct archive *_a, - const wchar_t *pathname, int nullSeparator) -{ - struct archive_match *a; - - archive_check_magic(_a, ARCHIVE_MATCH_MAGIC, - ARCHIVE_STATE_NEW, "archive_match_exclude_pattern_from_file_w"); - a = (struct archive_match *)_a; - - return add_pattern_from_file(a, &(a->exclusions), 0, pathname, - nullSeparator); -} - -int -archive_match_include_pattern(struct archive *_a, const char *pattern) -{ - struct archive_match *a; - int r; - - archive_check_magic(_a, ARCHIVE_MATCH_MAGIC, - ARCHIVE_STATE_NEW, "archive_match_include_pattern"); - a = (struct archive_match *)_a; - - if (pattern == NULL || *pattern == '\0') { - archive_set_error(&(a->archive), EINVAL, "pattern is empty"); - return (ARCHIVE_FAILED); - } - if ((r = add_pattern_mbs(a, &(a->inclusions), pattern)) != ARCHIVE_OK) - return (r); - return (ARCHIVE_OK); -} - -int -archive_match_include_pattern_w(struct archive *_a, const wchar_t *pattern) -{ - struct archive_match *a; - int r; - - archive_check_magic(_a, ARCHIVE_MATCH_MAGIC, - ARCHIVE_STATE_NEW, "archive_match_include_pattern_w"); - a = (struct archive_match *)_a; - - if (pattern == NULL || *pattern == L'\0') { - archive_set_error(&(a->archive), EINVAL, "pattern is empty"); - return (ARCHIVE_FAILED); - } - if ((r = add_pattern_wcs(a, &(a->inclusions), pattern)) != ARCHIVE_OK) - return (r); - return (ARCHIVE_OK); -} - -int -archive_match_include_pattern_from_file(struct archive *_a, - const char *pathname, int nullSeparator) -{ - struct archive_match *a; - - archive_check_magic(_a, ARCHIVE_MATCH_MAGIC, - ARCHIVE_STATE_NEW, "archive_match_include_pattern_from_file"); - a = (struct archive_match *)_a; - - return add_pattern_from_file(a, &(a->inclusions), 1, pathname, - nullSeparator); -} - -int -archive_match_include_pattern_from_file_w(struct archive *_a, - const wchar_t *pathname, int nullSeparator) -{ - struct archive_match *a; - - archive_check_magic(_a, ARCHIVE_MATCH_MAGIC, - ARCHIVE_STATE_NEW, "archive_match_include_pattern_from_file_w"); - a = (struct archive_match *)_a; - - return add_pattern_from_file(a, &(a->inclusions), 0, pathname, - nullSeparator); -} - -/* - * Test functions for pathname patterns. - * - * Returns 1 if archive entry is excluded. - * Returns 0 if archive entry is not excluded. - * Returns <0 if something error happened. - */ -int -archive_match_path_excluded(struct archive *_a, - struct archive_entry *entry) -{ - struct archive_match *a; - - archive_check_magic(_a, ARCHIVE_MATCH_MAGIC, - ARCHIVE_STATE_NEW, "archive_match_path_excluded"); - - a = (struct archive_match *)_a; - if (entry == NULL) { - archive_set_error(&(a->archive), EINVAL, "entry is NULL"); - return (ARCHIVE_FAILED); - } - - /* If we don't have exclusion/inclusion pattern set at all, - * the entry is always not excluded. */ - if ((a->setflag & PATTERN_IS_SET) == 0) - return (0); -#if defined(_WIN32) && !defined(__CYGWIN__) - return (path_excluded(a, 0, archive_entry_pathname_w(entry))); -#else - return (path_excluded(a, 1, archive_entry_pathname(entry))); -#endif -} - -/* - * When recursive inclusion of directory content is enabled, - * an inclusion pattern that matches a directory will also - * include everything beneath that directory. Enabled by default. - * - * For compatibility with GNU tar, exclusion patterns always - * match if a subset of the full patch matches (i.e., they are - * are not rooted at the beginning of the path) and thus there - * is no corresponding non-recursive exclusion mode. - */ -int -archive_match_set_inclusion_recursion(struct archive *_a, int enabled) -{ - struct archive_match *a; - - archive_check_magic(_a, ARCHIVE_MATCH_MAGIC, - ARCHIVE_STATE_NEW, "archive_match_set_inclusion_recursion"); - a = (struct archive_match *)_a; - a->recursive_include = enabled; - return (ARCHIVE_OK); -} - -/* - * Utility functions to get statistic information for inclusion patterns. - */ -int -archive_match_path_unmatched_inclusions(struct archive *_a) -{ - struct archive_match *a; - - archive_check_magic(_a, ARCHIVE_MATCH_MAGIC, - ARCHIVE_STATE_NEW, "archive_match_unmatched_inclusions"); - a = (struct archive_match *)_a; - - return (a->inclusions.unmatched_count); -} - -int -archive_match_path_unmatched_inclusions_next(struct archive *_a, - const char **_p) -{ - struct archive_match *a; - const void *v; - int r; - - archive_check_magic(_a, ARCHIVE_MATCH_MAGIC, - ARCHIVE_STATE_NEW, "archive_match_unmatched_inclusions_next"); - a = (struct archive_match *)_a; - - r = match_list_unmatched_inclusions_next(a, &(a->inclusions), 1, &v); - *_p = (const char *)v; - return (r); -} - -int -archive_match_path_unmatched_inclusions_next_w(struct archive *_a, - const wchar_t **_p) -{ - struct archive_match *a; - const void *v; - int r; - - archive_check_magic(_a, ARCHIVE_MATCH_MAGIC, - ARCHIVE_STATE_NEW, "archive_match_unmatched_inclusions_next_w"); - a = (struct archive_match *)_a; - - r = match_list_unmatched_inclusions_next(a, &(a->inclusions), 0, &v); - *_p = (const wchar_t *)v; - return (r); -} - -/* - * Add inclusion/exclusion patterns. - */ -static int -add_pattern_mbs(struct archive_match *a, struct match_list *list, - const char *pattern) -{ - struct match *match; - size_t len; - - match = calloc(1, sizeof(*match)); - if (match == NULL) - return (error_nomem(a)); - /* Both "foo/" and "foo" should match "foo/bar". */ - len = strlen(pattern); - if (len && pattern[len - 1] == '/') - --len; - archive_mstring_copy_mbs_len(&(match->pattern), pattern, len); - match_list_add(list, match); - a->setflag |= PATTERN_IS_SET; - return (ARCHIVE_OK); -} - -static int -add_pattern_wcs(struct archive_match *a, struct match_list *list, - const wchar_t *pattern) -{ - struct match *match; - size_t len; - - match = calloc(1, sizeof(*match)); - if (match == NULL) - return (error_nomem(a)); - /* Both "foo/" and "foo" should match "foo/bar". */ - len = wcslen(pattern); - if (len && pattern[len - 1] == L'/') - --len; - archive_mstring_copy_wcs_len(&(match->pattern), pattern, len); - match_list_add(list, match); - a->setflag |= PATTERN_IS_SET; - return (ARCHIVE_OK); -} - -static int -add_pattern_from_file(struct archive_match *a, struct match_list *mlist, - int mbs, const void *pathname, int nullSeparator) -{ - struct archive *ar; - struct archive_entry *ae; - struct archive_string as; - const void *buff; - size_t size; - int64_t offset; - int r; - - ar = archive_read_new(); - if (ar == NULL) { - archive_set_error(&(a->archive), ENOMEM, "No memory"); - return (ARCHIVE_FATAL); - } - r = archive_read_support_format_raw(ar); - r = archive_read_support_format_empty(ar); - if (r != ARCHIVE_OK) { - archive_copy_error(&(a->archive), ar); - archive_read_free(ar); - return (r); - } - if (mbs) - r = archive_read_open_filename(ar, pathname, 512*20); - else - r = archive_read_open_filename_w(ar, pathname, 512*20); - if (r != ARCHIVE_OK) { - archive_copy_error(&(a->archive), ar); - archive_read_free(ar); - return (r); - } - r = archive_read_next_header(ar, &ae); - if (r != ARCHIVE_OK) { - archive_read_free(ar); - if (r == ARCHIVE_EOF) { - return (ARCHIVE_OK); - } else { - archive_copy_error(&(a->archive), ar); - return (r); - } - } - - archive_string_init(&as); - - while ((r = archive_read_data_block(ar, &buff, &size, &offset)) - == ARCHIVE_OK) { - const char *b = (const char *)buff; - - while (size) { - const char *s = (const char *)b; - size_t length = 0; - int found_separator = 0; - - while (length < size) { - if (nullSeparator) { - if (*b == '\0') { - found_separator = 1; - break; - } - } else { - if (*b == 0x0d || *b == 0x0a) { - found_separator = 1; - break; - } - } - b++; - length++; - } - if (!found_separator) { - archive_strncat(&as, s, length); - /* Read next data block. */ - break; - } - b++; - size -= length + 1; - archive_strncat(&as, s, length); - - /* If the line is not empty, add the pattern. */ - if (archive_strlen(&as) > 0) { - /* Add pattern. */ - r = add_pattern_mbs(a, mlist, as.s); - if (r != ARCHIVE_OK) { - archive_read_free(ar); - archive_string_free(&as); - return (r); - } - archive_string_empty(&as); - } - } - } - - /* If an error occurred, report it immediately. */ - if (r < ARCHIVE_OK) { - archive_copy_error(&(a->archive), ar); - archive_read_free(ar); - archive_string_free(&as); - return (r); - } - - /* If the line is not empty, add the pattern. */ - if (r == ARCHIVE_EOF && archive_strlen(&as) > 0) { - /* Add pattern. */ - r = add_pattern_mbs(a, mlist, as.s); - if (r != ARCHIVE_OK) { - archive_read_free(ar); - archive_string_free(&as); - return (r); - } - } - archive_read_free(ar); - archive_string_free(&as); - return (ARCHIVE_OK); -} - -/* - * Test if pathname is excluded by inclusion/exclusion patterns. - */ -static int -path_excluded(struct archive_match *a, int mbs, const void *pathname) -{ - struct match *match; - struct match *matched; - int r; - - if (a == NULL) - return (0); - - /* Mark off any unmatched inclusions. */ - /* In particular, if a filename does appear in the archive and - * is explicitly included and excluded, then we don't report - * it as missing even though we don't extract it. - */ - matched = NULL; - for (match = a->inclusions.first; match != NULL; - match = match->next){ - if (match->matches == 0 && - (r = match_path_inclusion(a, match, mbs, pathname)) != 0) { - if (r < 0) - return (r); - a->inclusions.unmatched_count--; - match->matches++; - matched = match; - } - } - - /* Exclusions take priority */ - for (match = a->exclusions.first; match != NULL; - match = match->next){ - r = match_path_exclusion(a, match, mbs, pathname); - if (r) - return (r); - } - - /* It's not excluded and we found an inclusion above, so it's - * included. */ - if (matched != NULL) - return (0); - - - /* We didn't find an unmatched inclusion, check the remaining ones. */ - for (match = a->inclusions.first; match != NULL; - match = match->next){ - /* We looked at previously-unmatched inclusions already. */ - if (match->matches > 0 && - (r = match_path_inclusion(a, match, mbs, pathname)) != 0) { - if (r < 0) - return (r); - match->matches++; - return (0); - } - } - - /* If there were inclusions, default is to exclude. */ - if (a->inclusions.first != NULL) - return (1); - - /* No explicit inclusions, default is to match. */ - return (0); -} - -/* - * This is a little odd, but it matches the default behavior of - * gtar. In particular, 'a*b' will match 'foo/a1111/222b/bar' - * - */ -static int -match_path_exclusion(struct archive_match *a, struct match *m, - int mbs, const void *pn) -{ - int flag = PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END; - int r; - - if (mbs) { - const char *p; - r = archive_mstring_get_mbs(&(a->archive), &(m->pattern), &p); - if (r == 0) - return (archive_pathmatch(p, (const char *)pn, flag)); - } else { - const wchar_t *p; - r = archive_mstring_get_wcs(&(a->archive), &(m->pattern), &p); - if (r == 0) - return (archive_pathmatch_w(p, (const wchar_t *)pn, - flag)); - } - if (errno == ENOMEM) - return (error_nomem(a)); - return (0); -} - -/* - * Again, mimic gtar: inclusions are always anchored (have to match - * the beginning of the path) even though exclusions are not anchored. - */ -static int -match_path_inclusion(struct archive_match *a, struct match *m, - int mbs, const void *pn) -{ - /* Recursive operation requires only a prefix match. */ - int flag = a->recursive_include ? - PATHMATCH_NO_ANCHOR_END : - 0; - int r; - - if (mbs) { - const char *p; - r = archive_mstring_get_mbs(&(a->archive), &(m->pattern), &p); - if (r == 0) - return (archive_pathmatch(p, (const char *)pn, flag)); - } else { - const wchar_t *p; - r = archive_mstring_get_wcs(&(a->archive), &(m->pattern), &p); - if (r == 0) - return (archive_pathmatch_w(p, (const wchar_t *)pn, - flag)); - } - if (errno == ENOMEM) - return (error_nomem(a)); - return (0); -} - -static void -match_list_init(struct match_list *list) -{ - list->first = NULL; - list->last = &(list->first); - list->count = 0; -} - -static void -match_list_free(struct match_list *list) -{ - struct match *p, *q; - - for (p = list->first; p != NULL; ) { - q = p; - p = p->next; - archive_mstring_clean(&(q->pattern)); - free(q); - } -} - -static void -match_list_add(struct match_list *list, struct match *m) -{ - *list->last = m; - list->last = &(m->next); - list->count++; - list->unmatched_count++; -} - -static int -match_list_unmatched_inclusions_next(struct archive_match *a, - struct match_list *list, int mbs, const void **vp) -{ - struct match *m; - - *vp = NULL; - if (list->unmatched_eof) { - list->unmatched_eof = 0; - return (ARCHIVE_EOF); - } - if (list->unmatched_next == NULL) { - if (list->unmatched_count == 0) - return (ARCHIVE_EOF); - list->unmatched_next = list->first; - } - - for (m = list->unmatched_next; m != NULL; m = m->next) { - int r; - - if (m->matches) - continue; - if (mbs) { - const char *p; - r = archive_mstring_get_mbs(&(a->archive), - &(m->pattern), &p); - if (r < 0 && errno == ENOMEM) - return (error_nomem(a)); - if (p == NULL) - p = ""; - *vp = p; - } else { - const wchar_t *p; - r = archive_mstring_get_wcs(&(a->archive), - &(m->pattern), &p); - if (r < 0 && errno == ENOMEM) - return (error_nomem(a)); - if (p == NULL) - p = L""; - *vp = p; - } - list->unmatched_next = m->next; - if (list->unmatched_next == NULL) - /* To return EOF next time. */ - list->unmatched_eof = 1; - return (ARCHIVE_OK); - } - list->unmatched_next = NULL; - return (ARCHIVE_EOF); -} - -/* - * Utility functions to manage inclusion timestamps. - */ -int -archive_match_include_time(struct archive *_a, int flag, time_t sec, - long nsec) -{ - int r; - - r = validate_time_flag(_a, flag, "archive_match_include_time"); - if (r != ARCHIVE_OK) - return (r); - return set_timefilter((struct archive_match *)_a, flag, - sec, nsec, sec, nsec); -} - -int -archive_match_include_date(struct archive *_a, int flag, - const char *datestr) -{ - int r; - - r = validate_time_flag(_a, flag, "archive_match_include_date"); - if (r != ARCHIVE_OK) - return (r); - return set_timefilter_date((struct archive_match *)_a, flag, datestr); -} - -int -archive_match_include_date_w(struct archive *_a, int flag, - const wchar_t *datestr) -{ - int r; - - r = validate_time_flag(_a, flag, "archive_match_include_date_w"); - if (r != ARCHIVE_OK) - return (r); - - return set_timefilter_date_w((struct archive_match *)_a, flag, datestr); -} - -int -archive_match_include_file_time(struct archive *_a, int flag, - const char *pathname) -{ - int r; - - r = validate_time_flag(_a, flag, "archive_match_include_file_time"); - if (r != ARCHIVE_OK) - return (r); - return set_timefilter_pathname_mbs((struct archive_match *)_a, - flag, pathname); -} - -int -archive_match_include_file_time_w(struct archive *_a, int flag, - const wchar_t *pathname) -{ - int r; - - r = validate_time_flag(_a, flag, "archive_match_include_file_time_w"); - if (r != ARCHIVE_OK) - return (r); - return set_timefilter_pathname_wcs((struct archive_match *)_a, - flag, pathname); -} - -int -archive_match_exclude_entry(struct archive *_a, int flag, - struct archive_entry *entry) -{ - struct archive_match *a; - int r; - - archive_check_magic(_a, ARCHIVE_MATCH_MAGIC, - ARCHIVE_STATE_NEW, "archive_match_time_include_entry"); - a = (struct archive_match *)_a; - - if (entry == NULL) { - archive_set_error(&(a->archive), EINVAL, "entry is NULL"); - return (ARCHIVE_FAILED); - } - r = validate_time_flag(_a, flag, "archive_match_exclude_entry"); - if (r != ARCHIVE_OK) - return (r); - return (add_entry(a, flag, entry)); -} - -/* - * Test function for time stamps. - * - * Returns 1 if archive entry is excluded. - * Returns 0 if archive entry is not excluded. - * Returns <0 if something error happened. - */ -int -archive_match_time_excluded(struct archive *_a, - struct archive_entry *entry) -{ - struct archive_match *a; - - archive_check_magic(_a, ARCHIVE_MATCH_MAGIC, - ARCHIVE_STATE_NEW, "archive_match_time_excluded_ae"); - - a = (struct archive_match *)_a; - if (entry == NULL) { - archive_set_error(&(a->archive), EINVAL, "entry is NULL"); - return (ARCHIVE_FAILED); - } - - /* If we don't have inclusion time set at all, the entry is always - * not excluded. */ - if ((a->setflag & TIME_IS_SET) == 0) - return (0); - return (time_excluded(a, entry)); -} - -static int -validate_time_flag(struct archive *_a, int flag, const char *_fn) -{ - archive_check_magic(_a, ARCHIVE_MATCH_MAGIC, - ARCHIVE_STATE_NEW, _fn); - - /* Check a type of time. */ - if (flag & - ((~(ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME)) & 0xff00)) { - archive_set_error(_a, EINVAL, "Invalid time flag"); - return (ARCHIVE_FAILED); - } - if ((flag & (ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME)) == 0) { - archive_set_error(_a, EINVAL, "No time flag"); - return (ARCHIVE_FAILED); - } - - /* Check a type of comparison. */ - if (flag & - ((~(ARCHIVE_MATCH_NEWER | ARCHIVE_MATCH_OLDER - | ARCHIVE_MATCH_EQUAL)) & 0x00ff)) { - archive_set_error(_a, EINVAL, "Invalid comparison flag"); - return (ARCHIVE_FAILED); - } - if ((flag & (ARCHIVE_MATCH_NEWER | ARCHIVE_MATCH_OLDER - | ARCHIVE_MATCH_EQUAL)) == 0) { - archive_set_error(_a, EINVAL, "No comparison flag"); - return (ARCHIVE_FAILED); - } - - return (ARCHIVE_OK); -} - -#define JUST_EQUAL(t) (((t) & (ARCHIVE_MATCH_EQUAL |\ - ARCHIVE_MATCH_NEWER | ARCHIVE_MATCH_OLDER)) == ARCHIVE_MATCH_EQUAL) -static int -set_timefilter(struct archive_match *a, int timetype, - time_t mtime_sec, long mtime_nsec, time_t ctime_sec, long ctime_nsec) -{ - if (timetype & ARCHIVE_MATCH_MTIME) { - if ((timetype & ARCHIVE_MATCH_NEWER) || JUST_EQUAL(timetype)) { - a->newer_mtime_filter = timetype; - a->newer_mtime_sec = mtime_sec; - a->newer_mtime_nsec = mtime_nsec; - a->setflag |= TIME_IS_SET; - } - if ((timetype & ARCHIVE_MATCH_OLDER) || JUST_EQUAL(timetype)) { - a->older_mtime_filter = timetype; - a->older_mtime_sec = mtime_sec; - a->older_mtime_nsec = mtime_nsec; - a->setflag |= TIME_IS_SET; - } - } - if (timetype & ARCHIVE_MATCH_CTIME) { - if ((timetype & ARCHIVE_MATCH_NEWER) || JUST_EQUAL(timetype)) { - a->newer_ctime_filter = timetype; - a->newer_ctime_sec = ctime_sec; - a->newer_ctime_nsec = ctime_nsec; - a->setflag |= TIME_IS_SET; - } - if ((timetype & ARCHIVE_MATCH_OLDER) || JUST_EQUAL(timetype)) { - a->older_ctime_filter = timetype; - a->older_ctime_sec = ctime_sec; - a->older_ctime_nsec = ctime_nsec; - a->setflag |= TIME_IS_SET; - } - } - return (ARCHIVE_OK); -} - -static int -set_timefilter_date(struct archive_match *a, int timetype, const char *datestr) -{ - time_t t; - - if (datestr == NULL || *datestr == '\0') { - archive_set_error(&(a->archive), EINVAL, "date is empty"); - return (ARCHIVE_FAILED); - } - t = get_date(a->now, datestr); - if (t == (time_t)-1) { - archive_set_error(&(a->archive), EINVAL, "invalid date string"); - return (ARCHIVE_FAILED); - } - return set_timefilter(a, timetype, t, 0, t, 0); -} - -static int -set_timefilter_date_w(struct archive_match *a, int timetype, - const wchar_t *datestr) -{ - struct archive_string as; - time_t t; - - if (datestr == NULL || *datestr == L'\0') { - archive_set_error(&(a->archive), EINVAL, "date is empty"); - return (ARCHIVE_FAILED); - } - - archive_string_init(&as); - if (archive_string_append_from_wcs(&as, datestr, wcslen(datestr)) < 0) { - archive_string_free(&as); - if (errno == ENOMEM) - return (error_nomem(a)); - archive_set_error(&(a->archive), -1, - "Failed to convert WCS to MBS"); - return (ARCHIVE_FAILED); - } - t = get_date(a->now, as.s); - archive_string_free(&as); - if (t == (time_t)-1) { - archive_set_error(&(a->archive), EINVAL, "invalid date string"); - return (ARCHIVE_FAILED); - } - return set_timefilter(a, timetype, t, 0, t, 0); -} - -#if defined(_WIN32) && !defined(__CYGWIN__) -#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000) -static int -set_timefilter_find_data(struct archive_match *a, int timetype, - DWORD ftLastWriteTime_dwHighDateTime, DWORD ftLastWriteTime_dwLowDateTime, - DWORD ftCreationTime_dwHighDateTime, DWORD ftCreationTime_dwLowDateTime) -{ - ULARGE_INTEGER utc; - time_t ctime_sec, mtime_sec; - long ctime_ns, mtime_ns; - - utc.HighPart = ftCreationTime_dwHighDateTime; - utc.LowPart = ftCreationTime_dwLowDateTime; - if (utc.QuadPart >= EPOC_TIME) { - utc.QuadPart -= EPOC_TIME; - ctime_sec = (time_t)(utc.QuadPart / 10000000); - ctime_ns = (long)(utc.QuadPart % 10000000) * 100; - } else { - ctime_sec = 0; - ctime_ns = 0; - } - utc.HighPart = ftLastWriteTime_dwHighDateTime; - utc.LowPart = ftLastWriteTime_dwLowDateTime; - if (utc.QuadPart >= EPOC_TIME) { - utc.QuadPart -= EPOC_TIME; - mtime_sec = (time_t)(utc.QuadPart / 10000000); - mtime_ns = (long)(utc.QuadPart % 10000000) * 100; - } else { - mtime_sec = 0; - mtime_ns = 0; - } - return set_timefilter(a, timetype, - mtime_sec, mtime_ns, ctime_sec, ctime_ns); -} - -static int -set_timefilter_pathname_mbs(struct archive_match *a, int timetype, - const char *path) -{ - /* NOTE: stat() on Windows cannot handle nano seconds. */ - HANDLE h; - WIN32_FIND_DATAA d; - - if (path == NULL || *path == '\0') { - archive_set_error(&(a->archive), EINVAL, "pathname is empty"); - return (ARCHIVE_FAILED); - } - h = FindFirstFileA(path, &d); - if (h == INVALID_HANDLE_VALUE) { - la_dosmaperr(GetLastError()); - archive_set_error(&(a->archive), errno, - "Failed to FindFirstFileA"); - return (ARCHIVE_FAILED); - } - FindClose(h); - return set_timefilter_find_data(a, timetype, - d.ftLastWriteTime.dwHighDateTime, d.ftLastWriteTime.dwLowDateTime, - d.ftCreationTime.dwHighDateTime, d.ftCreationTime.dwLowDateTime); -} - -static int -set_timefilter_pathname_wcs(struct archive_match *a, int timetype, - const wchar_t *path) -{ - HANDLE h; - WIN32_FIND_DATAW d; - - if (path == NULL || *path == L'\0') { - archive_set_error(&(a->archive), EINVAL, "pathname is empty"); - return (ARCHIVE_FAILED); - } - h = FindFirstFileW(path, &d); - if (h == INVALID_HANDLE_VALUE) { - la_dosmaperr(GetLastError()); - archive_set_error(&(a->archive), errno, - "Failed to FindFirstFile"); - return (ARCHIVE_FAILED); - } - FindClose(h); - return set_timefilter_find_data(a, timetype, - d.ftLastWriteTime.dwHighDateTime, d.ftLastWriteTime.dwLowDateTime, - d.ftCreationTime.dwHighDateTime, d.ftCreationTime.dwLowDateTime); -} - -#else /* _WIN32 && !__CYGWIN__ */ - -static int -set_timefilter_stat(struct archive_match *a, int timetype, struct stat *st) -{ - struct archive_entry *ae; - time_t ctime_sec, mtime_sec; - long ctime_ns, mtime_ns; - - ae = archive_entry_new(); - if (ae == NULL) - return (error_nomem(a)); - archive_entry_copy_stat(ae, st); - ctime_sec = archive_entry_ctime(ae); - ctime_ns = archive_entry_ctime_nsec(ae); - mtime_sec = archive_entry_mtime(ae); - mtime_ns = archive_entry_mtime_nsec(ae); - archive_entry_free(ae); - return set_timefilter(a, timetype, mtime_sec, mtime_ns, - ctime_sec, ctime_ns); -} - -static int -set_timefilter_pathname_mbs(struct archive_match *a, int timetype, - const char *path) -{ - struct stat st; - - if (path == NULL || *path == '\0') { - archive_set_error(&(a->archive), EINVAL, "pathname is empty"); - return (ARCHIVE_FAILED); - } - if (la_stat(path, &st) != 0) { - archive_set_error(&(a->archive), errno, "Failed to stat()"); - return (ARCHIVE_FAILED); - } - return (set_timefilter_stat(a, timetype, &st)); -} - -static int -set_timefilter_pathname_wcs(struct archive_match *a, int timetype, - const wchar_t *path) -{ - struct archive_string as; - int r; - - if (path == NULL || *path == L'\0') { - archive_set_error(&(a->archive), EINVAL, "pathname is empty"); - return (ARCHIVE_FAILED); - } - - /* Convert WCS filename to MBS filename. */ - archive_string_init(&as); - if (archive_string_append_from_wcs(&as, path, wcslen(path)) < 0) { - archive_string_free(&as); - if (errno == ENOMEM) - return (error_nomem(a)); - archive_set_error(&(a->archive), -1, - "Failed to convert WCS to MBS"); - return (ARCHIVE_FAILED); - } - - r = set_timefilter_pathname_mbs(a, timetype, as.s); - archive_string_free(&as); - - return (r); -} -#endif /* _WIN32 && !__CYGWIN__ */ - -/* - * Call back functions for archive_rb. - */ -static int -cmp_node_mbs(const struct archive_rb_node *n1, - const struct archive_rb_node *n2) -{ - struct match_file *f1 = (struct match_file *)(uintptr_t)n1; - struct match_file *f2 = (struct match_file *)(uintptr_t)n2; - const char *p1, *p2; - - archive_mstring_get_mbs(NULL, &(f1->pathname), &p1); - archive_mstring_get_mbs(NULL, &(f2->pathname), &p2); - if (p1 == NULL) - return (1); - if (p2 == NULL) - return (-1); - return (strcmp(p1, p2)); -} - -static int -cmp_key_mbs(const struct archive_rb_node *n, const void *key) -{ - struct match_file *f = (struct match_file *)(uintptr_t)n; - const char *p; - - archive_mstring_get_mbs(NULL, &(f->pathname), &p); - if (p == NULL) - return (-1); - return (strcmp(p, (const char *)key)); -} - -static int -cmp_node_wcs(const struct archive_rb_node *n1, - const struct archive_rb_node *n2) -{ - struct match_file *f1 = (struct match_file *)(uintptr_t)n1; - struct match_file *f2 = (struct match_file *)(uintptr_t)n2; - const wchar_t *p1, *p2; - - archive_mstring_get_wcs(NULL, &(f1->pathname), &p1); - archive_mstring_get_wcs(NULL, &(f2->pathname), &p2); - if (p1 == NULL) - return (1); - if (p2 == NULL) - return (-1); - return (wcscmp(p1, p2)); -} - -static int -cmp_key_wcs(const struct archive_rb_node *n, const void *key) -{ - struct match_file *f = (struct match_file *)(uintptr_t)n; - const wchar_t *p; - - archive_mstring_get_wcs(NULL, &(f->pathname), &p); - if (p == NULL) - return (-1); - return (wcscmp(p, (const wchar_t *)key)); -} - -static void -entry_list_init(struct entry_list *list) -{ - list->first = NULL; - list->last = &(list->first); - list->count = 0; -} - -static void -entry_list_free(struct entry_list *list) -{ - struct match_file *p, *q; - - for (p = list->first; p != NULL; ) { - q = p; - p = p->next; - archive_mstring_clean(&(q->pathname)); - free(q); - } -} - -static void -entry_list_add(struct entry_list *list, struct match_file *file) -{ - *list->last = file; - list->last = &(file->next); - list->count++; -} - -static int -add_entry(struct archive_match *a, int flag, - struct archive_entry *entry) -{ - struct match_file *f; - const void *pathname; - int r; - - f = calloc(1, sizeof(*f)); - if (f == NULL) - return (error_nomem(a)); - -#if defined(_WIN32) && !defined(__CYGWIN__) - pathname = archive_entry_pathname_w(entry); - if (pathname == NULL) { - free(f); - archive_set_error(&(a->archive), EINVAL, "pathname is NULL"); - return (ARCHIVE_FAILED); - } - archive_mstring_copy_wcs(&(f->pathname), pathname); - a->exclusion_tree.rbt_ops = &rb_ops_wcs; -#else - (void)rb_ops_wcs; - pathname = archive_entry_pathname(entry); - if (pathname == NULL) { - free(f); - archive_set_error(&(a->archive), EINVAL, "pathname is NULL"); - return (ARCHIVE_FAILED); - } - archive_mstring_copy_mbs(&(f->pathname), pathname); - a->exclusion_tree.rbt_ops = &rb_ops_mbs; -#endif - f->flag = flag; - f->mtime_sec = archive_entry_mtime(entry); - f->mtime_nsec = archive_entry_mtime_nsec(entry); - f->ctime_sec = archive_entry_ctime(entry); - f->ctime_nsec = archive_entry_ctime_nsec(entry); - r = __archive_rb_tree_insert_node(&(a->exclusion_tree), &(f->node)); - if (!r) { - struct match_file *f2; - - /* Get the duplicated file. */ - f2 = (struct match_file *)__archive_rb_tree_find_node( - &(a->exclusion_tree), pathname); - - /* - * We always overwrite comparison condition. - * If you do not want to overwrite it, you should not - * call archive_match_exclude_entry(). We cannot know - * what behavior you really expect since overwriting - * condition might be different with the flag. - */ - if (f2 != NULL) { - f2->flag = f->flag; - f2->mtime_sec = f->mtime_sec; - f2->mtime_nsec = f->mtime_nsec; - f2->ctime_sec = f->ctime_sec; - f2->ctime_nsec = f->ctime_nsec; - } - /* Release the duplicated file. */ - archive_mstring_clean(&(f->pathname)); - free(f); - return (ARCHIVE_OK); - } - entry_list_add(&(a->exclusion_entry_list), f); - a->setflag |= TIME_IS_SET; - return (ARCHIVE_OK); -} - -/* - * Test if entry is excluded by its timestamp. - */ -static int -time_excluded(struct archive_match *a, struct archive_entry *entry) -{ - struct match_file *f; - const void *pathname; - time_t sec; - long nsec; - - /* - * If this file/dir is excluded by a time comparison, skip it. - */ - if (a->newer_ctime_filter) { - /* If ctime is not set, use mtime instead. */ - if (archive_entry_ctime_is_set(entry)) - sec = archive_entry_ctime(entry); - else - sec = archive_entry_mtime(entry); - if (sec < a->newer_ctime_sec) - return (1); /* Too old, skip it. */ - if (sec == a->newer_ctime_sec) { - if (archive_entry_ctime_is_set(entry)) - nsec = archive_entry_ctime_nsec(entry); - else - nsec = archive_entry_mtime_nsec(entry); - if (nsec < a->newer_ctime_nsec) - return (1); /* Too old, skip it. */ - if (nsec == a->newer_ctime_nsec && - (a->newer_ctime_filter & ARCHIVE_MATCH_EQUAL) - == 0) - return (1); /* Equal, skip it. */ - } - } - if (a->older_ctime_filter) { - /* If ctime is not set, use mtime instead. */ - if (archive_entry_ctime_is_set(entry)) - sec = archive_entry_ctime(entry); - else - sec = archive_entry_mtime(entry); - if (sec > a->older_ctime_sec) - return (1); /* Too new, skip it. */ - if (sec == a->older_ctime_sec) { - if (archive_entry_ctime_is_set(entry)) - nsec = archive_entry_ctime_nsec(entry); - else - nsec = archive_entry_mtime_nsec(entry); - if (nsec > a->older_ctime_nsec) - return (1); /* Too new, skip it. */ - if (nsec == a->older_ctime_nsec && - (a->older_ctime_filter & ARCHIVE_MATCH_EQUAL) - == 0) - return (1); /* Equal, skip it. */ - } - } - if (a->newer_mtime_filter) { - sec = archive_entry_mtime(entry); - if (sec < a->newer_mtime_sec) - return (1); /* Too old, skip it. */ - if (sec == a->newer_mtime_sec) { - nsec = archive_entry_mtime_nsec(entry); - if (nsec < a->newer_mtime_nsec) - return (1); /* Too old, skip it. */ - if (nsec == a->newer_mtime_nsec && - (a->newer_mtime_filter & ARCHIVE_MATCH_EQUAL) - == 0) - return (1); /* Equal, skip it. */ - } - } - if (a->older_mtime_filter) { - sec = archive_entry_mtime(entry); - if (sec > a->older_mtime_sec) - return (1); /* Too new, skip it. */ - nsec = archive_entry_mtime_nsec(entry); - if (sec == a->older_mtime_sec) { - if (nsec > a->older_mtime_nsec) - return (1); /* Too new, skip it. */ - if (nsec == a->older_mtime_nsec && - (a->older_mtime_filter & ARCHIVE_MATCH_EQUAL) - == 0) - return (1); /* Equal, skip it. */ - } - } - - /* If there is no exclusion list, include the file. */ - if (a->exclusion_entry_list.count == 0) - return (0); - -#if defined(_WIN32) && !defined(__CYGWIN__) - pathname = archive_entry_pathname_w(entry); - a->exclusion_tree.rbt_ops = &rb_ops_wcs; -#else - (void)rb_ops_wcs; - pathname = archive_entry_pathname(entry); - a->exclusion_tree.rbt_ops = &rb_ops_mbs; -#endif - if (pathname == NULL) - return (0); - - f = (struct match_file *)__archive_rb_tree_find_node( - &(a->exclusion_tree), pathname); - /* If the file wasn't rejected, include it. */ - if (f == NULL) - return (0); - - if (f->flag & ARCHIVE_MATCH_CTIME) { - sec = archive_entry_ctime(entry); - if (f->ctime_sec > sec) { - if (f->flag & ARCHIVE_MATCH_OLDER) - return (1); - } else if (f->ctime_sec < sec) { - if (f->flag & ARCHIVE_MATCH_NEWER) - return (1); - } else { - nsec = archive_entry_ctime_nsec(entry); - if (f->ctime_nsec > nsec) { - if (f->flag & ARCHIVE_MATCH_OLDER) - return (1); - } else if (f->ctime_nsec < nsec) { - if (f->flag & ARCHIVE_MATCH_NEWER) - return (1); - } else if (f->flag & ARCHIVE_MATCH_EQUAL) - return (1); - } - } - if (f->flag & ARCHIVE_MATCH_MTIME) { - sec = archive_entry_mtime(entry); - if (f->mtime_sec > sec) { - if (f->flag & ARCHIVE_MATCH_OLDER) - return (1); - } else if (f->mtime_sec < sec) { - if (f->flag & ARCHIVE_MATCH_NEWER) - return (1); - } else { - nsec = archive_entry_mtime_nsec(entry); - if (f->mtime_nsec > nsec) { - if (f->flag & ARCHIVE_MATCH_OLDER) - return (1); - } else if (f->mtime_nsec < nsec) { - if (f->flag & ARCHIVE_MATCH_NEWER) - return (1); - } else if (f->flag & ARCHIVE_MATCH_EQUAL) - return (1); - } - } - return (0); -} - -/* - * Utility functions to manage inclusion owners - */ - -int -archive_match_include_uid(struct archive *_a, la_int64_t uid) -{ - struct archive_match *a; - - archive_check_magic(_a, ARCHIVE_MATCH_MAGIC, - ARCHIVE_STATE_NEW, "archive_match_include_uid"); - a = (struct archive_match *)_a; - return (add_owner_id(a, &(a->inclusion_uids), uid)); -} - -int -archive_match_include_gid(struct archive *_a, la_int64_t gid) -{ - struct archive_match *a; - - archive_check_magic(_a, ARCHIVE_MATCH_MAGIC, - ARCHIVE_STATE_NEW, "archive_match_include_gid"); - a = (struct archive_match *)_a; - return (add_owner_id(a, &(a->inclusion_gids), gid)); -} - -int -archive_match_include_uname(struct archive *_a, const char *uname) -{ - struct archive_match *a; - - archive_check_magic(_a, ARCHIVE_MATCH_MAGIC, - ARCHIVE_STATE_NEW, "archive_match_include_uname"); - a = (struct archive_match *)_a; - return (add_owner_name(a, &(a->inclusion_unames), 1, uname)); -} - -int -archive_match_include_uname_w(struct archive *_a, const wchar_t *uname) -{ - struct archive_match *a; - - archive_check_magic(_a, ARCHIVE_MATCH_MAGIC, - ARCHIVE_STATE_NEW, "archive_match_include_uname_w"); - a = (struct archive_match *)_a; - return (add_owner_name(a, &(a->inclusion_unames), 0, uname)); -} - -int -archive_match_include_gname(struct archive *_a, const char *gname) -{ - struct archive_match *a; - - archive_check_magic(_a, ARCHIVE_MATCH_MAGIC, - ARCHIVE_STATE_NEW, "archive_match_include_gname"); - a = (struct archive_match *)_a; - return (add_owner_name(a, &(a->inclusion_gnames), 1, gname)); -} - -int -archive_match_include_gname_w(struct archive *_a, const wchar_t *gname) -{ - struct archive_match *a; - - archive_check_magic(_a, ARCHIVE_MATCH_MAGIC, - ARCHIVE_STATE_NEW, "archive_match_include_gname_w"); - a = (struct archive_match *)_a; - return (add_owner_name(a, &(a->inclusion_gnames), 0, gname)); -} - -/* - * Test function for owner(uid, gid, uname, gname). - * - * Returns 1 if archive entry is excluded. - * Returns 0 if archive entry is not excluded. - * Returns <0 if something error happened. - */ -int -archive_match_owner_excluded(struct archive *_a, - struct archive_entry *entry) -{ - struct archive_match *a; - - archive_check_magic(_a, ARCHIVE_MATCH_MAGIC, - ARCHIVE_STATE_NEW, "archive_match_id_excluded_ae"); - - a = (struct archive_match *)_a; - if (entry == NULL) { - archive_set_error(&(a->archive), EINVAL, "entry is NULL"); - return (ARCHIVE_FAILED); - } - - /* If we don't have inclusion id set at all, the entry is always - * not excluded. */ - if ((a->setflag & ID_IS_SET) == 0) - return (0); - return (owner_excluded(a, entry)); -} - -static int -add_owner_id(struct archive_match *a, struct id_array *ids, int64_t id) -{ - unsigned i; - - if (ids->count + 1 >= ids->size) { - void *p; - - if (ids->size == 0) - ids->size = 8; - else - ids->size *= 2; - p = realloc(ids->ids, sizeof(*ids->ids) * ids->size); - if (p == NULL) - return (error_nomem(a)); - ids->ids = (int64_t *)p; - } - - /* Find an insert point. */ - for (i = 0; i < ids->count; i++) { - if (ids->ids[i] >= id) - break; - } - - /* Add owner id. */ - if (i == ids->count) - ids->ids[ids->count++] = id; - else if (ids->ids[i] != id) { - memmove(&(ids->ids[i+1]), &(ids->ids[i]), - (ids->count - i) * sizeof(ids->ids[0])); - ids->ids[i] = id; - ids->count++; - } - a->setflag |= ID_IS_SET; - return (ARCHIVE_OK); -} - -static int -match_owner_id(struct id_array *ids, int64_t id) -{ - unsigned b, m, t; - - t = 0; - b = (unsigned)ids->count; - while (t < b) { - m = (t + b)>>1; - if (ids->ids[m] == id) - return (1); - if (ids->ids[m] < id) - t = m + 1; - else - b = m; - } - return (0); -} - -static int -add_owner_name(struct archive_match *a, struct match_list *list, - int mbs, const void *name) -{ - struct match *match; - - match = calloc(1, sizeof(*match)); - if (match == NULL) - return (error_nomem(a)); - if (mbs) - archive_mstring_copy_mbs(&(match->pattern), name); - else - archive_mstring_copy_wcs(&(match->pattern), name); - match_list_add(list, match); - a->setflag |= ID_IS_SET; - return (ARCHIVE_OK); -} - -#if !defined(_WIN32) || defined(__CYGWIN__) -static int -match_owner_name_mbs(struct archive_match *a, struct match_list *list, - const char *name) -{ - struct match *m; - const char *p; - - if (name == NULL || *name == '\0') - return (0); - for (m = list->first; m; m = m->next) { - if (archive_mstring_get_mbs(&(a->archive), &(m->pattern), &p) - < 0 && errno == ENOMEM) - return (error_nomem(a)); - if (p != NULL && strcmp(p, name) == 0) { - m->matches++; - return (1); - } - } - return (0); -} -#else -static int -match_owner_name_wcs(struct archive_match *a, struct match_list *list, - const wchar_t *name) -{ - struct match *m; - const wchar_t *p; - - if (name == NULL || *name == L'\0') - return (0); - for (m = list->first; m; m = m->next) { - if (archive_mstring_get_wcs(&(a->archive), &(m->pattern), &p) - < 0 && errno == ENOMEM) - return (error_nomem(a)); - if (p != NULL && wcscmp(p, name) == 0) { - m->matches++; - return (1); - } - } - return (0); -} -#endif - -/* - * Test if entry is excluded by uid, gid, uname or gname. - */ -static int -owner_excluded(struct archive_match *a, struct archive_entry *entry) -{ - int r; - - if (a->inclusion_uids.count) { - if (!match_owner_id(&(a->inclusion_uids), - archive_entry_uid(entry))) - return (1); - } - - if (a->inclusion_gids.count) { - if (!match_owner_id(&(a->inclusion_gids), - archive_entry_gid(entry))) - return (1); - } - - if (a->inclusion_unames.count) { -#if defined(_WIN32) && !defined(__CYGWIN__) - r = match_owner_name_wcs(a, &(a->inclusion_unames), - archive_entry_uname_w(entry)); -#else - r = match_owner_name_mbs(a, &(a->inclusion_unames), - archive_entry_uname(entry)); -#endif - if (!r) - return (1); - else if (r < 0) - return (r); - } - - if (a->inclusion_gnames.count) { -#if defined(_WIN32) && !defined(__CYGWIN__) - r = match_owner_name_wcs(a, &(a->inclusion_gnames), - archive_entry_gname_w(entry)); -#else - r = match_owner_name_mbs(a, &(a->inclusion_gnames), - archive_entry_gname(entry)); -#endif - if (!r) - return (1); - else if (r < 0) - return (r); - } - return (0); -} - diff --git a/thirdparty/libarchive/libarchive/archive_openssl_evp_private.h b/thirdparty/libarchive/libarchive/archive_openssl_evp_private.h deleted file mode 100644 index 8ac477280..000000000 --- a/thirdparty/libarchive/libarchive/archive_openssl_evp_private.h +++ /dev/null @@ -1,54 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#ifndef ARCHIVE_OPENSSL_EVP_PRIVATE_H_INCLUDED -#define ARCHIVE_OPENSSL_EVP_PRIVATE_H_INCLUDED - -#ifndef __LIBARCHIVE_BUILD -#error This header is only to be used internally to libarchive. -#endif - -#include -#include - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || \ - (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL) -#include /* malloc, free */ -#include /* memset */ -static inline EVP_MD_CTX *EVP_MD_CTX_new(void) -{ - EVP_MD_CTX *ctx = (EVP_MD_CTX *)calloc(1, sizeof(EVP_MD_CTX)); - return ctx; -} - -static inline void EVP_MD_CTX_free(EVP_MD_CTX *ctx) -{ - EVP_MD_CTX_cleanup(ctx); - memset(ctx, 0, sizeof(*ctx)); - free(ctx); -} -#endif - -#endif diff --git a/thirdparty/libarchive/libarchive/archive_openssl_hmac_private.h b/thirdparty/libarchive/libarchive/archive_openssl_hmac_private.h deleted file mode 100644 index 25c8dda65..000000000 --- a/thirdparty/libarchive/libarchive/archive_openssl_hmac_private.h +++ /dev/null @@ -1,54 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#ifndef ARCHIVE_OPENSSL_HMAC_PRIVATE_H_INCLUDED -#define ARCHIVE_OPENSSL_HMAC_PRIVATE_H_INCLUDED - -#ifndef __LIBARCHIVE_BUILD -#error This header is only to be used internally to libarchive. -#endif - -#include -#include - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || \ - (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L) -#include /* malloc, free */ -#include /* memset */ -static inline HMAC_CTX *HMAC_CTX_new(void) -{ - HMAC_CTX *ctx = (HMAC_CTX *)calloc(1, sizeof(HMAC_CTX)); - return ctx; -} - -static inline void HMAC_CTX_free(HMAC_CTX *ctx) -{ - HMAC_CTX_cleanup(ctx); - memset(ctx, 0, sizeof(*ctx)); - free(ctx); -} -#endif - -#endif diff --git a/thirdparty/libarchive/libarchive/archive_options.c b/thirdparty/libarchive/libarchive/archive_options.c deleted file mode 100644 index 6496025a5..000000000 --- a/thirdparty/libarchive/libarchive/archive_options.c +++ /dev/null @@ -1,218 +0,0 @@ -/*- - * Copyright (c) 2011 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_ERRNO_H -#include -#endif - -#include "archive_options_private.h" - -static const char * -parse_option(const char **str, - const char **mod, const char **opt, const char **val); - -int -_archive_set_option(struct archive *a, - const char *m, const char *o, const char *v, - int magic, const char *fn, option_handler use_option) -{ - const char *mp, *op, *vp; - int r; - - archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn); - - mp = (m != NULL && m[0] != '\0') ? m : NULL; - op = (o != NULL && o[0] != '\0') ? o : NULL; - vp = (v != NULL && v[0] != '\0') ? v : NULL; - - if (op == NULL && vp == NULL) - return (ARCHIVE_OK); - if (op == NULL) { - archive_set_error(a, ARCHIVE_ERRNO_MISC, "Empty option"); - return (ARCHIVE_FAILED); - } - - r = use_option(a, mp, op, vp); - if (r == ARCHIVE_WARN - 1) { - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Unknown module name: `%s'", mp); - return (ARCHIVE_FAILED); - } - if (r == ARCHIVE_WARN) { - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Undefined option: `%s%s%s%s%s%s'", - vp?"":"!", mp?mp:"", mp?":":"", op, vp?"=":"", vp?vp:""); - return (ARCHIVE_FAILED); - } - return (r); -} - -int -_archive_set_either_option(struct archive *a, const char *m, const char *o, const char *v, - option_handler use_format_option, option_handler use_filter_option) -{ - int r1, r2; - - if (o == NULL && v == NULL) - return (ARCHIVE_OK); - if (o == NULL) - return (ARCHIVE_FAILED); - - r1 = use_format_option(a, m, o, v); - if (r1 == ARCHIVE_FATAL) - return (ARCHIVE_FATAL); - - r2 = use_filter_option(a, m, o, v); - if (r2 == ARCHIVE_FATAL) - return (ARCHIVE_FATAL); - - if (r2 == ARCHIVE_WARN - 1) - return r1; - return r1 > r2 ? r1 : r2; -} - -int -_archive_set_options(struct archive *a, const char *options, - int magic, const char *fn, option_handler use_option) -{ - int allok = 1, anyok = 0, ignore_mod_err = 0, r; - char *data; - const char *s, *mod, *opt, *val; - - archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn); - - if (options == NULL || options[0] == '\0') - return ARCHIVE_OK; - - if ((data = strdup(options)) == NULL) { - archive_set_error(a, - ENOMEM, "Out of memory adding file to list"); - return (ARCHIVE_FATAL); - } - s = (const char *)data; - - do { - mod = opt = val = NULL; - - parse_option(&s, &mod, &opt, &val); - if (mod == NULL && opt != NULL && - strcmp("__ignore_wrong_module_name__", opt) == 0) { - /* Ignore module name error */ - if (val != NULL) { - ignore_mod_err = 1; - anyok = 1; - } - continue; - } - - r = use_option(a, mod, opt, val); - if (r == ARCHIVE_FATAL) { - free(data); - return (ARCHIVE_FATAL); - } - if (r == ARCHIVE_FAILED && mod != NULL) { - free(data); - return (ARCHIVE_FAILED); - } - if (r == ARCHIVE_WARN - 1) { - if (ignore_mod_err) - continue; - /* The module name is wrong. */ - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Unknown module name: `%s'", mod); - free(data); - return (ARCHIVE_FAILED); - } - if (r == ARCHIVE_WARN) { - /* The option name is wrong. No-one used this. */ - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Undefined option: `%s%s%s'", - mod?mod:"", mod?":":"", opt); - free(data); - return (ARCHIVE_FAILED); - } - if (r == ARCHIVE_OK) - anyok = 1; - else - allok = 0; - } while (s != NULL); - - free(data); - return allok ? ARCHIVE_OK : anyok ? ARCHIVE_WARN : ARCHIVE_FAILED; -} - -static const char * -parse_option(const char **s, const char **m, const char **o, const char **v) -{ - const char *end, *mod, *opt, *val; - char *p; - - end = NULL; - mod = NULL; - opt = *s; - val = "1"; - - p = strchr(opt, ','); - - if (p != NULL) { - *p = '\0'; - end = ((const char *)p) + 1; - } - - if (0 == strlen(opt)) { - *s = end; - *m = NULL; - *o = NULL; - *v = NULL; - return end; - } - - p = strchr(opt, ':'); - if (p != NULL) { - *p = '\0'; - mod = opt; - opt = ++p; - } - - p = strchr(opt, '='); - if (p != NULL) { - *p = '\0'; - val = ++p; - } else if (opt[0] == '!') { - ++opt; - val = NULL; - } - - *s = end; - *m = mod; - *o = opt; - *v = val; - - return end; -} - diff --git a/thirdparty/libarchive/libarchive/archive_options_private.h b/thirdparty/libarchive/libarchive/archive_options_private.h deleted file mode 100644 index 9a7f8080d..000000000 --- a/thirdparty/libarchive/libarchive/archive_options_private.h +++ /dev/null @@ -1,51 +0,0 @@ -/*- - * Copyright (c) 2011 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#ifndef ARCHIVE_OPTIONS_PRIVATE_H_INCLUDED -#define ARCHIVE_OPTIONS_PRIVATE_H_INCLUDED - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#include "archive_private.h" - -typedef int (*option_handler)(struct archive *a, - const char *mod, const char *opt, const char *val); - -int -_archive_set_option(struct archive *a, - const char *mod, const char *opt, const char *val, - int magic, const char *fn, option_handler use_option); - -int -_archive_set_options(struct archive *a, const char *options, - int magic, const char *fn, option_handler use_option); - -int -_archive_set_either_option(struct archive *a, - const char *m, const char *o, const char *v, - option_handler use_format_option, option_handler use_filter_option); - -#endif diff --git a/thirdparty/libarchive/libarchive/archive_pack_dev.c b/thirdparty/libarchive/libarchive/archive_pack_dev.c deleted file mode 100644 index d95444d97..000000000 --- a/thirdparty/libarchive/libarchive/archive_pack_dev.c +++ /dev/null @@ -1,337 +0,0 @@ -/* $NetBSD: pack_dev.c,v 1.12 2013/06/14 16:28:20 tsutsui Exp $ */ - -/*- - * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Charles M. Hannum. - * - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``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 FOUNDATION OR CONTRIBUTORS - * 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. - */ - -/* Originally from NetBSD's mknod(8) source. */ - -#include "archive_platform.h" - -#if HAVE_SYS_CDEFS_H -#include -#endif -#if !defined(lint) -__RCSID("$NetBSD$"); -#endif /* not lint */ - -#ifdef HAVE_LIMITS_H -#include -#endif - -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_STAT_H -#include -#endif -#if MAJOR_IN_MKDEV -#include -#define HAVE_MAJOR -#elif MAJOR_IN_SYSMACROS -#include -#define HAVE_MAJOR -#endif -#ifdef HAVE_UNISTD_H -#include -#endif - -#include "archive_pack_dev.h" - -static pack_t pack_netbsd; -static pack_t pack_freebsd; -static pack_t pack_8_8; -static pack_t pack_12_20; -static pack_t pack_14_18; -static pack_t pack_8_24; -static pack_t pack_bsdos; -static int __LA_LIBC_CC compare_format(const void *, const void *); - -static const char iMajorError[] = "invalid major number"; -static const char iMinorError[] = "invalid minor number"; -static const char tooManyFields[] = "too many fields for format"; - -/* This is blatantly stolen from libarchive/archive_entry.c, - * in an attempt to get this to play nice on MinGW... */ -#if !defined(HAVE_MAJOR) && !defined(major) -/* Replacement for major/minor/makedev. */ -#define major(x) ((int)(0x00ff & ((x) >> 8))) -#define minor(x) ((int)(0xffff00ff & (x))) -#define makedev(maj,min) ((0xff00 & ((maj)<<8)) | (0xffff00ff & (min))) -#endif - -/* Play games to come up with a suitable makedev() definition. */ -#ifdef __QNXNTO__ -/* QNX. */ -#include -#define apd_makedev(maj, min) makedev(ND_LOCAL_NODE, (maj), (min)) -#elif defined makedev -/* There's a "makedev" macro. */ -#define apd_makedev(maj, min) makedev((maj), (min)) -#elif defined mkdev || ((defined _WIN32 || defined __WIN32__) && !defined(__CYGWIN__)) -/* Windows. */ -#define apd_makedev(maj, min) mkdev((maj), (min)) -#else -/* There's a "makedev" function. */ -#define apd_makedev(maj, min) makedev((maj), (min)) -#endif - -/* exported */ -dev_t -pack_native(int n, unsigned long numbers[], const char **error) -{ - dev_t dev = 0; - - if (n == 2) { - dev = apd_makedev(numbers[0], numbers[1]); - if ((unsigned long)major(dev) != numbers[0]) - *error = iMajorError; - else if ((unsigned long)minor(dev) != numbers[1]) - *error = iMinorError; - } else - *error = tooManyFields; - return (dev); -} - - -static dev_t -pack_netbsd(int n, unsigned long numbers[], const char **error) -{ - dev_t dev = 0; - - if (n == 2) { - dev = makedev_netbsd(numbers[0], numbers[1]); - if ((unsigned long)major_netbsd(dev) != numbers[0]) - *error = iMajorError; - else if ((unsigned long)minor_netbsd(dev) != numbers[1]) - *error = iMinorError; - } else - *error = tooManyFields; - return (dev); -} - - -#define major_freebsd(x) ((int32_t)(((x) & 0x0000ff00) >> 8)) -#define minor_freebsd(x) ((int32_t)(((x) & 0xffff00ff) >> 0)) -#define makedev_freebsd(x,y) ((dev_t)((((x) << 8) & 0x0000ff00) | \ - (((y) << 0) & 0xffff00ff))) - -static dev_t -pack_freebsd(int n, unsigned long numbers[], const char **error) -{ - dev_t dev = 0; - - if (n == 2) { - dev = makedev_freebsd(numbers[0], numbers[1]); - if ((unsigned long)major_freebsd(dev) != numbers[0]) - *error = iMajorError; - if ((unsigned long)minor_freebsd(dev) != numbers[1]) - *error = iMinorError; - } else - *error = tooManyFields; - return (dev); -} - - -#define major_8_8(x) ((int32_t)(((x) & 0x0000ff00) >> 8)) -#define minor_8_8(x) ((int32_t)(((x) & 0x000000ff) >> 0)) -#define makedev_8_8(x,y) ((dev_t)((((x) << 8) & 0x0000ff00) | \ - (((y) << 0) & 0x000000ff))) - -static dev_t -pack_8_8(int n, unsigned long numbers[], const char **error) -{ - dev_t dev = 0; - - if (n == 2) { - dev = makedev_8_8(numbers[0], numbers[1]); - if ((unsigned long)major_8_8(dev) != numbers[0]) - *error = iMajorError; - if ((unsigned long)minor_8_8(dev) != numbers[1]) - *error = iMinorError; - } else - *error = tooManyFields; - return (dev); -} - - -#define major_12_20(x) ((int32_t)(((x) & 0xfff00000) >> 20)) -#define minor_12_20(x) ((int32_t)(((x) & 0x000fffff) >> 0)) -#define makedev_12_20(x,y) ((dev_t)((((x) << 20) & 0xfff00000) | \ - (((y) << 0) & 0x000fffff))) - -static dev_t -pack_12_20(int n, unsigned long numbers[], const char **error) -{ - dev_t dev = 0; - - if (n == 2) { - dev = makedev_12_20(numbers[0], numbers[1]); - if ((unsigned long)major_12_20(dev) != numbers[0]) - *error = iMajorError; - if ((unsigned long)minor_12_20(dev) != numbers[1]) - *error = iMinorError; - } else - *error = tooManyFields; - return (dev); -} - - -#define major_14_18(x) ((int32_t)(((x) & 0xfffc0000) >> 18)) -#define minor_14_18(x) ((int32_t)(((x) & 0x0003ffff) >> 0)) -#define makedev_14_18(x,y) ((dev_t)((((x) << 18) & 0xfffc0000) | \ - (((y) << 0) & 0x0003ffff))) - -static dev_t -pack_14_18(int n, unsigned long numbers[], const char **error) -{ - dev_t dev = 0; - - if (n == 2) { - dev = makedev_14_18(numbers[0], numbers[1]); - if ((unsigned long)major_14_18(dev) != numbers[0]) - *error = iMajorError; - if ((unsigned long)minor_14_18(dev) != numbers[1]) - *error = iMinorError; - } else - *error = tooManyFields; - return (dev); -} - - -#define major_8_24(x) ((int32_t)(((x) & 0xff000000) >> 24)) -#define minor_8_24(x) ((int32_t)(((x) & 0x00ffffff) >> 0)) -#define makedev_8_24(x,y) ((dev_t)((((x) << 24) & 0xff000000) | \ - (((y) << 0) & 0x00ffffff))) - -static dev_t -pack_8_24(int n, unsigned long numbers[], const char **error) -{ - dev_t dev = 0; - - if (n == 2) { - dev = makedev_8_24(numbers[0], numbers[1]); - if ((unsigned long)major_8_24(dev) != numbers[0]) - *error = iMajorError; - if ((unsigned long)minor_8_24(dev) != numbers[1]) - *error = iMinorError; - } else - *error = tooManyFields; - return (dev); -} - - -#define major_12_12_8(x) ((int32_t)(((x) & 0xfff00000) >> 20)) -#define unit_12_12_8(x) ((int32_t)(((x) & 0x000fff00) >> 8)) -#define subunit_12_12_8(x) ((int32_t)(((x) & 0x000000ff) >> 0)) -#define makedev_12_12_8(x,y,z) ((dev_t)((((x) << 20) & 0xfff00000) | \ - (((y) << 8) & 0x000fff00) | \ - (((z) << 0) & 0x000000ff))) - -static dev_t -pack_bsdos(int n, unsigned long numbers[], const char **error) -{ - dev_t dev = 0; - - if (n == 2) { - dev = makedev_12_20(numbers[0], numbers[1]); - if ((unsigned long)major_12_20(dev) != numbers[0]) - *error = iMajorError; - if ((unsigned long)minor_12_20(dev) != numbers[1]) - *error = iMinorError; - } else if (n == 3) { - dev = makedev_12_12_8(numbers[0], numbers[1], numbers[2]); - if ((unsigned long)major_12_12_8(dev) != numbers[0]) - *error = iMajorError; - if ((unsigned long)unit_12_12_8(dev) != numbers[1]) - *error = "invalid unit number"; - if ((unsigned long)subunit_12_12_8(dev) != numbers[2]) - *error = "invalid subunit number"; - } else - *error = tooManyFields; - return (dev); -} - - - /* list of formats and pack functions */ - /* this list must be sorted lexically */ -static const struct format { - const char *name; - pack_t *pack; -} formats[] = { - {"386bsd", pack_8_8}, - {"4bsd", pack_8_8}, - {"bsdos", pack_bsdos}, - {"freebsd", pack_freebsd}, - {"hpux", pack_8_24}, - {"isc", pack_8_8}, - {"linux", pack_8_8}, - {"native", pack_native}, - {"netbsd", pack_netbsd}, - {"osf1", pack_12_20}, - {"sco", pack_8_8}, - {"solaris", pack_14_18}, - {"sunos", pack_8_8}, - {"svr3", pack_8_8}, - {"svr4", pack_14_18}, - {"ultrix", pack_8_8}, -}; - -static int -__LA_LIBC_CC -compare_format(const void *key, const void *element) -{ - const char *name; - const struct format *format; - - name = key; - format = element; - - return (strcmp(name, format->name)); -} - - -pack_t * -pack_find(const char *name) -{ - struct format *format; - - format = bsearch(name, formats, - sizeof(formats)/sizeof(formats[0]), - sizeof(formats[0]), compare_format); - if (format == 0) - return (NULL); - return (format->pack); -} diff --git a/thirdparty/libarchive/libarchive/archive_pack_dev.h b/thirdparty/libarchive/libarchive/archive_pack_dev.h deleted file mode 100644 index eaf23e388..000000000 --- a/thirdparty/libarchive/libarchive/archive_pack_dev.h +++ /dev/null @@ -1,49 +0,0 @@ -/* $NetBSD: pack_dev.h,v 1.8 2013/06/14 16:28:20 tsutsui Exp $ */ - -/*- - * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Charles M. Hannum. - * - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``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 FOUNDATION OR CONTRIBUTORS - * 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. - */ - -/* Originally from NetBSD's mknod(8) source. */ - -#ifndef ARCHIVE_PACK_DEV_H -#define ARCHIVE_PACK_DEV_H - -typedef dev_t pack_t(int, unsigned long [], const char **); - -pack_t *pack_find(const char *); -pack_t pack_native; - -#define major_netbsd(x) ((int32_t)((((x) & 0x000fff00) >> 8))) -#define minor_netbsd(x) ((int32_t)((((x) & 0xfff00000) >> 12) | \ - (((x) & 0x000000ff) >> 0))) -#define makedev_netbsd(x,y) ((dev_t)((((x) << 8) & 0x000fff00) | \ - (((y) << 12) & 0xfff00000) | \ - (((y) << 0) & 0x000000ff))) - -#endif /* ARCHIVE_PACK_DEV_H */ diff --git a/thirdparty/libarchive/libarchive/archive_pathmatch.c b/thirdparty/libarchive/libarchive/archive_pathmatch.c deleted file mode 100644 index 0867a268e..000000000 --- a/thirdparty/libarchive/libarchive/archive_pathmatch.c +++ /dev/null @@ -1,463 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_WCHAR_H -#include -#endif - -#include "archive_pathmatch.h" - -/* - * Check whether a character 'c' is matched by a list specification [...]: - * * Leading '!' or '^' negates the class. - * * - is a range of characters - * * \ removes any special meaning for - * - * Some interesting boundary cases: - * a-d-e is one range (a-d) followed by two single characters - and e. - * \a-\d is same as a-d - * a\-d is three single characters: a, d, - - * Trailing - is not special (so [a-] is two characters a and -). - * Initial - is not special ([a-] is same as [-a] is same as [\\-a]) - * This function never sees a trailing \. - * [] always fails - * [!] always succeeds - */ -static int -pm_list(const char *start, const char *end, const char c, int flags) -{ - const char *p = start; - char rangeStart = '\0', nextRangeStart; - int match = 1, nomatch = 0; - - /* This will be used soon... */ - (void)flags; /* UNUSED */ - - /* If this is a negated class, return success for nomatch. */ - if ((*p == '!' || *p == '^') && p < end) { - match = 0; - nomatch = 1; - ++p; - } - - while (p < end) { - nextRangeStart = '\0'; - switch (*p) { - case '-': - /* Trailing or initial '-' is not special. */ - if ((rangeStart == '\0') || (p == end - 1)) { - if (*p == c) - return (match); - } else { - char rangeEnd = *++p; - if (rangeEnd == '\\') - rangeEnd = *++p; - if ((rangeStart <= c) && (c <= rangeEnd)) - return (match); - } - break; - case '\\': - ++p; - /* Fall through */ - default: - if (*p == c) - return (match); - nextRangeStart = *p; /* Possible start of range. */ - } - rangeStart = nextRangeStart; - ++p; - } - return (nomatch); -} - -static int -pm_list_w(const wchar_t *start, const wchar_t *end, const wchar_t c, int flags) -{ - const wchar_t *p = start; - wchar_t rangeStart = L'\0', nextRangeStart; - int match = 1, nomatch = 0; - - /* This will be used soon... */ - (void)flags; /* UNUSED */ - - /* If this is a negated class, return success for nomatch. */ - if ((*p == L'!' || *p == L'^') && p < end) { - match = 0; - nomatch = 1; - ++p; - } - - while (p < end) { - nextRangeStart = L'\0'; - switch (*p) { - case L'-': - /* Trailing or initial '-' is not special. */ - if ((rangeStart == L'\0') || (p == end - 1)) { - if (*p == c) - return (match); - } else { - wchar_t rangeEnd = *++p; - if (rangeEnd == L'\\') - rangeEnd = *++p; - if ((rangeStart <= c) && (c <= rangeEnd)) - return (match); - } - break; - case L'\\': - ++p; - /* Fall through */ - default: - if (*p == c) - return (match); - nextRangeStart = *p; /* Possible start of range. */ - } - rangeStart = nextRangeStart; - ++p; - } - return (nomatch); -} - -/* - * If s is pointing to "./", ".//", "./././" or the like, skip it. - */ -static const char * -pm_slashskip(const char *s) { - while ((*s == '/') - || (s[0] == '.' && s[1] == '/') - || (s[0] == '.' && s[1] == '\0')) - ++s; - return (s); -} - -static const wchar_t * -pm_slashskip_w(const wchar_t *s) { - while ((*s == L'/') - || (s[0] == L'.' && s[1] == L'/') - || (s[0] == L'.' && s[1] == L'\0')) - ++s; - return (s); -} - -static int -pm(const char *p, const char *s, int flags) -{ - const char *end; - - /* - * Ignore leading './', './/', '././', etc. - */ - if (s[0] == '.' && s[1] == '/') - s = pm_slashskip(s + 1); - if (p[0] == '.' && p[1] == '/') - p = pm_slashskip(p + 1); - - for (;;) { - switch (*p) { - case '\0': - if (s[0] == '/') { - if (flags & PATHMATCH_NO_ANCHOR_END) - return (1); - /* "dir" == "dir/" == "dir/." */ - s = pm_slashskip(s); - } - return (*s == '\0'); - case '?': - /* ? always succeeds, unless we hit end of 's' */ - if (*s == '\0') - return (0); - break; - case '*': - /* "*" == "**" == "***" ... */ - while (*p == '*') - ++p; - /* Trailing '*' always succeeds. */ - if (*p == '\0') - return (1); - while (*s) { - if (archive_pathmatch(p, s, flags)) - return (1); - ++s; - } - return (0); - case '[': - /* - * Find the end of the [...] character class, - * ignoring \] that might occur within the class. - */ - end = p + 1; - while (*end != '\0' && *end != ']') { - if (*end == '\\' && end[1] != '\0') - ++end; - ++end; - } - if (*end == ']') { - /* We found [...], try to match it. */ - if (!pm_list(p + 1, end, *s, flags)) - return (0); - p = end; /* Jump to trailing ']' char. */ - break; - } else - /* No final ']', so just match '['. */ - if (*p != *s) - return (0); - break; - case '\\': - /* Trailing '\\' matches itself. */ - if (p[1] == '\0') { - if (*s != '\\') - return (0); - } else { - ++p; - if (*p != *s) - return (0); - } - break; - case '/': - if (*s != '/' && *s != '\0') - return (0); - /* Note: pattern "/\./" won't match "/"; - * pm_slashskip() correctly stops at backslash. */ - p = pm_slashskip(p); - s = pm_slashskip(s); - if (*p == '\0' && (flags & PATHMATCH_NO_ANCHOR_END)) - return (1); - --p; /* Counteract the increment below. */ - --s; - break; - case '$': - /* '$' is special only at end of pattern and only - * if PATHMATCH_NO_ANCHOR_END is specified. */ - if (p[1] == '\0' && (flags & PATHMATCH_NO_ANCHOR_END)){ - /* "dir" == "dir/" == "dir/." */ - return (*pm_slashskip(s) == '\0'); - } - /* Otherwise, '$' is not special. */ - /* FALL THROUGH */ - default: - if (*p != *s) - return (0); - break; - } - ++p; - ++s; - } -} - -static int -pm_w(const wchar_t *p, const wchar_t *s, int flags) -{ - const wchar_t *end; - - /* - * Ignore leading './', './/', '././', etc. - */ - if (s[0] == L'.' && s[1] == L'/') - s = pm_slashskip_w(s + 1); - if (p[0] == L'.' && p[1] == L'/') - p = pm_slashskip_w(p + 1); - - for (;;) { - switch (*p) { - case L'\0': - if (s[0] == L'/') { - if (flags & PATHMATCH_NO_ANCHOR_END) - return (1); - /* "dir" == "dir/" == "dir/." */ - s = pm_slashskip_w(s); - } - return (*s == L'\0'); - case L'?': - /* ? always succeeds, unless we hit end of 's' */ - if (*s == L'\0') - return (0); - break; - case L'*': - /* "*" == "**" == "***" ... */ - while (*p == L'*') - ++p; - /* Trailing '*' always succeeds. */ - if (*p == L'\0') - return (1); - while (*s) { - if (archive_pathmatch_w(p, s, flags)) - return (1); - ++s; - } - return (0); - case L'[': - /* - * Find the end of the [...] character class, - * ignoring \] that might occur within the class. - */ - end = p + 1; - while (*end != L'\0' && *end != L']') { - if (*end == L'\\' && end[1] != L'\0') - ++end; - ++end; - } - if (*end == L']') { - /* We found [...], try to match it. */ - if (!pm_list_w(p + 1, end, *s, flags)) - return (0); - p = end; /* Jump to trailing ']' char. */ - break; - } else - /* No final ']', so just match '['. */ - if (*p != *s) - return (0); - break; - case L'\\': - /* Trailing '\\' matches itself. */ - if (p[1] == L'\0') { - if (*s != L'\\') - return (0); - } else { - ++p; - if (*p != *s) - return (0); - } - break; - case L'/': - if (*s != L'/' && *s != L'\0') - return (0); - /* Note: pattern "/\./" won't match "/"; - * pm_slashskip() correctly stops at backslash. */ - p = pm_slashskip_w(p); - s = pm_slashskip_w(s); - if (*p == L'\0' && (flags & PATHMATCH_NO_ANCHOR_END)) - return (1); - --p; /* Counteract the increment below. */ - --s; - break; - case L'$': - /* '$' is special only at end of pattern and only - * if PATHMATCH_NO_ANCHOR_END is specified. */ - if (p[1] == L'\0' && (flags & PATHMATCH_NO_ANCHOR_END)){ - /* "dir" == "dir/" == "dir/." */ - return (*pm_slashskip_w(s) == L'\0'); - } - /* Otherwise, '$' is not special. */ - /* FALL THROUGH */ - default: - if (*p != *s) - return (0); - break; - } - ++p; - ++s; - } -} - -/* Main entry point. */ -int -__archive_pathmatch(const char *p, const char *s, int flags) -{ - /* Empty pattern only matches the empty string. */ - if (p == NULL || *p == '\0') - return (s == NULL || *s == '\0'); - else if (s == NULL) - return (0); - - /* Leading '^' anchors the start of the pattern. */ - if (*p == '^') { - ++p; - flags &= ~PATHMATCH_NO_ANCHOR_START; - } - - if (*p == '/' && *s != '/') - return (0); - - /* Certain patterns anchor implicitly. */ - if (*p == '*' || *p == '/') { - while (*p == '/') - ++p; - while (*s == '/') - ++s; - return (pm(p, s, flags)); - } - - /* If start is unanchored, try to match start of each path element. */ - if (flags & PATHMATCH_NO_ANCHOR_START) { - for ( ; s != NULL; s = strchr(s, '/')) { - if (*s == '/') - s++; - if (pm(p, s, flags)) - return (1); - } - return (0); - } - - /* Default: Match from beginning. */ - return (pm(p, s, flags)); -} - -int -__archive_pathmatch_w(const wchar_t *p, const wchar_t *s, int flags) -{ - /* Empty pattern only matches the empty string. */ - if (p == NULL || *p == L'\0') - return (s == NULL || *s == L'\0'); - else if (s == NULL) - return (0); - - /* Leading '^' anchors the start of the pattern. */ - if (*p == L'^') { - ++p; - flags &= ~PATHMATCH_NO_ANCHOR_START; - } - - if (*p == L'/' && *s != L'/') - return (0); - - /* Certain patterns anchor implicitly. */ - if (*p == L'*' || *p == L'/') { - while (*p == L'/') - ++p; - while (*s == L'/') - ++s; - return (pm_w(p, s, flags)); - } - - /* If start is unanchored, try to match start of each path element. */ - if (flags & PATHMATCH_NO_ANCHOR_START) { - for ( ; s != NULL; s = wcschr(s, L'/')) { - if (*s == L'/') - s++; - if (pm_w(p, s, flags)) - return (1); - } - return (0); - } - - /* Default: Match from beginning. */ - return (pm_w(p, s, flags)); -} diff --git a/thirdparty/libarchive/libarchive/archive_pathmatch.h b/thirdparty/libarchive/libarchive/archive_pathmatch.h deleted file mode 100644 index 999514292..000000000 --- a/thirdparty/libarchive/libarchive/archive_pathmatch.h +++ /dev/null @@ -1,52 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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$ - */ - -#ifndef ARCHIVE_PATHMATCH_H -#define ARCHIVE_PATHMATCH_H - -#ifndef __LIBARCHIVE_BUILD -#ifndef __LIBARCHIVE_TEST -#error This header is only to be used internally to libarchive. -#endif -#endif - -/* Don't anchor at beginning unless the pattern starts with "^" */ -#define PATHMATCH_NO_ANCHOR_START 1 -/* Don't anchor at end unless the pattern ends with "$" */ -#define PATHMATCH_NO_ANCHOR_END 2 - -/* Note that "^" and "$" are not special unless you set the corresponding - * flag above. */ - -int __archive_pathmatch(const char *p, const char *s, int flags); -int __archive_pathmatch_w(const wchar_t *p, const wchar_t *s, int flags); - -#define archive_pathmatch(p, s, f) __archive_pathmatch(p, s, f) -#define archive_pathmatch_w(p, s, f) __archive_pathmatch_w(p, s, f) - -#endif diff --git a/thirdparty/libarchive/libarchive/archive_platform.h b/thirdparty/libarchive/libarchive/archive_platform.h deleted file mode 100644 index 1038932ac..000000000 --- a/thirdparty/libarchive/libarchive/archive_platform.h +++ /dev/null @@ -1,233 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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: head/lib/libarchive/archive_platform.h 201090 2009-12-28 02:22:04Z kientzle $ - */ - -/* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */ - -/* - * This header is the first thing included in any of the libarchive - * source files. As far as possible, platform-specific issues should - * be dealt with here and not within individual source files. I'm - * actively trying to minimize #if blocks within the main source, - * since they obfuscate the code. - */ - -#ifndef ARCHIVE_PLATFORM_H_INCLUDED -#define ARCHIVE_PLATFORM_H_INCLUDED - -/* archive.h and archive_entry.h require this. */ -#define __LIBARCHIVE_BUILD 1 - -#if defined(PLATFORM_CONFIG_H) -/* Use hand-built config.h in environments that need it. */ -#include PLATFORM_CONFIG_H -#elif defined(HAVE_CONFIG_H) -/* Most POSIX platforms use the 'configure' script to build config.h */ -#include "config.h" -#else -/* Warn if the library hasn't been (automatically or manually) configured. */ -#error Oops: No config.h and no pre-built configuration in archive_platform.h. -#endif - -/* On macOS check for some symbols based on the deployment target version. */ -#if defined(__APPLE__) -# undef HAVE_FUTIMENS -# undef HAVE_UTIMENSAT -# include -# if MAC_OS_X_VERSION_MIN_REQUIRED >= 101300 -# define HAVE_FUTIMENS 1 -# define HAVE_UTIMENSAT 1 -# endif -#endif - -/* It should be possible to get rid of this by extending the feature-test - * macros to cover Windows API functions, probably along with non-trivial - * refactoring of code to find structures that sit more cleanly on top of - * either Windows or Posix APIs. */ -#if (defined(__WIN32__) || defined(_WIN32) || defined(__WIN32)) && !defined(__CYGWIN__) -#include "archive_windows.h" -/* The C library on Windows specifies a calling convention for callback - * functions and exports; when we interact with them (capture pointers, - * call and pass function pointers) we need to match their calling - * convention. - * This only matters when libarchive is built with /Gr, /Gz or /Gv - * (which change the default calling convention.) */ -#define __LA_LIBC_CC __cdecl -#else -#define la_stat(path,stref) stat(path,stref) -#define __LA_LIBC_CC -#endif - -/* - * The config files define a lot of feature macros. The following - * uses those macros to select/define replacements and include key - * headers as required. - */ - -/* Get a real definition for __FBSDID or __RCSID if we can */ -#if HAVE_SYS_CDEFS_H -#include -#endif - -/* If not, define them so as to avoid dangling semicolons. */ -#ifndef __FBSDID -#define __FBSDID(a) struct _undefined_hack -#endif -#ifndef __RCSID -#define __RCSID(a) struct _undefined_hack -#endif - -/* Try to get standard C99-style integer type definitions. */ -#if HAVE_INTTYPES_H -#include -#endif -#if HAVE_STDINT_H -#include -#endif - -/* Borland warns about its own constants! */ -#if defined(__BORLANDC__) -# if HAVE_DECL_UINT64_MAX -# undef UINT64_MAX -# undef HAVE_DECL_UINT64_MAX -# endif -# if HAVE_DECL_UINT64_MIN -# undef UINT64_MIN -# undef HAVE_DECL_UINT64_MIN -# endif -# if HAVE_DECL_INT64_MAX -# undef INT64_MAX -# undef HAVE_DECL_INT64_MAX -# endif -# if HAVE_DECL_INT64_MIN -# undef INT64_MIN -# undef HAVE_DECL_INT64_MIN -# endif -#endif - -/* Some platforms lack the standard *_MAX definitions. */ -#if !HAVE_DECL_SIZE_MAX -#define SIZE_MAX (~(size_t)0) -#endif -#if !HAVE_DECL_SSIZE_MAX -#define SSIZE_MAX ((ssize_t)(SIZE_MAX >> 1)) -#endif -#if !HAVE_DECL_UINT32_MAX -#define UINT32_MAX (~(uint32_t)0) -#endif -#if !HAVE_DECL_INT32_MAX -#define INT32_MAX ((int32_t)(UINT32_MAX >> 1)) -#endif -#if !HAVE_DECL_INT32_MIN -#define INT32_MIN ((int32_t)(~INT32_MAX)) -#endif -#if !HAVE_DECL_UINT64_MAX -#define UINT64_MAX (~(uint64_t)0) -#endif -#if !HAVE_DECL_INT64_MAX -#define INT64_MAX ((int64_t)(UINT64_MAX >> 1)) -#endif -#if !HAVE_DECL_INT64_MIN -#define INT64_MIN ((int64_t)(~INT64_MAX)) -#endif -#if !HAVE_DECL_UINTMAX_MAX -#define UINTMAX_MAX (~(uintmax_t)0) -#endif -#if !HAVE_DECL_INTMAX_MAX -#define INTMAX_MAX ((intmax_t)(UINTMAX_MAX >> 1)) -#endif -#if !HAVE_DECL_INTMAX_MIN -#define INTMAX_MIN ((intmax_t)(~INTMAX_MAX)) -#endif - -/* Some platforms lack the standard PRIxN/PRIdN definitions. */ -#if !HAVE_INTTYPES_H || !defined(PRIx32) || !defined(PRId32) -#ifndef PRIx32 -#if SIZEOF_INT == 4 -#define PRIx32 "x" -#elif SIZEOF_LONG == 4 -#define PRIx32 "lx" -#else -#error No suitable 32-bit unsigned integer type found for this platform -#endif -#endif // PRIx32 -#ifndef PRId32 -#if SIZEOF_INT == 4 -#define PRId32 "d" -#elif SIZEOF_LONG == 4 -#define PRId32 "ld" -#else -#error No suitable 32-bit signed integer type found for this platform -#endif -#endif // PRId32 -#endif // !HAVE_INTTYPES_H || !defined(PRIx32) || !defined(PRId32) - -/* - * If we can't restore metadata using a file descriptor, then - * for compatibility's sake, close files before trying to restore metadata. - */ -#if defined(HAVE_FCHMOD) || defined(HAVE_FUTIMES) || defined(HAVE_ACL_SET_FD) || defined(HAVE_ACL_SET_FD_NP) || defined(HAVE_FCHOWN) -#define CAN_RESTORE_METADATA_FD -#endif - -/* - * glibc 2.24 deprecates readdir_r - * bionic c deprecates readdir_r too - */ -#if defined(HAVE_READDIR_R) && (!defined(__GLIBC__) || !defined(__GLIBC_MINOR__) || __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 24)) && (!defined(__ANDROID__)) -#define USE_READDIR_R 1 -#else -#undef USE_READDIR_R -#endif - -/* Set up defaults for internal error codes. */ -#ifndef ARCHIVE_ERRNO_FILE_FORMAT -#if HAVE_EFTYPE -#define ARCHIVE_ERRNO_FILE_FORMAT EFTYPE -#else -#if HAVE_EILSEQ -#define ARCHIVE_ERRNO_FILE_FORMAT EILSEQ -#else -#define ARCHIVE_ERRNO_FILE_FORMAT EINVAL -#endif -#endif -#endif - -#ifndef ARCHIVE_ERRNO_PROGRAMMER -#define ARCHIVE_ERRNO_PROGRAMMER EINVAL -#endif - -#ifndef ARCHIVE_ERRNO_MISC -#define ARCHIVE_ERRNO_MISC (-1) -#endif - -#if defined(__GNUC__) && (__GNUC__ >= 7) -#define __LA_FALLTHROUGH __attribute__((fallthrough)) -#else -#define __LA_FALLTHROUGH -#endif - -#endif /* !ARCHIVE_PLATFORM_H_INCLUDED */ diff --git a/thirdparty/libarchive/libarchive/archive_platform_acl.h b/thirdparty/libarchive/libarchive/archive_platform_acl.h deleted file mode 100644 index 264e6de37..000000000 --- a/thirdparty/libarchive/libarchive/archive_platform_acl.h +++ /dev/null @@ -1,55 +0,0 @@ -/*- - * Copyright (c) 2017 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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$ - */ - -/* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */ - -#ifndef ARCHIVE_PLATFORM_ACL_H_INCLUDED -#define ARCHIVE_PLATFORM_ACL_H_INCLUDED - -#ifndef __LIBARCHIVE_BUILD -#ifndef __LIBARCHIVE_TEST_COMMON -#error This header is only to be used internally to libarchive. -#endif -#endif - -/* - * Determine what ACL types are supported - */ -#if ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_SUNOS || ARCHIVE_ACL_LIBACL -#define ARCHIVE_ACL_POSIX1E 1 -#endif - -#if ARCHIVE_ACL_FREEBSD_NFS4 || ARCHIVE_ACL_SUNOS_NFS4 || \ - ARCHIVE_ACL_DARWIN || ARCHIVE_ACL_LIBRICHACL -#define ARCHIVE_ACL_NFS4 1 -#endif - -#if ARCHIVE_ACL_POSIX1E || ARCHIVE_ACL_NFS4 -#define ARCHIVE_ACL_SUPPORT 1 -#endif - -#endif /* ARCHIVE_PLATFORM_ACL_H_INCLUDED */ diff --git a/thirdparty/libarchive/libarchive/archive_platform_xattr.h b/thirdparty/libarchive/libarchive/archive_platform_xattr.h deleted file mode 100644 index ad4b90ab7..000000000 --- a/thirdparty/libarchive/libarchive/archive_platform_xattr.h +++ /dev/null @@ -1,47 +0,0 @@ -/*- - * Copyright (c) 2017 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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$ - */ - -/* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */ - -#ifndef ARCHIVE_PLATFORM_XATTR_H_INCLUDED -#define ARCHIVE_PLATFORM_XATTR_H_INCLUDED - -#ifndef __LIBARCHIVE_BUILD -#ifndef __LIBARCHIVE_TEST_COMMON -#error This header is only to be used internally to libarchive. -#endif -#endif - -/* - * Determine if we support extended attributes - */ -#if ARCHIVE_XATTR_LINUX || ARCHIVE_XATTR_DARWIN || ARCHIVE_XATTR_FREEBSD || \ - ARCHIVE_XATTR_AIX -#define ARCHIVE_XATTR_SUPPORT 1 -#endif - -#endif /* ARCHIVE_PLATFORM_XATTR_H_INCLUDED */ diff --git a/thirdparty/libarchive/libarchive/archive_ppmd7.c b/thirdparty/libarchive/libarchive/archive_ppmd7.c deleted file mode 100644 index cc3f77820..000000000 --- a/thirdparty/libarchive/libarchive/archive_ppmd7.c +++ /dev/null @@ -1,1168 +0,0 @@ -/* Ppmd7.c -- PPMdH codec -2010-03-12 : Igor Pavlov : Public domain -This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ - -#include "archive_platform.h" - -#include - -#include "archive_ppmd7_private.h" - -#ifdef PPMD_32BIT - #define Ppmd7_GetPtr(p, ptr) (ptr) - #define Ppmd7_GetContext(p, ptr) (ptr) - #define Ppmd7_GetStats(p, ctx) ((ctx)->Stats) -#else - #define Ppmd7_GetPtr(p, offs) ((void *)((p)->Base + (offs))) - #define Ppmd7_GetContext(p, offs) ((CPpmd7_Context *)Ppmd7_GetPtr((p), (offs))) - #define Ppmd7_GetStats(p, ctx) ((CPpmd_State *)Ppmd7_GetPtr((p), ((ctx)->Stats))) -#endif - -#define Ppmd7_GetBinSumm(p) \ - &p->BinSumm[Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \ - p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \ - (p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \ - 2 * p->HB2Flag[Ppmd7Context_OneState(p->MinContext)->Symbol] + \ - ((p->RunLength >> 26) & 0x20)] - -#define kTopValue (1 << 24) -#define MAX_FREQ 124 -#define UNIT_SIZE 12 - -#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE) -#define U2I(nu) (p->Units2Indx[(nu) - 1]) -#define I2U(indx) (p->Indx2Units[indx]) - -#ifdef PPMD_32BIT - #define REF(ptr) (ptr) -#else - #define REF(ptr) ((UInt32)((Byte *)(ptr) - (p)->Base)) -#endif - -#define STATS_REF(ptr) ((CPpmd_State_Ref)REF(ptr)) - -#define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref)) -#define STATS(ctx) Ppmd7_GetStats(p, ctx) -#define ONE_STATE(ctx) Ppmd7Context_OneState(ctx) -#define SUFFIX(ctx) CTX((ctx)->Suffix) - -static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051}; -static const Byte PPMD7_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 }; - -typedef CPpmd7_Context * CTX_PTR; - -struct CPpmd7_Node_; - -typedef - #ifdef PPMD_32BIT - struct CPpmd7_Node_ * - #else - UInt32 - #endif - CPpmd7_Node_Ref; - -typedef struct CPpmd7_Node_ -{ - UInt16 Stamp; /* must be at offset 0 as CPpmd7_Context::NumStats. Stamp=0 means free */ - UInt16 NU; - CPpmd7_Node_Ref Next; /* must be at offset >= 4 */ - CPpmd7_Node_Ref Prev; -} CPpmd7_Node; - -#ifdef PPMD_32BIT - #define NODE(ptr) (ptr) -#else - #define NODE(offs) ((CPpmd7_Node *)(p->Base + (offs))) -#endif - -static void Ppmd7_Update1(CPpmd7 *p); -static void Ppmd7_Update1_0(CPpmd7 *p); -static void Ppmd7_Update2(CPpmd7 *p); -static void Ppmd7_UpdateBin(CPpmd7 *p); -static CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, - UInt32 *scale); - -/* ----------- Base ----------- */ - -static void Ppmd7_Construct(CPpmd7 *p) -{ - unsigned i, k, m; - - p->Base = 0; - - for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++) - { - unsigned step = (i >= 12 ? 4 : (i >> 2) + 1); - do { p->Units2Indx[k++] = (Byte)i; } while(--step); - p->Indx2Units[i] = (Byte)k; - } - - p->NS2BSIndx[0] = (0 << 1); - p->NS2BSIndx[1] = (1 << 1); - memset(p->NS2BSIndx + 2, (2 << 1), 9); - memset(p->NS2BSIndx + 11, (3 << 1), 256 - 11); - - for (i = 0; i < 3; i++) - p->NS2Indx[i] = (Byte)i; - for (m = i, k = 1; i < 256; i++) - { - p->NS2Indx[i] = (Byte)m; - if (--k == 0) - k = (++m) - 2; - } - - memset(p->HB2Flag, 0, 0x40); - memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40); -} - -static void Ppmd7_Free(CPpmd7 *p) -{ - free(p->Base); - p->Size = 0; - p->Base = 0; -} - -static Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size) -{ - if (p->Base == 0 || p->Size != size) - { - /* RestartModel() below assumes that p->Size >= UNIT_SIZE - (see the calculation of m->MinContext). */ - if (size < UNIT_SIZE) { - return False; - } - Ppmd7_Free(p); - p->AlignOffset = - #ifdef PPMD_32BIT - (4 - size) & 3; - #else - 4 - (size & 3); - #endif - if ((p->Base = (Byte *)malloc(p->AlignOffset + size - #ifndef PPMD_32BIT - + UNIT_SIZE - #endif - )) == 0) - return False; - p->Size = size; - } - return True; -} - -static void InsertNode(CPpmd7 *p, void *node, unsigned indx) -{ - *((CPpmd_Void_Ref *)node) = p->FreeList[indx]; - p->FreeList[indx] = REF(node); -} - -static void *RemoveNode(CPpmd7 *p, unsigned indx) -{ - CPpmd_Void_Ref *node = (CPpmd_Void_Ref *)Ppmd7_GetPtr(p, p->FreeList[indx]); - p->FreeList[indx] = *node; - return node; -} - -static void SplitBlock(CPpmd7 *p, void *ptr, unsigned oldIndx, unsigned newIndx) -{ - unsigned i, nu = I2U(oldIndx) - I2U(newIndx); - ptr = (Byte *)ptr + U2B(I2U(newIndx)); - if (I2U(i = U2I(nu)) != nu) - { - unsigned k = I2U(--i); - InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1); - } - InsertNode(p, ptr, i); -} - -static void GlueFreeBlocks(CPpmd7 *p) -{ - #ifdef PPMD_32BIT - CPpmd7_Node headItem; - CPpmd7_Node_Ref head = &headItem; - #else - CPpmd7_Node_Ref head = p->AlignOffset + p->Size; - #endif - - CPpmd7_Node_Ref n = head; - unsigned i; - - p->GlueCount = 255; - - /* create doubly-linked list of free blocks */ - for (i = 0; i < PPMD_NUM_INDEXES; i++) - { - UInt16 nu = I2U(i); - CPpmd7_Node_Ref next = (CPpmd7_Node_Ref)p->FreeList[i]; - p->FreeList[i] = 0; - while (next != 0) - { - CPpmd7_Node *node = NODE(next); - node->Next = n; - n = NODE(n)->Prev = next; - next = *(const CPpmd7_Node_Ref *)node; - node->Stamp = 0; - node->NU = (UInt16)nu; - } - } - NODE(head)->Stamp = 1; - NODE(head)->Next = n; - NODE(n)->Prev = head; - if (p->LoUnit != p->HiUnit) - ((CPpmd7_Node *)p->LoUnit)->Stamp = 1; - - /* Glue free blocks */ - while (n != head) - { - CPpmd7_Node *node = NODE(n); - UInt32 nu = (UInt32)node->NU; - for (;;) - { - CPpmd7_Node *node2 = NODE(n) + nu; - nu += node2->NU; - if (node2->Stamp != 0 || nu >= 0x10000) - break; - NODE(node2->Prev)->Next = node2->Next; - NODE(node2->Next)->Prev = node2->Prev; - node->NU = (UInt16)nu; - } - n = node->Next; - } - - /* Fill lists of free blocks */ - for (n = NODE(head)->Next; n != head;) - { - CPpmd7_Node *node = NODE(n); - unsigned nu; - CPpmd7_Node_Ref next = node->Next; - for (nu = node->NU; nu > 128; nu -= 128, node += 128) - InsertNode(p, node, PPMD_NUM_INDEXES - 1); - if (I2U(i = U2I(nu)) != nu) - { - unsigned k = I2U(--i); - InsertNode(p, node + k, nu - k - 1); - } - InsertNode(p, node, i); - n = next; - } -} - -static void *AllocUnitsRare(CPpmd7 *p, unsigned indx) -{ - unsigned i; - void *retVal; - if (p->GlueCount == 0) - { - GlueFreeBlocks(p); - if (p->FreeList[indx] != 0) - return RemoveNode(p, indx); - } - i = indx; - do - { - if (++i == PPMD_NUM_INDEXES) - { - UInt32 numBytes = U2B(I2U(indx)); - p->GlueCount--; - return ((UInt32)(p->UnitsStart - p->Text) > numBytes) ? (p->UnitsStart -= numBytes) : (NULL); - } - } - while (p->FreeList[i] == 0); - retVal = RemoveNode(p, i); - SplitBlock(p, retVal, i, indx); - return retVal; -} - -static void *AllocUnits(CPpmd7 *p, unsigned indx) -{ - UInt32 numBytes; - if (p->FreeList[indx] != 0) - return RemoveNode(p, indx); - numBytes = U2B(I2U(indx)); - if (numBytes <= (UInt32)(p->HiUnit - p->LoUnit)) - { - void *retVal = p->LoUnit; - p->LoUnit += numBytes; - return retVal; - } - return AllocUnitsRare(p, indx); -} - -#define MyMem12Cpy(dest, src, num) \ - { UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \ - do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while(--n); } - -static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU) -{ - unsigned i0 = U2I(oldNU); - unsigned i1 = U2I(newNU); - if (i0 == i1) - return oldPtr; - if (p->FreeList[i1] != 0) - { - void *ptr = RemoveNode(p, i1); - MyMem12Cpy(ptr, oldPtr, newNU); - InsertNode(p, oldPtr, i0); - return ptr; - } - SplitBlock(p, oldPtr, i0, i1); - return oldPtr; -} - -#define SUCCESSOR(p) ((CPpmd_Void_Ref)((p)->SuccessorLow | ((UInt32)(p)->SuccessorHigh << 16))) - -static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v) -{ - (p)->SuccessorLow = (UInt16)((UInt32)(v) & 0xFFFF); - (p)->SuccessorHigh = (UInt16)(((UInt32)(v) >> 16) & 0xFFFF); -} - -static void RestartModel(CPpmd7 *p) -{ - unsigned i, k, m; - - memset(p->FreeList, 0, sizeof(p->FreeList)); - p->Text = p->Base + p->AlignOffset; - p->HiUnit = p->Text + p->Size; - p->LoUnit = p->UnitsStart = p->HiUnit - p->Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE; - p->GlueCount = 0; - - p->OrderFall = p->MaxOrder; - p->RunLength = p->InitRL = -(Int32)((p->MaxOrder < 12) ? p->MaxOrder : 12) - 1; - p->PrevSuccess = 0; - - p->MinContext = p->MaxContext = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */ - p->MinContext->Suffix = 0; - p->MinContext->NumStats = 256; - p->MinContext->SummFreq = 256 + 1; - p->FoundState = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */ - p->LoUnit += U2B(256 / 2); - p->MinContext->Stats = REF(p->FoundState); - for (i = 0; i < 256; i++) - { - CPpmd_State *s = &p->FoundState[i]; - s->Symbol = (Byte)i; - s->Freq = 1; - SetSuccessor(s, 0); - } - - for (i = 0; i < 128; i++) - for (k = 0; k < 8; k++) - { - UInt16 *dest = p->BinSumm[i] + k; - UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 2)); - for (m = 0; m < 64; m += 8) - dest[m] = val; - } - - for (i = 0; i < 25; i++) - for (k = 0; k < 16; k++) - { - CPpmd_See *s = &p->See[i][k]; - s->Summ = (UInt16)((5 * i + 10) << (s->Shift = PPMD_PERIOD_BITS - 4)); - s->Count = 4; - } -} - -static void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder) -{ - p->MaxOrder = maxOrder; - RestartModel(p); - p->DummySee.Shift = PPMD_PERIOD_BITS; - p->DummySee.Summ = 0; /* unused */ - p->DummySee.Count = 64; /* unused */ -} - -static CTX_PTR CreateSuccessors(CPpmd7 *p, Bool skip) -{ - CPpmd_State upState; - CTX_PTR c = p->MinContext; - CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState); - CPpmd_State *ps[PPMD7_MAX_ORDER]; - unsigned numPs = 0; - - if (!skip) - ps[numPs++] = p->FoundState; - - while (c->Suffix) - { - CPpmd_Void_Ref successor; - CPpmd_State *s; - c = SUFFIX(c); - if (c->NumStats != 1) - { - for (s = STATS(c); s->Symbol != p->FoundState->Symbol; s++); - } - else - s = ONE_STATE(c); - successor = SUCCESSOR(s); - if (successor != upBranch) - { - c = CTX(successor); - if (numPs == 0) - return c; - break; - } - ps[numPs++] = s; - } - - upState.Symbol = *(const Byte *)Ppmd7_GetPtr(p, upBranch); - SetSuccessor(&upState, upBranch + 1); - - if (c->NumStats == 1) - upState.Freq = ONE_STATE(c)->Freq; - else - { - UInt32 cf, s0; - CPpmd_State *s; - for (s = STATS(c); s->Symbol != upState.Symbol; s++); - cf = s->Freq - 1; - s0 = c->SummFreq - c->NumStats - cf; - upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((2 * cf + 3 * s0 - 1) / (2 * s0)))); - } - - while (numPs != 0) - { - /* Create Child */ - CTX_PTR c1; /* = AllocContext(p); */ - if (p->HiUnit != p->LoUnit) - c1 = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); - else if (p->FreeList[0] != 0) - c1 = (CTX_PTR)RemoveNode(p, 0); - else - { - c1 = (CTX_PTR)AllocUnitsRare(p, 0); - if (!c1) - return NULL; - } - c1->NumStats = 1; - *ONE_STATE(c1) = upState; - c1->Suffix = REF(c); - SetSuccessor(ps[--numPs], REF(c1)); - c = c1; - } - - return c; -} - -static void SwapStates(CPpmd_State *t1, CPpmd_State *t2) -{ - CPpmd_State tmp = *t1; - *t1 = *t2; - *t2 = tmp; -} - -static void UpdateModel(CPpmd7 *p) -{ - CPpmd_Void_Ref successor, fSuccessor = SUCCESSOR(p->FoundState); - CTX_PTR c; - unsigned s0, ns; - - if (p->FoundState->Freq < MAX_FREQ / 4 && p->MinContext->Suffix != 0) - { - c = SUFFIX(p->MinContext); - - if (c->NumStats == 1) - { - CPpmd_State *s = ONE_STATE(c); - if (s->Freq < 32) - s->Freq++; - } - else - { - CPpmd_State *s = STATS(c); - if (s->Symbol != p->FoundState->Symbol) - { - do { s++; } while (s->Symbol != p->FoundState->Symbol); - if (s[0].Freq >= s[-1].Freq) - { - SwapStates(&s[0], &s[-1]); - s--; - } - } - if (s->Freq < MAX_FREQ - 9) - { - s->Freq += 2; - c->SummFreq += 2; - } - } - } - - if (p->OrderFall == 0) - { - p->MinContext = p->MaxContext = CreateSuccessors(p, True); - if (p->MinContext == 0) - { - RestartModel(p); - return; - } - SetSuccessor(p->FoundState, REF(p->MinContext)); - return; - } - - *p->Text++ = p->FoundState->Symbol; - successor = REF(p->Text); - if (p->Text >= p->UnitsStart) - { - RestartModel(p); - return; - } - - if (fSuccessor) - { - if (fSuccessor <= successor) - { - CTX_PTR cs = CreateSuccessors(p, False); - if (cs == NULL) - { - RestartModel(p); - return; - } - fSuccessor = REF(cs); - } - if (--p->OrderFall == 0) - { - successor = fSuccessor; - p->Text -= (p->MaxContext != p->MinContext); - } - } - else - { - SetSuccessor(p->FoundState, successor); - fSuccessor = REF(p->MinContext); - } - - s0 = p->MinContext->SummFreq - (ns = p->MinContext->NumStats) - (p->FoundState->Freq - 1); - - for (c = p->MaxContext; c != p->MinContext; c = SUFFIX(c)) - { - unsigned ns1; - UInt32 cf, sf; - if ((ns1 = c->NumStats) != 1) - { - if ((ns1 & 1) == 0) - { - /* Expand for one UNIT */ - unsigned oldNU = ns1 >> 1; - unsigned i = U2I(oldNU); - if (i != U2I(oldNU + 1)) - { - void *ptr = AllocUnits(p, i + 1); - void *oldPtr; - if (!ptr) - { - RestartModel(p); - return; - } - oldPtr = STATS(c); - MyMem12Cpy(ptr, oldPtr, oldNU); - InsertNode(p, oldPtr, i); - c->Stats = STATS_REF(ptr); - } - } - c->SummFreq = (UInt16)(c->SummFreq + (2 * ns1 < ns) + 2 * ((4 * ns1 <= ns) & (c->SummFreq <= 8 * ns1))); - } - else - { - CPpmd_State *s = (CPpmd_State*)AllocUnits(p, 0); - if (!s) - { - RestartModel(p); - return; - } - *s = *ONE_STATE(c); - c->Stats = REF(s); - if (s->Freq < MAX_FREQ / 4 - 1) - s->Freq <<= 1; - else - s->Freq = MAX_FREQ - 4; - c->SummFreq = (UInt16)(s->Freq + p->InitEsc + (ns > 3)); - } - cf = 2 * (UInt32)p->FoundState->Freq * (c->SummFreq + 6); - sf = (UInt32)s0 + c->SummFreq; - if (cf < 6 * sf) - { - cf = 1 + (cf > sf) + (cf >= 4 * sf); - c->SummFreq += 3; - } - else - { - cf = 4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf); - c->SummFreq = (UInt16)(c->SummFreq + cf); - } - { - CPpmd_State *s = STATS(c) + ns1; - SetSuccessor(s, successor); - s->Symbol = p->FoundState->Symbol; - s->Freq = (Byte)cf; - c->NumStats = (UInt16)(ns1 + 1); - } - } - p->MaxContext = p->MinContext = CTX(fSuccessor); -} - -static void Rescale(CPpmd7 *p) -{ - unsigned i, adder, sumFreq, escFreq; - CPpmd_State *stats = STATS(p->MinContext); - CPpmd_State *s = p->FoundState; - { - CPpmd_State tmp = *s; - for (; s != stats; s--) - s[0] = s[-1]; - *s = tmp; - } - escFreq = p->MinContext->SummFreq - s->Freq; - s->Freq += 4; - adder = (p->OrderFall != 0); - s->Freq = (Byte)((s->Freq + adder) >> 1); - sumFreq = s->Freq; - - i = p->MinContext->NumStats - 1; - do - { - escFreq -= (++s)->Freq; - s->Freq = (Byte)((s->Freq + adder) >> 1); - sumFreq += s->Freq; - if (s[0].Freq > s[-1].Freq) - { - CPpmd_State *s1 = s; - CPpmd_State tmp = *s1; - do - s1[0] = s1[-1]; - while (--s1 != stats && tmp.Freq > s1[-1].Freq); - *s1 = tmp; - } - } - while (--i); - - if (s->Freq == 0) - { - unsigned numStats = p->MinContext->NumStats; - unsigned n0, n1; - do { i++; } while ((--s)->Freq == 0); - escFreq += i; - p->MinContext->NumStats = (UInt16)(p->MinContext->NumStats - i); - if (p->MinContext->NumStats == 1) - { - CPpmd_State tmp = *stats; - do - { - tmp.Freq = (Byte)(tmp.Freq - (tmp.Freq >> 1)); - escFreq >>= 1; - } - while (escFreq > 1); - InsertNode(p, stats, U2I(((numStats + 1) >> 1))); - *(p->FoundState = ONE_STATE(p->MinContext)) = tmp; - return; - } - n0 = (numStats + 1) >> 1; - n1 = (p->MinContext->NumStats + 1) >> 1; - if (n0 != n1) - p->MinContext->Stats = STATS_REF(ShrinkUnits(p, stats, n0, n1)); - } - p->MinContext->SummFreq = (UInt16)(sumFreq + escFreq - (escFreq >> 1)); - p->FoundState = STATS(p->MinContext); -} - -static CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq) -{ - CPpmd_See *see; - unsigned nonMasked = p->MinContext->NumStats - numMasked; - if (p->MinContext->NumStats != 256) - { - see = p->See[p->NS2Indx[nonMasked - 1]] + - (nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) + - 2 * (p->MinContext->SummFreq < 11 * p->MinContext->NumStats) + - 4 * (numMasked > nonMasked) + - p->HiBitsFlag; - { - unsigned r = (see->Summ >> see->Shift); - see->Summ = (UInt16)(see->Summ - r); - *escFreq = r + (r == 0); - } - } - else - { - see = &p->DummySee; - *escFreq = 1; - } - return see; -} - -static void NextContext(CPpmd7 *p) -{ - CTX_PTR c = CTX(SUCCESSOR(p->FoundState)); - if (p->OrderFall == 0 && (Byte *)c > p->Text) - p->MinContext = p->MaxContext = c; - else - UpdateModel(p); -} - -static void Ppmd7_Update1(CPpmd7 *p) -{ - CPpmd_State *s = p->FoundState; - s->Freq += 4; - p->MinContext->SummFreq += 4; - if (s[0].Freq > s[-1].Freq) - { - SwapStates(&s[0], &s[-1]); - p->FoundState = --s; - if (s->Freq > MAX_FREQ) - Rescale(p); - } - NextContext(p); -} - -static void Ppmd7_Update1_0(CPpmd7 *p) -{ - p->PrevSuccess = (2 * p->FoundState->Freq > p->MinContext->SummFreq); - p->RunLength += p->PrevSuccess; - p->MinContext->SummFreq += 4; - if ((p->FoundState->Freq += 4) > MAX_FREQ) - Rescale(p); - NextContext(p); -} - -static void Ppmd7_UpdateBin(CPpmd7 *p) -{ - p->FoundState->Freq = (Byte)(p->FoundState->Freq + (p->FoundState->Freq < 128 ? 1: 0)); - p->PrevSuccess = 1; - p->RunLength++; - NextContext(p); -} - -static void Ppmd7_Update2(CPpmd7 *p) -{ - p->MinContext->SummFreq += 4; - if ((p->FoundState->Freq += 4) > MAX_FREQ) - Rescale(p); - p->RunLength = p->InitRL; - UpdateModel(p); -} - -/* ---------- Decode ---------- */ - -static Bool Ppmd_RangeDec_Init(CPpmd7z_RangeDec *p) -{ - unsigned i; - p->Low = p->Bottom = 0; - p->Range = 0xFFFFFFFF; - for (i = 0; i < 4; i++) - p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); - return (p->Code < 0xFFFFFFFF); -} - -static Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p) -{ - if (p->Stream->Read((void *)p->Stream) != 0) - return False; - return Ppmd_RangeDec_Init(p); -} - -static Bool PpmdRAR_RangeDec_Init(CPpmd7z_RangeDec *p) -{ - if (!Ppmd_RangeDec_Init(p)) - return False; - p->Bottom = 0x8000; - return True; -} - -static UInt32 Range_GetThreshold(void *pp, UInt32 total) -{ - CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; - return (p->Code - p->Low) / (p->Range /= total); -} - -static void Range_Normalize(CPpmd7z_RangeDec *p) -{ - while (1) - { - if((p->Low ^ (p->Low + p->Range)) >= kTopValue) - { - if(p->Range >= p->Bottom) - break; - else - p->Range = ((uint32_t)(-(int32_t)p->Low)) & (p->Bottom - 1); - } - p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream); - p->Range <<= 8; - p->Low <<= 8; - } -} - -static void Range_Decode_7z(void *pp, UInt32 start, UInt32 size) -{ - CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; - p->Code -= start * p->Range; - p->Range *= size; - Range_Normalize(p); -} - -static void Range_Decode_RAR(void *pp, UInt32 start, UInt32 size) -{ - CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; - p->Low += start * p->Range; - p->Range *= size; - Range_Normalize(p); -} - -static UInt32 Range_DecodeBit_7z(void *pp, UInt32 size0) -{ - CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; - UInt32 newBound = (p->Range >> 14) * size0; - UInt32 symbol; - if (p->Code < newBound) - { - symbol = 0; - p->Range = newBound; - } - else - { - symbol = 1; - p->Code -= newBound; - p->Range -= newBound; - } - Range_Normalize(p); - return symbol; -} - -static UInt32 Range_DecodeBit_RAR(void *pp, UInt32 size0) -{ - CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp; - UInt32 bit, value = p->p.GetThreshold(p, PPMD_BIN_SCALE); - if(value < size0) - { - bit = 0; - p->p.Decode(p, 0, size0); - } - else - { - bit = 1; - p->p.Decode(p, size0, PPMD_BIN_SCALE - size0); - } - return bit; -} - -static void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p) -{ - p->p.GetThreshold = Range_GetThreshold; - p->p.Decode = Range_Decode_7z; - p->p.DecodeBit = Range_DecodeBit_7z; -} - -static void PpmdRAR_RangeDec_CreateVTable(CPpmd7z_RangeDec *p) -{ - p->p.GetThreshold = Range_GetThreshold; - p->p.Decode = Range_Decode_RAR; - p->p.DecodeBit = Range_DecodeBit_RAR; -} - -#define MASK(sym) ((signed char *)charMask)[sym] - -static int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc) -{ - size_t charMask[256 / sizeof(size_t)]; - if (p->MinContext->NumStats != 1) - { - CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext); - unsigned i; - UInt32 count, hiCnt; - if ((count = rc->GetThreshold(rc, p->MinContext->SummFreq)) < (hiCnt = s->Freq)) - { - Byte symbol; - rc->Decode(rc, 0, s->Freq); - p->FoundState = s; - symbol = s->Symbol; - Ppmd7_Update1_0(p); - return symbol; - } - p->PrevSuccess = 0; - i = p->MinContext->NumStats - 1; - do - { - if ((hiCnt += (++s)->Freq) > count) - { - Byte symbol; - rc->Decode(rc, hiCnt - s->Freq, s->Freq); - p->FoundState = s; - symbol = s->Symbol; - Ppmd7_Update1(p); - return symbol; - } - } - while (--i); - if (count >= p->MinContext->SummFreq) - return -2; - p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]; - rc->Decode(rc, hiCnt, p->MinContext->SummFreq - hiCnt); - PPMD_SetAllBitsIn256Bytes(charMask); - MASK(s->Symbol) = 0; - i = p->MinContext->NumStats - 1; - do { MASK((--s)->Symbol) = 0; } while (--i); - } - else - { - UInt16 *prob = Ppmd7_GetBinSumm(p); - if (rc->DecodeBit(rc, *prob) == 0) - { - Byte symbol; - *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob); - symbol = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol; - Ppmd7_UpdateBin(p); - return symbol; - } - *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob); - p->InitEsc = PPMD7_kExpEscape[*prob >> 10]; - PPMD_SetAllBitsIn256Bytes(charMask); - MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0; - p->PrevSuccess = 0; - } - for (;;) - { - CPpmd_State *ps[256], *s; - UInt32 freqSum, count, hiCnt; - CPpmd_See *see; - unsigned i, num, numMasked = p->MinContext->NumStats; - do - { - p->OrderFall++; - if (!p->MinContext->Suffix) - return -1; - p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix); - } - while (p->MinContext->NumStats == numMasked); - hiCnt = 0; - s = Ppmd7_GetStats(p, p->MinContext); - i = 0; - num = p->MinContext->NumStats - numMasked; - do - { - int k = (int)(MASK(s->Symbol)); - hiCnt += (s->Freq & k); - ps[i] = s++; - i -= k; - } - while (i != num); - - see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum); - freqSum += hiCnt; - count = rc->GetThreshold(rc, freqSum); - - if (count < hiCnt) - { - Byte symbol; - CPpmd_State **pps = ps; - for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++); - s = *pps; - rc->Decode(rc, hiCnt - s->Freq, s->Freq); - Ppmd_See_Update(see); - p->FoundState = s; - symbol = s->Symbol; - Ppmd7_Update2(p); - return symbol; - } - if (count >= freqSum) - return -2; - rc->Decode(rc, hiCnt, freqSum - hiCnt); - see->Summ = (UInt16)(see->Summ + freqSum); - do { MASK(ps[--i]->Symbol) = 0; } while (i != 0); - } -} - -/* ---------- Encode ---------- Ppmd7Enc.c */ - -#define kTopValue (1 << 24) - -static void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p) -{ - p->Low = 0; - p->Range = 0xFFFFFFFF; - p->Cache = 0; - p->CacheSize = 1; -} - -static void RangeEnc_ShiftLow(CPpmd7z_RangeEnc *p) -{ - if ((UInt32)p->Low < (UInt32)0xFF000000 || (unsigned)(p->Low >> 32) != 0) - { - Byte temp = p->Cache; - do - { - p->Stream->Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32))); - temp = 0xFF; - } - while(--p->CacheSize != 0); - p->Cache = (Byte)((UInt32)p->Low >> 24); - } - p->CacheSize++; - p->Low = ((UInt32)p->Low << 8) & 0xFFFFFFFF; -} - -static void RangeEnc_Encode(CPpmd7z_RangeEnc *p, UInt32 start, UInt32 size, UInt32 total) -{ - p->Low += (UInt64)start * (UInt64)(p->Range /= total); - p->Range *= size; - while (p->Range < kTopValue) - { - p->Range <<= 8; - RangeEnc_ShiftLow(p); - } -} - -static void RangeEnc_EncodeBit_0(CPpmd7z_RangeEnc *p, UInt32 size0) -{ - p->Range = (p->Range >> 14) * size0; - while (p->Range < kTopValue) - { - p->Range <<= 8; - RangeEnc_ShiftLow(p); - } -} - -static void RangeEnc_EncodeBit_1(CPpmd7z_RangeEnc *p, UInt32 size0) -{ - UInt32 newBound = (p->Range >> 14) * size0; - p->Low += newBound; - p->Range -= newBound; - while (p->Range < kTopValue) - { - p->Range <<= 8; - RangeEnc_ShiftLow(p); - } -} - -static void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p) -{ - unsigned i; - for (i = 0; i < 5; i++) - RangeEnc_ShiftLow(p); -} - - -#define MASK(sym) ((signed char *)charMask)[sym] - -static void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol) -{ - size_t charMask[256 / sizeof(size_t)]; - if (p->MinContext->NumStats != 1) - { - CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext); - UInt32 sum; - unsigned i; - if (s->Symbol == symbol) - { - RangeEnc_Encode(rc, 0, s->Freq, p->MinContext->SummFreq); - p->FoundState = s; - Ppmd7_Update1_0(p); - return; - } - p->PrevSuccess = 0; - sum = s->Freq; - i = p->MinContext->NumStats - 1; - do - { - if ((++s)->Symbol == symbol) - { - RangeEnc_Encode(rc, sum, s->Freq, p->MinContext->SummFreq); - p->FoundState = s; - Ppmd7_Update1(p); - return; - } - sum += s->Freq; - } - while (--i); - - p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]; - PPMD_SetAllBitsIn256Bytes(charMask); - MASK(s->Symbol) = 0; - i = p->MinContext->NumStats - 1; - do { MASK((--s)->Symbol) = 0; } while (--i); - RangeEnc_Encode(rc, sum, p->MinContext->SummFreq - sum, p->MinContext->SummFreq); - } - else - { - UInt16 *prob = Ppmd7_GetBinSumm(p); - CPpmd_State *s = Ppmd7Context_OneState(p->MinContext); - if (s->Symbol == symbol) - { - RangeEnc_EncodeBit_0(rc, *prob); - *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob); - p->FoundState = s; - Ppmd7_UpdateBin(p); - return; - } - else - { - RangeEnc_EncodeBit_1(rc, *prob); - *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob); - p->InitEsc = PPMD7_kExpEscape[*prob >> 10]; - PPMD_SetAllBitsIn256Bytes(charMask); - MASK(s->Symbol) = 0; - p->PrevSuccess = 0; - } - } - for (;;) - { - UInt32 escFreq; - CPpmd_See *see; - CPpmd_State *s; - UInt32 sum; - unsigned i, numMasked = p->MinContext->NumStats; - do - { - p->OrderFall++; - if (!p->MinContext->Suffix) - return; /* EndMarker (symbol = -1) */ - p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix); - } - while (p->MinContext->NumStats == numMasked); - - see = Ppmd7_MakeEscFreq(p, numMasked, &escFreq); - s = Ppmd7_GetStats(p, p->MinContext); - sum = 0; - i = p->MinContext->NumStats; - do - { - int cur = s->Symbol; - if (cur == symbol) - { - UInt32 low = sum; - CPpmd_State *s1 = s; - do - { - sum += (s->Freq & (int)(MASK(s->Symbol))); - s++; - } - while (--i); - RangeEnc_Encode(rc, low, s1->Freq, sum + escFreq); - Ppmd_See_Update(see); - p->FoundState = s1; - Ppmd7_Update2(p); - return; - } - sum += (s->Freq & (int)(MASK(cur))); - MASK(cur) = 0; - s++; - } - while (--i); - - RangeEnc_Encode(rc, sum, escFreq, sum + escFreq); - see->Summ = (UInt16)(see->Summ + sum + escFreq); - } -} - -const IPpmd7 __archive_ppmd7_functions = -{ - &Ppmd7_Construct, - &Ppmd7_Alloc, - &Ppmd7_Free, - &Ppmd7_Init, - &Ppmd7z_RangeDec_CreateVTable, - &PpmdRAR_RangeDec_CreateVTable, - &Ppmd7z_RangeDec_Init, - &PpmdRAR_RangeDec_Init, - &Ppmd7_DecodeSymbol, - &Ppmd7z_RangeEnc_Init, - &Ppmd7z_RangeEnc_FlushData, - &Ppmd7_EncodeSymbol -}; diff --git a/thirdparty/libarchive/libarchive/archive_ppmd7_private.h b/thirdparty/libarchive/libarchive/archive_ppmd7_private.h deleted file mode 100644 index 71b954458..000000000 --- a/thirdparty/libarchive/libarchive/archive_ppmd7_private.h +++ /dev/null @@ -1,119 +0,0 @@ -/* Ppmd7.h -- PPMdH compression codec -2010-03-12 : Igor Pavlov : Public domain -This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ - -/* This code supports virtual RangeDecoder and includes the implementation -of RangeCoder from 7z, instead of RangeCoder from original PPMd var.H. -If you need the compatibility with original PPMd var.H, you can use external RangeDecoder */ - -#ifndef ARCHIVE_PPMD7_PRIVATE_H_INCLUDED -#define ARCHIVE_PPMD7_PRIVATE_H_INCLUDED - -#ifndef __LIBARCHIVE_BUILD -#error This header is only to be used internally to libarchive. -#endif - -#include "archive_ppmd_private.h" - -#define PPMD7_MIN_ORDER 2 -#define PPMD7_MAX_ORDER 64 - -#define PPMD7_MIN_MEM_SIZE (1 << 11) -#define PPMD7_MAX_MEM_SIZE (0xFFFFFFFFu - 12 * 3) - -struct CPpmd7_Context_; - -typedef - #ifdef PPMD_32BIT - struct CPpmd7_Context_ * - #else - UInt32 - #endif - CPpmd7_Context_Ref; - -typedef struct CPpmd7_Context_ -{ - UInt16 NumStats; - UInt16 SummFreq; - CPpmd_State_Ref Stats; - CPpmd7_Context_Ref Suffix; -} CPpmd7_Context; - -#define Ppmd7Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq) - -typedef struct -{ - CPpmd7_Context *MinContext, *MaxContext; - CPpmd_State *FoundState; - unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag; - Int32 RunLength, InitRL; /* must be 32-bit at least */ - - UInt32 Size; - UInt32 GlueCount; - Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart; - UInt32 AlignOffset; - - Byte Indx2Units[PPMD_NUM_INDEXES]; - Byte Units2Indx[128]; - CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES]; - Byte NS2Indx[256], NS2BSIndx[256], HB2Flag[256]; - CPpmd_See DummySee, See[25][16]; - UInt16 BinSumm[128][64]; -} CPpmd7; - -/* ---------- Decode ---------- */ - -typedef struct -{ - UInt32 (*GetThreshold)(void *p, UInt32 total); - void (*Decode)(void *p, UInt32 start, UInt32 size); - UInt32 (*DecodeBit)(void *p, UInt32 size0); -} IPpmd7_RangeDec; - -typedef struct -{ - IPpmd7_RangeDec p; - UInt32 Range; - UInt32 Code; - UInt32 Low; - UInt32 Bottom; - IByteIn *Stream; -} CPpmd7z_RangeDec; - -/* ---------- Encode ---------- */ - -typedef struct -{ - UInt64 Low; - UInt32 Range; - Byte Cache; - UInt64 CacheSize; - IByteOut *Stream; -} CPpmd7z_RangeEnc; - -typedef struct -{ - /* Base Functions */ - void (*Ppmd7_Construct)(CPpmd7 *p); - Bool (*Ppmd7_Alloc)(CPpmd7 *p, UInt32 size); - void (*Ppmd7_Free)(CPpmd7 *p); - void (*Ppmd7_Init)(CPpmd7 *p, unsigned maxOrder); - #define Ppmd7_WasAllocated(p) ((p)->Base != NULL) - - /* Decode Functions */ - void (*Ppmd7z_RangeDec_CreateVTable)(CPpmd7z_RangeDec *p); - void (*PpmdRAR_RangeDec_CreateVTable)(CPpmd7z_RangeDec *p); - Bool (*Ppmd7z_RangeDec_Init)(CPpmd7z_RangeDec *p); - Bool (*PpmdRAR_RangeDec_Init)(CPpmd7z_RangeDec *p); - #define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0) - int (*Ppmd7_DecodeSymbol)(CPpmd7 *p, IPpmd7_RangeDec *rc); - - /* Encode Functions */ - void (*Ppmd7z_RangeEnc_Init)(CPpmd7z_RangeEnc *p); - void (*Ppmd7z_RangeEnc_FlushData)(CPpmd7z_RangeEnc *p); - - void (*Ppmd7_EncodeSymbol)(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol); -} IPpmd7; - -extern const IPpmd7 __archive_ppmd7_functions; -#endif diff --git a/thirdparty/libarchive/libarchive/archive_ppmd8.c b/thirdparty/libarchive/libarchive/archive_ppmd8.c deleted file mode 100644 index d1779395d..000000000 --- a/thirdparty/libarchive/libarchive/archive_ppmd8.c +++ /dev/null @@ -1,1287 +0,0 @@ -/* Ppmd8.c -- PPMdI codec -2016-05-21 : Igor Pavlov : Public domain -This code is based on PPMd var.I (2002): Dmitry Shkarin : Public domain */ - -#include "archive_platform.h" - -#include - -#include "archive_ppmd8_private.h" - -const Byte PPMD8_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 }; -static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051}; - -#define MAX_FREQ 124 -#define UNIT_SIZE 12 - -#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE) -#define U2I(nu) (p->Units2Indx[(nu) - 1]) -#define I2U(indx) (p->Indx2Units[indx]) - -#ifdef PPMD_32BIT - #define REF(ptr) (ptr) -#else - #define REF(ptr) ((UInt32)((Byte *)(ptr) - (p)->Base)) -#endif - -#define STATS_REF(ptr) ((CPpmd_State_Ref)REF(ptr)) - -#define CTX(ref) ((CPpmd8_Context *)Ppmd8_GetContext(p, ref)) -#define STATS(ctx) Ppmd8_GetStats(p, ctx) -#define ONE_STATE(ctx) Ppmd8Context_OneState(ctx) -#define SUFFIX(ctx) CTX((ctx)->Suffix) - -#define kTop (1 << 24) -#define kBot (1 << 15) - -typedef CPpmd8_Context * CTX_PTR; - -struct CPpmd8_Node_; - -typedef - #ifdef PPMD_32BIT - struct CPpmd8_Node_ * - #else - UInt32 - #endif - CPpmd8_Node_Ref; - -typedef struct CPpmd8_Node_ -{ - UInt32 Stamp; - CPpmd8_Node_Ref Next; - UInt32 NU; -} CPpmd8_Node; - -#ifdef PPMD_32BIT - #define NODE(ptr) (ptr) -#else - #define NODE(offs) ((CPpmd8_Node *)(p->Base + (offs))) -#endif - -#define EMPTY_NODE 0xFFFFFFFF - -void Ppmd8_Construct(CPpmd8 *p) -{ - unsigned i, k, m; - - p->Base = 0; - - for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++) - { - unsigned step = (i >= 12 ? 4 : (i >> 2) + 1); - do { p->Units2Indx[k++] = (Byte)i; } while (--step); - p->Indx2Units[i] = (Byte)k; - } - - p->NS2BSIndx[0] = (0 << 1); - p->NS2BSIndx[1] = (1 << 1); - memset(p->NS2BSIndx + 2, (2 << 1), 9); - memset(p->NS2BSIndx + 11, (3 << 1), 256 - 11); - - for (i = 0; i < 5; i++) - p->NS2Indx[i] = (Byte)i; - for (m = i, k = 1; i < 260; i++) - { - p->NS2Indx[i] = (Byte)m; - if (--k == 0) - k = (++m) - 4; - } -} - -void Ppmd8_Free(CPpmd8 *p) -{ - free(p->Base); - p->Size = 0; - p->Base = 0; -} - -Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size) -{ - if (p->Base == 0 || p->Size != size) - { - Ppmd8_Free(p); - p->AlignOffset = - #ifdef PPMD_32BIT - (4 - size) & 3; - #else - 4 - (size & 3); - #endif - if ((p->Base = (Byte *)malloc(p->AlignOffset + size)) == 0) - return False; - p->Size = size; - } - return True; -} - -static void InsertNode(CPpmd8 *p, void *node, unsigned indx) -{ - ((CPpmd8_Node *)node)->Stamp = EMPTY_NODE; - ((CPpmd8_Node *)node)->Next = (CPpmd8_Node_Ref)p->FreeList[indx]; - ((CPpmd8_Node *)node)->NU = I2U(indx); - p->FreeList[indx] = REF(node); - p->Stamps[indx]++; -} - -static void *RemoveNode(CPpmd8 *p, unsigned indx) -{ - CPpmd8_Node *node = NODE((CPpmd8_Node_Ref)p->FreeList[indx]); - p->FreeList[indx] = node->Next; - p->Stamps[indx]--; - return node; -} - -static void SplitBlock(CPpmd8 *p, void *ptr, unsigned oldIndx, unsigned newIndx) -{ - unsigned i, nu = I2U(oldIndx) - I2U(newIndx); - ptr = (Byte *)ptr + U2B(I2U(newIndx)); - if (I2U(i = U2I(nu)) != nu) - { - unsigned k = I2U(--i); - InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1); - } - InsertNode(p, ptr, i); -} - -static void GlueFreeBlocks(CPpmd8 *p) -{ - CPpmd8_Node_Ref head = 0; - CPpmd8_Node_Ref *prev = &head; - unsigned i; - - p->GlueCount = 1 << 13; - memset(p->Stamps, 0, sizeof(p->Stamps)); - - /* Order-0 context is always at top UNIT, so we don't need guard NODE at the end. - All blocks up to p->LoUnit can be free, so we need guard NODE at LoUnit. */ - if (p->LoUnit != p->HiUnit) - ((CPpmd8_Node *)p->LoUnit)->Stamp = 0; - - /* Glue free blocks */ - for (i = 0; i < PPMD_NUM_INDEXES; i++) - { - CPpmd8_Node_Ref next = (CPpmd8_Node_Ref)p->FreeList[i]; - p->FreeList[i] = 0; - while (next != 0) - { - CPpmd8_Node *node = NODE(next); - if (node->NU != 0) - { - CPpmd8_Node *node2; - *prev = next; - prev = &(node->Next); - while ((node2 = node + node->NU)->Stamp == EMPTY_NODE) - { - node->NU += node2->NU; - node2->NU = 0; - } - } - next = node->Next; - } - } - *prev = 0; - - /* Fill lists of free blocks */ - while (head != 0) - { - CPpmd8_Node *node = NODE(head); - unsigned nu; - head = node->Next; - nu = node->NU; - if (nu == 0) - continue; - for (; nu > 128; nu -= 128, node += 128) - InsertNode(p, node, PPMD_NUM_INDEXES - 1); - if (I2U(i = U2I(nu)) != nu) - { - unsigned k = I2U(--i); - InsertNode(p, node + k, nu - k - 1); - } - InsertNode(p, node, i); - } -} - -static void *AllocUnitsRare(CPpmd8 *p, unsigned indx) -{ - unsigned i; - void *retVal; - if (p->GlueCount == 0) - { - GlueFreeBlocks(p); - if (p->FreeList[indx] != 0) - return RemoveNode(p, indx); - } - i = indx; - do - { - if (++i == PPMD_NUM_INDEXES) - { - UInt32 numBytes = U2B(I2U(indx)); - p->GlueCount--; - return ((UInt32)(p->UnitsStart - p->Text) > numBytes) ? (p->UnitsStart -= numBytes) : (NULL); - } - } - while (p->FreeList[i] == 0); - retVal = RemoveNode(p, i); - SplitBlock(p, retVal, i, indx); - return retVal; -} - -static void *AllocUnits(CPpmd8 *p, unsigned indx) -{ - UInt32 numBytes; - if (p->FreeList[indx] != 0) - return RemoveNode(p, indx); - numBytes = U2B(I2U(indx)); - if (numBytes <= (UInt32)(p->HiUnit - p->LoUnit)) - { - void *retVal = p->LoUnit; - p->LoUnit += numBytes; - return retVal; - } - return AllocUnitsRare(p, indx); -} - -#define MyMem12Cpy(dest, src, num) \ - { UInt32 *d = (UInt32 *)dest; const UInt32 *z = (const UInt32 *)src; UInt32 n = num; \ - do { d[0] = z[0]; d[1] = z[1]; d[2] = z[2]; z += 3; d += 3; } while (--n); } - -static void *ShrinkUnits(CPpmd8 *p, void *oldPtr, unsigned oldNU, unsigned newNU) -{ - unsigned i0 = U2I(oldNU); - unsigned i1 = U2I(newNU); - if (i0 == i1) - return oldPtr; - if (p->FreeList[i1] != 0) - { - void *ptr = RemoveNode(p, i1); - MyMem12Cpy(ptr, oldPtr, newNU); - InsertNode(p, oldPtr, i0); - return ptr; - } - SplitBlock(p, oldPtr, i0, i1); - return oldPtr; -} - -static void FreeUnits(CPpmd8 *p, void *ptr, unsigned nu) -{ - InsertNode(p, ptr, U2I(nu)); -} - -static void SpecialFreeUnit(CPpmd8 *p, void *ptr) -{ - if ((Byte *)ptr != p->UnitsStart) - InsertNode(p, ptr, 0); - else - { - #ifdef PPMD8_FREEZE_SUPPORT - *(UInt32 *)ptr = EMPTY_NODE; /* it's used for (Flags == 0xFF) check in RemoveBinContexts */ - #endif - p->UnitsStart += UNIT_SIZE; - } -} - -static void *MoveUnitsUp(CPpmd8 *p, void *oldPtr, unsigned nu) -{ - unsigned indx = U2I(nu); - void *ptr; - if ((Byte *)oldPtr > p->UnitsStart + 16 * 1024 || REF(oldPtr) > p->FreeList[indx]) - return oldPtr; - ptr = RemoveNode(p, indx); - MyMem12Cpy(ptr, oldPtr, nu); - if ((Byte*)oldPtr != p->UnitsStart) - InsertNode(p, oldPtr, indx); - else - p->UnitsStart += U2B(I2U(indx)); - return ptr; -} - -static void ExpandTextArea(CPpmd8 *p) -{ - UInt32 count[PPMD_NUM_INDEXES]; - unsigned i; - memset(count, 0, sizeof(count)); - if (p->LoUnit != p->HiUnit) - ((CPpmd8_Node *)p->LoUnit)->Stamp = 0; - - { - CPpmd8_Node *node = (CPpmd8_Node *)p->UnitsStart; - for (; node->Stamp == EMPTY_NODE; node += node->NU) - { - node->Stamp = 0; - count[U2I(node->NU)]++; - } - p->UnitsStart = (Byte *)node; - } - - for (i = 0; i < PPMD_NUM_INDEXES; i++) - { - CPpmd8_Node_Ref *next = (CPpmd8_Node_Ref *)&p->FreeList[i]; - while (count[i] != 0) - { - CPpmd8_Node *node = NODE(*next); - while (node->Stamp == 0) - { - *next = node->Next; - node = NODE(*next); - p->Stamps[i]--; - if (--count[i] == 0) - break; - } - next = &node->Next; - } - } -} - -#define SUCCESSOR(p) ((CPpmd_Void_Ref)((p)->SuccessorLow | ((UInt32)(p)->SuccessorHigh << 16))) - -static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v) -{ - (p)->SuccessorLow = (UInt16)((UInt32)(v) & 0xFFFF); - (p)->SuccessorHigh = (UInt16)(((UInt32)(v) >> 16) & 0xFFFF); -} - -#define RESET_TEXT(offs) { p->Text = p->Base + p->AlignOffset + (offs); } - -static void RestartModel(CPpmd8 *p) -{ - unsigned i, k, m, r; - - memset(p->FreeList, 0, sizeof(p->FreeList)); - memset(p->Stamps, 0, sizeof(p->Stamps)); - RESET_TEXT(0); - p->HiUnit = p->Text + p->Size; - p->LoUnit = p->UnitsStart = p->HiUnit - p->Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE; - p->GlueCount = 0; - - p->OrderFall = p->MaxOrder; - p->RunLength = p->InitRL = -(Int32)((p->MaxOrder < 12) ? p->MaxOrder : 12) - 1; - p->PrevSuccess = 0; - - p->MinContext = p->MaxContext = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */ - p->MinContext->Suffix = 0; - p->MinContext->NumStats = 255; - p->MinContext->Flags = 0; - p->MinContext->SummFreq = 256 + 1; - p->FoundState = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */ - p->LoUnit += U2B(256 / 2); - p->MinContext->Stats = REF(p->FoundState); - for (i = 0; i < 256; i++) - { - CPpmd_State *s = &p->FoundState[i]; - s->Symbol = (Byte)i; - s->Freq = 1; - SetSuccessor(s, 0); - } - - for (i = m = 0; m < 25; m++) - { - while (p->NS2Indx[i] == m) - i++; - for (k = 0; k < 8; k++) - { - UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 1)); - UInt16 *dest = p->BinSumm[m] + k; - for (r = 0; r < 64; r += 8) - dest[r] = val; - } - } - - for (i = m = 0; m < 24; m++) - { - while (p->NS2Indx[i + 3] == m + 3) - i++; - for (k = 0; k < 32; k++) - { - CPpmd_See *s = &p->See[m][k]; - s->Summ = (UInt16)((2 * i + 5) << (s->Shift = PPMD_PERIOD_BITS - 4)); - s->Count = 7; - } - } -} - -void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod) -{ - p->MaxOrder = maxOrder; - p->RestoreMethod = restoreMethod; - RestartModel(p); - p->DummySee.Shift = PPMD_PERIOD_BITS; - p->DummySee.Summ = 0; /* unused */ - p->DummySee.Count = 64; /* unused */ -} - -static void Refresh(CPpmd8 *p, CTX_PTR ctx, unsigned oldNU, unsigned scale) -{ - unsigned i = ctx->NumStats, escFreq, sumFreq, flags; - CPpmd_State *s = (CPpmd_State *)ShrinkUnits(p, STATS(ctx), oldNU, (i + 2) >> 1); - ctx->Stats = REF(s); - #ifdef PPMD8_FREEZE_SUPPORT - /* fixed over Shkarin's code. Fixed code is not compatible with original code for some files in FREEZE mode. */ - scale |= (ctx->SummFreq >= ((UInt32)1 << 15)); - #endif - flags = (ctx->Flags & (0x10 + 0x04 * scale)) + 0x08 * (s->Symbol >= 0x40); - escFreq = ctx->SummFreq - s->Freq; - sumFreq = (s->Freq = (Byte)((s->Freq + scale) >> scale)); - do - { - escFreq -= (++s)->Freq; - sumFreq += (s->Freq = (Byte)((s->Freq + scale) >> scale)); - flags |= 0x08 * (s->Symbol >= 0x40); - } - while (--i); - ctx->SummFreq = (UInt16)(sumFreq + ((escFreq + scale) >> scale)); - ctx->Flags = (Byte)flags; -} - -static void SwapStates(CPpmd_State *t1, CPpmd_State *t2) -{ - CPpmd_State tmp = *t1; - *t1 = *t2; - *t2 = tmp; -} - -static CPpmd_Void_Ref CutOff(CPpmd8 *p, CTX_PTR ctx, unsigned order) -{ - int i; - unsigned tmp; - CPpmd_State *s; - - if (!ctx->NumStats) - { - s = ONE_STATE(ctx); - if ((Byte *)Ppmd8_GetPtr(p, SUCCESSOR(s)) >= p->UnitsStart) - { - if (order < p->MaxOrder) - SetSuccessor(s, CutOff(p, CTX(SUCCESSOR(s)), order + 1)); - else - SetSuccessor(s, 0); - if (SUCCESSOR(s) || order <= 9) /* O_BOUND */ - return REF(ctx); - } - SpecialFreeUnit(p, ctx); - return 0; - } - - ctx->Stats = STATS_REF(MoveUnitsUp(p, STATS(ctx), tmp = ((unsigned)ctx->NumStats + 2) >> 1)); - - for (s = STATS(ctx) + (i = ctx->NumStats); s >= STATS(ctx); s--) - if ((Byte *)Ppmd8_GetPtr(p, SUCCESSOR(s)) < p->UnitsStart) - { - CPpmd_State *s2 = STATS(ctx) + (i--); - SetSuccessor(s, 0); - SwapStates(s, s2); - } - else if (order < p->MaxOrder) - SetSuccessor(s, CutOff(p, CTX(SUCCESSOR(s)), order + 1)); - else - SetSuccessor(s, 0); - - if (i != ctx->NumStats && order) - { - ctx->NumStats = (Byte)i; - s = STATS(ctx); - if (i < 0) - { - FreeUnits(p, s, tmp); - SpecialFreeUnit(p, ctx); - return 0; - } - if (i == 0) - { - ctx->Flags = (Byte)((ctx->Flags & 0x10) + 0x08 * (s->Symbol >= 0x40)); - *ONE_STATE(ctx) = *s; - FreeUnits(p, s, tmp); - /* 9.31: the code was fixed. It's was not BUG, if Freq <= MAX_FREQ = 124 */ - ONE_STATE(ctx)->Freq = (Byte)(((unsigned)ONE_STATE(ctx)->Freq + 11) >> 3); - } - else - Refresh(p, ctx, tmp, ctx->SummFreq > 16 * i); - } - return REF(ctx); -} - -#ifdef PPMD8_FREEZE_SUPPORT -static CPpmd_Void_Ref RemoveBinContexts(CPpmd8 *p, CTX_PTR ctx, unsigned order) -{ - CPpmd_State *s; - if (!ctx->NumStats) - { - s = ONE_STATE(ctx); - if ((Byte *)Ppmd8_GetPtr(p, SUCCESSOR(s)) >= p->UnitsStart && order < p->MaxOrder) - SetSuccessor(s, RemoveBinContexts(p, CTX(SUCCESSOR(s)), order + 1)); - else - SetSuccessor(s, 0); - /* Suffix context can be removed already, since different (high-order) - Successors may refer to same context. So we check Flags == 0xFF (Stamp == EMPTY_NODE) */ - if (!SUCCESSOR(s) && (!SUFFIX(ctx)->NumStats || SUFFIX(ctx)->Flags == 0xFF)) - { - FreeUnits(p, ctx, 1); - return 0; - } - else - return REF(ctx); - } - - for (s = STATS(ctx) + ctx->NumStats; s >= STATS(ctx); s--) - if ((Byte *)Ppmd8_GetPtr(p, SUCCESSOR(s)) >= p->UnitsStart && order < p->MaxOrder) - SetSuccessor(s, RemoveBinContexts(p, CTX(SUCCESSOR(s)), order + 1)); - else - SetSuccessor(s, 0); - - return REF(ctx); -} -#endif - -static UInt32 GetUsedMemory(const CPpmd8 *p) -{ - UInt32 v = 0; - unsigned i; - for (i = 0; i < PPMD_NUM_INDEXES; i++) - v += p->Stamps[i] * I2U(i); - return p->Size - (UInt32)(p->HiUnit - p->LoUnit) - (UInt32)(p->UnitsStart - p->Text) - U2B(v); -} - -#ifdef PPMD8_FREEZE_SUPPORT - #define RESTORE_MODEL(c1, fSuccessor) RestoreModel(p, c1, fSuccessor) -#else - #define RESTORE_MODEL(c1, fSuccessor) RestoreModel(p, c1) -#endif - -static void RestoreModel(CPpmd8 *p, CTX_PTR c1 - #ifdef PPMD8_FREEZE_SUPPORT - , CTX_PTR fSuccessor - #endif - ) -{ - CTX_PTR c; - CPpmd_State *s; - RESET_TEXT(0); - for (c = p->MaxContext; c != c1; c = SUFFIX(c)) - if (--(c->NumStats) == 0) - { - s = STATS(c); - c->Flags = (Byte)((c->Flags & 0x10) + 0x08 * (s->Symbol >= 0x40)); - *ONE_STATE(c) = *s; - SpecialFreeUnit(p, s); - ONE_STATE(c)->Freq = (Byte)(((unsigned)ONE_STATE(c)->Freq + 11) >> 3); - } - else - Refresh(p, c, (c->NumStats+3) >> 1, 0); - - for (; c != p->MinContext; c = SUFFIX(c)) - if (!c->NumStats) - ONE_STATE(c)->Freq = (Byte)(ONE_STATE(c)->Freq - (ONE_STATE(c)->Freq >> 1)); - else if ((c->SummFreq += 4) > 128 + 4 * c->NumStats) - Refresh(p, c, (c->NumStats + 2) >> 1, 1); - - #ifdef PPMD8_FREEZE_SUPPORT - if (p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE) - { - p->MaxContext = fSuccessor; - p->GlueCount += !(p->Stamps[1] & 1); - } - else if (p->RestoreMethod == PPMD8_RESTORE_METHOD_FREEZE) - { - while (p->MaxContext->Suffix) - p->MaxContext = SUFFIX(p->MaxContext); - RemoveBinContexts(p, p->MaxContext, 0); - p->RestoreMethod++; - p->GlueCount = 0; - p->OrderFall = p->MaxOrder; - } - else - #endif - if (p->RestoreMethod == PPMD8_RESTORE_METHOD_RESTART || GetUsedMemory(p) < (p->Size >> 1)) - RestartModel(p); - else - { - while (p->MaxContext->Suffix) - p->MaxContext = SUFFIX(p->MaxContext); - do - { - CutOff(p, p->MaxContext, 0); - ExpandTextArea(p); - } - while (GetUsedMemory(p) > 3 * (p->Size >> 2)); - p->GlueCount = 0; - p->OrderFall = p->MaxOrder; - } -} - -static CTX_PTR CreateSuccessors(CPpmd8 *p, Bool skip, CPpmd_State *s1, CTX_PTR c) -{ - CPpmd_State upState; - Byte flags; - CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState); - /* fixed over Shkarin's code. Maybe it could work without + 1 too. */ - CPpmd_State *ps[PPMD8_MAX_ORDER + 1]; - unsigned numPs = 0; - - if (!skip) - ps[numPs++] = p->FoundState; - - while (c->Suffix) - { - CPpmd_Void_Ref successor; - CPpmd_State *s; - c = SUFFIX(c); - if (s1) - { - s = s1; - s1 = NULL; - } - else if (c->NumStats != 0) - { - for (s = STATS(c); s->Symbol != p->FoundState->Symbol; s++); - if (s->Freq < MAX_FREQ - 9) - { - s->Freq++; - c->SummFreq++; - } - } - else - { - s = ONE_STATE(c); - s->Freq = (Byte)(s->Freq + (!SUFFIX(c)->NumStats & (s->Freq < 24))); - } - successor = SUCCESSOR(s); - if (successor != upBranch) - { - c = CTX(successor); - if (numPs == 0) - return c; - break; - } - ps[numPs++] = s; - } - - upState.Symbol = *(const Byte *)Ppmd8_GetPtr(p, upBranch); - SetSuccessor(&upState, upBranch + 1); - flags = (Byte)(0x10 * (p->FoundState->Symbol >= 0x40) + 0x08 * (upState.Symbol >= 0x40)); - - if (c->NumStats == 0) - upState.Freq = ONE_STATE(c)->Freq; - else - { - UInt32 cf, s0; - CPpmd_State *s; - for (s = STATS(c); s->Symbol != upState.Symbol; s++); - cf = s->Freq - 1; - s0 = c->SummFreq - c->NumStats - cf; - upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((cf + 2 * s0 - 3) / s0))); - } - - do - { - /* Create Child */ - CTX_PTR c1; /* = AllocContext(p); */ - if (p->HiUnit != p->LoUnit) - c1 = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); - else if (p->FreeList[0] != 0) - c1 = (CTX_PTR)RemoveNode(p, 0); - else - { - c1 = (CTX_PTR)AllocUnitsRare(p, 0); - if (!c1) - return NULL; - } - c1->NumStats = 0; - c1->Flags = flags; - *ONE_STATE(c1) = upState; - c1->Suffix = REF(c); - SetSuccessor(ps[--numPs], REF(c1)); - c = c1; - } - while (numPs != 0); - - return c; -} - -static CTX_PTR ReduceOrder(CPpmd8 *p, CPpmd_State *s1, CTX_PTR c) -{ - CPpmd_State *s = NULL; - CTX_PTR c1 = c; - CPpmd_Void_Ref upBranch = REF(p->Text); - - #ifdef PPMD8_FREEZE_SUPPORT - /* The BUG in Shkarin's code was fixed: ps could overflow in CUT_OFF mode. */ - CPpmd_State *ps[PPMD8_MAX_ORDER + 1]; - unsigned numPs = 0; - ps[numPs++] = p->FoundState; - #endif - - SetSuccessor(p->FoundState, upBranch); - p->OrderFall++; - - for (;;) - { - if (s1) - { - c = SUFFIX(c); - s = s1; - s1 = NULL; - } - else - { - if (!c->Suffix) - { - #ifdef PPMD8_FREEZE_SUPPORT - if (p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE) - { - do { SetSuccessor(ps[--numPs], REF(c)); } while (numPs); - RESET_TEXT(1); - p->OrderFall = 1; - } - #endif - return c; - } - c = SUFFIX(c); - if (c->NumStats) - { - if ((s = STATS(c))->Symbol != p->FoundState->Symbol) - do { s++; } while (s->Symbol != p->FoundState->Symbol); - if (s->Freq < MAX_FREQ - 9) - { - s->Freq += 2; - c->SummFreq += 2; - } - } - else - { - s = ONE_STATE(c); - s->Freq = (Byte)(s->Freq + (s->Freq < 32)); - } - } - if (SUCCESSOR(s)) - break; - #ifdef PPMD8_FREEZE_SUPPORT - ps[numPs++] = s; - #endif - SetSuccessor(s, upBranch); - p->OrderFall++; - } - - #ifdef PPMD8_FREEZE_SUPPORT - if (p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE) - { - c = CTX(SUCCESSOR(s)); - do { SetSuccessor(ps[--numPs], REF(c)); } while (numPs); - RESET_TEXT(1); - p->OrderFall = 1; - return c; - } - else - #endif - if (SUCCESSOR(s) <= upBranch) - { - CTX_PTR successor; - CPpmd_State *s2 = p->FoundState; - p->FoundState = s; - - successor = CreateSuccessors(p, False, NULL, c); - if (successor == NULL) - SetSuccessor(s, 0); - else - SetSuccessor(s, REF(successor)); - p->FoundState = s2; - } - - if (p->OrderFall == 1 && c1 == p->MaxContext) - { - SetSuccessor(p->FoundState, SUCCESSOR(s)); - p->Text--; - } - if (SUCCESSOR(s) == 0) - return NULL; - return CTX(SUCCESSOR(s)); -} - -static void UpdateModel(CPpmd8 *p) -{ - CPpmd_Void_Ref successor, fSuccessor = SUCCESSOR(p->FoundState); - CTX_PTR c; - unsigned s0, ns, fFreq = p->FoundState->Freq; - Byte flag, fSymbol = p->FoundState->Symbol; - CPpmd_State *s = NULL; - - if (p->FoundState->Freq < MAX_FREQ / 4 && p->MinContext->Suffix != 0) - { - c = SUFFIX(p->MinContext); - - if (c->NumStats == 0) - { - s = ONE_STATE(c); - if (s->Freq < 32) - s->Freq++; - } - else - { - s = STATS(c); - if (s->Symbol != p->FoundState->Symbol) - { - do { s++; } while (s->Symbol != p->FoundState->Symbol); - if (s[0].Freq >= s[-1].Freq) - { - SwapStates(&s[0], &s[-1]); - s--; - } - } - if (s->Freq < MAX_FREQ - 9) - { - s->Freq += 2; - c->SummFreq += 2; - } - } - } - - c = p->MaxContext; - if (p->OrderFall == 0 && fSuccessor) - { - CTX_PTR cs = CreateSuccessors(p, True, s, p->MinContext); - if (cs == 0) - { - SetSuccessor(p->FoundState, 0); - RESTORE_MODEL(c, CTX(fSuccessor)); - } - else - { - SetSuccessor(p->FoundState, REF(cs)); - p->MaxContext = cs; - } - return; - } - - *p->Text++ = p->FoundState->Symbol; - successor = REF(p->Text); - if (p->Text >= p->UnitsStart) - { - RESTORE_MODEL(c, CTX(fSuccessor)); /* check it */ - return; - } - - if (!fSuccessor) - { - CTX_PTR cs = ReduceOrder(p, s, p->MinContext); - if (cs == NULL) - { - RESTORE_MODEL(c, 0); - return; - } - fSuccessor = REF(cs); - } - else if ((Byte *)Ppmd8_GetPtr(p, fSuccessor) < p->UnitsStart) - { - CTX_PTR cs = CreateSuccessors(p, False, s, p->MinContext); - if (cs == NULL) - { - RESTORE_MODEL(c, 0); - return; - } - fSuccessor = REF(cs); - } - - if (--p->OrderFall == 0) - { - successor = fSuccessor; - p->Text -= (p->MaxContext != p->MinContext); - } - #ifdef PPMD8_FREEZE_SUPPORT - else if (p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE) - { - successor = fSuccessor; - RESET_TEXT(0); - p->OrderFall = 0; - } - #endif - - s0 = p->MinContext->SummFreq - (ns = p->MinContext->NumStats) - fFreq; - flag = (Byte)(0x08 * (fSymbol >= 0x40)); - - for (; c != p->MinContext; c = SUFFIX(c)) - { - unsigned ns1; - UInt32 cf, sf; - if ((ns1 = c->NumStats) != 0) - { - if ((ns1 & 1) != 0) - { - /* Expand for one UNIT */ - unsigned oldNU = (ns1 + 1) >> 1; - unsigned i = U2I(oldNU); - if (i != U2I(oldNU + 1)) - { - void *ptr = AllocUnits(p, i + 1); - void *oldPtr; - if (!ptr) - { - RESTORE_MODEL(c, CTX(fSuccessor)); - return; - } - oldPtr = STATS(c); - MyMem12Cpy(ptr, oldPtr, oldNU); - InsertNode(p, oldPtr, i); - c->Stats = STATS_REF(ptr); - } - } - c->SummFreq = (UInt16)(c->SummFreq + (3 * ns1 + 1 < ns)); - } - else - { - CPpmd_State *s2 = (CPpmd_State*)AllocUnits(p, 0); - if (!s2) - { - RESTORE_MODEL(c, CTX(fSuccessor)); - return; - } - *s2 = *ONE_STATE(c); - c->Stats = REF(s2); - if (s2->Freq < MAX_FREQ / 4 - 1) - s2->Freq <<= 1; - else - s2->Freq = MAX_FREQ - 4; - c->SummFreq = (UInt16)(s2->Freq + p->InitEsc + (ns > 2)); - } - cf = 2 * fFreq * (c->SummFreq + 6); - sf = (UInt32)s0 + c->SummFreq; - if (cf < 6 * sf) - { - cf = 1 + (cf > sf) + (cf >= 4 * sf); - c->SummFreq += 4; - } - else - { - cf = 4 + (cf > 9 * sf) + (cf > 12 * sf) + (cf > 15 * sf); - c->SummFreq = (UInt16)(c->SummFreq + cf); - } - { - CPpmd_State *s2 = STATS(c) + ns1 + 1; - SetSuccessor(s2, successor); - s2->Symbol = fSymbol; - s2->Freq = (Byte)cf; - c->Flags |= flag; - c->NumStats = (Byte)(ns1 + 1); - } - } - p->MaxContext = p->MinContext = CTX(fSuccessor); -} - -static void Rescale(CPpmd8 *p) -{ - unsigned i, adder, sumFreq, escFreq; - CPpmd_State *stats = STATS(p->MinContext); - CPpmd_State *s = p->FoundState; - { - CPpmd_State tmp = *s; - for (; s != stats; s--) - s[0] = s[-1]; - *s = tmp; - } - escFreq = p->MinContext->SummFreq - s->Freq; - s->Freq += 4; - adder = (p->OrderFall != 0 - #ifdef PPMD8_FREEZE_SUPPORT - || p->RestoreMethod > PPMD8_RESTORE_METHOD_FREEZE - #endif - ); - s->Freq = (Byte)((s->Freq + adder) >> 1); - sumFreq = s->Freq; - - i = p->MinContext->NumStats; - do - { - escFreq -= (++s)->Freq; - s->Freq = (Byte)((s->Freq + adder) >> 1); - sumFreq += s->Freq; - if (s[0].Freq > s[-1].Freq) - { - CPpmd_State *s1 = s; - CPpmd_State tmp = *s1; - do - s1[0] = s1[-1]; - while (--s1 != stats && tmp.Freq > s1[-1].Freq); - *s1 = tmp; - } - } - while (--i); - - if (s->Freq == 0) - { - unsigned numStats = p->MinContext->NumStats; - unsigned n0, n1; - do { i++; } while ((--s)->Freq == 0); - escFreq += i; - p->MinContext->NumStats = (Byte)(p->MinContext->NumStats - i); - if (p->MinContext->NumStats == 0) - { - CPpmd_State tmp = *stats; - tmp.Freq = (Byte)((2 * tmp.Freq + escFreq - 1) / escFreq); - if (tmp.Freq > MAX_FREQ / 3) - tmp.Freq = MAX_FREQ / 3; - InsertNode(p, stats, U2I((numStats + 2) >> 1)); - p->MinContext->Flags = (Byte)((p->MinContext->Flags & 0x10) + 0x08 * (tmp.Symbol >= 0x40)); - *(p->FoundState = ONE_STATE(p->MinContext)) = tmp; - return; - } - n0 = (numStats + 2) >> 1; - n1 = (p->MinContext->NumStats + 2) >> 1; - if (n0 != n1) - p->MinContext->Stats = STATS_REF(ShrinkUnits(p, stats, n0, n1)); - p->MinContext->Flags &= ~0x08; - p->MinContext->Flags |= 0x08 * ((s = STATS(p->MinContext))->Symbol >= 0x40); - i = p->MinContext->NumStats; - do { p->MinContext->Flags |= 0x08*((++s)->Symbol >= 0x40); } while (--i); - } - p->MinContext->SummFreq = (UInt16)(sumFreq + escFreq - (escFreq >> 1)); - p->MinContext->Flags |= 0x4; - p->FoundState = STATS(p->MinContext); -} - -CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked1, UInt32 *escFreq) -{ - CPpmd_See *see; - if (p->MinContext->NumStats != 0xFF) - { - see = p->See[(unsigned)p->NS2Indx[(unsigned)p->MinContext->NumStats + 2] - 3] + - (p->MinContext->SummFreq > 11 * ((unsigned)p->MinContext->NumStats + 1)) + - 2 * (unsigned)(2 * (unsigned)p->MinContext->NumStats < - ((unsigned)SUFFIX(p->MinContext)->NumStats + numMasked1)) + - p->MinContext->Flags; - { - unsigned r = (see->Summ >> see->Shift); - see->Summ = (UInt16)(see->Summ - r); - *escFreq = r + (r == 0); - } - } - else - { - see = &p->DummySee; - *escFreq = 1; - } - return see; -} - -static void NextContext(CPpmd8 *p) -{ - CTX_PTR c = CTX(SUCCESSOR(p->FoundState)); - if (p->OrderFall == 0 && (Byte *)c >= p->UnitsStart) - p->MinContext = p->MaxContext = c; - else - { - UpdateModel(p); - p->MinContext = p->MaxContext; - } -} - -void Ppmd8_Update1(CPpmd8 *p) -{ - CPpmd_State *s = p->FoundState; - s->Freq += 4; - p->MinContext->SummFreq += 4; - if (s[0].Freq > s[-1].Freq) - { - SwapStates(&s[0], &s[-1]); - p->FoundState = --s; - if (s->Freq > MAX_FREQ) - Rescale(p); - } - NextContext(p); -} - -void Ppmd8_Update1_0(CPpmd8 *p) -{ - p->PrevSuccess = (2 * p->FoundState->Freq >= p->MinContext->SummFreq); - p->RunLength += p->PrevSuccess; - p->MinContext->SummFreq += 4; - if ((p->FoundState->Freq += 4) > MAX_FREQ) - Rescale(p); - NextContext(p); -} - -void Ppmd8_UpdateBin(CPpmd8 *p) -{ - p->FoundState->Freq = (Byte)(p->FoundState->Freq + (p->FoundState->Freq < 196)); - p->PrevSuccess = 1; - p->RunLength++; - NextContext(p); -} - -void Ppmd8_Update2(CPpmd8 *p) -{ - p->MinContext->SummFreq += 4; - if ((p->FoundState->Freq += 4) > MAX_FREQ) - Rescale(p); - p->RunLength = p->InitRL; - UpdateModel(p); - p->MinContext = p->MaxContext; -} - -/* Ppmd8Dec.c -- PPMdI Decoder -2010-04-16 : Igor Pavlov : Public domain -This code is based on: - PPMd var.I (2002): Dmitry Shkarin : Public domain - Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ - -Bool Ppmd8_RangeDec_Init(CPpmd8 *p) -{ - unsigned i; - p->Low = 0; - p->Range = 0xFFFFFFFF; - p->Code = 0; - for (i = 0; i < 4; i++) - p->Code = (p->Code << 8) | p->Stream.In->Read(p->Stream.In); - return (p->Code < 0xFFFFFFFF); -} - -static UInt32 RangeDec_GetThreshold(CPpmd8 *p, UInt32 total) -{ - return p->Code / (p->Range /= total); -} - -static void RangeDec_Decode(CPpmd8 *p, UInt32 start, UInt32 size) -{ - start *= p->Range; - p->Low += start; - p->Code -= start; - p->Range *= size; - - while ((p->Low ^ (p->Low + p->Range)) < kTop || - (p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1))) - { - p->Code = (p->Code << 8) | p->Stream.In->Read(p->Stream.In); - p->Range <<= 8; - p->Low <<= 8; - } -} - -#define MASK(sym) ((signed char *)charMask)[sym] - -int Ppmd8_DecodeSymbol(CPpmd8 *p) -{ - size_t charMask[256 / sizeof(size_t)]; - if (p->MinContext->NumStats != 0) - { - CPpmd_State *s = Ppmd8_GetStats(p, p->MinContext); - unsigned i; - UInt32 count, hiCnt; - if ((count = RangeDec_GetThreshold(p, p->MinContext->SummFreq)) < (hiCnt = s->Freq)) - { - Byte symbol; - RangeDec_Decode(p, 0, s->Freq); - p->FoundState = s; - symbol = s->Symbol; - Ppmd8_Update1_0(p); - return symbol; - } - p->PrevSuccess = 0; - i = p->MinContext->NumStats; - do - { - if ((hiCnt += (++s)->Freq) > count) - { - Byte symbol; - RangeDec_Decode(p, hiCnt - s->Freq, s->Freq); - p->FoundState = s; - symbol = s->Symbol; - Ppmd8_Update1(p); - return symbol; - } - } - while (--i); - if (count >= p->MinContext->SummFreq) - return -2; - RangeDec_Decode(p, hiCnt, p->MinContext->SummFreq - hiCnt); - PPMD_SetAllBitsIn256Bytes(charMask); - MASK(s->Symbol) = 0; - i = p->MinContext->NumStats; - do { MASK((--s)->Symbol) = 0; } while (--i); - } - else - { - UInt16 *prob = Ppmd8_GetBinSumm(p); - if (((p->Code / (p->Range >>= 14)) < *prob)) - { - Byte symbol; - RangeDec_Decode(p, 0, *prob); - *prob = (UInt16)PPMD_UPDATE_PROB_0(*prob); - symbol = (p->FoundState = Ppmd8Context_OneState(p->MinContext))->Symbol; - Ppmd8_UpdateBin(p); - return symbol; - } - RangeDec_Decode(p, *prob, (1 << 14) - *prob); - *prob = (UInt16)PPMD_UPDATE_PROB_1(*prob); - p->InitEsc = PPMD8_kExpEscape[*prob >> 10]; - PPMD_SetAllBitsIn256Bytes(charMask); - MASK(Ppmd8Context_OneState(p->MinContext)->Symbol) = 0; - p->PrevSuccess = 0; - } - for (;;) - { - CPpmd_State *ps[256], *s; - UInt32 freqSum, count, hiCnt; - CPpmd_See *see; - unsigned i, num, numMasked = p->MinContext->NumStats; - do - { - p->OrderFall++; - if (!p->MinContext->Suffix) - return -1; - p->MinContext = Ppmd8_GetContext(p, p->MinContext->Suffix); - } - while (p->MinContext->NumStats == numMasked); - hiCnt = 0; - s = Ppmd8_GetStats(p, p->MinContext); - i = 0; - num = p->MinContext->NumStats - numMasked; - do - { - int k = (int)(MASK(s->Symbol)); - hiCnt += (s->Freq & k); - ps[i] = s++; - i -= k; - } - while (i != num); - - see = Ppmd8_MakeEscFreq(p, numMasked, &freqSum); - freqSum += hiCnt; - count = RangeDec_GetThreshold(p, freqSum); - - if (count < hiCnt) - { - Byte symbol; - CPpmd_State **pps = ps; - for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++); - s = *pps; - RangeDec_Decode(p, hiCnt - s->Freq, s->Freq); - Ppmd_See_Update(see); - p->FoundState = s; - symbol = s->Symbol; - Ppmd8_Update2(p); - return symbol; - } - if (count >= freqSum) - return -2; - RangeDec_Decode(p, hiCnt, freqSum - hiCnt); - see->Summ = (UInt16)(see->Summ + freqSum); - do { MASK(ps[--i]->Symbol) = 0; } while (i != 0); - } -} - -/* H->I changes: - NS2Indx - GlewCount, and Glue method - BinSum - See / EscFreq - CreateSuccessors updates more suffix contexts - UpdateModel consts. - PrevSuccess Update -*/ - -const IPpmd8 __archive_ppmd8_functions = -{ - &Ppmd8_Construct, - &Ppmd8_Alloc, - &Ppmd8_Free, - &Ppmd8_Init, - &Ppmd8_RangeDec_Init, - &Ppmd8_DecodeSymbol, -}; diff --git a/thirdparty/libarchive/libarchive/archive_ppmd8_private.h b/thirdparty/libarchive/libarchive/archive_ppmd8_private.h deleted file mode 100644 index 454b75f41..000000000 --- a/thirdparty/libarchive/libarchive/archive_ppmd8_private.h +++ /dev/null @@ -1,148 +0,0 @@ -/* Ppmd8.h -- PPMdI codec -2011-01-27 : Igor Pavlov : Public domain -This code is based on: - PPMd var.I (2002): Dmitry Shkarin : Public domain - Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ - -#ifndef ARCHIVE_PPMD8_PRIVATE_H_INCLUDED -#define ARCHIVE_PPMD8_PRIVATE_H_INCLUDED - -#include "archive_ppmd_private.h" - -#define PPMD8_MIN_ORDER 2 -#define PPMD8_MAX_ORDER 16 - -struct CPpmd8_Context_; - -typedef - #ifdef PPMD_32BIT - struct CPpmd8_Context_ * - #else - UInt32 - #endif - CPpmd8_Context_Ref; - -#pragma pack(push, 1) - -typedef struct CPpmd8_Context_ -{ - Byte NumStats; - Byte Flags; - UInt16 SummFreq; - CPpmd_State_Ref Stats; - CPpmd8_Context_Ref Suffix; -} CPpmd8_Context; - -#pragma pack(pop) - -#define Ppmd8Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq) - -/* The BUG in Shkarin's code for FREEZE mode was fixed, but that fixed - code is not compatible with original code for some files compressed - in FREEZE mode. So we disable FREEZE mode support. */ - -enum -{ - PPMD8_RESTORE_METHOD_RESTART, - PPMD8_RESTORE_METHOD_CUT_OFF - #ifdef PPMD8_FREEZE_SUPPORT - , PPMD8_RESTORE_METHOD_FREEZE - #endif -}; - -typedef struct -{ - CPpmd8_Context *MinContext, *MaxContext; - CPpmd_State *FoundState; - unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder; - Int32 RunLength, InitRL; /* must be 32-bit at least */ - - UInt32 Size; - UInt32 GlueCount; - Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart; - UInt32 AlignOffset; - unsigned RestoreMethod; - - /* Range Coder */ - UInt32 Range; - UInt32 Code; - UInt32 Low; - union - { - IByteIn *In; - IByteOut *Out; - } Stream; - - Byte Indx2Units[PPMD_NUM_INDEXES]; - Byte Units2Indx[128]; - CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES]; - UInt32 Stamps[PPMD_NUM_INDEXES]; - - Byte NS2BSIndx[256], NS2Indx[260]; - CPpmd_See DummySee, See[24][32]; - UInt16 BinSumm[25][64]; -} CPpmd8; - -void Ppmd8_Construct(CPpmd8 *p); -Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size); -void Ppmd8_Free(CPpmd8 *p); -void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod); -#define Ppmd8_WasAllocated(p) ((p)->Base != NULL) - - -/* ---------- Internal Functions ---------- */ - -extern const Byte PPMD8_kExpEscape[16]; - -#ifdef PPMD_32BIT - #define Ppmd8_GetPtr(p, ptr) (ptr) - #define Ppmd8_GetContext(p, ptr) (ptr) - #define Ppmd8_GetStats(p, ctx) ((ctx)->Stats) -#else - #define Ppmd8_GetPtr(p, offs) ((void *)((p)->Base + (offs))) - #define Ppmd8_GetContext(p, offs) ((CPpmd8_Context *)Ppmd8_GetPtr((p), (offs))) - #define Ppmd8_GetStats(p, ctx) ((CPpmd_State *)Ppmd8_GetPtr((p), ((ctx)->Stats))) -#endif - -void Ppmd8_Update1(CPpmd8 *p); -void Ppmd8_Update1_0(CPpmd8 *p); -void Ppmd8_Update2(CPpmd8 *p); -void Ppmd8_UpdateBin(CPpmd8 *p); - -#define Ppmd8_GetBinSumm(p) \ - &p->BinSumm[p->NS2Indx[Ppmd8Context_OneState(p->MinContext)->Freq - 1]][ \ - p->NS2BSIndx[Ppmd8_GetContext(p, p->MinContext->Suffix)->NumStats] + \ - p->PrevSuccess + p->MinContext->Flags + ((p->RunLength >> 26) & 0x20)] - -CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked, UInt32 *scale); - - -/* ---------- Decode ---------- */ - -Bool Ppmd8_RangeDec_Init(CPpmd8 *p); -#define Ppmd8_RangeDec_IsFinishedOK(p) ((p)->Code == 0) -int Ppmd8_DecodeSymbol(CPpmd8 *p); /* returns: -1 as EndMarker, -2 as DataError */ - -/* ---------- Encode ---------- */ - -#define Ppmd8_RangeEnc_Init(p) { (p)->Low = 0; (p)->Range = 0xFFFFFFFF; } -void Ppmd8_RangeEnc_FlushData(CPpmd8 *p); -void Ppmd8_EncodeSymbol(CPpmd8 *p, int symbol); /* symbol = -1 means EndMarker */ - -typedef struct -{ - /* Base Functions */ - void (*Ppmd8_Construct)(CPpmd8 *p); - Bool (*Ppmd8_Alloc)(CPpmd8 *p, UInt32 size); - void (*Ppmd8_Free)(CPpmd8 *p); - void (*Ppmd8_Init)(CPpmd8 *p, unsigned max_order, unsigned restore_method); - #define Ppmd7_WasAllocated(p) ((p)->Base != NULL) - - /* Decode Functions */ - int (*Ppmd8_RangeDec_Init)(CPpmd8 *p); - int (*Ppmd8_DecodeSymbol)(CPpmd8 *p); -} IPpmd8; - -extern const IPpmd8 __archive_ppmd8_functions; - -#endif diff --git a/thirdparty/libarchive/libarchive/archive_ppmd_private.h b/thirdparty/libarchive/libarchive/archive_ppmd_private.h deleted file mode 100644 index 582803e5f..000000000 --- a/thirdparty/libarchive/libarchive/archive_ppmd_private.h +++ /dev/null @@ -1,151 +0,0 @@ -/* Ppmd.h -- PPMD codec common code -2010-03-12 : Igor Pavlov : Public domain -This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ - -#ifndef ARCHIVE_PPMD_PRIVATE_H_INCLUDED -#define ARCHIVE_PPMD_PRIVATE_H_INCLUDED - -#ifndef __LIBARCHIVE_BUILD -#error This header is only to be used internally to libarchive. -#endif - -#include - -#include "archive_read_private.h" - -/*** Begin defined in Types.h ***/ - -#if !defined(ZCONF_H) -typedef unsigned char Byte; -#endif -typedef short Int16; -typedef unsigned short UInt16; - -#ifdef _LZMA_UINT32_IS_ULONG -typedef long Int32; -typedef unsigned long UInt32; -#else -typedef int Int32; -typedef unsigned int UInt32; -#endif - -#ifdef _SZ_NO_INT_64 - -/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. - NOTES: Some code will work incorrectly in that case! */ - -typedef long Int64; -typedef unsigned long UInt64; - -#else - -#if defined(_MSC_VER) || defined(__BORLANDC__) -typedef __int64 Int64; -typedef unsigned __int64 UInt64; -#define UINT64_CONST(n) n -#else -typedef long long int Int64; -typedef unsigned long long int UInt64; -#define UINT64_CONST(n) n ## ULL -#endif - -#endif - -typedef int Bool; -#define True 1 -#define False 0 - -/* The following interfaces use first parameter as pointer to structure */ - -typedef struct -{ - struct archive_read *a; - Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */ -} IByteIn; - -typedef struct -{ - struct archive_write *a; - void (*Write)(void *p, Byte b); -} IByteOut; - -/*** End defined in Types.h ***/ -/*** Begin defined in CpuArch.h ***/ - -#if defined(_M_IX86) || defined(__i386__) -#define MY_CPU_X86 -#endif - -#if defined(MY_CPU_X86) || defined(_M_ARM) -#define MY_CPU_32BIT -#endif - -#ifdef MY_CPU_32BIT -#define PPMD_32BIT -#endif - -/*** End defined in CpuArch.h ***/ - -#define PPMD_INT_BITS 7 -#define PPMD_PERIOD_BITS 7 -#define PPMD_BIN_SCALE (1 << (PPMD_INT_BITS + PPMD_PERIOD_BITS)) - -#define PPMD_GET_MEAN_SPEC(summ, shift, round) (((summ) + (1 << ((shift) - (round)))) >> (shift)) -#define PPMD_GET_MEAN(summ) PPMD_GET_MEAN_SPEC((summ), PPMD_PERIOD_BITS, 2) -#define PPMD_UPDATE_PROB_0(prob) ((prob) + (1 << PPMD_INT_BITS) - PPMD_GET_MEAN(prob)) -#define PPMD_UPDATE_PROB_1(prob) ((prob) - PPMD_GET_MEAN(prob)) - -#define PPMD_N1 4 -#define PPMD_N2 4 -#define PPMD_N3 4 -#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4) -#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4) - -/* SEE-contexts for PPM-contexts with masked symbols */ -typedef struct -{ - UInt16 Summ; /* Freq */ - Byte Shift; /* Speed of Freq change; low Shift is for fast change */ - Byte Count; /* Count to next change of Shift */ -} CPpmd_See; - -#define Ppmd_See_Update(p) if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \ - { (p)->Summ <<= 1; (p)->Count = (Byte)(3 << (p)->Shift++); } - -typedef struct -{ - Byte Symbol; - Byte Freq; - UInt16 SuccessorLow; - UInt16 SuccessorHigh; -} CPpmd_State; - -typedef - #ifdef PPMD_32BIT - CPpmd_State * - #else - UInt32 - #endif - CPpmd_State_Ref; - -typedef - #ifdef PPMD_32BIT - void * - #else - UInt32 - #endif - CPpmd_Void_Ref; - -typedef - #ifdef PPMD_32BIT - Byte * - #else - UInt32 - #endif - CPpmd_Byte_Ref; - -#define PPMD_SetAllBitsIn256Bytes(p) \ - { unsigned j; for (j = 0; j < 256 / sizeof(p[0]); j += 8) { \ - p[j+7] = p[j+6] = p[j+5] = p[j+4] = p[j+3] = p[j+2] = p[j+1] = p[j+0] = ~(size_t)0; }} - -#endif diff --git a/thirdparty/libarchive/libarchive/archive_private.h b/thirdparty/libarchive/libarchive/archive_private.h deleted file mode 100644 index b2a2cda25..000000000 --- a/thirdparty/libarchive/libarchive/archive_private.h +++ /dev/null @@ -1,180 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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: head/lib/libarchive/archive_private.h 201098 2009-12-28 02:58:14Z kientzle $ - */ - -#ifndef ARCHIVE_PRIVATE_H_INCLUDED -#define ARCHIVE_PRIVATE_H_INCLUDED - -#ifndef __LIBARCHIVE_BUILD -#error This header is only to be used internally to libarchive. -#endif - -#if HAVE_ICONV_H -#include -#endif - -#include "archive.h" -#include "archive_string.h" - -#if defined(__GNUC__) && (__GNUC__ > 2 || \ - (__GNUC__ == 2 && __GNUC_MINOR__ >= 5)) -#define __LA_DEAD __attribute__((__noreturn__)) -#else -#define __LA_DEAD -#endif - -#if defined(__GNUC__) && (__GNUC__ > 2 || \ - (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)) -#define __LA_UNUSED __attribute__((__unused__)) -#else -#define __LA_UNUSED -#endif - -#define ARCHIVE_WRITE_MAGIC (0xb0c5c0deU) -#define ARCHIVE_READ_MAGIC (0xdeb0c5U) -#define ARCHIVE_WRITE_DISK_MAGIC (0xc001b0c5U) -#define ARCHIVE_READ_DISK_MAGIC (0xbadb0c5U) -#define ARCHIVE_MATCH_MAGIC (0xcad11c9U) - -#define ARCHIVE_STATE_NEW 1U -#define ARCHIVE_STATE_HEADER 2U -#define ARCHIVE_STATE_DATA 4U -#define ARCHIVE_STATE_EOF 0x10U -#define ARCHIVE_STATE_CLOSED 0x20U -#define ARCHIVE_STATE_FATAL 0x8000U -#define ARCHIVE_STATE_ANY (0xFFFFU & ~ARCHIVE_STATE_FATAL) - -struct archive_vtable { - int (*archive_close)(struct archive *); - int (*archive_free)(struct archive *); - int (*archive_write_header)(struct archive *, - struct archive_entry *); - int (*archive_write_finish_entry)(struct archive *); - ssize_t (*archive_write_data)(struct archive *, - const void *, size_t); - ssize_t (*archive_write_data_block)(struct archive *, - const void *, size_t, int64_t); - - int (*archive_read_next_header)(struct archive *, - struct archive_entry **); - int (*archive_read_next_header2)(struct archive *, - struct archive_entry *); - int (*archive_read_data_block)(struct archive *, - const void **, size_t *, int64_t *); - - int (*archive_filter_count)(struct archive *); - int64_t (*archive_filter_bytes)(struct archive *, int); - int (*archive_filter_code)(struct archive *, int); - const char * (*archive_filter_name)(struct archive *, int); -}; - -struct archive_string_conv; - -struct archive { - /* - * The magic/state values are used to sanity-check the - * client's usage. If an API function is called at a - * ridiculous time, or the client passes us an invalid - * pointer, these values allow me to catch that. - */ - unsigned int magic; - unsigned int state; - - /* - * Some public API functions depend on the "real" type of the - * archive object. - */ - const struct archive_vtable *vtable; - - int archive_format; - const char *archive_format_name; - - /* Number of file entries processed. */ - int file_count; - - int archive_error_number; - const char *error; - struct archive_string error_string; - - char *current_code; - unsigned current_codepage; /* Current ACP(ANSI CodePage). */ - unsigned current_oemcp; /* Current OEMCP(OEM CodePage). */ - struct archive_string_conv *sconv; - - /* - * Used by archive_read_data() to track blocks and copy - * data to client buffers, filling gaps with zero bytes. - */ - const char *read_data_block; - int64_t read_data_offset; - int64_t read_data_output_offset; - size_t read_data_remaining; - - /* - * Used by formats/filters to determine the amount of data - * requested from a call to archive_read_data(). This is only - * useful when the format/filter has seek support. - */ - char read_data_is_posix_read; - size_t read_data_requested; -}; - -/* Check magic value and state; return(ARCHIVE_FATAL) if it isn't valid. */ -int __archive_check_magic(struct archive *, unsigned int magic, - unsigned int state, const char *func); -#define archive_check_magic(a, expected_magic, allowed_states, function_name) \ - do { \ - int magic_test = __archive_check_magic((a), (expected_magic), \ - (allowed_states), (function_name)); \ - if (magic_test == ARCHIVE_FATAL) \ - return ARCHIVE_FATAL; \ - } while (0) - -void __archive_errx(int retvalue, const char *msg) __LA_DEAD; - -void __archive_ensure_cloexec_flag(int fd); -int __archive_mktemp(const char *tmpdir); -#if defined(_WIN32) && !defined(__CYGWIN__) -int __archive_mkstemp(wchar_t *template); -#else -int __archive_mkstemp(char *template); -#endif - -int __archive_clean(struct archive *); - -void __archive_reset_read_data(struct archive *); - -#define err_combine(a,b) ((a) < (b) ? (a) : (b)) - -#if defined(__BORLANDC__) || (defined(_MSC_VER) && _MSC_VER <= 1300) -# define ARCHIVE_LITERAL_LL(x) x##i64 -# define ARCHIVE_LITERAL_ULL(x) x##ui64 -#else -# define ARCHIVE_LITERAL_LL(x) x##ll -# define ARCHIVE_LITERAL_ULL(x) x##ull -#endif - -#endif diff --git a/thirdparty/libarchive/libarchive/archive_random.c b/thirdparty/libarchive/libarchive/archive_random.c deleted file mode 100644 index a410dc089..000000000 --- a/thirdparty/libarchive/libarchive/archive_random.c +++ /dev/null @@ -1,301 +0,0 @@ -/*- - * Copyright (c) 2014 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_STDLIB_H -#include -#endif - -#if !defined(HAVE_ARC4RANDOM_BUF) && (!defined(_WIN32) || defined(__CYGWIN__)) - -#ifdef HAVE_FCNTL -#include -#endif -#ifdef HAVE_LIMITS_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_TIME_H -#include -#endif -#ifdef HAVE_PTHREAD_H -#include -#endif - -static void la_arc4random_buf(void *, size_t); - -#endif /* HAVE_ARC4RANDOM_BUF */ - -#include "archive.h" -#include "archive_random_private.h" - -#if defined(_WIN32) && !defined(__CYGWIN__) -#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA -/* don't use bcrypt when XP needs to be supported */ -#include - -/* Common in other bcrypt implementations, but missing from VS2008. */ -#ifndef BCRYPT_SUCCESS -#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS) -#endif - -#elif defined(HAVE_WINCRYPT_H) -#include -#endif -#endif - -#ifndef O_CLOEXEC -#define O_CLOEXEC 0 -#endif - -/* - * Random number generator function. - * This simply calls arc4random_buf function if the platform provides it. - */ - -int -archive_random(void *buf, size_t nbytes) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) -# if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA - NTSTATUS status; - BCRYPT_ALG_HANDLE hAlg; - - status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_RNG_ALGORITHM, NULL, 0); - if (!BCRYPT_SUCCESS(status)) - return ARCHIVE_FAILED; - status = BCryptGenRandom(hAlg, buf, (ULONG)nbytes, 0); - BCryptCloseAlgorithmProvider(hAlg, 0); - if (!BCRYPT_SUCCESS(status)) - return ARCHIVE_FAILED; - - return ARCHIVE_OK; -# else - HCRYPTPROV hProv; - BOOL success; - - success = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT); - if (!success && GetLastError() == (DWORD)NTE_BAD_KEYSET) { - success = CryptAcquireContext(&hProv, NULL, NULL, - PROV_RSA_FULL, CRYPT_NEWKEYSET); - } - if (success) { - success = CryptGenRandom(hProv, (DWORD)nbytes, (BYTE*)buf); - CryptReleaseContext(hProv, 0); - if (success) - return ARCHIVE_OK; - } - /* TODO: Does this case really happen? */ - return ARCHIVE_FAILED; -# endif -#elif !defined(HAVE_ARC4RANDOM_BUF) && (!defined(_WIN32) || defined(__CYGWIN__)) - la_arc4random_buf(buf, nbytes); - return ARCHIVE_OK; -#else - arc4random_buf(buf, nbytes); - return ARCHIVE_OK; -#endif -} - -#if !defined(HAVE_ARC4RANDOM_BUF) && (!defined(_WIN32) || defined(__CYGWIN__)) - -/* $OpenBSD: arc4random.c,v 1.24 2013/06/11 16:59:50 deraadt Exp $ */ -/* - * Copyright (c) 1996, David Mazieres - * Copyright (c) 2008, Damien Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * Arc4 random number generator for OpenBSD. - * - * This code is derived from section 17.1 of Applied Cryptography, - * second edition, which describes a stream cipher allegedly - * compatible with RSA Labs "RC4" cipher (the actual description of - * which is a trade secret). The same algorithm is used as a stream - * cipher called "arcfour" in Tatu Ylonen's ssh package. - * - * RC4 is a registered trademark of RSA Laboratories. - */ - -#ifdef __GNUC__ -#define inline __inline -#else /* !__GNUC__ */ -#define inline -#endif /* !__GNUC__ */ - -struct arc4_stream { - uint8_t i; - uint8_t j; - uint8_t s[256]; -}; - -#define RANDOMDEV "/dev/urandom" -#define KEYSIZE 128 -#ifdef HAVE_PTHREAD_H -static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER; -#define _ARC4_LOCK() pthread_mutex_lock(&arc4random_mtx); -#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx); -#else -#define _ARC4_LOCK() -#define _ARC4_UNLOCK() -#endif - -static int rs_initialized; -static struct arc4_stream rs; -static pid_t arc4_stir_pid; -static int arc4_count; - -static inline uint8_t arc4_getbyte(void); -static void arc4_stir(void); - -static inline void -arc4_init(void) -{ - int n; - - for (n = 0; n < 256; n++) - rs.s[n] = n; - rs.i = 0; - rs.j = 0; -} - -static inline void -arc4_addrandom(uint8_t *dat, int datlen) -{ - int n; - uint8_t si; - - rs.i--; - for (n = 0; n < 256; n++) { - rs.i = (rs.i + 1); - si = rs.s[rs.i]; - rs.j = (rs.j + si + dat[n % datlen]); - rs.s[rs.i] = rs.s[rs.j]; - rs.s[rs.j] = si; - } - rs.j = rs.i; -} - -static void -arc4_stir(void) -{ - int done, fd, i; - struct { - struct timeval tv; - pid_t pid; - uint8_t rnd[KEYSIZE]; - } rdat; - - if (!rs_initialized) { - arc4_init(); - rs_initialized = 1; - } - done = 0; - fd = open(RANDOMDEV, O_RDONLY | O_CLOEXEC, 0); - if (fd >= 0) { - if (read(fd, &rdat, KEYSIZE) == KEYSIZE) - done = 1; - (void)close(fd); - } - if (!done) { - (void)gettimeofday(&rdat.tv, NULL); - rdat.pid = getpid(); - /* We'll just take whatever was on the stack too... */ - } - - arc4_addrandom((uint8_t *)&rdat, KEYSIZE); - - /* - * Discard early keystream, as per recommendations in: - * "(Not So) Random Shuffles of RC4" by Ilya Mironov. - * As per the Network Operations Division, cryptographic requirements - * published on wikileaks on March 2017. - */ - - for (i = 0; i < 3072; i++) - (void)arc4_getbyte(); - arc4_count = 1600000; -} - -static void -arc4_stir_if_needed(void) -{ - pid_t pid = getpid(); - - if (arc4_count <= 0 || !rs_initialized || arc4_stir_pid != pid) { - arc4_stir_pid = pid; - arc4_stir(); - } -} - -static inline uint8_t -arc4_getbyte(void) -{ - uint8_t si, sj; - - rs.i = (rs.i + 1); - si = rs.s[rs.i]; - rs.j = (rs.j + si); - sj = rs.s[rs.j]; - rs.s[rs.i] = sj; - rs.s[rs.j] = si; - return (rs.s[(si + sj) & 0xff]); -} - -static void -la_arc4random_buf(void *_buf, size_t n) -{ - uint8_t *buf = (uint8_t *)_buf; - _ARC4_LOCK(); - arc4_stir_if_needed(); - while (n--) { - if (--arc4_count <= 0) - arc4_stir(); - buf[n] = arc4_getbyte(); - } - _ARC4_UNLOCK(); -} - -#endif /* !HAVE_ARC4RANDOM_BUF */ diff --git a/thirdparty/libarchive/libarchive/archive_random_private.h b/thirdparty/libarchive/libarchive/archive_random_private.h deleted file mode 100644 index 08b91b3b7..000000000 --- a/thirdparty/libarchive/libarchive/archive_random_private.h +++ /dev/null @@ -1,36 +0,0 @@ -/*- - * Copyright (c) 2014 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#ifndef ARCHIVE_RANDOM_PRIVATE_H_INCLUDED -#define ARCHIVE_RANDOM_PRIVATE_H_INCLUDED - -#ifndef __LIBARCHIVE_BUILD -#error This header is only to be used internally to libarchive. -#endif - -/* Random number generator. */ -int archive_random(void *buf, size_t nbytes); - -#endif /* ARCHIVE_RANDOM_PRIVATE_H_INCLUDED */ diff --git a/thirdparty/libarchive/libarchive/archive_rb.c b/thirdparty/libarchive/libarchive/archive_rb.c deleted file mode 100644 index cf58ac335..000000000 --- a/thirdparty/libarchive/libarchive/archive_rb.c +++ /dev/null @@ -1,709 +0,0 @@ -/*- - * Copyright (c) 2001 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Matt Thomas . - * - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``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 FOUNDATION OR CONTRIBUTORS - * 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. - * - * Based on: NetBSD: rb.c,v 1.6 2010/04/30 13:58:09 joerg Exp - */ - -#include "archive_platform.h" - -#include - -#include "archive_rb.h" - -/* Keep in sync with archive_rb.h */ -#define RB_DIR_LEFT 0 -#define RB_DIR_RIGHT 1 -#define RB_DIR_OTHER 1 -#define rb_left rb_nodes[RB_DIR_LEFT] -#define rb_right rb_nodes[RB_DIR_RIGHT] - -#define RB_FLAG_POSITION 0x2 -#define RB_FLAG_RED 0x1 -#define RB_FLAG_MASK (RB_FLAG_POSITION|RB_FLAG_RED) -#define RB_FATHER(rb) \ - ((struct archive_rb_node *)((rb)->rb_info & ~RB_FLAG_MASK)) -#define RB_SET_FATHER(rb, father) \ - ((void)((rb)->rb_info = (uintptr_t)(father)|((rb)->rb_info & RB_FLAG_MASK))) - -#define RB_SENTINEL_P(rb) ((rb) == NULL) -#define RB_LEFT_SENTINEL_P(rb) RB_SENTINEL_P((rb)->rb_left) -#define RB_RIGHT_SENTINEL_P(rb) RB_SENTINEL_P((rb)->rb_right) -#define RB_FATHER_SENTINEL_P(rb) RB_SENTINEL_P(RB_FATHER((rb))) -#define RB_CHILDLESS_P(rb) \ - (RB_SENTINEL_P(rb) || (RB_LEFT_SENTINEL_P(rb) && RB_RIGHT_SENTINEL_P(rb))) -#define RB_TWOCHILDREN_P(rb) \ - (!RB_SENTINEL_P(rb) && !RB_LEFT_SENTINEL_P(rb) && !RB_RIGHT_SENTINEL_P(rb)) - -#define RB_POSITION(rb) \ - (((rb)->rb_info & RB_FLAG_POSITION) ? RB_DIR_RIGHT : RB_DIR_LEFT) -#define RB_RIGHT_P(rb) (RB_POSITION(rb) == RB_DIR_RIGHT) -#define RB_LEFT_P(rb) (RB_POSITION(rb) == RB_DIR_LEFT) -#define RB_RED_P(rb) (!RB_SENTINEL_P(rb) && ((rb)->rb_info & RB_FLAG_RED) != 0) -#define RB_BLACK_P(rb) (RB_SENTINEL_P(rb) || ((rb)->rb_info & RB_FLAG_RED) == 0) -#define RB_MARK_RED(rb) ((void)((rb)->rb_info |= RB_FLAG_RED)) -#define RB_MARK_BLACK(rb) ((void)((rb)->rb_info &= ~RB_FLAG_RED)) -#define RB_INVERT_COLOR(rb) ((void)((rb)->rb_info ^= RB_FLAG_RED)) -#define RB_ROOT_P(rbt, rb) ((rbt)->rbt_root == (rb)) -#define RB_SET_POSITION(rb, position) \ - ((void)((position) ? ((rb)->rb_info |= RB_FLAG_POSITION) : \ - ((rb)->rb_info &= ~RB_FLAG_POSITION))) -#define RB_ZERO_PROPERTIES(rb) ((void)((rb)->rb_info &= ~RB_FLAG_MASK)) -#define RB_COPY_PROPERTIES(dst, src) \ - ((void)((dst)->rb_info ^= ((dst)->rb_info ^ (src)->rb_info) & RB_FLAG_MASK)) -#define RB_SWAP_PROPERTIES(a, b) do { \ - uintptr_t xorinfo = ((a)->rb_info ^ (b)->rb_info) & RB_FLAG_MASK; \ - (a)->rb_info ^= xorinfo; \ - (b)->rb_info ^= xorinfo; \ - } while (/*CONSTCOND*/ 0) - -static void __archive_rb_tree_insert_rebalance(struct archive_rb_tree *, - struct archive_rb_node *); -static void __archive_rb_tree_removal_rebalance(struct archive_rb_tree *, - struct archive_rb_node *, unsigned int); - -#define RB_SENTINEL_NODE NULL - -#define T 1 -#define F 0 - -void -__archive_rb_tree_init(struct archive_rb_tree *rbt, - const struct archive_rb_tree_ops *ops) -{ - rbt->rbt_ops = ops; - *((struct archive_rb_node **)&rbt->rbt_root) = RB_SENTINEL_NODE; -} - -struct archive_rb_node * -__archive_rb_tree_find_node(struct archive_rb_tree *rbt, const void *key) -{ - archive_rbto_compare_key_fn compare_key = rbt->rbt_ops->rbto_compare_key; - struct archive_rb_node *parent = rbt->rbt_root; - - while (!RB_SENTINEL_P(parent)) { - const signed int diff = (*compare_key)(parent, key); - if (diff == 0) - return parent; - parent = parent->rb_nodes[diff > 0]; - } - - return NULL; -} - -struct archive_rb_node * -__archive_rb_tree_find_node_geq(struct archive_rb_tree *rbt, const void *key) -{ - archive_rbto_compare_key_fn compare_key = rbt->rbt_ops->rbto_compare_key; - struct archive_rb_node *parent = rbt->rbt_root; - struct archive_rb_node *last = NULL; - - while (!RB_SENTINEL_P(parent)) { - const signed int diff = (*compare_key)(parent, key); - if (diff == 0) - return parent; - if (diff < 0) - last = parent; - parent = parent->rb_nodes[diff > 0]; - } - - return last; -} - -struct archive_rb_node * -__archive_rb_tree_find_node_leq(struct archive_rb_tree *rbt, const void *key) -{ - archive_rbto_compare_key_fn compare_key = rbt->rbt_ops->rbto_compare_key; - struct archive_rb_node *parent = rbt->rbt_root; - struct archive_rb_node *last = NULL; - - while (!RB_SENTINEL_P(parent)) { - const signed int diff = (*compare_key)(parent, key); - if (diff == 0) - return parent; - if (diff > 0) - last = parent; - parent = parent->rb_nodes[diff > 0]; - } - - return last; -} - -int -__archive_rb_tree_insert_node(struct archive_rb_tree *rbt, - struct archive_rb_node *self) -{ - archive_rbto_compare_nodes_fn compare_nodes = rbt->rbt_ops->rbto_compare_nodes; - struct archive_rb_node *parent, *tmp; - unsigned int position; - int rebalance; - - tmp = rbt->rbt_root; - /* - * This is a hack. Because rbt->rbt_root is just a - * struct archive_rb_node *, just like rb_node->rb_nodes[RB_DIR_LEFT], - * we can use this fact to avoid a lot of tests for root and know - * that even at root, updating - * RB_FATHER(rb_node)->rb_nodes[RB_POSITION(rb_node)] will - * update rbt->rbt_root. - */ - parent = (struct archive_rb_node *)(void *)&rbt->rbt_root; - position = RB_DIR_LEFT; - - /* - * Find out where to place this new leaf. - */ - while (!RB_SENTINEL_P(tmp)) { - const signed int diff = (*compare_nodes)(tmp, self); - if (diff == 0) { - /* - * Node already exists; don't insert. - */ - return F; - } - parent = tmp; - position = (diff > 0); - tmp = parent->rb_nodes[position]; - } - - /* - * Initialize the node and insert as a leaf into the tree. - */ - RB_SET_FATHER(self, parent); - RB_SET_POSITION(self, position); - if (parent == (struct archive_rb_node *)(void *)&rbt->rbt_root) { - RB_MARK_BLACK(self); /* root is always black */ - rebalance = F; - } else { - /* - * All new nodes are colored red. We only need to rebalance - * if our parent is also red. - */ - RB_MARK_RED(self); - rebalance = RB_RED_P(parent); - } - self->rb_left = parent->rb_nodes[position]; - self->rb_right = parent->rb_nodes[position]; - parent->rb_nodes[position] = self; - - /* - * Rebalance tree after insertion - */ - if (rebalance) - __archive_rb_tree_insert_rebalance(rbt, self); - - return T; -} - -/* - * Swap the location and colors of 'self' and its child @ which. The child - * can not be a sentinel node. This is our rotation function. However, - * since it preserves coloring, it great simplifies both insertion and - * removal since rotation almost always involves the exchanging of colors - * as a separate step. - */ -/*ARGSUSED*/ -static void -__archive_rb_tree_reparent_nodes( - struct archive_rb_node *old_father, const unsigned int which) -{ - const unsigned int other = which ^ RB_DIR_OTHER; - struct archive_rb_node * const grandpa = RB_FATHER(old_father); - struct archive_rb_node * const old_child = old_father->rb_nodes[which]; - struct archive_rb_node * const new_father = old_child; - struct archive_rb_node * const new_child = old_father; - - if (new_father == NULL) - return; - /* - * Exchange descendant linkages. - */ - grandpa->rb_nodes[RB_POSITION(old_father)] = new_father; - new_child->rb_nodes[which] = old_child->rb_nodes[other]; - new_father->rb_nodes[other] = new_child; - - /* - * Update ancestor linkages - */ - RB_SET_FATHER(new_father, grandpa); - RB_SET_FATHER(new_child, new_father); - - /* - * Exchange properties between new_father and new_child. The only - * change is that new_child's position is now on the other side. - */ - RB_SWAP_PROPERTIES(new_father, new_child); - RB_SET_POSITION(new_child, other); - - /* - * Make sure to reparent the new child to ourself. - */ - if (!RB_SENTINEL_P(new_child->rb_nodes[which])) { - RB_SET_FATHER(new_child->rb_nodes[which], new_child); - RB_SET_POSITION(new_child->rb_nodes[which], which); - } - -} - -static void -__archive_rb_tree_insert_rebalance(struct archive_rb_tree *rbt, - struct archive_rb_node *self) -{ - struct archive_rb_node * father = RB_FATHER(self); - struct archive_rb_node * grandpa; - struct archive_rb_node * uncle; - unsigned int which; - unsigned int other; - - for (;;) { - /* - * We are red and our parent is red, therefore we must have a - * grandfather and he must be black. - */ - grandpa = RB_FATHER(father); - which = (father == grandpa->rb_right); - other = which ^ RB_DIR_OTHER; - uncle = grandpa->rb_nodes[other]; - - if (RB_BLACK_P(uncle)) - break; - - /* - * Case 1: our uncle is red - * Simply invert the colors of our parent and - * uncle and make our grandparent red. And - * then solve the problem up at his level. - */ - RB_MARK_BLACK(uncle); - RB_MARK_BLACK(father); - if (RB_ROOT_P(rbt, grandpa)) { - /* - * If our grandpa is root, don't bother - * setting him to red, just return. - */ - return; - } - RB_MARK_RED(grandpa); - self = grandpa; - father = RB_FATHER(self); - if (RB_BLACK_P(father)) { - /* - * If our great-grandpa is black, we're done. - */ - return; - } - } - - /* - * Case 2&3: our uncle is black. - */ - if (self == father->rb_nodes[other]) { - /* - * Case 2: we are on the same side as our uncle - * Swap ourselves with our parent so this case - * becomes case 3. Basically our parent becomes our - * child. - */ - __archive_rb_tree_reparent_nodes(father, other); - } - /* - * Case 3: we are opposite a child of a black uncle. - * Swap our parent and grandparent. Since our grandfather - * is black, our father will become black and our new sibling - * (former grandparent) will become red. - */ - __archive_rb_tree_reparent_nodes(grandpa, which); - - /* - * Final step: Set the root to black. - */ - RB_MARK_BLACK(rbt->rbt_root); -} - -static void -__archive_rb_tree_prune_node(struct archive_rb_tree *rbt, - struct archive_rb_node *self, int rebalance) -{ - const unsigned int which = RB_POSITION(self); - struct archive_rb_node *father = RB_FATHER(self); - - /* - * Since we are childless, we know that self->rb_left is pointing - * to the sentinel node. - */ - father->rb_nodes[which] = self->rb_left; - - /* - * Rebalance if requested. - */ - if (rebalance) - __archive_rb_tree_removal_rebalance(rbt, father, which); -} - -/* - * When deleting an interior node - */ -static void -__archive_rb_tree_swap_prune_and_rebalance(struct archive_rb_tree *rbt, - struct archive_rb_node *self, struct archive_rb_node *standin) -{ - const unsigned int standin_which = RB_POSITION(standin); - unsigned int standin_other = standin_which ^ RB_DIR_OTHER; - struct archive_rb_node *standin_son; - struct archive_rb_node *standin_father = RB_FATHER(standin); - int rebalance = RB_BLACK_P(standin); - - if (standin_father == self) { - /* - * As a child of self, any children would be opposite of - * our parent. - */ - standin_son = standin->rb_nodes[standin_which]; - } else { - /* - * Since we aren't a child of self, any children would be - * on the same side as our parent. - */ - standin_son = standin->rb_nodes[standin_other]; - } - - if (RB_RED_P(standin_son)) { - /* - * We know we have a red child so if we flip it to black - * we don't have to rebalance. - */ - RB_MARK_BLACK(standin_son); - rebalance = F; - - if (standin_father != self) { - /* - * Change the son's parentage to point to his grandpa. - */ - RB_SET_FATHER(standin_son, standin_father); - RB_SET_POSITION(standin_son, standin_which); - } - } - - if (standin_father == self) { - /* - * If we are about to delete the standin's father, then when - * we call rebalance, we need to use ourselves as our father. - * Otherwise remember our original father. Also, since we are - * our standin's father we only need to reparent the standin's - * brother. - * - * | R --> S | - * | Q S --> Q T | - * | t --> | - * - * Have our son/standin adopt his brother as his new son. - */ - standin_father = standin; - } else { - /* - * | R --> S . | - * | / \ | T --> / \ | / | - * | ..... | S --> ..... | T | - * - * Sever standin's connection to his father. - */ - standin_father->rb_nodes[standin_which] = standin_son; - /* - * Adopt the far son. - */ - standin->rb_nodes[standin_other] = self->rb_nodes[standin_other]; - RB_SET_FATHER(standin->rb_nodes[standin_other], standin); - /* - * Use standin_other because we need to preserve standin_which - * for the removal_rebalance. - */ - standin_other = standin_which; - } - - /* - * Move the only remaining son to our standin. If our standin is our - * son, this will be the only son needed to be moved. - */ - standin->rb_nodes[standin_other] = self->rb_nodes[standin_other]; - RB_SET_FATHER(standin->rb_nodes[standin_other], standin); - - /* - * Now copy the result of self to standin and then replace - * self with standin in the tree. - */ - RB_COPY_PROPERTIES(standin, self); - RB_SET_FATHER(standin, RB_FATHER(self)); - RB_FATHER(standin)->rb_nodes[RB_POSITION(standin)] = standin; - - if (rebalance) - __archive_rb_tree_removal_rebalance(rbt, standin_father, standin_which); -} - -/* - * We could do this by doing - * __archive_rb_tree_node_swap(rbt, self, which); - * __archive_rb_tree_prune_node(rbt, self, F); - * - * But it's more efficient to just evaluate and recolor the child. - */ -static void -__archive_rb_tree_prune_blackred_branch( - struct archive_rb_node *self, unsigned int which) -{ - struct archive_rb_node *father = RB_FATHER(self); - struct archive_rb_node *son = self->rb_nodes[which]; - - /* - * Remove ourselves from the tree and give our former child our - * properties (position, color, root). - */ - RB_COPY_PROPERTIES(son, self); - father->rb_nodes[RB_POSITION(son)] = son; - RB_SET_FATHER(son, father); -} -/* - * - */ -void -__archive_rb_tree_remove_node(struct archive_rb_tree *rbt, - struct archive_rb_node *self) -{ - struct archive_rb_node *standin; - unsigned int which; - - /* - * In the following diagrams, we (the node to be removed) are S. Red - * nodes are lowercase. T could be either red or black. - * - * Remember the major axiom of the red-black tree: the number of - * black nodes from the root to each leaf is constant across all - * leaves, only the number of red nodes varies. - * - * Thus removing a red leaf doesn't require any other changes to a - * red-black tree. So if we must remove a node, attempt to rearrange - * the tree so we can remove a red node. - * - * The simplest case is a childless red node or a childless root node: - * - * | T --> T | or | R --> * | - * | s --> * | - */ - if (RB_CHILDLESS_P(self)) { - const int rebalance = RB_BLACK_P(self) && !RB_ROOT_P(rbt, self); - __archive_rb_tree_prune_node(rbt, self, rebalance); - return; - } - if (!RB_TWOCHILDREN_P(self)) { - /* - * The next simplest case is the node we are deleting is - * black and has one red child. - * - * | T --> T --> T | - * | S --> R --> R | - * | r --> s --> * | - */ - which = RB_LEFT_SENTINEL_P(self) ? RB_DIR_RIGHT : RB_DIR_LEFT; - __archive_rb_tree_prune_blackred_branch(self, which); - return; - } - - /* - * We invert these because we prefer to remove from the inside of - * the tree. - */ - which = RB_POSITION(self) ^ RB_DIR_OTHER; - - /* - * Let's find the node closes to us opposite of our parent - * Now swap it with ourself, "prune" it, and rebalance, if needed. - */ - standin = __archive_rb_tree_iterate(rbt, self, which); - __archive_rb_tree_swap_prune_and_rebalance(rbt, self, standin); -} - -static void -__archive_rb_tree_removal_rebalance(struct archive_rb_tree *rbt, - struct archive_rb_node *parent, unsigned int which) -{ - - while (RB_BLACK_P(parent->rb_nodes[which])) { - unsigned int other = which ^ RB_DIR_OTHER; - struct archive_rb_node *brother = parent->rb_nodes[other]; - - if (brother == NULL) - return;/* The tree may be broken. */ - /* - * For cases 1, 2a, and 2b, our brother's children must - * be black and our father must be black - */ - if (RB_BLACK_P(parent) - && RB_BLACK_P(brother->rb_left) - && RB_BLACK_P(brother->rb_right)) { - if (RB_RED_P(brother)) { - /* - * Case 1: Our brother is red, swap its - * position (and colors) with our parent. - * This should now be case 2b (unless C or E - * has a red child which is case 3; thus no - * explicit branch to case 2b). - * - * B -> D - * A d -> b E - * C E -> A C - */ - __archive_rb_tree_reparent_nodes(parent, other); - brother = parent->rb_nodes[other]; - if (brother == NULL) - return;/* The tree may be broken. */ - } else { - /* - * Both our parent and brother are black. - * Change our brother to red, advance up rank - * and go through the loop again. - * - * B -> *B - * *A D -> A d - * C E -> C E - */ - RB_MARK_RED(brother); - if (RB_ROOT_P(rbt, parent)) - return; /* root == parent == black */ - which = RB_POSITION(parent); - parent = RB_FATHER(parent); - continue; - } - } - /* - * Avoid an else here so that case 2a above can hit either - * case 2b, 3, or 4. - */ - if (RB_RED_P(parent) - && RB_BLACK_P(brother) - && RB_BLACK_P(brother->rb_left) - && RB_BLACK_P(brother->rb_right)) { - /* - * We are black, our father is red, our brother and - * both nephews are black. Simply invert/exchange the - * colors of our father and brother (to black and red - * respectively). - * - * | f --> F | - * | * B --> * b | - * | N N --> N N | - */ - RB_MARK_BLACK(parent); - RB_MARK_RED(brother); - break; /* We're done! */ - } else { - /* - * Our brother must be black and have at least one - * red child (it may have two). - */ - if (RB_BLACK_P(brother->rb_nodes[other])) { - /* - * Case 3: our brother is black, our near - * nephew is red, and our far nephew is black. - * Swap our brother with our near nephew. - * This result in a tree that matches case 4. - * (Our father could be red or black). - * - * | F --> F | - * | x B --> x B | - * | n --> n | - */ - __archive_rb_tree_reparent_nodes(brother, which); - brother = parent->rb_nodes[other]; - } - /* - * Case 4: our brother is black and our far nephew - * is red. Swap our father and brother locations and - * change our far nephew to black. (these can be - * done in either order so we change the color first). - * The result is a valid red-black tree and is a - * terminal case. (again we don't care about the - * father's color) - * - * If the father is red, we will get a red-black-black - * tree: - * | f -> f --> b | - * | B -> B --> F N | - * | n -> N --> | - * - * If the father is black, we will get an all black - * tree: - * | F -> F --> B | - * | B -> B --> F N | - * | n -> N --> | - * - * If we had two red nephews, then after the swap, - * our former father would have a red grandson. - */ - if (brother->rb_nodes[other] == NULL) - return;/* The tree may be broken. */ - RB_MARK_BLACK(brother->rb_nodes[other]); - __archive_rb_tree_reparent_nodes(parent, other); - break; /* We're done! */ - } - } -} - -struct archive_rb_node * -__archive_rb_tree_iterate(struct archive_rb_tree *rbt, - struct archive_rb_node *self, const unsigned int direction) -{ - const unsigned int other = direction ^ RB_DIR_OTHER; - - if (self == NULL) { - self = rbt->rbt_root; - if (RB_SENTINEL_P(self)) - return NULL; - while (!RB_SENTINEL_P(self->rb_nodes[direction])) - self = self->rb_nodes[direction]; - return self; - } - /* - * We can't go any further in this direction. We proceed up in the - * opposite direction until our parent is in direction we want to go. - */ - if (RB_SENTINEL_P(self->rb_nodes[direction])) { - while (!RB_ROOT_P(rbt, self)) { - if (other == (unsigned int)RB_POSITION(self)) - return RB_FATHER(self); - self = RB_FATHER(self); - } - return NULL; - } - - /* - * Advance down one in current direction and go down as far as possible - * in the opposite direction. - */ - self = self->rb_nodes[direction]; - while (!RB_SENTINEL_P(self->rb_nodes[other])) - self = self->rb_nodes[other]; - return self; -} diff --git a/thirdparty/libarchive/libarchive/archive_rb.h b/thirdparty/libarchive/libarchive/archive_rb.h deleted file mode 100644 index 8851f1081..000000000 --- a/thirdparty/libarchive/libarchive/archive_rb.h +++ /dev/null @@ -1,113 +0,0 @@ -/*- - * Copyright (c) 2001 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Matt Thomas . - * - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``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 FOUNDATION OR CONTRIBUTORS - * 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. - * - * Based on NetBSD: rb.h,v 1.13 2009/08/16 10:57:01 yamt Exp - */ - -#ifndef ARCHIVE_RB_H_INCLUDED -#define ARCHIVE_RB_H_INCLUDED - -struct archive_rb_node { - struct archive_rb_node *rb_nodes[2]; - /* - * rb_info contains the two flags and the parent back pointer. - * We put the two flags in the low two bits since we know that - * rb_node will have an alignment of 4 or 8 bytes. - */ - uintptr_t rb_info; -}; - -#define ARCHIVE_RB_DIR_LEFT 0 -#define ARCHIVE_RB_DIR_RIGHT 1 - -#define ARCHIVE_RB_TREE_MIN(T) \ - __archive_rb_tree_iterate((T), NULL, ARCHIVE_RB_DIR_LEFT) -#define ARCHIVE_RB_TREE_MAX(T) \ - __archive_rb_tree_iterate((T), NULL, ARCHIVE_RB_DIR_RIGHT) -#define ARCHIVE_RB_TREE_NEXT(T, N) \ - __archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_RIGHT) -#define ARCHIVE_RB_TREE_PREV(T, N) \ - __archive_rb_tree_iterate((T), (N), ARCHIVE_RB_DIR_LEFT) -#define ARCHIVE_RB_TREE_FOREACH(N, T) \ - for ((N) = ARCHIVE_RB_TREE_MIN(T); (N); \ - (N) = ARCHIVE_RB_TREE_NEXT((T), (N))) -#define ARCHIVE_RB_TREE_FOREACH_REVERSE(N, T) \ - for ((N) = ARCHIVE_RB_TREE_MAX(T); (N); \ - (N) = ARCHIVE_RB_TREE_PREV((T), (N))) -#define ARCHIVE_RB_TREE_FOREACH_SAFE(N, T, S) \ - for ((N) = ARCHIVE_RB_TREE_MIN(T); \ - (N) && ((S) = ARCHIVE_RB_TREE_NEXT((T), (N)), 1); \ - (N) = (S)) -#define ARCHIVE_RB_TREE_FOREACH_REVERSE_SAFE(N, T, S) \ - for ((N) = ARCHIVE_RB_TREE_MAX(T); \ - (N) && ((S) = ARCHIVE_RB_TREE_PREV((T), (N)), 1); \ - (N) = (S)) - -/* - * archive_rbto_compare_nodes_fn: - * return a positive value if the first node < the second node. - * return a negative value if the first node > the second node. - * return 0 if they are considered same. - * - * archive_rbto_compare_key_fn: - * return a positive value if the node < the key. - * return a negative value if the node > the key. - * return 0 if they are considered same. - */ - -typedef signed int (*const archive_rbto_compare_nodes_fn)(const struct archive_rb_node *, - const struct archive_rb_node *); -typedef signed int (*const archive_rbto_compare_key_fn)(const struct archive_rb_node *, - const void *); - -struct archive_rb_tree_ops { - archive_rbto_compare_nodes_fn rbto_compare_nodes; - archive_rbto_compare_key_fn rbto_compare_key; -}; - -struct archive_rb_tree { - struct archive_rb_node *rbt_root; - const struct archive_rb_tree_ops *rbt_ops; -}; - -void __archive_rb_tree_init(struct archive_rb_tree *, - const struct archive_rb_tree_ops *); -int __archive_rb_tree_insert_node(struct archive_rb_tree *, - struct archive_rb_node *); -struct archive_rb_node * - __archive_rb_tree_find_node(struct archive_rb_tree *, const void *); -struct archive_rb_node * - __archive_rb_tree_find_node_geq(struct archive_rb_tree *, const void *); -struct archive_rb_node * - __archive_rb_tree_find_node_leq(struct archive_rb_tree *, const void *); -void __archive_rb_tree_remove_node(struct archive_rb_tree *, struct archive_rb_node *); -struct archive_rb_node * - __archive_rb_tree_iterate(struct archive_rb_tree *, - struct archive_rb_node *, const unsigned int); - -#endif /* ARCHIVE_RB_H_*/ diff --git a/thirdparty/libarchive/libarchive/archive_read.3 b/thirdparty/libarchive/libarchive/archive_read.3 deleted file mode 100644 index cbedd0a19..000000000 --- a/thirdparty/libarchive/libarchive/archive_read.3 +++ /dev/null @@ -1,252 +0,0 @@ -.\" Copyright (c) 2003-2007 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd February 2, 2012 -.Dt ARCHIVE_READ 3 -.Os -.Sh NAME -.Nm archive_read -.Nd functions for reading streaming archives -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive.h -.Sh DESCRIPTION -These functions provide a complete API for reading streaming archives. -The general process is to first create the -.Tn struct archive -object, set options, initialize the reader, iterate over the archive -headers and associated data, then close the archive and release all -resources. -.\" -.Ss Create archive object -See -.Xr archive_read_new 3 . -.Pp -To read an archive, you must first obtain an initialized -.Tn struct archive -object from -.Fn archive_read_new . -.\" -.Ss Enable filters and formats -See -.Xr archive_read_filter 3 -and -.Xr archive_read_format 3 . -.Pp -You can then modify this object for the desired operations with the -various -.Fn archive_read_set_XXX -and -.Fn archive_read_support_XXX -functions. -In particular, you will need to invoke appropriate -.Fn archive_read_support_XXX -functions to enable the corresponding compression and format -support. -Note that these latter functions perform two distinct operations: -they cause the corresponding support code to be linked into your -program, and they enable the corresponding auto-detect code. -Unless you have specific constraints, you will generally want -to invoke -.Fn archive_read_support_filter_all -and -.Fn archive_read_support_format_all -to enable auto-detect for all formats and compression types -currently supported by the library. -.\" -.Ss Set options -See -.Xr archive_read_set_options 3 . -.\" -.Ss Open archive -See -.Xr archive_read_open 3 . -.Pp -Once you have prepared the -.Tn struct archive -object, you call -.Fn archive_read_open -to actually open the archive and prepare it for reading. -There are several variants of this function; -the most basic expects you to provide pointers to several -functions that can provide blocks of bytes from the archive. -There are convenience forms that allow you to -specify a filename, file descriptor, -.Ft "FILE *" -object, or a block of memory from which to read the archive data. -Note that the core library makes no assumptions about the -size of the blocks read; -callback functions are free to read whatever block size is -most appropriate for the medium. -.\" -.Ss Consume archive -See -.Xr archive_read_header 3 , -.Xr archive_read_data 3 -and -.Xr archive_read_extract 3 . -.Pp -Each archive entry consists of a header followed by a certain -amount of data. -You can obtain the next header with -.Fn archive_read_next_header , -which returns a pointer to an -.Tn struct archive_entry -structure with information about the current archive element. -If the entry is a regular file, then the header will be followed -by the file data. -You can use -.Fn archive_read_data -(which works much like the -.Xr read 2 -system call) -to read this data from the archive, or -.Fn archive_read_data_block -which provides a slightly more efficient interface. -You may prefer to use the higher-level -.Fn archive_read_data_skip , -which reads and discards the data for this entry, -.Fn archive_read_data_into_fd , -which copies the data to the provided file descriptor, or -.Fn archive_read_extract , -which recreates the specified entry on disk and copies data -from the archive. -In particular, note that -.Fn archive_read_extract -uses the -.Tn struct archive_entry -structure that you provide it, which may differ from the -entry just read from the archive. -In particular, many applications will want to override the -pathname, file permissions, or ownership. -.\" -.Ss Release resources -See -.Xr archive_read_free 3 . -.Pp -Once you have finished reading data from the archive, you -should call -.Fn archive_read_close -to close the archive, then call -.Fn archive_read_free -to release all resources, including all memory allocated by the library. -.\" -.Sh EXAMPLES -The following illustrates basic usage of the library. -In this example, -the callback functions are simply wrappers around the standard -.Xr open 2 , -.Xr read 2 , -and -.Xr close 2 -system calls. -.Bd -literal -offset indent -void -list_archive(const char *name) -{ - struct mydata *mydata; - struct archive *a; - struct archive_entry *entry; - - mydata = malloc(sizeof(struct mydata)); - a = archive_read_new(); - mydata->name = name; - archive_read_support_filter_all(a); - archive_read_support_format_all(a); - archive_read_open(a, mydata, myopen, myread, myclose); - while (archive_read_next_header(a, &entry) == ARCHIVE_OK) { - printf("%s\en",archive_entry_pathname(entry)); - archive_read_data_skip(a); - } - archive_read_free(a); - free(mydata); -} - -la_ssize_t -myread(struct archive *a, void *client_data, const void **buff) -{ - struct mydata *mydata = client_data; - - *buff = mydata->buff; - return (read(mydata->fd, mydata->buff, 10240)); -} - -int -myopen(struct archive *a, void *client_data) -{ - struct mydata *mydata = client_data; - - mydata->fd = open(mydata->name, O_RDONLY); - return (mydata->fd >= 0 ? ARCHIVE_OK : ARCHIVE_FATAL); -} - -int -myclose(struct archive *a, void *client_data) -{ - struct mydata *mydata = client_data; - - if (mydata->fd > 0) - close(mydata->fd); - return (ARCHIVE_OK); -} -.Ed -.\" .Sh ERRORS -.Sh SEE ALSO -.Xr tar 1 , -.Xr archive_read_data 3 , -.Xr archive_read_extract 3 , -.Xr archive_read_filter 3 , -.Xr archive_read_format 3 , -.Xr archive_read_header 3 , -.Xr archive_read_new 3 , -.Xr archive_read_open 3 , -.Xr archive_read_set_options 3 , -.Xr archive_util 3 , -.Xr libarchive 3 , -.Xr tar 5 -.Sh HISTORY -The -.Nm libarchive -library first appeared in -.Fx 5.3 . -.Sh AUTHORS -.An -nosplit -The -.Nm libarchive -library was written by -.An Tim Kientzle Aq kientzle@acm.org . -.Sh BUGS -Many traditional archiver programs treat -empty files as valid empty archives. -For example, many implementations of -.Xr tar 1 -allow you to append entries to an empty file. -Of course, it is impossible to determine the format of an empty file -by inspecting the contents, so this library treats empty files as -having a special -.Dq empty -format. diff --git a/thirdparty/libarchive/libarchive/archive_read.c b/thirdparty/libarchive/libarchive/archive_read.c deleted file mode 100644 index 45a38aed0..000000000 --- a/thirdparty/libarchive/libarchive/archive_read.c +++ /dev/null @@ -1,1756 +0,0 @@ -/*- - * Copyright (c) 2003-2011 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -/* - * This file contains the "essential" portions of the read API, that - * is, stuff that will probably always be used by any client that - * actually needs to read an archive. Optional pieces have been, as - * far as possible, separated out into separate files to avoid - * needlessly bloating statically-linked clients. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_read.c 201157 2009-12-29 05:30:23Z kientzle $"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" -#include "archive_private.h" -#include "archive_read_private.h" - -#define minimum(a, b) (a < b ? a : b) - -static int choose_filters(struct archive_read *); -static int choose_format(struct archive_read *); -static int close_filters(struct archive_read *); -static int64_t _archive_filter_bytes(struct archive *, int); -static int _archive_filter_code(struct archive *, int); -static const char *_archive_filter_name(struct archive *, int); -static int _archive_filter_count(struct archive *); -static int _archive_read_close(struct archive *); -static int _archive_read_data_block(struct archive *, - const void **, size_t *, int64_t *); -static int _archive_read_free(struct archive *); -static int _archive_read_next_header(struct archive *, - struct archive_entry **); -static int _archive_read_next_header2(struct archive *, - struct archive_entry *); -static int64_t advance_file_pointer(struct archive_read_filter *, int64_t); - -static const struct archive_vtable -archive_read_vtable = { - .archive_filter_bytes = _archive_filter_bytes, - .archive_filter_code = _archive_filter_code, - .archive_filter_name = _archive_filter_name, - .archive_filter_count = _archive_filter_count, - .archive_read_data_block = _archive_read_data_block, - .archive_read_next_header = _archive_read_next_header, - .archive_read_next_header2 = _archive_read_next_header2, - .archive_free = _archive_read_free, - .archive_close = _archive_read_close, -}; - -/* - * Allocate, initialize and return a struct archive object. - */ -struct archive * -archive_read_new(void) -{ - struct archive_read *a; - - a = (struct archive_read *)calloc(1, sizeof(*a)); - if (a == NULL) - return (NULL); - a->archive.magic = ARCHIVE_READ_MAGIC; - - a->archive.state = ARCHIVE_STATE_NEW; - a->entry = archive_entry_new2(&a->archive); - a->archive.vtable = &archive_read_vtable; - - a->passphrases.last = &a->passphrases.first; - - return (&a->archive); -} - -/* - * Record the do-not-extract-to file. This belongs in archive_read_extract.c. - */ -void -archive_read_extract_set_skip_file(struct archive *_a, la_int64_t d, - la_int64_t i) -{ - struct archive_read *a = (struct archive_read *)_a; - - if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_ANY, "archive_read_extract_set_skip_file")) - return; - a->skip_file_set = 1; - a->skip_file_dev = d; - a->skip_file_ino = i; -} - -/* - * Open the archive - */ -int -archive_read_open(struct archive *a, void *client_data, - archive_open_callback *client_opener, archive_read_callback *client_reader, - archive_close_callback *client_closer) -{ - /* Old archive_read_open() is just a thin shell around - * archive_read_open1. */ - archive_read_set_open_callback(a, client_opener); - archive_read_set_read_callback(a, client_reader); - archive_read_set_close_callback(a, client_closer); - archive_read_set_callback_data(a, client_data); - return archive_read_open1(a); -} - - -int -archive_read_open2(struct archive *a, void *client_data, - archive_open_callback *client_opener, - archive_read_callback *client_reader, - archive_skip_callback *client_skipper, - archive_close_callback *client_closer) -{ - /* Old archive_read_open2() is just a thin shell around - * archive_read_open1. */ - archive_read_set_callback_data(a, client_data); - archive_read_set_open_callback(a, client_opener); - archive_read_set_read_callback(a, client_reader); - archive_read_set_skip_callback(a, client_skipper); - archive_read_set_close_callback(a, client_closer); - return archive_read_open1(a); -} - -static ssize_t -client_read_proxy(struct archive_read_filter *self, const void **buff) -{ - ssize_t r; - r = (self->archive->client.reader)(&self->archive->archive, - self->data, buff); - return (r); -} - -static int64_t -client_skip_proxy(struct archive_read_filter *self, int64_t request) -{ - if (request < 0) - __archive_errx(1, "Negative skip requested."); - if (request == 0) - return 0; - - if (self->archive->client.skipper != NULL) { - /* Seek requests over 1GiB are broken down into - * multiple seeks. This avoids overflows when the - * requests get passed through 32-bit arguments. */ - int64_t skip_limit = (int64_t)1 << 30; - int64_t total = 0; - for (;;) { - int64_t get, ask = request; - if (ask > skip_limit) - ask = skip_limit; - get = (self->archive->client.skipper) - (&self->archive->archive, self->data, ask); - total += get; - if (get == 0 || get == request) - return (total); - if (get > request) - return ARCHIVE_FATAL; - request -= get; - } - } else if (self->archive->client.seeker != NULL - && request > 64 * 1024) { - /* If the client provided a seeker but not a skipper, - * we can use the seeker to skip forward. - * - * Note: This isn't always a good idea. The client - * skipper is allowed to skip by less than requested - * if it needs to maintain block alignment. The - * seeker is not allowed to play such games, so using - * the seeker here may be a performance loss compared - * to just reading and discarding. That's why we - * only do this for skips of over 64k. - */ - int64_t before = self->position; - int64_t after = (self->archive->client.seeker) - (&self->archive->archive, self->data, request, SEEK_CUR); - if (after != before + request) - return ARCHIVE_FATAL; - return after - before; - } - return 0; -} - -static int64_t -client_seek_proxy(struct archive_read_filter *self, int64_t offset, int whence) -{ - /* DO NOT use the skipper here! If we transparently handled - * forward seek here by using the skipper, that will break - * other libarchive code that assumes a successful forward - * seek means it can also seek backwards. - */ - if (self->archive->client.seeker == NULL) { - archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC, - "Current client reader does not support seeking a device"); - return (ARCHIVE_FAILED); - } - return (self->archive->client.seeker)(&self->archive->archive, - self->data, offset, whence); -} - -static int -read_client_close_proxy(struct archive_read *a) -{ - int r = ARCHIVE_OK, r2; - unsigned int i; - - if (a->client.closer == NULL) - return (r); - for (i = 0; i < a->client.nodes; i++) - { - r2 = (a->client.closer) - ((struct archive *)a, a->client.dataset[i].data); - if (r > r2) - r = r2; - } - return (r); -} - -static int -client_close_proxy(struct archive_read_filter *self) -{ - return read_client_close_proxy(self->archive); -} - -static int -client_open_proxy(struct archive_read_filter *self) -{ - int r = ARCHIVE_OK; - if (self->archive->client.opener != NULL) - r = (self->archive->client.opener)( - (struct archive *)self->archive, self->data); - return (r); -} - -static int -client_switch_proxy(struct archive_read_filter *self, unsigned int iindex) -{ - int r1 = ARCHIVE_OK, r2 = ARCHIVE_OK; - void *data2 = NULL; - - /* Don't do anything if already in the specified data node */ - if (self->archive->client.cursor == iindex) - return (ARCHIVE_OK); - - self->archive->client.cursor = iindex; - data2 = self->archive->client.dataset[self->archive->client.cursor].data; - if (self->archive->client.switcher != NULL) - { - r1 = r2 = (self->archive->client.switcher) - ((struct archive *)self->archive, self->data, data2); - self->data = data2; - } - else - { - /* Attempt to call close and open instead */ - if (self->archive->client.closer != NULL) - r1 = (self->archive->client.closer) - ((struct archive *)self->archive, self->data); - self->data = data2; - r2 = client_open_proxy(self); - } - return (r1 < r2) ? r1 : r2; -} - -int -archive_read_set_open_callback(struct archive *_a, - archive_open_callback *client_opener) -{ - struct archive_read *a = (struct archive_read *)_a; - archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, - "archive_read_set_open_callback"); - a->client.opener = client_opener; - return ARCHIVE_OK; -} - -int -archive_read_set_read_callback(struct archive *_a, - archive_read_callback *client_reader) -{ - struct archive_read *a = (struct archive_read *)_a; - archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, - "archive_read_set_read_callback"); - a->client.reader = client_reader; - return ARCHIVE_OK; -} - -int -archive_read_set_skip_callback(struct archive *_a, - archive_skip_callback *client_skipper) -{ - struct archive_read *a = (struct archive_read *)_a; - archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, - "archive_read_set_skip_callback"); - a->client.skipper = client_skipper; - return ARCHIVE_OK; -} - -int -archive_read_set_seek_callback(struct archive *_a, - archive_seek_callback *client_seeker) -{ - struct archive_read *a = (struct archive_read *)_a; - archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, - "archive_read_set_seek_callback"); - a->client.seeker = client_seeker; - return ARCHIVE_OK; -} - -int -archive_read_set_close_callback(struct archive *_a, - archive_close_callback *client_closer) -{ - struct archive_read *a = (struct archive_read *)_a; - archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, - "archive_read_set_close_callback"); - a->client.closer = client_closer; - return ARCHIVE_OK; -} - -int -archive_read_set_switch_callback(struct archive *_a, - archive_switch_callback *client_switcher) -{ - struct archive_read *a = (struct archive_read *)_a; - archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, - "archive_read_set_switch_callback"); - a->client.switcher = client_switcher; - return ARCHIVE_OK; -} - -int -archive_read_set_callback_data(struct archive *_a, void *client_data) -{ - return archive_read_set_callback_data2(_a, client_data, 0); -} - -int -archive_read_set_callback_data2(struct archive *_a, void *client_data, - unsigned int iindex) -{ - struct archive_read *a = (struct archive_read *)_a; - archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, - "archive_read_set_callback_data2"); - - if (a->client.nodes == 0) - { - a->client.dataset = (struct archive_read_data_node *) - calloc(1, sizeof(*a->client.dataset)); - if (a->client.dataset == NULL) - { - archive_set_error(&a->archive, ENOMEM, - "No memory."); - return ARCHIVE_FATAL; - } - a->client.nodes = 1; - } - - if (iindex > a->client.nodes - 1) - { - archive_set_error(&a->archive, EINVAL, - "Invalid index specified."); - return ARCHIVE_FATAL; - } - a->client.dataset[iindex].data = client_data; - a->client.dataset[iindex].begin_position = -1; - a->client.dataset[iindex].total_size = -1; - return ARCHIVE_OK; -} - -int -archive_read_add_callback_data(struct archive *_a, void *client_data, - unsigned int iindex) -{ - struct archive_read *a = (struct archive_read *)_a; - void *p; - unsigned int i; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, - "archive_read_add_callback_data"); - if (iindex > a->client.nodes) { - archive_set_error(&a->archive, EINVAL, - "Invalid index specified."); - return ARCHIVE_FATAL; - } - p = realloc(a->client.dataset, sizeof(*a->client.dataset) - * (++(a->client.nodes))); - if (p == NULL) { - archive_set_error(&a->archive, ENOMEM, - "No memory."); - return ARCHIVE_FATAL; - } - a->client.dataset = (struct archive_read_data_node *)p; - for (i = a->client.nodes - 1; i > iindex; i--) { - a->client.dataset[i].data = a->client.dataset[i-1].data; - a->client.dataset[i].begin_position = -1; - a->client.dataset[i].total_size = -1; - } - a->client.dataset[iindex].data = client_data; - a->client.dataset[iindex].begin_position = -1; - a->client.dataset[iindex].total_size = -1; - return ARCHIVE_OK; -} - -int -archive_read_append_callback_data(struct archive *_a, void *client_data) -{ - struct archive_read *a = (struct archive_read *)_a; - return archive_read_add_callback_data(_a, client_data, a->client.nodes); -} - -int -archive_read_prepend_callback_data(struct archive *_a, void *client_data) -{ - return archive_read_add_callback_data(_a, client_data, 0); -} - -static const struct archive_read_filter_vtable -none_reader_vtable = { - .read = client_read_proxy, - .close = client_close_proxy, -}; - -int -archive_read_open1(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - struct archive_read_filter *filter, *tmp; - int slot, e = ARCHIVE_OK; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, - "archive_read_open"); - archive_clear_error(&a->archive); - - if (a->client.reader == NULL) { - archive_set_error(&a->archive, EINVAL, - "No reader function provided to archive_read_open"); - a->archive.state = ARCHIVE_STATE_FATAL; - return (ARCHIVE_FATAL); - } - - /* Open data source. */ - if (a->client.opener != NULL) { - e = (a->client.opener)(&a->archive, a->client.dataset[0].data); - if (e != 0) { - /* If the open failed, call the closer to clean up. */ - read_client_close_proxy(a); - return (e); - } - } - - filter = calloc(1, sizeof(*filter)); - if (filter == NULL) - return (ARCHIVE_FATAL); - filter->bidder = NULL; - filter->upstream = NULL; - filter->archive = a; - filter->data = a->client.dataset[0].data; - filter->vtable = &none_reader_vtable; - filter->name = "none"; - filter->code = ARCHIVE_FILTER_NONE; - filter->can_skip = 1; - filter->can_seek = 1; - - a->client.dataset[0].begin_position = 0; - if (!a->filter || !a->bypass_filter_bidding) - { - a->filter = filter; - /* Build out the input pipeline. */ - e = choose_filters(a); - if (e < ARCHIVE_WARN) { - a->archive.state = ARCHIVE_STATE_FATAL; - return (ARCHIVE_FATAL); - } - } - else - { - /* Need to add "NONE" type filter at the end of the filter chain */ - tmp = a->filter; - while (tmp->upstream) - tmp = tmp->upstream; - tmp->upstream = filter; - } - - if (!a->format) - { - slot = choose_format(a); - if (slot < 0) { - close_filters(a); - a->archive.state = ARCHIVE_STATE_FATAL; - return (ARCHIVE_FATAL); - } - a->format = &(a->formats[slot]); - } - - a->archive.state = ARCHIVE_STATE_HEADER; - - /* Ensure libarchive starts from the first node in a multivolume set */ - client_switch_proxy(a->filter, 0); - return (e); -} - -/* - * Allow each registered stream transform to bid on whether - * it wants to handle this stream. Repeat until we've finished - * building the pipeline. - */ - -/* We won't build a filter pipeline with more stages than this. */ -#define MAX_NUMBER_FILTERS 25 - -static int -choose_filters(struct archive_read *a) -{ - int number_bidders, i, bid, best_bid, number_filters; - struct archive_read_filter_bidder *bidder, *best_bidder; - struct archive_read_filter *filter; - ssize_t avail; - int r; - - for (number_filters = 0; number_filters < MAX_NUMBER_FILTERS; ++number_filters) { - number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]); - - best_bid = 0; - best_bidder = NULL; - - bidder = a->bidders; - for (i = 0; i < number_bidders; i++, bidder++) { - if (bidder->vtable == NULL) - continue; - bid = (bidder->vtable->bid)(bidder, a->filter); - if (bid > best_bid) { - best_bid = bid; - best_bidder = bidder; - } - } - - /* If no bidder, we're done. */ - if (best_bidder == NULL) { - /* Verify the filter by asking it for some data. */ - __archive_read_filter_ahead(a->filter, 1, &avail); - if (avail < 0) { - __archive_read_free_filters(a); - return (ARCHIVE_FATAL); - } - return (ARCHIVE_OK); - } - - filter - = (struct archive_read_filter *)calloc(1, sizeof(*filter)); - if (filter == NULL) - return (ARCHIVE_FATAL); - filter->bidder = best_bidder; - filter->archive = a; - filter->upstream = a->filter; - a->filter = filter; - r = (best_bidder->vtable->init)(a->filter); - if (r != ARCHIVE_OK) { - __archive_read_free_filters(a); - return (ARCHIVE_FATAL); - } - } - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Input requires too many filters for decoding"); - return (ARCHIVE_FATAL); -} - -int -__archive_read_header(struct archive_read *a, struct archive_entry *entry) -{ - if (!a->filter->vtable->read_header) - return (ARCHIVE_OK); - return a->filter->vtable->read_header(a->filter, entry); -} - -/* - * Read header of next entry. - */ -static int -_archive_read_next_header2(struct archive *_a, struct archive_entry *entry) -{ - struct archive_read *a = (struct archive_read *)_a; - int r1 = ARCHIVE_OK, r2; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, - "archive_read_next_header"); - - archive_entry_clear(entry); - archive_clear_error(&a->archive); - - /* - * If client didn't consume entire data, skip any remainder - * (This is especially important for GNU incremental directories.) - */ - if (a->archive.state == ARCHIVE_STATE_DATA) { - r1 = archive_read_data_skip(&a->archive); - if (r1 == ARCHIVE_EOF) - archive_set_error(&a->archive, EIO, - "Premature end-of-file."); - if (r1 == ARCHIVE_EOF || r1 == ARCHIVE_FATAL) { - a->archive.state = ARCHIVE_STATE_FATAL; - return (ARCHIVE_FATAL); - } - } - - /* Record start-of-header offset in uncompressed stream. */ - a->header_position = a->filter->position; - - ++_a->file_count; - r2 = (a->format->read_header)(a, entry); - - /* - * EOF and FATAL are persistent at this layer. By - * modifying the state, we guarantee that future calls to - * read a header or read data will fail. - */ - switch (r2) { - case ARCHIVE_EOF: - a->archive.state = ARCHIVE_STATE_EOF; - --_a->file_count;/* Revert a file counter. */ - break; - case ARCHIVE_OK: - a->archive.state = ARCHIVE_STATE_DATA; - break; - case ARCHIVE_WARN: - a->archive.state = ARCHIVE_STATE_DATA; - break; - case ARCHIVE_RETRY: - break; - case ARCHIVE_FATAL: - a->archive.state = ARCHIVE_STATE_FATAL; - break; - } - - __archive_reset_read_data(&a->archive); - - a->data_start_node = a->client.cursor; - /* EOF always wins; otherwise return the worst error. */ - return (r2 < r1 || r2 == ARCHIVE_EOF) ? r2 : r1; -} - -static int -_archive_read_next_header(struct archive *_a, struct archive_entry **entryp) -{ - int ret; - struct archive_read *a = (struct archive_read *)_a; - *entryp = NULL; - ret = _archive_read_next_header2(_a, a->entry); - *entryp = a->entry; - return ret; -} - -/* - * Allow each registered format to bid on whether it wants to handle - * the next entry. Return index of winning bidder. - */ -static int -choose_format(struct archive_read *a) -{ - int slots; - int i; - int bid, best_bid; - int best_bid_slot; - - slots = sizeof(a->formats) / sizeof(a->formats[0]); - best_bid = -1; - best_bid_slot = -1; - - /* Set up a->format for convenience of bidders. */ - a->format = &(a->formats[0]); - for (i = 0; i < slots; i++, a->format++) { - if (a->format->bid) { - bid = (a->format->bid)(a, best_bid); - if (bid == ARCHIVE_FATAL) - return (ARCHIVE_FATAL); - if (a->filter->position != 0) - __archive_read_seek(a, 0, SEEK_SET); - if ((bid > best_bid) || (best_bid_slot < 0)) { - best_bid = bid; - best_bid_slot = i; - } - } - } - - /* - * There were no bidders; this is a serious programmer error - * and demands a quick and definitive abort. - */ - if (best_bid_slot < 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "No formats registered"); - return (ARCHIVE_FATAL); - } - - /* - * There were bidders, but no non-zero bids; this means we - * can't support this stream. - */ - if (best_bid < 1) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Unrecognized archive format"); - return (ARCHIVE_FATAL); - } - - return (best_bid_slot); -} - -/* - * Return the file offset (within the uncompressed data stream) where - * the last header started. - */ -la_int64_t -archive_read_header_position(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_ANY, "archive_read_header_position"); - return (a->header_position); -} - -/* - * Returns 1 if the archive contains at least one encrypted entry. - * If the archive format not support encryption at all - * ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED is returned. - * If for any other reason (e.g. not enough data read so far) - * we cannot say whether there are encrypted entries, then - * ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW is returned. - * In general, this function will return values below zero when the - * reader is uncertain or totally incapable of encryption support. - * When this function returns 0 you can be sure that the reader - * supports encryption detection but no encrypted entries have - * been found yet. - * - * NOTE: If the metadata/header of an archive is also encrypted, you - * cannot rely on the number of encrypted entries. That is why this - * function does not return the number of encrypted entries but# - * just shows that there are some. - */ -int -archive_read_has_encrypted_entries(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - int format_supports_encryption = archive_read_format_capabilities(_a) - & (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA | ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA); - - if (!_a || !format_supports_encryption) { - /* Format in general doesn't support encryption */ - return ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED; - } - - /* A reader potentially has read enough data now. */ - if (a->format && a->format->has_encrypted_entries) { - return (a->format->has_encrypted_entries)(a); - } - - /* For any other reason we cannot say how many entries are there. */ - return ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW; -} - -/* - * Returns a bitmask of capabilities that are supported by the archive format reader. - * If the reader has no special capabilities, ARCHIVE_READ_FORMAT_CAPS_NONE is returned. - */ -int -archive_read_format_capabilities(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - if (a && a->format && a->format->format_capabilties) { - return (a->format->format_capabilties)(a); - } - return ARCHIVE_READ_FORMAT_CAPS_NONE; -} - -/* - * Read data from an archive entry, using a read(2)-style interface. - * This is a convenience routine that just calls - * archive_read_data_block and copies the results into the client - * buffer, filling any gaps with zero bytes. Clients using this - * API can be completely ignorant of sparse-file issues; sparse files - * will simply be padded with nulls. - * - * DO NOT intermingle calls to this function and archive_read_data_block - * to read a single entry body. - */ -la_ssize_t -archive_read_data(struct archive *_a, void *buff, size_t s) -{ - struct archive *a = (struct archive *)_a; - char *dest; - const void *read_buf; - size_t bytes_read; - size_t len; - int r; - - bytes_read = 0; - dest = (char *)buff; - - while (s > 0) { - if (a->read_data_offset == a->read_data_output_offset && - a->read_data_remaining == 0) { - read_buf = a->read_data_block; - a->read_data_is_posix_read = 1; - a->read_data_requested = s; - r = archive_read_data_block(a, &read_buf, - &a->read_data_remaining, &a->read_data_offset); - a->read_data_block = read_buf; - if (r == ARCHIVE_EOF) - return (bytes_read); - /* - * Error codes are all negative, so the status - * return here cannot be confused with a valid - * byte count. (ARCHIVE_OK is zero.) - */ - if (r < ARCHIVE_OK) - return (r); - } - - if (a->read_data_offset < a->read_data_output_offset) { - archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT, - "Encountered out-of-order sparse blocks"); - return (ARCHIVE_RETRY); - } - - /* Compute the amount of zero padding needed. */ - if (a->read_data_output_offset + (int64_t)s < - a->read_data_offset) { - len = s; - } else if (a->read_data_output_offset < - a->read_data_offset) { - len = (size_t)(a->read_data_offset - - a->read_data_output_offset); - } else - len = 0; - - /* Add zeroes. */ - memset(dest, 0, len); - s -= len; - a->read_data_output_offset += len; - dest += len; - bytes_read += len; - - /* Copy data if there is any space left. */ - if (s > 0) { - len = a->read_data_remaining; - if (len > s) - len = s; - if (len) { - memcpy(dest, a->read_data_block, len); - s -= len; - a->read_data_block += len; - a->read_data_remaining -= len; - a->read_data_output_offset += len; - a->read_data_offset += len; - dest += len; - bytes_read += len; - } - } - } - a->read_data_is_posix_read = 0; - a->read_data_requested = 0; - return (bytes_read); -} - -/* - * Reset the read_data_* variables, used for starting a new entry. - */ -void __archive_reset_read_data(struct archive * a) -{ - a->read_data_output_offset = 0; - a->read_data_remaining = 0; - a->read_data_is_posix_read = 0; - a->read_data_requested = 0; - - /* extra resets, from rar.c */ - a->read_data_block = NULL; - a->read_data_offset = 0; -} - -/* - * Skip over all remaining data in this entry. - */ -int -archive_read_data_skip(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - int r; - const void *buff; - size_t size; - int64_t offset; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA, - "archive_read_data_skip"); - - if (a->format->read_data_skip != NULL) - r = (a->format->read_data_skip)(a); - else { - while ((r = archive_read_data_block(&a->archive, - &buff, &size, &offset)) - == ARCHIVE_OK) - ; - } - - if (r == ARCHIVE_EOF) - r = ARCHIVE_OK; - - a->archive.state = ARCHIVE_STATE_HEADER; - return (r); -} - -la_int64_t -archive_seek_data(struct archive *_a, int64_t offset, int whence) -{ - struct archive_read *a = (struct archive_read *)_a; - archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA, - "archive_seek_data_block"); - - if (a->format->seek_data == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, - "Internal error: " - "No format_seek_data_block function registered"); - return (ARCHIVE_FATAL); - } - - return (a->format->seek_data)(a, offset, whence); -} - -/* - * Read the next block of entry data from the archive. - * This is a zero-copy interface; the client receives a pointer, - * size, and file offset of the next available block of data. - * - * Returns ARCHIVE_OK if the operation is successful, ARCHIVE_EOF if - * the end of entry is encountered. - */ -static int -_archive_read_data_block(struct archive *_a, - const void **buff, size_t *size, int64_t *offset) -{ - struct archive_read *a = (struct archive_read *)_a; - archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA, - "archive_read_data_block"); - - if (a->format->read_data == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, - "Internal error: " - "No format->read_data function registered"); - return (ARCHIVE_FATAL); - } - - return (a->format->read_data)(a, buff, size, offset); -} - -static int -close_filters(struct archive_read *a) -{ - struct archive_read_filter *f = a->filter; - int r = ARCHIVE_OK; - /* Close each filter in the pipeline. */ - while (f != NULL) { - struct archive_read_filter *t = f->upstream; - if (!f->closed && f->vtable != NULL) { - int r1 = (f->vtable->close)(f); - f->closed = 1; - if (r1 < r) - r = r1; - } - free(f->buffer); - f->buffer = NULL; - f = t; - } - return r; -} - -void -__archive_read_free_filters(struct archive_read *a) -{ - /* Make sure filters are closed and their buffers are freed */ - close_filters(a); - - while (a->filter != NULL) { - struct archive_read_filter *t = a->filter->upstream; - free(a->filter); - a->filter = t; - } -} - -/* - * return the count of # of filters in use - */ -static int -_archive_filter_count(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - struct archive_read_filter *p = a->filter; - int count = 0; - while(p) { - count++; - p = p->upstream; - } - return count; -} - -/* - * Close the file and all I/O. - */ -static int -_archive_read_close(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - int r = ARCHIVE_OK, r1 = ARCHIVE_OK; - - archive_check_magic(&a->archive, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_close"); - if (a->archive.state == ARCHIVE_STATE_CLOSED) - return (ARCHIVE_OK); - archive_clear_error(&a->archive); - a->archive.state = ARCHIVE_STATE_CLOSED; - - /* TODO: Clean up the formatters. */ - - /* Release the filter objects. */ - r1 = close_filters(a); - if (r1 < r) - r = r1; - - return (r); -} - -/* - * Release memory and other resources. - */ -static int -_archive_read_free(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - struct archive_read_passphrase *p; - int i, n; - int slots; - int r = ARCHIVE_OK; - - if (_a == NULL) - return (ARCHIVE_OK); - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_free"); - if (a->archive.state != ARCHIVE_STATE_CLOSED - && a->archive.state != ARCHIVE_STATE_FATAL) - r = archive_read_close(&a->archive); - - /* Call cleanup functions registered by optional components. */ - if (a->cleanup_archive_extract != NULL) - r = (a->cleanup_archive_extract)(a); - - /* Cleanup format-specific data. */ - slots = sizeof(a->formats) / sizeof(a->formats[0]); - for (i = 0; i < slots; i++) { - a->format = &(a->formats[i]); - if (a->formats[i].cleanup) - (a->formats[i].cleanup)(a); - } - - /* Free the filters */ - __archive_read_free_filters(a); - - /* Release the bidder objects. */ - n = sizeof(a->bidders)/sizeof(a->bidders[0]); - for (i = 0; i < n; i++) { - if (a->bidders[i].vtable == NULL || - a->bidders[i].vtable->free == NULL) - continue; - (a->bidders[i].vtable->free)(&a->bidders[i]); - } - - /* Release passphrase list. */ - p = a->passphrases.first; - while (p != NULL) { - struct archive_read_passphrase *np = p->next; - - /* A passphrase should be cleaned. */ - memset(p->passphrase, 0, strlen(p->passphrase)); - free(p->passphrase); - free(p); - p = np; - } - - archive_string_free(&a->archive.error_string); - archive_entry_free(a->entry); - a->archive.magic = 0; - __archive_clean(&a->archive); - free(a->client.dataset); - free(a); - return (r); -} - -static struct archive_read_filter * -get_filter(struct archive *_a, int n) -{ - struct archive_read *a = (struct archive_read *)_a; - struct archive_read_filter *f = a->filter; - /* We use n == -1 for 'the last filter', which is always the - * client proxy. */ - if (n == -1 && f != NULL) { - struct archive_read_filter *last = f; - f = f->upstream; - while (f != NULL) { - last = f; - f = f->upstream; - } - return (last); - } - if (n < 0) - return NULL; - while (n > 0 && f != NULL) { - f = f->upstream; - --n; - } - return (f); -} - -static int -_archive_filter_code(struct archive *_a, int n) -{ - struct archive_read_filter *f = get_filter(_a, n); - return f == NULL ? -1 : f->code; -} - -static const char * -_archive_filter_name(struct archive *_a, int n) -{ - struct archive_read_filter *f = get_filter(_a, n); - return f != NULL ? f->name : NULL; -} - -static int64_t -_archive_filter_bytes(struct archive *_a, int n) -{ - struct archive_read_filter *f = get_filter(_a, n); - return f == NULL ? -1 : f->position; -} - -/* - * Used internally by read format handlers to register their bid and - * initialization functions. - */ -int -__archive_read_register_format(struct archive_read *a, - void *format_data, - const char *name, - int (*bid)(struct archive_read *, int), - int (*options)(struct archive_read *, const char *, const char *), - int (*read_header)(struct archive_read *, struct archive_entry *), - int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *), - int (*read_data_skip)(struct archive_read *), - int64_t (*seek_data)(struct archive_read *, int64_t, int), - int (*cleanup)(struct archive_read *), - int (*format_capabilities)(struct archive_read *), - int (*has_encrypted_entries)(struct archive_read *)) -{ - int i, number_slots; - - archive_check_magic(&a->archive, - ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, - "__archive_read_register_format"); - - number_slots = sizeof(a->formats) / sizeof(a->formats[0]); - - for (i = 0; i < number_slots; i++) { - if (a->formats[i].bid == bid) - return (ARCHIVE_WARN); /* We've already installed */ - if (a->formats[i].bid == NULL) { - a->formats[i].bid = bid; - a->formats[i].options = options; - a->formats[i].read_header = read_header; - a->formats[i].read_data = read_data; - a->formats[i].read_data_skip = read_data_skip; - a->formats[i].seek_data = seek_data; - a->formats[i].cleanup = cleanup; - a->formats[i].data = format_data; - a->formats[i].name = name; - a->formats[i].format_capabilties = format_capabilities; - a->formats[i].has_encrypted_entries = has_encrypted_entries; - return (ARCHIVE_OK); - } - } - - archive_set_error(&a->archive, ENOMEM, - "Not enough slots for format registration"); - return (ARCHIVE_FATAL); -} - -/* - * Used internally by decompression routines to register their bid and - * initialization functions. - */ -int -__archive_read_register_bidder(struct archive_read *a, - void *bidder_data, - const char *name, - const struct archive_read_filter_bidder_vtable *vtable) -{ - struct archive_read_filter_bidder *bidder; - int i, number_slots; - - archive_check_magic(&a->archive, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "__archive_read_register_bidder"); - - number_slots = sizeof(a->bidders) / sizeof(a->bidders[0]); - - for (i = 0; i < number_slots; i++) { - if (a->bidders[i].vtable != NULL) - continue; - memset(a->bidders + i, 0, sizeof(a->bidders[0])); - bidder = (a->bidders + i); - bidder->data = bidder_data; - bidder->name = name; - bidder->vtable = vtable; - if (bidder->vtable->bid == NULL || bidder->vtable->init == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, - "Internal error: " - "no bid/init for filter bidder"); - return (ARCHIVE_FATAL); - } - - return (ARCHIVE_OK); - } - - archive_set_error(&a->archive, ENOMEM, - "Not enough slots for filter registration"); - return (ARCHIVE_FATAL); -} - -/* - * The next section implements the peek/consume internal I/O - * system used by archive readers. This system allows simple - * read-ahead for consumers while preserving zero-copy operation - * most of the time. - * - * The two key operations: - * * The read-ahead function returns a pointer to a block of data - * that satisfies a minimum request. - * * The consume function advances the file pointer. - * - * In the ideal case, filters generate blocks of data - * and __archive_read_ahead() just returns pointers directly into - * those blocks. Then __archive_read_consume() just bumps those - * pointers. Only if your request would span blocks does the I/O - * layer use a copy buffer to provide you with a contiguous block of - * data. - * - * A couple of useful idioms: - * * "I just want some data." Ask for 1 byte and pay attention to - * the "number of bytes available" from __archive_read_ahead(). - * Consume whatever you actually use. - * * "I want to output a large block of data." As above, ask for 1 byte, - * emit all that's available (up to whatever limit you have), consume - * it all, then repeat until you're done. This effectively means that - * you're passing along the blocks that came from your provider. - * * "I want to peek ahead by a large amount." Ask for 4k or so, then - * double and repeat until you get an error or have enough. Note - * that the I/O layer will likely end up expanding its copy buffer - * to fit your request, so use this technique cautiously. This - * technique is used, for example, by some of the format tasting - * code that has uncertain look-ahead needs. - */ - -/* - * Looks ahead in the input stream: - * * If 'avail' pointer is provided, that returns number of bytes available - * in the current buffer, which may be much larger than requested. - * * If end-of-file, *avail gets set to zero. - * * If error, *avail gets error code. - * * If request can be met, returns pointer to data. - * * If minimum request cannot be met, returns NULL. - * - * Note: If you just want "some data", ask for 1 byte and pay attention - * to *avail, which will have the actual amount available. If you - * know exactly how many bytes you need, just ask for that and treat - * a NULL return as an error. - * - * Important: This does NOT move the file pointer. See - * __archive_read_consume() below. - */ -const void * -__archive_read_ahead(struct archive_read *a, size_t min, ssize_t *avail) -{ - return (__archive_read_filter_ahead(a->filter, min, avail)); -} - -const void * -__archive_read_filter_ahead(struct archive_read_filter *filter, - size_t min, ssize_t *avail) -{ - ssize_t bytes_read; - size_t tocopy; - - if (filter->fatal) { - if (avail) - *avail = ARCHIVE_FATAL; - return (NULL); - } - - /* - * Keep pulling more data until we can satisfy the request. - */ - for (;;) { - - /* - * If we can satisfy from the copy buffer (and the - * copy buffer isn't empty), we're done. In particular, - * note that min == 0 is a perfectly well-defined - * request. - */ - if (filter->avail >= min && filter->avail > 0) { - if (avail != NULL) - *avail = filter->avail; - return (filter->next); - } - - /* - * We can satisfy directly from client buffer if everything - * currently in the copy buffer is still in the client buffer. - */ - if (filter->client_total >= filter->client_avail + filter->avail - && filter->client_avail + filter->avail >= min) { - /* "Roll back" to client buffer. */ - filter->client_avail += filter->avail; - filter->client_next -= filter->avail; - /* Copy buffer is now empty. */ - filter->avail = 0; - filter->next = filter->buffer; - /* Return data from client buffer. */ - if (avail != NULL) - *avail = filter->client_avail; - return (filter->client_next); - } - - /* Move data forward in copy buffer if necessary. */ - if (filter->next > filter->buffer && - filter->next + min > filter->buffer + filter->buffer_size) { - if (filter->avail > 0) - memmove(filter->buffer, filter->next, - filter->avail); - filter->next = filter->buffer; - } - - /* If we've used up the client data, get more. */ - if (filter->client_avail <= 0) { - if (filter->end_of_file) { - if (avail != NULL) - *avail = 0; - return (NULL); - } - bytes_read = (filter->vtable->read)(filter, - &filter->client_buff); - if (bytes_read < 0) { /* Read error. */ - filter->client_total = filter->client_avail = 0; - filter->client_next = - filter->client_buff = NULL; - filter->fatal = 1; - if (avail != NULL) - *avail = ARCHIVE_FATAL; - return (NULL); - } - if (bytes_read == 0) { - /* Check for another client object first */ - if (filter->archive->client.cursor != - filter->archive->client.nodes - 1) { - if (client_switch_proxy(filter, - filter->archive->client.cursor + 1) - == ARCHIVE_OK) - continue; - } - /* Premature end-of-file. */ - filter->client_total = filter->client_avail = 0; - filter->client_next = - filter->client_buff = NULL; - filter->end_of_file = 1; - /* Return whatever we do have. */ - if (avail != NULL) - *avail = filter->avail; - return (NULL); - } - filter->client_total = bytes_read; - filter->client_avail = filter->client_total; - filter->client_next = filter->client_buff; - } else { - /* - * We can't satisfy the request from the copy - * buffer or the existing client data, so we - * need to copy more client data over to the - * copy buffer. - */ - - /* Ensure the buffer is big enough. */ - if (min > filter->buffer_size) { - size_t s, t; - char *p; - - /* Double the buffer; watch for overflow. */ - s = t = filter->buffer_size; - if (s == 0) - s = min; - while (s < min) { - t *= 2; - if (t <= s) { /* Integer overflow! */ - archive_set_error( - &filter->archive->archive, - ENOMEM, - "Unable to allocate copy" - " buffer"); - filter->fatal = 1; - if (avail != NULL) - *avail = ARCHIVE_FATAL; - return (NULL); - } - s = t; - } - /* Now s >= min, so allocate a new buffer. */ - p = (char *)malloc(s); - if (p == NULL) { - archive_set_error( - &filter->archive->archive, - ENOMEM, - "Unable to allocate copy buffer"); - filter->fatal = 1; - if (avail != NULL) - *avail = ARCHIVE_FATAL; - return (NULL); - } - /* Move data into newly-enlarged buffer. */ - if (filter->avail > 0) - memmove(p, filter->next, filter->avail); - free(filter->buffer); - filter->next = filter->buffer = p; - filter->buffer_size = s; - } - - /* We can add client data to copy buffer. */ - /* First estimate: copy to fill rest of buffer. */ - tocopy = (filter->buffer + filter->buffer_size) - - (filter->next + filter->avail); - /* Don't waste time buffering more than we need to. */ - if (tocopy + filter->avail > min) - tocopy = min - filter->avail; - /* Don't copy more than is available. */ - if (tocopy > filter->client_avail) - tocopy = filter->client_avail; - - memcpy(filter->next + filter->avail, - filter->client_next, tocopy); - /* Remove this data from client buffer. */ - filter->client_next += tocopy; - filter->client_avail -= tocopy; - /* add it to copy buffer. */ - filter->avail += tocopy; - } - } -} - -/* - * Move the file pointer forward. - */ -int64_t -__archive_read_consume(struct archive_read *a, int64_t request) -{ - return (__archive_read_filter_consume(a->filter, request)); -} - -int64_t -__archive_read_filter_consume(struct archive_read_filter * filter, - int64_t request) -{ - int64_t skipped; - - if (request < 0) - return ARCHIVE_FATAL; - if (request == 0) - return 0; - - skipped = advance_file_pointer(filter, request); - if (skipped == request) - return (skipped); - /* We hit EOF before we satisfied the skip request. */ - if (skipped < 0) /* Map error code to 0 for error message below. */ - skipped = 0; - archive_set_error(&filter->archive->archive, - ARCHIVE_ERRNO_MISC, - "Truncated input file (needed %jd bytes, only %jd available)", - (intmax_t)request, (intmax_t)skipped); - return (ARCHIVE_FATAL); -} - -/* - * Advance the file pointer by the amount requested. - * Returns the amount actually advanced, which may be less than the - * request if EOF is encountered first. - * Returns a negative value if there's an I/O error. - */ -static int64_t -advance_file_pointer(struct archive_read_filter *filter, int64_t request) -{ - int64_t bytes_skipped, total_bytes_skipped = 0; - ssize_t bytes_read; - size_t min; - - if (filter->fatal) - return (-1); - - /* Use up the copy buffer first. */ - if (filter->avail > 0) { - min = (size_t)minimum(request, (int64_t)filter->avail); - filter->next += min; - filter->avail -= min; - request -= min; - filter->position += min; - total_bytes_skipped += min; - } - - /* Then use up the client buffer. */ - if (filter->client_avail > 0) { - min = (size_t)minimum(request, (int64_t)filter->client_avail); - filter->client_next += min; - filter->client_avail -= min; - request -= min; - filter->position += min; - total_bytes_skipped += min; - } - if (request == 0) - return (total_bytes_skipped); - - /* If there's an optimized skip function, use it. */ - if (filter->can_skip != 0) { - bytes_skipped = client_skip_proxy(filter, request); - if (bytes_skipped < 0) { /* error */ - filter->fatal = 1; - return (bytes_skipped); - } - filter->position += bytes_skipped; - total_bytes_skipped += bytes_skipped; - request -= bytes_skipped; - if (request == 0) - return (total_bytes_skipped); - } - - /* Use ordinary reads as necessary to complete the request. */ - for (;;) { - bytes_read = (filter->vtable->read)(filter, &filter->client_buff); - if (bytes_read < 0) { - filter->client_buff = NULL; - filter->fatal = 1; - return (bytes_read); - } - - if (bytes_read == 0) { - if (filter->archive->client.cursor != - filter->archive->client.nodes - 1) { - if (client_switch_proxy(filter, - filter->archive->client.cursor + 1) - == ARCHIVE_OK) - continue; - } - filter->client_buff = NULL; - filter->end_of_file = 1; - return (total_bytes_skipped); - } - - if (bytes_read >= request) { - filter->client_next = - ((const char *)filter->client_buff) + request; - filter->client_avail = (size_t)(bytes_read - request); - filter->client_total = bytes_read; - total_bytes_skipped += request; - filter->position += request; - return (total_bytes_skipped); - } - - filter->position += bytes_read; - total_bytes_skipped += bytes_read; - request -= bytes_read; - } -} - -/** - * Returns ARCHIVE_FAILED if seeking isn't supported. - */ -int64_t -__archive_read_seek(struct archive_read *a, int64_t offset, int whence) -{ - return __archive_read_filter_seek(a->filter, offset, whence); -} - -int64_t -__archive_read_filter_seek(struct archive_read_filter *filter, int64_t offset, - int whence) -{ - struct archive_read_client *client; - int64_t r; - unsigned int cursor; - - if (filter->closed || filter->fatal) - return (ARCHIVE_FATAL); - if (filter->can_seek == 0) - return (ARCHIVE_FAILED); - - client = &(filter->archive->client); - switch (whence) { - case SEEK_CUR: - /* Adjust the offset and use SEEK_SET instead */ - offset += filter->position; - __LA_FALLTHROUGH; - case SEEK_SET: - cursor = 0; - while (1) - { - if (client->dataset[cursor].begin_position < 0 || - client->dataset[cursor].total_size < 0 || - client->dataset[cursor].begin_position + - client->dataset[cursor].total_size - 1 > offset || - cursor + 1 >= client->nodes) - break; - r = client->dataset[cursor].begin_position + - client->dataset[cursor].total_size; - client->dataset[++cursor].begin_position = r; - } - while (1) { - r = client_switch_proxy(filter, cursor); - if (r != ARCHIVE_OK) - return r; - if ((r = client_seek_proxy(filter, 0, SEEK_END)) < 0) - return r; - client->dataset[cursor].total_size = r; - if (client->dataset[cursor].begin_position + - client->dataset[cursor].total_size - 1 > offset || - cursor + 1 >= client->nodes) - break; - r = client->dataset[cursor].begin_position + - client->dataset[cursor].total_size; - client->dataset[++cursor].begin_position = r; - } - offset -= client->dataset[cursor].begin_position; - if (offset < 0 - || offset > client->dataset[cursor].total_size) - return ARCHIVE_FATAL; - if ((r = client_seek_proxy(filter, offset, SEEK_SET)) < 0) - return r; - break; - - case SEEK_END: - cursor = 0; - while (1) { - if (client->dataset[cursor].begin_position < 0 || - client->dataset[cursor].total_size < 0 || - cursor + 1 >= client->nodes) - break; - r = client->dataset[cursor].begin_position + - client->dataset[cursor].total_size; - client->dataset[++cursor].begin_position = r; - } - while (1) { - r = client_switch_proxy(filter, cursor); - if (r != ARCHIVE_OK) - return r; - if ((r = client_seek_proxy(filter, 0, SEEK_END)) < 0) - return r; - client->dataset[cursor].total_size = r; - r = client->dataset[cursor].begin_position + - client->dataset[cursor].total_size; - if (cursor + 1 >= client->nodes) - break; - client->dataset[++cursor].begin_position = r; - } - while (1) { - if (r + offset >= - client->dataset[cursor].begin_position) - break; - offset += client->dataset[cursor].total_size; - if (cursor == 0) - break; - cursor--; - r = client->dataset[cursor].begin_position + - client->dataset[cursor].total_size; - } - offset = (r + offset) - client->dataset[cursor].begin_position; - if ((r = client_switch_proxy(filter, cursor)) != ARCHIVE_OK) - return r; - r = client_seek_proxy(filter, offset, SEEK_SET); - if (r < ARCHIVE_OK) - return r; - break; - - default: - return (ARCHIVE_FATAL); - } - r += client->dataset[cursor].begin_position; - - if (r >= 0) { - /* - * Ouch. Clearing the buffer like this hurts, especially - * at bid time. A lot of our efficiency at bid time comes - * from having bidders reuse the data we've already read. - * - * TODO: If the seek request is in data we already - * have, then don't call the seek callback. - * - * TODO: Zip seeks to end-of-file at bid time. If - * other formats also start doing this, we may need to - * find a way for clients to fudge the seek offset to - * a block boundary. - * - * Hmmm... If whence was SEEK_END, we know the file - * size is (r - offset). Can we use that to simplify - * the TODO items above? - */ - filter->avail = filter->client_avail = 0; - filter->next = filter->buffer; - filter->position = r; - filter->end_of_file = 0; - } - return r; -} diff --git a/thirdparty/libarchive/libarchive/archive_read_add_passphrase.3 b/thirdparty/libarchive/libarchive/archive_read_add_passphrase.3 deleted file mode 100644 index ca60d4fc6..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_add_passphrase.3 +++ /dev/null @@ -1,74 +0,0 @@ -.\" Copyright (c) 2014 Michihiro NAKAJIMA -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd September 14, 2014 -.Dt ARCHIVE_READ_ADD_PASSPHRASE 3 -.Os -.Sh NAME -.Nm archive_read_add_passphrase , -.Nm archive_read_set_passphrase_callback -.Nd functions for reading encrypted archives -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive.h -.Ft int -.Fo archive_read_add_passphrase -.Fa "struct archive *" -.Fa "const char *passphrase" -.Fc -.Ft int -.Fo archive_read_set_passphrase_callback -.Fa "struct archive *" -.Fa "void *client_data" -.Fa "archive_passphrase_callback *" -.Fc -.Sh DESCRIPTION -.Bl -tag -width indent -.It Fn archive_read_add_passphrase -Register passphrases for reading an encryption archive. -If -.Ar passphrase -is -.Dv NULL -or empty, this function will do nothing and -.Cm ARCHIVE_FAILED -will be returned. -Otherwise, -.Cm ARCHIVE_OK -will be returned. -.It Fn archive_read_set_passphrase_callback -Register a callback function that will be invoked to get a passphrase -for decryption after trying all the passphrases registered by the -.Fn archive_read_add_passphrase -function failed. -.El -.\" .Sh ERRORS -.Sh SEE ALSO -.Xr tar 1 , -.Xr archive_read 3 , -.Xr archive_read_set_options 3 , -.Xr libarchive 3 diff --git a/thirdparty/libarchive/libarchive/archive_read_add_passphrase.c b/thirdparty/libarchive/libarchive/archive_read_add_passphrase.c deleted file mode 100644 index f0b1ab933..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_add_passphrase.c +++ /dev/null @@ -1,190 +0,0 @@ -/*- - * Copyright (c) 2014 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#include "archive_read_private.h" - -static void -add_passphrase_to_tail(struct archive_read *a, - struct archive_read_passphrase *p) -{ - *a->passphrases.last = p; - a->passphrases.last = &p->next; - p->next = NULL; -} - -static struct archive_read_passphrase * -remove_passphrases_from_head(struct archive_read *a) -{ - struct archive_read_passphrase *p; - - p = a->passphrases.first; - if (p != NULL) - a->passphrases.first = p->next; - return (p); -} - -static void -insert_passphrase_to_head(struct archive_read *a, - struct archive_read_passphrase *p) -{ - p->next = a->passphrases.first; - a->passphrases.first = p; - if (&a->passphrases.first == a->passphrases.last) { - a->passphrases.last = &p->next; - p->next = NULL; - } -} - -static struct archive_read_passphrase * -new_read_passphrase(struct archive_read *a, const char *passphrase) -{ - struct archive_read_passphrase *p; - - p = malloc(sizeof(*p)); - if (p == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - return (NULL); - } - p->passphrase = strdup(passphrase); - if (p->passphrase == NULL) { - free(p); - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - return (NULL); - } - return (p); -} - -int -archive_read_add_passphrase(struct archive *_a, const char *passphrase) -{ - struct archive_read *a = (struct archive_read *)_a; - struct archive_read_passphrase *p; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, - "archive_read_add_passphrase"); - - if (passphrase == NULL || passphrase[0] == '\0') { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Empty passphrase is unacceptable"); - return (ARCHIVE_FAILED); - } - - p = new_read_passphrase(a, passphrase); - if (p == NULL) - return (ARCHIVE_FATAL); - add_passphrase_to_tail(a, p); - - return (ARCHIVE_OK); -} - -int -archive_read_set_passphrase_callback(struct archive *_a, void *client_data, - archive_passphrase_callback *cb) -{ - struct archive_read *a = (struct archive_read *)_a; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, - "archive_read_set_passphrase_callback"); - - a->passphrases.callback = cb; - a->passphrases.client_data = client_data; - return (ARCHIVE_OK); -} - -/* - * Call this in advance when you start to get a passphrase for decryption - * for a entry. - */ -void -__archive_read_reset_passphrase(struct archive_read *a) -{ - - a->passphrases.candidate = -1; -} - -/* - * Get a passphrase for decryption. - */ -const char * -__archive_read_next_passphrase(struct archive_read *a) -{ - struct archive_read_passphrase *p; - const char *passphrase; - - if (a->passphrases.candidate < 0) { - /* Count out how many passphrases we have. */ - int cnt = 0; - - for (p = a->passphrases.first; p != NULL; p = p->next) - cnt++; - a->passphrases.candidate = cnt; - p = a->passphrases.first; - } else if (a->passphrases.candidate > 1) { - /* Rotate a passphrase list. */ - a->passphrases.candidate--; - p = remove_passphrases_from_head(a); - add_passphrase_to_tail(a, p); - /* Pick a new passphrase candidate up. */ - p = a->passphrases.first; - } else if (a->passphrases.candidate == 1) { - /* This case is that all candidates failed to decrypt. */ - a->passphrases.candidate = 0; - if (a->passphrases.first->next != NULL) { - /* Rotate a passphrase list. */ - p = remove_passphrases_from_head(a); - add_passphrase_to_tail(a, p); - } - p = NULL; - } else /* There is no passphrase candidate. */ - p = NULL; - - if (p != NULL) - passphrase = p->passphrase; - else if (a->passphrases.callback != NULL) { - /* Get a passphrase through a call-back function - * since we tried all passphrases out or we don't - * have it. */ - passphrase = a->passphrases.callback(&a->archive, - a->passphrases.client_data); - if (passphrase != NULL) { - p = new_read_passphrase(a, passphrase); - if (p == NULL) - return (NULL); - insert_passphrase_to_head(a, p); - a->passphrases.candidate = 1; - } - } else - passphrase = NULL; - - return (passphrase); -} diff --git a/thirdparty/libarchive/libarchive/archive_read_append_filter.c b/thirdparty/libarchive/libarchive/archive_read_append_filter.c deleted file mode 100644 index 25dc4b2a2..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_append_filter.c +++ /dev/null @@ -1,204 +0,0 @@ -/*- - * Copyright (c) 2003-2012 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_ERRNO_H -#include -#endif - -#include "archive.h" -#include "archive_private.h" -#include "archive_read_private.h" - -int -archive_read_append_filter(struct archive *_a, int code) -{ - int r1, r2, number_bidders, i; - char str[20]; - struct archive_read_filter_bidder *bidder; - struct archive_read_filter *filter; - struct archive_read *a = (struct archive_read *)_a; - - r2 = (ARCHIVE_OK); - switch (code) - { - case ARCHIVE_FILTER_NONE: - /* No filter to add, so do nothing. - * NOTE: An initial "NONE" type filter is always set at the end of the - * filter chain. - */ - r1 = (ARCHIVE_OK); - break; - case ARCHIVE_FILTER_GZIP: - strcpy(str, "gzip"); - r1 = archive_read_support_filter_gzip(_a); - break; - case ARCHIVE_FILTER_BZIP2: - strcpy(str, "bzip2"); - r1 = archive_read_support_filter_bzip2(_a); - break; - case ARCHIVE_FILTER_COMPRESS: - strcpy(str, "compress (.Z)"); - r1 = archive_read_support_filter_compress(_a); - break; - case ARCHIVE_FILTER_PROGRAM: - archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, - "Cannot append program filter using archive_read_append_filter"); - return (ARCHIVE_FATAL); - case ARCHIVE_FILTER_LZMA: - strcpy(str, "lzma"); - r1 = archive_read_support_filter_lzma(_a); - break; - case ARCHIVE_FILTER_XZ: - strcpy(str, "xz"); - r1 = archive_read_support_filter_xz(_a); - break; - case ARCHIVE_FILTER_UU: - strcpy(str, "uu"); - r1 = archive_read_support_filter_uu(_a); - break; - case ARCHIVE_FILTER_RPM: - strcpy(str, "rpm"); - r1 = archive_read_support_filter_rpm(_a); - break; - case ARCHIVE_FILTER_LZ4: - strcpy(str, "lz4"); - r1 = archive_read_support_filter_lz4(_a); - break; - case ARCHIVE_FILTER_ZSTD: - strcpy(str, "zstd"); - r1 = archive_read_support_filter_zstd(_a); - break; - case ARCHIVE_FILTER_LZIP: - strcpy(str, "lzip"); - r1 = archive_read_support_filter_lzip(_a); - break; - case ARCHIVE_FILTER_LRZIP: - strcpy(str, "lrzip"); - r1 = archive_read_support_filter_lrzip(_a); - break; - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, - "Invalid filter code specified"); - return (ARCHIVE_FATAL); - } - - if (code != ARCHIVE_FILTER_NONE) - { - number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]); - - bidder = a->bidders; - for (i = 0; i < number_bidders; i++, bidder++) - { - if (!bidder->name || !strcmp(bidder->name, str)) - break; - } - if (!bidder->name || strcmp(bidder->name, str)) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, - "Internal error: Unable to append filter"); - return (ARCHIVE_FATAL); - } - - filter - = (struct archive_read_filter *)calloc(1, sizeof(*filter)); - if (filter == NULL) - { - archive_set_error(&a->archive, ENOMEM, "Out of memory"); - return (ARCHIVE_FATAL); - } - filter->bidder = bidder; - filter->archive = a; - filter->upstream = a->filter; - a->filter = filter; - r2 = (bidder->vtable->init)(a->filter); - if (r2 != ARCHIVE_OK) { - __archive_read_free_filters(a); - return (ARCHIVE_FATAL); - } - } - - a->bypass_filter_bidding = 1; - return (r1 < r2) ? r1 : r2; -} - -int -archive_read_append_filter_program(struct archive *_a, const char *cmd) -{ - return (archive_read_append_filter_program_signature(_a, cmd, NULL, 0)); -} - -int -archive_read_append_filter_program_signature(struct archive *_a, - const char *cmd, const void *signature, size_t signature_len) -{ - int r, number_bidders, i; - struct archive_read_filter_bidder *bidder; - struct archive_read_filter *filter; - struct archive_read *a = (struct archive_read *)_a; - - if (archive_read_support_filter_program_signature(_a, cmd, signature, - signature_len) != (ARCHIVE_OK)) - return (ARCHIVE_FATAL); - - number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]); - - bidder = a->bidders; - for (i = 0; i < number_bidders; i++, bidder++) - { - /* Program bidder name set to filter name after initialization */ - if (bidder->data && !bidder->name) - break; - } - if (!bidder->data) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, - "Internal error: Unable to append program filter"); - return (ARCHIVE_FATAL); - } - - filter - = (struct archive_read_filter *)calloc(1, sizeof(*filter)); - if (filter == NULL) - { - archive_set_error(&a->archive, ENOMEM, "Out of memory"); - return (ARCHIVE_FATAL); - } - filter->bidder = bidder; - filter->archive = a; - filter->upstream = a->filter; - a->filter = filter; - r = (bidder->vtable->init)(a->filter); - if (r != ARCHIVE_OK) { - __archive_read_free_filters(a); - return (ARCHIVE_FATAL); - } - bidder->name = a->filter->name; - - a->bypass_filter_bidding = 1; - return r; -} diff --git a/thirdparty/libarchive/libarchive/archive_read_data.3 b/thirdparty/libarchive/libarchive/archive_read_data.3 deleted file mode 100644 index 78c0c9000..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_data.3 +++ /dev/null @@ -1,130 +0,0 @@ -.\" Copyright (c) 2003-2011 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd February 2, 2012 -.Dt ARCHIVE_READ_DATA 3 -.Os -.Sh NAME -.Nm archive_read_data , -.Nm archive_read_data_block , -.Nm archive_read_data_skip , -.Nm archive_read_data_into_fd -.Nd functions for reading streaming archives -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive.h -.Ft la_ssize_t -.Fn archive_read_data "struct archive *" "void *buff" "size_t len" -.Ft int -.Fo archive_read_data_block -.Fa "struct archive *" -.Fa "const void **buff" -.Fa "size_t *len" -.Fa "off_t *offset" -.Fc -.Ft int -.Fn archive_read_data_skip "struct archive *" -.Ft int -.Fn archive_read_data_into_fd "struct archive *" "int fd" -.\" -.Sh DESCRIPTION -.Bl -tag -compact -width indent -.It Fn archive_read_data -Read data associated with the header just read. -Internally, this is a convenience function that calls -.Fn archive_read_data_block -and fills any gaps with nulls so that callers see a single -continuous stream of data. -.It Fn archive_read_data_block -Return the next available block of data for this entry. -Unlike -.Fn archive_read_data , -the -.Fn archive_read_data_block -function avoids copying data and allows you to correctly handle -sparse files, as supported by some archive formats. -The library guarantees that offsets will increase and that blocks -will not overlap. -Note that the blocks returned from this function can be much larger -than the block size read from disk, due to compression -and internal buffer optimizations. -.It Fn archive_read_data_skip -A convenience function that repeatedly calls -.Fn archive_read_data_block -to skip all of the data for this archive entry. -Note that this function is invoked automatically by -.Fn archive_read_next_header2 -if the previous entry was not completely consumed. -.It Fn archive_read_data_into_fd -A convenience function that repeatedly calls -.Fn archive_read_data_block -to copy the entire entry to the provided file descriptor. -.El -.\" -.Sh RETURN VALUES -Most functions return zero on success, non-zero on error. -The possible return codes include: -.Cm ARCHIVE_OK -(the operation succeeded), -.Cm ARCHIVE_WARN -(the operation succeeded but a non-critical error was encountered), -.Cm ARCHIVE_EOF -(end-of-archive was encountered), -.Cm ARCHIVE_RETRY -(the operation failed but can be retried), -and -.Cm ARCHIVE_FATAL -(there was a fatal error; the archive should be closed immediately). -.Pp -.Fn archive_read_data -returns a count of bytes actually read or zero at the end of the entry. -On error, a value of -.Cm ARCHIVE_FATAL , -.Cm ARCHIVE_WARN , -or -.Cm ARCHIVE_RETRY -is returned. -.\" -.Sh ERRORS -Detailed error codes and textual descriptions are available from the -.Fn archive_errno -and -.Fn archive_error_string -functions. -.\" -.Sh SEE ALSO -.Xr tar 1 , -.Xr archive_read 3 , -.Xr archive_read_extract 3 , -.Xr archive_read_filter 3 , -.Xr archive_read_format 3 , -.Xr archive_read_header 3 , -.Xr archive_read_open 3 , -.Xr archive_read_set_options 3 , -.Xr archive_util 3 , -.Xr libarchive 3 , -.Xr tar 5 diff --git a/thirdparty/libarchive/libarchive/archive_read_data_into_fd.c b/thirdparty/libarchive/libarchive/archive_read_data_into_fd.c deleted file mode 100644 index f16ca5c82..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_data_into_fd.c +++ /dev/null @@ -1,144 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_data_into_fd.c,v 1.16 2008/05/23 05:01:29 cperciva Exp $"); - -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif - -#include "archive.h" -#include "archive_private.h" - -/* Maximum amount of data to write at one time. */ -#define MAX_WRITE (1024 * 1024) - -/* - * This implementation minimizes copying of data and is sparse-file aware. - */ -static int -pad_to(struct archive *a, int fd, int can_lseek, - size_t nulls_size, const char *nulls, - int64_t target_offset, int64_t actual_offset) -{ - size_t to_write; - ssize_t bytes_written; - - if (can_lseek) { - actual_offset = lseek(fd, - target_offset - actual_offset, SEEK_CUR); - if (actual_offset != target_offset) { - archive_set_error(a, errno, "Seek error"); - return (ARCHIVE_FATAL); - } - return (ARCHIVE_OK); - } - while (target_offset > actual_offset) { - to_write = nulls_size; - if (target_offset < actual_offset + (int64_t)nulls_size) - to_write = (size_t)(target_offset - actual_offset); - bytes_written = write(fd, nulls, to_write); - if (bytes_written < 0) { - archive_set_error(a, errno, "Write error"); - return (ARCHIVE_FATAL); - } - actual_offset += bytes_written; - } - return (ARCHIVE_OK); -} - - -int -archive_read_data_into_fd(struct archive *a, int fd) -{ - struct stat st; - int r, r2; - const void *buff; - size_t size, bytes_to_write; - ssize_t bytes_written; - int64_t target_offset; - int64_t actual_offset = 0; - int can_lseek; - char *nulls = NULL; - size_t nulls_size = 16384; - - archive_check_magic(a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA, - "archive_read_data_into_fd"); - - can_lseek = (fstat(fd, &st) == 0) && S_ISREG(st.st_mode); - if (!can_lseek) { - nulls = calloc(1, nulls_size); - if (!nulls) { - r = ARCHIVE_FATAL; - goto cleanup; - } - } - - while ((r = archive_read_data_block(a, &buff, &size, &target_offset)) == - ARCHIVE_OK) { - const char *p = buff; - if (target_offset > actual_offset) { - r = pad_to(a, fd, can_lseek, nulls_size, nulls, - target_offset, actual_offset); - if (r != ARCHIVE_OK) - break; - actual_offset = target_offset; - } - while (size > 0) { - bytes_to_write = size; - if (bytes_to_write > MAX_WRITE) - bytes_to_write = MAX_WRITE; - bytes_written = write(fd, p, bytes_to_write); - if (bytes_written < 0) { - archive_set_error(a, errno, "Write error"); - r = ARCHIVE_FATAL; - goto cleanup; - } - actual_offset += bytes_written; - p += bytes_written; - size -= bytes_written; - } - } - - if (r == ARCHIVE_EOF && target_offset > actual_offset) { - r2 = pad_to(a, fd, can_lseek, nulls_size, nulls, - target_offset, actual_offset); - if (r2 != ARCHIVE_OK) - r = r2; - } - -cleanup: - free(nulls); - if (r != ARCHIVE_EOF) - return (r); - return (ARCHIVE_OK); -} diff --git a/thirdparty/libarchive/libarchive/archive_read_disk.3 b/thirdparty/libarchive/libarchive/archive_read_disk.3 deleted file mode 100644 index 8b568d7b0..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_disk.3 +++ /dev/null @@ -1,424 +0,0 @@ -.\" Copyright (c) 2003-2009 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd April 3, 2017 -.Dt ARCHIVE_READ_DISK 3 -.Os -.Sh NAME -.Nm archive_read_disk_new , -.Nm archive_read_disk_open , -.Nm archive_read_disk_open_w , -.Nm archive_read_disk_set_behavior , -.Nm archive_read_disk_set_symlink_logical , -.Nm archive_read_disk_set_symlink_physical , -.Nm archive_read_disk_set_symlink_hybrid , -.Nm archive_read_disk_entry_from_file , -.Nm archive_read_disk_gname , -.Nm archive_read_disk_uname , -.Nm archive_read_disk_set_uname_lookup , -.Nm archive_read_disk_set_gname_lookup , -.Nm archive_read_disk_set_standard_lookup , -.Nm archive_read_disk_descend , -.Nm archive_read_disk_can_descend , -.Nm archive_read_disk_current_filesystem , -.Nm archive_read_disk_current_filesystem_is_synthetic , -.Nm archive_read_disk_current_filesystem_is_remote , -.Nm archive_read_disk_set_matching , -.Nm archive_read_disk_set_metadata_filter_callback , -.Nd functions for reading objects from disk -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive.h -.Ft struct archive * -.Fn archive_read_disk_new "void" -.Ft int -.Fn archive_read_disk_open "struct archive *" "const char *" -.Ft int -.Fn archive_read_disk_open_w "struct archive *" "const wchar_t *" -.Ft int -.Fn archive_read_disk_set_behavior "struct archive *" "int" -.Ft int -.Fn archive_read_disk_set_symlink_logical "struct archive *" -.Ft int -.Fn archive_read_disk_set_symlink_physical "struct archive *" -.Ft int -.Fn archive_read_disk_set_symlink_hybrid "struct archive *" -.Ft const char * -.Fn archive_read_disk_gname "struct archive *" "gid_t" -.Ft const char * -.Fn archive_read_disk_uname "struct archive *" "uid_t" -.Ft int -.Fo archive_read_disk_set_gname_lookup -.Fa "struct archive *" -.Fa "void *" -.Fa "const char *(*lookup)(void *, gid_t)" -.Fa "void (*cleanup)(void *)" -.Fc -.Ft int -.Fo archive_read_disk_set_uname_lookup -.Fa "struct archive *" -.Fa "void *" -.Fa "const char *(*lookup)(void *, uid_t)" -.Fa "void (*cleanup)(void *)" -.Fc -.Ft int -.Fn archive_read_disk_set_standard_lookup "struct archive *" -.Ft int -.Fo archive_read_disk_entry_from_file -.Fa "struct archive *" -.Fa "struct archive_entry *" -.Fa "int fd" -.Fa "const struct stat *" -.Fc -.Ft int -.Fn archive_read_disk_descend "struct archive *" -.Ft int -.Fn archive_read_disk_can_descend "struct archive *" -.Ft int -.Fn archive_read_disk_current_filesystem "struct archive *" -.Ft int -.Fn archive_read_disk_current_filesystem_is_synthetic "struct archive *" -.Ft int -.Fn archive_read_disk_current_filesystem_is_remote "struct archive *" -.Ft int -.Fo archive_read_disk_set_matching -.Fa "struct archive *" -.Fa "struct archive *" -.Fa "void (*excluded_func)(struct archive *, void *, struct archive entry *)" -.Fa "void *" -.Fc -.Ft int -.Fo archive_read_disk_set_metadata_filter_callback -.Fa "struct archive *" -.Fa "int (*metadata_filter_func)(struct archive *, void*, struct archive_entry *)" -.Fa "void *" -.Fc -.Sh DESCRIPTION -These functions provide an API for reading information about -objects on disk. -In particular, they provide an interface for populating -.Tn struct archive_entry -objects. -.Bl -tag -width indent -.It Fn archive_read_disk_new -Allocates and initializes a -.Tn struct archive -object suitable for reading object information from disk. -.It Fn archive_read_disk_open -Opens the file or directory from the given path and prepares the -.Tn struct archive -to read it from disk. -.It Fn archive_read_disk_open_w -Opens the file or directory from the given path as a wide character string and prepares the -.Tn struct archive -to read it from disk. -.It Fn archive_read_disk_set_behavior -Configures various behavior options when reading entries from disk. -The flags field consists of a bitwise OR of one or more of the -following values: -.Bl -tag -compact -width "indent" -.It Cm ARCHIVE_READDISK_HONOR_NODUMP -Skip files and directories with the nodump file attribute (file flag) set. -By default, the nodump file attribute is ignored. -.It Cm ARCHIVE_READDISK_MAC_COPYFILE -Mac OS X specific. -Read metadata (ACLs and extended attributes) with -.Xr copyfile 3 . -By default, metadata is read using -.Xr copyfile 3 . -.It Cm ARCHIVE_READDISK_NO_ACL -Do not read Access Control Lists. -By default, ACLs are read from disk. -.It Cm ARCHIVE_READDISK_NO_FFLAGS -Do not read file attributes (file flags). -By default, file attributes are read from disk. -See -.Xr chattr 1 -.Pq Linux -or -.Xr chflags 1 -.Pq FreeBSD, Mac OS X -for more information on file attributes. -.It Cm ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS -Do not traverse mount points. -By default, mount points are traversed. -.It Cm ARCHIVE_READDISK_NO_XATTR -Do not read extended file attributes (xattrs). -By default, extended file attributes are read from disk. -See -.Xr xattr 7 -.Pq Linux , -.Xr xattr 2 -.Pq Mac OS X , -or -.Xr getextattr 8 -.Pq FreeBSD -for more information on extended file attributes. -.It Cm ARCHIVE_READDISK_RESTORE_ATIME -Restore access time of traversed files. -By default, access time of traversed files is not restored. -.It Cm ARCHIVE_READDISK_NO_SPARSE -Do not read sparse file information. -By default, sparse file information is read from disk. -.El -.It Xo -.Fn archive_read_disk_set_symlink_logical , -.Fn archive_read_disk_set_symlink_physical , -.Fn archive_read_disk_set_symlink_hybrid -.Xc -This sets the mode used for handling symbolic links. -The -.Dq logical -mode follows all symbolic links. -The -.Dq physical -mode does not follow any symbolic links. -The -.Dq hybrid -mode currently behaves identically to the -.Dq logical -mode. -.It Xo -.Fn archive_read_disk_gname , -.Fn archive_read_disk_uname -.Xc -Returns a user or group name given a gid or uid value. -By default, these always return a NULL string. -.It Xo -.Fn archive_read_disk_set_gname_lookup , -.Fn archive_read_disk_set_uname_lookup -.Xc -These allow you to override the functions used for -user and group name lookups. -You may also provide a -.Tn void * -pointer to a private data structure and a cleanup function for -that data. -The cleanup function will be invoked when the -.Tn struct archive -object is destroyed or when new lookup functions are registered. -.It Fn archive_read_disk_set_standard_lookup -This convenience function installs a standard set of user -and group name lookup functions. -These functions use -.Xr getpwuid 3 -and -.Xr getgrgid 3 -to convert ids to names, defaulting to NULL if the names cannot -be looked up. -These functions also implement a simple memory cache to reduce -the number of calls to -.Xr getpwuid 3 -and -.Xr getgrgid 3 . -.It Fn archive_read_disk_entry_from_file -Populates a -.Tn struct archive_entry -object with information about a particular file. -The -.Tn archive_entry -object must have already been created with -.Xr archive_entry_new 3 -and at least one of the source path or path fields must already be set. -(If both are set, the source path will be used.) -.Pp -Information is read from disk using the path name from the -.Tn struct archive_entry -object. -If a file descriptor is provided, some information will be obtained using -that file descriptor, on platforms that support the appropriate -system calls. -.Pp -If a pointer to a -.Tn struct stat -is provided, information from that structure will be used instead -of reading from the disk where appropriate. -This can provide performance benefits in scenarios where -.Tn struct stat -information has already been read from the disk as a side effect -of some other operation. -(For example, directory traversal libraries often provide this information.) -.Pp -Where necessary, user and group ids are converted to user and group names -using the currently-registered lookup functions above. -This affects the file ownership fields and ACL values in the -.Tn struct archive_entry -object. -.It Fn archive_read_disk_descend -If the current entry can be descended, this function will mark the directory as the next entry for -.Xr archive_read_header 3 -to visit. -.It Fn archive_read_disk_can_descend -Returns 1 if the current entry is an unvisited directory and 0 otherwise. -.It Fn archive_read_disk_current_filesystem -Returns the index of the most recent filesystem entry that has been visited through archive_read_disk -.It Fn archive_read_disk_current_filesystem_is_synthetic -Returns 1 if the current filesystem is a virtual filesystem. Returns 0 if the current filesystem is not a virtual filesystem. Returns -1 if it is unknown. -.It Fn archive_read_disk_current_filesystem_is_remote -Returns 1 if the current filesystem is a remote filesystem. Returns 0 if the current filesystem is not a remote filesystem. Returns -1 if it is unknown. -.It Fn archive_read_disk_set_matching -Allows the caller to set -.Tn struct archive -*_ma to compare each entry during -.Xr archive_read_header 3 -calls. If matched based on calls to -.Tn archive_match_path_excluded , -.Tn archive_match_time_excluded , -or -.Tn archive_match_owner_excluded , -then the callback function specified by the _excluded_func parameter will execute. This function will recieve data provided to the fourth parameter, void *_client_data. -.It Fn archive_read_disk_set_metadata_filter_callback -Allows the caller to set a callback function during calls to -.Xr archive_read_header 3 -to filter out metadata for each entry. The callback function recieves the -.Tn struct archive -object, void* custom filter data, and the -.Tn struct archive_entry . -If the callback function returns an error, ARCHIVE_RETRY will be returned and the entry will not be further processed. -.El -More information about the -.Va struct archive -object and the overall design of the library can be found in the -.Xr libarchive 3 -overview. -.Sh EXAMPLES -The following illustrates basic usage of the library by -showing how to use it to copy an item on disk into an archive. -.Bd -literal -offset indent -void -file_to_archive(struct archive *a, const char *name) -{ - char buff[8192]; - size_t bytes_read; - struct archive *ard; - struct archive_entry *entry; - int fd; - - ard = archive_read_disk_new(); - archive_read_disk_set_standard_lookup(ard); - entry = archive_entry_new(); - fd = open(name, O_RDONLY); - if (fd < 0) - return; - archive_entry_copy_pathname(entry, name); - archive_read_disk_entry_from_file(ard, entry, fd, NULL); - archive_write_header(a, entry); - while ((bytes_read = read(fd, buff, sizeof(buff))) > 0) - archive_write_data(a, buff, bytes_read); - archive_write_finish_entry(a); - archive_read_free(ard); - archive_entry_free(entry); -} -.Ed -.Sh RETURN VALUES -Most functions return -.Cm ARCHIVE_OK -(zero) on success, or one of several negative -error codes for errors. -Specific error codes include: -.Cm ARCHIVE_RETRY -for operations that might succeed if retried, -.Cm ARCHIVE_WARN -for unusual conditions that do not prevent further operations, and -.Cm ARCHIVE_FATAL -for serious errors that make remaining operations impossible. -.Pp -.Fn archive_read_disk_new -returns a pointer to a newly-allocated -.Tn struct archive -object or NULL if the allocation failed for any reason. -.Pp -.Fn archive_read_disk_gname -and -.Fn archive_read_disk_uname -return -.Tn const char * -pointers to the textual name or NULL if the lookup failed for any reason. -The returned pointer points to internal storage that -may be reused on the next call to either of these functions; -callers should copy the string if they need to continue accessing it. -.\" -.Sh ERRORS -Detailed error codes and textual descriptions are available from the -.Fn archive_errno -and -.Fn archive_error_string -functions. -.\" -.Sh SEE ALSO -.Xr tar 1 , -.Xr archive_read 3 , -.Xr archive_util 3 , -.Xr archive_write 3 , -.Xr archive_write_disk 3 , -.Xr libarchive 3 -.Sh HISTORY -The -.Nm libarchive -library first appeared in -.Fx 5.3 . -The -.Nm archive_read_disk -interface was added to -.Nm libarchive 2.6 -and first appeared in -.Fx 8.0 . -.Sh AUTHORS -.An -nosplit -The -.Nm libarchive -library was written by -.An Tim Kientzle Aq kientzle@FreeBSD.org . -.Sh BUGS -The -.Dq standard -user name and group name lookup functions are not the defaults because -.Xr getgrgid 3 -and -.Xr getpwuid 3 -are sometimes too large for particular applications. -The current design allows the application author to use a more -compact implementation when appropriate. -.Pp -The full list of metadata read from disk by -.Fn archive_read_disk_entry_from_file -is necessarily system-dependent. -.Pp -The -.Fn archive_read_disk_entry_from_file -function reads as much information as it can from disk. -Some method should be provided to limit this so that clients who -do not need ACLs, for instance, can avoid the extra work needed -to look up such information. -.Pp -This API should provide a set of methods for walking a directory tree. -That would make it a direct parallel of the -.Xr archive_read 3 -API. -When such methods are implemented, the -.Dq hybrid -symbolic link mode will make sense. diff --git a/thirdparty/libarchive/libarchive/archive_read_disk_entry_from_file.c b/thirdparty/libarchive/libarchive/archive_read_disk_entry_from_file.c deleted file mode 100644 index ab0270bc2..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_disk_entry_from_file.c +++ /dev/null @@ -1,1086 +0,0 @@ -/*- - * Copyright (c) 2003-2009 Tim Kientzle - * Copyright (c) 2010-2012 Michihiro NAKAJIMA - * Copyright (c) 2016 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD"); - -/* This is the tree-walking code for POSIX systems. */ -#if !defined(_WIN32) || defined(__CYGWIN__) - -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_EXTATTR_H -#include -#endif -#ifdef HAVE_SYS_IOCTL_H -#include -#endif -#ifdef HAVE_SYS_PARAM_H -#include -#endif -#ifdef HAVE_SYS_STAT_H -#include -#endif -#if defined(HAVE_SYS_XATTR_H) -#include -#elif defined(HAVE_ATTR_XATTR_H) -#include -#endif -#ifdef HAVE_SYS_EA_H -#include -#endif -#ifdef HAVE_COPYFILE_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif -#ifdef HAVE_LIMITS_H -#include -#endif -#ifdef HAVE_LINUX_TYPES_H -#include -#endif -#ifdef HAVE_LINUX_FIEMAP_H -#include -#endif -#ifdef HAVE_LINUX_FS_H -#include -#endif -/* - * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h. - * As the include guards don't agree, the order of include is important. - */ -#ifdef HAVE_LINUX_EXT2_FS_H -#include /* for Linux file flags */ -#endif -#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__) -#include /* Linux file flags, broken on Cygwin */ -#endif -#ifdef HAVE_PATHS_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" -#include "archive_private.h" -#include "archive_read_disk_private.h" - -#ifndef O_CLOEXEC -#define O_CLOEXEC 0 -#endif - -static int setup_mac_metadata(struct archive_read_disk *, - struct archive_entry *, int *fd); -#ifdef ARCHIVE_XATTR_FREEBSD -static int setup_xattrs_namespace(struct archive_read_disk *, - struct archive_entry *, int *, int); -#endif -static int setup_xattrs(struct archive_read_disk *, - struct archive_entry *, int *fd); -static int setup_sparse(struct archive_read_disk *, - struct archive_entry *, int *fd); -#if defined(HAVE_LINUX_FIEMAP_H) -static int setup_sparse_fiemap(struct archive_read_disk *, - struct archive_entry *, int *fd); -#endif - -#if !ARCHIVE_ACL_SUPPORT -int -archive_read_disk_entry_setup_acls(struct archive_read_disk *a, - struct archive_entry *entry, int *fd) -{ - (void)a; /* UNUSED */ - (void)entry; /* UNUSED */ - (void)fd; /* UNUSED */ - return (ARCHIVE_OK); -} -#endif - -/* - * Enter working directory and return working pathname of archive_entry. - * If a pointer to an integer is provided and its value is below zero - * open a file descriptor on this pathname. - */ -const char * -archive_read_disk_entry_setup_path(struct archive_read_disk *a, - struct archive_entry *entry, int *fd) -{ - const char *path; - - path = archive_entry_sourcepath(entry); - - if (path == NULL || (a->tree != NULL && - a->tree_enter_working_dir(a->tree) != 0)) - path = archive_entry_pathname(entry); - if (path == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Couldn't determine path"); - } else if (fd != NULL && *fd < 0 && a->tree != NULL && - (a->follow_symlinks || archive_entry_filetype(entry) != AE_IFLNK)) { - *fd = a->open_on_current_dir(a->tree, path, - O_RDONLY | O_NONBLOCK); - } - return (path); -} - -int -archive_read_disk_entry_from_file(struct archive *_a, - struct archive_entry *entry, - int fd, - const struct stat *st) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - const char *path, *name; - struct stat s; - int initial_fd = fd; - int r, r1; - - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_ANY, - "archive_read_disk_entry_from_file"); - - archive_clear_error(_a); - path = archive_entry_sourcepath(entry); - if (path == NULL) - path = archive_entry_pathname(entry); - - if (a->tree == NULL) { - if (st == NULL) { -#if HAVE_FSTAT - if (fd >= 0) { - if (fstat(fd, &s) != 0) { - archive_set_error(&a->archive, errno, - "Can't fstat"); - return (ARCHIVE_FAILED); - } - } else -#endif -#if HAVE_LSTAT - if (!a->follow_symlinks) { - if (lstat(path, &s) != 0) { - archive_set_error(&a->archive, errno, - "Can't lstat %s", path); - return (ARCHIVE_FAILED); - } - } else -#endif - if (la_stat(path, &s) != 0) { - archive_set_error(&a->archive, errno, - "Can't stat %s", path); - return (ARCHIVE_FAILED); - } - st = &s; - } - archive_entry_copy_stat(entry, st); - } - - /* Lookup uname/gname */ - name = archive_read_disk_uname(_a, archive_entry_uid(entry)); - if (name != NULL) - archive_entry_copy_uname(entry, name); - name = archive_read_disk_gname(_a, archive_entry_gid(entry)); - if (name != NULL) - archive_entry_copy_gname(entry, name); - -#ifdef HAVE_STRUCT_STAT_ST_FLAGS - /* On FreeBSD, we get flags for free with the stat. */ - /* TODO: Does this belong in copy_stat()? */ - if ((a->flags & ARCHIVE_READDISK_NO_FFLAGS) == 0 && st->st_flags != 0) - archive_entry_set_fflags(entry, st->st_flags, 0); -#endif - -#if (defined(FS_IOC_GETFLAGS) && defined(HAVE_WORKING_FS_IOC_GETFLAGS)) || \ - (defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)) - /* Linux requires an extra ioctl to pull the flags. Although - * this is an extra step, it has a nice side-effect: We get an - * open file descriptor which we can use in the subsequent lookups. */ - if ((a->flags & ARCHIVE_READDISK_NO_FFLAGS) == 0 && - (S_ISREG(st->st_mode) || S_ISDIR(st->st_mode))) { - if (fd < 0) { - if (a->tree != NULL) - fd = a->open_on_current_dir(a->tree, path, - O_RDONLY | O_NONBLOCK | O_CLOEXEC); - else - fd = open(path, O_RDONLY | O_NONBLOCK | - O_CLOEXEC); - __archive_ensure_cloexec_flag(fd); - } - if (fd >= 0) { - int stflags; - r = ioctl(fd, -#if defined(FS_IOC_GETFLAGS) - FS_IOC_GETFLAGS, -#else - EXT2_IOC_GETFLAGS, -#endif - &stflags); - if (r == 0 && stflags != 0) - archive_entry_set_fflags(entry, stflags, 0); - } - } -#endif - -#if defined(HAVE_READLINK) || defined(HAVE_READLINKAT) - if (S_ISLNK(st->st_mode)) { - size_t linkbuffer_len = st->st_size; - char *linkbuffer; - int lnklen; - - linkbuffer = malloc(linkbuffer_len + 1); - if (linkbuffer == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Couldn't read link data"); - return (ARCHIVE_FAILED); - } - if (a->tree != NULL) { -#ifdef HAVE_READLINKAT - lnklen = readlinkat(a->tree_current_dir_fd(a->tree), - path, linkbuffer, linkbuffer_len); -#else - if (a->tree_enter_working_dir(a->tree) != 0) { - archive_set_error(&a->archive, errno, - "Couldn't read link data"); - free(linkbuffer); - return (ARCHIVE_FAILED); - } - lnklen = readlink(path, linkbuffer, linkbuffer_len); -#endif /* HAVE_READLINKAT */ - } else - lnklen = readlink(path, linkbuffer, linkbuffer_len); - if (lnklen < 0) { - archive_set_error(&a->archive, errno, - "Couldn't read link data"); - free(linkbuffer); - return (ARCHIVE_FAILED); - } - linkbuffer[lnklen] = '\0'; - archive_entry_set_symlink(entry, linkbuffer); - free(linkbuffer); - } -#endif /* HAVE_READLINK || HAVE_READLINKAT */ - - r = 0; - if ((a->flags & ARCHIVE_READDISK_NO_ACL) == 0) - r = archive_read_disk_entry_setup_acls(a, entry, &fd); - if ((a->flags & ARCHIVE_READDISK_NO_XATTR) == 0) { - r1 = setup_xattrs(a, entry, &fd); - if (r1 < r) - r = r1; - } - if (a->flags & ARCHIVE_READDISK_MAC_COPYFILE) { - r1 = setup_mac_metadata(a, entry, &fd); - if (r1 < r) - r = r1; - } - if ((a->flags & ARCHIVE_READDISK_NO_SPARSE) == 0) { - r1 = setup_sparse(a, entry, &fd); - if (r1 < r) - r = r1; - } - - /* If we opened the file earlier in this function, close it. */ - if (initial_fd != fd) - close(fd); - return (r); -} - -#if defined(__APPLE__) && defined(HAVE_COPYFILE_H) -/* - * The Mac OS "copyfile()" API copies the extended metadata for a - * file into a separate file in AppleDouble format (see RFC 1740). - * - * Mac OS tar and cpio implementations store this extended - * metadata as a separate entry just before the regular entry - * with a "._" prefix added to the filename. - * - * Note that this is currently done unconditionally; the tar program has - * an option to discard this information before the archive is written. - * - * TODO: If there's a failure, report it and return ARCHIVE_WARN. - */ -static int -setup_mac_metadata(struct archive_read_disk *a, - struct archive_entry *entry, int *fd) -{ - int tempfd = -1; - int copyfile_flags = COPYFILE_NOFOLLOW | COPYFILE_ACL | COPYFILE_XATTR; - struct stat copyfile_stat; - int ret = ARCHIVE_OK; - void *buff = NULL; - int have_attrs; - const char *name, *tempdir; - struct archive_string tempfile; - - (void)fd; /* UNUSED */ - - name = archive_read_disk_entry_setup_path(a, entry, NULL); - if (name == NULL) - return (ARCHIVE_WARN); - - /* Short-circuit if there's nothing to do. */ - have_attrs = copyfile(name, NULL, 0, copyfile_flags | COPYFILE_CHECK); - if (have_attrs == -1) { - archive_set_error(&a->archive, errno, - "Could not check extended attributes"); - return (ARCHIVE_WARN); - } - if (have_attrs == 0) - return (ARCHIVE_OK); - - tempdir = NULL; - if (issetugid() == 0) - tempdir = getenv("TMPDIR"); - if (tempdir == NULL) - tempdir = _PATH_TMP; - archive_string_init(&tempfile); - archive_strcpy(&tempfile, tempdir); - archive_strcat(&tempfile, "tar.md.XXXXXX"); - tempfd = mkstemp(tempfile.s); - if (tempfd < 0) { - archive_set_error(&a->archive, errno, - "Could not open extended attribute file"); - ret = ARCHIVE_WARN; - goto cleanup; - } - __archive_ensure_cloexec_flag(tempfd); - - /* XXX I wish copyfile() could pack directly to a memory - * buffer; that would avoid the temp file here. For that - * matter, it would be nice if fcopyfile() actually worked, - * that would reduce the many open/close races here. */ - if (copyfile(name, tempfile.s, 0, copyfile_flags | COPYFILE_PACK)) { - archive_set_error(&a->archive, errno, - "Could not pack extended attributes"); - ret = ARCHIVE_WARN; - goto cleanup; - } - if (fstat(tempfd, ©file_stat)) { - archive_set_error(&a->archive, errno, - "Could not check size of extended attributes"); - ret = ARCHIVE_WARN; - goto cleanup; - } - buff = malloc(copyfile_stat.st_size); - if (buff == NULL) { - archive_set_error(&a->archive, errno, - "Could not allocate memory for extended attributes"); - ret = ARCHIVE_WARN; - goto cleanup; - } - if (copyfile_stat.st_size != read(tempfd, buff, copyfile_stat.st_size)) { - archive_set_error(&a->archive, errno, - "Could not read extended attributes into memory"); - ret = ARCHIVE_WARN; - goto cleanup; - } - archive_entry_copy_mac_metadata(entry, buff, copyfile_stat.st_size); - -cleanup: - if (tempfd >= 0) { - close(tempfd); - unlink(tempfile.s); - } - archive_string_free(&tempfile); - free(buff); - return (ret); -} - -#else - -/* - * Stub implementation for non-Mac systems. - */ -static int -setup_mac_metadata(struct archive_read_disk *a, - struct archive_entry *entry, int *fd) -{ - (void)a; /* UNUSED */ - (void)entry; /* UNUSED */ - (void)fd; /* UNUSED */ - return (ARCHIVE_OK); -} -#endif - -#if ARCHIVE_XATTR_LINUX || ARCHIVE_XATTR_DARWIN || ARCHIVE_XATTR_AIX - -/* - * Linux, Darwin and AIX extended attribute support. - * - * TODO: By using a stack-allocated buffer for the first - * call to getxattr(), we might be able to avoid the second - * call entirely. We only need the second call if the - * stack-allocated buffer is too small. But a modest buffer - * of 1024 bytes or so will often be big enough. Same applies - * to listxattr(). - */ - - -static int -setup_xattr(struct archive_read_disk *a, - struct archive_entry *entry, const char *name, int fd, const char *accpath) -{ - ssize_t size; - void *value = NULL; - - - if (fd >= 0) { -#if ARCHIVE_XATTR_LINUX - size = fgetxattr(fd, name, NULL, 0); -#elif ARCHIVE_XATTR_DARWIN - size = fgetxattr(fd, name, NULL, 0, 0, 0); -#elif ARCHIVE_XATTR_AIX - size = fgetea(fd, name, NULL, 0); -#endif - } else if (!a->follow_symlinks) { -#if ARCHIVE_XATTR_LINUX - size = lgetxattr(accpath, name, NULL, 0); -#elif ARCHIVE_XATTR_DARWIN - size = getxattr(accpath, name, NULL, 0, 0, XATTR_NOFOLLOW); -#elif ARCHIVE_XATTR_AIX - size = lgetea(accpath, name, NULL, 0); -#endif - } else { -#if ARCHIVE_XATTR_LINUX - size = getxattr(accpath, name, NULL, 0); -#elif ARCHIVE_XATTR_DARWIN - size = getxattr(accpath, name, NULL, 0, 0, 0); -#elif ARCHIVE_XATTR_AIX - size = getea(accpath, name, NULL, 0); -#endif - } - - if (size == -1) { - archive_set_error(&a->archive, errno, - "Couldn't query extended attribute"); - return (ARCHIVE_WARN); - } - - if (size > 0 && (value = malloc(size)) == NULL) { - archive_set_error(&a->archive, errno, "Out of memory"); - return (ARCHIVE_FATAL); - } - - - if (fd >= 0) { -#if ARCHIVE_XATTR_LINUX - size = fgetxattr(fd, name, value, size); -#elif ARCHIVE_XATTR_DARWIN - size = fgetxattr(fd, name, value, size, 0, 0); -#elif ARCHIVE_XATTR_AIX - size = fgetea(fd, name, value, size); -#endif - } else if (!a->follow_symlinks) { -#if ARCHIVE_XATTR_LINUX - size = lgetxattr(accpath, name, value, size); -#elif ARCHIVE_XATTR_DARWIN - size = getxattr(accpath, name, value, size, 0, XATTR_NOFOLLOW); -#elif ARCHIVE_XATTR_AIX - size = lgetea(accpath, name, value, size); -#endif - } else { -#if ARCHIVE_XATTR_LINUX - size = getxattr(accpath, name, value, size); -#elif ARCHIVE_XATTR_DARWIN - size = getxattr(accpath, name, value, size, 0, 0); -#elif ARCHIVE_XATTR_AIX - size = getea(accpath, name, value, size); -#endif - } - - if (size == -1) { - archive_set_error(&a->archive, errno, - "Couldn't read extended attribute"); - return (ARCHIVE_WARN); - } - - archive_entry_xattr_add_entry(entry, name, value, size); - - free(value); - return (ARCHIVE_OK); -} - -static int -setup_xattrs(struct archive_read_disk *a, - struct archive_entry *entry, int *fd) -{ - char *list, *p; - const char *path; - ssize_t list_size; - - path = NULL; - - if (*fd < 0) { - path = archive_read_disk_entry_setup_path(a, entry, fd); - if (path == NULL) - return (ARCHIVE_WARN); - } - - if (*fd >= 0) { -#if ARCHIVE_XATTR_LINUX - list_size = flistxattr(*fd, NULL, 0); -#elif ARCHIVE_XATTR_DARWIN - list_size = flistxattr(*fd, NULL, 0, 0); -#elif ARCHIVE_XATTR_AIX - list_size = flistea(*fd, NULL, 0); -#endif - } else if (!a->follow_symlinks) { -#if ARCHIVE_XATTR_LINUX - list_size = llistxattr(path, NULL, 0); -#elif ARCHIVE_XATTR_DARWIN - list_size = listxattr(path, NULL, 0, XATTR_NOFOLLOW); -#elif ARCHIVE_XATTR_AIX - list_size = llistea(path, NULL, 0); -#endif - } else { -#if ARCHIVE_XATTR_LINUX - list_size = listxattr(path, NULL, 0); -#elif ARCHIVE_XATTR_DARWIN - list_size = listxattr(path, NULL, 0, 0); -#elif ARCHIVE_XATTR_AIX - list_size = listea(path, NULL, 0); -#endif - } - - if (list_size == -1) { - if (errno == ENOTSUP || errno == ENOSYS) - return (ARCHIVE_OK); - archive_set_error(&a->archive, errno, - "Couldn't list extended attributes"); - return (ARCHIVE_WARN); - } - - if (list_size == 0) - return (ARCHIVE_OK); - - if ((list = malloc(list_size)) == NULL) { - archive_set_error(&a->archive, errno, "Out of memory"); - return (ARCHIVE_FATAL); - } - - if (*fd >= 0) { -#if ARCHIVE_XATTR_LINUX - list_size = flistxattr(*fd, list, list_size); -#elif ARCHIVE_XATTR_DARWIN - list_size = flistxattr(*fd, list, list_size, 0); -#elif ARCHIVE_XATTR_AIX - list_size = flistea(*fd, list, list_size); -#endif - } else if (!a->follow_symlinks) { -#if ARCHIVE_XATTR_LINUX - list_size = llistxattr(path, list, list_size); -#elif ARCHIVE_XATTR_DARWIN - list_size = listxattr(path, list, list_size, XATTR_NOFOLLOW); -#elif ARCHIVE_XATTR_AIX - list_size = llistea(path, list, list_size); -#endif - } else { -#if ARCHIVE_XATTR_LINUX - list_size = listxattr(path, list, list_size); -#elif ARCHIVE_XATTR_DARWIN - list_size = listxattr(path, list, list_size, 0); -#elif ARCHIVE_XATTR_AIX - list_size = listea(path, list, list_size); -#endif - } - - if (list_size == -1) { - archive_set_error(&a->archive, errno, - "Couldn't retrieve extended attributes"); - free(list); - return (ARCHIVE_WARN); - } - - for (p = list; (p - list) < list_size; p += strlen(p) + 1) { -#if ARCHIVE_XATTR_LINUX - /* Linux: skip POSIX.1e ACL extended attributes */ - if (strncmp(p, "system.", 7) == 0 && - (strcmp(p + 7, "posix_acl_access") == 0 || - strcmp(p + 7, "posix_acl_default") == 0)) - continue; - if (strncmp(p, "trusted.SGI_", 12) == 0 && - (strcmp(p + 12, "ACL_DEFAULT") == 0 || - strcmp(p + 12, "ACL_FILE") == 0)) - continue; - - /* Linux: xfsroot namespace is obsolete and unsupported */ - if (strncmp(p, "xfsroot.", 8) == 0) - continue; -#endif - setup_xattr(a, entry, p, *fd, path); - } - - free(list); - return (ARCHIVE_OK); -} - -#elif ARCHIVE_XATTR_FREEBSD - -/* - * FreeBSD extattr interface. - */ - -/* TODO: Implement this. Follow the Linux model above, but - * with FreeBSD-specific system calls, of course. Be careful - * to not include the system extattrs that hold ACLs; we handle - * those separately. - */ -static int -setup_xattr(struct archive_read_disk *a, struct archive_entry *entry, - int namespace, const char *name, const char *fullname, int fd, - const char *path); - -static int -setup_xattr(struct archive_read_disk *a, struct archive_entry *entry, - int namespace, const char *name, const char *fullname, int fd, - const char *accpath) -{ - ssize_t size; - void *value = NULL; - - if (fd >= 0) - size = extattr_get_fd(fd, namespace, name, NULL, 0); - else if (!a->follow_symlinks) - size = extattr_get_link(accpath, namespace, name, NULL, 0); - else - size = extattr_get_file(accpath, namespace, name, NULL, 0); - - if (size == -1) { - archive_set_error(&a->archive, errno, - "Couldn't query extended attribute"); - return (ARCHIVE_WARN); - } - - if (size > 0 && (value = malloc(size)) == NULL) { - archive_set_error(&a->archive, errno, "Out of memory"); - return (ARCHIVE_FATAL); - } - - if (fd >= 0) - size = extattr_get_fd(fd, namespace, name, value, size); - else if (!a->follow_symlinks) - size = extattr_get_link(accpath, namespace, name, value, size); - else - size = extattr_get_file(accpath, namespace, name, value, size); - - if (size == -1) { - free(value); - archive_set_error(&a->archive, errno, - "Couldn't read extended attribute"); - return (ARCHIVE_WARN); - } - - archive_entry_xattr_add_entry(entry, fullname, value, size); - - free(value); - return (ARCHIVE_OK); -} - -static int -setup_xattrs_namespace(struct archive_read_disk *a, - struct archive_entry *entry, int *fd, int namespace) -{ - char buff[512]; - char *list, *p; - ssize_t list_size; - const char *path; - - path = NULL; - - if (*fd < 0) { - path = archive_read_disk_entry_setup_path(a, entry, fd); - if (path == NULL) - return (ARCHIVE_WARN); - } - - if (*fd >= 0) - list_size = extattr_list_fd(*fd, namespace, NULL, 0); - else if (!a->follow_symlinks) - list_size = extattr_list_link(path, namespace, NULL, 0); - else - list_size = extattr_list_file(path, namespace, NULL, 0); - - if (list_size == -1 && errno == EOPNOTSUPP) - return (ARCHIVE_OK); - if (list_size == -1 && errno == EPERM) - return (ARCHIVE_OK); - if (list_size == -1) { - archive_set_error(&a->archive, errno, - "Couldn't list extended attributes"); - return (ARCHIVE_WARN); - } - - if (list_size == 0) - return (ARCHIVE_OK); - - if ((list = malloc(list_size)) == NULL) { - archive_set_error(&a->archive, errno, "Out of memory"); - return (ARCHIVE_FATAL); - } - - if (*fd >= 0) - list_size = extattr_list_fd(*fd, namespace, list, list_size); - else if (!a->follow_symlinks) - list_size = extattr_list_link(path, namespace, list, list_size); - else - list_size = extattr_list_file(path, namespace, list, list_size); - - if (list_size == -1) { - archive_set_error(&a->archive, errno, - "Couldn't retrieve extended attributes"); - free(list); - return (ARCHIVE_WARN); - } - - p = list; - while ((p - list) < list_size) { - size_t len = 255 & (int)*p; - char *name; - - if (namespace == EXTATTR_NAMESPACE_SYSTEM) { - if (!strcmp(p + 1, "nfs4.acl") || - !strcmp(p + 1, "posix1e.acl_access") || - !strcmp(p + 1, "posix1e.acl_default")) { - p += 1 + len; - continue; - } - strcpy(buff, "system."); - } else { - strcpy(buff, "user."); - } - name = buff + strlen(buff); - memcpy(name, p + 1, len); - name[len] = '\0'; - setup_xattr(a, entry, namespace, name, buff, *fd, path); - p += 1 + len; - } - - free(list); - return (ARCHIVE_OK); -} - -static int -setup_xattrs(struct archive_read_disk *a, - struct archive_entry *entry, int *fd) -{ - int namespaces[2]; - int i, res; - - namespaces[0] = EXTATTR_NAMESPACE_USER; - namespaces[1] = EXTATTR_NAMESPACE_SYSTEM; - - for (i = 0; i < 2; i++) { - res = setup_xattrs_namespace(a, entry, fd, - namespaces[i]); - switch (res) { - case (ARCHIVE_OK): - case (ARCHIVE_WARN): - break; - default: - return (res); - } - } - - return (ARCHIVE_OK); -} - -#else - -/* - * Generic (stub) extended attribute support. - */ -static int -setup_xattrs(struct archive_read_disk *a, - struct archive_entry *entry, int *fd) -{ - (void)a; /* UNUSED */ - (void)entry; /* UNUSED */ - (void)fd; /* UNUSED */ - return (ARCHIVE_OK); -} - -#endif - -#if defined(HAVE_LINUX_FIEMAP_H) - -/* - * Linux FIEMAP sparse interface. - * - * The FIEMAP ioctl returns an "extent" for each physical allocation - * on disk. We need to process those to generate a more compact list - * of logical file blocks. We also need to be very careful to use - * FIEMAP_FLAG_SYNC here, since there are reports that Linux sometimes - * does not report allocations for newly-written data that hasn't - * been synced to disk. - * - * It's important to return a minimal sparse file list because we want - * to not trigger sparse file extensions if we don't have to, since - * not all readers support them. - */ - -static int -setup_sparse_fiemap(struct archive_read_disk *a, - struct archive_entry *entry, int *fd) -{ - char buff[4096]; - struct fiemap *fm; - struct fiemap_extent *fe; - int64_t size; - int count, do_fiemap, iters; - int exit_sts = ARCHIVE_OK; - const char *path; - - if (archive_entry_filetype(entry) != AE_IFREG - || archive_entry_size(entry) <= 0 - || archive_entry_hardlink(entry) != NULL) - return (ARCHIVE_OK); - - if (*fd < 0) { - path = archive_read_disk_entry_setup_path(a, entry, NULL); - if (path == NULL) - return (ARCHIVE_FAILED); - - if (a->tree != NULL) - *fd = a->open_on_current_dir(a->tree, path, - O_RDONLY | O_NONBLOCK | O_CLOEXEC); - else - *fd = open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC); - if (*fd < 0) { - archive_set_error(&a->archive, errno, - "Can't open `%s'", path); - return (ARCHIVE_FAILED); - } - __archive_ensure_cloexec_flag(*fd); - } - - /* Initialize buffer to avoid the error valgrind complains about. */ - memset(buff, 0, sizeof(buff)); - count = (sizeof(buff) - sizeof(*fm))/sizeof(*fe); - fm = (struct fiemap *)buff; - fm->fm_start = 0; - fm->fm_length = ~0ULL;; - fm->fm_flags = FIEMAP_FLAG_SYNC; - fm->fm_extent_count = count; - do_fiemap = 1; - size = archive_entry_size(entry); - for (iters = 0; ; ++iters) { - int i, r; - - r = ioctl(*fd, FS_IOC_FIEMAP, fm); - if (r < 0) { - /* When something error happens, it is better we - * should return ARCHIVE_OK because an earlier - * version(<2.6.28) cannot perform FS_IOC_FIEMAP. */ - goto exit_setup_sparse_fiemap; - } - if (fm->fm_mapped_extents == 0) { - if (iters == 0) { - /* Fully sparse file; insert a zero-length "data" entry */ - archive_entry_sparse_add_entry(entry, 0, 0); - } - break; - } - fe = fm->fm_extents; - for (i = 0; i < (int)fm->fm_mapped_extents; i++, fe++) { - if (!(fe->fe_flags & FIEMAP_EXTENT_UNWRITTEN)) { - /* The fe_length of the last block does not - * adjust itself to its size files. */ - int64_t length = fe->fe_length; - if (fe->fe_logical + length > (uint64_t)size) - length -= fe->fe_logical + length - size; - if (fe->fe_logical == 0 && length == size) { - /* This is not sparse. */ - do_fiemap = 0; - break; - } - if (length > 0) - archive_entry_sparse_add_entry(entry, - fe->fe_logical, length); - } - if (fe->fe_flags & FIEMAP_EXTENT_LAST) - do_fiemap = 0; - } - if (do_fiemap) { - fe = fm->fm_extents + fm->fm_mapped_extents -1; - fm->fm_start = fe->fe_logical + fe->fe_length; - } else - break; - } -exit_setup_sparse_fiemap: - return (exit_sts); -} - -#if !defined(SEEK_HOLE) || !defined(SEEK_DATA) -static int -setup_sparse(struct archive_read_disk *a, - struct archive_entry *entry, int *fd) -{ - return setup_sparse_fiemap(a, entry, fd); -} -#endif -#endif /* defined(HAVE_LINUX_FIEMAP_H) */ - -#if defined(SEEK_HOLE) && defined(SEEK_DATA) - -/* - * SEEK_HOLE sparse interface (FreeBSD, Linux, Solaris) - */ - -static int -setup_sparse(struct archive_read_disk *a, - struct archive_entry *entry, int *fd) -{ - int64_t size; - off_t initial_off; - off_t off_s, off_e; - int exit_sts = ARCHIVE_OK; - int check_fully_sparse = 0; - const char *path; - - if (archive_entry_filetype(entry) != AE_IFREG - || archive_entry_size(entry) <= 0 - || archive_entry_hardlink(entry) != NULL) - return (ARCHIVE_OK); - - /* Does filesystem support the reporting of hole ? */ - if (*fd < 0) - path = archive_read_disk_entry_setup_path(a, entry, fd); - else - path = NULL; - - if (*fd >= 0) { -#ifdef _PC_MIN_HOLE_SIZE - if (fpathconf(*fd, _PC_MIN_HOLE_SIZE) <= 0) - return (ARCHIVE_OK); -#endif - initial_off = lseek(*fd, 0, SEEK_CUR); - if (initial_off != 0) - lseek(*fd, 0, SEEK_SET); - } else { - if (path == NULL) - return (ARCHIVE_FAILED); -#ifdef _PC_MIN_HOLE_SIZE - if (pathconf(path, _PC_MIN_HOLE_SIZE) <= 0) - return (ARCHIVE_OK); -#endif - *fd = open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC); - if (*fd < 0) { - archive_set_error(&a->archive, errno, - "Can't open `%s'", path); - return (ARCHIVE_FAILED); - } - __archive_ensure_cloexec_flag(*fd); - initial_off = 0; - } - -#ifndef _PC_MIN_HOLE_SIZE - /* Check if the underlying filesystem supports seek hole */ - off_s = lseek(*fd, 0, SEEK_HOLE); - if (off_s < 0) -#if defined(HAVE_LINUX_FIEMAP_H) - return setup_sparse_fiemap(a, entry, fd); -#else - goto exit_setup_sparse; -#endif - else if (off_s > 0) - lseek(*fd, 0, SEEK_SET); -#endif - - off_s = 0; - size = archive_entry_size(entry); - while (off_s < size) { - off_s = lseek(*fd, off_s, SEEK_DATA); - if (off_s == (off_t)-1) { - if (errno == ENXIO) { - /* no more hole */ - if (archive_entry_sparse_count(entry) == 0) { - /* Potentially a fully-sparse file. */ - check_fully_sparse = 1; - } - break; - } - archive_set_error(&a->archive, errno, - "lseek(SEEK_HOLE) failed"); - exit_sts = ARCHIVE_FAILED; - goto exit_setup_sparse; - } - off_e = lseek(*fd, off_s, SEEK_HOLE); - if (off_e == (off_t)-1) { - if (errno == ENXIO) { - off_e = lseek(*fd, 0, SEEK_END); - if (off_e != (off_t)-1) - break;/* no more data */ - } - archive_set_error(&a->archive, errno, - "lseek(SEEK_DATA) failed"); - exit_sts = ARCHIVE_FAILED; - goto exit_setup_sparse; - } - if (off_s == 0 && off_e == size) - break;/* This is not sparse. */ - archive_entry_sparse_add_entry(entry, off_s, - off_e - off_s); - off_s = off_e; - } - - if (check_fully_sparse) { - if (lseek(*fd, 0, SEEK_HOLE) == 0 && - lseek(*fd, 0, SEEK_END) == size) { - /* Fully sparse file; insert a zero-length "data" entry */ - archive_entry_sparse_add_entry(entry, 0, 0); - } - } -exit_setup_sparse: - lseek(*fd, initial_off, SEEK_SET); - return (exit_sts); -} - -#elif !defined(HAVE_LINUX_FIEMAP_H) - -/* - * Generic (stub) sparse support. - */ -static int -setup_sparse(struct archive_read_disk *a, - struct archive_entry *entry, int *fd) -{ - (void)a; /* UNUSED */ - (void)entry; /* UNUSED */ - (void)fd; /* UNUSED */ - return (ARCHIVE_OK); -} - -#endif - -#endif /* !defined(_WIN32) || defined(__CYGWIN__) */ - diff --git a/thirdparty/libarchive/libarchive/archive_read_disk_posix.c b/thirdparty/libarchive/libarchive/archive_read_disk_posix.c deleted file mode 100644 index 8d5c32f03..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_disk_posix.c +++ /dev/null @@ -1,2760 +0,0 @@ -/*- - * Copyright (c) 2003-2009 Tim Kientzle - * Copyright (c) 2010-2012 Michihiro NAKAJIMA - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -/* This is the tree-walking code for POSIX systems. */ -#if !defined(_WIN32) || defined(__CYGWIN__) - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_SYS_PARAM_H -#include -#endif -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_SYS_STATFS_H -#include -#endif -#ifdef HAVE_SYS_STATVFS_H -#include -#endif -#ifdef HAVE_SYS_TIME_H -#include -#endif -#ifdef HAVE_LINUX_MAGIC_H -#include -#endif -#ifdef HAVE_LINUX_FS_H -#include -#elif HAVE_SYS_MOUNT_H -#include -#endif -/* - * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h. - * As the include guards don't agree, the order of include is important. - */ -#ifdef HAVE_LINUX_EXT2_FS_H -#include /* for Linux file flags */ -#endif -#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__) -#include /* Linux file flags, broken on Cygwin */ -#endif -#ifdef HAVE_DIRECT_H -#include -#endif -#ifdef HAVE_DIRENT_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif -#ifdef HAVE_LIMITS_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_SYS_IOCTL_H -#include -#endif - -#include "archive.h" -#include "archive_string.h" -#include "archive_entry.h" -#include "archive_private.h" -#include "archive_read_disk_private.h" - -#ifndef HAVE_FCHDIR -#error fchdir function required. -#endif -#ifndef O_BINARY -#define O_BINARY 0 -#endif -#ifndef O_CLOEXEC -#define O_CLOEXEC 0 -#endif - -#if defined(__hpux) && !defined(HAVE_DIRFD) -#define dirfd(x) ((x)->__dd_fd) -#define HAVE_DIRFD -#endif - -/*- - * This is a new directory-walking system that addresses a number - * of problems I've had with fts(3). In particular, it has no - * pathname-length limits (other than the size of 'int'), handles - * deep logical traversals, uses considerably less memory, and has - * an opaque interface (easier to modify in the future). - * - * Internally, it keeps a single list of "tree_entry" items that - * represent filesystem objects that require further attention. - * Non-directories are not kept in memory: they are pulled from - * readdir(), returned to the client, then freed as soon as possible. - * Any directory entry to be traversed gets pushed onto the stack. - * - * There is surprisingly little information that needs to be kept for - * each item on the stack. Just the name, depth (represented here as the - * string length of the parent directory's pathname), and some markers - * indicating how to get back to the parent (via chdir("..") for a - * regular dir or via fchdir(2) for a symlink). - */ -/* - * TODO: - * 1) Loop checking. - * 3) Arbitrary logical traversals by closing/reopening intermediate fds. - */ - -struct restore_time { - const char *name; - time_t mtime; - long mtime_nsec; - time_t atime; - long atime_nsec; - mode_t filetype; - int noatime; -}; - -struct tree_entry { - int depth; - struct tree_entry *next; - struct tree_entry *parent; - struct archive_string name; - size_t dirname_length; - int64_t dev; - int64_t ino; - int flags; - int filesystem_id; - /* How to return back to the parent of a symlink. */ - int symlink_parent_fd; - /* How to restore time of a directory. */ - struct restore_time restore_time; -}; - -struct filesystem { - int64_t dev; - int synthetic; - int remote; - int noatime; -#if defined(USE_READDIR_R) - size_t name_max; -#endif - long incr_xfer_size; - long max_xfer_size; - long min_xfer_size; - long xfer_align; - - /* - * Buffer used for reading file contents. - */ - /* Exactly allocated memory pointer. */ - unsigned char *allocation_ptr; - /* Pointer adjusted to the filesystem alignment . */ - unsigned char *buff; - size_t buff_size; -}; - -/* Definitions for tree_entry.flags bitmap. */ -#define isDir 1 /* This entry is a regular directory. */ -#define isDirLink 2 /* This entry is a symbolic link to a directory. */ -#define needsFirstVisit 4 /* This is an initial entry. */ -#define needsDescent 8 /* This entry needs to be previsited. */ -#define needsOpen 16 /* This is a directory that needs to be opened. */ -#define needsAscent 32 /* This entry needs to be postvisited. */ - -/* - * Local data for this package. - */ -struct tree { - struct tree_entry *stack; - struct tree_entry *current; - DIR *d; -#define INVALID_DIR_HANDLE NULL - struct dirent *de; -#if defined(USE_READDIR_R) - struct dirent *dirent; - size_t dirent_allocated; -#endif - int flags; - int visit_type; - /* Error code from last failed operation. */ - int tree_errno; - - /* Dynamically-sized buffer for holding path */ - struct archive_string path; - - /* Last path element */ - const char *basename; - /* Leading dir length */ - size_t dirname_length; - - int depth; - int openCount; - int maxOpenCount; - int initial_dir_fd; - int working_dir_fd; - - struct stat lst; - struct stat st; - int descend; - int nlink; - /* How to restore time of a file. */ - struct restore_time restore_time; - - struct entry_sparse { - int64_t length; - int64_t offset; - } *sparse_list, *current_sparse; - int sparse_count; - int sparse_list_size; - - char initial_symlink_mode; - char symlink_mode; - struct filesystem *current_filesystem; - struct filesystem *filesystem_table; - int initial_filesystem_id; - int current_filesystem_id; - int max_filesystem_id; - int allocated_filesystem; - - int entry_fd; - int entry_eof; - int64_t entry_remaining_bytes; - int64_t entry_total; - unsigned char *entry_buff; - size_t entry_buff_size; -}; - -/* Definitions for tree.flags bitmap. */ -#define hasStat 16 /* The st entry is valid. */ -#define hasLstat 32 /* The lst entry is valid. */ -#define onWorkingDir 64 /* We are on the working dir where we are - * reading directory entry at this time. */ -#define needsRestoreTimes 128 -#define onInitialDir 256 /* We are on the initial dir. */ - -static int -tree_dir_next_posix(struct tree *t); - -#ifdef HAVE_DIRENT_D_NAMLEN -/* BSD extension; avoids need for a strlen() call. */ -#define D_NAMELEN(dp) (dp)->d_namlen -#else -#define D_NAMELEN(dp) (strlen((dp)->d_name)) -#endif - -/* Initiate/terminate a tree traversal. */ -static struct tree *tree_open(const char *, int, int); -static struct tree *tree_reopen(struct tree *, const char *, int); -static void tree_close(struct tree *); -static void tree_free(struct tree *); -static void tree_push(struct tree *, const char *, int, int64_t, int64_t, - struct restore_time *); -static int tree_enter_initial_dir(struct tree *); -static int tree_enter_working_dir(struct tree *); -static int tree_current_dir_fd(struct tree *); - -/* - * tree_next() returns Zero if there is no next entry, non-zero if - * there is. Note that directories are visited three times. - * Directories are always visited first as part of enumerating their - * parent; that is a "regular" visit. If tree_descend() is invoked at - * that time, the directory is added to a work list and will - * subsequently be visited two more times: once just after descending - * into the directory ("postdescent") and again just after ascending - * back to the parent ("postascent"). - * - * TREE_ERROR_DIR is returned if the descent failed (because the - * directory couldn't be opened, for instance). This is returned - * instead of TREE_POSTDESCENT/TREE_POSTASCENT. TREE_ERROR_DIR is not a - * fatal error, but it does imply that the relevant subtree won't be - * visited. TREE_ERROR_FATAL is returned for an error that left the - * traversal completely hosed. Right now, this is only returned for - * chdir() failures during ascent. - */ -#define TREE_REGULAR 1 -#define TREE_POSTDESCENT 2 -#define TREE_POSTASCENT 3 -#define TREE_ERROR_DIR -1 -#define TREE_ERROR_FATAL -2 - -static int tree_next(struct tree *); - -/* - * Return information about the current entry. - */ - -/* - * The current full pathname, length of the full pathname, and a name - * that can be used to access the file. Because tree does use chdir - * extensively, the access path is almost never the same as the full - * current path. - * - * TODO: On platforms that support it, use openat()-style operations - * to eliminate the chdir() operations entirely while still supporting - * arbitrarily deep traversals. This makes access_path troublesome to - * support, of course, which means we'll need a rich enough interface - * that clients can function without it. (In particular, we'll need - * tree_current_open() that returns an open file descriptor.) - * - */ -static const char *tree_current_path(struct tree *); -static const char *tree_current_access_path(struct tree *); - -/* - * Request the lstat() or stat() data for the current path. Since the - * tree package needs to do some of this anyway, and caches the - * results, you should take advantage of it here if you need it rather - * than make a redundant stat() or lstat() call of your own. - */ -static const struct stat *tree_current_stat(struct tree *); -static const struct stat *tree_current_lstat(struct tree *); -static int tree_current_is_symblic_link_target(struct tree *); - -/* The following functions use tricks to avoid a certain number of - * stat()/lstat() calls. */ -/* "is_physical_dir" is equivalent to S_ISDIR(tree_current_lstat()->st_mode) */ -static int tree_current_is_physical_dir(struct tree *); -/* "is_dir" is equivalent to S_ISDIR(tree_current_stat()->st_mode) */ -static int tree_current_is_dir(struct tree *); -static int update_current_filesystem(struct archive_read_disk *a, - int64_t dev); -static int setup_current_filesystem(struct archive_read_disk *); -static int tree_target_is_same_as_parent(struct tree *, const struct stat *); - -static int _archive_read_disk_open(struct archive *, const char *); -static int _archive_read_free(struct archive *); -static int _archive_read_close(struct archive *); -static int _archive_read_data_block(struct archive *, - const void **, size_t *, int64_t *); -static int _archive_read_next_header(struct archive *, - struct archive_entry **); -static int _archive_read_next_header2(struct archive *, - struct archive_entry *); -static const char *trivial_lookup_gname(void *, int64_t gid); -static const char *trivial_lookup_uname(void *, int64_t uid); -static int setup_sparse(struct archive_read_disk *, struct archive_entry *); -static int close_and_restore_time(int fd, struct tree *, - struct restore_time *); -static int open_on_current_dir(struct tree *, const char *, int); -static int tree_dup(int); - - -static const struct archive_vtable -archive_read_disk_vtable = { - .archive_free = _archive_read_free, - .archive_close = _archive_read_close, - .archive_read_data_block = _archive_read_data_block, - .archive_read_next_header = _archive_read_next_header, - .archive_read_next_header2 = _archive_read_next_header2, -}; - -const char * -archive_read_disk_gname(struct archive *_a, la_int64_t gid) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_read_disk_gname")) - return (NULL); - if (a->lookup_gname == NULL) - return (NULL); - return ((*a->lookup_gname)(a->lookup_gname_data, gid)); -} - -const char * -archive_read_disk_uname(struct archive *_a, la_int64_t uid) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_read_disk_uname")) - return (NULL); - if (a->lookup_uname == NULL) - return (NULL); - return ((*a->lookup_uname)(a->lookup_uname_data, uid)); -} - -int -archive_read_disk_set_gname_lookup(struct archive *_a, - void *private_data, - const char * (*lookup_gname)(void *private, la_int64_t gid), - void (*cleanup_gname)(void *private)) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_read_disk_set_gname_lookup"); - - if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL) - (a->cleanup_gname)(a->lookup_gname_data); - - a->lookup_gname = lookup_gname; - a->cleanup_gname = cleanup_gname; - a->lookup_gname_data = private_data; - return (ARCHIVE_OK); -} - -int -archive_read_disk_set_uname_lookup(struct archive *_a, - void *private_data, - const char * (*lookup_uname)(void *private, la_int64_t uid), - void (*cleanup_uname)(void *private)) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_read_disk_set_uname_lookup"); - - if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL) - (a->cleanup_uname)(a->lookup_uname_data); - - a->lookup_uname = lookup_uname; - a->cleanup_uname = cleanup_uname; - a->lookup_uname_data = private_data; - return (ARCHIVE_OK); -} - -/* - * Create a new archive_read_disk object and initialize it with global state. - */ -struct archive * -archive_read_disk_new(void) -{ - struct archive_read_disk *a; - - a = (struct archive_read_disk *)calloc(1, sizeof(*a)); - if (a == NULL) - return (NULL); - a->archive.magic = ARCHIVE_READ_DISK_MAGIC; - a->archive.state = ARCHIVE_STATE_NEW; - a->archive.vtable = &archive_read_disk_vtable; - a->entry = archive_entry_new2(&a->archive); - a->lookup_uname = trivial_lookup_uname; - a->lookup_gname = trivial_lookup_gname; - a->flags = ARCHIVE_READDISK_MAC_COPYFILE; - a->open_on_current_dir = open_on_current_dir; - a->tree_current_dir_fd = tree_current_dir_fd; - a->tree_enter_working_dir = tree_enter_working_dir; - return (&a->archive); -} - -static int -_archive_read_free(struct archive *_a) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - int r; - - if (_a == NULL) - return (ARCHIVE_OK); - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_free"); - - if (a->archive.state != ARCHIVE_STATE_CLOSED) - r = _archive_read_close(&a->archive); - else - r = ARCHIVE_OK; - - tree_free(a->tree); - if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL) - (a->cleanup_gname)(a->lookup_gname_data); - if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL) - (a->cleanup_uname)(a->lookup_uname_data); - archive_string_free(&a->archive.error_string); - archive_entry_free(a->entry); - a->archive.magic = 0; - __archive_clean(&a->archive); - free(a); - return (r); -} - -static int -_archive_read_close(struct archive *_a) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_close"); - - if (a->archive.state != ARCHIVE_STATE_FATAL) - a->archive.state = ARCHIVE_STATE_CLOSED; - - tree_close(a->tree); - - return (ARCHIVE_OK); -} - -static void -setup_symlink_mode(struct archive_read_disk *a, char symlink_mode, - int follow_symlinks) -{ - a->symlink_mode = symlink_mode; - a->follow_symlinks = follow_symlinks; - if (a->tree != NULL) { - a->tree->initial_symlink_mode = a->symlink_mode; - a->tree->symlink_mode = a->symlink_mode; - } -} - -int -archive_read_disk_set_symlink_logical(struct archive *_a) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_logical"); - setup_symlink_mode(a, 'L', 1); - return (ARCHIVE_OK); -} - -int -archive_read_disk_set_symlink_physical(struct archive *_a) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_physical"); - setup_symlink_mode(a, 'P', 0); - return (ARCHIVE_OK); -} - -int -archive_read_disk_set_symlink_hybrid(struct archive *_a) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_hybrid"); - setup_symlink_mode(a, 'H', 1);/* Follow symlinks initially. */ - return (ARCHIVE_OK); -} - -int -archive_read_disk_set_atime_restored(struct archive *_a) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_read_disk_restore_atime"); -#ifdef HAVE_UTIMES - a->flags |= ARCHIVE_READDISK_RESTORE_ATIME; - if (a->tree != NULL) - a->tree->flags |= needsRestoreTimes; - return (ARCHIVE_OK); -#else - /* Display warning and unset flag */ - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Cannot restore access time on this system"); - a->flags &= ~ARCHIVE_READDISK_RESTORE_ATIME; - return (ARCHIVE_WARN); -#endif -} - -int -archive_read_disk_set_behavior(struct archive *_a, int flags) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - int r = ARCHIVE_OK; - - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_read_disk_honor_nodump"); - - a->flags = flags; - - if (flags & ARCHIVE_READDISK_RESTORE_ATIME) - r = archive_read_disk_set_atime_restored(_a); - else { - if (a->tree != NULL) - a->tree->flags &= ~needsRestoreTimes; - } - return (r); -} - -/* - * Trivial implementations of gname/uname lookup functions. - * These are normally overridden by the client, but these stub - * versions ensure that we always have something that works. - */ -static const char * -trivial_lookup_gname(void *private_data, int64_t gid) -{ - (void)private_data; /* UNUSED */ - (void)gid; /* UNUSED */ - return (NULL); -} - -static const char * -trivial_lookup_uname(void *private_data, int64_t uid) -{ - (void)private_data; /* UNUSED */ - (void)uid; /* UNUSED */ - return (NULL); -} - -/* - * Allocate memory for the reading buffer adjusted to the filesystem - * alignment. - */ -static int -setup_suitable_read_buffer(struct archive_read_disk *a) -{ - struct tree *t = a->tree; - struct filesystem *cf = t->current_filesystem; - size_t asize; - size_t s; - - if (cf->allocation_ptr == NULL) { - /* If we couldn't get a filesystem alignment, - * we use 4096 as default value but we won't use - * O_DIRECT to open() and openat() operations. */ - long xfer_align = (cf->xfer_align == -1)?4096:cf->xfer_align; - - if (cf->max_xfer_size != -1) - asize = cf->max_xfer_size + xfer_align; - else { - long incr = cf->incr_xfer_size; - /* Some platform does not set a proper value to - * incr_xfer_size.*/ - if (incr < 0) - incr = cf->min_xfer_size; - if (cf->min_xfer_size < 0) { - incr = xfer_align; - asize = xfer_align; - } else - asize = cf->min_xfer_size; - - /* Increase a buffer size up to 64K bytes in - * a proper increment size. */ - while (asize < 1024*64) - asize += incr; - /* Take a margin to adjust to the filesystem - * alignment. */ - asize += xfer_align; - } - cf->allocation_ptr = malloc(asize); - if (cf->allocation_ptr == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Couldn't allocate memory"); - a->archive.state = ARCHIVE_STATE_FATAL; - return (ARCHIVE_FATAL); - } - - /* - * Calculate proper address for the filesystem. - */ - s = (uintptr_t)cf->allocation_ptr; - s %= xfer_align; - if (s > 0) - s = xfer_align - s; - - /* - * Set a read buffer pointer in the proper alignment of - * the current filesystem. - */ - cf->buff = cf->allocation_ptr + s; - cf->buff_size = asize - xfer_align; - } - return (ARCHIVE_OK); -} - -static int -_archive_read_data_block(struct archive *_a, const void **buff, - size_t *size, int64_t *offset) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - struct tree *t = a->tree; - int r; - ssize_t bytes; - int64_t sparse_bytes; - size_t buffbytes; - int empty_sparse_region = 0; - - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA, - "archive_read_data_block"); - - if (t->entry_eof || t->entry_remaining_bytes <= 0) { - r = ARCHIVE_EOF; - goto abort_read_data; - } - - /* - * Open the current file. - */ - if (t->entry_fd < 0) { - int flags = O_RDONLY | O_BINARY | O_CLOEXEC; - - /* - * Eliminate or reduce cache effects if we can. - * - * Carefully consider this to be enabled. - */ -#if defined(O_DIRECT) && 0/* Disabled for now */ - if (t->current_filesystem->xfer_align != -1 && - t->nlink == 1) - flags |= O_DIRECT; -#endif -#if defined(O_NOATIME) - /* - * Linux has O_NOATIME flag; use it if we need. - */ - if ((t->flags & needsRestoreTimes) != 0 && - t->restore_time.noatime == 0) - flags |= O_NOATIME; -#endif - t->entry_fd = open_on_current_dir(t, - tree_current_access_path(t), flags); - __archive_ensure_cloexec_flag(t->entry_fd); -#if defined(O_NOATIME) - /* - * When we did open the file with O_NOATIME flag, - * if successful, set 1 to t->restore_time.noatime - * not to restore an atime of the file later. - * if failed by EPERM, retry it without O_NOATIME flag. - */ - if (flags & O_NOATIME) { - if (t->entry_fd >= 0) - t->restore_time.noatime = 1; - else if (errno == EPERM) - flags &= ~O_NOATIME; - } -#endif - if (t->entry_fd < 0) { - archive_set_error(&a->archive, errno, - "Couldn't open %s", tree_current_path(t)); - r = ARCHIVE_FAILED; - tree_enter_initial_dir(t); - goto abort_read_data; - } - tree_enter_initial_dir(t); - } - - /* - * Allocate read buffer if not allocated. - */ - if (t->current_filesystem->allocation_ptr == NULL) { - r = setup_suitable_read_buffer(a); - if (r != ARCHIVE_OK) { - a->archive.state = ARCHIVE_STATE_FATAL; - goto abort_read_data; - } - } - t->entry_buff = t->current_filesystem->buff; - t->entry_buff_size = t->current_filesystem->buff_size; - - buffbytes = t->entry_buff_size; - if ((int64_t)buffbytes > t->current_sparse->length) - buffbytes = t->current_sparse->length; - - if (t->current_sparse->length == 0) - empty_sparse_region = 1; - - /* - * Skip hole. - * TODO: Should we consider t->current_filesystem->xfer_align? - */ - if (t->current_sparse->offset > t->entry_total) { - if (lseek(t->entry_fd, - (off_t)t->current_sparse->offset, SEEK_SET) < 0) { - archive_set_error(&a->archive, errno, "Seek error"); - r = ARCHIVE_FATAL; - a->archive.state = ARCHIVE_STATE_FATAL; - goto abort_read_data; - } - sparse_bytes = t->current_sparse->offset - t->entry_total; - t->entry_remaining_bytes -= sparse_bytes; - t->entry_total += sparse_bytes; - } - - /* - * Read file contents. - */ - if (buffbytes > 0) { - bytes = read(t->entry_fd, t->entry_buff, buffbytes); - if (bytes < 0) { - archive_set_error(&a->archive, errno, "Read error"); - r = ARCHIVE_FATAL; - a->archive.state = ARCHIVE_STATE_FATAL; - goto abort_read_data; - } - } else - bytes = 0; - /* - * Return an EOF unless we've read a leading empty sparse region, which - * is used to represent fully-sparse files. - */ - if (bytes == 0 && !empty_sparse_region) { - /* Get EOF */ - t->entry_eof = 1; - r = ARCHIVE_EOF; - goto abort_read_data; - } - *buff = t->entry_buff; - *size = bytes; - *offset = t->entry_total; - t->entry_total += bytes; - t->entry_remaining_bytes -= bytes; - if (t->entry_remaining_bytes == 0) { - /* Close the current file descriptor */ - close_and_restore_time(t->entry_fd, t, &t->restore_time); - t->entry_fd = -1; - t->entry_eof = 1; - } - t->current_sparse->offset += bytes; - t->current_sparse->length -= bytes; - if (t->current_sparse->length == 0 && !t->entry_eof) - t->current_sparse++; - return (ARCHIVE_OK); - -abort_read_data: - *buff = NULL; - *size = 0; - *offset = t->entry_total; - if (t->entry_fd >= 0) { - /* Close the current file descriptor */ - close_and_restore_time(t->entry_fd, t, &t->restore_time); - t->entry_fd = -1; - } - return (r); -} - -static int -next_entry(struct archive_read_disk *a, struct tree *t, - struct archive_entry *entry) -{ - const struct stat *st; /* info to use for this entry */ - const struct stat *lst;/* lstat() information */ - const char *name; - int delayed, delayed_errno, descend, r; - struct archive_string delayed_str; - - delayed = ARCHIVE_OK; - delayed_errno = 0; - archive_string_init(&delayed_str); - - st = NULL; - lst = NULL; - t->descend = 0; - do { - switch (tree_next(t)) { - case TREE_ERROR_FATAL: - archive_set_error(&a->archive, t->tree_errno, - "%s: Unable to continue traversing directory tree", - tree_current_path(t)); - a->archive.state = ARCHIVE_STATE_FATAL; - tree_enter_initial_dir(t); - return (ARCHIVE_FATAL); - case TREE_ERROR_DIR: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "%s: Couldn't visit directory", - tree_current_path(t)); - tree_enter_initial_dir(t); - return (ARCHIVE_FAILED); - case 0: - tree_enter_initial_dir(t); - return (ARCHIVE_EOF); - case TREE_POSTDESCENT: - case TREE_POSTASCENT: - break; - case TREE_REGULAR: - lst = tree_current_lstat(t); - if (lst == NULL) { - if (errno == ENOENT && t->depth > 0) { - delayed = ARCHIVE_WARN; - delayed_errno = errno; - if (delayed_str.length == 0) { - archive_string_sprintf(&delayed_str, - "%s", tree_current_path(t)); - } else { - archive_string_sprintf(&delayed_str, - " %s", tree_current_path(t)); - } - } else { - archive_set_error(&a->archive, errno, - "%s: Cannot stat", - tree_current_path(t)); - tree_enter_initial_dir(t); - return (ARCHIVE_FAILED); - } - } - break; - } - } while (lst == NULL); - -#ifdef __APPLE__ - if (a->flags & ARCHIVE_READDISK_MAC_COPYFILE) { - /* If we're using copyfile(), ignore "._XXX" files. */ - const char *bname = strrchr(tree_current_path(t), '/'); - if (bname == NULL) - bname = tree_current_path(t); - else - ++bname; - if (bname[0] == '.' && bname[1] == '_') - return (ARCHIVE_RETRY); - } -#endif - - archive_entry_copy_pathname(entry, tree_current_path(t)); - /* - * Perform path matching. - */ - if (a->matching) { - r = archive_match_path_excluded(a->matching, entry); - if (r < 0) { - archive_set_error(&(a->archive), errno, - "Failed : %s", archive_error_string(a->matching)); - return (r); - } - if (r) { - if (a->excluded_cb_func) - a->excluded_cb_func(&(a->archive), - a->excluded_cb_data, entry); - return (ARCHIVE_RETRY); - } - } - - /* - * Distinguish 'L'/'P'/'H' symlink following. - */ - switch(t->symlink_mode) { - case 'H': - /* 'H': After the first item, rest like 'P'. */ - t->symlink_mode = 'P'; - /* 'H': First item (from command line) like 'L'. */ - /* FALLTHROUGH */ - case 'L': - /* 'L': Do descend through a symlink to dir. */ - descend = tree_current_is_dir(t); - /* 'L': Follow symlinks to files. */ - a->symlink_mode = 'L'; - a->follow_symlinks = 1; - /* 'L': Archive symlinks as targets, if we can. */ - st = tree_current_stat(t); - if (st != NULL && !tree_target_is_same_as_parent(t, st)) - break; - /* If stat fails, we have a broken symlink; - * in that case, don't follow the link. */ - /* FALLTHROUGH */ - default: - /* 'P': Don't descend through a symlink to dir. */ - descend = tree_current_is_physical_dir(t); - /* 'P': Don't follow symlinks to files. */ - a->symlink_mode = 'P'; - a->follow_symlinks = 0; - /* 'P': Archive symlinks as symlinks. */ - st = lst; - break; - } - - if (update_current_filesystem(a, st->st_dev) != ARCHIVE_OK) { - a->archive.state = ARCHIVE_STATE_FATAL; - tree_enter_initial_dir(t); - return (ARCHIVE_FATAL); - } - if (t->initial_filesystem_id == -1) - t->initial_filesystem_id = t->current_filesystem_id; - if (a->flags & ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS) { - if (t->initial_filesystem_id != t->current_filesystem_id) - descend = 0; - } - t->descend = descend; - - /* - * Honor nodump flag. - * If the file is marked with nodump flag, do not return this entry. - */ - if (a->flags & ARCHIVE_READDISK_HONOR_NODUMP) { -#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP) - if (st->st_flags & UF_NODUMP) - return (ARCHIVE_RETRY); -#elif (defined(FS_IOC_GETFLAGS) && defined(FS_NODUMP_FL) && \ - defined(HAVE_WORKING_FS_IOC_GETFLAGS)) || \ - (defined(EXT2_IOC_GETFLAGS) && defined(EXT2_NODUMP_FL) && \ - defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)) - if (S_ISREG(st->st_mode) || S_ISDIR(st->st_mode)) { - int stflags; - - t->entry_fd = open_on_current_dir(t, - tree_current_access_path(t), - O_RDONLY | O_NONBLOCK | O_CLOEXEC); - __archive_ensure_cloexec_flag(t->entry_fd); - if (t->entry_fd >= 0) { - r = ioctl(t->entry_fd, -#ifdef FS_IOC_GETFLAGS - FS_IOC_GETFLAGS, -#else - EXT2_IOC_GETFLAGS, -#endif - &stflags); -#ifdef FS_NODUMP_FL - if (r == 0 && (stflags & FS_NODUMP_FL) != 0) -#else - if (r == 0 && (stflags & EXT2_NODUMP_FL) != 0) -#endif - return (ARCHIVE_RETRY); - } - } -#endif - } - - archive_entry_copy_stat(entry, st); - - /* Save the times to be restored. This must be in before - * calling archive_read_disk_descend() or any chance of it, - * especially, invoking a callback. */ - t->restore_time.mtime = archive_entry_mtime(entry); - t->restore_time.mtime_nsec = archive_entry_mtime_nsec(entry); - t->restore_time.atime = archive_entry_atime(entry); - t->restore_time.atime_nsec = archive_entry_atime_nsec(entry); - t->restore_time.filetype = archive_entry_filetype(entry); - t->restore_time.noatime = t->current_filesystem->noatime; - - /* - * Perform time matching. - */ - if (a->matching) { - r = archive_match_time_excluded(a->matching, entry); - if (r < 0) { - archive_set_error(&(a->archive), errno, - "Failed : %s", archive_error_string(a->matching)); - return (r); - } - if (r) { - if (a->excluded_cb_func) - a->excluded_cb_func(&(a->archive), - a->excluded_cb_data, entry); - return (ARCHIVE_RETRY); - } - } - - /* Lookup uname/gname */ - name = archive_read_disk_uname(&(a->archive), archive_entry_uid(entry)); - if (name != NULL) - archive_entry_copy_uname(entry, name); - name = archive_read_disk_gname(&(a->archive), archive_entry_gid(entry)); - if (name != NULL) - archive_entry_copy_gname(entry, name); - - /* - * Perform owner matching. - */ - if (a->matching) { - r = archive_match_owner_excluded(a->matching, entry); - if (r < 0) { - archive_set_error(&(a->archive), errno, - "Failed : %s", archive_error_string(a->matching)); - return (r); - } - if (r) { - if (a->excluded_cb_func) - a->excluded_cb_func(&(a->archive), - a->excluded_cb_data, entry); - return (ARCHIVE_RETRY); - } - } - - /* - * Invoke a meta data filter callback. - */ - if (a->metadata_filter_func) { - if (!a->metadata_filter_func(&(a->archive), - a->metadata_filter_data, entry)) - return (ARCHIVE_RETRY); - } - - /* - * Populate the archive_entry with metadata from the disk. - */ - archive_entry_copy_sourcepath(entry, tree_current_access_path(t)); - r = archive_read_disk_entry_from_file(&(a->archive), entry, - t->entry_fd, st); - - if (r == ARCHIVE_OK) { - r = delayed; - if (r != ARCHIVE_OK) { - archive_string_sprintf(&delayed_str, ": %s", - "File removed before we read it"); - archive_set_error(&(a->archive), delayed_errno, - "%s", delayed_str.s); - } - } - archive_string_free(&delayed_str); - - return (r); -} - -static int -_archive_read_next_header(struct archive *_a, struct archive_entry **entryp) -{ - int ret; - struct archive_read_disk *a = (struct archive_read_disk *)_a; - *entryp = NULL; - ret = _archive_read_next_header2(_a, a->entry); - *entryp = a->entry; - return ret; -} - -static int -_archive_read_next_header2(struct archive *_a, struct archive_entry *entry) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - struct tree *t; - int r; - - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, - "archive_read_next_header2"); - - t = a->tree; - if (t->entry_fd >= 0) { - close_and_restore_time(t->entry_fd, t, &t->restore_time); - t->entry_fd = -1; - } - - archive_entry_clear(entry); - - for (;;) { - r = next_entry(a, t, entry); - if (t->entry_fd >= 0) { - close(t->entry_fd); - t->entry_fd = -1; - } - - if (r == ARCHIVE_RETRY) { - archive_entry_clear(entry); - continue; - } - break; - } - - /* Return to the initial directory. */ - tree_enter_initial_dir(t); - - /* - * EOF and FATAL are persistent at this layer. By - * modifying the state, we guarantee that future calls to - * read a header or read data will fail. - */ - switch (r) { - case ARCHIVE_EOF: - a->archive.state = ARCHIVE_STATE_EOF; - break; - case ARCHIVE_OK: - case ARCHIVE_WARN: - /* Overwrite the sourcepath based on the initial directory. */ - archive_entry_copy_sourcepath(entry, tree_current_path(t)); - t->entry_total = 0; - if (archive_entry_filetype(entry) == AE_IFREG) { - t->nlink = archive_entry_nlink(entry); - t->entry_remaining_bytes = archive_entry_size(entry); - t->entry_eof = (t->entry_remaining_bytes == 0)? 1: 0; - if (!t->entry_eof && - setup_sparse(a, entry) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } else { - t->entry_remaining_bytes = 0; - t->entry_eof = 1; - } - a->archive.state = ARCHIVE_STATE_DATA; - break; - case ARCHIVE_RETRY: - break; - case ARCHIVE_FATAL: - a->archive.state = ARCHIVE_STATE_FATAL; - break; - } - - __archive_reset_read_data(&a->archive); - return (r); -} - -static int -setup_sparse(struct archive_read_disk *a, struct archive_entry *entry) -{ - struct tree *t = a->tree; - int64_t length, offset; - int i; - - t->sparse_count = archive_entry_sparse_reset(entry); - if (t->sparse_count+1 > t->sparse_list_size) { - free(t->sparse_list); - t->sparse_list_size = t->sparse_count + 1; - t->sparse_list = malloc(sizeof(t->sparse_list[0]) * - t->sparse_list_size); - if (t->sparse_list == NULL) { - t->sparse_list_size = 0; - archive_set_error(&a->archive, ENOMEM, - "Can't allocate data"); - a->archive.state = ARCHIVE_STATE_FATAL; - return (ARCHIVE_FATAL); - } - } - for (i = 0; i < t->sparse_count; i++) { - archive_entry_sparse_next(entry, &offset, &length); - t->sparse_list[i].offset = offset; - t->sparse_list[i].length = length; - } - if (i == 0) { - t->sparse_list[i].offset = 0; - t->sparse_list[i].length = archive_entry_size(entry); - } else { - t->sparse_list[i].offset = archive_entry_size(entry); - t->sparse_list[i].length = 0; - } - t->current_sparse = t->sparse_list; - - return (ARCHIVE_OK); -} - -int -archive_read_disk_set_matching(struct archive *_a, struct archive *_ma, - void (*_excluded_func)(struct archive *, void *, struct archive_entry *), - void *_client_data) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_read_disk_set_matching"); - a->matching = _ma; - a->excluded_cb_func = _excluded_func; - a->excluded_cb_data = _client_data; - return (ARCHIVE_OK); -} - -int -archive_read_disk_set_metadata_filter_callback(struct archive *_a, - int (*_metadata_filter_func)(struct archive *, void *, - struct archive_entry *), void *_client_data) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_ANY, - "archive_read_disk_set_metadata_filter_callback"); - - a->metadata_filter_func = _metadata_filter_func; - a->metadata_filter_data = _client_data; - return (ARCHIVE_OK); -} - -int -archive_read_disk_can_descend(struct archive *_a) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - struct tree *t = a->tree; - - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, - "archive_read_disk_can_descend"); - - return (t->visit_type == TREE_REGULAR && t->descend); -} - -/* - * Called by the client to mark the directory just returned from - * tree_next() as needing to be visited. - */ -int -archive_read_disk_descend(struct archive *_a) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - struct tree *t = a->tree; - - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, - "archive_read_disk_descend"); - - if (!archive_read_disk_can_descend(_a)) - return (ARCHIVE_OK); - - /* - * We must not treat the initial specified path as a physical dir, - * because if we do then we will try and ascend out of it by opening - * ".." which is (a) wrong and (b) causes spurious permissions errors - * if ".." is not readable by us. Instead, treat it as if it were a - * symlink. (This uses an extra fd, but it can only happen once at the - * top level of a traverse.) But we can't necessarily assume t->st is - * valid here (though t->lst is), which complicates the logic a - * little. - */ - if (tree_current_is_physical_dir(t)) { - tree_push(t, t->basename, t->current_filesystem_id, - t->lst.st_dev, t->lst.st_ino, &t->restore_time); - if (t->stack->parent->parent != NULL) - t->stack->flags |= isDir; - else - t->stack->flags |= isDirLink; - } else if (tree_current_is_dir(t)) { - tree_push(t, t->basename, t->current_filesystem_id, - t->st.st_dev, t->st.st_ino, &t->restore_time); - t->stack->flags |= isDirLink; - } - t->descend = 0; - return (ARCHIVE_OK); -} - -int -archive_read_disk_open(struct archive *_a, const char *pathname) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED, - "archive_read_disk_open"); - archive_clear_error(&a->archive); - - return (_archive_read_disk_open(_a, pathname)); -} - -int -archive_read_disk_open_w(struct archive *_a, const wchar_t *pathname) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - struct archive_string path; - int ret; - - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED, - "archive_read_disk_open_w"); - archive_clear_error(&a->archive); - - /* Make a char string from a wchar_t string. */ - archive_string_init(&path); - if (archive_string_append_from_wcs(&path, pathname, - wcslen(pathname)) != 0) { - if (errno == ENOMEM) - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - else - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Can't convert a path to a char string"); - a->archive.state = ARCHIVE_STATE_FATAL; - ret = ARCHIVE_FATAL; - } else - ret = _archive_read_disk_open(_a, path.s); - - archive_string_free(&path); - return (ret); -} - -static int -_archive_read_disk_open(struct archive *_a, const char *pathname) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - - if (a->tree != NULL) - a->tree = tree_reopen(a->tree, pathname, - a->flags & ARCHIVE_READDISK_RESTORE_ATIME); - else - a->tree = tree_open(pathname, a->symlink_mode, - a->flags & ARCHIVE_READDISK_RESTORE_ATIME); - if (a->tree == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate tar data"); - a->archive.state = ARCHIVE_STATE_FATAL; - return (ARCHIVE_FATAL); - } - a->archive.state = ARCHIVE_STATE_HEADER; - - return (ARCHIVE_OK); -} - -/* - * Return a current filesystem ID which is index of the filesystem entry - * you've visited through archive_read_disk. - */ -int -archive_read_disk_current_filesystem(struct archive *_a) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA, - "archive_read_disk_current_filesystem"); - - return (a->tree->current_filesystem_id); -} - -static int -update_current_filesystem(struct archive_read_disk *a, int64_t dev) -{ - struct tree *t = a->tree; - int i, fid; - - if (t->current_filesystem != NULL && - t->current_filesystem->dev == dev) - return (ARCHIVE_OK); - - for (i = 0; i < t->max_filesystem_id; i++) { - if (t->filesystem_table[i].dev == dev) { - /* There is the filesystem ID we've already generated. */ - t->current_filesystem_id = i; - t->current_filesystem = &(t->filesystem_table[i]); - return (ARCHIVE_OK); - } - } - - /* - * This is the new filesystem which we have to generate a new ID for. - */ - fid = t->max_filesystem_id++; - if (t->max_filesystem_id > t->allocated_filesystem) { - size_t s; - void *p; - - s = t->max_filesystem_id * 2; - p = realloc(t->filesystem_table, - s * sizeof(*t->filesystem_table)); - if (p == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate tar data"); - return (ARCHIVE_FATAL); - } - t->filesystem_table = (struct filesystem *)p; - t->allocated_filesystem = s; - } - t->current_filesystem_id = fid; - t->current_filesystem = &(t->filesystem_table[fid]); - t->current_filesystem->dev = dev; - t->current_filesystem->allocation_ptr = NULL; - t->current_filesystem->buff = NULL; - - /* Setup the current filesystem properties which depend on - * platform specific. */ - return (setup_current_filesystem(a)); -} - -/* - * Returns 1 if current filesystem is generated filesystem, 0 if it is not - * or -1 if it is unknown. - */ -int -archive_read_disk_current_filesystem_is_synthetic(struct archive *_a) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA, - "archive_read_disk_current_filesystem"); - - return (a->tree->current_filesystem->synthetic); -} - -/* - * Returns 1 if current filesystem is remote filesystem, 0 if it is not - * or -1 if it is unknown. - */ -int -archive_read_disk_current_filesystem_is_remote(struct archive *_a) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA, - "archive_read_disk_current_filesystem"); - - return (a->tree->current_filesystem->remote); -} - -#if defined(_PC_REC_INCR_XFER_SIZE) && defined(_PC_REC_MAX_XFER_SIZE) &&\ - defined(_PC_REC_MIN_XFER_SIZE) && defined(_PC_REC_XFER_ALIGN) -static int -get_xfer_size(struct tree *t, int fd, const char *path) -{ - t->current_filesystem->xfer_align = -1; - errno = 0; - if (fd >= 0) { - t->current_filesystem->incr_xfer_size = - fpathconf(fd, _PC_REC_INCR_XFER_SIZE); - t->current_filesystem->max_xfer_size = - fpathconf(fd, _PC_REC_MAX_XFER_SIZE); - t->current_filesystem->min_xfer_size = - fpathconf(fd, _PC_REC_MIN_XFER_SIZE); - t->current_filesystem->xfer_align = - fpathconf(fd, _PC_REC_XFER_ALIGN); - } else if (path != NULL) { - t->current_filesystem->incr_xfer_size = - pathconf(path, _PC_REC_INCR_XFER_SIZE); - t->current_filesystem->max_xfer_size = - pathconf(path, _PC_REC_MAX_XFER_SIZE); - t->current_filesystem->min_xfer_size = - pathconf(path, _PC_REC_MIN_XFER_SIZE); - t->current_filesystem->xfer_align = - pathconf(path, _PC_REC_XFER_ALIGN); - } - /* At least we need an alignment size. */ - if (t->current_filesystem->xfer_align == -1) - return ((errno == EINVAL)?1:-1); - else - return (0); -} -#else -static int -get_xfer_size(struct tree *t, int fd, const char *path) -{ - (void)t; /* UNUSED */ - (void)fd; /* UNUSED */ - (void)path; /* UNUSED */ - return (1);/* Not supported */ -} -#endif - -#if defined(HAVE_STATVFS) -static inline __LA_UNUSED void -set_statvfs_transfer_size(struct filesystem *fs, const struct statvfs *sfs) -{ - fs->xfer_align = sfs->f_frsize > 0 ? (long)sfs->f_frsize : -1; - fs->max_xfer_size = -1; -#if defined(HAVE_STRUCT_STATVFS_F_IOSIZE) - fs->min_xfer_size = sfs->f_iosize > 0 ? (long)sfs->f_iosize : -1; - fs->incr_xfer_size = sfs->f_iosize > 0 ? (long)sfs->f_iosize : -1; -#else - fs->min_xfer_size = sfs->f_bsize > 0 ? (long)sfs->f_bsize : -1; - fs->incr_xfer_size = sfs->f_bsize > 0 ? (long)sfs->f_bsize : -1; -#endif -} -#endif - -#if defined(HAVE_STRUCT_STATFS) -static inline __LA_UNUSED void -set_statfs_transfer_size(struct filesystem *fs, const struct statfs *sfs) -{ - fs->xfer_align = sfs->f_bsize > 0 ? (long)sfs->f_bsize : -1; - fs->max_xfer_size = -1; -#if defined(HAVE_STRUCT_STATFS_F_IOSIZE) - fs->min_xfer_size = sfs->f_iosize > 0 ? (long)sfs->f_iosize : -1; - fs->incr_xfer_size = sfs->f_iosize > 0 ? (long)sfs->f_iosize : -1; -#else - fs->min_xfer_size = sfs->f_bsize > 0 ? (long)sfs->f_bsize : -1; - fs->incr_xfer_size = sfs->f_bsize > 0 ? (long)sfs->f_bsize : -1; -#endif -} -#endif - -#if defined(HAVE_STRUCT_STATFS) && defined(HAVE_STATFS) && \ - defined(HAVE_FSTATFS) && defined(MNT_LOCAL) && !defined(ST_LOCAL) - -/* - * Gather current filesystem properties on FreeBSD, OpenBSD and Mac OS X. - */ -static int -setup_current_filesystem(struct archive_read_disk *a) -{ - struct tree *t = a->tree; - struct statfs sfs; -#if defined(HAVE_GETVFSBYNAME) && defined(VFCF_SYNTHETIC) -/* TODO: configure should set GETVFSBYNAME_ARG_TYPE to make - * this accurate; some platforms have both and we need the one that's - * used by getvfsbyname() - * - * Then the following would become: - * #if defined(GETVFSBYNAME_ARG_TYPE) - * GETVFSBYNAME_ARG_TYPE vfc; - * #endif - */ -# if defined(HAVE_STRUCT_XVFSCONF) - struct xvfsconf vfc; -# else - struct vfsconf vfc; -# endif -#endif - int r, xr = 0; -#if !defined(HAVE_STRUCT_STATFS_F_NAMEMAX) - long nm; -#endif - - t->current_filesystem->synthetic = -1; - t->current_filesystem->remote = -1; - if (tree_current_is_symblic_link_target(t)) { -#if defined(HAVE_OPENAT) - /* - * Get file system statistics on any directory - * where current is. - */ - int fd = openat(tree_current_dir_fd(t), - tree_current_access_path(t), O_RDONLY | O_CLOEXEC); - __archive_ensure_cloexec_flag(fd); - if (fd < 0) { - archive_set_error(&a->archive, errno, - "openat failed"); - return (ARCHIVE_FAILED); - } - r = fstatfs(fd, &sfs); - if (r == 0) - xr = get_xfer_size(t, fd, NULL); - close(fd); -#else - if (tree_enter_working_dir(t) != 0) { - archive_set_error(&a->archive, errno, "fchdir failed"); - return (ARCHIVE_FAILED); - } - r = statfs(tree_current_access_path(t), &sfs); - if (r == 0) - xr = get_xfer_size(t, -1, tree_current_access_path(t)); -#endif - } else { - r = fstatfs(tree_current_dir_fd(t), &sfs); - if (r == 0) - xr = get_xfer_size(t, tree_current_dir_fd(t), NULL); - } - if (r == -1 || xr == -1) { - archive_set_error(&a->archive, errno, "statfs failed"); - return (ARCHIVE_FAILED); - } else if (xr == 1) { - /* pathconf(_PC_REX_*) operations are not supported. */ - set_statfs_transfer_size(t->current_filesystem, &sfs); - } - if (sfs.f_flags & MNT_LOCAL) - t->current_filesystem->remote = 0; - else - t->current_filesystem->remote = 1; - -#if defined(HAVE_GETVFSBYNAME) && defined(VFCF_SYNTHETIC) - r = getvfsbyname(sfs.f_fstypename, &vfc); - if (r == -1) { - archive_set_error(&a->archive, errno, "getvfsbyname failed"); - return (ARCHIVE_FAILED); - } - if (vfc.vfc_flags & VFCF_SYNTHETIC) - t->current_filesystem->synthetic = 1; - else - t->current_filesystem->synthetic = 0; -#endif - -#if defined(MNT_NOATIME) - if (sfs.f_flags & MNT_NOATIME) - t->current_filesystem->noatime = 1; - else -#endif - t->current_filesystem->noatime = 0; - -#if defined(USE_READDIR_R) - /* Set maximum filename length. */ -#if defined(HAVE_STRUCT_STATFS_F_NAMEMAX) - t->current_filesystem->name_max = sfs.f_namemax; -#else -# if defined(_PC_NAME_MAX) - /* Mac OS X does not have f_namemax in struct statfs. */ - if (tree_current_is_symblic_link_target(t)) { - if (tree_enter_working_dir(t) != 0) { - archive_set_error(&a->archive, errno, "fchdir failed"); - return (ARCHIVE_FAILED); - } - nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX); - } else - nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX); -# else - nm = -1; -# endif - if (nm == -1) - t->current_filesystem->name_max = NAME_MAX; - else - t->current_filesystem->name_max = nm; -#endif - if (t->current_filesystem->name_max == 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Cannot determine name_max"); - return (ARCHIVE_FAILED); - } -#endif /* USE_READDIR_R */ - return (ARCHIVE_OK); -} - -#elif (defined(HAVE_STATVFS) || defined(HAVE_FSTATVFS)) && defined(ST_LOCAL) - -/* - * Gather current filesystem properties on NetBSD - */ -static int -setup_current_filesystem(struct archive_read_disk *a) -{ - struct tree *t = a->tree; - struct statvfs svfs; - int r, xr = 0; - - t->current_filesystem->synthetic = -1; - if (tree_enter_working_dir(t) != 0) { - archive_set_error(&a->archive, errno, "fchdir failed"); - return (ARCHIVE_FAILED); - } - if (tree_current_is_symblic_link_target(t)) { - r = statvfs(tree_current_access_path(t), &svfs); - if (r == 0) - xr = get_xfer_size(t, -1, tree_current_access_path(t)); - } else { -#ifdef HAVE_FSTATVFS - r = fstatvfs(tree_current_dir_fd(t), &svfs); - if (r == 0) - xr = get_xfer_size(t, tree_current_dir_fd(t), NULL); -#else - r = statvfs(".", &svfs); - if (r == 0) - xr = get_xfer_size(t, -1, "."); -#endif - } - if (r == -1 || xr == -1) { - t->current_filesystem->remote = -1; - archive_set_error(&a->archive, errno, "statvfs failed"); - return (ARCHIVE_FAILED); - } else if (xr == 1) { - /* Usually come here unless NetBSD supports _PC_REC_XFER_ALIGN - * for pathconf() function. */ - set_statvfs_transfer_size(t->current_filesystem, &svfs); - } - if (svfs.f_flag & ST_LOCAL) - t->current_filesystem->remote = 0; - else - t->current_filesystem->remote = 1; - -#if defined(ST_NOATIME) - if (svfs.f_flag & ST_NOATIME) - t->current_filesystem->noatime = 1; - else -#endif - t->current_filesystem->noatime = 0; - - /* Set maximum filename length. */ - t->current_filesystem->name_max = svfs.f_namemax; - return (ARCHIVE_OK); -} - -#elif defined(HAVE_SYS_STATFS_H) && defined(HAVE_LINUX_MAGIC_H) &&\ - defined(HAVE_STATFS) && defined(HAVE_FSTATFS) -/* - * Note: statfs is deprecated since LSB 3.2 - */ - -#ifndef CIFS_SUPER_MAGIC -#define CIFS_SUPER_MAGIC 0xFF534D42 -#endif -#ifndef DEVFS_SUPER_MAGIC -#define DEVFS_SUPER_MAGIC 0x1373 -#endif - -/* - * Gather current filesystem properties on Linux - */ -static int -setup_current_filesystem(struct archive_read_disk *a) -{ - struct tree *t = a->tree; - struct statfs sfs; -#if defined(HAVE_STATVFS) - struct statvfs svfs; -#endif - int r, vr = 0, xr = 0; - - if (tree_current_is_symblic_link_target(t)) { -#if defined(HAVE_OPENAT) - /* - * Get file system statistics on any directory - * where current is. - */ - int fd = openat(tree_current_dir_fd(t), - tree_current_access_path(t), O_RDONLY | O_CLOEXEC); - __archive_ensure_cloexec_flag(fd); - if (fd < 0) { - archive_set_error(&a->archive, errno, - "openat failed"); - return (ARCHIVE_FAILED); - } -#if defined(HAVE_FSTATVFS) - vr = fstatvfs(fd, &svfs);/* for f_flag, mount flags */ -#endif - r = fstatfs(fd, &sfs); - if (r == 0) - xr = get_xfer_size(t, fd, NULL); - close(fd); -#else - if (tree_enter_working_dir(t) != 0) { - archive_set_error(&a->archive, errno, "fchdir failed"); - return (ARCHIVE_FAILED); - } -#if defined(HAVE_STATVFS) - vr = statvfs(tree_current_access_path(t), &svfs); -#endif - r = statfs(tree_current_access_path(t), &sfs); - if (r == 0) - xr = get_xfer_size(t, -1, tree_current_access_path(t)); -#endif - } else { -#ifdef HAVE_FSTATFS -#if defined(HAVE_FSTATVFS) - vr = fstatvfs(tree_current_dir_fd(t), &svfs); -#endif - r = fstatfs(tree_current_dir_fd(t), &sfs); - if (r == 0) - xr = get_xfer_size(t, tree_current_dir_fd(t), NULL); -#else - if (tree_enter_working_dir(t) != 0) { - archive_set_error(&a->archive, errno, "fchdir failed"); - return (ARCHIVE_FAILED); - } -#if defined(HAVE_STATVFS) - vr = statvfs(".", &svfs); -#endif - r = statfs(".", &sfs); - if (r == 0) - xr = get_xfer_size(t, -1, "."); -#endif - } - if (r == -1 || xr == -1 || vr == -1) { - t->current_filesystem->synthetic = -1; - t->current_filesystem->remote = -1; - archive_set_error(&a->archive, errno, "statfs failed"); - return (ARCHIVE_FAILED); - } else if (xr == 1) { - /* pathconf(_PC_REX_*) operations are not supported. */ -#if defined(HAVE_STATVFS) - set_statvfs_transfer_size(t->current_filesystem, &svfs); -#else - set_statfs_transfer_size(t->current_filesystem, &sfs); -#endif - } - switch (sfs.f_type) { - case AFS_SUPER_MAGIC: - case CIFS_SUPER_MAGIC: - case CODA_SUPER_MAGIC: - case NCP_SUPER_MAGIC:/* NetWare */ - case NFS_SUPER_MAGIC: - case SMB_SUPER_MAGIC: - t->current_filesystem->remote = 1; - t->current_filesystem->synthetic = 0; - break; - case DEVFS_SUPER_MAGIC: - case PROC_SUPER_MAGIC: - case USBDEVICE_SUPER_MAGIC: - t->current_filesystem->remote = 0; - t->current_filesystem->synthetic = 1; - break; - default: - t->current_filesystem->remote = 0; - t->current_filesystem->synthetic = 0; - break; - } - -#if defined(ST_NOATIME) -#if defined(HAVE_STATVFS) - if (svfs.f_flag & ST_NOATIME) -#else - if (sfs.f_flags & ST_NOATIME) -#endif - t->current_filesystem->noatime = 1; - else -#endif - t->current_filesystem->noatime = 0; - -#if defined(USE_READDIR_R) - /* Set maximum filename length. */ -#if defined(HAVE_STATVFS) - t->current_filesystem->name_max = svfs.f_namemax; -#else - t->current_filesystem->name_max = sfs.f_namelen; -#endif - if (t->current_filesystem->name_max == 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Cannot determine name_max"); - return (ARCHIVE_FAILED); - } -#endif - return (ARCHIVE_OK); -} - -#elif defined(HAVE_SYS_STATVFS_H) &&\ - (defined(HAVE_STATVFS) || defined(HAVE_FSTATVFS)) - -/* - * Gather current filesystem properties on other posix platform. - */ -static int -setup_current_filesystem(struct archive_read_disk *a) -{ - struct tree *t = a->tree; - struct statvfs svfs; - int r, xr = 0; - - t->current_filesystem->synthetic = -1;/* Not supported */ - t->current_filesystem->remote = -1;/* Not supported */ - if (tree_current_is_symblic_link_target(t)) { -#if defined(HAVE_OPENAT) - /* - * Get file system statistics on any directory - * where current is. - */ - int fd = openat(tree_current_dir_fd(t), - tree_current_access_path(t), O_RDONLY | O_CLOEXEC); - __archive_ensure_cloexec_flag(fd); - if (fd < 0) { - archive_set_error(&a->archive, errno, - "openat failed"); - return (ARCHIVE_FAILED); - } - r = fstatvfs(fd, &svfs); - if (r == 0) - xr = get_xfer_size(t, fd, NULL); - close(fd); -#else - if (tree_enter_working_dir(t) != 0) { - archive_set_error(&a->archive, errno, "fchdir failed"); - return (ARCHIVE_FAILED); - } - r = statvfs(tree_current_access_path(t), &svfs); - if (r == 0) - xr = get_xfer_size(t, -1, tree_current_access_path(t)); -#endif - } else { -#ifdef HAVE_FSTATVFS - r = fstatvfs(tree_current_dir_fd(t), &svfs); - if (r == 0) - xr = get_xfer_size(t, tree_current_dir_fd(t), NULL); -#else - if (tree_enter_working_dir(t) != 0) { - archive_set_error(&a->archive, errno, "fchdir failed"); - return (ARCHIVE_FAILED); - } - r = statvfs(".", &svfs); - if (r == 0) - xr = get_xfer_size(t, -1, "."); -#endif - } - if (r == -1 || xr == -1) { - t->current_filesystem->synthetic = -1; - t->current_filesystem->remote = -1; - archive_set_error(&a->archive, errno, "statvfs failed"); - return (ARCHIVE_FAILED); - } else if (xr == 1) { - /* pathconf(_PC_REX_*) operations are not supported. */ - set_statvfs_transfer_size(t->current_filesystem, &svfs); - } - -#if defined(ST_NOATIME) - if (svfs.f_flag & ST_NOATIME) - t->current_filesystem->noatime = 1; - else -#endif - t->current_filesystem->noatime = 0; - -#if defined(USE_READDIR_R) - /* Set maximum filename length. */ - t->current_filesystem->name_max = svfs.f_namemax; - if (t->current_filesystem->name_max == 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Cannot determine name_max"); - return (ARCHIVE_FAILED); - } -#endif - return (ARCHIVE_OK); -} - -#else - -/* - * Generic: Gather current filesystem properties. - * TODO: Is this generic function really needed? - */ -static int -setup_current_filesystem(struct archive_read_disk *a) -{ - struct tree *t = a->tree; -#if defined(_PC_NAME_MAX) && defined(USE_READDIR_R) - long nm; -#endif - t->current_filesystem->synthetic = -1;/* Not supported */ - t->current_filesystem->remote = -1;/* Not supported */ - t->current_filesystem->noatime = 0; - (void)get_xfer_size(t, -1, ".");/* Dummy call to avoid build error. */ - t->current_filesystem->xfer_align = -1;/* Unknown */ - t->current_filesystem->max_xfer_size = -1; - t->current_filesystem->min_xfer_size = -1; - t->current_filesystem->incr_xfer_size = -1; - -#if defined(USE_READDIR_R) - /* Set maximum filename length. */ -# if defined(_PC_NAME_MAX) - if (tree_current_is_symblic_link_target(t)) { - if (tree_enter_working_dir(t) != 0) { - archive_set_error(&a->archive, errno, "fchdir failed"); - return (ARCHIVE_FAILED); - } - nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX); - } else - nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX); - if (nm == -1) -# endif /* _PC_NAME_MAX */ - /* - * Some systems (HP-UX or others?) incorrectly defined - * NAME_MAX macro to be a smaller value. - */ -# if defined(NAME_MAX) && NAME_MAX >= 255 - t->current_filesystem->name_max = NAME_MAX; -# else - /* No way to get a trusted value of maximum filename - * length. */ - t->current_filesystem->name_max = PATH_MAX; -# endif /* NAME_MAX */ -# if defined(_PC_NAME_MAX) - else - t->current_filesystem->name_max = nm; -# endif /* _PC_NAME_MAX */ - if (t->current_filesystem->name_max == 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Cannot determine name_max"); - return (ARCHIVE_FAILED); - } -#endif /* USE_READDIR_R */ - return (ARCHIVE_OK); -} - -#endif - -static int -close_and_restore_time(int fd, struct tree *t, struct restore_time *rt) -{ -#ifndef HAVE_UTIMES - (void)t; /* UNUSED */ - (void)rt; /* UNUSED */ - return (close(fd)); -#else -#if defined(HAVE_FUTIMENS) && !defined(__CYGWIN__) - struct timespec timespecs[2]; -#endif - struct timeval times[2]; - - if ((t->flags & needsRestoreTimes) == 0 || rt->noatime) { - if (fd >= 0) - return (close(fd)); - else - return (0); - } - -#if defined(HAVE_FUTIMENS) && !defined(__CYGWIN__) - timespecs[1].tv_sec = rt->mtime; - timespecs[1].tv_nsec = rt->mtime_nsec; - - timespecs[0].tv_sec = rt->atime; - timespecs[0].tv_nsec = rt->atime_nsec; - /* futimens() is defined in POSIX.1-2008. */ - if (futimens(fd, timespecs) == 0) - return (close(fd)); -#endif - - times[1].tv_sec = rt->mtime; - times[1].tv_usec = rt->mtime_nsec / 1000; - - times[0].tv_sec = rt->atime; - times[0].tv_usec = rt->atime_nsec / 1000; - -#if !defined(HAVE_FUTIMENS) && defined(HAVE_FUTIMES) && !defined(__CYGWIN__) - if (futimes(fd, times) == 0) - return (close(fd)); -#endif - close(fd); -#if defined(HAVE_FUTIMESAT) - if (futimesat(tree_current_dir_fd(t), rt->name, times) == 0) - return (0); -#endif -#ifdef HAVE_LUTIMES - if (lutimes(rt->name, times) != 0) -#else - if (AE_IFLNK != rt->filetype && utimes(rt->name, times) != 0) -#endif - return (-1); -#endif - return (0); -} - -static int -open_on_current_dir(struct tree *t, const char *path, int flags) -{ -#ifdef HAVE_OPENAT - return (openat(tree_current_dir_fd(t), path, flags)); -#else - if (tree_enter_working_dir(t) != 0) - return (-1); - return (open(path, flags)); -#endif -} - -static int -tree_dup(int fd) -{ - int new_fd; -#ifdef F_DUPFD_CLOEXEC - static volatile int can_dupfd_cloexec = 1; - - if (can_dupfd_cloexec) { - new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 0); - if (new_fd != -1) - return (new_fd); - /* Linux 2.6.18 - 2.6.23 declare F_DUPFD_CLOEXEC, - * but it cannot be used. So we have to try dup(). */ - /* We won't try F_DUPFD_CLOEXEC. */ - can_dupfd_cloexec = 0; - } -#endif /* F_DUPFD_CLOEXEC */ - new_fd = dup(fd); - __archive_ensure_cloexec_flag(new_fd); - return (new_fd); -} - -/* - * Add a directory path to the current stack. - */ -static void -tree_push(struct tree *t, const char *path, int filesystem_id, - int64_t dev, int64_t ino, struct restore_time *rt) -{ - struct tree_entry *te; - - te = calloc(1, sizeof(*te)); - if (te == NULL) - __archive_errx(1, "Out of memory"); - te->next = t->stack; - te->parent = t->current; - if (te->parent) - te->depth = te->parent->depth + 1; - t->stack = te; - archive_string_init(&te->name); - te->symlink_parent_fd = -1; - archive_strcpy(&te->name, path); - te->flags = needsDescent | needsOpen | needsAscent; - te->filesystem_id = filesystem_id; - te->dev = dev; - te->ino = ino; - te->dirname_length = t->dirname_length; - te->restore_time.name = te->name.s; - if (rt != NULL) { - te->restore_time.mtime = rt->mtime; - te->restore_time.mtime_nsec = rt->mtime_nsec; - te->restore_time.atime = rt->atime; - te->restore_time.atime_nsec = rt->atime_nsec; - te->restore_time.filetype = rt->filetype; - te->restore_time.noatime = rt->noatime; - } -} - -/* - * Append a name to the current dir path. - */ -static void -tree_append(struct tree *t, const char *name, size_t name_length) -{ - size_t size_needed; - - t->path.s[t->dirname_length] = '\0'; - t->path.length = t->dirname_length; - /* Strip trailing '/' from name, unless entire name is "/". */ - while (name_length > 1 && name[name_length - 1] == '/') - name_length--; - - /* Resize pathname buffer as needed. */ - size_needed = name_length + t->dirname_length + 2; - archive_string_ensure(&t->path, size_needed); - /* Add a separating '/' if it's needed. */ - if (t->dirname_length > 0 && t->path.s[archive_strlen(&t->path)-1] != '/') - archive_strappend_char(&t->path, '/'); - t->basename = t->path.s + archive_strlen(&t->path); - archive_strncat(&t->path, name, name_length); - t->restore_time.name = t->basename; -} - -/* - * Open a directory tree for traversal. - */ -static struct tree * -tree_open(const char *path, int symlink_mode, int restore_time) -{ - struct tree *t; - - if ((t = calloc(1, sizeof(*t))) == NULL) - return (NULL); - archive_string_init(&t->path); - archive_string_ensure(&t->path, 31); - t->initial_symlink_mode = symlink_mode; - return (tree_reopen(t, path, restore_time)); -} - -static struct tree * -tree_reopen(struct tree *t, const char *path, int restore_time) -{ -#if defined(O_PATH) - /* Linux */ - const int o_flag = O_PATH; -#elif defined(O_SEARCH) - /* SunOS */ - const int o_flag = O_SEARCH; -#elif defined(__FreeBSD__) && defined(O_EXEC) - /* FreeBSD */ - const int o_flag = O_EXEC; -#endif - - t->flags = (restore_time != 0)?needsRestoreTimes:0; - t->flags |= onInitialDir; - t->visit_type = 0; - t->tree_errno = 0; - t->dirname_length = 0; - t->depth = 0; - t->descend = 0; - t->current = NULL; - t->d = INVALID_DIR_HANDLE; - t->symlink_mode = t->initial_symlink_mode; - archive_string_empty(&t->path); - t->entry_fd = -1; - t->entry_eof = 0; - t->entry_remaining_bytes = 0; - t->initial_filesystem_id = -1; - - /* First item is set up a lot like a symlink traversal. */ - tree_push(t, path, 0, 0, 0, NULL); - t->stack->flags = needsFirstVisit; - t->maxOpenCount = t->openCount = 1; - t->initial_dir_fd = open(".", O_RDONLY | O_CLOEXEC); -#if defined(O_PATH) || defined(O_SEARCH) || \ - (defined(__FreeBSD__) && defined(O_EXEC)) - /* - * Most likely reason to fail opening "." is that it's not readable, - * so try again for execute. The consequences of not opening this are - * unhelpful and unnecessary errors later. - */ - if (t->initial_dir_fd < 0) - t->initial_dir_fd = open(".", o_flag | O_CLOEXEC); -#endif - __archive_ensure_cloexec_flag(t->initial_dir_fd); - t->working_dir_fd = tree_dup(t->initial_dir_fd); - return (t); -} - -static int -tree_descent(struct tree *t) -{ - int flag, new_fd, r = 0; - - t->dirname_length = archive_strlen(&t->path); - flag = O_RDONLY | O_CLOEXEC; -#if defined(O_DIRECTORY) - flag |= O_DIRECTORY; -#endif - new_fd = open_on_current_dir(t, t->stack->name.s, flag); - __archive_ensure_cloexec_flag(new_fd); - if (new_fd < 0) { - t->tree_errno = errno; - r = TREE_ERROR_DIR; - } else { - t->depth++; - /* If it is a link, set up fd for the ascent. */ - if (t->stack->flags & isDirLink) { - t->stack->symlink_parent_fd = t->working_dir_fd; - t->openCount++; - if (t->openCount > t->maxOpenCount) - t->maxOpenCount = t->openCount; - } else - close(t->working_dir_fd); - /* Renew the current working directory. */ - t->working_dir_fd = new_fd; - t->flags &= ~onWorkingDir; - } - return (r); -} - -/* - * We've finished a directory; ascend back to the parent. - */ -static int -tree_ascend(struct tree *t) -{ - struct tree_entry *te; - int new_fd, r = 0, prev_dir_fd; - - te = t->stack; - prev_dir_fd = t->working_dir_fd; - if (te->flags & isDirLink) - new_fd = te->symlink_parent_fd; - else { - new_fd = open_on_current_dir(t, "..", O_RDONLY | O_CLOEXEC); - __archive_ensure_cloexec_flag(new_fd); - } - if (new_fd < 0) { - t->tree_errno = errno; - r = TREE_ERROR_FATAL; - } else { - /* Renew the current working directory. */ - t->working_dir_fd = new_fd; - t->flags &= ~onWorkingDir; - /* Current directory has been changed, we should - * close an fd of previous working directory. */ - close_and_restore_time(prev_dir_fd, t, &te->restore_time); - if (te->flags & isDirLink) { - t->openCount--; - te->symlink_parent_fd = -1; - } - t->depth--; - } - return (r); -} - -/* - * Return to the initial directory where tree_open() was performed. - */ -static int -tree_enter_initial_dir(struct tree *t) -{ - int r = 0; - - if ((t->flags & onInitialDir) == 0) { - r = fchdir(t->initial_dir_fd); - if (r == 0) { - t->flags &= ~onWorkingDir; - t->flags |= onInitialDir; - } - } - return (r); -} - -/* - * Restore working directory of directory traversals. - */ -static int -tree_enter_working_dir(struct tree *t) -{ - int r = 0; - - /* - * Change the current directory if really needed. - * Sometimes this is unneeded when we did not do - * descent. - */ - if (t->depth > 0 && (t->flags & onWorkingDir) == 0) { - r = fchdir(t->working_dir_fd); - if (r == 0) { - t->flags &= ~onInitialDir; - t->flags |= onWorkingDir; - } - } - return (r); -} - -static int -tree_current_dir_fd(struct tree *t) -{ - return (t->working_dir_fd); -} - -/* - * Pop the working stack. - */ -static void -tree_pop(struct tree *t) -{ - struct tree_entry *te; - - t->path.s[t->dirname_length] = '\0'; - t->path.length = t->dirname_length; - if (t->stack == t->current && t->current != NULL) - t->current = t->current->parent; - te = t->stack; - t->stack = te->next; - t->dirname_length = te->dirname_length; - t->basename = t->path.s + t->dirname_length; - while (t->basename[0] == '/') - t->basename++; - archive_string_free(&te->name); - free(te); -} - -/* - * Get the next item in the tree traversal. - */ -static int -tree_next(struct tree *t) -{ - int r; - - while (t->stack != NULL) { - /* If there's an open dir, get the next entry from there. */ - if (t->d != INVALID_DIR_HANDLE) { - r = tree_dir_next_posix(t); - if (r == 0) - continue; - return (r); - } - - if (t->stack->flags & needsFirstVisit) { - /* Top stack item needs a regular visit. */ - t->current = t->stack; - tree_append(t, t->stack->name.s, - archive_strlen(&(t->stack->name))); - /* t->dirname_length = t->path_length; */ - /* tree_pop(t); */ - t->stack->flags &= ~needsFirstVisit; - return (t->visit_type = TREE_REGULAR); - } else if (t->stack->flags & needsDescent) { - /* Top stack item is dir to descend into. */ - t->current = t->stack; - tree_append(t, t->stack->name.s, - archive_strlen(&(t->stack->name))); - t->stack->flags &= ~needsDescent; - r = tree_descent(t); - if (r != 0) { - tree_pop(t); - t->visit_type = r; - } else - t->visit_type = TREE_POSTDESCENT; - return (t->visit_type); - } else if (t->stack->flags & needsOpen) { - t->stack->flags &= ~needsOpen; - r = tree_dir_next_posix(t); - if (r == 0) - continue; - return (r); - } else if (t->stack->flags & needsAscent) { - /* Top stack item is dir and we're done with it. */ - r = tree_ascend(t); - tree_pop(t); - t->visit_type = r != 0 ? r : TREE_POSTASCENT; - return (t->visit_type); - } else { - /* Top item on stack is dead. */ - tree_pop(t); - t->flags &= ~hasLstat; - t->flags &= ~hasStat; - } - } - return (t->visit_type = 0); -} - -static int -tree_dir_next_posix(struct tree *t) -{ - int r; - const char *name; - size_t namelen; - - if (t->d == NULL) { -#if defined(USE_READDIR_R) - size_t dirent_size; -#endif - -#if defined(HAVE_FDOPENDIR) - t->d = fdopendir(tree_dup(t->working_dir_fd)); -#else /* HAVE_FDOPENDIR */ - if (tree_enter_working_dir(t) == 0) { - t->d = opendir("."); -#ifdef HAVE_DIRFD - __archive_ensure_cloexec_flag(dirfd(t->d)); -#endif - } -#endif /* HAVE_FDOPENDIR */ - if (t->d == NULL) { - r = tree_ascend(t); /* Undo "chdir" */ - tree_pop(t); - t->tree_errno = errno; - t->visit_type = r != 0 ? r : TREE_ERROR_DIR; - return (t->visit_type); - } -#if defined(USE_READDIR_R) - dirent_size = offsetof(struct dirent, d_name) + - t->filesystem_table[t->current->filesystem_id].name_max + 1; - if (t->dirent == NULL || t->dirent_allocated < dirent_size) { - free(t->dirent); - t->dirent = malloc(dirent_size); - if (t->dirent == NULL) { - closedir(t->d); - t->d = INVALID_DIR_HANDLE; - (void)tree_ascend(t); - tree_pop(t); - t->tree_errno = ENOMEM; - t->visit_type = TREE_ERROR_DIR; - return (t->visit_type); - } - t->dirent_allocated = dirent_size; - } -#endif /* USE_READDIR_R */ - } - for (;;) { - errno = 0; -#if defined(USE_READDIR_R) - r = readdir_r(t->d, t->dirent, &t->de); -#ifdef _AIX - /* Note: According to the man page, return value 9 indicates - * that the readdir_r was not successful and the error code - * is set to the global errno variable. And then if the end - * of directory entries was reached, the return value is 9 - * and the third parameter is set to NULL and errno is - * unchanged. */ - if (r == 9) - r = errno; -#endif /* _AIX */ - if (r != 0 || t->de == NULL) { -#else - t->de = readdir(t->d); - if (t->de == NULL) { - r = errno; -#endif - closedir(t->d); - t->d = INVALID_DIR_HANDLE; - if (r != 0) { - t->tree_errno = r; - t->visit_type = TREE_ERROR_DIR; - return (t->visit_type); - } else - return (0); - } - name = t->de->d_name; - namelen = D_NAMELEN(t->de); - t->flags &= ~hasLstat; - t->flags &= ~hasStat; - if (name[0] == '.' && name[1] == '\0') - continue; - if (name[0] == '.' && name[1] == '.' && name[2] == '\0') - continue; - tree_append(t, name, namelen); - return (t->visit_type = TREE_REGULAR); - } -} - - -/* - * Get the stat() data for the entry just returned from tree_next(). - */ -static const struct stat * -tree_current_stat(struct tree *t) -{ - if (!(t->flags & hasStat)) { -#ifdef HAVE_FSTATAT - if (fstatat(tree_current_dir_fd(t), - tree_current_access_path(t), &t->st, 0) != 0) -#else - if (tree_enter_working_dir(t) != 0) - return NULL; - if (la_stat(tree_current_access_path(t), &t->st) != 0) -#endif - return NULL; - t->flags |= hasStat; - } - return (&t->st); -} - -/* - * Get the lstat() data for the entry just returned from tree_next(). - */ -static const struct stat * -tree_current_lstat(struct tree *t) -{ - if (!(t->flags & hasLstat)) { -#ifdef HAVE_FSTATAT - if (fstatat(tree_current_dir_fd(t), - tree_current_access_path(t), &t->lst, - AT_SYMLINK_NOFOLLOW) != 0) -#else - if (tree_enter_working_dir(t) != 0) - return NULL; -#ifdef HAVE_LSTAT - if (lstat(tree_current_access_path(t), &t->lst) != 0) -#else - if (la_stat(tree_current_access_path(t), &t->lst) != 0) -#endif -#endif - return NULL; - t->flags |= hasLstat; - } - return (&t->lst); -} - -/* - * Test whether current entry is a dir or link to a dir. - */ -static int -tree_current_is_dir(struct tree *t) -{ - const struct stat *st; - /* - * If we already have lstat() info, then try some - * cheap tests to determine if this is a dir. - */ - if (t->flags & hasLstat) { - /* If lstat() says it's a dir, it must be a dir. */ - st = tree_current_lstat(t); - if (st == NULL) - return 0; - if (S_ISDIR(st->st_mode)) - return 1; - /* Not a dir; might be a link to a dir. */ - /* If it's not a link, then it's not a link to a dir. */ - if (!S_ISLNK(st->st_mode)) - return 0; - /* - * It's a link, but we don't know what it's a link to, - * so we'll have to use stat(). - */ - } - - st = tree_current_stat(t); - /* If we can't stat it, it's not a dir. */ - if (st == NULL) - return 0; - /* Use the definitive test. Hopefully this is cached. */ - return (S_ISDIR(st->st_mode)); -} - -/* - * Test whether current entry is a physical directory. Usually, we - * already have at least one of stat() or lstat() in memory, so we - * use tricks to try to avoid an extra trip to the disk. - */ -static int -tree_current_is_physical_dir(struct tree *t) -{ - const struct stat *st; - - /* - * If stat() says it isn't a dir, then it's not a dir. - * If stat() data is cached, this check is free, so do it first. - */ - if (t->flags & hasStat) { - st = tree_current_stat(t); - if (st == NULL) - return (0); - if (!S_ISDIR(st->st_mode)) - return (0); - } - - /* - * Either stat() said it was a dir (in which case, we have - * to determine whether it's really a link to a dir) or - * stat() info wasn't available. So we use lstat(), which - * hopefully is already cached. - */ - - st = tree_current_lstat(t); - /* If we can't stat it, it's not a dir. */ - if (st == NULL) - return 0; - /* Use the definitive test. Hopefully this is cached. */ - return (S_ISDIR(st->st_mode)); -} - -/* - * Test whether the same file has been in the tree as its parent. - */ -static int -tree_target_is_same_as_parent(struct tree *t, const struct stat *st) -{ - struct tree_entry *te; - - for (te = t->current->parent; te != NULL; te = te->parent) { - if (te->dev == (int64_t)st->st_dev && - te->ino == (int64_t)st->st_ino) - return (1); - } - return (0); -} - -/* - * Test whether the current file is symbolic link target and - * on the other filesystem. - */ -static int -tree_current_is_symblic_link_target(struct tree *t) -{ - static const struct stat *lst, *st; - - lst = tree_current_lstat(t); - st = tree_current_stat(t); - return (st != NULL && lst != NULL && - (int64_t)st->st_dev == t->current_filesystem->dev && - st->st_dev != lst->st_dev); -} - -/* - * Return the access path for the entry just returned from tree_next(). - */ -static const char * -tree_current_access_path(struct tree *t) -{ - return (t->basename); -} - -/* - * Return the full path for the entry just returned from tree_next(). - */ -static const char * -tree_current_path(struct tree *t) -{ - return (t->path.s); -} - -/* - * Terminate the traversal. - */ -static void -tree_close(struct tree *t) -{ - - if (t == NULL) - return; - if (t->entry_fd >= 0) { - close_and_restore_time(t->entry_fd, t, &t->restore_time); - t->entry_fd = -1; - } - /* Close the handle of readdir(). */ - if (t->d != INVALID_DIR_HANDLE) { - closedir(t->d); - t->d = INVALID_DIR_HANDLE; - } - /* Release anything remaining in the stack. */ - while (t->stack != NULL) { - if (t->stack->flags & isDirLink) - close(t->stack->symlink_parent_fd); - tree_pop(t); - } - if (t->working_dir_fd >= 0) { - close(t->working_dir_fd); - t->working_dir_fd = -1; - } - if (t->initial_dir_fd >= 0) { - close(t->initial_dir_fd); - t->initial_dir_fd = -1; - } -} - -/* - * Release any resources. - */ -static void -tree_free(struct tree *t) -{ - int i; - - if (t == NULL) - return; - archive_string_free(&t->path); -#if defined(USE_READDIR_R) - free(t->dirent); -#endif - free(t->sparse_list); - for (i = 0; i < t->max_filesystem_id; i++) - free(t->filesystem_table[i].allocation_ptr); - free(t->filesystem_table); - free(t); -} - -#endif diff --git a/thirdparty/libarchive/libarchive/archive_read_disk_private.h b/thirdparty/libarchive/libarchive/archive_read_disk_private.h deleted file mode 100644 index bc8abc15d..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_disk_private.h +++ /dev/null @@ -1,98 +0,0 @@ -/*- - * Copyright (c) 2003-2009 Tim Kientzle - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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: head/lib/libarchive/archive_read_disk_private.h 201105 2009-12-28 03:20:54Z kientzle $ - */ - -#ifndef ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED -#define ARCHIVE_READ_DISK_PRIVATE_H_INCLUDED - -#ifndef __LIBARCHIVE_BUILD -#error This header is only to be used internally to libarchive. -#endif - -#include "archive_platform_acl.h" - -struct tree; -struct archive_entry; - -struct archive_read_disk { - struct archive archive; - - /* Reused by archive_read_next_header() */ - struct archive_entry *entry; - - /* - * Symlink mode is one of 'L'ogical, 'P'hysical, or 'H'ybrid, - * following an old BSD convention. 'L' follows all symlinks, - * 'P' follows none, 'H' follows symlinks only for the first - * item. - */ - char symlink_mode; - - /* - * Since symlink interaction changes, we need to track whether - * we're following symlinks for the current item. 'L' mode above - * sets this true, 'P' sets it false, 'H' changes it as we traverse. - */ - char follow_symlinks; /* Either 'L' or 'P'. */ - - /* Directory traversals. */ - struct tree *tree; - int (*open_on_current_dir)(struct tree*, const char *, int); - int (*tree_current_dir_fd)(struct tree*); - int (*tree_enter_working_dir)(struct tree*); - - /* Bitfield with ARCHIVE_READDISK_* tunables */ - int flags; - - const char * (*lookup_gname)(void *private, int64_t gid); - void (*cleanup_gname)(void *private); - void *lookup_gname_data; - const char * (*lookup_uname)(void *private, int64_t uid); - void (*cleanup_uname)(void *private); - void *lookup_uname_data; - - int (*metadata_filter_func)(struct archive *, void *, - struct archive_entry *); - void *metadata_filter_data; - - /* ARCHIVE_MATCH object. */ - struct archive *matching; - /* Callback function, this will be invoked when ARCHIVE_MATCH - * archive_match_*_excluded_ae return true. */ - void (*excluded_cb_func)(struct archive *, void *, - struct archive_entry *); - void *excluded_cb_data; -}; - -const char * -archive_read_disk_entry_setup_path(struct archive_read_disk *, - struct archive_entry *, int *); - -int -archive_read_disk_entry_setup_acls(struct archive_read_disk *, - struct archive_entry *, int *); -#endif diff --git a/thirdparty/libarchive/libarchive/archive_read_disk_set_standard_lookup.c b/thirdparty/libarchive/libarchive/archive_read_disk_set_standard_lookup.c deleted file mode 100644 index c7fd2471e..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_disk_set_standard_lookup.c +++ /dev/null @@ -1,313 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_disk_set_standard_lookup.c 201109 2009-12-28 03:30:31Z kientzle $"); - -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_GRP_H -#include -#endif -#ifdef HAVE_PWD_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "archive.h" - -#if defined(_WIN32) && !defined(__CYGWIN__) -int -archive_read_disk_set_standard_lookup(struct archive *a) -{ - archive_set_error(a, -1, "Standard lookups not available on Windows"); - return (ARCHIVE_FATAL); -} -#else /* ! (_WIN32 && !__CYGWIN__) */ -#define name_cache_size 127 - -static const char * const NO_NAME = "(noname)"; - -struct name_cache { - struct archive *archive; - char *buff; - size_t buff_size; - int probes; - int hits; - size_t size; - struct { - id_t id; - const char *name; - } cache[name_cache_size]; -}; - -static const char * lookup_gname(void *, int64_t); -static const char * lookup_uname(void *, int64_t); -static void cleanup(void *); -static const char * lookup_gname_helper(struct name_cache *, id_t gid); -static const char * lookup_uname_helper(struct name_cache *, id_t uid); - -/* - * Installs functions that use getpwuid()/getgrgid()---along with - * a simple cache to accelerate such lookups---into the archive_read_disk - * object. This is in a separate file because getpwuid()/getgrgid() - * can pull in a LOT of library code (including NIS/LDAP functions, which - * pull in DNS resolvers, etc). This can easily top 500kB, which makes - * it inappropriate for some space-constrained applications. - * - * Applications that are size-sensitive may want to just use the - * real default functions (defined in archive_read_disk.c) that just - * use the uid/gid without the lookup. Or define your own custom functions - * if you prefer. - */ -int -archive_read_disk_set_standard_lookup(struct archive *a) -{ - struct name_cache *ucache = malloc(sizeof(struct name_cache)); - struct name_cache *gcache = malloc(sizeof(struct name_cache)); - - if (ucache == NULL || gcache == NULL) { - archive_set_error(a, ENOMEM, - "Can't allocate uname/gname lookup cache"); - free(ucache); - free(gcache); - return (ARCHIVE_FATAL); - } - - memset(ucache, 0, sizeof(*ucache)); - ucache->archive = a; - ucache->size = name_cache_size; - memset(gcache, 0, sizeof(*gcache)); - gcache->archive = a; - gcache->size = name_cache_size; - - archive_read_disk_set_gname_lookup(a, gcache, lookup_gname, cleanup); - archive_read_disk_set_uname_lookup(a, ucache, lookup_uname, cleanup); - - return (ARCHIVE_OK); -} - -static void -cleanup(void *data) -{ - struct name_cache *cache = (struct name_cache *)data; - size_t i; - - if (cache != NULL) { - for (i = 0; i < cache->size; i++) { - if (cache->cache[i].name != NULL && - cache->cache[i].name != NO_NAME) - free((void *)(uintptr_t)cache->cache[i].name); - } - free(cache->buff); - free(cache); - } -} - -/* - * Lookup uid/gid from uname/gname, return NULL if no match. - */ -static const char * -lookup_name(struct name_cache *cache, - const char * (*lookup_fn)(struct name_cache *, id_t), id_t id) -{ - const char *name; - int slot; - - - cache->probes++; - - slot = id % cache->size; - if (cache->cache[slot].name != NULL) { - if (cache->cache[slot].id == id) { - cache->hits++; - if (cache->cache[slot].name == NO_NAME) - return (NULL); - return (cache->cache[slot].name); - } - if (cache->cache[slot].name != NO_NAME) - free((void *)(uintptr_t)cache->cache[slot].name); - cache->cache[slot].name = NULL; - } - - name = (lookup_fn)(cache, id); - if (name == NULL) { - /* Cache and return the negative response. */ - cache->cache[slot].name = NO_NAME; - cache->cache[slot].id = id; - return (NULL); - } - - cache->cache[slot].name = name; - cache->cache[slot].id = id; - return (cache->cache[slot].name); -} - -static const char * -lookup_uname(void *data, int64_t uid) -{ - struct name_cache *uname_cache = (struct name_cache *)data; - return (lookup_name(uname_cache, - &lookup_uname_helper, (id_t)uid)); -} - -#if HAVE_GETPWUID_R -static const char * -lookup_uname_helper(struct name_cache *cache, id_t id) -{ - struct passwd pwent, *result; - char * nbuff; - size_t nbuff_size; - int r; - - if (cache->buff_size == 0) { - cache->buff_size = 256; - cache->buff = malloc(cache->buff_size); - } - if (cache->buff == NULL) - return (NULL); - for (;;) { - result = &pwent; /* Old getpwuid_r ignores last arg. */ - r = getpwuid_r((uid_t)id, &pwent, - cache->buff, cache->buff_size, &result); - if (r == 0) - break; - if (r != ERANGE) - break; - /* ERANGE means our buffer was too small, but POSIX - * doesn't tell us how big the buffer should be, so - * we just double it and try again. Because the buffer - * is kept around in the cache object, we shouldn't - * have to do this very often. */ - nbuff_size = cache->buff_size * 2; - nbuff = realloc(cache->buff, nbuff_size); - if (nbuff == NULL) - break; - cache->buff = nbuff; - cache->buff_size = nbuff_size; - } - if (r != 0) { - archive_set_error(cache->archive, errno, - "Can't lookup user for id %d", (int)id); - return (NULL); - } - if (result == NULL) - return (NULL); - - return strdup(result->pw_name); -} -#else -static const char * -lookup_uname_helper(struct name_cache *cache, id_t id) -{ - struct passwd *result; - (void)cache; /* UNUSED */ - - result = getpwuid((uid_t)id); - - if (result == NULL) - return (NULL); - - return strdup(result->pw_name); -} -#endif - -static const char * -lookup_gname(void *data, int64_t gid) -{ - struct name_cache *gname_cache = (struct name_cache *)data; - return (lookup_name(gname_cache, - &lookup_gname_helper, (id_t)gid)); -} - -#if HAVE_GETGRGID_R -static const char * -lookup_gname_helper(struct name_cache *cache, id_t id) -{ - struct group grent, *result; - char * nbuff; - size_t nbuff_size; - int r; - - if (cache->buff_size == 0) { - cache->buff_size = 256; - cache->buff = malloc(cache->buff_size); - } - if (cache->buff == NULL) - return (NULL); - for (;;) { - result = &grent; /* Old getgrgid_r ignores last arg. */ - r = getgrgid_r((gid_t)id, &grent, - cache->buff, cache->buff_size, &result); - if (r == 0) - break; - if (r != ERANGE) - break; - /* ERANGE means our buffer was too small, but POSIX - * doesn't tell us how big the buffer should be, so - * we just double it and try again. */ - nbuff_size = cache->buff_size * 2; - nbuff = realloc(cache->buff, nbuff_size); - if (nbuff == NULL) - break; - cache->buff = nbuff; - cache->buff_size = nbuff_size; - } - if (r != 0) { - archive_set_error(cache->archive, errno, - "Can't lookup group for id %d", (int)id); - return (NULL); - } - if (result == NULL) - return (NULL); - - return strdup(result->gr_name); -} -#else -static const char * -lookup_gname_helper(struct name_cache *cache, id_t id) -{ - struct group *result; - (void)cache; /* UNUSED */ - - result = getgrgid((gid_t)id); - - if (result == NULL) - return (NULL); - - return strdup(result->gr_name); -} -#endif - -#endif /* ! (_WIN32 && !__CYGWIN__) */ diff --git a/thirdparty/libarchive/libarchive/archive_read_disk_windows.c b/thirdparty/libarchive/libarchive/archive_read_disk_windows.c deleted file mode 100644 index f92a78a21..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_disk_windows.c +++ /dev/null @@ -1,2547 +0,0 @@ -/*- - * Copyright (c) 2003-2009 Tim Kientzle - * Copyright (c) 2010-2012 Michihiro NAKAJIMA - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#if defined(_WIN32) && !defined(__CYGWIN__) - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#include - -#include "archive.h" -#include "archive_string.h" -#include "archive_entry.h" -#include "archive_private.h" -#include "archive_read_disk_private.h" - -#ifndef O_BINARY -#define O_BINARY 0 -#endif -#ifndef IO_REPARSE_TAG_SYMLINK -/* Old SDKs do not provide IO_REPARSE_TAG_SYMLINK */ -#define IO_REPARSE_TAG_SYMLINK 0xA000000CL -#endif - -/*- - * This is a new directory-walking system that addresses a number - * of problems I've had with fts(3). In particular, it has no - * pathname-length limits (other than the size of 'int'), handles - * deep logical traversals, uses considerably less memory, and has - * an opaque interface (easier to modify in the future). - * - * Internally, it keeps a single list of "tree_entry" items that - * represent filesystem objects that require further attention. - * Non-directories are not kept in memory: they are pulled from - * readdir(), returned to the client, then freed as soon as possible. - * Any directory entry to be traversed gets pushed onto the stack. - * - * There is surprisingly little information that needs to be kept for - * each item on the stack. Just the name, depth (represented here as the - * string length of the parent directory's pathname), and some markers - * indicating how to get back to the parent (via chdir("..") for a - * regular dir or via fchdir(2) for a symlink). - */ - -struct restore_time { - const wchar_t *full_path; - FILETIME lastWriteTime; - FILETIME lastAccessTime; - mode_t filetype; -}; - -struct tree_entry { - int depth; - struct tree_entry *next; - struct tree_entry *parent; - size_t full_path_dir_length; - struct archive_wstring name; - struct archive_wstring full_path; - size_t dirname_length; - int64_t dev; - int64_t ino; - int flags; - int filesystem_id; - /* How to restore time of a directory. */ - struct restore_time restore_time; -}; - -struct filesystem { - int64_t dev; - int synthetic; - int remote; - DWORD bytesPerSector; -}; - -/* Definitions for tree_entry.flags bitmap. */ -#define isDir 1 /* This entry is a regular directory. */ -#define isDirLink 2 /* This entry is a symbolic link to a directory. */ -#define needsFirstVisit 4 /* This is an initial entry. */ -#define needsDescent 8 /* This entry needs to be previsited. */ -#define needsOpen 16 /* This is a directory that needs to be opened. */ -#define needsAscent 32 /* This entry needs to be postvisited. */ - -/* - * On Windows, "first visit" is handled as a pattern to be handed to - * _findfirst(). This is consistent with Windows conventions that - * file patterns are handled within the application. On Posix, - * "first visit" is just returned to the client. - */ - -#define MAX_OVERLAPPED 8 -#define READ_BUFFER_SIZE (1024 * 64) /* Default to 64KB per https://technet.microsoft.com/en-us/library/cc938632.aspx */ -#define DIRECT_IO 0/* Disabled */ -#define ASYNC_IO 1/* Enabled */ - -/* - * Local data for this package. - */ -struct tree { - struct tree_entry *stack; - struct tree_entry *current; - HANDLE d; - WIN32_FIND_DATAW _findData; - WIN32_FIND_DATAW *findData; - int flags; - int visit_type; - /* Error code from last failed operation. */ - int tree_errno; - - /* A full path with "\\?\" prefix. */ - struct archive_wstring full_path; - size_t full_path_dir_length; - /* Dynamically-sized buffer for holding path */ - struct archive_wstring path; - - /* Last path element */ - const wchar_t *basename; - /* Leading dir length */ - size_t dirname_length; - - int depth; - - BY_HANDLE_FILE_INFORMATION lst; - BY_HANDLE_FILE_INFORMATION st; - int descend; - /* How to restore time of a file. */ - struct restore_time restore_time; - - struct entry_sparse { - int64_t length; - int64_t offset; - } *sparse_list, *current_sparse; - int sparse_count; - int sparse_list_size; - - char initial_symlink_mode; - char symlink_mode; - struct filesystem *current_filesystem; - struct filesystem *filesystem_table; - int initial_filesystem_id; - int current_filesystem_id; - int max_filesystem_id; - int allocated_filesystem; - - HANDLE entry_fh; - int entry_eof; - int64_t entry_remaining_bytes; - int64_t entry_total; - - int ol_idx_doing; - int ol_idx_done; - int ol_num_doing; - int ol_num_done; - int64_t ol_remaining_bytes; - int64_t ol_total; - struct la_overlapped { - OVERLAPPED ol; - struct archive * _a; - unsigned char *buff; - size_t buff_size; - int64_t offset; - size_t bytes_expected; - size_t bytes_transferred; - } ol[MAX_OVERLAPPED]; - int direct_io; - int async_io; -}; - -#define bhfi_dev(bhfi) ((bhfi)->dwVolumeSerialNumber) -/* Treat FileIndex as i-node. We should remove a sequence number - * which is high-16-bits of nFileIndexHigh. */ -#define bhfi_ino(bhfi) \ - ((((int64_t)((bhfi)->nFileIndexHigh & 0x0000FFFFUL)) << 32) \ - + (bhfi)->nFileIndexLow) - -/* Definitions for tree.flags bitmap. */ -#define hasStat 16 /* The st entry is valid. */ -#define hasLstat 32 /* The lst entry is valid. */ -#define needsRestoreTimes 128 - -static int -tree_dir_next_windows(struct tree *t, const wchar_t *pattern); - -/* Initiate/terminate a tree traversal. */ -static struct tree *tree_open(const wchar_t *, int, int); -static struct tree *tree_reopen(struct tree *, const wchar_t *, int); -static void tree_close(struct tree *); -static void tree_free(struct tree *); -static void tree_push(struct tree *, const wchar_t *, const wchar_t *, - int, int64_t, int64_t, struct restore_time *); - -/* - * tree_next() returns Zero if there is no next entry, non-zero if - * there is. Note that directories are visited three times. - * Directories are always visited first as part of enumerating their - * parent; that is a "regular" visit. If tree_descend() is invoked at - * that time, the directory is added to a work list and will - * subsequently be visited two more times: once just after descending - * into the directory ("postdescent") and again just after ascending - * back to the parent ("postascent"). - * - * TREE_ERROR_DIR is returned if the descent failed (because the - * directory couldn't be opened, for instance). This is returned - * instead of TREE_POSTDESCENT/TREE_POSTASCENT. TREE_ERROR_DIR is not a - * fatal error, but it does imply that the relevant subtree won't be - * visited. TREE_ERROR_FATAL is returned for an error that left the - * traversal completely hosed. Right now, this is only returned for - * chdir() failures during ascent. - */ -#define TREE_REGULAR 1 -#define TREE_POSTDESCENT 2 -#define TREE_POSTASCENT 3 -#define TREE_ERROR_DIR -1 -#define TREE_ERROR_FATAL -2 - -static int tree_next(struct tree *); - -/* - * Return information about the current entry. - */ - -/* - * The current full pathname, length of the full pathname, and a name - * that can be used to access the file. Because tree does use chdir - * extensively, the access path is almost never the same as the full - * current path. - * - */ -static const wchar_t *tree_current_path(struct tree *); -static const wchar_t *tree_current_access_path(struct tree *); - -/* - * Request the lstat() or stat() data for the current path. Since the - * tree package needs to do some of this anyway, and caches the - * results, you should take advantage of it here if you need it rather - * than make a redundant stat() or lstat() call of your own. - */ -static const BY_HANDLE_FILE_INFORMATION *tree_current_stat(struct tree *); -static const BY_HANDLE_FILE_INFORMATION *tree_current_lstat(struct tree *); - -/* The following functions use tricks to avoid a certain number of - * stat()/lstat() calls. */ -/* "is_physical_dir" is equivalent to S_ISDIR(tree_current_lstat()->st_mode) */ -static int tree_current_is_physical_dir(struct tree *); -/* "is_physical_link" is equivalent to S_ISLNK(tree_current_lstat()->st_mode) */ -static int tree_current_is_physical_link(struct tree *); -/* Instead of archive_entry_copy_stat for BY_HANDLE_FILE_INFORMATION */ -static void tree_archive_entry_copy_bhfi(struct archive_entry *, - struct tree *, const BY_HANDLE_FILE_INFORMATION *); -/* "is_dir" is equivalent to S_ISDIR(tree_current_stat()->st_mode) */ -static int tree_current_is_dir(struct tree *); -static int update_current_filesystem(struct archive_read_disk *a, - int64_t dev); -static int setup_current_filesystem(struct archive_read_disk *); -static int tree_target_is_same_as_parent(struct tree *, - const BY_HANDLE_FILE_INFORMATION *); - -static int _archive_read_disk_open_w(struct archive *, const wchar_t *); -static int _archive_read_free(struct archive *); -static int _archive_read_close(struct archive *); -static int _archive_read_data_block(struct archive *, - const void **, size_t *, int64_t *); -static int _archive_read_next_header(struct archive *, - struct archive_entry **); -static int _archive_read_next_header2(struct archive *, - struct archive_entry *); -static const char *trivial_lookup_gname(void *, int64_t gid); -static const char *trivial_lookup_uname(void *, int64_t uid); -static int setup_sparse(struct archive_read_disk *, struct archive_entry *); -static int close_and_restore_time(HANDLE, struct tree *, - struct restore_time *); -static int setup_sparse_from_disk(struct archive_read_disk *, - struct archive_entry *, HANDLE); -static int la_linkname_from_handle(HANDLE, wchar_t **, int *); -static int la_linkname_from_pathw(const wchar_t *, wchar_t **, int *); -static void entry_symlink_from_pathw(struct archive_entry *, - const wchar_t *path); - -typedef struct _REPARSE_DATA_BUFFER { - ULONG ReparseTag; - USHORT ReparseDataLength; - USHORT Reserved; - union { - struct { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - ULONG Flags; - WCHAR PathBuffer[1]; - } SymbolicLinkReparseBuffer; - struct { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - WCHAR PathBuffer[1]; - } MountPointReparseBuffer; - struct { - UCHAR DataBuffer[1]; - } GenericReparseBuffer; - } DUMMYUNIONNAME; -} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; - -/* - * Reads the target of a symbolic link - * - * Returns 0 on success and -1 on failure - * outbuf is allocated in the function - */ -static int -la_linkname_from_handle(HANDLE h, wchar_t **linkname, int *linktype) -{ - DWORD inbytes; - REPARSE_DATA_BUFFER *buf; - BY_HANDLE_FILE_INFORMATION st; - size_t len; - BOOL ret; - BYTE *indata; - wchar_t *tbuf; - - ret = GetFileInformationByHandle(h, &st); - if (ret == 0 || - (st.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) == 0) { - return (-1); - } - - indata = malloc(MAXIMUM_REPARSE_DATA_BUFFER_SIZE); - ret = DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, NULL, 0, indata, - 1024, &inbytes, NULL); - if (ret == 0) { - la_dosmaperr(GetLastError()); - free(indata); - return (-1); - } - - buf = (REPARSE_DATA_BUFFER *) indata; - if (buf->ReparseTag != IO_REPARSE_TAG_SYMLINK) { - free(indata); - /* File is not a symbolic link */ - errno = EINVAL; - return (-1); - } - - len = buf->SymbolicLinkReparseBuffer.SubstituteNameLength; - if (len <= 0) { - free(indata); - return (-1); - } - - tbuf = malloc(len + 1 * sizeof(wchar_t)); - if (tbuf == NULL) { - free(indata); - return (-1); - } - - memcpy(tbuf, &((BYTE *)buf->SymbolicLinkReparseBuffer.PathBuffer) - [buf->SymbolicLinkReparseBuffer.SubstituteNameOffset], len); - free(indata); - - tbuf[len / sizeof(wchar_t)] = L'\0'; - - *linkname = tbuf; - - /* - * Translate backslashes to slashes for libarchive internal use - */ - while(*tbuf != L'\0') { - if (*tbuf == L'\\') - *tbuf = L'/'; - tbuf++; - } - - if ((st.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) - *linktype = AE_SYMLINK_TYPE_FILE; - else - *linktype = AE_SYMLINK_TYPE_DIRECTORY; - - return (0); -} - -/* - * Returns AE_SYMLINK_TYPE_FILE, AE_SYMLINK_TYPE_DIRECTORY or -1 on error - */ -static int -la_linkname_from_pathw(const wchar_t *path, wchar_t **outbuf, int *linktype) -{ - HANDLE h; - const DWORD flag = FILE_FLAG_BACKUP_SEMANTICS | - FILE_FLAG_OPEN_REPARSE_POINT; - int ret; - -# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */ - CREATEFILE2_EXTENDED_PARAMETERS createExParams; - ZeroMemory(&createExParams, sizeof(createExParams)); - createExParams.dwSize = sizeof(createExParams); - createExParams.dwFileFlags = flag; - h = CreateFile2(path, 0, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - OPEN_EXISTING, &createExParams); -#else - h = CreateFileW(path, 0, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, - OPEN_EXISTING, flag, NULL); -#endif - if (h == INVALID_HANDLE_VALUE) { - la_dosmaperr(GetLastError()); - return (-1); - } - - ret = la_linkname_from_handle(h, outbuf, linktype); - CloseHandle(h); - - return (ret); -} - -static void -entry_symlink_from_pathw(struct archive_entry *entry, const wchar_t *path) -{ - wchar_t *linkname = NULL; - int ret, linktype; - - ret = la_linkname_from_pathw(path, &linkname, &linktype); - if (ret != 0) - return; - if (linktype >= 0) { - archive_entry_copy_symlink_w(entry, linkname); - archive_entry_set_symlink_type(entry, linktype); - } - free(linkname); - - return; -} - -static const struct archive_vtable -archive_read_disk_vtable = { - .archive_free = _archive_read_free, - .archive_close = _archive_read_close, - .archive_read_data_block = _archive_read_data_block, - .archive_read_next_header = _archive_read_next_header, - .archive_read_next_header2 = _archive_read_next_header2, -}; - -const char * -archive_read_disk_gname(struct archive *_a, la_int64_t gid) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_read_disk_gname")) - return (NULL); - if (a->lookup_gname == NULL) - return (NULL); - return ((*a->lookup_gname)(a->lookup_gname_data, gid)); -} - -const char * -archive_read_disk_uname(struct archive *_a, la_int64_t uid) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_read_disk_uname")) - return (NULL); - if (a->lookup_uname == NULL) - return (NULL); - return ((*a->lookup_uname)(a->lookup_uname_data, uid)); -} - -int -archive_read_disk_set_gname_lookup(struct archive *_a, - void *private_data, - const char * (*lookup_gname)(void *private, la_int64_t gid), - void (*cleanup_gname)(void *private)) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_read_disk_set_gname_lookup"); - - if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL) - (a->cleanup_gname)(a->lookup_gname_data); - - a->lookup_gname = lookup_gname; - a->cleanup_gname = cleanup_gname; - a->lookup_gname_data = private_data; - return (ARCHIVE_OK); -} - -int -archive_read_disk_set_uname_lookup(struct archive *_a, - void *private_data, - const char * (*lookup_uname)(void *private, int64_t uid), - void (*cleanup_uname)(void *private)) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_read_disk_set_uname_lookup"); - - if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL) - (a->cleanup_uname)(a->lookup_uname_data); - - a->lookup_uname = lookup_uname; - a->cleanup_uname = cleanup_uname; - a->lookup_uname_data = private_data; - return (ARCHIVE_OK); -} - -/* - * Create a new archive_read_disk object and initialize it with global state. - */ -struct archive * -archive_read_disk_new(void) -{ - struct archive_read_disk *a; - - a = (struct archive_read_disk *)calloc(1, sizeof(*a)); - if (a == NULL) - return (NULL); - a->archive.magic = ARCHIVE_READ_DISK_MAGIC; - a->archive.state = ARCHIVE_STATE_NEW; - a->archive.vtable = &archive_read_disk_vtable; - a->entry = archive_entry_new2(&a->archive); - a->lookup_uname = trivial_lookup_uname; - a->lookup_gname = trivial_lookup_gname; - a->flags = ARCHIVE_READDISK_MAC_COPYFILE; - return (&a->archive); -} - -static int -_archive_read_free(struct archive *_a) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - int r; - - if (_a == NULL) - return (ARCHIVE_OK); - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_free"); - - if (a->archive.state != ARCHIVE_STATE_CLOSED) - r = _archive_read_close(&a->archive); - else - r = ARCHIVE_OK; - - tree_free(a->tree); - if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL) - (a->cleanup_gname)(a->lookup_gname_data); - if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL) - (a->cleanup_uname)(a->lookup_uname_data); - archive_string_free(&a->archive.error_string); - archive_entry_free(a->entry); - a->archive.magic = 0; - free(a); - return (r); -} - -static int -_archive_read_close(struct archive *_a) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_close"); - - if (a->archive.state != ARCHIVE_STATE_FATAL) - a->archive.state = ARCHIVE_STATE_CLOSED; - - tree_close(a->tree); - - return (ARCHIVE_OK); -} - -static void -setup_symlink_mode(struct archive_read_disk *a, char symlink_mode, - int follow_symlinks) -{ - a->symlink_mode = symlink_mode; - a->follow_symlinks = follow_symlinks; - if (a->tree != NULL) { - a->tree->initial_symlink_mode = a->symlink_mode; - a->tree->symlink_mode = a->symlink_mode; - } -} - -int -archive_read_disk_set_symlink_logical(struct archive *_a) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_logical"); - setup_symlink_mode(a, 'L', 1); - return (ARCHIVE_OK); -} - -int -archive_read_disk_set_symlink_physical(struct archive *_a) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_physical"); - setup_symlink_mode(a, 'P', 0); - return (ARCHIVE_OK); -} - -int -archive_read_disk_set_symlink_hybrid(struct archive *_a) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_hybrid"); - setup_symlink_mode(a, 'H', 1);/* Follow symlinks initially. */ - return (ARCHIVE_OK); -} - -int -archive_read_disk_set_atime_restored(struct archive *_a) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_read_disk_restore_atime"); - a->flags |= ARCHIVE_READDISK_RESTORE_ATIME; - if (a->tree != NULL) - a->tree->flags |= needsRestoreTimes; - return (ARCHIVE_OK); -} - -int -archive_read_disk_set_behavior(struct archive *_a, int flags) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - int r = ARCHIVE_OK; - - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_read_disk_honor_nodump"); - - a->flags = flags; - - if (flags & ARCHIVE_READDISK_RESTORE_ATIME) - r = archive_read_disk_set_atime_restored(_a); - else { - if (a->tree != NULL) - a->tree->flags &= ~needsRestoreTimes; - } - return (r); -} - -/* - * Trivial implementations of gname/uname lookup functions. - * These are normally overridden by the client, but these stub - * versions ensure that we always have something that works. - */ -static const char * -trivial_lookup_gname(void *private_data, int64_t gid) -{ - (void)private_data; /* UNUSED */ - (void)gid; /* UNUSED */ - return (NULL); -} - -static const char * -trivial_lookup_uname(void *private_data, int64_t uid) -{ - (void)private_data; /* UNUSED */ - (void)uid; /* UNUSED */ - return (NULL); -} - -static int64_t -align_num_per_sector(struct tree *t, int64_t size) -{ - int64_t surplus; - - size += t->current_filesystem->bytesPerSector -1; - surplus = size % t->current_filesystem->bytesPerSector; - size -= surplus; - return (size); -} - -static int -start_next_async_read(struct archive_read_disk *a, struct tree *t) -{ - struct la_overlapped *olp; - DWORD buffbytes, rbytes; - - if (t->ol_remaining_bytes == 0) - return (ARCHIVE_EOF); - - olp = &(t->ol[t->ol_idx_doing]); - t->ol_idx_doing = (t->ol_idx_doing + 1) % MAX_OVERLAPPED; - - /* Allocate read buffer. */ - if (olp->buff == NULL) { - void *p; - size_t s = (size_t)align_num_per_sector(t, READ_BUFFER_SIZE); - p = VirtualAlloc(NULL, s, MEM_COMMIT, PAGE_READWRITE); - if (p == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Couldn't allocate memory"); - a->archive.state = ARCHIVE_STATE_FATAL; - return (ARCHIVE_FATAL); - } - olp->buff = p; - olp->buff_size = s; - olp->_a = &a->archive; - olp->ol.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); - if (olp->ol.hEvent == NULL) { - la_dosmaperr(GetLastError()); - archive_set_error(&a->archive, errno, - "CreateEvent failed"); - a->archive.state = ARCHIVE_STATE_FATAL; - return (ARCHIVE_FATAL); - } - } else - ResetEvent(olp->ol.hEvent); - - buffbytes = (DWORD)olp->buff_size; - if (buffbytes > t->current_sparse->length) - buffbytes = (DWORD)t->current_sparse->length; - - /* Skip hole. */ - if (t->current_sparse->offset > t->ol_total) { - t->ol_remaining_bytes -= - t->current_sparse->offset - t->ol_total; - } - - olp->offset = t->current_sparse->offset; - olp->ol.Offset = (DWORD)(olp->offset & 0xffffffff); - olp->ol.OffsetHigh = (DWORD)(olp->offset >> 32); - - if (t->ol_remaining_bytes > buffbytes) { - olp->bytes_expected = buffbytes; - t->ol_remaining_bytes -= buffbytes; - } else { - olp->bytes_expected = (size_t)t->ol_remaining_bytes; - t->ol_remaining_bytes = 0; - } - olp->bytes_transferred = 0; - t->current_sparse->offset += buffbytes; - t->current_sparse->length -= buffbytes; - t->ol_total = t->current_sparse->offset; - if (t->current_sparse->length == 0 && t->ol_remaining_bytes > 0) - t->current_sparse++; - - if (!ReadFile(t->entry_fh, olp->buff, buffbytes, &rbytes, &(olp->ol))) { - DWORD lasterr; - - lasterr = GetLastError(); - if (lasterr == ERROR_HANDLE_EOF) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Reading file truncated"); - a->archive.state = ARCHIVE_STATE_FATAL; - return (ARCHIVE_FATAL); - } else if (lasterr != ERROR_IO_PENDING) { - if (lasterr == ERROR_NO_DATA) - errno = EAGAIN; - else if (lasterr == ERROR_ACCESS_DENIED) - errno = EBADF; - else - la_dosmaperr(lasterr); - archive_set_error(&a->archive, errno, "Read error"); - a->archive.state = ARCHIVE_STATE_FATAL; - return (ARCHIVE_FATAL); - } - } else - olp->bytes_transferred = rbytes; - t->ol_num_doing++; - - return (t->ol_remaining_bytes == 0)? ARCHIVE_EOF: ARCHIVE_OK; -} - -static void -cancel_async(struct tree *t) -{ - if (t->ol_num_doing != t->ol_num_done) { - CancelIo(t->entry_fh); - t->ol_num_doing = t->ol_num_done = 0; - } -} - -static int -_archive_read_data_block(struct archive *_a, const void **buff, - size_t *size, int64_t *offset) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - struct tree *t = a->tree; - struct la_overlapped *olp; - DWORD bytes_transferred; - int r = ARCHIVE_FATAL; - - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA, - "archive_read_data_block"); - - if (t->entry_eof || t->entry_remaining_bytes <= 0) { - r = ARCHIVE_EOF; - goto abort_read_data; - } - - /* - * Make a request to read the file in asynchronous. - */ - if (t->ol_num_doing == 0) { - do { - r = start_next_async_read(a, t); - if (r == ARCHIVE_FATAL) - goto abort_read_data; - if (!t->async_io) - break; - } while (r == ARCHIVE_OK && t->ol_num_doing < MAX_OVERLAPPED); - } else { - if ((r = start_next_async_read(a, t)) == ARCHIVE_FATAL) - goto abort_read_data; - } - - olp = &(t->ol[t->ol_idx_done]); - t->ol_idx_done = (t->ol_idx_done + 1) % MAX_OVERLAPPED; - if (olp->bytes_transferred) - bytes_transferred = (DWORD)olp->bytes_transferred; - else if (!GetOverlappedResult(t->entry_fh, &(olp->ol), - &bytes_transferred, TRUE)) { - la_dosmaperr(GetLastError()); - archive_set_error(&a->archive, errno, - "GetOverlappedResult failed"); - a->archive.state = ARCHIVE_STATE_FATAL; - r = ARCHIVE_FATAL; - goto abort_read_data; - } - t->ol_num_done++; - - if (bytes_transferred == 0 || - olp->bytes_expected != bytes_transferred) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Reading file truncated"); - a->archive.state = ARCHIVE_STATE_FATAL; - r = ARCHIVE_FATAL; - goto abort_read_data; - } - - *buff = olp->buff; - *size = bytes_transferred; - *offset = olp->offset; - if (olp->offset > t->entry_total) - t->entry_remaining_bytes -= olp->offset - t->entry_total; - t->entry_total = olp->offset + *size; - t->entry_remaining_bytes -= *size; - if (t->entry_remaining_bytes == 0) { - /* Close the current file descriptor */ - close_and_restore_time(t->entry_fh, t, &t->restore_time); - t->entry_fh = INVALID_HANDLE_VALUE; - t->entry_eof = 1; - } - return (ARCHIVE_OK); - -abort_read_data: - *buff = NULL; - *size = 0; - *offset = t->entry_total; - if (t->entry_fh != INVALID_HANDLE_VALUE) { - cancel_async(t); - /* Close the current file descriptor */ - close_and_restore_time(t->entry_fh, t, &t->restore_time); - t->entry_fh = INVALID_HANDLE_VALUE; - } - return (r); -} - -static int -next_entry(struct archive_read_disk *a, struct tree *t, - struct archive_entry *entry) -{ - const BY_HANDLE_FILE_INFORMATION *st; - const BY_HANDLE_FILE_INFORMATION *lst; - const char*name; - int descend, r; - - st = NULL; - lst = NULL; - t->descend = 0; - do { - switch (tree_next(t)) { - case TREE_ERROR_FATAL: - archive_set_error(&a->archive, t->tree_errno, - "%ls: Unable to continue traversing directory tree", - tree_current_path(t)); - a->archive.state = ARCHIVE_STATE_FATAL; - return (ARCHIVE_FATAL); - case TREE_ERROR_DIR: - archive_set_error(&a->archive, t->tree_errno, - "%ls: Couldn't visit directory", - tree_current_path(t)); - return (ARCHIVE_FAILED); - case 0: - return (ARCHIVE_EOF); - case TREE_POSTDESCENT: - case TREE_POSTASCENT: - break; - case TREE_REGULAR: - lst = tree_current_lstat(t); - if (lst == NULL) { - archive_set_error(&a->archive, t->tree_errno, - "%ls: Cannot stat", - tree_current_path(t)); - return (ARCHIVE_FAILED); - } - break; - } - } while (lst == NULL); - - archive_entry_copy_pathname_w(entry, tree_current_path(t)); - - /* - * Perform path matching. - */ - if (a->matching) { - r = archive_match_path_excluded(a->matching, entry); - if (r < 0) { - archive_set_error(&(a->archive), errno, - "Failed : %s", archive_error_string(a->matching)); - return (r); - } - if (r) { - if (a->excluded_cb_func) - a->excluded_cb_func(&(a->archive), - a->excluded_cb_data, entry); - return (ARCHIVE_RETRY); - } - } - - /* - * Distinguish 'L'/'P'/'H' symlink following. - */ - switch(t->symlink_mode) { - case 'H': - /* 'H': After the first item, rest like 'P'. */ - t->symlink_mode = 'P'; - /* 'H': First item (from command line) like 'L'. */ - /* FALLTHROUGH */ - case 'L': - /* 'L': Do descend through a symlink to dir. */ - descend = tree_current_is_dir(t); - /* 'L': Follow symlinks to files. */ - a->symlink_mode = 'L'; - a->follow_symlinks = 1; - /* 'L': Archive symlinks as targets, if we can. */ - st = tree_current_stat(t); - if (st != NULL && !tree_target_is_same_as_parent(t, st)) - break; - /* If stat fails, we have a broken symlink; - * in that case, don't follow the link. */ - /* FALLTHROUGH */ - default: - /* 'P': Don't descend through a symlink to dir. */ - descend = tree_current_is_physical_dir(t); - /* 'P': Don't follow symlinks to files. */ - a->symlink_mode = 'P'; - a->follow_symlinks = 0; - /* 'P': Archive symlinks as symlinks. */ - st = lst; - break; - } - - if (update_current_filesystem(a, bhfi_dev(st)) != ARCHIVE_OK) { - a->archive.state = ARCHIVE_STATE_FATAL; - return (ARCHIVE_FATAL); - } - if (t->initial_filesystem_id == -1) - t->initial_filesystem_id = t->current_filesystem_id; - if (a->flags & ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS) { - if (t->initial_filesystem_id != t->current_filesystem_id) - return (ARCHIVE_RETRY); - } - t->descend = descend; - - tree_archive_entry_copy_bhfi(entry, t, st); - - /* Save the times to be restored. This must be in before - * calling archive_read_disk_descend() or any chance of it, - * especially, invoking a callback. */ - t->restore_time.lastWriteTime = st->ftLastWriteTime; - t->restore_time.lastAccessTime = st->ftLastAccessTime; - t->restore_time.filetype = archive_entry_filetype(entry); - - /* - * Perform time matching. - */ - if (a->matching) { - r = archive_match_time_excluded(a->matching, entry); - if (r < 0) { - archive_set_error(&(a->archive), errno, - "Failed : %s", archive_error_string(a->matching)); - return (r); - } - if (r) { - if (a->excluded_cb_func) - a->excluded_cb_func(&(a->archive), - a->excluded_cb_data, entry); - return (ARCHIVE_RETRY); - } - } - - /* Lookup uname/gname */ - name = archive_read_disk_uname(&(a->archive), archive_entry_uid(entry)); - if (name != NULL) - archive_entry_copy_uname(entry, name); - name = archive_read_disk_gname(&(a->archive), archive_entry_gid(entry)); - if (name != NULL) - archive_entry_copy_gname(entry, name); - - /* - * Perform owner matching. - */ - if (a->matching) { - r = archive_match_owner_excluded(a->matching, entry); - if (r < 0) { - archive_set_error(&(a->archive), errno, - "Failed : %s", archive_error_string(a->matching)); - return (r); - } - if (r) { - if (a->excluded_cb_func) - a->excluded_cb_func(&(a->archive), - a->excluded_cb_data, entry); - return (ARCHIVE_RETRY); - } - } - - /* - * File attributes - */ - if ((a->flags & ARCHIVE_READDISK_NO_FFLAGS) == 0) { - const int supported_attrs = - FILE_ATTRIBUTE_READONLY | - FILE_ATTRIBUTE_HIDDEN | - FILE_ATTRIBUTE_SYSTEM; - DWORD file_attrs = st->dwFileAttributes & supported_attrs; - if (file_attrs != 0) - archive_entry_set_fflags(entry, file_attrs, 0); - } - - /* - * Invoke a meta data filter callback. - */ - if (a->metadata_filter_func) { - if (!a->metadata_filter_func(&(a->archive), - a->metadata_filter_data, entry)) - return (ARCHIVE_RETRY); - } - - archive_entry_copy_sourcepath_w(entry, tree_current_access_path(t)); - - r = ARCHIVE_OK; - if (archive_entry_filetype(entry) == AE_IFREG && - archive_entry_size(entry) > 0) { - DWORD flags = FILE_FLAG_BACKUP_SEMANTICS; -#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */ - CREATEFILE2_EXTENDED_PARAMETERS createExParams; -#endif - if (t->async_io) - flags |= FILE_FLAG_OVERLAPPED; - if (t->direct_io) - flags |= FILE_FLAG_NO_BUFFERING; - else - flags |= FILE_FLAG_SEQUENTIAL_SCAN; -#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */ - ZeroMemory(&createExParams, sizeof(createExParams)); - createExParams.dwSize = sizeof(createExParams); - createExParams.dwFileFlags = flags; - t->entry_fh = CreateFile2(tree_current_access_path(t), - GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - OPEN_EXISTING, &createExParams); -#else - t->entry_fh = CreateFileW(tree_current_access_path(t), - GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, OPEN_EXISTING, flags, NULL); -#endif - if (t->entry_fh == INVALID_HANDLE_VALUE) { - la_dosmaperr(GetLastError()); - archive_set_error(&a->archive, errno, - "Couldn't open %ls", tree_current_path(a->tree)); - return (ARCHIVE_FAILED); - } - - /* Find sparse data from the disk. */ - if ((a->flags & ARCHIVE_READDISK_NO_SPARSE) == 0) { - if (archive_entry_hardlink(entry) == NULL && - (st->dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) != 0) - r = setup_sparse_from_disk(a, entry, t->entry_fh); - } - } - return (r); -} - -static int -_archive_read_next_header(struct archive *_a, struct archive_entry **entryp) -{ - int ret; - struct archive_read_disk *a = (struct archive_read_disk *)_a; - *entryp = NULL; - ret = _archive_read_next_header2(_a, a->entry); - *entryp = a->entry; - return ret; -} - -static int -_archive_read_next_header2(struct archive *_a, struct archive_entry *entry) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - struct tree *t; - int r; - - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, - "archive_read_next_header2"); - - t = a->tree; - if (t->entry_fh != INVALID_HANDLE_VALUE) { - cancel_async(t); - close_and_restore_time(t->entry_fh, t, &t->restore_time); - t->entry_fh = INVALID_HANDLE_VALUE; - } - - archive_entry_clear(entry); - - while ((r = next_entry(a, t, entry)) == ARCHIVE_RETRY) - archive_entry_clear(entry); - - /* - * EOF and FATAL are persistent at this layer. By - * modifying the state, we guarantee that future calls to - * read a header or read data will fail. - */ - switch (r) { - case ARCHIVE_EOF: - a->archive.state = ARCHIVE_STATE_EOF; - break; - case ARCHIVE_OK: - case ARCHIVE_WARN: - t->entry_total = 0; - if (archive_entry_filetype(entry) == AE_IFREG) { - t->entry_remaining_bytes = archive_entry_size(entry); - t->entry_eof = (t->entry_remaining_bytes == 0)? 1: 0; - if (!t->entry_eof && - setup_sparse(a, entry) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } else { - t->entry_remaining_bytes = 0; - t->entry_eof = 1; - } - t->ol_idx_doing = t->ol_idx_done = 0; - t->ol_num_doing = t->ol_num_done = 0; - t->ol_remaining_bytes = t->entry_remaining_bytes; - t->ol_total = 0; - a->archive.state = ARCHIVE_STATE_DATA; - break; - case ARCHIVE_RETRY: - break; - case ARCHIVE_FATAL: - a->archive.state = ARCHIVE_STATE_FATAL; - break; - } - - __archive_reset_read_data(&a->archive); - return (r); -} - -static int -setup_sparse(struct archive_read_disk *a, struct archive_entry *entry) -{ - struct tree *t = a->tree; - int64_t aligned, length, offset; - int i; - - t->sparse_count = archive_entry_sparse_reset(entry); - if (t->sparse_count+1 > t->sparse_list_size) { - free(t->sparse_list); - t->sparse_list_size = t->sparse_count + 1; - t->sparse_list = malloc(sizeof(t->sparse_list[0]) * - t->sparse_list_size); - if (t->sparse_list == NULL) { - t->sparse_list_size = 0; - archive_set_error(&a->archive, ENOMEM, - "Can't allocate data"); - a->archive.state = ARCHIVE_STATE_FATAL; - return (ARCHIVE_FATAL); - } - } - /* - * Get sparse list and make sure those offsets and lengths are - * aligned by a sector size. - */ - for (i = 0; i < t->sparse_count; i++) { - archive_entry_sparse_next(entry, &offset, &length); - aligned = align_num_per_sector(t, offset); - if (aligned != offset) { - aligned -= t->current_filesystem->bytesPerSector; - length += offset - aligned; - } - t->sparse_list[i].offset = aligned; - aligned = align_num_per_sector(t, length); - t->sparse_list[i].length = aligned; - } - - aligned = align_num_per_sector(t, archive_entry_size(entry)); - if (i == 0) { - t->sparse_list[i].offset = 0; - t->sparse_list[i].length = aligned; - } else { - int j, last = i; - - t->sparse_list[i].offset = aligned; - t->sparse_list[i].length = 0; - for (i = 0; i < last; i++) { - if ((t->sparse_list[i].offset + - t->sparse_list[i].length) <= - t->sparse_list[i+1].offset) - continue; - /* - * Now sparse_list[i+1] is overlapped by sparse_list[i]. - * Merge those two. - */ - length = t->sparse_list[i+1].offset - - t->sparse_list[i].offset; - t->sparse_list[i+1].offset = t->sparse_list[i].offset; - t->sparse_list[i+1].length += length; - /* Remove sparse_list[i]. */ - for (j = i; j < last; j++) { - t->sparse_list[j].offset = - t->sparse_list[j+1].offset; - t->sparse_list[j].length = - t->sparse_list[j+1].length; - } - last--; - } - } - t->current_sparse = t->sparse_list; - - return (ARCHIVE_OK); -} - -int -archive_read_disk_set_matching(struct archive *_a, struct archive *_ma, - void (*_excluded_func)(struct archive *, void *, struct archive_entry *), - void *_client_data) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_read_disk_set_matching"); - a->matching = _ma; - a->excluded_cb_func = _excluded_func; - a->excluded_cb_data = _client_data; - return (ARCHIVE_OK); -} - -int -archive_read_disk_set_metadata_filter_callback(struct archive *_a, - int (*_metadata_filter_func)(struct archive *, void *, - struct archive_entry *), void *_client_data) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_ANY, - "archive_read_disk_set_metadata_filter_callback"); - - a->metadata_filter_func = _metadata_filter_func; - a->metadata_filter_data = _client_data; - return (ARCHIVE_OK); -} - -int -archive_read_disk_can_descend(struct archive *_a) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - struct tree *t = a->tree; - - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, - "archive_read_disk_can_descend"); - - return (t->visit_type == TREE_REGULAR && t->descend); -} - -/* - * Called by the client to mark the directory just returned from - * tree_next() as needing to be visited. - */ -int -archive_read_disk_descend(struct archive *_a) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - struct tree *t = a->tree; - - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, - "archive_read_disk_descend"); - - if (!archive_read_disk_can_descend(_a)) - return (ARCHIVE_OK); - - if (tree_current_is_physical_dir(t)) { - tree_push(t, t->basename, t->full_path.s, - t->current_filesystem_id, - bhfi_dev(&(t->lst)), bhfi_ino(&(t->lst)), - &t->restore_time); - t->stack->flags |= isDir; - } else if (tree_current_is_dir(t)) { - tree_push(t, t->basename, t->full_path.s, - t->current_filesystem_id, - bhfi_dev(&(t->st)), bhfi_ino(&(t->st)), - &t->restore_time); - t->stack->flags |= isDirLink; - } - t->descend = 0; - return (ARCHIVE_OK); -} - -int -archive_read_disk_open(struct archive *_a, const char *pathname) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - struct archive_wstring wpath; - int ret; - - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED, - "archive_read_disk_open"); - archive_clear_error(&a->archive); - - /* Make a wchar_t string from a char string. */ - archive_string_init(&wpath); - if (archive_wstring_append_from_mbs(&wpath, pathname, - strlen(pathname)) != 0) { - if (errno == ENOMEM) - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - else - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Can't convert a path to a wchar_t string"); - a->archive.state = ARCHIVE_STATE_FATAL; - ret = ARCHIVE_FATAL; - } else - ret = _archive_read_disk_open_w(_a, wpath.s); - - archive_wstring_free(&wpath); - return (ret); -} - -int -archive_read_disk_open_w(struct archive *_a, const wchar_t *pathname) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, - ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED, - "archive_read_disk_open_w"); - archive_clear_error(&a->archive); - - return (_archive_read_disk_open_w(_a, pathname)); -} - -static int -_archive_read_disk_open_w(struct archive *_a, const wchar_t *pathname) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - - if (a->tree != NULL) - a->tree = tree_reopen(a->tree, pathname, - a->flags & ARCHIVE_READDISK_RESTORE_ATIME); - else - a->tree = tree_open(pathname, a->symlink_mode, - a->flags & ARCHIVE_READDISK_RESTORE_ATIME); - if (a->tree == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate directory traversal data"); - a->archive.state = ARCHIVE_STATE_FATAL; - return (ARCHIVE_FATAL); - } - a->archive.state = ARCHIVE_STATE_HEADER; - - return (ARCHIVE_OK); -} - -/* - * Return a current filesystem ID which is index of the filesystem entry - * you've visited through archive_read_disk. - */ -int -archive_read_disk_current_filesystem(struct archive *_a) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA, - "archive_read_disk_current_filesystem"); - - return (a->tree->current_filesystem_id); -} - -static int -update_current_filesystem(struct archive_read_disk *a, int64_t dev) -{ - struct tree *t = a->tree; - int i, fid; - - if (t->current_filesystem != NULL && - t->current_filesystem->dev == dev) - return (ARCHIVE_OK); - - for (i = 0; i < t->max_filesystem_id; i++) { - if (t->filesystem_table[i].dev == dev) { - /* There is the filesystem ID we've already generated. */ - t->current_filesystem_id = i; - t->current_filesystem = &(t->filesystem_table[i]); - return (ARCHIVE_OK); - } - } - - /* - * There is a new filesystem, we generate a new ID for. - */ - fid = t->max_filesystem_id++; - if (t->max_filesystem_id > t->allocated_filesystem) { - size_t s; - void *p; - - s = t->max_filesystem_id * 2; - p = realloc(t->filesystem_table, - s * sizeof(*t->filesystem_table)); - if (p == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate tar data"); - return (ARCHIVE_FATAL); - } - t->filesystem_table = (struct filesystem *)p; - t->allocated_filesystem = (int)s; - } - t->current_filesystem_id = fid; - t->current_filesystem = &(t->filesystem_table[fid]); - t->current_filesystem->dev = dev; - - return (setup_current_filesystem(a)); -} - -/* - * Returns 1 if current filesystem is generated filesystem, 0 if it is not - * or -1 if it is unknown. - */ -int -archive_read_disk_current_filesystem_is_synthetic(struct archive *_a) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA, - "archive_read_disk_current_filesystem"); - - return (a->tree->current_filesystem->synthetic); -} - -/* - * Returns 1 if current filesystem is remote filesystem, 0 if it is not - * or -1 if it is unknown. - */ -int -archive_read_disk_current_filesystem_is_remote(struct archive *_a) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - - archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA, - "archive_read_disk_current_filesystem"); - - return (a->tree->current_filesystem->remote); -} - -/* - * If symlink is broken, statfs or statvfs will fail. - * Use its directory path instead. - */ -static wchar_t * -safe_path_for_statfs(struct tree *t) -{ - const wchar_t *path; - wchar_t *cp, *p = NULL; - - path = tree_current_access_path(t); - if (tree_current_stat(t) == NULL) { - p = _wcsdup(path); - cp = wcsrchr(p, '/'); - if (cp != NULL && wcslen(cp) >= 2) { - cp[1] = '.'; - cp[2] = '\0'; - path = p; - } - } else - p = _wcsdup(path); - return (p); -} - -/* - * Get conditions of synthetic and remote on Windows - */ -static int -setup_current_filesystem(struct archive_read_disk *a) -{ - struct tree *t = a->tree; - wchar_t vol[256]; - wchar_t *path; - - t->current_filesystem->synthetic = -1;/* Not supported */ - path = safe_path_for_statfs(t); - if (!GetVolumePathNameW(path, vol, sizeof(vol)/sizeof(vol[0]))) { - free(path); - t->current_filesystem->remote = -1; - t->current_filesystem->bytesPerSector = 0; - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "GetVolumePathName failed: %d", (int)GetLastError()); - return (ARCHIVE_FAILED); - } - free(path); - switch (GetDriveTypeW(vol)) { - case DRIVE_UNKNOWN: - case DRIVE_NO_ROOT_DIR: - t->current_filesystem->remote = -1; - break; - case DRIVE_REMOTE: - t->current_filesystem->remote = 1; - break; - default: - t->current_filesystem->remote = 0; - break; - } - - if (!GetDiskFreeSpaceW(vol, NULL, - &(t->current_filesystem->bytesPerSector), NULL, NULL)) { - t->current_filesystem->bytesPerSector = 0; - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "GetDiskFreeSpace failed: %d", (int)GetLastError()); - return (ARCHIVE_FAILED); - } - - return (ARCHIVE_OK); -} - -static int -close_and_restore_time(HANDLE h, struct tree *t, struct restore_time *rt) -{ - HANDLE handle; - int r = 0; -#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */ - CREATEFILE2_EXTENDED_PARAMETERS createExParams; -#endif - - if (h == INVALID_HANDLE_VALUE && AE_IFLNK == rt->filetype) - return (0); - - /* Close a file descriptor. - * It will not be used for SetFileTime() because it has been opened - * by a read only mode. - */ - if (h != INVALID_HANDLE_VALUE) - CloseHandle(h); - if ((t->flags & needsRestoreTimes) == 0) - return (r); - -#if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */ - ZeroMemory(&createExParams, sizeof(createExParams)); - createExParams.dwSize = sizeof(createExParams); - createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS; - handle = CreateFile2(rt->full_path, FILE_WRITE_ATTRIBUTES, - 0, OPEN_EXISTING, &createExParams); -#else - handle = CreateFileW(rt->full_path, FILE_WRITE_ATTRIBUTES, - 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); -#endif - if (handle == INVALID_HANDLE_VALUE) { - errno = EINVAL; - return (-1); - } - - if (SetFileTime(handle, NULL, &rt->lastAccessTime, - &rt->lastWriteTime) == 0) { - errno = EINVAL; - r = -1; - } else - r = 0; - CloseHandle(handle); - return (r); -} - -/* - * Add a directory path to the current stack. - */ -static void -tree_push(struct tree *t, const wchar_t *path, const wchar_t *full_path, - int filesystem_id, int64_t dev, int64_t ino, struct restore_time *rt) -{ - struct tree_entry *te; - - te = calloc(1, sizeof(*te)); - te->next = t->stack; - te->parent = t->current; - if (te->parent) - te->depth = te->parent->depth + 1; - t->stack = te; - archive_string_init(&te->name); - archive_wstrcpy(&te->name, path); - archive_string_init(&te->full_path); - archive_wstrcpy(&te->full_path, full_path); - te->flags = needsDescent | needsOpen | needsAscent; - te->filesystem_id = filesystem_id; - te->dev = dev; - te->ino = ino; - te->dirname_length = t->dirname_length; - te->full_path_dir_length = t->full_path_dir_length; - te->restore_time.full_path = te->full_path.s; - if (rt != NULL) { - te->restore_time.lastWriteTime = rt->lastWriteTime; - te->restore_time.lastAccessTime = rt->lastAccessTime; - te->restore_time.filetype = rt->filetype; - } -} - -/* - * Append a name to the current dir path. - */ -static void -tree_append(struct tree *t, const wchar_t *name, size_t name_length) -{ - size_t size_needed; - - t->path.s[t->dirname_length] = L'\0'; - t->path.length = t->dirname_length; - /* Strip trailing '/' from name, unless entire name is "/". */ - while (name_length > 1 && name[name_length - 1] == L'/') - name_length--; - - /* Resize pathname buffer as needed. */ - size_needed = name_length + t->dirname_length + 2; - archive_wstring_ensure(&t->path, size_needed); - /* Add a separating '/' if it's needed. */ - if (t->dirname_length > 0 && - t->path.s[archive_strlen(&t->path)-1] != L'/') - archive_wstrappend_wchar(&t->path, L'/'); - t->basename = t->path.s + archive_strlen(&t->path); - archive_wstrncat(&t->path, name, name_length); - t->restore_time.full_path = t->basename; - if (t->full_path_dir_length > 0) { - t->full_path.s[t->full_path_dir_length] = L'\0'; - t->full_path.length = t->full_path_dir_length; - size_needed = name_length + t->full_path_dir_length + 2; - archive_wstring_ensure(&t->full_path, size_needed); - /* Add a separating '\' if it's needed. */ - if (t->full_path.s[archive_strlen(&t->full_path)-1] != L'\\') - archive_wstrappend_wchar(&t->full_path, L'\\'); - archive_wstrncat(&t->full_path, name, name_length); - t->restore_time.full_path = t->full_path.s; - } -} - -/* - * Open a directory tree for traversal. - */ -static struct tree * -tree_open(const wchar_t *path, int symlink_mode, int restore_time) -{ - struct tree *t; - - t = calloc(1, sizeof(*t)); - archive_string_init(&(t->full_path)); - archive_string_init(&t->path); - archive_wstring_ensure(&t->path, 15); - t->initial_symlink_mode = symlink_mode; - return (tree_reopen(t, path, restore_time)); -} - -static struct tree * -tree_reopen(struct tree *t, const wchar_t *path, int restore_time) -{ - struct archive_wstring ws; - wchar_t *pathname, *p, *base; - - t->flags = (restore_time != 0)?needsRestoreTimes:0; - t->visit_type = 0; - t->tree_errno = 0; - t->full_path_dir_length = 0; - t->dirname_length = 0; - t->depth = 0; - t->descend = 0; - t->current = NULL; - t->d = INVALID_HANDLE_VALUE; - t->symlink_mode = t->initial_symlink_mode; - archive_string_empty(&(t->full_path)); - archive_string_empty(&t->path); - t->entry_fh = INVALID_HANDLE_VALUE; - t->entry_eof = 0; - t->entry_remaining_bytes = 0; - t->initial_filesystem_id = -1; - - /* Get wchar_t strings from char strings. */ - archive_string_init(&ws); - archive_wstrcpy(&ws, path); - pathname = ws.s; - /* Get a full-path-name. */ - p = __la_win_permissive_name_w(pathname); - if (p == NULL) - goto failed; - archive_wstrcpy(&(t->full_path), p); - free(p); - - /* Convert path separators from '\' to '/' */ - for (p = pathname; *p != L'\0'; ++p) { - if (*p == L'\\') - *p = L'/'; - } - base = pathname; - - /* First item is set up a lot like a symlink traversal. */ - /* printf("Looking for wildcard in %s\n", path); */ - if ((base[0] == L'/' && base[1] == L'/' && - base[2] == L'?' && base[3] == L'/' && - (wcschr(base+4, L'*') || wcschr(base+4, L'?'))) || - (!(base[0] == L'/' && base[1] == L'/' && - base[2] == L'?' && base[3] == L'/') && - (wcschr(base, L'*') || wcschr(base, L'?')))) { - // It has a wildcard in it... - // Separate the last element. - p = wcsrchr(base, L'/'); - if (p != NULL) { - *p = L'\0'; - tree_append(t, base, p - base); - t->dirname_length = archive_strlen(&t->path); - base = p + 1; - } - p = wcsrchr(t->full_path.s, L'\\'); - if (p != NULL) { - *p = L'\0'; - t->full_path.length = wcslen(t->full_path.s); - t->full_path_dir_length = archive_strlen(&t->full_path); - } - } - tree_push(t, base, t->full_path.s, 0, 0, 0, NULL); - archive_wstring_free(&ws); - t->stack->flags = needsFirstVisit; - /* - * Debug flag for Direct IO(No buffering) or Async IO. - * Those dependent on environment variable switches - * will be removed until next release. - */ - { - const char *e; - if ((e = getenv("LIBARCHIVE_DIRECT_IO")) != NULL) { - if (e[0] == '0') - t->direct_io = 0; - else - t->direct_io = 1; - fprintf(stderr, "LIBARCHIVE_DIRECT_IO=%s\n", - (t->direct_io)?"Enabled":"Disabled"); - } else - t->direct_io = DIRECT_IO; - if ((e = getenv("LIBARCHIVE_ASYNC_IO")) != NULL) { - if (e[0] == '0') - t->async_io = 0; - else - t->async_io = 1; - fprintf(stderr, "LIBARCHIVE_ASYNC_IO=%s\n", - (t->async_io)?"Enabled":"Disabled"); - } else - t->async_io = ASYNC_IO; - } - return (t); -failed: - archive_wstring_free(&ws); - tree_free(t); - return (NULL); -} - -static int -tree_descent(struct tree *t) -{ - t->dirname_length = archive_strlen(&t->path); - t->full_path_dir_length = archive_strlen(&t->full_path); - t->depth++; - return (0); -} - -/* - * We've finished a directory; ascend back to the parent. - */ -static int -tree_ascend(struct tree *t) -{ - struct tree_entry *te; - - te = t->stack; - t->depth--; - close_and_restore_time(INVALID_HANDLE_VALUE, t, &te->restore_time); - return (0); -} - -/* - * Pop the working stack. - */ -static void -tree_pop(struct tree *t) -{ - struct tree_entry *te; - - t->full_path.s[t->full_path_dir_length] = L'\0'; - t->full_path.length = t->full_path_dir_length; - t->path.s[t->dirname_length] = L'\0'; - t->path.length = t->dirname_length; - if (t->stack == t->current && t->current != NULL) - t->current = t->current->parent; - te = t->stack; - t->stack = te->next; - t->dirname_length = te->dirname_length; - t->basename = t->path.s + t->dirname_length; - t->full_path_dir_length = te->full_path_dir_length; - while (t->basename[0] == L'/') - t->basename++; - archive_wstring_free(&te->name); - archive_wstring_free(&te->full_path); - free(te); -} - -/* - * Get the next item in the tree traversal. - */ -static int -tree_next(struct tree *t) -{ - int r; - - while (t->stack != NULL) { - /* If there's an open dir, get the next entry from there. */ - if (t->d != INVALID_HANDLE_VALUE) { - r = tree_dir_next_windows(t, NULL); - if (r == 0) - continue; - return (r); - } - - if (t->stack->flags & needsFirstVisit) { - wchar_t *d = t->stack->name.s; - t->stack->flags &= ~needsFirstVisit; - if (!(d[0] == L'/' && d[1] == L'/' && - d[2] == L'?' && d[3] == L'/') && - (wcschr(d, L'*') || wcschr(d, L'?'))) { - r = tree_dir_next_windows(t, d); - if (r == 0) - continue; - return (r); - } else { - HANDLE h = FindFirstFileW(t->stack->full_path.s, &t->_findData); - if (h == INVALID_HANDLE_VALUE) { - la_dosmaperr(GetLastError()); - t->tree_errno = errno; - t->visit_type = TREE_ERROR_DIR; - return (t->visit_type); - } - t->findData = &t->_findData; - FindClose(h); - } - /* Top stack item needs a regular visit. */ - t->current = t->stack; - tree_append(t, t->stack->name.s, - archive_strlen(&(t->stack->name))); - //t->dirname_length = t->path_length; - //tree_pop(t); - t->stack->flags &= ~needsFirstVisit; - return (t->visit_type = TREE_REGULAR); - } else if (t->stack->flags & needsDescent) { - /* Top stack item is dir to descend into. */ - t->current = t->stack; - tree_append(t, t->stack->name.s, - archive_strlen(&(t->stack->name))); - t->stack->flags &= ~needsDescent; - r = tree_descent(t); - if (r != 0) { - tree_pop(t); - t->visit_type = r; - } else - t->visit_type = TREE_POSTDESCENT; - return (t->visit_type); - } else if (t->stack->flags & needsOpen) { - t->stack->flags &= ~needsOpen; - r = tree_dir_next_windows(t, L"*"); - if (r == 0) - continue; - return (r); - } else if (t->stack->flags & needsAscent) { - /* Top stack item is dir and we're done with it. */ - r = tree_ascend(t); - tree_pop(t); - t->visit_type = r != 0 ? r : TREE_POSTASCENT; - return (t->visit_type); - } else { - /* Top item on stack is dead. */ - tree_pop(t); - t->flags &= ~hasLstat; - t->flags &= ~hasStat; - } - } - return (t->visit_type = 0); -} - -static int -tree_dir_next_windows(struct tree *t, const wchar_t *pattern) -{ - const wchar_t *name; - size_t namelen; - int r; - - for (;;) { - if (pattern != NULL) { - struct archive_wstring pt; - - archive_string_init(&pt); - archive_wstring_ensure(&pt, - archive_strlen(&(t->full_path)) - + 2 + wcslen(pattern)); - archive_wstring_copy(&pt, &(t->full_path)); - archive_wstrappend_wchar(&pt, L'\\'); - archive_wstrcat(&pt, pattern); - t->d = FindFirstFileW(pt.s, &t->_findData); - archive_wstring_free(&pt); - if (t->d == INVALID_HANDLE_VALUE) { - la_dosmaperr(GetLastError()); - t->tree_errno = errno; - r = tree_ascend(t); /* Undo "chdir" */ - tree_pop(t); - t->visit_type = r != 0 ? r : TREE_ERROR_DIR; - return (t->visit_type); - } - t->findData = &t->_findData; - pattern = NULL; - } else if (!FindNextFileW(t->d, &t->_findData)) { - FindClose(t->d); - t->d = INVALID_HANDLE_VALUE; - t->findData = NULL; - return (0); - } - name = t->findData->cFileName; - namelen = wcslen(name); - t->flags &= ~hasLstat; - t->flags &= ~hasStat; - if (name[0] == L'.' && name[1] == L'\0') - continue; - if (name[0] == L'.' && name[1] == L'.' && name[2] == L'\0') - continue; - tree_append(t, name, namelen); - return (t->visit_type = TREE_REGULAR); - } -} - -#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000) -static void -fileTimeToUtc(const FILETIME *filetime, time_t *t, long *ns) -{ - ULARGE_INTEGER utc; - - utc.HighPart = filetime->dwHighDateTime; - utc.LowPart = filetime->dwLowDateTime; - if (utc.QuadPart >= EPOC_TIME) { - utc.QuadPart -= EPOC_TIME; - /* milli seconds base */ - *t = (time_t)(utc.QuadPart / 10000000); - /* nano seconds base */ - *ns = (long)(utc.QuadPart % 10000000) * 100; - } else { - *t = 0; - *ns = 0; - } -} - -static void -entry_copy_bhfi(struct archive_entry *entry, const wchar_t *path, - const WIN32_FIND_DATAW *findData, - const BY_HANDLE_FILE_INFORMATION *bhfi) -{ - time_t secs; - long nsecs; - mode_t mode; - - fileTimeToUtc(&bhfi->ftLastAccessTime, &secs, &nsecs); - archive_entry_set_atime(entry, secs, nsecs); - fileTimeToUtc(&bhfi->ftLastWriteTime, &secs, &nsecs); - archive_entry_set_mtime(entry, secs, nsecs); - fileTimeToUtc(&bhfi->ftCreationTime, &secs, &nsecs); - archive_entry_set_birthtime(entry, secs, nsecs); - archive_entry_set_ctime(entry, secs, nsecs); - archive_entry_set_dev(entry, bhfi_dev(bhfi)); - archive_entry_set_ino64(entry, bhfi_ino(bhfi)); - if (bhfi->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - archive_entry_set_nlink(entry, bhfi->nNumberOfLinks + 1); - else - archive_entry_set_nlink(entry, bhfi->nNumberOfLinks); - archive_entry_set_size(entry, - (((int64_t)bhfi->nFileSizeHigh) << 32) - + bhfi->nFileSizeLow); - archive_entry_set_uid(entry, 0); - archive_entry_set_gid(entry, 0); - archive_entry_set_rdev(entry, 0); - - mode = S_IRUSR | S_IRGRP | S_IROTH; - if ((bhfi->dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0) - mode |= S_IWUSR | S_IWGRP | S_IWOTH; - if ((bhfi->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) && - findData != NULL && - findData->dwReserved0 == IO_REPARSE_TAG_SYMLINK) { - mode |= S_IFLNK; - entry_symlink_from_pathw(entry, path); - } else if (bhfi->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH; - else { - const wchar_t *p; - - mode |= S_IFREG; - p = wcsrchr(path, L'.'); - if (p != NULL && wcslen(p) == 4) { - switch (p[1]) { - case L'B': case L'b': - if ((p[2] == L'A' || p[2] == L'a' ) && - (p[3] == L'T' || p[3] == L't' )) - mode |= S_IXUSR | S_IXGRP | S_IXOTH; - break; - case L'C': case L'c': - if (((p[2] == L'M' || p[2] == L'm' ) && - (p[3] == L'D' || p[3] == L'd' ))) - mode |= S_IXUSR | S_IXGRP | S_IXOTH; - break; - case L'E': case L'e': - if ((p[2] == L'X' || p[2] == L'x' ) && - (p[3] == L'E' || p[3] == L'e' )) - mode |= S_IXUSR | S_IXGRP | S_IXOTH; - break; - default: - break; - } - } - } - archive_entry_set_mode(entry, mode); -} - -static void -tree_archive_entry_copy_bhfi(struct archive_entry *entry, struct tree *t, - const BY_HANDLE_FILE_INFORMATION *bhfi) -{ - entry_copy_bhfi(entry, tree_current_path(t), t->findData, bhfi); -} - -static int -tree_current_file_information(struct tree *t, BY_HANDLE_FILE_INFORMATION *st, - int sim_lstat) -{ - HANDLE h; - int r; - DWORD flag = FILE_FLAG_BACKUP_SEMANTICS; -# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */ - CREATEFILE2_EXTENDED_PARAMETERS createExParams; -#endif - - if (sim_lstat && tree_current_is_physical_link(t)) - flag |= FILE_FLAG_OPEN_REPARSE_POINT; -# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */ - ZeroMemory(&createExParams, sizeof(createExParams)); - createExParams.dwSize = sizeof(createExParams); - createExParams.dwFileFlags = flag; - h = CreateFile2(tree_current_access_path(t), 0, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - OPEN_EXISTING, &createExParams); -#else - h = CreateFileW(tree_current_access_path(t), 0, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, - OPEN_EXISTING, flag, NULL); -#endif - if (h == INVALID_HANDLE_VALUE) { - la_dosmaperr(GetLastError()); - t->tree_errno = errno; - return (0); - } - r = GetFileInformationByHandle(h, st); - CloseHandle(h); - return (r); -} - -/* - * Get the stat() data for the entry just returned from tree_next(). - */ -static const BY_HANDLE_FILE_INFORMATION * -tree_current_stat(struct tree *t) -{ - if (!(t->flags & hasStat)) { - if (!tree_current_file_information(t, &t->st, 0)) - return NULL; - t->flags |= hasStat; - } - return (&t->st); -} - -/* - * Get the lstat() data for the entry just returned from tree_next(). - */ -static const BY_HANDLE_FILE_INFORMATION * -tree_current_lstat(struct tree *t) -{ - if (!(t->flags & hasLstat)) { - if (!tree_current_file_information(t, &t->lst, 1)) - return NULL; - t->flags |= hasLstat; - } - return (&t->lst); -} - -/* - * Test whether current entry is a dir or link to a dir. - */ -static int -tree_current_is_dir(struct tree *t) -{ - if (t->findData) - return (t->findData->dwFileAttributes - & FILE_ATTRIBUTE_DIRECTORY); - return (0); -} - -/* - * Test whether current entry is a physical directory. Usually, we - * already have at least one of stat() or lstat() in memory, so we - * use tricks to try to avoid an extra trip to the disk. - */ -static int -tree_current_is_physical_dir(struct tree *t) -{ - if (tree_current_is_physical_link(t)) - return (0); - return (tree_current_is_dir(t)); -} - -/* - * Test whether current entry is a symbolic link. - */ -static int -tree_current_is_physical_link(struct tree *t) -{ - if (t->findData) - return ((t->findData->dwFileAttributes - & FILE_ATTRIBUTE_REPARSE_POINT) && - (t->findData->dwReserved0 - == IO_REPARSE_TAG_SYMLINK)); - return (0); -} - -/* - * Test whether the same file has been in the tree as its parent. - */ -static int -tree_target_is_same_as_parent(struct tree *t, - const BY_HANDLE_FILE_INFORMATION *st) -{ - struct tree_entry *te; - int64_t dev = bhfi_dev(st); - int64_t ino = bhfi_ino(st); - - for (te = t->current->parent; te != NULL; te = te->parent) { - if (te->dev == dev && te->ino == ino) - return (1); - } - return (0); -} - -/* - * Return the access path for the entry just returned from tree_next(). - */ -static const wchar_t * -tree_current_access_path(struct tree *t) -{ - return (t->full_path.s); -} - -/* - * Return the full path for the entry just returned from tree_next(). - */ -static const wchar_t * -tree_current_path(struct tree *t) -{ - return (t->path.s); -} - -/* - * Terminate the traversal. - */ -static void -tree_close(struct tree *t) -{ - - if (t == NULL) - return; - if (t->entry_fh != INVALID_HANDLE_VALUE) { - cancel_async(t); - close_and_restore_time(t->entry_fh, t, &t->restore_time); - t->entry_fh = INVALID_HANDLE_VALUE; - } - /* Close the handle of FindFirstFileW */ - if (t->d != INVALID_HANDLE_VALUE) { - FindClose(t->d); - t->d = INVALID_HANDLE_VALUE; - t->findData = NULL; - } - /* Release anything remaining in the stack. */ - while (t->stack != NULL) - tree_pop(t); -} - -/* - * Release any resources. - */ -static void -tree_free(struct tree *t) -{ - int i; - - if (t == NULL) - return; - archive_wstring_free(&t->path); - archive_wstring_free(&t->full_path); - free(t->sparse_list); - free(t->filesystem_table); - for (i = 0; i < MAX_OVERLAPPED; i++) { - if (t->ol[i].buff) - VirtualFree(t->ol[i].buff, 0, MEM_RELEASE); - CloseHandle(t->ol[i].ol.hEvent); - } - free(t); -} - - -/* - * Populate the archive_entry with metadata from the disk. - */ -int -archive_read_disk_entry_from_file(struct archive *_a, - struct archive_entry *entry, int fd, const struct stat *st) -{ - struct archive_read_disk *a = (struct archive_read_disk *)_a; - const wchar_t *path; - const wchar_t *wname; - const char *name; - HANDLE h; - BY_HANDLE_FILE_INFORMATION bhfi; - DWORD fileAttributes = 0; - int r; - - archive_clear_error(_a); - wname = archive_entry_sourcepath_w(entry); - if (wname == NULL) - wname = archive_entry_pathname_w(entry); - if (wname == NULL) { - archive_set_error(&a->archive, EINVAL, - "Can't get a wide character version of the path"); - return (ARCHIVE_FAILED); - } - path = __la_win_permissive_name_w(wname); - - if (st == NULL) { - /* - * Get metadata through GetFileInformationByHandle(). - */ - if (fd >= 0) { - h = (HANDLE)_get_osfhandle(fd); - r = GetFileInformationByHandle(h, &bhfi); - if (r == 0) { - la_dosmaperr(GetLastError()); - archive_set_error(&a->archive, errno, - "Can't GetFileInformationByHandle"); - return (ARCHIVE_FAILED); - } - entry_copy_bhfi(entry, path, NULL, &bhfi); - } else { - WIN32_FIND_DATAW findData; - DWORD flag, desiredAccess; -# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */ - CREATEFILE2_EXTENDED_PARAMETERS createExParams; -#endif - - h = FindFirstFileW(path, &findData); - if (h == INVALID_HANDLE_VALUE) { - la_dosmaperr(GetLastError()); - archive_set_error(&a->archive, errno, - "Can't FindFirstFileW"); - return (ARCHIVE_FAILED); - } - FindClose(h); - - flag = FILE_FLAG_BACKUP_SEMANTICS; - if (!a->follow_symlinks && - (findData.dwFileAttributes - & FILE_ATTRIBUTE_REPARSE_POINT) && - (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) { - flag |= FILE_FLAG_OPEN_REPARSE_POINT; - desiredAccess = 0; - } else if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - desiredAccess = 0; - } else - desiredAccess = GENERIC_READ; - -# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */ - ZeroMemory(&createExParams, sizeof(createExParams)); - createExParams.dwSize = sizeof(createExParams); - createExParams.dwFileFlags = flag; - h = CreateFile2(path, desiredAccess, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - OPEN_EXISTING, &createExParams); -#else - h = CreateFileW(path, desiredAccess, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, - OPEN_EXISTING, flag, NULL); -#endif - if (h == INVALID_HANDLE_VALUE) { - la_dosmaperr(GetLastError()); - archive_set_error(&a->archive, errno, - "Can't CreateFileW"); - return (ARCHIVE_FAILED); - } - r = GetFileInformationByHandle(h, &bhfi); - if (r == 0) { - la_dosmaperr(GetLastError()); - archive_set_error(&a->archive, errno, - "Can't GetFileInformationByHandle"); - CloseHandle(h); - return (ARCHIVE_FAILED); - } - entry_copy_bhfi(entry, path, &findData, &bhfi); - } - fileAttributes = bhfi.dwFileAttributes; - } else { - archive_entry_copy_stat(entry, st); - if (st->st_mode & S_IFLNK) - entry_symlink_from_pathw(entry, path); - h = INVALID_HANDLE_VALUE; - } - - /* Lookup uname/gname */ - name = archive_read_disk_uname(_a, archive_entry_uid(entry)); - if (name != NULL) - archive_entry_copy_uname(entry, name); - name = archive_read_disk_gname(_a, archive_entry_gid(entry)); - if (name != NULL) - archive_entry_copy_gname(entry, name); - - /* - * File attributes - */ - if ((a->flags & ARCHIVE_READDISK_NO_FFLAGS) == 0) { - const int supported_attrs = - FILE_ATTRIBUTE_READONLY | - FILE_ATTRIBUTE_HIDDEN | - FILE_ATTRIBUTE_SYSTEM; - DWORD file_attrs = fileAttributes & supported_attrs; - if (file_attrs != 0) - archive_entry_set_fflags(entry, file_attrs, 0); - } - - /* - * Can this file be sparse file ? - */ - if (archive_entry_filetype(entry) != AE_IFREG - || archive_entry_size(entry) <= 0 - || archive_entry_hardlink(entry) != NULL) { - if (h != INVALID_HANDLE_VALUE && fd < 0) - CloseHandle(h); - return (ARCHIVE_OK); - } - - if (h == INVALID_HANDLE_VALUE) { - if (fd >= 0) { - h = (HANDLE)_get_osfhandle(fd); - } else { -# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */ - CREATEFILE2_EXTENDED_PARAMETERS createExParams; - ZeroMemory(&createExParams, sizeof(createExParams)); - createExParams.dwSize = sizeof(createExParams); - createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS; - h = CreateFile2(path, GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - OPEN_EXISTING, &createExParams); -#else - h = CreateFileW(path, GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, - OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); -#endif - if (h == INVALID_HANDLE_VALUE) { - la_dosmaperr(GetLastError()); - archive_set_error(&a->archive, errno, - "Can't CreateFileW"); - return (ARCHIVE_FAILED); - } - } - r = GetFileInformationByHandle(h, &bhfi); - if (r == 0) { - la_dosmaperr(GetLastError()); - archive_set_error(&a->archive, errno, - "Can't GetFileInformationByHandle"); - if (h != INVALID_HANDLE_VALUE && fd < 0) - CloseHandle(h); - return (ARCHIVE_FAILED); - } - fileAttributes = bhfi.dwFileAttributes; - } - - /* Sparse file must be set a mark, FILE_ATTRIBUTE_SPARSE_FILE */ - if ((fileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) == 0) { - if (fd < 0) - CloseHandle(h); - return (ARCHIVE_OK); - } - - if ((a->flags & ARCHIVE_READDISK_NO_SPARSE) == 0) { - r = setup_sparse_from_disk(a, entry, h); - if (fd < 0) - CloseHandle(h); - } - - return (r); -} - -/* - * Windows sparse interface. - */ -#if defined(__MINGW32__) && !defined(FSCTL_QUERY_ALLOCATED_RANGES) -#define FSCTL_QUERY_ALLOCATED_RANGES 0x940CF -typedef struct { - LARGE_INTEGER FileOffset; - LARGE_INTEGER Length; -} FILE_ALLOCATED_RANGE_BUFFER; -#endif - -static int -setup_sparse_from_disk(struct archive_read_disk *a, - struct archive_entry *entry, HANDLE handle) -{ - FILE_ALLOCATED_RANGE_BUFFER range, *outranges = NULL; - size_t outranges_size; - int64_t entry_size = archive_entry_size(entry); - int exit_sts = ARCHIVE_OK; - - range.FileOffset.QuadPart = 0; - range.Length.QuadPart = entry_size; - outranges_size = 2048; - outranges = (FILE_ALLOCATED_RANGE_BUFFER *)malloc(outranges_size); - if (outranges == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Couldn't allocate memory"); - exit_sts = ARCHIVE_FATAL; - goto exit_setup_sparse; - } - - for (;;) { - DWORD retbytes; - BOOL ret; - - for (;;) { - ret = DeviceIoControl(handle, - FSCTL_QUERY_ALLOCATED_RANGES, - &range, sizeof(range), outranges, - (DWORD)outranges_size, &retbytes, NULL); - if (ret == 0 && GetLastError() == ERROR_MORE_DATA) { - free(outranges); - outranges_size *= 2; - outranges = (FILE_ALLOCATED_RANGE_BUFFER *) - malloc(outranges_size); - if (outranges == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Couldn't allocate memory"); - exit_sts = ARCHIVE_FATAL; - goto exit_setup_sparse; - } - continue; - } else - break; - } - if (ret != 0) { - if (retbytes > 0) { - DWORD i, n; - - n = retbytes / sizeof(outranges[0]); - if (n == 1 && - outranges[0].FileOffset.QuadPart == 0 && - outranges[0].Length.QuadPart == entry_size) - break;/* This is not sparse. */ - for (i = 0; i < n; i++) - archive_entry_sparse_add_entry(entry, - outranges[i].FileOffset.QuadPart, - outranges[i].Length.QuadPart); - range.FileOffset.QuadPart = - outranges[n-1].FileOffset.QuadPart - + outranges[n-1].Length.QuadPart; - range.Length.QuadPart = - entry_size - range.FileOffset.QuadPart; - if (range.Length.QuadPart > 0) - continue; - } else { - /* The entire file is a hole. Add one data block of size 0 at the end. */ - archive_entry_sparse_add_entry(entry, - entry_size, - 0); - } - break; - } else { - la_dosmaperr(GetLastError()); - archive_set_error(&a->archive, errno, - "DeviceIoControl Failed: %lu", GetLastError()); - exit_sts = ARCHIVE_FAILED; - goto exit_setup_sparse; - } - } -exit_setup_sparse: - free(outranges); - - return (exit_sts); -} - -#endif diff --git a/thirdparty/libarchive/libarchive/archive_read_extract.3 b/thirdparty/libarchive/libarchive/archive_read_extract.3 deleted file mode 100644 index 858f39742..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_extract.3 +++ /dev/null @@ -1,137 +0,0 @@ -.\" Copyright (c) 2003-2011 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd February 2, 2012 -.Dt ARCHIVE_READ_EXTRACT 3 -.Os -.Sh NAME -.Nm archive_read_extract , -.Nm archive_read_extract2 , -.Nm archive_read_extract_set_progress_callback -.Nd functions for reading streaming archives -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive.h -.Ft int -.Fo archive_read_extract -.Fa "struct archive *" -.Fa "struct archive_entry *" -.Fa "int flags" -.Fc -.Ft int -.Fo archive_read_extract2 -.Fa "struct archive *src" -.Fa "struct archive_entry *" -.Fa "struct archive *dest" -.Fc -.Ft void -.Fo archive_read_extract_set_progress_callback -.Fa "struct archive *" -.Fa "void (*func)(void *)" -.Fa "void *user_data" -.Fc -.Sh DESCRIPTION -.Bl -tag -compact -width indent -.It Fn archive_read_extract , Fn archive_read_extract_set_skip_file -A convenience function that wraps the corresponding -.Xr archive_write_disk 3 -interfaces. -The first call to -.Fn archive_read_extract -creates a restore object using -.Xr archive_write_disk_new 3 -and -.Xr archive_write_disk_set_standard_lookup 3 , -then transparently invokes -.Xr archive_write_disk_set_options 3 , -.Xr archive_write_header 3 , -.Xr archive_write_data 3 , -and -.Xr archive_write_finish_entry 3 -to create the entry on disk and copy data into it. -The -.Va flags -argument is passed unmodified to -.Xr archive_write_disk_set_options 3 . -.It Fn archive_read_extract2 -This is another version of -.Fn archive_read_extract -that allows you to provide your own restore object. -In particular, this allows you to override the standard lookup functions -using -.Xr archive_write_disk_set_group_lookup 3 , -and -.Xr archive_write_disk_set_user_lookup 3 . -Note that -.Fn archive_read_extract2 -does not accept a -.Va flags -argument; you should use -.Fn archive_write_disk_set_options -to set the restore options yourself. -.It Fn archive_read_extract_set_progress_callback -Sets a pointer to a user-defined callback that can be used -for updating progress displays during extraction. -The progress function will be invoked during the extraction of large -regular files. -The progress function will be invoked with the pointer provided to this call. -Generally, the data pointed to should include a reference to the archive -object and the archive_entry object so that various statistics -can be retrieved for the progress display. -.El -.\" -.Sh RETURN VALUES -Most functions return zero on success, non-zero on error. -The possible return codes include: -.Cm ARCHIVE_OK -(the operation succeeded), -.Cm ARCHIVE_WARN -(the operation succeeded but a non-critical error was encountered), -.Cm ARCHIVE_EOF -(end-of-archive was encountered), -.Cm ARCHIVE_RETRY -(the operation failed but can be retried), -and -.Cm ARCHIVE_FATAL -(there was a fatal error; the archive should be closed immediately). -.Sh ERRORS -Detailed error codes and textual descriptions are available from the -.Fn archive_errno -and -.Fn archive_error_string -functions. -.Sh SEE ALSO -.Xr tar 1 , -.Xr archive_read 3 , -.Xr archive_read_data 3 , -.Xr archive_read_filter 3 , -.Xr archive_read_format 3 , -.Xr archive_read_open 3 , -.Xr archive_read_set_options 3 , -.Xr archive_util 3 , -.Xr libarchive 3 , -.Xr tar 5 diff --git a/thirdparty/libarchive/libarchive/archive_read_extract.c b/thirdparty/libarchive/libarchive/archive_read_extract.c deleted file mode 100644 index b7973fa8e..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_extract.c +++ /dev/null @@ -1,60 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_extract.c,v 1.61 2008/05/26 17:00:22 kientzle Exp $"); - -#ifdef HAVE_ERRNO_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" -#include "archive_private.h" -#include "archive_read_private.h" - -int -archive_read_extract(struct archive *_a, struct archive_entry *entry, int flags) -{ - struct archive_read_extract *extract; - struct archive_read * a = (struct archive_read *)_a; - - extract = __archive_read_get_extract(a); - if (extract == NULL) - return (ARCHIVE_FATAL); - - /* If we haven't initialized the archive_write_disk object, do it now. */ - if (extract->ad == NULL) { - extract->ad = archive_write_disk_new(); - if (extract->ad == NULL) { - archive_set_error(&a->archive, ENOMEM, "Can't extract"); - return (ARCHIVE_FATAL); - } - archive_write_disk_set_standard_lookup(extract->ad); - } - - archive_write_disk_set_options(extract->ad, flags); - return (archive_read_extract2(&a->archive, entry, extract->ad)); -} diff --git a/thirdparty/libarchive/libarchive/archive_read_extract2.c b/thirdparty/libarchive/libarchive/archive_read_extract2.c deleted file mode 100644 index 4febd8ce0..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_extract2.c +++ /dev/null @@ -1,155 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_extract.c,v 1.61 2008/05/26 17:00:22 kientzle Exp $"); - -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" -#include "archive_private.h" -#include "archive_read_private.h" - -static int copy_data(struct archive *ar, struct archive *aw); -static int archive_read_extract_cleanup(struct archive_read *); - - -/* Retrieve an extract object without initialising the associated - * archive_write_disk object. - */ -struct archive_read_extract * -__archive_read_get_extract(struct archive_read *a) -{ - if (a->extract == NULL) { - a->extract = (struct archive_read_extract *)calloc(1, sizeof(*a->extract)); - if (a->extract == NULL) { - archive_set_error(&a->archive, ENOMEM, "Can't extract"); - return (NULL); - } - a->cleanup_archive_extract = archive_read_extract_cleanup; - } - return (a->extract); -} - -/* - * Cleanup function for archive_extract. - */ -static int -archive_read_extract_cleanup(struct archive_read *a) -{ - int ret = ARCHIVE_OK; - - if (a->extract->ad != NULL) { - ret = archive_write_free(a->extract->ad); - } - free(a->extract); - a->extract = NULL; - return (ret); -} - -int -archive_read_extract2(struct archive *_a, struct archive_entry *entry, - struct archive *ad) -{ - struct archive_read *a = (struct archive_read *)_a; - int r, r2; - - /* Set up for this particular entry. */ - if (a->skip_file_set) - archive_write_disk_set_skip_file(ad, - a->skip_file_dev, a->skip_file_ino); - r = archive_write_header(ad, entry); - if (r < ARCHIVE_WARN) - r = ARCHIVE_WARN; - if (r != ARCHIVE_OK) - /* If _write_header failed, copy the error. */ - archive_copy_error(&a->archive, ad); - else if (!archive_entry_size_is_set(entry) || archive_entry_size(entry) > 0) - /* Otherwise, pour data into the entry. */ - r = copy_data(_a, ad); - r2 = archive_write_finish_entry(ad); - if (r2 < ARCHIVE_WARN) - r2 = ARCHIVE_WARN; - /* Use the first message. */ - if (r2 != ARCHIVE_OK && r == ARCHIVE_OK) - archive_copy_error(&a->archive, ad); - /* Use the worst error return. */ - if (r2 < r) - r = r2; - return (r); -} - -void -archive_read_extract_set_progress_callback(struct archive *_a, - void (*progress_func)(void *), void *user_data) -{ - struct archive_read *a = (struct archive_read *)_a; - struct archive_read_extract *extract = __archive_read_get_extract(a); - if (extract != NULL) { - extract->extract_progress = progress_func; - extract->extract_progress_user_data = user_data; - } -} - -static int -copy_data(struct archive *ar, struct archive *aw) -{ - int64_t offset; - const void *buff; - struct archive_read_extract *extract; - size_t size; - int r; - - extract = __archive_read_get_extract((struct archive_read *)ar); - if (extract == NULL) - return (ARCHIVE_FATAL); - for (;;) { - r = archive_read_data_block(ar, &buff, &size, &offset); - if (r == ARCHIVE_EOF) - return (ARCHIVE_OK); - if (r != ARCHIVE_OK) - return (r); - r = (int)archive_write_data_block(aw, buff, size, offset); - if (r < ARCHIVE_WARN) - r = ARCHIVE_WARN; - if (r < ARCHIVE_OK) { - archive_set_error(ar, archive_errno(aw), - "%s", archive_error_string(aw)); - return (r); - } - if (extract->extract_progress) - (extract->extract_progress) - (extract->extract_progress_user_data); - } -} diff --git a/thirdparty/libarchive/libarchive/archive_read_filter.3 b/thirdparty/libarchive/libarchive/archive_read_filter.3 deleted file mode 100644 index 4f5c3518a..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_filter.3 +++ /dev/null @@ -1,164 +0,0 @@ -.\" Copyright (c) 2003-2011 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd June 9, 2020 -.Dt ARCHIVE_READ_FILTER 3 -.Os -.Sh NAME -.Nm archive_read_support_filter_all , -.Nm archive_read_support_filter_bzip2 , -.Nm archive_read_support_filter_compress , -.Nm archive_read_support_filter_gzip , -.Nm archive_read_support_filter_lz4 , -.Nm archive_read_support_filter_lzma , -.Nm archive_read_support_filter_none , -.Nm archive_read_support_filter_rpm , -.Nm archive_read_support_filter_uu , -.Nm archive_read_support_filter_xz , -.Nm archive_read_support_filter_zstd , -.Nm archive_read_support_filter_program , -.Nm archive_read_support_filter_program_signature -.Nd functions for reading streaming archives -.\" -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive.h -.Ft int -.Fn archive_read_support_filter_all "struct archive *" -.Ft int -.Fn archive_read_support_filter_by_code "struct archive *" "int" -.Ft int -.Fn archive_read_support_filter_bzip2 "struct archive *" -.Ft int -.Fn archive_read_support_filter_compress "struct archive *" -.Ft int -.Fn archive_read_support_filter_grzip "struct archive *" -.Ft int -.Fn archive_read_support_filter_gzip "struct archive *" -.Ft int -.Fn archive_read_support_filter_lrzip "struct archive *" -.Ft int -.Fn archive_read_support_filter_lz4 "struct archive *" -.Ft int -.Fn archive_read_support_filter_lzma "struct archive *" -.Ft int -.Fn archive_read_support_filter_lzop "struct archive *" -.Ft int -.Fn archive_read_support_filter_none "struct archive *" -.Ft int -.Fn archive_read_support_filter_rpm "struct archive *" -.Ft int -.Fn archive_read_support_filter_uu "struct archive *" -.Ft int -.Fn archive_read_support_filter_xz "struct archive *" -.Ft int -.Fn archive_read_support_filter_zstd "struct archive *" -.Ft int -.Fo archive_read_support_filter_program -.Fa "struct archive *" -.Fa "const char *cmd" -.Fc -.Ft int -.Fo archive_read_support_filter_program_signature -.Fa "struct archive *" -.Fa "const char *cmd" -.Fa "const void *signature" -.Fa "size_t signature_length" -.Fc -.\" -.Sh DESCRIPTION -.Bl -tag -compact -width indent -.It Xo -.Fn archive_read_support_filter_bzip2 , -.Fn archive_read_support_filter_compress , -.Fn archive_read_support_filter_grzip , -.Fn archive_read_support_filter_gzip , -.Fn archive_read_support_filter_lrzip , -.Fn archive_read_support_filter_lz4 , -.Fn archive_read_support_filter_lzma , -.Fn archive_read_support_filter_lzop , -.Fn archive_read_support_filter_none , -.Fn archive_read_support_filter_rpm , -.Fn archive_read_support_filter_uu , -.Fn archive_read_support_filter_xz , -.Fn archive_read_support_filter_zstd , -.Xc -Enables auto-detection code and decompression support for the -specified compression. -These functions may fall back on external programs if an appropriate -library was not available at build time. -Decompression using an external program is usually slower than -decompression through built-in libraries. -Note that -.Dq none -is always enabled by default. -.It Fn archive_read_support_filter_all -Enables all available decompression filters. -.It Fn archive_read_support_filter_by_code -Enables a single filter specified by the filter code. -This function does not work with -.Cm ARCHIVE_FILTER_PROGRAM . -Note: In statically-linked executables, this will cause -your program to include support for every filter. -If executable size is a concern, you may wish to avoid -using this function. -.It Fn archive_read_support_filter_program -Data is fed through the specified external program before being dearchived. -Note that this disables automatic detection of the compression format, -so it makes no sense to specify this in conjunction with any other -decompression option. -.It Fn archive_read_support_filter_program_signature -This feeds data through the specified external program -but only if the initial bytes of the data match the specified -signature value. -.El -.\" -.\". Sh EXAMPLE -.\" -.Sh RETURN VALUES -These functions return -.Cm ARCHIVE_OK -if the compression is fully supported, -.Cm ARCHIVE_WARN -if the compression is supported only through an external program. -.Pp -.Fn archive_read_support_filter_none -always succeeds. -.\" -.Sh ERRORS -Detailed error codes and textual descriptions are available from the -.Fn archive_errno -and -.Fn archive_error_string -functions. -.\" -.Sh SEE ALSO -.Xr archive_read 3 , -.Xr archive_read_data 3 , -.Xr archive_read_format 3 , -.Xr archive_read_format 3 , -.Xr libarchive 3 diff --git a/thirdparty/libarchive/libarchive/archive_read_format.3 b/thirdparty/libarchive/libarchive/archive_read_format.3 deleted file mode 100644 index f3804ce37..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_format.3 +++ /dev/null @@ -1,177 +0,0 @@ -.\" Copyright (c) 2003-2011 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd February 2, 2012 -.Dt ARCHIVE_READ_FORMAT 3 -.Os -.Sh NAME -.Nm archive_read_support_format_7zip , -.Nm archive_read_support_format_all , -.Nm archive_read_support_format_ar , -.Nm archive_read_support_format_by_code , -.Nm archive_read_support_format_cab , -.Nm archive_read_support_format_cpio , -.Nm archive_read_support_format_empty , -.Nm archive_read_support_format_iso9660 , -.Nm archive_read_support_format_lha , -.Nm archive_read_support_format_mtree , -.Nm archive_read_support_format_rar , -.Nm archive_read_support_format_raw , -.Nm archive_read_support_format_tar , -.Nm archive_read_support_format_xar , -.Nm archive_read_support_format_zip -.Nd functions for reading streaming archives -.\" -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive.h -.Ft int -.Fn archive_read_support_format_7zip "struct archive *" -.Ft int -.Fn archive_read_support_format_all "struct archive *" -.Ft int -.Fn archive_read_support_format_ar "struct archive *" -.Ft int -.Fn archive_read_support_format_by_code "struct archive *" "int" -.Ft int -.Fn archive_read_support_format_cab "struct archive *" -.Ft int -.Fn archive_read_support_format_cpio "struct archive *" -.Ft int -.Fn archive_read_support_format_empty "struct archive *" -.Ft int -.Fn archive_read_support_format_iso9660 "struct archive *" -.Ft int -.Fn archive_read_support_format_lha "struct archive *" -.Ft int -.Fn archive_read_support_format_mtree "struct archive *" -.Ft int -.Fn archive_read_support_format_rar "struct archive *" -.Ft int -.Fn archive_read_support_format_raw "struct archive *" -.Ft int -.Fn archive_read_support_format_tar "struct archive *" -.Ft int -.Fn archive_read_support_format_xar "struct archive *" -.Ft int -.Fn archive_read_support_format_zip "struct archive *" -.\" -.Sh DESCRIPTION -.Bl -tag -compact -width indent -.It Xo -.Fn archive_read_support_format_7zip , -.Fn archive_read_support_format_ar , -.Fn archive_read_support_format_cab , -.Fn archive_read_support_format_cpio , -.Fn archive_read_support_format_iso9660 , -.Fn archive_read_support_format_lha , -.Fn archive_read_support_format_mtree , -.Fn archive_read_support_format_rar , -.Fn archive_read_support_format_raw , -.Fn archive_read_support_format_tar , -.Fn archive_read_support_format_xar , -.Fn archive_read_support_format_zip -.Xc -Enables support---including auto-detection code---for the -specified archive format. -For example, -.Fn archive_read_support_format_tar -enables support for a variety of standard tar formats, old-style tar, -ustar, pax interchange format, and many common variants. -.It Fn archive_read_support_format_all -Enables support for all available formats except the -.Dq raw -format (see below). -.It Fn archive_read_support_format_by_code -Enables a single format specified by the format code. -This can be useful when reading a single archive twice; -use -.Fn archive_format -after reading the first time and pass the resulting code -to this function to selectively enable only the necessary -format support. -Note: In statically-linked executables, this will cause -your program to include support for every format. -If executable size is a concern, you may wish to avoid -using this function. -.It Fn archive_read_support_format_empty -Enables support for treating empty files as empty archives. -Because empty files are valid for several different formats, -it is not possible to accurately determine a format for -an empty file based purely on contents. -So empty files are treated by libarchive as a distinct -format. -.It Fn archive_read_support_format_raw -The -.Dq raw -format handler allows libarchive to be used to read arbitrary data. -It treats any data stream as an archive with a single entry. -The pathname of this entry is -.Dq data ; -all other entry fields are unset. -This is not enabled by -.Fn archive_read_support_format_all -in order to avoid erroneous handling of damaged archives. -.El -.\" .Sh EXAMPLE -.Sh RETURN VALUES -These functions return -.Cm ARCHIVE_OK -on success, or -.Cm ARCHIVE_FATAL . -.\" -.Sh ERRORS -Detailed error codes and textual descriptions are available from the -.Fn archive_errno -and -.Fn archive_error_string -functions. -.\" -.Sh SEE ALSO -.Xr tar 1 , -.Xr archive_read_data 3 , -.Xr archive_read_filter 3 , -.Xr archive_read_set_options 3 , -.Xr archive_util 3 , -.Xr libarchive 3 , -.Xr tar 5 -.Sh BUGS -Many traditional archiver programs treat -empty files as valid empty archives. -For example, many implementations of -.Xr tar 1 -allow you to append entries to an empty file. -Of course, it is impossible to determine the format of an empty file -by inspecting the contents, so this library treats empty files as -having a special -.Dq empty -format. -.Pp -Using the -.Dq raw -handler together with any other handler will often work -but can produce surprising results. diff --git a/thirdparty/libarchive/libarchive/archive_read_free.3 b/thirdparty/libarchive/libarchive/archive_read_free.3 deleted file mode 100644 index 8371c3a0c..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_free.3 +++ /dev/null @@ -1,93 +0,0 @@ -.\" Copyright (c) 2003-2011 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd February 2, 2012 -.Dt ARCHIVE_READ_FREE 3 -.Os -.Sh NAME -.Nm archive_read_close , -.Nm archive_read_finish , -.Nm archive_read_free -.Nd functions for reading streaming archives -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive.h -.Ft int -.Fn archive_read_close "struct archive *" -.Ft int -.Fn archive_read_finish "struct archive *" -.Ft int -.Fn archive_read_free "struct archive *" -.\" -.Sh DESCRIPTION -.Bl -tag -compact -width indent -.It Fn archive_read_close -Complete the archive and invoke the close callback. -.It Fn archive_read_finish -This is a deprecated synonym for -.Fn archive_read_free . -The new name was introduced with libarchive 3.0. -Applications that need to compile with either libarchive 2 -or libarchive 3 should continue to use the -.Fn archive_read_finish -name. -Both names will be supported until libarchive 4.0 is -released, which is not expected to occur earlier -than 2013. -.It Fn archive_read_free -Invokes -.Fn archive_read_close -if it was not invoked manually, then release all resources. -Note: In libarchive 1.x, this function was declared to return -.Ft void , -which made it impossible to detect certain errors when -.Fn archive_read_close -was invoked implicitly from this function. -The declaration is corrected beginning with libarchive 2.0. -.El -.Sh RETURN VALUES -These functions return -.Cm ARCHIVE_OK -on success, or -.Cm ARCHIVE_FATAL . -.\" -.Sh ERRORS -Detailed error codes and textual descriptions are available from the -.Fn archive_errno -and -.Fn archive_error_string -functions. -.\" -.Sh SEE ALSO -.Xr archive_read_data 3 , -.Xr archive_read_filter 3 , -.Xr archive_read_format 3 , -.Xr archive_read_new 3 , -.Xr archive_read_open 3 , -.Xr archive_read_set_options 3 , -.Xr archive_util 3 , -.Xr libarchive 3 diff --git a/thirdparty/libarchive/libarchive/archive_read_header.3 b/thirdparty/libarchive/libarchive/archive_read_header.3 deleted file mode 100644 index 1e97f3a27..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_header.3 +++ /dev/null @@ -1,91 +0,0 @@ -.\" Copyright (c) 2003-2011 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd February 2, 2012 -.Dt ARCHIVE_READ_HEADER 3 -.Os -.Sh NAME -.Nm archive_read_next_header , -.Nm archive_read_next_header2 -.Nd functions for reading streaming archives -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive.h -.Ft int -.Fn archive_read_next_header "struct archive *" "struct archive_entry **" -.Ft int -.Fn archive_read_next_header2 "struct archive *" "struct archive_entry *" -.\" -.Sh DESCRIPTION -.Bl -tag -compact -width indent -.It Fn archive_read_next_header -Read the header for the next entry and return a pointer to -a -.Tn struct archive_entry . -This is a convenience wrapper around -.Fn archive_read_next_header2 -that reuses an internal -.Tn struct archive_entry -object for each request. -.It Fn archive_read_next_header2 -Read the header for the next entry and populate the provided -.Tn struct archive_entry . -.El -.\" -.Sh RETURN VALUES -These functions return -.Cm ARCHIVE_OK -(the operation succeeded), -.Cm ARCHIVE_WARN -(the operation succeeded but a non-critical error was encountered), -.Cm ARCHIVE_EOF -(end-of-archive was encountered), -.Cm ARCHIVE_RETRY -(the operation failed but can be retried), -and -.Cm ARCHIVE_FATAL -(there was a fatal error; the archive should be closed immediately). -.\" -.Sh ERRORS -Detailed error codes and textual descriptions are available from the -.Fn archive_errno -and -.Fn archive_error_string -functions. -.\" -.Sh SEE ALSO -.Xr tar 1 , -.Xr archive_read 3 , -.Xr archive_read_data 3 , -.Xr archive_read_extract 3 , -.Xr archive_read_filter 3 , -.Xr archive_read_format 3 , -.Xr archive_read_open 3 , -.Xr archive_read_set_options 3 , -.Xr archive_util 3 , -.Xr libarchive 3 , -.Xr tar 5 diff --git a/thirdparty/libarchive/libarchive/archive_read_new.3 b/thirdparty/libarchive/libarchive/archive_read_new.3 deleted file mode 100644 index 8bb6b848b..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_new.3 +++ /dev/null @@ -1,59 +0,0 @@ -.\" Copyright (c) 2003-2011 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd February 2, 2012 -.Dt ARCHIVE_READ_NEW 3 -.Os -.Sh NAME -.Nm archive_read_new -.Nd functions for reading streaming archives -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive.h -.Ft struct archive * -.Fn archive_read_new "void" -.Sh DESCRIPTION -Allocates and initializes a -.Tn struct archive -object suitable for reading from an archive. -.Dv NULL -is returned on error. -.Pp -A complete description of the -.Tn struct archive -object can be found in the overview manual page for -.Xr libarchive 3 . -.\" .Sh ERRORS -.Sh SEE ALSO -.Xr tar 1 , -.Xr archive_read_data 3 , -.Xr archive_read_filter 3 , -.Xr archive_read_format 3 , -.Xr archive_read_set_options 3 , -.Xr archive_util 3 , -.Xr libarchive 3 , -.Xr tar 5 diff --git a/thirdparty/libarchive/libarchive/archive_read_open.3 b/thirdparty/libarchive/libarchive/archive_read_open.3 deleted file mode 100644 index f67677823..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_open.3 +++ /dev/null @@ -1,233 +0,0 @@ -.\" Copyright (c) 2003-2011 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd February 2, 2012 -.Dt ARCHIVE_READ_OPEN 3 -.Os -.Sh NAME -.Nm archive_read_open , -.Nm archive_read_open2 , -.Nm archive_read_open_fd , -.Nm archive_read_open_FILE , -.Nm archive_read_open_filename , -.Nm archive_read_open_memory -.Nd functions for reading streaming archives -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive.h -.Ft int -.Fo archive_read_open -.Fa "struct archive *" -.Fa "void *client_data" -.Fa "archive_open_callback *" -.Fa "archive_read_callback *" -.Fa "archive_close_callback *" -.Fc -.Ft int -.Fo archive_read_open2 -.Fa "struct archive *" -.Fa "void *client_data" -.Fa "archive_open_callback *" -.Fa "archive_read_callback *" -.Fa "archive_skip_callback *" -.Fa "archive_close_callback *" -.Fc -.Ft int -.Fn archive_read_open_FILE "struct archive *" "FILE *file" -.Ft int -.Fn archive_read_open_fd "struct archive *" "int fd" "size_t block_size" -.Ft int -.Fo archive_read_open_filename -.Fa "struct archive *" -.Fa "const char *filename" -.Fa "size_t block_size" -.Fc -.Ft int -.Fn archive_read_open_memory "struct archive *" "const void *buff" "size_t size" -.Sh DESCRIPTION -.Bl -tag -compact -width indent -.It Fn archive_read_open -The same as -.Fn archive_read_open2 , -except that the skip callback is assumed to be -.Dv NULL . -.It Fn archive_read_open2 -Freeze the settings, open the archive, and prepare for reading entries. -This is the most generic version of this call, which accepts -four callback functions. -Most clients will want to use -.Fn archive_read_open_filename , -.Fn archive_read_open_FILE , -.Fn archive_read_open_fd , -or -.Fn archive_read_open_memory -instead. -The library invokes the client-provided functions to obtain -raw bytes from the archive. -.It Fn archive_read_open_FILE -Like -.Fn archive_read_open , -except that it accepts a -.Ft "FILE *" -pointer. -This function should not be used with tape drives or other devices -that require strict I/O blocking. -.It Fn archive_read_open_fd -Like -.Fn archive_read_open , -except that it accepts a file descriptor and block size rather than -a set of function pointers. -Note that the file descriptor will not be automatically closed at -end-of-archive. -This function is safe for use with tape drives or other blocked devices. -.It Fn archive_read_open_file -This is a deprecated synonym for -.Fn archive_read_open_filename . -.It Fn archive_read_open_filename -Like -.Fn archive_read_open , -except that it accepts a simple filename and a block size. -A NULL filename represents standard input. -This function is safe for use with tape drives or other blocked devices. -.It Fn archive_read_open_memory -Like -.Fn archive_read_open , -except that it accepts a pointer and size of a block of -memory containing the archive data. -.El -.Pp -A complete description of the -.Tn struct archive -and -.Tn struct archive_entry -objects can be found in the overview manual page for -.Xr libarchive 3 . -.Sh CLIENT CALLBACKS -The callback functions must match the following prototypes: -.Bl -item -offset indent -.It -.Ft typedef la_ssize_t -.Fo archive_read_callback -.Fa "struct archive *" -.Fa "void *client_data" -.Fa "const void **buffer" -.Fc -.It -.Ft typedef la_int64_t -.Fo archive_skip_callback -.Fa "struct archive *" -.Fa "void *client_data" -.Fa "off_t request" -.Fc -.It -.Ft typedef int -.Fn archive_open_callback "struct archive *" "void *client_data" -.It -.Ft typedef int -.Fn archive_close_callback "struct archive *" "void *client_data" -.El -.Pp -The open callback is invoked by -.Fn archive_open . -It should return -.Cm ARCHIVE_OK -if the underlying file or data source is successfully -opened. -If the open fails, it should call -.Fn archive_set_error -to register an error code and message and return -.Cm ARCHIVE_FATAL . -.Pp -The read callback is invoked whenever the library -requires raw bytes from the archive. -The read callback should read data into a buffer, -set the -.Li const void **buffer -argument to point to the available data, and -return a count of the number of bytes available. -The library will invoke the read callback again -only after it has consumed this data. -The library imposes no constraints on the size -of the data blocks returned. -On end-of-file, the read callback should -return zero. -On error, the read callback should invoke -.Fn archive_set_error -to register an error code and message and -return -1. -.Pp -The skip callback is invoked when the -library wants to ignore a block of data. -The return value is the number of bytes actually -skipped, which may differ from the request. -If the callback cannot skip data, it should return -zero. -If the skip callback is not provided (the -function pointer is -.Dv NULL ), -the library will invoke the read function -instead and simply discard the result. -A skip callback can provide significant -performance gains when reading uncompressed -archives from slow disk drives or other media -that can skip quickly. -.Pp -The close callback is invoked by archive_close when -the archive processing is complete. -The callback should return -.Cm ARCHIVE_OK -on success. -On failure, the callback should invoke -.Fn archive_set_error -to register an error code and message and -return -.Cm ARCHIVE_FATAL . -.\" .Sh EXAMPLE -.\" -.Sh RETURN VALUES -These functions return -.Cm ARCHIVE_OK -on success, or -.Cm ARCHIVE_FATAL . -.\" -.Sh ERRORS -Detailed error codes and textual descriptions are available from the -.Fn archive_errno -and -.Fn archive_error_string -functions. -.\" -.Sh SEE ALSO -.Xr tar 1 , -.Xr archive_read 3 , -.Xr archive_read_data 3 , -.Xr archive_read_filter 3 , -.Xr archive_read_format 3 , -.Xr archive_read_set_options 3 , -.Xr archive_util 3 , -.Xr libarchive 3 , -.Xr tar 5 diff --git a/thirdparty/libarchive/libarchive/archive_read_open_fd.c b/thirdparty/libarchive/libarchive/archive_read_open_fd.c deleted file mode 100644 index f59cd07fe..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_open_fd.c +++ /dev/null @@ -1,211 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_open_fd.c 201103 2009-12-28 03:13:49Z kientzle $"); - -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif -#ifdef HAVE_IO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif - -#include "archive.h" - -struct read_fd_data { - int fd; - size_t block_size; - char use_lseek; - void *buffer; -}; - -static int file_close(struct archive *, void *); -static ssize_t file_read(struct archive *, void *, const void **buff); -static int64_t file_seek(struct archive *, void *, int64_t request, int); -static int64_t file_skip(struct archive *, void *, int64_t request); - -int -archive_read_open_fd(struct archive *a, int fd, size_t block_size) -{ - struct stat st; - struct read_fd_data *mine; - void *b; - - archive_clear_error(a); - if (fstat(fd, &st) != 0) { - archive_set_error(a, errno, "Can't stat fd %d", fd); - return (ARCHIVE_FATAL); - } - - mine = (struct read_fd_data *)calloc(1, sizeof(*mine)); - b = malloc(block_size); - if (mine == NULL || b == NULL) { - archive_set_error(a, ENOMEM, "No memory"); - free(mine); - free(b); - return (ARCHIVE_FATAL); - } - mine->block_size = block_size; - mine->buffer = b; - mine->fd = fd; - /* - * Skip support is a performance optimization for anything - * that supports lseek(). On FreeBSD, only regular files and - * raw disk devices support lseek() and there's no portable - * way to determine if a device is a raw disk device, so we - * only enable this optimization for regular files. - */ - if (S_ISREG(st.st_mode)) { - archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino); - mine->use_lseek = 1; - } -#if defined(__CYGWIN__) || defined(_WIN32) - setmode(mine->fd, O_BINARY); -#endif - - archive_read_set_read_callback(a, file_read); - archive_read_set_skip_callback(a, file_skip); - archive_read_set_seek_callback(a, file_seek); - archive_read_set_close_callback(a, file_close); - archive_read_set_callback_data(a, mine); - return (archive_read_open1(a)); -} - -static ssize_t -file_read(struct archive *a, void *client_data, const void **buff) -{ - struct read_fd_data *mine = (struct read_fd_data *)client_data; - ssize_t bytes_read; - - *buff = mine->buffer; - for (;;) { - bytes_read = read(mine->fd, mine->buffer, mine->block_size); - if (bytes_read < 0) { - if (errno == EINTR) - continue; - archive_set_error(a, errno, "Error reading fd %d", - mine->fd); - } - return (bytes_read); - } -} - -static int64_t -file_skip(struct archive *a, void *client_data, int64_t request) -{ - struct read_fd_data *mine = (struct read_fd_data *)client_data; - int64_t skip = request; - int64_t old_offset, new_offset; - int skip_bits = sizeof(skip) * 8 - 1; /* off_t is a signed type. */ - - if (!mine->use_lseek) - return (0); - - /* Reduce a request that would overflow the 'skip' variable. */ - if (sizeof(request) > sizeof(skip)) { - int64_t max_skip = - (((int64_t)1 << (skip_bits - 1)) - 1) * 2 + 1; - if (request > max_skip) - skip = max_skip; - } - - /* Reduce request to the next smallest multiple of block_size */ - request = (request / mine->block_size) * mine->block_size; - if (request == 0) - return (0); - - if (((old_offset = lseek(mine->fd, 0, SEEK_CUR)) >= 0) && - ((new_offset = lseek(mine->fd, skip, SEEK_CUR)) >= 0)) - return (new_offset - old_offset); - - /* If seek failed once, it will probably fail again. */ - mine->use_lseek = 0; - - /* Let libarchive recover with read+discard. */ - if (errno == ESPIPE) - return (0); - - /* - * There's been an error other than ESPIPE. This is most - * likely caused by a programmer error (too large request) - * or a corrupted archive file. - */ - archive_set_error(a, errno, "Error seeking"); - return (-1); -} - -/* - * TODO: Store the offset and use it in the read callback. - */ -static int64_t -file_seek(struct archive *a, void *client_data, int64_t request, int whence) -{ - struct read_fd_data *mine = (struct read_fd_data *)client_data; - int64_t r; - - /* We use off_t here because lseek() is declared that way. */ - /* See above for notes about when off_t is less than 64 bits. */ - r = lseek(mine->fd, request, whence); - if (r >= 0) - return r; - - if (errno == ESPIPE) { - archive_set_error(a, errno, - "A file descriptor(%d) is not seekable(PIPE)", mine->fd); - return (ARCHIVE_FAILED); - } else { - /* If the input is corrupted or truncated, fail. */ - archive_set_error(a, errno, - "Error seeking in a file descriptor(%d)", mine->fd); - return (ARCHIVE_FATAL); - } -} - -static int -file_close(struct archive *a, void *client_data) -{ - struct read_fd_data *mine = (struct read_fd_data *)client_data; - - (void)a; /* UNUSED */ - free(mine->buffer); - free(mine); - return (ARCHIVE_OK); -} diff --git a/thirdparty/libarchive/libarchive/archive_read_open_file.c b/thirdparty/libarchive/libarchive/archive_read_open_file.c deleted file mode 100644 index 03719e8bf..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_open_file.c +++ /dev/null @@ -1,180 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_open_file.c 201093 2009-12-28 02:28:44Z kientzle $"); - -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif -#ifdef HAVE_IO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif - -#include "archive.h" - -struct read_FILE_data { - FILE *f; - size_t block_size; - void *buffer; - char can_skip; -}; - -static int file_close(struct archive *, void *); -static ssize_t file_read(struct archive *, void *, const void **buff); -static int64_t file_skip(struct archive *, void *, int64_t request); - -int -archive_read_open_FILE(struct archive *a, FILE *f) -{ - struct stat st; - struct read_FILE_data *mine; - size_t block_size = 128 * 1024; - void *b; - - archive_clear_error(a); - mine = (struct read_FILE_data *)malloc(sizeof(*mine)); - b = malloc(block_size); - if (mine == NULL || b == NULL) { - archive_set_error(a, ENOMEM, "No memory"); - free(mine); - free(b); - return (ARCHIVE_FATAL); - } - mine->block_size = block_size; - mine->buffer = b; - mine->f = f; - /* - * If we can't fstat() the file, it may just be that it's not - * a file. (On some platforms, FILE * objects can wrap I/O - * streams that don't support fileno()). As a result, fileno() - * should be used cautiously.) - */ - if (fstat(fileno(mine->f), &st) == 0 && S_ISREG(st.st_mode)) { - archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino); - /* Enable the seek optimization only for regular files. */ - mine->can_skip = 1; - } else - mine->can_skip = 0; - -#if defined(__CYGWIN__) || defined(_WIN32) - setmode(fileno(mine->f), O_BINARY); -#endif - - archive_read_set_read_callback(a, file_read); - archive_read_set_skip_callback(a, file_skip); - archive_read_set_close_callback(a, file_close); - archive_read_set_callback_data(a, mine); - return (archive_read_open1(a)); -} - -static ssize_t -file_read(struct archive *a, void *client_data, const void **buff) -{ - struct read_FILE_data *mine = (struct read_FILE_data *)client_data; - size_t bytes_read; - - *buff = mine->buffer; - bytes_read = fread(mine->buffer, 1, mine->block_size, mine->f); - if (bytes_read < mine->block_size && ferror(mine->f)) { - archive_set_error(a, errno, "Error reading file"); - } - return (bytes_read); -} - -static int64_t -file_skip(struct archive *a, void *client_data, int64_t request) -{ - struct read_FILE_data *mine = (struct read_FILE_data *)client_data; -#if HAVE_FSEEKO - off_t skip = (off_t)request; -#elif HAVE__FSEEKI64 - int64_t skip = request; -#else - long skip = (long)request; -#endif - int skip_bits = sizeof(skip) * 8 - 1; - - (void)a; /* UNUSED */ - - /* - * If we can't skip, return 0 as the amount we did step and - * the caller will work around by reading and discarding. - */ - if (!mine->can_skip) - return (0); - if (request == 0) - return (0); - - /* If request is too big for a long or an off_t, reduce it. */ - if (sizeof(request) > sizeof(skip)) { - int64_t max_skip = - (((int64_t)1 << (skip_bits - 1)) - 1) * 2 + 1; - if (request > max_skip) - skip = max_skip; - } - -#ifdef __ANDROID__ - /* fileno() isn't safe on all platforms ... see above. */ - if (lseek(fileno(mine->f), skip, SEEK_CUR) < 0) -#elif HAVE__FSEEKI64 - if (_fseeki64(mine->f, skip, SEEK_CUR) != 0) -#elif HAVE_FSEEKO - if (fseeko(mine->f, skip, SEEK_CUR) != 0) -#else - if (fseek(mine->f, skip, SEEK_CUR) != 0) -#endif - { - mine->can_skip = 0; - return (0); - } - return (request); -} - -static int -file_close(struct archive *a, void *client_data) -{ - struct read_FILE_data *mine = (struct read_FILE_data *)client_data; - - (void)a; /* UNUSED */ - free(mine->buffer); - free(mine); - return (ARCHIVE_OK); -} diff --git a/thirdparty/libarchive/libarchive/archive_read_open_filename.c b/thirdparty/libarchive/libarchive/archive_read_open_filename.c deleted file mode 100644 index 561289b69..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_open_filename.c +++ /dev/null @@ -1,586 +0,0 @@ -/*- - * Copyright (c) 2003-2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_open_filename.c 201093 2009-12-28 02:28:44Z kientzle $"); - -#ifdef HAVE_SYS_IOCTL_H -#include -#endif -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif -#ifdef HAVE_IO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -#include -#elif defined(__NetBSD__) || defined(__OpenBSD__) -#include -#include -#elif defined(__DragonFly__) -#include -#endif - -#include "archive.h" -#include "archive_private.h" -#include "archive_string.h" - -#ifndef O_BINARY -#define O_BINARY 0 -#endif -#ifndef O_CLOEXEC -#define O_CLOEXEC 0 -#endif - -struct read_file_data { - int fd; - size_t block_size; - void *buffer; - mode_t st_mode; /* Mode bits for opened file. */ - char use_lseek; - enum fnt_e { FNT_STDIN, FNT_MBS, FNT_WCS } filename_type; - union { - char m[1];/* MBS filename. */ - wchar_t w[1];/* WCS filename. */ - } filename; /* Must be last! */ -}; - -static int file_open(struct archive *, void *); -static int file_close(struct archive *, void *); -static int file_close2(struct archive *, void *); -static int file_switch(struct archive *, void *, void *); -static ssize_t file_read(struct archive *, void *, const void **buff); -static int64_t file_seek(struct archive *, void *, int64_t request, int); -static int64_t file_skip(struct archive *, void *, int64_t request); -static int64_t file_skip_lseek(struct archive *, void *, int64_t request); - -int -archive_read_open_file(struct archive *a, const char *filename, - size_t block_size) -{ - return (archive_read_open_filename(a, filename, block_size)); -} - -int -archive_read_open_filename(struct archive *a, const char *filename, - size_t block_size) -{ - const char *filenames[2]; - filenames[0] = filename; - filenames[1] = NULL; - return archive_read_open_filenames(a, filenames, block_size); -} - -int -archive_read_open_filenames(struct archive *a, const char **filenames, - size_t block_size) -{ - struct read_file_data *mine; - const char *filename = NULL; - if (filenames) - filename = *(filenames++); - - archive_clear_error(a); - do - { - if (filename == NULL) - filename = ""; - mine = (struct read_file_data *)calloc(1, - sizeof(*mine) + strlen(filename)); - if (mine == NULL) - goto no_memory; - strcpy(mine->filename.m, filename); - mine->block_size = block_size; - mine->fd = -1; - mine->buffer = NULL; - mine->st_mode = mine->use_lseek = 0; - if (filename == NULL || filename[0] == '\0') { - mine->filename_type = FNT_STDIN; - } else - mine->filename_type = FNT_MBS; - if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK)) - return (ARCHIVE_FATAL); - if (filenames == NULL) - break; - filename = *(filenames++); - } while (filename != NULL && filename[0] != '\0'); - archive_read_set_open_callback(a, file_open); - archive_read_set_read_callback(a, file_read); - archive_read_set_skip_callback(a, file_skip); - archive_read_set_close_callback(a, file_close); - archive_read_set_switch_callback(a, file_switch); - archive_read_set_seek_callback(a, file_seek); - - return (archive_read_open1(a)); -no_memory: - archive_set_error(a, ENOMEM, "No memory"); - return (ARCHIVE_FATAL); -} - -int -archive_read_open_filename_w(struct archive *a, const wchar_t *wfilename, - size_t block_size) -{ - struct read_file_data *mine = (struct read_file_data *)calloc(1, - sizeof(*mine) + wcslen(wfilename) * sizeof(wchar_t)); - if (!mine) - { - archive_set_error(a, ENOMEM, "No memory"); - return (ARCHIVE_FATAL); - } - mine->fd = -1; - mine->block_size = block_size; - - if (wfilename == NULL || wfilename[0] == L'\0') { - mine->filename_type = FNT_STDIN; - } else { -#if defined(_WIN32) && !defined(__CYGWIN__) - mine->filename_type = FNT_WCS; - wcscpy(mine->filename.w, wfilename); -#else - /* - * POSIX system does not support a wchar_t interface for - * open() system call, so we have to translate a wchar_t - * filename to multi-byte one and use it. - */ - struct archive_string fn; - - archive_string_init(&fn); - if (archive_string_append_from_wcs(&fn, wfilename, - wcslen(wfilename)) != 0) { - if (errno == ENOMEM) - archive_set_error(a, errno, - "Can't allocate memory"); - else - archive_set_error(a, EINVAL, - "Failed to convert a wide-character" - " filename to a multi-byte filename"); - archive_string_free(&fn); - free(mine); - return (ARCHIVE_FATAL); - } - mine->filename_type = FNT_MBS; - strcpy(mine->filename.m, fn.s); - archive_string_free(&fn); -#endif - } - if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK)) - return (ARCHIVE_FATAL); - archive_read_set_open_callback(a, file_open); - archive_read_set_read_callback(a, file_read); - archive_read_set_skip_callback(a, file_skip); - archive_read_set_close_callback(a, file_close); - archive_read_set_switch_callback(a, file_switch); - archive_read_set_seek_callback(a, file_seek); - - return (archive_read_open1(a)); -} - -static int -file_open(struct archive *a, void *client_data) -{ - struct stat st; - struct read_file_data *mine = (struct read_file_data *)client_data; - void *buffer; - const char *filename = NULL; -#if defined(_WIN32) && !defined(__CYGWIN__) - const wchar_t *wfilename = NULL; -#endif - int fd = -1; - int is_disk_like = 0; -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - off_t mediasize = 0; /* FreeBSD-specific, so off_t okay here. */ -#elif defined(__NetBSD__) || defined(__OpenBSD__) - struct disklabel dl; -#elif defined(__DragonFly__) - struct partinfo pi; -#endif - - archive_clear_error(a); - if (mine->filename_type == FNT_STDIN) { - /* We used to delegate stdin support by - * directly calling archive_read_open_fd(a,0,block_size) - * here, but that doesn't (and shouldn't) handle the - * end-of-file flush when reading stdout from a pipe. - * Basically, read_open_fd() is intended for folks who - * are willing to handle such details themselves. This - * API is intended to be a little smarter for folks who - * want easy handling of the common case. - */ - fd = 0; -#if defined(__CYGWIN__) || defined(_WIN32) - setmode(0, O_BINARY); -#endif - filename = ""; - } else if (mine->filename_type == FNT_MBS) { - filename = mine->filename.m; - fd = open(filename, O_RDONLY | O_BINARY | O_CLOEXEC); - __archive_ensure_cloexec_flag(fd); - if (fd < 0) { - archive_set_error(a, errno, - "Failed to open '%s'", filename); - return (ARCHIVE_FATAL); - } - } else { -#if defined(_WIN32) && !defined(__CYGWIN__) - wfilename = mine->filename.w; - fd = _wopen(wfilename, O_RDONLY | O_BINARY); - if (fd < 0 && errno == ENOENT) { - wchar_t *fullpath; - fullpath = __la_win_permissive_name_w(wfilename); - if (fullpath != NULL) { - fd = _wopen(fullpath, O_RDONLY | O_BINARY); - free(fullpath); - } - } - if (fd < 0) { - archive_set_error(a, errno, - "Failed to open '%S'", wfilename); - return (ARCHIVE_FATAL); - } -#else - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Unexpedted operation in archive_read_open_filename"); - goto fail; -#endif - } - if (fstat(fd, &st) != 0) { -#if defined(_WIN32) && !defined(__CYGWIN__) - if (mine->filename_type == FNT_WCS) - archive_set_error(a, errno, "Can't stat '%S'", - wfilename); - else -#endif - archive_set_error(a, errno, "Can't stat '%s'", - filename); - goto fail; - } - - /* - * Determine whether the input looks like a disk device or a - * tape device. The results are used below to select an I/O - * strategy: - * = "disk-like" devices support arbitrary lseek() and will - * support I/O requests of any size. So we get easy skipping - * and can cheat on block sizes to get better performance. - * = "tape-like" devices require strict blocking and use - * specialized ioctls for seeking. - * = "socket-like" devices cannot seek at all but can improve - * performance by using nonblocking I/O to read "whatever is - * available right now". - * - * Right now, we only specially recognize disk-like devices, - * but it should be straightforward to add probes and strategy - * here for tape-like and socket-like devices. - */ - if (S_ISREG(st.st_mode)) { - /* Safety: Tell the extractor not to overwrite the input. */ - archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino); - /* Regular files act like disks. */ - is_disk_like = 1; - } -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - /* FreeBSD: if it supports DIOCGMEDIASIZE ioctl, it's disk-like. */ - else if (S_ISCHR(st.st_mode) && - ioctl(fd, DIOCGMEDIASIZE, &mediasize) == 0 && - mediasize > 0) { - is_disk_like = 1; - } -#elif defined(__NetBSD__) || defined(__OpenBSD__) - /* Net/OpenBSD: if it supports DIOCGDINFO ioctl, it's disk-like. */ - else if ((S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) && - ioctl(fd, DIOCGDINFO, &dl) == 0 && - dl.d_partitions[DISKPART(st.st_rdev)].p_size > 0) { - is_disk_like = 1; - } -#elif defined(__DragonFly__) - /* DragonFly BSD: if it supports DIOCGPART ioctl, it's disk-like. */ - else if (S_ISCHR(st.st_mode) && - ioctl(fd, DIOCGPART, &pi) == 0 && - pi.media_size > 0) { - is_disk_like = 1; - } -#elif defined(__linux__) - /* Linux: All block devices are disk-like. */ - else if (S_ISBLK(st.st_mode) && - lseek(fd, 0, SEEK_CUR) == 0 && - lseek(fd, 0, SEEK_SET) == 0 && - lseek(fd, 0, SEEK_END) > 0 && - lseek(fd, 0, SEEK_SET) == 0) { - is_disk_like = 1; - } -#endif - /* TODO: Add an "is_tape_like" variable and appropriate tests. */ - - /* Disk-like devices prefer power-of-two block sizes. */ - /* Use provided block_size as a guide so users have some control. */ - if (is_disk_like) { - size_t new_block_size = 64 * 1024; - while (new_block_size < mine->block_size - && new_block_size < 64 * 1024 * 1024) - new_block_size *= 2; - mine->block_size = new_block_size; - } - buffer = malloc(mine->block_size); - if (buffer == NULL) { - archive_set_error(a, ENOMEM, "No memory"); - goto fail; - } - mine->buffer = buffer; - mine->fd = fd; - /* Remember mode so close can decide whether to flush. */ - mine->st_mode = st.st_mode; - - /* Disk-like inputs can use lseek(). */ - if (is_disk_like) - mine->use_lseek = 1; - - return (ARCHIVE_OK); -fail: - /* - * Don't close file descriptors not opened or ones pointing referring - * to `FNT_STDIN`. - */ - if (fd != -1 && fd != 0) - close(fd); - return (ARCHIVE_FATAL); -} - -static ssize_t -file_read(struct archive *a, void *client_data, const void **buff) -{ - struct read_file_data *mine = (struct read_file_data *)client_data; - ssize_t bytes_read; - - /* TODO: If a recent lseek() operation has left us - * mis-aligned, read and return a short block to try to get - * us back in alignment. */ - - /* TODO: Someday, try mmap() here; if that succeeds, give - * the entire file to libarchive as a single block. That - * could be a lot faster than block-by-block manual I/O. */ - - /* TODO: We might be able to improve performance on pipes and - * sockets by setting non-blocking I/O and just accepting - * whatever we get here instead of waiting for a full block - * worth of data. */ - - *buff = mine->buffer; - for (;;) { - bytes_read = read(mine->fd, mine->buffer, mine->block_size); - if (bytes_read < 0) { - if (errno == EINTR) - continue; - else if (mine->filename_type == FNT_STDIN) - archive_set_error(a, errno, - "Error reading stdin"); - else if (mine->filename_type == FNT_MBS) - archive_set_error(a, errno, - "Error reading '%s'", mine->filename.m); - else - archive_set_error(a, errno, - "Error reading '%S'", mine->filename.w); - } - return (bytes_read); - } -} - -/* - * Regular files and disk-like block devices can use simple lseek - * without needing to round the request to the block size. - * - * TODO: This can leave future reads mis-aligned. Since we know the - * offset here, we should store it and use it in file_read() above - * to determine whether we should perform a short read to get back - * into alignment. Long series of mis-aligned reads can negatively - * impact disk throughput. (Of course, the performance impact should - * be carefully tested; extra code complexity is only worthwhile if - * it does provide measurable improvement.) - * - * TODO: Be lazy about the actual seek. There are a few pathological - * cases where libarchive makes a bunch of seek requests in a row - * without any intervening reads. This isn't a huge performance - * problem, since the kernel handles seeks lazily already, but - * it would be very slightly faster if we simply remembered the - * seek request here and then actually performed the seek at the - * top of the read callback above. - */ -static int64_t -file_skip_lseek(struct archive *a, void *client_data, int64_t request) -{ - struct read_file_data *mine = (struct read_file_data *)client_data; -#if defined(_WIN32) && !defined(__CYGWIN__) - /* We use _lseeki64() on Windows. */ - int64_t old_offset, new_offset; -#else - off_t old_offset, new_offset; -#endif - - /* We use off_t here because lseek() is declared that way. */ - - /* TODO: Deal with case where off_t isn't 64 bits. - * This shouldn't be a problem on Linux or other POSIX - * systems, since the configuration logic for libarchive - * tries to obtain a 64-bit off_t. - */ - if ((old_offset = lseek(mine->fd, 0, SEEK_CUR)) >= 0 && - (new_offset = lseek(mine->fd, request, SEEK_CUR)) >= 0) - return (new_offset - old_offset); - - /* If lseek() fails, don't bother trying again. */ - mine->use_lseek = 0; - - /* Let libarchive recover with read+discard */ - if (errno == ESPIPE) - return (0); - - /* If the input is corrupted or truncated, fail. */ - if (mine->filename_type == FNT_STDIN) - archive_set_error(a, errno, "Error seeking in stdin"); - else if (mine->filename_type == FNT_MBS) - archive_set_error(a, errno, "Error seeking in '%s'", - mine->filename.m); - else - archive_set_error(a, errno, "Error seeking in '%S'", - mine->filename.w); - return (-1); -} - - -/* - * TODO: Implement another file_skip_XXXX that uses MTIO ioctls to - * accelerate operation on tape drives. - */ - -static int64_t -file_skip(struct archive *a, void *client_data, int64_t request) -{ - struct read_file_data *mine = (struct read_file_data *)client_data; - - /* Delegate skip requests. */ - if (mine->use_lseek) - return (file_skip_lseek(a, client_data, request)); - - /* If we can't skip, return 0; libarchive will read+discard instead. */ - return (0); -} - -/* - * TODO: Store the offset and use it in the read callback. - */ -static int64_t -file_seek(struct archive *a, void *client_data, int64_t request, int whence) -{ - struct read_file_data *mine = (struct read_file_data *)client_data; - int64_t r; - - /* We use off_t here because lseek() is declared that way. */ - /* See above for notes about when off_t is less than 64 bits. */ - r = lseek(mine->fd, request, whence); - if (r >= 0) - return r; - - /* If the input is corrupted or truncated, fail. */ - if (mine->filename_type == FNT_STDIN) - archive_set_error(a, errno, "Error seeking in stdin"); - else if (mine->filename_type == FNT_MBS) - archive_set_error(a, errno, "Error seeking in '%s'", - mine->filename.m); - else - archive_set_error(a, errno, "Error seeking in '%S'", - mine->filename.w); - return (ARCHIVE_FATAL); -} - -static int -file_close2(struct archive *a, void *client_data) -{ - struct read_file_data *mine = (struct read_file_data *)client_data; - - (void)a; /* UNUSED */ - - /* Only flush and close if open succeeded. */ - if (mine->fd >= 0) { - /* - * Sometimes, we should flush the input before closing. - * Regular files: faster to just close without flush. - * Disk-like devices: Ditto. - * Tapes: must not flush (user might need to - * read the "next" item on a non-rewind device). - * Pipes and sockets: must flush (otherwise, the - * program feeding the pipe or socket may complain). - * Here, I flush everything except for regular files and - * device nodes. - */ - if (!S_ISREG(mine->st_mode) - && !S_ISCHR(mine->st_mode) - && !S_ISBLK(mine->st_mode)) { - ssize_t bytesRead; - do { - bytesRead = read(mine->fd, mine->buffer, - mine->block_size); - } while (bytesRead > 0); - } - /* If a named file was opened, then it needs to be closed. */ - if (mine->filename_type != FNT_STDIN) - close(mine->fd); - } - free(mine->buffer); - mine->buffer = NULL; - mine->fd = -1; - return (ARCHIVE_OK); -} - -static int -file_close(struct archive *a, void *client_data) -{ - struct read_file_data *mine = (struct read_file_data *)client_data; - file_close2(a, client_data); - free(mine); - return (ARCHIVE_OK); -} - -static int -file_switch(struct archive *a, void *client_data1, void *client_data2) -{ - file_close2(a, client_data1); - return file_open(a, client_data2); -} diff --git a/thirdparty/libarchive/libarchive/archive_read_open_memory.c b/thirdparty/libarchive/libarchive/archive_read_open_memory.c deleted file mode 100644 index 311be4704..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_open_memory.c +++ /dev/null @@ -1,186 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_open_memory.c,v 1.6 2007/07/06 15:51:59 kientzle Exp $"); - -#include -#include -#include - -#include "archive.h" - -/* - * Glue to read an archive from a block of memory. - * - * This is mostly a huge help in building test harnesses; - * test programs can build archives in memory and read them - * back again without having to mess with files on disk. - */ - -struct read_memory_data { - const unsigned char *start; - const unsigned char *p; - const unsigned char *end; - ssize_t read_size; -}; - -static int memory_read_close(struct archive *, void *); -static int memory_read_open(struct archive *, void *); -static int64_t memory_read_seek(struct archive *, void *, int64_t offset, int whence); -static int64_t memory_read_skip(struct archive *, void *, int64_t request); -static ssize_t memory_read(struct archive *, void *, const void **buff); - -int -archive_read_open_memory(struct archive *a, const void *buff, size_t size) -{ - return archive_read_open_memory2(a, buff, size, size); -} - -/* - * Don't use _open_memory2() in production code; the archive_read_open_memory() - * version is the one you really want. This is just here so that - * test harnesses can exercise block operations inside the library. - */ -int -archive_read_open_memory2(struct archive *a, const void *buff, - size_t size, size_t read_size) -{ - struct read_memory_data *mine; - - mine = (struct read_memory_data *)calloc(1, sizeof(*mine)); - if (mine == NULL) { - archive_set_error(a, ENOMEM, "No memory"); - return (ARCHIVE_FATAL); - } - mine->start = mine->p = (const unsigned char *)buff; - mine->end = mine->start + size; - mine->read_size = read_size; - archive_read_set_open_callback(a, memory_read_open); - archive_read_set_read_callback(a, memory_read); - archive_read_set_seek_callback(a, memory_read_seek); - archive_read_set_skip_callback(a, memory_read_skip); - archive_read_set_close_callback(a, memory_read_close); - archive_read_set_callback_data(a, mine); - return (archive_read_open1(a)); -} - -/* - * There's nothing to open. - */ -static int -memory_read_open(struct archive *a, void *client_data) -{ - (void)a; /* UNUSED */ - (void)client_data; /* UNUSED */ - return (ARCHIVE_OK); -} - -/* - * This is scary simple: Just advance a pointer. Limiting - * to read_size is not technically necessary, but it exercises - * more of the internal logic when used with a small block size - * in a test harness. Production use should not specify a block - * size; then this is much faster. - */ -static ssize_t -memory_read(struct archive *a, void *client_data, const void **buff) -{ - struct read_memory_data *mine = (struct read_memory_data *)client_data; - ssize_t size; - - (void)a; /* UNUSED */ - *buff = mine->p; - size = mine->end - mine->p; - if (size > mine->read_size) - size = mine->read_size; - mine->p += size; - return (size); -} - -/* - * Advancing is just as simple. Again, this is doing more than - * necessary in order to better exercise internal code when used - * as a test harness. - */ -static int64_t -memory_read_skip(struct archive *a, void *client_data, int64_t skip) -{ - struct read_memory_data *mine = (struct read_memory_data *)client_data; - - (void)a; /* UNUSED */ - if ((int64_t)skip > (int64_t)(mine->end - mine->p)) - skip = mine->end - mine->p; - /* Round down to block size. */ - skip /= mine->read_size; - skip *= mine->read_size; - mine->p += skip; - return (skip); -} - -/* - * Seeking. - */ -static int64_t -memory_read_seek(struct archive *a, void *client_data, int64_t offset, int whence) -{ - struct read_memory_data *mine = (struct read_memory_data *)client_data; - - (void)a; /* UNUSED */ - switch (whence) { - case SEEK_SET: - mine->p = mine->start + offset; - break; - case SEEK_CUR: - mine->p += offset; - break; - case SEEK_END: - mine->p = mine->end + offset; - break; - default: - return ARCHIVE_FATAL; - } - if (mine->p < mine->start) { - mine->p = mine->start; - return ARCHIVE_FAILED; - } - if (mine->p > mine->end) { - mine->p = mine->end; - return ARCHIVE_FAILED; - } - return (mine->p - mine->start); -} - -/* - * Close is just cleaning up our one small bit of data. - */ -static int -memory_read_close(struct archive *a, void *client_data) -{ - struct read_memory_data *mine = (struct read_memory_data *)client_data; - (void)a; /* UNUSED */ - free(mine); - return (ARCHIVE_OK); -} diff --git a/thirdparty/libarchive/libarchive/archive_read_private.h b/thirdparty/libarchive/libarchive/archive_read_private.h deleted file mode 100644 index 383405d52..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_private.h +++ /dev/null @@ -1,267 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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: head/lib/libarchive/archive_read_private.h 201088 2009-12-28 02:18:55Z kientzle $ - */ - -#ifndef ARCHIVE_READ_PRIVATE_H_INCLUDED -#define ARCHIVE_READ_PRIVATE_H_INCLUDED - -#ifndef __LIBARCHIVE_BUILD -#ifndef __LIBARCHIVE_TEST -#error This header is only to be used internally to libarchive. -#endif -#endif - -#include "archive.h" -#include "archive_string.h" -#include "archive_private.h" - -struct archive_read; -struct archive_read_filter_bidder; -struct archive_read_filter; - -struct archive_read_filter_bidder_vtable { - /* Taste the upstream filter to see if we handle this. */ - int (*bid)(struct archive_read_filter_bidder *, - struct archive_read_filter *); - /* Initialize a newly-created filter. */ - int (*init)(struct archive_read_filter *); - /* Release the bidder's configuration data. */ - void (*free)(struct archive_read_filter_bidder *); -}; - -/* - * How bidding works for filters: - * * The bid manager initializes the client-provided reader as the - * first filter. - * * It invokes the bidder for each registered filter with the - * current head filter. - * * The bidders can use archive_read_filter_ahead() to peek ahead - * at the incoming data to compose their bids. - * * The bid manager creates a new filter structure for the winning - * bidder and gives the winning bidder a chance to initialize it. - * * The new filter becomes the new top filter and we repeat the - * process. - * This ends only when no bidder provides a non-zero bid. Then - * we perform a similar dance with the registered format handlers. - */ -struct archive_read_filter_bidder { - /* Configuration data for the bidder. */ - void *data; - /* Name of the filter */ - const char *name; - const struct archive_read_filter_bidder_vtable *vtable; -}; - -struct archive_read_filter_vtable { - /* Return next block. */ - ssize_t (*read)(struct archive_read_filter *, const void **); - /* Close (just this filter) and free(self). */ - int (*close)(struct archive_read_filter *self); - /* Read any header metadata if available. */ - int (*read_header)(struct archive_read_filter *self, struct archive_entry *entry); -}; - -/* - * This structure is allocated within the archive_read core - * and initialized by archive_read and the init() method of the - * corresponding bidder above. - */ -struct archive_read_filter { - int64_t position; - /* Essentially all filters will need these values, so - * just declare them here. */ - struct archive_read_filter_bidder *bidder; /* My bidder. */ - struct archive_read_filter *upstream; /* Who I read from. */ - struct archive_read *archive; /* Associated archive. */ - const struct archive_read_filter_vtable *vtable; - /* My private data. */ - void *data; - - const char *name; - int code; - int can_skip; - int can_seek; - - /* Used by reblocking logic. */ - char *buffer; - size_t buffer_size; - char *next; /* Current read location. */ - size_t avail; /* Bytes in my buffer. */ - const void *client_buff; /* Client buffer information. */ - size_t client_total; - const char *client_next; - size_t client_avail; - char end_of_file; - char closed; - char fatal; -}; - -/* - * The client looks a lot like a filter, so we just wrap it here. - * - * TODO: Make archive_read_filter and archive_read_client identical so - * that users of the library can easily register their own - * transformation filters. This will probably break the API/ABI and - * so should be deferred at least until libarchive 3.0. - */ -struct archive_read_data_node { - int64_t begin_position; - int64_t total_size; - void *data; -}; -struct archive_read_client { - archive_open_callback *opener; - archive_read_callback *reader; - archive_skip_callback *skipper; - archive_seek_callback *seeker; - archive_close_callback *closer; - archive_switch_callback *switcher; - unsigned int nodes; - unsigned int cursor; - int64_t position; - struct archive_read_data_node *dataset; -}; -struct archive_read_passphrase { - char *passphrase; - struct archive_read_passphrase *next; -}; - -struct archive_read_extract { - struct archive *ad; /* archive_write_disk object */ - - /* Progress function invoked during extract. */ - void (*extract_progress)(void *); - void *extract_progress_user_data; -}; - -struct archive_read { - struct archive archive; - - struct archive_entry *entry; - - /* Dev/ino of the archive being read/written. */ - int skip_file_set; - int64_t skip_file_dev; - int64_t skip_file_ino; - - /* Callbacks to open/read/write/close client archive streams. */ - struct archive_read_client client; - - /* Registered filter bidders. */ - struct archive_read_filter_bidder bidders[16]; - - /* Last filter in chain */ - struct archive_read_filter *filter; - - /* Whether to bypass filter bidding process */ - int bypass_filter_bidding; - - /* File offset of beginning of most recently-read header. */ - int64_t header_position; - - /* Nodes and offsets of compressed data block */ - unsigned int data_start_node; - unsigned int data_end_node; - - /* - * Format detection is mostly the same as compression - * detection, with one significant difference: The bidders - * use the read_ahead calls above to examine the stream rather - * than having the supervisor hand them a block of data to - * examine. - */ - - struct archive_format_descriptor { - void *data; - const char *name; - int (*bid)(struct archive_read *, int best_bid); - int (*options)(struct archive_read *, const char *key, - const char *value); - int (*read_header)(struct archive_read *, struct archive_entry *); - int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *); - int (*read_data_skip)(struct archive_read *); - int64_t (*seek_data)(struct archive_read *, int64_t, int); - int (*cleanup)(struct archive_read *); - int (*format_capabilties)(struct archive_read *); - int (*has_encrypted_entries)(struct archive_read *); - } formats[16]; - struct archive_format_descriptor *format; /* Active format. */ - - /* - * Various information needed by archive_extract. - */ - struct archive_read_extract *extract; - int (*cleanup_archive_extract)(struct archive_read *); - - /* - * Decryption passphrase. - */ - struct { - struct archive_read_passphrase *first; - struct archive_read_passphrase **last; - int candidate; - archive_passphrase_callback *callback; - void *client_data; - } passphrases; -}; - -int __archive_read_register_format(struct archive_read *a, - void *format_data, - const char *name, - int (*bid)(struct archive_read *, int), - int (*options)(struct archive_read *, const char *, const char *), - int (*read_header)(struct archive_read *, struct archive_entry *), - int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *), - int (*read_data_skip)(struct archive_read *), - int64_t (*seek_data)(struct archive_read *, int64_t, int), - int (*cleanup)(struct archive_read *), - int (*format_capabilities)(struct archive_read *), - int (*has_encrypted_entries)(struct archive_read *)); - -int __archive_read_register_bidder(struct archive_read *a, - void *bidder_data, - const char *name, - const struct archive_read_filter_bidder_vtable *vtable); - -const void *__archive_read_ahead(struct archive_read *, size_t, ssize_t *); -const void *__archive_read_filter_ahead(struct archive_read_filter *, - size_t, ssize_t *); -int64_t __archive_read_seek(struct archive_read*, int64_t, int); -int64_t __archive_read_filter_seek(struct archive_read_filter *, int64_t, int); -int64_t __archive_read_consume(struct archive_read *, int64_t); -int64_t __archive_read_filter_consume(struct archive_read_filter *, int64_t); -int __archive_read_header(struct archive_read *, struct archive_entry *); -int __archive_read_program(struct archive_read_filter *, const char *); -void __archive_read_free_filters(struct archive_read *); -struct archive_read_extract *__archive_read_get_extract(struct archive_read *); - - -/* - * Get a decryption passphrase. - */ -void __archive_read_reset_passphrase(struct archive_read *a); -const char * __archive_read_next_passphrase(struct archive_read *a); -#endif diff --git a/thirdparty/libarchive/libarchive/archive_read_set_format.c b/thirdparty/libarchive/libarchive/archive_read_set_format.c deleted file mode 100644 index 796dcdcce..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_set_format.c +++ /dev/null @@ -1,117 +0,0 @@ -/*- - * Copyright (c) 2003-2012 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_ERRNO_H -#include -#endif - -#include "archive.h" -#include "archive_private.h" -#include "archive_read_private.h" - -int -archive_read_set_format(struct archive *_a, int code) -{ - int r1, r2, slots, i; - char str[10]; - struct archive_read *a = (struct archive_read *)_a; - - if ((r1 = archive_read_support_format_by_code(_a, code)) < (ARCHIVE_OK)) - return r1; - - r1 = r2 = (ARCHIVE_OK); - if (a->format) - r2 = (ARCHIVE_WARN); - switch (code & ARCHIVE_FORMAT_BASE_MASK) - { - case ARCHIVE_FORMAT_7ZIP: - strcpy(str, "7zip"); - break; - case ARCHIVE_FORMAT_AR: - strcpy(str, "ar"); - break; - case ARCHIVE_FORMAT_CAB: - strcpy(str, "cab"); - break; - case ARCHIVE_FORMAT_CPIO: - strcpy(str, "cpio"); - break; - case ARCHIVE_FORMAT_EMPTY: - strcpy(str, "empty"); - break; - case ARCHIVE_FORMAT_ISO9660: - strcpy(str, "iso9660"); - break; - case ARCHIVE_FORMAT_LHA: - strcpy(str, "lha"); - break; - case ARCHIVE_FORMAT_MTREE: - strcpy(str, "mtree"); - break; - case ARCHIVE_FORMAT_RAR: - strcpy(str, "rar"); - break; - case ARCHIVE_FORMAT_RAR_V5: - strcpy(str, "rar5"); - break; - case ARCHIVE_FORMAT_RAW: - strcpy(str, "raw"); - break; - case ARCHIVE_FORMAT_TAR: - strcpy(str, "tar"); - break; - case ARCHIVE_FORMAT_WARC: - strcpy(str, "warc"); - break; - case ARCHIVE_FORMAT_XAR: - strcpy(str, "xar"); - break; - case ARCHIVE_FORMAT_ZIP: - strcpy(str, "zip"); - break; - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, - "Invalid format code specified"); - return (ARCHIVE_FATAL); - } - - slots = sizeof(a->formats) / sizeof(a->formats[0]); - a->format = &(a->formats[0]); - for (i = 0; i < slots; i++, a->format++) { - if (!a->format->name || !strcmp(a->format->name, str)) - break; - } - if (!a->format->name || strcmp(a->format->name, str)) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, - "Internal error: Unable to set format"); - r1 = (ARCHIVE_FATAL); - } - - return (r1 < r2) ? r1 : r2; -} diff --git a/thirdparty/libarchive/libarchive/archive_read_set_options.3 b/thirdparty/libarchive/libarchive/archive_read_set_options.3 deleted file mode 100644 index 162b79da4..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_set_options.3 +++ /dev/null @@ -1,292 +0,0 @@ -.\" Copyright (c) 2011 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd January 31, 2020 -.Dt ARCHIVE_READ_OPTIONS 3 -.Os -.Sh NAME -.Nm archive_read_set_filter_option , -.Nm archive_read_set_format_option , -.Nm archive_read_set_option , -.Nm archive_read_set_options -.Nd functions controlling options for reading archives -.\" -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.Ft int -.Fo archive_read_set_filter_option -.Fa "struct archive *" -.Fa "const char *module" -.Fa "const char *option" -.Fa "const char *value" -.Fc -.Ft int -.Fo archive_read_set_format_option -.Fa "struct archive *" -.Fa "const char *module" -.Fa "const char *option" -.Fa "const char *value" -.Fc -.Ft int -.Fo archive_read_set_option -.Fa "struct archive *" -.Fa "const char *module" -.Fa "const char *option" -.Fa "const char *value" -.Fc -.Ft int -.Fo archive_read_set_options -.Fa "struct archive *" -.Fa "const char *options" -.Fc -.Sh DESCRIPTION -These functions provide a way for libarchive clients to configure -specific read modules. -.Bl -tag -width indent -.It Xo -.Fn archive_read_set_filter_option , -.Fn archive_read_set_format_option -.Xc -Specifies an option that will be passed to currently-registered -filters (including decompression filters) or format readers. -.Pp -If -.Ar option -and -.Ar value -are both -.Dv NULL , -these functions will do nothing and -.Cm ARCHIVE_OK -will be returned. -If -.Ar option -is -.Dv NULL -but -.Ar value -is not, these functions will do nothing and -.Cm ARCHIVE_FAILED -will be returned. -.Pp -If -.Ar module -is not -.Dv NULL , -.Ar option -and -.Ar value -will be provided to the filter or reader named -.Ar module . -The return value will be that of the module. -If there is no such module, -.Cm ARCHIVE_FAILED -will be returned. -.Pp -If -.Ar module -is -.Dv NULL , -.Ar option -and -.Ar value -will be provided to every registered module. -If any module returns -.Cm ARCHIVE_FATAL , -this value will be returned immediately. -Otherwise, -.Cm ARCHIVE_OK -will be returned if any module accepts the option, and -.Cm ARCHIVE_FAILED -in all other cases. -.\" -.It Xo -.Fn archive_read_set_option -.Xc -Calls -.Fn archive_read_set_format_option , -then -.Fn archive_read_set_filter_option . -If either function returns -.Cm ARCHIVE_FATAL , -.Cm ARCHIVE_FATAL -will be returned -immediately. -Otherwise, greater of the two values will be returned. -.\" -.It Xo -.Fn archive_read_set_options -.Xc -.Ar options -is a comma-separated list of options. -If -.Ar options -is -.Dv NULL -or empty, -.Cm ARCHIVE_OK -will be returned immediately. -.Pp -Calls -.Fn archive_read_set_option -with each option in turn. -If any -.Fn archive_read_set_option -call returns -.Cm ARCHIVE_FATAL , -.Cm ARCHIVE_FATAL -will be returned immediately. -.Pp -Individual options have one of the following forms: -.Bl -tag -compact -width indent -.It Ar option=value -The option/value pair will be provided to every module. -Modules that do not accept an option with this name will ignore it. -.It Ar option -The option will be provided to every module with a value of -.Dq 1 . -.It Ar !option -The option will be provided to every module with a NULL value. -.It Ar module:option=value , Ar module:option , Ar module:!option -As above, but the corresponding option and value will be provided -only to modules whose name matches -.Ar module . -.El -.El -.\" -.Sh OPTIONS -.Bl -tag -compact -width indent -.It Format cab -.Bl -tag -compact -width indent -.It Cm hdrcharset -The value is used as a character set name that will be -used when translating file names. -.El -.It Format cpio -.Bl -tag -compact -width indent -.It Cm compat-2x -Libarchive 2.x incorrectly encoded Unicode filenames on -some platforms. -This option mimics the libarchive 2.x filename handling -so that such archives can be read correctly. -.It Cm hdrcharset -The value is used as a character set name that will be -used when translating file names. -.It Cm pwb -When reading a binary CPIO archive, assume that it is -in the original PWB cpio format, and handle file mode -bits accordingly. The default is to assume v7 format. -.El -.It Format iso9660 -.Bl -tag -compact -width indent -.It Cm joliet -Support Joliet extensions. -Defaults to enabled, use -.Cm !joliet -to disable. -.It Cm rockridge -Support RockRidge extensions. -Defaults to enabled, use -.Cm !rockridge -to disable. -.El -.It Format lha -.Bl -tag -compact -width indent -.It Cm hdrcharset -The value is used as a character set name that will be -used when translating file names. -.El -.It Format mtree -.Bl -tag -compact -width indent -.It Cm checkfs -Allow reading information missing from the mtree from the file system. -Disabled by default. -.El -.It Format rar -.Bl -tag -compact -width indent -.It Cm hdrcharset -The value is used as a character set name that will be -used when translating file names. -.El -.It Format tar -.Bl -tag -compact -width indent -.It Cm compat-2x -Libarchive 2.x incorrectly encoded Unicode filenames on -some platforms. -This option mimics the libarchive 2.x filename handling -so that such archives can be read correctly. -.It Cm hdrcharset -The value is used as a character set name that will be -used when translating file names. -.It Cm mac-ext -Support Mac OS metadata extension that records data in special -files beginning with a period and underscore. -Defaults to enabled on Mac OS, disabled on other platforms. -Use -.Cm !mac-ext -to disable. -.It Cm read_concatenated_archives -Ignore zeroed blocks in the archive, which occurs when multiple tar archives -have been concatenated together. -Without this option, only the contents of -the first concatenated archive would be read. -.El -.It Format zip -.Bl -tag -compact -width indent -.It Cm compat-2x -Libarchive 2.x incorrectly encoded Unicode filenames on -some platforms. -This option mimics the libarchive 2.x filename handling -so that such archives can be read correctly. -.It Cm hdrcharset -The value is used as a character set name that will be -used when translating file names. -.It Cm ignorecrc32 -Skip the CRC32 check. -Mostly used for testing. -.It Cm mac-ext -Support Mac OS metadata extension that records data in special -files beginning with a period and underscore. -Defaults to enabled on Mac OS, disabled on other platforms. -Use -.Cm !mac-ext -to disable. -.El -.El -.\" -.Sh ERRORS -Detailed error codes and textual descriptions are available from the -.Fn archive_errno -and -.Fn archive_error_string -functions. -.\" -.Sh SEE ALSO -.Xr tar 1 , -.Xr archive_read 3 , -.Xr archive_write_set_options 3 , -.Xr libarchive 3 diff --git a/thirdparty/libarchive/libarchive/archive_read_set_options.c b/thirdparty/libarchive/libarchive/archive_read_set_options.c deleted file mode 100644 index 2bd9b811e..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_set_options.c +++ /dev/null @@ -1,133 +0,0 @@ -/*- - * Copyright (c) 2011 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#include "archive_read_private.h" -#include "archive_options_private.h" - -static int archive_set_format_option(struct archive *a, - const char *m, const char *o, const char *v); -static int archive_set_filter_option(struct archive *a, - const char *m, const char *o, const char *v); -static int archive_set_option(struct archive *a, - const char *m, const char *o, const char *v); - -int -archive_read_set_format_option(struct archive *a, const char *m, const char *o, - const char *v) -{ - return _archive_set_option(a, m, o, v, - ARCHIVE_READ_MAGIC, "archive_read_set_format_option", - archive_set_format_option); -} - -int -archive_read_set_filter_option(struct archive *a, const char *m, const char *o, - const char *v) -{ - return _archive_set_option(a, m, o, v, - ARCHIVE_READ_MAGIC, "archive_read_set_filter_option", - archive_set_filter_option); -} - -int -archive_read_set_option(struct archive *a, const char *m, const char *o, - const char *v) -{ - return _archive_set_option(a, m, o, v, - ARCHIVE_READ_MAGIC, "archive_read_set_option", - archive_set_option); -} - -int -archive_read_set_options(struct archive *a, const char *options) -{ - return _archive_set_options(a, options, - ARCHIVE_READ_MAGIC, "archive_read_set_options", - archive_set_option); -} - -static int -archive_set_format_option(struct archive *_a, const char *m, const char *o, - const char *v) -{ - struct archive_read *a = (struct archive_read *)_a; - size_t i; - int r, rv = ARCHIVE_WARN, matched_modules = 0; - - for (i = 0; i < sizeof(a->formats)/sizeof(a->formats[0]); i++) { - struct archive_format_descriptor *format = &a->formats[i]; - - if (format->options == NULL || format->name == NULL) - /* This format does not support option. */ - continue; - if (m != NULL) { - if (strcmp(format->name, m) != 0) - continue; - ++matched_modules; - } - - a->format = format; - r = format->options(a, o, v); - a->format = NULL; - - if (r == ARCHIVE_FATAL) - return (ARCHIVE_FATAL); - - if (r == ARCHIVE_OK) - rv = ARCHIVE_OK; - } - /* If the format name didn't match, return a special code for - * _archive_set_option[s]. */ - if (m != NULL && matched_modules == 0) - return ARCHIVE_WARN - 1; - return (rv); -} - -static int -archive_set_filter_option(struct archive *_a, const char *m, const char *o, - const char *v) -{ - (void)_a; /* UNUSED */ - (void)o; /* UNUSED */ - (void)v; /* UNUSED */ - - /* If the filter name didn't match, return a special code for - * _archive_set_option[s]. */ - if (m != NULL) - return ARCHIVE_WARN - 1; - return ARCHIVE_WARN; -} - -static int -archive_set_option(struct archive *a, const char *m, const char *o, - const char *v) -{ - return _archive_set_either_option(a, m, o, v, - archive_set_format_option, - archive_set_filter_option); -} diff --git a/thirdparty/libarchive/libarchive/archive_read_support_filter_all.c b/thirdparty/libarchive/libarchive/archive_read_support_filter_all.c deleted file mode 100644 index edb508c1d..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_filter_all.c +++ /dev/null @@ -1,85 +0,0 @@ -/*- - * Copyright (c) 2003-2011 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#include "archive.h" -#include "archive_private.h" - -#if ARCHIVE_VERSION_NUMBER < 4000000 -/* Deprecated; remove in libarchive 4.0 */ -int -archive_read_support_compression_all(struct archive *a) -{ - return archive_read_support_filter_all(a); -} -#endif - -int -archive_read_support_filter_all(struct archive *a) -{ - archive_check_magic(a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_filter_all"); - - /* Bzip falls back to "bunzip2" command-line */ - archive_read_support_filter_bzip2(a); - /* The decompress code doesn't use an outside library. */ - archive_read_support_filter_compress(a); - /* Gzip decompress falls back to "gzip -d" command-line. */ - archive_read_support_filter_gzip(a); - /* Lzip falls back to "unlzip" command-line program. */ - archive_read_support_filter_lzip(a); - /* The LZMA file format has a very weak signature, so it - * may not be feasible to keep this here, but we'll try. - * This will come back out if there are problems. */ - /* Lzma falls back to "unlzma" command-line program. */ - archive_read_support_filter_lzma(a); - /* Xz falls back to "unxz" command-line program. */ - archive_read_support_filter_xz(a); - /* The decode code doesn't use an outside library. */ - archive_read_support_filter_uu(a); - /* The decode code doesn't use an outside library. */ - archive_read_support_filter_rpm(a); - /* The decode code always uses "lrzip -q -d" command-line. */ - archive_read_support_filter_lrzip(a); - /* Lzop decompress falls back to "lzop -d" command-line. */ - archive_read_support_filter_lzop(a); - /* The decode code always uses "grzip -d" command-line. */ - archive_read_support_filter_grzip(a); - /* Lz4 falls back to "lz4 -d" command-line program. */ - archive_read_support_filter_lz4(a); - /* Zstd falls back to "zstd -d" command-line program. */ - archive_read_support_filter_zstd(a); - - /* Note: We always return ARCHIVE_OK here, even if some of the - * above return ARCHIVE_WARN. The intent here is to enable - * "as much as possible." Clients who need specific - * compression should enable those individually so they can - * verify the level of support. */ - /* Clear any warning messages set by the above functions. */ - archive_clear_error(a); - return (ARCHIVE_OK); -} diff --git a/thirdparty/libarchive/libarchive/archive_read_support_filter_by_code.c b/thirdparty/libarchive/libarchive/archive_read_support_filter_by_code.c deleted file mode 100644 index 94c4af695..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_filter_by_code.c +++ /dev/null @@ -1,83 +0,0 @@ -/*- - * Copyright (c) 2020 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#include "archive.h" -#include "archive_private.h" - -int -archive_read_support_filter_by_code(struct archive *a, int filter_code) -{ - archive_check_magic(a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_filter_by_code"); - - switch (filter_code) { - case ARCHIVE_FILTER_NONE: - return archive_read_support_filter_none(a); - break; - case ARCHIVE_FILTER_GZIP: - return archive_read_support_filter_gzip(a); - break; - case ARCHIVE_FILTER_BZIP2: - return archive_read_support_filter_bzip2(a); - break; - case ARCHIVE_FILTER_COMPRESS: - return archive_read_support_filter_compress(a); - break; - case ARCHIVE_FILTER_LZMA: - return archive_read_support_filter_lzma(a); - break; - case ARCHIVE_FILTER_XZ: - return archive_read_support_filter_xz(a); - break; - case ARCHIVE_FILTER_UU: - return archive_read_support_filter_uu(a); - break; - case ARCHIVE_FILTER_RPM: - return archive_read_support_filter_rpm(a); - break; - case ARCHIVE_FILTER_LZIP: - return archive_read_support_filter_lzip(a); - break; - case ARCHIVE_FILTER_LRZIP: - return archive_read_support_filter_lrzip(a); - break; - case ARCHIVE_FILTER_LZOP: - return archive_read_support_filter_lzop(a); - break; - case ARCHIVE_FILTER_GRZIP: - return archive_read_support_filter_grzip(a); - break; - case ARCHIVE_FILTER_LZ4: - return archive_read_support_filter_lz4(a); - break; - case ARCHIVE_FILTER_ZSTD: - return archive_read_support_filter_zstd(a); - break; - } - return (ARCHIVE_FATAL); -} diff --git a/thirdparty/libarchive/libarchive/archive_read_support_filter_bzip2.c b/thirdparty/libarchive/libarchive/archive_read_support_filter_bzip2.c deleted file mode 100644 index 9158e668e..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_filter_bzip2.c +++ /dev/null @@ -1,365 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_BZLIB_H -#include -#endif - -#include "archive.h" -#include "archive_private.h" -#include "archive_read_private.h" - -#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) -struct private_data { - bz_stream stream; - char *out_block; - size_t out_block_size; - char valid; /* True = decompressor is initialized */ - char eof; /* True = found end of compressed data. */ -}; - -/* Bzip2 filter */ -static ssize_t bzip2_filter_read(struct archive_read_filter *, const void **); -static int bzip2_filter_close(struct archive_read_filter *); -#endif - -/* - * Note that we can detect bzip2 archives even if we can't decompress - * them. (In fact, we like detecting them because we can give better - * error messages.) So the bid framework here gets compiled even - * if bzlib is unavailable. - */ -static int bzip2_reader_bid(struct archive_read_filter_bidder *, struct archive_read_filter *); -static int bzip2_reader_init(struct archive_read_filter *); - -#if ARCHIVE_VERSION_NUMBER < 4000000 -/* Deprecated; remove in libarchive 4.0 */ -int -archive_read_support_compression_bzip2(struct archive *a) -{ - return archive_read_support_filter_bzip2(a); -} -#endif - -static const struct archive_read_filter_bidder_vtable -bzip2_bidder_vtable = { - .bid = bzip2_reader_bid, - .init = bzip2_reader_init, -}; - -int -archive_read_support_filter_bzip2(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - - if (__archive_read_register_bidder(a, NULL, "bzip2", - &bzip2_bidder_vtable) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - -#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) - return (ARCHIVE_OK); -#else - archive_set_error(_a, ARCHIVE_ERRNO_MISC, - "Using external bzip2 program"); - return (ARCHIVE_WARN); -#endif -} - -/* - * Test whether we can handle this data. - * - * This logic returns zero if any part of the signature fails. It - * also tries to Do The Right Thing if a very short buffer prevents us - * from verifying as much as we would like. - */ -static int -bzip2_reader_bid(struct archive_read_filter_bidder *self, struct archive_read_filter *filter) -{ - const unsigned char *buffer; - ssize_t avail; - int bits_checked; - - (void)self; /* UNUSED */ - - /* Minimal bzip2 archive is 14 bytes. */ - buffer = __archive_read_filter_ahead(filter, 14, &avail); - if (buffer == NULL) - return (0); - - /* First three bytes must be "BZh" */ - bits_checked = 0; - if (memcmp(buffer, "BZh", 3) != 0) - return (0); - bits_checked += 24; - - /* Next follows a compression flag which must be an ASCII digit. */ - if (buffer[3] < '1' || buffer[3] > '9') - return (0); - bits_checked += 5; - - /* After BZh[1-9], there must be either a data block - * which begins with 0x314159265359 or an end-of-data - * marker of 0x177245385090. */ - if (memcmp(buffer + 4, "\x31\x41\x59\x26\x53\x59", 6) == 0) - bits_checked += 48; - else if (memcmp(buffer + 4, "\x17\x72\x45\x38\x50\x90", 6) == 0) - bits_checked += 48; - else - return (0); - - return (bits_checked); -} - -#if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR) - -/* - * If we don't have the library on this system, we can't actually do the - * decompression. We can, however, still detect compressed archives - * and emit a useful message. - */ -static int -bzip2_reader_init(struct archive_read_filter *self) -{ - int r; - - r = __archive_read_program(self, "bzip2 -d"); - /* Note: We set the format here even if __archive_read_program() - * above fails. We do, after all, know what the format is - * even if we weren't able to read it. */ - self->code = ARCHIVE_FILTER_BZIP2; - self->name = "bzip2"; - return (r); -} - - -#else - -static const struct archive_read_filter_vtable -bzip2_reader_vtable = { - .read = bzip2_filter_read, - .close = bzip2_filter_close, -}; - -/* - * Setup the callbacks. - */ -static int -bzip2_reader_init(struct archive_read_filter *self) -{ - static const size_t out_block_size = 64 * 1024; - void *out_block; - struct private_data *state; - - self->code = ARCHIVE_FILTER_BZIP2; - self->name = "bzip2"; - - state = (struct private_data *)calloc(sizeof(*state), 1); - out_block = (unsigned char *)malloc(out_block_size); - if (state == NULL || out_block == NULL) { - archive_set_error(&self->archive->archive, ENOMEM, - "Can't allocate data for bzip2 decompression"); - free(out_block); - free(state); - return (ARCHIVE_FATAL); - } - - self->data = state; - state->out_block_size = out_block_size; - state->out_block = out_block; - self->vtable = &bzip2_reader_vtable; - - return (ARCHIVE_OK); -} - -/* - * Return the next block of decompressed data. - */ -static ssize_t -bzip2_filter_read(struct archive_read_filter *self, const void **p) -{ - struct private_data *state; - size_t decompressed; - const char *read_buf; - ssize_t ret; - - state = (struct private_data *)self->data; - - if (state->eof) { - *p = NULL; - return (0); - } - - /* Empty our output buffer. */ - state->stream.next_out = state->out_block; - state->stream.avail_out = (uint32_t)state->out_block_size; - - /* Try to fill the output buffer. */ - for (;;) { - if (!state->valid) { - if (bzip2_reader_bid(self->bidder, self->upstream) == 0) { - state->eof = 1; - *p = state->out_block; - decompressed = state->stream.next_out - - state->out_block; - return (decompressed); - } - /* Initialize compression library. */ - ret = BZ2_bzDecompressInit(&(state->stream), - 0 /* library verbosity */, - 0 /* don't use low-mem algorithm */); - - /* If init fails, try low-memory algorithm instead. */ - if (ret == BZ_MEM_ERROR) - ret = BZ2_bzDecompressInit(&(state->stream), - 0 /* library verbosity */, - 1 /* do use low-mem algo */); - - if (ret != BZ_OK) { - const char *detail = NULL; - int err = ARCHIVE_ERRNO_MISC; - switch (ret) { - case BZ_PARAM_ERROR: - detail = "invalid setup parameter"; - break; - case BZ_MEM_ERROR: - err = ENOMEM; - detail = "out of memory"; - break; - case BZ_CONFIG_ERROR: - detail = "mis-compiled library"; - break; - } - archive_set_error(&self->archive->archive, err, - "Internal error initializing decompressor%s%s", - detail == NULL ? "" : ": ", - detail); - return (ARCHIVE_FATAL); - } - state->valid = 1; - } - - /* stream.next_in is really const, but bzlib - * doesn't declare it so. */ - read_buf = - __archive_read_filter_ahead(self->upstream, 1, &ret); - if (read_buf == NULL) { - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "truncated bzip2 input"); - return (ARCHIVE_FATAL); - } - state->stream.next_in = (char *)(uintptr_t)read_buf; - state->stream.avail_in = (uint32_t)ret; - /* There is no more data, return whatever we have. */ - if (ret == 0) { - state->eof = 1; - *p = state->out_block; - decompressed = state->stream.next_out - - state->out_block; - return (decompressed); - } - - /* Decompress as much as we can in one pass. */ - ret = BZ2_bzDecompress(&(state->stream)); - __archive_read_filter_consume(self->upstream, - state->stream.next_in - read_buf); - - switch (ret) { - case BZ_STREAM_END: /* Found end of stream. */ - switch (BZ2_bzDecompressEnd(&(state->stream))) { - case BZ_OK: - break; - default: - archive_set_error(&(self->archive->archive), - ARCHIVE_ERRNO_MISC, - "Failed to clean up decompressor"); - return (ARCHIVE_FATAL); - } - state->valid = 0; - /* FALLTHROUGH */ - case BZ_OK: /* Decompressor made some progress. */ - /* If we filled our buffer, update stats and return. */ - if (state->stream.avail_out == 0) { - *p = state->out_block; - decompressed = state->stream.next_out - - state->out_block; - return (decompressed); - } - break; - default: /* Return an error. */ - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, "bzip decompression failed"); - return (ARCHIVE_FATAL); - } - } -} - -/* - * Clean up the decompressor. - */ -static int -bzip2_filter_close(struct archive_read_filter *self) -{ - struct private_data *state; - int ret = ARCHIVE_OK; - - state = (struct private_data *)self->data; - - if (state->valid) { - switch (BZ2_bzDecompressEnd(&state->stream)) { - case BZ_OK: - break; - default: - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Failed to clean up decompressor"); - ret = ARCHIVE_FATAL; - } - state->valid = 0; - } - - free(state->out_block); - free(state); - return (ret); -} - -#endif /* HAVE_BZLIB_H && BZ_CONFIG_ERROR */ diff --git a/thirdparty/libarchive/libarchive/archive_read_support_filter_compress.c b/thirdparty/libarchive/libarchive/archive_read_support_filter_compress.c deleted file mode 100644 index 05b80a576..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_filter_compress.c +++ /dev/null @@ -1,452 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -/* - * This code borrows heavily from "compress" source code, which is - * protected by the following copyright. (Clause 3 dropped by request - * of the Regents.) - */ - -/*- - * Copyright (c) 1985, 1986, 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Diomidis Spinellis and James A. Woods, derived from original - * work by Spencer Thomas and Joseph Orost. - * - * 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. - * 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. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. - */ - - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif - -#include "archive.h" -#include "archive_private.h" -#include "archive_read_private.h" - -/* - * Because LZW decompression is pretty simple, I've just implemented - * the whole decompressor here (cribbing from "compress" source code, - * of course), rather than relying on an external library. I have - * made an effort to clarify and simplify the algorithm, so the - * names and structure here don't exactly match those used by compress. - */ - -struct private_data { - /* Input variables. */ - const unsigned char *next_in; - size_t avail_in; - size_t consume_unnotified; - int bit_buffer; - int bits_avail; - size_t bytes_in_section; - - /* Output variables. */ - size_t out_block_size; - void *out_block; - - /* Decompression status variables. */ - int use_reset_code; - int end_of_stream; /* EOF status. */ - int maxcode; /* Largest code. */ - int maxcode_bits; /* Length of largest code. */ - int section_end_code; /* When to increase bits. */ - int bits; /* Current code length. */ - int oldcode; /* Previous code. */ - int finbyte; /* Last byte of prev code. */ - - /* Dictionary. */ - int free_ent; /* Next dictionary entry. */ - unsigned char suffix[65536]; - uint16_t prefix[65536]; - - /* - * Scratch area for expanding dictionary entries. Note: - * "worst" case here comes from compressing /dev/zero: the - * last code in the dictionary will code a sequence of - * 65536-256 zero bytes. Thus, we need stack space to expand - * a 65280-byte dictionary entry. (Of course, 32640:1 - * compression could also be considered the "best" case. ;-) - */ - unsigned char *stackp; - unsigned char stack[65300]; -}; - -static int compress_bidder_bid(struct archive_read_filter_bidder *, struct archive_read_filter *); -static int compress_bidder_init(struct archive_read_filter *); - -static ssize_t compress_filter_read(struct archive_read_filter *, const void **); -static int compress_filter_close(struct archive_read_filter *); - -static int getbits(struct archive_read_filter *, int n); -static int next_code(struct archive_read_filter *); - -#if ARCHIVE_VERSION_NUMBER < 4000000 -/* Deprecated; remove in libarchive 4.0 */ -int -archive_read_support_compression_compress(struct archive *a) -{ - return archive_read_support_filter_compress(a); -} -#endif - -static const struct archive_read_filter_bidder_vtable -compress_bidder_vtable = { - .bid = compress_bidder_bid, - .init = compress_bidder_init, -}; - -int -archive_read_support_filter_compress(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - - return __archive_read_register_bidder(a, NULL, "compress (.Z)", - &compress_bidder_vtable); -} - -/* - * Test whether we can handle this data. - * This logic returns zero if any part of the signature fails. - */ -static int -compress_bidder_bid(struct archive_read_filter_bidder *self, - struct archive_read_filter *filter) -{ - const unsigned char *buffer; - ssize_t avail; - int bits_checked; - - (void)self; /* UNUSED */ - - /* Shortest valid compress file is 3 bytes. */ - buffer = __archive_read_filter_ahead(filter, 3, &avail); - - if (buffer == NULL) - return (0); - - bits_checked = 0; - /* First two bytes are the magic value */ - if (buffer[0] != 0x1F || buffer[1] != 0x9D) - return (0); - /* Third byte holds compression parameters. */ - if (buffer[2] & 0x20) /* Reserved bit, must be zero. */ - return (0); - if (buffer[2] & 0x40) /* Reserved bit, must be zero. */ - return (0); - bits_checked += 18; - - return (bits_checked); -} - -static const struct archive_read_filter_vtable -compress_reader_vtable = { - .read = compress_filter_read, - .close = compress_filter_close, -}; - -/* - * Setup the callbacks. - */ -static int -compress_bidder_init(struct archive_read_filter *self) -{ - struct private_data *state; - static const size_t out_block_size = 64 * 1024; - void *out_block; - int code; - - self->code = ARCHIVE_FILTER_COMPRESS; - self->name = "compress (.Z)"; - - state = (struct private_data *)calloc(sizeof(*state), 1); - out_block = malloc(out_block_size); - if (state == NULL || out_block == NULL) { - free(out_block); - free(state); - archive_set_error(&self->archive->archive, ENOMEM, - "Can't allocate data for %s decompression", - self->name); - return (ARCHIVE_FATAL); - } - - self->data = state; - state->out_block_size = out_block_size; - state->out_block = out_block; - self->vtable = &compress_reader_vtable; - - /* XXX MOVE THE FOLLOWING OUT OF INIT() XXX */ - - (void)getbits(self, 8); /* Skip first signature byte. */ - (void)getbits(self, 8); /* Skip second signature byte. */ - - /* Get compression parameters. */ - code = getbits(self, 8); - if ((code & 0x1f) > 16) { - archive_set_error(&self->archive->archive, -1, - "Invalid compressed data"); - return (ARCHIVE_FATAL); - } - state->maxcode_bits = code & 0x1f; - state->maxcode = (1 << state->maxcode_bits); - state->use_reset_code = code & 0x80; - - /* Initialize decompressor. */ - state->free_ent = 256; - state->stackp = state->stack; - if (state->use_reset_code) - state->free_ent++; - state->bits = 9; - state->section_end_code = (1<bits) - 1; - state->oldcode = -1; - for (code = 255; code >= 0; code--) { - state->prefix[code] = 0; - state->suffix[code] = code; - } - next_code(self); - - return (ARCHIVE_OK); -} - -/* - * Return a block of data from the decompression buffer. Decompress more - * as necessary. - */ -static ssize_t -compress_filter_read(struct archive_read_filter *self, const void **pblock) -{ - struct private_data *state; - unsigned char *p, *start, *end; - int ret; - - state = (struct private_data *)self->data; - if (state->end_of_stream) { - *pblock = NULL; - return (0); - } - p = start = (unsigned char *)state->out_block; - end = start + state->out_block_size; - - while (p < end && !state->end_of_stream) { - if (state->stackp > state->stack) { - *p++ = *--state->stackp; - } else { - ret = next_code(self); - if (ret == -1) - state->end_of_stream = ret; - else if (ret != ARCHIVE_OK) - return (ret); - } - } - - *pblock = start; - return (p - start); -} - -/* - * Close and release the filter. - */ -static int -compress_filter_close(struct archive_read_filter *self) -{ - struct private_data *state = (struct private_data *)self->data; - - free(state->out_block); - free(state); - return (ARCHIVE_OK); -} - -/* - * Process the next code and fill the stack with the expansion - * of the code. Returns ARCHIVE_FATAL if there is a fatal I/O or - * format error, ARCHIVE_EOF if we hit end of data, ARCHIVE_OK otherwise. - */ -static int -next_code(struct archive_read_filter *self) -{ - struct private_data *state = (struct private_data *)self->data; - int code, newcode; - - static int debug_buff[1024]; - static unsigned debug_index; - - code = newcode = getbits(self, state->bits); - if (code < 0) - return (code); - - debug_buff[debug_index++] = code; - if (debug_index >= sizeof(debug_buff)/sizeof(debug_buff[0])) - debug_index = 0; - - /* If it's a reset code, reset the dictionary. */ - if ((code == 256) && state->use_reset_code) { - /* - * The original 'compress' implementation blocked its - * I/O in a manner that resulted in junk bytes being - * inserted after every reset. The next section skips - * this junk. (Yes, the number of *bytes* to skip is - * a function of the current *bit* length.) - */ - int skip_bytes = state->bits - - (state->bytes_in_section % state->bits); - skip_bytes %= state->bits; - state->bits_avail = 0; /* Discard rest of this byte. */ - while (skip_bytes-- > 0) { - code = getbits(self, 8); - if (code < 0) - return (code); - } - /* Now, actually do the reset. */ - state->bytes_in_section = 0; - state->bits = 9; - state->section_end_code = (1 << state->bits) - 1; - state->free_ent = 257; - state->oldcode = -1; - return (next_code(self)); - } - - if (code > state->free_ent - || (code == state->free_ent && state->oldcode < 0)) { - /* An invalid code is a fatal error. */ - archive_set_error(&(self->archive->archive), -1, - "Invalid compressed data"); - return (ARCHIVE_FATAL); - } - - /* Special case for KwKwK string. */ - if (code >= state->free_ent) { - *state->stackp++ = state->finbyte; - code = state->oldcode; - } - - /* Generate output characters in reverse order. */ - while (code >= 256) { - *state->stackp++ = state->suffix[code]; - code = state->prefix[code]; - } - *state->stackp++ = state->finbyte = code; - - /* Generate the new entry. */ - code = state->free_ent; - if (code < state->maxcode && state->oldcode >= 0) { - state->prefix[code] = state->oldcode; - state->suffix[code] = state->finbyte; - ++state->free_ent; - } - if (state->free_ent > state->section_end_code) { - state->bits++; - state->bytes_in_section = 0; - if (state->bits == state->maxcode_bits) - state->section_end_code = state->maxcode; - else - state->section_end_code = (1 << state->bits) - 1; - } - - /* Remember previous code. */ - state->oldcode = newcode; - return (ARCHIVE_OK); -} - -/* - * Return next 'n' bits from stream. - * - * -1 indicates end of available data. - */ -static int -getbits(struct archive_read_filter *self, int n) -{ - struct private_data *state = (struct private_data *)self->data; - int code; - ssize_t ret; - static const int mask[] = { - 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff, - 0x1ff, 0x3ff, 0x7ff, 0xfff, 0x1fff, 0x3fff, 0x7fff, 0xffff - }; - - while (state->bits_avail < n) { - if (state->avail_in <= 0) { - if (state->consume_unnotified) { - __archive_read_filter_consume(self->upstream, - state->consume_unnotified); - state->consume_unnotified = 0; - } - state->next_in - = __archive_read_filter_ahead(self->upstream, - 1, &ret); - if (ret == 0) - return (-1); - if (ret < 0 || state->next_in == NULL) - return (ARCHIVE_FATAL); - state->consume_unnotified = state->avail_in = ret; - } - state->bit_buffer |= *state->next_in++ << state->bits_avail; - state->avail_in--; - state->bits_avail += 8; - state->bytes_in_section++; - } - - code = state->bit_buffer; - state->bit_buffer >>= n; - state->bits_avail -= n; - - return (code & mask[n]); -} diff --git a/thirdparty/libarchive/libarchive/archive_read_support_filter_grzip.c b/thirdparty/libarchive/libarchive/archive_read_support_filter_grzip.c deleted file mode 100644 index d4d1737cd..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_filter_grzip.c +++ /dev/null @@ -1,112 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -__FBSDID("$FreeBSD$"); - - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif - -#include "archive.h" -#include "archive_private.h" -#include "archive_read_private.h" - -static const unsigned char grzip_magic[] = { - 0x47, 0x52, 0x5a, 0x69, 0x70, 0x49, 0x49, 0x00, - 0x02, 0x04, 0x3a, 0x29 }; - -static int grzip_bidder_bid(struct archive_read_filter_bidder *, - struct archive_read_filter *); -static int grzip_bidder_init(struct archive_read_filter *); - - -static const struct archive_read_filter_bidder_vtable -grzip_bidder_vtable = { - .bid = grzip_bidder_bid, - .init = grzip_bidder_init, -}; - -int -archive_read_support_filter_grzip(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - - if (__archive_read_register_bidder(a, NULL, NULL, - &grzip_bidder_vtable) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - /* This filter always uses an external program. */ - archive_set_error(_a, ARCHIVE_ERRNO_MISC, - "Using external grzip program for grzip decompression"); - return (ARCHIVE_WARN); -} - -/* - * Bidder just verifies the header and returns the number of verified bits. - */ -static int -grzip_bidder_bid(struct archive_read_filter_bidder *self, - struct archive_read_filter *filter) -{ - const unsigned char *p; - ssize_t avail; - - (void)self; /* UNUSED */ - - p = __archive_read_filter_ahead(filter, sizeof(grzip_magic), &avail); - if (p == NULL || avail == 0) - return (0); - - if (memcmp(p, grzip_magic, sizeof(grzip_magic))) - return (0); - - return (sizeof(grzip_magic) * 8); -} - -static int -grzip_bidder_init(struct archive_read_filter *self) -{ - int r; - - r = __archive_read_program(self, "grzip -d"); - /* Note: We set the format here even if __archive_read_program() - * above fails. We do, after all, know what the format is - * even if we weren't able to read it. */ - self->code = ARCHIVE_FILTER_GRZIP; - self->name = "grzip"; - return (r); -} diff --git a/thirdparty/libarchive/libarchive/archive_read_support_filter_gzip.c b/thirdparty/libarchive/libarchive/archive_read_support_filter_gzip.c deleted file mode 100644 index 4135a6361..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_filter_gzip.c +++ /dev/null @@ -1,536 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -__FBSDID("$FreeBSD$"); - - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_LIMITS_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_ZLIB_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" -#include "archive_endian.h" -#include "archive_private.h" -#include "archive_read_private.h" - -#ifdef HAVE_ZLIB_H -struct private_data { - z_stream stream; - char in_stream; - unsigned char *out_block; - size_t out_block_size; - int64_t total_out; - unsigned long crc; - uint32_t mtime; - char *name; - char eof; /* True = found end of compressed data. */ -}; - -/* Gzip Filter. */ -static ssize_t gzip_filter_read(struct archive_read_filter *, const void **); -static int gzip_filter_close(struct archive_read_filter *); -#endif - -/* - * Note that we can detect gzip archives even if we can't decompress - * them. (In fact, we like detecting them because we can give better - * error messages.) So the bid framework here gets compiled even - * if zlib is unavailable. - * - * TODO: If zlib is unavailable, gzip_bidder_init() should - * use the compress_program framework to try to fire up an external - * gzip program. - */ -static int gzip_bidder_bid(struct archive_read_filter_bidder *, - struct archive_read_filter *); -static int gzip_bidder_init(struct archive_read_filter *); - -#if ARCHIVE_VERSION_NUMBER < 4000000 -/* Deprecated; remove in libarchive 4.0 */ -int -archive_read_support_compression_gzip(struct archive *a) -{ - return archive_read_support_filter_gzip(a); -} -#endif - -static const struct archive_read_filter_bidder_vtable -gzip_bidder_vtable = { - .bid = gzip_bidder_bid, - .init = gzip_bidder_init, -}; - -int -archive_read_support_filter_gzip(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - - if (__archive_read_register_bidder(a, NULL, "gzip", - &gzip_bidder_vtable) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - /* Signal the extent of gzip support with the return value here. */ -#if HAVE_ZLIB_H - return (ARCHIVE_OK); -#else - archive_set_error(_a, ARCHIVE_ERRNO_MISC, - "Using external gzip program"); - return (ARCHIVE_WARN); -#endif -} - -/* - * Read and verify the header. - * - * Returns zero if the header couldn't be validated, else returns - * number of bytes in header. If pbits is non-NULL, it receives a - * count of bits verified, suitable for use by bidder. - */ -static ssize_t -peek_at_header(struct archive_read_filter *filter, int *pbits, -#ifdef HAVE_ZLIB_H - struct private_data *state -#else - void *state -#endif - ) -{ - const unsigned char *p; - ssize_t avail, len; - int bits = 0; - int header_flags; -#ifndef HAVE_ZLIB_H - (void)state; /* UNUSED */ -#endif - - /* Start by looking at the first ten bytes of the header, which - * is all fixed layout. */ - len = 10; - p = __archive_read_filter_ahead(filter, len, &avail); - if (p == NULL || avail == 0) - return (0); - /* We only support deflation- third byte must be 0x08. */ - if (memcmp(p, "\x1F\x8B\x08", 3) != 0) - return (0); - bits += 24; - if ((p[3] & 0xE0)!= 0) /* No reserved flags set. */ - return (0); - bits += 3; - header_flags = p[3]; - /* Bytes 4-7 are mod time in little endian. */ -#ifdef HAVE_ZLIB_H - if (state) - state->mtime = archive_le32dec(p + 4); -#endif - /* Byte 8 is deflate flags. */ - /* XXXX TODO: return deflate flags back to consume_header for use - in initializing the decompressor. */ - /* Byte 9 is OS. */ - - /* Optional extra data: 2 byte length plus variable body. */ - if (header_flags & 4) { - p = __archive_read_filter_ahead(filter, len + 2, &avail); - if (p == NULL) - return (0); - len += ((int)p[len + 1] << 8) | (int)p[len]; - len += 2; - } - - /* Null-terminated optional filename. */ - if (header_flags & 8) { -#ifdef HAVE_ZLIB_H - ssize_t file_start = len; -#endif - do { - ++len; - if (avail < len) - p = __archive_read_filter_ahead(filter, - len, &avail); - if (p == NULL) - return (0); - } while (p[len - 1] != 0); - -#ifdef HAVE_ZLIB_H - if (state) { - /* Reset the name in case of repeat header reads. */ - free(state->name); - state->name = strdup((const char *)&p[file_start]); - } -#endif - } - - /* Null-terminated optional comment. */ - if (header_flags & 16) { - do { - ++len; - if (avail < len) - p = __archive_read_filter_ahead(filter, - len, &avail); - if (p == NULL) - return (0); - } while (p[len - 1] != 0); - } - - /* Optional header CRC */ - if ((header_flags & 2)) { - p = __archive_read_filter_ahead(filter, len + 2, &avail); - if (p == NULL) - return (0); -#if 0 - int hcrc = ((int)p[len + 1] << 8) | (int)p[len]; - int crc = /* XXX TODO: Compute header CRC. */; - if (crc != hcrc) - return (0); - bits += 16; -#endif - len += 2; - } - - if (pbits != NULL) - *pbits = bits; - return (len); -} - -/* - * Bidder just verifies the header and returns the number of verified bits. - */ -static int -gzip_bidder_bid(struct archive_read_filter_bidder *self, - struct archive_read_filter *filter) -{ - int bits_checked; - - (void)self; /* UNUSED */ - - if (peek_at_header(filter, &bits_checked, NULL)) - return (bits_checked); - return (0); -} - -#ifndef HAVE_ZLIB_H - -/* - * If we don't have the library on this system, we can't do the - * decompression directly. We can, however, try to run "gzip -d" - * in case that's available. - */ -static int -gzip_bidder_init(struct archive_read_filter *self) -{ - int r; - - r = __archive_read_program(self, "gzip -d"); - /* Note: We set the format here even if __archive_read_program() - * above fails. We do, after all, know what the format is - * even if we weren't able to read it. */ - self->code = ARCHIVE_FILTER_GZIP; - self->name = "gzip"; - return (r); -} - -#else - -static int -gzip_read_header(struct archive_read_filter *self, struct archive_entry *entry) -{ - struct private_data *state; - - state = (struct private_data *)self->data; - - /* A mtime of 0 is considered invalid/missing. */ - if (state->mtime != 0) - archive_entry_set_mtime(entry, state->mtime, 0); - - /* If the name is available, extract it. */ - if (state->name) - archive_entry_set_pathname(entry, state->name); - - return (ARCHIVE_OK); -} - -static const struct archive_read_filter_vtable -gzip_reader_vtable = { - .read = gzip_filter_read, - .close = gzip_filter_close, -#ifdef HAVE_ZLIB_H - .read_header = gzip_read_header, -#endif -}; - -/* - * Initialize the filter object. - */ -static int -gzip_bidder_init(struct archive_read_filter *self) -{ - struct private_data *state; - static const size_t out_block_size = 64 * 1024; - void *out_block; - - self->code = ARCHIVE_FILTER_GZIP; - self->name = "gzip"; - - state = (struct private_data *)calloc(sizeof(*state), 1); - out_block = (unsigned char *)malloc(out_block_size); - if (state == NULL || out_block == NULL) { - free(out_block); - free(state); - archive_set_error(&self->archive->archive, ENOMEM, - "Can't allocate data for gzip decompression"); - return (ARCHIVE_FATAL); - } - - self->data = state; - state->out_block_size = out_block_size; - state->out_block = out_block; - self->vtable = &gzip_reader_vtable; - - state->in_stream = 0; /* We're not actually within a stream yet. */ - - return (ARCHIVE_OK); -} - -static int -consume_header(struct archive_read_filter *self) -{ - struct private_data *state; - ssize_t avail; - size_t len; - int ret; - - state = (struct private_data *)self->data; - - /* If this is a real header, consume it. */ - len = peek_at_header(self->upstream, NULL, state); - if (len == 0) - return (ARCHIVE_EOF); - __archive_read_filter_consume(self->upstream, len); - - /* Initialize CRC accumulator. */ - state->crc = crc32(0L, NULL, 0); - - /* Initialize compression library. */ - state->stream.next_in = (unsigned char *)(uintptr_t) - __archive_read_filter_ahead(self->upstream, 1, &avail); - state->stream.avail_in = (uInt)avail; - ret = inflateInit2(&(state->stream), - -15 /* Don't check for zlib header */); - - /* Decipher the error code. */ - switch (ret) { - case Z_OK: - state->in_stream = 1; - return (ARCHIVE_OK); - case Z_STREAM_ERROR: - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Internal error initializing compression library: " - "invalid setup parameter"); - break; - case Z_MEM_ERROR: - archive_set_error(&self->archive->archive, ENOMEM, - "Internal error initializing compression library: " - "out of memory"); - break; - case Z_VERSION_ERROR: - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Internal error initializing compression library: " - "invalid library version"); - break; - default: - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Internal error initializing compression library: " - " Zlib error %d", ret); - break; - } - return (ARCHIVE_FATAL); -} - -static int -consume_trailer(struct archive_read_filter *self) -{ - struct private_data *state; - const unsigned char *p; - ssize_t avail; - - state = (struct private_data *)self->data; - - state->in_stream = 0; - switch (inflateEnd(&(state->stream))) { - case Z_OK: - break; - default: - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Failed to clean up gzip decompressor"); - return (ARCHIVE_FATAL); - } - - /* GZip trailer is a fixed 8 byte structure. */ - p = __archive_read_filter_ahead(self->upstream, 8, &avail); - if (p == NULL || avail == 0) - return (ARCHIVE_FATAL); - - /* XXX TODO: Verify the length and CRC. */ - - /* We've verified the trailer, so consume it now. */ - __archive_read_filter_consume(self->upstream, 8); - - return (ARCHIVE_OK); -} - -static ssize_t -gzip_filter_read(struct archive_read_filter *self, const void **p) -{ - struct private_data *state; - size_t decompressed; - ssize_t avail_in, max_in; - int ret; - - state = (struct private_data *)self->data; - - /* Empty our output buffer. */ - state->stream.next_out = state->out_block; - state->stream.avail_out = (uInt)state->out_block_size; - - /* Try to fill the output buffer. */ - while (state->stream.avail_out > 0 && !state->eof) { - /* If we're not in a stream, read a header - * and initialize the decompression library. */ - if (!state->in_stream) { - ret = consume_header(self); - if (ret == ARCHIVE_EOF) { - state->eof = 1; - break; - } - if (ret < ARCHIVE_OK) - return (ret); - } - - /* Peek at the next available data. */ - /* ZLib treats stream.next_in as const but doesn't declare - * it so, hence this ugly cast. */ - state->stream.next_in = (unsigned char *)(uintptr_t) - __archive_read_filter_ahead(self->upstream, 1, &avail_in); - if (state->stream.next_in == NULL) { - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "truncated gzip input"); - return (ARCHIVE_FATAL); - } - if (UINT_MAX >= SSIZE_MAX) - max_in = SSIZE_MAX; - else - max_in = UINT_MAX; - if (avail_in > max_in) - avail_in = max_in; - state->stream.avail_in = (uInt)avail_in; - - /* Decompress and consume some of that data. */ - ret = inflate(&(state->stream), 0); - switch (ret) { - case Z_OK: /* Decompressor made some progress. */ - __archive_read_filter_consume(self->upstream, - avail_in - state->stream.avail_in); - break; - case Z_STREAM_END: /* Found end of stream. */ - __archive_read_filter_consume(self->upstream, - avail_in - state->stream.avail_in); - /* Consume the stream trailer; release the - * decompression library. */ - ret = consume_trailer(self); - if (ret < ARCHIVE_OK) - return (ret); - break; - default: - /* Return an error. */ - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "gzip decompression failed"); - return (ARCHIVE_FATAL); - } - } - - /* We've read as much as we can. */ - decompressed = state->stream.next_out - state->out_block; - state->total_out += decompressed; - if (decompressed == 0) - *p = NULL; - else - *p = state->out_block; - return (decompressed); -} - -/* - * Clean up the decompressor. - */ -static int -gzip_filter_close(struct archive_read_filter *self) -{ - struct private_data *state; - int ret; - - state = (struct private_data *)self->data; - ret = ARCHIVE_OK; - - if (state->in_stream) { - switch (inflateEnd(&(state->stream))) { - case Z_OK: - break; - default: - archive_set_error(&(self->archive->archive), - ARCHIVE_ERRNO_MISC, - "Failed to clean up gzip compressor"); - ret = ARCHIVE_FATAL; - } - } - - free(state->name); - free(state->out_block); - free(state); - return (ret); -} - -#endif /* HAVE_ZLIB_H */ diff --git a/thirdparty/libarchive/libarchive/archive_read_support_filter_lrzip.c b/thirdparty/libarchive/libarchive/archive_read_support_filter_lrzip.c deleted file mode 100644 index a2389894f..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_filter_lrzip.c +++ /dev/null @@ -1,122 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -__FBSDID("$FreeBSD$"); - - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif - -#include "archive.h" -#include "archive_private.h" -#include "archive_read_private.h" - -#define LRZIP_HEADER_MAGIC "LRZI" -#define LRZIP_HEADER_MAGIC_LEN 4 - -static int lrzip_bidder_bid(struct archive_read_filter_bidder *, - struct archive_read_filter *); -static int lrzip_bidder_init(struct archive_read_filter *); - - -static const struct archive_read_filter_bidder_vtable -lrzip_bidder_vtable = { - .bid = lrzip_bidder_bid, - .init = lrzip_bidder_init, -}; - -int -archive_read_support_filter_lrzip(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - - if (__archive_read_register_bidder(a, NULL, "lrzip", - &lrzip_bidder_vtable) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - /* This filter always uses an external program. */ - archive_set_error(_a, ARCHIVE_ERRNO_MISC, - "Using external lrzip program for lrzip decompression"); - return (ARCHIVE_WARN); -} - -/* - * Bidder just verifies the header and returns the number of verified bits. - */ -static int -lrzip_bidder_bid(struct archive_read_filter_bidder *self, - struct archive_read_filter *filter) -{ - const unsigned char *p; - ssize_t avail, len; - int i; - - (void)self; /* UNUSED */ - /* Start by looking at the first six bytes of the header, which - * is all fixed layout. */ - len = 6; - p = __archive_read_filter_ahead(filter, len, &avail); - if (p == NULL || avail == 0) - return (0); - - if (memcmp(p, LRZIP_HEADER_MAGIC, LRZIP_HEADER_MAGIC_LEN)) - return (0); - - /* current major version is always 0, verify this */ - if (p[LRZIP_HEADER_MAGIC_LEN]) - return 0; - /* support only v0.6+ lrzip for sanity */ - i = p[LRZIP_HEADER_MAGIC_LEN + 1]; - if ((i < 6) || (i > 10)) - return 0; - - return (int)len; -} - -static int -lrzip_bidder_init(struct archive_read_filter *self) -{ - int r; - - r = __archive_read_program(self, "lrzip -d -q"); - /* Note: We set the format here even if __archive_read_program() - * above fails. We do, after all, know what the format is - * even if we weren't able to read it. */ - self->code = ARCHIVE_FILTER_LRZIP; - self->name = "lrzip"; - return (r); -} diff --git a/thirdparty/libarchive/libarchive/archive_read_support_filter_lz4.c b/thirdparty/libarchive/libarchive/archive_read_support_filter_lz4.c deleted file mode 100644 index d0fc1a83e..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_filter_lz4.c +++ /dev/null @@ -1,742 +0,0 @@ -/*- - * Copyright (c) 2014 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_LZ4_H -#include -#endif - -#include "archive.h" -#include "archive_endian.h" -#include "archive_private.h" -#include "archive_read_private.h" -#include "archive_xxhash.h" - -#define LZ4_MAGICNUMBER 0x184d2204 -#define LZ4_SKIPPABLED 0x184d2a50 -#define LZ4_LEGACY 0x184c2102 - -#if defined(HAVE_LIBLZ4) -struct private_data { - enum { SELECT_STREAM, - READ_DEFAULT_STREAM, - READ_DEFAULT_BLOCK, - READ_LEGACY_STREAM, - READ_LEGACY_BLOCK, - } stage; - struct { - unsigned block_independence:1; - unsigned block_checksum:3; - unsigned stream_size:1; - unsigned stream_checksum:1; - unsigned preset_dictionary:1; - int block_maximum_size; - } flags; - int64_t stream_size; - uint32_t dict_id; - char *out_block; - size_t out_block_size; - - /* Bytes read but not yet consumed via __archive_read_consume() */ - size_t unconsumed; - size_t decoded_size; - void *xxh32_state; - - char valid; /* True = decompressor is initialized */ - char eof; /* True = found end of compressed data. */ -}; - -#define LEGACY_BLOCK_SIZE (8 * 1024 * 1024) - -/* Lz4 filter */ -static ssize_t lz4_filter_read(struct archive_read_filter *, const void **); -static int lz4_filter_close(struct archive_read_filter *); -#endif - -/* - * Note that we can detect lz4 archives even if we can't decompress - * them. (In fact, we like detecting them because we can give better - * error messages.) So the bid framework here gets compiled even - * if liblz4 is unavailable. - */ -static int lz4_reader_bid(struct archive_read_filter_bidder *, struct archive_read_filter *); -static int lz4_reader_init(struct archive_read_filter *); -#if defined(HAVE_LIBLZ4) -static ssize_t lz4_filter_read_default_stream(struct archive_read_filter *, - const void **); -static ssize_t lz4_filter_read_legacy_stream(struct archive_read_filter *, - const void **); -#endif - -static const struct archive_read_filter_bidder_vtable -lz4_bidder_vtable = { - .bid = lz4_reader_bid, - .init = lz4_reader_init, -}; - -int -archive_read_support_filter_lz4(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - - if (__archive_read_register_bidder(a, NULL, "lz4", - &lz4_bidder_vtable) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - -#if defined(HAVE_LIBLZ4) - return (ARCHIVE_OK); -#else - archive_set_error(_a, ARCHIVE_ERRNO_MISC, - "Using external lz4 program"); - return (ARCHIVE_WARN); -#endif -} - -/* - * Test whether we can handle this data. - * - * This logic returns zero if any part of the signature fails. It - * also tries to Do The Right Thing if a very short buffer prevents us - * from verifying as much as we would like. - */ -static int -lz4_reader_bid(struct archive_read_filter_bidder *self, - struct archive_read_filter *filter) -{ - const unsigned char *buffer; - ssize_t avail; - int bits_checked; - uint32_t number; - - (void)self; /* UNUSED */ - - /* Minimal lz4 archive is 11 bytes. */ - buffer = __archive_read_filter_ahead(filter, 11, &avail); - if (buffer == NULL) - return (0); - - /* First four bytes must be LZ4 magic numbers. */ - bits_checked = 0; - if ((number = archive_le32dec(buffer)) == LZ4_MAGICNUMBER) { - unsigned char flag, BD; - - bits_checked += 32; - /* Next follows a stream descriptor. */ - /* Descriptor Flags. */ - flag = buffer[4]; - /* A version number must be "01". */ - if (((flag & 0xc0) >> 6) != 1) - return (0); - /* A reserved bit must be "0". */ - if (flag & 2) - return (0); - bits_checked += 8; - BD = buffer[5]; - /* A block maximum size should be more than 3. */ - if (((BD & 0x70) >> 4) < 4) - return (0); - /* Reserved bits must be "0". */ - if (BD & ~0x70) - return (0); - bits_checked += 8; - } else if (number == LZ4_LEGACY) { - bits_checked += 32; - } - - return (bits_checked); -} - -#if !defined(HAVE_LIBLZ4) - -/* - * If we don't have the library on this system, we can't actually do the - * decompression. We can, however, still detect compressed archives - * and emit a useful message. - */ -static int -lz4_reader_init(struct archive_read_filter *self) -{ - int r; - - r = __archive_read_program(self, "lz4 -d -q"); - /* Note: We set the format here even if __archive_read_program() - * above fails. We do, after all, know what the format is - * even if we weren't able to read it. */ - self->code = ARCHIVE_FILTER_LZ4; - self->name = "lz4"; - return (r); -} - - -#else - -static const struct archive_read_filter_vtable -lz4_reader_vtable = { - .read = lz4_filter_read, - .close = lz4_filter_close, -}; - -/* - * Setup the callbacks. - */ -static int -lz4_reader_init(struct archive_read_filter *self) -{ - struct private_data *state; - - self->code = ARCHIVE_FILTER_LZ4; - self->name = "lz4"; - - state = (struct private_data *)calloc(sizeof(*state), 1); - if (state == NULL) { - archive_set_error(&self->archive->archive, ENOMEM, - "Can't allocate data for lz4 decompression"); - return (ARCHIVE_FATAL); - } - - self->data = state; - state->stage = SELECT_STREAM; - self->vtable = &lz4_reader_vtable; - - return (ARCHIVE_OK); -} - -static int -lz4_allocate_out_block(struct archive_read_filter *self) -{ - struct private_data *state = (struct private_data *)self->data; - size_t out_block_size = state->flags.block_maximum_size; - void *out_block; - - if (!state->flags.block_independence) - out_block_size += 64 * 1024; - if (state->out_block_size < out_block_size) { - free(state->out_block); - out_block = (unsigned char *)malloc(out_block_size); - state->out_block_size = out_block_size; - if (out_block == NULL) { - archive_set_error(&self->archive->archive, ENOMEM, - "Can't allocate data for lz4 decompression"); - return (ARCHIVE_FATAL); - } - state->out_block = out_block; - } - if (!state->flags.block_independence) - memset(state->out_block, 0, 64 * 1024); - return (ARCHIVE_OK); -} - -static int -lz4_allocate_out_block_for_legacy(struct archive_read_filter *self) -{ - struct private_data *state = (struct private_data *)self->data; - size_t out_block_size = LEGACY_BLOCK_SIZE; - void *out_block; - - if (state->out_block_size < out_block_size) { - free(state->out_block); - out_block = (unsigned char *)malloc(out_block_size); - state->out_block_size = out_block_size; - if (out_block == NULL) { - archive_set_error(&self->archive->archive, ENOMEM, - "Can't allocate data for lz4 decompression"); - return (ARCHIVE_FATAL); - } - state->out_block = out_block; - } - return (ARCHIVE_OK); -} - -/* - * Return the next block of decompressed data. - */ -static ssize_t -lz4_filter_read(struct archive_read_filter *self, const void **p) -{ - struct private_data *state = (struct private_data *)self->data; - ssize_t ret; - - if (state->eof) { - *p = NULL; - return (0); - } - - __archive_read_filter_consume(self->upstream, state->unconsumed); - state->unconsumed = 0; - - switch (state->stage) { - case SELECT_STREAM: - break; - case READ_DEFAULT_STREAM: - case READ_LEGACY_STREAM: - /* Reading a lz4 stream already failed. */ - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, "Invalid sequence."); - return (ARCHIVE_FATAL); - case READ_DEFAULT_BLOCK: - ret = lz4_filter_read_default_stream(self, p); - if (ret != 0 || state->stage != SELECT_STREAM) - return ret; - break; - case READ_LEGACY_BLOCK: - ret = lz4_filter_read_legacy_stream(self, p); - if (ret != 0 || state->stage != SELECT_STREAM) - return ret; - break; - default: - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, "Program error."); - return (ARCHIVE_FATAL); - break; - } - - while (state->stage == SELECT_STREAM) { - const char *read_buf; - - /* Read a magic number. */ - read_buf = __archive_read_filter_ahead(self->upstream, 4, - NULL); - if (read_buf == NULL) { - state->eof = 1; - *p = NULL; - return (0); - } - uint32_t number = archive_le32dec(read_buf); - __archive_read_filter_consume(self->upstream, 4); - if (number == LZ4_MAGICNUMBER) - return lz4_filter_read_default_stream(self, p); - else if (number == LZ4_LEGACY) - return lz4_filter_read_legacy_stream(self, p); - else if ((number & ~0xF) == LZ4_SKIPPABLED) { - read_buf = __archive_read_filter_ahead( - self->upstream, 4, NULL); - if (read_buf == NULL) { - archive_set_error( - &self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Malformed lz4 data"); - return (ARCHIVE_FATAL); - } - uint32_t skip_bytes = archive_le32dec(read_buf); - __archive_read_filter_consume(self->upstream, - 4 + skip_bytes); - } else { - /* Ignore following unrecognized data. */ - state->eof = 1; - *p = NULL; - return (0); - } - } - state->eof = 1; - *p = NULL; - return (0); -} - -static int -lz4_filter_read_descriptor(struct archive_read_filter *self) -{ - struct private_data *state = (struct private_data *)self->data; - const char *read_buf; - ssize_t bytes_remaining; - ssize_t descriptor_bytes; - unsigned char flag, bd; - unsigned int chsum, chsum_verifier; - - /* Make sure we have 2 bytes for flags. */ - read_buf = __archive_read_filter_ahead(self->upstream, 2, - &bytes_remaining); - if (read_buf == NULL) { - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "truncated lz4 input"); - return (ARCHIVE_FATAL); - } - - /* - Parse flags. - */ - flag = (unsigned char)read_buf[0]; - /* Verify version number. */ - if ((flag & 0xc0) != 1<<6) - goto malformed_error; - /* A reserved bit must be zero. */ - if (flag & 0x02) - goto malformed_error; - state->flags.block_independence = (flag & 0x20) != 0; - state->flags.block_checksum = (flag & 0x10)?4:0; - state->flags.stream_size = (flag & 0x08) != 0; - state->flags.stream_checksum = (flag & 0x04) != 0; - state->flags.preset_dictionary = (flag & 0x01) != 0; - - /* BD */ - bd = (unsigned char)read_buf[1]; - /* Reserved bits must be zero. */ - if (bd & 0x8f) - goto malformed_error; - /* Get a maximum block size. */ - switch (read_buf[1] >> 4) { - case 4: /* 64 KB */ - state->flags.block_maximum_size = 64 * 1024; - break; - case 5: /* 256 KB */ - state->flags.block_maximum_size = 256 * 1024; - break; - case 6: /* 1 MB */ - state->flags.block_maximum_size = 1024 * 1024; - break; - case 7: /* 4 MB */ - state->flags.block_maximum_size = 4 * 1024 * 1024; - break; - default: - goto malformed_error; - } - - /* Read the whole descriptor in a stream block. */ - descriptor_bytes = 3; - if (state->flags.stream_size) - descriptor_bytes += 8; - if (state->flags.preset_dictionary) - descriptor_bytes += 4; - if (bytes_remaining < descriptor_bytes) { - read_buf = __archive_read_filter_ahead(self->upstream, - descriptor_bytes, &bytes_remaining); - if (read_buf == NULL) { - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "truncated lz4 input"); - return (ARCHIVE_FATAL); - } - } - /* Check if a descriptor is corrupted */ - chsum = __archive_xxhash.XXH32(read_buf, (int)descriptor_bytes -1, 0); - chsum = (chsum >> 8) & 0xff; - chsum_verifier = read_buf[descriptor_bytes-1] & 0xff; - if (chsum != chsum_verifier) -#ifndef DONT_FAIL_ON_CRC_ERROR - goto malformed_error; -#endif - - __archive_read_filter_consume(self->upstream, descriptor_bytes); - - /* Make sure we have a large enough buffer for uncompressed data. */ - if (lz4_allocate_out_block(self) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - if (state->flags.stream_checksum) - state->xxh32_state = __archive_xxhash.XXH32_init(0); - - state->decoded_size = 0; - /* Success */ - return (ARCHIVE_OK); -malformed_error: - archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC, - "malformed lz4 data"); - return (ARCHIVE_FATAL); -} - -static ssize_t -lz4_filter_read_data_block(struct archive_read_filter *self, const void **p) -{ - struct private_data *state = (struct private_data *)self->data; - ssize_t compressed_size; - const char *read_buf; - ssize_t bytes_remaining; - int checksum_size; - ssize_t uncompressed_size; - size_t prefix64k; - - *p = NULL; - - /* Make sure we have 4 bytes for a block size. */ - read_buf = __archive_read_filter_ahead(self->upstream, 4, - &bytes_remaining); - if (read_buf == NULL) - goto truncated_error; - compressed_size = archive_le32dec(read_buf); - if ((compressed_size & 0x7fffffff) > state->flags.block_maximum_size) - goto malformed_error; - /* A compressed size == 0 means the end of stream blocks. */ - if (compressed_size == 0) { - __archive_read_filter_consume(self->upstream, 4); - return 0; - } - - checksum_size = state->flags.block_checksum; - /* Check if the block is uncompressed. */ - if (compressed_size & 0x80000000U) { - compressed_size &= 0x7fffffff; - uncompressed_size = compressed_size; - } else - uncompressed_size = 0;/* Unknown yet. */ - - /* - Unfortunately, lz4 decompression API requires a whole block - for its decompression speed, so we read a whole block and allocate - a huge buffer used for decoded data. - */ - read_buf = __archive_read_filter_ahead(self->upstream, - 4 + compressed_size + checksum_size, &bytes_remaining); - if (read_buf == NULL) - goto truncated_error; - - /* Optional processing, checking a block sum. */ - if (checksum_size) { - unsigned int chsum = __archive_xxhash.XXH32( - read_buf + 4, (int)compressed_size, 0); - unsigned int chsum_block = - archive_le32dec(read_buf + 4 + compressed_size); - if (chsum != chsum_block) -#ifndef DONT_FAIL_ON_CRC_ERROR - goto malformed_error; -#endif - } - - - /* If the block is uncompressed, there is nothing to do. */ - if (uncompressed_size) { - /* Prepare a prefix 64k block for next block. */ - if (!state->flags.block_independence) { - prefix64k = 64 * 1024; - if (uncompressed_size < (ssize_t)prefix64k) { - memcpy(state->out_block - + prefix64k - uncompressed_size, - read_buf + 4, - uncompressed_size); - memset(state->out_block, 0, - prefix64k - uncompressed_size); - } else { - memcpy(state->out_block, - read_buf + 4 - + uncompressed_size - prefix64k, - prefix64k); - } - state->decoded_size = 0; - } - state->unconsumed = 4 + uncompressed_size + checksum_size; - *p = read_buf + 4; - return uncompressed_size; - } - - /* - Decompress a block data. - */ - if (state->flags.block_independence) { - prefix64k = 0; - uncompressed_size = LZ4_decompress_safe(read_buf + 4, - state->out_block, (int)compressed_size, - state->flags.block_maximum_size); - } else { - prefix64k = 64 * 1024; - if (state->decoded_size) { - if (state->decoded_size < prefix64k) { - memmove(state->out_block - + prefix64k - state->decoded_size, - state->out_block + prefix64k, - state->decoded_size); - memset(state->out_block, 0, - prefix64k - state->decoded_size); - } else { - memmove(state->out_block, - state->out_block + state->decoded_size, - prefix64k); - } - } -#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7 - uncompressed_size = LZ4_decompress_safe_usingDict( - read_buf + 4, - state->out_block + prefix64k, (int)compressed_size, - state->flags.block_maximum_size, - state->out_block, - (int)prefix64k); -#else - uncompressed_size = LZ4_decompress_safe_withPrefix64k( - read_buf + 4, - state->out_block + prefix64k, (int)compressed_size, - state->flags.block_maximum_size); -#endif - } - - /* Check if an error occurred in the decompression process. */ - if (uncompressed_size < 0) { - archive_set_error(&(self->archive->archive), - ARCHIVE_ERRNO_MISC, "lz4 decompression failed"); - return (ARCHIVE_FATAL); - } - - state->unconsumed = 4 + compressed_size + checksum_size; - *p = state->out_block + prefix64k; - state->decoded_size = uncompressed_size; - return uncompressed_size; - -malformed_error: - archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC, - "malformed lz4 data"); - return (ARCHIVE_FATAL); -truncated_error: - archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC, - "truncated lz4 input"); - return (ARCHIVE_FATAL); -} - -static ssize_t -lz4_filter_read_default_stream(struct archive_read_filter *self, const void **p) -{ - struct private_data *state = (struct private_data *)self->data; - const char *read_buf; - ssize_t bytes_remaining; - ssize_t ret; - - if (state->stage == SELECT_STREAM) { - state->stage = READ_DEFAULT_STREAM; - /* First, read a descriptor. */ - if((ret = lz4_filter_read_descriptor(self)) != ARCHIVE_OK) - return (ret); - state->stage = READ_DEFAULT_BLOCK; - } - /* Decompress a block. */ - ret = lz4_filter_read_data_block(self, p); - - /* If the end of block is detected, change the filter status - to read next stream. */ - if (ret == 0 && *p == NULL) - state->stage = SELECT_STREAM; - - /* Optional processing, checking a stream sum. */ - if (state->flags.stream_checksum) { - if (state->stage == SELECT_STREAM) { - unsigned int checksum; - unsigned int checksum_stream; - read_buf = __archive_read_filter_ahead(self->upstream, - 4, &bytes_remaining); - if (read_buf == NULL) { - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, "truncated lz4 input"); - return (ARCHIVE_FATAL); - } - checksum = archive_le32dec(read_buf); - __archive_read_filter_consume(self->upstream, 4); - checksum_stream = __archive_xxhash.XXH32_digest( - state->xxh32_state); - state->xxh32_state = NULL; - if (checksum != checksum_stream) { -#ifndef DONT_FAIL_ON_CRC_ERROR - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "lz4 stream checksum error"); - return (ARCHIVE_FATAL); -#endif - } - } else if (ret > 0) - __archive_xxhash.XXH32_update(state->xxh32_state, - *p, (int)ret); - } - return (ret); -} - -static ssize_t -lz4_filter_read_legacy_stream(struct archive_read_filter *self, const void **p) -{ - struct private_data *state = (struct private_data *)self->data; - uint32_t compressed; - const char *read_buf; - ssize_t ret; - - *p = NULL; - ret = lz4_allocate_out_block_for_legacy(self); - if (ret != ARCHIVE_OK) - return ret; - - /* Make sure we have 4 bytes for a block size. */ - read_buf = __archive_read_filter_ahead(self->upstream, 4, NULL); - if (read_buf == NULL) { - if (state->stage == SELECT_STREAM) { - state->stage = READ_LEGACY_STREAM; - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "truncated lz4 input"); - return (ARCHIVE_FATAL); - } - state->stage = SELECT_STREAM; - return 0; - } - state->stage = READ_LEGACY_BLOCK; - compressed = archive_le32dec(read_buf); - if (compressed > LZ4_COMPRESSBOUND(LEGACY_BLOCK_SIZE)) { - state->stage = SELECT_STREAM; - return 0; - } - - /* Make sure we have a whole block. */ - read_buf = __archive_read_filter_ahead(self->upstream, - 4 + compressed, NULL); - if (read_buf == NULL) { - archive_set_error(&(self->archive->archive), - ARCHIVE_ERRNO_MISC, "truncated lz4 input"); - return (ARCHIVE_FATAL); - } - ret = LZ4_decompress_safe(read_buf + 4, state->out_block, - compressed, (int)state->out_block_size); - if (ret < 0) { - archive_set_error(&(self->archive->archive), - ARCHIVE_ERRNO_MISC, "lz4 decompression failed"); - return (ARCHIVE_FATAL); - } - *p = state->out_block; - state->unconsumed = 4 + compressed; - return ret; -} - -/* - * Clean up the decompressor. - */ -static int -lz4_filter_close(struct archive_read_filter *self) -{ - struct private_data *state; - int ret = ARCHIVE_OK; - - state = (struct private_data *)self->data; - free(state->xxh32_state); - free(state->out_block); - free(state); - return (ret); -} - -#endif /* HAVE_LIBLZ4 */ diff --git a/thirdparty/libarchive/libarchive/archive_read_support_filter_lzop.c b/thirdparty/libarchive/libarchive/archive_read_support_filter_lzop.c deleted file mode 100644 index 4ebdd3bf3..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_filter_lzop.c +++ /dev/null @@ -1,499 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_LZO_LZOCONF_H -#include -#endif -#ifdef HAVE_LZO_LZO1X_H -#include -#endif -#ifdef HAVE_ZLIB_H -#include /* for crc32 and adler32 */ -#endif - -#include "archive.h" -#if !defined(HAVE_ZLIB_H) &&\ - defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H) -#include "archive_crc32.h" -#endif -#include "archive_endian.h" -#include "archive_private.h" -#include "archive_read_private.h" - -#ifndef HAVE_ZLIB_H -#define adler32 lzo_adler32 -#endif - -#define LZOP_HEADER_MAGIC "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a" -#define LZOP_HEADER_MAGIC_LEN 9 - -#if defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H) -struct read_lzop { - unsigned char *out_block; - size_t out_block_size; - int64_t total_out; - int flags; - uint32_t compressed_cksum; - uint32_t uncompressed_cksum; - size_t compressed_size; - size_t uncompressed_size; - size_t unconsumed_bytes; - char in_stream; - char eof; /* True = found end of compressed data. */ -}; - -#define FILTER 0x0800 -#define CRC32_HEADER 0x1000 -#define EXTRA_FIELD 0x0040 -#define ADLER32_UNCOMPRESSED 0x0001 -#define ADLER32_COMPRESSED 0x0002 -#define CRC32_UNCOMPRESSED 0x0100 -#define CRC32_COMPRESSED 0x0200 -#define MAX_BLOCK_SIZE (64 * 1024 * 1024) - -static ssize_t lzop_filter_read(struct archive_read_filter *, const void **); -static int lzop_filter_close(struct archive_read_filter *); -#endif - -static int lzop_bidder_bid(struct archive_read_filter_bidder *, - struct archive_read_filter *); -static int lzop_bidder_init(struct archive_read_filter *); - -static const struct archive_read_filter_bidder_vtable -lzop_bidder_vtable = { - .bid = lzop_bidder_bid, - .init = lzop_bidder_init, -}; - -int -archive_read_support_filter_lzop(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - - if (__archive_read_register_bidder(a, NULL, NULL, - &lzop_bidder_vtable) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - /* Signal the extent of lzop support with the return value here. */ -#if defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H) - return (ARCHIVE_OK); -#else - /* Return ARCHIVE_WARN since this always uses an external program. */ - archive_set_error(_a, ARCHIVE_ERRNO_MISC, - "Using external lzop program for lzop decompression"); - return (ARCHIVE_WARN); -#endif -} - -/* - * Bidder just verifies the header and returns the number of verified bits. - */ -static int -lzop_bidder_bid(struct archive_read_filter_bidder *self, - struct archive_read_filter *filter) -{ - const unsigned char *p; - ssize_t avail; - - (void)self; /* UNUSED */ - - p = __archive_read_filter_ahead(filter, LZOP_HEADER_MAGIC_LEN, &avail); - if (p == NULL || avail == 0) - return (0); - - if (memcmp(p, LZOP_HEADER_MAGIC, LZOP_HEADER_MAGIC_LEN)) - return (0); - - return (LZOP_HEADER_MAGIC_LEN * 8); -} - -#if !defined(HAVE_LZO_LZOCONF_H) || !defined(HAVE_LZO_LZO1X_H) -/* - * If we don't have the library on this system, we can't do the - * decompression directly. We can, however, try to run "lzop -d" - * in case that's available. - */ -static int -lzop_bidder_init(struct archive_read_filter *self) -{ - int r; - - r = __archive_read_program(self, "lzop -d"); - /* Note: We set the format here even if __archive_read_program() - * above fails. We do, after all, know what the format is - * even if we weren't able to read it. */ - self->code = ARCHIVE_FILTER_LZOP; - self->name = "lzop"; - return (r); -} -#else - -static const struct archive_read_filter_vtable -lzop_reader_vtable = { - .read = lzop_filter_read, - .close = lzop_filter_close -}; - -/* - * Initialize the filter object. - */ -static int -lzop_bidder_init(struct archive_read_filter *self) -{ - struct read_lzop *state; - - self->code = ARCHIVE_FILTER_LZOP; - self->name = "lzop"; - - state = (struct read_lzop *)calloc(sizeof(*state), 1); - if (state == NULL) { - archive_set_error(&self->archive->archive, ENOMEM, - "Can't allocate data for lzop decompression"); - return (ARCHIVE_FATAL); - } - - self->data = state; - self->vtable = &lzop_reader_vtable; - - return (ARCHIVE_OK); -} - -static int -consume_header(struct archive_read_filter *self) -{ - struct read_lzop *state = (struct read_lzop *)self->data; - const unsigned char *p, *_p; - unsigned checksum, flags, len, method, version; - - /* - * Check LZOP magic code. - */ - p = __archive_read_filter_ahead(self->upstream, - LZOP_HEADER_MAGIC_LEN, NULL); - if (p == NULL) - return (ARCHIVE_EOF); - - if (memcmp(p, LZOP_HEADER_MAGIC, LZOP_HEADER_MAGIC_LEN)) - return (ARCHIVE_EOF); - __archive_read_filter_consume(self->upstream, - LZOP_HEADER_MAGIC_LEN); - - p = __archive_read_filter_ahead(self->upstream, 29, NULL); - if (p == NULL) - goto truncated; - _p = p; - version = archive_be16dec(p); - p += 4;/* version(2 bytes) + library version(2 bytes) */ - - if (version >= 0x940) { - unsigned reqversion = archive_be16dec(p); p += 2; - if (reqversion < 0x900) { - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, "Invalid required version"); - return (ARCHIVE_FAILED); - } - } - - method = *p++; - if (method < 1 || method > 3) { - archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC, - "Unsupported method"); - return (ARCHIVE_FAILED); - } - - if (version >= 0x940) { - unsigned level = *p++; -#if 0 - unsigned default_level[] = {0, 3, 1, 9}; -#endif - if (level == 0) - /* Method is 1..3 here due to check above. */ -#if 0 /* Avoid an error Clang Static Analyzer claims - "Value stored to 'level' is never read". */ - level = default_level[method]; -#else - ;/* NOP */ -#endif - else if (level > 9) { - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, "Invalid level"); - return (ARCHIVE_FAILED); - } - } - - flags = archive_be32dec(p); p += 4; - - if (flags & FILTER) - p += 4; /* Skip filter */ - p += 4; /* Skip mode */ - if (version >= 0x940) - p += 8; /* Skip mtime */ - else - p += 4; /* Skip mtime */ - len = *p++; /* Read filename length */ - len += p - _p; - /* Make sure we have all bytes we need to calculate checksum. */ - p = __archive_read_filter_ahead(self->upstream, len + 4, NULL); - if (p == NULL) - goto truncated; - if (flags & CRC32_HEADER) - checksum = crc32(crc32(0, NULL, 0), p, len); - else - checksum = adler32(adler32(0, NULL, 0), p, len); - if (archive_be32dec(p + len) != checksum) -#ifndef DONT_FAIL_ON_CRC_ERROR - goto corrupted; -#endif - __archive_read_filter_consume(self->upstream, len + 4); - if (flags & EXTRA_FIELD) { - /* Skip extra field */ - p = __archive_read_filter_ahead(self->upstream, 4, NULL); - if (p == NULL) - goto truncated; - len = archive_be32dec(p); - __archive_read_filter_consume(self->upstream, len + 4 + 4); - } - state->flags = flags; - state->in_stream = 1; - return (ARCHIVE_OK); -truncated: - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_FILE_FORMAT, "Truncated lzop data"); - return (ARCHIVE_FAILED); -corrupted: - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_FILE_FORMAT, "Corrupted lzop header"); - return (ARCHIVE_FAILED); -} - -static int -consume_block_info(struct archive_read_filter *self) -{ - struct read_lzop *state = (struct read_lzop *)self->data; - const unsigned char *p; - unsigned flags = state->flags; - - p = __archive_read_filter_ahead(self->upstream, 4, NULL); - if (p == NULL) - goto truncated; - state->uncompressed_size = archive_be32dec(p); - __archive_read_filter_consume(self->upstream, 4); - if (state->uncompressed_size == 0) - return (ARCHIVE_EOF); - if (state->uncompressed_size > MAX_BLOCK_SIZE) - goto corrupted; - - p = __archive_read_filter_ahead(self->upstream, 4, NULL); - if (p == NULL) - goto truncated; - state->compressed_size = archive_be32dec(p); - __archive_read_filter_consume(self->upstream, 4); - if (state->compressed_size > state->uncompressed_size) - goto corrupted; - - if (flags & (CRC32_UNCOMPRESSED | ADLER32_UNCOMPRESSED)) { - p = __archive_read_filter_ahead(self->upstream, 4, NULL); - if (p == NULL) - goto truncated; - state->compressed_cksum = state->uncompressed_cksum = - archive_be32dec(p); - __archive_read_filter_consume(self->upstream, 4); - } - if ((flags & (CRC32_COMPRESSED | ADLER32_COMPRESSED)) && - state->compressed_size < state->uncompressed_size) { - p = __archive_read_filter_ahead(self->upstream, 4, NULL); - if (p == NULL) - goto truncated; - state->compressed_cksum = archive_be32dec(p); - __archive_read_filter_consume(self->upstream, 4); - } - return (ARCHIVE_OK); -truncated: - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_FILE_FORMAT, "Truncated lzop data"); - return (ARCHIVE_FAILED); -corrupted: - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_FILE_FORMAT, "Corrupted lzop header"); - return (ARCHIVE_FAILED); -} - -static ssize_t -lzop_filter_read(struct archive_read_filter *self, const void **p) -{ - struct read_lzop *state = (struct read_lzop *)self->data; - const void *b; - lzo_uint out_size; - uint32_t cksum; - int ret, r; - - if (state->unconsumed_bytes) { - __archive_read_filter_consume(self->upstream, - state->unconsumed_bytes); - state->unconsumed_bytes = 0; - } - if (state->eof) - return (0); - - for (;;) { - if (!state->in_stream) { - ret = consume_header(self); - if (ret < ARCHIVE_OK) - return (ret); - if (ret == ARCHIVE_EOF) { - state->eof = 1; - return (0); - } - } - ret = consume_block_info(self); - if (ret < ARCHIVE_OK) - return (ret); - if (ret == ARCHIVE_EOF) - state->in_stream = 0; - else - break; - } - - if (state->out_block == NULL || - state->out_block_size < state->uncompressed_size) { - void *new_block; - - new_block = realloc(state->out_block, state->uncompressed_size); - if (new_block == NULL) { - archive_set_error(&self->archive->archive, ENOMEM, - "Can't allocate data for lzop decompression"); - return (ARCHIVE_FATAL); - } - state->out_block = new_block; - state->out_block_size = state->uncompressed_size; - } - - b = __archive_read_filter_ahead(self->upstream, - state->compressed_size, NULL); - if (b == NULL) { - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_FILE_FORMAT, "Truncated lzop data"); - return (ARCHIVE_FATAL); - } - if (state->flags & CRC32_COMPRESSED) - cksum = crc32(crc32(0, NULL, 0), b, state->compressed_size); - else if (state->flags & ADLER32_COMPRESSED) - cksum = adler32(adler32(0, NULL, 0), b, state->compressed_size); - else - cksum = state->compressed_cksum; - if (cksum != state->compressed_cksum) { - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, "Corrupted data"); - return (ARCHIVE_FATAL); - } - - /* - * If the both uncompressed size and compressed size are the same, - * we do not decompress this block. - */ - if (state->uncompressed_size == state->compressed_size) { - *p = b; - state->total_out += state->compressed_size; - state->unconsumed_bytes = state->compressed_size; - return ((ssize_t)state->uncompressed_size); - } - - /* - * Drive lzo uncompression. - */ - out_size = (lzo_uint)state->uncompressed_size; - r = lzo1x_decompress_safe(b, (lzo_uint)state->compressed_size, - state->out_block, &out_size, NULL); - switch (r) { - case LZO_E_OK: - if (out_size == state->uncompressed_size) - break; - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, "Corrupted data"); - return (ARCHIVE_FATAL); - case LZO_E_OUT_OF_MEMORY: - archive_set_error(&self->archive->archive, ENOMEM, - "lzop decompression failed: out of memory"); - return (ARCHIVE_FATAL); - default: - archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC, - "lzop decompression failed: %d", r); - return (ARCHIVE_FATAL); - } - - if (state->flags & CRC32_UNCOMPRESSED) - cksum = crc32(crc32(0, NULL, 0), state->out_block, - state->uncompressed_size); - else if (state->flags & ADLER32_UNCOMPRESSED) - cksum = adler32(adler32(0, NULL, 0), state->out_block, - state->uncompressed_size); - else - cksum = state->uncompressed_cksum; - if (cksum != state->uncompressed_cksum) { - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, "Corrupted data"); - return (ARCHIVE_FATAL); - } - - __archive_read_filter_consume(self->upstream, state->compressed_size); - *p = state->out_block; - state->total_out += out_size; - return ((ssize_t)out_size); -} - -/* - * Clean up the decompressor. - */ -static int -lzop_filter_close(struct archive_read_filter *self) -{ - struct read_lzop *state = (struct read_lzop *)self->data; - - free(state->out_block); - free(state); - return (ARCHIVE_OK); -} - -#endif diff --git a/thirdparty/libarchive/libarchive/archive_read_support_filter_none.c b/thirdparty/libarchive/libarchive/archive_read_support_filter_none.c deleted file mode 100644 index 95e5cfdb1..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_filter_none.c +++ /dev/null @@ -1,52 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#include "archive.h" -#include "archive_private.h" - -#if ARCHIVE_VERSION_NUMBER < 4000000 -/* Deprecated; remove in libarchive 4.0 */ -int -archive_read_support_compression_none(struct archive *a) -{ - return archive_read_support_filter_none(a); -} -#endif - -/* - * Uncompressed streams are handled implicitly by the read core, - * so this is now a no-op. - */ -int -archive_read_support_filter_none(struct archive *a) -{ - archive_check_magic(a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_filter_none"); - - return (ARCHIVE_OK); -} diff --git a/thirdparty/libarchive/libarchive/archive_read_support_filter_program.c b/thirdparty/libarchive/libarchive/archive_read_support_filter_program.c deleted file mode 100644 index 885b2c205..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_filter_program.c +++ /dev/null @@ -1,496 +0,0 @@ -/*- - * Copyright (c) 2007 Joerg Sonnenberger - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_SYS_WAIT_H -# include -#endif -#ifdef HAVE_ERRNO_H -# include -#endif -#ifdef HAVE_FCNTL_H -# include -#endif -#ifdef HAVE_LIMITS_H -# include -#endif -#ifdef HAVE_SIGNAL_H -# include -#endif -#ifdef HAVE_STDLIB_H -# include -#endif -#ifdef HAVE_STRING_H -# include -#endif -#ifdef HAVE_UNISTD_H -# include -#endif - -#include "archive.h" -#include "archive_private.h" -#include "archive_string.h" -#include "archive_read_private.h" -#include "filter_fork.h" - - -#if ARCHIVE_VERSION_NUMBER < 4000000 -/* Deprecated; remove in libarchive 4.0 */ -int -archive_read_support_compression_program(struct archive *a, const char *cmd) -{ - return archive_read_support_filter_program(a, cmd); -} - -int -archive_read_support_compression_program_signature(struct archive *a, - const char *cmd, const void *signature, size_t signature_len) -{ - return archive_read_support_filter_program_signature(a, - cmd, signature, signature_len); -} -#endif - -int -archive_read_support_filter_program(struct archive *a, const char *cmd) -{ - return (archive_read_support_filter_program_signature(a, cmd, NULL, 0)); -} - -/* - * The bidder object stores the command and the signature to watch for. - * The 'inhibit' entry here is used to ensure that unchecked filters never - * bid twice in the same pipeline. - */ -struct program_bidder { - char *description; - char *cmd; - void *signature; - size_t signature_len; - int inhibit; -}; - -static int program_bidder_bid(struct archive_read_filter_bidder *, - struct archive_read_filter *upstream); -static int program_bidder_init(struct archive_read_filter *); -static void program_bidder_free(struct archive_read_filter_bidder *); - -/* - * The actual filter needs to track input and output data. - */ -struct program_filter { - struct archive_string description; -#if defined(_WIN32) && !defined(__CYGWIN__) - HANDLE child; -#else - pid_t child; -#endif - int exit_status; - int waitpid_return; - int child_stdin, child_stdout; - - char *out_buf; - size_t out_buf_len; -}; - -static ssize_t program_filter_read(struct archive_read_filter *, - const void **); -static int program_filter_close(struct archive_read_filter *); -static void free_state(struct program_bidder *); - -static const struct archive_read_filter_bidder_vtable -program_bidder_vtable = { - .bid = program_bidder_bid, - .init = program_bidder_init, - .free = program_bidder_free, -}; - -int -archive_read_support_filter_program_signature(struct archive *_a, - const char *cmd, const void *signature, size_t signature_len) -{ - struct archive_read *a = (struct archive_read *)_a; - struct program_bidder *state; - - /* - * Allocate our private state. - */ - state = (struct program_bidder *)calloc(1, sizeof (*state)); - if (state == NULL) - goto memerr; - state->cmd = strdup(cmd); - if (state->cmd == NULL) - goto memerr; - - if (signature != NULL && signature_len > 0) { - state->signature_len = signature_len; - state->signature = malloc(signature_len); - memcpy(state->signature, signature, signature_len); - } - - if (__archive_read_register_bidder(a, state, NULL, - &program_bidder_vtable) != ARCHIVE_OK) { - free_state(state); - return (ARCHIVE_FATAL); - } - return (ARCHIVE_OK); - -memerr: - free_state(state); - archive_set_error(_a, ENOMEM, "Can't allocate memory"); - return (ARCHIVE_FATAL); -} - -static void -program_bidder_free(struct archive_read_filter_bidder *self) -{ - struct program_bidder *state = (struct program_bidder *)self->data; - - free_state(state); -} - -static void -free_state(struct program_bidder *state) -{ - - if (state) { - free(state->cmd); - free(state->signature); - free(state); - } -} - -/* - * If we do have a signature, bid only if that matches. - * - * If there's no signature, we bid INT_MAX the first time - * we're called, then never bid again. - */ -static int -program_bidder_bid(struct archive_read_filter_bidder *self, - struct archive_read_filter *upstream) -{ - struct program_bidder *state = self->data; - const char *p; - - /* If we have a signature, use that to match. */ - if (state->signature_len > 0) { - p = __archive_read_filter_ahead(upstream, - state->signature_len, NULL); - if (p == NULL) - return (0); - /* No match, so don't bid. */ - if (memcmp(p, state->signature, state->signature_len) != 0) - return (0); - return ((int)state->signature_len * 8); - } - - /* Otherwise, bid once and then never bid again. */ - if (state->inhibit) - return (0); - state->inhibit = 1; - return (INT_MAX); -} - -/* - * Shut down the child, return ARCHIVE_OK if it exited normally. - * - * Note that the return value is sticky; if we're called again, - * we won't reap the child again, but we will return the same status - * (including error message if the child came to a bad end). - */ -static int -child_stop(struct archive_read_filter *self, struct program_filter *state) -{ - /* Close our side of the I/O with the child. */ - if (state->child_stdin != -1) { - close(state->child_stdin); - state->child_stdin = -1; - } - if (state->child_stdout != -1) { - close(state->child_stdout); - state->child_stdout = -1; - } - - if (state->child != 0) { - /* Reap the child. */ - do { - state->waitpid_return - = waitpid(state->child, &state->exit_status, 0); - } while (state->waitpid_return == -1 && errno == EINTR); -#if defined(_WIN32) && !defined(__CYGWIN__) - CloseHandle(state->child); -#endif - state->child = 0; - } - - if (state->waitpid_return < 0) { - /* waitpid() failed? This is ugly. */ - archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC, - "Child process exited badly"); - return (ARCHIVE_WARN); - } - -#if !defined(_WIN32) || defined(__CYGWIN__) - if (WIFSIGNALED(state->exit_status)) { -#ifdef SIGPIPE - /* If the child died because we stopped reading before - * it was done, that's okay. Some archive formats - * have padding at the end that we routinely ignore. */ - /* The alternative to this would be to add a step - * before close(child_stdout) above to read from the - * child until the child has no more to write. */ - if (WTERMSIG(state->exit_status) == SIGPIPE) - return (ARCHIVE_OK); -#endif - archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC, - "Child process exited with signal %d", - WTERMSIG(state->exit_status)); - return (ARCHIVE_WARN); - } -#endif /* !_WIN32 || __CYGWIN__ */ - - if (WIFEXITED(state->exit_status)) { - if (WEXITSTATUS(state->exit_status) == 0) - return (ARCHIVE_OK); - - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Child process exited with status %d", - WEXITSTATUS(state->exit_status)); - return (ARCHIVE_WARN); - } - - return (ARCHIVE_WARN); -} - -/* - * Use select() to decide whether the child is ready for read or write. - */ -static ssize_t -child_read(struct archive_read_filter *self, char *buf, size_t buf_len) -{ - struct program_filter *state = self->data; - ssize_t ret, requested, avail; - const char *p; -#if defined(_WIN32) && !defined(__CYGWIN__) - HANDLE handle = (HANDLE)_get_osfhandle(state->child_stdout); -#endif - - requested = buf_len > SSIZE_MAX ? SSIZE_MAX : buf_len; - - for (;;) { - do { -#if defined(_WIN32) && !defined(__CYGWIN__) - /* Avoid infinity wait. - * Note: If there is no data in the pipe, ReadFile() - * called in read() never returns and so we won't - * write remaining encoded data to the pipe. - * Note: This way may cause performance problem. - * we are looking forward to great code to resolve - * this. */ - DWORD pipe_avail = -1; - int cnt = 2; - - while (PeekNamedPipe(handle, NULL, 0, NULL, - &pipe_avail, NULL) != 0 && pipe_avail == 0 && - cnt--) - Sleep(5); - if (pipe_avail == 0) { - ret = -1; - errno = EAGAIN; - break; - } -#endif - ret = read(state->child_stdout, buf, requested); - } while (ret == -1 && errno == EINTR); - - if (ret > 0) - return (ret); - if (ret == 0 || (ret == -1 && errno == EPIPE)) - /* Child has closed its output; reap the child - * and return the status. */ - return (child_stop(self, state)); - if (ret == -1 && errno != EAGAIN) - return (-1); - - if (state->child_stdin == -1) { - /* Block until child has some I/O ready. */ - __archive_check_child(state->child_stdin, - state->child_stdout); - continue; - } - - /* Get some more data from upstream. */ - p = __archive_read_filter_ahead(self->upstream, 1, &avail); - if (p == NULL) { - close(state->child_stdin); - state->child_stdin = -1; - fcntl(state->child_stdout, F_SETFL, 0); - if (avail < 0) - return (avail); - continue; - } - - do { - ret = write(state->child_stdin, p, avail); - } while (ret == -1 && errno == EINTR); - - if (ret > 0) { - /* Consume whatever we managed to write. */ - __archive_read_filter_consume(self->upstream, ret); - } else if (ret == -1 && errno == EAGAIN) { - /* Block until child has some I/O ready. */ - __archive_check_child(state->child_stdin, - state->child_stdout); - } else { - /* Write failed. */ - close(state->child_stdin); - state->child_stdin = -1; - fcntl(state->child_stdout, F_SETFL, 0); - /* If it was a bad error, we're done; otherwise - * it was EPIPE or EOF, and we can still read - * from the child. */ - if (ret == -1 && errno != EPIPE) - return (-1); - } - } -} - -static const struct archive_read_filter_vtable -program_reader_vtable = { - .read = program_filter_read, - .close = program_filter_close, -}; - -int -__archive_read_program(struct archive_read_filter *self, const char *cmd) -{ - struct program_filter *state; - static const size_t out_buf_len = 65536; - char *out_buf; - const char *prefix = "Program: "; - int ret; - size_t l; - - l = strlen(prefix) + strlen(cmd) + 1; - state = (struct program_filter *)calloc(1, sizeof(*state)); - out_buf = (char *)malloc(out_buf_len); - if (state == NULL || out_buf == NULL || - archive_string_ensure(&state->description, l) == NULL) { - archive_set_error(&self->archive->archive, ENOMEM, - "Can't allocate input data"); - if (state != NULL) { - archive_string_free(&state->description); - free(state); - } - free(out_buf); - return (ARCHIVE_FATAL); - } - archive_strcpy(&state->description, prefix); - archive_strcat(&state->description, cmd); - - self->code = ARCHIVE_FILTER_PROGRAM; - self->name = state->description.s; - - state->out_buf = out_buf; - state->out_buf_len = out_buf_len; - - ret = __archive_create_child(cmd, &state->child_stdin, - &state->child_stdout, &state->child); - if (ret != ARCHIVE_OK) { - free(state->out_buf); - archive_string_free(&state->description); - free(state); - archive_set_error(&self->archive->archive, EINVAL, - "Can't initialize filter; unable to run program \"%s\"", - cmd); - return (ARCHIVE_FATAL); - } - - self->data = state; - self->vtable = &program_reader_vtable; - - /* XXX Check that we can read at least one byte? */ - return (ARCHIVE_OK); -} - -static int -program_bidder_init(struct archive_read_filter *self) -{ - struct program_bidder *bidder_state; - - bidder_state = (struct program_bidder *)self->bidder->data; - return (__archive_read_program(self, bidder_state->cmd)); -} - -static ssize_t -program_filter_read(struct archive_read_filter *self, const void **buff) -{ - struct program_filter *state; - ssize_t bytes; - size_t total; - char *p; - - state = (struct program_filter *)self->data; - - total = 0; - p = state->out_buf; - while (state->child_stdout != -1 && total < state->out_buf_len) { - bytes = child_read(self, p, state->out_buf_len - total); - if (bytes < 0) - /* No recovery is possible if we can no longer - * read from the child. */ - return (ARCHIVE_FATAL); - if (bytes == 0) - /* We got EOF from the child. */ - break; - total += bytes; - p += bytes; - } - - *buff = state->out_buf; - return (total); -} - -static int -program_filter_close(struct archive_read_filter *self) -{ - struct program_filter *state; - int e; - - state = (struct program_filter *)self->data; - e = child_stop(self, state); - - /* Release our private data. */ - free(state->out_buf); - archive_string_free(&state->description); - free(state); - - return (e); -} diff --git a/thirdparty/libarchive/libarchive/archive_read_support_filter_rpm.c b/thirdparty/libarchive/libarchive/archive_read_support_filter_rpm.c deleted file mode 100644 index 67a979cd7..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_filter_rpm.c +++ /dev/null @@ -1,287 +0,0 @@ -/*- - * Copyright (c) 2009 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif - -#include "archive.h" -#include "archive_endian.h" -#include "archive_private.h" -#include "archive_read_private.h" - -struct rpm { - int64_t total_in; - size_t hpos; - size_t hlen; - unsigned char header[16]; - enum { - ST_LEAD, /* Skipping 'Lead' section. */ - ST_HEADER, /* Reading 'Header' section; - * first 16 bytes. */ - ST_HEADER_DATA, /* Skipping 'Header' section. */ - ST_PADDING, /* Skipping padding data after the - * 'Header' section. */ - ST_ARCHIVE /* Reading 'Archive' section. */ - } state; - int first_header; -}; -#define RPM_LEAD_SIZE 96 /* Size of 'Lead' section. */ - -static int rpm_bidder_bid(struct archive_read_filter_bidder *, - struct archive_read_filter *); -static int rpm_bidder_init(struct archive_read_filter *); - -static ssize_t rpm_filter_read(struct archive_read_filter *, - const void **); -static int rpm_filter_close(struct archive_read_filter *); - -#if ARCHIVE_VERSION_NUMBER < 4000000 -/* Deprecated; remove in libarchive 4.0 */ -int -archive_read_support_compression_rpm(struct archive *a) -{ - return archive_read_support_filter_rpm(a); -} -#endif - -static const struct archive_read_filter_bidder_vtable -rpm_bidder_vtable = { - .bid = rpm_bidder_bid, - .init = rpm_bidder_init, -}; - -int -archive_read_support_filter_rpm(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - - return __archive_read_register_bidder(a, NULL, "rpm", - &rpm_bidder_vtable); -} - -static int -rpm_bidder_bid(struct archive_read_filter_bidder *self, - struct archive_read_filter *filter) -{ - const unsigned char *b; - ssize_t avail; - int bits_checked; - - (void)self; /* UNUSED */ - - b = __archive_read_filter_ahead(filter, 8, &avail); - if (b == NULL) - return (0); - - bits_checked = 0; - /* - * Verify Header Magic Bytes : 0XED 0XAB 0XEE 0XDB - */ - if (memcmp(b, "\xED\xAB\xEE\xDB", 4) != 0) - return (0); - bits_checked += 32; - /* - * Check major version. - */ - if (b[4] != 3 && b[4] != 4) - return (0); - bits_checked += 8; - /* - * Check package type; binary or source. - */ - if (b[6] != 0) - return (0); - bits_checked += 8; - if (b[7] != 0 && b[7] != 1) - return (0); - bits_checked += 8; - - return (bits_checked); -} - -static const struct archive_read_filter_vtable -rpm_reader_vtable = { - .read = rpm_filter_read, - .close = rpm_filter_close, -}; - -static int -rpm_bidder_init(struct archive_read_filter *self) -{ - struct rpm *rpm; - - self->code = ARCHIVE_FILTER_RPM; - self->name = "rpm"; - - rpm = (struct rpm *)calloc(sizeof(*rpm), 1); - if (rpm == NULL) { - archive_set_error(&self->archive->archive, ENOMEM, - "Can't allocate data for rpm"); - return (ARCHIVE_FATAL); - } - - self->data = rpm; - rpm->state = ST_LEAD; - self->vtable = &rpm_reader_vtable; - - return (ARCHIVE_OK); -} - -static ssize_t -rpm_filter_read(struct archive_read_filter *self, const void **buff) -{ - struct rpm *rpm; - const unsigned char *b; - ssize_t avail_in, total; - size_t used, n; - uint32_t section; - uint32_t bytes; - - rpm = (struct rpm *)self->data; - *buff = NULL; - total = avail_in = 0; - b = NULL; - used = 0; - do { - if (b == NULL) { - b = __archive_read_filter_ahead(self->upstream, 1, - &avail_in); - if (b == NULL) { - if (avail_in < 0) - return (ARCHIVE_FATAL); - else - break; - } - } - - switch (rpm->state) { - case ST_LEAD: - if (rpm->total_in + avail_in < RPM_LEAD_SIZE) - used += avail_in; - else { - n = (size_t)(RPM_LEAD_SIZE - rpm->total_in); - used += n; - b += n; - rpm->state = ST_HEADER; - rpm->hpos = 0; - rpm->hlen = 0; - rpm->first_header = 1; - } - break; - case ST_HEADER: - n = 16 - rpm->hpos; - if (n > avail_in - used) - n = avail_in - used; - memcpy(rpm->header+rpm->hpos, b, n); - b += n; - used += n; - rpm->hpos += n; - - if (rpm->hpos == 16) { - if (rpm->header[0] != 0x8e || - rpm->header[1] != 0xad || - rpm->header[2] != 0xe8 || - rpm->header[3] != 0x01) { - if (rpm->first_header) { - archive_set_error( - &self->archive->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Unrecognized rpm header"); - return (ARCHIVE_FATAL); - } - rpm->state = ST_ARCHIVE; - *buff = rpm->header; - total = rpm->hpos; - break; - } - /* Calculate 'Header' length. */ - section = archive_be32dec(rpm->header+8); - bytes = archive_be32dec(rpm->header+12); - rpm->hlen = 16 + section * 16 + bytes; - rpm->state = ST_HEADER_DATA; - rpm->first_header = 0; - } - break; - case ST_HEADER_DATA: - n = rpm->hlen - rpm->hpos; - if (n > avail_in - used) - n = avail_in - used; - b += n; - used += n; - rpm->hpos += n; - if (rpm->hpos == rpm->hlen) - rpm->state = ST_PADDING; - break; - case ST_PADDING: - while (used < (size_t)avail_in) { - if (*b != 0) { - /* Read next header. */ - rpm->state = ST_HEADER; - rpm->hpos = 0; - rpm->hlen = 0; - break; - } - b++; - used++; - } - break; - case ST_ARCHIVE: - *buff = b; - total = avail_in; - used = avail_in; - break; - } - if (used == (size_t)avail_in) { - rpm->total_in += used; - __archive_read_filter_consume(self->upstream, used); - b = NULL; - used = 0; - } - } while (total == 0 && avail_in > 0); - - if (used > 0 && b != NULL) { - rpm->total_in += used; - __archive_read_filter_consume(self->upstream, used); - } - return (total); -} - -static int -rpm_filter_close(struct archive_read_filter *self) -{ - struct rpm *rpm; - - rpm = (struct rpm *)self->data; - free(rpm); - - return (ARCHIVE_OK); -} - diff --git a/thirdparty/libarchive/libarchive/archive_read_support_filter_uu.c b/thirdparty/libarchive/libarchive/archive_read_support_filter_uu.c deleted file mode 100644 index cd79638e7..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_filter_uu.c +++ /dev/null @@ -1,731 +0,0 @@ -/*- - * Copyright (c) 2009-2011 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" -#include "archive_private.h" -#include "archive_read_private.h" - -/* Maximum lookahead during bid phase */ -#define UUENCODE_BID_MAX_READ 128*1024 /* in bytes */ - -struct uudecode { - int64_t total; - unsigned char *in_buff; -#define IN_BUFF_SIZE (1024) - int in_cnt; - size_t in_allocated; - unsigned char *out_buff; -#define OUT_BUFF_SIZE (64 * 1024) - int state; -#define ST_FIND_HEAD 0 -#define ST_READ_UU 1 -#define ST_UUEND 2 -#define ST_READ_BASE64 3 -#define ST_IGNORE 4 - mode_t mode; - int mode_set; - char *name; -}; - -static int uudecode_bidder_bid(struct archive_read_filter_bidder *, - struct archive_read_filter *filter); -static int uudecode_bidder_init(struct archive_read_filter *); - -static int uudecode_read_header(struct archive_read_filter *, - struct archive_entry *entry); -static ssize_t uudecode_filter_read(struct archive_read_filter *, - const void **); -static int uudecode_filter_close(struct archive_read_filter *); - -#if ARCHIVE_VERSION_NUMBER < 4000000 -/* Deprecated; remove in libarchive 4.0 */ -int -archive_read_support_compression_uu(struct archive *a) -{ - return archive_read_support_filter_uu(a); -} -#endif - -static const struct archive_read_filter_bidder_vtable -uudecode_bidder_vtable = { - .bid = uudecode_bidder_bid, - .init = uudecode_bidder_init, -}; - -int -archive_read_support_filter_uu(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - - return __archive_read_register_bidder(a, NULL, "uu", - &uudecode_bidder_vtable); -} - -static const unsigned char ascii[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\n', 0, 0, '\r', 0, 0, /* 00 - 0F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 30 - 3F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 - 5F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* 70 - 7F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F0 - FF */ -}; - -static const unsigned char uuchar[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 0F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 30 - 3F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 - 5F */ - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60 - 6F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 70 - 7F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F0 - FF */ -}; - -static const unsigned char base64[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 0F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, /* 20 - 2F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, /* 30 - 3F */ - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 50 - 5F */ - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 70 - 7F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F0 - FF */ -}; - -static const int base64num[128] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 0F */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 62, 0, 0, 0, 63, /* 20 - 2F */ - 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 0, 0, 0, 0, 0, 0, /* 30 - 3F */ - 0, 0, 1, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, /* 40 - 4F */ - 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 0, 0, 0, 0, 0, /* 50 - 5F */ - 0, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, /* 60 - 6F */ - 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 0, 0, 0, 0, 0, /* 70 - 7F */ -}; - -static ssize_t -get_line(const unsigned char *b, ssize_t avail, ssize_t *nlsize) -{ - ssize_t len; - - len = 0; - while (len < avail) { - switch (ascii[*b]) { - case 0: /* Non-ascii character or control character. */ - if (nlsize != NULL) - *nlsize = 0; - return (-1); - case '\r': - if (avail-len > 1 && b[1] == '\n') { - if (nlsize != NULL) - *nlsize = 2; - return (len+2); - } - /* FALL THROUGH */ - case '\n': - if (nlsize != NULL) - *nlsize = 1; - return (len+1); - case 1: - b++; - len++; - break; - } - } - if (nlsize != NULL) - *nlsize = 0; - return (avail); -} - -static ssize_t -bid_get_line(struct archive_read_filter *filter, - const unsigned char **b, ssize_t *avail, ssize_t *ravail, - ssize_t *nl, size_t* nbytes_read) -{ - ssize_t len; - int quit; - - quit = 0; - if (*avail == 0) { - *nl = 0; - len = 0; - } else - len = get_line(*b, *avail, nl); - - /* - * Read bytes more while it does not reach the end of line. - */ - while (*nl == 0 && len == *avail && !quit && - *nbytes_read < UUENCODE_BID_MAX_READ) { - ssize_t diff = *ravail - *avail; - size_t nbytes_req = (*ravail+1023) & ~1023U; - ssize_t tested; - - /* Increase reading bytes if it is not enough to at least - * new two lines. */ - if (nbytes_req < (size_t)*ravail + 160) - nbytes_req <<= 1; - - *b = __archive_read_filter_ahead(filter, nbytes_req, avail); - if (*b == NULL) { - if (*ravail >= *avail) - return (0); - /* Reading bytes reaches the end of a stream. */ - *b = __archive_read_filter_ahead(filter, *avail, avail); - quit = 1; - } - *nbytes_read = *avail; - *ravail = *avail; - *b += diff; - *avail -= diff; - tested = len;/* Skip some bytes we already determined. */ - len = get_line(*b + tested, *avail - tested, nl); - if (len >= 0) - len += tested; - } - return (len); -} - -#define UUDECODE(c) (((c) - 0x20) & 0x3f) - -static int -uudecode_bidder_bid(struct archive_read_filter_bidder *self, - struct archive_read_filter *filter) -{ - const unsigned char *b; - ssize_t avail, ravail; - ssize_t len, nl; - int l; - int firstline; - size_t nbytes_read; - - (void)self; /* UNUSED */ - - b = __archive_read_filter_ahead(filter, 1, &avail); - if (b == NULL) - return (0); - - firstline = 20; - ravail = avail; - nbytes_read = avail; - for (;;) { - len = bid_get_line(filter, &b, &avail, &ravail, &nl, &nbytes_read); - if (len < 0 || nl == 0) - return (0); /* No match found. */ - if (len - nl >= 11 && memcmp(b, "begin ", 6) == 0) - l = 6; - else if (len -nl >= 18 && memcmp(b, "begin-base64 ", 13) == 0) - l = 13; - else - l = 0; - - if (l > 0 && (b[l] < '0' || b[l] > '7' || - b[l+1] < '0' || b[l+1] > '7' || - b[l+2] < '0' || b[l+2] > '7' || b[l+3] != ' ')) - l = 0; - - b += len; - avail -= len; - if (l) - break; - firstline = 0; - - /* Do not read more than UUENCODE_BID_MAX_READ bytes */ - if (nbytes_read >= UUENCODE_BID_MAX_READ) - return (0); - } - if (!avail) - return (0); - len = bid_get_line(filter, &b, &avail, &ravail, &nl, &nbytes_read); - if (len < 0 || nl == 0) - return (0);/* There are non-ascii characters. */ - avail -= len; - - if (l == 6) { - /* "begin " */ - if (!uuchar[*b]) - return (0); - /* Get a length of decoded bytes. */ - l = UUDECODE(*b++); len--; - if (l > 45) - /* Normally, maximum length is 45(character 'M'). */ - return (0); - if (l > len - nl) - return (0); /* Line too short. */ - while (l) { - if (!uuchar[*b++]) - return (0); - --len; - --l; - } - if (len-nl == 1 && - (uuchar[*b] || /* Check sum. */ - (*b >= 'a' && *b <= 'z'))) {/* Padding data(MINIX). */ - ++b; - --len; - } - b += nl; - if (avail && uuchar[*b]) - return (firstline+30); - } else if (l == 13) { - /* "begin-base64 " */ - while (len-nl > 0) { - if (!base64[*b++]) - return (0); - --len; - } - b += nl; - - if (avail >= 5 && memcmp(b, "====\n", 5) == 0) - return (firstline+40); - if (avail >= 6 && memcmp(b, "====\r\n", 6) == 0) - return (firstline+40); - if (avail > 0 && base64[*b]) - return (firstline+30); - } - - return (0); -} - -static const struct archive_read_filter_vtable -uudecode_reader_vtable = { - .read = uudecode_filter_read, - .close = uudecode_filter_close, - .read_header = uudecode_read_header -}; - -static int -uudecode_bidder_init(struct archive_read_filter *self) -{ - struct uudecode *uudecode; - void *out_buff; - void *in_buff; - - self->code = ARCHIVE_FILTER_UU; - self->name = "uu"; - - uudecode = (struct uudecode *)calloc(sizeof(*uudecode), 1); - out_buff = malloc(OUT_BUFF_SIZE); - in_buff = malloc(IN_BUFF_SIZE); - if (uudecode == NULL || out_buff == NULL || in_buff == NULL) { - archive_set_error(&self->archive->archive, ENOMEM, - "Can't allocate data for uudecode"); - free(uudecode); - free(out_buff); - free(in_buff); - return (ARCHIVE_FATAL); - } - - self->data = uudecode; - uudecode->in_buff = in_buff; - uudecode->in_cnt = 0; - uudecode->in_allocated = IN_BUFF_SIZE; - uudecode->out_buff = out_buff; - uudecode->state = ST_FIND_HEAD; - uudecode->mode_set = 0; - uudecode->name = NULL; - self->vtable = &uudecode_reader_vtable; - - return (ARCHIVE_OK); -} - -static int -ensure_in_buff_size(struct archive_read_filter *self, - struct uudecode *uudecode, size_t size) -{ - - if (size > uudecode->in_allocated) { - unsigned char *ptr; - size_t newsize; - - /* - * Calculate a new buffer size for in_buff. - * Increase its value until it has enough size we need. - */ - newsize = uudecode->in_allocated; - do { - if (newsize < IN_BUFF_SIZE*32) - newsize <<= 1; - else - newsize += IN_BUFF_SIZE; - } while (size > newsize); - /* Allocate the new buffer. */ - ptr = malloc(newsize); - if (ptr == NULL) { - free(ptr); - archive_set_error(&self->archive->archive, - ENOMEM, - "Can't allocate data for uudecode"); - return (ARCHIVE_FATAL); - } - /* Move the remaining data in in_buff into the new buffer. */ - if (uudecode->in_cnt) - memmove(ptr, uudecode->in_buff, uudecode->in_cnt); - /* Replace in_buff with the new buffer. */ - free(uudecode->in_buff); - uudecode->in_buff = ptr; - uudecode->in_allocated = newsize; - } - return (ARCHIVE_OK); -} - -static int -uudecode_read_header(struct archive_read_filter *self, struct archive_entry *entry) -{ - - struct uudecode *uudecode; - uudecode = (struct uudecode *)self->data; - - if (uudecode->mode_set != 0) - archive_entry_set_mode(entry, S_IFREG | uudecode->mode); - - if (uudecode->name != NULL) - archive_entry_set_pathname(entry, uudecode->name); - - return (ARCHIVE_OK); -} - -static ssize_t -uudecode_filter_read(struct archive_read_filter *self, const void **buff) -{ - struct uudecode *uudecode; - const unsigned char *b, *d; - unsigned char *out; - ssize_t avail_in, ravail; - ssize_t used; - ssize_t total; - ssize_t len, llen, nl, namelen; - - uudecode = (struct uudecode *)self->data; - -read_more: - d = __archive_read_filter_ahead(self->upstream, 1, &avail_in); - if (d == NULL && avail_in < 0) - return (ARCHIVE_FATAL); - /* Quiet a code analyzer; make sure avail_in must be zero - * when d is NULL. */ - if (d == NULL) - avail_in = 0; - used = 0; - total = 0; - out = uudecode->out_buff; - ravail = avail_in; - if (uudecode->state == ST_IGNORE) { - used = avail_in; - goto finish; - } - if (uudecode->in_cnt) { - /* - * If there is remaining data which is saved by - * previous calling, use it first. - */ - if (ensure_in_buff_size(self, uudecode, - avail_in + uudecode->in_cnt) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - memcpy(uudecode->in_buff + uudecode->in_cnt, - d, avail_in); - d = uudecode->in_buff; - avail_in += uudecode->in_cnt; - uudecode->in_cnt = 0; - } - for (;used < avail_in; d += llen, used += llen) { - int64_t l, body; - - b = d; - len = get_line(b, avail_in - used, &nl); - if (len < 0) { - /* Non-ascii character is found. */ - if (uudecode->state == ST_FIND_HEAD && - (uudecode->total > 0 || total > 0)) { - uudecode->state = ST_IGNORE; - used = avail_in; - goto finish; - } - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Insufficient compressed data"); - return (ARCHIVE_FATAL); - } - llen = len; - if ((nl == 0) && (uudecode->state != ST_UUEND)) { - if (total == 0 && ravail <= 0) { - /* There is nothing more to read, fail */ - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Missing format data"); - return (ARCHIVE_FATAL); - } - /* - * Save remaining data which does not contain - * NL('\n','\r'). - */ - if (ensure_in_buff_size(self, uudecode, len) - != ARCHIVE_OK) - return (ARCHIVE_FATAL); - if (uudecode->in_buff != b) - memmove(uudecode->in_buff, b, len); - uudecode->in_cnt = (int)len; - if (total == 0) { - /* Do not return 0; it means end-of-file. - * We should try to read bytes more. */ - __archive_read_filter_consume( - self->upstream, ravail); - goto read_more; - } - used += len; - break; - } - switch (uudecode->state) { - default: - case ST_FIND_HEAD: - /* Do not read more than UUENCODE_BID_MAX_READ bytes */ - if (total + len >= UUENCODE_BID_MAX_READ) { - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid format data"); - return (ARCHIVE_FATAL); - } - if (len - nl >= 11 && memcmp(b, "begin ", 6) == 0) - l = 6; - else if (len - nl >= 18 && - memcmp(b, "begin-base64 ", 13) == 0) - l = 13; - else - l = 0; - if (l != 0 && b[l] >= '0' && b[l] <= '7' && - b[l+1] >= '0' && b[l+1] <= '7' && - b[l+2] >= '0' && b[l+2] <= '7' && b[l+3] == ' ') { - if (l == 6) - uudecode->state = ST_READ_UU; - else - uudecode->state = ST_READ_BASE64; - uudecode->mode = (mode_t)( - ((int)(b[l] - '0') * 64) + - ((int)(b[l+1] - '0') * 8) + - (int)(b[l+2] - '0')); - uudecode->mode_set = 1; - namelen = len - nl - 4 - l; - if (namelen > 1) { - if (uudecode->name != NULL) - free(uudecode->name); - uudecode->name = malloc(namelen + 1); - if (uudecode->name == NULL) { - archive_set_error( - &self->archive->archive, - ENOMEM, - "Can't allocate data for uudecode"); - return (ARCHIVE_FATAL); - } - strncpy(uudecode->name, - (const char *)(b + l + 4), - namelen); - uudecode->name[namelen] = '\0'; - } - } - break; - case ST_READ_UU: - if (total + len * 2 > OUT_BUFF_SIZE) - goto finish; - body = len - nl; - if (!uuchar[*b] || body <= 0) { - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Insufficient compressed data"); - return (ARCHIVE_FATAL); - } - /* Get length of undecoded bytes of current line. */ - l = UUDECODE(*b++); - body--; - if (l > body) { - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Insufficient compressed data"); - return (ARCHIVE_FATAL); - } - if (l == 0) { - uudecode->state = ST_UUEND; - break; - } - while (l > 0) { - int n = 0; - - if (!uuchar[b[0]] || !uuchar[b[1]]) - break; - n = UUDECODE(*b++) << 18; - n |= UUDECODE(*b++) << 12; - *out++ = n >> 16; total++; - --l; - - if (l > 0) { - if (!uuchar[b[0]]) - break; - n |= UUDECODE(*b++) << 6; - *out++ = (n >> 8) & 0xFF; total++; - --l; - } - if (l > 0) { - if (!uuchar[b[0]]) - break; - n |= UUDECODE(*b++); - *out++ = n & 0xFF; total++; - --l; - } - } - if (l) { - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Insufficient compressed data"); - return (ARCHIVE_FATAL); - } - break; - case ST_UUEND: - if (len - nl == 3 && memcmp(b, "end ", 3) == 0) - uudecode->state = ST_FIND_HEAD; - else { - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Insufficient compressed data"); - return (ARCHIVE_FATAL); - } - break; - case ST_READ_BASE64: - if (total + len * 2 > OUT_BUFF_SIZE) - goto finish; - l = len - nl; - if (l >= 3 && b[0] == '=' && b[1] == '=' && - b[2] == '=') { - uudecode->state = ST_FIND_HEAD; - break; - } - while (l > 0) { - int n = 0; - - if (!base64[b[0]] || !base64[b[1]]) - break; - n = base64num[*b++] << 18; - n |= base64num[*b++] << 12; - *out++ = n >> 16; total++; - l -= 2; - - if (l > 0) { - if (*b == '=') - break; - if (!base64[*b]) - break; - n |= base64num[*b++] << 6; - *out++ = (n >> 8) & 0xFF; total++; - --l; - } - if (l > 0) { - if (*b == '=') - break; - if (!base64[*b]) - break; - n |= base64num[*b++]; - *out++ = n & 0xFF; total++; - --l; - } - } - if (l && *b != '=') { - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Insufficient compressed data"); - return (ARCHIVE_FATAL); - } - break; - } - } -finish: - if (ravail < avail_in) - used -= avail_in - ravail; - __archive_read_filter_consume(self->upstream, used); - - *buff = uudecode->out_buff; - uudecode->total += total; - return (total); -} - -static int -uudecode_filter_close(struct archive_read_filter *self) -{ - struct uudecode *uudecode; - - uudecode = (struct uudecode *)self->data; - free(uudecode->in_buff); - free(uudecode->out_buff); - free(uudecode->name); - free(uudecode); - - return (ARCHIVE_OK); -} - diff --git a/thirdparty/libarchive/libarchive/archive_read_support_filter_xz.c b/thirdparty/libarchive/libarchive/archive_read_support_filter_xz.c deleted file mode 100644 index e313d39c0..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_filter_xz.c +++ /dev/null @@ -1,793 +0,0 @@ -/*- - * Copyright (c) 2009-2011 Michihiro NAKAJIMA - * Copyright (c) 2003-2008 Tim Kientzle and Miklos Vajna - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#if HAVE_LZMA_H -#include -#endif - -#include "archive.h" -#include "archive_endian.h" -#include "archive_private.h" -#include "archive_read_private.h" - -#if HAVE_LZMA_H && HAVE_LIBLZMA - -struct private_data { - lzma_stream stream; - unsigned char *out_block; - size_t out_block_size; - int64_t total_out; - char eof; /* True = found end of compressed data. */ - char in_stream; - - /* Following variables are used for lzip only. */ - char lzip_ver; - uint32_t crc32; - int64_t member_in; - int64_t member_out; -}; - -#if LZMA_VERSION_MAJOR >= 5 -/* Effectively disable the limiter. */ -#define LZMA_MEMLIMIT UINT64_MAX -#else -/* NOTE: This needs to check memory size which running system has. */ -#define LZMA_MEMLIMIT (1U << 30) -#endif - -/* Combined lzip/lzma/xz filter */ -static ssize_t xz_filter_read(struct archive_read_filter *, const void **); -static int xz_filter_close(struct archive_read_filter *); -static int xz_lzma_bidder_init(struct archive_read_filter *); - -#endif - -/* - * Note that we can detect xz and lzma compressed files even if we - * can't decompress them. (In fact, we like detecting them because we - * can give better error messages.) So the bid framework here gets - * compiled even if no lzma library is available. - */ -static int xz_bidder_bid(struct archive_read_filter_bidder *, - struct archive_read_filter *); -static int xz_bidder_init(struct archive_read_filter *); -static int lzma_bidder_bid(struct archive_read_filter_bidder *, - struct archive_read_filter *); -static int lzma_bidder_init(struct archive_read_filter *); -static int lzip_has_member(struct archive_read_filter *); -static int lzip_bidder_bid(struct archive_read_filter_bidder *, - struct archive_read_filter *); -static int lzip_bidder_init(struct archive_read_filter *); - -#if ARCHIVE_VERSION_NUMBER < 4000000 -/* Deprecated; remove in libarchive 4.0 */ -int -archive_read_support_compression_xz(struct archive *a) -{ - return archive_read_support_filter_xz(a); -} -#endif - -static const struct archive_read_filter_bidder_vtable -xz_bidder_vtable = { - .bid = xz_bidder_bid, - .init = xz_bidder_init, -}; - -int -archive_read_support_filter_xz(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - - if (__archive_read_register_bidder(a, NULL, "xz", - &xz_bidder_vtable) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - -#if HAVE_LZMA_H && HAVE_LIBLZMA - return (ARCHIVE_OK); -#else - archive_set_error(_a, ARCHIVE_ERRNO_MISC, - "Using external xz program for xz decompression"); - return (ARCHIVE_WARN); -#endif -} - -#if ARCHIVE_VERSION_NUMBER < 4000000 -int -archive_read_support_compression_lzma(struct archive *a) -{ - return archive_read_support_filter_lzma(a); -} -#endif - -static const struct archive_read_filter_bidder_vtable -lzma_bidder_vtable = { - .bid = lzma_bidder_bid, - .init = lzma_bidder_init, -}; - -int -archive_read_support_filter_lzma(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - - if (__archive_read_register_bidder(a, NULL, "lzma", - &lzma_bidder_vtable) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - -#if HAVE_LZMA_H && HAVE_LIBLZMA - return (ARCHIVE_OK); -#else - archive_set_error(_a, ARCHIVE_ERRNO_MISC, - "Using external lzma program for lzma decompression"); - return (ARCHIVE_WARN); -#endif -} - - -#if ARCHIVE_VERSION_NUMBER < 4000000 -int -archive_read_support_compression_lzip(struct archive *a) -{ - return archive_read_support_filter_lzip(a); -} -#endif - -static const struct archive_read_filter_bidder_vtable -lzip_bidder_vtable = { - .bid = lzip_bidder_bid, - .init = lzip_bidder_init, -}; - -int -archive_read_support_filter_lzip(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - - if (__archive_read_register_bidder(a, NULL, "lzip", - &lzip_bidder_vtable) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - -#if HAVE_LZMA_H && HAVE_LIBLZMA - return (ARCHIVE_OK); -#else - archive_set_error(_a, ARCHIVE_ERRNO_MISC, - "Using external lzip program for lzip decompression"); - return (ARCHIVE_WARN); -#endif -} - -/* - * Test whether we can handle this data. - */ -static int -xz_bidder_bid(struct archive_read_filter_bidder *self, - struct archive_read_filter *filter) -{ - const unsigned char *buffer; - ssize_t avail; - - (void)self; /* UNUSED */ - - buffer = __archive_read_filter_ahead(filter, 6, &avail); - if (buffer == NULL) - return (0); - - /* - * Verify Header Magic Bytes : FD 37 7A 58 5A 00 - */ - if (memcmp(buffer, "\xFD\x37\x7A\x58\x5A\x00", 6) != 0) - return (0); - - return (48); -} - -/* - * Test whether we can handle this data. - * - * LZMA has a rather poor file signature. Zeros do not - * make good signature bytes as a rule, and the only non-zero byte - * here is an ASCII character. For example, an uncompressed tar - * archive whose first file is ']' would satisfy this check. It may - * be necessary to exclude LZMA from compression_all() because of - * this. Clients of libarchive would then have to explicitly enable - * LZMA checking instead of (or in addition to) compression_all() when - * they have other evidence (file name, command-line option) to go on. - */ -static int -lzma_bidder_bid(struct archive_read_filter_bidder *self, - struct archive_read_filter *filter) -{ - const unsigned char *buffer; - ssize_t avail; - uint32_t dicsize; - uint64_t uncompressed_size; - int bits_checked; - - (void)self; /* UNUSED */ - - buffer = __archive_read_filter_ahead(filter, 14, &avail); - if (buffer == NULL) - return (0); - - /* First byte of raw LZMA stream is commonly 0x5d. - * The first byte is a special number, which consists of - * three parameters of LZMA compression, a number of literal - * context bits(which is from 0 to 8, default is 3), a number - * of literal pos bits(which is from 0 to 4, default is 0), - * a number of pos bits(which is from 0 to 4, default is 2). - * The first byte is made by - * (pos bits * 5 + literal pos bit) * 9 + * literal contest bit, - * and so the default value in this field is - * (2 * 5 + 0) * 9 + 3 = 0x5d. - * lzma of LZMA SDK has options to change those parameters. - * It means a range of this field is from 0 to 224. And lzma of - * XZ Utils with option -e records 0x5e in this field. */ - /* NOTE: If this checking of the first byte increases false - * recognition, we should allow only 0x5d and 0x5e for the first - * byte of LZMA stream. */ - bits_checked = 0; - if (buffer[0] > (4 * 5 + 4) * 9 + 8) - return (0); - /* Most likely value in the first byte of LZMA stream. */ - if (buffer[0] == 0x5d || buffer[0] == 0x5e) - bits_checked += 8; - - /* Sixth through fourteenth bytes are uncompressed size, - * stored in little-endian order. `-1' means uncompressed - * size is unknown and lzma of XZ Utils always records `-1' - * in this field. */ - uncompressed_size = archive_le64dec(buffer+5); - if (uncompressed_size == (uint64_t)ARCHIVE_LITERAL_LL(-1)) - bits_checked += 64; - - /* Second through fifth bytes are dictionary size, stored in - * little-endian order. The minimum dictionary size is - * 1 << 12(4KiB) which the lzma of LZMA SDK uses with option - * -d12 and the maximum dictionary size is 1 << 29(512MiB) - * which the one uses with option -d29. - * NOTE: A comment of LZMA SDK source code says this dictionary - * range is from 1 << 12 to 1 << 30. */ - dicsize = archive_le32dec(buffer+1); - switch (dicsize) { - case 0x00001000:/* lzma of LZMA SDK option -d12. */ - case 0x00002000:/* lzma of LZMA SDK option -d13. */ - case 0x00004000:/* lzma of LZMA SDK option -d14. */ - case 0x00008000:/* lzma of LZMA SDK option -d15. */ - case 0x00010000:/* lzma of XZ Utils option -0 and -1. - * lzma of LZMA SDK option -d16. */ - case 0x00020000:/* lzma of LZMA SDK option -d17. */ - case 0x00040000:/* lzma of LZMA SDK option -d18. */ - case 0x00080000:/* lzma of XZ Utils option -2. - * lzma of LZMA SDK option -d19. */ - case 0x00100000:/* lzma of XZ Utils option -3. - * lzma of LZMA SDK option -d20. */ - case 0x00200000:/* lzma of XZ Utils option -4. - * lzma of LZMA SDK option -d21. */ - case 0x00400000:/* lzma of XZ Utils option -5. - * lzma of LZMA SDK option -d22. */ - case 0x00800000:/* lzma of XZ Utils option -6. - * lzma of LZMA SDK option -d23. */ - case 0x01000000:/* lzma of XZ Utils option -7. - * lzma of LZMA SDK option -d24. */ - case 0x02000000:/* lzma of XZ Utils option -8. - * lzma of LZMA SDK option -d25. */ - case 0x04000000:/* lzma of XZ Utils option -9. - * lzma of LZMA SDK option -d26. */ - case 0x08000000:/* lzma of LZMA SDK option -d27. */ - bits_checked += 32; - break; - default: - /* If a memory usage for encoding was not enough on - * the platform where LZMA stream was made, lzma of - * XZ Utils automatically decreased the dictionary - * size to enough memory for encoding by 1Mi bytes - * (1 << 20).*/ - if (dicsize <= 0x03F00000 && dicsize >= 0x00300000 && - (dicsize & ((1 << 20)-1)) == 0 && - bits_checked == 8 + 64) { - bits_checked += 32; - break; - } - /* Otherwise dictionary size is unlikely. But it is - * possible that someone makes lzma stream with - * liblzma/LZMA SDK in one's dictionary size. */ - return (0); - } - - /* TODO: The above test is still very weak. It would be - * good to do better. */ - - return (bits_checked); -} - -static int -lzip_has_member(struct archive_read_filter *filter) -{ - const unsigned char *buffer; - ssize_t avail; - int bits_checked; - int log2dic; - - buffer = __archive_read_filter_ahead(filter, 6, &avail); - if (buffer == NULL) - return (0); - - /* - * Verify Header Magic Bytes : 4C 5A 49 50 (`LZIP') - */ - bits_checked = 0; - if (memcmp(buffer, "LZIP", 4) != 0) - return (0); - bits_checked += 32; - - /* A version number must be 0 or 1 */ - if (buffer[4] != 0 && buffer[4] != 1) - return (0); - bits_checked += 8; - - /* Dictionary size. */ - log2dic = buffer[5] & 0x1f; - if (log2dic < 12 || log2dic > 29) - return (0); - bits_checked += 8; - - return (bits_checked); -} - -static int -lzip_bidder_bid(struct archive_read_filter_bidder *self, - struct archive_read_filter *filter) -{ - - (void)self; /* UNUSED */ - return (lzip_has_member(filter)); -} - -#if HAVE_LZMA_H && HAVE_LIBLZMA - -/* - * liblzma 4.999.7 and later support both lzma and xz streams. - */ -static int -xz_bidder_init(struct archive_read_filter *self) -{ - self->code = ARCHIVE_FILTER_XZ; - self->name = "xz"; - return (xz_lzma_bidder_init(self)); -} - -static int -lzma_bidder_init(struct archive_read_filter *self) -{ - self->code = ARCHIVE_FILTER_LZMA; - self->name = "lzma"; - return (xz_lzma_bidder_init(self)); -} - -static int -lzip_bidder_init(struct archive_read_filter *self) -{ - self->code = ARCHIVE_FILTER_LZIP; - self->name = "lzip"; - return (xz_lzma_bidder_init(self)); -} - -/* - * Set an error code and choose an error message - */ -static void -set_error(struct archive_read_filter *self, int ret) -{ - - switch (ret) { - case LZMA_STREAM_END: /* Found end of stream. */ - case LZMA_OK: /* Decompressor made some progress. */ - break; - case LZMA_MEM_ERROR: - archive_set_error(&self->archive->archive, ENOMEM, - "Lzma library error: Cannot allocate memory"); - break; - case LZMA_MEMLIMIT_ERROR: - archive_set_error(&self->archive->archive, ENOMEM, - "Lzma library error: Out of memory"); - break; - case LZMA_FORMAT_ERROR: - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Lzma library error: format not recognized"); - break; - case LZMA_OPTIONS_ERROR: - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Lzma library error: Invalid options"); - break; - case LZMA_DATA_ERROR: - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Lzma library error: Corrupted input data"); - break; - case LZMA_BUF_ERROR: - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Lzma library error: No progress is possible"); - break; - default: - /* Return an error. */ - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Lzma decompression failed: Unknown error"); - break; - } -} - -static const struct archive_read_filter_vtable -xz_lzma_reader_vtable = { - .read = xz_filter_read, - .close = xz_filter_close, -}; - -/* - * Setup the callbacks. - */ -static int -xz_lzma_bidder_init(struct archive_read_filter *self) -{ - static const size_t out_block_size = 64 * 1024; - void *out_block; - struct private_data *state; - int ret; - - state = (struct private_data *)calloc(sizeof(*state), 1); - out_block = (unsigned char *)malloc(out_block_size); - if (state == NULL || out_block == NULL) { - archive_set_error(&self->archive->archive, ENOMEM, - "Can't allocate data for xz decompression"); - free(out_block); - free(state); - return (ARCHIVE_FATAL); - } - - self->data = state; - state->out_block_size = out_block_size; - state->out_block = out_block; - self->vtable = &xz_lzma_reader_vtable; - - state->stream.avail_in = 0; - - state->stream.next_out = state->out_block; - state->stream.avail_out = state->out_block_size; - - state->crc32 = 0; - if (self->code == ARCHIVE_FILTER_LZIP) { - /* - * We have to read a lzip header and use it to initialize - * compression library, thus we cannot initialize the - * library for lzip here. - */ - state->in_stream = 0; - return (ARCHIVE_OK); - } else - state->in_stream = 1; - - /* Initialize compression library. */ - if (self->code == ARCHIVE_FILTER_XZ) - ret = lzma_stream_decoder(&(state->stream), - LZMA_MEMLIMIT,/* memlimit */ - LZMA_CONCATENATED); - else - ret = lzma_alone_decoder(&(state->stream), - LZMA_MEMLIMIT);/* memlimit */ - - if (ret == LZMA_OK) - return (ARCHIVE_OK); - - /* Library setup failed: Choose an error message and clean up. */ - set_error(self, ret); - - free(state->out_block); - free(state); - self->data = NULL; - return (ARCHIVE_FATAL); -} - -static int -lzip_init(struct archive_read_filter *self) -{ - struct private_data *state; - const unsigned char *h; - lzma_filter filters[2]; - unsigned char props[5]; - ssize_t avail_in; - uint32_t dicsize; - int log2dic, ret; - - state = (struct private_data *)self->data; - h = __archive_read_filter_ahead(self->upstream, 6, &avail_in); - if (h == NULL) - return (ARCHIVE_FATAL); - - /* Get a version number. */ - state->lzip_ver = h[4]; - - /* - * Setup lzma property. - */ - props[0] = 0x5d; - - /* Get dictionary size. */ - log2dic = h[5] & 0x1f; - if (log2dic < 12 || log2dic > 29) - return (ARCHIVE_FATAL); - dicsize = 1U << log2dic; - if (log2dic > 12) - dicsize -= (dicsize / 16) * (h[5] >> 5); - archive_le32enc(props+1, dicsize); - - /* Consume lzip header. */ - __archive_read_filter_consume(self->upstream, 6); - state->member_in = 6; - - filters[0].id = LZMA_FILTER_LZMA1; - filters[0].options = NULL; - filters[1].id = LZMA_VLI_UNKNOWN; - filters[1].options = NULL; - - ret = lzma_properties_decode(&filters[0], NULL, props, sizeof(props)); - if (ret != LZMA_OK) { - set_error(self, ret); - return (ARCHIVE_FATAL); - } - ret = lzma_raw_decoder(&(state->stream), filters); - free(filters[0].options); - if (ret != LZMA_OK) { - set_error(self, ret); - return (ARCHIVE_FATAL); - } - return (ARCHIVE_OK); -} - -static int -lzip_tail(struct archive_read_filter *self) -{ - struct private_data *state; - const unsigned char *f; - ssize_t avail_in; - int tail; - - state = (struct private_data *)self->data; - if (state->lzip_ver == 0) - tail = 12; - else - tail = 20; - f = __archive_read_filter_ahead(self->upstream, tail, &avail_in); - if (f == NULL && avail_in < 0) - return (ARCHIVE_FATAL); - if (f == NULL || avail_in < tail) { - archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC, - "Lzip: Remaining data is less bytes"); - return (ARCHIVE_FAILED); - } - - /* Check the crc32 value of the uncompressed data of the current - * member */ - if (state->crc32 != archive_le32dec(f)) { -#ifndef DONT_FAIL_ON_CRC_ERROR - archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC, - "Lzip: CRC32 error"); - return (ARCHIVE_FAILED); -#endif - } - - /* Check the uncompressed size of the current member */ - if ((uint64_t)state->member_out != archive_le64dec(f + 4)) { - archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC, - "Lzip: Uncompressed size error"); - return (ARCHIVE_FAILED); - } - - /* Check the total size of the current member */ - if (state->lzip_ver == 1 && - (uint64_t)state->member_in + tail != archive_le64dec(f + 12)) { - archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC, - "Lzip: Member size error"); - return (ARCHIVE_FAILED); - } - __archive_read_filter_consume(self->upstream, tail); - - /* If current lzip data consists of multi member, try decompressing - * a next member. */ - if (lzip_has_member(self->upstream) != 0) { - state->in_stream = 0; - state->crc32 = 0; - state->member_out = 0; - state->member_in = 0; - state->eof = 0; - } - return (ARCHIVE_OK); -} - -/* - * Return the next block of decompressed data. - */ -static ssize_t -xz_filter_read(struct archive_read_filter *self, const void **p) -{ - struct private_data *state; - size_t decompressed; - ssize_t avail_in; - int ret; - - state = (struct private_data *)self->data; - - /* Empty our output buffer. */ - state->stream.next_out = state->out_block; - state->stream.avail_out = state->out_block_size; - - /* Try to fill the output buffer. */ - while (state->stream.avail_out > 0 && !state->eof) { - if (!state->in_stream) { - /* - * Initialize liblzma for lzip - */ - ret = lzip_init(self); - if (ret != ARCHIVE_OK) - return (ret); - state->in_stream = 1; - } - state->stream.next_in = - __archive_read_filter_ahead(self->upstream, 1, &avail_in); - if (state->stream.next_in == NULL && avail_in < 0) { - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "truncated input"); - return (ARCHIVE_FATAL); - } - state->stream.avail_in = avail_in; - - /* Decompress as much as we can in one pass. */ - ret = lzma_code(&(state->stream), - (state->stream.avail_in == 0)? LZMA_FINISH: LZMA_RUN); - switch (ret) { - case LZMA_STREAM_END: /* Found end of stream. */ - state->eof = 1; - /* FALL THROUGH */ - case LZMA_OK: /* Decompressor made some progress. */ - __archive_read_filter_consume(self->upstream, - avail_in - state->stream.avail_in); - state->member_in += - avail_in - state->stream.avail_in; - break; - default: - set_error(self, ret); - return (ARCHIVE_FATAL); - } - } - - decompressed = state->stream.next_out - state->out_block; - state->total_out += decompressed; - state->member_out += decompressed; - if (decompressed == 0) - *p = NULL; - else { - *p = state->out_block; - if (self->code == ARCHIVE_FILTER_LZIP) { - state->crc32 = lzma_crc32(state->out_block, - decompressed, state->crc32); - if (state->eof) { - ret = lzip_tail(self); - if (ret != ARCHIVE_OK) - return (ret); - } - } - } - return (decompressed); -} - -/* - * Clean up the decompressor. - */ -static int -xz_filter_close(struct archive_read_filter *self) -{ - struct private_data *state; - - state = (struct private_data *)self->data; - lzma_end(&(state->stream)); - free(state->out_block); - free(state); - return (ARCHIVE_OK); -} - -#else - -/* - * - * If we have no suitable library on this system, we can't actually do - * the decompression. We can, however, still detect compressed - * archives and emit a useful message. - * - */ -static int -lzma_bidder_init(struct archive_read_filter *self) -{ - int r; - - r = __archive_read_program(self, "lzma -d -qq"); - /* Note: We set the format here even if __archive_read_program() - * above fails. We do, after all, know what the format is - * even if we weren't able to read it. */ - self->code = ARCHIVE_FILTER_LZMA; - self->name = "lzma"; - return (r); -} - -static int -xz_bidder_init(struct archive_read_filter *self) -{ - int r; - - r = __archive_read_program(self, "xz -d -qq"); - /* Note: We set the format here even if __archive_read_program() - * above fails. We do, after all, know what the format is - * even if we weren't able to read it. */ - self->code = ARCHIVE_FILTER_XZ; - self->name = "xz"; - return (r); -} - -static int -lzip_bidder_init(struct archive_read_filter *self) -{ - int r; - - r = __archive_read_program(self, "lzip -d -q"); - /* Note: We set the format here even if __archive_read_program() - * above fails. We do, after all, know what the format is - * even if we weren't able to read it. */ - self->code = ARCHIVE_FILTER_LZIP; - self->name = "lzip"; - return (r); -} - -#endif /* HAVE_LZMA_H */ diff --git a/thirdparty/libarchive/libarchive/archive_read_support_filter_zstd.c b/thirdparty/libarchive/libarchive/archive_read_support_filter_zstd.c deleted file mode 100644 index 1959b5ac3..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_filter_zstd.c +++ /dev/null @@ -1,297 +0,0 @@ -/*- - * Copyright (c) 2009-2011 Sean Purcell - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_ERRNO_H -#include -#endif - -#ifdef HAVE_ERRNO_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#if HAVE_ZSTD_H -#include -#endif - -#include "archive.h" -#include "archive_endian.h" -#include "archive_private.h" -#include "archive_read_private.h" - -#if HAVE_ZSTD_H && HAVE_LIBZSTD - -struct private_data { - ZSTD_DStream *dstream; - unsigned char *out_block; - size_t out_block_size; - int64_t total_out; - char in_frame; /* True = in the middle of a zstd frame. */ - char eof; /* True = found end of compressed data. */ -}; - -/* Zstd Filter. */ -static ssize_t zstd_filter_read(struct archive_read_filter *, const void**); -static int zstd_filter_close(struct archive_read_filter *); -#endif - -/* - * Note that we can detect zstd compressed files even if we can't decompress - * them. (In fact, we like detecting them because we can give better error - * messages.) So the bid framework here gets compiled even if no zstd library - * is available. - */ -static int zstd_bidder_bid(struct archive_read_filter_bidder *, - struct archive_read_filter *); -static int zstd_bidder_init(struct archive_read_filter *); - -static const struct archive_read_filter_bidder_vtable -zstd_bidder_vtable = { - .bid = zstd_bidder_bid, - .init = zstd_bidder_init, -}; - -int -archive_read_support_filter_zstd(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - - if (__archive_read_register_bidder(a, NULL, "zstd", - &zstd_bidder_vtable) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - -#if HAVE_ZSTD_H && HAVE_LIBZSTD - return (ARCHIVE_OK); -#else - archive_set_error(_a, ARCHIVE_ERRNO_MISC, - "Using external zstd program for zstd decompression"); - return (ARCHIVE_WARN); -#endif -} - -/* - * Test whether we can handle this data. - */ -static int -zstd_bidder_bid(struct archive_read_filter_bidder *self, - struct archive_read_filter *filter) -{ - const unsigned char *buffer; - ssize_t avail; - unsigned prefix; - - /* Zstd frame magic values */ - unsigned zstd_magic = 0xFD2FB528U; - unsigned zstd_magic_skippable_start = 0x184D2A50U; - unsigned zstd_magic_skippable_mask = 0xFFFFFFF0; - - (void) self; /* UNUSED */ - - buffer = __archive_read_filter_ahead(filter, 4, &avail); - if (buffer == NULL) - return (0); - - prefix = archive_le32dec(buffer); - if (prefix == zstd_magic) - return (32); - if ((prefix & zstd_magic_skippable_mask) == zstd_magic_skippable_start) - return (32); - - return (0); -} - -#if !(HAVE_ZSTD_H && HAVE_LIBZSTD) - -/* - * If we don't have the library on this system, we can't do the - * decompression directly. We can, however, try to run "zstd -d" - * in case that's available. - */ -static int -zstd_bidder_init(struct archive_read_filter *self) -{ - int r; - - r = __archive_read_program(self, "zstd -d -qq"); - /* Note: We set the format here even if __archive_read_program() - * above fails. We do, after all, know what the format is - * even if we weren't able to read it. */ - self->code = ARCHIVE_FILTER_ZSTD; - self->name = "zstd"; - return (r); -} - -#else - -static const struct archive_read_filter_vtable -zstd_reader_vtable = { - .read = zstd_filter_read, - .close = zstd_filter_close, -}; - -/* - * Initialize the filter object - */ -static int -zstd_bidder_init(struct archive_read_filter *self) -{ - struct private_data *state; - size_t out_block_size = ZSTD_DStreamOutSize(); - void *out_block; - ZSTD_DStream *dstream; - - self->code = ARCHIVE_FILTER_ZSTD; - self->name = "zstd"; - - state = (struct private_data *)calloc(sizeof(*state), 1); - out_block = (unsigned char *)malloc(out_block_size); - dstream = ZSTD_createDStream(); - - if (state == NULL || out_block == NULL || dstream == NULL) { - free(out_block); - free(state); - ZSTD_freeDStream(dstream); /* supports free on NULL */ - archive_set_error(&self->archive->archive, ENOMEM, - "Can't allocate data for zstd decompression"); - return (ARCHIVE_FATAL); - } - - self->data = state; - - state->out_block_size = out_block_size; - state->out_block = out_block; - state->dstream = dstream; - self->vtable = &zstd_reader_vtable; - - state->eof = 0; - state->in_frame = 0; - - return (ARCHIVE_OK); -} - -static ssize_t -zstd_filter_read(struct archive_read_filter *self, const void **p) -{ - struct private_data *state; - size_t decompressed; - ssize_t avail_in; - ZSTD_outBuffer out; - ZSTD_inBuffer in; - size_t ret; - - state = (struct private_data *)self->data; - - out = (ZSTD_outBuffer) { state->out_block, state->out_block_size, 0 }; - - /* Try to fill the output buffer. */ - while (out.pos < out.size && !state->eof) { - if (!state->in_frame) { - ret = ZSTD_initDStream(state->dstream); - if (ZSTD_isError(ret)) { - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Error initializing zstd decompressor: %s", - ZSTD_getErrorName(ret)); - return (ARCHIVE_FATAL); - } - } - in.src = __archive_read_filter_ahead(self->upstream, 1, - &avail_in); - if (avail_in < 0) { - return avail_in; - } - if (in.src == NULL && avail_in == 0) { - if (!state->in_frame) { - /* end of stream */ - state->eof = 1; - break; - } else { - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Truncated zstd input"); - return (ARCHIVE_FATAL); - } - } - in.size = avail_in; - in.pos = 0; - - { - ret = ZSTD_decompressStream(state->dstream, &out, &in); - - if (ZSTD_isError(ret)) { - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Zstd decompression failed: %s", - ZSTD_getErrorName(ret)); - return (ARCHIVE_FATAL); - } - - /* Decompressor made some progress */ - __archive_read_filter_consume(self->upstream, in.pos); - - /* ret guaranteed to be > 0 if frame isn't done yet */ - state->in_frame = (ret != 0); - } - } - - decompressed = out.pos; - state->total_out += decompressed; - if (decompressed == 0) - *p = NULL; - else - *p = state->out_block; - return (decompressed); -} - -/* - * Clean up the decompressor. - */ -static int -zstd_filter_close(struct archive_read_filter *self) -{ - struct private_data *state; - - state = (struct private_data *)self->data; - - ZSTD_freeDStream(state->dstream); - free(state->out_block); - free(state); - - return (ARCHIVE_OK); -} - -#endif /* HAVE_ZLIB_H && HAVE_LIBZSTD */ diff --git a/thirdparty/libarchive/libarchive/archive_read_support_format_7zip.c b/thirdparty/libarchive/libarchive/archive_read_support_format_7zip.c deleted file mode 100644 index 051082bf7..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_format_7zip.c +++ /dev/null @@ -1,4152 +0,0 @@ -/*- - * Copyright (c) 2011 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_BZLIB_H -#include -#endif -#ifdef HAVE_LZMA_H -#include -#endif -#ifdef HAVE_ZLIB_H -#include -#endif -#ifdef HAVE_ZSTD_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" -#include "archive_entry_locale.h" -#include "archive_ppmd7_private.h" -#include "archive_private.h" -#include "archive_read_private.h" -#include "archive_endian.h" - -#ifndef HAVE_ZLIB_H -#include "archive_crc32.h" -#endif - -#define _7ZIP_SIGNATURE "7z\xBC\xAF\x27\x1C" -#define SFX_MIN_ADDR 0x27000 -#define SFX_MAX_ADDR 0x60000 - - -/* - * Codec ID - */ -#define _7Z_COPY 0 -#define _7Z_LZMA 0x030101 -#define _7Z_LZMA2 0x21 -#define _7Z_DEFLATE 0x040108 -#define _7Z_BZ2 0x040202 -#define _7Z_PPMD 0x030401 -#define _7Z_DELTA 0x03 -#define _7Z_CRYPTO_MAIN_ZIP 0x06F10101 /* Main Zip crypto algo */ -#define _7Z_CRYPTO_RAR_29 0x06F10303 /* Rar29 AES-128 + (modified SHA-1) */ -#define _7Z_CRYPTO_AES_256_SHA_256 0x06F10701 /* AES-256 + SHA-256 */ - - -#define _7Z_X86 0x03030103 -#define _7Z_X86_BCJ2 0x0303011B -#define _7Z_POWERPC 0x03030205 -#define _7Z_IA64 0x03030401 -#define _7Z_ARM 0x03030501 -#define _7Z_ARMTHUMB 0x03030701 -#define _7Z_ARM64 0xa -#define _7Z_SPARC 0x03030805 - -#define _7Z_ZSTD 0x4F71101 /* Copied from https://github.com/mcmilk/7-Zip-zstd.git */ - -/* - * 7-Zip header property IDs. - */ -#define kEnd 0x00 -#define kHeader 0x01 -#define kArchiveProperties 0x02 -#define kAdditionalStreamsInfo 0x03 -#define kMainStreamsInfo 0x04 -#define kFilesInfo 0x05 -#define kPackInfo 0x06 -#define kUnPackInfo 0x07 -#define kSubStreamsInfo 0x08 -#define kSize 0x09 -#define kCRC 0x0A -#define kFolder 0x0B -#define kCodersUnPackSize 0x0C -#define kNumUnPackStream 0x0D -#define kEmptyStream 0x0E -#define kEmptyFile 0x0F -#define kAnti 0x10 -#define kName 0x11 -#define kCTime 0x12 -#define kATime 0x13 -#define kMTime 0x14 -#define kAttributes 0x15 -#define kEncodedHeader 0x17 -#define kDummy 0x19 - -// Check that some windows file attribute constants are defined. -// Reference: https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants -#ifndef FILE_ATTRIBUTE_READONLY -#define FILE_ATTRIBUTE_READONLY 0x00000001 -#endif - -#ifndef FILE_ATTRIBUTE_HIDDEN -#define FILE_ATTRIBUTE_HIDDEN 0x00000002 -#endif - -#ifndef FILE_ATTRIBUTE_SYSTEM -#define FILE_ATTRIBUTE_SYSTEM 0x00000004 -#endif - -#ifndef FILE_ATTRIBUTE_DIRECTORY -#define FILE_ATTRIBUTE_DIRECTORY 0x00000010 -#endif - -// This value is defined in 7zip with the comment "trick for Unix". -// -// 7z archives created on unix have this bit set in the high 16 bits of -// the attr field along with the unix permissions. -#define FILE_ATTRIBUTE_UNIX_EXTENSION 0x8000 - -struct _7z_digests { - unsigned char *defineds; - uint32_t *digests; -}; - - -struct _7z_folder { - uint64_t numCoders; - struct _7z_coder { - unsigned long codec; - uint64_t numInStreams; - uint64_t numOutStreams; - uint64_t propertiesSize; - unsigned char *properties; - } *coders; - uint64_t numBindPairs; - struct { - uint64_t inIndex; - uint64_t outIndex; - } *bindPairs; - uint64_t numPackedStreams; - uint64_t *packedStreams; - uint64_t numInStreams; - uint64_t numOutStreams; - uint64_t *unPackSize; - unsigned char digest_defined; - uint32_t digest; - uint64_t numUnpackStreams; - uint32_t packIndex; - /* Unoperated bytes. */ - uint64_t skipped_bytes; -}; - -struct _7z_coders_info { - uint64_t numFolders; - struct _7z_folder *folders; - uint64_t dataStreamIndex; -}; - -struct _7z_pack_info { - uint64_t pos; - uint64_t numPackStreams; - uint64_t *sizes; - struct _7z_digests digest; - /* Calculated from pos and numPackStreams. */ - uint64_t *positions; -}; - -struct _7z_substream_info { - size_t unpack_streams; - uint64_t *unpackSizes; - unsigned char *digestsDefined; - uint32_t *digests; -}; - -struct _7z_stream_info { - struct _7z_pack_info pi; - struct _7z_coders_info ci; - struct _7z_substream_info ss; -}; - -struct _7z_header_info { - uint64_t dataIndex; - - unsigned char *emptyStreamBools; - unsigned char *emptyFileBools; - unsigned char *antiBools; - unsigned char *attrBools; -}; - -struct _7zip_entry { - size_t name_len; - unsigned char *utf16name; -#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG) - const wchar_t *wname; -#endif - uint32_t folderIndex; - uint32_t ssIndex; - unsigned flg; -#define MTIME_IS_SET (1<<0) -#define ATIME_IS_SET (1<<1) -#define CTIME_IS_SET (1<<2) -#define CRC32_IS_SET (1<<3) -#define HAS_STREAM (1<<4) - - time_t mtime; - time_t atime; - time_t ctime; - long mtime_ns; - long atime_ns; - long ctime_ns; - uint32_t mode; - uint32_t attr; -}; - -struct _7zip { - /* Structural information about the archive. */ - struct _7z_stream_info si; - - int header_is_being_read; - int header_is_encoded; - uint64_t header_bytes_remaining; - unsigned long header_crc32; - /* Header offset to check that reading points of the file contents - * will not exceed the header. */ - uint64_t header_offset; - /* Base offset of the archive file for a seek in case reading SFX. */ - uint64_t seek_base; - - /* List of entries */ - size_t entries_remaining; - uint64_t numFiles; - struct _7zip_entry *entries; - struct _7zip_entry *entry; - unsigned char *entry_names; - - /* entry_bytes_remaining is the number of bytes we expect. */ - int64_t entry_offset; - uint64_t entry_bytes_remaining; - - /* Running CRC32 of the decompressed data */ - unsigned long entry_crc32; - - /* Flags to mark progress of decompression. */ - char end_of_entry; - - /* Uncompressed buffer control. */ -#define UBUFF_SIZE (64 * 1024) - unsigned char *uncompressed_buffer; - unsigned char *uncompressed_buffer_pointer; - size_t uncompressed_buffer_size; - size_t uncompressed_buffer_bytes_remaining; - - /* Offset of the compressed data. */ - int64_t stream_offset; - - /* - * Decompressing control data. - */ - unsigned folder_index; - uint64_t folder_outbytes_remaining; - unsigned pack_stream_index; - unsigned pack_stream_remaining; - uint64_t pack_stream_inbytes_remaining; - size_t pack_stream_bytes_unconsumed; - - /* The codec information of a folder. */ - unsigned long codec; - unsigned long codec2; - - /* - * Decompressor controllers. - */ - /* Decoding LZMA1 and LZMA2 data. */ -#ifdef HAVE_LZMA_H - lzma_stream lzstream; - int lzstream_valid; -#endif - /* Decoding bzip2 data. */ -#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) - bz_stream bzstream; - int bzstream_valid; -#endif - /* Decoding deflate data. */ -#ifdef HAVE_ZLIB_H - z_stream stream; - int stream_valid; -#endif - /* Decoding Zstandard data. */ -#if HAVE_ZSTD_H - ZSTD_DStream *zstd_dstream; - int zstdstream_valid; -#endif - /* Decoding PPMd data. */ - int ppmd7_stat; - CPpmd7 ppmd7_context; - CPpmd7z_RangeDec range_dec; - IByteIn bytein; - struct { - const unsigned char *next_in; - int64_t avail_in; - int64_t total_in; - int64_t stream_in; - unsigned char *next_out; - int64_t avail_out; - int64_t total_out; - int overconsumed; - } ppstream; - int ppmd7_valid; - - /* Decoding BCJ and BCJ2 data. */ - uint32_t bcj_state; - size_t odd_bcj_size; - unsigned char odd_bcj[4]; - /* Decoding BCJ data. */ - size_t bcj_prevPosT; - uint32_t bcj_prevMask; - uint32_t bcj_ip; - - /* Decoding BCJ2 data. */ - size_t main_stream_bytes_remaining; - unsigned char *sub_stream_buff[3]; - size_t sub_stream_size[3]; - size_t sub_stream_bytes_remaining[3]; - unsigned char *tmp_stream_buff; - size_t tmp_stream_buff_size; - size_t tmp_stream_bytes_avail; - size_t tmp_stream_bytes_remaining; -#ifdef _LZMA_PROB32 -#define CProb uint32_t -#else -#define CProb uint16_t -#endif - CProb bcj2_p[256 + 2]; - uint8_t bcj2_prevByte; - uint32_t bcj2_range; - uint32_t bcj2_code; - uint64_t bcj2_outPos; - - /* Filename character-set conversion data. */ - struct archive_string_conv *sconv; - - char format_name[64]; - - /* Custom value that is non-zero if this archive contains encrypted entries. */ - int has_encrypted_entries; -}; - -/* Maximum entry size. This limitation prevents reading intentional - * corrupted 7-zip files on assuming there are not so many entries in - * the files. */ -#define UMAX_ENTRY ARCHIVE_LITERAL_ULL(100000000) - -static int archive_read_format_7zip_has_encrypted_entries(struct archive_read *); -static int archive_read_support_format_7zip_capabilities(struct archive_read *a); -static int archive_read_format_7zip_bid(struct archive_read *, int); -static int archive_read_format_7zip_cleanup(struct archive_read *); -static int archive_read_format_7zip_read_data(struct archive_read *, - const void **, size_t *, int64_t *); -static int archive_read_format_7zip_read_data_skip(struct archive_read *); -static int archive_read_format_7zip_read_header(struct archive_read *, - struct archive_entry *); -static int check_7zip_header_in_sfx(const char *); -static unsigned long decode_codec_id(const unsigned char *, size_t); -static int decode_encoded_header_info(struct archive_read *, - struct _7z_stream_info *); -static int decompress(struct archive_read *, struct _7zip *, - void *, size_t *, const void *, size_t *); -static ssize_t extract_pack_stream(struct archive_read *, size_t); -static void fileTimeToUtc(uint64_t, time_t *, long *); -static uint64_t folder_uncompressed_size(struct _7z_folder *); -static void free_CodersInfo(struct _7z_coders_info *); -static void free_Digest(struct _7z_digests *); -static void free_Folder(struct _7z_folder *); -static void free_Header(struct _7z_header_info *); -static void free_PackInfo(struct _7z_pack_info *); -static void free_StreamsInfo(struct _7z_stream_info *); -static void free_SubStreamsInfo(struct _7z_substream_info *); -static int free_decompression(struct archive_read *, struct _7zip *); -static ssize_t get_uncompressed_data(struct archive_read *, const void **, - size_t, size_t); -static const unsigned char * header_bytes(struct archive_read *, size_t); -static int init_decompression(struct archive_read *, struct _7zip *, - const struct _7z_coder *, const struct _7z_coder *); -static int parse_7zip_uint64(struct archive_read *, uint64_t *); -static int read_Bools(struct archive_read *, unsigned char *, size_t); -static int read_CodersInfo(struct archive_read *, - struct _7z_coders_info *); -static int read_Digests(struct archive_read *, struct _7z_digests *, - size_t); -static int read_Folder(struct archive_read *, struct _7z_folder *); -static int read_Header(struct archive_read *, struct _7z_header_info *, - int); -static int read_PackInfo(struct archive_read *, struct _7z_pack_info *); -static int read_StreamsInfo(struct archive_read *, - struct _7z_stream_info *); -static int read_SubStreamsInfo(struct archive_read *, - struct _7z_substream_info *, struct _7z_folder *, size_t); -static int read_Times(struct archive_read *, struct _7z_header_info *, - int); -static void read_consume(struct archive_read *); -static ssize_t read_stream(struct archive_read *, const void **, size_t, - size_t); -static int seek_pack(struct archive_read *); -static int64_t skip_stream(struct archive_read *, size_t); -static int skip_sfx(struct archive_read *, ssize_t); -static int slurp_central_directory(struct archive_read *, struct _7zip *, - struct _7z_header_info *); -static int setup_decode_folder(struct archive_read *, struct _7z_folder *, - int); -static void x86_Init(struct _7zip *); -static size_t x86_Convert(struct _7zip *, uint8_t *, size_t); -static void arm_Init(struct _7zip *); -static size_t arm_Convert(struct _7zip *, uint8_t *, size_t); -static size_t arm64_Convert(struct _7zip *, uint8_t *, size_t); -static ssize_t Bcj2_Decode(struct _7zip *, uint8_t *, size_t); - - -int -archive_read_support_format_7zip(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - struct _7zip *zip; - int r; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_format_7zip"); - - zip = calloc(1, sizeof(*zip)); - if (zip == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate 7zip data"); - return (ARCHIVE_FATAL); - } - - /* - * Until enough data has been read, we cannot tell about - * any encrypted entries yet. - */ - zip->has_encrypted_entries = ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW; - - - r = __archive_read_register_format(a, - zip, - "7zip", - archive_read_format_7zip_bid, - NULL, - archive_read_format_7zip_read_header, - archive_read_format_7zip_read_data, - archive_read_format_7zip_read_data_skip, - NULL, - archive_read_format_7zip_cleanup, - archive_read_support_format_7zip_capabilities, - archive_read_format_7zip_has_encrypted_entries); - - if (r != ARCHIVE_OK) - free(zip); - return (ARCHIVE_OK); -} - -static int -archive_read_support_format_7zip_capabilities(struct archive_read * a) -{ - (void)a; /* UNUSED */ - return (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA | - ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA); -} - - -static int -archive_read_format_7zip_has_encrypted_entries(struct archive_read *_a) -{ - if (_a && _a->format) { - struct _7zip * zip = (struct _7zip *)_a->format->data; - if (zip) { - return zip->has_encrypted_entries; - } - } - return ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW; -} - -static int -archive_read_format_7zip_bid(struct archive_read *a, int best_bid) -{ - const char *p; - - /* If someone has already bid more than 32, then avoid - trashing the look-ahead buffers with a seek. */ - if (best_bid > 32) - return (-1); - - if ((p = __archive_read_ahead(a, 6, NULL)) == NULL) - return (0); - - /* If first six bytes are the 7-Zip signature, - * return the bid right now. */ - if (memcmp(p, _7ZIP_SIGNATURE, 6) == 0) - return (48); - - /* - * It may a 7-Zip SFX archive file. If first two bytes are - * 'M' and 'Z' available on Windows or first four bytes are - * "\x7F\x45LF" available on posix like system, seek the 7-Zip - * signature. Although we will perform a seek when reading - * a header, what we do not use __archive_read_seek() here is - * due to a bidding performance. - */ - if ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0) { - ssize_t offset = SFX_MIN_ADDR; - ssize_t window = 4096; - ssize_t bytes_avail; - while (offset + window <= (SFX_MAX_ADDR)) { - const char *buff = __archive_read_ahead(a, - offset + window, &bytes_avail); - if (buff == NULL) { - /* Remaining bytes are less than window. */ - window >>= 1; - if (window < 0x40) - return (0); - continue; - } - p = buff + offset; - while (p + 32 < buff + bytes_avail) { - int step = check_7zip_header_in_sfx(p); - if (step == 0) - return (48); - p += step; - } - offset = p - buff; - } - } - return (0); -} - -static int -check_7zip_header_in_sfx(const char *p) -{ - switch ((unsigned char)p[5]) { - case 0x1C: - if (memcmp(p, _7ZIP_SIGNATURE, 6) != 0) - return (6); - /* - * Test the CRC because its extraction code has 7-Zip - * Magic Code, so we should do this in order not to - * make a mis-detection. - */ - if (crc32(0, (const unsigned char *)p + 12, 20) - != archive_le32dec(p + 8)) - return (6); - /* Hit the header! */ - return (0); - case 0x37: return (5); - case 0x7A: return (4); - case 0xBC: return (3); - case 0xAF: return (2); - case 0x27: return (1); - default: return (6); - } -} - -static int -skip_sfx(struct archive_read *a, ssize_t bytes_avail) -{ - const void *h; - const char *p, *q; - size_t skip, offset; - ssize_t bytes, window; - - /* - * If bytes_avail > SFX_MIN_ADDR we do not have to call - * __archive_read_seek() at this time since we have - * already had enough data. - */ - if (bytes_avail > SFX_MIN_ADDR) - __archive_read_consume(a, SFX_MIN_ADDR); - else if (__archive_read_seek(a, SFX_MIN_ADDR, SEEK_SET) < 0) - return (ARCHIVE_FATAL); - - offset = 0; - window = 1; - while (offset + window <= SFX_MAX_ADDR - SFX_MIN_ADDR) { - h = __archive_read_ahead(a, window, &bytes); - if (h == NULL) { - /* Remaining bytes are less than window. */ - window >>= 1; - if (window < 0x40) - goto fatal; - continue; - } - if (bytes < 6) { - /* This case might happen when window == 1. */ - window = 4096; - continue; - } - p = (const char *)h; - q = p + bytes; - - /* - * Scan ahead until we find something that looks - * like the 7-Zip header. - */ - while (p + 32 < q) { - int step = check_7zip_header_in_sfx(p); - if (step == 0) { - struct _7zip *zip = - (struct _7zip *)a->format->data; - skip = p - (const char *)h; - __archive_read_consume(a, skip); - zip->seek_base = SFX_MIN_ADDR + offset + skip; - return (ARCHIVE_OK); - } - p += step; - } - skip = p - (const char *)h; - __archive_read_consume(a, skip); - offset += skip; - if (window == 1) - window = 4096; - } -fatal: - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Couldn't find out 7-Zip header"); - return (ARCHIVE_FATAL); -} - -static int -archive_read_format_7zip_read_header(struct archive_read *a, - struct archive_entry *entry) -{ - struct _7zip *zip = (struct _7zip *)a->format->data; - struct _7zip_entry *zip_entry; - int r, ret = ARCHIVE_OK; - struct _7z_folder *folder = 0; - uint64_t fidx = 0; - - /* - * It should be sufficient to call archive_read_next_header() for - * a reader to determine if an entry is encrypted or not. If the - * encryption of an entry is only detectable when calling - * archive_read_data(), so be it. We'll do the same check there - * as well. - */ - if (zip->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) { - zip->has_encrypted_entries = 0; - } - - a->archive.archive_format = ARCHIVE_FORMAT_7ZIP; - if (a->archive.archive_format_name == NULL) - a->archive.archive_format_name = "7-Zip"; - - if (zip->entries == NULL) { - struct _7z_header_info header; - - memset(&header, 0, sizeof(header)); - r = slurp_central_directory(a, zip, &header); - free_Header(&header); - if (r != ARCHIVE_OK) - return (r); - zip->entries_remaining = (size_t)zip->numFiles; - zip->entry = zip->entries; - } else { - ++zip->entry; - } - zip_entry = zip->entry; - - if (zip->entries_remaining <= 0 || zip_entry == NULL) - return ARCHIVE_EOF; - --zip->entries_remaining; - - zip->entry_offset = 0; - zip->end_of_entry = 0; - zip->entry_crc32 = crc32(0, NULL, 0); - - /* Setup a string conversion for a filename. */ - if (zip->sconv == NULL) { - zip->sconv = archive_string_conversion_from_charset( - &a->archive, "UTF-16LE", 1); - if (zip->sconv == NULL) - return (ARCHIVE_FATAL); - } - - /* Figure out if the entry is encrypted by looking at the folder - that is associated to the current 7zip entry. If the folder - has a coder with a _7Z_CRYPTO codec then the folder is encrypted. - Hence the entry must also be encrypted. */ - if (zip_entry && zip_entry->folderIndex < zip->si.ci.numFolders) { - folder = &(zip->si.ci.folders[zip_entry->folderIndex]); - for (fidx=0; folder && fidxnumCoders; fidx++) { - switch(folder->coders[fidx].codec) { - case _7Z_CRYPTO_MAIN_ZIP: - case _7Z_CRYPTO_RAR_29: - case _7Z_CRYPTO_AES_256_SHA_256: { - archive_entry_set_is_data_encrypted(entry, 1); - zip->has_encrypted_entries = 1; - break; - } - } - } - } - - /* Now that we've checked for encryption, if there were still no - * encrypted entries found we can say for sure that there are none. - */ - if (zip->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) { - zip->has_encrypted_entries = 0; - } - - if (archive_entry_copy_pathname_l(entry, - (const char *)zip_entry->utf16name, - zip_entry->name_len, zip->sconv) != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Pathname"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Pathname cannot be converted " - "from %s to current locale.", - archive_string_conversion_charset_name(zip->sconv)); - ret = ARCHIVE_WARN; - } - - /* Populate some additional entry fields: */ - archive_entry_set_mode(entry, zip_entry->mode); - if (zip_entry->flg & MTIME_IS_SET) - archive_entry_set_mtime(entry, zip_entry->mtime, - zip_entry->mtime_ns); - if (zip_entry->flg & CTIME_IS_SET) - archive_entry_set_ctime(entry, zip_entry->ctime, - zip_entry->ctime_ns); - if (zip_entry->flg & ATIME_IS_SET) - archive_entry_set_atime(entry, zip_entry->atime, - zip_entry->atime_ns); - if (zip_entry->ssIndex != (uint32_t)-1) { - zip->entry_bytes_remaining = - zip->si.ss.unpackSizes[zip_entry->ssIndex]; - archive_entry_set_size(entry, zip->entry_bytes_remaining); - } else { - zip->entry_bytes_remaining = 0; - archive_entry_set_size(entry, 0); - } - - // These attributes are supported by the windows implementation of archive_write_disk. - const int supported_attrs = FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM; - - if (zip_entry->attr & supported_attrs) { - char *fflags_text, *ptr; - /* allocate for "rdonly,hidden,system," */ - fflags_text = malloc(22 * sizeof(char)); - if (fflags_text != NULL) { - ptr = fflags_text; - if (zip_entry->attr & FILE_ATTRIBUTE_READONLY) { - strcpy(ptr, "rdonly,"); - ptr = ptr + 7; - } - if (zip_entry->attr & FILE_ATTRIBUTE_HIDDEN) { - strcpy(ptr, "hidden,"); - ptr = ptr + 7; - } - if (zip_entry->attr & FILE_ATTRIBUTE_SYSTEM) { - strcpy(ptr, "system,"); - ptr = ptr + 7; - } - if (ptr > fflags_text) { - /* Delete trailing comma */ - *(ptr - 1) = '\0'; - archive_entry_copy_fflags_text(entry, - fflags_text); - } - free(fflags_text); - } - } - - /* If there's no body, force read_data() to return EOF immediately. */ - if (zip->entry_bytes_remaining < 1) - zip->end_of_entry = 1; - - if ((zip_entry->mode & AE_IFMT) == AE_IFLNK) { - unsigned char *symname = NULL; - size_t symsize = 0; - - /* - * Symbolic-name is recorded as its contents. We have to - * read the contents at this time. - */ - while (zip->entry_bytes_remaining > 0) { - const void *buff; - unsigned char *mem; - size_t size; - int64_t offset; - - r = archive_read_format_7zip_read_data(a, &buff, - &size, &offset); - if (r < ARCHIVE_WARN) { - free(symname); - return (r); - } - mem = realloc(symname, symsize + size + 1); - if (mem == NULL) { - free(symname); - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Symname"); - return (ARCHIVE_FATAL); - } - symname = mem; - memcpy(symname+symsize, buff, size); - symsize += size; - } - if (symsize == 0) { - /* If there is no symname, handle it as a regular - * file. */ - zip_entry->mode &= ~AE_IFMT; - zip_entry->mode |= AE_IFREG; - archive_entry_set_mode(entry, zip_entry->mode); - } else { - symname[symsize] = '\0'; - archive_entry_copy_symlink(entry, - (const char *)symname); - } - free(symname); - archive_entry_set_size(entry, 0); - } - - /* Set up a more descriptive format name. */ - snprintf(zip->format_name, sizeof(zip->format_name), "7-Zip"); - a->archive.archive_format_name = zip->format_name; - - return (ret); -} - -static int -archive_read_format_7zip_read_data(struct archive_read *a, - const void **buff, size_t *size, int64_t *offset) -{ - struct _7zip *zip; - ssize_t bytes; - int ret = ARCHIVE_OK; - - zip = (struct _7zip *)(a->format->data); - - if (zip->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) { - zip->has_encrypted_entries = 0; - } - - if (zip->pack_stream_bytes_unconsumed) - read_consume(a); - - *offset = zip->entry_offset; - *size = 0; - *buff = NULL; - /* - * If we hit end-of-entry last time, clean up and return - * ARCHIVE_EOF this time. - */ - if (zip->end_of_entry) - return (ARCHIVE_EOF); - - const uint64_t max_read_size = 16 * 1024 * 1024; // Don't try to read more than 16 MB at a time - size_t bytes_to_read = max_read_size; - if ((uint64_t)bytes_to_read > zip->entry_bytes_remaining) { - bytes_to_read = zip->entry_bytes_remaining; - } - bytes = read_stream(a, buff, bytes_to_read, 0); - if (bytes < 0) - return ((int)bytes); - if (bytes == 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated 7-Zip file body"); - return (ARCHIVE_FATAL); - } - zip->entry_bytes_remaining -= bytes; - if (zip->entry_bytes_remaining == 0) - zip->end_of_entry = 1; - - /* Update checksum */ - if ((zip->entry->flg & CRC32_IS_SET) && bytes) - zip->entry_crc32 = crc32(zip->entry_crc32, *buff, - (unsigned)bytes); - - /* If we hit the end, swallow any end-of-data marker. */ - if (zip->end_of_entry) { - /* Check computed CRC against file contents. */ - if ((zip->entry->flg & CRC32_IS_SET) && - zip->si.ss.digests[zip->entry->ssIndex] != - zip->entry_crc32) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "7-Zip bad CRC: 0x%lx should be 0x%lx", - (unsigned long)zip->entry_crc32, - (unsigned long)zip->si.ss.digests[ - zip->entry->ssIndex]); - ret = ARCHIVE_WARN; - } - } - - *size = bytes; - *offset = zip->entry_offset; - zip->entry_offset += bytes; - - return (ret); -} - -static int -archive_read_format_7zip_read_data_skip(struct archive_read *a) -{ - struct _7zip *zip; - int64_t bytes_skipped; - - zip = (struct _7zip *)(a->format->data); - - if (zip->pack_stream_bytes_unconsumed) - read_consume(a); - - /* If we've already read to end of data, we're done. */ - if (zip->end_of_entry) - return (ARCHIVE_OK); - - /* - * If the length is at the beginning, we can skip the - * compressed data much more quickly. - */ - bytes_skipped = skip_stream(a, (size_t)zip->entry_bytes_remaining); - if (bytes_skipped < 0) - return (ARCHIVE_FATAL); - zip->entry_bytes_remaining = 0; - - /* This entry is finished and done. */ - zip->end_of_entry = 1; - return (ARCHIVE_OK); -} - -static int -archive_read_format_7zip_cleanup(struct archive_read *a) -{ - struct _7zip *zip; - - zip = (struct _7zip *)(a->format->data); - free_StreamsInfo(&(zip->si)); - free(zip->entries); - free(zip->entry_names); - free_decompression(a, zip); - free(zip->uncompressed_buffer); - free(zip->sub_stream_buff[0]); - free(zip->sub_stream_buff[1]); - free(zip->sub_stream_buff[2]); - free(zip->tmp_stream_buff); - free(zip); - (a->format->data) = NULL; - return (ARCHIVE_OK); -} - -static void -read_consume(struct archive_read *a) -{ - struct _7zip *zip = (struct _7zip *)a->format->data; - - if (zip->pack_stream_bytes_unconsumed) { - __archive_read_consume(a, zip->pack_stream_bytes_unconsumed); - zip->stream_offset += zip->pack_stream_bytes_unconsumed; - zip->pack_stream_bytes_unconsumed = 0; - } -} - -#ifdef HAVE_LZMA_H - -/* - * Set an error code and choose an error message for liblzma. - */ -static void -set_error(struct archive_read *a, int ret) -{ - - switch (ret) { - case LZMA_STREAM_END: /* Found end of stream. */ - case LZMA_OK: /* Decompressor made some progress. */ - break; - case LZMA_MEM_ERROR: - archive_set_error(&a->archive, ENOMEM, - "Lzma library error: Cannot allocate memory"); - break; - case LZMA_MEMLIMIT_ERROR: - archive_set_error(&a->archive, ENOMEM, - "Lzma library error: Out of memory"); - break; - case LZMA_FORMAT_ERROR: - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Lzma library error: format not recognized"); - break; - case LZMA_OPTIONS_ERROR: - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Lzma library error: Invalid options"); - break; - case LZMA_DATA_ERROR: - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Lzma library error: Corrupted input data"); - break; - case LZMA_BUF_ERROR: - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Lzma library error: No progress is possible"); - break; - default: - /* Return an error. */ - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Lzma decompression failed: Unknown error"); - break; - } -} - -#endif - -static unsigned long -decode_codec_id(const unsigned char *codecId, size_t id_size) -{ - unsigned i; - unsigned long id = 0; - - for (i = 0; i < id_size; i++) { - id <<= 8; - id += codecId[i]; - } - return (id); -} - -static Byte -ppmd_read(void *p) -{ - struct archive_read *a = ((IByteIn*)p)->a; - struct _7zip *zip = (struct _7zip *)(a->format->data); - Byte b; - - if (zip->ppstream.avail_in <= 0) { - /* - * Ppmd7_DecodeSymbol might require reading multiple bytes - * and we are on boundary; - * last resort to read using __archive_read_ahead. - */ - ssize_t bytes_avail = 0; - const uint8_t* data = __archive_read_ahead(a, - zip->ppstream.stream_in+1, &bytes_avail); - if(bytes_avail < zip->ppstream.stream_in+1) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated 7z file data"); - zip->ppstream.overconsumed = 1; - return (0); - } - zip->ppstream.next_in++; - b = data[zip->ppstream.stream_in]; - } else { - b = *zip->ppstream.next_in++; - } - zip->ppstream.avail_in--; - zip->ppstream.total_in++; - zip->ppstream.stream_in++; - return (b); -} - -static int -init_decompression(struct archive_read *a, struct _7zip *zip, - const struct _7z_coder *coder1, const struct _7z_coder *coder2) -{ - int r; - - zip->codec = coder1->codec; - zip->codec2 = -1; - - switch (zip->codec) { - case _7Z_COPY: - case _7Z_BZ2: - case _7Z_DEFLATE: - case _7Z_ZSTD: - case _7Z_PPMD: - if (coder2 != NULL) { - if (coder2->codec != _7Z_X86 && - coder2->codec != _7Z_X86_BCJ2 && - coder2->codec != _7Z_ARM && - coder2->codec != _7Z_ARM64) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Unsupported filter %lx for %lx", - coder2->codec, coder1->codec); - return (ARCHIVE_FAILED); - } - zip->codec2 = coder2->codec; - zip->bcj_state = 0; - if (coder2->codec == _7Z_X86) - x86_Init(zip); - else if (coder2->codec == _7Z_ARM) - arm_Init(zip); - } - break; - default: - break; - } - - switch (zip->codec) { - case _7Z_COPY: - break; - - case _7Z_LZMA: case _7Z_LZMA2: -#ifdef HAVE_LZMA_H -#if LZMA_VERSION_MAJOR >= 5 -/* Effectively disable the limiter. */ -#define LZMA_MEMLIMIT UINT64_MAX -#else -/* NOTE: This needs to check memory size which running system has. */ -#define LZMA_MEMLIMIT (1U << 30) -#endif - { - lzma_options_delta delta_opt; - lzma_filter filters[LZMA_FILTERS_MAX], *ff; - int fi = 0; - - if (zip->lzstream_valid) { - lzma_end(&(zip->lzstream)); - zip->lzstream_valid = 0; - } - - /* - * NOTE: liblzma incompletely handle the BCJ+LZMA compressed - * data made by 7-Zip because 7-Zip does not add End-Of- - * Payload Marker(EOPM) at the end of LZMA compressed data, - * and so liblzma cannot know the end of the compressed data - * without EOPM. So consequently liblzma will not return last - * three or four bytes of uncompressed data because - * LZMA_FILTER_X86 filter does not handle input data if its - * data size is less than five bytes. If liblzma detect EOPM - * or know the uncompressed data size, liblzma will flush out - * the remaining that three or four bytes of uncompressed - * data. That is why we have to use our converting program - * for BCJ+LZMA. If we were able to tell the uncompressed - * size to liblzma when using lzma_raw_decoder() liblzma - * could correctly deal with BCJ+LZMA. But unfortunately - * there is no way to do that. - * Discussion about this can be found at XZ Utils forum. - */ - if (coder2 != NULL) { - zip->codec2 = coder2->codec; - - filters[fi].options = NULL; - switch (zip->codec2) { - case _7Z_X86: - if (zip->codec == _7Z_LZMA2) { - filters[fi].id = LZMA_FILTER_X86; - fi++; - } else - /* Use our filter. */ - x86_Init(zip); - break; - case _7Z_X86_BCJ2: - /* Use our filter. */ - zip->bcj_state = 0; - break; - case _7Z_DELTA: - if (coder2->propertiesSize != 1) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Invalid Delta parameter"); - return (ARCHIVE_FAILED); - } - filters[fi].id = LZMA_FILTER_DELTA; - memset(&delta_opt, 0, sizeof(delta_opt)); - delta_opt.type = LZMA_DELTA_TYPE_BYTE; - delta_opt.dist = - (uint32_t)coder2->properties[0] + 1; - filters[fi].options = &delta_opt; - fi++; - break; - /* Following filters have not been tested yet. */ - case _7Z_POWERPC: - filters[fi].id = LZMA_FILTER_POWERPC; - fi++; - break; - case _7Z_IA64: - filters[fi].id = LZMA_FILTER_IA64; - fi++; - break; - case _7Z_ARM: - filters[fi].id = LZMA_FILTER_ARM; - fi++; - break; - case _7Z_ARMTHUMB: - filters[fi].id = LZMA_FILTER_ARMTHUMB; - fi++; - break; -#ifdef LZMA_FILTER_ARM64 - case _7Z_ARM64: - filters[fi].id = LZMA_FILTER_ARM64; - fi++; - break; -#endif - case _7Z_SPARC: - filters[fi].id = LZMA_FILTER_SPARC; - fi++; - break; - default: - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Unexpected codec ID: %lX", zip->codec2); - return (ARCHIVE_FAILED); - } - } - - if (zip->codec == _7Z_LZMA2) - filters[fi].id = LZMA_FILTER_LZMA2; - else - filters[fi].id = LZMA_FILTER_LZMA1; - filters[fi].options = NULL; - ff = &filters[fi]; - r = lzma_properties_decode(&filters[fi], NULL, - coder1->properties, (size_t)coder1->propertiesSize); - if (r != LZMA_OK) { - set_error(a, r); - return (ARCHIVE_FAILED); - } - fi++; - - filters[fi].id = LZMA_VLI_UNKNOWN; - filters[fi].options = NULL; - r = lzma_raw_decoder(&(zip->lzstream), filters); - free(ff->options); - if (r != LZMA_OK) { - set_error(a, r); - return (ARCHIVE_FAILED); - } - zip->lzstream_valid = 1; - zip->lzstream.total_in = 0; - zip->lzstream.total_out = 0; - break; - } -#else - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "LZMA codec is unsupported"); - return (ARCHIVE_FAILED); -#endif - case _7Z_BZ2: -#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) - if (zip->bzstream_valid) { - BZ2_bzDecompressEnd(&(zip->bzstream)); - zip->bzstream_valid = 0; - } - r = BZ2_bzDecompressInit(&(zip->bzstream), 0, 0); - if (r == BZ_MEM_ERROR) - r = BZ2_bzDecompressInit(&(zip->bzstream), 0, 1); - if (r != BZ_OK) { - int err = ARCHIVE_ERRNO_MISC; - const char *detail = NULL; - switch (r) { - case BZ_PARAM_ERROR: - detail = "invalid setup parameter"; - break; - case BZ_MEM_ERROR: - err = ENOMEM; - detail = "out of memory"; - break; - case BZ_CONFIG_ERROR: - detail = "mis-compiled library"; - break; - } - archive_set_error(&a->archive, err, - "Internal error initializing decompressor: %s", - detail != NULL ? detail : "??"); - zip->bzstream_valid = 0; - return (ARCHIVE_FAILED); - } - zip->bzstream_valid = 1; - zip->bzstream.total_in_lo32 = 0; - zip->bzstream.total_in_hi32 = 0; - zip->bzstream.total_out_lo32 = 0; - zip->bzstream.total_out_hi32 = 0; - break; -#else - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "BZ2 codec is unsupported"); - return (ARCHIVE_FAILED); -#endif - case _7Z_ZSTD: - { -#if defined(HAVE_ZSTD_H) - if (zip->zstdstream_valid) { - ZSTD_freeDStream(zip->zstd_dstream); - zip->zstdstream_valid = 0; - } - zip->zstd_dstream = ZSTD_createDStream(); - zip->zstdstream_valid = 1; - break; -#else - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "ZSTD codec is unsupported"); - return (ARCHIVE_FAILED); -#endif - } - case _7Z_DEFLATE: -#ifdef HAVE_ZLIB_H - if (zip->stream_valid) - r = inflateReset(&(zip->stream)); - else - r = inflateInit2(&(zip->stream), - -15 /* Don't check for zlib header */); - if (r != Z_OK) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Couldn't initialize zlib stream."); - return (ARCHIVE_FAILED); - } - zip->stream_valid = 1; - zip->stream.total_in = 0; - zip->stream.total_out = 0; - break; -#else - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "DEFLATE codec is unsupported"); - return (ARCHIVE_FAILED); -#endif - case _7Z_PPMD: - { - unsigned order; - uint32_t msize; - - if (zip->ppmd7_valid) { - __archive_ppmd7_functions.Ppmd7_Free( - &zip->ppmd7_context); - zip->ppmd7_valid = 0; - } - - if (coder1->propertiesSize < 5) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Malformed PPMd parameter"); - return (ARCHIVE_FAILED); - } - order = coder1->properties[0]; - msize = archive_le32dec(&(coder1->properties[1])); - if (order < PPMD7_MIN_ORDER || order > PPMD7_MAX_ORDER || - msize < PPMD7_MIN_MEM_SIZE || msize > PPMD7_MAX_MEM_SIZE) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Malformed PPMd parameter"); - return (ARCHIVE_FAILED); - } - __archive_ppmd7_functions.Ppmd7_Construct(&zip->ppmd7_context); - r = __archive_ppmd7_functions.Ppmd7_Alloc( - &zip->ppmd7_context, msize); - if (r == 0) { - archive_set_error(&a->archive, ENOMEM, - "Coludn't allocate memory for PPMd"); - return (ARCHIVE_FATAL); - } - __archive_ppmd7_functions.Ppmd7_Init( - &zip->ppmd7_context, order); - __archive_ppmd7_functions.Ppmd7z_RangeDec_CreateVTable( - &zip->range_dec); - zip->ppmd7_valid = 1; - zip->ppmd7_stat = 0; - zip->ppstream.overconsumed = 0; - zip->ppstream.total_in = 0; - zip->ppstream.total_out = 0; - break; - } - case _7Z_X86: - case _7Z_X86_BCJ2: - case _7Z_POWERPC: - case _7Z_IA64: - case _7Z_ARM: - case _7Z_ARMTHUMB: - case _7Z_ARM64: - case _7Z_SPARC: - case _7Z_DELTA: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Unexpected codec ID: %lX", zip->codec); - return (ARCHIVE_FAILED); - case _7Z_CRYPTO_MAIN_ZIP: - case _7Z_CRYPTO_RAR_29: - case _7Z_CRYPTO_AES_256_SHA_256: - if (a->entry) { - archive_entry_set_is_metadata_encrypted(a->entry, 1); - archive_entry_set_is_data_encrypted(a->entry, 1); - zip->has_encrypted_entries = 1; - } - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Crypto codec not supported yet (ID: 0x%lX)", zip->codec); - return (ARCHIVE_FAILED); - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Unknown codec ID: %lX", zip->codec); - return (ARCHIVE_FAILED); - } - - return (ARCHIVE_OK); -} - -static int -decompress(struct archive_read *a, struct _7zip *zip, - void *buff, size_t *outbytes, const void *b, size_t *used) -{ - const uint8_t *t_next_in; - uint8_t *t_next_out; - size_t o_avail_in, o_avail_out; - size_t t_avail_in, t_avail_out; - uint8_t *bcj2_next_out; - size_t bcj2_avail_out; - int r, ret = ARCHIVE_OK; - - t_avail_in = o_avail_in = *used; - t_avail_out = o_avail_out = *outbytes; - t_next_in = b; - t_next_out = buff; - - if (zip->codec != _7Z_LZMA2 && zip->codec2 == _7Z_X86) { - int i; - - /* Do not copy out the BCJ remaining bytes when the output - * buffer size is less than five bytes. */ - if (o_avail_in != 0 && t_avail_out < 5 && zip->odd_bcj_size) { - *used = 0; - *outbytes = 0; - return (ret); - } - for (i = 0; zip->odd_bcj_size > 0 && t_avail_out; i++) { - *t_next_out++ = zip->odd_bcj[i]; - t_avail_out--; - zip->odd_bcj_size--; - } - if (o_avail_in == 0 || t_avail_out == 0) { - *used = o_avail_in - t_avail_in; - *outbytes = o_avail_out - t_avail_out; - if (o_avail_in == 0) - ret = ARCHIVE_EOF; - return (ret); - } - } - - bcj2_next_out = t_next_out; - bcj2_avail_out = t_avail_out; - if (zip->codec2 == _7Z_X86_BCJ2) { - /* - * Decord a remaining decompressed main stream for BCJ2. - */ - if (zip->tmp_stream_bytes_remaining) { - ssize_t bytes; - size_t remaining = zip->tmp_stream_bytes_remaining; - bytes = Bcj2_Decode(zip, t_next_out, t_avail_out); - if (bytes < 0) { - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, - "BCJ2 conversion Failed"); - return (ARCHIVE_FAILED); - } - zip->main_stream_bytes_remaining -= - remaining - zip->tmp_stream_bytes_remaining; - t_avail_out -= bytes; - if (o_avail_in == 0 || t_avail_out == 0) { - *used = 0; - *outbytes = o_avail_out - t_avail_out; - if (o_avail_in == 0 && - zip->tmp_stream_bytes_remaining) - ret = ARCHIVE_EOF; - return (ret); - } - t_next_out += bytes; - bcj2_next_out = t_next_out; - bcj2_avail_out = t_avail_out; - } - t_next_out = zip->tmp_stream_buff; - t_avail_out = zip->tmp_stream_buff_size; - } - - switch (zip->codec) { - case _7Z_COPY: - { - size_t bytes = - (t_avail_in > t_avail_out)?t_avail_out:t_avail_in; - - memcpy(t_next_out, t_next_in, bytes); - t_avail_in -= bytes; - t_avail_out -= bytes; - if (o_avail_in == 0) - ret = ARCHIVE_EOF; - break; - } -#ifdef HAVE_LZMA_H - case _7Z_LZMA: case _7Z_LZMA2: - zip->lzstream.next_in = t_next_in; - zip->lzstream.avail_in = t_avail_in; - zip->lzstream.next_out = t_next_out; - zip->lzstream.avail_out = t_avail_out; - - r = lzma_code(&(zip->lzstream), LZMA_RUN); - switch (r) { - case LZMA_STREAM_END: /* Found end of stream. */ - lzma_end(&(zip->lzstream)); - zip->lzstream_valid = 0; - ret = ARCHIVE_EOF; - break; - case LZMA_OK: /* Decompressor made some progress. */ - break; - default: - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, - "Decompression failed(%d)", - r); - return (ARCHIVE_FAILED); - } - t_avail_in = zip->lzstream.avail_in; - t_avail_out = zip->lzstream.avail_out; - break; -#endif -#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) - case _7Z_BZ2: - zip->bzstream.next_in = (char *)(uintptr_t)t_next_in; - zip->bzstream.avail_in = (uint32_t)t_avail_in; - zip->bzstream.next_out = (char *)(uintptr_t)t_next_out; - zip->bzstream.avail_out = (uint32_t)t_avail_out; - r = BZ2_bzDecompress(&(zip->bzstream)); - switch (r) { - case BZ_STREAM_END: /* Found end of stream. */ - switch (BZ2_bzDecompressEnd(&(zip->bzstream))) { - case BZ_OK: - break; - default: - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, - "Failed to clean up decompressor"); - return (ARCHIVE_FAILED); - } - zip->bzstream_valid = 0; - ret = ARCHIVE_EOF; - break; - case BZ_OK: /* Decompressor made some progress. */ - break; - default: - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, - "bzip decompression failed"); - return (ARCHIVE_FAILED); - } - t_avail_in = zip->bzstream.avail_in; - t_avail_out = zip->bzstream.avail_out; - break; -#endif -#ifdef HAVE_ZLIB_H - case _7Z_DEFLATE: - zip->stream.next_in = (Bytef *)(uintptr_t)t_next_in; - zip->stream.avail_in = (uInt)t_avail_in; - zip->stream.next_out = t_next_out; - zip->stream.avail_out = (uInt)t_avail_out; - r = inflate(&(zip->stream), 0); - switch (r) { - case Z_STREAM_END: /* Found end of stream. */ - ret = ARCHIVE_EOF; - break; - case Z_OK: /* Decompressor made some progress.*/ - break; - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "File decompression failed (%d)", r); - return (ARCHIVE_FAILED); - } - t_avail_in = zip->stream.avail_in; - t_avail_out = zip->stream.avail_out; - break; -#endif -#ifdef HAVE_ZSTD_H - case _7Z_ZSTD: - { - ZSTD_inBuffer input = { t_next_in, t_avail_in, 0 }; // src, size, pos - ZSTD_outBuffer output = { t_next_out, t_avail_out, 0 }; // dst, size, pos - - size_t const zret = ZSTD_decompressStream(zip->zstd_dstream, &output, &input); - if (ZSTD_isError(zret)) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Zstd decompression failed: %s", ZSTD_getErrorName(zret)); - return ARCHIVE_FAILED; - } - t_avail_in -= input.pos; - t_avail_out -= output.pos; - break; - } -#endif - case _7Z_PPMD: - { - uint64_t flush_bytes; - - if (!zip->ppmd7_valid || zip->ppmd7_stat < 0 || - t_avail_out <= 0) { - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, - "Decompression internal error"); - return (ARCHIVE_FAILED); - } - zip->ppstream.next_in = t_next_in; - zip->ppstream.avail_in = t_avail_in; - zip->ppstream.stream_in = 0; - zip->ppstream.next_out = t_next_out; - zip->ppstream.avail_out = t_avail_out; - if (zip->ppmd7_stat == 0) { - zip->bytein.a = a; - zip->bytein.Read = &ppmd_read; - zip->range_dec.Stream = &zip->bytein; - r = __archive_ppmd7_functions.Ppmd7z_RangeDec_Init( - &(zip->range_dec)); - if (r == 0) { - zip->ppmd7_stat = -1; - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Failed to initialize PPMd range decoder"); - return (ARCHIVE_FAILED); - } - if (zip->ppstream.overconsumed) { - zip->ppmd7_stat = -1; - return (ARCHIVE_FAILED); - } - zip->ppmd7_stat = 1; - } - - if (t_avail_in == 0) - /* XXX Flush out remaining decoded data XXX */ - flush_bytes = zip->folder_outbytes_remaining; - else - flush_bytes = 0; - - do { - int sym; - - sym = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( - &(zip->ppmd7_context), &(zip->range_dec.p)); - if (sym < 0) { - zip->ppmd7_stat = -1; - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Failed to decode PPMd"); - return (ARCHIVE_FAILED); - } - if (zip->ppstream.overconsumed) { - zip->ppmd7_stat = -1; - return (ARCHIVE_FAILED); - } - *zip->ppstream.next_out++ = (unsigned char)sym; - zip->ppstream.avail_out--; - zip->ppstream.total_out++; - if (flush_bytes) - flush_bytes--; - } while (zip->ppstream.avail_out && - (zip->ppstream.avail_in || flush_bytes)); - - t_avail_in = (size_t)zip->ppstream.avail_in; - t_avail_out = (size_t)zip->ppstream.avail_out; - break; - } - default: - archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC, - "Decompression internal error"); - return (ARCHIVE_FAILED); - } - if (ret != ARCHIVE_OK && ret != ARCHIVE_EOF) - return (ret); - - *used = o_avail_in - t_avail_in; - *outbytes = o_avail_out - t_avail_out; - - /* - * Decord BCJ. - */ - if (zip->codec != _7Z_LZMA2) { - if (zip->codec2 == _7Z_X86) { - size_t l = x86_Convert(zip, buff, *outbytes); - - zip->odd_bcj_size = *outbytes - l; - if (zip->odd_bcj_size > 0 && zip->odd_bcj_size <= 4 && - o_avail_in && ret != ARCHIVE_EOF) { - memcpy(zip->odd_bcj, ((unsigned char *)buff) + l, - zip->odd_bcj_size); - *outbytes = l; - } else - zip->odd_bcj_size = 0; - } else if (zip->codec2 == _7Z_ARM) { - *outbytes = arm_Convert(zip, buff, *outbytes); - } else if (zip->codec2 == _7Z_ARM64) { - *outbytes = arm64_Convert(zip, buff, *outbytes); - } - } - - /* - * Decord BCJ2 with a decompressed main stream. - */ - if (zip->codec2 == _7Z_X86_BCJ2) { - ssize_t bytes; - - zip->tmp_stream_bytes_avail = - zip->tmp_stream_buff_size - t_avail_out; - if (zip->tmp_stream_bytes_avail > - zip->main_stream_bytes_remaining) - zip->tmp_stream_bytes_avail = - zip->main_stream_bytes_remaining; - zip->tmp_stream_bytes_remaining = zip->tmp_stream_bytes_avail; - bytes = Bcj2_Decode(zip, bcj2_next_out, bcj2_avail_out); - if (bytes < 0) { - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, "BCJ2 conversion Failed"); - return (ARCHIVE_FAILED); - } - zip->main_stream_bytes_remaining -= - zip->tmp_stream_bytes_avail - - zip->tmp_stream_bytes_remaining; - bcj2_avail_out -= bytes; - *outbytes = o_avail_out - bcj2_avail_out; - } - - return (ret); -} - -static int -free_decompression(struct archive_read *a, struct _7zip *zip) -{ - int r = ARCHIVE_OK; - -#if !defined(HAVE_ZLIB_H) &&\ - !(defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)) - (void)a;/* UNUSED */ -#endif -#ifdef HAVE_LZMA_H - if (zip->lzstream_valid) - lzma_end(&(zip->lzstream)); -#endif -#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) - if (zip->bzstream_valid) { - if (BZ2_bzDecompressEnd(&(zip->bzstream)) != BZ_OK) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Failed to clean up bzip2 decompressor"); - r = ARCHIVE_FATAL; - } - zip->bzstream_valid = 0; - } -#endif -#ifdef HAVE_ZLIB_H - if (zip->stream_valid) { - if (inflateEnd(&(zip->stream)) != Z_OK) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Failed to clean up zlib decompressor"); - r = ARCHIVE_FATAL; - } - zip->stream_valid = 0; - } -#endif - if (zip->ppmd7_valid) { - __archive_ppmd7_functions.Ppmd7_Free( - &zip->ppmd7_context); - zip->ppmd7_valid = 0; - } - return (r); -} - -static int -parse_7zip_uint64(struct archive_read *a, uint64_t *val) -{ - const unsigned char *p; - unsigned char avail, mask; - int i; - - if ((p = header_bytes(a, 1)) == NULL) - return (-1); - avail = *p; - mask = 0x80; - *val = 0; - for (i = 0; i < 8; i++) { - if (avail & mask) { - if ((p = header_bytes(a, 1)) == NULL) - return (-1); - *val |= ((uint64_t)*p) << (8 * i); - mask >>= 1; - continue; - } - *val += ((uint64_t)(avail & (mask -1))) << (8 * i); - break; - } - return (0); -} - -static int -read_Bools(struct archive_read *a, unsigned char *data, size_t num) -{ - const unsigned char *p; - unsigned i, mask = 0, avail = 0; - - for (i = 0; i < num; i++) { - if (mask == 0) { - if ((p = header_bytes(a, 1)) == NULL) - return (-1); - avail = *p; - mask = 0x80; - } - data[i] = (avail & mask)?1:0; - mask >>= 1; - } - return (0); -} - -static void -free_Digest(struct _7z_digests *d) -{ - free(d->defineds); - free(d->digests); -} - -static int -read_Digests(struct archive_read *a, struct _7z_digests *d, size_t num) -{ - const unsigned char *p; - unsigned i; - - if (num == 0) - return (-1); - memset(d, 0, sizeof(*d)); - - d->defineds = malloc(num); - if (d->defineds == NULL) - return (-1); - /* - * Read Bools. - */ - if ((p = header_bytes(a, 1)) == NULL) - return (-1); - if (*p == 0) { - if (read_Bools(a, d->defineds, num) < 0) - return (-1); - } else - /* All are defined */ - memset(d->defineds, 1, num); - - d->digests = calloc(num, sizeof(*d->digests)); - if (d->digests == NULL) - return (-1); - for (i = 0; i < num; i++) { - if (d->defineds[i]) { - if ((p = header_bytes(a, 4)) == NULL) - return (-1); - d->digests[i] = archive_le32dec(p); - } - } - - return (0); -} - -static void -free_PackInfo(struct _7z_pack_info *pi) -{ - free(pi->sizes); - free(pi->positions); - free_Digest(&(pi->digest)); -} - -static int -read_PackInfo(struct archive_read *a, struct _7z_pack_info *pi) -{ - const unsigned char *p; - unsigned i; - - memset(pi, 0, sizeof(*pi)); - - /* - * Read PackPos. - */ - if (parse_7zip_uint64(a, &(pi->pos)) < 0) - return (-1); - - /* - * Read NumPackStreams. - */ - if (parse_7zip_uint64(a, &(pi->numPackStreams)) < 0) - return (-1); - if (pi->numPackStreams == 0) - return (-1); - if (UMAX_ENTRY < pi->numPackStreams) - return (-1); - - /* - * Read PackSizes[num] - */ - if ((p = header_bytes(a, 1)) == NULL) - return (-1); - if (*p == kEnd) - /* PackSizes[num] are not present. */ - return (0); - if (*p != kSize) - return (-1); - pi->sizes = calloc((size_t)pi->numPackStreams, sizeof(uint64_t)); - pi->positions = calloc((size_t)pi->numPackStreams, sizeof(uint64_t)); - if (pi->sizes == NULL || pi->positions == NULL) - return (-1); - - for (i = 0; i < pi->numPackStreams; i++) { - if (parse_7zip_uint64(a, &(pi->sizes[i])) < 0) - return (-1); - } - - /* - * Read PackStreamDigests[num] - */ - if ((p = header_bytes(a, 1)) == NULL) - return (-1); - if (*p == kEnd) { - /* PackStreamDigests[num] are not present. */ - pi->digest.defineds = - calloc((size_t)pi->numPackStreams, sizeof(*pi->digest.defineds)); - pi->digest.digests = - calloc((size_t)pi->numPackStreams, sizeof(*pi->digest.digests)); - if (pi->digest.defineds == NULL || pi->digest.digests == NULL) - return (-1); - return (0); - } - - if (*p != kCRC) - return (-1); - - if (read_Digests(a, &(pi->digest), (size_t)pi->numPackStreams) < 0) - return (-1); - - /* - * Must be marked by kEnd. - */ - if ((p = header_bytes(a, 1)) == NULL) - return (-1); - if (*p != kEnd) - return (-1); - return (0); -} - -static void -free_Folder(struct _7z_folder *f) -{ - unsigned i; - - if (f->coders) { - for (i = 0; i< f->numCoders; i++) { - free(f->coders[i].properties); - } - free(f->coders); - } - free(f->bindPairs); - free(f->packedStreams); - free(f->unPackSize); -} - -static int -read_Folder(struct archive_read *a, struct _7z_folder *f) -{ - struct _7zip *zip = (struct _7zip *)a->format->data; - const unsigned char *p; - uint64_t numInStreamsTotal = 0; - uint64_t numOutStreamsTotal = 0; - unsigned i; - - memset(f, 0, sizeof(*f)); - - /* - * Read NumCoders. - */ - if (parse_7zip_uint64(a, &(f->numCoders)) < 0) - return (-1); - if (f->numCoders > 4) - /* Too many coders. */ - return (-1); - - f->coders = calloc((size_t)f->numCoders, sizeof(*f->coders)); - if (f->coders == NULL) - return (-1); - for (i = 0; i< f->numCoders; i++) { - size_t codec_size; - int simple, attr; - - if ((p = header_bytes(a, 1)) == NULL) - return (-1); - /* - * 0:3 CodecIdSize - * 4: 0 - IsSimple - * 1 - Is not Simple - * 5: 0 - No Attributes - * 1 - There are Attributes; - * 7: Must be zero. - */ - codec_size = *p & 0xf; - simple = (*p & 0x10)?0:1; - attr = *p & 0x20; - if (*p & 0x80) - return (-1);/* Not supported. */ - - /* - * Read Decompression Method IDs. - */ - if ((p = header_bytes(a, codec_size)) == NULL) - return (-1); - - f->coders[i].codec = decode_codec_id(p, codec_size); - - if (simple) { - f->coders[i].numInStreams = 1; - f->coders[i].numOutStreams = 1; - } else { - if (parse_7zip_uint64( - a, &(f->coders[i].numInStreams)) < 0) - return (-1); - if (UMAX_ENTRY < f->coders[i].numInStreams) - return (-1); - if (parse_7zip_uint64( - a, &(f->coders[i].numOutStreams)) < 0) - return (-1); - if (UMAX_ENTRY < f->coders[i].numOutStreams) - return (-1); - } - - if (attr) { - if (parse_7zip_uint64( - a, &(f->coders[i].propertiesSize)) < 0) - return (-1); - if ((p = header_bytes( - a, (size_t)f->coders[i].propertiesSize)) == NULL) - return (-1); - f->coders[i].properties = - malloc((size_t)f->coders[i].propertiesSize); - if (f->coders[i].properties == NULL) - return (-1); - memcpy(f->coders[i].properties, p, - (size_t)f->coders[i].propertiesSize); - } - - numInStreamsTotal += f->coders[i].numInStreams; - numOutStreamsTotal += f->coders[i].numOutStreams; - } - - if (numOutStreamsTotal == 0 || - numInStreamsTotal < numOutStreamsTotal-1) - return (-1); - - f->numBindPairs = numOutStreamsTotal - 1; - if (zip->header_bytes_remaining < f->numBindPairs) - return (-1); - if (f->numBindPairs > 0) { - f->bindPairs = - calloc((size_t)f->numBindPairs, sizeof(*f->bindPairs)); - if (f->bindPairs == NULL) - return (-1); - } else - f->bindPairs = NULL; - for (i = 0; i < f->numBindPairs; i++) { - if (parse_7zip_uint64(a, &(f->bindPairs[i].inIndex)) < 0) - return (-1); - if (UMAX_ENTRY < f->bindPairs[i].inIndex) - return (-1); - if (parse_7zip_uint64(a, &(f->bindPairs[i].outIndex)) < 0) - return (-1); - if (UMAX_ENTRY < f->bindPairs[i].outIndex) - return (-1); - } - - f->numPackedStreams = numInStreamsTotal - f->numBindPairs; - f->packedStreams = - calloc((size_t)f->numPackedStreams, sizeof(*f->packedStreams)); - if (f->packedStreams == NULL) - return (-1); - if (f->numPackedStreams == 1) { - for (i = 0; i < numInStreamsTotal; i++) { - unsigned j; - for (j = 0; j < f->numBindPairs; j++) { - if (f->bindPairs[j].inIndex == i) - break; - } - if (j == f->numBindPairs) - break; - } - if (i == numInStreamsTotal) - return (-1); - f->packedStreams[0] = i; - } else { - for (i = 0; i < f->numPackedStreams; i++) { - if (parse_7zip_uint64(a, &(f->packedStreams[i])) < 0) - return (-1); - if (UMAX_ENTRY < f->packedStreams[i]) - return (-1); - } - } - f->numInStreams = numInStreamsTotal; - f->numOutStreams = numOutStreamsTotal; - - return (0); -} - -static void -free_CodersInfo(struct _7z_coders_info *ci) -{ - unsigned i; - - if (ci->folders) { - for (i = 0; i < ci->numFolders; i++) - free_Folder(&(ci->folders[i])); - free(ci->folders); - } -} - -static int -read_CodersInfo(struct archive_read *a, struct _7z_coders_info *ci) -{ - const unsigned char *p; - struct _7z_digests digest; - unsigned i; - - memset(ci, 0, sizeof(*ci)); - memset(&digest, 0, sizeof(digest)); - - if ((p = header_bytes(a, 1)) == NULL) - goto failed; - if (*p != kFolder) - goto failed; - - /* - * Read NumFolders. - */ - if (parse_7zip_uint64(a, &(ci->numFolders)) < 0) - goto failed; - if (UMAX_ENTRY < ci->numFolders) - return (-1); - - /* - * Read External. - */ - if ((p = header_bytes(a, 1)) == NULL) - goto failed; - switch (*p) { - case 0: - ci->folders = - calloc((size_t)ci->numFolders, sizeof(*ci->folders)); - if (ci->folders == NULL) - return (-1); - for (i = 0; i < ci->numFolders; i++) { - if (read_Folder(a, &(ci->folders[i])) < 0) - goto failed; - } - break; - case 1: - if (parse_7zip_uint64(a, &(ci->dataStreamIndex)) < 0) - return (-1); - if (UMAX_ENTRY < ci->dataStreamIndex) - return (-1); - if (ci->numFolders > 0) { - archive_set_error(&a->archive, -1, - "Malformed 7-Zip archive"); - goto failed; - } - break; - default: - archive_set_error(&a->archive, -1, - "Malformed 7-Zip archive"); - goto failed; - } - - if ((p = header_bytes(a, 1)) == NULL) - goto failed; - if (*p != kCodersUnPackSize) - goto failed; - - for (i = 0; i < ci->numFolders; i++) { - struct _7z_folder *folder = &(ci->folders[i]); - unsigned j; - - folder->unPackSize = - calloc((size_t)folder->numOutStreams, sizeof(*folder->unPackSize)); - if (folder->unPackSize == NULL) - goto failed; - for (j = 0; j < folder->numOutStreams; j++) { - if (parse_7zip_uint64(a, &(folder->unPackSize[j])) < 0) - goto failed; - } - } - - /* - * Read CRCs. - */ - if ((p = header_bytes(a, 1)) == NULL) - goto failed; - if (*p == kEnd) - return (0); - if (*p != kCRC) - goto failed; - if (read_Digests(a, &digest, (size_t)ci->numFolders) < 0) - goto failed; - for (i = 0; i < ci->numFolders; i++) { - ci->folders[i].digest_defined = digest.defineds[i]; - ci->folders[i].digest = digest.digests[i]; - } - - /* - * Must be kEnd. - */ - if ((p = header_bytes(a, 1)) == NULL) - goto failed; - if (*p != kEnd) - goto failed; - free_Digest(&digest); - return (0); -failed: - free_Digest(&digest); - return (-1); -} - -static uint64_t -folder_uncompressed_size(struct _7z_folder *f) -{ - int n = (int)f->numOutStreams; - unsigned pairs = (unsigned)f->numBindPairs; - - while (--n >= 0) { - unsigned i; - for (i = 0; i < pairs; i++) { - if (f->bindPairs[i].outIndex == (uint64_t)n) - break; - } - if (i >= pairs) - return (f->unPackSize[n]); - } - return (0); -} - -static void -free_SubStreamsInfo(struct _7z_substream_info *ss) -{ - free(ss->unpackSizes); - free(ss->digestsDefined); - free(ss->digests); -} - -static int -read_SubStreamsInfo(struct archive_read *a, struct _7z_substream_info *ss, - struct _7z_folder *f, size_t numFolders) -{ - const unsigned char *p; - uint64_t *usizes; - size_t unpack_streams; - int type; - unsigned i; - uint32_t numDigests; - - memset(ss, 0, sizeof(*ss)); - - for (i = 0; i < numFolders; i++) - f[i].numUnpackStreams = 1; - - if ((p = header_bytes(a, 1)) == NULL) - return (-1); - type = *p; - - if (type == kNumUnPackStream) { - unpack_streams = 0; - for (i = 0; i < numFolders; i++) { - if (parse_7zip_uint64(a, &(f[i].numUnpackStreams)) < 0) - return (-1); - if (UMAX_ENTRY < f[i].numUnpackStreams) - return (-1); - if (unpack_streams > SIZE_MAX - UMAX_ENTRY) { - return (-1); - } - unpack_streams += (size_t)f[i].numUnpackStreams; - } - if ((p = header_bytes(a, 1)) == NULL) - return (-1); - type = *p; - } else - unpack_streams = numFolders; - - ss->unpack_streams = unpack_streams; - if (unpack_streams) { - ss->unpackSizes = calloc(unpack_streams, - sizeof(*ss->unpackSizes)); - ss->digestsDefined = calloc(unpack_streams, - sizeof(*ss->digestsDefined)); - ss->digests = calloc(unpack_streams, - sizeof(*ss->digests)); - if (ss->unpackSizes == NULL || ss->digestsDefined == NULL || - ss->digests == NULL) - return (-1); - } - - usizes = ss->unpackSizes; - for (i = 0; i < numFolders; i++) { - unsigned pack; - uint64_t sum; - - if (f[i].numUnpackStreams == 0) - continue; - - sum = 0; - if (type == kSize) { - for (pack = 1; pack < f[i].numUnpackStreams; pack++) { - if (parse_7zip_uint64(a, usizes) < 0) - return (-1); - sum += *usizes++; - } - } - *usizes++ = folder_uncompressed_size(&f[i]) - sum; - } - - if (type == kSize) { - if ((p = header_bytes(a, 1)) == NULL) - return (-1); - type = *p; - } - - for (i = 0; i < unpack_streams; i++) { - ss->digestsDefined[i] = 0; - ss->digests[i] = 0; - } - - numDigests = 0; - for (i = 0; i < numFolders; i++) { - if (f[i].numUnpackStreams != 1 || !f[i].digest_defined) - numDigests += (uint32_t)f[i].numUnpackStreams; - } - - if (type == kCRC) { - struct _7z_digests tmpDigests; - unsigned char *digestsDefined = ss->digestsDefined; - uint32_t * digests = ss->digests; - int di = 0; - - memset(&tmpDigests, 0, sizeof(tmpDigests)); - if (read_Digests(a, &(tmpDigests), numDigests) < 0) { - free_Digest(&tmpDigests); - return (-1); - } - for (i = 0; i < numFolders; i++) { - if (f[i].numUnpackStreams == 1 && f[i].digest_defined) { - *digestsDefined++ = 1; - *digests++ = f[i].digest; - } else { - unsigned j; - - for (j = 0; j < f[i].numUnpackStreams; - j++, di++) { - *digestsDefined++ = - tmpDigests.defineds[di]; - *digests++ = - tmpDigests.digests[di]; - } - } - } - free_Digest(&tmpDigests); - if ((p = header_bytes(a, 1)) == NULL) - return (-1); - type = *p; - } - - /* - * Must be kEnd. - */ - if (type != kEnd) - return (-1); - return (0); -} - -static void -free_StreamsInfo(struct _7z_stream_info *si) -{ - free_PackInfo(&(si->pi)); - free_CodersInfo(&(si->ci)); - free_SubStreamsInfo(&(si->ss)); -} - -static int -read_StreamsInfo(struct archive_read *a, struct _7z_stream_info *si) -{ - struct _7zip *zip = (struct _7zip *)a->format->data; - const unsigned char *p; - unsigned i; - - memset(si, 0, sizeof(*si)); - - if ((p = header_bytes(a, 1)) == NULL) - return (-1); - if (*p == kPackInfo) { - uint64_t packPos; - - if (read_PackInfo(a, &(si->pi)) < 0) - return (-1); - - if (si->pi.positions == NULL || si->pi.sizes == NULL) - return (-1); - /* - * Calculate packed stream positions. - */ - packPos = si->pi.pos; - for (i = 0; i < si->pi.numPackStreams; i++) { - si->pi.positions[i] = packPos; - packPos += si->pi.sizes[i]; - if (packPos > zip->header_offset) - return (-1); - } - if ((p = header_bytes(a, 1)) == NULL) - return (-1); - } - if (*p == kUnPackInfo) { - uint32_t packIndex; - struct _7z_folder *f; - - if (read_CodersInfo(a, &(si->ci)) < 0) - return (-1); - - /* - * Calculate packed stream indexes. - */ - packIndex = 0; - f = si->ci.folders; - for (i = 0; i < si->ci.numFolders; i++) { - f[i].packIndex = packIndex; - packIndex += (uint32_t)f[i].numPackedStreams; - if (packIndex > si->pi.numPackStreams) - return (-1); - } - if ((p = header_bytes(a, 1)) == NULL) - return (-1); - } - - if (*p == kSubStreamsInfo) { - if (read_SubStreamsInfo(a, &(si->ss), - si->ci.folders, (size_t)si->ci.numFolders) < 0) - return (-1); - if ((p = header_bytes(a, 1)) == NULL) - return (-1); - } - - /* - * Must be kEnd. - */ - if (*p != kEnd) - return (-1); - return (0); -} - -static void -free_Header(struct _7z_header_info *h) -{ - free(h->emptyStreamBools); - free(h->emptyFileBools); - free(h->antiBools); - free(h->attrBools); -} - -static int -read_Header(struct archive_read *a, struct _7z_header_info *h, - int check_header_id) -{ - struct _7zip *zip = (struct _7zip *)a->format->data; - const unsigned char *p; - struct _7z_folder *folders; - struct _7z_stream_info *si = &(zip->si); - struct _7zip_entry *entries; - uint32_t folderIndex, indexInFolder; - unsigned i; - int eindex, empty_streams, sindex; - - if (check_header_id) { - /* - * Read Header. - */ - if ((p = header_bytes(a, 1)) == NULL) - return (-1); - if (*p != kHeader) - return (-1); - } - - /* - * Read ArchiveProperties. - */ - if ((p = header_bytes(a, 1)) == NULL) - return (-1); - if (*p == kArchiveProperties) { - for (;;) { - uint64_t size; - if ((p = header_bytes(a, 1)) == NULL) - return (-1); - if (*p == 0) - break; - if (parse_7zip_uint64(a, &size) < 0) - return (-1); - } - if ((p = header_bytes(a, 1)) == NULL) - return (-1); - } - - /* - * Read MainStreamsInfo. - */ - if (*p == kMainStreamsInfo) { - if (read_StreamsInfo(a, &(zip->si)) < 0) - return (-1); - if ((p = header_bytes(a, 1)) == NULL) - return (-1); - } - if (*p == kEnd) - return (0); - - /* - * Read FilesInfo. - */ - if (*p != kFilesInfo) - return (-1); - - if (parse_7zip_uint64(a, &(zip->numFiles)) < 0) - return (-1); - if (UMAX_ENTRY < zip->numFiles) - return (-1); - - zip->entries = calloc((size_t)zip->numFiles, sizeof(*zip->entries)); - if (zip->entries == NULL) - return (-1); - entries = zip->entries; - - empty_streams = 0; - for (;;) { - int type; - uint64_t size; - size_t ll; - - if ((p = header_bytes(a, 1)) == NULL) - return (-1); - type = *p; - if (type == kEnd) - break; - - if (parse_7zip_uint64(a, &size) < 0) - return (-1); - if (zip->header_bytes_remaining < size) - return (-1); - ll = (size_t)size; - - switch (type) { - case kEmptyStream: - if (h->emptyStreamBools != NULL) - return (-1); - h->emptyStreamBools = calloc((size_t)zip->numFiles, - sizeof(*h->emptyStreamBools)); - if (h->emptyStreamBools == NULL) - return (-1); - if (read_Bools( - a, h->emptyStreamBools, (size_t)zip->numFiles) < 0) - return (-1); - empty_streams = 0; - for (i = 0; i < zip->numFiles; i++) { - if (h->emptyStreamBools[i]) - empty_streams++; - } - break; - case kEmptyFile: - if (empty_streams <= 0) { - /* Unexcepted sequence. Skip this. */ - if (header_bytes(a, ll) == NULL) - return (-1); - break; - } - if (h->emptyFileBools != NULL) - return (-1); - h->emptyFileBools = calloc(empty_streams, - sizeof(*h->emptyFileBools)); - if (h->emptyFileBools == NULL) - return (-1); - if (read_Bools(a, h->emptyFileBools, empty_streams) < 0) - return (-1); - break; - case kAnti: - if (empty_streams <= 0) { - /* Unexcepted sequence. Skip this. */ - if (header_bytes(a, ll) == NULL) - return (-1); - break; - } - if (h->antiBools != NULL) - return (-1); - h->antiBools = calloc(empty_streams, - sizeof(*h->antiBools)); - if (h->antiBools == NULL) - return (-1); - if (read_Bools(a, h->antiBools, empty_streams) < 0) - return (-1); - break; - case kCTime: - case kATime: - case kMTime: - if (read_Times(a, h, type) < 0) - return (-1); - break; - case kName: - { - unsigned char *np; - size_t nl, nb; - - /* Skip one byte. */ - if ((p = header_bytes(a, 1)) == NULL) - return (-1); - ll--; - - if ((ll & 1) || ll < zip->numFiles * 4) - return (-1); - - if (zip->entry_names != NULL) - return (-1); - zip->entry_names = malloc(ll); - if (zip->entry_names == NULL) - return (-1); - np = zip->entry_names; - nb = ll; - /* - * Copy whole file names. - * NOTE: This loop prevents from expanding - * the uncompressed buffer in order not to - * use extra memory resource. - */ - while (nb) { - size_t b; - if (nb > UBUFF_SIZE) - b = UBUFF_SIZE; - else - b = nb; - if ((p = header_bytes(a, b)) == NULL) - return (-1); - memcpy(np, p, b); - np += b; - nb -= b; - } - np = zip->entry_names; - nl = ll; - - for (i = 0; i < zip->numFiles; i++) { - entries[i].utf16name = np; -#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG) - entries[i].wname = (wchar_t *)np; -#endif - - /* Find a terminator. */ - while (nl >= 2 && (np[0] || np[1])) { - np += 2; - nl -= 2; - } - if (nl < 2) - return (-1);/* Terminator not found */ - entries[i].name_len = np - entries[i].utf16name; - np += 2; - nl -= 2; - } - break; - } - case kAttributes: - { - int allAreDefined; - - if ((p = header_bytes(a, 2)) == NULL) - return (-1); - allAreDefined = *p; - if (h->attrBools != NULL) - return (-1); - h->attrBools = calloc((size_t)zip->numFiles, - sizeof(*h->attrBools)); - if (h->attrBools == NULL) - return (-1); - if (allAreDefined) - memset(h->attrBools, 1, (size_t)zip->numFiles); - else { - if (read_Bools(a, h->attrBools, - (size_t)zip->numFiles) < 0) - return (-1); - } - for (i = 0; i < zip->numFiles; i++) { - if (h->attrBools[i]) { - if ((p = header_bytes(a, 4)) == NULL) - return (-1); - entries[i].attr = archive_le32dec(p); - } - } - break; - } - case kDummy: - if (ll == 0) - break; - __LA_FALLTHROUGH; - default: - if (header_bytes(a, ll) == NULL) - return (-1); - break; - } - } - - /* - * Set up entry's attributes. - */ - folders = si->ci.folders; - eindex = sindex = 0; - folderIndex = indexInFolder = 0; - for (i = 0; i < zip->numFiles; i++) { - if (h->emptyStreamBools == NULL || h->emptyStreamBools[i] == 0) - entries[i].flg |= HAS_STREAM; - /* The high 16 bits of attributes is a posix file mode. */ - entries[i].mode = entries[i].attr >> 16; - - if (!(entries[i].attr & FILE_ATTRIBUTE_UNIX_EXTENSION)) { - // Only windows permissions specified for this entry. Translate to - // reasonable corresponding unix permissions. - - if (entries[i].attr & FILE_ATTRIBUTE_DIRECTORY) { - if (entries[i].attr & FILE_ATTRIBUTE_READONLY) { - // Read-only directory. - entries[i].mode = AE_IFDIR | 0555; - } else { - // Read-write directory. - entries[i].mode = AE_IFDIR | 0755; - } - } else if (entries[i].attr & FILE_ATTRIBUTE_READONLY) { - // Readonly file. - entries[i].mode = AE_IFREG | 0444; - } else { - // Assume read-write file. - entries[i].mode = AE_IFREG | 0644; - } - } - - if (entries[i].flg & HAS_STREAM) { - if ((size_t)sindex >= si->ss.unpack_streams) - return (-1); - if (entries[i].mode == 0) - entries[i].mode = AE_IFREG | 0666; - if (si->ss.digestsDefined[sindex]) - entries[i].flg |= CRC32_IS_SET; - entries[i].ssIndex = sindex; - sindex++; - } else { - int dir; - if (h->emptyFileBools == NULL) - dir = 1; - else { - if (h->emptyFileBools[eindex]) - dir = 0; - else - dir = 1; - eindex++; - } - if (entries[i].mode == 0) { - if (dir) - entries[i].mode = AE_IFDIR | 0777; - else - entries[i].mode = AE_IFREG | 0666; - } else if (dir && - (entries[i].mode & AE_IFMT) != AE_IFDIR) { - entries[i].mode &= ~AE_IFMT; - entries[i].mode |= AE_IFDIR; - } - if ((entries[i].mode & AE_IFMT) == AE_IFDIR && - entries[i].name_len >= 2 && - (entries[i].utf16name[entries[i].name_len-2] != '/' || - entries[i].utf16name[entries[i].name_len-1] != 0)) { - entries[i].utf16name[entries[i].name_len] = '/'; - entries[i].utf16name[entries[i].name_len+1] = 0; - entries[i].name_len += 2; - } - entries[i].ssIndex = -1; - } - if (entries[i].attr & FILE_ATTRIBUTE_READONLY) - entries[i].mode &= ~0222;/* Read only. */ - - if ((entries[i].flg & HAS_STREAM) == 0 && indexInFolder == 0) { - /* - * The entry is an empty file or a directory file, - * those both have no contents. - */ - entries[i].folderIndex = -1; - continue; - } - if (indexInFolder == 0) { - for (;;) { - if (folderIndex >= si->ci.numFolders) - return (-1); - if (folders[folderIndex].numUnpackStreams) - break; - folderIndex++; - } - } - entries[i].folderIndex = folderIndex; - if ((entries[i].flg & HAS_STREAM) == 0) - continue; - indexInFolder++; - if (indexInFolder >= folders[folderIndex].numUnpackStreams) { - folderIndex++; - indexInFolder = 0; - } - } - - return (0); -} - -#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000) -static void -fileTimeToUtc(uint64_t fileTime, time_t *timep, long *ns) -{ - - if (fileTime >= EPOC_TIME) { - fileTime -= EPOC_TIME; - /* milli seconds base */ - *timep = (time_t)(fileTime / 10000000); - /* nano seconds base */ - *ns = (long)(fileTime % 10000000) * 100; - } else { - *timep = 0; - *ns = 0; - } -} - -static int -read_Times(struct archive_read *a, struct _7z_header_info *h, int type) -{ - struct _7zip *zip = (struct _7zip *)a->format->data; - const unsigned char *p; - struct _7zip_entry *entries = zip->entries; - unsigned char *timeBools; - int allAreDefined; - unsigned i; - - timeBools = calloc((size_t)zip->numFiles, sizeof(*timeBools)); - if (timeBools == NULL) - return (-1); - - /* Read allAreDefined. */ - if ((p = header_bytes(a, 1)) == NULL) - goto failed; - allAreDefined = *p; - if (allAreDefined) - memset(timeBools, 1, (size_t)zip->numFiles); - else { - if (read_Bools(a, timeBools, (size_t)zip->numFiles) < 0) - goto failed; - } - - /* Read external. */ - if ((p = header_bytes(a, 1)) == NULL) - goto failed; - if (*p) { - if (parse_7zip_uint64(a, &(h->dataIndex)) < 0) - goto failed; - if (UMAX_ENTRY < h->dataIndex) - goto failed; - } - - for (i = 0; i < zip->numFiles; i++) { - if (!timeBools[i]) - continue; - if ((p = header_bytes(a, 8)) == NULL) - goto failed; - switch (type) { - case kCTime: - fileTimeToUtc(archive_le64dec(p), - &(entries[i].ctime), - &(entries[i].ctime_ns)); - entries[i].flg |= CTIME_IS_SET; - break; - case kATime: - fileTimeToUtc(archive_le64dec(p), - &(entries[i].atime), - &(entries[i].atime_ns)); - entries[i].flg |= ATIME_IS_SET; - break; - case kMTime: - fileTimeToUtc(archive_le64dec(p), - &(entries[i].mtime), - &(entries[i].mtime_ns)); - entries[i].flg |= MTIME_IS_SET; - break; - } - } - - free(timeBools); - return (0); -failed: - free(timeBools); - return (-1); -} - -static int -decode_encoded_header_info(struct archive_read *a, struct _7z_stream_info *si) -{ - struct _7zip *zip = (struct _7zip *)a->format->data; - - errno = 0; - if (read_StreamsInfo(a, si) < 0) { - if (errno == ENOMEM) - archive_set_error(&a->archive, -1, - "Couldn't allocate memory"); - else - archive_set_error(&a->archive, -1, - "Malformed 7-Zip archive"); - return (ARCHIVE_FATAL); - } - - if (si->pi.numPackStreams == 0 || si->ci.numFolders == 0) { - archive_set_error(&a->archive, -1, "Malformed 7-Zip archive"); - return (ARCHIVE_FATAL); - } - - if (zip->header_offset < si->pi.pos + si->pi.sizes[0] || - (int64_t)(si->pi.pos + si->pi.sizes[0]) < 0 || - si->pi.sizes[0] == 0 || (int64_t)si->pi.pos < 0) { - archive_set_error(&a->archive, -1, "Malformed Header offset"); - return (ARCHIVE_FATAL); - } - - return (ARCHIVE_OK); -} - -static const unsigned char * -header_bytes(struct archive_read *a, size_t rbytes) -{ - struct _7zip *zip = (struct _7zip *)a->format->data; - const unsigned char *p; - - if (zip->header_bytes_remaining < rbytes) - return (NULL); - if (zip->pack_stream_bytes_unconsumed) - read_consume(a); - - if (zip->header_is_encoded == 0) { - p = __archive_read_ahead(a, rbytes, NULL); - if (p == NULL) - return (NULL); - zip->header_bytes_remaining -= rbytes; - zip->pack_stream_bytes_unconsumed = rbytes; - } else { - const void *buff; - ssize_t bytes; - - bytes = read_stream(a, &buff, rbytes, rbytes); - if (bytes <= 0) - return (NULL); - zip->header_bytes_remaining -= bytes; - p = buff; - } - - /* Update checksum */ - zip->header_crc32 = crc32(zip->header_crc32, p, (unsigned)rbytes); - return (p); -} - -static int -slurp_central_directory(struct archive_read *a, struct _7zip *zip, - struct _7z_header_info *header) -{ - const unsigned char *p; - uint64_t next_header_offset; - uint64_t next_header_size; - uint32_t next_header_crc; - ssize_t bytes_avail; - int check_header_crc, r; - - if ((p = __archive_read_ahead(a, 32, &bytes_avail)) == NULL) - return (ARCHIVE_FATAL); - - if ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0) { - /* This is an executable ? Must be self-extracting... */ - r = skip_sfx(a, bytes_avail); - if (r < ARCHIVE_WARN) - return (r); - if ((p = __archive_read_ahead(a, 32, &bytes_avail)) == NULL) - return (ARCHIVE_FATAL); - } - zip->seek_base += 32; - - if (memcmp(p, _7ZIP_SIGNATURE, 6) != 0) { - archive_set_error(&a->archive, -1, "Not 7-Zip archive file"); - return (ARCHIVE_FATAL); - } - - /* CRC check. */ - if (crc32(0, (const unsigned char *)p + 12, 20) - != archive_le32dec(p + 8)) { -#ifdef DONT_FAIL_ON_CRC_ERROR - archive_set_error(&a->archive, -1, "Header CRC error"); - return (ARCHIVE_FATAL); -#endif - } - - next_header_offset = archive_le64dec(p + 12); - next_header_size = archive_le64dec(p + 20); - next_header_crc = archive_le32dec(p + 28); - - if (next_header_size == 0) - /* There is no entry in an archive file. */ - return (ARCHIVE_EOF); - - if (((int64_t)next_header_offset) < 0) { - archive_set_error(&a->archive, -1, "Malformed 7-Zip archive"); - return (ARCHIVE_FATAL); - } - __archive_read_consume(a, 32); - if (next_header_offset != 0) { - if (bytes_avail >= (ssize_t)next_header_offset) - __archive_read_consume(a, next_header_offset); - else if (__archive_read_seek(a, - next_header_offset + zip->seek_base, SEEK_SET) < 0) - return (ARCHIVE_FATAL); - } - zip->stream_offset = next_header_offset; - zip->header_offset = next_header_offset; - zip->header_bytes_remaining = next_header_size; - zip->header_crc32 = 0; - zip->header_is_encoded = 0; - zip->header_is_being_read = 1; - zip->has_encrypted_entries = 0; - check_header_crc = 1; - - if ((p = header_bytes(a, 1)) == NULL) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated 7-Zip file body"); - return (ARCHIVE_FATAL); - } - /* Parse ArchiveProperties. */ - switch (p[0]) { - case kEncodedHeader: - /* - * The archive has an encoded header and we have to decode it - * in order to parse the header correctly. - */ - r = decode_encoded_header_info(a, &(zip->si)); - - /* Check the EncodedHeader CRC.*/ - if (r == 0 && zip->header_crc32 != next_header_crc) { - archive_set_error(&a->archive, -1, -#ifndef DONT_FAIL_ON_CRC_ERROR - "Damaged 7-Zip archive"); - r = -1; -#endif - } - if (r == 0) { - if (zip->si.ci.folders[0].digest_defined) - next_header_crc = zip->si.ci.folders[0].digest; - else - check_header_crc = 0; - if (zip->pack_stream_bytes_unconsumed) - read_consume(a); - r = setup_decode_folder(a, zip->si.ci.folders, 1); - if (r == 0) { - zip->header_bytes_remaining = - zip->folder_outbytes_remaining; - r = seek_pack(a); - } - } - /* Clean up StreamsInfo. */ - free_StreamsInfo(&(zip->si)); - memset(&(zip->si), 0, sizeof(zip->si)); - if (r < 0) - return (ARCHIVE_FATAL); - zip->header_is_encoded = 1; - zip->header_crc32 = 0; - /* FALL THROUGH */ - case kHeader: - /* - * Parse the header. - */ - errno = 0; - r = read_Header(a, header, zip->header_is_encoded); - if (r < 0) { - if (errno == ENOMEM) - archive_set_error(&a->archive, -1, - "Couldn't allocate memory"); - else - archive_set_error(&a->archive, -1, - "Damaged 7-Zip archive"); - return (ARCHIVE_FATAL); - } - - /* - * Must be kEnd. - */ - if ((p = header_bytes(a, 1)) == NULL ||*p != kEnd) { - archive_set_error(&a->archive, -1, - "Malformed 7-Zip archive"); - return (ARCHIVE_FATAL); - } - - /* Check the Header CRC.*/ - if (check_header_crc && zip->header_crc32 != next_header_crc) { -#ifndef DONT_FAIL_ON_CRC_ERROR - archive_set_error(&a->archive, -1, - "Malformed 7-Zip archive"); - return (ARCHIVE_FATAL); -#endif - } - break; - default: - archive_set_error(&a->archive, -1, - "Unexpected Property ID = %X", p[0]); - return (ARCHIVE_FATAL); - } - - /* Clean up variables be used for decoding the archive header */ - zip->pack_stream_remaining = 0; - zip->pack_stream_index = 0; - zip->folder_outbytes_remaining = 0; - zip->uncompressed_buffer_bytes_remaining = 0; - zip->pack_stream_bytes_unconsumed = 0; - zip->header_is_being_read = 0; - - return (ARCHIVE_OK); -} - -static ssize_t -get_uncompressed_data(struct archive_read *a, const void **buff, size_t size, - size_t minimum) -{ - struct _7zip *zip = (struct _7zip *)a->format->data; - ssize_t bytes_avail; - - if (zip->codec == _7Z_COPY && zip->codec2 == (unsigned long)-1) { - /* Copy mode. */ - - *buff = __archive_read_ahead(a, minimum, &bytes_avail); - if (bytes_avail <= 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated 7-Zip file data"); - return (ARCHIVE_FATAL); - } - if ((size_t)bytes_avail > - zip->uncompressed_buffer_bytes_remaining) - bytes_avail = (ssize_t) - zip->uncompressed_buffer_bytes_remaining; - if ((size_t)bytes_avail > size) - bytes_avail = (ssize_t)size; - - zip->pack_stream_bytes_unconsumed = bytes_avail; - } else if (zip->uncompressed_buffer_pointer == NULL) { - /* Decompression has failed. */ - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, "Damaged 7-Zip archive"); - return (ARCHIVE_FATAL); - } else { - /* Packed mode. */ - if (minimum > zip->uncompressed_buffer_bytes_remaining) { - /* - * If remaining uncompressed data size is less than - * the minimum size, fill the buffer up to the - * minimum size. - */ - if (extract_pack_stream(a, minimum) < 0) - return (ARCHIVE_FATAL); - } - if (size > zip->uncompressed_buffer_bytes_remaining) - bytes_avail = (ssize_t) - zip->uncompressed_buffer_bytes_remaining; - else - bytes_avail = (ssize_t)size; - *buff = zip->uncompressed_buffer_pointer; - zip->uncompressed_buffer_pointer += bytes_avail; - } - zip->uncompressed_buffer_bytes_remaining -= bytes_avail; - return (bytes_avail); -} - -static ssize_t -extract_pack_stream(struct archive_read *a, size_t minimum) -{ - struct _7zip *zip = (struct _7zip *)a->format->data; - ssize_t bytes_avail; - int r; - - if (zip->codec == _7Z_COPY && zip->codec2 == (unsigned long)-1) { - if (minimum == 0) - minimum = 1; - if (__archive_read_ahead(a, minimum, &bytes_avail) == NULL - || bytes_avail <= 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated 7-Zip file body"); - return (ARCHIVE_FATAL); - } - if ((uint64_t)bytes_avail > zip->pack_stream_inbytes_remaining) - bytes_avail = (ssize_t)zip->pack_stream_inbytes_remaining; - zip->pack_stream_inbytes_remaining -= bytes_avail; - if ((uint64_t)bytes_avail > zip->folder_outbytes_remaining) - bytes_avail = (ssize_t)zip->folder_outbytes_remaining; - zip->folder_outbytes_remaining -= bytes_avail; - zip->uncompressed_buffer_bytes_remaining = bytes_avail; - return (ARCHIVE_OK); - } - - /* If the buffer hasn't been allocated, allocate it now. */ - if (zip->uncompressed_buffer == NULL) { - zip->uncompressed_buffer_size = UBUFF_SIZE; - if (zip->uncompressed_buffer_size < minimum) { - zip->uncompressed_buffer_size = minimum + 1023; - zip->uncompressed_buffer_size &= ~0x3ff; - } - zip->uncompressed_buffer = - malloc(zip->uncompressed_buffer_size); - if (zip->uncompressed_buffer == NULL) { - archive_set_error(&a->archive, ENOMEM, - "No memory for 7-Zip decompression"); - return (ARCHIVE_FATAL); - } - zip->uncompressed_buffer_bytes_remaining = 0; - } else if (zip->uncompressed_buffer_size < minimum || - zip->uncompressed_buffer_bytes_remaining < minimum) { - /* - * Make sure the uncompressed buffer can have bytes - * at least `minimum' bytes. - * NOTE: This case happen when reading the header. - */ - size_t used; - if (zip->uncompressed_buffer_pointer != 0) - used = zip->uncompressed_buffer_pointer - - zip->uncompressed_buffer; - else - used = 0; - if (zip->uncompressed_buffer_size < minimum) { - /* - * Expand the uncompressed buffer up to - * the minimum size. - */ - void *p; - size_t new_size; - - new_size = minimum + 1023; - new_size &= ~0x3ff; - p = realloc(zip->uncompressed_buffer, new_size); - if (p == NULL) { - archive_set_error(&a->archive, ENOMEM, - "No memory for 7-Zip decompression"); - return (ARCHIVE_FATAL); - } - zip->uncompressed_buffer = (unsigned char *)p; - zip->uncompressed_buffer_size = new_size; - } - /* - * Move unconsumed bytes to the head. - */ - if (used) { - memmove(zip->uncompressed_buffer, - zip->uncompressed_buffer + used, - zip->uncompressed_buffer_bytes_remaining); - } - } else - zip->uncompressed_buffer_bytes_remaining = 0; - zip->uncompressed_buffer_pointer = NULL; - for (;;) { - size_t bytes_in, bytes_out; - const void *buff_in; - unsigned char *buff_out; - int end_of_data; - - /* - * Note: '1' here is a performance optimization. - * Recall that the decompression layer returns a count of - * available bytes; asking for more than that forces the - * decompressor to combine reads by copying data. - */ - buff_in = __archive_read_ahead(a, 1, &bytes_avail); - if (bytes_avail <= 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated 7-Zip file body"); - return (ARCHIVE_FATAL); - } - - buff_out = zip->uncompressed_buffer - + zip->uncompressed_buffer_bytes_remaining; - bytes_out = zip->uncompressed_buffer_size - - zip->uncompressed_buffer_bytes_remaining; - bytes_in = bytes_avail; - if (bytes_in > zip->pack_stream_inbytes_remaining) - bytes_in = (size_t)zip->pack_stream_inbytes_remaining; - /* Drive decompression. */ - r = decompress(a, zip, buff_out, &bytes_out, - buff_in, &bytes_in); - switch (r) { - case ARCHIVE_OK: - end_of_data = 0; - break; - case ARCHIVE_EOF: - end_of_data = 1; - break; - default: - return (ARCHIVE_FATAL); - } - zip->pack_stream_inbytes_remaining -= bytes_in; - if (bytes_out > zip->folder_outbytes_remaining) - bytes_out = (size_t)zip->folder_outbytes_remaining; - zip->folder_outbytes_remaining -= bytes_out; - zip->uncompressed_buffer_bytes_remaining += bytes_out; - zip->pack_stream_bytes_unconsumed = bytes_in; - - /* - * Continue decompression until uncompressed_buffer is full. - */ - if (zip->uncompressed_buffer_bytes_remaining == - zip->uncompressed_buffer_size) - break; - if (zip->codec2 == _7Z_X86 && zip->odd_bcj_size && - zip->uncompressed_buffer_bytes_remaining + 5 > - zip->uncompressed_buffer_size) - break; - if (zip->pack_stream_inbytes_remaining == 0 && - zip->folder_outbytes_remaining == 0) - break; - if (end_of_data || (bytes_in == 0 && bytes_out == 0)) { - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, "Damaged 7-Zip archive"); - return (ARCHIVE_FATAL); - } - read_consume(a); - } - if (zip->uncompressed_buffer_bytes_remaining < minimum) { - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, "Damaged 7-Zip archive"); - return (ARCHIVE_FATAL); - } - zip->uncompressed_buffer_pointer = zip->uncompressed_buffer; - return (ARCHIVE_OK); -} - -static int -seek_pack(struct archive_read *a) -{ - struct _7zip *zip = (struct _7zip *)a->format->data; - int64_t pack_offset; - - if (zip->pack_stream_remaining <= 0) { - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, "Damaged 7-Zip archive"); - return (ARCHIVE_FATAL); - } - zip->pack_stream_inbytes_remaining = - zip->si.pi.sizes[zip->pack_stream_index]; - pack_offset = zip->si.pi.positions[zip->pack_stream_index]; - if (zip->stream_offset != pack_offset) { - if (0 > __archive_read_seek(a, pack_offset + zip->seek_base, - SEEK_SET)) - return (ARCHIVE_FATAL); - zip->stream_offset = pack_offset; - } - zip->pack_stream_index++; - zip->pack_stream_remaining--; - return (ARCHIVE_OK); -} - -static ssize_t -read_stream(struct archive_read *a, const void **buff, size_t size, - size_t minimum) -{ - struct _7zip *zip = (struct _7zip *)a->format->data; - uint64_t skip_bytes = 0; - ssize_t r; - - if (zip->uncompressed_buffer_bytes_remaining == 0) { - if (zip->pack_stream_inbytes_remaining > 0) { - r = extract_pack_stream(a, 0); - if (r < 0) - return (r); - return (get_uncompressed_data(a, buff, size, minimum)); - } else if (zip->folder_outbytes_remaining > 0) { - /* Extract a remaining pack stream. */ - r = extract_pack_stream(a, 0); - if (r < 0) - return (r); - return (get_uncompressed_data(a, buff, size, minimum)); - } - } else - return (get_uncompressed_data(a, buff, size, minimum)); - - /* - * Current pack stream has been consumed. - */ - if (zip->pack_stream_remaining == 0) { - if (zip->header_is_being_read) { - /* Invalid sequence. This might happen when - * reading a malformed archive. */ - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, "Malformed 7-Zip archive"); - return (ARCHIVE_FATAL); - } - - /* - * All current folder's pack streams have been - * consumed. Switch to next folder. - */ - if (zip->folder_index == 0 && - (zip->si.ci.folders[zip->entry->folderIndex].skipped_bytes - || zip->folder_index != zip->entry->folderIndex)) { - zip->folder_index = zip->entry->folderIndex; - skip_bytes = - zip->si.ci.folders[zip->folder_index].skipped_bytes; - } - - if (zip->folder_index >= zip->si.ci.numFolders) { - /* - * We have consumed all folders and its pack streams. - */ - *buff = NULL; - return (0); - } - r = setup_decode_folder(a, - &(zip->si.ci.folders[zip->folder_index]), 0); - if (r != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - zip->folder_index++; - } - - /* - * Switch to next pack stream. - */ - r = seek_pack(a); - if (r < 0) - return (r); - - /* Extract a new pack stream. */ - r = extract_pack_stream(a, 0); - if (r < 0) - return (r); - - /* - * Skip the bytes we already has skipped in skip_stream(). - */ - while (skip_bytes) { - ssize_t skipped; - - if (zip->uncompressed_buffer_bytes_remaining == 0) { - if (zip->pack_stream_inbytes_remaining > 0) { - r = extract_pack_stream(a, 0); - if (r < 0) - return (r); - } else if (zip->folder_outbytes_remaining > 0) { - /* Extract a remaining pack stream. */ - r = extract_pack_stream(a, 0); - if (r < 0) - return (r); - } else { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated 7-Zip file body"); - return (ARCHIVE_FATAL); - } - } - skipped = get_uncompressed_data( - a, buff, (size_t)skip_bytes, 0); - if (skipped < 0) - return (skipped); - skip_bytes -= skipped; - if (zip->pack_stream_bytes_unconsumed) - read_consume(a); - } - - return (get_uncompressed_data(a, buff, size, minimum)); -} - -static int -setup_decode_folder(struct archive_read *a, struct _7z_folder *folder, - int header) -{ - struct _7zip *zip = (struct _7zip *)a->format->data; - const struct _7z_coder *coder1, *coder2; - const char *cname = (header)?"archive header":"file content"; - unsigned i; - int r, found_bcj2 = 0; - - /* - * Release the memory which the previous folder used for BCJ2. - */ - for (i = 0; i < 3; i++) { - free(zip->sub_stream_buff[i]); - zip->sub_stream_buff[i] = NULL; - } - - /* - * Initialize a stream reader. - */ - zip->pack_stream_remaining = (unsigned)folder->numPackedStreams; - zip->pack_stream_index = (unsigned)folder->packIndex; - zip->folder_outbytes_remaining = folder_uncompressed_size(folder); - zip->uncompressed_buffer_bytes_remaining = 0; - - /* - * Check coder types. - */ - for (i = 0; i < folder->numCoders; i++) { - switch(folder->coders[i].codec) { - case _7Z_CRYPTO_MAIN_ZIP: - case _7Z_CRYPTO_RAR_29: - case _7Z_CRYPTO_AES_256_SHA_256: { - /* For entry that is associated with this folder, mark - it as encrypted (data+metadata). */ - zip->has_encrypted_entries = 1; - if (a->entry) { - archive_entry_set_is_data_encrypted(a->entry, 1); - archive_entry_set_is_metadata_encrypted(a->entry, 1); - } - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, - "The %s is encrypted, " - "but currently not supported", cname); - return (ARCHIVE_FATAL); - } - case _7Z_X86_BCJ2: { - found_bcj2++; - break; - } - } - } - /* Now that we've checked for encryption, if there were still no - * encrypted entries found we can say for sure that there are none. - */ - if (zip->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) { - zip->has_encrypted_entries = 0; - } - - if ((folder->numCoders > 2 && !found_bcj2) || found_bcj2 > 1) { - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, - "The %s is encoded with many filters, " - "but currently not supported", cname); - return (ARCHIVE_FATAL); - } - coder1 = &(folder->coders[0]); - if (folder->numCoders == 2) - coder2 = &(folder->coders[1]); - else - coder2 = NULL; - - if (found_bcj2) { - /* - * Preparation to decode BCJ2. - * Decoding BCJ2 requires four sources. Those are at least, - * as far as I know, two types of the storage form. - */ - const struct _7z_coder *fc = folder->coders; - static const struct _7z_coder coder_copy = {0, 1, 1, 0, NULL}; - const struct _7z_coder *scoder[3] = - {&coder_copy, &coder_copy, &coder_copy}; - const void *buff; - ssize_t bytes; - unsigned char *b[3] = {NULL, NULL, NULL}; - uint64_t sunpack[3] ={-1, -1, -1}; - size_t s[3] = {0, 0, 0}; - int idx[3] = {0, 1, 2}; - - if (folder->numCoders == 4 && fc[3].codec == _7Z_X86_BCJ2 && - folder->numInStreams == 7 && folder->numOutStreams == 4 && - zip->pack_stream_remaining == 4) { - /* Source type 1 made by 7zr or 7z with -m options. */ - if (folder->bindPairs[0].inIndex == 5) { - /* The form made by 7zr */ - idx[0] = 1; idx[1] = 2; idx[2] = 0; - scoder[1] = &(fc[1]); - scoder[2] = &(fc[0]); - sunpack[1] = folder->unPackSize[1]; - sunpack[2] = folder->unPackSize[0]; - coder1 = &(fc[2]); - } else { - /* - * NOTE: Some patterns do not work. - * work: - * 7z a -m0=BCJ2 -m1=COPY -m2=COPY - * -m3=(any) - * 7z a -m0=BCJ2 -m1=COPY -m2=(any) - * -m3=COPY - * 7z a -m0=BCJ2 -m1=(any) -m2=COPY - * -m3=COPY - * not work: - * other patterns. - * - * We have to handle this like `pipe' or - * our libarchive7s filter frame work, - * decoding the BCJ2 main stream sequentially, - * m3 -> m2 -> m1 -> BCJ2. - * - */ - if (fc[0].codec == _7Z_COPY && - fc[1].codec == _7Z_COPY) - coder1 = &(folder->coders[2]); - else if (fc[0].codec == _7Z_COPY && - fc[2].codec == _7Z_COPY) - coder1 = &(folder->coders[1]); - else if (fc[1].codec == _7Z_COPY && - fc[2].codec == _7Z_COPY) - coder1 = &(folder->coders[0]); - else { - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, - "Unsupported form of " - "BCJ2 streams"); - return (ARCHIVE_FATAL); - } - } - coder2 = &(fc[3]); - zip->main_stream_bytes_remaining = - (size_t)folder->unPackSize[2]; - } else if (coder2 != NULL && coder2->codec == _7Z_X86_BCJ2 && - zip->pack_stream_remaining == 4 && - folder->numInStreams == 5 && folder->numOutStreams == 2) { - /* Source type 0 made by 7z */ - zip->main_stream_bytes_remaining = - (size_t)folder->unPackSize[0]; - } else { - /* We got an unexpected form. */ - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, - "Unsupported form of BCJ2 streams"); - return (ARCHIVE_FATAL); - } - - /* Skip the main stream at this time. */ - if ((r = seek_pack(a)) < 0) - return (r); - zip->pack_stream_bytes_unconsumed = - (size_t)zip->pack_stream_inbytes_remaining; - read_consume(a); - - /* Read following three sub streams. */ - for (i = 0; i < 3; i++) { - const struct _7z_coder *coder = scoder[i]; - - if ((r = seek_pack(a)) < 0) { - free(b[0]); free(b[1]); free(b[2]); - return (r); - } - - if (sunpack[i] == (uint64_t)-1) - zip->folder_outbytes_remaining = - zip->pack_stream_inbytes_remaining; - else - zip->folder_outbytes_remaining = sunpack[i]; - - r = init_decompression(a, zip, coder, NULL); - if (r != ARCHIVE_OK) { - free(b[0]); free(b[1]); free(b[2]); - return (ARCHIVE_FATAL); - } - - /* Allocate memory for the decoded data of a sub - * stream. */ - b[i] = malloc((size_t)zip->folder_outbytes_remaining); - if (b[i] == NULL) { - free(b[0]); free(b[1]); free(b[2]); - archive_set_error(&a->archive, ENOMEM, - "No memory for 7-Zip decompression"); - return (ARCHIVE_FATAL); - } - - /* Extract a sub stream. */ - while (zip->pack_stream_inbytes_remaining > 0) { - r = (int)extract_pack_stream(a, 0); - if (r < 0) { - free(b[0]); free(b[1]); free(b[2]); - return (r); - } - bytes = get_uncompressed_data(a, &buff, - zip->uncompressed_buffer_bytes_remaining, - 0); - if (bytes < 0) { - free(b[0]); free(b[1]); free(b[2]); - return ((int)bytes); - } - memcpy(b[i]+s[i], buff, bytes); - s[i] += bytes; - if (zip->pack_stream_bytes_unconsumed) - read_consume(a); - } - } - - /* Set the sub streams to the right place. */ - for (i = 0; i < 3; i++) { - zip->sub_stream_buff[i] = b[idx[i]]; - zip->sub_stream_size[i] = s[idx[i]]; - zip->sub_stream_bytes_remaining[i] = s[idx[i]]; - } - - /* Allocate memory used for decoded main stream bytes. */ - if (zip->tmp_stream_buff == NULL) { - zip->tmp_stream_buff_size = 32 * 1024; - zip->tmp_stream_buff = - malloc(zip->tmp_stream_buff_size); - if (zip->tmp_stream_buff == NULL) { - archive_set_error(&a->archive, ENOMEM, - "No memory for 7-Zip decompression"); - return (ARCHIVE_FATAL); - } - } - zip->tmp_stream_bytes_avail = 0; - zip->tmp_stream_bytes_remaining = 0; - zip->odd_bcj_size = 0; - zip->bcj2_outPos = 0; - - /* - * Reset a stream reader in order to read the main stream - * of BCJ2. - */ - zip->pack_stream_remaining = 1; - zip->pack_stream_index = (unsigned)folder->packIndex; - zip->folder_outbytes_remaining = - folder_uncompressed_size(folder); - zip->uncompressed_buffer_bytes_remaining = 0; - } - - /* - * Initialize the decompressor for the new folder's pack streams. - */ - r = init_decompression(a, zip, coder1, coder2); - if (r != ARCHIVE_OK) - return (ARCHIVE_FATAL); - return (ARCHIVE_OK); -} - -static int64_t -skip_stream(struct archive_read *a, size_t skip_bytes) -{ - struct _7zip *zip = (struct _7zip *)a->format->data; - const void *p; - int64_t skipped_bytes; - size_t bytes = skip_bytes; - - if (zip->folder_index == 0) { - /* - * Optimization for a list mode. - * Avoid unnecessary decoding operations. - */ - zip->si.ci.folders[zip->entry->folderIndex].skipped_bytes - += skip_bytes; - return (skip_bytes); - } - - while (bytes) { - skipped_bytes = read_stream(a, &p, bytes, 0); - if (skipped_bytes < 0) - return (skipped_bytes); - if (skipped_bytes == 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated 7-Zip file body"); - return (ARCHIVE_FATAL); - } - bytes -= (size_t)skipped_bytes; - if (zip->pack_stream_bytes_unconsumed) - read_consume(a); - } - return (skip_bytes); -} - -/* - * Brought from LZMA SDK. - * - * Bra86.c -- Converter for x86 code (BCJ) - * 2008-10-04 : Igor Pavlov : Public domain - * - */ - -#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF) - -static void -x86_Init(struct _7zip *zip) -{ - zip->bcj_state = 0; - zip->bcj_prevPosT = (size_t)0 - 1; - zip->bcj_prevMask = 0; - zip->bcj_ip = 5; -} - -static size_t -x86_Convert(struct _7zip *zip, uint8_t *data, size_t size) -{ - static const uint8_t kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0}; - static const uint8_t kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3}; - size_t bufferPos, prevPosT; - uint32_t ip, prevMask; - - if (size < 5) - return 0; - - bufferPos = 0; - prevPosT = zip->bcj_prevPosT; - prevMask = zip->bcj_prevMask; - ip = zip->bcj_ip; - - for (;;) { - uint8_t *p = data + bufferPos; - uint8_t *limit = data + size - 4; - - for (; p < limit; p++) - if ((*p & 0xFE) == 0xE8) - break; - bufferPos = (size_t)(p - data); - if (p >= limit) - break; - prevPosT = bufferPos - prevPosT; - if (prevPosT > 3) - prevMask = 0; - else { - prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7; - if (prevMask != 0) { - unsigned char b = - p[4 - kMaskToBitNumber[prevMask]]; - if (!kMaskToAllowedStatus[prevMask] || - Test86MSByte(b)) { - prevPosT = bufferPos; - prevMask = ((prevMask << 1) & 0x7) | 1; - bufferPos++; - continue; - } - } - } - prevPosT = bufferPos; - - if (Test86MSByte(p[4])) { - uint32_t src = ((uint32_t)p[4] << 24) | - ((uint32_t)p[3] << 16) | ((uint32_t)p[2] << 8) | - ((uint32_t)p[1]); - uint32_t dest; - for (;;) { - uint8_t b; - int b_index; - - dest = src - (ip + (uint32_t)bufferPos); - if (prevMask == 0) - break; - b_index = kMaskToBitNumber[prevMask] * 8; - b = (uint8_t)(dest >> (24 - b_index)); - if (!Test86MSByte(b)) - break; - src = dest ^ ((1 << (32 - b_index)) - 1); - } - p[4] = (uint8_t)(~(((dest >> 24) & 1) - 1)); - p[3] = (uint8_t)(dest >> 16); - p[2] = (uint8_t)(dest >> 8); - p[1] = (uint8_t)dest; - bufferPos += 5; - } else { - prevMask = ((prevMask << 1) & 0x7) | 1; - bufferPos++; - } - } - zip->bcj_prevPosT = prevPosT; - zip->bcj_prevMask = prevMask; - zip->bcj_ip += (uint32_t)bufferPos; - return (bufferPos); -} - -static void -arm_Init(struct _7zip *zip) -{ - zip->bcj_ip = 8; -} - -static size_t -arm_Convert(struct _7zip *zip, uint8_t *buf, size_t size) -{ - // This function was adapted from - // static size_t bcj_arm(struct xz_dec_bcj *s, uint8_t *buf, size_t size) - // in https://git.tukaani.org/xz-embedded.git - - /* - * Branch/Call/Jump (BCJ) filter decoders - * - * Authors: Lasse Collin - * Igor Pavlov - * - * This file has been put into the public domain. - * You can do whatever you want with this file. - */ - - size_t i; - uint32_t addr; - - for (i = 0; i + 4 <= size; i += 4) { - if (buf[i + 3] == 0xEB) { - // Calculate the transformed addr. - addr = (uint32_t)buf[i] | ((uint32_t)buf[i + 1] << 8) - | ((uint32_t)buf[i + 2] << 16); - addr <<= 2; - addr -= zip->bcj_ip + (uint32_t)i; - addr >>= 2; - - // Store the transformed addr in buf. - buf[i] = (uint8_t)addr; - buf[i + 1] = (uint8_t)(addr >> 8); - buf[i + 2] = (uint8_t)(addr >> 16); - } - } - - zip->bcj_ip += (uint32_t)i; - - return i; -} - -static size_t -arm64_Convert(struct _7zip *zip, uint8_t *buf, size_t size) -{ - // This function was adapted from - // static size_t bcj_arm64(struct xz_dec_bcj *s, uint8_t *buf, size_t size) - // in https://git.tukaani.org/xz-embedded.git - - /* - * Branch/Call/Jump (BCJ) filter decoders - * - * Authors: Lasse Collin - * Igor Pavlov - * - * This file has been put into the public domain. - * You can do whatever you want with this file. - */ - - size_t i; - uint32_t instr; - uint32_t addr; - - for (i = 0; i + 4 <= size; i += 4) { - instr = (uint32_t)buf[i] - | ((uint32_t)buf[i+1] << 8) - | ((uint32_t)buf[i+2] << 16) - | ((uint32_t)buf[i+3] << 24); - - if ((instr >> 26) == 0x25) { - /* BL instruction */ - addr = instr - ((zip->bcj_ip + (uint32_t)i) >> 2); - instr = 0x94000000 | (addr & 0x03FFFFFF); - - buf[i] = (uint8_t)instr; - buf[i+1] = (uint8_t)(instr >> 8); - buf[i+2] = (uint8_t)(instr >> 16); - buf[i+3] = (uint8_t)(instr >> 24); - } else if ((instr & 0x9F000000) == 0x90000000) { - /* ADRP instruction */ - addr = ((instr >> 29) & 3) | ((instr >> 3) & 0x1FFFFC); - - /* Only convert values in the range +/-512 MiB. */ - if ((addr + 0x020000) & 0x1C0000) - continue; - - addr -= (zip->bcj_ip + (uint32_t)i) >> 12; - - instr &= 0x9000001F; - instr |= (addr & 3) << 29; - instr |= (addr & 0x03FFFC) << 3; - instr |= (0U - (addr & 0x020000)) & 0xE00000; - - buf[i] = (uint8_t)instr; - buf[i+1] = (uint8_t)(instr >> 8); - buf[i+2] = (uint8_t)(instr >> 16); - buf[i+3] = (uint8_t)(instr >> 24); - } - } - - zip->bcj_ip += (uint32_t)i; - - return i; -} - -/* - * Brought from LZMA SDK. - * - * Bcj2.c -- Converter for x86 code (BCJ2) - * 2008-10-04 : Igor Pavlov : Public domain - * - */ - -#define SZ_ERROR_DATA ARCHIVE_FAILED - -#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80) -#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1)) - -#define kNumTopBits 24 -#define kTopValue ((uint32_t)1 << kNumTopBits) - -#define kNumBitModelTotalBits 11 -#define kBitModelTotal (1 << kNumBitModelTotalBits) -#define kNumMoveBits 5 - -#define RC_READ_BYTE (*buffer++) -#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; } -#define RC_INIT2 zip->bcj2_code = 0; zip->bcj2_range = 0xFFFFFFFF; \ - { int ii; for (ii = 0; ii < 5; ii++) { RC_TEST; zip->bcj2_code = (zip->bcj2_code << 8) | RC_READ_BYTE; }} - -#define NORMALIZE if (zip->bcj2_range < kTopValue) { RC_TEST; zip->bcj2_range <<= 8; zip->bcj2_code = (zip->bcj2_code << 8) | RC_READ_BYTE; } - -#define IF_BIT_0(p) ttt = *(p); bound = (zip->bcj2_range >> kNumBitModelTotalBits) * ttt; if (zip->bcj2_code < bound) -#define UPDATE_0(p) zip->bcj2_range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE; -#define UPDATE_1(p) zip->bcj2_range -= bound; zip->bcj2_code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE; - -static ssize_t -Bcj2_Decode(struct _7zip *zip, uint8_t *outBuf, size_t outSize) -{ - size_t inPos = 0, outPos = 0; - const uint8_t *buf0, *buf1, *buf2, *buf3; - size_t size0, size1, size2, size3; - const uint8_t *buffer, *bufferLim; - unsigned int i, j; - - size0 = zip->tmp_stream_bytes_remaining; - buf0 = zip->tmp_stream_buff + zip->tmp_stream_bytes_avail - size0; - size1 = zip->sub_stream_bytes_remaining[0]; - buf1 = zip->sub_stream_buff[0] + zip->sub_stream_size[0] - size1; - size2 = zip->sub_stream_bytes_remaining[1]; - buf2 = zip->sub_stream_buff[1] + zip->sub_stream_size[1] - size2; - size3 = zip->sub_stream_bytes_remaining[2]; - buf3 = zip->sub_stream_buff[2] + zip->sub_stream_size[2] - size3; - - buffer = buf3; - bufferLim = buffer + size3; - - if (zip->bcj_state == 0) { - /* - * Initialize. - */ - zip->bcj2_prevByte = 0; - for (i = 0; - i < sizeof(zip->bcj2_p) / sizeof(zip->bcj2_p[0]); i++) - zip->bcj2_p[i] = kBitModelTotal >> 1; - RC_INIT2; - zip->bcj_state = 1; - } - - /* - * Gather the odd bytes of a previous call. - */ - for (i = 0; zip->odd_bcj_size > 0 && outPos < outSize; i++) { - outBuf[outPos++] = zip->odd_bcj[i]; - zip->odd_bcj_size--; - } - - if (outSize == 0) { - zip->bcj2_outPos += outPos; - return (outPos); - } - - for (;;) { - uint8_t b; - CProb *prob; - uint32_t bound; - uint32_t ttt; - - size_t limit = size0 - inPos; - if (outSize - outPos < limit) - limit = outSize - outPos; - - if (zip->bcj_state == 1) { - while (limit != 0) { - uint8_t bb = buf0[inPos]; - outBuf[outPos++] = bb; - if (IsJ(zip->bcj2_prevByte, bb)) { - zip->bcj_state = 2; - break; - } - inPos++; - zip->bcj2_prevByte = bb; - limit--; - } - } - - if (limit == 0 || outPos == outSize) - break; - zip->bcj_state = 1; - - b = buf0[inPos++]; - - if (b == 0xE8) - prob = zip->bcj2_p + zip->bcj2_prevByte; - else if (b == 0xE9) - prob = zip->bcj2_p + 256; - else - prob = zip->bcj2_p + 257; - - IF_BIT_0(prob) { - UPDATE_0(prob) - zip->bcj2_prevByte = b; - } else { - uint32_t dest; - const uint8_t *v; - uint8_t out[4]; - - UPDATE_1(prob) - if (b == 0xE8) { - v = buf1; - if (size1 < 4) - return SZ_ERROR_DATA; - buf1 += 4; - size1 -= 4; - } else { - v = buf2; - if (size2 < 4) - return SZ_ERROR_DATA; - buf2 += 4; - size2 -= 4; - } - dest = (((uint32_t)v[0] << 24) | - ((uint32_t)v[1] << 16) | - ((uint32_t)v[2] << 8) | - ((uint32_t)v[3])) - - ((uint32_t)zip->bcj2_outPos + (uint32_t)outPos + 4); - out[0] = (uint8_t)dest; - out[1] = (uint8_t)(dest >> 8); - out[2] = (uint8_t)(dest >> 16); - out[3] = zip->bcj2_prevByte = (uint8_t)(dest >> 24); - - for (i = 0; i < 4 && outPos < outSize; i++) - outBuf[outPos++] = out[i]; - if (i < 4) { - /* - * Save odd bytes which we could not add into - * the output buffer because of out of space. - */ - zip->odd_bcj_size = 4 -i; - for (; i < 4; i++) { - j = i - 4 + (unsigned)zip->odd_bcj_size; - zip->odd_bcj[j] = out[i]; - } - break; - } - } - } - zip->tmp_stream_bytes_remaining -= inPos; - zip->sub_stream_bytes_remaining[0] = size1; - zip->sub_stream_bytes_remaining[1] = size2; - zip->sub_stream_bytes_remaining[2] = bufferLim - buffer; - zip->bcj2_outPos += outPos; - - return ((ssize_t)outPos); -} - diff --git a/thirdparty/libarchive/libarchive/archive_read_support_format_all.c b/thirdparty/libarchive/libarchive/archive_read_support_format_all.c deleted file mode 100644 index dea558bbf..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_format_all.c +++ /dev/null @@ -1,89 +0,0 @@ -/*- - * Copyright (c) 2003-2011 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_all.c 174991 2007-12-30 04:58:22Z kientzle $"); - -#include "archive.h" -#include "archive_private.h" - -int -archive_read_support_format_all(struct archive *a) -{ - archive_check_magic(a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_format_all"); - - /* TODO: It would be nice to compute the ordering - * here automatically so that people who enable just - * a few formats can still get the benefits. That - * may just require the format registration to include - * a "maximum read-ahead" value (anything that uses seek - * would be essentially infinite read-ahead). The core - * bid management can then sort the bidders before calling - * them. - * - * If you implement the above, please return the list below - * to alphabetic order. - */ - - /* - * These bidders are all pretty cheap; they just examine a - * small initial part of the archive. If one of these bids - * high, we can maybe avoid running any of the more expensive - * bidders below. - */ - archive_read_support_format_ar(a); - archive_read_support_format_cpio(a); - archive_read_support_format_empty(a); - archive_read_support_format_lha(a); - archive_read_support_format_mtree(a); - archive_read_support_format_tar(a); - archive_read_support_format_xar(a); - archive_read_support_format_warc(a); - - /* - * Install expensive bidders last. By doing them last, we - * increase the chance that a high bid from someone else will - * make it unnecessary for these to do anything at all. - */ - /* These three have potentially large look-ahead. */ - archive_read_support_format_7zip(a); - archive_read_support_format_cab(a); - archive_read_support_format_rar(a); - archive_read_support_format_rar5(a); - archive_read_support_format_iso9660(a); - /* Seek is really bad, since it forces the read-ahead - * logic to discard buffered data. */ - archive_read_support_format_zip(a); - - /* Note: We always return ARCHIVE_OK here, even if some of the - * above return ARCHIVE_WARN. The intent here is to enable - * "as much as possible." Clients who need specific - * compression should enable those individually so they can - * verify the level of support. */ - /* Clear any warning messages set by the above functions. */ - archive_clear_error(a); - return (ARCHIVE_OK); -} diff --git a/thirdparty/libarchive/libarchive/archive_read_support_format_ar.c b/thirdparty/libarchive/libarchive/archive_read_support_format_ar.c deleted file mode 100644 index 296b7db04..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_format_ar.c +++ /dev/null @@ -1,638 +0,0 @@ -/*- - * Copyright (c) 2007 Kai Wang - * Copyright (c) 2007 Tim Kientzle - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_ar.c 201101 2009-12-28 03:06:27Z kientzle $"); - -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_LIMITS_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" -#include "archive_private.h" -#include "archive_read_private.h" - -struct ar { - int64_t entry_bytes_remaining; - /* unconsumed is purely to track data we've gotten from readahead, - * but haven't yet marked as consumed. Must be paired with - * entry_bytes_remaining usage/modification. - */ - size_t entry_bytes_unconsumed; - int64_t entry_offset; - int64_t entry_padding; - char *strtab; - size_t strtab_size; - char read_global_header; -}; - -/* - * Define structure of the "ar" header. - */ -#define AR_name_offset 0 -#define AR_name_size 16 -#define AR_date_offset 16 -#define AR_date_size 12 -#define AR_uid_offset 28 -#define AR_uid_size 6 -#define AR_gid_offset 34 -#define AR_gid_size 6 -#define AR_mode_offset 40 -#define AR_mode_size 8 -#define AR_size_offset 48 -#define AR_size_size 10 -#define AR_fmag_offset 58 -#define AR_fmag_size 2 - -static int archive_read_format_ar_bid(struct archive_read *a, int); -static int archive_read_format_ar_cleanup(struct archive_read *a); -static int archive_read_format_ar_read_data(struct archive_read *a, - const void **buff, size_t *size, int64_t *offset); -static int archive_read_format_ar_skip(struct archive_read *a); -static int archive_read_format_ar_read_header(struct archive_read *a, - struct archive_entry *e); -static uint64_t ar_atol8(const char *p, unsigned char_cnt); -static uint64_t ar_atol10(const char *p, unsigned char_cnt); -static int ar_parse_gnu_filename_table(struct archive_read *a); -static int ar_parse_common_header(struct ar *ar, struct archive_entry *, - const char *h); - -int -archive_read_support_format_ar(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - struct ar *ar; - int r; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_format_ar"); - - ar = (struct ar *)calloc(1, sizeof(*ar)); - if (ar == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate ar data"); - return (ARCHIVE_FATAL); - } - ar->strtab = NULL; - - r = __archive_read_register_format(a, - ar, - "ar", - archive_read_format_ar_bid, - NULL, - archive_read_format_ar_read_header, - archive_read_format_ar_read_data, - archive_read_format_ar_skip, - NULL, - archive_read_format_ar_cleanup, - NULL, - NULL); - - if (r != ARCHIVE_OK) { - free(ar); - return (r); - } - return (ARCHIVE_OK); -} - -static int -archive_read_format_ar_cleanup(struct archive_read *a) -{ - struct ar *ar; - - ar = (struct ar *)(a->format->data); - free(ar->strtab); - free(ar); - (a->format->data) = NULL; - return (ARCHIVE_OK); -} - -static int -archive_read_format_ar_bid(struct archive_read *a, int best_bid) -{ - const void *h; - - (void)best_bid; /* UNUSED */ - - /* - * Verify the 8-byte file signature. - * TODO: Do we need to check more than this? - */ - if ((h = __archive_read_ahead(a, 8, NULL)) == NULL) - return (-1); - if (memcmp(h, "!\n", 8) == 0) { - return (64); - } - return (-1); -} - -static int -_ar_read_header(struct archive_read *a, struct archive_entry *entry, - struct ar *ar, const char *h, size_t *unconsumed) -{ - char filename[AR_name_size + 1]; - uint64_t number; /* Used to hold parsed numbers before validation. */ - size_t bsd_name_length, entry_size; - char *p, *st; - const void *b; - int r; - - /* Verify the magic signature on the file header. */ - if (strncmp(h + AR_fmag_offset, "`\n", 2) != 0) { - archive_set_error(&a->archive, EINVAL, - "Incorrect file header signature"); - return (ARCHIVE_FATAL); - } - - /* Copy filename into work buffer. */ - strncpy(filename, h + AR_name_offset, AR_name_size); - filename[AR_name_size] = '\0'; - - /* - * Guess the format variant based on the filename. - */ - if (a->archive.archive_format == ARCHIVE_FORMAT_AR) { - /* We don't already know the variant, so let's guess. */ - /* - * Biggest clue is presence of '/': GNU starts special - * filenames with '/', appends '/' as terminator to - * non-special names, so anything with '/' should be - * GNU except for BSD long filenames. - */ - if (strncmp(filename, "#1/", 3) == 0) - a->archive.archive_format = ARCHIVE_FORMAT_AR_BSD; - else if (strchr(filename, '/') != NULL) - a->archive.archive_format = ARCHIVE_FORMAT_AR_GNU; - else if (strncmp(filename, "__.SYMDEF", 9) == 0) - a->archive.archive_format = ARCHIVE_FORMAT_AR_BSD; - /* - * XXX Do GNU/SVR4 'ar' programs ever omit trailing '/' - * if name exactly fills 16-byte field? If so, we - * can't assume entries without '/' are BSD. XXX - */ - } - - /* Update format name from the code. */ - if (a->archive.archive_format == ARCHIVE_FORMAT_AR_GNU) - a->archive.archive_format_name = "ar (GNU/SVR4)"; - else if (a->archive.archive_format == ARCHIVE_FORMAT_AR_BSD) - a->archive.archive_format_name = "ar (BSD)"; - else - a->archive.archive_format_name = "ar"; - - /* - * Remove trailing spaces from the filename. GNU and BSD - * variants both pad filename area out with spaces. - * This will only be wrong if GNU/SVR4 'ar' implementations - * omit trailing '/' for 16-char filenames and we have - * a 16-char filename that ends in ' '. - */ - p = filename + AR_name_size - 1; - while (p >= filename && *p == ' ') { - *p = '\0'; - p--; - } - - /* - * Remove trailing slash unless first character is '/'. - * (BSD entries never end in '/', so this will only trim - * GNU-format entries. GNU special entries start with '/' - * and are not terminated in '/', so we don't trim anything - * that starts with '/'.) - */ - if (filename[0] != '/' && p > filename && *p == '/') { - *p = '\0'; - } - - if (p < filename) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Found entry with empty filename"); - return (ARCHIVE_FATAL); - } - - /* - * '//' is the GNU filename table. - * Later entries can refer to names in this table. - */ - if (strcmp(filename, "//") == 0) { - /* This must come before any call to _read_ahead. */ - ar_parse_common_header(ar, entry, h); - archive_entry_copy_pathname(entry, filename); - archive_entry_set_filetype(entry, AE_IFREG); - /* Get the size of the filename table. */ - number = ar_atol10(h + AR_size_offset, AR_size_size); - if (number > SIZE_MAX || number > 1024 * 1024 * 1024) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Filename table too large"); - return (ARCHIVE_FATAL); - } - entry_size = (size_t)number; - if (entry_size == 0) { - archive_set_error(&a->archive, EINVAL, - "Invalid string table"); - return (ARCHIVE_FATAL); - } - if (ar->strtab != NULL) { - archive_set_error(&a->archive, EINVAL, - "More than one string tables exist"); - return (ARCHIVE_FATAL); - } - - /* Read the filename table into memory. */ - st = malloc(entry_size); - if (st == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate filename table buffer"); - return (ARCHIVE_FATAL); - } - ar->strtab = st; - ar->strtab_size = entry_size; - - if (*unconsumed) { - __archive_read_consume(a, *unconsumed); - *unconsumed = 0; - } - - if ((b = __archive_read_ahead(a, entry_size, NULL)) == NULL) - return (ARCHIVE_FATAL); - memcpy(st, b, entry_size); - __archive_read_consume(a, entry_size); - /* All contents are consumed. */ - ar->entry_bytes_remaining = 0; - archive_entry_set_size(entry, ar->entry_bytes_remaining); - - /* Parse the filename table. */ - return (ar_parse_gnu_filename_table(a)); - } - - /* - * GNU variant handles long filenames by storing / - * to indicate a name stored in the filename table. - * XXX TODO: Verify that it's all digits... Don't be fooled - * by "/9xyz" XXX - */ - if (filename[0] == '/' && filename[1] >= '0' && filename[1] <= '9') { - number = ar_atol10(h + AR_name_offset + 1, AR_name_size - 1); - /* - * If we can't look up the real name, warn and return - * the entry with the wrong name. - */ - if (ar->strtab == NULL || number >= ar->strtab_size) { - archive_set_error(&a->archive, EINVAL, - "Can't find long filename for GNU/SVR4 archive entry"); - archive_entry_copy_pathname(entry, filename); - /* Parse the time, owner, mode, size fields. */ - ar_parse_common_header(ar, entry, h); - return (ARCHIVE_FATAL); - } - - archive_entry_copy_pathname(entry, &ar->strtab[(size_t)number]); - /* Parse the time, owner, mode, size fields. */ - return (ar_parse_common_header(ar, entry, h)); - } - - /* - * BSD handles long filenames by storing "#1/" followed by the - * length of filename as a decimal number, then prepends the - * the filename to the file contents. - */ - if (strncmp(filename, "#1/", 3) == 0) { - /* Parse the time, owner, mode, size fields. */ - /* This must occur before _read_ahead is called again. */ - ar_parse_common_header(ar, entry, h); - - /* Parse the size of the name, adjust the file size. */ - number = ar_atol10(h + AR_name_offset + 3, AR_name_size - 3); - /* Sanity check the filename length: - * = Must be <= SIZE_MAX - 1 - * = Must be <= 1MB - * = Cannot be bigger than the entire entry - */ - if (number > SIZE_MAX - 1 - || number > 1024 * 1024 - || (int64_t)number > ar->entry_bytes_remaining) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Bad input file size"); - return (ARCHIVE_FATAL); - } - bsd_name_length = (size_t)number; - ar->entry_bytes_remaining -= bsd_name_length; - /* Adjust file size reported to client. */ - archive_entry_set_size(entry, ar->entry_bytes_remaining); - - if (*unconsumed) { - __archive_read_consume(a, *unconsumed); - *unconsumed = 0; - } - - /* Read the long name into memory. */ - if ((b = __archive_read_ahead(a, bsd_name_length, NULL)) == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Truncated input file"); - return (ARCHIVE_FATAL); - } - /* Store it in the entry. */ - p = (char *)malloc(bsd_name_length + 1); - if (p == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate fname buffer"); - return (ARCHIVE_FATAL); - } - strncpy(p, b, bsd_name_length); - p[bsd_name_length] = '\0'; - - __archive_read_consume(a, bsd_name_length); - - archive_entry_copy_pathname(entry, p); - free(p); - return (ARCHIVE_OK); - } - - /* - * "/" is the SVR4/GNU archive symbol table. - * "/SYM64/" is the SVR4/GNU 64-bit variant archive symbol table. - */ - if (strcmp(filename, "/") == 0 || strcmp(filename, "/SYM64/") == 0) { - archive_entry_copy_pathname(entry, filename); - /* Parse the time, owner, mode, size fields. */ - r = ar_parse_common_header(ar, entry, h); - /* Force the file type to a regular file. */ - archive_entry_set_filetype(entry, AE_IFREG); - return (r); - } - - /* - * "__.SYMDEF" is a BSD archive symbol table. - */ - if (strcmp(filename, "__.SYMDEF") == 0) { - archive_entry_copy_pathname(entry, filename); - /* Parse the time, owner, mode, size fields. */ - return (ar_parse_common_header(ar, entry, h)); - } - - /* - * Otherwise, this is a standard entry. The filename - * has already been trimmed as much as possible, based - * on our current knowledge of the format. - */ - archive_entry_copy_pathname(entry, filename); - return (ar_parse_common_header(ar, entry, h)); -} - -static int -archive_read_format_ar_read_header(struct archive_read *a, - struct archive_entry *entry) -{ - struct ar *ar = (struct ar*)(a->format->data); - size_t unconsumed; - const void *header_data; - int ret; - - if (!ar->read_global_header) { - /* - * We are now at the beginning of the archive, - * so we need first consume the ar global header. - */ - __archive_read_consume(a, 8); - ar->read_global_header = 1; - /* Set a default format code for now. */ - a->archive.archive_format = ARCHIVE_FORMAT_AR; - } - - /* Read the header for the next file entry. */ - if ((header_data = __archive_read_ahead(a, 60, NULL)) == NULL) - /* Broken header. */ - return (ARCHIVE_EOF); - - unconsumed = 60; - - ret = _ar_read_header(a, entry, ar, (const char *)header_data, &unconsumed); - - if (unconsumed) - __archive_read_consume(a, unconsumed); - - return ret; -} - - -static int -ar_parse_common_header(struct ar *ar, struct archive_entry *entry, - const char *h) -{ - uint64_t n; - - /* Copy remaining header */ - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_mtime(entry, - (time_t)ar_atol10(h + AR_date_offset, AR_date_size), 0L); - archive_entry_set_uid(entry, - (uid_t)ar_atol10(h + AR_uid_offset, AR_uid_size)); - archive_entry_set_gid(entry, - (gid_t)ar_atol10(h + AR_gid_offset, AR_gid_size)); - archive_entry_set_mode(entry, - (mode_t)ar_atol8(h + AR_mode_offset, AR_mode_size)); - n = ar_atol10(h + AR_size_offset, AR_size_size); - - ar->entry_offset = 0; - ar->entry_padding = n % 2; - archive_entry_set_size(entry, n); - ar->entry_bytes_remaining = n; - return (ARCHIVE_OK); -} - -static int -archive_read_format_ar_read_data(struct archive_read *a, - const void **buff, size_t *size, int64_t *offset) -{ - ssize_t bytes_read; - struct ar *ar; - - ar = (struct ar *)(a->format->data); - - if (ar->entry_bytes_unconsumed) { - __archive_read_consume(a, ar->entry_bytes_unconsumed); - ar->entry_bytes_unconsumed = 0; - } - - if (ar->entry_bytes_remaining > 0) { - *buff = __archive_read_ahead(a, 1, &bytes_read); - if (bytes_read == 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Truncated ar archive"); - return (ARCHIVE_FATAL); - } - if (bytes_read < 0) - return (ARCHIVE_FATAL); - if (bytes_read > ar->entry_bytes_remaining) - bytes_read = (ssize_t)ar->entry_bytes_remaining; - *size = bytes_read; - ar->entry_bytes_unconsumed = bytes_read; - *offset = ar->entry_offset; - ar->entry_offset += bytes_read; - ar->entry_bytes_remaining -= bytes_read; - return (ARCHIVE_OK); - } else { - int64_t skipped = __archive_read_consume(a, ar->entry_padding); - if (skipped >= 0) { - ar->entry_padding -= skipped; - } - if (ar->entry_padding) { - if (skipped >= 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Truncated ar archive- failed consuming padding"); - } - return (ARCHIVE_FATAL); - } - *buff = NULL; - *size = 0; - *offset = ar->entry_offset; - return (ARCHIVE_EOF); - } -} - -static int -archive_read_format_ar_skip(struct archive_read *a) -{ - int64_t bytes_skipped; - struct ar* ar; - - ar = (struct ar *)(a->format->data); - - bytes_skipped = __archive_read_consume(a, - ar->entry_bytes_remaining + ar->entry_padding - + ar->entry_bytes_unconsumed); - if (bytes_skipped < 0) - return (ARCHIVE_FATAL); - - ar->entry_bytes_remaining = 0; - ar->entry_bytes_unconsumed = 0; - ar->entry_padding = 0; - - return (ARCHIVE_OK); -} - -static int -ar_parse_gnu_filename_table(struct archive_read *a) -{ - struct ar *ar; - char *p; - size_t size; - - ar = (struct ar*)(a->format->data); - size = ar->strtab_size; - - for (p = ar->strtab; p < ar->strtab + size - 1; ++p) { - if (*p == '/') { - *p++ = '\0'; - if (*p != '\n') - goto bad_string_table; - *p = '\0'; - } - } - /* - * GNU ar always pads the table to an even size. - * The pad character is either '\n' or '`'. - */ - if (p != ar->strtab + size && *p != '\n' && *p != '`') - goto bad_string_table; - - /* Enforce zero termination. */ - ar->strtab[size - 1] = '\0'; - - return (ARCHIVE_OK); - -bad_string_table: - archive_set_error(&a->archive, EINVAL, - "Invalid string table"); - free(ar->strtab); - ar->strtab = NULL; - return (ARCHIVE_FATAL); -} - -static uint64_t -ar_atol8(const char *p, unsigned char_cnt) -{ - uint64_t l, limit, last_digit_limit; - unsigned int digit, base; - - base = 8; - limit = UINT64_MAX / base; - last_digit_limit = UINT64_MAX % base; - - while ((*p == ' ' || *p == '\t') && char_cnt-- > 0) - p++; - - l = 0; - digit = *p - '0'; - while (*p >= '0' && digit < base && char_cnt-- > 0) { - if (l>limit || (l == limit && digit > last_digit_limit)) { - l = UINT64_MAX; /* Truncate on overflow. */ - break; - } - l = (l * base) + digit; - digit = *++p - '0'; - } - return (l); -} - -static uint64_t -ar_atol10(const char *p, unsigned char_cnt) -{ - uint64_t l, limit, last_digit_limit; - unsigned int base, digit; - - base = 10; - limit = UINT64_MAX / base; - last_digit_limit = UINT64_MAX % base; - - while ((*p == ' ' || *p == '\t') && char_cnt-- > 0) - p++; - l = 0; - digit = *p - '0'; - while (*p >= '0' && digit < base && char_cnt-- > 0) { - if (l > limit || (l == limit && digit > last_digit_limit)) { - l = UINT64_MAX; /* Truncate on overflow. */ - break; - } - l = (l * base) + digit; - digit = *++p - '0'; - } - return (l); -} diff --git a/thirdparty/libarchive/libarchive/archive_read_support_format_by_code.c b/thirdparty/libarchive/libarchive/archive_read_support_format_by_code.c deleted file mode 100644 index 89e96f1f5..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_format_by_code.c +++ /dev/null @@ -1,92 +0,0 @@ -/*- - * Copyright (c) 2003-2011 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_ERRNO_H -#include -#endif - -#include "archive.h" -#include "archive_private.h" - -int -archive_read_support_format_by_code(struct archive *a, int format_code) -{ - archive_check_magic(a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_format_by_code"); - - switch (format_code & ARCHIVE_FORMAT_BASE_MASK) { - case ARCHIVE_FORMAT_7ZIP: - return archive_read_support_format_7zip(a); - break; - case ARCHIVE_FORMAT_AR: - return archive_read_support_format_ar(a); - break; - case ARCHIVE_FORMAT_CAB: - return archive_read_support_format_cab(a); - break; - case ARCHIVE_FORMAT_CPIO: - return archive_read_support_format_cpio(a); - break; - case ARCHIVE_FORMAT_EMPTY: - return archive_read_support_format_empty(a); - break; - case ARCHIVE_FORMAT_ISO9660: - return archive_read_support_format_iso9660(a); - break; - case ARCHIVE_FORMAT_LHA: - return archive_read_support_format_lha(a); - break; - case ARCHIVE_FORMAT_MTREE: - return archive_read_support_format_mtree(a); - break; - case ARCHIVE_FORMAT_RAR: - return archive_read_support_format_rar(a); - break; - case ARCHIVE_FORMAT_RAR_V5: - return archive_read_support_format_rar5(a); - break; - case ARCHIVE_FORMAT_RAW: - return archive_read_support_format_raw(a); - break; - case ARCHIVE_FORMAT_TAR: - return archive_read_support_format_tar(a); - break; - case ARCHIVE_FORMAT_WARC: - return archive_read_support_format_warc(a); - break; - case ARCHIVE_FORMAT_XAR: - return archive_read_support_format_xar(a); - break; - case ARCHIVE_FORMAT_ZIP: - return archive_read_support_format_zip(a); - break; - } - archive_set_error(a, ARCHIVE_ERRNO_PROGRAMMER, - "Invalid format code specified"); - return (ARCHIVE_FATAL); -} diff --git a/thirdparty/libarchive/libarchive/archive_read_support_format_cab.c b/thirdparty/libarchive/libarchive/archive_read_support_format_cab.c deleted file mode 100644 index 3b552a84d..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_format_cab.c +++ /dev/null @@ -1,3228 +0,0 @@ -/*- - * Copyright (c) 2010-2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_LIMITS_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_ZLIB_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" -#include "archive_entry_locale.h" -#include "archive_private.h" -#include "archive_read_private.h" -#include "archive_endian.h" - - -struct lzx_dec { - /* Decoding status. */ - int state; - - /* - * Window to see last decoded data, from 32KBi to 2MBi. - */ - int w_size; - int w_mask; - /* Window buffer, which is a loop buffer. */ - unsigned char *w_buff; - /* The insert position to the window. */ - int w_pos; - /* The position where we can copy decoded code from the window. */ - int copy_pos; - /* The length how many bytes we can copy decoded code from - * the window. */ - int copy_len; - /* Translation reversal for x86 processor CALL byte sequence(E8). - * This is used for LZX only. */ - uint32_t translation_size; - char translation; - char block_type; -#define VERBATIM_BLOCK 1 -#define ALIGNED_OFFSET_BLOCK 2 -#define UNCOMPRESSED_BLOCK 3 - size_t block_size; - size_t block_bytes_avail; - /* Repeated offset. */ - int r0, r1, r2; - unsigned char rbytes[4]; - int rbytes_avail; - int length_header; - int position_slot; - int offset_bits; - - struct lzx_pos_tbl { - int base; - int footer_bits; - } *pos_tbl; - /* - * Bit stream reader. - */ - struct lzx_br { -#define CACHE_TYPE uint64_t -#define CACHE_BITS (8 * sizeof(CACHE_TYPE)) - /* Cache buffer. */ - CACHE_TYPE cache_buffer; - /* Indicates how many bits avail in cache_buffer. */ - int cache_avail; - unsigned char odd; - char have_odd; - } br; - - /* - * Huffman coding. - */ - struct huffman { - int len_size; - int freq[17]; - unsigned char *bitlen; - - /* - * Use a index table. It's faster than searching a huffman - * coding tree, which is a binary tree. But a use of a large - * index table causes L1 cache read miss many times. - */ - int max_bits; - int tbl_bits; - int tree_used; - /* Direct access table. */ - uint16_t *tbl; - } at, lt, mt, pt; - - int loop; - int error; -}; - -static const int slots[] = { - 30, 32, 34, 36, 38, 42, 50, 66, 98, 162, 290 -}; -#define SLOT_BASE 15 -#define SLOT_MAX 21/*->25*/ - -struct lzx_stream { - const unsigned char *next_in; - int64_t avail_in; - int64_t total_in; - unsigned char *next_out; - int64_t avail_out; - int64_t total_out; - struct lzx_dec *ds; -}; - -/* - * Cabinet file definitions. - */ -/* CFHEADER offset */ -#define CFHEADER_signature 0 -#define CFHEADER_cbCabinet 8 -#define CFHEADER_coffFiles 16 -#define CFHEADER_versionMinor 24 -#define CFHEADER_versionMajor 25 -#define CFHEADER_cFolders 26 -#define CFHEADER_cFiles 28 -#define CFHEADER_flags 30 -#define CFHEADER_setID 32 -#define CFHEADER_iCabinet 34 -#define CFHEADER_cbCFHeader 36 -#define CFHEADER_cbCFFolder 38 -#define CFHEADER_cbCFData 39 - -/* CFFOLDER offset */ -#define CFFOLDER_coffCabStart 0 -#define CFFOLDER_cCFData 4 -#define CFFOLDER_typeCompress 6 -#define CFFOLDER_abReserve 8 - -/* CFFILE offset */ -#define CFFILE_cbFile 0 -#define CFFILE_uoffFolderStart 4 -#define CFFILE_iFolder 8 -#define CFFILE_date_time 10 -#define CFFILE_attribs 14 - -/* CFDATA offset */ -#define CFDATA_csum 0 -#define CFDATA_cbData 4 -#define CFDATA_cbUncomp 6 - -static const char * const compression_name[] = { - "NONE", - "MSZIP", - "Quantum", - "LZX", -}; - -struct cfdata { - /* Sum value of this CFDATA. */ - uint32_t sum; - uint16_t compressed_size; - uint16_t compressed_bytes_remaining; - uint16_t uncompressed_size; - uint16_t uncompressed_bytes_remaining; - /* To know how many bytes we have decompressed. */ - uint16_t uncompressed_avail; - /* Offset from the beginning of compressed data of this CFDATA */ - uint16_t read_offset; - int64_t unconsumed; - /* To keep memory image of this CFDATA to compute the sum. */ - size_t memimage_size; - unsigned char *memimage; - /* Result of calculation of sum. */ - uint32_t sum_calculated; - unsigned char sum_extra[4]; - int sum_extra_avail; - const void *sum_ptr; -}; - -struct cffolder { - uint32_t cfdata_offset_in_cab; - uint16_t cfdata_count; - uint16_t comptype; -#define COMPTYPE_NONE 0x0000 -#define COMPTYPE_MSZIP 0x0001 -#define COMPTYPE_QUANTUM 0x0002 -#define COMPTYPE_LZX 0x0003 - uint16_t compdata; - const char *compname; - /* At the time reading CFDATA */ - struct cfdata cfdata; - int cfdata_index; - /* Flags to mark progress of decompression. */ - char decompress_init; -}; - -struct cffile { - uint32_t uncompressed_size; - uint32_t offset; - time_t mtime; - uint16_t folder; -#define iFoldCONTINUED_FROM_PREV 0xFFFD -#define iFoldCONTINUED_TO_NEXT 0xFFFE -#define iFoldCONTINUED_PREV_AND_NEXT 0xFFFF - unsigned char attr; -#define ATTR_RDONLY 0x01 -#define ATTR_NAME_IS_UTF 0x80 - struct archive_string pathname; -}; - -struct cfheader { - /* Total bytes of all file size in a Cabinet. */ - uint32_t total_bytes; - uint32_t files_offset; - uint16_t folder_count; - uint16_t file_count; - uint16_t flags; -#define PREV_CABINET 0x0001 -#define NEXT_CABINET 0x0002 -#define RESERVE_PRESENT 0x0004 - uint16_t setid; - uint16_t cabinet; - /* Version number. */ - unsigned char major; - unsigned char minor; - unsigned char cffolder; - unsigned char cfdata; - /* All folders in a cabinet. */ - struct cffolder *folder_array; - /* All files in a cabinet. */ - struct cffile *file_array; - int file_index; -}; - -struct cab { - /* entry_bytes_remaining is the number of bytes we expect. */ - int64_t entry_offset; - int64_t entry_bytes_remaining; - int64_t entry_unconsumed; - int64_t entry_compressed_bytes_read; - int64_t entry_uncompressed_bytes_read; - struct cffolder *entry_cffolder; - struct cffile *entry_cffile; - struct cfdata *entry_cfdata; - - /* Offset from beginning of a cabinet file. */ - int64_t cab_offset; - struct cfheader cfheader; - struct archive_wstring ws; - - /* Flag to mark progress that an archive was read their first header.*/ - char found_header; - char end_of_archive; - char end_of_entry; - char end_of_entry_cleanup; - char read_data_invoked; - int64_t bytes_skipped; - - unsigned char *uncompressed_buffer; - size_t uncompressed_buffer_size; - - int init_default_conversion; - struct archive_string_conv *sconv; - struct archive_string_conv *sconv_default; - struct archive_string_conv *sconv_utf8; - char format_name[64]; - -#ifdef HAVE_ZLIB_H - z_stream stream; - char stream_valid; -#endif - struct lzx_stream xstrm; -}; - -static int archive_read_format_cab_bid(struct archive_read *, int); -static int archive_read_format_cab_options(struct archive_read *, - const char *, const char *); -static int archive_read_format_cab_read_header(struct archive_read *, - struct archive_entry *); -static int archive_read_format_cab_read_data(struct archive_read *, - const void **, size_t *, int64_t *); -static int archive_read_format_cab_read_data_skip(struct archive_read *); -static int archive_read_format_cab_cleanup(struct archive_read *); - -static int cab_skip_sfx(struct archive_read *); -static time_t cab_dos_time(const unsigned char *); -static int cab_read_data(struct archive_read *, const void **, - size_t *, int64_t *); -static int cab_read_header(struct archive_read *); -static uint32_t cab_checksum_cfdata_4(const void *, size_t bytes, uint32_t); -static uint32_t cab_checksum_cfdata(const void *, size_t bytes, uint32_t); -static void cab_checksum_update(struct archive_read *, size_t); -static int cab_checksum_finish(struct archive_read *); -static int cab_next_cfdata(struct archive_read *); -static const void *cab_read_ahead_cfdata(struct archive_read *, ssize_t *); -static const void *cab_read_ahead_cfdata_none(struct archive_read *, ssize_t *); -static const void *cab_read_ahead_cfdata_deflate(struct archive_read *, - ssize_t *); -static const void *cab_read_ahead_cfdata_lzx(struct archive_read *, - ssize_t *); -static int64_t cab_consume_cfdata(struct archive_read *, int64_t); -static int64_t cab_minimum_consume_cfdata(struct archive_read *, int64_t); -static int lzx_decode_init(struct lzx_stream *, int); -static int lzx_read_blocks(struct lzx_stream *, int); -static int lzx_decode_blocks(struct lzx_stream *, int); -static void lzx_decode_free(struct lzx_stream *); -static void lzx_translation(struct lzx_stream *, void *, size_t, uint32_t); -static void lzx_cleanup_bitstream(struct lzx_stream *); -static int lzx_decode(struct lzx_stream *, int); -static int lzx_read_pre_tree(struct lzx_stream *); -static int lzx_read_bitlen(struct lzx_stream *, struct huffman *, int); -static int lzx_huffman_init(struct huffman *, size_t, int); -static void lzx_huffman_free(struct huffman *); -static int lzx_make_huffman_table(struct huffman *); -static inline int lzx_decode_huffman(struct huffman *, unsigned); - - -int -archive_read_support_format_cab(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - struct cab *cab; - int r; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_format_cab"); - - cab = (struct cab *)calloc(1, sizeof(*cab)); - if (cab == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate CAB data"); - return (ARCHIVE_FATAL); - } - archive_string_init(&cab->ws); - archive_wstring_ensure(&cab->ws, 256); - - r = __archive_read_register_format(a, - cab, - "cab", - archive_read_format_cab_bid, - archive_read_format_cab_options, - archive_read_format_cab_read_header, - archive_read_format_cab_read_data, - archive_read_format_cab_read_data_skip, - NULL, - archive_read_format_cab_cleanup, - NULL, - NULL); - - if (r != ARCHIVE_OK) - free(cab); - return (ARCHIVE_OK); -} - -static int -find_cab_magic(const char *p) -{ - switch (p[4]) { - case 0: - /* - * Note: Self-Extraction program has 'MSCF' string in their - * program. If we were finding 'MSCF' string only, we got - * wrong place for Cabinet header, thus, we have to check - * following four bytes which are reserved and must be set - * to zero. - */ - if (memcmp(p, "MSCF\0\0\0\0", 8) == 0) - return 0; - return 5; - case 'F': return 1; - case 'C': return 2; - case 'S': return 3; - case 'M': return 4; - default: return 5; - } -} - -static int -archive_read_format_cab_bid(struct archive_read *a, int best_bid) -{ - const char *p; - ssize_t bytes_avail, offset, window; - - /* If there's already a better bid than we can ever - make, don't bother testing. */ - if (best_bid > 64) - return (-1); - - if ((p = __archive_read_ahead(a, 8, NULL)) == NULL) - return (-1); - - if (memcmp(p, "MSCF\0\0\0\0", 8) == 0) - return (64); - - /* - * Attempt to handle self-extracting archives - * by noting a PE header and searching forward - * up to 128k for a 'MSCF' marker. - */ - if (p[0] == 'M' && p[1] == 'Z') { - offset = 0; - window = 4096; - while (offset < (1024 * 128)) { - const char *h = __archive_read_ahead(a, offset + window, - &bytes_avail); - if (h == NULL) { - /* Remaining bytes are less than window. */ - window >>= 1; - if (window < 128) - return (0); - continue; - } - p = h + offset; - while (p + 8 < h + bytes_avail) { - int next; - if ((next = find_cab_magic(p)) == 0) - return (64); - p += next; - } - offset = p - h; - } - } - return (0); -} - -static int -archive_read_format_cab_options(struct archive_read *a, - const char *key, const char *val) -{ - struct cab *cab; - int ret = ARCHIVE_FAILED; - - cab = (struct cab *)(a->format->data); - if (strcmp(key, "hdrcharset") == 0) { - if (val == NULL || val[0] == 0) - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "cab: hdrcharset option needs a character-set name"); - else { - cab->sconv = archive_string_conversion_from_charset( - &a->archive, val, 0); - if (cab->sconv != NULL) - ret = ARCHIVE_OK; - else - ret = ARCHIVE_FATAL; - } - return (ret); - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -static int -cab_skip_sfx(struct archive_read *a) -{ - const char *p, *q; - size_t skip; - ssize_t bytes, window; - - window = 4096; - for (;;) { - const char *h = __archive_read_ahead(a, window, &bytes); - if (h == NULL) { - /* Remaining size are less than window. */ - window >>= 1; - if (window < 128) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Couldn't find out CAB header"); - return (ARCHIVE_FATAL); - } - continue; - } - p = h; - q = p + bytes; - - /* - * Scan ahead until we find something that looks - * like the cab header. - */ - while (p + 8 < q) { - int next; - if ((next = find_cab_magic(p)) == 0) { - skip = p - h; - __archive_read_consume(a, skip); - return (ARCHIVE_OK); - } - p += next; - } - skip = p - h; - __archive_read_consume(a, skip); - } -} - -static int -truncated_error(struct archive_read *a) -{ - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated CAB header"); - return (ARCHIVE_FATAL); -} - -static ssize_t -cab_strnlen(const unsigned char *p, size_t maxlen) -{ - size_t i; - - for (i = 0; i <= maxlen; i++) { - if (p[i] == 0) - break; - } - if (i > maxlen) - return (-1);/* invalid */ - return ((ssize_t)i); -} - -/* Read bytes as much as remaining. */ -static const void * -cab_read_ahead_remaining(struct archive_read *a, size_t min, ssize_t *avail) -{ - const void *p; - - while (min > 0) { - p = __archive_read_ahead(a, min, avail); - if (p != NULL) - return (p); - min--; - } - return (NULL); -} - -/* Convert a path separator '\' -> '/' */ -static int -cab_convert_path_separator_1(struct archive_string *fn, unsigned char attr) -{ - size_t i; - int mb; - - /* Easy check if we have '\' in multi-byte string. */ - mb = 0; - for (i = 0; i < archive_strlen(fn); i++) { - if (fn->s[i] == '\\') { - if (mb) { - /* This may be second byte of multi-byte - * character. */ - break; - } - fn->s[i] = '/'; - mb = 0; - } else if ((fn->s[i] & 0x80) && !(attr & ATTR_NAME_IS_UTF)) - mb = 1; - else - mb = 0; - } - if (i == archive_strlen(fn)) - return (0); - return (-1); -} - -/* - * Replace a character '\' with '/' in wide character. - */ -static void -cab_convert_path_separator_2(struct cab *cab, struct archive_entry *entry) -{ - const wchar_t *wp; - size_t i; - - /* If a conversion to wide character failed, force the replacement. */ - if ((wp = archive_entry_pathname_w(entry)) != NULL) { - archive_wstrcpy(&(cab->ws), wp); - for (i = 0; i < archive_strlen(&(cab->ws)); i++) { - if (cab->ws.s[i] == L'\\') - cab->ws.s[i] = L'/'; - } - archive_entry_copy_pathname_w(entry, cab->ws.s); - } -} - -/* - * Read CFHEADER, CFFOLDER and CFFILE. - */ -static int -cab_read_header(struct archive_read *a) -{ - const unsigned char *p; - struct cab *cab; - struct cfheader *hd; - size_t bytes, used; - ssize_t len; - int64_t skip; - int err, i; - int cur_folder, prev_folder; - uint32_t offset32; - - a->archive.archive_format = ARCHIVE_FORMAT_CAB; - if (a->archive.archive_format_name == NULL) - a->archive.archive_format_name = "CAB"; - - if ((p = __archive_read_ahead(a, 42, NULL)) == NULL) - return (truncated_error(a)); - - cab = (struct cab *)(a->format->data); - if (cab->found_header == 0 && - p[0] == 'M' && p[1] == 'Z') { - /* This is an executable? Must be self-extracting... */ - err = cab_skip_sfx(a); - if (err < ARCHIVE_WARN) - return (err); - - /* Re-read header after processing the SFX. */ - if ((p = __archive_read_ahead(a, 42, NULL)) == NULL) - return (truncated_error(a)); - } - - cab->cab_offset = 0; - /* - * Read CFHEADER. - */ - hd = &cab->cfheader; - if (p[CFHEADER_signature+0] != 'M' || p[CFHEADER_signature+1] != 'S' || - p[CFHEADER_signature+2] != 'C' || p[CFHEADER_signature+3] != 'F') { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Couldn't find out CAB header"); - return (ARCHIVE_FATAL); - } - hd->total_bytes = archive_le32dec(p + CFHEADER_cbCabinet); - hd->files_offset = archive_le32dec(p + CFHEADER_coffFiles); - hd->minor = p[CFHEADER_versionMinor]; - hd->major = p[CFHEADER_versionMajor]; - hd->folder_count = archive_le16dec(p + CFHEADER_cFolders); - if (hd->folder_count == 0) - goto invalid; - hd->file_count = archive_le16dec(p + CFHEADER_cFiles); - if (hd->file_count == 0) - goto invalid; - hd->flags = archive_le16dec(p + CFHEADER_flags); - hd->setid = archive_le16dec(p + CFHEADER_setID); - hd->cabinet = archive_le16dec(p + CFHEADER_iCabinet); - used = CFHEADER_iCabinet + 2; - if (hd->flags & RESERVE_PRESENT) { - uint16_t cfheader; - cfheader = archive_le16dec(p + CFHEADER_cbCFHeader); - if (cfheader > 60000U) - goto invalid; - hd->cffolder = p[CFHEADER_cbCFFolder]; - hd->cfdata = p[CFHEADER_cbCFData]; - used += 4;/* cbCFHeader, cbCFFolder and cbCFData */ - used += cfheader;/* abReserve */ - } else - hd->cffolder = 0;/* Avoid compiling warning. */ - if (hd->flags & PREV_CABINET) { - /* How many bytes are used for szCabinetPrev. */ - if ((p = __archive_read_ahead(a, used+256, NULL)) == NULL) - return (truncated_error(a)); - if ((len = cab_strnlen(p + used, 255)) <= 0) - goto invalid; - used += len + 1; - /* How many bytes are used for szDiskPrev. */ - if ((p = __archive_read_ahead(a, used+256, NULL)) == NULL) - return (truncated_error(a)); - if ((len = cab_strnlen(p + used, 255)) <= 0) - goto invalid; - used += len + 1; - } - if (hd->flags & NEXT_CABINET) { - /* How many bytes are used for szCabinetNext. */ - if ((p = __archive_read_ahead(a, used+256, NULL)) == NULL) - return (truncated_error(a)); - if ((len = cab_strnlen(p + used, 255)) <= 0) - goto invalid; - used += len + 1; - /* How many bytes are used for szDiskNext. */ - if ((p = __archive_read_ahead(a, used+256, NULL)) == NULL) - return (truncated_error(a)); - if ((len = cab_strnlen(p + used, 255)) <= 0) - goto invalid; - used += len + 1; - } - __archive_read_consume(a, used); - cab->cab_offset += used; - used = 0; - - /* - * Read CFFOLDER. - */ - hd->folder_array = (struct cffolder *)calloc( - hd->folder_count, sizeof(struct cffolder)); - if (hd->folder_array == NULL) - goto nomem; - - bytes = 8; - if (hd->flags & RESERVE_PRESENT) - bytes += hd->cffolder; - bytes *= hd->folder_count; - if ((p = __archive_read_ahead(a, bytes, NULL)) == NULL) - return (truncated_error(a)); - offset32 = 0; - for (i = 0; i < hd->folder_count; i++) { - struct cffolder *folder = &(hd->folder_array[i]); - folder->cfdata_offset_in_cab = - archive_le32dec(p + CFFOLDER_coffCabStart); - folder->cfdata_count = archive_le16dec(p+CFFOLDER_cCFData); - folder->comptype = - archive_le16dec(p+CFFOLDER_typeCompress) & 0x0F; - folder->compdata = - archive_le16dec(p+CFFOLDER_typeCompress) >> 8; - /* Get a compression name. */ - if (folder->comptype < - sizeof(compression_name) / sizeof(compression_name[0])) - folder->compname = compression_name[folder->comptype]; - else - folder->compname = "UNKNOWN"; - p += 8; - used += 8; - if (hd->flags & RESERVE_PRESENT) { - p += hd->cffolder;/* abReserve */ - used += hd->cffolder; - } - /* - * Sanity check if each data is acceptable. - */ - if (offset32 >= folder->cfdata_offset_in_cab) - goto invalid; - offset32 = folder->cfdata_offset_in_cab; - - /* Set a request to initialize zlib for the CFDATA of - * this folder. */ - folder->decompress_init = 0; - } - __archive_read_consume(a, used); - cab->cab_offset += used; - - /* - * Read CFFILE. - */ - /* Seek read pointer to the offset of CFFILE if needed. */ - skip = (int64_t)hd->files_offset - cab->cab_offset; - if (skip < 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Invalid offset of CFFILE %jd < %jd", - (intmax_t)hd->files_offset, (intmax_t)cab->cab_offset); - return (ARCHIVE_FATAL); - } - if (skip) { - __archive_read_consume(a, skip); - cab->cab_offset += skip; - } - /* Allocate memory for CFDATA */ - hd->file_array = (struct cffile *)calloc( - hd->file_count, sizeof(struct cffile)); - if (hd->file_array == NULL) - goto nomem; - - prev_folder = -1; - for (i = 0; i < hd->file_count; i++) { - struct cffile *file = &(hd->file_array[i]); - ssize_t avail; - - if ((p = __archive_read_ahead(a, 16, NULL)) == NULL) - return (truncated_error(a)); - file->uncompressed_size = archive_le32dec(p + CFFILE_cbFile); - file->offset = archive_le32dec(p + CFFILE_uoffFolderStart); - file->folder = archive_le16dec(p + CFFILE_iFolder); - file->mtime = cab_dos_time(p + CFFILE_date_time); - file->attr = (uint8_t)archive_le16dec(p + CFFILE_attribs); - __archive_read_consume(a, 16); - - cab->cab_offset += 16; - if ((p = cab_read_ahead_remaining(a, 256, &avail)) == NULL) - return (truncated_error(a)); - if ((len = cab_strnlen(p, avail-1)) <= 0) - goto invalid; - - /* Copy a pathname. */ - archive_string_init(&(file->pathname)); - archive_strncpy(&(file->pathname), p, len); - __archive_read_consume(a, len + 1); - cab->cab_offset += len + 1; - - /* - * Sanity check if each data is acceptable. - */ - if (file->uncompressed_size > 0x7FFF8000) - goto invalid;/* Too large */ - if ((int64_t)file->offset + (int64_t)file->uncompressed_size - > ARCHIVE_LITERAL_LL(0x7FFF8000)) - goto invalid;/* Too large */ - switch (file->folder) { - case iFoldCONTINUED_TO_NEXT: - /* This must be last file in a folder. */ - if (i != hd->file_count -1) - goto invalid; - cur_folder = hd->folder_count -1; - break; - case iFoldCONTINUED_PREV_AND_NEXT: - /* This must be only one file in a folder. */ - if (hd->file_count != 1) - goto invalid; - /* FALL THROUGH */ - case iFoldCONTINUED_FROM_PREV: - /* This must be first file in a folder. */ - if (i != 0) - goto invalid; - prev_folder = cur_folder = 0; - offset32 = file->offset; - break; - default: - if (file->folder >= hd->folder_count) - goto invalid; - cur_folder = file->folder; - break; - } - /* Dot not back track. */ - if (cur_folder < prev_folder) - goto invalid; - if (cur_folder != prev_folder) - offset32 = 0; - prev_folder = cur_folder; - - /* Make sure there are not any blanks from last file - * contents. */ - if (offset32 != file->offset) - goto invalid; - offset32 += file->uncompressed_size; - - /* CFDATA is available for file contents. */ - if (file->uncompressed_size > 0 && - hd->folder_array[cur_folder].cfdata_count == 0) - goto invalid; - } - - if (hd->cabinet != 0 || hd->flags & (PREV_CABINET | NEXT_CABINET)) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Multivolume cabinet file is unsupported"); - return (ARCHIVE_WARN); - } - return (ARCHIVE_OK); -invalid: - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid CAB header"); - return (ARCHIVE_FATAL); -nomem: - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for CAB data"); - return (ARCHIVE_FATAL); -} - -static int -archive_read_format_cab_read_header(struct archive_read *a, - struct archive_entry *entry) -{ - struct cab *cab; - struct cfheader *hd; - struct cffolder *prev_folder; - struct cffile *file; - struct archive_string_conv *sconv; - int err = ARCHIVE_OK, r; - - cab = (struct cab *)(a->format->data); - if (cab->found_header == 0) { - err = cab_read_header(a); - if (err < ARCHIVE_WARN) - return (err); - /* We've found the header. */ - cab->found_header = 1; - } - hd = &cab->cfheader; - - if (hd->file_index >= hd->file_count) { - cab->end_of_archive = 1; - return (ARCHIVE_EOF); - } - file = &hd->file_array[hd->file_index++]; - - cab->end_of_entry = 0; - cab->end_of_entry_cleanup = 0; - cab->entry_compressed_bytes_read = 0; - cab->entry_uncompressed_bytes_read = 0; - cab->entry_unconsumed = 0; - cab->entry_cffile = file; - - /* - * Choose a proper folder. - */ - prev_folder = cab->entry_cffolder; - switch (file->folder) { - case iFoldCONTINUED_FROM_PREV: - case iFoldCONTINUED_PREV_AND_NEXT: - cab->entry_cffolder = &hd->folder_array[0]; - break; - case iFoldCONTINUED_TO_NEXT: - cab->entry_cffolder = &hd->folder_array[hd->folder_count-1]; - break; - default: - cab->entry_cffolder = &hd->folder_array[file->folder]; - break; - } - /* If a cffolder of this file is changed, reset a cfdata to read - * file contents from next cfdata. */ - if (prev_folder != cab->entry_cffolder) - cab->entry_cfdata = NULL; - - /* If a pathname is UTF-8, prepare a string conversion object - * for UTF-8 and use it. */ - if (file->attr & ATTR_NAME_IS_UTF) { - if (cab->sconv_utf8 == NULL) { - cab->sconv_utf8 = - archive_string_conversion_from_charset( - &(a->archive), "UTF-8", 1); - if (cab->sconv_utf8 == NULL) - return (ARCHIVE_FATAL); - } - sconv = cab->sconv_utf8; - } else if (cab->sconv != NULL) { - /* Choose the conversion specified by the option. */ - sconv = cab->sconv; - } else { - /* Choose the default conversion. */ - if (!cab->init_default_conversion) { - cab->sconv_default = - archive_string_default_conversion_for_read( - &(a->archive)); - cab->init_default_conversion = 1; - } - sconv = cab->sconv_default; - } - - /* - * Set a default value and common data - */ - r = cab_convert_path_separator_1(&(file->pathname), file->attr); - if (archive_entry_copy_pathname_l(entry, file->pathname.s, - archive_strlen(&(file->pathname)), sconv) != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Pathname"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Pathname cannot be converted " - "from %s to current locale.", - archive_string_conversion_charset_name(sconv)); - err = ARCHIVE_WARN; - } - if (r < 0) { - /* Convert a path separator '\' -> '/' */ - cab_convert_path_separator_2(cab, entry); - } - - archive_entry_set_size(entry, file->uncompressed_size); - if (file->attr & ATTR_RDONLY) - archive_entry_set_mode(entry, AE_IFREG | 0555); - else - archive_entry_set_mode(entry, AE_IFREG | 0666); - archive_entry_set_mtime(entry, file->mtime, 0); - - cab->entry_bytes_remaining = file->uncompressed_size; - cab->entry_offset = 0; - /* We don't need compress data. */ - if (file->uncompressed_size == 0) - cab->end_of_entry_cleanup = cab->end_of_entry = 1; - - /* Set up a more descriptive format name. */ - snprintf(cab->format_name, sizeof(cab->format_name), "CAB %d.%d (%s)", - hd->major, hd->minor, cab->entry_cffolder->compname); - a->archive.archive_format_name = cab->format_name; - - return (err); -} - -static int -archive_read_format_cab_read_data(struct archive_read *a, - const void **buff, size_t *size, int64_t *offset) -{ - struct cab *cab = (struct cab *)(a->format->data); - int r; - - switch (cab->entry_cffile->folder) { - case iFoldCONTINUED_FROM_PREV: - case iFoldCONTINUED_TO_NEXT: - case iFoldCONTINUED_PREV_AND_NEXT: - *buff = NULL; - *size = 0; - *offset = 0; - archive_clear_error(&a->archive); - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Cannot restore this file split in multivolume."); - return (ARCHIVE_FAILED); - default: - break; - } - if (cab->read_data_invoked == 0) { - if (cab->bytes_skipped) { - if (cab->entry_cfdata == NULL) { - r = cab_next_cfdata(a); - if (r < 0) - return (r); - } - if (cab_consume_cfdata(a, cab->bytes_skipped) < 0) - return (ARCHIVE_FATAL); - cab->bytes_skipped = 0; - } - cab->read_data_invoked = 1; - } - if (cab->entry_unconsumed) { - /* Consume as much as the compressor actually used. */ - r = (int)cab_consume_cfdata(a, cab->entry_unconsumed); - cab->entry_unconsumed = 0; - if (r < 0) - return (r); - } - if (cab->end_of_archive || cab->end_of_entry) { - if (!cab->end_of_entry_cleanup) { - /* End-of-entry cleanup done. */ - cab->end_of_entry_cleanup = 1; - } - *offset = cab->entry_offset; - *size = 0; - *buff = NULL; - return (ARCHIVE_EOF); - } - - return (cab_read_data(a, buff, size, offset)); -} - -static uint32_t -cab_checksum_cfdata_4(const void *p, size_t bytes, uint32_t seed) -{ - const unsigned char *b; - unsigned u32num; - uint32_t sum; - - u32num = (unsigned)bytes / 4; - sum = seed; - b = p; - for (;u32num > 0; --u32num) { - sum ^= archive_le32dec(b); - b += 4; - } - return (sum); -} - -static uint32_t -cab_checksum_cfdata(const void *p, size_t bytes, uint32_t seed) -{ - const unsigned char *b; - uint32_t sum; - uint32_t t; - - sum = cab_checksum_cfdata_4(p, bytes, seed); - b = p; - b += bytes & ~3; - t = 0; - switch (bytes & 3) { - case 3: - t |= ((uint32_t)(*b++)) << 16; - /* FALL THROUGH */ - case 2: - t |= ((uint32_t)(*b++)) << 8; - /* FALL THROUGH */ - case 1: - t |= *b; - /* FALL THROUGH */ - default: - break; - } - sum ^= t; - - return (sum); -} - -static void -cab_checksum_update(struct archive_read *a, size_t bytes) -{ - struct cab *cab = (struct cab *)(a->format->data); - struct cfdata *cfdata = cab->entry_cfdata; - const unsigned char *p; - size_t sumbytes; - - if (cfdata->sum == 0 || cfdata->sum_ptr == NULL) - return; - /* - * Calculate the sum of this CFDATA. - * Make sure CFDATA must be calculated in four bytes. - */ - p = cfdata->sum_ptr; - sumbytes = bytes; - if (cfdata->sum_extra_avail) { - while (cfdata->sum_extra_avail < 4 && sumbytes > 0) { - cfdata->sum_extra[ - cfdata->sum_extra_avail++] = *p++; - sumbytes--; - } - if (cfdata->sum_extra_avail == 4) { - cfdata->sum_calculated = cab_checksum_cfdata_4( - cfdata->sum_extra, 4, cfdata->sum_calculated); - cfdata->sum_extra_avail = 0; - } - } - if (sumbytes) { - int odd = sumbytes & 3; - if ((int)(sumbytes - odd) > 0) - cfdata->sum_calculated = cab_checksum_cfdata_4( - p, sumbytes - odd, cfdata->sum_calculated); - if (odd) - memcpy(cfdata->sum_extra, p + sumbytes - odd, odd); - cfdata->sum_extra_avail = odd; - } - cfdata->sum_ptr = NULL; -} - -static int -cab_checksum_finish(struct archive_read *a) -{ - struct cab *cab = (struct cab *)(a->format->data); - struct cfdata *cfdata = cab->entry_cfdata; - int l; - - /* Do not need to compute a sum. */ - if (cfdata->sum == 0) - return (ARCHIVE_OK); - - /* - * Calculate the sum of remaining CFDATA. - */ - if (cfdata->sum_extra_avail) { - cfdata->sum_calculated = - cab_checksum_cfdata(cfdata->sum_extra, - cfdata->sum_extra_avail, cfdata->sum_calculated); - cfdata->sum_extra_avail = 0; - } - - l = 4; - if (cab->cfheader.flags & RESERVE_PRESENT) - l += cab->cfheader.cfdata; - cfdata->sum_calculated = cab_checksum_cfdata( - cfdata->memimage + CFDATA_cbData, l, cfdata->sum_calculated); - if (cfdata->sum_calculated != cfdata->sum) { -#ifndef DONT_FAIL_ON_CRC_ERROR - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Checksum error CFDATA[%d] %" PRIx32 ":%" PRIx32 " in %d bytes", - cab->entry_cffolder->cfdata_index -1, - cfdata->sum, cfdata->sum_calculated, - cfdata->compressed_size); - return (ARCHIVE_FAILED); -#endif - } - return (ARCHIVE_OK); -} - -/* - * Read CFDATA if needed. - */ -static int -cab_next_cfdata(struct archive_read *a) -{ - struct cab *cab = (struct cab *)(a->format->data); - struct cfdata *cfdata = cab->entry_cfdata; - - /* There are remaining bytes in current CFDATA, use it first. */ - if (cfdata != NULL && cfdata->uncompressed_bytes_remaining > 0) - return (ARCHIVE_OK); - - if (cfdata == NULL) { - int64_t skip; - - cab->entry_cffolder->cfdata_index = 0; - - /* Seek read pointer to the offset of CFDATA if needed. */ - skip = cab->entry_cffolder->cfdata_offset_in_cab - - cab->cab_offset; - if (skip < 0) { - int folder_index; - switch (cab->entry_cffile->folder) { - case iFoldCONTINUED_FROM_PREV: - case iFoldCONTINUED_PREV_AND_NEXT: - folder_index = 0; - break; - case iFoldCONTINUED_TO_NEXT: - folder_index = cab->cfheader.folder_count-1; - break; - default: - folder_index = cab->entry_cffile->folder; - break; - } - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Invalid offset of CFDATA in folder(%d) %jd < %jd", - folder_index, - (intmax_t)cab->entry_cffolder->cfdata_offset_in_cab, - (intmax_t)cab->cab_offset); - return (ARCHIVE_FATAL); - } - if (skip > 0) { - if (__archive_read_consume(a, skip) < 0) - return (ARCHIVE_FATAL); - cab->cab_offset = - cab->entry_cffolder->cfdata_offset_in_cab; - } - } - - /* - * Read a CFDATA. - */ - if (cab->entry_cffolder->cfdata_index < - cab->entry_cffolder->cfdata_count) { - const unsigned char *p; - int l; - - cfdata = &(cab->entry_cffolder->cfdata); - cab->entry_cffolder->cfdata_index++; - cab->entry_cfdata = cfdata; - cfdata->sum_calculated = 0; - cfdata->sum_extra_avail = 0; - cfdata->sum_ptr = NULL; - l = 8; - if (cab->cfheader.flags & RESERVE_PRESENT) - l += cab->cfheader.cfdata; - if ((p = __archive_read_ahead(a, l, NULL)) == NULL) - return (truncated_error(a)); - cfdata->sum = archive_le32dec(p + CFDATA_csum); - cfdata->compressed_size = archive_le16dec(p + CFDATA_cbData); - cfdata->compressed_bytes_remaining = cfdata->compressed_size; - cfdata->uncompressed_size = - archive_le16dec(p + CFDATA_cbUncomp); - cfdata->uncompressed_bytes_remaining = - cfdata->uncompressed_size; - cfdata->uncompressed_avail = 0; - cfdata->read_offset = 0; - cfdata->unconsumed = 0; - - /* - * Sanity check if data size is acceptable. - */ - if (cfdata->compressed_size == 0 || - cfdata->compressed_size > (0x8000+6144)) - goto invalid; - if (cfdata->uncompressed_size > 0x8000) - goto invalid; - if (cfdata->uncompressed_size == 0) { - switch (cab->entry_cffile->folder) { - case iFoldCONTINUED_PREV_AND_NEXT: - case iFoldCONTINUED_TO_NEXT: - break; - case iFoldCONTINUED_FROM_PREV: - default: - goto invalid; - } - } - /* If CFDATA is not last in a folder, an uncompressed - * size must be 0x8000(32KBi) */ - if ((cab->entry_cffolder->cfdata_index < - cab->entry_cffolder->cfdata_count) && - cfdata->uncompressed_size != 0x8000) - goto invalid; - - /* A compressed data size and an uncompressed data size must - * be the same in no compression mode. */ - if (cab->entry_cffolder->comptype == COMPTYPE_NONE && - cfdata->compressed_size != cfdata->uncompressed_size) - goto invalid; - - /* - * Save CFDATA image for sum check. - */ - if (cfdata->memimage_size < (size_t)l) { - free(cfdata->memimage); - cfdata->memimage = malloc(l); - if (cfdata->memimage == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for CAB data"); - return (ARCHIVE_FATAL); - } - cfdata->memimage_size = l; - } - memcpy(cfdata->memimage, p, l); - - /* Consume bytes as much as we used. */ - __archive_read_consume(a, l); - cab->cab_offset += l; - } else if (cab->entry_cffolder->cfdata_count > 0) { - /* Run out of all CFDATA in a folder. */ - cfdata->compressed_size = 0; - cfdata->uncompressed_size = 0; - cfdata->compressed_bytes_remaining = 0; - cfdata->uncompressed_bytes_remaining = 0; - } else { - /* Current folder does not have any CFDATA. */ - cfdata = &(cab->entry_cffolder->cfdata); - cab->entry_cfdata = cfdata; - memset(cfdata, 0, sizeof(*cfdata)); - } - return (ARCHIVE_OK); -invalid: - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid CFDATA"); - return (ARCHIVE_FATAL); -} - -/* - * Read ahead CFDATA. - */ -static const void * -cab_read_ahead_cfdata(struct archive_read *a, ssize_t *avail) -{ - struct cab *cab = (struct cab *)(a->format->data); - int err; - - err = cab_next_cfdata(a); - if (err < ARCHIVE_OK) { - *avail = err; - return (NULL); - } - - switch (cab->entry_cffolder->comptype) { - case COMPTYPE_NONE: - return (cab_read_ahead_cfdata_none(a, avail)); - case COMPTYPE_MSZIP: - return (cab_read_ahead_cfdata_deflate(a, avail)); - case COMPTYPE_LZX: - return (cab_read_ahead_cfdata_lzx(a, avail)); - default: /* Unsupported compression. */ - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Unsupported CAB compression : %s", - cab->entry_cffolder->compname); - *avail = ARCHIVE_FAILED; - return (NULL); - } -} - -/* - * Read ahead CFDATA as uncompressed data. - */ -static const void * -cab_read_ahead_cfdata_none(struct archive_read *a, ssize_t *avail) -{ - struct cab *cab = (struct cab *)(a->format->data); - struct cfdata *cfdata; - const void *d; - - cfdata = cab->entry_cfdata; - - /* - * Note: '1' here is a performance optimization. - * Recall that the decompression layer returns a count of - * available bytes; asking for more than that forces the - * decompressor to combine reads by copying data. - */ - d = __archive_read_ahead(a, 1, avail); - if (*avail <= 0) { - *avail = truncated_error(a); - return (NULL); - } - if (*avail > cfdata->uncompressed_bytes_remaining) - *avail = cfdata->uncompressed_bytes_remaining; - cfdata->uncompressed_avail = cfdata->uncompressed_size; - cfdata->unconsumed = *avail; - cfdata->sum_ptr = d; - return (d); -} - -/* - * Read ahead CFDATA as deflate data. - */ -#ifdef HAVE_ZLIB_H -static const void * -cab_read_ahead_cfdata_deflate(struct archive_read *a, ssize_t *avail) -{ - struct cab *cab = (struct cab *)(a->format->data); - struct cfdata *cfdata; - const void *d; - int r, mszip; - uint16_t uavail; - char eod = 0; - - cfdata = cab->entry_cfdata; - /* If the buffer hasn't been allocated, allocate it now. */ - if (cab->uncompressed_buffer == NULL) { - cab->uncompressed_buffer_size = 0x8000; - cab->uncompressed_buffer - = (unsigned char *)malloc(cab->uncompressed_buffer_size); - if (cab->uncompressed_buffer == NULL) { - archive_set_error(&a->archive, ENOMEM, - "No memory for CAB reader"); - *avail = ARCHIVE_FATAL; - return (NULL); - } - } - - uavail = cfdata->uncompressed_avail; - if (uavail == cfdata->uncompressed_size) { - d = cab->uncompressed_buffer + cfdata->read_offset; - *avail = uavail - cfdata->read_offset; - return (d); - } - - if (!cab->entry_cffolder->decompress_init) { - cab->stream.next_in = NULL; - cab->stream.avail_in = 0; - cab->stream.total_in = 0; - cab->stream.next_out = NULL; - cab->stream.avail_out = 0; - cab->stream.total_out = 0; - if (cab->stream_valid) - r = inflateReset(&cab->stream); - else - r = inflateInit2(&cab->stream, - -15 /* Don't check for zlib header */); - if (r != Z_OK) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Can't initialize deflate decompression."); - *avail = ARCHIVE_FATAL; - return (NULL); - } - /* Stream structure has been set up. */ - cab->stream_valid = 1; - /* We've initialized decompression for this stream. */ - cab->entry_cffolder->decompress_init = 1; - } - - if (cfdata->compressed_bytes_remaining == cfdata->compressed_size) - mszip = 2; - else - mszip = 0; - eod = 0; - cab->stream.total_out = uavail; - /* - * We always uncompress all data in current CFDATA. - */ - while (!eod && cab->stream.total_out < cfdata->uncompressed_size) { - ssize_t bytes_avail; - - cab->stream.next_out = - cab->uncompressed_buffer + cab->stream.total_out; - cab->stream.avail_out = - cfdata->uncompressed_size - cab->stream.total_out; - - d = __archive_read_ahead(a, 1, &bytes_avail); - if (bytes_avail <= 0) { - *avail = truncated_error(a); - return (NULL); - } - if (bytes_avail > cfdata->compressed_bytes_remaining) - bytes_avail = cfdata->compressed_bytes_remaining; - /* - * A bug in zlib.h: stream.next_in should be marked 'const' - * but isn't (the library never alters data through the - * next_in pointer, only reads it). The result: this ugly - * cast to remove 'const'. - */ - cab->stream.next_in = (Bytef *)(uintptr_t)d; - cab->stream.avail_in = (uInt)bytes_avail; - cab->stream.total_in = 0; - - /* Cut out a tow-byte MSZIP signature(0x43, 0x4b). */ - if (mszip > 0) { - if (bytes_avail <= 0) - goto nomszip; - if (bytes_avail <= mszip) { - if (mszip == 2) { - if (cab->stream.next_in[0] != 0x43) - goto nomszip; - if (bytes_avail > 1 && - cab->stream.next_in[1] != 0x4b) - goto nomszip; - } else if (cab->stream.next_in[0] != 0x4b) - goto nomszip; - cfdata->unconsumed = bytes_avail; - cfdata->sum_ptr = d; - if (cab_minimum_consume_cfdata( - a, cfdata->unconsumed) < 0) { - *avail = ARCHIVE_FATAL; - return (NULL); - } - mszip -= (int)bytes_avail; - continue; - } - if (mszip == 1 && cab->stream.next_in[0] != 0x4b) - goto nomszip; - else if (mszip == 2 && (cab->stream.next_in[0] != 0x43 || - cab->stream.next_in[1] != 0x4b)) - goto nomszip; - cab->stream.next_in += mszip; - cab->stream.avail_in -= mszip; - cab->stream.total_in += mszip; - mszip = 0; - } - - r = inflate(&cab->stream, 0); - switch (r) { - case Z_OK: - break; - case Z_STREAM_END: - eod = 1; - break; - default: - goto zlibfailed; - } - cfdata->unconsumed = cab->stream.total_in; - cfdata->sum_ptr = d; - if (cab_minimum_consume_cfdata(a, cfdata->unconsumed) < 0) { - *avail = ARCHIVE_FATAL; - return (NULL); - } - } - uavail = (uint16_t)cab->stream.total_out; - - if (uavail < cfdata->uncompressed_size) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Invalid uncompressed size (%d < %d)", - uavail, cfdata->uncompressed_size); - *avail = ARCHIVE_FATAL; - return (NULL); - } - - /* - * Note: I suspect there is a bug in makecab.exe because, in rare - * case, compressed bytes are still remaining regardless we have - * gotten all uncompressed bytes, which size is recorded in CFDATA, - * as much as we need, and we have to use the garbage so as to - * correctly compute the sum of CFDATA accordingly. - */ - if (cfdata->compressed_bytes_remaining > 0) { - ssize_t bytes_avail; - - d = __archive_read_ahead(a, cfdata->compressed_bytes_remaining, - &bytes_avail); - if (bytes_avail <= 0) { - *avail = truncated_error(a); - return (NULL); - } - cfdata->unconsumed = cfdata->compressed_bytes_remaining; - cfdata->sum_ptr = d; - if (cab_minimum_consume_cfdata(a, cfdata->unconsumed) < 0) { - *avail = ARCHIVE_FATAL; - return (NULL); - } - } - - /* - * Set dictionary data for decompressing of next CFDATA, which - * in the same folder. This is why we always do decompress CFDATA - * even if beginning CFDATA or some of CFDATA are not used in - * skipping file data. - */ - if (cab->entry_cffolder->cfdata_index < - cab->entry_cffolder->cfdata_count) { - r = inflateReset(&cab->stream); - if (r != Z_OK) - goto zlibfailed; - r = inflateSetDictionary(&cab->stream, - cab->uncompressed_buffer, cfdata->uncompressed_size); - if (r != Z_OK) - goto zlibfailed; - } - - d = cab->uncompressed_buffer + cfdata->read_offset; - *avail = uavail - cfdata->read_offset; - cfdata->uncompressed_avail = uavail; - - return (d); - -zlibfailed: - switch (r) { - case Z_MEM_ERROR: - archive_set_error(&a->archive, ENOMEM, - "Out of memory for deflate decompression"); - break; - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Deflate decompression failed (%d)", r); - break; - } - *avail = ARCHIVE_FATAL; - return (NULL); -nomszip: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "CFDATA incorrect(no MSZIP signature)"); - *avail = ARCHIVE_FATAL; - return (NULL); -} - -#else /* HAVE_ZLIB_H */ - -static const void * -cab_read_ahead_cfdata_deflate(struct archive_read *a, ssize_t *avail) -{ - *avail = ARCHIVE_FATAL; - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "libarchive compiled without deflate support (no libz)"); - return (NULL); -} - -#endif /* HAVE_ZLIB_H */ - -static const void * -cab_read_ahead_cfdata_lzx(struct archive_read *a, ssize_t *avail) -{ - struct cab *cab = (struct cab *)(a->format->data); - struct cfdata *cfdata; - const void *d; - int r; - uint16_t uavail; - - cfdata = cab->entry_cfdata; - /* If the buffer hasn't been allocated, allocate it now. */ - if (cab->uncompressed_buffer == NULL) { - cab->uncompressed_buffer_size = 0x8000; - cab->uncompressed_buffer - = (unsigned char *)malloc(cab->uncompressed_buffer_size); - if (cab->uncompressed_buffer == NULL) { - archive_set_error(&a->archive, ENOMEM, - "No memory for CAB reader"); - *avail = ARCHIVE_FATAL; - return (NULL); - } - } - - uavail = cfdata->uncompressed_avail; - if (uavail == cfdata->uncompressed_size) { - d = cab->uncompressed_buffer + cfdata->read_offset; - *avail = uavail - cfdata->read_offset; - return (d); - } - - if (!cab->entry_cffolder->decompress_init) { - r = lzx_decode_init(&cab->xstrm, - cab->entry_cffolder->compdata); - if (r != ARCHIVE_OK) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Can't initialize LZX decompression."); - *avail = ARCHIVE_FATAL; - return (NULL); - } - /* We've initialized decompression for this stream. */ - cab->entry_cffolder->decompress_init = 1; - } - - /* Clean up remaining bits of previous CFDATA. */ - lzx_cleanup_bitstream(&cab->xstrm); - cab->xstrm.total_out = uavail; - while (cab->xstrm.total_out < cfdata->uncompressed_size) { - ssize_t bytes_avail; - - cab->xstrm.next_out = - cab->uncompressed_buffer + cab->xstrm.total_out; - cab->xstrm.avail_out = - cfdata->uncompressed_size - cab->xstrm.total_out; - - d = __archive_read_ahead(a, 1, &bytes_avail); - if (bytes_avail <= 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated CAB file data"); - *avail = ARCHIVE_FATAL; - return (NULL); - } - if (bytes_avail > cfdata->compressed_bytes_remaining) - bytes_avail = cfdata->compressed_bytes_remaining; - - cab->xstrm.next_in = d; - cab->xstrm.avail_in = bytes_avail; - cab->xstrm.total_in = 0; - r = lzx_decode(&cab->xstrm, - cfdata->compressed_bytes_remaining == bytes_avail); - switch (r) { - case ARCHIVE_OK: - case ARCHIVE_EOF: - break; - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "LZX decompression failed (%d)", r); - *avail = ARCHIVE_FATAL; - return (NULL); - } - cfdata->unconsumed = cab->xstrm.total_in; - cfdata->sum_ptr = d; - if (cab_minimum_consume_cfdata(a, cfdata->unconsumed) < 0) { - *avail = ARCHIVE_FATAL; - return (NULL); - } - } - - uavail = (uint16_t)cab->xstrm.total_out; - /* - * Make sure a read pointer advances to next CFDATA. - */ - if (cfdata->compressed_bytes_remaining > 0) { - ssize_t bytes_avail; - - d = __archive_read_ahead(a, cfdata->compressed_bytes_remaining, - &bytes_avail); - if (bytes_avail <= 0) { - *avail = truncated_error(a); - return (NULL); - } - cfdata->unconsumed = cfdata->compressed_bytes_remaining; - cfdata->sum_ptr = d; - if (cab_minimum_consume_cfdata(a, cfdata->unconsumed) < 0) { - *avail = ARCHIVE_FATAL; - return (NULL); - } - } - - /* - * Translation reversal of x86 processor CALL byte sequence(E8). - */ - lzx_translation(&cab->xstrm, cab->uncompressed_buffer, - cfdata->uncompressed_size, - (cab->entry_cffolder->cfdata_index-1) * 0x8000); - - d = cab->uncompressed_buffer + cfdata->read_offset; - *avail = uavail - cfdata->read_offset; - cfdata->uncompressed_avail = uavail; - - return (d); -} - -/* - * Consume CFDATA. - * We always decompress CFDATA to consume CFDATA as much as we need - * in uncompressed bytes because all CFDATA in a folder are related - * so we do not skip any CFDATA without decompressing. - * Note: If the folder of a CFFILE is iFoldCONTINUED_PREV_AND_NEXT or - * iFoldCONTINUED_FROM_PREV, we won't decompress because a CFDATA for - * the CFFILE is remaining bytes of previous Multivolume CAB file. - */ -static int64_t -cab_consume_cfdata(struct archive_read *a, int64_t consumed_bytes) -{ - struct cab *cab = (struct cab *)(a->format->data); - struct cfdata *cfdata; - int64_t cbytes, rbytes; - int err; - - rbytes = cab_minimum_consume_cfdata(a, consumed_bytes); - if (rbytes < 0) - return (ARCHIVE_FATAL); - - cfdata = cab->entry_cfdata; - while (rbytes > 0) { - ssize_t avail; - - if (cfdata->compressed_size == 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid CFDATA"); - return (ARCHIVE_FATAL); - } - cbytes = cfdata->uncompressed_bytes_remaining; - if (cbytes > rbytes) - cbytes = rbytes; - rbytes -= cbytes; - - if (cfdata->uncompressed_avail == 0 && - (cab->entry_cffile->folder == iFoldCONTINUED_PREV_AND_NEXT || - cab->entry_cffile->folder == iFoldCONTINUED_FROM_PREV)) { - /* We have not read any data yet. */ - if (cbytes == cfdata->uncompressed_bytes_remaining) { - /* Skip whole current CFDATA. */ - __archive_read_consume(a, - cfdata->compressed_size); - cab->cab_offset += cfdata->compressed_size; - cfdata->compressed_bytes_remaining = 0; - cfdata->uncompressed_bytes_remaining = 0; - err = cab_next_cfdata(a); - if (err < 0) - return (err); - cfdata = cab->entry_cfdata; - if (cfdata->uncompressed_size == 0) { - switch (cab->entry_cffile->folder) { - case iFoldCONTINUED_PREV_AND_NEXT: - case iFoldCONTINUED_TO_NEXT: - case iFoldCONTINUED_FROM_PREV: - rbytes = 0; - break; - default: - break; - } - } - continue; - } - cfdata->read_offset += (uint16_t)cbytes; - cfdata->uncompressed_bytes_remaining -= (uint16_t)cbytes; - break; - } else if (cbytes == 0) { - err = cab_next_cfdata(a); - if (err < 0) - return (err); - cfdata = cab->entry_cfdata; - if (cfdata->uncompressed_size == 0) { - switch (cab->entry_cffile->folder) { - case iFoldCONTINUED_PREV_AND_NEXT: - case iFoldCONTINUED_TO_NEXT: - case iFoldCONTINUED_FROM_PREV: - return (ARCHIVE_FATAL); - default: - break; - } - } - continue; - } - while (cbytes > 0) { - (void)cab_read_ahead_cfdata(a, &avail); - if (avail <= 0) - return (ARCHIVE_FATAL); - if (avail > cbytes) - avail = (ssize_t)cbytes; - if (cab_minimum_consume_cfdata(a, avail) < 0) - return (ARCHIVE_FATAL); - cbytes -= avail; - } - } - return (consumed_bytes); -} - -/* - * Consume CFDATA as much as we have already gotten and - * compute the sum of CFDATA. - */ -static int64_t -cab_minimum_consume_cfdata(struct archive_read *a, int64_t consumed_bytes) -{ - struct cab *cab = (struct cab *)(a->format->data); - struct cfdata *cfdata; - int64_t cbytes, rbytes; - int err; - - cfdata = cab->entry_cfdata; - rbytes = consumed_bytes; - if (cab->entry_cffolder->comptype == COMPTYPE_NONE) { - if (consumed_bytes < cfdata->unconsumed) - cbytes = consumed_bytes; - else - cbytes = cfdata->unconsumed; - rbytes -= cbytes; - cfdata->read_offset += (uint16_t)cbytes; - cfdata->uncompressed_bytes_remaining -= (uint16_t)cbytes; - cfdata->unconsumed -= cbytes; - } else { - cbytes = cfdata->uncompressed_avail - cfdata->read_offset; - if (cbytes > 0) { - if (consumed_bytes < cbytes) - cbytes = consumed_bytes; - rbytes -= cbytes; - cfdata->read_offset += (uint16_t)cbytes; - cfdata->uncompressed_bytes_remaining -= (uint16_t)cbytes; - } - - if (cfdata->unconsumed) { - cbytes = cfdata->unconsumed; - cfdata->unconsumed = 0; - } else - cbytes = 0; - } - if (cbytes) { - /* Compute the sum. */ - cab_checksum_update(a, (size_t)cbytes); - - /* Consume as much as the compressor actually used. */ - __archive_read_consume(a, cbytes); - cab->cab_offset += cbytes; - cfdata->compressed_bytes_remaining -= (uint16_t)cbytes; - if (cfdata->compressed_bytes_remaining == 0) { - err = cab_checksum_finish(a); - if (err < 0) - return (err); - } - } - return (rbytes); -} - -/* - * Returns ARCHIVE_OK if successful, ARCHIVE_FATAL otherwise, sets - * cab->end_of_entry if it consumes all of the data. - */ -static int -cab_read_data(struct archive_read *a, const void **buff, - size_t *size, int64_t *offset) -{ - struct cab *cab = (struct cab *)(a->format->data); - ssize_t bytes_avail; - - if (cab->entry_bytes_remaining == 0) { - *buff = NULL; - *size = 0; - *offset = cab->entry_offset; - cab->end_of_entry = 1; - return (ARCHIVE_OK); - } - - *buff = cab_read_ahead_cfdata(a, &bytes_avail); - if (bytes_avail <= 0) { - *buff = NULL; - *size = 0; - *offset = 0; - if (bytes_avail == 0 && - cab->entry_cfdata->uncompressed_size == 0) { - /* All of CFDATA in a folder has been handled. */ - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, "Invalid CFDATA"); - return (ARCHIVE_FATAL); - } else - return ((int)bytes_avail); - } - if (bytes_avail > cab->entry_bytes_remaining) - bytes_avail = (ssize_t)cab->entry_bytes_remaining; - - *size = bytes_avail; - *offset = cab->entry_offset; - cab->entry_offset += bytes_avail; - cab->entry_bytes_remaining -= bytes_avail; - if (cab->entry_bytes_remaining == 0) - cab->end_of_entry = 1; - cab->entry_unconsumed = bytes_avail; - if (cab->entry_cffolder->comptype == COMPTYPE_NONE) { - /* Don't consume more than current entry used. */ - if (cab->entry_cfdata->unconsumed > cab->entry_unconsumed) - cab->entry_cfdata->unconsumed = cab->entry_unconsumed; - } - return (ARCHIVE_OK); -} - -static int -archive_read_format_cab_read_data_skip(struct archive_read *a) -{ - struct cab *cab; - int64_t bytes_skipped; - int r; - - cab = (struct cab *)(a->format->data); - - if (cab->end_of_archive) - return (ARCHIVE_EOF); - - if (!cab->read_data_invoked) { - cab->bytes_skipped += cab->entry_bytes_remaining; - cab->entry_bytes_remaining = 0; - /* This entry is finished and done. */ - cab->end_of_entry_cleanup = cab->end_of_entry = 1; - return (ARCHIVE_OK); - } - - if (cab->entry_unconsumed) { - /* Consume as much as the compressor actually used. */ - r = (int)cab_consume_cfdata(a, cab->entry_unconsumed); - cab->entry_unconsumed = 0; - if (r < 0) - return (r); - } else if (cab->entry_cfdata == NULL) { - r = cab_next_cfdata(a); - if (r < 0) - return (r); - } - - /* if we've already read to end of data, we're done. */ - if (cab->end_of_entry_cleanup) - return (ARCHIVE_OK); - - /* - * If the length is at the beginning, we can skip the - * compressed data much more quickly. - */ - bytes_skipped = cab_consume_cfdata(a, cab->entry_bytes_remaining); - if (bytes_skipped < 0) - return (ARCHIVE_FATAL); - - /* If the compression type is none(uncompressed), we've already - * consumed data as much as the current entry size. */ - if (cab->entry_cffolder->comptype == COMPTYPE_NONE && - cab->entry_cfdata != NULL) - cab->entry_cfdata->unconsumed = 0; - - /* This entry is finished and done. */ - cab->end_of_entry_cleanup = cab->end_of_entry = 1; - return (ARCHIVE_OK); -} - -static int -archive_read_format_cab_cleanup(struct archive_read *a) -{ - struct cab *cab = (struct cab *)(a->format->data); - struct cfheader *hd = &cab->cfheader; - int i; - - if (hd->folder_array != NULL) { - for (i = 0; i < hd->folder_count; i++) - free(hd->folder_array[i].cfdata.memimage); - free(hd->folder_array); - } - if (hd->file_array != NULL) { - for (i = 0; i < cab->cfheader.file_count; i++) - archive_string_free(&(hd->file_array[i].pathname)); - free(hd->file_array); - } -#ifdef HAVE_ZLIB_H - if (cab->stream_valid) - inflateEnd(&cab->stream); -#endif - lzx_decode_free(&cab->xstrm); - archive_wstring_free(&cab->ws); - free(cab->uncompressed_buffer); - free(cab); - (a->format->data) = NULL; - return (ARCHIVE_OK); -} - -/* Convert an MSDOS-style date/time into Unix-style time. */ -static time_t -cab_dos_time(const unsigned char *p) -{ - int msTime, msDate; - struct tm ts; - - msDate = archive_le16dec(p); - msTime = archive_le16dec(p+2); - - memset(&ts, 0, sizeof(ts)); - ts.tm_year = ((msDate >> 9) & 0x7f) + 80; /* Years since 1900. */ - ts.tm_mon = ((msDate >> 5) & 0x0f) - 1; /* Month number. */ - ts.tm_mday = msDate & 0x1f; /* Day of month. */ - ts.tm_hour = (msTime >> 11) & 0x1f; - ts.tm_min = (msTime >> 5) & 0x3f; - ts.tm_sec = (msTime << 1) & 0x3e; - ts.tm_isdst = -1; - return (mktime(&ts)); -} - -/***************************************************************** - * - * LZX decompression code. - * - *****************************************************************/ - -/* - * Initialize LZX decoder. - * - * Returns ARCHIVE_OK if initialization was successful. - * Returns ARCHIVE_FAILED if w_bits has unsupported value. - * Returns ARCHIVE_FATAL if initialization failed; memory allocation - * error occurred. - */ -static int -lzx_decode_init(struct lzx_stream *strm, int w_bits) -{ - struct lzx_dec *ds; - int slot, w_size, w_slot; - int base, footer; - int base_inc[18]; - - if (strm->ds == NULL) { - strm->ds = calloc(1, sizeof(*strm->ds)); - if (strm->ds == NULL) - return (ARCHIVE_FATAL); - } - ds = strm->ds; - ds->error = ARCHIVE_FAILED; - - /* Allow bits from 15(32KBi) up to 21(2MBi) */ - if (w_bits < SLOT_BASE || w_bits > SLOT_MAX) - return (ARCHIVE_FAILED); - - ds->error = ARCHIVE_FATAL; - - /* - * Alloc window - */ - w_size = ds->w_size; - w_slot = slots[w_bits - SLOT_BASE]; - ds->w_size = 1U << w_bits; - ds->w_mask = ds->w_size -1; - if (ds->w_buff == NULL || w_size != ds->w_size) { - free(ds->w_buff); - ds->w_buff = malloc(ds->w_size); - if (ds->w_buff == NULL) - return (ARCHIVE_FATAL); - free(ds->pos_tbl); - ds->pos_tbl = malloc(sizeof(ds->pos_tbl[0]) * w_slot); - if (ds->pos_tbl == NULL) - return (ARCHIVE_FATAL); - } - - for (footer = 0; footer < 18; footer++) - base_inc[footer] = 1 << footer; - base = footer = 0; - for (slot = 0; slot < w_slot; slot++) { - int n; - if (footer == 0) - base = slot; - else - base += base_inc[footer]; - if (footer < 17) { - footer = -2; - for (n = base; n; n >>= 1) - footer++; - if (footer <= 0) - footer = 0; - } - ds->pos_tbl[slot].base = base; - ds->pos_tbl[slot].footer_bits = footer; - } - - ds->w_pos = 0; - ds->state = 0; - ds->br.cache_buffer = 0; - ds->br.cache_avail = 0; - ds->r0 = ds->r1 = ds->r2 = 1; - - /* Initialize aligned offset tree. */ - if (lzx_huffman_init(&(ds->at), 8, 8) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - /* Initialize pre-tree. */ - if (lzx_huffman_init(&(ds->pt), 20, 10) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - /* Initialize Main tree. */ - if (lzx_huffman_init(&(ds->mt), 256+(w_slot<<3), 16) - != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - /* Initialize Length tree. */ - if (lzx_huffman_init(&(ds->lt), 249, 16) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - ds->error = 0; - - return (ARCHIVE_OK); -} - -/* - * Release LZX decoder. - */ -static void -lzx_decode_free(struct lzx_stream *strm) -{ - - if (strm->ds == NULL) - return; - free(strm->ds->w_buff); - free(strm->ds->pos_tbl); - lzx_huffman_free(&(strm->ds->at)); - lzx_huffman_free(&(strm->ds->pt)); - lzx_huffman_free(&(strm->ds->mt)); - lzx_huffman_free(&(strm->ds->lt)); - free(strm->ds); - strm->ds = NULL; -} - -/* - * E8 Call Translation reversal. - */ -static void -lzx_translation(struct lzx_stream *strm, void *p, size_t size, uint32_t offset) -{ - struct lzx_dec *ds = strm->ds; - unsigned char *b, *end; - - if (!ds->translation || size <= 10) - return; - b = p; - end = b + size - 10; - while (b < end && (b = memchr(b, 0xE8, end - b)) != NULL) { - size_t i = b - (unsigned char *)p; - int32_t cp, displacement, value; - - cp = (int32_t)(offset + (uint32_t)i); - value = archive_le32dec(&b[1]); - if (value >= -cp && value < (int32_t)ds->translation_size) { - if (value >= 0) - displacement = value - cp; - else - displacement = value + ds->translation_size; - archive_le32enc(&b[1], (uint32_t)displacement); - } - b += 5; - } -} - -/* - * Bit stream reader. - */ -/* Check that the cache buffer has enough bits. */ -#define lzx_br_has(br, n) ((br)->cache_avail >= n) -/* Get compressed data by bit. */ -#define lzx_br_bits(br, n) \ - (((uint32_t)((br)->cache_buffer >> \ - ((br)->cache_avail - (n)))) & cache_masks[n]) -#define lzx_br_bits_forced(br, n) \ - (((uint32_t)((br)->cache_buffer << \ - ((n) - (br)->cache_avail))) & cache_masks[n]) -/* Read ahead to make sure the cache buffer has enough compressed data we - * will use. - * True : completed, there is enough data in the cache buffer. - * False : we met that strm->next_in is empty, we have to get following - * bytes. */ -#define lzx_br_read_ahead_0(strm, br, n) \ - (lzx_br_has((br), (n)) || lzx_br_fillup(strm, br)) -/* True : the cache buffer has some bits as much as we need. - * False : there are no enough bits in the cache buffer to be used, - * we have to get following bytes if we could. */ -#define lzx_br_read_ahead(strm, br, n) \ - (lzx_br_read_ahead_0((strm), (br), (n)) || lzx_br_has((br), (n))) - -/* Notify how many bits we consumed. */ -#define lzx_br_consume(br, n) ((br)->cache_avail -= (n)) -#define lzx_br_consume_unaligned_bits(br) ((br)->cache_avail &= ~0x0f) - -#define lzx_br_is_unaligned(br) ((br)->cache_avail & 0x0f) - -static const uint32_t cache_masks[] = { - 0x00000000, 0x00000001, 0x00000003, 0x00000007, - 0x0000000F, 0x0000001F, 0x0000003F, 0x0000007F, - 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF, - 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF, - 0x0000FFFF, 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, - 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF, - 0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, - 0x0FFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF -}; - -/* - * Shift away used bits in the cache data and fill it up with following bits. - * Call this when cache buffer does not have enough bits you need. - * - * Returns 1 if the cache buffer is full. - * Returns 0 if the cache buffer is not full; input buffer is empty. - */ -static int -lzx_br_fillup(struct lzx_stream *strm, struct lzx_br *br) -{ -/* - * x86 processor family can read misaligned data without an access error. - */ - int n = CACHE_BITS - br->cache_avail; - - for (;;) { - switch (n >> 4) { - case 4: - if (strm->avail_in >= 8) { - br->cache_buffer = - ((uint64_t)strm->next_in[1]) << 56 | - ((uint64_t)strm->next_in[0]) << 48 | - ((uint64_t)strm->next_in[3]) << 40 | - ((uint64_t)strm->next_in[2]) << 32 | - ((uint32_t)strm->next_in[5]) << 24 | - ((uint32_t)strm->next_in[4]) << 16 | - ((uint32_t)strm->next_in[7]) << 8 | - (uint32_t)strm->next_in[6]; - strm->next_in += 8; - strm->avail_in -= 8; - br->cache_avail += 8 * 8; - return (1); - } - break; - case 3: - if (strm->avail_in >= 6) { - br->cache_buffer = - (br->cache_buffer << 48) | - ((uint64_t)strm->next_in[1]) << 40 | - ((uint64_t)strm->next_in[0]) << 32 | - ((uint64_t)strm->next_in[3]) << 24 | - ((uint64_t)strm->next_in[2]) << 16 | - ((uint64_t)strm->next_in[5]) << 8 | - (uint64_t)strm->next_in[4]; - strm->next_in += 6; - strm->avail_in -= 6; - br->cache_avail += 6 * 8; - return (1); - } - break; - case 0: - /* We have enough compressed data in - * the cache buffer.*/ - return (1); - default: - break; - } - if (strm->avail_in < 2) { - /* There is not enough compressed data to - * fill up the cache buffer. */ - if (strm->avail_in == 1) { - br->odd = *strm->next_in++; - strm->avail_in--; - br->have_odd = 1; - } - return (0); - } - br->cache_buffer = - (br->cache_buffer << 16) | - archive_le16dec(strm->next_in); - strm->next_in += 2; - strm->avail_in -= 2; - br->cache_avail += 16; - n -= 16; - } -} - -static void -lzx_br_fixup(struct lzx_stream *strm, struct lzx_br *br) -{ - int n = CACHE_BITS - br->cache_avail; - - if (br->have_odd && n >= 16 && strm->avail_in > 0) { - br->cache_buffer = - (br->cache_buffer << 16) | - ((uint16_t)(*strm->next_in)) << 8 | br->odd; - strm->next_in++; - strm->avail_in--; - br->cache_avail += 16; - br->have_odd = 0; - } -} - -static void -lzx_cleanup_bitstream(struct lzx_stream *strm) -{ - strm->ds->br.cache_avail = 0; - strm->ds->br.have_odd = 0; -} - -/* - * Decode LZX. - * - * 1. Returns ARCHIVE_OK if output buffer or input buffer are empty. - * Please set available buffer and call this function again. - * 2. Returns ARCHIVE_EOF if decompression has been completed. - * 3. Returns ARCHIVE_FAILED if an error occurred; compressed data - * is broken or you do not set 'last' flag properly. - */ -#define ST_RD_TRANSLATION 0 -#define ST_RD_TRANSLATION_SIZE 1 -#define ST_RD_BLOCK_TYPE 2 -#define ST_RD_BLOCK_SIZE 3 -#define ST_RD_ALIGNMENT 4 -#define ST_RD_R0 5 -#define ST_RD_R1 6 -#define ST_RD_R2 7 -#define ST_COPY_UNCOMP1 8 -#define ST_COPY_UNCOMP2 9 -#define ST_RD_ALIGNED_OFFSET 10 -#define ST_RD_VERBATIM 11 -#define ST_RD_PRE_MAIN_TREE_256 12 -#define ST_MAIN_TREE_256 13 -#define ST_RD_PRE_MAIN_TREE_REM 14 -#define ST_MAIN_TREE_REM 15 -#define ST_RD_PRE_LENGTH_TREE 16 -#define ST_LENGTH_TREE 17 -#define ST_MAIN 18 -#define ST_LENGTH 19 -#define ST_OFFSET 20 -#define ST_REAL_POS 21 -#define ST_COPY 22 - -static int -lzx_decode(struct lzx_stream *strm, int last) -{ - struct lzx_dec *ds = strm->ds; - int64_t avail_in; - int r; - - if (ds->error) - return (ds->error); - - avail_in = strm->avail_in; - lzx_br_fixup(strm, &(ds->br)); - do { - if (ds->state < ST_MAIN) - r = lzx_read_blocks(strm, last); - else { - int64_t bytes_written = strm->avail_out; - r = lzx_decode_blocks(strm, last); - bytes_written -= strm->avail_out; - strm->next_out += bytes_written; - strm->total_out += bytes_written; - } - } while (r == 100); - strm->total_in += avail_in - strm->avail_in; - return (r); -} - -static int -lzx_read_blocks(struct lzx_stream *strm, int last) -{ - struct lzx_dec *ds = strm->ds; - struct lzx_br *br = &(ds->br); - int i, r; - - for (;;) { - switch (ds->state) { - case ST_RD_TRANSLATION: - if (!lzx_br_read_ahead(strm, br, 1)) { - ds->state = ST_RD_TRANSLATION; - if (last) - goto failed; - return (ARCHIVE_OK); - } - ds->translation = lzx_br_bits(br, 1); - lzx_br_consume(br, 1); - /* FALL THROUGH */ - case ST_RD_TRANSLATION_SIZE: - if (ds->translation) { - if (!lzx_br_read_ahead(strm, br, 32)) { - ds->state = ST_RD_TRANSLATION_SIZE; - if (last) - goto failed; - return (ARCHIVE_OK); - } - ds->translation_size = lzx_br_bits(br, 16); - lzx_br_consume(br, 16); - ds->translation_size <<= 16; - ds->translation_size |= lzx_br_bits(br, 16); - lzx_br_consume(br, 16); - } - /* FALL THROUGH */ - case ST_RD_BLOCK_TYPE: - if (!lzx_br_read_ahead(strm, br, 3)) { - ds->state = ST_RD_BLOCK_TYPE; - if (last) - goto failed; - return (ARCHIVE_OK); - } - ds->block_type = lzx_br_bits(br, 3); - lzx_br_consume(br, 3); - /* Check a block type. */ - switch (ds->block_type) { - case VERBATIM_BLOCK: - case ALIGNED_OFFSET_BLOCK: - case UNCOMPRESSED_BLOCK: - break; - default: - goto failed;/* Invalid */ - } - /* FALL THROUGH */ - case ST_RD_BLOCK_SIZE: - if (!lzx_br_read_ahead(strm, br, 24)) { - ds->state = ST_RD_BLOCK_SIZE; - if (last) - goto failed; - return (ARCHIVE_OK); - } - ds->block_size = lzx_br_bits(br, 8); - lzx_br_consume(br, 8); - ds->block_size <<= 16; - ds->block_size |= lzx_br_bits(br, 16); - lzx_br_consume(br, 16); - if (ds->block_size == 0) - goto failed; - ds->block_bytes_avail = ds->block_size; - if (ds->block_type != UNCOMPRESSED_BLOCK) { - if (ds->block_type == VERBATIM_BLOCK) - ds->state = ST_RD_VERBATIM; - else - ds->state = ST_RD_ALIGNED_OFFSET; - break; - } - /* FALL THROUGH */ - case ST_RD_ALIGNMENT: - /* - * Handle an Uncompressed Block. - */ - /* Skip padding to align following field on - * 16-bit boundary. */ - if (lzx_br_is_unaligned(br)) - lzx_br_consume_unaligned_bits(br); - else { - if (lzx_br_read_ahead(strm, br, 16)) - lzx_br_consume(br, 16); - else { - ds->state = ST_RD_ALIGNMENT; - if (last) - goto failed; - return (ARCHIVE_OK); - } - } - /* Preparation to read repeated offsets R0,R1 and R2. */ - ds->rbytes_avail = 0; - ds->state = ST_RD_R0; - /* FALL THROUGH */ - case ST_RD_R0: - case ST_RD_R1: - case ST_RD_R2: - do { - uint16_t u16; - /* Drain bits in the cache buffer of - * bit-stream. */ - if (lzx_br_has(br, 32)) { - u16 = lzx_br_bits(br, 16); - lzx_br_consume(br, 16); - archive_le16enc(ds->rbytes, u16); - u16 = lzx_br_bits(br, 16); - lzx_br_consume(br, 16); - archive_le16enc(ds->rbytes+2, u16); - ds->rbytes_avail = 4; - } else if (lzx_br_has(br, 16)) { - u16 = lzx_br_bits(br, 16); - lzx_br_consume(br, 16); - archive_le16enc(ds->rbytes, u16); - ds->rbytes_avail = 2; - } - if (ds->rbytes_avail < 4 && ds->br.have_odd) { - ds->rbytes[ds->rbytes_avail++] = - ds->br.odd; - ds->br.have_odd = 0; - } - while (ds->rbytes_avail < 4) { - if (strm->avail_in <= 0) { - if (last) - goto failed; - return (ARCHIVE_OK); - } - ds->rbytes[ds->rbytes_avail++] = - *strm->next_in++; - strm->avail_in--; - } - ds->rbytes_avail = 0; - if (ds->state == ST_RD_R0) { - ds->r0 = archive_le32dec(ds->rbytes); - if (ds->r0 < 0) - goto failed; - ds->state = ST_RD_R1; - } else if (ds->state == ST_RD_R1) { - ds->r1 = archive_le32dec(ds->rbytes); - if (ds->r1 < 0) - goto failed; - ds->state = ST_RD_R2; - } else if (ds->state == ST_RD_R2) { - ds->r2 = archive_le32dec(ds->rbytes); - if (ds->r2 < 0) - goto failed; - /* We've gotten all repeated offsets. */ - ds->state = ST_COPY_UNCOMP1; - } - } while (ds->state != ST_COPY_UNCOMP1); - /* FALL THROUGH */ - case ST_COPY_UNCOMP1: - /* - * Copy bytes form next_in to next_out directly. - */ - while (ds->block_bytes_avail) { - int l; - - if (strm->avail_out <= 0) - /* Output buffer is empty. */ - return (ARCHIVE_OK); - if (strm->avail_in <= 0) { - /* Input buffer is empty. */ - if (last) - goto failed; - return (ARCHIVE_OK); - } - l = (int)ds->block_bytes_avail; - if (l > ds->w_size - ds->w_pos) - l = ds->w_size - ds->w_pos; - if (l > strm->avail_out) - l = (int)strm->avail_out; - if (l > strm->avail_in) - l = (int)strm->avail_in; - memcpy(strm->next_out, strm->next_in, l); - memcpy(&(ds->w_buff[ds->w_pos]), - strm->next_in, l); - strm->next_in += l; - strm->avail_in -= l; - strm->next_out += l; - strm->avail_out -= l; - strm->total_out += l; - ds->w_pos = (ds->w_pos + l) & ds->w_mask; - ds->block_bytes_avail -= l; - } - /* FALL THROUGH */ - case ST_COPY_UNCOMP2: - /* Re-align; skip padding byte. */ - if (ds->block_size & 1) { - if (strm->avail_in <= 0) { - /* Input buffer is empty. */ - ds->state = ST_COPY_UNCOMP2; - if (last) - goto failed; - return (ARCHIVE_OK); - } - strm->next_in++; - strm->avail_in --; - } - /* This block ended. */ - ds->state = ST_RD_BLOCK_TYPE; - return (ARCHIVE_EOF); - /********************/ - case ST_RD_ALIGNED_OFFSET: - /* - * Read Aligned offset tree. - */ - if (!lzx_br_read_ahead(strm, br, 3 * ds->at.len_size)) { - ds->state = ST_RD_ALIGNED_OFFSET; - if (last) - goto failed; - return (ARCHIVE_OK); - } - memset(ds->at.freq, 0, sizeof(ds->at.freq)); - for (i = 0; i < ds->at.len_size; i++) { - ds->at.bitlen[i] = lzx_br_bits(br, 3); - ds->at.freq[ds->at.bitlen[i]]++; - lzx_br_consume(br, 3); - } - if (!lzx_make_huffman_table(&ds->at)) - goto failed; - /* FALL THROUGH */ - case ST_RD_VERBATIM: - ds->loop = 0; - /* FALL THROUGH */ - case ST_RD_PRE_MAIN_TREE_256: - /* - * Read Pre-tree for first 256 elements of main tree. - */ - if (!lzx_read_pre_tree(strm)) { - ds->state = ST_RD_PRE_MAIN_TREE_256; - if (last) - goto failed; - return (ARCHIVE_OK); - } - if (!lzx_make_huffman_table(&ds->pt)) - goto failed; - ds->loop = 0; - /* FALL THROUGH */ - case ST_MAIN_TREE_256: - /* - * Get path lengths of first 256 elements of main tree. - */ - r = lzx_read_bitlen(strm, &ds->mt, 256); - if (r < 0) - goto failed; - else if (!r) { - ds->state = ST_MAIN_TREE_256; - if (last) - goto failed; - return (ARCHIVE_OK); - } - ds->loop = 0; - /* FALL THROUGH */ - case ST_RD_PRE_MAIN_TREE_REM: - /* - * Read Pre-tree for remaining elements of main tree. - */ - if (!lzx_read_pre_tree(strm)) { - ds->state = ST_RD_PRE_MAIN_TREE_REM; - if (last) - goto failed; - return (ARCHIVE_OK); - } - if (!lzx_make_huffman_table(&ds->pt)) - goto failed; - ds->loop = 256; - /* FALL THROUGH */ - case ST_MAIN_TREE_REM: - /* - * Get path lengths of remaining elements of main tree. - */ - r = lzx_read_bitlen(strm, &ds->mt, -1); - if (r < 0) - goto failed; - else if (!r) { - ds->state = ST_MAIN_TREE_REM; - if (last) - goto failed; - return (ARCHIVE_OK); - } - if (!lzx_make_huffman_table(&ds->mt)) - goto failed; - ds->loop = 0; - /* FALL THROUGH */ - case ST_RD_PRE_LENGTH_TREE: - /* - * Read Pre-tree for remaining elements of main tree. - */ - if (!lzx_read_pre_tree(strm)) { - ds->state = ST_RD_PRE_LENGTH_TREE; - if (last) - goto failed; - return (ARCHIVE_OK); - } - if (!lzx_make_huffman_table(&ds->pt)) - goto failed; - ds->loop = 0; - /* FALL THROUGH */ - case ST_LENGTH_TREE: - /* - * Get path lengths of remaining elements of main tree. - */ - r = lzx_read_bitlen(strm, &ds->lt, -1); - if (r < 0) - goto failed; - else if (!r) { - ds->state = ST_LENGTH_TREE; - if (last) - goto failed; - return (ARCHIVE_OK); - } - if (!lzx_make_huffman_table(&ds->lt)) - goto failed; - ds->state = ST_MAIN; - return (100); - } - } -failed: - return (ds->error = ARCHIVE_FAILED); -} - -static int -lzx_decode_blocks(struct lzx_stream *strm, int last) -{ - struct lzx_dec *ds = strm->ds; - struct lzx_br bre = ds->br; - struct huffman *at = &(ds->at), *lt = &(ds->lt), *mt = &(ds->mt); - const struct lzx_pos_tbl *pos_tbl = ds->pos_tbl; - unsigned char *noutp = strm->next_out; - unsigned char *endp = noutp + strm->avail_out; - unsigned char *w_buff = ds->w_buff; - unsigned char *at_bitlen = at->bitlen; - unsigned char *lt_bitlen = lt->bitlen; - unsigned char *mt_bitlen = mt->bitlen; - size_t block_bytes_avail = ds->block_bytes_avail; - int at_max_bits = at->max_bits; - int lt_max_bits = lt->max_bits; - int mt_max_bits = mt->max_bits; - int c, copy_len = ds->copy_len, copy_pos = ds->copy_pos; - int w_pos = ds->w_pos, w_mask = ds->w_mask, w_size = ds->w_size; - int length_header = ds->length_header; - int offset_bits = ds->offset_bits; - int position_slot = ds->position_slot; - int r0 = ds->r0, r1 = ds->r1, r2 = ds->r2; - int state = ds->state; - char block_type = ds->block_type; - - for (;;) { - switch (state) { - case ST_MAIN: - for (;;) { - if (block_bytes_avail == 0) { - /* This block ended. */ - ds->state = ST_RD_BLOCK_TYPE; - ds->br = bre; - ds->block_bytes_avail = - block_bytes_avail; - ds->copy_len = copy_len; - ds->copy_pos = copy_pos; - ds->length_header = length_header; - ds->position_slot = position_slot; - ds->r0 = r0; ds->r1 = r1; ds->r2 = r2; - ds->w_pos = w_pos; - strm->avail_out = endp - noutp; - return (ARCHIVE_EOF); - } - if (noutp >= endp) - /* Output buffer is empty. */ - goto next_data; - - if (!lzx_br_read_ahead(strm, &bre, - mt_max_bits)) { - if (!last) - goto next_data; - /* Remaining bits are less than - * maximum bits(mt.max_bits) but maybe - * it still remains as much as we need, - * so we should try to use it with - * dummy bits. */ - c = lzx_decode_huffman(mt, - lzx_br_bits_forced( - &bre, mt_max_bits)); - lzx_br_consume(&bre, mt_bitlen[c]); - if (!lzx_br_has(&bre, 0)) - goto failed;/* Over read. */ - } else { - c = lzx_decode_huffman(mt, - lzx_br_bits(&bre, mt_max_bits)); - lzx_br_consume(&bre, mt_bitlen[c]); - } - if (c > UCHAR_MAX) - break; - /* - * 'c' is exactly literal code. - */ - /* Save a decoded code to reference it - * afterward. */ - w_buff[w_pos] = c; - w_pos = (w_pos + 1) & w_mask; - /* Store the decoded code to output buffer. */ - *noutp++ = c; - block_bytes_avail--; - } - /* - * Get a match code, its length and offset. - */ - c -= UCHAR_MAX + 1; - length_header = c & 7; - position_slot = c >> 3; - /* FALL THROUGH */ - case ST_LENGTH: - /* - * Get a length. - */ - if (length_header == 7) { - if (!lzx_br_read_ahead(strm, &bre, - lt_max_bits)) { - if (!last) { - state = ST_LENGTH; - goto next_data; - } - c = lzx_decode_huffman(lt, - lzx_br_bits_forced( - &bre, lt_max_bits)); - lzx_br_consume(&bre, lt_bitlen[c]); - if (!lzx_br_has(&bre, 0)) - goto failed;/* Over read. */ - } else { - c = lzx_decode_huffman(lt, - lzx_br_bits(&bre, lt_max_bits)); - lzx_br_consume(&bre, lt_bitlen[c]); - } - copy_len = c + 7 + 2; - } else - copy_len = length_header + 2; - if ((size_t)copy_len > block_bytes_avail) - goto failed; - /* - * Get an offset. - */ - switch (position_slot) { - case 0: /* Use repeated offset 0. */ - copy_pos = r0; - state = ST_REAL_POS; - continue; - case 1: /* Use repeated offset 1. */ - copy_pos = r1; - /* Swap repeated offset. */ - r1 = r0; - r0 = copy_pos; - state = ST_REAL_POS; - continue; - case 2: /* Use repeated offset 2. */ - copy_pos = r2; - /* Swap repeated offset. */ - r2 = r0; - r0 = copy_pos; - state = ST_REAL_POS; - continue; - default: - offset_bits = - pos_tbl[position_slot].footer_bits; - break; - } - /* FALL THROUGH */ - case ST_OFFSET: - /* - * Get the offset, which is a distance from - * current window position. - */ - if (block_type == ALIGNED_OFFSET_BLOCK && - offset_bits >= 3) { - int offbits = offset_bits - 3; - - if (!lzx_br_read_ahead(strm, &bre, offbits)) { - state = ST_OFFSET; - if (last) - goto failed; - goto next_data; - } - copy_pos = lzx_br_bits(&bre, offbits) << 3; - - /* Get an aligned number. */ - if (!lzx_br_read_ahead(strm, &bre, - offbits + at_max_bits)) { - if (!last) { - state = ST_OFFSET; - goto next_data; - } - lzx_br_consume(&bre, offbits); - c = lzx_decode_huffman(at, - lzx_br_bits_forced(&bre, - at_max_bits)); - lzx_br_consume(&bre, at_bitlen[c]); - if (!lzx_br_has(&bre, 0)) - goto failed;/* Over read. */ - } else { - lzx_br_consume(&bre, offbits); - c = lzx_decode_huffman(at, - lzx_br_bits(&bre, at_max_bits)); - lzx_br_consume(&bre, at_bitlen[c]); - } - /* Add an aligned number. */ - copy_pos += c; - } else { - if (!lzx_br_read_ahead(strm, &bre, - offset_bits)) { - state = ST_OFFSET; - if (last) - goto failed; - goto next_data; - } - copy_pos = lzx_br_bits(&bre, offset_bits); - lzx_br_consume(&bre, offset_bits); - } - copy_pos += pos_tbl[position_slot].base -2; - - /* Update repeated offset LRU queue. */ - r2 = r1; - r1 = r0; - r0 = copy_pos; - /* FALL THROUGH */ - case ST_REAL_POS: - /* - * Compute a real position in window. - */ - copy_pos = (w_pos - copy_pos) & w_mask; - /* FALL THROUGH */ - case ST_COPY: - /* - * Copy several bytes as extracted data from the window - * into the output buffer. - */ - for (;;) { - const unsigned char *s; - int l; - - l = copy_len; - if (copy_pos > w_pos) { - if (l > w_size - copy_pos) - l = w_size - copy_pos; - } else { - if (l > w_size - w_pos) - l = w_size - w_pos; - } - if (noutp + l >= endp) - l = (int)(endp - noutp); - s = w_buff + copy_pos; - if (l >= 8 && ((copy_pos + l < w_pos) - || (w_pos + l < copy_pos))) { - memcpy(w_buff + w_pos, s, l); - memcpy(noutp, s, l); - } else { - unsigned char *d; - int li; - - d = w_buff + w_pos; - for (li = 0; li < l; li++) - noutp[li] = d[li] = s[li]; - } - noutp += l; - copy_pos = (copy_pos + l) & w_mask; - w_pos = (w_pos + l) & w_mask; - block_bytes_avail -= l; - if (copy_len <= l) - /* A copy of current pattern ended. */ - break; - copy_len -= l; - if (noutp >= endp) { - /* Output buffer is empty. */ - state = ST_COPY; - goto next_data; - } - } - state = ST_MAIN; - break; - } - } -failed: - return (ds->error = ARCHIVE_FAILED); -next_data: - ds->br = bre; - ds->block_bytes_avail = block_bytes_avail; - ds->copy_len = copy_len; - ds->copy_pos = copy_pos; - ds->length_header = length_header; - ds->offset_bits = offset_bits; - ds->position_slot = position_slot; - ds->r0 = r0; ds->r1 = r1; ds->r2 = r2; - ds->state = state; - ds->w_pos = w_pos; - strm->avail_out = endp - noutp; - return (ARCHIVE_OK); -} - -static int -lzx_read_pre_tree(struct lzx_stream *strm) -{ - struct lzx_dec *ds = strm->ds; - struct lzx_br *br = &(ds->br); - int i; - - if (ds->loop == 0) - memset(ds->pt.freq, 0, sizeof(ds->pt.freq)); - for (i = ds->loop; i < ds->pt.len_size; i++) { - if (!lzx_br_read_ahead(strm, br, 4)) { - ds->loop = i; - return (0); - } - ds->pt.bitlen[i] = lzx_br_bits(br, 4); - ds->pt.freq[ds->pt.bitlen[i]]++; - lzx_br_consume(br, 4); - } - ds->loop = i; - return (1); -} - -/* - * Read a bunch of bit-lengths from pre-tree. - */ -static int -lzx_read_bitlen(struct lzx_stream *strm, struct huffman *d, int end) -{ - struct lzx_dec *ds = strm->ds; - struct lzx_br *br = &(ds->br); - int c, i, j, ret, same; - unsigned rbits; - - i = ds->loop; - if (i == 0) - memset(d->freq, 0, sizeof(d->freq)); - ret = 0; - if (end < 0) - end = d->len_size; - while (i < end) { - ds->loop = i; - if (!lzx_br_read_ahead(strm, br, ds->pt.max_bits)) - goto getdata; - rbits = lzx_br_bits(br, ds->pt.max_bits); - c = lzx_decode_huffman(&(ds->pt), rbits); - switch (c) { - case 17:/* several zero lengths, from 4 to 19. */ - if (!lzx_br_read_ahead(strm, br, ds->pt.bitlen[c]+4)) - goto getdata; - lzx_br_consume(br, ds->pt.bitlen[c]); - same = lzx_br_bits(br, 4) + 4; - if (i + same > end) - return (-1);/* Invalid */ - lzx_br_consume(br, 4); - for (j = 0; j < same; j++) - d->bitlen[i++] = 0; - break; - case 18:/* many zero lengths, from 20 to 51. */ - if (!lzx_br_read_ahead(strm, br, ds->pt.bitlen[c]+5)) - goto getdata; - lzx_br_consume(br, ds->pt.bitlen[c]); - same = lzx_br_bits(br, 5) + 20; - if (i + same > end) - return (-1);/* Invalid */ - lzx_br_consume(br, 5); - memset(d->bitlen + i, 0, same); - i += same; - break; - case 19:/* a few same lengths. */ - if (!lzx_br_read_ahead(strm, br, - ds->pt.bitlen[c]+1+ds->pt.max_bits)) - goto getdata; - lzx_br_consume(br, ds->pt.bitlen[c]); - same = lzx_br_bits(br, 1) + 4; - if (i + same > end) - return (-1); - lzx_br_consume(br, 1); - rbits = lzx_br_bits(br, ds->pt.max_bits); - c = lzx_decode_huffman(&(ds->pt), rbits); - lzx_br_consume(br, ds->pt.bitlen[c]); - c = (d->bitlen[i] - c + 17) % 17; - if (c < 0) - return (-1);/* Invalid */ - for (j = 0; j < same; j++) - d->bitlen[i++] = c; - d->freq[c] += same; - break; - default: - lzx_br_consume(br, ds->pt.bitlen[c]); - c = (d->bitlen[i] - c + 17) % 17; - if (c < 0) - return (-1);/* Invalid */ - d->freq[c]++; - d->bitlen[i++] = c; - break; - } - } - ret = 1; -getdata: - ds->loop = i; - return (ret); -} - -static int -lzx_huffman_init(struct huffman *hf, size_t len_size, int tbl_bits) -{ - - if (hf->bitlen == NULL || hf->len_size != (int)len_size) { - free(hf->bitlen); - hf->bitlen = calloc(len_size, sizeof(hf->bitlen[0])); - if (hf->bitlen == NULL) - return (ARCHIVE_FATAL); - hf->len_size = (int)len_size; - } else - memset(hf->bitlen, 0, len_size * sizeof(hf->bitlen[0])); - if (hf->tbl == NULL) { - hf->tbl = malloc(((size_t)1 << tbl_bits) * sizeof(hf->tbl[0])); - if (hf->tbl == NULL) - return (ARCHIVE_FATAL); - hf->tbl_bits = tbl_bits; - } - return (ARCHIVE_OK); -} - -static void -lzx_huffman_free(struct huffman *hf) -{ - free(hf->bitlen); - free(hf->tbl); -} - -/* - * Make a huffman coding table. - */ -static int -lzx_make_huffman_table(struct huffman *hf) -{ - uint16_t *tbl; - const unsigned char *bitlen; - int bitptn[17], weight[17]; - int i, maxbits = 0, ptn, tbl_size, w; - int len_avail; - - /* - * Initialize bit patterns. - */ - ptn = 0; - for (i = 1, w = 1 << 15; i <= 16; i++, w >>= 1) { - bitptn[i] = ptn; - weight[i] = w; - if (hf->freq[i]) { - ptn += hf->freq[i] * w; - maxbits = i; - } - } - if ((ptn & 0xffff) != 0 || maxbits > hf->tbl_bits) - return (0);/* Invalid */ - - hf->max_bits = maxbits; - - /* - * Cut out extra bits which we won't house in the table. - * This preparation reduces the same calculation in the for-loop - * making the table. - */ - if (maxbits < 16) { - int ebits = 16 - maxbits; - for (i = 1; i <= maxbits; i++) { - bitptn[i] >>= ebits; - weight[i] >>= ebits; - } - } - - /* - * Make the table. - */ - tbl_size = 1 << hf->tbl_bits; - tbl = hf->tbl; - bitlen = hf->bitlen; - len_avail = hf->len_size; - hf->tree_used = 0; - for (i = 0; i < len_avail; i++) { - uint16_t *p; - int len, cnt; - - if (bitlen[i] == 0) - continue; - /* Get a bit pattern */ - len = bitlen[i]; - if (len > tbl_size) - return (0); - ptn = bitptn[len]; - cnt = weight[len]; - /* Calculate next bit pattern */ - if ((bitptn[len] = ptn + cnt) > tbl_size) - return (0);/* Invalid */ - /* Update the table */ - p = &(tbl[ptn]); - while (--cnt >= 0) - p[cnt] = (uint16_t)i; - } - return (1); -} - -static inline int -lzx_decode_huffman(struct huffman *hf, unsigned rbits) -{ - int c; - c = hf->tbl[rbits]; - if (c < hf->len_size) - return (c); - return (0); -} diff --git a/thirdparty/libarchive/libarchive/archive_read_support_format_cpio.c b/thirdparty/libarchive/libarchive/archive_read_support_format_cpio.c deleted file mode 100644 index 9adcfd335..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_format_cpio.c +++ /dev/null @@ -1,1104 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2010-2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_cpio.c 201163 2009-12-29 05:50:34Z kientzle $"); - -#ifdef HAVE_ERRNO_H -#include -#endif -/* #include */ /* See archive_platform.h */ -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" -#include "archive_entry_locale.h" -#include "archive_private.h" -#include "archive_read_private.h" - -#define bin_magic_offset 0 -#define bin_magic_size 2 -#define bin_dev_offset 2 -#define bin_dev_size 2 -#define bin_ino_offset 4 -#define bin_ino_size 2 -#define bin_mode_offset 6 -#define bin_mode_size 2 -#define bin_uid_offset 8 -#define bin_uid_size 2 -#define bin_gid_offset 10 -#define bin_gid_size 2 -#define bin_nlink_offset 12 -#define bin_nlink_size 2 -#define bin_rdev_offset 14 -#define bin_rdev_size 2 -#define bin_mtime_offset 16 -#define bin_mtime_size 4 -#define bin_namesize_offset 20 -#define bin_namesize_size 2 -#define bin_filesize_offset 22 -#define bin_filesize_size 4 -#define bin_header_size 26 - -#define odc_magic_offset 0 -#define odc_magic_size 6 -#define odc_dev_offset 6 -#define odc_dev_size 6 -#define odc_ino_offset 12 -#define odc_ino_size 6 -#define odc_mode_offset 18 -#define odc_mode_size 6 -#define odc_uid_offset 24 -#define odc_uid_size 6 -#define odc_gid_offset 30 -#define odc_gid_size 6 -#define odc_nlink_offset 36 -#define odc_nlink_size 6 -#define odc_rdev_offset 42 -#define odc_rdev_size 6 -#define odc_mtime_offset 48 -#define odc_mtime_size 11 -#define odc_namesize_offset 59 -#define odc_namesize_size 6 -#define odc_filesize_offset 65 -#define odc_filesize_size 11 -#define odc_header_size 76 - -#define newc_magic_offset 0 -#define newc_magic_size 6 -#define newc_ino_offset 6 -#define newc_ino_size 8 -#define newc_mode_offset 14 -#define newc_mode_size 8 -#define newc_uid_offset 22 -#define newc_uid_size 8 -#define newc_gid_offset 30 -#define newc_gid_size 8 -#define newc_nlink_offset 38 -#define newc_nlink_size 8 -#define newc_mtime_offset 46 -#define newc_mtime_size 8 -#define newc_filesize_offset 54 -#define newc_filesize_size 8 -#define newc_devmajor_offset 62 -#define newc_devmajor_size 8 -#define newc_devminor_offset 70 -#define newc_devminor_size 8 -#define newc_rdevmajor_offset 78 -#define newc_rdevmajor_size 8 -#define newc_rdevminor_offset 86 -#define newc_rdevminor_size 8 -#define newc_namesize_offset 94 -#define newc_namesize_size 8 -#define newc_checksum_offset 102 -#define newc_checksum_size 8 -#define newc_header_size 110 - -/* - * An afio large ASCII header, which they named itself. - * afio utility uses this header, if a file size is larger than 2G bytes - * or inode/uid/gid is bigger than 65535(0xFFFF) or mtime is bigger than - * 0x7fffffff, which we cannot record to odc header because of its limit. - * If not, uses odc header. - */ -#define afiol_magic_offset 0 -#define afiol_magic_size 6 -#define afiol_dev_offset 6 -#define afiol_dev_size 8 /* hex */ -#define afiol_ino_offset 14 -#define afiol_ino_size 16 /* hex */ -#define afiol_ino_m_offset 30 /* 'm' */ -#define afiol_mode_offset 31 -#define afiol_mode_size 6 /* oct */ -#define afiol_uid_offset 37 -#define afiol_uid_size 8 /* hex */ -#define afiol_gid_offset 45 -#define afiol_gid_size 8 /* hex */ -#define afiol_nlink_offset 53 -#define afiol_nlink_size 8 /* hex */ -#define afiol_rdev_offset 61 -#define afiol_rdev_size 8 /* hex */ -#define afiol_mtime_offset 69 -#define afiol_mtime_size 16 /* hex */ -#define afiol_mtime_n_offset 85 /* 'n' */ -#define afiol_namesize_offset 86 -#define afiol_namesize_size 4 /* hex */ -#define afiol_flag_offset 90 -#define afiol_flag_size 4 /* hex */ -#define afiol_xsize_offset 94 -#define afiol_xsize_size 4 /* hex */ -#define afiol_xsize_s_offset 98 /* 's' */ -#define afiol_filesize_offset 99 -#define afiol_filesize_size 16 /* hex */ -#define afiol_filesize_c_offset 115 /* ':' */ -#define afiol_header_size 116 - - -struct links_entry { - struct links_entry *next; - struct links_entry *previous; - unsigned int links; - dev_t dev; - int64_t ino; - char *name; -}; - -#define CPIO_MAGIC 0x13141516 -struct cpio { - int magic; - int (*read_header)(struct archive_read *, struct cpio *, - struct archive_entry *, size_t *, size_t *); - struct links_entry *links_head; - int64_t entry_bytes_remaining; - int64_t entry_bytes_unconsumed; - int64_t entry_offset; - int64_t entry_padding; - - struct archive_string_conv *opt_sconv; - struct archive_string_conv *sconv_default; - int init_default_conversion; - - int option_pwb; -}; - -static int64_t atol16(const char *, unsigned); -static int64_t atol8(const char *, unsigned); -static int archive_read_format_cpio_bid(struct archive_read *, int); -static int archive_read_format_cpio_options(struct archive_read *, - const char *, const char *); -static int archive_read_format_cpio_cleanup(struct archive_read *); -static int archive_read_format_cpio_read_data(struct archive_read *, - const void **, size_t *, int64_t *); -static int archive_read_format_cpio_read_header(struct archive_read *, - struct archive_entry *); -static int archive_read_format_cpio_skip(struct archive_read *); -static int64_t be4(const unsigned char *); -static int find_odc_header(struct archive_read *); -static int find_newc_header(struct archive_read *); -static int header_bin_be(struct archive_read *, struct cpio *, - struct archive_entry *, size_t *, size_t *); -static int header_bin_le(struct archive_read *, struct cpio *, - struct archive_entry *, size_t *, size_t *); -static int header_newc(struct archive_read *, struct cpio *, - struct archive_entry *, size_t *, size_t *); -static int header_odc(struct archive_read *, struct cpio *, - struct archive_entry *, size_t *, size_t *); -static int header_afiol(struct archive_read *, struct cpio *, - struct archive_entry *, size_t *, size_t *); -static int is_octal(const char *, size_t); -static int is_hex(const char *, size_t); -static int64_t le4(const unsigned char *); -static int record_hardlink(struct archive_read *a, - struct cpio *cpio, struct archive_entry *entry); - -int -archive_read_support_format_cpio(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - struct cpio *cpio; - int r; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_format_cpio"); - - cpio = (struct cpio *)calloc(1, sizeof(*cpio)); - if (cpio == NULL) { - archive_set_error(&a->archive, ENOMEM, "Can't allocate cpio data"); - return (ARCHIVE_FATAL); - } - cpio->magic = CPIO_MAGIC; - - r = __archive_read_register_format(a, - cpio, - "cpio", - archive_read_format_cpio_bid, - archive_read_format_cpio_options, - archive_read_format_cpio_read_header, - archive_read_format_cpio_read_data, - archive_read_format_cpio_skip, - NULL, - archive_read_format_cpio_cleanup, - NULL, - NULL); - - if (r != ARCHIVE_OK) - free(cpio); - return (ARCHIVE_OK); -} - - -static int -archive_read_format_cpio_bid(struct archive_read *a, int best_bid) -{ - const unsigned char *p; - struct cpio *cpio; - int bid; - - (void)best_bid; /* UNUSED */ - - cpio = (struct cpio *)(a->format->data); - - if ((p = __archive_read_ahead(a, 6, NULL)) == NULL) - return (-1); - - bid = 0; - if (memcmp(p, "070707", 6) == 0) { - /* ASCII cpio archive (odc, POSIX.1) */ - cpio->read_header = header_odc; - bid += 48; - /* - * XXX TODO: More verification; Could check that only octal - * digits appear in appropriate header locations. XXX - */ - } else if (memcmp(p, "070727", 6) == 0) { - /* afio large ASCII cpio archive */ - cpio->read_header = header_odc; - bid += 48; - /* - * XXX TODO: More verification; Could check that almost hex - * digits appear in appropriate header locations. XXX - */ - } else if (memcmp(p, "070701", 6) == 0) { - /* ASCII cpio archive (SVR4 without CRC) */ - cpio->read_header = header_newc; - bid += 48; - /* - * XXX TODO: More verification; Could check that only hex - * digits appear in appropriate header locations. XXX - */ - } else if (memcmp(p, "070702", 6) == 0) { - /* ASCII cpio archive (SVR4 with CRC) */ - /* XXX TODO: Flag that we should check the CRC. XXX */ - cpio->read_header = header_newc; - bid += 48; - /* - * XXX TODO: More verification; Could check that only hex - * digits appear in appropriate header locations. XXX - */ - } else if (p[0] * 256 + p[1] == 070707) { - /* big-endian binary cpio archives */ - cpio->read_header = header_bin_be; - bid += 16; - /* Is more verification possible here? */ - } else if (p[0] + p[1] * 256 == 070707) { - /* little-endian binary cpio archives */ - cpio->read_header = header_bin_le; - bid += 16; - /* Is more verification possible here? */ - } else - return (ARCHIVE_WARN); - - return (bid); -} - -static int -archive_read_format_cpio_options(struct archive_read *a, - const char *key, const char *val) -{ - struct cpio *cpio; - int ret = ARCHIVE_FAILED; - - cpio = (struct cpio *)(a->format->data); - if (strcmp(key, "compat-2x") == 0) { - /* Handle filenames as libarchive 2.x */ - cpio->init_default_conversion = (val != NULL)?1:0; - return (ARCHIVE_OK); - } else if (strcmp(key, "hdrcharset") == 0) { - if (val == NULL || val[0] == 0) - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "cpio: hdrcharset option needs a character-set name"); - else { - cpio->opt_sconv = - archive_string_conversion_from_charset( - &a->archive, val, 0); - if (cpio->opt_sconv != NULL) - ret = ARCHIVE_OK; - else - ret = ARCHIVE_FATAL; - } - return (ret); - } else if (strcmp(key, "pwb") == 0) { - if (val != NULL && val[0] != 0) - cpio->option_pwb = 1; - return (ARCHIVE_OK); - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -static int -archive_read_format_cpio_read_header(struct archive_read *a, - struct archive_entry *entry) -{ - struct cpio *cpio; - const void *h, *hl; - struct archive_string_conv *sconv; - size_t namelength; - size_t name_pad; - int r; - - cpio = (struct cpio *)(a->format->data); - sconv = cpio->opt_sconv; - if (sconv == NULL) { - if (!cpio->init_default_conversion) { - cpio->sconv_default = - archive_string_default_conversion_for_read( - &(a->archive)); - cpio->init_default_conversion = 1; - } - sconv = cpio->sconv_default; - } - - r = (cpio->read_header(a, cpio, entry, &namelength, &name_pad)); - - if (r < ARCHIVE_WARN) - return (r); - - /* Read name from buffer. */ - h = __archive_read_ahead(a, namelength + name_pad, NULL); - if (h == NULL) - return (ARCHIVE_FATAL); - if (archive_entry_copy_pathname_l(entry, - (const char *)h, namelength, sconv) != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Pathname"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Pathname can't be converted from %s to current locale.", - archive_string_conversion_charset_name(sconv)); - r = ARCHIVE_WARN; - } - cpio->entry_offset = 0; - - __archive_read_consume(a, namelength + name_pad); - - /* If this is a symlink, read the link contents. */ - if (archive_entry_filetype(entry) == AE_IFLNK) { - if (cpio->entry_bytes_remaining > 1024 * 1024) { - archive_set_error(&a->archive, ENOMEM, - "Rejecting malformed cpio archive: symlink contents exceed 1 megabyte"); - return (ARCHIVE_FATAL); - } - hl = __archive_read_ahead(a, - (size_t)cpio->entry_bytes_remaining, NULL); - if (hl == NULL) - return (ARCHIVE_FATAL); - if (archive_entry_copy_symlink_l(entry, (const char *)hl, - (size_t)cpio->entry_bytes_remaining, sconv) != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Linkname"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Linkname can't be converted from %s to " - "current locale.", - archive_string_conversion_charset_name(sconv)); - r = ARCHIVE_WARN; - } - __archive_read_consume(a, cpio->entry_bytes_remaining); - cpio->entry_bytes_remaining = 0; - } - - /* XXX TODO: If the full mode is 0160200, then this is a Solaris - * ACL description for the following entry. Read this body - * and parse it as a Solaris-style ACL, then read the next - * header. XXX */ - - /* Compare name to "TRAILER!!!" to test for end-of-archive. */ - if (namelength == 11 && strncmp((const char *)h, "TRAILER!!!", - 10) == 0) { - /* TODO: Store file location of start of block. */ - archive_clear_error(&a->archive); - return (ARCHIVE_EOF); - } - - /* Detect and record hardlinks to previously-extracted entries. */ - if (record_hardlink(a, cpio, entry) != ARCHIVE_OK) { - return (ARCHIVE_FATAL); - } - - return (r); -} - -static int -archive_read_format_cpio_read_data(struct archive_read *a, - const void **buff, size_t *size, int64_t *offset) -{ - ssize_t bytes_read; - struct cpio *cpio; - - cpio = (struct cpio *)(a->format->data); - - if (cpio->entry_bytes_unconsumed) { - __archive_read_consume(a, cpio->entry_bytes_unconsumed); - cpio->entry_bytes_unconsumed = 0; - } - - if (cpio->entry_bytes_remaining > 0) { - *buff = __archive_read_ahead(a, 1, &bytes_read); - if (bytes_read <= 0) - return (ARCHIVE_FATAL); - if (bytes_read > cpio->entry_bytes_remaining) - bytes_read = (ssize_t)cpio->entry_bytes_remaining; - *size = bytes_read; - cpio->entry_bytes_unconsumed = bytes_read; - *offset = cpio->entry_offset; - cpio->entry_offset += bytes_read; - cpio->entry_bytes_remaining -= bytes_read; - return (ARCHIVE_OK); - } else { - if (cpio->entry_padding != - __archive_read_consume(a, cpio->entry_padding)) { - return (ARCHIVE_FATAL); - } - cpio->entry_padding = 0; - *buff = NULL; - *size = 0; - *offset = cpio->entry_offset; - return (ARCHIVE_EOF); - } -} - -static int -archive_read_format_cpio_skip(struct archive_read *a) -{ - struct cpio *cpio = (struct cpio *)(a->format->data); - int64_t to_skip = cpio->entry_bytes_remaining + cpio->entry_padding + - cpio->entry_bytes_unconsumed; - - if (to_skip != __archive_read_consume(a, to_skip)) { - return (ARCHIVE_FATAL); - } - cpio->entry_bytes_remaining = 0; - cpio->entry_padding = 0; - cpio->entry_bytes_unconsumed = 0; - return (ARCHIVE_OK); -} - -/* - * Skip forward to the next cpio newc header by searching for the - * 07070[12] string. This should be generalized and merged with - * find_odc_header below. - */ -static int -is_hex(const char *p, size_t len) -{ - while (len-- > 0) { - if ((*p >= '0' && *p <= '9') - || (*p >= 'a' && *p <= 'f') - || (*p >= 'A' && *p <= 'F')) - ++p; - else - return (0); - } - return (1); -} - -static int -find_newc_header(struct archive_read *a) -{ - const void *h; - const char *p, *q; - size_t skip, skipped = 0; - ssize_t bytes; - - for (;;) { - h = __archive_read_ahead(a, newc_header_size, &bytes); - if (h == NULL) - return (ARCHIVE_FATAL); - p = h; - q = p + bytes; - - /* Try the typical case first, then go into the slow search.*/ - if (memcmp("07070", p, 5) == 0 - && (p[5] == '1' || p[5] == '2') - && is_hex(p, newc_header_size)) - return (ARCHIVE_OK); - - /* - * Scan ahead until we find something that looks - * like a newc header. - */ - while (p + newc_header_size <= q) { - switch (p[5]) { - case '1': - case '2': - if (memcmp("07070", p, 5) == 0 - && is_hex(p, newc_header_size)) { - skip = p - (const char *)h; - __archive_read_consume(a, skip); - skipped += skip; - if (skipped > 0) { - archive_set_error(&a->archive, - 0, - "Skipped %d bytes before " - "finding valid header", - (int)skipped); - return (ARCHIVE_WARN); - } - return (ARCHIVE_OK); - } - p += 2; - break; - case '0': - p++; - break; - default: - p += 6; - break; - } - } - skip = p - (const char *)h; - __archive_read_consume(a, skip); - skipped += skip; - } -} - -static int -header_newc(struct archive_read *a, struct cpio *cpio, - struct archive_entry *entry, size_t *namelength, size_t *name_pad) -{ - const void *h; - const char *header; - int r; - - r = find_newc_header(a); - if (r < ARCHIVE_WARN) - return (r); - - /* Read fixed-size portion of header. */ - h = __archive_read_ahead(a, newc_header_size, NULL); - if (h == NULL) - return (ARCHIVE_FATAL); - - /* Parse out hex fields. */ - header = (const char *)h; - - if (memcmp(header + newc_magic_offset, "070701", 6) == 0) { - a->archive.archive_format = ARCHIVE_FORMAT_CPIO_SVR4_NOCRC; - a->archive.archive_format_name = "ASCII cpio (SVR4 with no CRC)"; - } else if (memcmp(header + newc_magic_offset, "070702", 6) == 0) { - a->archive.archive_format = ARCHIVE_FORMAT_CPIO_SVR4_CRC; - a->archive.archive_format_name = "ASCII cpio (SVR4 with CRC)"; - } else { - /* TODO: Abort here? */ - } - - archive_entry_set_devmajor(entry, - (dev_t)atol16(header + newc_devmajor_offset, newc_devmajor_size)); - archive_entry_set_devminor(entry, - (dev_t)atol16(header + newc_devminor_offset, newc_devminor_size)); - archive_entry_set_ino(entry, atol16(header + newc_ino_offset, newc_ino_size)); - archive_entry_set_mode(entry, - (mode_t)atol16(header + newc_mode_offset, newc_mode_size)); - archive_entry_set_uid(entry, atol16(header + newc_uid_offset, newc_uid_size)); - archive_entry_set_gid(entry, atol16(header + newc_gid_offset, newc_gid_size)); - archive_entry_set_nlink(entry, - (unsigned int)atol16(header + newc_nlink_offset, newc_nlink_size)); - archive_entry_set_rdevmajor(entry, - (dev_t)atol16(header + newc_rdevmajor_offset, newc_rdevmajor_size)); - archive_entry_set_rdevminor(entry, - (dev_t)atol16(header + newc_rdevminor_offset, newc_rdevminor_size)); - archive_entry_set_mtime(entry, atol16(header + newc_mtime_offset, newc_mtime_size), 0); - *namelength = (size_t)atol16(header + newc_namesize_offset, newc_namesize_size); - /* Pad name to 2 more than a multiple of 4. */ - *name_pad = (2 - *namelength) & 3; - - /* Make sure that the padded name length fits into size_t. */ - if (*name_pad > SIZE_MAX - *namelength) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "cpio archive has invalid namelength"); - return (ARCHIVE_FATAL); - } - - /* - * Note: entry_bytes_remaining is at least 64 bits and - * therefore guaranteed to be big enough for a 33-bit file - * size. - */ - cpio->entry_bytes_remaining = - atol16(header + newc_filesize_offset, newc_filesize_size); - archive_entry_set_size(entry, cpio->entry_bytes_remaining); - /* Pad file contents to a multiple of 4. */ - cpio->entry_padding = 3 & -cpio->entry_bytes_remaining; - __archive_read_consume(a, newc_header_size); - return (r); -} - -/* - * Skip forward to the next cpio odc header by searching for the - * 070707 string. This is a hand-optimized search that could - * probably be easily generalized to handle all character-based - * cpio variants. - */ -static int -is_octal(const char *p, size_t len) -{ - while (len-- > 0) { - if (*p < '0' || *p > '7') - return (0); - ++p; - } - return (1); -} - -static int -is_afio_large(const char *h, size_t len) -{ - if (len < afiol_header_size) - return (0); - if (h[afiol_ino_m_offset] != 'm' - || h[afiol_mtime_n_offset] != 'n' - || h[afiol_xsize_s_offset] != 's' - || h[afiol_filesize_c_offset] != ':') - return (0); - if (!is_hex(h + afiol_dev_offset, afiol_ino_m_offset - afiol_dev_offset)) - return (0); - if (!is_hex(h + afiol_mode_offset, afiol_mtime_n_offset - afiol_mode_offset)) - return (0); - if (!is_hex(h + afiol_namesize_offset, afiol_xsize_s_offset - afiol_namesize_offset)) - return (0); - if (!is_hex(h + afiol_filesize_offset, afiol_filesize_size)) - return (0); - return (1); -} - -static int -find_odc_header(struct archive_read *a) -{ - const void *h; - const char *p, *q; - size_t skip, skipped = 0; - ssize_t bytes; - - for (;;) { - h = __archive_read_ahead(a, odc_header_size, &bytes); - if (h == NULL) - return (ARCHIVE_FATAL); - p = h; - q = p + bytes; - - /* Try the typical case first, then go into the slow search.*/ - if (memcmp("070707", p, 6) == 0 && is_octal(p, odc_header_size)) - return (ARCHIVE_OK); - if (memcmp("070727", p, 6) == 0 && is_afio_large(p, bytes)) { - a->archive.archive_format = ARCHIVE_FORMAT_CPIO_AFIO_LARGE; - return (ARCHIVE_OK); - } - - /* - * Scan ahead until we find something that looks - * like an odc header. - */ - while (p + odc_header_size <= q) { - switch (p[5]) { - case '7': - if ((memcmp("070707", p, 6) == 0 - && is_octal(p, odc_header_size)) - || (memcmp("070727", p, 6) == 0 - && is_afio_large(p, q - p))) { - skip = p - (const char *)h; - __archive_read_consume(a, skip); - skipped += skip; - if (p[4] == '2') - a->archive.archive_format = - ARCHIVE_FORMAT_CPIO_AFIO_LARGE; - if (skipped > 0) { - archive_set_error(&a->archive, - 0, - "Skipped %d bytes before " - "finding valid header", - (int)skipped); - return (ARCHIVE_WARN); - } - return (ARCHIVE_OK); - } - p += 2; - break; - case '0': - p++; - break; - default: - p += 6; - break; - } - } - skip = p - (const char *)h; - __archive_read_consume(a, skip); - skipped += skip; - } -} - -static int -header_odc(struct archive_read *a, struct cpio *cpio, - struct archive_entry *entry, size_t *namelength, size_t *name_pad) -{ - const void *h; - int r; - const char *header; - - a->archive.archive_format = ARCHIVE_FORMAT_CPIO_POSIX; - a->archive.archive_format_name = "POSIX octet-oriented cpio"; - - /* Find the start of the next header. */ - r = find_odc_header(a); - if (r < ARCHIVE_WARN) - return (r); - - if (a->archive.archive_format == ARCHIVE_FORMAT_CPIO_AFIO_LARGE) { - int r2 = (header_afiol(a, cpio, entry, namelength, name_pad)); - if (r2 == ARCHIVE_OK) - return (r); - else - return (r2); - } - - /* Read fixed-size portion of header. */ - h = __archive_read_ahead(a, odc_header_size, NULL); - if (h == NULL) - return (ARCHIVE_FATAL); - - /* Parse out octal fields. */ - header = (const char *)h; - - archive_entry_set_dev(entry, - (dev_t)atol8(header + odc_dev_offset, odc_dev_size)); - archive_entry_set_ino(entry, atol8(header + odc_ino_offset, odc_ino_size)); - archive_entry_set_mode(entry, - (mode_t)atol8(header + odc_mode_offset, odc_mode_size)); - archive_entry_set_uid(entry, atol8(header + odc_uid_offset, odc_uid_size)); - archive_entry_set_gid(entry, atol8(header + odc_gid_offset, odc_gid_size)); - archive_entry_set_nlink(entry, - (unsigned int)atol8(header + odc_nlink_offset, odc_nlink_size)); - archive_entry_set_rdev(entry, - (dev_t)atol8(header + odc_rdev_offset, odc_rdev_size)); - archive_entry_set_mtime(entry, atol8(header + odc_mtime_offset, odc_mtime_size), 0); - *namelength = (size_t)atol8(header + odc_namesize_offset, odc_namesize_size); - *name_pad = 0; /* No padding of filename. */ - - /* - * Note: entry_bytes_remaining is at least 64 bits and - * therefore guaranteed to be big enough for a 33-bit file - * size. - */ - cpio->entry_bytes_remaining = - atol8(header + odc_filesize_offset, odc_filesize_size); - archive_entry_set_size(entry, cpio->entry_bytes_remaining); - cpio->entry_padding = 0; - __archive_read_consume(a, odc_header_size); - return (r); -} - -/* - * NOTE: if a filename suffix is ".z", it is the file gziped by afio. - * it would be nice that we can show uncompressed file size and we can - * uncompressed file contents automatically, unfortunately we have nothing - * to get a uncompressed file size while reading each header. It means - * we also cannot uncompress file contents under our framework. - */ -static int -header_afiol(struct archive_read *a, struct cpio *cpio, - struct archive_entry *entry, size_t *namelength, size_t *name_pad) -{ - const void *h; - const char *header; - - a->archive.archive_format = ARCHIVE_FORMAT_CPIO_AFIO_LARGE; - a->archive.archive_format_name = "afio large ASCII"; - - /* Read fixed-size portion of header. */ - h = __archive_read_ahead(a, afiol_header_size, NULL); - if (h == NULL) - return (ARCHIVE_FATAL); - - /* Parse out octal fields. */ - header = (const char *)h; - - archive_entry_set_dev(entry, - (dev_t)atol16(header + afiol_dev_offset, afiol_dev_size)); - archive_entry_set_ino(entry, atol16(header + afiol_ino_offset, afiol_ino_size)); - archive_entry_set_mode(entry, - (mode_t)atol8(header + afiol_mode_offset, afiol_mode_size)); - archive_entry_set_uid(entry, atol16(header + afiol_uid_offset, afiol_uid_size)); - archive_entry_set_gid(entry, atol16(header + afiol_gid_offset, afiol_gid_size)); - archive_entry_set_nlink(entry, - (unsigned int)atol16(header + afiol_nlink_offset, afiol_nlink_size)); - archive_entry_set_rdev(entry, - (dev_t)atol16(header + afiol_rdev_offset, afiol_rdev_size)); - archive_entry_set_mtime(entry, atol16(header + afiol_mtime_offset, afiol_mtime_size), 0); - *namelength = (size_t)atol16(header + afiol_namesize_offset, afiol_namesize_size); - *name_pad = 0; /* No padding of filename. */ - - cpio->entry_bytes_remaining = - atol16(header + afiol_filesize_offset, afiol_filesize_size); - archive_entry_set_size(entry, cpio->entry_bytes_remaining); - cpio->entry_padding = 0; - __archive_read_consume(a, afiol_header_size); - return (ARCHIVE_OK); -} - - -static int -header_bin_le(struct archive_read *a, struct cpio *cpio, - struct archive_entry *entry, size_t *namelength, size_t *name_pad) -{ - const void *h; - const unsigned char *header; - - a->archive.archive_format = ARCHIVE_FORMAT_CPIO_BIN_LE; - a->archive.archive_format_name = "cpio (little-endian binary)"; - - /* Read fixed-size portion of header. */ - h = __archive_read_ahead(a, bin_header_size, NULL); - if (h == NULL) { - archive_set_error(&a->archive, 0, - "End of file trying to read next cpio header"); - return (ARCHIVE_FATAL); - } - - /* Parse out binary fields. */ - header = (const unsigned char *)h; - - archive_entry_set_dev(entry, header[bin_dev_offset] + header[bin_dev_offset + 1] * 256); - archive_entry_set_ino(entry, header[bin_ino_offset] + header[bin_ino_offset + 1] * 256); - archive_entry_set_mode(entry, header[bin_mode_offset] + header[bin_mode_offset + 1] * 256); - if (cpio->option_pwb) { - /* turn off random bits left over from V6 inode */ - archive_entry_set_mode(entry, archive_entry_mode(entry) & 067777); - if ((archive_entry_mode(entry) & AE_IFMT) == 0) - archive_entry_set_mode(entry, archive_entry_mode(entry) | AE_IFREG); - } - archive_entry_set_uid(entry, header[bin_uid_offset] + header[bin_uid_offset + 1] * 256); - archive_entry_set_gid(entry, header[bin_gid_offset] + header[bin_gid_offset + 1] * 256); - archive_entry_set_nlink(entry, header[bin_nlink_offset] + header[bin_nlink_offset + 1] * 256); - archive_entry_set_rdev(entry, header[bin_rdev_offset] + header[bin_rdev_offset + 1] * 256); - archive_entry_set_mtime(entry, le4(header + bin_mtime_offset), 0); - *namelength = header[bin_namesize_offset] + header[bin_namesize_offset + 1] * 256; - *name_pad = *namelength & 1; /* Pad to even. */ - - cpio->entry_bytes_remaining = le4(header + bin_filesize_offset); - archive_entry_set_size(entry, cpio->entry_bytes_remaining); - cpio->entry_padding = cpio->entry_bytes_remaining & 1; /* Pad to even. */ - __archive_read_consume(a, bin_header_size); - return (ARCHIVE_OK); -} - -static int -header_bin_be(struct archive_read *a, struct cpio *cpio, - struct archive_entry *entry, size_t *namelength, size_t *name_pad) -{ - const void *h; - const unsigned char *header; - - a->archive.archive_format = ARCHIVE_FORMAT_CPIO_BIN_BE; - a->archive.archive_format_name = "cpio (big-endian binary)"; - - /* Read fixed-size portion of header. */ - h = __archive_read_ahead(a, bin_header_size, NULL); - if (h == NULL) { - archive_set_error(&a->archive, 0, - "End of file trying to read next cpio header"); - return (ARCHIVE_FATAL); - } - - /* Parse out binary fields. */ - header = (const unsigned char *)h; - - archive_entry_set_dev(entry, header[bin_dev_offset] * 256 + header[bin_dev_offset + 1]); - archive_entry_set_ino(entry, header[bin_ino_offset] * 256 + header[bin_ino_offset + 1]); - archive_entry_set_mode(entry, header[bin_mode_offset] * 256 + header[bin_mode_offset + 1]); - if (cpio->option_pwb) { - /* turn off random bits left over from V6 inode */ - archive_entry_set_mode(entry, archive_entry_mode(entry) & 067777); - if ((archive_entry_mode(entry) & AE_IFMT) == 0) - archive_entry_set_mode(entry, archive_entry_mode(entry) | AE_IFREG); - } - archive_entry_set_uid(entry, header[bin_uid_offset] * 256 + header[bin_uid_offset + 1]); - archive_entry_set_gid(entry, header[bin_gid_offset] * 256 + header[bin_gid_offset + 1]); - archive_entry_set_nlink(entry, header[bin_nlink_offset] * 256 + header[bin_nlink_offset + 1]); - archive_entry_set_rdev(entry, header[bin_rdev_offset] * 256 + header[bin_rdev_offset + 1]); - archive_entry_set_mtime(entry, be4(header + bin_mtime_offset), 0); - *namelength = header[bin_namesize_offset] * 256 + header[bin_namesize_offset + 1]; - *name_pad = *namelength & 1; /* Pad to even. */ - - cpio->entry_bytes_remaining = be4(header + bin_filesize_offset); - archive_entry_set_size(entry, cpio->entry_bytes_remaining); - cpio->entry_padding = cpio->entry_bytes_remaining & 1; /* Pad to even. */ - __archive_read_consume(a, bin_header_size); - return (ARCHIVE_OK); -} - -static int -archive_read_format_cpio_cleanup(struct archive_read *a) -{ - struct cpio *cpio; - - cpio = (struct cpio *)(a->format->data); - /* Free inode->name map */ - while (cpio->links_head != NULL) { - struct links_entry *lp = cpio->links_head->next; - - free(cpio->links_head->name); - free(cpio->links_head); - cpio->links_head = lp; - } - free(cpio); - (a->format->data) = NULL; - return (ARCHIVE_OK); -} - -static int64_t -le4(const unsigned char *p) -{ - return ((p[0] << 16) | (((int64_t)p[1]) << 24) | (p[2] << 0) | (p[3] << 8)); -} - - -static int64_t -be4(const unsigned char *p) -{ - return ((((int64_t)p[0]) << 24) | (p[1] << 16) | (p[2] << 8) | (p[3])); -} - -/* - * Note that this implementation does not (and should not!) obey - * locale settings; you cannot simply substitute strtol here, since - * it does obey locale. - */ -static int64_t -atol8(const char *p, unsigned char_cnt) -{ - int64_t l; - int digit; - - l = 0; - while (char_cnt-- > 0) { - if (*p >= '0' && *p <= '7') - digit = *p - '0'; - else - return (l); - p++; - l <<= 3; - l |= digit; - } - return (l); -} - -static int64_t -atol16(const char *p, unsigned char_cnt) -{ - int64_t l; - int digit; - - l = 0; - while (char_cnt-- > 0) { - if (*p >= 'a' && *p <= 'f') - digit = *p - 'a' + 10; - else if (*p >= 'A' && *p <= 'F') - digit = *p - 'A' + 10; - else if (*p >= '0' && *p <= '9') - digit = *p - '0'; - else - return (l); - p++; - l <<= 4; - l |= digit; - } - return (l); -} - -static int -record_hardlink(struct archive_read *a, - struct cpio *cpio, struct archive_entry *entry) -{ - struct links_entry *le; - dev_t dev; - int64_t ino; - - if (archive_entry_nlink(entry) <= 1) - return (ARCHIVE_OK); - - dev = archive_entry_dev(entry); - ino = archive_entry_ino64(entry); - - /* - * First look in the list of multiply-linked files. If we've - * already dumped it, convert this entry to a hard link entry. - */ - for (le = cpio->links_head; le; le = le->next) { - if (le->dev == dev && le->ino == ino) { - archive_entry_copy_hardlink(entry, le->name); - - if (--le->links <= 0) { - if (le->previous != NULL) - le->previous->next = le->next; - if (le->next != NULL) - le->next->previous = le->previous; - if (cpio->links_head == le) - cpio->links_head = le->next; - free(le->name); - free(le); - } - - return (ARCHIVE_OK); - } - } - - le = (struct links_entry *)malloc(sizeof(struct links_entry)); - if (le == NULL) { - archive_set_error(&a->archive, - ENOMEM, "Out of memory adding file to list"); - return (ARCHIVE_FATAL); - } - if (cpio->links_head != NULL) - cpio->links_head->previous = le; - le->next = cpio->links_head; - le->previous = NULL; - cpio->links_head = le; - le->dev = dev; - le->ino = ino; - le->links = archive_entry_nlink(entry) - 1; - le->name = strdup(archive_entry_pathname(entry)); - if (le->name == NULL) { - archive_set_error(&a->archive, - ENOMEM, "Out of memory adding file to list"); - return (ARCHIVE_FATAL); - } - - return (ARCHIVE_OK); -} diff --git a/thirdparty/libarchive/libarchive/archive_read_support_format_empty.c b/thirdparty/libarchive/libarchive/archive_read_support_format_empty.c deleted file mode 100644 index 53fb6cc47..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_format_empty.c +++ /dev/null @@ -1,96 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_empty.c 191524 2009-04-26 18:24:14Z kientzle $"); - -#include "archive.h" -#include "archive_entry.h" -#include "archive_private.h" -#include "archive_read_private.h" - -static int archive_read_format_empty_bid(struct archive_read *, int); -static int archive_read_format_empty_read_data(struct archive_read *, - const void **, size_t *, int64_t *); -static int archive_read_format_empty_read_header(struct archive_read *, - struct archive_entry *); -int -archive_read_support_format_empty(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - int r; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_format_empty"); - - r = __archive_read_register_format(a, - NULL, - "empty", - archive_read_format_empty_bid, - NULL, - archive_read_format_empty_read_header, - archive_read_format_empty_read_data, - NULL, - NULL, - NULL, - NULL, - NULL); - - return (r); -} - - -static int -archive_read_format_empty_bid(struct archive_read *a, int best_bid) -{ - if (best_bid < 1 && __archive_read_ahead(a, 1, NULL) == NULL) - return (1); - return (-1); -} - -static int -archive_read_format_empty_read_header(struct archive_read *a, - struct archive_entry *entry) -{ - (void)a; /* UNUSED */ - (void)entry; /* UNUSED */ - - a->archive.archive_format = ARCHIVE_FORMAT_EMPTY; - a->archive.archive_format_name = "Empty file"; - - return (ARCHIVE_EOF); -} - -static int -archive_read_format_empty_read_data(struct archive_read *a, - const void **buff, size_t *size, int64_t *offset) -{ - (void)a; /* UNUSED */ - (void)buff; /* UNUSED */ - (void)size; /* UNUSED */ - (void)offset; /* UNUSED */ - - return (ARCHIVE_EOF); -} diff --git a/thirdparty/libarchive/libarchive/archive_read_support_format_iso9660.c b/thirdparty/libarchive/libarchive/archive_read_support_format_iso9660.c deleted file mode 100644 index f5414be2a..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_format_iso9660.c +++ /dev/null @@ -1,3279 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2009 Andreas Henriksson - * Copyright (c) 2009-2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_iso9660.c 201246 2009-12-30 05:30:35Z kientzle $"); - -#ifdef HAVE_ERRNO_H -#include -#endif -/* #include */ /* See archive_platform.h */ -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#include -#ifdef HAVE_ZLIB_H -#include -#endif - -#include "archive.h" -#include "archive_endian.h" -#include "archive_entry.h" -#include "archive_entry_locale.h" -#include "archive_private.h" -#include "archive_read_private.h" -#include "archive_string.h" - -/* - * An overview of ISO 9660 format: - * - * Each disk is laid out as follows: - * * 32k reserved for private use - * * Volume descriptor table. Each volume descriptor - * is 2k and specifies basic format information. - * The "Primary Volume Descriptor" (PVD) is defined by the - * standard and should always be present; other volume - * descriptors include various vendor-specific extensions. - * * Files and directories. Each file/dir is specified by - * an "extent" (starting sector and length in bytes). - * Dirs are just files with directory records packed one - * after another. The PVD contains a single dir entry - * specifying the location of the root directory. Everything - * else follows from there. - * - * This module works by first reading the volume descriptors, then - * building a list of directory entries, sorted by starting - * sector. At each step, I look for the earliest dir entry that - * hasn't yet been read, seek forward to that location and read - * that entry. If it's a dir, I slurp in the new dir entries and - * add them to the heap; if it's a regular file, I return the - * corresponding archive_entry and wait for the client to request - * the file body. This strategy allows us to read most compliant - * CDs with a single pass through the data, as required by libarchive. - */ -#define LOGICAL_BLOCK_SIZE 2048 -#define SYSTEM_AREA_BLOCK 16 - -/* Structure of on-disk primary volume descriptor. */ -#define PVD_type_offset 0 -#define PVD_type_size 1 -#define PVD_id_offset (PVD_type_offset + PVD_type_size) -#define PVD_id_size 5 -#define PVD_version_offset (PVD_id_offset + PVD_id_size) -#define PVD_version_size 1 -#define PVD_reserved1_offset (PVD_version_offset + PVD_version_size) -#define PVD_reserved1_size 1 -#define PVD_system_id_offset (PVD_reserved1_offset + PVD_reserved1_size) -#define PVD_system_id_size 32 -#define PVD_volume_id_offset (PVD_system_id_offset + PVD_system_id_size) -#define PVD_volume_id_size 32 -#define PVD_reserved2_offset (PVD_volume_id_offset + PVD_volume_id_size) -#define PVD_reserved2_size 8 -#define PVD_volume_space_size_offset (PVD_reserved2_offset + PVD_reserved2_size) -#define PVD_volume_space_size_size 8 -#define PVD_reserved3_offset (PVD_volume_space_size_offset + PVD_volume_space_size_size) -#define PVD_reserved3_size 32 -#define PVD_volume_set_size_offset (PVD_reserved3_offset + PVD_reserved3_size) -#define PVD_volume_set_size_size 4 -#define PVD_volume_sequence_number_offset (PVD_volume_set_size_offset + PVD_volume_set_size_size) -#define PVD_volume_sequence_number_size 4 -#define PVD_logical_block_size_offset (PVD_volume_sequence_number_offset + PVD_volume_sequence_number_size) -#define PVD_logical_block_size_size 4 -#define PVD_path_table_size_offset (PVD_logical_block_size_offset + PVD_logical_block_size_size) -#define PVD_path_table_size_size 8 -#define PVD_type_1_path_table_offset (PVD_path_table_size_offset + PVD_path_table_size_size) -#define PVD_type_1_path_table_size 4 -#define PVD_opt_type_1_path_table_offset (PVD_type_1_path_table_offset + PVD_type_1_path_table_size) -#define PVD_opt_type_1_path_table_size 4 -#define PVD_type_m_path_table_offset (PVD_opt_type_1_path_table_offset + PVD_opt_type_1_path_table_size) -#define PVD_type_m_path_table_size 4 -#define PVD_opt_type_m_path_table_offset (PVD_type_m_path_table_offset + PVD_type_m_path_table_size) -#define PVD_opt_type_m_path_table_size 4 -#define PVD_root_directory_record_offset (PVD_opt_type_m_path_table_offset + PVD_opt_type_m_path_table_size) -#define PVD_root_directory_record_size 34 -#define PVD_volume_set_id_offset (PVD_root_directory_record_offset + PVD_root_directory_record_size) -#define PVD_volume_set_id_size 128 -#define PVD_publisher_id_offset (PVD_volume_set_id_offset + PVD_volume_set_id_size) -#define PVD_publisher_id_size 128 -#define PVD_preparer_id_offset (PVD_publisher_id_offset + PVD_publisher_id_size) -#define PVD_preparer_id_size 128 -#define PVD_application_id_offset (PVD_preparer_id_offset + PVD_preparer_id_size) -#define PVD_application_id_size 128 -#define PVD_copyright_file_id_offset (PVD_application_id_offset + PVD_application_id_size) -#define PVD_copyright_file_id_size 37 -#define PVD_abstract_file_id_offset (PVD_copyright_file_id_offset + PVD_copyright_file_id_size) -#define PVD_abstract_file_id_size 37 -#define PVD_bibliographic_file_id_offset (PVD_abstract_file_id_offset + PVD_abstract_file_id_size) -#define PVD_bibliographic_file_id_size 37 -#define PVD_creation_date_offset (PVD_bibliographic_file_id_offset + PVD_bibliographic_file_id_size) -#define PVD_creation_date_size 17 -#define PVD_modification_date_offset (PVD_creation_date_offset + PVD_creation_date_size) -#define PVD_modification_date_size 17 -#define PVD_expiration_date_offset (PVD_modification_date_offset + PVD_modification_date_size) -#define PVD_expiration_date_size 17 -#define PVD_effective_date_offset (PVD_expiration_date_offset + PVD_expiration_date_size) -#define PVD_effective_date_size 17 -#define PVD_file_structure_version_offset (PVD_effective_date_offset + PVD_effective_date_size) -#define PVD_file_structure_version_size 1 -#define PVD_reserved4_offset (PVD_file_structure_version_offset + PVD_file_structure_version_size) -#define PVD_reserved4_size 1 -#define PVD_application_data_offset (PVD_reserved4_offset + PVD_reserved4_size) -#define PVD_application_data_size 512 -#define PVD_reserved5_offset (PVD_application_data_offset + PVD_application_data_size) -#define PVD_reserved5_size (2048 - PVD_reserved5_offset) - -/* TODO: It would make future maintenance easier to just hardcode the - * above values. In particular, ECMA119 states the offsets as part of - * the standard. That would eliminate the need for the following check.*/ -#if PVD_reserved5_offset != 1395 -#error PVD offset and size definitions are wrong. -#endif - - -/* Structure of optional on-disk supplementary volume descriptor. */ -#define SVD_type_offset 0 -#define SVD_type_size 1 -#define SVD_id_offset (SVD_type_offset + SVD_type_size) -#define SVD_id_size 5 -#define SVD_version_offset (SVD_id_offset + SVD_id_size) -#define SVD_version_size 1 -/* ... */ -#define SVD_reserved1_offset 72 -#define SVD_reserved1_size 8 -#define SVD_volume_space_size_offset 80 -#define SVD_volume_space_size_size 8 -#define SVD_escape_sequences_offset (SVD_volume_space_size_offset + SVD_volume_space_size_size) -#define SVD_escape_sequences_size 32 -/* ... */ -#define SVD_logical_block_size_offset 128 -#define SVD_logical_block_size_size 4 -#define SVD_type_L_path_table_offset 140 -#define SVD_type_M_path_table_offset 148 -/* ... */ -#define SVD_root_directory_record_offset 156 -#define SVD_root_directory_record_size 34 -#define SVD_file_structure_version_offset 881 -#define SVD_reserved2_offset 882 -#define SVD_reserved2_size 1 -#define SVD_reserved3_offset 1395 -#define SVD_reserved3_size 653 -/* ... */ -/* FIXME: validate correctness of last SVD entry offset. */ - -/* Structure of an on-disk directory record. */ -/* Note: ISO9660 stores each multi-byte integer twice, once in - * each byte order. The sizes here are the size of just one - * of the two integers. (This is why the offset of a field isn't - * the same as the offset+size of the previous field.) */ -#define DR_length_offset 0 -#define DR_length_size 1 -#define DR_ext_attr_length_offset 1 -#define DR_ext_attr_length_size 1 -#define DR_extent_offset 2 -#define DR_extent_size 4 -#define DR_size_offset 10 -#define DR_size_size 4 -#define DR_date_offset 18 -#define DR_date_size 7 -#define DR_flags_offset 25 -#define DR_flags_size 1 -#define DR_file_unit_size_offset 26 -#define DR_file_unit_size_size 1 -#define DR_interleave_offset 27 -#define DR_interleave_size 1 -#define DR_volume_sequence_number_offset 28 -#define DR_volume_sequence_number_size 2 -#define DR_name_len_offset 32 -#define DR_name_len_size 1 -#define DR_name_offset 33 - -#ifdef HAVE_ZLIB_H -static const unsigned char zisofs_magic[8] = { - 0x37, 0xE4, 0x53, 0x96, 0xC9, 0xDB, 0xD6, 0x07 -}; - -struct zisofs { - /* Set 1 if this file compressed by paged zlib */ - int pz; - int pz_log2_bs; /* Log2 of block size */ - uint64_t pz_uncompressed_size; - - int initialized; - unsigned char *uncompressed_buffer; - size_t uncompressed_buffer_size; - - uint32_t pz_offset; - unsigned char header[16]; - size_t header_avail; - int header_passed; - unsigned char *block_pointers; - size_t block_pointers_alloc; - size_t block_pointers_size; - size_t block_pointers_avail; - size_t block_off; - uint32_t block_avail; - - z_stream stream; - int stream_valid; -}; -#else -struct zisofs { - /* Set 1 if this file compressed by paged zlib */ - int pz; -}; -#endif - -struct content { - uint64_t offset;/* Offset on disk. */ - uint64_t size; /* File size in bytes. */ - struct content *next; -}; - -/* In-memory storage for a directory record. */ -struct file_info { - struct file_info *use_next; - struct file_info *parent; - struct file_info *next; - struct file_info *re_next; - int subdirs; - uint64_t key; /* Heap Key. */ - uint64_t offset; /* Offset on disk. */ - uint64_t size; /* File size in bytes. */ - uint32_t ce_offset; /* Offset of CE. */ - uint32_t ce_size; /* Size of CE. */ - char rr_moved; /* Flag to rr_moved. */ - char rr_moved_has_re_only; - char re; /* Having RRIP "RE" extension. */ - char re_descendant; - uint64_t cl_offset; /* Having RRIP "CL" extension. */ - int birthtime_is_set; - time_t birthtime; /* File created time. */ - time_t mtime; /* File last modified time. */ - time_t atime; /* File last accessed time. */ - time_t ctime; /* File attribute change time. */ - uint64_t rdev; /* Device number. */ - mode_t mode; - uid_t uid; - gid_t gid; - int64_t number; - int nlinks; - struct archive_string name; /* Pathname */ - unsigned char *utf16be_name; - size_t utf16be_bytes; - char name_continues; /* Non-zero if name continues */ - struct archive_string symlink; - char symlink_continues; /* Non-zero if link continues */ - /* Set 1 if this file compressed by paged zlib(zisofs) */ - int pz; - int pz_log2_bs; /* Log2 of block size */ - uint64_t pz_uncompressed_size; - /* Set 1 if this file is multi extent. */ - int multi_extent; - struct { - struct content *first; - struct content **last; - } contents; - struct { - struct file_info *first; - struct file_info **last; - } rede_files; -}; - -struct heap_queue { - struct file_info **files; - int allocated; - int used; -}; - -struct iso9660 { - int magic; -#define ISO9660_MAGIC 0x96609660 - - int opt_support_joliet; - int opt_support_rockridge; - - struct archive_string pathname; - char seenRockridge; /* Set true if RR extensions are used. */ - char seenSUSP; /* Set true if SUSP is being used. */ - char seenJoliet; - - unsigned char suspOffset; - struct file_info *rr_moved; - struct read_ce_queue { - struct read_ce_req { - uint64_t offset;/* Offset of CE on disk. */ - struct file_info *file; - } *reqs; - int cnt; - int allocated; - } read_ce_req; - - int64_t previous_number; - struct archive_string previous_pathname; - - struct file_info *use_files; - struct heap_queue pending_files; - struct { - struct file_info *first; - struct file_info **last; - } cache_files; - struct { - struct file_info *first; - struct file_info **last; - } re_files; - - uint64_t current_position; - ssize_t logical_block_size; - uint64_t volume_size; /* Total size of volume in bytes. */ - int32_t volume_block;/* Total size of volume in logical blocks. */ - - struct vd { - int location; /* Location of Extent. */ - uint32_t size; - } primary, joliet; - - int64_t entry_sparse_offset; - int64_t entry_bytes_remaining; - size_t entry_bytes_unconsumed; - struct zisofs entry_zisofs; - struct content *entry_content; - struct archive_string_conv *sconv_utf16be; - /* - * Buffers for a full pathname in UTF-16BE in Joliet extensions. - */ -#define UTF16_NAME_MAX 1024 - unsigned char *utf16be_path; - size_t utf16be_path_len; - unsigned char *utf16be_previous_path; - size_t utf16be_previous_path_len; - /* Null buffer used in bidder to improve its performance. */ - unsigned char null[2048]; -}; - -static int archive_read_format_iso9660_bid(struct archive_read *, int); -static int archive_read_format_iso9660_options(struct archive_read *, - const char *, const char *); -static int archive_read_format_iso9660_cleanup(struct archive_read *); -static int archive_read_format_iso9660_read_data(struct archive_read *, - const void **, size_t *, int64_t *); -static int archive_read_format_iso9660_read_data_skip(struct archive_read *); -static int archive_read_format_iso9660_read_header(struct archive_read *, - struct archive_entry *); -static const char *build_pathname(struct archive_string *, struct file_info *, int); -static int build_pathname_utf16be(unsigned char *, size_t, size_t *, - struct file_info *); -#if DEBUG -static void dump_isodirrec(FILE *, const unsigned char *isodirrec); -#endif -static time_t time_from_tm(struct tm *); -static time_t isodate17(const unsigned char *); -static time_t isodate7(const unsigned char *); -static int isBootRecord(struct iso9660 *, const unsigned char *); -static int isVolumePartition(struct iso9660 *, const unsigned char *); -static int isVDSetTerminator(struct iso9660 *, const unsigned char *); -static int isJolietSVD(struct iso9660 *, const unsigned char *); -static int isSVD(struct iso9660 *, const unsigned char *); -static int isEVD(struct iso9660 *, const unsigned char *); -static int isPVD(struct iso9660 *, const unsigned char *); -static int next_cache_entry(struct archive_read *, struct iso9660 *, - struct file_info **); -static int next_entry_seek(struct archive_read *, struct iso9660 *, - struct file_info **); -static struct file_info * - parse_file_info(struct archive_read *a, - struct file_info *parent, const unsigned char *isodirrec, - size_t reclen); -static int parse_rockridge(struct archive_read *a, - struct file_info *file, const unsigned char *start, - const unsigned char *end); -static int register_CE(struct archive_read *a, int32_t location, - struct file_info *file); -static int read_CE(struct archive_read *a, struct iso9660 *iso9660); -static void parse_rockridge_NM1(struct file_info *, - const unsigned char *, int); -static void parse_rockridge_SL1(struct file_info *, - const unsigned char *, int); -static void parse_rockridge_TF1(struct file_info *, - const unsigned char *, int); -static void parse_rockridge_ZF1(struct file_info *, - const unsigned char *, int); -static void register_file(struct iso9660 *, struct file_info *); -static void release_files(struct iso9660 *); -static unsigned toi(const void *p, int n); -static inline void re_add_entry(struct iso9660 *, struct file_info *); -static inline struct file_info * re_get_entry(struct iso9660 *); -static inline int rede_add_entry(struct file_info *); -static inline struct file_info * rede_get_entry(struct file_info *); -static inline void cache_add_entry(struct iso9660 *iso9660, - struct file_info *file); -static inline struct file_info *cache_get_entry(struct iso9660 *iso9660); -static int heap_add_entry(struct archive_read *a, struct heap_queue *heap, - struct file_info *file, uint64_t key); -static struct file_info *heap_get_entry(struct heap_queue *heap); - -#define add_entry(arch, iso9660, file) \ - heap_add_entry(arch, &((iso9660)->pending_files), file, file->offset) -#define next_entry(iso9660) \ - heap_get_entry(&((iso9660)->pending_files)) - -int -archive_read_support_format_iso9660(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - struct iso9660 *iso9660; - int r; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_format_iso9660"); - - iso9660 = (struct iso9660 *)calloc(1, sizeof(*iso9660)); - if (iso9660 == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate iso9660 data"); - return (ARCHIVE_FATAL); - } - iso9660->magic = ISO9660_MAGIC; - iso9660->cache_files.first = NULL; - iso9660->cache_files.last = &(iso9660->cache_files.first); - iso9660->re_files.first = NULL; - iso9660->re_files.last = &(iso9660->re_files.first); - /* Enable to support Joliet extensions by default. */ - iso9660->opt_support_joliet = 1; - /* Enable to support Rock Ridge extensions by default. */ - iso9660->opt_support_rockridge = 1; - - r = __archive_read_register_format(a, - iso9660, - "iso9660", - archive_read_format_iso9660_bid, - archive_read_format_iso9660_options, - archive_read_format_iso9660_read_header, - archive_read_format_iso9660_read_data, - archive_read_format_iso9660_read_data_skip, - NULL, - archive_read_format_iso9660_cleanup, - NULL, - NULL); - - if (r != ARCHIVE_OK) { - free(iso9660); - return (r); - } - return (ARCHIVE_OK); -} - - -static int -archive_read_format_iso9660_bid(struct archive_read *a, int best_bid) -{ - struct iso9660 *iso9660; - ssize_t bytes_read; - const unsigned char *p; - int seenTerminator; - - /* If there's already a better bid than we can ever - make, don't bother testing. */ - if (best_bid > 48) - return (-1); - - iso9660 = (struct iso9660 *)(a->format->data); - - /* - * Skip the first 32k (reserved area) and get the first - * 8 sectors of the volume descriptor table. Of course, - * if the I/O layer gives us more, we'll take it. - */ -#define RESERVED_AREA (SYSTEM_AREA_BLOCK * LOGICAL_BLOCK_SIZE) - p = __archive_read_ahead(a, - RESERVED_AREA + 8 * LOGICAL_BLOCK_SIZE, - &bytes_read); - if (p == NULL) - return (-1); - - /* Skip the reserved area. */ - bytes_read -= RESERVED_AREA; - p += RESERVED_AREA; - - /* Check each volume descriptor. */ - seenTerminator = 0; - for (; bytes_read > LOGICAL_BLOCK_SIZE; - bytes_read -= LOGICAL_BLOCK_SIZE, p += LOGICAL_BLOCK_SIZE) { - /* Do not handle undefined Volume Descriptor Type. */ - if (p[0] >= 4 && p[0] <= 254) - return (0); - /* Standard Identifier must be "CD001" */ - if (memcmp(p + 1, "CD001", 5) != 0) - return (0); - if (isPVD(iso9660, p)) - continue; - if (!iso9660->joliet.location) { - if (isJolietSVD(iso9660, p)) - continue; - } - if (isBootRecord(iso9660, p)) - continue; - if (isEVD(iso9660, p)) - continue; - if (isSVD(iso9660, p)) - continue; - if (isVolumePartition(iso9660, p)) - continue; - if (isVDSetTerminator(iso9660, p)) { - seenTerminator = 1; - break; - } - return (0); - } - /* - * ISO 9660 format must have Primary Volume Descriptor and - * Volume Descriptor Set Terminator. - */ - if (seenTerminator && iso9660->primary.location > 16) - return (48); - - /* We didn't find a valid PVD; return a bid of zero. */ - return (0); -} - -static int -archive_read_format_iso9660_options(struct archive_read *a, - const char *key, const char *val) -{ - struct iso9660 *iso9660; - - iso9660 = (struct iso9660 *)(a->format->data); - - if (strcmp(key, "joliet") == 0) { - if (val == NULL || strcmp(val, "off") == 0 || - strcmp(val, "ignore") == 0 || - strcmp(val, "disable") == 0 || - strcmp(val, "0") == 0) - iso9660->opt_support_joliet = 0; - else - iso9660->opt_support_joliet = 1; - return (ARCHIVE_OK); - } - if (strcmp(key, "rockridge") == 0 || - strcmp(key, "Rockridge") == 0) { - iso9660->opt_support_rockridge = val != NULL; - return (ARCHIVE_OK); - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -static int -isNull(struct iso9660 *iso9660, const unsigned char *h, unsigned offset, -unsigned bytes) -{ - - while (bytes >= sizeof(iso9660->null)) { - if (!memcmp(iso9660->null, h + offset, sizeof(iso9660->null))) - return (0); - offset += sizeof(iso9660->null); - bytes -= sizeof(iso9660->null); - } - if (bytes) - return memcmp(iso9660->null, h + offset, bytes) == 0; - else - return (1); -} - -static int -isBootRecord(struct iso9660 *iso9660, const unsigned char *h) -{ - (void)iso9660; /* UNUSED */ - - /* Type of the Volume Descriptor Boot Record must be 0. */ - if (h[0] != 0) - return (0); - - /* Volume Descriptor Version must be 1. */ - if (h[6] != 1) - return (0); - - return (1); -} - -static int -isVolumePartition(struct iso9660 *iso9660, const unsigned char *h) -{ - int32_t location; - - /* Type of the Volume Partition Descriptor must be 3. */ - if (h[0] != 3) - return (0); - - /* Volume Descriptor Version must be 1. */ - if (h[6] != 1) - return (0); - /* Unused Field */ - if (h[7] != 0) - return (0); - - location = archive_le32dec(h + 72); - if (location <= SYSTEM_AREA_BLOCK || - location >= iso9660->volume_block) - return (0); - if ((uint32_t)location != archive_be32dec(h + 76)) - return (0); - - return (1); -} - -static int -isVDSetTerminator(struct iso9660 *iso9660, const unsigned char *h) -{ - (void)iso9660; /* UNUSED */ - - /* Type of the Volume Descriptor Set Terminator must be 255. */ - if (h[0] != 255) - return (0); - - /* Volume Descriptor Version must be 1. */ - if (h[6] != 1) - return (0); - - /* Reserved field must be 0. */ - if (!isNull(iso9660, h, 7, 2048-7)) - return (0); - - return (1); -} - -static int -isJolietSVD(struct iso9660 *iso9660, const unsigned char *h) -{ - const unsigned char *p; - ssize_t logical_block_size; - int32_t volume_block; - - /* Check if current sector is a kind of Supplementary Volume - * Descriptor. */ - if (!isSVD(iso9660, h)) - return (0); - - /* FIXME: do more validations according to joliet spec. */ - - /* check if this SVD contains joliet extension! */ - p = h + SVD_escape_sequences_offset; - /* N.B. Joliet spec says p[1] == '\\', but.... */ - if (p[0] == '%' && p[1] == '/') { - int level = 0; - - if (p[2] == '@') - level = 1; - else if (p[2] == 'C') - level = 2; - else if (p[2] == 'E') - level = 3; - else /* not joliet */ - return (0); - - iso9660->seenJoliet = level; - - } else /* not joliet */ - return (0); - - logical_block_size = - archive_le16dec(h + SVD_logical_block_size_offset); - volume_block = archive_le32dec(h + SVD_volume_space_size_offset); - - iso9660->logical_block_size = logical_block_size; - iso9660->volume_block = volume_block; - iso9660->volume_size = logical_block_size * (uint64_t)volume_block; - /* Read Root Directory Record in Volume Descriptor. */ - p = h + SVD_root_directory_record_offset; - iso9660->joliet.location = archive_le32dec(p + DR_extent_offset); - iso9660->joliet.size = archive_le32dec(p + DR_size_offset); - - return (48); -} - -static int -isSVD(struct iso9660 *iso9660, const unsigned char *h) -{ - const unsigned char *p; - ssize_t logical_block_size; - int32_t volume_block; - int32_t location; - - (void)iso9660; /* UNUSED */ - - /* Type 2 means it's a SVD. */ - if (h[SVD_type_offset] != 2) - return (0); - - /* Reserved field must be 0. */ - if (!isNull(iso9660, h, SVD_reserved1_offset, SVD_reserved1_size)) - return (0); - if (!isNull(iso9660, h, SVD_reserved2_offset, SVD_reserved2_size)) - return (0); - if (!isNull(iso9660, h, SVD_reserved3_offset, SVD_reserved3_size)) - return (0); - - /* File structure version must be 1 for ISO9660/ECMA119. */ - if (h[SVD_file_structure_version_offset] != 1) - return (0); - - logical_block_size = - archive_le16dec(h + SVD_logical_block_size_offset); - if (logical_block_size <= 0) - return (0); - - volume_block = archive_le32dec(h + SVD_volume_space_size_offset); - if (volume_block <= SYSTEM_AREA_BLOCK+4) - return (0); - - /* Location of Occurrence of Type L Path Table must be - * available location, - * >= SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */ - location = archive_le32dec(h+SVD_type_L_path_table_offset); - if (location < SYSTEM_AREA_BLOCK+2 || location >= volume_block) - return (0); - - /* The Type M Path Table must be at a valid location (WinISO - * and probably other programs omit this, so we allow zero) - * - * >= SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */ - location = archive_be32dec(h+SVD_type_M_path_table_offset); - if ((location > 0 && location < SYSTEM_AREA_BLOCK+2) - || location >= volume_block) - return (0); - - /* Read Root Directory Record in Volume Descriptor. */ - p = h + SVD_root_directory_record_offset; - if (p[DR_length_offset] != 34) - return (0); - - return (48); -} - -static int -isEVD(struct iso9660 *iso9660, const unsigned char *h) -{ - const unsigned char *p; - ssize_t logical_block_size; - int32_t volume_block; - int32_t location; - - (void)iso9660; /* UNUSED */ - - /* Type of the Enhanced Volume Descriptor must be 2. */ - if (h[PVD_type_offset] != 2) - return (0); - - /* EVD version must be 2. */ - if (h[PVD_version_offset] != 2) - return (0); - - /* Reserved field must be 0. */ - if (h[PVD_reserved1_offset] != 0) - return (0); - - /* Reserved field must be 0. */ - if (!isNull(iso9660, h, PVD_reserved2_offset, PVD_reserved2_size)) - return (0); - - /* Reserved field must be 0. */ - if (!isNull(iso9660, h, PVD_reserved3_offset, PVD_reserved3_size)) - return (0); - - /* Logical block size must be > 0. */ - /* I've looked at Ecma 119 and can't find any stronger - * restriction on this field. */ - logical_block_size = - archive_le16dec(h + PVD_logical_block_size_offset); - if (logical_block_size <= 0) - return (0); - - volume_block = - archive_le32dec(h + PVD_volume_space_size_offset); - if (volume_block <= SYSTEM_AREA_BLOCK+4) - return (0); - - /* File structure version must be 2 for ISO9660:1999. */ - if (h[PVD_file_structure_version_offset] != 2) - return (0); - - /* Location of Occurrence of Type L Path Table must be - * available location, - * >= SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */ - location = archive_le32dec(h+PVD_type_1_path_table_offset); - if (location < SYSTEM_AREA_BLOCK+2 || location >= volume_block) - return (0); - - /* Location of Occurrence of Type M Path Table must be - * available location, - * >= SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */ - location = archive_be32dec(h+PVD_type_m_path_table_offset); - if ((location > 0 && location < SYSTEM_AREA_BLOCK+2) - || location >= volume_block) - return (0); - - /* Reserved field must be 0. */ - if (!isNull(iso9660, h, PVD_reserved4_offset, PVD_reserved4_size)) - return (0); - - /* Reserved field must be 0. */ - if (!isNull(iso9660, h, PVD_reserved5_offset, PVD_reserved5_size)) - return (0); - - /* Read Root Directory Record in Volume Descriptor. */ - p = h + PVD_root_directory_record_offset; - if (p[DR_length_offset] != 34) - return (0); - - return (48); -} - -static int -isPVD(struct iso9660 *iso9660, const unsigned char *h) -{ - const unsigned char *p; - ssize_t logical_block_size; - int32_t volume_block; - int32_t location; - int i; - - /* Type of the Primary Volume Descriptor must be 1. */ - if (h[PVD_type_offset] != 1) - return (0); - - /* PVD version must be 1. */ - if (h[PVD_version_offset] != 1) - return (0); - - /* Reserved field must be 0. */ - if (h[PVD_reserved1_offset] != 0) - return (0); - - /* Reserved field must be 0. */ - if (!isNull(iso9660, h, PVD_reserved2_offset, PVD_reserved2_size)) - return (0); - - /* Reserved field must be 0. */ - if (!isNull(iso9660, h, PVD_reserved3_offset, PVD_reserved3_size)) - return (0); - - /* Logical block size must be > 0. */ - /* I've looked at Ecma 119 and can't find any stronger - * restriction on this field. */ - logical_block_size = - archive_le16dec(h + PVD_logical_block_size_offset); - if (logical_block_size <= 0) - return (0); - - volume_block = archive_le32dec(h + PVD_volume_space_size_offset); - if (volume_block <= SYSTEM_AREA_BLOCK+4) - return (0); - - /* File structure version must be 1 for ISO9660/ECMA119. */ - if (h[PVD_file_structure_version_offset] != 1) - return (0); - - /* Location of Occurrence of Type L Path Table must be - * available location, - * > SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */ - location = archive_le32dec(h+PVD_type_1_path_table_offset); - if (location < SYSTEM_AREA_BLOCK+2 || location >= volume_block) - return (0); - - /* The Type M Path Table must also be at a valid location - * (although ECMA 119 requires a Type M Path Table, WinISO and - * probably other programs omit it, so we permit a zero here) - * - * >= SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */ - location = archive_be32dec(h+PVD_type_m_path_table_offset); - if ((location > 0 && location < SYSTEM_AREA_BLOCK+2) - || location >= volume_block) - return (0); - - /* Reserved field must be 0. */ - /* But accept NetBSD/FreeBSD "makefs" images with 0x20 here. */ - for (i = 0; i < PVD_reserved4_size; ++i) - if (h[PVD_reserved4_offset + i] != 0 - && h[PVD_reserved4_offset + i] != 0x20) - return (0); - - /* Reserved field must be 0. */ - if (!isNull(iso9660, h, PVD_reserved5_offset, PVD_reserved5_size)) - return (0); - - /* XXX TODO: Check other values for sanity; reject more - * malformed PVDs. XXX */ - - /* Read Root Directory Record in Volume Descriptor. */ - p = h + PVD_root_directory_record_offset; - if (p[DR_length_offset] != 34) - return (0); - - if (!iso9660->primary.location) { - iso9660->logical_block_size = logical_block_size; - iso9660->volume_block = volume_block; - iso9660->volume_size = - logical_block_size * (uint64_t)volume_block; - iso9660->primary.location = - archive_le32dec(p + DR_extent_offset); - iso9660->primary.size = archive_le32dec(p + DR_size_offset); - } - - return (48); -} - -static int -read_children(struct archive_read *a, struct file_info *parent) -{ - struct iso9660 *iso9660; - const unsigned char *b, *p; - struct file_info *multi; - size_t step, skip_size; - - iso9660 = (struct iso9660 *)(a->format->data); - /* flush any remaining bytes from the last round to ensure - * we're positioned */ - if (iso9660->entry_bytes_unconsumed) { - __archive_read_consume(a, iso9660->entry_bytes_unconsumed); - iso9660->entry_bytes_unconsumed = 0; - } - if (iso9660->current_position > parent->offset) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Ignoring out-of-order directory (%s) %jd > %jd", - parent->name.s, - (intmax_t)iso9660->current_position, - (intmax_t)parent->offset); - return (ARCHIVE_WARN); - } - if (parent->offset + parent->size > iso9660->volume_size) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Directory is beyond end-of-media: %s", - parent->name.s); - return (ARCHIVE_WARN); - } - if (iso9660->current_position < parent->offset) { - int64_t skipsize; - - skipsize = parent->offset - iso9660->current_position; - skipsize = __archive_read_consume(a, skipsize); - if (skipsize < 0) - return ((int)skipsize); - iso9660->current_position = parent->offset; - } - - step = (size_t)(((parent->size + iso9660->logical_block_size -1) / - iso9660->logical_block_size) * iso9660->logical_block_size); - b = __archive_read_ahead(a, step, NULL); - if (b == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Failed to read full block when scanning " - "ISO9660 directory list"); - return (ARCHIVE_FATAL); - } - iso9660->current_position += step; - multi = NULL; - skip_size = step; - while (step) { - p = b; - b += iso9660->logical_block_size; - step -= iso9660->logical_block_size; - for (; *p != 0 && p + DR_name_offset < b && p + *p <= b; - p += *p) { - struct file_info *child; - - /* N.B.: these special directory identifiers - * are 8 bit "values" even on a - * Joliet CD with UCS-2 (16bit) encoding. - */ - - /* Skip '.' entry. */ - if (*(p + DR_name_len_offset) == 1 - && *(p + DR_name_offset) == '\0') - continue; - /* Skip '..' entry. */ - if (*(p + DR_name_len_offset) == 1 - && *(p + DR_name_offset) == '\001') - continue; - child = parse_file_info(a, parent, p, b - p); - if (child == NULL) { - __archive_read_consume(a, skip_size); - return (ARCHIVE_FATAL); - } - if (child->cl_offset == 0 && - (child->multi_extent || multi != NULL)) { - struct content *con; - - if (multi == NULL) { - multi = child; - multi->contents.first = NULL; - multi->contents.last = - &(multi->contents.first); - } - con = malloc(sizeof(struct content)); - if (con == NULL) { - archive_set_error( - &a->archive, ENOMEM, - "No memory for multi extent"); - __archive_read_consume(a, skip_size); - return (ARCHIVE_FATAL); - } - con->offset = child->offset; - con->size = child->size; - con->next = NULL; - *multi->contents.last = con; - multi->contents.last = &(con->next); - if (multi == child) { - if (add_entry(a, iso9660, child) - != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } else { - multi->size += child->size; - if (!child->multi_extent) - multi = NULL; - } - } else - if (add_entry(a, iso9660, child) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } - } - - __archive_read_consume(a, skip_size); - - /* Read data which recorded by RRIP "CE" extension. */ - if (read_CE(a, iso9660) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - return (ARCHIVE_OK); -} - -static int -choose_volume(struct archive_read *a, struct iso9660 *iso9660) -{ - struct file_info *file; - int64_t skipsize; - struct vd *vd; - const void *block; - char seenJoliet; - - vd = &(iso9660->primary); - if (!iso9660->opt_support_joliet) - iso9660->seenJoliet = 0; - if (iso9660->seenJoliet && - vd->location > iso9660->joliet.location) - /* This condition is unlikely; by way of caution. */ - vd = &(iso9660->joliet); - - skipsize = LOGICAL_BLOCK_SIZE * (int64_t)vd->location; - skipsize = __archive_read_consume(a, skipsize); - if (skipsize < 0) - return ((int)skipsize); - iso9660->current_position = skipsize; - - block = __archive_read_ahead(a, vd->size, NULL); - if (block == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Failed to read full block when scanning " - "ISO9660 directory list"); - return (ARCHIVE_FATAL); - } - - /* - * While reading Root Directory, flag seenJoliet must be zero to - * avoid converting special name 0x00(Current Directory) and - * next byte to UCS2. - */ - seenJoliet = iso9660->seenJoliet;/* Save flag. */ - iso9660->seenJoliet = 0; - file = parse_file_info(a, NULL, block, vd->size); - if (file == NULL) - return (ARCHIVE_FATAL); - iso9660->seenJoliet = seenJoliet; - - /* - * If the iso image has both RockRidge and Joliet, we preferentially - * use RockRidge Extensions rather than Joliet ones. - */ - if (vd == &(iso9660->primary) && iso9660->seenRockridge - && iso9660->seenJoliet) - iso9660->seenJoliet = 0; - - if (vd == &(iso9660->primary) && !iso9660->seenRockridge - && iso9660->seenJoliet) { - /* Switch reading data from primary to joliet. */ - vd = &(iso9660->joliet); - skipsize = LOGICAL_BLOCK_SIZE * (int64_t)vd->location; - skipsize -= iso9660->current_position; - skipsize = __archive_read_consume(a, skipsize); - if (skipsize < 0) - return ((int)skipsize); - iso9660->current_position += skipsize; - - block = __archive_read_ahead(a, vd->size, NULL); - if (block == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Failed to read full block when scanning " - "ISO9660 directory list"); - return (ARCHIVE_FATAL); - } - iso9660->seenJoliet = 0; - file = parse_file_info(a, NULL, block, vd->size); - if (file == NULL) - return (ARCHIVE_FATAL); - iso9660->seenJoliet = seenJoliet; - } - - /* Store the root directory in the pending list. */ - if (add_entry(a, iso9660, file) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - if (iso9660->seenRockridge) { - a->archive.archive_format = ARCHIVE_FORMAT_ISO9660_ROCKRIDGE; - a->archive.archive_format_name = - "ISO9660 with Rockridge extensions"; - } - - return (ARCHIVE_OK); -} - -static int -archive_read_format_iso9660_read_header(struct archive_read *a, - struct archive_entry *entry) -{ - struct iso9660 *iso9660; - struct file_info *file; - int r, rd_r = ARCHIVE_OK; - - iso9660 = (struct iso9660 *)(a->format->data); - - if (!a->archive.archive_format) { - a->archive.archive_format = ARCHIVE_FORMAT_ISO9660; - a->archive.archive_format_name = "ISO9660"; - } - - if (iso9660->current_position == 0) { - r = choose_volume(a, iso9660); - if (r != ARCHIVE_OK) - return (r); - } - - file = NULL;/* Eliminate a warning. */ - /* Get the next entry that appears after the current offset. */ - r = next_entry_seek(a, iso9660, &file); - if (r != ARCHIVE_OK) - return (r); - - if (iso9660->seenJoliet) { - /* - * Convert UTF-16BE of a filename to local locale MBS - * and store the result into a filename field. - */ - if (iso9660->sconv_utf16be == NULL) { - iso9660->sconv_utf16be = - archive_string_conversion_from_charset( - &(a->archive), "UTF-16BE", 1); - if (iso9660->sconv_utf16be == NULL) - /* Couldn't allocate memory */ - return (ARCHIVE_FATAL); - } - if (iso9660->utf16be_path == NULL) { - iso9660->utf16be_path = malloc(UTF16_NAME_MAX); - if (iso9660->utf16be_path == NULL) { - archive_set_error(&a->archive, ENOMEM, - "No memory"); - return (ARCHIVE_FATAL); - } - } - if (iso9660->utf16be_previous_path == NULL) { - iso9660->utf16be_previous_path = malloc(UTF16_NAME_MAX); - if (iso9660->utf16be_previous_path == NULL) { - archive_set_error(&a->archive, ENOMEM, - "No memory"); - return (ARCHIVE_FATAL); - } - } - - iso9660->utf16be_path_len = 0; - if (build_pathname_utf16be(iso9660->utf16be_path, - UTF16_NAME_MAX, &(iso9660->utf16be_path_len), file) != 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Pathname is too long"); - return (ARCHIVE_FATAL); - } - - r = archive_entry_copy_pathname_l(entry, - (const char *)iso9660->utf16be_path, - iso9660->utf16be_path_len, - iso9660->sconv_utf16be); - if (r != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "No memory for Pathname"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Pathname cannot be converted " - "from %s to current locale.", - archive_string_conversion_charset_name( - iso9660->sconv_utf16be)); - - rd_r = ARCHIVE_WARN; - } - } else { - const char *path = build_pathname(&iso9660->pathname, file, 0); - if (path == NULL) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Pathname is too long"); - return (ARCHIVE_FATAL); - } else { - archive_string_empty(&iso9660->pathname); - archive_entry_set_pathname(entry, path); - } - } - - iso9660->entry_bytes_remaining = file->size; - /* Offset for sparse-file-aware clients. */ - iso9660->entry_sparse_offset = 0; - - if (file->offset + file->size > iso9660->volume_size) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "File is beyond end-of-media: %s", - archive_entry_pathname(entry)); - iso9660->entry_bytes_remaining = 0; - return (ARCHIVE_WARN); - } - - /* Set up the entry structure with information about this entry. */ - archive_entry_set_mode(entry, file->mode); - archive_entry_set_uid(entry, file->uid); - archive_entry_set_gid(entry, file->gid); - archive_entry_set_nlink(entry, file->nlinks); - if (file->birthtime_is_set) - archive_entry_set_birthtime(entry, file->birthtime, 0); - else - archive_entry_unset_birthtime(entry); - archive_entry_set_mtime(entry, file->mtime, 0); - archive_entry_set_ctime(entry, file->ctime, 0); - archive_entry_set_atime(entry, file->atime, 0); - /* N.B.: Rock Ridge supports 64-bit device numbers. */ - archive_entry_set_rdev(entry, (dev_t)file->rdev); - archive_entry_set_size(entry, iso9660->entry_bytes_remaining); - if (file->symlink.s != NULL) - archive_entry_copy_symlink(entry, file->symlink.s); - - /* Note: If the input isn't seekable, we can't rewind to - * return the same body again, so if the next entry refers to - * the same data, we have to return it as a hardlink to the - * original entry. */ - if (file->number != -1 && - file->number == iso9660->previous_number) { - if (iso9660->seenJoliet) { - r = archive_entry_copy_hardlink_l(entry, - (const char *)iso9660->utf16be_previous_path, - iso9660->utf16be_previous_path_len, - iso9660->sconv_utf16be); - if (r != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "No memory for Linkname"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Linkname cannot be converted " - "from %s to current locale.", - archive_string_conversion_charset_name( - iso9660->sconv_utf16be)); - rd_r = ARCHIVE_WARN; - } - } else - archive_entry_set_hardlink(entry, - iso9660->previous_pathname.s); - archive_entry_unset_size(entry); - iso9660->entry_bytes_remaining = 0; - return (rd_r); - } - - if ((file->mode & AE_IFMT) != AE_IFDIR && - file->offset < iso9660->current_position) { - int64_t r64; - - r64 = __archive_read_seek(a, file->offset, SEEK_SET); - if (r64 != (int64_t)file->offset) { - /* We can't seek backwards to extract it, so issue - * a warning. Note that this can only happen if - * this entry was added to the heap after we passed - * this offset, that is, only if the directory - * mentioning this entry is later than the body of - * the entry. Such layouts are very unusual; most - * ISO9660 writers lay out and record all directory - * information first, then store all file bodies. */ - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Ignoring out-of-order file @%jx (%s) %jd < %jd", - (intmax_t)file->number, - iso9660->pathname.s, - (intmax_t)file->offset, - (intmax_t)iso9660->current_position); - iso9660->entry_bytes_remaining = 0; - return (ARCHIVE_WARN); - } - iso9660->current_position = (uint64_t)r64; - } - - /* Initialize zisofs variables. */ - iso9660->entry_zisofs.pz = file->pz; - if (file->pz) { -#ifdef HAVE_ZLIB_H - struct zisofs *zisofs; - - zisofs = &iso9660->entry_zisofs; - zisofs->initialized = 0; - zisofs->pz_log2_bs = file->pz_log2_bs; - zisofs->pz_uncompressed_size = file->pz_uncompressed_size; - zisofs->pz_offset = 0; - zisofs->header_avail = 0; - zisofs->header_passed = 0; - zisofs->block_pointers_avail = 0; -#endif - archive_entry_set_size(entry, file->pz_uncompressed_size); - } - - iso9660->previous_number = file->number; - if (iso9660->seenJoliet) { - memcpy(iso9660->utf16be_previous_path, iso9660->utf16be_path, - iso9660->utf16be_path_len); - iso9660->utf16be_previous_path_len = iso9660->utf16be_path_len; - } else - archive_strcpy( - &iso9660->previous_pathname, iso9660->pathname.s); - - /* Reset entry_bytes_remaining if the file is multi extent. */ - iso9660->entry_content = file->contents.first; - if (iso9660->entry_content != NULL) - iso9660->entry_bytes_remaining = iso9660->entry_content->size; - - if (archive_entry_filetype(entry) == AE_IFDIR) { - /* Overwrite nlinks by proper link number which is - * calculated from number of sub directories. */ - archive_entry_set_nlink(entry, 2 + file->subdirs); - /* Directory data has been read completely. */ - iso9660->entry_bytes_remaining = 0; - } - - if (rd_r != ARCHIVE_OK) - return (rd_r); - return (ARCHIVE_OK); -} - -static int -archive_read_format_iso9660_read_data_skip(struct archive_read *a) -{ - /* Because read_next_header always does an explicit skip - * to the next entry, we don't need to do anything here. */ - (void)a; /* UNUSED */ - return (ARCHIVE_OK); -} - -#ifdef HAVE_ZLIB_H - -static int -zisofs_read_data(struct archive_read *a, - const void **buff, size_t *size, int64_t *offset) -{ - struct iso9660 *iso9660; - struct zisofs *zisofs; - const unsigned char *p; - size_t avail; - ssize_t bytes_read; - size_t uncompressed_size; - int r; - - iso9660 = (struct iso9660 *)(a->format->data); - zisofs = &iso9660->entry_zisofs; - - p = __archive_read_ahead(a, 1, &bytes_read); - if (bytes_read <= 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated zisofs file body"); - return (ARCHIVE_FATAL); - } - if (bytes_read > iso9660->entry_bytes_remaining) - bytes_read = (ssize_t)iso9660->entry_bytes_remaining; - avail = bytes_read; - uncompressed_size = 0; - - if (!zisofs->initialized) { - size_t ceil, xsize; - - /* Allocate block pointers buffer. */ - ceil = (size_t)((zisofs->pz_uncompressed_size + - (((int64_t)1) << zisofs->pz_log2_bs) - 1) - >> zisofs->pz_log2_bs); - xsize = (ceil + 1) * 4; - if (zisofs->block_pointers_alloc < xsize) { - size_t alloc; - - if (zisofs->block_pointers != NULL) - free(zisofs->block_pointers); - alloc = ((xsize >> 10) + 1) << 10; - zisofs->block_pointers = malloc(alloc); - if (zisofs->block_pointers == NULL) { - archive_set_error(&a->archive, ENOMEM, - "No memory for zisofs decompression"); - return (ARCHIVE_FATAL); - } - zisofs->block_pointers_alloc = alloc; - } - zisofs->block_pointers_size = xsize; - - /* Allocate uncompressed data buffer. */ - xsize = (size_t)1UL << zisofs->pz_log2_bs; - if (zisofs->uncompressed_buffer_size < xsize) { - if (zisofs->uncompressed_buffer != NULL) - free(zisofs->uncompressed_buffer); - zisofs->uncompressed_buffer = malloc(xsize); - if (zisofs->uncompressed_buffer == NULL) { - archive_set_error(&a->archive, ENOMEM, - "No memory for zisofs decompression"); - return (ARCHIVE_FATAL); - } - } - zisofs->uncompressed_buffer_size = xsize; - - /* - * Read the file header, and check the magic code of zisofs. - */ - if (zisofs->header_avail < sizeof(zisofs->header)) { - xsize = sizeof(zisofs->header) - zisofs->header_avail; - if (avail < xsize) - xsize = avail; - memcpy(zisofs->header + zisofs->header_avail, p, xsize); - zisofs->header_avail += xsize; - avail -= xsize; - p += xsize; - } - if (!zisofs->header_passed && - zisofs->header_avail == sizeof(zisofs->header)) { - int err = 0; - - if (memcmp(zisofs->header, zisofs_magic, - sizeof(zisofs_magic)) != 0) - err = 1; - if (archive_le32dec(zisofs->header + 8) - != zisofs->pz_uncompressed_size) - err = 1; - if (zisofs->header[12] != 4) - err = 1; - if (zisofs->header[13] != zisofs->pz_log2_bs) - err = 1; - if (err) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Illegal zisofs file body"); - return (ARCHIVE_FATAL); - } - zisofs->header_passed = 1; - } - /* - * Read block pointers. - */ - if (zisofs->header_passed && - zisofs->block_pointers_avail < zisofs->block_pointers_size) { - xsize = zisofs->block_pointers_size - - zisofs->block_pointers_avail; - if (avail < xsize) - xsize = avail; - memcpy(zisofs->block_pointers - + zisofs->block_pointers_avail, p, xsize); - zisofs->block_pointers_avail += xsize; - avail -= xsize; - p += xsize; - if (zisofs->block_pointers_avail - == zisofs->block_pointers_size) { - /* We've got all block pointers and initialize - * related variables. */ - zisofs->block_off = 0; - zisofs->block_avail = 0; - /* Complete a initialization */ - zisofs->initialized = 1; - } - } - - if (!zisofs->initialized) - goto next_data; /* We need more data. */ - } - - /* - * Get block offsets from block pointers. - */ - if (zisofs->block_avail == 0) { - uint32_t bst, bed; - - if (zisofs->block_off + 4 >= zisofs->block_pointers_size) { - /* There isn't a pair of offsets. */ - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Illegal zisofs block pointers"); - return (ARCHIVE_FATAL); - } - bst = archive_le32dec( - zisofs->block_pointers + zisofs->block_off); - if (bst != zisofs->pz_offset + (bytes_read - avail)) { - /* TODO: Should we seek offset of current file - * by bst ? */ - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Illegal zisofs block pointers(cannot seek)"); - return (ARCHIVE_FATAL); - } - bed = archive_le32dec( - zisofs->block_pointers + zisofs->block_off + 4); - if (bed < bst) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Illegal zisofs block pointers"); - return (ARCHIVE_FATAL); - } - zisofs->block_avail = bed - bst; - zisofs->block_off += 4; - - /* Initialize compression library for new block. */ - if (zisofs->stream_valid) - r = inflateReset(&zisofs->stream); - else - r = inflateInit(&zisofs->stream); - if (r != Z_OK) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Can't initialize zisofs decompression."); - return (ARCHIVE_FATAL); - } - zisofs->stream_valid = 1; - zisofs->stream.total_in = 0; - zisofs->stream.total_out = 0; - } - - /* - * Make uncompressed data. - */ - if (zisofs->block_avail == 0) { - memset(zisofs->uncompressed_buffer, 0, - zisofs->uncompressed_buffer_size); - uncompressed_size = zisofs->uncompressed_buffer_size; - } else { - zisofs->stream.next_in = (Bytef *)(uintptr_t)(const void *)p; - if (avail > zisofs->block_avail) - zisofs->stream.avail_in = zisofs->block_avail; - else - zisofs->stream.avail_in = (uInt)avail; - zisofs->stream.next_out = zisofs->uncompressed_buffer; - zisofs->stream.avail_out = - (uInt)zisofs->uncompressed_buffer_size; - - r = inflate(&zisofs->stream, 0); - switch (r) { - case Z_OK: /* Decompressor made some progress.*/ - case Z_STREAM_END: /* Found end of stream. */ - break; - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "zisofs decompression failed (%d)", r); - return (ARCHIVE_FATAL); - } - uncompressed_size = - zisofs->uncompressed_buffer_size - zisofs->stream.avail_out; - avail -= zisofs->stream.next_in - p; - zisofs->block_avail -= (uint32_t)(zisofs->stream.next_in - p); - } -next_data: - bytes_read -= avail; - *buff = zisofs->uncompressed_buffer; - *size = uncompressed_size; - *offset = iso9660->entry_sparse_offset; - iso9660->entry_sparse_offset += uncompressed_size; - iso9660->entry_bytes_remaining -= bytes_read; - iso9660->current_position += bytes_read; - zisofs->pz_offset += (uint32_t)bytes_read; - iso9660->entry_bytes_unconsumed += bytes_read; - - return (ARCHIVE_OK); -} - -#else /* HAVE_ZLIB_H */ - -static int -zisofs_read_data(struct archive_read *a, - const void **buff, size_t *size, int64_t *offset) -{ - - (void)buff;/* UNUSED */ - (void)size;/* UNUSED */ - (void)offset;/* UNUSED */ - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "zisofs is not supported on this platform."); - return (ARCHIVE_FAILED); -} - -#endif /* HAVE_ZLIB_H */ - -static int -archive_read_format_iso9660_read_data(struct archive_read *a, - const void **buff, size_t *size, int64_t *offset) -{ - ssize_t bytes_read; - struct iso9660 *iso9660; - - iso9660 = (struct iso9660 *)(a->format->data); - - if (iso9660->entry_bytes_unconsumed) { - __archive_read_consume(a, iso9660->entry_bytes_unconsumed); - iso9660->entry_bytes_unconsumed = 0; - } - - if (iso9660->entry_bytes_remaining <= 0) { - if (iso9660->entry_content != NULL) - iso9660->entry_content = iso9660->entry_content->next; - if (iso9660->entry_content == NULL) { - *buff = NULL; - *size = 0; - *offset = iso9660->entry_sparse_offset; - return (ARCHIVE_EOF); - } - /* Seek forward to the start of the entry. */ - if (iso9660->current_position < iso9660->entry_content->offset) { - int64_t step; - - step = iso9660->entry_content->offset - - iso9660->current_position; - step = __archive_read_consume(a, step); - if (step < 0) - return ((int)step); - iso9660->current_position = - iso9660->entry_content->offset; - } - if (iso9660->entry_content->offset < iso9660->current_position) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Ignoring out-of-order file (%s) %jd < %jd", - iso9660->pathname.s, - (intmax_t)iso9660->entry_content->offset, - (intmax_t)iso9660->current_position); - *buff = NULL; - *size = 0; - *offset = iso9660->entry_sparse_offset; - return (ARCHIVE_WARN); - } - iso9660->entry_bytes_remaining = iso9660->entry_content->size; - } - if (iso9660->entry_zisofs.pz) - return (zisofs_read_data(a, buff, size, offset)); - - *buff = __archive_read_ahead(a, 1, &bytes_read); - if (bytes_read == 0) - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Truncated input file"); - if (*buff == NULL) - return (ARCHIVE_FATAL); - if (bytes_read > iso9660->entry_bytes_remaining) - bytes_read = (ssize_t)iso9660->entry_bytes_remaining; - *size = bytes_read; - *offset = iso9660->entry_sparse_offset; - iso9660->entry_sparse_offset += bytes_read; - iso9660->entry_bytes_remaining -= bytes_read; - iso9660->entry_bytes_unconsumed = bytes_read; - iso9660->current_position += bytes_read; - return (ARCHIVE_OK); -} - -static int -archive_read_format_iso9660_cleanup(struct archive_read *a) -{ - struct iso9660 *iso9660; - int r = ARCHIVE_OK; - - iso9660 = (struct iso9660 *)(a->format->data); - release_files(iso9660); - free(iso9660->read_ce_req.reqs); - archive_string_free(&iso9660->pathname); - archive_string_free(&iso9660->previous_pathname); - free(iso9660->pending_files.files); -#ifdef HAVE_ZLIB_H - free(iso9660->entry_zisofs.uncompressed_buffer); - free(iso9660->entry_zisofs.block_pointers); - if (iso9660->entry_zisofs.stream_valid) { - if (inflateEnd(&iso9660->entry_zisofs.stream) != Z_OK) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Failed to clean up zlib decompressor"); - r = ARCHIVE_FATAL; - } - } -#endif - free(iso9660->utf16be_path); - free(iso9660->utf16be_previous_path); - free(iso9660); - (a->format->data) = NULL; - return (r); -} - -/* - * This routine parses a single ISO directory record, makes sense - * of any extensions, and stores the result in memory. - */ -static struct file_info * -parse_file_info(struct archive_read *a, struct file_info *parent, - const unsigned char *isodirrec, size_t reclen) -{ - struct iso9660 *iso9660; - struct file_info *file, *filep; - size_t name_len; - const unsigned char *rr_start, *rr_end; - const unsigned char *p; - size_t dr_len = 0; - uint64_t fsize, offset; - int32_t location; - int flags; - - iso9660 = (struct iso9660 *)(a->format->data); - - if (reclen != 0) - dr_len = (size_t)isodirrec[DR_length_offset]; - /* - * Sanity check that reclen is not zero and dr_len is greater than - * reclen but at least 34 - */ - if (reclen == 0 || reclen < dr_len || dr_len < 34) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Invalid length of directory record"); - return (NULL); - } - name_len = (size_t)isodirrec[DR_name_len_offset]; - location = archive_le32dec(isodirrec + DR_extent_offset); - fsize = toi(isodirrec + DR_size_offset, DR_size_size); - /* Sanity check that name_len doesn't exceed dr_len. */ - if (dr_len - 33 < name_len || name_len == 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Invalid length of file identifier"); - return (NULL); - } - /* Sanity check that location doesn't exceed volume block. - * Don't check lower limit of location; it's possibility - * the location has negative value when file type is symbolic - * link or file size is zero. As far as I know latest mkisofs - * do that. - */ - if (location > 0 && - (location + ((fsize + iso9660->logical_block_size -1) - / iso9660->logical_block_size)) - > (uint32_t)iso9660->volume_block) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Invalid location of extent of file"); - return (NULL); - } - /* Sanity check that location doesn't have a negative value - * when the file is not empty. it's too large. */ - if (fsize != 0 && location < 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Invalid location of extent of file"); - return (NULL); - } - - /* Sanity check that this entry does not create a cycle. */ - offset = iso9660->logical_block_size * (uint64_t)location; - for (filep = parent; filep != NULL; filep = filep->parent) { - if (filep->offset == offset) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Directory structure contains loop"); - return (NULL); - } - } - - /* Create a new file entry and copy data from the ISO dir record. */ - file = (struct file_info *)calloc(1, sizeof(*file)); - if (file == NULL) { - archive_set_error(&a->archive, ENOMEM, - "No memory for file entry"); - return (NULL); - } - file->parent = parent; - file->offset = offset; - file->size = fsize; - file->mtime = isodate7(isodirrec + DR_date_offset); - file->ctime = file->atime = file->mtime; - file->rede_files.first = NULL; - file->rede_files.last = &(file->rede_files.first); - - p = isodirrec + DR_name_offset; - /* Rockridge extensions (if any) follow name. Compute this - * before fidgeting the name_len below. */ - rr_start = p + name_len + (name_len & 1 ? 0 : 1); - rr_end = isodirrec + dr_len; - - if (iso9660->seenJoliet) { - /* Joliet names are max 64 chars (128 bytes) according to spec, - * but genisoimage/mkisofs allows recording longer Joliet - * names which are 103 UCS2 characters(206 bytes) by their - * option '-joliet-long'. - */ - if (name_len > 206) - name_len = 206; - name_len &= ~1; - - /* trim trailing first version and dot from filename. - * - * Remember we were in UTF-16BE land! - * SEPARATOR 1 (.) and SEPARATOR 2 (;) are both - * 16 bits big endian characters on Joliet. - * - * TODO: sanitize filename? - * Joliet allows any UCS-2 char except: - * *, /, :, ;, ? and \. - */ - /* Chop off trailing ';1' from files. */ - if (name_len > 4 && p[name_len-4] == 0 && p[name_len-3] == ';' - && p[name_len-2] == 0 && p[name_len-1] == '1') - name_len -= 4; -#if 0 /* XXX: this somehow manages to strip of single-character file extensions, like '.c'. */ - /* Chop off trailing '.' from filenames. */ - if (name_len > 2 && p[name_len-2] == 0 && p[name_len-1] == '.') - name_len -= 2; -#endif - if ((file->utf16be_name = malloc(name_len)) == NULL) { - archive_set_error(&a->archive, ENOMEM, - "No memory for file name"); - goto fail; - } - memcpy(file->utf16be_name, p, name_len); - file->utf16be_bytes = name_len; - } else { - /* Chop off trailing ';1' from files. */ - if (name_len > 2 && p[name_len - 2] == ';' && - p[name_len - 1] == '1') - name_len -= 2; - /* Chop off trailing '.' from filenames. */ - if (name_len > 1 && p[name_len - 1] == '.') - --name_len; - - archive_strncpy(&file->name, (const char *)p, name_len); - } - - flags = isodirrec[DR_flags_offset]; - if (flags & 0x02) - file->mode = AE_IFDIR | 0700; - else - file->mode = AE_IFREG | 0400; - if (flags & 0x80) - file->multi_extent = 1; - else - file->multi_extent = 0; - /* - * Use a location for the file number, which is treated as an inode - * number to find out hardlink target. If Rockridge extensions is - * being used, the file number will be overwritten by FILE SERIAL - * NUMBER of RRIP "PX" extension. - * Note: Old mkisofs did not record that FILE SERIAL NUMBER - * in ISO images. - * Note2: xorriso set 0 to the location of a symlink file. - */ - if (file->size == 0 && location >= 0) { - /* If file->size is zero, its location points wrong place, - * and so we should not use it for the file number. - * When the location has negative value, it can be used - * for the file number. - */ - file->number = -1; - /* Do not appear before any directory entries. */ - file->offset = -1; - } else - file->number = (int64_t)(uint32_t)location; - - /* Rockridge extensions overwrite information from above. */ - if (iso9660->opt_support_rockridge) { - if (parent == NULL && rr_end - rr_start >= 7) { - p = rr_start; - if (memcmp(p, "SP\x07\x01\xbe\xef", 6) == 0) { - /* - * SP extension stores the suspOffset - * (Number of bytes to skip between - * filename and SUSP records.) - * It is mandatory by the SUSP standard - * (IEEE 1281). - * - * It allows SUSP to coexist with - * non-SUSP uses of the System - * Use Area by placing non-SUSP data - * before SUSP data. - * - * SP extension must be in the root - * directory entry, disable all SUSP - * processing if not found. - */ - iso9660->suspOffset = p[6]; - iso9660->seenSUSP = 1; - rr_start += 7; - } - } - if (iso9660->seenSUSP) { - int r; - - file->name_continues = 0; - file->symlink_continues = 0; - rr_start += iso9660->suspOffset; - r = parse_rockridge(a, file, rr_start, rr_end); - if (r != ARCHIVE_OK) - goto fail; - /* - * A file size of symbolic link files in ISO images - * made by makefs is not zero and its location is - * the same as those of next regular file. That is - * the same as hard like file and it causes unexpected - * error. - */ - if (file->size > 0 && - (file->mode & AE_IFMT) == AE_IFLNK) { - file->size = 0; - file->number = -1; - file->offset = -1; - } - } else - /* If there isn't SUSP, disable parsing - * rock ridge extensions. */ - iso9660->opt_support_rockridge = 0; - } - - file->nlinks = 1;/* Reset nlink. we'll calculate it later. */ - /* Tell file's parent how many children that parent has. */ - if (parent != NULL && (flags & 0x02)) - parent->subdirs++; - - if (iso9660->seenRockridge) { - if (parent != NULL && parent->parent == NULL && - (flags & 0x02) && iso9660->rr_moved == NULL && - file->name.s && - (strcmp(file->name.s, "rr_moved") == 0 || - strcmp(file->name.s, ".rr_moved") == 0)) { - iso9660->rr_moved = file; - file->rr_moved = 1; - file->rr_moved_has_re_only = 1; - file->re = 0; - parent->subdirs--; - } else if (file->re) { - /* - * Sanity check: file's parent is rr_moved. - */ - if (parent == NULL || parent->rr_moved == 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Invalid Rockridge RE"); - goto fail; - } - /* - * Sanity check: file does not have "CL" extension. - */ - if (file->cl_offset) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Invalid Rockridge RE and CL"); - goto fail; - } - /* - * Sanity check: The file type must be a directory. - */ - if ((flags & 0x02) == 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Invalid Rockridge RE"); - goto fail; - } - } else if (parent != NULL && parent->rr_moved) - file->rr_moved_has_re_only = 0; - else if (parent != NULL && (flags & 0x02) && - (parent->re || parent->re_descendant)) - file->re_descendant = 1; - if (file->cl_offset) { - struct file_info *r; - - if (parent == NULL || parent->parent == NULL) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Invalid Rockridge CL"); - goto fail; - } - /* - * Sanity check: The file type must be a regular file. - */ - if ((flags & 0x02) != 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Invalid Rockridge CL"); - goto fail; - } - parent->subdirs++; - /* Overwrite an offset and a number of this "CL" entry - * to appear before other dirs. "+1" to those is to - * make sure to appear after "RE" entry which this - * "CL" entry should be connected with. */ - file->offset = file->number = file->cl_offset + 1; - - /* - * Sanity check: cl_offset does not point at its - * the parents or itself. - */ - for (r = parent; r; r = r->parent) { - if (r->offset == file->cl_offset) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Invalid Rockridge CL"); - goto fail; - } - } - if (file->cl_offset == file->offset || - parent->rr_moved) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Invalid Rockridge CL"); - goto fail; - } - } - } - -#if DEBUG - /* DEBUGGING: Warn about attributes I don't yet fully support. */ - if ((flags & ~0x02) != 0) { - fprintf(stderr, "\n ** Unrecognized flag: "); - dump_isodirrec(stderr, isodirrec); - fprintf(stderr, "\n"); - } else if (toi(isodirrec + DR_volume_sequence_number_offset, 2) != 1) { - fprintf(stderr, "\n ** Unrecognized sequence number: "); - dump_isodirrec(stderr, isodirrec); - fprintf(stderr, "\n"); - } else if (*(isodirrec + DR_file_unit_size_offset) != 0) { - fprintf(stderr, "\n ** Unexpected file unit size: "); - dump_isodirrec(stderr, isodirrec); - fprintf(stderr, "\n"); - } else if (*(isodirrec + DR_interleave_offset) != 0) { - fprintf(stderr, "\n ** Unexpected interleave: "); - dump_isodirrec(stderr, isodirrec); - fprintf(stderr, "\n"); - } else if (*(isodirrec + DR_ext_attr_length_offset) != 0) { - fprintf(stderr, "\n ** Unexpected extended attribute length: "); - dump_isodirrec(stderr, isodirrec); - fprintf(stderr, "\n"); - } -#endif - register_file(iso9660, file); - return (file); -fail: - archive_string_free(&file->name); - free(file); - return (NULL); -} - -static int -parse_rockridge(struct archive_read *a, struct file_info *file, - const unsigned char *p, const unsigned char *end) -{ - struct iso9660 *iso9660; - int entry_seen = 0; - - iso9660 = (struct iso9660 *)(a->format->data); - - while (p + 4 <= end /* Enough space for another entry. */ - && p[0] >= 'A' && p[0] <= 'Z' /* Sanity-check 1st char of name. */ - && p[1] >= 'A' && p[1] <= 'Z' /* Sanity-check 2nd char of name. */ - && p[2] >= 4 /* Sanity-check length. */ - && p + p[2] <= end) { /* Sanity-check length. */ - const unsigned char *data = p + 4; - int data_length = p[2] - 4; - int version = p[3]; - - switch(p[0]) { - case 'C': - if (p[1] == 'E') { - if (version == 1 && data_length == 24) { - /* - * CE extension comprises: - * 8 byte sector containing extension - * 8 byte offset w/in above sector - * 8 byte length of continuation - */ - int32_t location = - archive_le32dec(data); - file->ce_offset = - archive_le32dec(data+8); - file->ce_size = - archive_le32dec(data+16); - if (register_CE(a, location, file) - != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } - } - else if (p[1] == 'L') { - if (version == 1 && data_length == 8) { - file->cl_offset = (uint64_t) - iso9660->logical_block_size * - (uint64_t)archive_le32dec(data); - iso9660->seenRockridge = 1; - } - } - break; - case 'N': - if (p[1] == 'M') { - if (version == 1) { - parse_rockridge_NM1(file, - data, data_length); - iso9660->seenRockridge = 1; - } - } - break; - case 'P': - /* - * PD extension is padding; - * contents are always ignored. - * - * PL extension won't appear; - * contents are always ignored. - */ - if (p[1] == 'N') { - if (version == 1 && data_length == 16) { - file->rdev = toi(data,4); - file->rdev <<= 32; - file->rdev |= toi(data + 8, 4); - iso9660->seenRockridge = 1; - } - } - else if (p[1] == 'X') { - /* - * PX extension comprises: - * 8 bytes for mode, - * 8 bytes for nlinks, - * 8 bytes for uid, - * 8 bytes for gid, - * 8 bytes for inode. - */ - if (version == 1) { - if (data_length >= 8) - file->mode - = toi(data, 4); - if (data_length >= 16) - file->nlinks - = toi(data + 8, 4); - if (data_length >= 24) - file->uid - = toi(data + 16, 4); - if (data_length >= 32) - file->gid - = toi(data + 24, 4); - if (data_length >= 40) - file->number - = toi(data + 32, 4); - iso9660->seenRockridge = 1; - } - } - break; - case 'R': - if (p[1] == 'E' && version == 1) { - file->re = 1; - iso9660->seenRockridge = 1; - } - else if (p[1] == 'R' && version == 1) { - /* - * RR extension comprises: - * one byte flag value - * This extension is obsolete, - * so contents are always ignored. - */ - } - break; - case 'S': - if (p[1] == 'L') { - if (version == 1) { - parse_rockridge_SL1(file, - data, data_length); - iso9660->seenRockridge = 1; - } - } - else if (p[1] == 'T' - && data_length == 0 && version == 1) { - /* - * ST extension marks end of this - * block of SUSP entries. - * - * It allows SUSP to coexist with - * non-SUSP uses of the System - * Use Area by placing non-SUSP data - * after SUSP data. - */ - iso9660->seenSUSP = 0; - iso9660->seenRockridge = 0; - return (ARCHIVE_OK); - } - break; - case 'T': - if (p[1] == 'F') { - if (version == 1) { - parse_rockridge_TF1(file, - data, data_length); - iso9660->seenRockridge = 1; - } - } - break; - case 'Z': - if (p[1] == 'F') { - if (version == 1) - parse_rockridge_ZF1(file, - data, data_length); - } - break; - default: - break; - } - - p += p[2]; - entry_seen = 1; - } - - if (entry_seen) - return (ARCHIVE_OK); - else { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Tried to parse Rockridge extensions, but none found"); - return (ARCHIVE_WARN); - } -} - -static int -register_CE(struct archive_read *a, int32_t location, - struct file_info *file) -{ - struct iso9660 *iso9660; - struct read_ce_queue *heap; - struct read_ce_req *p; - uint64_t offset, parent_offset; - int hole, parent; - - iso9660 = (struct iso9660 *)(a->format->data); - offset = ((uint64_t)location) * (uint64_t)iso9660->logical_block_size; - if (((file->mode & AE_IFMT) == AE_IFREG && - offset >= file->offset) || - offset < iso9660->current_position || - (((uint64_t)file->ce_offset) + file->ce_size) - > (uint64_t)iso9660->logical_block_size || - offset + file->ce_offset + file->ce_size - > iso9660->volume_size) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Invalid parameter in SUSP \"CE\" extension"); - return (ARCHIVE_FATAL); - } - - /* Expand our CE list as necessary. */ - heap = &(iso9660->read_ce_req); - if (heap->cnt >= heap->allocated) { - int new_size; - - if (heap->allocated < 16) - new_size = 16; - else - new_size = heap->allocated * 2; - /* Overflow might keep us from growing the list. */ - if (new_size <= heap->allocated) { - archive_set_error(&a->archive, ENOMEM, "Out of memory"); - return (ARCHIVE_FATAL); - } - p = calloc(new_size, sizeof(p[0])); - if (p == NULL) { - archive_set_error(&a->archive, ENOMEM, "Out of memory"); - return (ARCHIVE_FATAL); - } - if (heap->reqs != NULL) { - memcpy(p, heap->reqs, heap->cnt * sizeof(*p)); - free(heap->reqs); - } - heap->reqs = p; - heap->allocated = new_size; - } - - /* - * Start with hole at end, walk it up tree to find insertion point. - */ - hole = heap->cnt++; - while (hole > 0) { - parent = (hole - 1)/2; - parent_offset = heap->reqs[parent].offset; - if (offset >= parent_offset) { - heap->reqs[hole].offset = offset; - heap->reqs[hole].file = file; - return (ARCHIVE_OK); - } - /* Move parent into hole <==> move hole up tree. */ - heap->reqs[hole] = heap->reqs[parent]; - hole = parent; - } - heap->reqs[0].offset = offset; - heap->reqs[0].file = file; - return (ARCHIVE_OK); -} - -static void -next_CE(struct read_ce_queue *heap) -{ - uint64_t a_offset, b_offset, c_offset; - int a, b, c; - struct read_ce_req tmp; - - if (heap->cnt < 1) - return; - - /* - * Move the last item in the heap to the root of the tree - */ - heap->reqs[0] = heap->reqs[--(heap->cnt)]; - - /* - * Rebalance the heap. - */ - a = 0; /* Starting element and its offset */ - a_offset = heap->reqs[a].offset; - for (;;) { - b = a + a + 1; /* First child */ - if (b >= heap->cnt) - return; - b_offset = heap->reqs[b].offset; - c = b + 1; /* Use second child if it is smaller. */ - if (c < heap->cnt) { - c_offset = heap->reqs[c].offset; - if (c_offset < b_offset) { - b = c; - b_offset = c_offset; - } - } - if (a_offset <= b_offset) - return; - tmp = heap->reqs[a]; - heap->reqs[a] = heap->reqs[b]; - heap->reqs[b] = tmp; - a = b; - } -} - - -static int -read_CE(struct archive_read *a, struct iso9660 *iso9660) -{ - struct read_ce_queue *heap; - const unsigned char *b, *p, *end; - struct file_info *file; - size_t step; - int r; - - /* Read data which RRIP "CE" extension points. */ - heap = &(iso9660->read_ce_req); - step = iso9660->logical_block_size; - while (heap->cnt && - heap->reqs[0].offset == iso9660->current_position) { - b = __archive_read_ahead(a, step, NULL); - if (b == NULL) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Failed to read full block when scanning " - "ISO9660 directory list"); - return (ARCHIVE_FATAL); - } - do { - file = heap->reqs[0].file; - if (file->ce_offset + file->ce_size > step) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Malformed CE information"); - return (ARCHIVE_FATAL); - } - p = b + file->ce_offset; - end = p + file->ce_size; - next_CE(heap); - r = parse_rockridge(a, file, p, end); - if (r != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } while (heap->cnt && - heap->reqs[0].offset == iso9660->current_position); - /* NOTE: Do not move this consume's code to front of - * do-while loop. Registration of nested CE extension - * might cause error because of current position. */ - __archive_read_consume(a, step); - iso9660->current_position += step; - } - return (ARCHIVE_OK); -} - -static void -parse_rockridge_NM1(struct file_info *file, - const unsigned char *data, int data_length) -{ - if (!file->name_continues) - archive_string_empty(&file->name); - file->name_continues = 0; - if (data_length < 1) - return; - /* - * NM version 1 extension comprises: - * 1 byte flag, value is one of: - * = 0: remainder is name - * = 1: remainder is name, next NM entry continues name - * = 2: "." - * = 4: ".." - * = 32: Implementation specific - * All other values are reserved. - */ - switch(data[0]) { - case 0: - if (data_length < 2) - return; - archive_strncat(&file->name, - (const char *)data + 1, data_length - 1); - break; - case 1: - if (data_length < 2) - return; - archive_strncat(&file->name, - (const char *)data + 1, data_length - 1); - file->name_continues = 1; - break; - case 2: - archive_strcat(&file->name, "."); - break; - case 4: - archive_strcat(&file->name, ".."); - break; - default: - return; - } - -} - -static void -parse_rockridge_TF1(struct file_info *file, const unsigned char *data, - int data_length) -{ - char flag; - /* - * TF extension comprises: - * one byte flag - * create time (optional) - * modify time (optional) - * access time (optional) - * attribute time (optional) - * Time format and presence of fields - * is controlled by flag bits. - */ - if (data_length < 1) - return; - flag = data[0]; - ++data; - --data_length; - if (flag & 0x80) { - /* Use 17-byte time format. */ - if ((flag & 1) && data_length >= 17) { - /* Create time. */ - file->birthtime_is_set = 1; - file->birthtime = isodate17(data); - data += 17; - data_length -= 17; - } - if ((flag & 2) && data_length >= 17) { - /* Modify time. */ - file->mtime = isodate17(data); - data += 17; - data_length -= 17; - } - if ((flag & 4) && data_length >= 17) { - /* Access time. */ - file->atime = isodate17(data); - data += 17; - data_length -= 17; - } - if ((flag & 8) && data_length >= 17) { - /* Attribute change time. */ - file->ctime = isodate17(data); - } - } else { - /* Use 7-byte time format. */ - if ((flag & 1) && data_length >= 7) { - /* Create time. */ - file->birthtime_is_set = 1; - file->birthtime = isodate7(data); - data += 7; - data_length -= 7; - } - if ((flag & 2) && data_length >= 7) { - /* Modify time. */ - file->mtime = isodate7(data); - data += 7; - data_length -= 7; - } - if ((flag & 4) && data_length >= 7) { - /* Access time. */ - file->atime = isodate7(data); - data += 7; - data_length -= 7; - } - if ((flag & 8) && data_length >= 7) { - /* Attribute change time. */ - file->ctime = isodate7(data); - } - } -} - -static void -parse_rockridge_SL1(struct file_info *file, const unsigned char *data, - int data_length) -{ - const char *separator = ""; - - if (!file->symlink_continues || file->symlink.length < 1) - archive_string_empty(&file->symlink); - file->symlink_continues = 0; - - /* - * Defined flag values: - * 0: This is the last SL record for this symbolic link - * 1: this symbolic link field continues in next SL entry - * All other values are reserved. - */ - if (data_length < 1) - return; - switch(*data) { - case 0: - break; - case 1: - file->symlink_continues = 1; - break; - default: - return; - } - ++data; /* Skip flag byte. */ - --data_length; - - /* - * SL extension body stores "components". - * Basically, this is a complicated way of storing - * a POSIX path. It also interferes with using - * symlinks for storing non-path data. - * - * Each component is 2 bytes (flag and length) - * possibly followed by name data. - */ - while (data_length >= 2) { - unsigned char flag = *data++; - unsigned char nlen = *data++; - data_length -= 2; - - archive_strcat(&file->symlink, separator); - separator = "/"; - - switch(flag) { - case 0: /* Usual case, this is text. */ - if (data_length < nlen) - return; - archive_strncat(&file->symlink, - (const char *)data, nlen); - break; - case 0x01: /* Text continues in next component. */ - if (data_length < nlen) - return; - archive_strncat(&file->symlink, - (const char *)data, nlen); - separator = ""; - break; - case 0x02: /* Current dir. */ - archive_strcat(&file->symlink, "."); - break; - case 0x04: /* Parent dir. */ - archive_strcat(&file->symlink, ".."); - break; - case 0x08: /* Root of filesystem. */ - archive_strcat(&file->symlink, "/"); - separator = ""; - break; - case 0x10: /* Undefined (historically "volume root" */ - archive_string_empty(&file->symlink); - archive_strcat(&file->symlink, "ROOT"); - break; - case 0x20: /* Undefined (historically "hostname") */ - archive_strcat(&file->symlink, "hostname"); - break; - default: - /* TODO: issue a warning ? */ - return; - } - data += nlen; - data_length -= nlen; - } -} - -static void -parse_rockridge_ZF1(struct file_info *file, const unsigned char *data, - int data_length) -{ - - if (data[0] == 0x70 && data[1] == 0x7a && data_length == 12) { - /* paged zlib */ - file->pz = 1; - file->pz_log2_bs = data[3]; - file->pz_uncompressed_size = archive_le32dec(&data[4]); - } -} - -static void -register_file(struct iso9660 *iso9660, struct file_info *file) -{ - - file->use_next = iso9660->use_files; - iso9660->use_files = file; -} - -static void -release_files(struct iso9660 *iso9660) -{ - struct content *con, *connext; - struct file_info *file; - - file = iso9660->use_files; - while (file != NULL) { - struct file_info *next = file->use_next; - - archive_string_free(&file->name); - archive_string_free(&file->symlink); - free(file->utf16be_name); - con = file->contents.first; - while (con != NULL) { - connext = con->next; - free(con); - con = connext; - } - free(file); - file = next; - } -} - -static int -next_entry_seek(struct archive_read *a, struct iso9660 *iso9660, - struct file_info **pfile) -{ - struct file_info *file; - int r; - - r = next_cache_entry(a, iso9660, pfile); - if (r != ARCHIVE_OK) - return (r); - file = *pfile; - - /* Don't waste time seeking for zero-length bodies. */ - if (file->size == 0) - file->offset = iso9660->current_position; - - /* flush any remaining bytes from the last round to ensure - * we're positioned */ - if (iso9660->entry_bytes_unconsumed) { - __archive_read_consume(a, iso9660->entry_bytes_unconsumed); - iso9660->entry_bytes_unconsumed = 0; - } - - /* Seek forward to the start of the entry. */ - if (iso9660->current_position < file->offset) { - int64_t step; - - step = file->offset - iso9660->current_position; - step = __archive_read_consume(a, step); - if (step < 0) - return ((int)step); - iso9660->current_position = file->offset; - } - - /* We found body of file; handle it now. */ - return (ARCHIVE_OK); -} - -static int -next_cache_entry(struct archive_read *a, struct iso9660 *iso9660, - struct file_info **pfile) -{ - struct file_info *file; - struct { - struct file_info *first; - struct file_info **last; - } empty_files; - int64_t number; - int count; - - file = cache_get_entry(iso9660); - if (file != NULL) { - *pfile = file; - return (ARCHIVE_OK); - } - - for (;;) { - struct file_info *re, *d; - - *pfile = file = next_entry(iso9660); - if (file == NULL) { - /* - * If directory entries all which are descendant of - * rr_moved are still remaining, expose their. - */ - if (iso9660->re_files.first != NULL && - iso9660->rr_moved != NULL && - iso9660->rr_moved->rr_moved_has_re_only) - /* Expose "rr_moved" entry. */ - cache_add_entry(iso9660, iso9660->rr_moved); - while ((re = re_get_entry(iso9660)) != NULL) { - /* Expose its descendant dirs. */ - while ((d = rede_get_entry(re)) != NULL) - cache_add_entry(iso9660, d); - } - if (iso9660->cache_files.first != NULL) - return (next_cache_entry(a, iso9660, pfile)); - return (ARCHIVE_EOF); - } - - if (file->cl_offset) { - struct file_info *first_re = NULL; - int nexted_re = 0; - - /* - * Find "RE" dir for the current file, which - * has "CL" flag. - */ - while ((re = re_get_entry(iso9660)) - != first_re) { - if (first_re == NULL) - first_re = re; - if (re->offset == file->cl_offset) { - re->parent->subdirs--; - re->parent = file->parent; - re->re = 0; - if (re->parent->re_descendant) { - nexted_re = 1; - re->re_descendant = 1; - if (rede_add_entry(re) < 0) - goto fatal_rr; - /* Move a list of descendants - * to a new ancestor. */ - while ((d = rede_get_entry( - re)) != NULL) - if (rede_add_entry(d) - < 0) - goto fatal_rr; - break; - } - /* Replace the current file - * with "RE" dir */ - *pfile = file = re; - /* Expose its descendant */ - while ((d = rede_get_entry( - file)) != NULL) - cache_add_entry( - iso9660, d); - break; - } else - re_add_entry(iso9660, re); - } - if (nexted_re) { - /* - * Do not expose this at this time - * because we have not gotten its full-path - * name yet. - */ - continue; - } - } else if ((file->mode & AE_IFMT) == AE_IFDIR) { - int r; - - /* Read file entries in this dir. */ - r = read_children(a, file); - if (r != ARCHIVE_OK) - return (r); - - /* - * Handle a special dir of Rockridge extensions, - * "rr_moved". - */ - if (file->rr_moved) { - /* - * If this has only the subdirectories which - * have "RE" flags, do not expose at this time. - */ - if (file->rr_moved_has_re_only) - continue; - /* Otherwise expose "rr_moved" entry. */ - } else if (file->re) { - /* - * Do not expose this at this time - * because we have not gotten its full-path - * name yet. - */ - re_add_entry(iso9660, file); - continue; - } else if (file->re_descendant) { - /* - * If the top level "RE" entry of this entry - * is not exposed, we, accordingly, should not - * expose this entry at this time because - * we cannot make its proper full-path name. - */ - if (rede_add_entry(file) == 0) - continue; - /* Otherwise we can expose this entry because - * it seems its top level "RE" has already been - * exposed. */ - } - } - break; - } - - if ((file->mode & AE_IFMT) != AE_IFREG || file->number == -1) - return (ARCHIVE_OK); - - count = 0; - number = file->number; - iso9660->cache_files.first = NULL; - iso9660->cache_files.last = &(iso9660->cache_files.first); - empty_files.first = NULL; - empty_files.last = &empty_files.first; - /* Collect files which has the same file serial number. - * Peek pending_files so that file which number is different - * is not put back. */ - while (iso9660->pending_files.used > 0 && - (iso9660->pending_files.files[0]->number == -1 || - iso9660->pending_files.files[0]->number == number)) { - if (file->number == -1) { - /* This file has the same offset - * but it's wrong offset which empty files - * and symlink files have. - * NOTE: This wrong offset was recorded by - * old mkisofs utility. If ISO images is - * created by latest mkisofs, this does not - * happen. - */ - file->next = NULL; - *empty_files.last = file; - empty_files.last = &(file->next); - } else { - count++; - cache_add_entry(iso9660, file); - } - file = next_entry(iso9660); - } - - if (count == 0) { - *pfile = file; - return ((file == NULL)?ARCHIVE_EOF:ARCHIVE_OK); - } - if (file->number == -1) { - file->next = NULL; - *empty_files.last = file; - empty_files.last = &(file->next); - } else { - count++; - cache_add_entry(iso9660, file); - } - - if (count > 1) { - /* The count is the same as number of hardlink, - * so much so that each nlinks of files in cache_file - * is overwritten by value of the count. - */ - for (file = iso9660->cache_files.first; - file != NULL; file = file->next) - file->nlinks = count; - } - /* If there are empty files, that files are added - * to the tail of the cache_files. */ - if (empty_files.first != NULL) { - *iso9660->cache_files.last = empty_files.first; - iso9660->cache_files.last = empty_files.last; - } - *pfile = cache_get_entry(iso9660); - return ((*pfile == NULL)?ARCHIVE_EOF:ARCHIVE_OK); - -fatal_rr: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Failed to connect 'CL' pointer to 'RE' rr_moved pointer of " - "Rockridge extensions: current position = %jd, CL offset = %jd", - (intmax_t)iso9660->current_position, (intmax_t)file->cl_offset); - return (ARCHIVE_FATAL); -} - -static inline void -re_add_entry(struct iso9660 *iso9660, struct file_info *file) -{ - file->re_next = NULL; - *iso9660->re_files.last = file; - iso9660->re_files.last = &(file->re_next); -} - -static inline struct file_info * -re_get_entry(struct iso9660 *iso9660) -{ - struct file_info *file; - - if ((file = iso9660->re_files.first) != NULL) { - iso9660->re_files.first = file->re_next; - if (iso9660->re_files.first == NULL) - iso9660->re_files.last = - &(iso9660->re_files.first); - } - return (file); -} - -static inline int -rede_add_entry(struct file_info *file) -{ - struct file_info *re; - - /* - * Find "RE" entry. - */ - re = file->parent; - while (re != NULL && !re->re) - re = re->parent; - if (re == NULL) - return (-1); - - file->re_next = NULL; - *re->rede_files.last = file; - re->rede_files.last = &(file->re_next); - return (0); -} - -static inline struct file_info * -rede_get_entry(struct file_info *re) -{ - struct file_info *file; - - if ((file = re->rede_files.first) != NULL) { - re->rede_files.first = file->re_next; - if (re->rede_files.first == NULL) - re->rede_files.last = - &(re->rede_files.first); - } - return (file); -} - -static inline void -cache_add_entry(struct iso9660 *iso9660, struct file_info *file) -{ - file->next = NULL; - *iso9660->cache_files.last = file; - iso9660->cache_files.last = &(file->next); -} - -static inline struct file_info * -cache_get_entry(struct iso9660 *iso9660) -{ - struct file_info *file; - - if ((file = iso9660->cache_files.first) != NULL) { - iso9660->cache_files.first = file->next; - if (iso9660->cache_files.first == NULL) - iso9660->cache_files.last = - &(iso9660->cache_files.first); - } - return (file); -} - -static int -heap_add_entry(struct archive_read *a, struct heap_queue *heap, - struct file_info *file, uint64_t key) -{ - uint64_t file_key, parent_key; - int hole, parent; - - /* Expand our pending files list as necessary. */ - if (heap->used >= heap->allocated) { - struct file_info **new_pending_files; - int new_size = heap->allocated * 2; - - if (heap->allocated < 1024) - new_size = 1024; - /* Overflow might keep us from growing the list. */ - if (new_size <= heap->allocated) { - archive_set_error(&a->archive, - ENOMEM, "Out of memory"); - return (ARCHIVE_FATAL); - } - new_pending_files = (struct file_info **) - malloc(new_size * sizeof(new_pending_files[0])); - if (new_pending_files == NULL) { - archive_set_error(&a->archive, - ENOMEM, "Out of memory"); - return (ARCHIVE_FATAL); - } - if (heap->allocated) - memcpy(new_pending_files, heap->files, - heap->allocated * sizeof(new_pending_files[0])); - free(heap->files); - heap->files = new_pending_files; - heap->allocated = new_size; - } - - file_key = file->key = key; - - /* - * Start with hole at end, walk it up tree to find insertion point. - */ - hole = heap->used++; - while (hole > 0) { - parent = (hole - 1)/2; - parent_key = heap->files[parent]->key; - if (file_key >= parent_key) { - heap->files[hole] = file; - return (ARCHIVE_OK); - } - /* Move parent into hole <==> move hole up tree. */ - heap->files[hole] = heap->files[parent]; - hole = parent; - } - heap->files[0] = file; - - return (ARCHIVE_OK); -} - -static struct file_info * -heap_get_entry(struct heap_queue *heap) -{ - uint64_t a_key, b_key, c_key; - int a, b, c; - struct file_info *r, *tmp; - - if (heap->used < 1) - return (NULL); - - /* - * The first file in the list is the earliest; we'll return this. - */ - r = heap->files[0]; - - /* - * Move the last item in the heap to the root of the tree - */ - heap->files[0] = heap->files[--(heap->used)]; - - /* - * Rebalance the heap. - */ - a = 0; /* Starting element and its heap key */ - a_key = heap->files[a]->key; - for (;;) { - b = a + a + 1; /* First child */ - if (b >= heap->used) - return (r); - b_key = heap->files[b]->key; - c = b + 1; /* Use second child if it is smaller. */ - if (c < heap->used) { - c_key = heap->files[c]->key; - if (c_key < b_key) { - b = c; - b_key = c_key; - } - } - if (a_key <= b_key) - return (r); - tmp = heap->files[a]; - heap->files[a] = heap->files[b]; - heap->files[b] = tmp; - a = b; - } -} - -static unsigned int -toi(const void *p, int n) -{ - const unsigned char *v = (const unsigned char *)p; - if (n > 1) - return v[0] + 256 * toi(v + 1, n - 1); - if (n == 1) - return v[0]; - return (0); -} - -static time_t -isodate7(const unsigned char *v) -{ - struct tm tm; - int offset; - time_t t; - - memset(&tm, 0, sizeof(tm)); - tm.tm_year = v[0]; - tm.tm_mon = v[1] - 1; - tm.tm_mday = v[2]; - tm.tm_hour = v[3]; - tm.tm_min = v[4]; - tm.tm_sec = v[5]; - /* v[6] is the signed timezone offset, in 1/4-hour increments. */ - offset = ((const signed char *)v)[6]; - if (offset > -48 && offset < 52) { - tm.tm_hour -= offset / 4; - tm.tm_min -= (offset % 4) * 15; - } - t = time_from_tm(&tm); - if (t == (time_t)-1) - return ((time_t)0); - return (t); -} - -static time_t -isodate17(const unsigned char *v) -{ - struct tm tm; - int offset; - time_t t; - - memset(&tm, 0, sizeof(tm)); - tm.tm_year = (v[0] - '0') * 1000 + (v[1] - '0') * 100 - + (v[2] - '0') * 10 + (v[3] - '0') - - 1900; - tm.tm_mon = (v[4] - '0') * 10 + (v[5] - '0'); - tm.tm_mday = (v[6] - '0') * 10 + (v[7] - '0'); - tm.tm_hour = (v[8] - '0') * 10 + (v[9] - '0'); - tm.tm_min = (v[10] - '0') * 10 + (v[11] - '0'); - tm.tm_sec = (v[12] - '0') * 10 + (v[13] - '0'); - /* v[16] is the signed timezone offset, in 1/4-hour increments. */ - offset = ((const signed char *)v)[16]; - if (offset > -48 && offset < 52) { - tm.tm_hour -= offset / 4; - tm.tm_min -= (offset % 4) * 15; - } - t = time_from_tm(&tm); - if (t == (time_t)-1) - return ((time_t)0); - return (t); -} - -static time_t -time_from_tm(struct tm *t) -{ -#if HAVE__MKGMTIME - return _mkgmtime(t); -#elif HAVE_TIMEGM - /* Use platform timegm() if available. */ - return (timegm(t)); -#else - /* Else use direct calculation using POSIX assumptions. */ - /* First, fix up tm_yday based on the year/month/day. */ - if (mktime(t) == (time_t)-1) - return ((time_t)-1); - /* Then we can compute timegm() from first principles. */ - return (t->tm_sec - + t->tm_min * 60 - + t->tm_hour * 3600 - + t->tm_yday * 86400 - + (t->tm_year - 70) * 31536000 - + ((t->tm_year - 69) / 4) * 86400 - - ((t->tm_year - 1) / 100) * 86400 - + ((t->tm_year + 299) / 400) * 86400); -#endif -} - -static const char * -build_pathname(struct archive_string *as, struct file_info *file, int depth) -{ - // Plain ISO9660 only allows 8 dir levels; if we get - // to 1000, then something is very, very wrong. - if (depth > 1000) { - return NULL; - } - if (file->parent != NULL && archive_strlen(&file->parent->name) > 0) { - if (build_pathname(as, file->parent, depth + 1) == NULL) { - return NULL; - } - archive_strcat(as, "/"); - } - if (archive_strlen(&file->name) == 0) - archive_strcat(as, "."); - else - archive_string_concat(as, &file->name); - return (as->s); -} - -static int -build_pathname_utf16be(unsigned char *p, size_t max, size_t *len, - struct file_info *file) -{ - if (file->parent != NULL && file->parent->utf16be_bytes > 0) { - if (build_pathname_utf16be(p, max, len, file->parent) != 0) - return (-1); - p[*len] = 0; - p[*len + 1] = '/'; - *len += 2; - } - if (file->utf16be_bytes == 0) { - if (*len + 2 > max) - return (-1);/* Path is too long! */ - p[*len] = 0; - p[*len + 1] = '.'; - *len += 2; - } else { - if (*len + file->utf16be_bytes > max) - return (-1);/* Path is too long! */ - memcpy(p + *len, file->utf16be_name, file->utf16be_bytes); - *len += file->utf16be_bytes; - } - return (0); -} - -#if DEBUG -static void -dump_isodirrec(FILE *out, const unsigned char *isodirrec) -{ - fprintf(out, " l %d,", - toi(isodirrec + DR_length_offset, DR_length_size)); - fprintf(out, " a %d,", - toi(isodirrec + DR_ext_attr_length_offset, DR_ext_attr_length_size)); - fprintf(out, " ext 0x%x,", - toi(isodirrec + DR_extent_offset, DR_extent_size)); - fprintf(out, " s %d,", - toi(isodirrec + DR_size_offset, DR_extent_size)); - fprintf(out, " f 0x%x,", - toi(isodirrec + DR_flags_offset, DR_flags_size)); - fprintf(out, " u %d,", - toi(isodirrec + DR_file_unit_size_offset, DR_file_unit_size_size)); - fprintf(out, " ilv %d,", - toi(isodirrec + DR_interleave_offset, DR_interleave_size)); - fprintf(out, " seq %d,", - toi(isodirrec + DR_volume_sequence_number_offset, - DR_volume_sequence_number_size)); - fprintf(out, " nl %d:", - toi(isodirrec + DR_name_len_offset, DR_name_len_size)); - fprintf(out, " `%.*s'", - toi(isodirrec + DR_name_len_offset, DR_name_len_size), - isodirrec + DR_name_offset); -} -#endif diff --git a/thirdparty/libarchive/libarchive/archive_read_support_format_lha.c b/thirdparty/libarchive/libarchive/archive_read_support_format_lha.c deleted file mode 100644 index 1c64b2900..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_format_lha.c +++ /dev/null @@ -1,2919 +0,0 @@ -/*- - * Copyright (c) 2008-2014 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_LIMITS_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" -#include "archive_entry_locale.h" -#include "archive_private.h" -#include "archive_read_private.h" -#include "archive_endian.h" - - -#define MAXMATCH 256 /* Maximum match length. */ -#define MINMATCH 3 /* Minimum match length. */ -/* - * Literal table format: - * +0 +256 +510 - * +---------------+-------------------------+ - * | literal code | match length | - * | 0 ... 255 | MINMATCH ... MAXMATCH | - * +---------------+-------------------------+ - * <--- LT_BITLEN_SIZE ---> - */ -/* Literal table size. */ -#define LT_BITLEN_SIZE (UCHAR_MAX + 1 + MAXMATCH - MINMATCH + 1) -/* Position table size. - * Note: this used for both position table and pre literal table.*/ -#define PT_BITLEN_SIZE (3 + 16) - -struct lzh_dec { - /* Decoding status. */ - int state; - - /* - * Window to see last 8Ki(lh5),32Ki(lh6),64Ki(lh7) bytes of decoded - * data. - */ - int w_size; - int w_mask; - /* Window buffer, which is a loop buffer. */ - unsigned char *w_buff; - /* The insert position to the window. */ - int w_pos; - /* The position where we can copy decoded code from the window. */ - int copy_pos; - /* The length how many bytes we can copy decoded code from - * the window. */ - int copy_len; - - /* - * Bit stream reader. - */ - struct lzh_br { -#define CACHE_TYPE uint64_t -#define CACHE_BITS (8 * sizeof(CACHE_TYPE)) - /* Cache buffer. */ - CACHE_TYPE cache_buffer; - /* Indicates how many bits avail in cache_buffer. */ - int cache_avail; - } br; - - /* - * Huffman coding. - */ - struct huffman { - int len_size; - int len_avail; - int len_bits; - int freq[17]; - unsigned char *bitlen; - - /* - * Use a index table. It's faster than searching a huffman - * coding tree, which is a binary tree. But a use of a large - * index table causes L1 cache read miss many times. - */ -#define HTBL_BITS 10 - int max_bits; - int shift_bits; - int tbl_bits; - int tree_used; - int tree_avail; - /* Direct access table. */ - uint16_t *tbl; - /* Binary tree table for extra bits over the direct access. */ - struct htree_t { - uint16_t left; - uint16_t right; - } *tree; - } lt, pt; - - int blocks_avail; - int pos_pt_len_size; - int pos_pt_len_bits; - int literal_pt_len_size; - int literal_pt_len_bits; - int reading_position; - int loop; - int error; -}; - -struct lzh_stream { - const unsigned char *next_in; - int avail_in; - int64_t total_in; - const unsigned char *ref_ptr; - int avail_out; - int64_t total_out; - struct lzh_dec *ds; -}; - -struct lha { - /* entry_bytes_remaining is the number of bytes we expect. */ - int64_t entry_offset; - int64_t entry_bytes_remaining; - int64_t entry_unconsumed; - uint16_t entry_crc_calculated; - - size_t header_size; /* header size */ - unsigned char level; /* header level */ - char method[3]; /* compress type */ - int64_t compsize; /* compressed data size */ - int64_t origsize; /* original file size */ - int setflag; -#define BIRTHTIME_IS_SET 1 -#define ATIME_IS_SET 2 -#define UNIX_MODE_IS_SET 4 -#define CRC_IS_SET 8 - time_t birthtime; - long birthtime_tv_nsec; - time_t mtime; - long mtime_tv_nsec; - time_t atime; - long atime_tv_nsec; - mode_t mode; - int64_t uid; - int64_t gid; - struct archive_string uname; - struct archive_string gname; - uint16_t header_crc; - uint16_t crc; - /* dirname and filename could be in different codepages */ - struct archive_string_conv *sconv_dir; - struct archive_string_conv *sconv_fname; - struct archive_string_conv *opt_sconv; - - struct archive_string dirname; - struct archive_string filename; - struct archive_wstring ws; - - unsigned char dos_attr; - - /* Flag to mark progress that an archive was read their first header.*/ - char found_first_header; - /* Flag to mark that indicates an empty directory. */ - char directory; - - /* Flags to mark progress of decompression. */ - char decompress_init; - char end_of_entry; - char end_of_entry_cleanup; - char entry_is_compressed; - - char format_name[64]; - - struct lzh_stream strm; -}; - -/* - * LHA header common member offset. - */ -#define H_METHOD_OFFSET 2 /* Compress type. */ -#define H_ATTR_OFFSET 19 /* DOS attribute. */ -#define H_LEVEL_OFFSET 20 /* Header Level. */ -#define H_SIZE 22 /* Minimum header size. */ - -static int archive_read_format_lha_bid(struct archive_read *, int); -static int archive_read_format_lha_options(struct archive_read *, - const char *, const char *); -static int archive_read_format_lha_read_header(struct archive_read *, - struct archive_entry *); -static int archive_read_format_lha_read_data(struct archive_read *, - const void **, size_t *, int64_t *); -static int archive_read_format_lha_read_data_skip(struct archive_read *); -static int archive_read_format_lha_cleanup(struct archive_read *); - -static void lha_replace_path_separator(struct lha *, - struct archive_entry *); -static int lha_read_file_header_0(struct archive_read *, struct lha *); -static int lha_read_file_header_1(struct archive_read *, struct lha *); -static int lha_read_file_header_2(struct archive_read *, struct lha *); -static int lha_read_file_header_3(struct archive_read *, struct lha *); -static int lha_read_file_extended_header(struct archive_read *, - struct lha *, uint16_t *, int, size_t, size_t *); -static size_t lha_check_header_format(const void *); -static int lha_skip_sfx(struct archive_read *); -static time_t lha_dos_time(const unsigned char *); -static time_t lha_win_time(uint64_t, long *); -static unsigned char lha_calcsum(unsigned char, const void *, - int, size_t); -static int lha_parse_linkname(struct archive_wstring *, - struct archive_wstring *); -static int lha_read_data_none(struct archive_read *, const void **, - size_t *, int64_t *); -static int lha_read_data_lzh(struct archive_read *, const void **, - size_t *, int64_t *); -static void lha_crc16_init(void); -static uint16_t lha_crc16(uint16_t, const void *, size_t); -static int lzh_decode_init(struct lzh_stream *, const char *); -static void lzh_decode_free(struct lzh_stream *); -static int lzh_decode(struct lzh_stream *, int); -static int lzh_br_fillup(struct lzh_stream *, struct lzh_br *); -static int lzh_huffman_init(struct huffman *, size_t, int); -static void lzh_huffman_free(struct huffman *); -static int lzh_read_pt_bitlen(struct lzh_stream *, int start, int end); -static int lzh_make_fake_table(struct huffman *, uint16_t); -static int lzh_make_huffman_table(struct huffman *); -static inline int lzh_decode_huffman(struct huffman *, unsigned); -static int lzh_decode_huffman_tree(struct huffman *, unsigned, int); - - -int -archive_read_support_format_lha(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - struct lha *lha; - int r; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_format_lha"); - - lha = (struct lha *)calloc(1, sizeof(*lha)); - if (lha == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate lha data"); - return (ARCHIVE_FATAL); - } - archive_string_init(&lha->ws); - - r = __archive_read_register_format(a, - lha, - "lha", - archive_read_format_lha_bid, - archive_read_format_lha_options, - archive_read_format_lha_read_header, - archive_read_format_lha_read_data, - archive_read_format_lha_read_data_skip, - NULL, - archive_read_format_lha_cleanup, - NULL, - NULL); - - if (r != ARCHIVE_OK) - free(lha); - return (ARCHIVE_OK); -} - -static size_t -lha_check_header_format(const void *h) -{ - const unsigned char *p = h; - size_t next_skip_bytes; - - switch (p[H_METHOD_OFFSET+3]) { - /* - * "-lh0-" ... "-lh7-" "-lhd-" - * "-lzs-" "-lz5-" - */ - case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': - case 'd': - case 's': - next_skip_bytes = 4; - - /* b0 == 0 means the end of an LHa archive file. */ - if (p[0] == 0) - break; - if (p[H_METHOD_OFFSET] != '-' || p[H_METHOD_OFFSET+1] != 'l' - || p[H_METHOD_OFFSET+4] != '-') - break; - - if (p[H_METHOD_OFFSET+2] == 'h') { - /* "-lh?-" */ - if (p[H_METHOD_OFFSET+3] == 's') - break; - if (p[H_LEVEL_OFFSET] == 0) - return (0); - if (p[H_LEVEL_OFFSET] <= 3 && p[H_ATTR_OFFSET] == 0x20) - return (0); - } - if (p[H_METHOD_OFFSET+2] == 'z') { - /* LArc extensions: -lzs-,-lz4- and -lz5- */ - if (p[H_LEVEL_OFFSET] != 0) - break; - if (p[H_METHOD_OFFSET+3] == 's' - || p[H_METHOD_OFFSET+3] == '4' - || p[H_METHOD_OFFSET+3] == '5') - return (0); - } - break; - case 'h': next_skip_bytes = 1; break; - case 'z': next_skip_bytes = 1; break; - case 'l': next_skip_bytes = 2; break; - case '-': next_skip_bytes = 3; break; - default : next_skip_bytes = 4; break; - } - - return (next_skip_bytes); -} - -static int -archive_read_format_lha_bid(struct archive_read *a, int best_bid) -{ - const char *p; - const void *buff; - ssize_t bytes_avail, offset, window; - size_t next; - - /* If there's already a better bid than we can ever - make, don't bother testing. */ - if (best_bid > 30) - return (-1); - - if ((p = __archive_read_ahead(a, H_SIZE, NULL)) == NULL) - return (-1); - - if (lha_check_header_format(p) == 0) - return (30); - - if (p[0] == 'M' && p[1] == 'Z') { - /* PE file */ - offset = 0; - window = 4096; - while (offset < (1024 * 20)) { - buff = __archive_read_ahead(a, offset + window, - &bytes_avail); - if (buff == NULL) { - /* Remaining bytes are less than window. */ - window >>= 1; - if (window < (H_SIZE + 3)) - return (0); - continue; - } - p = (const char *)buff + offset; - while (p + H_SIZE < (const char *)buff + bytes_avail) { - if ((next = lha_check_header_format(p)) == 0) - return (30); - p += next; - } - offset = p - (const char *)buff; - } - } - return (0); -} - -static int -archive_read_format_lha_options(struct archive_read *a, - const char *key, const char *val) -{ - struct lha *lha; - int ret = ARCHIVE_FAILED; - - lha = (struct lha *)(a->format->data); - if (strcmp(key, "hdrcharset") == 0) { - if (val == NULL || val[0] == 0) - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "lha: hdrcharset option needs a character-set name"); - else { - lha->opt_sconv = - archive_string_conversion_from_charset( - &a->archive, val, 0); - if (lha->opt_sconv != NULL) - ret = ARCHIVE_OK; - else - ret = ARCHIVE_FATAL; - } - return (ret); - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -static int -lha_skip_sfx(struct archive_read *a) -{ - const void *h; - const char *p, *q; - size_t next, skip; - ssize_t bytes, window; - - window = 4096; - for (;;) { - h = __archive_read_ahead(a, window, &bytes); - if (h == NULL) { - /* Remaining bytes are less than window. */ - window >>= 1; - if (window < (H_SIZE + 3)) - goto fatal; - continue; - } - if (bytes < H_SIZE) - goto fatal; - p = h; - q = p + bytes; - - /* - * Scan ahead until we find something that looks - * like the lha header. - */ - while (p + H_SIZE < q) { - if ((next = lha_check_header_format(p)) == 0) { - skip = p - (const char *)h; - __archive_read_consume(a, skip); - return (ARCHIVE_OK); - } - p += next; - } - skip = p - (const char *)h; - __archive_read_consume(a, skip); - } -fatal: - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Couldn't find out LHa header"); - return (ARCHIVE_FATAL); -} - -static int -truncated_error(struct archive_read *a) -{ - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated LHa header"); - return (ARCHIVE_FATAL); -} - -static int -archive_read_format_lha_read_header(struct archive_read *a, - struct archive_entry *entry) -{ - struct archive_wstring linkname; - struct archive_wstring pathname; - struct lha *lha; - const unsigned char *p; - const char *signature; - int err; - struct archive_mstring conv_buffer; - const wchar_t *conv_buffer_p; - - lha_crc16_init(); - - a->archive.archive_format = ARCHIVE_FORMAT_LHA; - if (a->archive.archive_format_name == NULL) - a->archive.archive_format_name = "lha"; - - lha = (struct lha *)(a->format->data); - lha->decompress_init = 0; - lha->end_of_entry = 0; - lha->end_of_entry_cleanup = 0; - lha->entry_unconsumed = 0; - - if ((p = __archive_read_ahead(a, H_SIZE, NULL)) == NULL) { - /* - * LHa archiver added 0 to the tail of its archive file as - * the mark of the end of the archive. - */ - signature = __archive_read_ahead(a, sizeof(signature[0]), NULL); - if (signature == NULL || signature[0] == 0) - return (ARCHIVE_EOF); - return (truncated_error(a)); - } - - signature = (const char *)p; - if (lha->found_first_header == 0 && - signature[0] == 'M' && signature[1] == 'Z') { - /* This is an executable? Must be self-extracting... */ - err = lha_skip_sfx(a); - if (err < ARCHIVE_WARN) - return (err); - - if ((p = __archive_read_ahead(a, sizeof(*p), NULL)) == NULL) - return (truncated_error(a)); - signature = (const char *)p; - } - /* signature[0] == 0 means the end of an LHa archive file. */ - if (signature[0] == 0) - return (ARCHIVE_EOF); - - /* - * Check the header format and method type. - */ - if (lha_check_header_format(p) != 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Bad LHa file"); - return (ARCHIVE_FATAL); - } - - /* We've found the first header. */ - lha->found_first_header = 1; - /* Set a default value and common data */ - lha->header_size = 0; - lha->level = p[H_LEVEL_OFFSET]; - lha->method[0] = p[H_METHOD_OFFSET+1]; - lha->method[1] = p[H_METHOD_OFFSET+2]; - lha->method[2] = p[H_METHOD_OFFSET+3]; - if (memcmp(lha->method, "lhd", 3) == 0) - lha->directory = 1; - else - lha->directory = 0; - if (memcmp(lha->method, "lh0", 3) == 0 || - memcmp(lha->method, "lz4", 3) == 0) - lha->entry_is_compressed = 0; - else - lha->entry_is_compressed = 1; - - lha->compsize = 0; - lha->origsize = 0; - lha->setflag = 0; - lha->birthtime = 0; - lha->birthtime_tv_nsec = 0; - lha->mtime = 0; - lha->mtime_tv_nsec = 0; - lha->atime = 0; - lha->atime_tv_nsec = 0; - lha->mode = (lha->directory)? 0777 : 0666; - lha->uid = 0; - lha->gid = 0; - archive_string_empty(&lha->dirname); - archive_string_empty(&lha->filename); - lha->dos_attr = 0; - if (lha->opt_sconv != NULL) { - lha->sconv_dir = lha->opt_sconv; - lha->sconv_fname = lha->opt_sconv; - } else { - lha->sconv_dir = NULL; - lha->sconv_fname = NULL; - } - - switch (p[H_LEVEL_OFFSET]) { - case 0: - err = lha_read_file_header_0(a, lha); - break; - case 1: - err = lha_read_file_header_1(a, lha); - break; - case 2: - err = lha_read_file_header_2(a, lha); - break; - case 3: - err = lha_read_file_header_3(a, lha); - break; - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Unsupported LHa header level %d", p[H_LEVEL_OFFSET]); - err = ARCHIVE_FATAL; - break; - } - if (err < ARCHIVE_WARN) - return (err); - - - if (!lha->directory && archive_strlen(&lha->filename) == 0) - /* The filename has not been set */ - return (truncated_error(a)); - - /* - * Make a pathname from a dirname and a filename, after converting to Unicode. - * This is because codepages might differ between dirname and filename. - */ - archive_string_init(&pathname); - archive_string_init(&linkname); - archive_string_init(&conv_buffer.aes_mbs); - archive_string_init(&conv_buffer.aes_mbs_in_locale); - archive_string_init(&conv_buffer.aes_utf8); - archive_string_init(&conv_buffer.aes_wcs); - if (0 != archive_mstring_copy_mbs_len_l(&conv_buffer, lha->dirname.s, lha->dirname.length, lha->sconv_dir)) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Pathname cannot be converted " - "from %s to Unicode.", - archive_string_conversion_charset_name(lha->sconv_dir)); - err = ARCHIVE_FATAL; - } else if (0 != archive_mstring_get_wcs(&a->archive, &conv_buffer, &conv_buffer_p)) - err = ARCHIVE_FATAL; - if (err == ARCHIVE_FATAL) { - archive_mstring_clean(&conv_buffer); - archive_wstring_free(&pathname); - archive_wstring_free(&linkname); - return (err); - } - archive_wstring_copy(&pathname, &conv_buffer.aes_wcs); - - archive_string_empty(&conv_buffer.aes_mbs); - archive_string_empty(&conv_buffer.aes_mbs_in_locale); - archive_string_empty(&conv_buffer.aes_utf8); - archive_wstring_empty(&conv_buffer.aes_wcs); - if (0 != archive_mstring_copy_mbs_len_l(&conv_buffer, lha->filename.s, lha->filename.length, lha->sconv_fname)) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Pathname cannot be converted " - "from %s to Unicode.", - archive_string_conversion_charset_name(lha->sconv_fname)); - err = ARCHIVE_FATAL; - } - else if (0 != archive_mstring_get_wcs(&a->archive, &conv_buffer, &conv_buffer_p)) - err = ARCHIVE_FATAL; - if (err == ARCHIVE_FATAL) { - archive_mstring_clean(&conv_buffer); - archive_wstring_free(&pathname); - archive_wstring_free(&linkname); - return (err); - } - archive_wstring_concat(&pathname, &conv_buffer.aes_wcs); - archive_mstring_clean(&conv_buffer); - - if ((lha->mode & AE_IFMT) == AE_IFLNK) { - /* - * Extract the symlink-name if it's included in the pathname. - */ - if (!lha_parse_linkname(&linkname, &pathname)) { - /* We couldn't get the symlink-name. */ - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Unknown symlink-name"); - archive_wstring_free(&pathname); - archive_wstring_free(&linkname); - return (ARCHIVE_FAILED); - } - } else { - /* - * Make sure a file-type is set. - * The mode has been overridden if it is in the extended data. - */ - lha->mode = (lha->mode & ~AE_IFMT) | - ((lha->directory)? AE_IFDIR: AE_IFREG); - } - if ((lha->setflag & UNIX_MODE_IS_SET) == 0 && - (lha->dos_attr & 1) != 0) - lha->mode &= ~(0222);/* read only. */ - - /* - * Set basic file parameters. - */ - archive_entry_copy_pathname_w(entry, pathname.s); - archive_wstring_free(&pathname); - if (archive_strlen(&linkname) > 0) { - archive_entry_copy_symlink_w(entry, linkname.s); - } else - archive_entry_set_symlink(entry, NULL); - archive_wstring_free(&linkname); - /* - * When a header level is 0, there is a possibility that - * a pathname and a symlink has '\' character, a directory - * separator in DOS/Windows. So we should convert it to '/'. - */ - if (p[H_LEVEL_OFFSET] == 0) - lha_replace_path_separator(lha, entry); - - archive_entry_set_mode(entry, lha->mode); - archive_entry_set_uid(entry, lha->uid); - archive_entry_set_gid(entry, lha->gid); - if (archive_strlen(&lha->uname) > 0) - archive_entry_set_uname(entry, lha->uname.s); - if (archive_strlen(&lha->gname) > 0) - archive_entry_set_gname(entry, lha->gname.s); - if (lha->setflag & BIRTHTIME_IS_SET) { - archive_entry_set_birthtime(entry, lha->birthtime, - lha->birthtime_tv_nsec); - archive_entry_set_ctime(entry, lha->birthtime, - lha->birthtime_tv_nsec); - } else { - archive_entry_unset_birthtime(entry); - archive_entry_unset_ctime(entry); - } - archive_entry_set_mtime(entry, lha->mtime, lha->mtime_tv_nsec); - if (lha->setflag & ATIME_IS_SET) - archive_entry_set_atime(entry, lha->atime, - lha->atime_tv_nsec); - else - archive_entry_unset_atime(entry); - if (lha->directory || archive_entry_symlink(entry) != NULL) - archive_entry_unset_size(entry); - else - archive_entry_set_size(entry, lha->origsize); - - /* - * Prepare variables used to read a file content. - */ - lha->entry_bytes_remaining = lha->compsize; - if (lha->entry_bytes_remaining < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid LHa entry size"); - return (ARCHIVE_FATAL); - } - lha->entry_offset = 0; - lha->entry_crc_calculated = 0; - - /* - * This file does not have a content. - */ - if (lha->directory || lha->compsize == 0) - lha->end_of_entry = 1; - - snprintf(lha->format_name, sizeof(lha->format_name), "lha -%c%c%c-", - lha->method[0], lha->method[1], lha->method[2]); - a->archive.archive_format_name = lha->format_name; - - return (err); -} - -/* - * Replace a DOS path separator '\' by a character '/'. - * Some multi-byte character set have a character '\' in its second byte. - */ -static void -lha_replace_path_separator(struct lha *lha, struct archive_entry *entry) -{ - const wchar_t *wp; - size_t i; - - if ((wp = archive_entry_pathname_w(entry)) != NULL) { - archive_wstrcpy(&(lha->ws), wp); - for (i = 0; i < archive_strlen(&(lha->ws)); i++) { - if (lha->ws.s[i] == L'\\') - lha->ws.s[i] = L'/'; - } - archive_entry_copy_pathname_w(entry, lha->ws.s); - } - - if ((wp = archive_entry_symlink_w(entry)) != NULL) { - archive_wstrcpy(&(lha->ws), wp); - for (i = 0; i < archive_strlen(&(lha->ws)); i++) { - if (lha->ws.s[i] == L'\\') - lha->ws.s[i] = L'/'; - } - archive_entry_copy_symlink_w(entry, lha->ws.s); - } -} - -/* - * Header 0 format - * - * +0 +1 +2 +7 +11 - * +---------------+----------+----------------+-------------------+ - * |header size(*1)|header sum|compression type|compressed size(*2)| - * +---------------+----------+----------------+-------------------+ - * <---------------------(*1)----------* - * - * +11 +15 +17 +19 +20 +21 - * +-----------------+---------+---------+--------------+----------------+ - * |uncompressed size|time(DOS)|date(DOS)|attribute(DOS)|header level(=0)| - * +-----------------+---------+---------+--------------+----------------+ - * *--------------------------------(*1)---------------------------------* - * - * +21 +22 +22+(*3) +22+(*3)+2 +22+(*3)+2+(*4) - * +---------------+---------+----------+----------------+------------------+ - * |name length(*3)|file name|file CRC16|extra header(*4)| compressed data | - * +---------------+---------+----------+----------------+------------------+ - * <--(*3)-> <------(*2)------> - * *----------------------(*1)--------------------------> - * - */ -#define H0_HEADER_SIZE_OFFSET 0 -#define H0_HEADER_SUM_OFFSET 1 -#define H0_COMP_SIZE_OFFSET 7 -#define H0_ORIG_SIZE_OFFSET 11 -#define H0_DOS_TIME_OFFSET 15 -#define H0_NAME_LEN_OFFSET 21 -#define H0_FILE_NAME_OFFSET 22 -#define H0_FIXED_SIZE 24 -static int -lha_read_file_header_0(struct archive_read *a, struct lha *lha) -{ - const unsigned char *p; - int extdsize, namelen; - unsigned char headersum, sum_calculated; - - if ((p = __archive_read_ahead(a, H0_FIXED_SIZE, NULL)) == NULL) - return (truncated_error(a)); - lha->header_size = p[H0_HEADER_SIZE_OFFSET] + 2; - headersum = p[H0_HEADER_SUM_OFFSET]; - lha->compsize = archive_le32dec(p + H0_COMP_SIZE_OFFSET); - lha->origsize = archive_le32dec(p + H0_ORIG_SIZE_OFFSET); - lha->mtime = lha_dos_time(p + H0_DOS_TIME_OFFSET); - namelen = p[H0_NAME_LEN_OFFSET]; - extdsize = (int)lha->header_size - H0_FIXED_SIZE - namelen; - if ((namelen > 221 || extdsize < 0) && extdsize != -2) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid LHa header"); - return (ARCHIVE_FATAL); - } - if ((p = __archive_read_ahead(a, lha->header_size, NULL)) == NULL) - return (truncated_error(a)); - - archive_strncpy(&lha->filename, p + H0_FILE_NAME_OFFSET, namelen); - /* When extdsize == -2, A CRC16 value is not present in the header. */ - if (extdsize >= 0) { - lha->crc = archive_le16dec(p + H0_FILE_NAME_OFFSET + namelen); - lha->setflag |= CRC_IS_SET; - } - sum_calculated = lha_calcsum(0, p, 2, lha->header_size - 2); - - /* Read an extended header */ - if (extdsize > 0) { - /* This extended data is set by 'LHa for UNIX' only. - * Maybe fixed size. - */ - p += H0_FILE_NAME_OFFSET + namelen + 2; - if (p[0] == 'U' && extdsize == 12) { - /* p[1] is a minor version. */ - lha->mtime = archive_le32dec(&p[2]); - lha->mode = archive_le16dec(&p[6]); - lha->uid = archive_le16dec(&p[8]); - lha->gid = archive_le16dec(&p[10]); - lha->setflag |= UNIX_MODE_IS_SET; - } - } - __archive_read_consume(a, lha->header_size); - - if (sum_calculated != headersum) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "LHa header sum error"); - return (ARCHIVE_FATAL); - } - - return (ARCHIVE_OK); -} - -/* - * Header 1 format - * - * +0 +1 +2 +7 +11 - * +---------------+----------+----------------+-------------+ - * |header size(*1)|header sum|compression type|skip size(*2)| - * +---------------+----------+----------------+-------------+ - * <---------------(*1)----------* - * - * +11 +15 +17 +19 +20 +21 - * +-----------------+---------+---------+--------------+----------------+ - * |uncompressed size|time(DOS)|date(DOS)|attribute(DOS)|header level(=1)| - * +-----------------+---------+---------+--------------+----------------+ - * *-------------------------------(*1)----------------------------------* - * - * +21 +22 +22+(*3) +22+(*3)+2 +22+(*3)+3 +22+(*3)+3+(*4) - * +---------------+---------+----------+-----------+-----------+ - * |name length(*3)|file name|file CRC16| creator |padding(*4)| - * +---------------+---------+----------+-----------+-----------+ - * <--(*3)-> - * *----------------------------(*1)----------------------------* - * - * +22+(*3)+3+(*4) +22+(*3)+3+(*4)+2 +22+(*3)+3+(*4)+2+(*5) - * +----------------+---------------------+------------------------+ - * |next header size| extended header(*5) | compressed data | - * +----------------+---------------------+------------------------+ - * *------(*1)-----> <--------------------(*2)--------------------> - */ -#define H1_HEADER_SIZE_OFFSET 0 -#define H1_HEADER_SUM_OFFSET 1 -#define H1_COMP_SIZE_OFFSET 7 -#define H1_ORIG_SIZE_OFFSET 11 -#define H1_DOS_TIME_OFFSET 15 -#define H1_NAME_LEN_OFFSET 21 -#define H1_FILE_NAME_OFFSET 22 -#define H1_FIXED_SIZE 27 -static int -lha_read_file_header_1(struct archive_read *a, struct lha *lha) -{ - const unsigned char *p; - size_t extdsize; - int i, err, err2; - int namelen, padding; - unsigned char headersum, sum_calculated; - - err = ARCHIVE_OK; - - if ((p = __archive_read_ahead(a, H1_FIXED_SIZE, NULL)) == NULL) - return (truncated_error(a)); - - lha->header_size = p[H1_HEADER_SIZE_OFFSET] + 2; - headersum = p[H1_HEADER_SUM_OFFSET]; - /* Note: An extended header size is included in a compsize. */ - lha->compsize = archive_le32dec(p + H1_COMP_SIZE_OFFSET); - lha->origsize = archive_le32dec(p + H1_ORIG_SIZE_OFFSET); - lha->mtime = lha_dos_time(p + H1_DOS_TIME_OFFSET); - namelen = p[H1_NAME_LEN_OFFSET]; - /* Calculate a padding size. The result will be normally 0 only(?) */ - padding = ((int)lha->header_size) - H1_FIXED_SIZE - namelen; - - if (namelen > 230 || padding < 0) - goto invalid; - - if ((p = __archive_read_ahead(a, lha->header_size, NULL)) == NULL) - return (truncated_error(a)); - - for (i = 0; i < namelen; i++) { - if (p[i + H1_FILE_NAME_OFFSET] == 0xff) - goto invalid;/* Invalid filename. */ - } - archive_strncpy(&lha->filename, p + H1_FILE_NAME_OFFSET, namelen); - lha->crc = archive_le16dec(p + H1_FILE_NAME_OFFSET + namelen); - lha->setflag |= CRC_IS_SET; - - sum_calculated = lha_calcsum(0, p, 2, lha->header_size - 2); - /* Consume used bytes but not include `next header size' data - * since it will be consumed in lha_read_file_extended_header(). */ - __archive_read_consume(a, lha->header_size - 2); - - /* Read extended headers */ - err2 = lha_read_file_extended_header(a, lha, NULL, 2, - (size_t)(lha->compsize + 2), &extdsize); - if (err2 < ARCHIVE_WARN) - return (err2); - if (err2 < err) - err = err2; - /* Get a real compressed file size. */ - lha->compsize -= extdsize - 2; - - if (lha->compsize < 0) - goto invalid; /* Invalid compressed file size */ - - if (sum_calculated != headersum) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "LHa header sum error"); - return (ARCHIVE_FATAL); - } - return (err); -invalid: - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid LHa header"); - return (ARCHIVE_FATAL); -} - -/* - * Header 2 format - * - * +0 +2 +7 +11 +15 - * +---------------+----------------+-------------------+-----------------+ - * |header size(*1)|compression type|compressed size(*2)|uncompressed size| - * +---------------+----------------+-------------------+-----------------+ - * <--------------------------------(*1)---------------------------------* - * - * +15 +19 +20 +21 +23 +24 - * +-----------------+------------+----------------+----------+-----------+ - * |data/time(time_t)| 0x20 fixed |header level(=2)|file CRC16| creator | - * +-----------------+------------+----------------+----------+-----------+ - * *---------------------------------(*1)---------------------------------* - * - * +24 +26 +26+(*3) +26+(*3)+(*4) - * +----------------+-------------------+-------------+-------------------+ - * |next header size|extended header(*3)| padding(*4) | compressed data | - * +----------------+-------------------+-------------+-------------------+ - * *--------------------------(*1)-------------------> <------(*2)-------> - * - */ -#define H2_HEADER_SIZE_OFFSET 0 -#define H2_COMP_SIZE_OFFSET 7 -#define H2_ORIG_SIZE_OFFSET 11 -#define H2_TIME_OFFSET 15 -#define H2_CRC_OFFSET 21 -#define H2_FIXED_SIZE 24 -static int -lha_read_file_header_2(struct archive_read *a, struct lha *lha) -{ - const unsigned char *p; - size_t extdsize; - int err, padding; - uint16_t header_crc; - - if ((p = __archive_read_ahead(a, H2_FIXED_SIZE, NULL)) == NULL) - return (truncated_error(a)); - - lha->header_size =archive_le16dec(p + H2_HEADER_SIZE_OFFSET); - lha->compsize = archive_le32dec(p + H2_COMP_SIZE_OFFSET); - lha->origsize = archive_le32dec(p + H2_ORIG_SIZE_OFFSET); - lha->mtime = archive_le32dec(p + H2_TIME_OFFSET); - lha->crc = archive_le16dec(p + H2_CRC_OFFSET); - lha->setflag |= CRC_IS_SET; - - if (lha->header_size < H2_FIXED_SIZE) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid LHa header size"); - return (ARCHIVE_FATAL); - } - - header_crc = lha_crc16(0, p, H2_FIXED_SIZE); - __archive_read_consume(a, H2_FIXED_SIZE); - - /* Read extended headers */ - err = lha_read_file_extended_header(a, lha, &header_crc, 2, - lha->header_size - H2_FIXED_SIZE, &extdsize); - if (err < ARCHIVE_WARN) - return (err); - - /* Calculate a padding size. The result will be normally 0 or 1. */ - padding = (int)lha->header_size - (int)(H2_FIXED_SIZE + extdsize); - if (padding > 0) { - if ((p = __archive_read_ahead(a, padding, NULL)) == NULL) - return (truncated_error(a)); - header_crc = lha_crc16(header_crc, p, padding); - __archive_read_consume(a, padding); - } - - if (header_crc != lha->header_crc) { -#ifndef DONT_FAIL_ON_CRC_ERROR - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "LHa header CRC error"); - return (ARCHIVE_FATAL); -#endif - } - return (err); -} - -/* - * Header 3 format - * - * +0 +2 +7 +11 +15 - * +------------+----------------+-------------------+-----------------+ - * | 0x04 fixed |compression type|compressed size(*2)|uncompressed size| - * +------------+----------------+-------------------+-----------------+ - * <-------------------------------(*1)-------------------------------* - * - * +15 +19 +20 +21 +23 +24 - * +-----------------+------------+----------------+----------+-----------+ - * |date/time(time_t)| 0x20 fixed |header level(=3)|file CRC16| creator | - * +-----------------+------------+----------------+----------+-----------+ - * *--------------------------------(*1)----------------------------------* - * - * +24 +28 +32 +32+(*3) - * +---------------+----------------+-------------------+-----------------+ - * |header size(*1)|next header size|extended header(*3)| compressed data | - * +---------------+----------------+-------------------+-----------------+ - * *------------------------(*1)-----------------------> <------(*2)-----> - * - */ -#define H3_FIELD_LEN_OFFSET 0 -#define H3_COMP_SIZE_OFFSET 7 -#define H3_ORIG_SIZE_OFFSET 11 -#define H3_TIME_OFFSET 15 -#define H3_CRC_OFFSET 21 -#define H3_HEADER_SIZE_OFFSET 24 -#define H3_FIXED_SIZE 28 -static int -lha_read_file_header_3(struct archive_read *a, struct lha *lha) -{ - const unsigned char *p; - size_t extdsize; - int err; - uint16_t header_crc; - - if ((p = __archive_read_ahead(a, H3_FIXED_SIZE, NULL)) == NULL) - return (truncated_error(a)); - - if (archive_le16dec(p + H3_FIELD_LEN_OFFSET) != 4) - goto invalid; - lha->header_size =archive_le32dec(p + H3_HEADER_SIZE_OFFSET); - lha->compsize = archive_le32dec(p + H3_COMP_SIZE_OFFSET); - lha->origsize = archive_le32dec(p + H3_ORIG_SIZE_OFFSET); - lha->mtime = archive_le32dec(p + H3_TIME_OFFSET); - lha->crc = archive_le16dec(p + H3_CRC_OFFSET); - lha->setflag |= CRC_IS_SET; - - if (lha->header_size < H3_FIXED_SIZE + 4) - goto invalid; - header_crc = lha_crc16(0, p, H3_FIXED_SIZE); - __archive_read_consume(a, H3_FIXED_SIZE); - - /* Read extended headers */ - err = lha_read_file_extended_header(a, lha, &header_crc, 4, - lha->header_size - H3_FIXED_SIZE, &extdsize); - if (err < ARCHIVE_WARN) - return (err); - - if (header_crc != lha->header_crc) { -#ifndef DONT_FAIL_ON_CRC_ERROR - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "LHa header CRC error"); - return (ARCHIVE_FATAL); -#endif - } - return (err); -invalid: - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid LHa header"); - return (ARCHIVE_FATAL); -} - -/* - * Extended header format - * - * +0 +2 +3 -- used in header 1 and 2 - * +0 +4 +5 -- used in header 3 - * +--------------+---------+-------------------+--------------+-- - * |ex-header size|header id| data |ex-header size| ....... - * +--------------+---------+-------------------+--------------+-- - * <-------------( ex-header size)------------> <-- next extended header --* - * - * If the ex-header size is zero, it is the make of the end of extended - * headers. - * - */ -static int -lha_read_file_extended_header(struct archive_read *a, struct lha *lha, - uint16_t *crc, int sizefield_length, size_t limitsize, size_t *total_size) -{ - const void *h; - const unsigned char *extdheader; - size_t extdsize; - size_t datasize; - unsigned int i; - unsigned char extdtype; - -#define EXT_HEADER_CRC 0x00 /* Header CRC and information*/ -#define EXT_FILENAME 0x01 /* Filename */ -#define EXT_DIRECTORY 0x02 /* Directory name */ -#define EXT_DOS_ATTR 0x40 /* MS-DOS attribute */ -#define EXT_TIMESTAMP 0x41 /* Windows time stamp */ -#define EXT_FILESIZE 0x42 /* Large file size */ -#define EXT_TIMEZONE 0x43 /* Time zone */ -#define EXT_UTF16_FILENAME 0x44 /* UTF-16 filename */ -#define EXT_UTF16_DIRECTORY 0x45 /* UTF-16 directory name */ -#define EXT_CODEPAGE 0x46 /* Codepage */ -#define EXT_UNIX_MODE 0x50 /* File permission */ -#define EXT_UNIX_GID_UID 0x51 /* gid,uid */ -#define EXT_UNIX_GNAME 0x52 /* Group name */ -#define EXT_UNIX_UNAME 0x53 /* User name */ -#define EXT_UNIX_MTIME 0x54 /* Modified time */ -#define EXT_OS2_NEW_ATTR 0x7f /* new attribute(OS/2 only) */ -#define EXT_NEW_ATTR 0xff /* new attribute */ - - *total_size = sizefield_length; - - for (;;) { - /* Read an extended header size. */ - if ((h = - __archive_read_ahead(a, sizefield_length, NULL)) == NULL) - return (truncated_error(a)); - /* Check if the size is the zero indicates the end of the - * extended header. */ - if (sizefield_length == sizeof(uint16_t)) - extdsize = archive_le16dec(h); - else - extdsize = archive_le32dec(h); - if (extdsize == 0) { - /* End of extended header */ - if (crc != NULL) - *crc = lha_crc16(*crc, h, sizefield_length); - __archive_read_consume(a, sizefield_length); - return (ARCHIVE_OK); - } - - /* Sanity check to the extended header size. */ - if (((uint64_t)*total_size + extdsize) > - (uint64_t)limitsize || - extdsize <= (size_t)sizefield_length) - goto invalid; - - /* Read the extended header. */ - if ((h = __archive_read_ahead(a, extdsize, NULL)) == NULL) - return (truncated_error(a)); - *total_size += extdsize; - - extdheader = (const unsigned char *)h; - /* Get the extended header type. */ - extdtype = extdheader[sizefield_length]; - /* Calculate an extended data size. */ - datasize = extdsize - (1 + sizefield_length); - /* Skip an extended header size field and type field. */ - extdheader += sizefield_length + 1; - - if (crc != NULL && extdtype != EXT_HEADER_CRC) - *crc = lha_crc16(*crc, h, extdsize); - switch (extdtype) { - case EXT_HEADER_CRC: - /* We only use a header CRC. Following data will not - * be used. */ - if (datasize >= 2) { - lha->header_crc = archive_le16dec(extdheader); - if (crc != NULL) { - static const char zeros[2] = {0, 0}; - *crc = lha_crc16(*crc, h, - extdsize - datasize); - /* CRC value itself as zero */ - *crc = lha_crc16(*crc, zeros, 2); - *crc = lha_crc16(*crc, - extdheader+2, datasize - 2); - } - } - break; - case EXT_FILENAME: - if (datasize == 0) { - /* maybe directory header */ - archive_string_empty(&lha->filename); - break; - } - if (extdheader[0] == '\0') - goto invalid; - archive_strncpy(&lha->filename, - (const char *)extdheader, datasize); - break; - case EXT_UTF16_FILENAME: - if (datasize == 0) { - /* maybe directory header */ - archive_string_empty(&lha->filename); - break; - } else if (datasize & 1) { - /* UTF-16 characters take always 2 or 4 bytes */ - goto invalid; - } - if (extdheader[0] == '\0') - goto invalid; - archive_string_empty(&lha->filename); - archive_array_append(&lha->filename, - (const char *)extdheader, datasize); - /* Setup a string conversion for a filename. */ - lha->sconv_fname = - archive_string_conversion_from_charset(&a->archive, - "UTF-16LE", 1); - if (lha->sconv_fname == NULL) - return (ARCHIVE_FATAL); - break; - case EXT_DIRECTORY: - if (datasize == 0 || extdheader[0] == '\0') - /* no directory name data. exit this case. */ - goto invalid; - - archive_strncpy(&lha->dirname, - (const char *)extdheader, datasize); - /* - * Convert directory delimiter from 0xFF - * to '/' for local system. - */ - for (i = 0; i < lha->dirname.length; i++) { - if ((unsigned char)lha->dirname.s[i] == 0xFF) - lha->dirname.s[i] = '/'; - } - /* Is last character directory separator? */ - if (lha->dirname.s[lha->dirname.length-1] != '/') - /* invalid directory data */ - goto invalid; - break; - case EXT_UTF16_DIRECTORY: - /* UTF-16 characters take always 2 or 4 bytes */ - if (datasize == 0 || (datasize & 1) || - extdheader[0] == '\0') { - /* no directory name data. exit this case. */ - goto invalid; - } - - archive_string_empty(&lha->dirname); - archive_array_append(&lha->dirname, - (const char *)extdheader, datasize); - lha->sconv_dir = - archive_string_conversion_from_charset(&a->archive, - "UTF-16LE", 1); - if (lha->sconv_dir == NULL) - return (ARCHIVE_FATAL); - else { - /* - * Convert directory delimiter from 0xFFFF - * to '/' for local system. - */ - uint16_t dirSep; - uint16_t d = 1; - if (archive_be16dec(&d) == 1) - dirSep = 0x2F00; - else - dirSep = 0x002F; - - /* UTF-16LE character */ - uint16_t *utf16name = - (uint16_t *)lha->dirname.s; - for (i = 0; i < lha->dirname.length / 2; i++) { - if (utf16name[i] == 0xFFFF) { - utf16name[i] = dirSep; - } - } - /* Is last character directory separator? */ - if (utf16name[lha->dirname.length / 2 - 1] != - dirSep) { - /* invalid directory data */ - goto invalid; - } - } - break; - case EXT_DOS_ATTR: - if (datasize == 2) - lha->dos_attr = (unsigned char) - (archive_le16dec(extdheader) & 0xff); - break; - case EXT_TIMESTAMP: - if (datasize == (sizeof(uint64_t) * 3)) { - lha->birthtime = lha_win_time( - archive_le64dec(extdheader), - &lha->birthtime_tv_nsec); - extdheader += sizeof(uint64_t); - lha->mtime = lha_win_time( - archive_le64dec(extdheader), - &lha->mtime_tv_nsec); - extdheader += sizeof(uint64_t); - lha->atime = lha_win_time( - archive_le64dec(extdheader), - &lha->atime_tv_nsec); - lha->setflag |= BIRTHTIME_IS_SET | - ATIME_IS_SET; - } - break; - case EXT_FILESIZE: - if (datasize == sizeof(uint64_t) * 2) { - lha->compsize = archive_le64dec(extdheader); - extdheader += sizeof(uint64_t); - lha->origsize = archive_le64dec(extdheader); - } - break; - case EXT_CODEPAGE: - /* Get an archived filename charset from codepage. - * This overwrites the charset specified by - * hdrcharset option. */ - if (datasize == sizeof(uint32_t)) { - struct archive_string cp; - const char *charset; - - archive_string_init(&cp); - switch (archive_le32dec(extdheader)) { - case 65001: /* UTF-8 */ - charset = "UTF-8"; - break; - default: - archive_string_sprintf(&cp, "CP%d", - (int)archive_le32dec(extdheader)); - charset = cp.s; - break; - } - lha->sconv_dir = - archive_string_conversion_from_charset( - &(a->archive), charset, 1); - lha->sconv_fname = - archive_string_conversion_from_charset( - &(a->archive), charset, 1); - archive_string_free(&cp); - if (lha->sconv_dir == NULL) - return (ARCHIVE_FATAL); - if (lha->sconv_fname == NULL) - return (ARCHIVE_FATAL); - } - break; - case EXT_UNIX_MODE: - if (datasize == sizeof(uint16_t)) { - lha->mode = archive_le16dec(extdheader); - lha->setflag |= UNIX_MODE_IS_SET; - } - break; - case EXT_UNIX_GID_UID: - if (datasize == (sizeof(uint16_t) * 2)) { - lha->gid = archive_le16dec(extdheader); - lha->uid = archive_le16dec(extdheader+2); - } - break; - case EXT_UNIX_GNAME: - if (datasize > 0) - archive_strncpy(&lha->gname, - (const char *)extdheader, datasize); - break; - case EXT_UNIX_UNAME: - if (datasize > 0) - archive_strncpy(&lha->uname, - (const char *)extdheader, datasize); - break; - case EXT_UNIX_MTIME: - if (datasize == sizeof(uint32_t)) - lha->mtime = archive_le32dec(extdheader); - break; - case EXT_OS2_NEW_ATTR: - /* This extended header is OS/2 depend. */ - if (datasize == 16) { - lha->dos_attr = (unsigned char) - (archive_le16dec(extdheader) & 0xff); - lha->mode = archive_le16dec(extdheader+2); - lha->gid = archive_le16dec(extdheader+4); - lha->uid = archive_le16dec(extdheader+6); - lha->birthtime = archive_le32dec(extdheader+8); - lha->atime = archive_le32dec(extdheader+12); - lha->setflag |= UNIX_MODE_IS_SET - | BIRTHTIME_IS_SET | ATIME_IS_SET; - } - break; - case EXT_NEW_ATTR: - if (datasize == 20) { - lha->mode = (mode_t)archive_le32dec(extdheader); - lha->gid = archive_le32dec(extdheader+4); - lha->uid = archive_le32dec(extdheader+8); - lha->birthtime = archive_le32dec(extdheader+12); - lha->atime = archive_le32dec(extdheader+16); - lha->setflag |= UNIX_MODE_IS_SET - | BIRTHTIME_IS_SET | ATIME_IS_SET; - } - break; - case EXT_TIMEZONE: /* Not supported */ - break; - default: - break; - } - - __archive_read_consume(a, extdsize); - } -invalid: - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid extended LHa header"); - return (ARCHIVE_FATAL); -} - -static int -lha_end_of_entry(struct archive_read *a) -{ - struct lha *lha = (struct lha *)(a->format->data); - int r = ARCHIVE_EOF; - - if (!lha->end_of_entry_cleanup) { - if ((lha->setflag & CRC_IS_SET) && - lha->crc != lha->entry_crc_calculated) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "LHa data CRC error"); - r = ARCHIVE_WARN; - } - - /* End-of-entry cleanup done. */ - lha->end_of_entry_cleanup = 1; - } - return (r); -} - -static int -archive_read_format_lha_read_data(struct archive_read *a, - const void **buff, size_t *size, int64_t *offset) -{ - struct lha *lha = (struct lha *)(a->format->data); - int r; - - if (lha->entry_unconsumed) { - /* Consume as much as the decompressor actually used. */ - __archive_read_consume(a, lha->entry_unconsumed); - lha->entry_unconsumed = 0; - } - if (lha->end_of_entry) { - *offset = lha->entry_offset; - *size = 0; - *buff = NULL; - return (lha_end_of_entry(a)); - } - - if (lha->entry_is_compressed) - r = lha_read_data_lzh(a, buff, size, offset); - else - /* No compression. */ - r = lha_read_data_none(a, buff, size, offset); - return (r); -} - -/* - * Read a file content in no compression. - * - * Returns ARCHIVE_OK if successful, ARCHIVE_FATAL otherwise, sets - * lha->end_of_entry if it consumes all of the data. - */ -static int -lha_read_data_none(struct archive_read *a, const void **buff, - size_t *size, int64_t *offset) -{ - struct lha *lha = (struct lha *)(a->format->data); - ssize_t bytes_avail; - - if (lha->entry_bytes_remaining == 0) { - *buff = NULL; - *size = 0; - *offset = lha->entry_offset; - lha->end_of_entry = 1; - return (ARCHIVE_OK); - } - /* - * Note: '1' here is a performance optimization. - * Recall that the decompression layer returns a count of - * available bytes; asking for more than that forces the - * decompressor to combine reads by copying data. - */ - *buff = __archive_read_ahead(a, 1, &bytes_avail); - if (bytes_avail <= 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated LHa file data"); - return (ARCHIVE_FATAL); - } - if (bytes_avail > lha->entry_bytes_remaining) - bytes_avail = (ssize_t)lha->entry_bytes_remaining; - lha->entry_crc_calculated = - lha_crc16(lha->entry_crc_calculated, *buff, bytes_avail); - *size = bytes_avail; - *offset = lha->entry_offset; - lha->entry_offset += bytes_avail; - lha->entry_bytes_remaining -= bytes_avail; - if (lha->entry_bytes_remaining == 0) - lha->end_of_entry = 1; - lha->entry_unconsumed = bytes_avail; - return (ARCHIVE_OK); -} - -/* - * Read a file content in LZHUFF encoding. - * - * Returns ARCHIVE_OK if successful, returns ARCHIVE_WARN if compression is - * unsupported, ARCHIVE_FATAL otherwise, sets lha->end_of_entry if it consumes - * all of the data. - */ -static int -lha_read_data_lzh(struct archive_read *a, const void **buff, - size_t *size, int64_t *offset) -{ - struct lha *lha = (struct lha *)(a->format->data); - ssize_t bytes_avail; - int r; - - /* If we haven't yet read any data, initialize the decompressor. */ - if (!lha->decompress_init) { - r = lzh_decode_init(&(lha->strm), lha->method); - switch (r) { - case ARCHIVE_OK: - break; - case ARCHIVE_FAILED: - /* Unsupported compression. */ - *buff = NULL; - *size = 0; - *offset = 0; - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Unsupported lzh compression method -%c%c%c-", - lha->method[0], lha->method[1], lha->method[2]); - /* We know compressed size; just skip it. */ - archive_read_format_lha_read_data_skip(a); - return (ARCHIVE_WARN); - default: - archive_set_error(&a->archive, ENOMEM, - "Couldn't allocate memory " - "for lzh decompression"); - return (ARCHIVE_FATAL); - } - /* We've initialized decompression for this stream. */ - lha->decompress_init = 1; - lha->strm.avail_out = 0; - lha->strm.total_out = 0; - } - - /* - * Note: '1' here is a performance optimization. - * Recall that the decompression layer returns a count of - * available bytes; asking for more than that forces the - * decompressor to combine reads by copying data. - */ - lha->strm.next_in = __archive_read_ahead(a, 1, &bytes_avail); - if (bytes_avail <= 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated LHa file body"); - return (ARCHIVE_FATAL); - } - if (bytes_avail > lha->entry_bytes_remaining) - bytes_avail = (ssize_t)lha->entry_bytes_remaining; - - lha->strm.avail_in = (int)bytes_avail; - lha->strm.total_in = 0; - lha->strm.avail_out = 0; - - r = lzh_decode(&(lha->strm), bytes_avail == lha->entry_bytes_remaining); - switch (r) { - case ARCHIVE_OK: - break; - case ARCHIVE_EOF: - lha->end_of_entry = 1; - break; - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Bad lzh data"); - return (ARCHIVE_FAILED); - } - lha->entry_unconsumed = lha->strm.total_in; - lha->entry_bytes_remaining -= lha->strm.total_in; - - if (lha->strm.avail_out) { - *offset = lha->entry_offset; - *size = lha->strm.avail_out; - *buff = lha->strm.ref_ptr; - lha->entry_crc_calculated = - lha_crc16(lha->entry_crc_calculated, *buff, *size); - lha->entry_offset += *size; - } else { - *offset = lha->entry_offset; - *size = 0; - *buff = NULL; - if (lha->end_of_entry) - return (lha_end_of_entry(a)); - } - return (ARCHIVE_OK); -} - -/* - * Skip a file content. - */ -static int -archive_read_format_lha_read_data_skip(struct archive_read *a) -{ - struct lha *lha; - int64_t bytes_skipped; - - lha = (struct lha *)(a->format->data); - - if (lha->entry_unconsumed) { - /* Consume as much as the decompressor actually used. */ - __archive_read_consume(a, lha->entry_unconsumed); - lha->entry_unconsumed = 0; - } - - /* if we've already read to end of data, we're done. */ - if (lha->end_of_entry_cleanup) - return (ARCHIVE_OK); - - /* - * If the length is at the beginning, we can skip the - * compressed data much more quickly. - */ - bytes_skipped = __archive_read_consume(a, lha->entry_bytes_remaining); - if (bytes_skipped < 0) - return (ARCHIVE_FATAL); - - /* This entry is finished and done. */ - lha->end_of_entry_cleanup = lha->end_of_entry = 1; - return (ARCHIVE_OK); -} - -static int -archive_read_format_lha_cleanup(struct archive_read *a) -{ - struct lha *lha = (struct lha *)(a->format->data); - - lzh_decode_free(&(lha->strm)); - archive_string_free(&(lha->dirname)); - archive_string_free(&(lha->filename)); - archive_string_free(&(lha->uname)); - archive_string_free(&(lha->gname)); - archive_wstring_free(&(lha->ws)); - free(lha); - (a->format->data) = NULL; - return (ARCHIVE_OK); -} - -/* - * 'LHa for UNIX' utility has archived a symbolic-link name after - * a pathname with '|' character. - * This function extracts the symbolic-link name from the pathname. - * - * example. - * 1. a symbolic-name is 'aaa/bb/cc' - * 2. a filename is 'xxx/bbb' - * then a archived pathname is 'xxx/bbb|aaa/bb/cc' - */ -static int -lha_parse_linkname(struct archive_wstring *linkname, - struct archive_wstring *pathname) -{ - wchar_t * linkptr; - size_t symlen; - - linkptr = wcschr(pathname->s, L'|'); - if (linkptr != NULL) { - symlen = wcslen(linkptr + 1); - archive_wstrncpy(linkname, linkptr+1, symlen); - - *linkptr = 0; - pathname->length = wcslen(pathname->s); - - return (1); - } - return (0); -} - -/* Convert an MSDOS-style date/time into Unix-style time. */ -static time_t -lha_dos_time(const unsigned char *p) -{ - int msTime, msDate; - struct tm ts; - - msTime = archive_le16dec(p); - msDate = archive_le16dec(p+2); - - memset(&ts, 0, sizeof(ts)); - ts.tm_year = ((msDate >> 9) & 0x7f) + 80; /* Years since 1900. */ - ts.tm_mon = ((msDate >> 5) & 0x0f) - 1; /* Month number. */ - ts.tm_mday = msDate & 0x1f; /* Day of month. */ - ts.tm_hour = (msTime >> 11) & 0x1f; - ts.tm_min = (msTime >> 5) & 0x3f; - ts.tm_sec = (msTime << 1) & 0x3e; - ts.tm_isdst = -1; - return (mktime(&ts)); -} - -/* Convert an MS-Windows-style date/time into Unix-style time. */ -static time_t -lha_win_time(uint64_t wintime, long *ns) -{ -#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000) - - if (wintime >= EPOC_TIME) { - wintime -= EPOC_TIME; /* 1970-01-01 00:00:00 (UTC) */ - if (ns != NULL) - *ns = (long)(wintime % 10000000) * 100; - return (wintime / 10000000); - } else { - if (ns != NULL) - *ns = 0; - return (0); - } -} - -static unsigned char -lha_calcsum(unsigned char sum, const void *pp, int offset, size_t size) -{ - unsigned char const *p = (unsigned char const *)pp; - - p += offset; - for (;size > 0; --size) - sum += *p++; - return (sum); -} - -static uint16_t crc16tbl[2][256]; -static void -lha_crc16_init(void) -{ - unsigned int i; - static int crc16init = 0; - - if (crc16init) - return; - crc16init = 1; - - for (i = 0; i < 256; i++) { - unsigned int j; - uint16_t crc = (uint16_t)i; - for (j = 8; j; j--) - crc = (crc >> 1) ^ ((crc & 1) * 0xA001); - crc16tbl[0][i] = crc; - } - - for (i = 0; i < 256; i++) { - crc16tbl[1][i] = (crc16tbl[0][i] >> 8) - ^ crc16tbl[0][crc16tbl[0][i] & 0xff]; - } -} - -static uint16_t -lha_crc16(uint16_t crc, const void *pp, size_t len) -{ - const unsigned char *p = (const unsigned char *)pp; - const uint16_t *buff; - const union { - uint32_t i; - char c[4]; - } u = { 0x01020304 }; - - if (len == 0) - return crc; - - /* Process unaligned address. */ - if (((uintptr_t)p) & (uintptr_t)0x1) { - crc = (crc >> 8) ^ crc16tbl[0][(crc ^ *p++) & 0xff]; - len--; - } - buff = (const uint16_t *)p; - /* - * Modern C compiler such as GCC does not unroll automatically yet - * without unrolling pragma, and Clang is so. So we should - * unroll this loop for its performance. - */ - for (;len >= 8; len -= 8) { - /* This if statement expects compiler optimization will - * remove the statement which will not be executed. */ -#undef bswap16 -#ifndef __has_builtin -#define __has_builtin(x) 0 -#endif -#if defined(_MSC_VER) && _MSC_VER >= 1400 /* Visual Studio */ -# define bswap16(x) _byteswap_ushort(x) -#elif defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || __GNUC__ > 4) -/* GCC 4.8 and later has __builtin_bswap16() */ -# define bswap16(x) __builtin_bswap16(x) -#elif defined(__clang__) && __has_builtin(__builtin_bswap16) -/* Newer clang versions have __builtin_bswap16() */ -# define bswap16(x) __builtin_bswap16(x) -#else -# define bswap16(x) ((((x) >> 8) & 0xff) | ((x) << 8)) -#endif -#define CRC16W do { \ - if(u.c[0] == 1) { /* Big endian */ \ - crc ^= bswap16(*buff); buff++; \ - } else \ - crc ^= *buff++; \ - crc = crc16tbl[1][crc & 0xff] ^ crc16tbl[0][crc >> 8];\ -} while (0) - CRC16W; - CRC16W; - CRC16W; - CRC16W; -#undef CRC16W -#undef bswap16 - } - - p = (const unsigned char *)buff; - for (;len; len--) { - crc = (crc >> 8) ^ crc16tbl[0][(crc ^ *p++) & 0xff]; - } - return crc; -} - -/* - * Initialize LZHUF decoder. - * - * Returns ARCHIVE_OK if initialization was successful. - * Returns ARCHIVE_FAILED if method is unsupported. - * Returns ARCHIVE_FATAL if initialization failed; memory allocation - * error occurred. - */ -static int -lzh_decode_init(struct lzh_stream *strm, const char *method) -{ - struct lzh_dec *ds; - int w_bits, w_size; - - if (strm->ds == NULL) { - strm->ds = calloc(1, sizeof(*strm->ds)); - if (strm->ds == NULL) - return (ARCHIVE_FATAL); - } - ds = strm->ds; - ds->error = ARCHIVE_FAILED; - if (method == NULL || method[0] != 'l' || method[1] != 'h') - return (ARCHIVE_FAILED); - switch (method[2]) { - case '5': - w_bits = 13;/* 8KiB for window */ - break; - case '6': - w_bits = 15;/* 32KiB for window */ - break; - case '7': - w_bits = 16;/* 64KiB for window */ - break; - default: - return (ARCHIVE_FAILED);/* Not supported. */ - } - ds->error = ARCHIVE_FATAL; - /* Expand a window size up to 128 KiB for decompressing process - * performance whatever its original window size is. */ - ds->w_size = 1U << 17; - ds->w_mask = ds->w_size -1; - if (ds->w_buff == NULL) { - ds->w_buff = malloc(ds->w_size); - if (ds->w_buff == NULL) - return (ARCHIVE_FATAL); - } - w_size = 1U << w_bits; - memset(ds->w_buff + ds->w_size - w_size, 0x20, w_size); - ds->w_pos = 0; - ds->state = 0; - ds->pos_pt_len_size = w_bits + 1; - ds->pos_pt_len_bits = (w_bits == 15 || w_bits == 16)? 5: 4; - ds->literal_pt_len_size = PT_BITLEN_SIZE; - ds->literal_pt_len_bits = 5; - ds->br.cache_buffer = 0; - ds->br.cache_avail = 0; - - if (lzh_huffman_init(&(ds->lt), LT_BITLEN_SIZE, 16) - != ARCHIVE_OK) - return (ARCHIVE_FATAL); - ds->lt.len_bits = 9; - if (lzh_huffman_init(&(ds->pt), PT_BITLEN_SIZE, 16) - != ARCHIVE_OK) - return (ARCHIVE_FATAL); - ds->error = 0; - - return (ARCHIVE_OK); -} - -/* - * Release LZHUF decoder. - */ -static void -lzh_decode_free(struct lzh_stream *strm) -{ - - if (strm->ds == NULL) - return; - free(strm->ds->w_buff); - lzh_huffman_free(&(strm->ds->lt)); - lzh_huffman_free(&(strm->ds->pt)); - free(strm->ds); - strm->ds = NULL; -} - -/* - * Bit stream reader. - */ -/* Check that the cache buffer has enough bits. */ -#define lzh_br_has(br, n) ((br)->cache_avail >= n) -/* Get compressed data by bit. */ -#define lzh_br_bits(br, n) \ - (((uint16_t)((br)->cache_buffer >> \ - ((br)->cache_avail - (n)))) & cache_masks[n]) -#define lzh_br_bits_forced(br, n) \ - (((uint16_t)((br)->cache_buffer << \ - ((n) - (br)->cache_avail))) & cache_masks[n]) -/* Read ahead to make sure the cache buffer has enough compressed data we - * will use. - * True : completed, there is enough data in the cache buffer. - * False : we met that strm->next_in is empty, we have to get following - * bytes. */ -#define lzh_br_read_ahead_0(strm, br, n) \ - (lzh_br_has(br, (n)) || lzh_br_fillup(strm, br)) -/* True : the cache buffer has some bits as much as we need. - * False : there are no enough bits in the cache buffer to be used, - * we have to get following bytes if we could. */ -#define lzh_br_read_ahead(strm, br, n) \ - (lzh_br_read_ahead_0((strm), (br), (n)) || lzh_br_has((br), (n))) - -/* Notify how many bits we consumed. */ -#define lzh_br_consume(br, n) ((br)->cache_avail -= (n)) -#define lzh_br_unconsume(br, n) ((br)->cache_avail += (n)) - -static const uint16_t cache_masks[] = { - 0x0000, 0x0001, 0x0003, 0x0007, - 0x000F, 0x001F, 0x003F, 0x007F, - 0x00FF, 0x01FF, 0x03FF, 0x07FF, - 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, - 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF -}; - -/* - * Shift away used bits in the cache data and fill it up with following bits. - * Call this when cache buffer does not have enough bits you need. - * - * Returns 1 if the cache buffer is full. - * Returns 0 if the cache buffer is not full; input buffer is empty. - */ -static int -lzh_br_fillup(struct lzh_stream *strm, struct lzh_br *br) -{ - int n = CACHE_BITS - br->cache_avail; - - for (;;) { - const int x = n >> 3; - if (strm->avail_in >= x) { - switch (x) { - case 8: - br->cache_buffer = - ((uint64_t)strm->next_in[0]) << 56 | - ((uint64_t)strm->next_in[1]) << 48 | - ((uint64_t)strm->next_in[2]) << 40 | - ((uint64_t)strm->next_in[3]) << 32 | - ((uint32_t)strm->next_in[4]) << 24 | - ((uint32_t)strm->next_in[5]) << 16 | - ((uint32_t)strm->next_in[6]) << 8 | - (uint32_t)strm->next_in[7]; - strm->next_in += 8; - strm->avail_in -= 8; - br->cache_avail += 8 * 8; - return (1); - case 7: - br->cache_buffer = - (br->cache_buffer << 56) | - ((uint64_t)strm->next_in[0]) << 48 | - ((uint64_t)strm->next_in[1]) << 40 | - ((uint64_t)strm->next_in[2]) << 32 | - ((uint64_t)strm->next_in[3]) << 24 | - ((uint64_t)strm->next_in[4]) << 16 | - ((uint64_t)strm->next_in[5]) << 8 | - (uint64_t)strm->next_in[6]; - strm->next_in += 7; - strm->avail_in -= 7; - br->cache_avail += 7 * 8; - return (1); - case 6: - br->cache_buffer = - (br->cache_buffer << 48) | - ((uint64_t)strm->next_in[0]) << 40 | - ((uint64_t)strm->next_in[1]) << 32 | - ((uint64_t)strm->next_in[2]) << 24 | - ((uint64_t)strm->next_in[3]) << 16 | - ((uint64_t)strm->next_in[4]) << 8 | - (uint64_t)strm->next_in[5]; - strm->next_in += 6; - strm->avail_in -= 6; - br->cache_avail += 6 * 8; - return (1); - case 0: - /* We have enough compressed data in - * the cache buffer.*/ - return (1); - default: - break; - } - } - if (strm->avail_in == 0) { - /* There is not enough compressed data to fill up the - * cache buffer. */ - return (0); - } - br->cache_buffer = - (br->cache_buffer << 8) | *strm->next_in++; - strm->avail_in--; - br->cache_avail += 8; - n -= 8; - } -} - -/* - * Decode LZHUF. - * - * 1. Returns ARCHIVE_OK if output buffer or input buffer are empty. - * Please set available buffer and call this function again. - * 2. Returns ARCHIVE_EOF if decompression has been completed. - * 3. Returns ARCHIVE_FAILED if an error occurred; compressed data - * is broken or you do not set 'last' flag properly. - * 4. 'last' flag is very important, you must set 1 to the flag if there - * is no input data. The lha compressed data format does not provide how - * to know the compressed data is really finished. - * Note: lha command utility check if the total size of output bytes is - * reached the uncompressed size recorded in its header. it does not mind - * that the decoding process is properly finished. - * GNU ZIP can decompress another compressed file made by SCO LZH compress. - * it handles EOF as null to fill read buffer with zero until the decoding - * process meet 2 bytes of zeros at reading a size of a next chunk, so the - * zeros are treated as the mark of the end of the data although the zeros - * is dummy, not the file data. - */ -static int lzh_read_blocks(struct lzh_stream *, int); -static int lzh_decode_blocks(struct lzh_stream *, int); -#define ST_RD_BLOCK 0 -#define ST_RD_PT_1 1 -#define ST_RD_PT_2 2 -#define ST_RD_PT_3 3 -#define ST_RD_PT_4 4 -#define ST_RD_LITERAL_1 5 -#define ST_RD_LITERAL_2 6 -#define ST_RD_LITERAL_3 7 -#define ST_RD_POS_DATA_1 8 -#define ST_GET_LITERAL 9 -#define ST_GET_POS_1 10 -#define ST_GET_POS_2 11 -#define ST_COPY_DATA 12 - -static int -lzh_decode(struct lzh_stream *strm, int last) -{ - struct lzh_dec *ds = strm->ds; - int avail_in; - int r; - - if (ds->error) - return (ds->error); - - avail_in = strm->avail_in; - do { - if (ds->state < ST_GET_LITERAL) - r = lzh_read_blocks(strm, last); - else - r = lzh_decode_blocks(strm, last); - } while (r == 100); - strm->total_in += avail_in - strm->avail_in; - return (r); -} - -static void -lzh_emit_window(struct lzh_stream *strm, size_t s) -{ - strm->ref_ptr = strm->ds->w_buff; - strm->avail_out = (int)s; - strm->total_out += s; -} - -static int -lzh_read_blocks(struct lzh_stream *strm, int last) -{ - struct lzh_dec *ds = strm->ds; - struct lzh_br *br = &(ds->br); - int c = 0, i; - unsigned rbits; - - for (;;) { - switch (ds->state) { - case ST_RD_BLOCK: - /* - * Read a block number indicates how many blocks - * we will handle. The block is composed of a - * literal and a match, sometimes a literal only - * in particular, there are no reference data at - * the beginning of the decompression. - */ - if (!lzh_br_read_ahead_0(strm, br, 16)) { - if (!last) - /* We need following data. */ - return (ARCHIVE_OK); - if (lzh_br_has(br, 8)) { - /* - * It seems there are extra bits. - * 1. Compressed data is broken. - * 2. `last' flag does not properly - * set. - */ - goto failed; - } - if (ds->w_pos > 0) { - lzh_emit_window(strm, ds->w_pos); - ds->w_pos = 0; - return (ARCHIVE_OK); - } - /* End of compressed data; we have completely - * handled all compressed data. */ - return (ARCHIVE_EOF); - } - ds->blocks_avail = lzh_br_bits(br, 16); - if (ds->blocks_avail == 0) - goto failed; - lzh_br_consume(br, 16); - /* - * Read a literal table compressed in huffman - * coding. - */ - ds->pt.len_size = ds->literal_pt_len_size; - ds->pt.len_bits = ds->literal_pt_len_bits; - ds->reading_position = 0; - /* FALL THROUGH */ - case ST_RD_PT_1: - /* Note: ST_RD_PT_1, ST_RD_PT_2 and ST_RD_PT_4 are - * used in reading both a literal table and a - * position table. */ - if (!lzh_br_read_ahead(strm, br, ds->pt.len_bits)) { - if (last) - goto failed;/* Truncated data. */ - ds->state = ST_RD_PT_1; - return (ARCHIVE_OK); - } - ds->pt.len_avail = lzh_br_bits(br, ds->pt.len_bits); - lzh_br_consume(br, ds->pt.len_bits); - /* FALL THROUGH */ - case ST_RD_PT_2: - if (ds->pt.len_avail == 0) { - /* There is no bitlen. */ - if (!lzh_br_read_ahead(strm, br, - ds->pt.len_bits)) { - if (last) - goto failed;/* Truncated data.*/ - ds->state = ST_RD_PT_2; - return (ARCHIVE_OK); - } - if (!lzh_make_fake_table(&(ds->pt), - lzh_br_bits(br, ds->pt.len_bits))) - goto failed;/* Invalid data. */ - lzh_br_consume(br, ds->pt.len_bits); - if (ds->reading_position) - ds->state = ST_GET_LITERAL; - else - ds->state = ST_RD_LITERAL_1; - break; - } else if (ds->pt.len_avail > ds->pt.len_size) - goto failed;/* Invalid data. */ - ds->loop = 0; - memset(ds->pt.freq, 0, sizeof(ds->pt.freq)); - if (ds->pt.len_avail < 3 || - ds->pt.len_size == ds->pos_pt_len_size) { - ds->state = ST_RD_PT_4; - break; - } - /* FALL THROUGH */ - case ST_RD_PT_3: - ds->loop = lzh_read_pt_bitlen(strm, ds->loop, 3); - if (ds->loop < 3) { - if (ds->loop < 0 || last) - goto failed;/* Invalid data. */ - /* Not completed, get following data. */ - ds->state = ST_RD_PT_3; - return (ARCHIVE_OK); - } - /* There are some null in bitlen of the literal. */ - if (!lzh_br_read_ahead(strm, br, 2)) { - if (last) - goto failed;/* Truncated data. */ - ds->state = ST_RD_PT_3; - return (ARCHIVE_OK); - } - c = lzh_br_bits(br, 2); - lzh_br_consume(br, 2); - if (c > ds->pt.len_avail - 3) - goto failed;/* Invalid data. */ - for (i = 3; c-- > 0 ;) - ds->pt.bitlen[i++] = 0; - ds->loop = i; - /* FALL THROUGH */ - case ST_RD_PT_4: - ds->loop = lzh_read_pt_bitlen(strm, ds->loop, - ds->pt.len_avail); - if (ds->loop < ds->pt.len_avail) { - if (ds->loop < 0 || last) - goto failed;/* Invalid data. */ - /* Not completed, get following data. */ - ds->state = ST_RD_PT_4; - return (ARCHIVE_OK); - } - if (!lzh_make_huffman_table(&(ds->pt))) - goto failed;/* Invalid data */ - if (ds->reading_position) { - ds->state = ST_GET_LITERAL; - break; - } - /* FALL THROUGH */ - case ST_RD_LITERAL_1: - if (!lzh_br_read_ahead(strm, br, ds->lt.len_bits)) { - if (last) - goto failed;/* Truncated data. */ - ds->state = ST_RD_LITERAL_1; - return (ARCHIVE_OK); - } - ds->lt.len_avail = lzh_br_bits(br, ds->lt.len_bits); - lzh_br_consume(br, ds->lt.len_bits); - /* FALL THROUGH */ - case ST_RD_LITERAL_2: - if (ds->lt.len_avail == 0) { - /* There is no bitlen. */ - if (!lzh_br_read_ahead(strm, br, - ds->lt.len_bits)) { - if (last) - goto failed;/* Truncated data.*/ - ds->state = ST_RD_LITERAL_2; - return (ARCHIVE_OK); - } - if (!lzh_make_fake_table(&(ds->lt), - lzh_br_bits(br, ds->lt.len_bits))) - goto failed;/* Invalid data */ - lzh_br_consume(br, ds->lt.len_bits); - ds->state = ST_RD_POS_DATA_1; - break; - } else if (ds->lt.len_avail > ds->lt.len_size) - goto failed;/* Invalid data */ - ds->loop = 0; - memset(ds->lt.freq, 0, sizeof(ds->lt.freq)); - /* FALL THROUGH */ - case ST_RD_LITERAL_3: - i = ds->loop; - while (i < ds->lt.len_avail) { - if (!lzh_br_read_ahead(strm, br, - ds->pt.max_bits)) { - if (last) - goto failed;/* Truncated data.*/ - ds->loop = i; - ds->state = ST_RD_LITERAL_3; - return (ARCHIVE_OK); - } - rbits = lzh_br_bits(br, ds->pt.max_bits); - c = lzh_decode_huffman(&(ds->pt), rbits); - if (c > 2) { - /* Note: 'c' will never be more than - * eighteen since it's limited by - * PT_BITLEN_SIZE, which is being set - * to ds->pt.len_size through - * ds->literal_pt_len_size. */ - lzh_br_consume(br, ds->pt.bitlen[c]); - c -= 2; - ds->lt.freq[c]++; - ds->lt.bitlen[i++] = c; - } else if (c == 0) { - lzh_br_consume(br, ds->pt.bitlen[c]); - ds->lt.bitlen[i++] = 0; - } else { - /* c == 1 or c == 2 */ - int n = (c == 1)?4:9; - if (!lzh_br_read_ahead(strm, br, - ds->pt.bitlen[c] + n)) { - if (last) /* Truncated data. */ - goto failed; - ds->loop = i; - ds->state = ST_RD_LITERAL_3; - return (ARCHIVE_OK); - } - lzh_br_consume(br, ds->pt.bitlen[c]); - c = lzh_br_bits(br, n); - lzh_br_consume(br, n); - c += (n == 4)?3:20; - if (i + c > ds->lt.len_avail) - goto failed;/* Invalid data */ - memset(&(ds->lt.bitlen[i]), 0, c); - i += c; - } - } - if (i > ds->lt.len_avail || - !lzh_make_huffman_table(&(ds->lt))) - goto failed;/* Invalid data */ - /* FALL THROUGH */ - case ST_RD_POS_DATA_1: - /* - * Read a position table compressed in huffman - * coding. - */ - ds->pt.len_size = ds->pos_pt_len_size; - ds->pt.len_bits = ds->pos_pt_len_bits; - ds->reading_position = 1; - ds->state = ST_RD_PT_1; - break; - case ST_GET_LITERAL: - return (100); - } - } -failed: - return (ds->error = ARCHIVE_FAILED); -} - -static int -lzh_decode_blocks(struct lzh_stream *strm, int last) -{ - struct lzh_dec *ds = strm->ds; - struct lzh_br bre = ds->br; - struct huffman *lt = &(ds->lt); - struct huffman *pt = &(ds->pt); - unsigned char *w_buff = ds->w_buff; - unsigned char *lt_bitlen = lt->bitlen; - unsigned char *pt_bitlen = pt->bitlen; - int blocks_avail = ds->blocks_avail, c = 0; - int copy_len = ds->copy_len, copy_pos = ds->copy_pos; - int w_pos = ds->w_pos, w_mask = ds->w_mask, w_size = ds->w_size; - int lt_max_bits = lt->max_bits, pt_max_bits = pt->max_bits; - int state = ds->state; - - for (;;) { - switch (state) { - case ST_GET_LITERAL: - for (;;) { - if (blocks_avail == 0) { - /* We have decoded all blocks. - * Let's handle next blocks. */ - ds->state = ST_RD_BLOCK; - ds->br = bre; - ds->blocks_avail = 0; - ds->w_pos = w_pos; - ds->copy_pos = 0; - return (100); - } - - /* lzh_br_read_ahead() always try to fill the - * cache buffer up. In specific situation we - * are close to the end of the data, the cache - * buffer will not be full and thus we have to - * determine if the cache buffer has some bits - * as much as we need after lzh_br_read_ahead() - * failed. */ - if (!lzh_br_read_ahead(strm, &bre, - lt_max_bits)) { - if (!last) - goto next_data; - /* Remaining bits are less than - * maximum bits(lt.max_bits) but maybe - * it still remains as much as we need, - * so we should try to use it with - * dummy bits. */ - c = lzh_decode_huffman(lt, - lzh_br_bits_forced(&bre, - lt_max_bits)); - lzh_br_consume(&bre, lt_bitlen[c]); - if (!lzh_br_has(&bre, 0)) - goto failed;/* Over read. */ - } else { - c = lzh_decode_huffman(lt, - lzh_br_bits(&bre, lt_max_bits)); - lzh_br_consume(&bre, lt_bitlen[c]); - } - blocks_avail--; - if (c > UCHAR_MAX) - /* Current block is a match data. */ - break; - /* - * 'c' is exactly a literal code. - */ - /* Save a decoded code to reference it - * afterward. */ - w_buff[w_pos] = c; - if (++w_pos >= w_size) { - w_pos = 0; - lzh_emit_window(strm, w_size); - goto next_data; - } - } - /* 'c' is the length of a match pattern we have - * already extracted, which has be stored in - * window(ds->w_buff). */ - copy_len = c - (UCHAR_MAX + 1) + MINMATCH; - /* FALL THROUGH */ - case ST_GET_POS_1: - /* - * Get a reference position. - */ - if (!lzh_br_read_ahead(strm, &bre, pt_max_bits)) { - if (!last) { - state = ST_GET_POS_1; - ds->copy_len = copy_len; - goto next_data; - } - copy_pos = lzh_decode_huffman(pt, - lzh_br_bits_forced(&bre, pt_max_bits)); - lzh_br_consume(&bre, pt_bitlen[copy_pos]); - if (!lzh_br_has(&bre, 0)) - goto failed;/* Over read. */ - } else { - copy_pos = lzh_decode_huffman(pt, - lzh_br_bits(&bre, pt_max_bits)); - lzh_br_consume(&bre, pt_bitlen[copy_pos]); - } - /* FALL THROUGH */ - case ST_GET_POS_2: - if (copy_pos > 1) { - /* We need an additional adjustment number to - * the position. */ - int p = copy_pos - 1; - if (!lzh_br_read_ahead(strm, &bre, p)) { - if (last) - goto failed;/* Truncated data.*/ - state = ST_GET_POS_2; - ds->copy_len = copy_len; - ds->copy_pos = copy_pos; - goto next_data; - } - copy_pos = (1 << p) + lzh_br_bits(&bre, p); - lzh_br_consume(&bre, p); - } - /* The position is actually a distance from the last - * code we had extracted and thus we have to convert - * it to a position of the window. */ - copy_pos = (w_pos - copy_pos - 1) & w_mask; - /* FALL THROUGH */ - case ST_COPY_DATA: - /* - * Copy `copy_len' bytes as extracted data from - * the window into the output buffer. - */ - for (;;) { - int l; - - l = copy_len; - if (copy_pos > w_pos) { - if (l > w_size - copy_pos) - l = w_size - copy_pos; - } else { - if (l > w_size - w_pos) - l = w_size - w_pos; - } - if ((copy_pos + l < w_pos) - || (w_pos + l < copy_pos)) { - /* No overlap. */ - memcpy(w_buff + w_pos, - w_buff + copy_pos, l); - } else { - const unsigned char *s; - unsigned char *d; - int li; - - d = w_buff + w_pos; - s = w_buff + copy_pos; - for (li = 0; li < l-1;) { - d[li] = s[li];li++; - d[li] = s[li];li++; - } - if (li < l) - d[li] = s[li]; - } - w_pos += l; - if (w_pos == w_size) { - w_pos = 0; - lzh_emit_window(strm, w_size); - if (copy_len <= l) - state = ST_GET_LITERAL; - else { - state = ST_COPY_DATA; - ds->copy_len = copy_len - l; - ds->copy_pos = - (copy_pos + l) & w_mask; - } - goto next_data; - } - if (copy_len <= l) - /* A copy of current pattern ended. */ - break; - copy_len -= l; - copy_pos = (copy_pos + l) & w_mask; - } - state = ST_GET_LITERAL; - break; - } - } -failed: - return (ds->error = ARCHIVE_FAILED); -next_data: - ds->br = bre; - ds->blocks_avail = blocks_avail; - ds->state = state; - ds->w_pos = w_pos; - return (ARCHIVE_OK); -} - -static int -lzh_huffman_init(struct huffman *hf, size_t len_size, int tbl_bits) -{ - int bits; - - if (hf->bitlen == NULL) { - hf->bitlen = malloc(len_size * sizeof(hf->bitlen[0])); - if (hf->bitlen == NULL) - return (ARCHIVE_FATAL); - } - if (hf->tbl == NULL) { - if (tbl_bits < HTBL_BITS) - bits = tbl_bits; - else - bits = HTBL_BITS; - hf->tbl = malloc(((size_t)1 << bits) * sizeof(hf->tbl[0])); - if (hf->tbl == NULL) - return (ARCHIVE_FATAL); - } - if (hf->tree == NULL && tbl_bits > HTBL_BITS) { - hf->tree_avail = 1 << (tbl_bits - HTBL_BITS + 4); - hf->tree = malloc(hf->tree_avail * sizeof(hf->tree[0])); - if (hf->tree == NULL) - return (ARCHIVE_FATAL); - } - hf->len_size = (int)len_size; - hf->tbl_bits = tbl_bits; - return (ARCHIVE_OK); -} - -static void -lzh_huffman_free(struct huffman *hf) -{ - free(hf->bitlen); - free(hf->tbl); - free(hf->tree); -} - -static const char bitlen_tbl[0x400] = { - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 16, 0 -}; -static int -lzh_read_pt_bitlen(struct lzh_stream *strm, int start, int end) -{ - struct lzh_dec *ds = strm->ds; - struct lzh_br *br = &(ds->br); - int c, i; - - for (i = start; i < end; ) { - /* - * bit pattern the number we need - * 000 -> 0 - * 001 -> 1 - * 010 -> 2 - * ... - * 110 -> 6 - * 1110 -> 7 - * 11110 -> 8 - * ... - * 1111111111110 -> 16 - */ - if (!lzh_br_read_ahead(strm, br, 3)) - return (i); - if ((c = lzh_br_bits(br, 3)) == 7) { - if (!lzh_br_read_ahead(strm, br, 13)) - return (i); - c = bitlen_tbl[lzh_br_bits(br, 13) & 0x3FF]; - if (c) - lzh_br_consume(br, c - 3); - else - return (-1);/* Invalid data. */ - } else - lzh_br_consume(br, 3); - ds->pt.bitlen[i++] = c; - ds->pt.freq[c]++; - } - return (i); -} - -static int -lzh_make_fake_table(struct huffman *hf, uint16_t c) -{ - if (c >= hf->len_size) - return (0); - hf->tbl[0] = c; - hf->max_bits = 0; - hf->shift_bits = 0; - hf->bitlen[hf->tbl[0]] = 0; - return (1); -} - -/* - * Make a huffman coding table. - */ -static int -lzh_make_huffman_table(struct huffman *hf) -{ - uint16_t *tbl; - const unsigned char *bitlen; - int bitptn[17], weight[17]; - int i, maxbits = 0, ptn, tbl_size, w; - int diffbits, len_avail; - - /* - * Initialize bit patterns. - */ - ptn = 0; - for (i = 1, w = 1 << 15; i <= 16; i++, w >>= 1) { - bitptn[i] = ptn; - weight[i] = w; - if (hf->freq[i]) { - ptn += hf->freq[i] * w; - maxbits = i; - } - } - if (ptn != 0x10000 || maxbits > hf->tbl_bits) - return (0);/* Invalid */ - - hf->max_bits = maxbits; - - /* - * Cut out extra bits which we won't house in the table. - * This preparation reduces the same calculation in the for-loop - * making the table. - */ - if (maxbits < 16) { - int ebits = 16 - maxbits; - for (i = 1; i <= maxbits; i++) { - bitptn[i] >>= ebits; - weight[i] >>= ebits; - } - } - if (maxbits > HTBL_BITS) { - unsigned htbl_max; - uint16_t *p; - - diffbits = maxbits - HTBL_BITS; - for (i = 1; i <= HTBL_BITS; i++) { - bitptn[i] >>= diffbits; - weight[i] >>= diffbits; - } - htbl_max = bitptn[HTBL_BITS] + - weight[HTBL_BITS] * hf->freq[HTBL_BITS]; - p = &(hf->tbl[htbl_max]); - while (p < &hf->tbl[1U<shift_bits = diffbits; - - /* - * Make the table. - */ - tbl_size = 1 << HTBL_BITS; - tbl = hf->tbl; - bitlen = hf->bitlen; - len_avail = hf->len_avail; - hf->tree_used = 0; - for (i = 0; i < len_avail; i++) { - uint16_t *p; - int len, cnt; - uint16_t bit; - int extlen; - struct htree_t *ht; - - if (bitlen[i] == 0) - continue; - /* Get a bit pattern */ - len = bitlen[i]; - ptn = bitptn[len]; - cnt = weight[len]; - if (len <= HTBL_BITS) { - /* Calculate next bit pattern */ - if ((bitptn[len] = ptn + cnt) > tbl_size) - return (0);/* Invalid */ - /* Update the table */ - p = &(tbl[ptn]); - if (cnt > 7) { - uint16_t *pc; - - cnt -= 8; - pc = &p[cnt]; - pc[0] = (uint16_t)i; - pc[1] = (uint16_t)i; - pc[2] = (uint16_t)i; - pc[3] = (uint16_t)i; - pc[4] = (uint16_t)i; - pc[5] = (uint16_t)i; - pc[6] = (uint16_t)i; - pc[7] = (uint16_t)i; - if (cnt > 7) { - cnt -= 8; - memcpy(&p[cnt], pc, - 8 * sizeof(uint16_t)); - pc = &p[cnt]; - while (cnt > 15) { - cnt -= 16; - memcpy(&p[cnt], pc, - 16 * sizeof(uint16_t)); - } - } - if (cnt) - memcpy(p, pc, cnt * sizeof(uint16_t)); - } else { - while (cnt > 1) { - p[--cnt] = (uint16_t)i; - p[--cnt] = (uint16_t)i; - } - if (cnt) - p[--cnt] = (uint16_t)i; - } - continue; - } - - /* - * A bit length is too big to be housed to a direct table, - * so we use a tree model for its extra bits. - */ - bitptn[len] = ptn + cnt; - bit = 1U << (diffbits -1); - extlen = len - HTBL_BITS; - - p = &(tbl[ptn >> diffbits]); - if (*p == 0) { - *p = len_avail + hf->tree_used; - ht = &(hf->tree[hf->tree_used++]); - if (hf->tree_used > hf->tree_avail) - return (0);/* Invalid */ - ht->left = 0; - ht->right = 0; - } else { - if (*p < len_avail || - *p >= (len_avail + hf->tree_used)) - return (0);/* Invalid */ - ht = &(hf->tree[*p - len_avail]); - } - while (--extlen > 0) { - if (ptn & bit) { - if (ht->left < len_avail) { - ht->left = len_avail + hf->tree_used; - ht = &(hf->tree[hf->tree_used++]); - if (hf->tree_used > hf->tree_avail) - return (0);/* Invalid */ - ht->left = 0; - ht->right = 0; - } else { - ht = &(hf->tree[ht->left - len_avail]); - } - } else { - if (ht->right < len_avail) { - ht->right = len_avail + hf->tree_used; - ht = &(hf->tree[hf->tree_used++]); - if (hf->tree_used > hf->tree_avail) - return (0);/* Invalid */ - ht->left = 0; - ht->right = 0; - } else { - ht = &(hf->tree[ht->right - len_avail]); - } - } - bit >>= 1; - } - if (ptn & bit) { - if (ht->left != 0) - return (0);/* Invalid */ - ht->left = (uint16_t)i; - } else { - if (ht->right != 0) - return (0);/* Invalid */ - ht->right = (uint16_t)i; - } - } - return (1); -} - -static int -lzh_decode_huffman_tree(struct huffman *hf, unsigned rbits, int c) -{ - struct htree_t *ht; - int extlen; - - ht = hf->tree; - extlen = hf->shift_bits; - while (c >= hf->len_avail) { - c -= hf->len_avail; - if (extlen-- <= 0 || c >= hf->tree_used) - return (0); - if (rbits & (1U << extlen)) - c = ht[c].left; - else - c = ht[c].right; - } - return (c); -} - -static inline int -lzh_decode_huffman(struct huffman *hf, unsigned rbits) -{ - int c; - /* - * At first search an index table for a bit pattern. - * If it fails, search a huffman tree for. - */ - c = hf->tbl[rbits >> hf->shift_bits]; - if (c < hf->len_avail || hf->len_avail == 0) - return (c); - /* This bit pattern needs to be found out at a huffman tree. */ - return (lzh_decode_huffman_tree(hf, rbits, c)); -} - diff --git a/thirdparty/libarchive/libarchive/archive_read_support_format_mtree.c b/thirdparty/libarchive/libarchive/archive_read_support_format_mtree.c deleted file mode 100644 index a5fa30e3c..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_format_mtree.c +++ /dev/null @@ -1,2156 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2008 Joerg Sonnenberger - * Copyright (c) 2011-2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_mtree.c 201165 2009-12-29 05:52:13Z kientzle $"); - -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif -#include -/* #include */ /* See archive_platform.h */ -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_CTYPE_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" -#include "archive_entry_private.h" -#include "archive_private.h" -#include "archive_rb.h" -#include "archive_read_private.h" -#include "archive_string.h" -#include "archive_pack_dev.h" - -#ifndef O_BINARY -#define O_BINARY 0 -#endif -#ifndef O_CLOEXEC -#define O_CLOEXEC 0 -#endif - -#define MTREE_HAS_DEVICE 0x0001 -#define MTREE_HAS_FFLAGS 0x0002 -#define MTREE_HAS_GID 0x0004 -#define MTREE_HAS_GNAME 0x0008 -#define MTREE_HAS_MTIME 0x0010 -#define MTREE_HAS_NLINK 0x0020 -#define MTREE_HAS_PERM 0x0040 -#define MTREE_HAS_SIZE 0x0080 -#define MTREE_HAS_TYPE 0x0100 -#define MTREE_HAS_UID 0x0200 -#define MTREE_HAS_UNAME 0x0400 - -#define MTREE_HAS_OPTIONAL 0x0800 -#define MTREE_HAS_NOCHANGE 0x1000 /* FreeBSD specific */ - -#define MAX_LINE_LEN (1024 * 1024) - -struct mtree_option { - struct mtree_option *next; - char *value; -}; - -struct mtree_entry { - struct archive_rb_node rbnode; - struct mtree_entry *next_dup; - struct mtree_entry *next; - struct mtree_option *options; - char *name; - char full; - char used; -}; - -struct mtree { - struct archive_string line; - size_t buffsize; - char *buff; - int64_t offset; - int fd; - int archive_format; - const char *archive_format_name; - struct mtree_entry *entries; - struct mtree_entry *this_entry; - struct archive_rb_tree entry_rbtree; - struct archive_string current_dir; - struct archive_string contents_name; - - struct archive_entry_linkresolver *resolver; - struct archive_rb_tree rbtree; - - int64_t cur_size; - char checkfs; -}; - -static int bid_keycmp(const char *, const char *, ssize_t); -static int cleanup(struct archive_read *); -static int detect_form(struct archive_read *, int *); -static int mtree_bid(struct archive_read *, int); -static int parse_file(struct archive_read *, struct archive_entry *, - struct mtree *, struct mtree_entry *, int *); -static void parse_escapes(char *, struct mtree_entry *); -static int parse_line(struct archive_read *, struct archive_entry *, - struct mtree *, struct mtree_entry *, int *); -static int parse_keyword(struct archive_read *, struct mtree *, - struct archive_entry *, struct mtree_option *, int *); -static int read_data(struct archive_read *a, - const void **buff, size_t *size, int64_t *offset); -static ssize_t readline(struct archive_read *, struct mtree *, char **, ssize_t); -static int skip(struct archive_read *a); -static int read_header(struct archive_read *, - struct archive_entry *); -static int64_t mtree_atol(char **, int base); -#ifndef HAVE_STRNLEN -static size_t mtree_strnlen(const char *, size_t); -#endif - -/* - * There's no standard for TIME_T_MAX/TIME_T_MIN. So we compute them - * here. TODO: Move this to configure time, but be careful - * about cross-compile environments. - */ -static int64_t -get_time_t_max(void) -{ -#if defined(TIME_T_MAX) - return TIME_T_MAX; -#else - /* ISO C allows time_t to be a floating-point type, - but POSIX requires an integer type. The following - should work on any system that follows the POSIX - conventions. */ - if (((time_t)0) < ((time_t)-1)) { - /* Time_t is unsigned */ - return (~(time_t)0); - } else { - /* Time_t is signed. */ - /* Assume it's the same as int64_t or int32_t */ - if (sizeof(time_t) == sizeof(int64_t)) { - return (time_t)INT64_MAX; - } else { - return (time_t)INT32_MAX; - } - } -#endif -} - -static int64_t -get_time_t_min(void) -{ -#if defined(TIME_T_MIN) - return TIME_T_MIN; -#else - if (((time_t)0) < ((time_t)-1)) { - /* Time_t is unsigned */ - return (time_t)0; - } else { - /* Time_t is signed. */ - if (sizeof(time_t) == sizeof(int64_t)) { - return (time_t)INT64_MIN; - } else { - return (time_t)INT32_MIN; - } - } -#endif -} - -#ifdef HAVE_STRNLEN -#define mtree_strnlen(a,b) strnlen(a,b) -#else -static size_t -mtree_strnlen(const char *p, size_t maxlen) -{ - size_t i; - - for (i = 0; i <= maxlen; i++) { - if (p[i] == 0) - break; - } - if (i > maxlen) - return (-1);/* invalid */ - return (i); -} -#endif - -static int -archive_read_format_mtree_options(struct archive_read *a, - const char *key, const char *val) -{ - struct mtree *mtree; - - mtree = (struct mtree *)(a->format->data); - if (strcmp(key, "checkfs") == 0) { - /* Allows to read information missing from the mtree from the file system */ - if (val == NULL || val[0] == 0) { - mtree->checkfs = 0; - } else { - mtree->checkfs = 1; - } - return (ARCHIVE_OK); - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -static void -free_options(struct mtree_option *head) -{ - struct mtree_option *next; - - for (; head != NULL; head = next) { - next = head->next; - free(head->value); - free(head); - } -} - -static int -mtree_cmp_node(const struct archive_rb_node *n1, - const struct archive_rb_node *n2) -{ - const struct mtree_entry *e1 = (const struct mtree_entry *)n1; - const struct mtree_entry *e2 = (const struct mtree_entry *)n2; - - return (strcmp(e1->name, e2->name)); -} - -static int -mtree_cmp_key(const struct archive_rb_node *n, const void *key) -{ - const struct mtree_entry *e = (const struct mtree_entry *)n; - - return (strcmp(e->name, key)); -} - -int -archive_read_support_format_mtree(struct archive *_a) -{ - static const struct archive_rb_tree_ops rb_ops = { - mtree_cmp_node, mtree_cmp_key, - }; - struct archive_read *a = (struct archive_read *)_a; - struct mtree *mtree; - int r; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_format_mtree"); - - mtree = (struct mtree *)calloc(1, sizeof(*mtree)); - if (mtree == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate mtree data"); - return (ARCHIVE_FATAL); - } - mtree->checkfs = 0; - mtree->fd = -1; - - __archive_rb_tree_init(&mtree->rbtree, &rb_ops); - - r = __archive_read_register_format(a, mtree, "mtree", - mtree_bid, archive_read_format_mtree_options, read_header, read_data, skip, NULL, cleanup, NULL, NULL); - - if (r != ARCHIVE_OK) - free(mtree); - return (ARCHIVE_OK); -} - -static int -cleanup(struct archive_read *a) -{ - struct mtree *mtree; - struct mtree_entry *p, *q; - - mtree = (struct mtree *)(a->format->data); - - p = mtree->entries; - while (p != NULL) { - q = p->next; - free(p->name); - free_options(p->options); - free(p); - p = q; - } - archive_string_free(&mtree->line); - archive_string_free(&mtree->current_dir); - archive_string_free(&mtree->contents_name); - archive_entry_linkresolver_free(mtree->resolver); - - free(mtree->buff); - free(mtree); - (a->format->data) = NULL; - return (ARCHIVE_OK); -} - -static ssize_t -get_line_size(const char *b, ssize_t avail, ssize_t *nlsize) -{ - ssize_t len; - - len = 0; - while (len < avail) { - switch (*b) { - case '\0':/* Non-ascii character or control character. */ - if (nlsize != NULL) - *nlsize = 0; - return (-1); - case '\r': - if (avail-len > 1 && b[1] == '\n') { - if (nlsize != NULL) - *nlsize = 2; - return (len+2); - } - /* FALL THROUGH */ - case '\n': - if (nlsize != NULL) - *nlsize = 1; - return (len+1); - default: - b++; - len++; - break; - } - } - if (nlsize != NULL) - *nlsize = 0; - return (avail); -} - -/* - * <---------------- ravail ---------------------> - * <-- diff ------> <--- avail -----------------> - * <---- len -----------> - * | Previous lines | line being parsed nl extra | - * ^ - * b - * - */ -static ssize_t -next_line(struct archive_read *a, - const char **b, ssize_t *avail, ssize_t *ravail, ssize_t *nl) -{ - ssize_t len; - int quit; - - quit = 0; - if (*avail == 0) { - *nl = 0; - len = 0; - } else - len = get_line_size(*b, *avail, nl); - /* - * Read bytes more while it does not reach the end of line. - */ - while (*nl == 0 && len == *avail && !quit) { - ssize_t diff = *ravail - *avail; - size_t nbytes_req = (*ravail+1023) & ~1023U; - ssize_t tested; - - /* - * Place an arbitrary limit on the line length. - * mtree is almost free-form input and without line length limits, - * it can consume a lot of memory. - */ - if (len >= MAX_LINE_LEN) - return (-1); - - /* Increase reading bytes if it is not enough to at least - * new two lines. */ - if (nbytes_req < (size_t)*ravail + 160) - nbytes_req <<= 1; - - *b = __archive_read_ahead(a, nbytes_req, avail); - if (*b == NULL) { - if (*ravail >= *avail) - return (0); - /* Reading bytes reaches the end of file. */ - *b = __archive_read_ahead(a, *avail, avail); - quit = 1; - } - *ravail = *avail; - *b += diff; - *avail -= diff; - tested = len;/* Skip some bytes we already determined. */ - len = get_line_size(*b + len, *avail - len, nl); - if (len >= 0) - len += tested; - } - return (len); -} - -/* - * Compare characters with a mtree keyword. - * Returns the length of a mtree keyword if matched. - * Returns 0 if not matched. - */ -static int -bid_keycmp(const char *p, const char *key, ssize_t len) -{ - int match_len = 0; - - while (len > 0 && *p && *key) { - if (*p == *key) { - --len; - ++p; - ++key; - ++match_len; - continue; - } - return (0);/* Not match */ - } - if (*key != '\0') - return (0);/* Not match */ - - /* A following character should be specified characters */ - if (p[0] == '=' || p[0] == ' ' || p[0] == '\t' || - p[0] == '\n' || p[0] == '\r' || - (p[0] == '\\' && (p[1] == '\n' || p[1] == '\r'))) - return (match_len); - return (0);/* Not match */ -} - -/* - * Test whether the characters 'p' has is mtree keyword. - * Returns the length of a detected keyword. - * Returns 0 if any keywords were not found. - */ -static int -bid_keyword(const char *p, ssize_t len) -{ - static const char * const keys_c[] = { - "content", "contents", "cksum", NULL - }; - static const char * const keys_df[] = { - "device", "flags", NULL - }; - static const char * const keys_g[] = { - "gid", "gname", NULL - }; - static const char * const keys_il[] = { - "ignore", "inode", "link", NULL - }; - static const char * const keys_m[] = { - "md5", "md5digest", "mode", NULL - }; - static const char * const keys_no[] = { - "nlink", "nochange", "optional", NULL - }; - static const char * const keys_r[] = { - "resdevice", "rmd160", "rmd160digest", NULL - }; - static const char * const keys_s[] = { - "sha1", "sha1digest", - "sha256", "sha256digest", - "sha384", "sha384digest", - "sha512", "sha512digest", - "size", NULL - }; - static const char * const keys_t[] = { - "tags", "time", "type", NULL - }; - static const char * const keys_u[] = { - "uid", "uname", NULL - }; - const char * const *keys; - int i; - - switch (*p) { - case 'c': keys = keys_c; break; - case 'd': case 'f': keys = keys_df; break; - case 'g': keys = keys_g; break; - case 'i': case 'l': keys = keys_il; break; - case 'm': keys = keys_m; break; - case 'n': case 'o': keys = keys_no; break; - case 'r': keys = keys_r; break; - case 's': keys = keys_s; break; - case 't': keys = keys_t; break; - case 'u': keys = keys_u; break; - default: return (0);/* Unknown key */ - } - - for (i = 0; keys[i] != NULL; i++) { - int l = bid_keycmp(p, keys[i], len); - if (l > 0) - return (l); - } - return (0);/* Unknown key */ -} - -/* - * Test whether there is a set of mtree keywords. - * Returns the number of keyword. - * Returns -1 if we got incorrect sequence. - * This function expects a set of "keyword=value". - * When "unset" is specified, expects a set of "keyword". - */ -static int -bid_keyword_list(const char *p, ssize_t len, int unset, int last_is_path) -{ - int l; - int keycnt = 0; - - while (len > 0 && *p) { - int blank = 0; - - /* Test whether there are blank characters in the line. */ - while (len >0 && (*p == ' ' || *p == '\t')) { - ++p; - --len; - blank = 1; - } - if (*p == '\n' || *p == '\r') - break; - if (p[0] == '\\' && (p[1] == '\n' || p[1] == '\r')) - break; - if (!blank && !last_is_path) /* No blank character. */ - return (-1); - if (last_is_path && len == 0) - return (keycnt); - - if (unset) { - l = bid_keycmp(p, "all", len); - if (l > 0) - return (1); - } - /* Test whether there is a correct key in the line. */ - l = bid_keyword(p, len); - if (l == 0) - return (-1);/* Unknown keyword was found. */ - p += l; - len -= l; - keycnt++; - - /* Skip value */ - if (*p == '=') { - int value = 0; - ++p; - --len; - while (len > 0 && *p != ' ' && *p != '\t') { - ++p; - --len; - value = 1; - } - /* A keyword should have a its value unless - * "/unset" operation. */ - if (!unset && value == 0) - return (-1); - } - } - return (keycnt); -} - -static int -bid_entry(const char *p, ssize_t len, ssize_t nl, int *last_is_path) -{ - int f = 0; - static const unsigned char safe_char[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 0F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */ - /* !"$%&'()*+,-./ EXCLUSION:( )(#) */ - 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */ - /* 0123456789:;<>? EXCLUSION:(=) */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, /* 30 - 3F */ - /* @ABCDEFGHIJKLMNO */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */ - /* PQRSTUVWXYZ[\]^_ */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 - 5F */ - /* `abcdefghijklmno */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */ - /* pqrstuvwxyz{|}~ */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* 70 - 7F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F0 - FF */ - }; - ssize_t ll; - const char *pp = p; - const char * const pp_end = pp + len; - - *last_is_path = 0; - /* - * Skip the path-name which is quoted. - */ - for (;pp < pp_end; ++pp) { - if (!safe_char[*(const unsigned char *)pp]) { - if (*pp != ' ' && *pp != '\t' && *pp != '\r' - && *pp != '\n') - f = 0; - break; - } - f = 1; - } - ll = pp_end - pp; - - /* If a path-name was not found at the first, try to check - * a mtree format(a.k.a form D) ``NetBSD's mtree -D'' creates, - * which places the path-name at the last. */ - if (f == 0) { - const char *pb = p + len - nl; - int name_len = 0; - int slash; - - /* The form D accepts only a single line for an entry. */ - if (pb-2 >= p && - pb[-1] == '\\' && (pb[-2] == ' ' || pb[-2] == '\t')) - return (-1); - if (pb-1 >= p && pb[-1] == '\\') - return (-1); - - slash = 0; - while (p <= --pb && *pb != ' ' && *pb != '\t') { - if (!safe_char[*(const unsigned char *)pb]) - return (-1); - name_len++; - /* The pathname should have a slash in this - * format. */ - if (*pb == '/') - slash = 1; - } - if (name_len == 0 || slash == 0) - return (-1); - /* If '/' is placed at the first in this field, this is not - * a valid filename. */ - if (pb[1] == '/') - return (-1); - ll = len - nl - name_len; - pp = p; - *last_is_path = 1; - } - - return (bid_keyword_list(pp, ll, 0, *last_is_path)); -} - -#define MAX_BID_ENTRY 3 - -static int -mtree_bid(struct archive_read *a, int best_bid) -{ - const char *signature = "#mtree"; - const char *p; - - (void)best_bid; /* UNUSED */ - - /* Now let's look at the actual header and see if it matches. */ - p = __archive_read_ahead(a, strlen(signature), NULL); - if (p == NULL) - return (-1); - - if (memcmp(p, signature, strlen(signature)) == 0) - return (8 * (int)strlen(signature)); - - /* - * There is not a mtree signature. Let's try to detect mtree format. - */ - return (detect_form(a, NULL)); -} - -static int -detect_form(struct archive_read *a, int *is_form_d) -{ - const char *p; - ssize_t avail, ravail; - ssize_t len, nl; - int entry_cnt = 0, multiline = 0; - int form_D = 0;/* The archive is generated by `NetBSD mtree -D' - * (In this source we call it `form D') . */ - - if (is_form_d != NULL) - *is_form_d = 0; - p = __archive_read_ahead(a, 1, &avail); - if (p == NULL) - return (-1); - ravail = avail; - for (;;) { - len = next_line(a, &p, &avail, &ravail, &nl); - /* The terminal character of the line should be - * a new line character, '\r\n' or '\n'. */ - if (len <= 0 || nl == 0) - break; - if (!multiline) { - /* Leading whitespace is never significant, - * ignore it. */ - while (len > 0 && (*p == ' ' || *p == '\t')) { - ++p; - --avail; - --len; - } - /* Skip comment or empty line. */ - if (p[0] == '#' || p[0] == '\n' || p[0] == '\r') { - p += len; - avail -= len; - continue; - } - } else { - /* A continuance line; the terminal - * character of previous line was '\' character. */ - if (bid_keyword_list(p, len, 0, 0) <= 0) - break; - if (p[len-nl-1] != '\\') { - if (multiline == 1 && - ++entry_cnt >= MAX_BID_ENTRY) - break; - multiline = 0; - } - p += len; - avail -= len; - continue; - } - if (p[0] != '/') { - int last_is_path, keywords; - - keywords = bid_entry(p, len, nl, &last_is_path); - if (keywords >= 0) { - if (form_D == 0) { - if (last_is_path) - form_D = 1; - else if (keywords > 0) - /* This line is not `form D'. */ - form_D = -1; - } else if (form_D == 1) { - if (!last_is_path && keywords > 0) - /* This this is not `form D' - * and We cannot accept mixed - * format. */ - break; - } - if (!last_is_path && p[len-nl-1] == '\\') - /* This line continues. */ - multiline = 1; - else { - /* We've got plenty of correct lines - * to assume that this file is a mtree - * format. */ - if (++entry_cnt >= MAX_BID_ENTRY) - break; - } - } else - break; - } else if (len > 4 && strncmp(p, "/set", 4) == 0) { - if (bid_keyword_list(p+4, len-4, 0, 0) <= 0) - break; - /* This line continues. */ - if (p[len-nl-1] == '\\') - multiline = 2; - } else if (len > 6 && strncmp(p, "/unset", 6) == 0) { - if (bid_keyword_list(p+6, len-6, 1, 0) <= 0) - break; - /* This line continues. */ - if (p[len-nl-1] == '\\') - multiline = 2; - } else - break; - - /* Test next line. */ - p += len; - avail -= len; - } - if (entry_cnt >= MAX_BID_ENTRY || (entry_cnt > 0 && len == 0)) { - if (is_form_d != NULL) { - if (form_D == 1) - *is_form_d = 1; - } - return (32); - } - - return (0); -} - -/* - * The extended mtree format permits multiple lines specifying - * attributes for each file. For those entries, only the last line - * is actually used. Practically speaking, that means we have - * to read the entire mtree file into memory up front. - * - * The parsing is done in two steps. First, it is decided if a line - * changes the global defaults and if it is, processed accordingly. - * Otherwise, the options of the line are merged with the current - * global options. - */ -static int -add_option(struct archive_read *a, struct mtree_option **global, - const char *value, size_t len) -{ - struct mtree_option *opt; - - if ((opt = malloc(sizeof(*opt))) == NULL) { - archive_set_error(&a->archive, errno, "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - if ((opt->value = malloc(len + 1)) == NULL) { - free(opt); - archive_set_error(&a->archive, errno, "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - memcpy(opt->value, value, len); - opt->value[len] = '\0'; - opt->next = *global; - *global = opt; - return (ARCHIVE_OK); -} - -static void -remove_option(struct mtree_option **global, const char *value, size_t len) -{ - struct mtree_option *iter, *last; - - last = NULL; - for (iter = *global; iter != NULL; last = iter, iter = iter->next) { - if (strncmp(iter->value, value, len) == 0 && - (iter->value[len] == '\0' || - iter->value[len] == '=')) - break; - } - if (iter == NULL) - return; - if (last == NULL) - *global = iter->next; - else - last->next = iter->next; - - free(iter->value); - free(iter); -} - -static int -process_global_set(struct archive_read *a, - struct mtree_option **global, const char *line) -{ - const char *next, *eq; - size_t len; - int r; - - line += 4; - for (;;) { - next = line + strspn(line, " \t\r\n"); - if (*next == '\0') - return (ARCHIVE_OK); - line = next; - next = line + strcspn(line, " \t\r\n"); - eq = strchr(line, '='); - if (eq > next) - len = next - line; - else - len = eq - line; - - remove_option(global, line, len); - r = add_option(a, global, line, next - line); - if (r != ARCHIVE_OK) - return (r); - line = next; - } -} - -static int -process_global_unset(struct archive_read *a, - struct mtree_option **global, const char *line) -{ - const char *next; - size_t len; - - line += 6; - if (strchr(line, '=') != NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "/unset shall not contain `='"); - return ARCHIVE_FATAL; - } - - for (;;) { - next = line + strspn(line, " \t\r\n"); - if (*next == '\0') - return (ARCHIVE_OK); - line = next; - len = strcspn(line, " \t\r\n"); - - if (len == 3 && strncmp(line, "all", 3) == 0) { - free_options(*global); - *global = NULL; - } else { - remove_option(global, line, len); - } - - line += len; - } -} - -static int -process_add_entry(struct archive_read *a, struct mtree *mtree, - struct mtree_option **global, const char *line, ssize_t line_len, - struct mtree_entry **last_entry, int is_form_d) -{ - struct mtree_entry *entry; - struct mtree_option *iter; - const char *next, *eq, *name, *end; - size_t name_len, len; - int r, i; - - if ((entry = malloc(sizeof(*entry))) == NULL) { - archive_set_error(&a->archive, errno, "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - entry->next = NULL; - entry->options = NULL; - entry->name = NULL; - entry->used = 0; - entry->full = 0; - - /* Add this entry to list. */ - if (*last_entry == NULL) - mtree->entries = entry; - else - (*last_entry)->next = entry; - *last_entry = entry; - - if (is_form_d) { - /* Filename is last item on line. */ - /* Adjust line_len to trim trailing whitespace */ - while (line_len > 0) { - char last_character = line[line_len - 1]; - if (last_character == '\r' - || last_character == '\n' - || last_character == '\t' - || last_character == ' ') { - line_len--; - } else { - break; - } - } - /* Name starts after the last whitespace separator */ - name = line; - for (i = 0; i < line_len; i++) { - if (line[i] == '\r' - || line[i] == '\n' - || line[i] == '\t' - || line[i] == ' ') { - name = line + i + 1; - } - } - name_len = line + line_len - name; - end = name; - } else { - /* Filename is first item on line */ - name_len = strcspn(line, " \t\r\n"); - name = line; - line += name_len; - end = line + line_len; - } - /* name/name_len is the name within the line. */ - /* line..end brackets the entire line except the name */ - - if ((entry->name = malloc(name_len + 1)) == NULL) { - archive_set_error(&a->archive, errno, "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - - memcpy(entry->name, name, name_len); - entry->name[name_len] = '\0'; - parse_escapes(entry->name, entry); - - entry->next_dup = NULL; - if (entry->full) { - if (!__archive_rb_tree_insert_node(&mtree->rbtree, &entry->rbnode)) { - struct mtree_entry *alt; - alt = (struct mtree_entry *)__archive_rb_tree_find_node( - &mtree->rbtree, entry->name); - if (alt != NULL) { - while (alt->next_dup) - alt = alt->next_dup; - alt->next_dup = entry; - } - } - } - - for (iter = *global; iter != NULL; iter = iter->next) { - r = add_option(a, &entry->options, iter->value, - strlen(iter->value)); - if (r != ARCHIVE_OK) - return (r); - } - - for (;;) { - next = line + strspn(line, " \t\r\n"); - if (*next == '\0') - return (ARCHIVE_OK); - if (next >= end) - return (ARCHIVE_OK); - line = next; - next = line + strcspn(line, " \t\r\n"); - eq = strchr(line, '='); - if (eq == NULL || eq > next) - len = next - line; - else - len = eq - line; - - remove_option(&entry->options, line, len); - r = add_option(a, &entry->options, line, next - line); - if (r != ARCHIVE_OK) - return (r); - line = next; - } -} - -static int -read_mtree(struct archive_read *a, struct mtree *mtree) -{ - ssize_t len; - uintmax_t counter; - char *p, *s; - struct mtree_option *global; - struct mtree_entry *last_entry; - int r, is_form_d; - - mtree->archive_format = ARCHIVE_FORMAT_MTREE; - mtree->archive_format_name = "mtree"; - - global = NULL; - last_entry = NULL; - - (void)detect_form(a, &is_form_d); - - for (counter = 1; ; ++counter) { - r = ARCHIVE_OK; - len = readline(a, mtree, &p, 65536); - if (len == 0) { - mtree->this_entry = mtree->entries; - free_options(global); - return (ARCHIVE_OK); - } - if (len < 0) { - free_options(global); - return ((int)len); - } - /* Leading whitespace is never significant, ignore it. */ - while (*p == ' ' || *p == '\t') { - ++p; - --len; - } - /* Skip content lines and blank lines. */ - if (*p == '#') - continue; - if (*p == '\r' || *p == '\n' || *p == '\0') - continue; - /* Non-printable characters are not allowed */ - for (s = p;s < p + len - 1; s++) { - if (!isprint((unsigned char)*s) && *s != '\t') { - r = ARCHIVE_FATAL; - break; - } - } - if (r != ARCHIVE_OK) - break; - if (*p != '/') { - r = process_add_entry(a, mtree, &global, p, len, - &last_entry, is_form_d); - } else if (len > 4 && strncmp(p, "/set", 4) == 0) { - if (p[4] != ' ' && p[4] != '\t') - break; - r = process_global_set(a, &global, p); - } else if (len > 6 && strncmp(p, "/unset", 6) == 0) { - if (p[6] != ' ' && p[6] != '\t') - break; - r = process_global_unset(a, &global, p); - } else - break; - - if (r != ARCHIVE_OK) { - free_options(global); - return r; - } - } - - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Can't parse line %ju", counter); - free_options(global); - return (ARCHIVE_FATAL); -} - -/* - * Read in the entire mtree file into memory on the first request. - * Then use the next unused file to satisfy each header request. - */ -static int -read_header(struct archive_read *a, struct archive_entry *entry) -{ - struct mtree *mtree; - char *p; - int r, use_next; - - mtree = (struct mtree *)(a->format->data); - - if (mtree->fd >= 0) { - close(mtree->fd); - mtree->fd = -1; - } - - if (mtree->entries == NULL) { - mtree->resolver = archive_entry_linkresolver_new(); - if (mtree->resolver == NULL) - return ARCHIVE_FATAL; - archive_entry_linkresolver_set_strategy(mtree->resolver, - ARCHIVE_FORMAT_MTREE); - r = read_mtree(a, mtree); - if (r != ARCHIVE_OK) - return (r); - } - - a->archive.archive_format = mtree->archive_format; - a->archive.archive_format_name = mtree->archive_format_name; - - for (;;) { - if (mtree->this_entry == NULL) - return (ARCHIVE_EOF); - if (strcmp(mtree->this_entry->name, "..") == 0) { - mtree->this_entry->used = 1; - if (archive_strlen(&mtree->current_dir) > 0) { - /* Roll back current path. */ - p = mtree->current_dir.s - + mtree->current_dir.length - 1; - while (p >= mtree->current_dir.s && *p != '/') - --p; - if (p >= mtree->current_dir.s) - --p; - mtree->current_dir.length - = p - mtree->current_dir.s + 1; - } - } - if (!mtree->this_entry->used) { - use_next = 0; - r = parse_file(a, entry, mtree, mtree->this_entry, - &use_next); - if (use_next == 0) - return (r); - } - mtree->this_entry = mtree->this_entry->next; - } -} - -/* - * A single file can have multiple lines contribute specifications. - * Parse as many lines as necessary, then pull additional information - * from a backing file on disk as necessary. - */ -static int -parse_file(struct archive_read *a, struct archive_entry *entry, - struct mtree *mtree, struct mtree_entry *mentry, int *use_next) -{ - const char *path; - struct stat st_storage, *st; - struct mtree_entry *mp; - struct archive_entry *sparse_entry; - int r = ARCHIVE_OK, r1, parsed_kws; - - mentry->used = 1; - - /* Initialize reasonable defaults. */ - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - archive_string_empty(&mtree->contents_name); - - /* Parse options from this line. */ - parsed_kws = 0; - r = parse_line(a, entry, mtree, mentry, &parsed_kws); - - if (mentry->full) { - archive_entry_copy_pathname(entry, mentry->name); - /* - * "Full" entries are allowed to have multiple lines - * and those lines aren't required to be adjacent. We - * don't support multiple lines for "relative" entries - * nor do we make any attempt to merge data from - * separate "relative" and "full" entries. (Merging - * "relative" and "full" entries would require dealing - * with pathname canonicalization, which is a very - * tricky subject.) - */ - mp = (struct mtree_entry *)__archive_rb_tree_find_node( - &mtree->rbtree, mentry->name); - for (; mp; mp = mp->next_dup) { - if (mp->full && !mp->used) { - /* Later lines override earlier ones. */ - mp->used = 1; - r1 = parse_line(a, entry, mtree, mp, &parsed_kws); - if (r1 < r) - r = r1; - } - } - } else { - /* - * Relative entries require us to construct - * the full path and possibly update the - * current directory. - */ - size_t n = archive_strlen(&mtree->current_dir); - if (n > 0) - archive_strcat(&mtree->current_dir, "/"); - archive_strcat(&mtree->current_dir, mentry->name); - archive_entry_copy_pathname(entry, mtree->current_dir.s); - if (archive_entry_filetype(entry) != AE_IFDIR) - mtree->current_dir.length = n; - } - - if (mtree->checkfs) { - /* - * Try to open and stat the file to get the real size - * and other file info. It would be nice to avoid - * this here so that getting a listing of an mtree - * wouldn't require opening every referenced contents - * file. But then we wouldn't know the actual - * contents size, so I don't see a really viable way - * around this. (Also, we may want to someday pull - * other unspecified info from the contents file on - * disk.) - */ - mtree->fd = -1; - if (archive_strlen(&mtree->contents_name) > 0) - path = mtree->contents_name.s; - else - path = archive_entry_pathname(entry); - - if (archive_entry_filetype(entry) == AE_IFREG || - archive_entry_filetype(entry) == AE_IFDIR) { - mtree->fd = open(path, O_RDONLY | O_BINARY | O_CLOEXEC); - __archive_ensure_cloexec_flag(mtree->fd); - if (mtree->fd == -1 && ( -#if defined(_WIN32) && !defined(__CYGWIN__) - /* - * On Windows, attempting to open a file with an - * invalid name result in EINVAL (Error 22) - */ - (errno != ENOENT && errno != EINVAL) -#else - errno != ENOENT -#endif - || archive_strlen(&mtree->contents_name) > 0)) { - archive_set_error(&a->archive, errno, - "Can't open %s", path); - r = ARCHIVE_WARN; - } - } - - st = &st_storage; - if (mtree->fd >= 0) { - if (fstat(mtree->fd, st) == -1) { - archive_set_error(&a->archive, errno, - "Could not fstat %s", path); - r = ARCHIVE_WARN; - /* If we can't stat it, don't keep it open. */ - close(mtree->fd); - mtree->fd = -1; - st = NULL; - } - } -#ifdef HAVE_LSTAT - else if (lstat(path, st) == -1) -#else - else if (la_stat(path, st) == -1) -#endif - { - st = NULL; - } - - /* - * Check for a mismatch between the type in the specification - * and the type of the contents object on disk. - */ - if (st != NULL) { - if (((st->st_mode & S_IFMT) == S_IFREG && - archive_entry_filetype(entry) == AE_IFREG) -#ifdef S_IFLNK - ||((st->st_mode & S_IFMT) == S_IFLNK && - archive_entry_filetype(entry) == AE_IFLNK) -#endif -#ifdef S_IFSOCK - ||((st->st_mode & S_IFSOCK) == S_IFSOCK && - archive_entry_filetype(entry) == AE_IFSOCK) -#endif -#ifdef S_IFCHR - ||((st->st_mode & S_IFMT) == S_IFCHR && - archive_entry_filetype(entry) == AE_IFCHR) -#endif -#ifdef S_IFBLK - ||((st->st_mode & S_IFMT) == S_IFBLK && - archive_entry_filetype(entry) == AE_IFBLK) -#endif - ||((st->st_mode & S_IFMT) == S_IFDIR && - archive_entry_filetype(entry) == AE_IFDIR) -#ifdef S_IFIFO - ||((st->st_mode & S_IFMT) == S_IFIFO && - archive_entry_filetype(entry) == AE_IFIFO) -#endif - ) { - /* Types match. */ - } else { - /* Types don't match; bail out gracefully. */ - if (mtree->fd >= 0) - close(mtree->fd); - mtree->fd = -1; - if (parsed_kws & MTREE_HAS_OPTIONAL) { - /* It's not an error for an optional - * entry to not match disk. */ - *use_next = 1; - } else if (r == ARCHIVE_OK) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "mtree specification has different" - " type for %s", - archive_entry_pathname(entry)); - r = ARCHIVE_WARN; - } - return (r); - } - } - - /* - * If there is a contents file on disk, pick some of the - * metadata from that file. For most of these, we only - * set it from the contents if it wasn't already parsed - * from the specification. - */ - if (st != NULL) { - if (((parsed_kws & MTREE_HAS_DEVICE) == 0 || - (parsed_kws & MTREE_HAS_NOCHANGE) != 0) && - (archive_entry_filetype(entry) == AE_IFCHR || - archive_entry_filetype(entry) == AE_IFBLK)) - archive_entry_set_rdev(entry, st->st_rdev); - if ((parsed_kws & (MTREE_HAS_GID | MTREE_HAS_GNAME)) - == 0 || - (parsed_kws & MTREE_HAS_NOCHANGE) != 0) - archive_entry_set_gid(entry, st->st_gid); - if ((parsed_kws & (MTREE_HAS_UID | MTREE_HAS_UNAME)) - == 0 || - (parsed_kws & MTREE_HAS_NOCHANGE) != 0) - archive_entry_set_uid(entry, st->st_uid); - if ((parsed_kws & MTREE_HAS_MTIME) == 0 || - (parsed_kws & MTREE_HAS_NOCHANGE) != 0) { -#if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC - archive_entry_set_mtime(entry, st->st_mtime, - st->st_mtimespec.tv_nsec); -#elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC - archive_entry_set_mtime(entry, st->st_mtime, - st->st_mtim.tv_nsec); -#elif HAVE_STRUCT_STAT_ST_MTIME_N - archive_entry_set_mtime(entry, st->st_mtime, - st->st_mtime_n); -#elif HAVE_STRUCT_STAT_ST_UMTIME - archive_entry_set_mtime(entry, st->st_mtime, - st->st_umtime*1000); -#elif HAVE_STRUCT_STAT_ST_MTIME_USEC - archive_entry_set_mtime(entry, st->st_mtime, - st->st_mtime_usec*1000); -#else - archive_entry_set_mtime(entry, st->st_mtime, 0); -#endif - } - if ((parsed_kws & MTREE_HAS_NLINK) == 0 || - (parsed_kws & MTREE_HAS_NOCHANGE) != 0) - archive_entry_set_nlink(entry, st->st_nlink); - if ((parsed_kws & MTREE_HAS_PERM) == 0 || - (parsed_kws & MTREE_HAS_NOCHANGE) != 0) - archive_entry_set_perm(entry, st->st_mode); - if ((parsed_kws & MTREE_HAS_SIZE) == 0 || - (parsed_kws & MTREE_HAS_NOCHANGE) != 0) - archive_entry_set_size(entry, st->st_size); - archive_entry_set_ino(entry, st->st_ino); - archive_entry_set_dev(entry, st->st_dev); - - archive_entry_linkify(mtree->resolver, &entry, - &sparse_entry); - } else if (parsed_kws & MTREE_HAS_OPTIONAL) { - /* - * Couldn't open the entry, stat it or the on-disk type - * didn't match. If this entry is optional, just - * ignore it and read the next header entry. - */ - *use_next = 1; - return ARCHIVE_OK; - } - } - - mtree->cur_size = archive_entry_size(entry); - mtree->offset = 0; - - return r; -} - -/* - * Each line contains a sequence of keywords. - */ -static int -parse_line(struct archive_read *a, struct archive_entry *entry, - struct mtree *mtree, struct mtree_entry *mp, int *parsed_kws) -{ - struct mtree_option *iter; - int r = ARCHIVE_OK, r1; - - for (iter = mp->options; iter != NULL; iter = iter->next) { - r1 = parse_keyword(a, mtree, entry, iter, parsed_kws); - if (r1 < r) - r = r1; - } - if (r == ARCHIVE_OK && (*parsed_kws & MTREE_HAS_TYPE) == 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Missing type keyword in mtree specification"); - return (ARCHIVE_WARN); - } - return (r); -} - -/* - * Device entries have one of the following forms: - * - raw dev_t - * - format,major,minor[,subdevice] - * When parsing succeeded, `pdev' will contain the appropriate dev_t value. - */ - -/* strsep() is not in C90, but strcspn() is. */ -/* Taken from http://unixpapa.com/incnote/string.html */ -static char * -la_strsep(char **sp, const char *sep) -{ - char *p, *s; - if (sp == NULL || *sp == NULL || **sp == '\0') - return(NULL); - s = *sp; - p = s + strcspn(s, sep); - if (*p != '\0') - *p++ = '\0'; - *sp = p; - return(s); -} - -static int -parse_device(dev_t *pdev, struct archive *a, char *val) -{ -#define MAX_PACK_ARGS 3 - unsigned long numbers[MAX_PACK_ARGS]; - char *p, *dev; - int argc; - pack_t *pack; - dev_t result; - const char *error = NULL; - - memset(pdev, 0, sizeof(*pdev)); - if ((dev = strchr(val, ',')) != NULL) { - /* - * Device's major/minor are given in a specified format. - * Decode and pack it accordingly. - */ - *dev++ = '\0'; - if ((pack = pack_find(val)) == NULL) { - archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT, - "Unknown format `%s'", val); - return ARCHIVE_WARN; - } - argc = 0; - while ((p = la_strsep(&dev, ",")) != NULL) { - if (*p == '\0') { - archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT, - "Missing number"); - return ARCHIVE_WARN; - } - if (argc >= MAX_PACK_ARGS) { - archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT, - "Too many arguments"); - return ARCHIVE_WARN; - } - numbers[argc++] = (unsigned long)mtree_atol(&p, 0); - } - if (argc < 2) { - archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT, - "Not enough arguments"); - return ARCHIVE_WARN; - } - result = (*pack)(argc, numbers, &error); - if (error != NULL) { - archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT, - "%s", error); - return ARCHIVE_WARN; - } - } else { - /* file system raw value. */ - result = (dev_t)mtree_atol(&val, 0); - } - *pdev = result; - return ARCHIVE_OK; -#undef MAX_PACK_ARGS -} - -static int -parse_hex_nibble(char c) -{ - if (c >= '0' && c <= '9') - return c - '0'; - if (c >= 'a' && c <= 'f') - return 10 + c - 'a'; -#if 0 - /* XXX: Is uppercase something we should support? */ - if (c >= 'A' && c <= 'F') - return 10 + c - 'A'; -#endif - - return -1; -} - -static int -parse_digest(struct archive_read *a, struct archive_entry *entry, - const char *digest, int type) -{ - unsigned char digest_buf[64]; - int high, low; - size_t i, j, len; - - switch (type) { - case ARCHIVE_ENTRY_DIGEST_MD5: - len = sizeof(entry->digest.md5); - break; - case ARCHIVE_ENTRY_DIGEST_RMD160: - len = sizeof(entry->digest.rmd160); - break; - case ARCHIVE_ENTRY_DIGEST_SHA1: - len = sizeof(entry->digest.sha1); - break; - case ARCHIVE_ENTRY_DIGEST_SHA256: - len = sizeof(entry->digest.sha256); - break; - case ARCHIVE_ENTRY_DIGEST_SHA384: - len = sizeof(entry->digest.sha384); - break; - case ARCHIVE_ENTRY_DIGEST_SHA512: - len = sizeof(entry->digest.sha512); - break; - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, - "Internal error: Unknown digest type"); - return ARCHIVE_FATAL; - } - - if (len > sizeof(digest_buf)) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, - "Internal error: Digest storage too large"); - return ARCHIVE_FATAL; - } - - len *= 2; - - if (mtree_strnlen(digest, len+1) != len) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "incorrect digest length, ignoring"); - return ARCHIVE_WARN; - } - - for (i = 0, j = 0; i < len; i += 2, j++) { - high = parse_hex_nibble(digest[i]); - low = parse_hex_nibble(digest[i+1]); - if (high == -1 || low == -1) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "invalid digest data, ignoring"); - return ARCHIVE_WARN; - } - - digest_buf[j] = high << 4 | low; - } - - return archive_entry_set_digest(entry, type, digest_buf); -} - -/* - * Parse a single keyword and its value. - */ -static int -parse_keyword(struct archive_read *a, struct mtree *mtree, - struct archive_entry *entry, struct mtree_option *opt, int *parsed_kws) -{ - char *val, *key; - - key = opt->value; - - if (*key == '\0') - return (ARCHIVE_OK); - - if (strcmp(key, "nochange") == 0) { - *parsed_kws |= MTREE_HAS_NOCHANGE; - return (ARCHIVE_OK); - } - if (strcmp(key, "optional") == 0) { - *parsed_kws |= MTREE_HAS_OPTIONAL; - return (ARCHIVE_OK); - } - if (strcmp(key, "ignore") == 0) { - /* - * The mtree processing is not recursive, so - * recursion will only happen for explicitly listed - * entries. - */ - return (ARCHIVE_OK); - } - - val = strchr(key, '='); - if (val == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Malformed attribute \"%s\" (%d)", key, key[0]); - return (ARCHIVE_WARN); - } - - *val = '\0'; - ++val; - - switch (key[0]) { - case 'c': - if (strcmp(key, "content") == 0 - || strcmp(key, "contents") == 0) { - parse_escapes(val, NULL); - archive_strcpy(&mtree->contents_name, val); - return (ARCHIVE_OK); - } - if (strcmp(key, "cksum") == 0) - return (ARCHIVE_OK); - break; - case 'd': - if (strcmp(key, "device") == 0) { - /* stat(2) st_rdev field, e.g. the major/minor IDs - * of a char/block special file */ - int r; - dev_t dev; - - *parsed_kws |= MTREE_HAS_DEVICE; - r = parse_device(&dev, &a->archive, val); - if (r == ARCHIVE_OK) - archive_entry_set_rdev(entry, dev); - return r; - } - break; - case 'f': - if (strcmp(key, "flags") == 0) { - *parsed_kws |= MTREE_HAS_FFLAGS; - archive_entry_copy_fflags_text(entry, val); - return (ARCHIVE_OK); - } - break; - case 'g': - if (strcmp(key, "gid") == 0) { - *parsed_kws |= MTREE_HAS_GID; - archive_entry_set_gid(entry, mtree_atol(&val, 10)); - return (ARCHIVE_OK); - } - if (strcmp(key, "gname") == 0) { - *parsed_kws |= MTREE_HAS_GNAME; - archive_entry_copy_gname(entry, val); - return (ARCHIVE_OK); - } - break; - case 'i': - if (strcmp(key, "inode") == 0) { - archive_entry_set_ino(entry, mtree_atol(&val, 10)); - return (ARCHIVE_OK); - } - break; - case 'l': - if (strcmp(key, "link") == 0) { - parse_escapes(val, NULL); - archive_entry_copy_symlink(entry, val); - return (ARCHIVE_OK); - } - break; - case 'm': - if (strcmp(key, "md5") == 0 || strcmp(key, "md5digest") == 0) { - return parse_digest(a, entry, val, - ARCHIVE_ENTRY_DIGEST_MD5); - } - if (strcmp(key, "mode") == 0) { - if (val[0] < '0' || val[0] > '7') { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Symbolic or non-octal mode \"%s\" unsupported", val); - return (ARCHIVE_WARN); - } - *parsed_kws |= MTREE_HAS_PERM; - archive_entry_set_perm(entry, (mode_t)mtree_atol(&val, 8)); - return (ARCHIVE_OK); - } - break; - case 'n': - if (strcmp(key, "nlink") == 0) { - *parsed_kws |= MTREE_HAS_NLINK; - archive_entry_set_nlink(entry, - (unsigned int)mtree_atol(&val, 10)); - return (ARCHIVE_OK); - } - break; - case 'r': - if (strcmp(key, "resdevice") == 0) { - /* stat(2) st_dev field, e.g. the device ID where the - * inode resides */ - int r; - dev_t dev; - - r = parse_device(&dev, &a->archive, val); - if (r == ARCHIVE_OK) - archive_entry_set_dev(entry, dev); - return r; - } - if (strcmp(key, "rmd160") == 0 || - strcmp(key, "rmd160digest") == 0) { - return parse_digest(a, entry, val, - ARCHIVE_ENTRY_DIGEST_RMD160); - } - break; - case 's': - if (strcmp(key, "sha1") == 0 || - strcmp(key, "sha1digest") == 0) { - return parse_digest(a, entry, val, - ARCHIVE_ENTRY_DIGEST_SHA1); - } - if (strcmp(key, "sha256") == 0 || - strcmp(key, "sha256digest") == 0) { - return parse_digest(a, entry, val, - ARCHIVE_ENTRY_DIGEST_SHA256); - } - if (strcmp(key, "sha384") == 0 || - strcmp(key, "sha384digest") == 0) { - return parse_digest(a, entry, val, - ARCHIVE_ENTRY_DIGEST_SHA384); - } - if (strcmp(key, "sha512") == 0 || - strcmp(key, "sha512digest") == 0) { - return parse_digest(a, entry, val, - ARCHIVE_ENTRY_DIGEST_SHA512); - } - if (strcmp(key, "size") == 0) { - archive_entry_set_size(entry, mtree_atol(&val, 10)); - return (ARCHIVE_OK); - } - break; - case 't': - if (strcmp(key, "tags") == 0) { - /* - * Comma delimited list of tags. - * Ignore the tags for now, but the interface - * should be extended to allow inclusion/exclusion. - */ - return (ARCHIVE_OK); - } - if (strcmp(key, "time") == 0) { - int64_t m; - int64_t my_time_t_max = get_time_t_max(); - int64_t my_time_t_min = get_time_t_min(); - long ns = 0; - - *parsed_kws |= MTREE_HAS_MTIME; - m = mtree_atol(&val, 10); - /* Replicate an old mtree bug: - * 123456789.1 represents 123456789 - * seconds and 1 nanosecond. */ - if (*val == '.') { - ++val; - ns = (long)mtree_atol(&val, 10); - if (ns < 0) - ns = 0; - else if (ns > 999999999) - ns = 999999999; - } - if (m > my_time_t_max) - m = my_time_t_max; - else if (m < my_time_t_min) - m = my_time_t_min; - archive_entry_set_mtime(entry, (time_t)m, ns); - return (ARCHIVE_OK); - } - if (strcmp(key, "type") == 0) { - switch (val[0]) { - case 'b': - if (strcmp(val, "block") == 0) { - *parsed_kws |= MTREE_HAS_TYPE; - archive_entry_set_filetype(entry, - AE_IFBLK); - return (ARCHIVE_OK); - } - break; - case 'c': - if (strcmp(val, "char") == 0) { - *parsed_kws |= MTREE_HAS_TYPE; - archive_entry_set_filetype(entry, - AE_IFCHR); - return (ARCHIVE_OK); - } - break; - case 'd': - if (strcmp(val, "dir") == 0) { - *parsed_kws |= MTREE_HAS_TYPE; - archive_entry_set_filetype(entry, - AE_IFDIR); - return (ARCHIVE_OK); - } - break; - case 'f': - if (strcmp(val, "fifo") == 0) { - *parsed_kws |= MTREE_HAS_TYPE; - archive_entry_set_filetype(entry, - AE_IFIFO); - return (ARCHIVE_OK); - } - if (strcmp(val, "file") == 0) { - *parsed_kws |= MTREE_HAS_TYPE; - archive_entry_set_filetype(entry, - AE_IFREG); - return (ARCHIVE_OK); - } - break; - case 'l': - if (strcmp(val, "link") == 0) { - *parsed_kws |= MTREE_HAS_TYPE; - archive_entry_set_filetype(entry, - AE_IFLNK); - return (ARCHIVE_OK); - } - break; - default: - break; - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Unrecognized file type \"%s\"; " - "assuming \"file\"", val); - archive_entry_set_filetype(entry, AE_IFREG); - return (ARCHIVE_WARN); - } - break; - case 'u': - if (strcmp(key, "uid") == 0) { - *parsed_kws |= MTREE_HAS_UID; - archive_entry_set_uid(entry, mtree_atol(&val, 10)); - return (ARCHIVE_OK); - } - if (strcmp(key, "uname") == 0) { - *parsed_kws |= MTREE_HAS_UNAME; - archive_entry_copy_uname(entry, val); - return (ARCHIVE_OK); - } - break; - default: - break; - } - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Unrecognized key %s=%s", key, val); - return (ARCHIVE_WARN); -} - -static int -read_data(struct archive_read *a, const void **buff, size_t *size, - int64_t *offset) -{ - size_t bytes_to_read; - ssize_t bytes_read; - struct mtree *mtree; - - mtree = (struct mtree *)(a->format->data); - if (mtree->fd < 0) { - *buff = NULL; - *offset = 0; - *size = 0; - return (ARCHIVE_EOF); - } - if (mtree->buff == NULL) { - mtree->buffsize = 64 * 1024; - mtree->buff = malloc(mtree->buffsize); - if (mtree->buff == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - } - - *buff = mtree->buff; - *offset = mtree->offset; - if ((int64_t)mtree->buffsize > mtree->cur_size - mtree->offset) - bytes_to_read = (size_t)(mtree->cur_size - mtree->offset); - else - bytes_to_read = mtree->buffsize; - bytes_read = read(mtree->fd, mtree->buff, bytes_to_read); - if (bytes_read < 0) { - archive_set_error(&a->archive, errno, "Can't read"); - return (ARCHIVE_WARN); - } - if (bytes_read == 0) { - *size = 0; - return (ARCHIVE_EOF); - } - mtree->offset += bytes_read; - *size = bytes_read; - return (ARCHIVE_OK); -} - -/* Skip does nothing except possibly close the contents file. */ -static int -skip(struct archive_read *a) -{ - struct mtree *mtree; - - mtree = (struct mtree *)(a->format->data); - if (mtree->fd >= 0) { - close(mtree->fd); - mtree->fd = -1; - } - return (ARCHIVE_OK); -} - -/* - * Since parsing backslash sequences always makes strings shorter, - * we can always do this conversion in-place. - */ -static void -parse_escapes(char *src, struct mtree_entry *mentry) -{ - char *dest = src; - char c; - - if (mentry != NULL && strcmp(src, ".") == 0) - mentry->full = 1; - - while (*src != '\0') { - c = *src++; - if (c == '/' && mentry != NULL) - mentry->full = 1; - if (c == '\\') { - switch (src[0]) { - case '0': - if (src[1] < '0' || src[1] > '7') { - c = 0; - ++src; - break; - } - /* FALLTHROUGH */ - case '1': - case '2': - case '3': - if (src[1] >= '0' && src[1] <= '7' && - src[2] >= '0' && src[2] <= '7') { - c = (src[0] - '0') << 6; - c |= (src[1] - '0') << 3; - c |= (src[2] - '0'); - src += 3; - } - break; - case 'a': - c = '\a'; - ++src; - break; - case 'b': - c = '\b'; - ++src; - break; - case 'f': - c = '\f'; - ++src; - break; - case 'n': - c = '\n'; - ++src; - break; - case 'r': - c = '\r'; - ++src; - break; - case 's': - c = ' '; - ++src; - break; - case 't': - c = '\t'; - ++src; - break; - case 'v': - c = '\v'; - ++src; - break; - case '\\': - c = '\\'; - ++src; - break; - } - } - *dest++ = c; - } - *dest = '\0'; -} - -/* Parse a hex digit. */ -static int -parsedigit(char c) -{ - if (c >= '0' && c <= '9') - return c - '0'; - else if (c >= 'a' && c <= 'f') - return c - 'a'; - else if (c >= 'A' && c <= 'F') - return c - 'A'; - else - return -1; -} - -/* - * Note that this implementation does not (and should not!) obey - * locale settings; you cannot simply substitute strtol here, since - * it does obey locale. - */ -static int64_t -mtree_atol(char **p, int base) -{ - int64_t l, limit; - int digit, last_digit_limit; - - if (base == 0) { - if (**p != '0') - base = 10; - else if ((*p)[1] == 'x' || (*p)[1] == 'X') { - *p += 2; - base = 16; - } else { - base = 8; - } - } - - if (**p == '-') { - limit = INT64_MIN / base; - last_digit_limit = -(INT64_MIN % base); - ++(*p); - - l = 0; - digit = parsedigit(**p); - while (digit >= 0 && digit < base) { - if (l < limit || (l == limit && digit >= last_digit_limit)) - return INT64_MIN; - l = (l * base) - digit; - digit = parsedigit(*++(*p)); - } - return l; - } else { - limit = INT64_MAX / base; - last_digit_limit = INT64_MAX % base; - - l = 0; - digit = parsedigit(**p); - while (digit >= 0 && digit < base) { - if (l > limit || (l == limit && digit > last_digit_limit)) - return INT64_MAX; - l = (l * base) + digit; - digit = parsedigit(*++(*p)); - } - return l; - } -} - -/* - * Returns length of line (including trailing newline) - * or negative on error. 'start' argument is updated to - * point to first character of line. - */ -static ssize_t -readline(struct archive_read *a, struct mtree *mtree, char **start, - ssize_t limit) -{ - ssize_t bytes_read; - ssize_t total_size = 0; - ssize_t find_off = 0; - const void *t; - void *nl; - char *u; - - /* Accumulate line in a line buffer. */ - for (;;) { - /* Read some more. */ - t = __archive_read_ahead(a, 1, &bytes_read); - if (t == NULL) - return (0); - if (bytes_read < 0) - return (ARCHIVE_FATAL); - nl = memchr(t, '\n', bytes_read); - /* If we found '\n', trim the read to end exactly there. */ - if (nl != NULL) { - bytes_read = ((const char *)nl) - ((const char *)t) + 1; - } - if (total_size + bytes_read + 1 > limit) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Line too long"); - return (ARCHIVE_FATAL); - } - if (archive_string_ensure(&mtree->line, - total_size + bytes_read + 1) == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate working buffer"); - return (ARCHIVE_FATAL); - } - /* Append new bytes to string. */ - memcpy(mtree->line.s + total_size, t, bytes_read); - __archive_read_consume(a, bytes_read); - total_size += bytes_read; - mtree->line.s[total_size] = '\0'; - - for (u = mtree->line.s + find_off; *u; ++u) { - if (u[0] == '\n') { - /* Ends with unescaped newline. */ - *start = mtree->line.s; - return total_size; - } else if (u[0] == '#') { - /* Ends with comment sequence #...\n */ - if (nl == NULL) { - /* But we've not found the \n yet */ - break; - } - } else if (u[0] == '\\') { - if (u[1] == '\n') { - /* Trim escaped newline. */ - total_size -= 2; - mtree->line.s[total_size] = '\0'; - break; - } else if (u[1] != '\0') { - /* Skip the two-char escape sequence */ - ++u; - } - } - } - find_off = u - mtree->line.s; - } -} diff --git a/thirdparty/libarchive/libarchive/archive_read_support_format_rar.c b/thirdparty/libarchive/libarchive/archive_read_support_format_rar.c deleted file mode 100644 index 16b6e6eed..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_format_rar.c +++ /dev/null @@ -1,3788 +0,0 @@ -/*- -* Copyright (c) 2003-2007 Tim Kientzle -* Copyright (c) 2011 Andres Mejia -* 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. -* 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. -* -* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. -*/ - -#include "archive_platform.h" - -#ifdef HAVE_ERRNO_H -#include -#endif -#include -#include -#ifdef HAVE_ZLIB_H -#include /* crc32 */ -#endif - -#include "archive.h" -#ifndef HAVE_ZLIB_H -#include "archive_crc32.h" -#endif -#include "archive_endian.h" -#include "archive_entry.h" -#include "archive_entry_locale.h" -#include "archive_ppmd7_private.h" -#include "archive_private.h" -#include "archive_read_private.h" - -/* RAR signature, also known as the mark header */ -#define RAR_SIGNATURE "\x52\x61\x72\x21\x1A\x07\x00" - -/* Header types */ -#define MARK_HEAD 0x72 -#define MAIN_HEAD 0x73 -#define FILE_HEAD 0x74 -#define COMM_HEAD 0x75 -#define AV_HEAD 0x76 -#define SUB_HEAD 0x77 -#define PROTECT_HEAD 0x78 -#define SIGN_HEAD 0x79 -#define NEWSUB_HEAD 0x7a -#define ENDARC_HEAD 0x7b - -/* Main Header Flags */ -#define MHD_VOLUME 0x0001 -#define MHD_COMMENT 0x0002 -#define MHD_LOCK 0x0004 -#define MHD_SOLID 0x0008 -#define MHD_NEWNUMBERING 0x0010 -#define MHD_AV 0x0020 -#define MHD_PROTECT 0x0040 -#define MHD_PASSWORD 0x0080 -#define MHD_FIRSTVOLUME 0x0100 -#define MHD_ENCRYPTVER 0x0200 - -/* Flags common to all headers */ -#define HD_MARKDELETION 0x4000 -#define HD_ADD_SIZE_PRESENT 0x8000 - -/* File Header Flags */ -#define FHD_SPLIT_BEFORE 0x0001 -#define FHD_SPLIT_AFTER 0x0002 -#define FHD_PASSWORD 0x0004 -#define FHD_COMMENT 0x0008 -#define FHD_SOLID 0x0010 -#define FHD_LARGE 0x0100 -#define FHD_UNICODE 0x0200 -#define FHD_SALT 0x0400 -#define FHD_VERSION 0x0800 -#define FHD_EXTTIME 0x1000 -#define FHD_EXTFLAGS 0x2000 - -/* File dictionary sizes */ -#define DICTIONARY_SIZE_64 0x00 -#define DICTIONARY_SIZE_128 0x20 -#define DICTIONARY_SIZE_256 0x40 -#define DICTIONARY_SIZE_512 0x60 -#define DICTIONARY_SIZE_1024 0x80 -#define DICTIONARY_SIZE_2048 0xA0 -#define DICTIONARY_SIZE_4096 0xC0 -#define FILE_IS_DIRECTORY 0xE0 -#define DICTIONARY_MASK FILE_IS_DIRECTORY - -/* OS Flags */ -#define OS_MSDOS 0 -#define OS_OS2 1 -#define OS_WIN32 2 -#define OS_UNIX 3 -#define OS_MAC_OS 4 -#define OS_BEOS 5 - -/* Compression Methods */ -#define COMPRESS_METHOD_STORE 0x30 -/* LZSS */ -#define COMPRESS_METHOD_FASTEST 0x31 -#define COMPRESS_METHOD_FAST 0x32 -#define COMPRESS_METHOD_NORMAL 0x33 -/* PPMd Variant H */ -#define COMPRESS_METHOD_GOOD 0x34 -#define COMPRESS_METHOD_BEST 0x35 - -#define CRC_POLYNOMIAL 0xEDB88320 - -#define NS_UNIT 10000000 - -#define DICTIONARY_MAX_SIZE 0x400000 - -#define MAINCODE_SIZE 299 -#define OFFSETCODE_SIZE 60 -#define LOWOFFSETCODE_SIZE 17 -#define LENGTHCODE_SIZE 28 -#define HUFFMAN_TABLE_SIZE \ - MAINCODE_SIZE + OFFSETCODE_SIZE + LOWOFFSETCODE_SIZE + LENGTHCODE_SIZE - -#define MAX_SYMBOL_LENGTH 0xF -#define MAX_SYMBOLS 20 - -/* Virtual Machine Properties */ -#define VM_MEMORY_SIZE 0x40000 -#define VM_MEMORY_MASK (VM_MEMORY_SIZE - 1) -#define PROGRAM_WORK_SIZE 0x3C000 -#define PROGRAM_GLOBAL_SIZE 0x2000 -#define PROGRAM_SYSTEM_GLOBAL_ADDRESS PROGRAM_WORK_SIZE -#define PROGRAM_SYSTEM_GLOBAL_SIZE 0x40 -#define PROGRAM_USER_GLOBAL_ADDRESS (PROGRAM_SYSTEM_GLOBAL_ADDRESS + PROGRAM_SYSTEM_GLOBAL_SIZE) -#define PROGRAM_USER_GLOBAL_SIZE (PROGRAM_GLOBAL_SIZE - PROGRAM_SYSTEM_GLOBAL_SIZE) - -/* - * Considering L1,L2 cache miss and a calling of write system-call, - * the best size of the output buffer(uncompressed buffer) is 128K. - * If the structure of extracting process is changed, this value - * might be researched again. - */ -#define UNP_BUFFER_SIZE (128 * 1024) - -/* Define this here for non-Windows platforms */ -#if !((defined(__WIN32__) || defined(_WIN32) || defined(__WIN32)) && !defined(__CYGWIN__)) -#define FILE_ATTRIBUTE_DIRECTORY 0x10 -#endif - -#undef minimum -#define minimum(a, b) ((a)<(b)?(a):(b)) - -/* Stack overflow check */ -#define MAX_COMPRESS_DEPTH 1024 - -/* Fields common to all headers */ -struct rar_header -{ - char crc[2]; - char type; - char flags[2]; - char size[2]; -}; - -/* Fields common to all file headers */ -struct rar_file_header -{ - char pack_size[4]; - char unp_size[4]; - char host_os; - char file_crc[4]; - char file_time[4]; - char unp_ver; - char method; - char name_size[2]; - char file_attr[4]; -}; - -struct huffman_tree_node -{ - int branches[2]; -}; - -struct huffman_table_entry -{ - unsigned int length; - int value; -}; - -struct huffman_code -{ - struct huffman_tree_node *tree; - int numentries; - int numallocatedentries; - int minlength; - int maxlength; - int tablesize; - struct huffman_table_entry *table; -}; - -struct lzss -{ - unsigned char *window; - int mask; - int64_t position; -}; - -struct data_block_offsets -{ - int64_t header_size; - int64_t start_offset; - int64_t end_offset; -}; - -struct rar_program_code -{ - uint8_t *staticdata; - uint32_t staticdatalen; - uint8_t *globalbackup; - uint32_t globalbackuplen; - uint64_t fingerprint; - uint32_t usagecount; - uint32_t oldfilterlength; - struct rar_program_code *next; -}; - -struct rar_filter -{ - struct rar_program_code *prog; - uint32_t initialregisters[8]; - uint8_t *globaldata; - uint32_t globaldatalen; - size_t blockstartpos; - uint32_t blocklength; - uint32_t filteredblockaddress; - uint32_t filteredblocklength; - struct rar_filter *next; -}; - -struct memory_bit_reader -{ - const uint8_t *bytes; - size_t length; - size_t offset; - uint64_t bits; - int available; - int at_eof; -}; - -struct rar_virtual_machine -{ - uint32_t registers[8]; - uint8_t memory[VM_MEMORY_SIZE + sizeof(uint32_t)]; -}; - -struct rar_filters -{ - struct rar_virtual_machine *vm; - struct rar_program_code *progs; - struct rar_filter *stack; - int64_t filterstart; - uint32_t lastfilternum; - int64_t lastend; - uint8_t *bytes; - size_t bytes_ready; -}; - -struct audio_state -{ - int8_t weight[5]; - int16_t delta[4]; - int8_t lastdelta; - int error[11]; - int count; - uint8_t lastbyte; -}; - -struct rar -{ - /* Entries from main RAR header */ - unsigned main_flags; - unsigned long file_crc; - char reserved1[2]; - char reserved2[4]; - char encryptver; - - /* File header entries */ - char compression_method; - unsigned file_flags; - int64_t packed_size; - int64_t unp_size; - time_t mtime; - long mnsec; - mode_t mode; - char *filename; - char *filename_save; - size_t filename_save_size; - size_t filename_allocated; - - /* File header optional entries */ - char salt[8]; - time_t atime; - long ansec; - time_t ctime; - long cnsec; - time_t arctime; - long arcnsec; - - /* Fields to help with tracking decompression of files. */ - int64_t bytes_unconsumed; - int64_t bytes_remaining; - int64_t bytes_uncopied; - int64_t offset; - int64_t offset_outgoing; - int64_t offset_seek; - char valid; - unsigned int unp_offset; - unsigned int unp_buffer_size; - unsigned char *unp_buffer; - unsigned int dictionary_size; - char start_new_block; - char entry_eof; - unsigned long crc_calculated; - int found_first_header; - char has_endarc_header; - struct data_block_offsets *dbo; - unsigned int cursor; - unsigned int nodes; - char filename_must_match; - - /* LZSS members */ - struct huffman_code maincode; - struct huffman_code offsetcode; - struct huffman_code lowoffsetcode; - struct huffman_code lengthcode; - unsigned char lengthtable[HUFFMAN_TABLE_SIZE]; - struct lzss lzss; - unsigned int lastlength; - unsigned int lastoffset; - unsigned int oldoffset[4]; - unsigned int lastlowoffset; - unsigned int numlowoffsetrepeats; - char start_new_table; - - /* Filters */ - struct rar_filters filters; - - /* PPMd Variant H members */ - char ppmd_valid; - char ppmd_eod; - char is_ppmd_block; - int ppmd_escape; - CPpmd7 ppmd7_context; - CPpmd7z_RangeDec range_dec; - IByteIn bytein; - - /* - * String conversion object. - */ - int init_default_conversion; - struct archive_string_conv *sconv_default; - struct archive_string_conv *opt_sconv; - struct archive_string_conv *sconv_utf8; - struct archive_string_conv *sconv_utf16be; - - /* - * Bit stream reader. - */ - struct rar_br { -#define CACHE_TYPE uint64_t -#define CACHE_BITS (8 * sizeof(CACHE_TYPE)) - /* Cache buffer. */ - CACHE_TYPE cache_buffer; - /* Indicates how many bits avail in cache_buffer. */ - int cache_avail; - ssize_t avail_in; - const unsigned char *next_in; - } br; - - /* - * Custom field to denote that this archive contains encrypted entries - */ - int has_encrypted_entries; -}; - -static int archive_read_support_format_rar_capabilities(struct archive_read *); -static int archive_read_format_rar_has_encrypted_entries(struct archive_read *); -static int archive_read_format_rar_bid(struct archive_read *, int); -static int archive_read_format_rar_options(struct archive_read *, - const char *, const char *); -static int archive_read_format_rar_read_header(struct archive_read *, - struct archive_entry *); -static int archive_read_format_rar_read_data(struct archive_read *, - const void **, size_t *, int64_t *); -static int archive_read_format_rar_read_data_skip(struct archive_read *a); -static int64_t archive_read_format_rar_seek_data(struct archive_read *, int64_t, - int); -static int archive_read_format_rar_cleanup(struct archive_read *); - -/* Support functions */ -static int read_header(struct archive_read *, struct archive_entry *, char); -static time_t get_time(int); -static int read_exttime(const char *, struct rar *, const char *); -static int read_symlink_stored(struct archive_read *, struct archive_entry *, - struct archive_string_conv *); -static int read_data_stored(struct archive_read *, const void **, size_t *, - int64_t *); -static int read_data_compressed(struct archive_read *, const void **, size_t *, - int64_t *, size_t); -static int rar_br_preparation(struct archive_read *, struct rar_br *); -static int parse_codes(struct archive_read *); -static void free_codes(struct archive_read *); -static int read_next_symbol(struct archive_read *, struct huffman_code *); -static int create_code(struct archive_read *, struct huffman_code *, - unsigned char *, int, char); -static int add_value(struct archive_read *, struct huffman_code *, int, int, - int); -static int new_node(struct huffman_code *); -static int make_table(struct archive_read *, struct huffman_code *); -static int make_table_recurse(struct archive_read *, struct huffman_code *, int, - struct huffman_table_entry *, int, int); -static int expand(struct archive_read *, int64_t *); -static int copy_from_lzss_window_to_unp(struct archive_read *, const void **, - int64_t, int); -static const void *rar_read_ahead(struct archive_read *, size_t, ssize_t *); -static int parse_filter(struct archive_read *, const uint8_t *, uint16_t, - uint8_t); -static int run_filters(struct archive_read *); -static void clear_filters(struct rar_filters *); -static struct rar_filter *create_filter(struct rar_program_code *, - const uint8_t *, uint32_t, - uint32_t[8], size_t, uint32_t); -static void delete_filter(struct rar_filter *filter); -static struct rar_program_code *compile_program(const uint8_t *, size_t); -static void delete_program_code(struct rar_program_code *prog); -static uint32_t membr_next_rarvm_number(struct memory_bit_reader *br); -static inline uint32_t membr_bits(struct memory_bit_reader *br, int bits); -static int membr_fill(struct memory_bit_reader *br, int bits); -static int read_filter(struct archive_read *, int64_t *); -static int rar_decode_byte(struct archive_read*, uint8_t *); -static int execute_filter(struct archive_read*, struct rar_filter *, - struct rar_virtual_machine *, size_t); -static int copy_from_lzss_window(struct archive_read *, void *, int64_t, int); -static inline void vm_write_32(struct rar_virtual_machine*, size_t, uint32_t); -static inline uint32_t vm_read_32(struct rar_virtual_machine*, size_t); - -/* - * Bit stream reader. - */ -/* Check that the cache buffer has enough bits. */ -#define rar_br_has(br, n) ((br)->cache_avail >= n) -/* Get compressed data by bit. */ -#define rar_br_bits(br, n) \ - (((uint32_t)((br)->cache_buffer >> \ - ((br)->cache_avail - (n)))) & cache_masks[n]) -#define rar_br_bits_forced(br, n) \ - (((uint32_t)((br)->cache_buffer << \ - ((n) - (br)->cache_avail))) & cache_masks[n]) -/* Read ahead to make sure the cache buffer has enough compressed data we - * will use. - * True : completed, there is enough data in the cache buffer. - * False : there is no data in the stream. */ -#define rar_br_read_ahead(a, br, n) \ - ((rar_br_has(br, (n)) || rar_br_fillup(a, br)) || rar_br_has(br, (n))) -/* Notify how many bits we consumed. */ -#define rar_br_consume(br, n) ((br)->cache_avail -= (n)) -#define rar_br_consume_unalined_bits(br) ((br)->cache_avail &= ~7) - -static const uint32_t cache_masks[] = { - 0x00000000, 0x00000001, 0x00000003, 0x00000007, - 0x0000000F, 0x0000001F, 0x0000003F, 0x0000007F, - 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF, - 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF, - 0x0000FFFF, 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, - 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF, - 0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, - 0x0FFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF -}; - -/* - * Shift away used bits in the cache data and fill it up with following bits. - * Call this when cache buffer does not have enough bits you need. - * - * Returns 1 if the cache buffer is full. - * Returns 0 if the cache buffer is not full; input buffer is empty. - */ -static int -rar_br_fillup(struct archive_read *a, struct rar_br *br) -{ - struct rar *rar = (struct rar *)(a->format->data); - int n = CACHE_BITS - br->cache_avail; - - for (;;) { - switch (n >> 3) { - case 8: - if (br->avail_in >= 8) { - br->cache_buffer = - ((uint64_t)br->next_in[0]) << 56 | - ((uint64_t)br->next_in[1]) << 48 | - ((uint64_t)br->next_in[2]) << 40 | - ((uint64_t)br->next_in[3]) << 32 | - ((uint32_t)br->next_in[4]) << 24 | - ((uint32_t)br->next_in[5]) << 16 | - ((uint32_t)br->next_in[6]) << 8 | - (uint32_t)br->next_in[7]; - br->next_in += 8; - br->avail_in -= 8; - br->cache_avail += 8 * 8; - rar->bytes_unconsumed += 8; - rar->bytes_remaining -= 8; - return (1); - } - break; - case 7: - if (br->avail_in >= 7) { - br->cache_buffer = - (br->cache_buffer << 56) | - ((uint64_t)br->next_in[0]) << 48 | - ((uint64_t)br->next_in[1]) << 40 | - ((uint64_t)br->next_in[2]) << 32 | - ((uint32_t)br->next_in[3]) << 24 | - ((uint32_t)br->next_in[4]) << 16 | - ((uint32_t)br->next_in[5]) << 8 | - (uint32_t)br->next_in[6]; - br->next_in += 7; - br->avail_in -= 7; - br->cache_avail += 7 * 8; - rar->bytes_unconsumed += 7; - rar->bytes_remaining -= 7; - return (1); - } - break; - case 6: - if (br->avail_in >= 6) { - br->cache_buffer = - (br->cache_buffer << 48) | - ((uint64_t)br->next_in[0]) << 40 | - ((uint64_t)br->next_in[1]) << 32 | - ((uint32_t)br->next_in[2]) << 24 | - ((uint32_t)br->next_in[3]) << 16 | - ((uint32_t)br->next_in[4]) << 8 | - (uint32_t)br->next_in[5]; - br->next_in += 6; - br->avail_in -= 6; - br->cache_avail += 6 * 8; - rar->bytes_unconsumed += 6; - rar->bytes_remaining -= 6; - return (1); - } - break; - case 0: - /* We have enough compressed data in - * the cache buffer.*/ - return (1); - default: - break; - } - if (br->avail_in <= 0) { - - if (rar->bytes_unconsumed > 0) { - /* Consume as much as the decompressor - * actually used. */ - __archive_read_consume(a, rar->bytes_unconsumed); - rar->bytes_unconsumed = 0; - } - br->next_in = rar_read_ahead(a, 1, &(br->avail_in)); - if (br->next_in == NULL) - return (0); - if (br->avail_in == 0) - return (0); - } - br->cache_buffer = - (br->cache_buffer << 8) | *br->next_in++; - br->avail_in--; - br->cache_avail += 8; - n -= 8; - rar->bytes_unconsumed++; - rar->bytes_remaining--; - } -} - -static int -rar_br_preparation(struct archive_read *a, struct rar_br *br) -{ - struct rar *rar = (struct rar *)(a->format->data); - - if (rar->bytes_remaining > 0) { - br->next_in = rar_read_ahead(a, 1, &(br->avail_in)); - if (br->next_in == NULL) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated RAR file data"); - return (ARCHIVE_FATAL); - } - if (br->cache_avail == 0) - (void)rar_br_fillup(a, br); - } - return (ARCHIVE_OK); -} - -/* Find last bit set */ -static inline int -rar_fls(unsigned int word) -{ - word |= (word >> 1); - word |= (word >> 2); - word |= (word >> 4); - word |= (word >> 8); - word |= (word >> 16); - return word - (word >> 1); -} - -/* LZSS functions */ -static inline int64_t -lzss_position(struct lzss *lzss) -{ - return lzss->position; -} - -static inline int -lzss_mask(struct lzss *lzss) -{ - return lzss->mask; -} - -static inline int -lzss_size(struct lzss *lzss) -{ - return lzss->mask + 1; -} - -static inline int -lzss_offset_for_position(struct lzss *lzss, int64_t pos) -{ - return (int)(pos & lzss->mask); -} - -static inline unsigned char * -lzss_pointer_for_position(struct lzss *lzss, int64_t pos) -{ - return &lzss->window[lzss_offset_for_position(lzss, pos)]; -} - -static inline int -lzss_current_offset(struct lzss *lzss) -{ - return lzss_offset_for_position(lzss, lzss->position); -} - -static inline uint8_t * -lzss_current_pointer(struct lzss *lzss) -{ - return lzss_pointer_for_position(lzss, lzss->position); -} - -static inline void -lzss_emit_literal(struct rar *rar, uint8_t literal) -{ - *lzss_current_pointer(&rar->lzss) = literal; - rar->lzss.position++; -} - -static inline void -lzss_emit_match(struct rar *rar, int offset, int length) -{ - int dstoffs = lzss_current_offset(&rar->lzss); - int srcoffs = (dstoffs - offset) & lzss_mask(&rar->lzss); - int l, li, remaining; - unsigned char *d, *s; - - remaining = length; - while (remaining > 0) { - l = remaining; - if (dstoffs > srcoffs) { - if (l > lzss_size(&rar->lzss) - dstoffs) - l = lzss_size(&rar->lzss) - dstoffs; - } else { - if (l > lzss_size(&rar->lzss) - srcoffs) - l = lzss_size(&rar->lzss) - srcoffs; - } - d = &(rar->lzss.window[dstoffs]); - s = &(rar->lzss.window[srcoffs]); - if ((dstoffs + l < srcoffs) || (srcoffs + l < dstoffs)) - memcpy(d, s, l); - else { - for (li = 0; li < l; li++) - d[li] = s[li]; - } - remaining -= l; - dstoffs = (dstoffs + l) & lzss_mask(&(rar->lzss)); - srcoffs = (srcoffs + l) & lzss_mask(&(rar->lzss)); - } - rar->lzss.position += length; -} - -static Byte -ppmd_read(void *p) -{ - struct archive_read *a = ((IByteIn*)p)->a; - struct rar *rar = (struct rar *)(a->format->data); - struct rar_br *br = &(rar->br); - Byte b; - if (!rar_br_read_ahead(a, br, 8)) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated RAR file data"); - rar->valid = 0; - return 0; - } - b = rar_br_bits(br, 8); - rar_br_consume(br, 8); - return b; -} - -int -archive_read_support_format_rar(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - struct rar *rar; - int r; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, - "archive_read_support_format_rar"); - - rar = (struct rar *)calloc(sizeof(*rar), 1); - if (rar == NULL) - { - archive_set_error(&a->archive, ENOMEM, "Can't allocate rar data"); - return (ARCHIVE_FATAL); - } - - /* - * Until enough data has been read, we cannot tell about - * any encrypted entries yet. - */ - rar->has_encrypted_entries = ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW; - - r = __archive_read_register_format(a, - rar, - "rar", - archive_read_format_rar_bid, - archive_read_format_rar_options, - archive_read_format_rar_read_header, - archive_read_format_rar_read_data, - archive_read_format_rar_read_data_skip, - archive_read_format_rar_seek_data, - archive_read_format_rar_cleanup, - archive_read_support_format_rar_capabilities, - archive_read_format_rar_has_encrypted_entries); - - if (r != ARCHIVE_OK) - free(rar); - return (r); -} - -static int -archive_read_support_format_rar_capabilities(struct archive_read * a) -{ - (void)a; /* UNUSED */ - return (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA - | ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA); -} - -static int -archive_read_format_rar_has_encrypted_entries(struct archive_read *_a) -{ - if (_a && _a->format) { - struct rar * rar = (struct rar *)_a->format->data; - if (rar) { - return rar->has_encrypted_entries; - } - } - return ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW; -} - - -static int -archive_read_format_rar_bid(struct archive_read *a, int best_bid) -{ - const char *p; - - /* If there's already a bid > 30, we'll never win. */ - if (best_bid > 30) - return (-1); - - if ((p = __archive_read_ahead(a, 7, NULL)) == NULL) - return (-1); - - if (memcmp(p, RAR_SIGNATURE, 7) == 0) - return (30); - - if ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0) { - /* This is a PE file */ - ssize_t offset = 0x10000; - ssize_t window = 4096; - ssize_t bytes_avail; - while (offset + window <= (1024 * 128)) { - const char *buff = __archive_read_ahead(a, offset + window, &bytes_avail); - if (buff == NULL) { - /* Remaining bytes are less than window. */ - window >>= 1; - if (window < 0x40) - return (0); - continue; - } - p = buff + offset; - while (p + 7 < buff + bytes_avail) { - if (memcmp(p, RAR_SIGNATURE, 7) == 0) - return (30); - p += 0x10; - } - offset = p - buff; - } - } - return (0); -} - -static int -skip_sfx(struct archive_read *a) -{ - const void *h; - const char *p, *q; - size_t skip, total; - ssize_t bytes, window; - - total = 0; - window = 4096; - while (total + window <= (1024 * 128)) { - h = __archive_read_ahead(a, window, &bytes); - if (h == NULL) { - /* Remaining bytes are less than window. */ - window >>= 1; - if (window < 0x40) - goto fatal; - continue; - } - if (bytes < 0x40) - goto fatal; - p = h; - q = p + bytes; - - /* - * Scan ahead until we find something that looks - * like the RAR header. - */ - while (p + 7 < q) { - if (memcmp(p, RAR_SIGNATURE, 7) == 0) { - skip = p - (const char *)h; - __archive_read_consume(a, skip); - return (ARCHIVE_OK); - } - p += 0x10; - } - skip = p - (const char *)h; - __archive_read_consume(a, skip); - total += skip; - } -fatal: - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Couldn't find out RAR header"); - return (ARCHIVE_FATAL); -} - -static int -archive_read_format_rar_options(struct archive_read *a, - const char *key, const char *val) -{ - struct rar *rar; - int ret = ARCHIVE_FAILED; - - rar = (struct rar *)(a->format->data); - if (strcmp(key, "hdrcharset") == 0) { - if (val == NULL || val[0] == 0) - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "rar: hdrcharset option needs a character-set name"); - else { - rar->opt_sconv = - archive_string_conversion_from_charset( - &a->archive, val, 0); - if (rar->opt_sconv != NULL) - ret = ARCHIVE_OK; - else - ret = ARCHIVE_FATAL; - } - return (ret); - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -static int -archive_read_format_rar_read_header(struct archive_read *a, - struct archive_entry *entry) -{ - const void *h; - const char *p; - struct rar *rar; - size_t skip; - char head_type; - int ret; - unsigned flags; - unsigned long crc32_expected; - - a->archive.archive_format = ARCHIVE_FORMAT_RAR; - if (a->archive.archive_format_name == NULL) - a->archive.archive_format_name = "RAR"; - - rar = (struct rar *)(a->format->data); - - /* - * It should be sufficient to call archive_read_next_header() for - * a reader to determine if an entry is encrypted or not. If the - * encryption of an entry is only detectable when calling - * archive_read_data(), so be it. We'll do the same check there - * as well. - */ - if (rar->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) { - rar->has_encrypted_entries = 0; - } - - /* RAR files can be generated without EOF headers, so return ARCHIVE_EOF if - * this fails. - */ - if ((h = __archive_read_ahead(a, 7, NULL)) == NULL) - return (ARCHIVE_EOF); - - p = h; - if (rar->found_first_header == 0 && - ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0)) { - /* This is an executable ? Must be self-extracting... */ - ret = skip_sfx(a); - if (ret < ARCHIVE_WARN) - return (ret); - } - rar->found_first_header = 1; - - while (1) - { - unsigned long crc32_val; - - if ((h = __archive_read_ahead(a, 7, NULL)) == NULL) - return (ARCHIVE_FATAL); - p = h; - - head_type = p[2]; - switch(head_type) - { - case MARK_HEAD: - if (memcmp(p, RAR_SIGNATURE, 7) != 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid marker header"); - return (ARCHIVE_FATAL); - } - __archive_read_consume(a, 7); - break; - - case MAIN_HEAD: - rar->main_flags = archive_le16dec(p + 3); - skip = archive_le16dec(p + 5); - if (skip < 7 + sizeof(rar->reserved1) + sizeof(rar->reserved2)) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid header size"); - return (ARCHIVE_FATAL); - } - if ((h = __archive_read_ahead(a, skip, NULL)) == NULL) - return (ARCHIVE_FATAL); - p = h; - memcpy(rar->reserved1, p + 7, sizeof(rar->reserved1)); - memcpy(rar->reserved2, p + 7 + sizeof(rar->reserved1), - sizeof(rar->reserved2)); - if (rar->main_flags & MHD_ENCRYPTVER) { - if (skip < 7 + sizeof(rar->reserved1) + sizeof(rar->reserved2)+1) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid header size"); - return (ARCHIVE_FATAL); - } - rar->encryptver = *(p + 7 + sizeof(rar->reserved1) + - sizeof(rar->reserved2)); - } - - /* Main header is password encrypted, so we cannot read any - file names or any other info about files from the header. */ - if (rar->main_flags & MHD_PASSWORD) - { - archive_entry_set_is_metadata_encrypted(entry, 1); - archive_entry_set_is_data_encrypted(entry, 1); - rar->has_encrypted_entries = 1; - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "RAR encryption support unavailable."); - return (ARCHIVE_FATAL); - } - - crc32_val = crc32(0, (const unsigned char *)p + 2, (unsigned)skip - 2); - if ((crc32_val & 0xffff) != archive_le16dec(p)) { -#ifndef DONT_FAIL_ON_CRC_ERROR - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Header CRC error"); - return (ARCHIVE_FATAL); -#endif - } - __archive_read_consume(a, skip); - break; - - case FILE_HEAD: - return read_header(a, entry, head_type); - - case COMM_HEAD: - case AV_HEAD: - case SUB_HEAD: - case PROTECT_HEAD: - case SIGN_HEAD: - case ENDARC_HEAD: - flags = archive_le16dec(p + 3); - skip = archive_le16dec(p + 5); - if (skip < 7) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid header size too small"); - return (ARCHIVE_FATAL); - } - if (flags & HD_ADD_SIZE_PRESENT) - { - if (skip < 7 + 4) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid header size too small"); - return (ARCHIVE_FATAL); - } - if ((h = __archive_read_ahead(a, skip, NULL)) == NULL) - return (ARCHIVE_FATAL); - p = h; - skip += archive_le32dec(p + 7); - } - - /* Skip over the 2-byte CRC at the beginning of the header. */ - crc32_expected = archive_le16dec(p); - __archive_read_consume(a, 2); - skip -= 2; - - /* Skim the entire header and compute the CRC. */ - crc32_val = 0; - while (skip > 0) { - size_t to_read = skip; - if (to_read > 32 * 1024) - to_read = 32 * 1024; - if ((h = __archive_read_ahead(a, to_read, NULL)) == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Bad RAR file"); - return (ARCHIVE_FATAL); - } - p = h; - crc32_val = crc32(crc32_val, (const unsigned char *)p, (unsigned int)to_read); - __archive_read_consume(a, to_read); - skip -= to_read; - } - if ((crc32_val & 0xffff) != crc32_expected) { -#ifndef DONT_FAIL_ON_CRC_ERROR - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Header CRC error"); - return (ARCHIVE_FATAL); -#endif - } - if (head_type == ENDARC_HEAD) - return (ARCHIVE_EOF); - break; - - case NEWSUB_HEAD: - if ((ret = read_header(a, entry, head_type)) < ARCHIVE_WARN) - return ret; - break; - - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Bad RAR file"); - return (ARCHIVE_FATAL); - } - } -} - -static int -archive_read_format_rar_read_data(struct archive_read *a, const void **buff, - size_t *size, int64_t *offset) -{ - struct rar *rar = (struct rar *)(a->format->data); - int ret; - - if (rar->has_encrypted_entries == ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) { - rar->has_encrypted_entries = 0; - } - - if (rar->bytes_unconsumed > 0) { - /* Consume as much as the decompressor actually used. */ - __archive_read_consume(a, rar->bytes_unconsumed); - rar->bytes_unconsumed = 0; - } - - *buff = NULL; - if (rar->entry_eof || rar->offset_seek >= rar->unp_size) { - *size = 0; - *offset = rar->offset; - if (*offset < rar->unp_size) - *offset = rar->unp_size; - return (ARCHIVE_EOF); - } - - switch (rar->compression_method) - { - case COMPRESS_METHOD_STORE: - ret = read_data_stored(a, buff, size, offset); - break; - - case COMPRESS_METHOD_FASTEST: - case COMPRESS_METHOD_FAST: - case COMPRESS_METHOD_NORMAL: - case COMPRESS_METHOD_GOOD: - case COMPRESS_METHOD_BEST: - ret = read_data_compressed(a, buff, size, offset, 0); - if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN) { - __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context); - rar->start_new_table = 1; - rar->ppmd_valid = 0; - } - break; - - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Unsupported compression method for RAR file."); - ret = ARCHIVE_FATAL; - break; - } - return (ret); -} - -static int -archive_read_format_rar_read_data_skip(struct archive_read *a) -{ - struct rar *rar; - int64_t bytes_skipped; - int ret; - - rar = (struct rar *)(a->format->data); - - if (rar->bytes_unconsumed > 0) { - /* Consume as much as the decompressor actually used. */ - __archive_read_consume(a, rar->bytes_unconsumed); - rar->bytes_unconsumed = 0; - } - - if (rar->bytes_remaining > 0) { - bytes_skipped = __archive_read_consume(a, rar->bytes_remaining); - if (bytes_skipped < 0) - return (ARCHIVE_FATAL); - } - - /* Compressed data to skip must be read from each header in a multivolume - * archive. - */ - if (rar->main_flags & MHD_VOLUME && rar->file_flags & FHD_SPLIT_AFTER) - { - ret = archive_read_format_rar_read_header(a, a->entry); - if (ret == (ARCHIVE_EOF)) - ret = archive_read_format_rar_read_header(a, a->entry); - if (ret != (ARCHIVE_OK)) - return ret; - return archive_read_format_rar_read_data_skip(a); - } - - return (ARCHIVE_OK); -} - -static int64_t -archive_read_format_rar_seek_data(struct archive_read *a, int64_t offset, - int whence) -{ - int64_t client_offset, ret; - unsigned int i; - struct rar *rar = (struct rar *)(a->format->data); - - if (rar->compression_method == COMPRESS_METHOD_STORE) - { - /* Modify the offset for use with SEEK_SET */ - switch (whence) - { - case SEEK_CUR: - client_offset = rar->offset_seek; - break; - case SEEK_END: - client_offset = rar->unp_size; - break; - case SEEK_SET: - default: - client_offset = 0; - } - client_offset += offset; - if (client_offset < 0) - { - /* Can't seek past beginning of data block */ - return -1; - } - else if (client_offset > rar->unp_size) - { - /* - * Set the returned offset but only seek to the end of - * the data block. - */ - rar->offset_seek = client_offset; - client_offset = rar->unp_size; - } - - client_offset += rar->dbo[0].start_offset; - i = 0; - while (i < rar->cursor) - { - i++; - client_offset += rar->dbo[i].start_offset - rar->dbo[i-1].end_offset; - } - if (rar->main_flags & MHD_VOLUME) - { - /* Find the appropriate offset among the multivolume archive */ - while (1) - { - if (client_offset < rar->dbo[rar->cursor].start_offset && - rar->file_flags & FHD_SPLIT_BEFORE) - { - /* Search backwards for the correct data block */ - if (rar->cursor == 0) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Attempt to seek past beginning of RAR data block"); - return (ARCHIVE_FAILED); - } - rar->cursor--; - client_offset -= rar->dbo[rar->cursor+1].start_offset - - rar->dbo[rar->cursor].end_offset; - if (client_offset < rar->dbo[rar->cursor].start_offset) - continue; - ret = __archive_read_seek(a, rar->dbo[rar->cursor].start_offset - - rar->dbo[rar->cursor].header_size, SEEK_SET); - if (ret < (ARCHIVE_OK)) - return ret; - ret = archive_read_format_rar_read_header(a, a->entry); - if (ret != (ARCHIVE_OK)) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Error during seek of RAR file"); - return (ARCHIVE_FAILED); - } - rar->cursor--; - break; - } - else if (client_offset > rar->dbo[rar->cursor].end_offset && - rar->file_flags & FHD_SPLIT_AFTER) - { - /* Search forward for the correct data block */ - rar->cursor++; - if (rar->cursor < rar->nodes && - client_offset > rar->dbo[rar->cursor].end_offset) - { - client_offset += rar->dbo[rar->cursor].start_offset - - rar->dbo[rar->cursor-1].end_offset; - continue; - } - rar->cursor--; - ret = __archive_read_seek(a, rar->dbo[rar->cursor].end_offset, - SEEK_SET); - if (ret < (ARCHIVE_OK)) - return ret; - ret = archive_read_format_rar_read_header(a, a->entry); - if (ret == (ARCHIVE_EOF)) - { - rar->has_endarc_header = 1; - ret = archive_read_format_rar_read_header(a, a->entry); - } - if (ret != (ARCHIVE_OK)) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Error during seek of RAR file"); - return (ARCHIVE_FAILED); - } - client_offset += rar->dbo[rar->cursor].start_offset - - rar->dbo[rar->cursor-1].end_offset; - continue; - } - break; - } - } - - ret = __archive_read_seek(a, client_offset, SEEK_SET); - if (ret < (ARCHIVE_OK)) - return ret; - rar->bytes_remaining = rar->dbo[rar->cursor].end_offset - ret; - i = rar->cursor; - while (i > 0) - { - i--; - ret -= rar->dbo[i+1].start_offset - rar->dbo[i].end_offset; - } - ret -= rar->dbo[0].start_offset; - - /* Always restart reading the file after a seek */ - __archive_reset_read_data(&a->archive); - - rar->bytes_unconsumed = 0; - rar->offset = 0; - - /* - * If a seek past the end of file was requested, return the requested - * offset. - */ - if (ret == rar->unp_size && rar->offset_seek > rar->unp_size) - return rar->offset_seek; - - /* Return the new offset */ - rar->offset_seek = ret; - return rar->offset_seek; - } - else - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Seeking of compressed RAR files is unsupported"); - } - return (ARCHIVE_FAILED); -} - -static int -archive_read_format_rar_cleanup(struct archive_read *a) -{ - struct rar *rar; - - rar = (struct rar *)(a->format->data); - free_codes(a); - clear_filters(&rar->filters); - free(rar->filename); - free(rar->filename_save); - free(rar->dbo); - free(rar->unp_buffer); - free(rar->lzss.window); - __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context); - free(rar); - (a->format->data) = NULL; - return (ARCHIVE_OK); -} - -static int -read_header(struct archive_read *a, struct archive_entry *entry, - char head_type) -{ - const void *h; - const char *p, *endp; - struct rar *rar; - struct rar_header rar_header; - struct rar_file_header file_header; - int64_t header_size; - unsigned filename_size, end; - char *filename; - char *strp; - char packed_size[8]; - char unp_size[8]; - int ttime; - struct archive_string_conv *sconv, *fn_sconv; - unsigned long crc32_val; - int ret = (ARCHIVE_OK), ret2; - - rar = (struct rar *)(a->format->data); - - /* Setup a string conversion object for non-rar-unicode filenames. */ - sconv = rar->opt_sconv; - if (sconv == NULL) { - if (!rar->init_default_conversion) { - rar->sconv_default = - archive_string_default_conversion_for_read( - &(a->archive)); - rar->init_default_conversion = 1; - } - sconv = rar->sconv_default; - } - - - if ((h = __archive_read_ahead(a, 7, NULL)) == NULL) - return (ARCHIVE_FATAL); - p = h; - memcpy(&rar_header, p, sizeof(rar_header)); - rar->file_flags = archive_le16dec(rar_header.flags); - header_size = archive_le16dec(rar_header.size); - if (header_size < (int64_t)sizeof(file_header) + 7) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid header size"); - return (ARCHIVE_FATAL); - } - crc32_val = crc32(0, (const unsigned char *)p + 2, 7 - 2); - __archive_read_consume(a, 7); - - if (!(rar->file_flags & FHD_SOLID)) - { - rar->compression_method = 0; - rar->packed_size = 0; - rar->unp_size = 0; - rar->mtime = 0; - rar->ctime = 0; - rar->atime = 0; - rar->arctime = 0; - rar->mode = 0; - memset(&rar->salt, 0, sizeof(rar->salt)); - rar->atime = 0; - rar->ansec = 0; - rar->ctime = 0; - rar->cnsec = 0; - rar->mtime = 0; - rar->mnsec = 0; - rar->arctime = 0; - rar->arcnsec = 0; - } - else - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "RAR solid archive support unavailable."); - return (ARCHIVE_FATAL); - } - - if ((h = __archive_read_ahead(a, (size_t)header_size - 7, NULL)) == NULL) - return (ARCHIVE_FATAL); - - /* File Header CRC check. */ - crc32_val = crc32(crc32_val, h, (unsigned)(header_size - 7)); - if ((crc32_val & 0xffff) != archive_le16dec(rar_header.crc)) { -#ifndef DONT_FAIL_ON_CRC_ERROR - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Header CRC error"); - return (ARCHIVE_FATAL); -#endif - } - /* If no CRC error, Go on parsing File Header. */ - p = h; - endp = p + header_size - 7; - memcpy(&file_header, p, sizeof(file_header)); - p += sizeof(file_header); - - rar->compression_method = file_header.method; - - ttime = archive_le32dec(file_header.file_time); - rar->mtime = get_time(ttime); - - rar->file_crc = archive_le32dec(file_header.file_crc); - - if (rar->file_flags & FHD_PASSWORD) - { - archive_entry_set_is_data_encrypted(entry, 1); - rar->has_encrypted_entries = 1; - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "RAR encryption support unavailable."); - /* Since it is only the data part itself that is encrypted we can at least - extract information about the currently processed entry and don't need - to return ARCHIVE_FATAL here. */ - /*return (ARCHIVE_FATAL);*/ - } - - if (rar->file_flags & FHD_LARGE) - { - memcpy(packed_size, file_header.pack_size, 4); - memcpy(packed_size + 4, p, 4); /* High pack size */ - p += 4; - memcpy(unp_size, file_header.unp_size, 4); - memcpy(unp_size + 4, p, 4); /* High unpack size */ - p += 4; - rar->packed_size = archive_le64dec(&packed_size); - rar->unp_size = archive_le64dec(&unp_size); - } - else - { - rar->packed_size = archive_le32dec(file_header.pack_size); - rar->unp_size = archive_le32dec(file_header.unp_size); - } - - if (rar->packed_size < 0 || rar->unp_size < 0) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid sizes specified."); - return (ARCHIVE_FATAL); - } - - rar->bytes_remaining = rar->packed_size; - - /* TODO: RARv3 subblocks contain comments. For now the complete block is - * consumed at the end. - */ - if (head_type == NEWSUB_HEAD) { - size_t distance = p - (const char *)h; - header_size += rar->packed_size; - /* Make sure we have the extended data. */ - if ((h = __archive_read_ahead(a, (size_t)header_size - 7, NULL)) == NULL) - return (ARCHIVE_FATAL); - p = h; - endp = p + header_size - 7; - p += distance; - } - - filename_size = archive_le16dec(file_header.name_size); - if (p + filename_size > endp) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid filename size"); - return (ARCHIVE_FATAL); - } - if (rar->filename_allocated < filename_size * 2 + 2) { - char *newptr; - size_t newsize = filename_size * 2 + 2; - newptr = realloc(rar->filename, newsize); - if (newptr == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Couldn't allocate memory."); - return (ARCHIVE_FATAL); - } - rar->filename = newptr; - rar->filename_allocated = newsize; - } - filename = rar->filename; - memcpy(filename, p, filename_size); - filename[filename_size] = '\0'; - if (rar->file_flags & FHD_UNICODE) - { - if (filename_size != strlen(filename)) - { - unsigned char highbyte, flagbits, flagbyte; - unsigned fn_end, offset; - - end = filename_size; - fn_end = filename_size * 2; - filename_size = 0; - offset = (unsigned)strlen(filename) + 1; - highbyte = *(p + offset++); - flagbits = 0; - flagbyte = 0; - while (offset < end && filename_size < fn_end) - { - if (!flagbits) - { - flagbyte = *(p + offset++); - flagbits = 8; - } - - flagbits -= 2; - switch((flagbyte >> flagbits) & 3) - { - case 0: - filename[filename_size++] = '\0'; - filename[filename_size++] = *(p + offset++); - break; - case 1: - filename[filename_size++] = highbyte; - filename[filename_size++] = *(p + offset++); - break; - case 2: - filename[filename_size++] = *(p + offset + 1); - filename[filename_size++] = *(p + offset); - offset += 2; - break; - case 3: - { - char extra, high; - uint8_t length = *(p + offset++); - - if (length & 0x80) { - extra = *(p + offset++); - high = (char)highbyte; - } else - extra = high = 0; - length = (length & 0x7f) + 2; - while (length && filename_size < fn_end) { - unsigned cp = filename_size >> 1; - filename[filename_size++] = high; - filename[filename_size++] = p[cp] + extra; - length--; - } - } - break; - } - } - if (filename_size > fn_end) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid filename"); - return (ARCHIVE_FATAL); - } - filename[filename_size++] = '\0'; - /* - * Do not increment filename_size here as the computations below - * add the space for the terminating NUL explicitly. - */ - filename[filename_size] = '\0'; - - /* Decoded unicode form is UTF-16BE, so we have to update a string - * conversion object for it. */ - if (rar->sconv_utf16be == NULL) { - rar->sconv_utf16be = archive_string_conversion_from_charset( - &a->archive, "UTF-16BE", 1); - if (rar->sconv_utf16be == NULL) - return (ARCHIVE_FATAL); - } - fn_sconv = rar->sconv_utf16be; - - strp = filename; - while (memcmp(strp, "\x00\x00", 2)) - { - if (!memcmp(strp, "\x00\\", 2)) - *(strp + 1) = '/'; - strp += 2; - } - p += offset; - } else { - /* - * If FHD_UNICODE is set but no unicode data, this file name form - * is UTF-8, so we have to update a string conversion object for - * it accordingly. - */ - if (rar->sconv_utf8 == NULL) { - rar->sconv_utf8 = archive_string_conversion_from_charset( - &a->archive, "UTF-8", 1); - if (rar->sconv_utf8 == NULL) - return (ARCHIVE_FATAL); - } - fn_sconv = rar->sconv_utf8; - while ((strp = strchr(filename, '\\')) != NULL) - *strp = '/'; - p += filename_size; - } - } - else - { - fn_sconv = sconv; - while ((strp = strchr(filename, '\\')) != NULL) - *strp = '/'; - p += filename_size; - } - - /* Split file in multivolume RAR. No more need to process header. */ - if (rar->filename_save && - filename_size == rar->filename_save_size && - !memcmp(rar->filename, rar->filename_save, filename_size + 1)) - { - __archive_read_consume(a, header_size - 7); - rar->cursor++; - if (rar->cursor >= rar->nodes) - { - rar->nodes++; - if ((rar->dbo = - realloc(rar->dbo, sizeof(*rar->dbo) * rar->nodes)) == NULL) - { - archive_set_error(&a->archive, ENOMEM, "Couldn't allocate memory."); - return (ARCHIVE_FATAL); - } - rar->dbo[rar->cursor].header_size = header_size; - rar->dbo[rar->cursor].start_offset = -1; - rar->dbo[rar->cursor].end_offset = -1; - } - if (rar->dbo[rar->cursor].start_offset < 0) - { - rar->dbo[rar->cursor].start_offset = a->filter->position; - rar->dbo[rar->cursor].end_offset = rar->dbo[rar->cursor].start_offset + - rar->packed_size; - } - return ret; - } - else if (rar->filename_must_match) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Mismatch of file parts split across multi-volume archive"); - return (ARCHIVE_FATAL); - } - - rar->filename_save = (char*)realloc(rar->filename_save, - filename_size + 1); - memcpy(rar->filename_save, rar->filename, filename_size + 1); - rar->filename_save_size = filename_size; - - /* Set info for seeking */ - free(rar->dbo); - if ((rar->dbo = calloc(1, sizeof(*rar->dbo))) == NULL) - { - archive_set_error(&a->archive, ENOMEM, "Couldn't allocate memory."); - return (ARCHIVE_FATAL); - } - rar->dbo[0].header_size = header_size; - rar->dbo[0].start_offset = -1; - rar->dbo[0].end_offset = -1; - rar->cursor = 0; - rar->nodes = 1; - - if (rar->file_flags & FHD_SALT) - { - if (p + 8 > endp) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid header size"); - return (ARCHIVE_FATAL); - } - memcpy(rar->salt, p, 8); - p += 8; - } - - if (rar->file_flags & FHD_EXTTIME) { - if (read_exttime(p, rar, endp) < 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid header size"); - return (ARCHIVE_FATAL); - } - } - - __archive_read_consume(a, header_size - 7); - rar->dbo[0].start_offset = a->filter->position; - rar->dbo[0].end_offset = rar->dbo[0].start_offset + rar->packed_size; - - switch(file_header.host_os) - { - case OS_MSDOS: - case OS_OS2: - case OS_WIN32: - rar->mode = archive_le32dec(file_header.file_attr); - if (rar->mode & FILE_ATTRIBUTE_DIRECTORY) - rar->mode = AE_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH; - else - rar->mode = AE_IFREG; - rar->mode |= S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; - break; - - case OS_UNIX: - case OS_MAC_OS: - case OS_BEOS: - rar->mode = archive_le32dec(file_header.file_attr); - break; - - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Unknown file attributes from RAR file's host OS"); - return (ARCHIVE_FATAL); - } - - rar->bytes_uncopied = rar->bytes_unconsumed = 0; - rar->lzss.position = rar->offset = 0; - rar->offset_seek = 0; - rar->dictionary_size = 0; - rar->offset_outgoing = 0; - rar->br.cache_avail = 0; - rar->br.avail_in = 0; - rar->crc_calculated = 0; - rar->entry_eof = 0; - rar->valid = 1; - rar->is_ppmd_block = 0; - rar->start_new_table = 1; - free(rar->unp_buffer); - rar->unp_buffer = NULL; - rar->unp_offset = 0; - rar->unp_buffer_size = UNP_BUFFER_SIZE; - memset(rar->lengthtable, 0, sizeof(rar->lengthtable)); - __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context); - rar->ppmd_valid = rar->ppmd_eod = 0; - rar->filters.filterstart = INT64_MAX; - - /* Don't set any archive entries for non-file header types */ - if (head_type == NEWSUB_HEAD) - return ret; - - archive_entry_set_mtime(entry, rar->mtime, rar->mnsec); - archive_entry_set_ctime(entry, rar->ctime, rar->cnsec); - archive_entry_set_atime(entry, rar->atime, rar->ansec); - archive_entry_set_size(entry, rar->unp_size); - archive_entry_set_mode(entry, rar->mode); - - if (archive_entry_copy_pathname_l(entry, filename, filename_size, fn_sconv)) - { - if (errno == ENOMEM) - { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Pathname"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Pathname cannot be converted from %s to current locale.", - archive_string_conversion_charset_name(fn_sconv)); - ret = (ARCHIVE_WARN); - } - - if (((rar->mode) & AE_IFMT) == AE_IFLNK) - { - /* Make sure a symbolic-link file does not have its body. */ - rar->bytes_remaining = 0; - archive_entry_set_size(entry, 0); - - /* Read a symbolic-link name. */ - if ((ret2 = read_symlink_stored(a, entry, sconv)) < (ARCHIVE_WARN)) - return ret2; - if (ret > ret2) - ret = ret2; - } - - if (rar->bytes_remaining == 0) - rar->entry_eof = 1; - - return ret; -} - -static time_t -get_time(int ttime) -{ - struct tm tm; - tm.tm_sec = 2 * (ttime & 0x1f); - tm.tm_min = (ttime >> 5) & 0x3f; - tm.tm_hour = (ttime >> 11) & 0x1f; - tm.tm_mday = (ttime >> 16) & 0x1f; - tm.tm_mon = ((ttime >> 21) & 0x0f) - 1; - tm.tm_year = ((ttime >> 25) & 0x7f) + 80; - tm.tm_isdst = -1; - return mktime(&tm); -} - -static int -read_exttime(const char *p, struct rar *rar, const char *endp) -{ - unsigned rmode, flags, rem, j, count; - int ttime, i; - struct tm *tm; - time_t t; - long nsec; -#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S) - struct tm tmbuf; -#endif - - if (p + 2 > endp) - return (-1); - flags = archive_le16dec(p); - p += 2; - - for (i = 3; i >= 0; i--) - { - t = 0; - if (i == 3) - t = rar->mtime; - rmode = flags >> i * 4; - if (rmode & 8) - { - if (!t) - { - if (p + 4 > endp) - return (-1); - ttime = archive_le32dec(p); - t = get_time(ttime); - p += 4; - } - rem = 0; - count = rmode & 3; - if (p + count > endp) - return (-1); - for (j = 0; j < count; j++) - { - rem = (((unsigned)(unsigned char)*p) << 16) | (rem >> 8); - p++; - } -#if defined(HAVE_LOCALTIME_S) - tm = localtime_s(&tmbuf, &t) ? NULL : &tmbuf; -#elif defined(HAVE_LOCALTIME_R) - tm = localtime_r(&t, &tmbuf); -#else - tm = localtime(&t); -#endif - nsec = tm->tm_sec + rem / NS_UNIT; - if (rmode & 4) - { - tm->tm_sec++; - t = mktime(tm); - } - if (i == 3) - { - rar->mtime = t; - rar->mnsec = nsec; - } - else if (i == 2) - { - rar->ctime = t; - rar->cnsec = nsec; - } - else if (i == 1) - { - rar->atime = t; - rar->ansec = nsec; - } - else - { - rar->arctime = t; - rar->arcnsec = nsec; - } - } - } - return (0); -} - -static int -read_symlink_stored(struct archive_read *a, struct archive_entry *entry, - struct archive_string_conv *sconv) -{ - const void *h; - const char *p; - struct rar *rar; - int ret = (ARCHIVE_OK); - - rar = (struct rar *)(a->format->data); - if ((h = rar_read_ahead(a, (size_t)rar->packed_size, NULL)) == NULL) - return (ARCHIVE_FATAL); - p = h; - - if (archive_entry_copy_symlink_l(entry, - p, (size_t)rar->packed_size, sconv)) - { - if (errno == ENOMEM) - { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for link"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "link cannot be converted from %s to current locale.", - archive_string_conversion_charset_name(sconv)); - ret = (ARCHIVE_WARN); - } - __archive_read_consume(a, rar->packed_size); - return ret; -} - -static int -read_data_stored(struct archive_read *a, const void **buff, size_t *size, - int64_t *offset) -{ - struct rar *rar; - ssize_t bytes_avail; - - rar = (struct rar *)(a->format->data); - if (rar->bytes_remaining == 0 && - !(rar->main_flags & MHD_VOLUME && rar->file_flags & FHD_SPLIT_AFTER)) - { - *buff = NULL; - *size = 0; - *offset = rar->offset; - if (rar->file_crc != rar->crc_calculated) { -#ifndef DONT_FAIL_ON_CRC_ERROR - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "File CRC error"); - return (ARCHIVE_FATAL); -#endif - } - rar->entry_eof = 1; - return (ARCHIVE_EOF); - } - - *buff = rar_read_ahead(a, 1, &bytes_avail); - if (bytes_avail <= 0) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated RAR file data"); - return (ARCHIVE_FATAL); - } - - *size = bytes_avail; - *offset = rar->offset; - rar->offset += bytes_avail; - rar->offset_seek += bytes_avail; - rar->bytes_remaining -= bytes_avail; - rar->bytes_unconsumed = bytes_avail; - /* Calculate File CRC. */ - rar->crc_calculated = crc32(rar->crc_calculated, *buff, - (unsigned)bytes_avail); - return (ARCHIVE_OK); -} - -static int -read_data_compressed(struct archive_read *a, const void **buff, size_t *size, - int64_t *offset, size_t looper) -{ - if (looper++ > MAX_COMPRESS_DEPTH) - return (ARCHIVE_FATAL); - - struct rar *rar; - int64_t start, end; - size_t bs; - int ret = (ARCHIVE_OK), sym, code, lzss_offset, length, i; - - rar = (struct rar *)(a->format->data); - - do { - if (!rar->valid) - return (ARCHIVE_FATAL); - - if (rar->filters.bytes_ready > 0) - { - /* Flush unp_buffer first */ - if (rar->unp_offset > 0) - { - *buff = rar->unp_buffer; - *size = rar->unp_offset; - rar->unp_offset = 0; - *offset = rar->offset_outgoing; - rar->offset_outgoing += *size; - } - else - { - *buff = rar->filters.bytes; - *size = rar->filters.bytes_ready; - - rar->offset += *size; - *offset = rar->offset_outgoing; - rar->offset_outgoing += *size; - - rar->filters.bytes_ready -= *size; - rar->filters.bytes += *size; - } - goto ending_block; - } - - if (rar->ppmd_eod || - (rar->dictionary_size && rar->offset >= rar->unp_size)) - { - if (rar->unp_offset > 0) { - /* - * We have unprocessed extracted data. write it out. - */ - *buff = rar->unp_buffer; - *size = rar->unp_offset; - *offset = rar->offset_outgoing; - rar->offset_outgoing += *size; - /* Calculate File CRC. */ - rar->crc_calculated = crc32(rar->crc_calculated, *buff, - (unsigned)*size); - rar->unp_offset = 0; - return (ARCHIVE_OK); - } - *buff = NULL; - *size = 0; - *offset = rar->offset; - if (rar->file_crc != rar->crc_calculated) { -#ifndef DONT_FAIL_ON_CRC_ERROR - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "File CRC error"); - return (ARCHIVE_FATAL); -#endif - } - rar->entry_eof = 1; - return (ARCHIVE_EOF); - } - - if (!rar->is_ppmd_block && rar->dictionary_size && rar->bytes_uncopied > 0) - { - if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset)) - bs = rar->unp_buffer_size - rar->unp_offset; - else - bs = (size_t)rar->bytes_uncopied; - ret = copy_from_lzss_window_to_unp(a, buff, rar->offset, (int)bs); - if (ret != ARCHIVE_OK) - return (ret); - rar->offset += bs; - rar->bytes_uncopied -= bs; - if (*buff != NULL) { - rar->unp_offset = 0; - *size = rar->unp_buffer_size; - *offset = rar->offset_outgoing; - rar->offset_outgoing += *size; - /* Calculate File CRC. */ - rar->crc_calculated = crc32(rar->crc_calculated, *buff, - (unsigned)*size); - return (ret); - } - continue; - } - - if (rar->filters.lastend == rar->filters.filterstart) - { - if (!run_filters(a)) - return (ARCHIVE_FATAL); - continue; - } - - if (!rar->br.next_in && - (ret = rar_br_preparation(a, &(rar->br))) < ARCHIVE_WARN) - return (ret); - if (rar->start_new_table && ((ret = parse_codes(a)) < (ARCHIVE_WARN))) - return (ret); - - if (rar->is_ppmd_block) - { - if ((sym = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( - &rar->ppmd7_context, &rar->range_dec.p)) < 0) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid symbol"); - return (ARCHIVE_FATAL); - } - if(sym != rar->ppmd_escape) - { - lzss_emit_literal(rar, sym); - rar->bytes_uncopied++; - } - else - { - if ((code = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( - &rar->ppmd7_context, &rar->range_dec.p)) < 0) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid symbol"); - return (ARCHIVE_FATAL); - } - - switch(code) - { - case 0: - rar->start_new_table = 1; - return read_data_compressed(a, buff, size, offset, looper); - - case 2: - rar->ppmd_eod = 1;/* End Of ppmd Data. */ - continue; - - case 3: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Parsing filters is unsupported."); - return (ARCHIVE_FAILED); - - case 4: - lzss_offset = 0; - for (i = 2; i >= 0; i--) - { - if ((code = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( - &rar->ppmd7_context, &rar->range_dec.p)) < 0) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid symbol"); - return (ARCHIVE_FATAL); - } - lzss_offset |= code << (i * 8); - } - if ((length = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( - &rar->ppmd7_context, &rar->range_dec.p)) < 0) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid symbol"); - return (ARCHIVE_FATAL); - } - lzss_emit_match(rar, lzss_offset + 2, length + 32); - rar->bytes_uncopied += length + 32; - break; - - case 5: - if ((length = __archive_ppmd7_functions.Ppmd7_DecodeSymbol( - &rar->ppmd7_context, &rar->range_dec.p)) < 0) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid symbol"); - return (ARCHIVE_FATAL); - } - lzss_emit_match(rar, 1, length + 4); - rar->bytes_uncopied += length + 4; - break; - - default: - lzss_emit_literal(rar, sym); - rar->bytes_uncopied++; - } - } - } - else - { - start = rar->offset; - end = start + rar->dictionary_size; - if (rar->filters.filterstart < end) { - end = rar->filters.filterstart; - } - - ret = expand(a, &end); - if (ret != ARCHIVE_OK) - return (ret); - - rar->bytes_uncopied = end - start; - rar->filters.lastend = end; - if (rar->filters.lastend != rar->filters.filterstart && rar->bytes_uncopied == 0) { - /* Broken RAR files cause this case. - * NOTE: If this case were possible on a normal RAR file - * we would find out where it was actually bad and - * what we would do to solve it. */ - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Internal error extracting RAR file"); - return (ARCHIVE_FATAL); - } - } - if (rar->bytes_uncopied > (rar->unp_buffer_size - rar->unp_offset)) - bs = rar->unp_buffer_size - rar->unp_offset; - else - bs = (size_t)rar->bytes_uncopied; - ret = copy_from_lzss_window_to_unp(a, buff, rar->offset, (int)bs); - if (ret != ARCHIVE_OK) - return (ret); - rar->offset += bs; - rar->bytes_uncopied -= bs; - /* - * If *buff is NULL, it means unp_buffer is not full. - * So we have to continue extracting a RAR file. - */ - } while (*buff == NULL); - - rar->unp_offset = 0; - *size = rar->unp_buffer_size; - *offset = rar->offset_outgoing; - rar->offset_outgoing += *size; -ending_block: - /* Calculate File CRC. */ - rar->crc_calculated = crc32(rar->crc_calculated, *buff, (unsigned)*size); - return ret; -} - -static int -parse_codes(struct archive_read *a) -{ - int i, j, val, n, r; - unsigned char bitlengths[MAX_SYMBOLS], zerocount, ppmd_flags; - unsigned int maxorder; - struct huffman_code precode; - struct rar *rar = (struct rar *)(a->format->data); - struct rar_br *br = &(rar->br); - - free_codes(a); - - /* Skip to the next byte */ - rar_br_consume_unalined_bits(br); - - /* PPMd block flag */ - if (!rar_br_read_ahead(a, br, 1)) - goto truncated_data; - if ((rar->is_ppmd_block = rar_br_bits(br, 1)) != 0) - { - rar_br_consume(br, 1); - if (!rar_br_read_ahead(a, br, 7)) - goto truncated_data; - ppmd_flags = rar_br_bits(br, 7); - rar_br_consume(br, 7); - - /* Memory is allocated in MB */ - if (ppmd_flags & 0x20) - { - if (!rar_br_read_ahead(a, br, 8)) - goto truncated_data; - rar->dictionary_size = (rar_br_bits(br, 8) + 1) << 20; - rar_br_consume(br, 8); - } - - if (ppmd_flags & 0x40) - { - if (!rar_br_read_ahead(a, br, 8)) - goto truncated_data; - rar->ppmd_escape = rar->ppmd7_context.InitEsc = rar_br_bits(br, 8); - rar_br_consume(br, 8); - } - else - rar->ppmd_escape = 2; - - if (ppmd_flags & 0x20) - { - maxorder = (ppmd_flags & 0x1F) + 1; - if(maxorder > 16) - maxorder = 16 + (maxorder - 16) * 3; - - if (maxorder == 1) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated RAR file data"); - return (ARCHIVE_FATAL); - } - - /* Make sure ppmd7_contest is freed before Ppmd7_Construct - * because reading a broken file cause this abnormal sequence. */ - __archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context); - - rar->bytein.a = a; - rar->bytein.Read = &ppmd_read; - __archive_ppmd7_functions.PpmdRAR_RangeDec_CreateVTable(&rar->range_dec); - rar->range_dec.Stream = &rar->bytein; - __archive_ppmd7_functions.Ppmd7_Construct(&rar->ppmd7_context); - - if (rar->dictionary_size == 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid zero dictionary size"); - return (ARCHIVE_FATAL); - } - - if (!__archive_ppmd7_functions.Ppmd7_Alloc(&rar->ppmd7_context, - rar->dictionary_size)) - { - archive_set_error(&a->archive, ENOMEM, - "Out of memory"); - return (ARCHIVE_FATAL); - } - if (!__archive_ppmd7_functions.PpmdRAR_RangeDec_Init(&rar->range_dec)) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Unable to initialize PPMd range decoder"); - return (ARCHIVE_FATAL); - } - __archive_ppmd7_functions.Ppmd7_Init(&rar->ppmd7_context, maxorder); - rar->ppmd_valid = 1; - } - else - { - if (!rar->ppmd_valid) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid PPMd sequence"); - return (ARCHIVE_FATAL); - } - if (!__archive_ppmd7_functions.PpmdRAR_RangeDec_Init(&rar->range_dec)) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Unable to initialize PPMd range decoder"); - return (ARCHIVE_FATAL); - } - } - } - else - { - rar_br_consume(br, 1); - - /* Keep existing table flag */ - if (!rar_br_read_ahead(a, br, 1)) - goto truncated_data; - if (!rar_br_bits(br, 1)) - memset(rar->lengthtable, 0, sizeof(rar->lengthtable)); - rar_br_consume(br, 1); - - memset(&bitlengths, 0, sizeof(bitlengths)); - for (i = 0; i < MAX_SYMBOLS;) - { - if (!rar_br_read_ahead(a, br, 4)) - goto truncated_data; - bitlengths[i++] = rar_br_bits(br, 4); - rar_br_consume(br, 4); - if (bitlengths[i-1] == 0xF) - { - if (!rar_br_read_ahead(a, br, 4)) - goto truncated_data; - zerocount = rar_br_bits(br, 4); - rar_br_consume(br, 4); - if (zerocount) - { - i--; - for (j = 0; j < zerocount + 2 && i < MAX_SYMBOLS; j++) - bitlengths[i++] = 0; - } - } - } - - memset(&precode, 0, sizeof(precode)); - r = create_code(a, &precode, bitlengths, MAX_SYMBOLS, MAX_SYMBOL_LENGTH); - if (r != ARCHIVE_OK) { - free(precode.tree); - free(precode.table); - return (r); - } - - for (i = 0; i < HUFFMAN_TABLE_SIZE;) - { - if ((val = read_next_symbol(a, &precode)) < 0) { - free(precode.tree); - free(precode.table); - return (ARCHIVE_FATAL); - } - if (val < 16) - { - rar->lengthtable[i] = (rar->lengthtable[i] + val) & 0xF; - i++; - } - else if (val < 18) - { - if (i == 0) - { - free(precode.tree); - free(precode.table); - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Internal error extracting RAR file."); - return (ARCHIVE_FATAL); - } - - if(val == 16) { - if (!rar_br_read_ahead(a, br, 3)) { - free(precode.tree); - free(precode.table); - goto truncated_data; - } - n = rar_br_bits(br, 3) + 3; - rar_br_consume(br, 3); - } else { - if (!rar_br_read_ahead(a, br, 7)) { - free(precode.tree); - free(precode.table); - goto truncated_data; - } - n = rar_br_bits(br, 7) + 11; - rar_br_consume(br, 7); - } - - for (j = 0; j < n && i < HUFFMAN_TABLE_SIZE; j++) - { - rar->lengthtable[i] = rar->lengthtable[i-1]; - i++; - } - } - else - { - if(val == 18) { - if (!rar_br_read_ahead(a, br, 3)) { - free(precode.tree); - free(precode.table); - goto truncated_data; - } - n = rar_br_bits(br, 3) + 3; - rar_br_consume(br, 3); - } else { - if (!rar_br_read_ahead(a, br, 7)) { - free(precode.tree); - free(precode.table); - goto truncated_data; - } - n = rar_br_bits(br, 7) + 11; - rar_br_consume(br, 7); - } - - for(j = 0; j < n && i < HUFFMAN_TABLE_SIZE; j++) - rar->lengthtable[i++] = 0; - } - } - free(precode.tree); - free(precode.table); - - r = create_code(a, &rar->maincode, &rar->lengthtable[0], MAINCODE_SIZE, - MAX_SYMBOL_LENGTH); - if (r != ARCHIVE_OK) - return (r); - r = create_code(a, &rar->offsetcode, &rar->lengthtable[MAINCODE_SIZE], - OFFSETCODE_SIZE, MAX_SYMBOL_LENGTH); - if (r != ARCHIVE_OK) - return (r); - r = create_code(a, &rar->lowoffsetcode, - &rar->lengthtable[MAINCODE_SIZE + OFFSETCODE_SIZE], - LOWOFFSETCODE_SIZE, MAX_SYMBOL_LENGTH); - if (r != ARCHIVE_OK) - return (r); - r = create_code(a, &rar->lengthcode, - &rar->lengthtable[MAINCODE_SIZE + OFFSETCODE_SIZE + - LOWOFFSETCODE_SIZE], LENGTHCODE_SIZE, MAX_SYMBOL_LENGTH); - if (r != ARCHIVE_OK) - return (r); - } - - if (!rar->dictionary_size || !rar->lzss.window) - { - /* Seems as though dictionary sizes are not used. Even so, minimize - * memory usage as much as possible. - */ - void *new_window; - unsigned int new_size; - - if (rar->unp_size >= DICTIONARY_MAX_SIZE) - new_size = DICTIONARY_MAX_SIZE; - else - new_size = rar_fls((unsigned int)rar->unp_size) << 1; - if (new_size == 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Zero window size is invalid."); - return (ARCHIVE_FATAL); - } - new_window = realloc(rar->lzss.window, new_size); - if (new_window == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Unable to allocate memory for uncompressed data."); - return (ARCHIVE_FATAL); - } - rar->lzss.window = (unsigned char *)new_window; - rar->dictionary_size = new_size; - memset(rar->lzss.window, 0, rar->dictionary_size); - rar->lzss.mask = rar->dictionary_size - 1; - } - - rar->start_new_table = 0; - return (ARCHIVE_OK); -truncated_data: - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated RAR file data"); - rar->valid = 0; - return (ARCHIVE_FATAL); -} - -static void -free_codes(struct archive_read *a) -{ - struct rar *rar = (struct rar *)(a->format->data); - free(rar->maincode.tree); - free(rar->offsetcode.tree); - free(rar->lowoffsetcode.tree); - free(rar->lengthcode.tree); - free(rar->maincode.table); - free(rar->offsetcode.table); - free(rar->lowoffsetcode.table); - free(rar->lengthcode.table); - memset(&rar->maincode, 0, sizeof(rar->maincode)); - memset(&rar->offsetcode, 0, sizeof(rar->offsetcode)); - memset(&rar->lowoffsetcode, 0, sizeof(rar->lowoffsetcode)); - memset(&rar->lengthcode, 0, sizeof(rar->lengthcode)); -} - - -static int -read_next_symbol(struct archive_read *a, struct huffman_code *code) -{ - unsigned char bit; - unsigned int bits; - int length, value, node; - struct rar *rar; - struct rar_br *br; - - if (!code->table) - { - if (make_table(a, code) != (ARCHIVE_OK)) - return -1; - } - - rar = (struct rar *)(a->format->data); - br = &(rar->br); - - /* Look ahead (peek) at bits */ - if (!rar_br_read_ahead(a, br, code->tablesize)) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated RAR file data"); - rar->valid = 0; - return -1; - } - bits = rar_br_bits(br, code->tablesize); - - length = code->table[bits].length; - value = code->table[bits].value; - - if (length < 0) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid prefix code in bitstream"); - return -1; - } - - if (length <= code->tablesize) - { - /* Skip length bits */ - rar_br_consume(br, length); - return value; - } - - /* Skip tablesize bits */ - rar_br_consume(br, code->tablesize); - - node = value; - while (!(code->tree[node].branches[0] == - code->tree[node].branches[1])) - { - if (!rar_br_read_ahead(a, br, 1)) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated RAR file data"); - rar->valid = 0; - return -1; - } - bit = rar_br_bits(br, 1); - rar_br_consume(br, 1); - - if (code->tree[node].branches[bit] < 0) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid prefix code in bitstream"); - return -1; - } - node = code->tree[node].branches[bit]; - } - - return code->tree[node].branches[0]; -} - -static int -create_code(struct archive_read *a, struct huffman_code *code, - unsigned char *lengths, int numsymbols, char maxlength) -{ - int i, j, codebits = 0, symbolsleft = numsymbols; - - code->numentries = 0; - code->numallocatedentries = 0; - if (new_node(code) < 0) { - archive_set_error(&a->archive, ENOMEM, - "Unable to allocate memory for node data."); - return (ARCHIVE_FATAL); - } - code->numentries = 1; - code->minlength = INT_MAX; - code->maxlength = INT_MIN; - codebits = 0; - for(i = 1; i <= maxlength; i++) - { - for(j = 0; j < numsymbols; j++) - { - if (lengths[j] != i) continue; - if (add_value(a, code, j, codebits, i) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - codebits++; - if (--symbolsleft <= 0) - break; - } - if (symbolsleft <= 0) - break; - codebits <<= 1; - } - return (ARCHIVE_OK); -} - -static int -add_value(struct archive_read *a, struct huffman_code *code, int value, - int codebits, int length) -{ - int lastnode, bitpos, bit; - /* int repeatpos, repeatnode, nextnode; */ - - free(code->table); - code->table = NULL; - - if(length > code->maxlength) - code->maxlength = length; - if(length < code->minlength) - code->minlength = length; - - /* - * Dead code, repeatpos was is -1 - * - repeatpos = -1; - if (repeatpos == 0 || (repeatpos >= 0 - && (((codebits >> (repeatpos - 1)) & 3) == 0 - || ((codebits >> (repeatpos - 1)) & 3) == 3))) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid repeat position"); - return (ARCHIVE_FATAL); - } - */ - - lastnode = 0; - for (bitpos = length - 1; bitpos >= 0; bitpos--) - { - bit = (codebits >> bitpos) & 1; - - /* Leaf node check */ - if (code->tree[lastnode].branches[0] == - code->tree[lastnode].branches[1]) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Prefix found"); - return (ARCHIVE_FATAL); - } - - /* - * Dead code, repeatpos was -1, bitpos >=0 - * - if (bitpos == repeatpos) - { - * Open branch check * - if (!(code->tree[lastnode].branches[bit] < 0)) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid repeating code"); - return (ARCHIVE_FATAL); - } - - if ((repeatnode = new_node(code)) < 0) { - archive_set_error(&a->archive, ENOMEM, - "Unable to allocate memory for node data."); - return (ARCHIVE_FATAL); - } - if ((nextnode = new_node(code)) < 0) { - archive_set_error(&a->archive, ENOMEM, - "Unable to allocate memory for node data."); - return (ARCHIVE_FATAL); - } - - * Set branches * - code->tree[lastnode].branches[bit] = repeatnode; - code->tree[repeatnode].branches[bit] = repeatnode; - code->tree[repeatnode].branches[bit^1] = nextnode; - lastnode = nextnode; - - bitpos++; * terminating bit already handled, skip it * - } - else - { - */ - /* Open branch check */ - if (code->tree[lastnode].branches[bit] < 0) - { - if (new_node(code) < 0) { - archive_set_error(&a->archive, ENOMEM, - "Unable to allocate memory for node data."); - return (ARCHIVE_FATAL); - } - code->tree[lastnode].branches[bit] = code->numentries++; - } - - /* set to branch */ - lastnode = code->tree[lastnode].branches[bit]; - /* } */ - } - - if (!(code->tree[lastnode].branches[0] == -1 - && code->tree[lastnode].branches[1] == -2)) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Prefix found"); - return (ARCHIVE_FATAL); - } - - /* Set leaf value */ - code->tree[lastnode].branches[0] = value; - code->tree[lastnode].branches[1] = value; - - return (ARCHIVE_OK); -} - -static int -new_node(struct huffman_code *code) -{ - void *new_tree; - if (code->numallocatedentries == code->numentries) { - int new_num_entries = 256; - if (code->numentries > 0) { - new_num_entries = code->numentries * 2; - } - new_tree = realloc(code->tree, new_num_entries * sizeof(*code->tree)); - if (new_tree == NULL) - return (-1); - code->tree = (struct huffman_tree_node *)new_tree; - code->numallocatedentries = new_num_entries; - } - code->tree[code->numentries].branches[0] = -1; - code->tree[code->numentries].branches[1] = -2; - return 1; -} - -static int -make_table(struct archive_read *a, struct huffman_code *code) -{ - if (code->maxlength < code->minlength || code->maxlength > 10) - code->tablesize = 10; - else - code->tablesize = code->maxlength; - - code->table = - (struct huffman_table_entry *)calloc(1, sizeof(*code->table) - * ((size_t)1 << code->tablesize)); - - return make_table_recurse(a, code, 0, code->table, 0, code->tablesize); -} - -static int -make_table_recurse(struct archive_read *a, struct huffman_code *code, int node, - struct huffman_table_entry *table, int depth, - int maxdepth) -{ - int currtablesize, i, ret = (ARCHIVE_OK); - - if (!code->tree) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Huffman tree was not created."); - return (ARCHIVE_FATAL); - } - if (node < 0 || node >= code->numentries) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid location to Huffman tree specified."); - return (ARCHIVE_FATAL); - } - - currtablesize = 1 << (maxdepth - depth); - - if (code->tree[node].branches[0] == - code->tree[node].branches[1]) - { - for(i = 0; i < currtablesize; i++) - { - table[i].length = depth; - table[i].value = code->tree[node].branches[0]; - } - } - /* - * Dead code, node >= 0 - * - else if (node < 0) - { - for(i = 0; i < currtablesize; i++) - table[i].length = -1; - } - */ - else - { - if(depth == maxdepth) - { - table[0].length = maxdepth + 1; - table[0].value = node; - } - else - { - ret |= make_table_recurse(a, code, code->tree[node].branches[0], table, - depth + 1, maxdepth); - ret |= make_table_recurse(a, code, code->tree[node].branches[1], - table + currtablesize / 2, depth + 1, maxdepth); - } - } - return ret; -} - -static int -expand(struct archive_read *a, int64_t *end) -{ - static const unsigned char lengthbases[] = - { 0, 1, 2, 3, 4, 5, 6, - 7, 8, 10, 12, 14, 16, 20, - 24, 28, 32, 40, 48, 56, 64, - 80, 96, 112, 128, 160, 192, 224 }; - static const unsigned char lengthbits[] = - { 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 1, 1, 2, 2, - 2, 2, 3, 3, 3, 3, 4, - 4, 4, 4, 5, 5, 5, 5 }; - static const int lengthb_min = minimum( - (int)(sizeof(lengthbases)/sizeof(lengthbases[0])), - (int)(sizeof(lengthbits)/sizeof(lengthbits[0])) - ); - static const unsigned int offsetbases[] = - { 0, 1, 2, 3, 4, 6, - 8, 12, 16, 24, 32, 48, - 64, 96, 128, 192, 256, 384, - 512, 768, 1024, 1536, 2048, 3072, - 4096, 6144, 8192, 12288, 16384, 24576, - 32768, 49152, 65536, 98304, 131072, 196608, - 262144, 327680, 393216, 458752, 524288, 589824, - 655360, 720896, 786432, 851968, 917504, 983040, - 1048576, 1310720, 1572864, 1835008, 2097152, 2359296, - 2621440, 2883584, 3145728, 3407872, 3670016, 3932160 }; - static const unsigned char offsetbits[] = - { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, - 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, - 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18 }; - static const int offsetb_min = minimum( - (int)(sizeof(offsetbases)/sizeof(offsetbases[0])), - (int)(sizeof(offsetbits)/sizeof(offsetbits[0])) - ); - static const unsigned char shortbases[] = - { 0, 4, 8, 16, 32, 64, 128, 192 }; - static const unsigned char shortbits[] = - { 2, 2, 3, 4, 5, 6, 6, 6 }; - - int symbol, offs, len, offsindex, lensymbol, i, offssymbol, lowoffsetsymbol; - unsigned char newfile; - struct rar *rar = (struct rar *)(a->format->data); - struct rar_br *br = &(rar->br); - - if (rar->filters.filterstart < *end) - *end = rar->filters.filterstart; - - while (1) - { - if(lzss_position(&rar->lzss) >= *end) { - return (ARCHIVE_OK); - } - - if(rar->is_ppmd_block) { - *end = lzss_position(&rar->lzss); - return (ARCHIVE_OK); - } - - if ((symbol = read_next_symbol(a, &rar->maincode)) < 0) - return (ARCHIVE_FATAL); - - if (symbol < 256) - { - lzss_emit_literal(rar, symbol); - continue; - } - else if (symbol == 256) - { - if (!rar_br_read_ahead(a, br, 1)) - goto truncated_data; - newfile = !rar_br_bits(br, 1); - rar_br_consume(br, 1); - - if(newfile) - { - rar->start_new_block = 1; - if (!rar_br_read_ahead(a, br, 1)) - goto truncated_data; - rar->start_new_table = rar_br_bits(br, 1); - rar_br_consume(br, 1); - *end = lzss_position(&rar->lzss); - return (ARCHIVE_OK); - } - else - { - if (parse_codes(a) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - continue; - } - } - else if(symbol==257) - { - if (!read_filter(a, end)) - return (ARCHIVE_FATAL); - continue; - } - else if(symbol==258) - { - if(rar->lastlength == 0) - continue; - - offs = rar->lastoffset; - len = rar->lastlength; - } - else if (symbol <= 262) - { - offsindex = symbol - 259; - offs = rar->oldoffset[offsindex]; - - if ((lensymbol = read_next_symbol(a, &rar->lengthcode)) < 0) - goto bad_data; - if (lensymbol > lengthb_min) - goto bad_data; - len = lengthbases[lensymbol] + 2; - if (lengthbits[lensymbol] > 0) { - if (!rar_br_read_ahead(a, br, lengthbits[lensymbol])) - goto truncated_data; - len += rar_br_bits(br, lengthbits[lensymbol]); - rar_br_consume(br, lengthbits[lensymbol]); - } - - for (i = offsindex; i > 0; i--) - rar->oldoffset[i] = rar->oldoffset[i-1]; - rar->oldoffset[0] = offs; - } - else if(symbol<=270) - { - offs = shortbases[symbol-263] + 1; - if(shortbits[symbol-263] > 0) { - if (!rar_br_read_ahead(a, br, shortbits[symbol-263])) - goto truncated_data; - offs += rar_br_bits(br, shortbits[symbol-263]); - rar_br_consume(br, shortbits[symbol-263]); - } - - len = 2; - - for(i = 3; i > 0; i--) - rar->oldoffset[i] = rar->oldoffset[i-1]; - rar->oldoffset[0] = offs; - } - else - { - if (symbol-271 > lengthb_min) - goto bad_data; - len = lengthbases[symbol-271]+3; - if(lengthbits[symbol-271] > 0) { - if (!rar_br_read_ahead(a, br, lengthbits[symbol-271])) - goto truncated_data; - len += rar_br_bits(br, lengthbits[symbol-271]); - rar_br_consume(br, lengthbits[symbol-271]); - } - - if ((offssymbol = read_next_symbol(a, &rar->offsetcode)) < 0) - goto bad_data; - if (offssymbol > offsetb_min) - goto bad_data; - offs = offsetbases[offssymbol]+1; - if(offsetbits[offssymbol] > 0) - { - if(offssymbol > 9) - { - if(offsetbits[offssymbol] > 4) { - if (!rar_br_read_ahead(a, br, offsetbits[offssymbol] - 4)) - goto truncated_data; - offs += rar_br_bits(br, offsetbits[offssymbol] - 4) << 4; - rar_br_consume(br, offsetbits[offssymbol] - 4); - } - - if(rar->numlowoffsetrepeats > 0) - { - rar->numlowoffsetrepeats--; - offs += rar->lastlowoffset; - } - else - { - if ((lowoffsetsymbol = - read_next_symbol(a, &rar->lowoffsetcode)) < 0) - return (ARCHIVE_FATAL); - if(lowoffsetsymbol == 16) - { - rar->numlowoffsetrepeats = 15; - offs += rar->lastlowoffset; - } - else - { - offs += lowoffsetsymbol; - rar->lastlowoffset = lowoffsetsymbol; - } - } - } - else { - if (!rar_br_read_ahead(a, br, offsetbits[offssymbol])) - goto truncated_data; - offs += rar_br_bits(br, offsetbits[offssymbol]); - rar_br_consume(br, offsetbits[offssymbol]); - } - } - - if (offs >= 0x40000) - len++; - if (offs >= 0x2000) - len++; - - for(i = 3; i > 0; i--) - rar->oldoffset[i] = rar->oldoffset[i-1]; - rar->oldoffset[0] = offs; - } - - rar->lastoffset = offs; - rar->lastlength = len; - - lzss_emit_match(rar, rar->lastoffset, rar->lastlength); - } -truncated_data: - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated RAR file data"); - rar->valid = 0; - return (ARCHIVE_FATAL); -bad_data: - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Bad RAR file data"); - return (ARCHIVE_FATAL); -} - -static int -copy_from_lzss_window(struct archive_read *a, void *buffer, - int64_t startpos, int length) -{ - int windowoffs, firstpart; - struct rar *rar = (struct rar *)(a->format->data); - - windowoffs = lzss_offset_for_position(&rar->lzss, startpos); - firstpart = lzss_size(&rar->lzss) - windowoffs; - if (firstpart < 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Bad RAR file data"); - return (ARCHIVE_FATAL); - } - if (firstpart < length) { - memcpy(buffer, &rar->lzss.window[windowoffs], firstpart); - memcpy(buffer, &rar->lzss.window[0], length - firstpart); - } else { - memcpy(buffer, &rar->lzss.window[windowoffs], length); - } - return (ARCHIVE_OK); -} - -static int -copy_from_lzss_window_to_unp(struct archive_read *a, const void **buffer, - int64_t startpos, int length) -{ - int windowoffs, firstpart; - struct rar *rar = (struct rar *)(a->format->data); - - if (!rar->unp_buffer) - { - if ((rar->unp_buffer = malloc(rar->unp_buffer_size)) == NULL) - { - archive_set_error(&a->archive, ENOMEM, - "Unable to allocate memory for uncompressed data."); - return (ARCHIVE_FATAL); - } - } - - windowoffs = lzss_offset_for_position(&rar->lzss, startpos); - if(windowoffs + length <= lzss_size(&rar->lzss)) { - memcpy(&rar->unp_buffer[rar->unp_offset], &rar->lzss.window[windowoffs], - length); - } else if (length <= lzss_size(&rar->lzss)) { - firstpart = lzss_size(&rar->lzss) - windowoffs; - if (firstpart < 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Bad RAR file data"); - return (ARCHIVE_FATAL); - } - if (firstpart < length) { - memcpy(&rar->unp_buffer[rar->unp_offset], - &rar->lzss.window[windowoffs], firstpart); - memcpy(&rar->unp_buffer[rar->unp_offset + firstpart], - &rar->lzss.window[0], length - firstpart); - } else { - memcpy(&rar->unp_buffer[rar->unp_offset], - &rar->lzss.window[windowoffs], length); - } - } else { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Bad RAR file data"); - return (ARCHIVE_FATAL); - } - rar->unp_offset += length; - if (rar->unp_offset >= rar->unp_buffer_size) - *buffer = rar->unp_buffer; - else - *buffer = NULL; - return (ARCHIVE_OK); -} - -static const void * -rar_read_ahead(struct archive_read *a, size_t min, ssize_t *avail) -{ - struct rar *rar = (struct rar *)(a->format->data); - const void *h = __archive_read_ahead(a, min, avail); - int ret; - if (avail) - { - if (a->archive.read_data_is_posix_read && *avail > (ssize_t)a->archive.read_data_requested) - *avail = a->archive.read_data_requested; - if (*avail > rar->bytes_remaining) - *avail = (ssize_t)rar->bytes_remaining; - if (*avail < 0) - return NULL; - else if (*avail == 0 && rar->main_flags & MHD_VOLUME && - rar->file_flags & FHD_SPLIT_AFTER) - { - rar->filename_must_match = 1; - ret = archive_read_format_rar_read_header(a, a->entry); - if (ret == (ARCHIVE_EOF)) - { - rar->has_endarc_header = 1; - ret = archive_read_format_rar_read_header(a, a->entry); - } - rar->filename_must_match = 0; - if (ret != (ARCHIVE_OK)) - return NULL; - return rar_read_ahead(a, min, avail); - } - } - return h; -} - -static int -parse_filter(struct archive_read *a, const uint8_t *bytes, uint16_t length, uint8_t flags) -{ - struct rar *rar = (struct rar *)(a->format->data); - struct rar_filters *filters = &rar->filters; - - struct memory_bit_reader br = { 0 }; - struct rar_program_code *prog; - struct rar_filter *filter, **nextfilter; - - uint32_t numprogs, num, blocklength, globaldatalen; - uint8_t *globaldata; - size_t blockstartpos; - uint32_t registers[8] = { 0 }; - uint32_t i; - - br.bytes = bytes; - br.length = length; - - numprogs = 0; - for (prog = filters->progs; prog; prog = prog->next) - numprogs++; - - if ((flags & 0x80)) - { - num = membr_next_rarvm_number(&br); - if (num == 0) - { - delete_filter(filters->stack); - filters->stack = NULL; - delete_program_code(filters->progs); - filters->progs = NULL; - } - else - num--; - if (num > numprogs) { - return 0; - } - filters->lastfilternum = num; - } - else - num = filters->lastfilternum; - - prog = filters->progs; - for (i = 0; i < num; i++) - prog = prog->next; - if (prog) - prog->usagecount++; - - blockstartpos = membr_next_rarvm_number(&br) + (size_t)lzss_position(&rar->lzss); - if ((flags & 0x40)) - blockstartpos += 258; - if ((flags & 0x20)) - blocklength = membr_next_rarvm_number(&br); - else - blocklength = prog ? prog->oldfilterlength : 0; - - registers[3] = PROGRAM_SYSTEM_GLOBAL_ADDRESS; - registers[4] = blocklength; - registers[5] = prog ? prog->usagecount : 0; - registers[7] = VM_MEMORY_SIZE; - - if ((flags & 0x10)) - { - uint8_t mask = (uint8_t)membr_bits(&br, 7); - for (i = 0; i < 7; i++) - if ((mask & (1 << i))) - registers[i] = membr_next_rarvm_number(&br); - } - - if (!prog) - { - uint32_t len = membr_next_rarvm_number(&br); - uint8_t *bytecode; - struct rar_program_code **next; - - if (len == 0 || len > 0x10000) - return 0; - bytecode = malloc(len); - if (!bytecode) - return 0; - for (i = 0; i < len; i++) - bytecode[i] = (uint8_t)membr_bits(&br, 8); - prog = compile_program(bytecode, len); - if (!prog) { - free(bytecode); - return 0; - } - free(bytecode); - next = &filters->progs; - while (*next) - next = &(*next)->next; - *next = prog; - } - prog->oldfilterlength = blocklength; - - globaldata = NULL; - globaldatalen = 0; - if ((flags & 0x08)) - { - globaldatalen = membr_next_rarvm_number(&br); - if (globaldatalen > PROGRAM_USER_GLOBAL_SIZE) - return 0; - globaldata = malloc(globaldatalen + PROGRAM_SYSTEM_GLOBAL_SIZE); - if (!globaldata) - return 0; - for (i = 0; i < globaldatalen; i++) - globaldata[i + PROGRAM_SYSTEM_GLOBAL_SIZE] = (uint8_t)membr_bits(&br, 8); - } - - if (br.at_eof) - { - free(globaldata); - return 0; - } - - filter = create_filter(prog, globaldata, globaldatalen, registers, blockstartpos, blocklength); - free(globaldata); - if (!filter) - return 0; - - for (i = 0; i < 7; i++) - archive_le32enc(&filter->globaldata[i * 4], registers[i]); - archive_le32enc(&filter->globaldata[0x1C], blocklength); - archive_le32enc(&filter->globaldata[0x20], 0); - archive_le32enc(&filter->globaldata[0x2C], prog->usagecount); - - nextfilter = &filters->stack; - while (*nextfilter) - nextfilter = &(*nextfilter)->next; - *nextfilter = filter; - - if (!filters->stack->next) - filters->filterstart = blockstartpos; - - return 1; -} - -static struct rar_filter * -create_filter(struct rar_program_code *prog, const uint8_t *globaldata, uint32_t globaldatalen, uint32_t registers[8], size_t startpos, uint32_t length) -{ - struct rar_filter *filter; - - filter = calloc(1, sizeof(*filter)); - if (!filter) - return NULL; - filter->prog = prog; - filter->globaldatalen = globaldatalen > PROGRAM_SYSTEM_GLOBAL_SIZE ? globaldatalen : PROGRAM_SYSTEM_GLOBAL_SIZE; - filter->globaldata = calloc(1, filter->globaldatalen); - if (!filter->globaldata) - return NULL; - if (globaldata) - memcpy(filter->globaldata, globaldata, globaldatalen); - if (registers) - memcpy(filter->initialregisters, registers, sizeof(filter->initialregisters)); - filter->blockstartpos = startpos; - filter->blocklength = length; - - return filter; -} - -static int -run_filters(struct archive_read *a) -{ - struct rar *rar = (struct rar *)(a->format->data); - struct rar_filters *filters = &rar->filters; - struct rar_filter *filter = filters->stack; - struct rar_filter *f; - size_t start, end; - int64_t tend; - uint32_t lastfilteraddress; - uint32_t lastfilterlength; - int ret; - - if (filters == NULL || filter == NULL) - return (0); - - start = filters->filterstart; - end = start + filter->blocklength; - - filters->filterstart = INT64_MAX; - tend = (int64_t)end; - ret = expand(a, &tend); - if (ret != ARCHIVE_OK) - return 0; - - /* Check if filter stack was modified in expand() */ - ret = ARCHIVE_FATAL; - f = filters->stack; - while (f) - { - if (f == filter) - { - ret = ARCHIVE_OK; - break; - } - f = f->next; - } - if (ret != ARCHIVE_OK) - return 0; - - if (tend < 0) - return 0; - end = (size_t)tend; - if (end != start + filter->blocklength) - return 0; - - if (!filters->vm) - { - filters->vm = calloc(1, sizeof(*filters->vm)); - if (!filters->vm) - return 0; - } - - ret = copy_from_lzss_window(a, filters->vm->memory, start, filter->blocklength); - if (ret != ARCHIVE_OK) - return 0; - if (!execute_filter(a, filter, filters->vm, rar->offset)) - return 0; - - lastfilteraddress = filter->filteredblockaddress; - lastfilterlength = filter->filteredblocklength; - filters->stack = filter->next; - filter->next = NULL; - delete_filter(filter); - - while ((filter = filters->stack) != NULL && (int64_t)filter->blockstartpos == filters->filterstart && filter->blocklength == lastfilterlength) - { - memmove(&filters->vm->memory[0], &filters->vm->memory[lastfilteraddress], lastfilterlength); - if (!execute_filter(a, filter, filters->vm, rar->offset)) - return 0; - - lastfilteraddress = filter->filteredblockaddress; - lastfilterlength = filter->filteredblocklength; - filters->stack = filter->next; - filter->next = NULL; - delete_filter(filter); - } - - if (filters->stack) - { - if (filters->stack->blockstartpos < end) - return 0; - filters->filterstart = filters->stack->blockstartpos; - } - - filters->lastend = end; - filters->bytes = &filters->vm->memory[lastfilteraddress]; - filters->bytes_ready = lastfilterlength; - - return 1; -} - -static struct rar_program_code * -compile_program(const uint8_t *bytes, size_t length) -{ - struct memory_bit_reader br = { 0 }; - struct rar_program_code *prog; - // uint32_t instrcount = 0; - uint8_t xor; - size_t i; - - xor = 0; - for (i = 1; i < length; i++) - xor ^= bytes[i]; - if (!length || xor != bytes[0]) - return NULL; - - br.bytes = bytes; - br.length = length; - br.offset = 1; - - prog = calloc(1, sizeof(*prog)); - if (!prog) - return NULL; - prog->fingerprint = crc32(0, bytes, (unsigned int)length) | ((uint64_t)length << 32); - - if (membr_bits(&br, 1)) - { - prog->staticdatalen = membr_next_rarvm_number(&br) + 1; - prog->staticdata = malloc(prog->staticdatalen); - if (!prog->staticdata) - { - delete_program_code(prog); - return NULL; - } - for (i = 0; i < prog->staticdatalen; i++) - prog->staticdata[i] = (uint8_t)membr_bits(&br, 8); - } - - return prog; -} - -static void -delete_filter(struct rar_filter *filter) -{ - while (filter) - { - struct rar_filter *next = filter->next; - free(filter->globaldata); - free(filter); - filter = next; - } -} - -static void -clear_filters(struct rar_filters *filters) -{ - delete_filter(filters->stack); - delete_program_code(filters->progs); - free(filters->vm); -} - -static void -delete_program_code(struct rar_program_code *prog) -{ - while (prog) - { - struct rar_program_code *next = prog->next; - free(prog->staticdata); - free(prog->globalbackup); - free(prog); - prog = next; - } -} - -static uint32_t -membr_next_rarvm_number(struct memory_bit_reader *br) -{ - uint32_t val; - switch (membr_bits(br, 2)) - { - case 0: - return membr_bits(br, 4); - case 1: - val = membr_bits(br, 8); - if (val >= 16) - return val; - return 0xFFFFFF00 | (val << 4) | membr_bits(br, 4); - case 2: - return membr_bits(br, 16); - default: - return membr_bits(br, 32); - } -} - -static inline uint32_t -membr_bits(struct memory_bit_reader *br, int bits) -{ - if (bits > br->available && (br->at_eof || !membr_fill(br, bits))) - return 0; - return (uint32_t)((br->bits >> (br->available -= bits)) & (((uint64_t)1 << bits) - 1)); -} - -static int -membr_fill(struct memory_bit_reader *br, int bits) -{ - while (br->available < bits && br->offset < br->length) - { - br->bits = (br->bits << 8) | br->bytes[br->offset++]; - br->available += 8; - } - if (bits > br->available) - { - br->at_eof = 1; - return 0; - } - return 1; -} - -static int -read_filter(struct archive_read *a, int64_t *end) -{ - struct rar *rar = (struct rar *)(a->format->data); - uint8_t flags, val, *code; - uint16_t length, i; - - if (!rar_decode_byte(a, &flags)) - return 0; - length = (flags & 0x07) + 1; - if (length == 7) - { - if (!rar_decode_byte(a, &val)) - return 0; - length = val + 7; - } - else if (length == 8) - { - if (!rar_decode_byte(a, &val)) - return 0; - length = val << 8; - if (!rar_decode_byte(a, &val)) - return 0; - length |= val; - } - - code = malloc(length); - if (!code) - return 0; - for (i = 0; i < length; i++) - { - if (!rar_decode_byte(a, &code[i])) - { - free(code); - return 0; - } - } - if (!parse_filter(a, code, length, flags)) - { - free(code); - return 0; - } - free(code); - - if (rar->filters.filterstart < *end) - *end = rar->filters.filterstart; - - return 1; -} - -static int -execute_filter_delta(struct rar_filter *filter, struct rar_virtual_machine *vm) -{ - uint32_t length = filter->initialregisters[4]; - uint32_t numchannels = filter->initialregisters[0]; - uint8_t *src, *dst; - uint32_t i, idx; - - if (length > PROGRAM_WORK_SIZE / 2) - return 0; - - src = &vm->memory[0]; - dst = &vm->memory[length]; - for (i = 0; i < numchannels; i++) - { - uint8_t lastbyte = 0; - for (idx = i; idx < length; idx += numchannels) - lastbyte = dst[idx] = lastbyte - *src++; - } - - filter->filteredblockaddress = length; - filter->filteredblocklength = length; - - return 1; -} - -static int -execute_filter_e8(struct rar_filter *filter, struct rar_virtual_machine *vm, size_t pos, int e9also) -{ - uint32_t length = filter->initialregisters[4]; - uint32_t filesize = 0x1000000; - uint32_t i; - - if (length > PROGRAM_WORK_SIZE || length < 4) - return 0; - - for (i = 0; i <= length - 5; i++) - { - if (vm->memory[i] == 0xE8 || (e9also && vm->memory[i] == 0xE9)) - { - uint32_t currpos = (uint32_t)pos + i + 1; - int32_t address = (int32_t)vm_read_32(vm, i + 1); - if (address < 0 && currpos >= (uint32_t)-address) - vm_write_32(vm, i + 1, address + filesize); - else if (address >= 0 && (uint32_t)address < filesize) - vm_write_32(vm, i + 1, address - currpos); - i += 4; - } - } - - filter->filteredblockaddress = 0; - filter->filteredblocklength = length; - - return 1; -} - -static int -execute_filter_rgb(struct rar_filter *filter, struct rar_virtual_machine *vm) -{ - uint32_t stride = filter->initialregisters[0]; - uint32_t byteoffset = filter->initialregisters[1]; - uint32_t blocklength = filter->initialregisters[4]; - uint8_t *src, *dst; - uint32_t i, j; - - if (blocklength > PROGRAM_WORK_SIZE / 2 || stride > blocklength) - return 0; - - src = &vm->memory[0]; - dst = &vm->memory[blocklength]; - for (i = 0; i < 3; i++) { - uint8_t byte = 0; - uint8_t *prev = dst + i - stride; - for (j = i; j < blocklength; j += 3) - { - if (prev >= dst) - { - uint32_t delta1 = abs(prev[3] - prev[0]); - uint32_t delta2 = abs(byte - prev[0]); - uint32_t delta3 = abs(prev[3] - prev[0] + byte - prev[0]); - if (delta1 > delta2 || delta1 > delta3) - byte = delta2 <= delta3 ? prev[3] : prev[0]; - } - byte -= *src++; - dst[j] = byte; - prev += 3; - } - } - for (i = byteoffset; i < blocklength - 2; i += 3) - { - dst[i] += dst[i + 1]; - dst[i + 2] += dst[i + 1]; - } - - filter->filteredblockaddress = blocklength; - filter->filteredblocklength = blocklength; - - return 1; -} - -static int -execute_filter_audio(struct rar_filter *filter, struct rar_virtual_machine *vm) -{ - uint32_t length = filter->initialregisters[4]; - uint32_t numchannels = filter->initialregisters[0]; - uint8_t *src, *dst; - uint32_t i, j; - - if (length > PROGRAM_WORK_SIZE / 2) - return 0; - - src = &vm->memory[0]; - dst = &vm->memory[length]; - for (i = 0; i < numchannels; i++) - { - struct audio_state state; - memset(&state, 0, sizeof(state)); - for (j = i; j < length; j += numchannels) - { - int8_t delta = (int8_t)*src++; - uint8_t predbyte, byte; - int prederror; - state.delta[2] = state.delta[1]; - state.delta[1] = state.lastdelta - state.delta[0]; - state.delta[0] = state.lastdelta; - predbyte = ((8 * state.lastbyte + state.weight[0] * state.delta[0] + state.weight[1] * state.delta[1] + state.weight[2] * state.delta[2]) >> 3) & 0xFF; - byte = (predbyte - delta) & 0xFF; - prederror = delta << 3; - state.error[0] += abs(prederror); - state.error[1] += abs(prederror - state.delta[0]); state.error[2] += abs(prederror + state.delta[0]); - state.error[3] += abs(prederror - state.delta[1]); state.error[4] += abs(prederror + state.delta[1]); - state.error[5] += abs(prederror - state.delta[2]); state.error[6] += abs(prederror + state.delta[2]); - state.lastdelta = (int8_t)(byte - state.lastbyte); - dst[j] = state.lastbyte = byte; - if (!(state.count++ & 0x1F)) - { - uint8_t k, idx = 0; - for (k = 1; k < 7; k++) - { - if (state.error[k] < state.error[idx]) - idx = k; - } - memset(state.error, 0, sizeof(state.error)); - switch (idx) - { - case 1: if (state.weight[0] >= -16) state.weight[0]--; break; - case 2: if (state.weight[0] < 16) state.weight[0]++; break; - case 3: if (state.weight[1] >= -16) state.weight[1]--; break; - case 4: if (state.weight[1] < 16) state.weight[1]++; break; - case 5: if (state.weight[2] >= -16) state.weight[2]--; break; - case 6: if (state.weight[2] < 16) state.weight[2]++; break; - } - } - } - } - - filter->filteredblockaddress = length; - filter->filteredblocklength = length; - - return 1; -} - - -static int -execute_filter(struct archive_read *a, struct rar_filter *filter, struct rar_virtual_machine *vm, size_t pos) -{ - if (filter->prog->fingerprint == 0x1D0E06077D) - return execute_filter_delta(filter, vm); - if (filter->prog->fingerprint == 0x35AD576887) - return execute_filter_e8(filter, vm, pos, 0); - if (filter->prog->fingerprint == 0x393CD7E57E) - return execute_filter_e8(filter, vm, pos, 1); - if (filter->prog->fingerprint == 0x951C2C5DC8) - return execute_filter_rgb(filter, vm); - if (filter->prog->fingerprint == 0xD8BC85E701) - return execute_filter_audio(filter, vm); - - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "No support for RAR VM program filter"); - return 0; -} - -static int -rar_decode_byte(struct archive_read *a, uint8_t *byte) -{ - struct rar *rar = (struct rar *)(a->format->data); - struct rar_br *br = &(rar->br); - if (!rar_br_read_ahead(a, br, 8)) - return 0; - *byte = (uint8_t)rar_br_bits(br, 8); - rar_br_consume(br, 8); - return 1; -} - -static inline void -vm_write_32(struct rar_virtual_machine* vm, size_t offset, uint32_t u32) -{ - archive_le32enc(vm->memory + offset, u32); -} - -static inline uint32_t -vm_read_32(struct rar_virtual_machine* vm, size_t offset) -{ - return archive_le32dec(vm->memory + offset); -} diff --git a/thirdparty/libarchive/libarchive/archive_read_support_format_rar5.c b/thirdparty/libarchive/libarchive/archive_read_support_format_rar5.c deleted file mode 100644 index 1f9099439..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_format_rar5.c +++ /dev/null @@ -1,4251 +0,0 @@ -/*- -* Copyright (c) 2018 Grzegorz Antoniak (http://antoniak.org) -* 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. -* 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. -* -* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. -*/ - -#include "archive_platform.h" -#include "archive_endian.h" - -#ifdef HAVE_ERRNO_H -#include -#endif -#include -#ifdef HAVE_ZLIB_H -#include /* crc32 */ -#endif -#ifdef HAVE_LIMITS_H -#include -#endif - -#include "archive.h" -#ifndef HAVE_ZLIB_H -#include "archive_crc32.h" -#endif - -#include "archive_entry.h" -#include "archive_entry_locale.h" -#include "archive_ppmd7_private.h" -#include "archive_entry_private.h" - -#ifdef HAVE_BLAKE2_H -#include -#else -#include "archive_blake2.h" -#endif - -/*#define CHECK_CRC_ON_SOLID_SKIP*/ -/*#define DONT_FAIL_ON_CRC_ERROR*/ -/*#define DEBUG*/ - -#define rar5_min(a, b) (((a) > (b)) ? (b) : (a)) -#define rar5_max(a, b) (((a) > (b)) ? (a) : (b)) -#define rar5_countof(X) ((const ssize_t) (sizeof(X) / sizeof(*X))) - -#if defined DEBUG -#define DEBUG_CODE if(1) -#define LOG(...) do { printf("rar5: " __VA_ARGS__); puts(""); } while(0) -#else -#define DEBUG_CODE if(0) -#endif - -/* Real RAR5 magic number is: - * - * 0x52, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x01, 0x00 - * "Rar!→•☺·\x00" - * - * Retrieved with `rar5_signature()` by XOR'ing it with 0xA1, because I don't - * want to put this magic sequence in each binary that uses libarchive, so - * applications that scan through the file for this marker won't trigger on - * this "false" one. - * - * The array itself is decrypted in `rar5_init` function. */ - -static unsigned char rar5_signature_xor[] = { 243, 192, 211, 128, 187, 166, 160, 161 }; -static const size_t g_unpack_window_size = 0x20000; - -/* These could have been static const's, but they aren't, because of - * Visual Studio. */ -#define MAX_NAME_IN_CHARS 2048 -#define MAX_NAME_IN_BYTES (4 * MAX_NAME_IN_CHARS) - -struct file_header { - ssize_t bytes_remaining; - ssize_t unpacked_size; - int64_t last_offset; /* Used in sanity checks. */ - int64_t last_size; /* Used in sanity checks. */ - - uint8_t solid : 1; /* Is this a solid stream? */ - uint8_t service : 1; /* Is this file a service data? */ - uint8_t eof : 1; /* Did we finish unpacking the file? */ - uint8_t dir : 1; /* Is this file entry a directory? */ - - /* Optional time fields. */ - uint64_t e_mtime; - uint64_t e_ctime; - uint64_t e_atime; - uint32_t e_unix_ns; - - /* Optional hash fields. */ - uint32_t stored_crc32; - uint32_t calculated_crc32; - uint8_t blake2sp[32]; - blake2sp_state b2state; - char has_blake2; - - /* Optional redir fields */ - uint64_t redir_type; - uint64_t redir_flags; - - ssize_t solid_window_size; /* Used in file format check. */ -}; - -enum EXTRA { - EX_CRYPT = 0x01, - EX_HASH = 0x02, - EX_HTIME = 0x03, - EX_VERSION = 0x04, - EX_REDIR = 0x05, - EX_UOWNER = 0x06, - EX_SUBDATA = 0x07 -}; - -#define REDIR_SYMLINK_IS_DIR 1 - -enum REDIR_TYPE { - REDIR_TYPE_NONE = 0, - REDIR_TYPE_UNIXSYMLINK = 1, - REDIR_TYPE_WINSYMLINK = 2, - REDIR_TYPE_JUNCTION = 3, - REDIR_TYPE_HARDLINK = 4, - REDIR_TYPE_FILECOPY = 5, -}; - -#define OWNER_USER_NAME 0x01 -#define OWNER_GROUP_NAME 0x02 -#define OWNER_USER_UID 0x04 -#define OWNER_GROUP_GID 0x08 -#define OWNER_MAXNAMELEN 256 - -enum FILTER_TYPE { - FILTER_DELTA = 0, /* Generic pattern. */ - FILTER_E8 = 1, /* Intel x86 code. */ - FILTER_E8E9 = 2, /* Intel x86 code. */ - FILTER_ARM = 3, /* ARM code. */ - FILTER_AUDIO = 4, /* Audio filter, not used in RARv5. */ - FILTER_RGB = 5, /* Color palette, not used in RARv5. */ - FILTER_ITANIUM = 6, /* Intel's Itanium, not used in RARv5. */ - FILTER_PPM = 7, /* Predictive pattern matching, not used in - RARv5. */ - FILTER_NONE = 8, -}; - -struct filter_info { - int type; - int channels; - int pos_r; - - int64_t block_start; - ssize_t block_length; - uint16_t width; -}; - -struct data_ready { - char used; - const uint8_t* buf; - size_t size; - int64_t offset; -}; - -struct cdeque { - uint16_t beg_pos; - uint16_t end_pos; - uint16_t cap_mask; - uint16_t size; - size_t* arr; -}; - -struct decode_table { - uint32_t size; - int32_t decode_len[16]; - uint32_t decode_pos[16]; - uint32_t quick_bits; - uint8_t quick_len[1 << 10]; - uint16_t quick_num[1 << 10]; - uint16_t decode_num[306]; -}; - -struct comp_state { - /* Flag used to specify if unpacker needs to reinitialize the - uncompression context. */ - uint8_t initialized : 1; - - /* Flag used when applying filters. */ - uint8_t all_filters_applied : 1; - - /* Flag used to skip file context reinitialization, used when unpacker - is skipping through different multivolume archives. */ - uint8_t switch_multivolume : 1; - - /* Flag used to specify if unpacker has processed the whole data block - or just a part of it. */ - uint8_t block_parsing_finished : 1; - - signed int notused : 4; - - int flags; /* Uncompression flags. */ - int method; /* Uncompression algorithm method. */ - int version; /* Uncompression algorithm version. */ - ssize_t window_size; /* Size of window_buf. */ - uint8_t* window_buf; /* Circular buffer used during - decompression. */ - uint8_t* filtered_buf; /* Buffer used when applying filters. */ - const uint8_t* block_buf; /* Buffer used when merging blocks. */ - size_t window_mask; /* Convenience field; window_size - 1. */ - int64_t write_ptr; /* This amount of data has been unpacked - in the window buffer. */ - int64_t last_write_ptr; /* This amount of data has been stored in - the output file. */ - int64_t last_unstore_ptr; /* Counter of bytes extracted during - unstoring. This is separate from - last_write_ptr because of how SERVICE - base blocks are handled during skipping - in solid multiarchive archives. */ - int64_t solid_offset; /* Additional offset inside the window - buffer, used in unpacking solid - archives. */ - ssize_t cur_block_size; /* Size of current data block. */ - int last_len; /* Flag used in lzss decompression. */ - - /* Decode tables used during lzss uncompression. */ - -#define HUFF_BC 20 - struct decode_table bd; /* huffman bit lengths */ -#define HUFF_NC 306 - struct decode_table ld; /* literals */ -#define HUFF_DC 64 - struct decode_table dd; /* distances */ -#define HUFF_LDC 16 - struct decode_table ldd; /* lower bits of distances */ -#define HUFF_RC 44 - struct decode_table rd; /* repeating distances */ -#define HUFF_TABLE_SIZE (HUFF_NC + HUFF_DC + HUFF_RC + HUFF_LDC) - - /* Circular deque for storing filters. */ - struct cdeque filters; - int64_t last_block_start; /* Used for sanity checking. */ - ssize_t last_block_length; /* Used for sanity checking. */ - - /* Distance cache used during lzss uncompression. */ - int dist_cache[4]; - - /* Data buffer stack. */ - struct data_ready dready[2]; -}; - -/* Bit reader state. */ -struct bit_reader { - int8_t bit_addr; /* Current bit pointer inside current byte. */ - int in_addr; /* Current byte pointer. */ -}; - -/* RARv5 block header structure. Use bf_* functions to get values from - * block_flags_u8 field. I.e. bf_byte_count, etc. */ -struct compressed_block_header { - /* block_flags_u8 contain fields encoded in little-endian bitfield: - * - * - table present flag (shr 7, and 1), - * - last block flag (shr 6, and 1), - * - byte_count (shr 3, and 7), - * - bit_size (shr 0, and 7). - */ - uint8_t block_flags_u8; - uint8_t block_cksum; -}; - -/* RARv5 main header structure. */ -struct main_header { - /* Does the archive contain solid streams? */ - uint8_t solid : 1; - - /* If this a multi-file archive? */ - uint8_t volume : 1; - uint8_t endarc : 1; - uint8_t notused : 5; - - unsigned int vol_no; -}; - -struct generic_header { - uint8_t split_after : 1; - uint8_t split_before : 1; - uint8_t padding : 6; - int size; - int last_header_id; -}; - -struct multivolume { - unsigned int expected_vol_no; - uint8_t* push_buf; -}; - -/* Main context structure. */ -struct rar5 { - int header_initialized; - - /* Set to 1 if current file is positioned AFTER the magic value - * of the archive file. This is used in header reading functions. */ - int skipped_magic; - - /* Set to not zero if we're in skip mode (either by calling - * rar5_data_skip function or when skipping over solid streams). - * Set to 0 when in * extraction mode. This is used during checksum - * calculation functions. */ - int skip_mode; - - /* Set to not zero if we're in block merging mode (i.e. when switching - * to another file in multivolume archive, last block from 1st archive - * needs to be merged with 1st block from 2nd archive). This flag - * guards against recursive use of the merging function, which doesn't - * support recursive calls. */ - int merge_mode; - - /* An offset to QuickOpen list. This is not supported by this unpacker, - * because we're focusing on streaming interface. QuickOpen is designed - * to make things quicker for non-stream interfaces, so it's not our - * use case. */ - uint64_t qlist_offset; - - /* An offset to additional Recovery data. This is not supported by this - * unpacker. Recovery data are additional Reed-Solomon codes that could - * be used to calculate bytes that are missing in archive or are - * corrupted. */ - uint64_t rr_offset; - - /* Various context variables grouped to different structures. */ - struct generic_header generic; - struct main_header main; - struct comp_state cstate; - struct file_header file; - struct bit_reader bits; - struct multivolume vol; - - /* The header of currently processed RARv5 block. Used in main - * decompression logic loop. */ - struct compressed_block_header last_block_hdr; -}; - -/* Forward function declarations. */ - -static void rar5_signature(char *buf); -static int verify_global_checksums(struct archive_read* a); -static int rar5_read_data_skip(struct archive_read *a); -static int push_data_ready(struct archive_read* a, struct rar5* rar, - const uint8_t* buf, size_t size, int64_t offset); - -/* CDE_xxx = Circular Double Ended (Queue) return values. */ -enum CDE_RETURN_VALUES { - CDE_OK, CDE_ALLOC, CDE_PARAM, CDE_OUT_OF_BOUNDS, -}; - -/* Clears the contents of this circular deque. */ -static void cdeque_clear(struct cdeque* d) { - d->size = 0; - d->beg_pos = 0; - d->end_pos = 0; -} - -/* Creates a new circular deque object. Capacity must be power of 2: 8, 16, 32, - * 64, 256, etc. When the user will add another item above current capacity, - * the circular deque will overwrite the oldest entry. */ -static int cdeque_init(struct cdeque* d, int max_capacity_power_of_2) { - if(d == NULL || max_capacity_power_of_2 == 0) - return CDE_PARAM; - - d->cap_mask = max_capacity_power_of_2 - 1; - d->arr = NULL; - - if((max_capacity_power_of_2 & d->cap_mask) != 0) - return CDE_PARAM; - - cdeque_clear(d); - d->arr = malloc(sizeof(void*) * max_capacity_power_of_2); - - return d->arr ? CDE_OK : CDE_ALLOC; -} - -/* Return the current size (not capacity) of circular deque `d`. */ -static size_t cdeque_size(struct cdeque* d) { - return d->size; -} - -/* Returns the first element of current circular deque. Note that this function - * doesn't perform any bounds checking. If you need bounds checking, use - * `cdeque_front()` function instead. */ -static void cdeque_front_fast(struct cdeque* d, void** value) { - *value = (void*) d->arr[d->beg_pos]; -} - -/* Returns the first element of current circular deque. This function - * performs bounds checking. */ -static int cdeque_front(struct cdeque* d, void** value) { - if(d->size > 0) { - cdeque_front_fast(d, value); - return CDE_OK; - } else - return CDE_OUT_OF_BOUNDS; -} - -/* Pushes a new element into the end of this circular deque object. If current - * size will exceed capacity, the oldest element will be overwritten. */ -static int cdeque_push_back(struct cdeque* d, void* item) { - if(d == NULL) - return CDE_PARAM; - - if(d->size == d->cap_mask + 1) - return CDE_OUT_OF_BOUNDS; - - d->arr[d->end_pos] = (size_t) item; - d->end_pos = (d->end_pos + 1) & d->cap_mask; - d->size++; - - return CDE_OK; -} - -/* Pops a front element of this circular deque object and returns its value. - * This function doesn't perform any bounds checking. */ -static void cdeque_pop_front_fast(struct cdeque* d, void** value) { - *value = (void*) d->arr[d->beg_pos]; - d->beg_pos = (d->beg_pos + 1) & d->cap_mask; - d->size--; -} - -/* Pops a front element of this circular deque object and returns its value. - * This function performs bounds checking. */ -static int cdeque_pop_front(struct cdeque* d, void** value) { - if(!d || !value) - return CDE_PARAM; - - if(d->size == 0) - return CDE_OUT_OF_BOUNDS; - - cdeque_pop_front_fast(d, value); - return CDE_OK; -} - -/* Convenience function to cast filter_info** to void **. */ -static void** cdeque_filter_p(struct filter_info** f) { - return (void**) (size_t) f; -} - -/* Convenience function to cast filter_info* to void *. */ -static void* cdeque_filter(struct filter_info* f) { - return (void**) (size_t) f; -} - -/* Destroys this circular deque object. Deallocates the memory of the - * collection buffer, but doesn't deallocate the memory of any pointer passed - * to this deque as a value. */ -static void cdeque_free(struct cdeque* d) { - if(!d) - return; - - if(!d->arr) - return; - - free(d->arr); - - d->arr = NULL; - d->beg_pos = -1; - d->end_pos = -1; - d->cap_mask = 0; -} - -static inline -uint8_t bf_bit_size(const struct compressed_block_header* hdr) { - return hdr->block_flags_u8 & 7; -} - -static inline -uint8_t bf_byte_count(const struct compressed_block_header* hdr) { - return (hdr->block_flags_u8 >> 3) & 7; -} - -static inline -uint8_t bf_is_table_present(const struct compressed_block_header* hdr) { - return (hdr->block_flags_u8 >> 7) & 1; -} - -static inline struct rar5* get_context(struct archive_read* a) { - return (struct rar5*) a->format->data; -} - -/* Convenience functions used by filter implementations. */ -static void circular_memcpy(uint8_t* dst, uint8_t* window, const uint64_t mask, - int64_t start, int64_t end) -{ - if((start & mask) > (end & mask)) { - ssize_t len1 = mask + 1 - (start & mask); - ssize_t len2 = end & mask; - - memcpy(dst, &window[start & mask], len1); - memcpy(dst + len1, window, len2); - } else { - memcpy(dst, &window[start & mask], (size_t) (end - start)); - } -} - -static uint32_t read_filter_data(struct rar5* rar, uint32_t offset) { - uint8_t linear_buf[4]; - circular_memcpy(linear_buf, rar->cstate.window_buf, - rar->cstate.window_mask, offset, offset + 4); - return archive_le32dec(linear_buf); -} - -static void write_filter_data(struct rar5* rar, uint32_t offset, - uint32_t value) -{ - archive_le32enc(&rar->cstate.filtered_buf[offset], value); -} - -/* Allocates a new filter descriptor and adds it to the filter array. */ -static struct filter_info* add_new_filter(struct rar5* rar) { - struct filter_info* f = - (struct filter_info*) calloc(1, sizeof(struct filter_info)); - - if(!f) { - return NULL; - } - - cdeque_push_back(&rar->cstate.filters, cdeque_filter(f)); - return f; -} - -static int run_delta_filter(struct rar5* rar, struct filter_info* flt) { - int i; - ssize_t dest_pos, src_pos = 0; - - for(i = 0; i < flt->channels; i++) { - uint8_t prev_byte = 0; - for(dest_pos = i; - dest_pos < flt->block_length; - dest_pos += flt->channels) - { - uint8_t byte; - - byte = rar->cstate.window_buf[ - (rar->cstate.solid_offset + flt->block_start + - src_pos) & rar->cstate.window_mask]; - - prev_byte -= byte; - rar->cstate.filtered_buf[dest_pos] = prev_byte; - src_pos++; - } - } - - return ARCHIVE_OK; -} - -static int run_e8e9_filter(struct rar5* rar, struct filter_info* flt, - int extended) -{ - const uint32_t file_size = 0x1000000; - ssize_t i; - - circular_memcpy(rar->cstate.filtered_buf, - rar->cstate.window_buf, rar->cstate.window_mask, - rar->cstate.solid_offset + flt->block_start, - rar->cstate.solid_offset + flt->block_start + flt->block_length); - - for(i = 0; i < flt->block_length - 4;) { - uint8_t b = rar->cstate.window_buf[ - (rar->cstate.solid_offset + flt->block_start + - i++) & rar->cstate.window_mask]; - - /* - * 0xE8 = x86's call (function call) - * 0xE9 = x86's jmp (unconditional jump) - */ - if(b == 0xE8 || (extended && b == 0xE9)) { - - uint32_t addr; - uint32_t offset = (i + flt->block_start) % file_size; - - addr = read_filter_data(rar, - (uint32_t)(rar->cstate.solid_offset + - flt->block_start + i) & rar->cstate.window_mask); - - if(addr & 0x80000000) { - if(((addr + offset) & 0x80000000) == 0) { - write_filter_data(rar, (uint32_t)i, - addr + file_size); - } - } else { - if((addr - file_size) & 0x80000000) { - uint32_t naddr = addr - offset; - write_filter_data(rar, (uint32_t)i, - naddr); - } - } - - i += 4; - } - } - - return ARCHIVE_OK; -} - -static int run_arm_filter(struct rar5* rar, struct filter_info* flt) { - ssize_t i = 0; - uint32_t offset; - - circular_memcpy(rar->cstate.filtered_buf, - rar->cstate.window_buf, rar->cstate.window_mask, - rar->cstate.solid_offset + flt->block_start, - rar->cstate.solid_offset + flt->block_start + flt->block_length); - - for(i = 0; i < flt->block_length - 3; i += 4) { - uint8_t* b = &rar->cstate.window_buf[ - (rar->cstate.solid_offset + - flt->block_start + i + 3) & rar->cstate.window_mask]; - - if(*b == 0xEB) { - /* 0xEB = ARM's BL (branch + link) instruction. */ - offset = read_filter_data(rar, - (rar->cstate.solid_offset + flt->block_start + i) & - (uint32_t)rar->cstate.window_mask) & 0x00ffffff; - - offset -= (uint32_t) ((i + flt->block_start) / 4); - offset = (offset & 0x00ffffff) | 0xeb000000; - write_filter_data(rar, (uint32_t)i, offset); - } - } - - return ARCHIVE_OK; -} - -static int run_filter(struct archive_read* a, struct filter_info* flt) { - int ret; - struct rar5* rar = get_context(a); - - free(rar->cstate.filtered_buf); - - rar->cstate.filtered_buf = malloc(flt->block_length); - if(!rar->cstate.filtered_buf) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for filter data."); - return ARCHIVE_FATAL; - } - - switch(flt->type) { - case FILTER_DELTA: - ret = run_delta_filter(rar, flt); - break; - - case FILTER_E8: - /* fallthrough */ - case FILTER_E8E9: - ret = run_e8e9_filter(rar, flt, - flt->type == FILTER_E8E9); - break; - - case FILTER_ARM: - ret = run_arm_filter(rar, flt); - break; - - default: - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Unsupported filter type: 0x%x", flt->type); - return ARCHIVE_FATAL; - } - - if(ret != ARCHIVE_OK) { - /* Filter has failed. */ - return ret; - } - - if(ARCHIVE_OK != push_data_ready(a, rar, rar->cstate.filtered_buf, - flt->block_length, rar->cstate.last_write_ptr)) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, - "Stack overflow when submitting unpacked data"); - - return ARCHIVE_FATAL; - } - - rar->cstate.last_write_ptr += flt->block_length; - return ARCHIVE_OK; -} - -/* The `push_data` function submits the selected data range to the user. - * Next call of `use_data` will use the pointer, size and offset arguments - * that are specified here. These arguments are pushed to the FIFO stack here, - * and popped from the stack by the `use_data` function. */ -static void push_data(struct archive_read* a, struct rar5* rar, - const uint8_t* buf, int64_t idx_begin, int64_t idx_end) -{ - const uint64_t wmask = rar->cstate.window_mask; - const ssize_t solid_write_ptr = (rar->cstate.solid_offset + - rar->cstate.last_write_ptr) & wmask; - - idx_begin += rar->cstate.solid_offset; - idx_end += rar->cstate.solid_offset; - - /* Check if our unpacked data is wrapped inside the window circular - * buffer. If it's not wrapped, it can be copied out by using - * a single memcpy, but when it's wrapped, we need to copy the first - * part with one memcpy, and the second part with another memcpy. */ - - if((idx_begin & wmask) > (idx_end & wmask)) { - /* The data is wrapped (begin offset sis bigger than end - * offset). */ - const ssize_t frag1_size = rar->cstate.window_size - - (idx_begin & wmask); - const ssize_t frag2_size = idx_end & wmask; - - /* Copy the first part of the buffer first. */ - push_data_ready(a, rar, buf + solid_write_ptr, frag1_size, - rar->cstate.last_write_ptr); - - /* Copy the second part of the buffer. */ - push_data_ready(a, rar, buf, frag2_size, - rar->cstate.last_write_ptr + frag1_size); - - rar->cstate.last_write_ptr += frag1_size + frag2_size; - } else { - /* Data is not wrapped, so we can just use one call to copy the - * data. */ - push_data_ready(a, rar, - buf + solid_write_ptr, (idx_end - idx_begin) & wmask, - rar->cstate.last_write_ptr); - - rar->cstate.last_write_ptr += idx_end - idx_begin; - } -} - -/* Convenience function that submits the data to the user. It uses the - * unpack window buffer as a source location. */ -static void push_window_data(struct archive_read* a, struct rar5* rar, - int64_t idx_begin, int64_t idx_end) -{ - push_data(a, rar, rar->cstate.window_buf, idx_begin, idx_end); -} - -static int apply_filters(struct archive_read* a) { - struct filter_info* flt; - struct rar5* rar = get_context(a); - int ret; - - rar->cstate.all_filters_applied = 0; - - /* Get the first filter that can be applied to our data. The data - * needs to be fully unpacked before the filter can be run. */ - if(CDE_OK == cdeque_front(&rar->cstate.filters, - cdeque_filter_p(&flt))) { - /* Check if our unpacked data fully covers this filter's - * range. */ - if(rar->cstate.write_ptr > flt->block_start && - rar->cstate.write_ptr >= flt->block_start + - flt->block_length) { - /* Check if we have some data pending to be written - * right before the filter's start offset. */ - if(rar->cstate.last_write_ptr == flt->block_start) { - /* Run the filter specified by descriptor - * `flt`. */ - ret = run_filter(a, flt); - if(ret != ARCHIVE_OK) { - /* Filter failure, return error. */ - return ret; - } - - /* Filter descriptor won't be needed anymore - * after it's used, * so remove it from the - * filter list and free its memory. */ - (void) cdeque_pop_front(&rar->cstate.filters, - cdeque_filter_p(&flt)); - - free(flt); - } else { - /* We can't run filters yet, dump the memory - * right before the filter. */ - push_window_data(a, rar, - rar->cstate.last_write_ptr, - flt->block_start); - } - - /* Return 'filter applied or not needed' state to the - * caller. */ - return ARCHIVE_RETRY; - } - } - - rar->cstate.all_filters_applied = 1; - return ARCHIVE_OK; -} - -static void dist_cache_push(struct rar5* rar, int value) { - int* q = rar->cstate.dist_cache; - - q[3] = q[2]; - q[2] = q[1]; - q[1] = q[0]; - q[0] = value; -} - -static int dist_cache_touch(struct rar5* rar, int idx) { - int* q = rar->cstate.dist_cache; - int i, dist = q[idx]; - - for(i = idx; i > 0; i--) - q[i] = q[i - 1]; - - q[0] = dist; - return dist; -} - -static void free_filters(struct rar5* rar) { - struct cdeque* d = &rar->cstate.filters; - - /* Free any remaining filters. All filters should be naturally - * consumed by the unpacking function, so remaining filters after - * unpacking normally mean that unpacking wasn't successful. - * But still of course we shouldn't leak memory in such case. */ - - /* cdeque_size() is a fast operation, so we can use it as a loop - * expression. */ - while(cdeque_size(d) > 0) { - struct filter_info* f = NULL; - - /* Pop_front will also decrease the collection's size. */ - if (CDE_OK == cdeque_pop_front(d, cdeque_filter_p(&f))) - free(f); - } - - cdeque_clear(d); - - /* Also clear out the variables needed for sanity checking. */ - rar->cstate.last_block_start = 0; - rar->cstate.last_block_length = 0; -} - -static void reset_file_context(struct rar5* rar) { - memset(&rar->file, 0, sizeof(rar->file)); - blake2sp_init(&rar->file.b2state, 32); - - if(rar->main.solid) { - rar->cstate.solid_offset += rar->cstate.write_ptr; - } else { - rar->cstate.solid_offset = 0; - } - - rar->cstate.write_ptr = 0; - rar->cstate.last_write_ptr = 0; - rar->cstate.last_unstore_ptr = 0; - - rar->file.redir_type = REDIR_TYPE_NONE; - rar->file.redir_flags = 0; - - free_filters(rar); -} - -static inline int get_archive_read(struct archive* a, - struct archive_read** ar) -{ - *ar = (struct archive_read*) a; - archive_check_magic(a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, - "archive_read_support_format_rar5"); - - return ARCHIVE_OK; -} - -static int read_ahead(struct archive_read* a, size_t how_many, - const uint8_t** ptr) -{ - ssize_t avail = -1; - if(!ptr) - return 0; - - *ptr = __archive_read_ahead(a, how_many, &avail); - if(*ptr == NULL) { - return 0; - } - - return 1; -} - -static int consume(struct archive_read* a, int64_t how_many) { - int ret; - - ret = how_many == __archive_read_consume(a, how_many) - ? ARCHIVE_OK - : ARCHIVE_FATAL; - - return ret; -} - -/** - * Read a RAR5 variable sized numeric value. This value will be stored in - * `pvalue`. The `pvalue_len` argument points to a variable that will receive - * the byte count that was consumed in order to decode the `pvalue` value, plus - * one. - * - * pvalue_len is optional and can be NULL. - * - * NOTE: if `pvalue_len` is NOT NULL, the caller needs to manually consume - * the number of bytes that `pvalue_len` value contains. If the `pvalue_len` - * is NULL, this consuming operation is done automatically. - * - * Returns 1 if *pvalue was successfully read. - * Returns 0 if there was an error. In this case, *pvalue contains an - * invalid value. - */ - -static int read_var(struct archive_read* a, uint64_t* pvalue, - uint64_t* pvalue_len) -{ - uint64_t result = 0; - size_t shift, i; - const uint8_t* p; - uint8_t b; - - /* We will read maximum of 8 bytes. We don't have to handle the - * situation to read the RAR5 variable-sized value stored at the end of - * the file, because such situation will never happen. */ - if(!read_ahead(a, 8, &p)) - return 0; - - for(shift = 0, i = 0; i < 8; i++, shift += 7) { - b = p[i]; - - /* Strip the MSB from the input byte and add the resulting - * number to the `result`. */ - result += (b & (uint64_t)0x7F) << shift; - - /* MSB set to 1 means we need to continue decoding process. - * MSB set to 0 means we're done. - * - * This conditional checks for the second case. */ - if((b & 0x80) == 0) { - if(pvalue) { - *pvalue = result; - } - - /* If the caller has passed the `pvalue_len` pointer, - * store the number of consumed bytes in it and do NOT - * consume those bytes, since the caller has all the - * information it needs to perform */ - if(pvalue_len) { - *pvalue_len = 1 + i; - } else { - /* If the caller did not provide the - * `pvalue_len` pointer, it will not have the - * possibility to advance the file pointer, - * because it will not know how many bytes it - * needs to consume. This is why we handle - * such situation here automatically. */ - if(ARCHIVE_OK != consume(a, 1 + i)) { - return 0; - } - } - - /* End of decoding process, return success. */ - return 1; - } - } - - /* The decoded value takes the maximum number of 8 bytes. - * It's a maximum number of bytes, so end decoding process here - * even if the first bit of last byte is 1. */ - if(pvalue) { - *pvalue = result; - } - - if(pvalue_len) { - *pvalue_len = 9; - } else { - if(ARCHIVE_OK != consume(a, 9)) { - return 0; - } - } - - return 1; -} - -static int read_var_sized(struct archive_read* a, size_t* pvalue, - size_t* pvalue_len) -{ - uint64_t v; - uint64_t v_size = 0; - - const int ret = pvalue_len ? read_var(a, &v, &v_size) - : read_var(a, &v, NULL); - - if(ret == 1 && pvalue) { - *pvalue = (size_t) v; - } - - if(pvalue_len) { - /* Possible data truncation should be safe. */ - *pvalue_len = (size_t) v_size; - } - - return ret; -} - -static int read_bits_32(struct archive_read* a, struct rar5* rar, - const uint8_t* p, uint32_t* value) -{ - if(rar->bits.in_addr >= rar->cstate.cur_block_size) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_PROGRAMMER, - "Premature end of stream during extraction of data (#1)"); - return ARCHIVE_FATAL; - } - - uint32_t bits = ((uint32_t) p[rar->bits.in_addr]) << 24; - bits |= p[rar->bits.in_addr + 1] << 16; - bits |= p[rar->bits.in_addr + 2] << 8; - bits |= p[rar->bits.in_addr + 3]; - bits <<= rar->bits.bit_addr; - bits |= p[rar->bits.in_addr + 4] >> (8 - rar->bits.bit_addr); - *value = bits; - return ARCHIVE_OK; -} - -static int read_bits_16(struct archive_read* a, struct rar5* rar, - const uint8_t* p, uint16_t* value) -{ - if(rar->bits.in_addr >= rar->cstate.cur_block_size) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_PROGRAMMER, - "Premature end of stream during extraction of data (#2)"); - return ARCHIVE_FATAL; - } - - int bits = (int) ((uint32_t) p[rar->bits.in_addr]) << 16; - bits |= (int) p[rar->bits.in_addr + 1] << 8; - bits |= (int) p[rar->bits.in_addr + 2]; - bits >>= (8 - rar->bits.bit_addr); - *value = bits & 0xffff; - return ARCHIVE_OK; -} - -static void skip_bits(struct rar5* rar, int bits) { - const int new_bits = rar->bits.bit_addr + bits; - rar->bits.in_addr += new_bits >> 3; - rar->bits.bit_addr = new_bits & 7; -} - -/* n = up to 16 */ -static int read_consume_bits(struct archive_read* a, struct rar5* rar, - const uint8_t* p, int n, int* value) -{ - uint16_t v; - int ret, num; - - if(n == 0 || n > 16) { - /* This is a programmer error and should never happen - * in runtime. */ - return ARCHIVE_FATAL; - } - - ret = read_bits_16(a, rar, p, &v); - if(ret != ARCHIVE_OK) - return ret; - - num = (int) v; - num >>= 16 - n; - - skip_bits(rar, n); - - if(value) - *value = num; - - return ARCHIVE_OK; -} - -static int read_u32(struct archive_read* a, uint32_t* pvalue) { - const uint8_t* p; - if(!read_ahead(a, 4, &p)) - return 0; - - *pvalue = archive_le32dec(p); - return ARCHIVE_OK == consume(a, 4) ? 1 : 0; -} - -static int read_u64(struct archive_read* a, uint64_t* pvalue) { - const uint8_t* p; - if(!read_ahead(a, 8, &p)) - return 0; - - *pvalue = archive_le64dec(p); - return ARCHIVE_OK == consume(a, 8) ? 1 : 0; -} - -static int bid_standard(struct archive_read* a) { - const uint8_t* p; - char signature[sizeof(rar5_signature_xor)]; - - rar5_signature(signature); - - if(!read_ahead(a, sizeof(rar5_signature_xor), &p)) - return -1; - - if(!memcmp(signature, p, sizeof(rar5_signature_xor))) - return 30; - - return -1; -} - -static int bid_sfx(struct archive_read *a) -{ - const char *p; - - if ((p = __archive_read_ahead(a, 7, NULL)) == NULL) - return -1; - - if ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0) { - /* This is a PE file */ - char signature[sizeof(rar5_signature_xor)]; - ssize_t offset = 0x10000; - ssize_t window = 4096; - ssize_t bytes_avail; - - rar5_signature(signature); - - while (offset + window <= (1024 * 512)) { - const char *buff = __archive_read_ahead(a, offset + window, &bytes_avail); - if (buff == NULL) { - /* Remaining bytes are less than window. */ - window >>= 1; - if (window < 0x40) - return 0; - continue; - } - p = buff + offset; - while (p + 8 < buff + bytes_avail) { - if (memcmp(p, signature, sizeof(signature)) == 0) - return 30; - p += 0x10; - } - offset = p - buff; - } - } - - return 0; -} - -static int rar5_bid(struct archive_read* a, int best_bid) { - int my_bid; - - if(best_bid > 30) - return -1; - - my_bid = bid_standard(a); - if(my_bid > -1) { - return my_bid; - } - my_bid = bid_sfx(a); - if (my_bid > -1) { - return my_bid; - } - - return -1; -} - -static int rar5_options(struct archive_read *a, const char *key, - const char *val) { - (void) a; - (void) key; - (void) val; - - /* No options supported in this version. Return the ARCHIVE_WARN code - * to signal the options supervisor that the unpacker didn't handle - * setting this option. */ - - return ARCHIVE_WARN; -} - -static void init_header(struct archive_read* a) { - a->archive.archive_format = ARCHIVE_FORMAT_RAR_V5; - a->archive.archive_format_name = "RAR5"; -} - -static void init_window_mask(struct rar5* rar) { - if (rar->cstate.window_size) - rar->cstate.window_mask = rar->cstate.window_size - 1; - else - rar->cstate.window_mask = 0; -} - -enum HEADER_FLAGS { - HFL_EXTRA_DATA = 0x0001, - HFL_DATA = 0x0002, - HFL_SKIP_IF_UNKNOWN = 0x0004, - HFL_SPLIT_BEFORE = 0x0008, - HFL_SPLIT_AFTER = 0x0010, - HFL_CHILD = 0x0020, - HFL_INHERITED = 0x0040 -}; - -static int process_main_locator_extra_block(struct archive_read* a, - struct rar5* rar) -{ - uint64_t locator_flags; - - enum LOCATOR_FLAGS { - QLIST = 0x01, RECOVERY = 0x02, - }; - - if(!read_var(a, &locator_flags, NULL)) { - return ARCHIVE_EOF; - } - - if(locator_flags & QLIST) { - if(!read_var(a, &rar->qlist_offset, NULL)) { - return ARCHIVE_EOF; - } - - /* qlist is not used */ - } - - if(locator_flags & RECOVERY) { - if(!read_var(a, &rar->rr_offset, NULL)) { - return ARCHIVE_EOF; - } - - /* rr is not used */ - } - - return ARCHIVE_OK; -} - -static int parse_file_extra_hash(struct archive_read* a, struct rar5* rar, - ssize_t* extra_data_size) -{ - size_t hash_type = 0; - size_t value_len; - - enum HASH_TYPE { - BLAKE2sp = 0x00 - }; - - if(!read_var_sized(a, &hash_type, &value_len)) - return ARCHIVE_EOF; - - *extra_data_size -= value_len; - if(ARCHIVE_OK != consume(a, value_len)) { - return ARCHIVE_EOF; - } - - /* The file uses BLAKE2sp checksum algorithm instead of plain old - * CRC32. */ - if(hash_type == BLAKE2sp) { - const uint8_t* p; - const int hash_size = sizeof(rar->file.blake2sp); - - if(!read_ahead(a, hash_size, &p)) - return ARCHIVE_EOF; - - rar->file.has_blake2 = 1; - memcpy(&rar->file.blake2sp, p, hash_size); - - if(ARCHIVE_OK != consume(a, hash_size)) { - return ARCHIVE_EOF; - } - - *extra_data_size -= hash_size; - } else { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Unsupported hash type (0x%x)", (int) hash_type); - return ARCHIVE_FATAL; - } - - return ARCHIVE_OK; -} - -static uint64_t time_win_to_unix(uint64_t win_time) { - const size_t ns_in_sec = 10000000; - const uint64_t sec_to_unix = 11644473600LL; - return win_time / ns_in_sec - sec_to_unix; -} - -static int parse_htime_item(struct archive_read* a, char unix_time, - uint64_t* where, ssize_t* extra_data_size) -{ - if(unix_time) { - uint32_t time_val; - if(!read_u32(a, &time_val)) - return ARCHIVE_EOF; - - *extra_data_size -= 4; - *where = (uint64_t) time_val; - } else { - uint64_t windows_time; - if(!read_u64(a, &windows_time)) - return ARCHIVE_EOF; - - *where = time_win_to_unix(windows_time); - *extra_data_size -= 8; - } - - return ARCHIVE_OK; -} - -static int parse_file_extra_version(struct archive_read* a, - struct archive_entry* e, ssize_t* extra_data_size) -{ - size_t flags = 0; - size_t version = 0; - size_t value_len = 0; - struct archive_string version_string; - struct archive_string name_utf8_string; - const char* cur_filename; - - /* Flags are ignored. */ - if(!read_var_sized(a, &flags, &value_len)) - return ARCHIVE_EOF; - - *extra_data_size -= value_len; - if(ARCHIVE_OK != consume(a, value_len)) - return ARCHIVE_EOF; - - if(!read_var_sized(a, &version, &value_len)) - return ARCHIVE_EOF; - - *extra_data_size -= value_len; - if(ARCHIVE_OK != consume(a, value_len)) - return ARCHIVE_EOF; - - /* extra_data_size should be zero here. */ - - cur_filename = archive_entry_pathname_utf8(e); - if(cur_filename == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, - "Version entry without file name"); - return ARCHIVE_FATAL; - } - - archive_string_init(&version_string); - archive_string_init(&name_utf8_string); - - /* Prepare a ;123 suffix for the filename, where '123' is the version - * value of this file. */ - archive_string_sprintf(&version_string, ";%zu", version); - - /* Build the new filename. */ - archive_strcat(&name_utf8_string, cur_filename); - archive_strcat(&name_utf8_string, version_string.s); - - /* Apply the new filename into this file's context. */ - archive_entry_update_pathname_utf8(e, name_utf8_string.s); - - /* Free buffers. */ - archive_string_free(&version_string); - archive_string_free(&name_utf8_string); - return ARCHIVE_OK; -} - -static int parse_file_extra_htime(struct archive_read* a, - struct archive_entry* e, struct rar5* rar, ssize_t* extra_data_size) -{ - char unix_time = 0; - size_t flags = 0; - size_t value_len; - - enum HTIME_FLAGS { - IS_UNIX = 0x01, - HAS_MTIME = 0x02, - HAS_CTIME = 0x04, - HAS_ATIME = 0x08, - HAS_UNIX_NS = 0x10, - }; - - if(!read_var_sized(a, &flags, &value_len)) - return ARCHIVE_EOF; - - *extra_data_size -= value_len; - if(ARCHIVE_OK != consume(a, value_len)) { - return ARCHIVE_EOF; - } - - unix_time = flags & IS_UNIX; - - if(flags & HAS_MTIME) { - parse_htime_item(a, unix_time, &rar->file.e_mtime, - extra_data_size); - archive_entry_set_mtime(e, rar->file.e_mtime, 0); - } - - if(flags & HAS_CTIME) { - parse_htime_item(a, unix_time, &rar->file.e_ctime, - extra_data_size); - archive_entry_set_ctime(e, rar->file.e_ctime, 0); - } - - if(flags & HAS_ATIME) { - parse_htime_item(a, unix_time, &rar->file.e_atime, - extra_data_size); - archive_entry_set_atime(e, rar->file.e_atime, 0); - } - - if(flags & HAS_UNIX_NS) { - if(!read_u32(a, &rar->file.e_unix_ns)) - return ARCHIVE_EOF; - - *extra_data_size -= 4; - } - - return ARCHIVE_OK; -} - -static int parse_file_extra_redir(struct archive_read* a, - struct archive_entry* e, struct rar5* rar, ssize_t* extra_data_size) -{ - uint64_t value_size = 0; - size_t target_size = 0; - char target_utf8_buf[MAX_NAME_IN_BYTES]; - const uint8_t* p; - - if(!read_var(a, &rar->file.redir_type, &value_size)) - return ARCHIVE_EOF; - if(ARCHIVE_OK != consume(a, (int64_t)value_size)) - return ARCHIVE_EOF; - *extra_data_size -= value_size; - - if(!read_var(a, &rar->file.redir_flags, &value_size)) - return ARCHIVE_EOF; - if(ARCHIVE_OK != consume(a, (int64_t)value_size)) - return ARCHIVE_EOF; - *extra_data_size -= value_size; - - if(!read_var_sized(a, &target_size, NULL)) - return ARCHIVE_EOF; - *extra_data_size -= target_size + 1; - - if(!read_ahead(a, target_size, &p)) - return ARCHIVE_EOF; - - if(target_size > (MAX_NAME_IN_CHARS - 1)) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Link target is too long"); - return ARCHIVE_FATAL; - } - - if(target_size == 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "No link target specified"); - return ARCHIVE_FATAL; - } - - memcpy(target_utf8_buf, p, target_size); - target_utf8_buf[target_size] = 0; - - if(ARCHIVE_OK != consume(a, (int64_t)target_size)) - return ARCHIVE_EOF; - - switch(rar->file.redir_type) { - case REDIR_TYPE_UNIXSYMLINK: - case REDIR_TYPE_WINSYMLINK: - archive_entry_set_filetype(e, AE_IFLNK); - archive_entry_update_symlink_utf8(e, target_utf8_buf); - if (rar->file.redir_flags & REDIR_SYMLINK_IS_DIR) { - archive_entry_set_symlink_type(e, - AE_SYMLINK_TYPE_DIRECTORY); - } else { - archive_entry_set_symlink_type(e, - AE_SYMLINK_TYPE_FILE); - } - break; - - case REDIR_TYPE_HARDLINK: - archive_entry_set_filetype(e, AE_IFREG); - archive_entry_update_hardlink_utf8(e, target_utf8_buf); - break; - - default: - /* Unknown redir type, skip it. */ - break; - } - return ARCHIVE_OK; -} - -static int parse_file_extra_owner(struct archive_read* a, - struct archive_entry* e, ssize_t* extra_data_size) -{ - uint64_t flags = 0; - uint64_t value_size = 0; - uint64_t id = 0; - size_t name_len = 0; - size_t name_size = 0; - char namebuf[OWNER_MAXNAMELEN]; - const uint8_t* p; - - if(!read_var(a, &flags, &value_size)) - return ARCHIVE_EOF; - if(ARCHIVE_OK != consume(a, (int64_t)value_size)) - return ARCHIVE_EOF; - *extra_data_size -= value_size; - - if ((flags & OWNER_USER_NAME) != 0) { - if(!read_var_sized(a, &name_size, NULL)) - return ARCHIVE_EOF; - *extra_data_size -= name_size + 1; - - if(!read_ahead(a, name_size, &p)) - return ARCHIVE_EOF; - - if (name_size >= OWNER_MAXNAMELEN) { - name_len = OWNER_MAXNAMELEN - 1; - } else { - name_len = name_size; - } - - memcpy(namebuf, p, name_len); - namebuf[name_len] = 0; - if(ARCHIVE_OK != consume(a, (int64_t)name_size)) - return ARCHIVE_EOF; - - archive_entry_set_uname(e, namebuf); - } - if ((flags & OWNER_GROUP_NAME) != 0) { - if(!read_var_sized(a, &name_size, NULL)) - return ARCHIVE_EOF; - *extra_data_size -= name_size + 1; - - if(!read_ahead(a, name_size, &p)) - return ARCHIVE_EOF; - - if (name_size >= OWNER_MAXNAMELEN) { - name_len = OWNER_MAXNAMELEN - 1; - } else { - name_len = name_size; - } - - memcpy(namebuf, p, name_len); - namebuf[name_len] = 0; - if(ARCHIVE_OK != consume(a, (int64_t)name_size)) - return ARCHIVE_EOF; - - archive_entry_set_gname(e, namebuf); - } - if ((flags & OWNER_USER_UID) != 0) { - if(!read_var(a, &id, &value_size)) - return ARCHIVE_EOF; - if(ARCHIVE_OK != consume(a, (int64_t)value_size)) - return ARCHIVE_EOF; - *extra_data_size -= value_size; - - archive_entry_set_uid(e, (la_int64_t)id); - } - if ((flags & OWNER_GROUP_GID) != 0) { - if(!read_var(a, &id, &value_size)) - return ARCHIVE_EOF; - if(ARCHIVE_OK != consume(a, (int64_t)value_size)) - return ARCHIVE_EOF; - *extra_data_size -= value_size; - - archive_entry_set_gid(e, (la_int64_t)id); - } - return ARCHIVE_OK; -} - -static int process_head_file_extra(struct archive_read* a, - struct archive_entry* e, struct rar5* rar, ssize_t extra_data_size) -{ - size_t extra_field_size; - size_t extra_field_id = 0; - int ret = ARCHIVE_FATAL; - size_t var_size; - - while(extra_data_size > 0) { - if(!read_var_sized(a, &extra_field_size, &var_size)) - return ARCHIVE_EOF; - - extra_data_size -= var_size; - if(ARCHIVE_OK != consume(a, var_size)) { - return ARCHIVE_EOF; - } - - if(!read_var_sized(a, &extra_field_id, &var_size)) - return ARCHIVE_EOF; - - extra_data_size -= var_size; - if(ARCHIVE_OK != consume(a, var_size)) { - return ARCHIVE_EOF; - } - - switch(extra_field_id) { - case EX_HASH: - ret = parse_file_extra_hash(a, rar, - &extra_data_size); - break; - case EX_HTIME: - ret = parse_file_extra_htime(a, e, rar, - &extra_data_size); - break; - case EX_REDIR: - ret = parse_file_extra_redir(a, e, rar, - &extra_data_size); - break; - case EX_UOWNER: - ret = parse_file_extra_owner(a, e, - &extra_data_size); - break; - case EX_VERSION: - ret = parse_file_extra_version(a, e, - &extra_data_size); - break; - case EX_CRYPT: - /* fallthrough */ - case EX_SUBDATA: - /* fallthrough */ - default: - /* Skip unsupported entry. */ - return consume(a, extra_data_size); - } - } - - if(ret != ARCHIVE_OK) { - /* Attribute not implemented. */ - return ret; - } - - return ARCHIVE_OK; -} - -static int process_head_file(struct archive_read* a, struct rar5* rar, - struct archive_entry* entry, size_t block_flags) -{ - ssize_t extra_data_size = 0; - size_t data_size = 0; - size_t file_flags = 0; - size_t file_attr = 0; - size_t compression_info = 0; - size_t host_os = 0; - size_t name_size = 0; - uint64_t unpacked_size, window_size; - uint32_t mtime = 0, crc = 0; - int c_method = 0, c_version = 0; - char name_utf8_buf[MAX_NAME_IN_BYTES]; - const uint8_t* p; - - enum FILE_FLAGS { - DIRECTORY = 0x0001, UTIME = 0x0002, CRC32 = 0x0004, - UNKNOWN_UNPACKED_SIZE = 0x0008, - }; - - enum FILE_ATTRS { - ATTR_READONLY = 0x1, ATTR_HIDDEN = 0x2, ATTR_SYSTEM = 0x4, - ATTR_DIRECTORY = 0x10, - }; - - enum COMP_INFO_FLAGS { - SOLID = 0x0040, - }; - - enum HOST_OS { - HOST_WINDOWS = 0, - HOST_UNIX = 1, - }; - - archive_entry_clear(entry); - - /* Do not reset file context if we're switching archives. */ - if(!rar->cstate.switch_multivolume) { - reset_file_context(rar); - } - - if(block_flags & HFL_EXTRA_DATA) { - size_t edata_size = 0; - if(!read_var_sized(a, &edata_size, NULL)) - return ARCHIVE_EOF; - - /* Intentional type cast from unsigned to signed. */ - extra_data_size = (ssize_t) edata_size; - } - - if(block_flags & HFL_DATA) { - if(!read_var_sized(a, &data_size, NULL)) - return ARCHIVE_EOF; - - rar->file.bytes_remaining = data_size; - } else { - rar->file.bytes_remaining = 0; - - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "no data found in file/service block"); - return ARCHIVE_FATAL; - } - - if(!read_var_sized(a, &file_flags, NULL)) - return ARCHIVE_EOF; - - if(!read_var(a, &unpacked_size, NULL)) - return ARCHIVE_EOF; - - if(file_flags & UNKNOWN_UNPACKED_SIZE) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, - "Files with unknown unpacked size are not supported"); - return ARCHIVE_FATAL; - } - - rar->file.dir = (uint8_t) ((file_flags & DIRECTORY) > 0); - - if(!read_var_sized(a, &file_attr, NULL)) - return ARCHIVE_EOF; - - if(file_flags & UTIME) { - if(!read_u32(a, &mtime)) - return ARCHIVE_EOF; - } - - if(file_flags & CRC32) { - if(!read_u32(a, &crc)) - return ARCHIVE_EOF; - } - - if(!read_var_sized(a, &compression_info, NULL)) - return ARCHIVE_EOF; - - c_method = (int) (compression_info >> 7) & 0x7; - c_version = (int) (compression_info & 0x3f); - - /* RAR5 seems to limit the dictionary size to 64MB. */ - window_size = (rar->file.dir > 0) ? - 0 : - g_unpack_window_size << ((compression_info >> 10) & 15); - rar->cstate.method = c_method; - rar->cstate.version = c_version + 50; - rar->file.solid = (compression_info & SOLID) > 0; - - /* Archives which declare solid files without initializing the window - * buffer first are invalid. */ - - if(rar->file.solid > 0 && rar->cstate.window_buf == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Declared solid file, but no window buffer " - "initialized yet."); - return ARCHIVE_FATAL; - } - - /* Check if window_size is a sane value. Also, if the file is not - * declared as a directory, disallow window_size == 0. */ - if(window_size > (64 * 1024 * 1024) || - (rar->file.dir == 0 && window_size == 0)) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Declared dictionary size is not supported."); - return ARCHIVE_FATAL; - } - - if(rar->file.solid > 0) { - /* Re-check if current window size is the same as previous - * window size (for solid files only). */ - if(rar->file.solid_window_size > 0 && - rar->file.solid_window_size != (ssize_t) window_size) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Window size for this solid file doesn't match " - "the window size used in previous solid file. "); - return ARCHIVE_FATAL; - } - } - - if(rar->cstate.window_size < (ssize_t) window_size && - rar->cstate.window_buf) - { - /* If window_buf has been allocated before, reallocate it, so - * that its size will match new window_size. */ - - uint8_t* new_window_buf = - realloc(rar->cstate.window_buf, window_size); - - if(!new_window_buf) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, - "Not enough memory when trying to realloc the window " - "buffer."); - return ARCHIVE_FATAL; - } - - rar->cstate.window_buf = new_window_buf; - } - - /* Values up to 64M should fit into ssize_t on every - * architecture. */ - rar->cstate.window_size = (ssize_t) window_size; - - if(rar->file.solid > 0 && rar->file.solid_window_size == 0) { - /* Solid files have to have the same window_size across - whole archive. Remember the window_size parameter - for first solid file found. */ - rar->file.solid_window_size = rar->cstate.window_size; - } - - init_window_mask(rar); - - rar->file.service = 0; - - if(!read_var_sized(a, &host_os, NULL)) - return ARCHIVE_EOF; - - if(host_os == HOST_WINDOWS) { - /* Host OS is Windows */ - - __LA_MODE_T mode; - - if(file_attr & ATTR_DIRECTORY) { - if (file_attr & ATTR_READONLY) { - mode = 0555 | AE_IFDIR; - } else { - mode = 0755 | AE_IFDIR; - } - } else { - if (file_attr & ATTR_READONLY) { - mode = 0444 | AE_IFREG; - } else { - mode = 0644 | AE_IFREG; - } - } - - archive_entry_set_mode(entry, mode); - - if (file_attr & (ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM)) { - char *fflags_text, *ptr; - /* allocate for "rdonly,hidden,system," */ - fflags_text = malloc(22 * sizeof(char)); - if (fflags_text != NULL) { - ptr = fflags_text; - if (file_attr & ATTR_READONLY) { - strcpy(ptr, "rdonly,"); - ptr = ptr + 7; - } - if (file_attr & ATTR_HIDDEN) { - strcpy(ptr, "hidden,"); - ptr = ptr + 7; - } - if (file_attr & ATTR_SYSTEM) { - strcpy(ptr, "system,"); - ptr = ptr + 7; - } - if (ptr > fflags_text) { - /* Delete trailing comma */ - *(ptr - 1) = '\0'; - archive_entry_copy_fflags_text(entry, - fflags_text); - } - free(fflags_text); - } - } - } else if(host_os == HOST_UNIX) { - /* Host OS is Unix */ - archive_entry_set_mode(entry, (__LA_MODE_T) file_attr); - } else { - /* Unknown host OS */ - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Unsupported Host OS: 0x%x", (int) host_os); - - return ARCHIVE_FATAL; - } - - if(!read_var_sized(a, &name_size, NULL)) - return ARCHIVE_EOF; - - if(!read_ahead(a, name_size, &p)) - return ARCHIVE_EOF; - - if(name_size > (MAX_NAME_IN_CHARS - 1)) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Filename is too long"); - - return ARCHIVE_FATAL; - } - - if(name_size == 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "No filename specified"); - - return ARCHIVE_FATAL; - } - - memcpy(name_utf8_buf, p, name_size); - name_utf8_buf[name_size] = 0; - if(ARCHIVE_OK != consume(a, name_size)) { - return ARCHIVE_EOF; - } - - archive_entry_update_pathname_utf8(entry, name_utf8_buf); - - if(extra_data_size > 0) { - int ret = process_head_file_extra(a, entry, rar, - extra_data_size); - - /* - * TODO: rewrite or remove useless sanity check - * as extra_data_size is not passed as a pointer - * - if(extra_data_size < 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, - "File extra data size is not zero"); - return ARCHIVE_FATAL; - } - */ - - if(ret != ARCHIVE_OK) - return ret; - } - - if((file_flags & UNKNOWN_UNPACKED_SIZE) == 0) { - rar->file.unpacked_size = (ssize_t) unpacked_size; - if(rar->file.redir_type == REDIR_TYPE_NONE) - archive_entry_set_size(entry, unpacked_size); - } - - if(file_flags & UTIME) { - archive_entry_set_mtime(entry, (time_t) mtime, 0); - } - - if(file_flags & CRC32) { - rar->file.stored_crc32 = crc; - } - - if(!rar->cstate.switch_multivolume) { - /* Do not reinitialize unpacking state if we're switching - * archives. */ - rar->cstate.block_parsing_finished = 1; - rar->cstate.all_filters_applied = 1; - rar->cstate.initialized = 0; - } - - if(rar->generic.split_before > 0) { - /* If now we're standing on a header that has a 'split before' - * mark, it means we're standing on a 'continuation' file - * header. Signal the caller that if it wants to move to - * another file, it must call rar5_read_header() function - * again. */ - - return ARCHIVE_RETRY; - } else { - return ARCHIVE_OK; - } -} - -static int process_head_service(struct archive_read* a, struct rar5* rar, - struct archive_entry* entry, size_t block_flags) -{ - /* Process this SERVICE block the same way as FILE blocks. */ - int ret = process_head_file(a, rar, entry, block_flags); - if(ret != ARCHIVE_OK) - return ret; - - rar->file.service = 1; - - /* But skip the data part automatically. It's no use for the user - * anyway. It contains only service data, not even needed to - * properly unpack the file. */ - ret = rar5_read_data_skip(a); - if(ret != ARCHIVE_OK) - return ret; - - /* After skipping, try parsing another block automatically. */ - return ARCHIVE_RETRY; -} - -static int process_head_main(struct archive_read* a, struct rar5* rar, - struct archive_entry* entry, size_t block_flags) -{ - int ret; - size_t extra_data_size = 0; - size_t extra_field_size = 0; - size_t extra_field_id = 0; - size_t archive_flags = 0; - - enum MAIN_FLAGS { - VOLUME = 0x0001, /* multi-volume archive */ - VOLUME_NUMBER = 0x0002, /* volume number, first vol doesn't - * have it */ - SOLID = 0x0004, /* solid archive */ - PROTECT = 0x0008, /* contains Recovery info */ - LOCK = 0x0010, /* readonly flag, not used */ - }; - - enum MAIN_EXTRA { - // Just one attribute here. - LOCATOR = 0x01, - }; - - (void) entry; - - if(block_flags & HFL_EXTRA_DATA) { - if(!read_var_sized(a, &extra_data_size, NULL)) - return ARCHIVE_EOF; - } else { - extra_data_size = 0; - } - - if(!read_var_sized(a, &archive_flags, NULL)) { - return ARCHIVE_EOF; - } - - rar->main.volume = (archive_flags & VOLUME) > 0; - rar->main.solid = (archive_flags & SOLID) > 0; - - if(archive_flags & VOLUME_NUMBER) { - size_t v = 0; - if(!read_var_sized(a, &v, NULL)) { - return ARCHIVE_EOF; - } - - if (v > UINT_MAX) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid volume number"); - return ARCHIVE_FATAL; - } - - rar->main.vol_no = (unsigned int) v; - } else { - rar->main.vol_no = 0; - } - - if(rar->vol.expected_vol_no > 0 && - rar->main.vol_no != rar->vol.expected_vol_no) - { - /* Returning EOF instead of FATAL because of strange - * libarchive behavior. When opening multiple files via - * archive_read_open_filenames(), after reading up the whole - * last file, the __archive_read_ahead function wraps up to - * the first archive instead of returning EOF. */ - return ARCHIVE_EOF; - } - - if(extra_data_size == 0) { - /* Early return. */ - return ARCHIVE_OK; - } - - if(!read_var_sized(a, &extra_field_size, NULL)) { - return ARCHIVE_EOF; - } - - if(!read_var_sized(a, &extra_field_id, NULL)) { - return ARCHIVE_EOF; - } - - if(extra_field_size == 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid extra field size"); - return ARCHIVE_FATAL; - } - - switch(extra_field_id) { - case LOCATOR: - ret = process_main_locator_extra_block(a, rar); - if(ret != ARCHIVE_OK) { - /* Error while parsing main locator extra - * block. */ - return ret; - } - - break; - default: - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Unsupported extra type (0x%x)", - (int) extra_field_id); - return ARCHIVE_FATAL; - } - - return ARCHIVE_OK; -} - -static int skip_unprocessed_bytes(struct archive_read* a) { - struct rar5* rar = get_context(a); - int ret; - - if(rar->file.bytes_remaining) { - /* Use different skipping method in block merging mode than in - * normal mode. If merge mode is active, rar5_read_data_skip - * can't be used, because it could allow recursive use of - * merge_block() * function, and this function doesn't support - * recursive use. */ - if(rar->merge_mode) { - /* Discard whole merged block. This is valid in solid - * mode as well, because the code will discard blocks - * only if those blocks are safe to discard (i.e. - * they're not FILE blocks). */ - ret = consume(a, rar->file.bytes_remaining); - if(ret != ARCHIVE_OK) { - return ret; - } - rar->file.bytes_remaining = 0; - } else { - /* If we're not in merge mode, use safe skipping code. - * This will ensure we'll handle solid archives - * properly. */ - ret = rar5_read_data_skip(a); - if(ret != ARCHIVE_OK) { - return ret; - } - } - } - - return ARCHIVE_OK; -} - -static int scan_for_signature(struct archive_read* a); - -/* Base block processing function. A 'base block' is a RARv5 header block - * that tells the reader what kind of data is stored inside the block. - * - * From the birds-eye view a RAR file looks file this: - * - * ... - * - * There are a few types of base blocks. Those types are specified inside - * the 'switch' statement in this function. For example purposes, I'll write - * how a standard RARv5 file could look like here: - * - *
    - * - * The structure above could describe an archive file with 3 files in it, - * one service "QuickOpen" block (that is ignored by this parser), and an - * end of file base block marker. - * - * If the file is stored in multiple archive files ("multiarchive"), it might - * look like this: - * - * .part01.rar:
    - * .part02.rar:
    - * .part03.rar:
    - * - * This example could describe 3 RAR files that contain ONE archived file. - * Or it could describe 3 RAR files that contain 3 different files. Or 3 - * RAR files than contain 2 files. It all depends what metadata is stored in - * the headers of blocks. - * - * Each block contains info about its size, the name of the file it's - * storing inside, and whether this FILE block is a continuation block of - * previous archive ('split before'), and is this FILE block should be - * continued in another archive ('split after'). By parsing the 'split before' - * and 'split after' flags, we're able to tell if multiple base blocks - * are describing one file, or multiple files (with the same filename, for - * example). - * - * One thing to note is that if we're parsing the first block, and - * we see 'split after' flag, then we need to jump over to another - * block to be able to decompress rest of the data. To do this, we need - * to skip the block, then switch to another file, then skip the - * block,
    block, and then we're standing on the proper - * block. - */ - -static int process_base_block(struct archive_read* a, - struct archive_entry* entry) -{ - const size_t SMALLEST_RAR5_BLOCK_SIZE = 3; - - struct rar5* rar = get_context(a); - uint32_t hdr_crc, computed_crc; - size_t raw_hdr_size = 0, hdr_size_len, hdr_size; - size_t header_id = 0; - size_t header_flags = 0; - const uint8_t* p; - int ret; - - enum HEADER_TYPE { - HEAD_MARK = 0x00, HEAD_MAIN = 0x01, HEAD_FILE = 0x02, - HEAD_SERVICE = 0x03, HEAD_CRYPT = 0x04, HEAD_ENDARC = 0x05, - HEAD_UNKNOWN = 0xff, - }; - - /* Skip any unprocessed data for this file. */ - ret = skip_unprocessed_bytes(a); - if(ret != ARCHIVE_OK) - return ret; - - /* Read the expected CRC32 checksum. */ - if(!read_u32(a, &hdr_crc)) { - return ARCHIVE_EOF; - } - - /* Read header size. */ - if(!read_var_sized(a, &raw_hdr_size, &hdr_size_len)) { - return ARCHIVE_EOF; - } - - hdr_size = raw_hdr_size + hdr_size_len; - - /* Sanity check, maximum header size for RAR5 is 2MB. */ - if(hdr_size > (2 * 1024 * 1024)) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Base block header is too large"); - - return ARCHIVE_FATAL; - } - - /* Additional sanity checks to weed out invalid files. */ - if(raw_hdr_size == 0 || hdr_size_len == 0 || - hdr_size < SMALLEST_RAR5_BLOCK_SIZE) - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Too small block encountered (%zu bytes)", - raw_hdr_size); - - return ARCHIVE_FATAL; - } - - /* Read the whole header data into memory, maximum memory use here is - * 2MB. */ - if(!read_ahead(a, hdr_size, &p)) { - return ARCHIVE_EOF; - } - - /* Verify the CRC32 of the header data. */ - computed_crc = (uint32_t) crc32(0, p, (int) hdr_size); - if(computed_crc != hdr_crc) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Header CRC error"); - - return ARCHIVE_FATAL; - } - - /* If the checksum is OK, we proceed with parsing. */ - if(ARCHIVE_OK != consume(a, hdr_size_len)) { - return ARCHIVE_EOF; - } - - if(!read_var_sized(a, &header_id, NULL)) - return ARCHIVE_EOF; - - if(!read_var_sized(a, &header_flags, NULL)) - return ARCHIVE_EOF; - - rar->generic.split_after = (header_flags & HFL_SPLIT_AFTER) > 0; - rar->generic.split_before = (header_flags & HFL_SPLIT_BEFORE) > 0; - rar->generic.size = (int)hdr_size; - rar->generic.last_header_id = (int)header_id; - rar->main.endarc = 0; - - /* Those are possible header ids in RARv5. */ - switch(header_id) { - case HEAD_MAIN: - ret = process_head_main(a, rar, entry, header_flags); - - /* Main header doesn't have any files in it, so it's - * pointless to return to the caller. Retry to next - * header, which should be HEAD_FILE/HEAD_SERVICE. */ - if(ret == ARCHIVE_OK) - return ARCHIVE_RETRY; - - return ret; - case HEAD_SERVICE: - ret = process_head_service(a, rar, entry, header_flags); - return ret; - case HEAD_FILE: - ret = process_head_file(a, rar, entry, header_flags); - return ret; - case HEAD_CRYPT: - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Encryption is not supported"); - return ARCHIVE_FATAL; - case HEAD_ENDARC: - rar->main.endarc = 1; - - /* After encountering an end of file marker, we need - * to take into consideration if this archive is - * continued in another file (i.e. is it part01.rar: - * is there a part02.rar?) */ - if(rar->main.volume) { - /* In case there is part02.rar, position the - * read pointer in a proper place, so we can - * resume parsing. */ - ret = scan_for_signature(a); - if(ret == ARCHIVE_FATAL) { - return ARCHIVE_EOF; - } else { - if(rar->vol.expected_vol_no == - UINT_MAX) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Header error"); - return ARCHIVE_FATAL; - } - - rar->vol.expected_vol_no = - rar->main.vol_no + 1; - return ARCHIVE_OK; - } - } else { - return ARCHIVE_EOF; - } - case HEAD_MARK: - return ARCHIVE_EOF; - default: - if((header_flags & HFL_SKIP_IF_UNKNOWN) == 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Header type error"); - return ARCHIVE_FATAL; - } else { - /* If the block is marked as 'skip if unknown', - * do as the flag says: skip the block - * instead on failing on it. */ - return ARCHIVE_RETRY; - } - } - -#if !defined WIN32 - // Not reached. - archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, - "Internal unpacker error"); - return ARCHIVE_FATAL; -#endif -} - -static int skip_base_block(struct archive_read* a) { - int ret; - struct rar5* rar = get_context(a); - - /* Create a new local archive_entry structure that will be operated on - * by header reader; operations on this archive_entry will be discarded. - */ - struct archive_entry* entry = archive_entry_new(); - ret = process_base_block(a, entry); - - /* Discard operations on this archive_entry structure. */ - archive_entry_free(entry); - if(ret == ARCHIVE_FATAL) - return ret; - - if(rar->generic.last_header_id == 2 && rar->generic.split_before > 0) - return ARCHIVE_OK; - - if(ret == ARCHIVE_OK) - return ARCHIVE_RETRY; - else - return ret; -} - -static int try_skip_sfx(struct archive_read *a) -{ - const char *p; - - if ((p = __archive_read_ahead(a, 7, NULL)) == NULL) - return ARCHIVE_EOF; - - if ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0) - { - char signature[sizeof(rar5_signature_xor)]; - const void *h; - const char *q; - size_t skip, total = 0; - ssize_t bytes, window = 4096; - - rar5_signature(signature); - - while (total + window <= (1024 * 512)) { - h = __archive_read_ahead(a, window, &bytes); - if (h == NULL) { - /* Remaining bytes are less than window. */ - window >>= 1; - if (window < 0x40) - goto fatal; - continue; - } - if (bytes < 0x40) - goto fatal; - p = h; - q = p + bytes; - - /* - * Scan ahead until we find something that looks - * like the RAR header. - */ - while (p + 8 < q) { - if (memcmp(p, signature, sizeof(signature)) == 0) { - skip = p - (const char *)h; - __archive_read_consume(a, skip); - return (ARCHIVE_OK); - } - p += 0x10; - } - skip = p - (const char *)h; - __archive_read_consume(a, skip); - total += skip; - } - } - - return ARCHIVE_OK; -fatal: - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Couldn't find out RAR header"); - return (ARCHIVE_FATAL); -} - -static int rar5_read_header(struct archive_read *a, - struct archive_entry *entry) -{ - struct rar5* rar = get_context(a); - int ret; - - if(rar->header_initialized == 0) { - init_header(a); - if ((ret = try_skip_sfx(a)) < ARCHIVE_WARN) - return ret; - rar->header_initialized = 1; - } - - if(rar->skipped_magic == 0) { - if(ARCHIVE_OK != consume(a, sizeof(rar5_signature_xor))) { - return ARCHIVE_EOF; - } - - rar->skipped_magic = 1; - } - - do { - ret = process_base_block(a, entry); - } while(ret == ARCHIVE_RETRY || - (rar->main.endarc > 0 && ret == ARCHIVE_OK)); - - return ret; -} - -static void init_unpack(struct rar5* rar) { - rar->file.calculated_crc32 = 0; - init_window_mask(rar); - - free(rar->cstate.window_buf); - free(rar->cstate.filtered_buf); - - if(rar->cstate.window_size > 0) { - rar->cstate.window_buf = calloc(1, rar->cstate.window_size); - rar->cstate.filtered_buf = calloc(1, rar->cstate.window_size); - } else { - rar->cstate.window_buf = NULL; - rar->cstate.filtered_buf = NULL; - } - - rar->cstate.write_ptr = 0; - rar->cstate.last_write_ptr = 0; - - memset(&rar->cstate.bd, 0, sizeof(rar->cstate.bd)); - memset(&rar->cstate.ld, 0, sizeof(rar->cstate.ld)); - memset(&rar->cstate.dd, 0, sizeof(rar->cstate.dd)); - memset(&rar->cstate.ldd, 0, sizeof(rar->cstate.ldd)); - memset(&rar->cstate.rd, 0, sizeof(rar->cstate.rd)); -} - -static void update_crc(struct rar5* rar, const uint8_t* p, size_t to_read) { - int verify_crc; - - if(rar->skip_mode) { -#if defined CHECK_CRC_ON_SOLID_SKIP - verify_crc = 1; -#else - verify_crc = 0; -#endif - } else - verify_crc = 1; - - if(verify_crc) { - /* Don't update CRC32 if the file doesn't have the - * `stored_crc32` info filled in. */ - if(rar->file.stored_crc32 > 0) { - rar->file.calculated_crc32 = - crc32(rar->file.calculated_crc32, p, (unsigned int)to_read); - } - - /* Check if the file uses an optional BLAKE2sp checksum - * algorithm. */ - if(rar->file.has_blake2 > 0) { - /* Return value of the `update` function is always 0, - * so we can explicitly ignore it here. */ - (void) blake2sp_update(&rar->file.b2state, p, to_read); - } - } -} - -static int create_decode_tables(uint8_t* bit_length, - struct decode_table* table, int size) -{ - int code, upper_limit = 0, i, lc[16]; - uint32_t decode_pos_clone[rar5_countof(table->decode_pos)]; - ssize_t cur_len, quick_data_size; - - memset(&lc, 0, sizeof(lc)); - memset(table->decode_num, 0, sizeof(table->decode_num)); - table->size = size; - table->quick_bits = size == HUFF_NC ? 10 : 7; - - for(i = 0; i < size; i++) { - lc[bit_length[i] & 15]++; - } - - lc[0] = 0; - table->decode_pos[0] = 0; - table->decode_len[0] = 0; - - for(i = 1; i < 16; i++) { - upper_limit += lc[i]; - - table->decode_len[i] = upper_limit << (16 - i); - table->decode_pos[i] = table->decode_pos[i - 1] + lc[i - 1]; - - upper_limit <<= 1; - } - - memcpy(decode_pos_clone, table->decode_pos, sizeof(decode_pos_clone)); - - for(i = 0; i < size; i++) { - uint8_t clen = bit_length[i] & 15; - if(clen > 0) { - int last_pos = decode_pos_clone[clen]; - table->decode_num[last_pos] = i; - decode_pos_clone[clen]++; - } - } - - quick_data_size = (int64_t)1 << table->quick_bits; - cur_len = 1; - for(code = 0; code < quick_data_size; code++) { - int bit_field = code << (16 - table->quick_bits); - int dist, pos; - - while(cur_len < rar5_countof(table->decode_len) && - bit_field >= table->decode_len[cur_len]) { - cur_len++; - } - - table->quick_len[code] = (uint8_t) cur_len; - - dist = bit_field - table->decode_len[cur_len - 1]; - dist >>= (16 - cur_len); - - pos = table->decode_pos[cur_len & 15] + dist; - if(cur_len < rar5_countof(table->decode_pos) && pos < size) { - table->quick_num[code] = table->decode_num[pos]; - } else { - table->quick_num[code] = 0; - } - } - - return ARCHIVE_OK; -} - -static int decode_number(struct archive_read* a, struct decode_table* table, - const uint8_t* p, uint16_t* num) -{ - int i, bits, dist, ret; - uint16_t bitfield; - uint32_t pos; - struct rar5* rar = get_context(a); - - if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &bitfield))) { - return ret; - } - - bitfield &= 0xfffe; - - if(bitfield < table->decode_len[table->quick_bits]) { - int code = bitfield >> (16 - table->quick_bits); - skip_bits(rar, table->quick_len[code]); - *num = table->quick_num[code]; - return ARCHIVE_OK; - } - - bits = 15; - - for(i = table->quick_bits + 1; i < 15; i++) { - if(bitfield < table->decode_len[i]) { - bits = i; - break; - } - } - - skip_bits(rar, bits); - - dist = bitfield - table->decode_len[bits - 1]; - dist >>= (16 - bits); - pos = table->decode_pos[bits] + dist; - - if(pos >= table->size) - pos = 0; - - *num = table->decode_num[pos]; - return ARCHIVE_OK; -} - -/* Reads and parses Huffman tables from the beginning of the block. */ -static int parse_tables(struct archive_read* a, struct rar5* rar, - const uint8_t* p) -{ - int ret, value, i, w, idx = 0; - uint8_t bit_length[HUFF_BC], - table[HUFF_TABLE_SIZE], - nibble_mask = 0xF0, - nibble_shift = 4; - - enum { ESCAPE = 15 }; - - /* The data for table generation is compressed using a simple RLE-like - * algorithm when storing zeroes, so we need to unpack it first. */ - for(w = 0, i = 0; w < HUFF_BC;) { - if(i >= rar->cstate.cur_block_size) { - /* Truncated data, can't continue. */ - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated data in huffman tables"); - return ARCHIVE_FATAL; - } - - value = (p[i] & nibble_mask) >> nibble_shift; - - if(nibble_mask == 0x0F) - ++i; - - nibble_mask ^= 0xFF; - nibble_shift ^= 4; - - /* Values smaller than 15 is data, so we write it directly. - * Value 15 is a flag telling us that we need to unpack more - * bytes. */ - if(value == ESCAPE) { - value = (p[i] & nibble_mask) >> nibble_shift; - if(nibble_mask == 0x0F) - ++i; - nibble_mask ^= 0xFF; - nibble_shift ^= 4; - - if(value == 0) { - /* We sometimes need to write the actual value - * of 15, so this case handles that. */ - bit_length[w++] = ESCAPE; - } else { - int k; - - /* Fill zeroes. */ - for(k = 0; (k < value + 2) && (w < HUFF_BC); - k++) { - bit_length[w++] = 0; - } - } - } else { - bit_length[w++] = value; - } - } - - rar->bits.in_addr = i; - rar->bits.bit_addr = nibble_shift ^ 4; - - ret = create_decode_tables(bit_length, &rar->cstate.bd, HUFF_BC); - if(ret != ARCHIVE_OK) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Decoding huffman tables failed"); - return ARCHIVE_FATAL; - } - - for(i = 0; i < HUFF_TABLE_SIZE;) { - uint16_t num; - - ret = decode_number(a, &rar->cstate.bd, p, &num); - if(ret != ARCHIVE_OK) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Decoding huffman tables failed"); - return ARCHIVE_FATAL; - } - - if(num < 16) { - /* 0..15: store directly */ - table[i] = (uint8_t) num; - i++; - } else if(num < 18) { - /* 16..17: repeat previous code */ - uint16_t n; - - if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &n))) - return ret; - - if(num == 16) { - n >>= 13; - n += 3; - skip_bits(rar, 3); - } else { - n >>= 9; - n += 11; - skip_bits(rar, 7); - } - - if(i > 0) { - while(n-- > 0 && i < HUFF_TABLE_SIZE) { - table[i] = table[i - 1]; - i++; - } - } else { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Unexpected error when decoding " - "huffman tables"); - return ARCHIVE_FATAL; - } - } else { - /* other codes: fill with zeroes `n` times */ - uint16_t n; - - if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &n))) - return ret; - - if(num == 18) { - n >>= 13; - n += 3; - skip_bits(rar, 3); - } else { - n >>= 9; - n += 11; - skip_bits(rar, 7); - } - - while(n-- > 0 && i < HUFF_TABLE_SIZE) - table[i++] = 0; - } - } - - ret = create_decode_tables(&table[idx], &rar->cstate.ld, HUFF_NC); - if(ret != ARCHIVE_OK) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Failed to create literal table"); - return ARCHIVE_FATAL; - } - - idx += HUFF_NC; - - ret = create_decode_tables(&table[idx], &rar->cstate.dd, HUFF_DC); - if(ret != ARCHIVE_OK) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Failed to create distance table"); - return ARCHIVE_FATAL; - } - - idx += HUFF_DC; - - ret = create_decode_tables(&table[idx], &rar->cstate.ldd, HUFF_LDC); - if(ret != ARCHIVE_OK) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Failed to create lower bits of distances table"); - return ARCHIVE_FATAL; - } - - idx += HUFF_LDC; - - ret = create_decode_tables(&table[idx], &rar->cstate.rd, HUFF_RC); - if(ret != ARCHIVE_OK) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Failed to create repeating distances table"); - return ARCHIVE_FATAL; - } - - return ARCHIVE_OK; -} - -/* Parses the block header, verifies its CRC byte, and saves the header - * fields inside the `hdr` pointer. */ -static int parse_block_header(struct archive_read* a, const uint8_t* p, - ssize_t* block_size, struct compressed_block_header* hdr) -{ - uint8_t calculated_cksum; - memcpy(hdr, p, sizeof(struct compressed_block_header)); - - if(bf_byte_count(hdr) > 2) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Unsupported block header size (was %d, max is 2)", - bf_byte_count(hdr)); - return ARCHIVE_FATAL; - } - - /* This should probably use bit reader interface in order to be more - * future-proof. */ - *block_size = 0; - switch(bf_byte_count(hdr)) { - /* 1-byte block size */ - case 0: - *block_size = *(const uint8_t*) &p[2]; - break; - - /* 2-byte block size */ - case 1: - *block_size = archive_le16dec(&p[2]); - break; - - /* 3-byte block size */ - case 2: - *block_size = archive_le32dec(&p[2]); - *block_size &= 0x00FFFFFF; - break; - - /* Other block sizes are not supported. This case is not - * reached, because we have an 'if' guard before the switch - * that makes sure of it. */ - default: - return ARCHIVE_FATAL; - } - - /* Verify the block header checksum. 0x5A is a magic value and is - * always * constant. */ - calculated_cksum = 0x5A - ^ (uint8_t) hdr->block_flags_u8 - ^ (uint8_t) *block_size - ^ (uint8_t) (*block_size >> 8) - ^ (uint8_t) (*block_size >> 16); - - if(calculated_cksum != hdr->block_cksum) { -#ifndef DONT_FAIL_ON_CRC_ERROR - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Block checksum error: got 0x%x, expected 0x%x", - hdr->block_cksum, calculated_cksum); - - return ARCHIVE_FATAL; -#endif - } - - return ARCHIVE_OK; -} - -/* Convenience function used during filter processing. */ -static int parse_filter_data(struct archive_read* a, struct rar5* rar, - const uint8_t* p, uint32_t* filter_data) -{ - int i, bytes, ret; - uint32_t data = 0; - - if(ARCHIVE_OK != (ret = read_consume_bits(a, rar, p, 2, &bytes))) - return ret; - - bytes++; - - for(i = 0; i < bytes; i++) { - uint16_t byte; - - if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &byte))) { - return ret; - } - - /* Cast to uint32_t will ensure the shift operation will not - * produce undefined result. */ - data += ((uint32_t) byte >> 8) << (i * 8); - skip_bits(rar, 8); - } - - *filter_data = data; - return ARCHIVE_OK; -} - -/* Function is used during sanity checking. */ -static int is_valid_filter_block_start(struct rar5* rar, - uint32_t start) -{ - const int64_t block_start = (ssize_t) start + rar->cstate.write_ptr; - const int64_t last_bs = rar->cstate.last_block_start; - const ssize_t last_bl = rar->cstate.last_block_length; - - if(last_bs == 0 || last_bl == 0) { - /* We didn't have any filters yet, so accept this offset. */ - return 1; - } - - if(block_start >= last_bs + last_bl) { - /* Current offset is bigger than last block's end offset, so - * accept current offset. */ - return 1; - } - - /* Any other case is not a normal situation and we should fail. */ - return 0; -} - -/* The function will create a new filter, read its parameters from the input - * stream and add it to the filter collection. */ -static int parse_filter(struct archive_read* ar, const uint8_t* p) { - uint32_t block_start, block_length; - uint16_t filter_type; - struct filter_info* filt = NULL; - struct rar5* rar = get_context(ar); - int ret; - - /* Read the parameters from the input stream. */ - if(ARCHIVE_OK != (ret = parse_filter_data(ar, rar, p, &block_start))) - return ret; - - if(ARCHIVE_OK != (ret = parse_filter_data(ar, rar, p, &block_length))) - return ret; - - if(ARCHIVE_OK != (ret = read_bits_16(ar, rar, p, &filter_type))) - return ret; - - filter_type >>= 13; - skip_bits(rar, 3); - - /* Perform some sanity checks on this filter parameters. Note that we - * allow only DELTA, E8/E9 and ARM filters here, because rest of - * filters are not used in RARv5. */ - - if(block_length < 4 || - block_length > 0x400000 || - filter_type > FILTER_ARM || - !is_valid_filter_block_start(rar, block_start)) - { - archive_set_error(&ar->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid filter encountered"); - return ARCHIVE_FATAL; - } - - /* Allocate a new filter. */ - filt = add_new_filter(rar); - if(filt == NULL) { - archive_set_error(&ar->archive, ENOMEM, - "Can't allocate memory for a filter descriptor."); - return ARCHIVE_FATAL; - } - - filt->type = filter_type; - filt->block_start = rar->cstate.write_ptr + block_start; - filt->block_length = block_length; - - rar->cstate.last_block_start = filt->block_start; - rar->cstate.last_block_length = filt->block_length; - - /* Read some more data in case this is a DELTA filter. Other filter - * types don't require any additional data over what was already - * read. */ - if(filter_type == FILTER_DELTA) { - int channels; - - if(ARCHIVE_OK != (ret = read_consume_bits(ar, rar, p, 5, &channels))) - return ret; - - filt->channels = channels + 1; - } - - return ARCHIVE_OK; -} - -static int decode_code_length(struct archive_read* a, struct rar5* rar, - const uint8_t* p, uint16_t code) -{ - int lbits, length = 2; - - if(code < 8) { - lbits = 0; - length += code; - } else { - lbits = code / 4 - 1; - length += (4 | (code & 3)) << lbits; - } - - if(lbits > 0) { - int add; - - if(ARCHIVE_OK != read_consume_bits(a, rar, p, lbits, &add)) - return -1; - - length += add; - } - - return length; -} - -static int copy_string(struct archive_read* a, int len, int dist) { - struct rar5* rar = get_context(a); - const uint64_t cmask = rar->cstate.window_mask; - const uint64_t write_ptr = rar->cstate.write_ptr + - rar->cstate.solid_offset; - int i; - - if (rar->cstate.window_buf == NULL) - return ARCHIVE_FATAL; - - /* The unpacker spends most of the time in this function. It would be - * a good idea to introduce some optimizations here. - * - * Just remember that this loop treats buffers that overlap differently - * than buffers that do not overlap. This is why a simple memcpy(3) - * call will not be enough. */ - - for(i = 0; i < len; i++) { - const ssize_t write_idx = (write_ptr + i) & cmask; - const ssize_t read_idx = (write_ptr + i - dist) & cmask; - rar->cstate.window_buf[write_idx] = - rar->cstate.window_buf[read_idx]; - } - - rar->cstate.write_ptr += len; - return ARCHIVE_OK; -} - -static int do_uncompress_block(struct archive_read* a, const uint8_t* p) { - struct rar5* rar = get_context(a); - uint16_t num; - int ret; - - const uint64_t cmask = rar->cstate.window_mask; - const struct compressed_block_header* hdr = &rar->last_block_hdr; - const uint8_t bit_size = 1 + bf_bit_size(hdr); - - while(1) { - if(rar->cstate.write_ptr - rar->cstate.last_write_ptr > - (rar->cstate.window_size >> 1)) { - /* Don't allow growing data by more than half of the - * window size at a time. In such case, break the loop; - * next call to this function will continue processing - * from this moment. */ - break; - } - - if(rar->bits.in_addr > rar->cstate.cur_block_size - 1 || - (rar->bits.in_addr == rar->cstate.cur_block_size - 1 && - rar->bits.bit_addr >= bit_size)) - { - /* If the program counter is here, it means the - * function has finished processing the block. */ - rar->cstate.block_parsing_finished = 1; - break; - } - - /* Decode the next literal. */ - if(ARCHIVE_OK != decode_number(a, &rar->cstate.ld, p, &num)) { - return ARCHIVE_EOF; - } - - /* Num holds a decompression literal, or 'command code'. - * - * - Values lower than 256 are just bytes. Those codes - * can be stored in the output buffer directly. - * - * - Code 256 defines a new filter, which is later used to - * ransform the data block accordingly to the filter type. - * The data block needs to be fully uncompressed first. - * - * - Code bigger than 257 and smaller than 262 define - * a repetition pattern that should be copied from - * an already uncompressed chunk of data. - */ - - if(num < 256) { - /* Directly store the byte. */ - int64_t write_idx = rar->cstate.solid_offset + - rar->cstate.write_ptr++; - - rar->cstate.window_buf[write_idx & cmask] = - (uint8_t) num; - continue; - } else if(num >= 262) { - uint16_t dist_slot; - int len = decode_code_length(a, rar, p, num - 262), - dbits, - dist = 1; - - if(len == -1) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_PROGRAMMER, - "Failed to decode the code length"); - - return ARCHIVE_FATAL; - } - - if(ARCHIVE_OK != decode_number(a, &rar->cstate.dd, p, - &dist_slot)) - { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_PROGRAMMER, - "Failed to decode the distance slot"); - - return ARCHIVE_FATAL; - } - - if(dist_slot < 4) { - dbits = 0; - dist += dist_slot; - } else { - dbits = dist_slot / 2 - 1; - - /* Cast to uint32_t will make sure the shift - * left operation won't produce undefined - * result. Then, the uint32_t type will - * be implicitly casted to int. */ - dist += (uint32_t) (2 | - (dist_slot & 1)) << dbits; - } - - if(dbits > 0) { - if(dbits >= 4) { - uint32_t add = 0; - uint16_t low_dist; - - if(dbits > 4) { - if(ARCHIVE_OK != (ret = read_bits_32( - a, rar, p, &add))) { - /* Return EOF if we - * can't read more - * data. */ - return ret; - } - - skip_bits(rar, dbits - 4); - add = (add >> ( - 36 - dbits)) << 4; - dist += add; - } - - if(ARCHIVE_OK != decode_number(a, - &rar->cstate.ldd, p, &low_dist)) - { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_PROGRAMMER, - "Failed to decode the " - "distance slot"); - - return ARCHIVE_FATAL; - } - - if(dist >= INT_MAX - low_dist - 1) { - /* This only happens in - * invalid archives. */ - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Distance pointer " - "overflow"); - return ARCHIVE_FATAL; - } - - dist += low_dist; - } else { - /* dbits is one of [0,1,2,3] */ - int add; - - if(ARCHIVE_OK != (ret = read_consume_bits(a, rar, - p, dbits, &add))) { - /* Return EOF if we can't read - * more data. */ - return ret; - } - - dist += add; - } - } - - if(dist > 0x100) { - len++; - - if(dist > 0x2000) { - len++; - - if(dist > 0x40000) { - len++; - } - } - } - - dist_cache_push(rar, dist); - rar->cstate.last_len = len; - - if(ARCHIVE_OK != copy_string(a, len, dist)) - return ARCHIVE_FATAL; - - continue; - } else if(num == 256) { - /* Create a filter. */ - ret = parse_filter(a, p); - if(ret != ARCHIVE_OK) - return ret; - - continue; - } else if(num == 257) { - if(rar->cstate.last_len != 0) { - if(ARCHIVE_OK != copy_string(a, - rar->cstate.last_len, - rar->cstate.dist_cache[0])) - { - return ARCHIVE_FATAL; - } - } - - continue; - } else { - /* num < 262 */ - const int idx = num - 258; - const int dist = dist_cache_touch(rar, idx); - - uint16_t len_slot; - int len; - - if(ARCHIVE_OK != decode_number(a, &rar->cstate.rd, p, - &len_slot)) { - return ARCHIVE_FATAL; - } - - len = decode_code_length(a, rar, p, len_slot); - if (len == -1) { - return ARCHIVE_FATAL; - } - - rar->cstate.last_len = len; - - if(ARCHIVE_OK != copy_string(a, len, dist)) - return ARCHIVE_FATAL; - - continue; - } - } - - return ARCHIVE_OK; -} - -/* Binary search for the RARv5 signature. */ -static int scan_for_signature(struct archive_read* a) { - const uint8_t* p; - const int chunk_size = 512; - ssize_t i; - char signature[sizeof(rar5_signature_xor)]; - - /* If we're here, it means we're on an 'unknown territory' data. - * There's no indication what kind of data we're reading here. - * It could be some text comment, any kind of binary data, - * digital sign, dragons, etc. - * - * We want to find a valid RARv5 magic header inside this unknown - * data. */ - - /* Is it possible in libarchive to just skip everything until the - * end of the file? If so, it would be a better approach than the - * current implementation of this function. */ - - rar5_signature(signature); - - while(1) { - if(!read_ahead(a, chunk_size, &p)) - return ARCHIVE_EOF; - - for(i = 0; i < chunk_size - (int)sizeof(rar5_signature_xor); - i++) { - if(memcmp(&p[i], signature, - sizeof(rar5_signature_xor)) == 0) { - /* Consume the number of bytes we've used to - * search for the signature, as well as the - * number of bytes used by the signature - * itself. After this we should be standing - * on a valid base block header. */ - (void) consume(a, - i + sizeof(rar5_signature_xor)); - return ARCHIVE_OK; - } - } - - consume(a, chunk_size); - } - - return ARCHIVE_FATAL; -} - -/* This function will switch the multivolume archive file to another file, - * i.e. from part03 to part 04. */ -static int advance_multivolume(struct archive_read* a) { - int lret; - struct rar5* rar = get_context(a); - - /* A small state machine that will skip unnecessary data, needed to - * switch from one multivolume to another. Such skipping is needed if - * we want to be an stream-oriented (instead of file-oriented) - * unpacker. - * - * The state machine starts with `rar->main.endarc` == 0. It also - * assumes that current stream pointer points to some base block - * header. - * - * The `endarc` field is being set when the base block parsing - * function encounters the 'end of archive' marker. - */ - - while(1) { - if(rar->main.endarc == 1) { - int looping = 1; - - rar->main.endarc = 0; - - while(looping) { - lret = skip_base_block(a); - switch(lret) { - case ARCHIVE_RETRY: - /* Continue looping. */ - break; - case ARCHIVE_OK: - /* Break loop. */ - looping = 0; - break; - default: - /* Forward any errors to the - * caller. */ - return lret; - } - } - - break; - } else { - /* Skip current base block. In order to properly skip - * it, we really need to simply parse it and discard - * the results. */ - - lret = skip_base_block(a); - if(lret == ARCHIVE_FATAL || lret == ARCHIVE_FAILED) - return lret; - - /* The `skip_base_block` function tells us if we - * should continue with skipping, or we should stop - * skipping. We're trying to skip everything up to - * a base FILE block. */ - - if(lret != ARCHIVE_RETRY) { - /* If there was an error during skipping, or we - * have just skipped a FILE base block... */ - - if(rar->main.endarc == 0) { - return lret; - } else { - continue; - } - } - } - } - - return ARCHIVE_OK; -} - -/* Merges the partial block from the first multivolume archive file, and - * partial block from the second multivolume archive file. The result is - * a chunk of memory containing the whole block, and the stream pointer - * is advanced to the next block in the second multivolume archive file. */ -static int merge_block(struct archive_read* a, ssize_t block_size, - const uint8_t** p) -{ - struct rar5* rar = get_context(a); - ssize_t cur_block_size, partial_offset = 0; - const uint8_t* lp; - int ret; - - if(rar->merge_mode) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, - "Recursive merge is not allowed"); - - return ARCHIVE_FATAL; - } - - /* Set a flag that we're in the switching mode. */ - rar->cstate.switch_multivolume = 1; - - /* Reallocate the memory which will hold the whole block. */ - if(rar->vol.push_buf) - free((void*) rar->vol.push_buf); - - /* Increasing the allocation block by 8 is due to bit reading functions, - * which are using additional 2 or 4 bytes. Allocating the block size - * by exact value would make bit reader perform reads from invalid - * memory block when reading the last byte from the buffer. */ - rar->vol.push_buf = malloc(block_size + 8); - if(!rar->vol.push_buf) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for a merge block buffer."); - return ARCHIVE_FATAL; - } - - /* Valgrind complains if the extension block for bit reader is not - * initialized, so initialize it. */ - memset(&rar->vol.push_buf[block_size], 0, 8); - - /* A single block can span across multiple multivolume archive files, - * so we use a loop here. This loop will consume enough multivolume - * archive files until the whole block is read. */ - - while(1) { - /* Get the size of current block chunk in this multivolume - * archive file and read it. */ - cur_block_size = rar5_min(rar->file.bytes_remaining, - block_size - partial_offset); - - if(cur_block_size == 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Encountered block size == 0 during block merge"); - return ARCHIVE_FATAL; - } - - if(!read_ahead(a, cur_block_size, &lp)) - return ARCHIVE_EOF; - - /* Sanity check; there should never be a situation where this - * function reads more data than the block's size. */ - if(partial_offset + cur_block_size > block_size) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_PROGRAMMER, - "Consumed too much data when merging blocks."); - return ARCHIVE_FATAL; - } - - /* Merge previous block chunk with current block chunk, - * or create first block chunk if this is our first - * iteration. */ - memcpy(&rar->vol.push_buf[partial_offset], lp, cur_block_size); - - /* Advance the stream read pointer by this block chunk size. */ - if(ARCHIVE_OK != consume(a, cur_block_size)) - return ARCHIVE_EOF; - - /* Update the pointers. `partial_offset` contains information - * about the sum of merged block chunks. */ - partial_offset += cur_block_size; - rar->file.bytes_remaining -= cur_block_size; - - /* If `partial_offset` is the same as `block_size`, this means - * we've merged all block chunks and we have a valid full - * block. */ - if(partial_offset == block_size) { - break; - } - - /* If we don't have any bytes to read, this means we should - * switch to another multivolume archive file. */ - if(rar->file.bytes_remaining == 0) { - rar->merge_mode++; - ret = advance_multivolume(a); - rar->merge_mode--; - if(ret != ARCHIVE_OK) { - return ret; - } - } - } - - *p = rar->vol.push_buf; - - /* If we're here, we can resume unpacking by processing the block - * pointed to by the `*p` memory pointer. */ - - return ARCHIVE_OK; -} - -static int process_block(struct archive_read* a) { - const uint8_t* p; - struct rar5* rar = get_context(a); - int ret; - - /* If we don't have any data to be processed, this most probably means - * we need to switch to the next volume. */ - if(rar->main.volume && rar->file.bytes_remaining == 0) { - ret = advance_multivolume(a); - if(ret != ARCHIVE_OK) - return ret; - } - - if(rar->cstate.block_parsing_finished) { - ssize_t block_size; - ssize_t to_skip; - ssize_t cur_block_size; - - /* The header size won't be bigger than 6 bytes. */ - if(!read_ahead(a, 6, &p)) { - /* Failed to prefetch data block header. */ - return ARCHIVE_EOF; - } - - /* - * Read block_size by parsing block header. Validate the header - * by calculating CRC byte stored inside the header. Size of - * the header is not constant (block size can be stored either - * in 1 or 2 bytes), that's why block size is left out from the - * `compressed_block_header` structure and returned by - * `parse_block_header` as the second argument. */ - - ret = parse_block_header(a, p, &block_size, - &rar->last_block_hdr); - if(ret != ARCHIVE_OK) { - return ret; - } - - /* Skip block header. Next data is huffman tables, - * if present. */ - to_skip = sizeof(struct compressed_block_header) + - bf_byte_count(&rar->last_block_hdr) + 1; - - if(ARCHIVE_OK != consume(a, to_skip)) - return ARCHIVE_EOF; - - rar->file.bytes_remaining -= to_skip; - - /* The block size gives information about the whole block size, - * but the block could be stored in split form when using - * multi-volume archives. In this case, the block size will be - * bigger than the actual data stored in this file. Remaining - * part of the data will be in another file. */ - - cur_block_size = - rar5_min(rar->file.bytes_remaining, block_size); - - if(block_size > rar->file.bytes_remaining) { - /* If current blocks' size is bigger than our data - * size, this means we have a multivolume archive. - * In this case, skip all base headers until the end - * of the file, proceed to next "partXXX.rar" volume, - * find its signature, skip all headers up to the first - * FILE base header, and continue from there. - * - * Note that `merge_block` will update the `rar` - * context structure quite extensively. */ - - ret = merge_block(a, block_size, &p); - if(ret != ARCHIVE_OK) { - return ret; - } - - cur_block_size = block_size; - - /* Current stream pointer should be now directly - * *after* the block that spanned through multiple - * archive files. `p` pointer should have the data of - * the *whole* block (merged from partial blocks - * stored in multiple archives files). */ - } else { - rar->cstate.switch_multivolume = 0; - - /* Read the whole block size into memory. This can take - * up to 8 megabytes of memory in theoretical cases. - * Might be worth to optimize this and use a standard - * chunk of 4kb's. */ - if(!read_ahead(a, 4 + cur_block_size, &p)) { - /* Failed to prefetch block data. */ - return ARCHIVE_EOF; - } - } - - rar->cstate.block_buf = p; - rar->cstate.cur_block_size = cur_block_size; - rar->cstate.block_parsing_finished = 0; - - rar->bits.in_addr = 0; - rar->bits.bit_addr = 0; - - if(bf_is_table_present(&rar->last_block_hdr)) { - /* Load Huffman tables. */ - ret = parse_tables(a, rar, p); - if(ret != ARCHIVE_OK) { - /* Error during decompression of Huffman - * tables. */ - return ret; - } - } - } else { - /* Block parsing not finished, reuse previous memory buffer. */ - p = rar->cstate.block_buf; - } - - /* Uncompress the block, or a part of it, depending on how many bytes - * will be generated by uncompressing the block. - * - * In case too many bytes will be generated, calling this function - * again will resume the uncompression operation. */ - ret = do_uncompress_block(a, p); - if(ret != ARCHIVE_OK) { - return ret; - } - - if(rar->cstate.block_parsing_finished && - rar->cstate.switch_multivolume == 0 && - rar->cstate.cur_block_size > 0) - { - /* If we're processing a normal block, consume the whole - * block. We can do this because we've already read the whole - * block to memory. */ - if(ARCHIVE_OK != consume(a, rar->cstate.cur_block_size)) - return ARCHIVE_FATAL; - - rar->file.bytes_remaining -= rar->cstate.cur_block_size; - } else if(rar->cstate.switch_multivolume) { - /* Don't consume the block if we're doing multivolume - * processing. The volume switching function will consume - * the proper count of bytes instead. */ - rar->cstate.switch_multivolume = 0; - } - - return ARCHIVE_OK; -} - -/* Pops the `buf`, `size` and `offset` from the "data ready" stack. - * - * Returns ARCHIVE_OK when those arguments can be used, ARCHIVE_RETRY - * when there is no data on the stack. */ -static int use_data(struct rar5* rar, const void** buf, size_t* size, - int64_t* offset) -{ - int i; - - for(i = 0; i < rar5_countof(rar->cstate.dready); i++) { - struct data_ready *d = &rar->cstate.dready[i]; - - if(d->used) { - if(buf) *buf = d->buf; - if(size) *size = d->size; - if(offset) *offset = d->offset; - - d->used = 0; - return ARCHIVE_OK; - } - } - - return ARCHIVE_RETRY; -} - -/* Pushes the `buf`, `size` and `offset` arguments to the rar->cstate.dready - * FIFO stack. Those values will be popped from this stack by the `use_data` - * function. */ -static int push_data_ready(struct archive_read* a, struct rar5* rar, - const uint8_t* buf, size_t size, int64_t offset) -{ - int i; - - /* Don't push if we're in skip mode. This is needed because solid - * streams need full processing even if we're skipping data. After - * fully processing the stream, we need to discard the generated bytes, - * because we're interested only in the side effect: building up the - * internal window circular buffer. This window buffer will be used - * later during unpacking of requested data. */ - if(rar->skip_mode) - return ARCHIVE_OK; - - /* Sanity check. */ - if(offset != rar->file.last_offset + rar->file.last_size) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, - "Sanity check error: output stream is not continuous"); - return ARCHIVE_FATAL; - } - - for(i = 0; i < rar5_countof(rar->cstate.dready); i++) { - struct data_ready* d = &rar->cstate.dready[i]; - if(!d->used) { - d->used = 1; - d->buf = buf; - d->size = size; - d->offset = offset; - - /* These fields are used only in sanity checking. */ - rar->file.last_offset = offset; - rar->file.last_size = size; - - /* Calculate the checksum of this new block before - * submitting data to libarchive's engine. */ - update_crc(rar, d->buf, d->size); - - return ARCHIVE_OK; - } - } - - /* Program counter will reach this code if the `rar->cstate.data_ready` - * stack will be filled up so that no new entries will be allowed. The - * code shouldn't allow such situation to occur. So we treat this case - * as an internal error. */ - - archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, - "Error: premature end of data_ready stack"); - return ARCHIVE_FATAL; -} - -/* This function uncompresses the data that is stored in the base - * block. - * - * The FILE base block looks like this: - * - *
    ... - * - * The
    is a block header, that is parsed in parse_block_header(). - * It's a "compressed_block_header" structure, containing metadata needed - * to know when we should stop looking for more blocks. - * - * contain data needed to set up the huffman tables, needed - * for the actual decompression. - * - * Each consists of series of literals: - * - * ... - * - * Those literals generate the uncompression data. They operate on a circular - * buffer, sometimes writing raw data into it, sometimes referencing - * some previous data inside this buffer, and sometimes declaring a filter - * that will need to be executed on the data stored in the circular buffer. - * It all depends on the literal that is used. - * - * Sometimes blocks produce output data, sometimes they don't. For example, for - * some huge files that use lots of filters, sometimes a block is filled with - * only filter declaration literals. Such blocks won't produce any data in the - * circular buffer. - * - * Sometimes blocks will produce 4 bytes of data, and sometimes 1 megabyte, - * because a literal can reference previously decompressed data. For example, - * there can be a literal that says: 'append a byte 0xFE here', and after - * it another literal can say 'append 1 megabyte of data from circular buffer - * offset 0x12345'. This is how RAR format handles compressing repeated - * patterns. - * - * The RAR compressor creates those literals and the actual efficiency of - * compression depends on what those literals are. The literals can also - * be seen as a kind of a non-turing-complete virtual machine that simply - * tells the decompressor what it should do. - * */ - -static int do_uncompress_file(struct archive_read* a) { - struct rar5* rar = get_context(a); - int ret; - int64_t max_end_pos; - - if(!rar->cstate.initialized) { - /* Don't perform full context reinitialization if we're - * processing a solid archive. */ - if(!rar->main.solid || !rar->cstate.window_buf) { - init_unpack(rar); - } - - rar->cstate.initialized = 1; - } - - /* Don't allow extraction if window_size is invalid. */ - if(rar->cstate.window_size == 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid window size declaration in this file"); - - /* This should never happen in valid files. */ - return ARCHIVE_FATAL; - } - - if(rar->cstate.all_filters_applied == 1) { - /* We use while(1) here, but standard case allows for just 1 - * iteration. The loop will iterate if process_block() didn't - * generate any data at all. This can happen if the block - * contains only filter definitions (this is common in big - * files). */ - while(1) { - ret = process_block(a); - if(ret == ARCHIVE_EOF || ret == ARCHIVE_FATAL) - return ret; - - if(rar->cstate.last_write_ptr == - rar->cstate.write_ptr) { - /* The block didn't generate any new data, - * so just process a new block. */ - continue; - } - - /* The block has generated some new data, so break - * the loop. */ - break; - } - } - - /* Try to run filters. If filters won't be applied, it means that - * insufficient data was generated. */ - ret = apply_filters(a); - if(ret == ARCHIVE_RETRY) { - return ARCHIVE_OK; - } else if(ret == ARCHIVE_FATAL) { - return ARCHIVE_FATAL; - } - - /* If apply_filters() will return ARCHIVE_OK, we can continue here. */ - - if(cdeque_size(&rar->cstate.filters) > 0) { - /* Check if we can write something before hitting first - * filter. */ - struct filter_info* flt; - - /* Get the block_start offset from the first filter. */ - if(CDE_OK != cdeque_front(&rar->cstate.filters, - cdeque_filter_p(&flt))) - { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_PROGRAMMER, - "Can't read first filter"); - return ARCHIVE_FATAL; - } - - max_end_pos = rar5_min(flt->block_start, - rar->cstate.write_ptr); - } else { - /* There are no filters defined, or all filters were applied. - * This means we can just store the data without any - * postprocessing. */ - max_end_pos = rar->cstate.write_ptr; - } - - if(max_end_pos == rar->cstate.last_write_ptr) { - /* We can't write anything yet. The block uncompression - * function did not generate enough data, and no filter can be - * applied. At the same time we don't have any data that can be - * stored without filter postprocessing. This means we need to - * wait for more data to be generated, so we can apply the - * filters. - * - * Signal the caller that we need more data to be able to do - * anything. - */ - return ARCHIVE_RETRY; - } else { - /* We can write the data before hitting the first filter. - * So let's do it. The push_window_data() function will - * effectively return the selected data block to the user - * application. */ - push_window_data(a, rar, rar->cstate.last_write_ptr, - max_end_pos); - rar->cstate.last_write_ptr = max_end_pos; - } - - return ARCHIVE_OK; -} - -static int uncompress_file(struct archive_read* a) { - int ret; - - while(1) { - /* Sometimes the uncompression function will return a - * 'retry' signal. If this will happen, we have to retry - * the function. */ - ret = do_uncompress_file(a); - if(ret != ARCHIVE_RETRY) - return ret; - } -} - - -static int do_unstore_file(struct archive_read* a, - struct rar5* rar, const void** buf, size_t* size, int64_t* offset) -{ - size_t to_read; - const uint8_t* p; - - if(rar->file.bytes_remaining == 0 && rar->main.volume > 0 && - rar->generic.split_after > 0) - { - int ret; - - rar->cstate.switch_multivolume = 1; - ret = advance_multivolume(a); - rar->cstate.switch_multivolume = 0; - - if(ret != ARCHIVE_OK) { - /* Failed to advance to next multivolume archive - * file. */ - return ret; - } - } - - to_read = rar5_min(rar->file.bytes_remaining, 64 * 1024); - if(to_read == 0) { - return ARCHIVE_EOF; - } - - if(!read_ahead(a, to_read, &p)) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "I/O error when unstoring file"); - return ARCHIVE_FATAL; - } - - if(ARCHIVE_OK != consume(a, to_read)) { - return ARCHIVE_EOF; - } - - if(buf) *buf = p; - if(size) *size = to_read; - if(offset) *offset = rar->cstate.last_unstore_ptr; - - rar->file.bytes_remaining -= to_read; - rar->cstate.last_unstore_ptr += to_read; - - update_crc(rar, p, to_read); - return ARCHIVE_OK; -} - -static int do_unpack(struct archive_read* a, struct rar5* rar, - const void** buf, size_t* size, int64_t* offset) -{ - enum COMPRESSION_METHOD { - STORE = 0, FASTEST = 1, FAST = 2, NORMAL = 3, GOOD = 4, - BEST = 5 - }; - - if(rar->file.service > 0) { - return do_unstore_file(a, rar, buf, size, offset); - } else { - switch(rar->cstate.method) { - case STORE: - return do_unstore_file(a, rar, buf, size, - offset); - case FASTEST: - /* fallthrough */ - case FAST: - /* fallthrough */ - case NORMAL: - /* fallthrough */ - case GOOD: - /* fallthrough */ - case BEST: - /* No data is returned here. But because a sparse-file aware - * caller (like archive_read_data_into_fd) may treat zero-size - * as a sparse file block, we need to update the offset - * accordingly. At this point the decoder doesn't have any - * pending uncompressed data blocks, so the current position in - * the output file should be last_write_ptr. */ - if (offset) *offset = rar->cstate.last_write_ptr; - return uncompress_file(a); - default: - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Compression method not supported: 0x%x", - rar->cstate.method); - - return ARCHIVE_FATAL; - } - } - -#if !defined WIN32 - /* Not reached. */ - return ARCHIVE_OK; -#endif -} - -static int verify_checksums(struct archive_read* a) { - int verify_crc; - struct rar5* rar = get_context(a); - - /* Check checksums only when actually unpacking the data. There's no - * need to calculate checksum when we're skipping data in solid archives - * (skipping in solid archives is the same thing as unpacking compressed - * data and discarding the result). */ - - if(!rar->skip_mode) { - /* Always check checksums if we're not in skip mode */ - verify_crc = 1; - } else { - /* We can override the logic above with a compile-time option - * NO_CRC_ON_SOLID_SKIP. This option is used during debugging, - * and it will check checksums of unpacked data even when - * we're skipping it. */ - -#if defined CHECK_CRC_ON_SOLID_SKIP - /* Debug case */ - verify_crc = 1; -#else - /* Normal case */ - verify_crc = 0; -#endif - } - - if(verify_crc) { - /* During unpacking, on each unpacked block we're calling the - * update_crc() function. Since we are here, the unpacking - * process is already over and we can check if calculated - * checksum (CRC32 or BLAKE2sp) is the same as what is stored - * in the archive. */ - if(rar->file.stored_crc32 > 0) { - /* Check CRC32 only when the file contains a CRC32 - * value for this file. */ - - if(rar->file.calculated_crc32 != - rar->file.stored_crc32) { - /* Checksums do not match; the unpacked file - * is corrupted. */ - - DEBUG_CODE { - printf("Checksum error: CRC32 " - "(was: %08" PRIx32 ", expected: %08" PRIx32 ")\n", - rar->file.calculated_crc32, - rar->file.stored_crc32); - } - -#ifndef DONT_FAIL_ON_CRC_ERROR - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Checksum error: CRC32"); - return ARCHIVE_FATAL; -#endif - } else { - DEBUG_CODE { - printf("Checksum OK: CRC32 " - "(%08" PRIx32 "/%08" PRIx32 ")\n", - rar->file.stored_crc32, - rar->file.calculated_crc32); - } - } - } - - if(rar->file.has_blake2 > 0) { - /* BLAKE2sp is an optional checksum algorithm that is - * added to RARv5 archives when using the `-htb` switch - * during creation of archive. - * - * We now finalize the hash calculation by calling the - * `final` function. This will generate the final hash - * value we can use to compare it with the BLAKE2sp - * checksum that is stored in the archive. - * - * The return value of this `final` function is not - * very helpful, as it guards only against improper use. - * This is why we're explicitly ignoring it. */ - - uint8_t b2_buf[32]; - (void) blake2sp_final(&rar->file.b2state, b2_buf, 32); - - if(memcmp(&rar->file.blake2sp, b2_buf, 32) != 0) { -#ifndef DONT_FAIL_ON_CRC_ERROR - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Checksum error: BLAKE2"); - - return ARCHIVE_FATAL; -#endif - } - } - } - - /* Finalization for this file has been successfully completed. */ - return ARCHIVE_OK; -} - -static int verify_global_checksums(struct archive_read* a) { - return verify_checksums(a); -} - -/* - * Decryption function for the magic signature pattern. Check the comment near - * the `rar5_signature_xor` symbol to read the rationale behind this. - */ -static void rar5_signature(char *buf) { - size_t i; - - for(i = 0; i < sizeof(rar5_signature_xor); i++) { - buf[i] = rar5_signature_xor[i] ^ 0xA1; - } -} - -static int rar5_read_data(struct archive_read *a, const void **buff, - size_t *size, int64_t *offset) { - int ret; - struct rar5* rar = get_context(a); - - if (size) - *size = 0; - - if(rar->file.dir > 0) { - /* Don't process any data if this file entry was declared - * as a directory. This is needed, because entries marked as - * directory doesn't have any dictionary buffer allocated, so - * it's impossible to perform any decompression. */ - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Can't decompress an entry marked as a directory"); - return ARCHIVE_FAILED; - } - - if(!rar->skip_mode && (rar->cstate.last_write_ptr > rar->file.unpacked_size)) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, - "Unpacker has written too many bytes"); - return ARCHIVE_FATAL; - } - - ret = use_data(rar, buff, size, offset); - if(ret == ARCHIVE_OK) { - return ret; - } - - if(rar->file.eof == 1) { - return ARCHIVE_EOF; - } - - ret = do_unpack(a, rar, buff, size, offset); - if(ret != ARCHIVE_OK) { - return ret; - } - - if(rar->file.bytes_remaining == 0 && - rar->cstate.last_write_ptr == rar->file.unpacked_size) - { - /* If all bytes of current file were processed, run - * finalization. - * - * Finalization will check checksum against proper values. If - * some of the checksums will not match, we'll return an error - * value in the last `archive_read_data` call to signal an error - * to the user. */ - - rar->file.eof = 1; - return verify_global_checksums(a); - } - - return ARCHIVE_OK; -} - -static int rar5_read_data_skip(struct archive_read *a) { - struct rar5* rar = get_context(a); - - if(rar->main.solid) { - /* In solid archives, instead of skipping the data, we need to - * extract it, and dispose the result. The side effect of this - * operation will be setting up the initial window buffer state - * needed to be able to extract the selected file. */ - - int ret; - - /* Make sure to process all blocks in the compressed stream. */ - while(rar->file.bytes_remaining > 0) { - /* Setting the "skip mode" will allow us to skip - * checksum checks during data skipping. Checking the - * checksum of skipped data isn't really necessary and - * it's only slowing things down. - * - * This is incremented instead of setting to 1 because - * this data skipping function can be called - * recursively. */ - rar->skip_mode++; - - /* We're disposing 1 block of data, so we use triple - * NULLs in arguments. */ - ret = rar5_read_data(a, NULL, NULL, NULL); - - /* Turn off "skip mode". */ - rar->skip_mode--; - - if(ret < 0 || ret == ARCHIVE_EOF) { - /* Propagate any potential error conditions - * to the caller. */ - return ret; - } - } - } else { - /* In standard archives, we can just jump over the compressed - * stream. Each file in non-solid archives starts from an empty - * window buffer. */ - - if(ARCHIVE_OK != consume(a, rar->file.bytes_remaining)) { - return ARCHIVE_FATAL; - } - - rar->file.bytes_remaining = 0; - } - - return ARCHIVE_OK; -} - -static int64_t rar5_seek_data(struct archive_read *a, int64_t offset, - int whence) -{ - (void) a; - (void) offset; - (void) whence; - - /* We're a streaming unpacker, and we don't support seeking. */ - - return ARCHIVE_FATAL; -} - -static int rar5_cleanup(struct archive_read *a) { - struct rar5* rar = get_context(a); - - free(rar->cstate.window_buf); - free(rar->cstate.filtered_buf); - - free(rar->vol.push_buf); - - free_filters(rar); - cdeque_free(&rar->cstate.filters); - - free(rar); - a->format->data = NULL; - - return ARCHIVE_OK; -} - -static int rar5_capabilities(struct archive_read * a) { - (void) a; - return 0; -} - -static int rar5_has_encrypted_entries(struct archive_read *_a) { - (void) _a; - - /* Unsupported for now. */ - return ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED; -} - -static int rar5_init(struct rar5* rar) { - memset(rar, 0, sizeof(struct rar5)); - - if(CDE_OK != cdeque_init(&rar->cstate.filters, 8192)) - return ARCHIVE_FATAL; - - return ARCHIVE_OK; -} - -int archive_read_support_format_rar5(struct archive *_a) { - struct archive_read* ar; - int ret; - struct rar5* rar; - - if(ARCHIVE_OK != (ret = get_archive_read(_a, &ar))) - return ret; - - rar = malloc(sizeof(*rar)); - if(rar == NULL) { - archive_set_error(&ar->archive, ENOMEM, - "Can't allocate rar5 data"); - return ARCHIVE_FATAL; - } - - if(ARCHIVE_OK != rar5_init(rar)) { - archive_set_error(&ar->archive, ENOMEM, - "Can't allocate rar5 filter buffer"); - free(rar); - return ARCHIVE_FATAL; - } - - ret = __archive_read_register_format(ar, - rar, - "rar5", - rar5_bid, - rar5_options, - rar5_read_header, - rar5_read_data, - rar5_read_data_skip, - rar5_seek_data, - rar5_cleanup, - rar5_capabilities, - rar5_has_encrypted_entries); - - if(ret != ARCHIVE_OK) { - (void) rar5_cleanup(ar); - } - - return ret; -} diff --git a/thirdparty/libarchive/libarchive/archive_read_support_format_raw.c b/thirdparty/libarchive/libarchive/archive_read_support_format_raw.c deleted file mode 100644 index ec0520b60..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_format_raw.c +++ /dev/null @@ -1,192 +0,0 @@ -/*- - * Copyright (c) 2003-2009 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_raw.c 201107 2009-12-28 03:25:33Z kientzle $"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" -#include "archive_private.h" -#include "archive_read_private.h" - -struct raw_info { - int64_t offset; /* Current position in the file. */ - int64_t unconsumed; - int end_of_file; -}; - -static int archive_read_format_raw_bid(struct archive_read *, int); -static int archive_read_format_raw_cleanup(struct archive_read *); -static int archive_read_format_raw_read_data(struct archive_read *, - const void **, size_t *, int64_t *); -static int archive_read_format_raw_read_data_skip(struct archive_read *); -static int archive_read_format_raw_read_header(struct archive_read *, - struct archive_entry *); - -int -archive_read_support_format_raw(struct archive *_a) -{ - struct raw_info *info; - struct archive_read *a = (struct archive_read *)_a; - int r; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_format_raw"); - - info = (struct raw_info *)calloc(1, sizeof(*info)); - if (info == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate raw_info data"); - return (ARCHIVE_FATAL); - } - - r = __archive_read_register_format(a, - info, - "raw", - archive_read_format_raw_bid, - NULL, - archive_read_format_raw_read_header, - archive_read_format_raw_read_data, - archive_read_format_raw_read_data_skip, - NULL, - archive_read_format_raw_cleanup, - NULL, - NULL); - if (r != ARCHIVE_OK) - free(info); - return (r); -} - -/* - * Bid 1 if this is a non-empty file. Anyone who can really support - * this should outbid us, so it should generally be safe to use "raw" - * in conjunction with other formats. But, this could really confuse - * folks if there are bid errors or minor file damage, so we don't - * include "raw" as part of support_format_all(). - */ -static int -archive_read_format_raw_bid(struct archive_read *a, int best_bid) -{ - if (best_bid < 1 && __archive_read_ahead(a, 1, NULL) != NULL) - return (1); - return (-1); -} - -/* - * Mock up a fake header. - */ -static int -archive_read_format_raw_read_header(struct archive_read *a, - struct archive_entry *entry) -{ - struct raw_info *info; - - info = (struct raw_info *)(a->format->data); - if (info->end_of_file) - return (ARCHIVE_EOF); - - a->archive.archive_format = ARCHIVE_FORMAT_RAW; - a->archive.archive_format_name = "raw"; - archive_entry_set_pathname(entry, "data"); - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_perm(entry, 0644); - /* I'm deliberately leaving most fields unset here. */ - - /* Let the filter fill out any fields it might have. */ - return __archive_read_header(a, entry); -} - -static int -archive_read_format_raw_read_data(struct archive_read *a, - const void **buff, size_t *size, int64_t *offset) -{ - struct raw_info *info; - ssize_t avail; - - info = (struct raw_info *)(a->format->data); - - /* Consume the bytes we read last time. */ - if (info->unconsumed) { - __archive_read_consume(a, info->unconsumed); - info->unconsumed = 0; - } - - if (info->end_of_file) - return (ARCHIVE_EOF); - - /* Get whatever bytes are immediately available. */ - *buff = __archive_read_ahead(a, 1, &avail); - if (avail > 0) { - /* Return the bytes we just read */ - *size = avail; - *offset = info->offset; - info->offset += *size; - info->unconsumed = avail; - return (ARCHIVE_OK); - } else if (0 == avail) { - /* Record and return end-of-file. */ - info->end_of_file = 1; - *size = 0; - *offset = info->offset; - return (ARCHIVE_EOF); - } else { - /* Record and return an error. */ - *size = 0; - *offset = info->offset; - return ((int)avail); - } -} - -static int -archive_read_format_raw_read_data_skip(struct archive_read *a) -{ - struct raw_info *info = (struct raw_info *)(a->format->data); - - /* Consume the bytes we read last time. */ - if (info->unconsumed) { - __archive_read_consume(a, info->unconsumed); - info->unconsumed = 0; - } - info->end_of_file = 1; - return (ARCHIVE_OK); -} - -static int -archive_read_format_raw_cleanup(struct archive_read *a) -{ - struct raw_info *info; - - info = (struct raw_info *)(a->format->data); - free(info); - a->format->data = NULL; - return (ARCHIVE_OK); -} diff --git a/thirdparty/libarchive/libarchive/archive_read_support_format_tar.c b/thirdparty/libarchive/libarchive/archive_read_support_format_tar.c deleted file mode 100644 index 93c3fd585..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_format_tar.c +++ /dev/null @@ -1,2946 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2011-2012 Michihiro NAKAJIMA - * Copyright (c) 2016 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_tar.c 201161 2009-12-29 05:44:39Z kientzle $"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "archive.h" -#include "archive_acl_private.h" /* For ACL parsing routines. */ -#include "archive_entry.h" -#include "archive_entry_locale.h" -#include "archive_private.h" -#include "archive_read_private.h" - -#define tar_min(a,b) ((a) < (b) ? (a) : (b)) - -/* - * Layout of POSIX 'ustar' tar header. - */ -struct archive_entry_header_ustar { - char name[100]; - char mode[8]; - char uid[8]; - char gid[8]; - char size[12]; - char mtime[12]; - char checksum[8]; - char typeflag[1]; - char linkname[100]; /* "old format" header ends here */ - char magic[6]; /* For POSIX: "ustar\0" */ - char version[2]; /* For POSIX: "00" */ - char uname[32]; - char gname[32]; - char rdevmajor[8]; - char rdevminor[8]; - char prefix[155]; -}; - -/* - * Structure of GNU tar header - */ -struct gnu_sparse { - char offset[12]; - char numbytes[12]; -}; - -struct archive_entry_header_gnutar { - char name[100]; - char mode[8]; - char uid[8]; - char gid[8]; - char size[12]; - char mtime[12]; - char checksum[8]; - char typeflag[1]; - char linkname[100]; - char magic[8]; /* "ustar \0" (note blank/blank/null at end) */ - char uname[32]; - char gname[32]; - char rdevmajor[8]; - char rdevminor[8]; - char atime[12]; - char ctime[12]; - char offset[12]; - char longnames[4]; - char unused[1]; - struct gnu_sparse sparse[4]; - char isextended[1]; - char realsize[12]; - /* - * Old GNU format doesn't use POSIX 'prefix' field; they use - * the 'L' (longname) entry instead. - */ -}; - -/* - * Data specific to this format. - */ -struct sparse_block { - struct sparse_block *next; - int64_t offset; - int64_t remaining; - int hole; -}; - -struct tar { - struct archive_string acl_text; - struct archive_string entry_pathname; - /* For "GNU.sparse.name" and other similar path extensions. */ - struct archive_string entry_pathname_override; - struct archive_string entry_linkpath; - struct archive_string entry_uname; - struct archive_string entry_gname; - struct archive_string longlink; - struct archive_string longname; - struct archive_string pax_header; - struct archive_string pax_global; - struct archive_string line; - int pax_hdrcharset_binary; - int header_recursion_depth; - int64_t entry_bytes_remaining; - int64_t entry_offset; - int64_t entry_padding; - int64_t entry_bytes_unconsumed; - int64_t realsize; - int sparse_allowed; - struct sparse_block *sparse_list; - struct sparse_block *sparse_last; - int64_t sparse_offset; - int64_t sparse_numbytes; - int sparse_gnu_major; - int sparse_gnu_minor; - char sparse_gnu_pending; - - struct archive_string localname; - struct archive_string_conv *opt_sconv; - struct archive_string_conv *sconv; - struct archive_string_conv *sconv_acl; - struct archive_string_conv *sconv_default; - int init_default_conversion; - int compat_2x; - int process_mac_extensions; - int read_concatenated_archives; - int realsize_override; -}; - -static int archive_block_is_null(const char *p); -static char *base64_decode(const char *, size_t, size_t *); -static int gnu_add_sparse_entry(struct archive_read *, struct tar *, - int64_t offset, int64_t remaining); - -static void gnu_clear_sparse_list(struct tar *); -static int gnu_sparse_old_read(struct archive_read *, struct tar *, - const struct archive_entry_header_gnutar *header, size_t *); -static int gnu_sparse_old_parse(struct archive_read *, struct tar *, - const struct gnu_sparse *sparse, int length); -static int gnu_sparse_01_parse(struct archive_read *, struct tar *, - const char *); -static ssize_t gnu_sparse_10_read(struct archive_read *, struct tar *, - size_t *); -static int header_Solaris_ACL(struct archive_read *, struct tar *, - struct archive_entry *, const void *, size_t *); -static int header_common(struct archive_read *, struct tar *, - struct archive_entry *, const void *); -static int header_old_tar(struct archive_read *, struct tar *, - struct archive_entry *, const void *); -static int header_pax_extensions(struct archive_read *, struct tar *, - struct archive_entry *, const void *, size_t *); -static int header_pax_global(struct archive_read *, struct tar *, - struct archive_entry *, const void *h, size_t *); -static int header_longlink(struct archive_read *, struct tar *, - struct archive_entry *, const void *h, size_t *); -static int header_longname(struct archive_read *, struct tar *, - struct archive_entry *, const void *h, size_t *); -static int read_mac_metadata_blob(struct archive_read *, struct tar *, - struct archive_entry *, const void *h, size_t *); -static int header_volume(struct archive_read *, struct tar *, - struct archive_entry *, const void *h, size_t *); -static int header_ustar(struct archive_read *, struct tar *, - struct archive_entry *, const void *h); -static int header_gnutar(struct archive_read *, struct tar *, - struct archive_entry *, const void *h, size_t *); -static int archive_read_format_tar_bid(struct archive_read *, int); -static int archive_read_format_tar_options(struct archive_read *, - const char *, const char *); -static int archive_read_format_tar_cleanup(struct archive_read *); -static int archive_read_format_tar_read_data(struct archive_read *a, - const void **buff, size_t *size, int64_t *offset); -static int archive_read_format_tar_skip(struct archive_read *a); -static int archive_read_format_tar_read_header(struct archive_read *, - struct archive_entry *); -static int checksum(struct archive_read *, const void *); -static int pax_attribute(struct archive_read *, struct tar *, - struct archive_entry *, const char *key, const char *value, - size_t value_length); -static int pax_attribute_acl(struct archive_read *, struct tar *, - struct archive_entry *, const char *, int); -static int pax_attribute_xattr(struct archive_entry *, const char *, - const char *); -static int pax_header(struct archive_read *, struct tar *, - struct archive_entry *, struct archive_string *); -static void pax_time(const char *, int64_t *sec, long *nanos); -static ssize_t readline(struct archive_read *, struct tar *, const char **, - ssize_t limit, size_t *); -static int read_body_to_string(struct archive_read *, struct tar *, - struct archive_string *, const void *h, size_t *); -static int solaris_sparse_parse(struct archive_read *, struct tar *, - struct archive_entry *, const char *); -static int64_t tar_atol(const char *, size_t); -static int64_t tar_atol10(const char *, size_t); -static int64_t tar_atol256(const char *, size_t); -static int64_t tar_atol8(const char *, size_t); -static int tar_read_header(struct archive_read *, struct tar *, - struct archive_entry *, size_t *); -static int tohex(int c); -static char *url_decode(const char *); -static void tar_flush_unconsumed(struct archive_read *, size_t *); - - -int -archive_read_support_format_gnutar(struct archive *a) -{ - archive_check_magic(a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_format_gnutar"); - return (archive_read_support_format_tar(a)); -} - - -int -archive_read_support_format_tar(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - struct tar *tar; - int r; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_format_tar"); - - tar = (struct tar *)calloc(1, sizeof(*tar)); - if (tar == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate tar data"); - return (ARCHIVE_FATAL); - } -#ifdef HAVE_COPYFILE_H - /* Set this by default on Mac OS. */ - tar->process_mac_extensions = 1; -#endif - - r = __archive_read_register_format(a, tar, "tar", - archive_read_format_tar_bid, - archive_read_format_tar_options, - archive_read_format_tar_read_header, - archive_read_format_tar_read_data, - archive_read_format_tar_skip, - NULL, - archive_read_format_tar_cleanup, - NULL, - NULL); - - if (r != ARCHIVE_OK) - free(tar); - return (ARCHIVE_OK); -} - -static int -archive_read_format_tar_cleanup(struct archive_read *a) -{ - struct tar *tar; - - tar = (struct tar *)(a->format->data); - gnu_clear_sparse_list(tar); - archive_string_free(&tar->acl_text); - archive_string_free(&tar->entry_pathname); - archive_string_free(&tar->entry_pathname_override); - archive_string_free(&tar->entry_linkpath); - archive_string_free(&tar->entry_uname); - archive_string_free(&tar->entry_gname); - archive_string_free(&tar->line); - archive_string_free(&tar->pax_global); - archive_string_free(&tar->pax_header); - archive_string_free(&tar->longname); - archive_string_free(&tar->longlink); - archive_string_free(&tar->localname); - free(tar); - (a->format->data) = NULL; - return (ARCHIVE_OK); -} - -/* - * Validate number field - * - * This has to be pretty lenient in order to accommodate the enormous - * variety of tar writers in the world: - * = POSIX (IEEE Std 1003.1-1988) ustar requires octal values with leading - * zeros and allows fields to be terminated with space or null characters - * = Many writers use different termination (in particular, libarchive - * omits terminator bytes to squeeze one or two more digits) - * = Many writers pad with space and omit leading zeros - * = GNU tar and star write base-256 values if numbers are too - * big to be represented in octal - * - * Examples of specific tar headers that we should support: - * = Perl Archive::Tar terminates uid, gid, devminor and devmajor with two - * null bytes, pads size with spaces and other numeric fields with zeroes - * = plexus-archiver prior to 2.6.3 (before switching to commons-compress) - * may have uid and gid fields filled with spaces without any octal digits - * at all and pads all numeric fields with spaces - * - * This should tolerate all variants in use. It will reject a field - * where the writer just left garbage after a trailing NUL. - */ -static int -validate_number_field(const char* p_field, size_t i_size) -{ - unsigned char marker = (unsigned char)p_field[0]; - if (marker == 128 || marker == 255 || marker == 0) { - /* Base-256 marker, there's nothing we can check. */ - return 1; - } else { - /* Must be octal */ - size_t i = 0; - /* Skip any leading spaces */ - while (i < i_size && p_field[i] == ' ') { - ++i; - } - /* Skip octal digits. */ - while (i < i_size && p_field[i] >= '0' && p_field[i] <= '7') { - ++i; - } - /* Any remaining characters must be space or NUL padding. */ - while (i < i_size) { - if (p_field[i] != ' ' && p_field[i] != 0) { - return 0; - } - ++i; - } - return 1; - } -} - -static int -archive_read_format_tar_bid(struct archive_read *a, int best_bid) -{ - int bid; - const char *h; - const struct archive_entry_header_ustar *header; - - (void)best_bid; /* UNUSED */ - - bid = 0; - - /* Now let's look at the actual header and see if it matches. */ - h = __archive_read_ahead(a, 512, NULL); - if (h == NULL) - return (-1); - - /* If it's an end-of-archive mark, we can handle it. */ - if (h[0] == 0 && archive_block_is_null(h)) { - /* - * Usually, I bid the number of bits verified, but - * in this case, 4096 seems excessive so I picked 10 as - * an arbitrary but reasonable-seeming value. - */ - return (10); - } - - /* If it's not an end-of-archive mark, it must have a valid checksum.*/ - if (!checksum(a, h)) - return (0); - bid += 48; /* Checksum is usually 6 octal digits. */ - - header = (const struct archive_entry_header_ustar *)h; - - /* Recognize POSIX formats. */ - if ((memcmp(header->magic, "ustar\0", 6) == 0) - && (memcmp(header->version, "00", 2) == 0)) - bid += 56; - - /* Recognize GNU tar format. */ - if ((memcmp(header->magic, "ustar ", 6) == 0) - && (memcmp(header->version, " \0", 2) == 0)) - bid += 56; - - /* Type flag must be null, digit or A-Z, a-z. */ - if (header->typeflag[0] != 0 && - !( header->typeflag[0] >= '0' && header->typeflag[0] <= '9') && - !( header->typeflag[0] >= 'A' && header->typeflag[0] <= 'Z') && - !( header->typeflag[0] >= 'a' && header->typeflag[0] <= 'z') ) - return (0); - bid += 2; /* 6 bits of variation in an 8-bit field leaves 2 bits. */ - - /* - * Check format of mode/uid/gid/mtime/size/rdevmajor/rdevminor fields. - */ - if (validate_number_field(header->mode, sizeof(header->mode)) == 0 - || validate_number_field(header->uid, sizeof(header->uid)) == 0 - || validate_number_field(header->gid, sizeof(header->gid)) == 0 - || validate_number_field(header->mtime, sizeof(header->mtime)) == 0 - || validate_number_field(header->size, sizeof(header->size)) == 0 - || validate_number_field(header->rdevmajor, sizeof(header->rdevmajor)) == 0 - || validate_number_field(header->rdevminor, sizeof(header->rdevminor)) == 0) { - bid = 0; - } - - return (bid); -} - -static int -archive_read_format_tar_options(struct archive_read *a, - const char *key, const char *val) -{ - struct tar *tar; - int ret = ARCHIVE_FAILED; - - tar = (struct tar *)(a->format->data); - if (strcmp(key, "compat-2x") == 0) { - /* Handle UTF-8 filenames as libarchive 2.x */ - tar->compat_2x = (val != NULL && val[0] != 0); - tar->init_default_conversion = tar->compat_2x; - return (ARCHIVE_OK); - } else if (strcmp(key, "hdrcharset") == 0) { - if (val == NULL || val[0] == 0) - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "tar: hdrcharset option needs a character-set name"); - else { - tar->opt_sconv = - archive_string_conversion_from_charset( - &a->archive, val, 0); - if (tar->opt_sconv != NULL) - ret = ARCHIVE_OK; - else - ret = ARCHIVE_FATAL; - } - return (ret); - } else if (strcmp(key, "mac-ext") == 0) { - tar->process_mac_extensions = (val != NULL && val[0] != 0); - return (ARCHIVE_OK); - } else if (strcmp(key, "read_concatenated_archives") == 0) { - tar->read_concatenated_archives = (val != NULL && val[0] != 0); - return (ARCHIVE_OK); - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -/* utility function- this exists to centralize the logic of tracking - * how much unconsumed data we have floating around, and to consume - * anything outstanding since we're going to do read_aheads - */ -static void -tar_flush_unconsumed(struct archive_read *a, size_t *unconsumed) -{ - if (*unconsumed) { -/* - void *data = (void *)__archive_read_ahead(a, *unconsumed, NULL); - * this block of code is to poison claimed unconsumed space, ensuring - * things break if it is in use still. - * currently it WILL break things, so enable it only for debugging this issue - if (data) { - memset(data, 0xff, *unconsumed); - } -*/ - __archive_read_consume(a, *unconsumed); - *unconsumed = 0; - } -} - -/* - * The function invoked by archive_read_next_header(). This - * just sets up a few things and then calls the internal - * tar_read_header() function below. - */ -static int -archive_read_format_tar_read_header(struct archive_read *a, - struct archive_entry *entry) -{ - /* - * When converting tar archives to cpio archives, it is - * essential that each distinct file have a distinct inode - * number. To simplify this, we keep a static count here to - * assign fake dev/inode numbers to each tar entry. Note that - * pax format archives may overwrite this with something more - * useful. - * - * Ideally, we would track every file read from the archive so - * that we could assign the same dev/ino pair to hardlinks, - * but the memory required to store a complete lookup table is - * probably not worthwhile just to support the relatively - * obscure tar->cpio conversion case. - */ - static int default_inode; - static int default_dev; - struct tar *tar; - const char *p; - const wchar_t *wp; - int r; - size_t l, unconsumed = 0; - - /* Assign default device/inode values. */ - archive_entry_set_dev(entry, 1 + default_dev); /* Don't use zero. */ - archive_entry_set_ino(entry, ++default_inode); /* Don't use zero. */ - /* Limit generated st_ino number to 16 bits. */ - if (default_inode >= 0xffff) { - ++default_dev; - default_inode = 0; - } - - tar = (struct tar *)(a->format->data); - tar->entry_offset = 0; - gnu_clear_sparse_list(tar); - tar->realsize = -1; /* Mark this as "unset" */ - tar->realsize_override = 0; - - /* Setup default string conversion. */ - tar->sconv = tar->opt_sconv; - if (tar->sconv == NULL) { - if (!tar->init_default_conversion) { - tar->sconv_default = - archive_string_default_conversion_for_read(&(a->archive)); - tar->init_default_conversion = 1; - } - tar->sconv = tar->sconv_default; - } - - r = tar_read_header(a, tar, entry, &unconsumed); - - tar_flush_unconsumed(a, &unconsumed); - - /* - * "non-sparse" files are really just sparse files with - * a single block. - */ - if (tar->sparse_list == NULL) { - if (gnu_add_sparse_entry(a, tar, 0, tar->entry_bytes_remaining) - != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } else { - struct sparse_block *sb; - - for (sb = tar->sparse_list; sb != NULL; sb = sb->next) { - if (!sb->hole) - archive_entry_sparse_add_entry(entry, - sb->offset, sb->remaining); - } - } - - if (r == ARCHIVE_OK && archive_entry_filetype(entry) == AE_IFREG) { - /* - * "Regular" entry with trailing '/' is really - * directory: This is needed for certain old tar - * variants and even for some broken newer ones. - */ - if ((wp = archive_entry_pathname_w(entry)) != NULL) { - l = wcslen(wp); - if (l > 0 && wp[l - 1] == L'/') { - archive_entry_set_filetype(entry, AE_IFDIR); - tar->entry_bytes_remaining = 0; - tar->entry_padding = 0; - } - } else if ((p = archive_entry_pathname(entry)) != NULL) { - l = strlen(p); - if (l > 0 && p[l - 1] == '/') { - archive_entry_set_filetype(entry, AE_IFDIR); - tar->entry_bytes_remaining = 0; - tar->entry_padding = 0; - } - } - } - return (r); -} - -static int -archive_read_format_tar_read_data(struct archive_read *a, - const void **buff, size_t *size, int64_t *offset) -{ - ssize_t bytes_read; - struct tar *tar; - struct sparse_block *p; - - tar = (struct tar *)(a->format->data); - - for (;;) { - /* Remove exhausted entries from sparse list. */ - while (tar->sparse_list != NULL && - tar->sparse_list->remaining == 0) { - p = tar->sparse_list; - tar->sparse_list = p->next; - free(p); - } - - if (tar->entry_bytes_unconsumed) { - __archive_read_consume(a, tar->entry_bytes_unconsumed); - tar->entry_bytes_unconsumed = 0; - } - - /* If we're at end of file, return EOF. */ - if (tar->sparse_list == NULL || - tar->entry_bytes_remaining == 0) { - if (__archive_read_consume(a, tar->entry_padding) < 0) - return (ARCHIVE_FATAL); - tar->entry_padding = 0; - *buff = NULL; - *size = 0; - *offset = tar->realsize; - return (ARCHIVE_EOF); - } - - *buff = __archive_read_ahead(a, 1, &bytes_read); - if (bytes_read < 0) - return (ARCHIVE_FATAL); - if (*buff == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Truncated tar archive"); - return (ARCHIVE_FATAL); - } - if (bytes_read > tar->entry_bytes_remaining) - bytes_read = (ssize_t)tar->entry_bytes_remaining; - /* Don't read more than is available in the - * current sparse block. */ - if (tar->sparse_list->remaining < bytes_read) - bytes_read = (ssize_t)tar->sparse_list->remaining; - *size = bytes_read; - *offset = tar->sparse_list->offset; - tar->sparse_list->remaining -= bytes_read; - tar->sparse_list->offset += bytes_read; - tar->entry_bytes_remaining -= bytes_read; - tar->entry_bytes_unconsumed = bytes_read; - - if (!tar->sparse_list->hole) - return (ARCHIVE_OK); - /* Current is hole data and skip this. */ - } -} - -static int -archive_read_format_tar_skip(struct archive_read *a) -{ - int64_t bytes_skipped; - int64_t request; - struct sparse_block *p; - struct tar* tar; - - tar = (struct tar *)(a->format->data); - - /* Do not consume the hole of a sparse file. */ - request = 0; - for (p = tar->sparse_list; p != NULL; p = p->next) { - if (!p->hole) { - if (p->remaining >= INT64_MAX - request) { - return ARCHIVE_FATAL; - } - request += p->remaining; - } - } - if (request > tar->entry_bytes_remaining) - request = tar->entry_bytes_remaining; - request += tar->entry_padding + tar->entry_bytes_unconsumed; - - bytes_skipped = __archive_read_consume(a, request); - if (bytes_skipped < 0) - return (ARCHIVE_FATAL); - - tar->entry_bytes_remaining = 0; - tar->entry_bytes_unconsumed = 0; - tar->entry_padding = 0; - - /* Free the sparse list. */ - gnu_clear_sparse_list(tar); - - return (ARCHIVE_OK); -} - -/* - * This function recursively interprets all of the headers associated - * with a single entry. - */ -static int -tar_read_header(struct archive_read *a, struct tar *tar, - struct archive_entry *entry, size_t *unconsumed) -{ - ssize_t bytes; - int err, eof_vol_header; - const char *h; - const struct archive_entry_header_ustar *header; - const struct archive_entry_header_gnutar *gnuheader; - - eof_vol_header = 0; - - /* Loop until we find a workable header record. */ - for (;;) { - tar_flush_unconsumed(a, unconsumed); - - /* Read 512-byte header record */ - h = __archive_read_ahead(a, 512, &bytes); - if (bytes < 0) - return ((int)bytes); - if (bytes == 0) { /* EOF at a block boundary. */ - /* Some writers do omit the block of nulls. */ - return (ARCHIVE_EOF); - } - if (bytes < 512) { /* Short block at EOF; this is bad. */ - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated tar archive"); - return (ARCHIVE_FATAL); - } - *unconsumed = 512; - - /* Header is workable if it's not an end-of-archive mark. */ - if (h[0] != 0 || !archive_block_is_null(h)) - break; - - /* Ensure format is set for archives with only null blocks. */ - if (a->archive.archive_format_name == NULL) { - a->archive.archive_format = ARCHIVE_FORMAT_TAR; - a->archive.archive_format_name = "tar"; - } - - if (!tar->read_concatenated_archives) { - /* Try to consume a second all-null record, as well. */ - tar_flush_unconsumed(a, unconsumed); - h = __archive_read_ahead(a, 512, NULL); - if (h != NULL && h[0] == 0 && archive_block_is_null(h)) - __archive_read_consume(a, 512); - archive_clear_error(&a->archive); - return (ARCHIVE_EOF); - } - - /* - * We're reading concatenated archives, ignore this block and - * loop to get the next. - */ - } - - /* - * Note: If the checksum fails and we return ARCHIVE_RETRY, - * then the client is likely to just retry. This is a very - * crude way to search for the next valid header! - * - * TODO: Improve this by implementing a real header scan. - */ - if (!checksum(a, h)) { - tar_flush_unconsumed(a, unconsumed); - archive_set_error(&a->archive, EINVAL, "Damaged tar archive"); - return (ARCHIVE_RETRY); /* Retryable: Invalid header */ - } - - if (++tar->header_recursion_depth > 32) { - tar_flush_unconsumed(a, unconsumed); - archive_set_error(&a->archive, EINVAL, "Too many special headers"); - return (ARCHIVE_WARN); - } - - /* Determine the format variant. */ - header = (const struct archive_entry_header_ustar *)h; - - switch(header->typeflag[0]) { - case 'A': /* Solaris tar ACL */ - a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE; - a->archive.archive_format_name = "Solaris tar"; - err = header_Solaris_ACL(a, tar, entry, h, unconsumed); - break; - case 'g': /* POSIX-standard 'g' header. */ - a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE; - a->archive.archive_format_name = "POSIX pax interchange format"; - err = header_pax_global(a, tar, entry, h, unconsumed); - if (err == ARCHIVE_EOF) - return (err); - break; - case 'K': /* Long link name (GNU tar, others) */ - err = header_longlink(a, tar, entry, h, unconsumed); - break; - case 'L': /* Long filename (GNU tar, others) */ - err = header_longname(a, tar, entry, h, unconsumed); - break; - case 'V': /* GNU volume header */ - err = header_volume(a, tar, entry, h, unconsumed); - if (err == ARCHIVE_EOF) - eof_vol_header = 1; - break; - case 'X': /* Used by SUN tar; same as 'x'. */ - a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE; - a->archive.archive_format_name = - "POSIX pax interchange format (Sun variant)"; - err = header_pax_extensions(a, tar, entry, h, unconsumed); - break; - case 'x': /* POSIX-standard 'x' header. */ - a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE; - a->archive.archive_format_name = "POSIX pax interchange format"; - err = header_pax_extensions(a, tar, entry, h, unconsumed); - break; - default: - gnuheader = (const struct archive_entry_header_gnutar *)h; - if (memcmp(gnuheader->magic, "ustar \0", 8) == 0) { - a->archive.archive_format = ARCHIVE_FORMAT_TAR_GNUTAR; - a->archive.archive_format_name = "GNU tar format"; - err = header_gnutar(a, tar, entry, h, unconsumed); - } else if (memcmp(header->magic, "ustar", 5) == 0) { - if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE) { - a->archive.archive_format = ARCHIVE_FORMAT_TAR_USTAR; - a->archive.archive_format_name = "POSIX ustar format"; - } - err = header_ustar(a, tar, entry, h); - } else { - a->archive.archive_format = ARCHIVE_FORMAT_TAR; - a->archive.archive_format_name = "tar (non-POSIX)"; - err = header_old_tar(a, tar, entry, h); - } - } - if (err == ARCHIVE_FATAL) - return (err); - - tar_flush_unconsumed(a, unconsumed); - - h = NULL; - header = NULL; - - --tar->header_recursion_depth; - /* Yuck. Apple's design here ends up storing long pathname - * extensions for both the AppleDouble extension entry and the - * regular entry. - */ - if ((err == ARCHIVE_WARN || err == ARCHIVE_OK) && - tar->header_recursion_depth == 0 && - tar->process_mac_extensions) { - int err2 = read_mac_metadata_blob(a, tar, entry, h, unconsumed); - if (err2 < err) - err = err2; - } - - /* We return warnings or success as-is. Anything else is fatal. */ - if (err == ARCHIVE_WARN || err == ARCHIVE_OK) { - if (tar->sparse_gnu_pending) { - if (tar->sparse_gnu_major == 1 && - tar->sparse_gnu_minor == 0) { - ssize_t bytes_read; - - tar->sparse_gnu_pending = 0; - /* Read initial sparse map. */ - bytes_read = gnu_sparse_10_read(a, tar, unconsumed); - if (bytes_read < 0) - return ((int)bytes_read); - tar->entry_bytes_remaining -= bytes_read; - } else { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Unrecognized GNU sparse file format"); - return (ARCHIVE_WARN); - } - tar->sparse_gnu_pending = 0; - } - return (err); - } - if (err == ARCHIVE_EOF) { - if (!eof_vol_header) { - /* EOF when recursively reading a header is bad. */ - archive_set_error(&a->archive, EINVAL, - "Damaged tar archive"); - } else { - /* If we encounter just a GNU volume header treat - * this situation as an empty archive */ - return (ARCHIVE_EOF); - } - } - return (ARCHIVE_FATAL); -} - -/* - * Return true if block checksum is correct. - */ -static int -checksum(struct archive_read *a, const void *h) -{ - const unsigned char *bytes; - const struct archive_entry_header_ustar *header; - int check, sum; - size_t i; - - (void)a; /* UNUSED */ - bytes = (const unsigned char *)h; - header = (const struct archive_entry_header_ustar *)h; - - /* Checksum field must hold an octal number */ - for (i = 0; i < sizeof(header->checksum); ++i) { - char c = header->checksum[i]; - if (c != ' ' && c != '\0' && (c < '0' || c > '7')) - return 0; - } - - /* - * Test the checksum. Note that POSIX specifies _unsigned_ - * bytes for this calculation. - */ - sum = (int)tar_atol(header->checksum, sizeof(header->checksum)); - check = 0; - for (i = 0; i < 148; i++) - check += (unsigned char)bytes[i]; - for (; i < 156; i++) - check += 32; - for (; i < 512; i++) - check += (unsigned char)bytes[i]; - if (sum == check) - return (1); - - /* - * Repeat test with _signed_ bytes, just in case this archive - * was created by an old BSD, Solaris, or HP-UX tar with a - * broken checksum calculation. - */ - check = 0; - for (i = 0; i < 148; i++) - check += (signed char)bytes[i]; - for (; i < 156; i++) - check += 32; - for (; i < 512; i++) - check += (signed char)bytes[i]; - if (sum == check) - return (1); - - return (0); -} - -/* - * Return true if this block contains only nulls. - */ -static int -archive_block_is_null(const char *p) -{ - unsigned i; - - for (i = 0; i < 512; i++) - if (*p++) - return (0); - return (1); -} - -/* - * Interpret 'A' Solaris ACL header - */ -static int -header_Solaris_ACL(struct archive_read *a, struct tar *tar, - struct archive_entry *entry, const void *h, size_t *unconsumed) -{ - const struct archive_entry_header_ustar *header; - size_t size; - int err, acl_type; - int64_t type; - char *acl, *p; - - /* - * read_body_to_string adds a NUL terminator, but we need a little - * more to make sure that we don't overrun acl_text later. - */ - header = (const struct archive_entry_header_ustar *)h; - size = (size_t)tar_atol(header->size, sizeof(header->size)); - err = read_body_to_string(a, tar, &(tar->acl_text), h, unconsumed); - if (err != ARCHIVE_OK) - return (err); - - /* Recursively read next header */ - err = tar_read_header(a, tar, entry, unconsumed); - if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN)) - return (err); - - /* TODO: Examine the first characters to see if this - * is an AIX ACL descriptor. We'll likely never support - * them, but it would be polite to recognize and warn when - * we do see them. */ - - /* Leading octal number indicates ACL type and number of entries. */ - p = acl = tar->acl_text.s; - type = 0; - while (*p != '\0' && p < acl + size) { - if (*p < '0' || *p > '7') { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Malformed Solaris ACL attribute (invalid digit)"); - return(ARCHIVE_WARN); - } - type <<= 3; - type += *p - '0'; - if (type > 077777777) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Malformed Solaris ACL attribute (count too large)"); - return (ARCHIVE_WARN); - } - p++; - } - switch ((int)type & ~0777777) { - case 01000000: - /* POSIX.1e ACL */ - acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS; - break; - case 03000000: - /* NFSv4 ACL */ - acl_type = ARCHIVE_ENTRY_ACL_TYPE_NFS4; - break; - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Malformed Solaris ACL attribute (unsupported type %o)", - (int)type); - return (ARCHIVE_WARN); - } - p++; - - if (p >= acl + size) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Malformed Solaris ACL attribute (body overflow)"); - return(ARCHIVE_WARN); - } - - /* ACL text is null-terminated; find the end. */ - size -= (p - acl); - acl = p; - - while (*p != '\0' && p < acl + size) - p++; - - if (tar->sconv_acl == NULL) { - tar->sconv_acl = archive_string_conversion_from_charset( - &(a->archive), "UTF-8", 1); - if (tar->sconv_acl == NULL) - return (ARCHIVE_FATAL); - } - archive_strncpy(&(tar->localname), acl, p - acl); - err = archive_acl_from_text_l(archive_entry_acl(entry), - tar->localname.s, acl_type, tar->sconv_acl); - if (err != ARCHIVE_OK) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for ACL"); - } else - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Malformed Solaris ACL attribute (unparsable)"); - } - return (err); -} - -/* - * Interpret 'K' long linkname header. - */ -static int -header_longlink(struct archive_read *a, struct tar *tar, - struct archive_entry *entry, const void *h, size_t *unconsumed) -{ - int err; - - err = read_body_to_string(a, tar, &(tar->longlink), h, unconsumed); - if (err != ARCHIVE_OK) - return (err); - err = tar_read_header(a, tar, entry, unconsumed); - if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN)) - return (err); - /* Set symlink if symlink already set, else hardlink. */ - archive_entry_copy_link(entry, tar->longlink.s); - return (ARCHIVE_OK); -} - -static int -set_conversion_failed_error(struct archive_read *a, - struct archive_string_conv *sconv, const char *name) -{ - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for %s", name); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "%s can't be converted from %s to current locale.", - name, archive_string_conversion_charset_name(sconv)); - return (ARCHIVE_WARN); -} - -/* - * Interpret 'L' long filename header. - */ -static int -header_longname(struct archive_read *a, struct tar *tar, - struct archive_entry *entry, const void *h, size_t *unconsumed) -{ - int err; - - err = read_body_to_string(a, tar, &(tar->longname), h, unconsumed); - if (err != ARCHIVE_OK) - return (err); - /* Read and parse "real" header, then override name. */ - err = tar_read_header(a, tar, entry, unconsumed); - if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN)) - return (err); - if (archive_entry_copy_pathname_l(entry, tar->longname.s, - archive_strlen(&(tar->longname)), tar->sconv) != 0) - err = set_conversion_failed_error(a, tar->sconv, "Pathname"); - return (err); -} - - -/* - * Interpret 'V' GNU tar volume header. - */ -static int -header_volume(struct archive_read *a, struct tar *tar, - struct archive_entry *entry, const void *h, size_t *unconsumed) -{ - (void)h; - - /* Just skip this and read the next header. */ - return (tar_read_header(a, tar, entry, unconsumed)); -} - -/* - * Read body of an archive entry into an archive_string object. - */ -static int -read_body_to_string(struct archive_read *a, struct tar *tar, - struct archive_string *as, const void *h, size_t *unconsumed) -{ - int64_t size; - const struct archive_entry_header_ustar *header; - const void *src; - - (void)tar; /* UNUSED */ - header = (const struct archive_entry_header_ustar *)h; - size = tar_atol(header->size, sizeof(header->size)); - if ((size > 1048576) || (size < 0)) { - archive_set_error(&a->archive, EINVAL, - "Special header too large"); - return (ARCHIVE_FATAL); - } - - /* Fail if we can't make our buffer big enough. */ - if (archive_string_ensure(as, (size_t)size+1) == NULL) { - archive_set_error(&a->archive, ENOMEM, - "No memory"); - return (ARCHIVE_FATAL); - } - - tar_flush_unconsumed(a, unconsumed); - - /* Read the body into the string. */ - *unconsumed = (size_t)((size + 511) & ~ 511); - src = __archive_read_ahead(a, *unconsumed, NULL); - if (src == NULL) { - *unconsumed = 0; - return (ARCHIVE_FATAL); - } - memcpy(as->s, src, (size_t)size); - as->s[size] = '\0'; - as->length = (size_t)size; - return (ARCHIVE_OK); -} - -/* - * Parse out common header elements. - * - * This would be the same as header_old_tar, except that the - * filename is handled slightly differently for old and POSIX - * entries (POSIX entries support a 'prefix'). This factoring - * allows header_old_tar and header_ustar - * to handle filenames differently, while still putting most of the - * common parsing into one place. - */ -static int -header_common(struct archive_read *a, struct tar *tar, - struct archive_entry *entry, const void *h) -{ - const struct archive_entry_header_ustar *header; - char tartype; - int err = ARCHIVE_OK; - - header = (const struct archive_entry_header_ustar *)h; - if (header->linkname[0]) - archive_strncpy(&(tar->entry_linkpath), - header->linkname, sizeof(header->linkname)); - else - archive_string_empty(&(tar->entry_linkpath)); - - /* Parse out the numeric fields (all are octal) */ - archive_entry_set_mode(entry, - (mode_t)tar_atol(header->mode, sizeof(header->mode))); - archive_entry_set_uid(entry, tar_atol(header->uid, sizeof(header->uid))); - archive_entry_set_gid(entry, tar_atol(header->gid, sizeof(header->gid))); - tar->entry_bytes_remaining = tar_atol(header->size, sizeof(header->size)); - if (tar->entry_bytes_remaining < 0) { - tar->entry_bytes_remaining = 0; - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Tar entry has negative size"); - return (ARCHIVE_FATAL); - } - if (tar->entry_bytes_remaining == INT64_MAX) { - /* Note: tar_atol returns INT64_MAX on overflow */ - tar->entry_bytes_remaining = 0; - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Tar entry size overflow"); - return (ARCHIVE_FATAL); - } - tar->realsize = tar->entry_bytes_remaining; - archive_entry_set_size(entry, tar->entry_bytes_remaining); - archive_entry_set_mtime(entry, tar_atol(header->mtime, sizeof(header->mtime)), 0); - - /* Handle the tar type flag appropriately. */ - tartype = header->typeflag[0]; - - switch (tartype) { - case '1': /* Hard link */ - if (archive_entry_copy_hardlink_l(entry, tar->entry_linkpath.s, - archive_strlen(&(tar->entry_linkpath)), tar->sconv) != 0) { - err = set_conversion_failed_error(a, tar->sconv, - "Linkname"); - if (err == ARCHIVE_FATAL) - return (err); - } - /* - * The following may seem odd, but: Technically, tar - * does not store the file type for a "hard link" - * entry, only the fact that it is a hard link. So, I - * leave the type zero normally. But, pax interchange - * format allows hard links to have data, which - * implies that the underlying entry is a regular - * file. - */ - if (archive_entry_size(entry) > 0) - archive_entry_set_filetype(entry, AE_IFREG); - - /* - * A tricky point: Traditionally, tar readers have - * ignored the size field when reading hardlink - * entries, and some writers put non-zero sizes even - * though the body is empty. POSIX blessed this - * convention in the 1988 standard, but broke with - * this tradition in 2001 by permitting hardlink - * entries to store valid bodies in pax interchange - * format, but not in ustar format. Since there is no - * hard and fast way to distinguish pax interchange - * from earlier archives (the 'x' and 'g' entries are - * optional, after all), we need a heuristic. - */ - if (archive_entry_size(entry) == 0) { - /* If the size is already zero, we're done. */ - } else if (a->archive.archive_format - == ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE) { - /* Definitely pax extended; must obey hardlink size. */ - } else if (a->archive.archive_format == ARCHIVE_FORMAT_TAR - || a->archive.archive_format == ARCHIVE_FORMAT_TAR_GNUTAR) - { - /* Old-style or GNU tar: we must ignore the size. */ - archive_entry_set_size(entry, 0); - tar->entry_bytes_remaining = 0; - } else if (archive_read_format_tar_bid(a, 50) > 50) { - /* - * We don't know if it's pax: If the bid - * function sees a valid ustar header - * immediately following, then let's ignore - * the hardlink size. - */ - archive_entry_set_size(entry, 0); - tar->entry_bytes_remaining = 0; - } - /* - * TODO: There are still two cases I'd like to handle: - * = a ustar non-pax archive with a hardlink entry at - * end-of-archive. (Look for block of nulls following?) - * = a pax archive that has not seen any pax headers - * and has an entry which is a hardlink entry storing - * a body containing an uncompressed tar archive. - * The first is worth addressing; I don't see any reliable - * way to deal with the second possibility. - */ - break; - case '2': /* Symlink */ - archive_entry_set_filetype(entry, AE_IFLNK); - archive_entry_set_size(entry, 0); - tar->entry_bytes_remaining = 0; - if (archive_entry_copy_symlink_l(entry, tar->entry_linkpath.s, - archive_strlen(&(tar->entry_linkpath)), tar->sconv) != 0) { - err = set_conversion_failed_error(a, tar->sconv, - "Linkname"); - if (err == ARCHIVE_FATAL) - return (err); - } - break; - case '3': /* Character device */ - archive_entry_set_filetype(entry, AE_IFCHR); - archive_entry_set_size(entry, 0); - tar->entry_bytes_remaining = 0; - break; - case '4': /* Block device */ - archive_entry_set_filetype(entry, AE_IFBLK); - archive_entry_set_size(entry, 0); - tar->entry_bytes_remaining = 0; - break; - case '5': /* Dir */ - archive_entry_set_filetype(entry, AE_IFDIR); - archive_entry_set_size(entry, 0); - tar->entry_bytes_remaining = 0; - break; - case '6': /* FIFO device */ - archive_entry_set_filetype(entry, AE_IFIFO); - archive_entry_set_size(entry, 0); - tar->entry_bytes_remaining = 0; - break; - case 'D': /* GNU incremental directory type */ - /* - * No special handling is actually required here. - * It might be nice someday to preprocess the file list and - * provide it to the client, though. - */ - archive_entry_set_filetype(entry, AE_IFDIR); - break; - case 'M': /* GNU "Multi-volume" (remainder of file from last archive)*/ - /* - * As far as I can tell, this is just like a regular file - * entry, except that the contents should be _appended_ to - * the indicated file at the indicated offset. This may - * require some API work to fully support. - */ - break; - case 'N': /* Old GNU "long filename" entry. */ - /* The body of this entry is a script for renaming - * previously-extracted entries. Ugh. It will never - * be supported by libarchive. */ - archive_entry_set_filetype(entry, AE_IFREG); - break; - case 'S': /* GNU sparse files */ - /* - * Sparse files are really just regular files with - * sparse information in the extended area. - */ - /* FALLTHROUGH */ - case '0': - /* - * Enable sparse file "read" support only for regular - * files and explicit GNU sparse files. However, we - * don't allow non-standard file types to be sparse. - */ - tar->sparse_allowed = 1; - /* FALLTHROUGH */ - default: /* Regular file and non-standard types */ - /* - * Per POSIX: non-recognized types should always be - * treated as regular files. - */ - archive_entry_set_filetype(entry, AE_IFREG); - break; - } - return (err); -} - -/* - * Parse out header elements for "old-style" tar archives. - */ -static int -header_old_tar(struct archive_read *a, struct tar *tar, - struct archive_entry *entry, const void *h) -{ - const struct archive_entry_header_ustar *header; - int err = ARCHIVE_OK, err2; - - /* Copy filename over (to ensure null termination). */ - header = (const struct archive_entry_header_ustar *)h; - if (archive_entry_copy_pathname_l(entry, - header->name, sizeof(header->name), tar->sconv) != 0) { - err = set_conversion_failed_error(a, tar->sconv, "Pathname"); - if (err == ARCHIVE_FATAL) - return (err); - } - - /* Grab rest of common fields */ - err2 = header_common(a, tar, entry, h); - if (err > err2) - err = err2; - - tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining); - return (err); -} - -/* - * Read a Mac AppleDouble-encoded blob of file metadata, - * if there is one. - */ -static int -read_mac_metadata_blob(struct archive_read *a, struct tar *tar, - struct archive_entry *entry, const void *h, size_t *unconsumed) -{ - int64_t size; - size_t msize; - const void *data; - const char *p, *name; - const wchar_t *wp, *wname; - - (void)h; /* UNUSED */ - - wname = wp = archive_entry_pathname_w(entry); - if (wp != NULL) { - /* Find the last path element. */ - for (; *wp != L'\0'; ++wp) { - if (wp[0] == '/' && wp[1] != L'\0') - wname = wp + 1; - } - /* - * If last path element starts with "._", then - * this is a Mac extension. - */ - if (wname[0] != L'.' || wname[1] != L'_' || wname[2] == L'\0') - return ARCHIVE_OK; - } else { - /* Find the last path element. */ - name = p = archive_entry_pathname(entry); - if (p == NULL) - return (ARCHIVE_FAILED); - for (; *p != '\0'; ++p) { - if (p[0] == '/' && p[1] != '\0') - name = p + 1; - } - /* - * If last path element starts with "._", then - * this is a Mac extension. - */ - if (name[0] != '.' || name[1] != '_' || name[2] == '\0') - return ARCHIVE_OK; - } - - /* Read the body as a Mac OS metadata blob. */ - size = archive_entry_size(entry); - msize = (size_t)size; - if (size < 0 || (uintmax_t)msize != (uintmax_t)size) { - *unconsumed = 0; - return (ARCHIVE_FATAL); - } - - /* - * TODO: Look beyond the body here to peek at the next header. - * If it's a regular header (not an extension header) - * that has the wrong name, just return the current - * entry as-is, without consuming the body here. - * That would reduce the risk of us mis-identifying - * an ordinary file that just happened to have - * a name starting with "._". - * - * Q: Is the above idea really possible? Even - * when there are GNU or pax extension entries? - */ - data = __archive_read_ahead(a, msize, NULL); - if (data == NULL) { - *unconsumed = 0; - return (ARCHIVE_FATAL); - } - archive_entry_copy_mac_metadata(entry, data, msize); - *unconsumed = (msize + 511) & ~ 511; - tar_flush_unconsumed(a, unconsumed); - return (tar_read_header(a, tar, entry, unconsumed)); -} - -/* - * Parse a file header for a pax extended archive entry. - */ -static int -header_pax_global(struct archive_read *a, struct tar *tar, - struct archive_entry *entry, const void *h, size_t *unconsumed) -{ - int err; - - err = read_body_to_string(a, tar, &(tar->pax_global), h, unconsumed); - if (err != ARCHIVE_OK) - return (err); - err = tar_read_header(a, tar, entry, unconsumed); - return (err); -} - -static int -header_pax_extensions(struct archive_read *a, struct tar *tar, - struct archive_entry *entry, const void *h, size_t *unconsumed) -{ - int err, err2; - - err = read_body_to_string(a, tar, &(tar->pax_header), h, unconsumed); - if (err != ARCHIVE_OK) - return (err); - - /* Parse the next header. */ - err = tar_read_header(a, tar, entry, unconsumed); - if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN)) - return (err); - - /* - * TODO: Parse global/default options into 'entry' struct here - * before handling file-specific options. - * - * This design (parse standard header, then overwrite with pax - * extended attribute data) usually works well, but isn't ideal; - * it would be better to parse the pax extended attributes first - * and then skip any fields in the standard header that were - * defined in the pax header. - */ - err2 = pax_header(a, tar, entry, &tar->pax_header); - err = err_combine(err, err2); - tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining); - return (err); -} - - -/* - * Parse a file header for a Posix "ustar" archive entry. This also - * handles "pax" or "extended ustar" entries. - */ -static int -header_ustar(struct archive_read *a, struct tar *tar, - struct archive_entry *entry, const void *h) -{ - const struct archive_entry_header_ustar *header; - struct archive_string *as; - int err = ARCHIVE_OK, r; - - header = (const struct archive_entry_header_ustar *)h; - - /* Copy name into an internal buffer to ensure null-termination. */ - as = &(tar->entry_pathname); - if (header->prefix[0]) { - archive_strncpy(as, header->prefix, sizeof(header->prefix)); - if (as->s[archive_strlen(as) - 1] != '/') - archive_strappend_char(as, '/'); - archive_strncat(as, header->name, sizeof(header->name)); - } else { - archive_strncpy(as, header->name, sizeof(header->name)); - } - if (archive_entry_copy_pathname_l(entry, as->s, archive_strlen(as), - tar->sconv) != 0) { - err = set_conversion_failed_error(a, tar->sconv, "Pathname"); - if (err == ARCHIVE_FATAL) - return (err); - } - - /* Handle rest of common fields. */ - r = header_common(a, tar, entry, h); - if (r == ARCHIVE_FATAL) - return (r); - if (r < err) - err = r; - - /* Handle POSIX ustar fields. */ - if (archive_entry_copy_uname_l(entry, - header->uname, sizeof(header->uname), tar->sconv) != 0) { - err = set_conversion_failed_error(a, tar->sconv, "Uname"); - if (err == ARCHIVE_FATAL) - return (err); - } - - if (archive_entry_copy_gname_l(entry, - header->gname, sizeof(header->gname), tar->sconv) != 0) { - err = set_conversion_failed_error(a, tar->sconv, "Gname"); - if (err == ARCHIVE_FATAL) - return (err); - } - - /* Parse out device numbers only for char and block specials. */ - if (header->typeflag[0] == '3' || header->typeflag[0] == '4') { - archive_entry_set_rdevmajor(entry, (dev_t) - tar_atol(header->rdevmajor, sizeof(header->rdevmajor))); - archive_entry_set_rdevminor(entry, (dev_t) - tar_atol(header->rdevminor, sizeof(header->rdevminor))); - } - - tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining); - - return (err); -} - - -/* - * Parse the pax extended attributes record. - * - * Returns non-zero if there's an error in the data. - */ -static int -pax_header(struct archive_read *a, struct tar *tar, - struct archive_entry *entry, struct archive_string *in_as) -{ - size_t attr_length, l, line_length, value_length; - char *p; - char *key, *value; - struct archive_string *as; - struct archive_string_conv *sconv; - int err, err2; - char *attr = in_as->s; - - attr_length = in_as->length; - tar->pax_hdrcharset_binary = 0; - archive_string_empty(&(tar->entry_gname)); - archive_string_empty(&(tar->entry_linkpath)); - archive_string_empty(&(tar->entry_pathname)); - archive_string_empty(&(tar->entry_pathname_override)); - archive_string_empty(&(tar->entry_uname)); - err = ARCHIVE_OK; - while (attr_length > 0) { - /* Parse decimal length field at start of line. */ - line_length = 0; - l = attr_length; - p = attr; /* Record start of line. */ - while (l>0) { - if (*p == ' ') { - p++; - l--; - break; - } - if (*p < '0' || *p > '9') { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Ignoring malformed pax extended attributes"); - return (ARCHIVE_WARN); - } - line_length *= 10; - line_length += *p - '0'; - if (line_length > 999999) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Rejecting pax extended attribute > 1MB"); - return (ARCHIVE_WARN); - } - p++; - l--; - } - - /* - * Parsed length must be no bigger than available data, - * at least 1, and the last character of the line must - * be '\n'. - */ - if (line_length > attr_length - || line_length < 1 - || attr[line_length - 1] != '\n') - { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Ignoring malformed pax extended attribute"); - return (ARCHIVE_WARN); - } - - /* Null-terminate the line. */ - attr[line_length - 1] = '\0'; - - /* Find end of key and null terminate it. */ - key = p; - if (key[0] == '=') - return (-1); - while (*p && *p != '=') - ++p; - if (*p == '\0') { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Invalid pax extended attributes"); - return (ARCHIVE_WARN); - } - *p = '\0'; - - value = p + 1; - - /* Some values may be binary data */ - value_length = attr + line_length - 1 - value; - - /* Identify this attribute and set it in the entry. */ - err2 = pax_attribute(a, tar, entry, key, value, value_length); - if (err2 == ARCHIVE_FATAL) - return (err2); - err = err_combine(err, err2); - - /* Skip to next line */ - attr += line_length; - attr_length -= line_length; - } - - /* - * PAX format uses UTF-8 as default charset for its metadata - * unless hdrcharset=BINARY is present in its header. - * We apply the charset specified by the hdrcharset option only - * when the hdrcharset attribute(in PAX header) is BINARY because - * we respect the charset described in PAX header and BINARY also - * means that metadata(filename,uname and gname) character-set - * is unknown. - */ - if (tar->pax_hdrcharset_binary) - sconv = tar->opt_sconv; - else { - sconv = archive_string_conversion_from_charset( - &(a->archive), "UTF-8", 1); - if (sconv == NULL) - return (ARCHIVE_FATAL); - if (tar->compat_2x) - archive_string_conversion_set_opt(sconv, - SCONV_SET_OPT_UTF8_LIBARCHIVE2X); - } - - if (archive_strlen(&(tar->entry_gname)) > 0) { - if (archive_entry_copy_gname_l(entry, tar->entry_gname.s, - archive_strlen(&(tar->entry_gname)), sconv) != 0) { - err = set_conversion_failed_error(a, sconv, "Gname"); - if (err == ARCHIVE_FATAL) - return (err); - /* Use a converted an original name. */ - archive_entry_copy_gname(entry, tar->entry_gname.s); - } - } - if (archive_strlen(&(tar->entry_linkpath)) > 0) { - if (archive_entry_copy_link_l(entry, tar->entry_linkpath.s, - archive_strlen(&(tar->entry_linkpath)), sconv) != 0) { - err = set_conversion_failed_error(a, sconv, "Linkname"); - if (err == ARCHIVE_FATAL) - return (err); - /* Use a converted an original name. */ - archive_entry_copy_link(entry, tar->entry_linkpath.s); - } - } - /* - * Some extensions (such as the GNU sparse file extensions) - * deliberately store a synthetic name under the regular 'path' - * attribute and the real file name under a different attribute. - * Since we're supposed to not care about the order, we - * have no choice but to store all of the various filenames - * we find and figure it all out afterwards. This is the - * figuring out part. - */ - as = NULL; - if (archive_strlen(&(tar->entry_pathname_override)) > 0) - as = &(tar->entry_pathname_override); - else if (archive_strlen(&(tar->entry_pathname)) > 0) - as = &(tar->entry_pathname); - if (as != NULL) { - if (archive_entry_copy_pathname_l(entry, as->s, - archive_strlen(as), sconv) != 0) { - err = set_conversion_failed_error(a, sconv, "Pathname"); - if (err == ARCHIVE_FATAL) - return (err); - /* Use a converted an original name. */ - archive_entry_copy_pathname(entry, as->s); - } - } - if (archive_strlen(&(tar->entry_uname)) > 0) { - if (archive_entry_copy_uname_l(entry, tar->entry_uname.s, - archive_strlen(&(tar->entry_uname)), sconv) != 0) { - err = set_conversion_failed_error(a, sconv, "Uname"); - if (err == ARCHIVE_FATAL) - return (err); - /* Use a converted an original name. */ - archive_entry_copy_uname(entry, tar->entry_uname.s); - } - } - return (err); -} - -static int -pax_attribute_xattr(struct archive_entry *entry, - const char *name, const char *value) -{ - char *name_decoded; - void *value_decoded; - size_t value_len; - - if (strlen(name) < 18 || (memcmp(name, "LIBARCHIVE.xattr.", 17)) != 0) - return 3; - - name += 17; - - /* URL-decode name */ - name_decoded = url_decode(name); - if (name_decoded == NULL) - return 2; - - /* Base-64 decode value */ - value_decoded = base64_decode(value, strlen(value), &value_len); - if (value_decoded == NULL) { - free(name_decoded); - return 1; - } - - archive_entry_xattr_add_entry(entry, name_decoded, - value_decoded, value_len); - - free(name_decoded); - free(value_decoded); - return 0; -} - -static int -pax_attribute_schily_xattr(struct archive_entry *entry, - const char *name, const char *value, size_t value_length) -{ - if (strlen(name) < 14 || (memcmp(name, "SCHILY.xattr.", 13)) != 0) - return 1; - - name += 13; - - archive_entry_xattr_add_entry(entry, name, value, value_length); - - return 0; -} - -static int -pax_attribute_rht_security_selinux(struct archive_entry *entry, - const char *value, size_t value_length) -{ - archive_entry_xattr_add_entry(entry, "security.selinux", - value, value_length); - - return 0; -} - -static int -pax_attribute_acl(struct archive_read *a, struct tar *tar, - struct archive_entry *entry, const char *value, int type) -{ - int r; - const char* errstr; - - switch (type) { - case ARCHIVE_ENTRY_ACL_TYPE_ACCESS: - errstr = "SCHILY.acl.access"; - break; - case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT: - errstr = "SCHILY.acl.default"; - break; - case ARCHIVE_ENTRY_ACL_TYPE_NFS4: - errstr = "SCHILY.acl.ace"; - break; - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Unknown ACL type: %d", type); - return(ARCHIVE_FATAL); - } - - if (tar->sconv_acl == NULL) { - tar->sconv_acl = - archive_string_conversion_from_charset( - &(a->archive), "UTF-8", 1); - if (tar->sconv_acl == NULL) - return (ARCHIVE_FATAL); - } - - r = archive_acl_from_text_l(archive_entry_acl(entry), value, type, - tar->sconv_acl); - if (r != ARCHIVE_OK) { - if (r == ARCHIVE_FATAL) { - archive_set_error(&a->archive, ENOMEM, - "%s %s", "Can't allocate memory for ", - errstr); - return (r); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, "%s %s", "Parse error: ", errstr); - } - return (r); -} - -/* - * Parse a single key=value attribute. key/value pointers are - * assumed to point into reasonably long-lived storage. - * - * Note that POSIX reserves all-lowercase keywords. Vendor-specific - * extensions should always have keywords of the form "VENDOR.attribute" - * In particular, it's quite feasible to support many different - * vendor extensions here. I'm using "LIBARCHIVE" for extensions - * unique to this library. - * - * Investigate other vendor-specific extensions and see if - * any of them look useful. - */ -static int -pax_attribute(struct archive_read *a, struct tar *tar, - struct archive_entry *entry, const char *key, const char *value, size_t value_length) -{ - int64_t s; - long n; - int err = ARCHIVE_OK, r; - - if (value == NULL) - value = ""; /* Disable compiler warning; do not pass - * NULL pointer to strlen(). */ - switch (key[0]) { - case 'G': - /* Reject GNU.sparse.* headers on non-regular files. */ - if (strncmp(key, "GNU.sparse", 10) == 0 && - !tar->sparse_allowed) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Non-regular file cannot be sparse"); - return (ARCHIVE_FATAL); - } - - /* GNU "0.0" sparse pax format. */ - if (strcmp(key, "GNU.sparse.numblocks") == 0) { - tar->sparse_offset = -1; - tar->sparse_numbytes = -1; - tar->sparse_gnu_major = 0; - tar->sparse_gnu_minor = 0; - } - if (strcmp(key, "GNU.sparse.offset") == 0) { - tar->sparse_offset = tar_atol10(value, strlen(value)); - if (tar->sparse_numbytes != -1) { - if (gnu_add_sparse_entry(a, tar, - tar->sparse_offset, tar->sparse_numbytes) - != ARCHIVE_OK) - return (ARCHIVE_FATAL); - tar->sparse_offset = -1; - tar->sparse_numbytes = -1; - } - } - if (strcmp(key, "GNU.sparse.numbytes") == 0) { - tar->sparse_numbytes = tar_atol10(value, strlen(value)); - if (tar->sparse_offset != -1) { - if (gnu_add_sparse_entry(a, tar, - tar->sparse_offset, tar->sparse_numbytes) - != ARCHIVE_OK) - return (ARCHIVE_FATAL); - tar->sparse_offset = -1; - tar->sparse_numbytes = -1; - } - } - if (strcmp(key, "GNU.sparse.size") == 0) { - tar->realsize = tar_atol10(value, strlen(value)); - archive_entry_set_size(entry, tar->realsize); - tar->realsize_override = 1; - } - - /* GNU "0.1" sparse pax format. */ - if (strcmp(key, "GNU.sparse.map") == 0) { - tar->sparse_gnu_major = 0; - tar->sparse_gnu_minor = 1; - if (gnu_sparse_01_parse(a, tar, value) != ARCHIVE_OK) - return (ARCHIVE_WARN); - } - - /* GNU "1.0" sparse pax format */ - if (strcmp(key, "GNU.sparse.major") == 0) { - tar->sparse_gnu_major = (int)tar_atol10(value, strlen(value)); - tar->sparse_gnu_pending = 1; - } - if (strcmp(key, "GNU.sparse.minor") == 0) { - tar->sparse_gnu_minor = (int)tar_atol10(value, strlen(value)); - tar->sparse_gnu_pending = 1; - } - if (strcmp(key, "GNU.sparse.name") == 0) { - /* - * The real filename; when storing sparse - * files, GNU tar puts a synthesized name into - * the regular 'path' attribute in an attempt - * to limit confusion. ;-) - */ - archive_strcpy(&(tar->entry_pathname_override), value); - } - if (strcmp(key, "GNU.sparse.realsize") == 0) { - tar->realsize = tar_atol10(value, strlen(value)); - archive_entry_set_size(entry, tar->realsize); - tar->realsize_override = 1; - } - break; - case 'L': - /* Our extensions */ -/* TODO: Handle arbitrary extended attributes... */ -/* - if (strcmp(key, "LIBARCHIVE.xxxxxxx") == 0) - archive_entry_set_xxxxxx(entry, value); -*/ - if (strcmp(key, "LIBARCHIVE.creationtime") == 0) { - pax_time(value, &s, &n); - archive_entry_set_birthtime(entry, s, n); - } - if (strcmp(key, "LIBARCHIVE.symlinktype") == 0) { - if (strcmp(value, "file") == 0) { - archive_entry_set_symlink_type(entry, - AE_SYMLINK_TYPE_FILE); - } else if (strcmp(value, "dir") == 0) { - archive_entry_set_symlink_type(entry, - AE_SYMLINK_TYPE_DIRECTORY); - } - } - if (memcmp(key, "LIBARCHIVE.xattr.", 17) == 0) - pax_attribute_xattr(entry, key, value); - break; - case 'R': - /* GNU tar uses RHT.security header to store SELinux xattrs - * SCHILY.xattr.security.selinux == RHT.security.selinux */ - if (strcmp(key, "RHT.security.selinux") == 0) { - pax_attribute_rht_security_selinux(entry, value, - value_length); - } - break; - case 'S': - /* We support some keys used by the "star" archiver */ - if (strcmp(key, "SCHILY.acl.access") == 0) { - r = pax_attribute_acl(a, tar, entry, value, - ARCHIVE_ENTRY_ACL_TYPE_ACCESS); - if (r == ARCHIVE_FATAL) - return (r); - } else if (strcmp(key, "SCHILY.acl.default") == 0) { - r = pax_attribute_acl(a, tar, entry, value, - ARCHIVE_ENTRY_ACL_TYPE_DEFAULT); - if (r == ARCHIVE_FATAL) - return (r); - } else if (strcmp(key, "SCHILY.acl.ace") == 0) { - r = pax_attribute_acl(a, tar, entry, value, - ARCHIVE_ENTRY_ACL_TYPE_NFS4); - if (r == ARCHIVE_FATAL) - return (r); - } else if (strcmp(key, "SCHILY.devmajor") == 0) { - archive_entry_set_rdevmajor(entry, - (dev_t)tar_atol10(value, strlen(value))); - } else if (strcmp(key, "SCHILY.devminor") == 0) { - archive_entry_set_rdevminor(entry, - (dev_t)tar_atol10(value, strlen(value))); - } else if (strcmp(key, "SCHILY.fflags") == 0) { - archive_entry_copy_fflags_text(entry, value); - } else if (strcmp(key, "SCHILY.dev") == 0) { - archive_entry_set_dev(entry, - (dev_t)tar_atol10(value, strlen(value))); - } else if (strcmp(key, "SCHILY.ino") == 0) { - archive_entry_set_ino(entry, - tar_atol10(value, strlen(value))); - } else if (strcmp(key, "SCHILY.nlink") == 0) { - archive_entry_set_nlink(entry, (unsigned) - tar_atol10(value, strlen(value))); - } else if (strcmp(key, "SCHILY.realsize") == 0) { - tar->realsize = tar_atol10(value, strlen(value)); - tar->realsize_override = 1; - archive_entry_set_size(entry, tar->realsize); - } else if (strncmp(key, "SCHILY.xattr.", 13) == 0) { - pax_attribute_schily_xattr(entry, key, value, - value_length); - } else if (strcmp(key, "SUN.holesdata") == 0) { - /* A Solaris extension for sparse. */ - r = solaris_sparse_parse(a, tar, entry, value); - if (r < err) { - if (r == ARCHIVE_FATAL) - return (r); - err = r; - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Parse error: SUN.holesdata"); - } - } - break; - case 'a': - if (strcmp(key, "atime") == 0) { - pax_time(value, &s, &n); - archive_entry_set_atime(entry, s, n); - } - break; - case 'c': - if (strcmp(key, "ctime") == 0) { - pax_time(value, &s, &n); - archive_entry_set_ctime(entry, s, n); - } else if (strcmp(key, "charset") == 0) { - /* TODO: Publish charset information in entry. */ - } else if (strcmp(key, "comment") == 0) { - /* TODO: Publish comment in entry. */ - } - break; - case 'g': - if (strcmp(key, "gid") == 0) { - archive_entry_set_gid(entry, - tar_atol10(value, strlen(value))); - } else if (strcmp(key, "gname") == 0) { - archive_strcpy(&(tar->entry_gname), value); - } - break; - case 'h': - if (strcmp(key, "hdrcharset") == 0) { - if (strcmp(value, "BINARY") == 0) - /* Binary mode. */ - tar->pax_hdrcharset_binary = 1; - else if (strcmp(value, "ISO-IR 10646 2000 UTF-8") == 0) - tar->pax_hdrcharset_binary = 0; - } - break; - case 'l': - /* pax interchange doesn't distinguish hardlink vs. symlink. */ - if (strcmp(key, "linkpath") == 0) { - archive_strcpy(&(tar->entry_linkpath), value); - } - break; - case 'm': - if (strcmp(key, "mtime") == 0) { - pax_time(value, &s, &n); - archive_entry_set_mtime(entry, s, n); - } - break; - case 'p': - if (strcmp(key, "path") == 0) { - archive_strcpy(&(tar->entry_pathname), value); - } - break; - case 'r': - /* POSIX has reserved 'realtime.*' */ - break; - case 's': - /* POSIX has reserved 'security.*' */ - /* Someday: if (strcmp(key, "security.acl") == 0) { ... } */ - if (strcmp(key, "size") == 0) { - /* "size" is the size of the data in the entry. */ - tar->entry_bytes_remaining - = tar_atol10(value, strlen(value)); - if (tar->entry_bytes_remaining < 0) { - tar->entry_bytes_remaining = 0; - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Tar size attribute is negative"); - return (ARCHIVE_FATAL); - } - if (tar->entry_bytes_remaining == INT64_MAX) { - /* Note: tar_atol returns INT64_MAX on overflow */ - tar->entry_bytes_remaining = 0; - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Tar size attribute overflow"); - return (ARCHIVE_FATAL); - } - /* - * The "size" pax header keyword always overrides the - * "size" field in the tar header. - * GNU.sparse.realsize, GNU.sparse.size and - * SCHILY.realsize override this value. - */ - if (!tar->realsize_override) { - archive_entry_set_size(entry, - tar->entry_bytes_remaining); - tar->realsize - = tar->entry_bytes_remaining; - } - } - break; - case 'u': - if (strcmp(key, "uid") == 0) { - archive_entry_set_uid(entry, - tar_atol10(value, strlen(value))); - } else if (strcmp(key, "uname") == 0) { - archive_strcpy(&(tar->entry_uname), value); - } - break; - } - return (err); -} - - - -/* - * parse a decimal time value, which may include a fractional portion - */ -static void -pax_time(const char *p, int64_t *ps, long *pn) -{ - char digit; - int64_t s; - unsigned long l; - int sign; - int64_t limit, last_digit_limit; - - limit = INT64_MAX / 10; - last_digit_limit = INT64_MAX % 10; - - s = 0; - sign = 1; - if (*p == '-') { - sign = -1; - p++; - } - while (*p >= '0' && *p <= '9') { - digit = *p - '0'; - if (s > limit || - (s == limit && digit > last_digit_limit)) { - s = INT64_MAX; - break; - } - s = (s * 10) + digit; - ++p; - } - - *ps = s * sign; - - /* Calculate nanoseconds. */ - *pn = 0; - - if (*p != '.') - return; - - l = 100000000UL; - do { - ++p; - if (*p >= '0' && *p <= '9') - *pn += (*p - '0') * l; - else - break; - } while (l /= 10); -} - -/* - * Parse GNU tar header - */ -static int -header_gnutar(struct archive_read *a, struct tar *tar, - struct archive_entry *entry, const void *h, size_t *unconsumed) -{ - const struct archive_entry_header_gnutar *header; - int64_t t; - int err = ARCHIVE_OK; - - /* - * GNU header is like POSIX ustar, except 'prefix' is - * replaced with some other fields. This also means the - * filename is stored as in old-style archives. - */ - - /* Grab fields common to all tar variants. */ - err = header_common(a, tar, entry, h); - if (err == ARCHIVE_FATAL) - return (err); - - /* Copy filename over (to ensure null termination). */ - header = (const struct archive_entry_header_gnutar *)h; - if (archive_entry_copy_pathname_l(entry, - header->name, sizeof(header->name), tar->sconv) != 0) { - err = set_conversion_failed_error(a, tar->sconv, "Pathname"); - if (err == ARCHIVE_FATAL) - return (err); - } - - /* Fields common to ustar and GNU */ - /* XXX Can the following be factored out since it's common - * to ustar and gnu tar? Is it okay to move it down into - * header_common, perhaps? */ - if (archive_entry_copy_uname_l(entry, - header->uname, sizeof(header->uname), tar->sconv) != 0) { - err = set_conversion_failed_error(a, tar->sconv, "Uname"); - if (err == ARCHIVE_FATAL) - return (err); - } - - if (archive_entry_copy_gname_l(entry, - header->gname, sizeof(header->gname), tar->sconv) != 0) { - err = set_conversion_failed_error(a, tar->sconv, "Gname"); - if (err == ARCHIVE_FATAL) - return (err); - } - - /* Parse out device numbers only for char and block specials */ - if (header->typeflag[0] == '3' || header->typeflag[0] == '4') { - archive_entry_set_rdevmajor(entry, (dev_t) - tar_atol(header->rdevmajor, sizeof(header->rdevmajor))); - archive_entry_set_rdevminor(entry, (dev_t) - tar_atol(header->rdevminor, sizeof(header->rdevminor))); - } else - archive_entry_set_rdev(entry, 0); - - tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining); - - /* Grab GNU-specific fields. */ - t = tar_atol(header->atime, sizeof(header->atime)); - if (t > 0) - archive_entry_set_atime(entry, t, 0); - t = tar_atol(header->ctime, sizeof(header->ctime)); - if (t > 0) - archive_entry_set_ctime(entry, t, 0); - - if (header->realsize[0] != 0) { - tar->realsize - = tar_atol(header->realsize, sizeof(header->realsize)); - archive_entry_set_size(entry, tar->realsize); - tar->realsize_override = 1; - } - - if (header->sparse[0].offset[0] != 0) { - if (gnu_sparse_old_read(a, tar, header, unconsumed) - != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } else { - if (header->isextended[0] != 0) { - /* XXX WTF? XXX */ - } - } - - return (err); -} - -static int -gnu_add_sparse_entry(struct archive_read *a, struct tar *tar, - int64_t offset, int64_t remaining) -{ - struct sparse_block *p; - - p = (struct sparse_block *)calloc(1, sizeof(*p)); - if (p == NULL) { - archive_set_error(&a->archive, ENOMEM, "Out of memory"); - return (ARCHIVE_FATAL); - } - if (tar->sparse_last != NULL) - tar->sparse_last->next = p; - else - tar->sparse_list = p; - tar->sparse_last = p; - if (remaining < 0 || offset < 0 || offset > INT64_MAX - remaining) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Malformed sparse map data"); - return (ARCHIVE_FATAL); - } - p->offset = offset; - p->remaining = remaining; - return (ARCHIVE_OK); -} - -static void -gnu_clear_sparse_list(struct tar *tar) -{ - struct sparse_block *p; - - while (tar->sparse_list != NULL) { - p = tar->sparse_list; - tar->sparse_list = p->next; - free(p); - } - tar->sparse_last = NULL; -} - -/* - * GNU tar old-format sparse data. - * - * GNU old-format sparse data is stored in a fixed-field - * format. Offset/size values are 11-byte octal fields (same - * format as 'size' field in ustart header). These are - * stored in the header, allocating subsequent header blocks - * as needed. Extending the header in this way is a pretty - * severe POSIX violation; this design has earned GNU tar a - * lot of criticism. - */ - -static int -gnu_sparse_old_read(struct archive_read *a, struct tar *tar, - const struct archive_entry_header_gnutar *header, size_t *unconsumed) -{ - ssize_t bytes_read; - const void *data; - struct extended { - struct gnu_sparse sparse[21]; - char isextended[1]; - char padding[7]; - }; - const struct extended *ext; - - if (gnu_sparse_old_parse(a, tar, header->sparse, 4) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - if (header->isextended[0] == 0) - return (ARCHIVE_OK); - - do { - tar_flush_unconsumed(a, unconsumed); - data = __archive_read_ahead(a, 512, &bytes_read); - if (bytes_read < 0) - return (ARCHIVE_FATAL); - if (bytes_read < 512) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated tar archive " - "detected while reading sparse file data"); - return (ARCHIVE_FATAL); - } - *unconsumed = 512; - ext = (const struct extended *)data; - if (gnu_sparse_old_parse(a, tar, ext->sparse, 21) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } while (ext->isextended[0] != 0); - if (tar->sparse_list != NULL) - tar->entry_offset = tar->sparse_list->offset; - return (ARCHIVE_OK); -} - -static int -gnu_sparse_old_parse(struct archive_read *a, struct tar *tar, - const struct gnu_sparse *sparse, int length) -{ - while (length > 0 && sparse->offset[0] != 0) { - if (gnu_add_sparse_entry(a, tar, - tar_atol(sparse->offset, sizeof(sparse->offset)), - tar_atol(sparse->numbytes, sizeof(sparse->numbytes))) - != ARCHIVE_OK) - return (ARCHIVE_FATAL); - sparse++; - length--; - } - return (ARCHIVE_OK); -} - -/* - * GNU tar sparse format 0.0 - * - * Beginning with GNU tar 1.15, sparse files are stored using - * information in the pax extended header. The GNU tar maintainers - * have gone through a number of variations in the process of working - * out this scheme; fortunately, they're all numbered. - * - * Sparse format 0.0 uses attribute GNU.sparse.numblocks to store the - * number of blocks, and GNU.sparse.offset/GNU.sparse.numbytes to - * store offset/size for each block. The repeated instances of these - * latter fields violate the pax specification (which frowns on - * duplicate keys), so this format was quickly replaced. - */ - -/* - * GNU tar sparse format 0.1 - * - * This version replaced the offset/numbytes attributes with - * a single "map" attribute that stored a list of integers. This - * format had two problems: First, the "map" attribute could be very - * long, which caused problems for some implementations. More - * importantly, the sparse data was lost when extracted by archivers - * that didn't recognize this extension. - */ - -static int -gnu_sparse_01_parse(struct archive_read *a, struct tar *tar, const char *p) -{ - const char *e; - int64_t offset = -1, size = -1; - - for (;;) { - e = p; - while (*e != '\0' && *e != ',') { - if (*e < '0' || *e > '9') - return (ARCHIVE_WARN); - e++; - } - if (offset < 0) { - offset = tar_atol10(p, e - p); - if (offset < 0) - return (ARCHIVE_WARN); - } else { - size = tar_atol10(p, e - p); - if (size < 0) - return (ARCHIVE_WARN); - if (gnu_add_sparse_entry(a, tar, offset, size) - != ARCHIVE_OK) - return (ARCHIVE_FATAL); - offset = -1; - } - if (*e == '\0') - return (ARCHIVE_OK); - p = e + 1; - } -} - -/* - * GNU tar sparse format 1.0 - * - * The idea: The offset/size data is stored as a series of base-10 - * ASCII numbers prepended to the file data, so that dearchivers that - * don't support this format will extract the block map along with the - * data and a separate post-process can restore the sparseness. - * - * Unfortunately, GNU tar 1.16 had a bug that added unnecessary - * padding to the body of the file when using this format. GNU tar - * 1.17 corrected this bug without bumping the version number, so - * it's not possible to support both variants. This code supports - * the later variant at the expense of not supporting the former. - * - * This variant also replaced GNU.sparse.size with GNU.sparse.realsize - * and introduced the GNU.sparse.major/GNU.sparse.minor attributes. - */ - -/* - * Read the next line from the input, and parse it as a decimal - * integer followed by '\n'. Returns positive integer value or - * negative on error. - */ -static int64_t -gnu_sparse_10_atol(struct archive_read *a, struct tar *tar, - int64_t *remaining, size_t *unconsumed) -{ - int64_t l, limit, last_digit_limit; - const char *p; - ssize_t bytes_read; - int base, digit; - - base = 10; - limit = INT64_MAX / base; - last_digit_limit = INT64_MAX % base; - - /* - * Skip any lines starting with '#'; GNU tar specs - * don't require this, but they should. - */ - do { - bytes_read = readline(a, tar, &p, - (ssize_t)tar_min(*remaining, 100), unconsumed); - if (bytes_read <= 0) - return (ARCHIVE_FATAL); - *remaining -= bytes_read; - } while (p[0] == '#'); - - l = 0; - while (bytes_read > 0) { - if (*p == '\n') - return (l); - if (*p < '0' || *p >= '0' + base) - return (ARCHIVE_WARN); - digit = *p - '0'; - if (l > limit || (l == limit && digit > last_digit_limit)) - l = INT64_MAX; /* Truncate on overflow. */ - else - l = (l * base) + digit; - p++; - bytes_read--; - } - /* TODO: Error message. */ - return (ARCHIVE_WARN); -} - -/* - * Returns length (in bytes) of the sparse data description - * that was read. - */ -static ssize_t -gnu_sparse_10_read(struct archive_read *a, struct tar *tar, size_t *unconsumed) -{ - ssize_t bytes_read; - int entries; - int64_t offset, size, to_skip, remaining; - - /* Clear out the existing sparse list. */ - gnu_clear_sparse_list(tar); - - remaining = tar->entry_bytes_remaining; - - /* Parse entries. */ - entries = (int)gnu_sparse_10_atol(a, tar, &remaining, unconsumed); - if (entries < 0) - return (ARCHIVE_FATAL); - /* Parse the individual entries. */ - while (entries-- > 0) { - /* Parse offset/size */ - offset = gnu_sparse_10_atol(a, tar, &remaining, unconsumed); - if (offset < 0) - return (ARCHIVE_FATAL); - size = gnu_sparse_10_atol(a, tar, &remaining, unconsumed); - if (size < 0) - return (ARCHIVE_FATAL); - /* Add a new sparse entry. */ - if (gnu_add_sparse_entry(a, tar, offset, size) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } - /* Skip rest of block... */ - tar_flush_unconsumed(a, unconsumed); - bytes_read = (ssize_t)(tar->entry_bytes_remaining - remaining); - to_skip = 0x1ff & -bytes_read; - /* Fail if tar->entry_bytes_remaing would get negative */ - if (to_skip > remaining) - return (ARCHIVE_FATAL); - if (to_skip != __archive_read_consume(a, to_skip)) - return (ARCHIVE_FATAL); - return ((ssize_t)(bytes_read + to_skip)); -} - -/* - * Solaris pax extension for a sparse file. This is recorded with the - * data and hole pairs. The way recording sparse information by Solaris' - * pax simply indicates where data and sparse are, so the stored contents - * consist of both data and hole. - */ -static int -solaris_sparse_parse(struct archive_read *a, struct tar *tar, - struct archive_entry *entry, const char *p) -{ - const char *e; - int64_t start, end; - int hole = 1; - - (void)entry; /* UNUSED */ - - end = 0; - if (*p == ' ') - p++; - else - return (ARCHIVE_WARN); - for (;;) { - e = p; - while (*e != '\0' && *e != ' ') { - if (*e < '0' || *e > '9') - return (ARCHIVE_WARN); - e++; - } - start = end; - end = tar_atol10(p, e - p); - if (end < 0) - return (ARCHIVE_WARN); - if (start < end) { - if (gnu_add_sparse_entry(a, tar, start, - end - start) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - tar->sparse_last->hole = hole; - } - if (*e == '\0') - return (ARCHIVE_OK); - p = e + 1; - hole = hole == 0; - } -} - -/*- - * Convert text->integer. - * - * Traditional tar formats (including POSIX) specify base-8 for - * all of the standard numeric fields. This is a significant limitation - * in practice: - * = file size is limited to 8GB - * = rdevmajor and rdevminor are limited to 21 bits - * = uid/gid are limited to 21 bits - * - * There are two workarounds for this: - * = pax extended headers, which use variable-length string fields - * = GNU tar and STAR both allow either base-8 or base-256 in - * most fields. The high bit is set to indicate base-256. - * - * On read, this implementation supports both extensions. - */ -static int64_t -tar_atol(const char *p, size_t char_cnt) -{ - /* - * Technically, GNU tar considers a field to be in base-256 - * only if the first byte is 0xff or 0x80. - */ - if (*p & 0x80) - return (tar_atol256(p, char_cnt)); - return (tar_atol8(p, char_cnt)); -} - -/* - * Note that this implementation does not (and should not!) obey - * locale settings; you cannot simply substitute strtol here, since - * it does obey locale. - */ -static int64_t -tar_atol_base_n(const char *p, size_t char_cnt, int base) -{ - int64_t l, maxval, limit, last_digit_limit; - int digit, sign; - - maxval = INT64_MAX; - limit = INT64_MAX / base; - last_digit_limit = INT64_MAX % base; - - /* the pointer will not be dereferenced if char_cnt is zero - * due to the way the && operator is evaluated. - */ - while (char_cnt != 0 && (*p == ' ' || *p == '\t')) { - p++; - char_cnt--; - } - - sign = 1; - if (char_cnt != 0 && *p == '-') { - sign = -1; - p++; - char_cnt--; - - maxval = INT64_MIN; - limit = -(INT64_MIN / base); - last_digit_limit = -(INT64_MIN % base); - } - - l = 0; - if (char_cnt != 0) { - digit = *p - '0'; - while (digit >= 0 && digit < base && char_cnt != 0) { - if (l>limit || (l == limit && digit >= last_digit_limit)) { - return maxval; /* Truncate on overflow. */ - } - l = (l * base) + digit; - digit = *++p - '0'; - char_cnt--; - } - } - return (sign < 0) ? -l : l; -} - -static int64_t -tar_atol8(const char *p, size_t char_cnt) -{ - return tar_atol_base_n(p, char_cnt, 8); -} - -static int64_t -tar_atol10(const char *p, size_t char_cnt) -{ - return tar_atol_base_n(p, char_cnt, 10); -} - -/* - * Parse a base-256 integer. This is just a variable-length - * twos-complement signed binary value in big-endian order, except - * that the high-order bit is ignored. The values here can be up to - * 12 bytes, so we need to be careful about overflowing 64-bit - * (8-byte) integers. - * - * This code unashamedly assumes that the local machine uses 8-bit - * bytes and twos-complement arithmetic. - */ -static int64_t -tar_atol256(const char *_p, size_t char_cnt) -{ - uint64_t l; - const unsigned char *p = (const unsigned char *)_p; - unsigned char c, neg; - - /* Extend 7-bit 2s-comp to 8-bit 2s-comp, decide sign. */ - c = *p; - if (c & 0x40) { - neg = 0xff; - c |= 0x80; - l = ~ARCHIVE_LITERAL_ULL(0); - } else { - neg = 0; - c &= 0x7f; - l = 0; - } - - /* If more than 8 bytes, check that we can ignore - * high-order bits without overflow. */ - while (char_cnt > sizeof(int64_t)) { - --char_cnt; - if (c != neg) - return neg ? INT64_MIN : INT64_MAX; - c = *++p; - } - - /* c is first byte that fits; if sign mismatch, return overflow */ - if ((c ^ neg) & 0x80) { - return neg ? INT64_MIN : INT64_MAX; - } - - /* Accumulate remaining bytes. */ - while (--char_cnt > 0) { - l = (l << 8) | c; - c = *++p; - } - l = (l << 8) | c; - /* Return signed twos-complement value. */ - return (int64_t)(l); -} - -/* - * Returns length of line (including trailing newline) - * or negative on error. 'start' argument is updated to - * point to first character of line. This avoids copying - * when possible. - */ -static ssize_t -readline(struct archive_read *a, struct tar *tar, const char **start, - ssize_t limit, size_t *unconsumed) -{ - ssize_t bytes_read; - ssize_t total_size = 0; - const void *t; - const char *s; - void *p; - - tar_flush_unconsumed(a, unconsumed); - - t = __archive_read_ahead(a, 1, &bytes_read); - if (bytes_read <= 0) - return (ARCHIVE_FATAL); - s = t; /* Start of line? */ - p = memchr(t, '\n', bytes_read); - /* If we found '\n' in the read buffer, return pointer to that. */ - if (p != NULL) { - bytes_read = 1 + ((const char *)p) - s; - if (bytes_read > limit) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Line too long"); - return (ARCHIVE_FATAL); - } - *unconsumed = bytes_read; - *start = s; - return (bytes_read); - } - *unconsumed = bytes_read; - /* Otherwise, we need to accumulate in a line buffer. */ - for (;;) { - if (total_size + bytes_read > limit) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Line too long"); - return (ARCHIVE_FATAL); - } - if (archive_string_ensure(&tar->line, total_size + bytes_read) == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate working buffer"); - return (ARCHIVE_FATAL); - } - memcpy(tar->line.s + total_size, t, bytes_read); - tar_flush_unconsumed(a, unconsumed); - total_size += bytes_read; - /* If we found '\n', clean up and return. */ - if (p != NULL) { - *start = tar->line.s; - return (total_size); - } - /* Read some more. */ - t = __archive_read_ahead(a, 1, &bytes_read); - if (bytes_read <= 0) - return (ARCHIVE_FATAL); - s = t; /* Start of line? */ - p = memchr(t, '\n', bytes_read); - /* If we found '\n', trim the read. */ - if (p != NULL) { - bytes_read = 1 + ((const char *)p) - s; - } - *unconsumed = bytes_read; - } -} - -/* - * base64_decode - Base64 decode - * - * This accepts most variations of base-64 encoding, including: - * * with or without line breaks - * * with or without the final group padded with '=' or '_' characters - * (The most economical Base-64 variant does not pad the last group and - * omits line breaks; RFC1341 used for MIME requires both.) - */ -static char * -base64_decode(const char *s, size_t len, size_t *out_len) -{ - static const unsigned char digits[64] = { - 'A','B','C','D','E','F','G','H','I','J','K','L','M','N', - 'O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b', - 'c','d','e','f','g','h','i','j','k','l','m','n','o','p', - 'q','r','s','t','u','v','w','x','y','z','0','1','2','3', - '4','5','6','7','8','9','+','/' }; - static unsigned char decode_table[128]; - char *out, *d; - const unsigned char *src = (const unsigned char *)s; - - /* If the decode table is not yet initialized, prepare it. */ - if (decode_table[digits[1]] != 1) { - unsigned i; - memset(decode_table, 0xff, sizeof(decode_table)); - for (i = 0; i < sizeof(digits); i++) - decode_table[digits[i]] = i; - } - - /* Allocate enough space to hold the entire output. */ - /* Note that we may not use all of this... */ - out = (char *)malloc(len - len / 4 + 1); - if (out == NULL) { - *out_len = 0; - return (NULL); - } - d = out; - - while (len > 0) { - /* Collect the next group of (up to) four characters. */ - int v = 0; - int group_size = 0; - while (group_size < 4 && len > 0) { - /* '=' or '_' padding indicates final group. */ - if (*src == '=' || *src == '_') { - len = 0; - break; - } - /* Skip illegal characters (including line breaks) */ - if (*src > 127 || *src < 32 - || decode_table[*src] == 0xff) { - len--; - src++; - continue; - } - v <<= 6; - v |= decode_table[*src++]; - len --; - group_size++; - } - /* Align a short group properly. */ - v <<= 6 * (4 - group_size); - /* Unpack the group we just collected. */ - switch (group_size) { - case 4: d[2] = v & 0xff; - /* FALLTHROUGH */ - case 3: d[1] = (v >> 8) & 0xff; - /* FALLTHROUGH */ - case 2: d[0] = (v >> 16) & 0xff; - break; - case 1: /* this is invalid! */ - break; - } - d += group_size * 3 / 4; - } - - *out_len = d - out; - return (out); -} - -static char * -url_decode(const char *in) -{ - char *out, *d; - const char *s; - - out = (char *)malloc(strlen(in) + 1); - if (out == NULL) - return (NULL); - for (s = in, d = out; *s != '\0'; ) { - if (s[0] == '%' && s[1] != '\0' && s[2] != '\0') { - /* Try to convert % escape */ - int digit1 = tohex(s[1]); - int digit2 = tohex(s[2]); - if (digit1 >= 0 && digit2 >= 0) { - /* Looks good, consume three chars */ - s += 3; - /* Convert output */ - *d++ = ((digit1 << 4) | digit2); - continue; - } - /* Else fall through and treat '%' as normal char */ - } - *d++ = *s++; - } - *d = '\0'; - return (out); -} - -static int -tohex(int c) -{ - if (c >= '0' && c <= '9') - return (c - '0'); - else if (c >= 'A' && c <= 'F') - return (c - 'A' + 10); - else if (c >= 'a' && c <= 'f') - return (c - 'a' + 10); - else - return (-1); -} diff --git a/thirdparty/libarchive/libarchive/archive_read_support_format_warc.c b/thirdparty/libarchive/libarchive/archive_read_support_format_warc.c deleted file mode 100644 index 61ab29ea1..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_format_warc.c +++ /dev/null @@ -1,848 +0,0 @@ -/*- - * Copyright (c) 2014 Sebastian Freundt - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -/** - * WARC is standardised by ISO TC46/SC4/WG12 and currently available as - * ISO 28500:2009. - * For the purposes of this file we used the final draft from: - * http://bibnum.bnf.fr/warc/WARC_ISO_28500_version1_latestdraft.pdf - * - * Todo: - * [ ] real-world warcs can contain resources at endpoints ending in / - * e.g. http://bibnum.bnf.fr/warc/ - * if you're lucky their response contains a Content-Location: header - * pointing to a unix-compliant filename, in the example above it's - * Content-Location: http://bibnum.bnf.fr/warc/index.html - * however, that's not mandated and github for example doesn't follow - * this convention. - * We need a set of archive options to control what to do with - * entries like these, at the moment care is taken to skip them. - * - **/ - -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_LIMITS_H -#include -#endif -#ifdef HAVE_CTYPE_H -#include -#endif -#ifdef HAVE_TIME_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" -#include "archive_private.h" -#include "archive_read_private.h" - -typedef enum { - WT_NONE, - /* warcinfo */ - WT_INFO, - /* metadata */ - WT_META, - /* resource */ - WT_RSRC, - /* request, unsupported */ - WT_REQ, - /* response, unsupported */ - WT_RSP, - /* revisit, unsupported */ - WT_RVIS, - /* conversion, unsupported */ - WT_CONV, - /* continuation, unsupported at the moment */ - WT_CONT, - /* invalid type */ - LAST_WT -} warc_type_t; - -typedef struct { - size_t len; - const char *str; -} warc_string_t; - -typedef struct { - size_t len; - char *str; -} warc_strbuf_t; - -struct warc_s { - /* content length ahead */ - size_t cntlen; - /* and how much we've processed so far */ - size_t cntoff; - /* and how much we need to consume between calls */ - size_t unconsumed; - - /* string pool */ - warc_strbuf_t pool; - /* previous version */ - unsigned int pver; - /* stringified format name */ - struct archive_string sver; -}; - -static int _warc_bid(struct archive_read *a, int); -static int _warc_cleanup(struct archive_read *a); -static int _warc_read(struct archive_read*, const void**, size_t*, int64_t*); -static int _warc_skip(struct archive_read *a); -static int _warc_rdhdr(struct archive_read *a, struct archive_entry *e); - -/* private routines */ -static unsigned int _warc_rdver(const char *buf, size_t bsz); -static unsigned int _warc_rdtyp(const char *buf, size_t bsz); -static warc_string_t _warc_rduri(const char *buf, size_t bsz); -static ssize_t _warc_rdlen(const char *buf, size_t bsz); -static time_t _warc_rdrtm(const char *buf, size_t bsz); -static time_t _warc_rdmtm(const char *buf, size_t bsz); -static const char *_warc_find_eoh(const char *buf, size_t bsz); -static const char *_warc_find_eol(const char *buf, size_t bsz); - -int -archive_read_support_format_warc(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - struct warc_s *w; - int r; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_format_warc"); - - if ((w = calloc(1, sizeof(*w))) == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate warc data"); - return (ARCHIVE_FATAL); - } - - r = __archive_read_register_format( - a, w, "warc", - _warc_bid, NULL, _warc_rdhdr, _warc_read, - _warc_skip, NULL, _warc_cleanup, NULL, NULL); - - if (r != ARCHIVE_OK) { - free(w); - return (r); - } - return (ARCHIVE_OK); -} - -static int -_warc_cleanup(struct archive_read *a) -{ - struct warc_s *w = a->format->data; - - if (w->pool.len > 0U) { - free(w->pool.str); - } - archive_string_free(&w->sver); - free(w); - a->format->data = NULL; - return (ARCHIVE_OK); -} - -static int -_warc_bid(struct archive_read *a, int best_bid) -{ - const char *hdr; - ssize_t nrd; - unsigned int ver; - - (void)best_bid; /* UNUSED */ - - /* check first line of file, it should be a record already */ - if ((hdr = __archive_read_ahead(a, 12U, &nrd)) == NULL) { - /* no idea what to do */ - return -1; - } else if (nrd < 12) { - /* nah, not for us, our magic cookie is at least 12 bytes */ - return -1; - } - - /* otherwise snarf the record's version number */ - ver = _warc_rdver(hdr, nrd); - if (ver < 1200U || ver > 10000U) { - /* we only support WARC 0.12 to 1.0 */ - return -1; - } - - /* otherwise be confident */ - return (64); -} - -static int -_warc_rdhdr(struct archive_read *a, struct archive_entry *entry) -{ -#define HDR_PROBE_LEN (12U) - struct warc_s *w = a->format->data; - unsigned int ver; - const char *buf; - ssize_t nrd; - const char *eoh; - /* for the file name, saves some strndup()'ing */ - warc_string_t fnam; - /* warc record type, not that we really use it a lot */ - warc_type_t ftyp; - /* content-length+error monad */ - ssize_t cntlen; - /* record time is the WARC-Date time we reinterpret it as ctime */ - time_t rtime; - /* mtime is the Last-Modified time which will be the entry's mtime */ - time_t mtime; - -start_over: - /* just use read_ahead() they keep track of unconsumed - * bits and bobs for us; no need to put an extra shift in - * and reproduce that functionality here */ - buf = __archive_read_ahead(a, HDR_PROBE_LEN, &nrd); - - if (nrd < 0) { - /* no good */ - archive_set_error( - &a->archive, ARCHIVE_ERRNO_MISC, - "Bad record header"); - return (ARCHIVE_FATAL); - } else if (buf == NULL) { - /* there should be room for at least WARC/bla\r\n - * must be EOF therefore */ - return (ARCHIVE_EOF); - } - /* looks good so far, try and find the end of the header now */ - eoh = _warc_find_eoh(buf, nrd); - if (eoh == NULL) { - /* still no good, the header end might be beyond the - * probe we've requested, but then again who'd cram - * so much stuff into the header *and* be 28500-compliant */ - archive_set_error( - &a->archive, ARCHIVE_ERRNO_MISC, - "Bad record header"); - return (ARCHIVE_FATAL); - } - ver = _warc_rdver(buf, eoh - buf); - /* we currently support WARC 0.12 to 1.0 */ - if (ver == 0U) { - archive_set_error( - &a->archive, ARCHIVE_ERRNO_MISC, - "Invalid record version"); - return (ARCHIVE_FATAL); - } else if (ver < 1200U || ver > 10000U) { - archive_set_error( - &a->archive, ARCHIVE_ERRNO_MISC, - "Unsupported record version: %u.%u", - ver / 10000, (ver % 10000) / 100); - return (ARCHIVE_FATAL); - } - cntlen = _warc_rdlen(buf, eoh - buf); - if (cntlen < 0) { - /* nightmare! the specs say content-length is mandatory - * so I don't feel overly bad stopping the reader here */ - archive_set_error( - &a->archive, EINVAL, - "Bad content length"); - return (ARCHIVE_FATAL); - } - rtime = _warc_rdrtm(buf, eoh - buf); - if (rtime == (time_t)-1) { - /* record time is mandatory as per WARC/1.0, - * so just barf here, fast and loud */ - archive_set_error( - &a->archive, EINVAL, - "Bad record time"); - return (ARCHIVE_FATAL); - } - - /* let the world know we're a WARC archive */ - a->archive.archive_format = ARCHIVE_FORMAT_WARC; - if (ver != w->pver) { - /* stringify this entry's version */ - archive_string_sprintf(&w->sver, - "WARC/%u.%u", ver / 10000, (ver % 10000) / 100); - /* remember the version */ - w->pver = ver; - } - /* start off with the type */ - ftyp = _warc_rdtyp(buf, eoh - buf); - /* and let future calls know about the content */ - w->cntlen = cntlen; - w->cntoff = 0U; - mtime = 0;/* Avoid compiling error on some platform. */ - - switch (ftyp) { - case WT_RSRC: - case WT_RSP: - /* only try and read the filename in the cases that are - * guaranteed to have one */ - fnam = _warc_rduri(buf, eoh - buf); - /* check the last character in the URI to avoid creating - * directory endpoints as files, see Todo above */ - if (fnam.len == 0 || fnam.str[fnam.len - 1] == '/') { - /* break here for now */ - fnam.len = 0U; - fnam.str = NULL; - break; - } - /* bang to our string pool, so we save a - * malloc()+free() roundtrip */ - if (fnam.len + 1U > w->pool.len) { - w->pool.len = ((fnam.len + 64U) / 64U) * 64U; - w->pool.str = realloc(w->pool.str, w->pool.len); - } - memcpy(w->pool.str, fnam.str, fnam.len); - w->pool.str[fnam.len] = '\0'; - /* let no one else know about the pool, it's a secret, shhh */ - fnam.str = w->pool.str; - - /* snarf mtime or deduce from rtime - * this is a custom header added by our writer, it's quite - * hard to believe anyone else would go through with it - * (apart from being part of some http responses of course) */ - if ((mtime = _warc_rdmtm(buf, eoh - buf)) == (time_t)-1) { - mtime = rtime; - } - break; - case WT_NONE: - case WT_INFO: - case WT_META: - case WT_REQ: - case WT_RVIS: - case WT_CONV: - case WT_CONT: - case LAST_WT: - default: - fnam.len = 0U; - fnam.str = NULL; - break; - } - - /* now eat some of those delicious buffer bits */ - __archive_read_consume(a, eoh - buf); - - switch (ftyp) { - case WT_RSRC: - case WT_RSP: - if (fnam.len > 0U) { - /* populate entry object */ - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_copy_pathname(entry, fnam.str); - archive_entry_set_size(entry, cntlen); - archive_entry_set_perm(entry, 0644); - /* rtime is the new ctime, mtime stays mtime */ - archive_entry_set_ctime(entry, rtime, 0L); - archive_entry_set_mtime(entry, mtime, 0L); - break; - } - /* FALLTHROUGH */ - case WT_NONE: - case WT_INFO: - case WT_META: - case WT_REQ: - case WT_RVIS: - case WT_CONV: - case WT_CONT: - case LAST_WT: - default: - /* consume the content and start over */ - _warc_skip(a); - goto start_over; - } - return (ARCHIVE_OK); -} - -static int -_warc_read(struct archive_read *a, const void **buf, size_t *bsz, int64_t *off) -{ - struct warc_s *w = a->format->data; - const char *rab; - ssize_t nrd; - - if (w->cntoff >= w->cntlen) { - eof: - /* it's our lucky day, no work, we can leave early */ - *buf = NULL; - *bsz = 0U; - *off = w->cntoff + 4U/*for \r\n\r\n separator*/; - w->unconsumed = 0U; - return (ARCHIVE_EOF); - } - - if (w->unconsumed) { - __archive_read_consume(a, w->unconsumed); - w->unconsumed = 0U; - } - - rab = __archive_read_ahead(a, 1U, &nrd); - if (nrd < 0) { - *bsz = 0U; - /* big catastrophe */ - return (int)nrd; - } else if (nrd == 0) { - goto eof; - } else if ((size_t)nrd > w->cntlen - w->cntoff) { - /* clamp to content-length */ - nrd = w->cntlen - w->cntoff; - } - *off = w->cntoff; - *bsz = nrd; - *buf = rab; - - w->cntoff += nrd; - w->unconsumed = (size_t)nrd; - return (ARCHIVE_OK); -} - -static int -_warc_skip(struct archive_read *a) -{ - struct warc_s *w = a->format->data; - - __archive_read_consume(a, w->cntlen + 4U/*\r\n\r\n separator*/); - w->cntlen = 0U; - w->cntoff = 0U; - return (ARCHIVE_OK); -} - - -/* private routines */ -static void* -deconst(const void *c) -{ - return (void *)(uintptr_t)c; -} - -static char* -xmemmem(const char *hay, const size_t haysize, - const char *needle, const size_t needlesize) -{ - const char *const eoh = hay + haysize; - const char *const eon = needle + needlesize; - const char *hp; - const char *np; - const char *cand; - unsigned int hsum; - unsigned int nsum; - unsigned int eqp; - - /* trivial checks first - * a 0-sized needle is defined to be found anywhere in haystack - * then run strchr() to find a candidate in HAYSTACK (i.e. a portion - * that happens to begin with *NEEDLE) */ - if (needlesize == 0UL) { - return deconst(hay); - } else if ((hay = memchr(hay, *needle, haysize)) == NULL) { - /* trivial */ - return NULL; - } - - /* First characters of haystack and needle are the same now. Both are - * guaranteed to be at least one character long. Now computes the sum - * of characters values of needle together with the sum of the first - * needle_len characters of haystack. */ - for (hp = hay + 1U, np = needle + 1U, hsum = *hay, nsum = *hay, eqp = 1U; - hp < eoh && np < eon; - hsum ^= *hp, nsum ^= *np, eqp &= *hp == *np, hp++, np++); - - /* HP now references the (NEEDLESIZE + 1)-th character. */ - if (np < eon) { - /* haystack is smaller than needle, :O */ - return NULL; - } else if (eqp) { - /* found a match */ - return deconst(hay); - } - - /* now loop through the rest of haystack, - * updating the sum iteratively */ - for (cand = hay; hp < eoh; hp++) { - hsum ^= *cand++; - hsum ^= *hp; - - /* Since the sum of the characters is already known to be - * equal at that point, it is enough to check just NEEDLESIZE - 1 - * characters for equality, - * also CAND is by design < HP, so no need for range checks */ - if (hsum == nsum && memcmp(cand, needle, needlesize - 1U) == 0) { - return deconst(cand); - } - } - return NULL; -} - -static int -strtoi_lim(const char *str, const char **ep, int llim, int ulim) -{ - int res = 0; - const char *sp; - /* we keep track of the number of digits via rulim */ - int rulim; - - for (sp = str, rulim = ulim > 10 ? ulim : 10; - res * 10 <= ulim && rulim && *sp >= '0' && *sp <= '9'; - sp++, rulim /= 10) { - res *= 10; - res += *sp - '0'; - } - if (sp == str) { - res = -1; - } else if (res < llim || res > ulim) { - res = -2; - } - *ep = (const char*)sp; - return res; -} - -static time_t -time_from_tm(struct tm *t) -{ -#if HAVE__MKGMTIME - return _mkgmtime(t); -#elif HAVE_TIMEGM - /* Use platform timegm() if available. */ - return (timegm(t)); -#else - /* Else use direct calculation using POSIX assumptions. */ - /* First, fix up tm_yday based on the year/month/day. */ - if (mktime(t) == (time_t)-1) - return ((time_t)-1); - /* Then we can compute timegm() from first principles. */ - return (t->tm_sec - + t->tm_min * 60 - + t->tm_hour * 3600 - + t->tm_yday * 86400 - + (t->tm_year - 70) * 31536000 - + ((t->tm_year - 69) / 4) * 86400 - - ((t->tm_year - 1) / 100) * 86400 - + ((t->tm_year + 299) / 400) * 86400); -#endif -} - -static time_t -xstrpisotime(const char *s, char **endptr) -{ -/** like strptime() but strictly for ISO 8601 Zulu strings */ - struct tm tm; - time_t res = (time_t)-1; - - /* make sure tm is clean */ - memset(&tm, 0, sizeof(tm)); - - /* as a courtesy to our callers, and since this is a non-standard - * routine, we skip leading whitespace */ - while (*s == ' ' || *s == '\t') - ++s; - - /* read year */ - if ((tm.tm_year = strtoi_lim(s, &s, 1583, 4095)) < 0 || *s++ != '-') { - goto out; - } - /* read month */ - if ((tm.tm_mon = strtoi_lim(s, &s, 1, 12)) < 0 || *s++ != '-') { - goto out; - } - /* read day-of-month */ - if ((tm.tm_mday = strtoi_lim(s, &s, 1, 31)) < 0 || *s++ != 'T') { - goto out; - } - /* read hour */ - if ((tm.tm_hour = strtoi_lim(s, &s, 0, 23)) < 0 || *s++ != ':') { - goto out; - } - /* read minute */ - if ((tm.tm_min = strtoi_lim(s, &s, 0, 59)) < 0 || *s++ != ':') { - goto out; - } - /* read second */ - if ((tm.tm_sec = strtoi_lim(s, &s, 0, 60)) < 0 || *s++ != 'Z') { - goto out; - } - - /* massage TM to fulfill some of POSIX' constraints */ - tm.tm_year -= 1900; - tm.tm_mon--; - - /* now convert our custom tm struct to a unix stamp using UTC */ - res = time_from_tm(&tm); - -out: - if (endptr != NULL) { - *endptr = deconst(s); - } - return res; -} - -static unsigned int -_warc_rdver(const char *buf, size_t bsz) -{ - static const char magic[] = "WARC/"; - const char *c; - unsigned int ver = 0U; - unsigned int end = 0U; - - if (bsz < 12 || memcmp(buf, magic, sizeof(magic) - 1U) != 0) { - /* buffer too small or invalid magic */ - return ver; - } - /* looks good so far, read the version number for a laugh */ - buf += sizeof(magic) - 1U; - - if (isdigit((unsigned char)buf[0U]) && (buf[1U] == '.') && - isdigit((unsigned char)buf[2U])) { - /* we support a maximum of 2 digits in the minor version */ - if (isdigit((unsigned char)buf[3U])) - end = 1U; - /* set up major version */ - ver = (buf[0U] - '0') * 10000U; - /* set up minor version */ - if (end == 1U) { - ver += (buf[2U] - '0') * 1000U; - ver += (buf[3U] - '0') * 100U; - } else - ver += (buf[2U] - '0') * 100U; - /* - * WARC below version 0.12 has a space-separated header - * WARC 0.12 and above terminates the version with a CRLF - */ - c = buf + 3U + end; - if (ver >= 1200U) { - if (memcmp(c, "\r\n", 2U) != 0) - ver = 0U; - } else { - /* ver < 1200U */ - if (*c != ' ' && *c != '\t') - ver = 0U; - } - } - return ver; -} - -static unsigned int -_warc_rdtyp(const char *buf, size_t bsz) -{ - static const char _key[] = "\r\nWARC-Type:"; - const char *val, *eol; - - if ((val = xmemmem(buf, bsz, _key, sizeof(_key) - 1U)) == NULL) { - /* no bother */ - return WT_NONE; - } - val += sizeof(_key) - 1U; - if ((eol = _warc_find_eol(val, buf + bsz - val)) == NULL) { - /* no end of line */ - return WT_NONE; - } - - /* overread whitespace */ - while (val < eol && (*val == ' ' || *val == '\t')) - ++val; - - if (val + 8U == eol) { - if (memcmp(val, "resource", 8U) == 0) - return WT_RSRC; - else if (memcmp(val, "response", 8U) == 0) - return WT_RSP; - } - return WT_NONE; -} - -static warc_string_t -_warc_rduri(const char *buf, size_t bsz) -{ - static const char _key[] = "\r\nWARC-Target-URI:"; - const char *val, *uri, *eol, *p; - warc_string_t res = {0U, NULL}; - - if ((val = xmemmem(buf, bsz, _key, sizeof(_key) - 1U)) == NULL) { - /* no bother */ - return res; - } - /* overread whitespace */ - val += sizeof(_key) - 1U; - if ((eol = _warc_find_eol(val, buf + bsz - val)) == NULL) { - /* no end of line */ - return res; - } - - while (val < eol && (*val == ' ' || *val == '\t')) - ++val; - - /* overread URL designators */ - if ((uri = xmemmem(val, eol - val, "://", 3U)) == NULL) { - /* not touching that! */ - return res; - } - - /* spaces inside uri are not allowed, CRLF should follow */ - for (p = val; p < eol; p++) { - if (isspace((unsigned char)*p)) - return res; - } - - /* there must be at least space for ftp */ - if (uri < (val + 3U)) - return res; - - /* move uri to point to after :// */ - uri += 3U; - - /* now then, inspect the URI */ - if (memcmp(val, "file", 4U) == 0) { - /* perfect, nothing left to do here */ - - } else if (memcmp(val, "http", 4U) == 0 || - memcmp(val, "ftp", 3U) == 0) { - /* overread domain, and the first / */ - while (uri < eol && *uri++ != '/'); - } else { - /* not sure what to do? best to bugger off */ - return res; - } - res.str = uri; - res.len = eol - uri; - return res; -} - -static ssize_t -_warc_rdlen(const char *buf, size_t bsz) -{ - static const char _key[] = "\r\nContent-Length:"; - const char *val, *eol; - char *on = NULL; - long int len; - - if ((val = xmemmem(buf, bsz, _key, sizeof(_key) - 1U)) == NULL) { - /* no bother */ - return -1; - } - val += sizeof(_key) - 1U; - if ((eol = _warc_find_eol(val, buf + bsz - val)) == NULL) { - /* no end of line */ - return -1; - } - - /* skip leading whitespace */ - while (val < eol && (*val == ' ' || *val == '\t')) - val++; - /* there must be at least one digit */ - if (!isdigit((unsigned char)*val)) - return -1; - errno = 0; - len = strtol(val, &on, 10); - if (errno != 0 || on != eol) { - /* line must end here */ - return -1; - } - - return (size_t)len; -} - -static time_t -_warc_rdrtm(const char *buf, size_t bsz) -{ - static const char _key[] = "\r\nWARC-Date:"; - const char *val, *eol; - char *on = NULL; - time_t res; - - if ((val = xmemmem(buf, bsz, _key, sizeof(_key) - 1U)) == NULL) { - /* no bother */ - return (time_t)-1; - } - val += sizeof(_key) - 1U; - if ((eol = _warc_find_eol(val, buf + bsz - val)) == NULL ) { - /* no end of line */ - return -1; - } - - /* xstrpisotime() kindly overreads whitespace for us, so use that */ - res = xstrpisotime(val, &on); - if (on != eol) { - /* line must end here */ - return -1; - } - return res; -} - -static time_t -_warc_rdmtm(const char *buf, size_t bsz) -{ - static const char _key[] = "\r\nLast-Modified:"; - const char *val, *eol; - char *on = NULL; - time_t res; - - if ((val = xmemmem(buf, bsz, _key, sizeof(_key) - 1U)) == NULL) { - /* no bother */ - return (time_t)-1; - } - val += sizeof(_key) - 1U; - if ((eol = _warc_find_eol(val, buf + bsz - val)) == NULL ) { - /* no end of line */ - return -1; - } - - /* xstrpisotime() kindly overreads whitespace for us, so use that */ - res = xstrpisotime(val, &on); - if (on != eol) { - /* line must end here */ - return -1; - } - return res; -} - -static const char* -_warc_find_eoh(const char *buf, size_t bsz) -{ - static const char _marker[] = "\r\n\r\n"; - const char *hit = xmemmem(buf, bsz, _marker, sizeof(_marker) - 1U); - - if (hit != NULL) { - hit += sizeof(_marker) - 1U; - } - return hit; -} - -static const char* -_warc_find_eol(const char *buf, size_t bsz) -{ - static const char _marker[] = "\r\n"; - const char *hit = xmemmem(buf, bsz, _marker, sizeof(_marker) - 1U); - - return hit; -} -/* archive_read_support_format_warc.c ends here */ diff --git a/thirdparty/libarchive/libarchive/archive_read_support_format_xar.c b/thirdparty/libarchive/libarchive/archive_read_support_format_xar.c deleted file mode 100644 index ec9cb1981..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_format_xar.c +++ /dev/null @@ -1,3332 +0,0 @@ -/*- - * Copyright (c) 2009 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#if HAVE_LIBXML_XMLREADER_H -#include -#elif HAVE_BSDXML_H -#include -#elif HAVE_EXPAT_H -#include -#endif -#ifdef HAVE_BZLIB_H -#include -#endif -#if HAVE_LZMA_H -#include -#endif -#ifdef HAVE_ZLIB_H -#include -#endif - -#include "archive.h" -#include "archive_digest_private.h" -#include "archive_endian.h" -#include "archive_entry.h" -#include "archive_entry_locale.h" -#include "archive_private.h" -#include "archive_read_private.h" - -#if (!defined(HAVE_LIBXML_XMLREADER_H) && \ - !defined(HAVE_BSDXML_H) && !defined(HAVE_EXPAT_H)) ||\ - !defined(HAVE_ZLIB_H) || \ - !defined(ARCHIVE_HAS_MD5) || !defined(ARCHIVE_HAS_SHA1) -/* - * xar needs several external libraries. - * o libxml2 or expat --- XML parser - * o openssl or MD5/SHA1 hash function - * o zlib - * o bzlib2 (option) - * o liblzma (option) - */ -int -archive_read_support_format_xar(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_format_xar"); - - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Xar not supported on this platform"); - return (ARCHIVE_WARN); -} - -#else /* Support xar format */ - -/* #define DEBUG 1 */ -/* #define DEBUG_PRINT_TOC 1 */ -#if DEBUG_PRINT_TOC -#define PRINT_TOC(d, outbytes) do { \ - unsigned char *x = (unsigned char *)(uintptr_t)d; \ - unsigned char c = x[outbytes-1]; \ - x[outbytes - 1] = 0; \ - fprintf(stderr, "%s", x); \ - fprintf(stderr, "%c", c); \ - x[outbytes - 1] = c; \ -} while (0) -#else -#define PRINT_TOC(d, outbytes) -#endif - -#define HEADER_MAGIC 0x78617221 -#define HEADER_SIZE 28 -#define HEADER_VERSION 1 -#define CKSUM_NONE 0 -#define CKSUM_SHA1 1 -#define CKSUM_MD5 2 - -#define MD5_SIZE 16 -#define SHA1_SIZE 20 -#define MAX_SUM_SIZE 20 - -enum enctype { - NONE, - GZIP, - BZIP2, - LZMA, - XZ, -}; - -struct chksumval { - int alg; - size_t len; - unsigned char val[MAX_SUM_SIZE]; -}; - -struct chksumwork { - int alg; -#ifdef ARCHIVE_HAS_MD5 - archive_md5_ctx md5ctx; -#endif -#ifdef ARCHIVE_HAS_SHA1 - archive_sha1_ctx sha1ctx; -#endif -}; - -struct xattr { - struct xattr *next; - struct archive_string name; - uint64_t id; - uint64_t length; - uint64_t offset; - uint64_t size; - enum enctype encoding; - struct chksumval a_sum; - struct chksumval e_sum; - struct archive_string fstype; -}; - -struct xar_file { - struct xar_file *next; - struct xar_file *hdnext; - struct xar_file *parent; - int subdirs; - - unsigned int has; -#define HAS_DATA 0x00001 -#define HAS_PATHNAME 0x00002 -#define HAS_SYMLINK 0x00004 -#define HAS_TIME 0x00008 -#define HAS_UID 0x00010 -#define HAS_GID 0x00020 -#define HAS_MODE 0x00040 -#define HAS_TYPE 0x00080 -#define HAS_DEV 0x00100 -#define HAS_DEVMAJOR 0x00200 -#define HAS_DEVMINOR 0x00400 -#define HAS_INO 0x00800 -#define HAS_FFLAGS 0x01000 -#define HAS_XATTR 0x02000 -#define HAS_ACL 0x04000 -#define HAS_CTIME 0x08000 -#define HAS_MTIME 0x10000 -#define HAS_ATIME 0x20000 - - uint64_t id; - uint64_t length; - uint64_t offset; - uint64_t size; - enum enctype encoding; - struct chksumval a_sum; - struct chksumval e_sum; - struct archive_string pathname; - struct archive_string symlink; - time_t ctime; - time_t mtime; - time_t atime; - struct archive_string uname; - int64_t uid; - struct archive_string gname; - int64_t gid; - mode_t mode; - dev_t dev; - dev_t devmajor; - dev_t devminor; - int64_t ino64; - struct archive_string fflags_text; - unsigned int link; - unsigned int nlink; - struct archive_string hardlink; - struct xattr *xattr_list; -}; - -struct hdlink { - struct hdlink *next; - - unsigned int id; - int cnt; - struct xar_file *files; -}; - -struct heap_queue { - struct xar_file **files; - int allocated; - int used; -}; - -enum xmlstatus { - INIT, - XAR, - TOC, - TOC_CREATION_TIME, - TOC_CHECKSUM, - TOC_CHECKSUM_OFFSET, - TOC_CHECKSUM_SIZE, - TOC_FILE, - FILE_DATA, - FILE_DATA_LENGTH, - FILE_DATA_OFFSET, - FILE_DATA_SIZE, - FILE_DATA_ENCODING, - FILE_DATA_A_CHECKSUM, - FILE_DATA_E_CHECKSUM, - FILE_DATA_CONTENT, - FILE_EA, - FILE_EA_LENGTH, - FILE_EA_OFFSET, - FILE_EA_SIZE, - FILE_EA_ENCODING, - FILE_EA_A_CHECKSUM, - FILE_EA_E_CHECKSUM, - FILE_EA_NAME, - FILE_EA_FSTYPE, - FILE_CTIME, - FILE_MTIME, - FILE_ATIME, - FILE_GROUP, - FILE_GID, - FILE_USER, - FILE_UID, - FILE_MODE, - FILE_DEVICE, - FILE_DEVICE_MAJOR, - FILE_DEVICE_MINOR, - FILE_DEVICENO, - FILE_INODE, - FILE_LINK, - FILE_TYPE, - FILE_NAME, - FILE_ACL, - FILE_ACL_DEFAULT, - FILE_ACL_ACCESS, - FILE_ACL_APPLEEXTENDED, - /* BSD file flags. */ - FILE_FLAGS, - FILE_FLAGS_USER_NODUMP, - FILE_FLAGS_USER_IMMUTABLE, - FILE_FLAGS_USER_APPEND, - FILE_FLAGS_USER_OPAQUE, - FILE_FLAGS_USER_NOUNLINK, - FILE_FLAGS_SYS_ARCHIVED, - FILE_FLAGS_SYS_IMMUTABLE, - FILE_FLAGS_SYS_APPEND, - FILE_FLAGS_SYS_NOUNLINK, - FILE_FLAGS_SYS_SNAPSHOT, - /* Linux file flags. */ - FILE_EXT2, - FILE_EXT2_SecureDeletion, - FILE_EXT2_Undelete, - FILE_EXT2_Compress, - FILE_EXT2_Synchronous, - FILE_EXT2_Immutable, - FILE_EXT2_AppendOnly, - FILE_EXT2_NoDump, - FILE_EXT2_NoAtime, - FILE_EXT2_CompDirty, - FILE_EXT2_CompBlock, - FILE_EXT2_NoCompBlock, - FILE_EXT2_CompError, - FILE_EXT2_BTree, - FILE_EXT2_HashIndexed, - FILE_EXT2_iMagic, - FILE_EXT2_Journaled, - FILE_EXT2_NoTail, - FILE_EXT2_DirSync, - FILE_EXT2_TopDir, - FILE_EXT2_Reserved, - UNKNOWN, -}; - -struct unknown_tag { - struct unknown_tag *next; - struct archive_string name; -}; - -struct xar { - uint64_t offset; /* Current position in the file. */ - int64_t total; - uint64_t h_base; - int end_of_file; -#define OUTBUFF_SIZE (1024 * 64) - unsigned char *outbuff; - - enum xmlstatus xmlsts; - enum xmlstatus xmlsts_unknown; - struct unknown_tag *unknowntags; - int base64text; - - /* - * TOC - */ - uint64_t toc_remaining; - uint64_t toc_total; - uint64_t toc_chksum_offset; - uint64_t toc_chksum_size; - - /* - * For Decoding data. - */ - enum enctype rd_encoding; - z_stream stream; - int stream_valid; -#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) - bz_stream bzstream; - int bzstream_valid; -#endif -#if HAVE_LZMA_H && HAVE_LIBLZMA - lzma_stream lzstream; - int lzstream_valid; -#endif - /* - * For Checksum data. - */ - struct chksumwork a_sumwrk; - struct chksumwork e_sumwrk; - - struct xar_file *file; /* current reading file. */ - struct xattr *xattr; /* current reading extended attribute. */ - struct heap_queue file_queue; - struct xar_file *hdlink_orgs; - struct hdlink *hdlink_list; - - int entry_init; - uint64_t entry_total; - uint64_t entry_remaining; - size_t entry_unconsumed; - uint64_t entry_size; - enum enctype entry_encoding; - struct chksumval entry_a_sum; - struct chksumval entry_e_sum; - - struct archive_string_conv *sconv; -}; - -struct xmlattr { - struct xmlattr *next; - char *name; - char *value; -}; - -struct xmlattr_list { - struct xmlattr *first; - struct xmlattr **last; -}; - -static int xar_bid(struct archive_read *, int); -static int xar_read_header(struct archive_read *, - struct archive_entry *); -static int xar_read_data(struct archive_read *, - const void **, size_t *, int64_t *); -static int xar_read_data_skip(struct archive_read *); -static int xar_cleanup(struct archive_read *); -static int move_reading_point(struct archive_read *, uint64_t); -static int rd_contents_init(struct archive_read *, - enum enctype, int, int); -static int rd_contents(struct archive_read *, const void **, - size_t *, size_t *, uint64_t); -static uint64_t atol10(const char *, size_t); -static int64_t atol8(const char *, size_t); -static size_t atohex(unsigned char *, size_t, const char *, size_t); -static time_t parse_time(const char *p, size_t n); -static int heap_add_entry(struct archive_read *a, - struct heap_queue *, struct xar_file *); -static struct xar_file *heap_get_entry(struct heap_queue *); -static int add_link(struct archive_read *, - struct xar *, struct xar_file *); -static void checksum_init(struct archive_read *, int, int); -static void checksum_update(struct archive_read *, const void *, - size_t, const void *, size_t); -static int checksum_final(struct archive_read *, const void *, - size_t, const void *, size_t); -static void checksum_cleanup(struct archive_read *); -static int decompression_init(struct archive_read *, enum enctype); -static int decompress(struct archive_read *, const void **, - size_t *, const void *, size_t *); -static int decompression_cleanup(struct archive_read *); -static void xmlattr_cleanup(struct xmlattr_list *); -static int file_new(struct archive_read *, - struct xar *, struct xmlattr_list *); -static void file_free(struct xar_file *); -static int xattr_new(struct archive_read *, - struct xar *, struct xmlattr_list *); -static void xattr_free(struct xattr *); -static int getencoding(struct xmlattr_list *); -static int getsumalgorithm(struct xmlattr_list *); -static int unknowntag_start(struct archive_read *, - struct xar *, const char *); -static void unknowntag_end(struct xar *, const char *); -static int xml_start(struct archive_read *, - const char *, struct xmlattr_list *); -static void xml_end(void *, const char *); -static void xml_data(void *, const char *, int); -static int xml_parse_file_flags(struct xar *, const char *); -static int xml_parse_file_ext2(struct xar *, const char *); -#if defined(HAVE_LIBXML_XMLREADER_H) -static int xml2_xmlattr_setup(struct archive_read *, - struct xmlattr_list *, xmlTextReaderPtr); -static int xml2_read_cb(void *, char *, int); -static int xml2_close_cb(void *); -static void xml2_error_hdr(void *, const char *, xmlParserSeverities, - xmlTextReaderLocatorPtr); -static int xml2_read_toc(struct archive_read *); -#elif defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H) -struct expat_userData { - int state; - struct archive_read *archive; -}; -static int expat_xmlattr_setup(struct archive_read *, - struct xmlattr_list *, const XML_Char **); -static void expat_start_cb(void *, const XML_Char *, const XML_Char **); -static void expat_end_cb(void *, const XML_Char *); -static void expat_data_cb(void *, const XML_Char *, int); -static int expat_read_toc(struct archive_read *); -#endif - -int -archive_read_support_format_xar(struct archive *_a) -{ - struct xar *xar; - struct archive_read *a = (struct archive_read *)_a; - int r; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_format_xar"); - - xar = (struct xar *)calloc(1, sizeof(*xar)); - if (xar == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate xar data"); - return (ARCHIVE_FATAL); - } - - /* initialize xar->file_queue */ - xar->file_queue.allocated = 0; - xar->file_queue.used = 0; - xar->file_queue.files = NULL; - - r = __archive_read_register_format(a, - xar, - "xar", - xar_bid, - NULL, - xar_read_header, - xar_read_data, - xar_read_data_skip, - NULL, - xar_cleanup, - NULL, - NULL); - if (r != ARCHIVE_OK) - free(xar); - return (r); -} - -static int -xar_bid(struct archive_read *a, int best_bid) -{ - const unsigned char *b; - int bid; - - (void)best_bid; /* UNUSED */ - - b = __archive_read_ahead(a, HEADER_SIZE, NULL); - if (b == NULL) - return (-1); - - bid = 0; - /* - * Verify magic code - */ - if (archive_be32dec(b) != HEADER_MAGIC) - return (0); - bid += 32; - /* - * Verify header size - */ - if (archive_be16dec(b+4) != HEADER_SIZE) - return (0); - bid += 16; - /* - * Verify header version - */ - if (archive_be16dec(b+6) != HEADER_VERSION) - return (0); - bid += 16; - /* - * Verify type of checksum - */ - switch (archive_be32dec(b+24)) { - case CKSUM_NONE: - case CKSUM_SHA1: - case CKSUM_MD5: - bid += 32; - break; - default: - return (0); - } - - return (bid); -} - -static int -read_toc(struct archive_read *a) -{ - struct xar *xar; - struct xar_file *file; - const unsigned char *b; - uint64_t toc_compressed_size; - uint64_t toc_uncompressed_size; - uint32_t toc_chksum_alg; - ssize_t bytes; - int r; - - xar = (struct xar *)(a->format->data); - - /* - * Read xar header. - */ - b = __archive_read_ahead(a, HEADER_SIZE, &bytes); - if (bytes < 0) - return ((int)bytes); - if (bytes < HEADER_SIZE) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated archive header"); - return (ARCHIVE_FATAL); - } - - if (archive_be32dec(b) != HEADER_MAGIC) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid header magic"); - return (ARCHIVE_FATAL); - } - if (archive_be16dec(b+6) != HEADER_VERSION) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Unsupported header version(%d)", - archive_be16dec(b+6)); - return (ARCHIVE_FATAL); - } - toc_compressed_size = archive_be64dec(b+8); - xar->toc_remaining = toc_compressed_size; - toc_uncompressed_size = archive_be64dec(b+16); - toc_chksum_alg = archive_be32dec(b+24); - __archive_read_consume(a, HEADER_SIZE); - xar->offset += HEADER_SIZE; - xar->toc_total = 0; - - /* - * Read TOC(Table of Contents). - */ - /* Initialize reading contents. */ - r = move_reading_point(a, HEADER_SIZE); - if (r != ARCHIVE_OK) - return (r); - r = rd_contents_init(a, GZIP, toc_chksum_alg, CKSUM_NONE); - if (r != ARCHIVE_OK) - return (r); - -#ifdef HAVE_LIBXML_XMLREADER_H - r = xml2_read_toc(a); -#elif defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H) - r = expat_read_toc(a); -#endif - if (r != ARCHIVE_OK) - return (r); - - /* Set 'The HEAP' base. */ - xar->h_base = xar->offset; - if (xar->toc_total != toc_uncompressed_size) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "TOC uncompressed size error"); - return (ARCHIVE_FATAL); - } - - /* - * Checksum TOC - */ - if (toc_chksum_alg != CKSUM_NONE) { - r = move_reading_point(a, xar->toc_chksum_offset); - if (r != ARCHIVE_OK) - return (r); - b = __archive_read_ahead(a, - (size_t)xar->toc_chksum_size, &bytes); - if (bytes < 0) - return ((int)bytes); - if ((uint64_t)bytes < xar->toc_chksum_size) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated archive file"); - return (ARCHIVE_FATAL); - } - r = checksum_final(a, b, - (size_t)xar->toc_chksum_size, NULL, 0); - __archive_read_consume(a, xar->toc_chksum_size); - xar->offset += xar->toc_chksum_size; - if (r != ARCHIVE_OK) -#ifndef DONT_FAIL_ON_CRC_ERROR - return (ARCHIVE_FATAL); -#endif - } - - /* - * Connect hardlinked files. - */ - for (file = xar->hdlink_orgs; file != NULL; file = file->hdnext) { - struct hdlink **hdlink; - - for (hdlink = &(xar->hdlink_list); *hdlink != NULL; - hdlink = &((*hdlink)->next)) { - if ((*hdlink)->id == file->id) { - struct hdlink *hltmp; - struct xar_file *f2; - int nlink = (*hdlink)->cnt + 1; - - file->nlink = nlink; - for (f2 = (*hdlink)->files; f2 != NULL; - f2 = f2->hdnext) { - f2->nlink = nlink; - archive_string_copy( - &(f2->hardlink), &(file->pathname)); - } - /* Remove resolved files from hdlist_list. */ - hltmp = *hdlink; - *hdlink = hltmp->next; - free(hltmp); - break; - } - } - } - a->archive.archive_format = ARCHIVE_FORMAT_XAR; - a->archive.archive_format_name = "xar"; - - return (ARCHIVE_OK); -} - -static int -xar_read_header(struct archive_read *a, struct archive_entry *entry) -{ - struct xar *xar; - struct xar_file *file; - struct xattr *xattr; - int r; - - xar = (struct xar *)(a->format->data); - r = ARCHIVE_OK; - - if (xar->offset == 0) { - /* Create a character conversion object. */ - if (xar->sconv == NULL) { - xar->sconv = archive_string_conversion_from_charset( - &(a->archive), "UTF-8", 1); - if (xar->sconv == NULL) - return (ARCHIVE_FATAL); - } - - /* Read TOC. */ - r = read_toc(a); - if (r != ARCHIVE_OK) - return (r); - } - - for (;;) { - file = xar->file = heap_get_entry(&(xar->file_queue)); - if (file == NULL) { - xar->end_of_file = 1; - return (ARCHIVE_EOF); - } - if ((file->mode & AE_IFMT) != AE_IFDIR) - break; - if (file->has != (HAS_PATHNAME | HAS_TYPE)) - break; - /* - * If a file type is a directory and it does not have - * any metadata, do not export. - */ - file_free(file); - } - if (file->has & HAS_ATIME) { - archive_entry_set_atime(entry, file->atime, 0); - } - if (file->has & HAS_CTIME) { - archive_entry_set_ctime(entry, file->ctime, 0); - } - if (file->has & HAS_MTIME) { - archive_entry_set_mtime(entry, file->mtime, 0); - } - archive_entry_set_gid(entry, file->gid); - if (file->gname.length > 0 && - archive_entry_copy_gname_l(entry, file->gname.s, - archive_strlen(&(file->gname)), xar->sconv) != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Gname"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Gname cannot be converted from %s to current locale.", - archive_string_conversion_charset_name(xar->sconv)); - r = ARCHIVE_WARN; - } - archive_entry_set_uid(entry, file->uid); - if (file->uname.length > 0 && - archive_entry_copy_uname_l(entry, file->uname.s, - archive_strlen(&(file->uname)), xar->sconv) != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Uname"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Uname cannot be converted from %s to current locale.", - archive_string_conversion_charset_name(xar->sconv)); - r = ARCHIVE_WARN; - } - archive_entry_set_mode(entry, file->mode); - if (archive_entry_copy_pathname_l(entry, file->pathname.s, - archive_strlen(&(file->pathname)), xar->sconv) != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Pathname"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Pathname cannot be converted from %s to current locale.", - archive_string_conversion_charset_name(xar->sconv)); - r = ARCHIVE_WARN; - } - - - if (file->symlink.length > 0 && - archive_entry_copy_symlink_l(entry, file->symlink.s, - archive_strlen(&(file->symlink)), xar->sconv) != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Linkname"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Linkname cannot be converted from %s to current locale.", - archive_string_conversion_charset_name(xar->sconv)); - r = ARCHIVE_WARN; - } - /* Set proper nlink. */ - if ((file->mode & AE_IFMT) == AE_IFDIR) - archive_entry_set_nlink(entry, file->subdirs + 2); - else - archive_entry_set_nlink(entry, file->nlink); - archive_entry_set_size(entry, file->size); - if (archive_strlen(&(file->hardlink)) > 0) - archive_entry_set_hardlink(entry, file->hardlink.s); - archive_entry_set_ino64(entry, file->ino64); - if (file->has & HAS_DEV) - archive_entry_set_dev(entry, file->dev); - if (file->has & HAS_DEVMAJOR) - archive_entry_set_devmajor(entry, file->devmajor); - if (file->has & HAS_DEVMINOR) - archive_entry_set_devminor(entry, file->devminor); - if (archive_strlen(&(file->fflags_text)) > 0) - archive_entry_copy_fflags_text(entry, file->fflags_text.s); - - xar->entry_init = 1; - xar->entry_total = 0; - xar->entry_remaining = file->length; - xar->entry_size = file->size; - xar->entry_encoding = file->encoding; - xar->entry_a_sum = file->a_sum; - xar->entry_e_sum = file->e_sum; - /* - * Read extended attributes. - */ - xattr = file->xattr_list; - while (xattr != NULL) { - const void *d; - size_t outbytes = 0; - size_t used = 0; - - r = move_reading_point(a, xattr->offset); - if (r != ARCHIVE_OK) - break; - r = rd_contents_init(a, xattr->encoding, - xattr->a_sum.alg, xattr->e_sum.alg); - if (r != ARCHIVE_OK) - break; - d = NULL; - r = rd_contents(a, &d, &outbytes, &used, xattr->length); - if (r != ARCHIVE_OK) - break; - if (outbytes != xattr->size) { - archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC, - "Decompressed size error"); - r = ARCHIVE_FATAL; - break; - } - r = checksum_final(a, - xattr->a_sum.val, xattr->a_sum.len, - xattr->e_sum.val, xattr->e_sum.len); - if (r != ARCHIVE_OK) { -#ifndef DONT_FAIL_ON_CRC_ERROR - archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC, - "Xattr checksum error"); - r = ARCHIVE_WARN; - break; -#endif - } - if (xattr->name.s == NULL) { - archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC, - "Xattr name error"); - r = ARCHIVE_WARN; - break; - } - archive_entry_xattr_add_entry(entry, - xattr->name.s, d, outbytes); - xattr = xattr->next; - } - if (r != ARCHIVE_OK) { - file_free(file); - return (r); - } - - if (xar->entry_remaining > 0) - /* Move reading point to the beginning of current - * file contents. */ - r = move_reading_point(a, file->offset); - else - r = ARCHIVE_OK; - - file_free(file); - return (r); -} - -static int -xar_read_data(struct archive_read *a, - const void **buff, size_t *size, int64_t *offset) -{ - struct xar *xar; - size_t used = 0; - int r; - - xar = (struct xar *)(a->format->data); - - if (xar->entry_unconsumed) { - __archive_read_consume(a, xar->entry_unconsumed); - xar->entry_unconsumed = 0; - } - - if (xar->end_of_file || xar->entry_remaining <= 0) { - r = ARCHIVE_EOF; - goto abort_read_data; - } - - if (xar->entry_init) { - r = rd_contents_init(a, xar->entry_encoding, - xar->entry_a_sum.alg, xar->entry_e_sum.alg); - if (r != ARCHIVE_OK) { - xar->entry_remaining = 0; - return (r); - } - xar->entry_init = 0; - } - - *buff = NULL; - r = rd_contents(a, buff, size, &used, xar->entry_remaining); - if (r != ARCHIVE_OK) - goto abort_read_data; - - *offset = xar->entry_total; - xar->entry_total += *size; - xar->total += *size; - xar->offset += used; - xar->entry_remaining -= used; - xar->entry_unconsumed = used; - - if (xar->entry_remaining == 0) { - if (xar->entry_total != xar->entry_size) { - archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC, - "Decompressed size error"); - r = ARCHIVE_FATAL; - goto abort_read_data; - } - r = checksum_final(a, - xar->entry_a_sum.val, xar->entry_a_sum.len, - xar->entry_e_sum.val, xar->entry_e_sum.len); - if (r != ARCHIVE_OK) - goto abort_read_data; - } - - return (ARCHIVE_OK); -abort_read_data: - *buff = NULL; - *size = 0; - *offset = xar->total; - return (r); -} - -static int -xar_read_data_skip(struct archive_read *a) -{ - struct xar *xar; - int64_t bytes_skipped; - - xar = (struct xar *)(a->format->data); - if (xar->end_of_file) - return (ARCHIVE_EOF); - bytes_skipped = __archive_read_consume(a, xar->entry_remaining + - xar->entry_unconsumed); - if (bytes_skipped < 0) - return (ARCHIVE_FATAL); - xar->offset += bytes_skipped; - xar->entry_unconsumed = 0; - return (ARCHIVE_OK); -} - -static int -xar_cleanup(struct archive_read *a) -{ - struct xar *xar; - struct hdlink *hdlink; - int i; - int r; - - xar = (struct xar *)(a->format->data); - checksum_cleanup(a); - r = decompression_cleanup(a); - hdlink = xar->hdlink_list; - while (hdlink != NULL) { - struct hdlink *next = hdlink->next; - - free(hdlink); - hdlink = next; - } - for (i = 0; i < xar->file_queue.used; i++) - file_free(xar->file_queue.files[i]); - free(xar->file_queue.files); - while (xar->unknowntags != NULL) { - struct unknown_tag *tag; - - tag = xar->unknowntags; - xar->unknowntags = tag->next; - archive_string_free(&(tag->name)); - free(tag); - } - free(xar->outbuff); - free(xar); - a->format->data = NULL; - return (r); -} - -static int -move_reading_point(struct archive_read *a, uint64_t offset) -{ - struct xar *xar; - - xar = (struct xar *)(a->format->data); - if (xar->offset - xar->h_base != offset) { - /* Seek forward to the start of file contents. */ - int64_t step; - - step = offset - (xar->offset - xar->h_base); - if (step > 0) { - step = __archive_read_consume(a, step); - if (step < 0) - return ((int)step); - xar->offset += step; - } else { - int64_t pos = __archive_read_seek(a, xar->h_base + offset, SEEK_SET); - if (pos == ARCHIVE_FAILED) { - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, - "Cannot seek."); - return (ARCHIVE_FAILED); - } - xar->offset = pos; - } - } - return (ARCHIVE_OK); -} - -static int -rd_contents_init(struct archive_read *a, enum enctype encoding, - int a_sum_alg, int e_sum_alg) -{ - int r; - - /* Init decompress library. */ - if ((r = decompression_init(a, encoding)) != ARCHIVE_OK) - return (r); - /* Init checksum library. */ - checksum_init(a, a_sum_alg, e_sum_alg); - return (ARCHIVE_OK); -} - -static int -rd_contents(struct archive_read *a, const void **buff, size_t *size, - size_t *used, uint64_t remaining) -{ - const unsigned char *b; - ssize_t bytes; - - /* Get whatever bytes are immediately available. */ - b = __archive_read_ahead(a, 1, &bytes); - if (bytes < 0) - return ((int)bytes); - if (bytes == 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Truncated archive file"); - return (ARCHIVE_FATAL); - } - if ((uint64_t)bytes > remaining) - bytes = (ssize_t)remaining; - - /* - * Decompress contents of file. - */ - *used = bytes; - if (decompress(a, buff, size, b, used) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - /* - * Update checksum of a compressed data and a extracted data. - */ - checksum_update(a, b, *used, *buff, *size); - - return (ARCHIVE_OK); -} - -/* - * Note that this implementation does not (and should not!) obey - * locale settings; you cannot simply substitute strtol here, since - * it does obey locale. - */ - -static uint64_t -atol10(const char *p, size_t char_cnt) -{ - uint64_t l; - int digit; - - if (char_cnt == 0) - return (0); - - l = 0; - digit = *p - '0'; - while (digit >= 0 && digit < 10 && char_cnt-- > 0) { - l = (l * 10) + digit; - digit = *++p - '0'; - } - return (l); -} - -static int64_t -atol8(const char *p, size_t char_cnt) -{ - int64_t l; - int digit; - - if (char_cnt == 0) - return (0); - - l = 0; - while (char_cnt-- > 0) { - if (*p >= '0' && *p <= '7') - digit = *p - '0'; - else - break; - p++; - l <<= 3; - l |= digit; - } - return (l); -} - -static size_t -atohex(unsigned char *b, size_t bsize, const char *p, size_t psize) -{ - size_t fbsize = bsize; - - while (bsize && psize > 1) { - unsigned char x; - - if (p[0] >= 'a' && p[0] <= 'z') - x = (p[0] - 'a' + 0x0a) << 4; - else if (p[0] >= 'A' && p[0] <= 'Z') - x = (p[0] - 'A' + 0x0a) << 4; - else if (p[0] >= '0' && p[0] <= '9') - x = (p[0] - '0') << 4; - else - return (-1); - if (p[1] >= 'a' && p[1] <= 'z') - x |= p[1] - 'a' + 0x0a; - else if (p[1] >= 'A' && p[1] <= 'Z') - x |= p[1] - 'A' + 0x0a; - else if (p[1] >= '0' && p[1] <= '9') - x |= p[1] - '0'; - else - return (-1); - - *b++ = x; - bsize--; - p += 2; - psize -= 2; - } - return (fbsize - bsize); -} - -static time_t -time_from_tm(struct tm *t) -{ -#if HAVE__MKGMTIME - return _mkgmtime(t); -#elif HAVE_TIMEGM - /* Use platform timegm() if available. */ - return (timegm(t)); -#else - /* Else use direct calculation using POSIX assumptions. */ - /* First, fix up tm_yday based on the year/month/day. */ - mktime(t); - /* Then we can compute timegm() from first principles. */ - return (t->tm_sec - + t->tm_min * 60 - + t->tm_hour * 3600 - + t->tm_yday * 86400 - + (t->tm_year - 70) * 31536000 - + ((t->tm_year - 69) / 4) * 86400 - - ((t->tm_year - 1) / 100) * 86400 - + ((t->tm_year + 299) / 400) * 86400); -#endif -} - -static time_t -parse_time(const char *p, size_t n) -{ - struct tm tm; - time_t t = 0; - int64_t data; - - memset(&tm, 0, sizeof(tm)); - if (n != 20) - return (t); - data = atol10(p, 4); - if (data < 1900) - return (t); - tm.tm_year = (int)data - 1900; - p += 4; - if (*p++ != '-') - return (t); - data = atol10(p, 2); - if (data < 1 || data > 12) - return (t); - tm.tm_mon = (int)data -1; - p += 2; - if (*p++ != '-') - return (t); - data = atol10(p, 2); - if (data < 1 || data > 31) - return (t); - tm.tm_mday = (int)data; - p += 2; - if (*p++ != 'T') - return (t); - data = atol10(p, 2); - if (data < 0 || data > 23) - return (t); - tm.tm_hour = (int)data; - p += 2; - if (*p++ != ':') - return (t); - data = atol10(p, 2); - if (data < 0 || data > 59) - return (t); - tm.tm_min = (int)data; - p += 2; - if (*p++ != ':') - return (t); - data = atol10(p, 2); - if (data < 0 || data > 60) - return (t); - tm.tm_sec = (int)data; -#if 0 - p += 2; - if (*p != 'Z') - return (t); -#endif - - t = time_from_tm(&tm); - - return (t); -} - -static int -heap_add_entry(struct archive_read *a, - struct heap_queue *heap, struct xar_file *file) -{ - uint64_t file_id, parent_id; - int hole, parent; - - /* Expand our pending files list as necessary. */ - if (heap->used >= heap->allocated) { - struct xar_file **new_pending_files; - int new_size; - - if (heap->allocated < 1024) - new_size = 1024; - else - new_size = heap->allocated * 2; - /* Overflow might keep us from growing the list. */ - if (new_size <= heap->allocated) { - archive_set_error(&a->archive, - ENOMEM, "Out of memory"); - return (ARCHIVE_FATAL); - } - new_pending_files = (struct xar_file **) - malloc(new_size * sizeof(new_pending_files[0])); - if (new_pending_files == NULL) { - archive_set_error(&a->archive, - ENOMEM, "Out of memory"); - return (ARCHIVE_FATAL); - } - if (heap->allocated) { - memcpy(new_pending_files, heap->files, - heap->allocated * sizeof(new_pending_files[0])); - free(heap->files); - } - heap->files = new_pending_files; - heap->allocated = new_size; - } - - file_id = file->id; - - /* - * Start with hole at end, walk it up tree to find insertion point. - */ - hole = heap->used++; - while (hole > 0) { - parent = (hole - 1)/2; - parent_id = heap->files[parent]->id; - if (file_id >= parent_id) { - heap->files[hole] = file; - return (ARCHIVE_OK); - } - /* Move parent into hole <==> move hole up tree. */ - heap->files[hole] = heap->files[parent]; - hole = parent; - } - heap->files[0] = file; - - return (ARCHIVE_OK); -} - -static struct xar_file * -heap_get_entry(struct heap_queue *heap) -{ - uint64_t a_id, b_id, c_id; - int a, b, c; - struct xar_file *r, *tmp; - - if (heap->used < 1) - return (NULL); - - /* - * The first file in the list is the earliest; we'll return this. - */ - r = heap->files[0]; - - /* - * Move the last item in the heap to the root of the tree - */ - heap->files[0] = heap->files[--(heap->used)]; - - /* - * Rebalance the heap. - */ - a = 0; /* Starting element and its heap key */ - a_id = heap->files[a]->id; - for (;;) { - b = a + a + 1; /* First child */ - if (b >= heap->used) - return (r); - b_id = heap->files[b]->id; - c = b + 1; /* Use second child if it is smaller. */ - if (c < heap->used) { - c_id = heap->files[c]->id; - if (c_id < b_id) { - b = c; - b_id = c_id; - } - } - if (a_id <= b_id) - return (r); - tmp = heap->files[a]; - heap->files[a] = heap->files[b]; - heap->files[b] = tmp; - a = b; - } -} - -static int -add_link(struct archive_read *a, struct xar *xar, struct xar_file *file) -{ - struct hdlink *hdlink; - - for (hdlink = xar->hdlink_list; hdlink != NULL; hdlink = hdlink->next) { - if (hdlink->id == file->link) { - file->hdnext = hdlink->files; - hdlink->cnt++; - hdlink->files = file; - return (ARCHIVE_OK); - } - } - hdlink = malloc(sizeof(*hdlink)); - if (hdlink == NULL) { - archive_set_error(&a->archive, ENOMEM, "Out of memory"); - return (ARCHIVE_FATAL); - } - file->hdnext = NULL; - hdlink->id = file->link; - hdlink->cnt = 1; - hdlink->files = file; - hdlink->next = xar->hdlink_list; - xar->hdlink_list = hdlink; - return (ARCHIVE_OK); -} - -static void -_checksum_init(struct chksumwork *sumwrk, int sum_alg) -{ - sumwrk->alg = sum_alg; - switch (sum_alg) { - case CKSUM_NONE: - break; - case CKSUM_SHA1: - archive_sha1_init(&(sumwrk->sha1ctx)); - break; - case CKSUM_MD5: - archive_md5_init(&(sumwrk->md5ctx)); - break; - } -} - -static void -_checksum_update(struct chksumwork *sumwrk, const void *buff, size_t size) -{ - - switch (sumwrk->alg) { - case CKSUM_NONE: - break; - case CKSUM_SHA1: - archive_sha1_update(&(sumwrk->sha1ctx), buff, size); - break; - case CKSUM_MD5: - archive_md5_update(&(sumwrk->md5ctx), buff, size); - break; - } -} - -static int -_checksum_final(struct chksumwork *sumwrk, const void *val, size_t len) -{ - unsigned char sum[MAX_SUM_SIZE]; - int r = ARCHIVE_OK; - - switch (sumwrk->alg) { - case CKSUM_NONE: - break; - case CKSUM_SHA1: - archive_sha1_final(&(sumwrk->sha1ctx), sum); - if (len != SHA1_SIZE || - memcmp(val, sum, SHA1_SIZE) != 0) - r = ARCHIVE_FAILED; - break; - case CKSUM_MD5: - archive_md5_final(&(sumwrk->md5ctx), sum); - if (len != MD5_SIZE || - memcmp(val, sum, MD5_SIZE) != 0) - r = ARCHIVE_FAILED; - break; - } - return (r); -} - -static void -checksum_init(struct archive_read *a, int a_sum_alg, int e_sum_alg) -{ - struct xar *xar; - - xar = (struct xar *)(a->format->data); - _checksum_init(&(xar->a_sumwrk), a_sum_alg); - _checksum_init(&(xar->e_sumwrk), e_sum_alg); -} - -static void -checksum_update(struct archive_read *a, const void *abuff, size_t asize, - const void *ebuff, size_t esize) -{ - struct xar *xar; - - xar = (struct xar *)(a->format->data); - _checksum_update(&(xar->a_sumwrk), abuff, asize); - _checksum_update(&(xar->e_sumwrk), ebuff, esize); -} - -static int -checksum_final(struct archive_read *a, const void *a_sum_val, - size_t a_sum_len, const void *e_sum_val, size_t e_sum_len) -{ - struct xar *xar; - int r; - - xar = (struct xar *)(a->format->data); - r = _checksum_final(&(xar->a_sumwrk), a_sum_val, a_sum_len); - if (r == ARCHIVE_OK) - r = _checksum_final(&(xar->e_sumwrk), e_sum_val, e_sum_len); - if (r != ARCHIVE_OK) - archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC, - "Sumcheck error"); - return (r); -} - -static int -decompression_init(struct archive_read *a, enum enctype encoding) -{ - struct xar *xar; - const char *detail; - int r; - - xar = (struct xar *)(a->format->data); - xar->rd_encoding = encoding; - switch (encoding) { - case NONE: - break; - case GZIP: - if (xar->stream_valid) - r = inflateReset(&(xar->stream)); - else - r = inflateInit(&(xar->stream)); - if (r != Z_OK) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Couldn't initialize zlib stream."); - return (ARCHIVE_FATAL); - } - xar->stream_valid = 1; - xar->stream.total_in = 0; - xar->stream.total_out = 0; - break; -#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) - case BZIP2: - if (xar->bzstream_valid) { - BZ2_bzDecompressEnd(&(xar->bzstream)); - xar->bzstream_valid = 0; - } - r = BZ2_bzDecompressInit(&(xar->bzstream), 0, 0); - if (r == BZ_MEM_ERROR) - r = BZ2_bzDecompressInit(&(xar->bzstream), 0, 1); - if (r != BZ_OK) { - int err = ARCHIVE_ERRNO_MISC; - detail = NULL; - switch (r) { - case BZ_PARAM_ERROR: - detail = "invalid setup parameter"; - break; - case BZ_MEM_ERROR: - err = ENOMEM; - detail = "out of memory"; - break; - case BZ_CONFIG_ERROR: - detail = "mis-compiled library"; - break; - } - archive_set_error(&a->archive, err, - "Internal error initializing decompressor: %s", - detail == NULL ? "??" : detail); - xar->bzstream_valid = 0; - return (ARCHIVE_FATAL); - } - xar->bzstream_valid = 1; - xar->bzstream.total_in_lo32 = 0; - xar->bzstream.total_in_hi32 = 0; - xar->bzstream.total_out_lo32 = 0; - xar->bzstream.total_out_hi32 = 0; - break; -#endif -#if defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA) -#if LZMA_VERSION_MAJOR >= 5 -/* Effectively disable the limiter. */ -#define LZMA_MEMLIMIT UINT64_MAX -#else -/* NOTE: This needs to check memory size which running system has. */ -#define LZMA_MEMLIMIT (1U << 30) -#endif - case XZ: - case LZMA: - if (xar->lzstream_valid) { - lzma_end(&(xar->lzstream)); - xar->lzstream_valid = 0; - } - if (xar->entry_encoding == XZ) - r = lzma_stream_decoder(&(xar->lzstream), - LZMA_MEMLIMIT,/* memlimit */ - LZMA_CONCATENATED); - else - r = lzma_alone_decoder(&(xar->lzstream), - LZMA_MEMLIMIT);/* memlimit */ - if (r != LZMA_OK) { - switch (r) { - case LZMA_MEM_ERROR: - archive_set_error(&a->archive, - ENOMEM, - "Internal error initializing " - "compression library: " - "Cannot allocate memory"); - break; - case LZMA_OPTIONS_ERROR: - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Internal error initializing " - "compression library: " - "Invalid or unsupported options"); - break; - default: - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Internal error initializing " - "lzma library"); - break; - } - return (ARCHIVE_FATAL); - } - xar->lzstream_valid = 1; - xar->lzstream.total_in = 0; - xar->lzstream.total_out = 0; - break; -#endif - /* - * Unsupported compression. - */ - default: -#if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR) - case BZIP2: -#endif -#if !defined(HAVE_LZMA_H) || !defined(HAVE_LIBLZMA) - case LZMA: - case XZ: -#endif - switch (xar->entry_encoding) { - case BZIP2: detail = "bzip2"; break; - case LZMA: detail = "lzma"; break; - case XZ: detail = "xz"; break; - default: detail = "??"; break; - } - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "%s compression not supported on this platform", - detail); - return (ARCHIVE_FAILED); - } - return (ARCHIVE_OK); -} - -static int -decompress(struct archive_read *a, const void **buff, size_t *outbytes, - const void *b, size_t *used) -{ - struct xar *xar; - void *outbuff; - size_t avail_in, avail_out; - int r; - - xar = (struct xar *)(a->format->data); - avail_in = *used; - outbuff = (void *)(uintptr_t)*buff; - if (outbuff == NULL) { - if (xar->outbuff == NULL) { - xar->outbuff = malloc(OUTBUFF_SIZE); - if (xar->outbuff == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Couldn't allocate memory for out buffer"); - return (ARCHIVE_FATAL); - } - } - outbuff = xar->outbuff; - *buff = outbuff; - avail_out = OUTBUFF_SIZE; - } else - avail_out = *outbytes; - switch (xar->rd_encoding) { - case GZIP: - xar->stream.next_in = (Bytef *)(uintptr_t)b; - xar->stream.avail_in = avail_in; - xar->stream.next_out = (unsigned char *)outbuff; - xar->stream.avail_out = avail_out; - r = inflate(&(xar->stream), 0); - switch (r) { - case Z_OK: /* Decompressor made some progress.*/ - case Z_STREAM_END: /* Found end of stream. */ - break; - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "File decompression failed (%d)", r); - return (ARCHIVE_FATAL); - } - *used = avail_in - xar->stream.avail_in; - *outbytes = avail_out - xar->stream.avail_out; - break; -#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) - case BZIP2: - xar->bzstream.next_in = (char *)(uintptr_t)b; - xar->bzstream.avail_in = avail_in; - xar->bzstream.next_out = (char *)outbuff; - xar->bzstream.avail_out = avail_out; - r = BZ2_bzDecompress(&(xar->bzstream)); - switch (r) { - case BZ_STREAM_END: /* Found end of stream. */ - switch (BZ2_bzDecompressEnd(&(xar->bzstream))) { - case BZ_OK: - break; - default: - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, - "Failed to clean up decompressor"); - return (ARCHIVE_FATAL); - } - xar->bzstream_valid = 0; - /* FALLTHROUGH */ - case BZ_OK: /* Decompressor made some progress. */ - break; - default: - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, - "bzip decompression failed"); - return (ARCHIVE_FATAL); - } - *used = avail_in - xar->bzstream.avail_in; - *outbytes = avail_out - xar->bzstream.avail_out; - break; -#endif -#if defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA) - case LZMA: - case XZ: - xar->lzstream.next_in = b; - xar->lzstream.avail_in = avail_in; - xar->lzstream.next_out = (unsigned char *)outbuff; - xar->lzstream.avail_out = avail_out; - r = lzma_code(&(xar->lzstream), LZMA_RUN); - switch (r) { - case LZMA_STREAM_END: /* Found end of stream. */ - lzma_end(&(xar->lzstream)); - xar->lzstream_valid = 0; - /* FALLTHROUGH */ - case LZMA_OK: /* Decompressor made some progress. */ - break; - default: - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, - "%s decompression failed(%d)", - (xar->entry_encoding == XZ)?"xz":"lzma", - r); - return (ARCHIVE_FATAL); - } - *used = avail_in - xar->lzstream.avail_in; - *outbytes = avail_out - xar->lzstream.avail_out; - break; -#endif -#if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR) - case BZIP2: -#endif -#if !defined(HAVE_LZMA_H) || !defined(HAVE_LIBLZMA) - case LZMA: - case XZ: -#endif - case NONE: - default: - if (outbuff == xar->outbuff) { - *buff = b; - *used = avail_in; - *outbytes = avail_in; - } else { - if (avail_out > avail_in) - avail_out = avail_in; - memcpy(outbuff, b, avail_out); - *used = avail_out; - *outbytes = avail_out; - } - break; - } - return (ARCHIVE_OK); -} - -static int -decompression_cleanup(struct archive_read *a) -{ - struct xar *xar; - int r; - - xar = (struct xar *)(a->format->data); - r = ARCHIVE_OK; - if (xar->stream_valid) { - if (inflateEnd(&(xar->stream)) != Z_OK) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Failed to clean up zlib decompressor"); - r = ARCHIVE_FATAL; - } - } -#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) - if (xar->bzstream_valid) { - if (BZ2_bzDecompressEnd(&(xar->bzstream)) != BZ_OK) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Failed to clean up bzip2 decompressor"); - r = ARCHIVE_FATAL; - } - } -#endif -#if defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA) - if (xar->lzstream_valid) - lzma_end(&(xar->lzstream)); -#elif defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA) - if (xar->lzstream_valid) { - if (lzmadec_end(&(xar->lzstream)) != LZMADEC_OK) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Failed to clean up lzmadec decompressor"); - r = ARCHIVE_FATAL; - } - } -#endif - return (r); -} - -static void -checksum_cleanup(struct archive_read *a) { - struct xar *xar; - - xar = (struct xar *)(a->format->data); - - _checksum_final(&(xar->a_sumwrk), NULL, 0); - _checksum_final(&(xar->e_sumwrk), NULL, 0); -} - -static void -xmlattr_cleanup(struct xmlattr_list *list) -{ - struct xmlattr *attr, *next; - - attr = list->first; - while (attr != NULL) { - next = attr->next; - free(attr->name); - free(attr->value); - free(attr); - attr = next; - } - list->first = NULL; - list->last = &(list->first); -} - -static int -file_new(struct archive_read *a, struct xar *xar, struct xmlattr_list *list) -{ - struct xar_file *file; - struct xmlattr *attr; - - file = calloc(1, sizeof(*file)); - if (file == NULL) { - archive_set_error(&a->archive, ENOMEM, "Out of memory"); - return (ARCHIVE_FATAL); - } - file->parent = xar->file; - file->mode = 0777 | AE_IFREG; - file->atime = 0; - file->mtime = 0; - xar->file = file; - xar->xattr = NULL; - for (attr = list->first; attr != NULL; attr = attr->next) { - if (strcmp(attr->name, "id") == 0) - file->id = atol10(attr->value, strlen(attr->value)); - } - file->nlink = 1; - if (heap_add_entry(a, &(xar->file_queue), file) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - return (ARCHIVE_OK); -} - -static void -file_free(struct xar_file *file) -{ - struct xattr *xattr; - - archive_string_free(&(file->pathname)); - archive_string_free(&(file->symlink)); - archive_string_free(&(file->uname)); - archive_string_free(&(file->gname)); - archive_string_free(&(file->hardlink)); - xattr = file->xattr_list; - while (xattr != NULL) { - struct xattr *next; - - next = xattr->next; - xattr_free(xattr); - xattr = next; - } - - free(file); -} - -static int -xattr_new(struct archive_read *a, struct xar *xar, struct xmlattr_list *list) -{ - struct xattr *xattr, **nx; - struct xmlattr *attr; - - xattr = calloc(1, sizeof(*xattr)); - if (xattr == NULL) { - archive_set_error(&a->archive, ENOMEM, "Out of memory"); - return (ARCHIVE_FATAL); - } - xar->xattr = xattr; - for (attr = list->first; attr != NULL; attr = attr->next) { - if (strcmp(attr->name, "id") == 0) - xattr->id = atol10(attr->value, strlen(attr->value)); - } - /* Chain to xattr list. */ - for (nx = &(xar->file->xattr_list); - *nx != NULL; nx = &((*nx)->next)) { - if (xattr->id < (*nx)->id) - break; - } - xattr->next = *nx; - *nx = xattr; - - return (ARCHIVE_OK); -} - -static void -xattr_free(struct xattr *xattr) -{ - archive_string_free(&(xattr->name)); - free(xattr); -} - -static int -getencoding(struct xmlattr_list *list) -{ - struct xmlattr *attr; - enum enctype encoding = NONE; - - for (attr = list->first; attr != NULL; attr = attr->next) { - if (strcmp(attr->name, "style") == 0) { - if (strcmp(attr->value, "application/octet-stream") == 0) - encoding = NONE; - else if (strcmp(attr->value, "application/x-gzip") == 0) - encoding = GZIP; - else if (strcmp(attr->value, "application/x-bzip2") == 0) - encoding = BZIP2; - else if (strcmp(attr->value, "application/x-lzma") == 0) - encoding = LZMA; - else if (strcmp(attr->value, "application/x-xz") == 0) - encoding = XZ; - } - } - return (encoding); -} - -static int -getsumalgorithm(struct xmlattr_list *list) -{ - struct xmlattr *attr; - int alg = CKSUM_NONE; - - for (attr = list->first; attr != NULL; attr = attr->next) { - if (strcmp(attr->name, "style") == 0) { - const char *v = attr->value; - if ((v[0] == 'S' || v[0] == 's') && - (v[1] == 'H' || v[1] == 'h') && - (v[2] == 'A' || v[2] == 'a') && - v[3] == '1' && v[4] == '\0') - alg = CKSUM_SHA1; - if ((v[0] == 'M' || v[0] == 'm') && - (v[1] == 'D' || v[1] == 'd') && - v[2] == '5' && v[3] == '\0') - alg = CKSUM_MD5; - } - } - return (alg); -} - -static int -unknowntag_start(struct archive_read *a, struct xar *xar, const char *name) -{ - struct unknown_tag *tag; - - tag = malloc(sizeof(*tag)); - if (tag == NULL) { - archive_set_error(&a->archive, ENOMEM, "Out of memory"); - return (ARCHIVE_FATAL); - } - tag->next = xar->unknowntags; - archive_string_init(&(tag->name)); - archive_strcpy(&(tag->name), name); - if (xar->unknowntags == NULL) { -#if DEBUG - fprintf(stderr, "UNKNOWNTAG_START:%s\n", name); -#endif - xar->xmlsts_unknown = xar->xmlsts; - xar->xmlsts = UNKNOWN; - } - xar->unknowntags = tag; - return (ARCHIVE_OK); -} - -static void -unknowntag_end(struct xar *xar, const char *name) -{ - struct unknown_tag *tag; - - tag = xar->unknowntags; - if (tag == NULL || name == NULL) - return; - if (strcmp(tag->name.s, name) == 0) { - xar->unknowntags = tag->next; - archive_string_free(&(tag->name)); - free(tag); - if (xar->unknowntags == NULL) { -#if DEBUG - fprintf(stderr, "UNKNOWNTAG_END:%s\n", name); -#endif - xar->xmlsts = xar->xmlsts_unknown; - } - } -} - -static int -xml_start(struct archive_read *a, const char *name, struct xmlattr_list *list) -{ - struct xar *xar; - struct xmlattr *attr; - - xar = (struct xar *)(a->format->data); - -#if DEBUG - fprintf(stderr, "xml_sta:[%s]\n", name); - for (attr = list->first; attr != NULL; attr = attr->next) - fprintf(stderr, " attr:\"%s\"=\"%s\"\n", - attr->name, attr->value); -#endif - xar->base64text = 0; - switch (xar->xmlsts) { - case INIT: - if (strcmp(name, "xar") == 0) - xar->xmlsts = XAR; - else - if (unknowntag_start(a, xar, name) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - break; - case XAR: - if (strcmp(name, "toc") == 0) - xar->xmlsts = TOC; - else - if (unknowntag_start(a, xar, name) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - break; - case TOC: - if (strcmp(name, "creation-time") == 0) - xar->xmlsts = TOC_CREATION_TIME; - else if (strcmp(name, "checksum") == 0) - xar->xmlsts = TOC_CHECKSUM; - else if (strcmp(name, "file") == 0) { - if (file_new(a, xar, list) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - xar->xmlsts = TOC_FILE; - } - else - if (unknowntag_start(a, xar, name) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - break; - case TOC_CHECKSUM: - if (strcmp(name, "offset") == 0) - xar->xmlsts = TOC_CHECKSUM_OFFSET; - else if (strcmp(name, "size") == 0) - xar->xmlsts = TOC_CHECKSUM_SIZE; - else - if (unknowntag_start(a, xar, name) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - break; - case TOC_FILE: - if (strcmp(name, "file") == 0) { - if (file_new(a, xar, list) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } - else if (strcmp(name, "data") == 0) - xar->xmlsts = FILE_DATA; - else if (strcmp(name, "ea") == 0) { - if (xattr_new(a, xar, list) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - xar->xmlsts = FILE_EA; - } - else if (strcmp(name, "ctime") == 0) - xar->xmlsts = FILE_CTIME; - else if (strcmp(name, "mtime") == 0) - xar->xmlsts = FILE_MTIME; - else if (strcmp(name, "atime") == 0) - xar->xmlsts = FILE_ATIME; - else if (strcmp(name, "group") == 0) - xar->xmlsts = FILE_GROUP; - else if (strcmp(name, "gid") == 0) - xar->xmlsts = FILE_GID; - else if (strcmp(name, "user") == 0) - xar->xmlsts = FILE_USER; - else if (strcmp(name, "uid") == 0) - xar->xmlsts = FILE_UID; - else if (strcmp(name, "mode") == 0) - xar->xmlsts = FILE_MODE; - else if (strcmp(name, "device") == 0) - xar->xmlsts = FILE_DEVICE; - else if (strcmp(name, "deviceno") == 0) - xar->xmlsts = FILE_DEVICENO; - else if (strcmp(name, "inode") == 0) - xar->xmlsts = FILE_INODE; - else if (strcmp(name, "link") == 0) - xar->xmlsts = FILE_LINK; - else if (strcmp(name, "type") == 0) { - xar->xmlsts = FILE_TYPE; - for (attr = list->first; attr != NULL; - attr = attr->next) { - if (strcmp(attr->name, "link") != 0) - continue; - if (strcmp(attr->value, "original") == 0) { - xar->file->hdnext = xar->hdlink_orgs; - xar->hdlink_orgs = xar->file; - } else { - xar->file->link = (unsigned)atol10(attr->value, - strlen(attr->value)); - if (xar->file->link > 0) - if (add_link(a, xar, xar->file) != ARCHIVE_OK) { - return (ARCHIVE_FATAL); - }; - } - } - } - else if (strcmp(name, "name") == 0) { - xar->xmlsts = FILE_NAME; - for (attr = list->first; attr != NULL; - attr = attr->next) { - if (strcmp(attr->name, "enctype") == 0 && - strcmp(attr->value, "base64") == 0) - xar->base64text = 1; - } - } - else if (strcmp(name, "acl") == 0) - xar->xmlsts = FILE_ACL; - else if (strcmp(name, "flags") == 0) - xar->xmlsts = FILE_FLAGS; - else if (strcmp(name, "ext2") == 0) - xar->xmlsts = FILE_EXT2; - else - if (unknowntag_start(a, xar, name) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - break; - case FILE_DATA: - if (strcmp(name, "length") == 0) - xar->xmlsts = FILE_DATA_LENGTH; - else if (strcmp(name, "offset") == 0) - xar->xmlsts = FILE_DATA_OFFSET; - else if (strcmp(name, "size") == 0) - xar->xmlsts = FILE_DATA_SIZE; - else if (strcmp(name, "encoding") == 0) { - xar->xmlsts = FILE_DATA_ENCODING; - xar->file->encoding = getencoding(list); - } - else if (strcmp(name, "archived-checksum") == 0) { - xar->xmlsts = FILE_DATA_A_CHECKSUM; - xar->file->a_sum.alg = getsumalgorithm(list); - } - else if (strcmp(name, "extracted-checksum") == 0) { - xar->xmlsts = FILE_DATA_E_CHECKSUM; - xar->file->e_sum.alg = getsumalgorithm(list); - } - else if (strcmp(name, "content") == 0) - xar->xmlsts = FILE_DATA_CONTENT; - else - if (unknowntag_start(a, xar, name) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - break; - case FILE_DEVICE: - if (strcmp(name, "major") == 0) - xar->xmlsts = FILE_DEVICE_MAJOR; - else if (strcmp(name, "minor") == 0) - xar->xmlsts = FILE_DEVICE_MINOR; - else - if (unknowntag_start(a, xar, name) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - break; - case FILE_DATA_CONTENT: - if (unknowntag_start(a, xar, name) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - break; - case FILE_EA: - if (strcmp(name, "length") == 0) - xar->xmlsts = FILE_EA_LENGTH; - else if (strcmp(name, "offset") == 0) - xar->xmlsts = FILE_EA_OFFSET; - else if (strcmp(name, "size") == 0) - xar->xmlsts = FILE_EA_SIZE; - else if (strcmp(name, "encoding") == 0) { - xar->xmlsts = FILE_EA_ENCODING; - xar->xattr->encoding = getencoding(list); - } else if (strcmp(name, "archived-checksum") == 0) - xar->xmlsts = FILE_EA_A_CHECKSUM; - else if (strcmp(name, "extracted-checksum") == 0) - xar->xmlsts = FILE_EA_E_CHECKSUM; - else if (strcmp(name, "name") == 0) - xar->xmlsts = FILE_EA_NAME; - else if (strcmp(name, "fstype") == 0) - xar->xmlsts = FILE_EA_FSTYPE; - else - if (unknowntag_start(a, xar, name) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - break; - case FILE_ACL: - if (strcmp(name, "appleextended") == 0) - xar->xmlsts = FILE_ACL_APPLEEXTENDED; - else if (strcmp(name, "default") == 0) - xar->xmlsts = FILE_ACL_DEFAULT; - else if (strcmp(name, "access") == 0) - xar->xmlsts = FILE_ACL_ACCESS; - else - if (unknowntag_start(a, xar, name) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - break; - case FILE_FLAGS: - if (!xml_parse_file_flags(xar, name)) - if (unknowntag_start(a, xar, name) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - break; - case FILE_EXT2: - if (!xml_parse_file_ext2(xar, name)) - if (unknowntag_start(a, xar, name) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - break; - case TOC_CREATION_TIME: - case TOC_CHECKSUM_OFFSET: - case TOC_CHECKSUM_SIZE: - case FILE_DATA_LENGTH: - case FILE_DATA_OFFSET: - case FILE_DATA_SIZE: - case FILE_DATA_ENCODING: - case FILE_DATA_A_CHECKSUM: - case FILE_DATA_E_CHECKSUM: - case FILE_EA_LENGTH: - case FILE_EA_OFFSET: - case FILE_EA_SIZE: - case FILE_EA_ENCODING: - case FILE_EA_A_CHECKSUM: - case FILE_EA_E_CHECKSUM: - case FILE_EA_NAME: - case FILE_EA_FSTYPE: - case FILE_CTIME: - case FILE_MTIME: - case FILE_ATIME: - case FILE_GROUP: - case FILE_GID: - case FILE_USER: - case FILE_UID: - case FILE_INODE: - case FILE_DEVICE_MAJOR: - case FILE_DEVICE_MINOR: - case FILE_DEVICENO: - case FILE_MODE: - case FILE_TYPE: - case FILE_LINK: - case FILE_NAME: - case FILE_ACL_DEFAULT: - case FILE_ACL_ACCESS: - case FILE_ACL_APPLEEXTENDED: - case FILE_FLAGS_USER_NODUMP: - case FILE_FLAGS_USER_IMMUTABLE: - case FILE_FLAGS_USER_APPEND: - case FILE_FLAGS_USER_OPAQUE: - case FILE_FLAGS_USER_NOUNLINK: - case FILE_FLAGS_SYS_ARCHIVED: - case FILE_FLAGS_SYS_IMMUTABLE: - case FILE_FLAGS_SYS_APPEND: - case FILE_FLAGS_SYS_NOUNLINK: - case FILE_FLAGS_SYS_SNAPSHOT: - case FILE_EXT2_SecureDeletion: - case FILE_EXT2_Undelete: - case FILE_EXT2_Compress: - case FILE_EXT2_Synchronous: - case FILE_EXT2_Immutable: - case FILE_EXT2_AppendOnly: - case FILE_EXT2_NoDump: - case FILE_EXT2_NoAtime: - case FILE_EXT2_CompDirty: - case FILE_EXT2_CompBlock: - case FILE_EXT2_NoCompBlock: - case FILE_EXT2_CompError: - case FILE_EXT2_BTree: - case FILE_EXT2_HashIndexed: - case FILE_EXT2_iMagic: - case FILE_EXT2_Journaled: - case FILE_EXT2_NoTail: - case FILE_EXT2_DirSync: - case FILE_EXT2_TopDir: - case FILE_EXT2_Reserved: - case UNKNOWN: - if (unknowntag_start(a, xar, name) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - break; - } - return (ARCHIVE_OK); -} - -static void -xml_end(void *userData, const char *name) -{ - struct archive_read *a; - struct xar *xar; - - a = (struct archive_read *)userData; - xar = (struct xar *)(a->format->data); - -#if DEBUG - fprintf(stderr, "xml_end:[%s]\n", name); -#endif - switch (xar->xmlsts) { - case INIT: - break; - case XAR: - if (strcmp(name, "xar") == 0) - xar->xmlsts = INIT; - break; - case TOC: - if (strcmp(name, "toc") == 0) - xar->xmlsts = XAR; - break; - case TOC_CREATION_TIME: - if (strcmp(name, "creation-time") == 0) - xar->xmlsts = TOC; - break; - case TOC_CHECKSUM: - if (strcmp(name, "checksum") == 0) - xar->xmlsts = TOC; - break; - case TOC_CHECKSUM_OFFSET: - if (strcmp(name, "offset") == 0) - xar->xmlsts = TOC_CHECKSUM; - break; - case TOC_CHECKSUM_SIZE: - if (strcmp(name, "size") == 0) - xar->xmlsts = TOC_CHECKSUM; - break; - case TOC_FILE: - if (strcmp(name, "file") == 0) { - if (xar->file->parent != NULL && - ((xar->file->mode & AE_IFMT) == AE_IFDIR)) - xar->file->parent->subdirs++; - xar->file = xar->file->parent; - if (xar->file == NULL) - xar->xmlsts = TOC; - } - break; - case FILE_DATA: - if (strcmp(name, "data") == 0) - xar->xmlsts = TOC_FILE; - break; - case FILE_DATA_LENGTH: - if (strcmp(name, "length") == 0) - xar->xmlsts = FILE_DATA; - break; - case FILE_DATA_OFFSET: - if (strcmp(name, "offset") == 0) - xar->xmlsts = FILE_DATA; - break; - case FILE_DATA_SIZE: - if (strcmp(name, "size") == 0) - xar->xmlsts = FILE_DATA; - break; - case FILE_DATA_ENCODING: - if (strcmp(name, "encoding") == 0) - xar->xmlsts = FILE_DATA; - break; - case FILE_DATA_A_CHECKSUM: - if (strcmp(name, "archived-checksum") == 0) - xar->xmlsts = FILE_DATA; - break; - case FILE_DATA_E_CHECKSUM: - if (strcmp(name, "extracted-checksum") == 0) - xar->xmlsts = FILE_DATA; - break; - case FILE_DATA_CONTENT: - if (strcmp(name, "content") == 0) - xar->xmlsts = FILE_DATA; - break; - case FILE_EA: - if (strcmp(name, "ea") == 0) { - xar->xmlsts = TOC_FILE; - xar->xattr = NULL; - } - break; - case FILE_EA_LENGTH: - if (strcmp(name, "length") == 0) - xar->xmlsts = FILE_EA; - break; - case FILE_EA_OFFSET: - if (strcmp(name, "offset") == 0) - xar->xmlsts = FILE_EA; - break; - case FILE_EA_SIZE: - if (strcmp(name, "size") == 0) - xar->xmlsts = FILE_EA; - break; - case FILE_EA_ENCODING: - if (strcmp(name, "encoding") == 0) - xar->xmlsts = FILE_EA; - break; - case FILE_EA_A_CHECKSUM: - if (strcmp(name, "archived-checksum") == 0) - xar->xmlsts = FILE_EA; - break; - case FILE_EA_E_CHECKSUM: - if (strcmp(name, "extracted-checksum") == 0) - xar->xmlsts = FILE_EA; - break; - case FILE_EA_NAME: - if (strcmp(name, "name") == 0) - xar->xmlsts = FILE_EA; - break; - case FILE_EA_FSTYPE: - if (strcmp(name, "fstype") == 0) - xar->xmlsts = FILE_EA; - break; - case FILE_CTIME: - if (strcmp(name, "ctime") == 0) - xar->xmlsts = TOC_FILE; - break; - case FILE_MTIME: - if (strcmp(name, "mtime") == 0) - xar->xmlsts = TOC_FILE; - break; - case FILE_ATIME: - if (strcmp(name, "atime") == 0) - xar->xmlsts = TOC_FILE; - break; - case FILE_GROUP: - if (strcmp(name, "group") == 0) - xar->xmlsts = TOC_FILE; - break; - case FILE_GID: - if (strcmp(name, "gid") == 0) - xar->xmlsts = TOC_FILE; - break; - case FILE_USER: - if (strcmp(name, "user") == 0) - xar->xmlsts = TOC_FILE; - break; - case FILE_UID: - if (strcmp(name, "uid") == 0) - xar->xmlsts = TOC_FILE; - break; - case FILE_MODE: - if (strcmp(name, "mode") == 0) - xar->xmlsts = TOC_FILE; - break; - case FILE_DEVICE: - if (strcmp(name, "device") == 0) - xar->xmlsts = TOC_FILE; - break; - case FILE_DEVICE_MAJOR: - if (strcmp(name, "major") == 0) - xar->xmlsts = FILE_DEVICE; - break; - case FILE_DEVICE_MINOR: - if (strcmp(name, "minor") == 0) - xar->xmlsts = FILE_DEVICE; - break; - case FILE_DEVICENO: - if (strcmp(name, "deviceno") == 0) - xar->xmlsts = TOC_FILE; - break; - case FILE_INODE: - if (strcmp(name, "inode") == 0) - xar->xmlsts = TOC_FILE; - break; - case FILE_LINK: - if (strcmp(name, "link") == 0) - xar->xmlsts = TOC_FILE; - break; - case FILE_TYPE: - if (strcmp(name, "type") == 0) - xar->xmlsts = TOC_FILE; - break; - case FILE_NAME: - if (strcmp(name, "name") == 0) - xar->xmlsts = TOC_FILE; - break; - case FILE_ACL: - if (strcmp(name, "acl") == 0) - xar->xmlsts = TOC_FILE; - break; - case FILE_ACL_DEFAULT: - if (strcmp(name, "default") == 0) - xar->xmlsts = FILE_ACL; - break; - case FILE_ACL_ACCESS: - if (strcmp(name, "access") == 0) - xar->xmlsts = FILE_ACL; - break; - case FILE_ACL_APPLEEXTENDED: - if (strcmp(name, "appleextended") == 0) - xar->xmlsts = FILE_ACL; - break; - case FILE_FLAGS: - if (strcmp(name, "flags") == 0) - xar->xmlsts = TOC_FILE; - break; - case FILE_FLAGS_USER_NODUMP: - if (strcmp(name, "UserNoDump") == 0) - xar->xmlsts = FILE_FLAGS; - break; - case FILE_FLAGS_USER_IMMUTABLE: - if (strcmp(name, "UserImmutable") == 0) - xar->xmlsts = FILE_FLAGS; - break; - case FILE_FLAGS_USER_APPEND: - if (strcmp(name, "UserAppend") == 0) - xar->xmlsts = FILE_FLAGS; - break; - case FILE_FLAGS_USER_OPAQUE: - if (strcmp(name, "UserOpaque") == 0) - xar->xmlsts = FILE_FLAGS; - break; - case FILE_FLAGS_USER_NOUNLINK: - if (strcmp(name, "UserNoUnlink") == 0) - xar->xmlsts = FILE_FLAGS; - break; - case FILE_FLAGS_SYS_ARCHIVED: - if (strcmp(name, "SystemArchived") == 0) - xar->xmlsts = FILE_FLAGS; - break; - case FILE_FLAGS_SYS_IMMUTABLE: - if (strcmp(name, "SystemImmutable") == 0) - xar->xmlsts = FILE_FLAGS; - break; - case FILE_FLAGS_SYS_APPEND: - if (strcmp(name, "SystemAppend") == 0) - xar->xmlsts = FILE_FLAGS; - break; - case FILE_FLAGS_SYS_NOUNLINK: - if (strcmp(name, "SystemNoUnlink") == 0) - xar->xmlsts = FILE_FLAGS; - break; - case FILE_FLAGS_SYS_SNAPSHOT: - if (strcmp(name, "SystemSnapshot") == 0) - xar->xmlsts = FILE_FLAGS; - break; - case FILE_EXT2: - if (strcmp(name, "ext2") == 0) - xar->xmlsts = TOC_FILE; - break; - case FILE_EXT2_SecureDeletion: - if (strcmp(name, "SecureDeletion") == 0) - xar->xmlsts = FILE_EXT2; - break; - case FILE_EXT2_Undelete: - if (strcmp(name, "Undelete") == 0) - xar->xmlsts = FILE_EXT2; - break; - case FILE_EXT2_Compress: - if (strcmp(name, "Compress") == 0) - xar->xmlsts = FILE_EXT2; - break; - case FILE_EXT2_Synchronous: - if (strcmp(name, "Synchronous") == 0) - xar->xmlsts = FILE_EXT2; - break; - case FILE_EXT2_Immutable: - if (strcmp(name, "Immutable") == 0) - xar->xmlsts = FILE_EXT2; - break; - case FILE_EXT2_AppendOnly: - if (strcmp(name, "AppendOnly") == 0) - xar->xmlsts = FILE_EXT2; - break; - case FILE_EXT2_NoDump: - if (strcmp(name, "NoDump") == 0) - xar->xmlsts = FILE_EXT2; - break; - case FILE_EXT2_NoAtime: - if (strcmp(name, "NoAtime") == 0) - xar->xmlsts = FILE_EXT2; - break; - case FILE_EXT2_CompDirty: - if (strcmp(name, "CompDirty") == 0) - xar->xmlsts = FILE_EXT2; - break; - case FILE_EXT2_CompBlock: - if (strcmp(name, "CompBlock") == 0) - xar->xmlsts = FILE_EXT2; - break; - case FILE_EXT2_NoCompBlock: - if (strcmp(name, "NoCompBlock") == 0) - xar->xmlsts = FILE_EXT2; - break; - case FILE_EXT2_CompError: - if (strcmp(name, "CompError") == 0) - xar->xmlsts = FILE_EXT2; - break; - case FILE_EXT2_BTree: - if (strcmp(name, "BTree") == 0) - xar->xmlsts = FILE_EXT2; - break; - case FILE_EXT2_HashIndexed: - if (strcmp(name, "HashIndexed") == 0) - xar->xmlsts = FILE_EXT2; - break; - case FILE_EXT2_iMagic: - if (strcmp(name, "iMagic") == 0) - xar->xmlsts = FILE_EXT2; - break; - case FILE_EXT2_Journaled: - if (strcmp(name, "Journaled") == 0) - xar->xmlsts = FILE_EXT2; - break; - case FILE_EXT2_NoTail: - if (strcmp(name, "NoTail") == 0) - xar->xmlsts = FILE_EXT2; - break; - case FILE_EXT2_DirSync: - if (strcmp(name, "DirSync") == 0) - xar->xmlsts = FILE_EXT2; - break; - case FILE_EXT2_TopDir: - if (strcmp(name, "TopDir") == 0) - xar->xmlsts = FILE_EXT2; - break; - case FILE_EXT2_Reserved: - if (strcmp(name, "Reserved") == 0) - xar->xmlsts = FILE_EXT2; - break; - case UNKNOWN: - unknowntag_end(xar, name); - break; - } -} - -static const int base64[256] = { - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, /* 00 - 0F */ - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, /* 10 - 1F */ - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 62, -1, -1, -1, 63, /* 20 - 2F */ - 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, -1, -1, -1, -1, -1, -1, /* 30 - 3F */ - -1, 0, 1, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, /* 40 - 4F */ - 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, -1, -1, -1, -1, -1, /* 50 - 5F */ - -1, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, /* 60 - 6F */ - 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, -1, -1, -1, -1, -1, /* 70 - 7F */ - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, /* 80 - 8F */ - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, /* 90 - 9F */ - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, /* A0 - AF */ - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, /* B0 - BF */ - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, /* C0 - CF */ - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, /* D0 - DF */ - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, /* E0 - EF */ - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, /* F0 - FF */ -}; - -static void -strappend_base64(struct xar *xar, - struct archive_string *as, const char *s, size_t l) -{ - unsigned char buff[256]; - unsigned char *out; - const unsigned char *b; - size_t len; - - (void)xar; /* UNUSED */ - len = 0; - out = buff; - b = (const unsigned char *)s; - while (l > 0) { - int n = 0; - - if (base64[b[0]] < 0 || base64[b[1]] < 0) - break; - n = base64[*b++] << 18; - n |= base64[*b++] << 12; - *out++ = n >> 16; - len++; - l -= 2; - - if (l > 0) { - if (base64[*b] < 0) - break; - n |= base64[*b++] << 6; - *out++ = (n >> 8) & 0xFF; - len++; - --l; - } - if (l > 0) { - if (base64[*b] < 0) - break; - n |= base64[*b++]; - *out++ = n & 0xFF; - len++; - --l; - } - if (len+3 >= sizeof(buff)) { - archive_strncat(as, (const char *)buff, len); - len = 0; - out = buff; - } - } - if (len > 0) - archive_strncat(as, (const char *)buff, len); -} - -static int -is_string(const char *known, const char *data, size_t len) -{ - if (strlen(known) != len) - return -1; - return memcmp(data, known, len); -} - -static void -xml_data(void *userData, const char *s, int len) -{ - struct archive_read *a; - struct xar *xar; - - a = (struct archive_read *)userData; - xar = (struct xar *)(a->format->data); - -#if DEBUG - { - char buff[1024]; - if (len > (int)(sizeof(buff)-1)) - len = (int)(sizeof(buff)-1); - strncpy(buff, s, len); - buff[len] = 0; - fprintf(stderr, "\tlen=%d:\"%s\"\n", len, buff); - } -#endif - switch (xar->xmlsts) { - case TOC_CHECKSUM_OFFSET: - xar->toc_chksum_offset = atol10(s, len); - break; - case TOC_CHECKSUM_SIZE: - xar->toc_chksum_size = atol10(s, len); - break; - default: - break; - } - if (xar->file == NULL) - return; - - switch (xar->xmlsts) { - case FILE_NAME: - if (xar->file->parent != NULL) { - archive_string_concat(&(xar->file->pathname), - &(xar->file->parent->pathname)); - archive_strappend_char(&(xar->file->pathname), '/'); - } - xar->file->has |= HAS_PATHNAME; - if (xar->base64text) { - strappend_base64(xar, - &(xar->file->pathname), s, len); - } else - archive_strncat(&(xar->file->pathname), s, len); - break; - case FILE_LINK: - xar->file->has |= HAS_SYMLINK; - archive_strncpy(&(xar->file->symlink), s, len); - break; - case FILE_TYPE: - if (is_string("file", s, len) == 0 || - is_string("hardlink", s, len) == 0) - xar->file->mode = - (xar->file->mode & ~AE_IFMT) | AE_IFREG; - if (is_string("directory", s, len) == 0) - xar->file->mode = - (xar->file->mode & ~AE_IFMT) | AE_IFDIR; - if (is_string("symlink", s, len) == 0) - xar->file->mode = - (xar->file->mode & ~AE_IFMT) | AE_IFLNK; - if (is_string("character special", s, len) == 0) - xar->file->mode = - (xar->file->mode & ~AE_IFMT) | AE_IFCHR; - if (is_string("block special", s, len) == 0) - xar->file->mode = - (xar->file->mode & ~AE_IFMT) | AE_IFBLK; - if (is_string("socket", s, len) == 0) - xar->file->mode = - (xar->file->mode & ~AE_IFMT) | AE_IFSOCK; - if (is_string("fifo", s, len) == 0) - xar->file->mode = - (xar->file->mode & ~AE_IFMT) | AE_IFIFO; - xar->file->has |= HAS_TYPE; - break; - case FILE_INODE: - xar->file->has |= HAS_INO; - xar->file->ino64 = atol10(s, len); - break; - case FILE_DEVICE_MAJOR: - xar->file->has |= HAS_DEVMAJOR; - xar->file->devmajor = (dev_t)atol10(s, len); - break; - case FILE_DEVICE_MINOR: - xar->file->has |= HAS_DEVMINOR; - xar->file->devminor = (dev_t)atol10(s, len); - break; - case FILE_DEVICENO: - xar->file->has |= HAS_DEV; - xar->file->dev = (dev_t)atol10(s, len); - break; - case FILE_MODE: - xar->file->has |= HAS_MODE; - xar->file->mode = - (xar->file->mode & AE_IFMT) | - ((mode_t)(atol8(s, len)) & ~AE_IFMT); - break; - case FILE_GROUP: - xar->file->has |= HAS_GID; - archive_strncpy(&(xar->file->gname), s, len); - break; - case FILE_GID: - xar->file->has |= HAS_GID; - xar->file->gid = atol10(s, len); - break; - case FILE_USER: - xar->file->has |= HAS_UID; - archive_strncpy(&(xar->file->uname), s, len); - break; - case FILE_UID: - xar->file->has |= HAS_UID; - xar->file->uid = atol10(s, len); - break; - case FILE_CTIME: - xar->file->has |= HAS_TIME | HAS_CTIME; - xar->file->ctime = parse_time(s, len); - break; - case FILE_MTIME: - xar->file->has |= HAS_TIME | HAS_MTIME; - xar->file->mtime = parse_time(s, len); - break; - case FILE_ATIME: - xar->file->has |= HAS_TIME | HAS_ATIME; - xar->file->atime = parse_time(s, len); - break; - case FILE_DATA_LENGTH: - xar->file->has |= HAS_DATA; - xar->file->length = atol10(s, len); - break; - case FILE_DATA_OFFSET: - xar->file->has |= HAS_DATA; - xar->file->offset = atol10(s, len); - break; - case FILE_DATA_SIZE: - xar->file->has |= HAS_DATA; - xar->file->size = atol10(s, len); - break; - case FILE_DATA_A_CHECKSUM: - xar->file->a_sum.len = atohex(xar->file->a_sum.val, - sizeof(xar->file->a_sum.val), s, len); - break; - case FILE_DATA_E_CHECKSUM: - xar->file->e_sum.len = atohex(xar->file->e_sum.val, - sizeof(xar->file->e_sum.val), s, len); - break; - case FILE_EA_LENGTH: - xar->file->has |= HAS_XATTR; - xar->xattr->length = atol10(s, len); - break; - case FILE_EA_OFFSET: - xar->file->has |= HAS_XATTR; - xar->xattr->offset = atol10(s, len); - break; - case FILE_EA_SIZE: - xar->file->has |= HAS_XATTR; - xar->xattr->size = atol10(s, len); - break; - case FILE_EA_A_CHECKSUM: - xar->file->has |= HAS_XATTR; - xar->xattr->a_sum.len = atohex(xar->xattr->a_sum.val, - sizeof(xar->xattr->a_sum.val), s, len); - break; - case FILE_EA_E_CHECKSUM: - xar->file->has |= HAS_XATTR; - xar->xattr->e_sum.len = atohex(xar->xattr->e_sum.val, - sizeof(xar->xattr->e_sum.val), s, len); - break; - case FILE_EA_NAME: - xar->file->has |= HAS_XATTR; - archive_strncpy(&(xar->xattr->name), s, len); - break; - case FILE_EA_FSTYPE: - xar->file->has |= HAS_XATTR; - archive_strncpy(&(xar->xattr->fstype), s, len); - break; - break; - case FILE_ACL_DEFAULT: - case FILE_ACL_ACCESS: - case FILE_ACL_APPLEEXTENDED: - xar->file->has |= HAS_ACL; - /* TODO */ - break; - case INIT: - case XAR: - case TOC: - case TOC_CREATION_TIME: - case TOC_CHECKSUM: - case TOC_CHECKSUM_OFFSET: - case TOC_CHECKSUM_SIZE: - case TOC_FILE: - case FILE_DATA: - case FILE_DATA_ENCODING: - case FILE_DATA_CONTENT: - case FILE_DEVICE: - case FILE_EA: - case FILE_EA_ENCODING: - case FILE_ACL: - case FILE_FLAGS: - case FILE_FLAGS_USER_NODUMP: - case FILE_FLAGS_USER_IMMUTABLE: - case FILE_FLAGS_USER_APPEND: - case FILE_FLAGS_USER_OPAQUE: - case FILE_FLAGS_USER_NOUNLINK: - case FILE_FLAGS_SYS_ARCHIVED: - case FILE_FLAGS_SYS_IMMUTABLE: - case FILE_FLAGS_SYS_APPEND: - case FILE_FLAGS_SYS_NOUNLINK: - case FILE_FLAGS_SYS_SNAPSHOT: - case FILE_EXT2: - case FILE_EXT2_SecureDeletion: - case FILE_EXT2_Undelete: - case FILE_EXT2_Compress: - case FILE_EXT2_Synchronous: - case FILE_EXT2_Immutable: - case FILE_EXT2_AppendOnly: - case FILE_EXT2_NoDump: - case FILE_EXT2_NoAtime: - case FILE_EXT2_CompDirty: - case FILE_EXT2_CompBlock: - case FILE_EXT2_NoCompBlock: - case FILE_EXT2_CompError: - case FILE_EXT2_BTree: - case FILE_EXT2_HashIndexed: - case FILE_EXT2_iMagic: - case FILE_EXT2_Journaled: - case FILE_EXT2_NoTail: - case FILE_EXT2_DirSync: - case FILE_EXT2_TopDir: - case FILE_EXT2_Reserved: - case UNKNOWN: - break; - } -} - -/* - * BSD file flags. - */ -static int -xml_parse_file_flags(struct xar *xar, const char *name) -{ - const char *flag = NULL; - - if (strcmp(name, "UserNoDump") == 0) { - xar->xmlsts = FILE_FLAGS_USER_NODUMP; - flag = "nodump"; - } - else if (strcmp(name, "UserImmutable") == 0) { - xar->xmlsts = FILE_FLAGS_USER_IMMUTABLE; - flag = "uimmutable"; - } - else if (strcmp(name, "UserAppend") == 0) { - xar->xmlsts = FILE_FLAGS_USER_APPEND; - flag = "uappend"; - } - else if (strcmp(name, "UserOpaque") == 0) { - xar->xmlsts = FILE_FLAGS_USER_OPAQUE; - flag = "opaque"; - } - else if (strcmp(name, "UserNoUnlink") == 0) { - xar->xmlsts = FILE_FLAGS_USER_NOUNLINK; - flag = "nouunlink"; - } - else if (strcmp(name, "SystemArchived") == 0) { - xar->xmlsts = FILE_FLAGS_SYS_ARCHIVED; - flag = "archived"; - } - else if (strcmp(name, "SystemImmutable") == 0) { - xar->xmlsts = FILE_FLAGS_SYS_IMMUTABLE; - flag = "simmutable"; - } - else if (strcmp(name, "SystemAppend") == 0) { - xar->xmlsts = FILE_FLAGS_SYS_APPEND; - flag = "sappend"; - } - else if (strcmp(name, "SystemNoUnlink") == 0) { - xar->xmlsts = FILE_FLAGS_SYS_NOUNLINK; - flag = "nosunlink"; - } - else if (strcmp(name, "SystemSnapshot") == 0) { - xar->xmlsts = FILE_FLAGS_SYS_SNAPSHOT; - flag = "snapshot"; - } - - if (flag == NULL) - return (0); - xar->file->has |= HAS_FFLAGS; - if (archive_strlen(&(xar->file->fflags_text)) > 0) - archive_strappend_char(&(xar->file->fflags_text), ','); - archive_strcat(&(xar->file->fflags_text), flag); - return (1); -} - -/* - * Linux file flags. - */ -static int -xml_parse_file_ext2(struct xar *xar, const char *name) -{ - const char *flag = NULL; - - if (strcmp(name, "SecureDeletion") == 0) { - xar->xmlsts = FILE_EXT2_SecureDeletion; - flag = "securedeletion"; - } - else if (strcmp(name, "Undelete") == 0) { - xar->xmlsts = FILE_EXT2_Undelete; - flag = "nouunlink"; - } - else if (strcmp(name, "Compress") == 0) { - xar->xmlsts = FILE_EXT2_Compress; - flag = "compress"; - } - else if (strcmp(name, "Synchronous") == 0) { - xar->xmlsts = FILE_EXT2_Synchronous; - flag = "sync"; - } - else if (strcmp(name, "Immutable") == 0) { - xar->xmlsts = FILE_EXT2_Immutable; - flag = "simmutable"; - } - else if (strcmp(name, "AppendOnly") == 0) { - xar->xmlsts = FILE_EXT2_AppendOnly; - flag = "sappend"; - } - else if (strcmp(name, "NoDump") == 0) { - xar->xmlsts = FILE_EXT2_NoDump; - flag = "nodump"; - } - else if (strcmp(name, "NoAtime") == 0) { - xar->xmlsts = FILE_EXT2_NoAtime; - flag = "noatime"; - } - else if (strcmp(name, "CompDirty") == 0) { - xar->xmlsts = FILE_EXT2_CompDirty; - flag = "compdirty"; - } - else if (strcmp(name, "CompBlock") == 0) { - xar->xmlsts = FILE_EXT2_CompBlock; - flag = "comprblk"; - } - else if (strcmp(name, "NoCompBlock") == 0) { - xar->xmlsts = FILE_EXT2_NoCompBlock; - flag = "nocomprblk"; - } - else if (strcmp(name, "CompError") == 0) { - xar->xmlsts = FILE_EXT2_CompError; - flag = "comperr"; - } - else if (strcmp(name, "BTree") == 0) { - xar->xmlsts = FILE_EXT2_BTree; - flag = "btree"; - } - else if (strcmp(name, "HashIndexed") == 0) { - xar->xmlsts = FILE_EXT2_HashIndexed; - flag = "hashidx"; - } - else if (strcmp(name, "iMagic") == 0) { - xar->xmlsts = FILE_EXT2_iMagic; - flag = "imagic"; - } - else if (strcmp(name, "Journaled") == 0) { - xar->xmlsts = FILE_EXT2_Journaled; - flag = "journal"; - } - else if (strcmp(name, "NoTail") == 0) { - xar->xmlsts = FILE_EXT2_NoTail; - flag = "notail"; - } - else if (strcmp(name, "DirSync") == 0) { - xar->xmlsts = FILE_EXT2_DirSync; - flag = "dirsync"; - } - else if (strcmp(name, "TopDir") == 0) { - xar->xmlsts = FILE_EXT2_TopDir; - flag = "topdir"; - } - else if (strcmp(name, "Reserved") == 0) { - xar->xmlsts = FILE_EXT2_Reserved; - flag = "reserved"; - } - - if (flag == NULL) - return (0); - if (archive_strlen(&(xar->file->fflags_text)) > 0) - archive_strappend_char(&(xar->file->fflags_text), ','); - archive_strcat(&(xar->file->fflags_text), flag); - return (1); -} - -#ifdef HAVE_LIBXML_XMLREADER_H - -static int -xml2_xmlattr_setup(struct archive_read *a, - struct xmlattr_list *list, xmlTextReaderPtr reader) -{ - struct xmlattr *attr; - int r; - - list->first = NULL; - list->last = &(list->first); - r = xmlTextReaderMoveToFirstAttribute(reader); - while (r == 1) { - attr = malloc(sizeof*(attr)); - if (attr == NULL) { - archive_set_error(&a->archive, ENOMEM, "Out of memory"); - return (ARCHIVE_FATAL); - } - attr->name = strdup( - (const char *)xmlTextReaderConstLocalName(reader)); - if (attr->name == NULL) { - free(attr); - archive_set_error(&a->archive, ENOMEM, "Out of memory"); - return (ARCHIVE_FATAL); - } - attr->value = strdup( - (const char *)xmlTextReaderConstValue(reader)); - if (attr->value == NULL) { - free(attr->name); - free(attr); - archive_set_error(&a->archive, ENOMEM, "Out of memory"); - return (ARCHIVE_FATAL); - } - attr->next = NULL; - *list->last = attr; - list->last = &(attr->next); - r = xmlTextReaderMoveToNextAttribute(reader); - } - return (r); -} - -static int -xml2_read_cb(void *context, char *buffer, int len) -{ - struct archive_read *a; - struct xar *xar; - const void *d; - size_t outbytes; - size_t used = 0; - int r; - - a = (struct archive_read *)context; - xar = (struct xar *)(a->format->data); - - if (xar->toc_remaining <= 0) - return (0); - d = buffer; - outbytes = len; - r = rd_contents(a, &d, &outbytes, &used, xar->toc_remaining); - if (r != ARCHIVE_OK) - return (r); - __archive_read_consume(a, used); - xar->toc_remaining -= used; - xar->offset += used; - xar->toc_total += outbytes; - PRINT_TOC(buffer, len); - - return ((int)outbytes); -} - -static int -xml2_close_cb(void *context) -{ - - (void)context; /* UNUSED */ - return (0); -} - -static void -xml2_error_hdr(void *arg, const char *msg, xmlParserSeverities severity, - xmlTextReaderLocatorPtr locator) -{ - struct archive_read *a; - - (void)locator; /* UNUSED */ - a = (struct archive_read *)arg; - switch (severity) { - case XML_PARSER_SEVERITY_VALIDITY_WARNING: - case XML_PARSER_SEVERITY_WARNING: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "XML Parsing error: %s", msg); - break; - case XML_PARSER_SEVERITY_VALIDITY_ERROR: - case XML_PARSER_SEVERITY_ERROR: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "XML Parsing error: %s", msg); - break; - } -} - -static int -xml2_read_toc(struct archive_read *a) -{ - xmlTextReaderPtr reader; - struct xmlattr_list list; - int r; - - reader = xmlReaderForIO(xml2_read_cb, xml2_close_cb, a, NULL, NULL, 0); - if (reader == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Couldn't allocate memory for xml parser"); - return (ARCHIVE_FATAL); - } - xmlTextReaderSetErrorHandler(reader, xml2_error_hdr, a); - - while ((r = xmlTextReaderRead(reader)) == 1) { - const char *name, *value; - int type, empty; - - type = xmlTextReaderNodeType(reader); - name = (const char *)xmlTextReaderConstLocalName(reader); - switch (type) { - case XML_READER_TYPE_ELEMENT: - empty = xmlTextReaderIsEmptyElement(reader); - r = xml2_xmlattr_setup(a, &list, reader); - if (r == ARCHIVE_OK) - r = xml_start(a, name, &list); - xmlattr_cleanup(&list); - if (r != ARCHIVE_OK) - return (r); - if (empty) - xml_end(a, name); - break; - case XML_READER_TYPE_END_ELEMENT: - xml_end(a, name); - break; - case XML_READER_TYPE_TEXT: - value = (const char *)xmlTextReaderConstValue(reader); - xml_data(a, value, strlen(value)); - break; - case XML_READER_TYPE_SIGNIFICANT_WHITESPACE: - default: - break; - } - if (r < 0) - break; - } - xmlFreeTextReader(reader); - xmlCleanupParser(); - - return ((r == 0)?ARCHIVE_OK:ARCHIVE_FATAL); -} - -#elif defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H) - -static int -expat_xmlattr_setup(struct archive_read *a, - struct xmlattr_list *list, const XML_Char **atts) -{ - struct xmlattr *attr; - char *name, *value; - - list->first = NULL; - list->last = &(list->first); - if (atts == NULL) - return (ARCHIVE_OK); - while (atts[0] != NULL && atts[1] != NULL) { - attr = malloc(sizeof*(attr)); - name = strdup(atts[0]); - value = strdup(atts[1]); - if (attr == NULL || name == NULL || value == NULL) { - archive_set_error(&a->archive, ENOMEM, "Out of memory"); - free(attr); - free(name); - free(value); - return (ARCHIVE_FATAL); - } - attr->name = name; - attr->value = value; - attr->next = NULL; - *list->last = attr; - list->last = &(attr->next); - atts += 2; - } - return (ARCHIVE_OK); -} - -static void -expat_start_cb(void *userData, const XML_Char *name, const XML_Char **atts) -{ - struct expat_userData *ud = (struct expat_userData *)userData; - struct archive_read *a = ud->archive; - struct xmlattr_list list; - int r; - - r = expat_xmlattr_setup(a, &list, atts); - if (r == ARCHIVE_OK) - r = xml_start(a, (const char *)name, &list); - xmlattr_cleanup(&list); - ud->state = r; -} - -static void -expat_end_cb(void *userData, const XML_Char *name) -{ - struct expat_userData *ud = (struct expat_userData *)userData; - - xml_end(ud->archive, (const char *)name); -} - -static void -expat_data_cb(void *userData, const XML_Char *s, int len) -{ - struct expat_userData *ud = (struct expat_userData *)userData; - - xml_data(ud->archive, s, len); -} - -static int -expat_read_toc(struct archive_read *a) -{ - struct xar *xar; - XML_Parser parser; - struct expat_userData ud; - - ud.state = ARCHIVE_OK; - ud.archive = a; - - xar = (struct xar *)(a->format->data); - - /* Initialize XML Parser library. */ - parser = XML_ParserCreate(NULL); - if (parser == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Couldn't allocate memory for xml parser"); - return (ARCHIVE_FATAL); - } - XML_SetUserData(parser, &ud); - XML_SetElementHandler(parser, expat_start_cb, expat_end_cb); - XML_SetCharacterDataHandler(parser, expat_data_cb); - xar->xmlsts = INIT; - - while (xar->toc_remaining && ud.state == ARCHIVE_OK) { - enum XML_Status xr; - const void *d; - size_t outbytes; - size_t used; - int r; - - d = NULL; - r = rd_contents(a, &d, &outbytes, &used, xar->toc_remaining); - if (r != ARCHIVE_OK) - return (r); - xar->toc_remaining -= used; - xar->offset += used; - xar->toc_total += outbytes; - PRINT_TOC(d, outbytes); - - xr = XML_Parse(parser, d, outbytes, xar->toc_remaining == 0); - __archive_read_consume(a, used); - if (xr == XML_STATUS_ERROR) { - XML_ParserFree(parser); - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "XML Parsing failed"); - return (ARCHIVE_FATAL); - } - } - XML_ParserFree(parser); - return (ud.state); -} -#endif /* defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H) */ - -#endif /* Support xar format */ diff --git a/thirdparty/libarchive/libarchive/archive_read_support_format_zip.c b/thirdparty/libarchive/libarchive/archive_read_support_format_zip.c deleted file mode 100644 index c3b9b5755..000000000 --- a/thirdparty/libarchive/libarchive/archive_read_support_format_zip.c +++ /dev/null @@ -1,4270 +0,0 @@ -/*- - * Copyright (c) 2004-2013 Tim Kientzle - * Copyright (c) 2011-2012,2014 Michihiro NAKAJIMA - * Copyright (c) 2013 Konrad Kleine - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_zip.c 201102 2009-12-28 03:11:36Z kientzle $"); - -/* - * The definitive documentation of the Zip file format is: - * http://www.pkware.com/documents/casestudies/APPNOTE.TXT - * - * The Info-Zip project has pioneered various extensions to better - * support Zip on Unix, including the 0x5455 "UT", 0x5855 "UX", 0x7855 - * "Ux", and 0x7875 "ux" extensions for time and ownership - * information. - * - * History of this code: The streaming Zip reader was first added to - * libarchive in January 2005. Support for seekable input sources was - * added in Nov 2011. Zip64 support (including a significant code - * refactoring) was added in 2014. - */ - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_ZLIB_H -#include -#endif -#ifdef HAVE_BZLIB_H -#include -#endif -#ifdef HAVE_LZMA_H -#include -#endif -#ifdef HAVE_ZSTD_H -#include -#endif - -#include "archive.h" -#include "archive_digest_private.h" -#include "archive_cryptor_private.h" -#include "archive_endian.h" -#include "archive_entry.h" -#include "archive_entry_locale.h" -#include "archive_hmac_private.h" -#include "archive_private.h" -#include "archive_rb.h" -#include "archive_read_private.h" -#include "archive_ppmd8_private.h" - -#ifndef HAVE_ZLIB_H -#include "archive_crc32.h" -#endif - -struct zip_entry { - struct archive_rb_node node; - struct zip_entry *next; - int64_t local_header_offset; - int64_t compressed_size; - int64_t uncompressed_size; - int64_t gid; - int64_t uid; - struct archive_string rsrcname; - time_t mtime; - time_t atime; - time_t ctime; - uint32_t crc32; - uint16_t mode; - uint16_t zip_flags; /* From GP Flags Field */ - unsigned char compression; - unsigned char system; /* From "version written by" */ - unsigned char flags; /* Our extra markers. */ - unsigned char decdat;/* Used for Decryption check */ - - /* WinZip AES encryption extra field should be available - * when compression is 99. */ - struct { - /* Vendor version: AE-1 - 0x0001, AE-2 - 0x0002 */ - unsigned vendor; -#define AES_VENDOR_AE_1 0x0001 -#define AES_VENDOR_AE_2 0x0002 - /* AES encryption strength: - * 1 - 128 bits, 2 - 192 bits, 2 - 256 bits. */ - unsigned strength; - /* Actual compression method. */ - unsigned char compression; - } aes_extra; -}; - -struct trad_enc_ctx { - uint32_t keys[3]; -}; - -/* Bits used in zip_flags. */ -#define ZIP_ENCRYPTED (1 << 0) -#define ZIP_LENGTH_AT_END (1 << 3) -#define ZIP_STRONG_ENCRYPTED (1 << 6) -#define ZIP_UTF8_NAME (1 << 11) -/* See "7.2 Single Password Symmetric Encryption Method" - in http://www.pkware.com/documents/casestudies/APPNOTE.TXT */ -#define ZIP_CENTRAL_DIRECTORY_ENCRYPTED (1 << 13) - -/* Bits used in flags. */ -#define LA_USED_ZIP64 (1 << 0) -#define LA_FROM_CENTRAL_DIRECTORY (1 << 1) - -/* - * See "WinZip - AES Encryption Information" - * http://www.winzip.com/aes_info.htm - */ -/* Value used in compression method. */ -#define WINZIP_AES_ENCRYPTION 99 -/* Authentication code size. */ -#define AUTH_CODE_SIZE 10 -/**/ -#define MAX_DERIVED_KEY_BUF_SIZE (AES_MAX_KEY_SIZE * 2 + 2) - -struct zip { - /* Structural information about the archive. */ - struct archive_string format_name; - int64_t central_directory_offset; - int64_t central_directory_offset_adjusted; - size_t central_directory_entries_total; - size_t central_directory_entries_on_this_disk; - int has_encrypted_entries; - - /* List of entries (seekable Zip only) */ - struct zip_entry *zip_entries; - struct archive_rb_tree tree; - struct archive_rb_tree tree_rsrc; - - /* Bytes read but not yet consumed via __archive_read_consume() */ - size_t unconsumed; - - /* Information about entry we're currently reading. */ - struct zip_entry *entry; - int64_t entry_bytes_remaining; - - /* These count the number of bytes actually read for the entry. */ - int64_t entry_compressed_bytes_read; - int64_t entry_uncompressed_bytes_read; - - /* Running CRC32 of the decompressed data */ - unsigned long entry_crc32; - unsigned long (*crc32func)(unsigned long, const void *, - size_t); - char ignore_crc32; - - /* Flags to mark progress of decompression. */ - char decompress_init; - char end_of_entry; - - unsigned char *uncompressed_buffer; - size_t uncompressed_buffer_size; - -#ifdef HAVE_ZLIB_H - z_stream stream; - char stream_valid; -#endif - -#if HAVE_LZMA_H && HAVE_LIBLZMA - lzma_stream zipx_lzma_stream; - char zipx_lzma_valid; -#endif - -#ifdef HAVE_BZLIB_H - bz_stream bzstream; - char bzstream_valid; -#endif - -#if HAVE_ZSTD_H && HAVE_LIBZSTD - ZSTD_DStream *zstdstream; - char zstdstream_valid; -#endif - - IByteIn zipx_ppmd_stream; - ssize_t zipx_ppmd_read_compressed; - CPpmd8 ppmd8; - char ppmd8_valid; - char ppmd8_stream_failed; - - struct archive_string_conv *sconv; - struct archive_string_conv *sconv_default; - struct archive_string_conv *sconv_utf8; - int init_default_conversion; - int process_mac_extensions; - - char init_decryption; - - /* Decryption buffer. */ - /* - * The decrypted data starts at decrypted_ptr and - * extends for decrypted_bytes_remaining. Decryption - * adds new data to the end of this block, data is returned - * to clients from the beginning. When the block hits the - * end of decrypted_buffer, it has to be shuffled back to - * the beginning of the buffer. - */ - unsigned char *decrypted_buffer; - unsigned char *decrypted_ptr; - size_t decrypted_buffer_size; - size_t decrypted_bytes_remaining; - size_t decrypted_unconsumed_bytes; - - /* Traditional PKWARE decryption. */ - struct trad_enc_ctx tctx; - char tctx_valid; - - /* WinZip AES decryption. */ - /* Contexts used for AES decryption. */ - archive_crypto_ctx cctx; - char cctx_valid; - archive_hmac_sha1_ctx hctx; - char hctx_valid; - - /* Strong encryption's decryption header information. */ - unsigned iv_size; - unsigned alg_id; - unsigned bit_len; - unsigned flags; - unsigned erd_size; - unsigned v_size; - unsigned v_crc32; - uint8_t *iv; - uint8_t *erd; - uint8_t *v_data; -}; - -/* Many systems define min or MIN, but not all. */ -#define zipmin(a,b) ((a) < (b) ? (a) : (b)) - -#ifdef HAVE_ZLIB_H -static int -zip_read_data_deflate(struct archive_read *a, const void **buff, - size_t *size, int64_t *offset); -#endif -#if HAVE_LZMA_H && HAVE_LIBLZMA -static int -zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff, - size_t *size, int64_t *offset); -#endif - -/* This function is used by Ppmd8_DecodeSymbol during decompression of Ppmd8 - * streams inside ZIP files. It has 2 purposes: one is to fetch the next - * compressed byte from the stream, second one is to increase the counter how - * many compressed bytes were read. */ -static Byte -ppmd_read(void* p) { - /* Get the handle to current decompression context. */ - struct archive_read *a = ((IByteIn*)p)->a; - struct zip *zip = (struct zip*) a->format->data; - ssize_t bytes_avail = 0; - - /* Fetch next byte. */ - const uint8_t* data = __archive_read_ahead(a, 1, &bytes_avail); - if(bytes_avail < 1) { - zip->ppmd8_stream_failed = 1; - return 0; - } - - __archive_read_consume(a, 1); - - /* Increment the counter. */ - ++zip->zipx_ppmd_read_compressed; - - /* Return the next compressed byte. */ - return data[0]; -} - -/* ------------------------------------------------------------------------ */ - -/* - Traditional PKWARE Decryption functions. - */ - -static void -trad_enc_update_keys(struct trad_enc_ctx *ctx, uint8_t c) -{ - uint8_t t; -#define CRC32(c, b) (crc32(c ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL) - - ctx->keys[0] = CRC32(ctx->keys[0], c); - ctx->keys[1] = (ctx->keys[1] + (ctx->keys[0] & 0xff)) * 134775813L + 1; - t = (ctx->keys[1] >> 24) & 0xff; - ctx->keys[2] = CRC32(ctx->keys[2], t); -#undef CRC32 -} - -static uint8_t -trad_enc_decrypt_byte(struct trad_enc_ctx *ctx) -{ - unsigned temp = ctx->keys[2] | 2; - return (uint8_t)((temp * (temp ^ 1)) >> 8) & 0xff; -} - -static void -trad_enc_decrypt_update(struct trad_enc_ctx *ctx, const uint8_t *in, - size_t in_len, uint8_t *out, size_t out_len) -{ - unsigned i, max; - - max = (unsigned)((in_len < out_len)? in_len: out_len); - - for (i = 0; i < max; i++) { - uint8_t t = in[i] ^ trad_enc_decrypt_byte(ctx); - out[i] = t; - trad_enc_update_keys(ctx, t); - } -} - -static int -trad_enc_init(struct trad_enc_ctx *ctx, const char *pw, size_t pw_len, - const uint8_t *key, size_t key_len, uint8_t *crcchk) -{ - uint8_t header[12]; - - if (key_len < 12) { - *crcchk = 0xff; - return -1; - } - - ctx->keys[0] = 305419896L; - ctx->keys[1] = 591751049L; - ctx->keys[2] = 878082192L; - - for (;pw_len; --pw_len) - trad_enc_update_keys(ctx, *pw++); - - trad_enc_decrypt_update(ctx, key, 12, header, 12); - /* Return the last byte for CRC check. */ - *crcchk = header[11]; - return 0; -} - -#if 0 -static void -crypt_derive_key_sha1(const void *p, int size, unsigned char *key, - int key_size) -{ -#define MD_SIZE 20 - archive_sha1_ctx ctx; - unsigned char md1[MD_SIZE]; - unsigned char md2[MD_SIZE * 2]; - unsigned char mkb[64]; - int i; - - archive_sha1_init(&ctx); - archive_sha1_update(&ctx, p, size); - archive_sha1_final(&ctx, md1); - - memset(mkb, 0x36, sizeof(mkb)); - for (i = 0; i < MD_SIZE; i++) - mkb[i] ^= md1[i]; - archive_sha1_init(&ctx); - archive_sha1_update(&ctx, mkb, sizeof(mkb)); - archive_sha1_final(&ctx, md2); - - memset(mkb, 0x5C, sizeof(mkb)); - for (i = 0; i < MD_SIZE; i++) - mkb[i] ^= md1[i]; - archive_sha1_init(&ctx); - archive_sha1_update(&ctx, mkb, sizeof(mkb)); - archive_sha1_final(&ctx, md2 + MD_SIZE); - - if (key_size > 32) - key_size = 32; - memcpy(key, md2, key_size); -#undef MD_SIZE -} -#endif - -/* - * Common code for streaming or seeking modes. - * - * Includes code to read local file headers, decompress data - * from entry bodies, and common API. - */ - -static unsigned long -real_crc32(unsigned long crc, const void *buff, size_t len) -{ - return crc32(crc, buff, (unsigned int)len); -} - -/* Used by "ignorecrc32" option to speed up tests. */ -static unsigned long -fake_crc32(unsigned long crc, const void *buff, size_t len) -{ - (void)crc; /* UNUSED */ - (void)buff; /* UNUSED */ - (void)len; /* UNUSED */ - return 0; -} - -static const struct { - int id; - const char * name; -} compression_methods[] = { - {0, "uncompressed"}, /* The file is stored (no compression) */ - {1, "shrinking"}, /* The file is Shrunk */ - {2, "reduced-1"}, /* The file is Reduced with compression factor 1 */ - {3, "reduced-2"}, /* The file is Reduced with compression factor 2 */ - {4, "reduced-3"}, /* The file is Reduced with compression factor 3 */ - {5, "reduced-4"}, /* The file is Reduced with compression factor 4 */ - {6, "imploded"}, /* The file is Imploded */ - {7, "reserved"}, /* Reserved for Tokenizing compression algorithm */ - {8, "deflation"}, /* The file is Deflated */ - {9, "deflation-64-bit"}, /* Enhanced Deflating using Deflate64(tm) */ - {10, "ibm-terse"},/* PKWARE Data Compression Library Imploding - * (old IBM TERSE) */ - {11, "reserved"}, /* Reserved by PKWARE */ - {12, "bzip"}, /* File is compressed using BZIP2 algorithm */ - {13, "reserved"}, /* Reserved by PKWARE */ - {14, "lzma"}, /* LZMA (EFS) */ - {15, "reserved"}, /* Reserved by PKWARE */ - {16, "reserved"}, /* Reserved by PKWARE */ - {17, "reserved"}, /* Reserved by PKWARE */ - {18, "ibm-terse-new"}, /* File is compressed using IBM TERSE (new) */ - {19, "ibm-lz777"},/* IBM LZ77 z Architecture (PFS) */ - {93, "zstd"}, /* Zstandard (zstd) Compression */ - {95, "xz"}, /* XZ compressed data */ - {96, "jpeg"}, /* JPEG compressed data */ - {97, "wav-pack"}, /* WavPack compressed data */ - {98, "ppmd-1"}, /* PPMd version I, Rev 1 */ - {99, "aes"} /* WinZip AES encryption */ -}; - -static const char * -compression_name(const int compression) -{ - static const int num_compression_methods = - sizeof(compression_methods)/sizeof(compression_methods[0]); - int i=0; - - while(compression >= 0 && i < num_compression_methods) { - if (compression_methods[i].id == compression) - return compression_methods[i].name; - i++; - } - return "??"; -} - -/* Convert an MSDOS-style date/time into Unix-style time. */ -static time_t -zip_time(const char *p) -{ - int msTime, msDate; - struct tm ts; - - msTime = (0xff & (unsigned)p[0]) + 256 * (0xff & (unsigned)p[1]); - msDate = (0xff & (unsigned)p[2]) + 256 * (0xff & (unsigned)p[3]); - - memset(&ts, 0, sizeof(ts)); - ts.tm_year = ((msDate >> 9) & 0x7f) + 80; /* Years since 1900. */ - ts.tm_mon = ((msDate >> 5) & 0x0f) - 1; /* Month number. */ - ts.tm_mday = msDate & 0x1f; /* Day of month. */ - ts.tm_hour = (msTime >> 11) & 0x1f; - ts.tm_min = (msTime >> 5) & 0x3f; - ts.tm_sec = (msTime << 1) & 0x3e; - ts.tm_isdst = -1; - return mktime(&ts); -} - -/* - * The extra data is stored as a list of - * id1+size1+data1 + id2+size2+data2 ... - * triplets. id and size are 2 bytes each. - */ -static int -process_extra(struct archive_read *a, struct archive_entry *entry, - const char *p, size_t extra_length, struct zip_entry* zip_entry) -{ - unsigned offset = 0; - struct zip *zip = (struct zip *)(a->format->data); - - if (extra_length == 0) { - return ARCHIVE_OK; - } - - if (extra_length < 4) { - size_t i = 0; - /* Some ZIP files may have trailing 0 bytes. Let's check they - * are all 0 and ignore them instead of returning an error. - * - * This is not technically correct, but some ZIP files look - * like this and other tools support those files - so let's - * also support them. - */ - for (; i < extra_length; i++) { - if (p[i] != 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Too-small extra data: " - "Need at least 4 bytes, " - "but only found %d bytes", - (int)extra_length); - return ARCHIVE_FAILED; - } - } - - return ARCHIVE_OK; - } - - while (offset <= extra_length - 4) { - unsigned short headerid = archive_le16dec(p + offset); - unsigned short datasize = archive_le16dec(p + offset + 2); - - offset += 4; - if (offset + datasize > extra_length) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, "Extra data overflow: " - "Need %d bytes but only found %d bytes", - (int)datasize, (int)(extra_length - offset)); - return ARCHIVE_FAILED; - } -#ifdef DEBUG - fprintf(stderr, "Header id 0x%04x, length %d\n", - headerid, datasize); -#endif - switch (headerid) { - case 0x0001: - /* Zip64 extended information extra field. */ - zip_entry->flags |= LA_USED_ZIP64; - if (zip_entry->uncompressed_size == 0xffffffff) { - uint64_t t = 0; - if (datasize < 8 - || (t = archive_le64dec(p + offset)) > - INT64_MAX) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Malformed 64-bit " - "uncompressed size"); - return ARCHIVE_FAILED; - } - zip_entry->uncompressed_size = t; - offset += 8; - datasize -= 8; - } - if (zip_entry->compressed_size == 0xffffffff) { - uint64_t t = 0; - if (datasize < 8 - || (t = archive_le64dec(p + offset)) > - INT64_MAX) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Malformed 64-bit " - "compressed size"); - return ARCHIVE_FAILED; - } - zip_entry->compressed_size = t; - offset += 8; - datasize -= 8; - } - if (zip_entry->local_header_offset == 0xffffffff) { - uint64_t t = 0; - if (datasize < 8 - || (t = archive_le64dec(p + offset)) > - INT64_MAX) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Malformed 64-bit " - "local header offset"); - return ARCHIVE_FAILED; - } - zip_entry->local_header_offset = t; - offset += 8; - datasize -= 8; - } - /* archive_le32dec(p + offset) gives disk - * on which file starts, but we don't handle - * multi-volume Zip files. */ - break; -#ifdef DEBUG - case 0x0017: - { - /* Strong encryption field. */ - if (archive_le16dec(p + offset) == 2) { - unsigned algId = - archive_le16dec(p + offset + 2); - unsigned bitLen = - archive_le16dec(p + offset + 4); - int flags = - archive_le16dec(p + offset + 6); - fprintf(stderr, "algId=0x%04x, bitLen=%u, " - "flgas=%d\n", algId, bitLen,flags); - } - break; - } -#endif - case 0x5455: - { - /* Extended time field "UT". */ - int flags; - if (datasize == 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Incomplete extended time field"); - return ARCHIVE_FAILED; - } - flags = p[offset]; - offset++; - datasize--; - /* Flag bits indicate which dates are present. */ - if (flags & 0x01) - { -#ifdef DEBUG - fprintf(stderr, "mtime: %lld -> %d\n", - (long long)zip_entry->mtime, - archive_le32dec(p + offset)); -#endif - if (datasize < 4) - break; - zip_entry->mtime = archive_le32dec(p + offset); - offset += 4; - datasize -= 4; - } - if (flags & 0x02) - { - if (datasize < 4) - break; - zip_entry->atime = archive_le32dec(p + offset); - offset += 4; - datasize -= 4; - } - if (flags & 0x04) - { - if (datasize < 4) - break; - zip_entry->ctime = archive_le32dec(p + offset); - offset += 4; - datasize -= 4; - } - break; - } - case 0x5855: - { - /* Info-ZIP Unix Extra Field (old version) "UX". */ - if (datasize >= 8) { - zip_entry->atime = archive_le32dec(p + offset); - zip_entry->mtime = - archive_le32dec(p + offset + 4); - } - if (datasize >= 12) { - zip_entry->uid = - archive_le16dec(p + offset + 8); - zip_entry->gid = - archive_le16dec(p + offset + 10); - } - break; - } - case 0x6c78: - { - /* Experimental 'xl' field */ - /* - * Introduced Dec 2013 to provide a way to - * include external file attributes (and other - * fields that ordinarily appear only in - * central directory) in local file header. - * This provides file type and permission - * information necessary to support full - * streaming extraction. Currently being - * discussed with other Zip developers - * ... subject to change. - * - * Format: - * The field starts with a bitmap that specifies - * which additional fields are included. The - * bitmap is variable length and can be extended in - * the future. - * - * n bytes - feature bitmap: first byte has low-order - * 7 bits. If high-order bit is set, a subsequent - * byte holds the next 7 bits, etc. - * - * if bitmap & 1, 2 byte "version made by" - * if bitmap & 2, 2 byte "internal file attributes" - * if bitmap & 4, 4 byte "external file attributes" - * if bitmap & 8, 2 byte comment length + n byte - * comment - */ - int bitmap, bitmap_last; - - if (datasize < 1) - break; - bitmap_last = bitmap = 0xff & p[offset]; - offset += 1; - datasize -= 1; - - /* We only support first 7 bits of bitmap; skip rest. */ - while ((bitmap_last & 0x80) != 0 - && datasize >= 1) { - bitmap_last = p[offset]; - offset += 1; - datasize -= 1; - } - - if (bitmap & 1) { - /* 2 byte "version made by" */ - if (datasize < 2) - break; - zip_entry->system - = archive_le16dec(p + offset) >> 8; - offset += 2; - datasize -= 2; - } - if (bitmap & 2) { - /* 2 byte "internal file attributes" */ - uint32_t internal_attributes; - if (datasize < 2) - break; - internal_attributes - = archive_le16dec(p + offset); - /* Not used by libarchive at present. */ - (void)internal_attributes; /* UNUSED */ - offset += 2; - datasize -= 2; - } - if (bitmap & 4) { - /* 4 byte "external file attributes" */ - uint32_t external_attributes; - if (datasize < 4) - break; - external_attributes - = archive_le32dec(p + offset); - if (zip_entry->system == 3) { - zip_entry->mode - = external_attributes >> 16; - } else if (zip_entry->system == 0) { - // Interpret MSDOS directory bit - if (0x10 == (external_attributes & - 0x10)) { - zip_entry->mode = - AE_IFDIR | 0775; - } else { - zip_entry->mode = - AE_IFREG | 0664; - } - if (0x01 == (external_attributes & - 0x01)) { - /* Read-only bit; - * strip write permissions */ - zip_entry->mode &= 0555; - } - } else { - zip_entry->mode = 0; - } - offset += 4; - datasize -= 4; - } - if (bitmap & 8) { - /* 2 byte comment length + comment */ - uint32_t comment_length; - if (datasize < 2) - break; - comment_length - = archive_le16dec(p + offset); - offset += 2; - datasize -= 2; - - if (datasize < comment_length) - break; - /* Comment is not supported by libarchive */ - offset += comment_length; - datasize -= comment_length; - } - break; - } - case 0x7075: - { - /* Info-ZIP Unicode Path Extra Field. */ - if (datasize < 5 || entry == NULL) - break; - offset += 5; - datasize -= 5; - - /* The path name in this field is always encoded - * in UTF-8. */ - if (zip->sconv_utf8 == NULL) { - zip->sconv_utf8 = - archive_string_conversion_from_charset( - &a->archive, "UTF-8", 1); - /* If the converter from UTF-8 is not - * available, then the path name from the main - * field will more likely be correct. */ - if (zip->sconv_utf8 == NULL) - break; - } - - /* Make sure the CRC32 of the filename matches. */ - if (!zip->ignore_crc32) { - const char *cp = archive_entry_pathname(entry); - if (cp) { - unsigned long file_crc = - zip->crc32func(0, cp, strlen(cp)); - unsigned long utf_crc = - archive_le32dec(p + offset - 4); - if (file_crc != utf_crc) { -#ifdef DEBUG - fprintf(stderr, - "CRC filename mismatch; " - "CDE is %lx, but UTF8 " - "is outdated with %lx\n", - file_crc, utf_crc); -#endif - break; - } - } - } - - if (archive_entry_copy_pathname_l(entry, - p + offset, datasize, zip->sconv_utf8) != 0) { - /* Ignore the error, and fallback to the path - * name from the main field. */ -#ifdef DEBUG - fprintf(stderr, "Failed to read the ZIP " - "0x7075 extra field path.\n"); -#endif - } - break; - } - case 0x7855: - /* Info-ZIP Unix Extra Field (type 2) "Ux". */ -#ifdef DEBUG - fprintf(stderr, "uid %d gid %d\n", - archive_le16dec(p + offset), - archive_le16dec(p + offset + 2)); -#endif - if (datasize >= 2) - zip_entry->uid = archive_le16dec(p + offset); - if (datasize >= 4) - zip_entry->gid = - archive_le16dec(p + offset + 2); - break; - case 0x7875: - { - /* Info-Zip Unix Extra Field (type 3) "ux". */ - int uidsize = 0, gidsize = 0; - - /* TODO: support arbitrary uidsize/gidsize. */ - if (datasize >= 1 && p[offset] == 1) {/* version=1 */ - if (datasize >= 4) { - /* get a uid size. */ - uidsize = 0xff & (int)p[offset+1]; - if (uidsize == 2) - zip_entry->uid = - archive_le16dec( - p + offset + 2); - else if (uidsize == 4 && datasize >= 6) - zip_entry->uid = - archive_le32dec( - p + offset + 2); - } - if (datasize >= (2 + uidsize + 3)) { - /* get a gid size. */ - gidsize = 0xff & - (int)p[offset+2+uidsize]; - if (gidsize == 2) - zip_entry->gid = - archive_le16dec( - p+offset+2+uidsize+1); - else if (gidsize == 4 && - datasize >= (2 + uidsize + 5)) - zip_entry->gid = - archive_le32dec( - p+offset+2+uidsize+1); - } - } - break; - } - case 0x9901: - /* WinZip AES extra data field. */ - if (datasize < 6) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Incomplete AES field"); - return ARCHIVE_FAILED; - } - if (p[offset + 2] == 'A' && p[offset + 3] == 'E') { - /* Vendor version. */ - zip_entry->aes_extra.vendor = - archive_le16dec(p + offset); - /* AES encryption strength. */ - zip_entry->aes_extra.strength = p[offset + 4]; - /* Actual compression method. */ - zip_entry->aes_extra.compression = - p[offset + 5]; - } - break; - default: - break; - } - offset += datasize; - } - return ARCHIVE_OK; -} - -/* - * Assumes file pointer is at beginning of local file header. - */ -static int -zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry, - struct zip *zip) -{ - const char *p; - const void *h; - const wchar_t *wp; - const char *cp; - size_t len, filename_length, extra_length; - struct archive_string_conv *sconv; - struct zip_entry *zip_entry = zip->entry; - struct zip_entry zip_entry_central_dir; - int ret = ARCHIVE_OK; - char version; - - /* Save a copy of the original for consistency checks. */ - zip_entry_central_dir = *zip_entry; - - zip->decompress_init = 0; - zip->end_of_entry = 0; - zip->entry_uncompressed_bytes_read = 0; - zip->entry_compressed_bytes_read = 0; - zip->entry_crc32 = zip->crc32func(0, NULL, 0); - - /* Setup default conversion. */ - if (zip->sconv == NULL && !zip->init_default_conversion) { - zip->sconv_default = - archive_string_default_conversion_for_read(&(a->archive)); - zip->init_default_conversion = 1; - } - - if ((p = __archive_read_ahead(a, 30, NULL)) == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated ZIP file header"); - return (ARCHIVE_FATAL); - } - - if (memcmp(p, "PK\003\004", 4) != 0) { - archive_set_error(&a->archive, -1, "Damaged Zip archive"); - return ARCHIVE_FATAL; - } - version = p[4]; - zip_entry->system = p[5]; - zip_entry->zip_flags = archive_le16dec(p + 6); - if (zip_entry->zip_flags & (ZIP_ENCRYPTED | ZIP_STRONG_ENCRYPTED)) { - zip->has_encrypted_entries = 1; - archive_entry_set_is_data_encrypted(entry, 1); - if (zip_entry->zip_flags & ZIP_CENTRAL_DIRECTORY_ENCRYPTED && - zip_entry->zip_flags & ZIP_ENCRYPTED && - zip_entry->zip_flags & ZIP_STRONG_ENCRYPTED) { - archive_entry_set_is_metadata_encrypted(entry, 1); - return ARCHIVE_FATAL; - } - } - zip->init_decryption = (zip_entry->zip_flags & ZIP_ENCRYPTED); - zip_entry->compression = (char)archive_le16dec(p + 8); - zip_entry->mtime = zip_time(p + 10); - zip_entry->crc32 = archive_le32dec(p + 14); - if (zip_entry->zip_flags & ZIP_LENGTH_AT_END) - zip_entry->decdat = p[11]; - else - zip_entry->decdat = p[17]; - zip_entry->compressed_size = archive_le32dec(p + 18); - zip_entry->uncompressed_size = archive_le32dec(p + 22); - filename_length = archive_le16dec(p + 26); - extra_length = archive_le16dec(p + 28); - - __archive_read_consume(a, 30); - - /* Read the filename. */ - if ((h = __archive_read_ahead(a, filename_length, NULL)) == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated ZIP file header"); - return (ARCHIVE_FATAL); - } - if (zip_entry->zip_flags & ZIP_UTF8_NAME) { - /* The filename is stored to be UTF-8. */ - if (zip->sconv_utf8 == NULL) { - zip->sconv_utf8 = - archive_string_conversion_from_charset( - &a->archive, "UTF-8", 1); - if (zip->sconv_utf8 == NULL) - return (ARCHIVE_FATAL); - } - sconv = zip->sconv_utf8; - } else if (zip->sconv != NULL) - sconv = zip->sconv; - else - sconv = zip->sconv_default; - - if (archive_entry_copy_pathname_l(entry, - h, filename_length, sconv) != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Pathname"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Pathname cannot be converted " - "from %s to current locale.", - archive_string_conversion_charset_name(sconv)); - ret = ARCHIVE_WARN; - } - __archive_read_consume(a, filename_length); - - /* Read the extra data. */ - if ((h = __archive_read_ahead(a, extra_length, NULL)) == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated ZIP file header"); - return (ARCHIVE_FATAL); - } - - if (ARCHIVE_OK != process_extra(a, entry, h, extra_length, - zip_entry)) { - return ARCHIVE_FATAL; - } - __archive_read_consume(a, extra_length); - - /* Work around a bug in Info-Zip: When reading from a pipe, it - * stats the pipe instead of synthesizing a file entry. */ - if ((zip_entry->mode & AE_IFMT) == AE_IFIFO) { - zip_entry->mode &= ~ AE_IFMT; - zip_entry->mode |= AE_IFREG; - } - - /* If the mode is totally empty, set some sane default. */ - if (zip_entry->mode == 0) { - zip_entry->mode |= 0664; - } - - /* Windows archivers sometimes use backslash as the directory - * separator. Normalize to slash. */ - if (zip_entry->system == 0 && - (wp = archive_entry_pathname_w(entry)) != NULL) { - if (wcschr(wp, L'/') == NULL && wcschr(wp, L'\\') != NULL) { - size_t i; - struct archive_wstring s; - archive_string_init(&s); - archive_wstrcpy(&s, wp); - for (i = 0; i < archive_strlen(&s); i++) { - if (s.s[i] == '\\') - s.s[i] = '/'; - } - archive_entry_copy_pathname_w(entry, s.s); - archive_wstring_free(&s); - } - } - - /* Make sure that entries with a trailing '/' are marked as directories - * even if the External File Attributes contains bogus values. If this - * is not a directory and there is no type, assume a regular file. */ - if ((zip_entry->mode & AE_IFMT) != AE_IFDIR) { - int has_slash; - - wp = archive_entry_pathname_w(entry); - if (wp != NULL) { - len = wcslen(wp); - has_slash = len > 0 && wp[len - 1] == L'/'; - } else { - cp = archive_entry_pathname(entry); - len = (cp != NULL)?strlen(cp):0; - has_slash = len > 0 && cp[len - 1] == '/'; - } - /* Correct file type as needed. */ - if (has_slash) { - zip_entry->mode &= ~AE_IFMT; - zip_entry->mode |= AE_IFDIR; - zip_entry->mode |= 0111; - } else if ((zip_entry->mode & AE_IFMT) == 0) { - zip_entry->mode |= AE_IFREG; - } - } - - /* Make sure directories end in '/' */ - if ((zip_entry->mode & AE_IFMT) == AE_IFDIR) { - wp = archive_entry_pathname_w(entry); - if (wp != NULL) { - len = wcslen(wp); - if (len > 0 && wp[len - 1] != L'/') { - struct archive_wstring s; - archive_string_init(&s); - archive_wstrcat(&s, wp); - archive_wstrappend_wchar(&s, L'/'); - archive_entry_copy_pathname_w(entry, s.s); - archive_wstring_free(&s); - } - } else { - cp = archive_entry_pathname(entry); - len = (cp != NULL)?strlen(cp):0; - if (len > 0 && cp[len - 1] != '/') { - struct archive_string s; - archive_string_init(&s); - archive_strcat(&s, cp); - archive_strappend_char(&s, '/'); - archive_entry_set_pathname(entry, s.s); - archive_string_free(&s); - } - } - } - - if (zip_entry->flags & LA_FROM_CENTRAL_DIRECTORY) { - /* If this came from the central dir, its size info - * is definitive, so ignore the length-at-end flag. */ - zip_entry->zip_flags &= ~ZIP_LENGTH_AT_END; - /* If local header is missing a value, use the one from - the central directory. If both have it, warn about - mismatches. */ - if (zip_entry->crc32 == 0) { - zip_entry->crc32 = zip_entry_central_dir.crc32; - } else if (!zip->ignore_crc32 - && zip_entry->crc32 != zip_entry_central_dir.crc32) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Inconsistent CRC32 values"); - ret = ARCHIVE_WARN; - } - if (zip_entry->compressed_size == 0) { - zip_entry->compressed_size - = zip_entry_central_dir.compressed_size; - } else if (zip_entry->compressed_size - != zip_entry_central_dir.compressed_size) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Inconsistent compressed size: " - "%jd in central directory, %jd in local header", - (intmax_t)zip_entry_central_dir.compressed_size, - (intmax_t)zip_entry->compressed_size); - ret = ARCHIVE_WARN; - } - if (zip_entry->uncompressed_size == 0 || - zip_entry->uncompressed_size == 0xffffffff) { - zip_entry->uncompressed_size - = zip_entry_central_dir.uncompressed_size; - } else if (zip_entry->uncompressed_size - != zip_entry_central_dir.uncompressed_size) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Inconsistent uncompressed size: " - "%jd in central directory, %jd in local header", - (intmax_t)zip_entry_central_dir.uncompressed_size, - (intmax_t)zip_entry->uncompressed_size); - ret = ARCHIVE_WARN; - } - } - - /* Populate some additional entry fields: */ - archive_entry_set_mode(entry, zip_entry->mode); - archive_entry_set_uid(entry, zip_entry->uid); - archive_entry_set_gid(entry, zip_entry->gid); - archive_entry_set_mtime(entry, zip_entry->mtime, 0); - archive_entry_set_ctime(entry, zip_entry->ctime, 0); - archive_entry_set_atime(entry, zip_entry->atime, 0); - - if ((zip->entry->mode & AE_IFMT) == AE_IFLNK) { - size_t linkname_length; - - if (zip_entry->compressed_size > 64 * 1024) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Zip file with oversized link entry"); - return ARCHIVE_FATAL; - } - - linkname_length = (size_t)zip_entry->compressed_size; - - archive_entry_set_size(entry, 0); - - // take into account link compression if any - size_t linkname_full_length = linkname_length; - if (zip->entry->compression != 0) - { - // symlink target string appeared to be compressed - int status = ARCHIVE_FATAL; - const void *uncompressed_buffer = NULL; - - switch (zip->entry->compression) - { -#if HAVE_ZLIB_H - case 8: /* Deflate compression. */ - zip->entry_bytes_remaining = zip_entry->compressed_size; - status = zip_read_data_deflate(a, &uncompressed_buffer, - &linkname_full_length, NULL); - break; -#endif -#if HAVE_LZMA_H && HAVE_LIBLZMA - case 14: /* ZIPx LZMA compression. */ - /*(see zip file format specification, section 4.4.5)*/ - zip->entry_bytes_remaining = zip_entry->compressed_size; - status = zip_read_data_zipx_lzma_alone(a, &uncompressed_buffer, - &linkname_full_length, NULL); - break; -#endif - default: /* Unsupported compression. */ - break; - } - if (status == ARCHIVE_OK) - { - p = uncompressed_buffer; - } - else - { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Unsupported ZIP compression method " - "during decompression of link entry (%d: %s)", - zip->entry->compression, - compression_name(zip->entry->compression)); - return ARCHIVE_FAILED; - } - } - else - { - p = __archive_read_ahead(a, linkname_length, NULL); - } - - if (p == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Truncated Zip file"); - return ARCHIVE_FATAL; - } - - sconv = zip->sconv; - if (sconv == NULL && (zip->entry->zip_flags & ZIP_UTF8_NAME)) - sconv = zip->sconv_utf8; - if (sconv == NULL) - sconv = zip->sconv_default; - if (archive_entry_copy_symlink_l(entry, p, linkname_full_length, - sconv) != 0) { - if (errno != ENOMEM && sconv == zip->sconv_utf8 && - (zip->entry->zip_flags & ZIP_UTF8_NAME)) - archive_entry_copy_symlink_l(entry, p, - linkname_full_length, NULL); - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Symlink"); - return (ARCHIVE_FATAL); - } - /* - * Since there is no character-set regulation for - * symlink name, do not report the conversion error - * in an automatic conversion. - */ - if (sconv != zip->sconv_utf8 || - (zip->entry->zip_flags & ZIP_UTF8_NAME) == 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Symlink cannot be converted " - "from %s to current locale.", - archive_string_conversion_charset_name( - sconv)); - ret = ARCHIVE_WARN; - } - } - zip_entry->uncompressed_size = zip_entry->compressed_size = 0; - - if (__archive_read_consume(a, linkname_length) < 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Read error skipping symlink target name"); - return ARCHIVE_FATAL; - } - } else if (0 == (zip_entry->zip_flags & ZIP_LENGTH_AT_END) - || zip_entry->uncompressed_size > 0) { - /* Set the size only if it's meaningful. */ - archive_entry_set_size(entry, zip_entry->uncompressed_size); - } - zip->entry_bytes_remaining = zip_entry->compressed_size; - - /* If there's no body, force read_data() to return EOF immediately. */ - if (0 == (zip_entry->zip_flags & ZIP_LENGTH_AT_END) - && zip->entry_bytes_remaining < 1) - zip->end_of_entry = 1; - - /* Set up a more descriptive format name. */ - archive_string_empty(&zip->format_name); - archive_string_sprintf(&zip->format_name, "ZIP %d.%d (%s)", - version / 10, version % 10, - compression_name(zip->entry->compression)); - a->archive.archive_format_name = zip->format_name.s; - - return (ret); -} - -static int -check_authentication_code(struct archive_read *a, const void *_p) -{ - struct zip *zip = (struct zip *)(a->format->data); - - /* Check authentication code. */ - if (zip->hctx_valid) { - const void *p; - uint8_t hmac[20]; - size_t hmac_len = 20; - int cmp; - - archive_hmac_sha1_final(&zip->hctx, hmac, &hmac_len); - if (_p == NULL) { - /* Read authentication code. */ - p = __archive_read_ahead(a, AUTH_CODE_SIZE, NULL); - if (p == NULL) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated ZIP file data"); - return (ARCHIVE_FATAL); - } - } else { - p = _p; - } - cmp = memcmp(hmac, p, AUTH_CODE_SIZE); - __archive_read_consume(a, AUTH_CODE_SIZE); - if (cmp != 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "ZIP bad Authentication code"); - return (ARCHIVE_WARN); - } - } - return (ARCHIVE_OK); -} - -/* - * Read "uncompressed" data. There are three cases: - * 1) We know the size of the data. This is always true for the - * seeking reader (we've examined the Central Directory already). - * 2) ZIP_LENGTH_AT_END was set, but only the CRC was deferred. - * Info-ZIP seems to do this; we know the size but have to grab - * the CRC from the data descriptor afterwards. - * 3) We're streaming and ZIP_LENGTH_AT_END was specified and - * we have no size information. In this case, we can do pretty - * well by watching for the data descriptor record. The data - * descriptor is 16 bytes and includes a computed CRC that should - * provide a strong check. - * - * TODO: Technically, the PK\007\010 signature is optional. - * In the original spec, the data descriptor contained CRC - * and size fields but had no leading signature. In practice, - * newer writers seem to provide the signature pretty consistently. - * - * For uncompressed data, the PK\007\010 marker seems essential - * to be sure we've actually seen the end of the entry. - * - * Returns ARCHIVE_OK if successful, ARCHIVE_FATAL otherwise, sets - * zip->end_of_entry if it consumes all of the data. - */ -static int -zip_read_data_none(struct archive_read *a, const void **_buff, - size_t *size, int64_t *offset) -{ - struct zip *zip; - const char *buff; - ssize_t bytes_avail; - int r; - - (void)offset; /* UNUSED */ - - zip = (struct zip *)(a->format->data); - - if (zip->entry->zip_flags & ZIP_LENGTH_AT_END) { - const char *p; - ssize_t grabbing_bytes = 24; - - if (zip->hctx_valid) - grabbing_bytes += AUTH_CODE_SIZE; - /* Grab at least 24 bytes. */ - buff = __archive_read_ahead(a, grabbing_bytes, &bytes_avail); - if (bytes_avail < grabbing_bytes) { - /* Zip archives have end-of-archive markers - that are longer than this, so a failure to get at - least 24 bytes really does indicate a truncated - file. */ - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated ZIP file data"); - return (ARCHIVE_FATAL); - } - /* Check for a complete PK\007\010 signature, followed - * by the correct 4-byte CRC. */ - p = buff; - if (zip->hctx_valid) - p += AUTH_CODE_SIZE; - if (p[0] == 'P' && p[1] == 'K' - && p[2] == '\007' && p[3] == '\010' - && (archive_le32dec(p + 4) == zip->entry_crc32 - || zip->ignore_crc32 - || (zip->hctx_valid - && zip->entry->aes_extra.vendor == AES_VENDOR_AE_2))) { - if (zip->entry->flags & LA_USED_ZIP64) { - uint64_t compressed, uncompressed; - zip->entry->crc32 = archive_le32dec(p + 4); - compressed = archive_le64dec(p + 8); - uncompressed = archive_le64dec(p + 16); - if (compressed > INT64_MAX || uncompressed > - INT64_MAX) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Overflow of 64-bit file sizes"); - return ARCHIVE_FAILED; - } - zip->entry->compressed_size = compressed; - zip->entry->uncompressed_size = uncompressed; - zip->unconsumed = 24; - } else { - zip->entry->crc32 = archive_le32dec(p + 4); - zip->entry->compressed_size = - archive_le32dec(p + 8); - zip->entry->uncompressed_size = - archive_le32dec(p + 12); - zip->unconsumed = 16; - } - if (zip->hctx_valid) { - r = check_authentication_code(a, buff); - if (r != ARCHIVE_OK) - return (r); - } - zip->end_of_entry = 1; - return (ARCHIVE_OK); - } - /* If not at EOF, ensure we consume at least one byte. */ - ++p; - - /* Scan forward until we see where a PK\007\010 signature - * might be. */ - /* Return bytes up until that point. On the next call, - * the code above will verify the data descriptor. */ - while (p < buff + bytes_avail - 4) { - if (p[3] == 'P') { p += 3; } - else if (p[3] == 'K') { p += 2; } - else if (p[3] == '\007') { p += 1; } - else if (p[3] == '\010' && p[2] == '\007' - && p[1] == 'K' && p[0] == 'P') { - if (zip->hctx_valid) - p -= AUTH_CODE_SIZE; - break; - } else { p += 4; } - } - bytes_avail = p - buff; - } else { - if (zip->entry_bytes_remaining == 0) { - zip->end_of_entry = 1; - if (zip->hctx_valid) { - r = check_authentication_code(a, NULL); - if (r != ARCHIVE_OK) - return (r); - } - return (ARCHIVE_OK); - } - /* Grab a bunch of bytes. */ - buff = __archive_read_ahead(a, 1, &bytes_avail); - if (bytes_avail <= 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated ZIP file data"); - return (ARCHIVE_FATAL); - } - if (bytes_avail > zip->entry_bytes_remaining) - bytes_avail = (ssize_t)zip->entry_bytes_remaining; - } - if (zip->tctx_valid || zip->cctx_valid) { - size_t dec_size = bytes_avail; - - if (dec_size > zip->decrypted_buffer_size) - dec_size = zip->decrypted_buffer_size; - if (zip->tctx_valid) { - trad_enc_decrypt_update(&zip->tctx, - (const uint8_t *)buff, dec_size, - zip->decrypted_buffer, dec_size); - } else { - size_t dsize = dec_size; - archive_hmac_sha1_update(&zip->hctx, - (const uint8_t *)buff, dec_size); - archive_decrypto_aes_ctr_update(&zip->cctx, - (const uint8_t *)buff, dec_size, - zip->decrypted_buffer, &dsize); - } - bytes_avail = dec_size; - buff = (const char *)zip->decrypted_buffer; - } - *size = bytes_avail; - zip->entry_bytes_remaining -= bytes_avail; - zip->entry_uncompressed_bytes_read += bytes_avail; - zip->entry_compressed_bytes_read += bytes_avail; - zip->unconsumed += bytes_avail; - *_buff = buff; - return (ARCHIVE_OK); -} - -static int -consume_optional_marker(struct archive_read *a, struct zip *zip) -{ - if (zip->end_of_entry && (zip->entry->zip_flags & ZIP_LENGTH_AT_END)) { - const char *p; - - if (NULL == (p = __archive_read_ahead(a, 24, NULL))) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated ZIP end-of-file record"); - return (ARCHIVE_FATAL); - } - /* Consume the optional PK\007\010 marker. */ - if (p[0] == 'P' && p[1] == 'K' && - p[2] == '\007' && p[3] == '\010') { - p += 4; - zip->unconsumed = 4; - } - if (zip->entry->flags & LA_USED_ZIP64) { - uint64_t compressed, uncompressed; - zip->entry->crc32 = archive_le32dec(p); - compressed = archive_le64dec(p + 4); - uncompressed = archive_le64dec(p + 12); - if (compressed > INT64_MAX || - uncompressed > INT64_MAX) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Overflow of 64-bit file sizes"); - return ARCHIVE_FAILED; - } - zip->entry->compressed_size = compressed; - zip->entry->uncompressed_size = uncompressed; - zip->unconsumed += 20; - } else { - zip->entry->crc32 = archive_le32dec(p); - zip->entry->compressed_size = archive_le32dec(p + 4); - zip->entry->uncompressed_size = archive_le32dec(p + 8); - zip->unconsumed += 12; - } - } - - return (ARCHIVE_OK); -} - -#if HAVE_LZMA_H && HAVE_LIBLZMA -static int -zipx_xz_init(struct archive_read *a, struct zip *zip) -{ - lzma_ret r; - - if(zip->zipx_lzma_valid) { - lzma_end(&zip->zipx_lzma_stream); - zip->zipx_lzma_valid = 0; - } - - memset(&zip->zipx_lzma_stream, 0, sizeof(zip->zipx_lzma_stream)); - r = lzma_stream_decoder(&zip->zipx_lzma_stream, UINT64_MAX, 0); - if (r != LZMA_OK) { - archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC, - "xz initialization failed(%d)", - r); - - return (ARCHIVE_FAILED); - } - - zip->zipx_lzma_valid = 1; - - free(zip->uncompressed_buffer); - - zip->uncompressed_buffer_size = 256 * 1024; - zip->uncompressed_buffer = - (uint8_t*) malloc(zip->uncompressed_buffer_size); - if (zip->uncompressed_buffer == NULL) { - archive_set_error(&a->archive, ENOMEM, - "No memory for xz decompression"); - return (ARCHIVE_FATAL); - } - - zip->decompress_init = 1; - return (ARCHIVE_OK); -} - -static int -zipx_lzma_alone_init(struct archive_read *a, struct zip *zip) -{ - lzma_ret r; - const uint8_t* p; - -#pragma pack(push) -#pragma pack(1) - struct _alone_header { - uint8_t bytes[5]; - uint64_t uncompressed_size; - } alone_header; -#pragma pack(pop) - - if(zip->zipx_lzma_valid) { - lzma_end(&zip->zipx_lzma_stream); - zip->zipx_lzma_valid = 0; - } - - /* To unpack ZIPX's "LZMA" (id 14) stream we can use standard liblzma - * that is a part of XZ Utils. The stream format stored inside ZIPX - * file is a modified "lzma alone" file format, that was used by the - * `lzma` utility which was later deprecated in favour of `xz` utility. - * Since those formats are nearly the same, we can use a standard - * "lzma alone" decoder from XZ Utils. */ - - memset(&zip->zipx_lzma_stream, 0, sizeof(zip->zipx_lzma_stream)); - r = lzma_alone_decoder(&zip->zipx_lzma_stream, UINT64_MAX); - if (r != LZMA_OK) { - archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC, - "lzma initialization failed(%d)", r); - - return (ARCHIVE_FAILED); - } - - /* Flag the cleanup function that we want our lzma-related structures - * to be freed later. */ - zip->zipx_lzma_valid = 1; - - /* The "lzma alone" file format and the stream format inside ZIPx are - * almost the same. Here's an example of a structure of "lzma alone" - * format: - * - * $ cat /bin/ls | lzma | xxd | head -n 1 - * 00000000: 5d00 0080 00ff ffff ffff ffff ff00 2814 - * - * 5 bytes 8 bytes n bytes - * - * - * lzma_params is a 5-byte blob that has to be decoded to extract - * parameters of this LZMA stream. The uncompressed_size field is an - * uint64_t value that contains information about the size of the - * uncompressed file, or UINT64_MAX if this value is unknown. - * The part is the actual lzma-compressed data stream. - * - * Now here's the structure of the stream inside the ZIPX file: - * - * $ cat stream_inside_zipx | xxd | head -n 1 - * 00000000: 0914 0500 5d00 8000 0000 2814 .... .... - * - * 2byte 2byte 5 bytes n bytes - * - * - * This means that the ZIPX file contains an additional magic1 and - * magic2 headers, the lzma_params field contains the same parameter - * set as in the "lzma alone" format, and the field is the - * same as in the "lzma alone" format as well. Note that also the zipx - * format is missing the uncompressed_size field. - * - * So, in order to use the "lzma alone" decoder for the zipx lzma - * stream, we simply need to shuffle around some fields, prepare a new - * lzma alone header, feed it into lzma alone decoder so it will - * initialize itself properly, and then we can start feeding normal - * zipx lzma stream into the decoder. - */ - - /* Read magic1,magic2,lzma_params from the ZIPX stream. */ - if(zip->entry_bytes_remaining < 9 || (p = __archive_read_ahead(a, 9, NULL)) == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated lzma data"); - return (ARCHIVE_FATAL); - } - - if(p[2] != 0x05 || p[3] != 0x00) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid lzma data"); - return (ARCHIVE_FATAL); - } - - /* Prepare an lzma alone header: copy the lzma_params blob into - * a proper place into the lzma alone header. */ - memcpy(&alone_header.bytes[0], p + 4, 5); - - /* Initialize the 'uncompressed size' field to unknown; we'll manually - * monitor how many bytes there are still to be uncompressed. */ - alone_header.uncompressed_size = UINT64_MAX; - - if(!zip->uncompressed_buffer) { - zip->uncompressed_buffer_size = 256 * 1024; - zip->uncompressed_buffer = - (uint8_t*) malloc(zip->uncompressed_buffer_size); - - if (zip->uncompressed_buffer == NULL) { - archive_set_error(&a->archive, ENOMEM, - "No memory for lzma decompression"); - return (ARCHIVE_FATAL); - } - } - - zip->zipx_lzma_stream.next_in = (void*) &alone_header; - zip->zipx_lzma_stream.avail_in = sizeof(alone_header); - zip->zipx_lzma_stream.total_in = 0; - zip->zipx_lzma_stream.next_out = zip->uncompressed_buffer; - zip->zipx_lzma_stream.avail_out = zip->uncompressed_buffer_size; - zip->zipx_lzma_stream.total_out = 0; - - /* Feed only the header into the lzma alone decoder. This will - * effectively initialize the decoder, and will not produce any - * output bytes yet. */ - r = lzma_code(&zip->zipx_lzma_stream, LZMA_RUN); - if (r != LZMA_OK) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, - "lzma stream initialization error"); - return ARCHIVE_FATAL; - } - - /* We've already consumed some bytes, so take this into account. */ - __archive_read_consume(a, 9); - zip->entry_bytes_remaining -= 9; - zip->entry_compressed_bytes_read += 9; - - zip->decompress_init = 1; - return (ARCHIVE_OK); -} - -static int -zip_read_data_zipx_xz(struct archive_read *a, const void **buff, - size_t *size, int64_t *offset) -{ - struct zip* zip = (struct zip *)(a->format->data); - int ret; - lzma_ret lz_ret; - const void* compressed_buf; - ssize_t bytes_avail, in_bytes, to_consume = 0; - - (void) offset; /* UNUSED */ - - /* Initialize decompressor if not yet initialized. */ - if (!zip->decompress_init) { - ret = zipx_xz_init(a, zip); - if (ret != ARCHIVE_OK) - return (ret); - } - - compressed_buf = __archive_read_ahead(a, 1, &bytes_avail); - if (bytes_avail < 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated xz file body"); - return (ARCHIVE_FATAL); - } - - in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail); - zip->zipx_lzma_stream.next_in = compressed_buf; - zip->zipx_lzma_stream.avail_in = in_bytes; - zip->zipx_lzma_stream.total_in = 0; - zip->zipx_lzma_stream.next_out = zip->uncompressed_buffer; - zip->zipx_lzma_stream.avail_out = zip->uncompressed_buffer_size; - zip->zipx_lzma_stream.total_out = 0; - - /* Perform the decompression. */ - lz_ret = lzma_code(&zip->zipx_lzma_stream, LZMA_RUN); - switch(lz_ret) { - case LZMA_DATA_ERROR: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "xz data error (error %d)", (int) lz_ret); - return (ARCHIVE_FATAL); - - case LZMA_NO_CHECK: - case LZMA_OK: - break; - - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "xz unknown error %d", (int) lz_ret); - return (ARCHIVE_FATAL); - - case LZMA_STREAM_END: - lzma_end(&zip->zipx_lzma_stream); - zip->zipx_lzma_valid = 0; - - if((int64_t) zip->zipx_lzma_stream.total_in != - zip->entry_bytes_remaining) - { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xz premature end of stream"); - return (ARCHIVE_FATAL); - } - - zip->end_of_entry = 1; - break; - } - - to_consume = zip->zipx_lzma_stream.total_in; - - __archive_read_consume(a, to_consume); - zip->entry_bytes_remaining -= to_consume; - zip->entry_compressed_bytes_read += to_consume; - zip->entry_uncompressed_bytes_read += zip->zipx_lzma_stream.total_out; - - *size = zip->zipx_lzma_stream.total_out; - *buff = zip->uncompressed_buffer; - - ret = consume_optional_marker(a, zip); - if (ret != ARCHIVE_OK) - return (ret); - - return (ARCHIVE_OK); -} - -static int -zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff, - size_t *size, int64_t *offset) -{ - struct zip* zip = (struct zip *)(a->format->data); - int ret; - lzma_ret lz_ret; - const void* compressed_buf; - ssize_t bytes_avail, in_bytes, to_consume; - - (void) offset; /* UNUSED */ - - /* Initialize decompressor if not yet initialized. */ - if (!zip->decompress_init) { - ret = zipx_lzma_alone_init(a, zip); - if (ret != ARCHIVE_OK) - return (ret); - } - - /* Fetch more compressed data. The same note as in deflate handler - * applies here as well: - * - * Note: '1' here is a performance optimization. Recall that the - * decompression layer returns a count of available bytes; asking for - * more than that forces the decompressor to combine reads by copying - * data. - */ - compressed_buf = __archive_read_ahead(a, 1, &bytes_avail); - if (bytes_avail < 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated lzma file body"); - return (ARCHIVE_FATAL); - } - - /* Set decompressor parameters. */ - in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail); - - zip->zipx_lzma_stream.next_in = compressed_buf; - zip->zipx_lzma_stream.avail_in = in_bytes; - zip->zipx_lzma_stream.total_in = 0; - zip->zipx_lzma_stream.next_out = zip->uncompressed_buffer; - zip->zipx_lzma_stream.avail_out = - /* These lzma_alone streams lack end of stream marker, so let's - * make sure the unpacker won't try to unpack more than it's - * supposed to. */ - zipmin((int64_t) zip->uncompressed_buffer_size, - zip->entry->uncompressed_size - - zip->entry_uncompressed_bytes_read); - zip->zipx_lzma_stream.total_out = 0; - - /* Perform the decompression. */ - lz_ret = lzma_code(&zip->zipx_lzma_stream, LZMA_RUN); - switch(lz_ret) { - case LZMA_DATA_ERROR: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "lzma data error (error %d)", (int) lz_ret); - return (ARCHIVE_FATAL); - - /* This case is optional in lzma alone format. It can happen, - * but most of the files don't have it. (GitHub #1257) */ - case LZMA_STREAM_END: - lzma_end(&zip->zipx_lzma_stream); - zip->zipx_lzma_valid = 0; - if((int64_t) zip->zipx_lzma_stream.total_in != - zip->entry_bytes_remaining) - { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "lzma alone premature end of stream"); - return (ARCHIVE_FATAL); - } - - zip->end_of_entry = 1; - break; - - case LZMA_OK: - break; - - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "lzma unknown error %d", (int) lz_ret); - return (ARCHIVE_FATAL); - } - - to_consume = zip->zipx_lzma_stream.total_in; - - /* Update pointers. */ - __archive_read_consume(a, to_consume); - zip->entry_bytes_remaining -= to_consume; - zip->entry_compressed_bytes_read += to_consume; - zip->entry_uncompressed_bytes_read += zip->zipx_lzma_stream.total_out; - - if(zip->entry_bytes_remaining == 0) { - zip->end_of_entry = 1; - } - - /* Return values. */ - *size = zip->zipx_lzma_stream.total_out; - *buff = zip->uncompressed_buffer; - - /* Behave the same way as during deflate decompression. */ - ret = consume_optional_marker(a, zip); - if (ret != ARCHIVE_OK) - return (ret); - - /* Free lzma decoder handle because we'll no longer need it. */ - if(zip->end_of_entry) { - lzma_end(&zip->zipx_lzma_stream); - zip->zipx_lzma_valid = 0; - } - - /* If we're here, then we're good! */ - return (ARCHIVE_OK); -} -#endif /* HAVE_LZMA_H && HAVE_LIBLZMA */ - -static int -zipx_ppmd8_init(struct archive_read *a, struct zip *zip) -{ - const void* p; - uint32_t val; - uint32_t order; - uint32_t mem; - uint32_t restore_method; - - /* Remove previous decompression context if it exists. */ - if(zip->ppmd8_valid) { - __archive_ppmd8_functions.Ppmd8_Free(&zip->ppmd8); - zip->ppmd8_valid = 0; - } - - /* Create a new decompression context. */ - __archive_ppmd8_functions.Ppmd8_Construct(&zip->ppmd8); - zip->ppmd8_stream_failed = 0; - - /* Setup function pointers required by Ppmd8 decompressor. The - * 'ppmd_read' function will feed new bytes to the decompressor, - * and will increment the 'zip->zipx_ppmd_read_compressed' counter. */ - zip->ppmd8.Stream.In = &zip->zipx_ppmd_stream; - zip->zipx_ppmd_stream.a = a; - zip->zipx_ppmd_stream.Read = &ppmd_read; - - /* Reset number of read bytes to 0. */ - zip->zipx_ppmd_read_compressed = 0; - - /* Read Ppmd8 header (2 bytes). */ - p = __archive_read_ahead(a, 2, NULL); - if(!p) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated file data in PPMd8 stream"); - return (ARCHIVE_FATAL); - } - __archive_read_consume(a, 2); - - /* Decode the stream's compression parameters. */ - val = archive_le16dec(p); - order = (val & 15) + 1; - mem = ((val >> 4) & 0xff) + 1; - restore_method = (val >> 12); - - if(order < 2 || restore_method > 2) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Invalid parameter set in PPMd8 stream (order=%" PRId32 ", " - "restore=%" PRId32 ")", order, restore_method); - return (ARCHIVE_FAILED); - } - - /* Allocate the memory needed to properly decompress the file. */ - if(!__archive_ppmd8_functions.Ppmd8_Alloc(&zip->ppmd8, mem << 20)) { - archive_set_error(&a->archive, ENOMEM, - "Unable to allocate memory for PPMd8 stream: %" PRId32 " bytes", - mem << 20); - return (ARCHIVE_FATAL); - } - - /* Signal the cleanup function to release Ppmd8 context in the - * cleanup phase. */ - zip->ppmd8_valid = 1; - - /* Perform further Ppmd8 initialization. */ - if(!__archive_ppmd8_functions.Ppmd8_RangeDec_Init(&zip->ppmd8)) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, - "PPMd8 stream range decoder initialization error"); - return (ARCHIVE_FATAL); - } - - __archive_ppmd8_functions.Ppmd8_Init(&zip->ppmd8, order, - restore_method); - - /* Allocate the buffer that will hold uncompressed data. */ - free(zip->uncompressed_buffer); - - zip->uncompressed_buffer_size = 256 * 1024; - zip->uncompressed_buffer = - (uint8_t*) malloc(zip->uncompressed_buffer_size); - - if(zip->uncompressed_buffer == NULL) { - archive_set_error(&a->archive, ENOMEM, - "No memory for PPMd8 decompression"); - return ARCHIVE_FATAL; - } - - /* Ppmd8 initialization is done. */ - zip->decompress_init = 1; - - /* We've already read 2 bytes in the output stream. Additionally, - * Ppmd8 initialization code could read some data as well. So we - * are advancing the stream by 2 bytes plus whatever number of - * bytes Ppmd8 init function used. */ - zip->entry_compressed_bytes_read += 2 + zip->zipx_ppmd_read_compressed; - - return ARCHIVE_OK; -} - -static int -zip_read_data_zipx_ppmd(struct archive_read *a, const void **buff, - size_t *size, int64_t *offset) -{ - struct zip* zip = (struct zip *)(a->format->data); - int ret; - size_t consumed_bytes = 0; - ssize_t bytes_avail = 0; - - (void) offset; /* UNUSED */ - - /* If we're here for the first time, initialize Ppmd8 decompression - * context first. */ - if(!zip->decompress_init) { - ret = zipx_ppmd8_init(a, zip); - if(ret != ARCHIVE_OK) - return ret; - } - - /* Fetch for more data. We're reading 1 byte here, but libarchive - * should prefetch more bytes. */ - (void) __archive_read_ahead(a, 1, &bytes_avail); - if(bytes_avail < 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated PPMd8 file body"); - return (ARCHIVE_FATAL); - } - - /* This counter will be updated inside ppmd_read(), which at one - * point will be called by Ppmd8_DecodeSymbol. */ - zip->zipx_ppmd_read_compressed = 0; - - /* Decompression loop. */ - do { - int sym = __archive_ppmd8_functions.Ppmd8_DecodeSymbol( - &zip->ppmd8); - if(sym < 0) { - zip->end_of_entry = 1; - break; - } - - /* This field is set by ppmd_read() when there was no more data - * to be read. */ - if(zip->ppmd8_stream_failed) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated PPMd8 file body"); - return (ARCHIVE_FATAL); - } - - zip->uncompressed_buffer[consumed_bytes] = (uint8_t) sym; - ++consumed_bytes; - } while(consumed_bytes < zip->uncompressed_buffer_size); - - /* Update pointers for libarchive. */ - *buff = zip->uncompressed_buffer; - *size = consumed_bytes; - - /* Update pointers so we can continue decompression in another call. */ - zip->entry_bytes_remaining -= zip->zipx_ppmd_read_compressed; - zip->entry_compressed_bytes_read += zip->zipx_ppmd_read_compressed; - zip->entry_uncompressed_bytes_read += consumed_bytes; - - /* If we're at the end of stream, deinitialize Ppmd8 context. */ - if(zip->end_of_entry) { - __archive_ppmd8_functions.Ppmd8_Free(&zip->ppmd8); - zip->ppmd8_valid = 0; - } - - /* Seek for optional marker, same way as in each zip entry. */ - ret = consume_optional_marker(a, zip); - if (ret != ARCHIVE_OK) - return ret; - - return ARCHIVE_OK; -} - -#ifdef HAVE_BZLIB_H -static int -zipx_bzip2_init(struct archive_read *a, struct zip *zip) -{ - int r; - - /* Deallocate already existing BZ2 decompression context if it - * exists. */ - if(zip->bzstream_valid) { - BZ2_bzDecompressEnd(&zip->bzstream); - zip->bzstream_valid = 0; - } - - /* Allocate a new BZ2 decompression context. */ - memset(&zip->bzstream, 0, sizeof(bz_stream)); - r = BZ2_bzDecompressInit(&zip->bzstream, 0, 1); - if(r != BZ_OK) { - archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC, - "bzip2 initialization failed(%d)", - r); - - return ARCHIVE_FAILED; - } - - /* Mark the bzstream field to be released in cleanup phase. */ - zip->bzstream_valid = 1; - - /* (Re)allocate the buffer that will contain decompressed bytes. */ - free(zip->uncompressed_buffer); - - zip->uncompressed_buffer_size = 256 * 1024; - zip->uncompressed_buffer = - (uint8_t*) malloc(zip->uncompressed_buffer_size); - if (zip->uncompressed_buffer == NULL) { - archive_set_error(&a->archive, ENOMEM, - "No memory for bzip2 decompression"); - return ARCHIVE_FATAL; - } - - /* Initialization done. */ - zip->decompress_init = 1; - return ARCHIVE_OK; -} - -static int -zip_read_data_zipx_bzip2(struct archive_read *a, const void **buff, - size_t *size, int64_t *offset) -{ - struct zip *zip = (struct zip *)(a->format->data); - ssize_t bytes_avail = 0, in_bytes, to_consume; - const void *compressed_buff; - int r; - uint64_t total_out; - - (void) offset; /* UNUSED */ - - /* Initialize decompression context if we're here for the first time. */ - if(!zip->decompress_init) { - r = zipx_bzip2_init(a, zip); - if(r != ARCHIVE_OK) - return r; - } - - /* Fetch more compressed bytes. */ - compressed_buff = __archive_read_ahead(a, 1, &bytes_avail); - if(bytes_avail < 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated bzip2 file body"); - return (ARCHIVE_FATAL); - } - - in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail); - if(in_bytes < 1) { - /* libbz2 doesn't complain when caller feeds avail_in == 0. - * It will actually return success in this case, which is - * undesirable. This is why we need to make this check - * manually. */ - - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated bzip2 file body"); - return (ARCHIVE_FATAL); - } - - /* Setup buffer boundaries. */ - zip->bzstream.next_in = (char*)(uintptr_t) compressed_buff; - zip->bzstream.avail_in = (uint32_t)in_bytes; - zip->bzstream.total_in_hi32 = 0; - zip->bzstream.total_in_lo32 = 0; - zip->bzstream.next_out = (char*) zip->uncompressed_buffer; - zip->bzstream.avail_out = (uint32_t)zip->uncompressed_buffer_size; - zip->bzstream.total_out_hi32 = 0; - zip->bzstream.total_out_lo32 = 0; - - /* Perform the decompression. */ - r = BZ2_bzDecompress(&zip->bzstream); - switch(r) { - case BZ_STREAM_END: - /* If we're at the end of the stream, deinitialize the - * decompression context now. */ - switch(BZ2_bzDecompressEnd(&zip->bzstream)) { - case BZ_OK: - break; - default: - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Failed to clean up bzip2 " - "decompressor"); - return ARCHIVE_FATAL; - } - - zip->end_of_entry = 1; - break; - case BZ_OK: - /* The decompressor has successfully decoded this - * chunk of data, but more data is still in queue. */ - break; - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "bzip2 decompression failed"); - return ARCHIVE_FATAL; - } - - /* Update the pointers so decompressor can continue decoding. */ - to_consume = zip->bzstream.total_in_lo32; - __archive_read_consume(a, to_consume); - - total_out = ((uint64_t) zip->bzstream.total_out_hi32 << 32) | - zip->bzstream.total_out_lo32; - - zip->entry_bytes_remaining -= to_consume; - zip->entry_compressed_bytes_read += to_consume; - zip->entry_uncompressed_bytes_read += total_out; - - /* Give libarchive its due. */ - *size = total_out; - *buff = zip->uncompressed_buffer; - - /* Seek for optional marker, like in other entries. */ - r = consume_optional_marker(a, zip); - if(r != ARCHIVE_OK) - return r; - - return ARCHIVE_OK; -} - -#endif - -#if HAVE_ZSTD_H && HAVE_LIBZSTD -static int -zipx_zstd_init(struct archive_read *a, struct zip *zip) -{ - size_t r; - - /* Deallocate already existing Zstd decompression context if it - * exists. */ - if(zip->zstdstream_valid) { - ZSTD_freeDStream(zip->zstdstream); - zip->zstdstream_valid = 0; - } - - /* Allocate a new Zstd decompression context. */ - zip->zstdstream = ZSTD_createDStream(); - - r = ZSTD_initDStream(zip->zstdstream); - if (ZSTD_isError(r)) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Error initializing zstd decompressor: %s", - ZSTD_getErrorName(r)); - - return ARCHIVE_FAILED; - } - - /* Mark the zstdstream field to be released in cleanup phase. */ - zip->zstdstream_valid = 1; - - /* (Re)allocate the buffer that will contain decompressed bytes. */ - free(zip->uncompressed_buffer); - - zip->uncompressed_buffer_size = ZSTD_DStreamOutSize(); - zip->uncompressed_buffer = - (uint8_t*) malloc(zip->uncompressed_buffer_size); - if (zip->uncompressed_buffer == NULL) { - archive_set_error(&a->archive, ENOMEM, - "No memory for Zstd decompression"); - - return ARCHIVE_FATAL; - } - - /* Initialization done. */ - zip->decompress_init = 1; - return ARCHIVE_OK; -} - -static int -zip_read_data_zipx_zstd(struct archive_read *a, const void **buff, - size_t *size, int64_t *offset) -{ - struct zip *zip = (struct zip *)(a->format->data); - ssize_t bytes_avail = 0, in_bytes, to_consume; - const void *compressed_buff; - int r; - size_t ret; - uint64_t total_out; - ZSTD_outBuffer out; - ZSTD_inBuffer in; - - (void) offset; /* UNUSED */ - - /* Initialize decompression context if we're here for the first time. */ - if(!zip->decompress_init) { - r = zipx_zstd_init(a, zip); - if(r != ARCHIVE_OK) - return r; - } - - /* Fetch more compressed bytes */ - compressed_buff = __archive_read_ahead(a, 1, &bytes_avail); - if(bytes_avail < 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated zstd file body"); - return (ARCHIVE_FATAL); - } - - in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail); - if(in_bytes < 1) { - /* zstd doesn't complain when caller feeds avail_in == 0. - * It will actually return success in this case, which is - * undesirable. This is why we need to make this check - * manually. */ - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated zstd file body"); - return (ARCHIVE_FATAL); - } - - /* Setup buffer boundaries */ - in.src = compressed_buff; - in.size = in_bytes; - in.pos = 0; - out = (ZSTD_outBuffer) { zip->uncompressed_buffer, zip->uncompressed_buffer_size, 0 }; - - /* Perform the decompression. */ - ret = ZSTD_decompressStream(zip->zstdstream, &out, &in); - if (ZSTD_isError(ret)) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Error during zstd decompression: %s", - ZSTD_getErrorName(ret)); - return (ARCHIVE_FATAL); - } - - /* Check end of the stream. */ - if (ret == 0) { - if ((in.pos == in.size) && (out.pos < out.size)) { - zip->end_of_entry = 1; - ZSTD_freeDStream(zip->zstdstream); - zip->zstdstream_valid = 0; - } - } - - /* Update the pointers so decompressor can continue decoding. */ - to_consume = in.pos; - __archive_read_consume(a, to_consume); - - total_out = out.pos; - - zip->entry_bytes_remaining -= to_consume; - zip->entry_compressed_bytes_read += to_consume; - zip->entry_uncompressed_bytes_read += total_out; - - /* Give libarchive its due. */ - *size = total_out; - *buff = zip->uncompressed_buffer; - - /* Seek for optional marker, like in other entries. */ - r = consume_optional_marker(a, zip); - if(r != ARCHIVE_OK) - return r; - - return ARCHIVE_OK; -} -#endif - -#ifdef HAVE_ZLIB_H -static int -zip_deflate_init(struct archive_read *a, struct zip *zip) -{ - int r; - - /* If we haven't yet read any data, initialize the decompressor. */ - if (!zip->decompress_init) { - if (zip->stream_valid) - r = inflateReset(&zip->stream); - else - r = inflateInit2(&zip->stream, - -15 /* Don't check for zlib header */); - if (r != Z_OK) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Can't initialize ZIP decompression."); - return (ARCHIVE_FATAL); - } - /* Stream structure has been set up. */ - zip->stream_valid = 1; - /* We've initialized decompression for this stream. */ - zip->decompress_init = 1; - } - return (ARCHIVE_OK); -} - -static int -zip_read_data_deflate(struct archive_read *a, const void **buff, - size_t *size, int64_t *offset) -{ - struct zip *zip; - ssize_t bytes_avail; - const void *compressed_buff, *sp; - int r; - - (void)offset; /* UNUSED */ - - zip = (struct zip *)(a->format->data); - - /* If the buffer hasn't been allocated, allocate it now. */ - if (zip->uncompressed_buffer == NULL) { - zip->uncompressed_buffer_size = 256 * 1024; - zip->uncompressed_buffer - = (unsigned char *)malloc(zip->uncompressed_buffer_size); - if (zip->uncompressed_buffer == NULL) { - archive_set_error(&a->archive, ENOMEM, - "No memory for ZIP decompression"); - return (ARCHIVE_FATAL); - } - } - - r = zip_deflate_init(a, zip); - if (r != ARCHIVE_OK) - return (r); - - /* - * Note: '1' here is a performance optimization. - * Recall that the decompression layer returns a count of - * available bytes; asking for more than that forces the - * decompressor to combine reads by copying data. - */ - compressed_buff = sp = __archive_read_ahead(a, 1, &bytes_avail); - if (0 == (zip->entry->zip_flags & ZIP_LENGTH_AT_END) - && bytes_avail > zip->entry_bytes_remaining) { - bytes_avail = (ssize_t)zip->entry_bytes_remaining; - } - if (bytes_avail < 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated ZIP file body"); - return (ARCHIVE_FATAL); - } - - if (zip->tctx_valid || zip->cctx_valid) { - if (zip->decrypted_bytes_remaining < (size_t)bytes_avail) { - size_t buff_remaining = - (zip->decrypted_buffer + - zip->decrypted_buffer_size) - - (zip->decrypted_ptr + - zip->decrypted_bytes_remaining); - - if (buff_remaining > (size_t)bytes_avail) - buff_remaining = (size_t)bytes_avail; - - if (0 == (zip->entry->zip_flags & ZIP_LENGTH_AT_END) && - zip->entry_bytes_remaining > 0) { - if ((int64_t)(zip->decrypted_bytes_remaining - + buff_remaining) - > zip->entry_bytes_remaining) { - if (zip->entry_bytes_remaining < - (int64_t)zip->decrypted_bytes_remaining) - buff_remaining = 0; - else - buff_remaining = - (size_t)zip->entry_bytes_remaining - - zip->decrypted_bytes_remaining; - } - } - if (buff_remaining > 0) { - if (zip->tctx_valid) { - trad_enc_decrypt_update(&zip->tctx, - compressed_buff, buff_remaining, - zip->decrypted_ptr - + zip->decrypted_bytes_remaining, - buff_remaining); - } else { - size_t dsize = buff_remaining; - archive_decrypto_aes_ctr_update( - &zip->cctx, - compressed_buff, buff_remaining, - zip->decrypted_ptr - + zip->decrypted_bytes_remaining, - &dsize); - } - zip->decrypted_bytes_remaining += - buff_remaining; - } - } - bytes_avail = zip->decrypted_bytes_remaining; - compressed_buff = (const char *)zip->decrypted_ptr; - } - - /* - * A bug in zlib.h: stream.next_in should be marked 'const' - * but isn't (the library never alters data through the - * next_in pointer, only reads it). The result: this ugly - * cast to remove 'const'. - */ - zip->stream.next_in = (Bytef *)(uintptr_t)(const void *)compressed_buff; - zip->stream.avail_in = (uInt)bytes_avail; - zip->stream.total_in = 0; - zip->stream.next_out = zip->uncompressed_buffer; - zip->stream.avail_out = (uInt)zip->uncompressed_buffer_size; - zip->stream.total_out = 0; - - r = inflate(&zip->stream, 0); - switch (r) { - case Z_OK: - break; - case Z_STREAM_END: - zip->end_of_entry = 1; - break; - case Z_MEM_ERROR: - archive_set_error(&a->archive, ENOMEM, - "Out of memory for ZIP decompression"); - return (ARCHIVE_FATAL); - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "ZIP decompression failed (%d)", r); - return (ARCHIVE_FATAL); - } - - /* Consume as much as the compressor actually used. */ - bytes_avail = zip->stream.total_in; - if (zip->tctx_valid || zip->cctx_valid) { - zip->decrypted_bytes_remaining -= bytes_avail; - if (zip->decrypted_bytes_remaining == 0) - zip->decrypted_ptr = zip->decrypted_buffer; - else - zip->decrypted_ptr += bytes_avail; - } - /* Calculate compressed data as much as we used.*/ - if (zip->hctx_valid) - archive_hmac_sha1_update(&zip->hctx, sp, bytes_avail); - __archive_read_consume(a, bytes_avail); - zip->entry_bytes_remaining -= bytes_avail; - zip->entry_compressed_bytes_read += bytes_avail; - - *size = zip->stream.total_out; - zip->entry_uncompressed_bytes_read += zip->stream.total_out; - *buff = zip->uncompressed_buffer; - - if (zip->end_of_entry && zip->hctx_valid) { - r = check_authentication_code(a, NULL); - if (r != ARCHIVE_OK) - return (r); - } - - r = consume_optional_marker(a, zip); - if (r != ARCHIVE_OK) - return (r); - - return (ARCHIVE_OK); -} -#endif - -static int -read_decryption_header(struct archive_read *a) -{ - struct zip *zip = (struct zip *)(a->format->data); - const char *p; - unsigned int remaining_size; - unsigned int ts; - - /* - * Read an initialization vector data field. - */ - p = __archive_read_ahead(a, 2, NULL); - if (p == NULL) - goto truncated; - ts = zip->iv_size; - zip->iv_size = archive_le16dec(p); - __archive_read_consume(a, 2); - if (ts < zip->iv_size) { - free(zip->iv); - zip->iv = NULL; - } - p = __archive_read_ahead(a, zip->iv_size, NULL); - if (p == NULL) - goto truncated; - if (zip->iv == NULL) { - zip->iv = malloc(zip->iv_size); - if (zip->iv == NULL) - goto nomem; - } - memcpy(zip->iv, p, zip->iv_size); - __archive_read_consume(a, zip->iv_size); - - /* - * Read a size of remaining decryption header field. - */ - p = __archive_read_ahead(a, 14, NULL); - if (p == NULL) - goto truncated; - remaining_size = archive_le32dec(p); - if (remaining_size < 16 || remaining_size > (1 << 18)) - goto corrupted; - - /* Check if format version is supported. */ - if (archive_le16dec(p+4) != 3) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Unsupported encryption format version: %u", - archive_le16dec(p+4)); - return (ARCHIVE_FAILED); - } - - /* - * Read an encryption algorithm field. - */ - zip->alg_id = archive_le16dec(p+6); - switch (zip->alg_id) { - case 0x6601:/* DES */ - case 0x6602:/* RC2 */ - case 0x6603:/* 3DES 168 */ - case 0x6609:/* 3DES 112 */ - case 0x660E:/* AES 128 */ - case 0x660F:/* AES 192 */ - case 0x6610:/* AES 256 */ - case 0x6702:/* RC2 (version >= 5.2) */ - case 0x6720:/* Blowfish */ - case 0x6721:/* Twofish */ - case 0x6801:/* RC4 */ - /* Supported encryption algorithm. */ - break; - default: - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Unknown encryption algorithm: %u", zip->alg_id); - return (ARCHIVE_FAILED); - } - - /* - * Read a bit length field. - */ - zip->bit_len = archive_le16dec(p+8); - - /* - * Read a flags field. - */ - zip->flags = archive_le16dec(p+10); - switch (zip->flags & 0xf000) { - case 0x0001: /* Password is required to decrypt. */ - case 0x0002: /* Certificates only. */ - case 0x0003: /* Password or certificate required to decrypt. */ - break; - default: - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Unknown encryption flag: %u", zip->flags); - return (ARCHIVE_FAILED); - } - if ((zip->flags & 0xf000) == 0 || - (zip->flags & 0xf000) == 0x4000) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Unknown encryption flag: %u", zip->flags); - return (ARCHIVE_FAILED); - } - - /* - * Read an encrypted random data field. - */ - ts = zip->erd_size; - zip->erd_size = archive_le16dec(p+12); - __archive_read_consume(a, 14); - if ((zip->erd_size & 0xf) != 0 || - (zip->erd_size + 16) > remaining_size || - (zip->erd_size + 16) < zip->erd_size) - goto corrupted; - - if (ts < zip->erd_size) { - free(zip->erd); - zip->erd = NULL; - } - p = __archive_read_ahead(a, zip->erd_size, NULL); - if (p == NULL) - goto truncated; - if (zip->erd == NULL) { - zip->erd = malloc(zip->erd_size); - if (zip->erd == NULL) - goto nomem; - } - memcpy(zip->erd, p, zip->erd_size); - __archive_read_consume(a, zip->erd_size); - - /* - * Read a reserved data field. - */ - p = __archive_read_ahead(a, 4, NULL); - if (p == NULL) - goto truncated; - /* Reserved data size should be zero. */ - if (archive_le32dec(p) != 0) - goto corrupted; - __archive_read_consume(a, 4); - - /* - * Read a password validation data field. - */ - p = __archive_read_ahead(a, 2, NULL); - if (p == NULL) - goto truncated; - ts = zip->v_size; - zip->v_size = archive_le16dec(p); - __archive_read_consume(a, 2); - if ((zip->v_size & 0x0f) != 0 || - (zip->erd_size + zip->v_size + 16) > remaining_size || - (zip->erd_size + zip->v_size + 16) < (zip->erd_size + zip->v_size)) - goto corrupted; - if (ts < zip->v_size) { - free(zip->v_data); - zip->v_data = NULL; - } - p = __archive_read_ahead(a, zip->v_size, NULL); - if (p == NULL) - goto truncated; - if (zip->v_data == NULL) { - zip->v_data = malloc(zip->v_size); - if (zip->v_data == NULL) - goto nomem; - } - memcpy(zip->v_data, p, zip->v_size); - __archive_read_consume(a, zip->v_size); - - p = __archive_read_ahead(a, 4, NULL); - if (p == NULL) - goto truncated; - zip->v_crc32 = archive_le32dec(p); - __archive_read_consume(a, 4); - - /*return (ARCHIVE_OK); - * This is not fully implemented yet.*/ - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Encrypted file is unsupported"); - return (ARCHIVE_FAILED); -truncated: - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated ZIP file data"); - return (ARCHIVE_FATAL); -corrupted: - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Corrupted ZIP file data"); - return (ARCHIVE_FATAL); -nomem: - archive_set_error(&a->archive, ENOMEM, - "No memory for ZIP decryption"); - return (ARCHIVE_FATAL); -} - -static int -zip_alloc_decryption_buffer(struct archive_read *a) -{ - struct zip *zip = (struct zip *)(a->format->data); - size_t bs = 256 * 1024; - - if (zip->decrypted_buffer == NULL) { - zip->decrypted_buffer_size = bs; - zip->decrypted_buffer = malloc(bs); - if (zip->decrypted_buffer == NULL) { - archive_set_error(&a->archive, ENOMEM, - "No memory for ZIP decryption"); - return (ARCHIVE_FATAL); - } - } - zip->decrypted_ptr = zip->decrypted_buffer; - return (ARCHIVE_OK); -} - -static int -init_traditional_PKWARE_decryption(struct archive_read *a) -{ - struct zip *zip = (struct zip *)(a->format->data); - const void *p; - int retry; - int r; - - if (zip->tctx_valid) - return (ARCHIVE_OK); - - /* - Read the 12 bytes encryption header stored at - the start of the data area. - */ -#define ENC_HEADER_SIZE 12 - if (0 == (zip->entry->zip_flags & ZIP_LENGTH_AT_END) - && zip->entry_bytes_remaining < ENC_HEADER_SIZE) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated Zip encrypted body: only %jd bytes available", - (intmax_t)zip->entry_bytes_remaining); - return (ARCHIVE_FATAL); - } - - p = __archive_read_ahead(a, ENC_HEADER_SIZE, NULL); - if (p == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated ZIP file data"); - return (ARCHIVE_FATAL); - } - - for (retry = 0;; retry++) { - const char *passphrase; - uint8_t crcchk; - - passphrase = __archive_read_next_passphrase(a); - if (passphrase == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - (retry > 0)? - "Incorrect passphrase": - "Passphrase required for this entry"); - return (ARCHIVE_FAILED); - } - - /* - * Initialize ctx for Traditional PKWARE Decryption. - */ - r = trad_enc_init(&zip->tctx, passphrase, strlen(passphrase), - p, ENC_HEADER_SIZE, &crcchk); - if (r == 0 && crcchk == zip->entry->decdat) - break;/* The passphrase is OK. */ - if (retry > 10000) { - /* Avoid infinity loop. */ - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Too many incorrect passphrases"); - return (ARCHIVE_FAILED); - } - } - - __archive_read_consume(a, ENC_HEADER_SIZE); - zip->tctx_valid = 1; - if (0 == (zip->entry->zip_flags & ZIP_LENGTH_AT_END)) { - zip->entry_bytes_remaining -= ENC_HEADER_SIZE; - } - /*zip->entry_uncompressed_bytes_read += ENC_HEADER_SIZE;*/ - zip->entry_compressed_bytes_read += ENC_HEADER_SIZE; - zip->decrypted_bytes_remaining = 0; - - return (zip_alloc_decryption_buffer(a)); -#undef ENC_HEADER_SIZE -} - -static int -init_WinZip_AES_decryption(struct archive_read *a) -{ - struct zip *zip = (struct zip *)(a->format->data); - const void *p; - const uint8_t *pv; - size_t key_len, salt_len; - uint8_t derived_key[MAX_DERIVED_KEY_BUF_SIZE]; - int retry; - int r; - - if (zip->cctx_valid || zip->hctx_valid) - return (ARCHIVE_OK); - - switch (zip->entry->aes_extra.strength) { - case 1: salt_len = 8; key_len = 16; break; - case 2: salt_len = 12; key_len = 24; break; - case 3: salt_len = 16; key_len = 32; break; - default: goto corrupted; - } - p = __archive_read_ahead(a, salt_len + 2, NULL); - if (p == NULL) - goto truncated; - - for (retry = 0;; retry++) { - const char *passphrase; - - passphrase = __archive_read_next_passphrase(a); - if (passphrase == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - (retry > 0)? - "Incorrect passphrase": - "Passphrase required for this entry"); - return (ARCHIVE_FAILED); - } - memset(derived_key, 0, sizeof(derived_key)); - r = archive_pbkdf2_sha1(passphrase, strlen(passphrase), - p, salt_len, 1000, derived_key, key_len * 2 + 2); - if (r != 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Decryption is unsupported due to lack of " - "crypto library"); - return (ARCHIVE_FAILED); - } - - /* Check password verification value. */ - pv = ((const uint8_t *)p) + salt_len; - if (derived_key[key_len * 2] == pv[0] && - derived_key[key_len * 2 + 1] == pv[1]) - break;/* The passphrase is OK. */ - if (retry > 10000) { - /* Avoid infinity loop. */ - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Too many incorrect passphrases"); - return (ARCHIVE_FAILED); - } - } - - r = archive_decrypto_aes_ctr_init(&zip->cctx, derived_key, key_len); - if (r != 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Decryption is unsupported due to lack of crypto library"); - return (ARCHIVE_FAILED); - } - r = archive_hmac_sha1_init(&zip->hctx, derived_key + key_len, key_len); - if (r != 0) { - archive_decrypto_aes_ctr_release(&zip->cctx); - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Failed to initialize HMAC-SHA1"); - return (ARCHIVE_FAILED); - } - zip->cctx_valid = zip->hctx_valid = 1; - __archive_read_consume(a, salt_len + 2); - zip->entry_bytes_remaining -= salt_len + 2 + AUTH_CODE_SIZE; - if (0 == (zip->entry->zip_flags & ZIP_LENGTH_AT_END) - && zip->entry_bytes_remaining < 0) - goto corrupted; - zip->entry_compressed_bytes_read += salt_len + 2 + AUTH_CODE_SIZE; - zip->decrypted_bytes_remaining = 0; - - zip->entry->compression = zip->entry->aes_extra.compression; - return (zip_alloc_decryption_buffer(a)); - -truncated: - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated ZIP file data"); - return (ARCHIVE_FATAL); -corrupted: - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Corrupted ZIP file data"); - return (ARCHIVE_FATAL); -} - -static int -archive_read_format_zip_read_data(struct archive_read *a, - const void **buff, size_t *size, int64_t *offset) -{ - int r; - struct zip *zip = (struct zip *)(a->format->data); - - if (zip->has_encrypted_entries == - ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) { - zip->has_encrypted_entries = 0; - } - - *offset = zip->entry_uncompressed_bytes_read; - *size = 0; - *buff = NULL; - - /* If we hit end-of-entry last time, return ARCHIVE_EOF. */ - if (zip->end_of_entry) - return (ARCHIVE_EOF); - - /* Return EOF immediately if this is a non-regular file. */ - if (AE_IFREG != (zip->entry->mode & AE_IFMT)) - return (ARCHIVE_EOF); - - __archive_read_consume(a, zip->unconsumed); - zip->unconsumed = 0; - - if (zip->init_decryption) { - zip->has_encrypted_entries = 1; - if (zip->entry->zip_flags & ZIP_STRONG_ENCRYPTED) - r = read_decryption_header(a); - else if (zip->entry->compression == WINZIP_AES_ENCRYPTION) - r = init_WinZip_AES_decryption(a); - else - r = init_traditional_PKWARE_decryption(a); - if (r != ARCHIVE_OK) - return (r); - zip->init_decryption = 0; - } - - switch(zip->entry->compression) { - case 0: /* No compression. */ - r = zip_read_data_none(a, buff, size, offset); - break; -#ifdef HAVE_BZLIB_H - case 12: /* ZIPx bzip2 compression. */ - r = zip_read_data_zipx_bzip2(a, buff, size, offset); - break; -#endif -#if HAVE_LZMA_H && HAVE_LIBLZMA - case 14: /* ZIPx LZMA compression. */ - r = zip_read_data_zipx_lzma_alone(a, buff, size, offset); - break; - case 95: /* ZIPx XZ compression. */ - r = zip_read_data_zipx_xz(a, buff, size, offset); - break; -#endif -#if HAVE_ZSTD_H && HAVE_LIBZSTD - case 93: /* ZIPx Zstd compression. */ - r = zip_read_data_zipx_zstd(a, buff, size, offset); - break; -#endif - /* PPMd support is built-in, so we don't need any #if guards. */ - case 98: /* ZIPx PPMd compression. */ - r = zip_read_data_zipx_ppmd(a, buff, size, offset); - break; - -#ifdef HAVE_ZLIB_H - case 8: /* Deflate compression. */ - r = zip_read_data_deflate(a, buff, size, offset); - break; -#endif - default: /* Unsupported compression. */ - /* Return a warning. */ - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Unsupported ZIP compression method (%d: %s)", - zip->entry->compression, compression_name(zip->entry->compression)); - /* We can't decompress this entry, but we will - * be able to skip() it and try the next entry. */ - return (ARCHIVE_FAILED); - break; - } - if (r != ARCHIVE_OK) - return (r); - /* Update checksum */ - if (*size) - zip->entry_crc32 = zip->crc32func(zip->entry_crc32, *buff, - (unsigned)*size); - /* If we hit the end, swallow any end-of-data marker. */ - if (zip->end_of_entry) { - /* Check file size, CRC against these values. */ - if (zip->entry->compressed_size != - zip->entry_compressed_bytes_read) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "ZIP compressed data is wrong size " - "(read %jd, expected %jd)", - (intmax_t)zip->entry_compressed_bytes_read, - (intmax_t)zip->entry->compressed_size); - return (ARCHIVE_WARN); - } - /* Size field only stores the lower 32 bits of the actual - * size. */ - if ((zip->entry->uncompressed_size & UINT32_MAX) - != (zip->entry_uncompressed_bytes_read & UINT32_MAX)) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "ZIP uncompressed data is wrong size " - "(read %jd, expected %jd)\n", - (intmax_t)zip->entry_uncompressed_bytes_read, - (intmax_t)zip->entry->uncompressed_size); - return (ARCHIVE_WARN); - } - /* Check computed CRC against header */ - if ((!zip->hctx_valid || - zip->entry->aes_extra.vendor != AES_VENDOR_AE_2) && - zip->entry->crc32 != zip->entry_crc32 - && !zip->ignore_crc32) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "ZIP bad CRC: 0x%lx should be 0x%lx", - (unsigned long)zip->entry_crc32, - (unsigned long)zip->entry->crc32); - return (ARCHIVE_WARN); - } - } - - return (ARCHIVE_OK); -} - -static int -archive_read_format_zip_cleanup(struct archive_read *a) -{ - struct zip *zip; - struct zip_entry *zip_entry, *next_zip_entry; - - zip = (struct zip *)(a->format->data); - -#ifdef HAVE_ZLIB_H - if (zip->stream_valid) - inflateEnd(&zip->stream); -#endif - -#if HAVE_LZMA_H && HAVE_LIBLZMA - if (zip->zipx_lzma_valid) { - lzma_end(&zip->zipx_lzma_stream); - } -#endif - -#ifdef HAVE_BZLIB_H - if (zip->bzstream_valid) { - BZ2_bzDecompressEnd(&zip->bzstream); - } -#endif - -#if HAVE_ZSTD_H && HAVE_LIBZSTD - if (zip->zstdstream_valid) { - ZSTD_freeDStream(zip->zstdstream); - } -#endif - - free(zip->uncompressed_buffer); - - if (zip->ppmd8_valid) - __archive_ppmd8_functions.Ppmd8_Free(&zip->ppmd8); - - if (zip->zip_entries) { - zip_entry = zip->zip_entries; - while (zip_entry != NULL) { - next_zip_entry = zip_entry->next; - archive_string_free(&zip_entry->rsrcname); - free(zip_entry); - zip_entry = next_zip_entry; - } - } - free(zip->decrypted_buffer); - if (zip->cctx_valid) - archive_decrypto_aes_ctr_release(&zip->cctx); - if (zip->hctx_valid) - archive_hmac_sha1_cleanup(&zip->hctx); - free(zip->iv); - free(zip->erd); - free(zip->v_data); - archive_string_free(&zip->format_name); - free(zip); - (a->format->data) = NULL; - return (ARCHIVE_OK); -} - -static int -archive_read_format_zip_has_encrypted_entries(struct archive_read *_a) -{ - if (_a && _a->format) { - struct zip * zip = (struct zip *)_a->format->data; - if (zip) { - return zip->has_encrypted_entries; - } - } - return ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW; -} - -static int -archive_read_format_zip_options(struct archive_read *a, - const char *key, const char *val) -{ - struct zip *zip; - int ret = ARCHIVE_FAILED; - - zip = (struct zip *)(a->format->data); - if (strcmp(key, "compat-2x") == 0) { - /* Handle filenames as libarchive 2.x */ - zip->init_default_conversion = (val != NULL) ? 1 : 0; - return (ARCHIVE_OK); - } else if (strcmp(key, "hdrcharset") == 0) { - if (val == NULL || val[0] == 0) - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "zip: hdrcharset option needs a character-set name" - ); - else { - zip->sconv = archive_string_conversion_from_charset( - &a->archive, val, 0); - if (zip->sconv != NULL) { - if (strcmp(val, "UTF-8") == 0) - zip->sconv_utf8 = zip->sconv; - ret = ARCHIVE_OK; - } else - ret = ARCHIVE_FATAL; - } - return (ret); - } else if (strcmp(key, "ignorecrc32") == 0) { - /* Mostly useful for testing. */ - if (val == NULL || val[0] == 0) { - zip->crc32func = real_crc32; - zip->ignore_crc32 = 0; - } else { - zip->crc32func = fake_crc32; - zip->ignore_crc32 = 1; - } - return (ARCHIVE_OK); - } else if (strcmp(key, "mac-ext") == 0) { - zip->process_mac_extensions = (val != NULL && val[0] != 0); - return (ARCHIVE_OK); - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -int -archive_read_support_format_zip(struct archive *a) -{ - int r; - r = archive_read_support_format_zip_streamable(a); - if (r != ARCHIVE_OK) - return r; - return (archive_read_support_format_zip_seekable(a)); -} - -/* ------------------------------------------------------------------------ */ - -/* - * Streaming-mode support - */ - - -static int -archive_read_support_format_zip_capabilities_streamable(struct archive_read * a) -{ - (void)a; /* UNUSED */ - return (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA | - ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA); -} - -static int -archive_read_format_zip_streamable_bid(struct archive_read *a, int best_bid) -{ - const char *p; - - (void)best_bid; /* UNUSED */ - - if ((p = __archive_read_ahead(a, 4, NULL)) == NULL) - return (-1); - - /* - * Bid of 29 here comes from: - * + 16 bits for "PK", - * + next 16-bit field has 6 options so contributes - * about 16 - log_2(6) ~= 16 - 2.6 ~= 13 bits - * - * So we've effectively verified ~29 total bits of check data. - */ - if (p[0] == 'P' && p[1] == 'K') { - if ((p[2] == '\001' && p[3] == '\002') - || (p[2] == '\003' && p[3] == '\004') - || (p[2] == '\005' && p[3] == '\006') - || (p[2] == '\006' && p[3] == '\006') - || (p[2] == '\007' && p[3] == '\010') - || (p[2] == '0' && p[3] == '0')) - return (29); - } - - /* TODO: It's worth looking ahead a little bit for a valid - * PK signature. In particular, that would make it possible - * to read some UUEncoded SFX files or SFX files coming from - * a network socket. */ - - return (0); -} - -static int -archive_read_format_zip_streamable_read_header(struct archive_read *a, - struct archive_entry *entry) -{ - struct zip *zip; - - a->archive.archive_format = ARCHIVE_FORMAT_ZIP; - if (a->archive.archive_format_name == NULL) - a->archive.archive_format_name = "ZIP"; - - zip = (struct zip *)(a->format->data); - - /* - * It should be sufficient to call archive_read_next_header() for - * a reader to determine if an entry is encrypted or not. If the - * encryption of an entry is only detectable when calling - * archive_read_data(), so be it. We'll do the same check there - * as well. - */ - if (zip->has_encrypted_entries == - ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) - zip->has_encrypted_entries = 0; - - /* Make sure we have a zip_entry structure to use. */ - if (zip->zip_entries == NULL) { - zip->zip_entries = malloc(sizeof(struct zip_entry)); - if (zip->zip_entries == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Out of memory"); - return ARCHIVE_FATAL; - } - } - zip->entry = zip->zip_entries; - memset(zip->entry, 0, sizeof(struct zip_entry)); - - if (zip->cctx_valid) - archive_decrypto_aes_ctr_release(&zip->cctx); - if (zip->hctx_valid) - archive_hmac_sha1_cleanup(&zip->hctx); - zip->tctx_valid = zip->cctx_valid = zip->hctx_valid = 0; - __archive_read_reset_passphrase(a); - - /* Search ahead for the next local file header. */ - __archive_read_consume(a, zip->unconsumed); - zip->unconsumed = 0; - for (;;) { - int64_t skipped = 0; - const char *p, *end; - ssize_t bytes; - - p = __archive_read_ahead(a, 4, &bytes); - if (p == NULL) - return (ARCHIVE_FATAL); - end = p + bytes; - - while (p + 4 <= end) { - if (p[0] == 'P' && p[1] == 'K') { - if (p[2] == '\003' && p[3] == '\004') { - /* Regular file entry. */ - __archive_read_consume(a, skipped); - return zip_read_local_file_header(a, - entry, zip); - } - - /* - * TODO: We cannot restore permissions - * based only on the local file headers. - * Consider scanning the central - * directory and returning additional - * entries for at least directories. - * This would allow us to properly set - * directory permissions. - * - * This won't help us fix symlinks - * and may not help with regular file - * permissions, either. - */ - if (p[2] == '\001' && p[3] == '\002') { - return (ARCHIVE_EOF); - } - - /* End of central directory? Must be an - * empty archive. */ - if ((p[2] == '\005' && p[3] == '\006') - || (p[2] == '\006' && p[3] == '\006')) - return (ARCHIVE_EOF); - } - ++p; - ++skipped; - } - __archive_read_consume(a, skipped); - } -} - -static int -archive_read_format_zip_read_data_skip_streamable(struct archive_read *a) -{ - struct zip *zip; - int64_t bytes_skipped; - - zip = (struct zip *)(a->format->data); - bytes_skipped = __archive_read_consume(a, zip->unconsumed); - zip->unconsumed = 0; - if (bytes_skipped < 0) - return (ARCHIVE_FATAL); - - /* If we've already read to end of data, we're done. */ - if (zip->end_of_entry) - return (ARCHIVE_OK); - - /* So we know we're streaming... */ - if (0 == (zip->entry->zip_flags & ZIP_LENGTH_AT_END) - || zip->entry->compressed_size > 0) { - /* We know the compressed length, so we can just skip. */ - bytes_skipped = __archive_read_consume(a, - zip->entry_bytes_remaining); - if (bytes_skipped < 0) - return (ARCHIVE_FATAL); - return (ARCHIVE_OK); - } - - if (zip->init_decryption) { - int r; - - zip->has_encrypted_entries = 1; - if (zip->entry->zip_flags & ZIP_STRONG_ENCRYPTED) - r = read_decryption_header(a); - else if (zip->entry->compression == WINZIP_AES_ENCRYPTION) - r = init_WinZip_AES_decryption(a); - else - r = init_traditional_PKWARE_decryption(a); - if (r != ARCHIVE_OK) - return (r); - zip->init_decryption = 0; - } - - /* We're streaming and we don't know the length. */ - /* If the body is compressed and we know the format, we can - * find an exact end-of-entry by decompressing it. */ - switch (zip->entry->compression) { -#ifdef HAVE_ZLIB_H - case 8: /* Deflate compression. */ - while (!zip->end_of_entry) { - int64_t offset = 0; - const void *buff = NULL; - size_t size = 0; - int r; - r = zip_read_data_deflate(a, &buff, &size, &offset); - if (r != ARCHIVE_OK) - return (r); - } - return ARCHIVE_OK; -#endif - default: /* Uncompressed or unknown. */ - /* Scan for a PK\007\010 signature. */ - for (;;) { - const char *p, *buff; - ssize_t bytes_avail; - buff = __archive_read_ahead(a, 16, &bytes_avail); - if (bytes_avail < 16) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated ZIP file data"); - return (ARCHIVE_FATAL); - } - p = buff; - while (p <= buff + bytes_avail - 16) { - if (p[3] == 'P') { p += 3; } - else if (p[3] == 'K') { p += 2; } - else if (p[3] == '\007') { p += 1; } - else if (p[3] == '\010' && p[2] == '\007' - && p[1] == 'K' && p[0] == 'P') { - if (zip->entry->flags & LA_USED_ZIP64) - __archive_read_consume(a, - p - buff + 24); - else - __archive_read_consume(a, - p - buff + 16); - return ARCHIVE_OK; - } else { p += 4; } - } - __archive_read_consume(a, p - buff); - } - } -} - -int -archive_read_support_format_zip_streamable(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - struct zip *zip; - int r; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_format_zip"); - - zip = (struct zip *)calloc(1, sizeof(*zip)); - if (zip == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate zip data"); - return (ARCHIVE_FATAL); - } - - /* Streamable reader doesn't support mac extensions. */ - zip->process_mac_extensions = 0; - - /* - * Until enough data has been read, we cannot tell about - * any encrypted entries yet. - */ - zip->has_encrypted_entries = ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW; - zip->crc32func = real_crc32; - - r = __archive_read_register_format(a, - zip, - "zip", - archive_read_format_zip_streamable_bid, - archive_read_format_zip_options, - archive_read_format_zip_streamable_read_header, - archive_read_format_zip_read_data, - archive_read_format_zip_read_data_skip_streamable, - NULL, - archive_read_format_zip_cleanup, - archive_read_support_format_zip_capabilities_streamable, - archive_read_format_zip_has_encrypted_entries); - - if (r != ARCHIVE_OK) - free(zip); - return (ARCHIVE_OK); -} - -/* ------------------------------------------------------------------------ */ - -/* - * Seeking-mode support - */ - -static int -archive_read_support_format_zip_capabilities_seekable(struct archive_read * a) -{ - (void)a; /* UNUSED */ - return (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA | - ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA); -} - -/* - * TODO: This is a performance sink because it forces the read core to - * drop buffered data from the start of file, which will then have to - * be re-read again if this bidder loses. - * - * We workaround this a little by passing in the best bid so far so - * that later bidders can do nothing if they know they'll never - * outbid. But we can certainly do better... - */ -static int -read_eocd(struct zip *zip, const char *p, int64_t current_offset) -{ - uint16_t disk_num; - uint32_t cd_size, cd_offset; - - disk_num = archive_le16dec(p + 4); - cd_size = archive_le32dec(p + 12); - cd_offset = archive_le32dec(p + 16); - - /* Sanity-check the EOCD we've found. */ - - /* This must be the first volume. */ - if (disk_num != 0) - return 0; - /* Central directory must be on this volume. */ - if (disk_num != archive_le16dec(p + 6)) - return 0; - /* All central directory entries must be on this volume. */ - if (archive_le16dec(p + 10) != archive_le16dec(p + 8)) - return 0; - /* Central directory can't extend beyond start of EOCD record. */ - if (cd_offset + cd_size > current_offset) - return 0; - - /* Save the central directory location for later use. */ - zip->central_directory_offset = cd_offset; - zip->central_directory_offset_adjusted = current_offset - cd_size; - - /* This is just a tiny bit higher than the maximum - returned by the streaming Zip bidder. This ensures - that the more accurate seeking Zip parser wins - whenever seek is available. */ - return 32; -} - -/* - * Examine Zip64 EOCD locator: If it's valid, store the information - * from it. - */ -static int -read_zip64_eocd(struct archive_read *a, struct zip *zip, const char *p) -{ - int64_t eocd64_offset; - int64_t eocd64_size; - - /* Sanity-check the locator record. */ - - /* Central dir must be on first volume. */ - if (archive_le32dec(p + 4) != 0) - return 0; - /* Must be only a single volume. */ - if (archive_le32dec(p + 16) != 1) - return 0; - - /* Find the Zip64 EOCD record. */ - eocd64_offset = archive_le64dec(p + 8); - if (__archive_read_seek(a, eocd64_offset, SEEK_SET) < 0) - return 0; - if ((p = __archive_read_ahead(a, 56, NULL)) == NULL) - return 0; - /* Make sure we can read all of it. */ - eocd64_size = archive_le64dec(p + 4) + 12; - if (eocd64_size < 56 || eocd64_size > 16384) - return 0; - if ((p = __archive_read_ahead(a, (size_t)eocd64_size, NULL)) == NULL) - return 0; - - /* Sanity-check the EOCD64 */ - if (archive_le32dec(p + 16) != 0) /* Must be disk #0 */ - return 0; - if (archive_le32dec(p + 20) != 0) /* CD must be on disk #0 */ - return 0; - /* CD can't be split. */ - if (archive_le64dec(p + 24) != archive_le64dec(p + 32)) - return 0; - - /* Save the central directory offset for later use. */ - zip->central_directory_offset = archive_le64dec(p + 48); - /* TODO: Needs scanning backwards to find the eocd64 instead of assuming */ - zip->central_directory_offset_adjusted = zip->central_directory_offset; - - return 32; -} - -static int -archive_read_format_zip_seekable_bid(struct archive_read *a, int best_bid) -{ - struct zip *zip = (struct zip *)a->format->data; - int64_t file_size, current_offset; - const char *p; - int i, tail; - - /* If someone has already bid more than 32, then avoid - trashing the look-ahead buffers with a seek. */ - if (best_bid > 32) - return (-1); - - file_size = __archive_read_seek(a, 0, SEEK_END); - if (file_size <= 0) - return 0; - - /* Search last 16k of file for end-of-central-directory - * record (which starts with PK\005\006) */ - tail = (int)zipmin(1024 * 16, file_size); - current_offset = __archive_read_seek(a, -tail, SEEK_END); - if (current_offset < 0) - return 0; - if ((p = __archive_read_ahead(a, (size_t)tail, NULL)) == NULL) - return 0; - /* Boyer-Moore search backwards from the end, since we want - * to match the last EOCD in the file (there can be more than - * one if there is an uncompressed Zip archive as a member - * within this Zip archive). */ - for (i = tail - 22; i > 0;) { - switch (p[i]) { - case 'P': - if (memcmp(p + i, "PK\005\006", 4) == 0) { - int ret = read_eocd(zip, p + i, - current_offset + i); - /* Zip64 EOCD locator precedes - * regular EOCD if present. */ - if (i >= 20 && memcmp(p + i - 20, "PK\006\007", 4) == 0) { - int ret_zip64 = read_zip64_eocd(a, zip, p + i - 20); - if (ret_zip64 > ret) - ret = ret_zip64; - } - return (ret); - } - i -= 4; - break; - case 'K': i -= 1; break; - case 005: i -= 2; break; - case 006: i -= 3; break; - default: i -= 4; break; - } - } - return 0; -} - -/* The red-black trees are only used in seeking mode to manage - * the in-memory copy of the central directory. */ - -static int -cmp_node(const struct archive_rb_node *n1, const struct archive_rb_node *n2) -{ - const struct zip_entry *e1 = (const struct zip_entry *)n1; - const struct zip_entry *e2 = (const struct zip_entry *)n2; - - if (e1->local_header_offset > e2->local_header_offset) - return -1; - if (e1->local_header_offset < e2->local_header_offset) - return 1; - return 0; -} - -static int -cmp_key(const struct archive_rb_node *n, const void *key) -{ - /* This function won't be called */ - (void)n; /* UNUSED */ - (void)key; /* UNUSED */ - return 1; -} - -static const struct archive_rb_tree_ops rb_ops = { - &cmp_node, &cmp_key -}; - -static int -rsrc_cmp_node(const struct archive_rb_node *n1, - const struct archive_rb_node *n2) -{ - const struct zip_entry *e1 = (const struct zip_entry *)n1; - const struct zip_entry *e2 = (const struct zip_entry *)n2; - - return (strcmp(e2->rsrcname.s, e1->rsrcname.s)); -} - -static int -rsrc_cmp_key(const struct archive_rb_node *n, const void *key) -{ - const struct zip_entry *e = (const struct zip_entry *)n; - return (strcmp((const char *)key, e->rsrcname.s)); -} - -static const struct archive_rb_tree_ops rb_rsrc_ops = { - &rsrc_cmp_node, &rsrc_cmp_key -}; - -static const char * -rsrc_basename(const char *name, size_t name_length) -{ - const char *s, *r; - - r = s = name; - for (;;) { - s = memchr(s, '/', name_length - (s - name)); - if (s == NULL) - break; - r = ++s; - } - return (r); -} - -static void -expose_parent_dirs(struct zip *zip, const char *name, size_t name_length) -{ - struct archive_string str; - struct zip_entry *dir; - char *s; - - archive_string_init(&str); - archive_strncpy(&str, name, name_length); - for (;;) { - s = strrchr(str.s, '/'); - if (s == NULL) - break; - *s = '\0'; - /* Transfer the parent directory from zip->tree_rsrc RB - * tree to zip->tree RB tree to expose. */ - dir = (struct zip_entry *) - __archive_rb_tree_find_node(&zip->tree_rsrc, str.s); - if (dir == NULL) - break; - __archive_rb_tree_remove_node(&zip->tree_rsrc, &dir->node); - archive_string_free(&dir->rsrcname); - __archive_rb_tree_insert_node(&zip->tree, &dir->node); - } - archive_string_free(&str); -} - -static int -slurp_central_directory(struct archive_read *a, struct archive_entry* entry, - struct zip *zip) -{ - ssize_t i; - unsigned found; - int64_t correction; - ssize_t bytes_avail; - const char *p; - - /* - * Find the start of the central directory. The end-of-CD - * record has our starting point, but there are lots of - * Zip archives which have had other data prepended to the - * file, which makes the recorded offsets all too small. - * So we search forward from the specified offset until we - * find the real start of the central directory. Then we - * know the correction we need to apply to account for leading - * padding. - */ - if (__archive_read_seek(a, zip->central_directory_offset_adjusted, SEEK_SET) - < 0) - return ARCHIVE_FATAL; - - found = 0; - while (!found) { - if ((p = __archive_read_ahead(a, 20, &bytes_avail)) == NULL) - return ARCHIVE_FATAL; - for (found = 0, i = 0; !found && i < bytes_avail - 4;) { - switch (p[i + 3]) { - case 'P': i += 3; break; - case 'K': i += 2; break; - case 001: i += 1; break; - case 002: - if (memcmp(p + i, "PK\001\002", 4) == 0) { - p += i; - found = 1; - } else - i += 4; - break; - case 005: i += 1; break; - case 006: - if (memcmp(p + i, "PK\005\006", 4) == 0) { - p += i; - found = 1; - } else if (memcmp(p + i, "PK\006\006", 4) == 0) { - p += i; - found = 1; - } else - i += 1; - break; - default: i += 4; break; - } - } - __archive_read_consume(a, i); - } - correction = archive_filter_bytes(&a->archive, 0) - - zip->central_directory_offset; - - __archive_rb_tree_init(&zip->tree, &rb_ops); - __archive_rb_tree_init(&zip->tree_rsrc, &rb_rsrc_ops); - - zip->central_directory_entries_total = 0; - while (1) { - struct zip_entry *zip_entry; - size_t filename_length, extra_length, comment_length; - uint32_t external_attributes; - const char *name, *r; - - if ((p = __archive_read_ahead(a, 4, NULL)) == NULL) - return ARCHIVE_FATAL; - if (memcmp(p, "PK\006\006", 4) == 0 - || memcmp(p, "PK\005\006", 4) == 0) { - break; - } else if (memcmp(p, "PK\001\002", 4) != 0) { - archive_set_error(&a->archive, - -1, "Invalid central directory signature"); - return ARCHIVE_FATAL; - } - if ((p = __archive_read_ahead(a, 46, NULL)) == NULL) - return ARCHIVE_FATAL; - - zip_entry = calloc(1, sizeof(struct zip_entry)); - if (zip_entry == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate zip entry"); - return ARCHIVE_FATAL; - } - zip_entry->next = zip->zip_entries; - zip_entry->flags |= LA_FROM_CENTRAL_DIRECTORY; - zip->zip_entries = zip_entry; - zip->central_directory_entries_total++; - - /* version = p[4]; */ - zip_entry->system = p[5]; - /* version_required = archive_le16dec(p + 6); */ - zip_entry->zip_flags = archive_le16dec(p + 8); - if (zip_entry->zip_flags - & (ZIP_ENCRYPTED | ZIP_STRONG_ENCRYPTED)){ - zip->has_encrypted_entries = 1; - } - zip_entry->compression = (char)archive_le16dec(p + 10); - zip_entry->mtime = zip_time(p + 12); - zip_entry->crc32 = archive_le32dec(p + 16); - if (zip_entry->zip_flags & ZIP_LENGTH_AT_END) - zip_entry->decdat = p[13]; - else - zip_entry->decdat = p[19]; - zip_entry->compressed_size = archive_le32dec(p + 20); - zip_entry->uncompressed_size = archive_le32dec(p + 24); - filename_length = archive_le16dec(p + 28); - extra_length = archive_le16dec(p + 30); - comment_length = archive_le16dec(p + 32); - /* disk_start = archive_le16dec(p + 34); - * Better be zero. - * internal_attributes = archive_le16dec(p + 36); - * text bit */ - external_attributes = archive_le32dec(p + 38); - zip_entry->local_header_offset = - archive_le32dec(p + 42) + correction; - - /* If we can't guess the mode, leave it zero here; - when we read the local file header we might get - more information. */ - if (zip_entry->system == 3) { - zip_entry->mode = external_attributes >> 16; - } else if (zip_entry->system == 0) { - // Interpret MSDOS directory bit - if (0x10 == (external_attributes & 0x10)) { - zip_entry->mode = AE_IFDIR | 0775; - } else { - zip_entry->mode = AE_IFREG | 0664; - } - if (0x01 == (external_attributes & 0x01)) { - // Read-only bit; strip write permissions - zip_entry->mode &= 0555; - } - } else { - zip_entry->mode = 0; - } - - /* We're done with the regular data; get the filename and - * extra data. */ - __archive_read_consume(a, 46); - p = __archive_read_ahead(a, filename_length + extra_length, - NULL); - if (p == NULL) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated ZIP file header"); - return ARCHIVE_FATAL; - } - if (ARCHIVE_OK != process_extra(a, entry, p + filename_length, - extra_length, zip_entry)) { - return ARCHIVE_FATAL; - } - - /* - * Mac resource fork files are stored under the - * "__MACOSX/" directory, so we should check if - * it is. - */ - if (!zip->process_mac_extensions) { - /* Treat every entry as a regular entry. */ - __archive_rb_tree_insert_node(&zip->tree, - &zip_entry->node); - } else { - name = p; - r = rsrc_basename(name, filename_length); - if (filename_length >= 9 && - strncmp("__MACOSX/", name, 9) == 0) { - /* If this file is not a resource fork nor - * a directory. We should treat it as a non - * resource fork file to expose it. */ - if (name[filename_length-1] != '/' && - (r - name < 3 || r[0] != '.' || - r[1] != '_')) { - __archive_rb_tree_insert_node( - &zip->tree, &zip_entry->node); - /* Expose its parent directories. */ - expose_parent_dirs(zip, name, - filename_length); - } else { - /* This file is a resource fork file or - * a directory. */ - archive_strncpy(&(zip_entry->rsrcname), - name, filename_length); - __archive_rb_tree_insert_node( - &zip->tree_rsrc, &zip_entry->node); - } - } else { - /* Generate resource fork name to find its - * resource file at zip->tree_rsrc. */ - archive_strcpy(&(zip_entry->rsrcname), - "__MACOSX/"); - archive_strncat(&(zip_entry->rsrcname), - name, r - name); - archive_strcat(&(zip_entry->rsrcname), "._"); - archive_strncat(&(zip_entry->rsrcname), - name + (r - name), - filename_length - (r - name)); - /* Register an entry to RB tree to sort it by - * file offset. */ - __archive_rb_tree_insert_node(&zip->tree, - &zip_entry->node); - } - } - - /* Skip the comment too ... */ - __archive_read_consume(a, - filename_length + extra_length + comment_length); - } - - return ARCHIVE_OK; -} - -static ssize_t -zip_get_local_file_header_size(struct archive_read *a, size_t extra) -{ - const char *p; - ssize_t filename_length, extra_length; - - if ((p = __archive_read_ahead(a, extra + 30, NULL)) == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated ZIP file header"); - return (ARCHIVE_WARN); - } - p += extra; - - if (memcmp(p, "PK\003\004", 4) != 0) { - archive_set_error(&a->archive, -1, "Damaged Zip archive"); - return ARCHIVE_WARN; - } - filename_length = archive_le16dec(p + 26); - extra_length = archive_le16dec(p + 28); - - return (30 + filename_length + extra_length); -} - -static int -zip_read_mac_metadata(struct archive_read *a, struct archive_entry *entry, - struct zip_entry *rsrc) -{ - struct zip *zip = (struct zip *)a->format->data; - unsigned char *metadata, *mp; - int64_t offset = archive_filter_bytes(&a->archive, 0); - size_t remaining_bytes, metadata_bytes; - ssize_t hsize; - int ret = ARCHIVE_OK, eof; - - switch(rsrc->compression) { - case 0: /* No compression. */ - if (rsrc->uncompressed_size != rsrc->compressed_size) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Malformed OS X metadata entry: " - "inconsistent size"); - return (ARCHIVE_FATAL); - } -#ifdef HAVE_ZLIB_H - case 8: /* Deflate compression. */ -#endif - break; - default: /* Unsupported compression. */ - /* Return a warning. */ - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Unsupported ZIP compression method (%s)", - compression_name(rsrc->compression)); - /* We can't decompress this entry, but we will - * be able to skip() it and try the next entry. */ - return (ARCHIVE_WARN); - } - - if (rsrc->uncompressed_size > (4 * 1024 * 1024)) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Mac metadata is too large: %jd > 4M bytes", - (intmax_t)rsrc->uncompressed_size); - return (ARCHIVE_WARN); - } - if (rsrc->compressed_size > (4 * 1024 * 1024)) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Mac metadata is too large: %jd > 4M bytes", - (intmax_t)rsrc->compressed_size); - return (ARCHIVE_WARN); - } - - metadata = malloc((size_t)rsrc->uncompressed_size); - if (metadata == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Mac metadata"); - return (ARCHIVE_FATAL); - } - - if (offset < rsrc->local_header_offset) - __archive_read_consume(a, rsrc->local_header_offset - offset); - else if (offset != rsrc->local_header_offset) { - __archive_read_seek(a, rsrc->local_header_offset, SEEK_SET); - } - - hsize = zip_get_local_file_header_size(a, 0); - __archive_read_consume(a, hsize); - - remaining_bytes = (size_t)rsrc->compressed_size; - metadata_bytes = (size_t)rsrc->uncompressed_size; - mp = metadata; - eof = 0; - while (!eof && remaining_bytes) { - const unsigned char *p; - ssize_t bytes_avail; - size_t bytes_used; - - p = __archive_read_ahead(a, 1, &bytes_avail); - if (p == NULL) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Truncated ZIP file header"); - ret = ARCHIVE_WARN; - goto exit_mac_metadata; - } - if ((size_t)bytes_avail > remaining_bytes) - bytes_avail = remaining_bytes; - switch(rsrc->compression) { - case 0: /* No compression. */ - if ((size_t)bytes_avail > metadata_bytes) - bytes_avail = metadata_bytes; - memcpy(mp, p, bytes_avail); - bytes_used = (size_t)bytes_avail; - metadata_bytes -= bytes_used; - mp += bytes_used; - if (metadata_bytes == 0) - eof = 1; - break; -#ifdef HAVE_ZLIB_H - case 8: /* Deflate compression. */ - { - int r; - - ret = zip_deflate_init(a, zip); - if (ret != ARCHIVE_OK) - goto exit_mac_metadata; - zip->stream.next_in = - (Bytef *)(uintptr_t)(const void *)p; - zip->stream.avail_in = (uInt)bytes_avail; - zip->stream.total_in = 0; - zip->stream.next_out = mp; - zip->stream.avail_out = (uInt)metadata_bytes; - zip->stream.total_out = 0; - - r = inflate(&zip->stream, 0); - switch (r) { - case Z_OK: - break; - case Z_STREAM_END: - eof = 1; - break; - case Z_MEM_ERROR: - archive_set_error(&a->archive, ENOMEM, - "Out of memory for ZIP decompression"); - ret = ARCHIVE_FATAL; - goto exit_mac_metadata; - default: - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "ZIP decompression failed (%d)", r); - ret = ARCHIVE_FATAL; - goto exit_mac_metadata; - } - bytes_used = zip->stream.total_in; - metadata_bytes -= zip->stream.total_out; - mp += zip->stream.total_out; - break; - } -#endif - default: - bytes_used = 0; - break; - } - __archive_read_consume(a, bytes_used); - remaining_bytes -= bytes_used; - } - archive_entry_copy_mac_metadata(entry, metadata, - (size_t)rsrc->uncompressed_size - metadata_bytes); - -exit_mac_metadata: - __archive_read_seek(a, offset, SEEK_SET); - zip->decompress_init = 0; - free(metadata); - return (ret); -} - -static int -archive_read_format_zip_seekable_read_header(struct archive_read *a, - struct archive_entry *entry) -{ - struct zip *zip = (struct zip *)a->format->data; - struct zip_entry *rsrc; - int64_t offset; - int r, ret = ARCHIVE_OK; - - /* - * It should be sufficient to call archive_read_next_header() for - * a reader to determine if an entry is encrypted or not. If the - * encryption of an entry is only detectable when calling - * archive_read_data(), so be it. We'll do the same check there - * as well. - */ - if (zip->has_encrypted_entries == - ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) - zip->has_encrypted_entries = 0; - - a->archive.archive_format = ARCHIVE_FORMAT_ZIP; - if (a->archive.archive_format_name == NULL) - a->archive.archive_format_name = "ZIP"; - - if (zip->zip_entries == NULL) { - r = slurp_central_directory(a, entry, zip); - if (r != ARCHIVE_OK) - return r; - /* Get first entry whose local header offset is lower than - * other entries in the archive file. */ - zip->entry = - (struct zip_entry *)ARCHIVE_RB_TREE_MIN(&zip->tree); - } else if (zip->entry != NULL) { - /* Get next entry in local header offset order. */ - zip->entry = (struct zip_entry *)__archive_rb_tree_iterate( - &zip->tree, &zip->entry->node, ARCHIVE_RB_DIR_RIGHT); - } - - if (zip->entry == NULL) - return ARCHIVE_EOF; - - if (zip->entry->rsrcname.s) - rsrc = (struct zip_entry *)__archive_rb_tree_find_node( - &zip->tree_rsrc, zip->entry->rsrcname.s); - else - rsrc = NULL; - - if (zip->cctx_valid) - archive_decrypto_aes_ctr_release(&zip->cctx); - if (zip->hctx_valid) - archive_hmac_sha1_cleanup(&zip->hctx); - zip->tctx_valid = zip->cctx_valid = zip->hctx_valid = 0; - __archive_read_reset_passphrase(a); - - /* File entries are sorted by the header offset, we should mostly - * use __archive_read_consume to advance a read point to avoid - * redundant data reading. */ - offset = archive_filter_bytes(&a->archive, 0); - if (offset < zip->entry->local_header_offset) - __archive_read_consume(a, - zip->entry->local_header_offset - offset); - else if (offset != zip->entry->local_header_offset) { - __archive_read_seek(a, zip->entry->local_header_offset, - SEEK_SET); - } - zip->unconsumed = 0; - r = zip_read_local_file_header(a, entry, zip); - if (r != ARCHIVE_OK) - return r; - if (rsrc) { - int ret2 = zip_read_mac_metadata(a, entry, rsrc); - if (ret2 < ret) - ret = ret2; - } - return (ret); -} - -/* - * We're going to seek for the next header anyway, so we don't - * need to bother doing anything here. - */ -static int -archive_read_format_zip_read_data_skip_seekable(struct archive_read *a) -{ - struct zip *zip; - zip = (struct zip *)(a->format->data); - - zip->unconsumed = 0; - return (ARCHIVE_OK); -} - -int -archive_read_support_format_zip_seekable(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - struct zip *zip; - int r; - - archive_check_magic(_a, ARCHIVE_READ_MAGIC, - ARCHIVE_STATE_NEW, "archive_read_support_format_zip_seekable"); - - zip = (struct zip *)calloc(1, sizeof(*zip)); - if (zip == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate zip data"); - return (ARCHIVE_FATAL); - } - -#ifdef HAVE_COPYFILE_H - /* Set this by default on Mac OS. */ - zip->process_mac_extensions = 1; -#endif - - /* - * Until enough data has been read, we cannot tell about - * any encrypted entries yet. - */ - zip->has_encrypted_entries = ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW; - zip->crc32func = real_crc32; - - r = __archive_read_register_format(a, - zip, - "zip", - archive_read_format_zip_seekable_bid, - archive_read_format_zip_options, - archive_read_format_zip_seekable_read_header, - archive_read_format_zip_read_data, - archive_read_format_zip_read_data_skip_seekable, - NULL, - archive_read_format_zip_cleanup, - archive_read_support_format_zip_capabilities_seekable, - archive_read_format_zip_has_encrypted_entries); - - if (r != ARCHIVE_OK) - free(zip); - return (ARCHIVE_OK); -} - -/*# vim:set noet:*/ diff --git a/thirdparty/libarchive/libarchive/archive_string.c b/thirdparty/libarchive/libarchive/archive_string.c deleted file mode 100644 index accf52631..000000000 --- a/thirdparty/libarchive/libarchive/archive_string.c +++ /dev/null @@ -1,4244 +0,0 @@ -/*- - * Copyright (c) 2003-2011 Tim Kientzle - * Copyright (c) 2011-2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_string.c 201095 2009-12-28 02:33:22Z kientzle $"); - -/* - * Basic resizable string support, to simplify manipulating arbitrary-sized - * strings while minimizing heap activity. - * - * In particular, the buffer used by a string object is only grown, it - * never shrinks, so you can clear and reuse the same string object - * without incurring additional memory allocations. - */ - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_ICONV_H -#include -#endif -#ifdef HAVE_LANGINFO_H -#include -#endif -#ifdef HAVE_LOCALCHARSET_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_WCHAR_H -#include -#endif -#if defined(_WIN32) && !defined(__CYGWIN__) -#include -#include -#endif - -#include "archive_endian.h" -#include "archive_private.h" -#include "archive_string.h" -#include "archive_string_composition.h" - -#if !defined(HAVE_WMEMCPY) && !defined(wmemcpy) -#define wmemcpy(a,b,i) (wchar_t *)memcpy((a), (b), (i) * sizeof(wchar_t)) -#endif - -#if !defined(HAVE_WMEMMOVE) && !defined(wmemmove) -#define wmemmove(a,b,i) (wchar_t *)memmove((a), (b), (i) * sizeof(wchar_t)) -#endif - -#undef max -#define max(a, b) ((a)>(b)?(a):(b)) - -struct archive_string_conv { - struct archive_string_conv *next; - char *from_charset; - char *to_charset; - unsigned from_cp; - unsigned to_cp; - /* Set 1 if from_charset and to_charset are the same. */ - int same; - int flag; -#define SCONV_TO_CHARSET 1 /* MBS is being converted to specified - * charset. */ -#define SCONV_FROM_CHARSET (1<<1) /* MBS is being converted from - * specified charset. */ -#define SCONV_BEST_EFFORT (1<<2) /* Copy at least ASCII code. */ -#define SCONV_WIN_CP (1<<3) /* Use Windows API for converting - * MBS. */ -#define SCONV_UTF8_LIBARCHIVE_2 (1<<4) /* Incorrect UTF-8 made by libarchive - * 2.x in the wrong assumption. */ -#define SCONV_NORMALIZATION_C (1<<6) /* Need normalization to be Form C. - * Before UTF-8 characters are actually - * processed. */ -#define SCONV_NORMALIZATION_D (1<<7) /* Need normalization to be Form D. - * Before UTF-8 characters are actually - * processed. - * Currently this only for MAC OS X. */ -#define SCONV_TO_UTF8 (1<<8) /* "to charset" side is UTF-8. */ -#define SCONV_FROM_UTF8 (1<<9) /* "from charset" side is UTF-8. */ -#define SCONV_TO_UTF16BE (1<<10) /* "to charset" side is UTF-16BE. */ -#define SCONV_FROM_UTF16BE (1<<11) /* "from charset" side is UTF-16BE. */ -#define SCONV_TO_UTF16LE (1<<12) /* "to charset" side is UTF-16LE. */ -#define SCONV_FROM_UTF16LE (1<<13) /* "from charset" side is UTF-16LE. */ -#define SCONV_TO_UTF16 (SCONV_TO_UTF16BE | SCONV_TO_UTF16LE) -#define SCONV_FROM_UTF16 (SCONV_FROM_UTF16BE | SCONV_FROM_UTF16LE) - -#if HAVE_ICONV - iconv_t cd; - iconv_t cd_w;/* Use at archive_mstring on - * Windows. */ -#endif - /* A temporary buffer for normalization. */ - struct archive_string utftmp; - int (*converter[2])(struct archive_string *, const void *, size_t, - struct archive_string_conv *); - int nconverter; -}; - -#define CP_C_LOCALE 0 /* "C" locale only for this file. */ -#define CP_UTF16LE 1200 -#define CP_UTF16BE 1201 - -#define IS_HIGH_SURROGATE_LA(uc) ((uc) >= 0xD800 && (uc) <= 0xDBFF) -#define IS_LOW_SURROGATE_LA(uc) ((uc) >= 0xDC00 && (uc) <= 0xDFFF) -#define IS_SURROGATE_PAIR_LA(uc) ((uc) >= 0xD800 && (uc) <= 0xDFFF) -#define UNICODE_MAX 0x10FFFF -#define UNICODE_R_CHAR 0xFFFD /* Replacement character. */ -/* Set U+FFFD(Replacement character) in UTF-8. */ -static const char utf8_replacement_char[] = {0xef, 0xbf, 0xbd}; - -static struct archive_string_conv *find_sconv_object(struct archive *, - const char *, const char *); -static void add_sconv_object(struct archive *, struct archive_string_conv *); -static struct archive_string_conv *create_sconv_object(const char *, - const char *, unsigned, int); -static void free_sconv_object(struct archive_string_conv *); -static struct archive_string_conv *get_sconv_object(struct archive *, - const char *, const char *, int); -static unsigned make_codepage_from_charset(const char *); -static unsigned get_current_codepage(void); -static unsigned get_current_oemcp(void); -static size_t mbsnbytes(const void *, size_t); -static size_t utf16nbytes(const void *, size_t); -#if defined(_WIN32) && !defined(__CYGWIN__) -static int archive_wstring_append_from_mbs_in_codepage( - struct archive_wstring *, const char *, size_t, - struct archive_string_conv *); -static int archive_string_append_from_wcs_in_codepage(struct archive_string *, - const wchar_t *, size_t, struct archive_string_conv *); -static int is_big_endian(void); -static int strncat_in_codepage(struct archive_string *, const void *, - size_t, struct archive_string_conv *); -static int win_strncat_from_utf16be(struct archive_string *, const void *, - size_t, struct archive_string_conv *); -static int win_strncat_from_utf16le(struct archive_string *, const void *, - size_t, struct archive_string_conv *); -static int win_strncat_to_utf16be(struct archive_string *, const void *, - size_t, struct archive_string_conv *); -static int win_strncat_to_utf16le(struct archive_string *, const void *, - size_t, struct archive_string_conv *); -#endif -static int best_effort_strncat_from_utf16be(struct archive_string *, - const void *, size_t, struct archive_string_conv *); -static int best_effort_strncat_from_utf16le(struct archive_string *, - const void *, size_t, struct archive_string_conv *); -static int best_effort_strncat_to_utf16be(struct archive_string *, - const void *, size_t, struct archive_string_conv *); -static int best_effort_strncat_to_utf16le(struct archive_string *, - const void *, size_t, struct archive_string_conv *); -#if defined(HAVE_ICONV) -static int iconv_strncat_in_locale(struct archive_string *, const void *, - size_t, struct archive_string_conv *); -#endif -static int best_effort_strncat_in_locale(struct archive_string *, - const void *, size_t, struct archive_string_conv *); -static int _utf8_to_unicode(uint32_t *, const char *, size_t); -static int utf8_to_unicode(uint32_t *, const char *, size_t); -static inline uint32_t combine_surrogate_pair(uint32_t, uint32_t); -static int cesu8_to_unicode(uint32_t *, const char *, size_t); -static size_t unicode_to_utf8(char *, size_t, uint32_t); -static int utf16_to_unicode(uint32_t *, const char *, size_t, int); -static size_t unicode_to_utf16be(char *, size_t, uint32_t); -static size_t unicode_to_utf16le(char *, size_t, uint32_t); -static int strncat_from_utf8_libarchive2(struct archive_string *, - const void *, size_t, struct archive_string_conv *); -static int strncat_from_utf8_to_utf8(struct archive_string *, const void *, - size_t, struct archive_string_conv *); -static int archive_string_normalize_C(struct archive_string *, const void *, - size_t, struct archive_string_conv *); -static int archive_string_normalize_D(struct archive_string *, const void *, - size_t, struct archive_string_conv *); -static int archive_string_append_unicode(struct archive_string *, - const void *, size_t, struct archive_string_conv *); - -static struct archive_string * -archive_string_append(struct archive_string *as, const char *p, size_t s) -{ - if (archive_string_ensure(as, as->length + s + 1) == NULL) - return (NULL); - if (s) - memmove(as->s + as->length, p, s); - as->length += s; - as->s[as->length] = 0; - return (as); -} - -static struct archive_wstring * -archive_wstring_append(struct archive_wstring *as, const wchar_t *p, size_t s) -{ - if (archive_wstring_ensure(as, as->length + s + 1) == NULL) - return (NULL); - if (s) - wmemmove(as->s + as->length, p, s); - as->length += s; - as->s[as->length] = 0; - return (as); -} - -struct archive_string * -archive_array_append(struct archive_string *as, const char *p, size_t s) -{ - return archive_string_append(as, p, s); -} - -void -archive_string_concat(struct archive_string *dest, struct archive_string *src) -{ - if (archive_string_append(dest, src->s, src->length) == NULL) - __archive_errx(1, "Out of memory"); -} - -void -archive_wstring_concat(struct archive_wstring *dest, - struct archive_wstring *src) -{ - if (archive_wstring_append(dest, src->s, src->length) == NULL) - __archive_errx(1, "Out of memory"); -} - -void -archive_string_free(struct archive_string *as) -{ - as->length = 0; - as->buffer_length = 0; - free(as->s); - as->s = NULL; -} - -void -archive_wstring_free(struct archive_wstring *as) -{ - as->length = 0; - as->buffer_length = 0; - free(as->s); - as->s = NULL; -} - -struct archive_wstring * -archive_wstring_ensure(struct archive_wstring *as, size_t s) -{ - return (struct archive_wstring *) - archive_string_ensure((struct archive_string *)as, - s * sizeof(wchar_t)); -} - -/* Returns NULL on any allocation failure. */ -struct archive_string * -archive_string_ensure(struct archive_string *as, size_t s) -{ - char *p; - size_t new_length; - - /* If buffer is already big enough, don't reallocate. */ - if (as->s && (s <= as->buffer_length)) - return (as); - - /* - * Growing the buffer at least exponentially ensures that - * append operations are always linear in the number of - * characters appended. Using a smaller growth rate for - * larger buffers reduces memory waste somewhat at the cost of - * a larger constant factor. - */ - if (as->buffer_length < 32) - /* Start with a minimum 32-character buffer. */ - new_length = 32; - else if (as->buffer_length < 8192) - /* Buffers under 8k are doubled for speed. */ - new_length = as->buffer_length + as->buffer_length; - else { - /* Buffers 8k and over grow by at least 25% each time. */ - new_length = as->buffer_length + as->buffer_length / 4; - /* Be safe: If size wraps, fail. */ - if (new_length < as->buffer_length) { - /* On failure, wipe the string and return NULL. */ - archive_string_free(as); - errno = ENOMEM;/* Make sure errno has ENOMEM. */ - return (NULL); - } - } - /* - * The computation above is a lower limit to how much we'll - * grow the buffer. In any case, we have to grow it enough to - * hold the request. - */ - if (new_length < s) - new_length = s; - /* Now we can reallocate the buffer. */ - p = (char *)realloc(as->s, new_length); - if (p == NULL) { - /* On failure, wipe the string and return NULL. */ - archive_string_free(as); - errno = ENOMEM;/* Make sure errno has ENOMEM. */ - return (NULL); - } - - as->s = p; - as->buffer_length = new_length; - return (as); -} - -/* - * TODO: See if there's a way to avoid scanning - * the source string twice. Then test to see - * if it actually helps (remember that we're almost - * always called with pretty short arguments, so - * such an optimization might not help). - */ -struct archive_string * -archive_strncat(struct archive_string *as, const void *_p, size_t n) -{ - size_t s; - const char *p, *pp; - - p = (const char *)_p; - - /* Like strlen(p), except won't examine positions beyond p[n]. */ - s = 0; - pp = p; - while (s < n && *pp) { - pp++; - s++; - } - if ((as = archive_string_append(as, p, s)) == NULL) - __archive_errx(1, "Out of memory"); - return (as); -} - -struct archive_wstring * -archive_wstrncat(struct archive_wstring *as, const wchar_t *p, size_t n) -{ - size_t s; - const wchar_t *pp; - - /* Like strlen(p), except won't examine positions beyond p[n]. */ - s = 0; - pp = p; - while (s < n && *pp) { - pp++; - s++; - } - if ((as = archive_wstring_append(as, p, s)) == NULL) - __archive_errx(1, "Out of memory"); - return (as); -} - -struct archive_string * -archive_strcat(struct archive_string *as, const void *p) -{ - /* strcat is just strncat without an effective limit. - * Assert that we'll never get called with a source - * string over 16MB. - * TODO: Review all uses of strcat in the source - * and try to replace them with strncat(). - */ - return archive_strncat(as, p, 0x1000000); -} - -struct archive_wstring * -archive_wstrcat(struct archive_wstring *as, const wchar_t *p) -{ - /* Ditto. */ - return archive_wstrncat(as, p, 0x1000000); -} - -struct archive_string * -archive_strappend_char(struct archive_string *as, char c) -{ - if ((as = archive_string_append(as, &c, 1)) == NULL) - __archive_errx(1, "Out of memory"); - return (as); -} - -struct archive_wstring * -archive_wstrappend_wchar(struct archive_wstring *as, wchar_t c) -{ - if ((as = archive_wstring_append(as, &c, 1)) == NULL) - __archive_errx(1, "Out of memory"); - return (as); -} - -/* - * Get the "current character set" name to use with iconv. - * On FreeBSD, the empty character set name "" chooses - * the correct character encoding for the current locale, - * so this isn't necessary. - * But iconv on Mac OS 10.6 doesn't seem to handle this correctly; - * on that system, we have to explicitly call nl_langinfo() - * to get the right name. Not sure about other platforms. - * - * NOTE: GNU libiconv does not recognize the character-set name - * which some platform nl_langinfo(CODESET) returns, so we should - * use locale_charset() instead of nl_langinfo(CODESET) for GNU libiconv. - */ -static const char * -default_iconv_charset(const char *charset) { - if (charset != NULL && charset[0] != '\0') - return charset; -#if HAVE_LOCALE_CHARSET && !defined(__APPLE__) - /* locale_charset() is broken on Mac OS */ - return locale_charset(); -#elif HAVE_NL_LANGINFO - return nl_langinfo(CODESET); -#else - return ""; -#endif -} - -#if defined(_WIN32) && !defined(__CYGWIN__) - -/* - * Convert MBS to WCS. - * Note: returns -1 if conversion fails. - */ -int -archive_wstring_append_from_mbs(struct archive_wstring *dest, - const char *p, size_t len) -{ - return archive_wstring_append_from_mbs_in_codepage(dest, p, len, NULL); -} - -static int -archive_wstring_append_from_mbs_in_codepage(struct archive_wstring *dest, - const char *s, size_t length, struct archive_string_conv *sc) -{ - int count, ret = 0; - UINT from_cp; - - if (sc != NULL) - from_cp = sc->from_cp; - else - from_cp = get_current_codepage(); - - if (from_cp == CP_C_LOCALE) { - /* - * "C" locale special processing. - */ - wchar_t *ws; - const unsigned char *mp; - - if (NULL == archive_wstring_ensure(dest, - dest->length + length + 1)) - return (-1); - - ws = dest->s + dest->length; - mp = (const unsigned char *)s; - count = 0; - while (count < (int)length && *mp) { - *ws++ = (wchar_t)*mp++; - count++; - } - } else if (sc != NULL && - (sc->flag & (SCONV_NORMALIZATION_C | SCONV_NORMALIZATION_D))) { - /* - * Normalize UTF-8 and UTF-16BE and convert it directly - * to UTF-16 as wchar_t. - */ - struct archive_string u16; - int saved_flag = sc->flag;/* save current flag. */ - - if (is_big_endian()) - sc->flag |= SCONV_TO_UTF16BE; - else - sc->flag |= SCONV_TO_UTF16LE; - - if (sc->flag & SCONV_FROM_UTF16) { - /* - * UTF-16BE/LE NFD ===> UTF-16 NFC - * UTF-16BE/LE NFC ===> UTF-16 NFD - */ - count = (int)utf16nbytes(s, length); - } else { - /* - * UTF-8 NFD ===> UTF-16 NFC - * UTF-8 NFC ===> UTF-16 NFD - */ - count = (int)mbsnbytes(s, length); - } - u16.s = (char *)dest->s; - u16.length = dest->length << 1;; - u16.buffer_length = dest->buffer_length; - if (sc->flag & SCONV_NORMALIZATION_C) - ret = archive_string_normalize_C(&u16, s, count, sc); - else - ret = archive_string_normalize_D(&u16, s, count, sc); - dest->s = (wchar_t *)u16.s; - dest->length = u16.length >> 1; - dest->buffer_length = u16.buffer_length; - sc->flag = saved_flag;/* restore the saved flag. */ - return (ret); - } else if (sc != NULL && (sc->flag & SCONV_FROM_UTF16)) { - count = (int)utf16nbytes(s, length); - count >>= 1; /* to be WCS length */ - /* Allocate memory for WCS. */ - if (NULL == archive_wstring_ensure(dest, - dest->length + count + 1)) - return (-1); - wmemcpy(dest->s + dest->length, (const wchar_t *)s, count); - if ((sc->flag & SCONV_FROM_UTF16BE) && !is_big_endian()) { - uint16_t *u16 = (uint16_t *)(dest->s + dest->length); - int b; - for (b = 0; b < count; b++) { - uint16_t val = archive_le16dec(u16+b); - archive_be16enc(u16+b, val); - } - } else if ((sc->flag & SCONV_FROM_UTF16LE) && is_big_endian()) { - uint16_t *u16 = (uint16_t *)(dest->s + dest->length); - int b; - for (b = 0; b < count; b++) { - uint16_t val = archive_be16dec(u16+b); - archive_le16enc(u16+b, val); - } - } - } else { - DWORD mbflag; - size_t buffsize; - - if (sc == NULL) - mbflag = 0; - else if (sc->flag & SCONV_FROM_CHARSET) { - /* Do not trust the length which comes from - * an archive file. */ - length = mbsnbytes(s, length); - mbflag = 0; - } else - mbflag = MB_PRECOMPOSED; - - buffsize = dest->length + length + 1; - do { - /* Allocate memory for WCS. */ - if (NULL == archive_wstring_ensure(dest, buffsize)) - return (-1); - /* Convert MBS to WCS. */ - count = MultiByteToWideChar(from_cp, - mbflag, s, (int)length, dest->s + dest->length, - (int)(dest->buffer_length >> 1) -1); - if (count == 0 && - GetLastError() == ERROR_INSUFFICIENT_BUFFER) { - /* Expand the WCS buffer. */ - buffsize = dest->buffer_length << 1; - continue; - } - if (count == 0 && length != 0) - ret = -1; - break; - } while (1); - } - dest->length += count; - dest->s[dest->length] = L'\0'; - return (ret); -} - -#else - -/* - * Convert MBS to WCS. - * Note: returns -1 if conversion fails. - */ -int -archive_wstring_append_from_mbs(struct archive_wstring *dest, - const char *p, size_t len) -{ - size_t r; - int ret_val = 0; - /* - * No single byte will be more than one wide character, - * so this length estimate will always be big enough. - */ - // size_t wcs_length = len; - size_t mbs_length = len; - const char *mbs = p; - wchar_t *wcs; -#if HAVE_MBRTOWC - mbstate_t shift_state; - - memset(&shift_state, 0, sizeof(shift_state)); -#endif - /* - * As we decided to have wcs_length == mbs_length == len - * we can use len here instead of wcs_length - */ - if (NULL == archive_wstring_ensure(dest, dest->length + len + 1)) - return (-1); - wcs = dest->s + dest->length; - /* - * We cannot use mbsrtowcs/mbstowcs here because those may convert - * extra MBS when strlen(p) > len and one wide character consists of - * multi bytes. - */ - while (*mbs && mbs_length > 0) { - /* - * The buffer we allocated is always big enough. - * Keep this code path in a comment if we decide to choose - * smaller wcs_length in the future - */ -/* - if (wcs_length == 0) { - dest->length = wcs - dest->s; - dest->s[dest->length] = L'\0'; - wcs_length = mbs_length; - if (NULL == archive_wstring_ensure(dest, - dest->length + wcs_length + 1)) - return (-1); - wcs = dest->s + dest->length; - } -*/ -#if HAVE_MBRTOWC - r = mbrtowc(wcs, mbs, mbs_length, &shift_state); -#else - r = mbtowc(wcs, mbs, mbs_length); -#endif - if (r == (size_t)-1 || r == (size_t)-2) { - ret_val = -1; - break; - } - if (r == 0 || r > mbs_length) - break; - wcs++; - // wcs_length--; - mbs += r; - mbs_length -= r; - } - dest->length = wcs - dest->s; - dest->s[dest->length] = L'\0'; - return (ret_val); -} - -#endif - -#if defined(_WIN32) && !defined(__CYGWIN__) - -/* - * WCS ==> MBS. - * Note: returns -1 if conversion fails. - * - * Win32 builds use WideCharToMultiByte from the Windows API. - * (Maybe Cygwin should too? WideCharToMultiByte will know a - * lot more about local character encodings than the wcrtomb() - * wrapper is going to know.) - */ -int -archive_string_append_from_wcs(struct archive_string *as, - const wchar_t *w, size_t len) -{ - return archive_string_append_from_wcs_in_codepage(as, w, len, NULL); -} - -static int -archive_string_append_from_wcs_in_codepage(struct archive_string *as, - const wchar_t *ws, size_t len, struct archive_string_conv *sc) -{ - BOOL defchar_used, *dp; - int count, ret = 0; - UINT to_cp; - int wslen = (int)len; - - if (sc != NULL) - to_cp = sc->to_cp; - else - to_cp = get_current_codepage(); - - if (to_cp == CP_C_LOCALE) { - /* - * "C" locale special processing. - */ - const wchar_t *wp = ws; - char *p; - - if (NULL == archive_string_ensure(as, - as->length + wslen +1)) - return (-1); - p = as->s + as->length; - count = 0; - defchar_used = 0; - while (count < wslen && *wp) { - if (*wp > 255) { - *p++ = '?'; - wp++; - defchar_used = 1; - } else - *p++ = (char)*wp++; - count++; - } - } else if (sc != NULL && (sc->flag & SCONV_TO_UTF16)) { - uint16_t *u16; - - if (NULL == - archive_string_ensure(as, as->length + len * 2 + 2)) - return (-1); - u16 = (uint16_t *)(as->s + as->length); - count = 0; - defchar_used = 0; - if (sc->flag & SCONV_TO_UTF16BE) { - while (count < (int)len && *ws) { - archive_be16enc(u16+count, *ws); - ws++; - count++; - } - } else { - while (count < (int)len && *ws) { - archive_le16enc(u16+count, *ws); - ws++; - count++; - } - } - count <<= 1; /* to be byte size */ - } else { - /* Make sure the MBS buffer has plenty to set. */ - if (NULL == - archive_string_ensure(as, as->length + len * 2 + 1)) - return (-1); - do { - defchar_used = 0; - if (to_cp == CP_UTF8 || sc == NULL) - dp = NULL; - else - dp = &defchar_used; - count = WideCharToMultiByte(to_cp, 0, ws, wslen, - as->s + as->length, - (int)as->buffer_length - (int)as->length - 1, NULL, dp); - if (count == 0 && - GetLastError() == ERROR_INSUFFICIENT_BUFFER) { - /* Expand the MBS buffer and retry. */ - if (NULL == archive_string_ensure(as, - as->buffer_length + len)) - return (-1); - continue; - } - if (count == 0) - ret = -1; - break; - } while (1); - } - as->length += count; - as->s[as->length] = '\0'; - return (defchar_used?-1:ret); -} - -#elif defined(HAVE_WCTOMB) || defined(HAVE_WCRTOMB) - -/* - * Translates a wide character string into current locale character set - * and appends to the archive_string. Note: returns -1 if conversion - * fails. - */ -int -archive_string_append_from_wcs(struct archive_string *as, - const wchar_t *w, size_t len) -{ - /* We cannot use the standard wcstombs() here because it - * cannot tell us how big the output buffer should be. So - * I've built a loop around wcrtomb() or wctomb() that - * converts a character at a time and resizes the string as - * needed. We prefer wcrtomb() when it's available because - * it's thread-safe. */ - int n, ret_val = 0; - char *p; - char *end; -#if HAVE_WCRTOMB - mbstate_t shift_state; - - memset(&shift_state, 0, sizeof(shift_state)); -#else - /* Clear the shift state before starting. */ - wctomb(NULL, L'\0'); -#endif - /* - * Allocate buffer for MBS. - * We need this allocation here since it is possible that - * as->s is still NULL. - */ - if (archive_string_ensure(as, as->length + len + 1) == NULL) - return (-1); - - p = as->s + as->length; - end = as->s + as->buffer_length - MB_CUR_MAX -1; - while (*w != L'\0' && len > 0) { - if (p >= end) { - as->length = p - as->s; - as->s[as->length] = '\0'; - /* Re-allocate buffer for MBS. */ - if (archive_string_ensure(as, - as->length + max(len * 2, - (size_t)MB_CUR_MAX) + 1) == NULL) - return (-1); - p = as->s + as->length; - end = as->s + as->buffer_length - MB_CUR_MAX -1; - } -#if HAVE_WCRTOMB - n = wcrtomb(p, *w++, &shift_state); -#else - n = wctomb(p, *w++); -#endif - if (n == -1) { - if (errno == EILSEQ) { - /* Skip an illegal wide char. */ - *p++ = '?'; - ret_val = -1; - } else { - ret_val = -1; - break; - } - } else - p += n; - len--; - } - as->length = p - as->s; - as->s[as->length] = '\0'; - return (ret_val); -} - -#else /* HAVE_WCTOMB || HAVE_WCRTOMB */ - -/* - * TODO: Test if __STDC_ISO_10646__ is defined. - * Non-Windows uses ISO C wcrtomb() or wctomb() to perform the conversion - * one character at a time. If a non-Windows platform doesn't have - * either of these, fall back to the built-in UTF8 conversion. - */ -int -archive_string_append_from_wcs(struct archive_string *as, - const wchar_t *w, size_t len) -{ - (void)as;/* UNUSED */ - (void)w;/* UNUSED */ - (void)len;/* UNUSED */ - errno = ENOSYS; - return (-1); -} - -#endif /* HAVE_WCTOMB || HAVE_WCRTOMB */ - -/* - * Find a string conversion object by a pair of 'from' charset name - * and 'to' charset name from an archive object. - * Return NULL if not found. - */ -static struct archive_string_conv * -find_sconv_object(struct archive *a, const char *fc, const char *tc) -{ - struct archive_string_conv *sc; - - if (a == NULL) - return (NULL); - - for (sc = a->sconv; sc != NULL; sc = sc->next) { - if (strcmp(sc->from_charset, fc) == 0 && - strcmp(sc->to_charset, tc) == 0) - break; - } - return (sc); -} - -/* - * Register a string object to an archive object. - */ -static void -add_sconv_object(struct archive *a, struct archive_string_conv *sc) -{ - struct archive_string_conv **psc; - - /* Add a new sconv to sconv list. */ - psc = &(a->sconv); - while (*psc != NULL) - psc = &((*psc)->next); - *psc = sc; -} - -static void -add_converter(struct archive_string_conv *sc, int (*converter) - (struct archive_string *, const void *, size_t, - struct archive_string_conv *)) -{ - if (sc == NULL || sc->nconverter >= 2) - __archive_errx(1, "Programming error"); - sc->converter[sc->nconverter++] = converter; -} - -static void -setup_converter(struct archive_string_conv *sc) -{ - - /* Reset. */ - sc->nconverter = 0; - - /* - * Perform special sequence for the incorrect UTF-8 filenames - * made by libarchive2.x. - */ - if (sc->flag & SCONV_UTF8_LIBARCHIVE_2) { - add_converter(sc, strncat_from_utf8_libarchive2); - return; - } - - /* - * Convert a string to UTF-16BE/LE. - */ - if (sc->flag & SCONV_TO_UTF16) { - /* - * If the current locale is UTF-8, we can translate - * a UTF-8 string into a UTF-16BE string. - */ - if (sc->flag & SCONV_FROM_UTF8) { - add_converter(sc, archive_string_append_unicode); - return; - } - -#if defined(_WIN32) && !defined(__CYGWIN__) - if (sc->flag & SCONV_WIN_CP) { - if (sc->flag & SCONV_TO_UTF16BE) - add_converter(sc, win_strncat_to_utf16be); - else - add_converter(sc, win_strncat_to_utf16le); - return; - } -#endif - -#if defined(HAVE_ICONV) - if (sc->cd != (iconv_t)-1) { - add_converter(sc, iconv_strncat_in_locale); - return; - } -#endif - - if (sc->flag & SCONV_BEST_EFFORT) { - if (sc->flag & SCONV_TO_UTF16BE) - add_converter(sc, - best_effort_strncat_to_utf16be); - else - add_converter(sc, - best_effort_strncat_to_utf16le); - } else - /* Make sure we have no converter. */ - sc->nconverter = 0; - return; - } - - /* - * Convert a string from UTF-16BE/LE. - */ - if (sc->flag & SCONV_FROM_UTF16) { - /* - * At least we should normalize a UTF-16BE string. - */ - if (sc->flag & SCONV_NORMALIZATION_D) - add_converter(sc,archive_string_normalize_D); - else if (sc->flag & SCONV_NORMALIZATION_C) - add_converter(sc, archive_string_normalize_C); - - if (sc->flag & SCONV_TO_UTF8) { - /* - * If the current locale is UTF-8, we can translate - * a UTF-16BE/LE string into a UTF-8 string directly. - */ - if (!(sc->flag & - (SCONV_NORMALIZATION_D |SCONV_NORMALIZATION_C))) - add_converter(sc, - archive_string_append_unicode); - return; - } - -#if defined(_WIN32) && !defined(__CYGWIN__) - if (sc->flag & SCONV_WIN_CP) { - if (sc->flag & SCONV_FROM_UTF16BE) - add_converter(sc, win_strncat_from_utf16be); - else - add_converter(sc, win_strncat_from_utf16le); - return; - } -#endif - -#if defined(HAVE_ICONV) - if (sc->cd != (iconv_t)-1) { - add_converter(sc, iconv_strncat_in_locale); - return; - } -#endif - - if ((sc->flag & (SCONV_BEST_EFFORT | SCONV_FROM_UTF16BE)) - == (SCONV_BEST_EFFORT | SCONV_FROM_UTF16BE)) - add_converter(sc, best_effort_strncat_from_utf16be); - else if ((sc->flag & (SCONV_BEST_EFFORT | SCONV_FROM_UTF16LE)) - == (SCONV_BEST_EFFORT | SCONV_FROM_UTF16LE)) - add_converter(sc, best_effort_strncat_from_utf16le); - else - /* Make sure we have no converter. */ - sc->nconverter = 0; - return; - } - - if (sc->flag & SCONV_FROM_UTF8) { - /* - * At least we should normalize a UTF-8 string. - */ - if (sc->flag & SCONV_NORMALIZATION_D) - add_converter(sc,archive_string_normalize_D); - else if (sc->flag & SCONV_NORMALIZATION_C) - add_converter(sc, archive_string_normalize_C); - - /* - * Copy UTF-8 string with a check of CESU-8. - * Apparently, iconv does not check surrogate pairs in UTF-8 - * when both from-charset and to-charset are UTF-8, and then - * we use our UTF-8 copy code. - */ - if (sc->flag & SCONV_TO_UTF8) { - /* - * If the current locale is UTF-8, we can translate - * a UTF-16BE string into a UTF-8 string directly. - */ - if (!(sc->flag & - (SCONV_NORMALIZATION_D |SCONV_NORMALIZATION_C))) - add_converter(sc, strncat_from_utf8_to_utf8); - return; - } - } - -#if defined(_WIN32) && !defined(__CYGWIN__) - /* - * On Windows we can use Windows API for a string conversion. - */ - if (sc->flag & SCONV_WIN_CP) { - add_converter(sc, strncat_in_codepage); - return; - } -#endif - -#if HAVE_ICONV - if (sc->cd != (iconv_t)-1) { - add_converter(sc, iconv_strncat_in_locale); - /* - * iconv generally does not support UTF-8-MAC and so - * we have to the output of iconv from NFC to NFD if - * need. - */ - if ((sc->flag & SCONV_FROM_CHARSET) && - (sc->flag & SCONV_TO_UTF8)) { - if (sc->flag & SCONV_NORMALIZATION_D) - add_converter(sc, archive_string_normalize_D); - } - return; - } -#endif - - /* - * Try conversion in the best effort or no conversion. - */ - if ((sc->flag & SCONV_BEST_EFFORT) || sc->same) - add_converter(sc, best_effort_strncat_in_locale); - else - /* Make sure we have no converter. */ - sc->nconverter = 0; -} - -/* - * Return canonicalized charset-name but this supports just UTF-8, UTF-16BE - * and CP932 which are referenced in create_sconv_object(). - */ -static const char * -canonical_charset_name(const char *charset) -{ - char cs[16]; - char *p; - const char *s; - - if (charset == NULL || charset[0] == '\0' - || strlen(charset) > 15) - return (charset); - - /* Copy name to uppercase. */ - p = cs; - s = charset; - while (*s) { - char c = *s++; - if (c >= 'a' && c <= 'z') - c -= 'a' - 'A'; - *p++ = c; - } - *p++ = '\0'; - - if (strcmp(cs, "UTF-8") == 0 || - strcmp(cs, "UTF8") == 0) - return ("UTF-8"); - if (strcmp(cs, "UTF-16BE") == 0 || - strcmp(cs, "UTF16BE") == 0) - return ("UTF-16BE"); - if (strcmp(cs, "UTF-16LE") == 0 || - strcmp(cs, "UTF16LE") == 0) - return ("UTF-16LE"); - if (strcmp(cs, "CP932") == 0) - return ("CP932"); - return (charset); -} - -/* - * Create a string conversion object. - */ -static struct archive_string_conv * -create_sconv_object(const char *fc, const char *tc, - unsigned current_codepage, int flag) -{ - struct archive_string_conv *sc; - - sc = calloc(1, sizeof(*sc)); - if (sc == NULL) - return (NULL); - sc->next = NULL; - sc->from_charset = strdup(fc); - if (sc->from_charset == NULL) { - free(sc); - return (NULL); - } - sc->to_charset = strdup(tc); - if (sc->to_charset == NULL) { - free(sc->from_charset); - free(sc); - return (NULL); - } - archive_string_init(&sc->utftmp); - - if (flag & SCONV_TO_CHARSET) { - /* - * Convert characters from the current locale charset to - * a specified charset. - */ - sc->from_cp = current_codepage; - sc->to_cp = make_codepage_from_charset(tc); -#if defined(_WIN32) && !defined(__CYGWIN__) - if (IsValidCodePage(sc->to_cp)) - flag |= SCONV_WIN_CP; -#endif - } else if (flag & SCONV_FROM_CHARSET) { - /* - * Convert characters from a specified charset to - * the current locale charset. - */ - sc->to_cp = current_codepage; - sc->from_cp = make_codepage_from_charset(fc); -#if defined(_WIN32) && !defined(__CYGWIN__) - if (IsValidCodePage(sc->from_cp)) - flag |= SCONV_WIN_CP; -#endif - } - - /* - * Check if "from charset" and "to charset" are the same. - */ - if (strcmp(fc, tc) == 0 || - (sc->from_cp != (unsigned)-1 && sc->from_cp == sc->to_cp)) - sc->same = 1; - else - sc->same = 0; - - /* - * Mark if "from charset" or "to charset" are UTF-8 or UTF-16BE/LE. - */ - if (strcmp(tc, "UTF-8") == 0) - flag |= SCONV_TO_UTF8; - else if (strcmp(tc, "UTF-16BE") == 0) - flag |= SCONV_TO_UTF16BE; - else if (strcmp(tc, "UTF-16LE") == 0) - flag |= SCONV_TO_UTF16LE; - if (strcmp(fc, "UTF-8") == 0) - flag |= SCONV_FROM_UTF8; - else if (strcmp(fc, "UTF-16BE") == 0) - flag |= SCONV_FROM_UTF16BE; - else if (strcmp(fc, "UTF-16LE") == 0) - flag |= SCONV_FROM_UTF16LE; -#if defined(_WIN32) && !defined(__CYGWIN__) - if (sc->to_cp == CP_UTF8) - flag |= SCONV_TO_UTF8; - else if (sc->to_cp == CP_UTF16BE) - flag |= SCONV_TO_UTF16BE | SCONV_WIN_CP; - else if (sc->to_cp == CP_UTF16LE) - flag |= SCONV_TO_UTF16LE | SCONV_WIN_CP; - if (sc->from_cp == CP_UTF8) - flag |= SCONV_FROM_UTF8; - else if (sc->from_cp == CP_UTF16BE) - flag |= SCONV_FROM_UTF16BE | SCONV_WIN_CP; - else if (sc->from_cp == CP_UTF16LE) - flag |= SCONV_FROM_UTF16LE | SCONV_WIN_CP; -#endif - - /* - * Set a flag for Unicode NFD. Usually iconv cannot correctly - * handle it. So we have to translate NFD characters to NFC ones - * ourselves before iconv handles. Another reason is to prevent - * that the same sight of two filenames, one is NFC and other - * is NFD, would be in its directory. - * On Mac OS X, although its filesystem layer automatically - * convert filenames to NFD, it would be useful for filename - * comparing to find out the same filenames that we normalize - * that to be NFD ourselves. - */ - if ((flag & SCONV_FROM_CHARSET) && - (flag & (SCONV_FROM_UTF16 | SCONV_FROM_UTF8))) { -#if defined(__APPLE__) - if (flag & SCONV_TO_UTF8) - flag |= SCONV_NORMALIZATION_D; - else -#endif - flag |= SCONV_NORMALIZATION_C; - } -#if defined(__APPLE__) - /* - * In case writing an archive file, make sure that a filename - * going to be passed to iconv is a Unicode NFC string since - * a filename in HFS Plus filesystem is a Unicode NFD one and - * iconv cannot handle it with "UTF-8" charset. It is simpler - * than a use of "UTF-8-MAC" charset. - */ - if ((flag & SCONV_TO_CHARSET) && - (flag & (SCONV_FROM_UTF16 | SCONV_FROM_UTF8)) && - !(flag & (SCONV_TO_UTF16 | SCONV_TO_UTF8))) - flag |= SCONV_NORMALIZATION_C; - /* - * In case reading an archive file. make sure that a filename - * will be passed to users is a Unicode NFD string in order to - * correctly compare the filename with other one which comes - * from HFS Plus filesystem. - */ - if ((flag & SCONV_FROM_CHARSET) && - !(flag & (SCONV_FROM_UTF16 | SCONV_FROM_UTF8)) && - (flag & SCONV_TO_UTF8)) - flag |= SCONV_NORMALIZATION_D; -#endif - -#if defined(HAVE_ICONV) - sc->cd_w = (iconv_t)-1; - /* - * Create an iconv object. - */ - if (((flag & (SCONV_TO_UTF8 | SCONV_TO_UTF16)) && - (flag & (SCONV_FROM_UTF8 | SCONV_FROM_UTF16))) || - (flag & SCONV_WIN_CP)) { - /* This case we won't use iconv. */ - sc->cd = (iconv_t)-1; - } else { - sc->cd = iconv_open(tc, fc); - if (sc->cd == (iconv_t)-1 && (sc->flag & SCONV_BEST_EFFORT)) { - /* - * Unfortunately, all of iconv implements do support - * "CP932" character-set, so we should use "SJIS" - * instead if iconv_open failed. - */ - if (strcmp(tc, "CP932") == 0) - sc->cd = iconv_open("SJIS", fc); - else if (strcmp(fc, "CP932") == 0) - sc->cd = iconv_open(tc, "SJIS"); - } -#if defined(_WIN32) && !defined(__CYGWIN__) - /* - * archive_mstring on Windows directly convert multi-bytes - * into archive_wstring in order not to depend on locale - * so that you can do a I18N programming. This will be - * used only in archive_mstring_copy_mbs_len_l so far. - */ - if (flag & SCONV_FROM_CHARSET) { - sc->cd_w = iconv_open("UTF-8", fc); - if (sc->cd_w == (iconv_t)-1 && - (sc->flag & SCONV_BEST_EFFORT)) { - if (strcmp(fc, "CP932") == 0) - sc->cd_w = iconv_open("UTF-8", "SJIS"); - } - } -#endif /* _WIN32 && !__CYGWIN__ */ - } -#endif /* HAVE_ICONV */ - - sc->flag = flag; - - /* - * Set up converters. - */ - setup_converter(sc); - - return (sc); -} - -/* - * Free a string conversion object. - */ -static void -free_sconv_object(struct archive_string_conv *sc) -{ - free(sc->from_charset); - free(sc->to_charset); - archive_string_free(&sc->utftmp); -#if HAVE_ICONV - if (sc->cd != (iconv_t)-1) - iconv_close(sc->cd); - if (sc->cd_w != (iconv_t)-1) - iconv_close(sc->cd_w); -#endif - free(sc); -} - -#if defined(_WIN32) && !defined(__CYGWIN__) -# if defined(WINAPI_FAMILY_PARTITION) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) -# define GetOEMCP() CP_OEMCP -# endif - -static unsigned -my_atoi(const char *p) -{ - unsigned cp; - - cp = 0; - while (*p) { - if (*p >= '0' && *p <= '9') - cp = cp * 10 + (*p - '0'); - else - return (-1); - p++; - } - return (cp); -} - -/* - * Translate Charset name (as used by iconv) into CodePage (as used by Windows) - * Return -1 if failed. - * - * Note: This translation code may be insufficient. - */ -static struct charset { - const char *name; - unsigned cp; -} charsets[] = { - /* MUST BE SORTED! */ - {"ASCII", 1252}, - {"ASMO-708", 708}, - {"BIG5", 950}, - {"CHINESE", 936}, - {"CP367", 1252}, - {"CP819", 1252}, - {"CP1025", 21025}, - {"DOS-720", 720}, - {"DOS-862", 862}, - {"EUC-CN", 51936}, - {"EUC-JP", 51932}, - {"EUC-KR", 949}, - {"EUCCN", 51936}, - {"EUCJP", 51932}, - {"EUCKR", 949}, - {"GB18030", 54936}, - {"GB2312", 936}, - {"HEBREW", 1255}, - {"HZ-GB-2312", 52936}, - {"IBM273", 20273}, - {"IBM277", 20277}, - {"IBM278", 20278}, - {"IBM280", 20280}, - {"IBM284", 20284}, - {"IBM285", 20285}, - {"IBM290", 20290}, - {"IBM297", 20297}, - {"IBM367", 1252}, - {"IBM420", 20420}, - {"IBM423", 20423}, - {"IBM424", 20424}, - {"IBM819", 1252}, - {"IBM871", 20871}, - {"IBM880", 20880}, - {"IBM905", 20905}, - {"IBM924", 20924}, - {"ISO-8859-1", 28591}, - {"ISO-8859-13", 28603}, - {"ISO-8859-15", 28605}, - {"ISO-8859-2", 28592}, - {"ISO-8859-3", 28593}, - {"ISO-8859-4", 28594}, - {"ISO-8859-5", 28595}, - {"ISO-8859-6", 28596}, - {"ISO-8859-7", 28597}, - {"ISO-8859-8", 28598}, - {"ISO-8859-9", 28599}, - {"ISO8859-1", 28591}, - {"ISO8859-13", 28603}, - {"ISO8859-15", 28605}, - {"ISO8859-2", 28592}, - {"ISO8859-3", 28593}, - {"ISO8859-4", 28594}, - {"ISO8859-5", 28595}, - {"ISO8859-6", 28596}, - {"ISO8859-7", 28597}, - {"ISO8859-8", 28598}, - {"ISO8859-9", 28599}, - {"JOHAB", 1361}, - {"KOI8-R", 20866}, - {"KOI8-U", 21866}, - {"KS_C_5601-1987", 949}, - {"LATIN1", 1252}, - {"LATIN2", 28592}, - {"MACINTOSH", 10000}, - {"SHIFT-JIS", 932}, - {"SHIFT_JIS", 932}, - {"SJIS", 932}, - {"US", 1252}, - {"US-ASCII", 1252}, - {"UTF-16", 1200}, - {"UTF-16BE", 1201}, - {"UTF-16LE", 1200}, - {"UTF-8", CP_UTF8}, - {"X-EUROPA", 29001}, - {"X-MAC-ARABIC", 10004}, - {"X-MAC-CE", 10029}, - {"X-MAC-CHINESEIMP", 10008}, - {"X-MAC-CHINESETRAD", 10002}, - {"X-MAC-CROATIAN", 10082}, - {"X-MAC-CYRILLIC", 10007}, - {"X-MAC-GREEK", 10006}, - {"X-MAC-HEBREW", 10005}, - {"X-MAC-ICELANDIC", 10079}, - {"X-MAC-JAPANESE", 10001}, - {"X-MAC-KOREAN", 10003}, - {"X-MAC-ROMANIAN", 10010}, - {"X-MAC-THAI", 10021}, - {"X-MAC-TURKISH", 10081}, - {"X-MAC-UKRAINIAN", 10017}, -}; -static unsigned -make_codepage_from_charset(const char *charset) -{ - char cs[16]; - char *p; - unsigned cp; - int a, b; - - if (charset == NULL || strlen(charset) > 15) - return -1; - - /* Copy name to uppercase. */ - p = cs; - while (*charset) { - char c = *charset++; - if (c >= 'a' && c <= 'z') - c -= 'a' - 'A'; - *p++ = c; - } - *p++ = '\0'; - cp = -1; - - /* Look it up in the table first, so that we can easily - * override CP367, which we map to 1252 instead of 367. */ - a = 0; - b = sizeof(charsets)/sizeof(charsets[0]); - while (b > a) { - int c = (b + a) / 2; - int r = strcmp(charsets[c].name, cs); - if (r < 0) - a = c + 1; - else if (r > 0) - b = c; - else - return charsets[c].cp; - } - - /* If it's not in the table, try to parse it. */ - switch (*cs) { - case 'C': - if (cs[1] == 'P' && cs[2] >= '0' && cs[2] <= '9') { - cp = my_atoi(cs + 2); - } else if (strcmp(cs, "CP_ACP") == 0) - cp = get_current_codepage(); - else if (strcmp(cs, "CP_OEMCP") == 0) - cp = get_current_oemcp(); - break; - case 'I': - if (cs[1] == 'B' && cs[2] == 'M' && - cs[3] >= '0' && cs[3] <= '9') { - cp = my_atoi(cs + 3); - } - break; - case 'W': - if (strncmp(cs, "WINDOWS-", 8) == 0) { - cp = my_atoi(cs + 8); - if (cp != 874 && (cp < 1250 || cp > 1258)) - cp = -1;/* This may invalid code. */ - } - break; - } - return (cp); -} - -/* - * Return ANSI Code Page of current locale set by setlocale(). - */ -static unsigned -get_current_codepage(void) -{ - char *locale, *p; - unsigned cp; - - locale = setlocale(LC_CTYPE, NULL); - if (locale == NULL) - return (GetACP()); - if (locale[0] == 'C' && locale[1] == '\0') - return (CP_C_LOCALE); - p = strrchr(locale, '.'); - if (p == NULL) - return (GetACP()); - if (strcmp(p+1, "utf8") == 0) - return CP_UTF8; - cp = my_atoi(p+1); - if ((int)cp <= 0) - return (GetACP()); - return (cp); -} - -/* - * Translation table between Locale Name and ACP/OEMCP. - */ -static struct { - unsigned acp; - unsigned ocp; - const char *locale; -} acp_ocp_map[] = { - { 950, 950, "Chinese_Taiwan" }, - { 936, 936, "Chinese_People's Republic of China" }, - { 950, 950, "Chinese_Taiwan" }, - { 1250, 852, "Czech_Czech Republic" }, - { 1252, 850, "Danish_Denmark" }, - { 1252, 850, "Dutch_Netherlands" }, - { 1252, 850, "Dutch_Belgium" }, - { 1252, 437, "English_United States" }, - { 1252, 850, "English_Australia" }, - { 1252, 850, "English_Canada" }, - { 1252, 850, "English_New Zealand" }, - { 1252, 850, "English_United Kingdom" }, - { 1252, 437, "English_United States" }, - { 1252, 850, "Finnish_Finland" }, - { 1252, 850, "French_France" }, - { 1252, 850, "French_Belgium" }, - { 1252, 850, "French_Canada" }, - { 1252, 850, "French_Switzerland" }, - { 1252, 850, "German_Germany" }, - { 1252, 850, "German_Austria" }, - { 1252, 850, "German_Switzerland" }, - { 1253, 737, "Greek_Greece" }, - { 1250, 852, "Hungarian_Hungary" }, - { 1252, 850, "Icelandic_Iceland" }, - { 1252, 850, "Italian_Italy" }, - { 1252, 850, "Italian_Switzerland" }, - { 932, 932, "Japanese_Japan" }, - { 949, 949, "Korean_Korea" }, - { 1252, 850, "Norwegian (BokmOl)_Norway" }, - { 1252, 850, "Norwegian (BokmOl)_Norway" }, - { 1252, 850, "Norwegian-Nynorsk_Norway" }, - { 1250, 852, "Polish_Poland" }, - { 1252, 850, "Portuguese_Portugal" }, - { 1252, 850, "Portuguese_Brazil" }, - { 1251, 866, "Russian_Russia" }, - { 1250, 852, "Slovak_Slovakia" }, - { 1252, 850, "Spanish_Spain" }, - { 1252, 850, "Spanish_Mexico" }, - { 1252, 850, "Spanish_Spain" }, - { 1252, 850, "Swedish_Sweden" }, - { 1254, 857, "Turkish_Turkey" }, - { 0, 0, NULL} -}; - -/* - * Return OEM Code Page of current locale set by setlocale(). - */ -static unsigned -get_current_oemcp(void) -{ - int i; - char *locale, *p; - size_t len; - - locale = setlocale(LC_CTYPE, NULL); - if (locale == NULL) - return (GetOEMCP()); - if (locale[0] == 'C' && locale[1] == '\0') - return (CP_C_LOCALE); - - p = strrchr(locale, '.'); - if (p == NULL) - return (GetOEMCP()); - len = p - locale; - for (i = 0; acp_ocp_map[i].acp; i++) { - if (strncmp(acp_ocp_map[i].locale, locale, len) == 0) - return (acp_ocp_map[i].ocp); - } - return (GetOEMCP()); -} -#else - -/* - * POSIX platform does not use CodePage. - */ - -static unsigned -get_current_codepage(void) -{ - return (-1);/* Unknown */ -} -static unsigned -make_codepage_from_charset(const char *charset) -{ - (void)charset; /* UNUSED */ - return (-1);/* Unknown */ -} -static unsigned -get_current_oemcp(void) -{ - return (-1);/* Unknown */ -} - -#endif /* defined(_WIN32) && !defined(__CYGWIN__) */ - -/* - * Return a string conversion object. - */ -static struct archive_string_conv * -get_sconv_object(struct archive *a, const char *fc, const char *tc, int flag) -{ - struct archive_string_conv *sc; - unsigned current_codepage; - - /* Check if we have made the sconv object. */ - sc = find_sconv_object(a, fc, tc); - if (sc != NULL) - return (sc); - - if (a == NULL) - current_codepage = get_current_codepage(); - else - current_codepage = a->current_codepage; - - sc = create_sconv_object(canonical_charset_name(fc), - canonical_charset_name(tc), current_codepage, flag); - if (sc == NULL) { - if (a != NULL) - archive_set_error(a, ENOMEM, - "Could not allocate memory for " - "a string conversion object"); - return (NULL); - } - - /* - * If there is no converter for current string conversion object, - * we cannot handle this conversion. - */ - if (sc->nconverter == 0) { - if (a != NULL) { -#if HAVE_ICONV - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "iconv_open failed : Cannot handle ``%s''", - (flag & SCONV_TO_CHARSET)?tc:fc); -#else - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "A character-set conversion not fully supported " - "on this platform"); -#endif - } - /* Failed; free a sconv object. */ - free_sconv_object(sc); - return (NULL); - } - - /* - * Success! - */ - if (a != NULL) - add_sconv_object(a, sc); - return (sc); -} - -static const char * -get_current_charset(struct archive *a) -{ - const char *cur_charset; - - if (a == NULL) - cur_charset = default_iconv_charset(""); - else { - cur_charset = default_iconv_charset(a->current_code); - if (a->current_code == NULL) { - a->current_code = strdup(cur_charset); - a->current_codepage = get_current_codepage(); - a->current_oemcp = get_current_oemcp(); - } - } - return (cur_charset); -} - -/* - * Make and Return a string conversion object. - * Return NULL if the platform does not support the specified conversion - * and best_effort is 0. - * If best_effort is set, A string conversion object must be returned - * unless memory allocation for the object fails, but the conversion - * might fail when non-ASCII code is found. - */ -struct archive_string_conv * -archive_string_conversion_to_charset(struct archive *a, const char *charset, - int best_effort) -{ - int flag = SCONV_TO_CHARSET; - - if (best_effort) - flag |= SCONV_BEST_EFFORT; - return (get_sconv_object(a, get_current_charset(a), charset, flag)); -} - -struct archive_string_conv * -archive_string_conversion_from_charset(struct archive *a, const char *charset, - int best_effort) -{ - int flag = SCONV_FROM_CHARSET; - - if (best_effort) - flag |= SCONV_BEST_EFFORT; - return (get_sconv_object(a, charset, get_current_charset(a), flag)); -} - -/* - * archive_string_default_conversion_*_archive() are provided for Windows - * platform because other archiver application use CP_OEMCP for - * MultiByteToWideChar() and WideCharToMultiByte() for the filenames - * in tar or zip files. But mbstowcs/wcstombs(CRT) usually use CP_ACP - * unless you use setlocale(LC_ALL, ".OCP")(specify CP_OEMCP). - * So we should make a string conversion between CP_ACP and CP_OEMCP - * for compatibility. - */ -#if defined(_WIN32) && !defined(__CYGWIN__) -struct archive_string_conv * -archive_string_default_conversion_for_read(struct archive *a) -{ - const char *cur_charset = get_current_charset(a); - char oemcp[16]; - - /* NOTE: a check of cur_charset is unneeded but we need - * that get_current_charset() has been surely called at - * this time whatever C compiler optimized. */ - if (cur_charset != NULL && - (a->current_codepage == CP_C_LOCALE || - a->current_codepage == a->current_oemcp)) - return (NULL);/* no conversion. */ - - _snprintf(oemcp, sizeof(oemcp)-1, "CP%d", a->current_oemcp); - /* Make sure a null termination must be set. */ - oemcp[sizeof(oemcp)-1] = '\0'; - return (get_sconv_object(a, oemcp, cur_charset, - SCONV_FROM_CHARSET)); -} - -struct archive_string_conv * -archive_string_default_conversion_for_write(struct archive *a) -{ - const char *cur_charset = get_current_charset(a); - char oemcp[16]; - - /* NOTE: a check of cur_charset is unneeded but we need - * that get_current_charset() has been surely called at - * this time whatever C compiler optimized. */ - if (cur_charset != NULL && - (a->current_codepage == CP_C_LOCALE || - a->current_codepage == a->current_oemcp)) - return (NULL);/* no conversion. */ - - _snprintf(oemcp, sizeof(oemcp)-1, "CP%d", a->current_oemcp); - /* Make sure a null termination must be set. */ - oemcp[sizeof(oemcp)-1] = '\0'; - return (get_sconv_object(a, cur_charset, oemcp, - SCONV_TO_CHARSET)); -} -#else -struct archive_string_conv * -archive_string_default_conversion_for_read(struct archive *a) -{ - (void)a; /* UNUSED */ - return (NULL); -} - -struct archive_string_conv * -archive_string_default_conversion_for_write(struct archive *a) -{ - (void)a; /* UNUSED */ - return (NULL); -} -#endif - -/* - * Dispose of all character conversion objects in the archive object. - */ -void -archive_string_conversion_free(struct archive *a) -{ - struct archive_string_conv *sc; - struct archive_string_conv *sc_next; - - for (sc = a->sconv; sc != NULL; sc = sc_next) { - sc_next = sc->next; - free_sconv_object(sc); - } - a->sconv = NULL; - free(a->current_code); - a->current_code = NULL; -} - -/* - * Return a conversion charset name. - */ -const char * -archive_string_conversion_charset_name(struct archive_string_conv *sc) -{ - if (sc->flag & SCONV_TO_CHARSET) - return (sc->to_charset); - else - return (sc->from_charset); -} - -/* - * Change the behavior of a string conversion. - */ -void -archive_string_conversion_set_opt(struct archive_string_conv *sc, int opt) -{ - switch (opt) { - /* - * A filename in UTF-8 was made with libarchive 2.x in a wrong - * assumption that wchar_t was Unicode. - * This option enables simulating the assumption in order to read - * that filename correctly. - */ - case SCONV_SET_OPT_UTF8_LIBARCHIVE2X: -#if (defined(_WIN32) && !defined(__CYGWIN__)) \ - || defined(__STDC_ISO_10646__) || defined(__APPLE__) - /* - * Nothing to do for it since wchar_t on these platforms - * is really Unicode. - */ - (void)sc; /* UNUSED */ -#else - if ((sc->flag & SCONV_UTF8_LIBARCHIVE_2) == 0) { - sc->flag |= SCONV_UTF8_LIBARCHIVE_2; - /* Set up string converters. */ - setup_converter(sc); - } -#endif - break; - case SCONV_SET_OPT_NORMALIZATION_C: - if ((sc->flag & SCONV_NORMALIZATION_C) == 0) { - sc->flag |= SCONV_NORMALIZATION_C; - sc->flag &= ~SCONV_NORMALIZATION_D; - /* Set up string converters. */ - setup_converter(sc); - } - break; - case SCONV_SET_OPT_NORMALIZATION_D: -#if defined(HAVE_ICONV) - /* - * If iconv will take the string, do not change the - * setting of the normalization. - */ - if (!(sc->flag & SCONV_WIN_CP) && - (sc->flag & (SCONV_FROM_UTF16 | SCONV_FROM_UTF8)) && - !(sc->flag & (SCONV_TO_UTF16 | SCONV_TO_UTF8))) - break; -#endif - if ((sc->flag & SCONV_NORMALIZATION_D) == 0) { - sc->flag |= SCONV_NORMALIZATION_D; - sc->flag &= ~SCONV_NORMALIZATION_C; - /* Set up string converters. */ - setup_converter(sc); - } - break; - default: - break; - } -} - -/* - * - * Copy one archive_string to another in locale conversion. - * - * archive_strncat_l(); - * archive_strncpy_l(); - * - */ - -static size_t -mbsnbytes(const void *_p, size_t n) -{ - size_t s; - const char *p, *pp; - - if (_p == NULL) - return (0); - p = (const char *)_p; - - /* Like strlen(p), except won't examine positions beyond p[n]. */ - s = 0; - pp = p; - while (s < n && *pp) { - pp++; - s++; - } - return (s); -} - -static size_t -utf16nbytes(const void *_p, size_t n) -{ - size_t s; - const char *p, *pp; - - if (_p == NULL) - return (0); - p = (const char *)_p; - - /* Like strlen(p), except won't examine positions beyond p[n]. */ - s = 0; - pp = p; - n >>= 1; - while (s < n && (pp[0] || pp[1])) { - pp += 2; - s++; - } - return (s<<1); -} - -int -archive_strncpy_l(struct archive_string *as, const void *_p, size_t n, - struct archive_string_conv *sc) -{ - as->length = 0; - return (archive_strncat_l(as, _p, n, sc)); -} - -int -archive_strncat_l(struct archive_string *as, const void *_p, size_t n, - struct archive_string_conv *sc) -{ - const void *s; - size_t length = 0; - int i, r = 0, r2; - - if (_p != NULL && n > 0) { - if (sc != NULL && (sc->flag & SCONV_FROM_UTF16)) - length = utf16nbytes(_p, n); - else - length = mbsnbytes(_p, n); - } - - /* We must allocate memory even if there is no data for conversion - * or copy. This simulates archive_string_append behavior. */ - if (length == 0) { - int tn = 1; - if (sc != NULL && (sc->flag & SCONV_TO_UTF16)) - tn = 2; - if (archive_string_ensure(as, as->length + tn) == NULL) - return (-1); - as->s[as->length] = 0; - if (tn == 2) - as->s[as->length+1] = 0; - return (0); - } - - /* - * If sc is NULL, we just make a copy. - */ - if (sc == NULL) { - if (archive_string_append(as, _p, length) == NULL) - return (-1);/* No memory */ - return (0); - } - - s = _p; - i = 0; - if (sc->nconverter > 1) { - sc->utftmp.length = 0; - r2 = sc->converter[0](&(sc->utftmp), s, length, sc); - if (r2 != 0 && errno == ENOMEM) - return (r2); - if (r > r2) - r = r2; - s = sc->utftmp.s; - length = sc->utftmp.length; - ++i; - } - r2 = sc->converter[i](as, s, length, sc); - if (r > r2) - r = r2; - return (r); -} - -#if HAVE_ICONV - -/* - * Return -1 if conversion fails. - */ -static int -iconv_strncat_in_locale(struct archive_string *as, const void *_p, - size_t length, struct archive_string_conv *sc) -{ - ICONV_CONST char *itp; - size_t remaining; - iconv_t cd; - char *outp; - size_t avail, bs; - int return_value = 0; /* success */ - int to_size, from_size; - - if (sc->flag & SCONV_TO_UTF16) - to_size = 2; - else - to_size = 1; - if (sc->flag & SCONV_FROM_UTF16) - from_size = 2; - else - from_size = 1; - - if (archive_string_ensure(as, as->length + length*2+to_size) == NULL) - return (-1); - - cd = sc->cd; - itp = (char *)(uintptr_t)_p; - remaining = length; - outp = as->s + as->length; - avail = as->buffer_length - as->length - to_size; - while (remaining >= (size_t)from_size) { - size_t result = iconv(cd, &itp, &remaining, &outp, &avail); - - if (result != (size_t)-1) - break; /* Conversion completed. */ - - if (errno == EILSEQ || errno == EINVAL) { - /* - * If an output charset is UTF-8 or UTF-16BE/LE, - * unknown character should be U+FFFD - * (replacement character). - */ - if (sc->flag & (SCONV_TO_UTF8 | SCONV_TO_UTF16)) { - size_t rbytes; - if (sc->flag & SCONV_TO_UTF8) - rbytes = sizeof(utf8_replacement_char); - else - rbytes = 2; - - if (avail < rbytes) { - as->length = outp - as->s; - bs = as->buffer_length + - (remaining * to_size) + rbytes; - if (NULL == - archive_string_ensure(as, bs)) - return (-1); - outp = as->s + as->length; - avail = as->buffer_length - - as->length - to_size; - } - if (sc->flag & SCONV_TO_UTF8) - memcpy(outp, utf8_replacement_char, sizeof(utf8_replacement_char)); - else if (sc->flag & SCONV_TO_UTF16BE) - archive_be16enc(outp, UNICODE_R_CHAR); - else - archive_le16enc(outp, UNICODE_R_CHAR); - outp += rbytes; - avail -= rbytes; - } else { - /* Skip the illegal input bytes. */ - *outp++ = '?'; - avail--; - } - itp += from_size; - remaining -= from_size; - return_value = -1; /* failure */ - } else { - /* E2BIG no output buffer, - * Increase an output buffer. */ - as->length = outp - as->s; - bs = as->buffer_length + remaining * 2; - if (NULL == archive_string_ensure(as, bs)) - return (-1); - outp = as->s + as->length; - avail = as->buffer_length - as->length - to_size; - } - } - as->length = outp - as->s; - as->s[as->length] = 0; - if (to_size == 2) - as->s[as->length+1] = 0; - return (return_value); -} - -#endif /* HAVE_ICONV */ - - -#if defined(_WIN32) && !defined(__CYGWIN__) - -/* - * Translate a string from a some CodePage to an another CodePage by - * Windows APIs, and copy the result. Return -1 if conversion fails. - */ -static int -strncat_in_codepage(struct archive_string *as, - const void *_p, size_t length, struct archive_string_conv *sc) -{ - const char *s = (const char *)_p; - struct archive_wstring aws; - size_t l; - int r, saved_flag; - - archive_string_init(&aws); - saved_flag = sc->flag; - sc->flag &= ~(SCONV_NORMALIZATION_D | SCONV_NORMALIZATION_C); - r = archive_wstring_append_from_mbs_in_codepage(&aws, s, length, sc); - sc->flag = saved_flag; - if (r != 0) { - archive_wstring_free(&aws); - if (errno != ENOMEM) - archive_string_append(as, s, length); - return (-1); - } - - l = as->length; - r = archive_string_append_from_wcs_in_codepage( - as, aws.s, aws.length, sc); - if (r != 0 && errno != ENOMEM && l == as->length) - archive_string_append(as, s, length); - archive_wstring_free(&aws); - return (r); -} - -/* - * Test whether MBS ==> WCS is okay. - */ -static int -invalid_mbs(const void *_p, size_t n, struct archive_string_conv *sc) -{ - const char *p = (const char *)_p; - unsigned codepage; - DWORD mbflag = MB_ERR_INVALID_CHARS; - - if (sc->flag & SCONV_FROM_CHARSET) - codepage = sc->to_cp; - else - codepage = sc->from_cp; - - if (codepage == CP_C_LOCALE) - return (0); - if (codepage != CP_UTF8) - mbflag |= MB_PRECOMPOSED; - - if (MultiByteToWideChar(codepage, mbflag, p, (int)n, NULL, 0) == 0) - return (-1); /* Invalid */ - return (0); /* Okay */ -} - -#else - -/* - * Test whether MBS ==> WCS is okay. - */ -static int -invalid_mbs(const void *_p, size_t n, struct archive_string_conv *sc) -{ - const char *p = (const char *)_p; - size_t r; - -#if HAVE_MBRTOWC - mbstate_t shift_state; - - memset(&shift_state, 0, sizeof(shift_state)); -#else - /* Clear the shift state before starting. */ - mbtowc(NULL, NULL, 0); -#endif - while (n) { - wchar_t wc; - -#if HAVE_MBRTOWC - r = mbrtowc(&wc, p, n, &shift_state); -#else - r = mbtowc(&wc, p, n); -#endif - if (r == (size_t)-1 || r == (size_t)-2) - return (-1);/* Invalid. */ - if (r == 0) - break; - p += r; - n -= r; - } - (void)sc; /* UNUSED */ - return (0); /* All Okey. */ -} - -#endif /* defined(_WIN32) && !defined(__CYGWIN__) */ - -/* - * Basically returns -1 because we cannot make a conversion of charset - * without iconv but in some cases this would return 0. - * Returns 0 if all copied characters are ASCII. - * Returns 0 if both from-locale and to-locale are the same and those - * can be WCS with no error. - */ -static int -best_effort_strncat_in_locale(struct archive_string *as, const void *_p, - size_t length, struct archive_string_conv *sc) -{ - size_t remaining; - const uint8_t *itp; - int return_value = 0; /* success */ - - /* - * If both from-locale and to-locale is the same, this makes a copy. - * And then this checks all copied MBS can be WCS if so returns 0. - */ - if (sc->same) { - if (archive_string_append(as, _p, length) == NULL) - return (-1);/* No memory */ - return (invalid_mbs(_p, length, sc)); - } - - /* - * If a character is ASCII, this just copies it. If not, this - * assigns '?' character instead but in UTF-8 locale this assigns - * byte sequence 0xEF 0xBD 0xBD, which are code point U+FFFD, - * a Replacement Character in Unicode. - */ - - remaining = length; - itp = (const uint8_t *)_p; - while (*itp && remaining > 0) { - if (*itp > 127) { - // Non-ASCII: Substitute with suitable replacement - if (sc->flag & SCONV_TO_UTF8) { - if (archive_string_append(as, utf8_replacement_char, sizeof(utf8_replacement_char)) == NULL) { - __archive_errx(1, "Out of memory"); - } - } else { - archive_strappend_char(as, '?'); - } - return_value = -1; - } else { - archive_strappend_char(as, *itp); - } - ++itp; - } - return (return_value); -} - - -/* - * Unicode conversion functions. - * - UTF-8 <===> UTF-8 in removing surrogate pairs. - * - UTF-8 NFD ===> UTF-8 NFC in removing surrogate pairs. - * - UTF-8 made by libarchive 2.x ===> UTF-8. - * - UTF-16BE <===> UTF-8. - * - */ - -/* - * Utility to convert a single UTF-8 sequence. - * - * Usually return used bytes, return used byte in negative value when - * a unicode character is replaced with U+FFFD. - * See also http://unicode.org/review/pr-121.html Public Review Issue #121 - * Recommended Practice for Replacement Characters. - */ -static int -_utf8_to_unicode(uint32_t *pwc, const char *s, size_t n) -{ - static const char utf8_count[256] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 00 - 0F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 10 - 1F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 20 - 2F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 30 - 3F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40 - 4F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 50 - 5F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 60 - 6F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 70 - 7F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 80 - 8F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 90 - 9F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* A0 - AF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* B0 - BF */ - 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,/* C0 - CF */ - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,/* D0 - DF */ - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,/* E0 - EF */ - 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* F0 - FF */ - }; - int ch, i; - int cnt; - uint32_t wc; - - /* Sanity check. */ - if (n == 0) - return (0); - /* - * Decode 1-4 bytes depending on the value of the first byte. - */ - ch = (unsigned char)*s; - if (ch == 0) - return (0); /* Standard: return 0 for end-of-string. */ - cnt = utf8_count[ch]; - - /* Invalid sequence or there are not plenty bytes. */ - if ((int)n < cnt) { - cnt = (int)n; - for (i = 1; i < cnt; i++) { - if ((s[i] & 0xc0) != 0x80) { - cnt = i; - break; - } - } - goto invalid_sequence; - } - - /* Make a Unicode code point from a single UTF-8 sequence. */ - switch (cnt) { - case 1: /* 1 byte sequence. */ - *pwc = ch & 0x7f; - return (cnt); - case 2: /* 2 bytes sequence. */ - if ((s[1] & 0xc0) != 0x80) { - cnt = 1; - goto invalid_sequence; - } - *pwc = ((ch & 0x1f) << 6) | (s[1] & 0x3f); - return (cnt); - case 3: /* 3 bytes sequence. */ - if ((s[1] & 0xc0) != 0x80) { - cnt = 1; - goto invalid_sequence; - } - if ((s[2] & 0xc0) != 0x80) { - cnt = 2; - goto invalid_sequence; - } - wc = ((ch & 0x0f) << 12) - | ((s[1] & 0x3f) << 6) - | (s[2] & 0x3f); - if (wc < 0x800) - goto invalid_sequence;/* Overlong sequence. */ - break; - case 4: /* 4 bytes sequence. */ - if ((s[1] & 0xc0) != 0x80) { - cnt = 1; - goto invalid_sequence; - } - if ((s[2] & 0xc0) != 0x80) { - cnt = 2; - goto invalid_sequence; - } - if ((s[3] & 0xc0) != 0x80) { - cnt = 3; - goto invalid_sequence; - } - wc = ((ch & 0x07) << 18) - | ((s[1] & 0x3f) << 12) - | ((s[2] & 0x3f) << 6) - | (s[3] & 0x3f); - if (wc < 0x10000) - goto invalid_sequence;/* Overlong sequence. */ - break; - default: /* Others are all invalid sequence. */ - if (ch == 0xc0 || ch == 0xc1) - cnt = 2; - else if (ch >= 0xf5 && ch <= 0xf7) - cnt = 4; - else if (ch >= 0xf8 && ch <= 0xfb) - cnt = 5; - else if (ch == 0xfc || ch == 0xfd) - cnt = 6; - else - cnt = 1; - if ((int)n < cnt) - cnt = (int)n; - for (i = 1; i < cnt; i++) { - if ((s[i] & 0xc0) != 0x80) { - cnt = i; - break; - } - } - goto invalid_sequence; - } - - /* The code point larger than 0x10FFFF is not legal - * Unicode values. */ - if (wc > UNICODE_MAX) - goto invalid_sequence; - /* Correctly gets a Unicode, returns used bytes. */ - *pwc = wc; - return (cnt); -invalid_sequence: - *pwc = UNICODE_R_CHAR;/* set the Replacement Character instead. */ - return (cnt * -1); -} - -static int -utf8_to_unicode(uint32_t *pwc, const char *s, size_t n) -{ - int cnt; - - cnt = _utf8_to_unicode(pwc, s, n); - /* Any of Surrogate pair is not legal Unicode values. */ - if (cnt == 3 && IS_SURROGATE_PAIR_LA(*pwc)) - return (-3); - return (cnt); -} - -static inline uint32_t -combine_surrogate_pair(uint32_t uc, uint32_t uc2) -{ - uc -= 0xD800; - uc *= 0x400; - uc += uc2 - 0xDC00; - uc += 0x10000; - return (uc); -} - -/* - * Convert a single UTF-8/CESU-8 sequence to a Unicode code point in - * removing surrogate pairs. - * - * CESU-8: The Compatibility Encoding Scheme for UTF-16. - * - * Usually return used bytes, return used byte in negative value when - * a unicode character is replaced with U+FFFD. - */ -static int -cesu8_to_unicode(uint32_t *pwc, const char *s, size_t n) -{ - uint32_t wc = 0; - int cnt; - - cnt = _utf8_to_unicode(&wc, s, n); - if (cnt == 3 && IS_HIGH_SURROGATE_LA(wc)) { - uint32_t wc2 = 0; - if (n - 3 < 3) { - /* Invalid byte sequence. */ - goto invalid_sequence; - } - cnt = _utf8_to_unicode(&wc2, s+3, n-3); - if (cnt != 3 || !IS_LOW_SURROGATE_LA(wc2)) { - /* Invalid byte sequence. */ - goto invalid_sequence; - } - wc = combine_surrogate_pair(wc, wc2); - cnt = 6; - } else if (cnt == 3 && IS_LOW_SURROGATE_LA(wc)) { - /* Invalid byte sequence. */ - goto invalid_sequence; - } - *pwc = wc; - return (cnt); -invalid_sequence: - *pwc = UNICODE_R_CHAR;/* set the Replacement Character instead. */ - if (cnt > 0) - cnt *= -1; - return (cnt); -} - -/* - * Convert a Unicode code point to a single UTF-8 sequence. - * - * NOTE:This function does not check if the Unicode is legal or not. - * Please you definitely check it before calling this. - */ -static size_t -unicode_to_utf8(char *p, size_t remaining, uint32_t uc) -{ - char *_p = p; - - /* Invalid Unicode char maps to Replacement character */ - if (uc > UNICODE_MAX) - uc = UNICODE_R_CHAR; - /* Translate code point to UTF8 */ - if (uc <= 0x7f) { - if (remaining == 0) - return (0); - *p++ = (char)uc; - } else if (uc <= 0x7ff) { - if (remaining < 2) - return (0); - *p++ = 0xc0 | ((uc >> 6) & 0x1f); - *p++ = 0x80 | (uc & 0x3f); - } else if (uc <= 0xffff) { - if (remaining < 3) - return (0); - *p++ = 0xe0 | ((uc >> 12) & 0x0f); - *p++ = 0x80 | ((uc >> 6) & 0x3f); - *p++ = 0x80 | (uc & 0x3f); - } else { - if (remaining < 4) - return (0); - *p++ = 0xf0 | ((uc >> 18) & 0x07); - *p++ = 0x80 | ((uc >> 12) & 0x3f); - *p++ = 0x80 | ((uc >> 6) & 0x3f); - *p++ = 0x80 | (uc & 0x3f); - } - return (p - _p); -} - -static int -utf16be_to_unicode(uint32_t *pwc, const char *s, size_t n) -{ - return (utf16_to_unicode(pwc, s, n, 1)); -} - -static int -utf16le_to_unicode(uint32_t *pwc, const char *s, size_t n) -{ - return (utf16_to_unicode(pwc, s, n, 0)); -} - -static int -utf16_to_unicode(uint32_t *pwc, const char *s, size_t n, int be) -{ - const char *utf16 = s; - unsigned uc; - - if (n == 0) - return (0); - if (n == 1) { - /* set the Replacement Character instead. */ - *pwc = UNICODE_R_CHAR; - return (-1); - } - - if (be) - uc = archive_be16dec(utf16); - else - uc = archive_le16dec(utf16); - utf16 += 2; - - /* If this is a surrogate pair, assemble the full code point.*/ - if (IS_HIGH_SURROGATE_LA(uc)) { - unsigned uc2; - - if (n >= 4) { - if (be) - uc2 = archive_be16dec(utf16); - else - uc2 = archive_le16dec(utf16); - } else - uc2 = 0; - if (IS_LOW_SURROGATE_LA(uc2)) { - uc = combine_surrogate_pair(uc, uc2); - utf16 += 2; - } else { - /* Undescribed code point should be U+FFFD - * (replacement character). */ - *pwc = UNICODE_R_CHAR; - return (-2); - } - } - - /* - * Surrogate pair values(0xd800 through 0xdfff) are only - * used by UTF-16, so, after above calculation, the code - * must not be surrogate values, and Unicode has no codes - * larger than 0x10ffff. Thus, those are not legal Unicode - * values. - */ - if (IS_SURROGATE_PAIR_LA(uc) || uc > UNICODE_MAX) { - /* Undescribed code point should be U+FFFD - * (replacement character). */ - *pwc = UNICODE_R_CHAR; - return (((int)(utf16 - s)) * -1); - } - *pwc = uc; - return ((int)(utf16 - s)); -} - -static size_t -unicode_to_utf16be(char *p, size_t remaining, uint32_t uc) -{ - char *utf16 = p; - - if (uc > 0xffff) { - /* We have a code point that won't fit into a - * wchar_t; convert it to a surrogate pair. */ - if (remaining < 4) - return (0); - uc -= 0x10000; - archive_be16enc(utf16, ((uc >> 10) & 0x3ff) + 0xD800); - archive_be16enc(utf16+2, (uc & 0x3ff) + 0xDC00); - return (4); - } else { - if (remaining < 2) - return (0); - archive_be16enc(utf16, uc); - return (2); - } -} - -static size_t -unicode_to_utf16le(char *p, size_t remaining, uint32_t uc) -{ - char *utf16 = p; - - if (uc > 0xffff) { - /* We have a code point that won't fit into a - * wchar_t; convert it to a surrogate pair. */ - if (remaining < 4) - return (0); - uc -= 0x10000; - archive_le16enc(utf16, ((uc >> 10) & 0x3ff) + 0xD800); - archive_le16enc(utf16+2, (uc & 0x3ff) + 0xDC00); - return (4); - } else { - if (remaining < 2) - return (0); - archive_le16enc(utf16, uc); - return (2); - } -} - -/* - * Copy UTF-8 string in checking surrogate pair. - * If any surrogate pair are found, it would be canonicalized. - */ -static int -strncat_from_utf8_to_utf8(struct archive_string *as, const void *_p, - size_t len, struct archive_string_conv *sc) -{ - const char *s; - char *p, *endp; - int n, ret = 0; - - (void)sc; /* UNUSED */ - - if (archive_string_ensure(as, as->length + len + 1) == NULL) - return (-1); - - s = (const char *)_p; - p = as->s + as->length; - endp = as->s + as->buffer_length -1; - do { - uint32_t uc; - const char *ss = s; - size_t w; - - /* - * Forward byte sequence until a conversion of that is needed. - */ - while ((n = utf8_to_unicode(&uc, s, len)) > 0) { - s += n; - len -= n; - } - if (ss < s) { - if (p + (s - ss) > endp) { - as->length = p - as->s; - if (archive_string_ensure(as, - as->buffer_length + len + 1) == NULL) - return (-1); - p = as->s + as->length; - endp = as->s + as->buffer_length -1; - } - - memcpy(p, ss, s - ss); - p += s - ss; - } - - /* - * If n is negative, current byte sequence needs a replacement. - */ - if (n < 0) { - if (n == -3 && IS_SURROGATE_PAIR_LA(uc)) { - /* Current byte sequence may be CESU-8. */ - n = cesu8_to_unicode(&uc, s, len); - } - if (n < 0) { - ret = -1; - n *= -1;/* Use a replaced unicode character. */ - } - - /* Rebuild UTF-8 byte sequence. */ - while ((w = unicode_to_utf8(p, endp - p, uc)) == 0) { - as->length = p - as->s; - if (archive_string_ensure(as, - as->buffer_length + len + 1) == NULL) - return (-1); - p = as->s + as->length; - endp = as->s + as->buffer_length -1; - } - p += w; - s += n; - len -= n; - } - } while (n > 0); - as->length = p - as->s; - as->s[as->length] = '\0'; - return (ret); -} - -static int -archive_string_append_unicode(struct archive_string *as, const void *_p, - size_t len, struct archive_string_conv *sc) -{ - const char *s; - char *p, *endp; - uint32_t uc; - size_t w; - int n, ret = 0, ts, tm; - int (*parse)(uint32_t *, const char *, size_t); - size_t (*unparse)(char *, size_t, uint32_t); - - if (sc->flag & SCONV_TO_UTF16BE) { - unparse = unicode_to_utf16be; - ts = 2; - } else if (sc->flag & SCONV_TO_UTF16LE) { - unparse = unicode_to_utf16le; - ts = 2; - } else if (sc->flag & SCONV_TO_UTF8) { - unparse = unicode_to_utf8; - ts = 1; - } else { - /* - * This case is going to be converted to another - * character-set through iconv. - */ - if (sc->flag & SCONV_FROM_UTF16BE) { - unparse = unicode_to_utf16be; - ts = 2; - } else if (sc->flag & SCONV_FROM_UTF16LE) { - unparse = unicode_to_utf16le; - ts = 2; - } else { - unparse = unicode_to_utf8; - ts = 1; - } - } - - if (sc->flag & SCONV_FROM_UTF16BE) { - parse = utf16be_to_unicode; - tm = 1; - } else if (sc->flag & SCONV_FROM_UTF16LE) { - parse = utf16le_to_unicode; - tm = 1; - } else { - parse = cesu8_to_unicode; - tm = ts; - } - - if (archive_string_ensure(as, as->length + len * tm + ts) == NULL) - return (-1); - - s = (const char *)_p; - p = as->s + as->length; - endp = as->s + as->buffer_length - ts; - while ((n = parse(&uc, s, len)) != 0) { - if (n < 0) { - /* Use a replaced unicode character. */ - n *= -1; - ret = -1; - } - s += n; - len -= n; - while ((w = unparse(p, endp - p, uc)) == 0) { - /* There is not enough output buffer so - * we have to expand it. */ - as->length = p - as->s; - if (archive_string_ensure(as, - as->buffer_length + len * tm + ts) == NULL) - return (-1); - p = as->s + as->length; - endp = as->s + as->buffer_length - ts; - } - p += w; - } - as->length = p - as->s; - as->s[as->length] = '\0'; - if (ts == 2) - as->s[as->length+1] = '\0'; - return (ret); -} - -/* - * Following Constants for Hangul compositions this information comes from - * Unicode Standard Annex #15 http://unicode.org/reports/tr15/ - */ -#define HC_SBASE 0xAC00 -#define HC_LBASE 0x1100 -#define HC_VBASE 0x1161 -#define HC_TBASE 0x11A7 -#define HC_LCOUNT 19 -#define HC_VCOUNT 21 -#define HC_TCOUNT 28 -#define HC_NCOUNT (HC_VCOUNT * HC_TCOUNT) -#define HC_SCOUNT (HC_LCOUNT * HC_NCOUNT) - -static uint32_t -get_nfc(uint32_t uc, uint32_t uc2) -{ - int t, b; - - t = 0; - b = sizeof(u_composition_table)/sizeof(u_composition_table[0]) -1; - while (b >= t) { - int m = (t + b) / 2; - if (u_composition_table[m].cp1 < uc) - t = m + 1; - else if (u_composition_table[m].cp1 > uc) - b = m - 1; - else if (u_composition_table[m].cp2 < uc2) - t = m + 1; - else if (u_composition_table[m].cp2 > uc2) - b = m - 1; - else - return (u_composition_table[m].nfc); - } - return (0); -} - -#define FDC_MAX 10 /* The maximum number of Following Decomposable - * Characters. */ - -/* - * Update first code point. - */ -#define UPDATE_UC(new_uc) do { \ - uc = new_uc; \ - ucptr = NULL; \ -} while (0) - -/* - * Replace first code point with second code point. - */ -#define REPLACE_UC_WITH_UC2() do { \ - uc = uc2; \ - ucptr = uc2ptr; \ - n = n2; \ -} while (0) - -#define EXPAND_BUFFER() do { \ - as->length = p - as->s; \ - if (archive_string_ensure(as, \ - as->buffer_length + len * tm + ts) == NULL)\ - return (-1); \ - p = as->s + as->length; \ - endp = as->s + as->buffer_length - ts; \ -} while (0) - -#define UNPARSE(p, endp, uc) do { \ - while ((w = unparse(p, (endp) - (p), uc)) == 0) {\ - EXPAND_BUFFER(); \ - } \ - p += w; \ -} while (0) - -/* - * Write first code point. - * If the code point has not be changed from its original code, - * this just copies it from its original buffer pointer. - * If not, this converts it to UTF-8 byte sequence and copies it. - */ -#define WRITE_UC() do { \ - if (ucptr) { \ - if (p + n > endp) \ - EXPAND_BUFFER(); \ - switch (n) { \ - case 4: \ - *p++ = *ucptr++; \ - /* FALL THROUGH */ \ - case 3: \ - *p++ = *ucptr++; \ - /* FALL THROUGH */ \ - case 2: \ - *p++ = *ucptr++; \ - /* FALL THROUGH */ \ - case 1: \ - *p++ = *ucptr; \ - break; \ - } \ - ucptr = NULL; \ - } else { \ - UNPARSE(p, endp, uc); \ - } \ -} while (0) - -/* - * Collect following decomposable code points. - */ -#define COLLECT_CPS(start) do { \ - int _i; \ - for (_i = start; _i < FDC_MAX ; _i++) { \ - nx = parse(&ucx[_i], s, len); \ - if (nx <= 0) \ - break; \ - cx = CCC(ucx[_i]); \ - if (cl >= cx && cl != 228 && cx != 228)\ - break; \ - s += nx; \ - len -= nx; \ - cl = cx; \ - ccx[_i] = cx; \ - } \ - if (_i >= FDC_MAX) { \ - ret = -1; \ - ucx_size = FDC_MAX; \ - } else \ - ucx_size = _i; \ -} while (0) - -/* - * Normalize UTF-8/UTF-16BE characters to Form C and copy the result. - * - * TODO: Convert composition exclusions, which are never converted - * from NFC,NFD,NFKC and NFKD, to Form C. - */ -static int -archive_string_normalize_C(struct archive_string *as, const void *_p, - size_t len, struct archive_string_conv *sc) -{ - const char *s = (const char *)_p; - char *p, *endp; - uint32_t uc, uc2; - size_t w; - int always_replace, n, n2, ret = 0, spair, ts, tm; - int (*parse)(uint32_t *, const char *, size_t); - size_t (*unparse)(char *, size_t, uint32_t); - - always_replace = 1; - ts = 1;/* text size. */ - if (sc->flag & SCONV_TO_UTF16BE) { - unparse = unicode_to_utf16be; - ts = 2; - if (sc->flag & SCONV_FROM_UTF16BE) - always_replace = 0; - } else if (sc->flag & SCONV_TO_UTF16LE) { - unparse = unicode_to_utf16le; - ts = 2; - if (sc->flag & SCONV_FROM_UTF16LE) - always_replace = 0; - } else if (sc->flag & SCONV_TO_UTF8) { - unparse = unicode_to_utf8; - if (sc->flag & SCONV_FROM_UTF8) - always_replace = 0; - } else { - /* - * This case is going to be converted to another - * character-set through iconv. - */ - always_replace = 0; - if (sc->flag & SCONV_FROM_UTF16BE) { - unparse = unicode_to_utf16be; - ts = 2; - } else if (sc->flag & SCONV_FROM_UTF16LE) { - unparse = unicode_to_utf16le; - ts = 2; - } else { - unparse = unicode_to_utf8; - } - } - - if (sc->flag & SCONV_FROM_UTF16BE) { - parse = utf16be_to_unicode; - tm = 1; - spair = 4;/* surrogate pair size in UTF-16. */ - } else if (sc->flag & SCONV_FROM_UTF16LE) { - parse = utf16le_to_unicode; - tm = 1; - spair = 4;/* surrogate pair size in UTF-16. */ - } else { - parse = cesu8_to_unicode; - tm = ts; - spair = 6;/* surrogate pair size in UTF-8. */ - } - - if (archive_string_ensure(as, as->length + len * tm + ts) == NULL) - return (-1); - - p = as->s + as->length; - endp = as->s + as->buffer_length - ts; - while ((n = parse(&uc, s, len)) != 0) { - const char *ucptr, *uc2ptr; - - if (n < 0) { - /* Use a replaced unicode character. */ - UNPARSE(p, endp, uc); - s += n*-1; - len -= n*-1; - ret = -1; - continue; - } else if (n == spair || always_replace) - /* uc is converted from a surrogate pair. - * this should be treated as a changed code. */ - ucptr = NULL; - else - ucptr = s; - s += n; - len -= n; - - /* Read second code point. */ - while ((n2 = parse(&uc2, s, len)) > 0) { - uint32_t ucx[FDC_MAX]; - int ccx[FDC_MAX]; - int cl, cx, i, nx, ucx_size; - int LIndex,SIndex; - uint32_t nfc; - - if (n2 == spair || always_replace) - /* uc2 is converted from a surrogate pair. - * this should be treated as a changed code. */ - uc2ptr = NULL; - else - uc2ptr = s; - s += n2; - len -= n2; - - /* - * If current second code point is out of decomposable - * code points, finding compositions is unneeded. - */ - if (!IS_DECOMPOSABLE_BLOCK(uc2)) { - WRITE_UC(); - REPLACE_UC_WITH_UC2(); - continue; - } - - /* - * Try to combine current code points. - */ - /* - * We have to combine Hangul characters according to - * http://uniicode.org/reports/tr15/#Hangul - */ - if (0 <= (LIndex = uc - HC_LBASE) && - LIndex < HC_LCOUNT) { - /* - * Hangul Composition. - * 1. Two current code points are L and V. - */ - int VIndex = uc2 - HC_VBASE; - if (0 <= VIndex && VIndex < HC_VCOUNT) { - /* Make syllable of form LV. */ - UPDATE_UC(HC_SBASE + - (LIndex * HC_VCOUNT + VIndex) * - HC_TCOUNT); - } else { - WRITE_UC(); - REPLACE_UC_WITH_UC2(); - } - continue; - } else if (0 <= (SIndex = uc - HC_SBASE) && - SIndex < HC_SCOUNT && (SIndex % HC_TCOUNT) == 0) { - /* - * Hangul Composition. - * 2. Two current code points are LV and T. - */ - int TIndex = uc2 - HC_TBASE; - if (0 < TIndex && TIndex < HC_TCOUNT) { - /* Make syllable of form LVT. */ - UPDATE_UC(uc + TIndex); - } else { - WRITE_UC(); - REPLACE_UC_WITH_UC2(); - } - continue; - } else if ((nfc = get_nfc(uc, uc2)) != 0) { - /* A composition to current code points - * is found. */ - UPDATE_UC(nfc); - continue; - } else if ((cl = CCC(uc2)) == 0) { - /* Clearly 'uc2' the second code point is not - * a decomposable code. */ - WRITE_UC(); - REPLACE_UC_WITH_UC2(); - continue; - } - - /* - * Collect following decomposable code points. - */ - cx = 0; - ucx[0] = uc2; - ccx[0] = cl; - COLLECT_CPS(1); - - /* - * Find a composed code in the collected code points. - */ - i = 1; - while (i < ucx_size) { - int j; - - if ((nfc = get_nfc(uc, ucx[i])) == 0) { - i++; - continue; - } - - /* - * nfc is composed of uc and ucx[i]. - */ - UPDATE_UC(nfc); - - /* - * Remove ucx[i] by shifting - * following code points. - */ - for (j = i; j+1 < ucx_size; j++) { - ucx[j] = ucx[j+1]; - ccx[j] = ccx[j+1]; - } - ucx_size --; - - /* - * Collect following code points blocked - * by ucx[i] the removed code point. - */ - if (ucx_size > 0 && i == ucx_size && - nx > 0 && cx == cl) { - cl = ccx[ucx_size-1]; - COLLECT_CPS(ucx_size); - } - /* - * Restart finding a composed code with - * the updated uc from the top of the - * collected code points. - */ - i = 0; - } - - /* - * Apparently the current code points are not - * decomposed characters or already composed. - */ - WRITE_UC(); - for (i = 0; i < ucx_size; i++) - UNPARSE(p, endp, ucx[i]); - - /* - * Flush out remaining canonical combining characters. - */ - if (nx > 0 && cx == cl && len > 0) { - while ((nx = parse(&ucx[0], s, len)) - > 0) { - cx = CCC(ucx[0]); - if (cl > cx) - break; - s += nx; - len -= nx; - cl = cx; - UNPARSE(p, endp, ucx[0]); - } - } - break; - } - if (n2 < 0) { - WRITE_UC(); - /* Use a replaced unicode character. */ - UNPARSE(p, endp, uc2); - s += n2*-1; - len -= n2*-1; - ret = -1; - continue; - } else if (n2 == 0) { - WRITE_UC(); - break; - } - } - as->length = p - as->s; - as->s[as->length] = '\0'; - if (ts == 2) - as->s[as->length+1] = '\0'; - return (ret); -} - -static int -get_nfd(uint32_t *cp1, uint32_t *cp2, uint32_t uc) -{ - int t, b; - - /* - * These are not converted to NFD on Mac OS. - */ - if ((uc >= 0x2000 && uc <= 0x2FFF) || - (uc >= 0xF900 && uc <= 0xFAFF) || - (uc >= 0x2F800 && uc <= 0x2FAFF)) - return (0); - /* - * Those code points are not converted to NFD on Mac OS. - * I do not know the reason because it is undocumented. - * NFC NFD - * 1109A ==> 11099 110BA - * 1109C ==> 1109B 110BA - * 110AB ==> 110A5 110BA - */ - if (uc == 0x1109A || uc == 0x1109C || uc == 0x110AB) - return (0); - - t = 0; - b = sizeof(u_decomposition_table)/sizeof(u_decomposition_table[0]) -1; - while (b >= t) { - int m = (t + b) / 2; - if (u_decomposition_table[m].nfc < uc) - t = m + 1; - else if (u_decomposition_table[m].nfc > uc) - b = m - 1; - else { - *cp1 = u_decomposition_table[m].cp1; - *cp2 = u_decomposition_table[m].cp2; - return (1); - } - } - return (0); -} - -#define REPLACE_UC_WITH(cp) do { \ - uc = cp; \ - ucptr = NULL; \ -} while (0) - -/* - * Normalize UTF-8 characters to Form D and copy the result. - */ -static int -archive_string_normalize_D(struct archive_string *as, const void *_p, - size_t len, struct archive_string_conv *sc) -{ - const char *s = (const char *)_p; - char *p, *endp; - uint32_t uc, uc2; - size_t w; - int always_replace, n, n2, ret = 0, spair, ts, tm; - int (*parse)(uint32_t *, const char *, size_t); - size_t (*unparse)(char *, size_t, uint32_t); - - always_replace = 1; - ts = 1;/* text size. */ - if (sc->flag & SCONV_TO_UTF16BE) { - unparse = unicode_to_utf16be; - ts = 2; - if (sc->flag & SCONV_FROM_UTF16BE) - always_replace = 0; - } else if (sc->flag & SCONV_TO_UTF16LE) { - unparse = unicode_to_utf16le; - ts = 2; - if (sc->flag & SCONV_FROM_UTF16LE) - always_replace = 0; - } else if (sc->flag & SCONV_TO_UTF8) { - unparse = unicode_to_utf8; - if (sc->flag & SCONV_FROM_UTF8) - always_replace = 0; - } else { - /* - * This case is going to be converted to another - * character-set through iconv. - */ - always_replace = 0; - if (sc->flag & SCONV_FROM_UTF16BE) { - unparse = unicode_to_utf16be; - ts = 2; - } else if (sc->flag & SCONV_FROM_UTF16LE) { - unparse = unicode_to_utf16le; - ts = 2; - } else { - unparse = unicode_to_utf8; - } - } - - if (sc->flag & SCONV_FROM_UTF16BE) { - parse = utf16be_to_unicode; - tm = 1; - spair = 4;/* surrogate pair size in UTF-16. */ - } else if (sc->flag & SCONV_FROM_UTF16LE) { - parse = utf16le_to_unicode; - tm = 1; - spair = 4;/* surrogate pair size in UTF-16. */ - } else { - parse = cesu8_to_unicode; - tm = ts; - spair = 6;/* surrogate pair size in UTF-8. */ - } - - if (archive_string_ensure(as, as->length + len * tm + ts) == NULL) - return (-1); - - p = as->s + as->length; - endp = as->s + as->buffer_length - ts; - while ((n = parse(&uc, s, len)) != 0) { - const char *ucptr; - uint32_t cp1, cp2; - int SIndex; - struct { - uint32_t uc; - int ccc; - } fdc[FDC_MAX]; - int fdi, fdj; - int ccc; - -check_first_code: - if (n < 0) { - /* Use a replaced unicode character. */ - UNPARSE(p, endp, uc); - s += n*-1; - len -= n*-1; - ret = -1; - continue; - } else if (n == spair || always_replace) - /* uc is converted from a surrogate pair. - * this should be treated as a changed code. */ - ucptr = NULL; - else - ucptr = s; - s += n; - len -= n; - - /* Hangul Decomposition. */ - if ((SIndex = uc - HC_SBASE) >= 0 && SIndex < HC_SCOUNT) { - int L = HC_LBASE + SIndex / HC_NCOUNT; - int V = HC_VBASE + (SIndex % HC_NCOUNT) / HC_TCOUNT; - int T = HC_TBASE + SIndex % HC_TCOUNT; - - REPLACE_UC_WITH(L); - WRITE_UC(); - REPLACE_UC_WITH(V); - WRITE_UC(); - if (T != HC_TBASE) { - REPLACE_UC_WITH(T); - WRITE_UC(); - } - continue; - } - if (IS_DECOMPOSABLE_BLOCK(uc) && CCC(uc) != 0) { - WRITE_UC(); - continue; - } - - fdi = 0; - while (get_nfd(&cp1, &cp2, uc) && fdi < FDC_MAX) { - int k; - - for (k = fdi; k > 0; k--) - fdc[k] = fdc[k-1]; - fdc[0].ccc = CCC(cp2); - fdc[0].uc = cp2; - fdi++; - REPLACE_UC_WITH(cp1); - } - - /* Read following code points. */ - while ((n2 = parse(&uc2, s, len)) > 0 && - (ccc = CCC(uc2)) != 0 && fdi < FDC_MAX) { - int j, k; - - s += n2; - len -= n2; - for (j = 0; j < fdi; j++) { - if (fdc[j].ccc > ccc) - break; - } - if (j < fdi) { - for (k = fdi; k > j; k--) - fdc[k] = fdc[k-1]; - fdc[j].ccc = ccc; - fdc[j].uc = uc2; - } else { - fdc[fdi].ccc = ccc; - fdc[fdi].uc = uc2; - } - fdi++; - } - - WRITE_UC(); - for (fdj = 0; fdj < fdi; fdj++) { - REPLACE_UC_WITH(fdc[fdj].uc); - WRITE_UC(); - } - - if (n2 == 0) - break; - REPLACE_UC_WITH(uc2); - n = n2; - goto check_first_code; - } - as->length = p - as->s; - as->s[as->length] = '\0'; - if (ts == 2) - as->s[as->length+1] = '\0'; - return (ret); -} - -/* - * libarchive 2.x made incorrect UTF-8 strings in the wrong assumption - * that WCS is Unicode. It is true for several platforms but some are false. - * And then people who did not use UTF-8 locale on the non Unicode WCS - * platform and made a tar file with libarchive(mostly bsdtar) 2.x. Those - * now cannot get right filename from libarchive 3.x and later since we - * fixed the wrong assumption and it is incompatible to older its versions. - * So we provide special option, "compat-2x.x", for resolving it. - * That option enable the string conversion of libarchive 2.x. - * - * Translates the wrong UTF-8 string made by libarchive 2.x into current - * locale character set and appends to the archive_string. - * Note: returns -1 if conversion fails. - */ -static int -strncat_from_utf8_libarchive2(struct archive_string *as, - const void *_p, size_t len, struct archive_string_conv *sc) -{ - const char *s; - int n; - char *p; - char *end; - uint32_t unicode; -#if HAVE_WCRTOMB - mbstate_t shift_state; - - memset(&shift_state, 0, sizeof(shift_state)); -#else - /* Clear the shift state before starting. */ - wctomb(NULL, L'\0'); -#endif - (void)sc; /* UNUSED */ - /* - * Allocate buffer for MBS. - * We need this allocation here since it is possible that - * as->s is still NULL. - */ - if (archive_string_ensure(as, as->length + len + 1) == NULL) - return (-1); - - s = (const char *)_p; - p = as->s + as->length; - end = as->s + as->buffer_length - MB_CUR_MAX -1; - while ((n = _utf8_to_unicode(&unicode, s, len)) != 0) { - wchar_t wc; - - if (p >= end) { - as->length = p - as->s; - /* Re-allocate buffer for MBS. */ - if (archive_string_ensure(as, - as->length + max(len * 2, - (size_t)MB_CUR_MAX) + 1) == NULL) - return (-1); - p = as->s + as->length; - end = as->s + as->buffer_length - MB_CUR_MAX -1; - } - - /* - * As libarchive 2.x, translates the UTF-8 characters into - * wide-characters in the assumption that WCS is Unicode. - */ - if (n < 0) { - n *= -1; - wc = L'?'; - } else - wc = (wchar_t)unicode; - - s += n; - len -= n; - /* - * Translates the wide-character into the current locale MBS. - */ -#if HAVE_WCRTOMB - n = (int)wcrtomb(p, wc, &shift_state); -#else - n = (int)wctomb(p, wc); -#endif - if (n == -1) - return (-1); - p += n; - } - as->length = p - as->s; - as->s[as->length] = '\0'; - return (0); -} - - -/* - * Conversion functions between current locale dependent MBS and UTF-16BE. - * strncat_from_utf16be() : UTF-16BE --> MBS - * strncat_to_utf16be() : MBS --> UTF16BE - */ - -#if defined(_WIN32) && !defined(__CYGWIN__) - -/* - * Convert a UTF-16BE/LE string to current locale and copy the result. - * Return -1 if conversion fails. - */ -static int -win_strncat_from_utf16(struct archive_string *as, const void *_p, size_t bytes, - struct archive_string_conv *sc, int be) -{ - struct archive_string tmp; - const char *u16; - int ll; - BOOL defchar; - char *mbs; - size_t mbs_size, b; - int ret = 0; - - bytes &= ~1; - if (archive_string_ensure(as, as->length + bytes +1) == NULL) - return (-1); - - mbs = as->s + as->length; - mbs_size = as->buffer_length - as->length -1; - - if (sc->to_cp == CP_C_LOCALE) { - /* - * "C" locale special process. - */ - u16 = _p; - ll = 0; - for (b = 0; b < bytes; b += 2) { - uint16_t val; - if (be) - val = archive_be16dec(u16+b); - else - val = archive_le16dec(u16+b); - if (val > 255) { - *mbs++ = '?'; - ret = -1; - } else - *mbs++ = (char)(val&0xff); - ll++; - } - as->length += ll; - as->s[as->length] = '\0'; - return (ret); - } - - archive_string_init(&tmp); - if (be) { - if (is_big_endian()) { - u16 = _p; - } else { - if (archive_string_ensure(&tmp, bytes+2) == NULL) - return (-1); - memcpy(tmp.s, _p, bytes); - for (b = 0; b < bytes; b += 2) { - uint16_t val = archive_be16dec(tmp.s+b); - archive_le16enc(tmp.s+b, val); - } - u16 = tmp.s; - } - } else { - if (!is_big_endian()) { - u16 = _p; - } else { - if (archive_string_ensure(&tmp, bytes+2) == NULL) - return (-1); - memcpy(tmp.s, _p, bytes); - for (b = 0; b < bytes; b += 2) { - uint16_t val = archive_le16dec(tmp.s+b); - archive_be16enc(tmp.s+b, val); - } - u16 = tmp.s; - } - } - - do { - defchar = 0; - ll = WideCharToMultiByte(sc->to_cp, 0, - (LPCWSTR)u16, (int)bytes>>1, mbs, (int)mbs_size, - NULL, &defchar); - /* Exit loop if we succeeded */ - if (ll != 0 || - GetLastError() != ERROR_INSUFFICIENT_BUFFER) { - break; - } - /* Else expand buffer and loop to try again. */ - ll = WideCharToMultiByte(sc->to_cp, 0, - (LPCWSTR)u16, (int)bytes, NULL, 0, NULL, NULL); - if (archive_string_ensure(as, ll +1) == NULL) - return (-1); - mbs = as->s + as->length; - mbs_size = as->buffer_length - as->length -1; - } while (1); - archive_string_free(&tmp); - as->length += ll; - as->s[as->length] = '\0'; - if (ll == 0 || defchar) - ret = -1; - return (ret); -} - -static int -win_strncat_from_utf16be(struct archive_string *as, const void *_p, - size_t bytes, struct archive_string_conv *sc) -{ - return (win_strncat_from_utf16(as, _p, bytes, sc, 1)); -} - -static int -win_strncat_from_utf16le(struct archive_string *as, const void *_p, - size_t bytes, struct archive_string_conv *sc) -{ - return (win_strncat_from_utf16(as, _p, bytes, sc, 0)); -} - -static int -is_big_endian(void) -{ - uint16_t d = 1; - - return (archive_be16dec(&d) == 1); -} - -/* - * Convert a current locale string to UTF-16BE/LE and copy the result. - * Return -1 if conversion fails. - */ -static int -win_strncat_to_utf16(struct archive_string *as16, const void *_p, - size_t length, struct archive_string_conv *sc, int bigendian) -{ - const char *s = (const char *)_p; - char *u16; - size_t count, avail; - - if (archive_string_ensure(as16, - as16->length + (length + 1) * 2) == NULL) - return (-1); - - u16 = as16->s + as16->length; - avail = as16->buffer_length - 2; - if (sc->from_cp == CP_C_LOCALE) { - /* - * "C" locale special process. - */ - count = 0; - while (count < length && *s) { - if (bigendian) - archive_be16enc(u16, *s); - else - archive_le16enc(u16, *s); - u16 += 2; - s++; - count++; - } - as16->length += count << 1; - as16->s[as16->length] = 0; - as16->s[as16->length+1] = 0; - return (0); - } - do { - count = MultiByteToWideChar(sc->from_cp, - MB_PRECOMPOSED, s, (int)length, (LPWSTR)u16, (int)avail>>1); - /* Exit loop if we succeeded */ - if (count != 0 || - GetLastError() != ERROR_INSUFFICIENT_BUFFER) { - break; - } - /* Expand buffer and try again */ - count = MultiByteToWideChar(sc->from_cp, - MB_PRECOMPOSED, s, (int)length, NULL, 0); - if (archive_string_ensure(as16, (count +1) * 2) - == NULL) - return (-1); - u16 = as16->s + as16->length; - avail = as16->buffer_length - 2; - } while (1); - as16->length += count * 2; - as16->s[as16->length] = 0; - as16->s[as16->length+1] = 0; - if (count == 0) - return (-1); - - if (is_big_endian()) { - if (!bigendian) { - while (count > 0) { - uint16_t v = archive_be16dec(u16); - archive_le16enc(u16, v); - u16 += 2; - count--; - } - } - } else { - if (bigendian) { - while (count > 0) { - uint16_t v = archive_le16dec(u16); - archive_be16enc(u16, v); - u16 += 2; - count--; - } - } - } - return (0); -} - -static int -win_strncat_to_utf16be(struct archive_string *as16, const void *_p, - size_t length, struct archive_string_conv *sc) -{ - return (win_strncat_to_utf16(as16, _p, length, sc, 1)); -} - -static int -win_strncat_to_utf16le(struct archive_string *as16, const void *_p, - size_t length, struct archive_string_conv *sc) -{ - return (win_strncat_to_utf16(as16, _p, length, sc, 0)); -} - -#endif /* _WIN32 && !__CYGWIN__ */ - -/* - * Do the best effort for conversions. - * We cannot handle UTF-16BE character-set without such iconv, - * but there is a chance if a string consists just ASCII code or - * a current locale is UTF-8. - */ - -/* - * Convert a UTF-16BE string to current locale and copy the result. - * Return -1 if conversion fails. - */ -static int -best_effort_strncat_from_utf16(struct archive_string *as, const void *_p, - size_t bytes, struct archive_string_conv *sc, int be) -{ - const char *utf16 = (const char *)_p; - char *mbs; - uint32_t uc; - int n, ret; - - (void)sc; /* UNUSED */ - /* - * Other case, we should do the best effort. - * If all character are ASCII(<0x7f), we can convert it. - * if not , we set a alternative character and return -1. - */ - ret = 0; - if (archive_string_ensure(as, as->length + bytes +1) == NULL) - return (-1); - mbs = as->s + as->length; - - while ((n = utf16_to_unicode(&uc, utf16, bytes, be)) != 0) { - if (n < 0) { - n *= -1; - ret = -1; - } - bytes -= n; - utf16 += n; - - if (uc > 127) { - /* We cannot handle it. */ - *mbs++ = '?'; - ret = -1; - } else - *mbs++ = (char)uc; - } - as->length = mbs - as->s; - as->s[as->length] = '\0'; - return (ret); -} - -static int -best_effort_strncat_from_utf16be(struct archive_string *as, const void *_p, - size_t bytes, struct archive_string_conv *sc) -{ - return (best_effort_strncat_from_utf16(as, _p, bytes, sc, 1)); -} - -static int -best_effort_strncat_from_utf16le(struct archive_string *as, const void *_p, - size_t bytes, struct archive_string_conv *sc) -{ - return (best_effort_strncat_from_utf16(as, _p, bytes, sc, 0)); -} - -/* - * Convert a current locale string to UTF-16BE/LE and copy the result. - * Return -1 if conversion fails. - */ -static int -best_effort_strncat_to_utf16(struct archive_string *as16, const void *_p, - size_t length, struct archive_string_conv *sc, int bigendian) -{ - const char *s = (const char *)_p; - char *utf16; - size_t remaining; - int ret; - - (void)sc; /* UNUSED */ - /* - * Other case, we should do the best effort. - * If all character are ASCII(<0x7f), we can convert it. - * if not , we set a alternative character and return -1. - */ - ret = 0; - remaining = length; - - if (archive_string_ensure(as16, - as16->length + (length + 1) * 2) == NULL) - return (-1); - - utf16 = as16->s + as16->length; - while (remaining--) { - unsigned c = *s++; - if (c > 127) { - /* We cannot handle it. */ - c = UNICODE_R_CHAR; - ret = -1; - } - if (bigendian) - archive_be16enc(utf16, c); - else - archive_le16enc(utf16, c); - utf16 += 2; - } - as16->length = utf16 - as16->s; - as16->s[as16->length] = 0; - as16->s[as16->length+1] = 0; - return (ret); -} - -static int -best_effort_strncat_to_utf16be(struct archive_string *as16, const void *_p, - size_t length, struct archive_string_conv *sc) -{ - return (best_effort_strncat_to_utf16(as16, _p, length, sc, 1)); -} - -static int -best_effort_strncat_to_utf16le(struct archive_string *as16, const void *_p, - size_t length, struct archive_string_conv *sc) -{ - return (best_effort_strncat_to_utf16(as16, _p, length, sc, 0)); -} - - -/* - * Multistring operations. - */ - -void -archive_mstring_clean(struct archive_mstring *aes) -{ - archive_wstring_free(&(aes->aes_wcs)); - archive_string_free(&(aes->aes_mbs)); - archive_string_free(&(aes->aes_utf8)); - archive_string_free(&(aes->aes_mbs_in_locale)); - aes->aes_set = 0; -} - -void -archive_mstring_copy(struct archive_mstring *dest, struct archive_mstring *src) -{ - dest->aes_set = src->aes_set; - archive_string_copy(&(dest->aes_mbs), &(src->aes_mbs)); - archive_string_copy(&(dest->aes_utf8), &(src->aes_utf8)); - archive_wstring_copy(&(dest->aes_wcs), &(src->aes_wcs)); -} - -int -archive_mstring_get_utf8(struct archive *a, struct archive_mstring *aes, - const char **p) -{ - struct archive_string_conv *sc; - int r; - - /* If we already have a UTF8 form, return that immediately. */ - if (aes->aes_set & AES_SET_UTF8) { - *p = aes->aes_utf8.s; - return (0); - } - - *p = NULL; - /* Try converting WCS to MBS first if MBS does not exist yet. */ - if ((aes->aes_set & AES_SET_MBS) == 0) { - const char *pm; /* unused */ - archive_mstring_get_mbs(a, aes, &pm); /* ignore errors, we'll handle it later */ - } - if (aes->aes_set & AES_SET_MBS) { - sc = archive_string_conversion_to_charset(a, "UTF-8", 1); - if (sc == NULL) - return (-1);/* Couldn't allocate memory for sc. */ - r = archive_strncpy_l(&(aes->aes_utf8), aes->aes_mbs.s, - aes->aes_mbs.length, sc); - if (a == NULL) - free_sconv_object(sc); - if (r == 0) { - aes->aes_set |= AES_SET_UTF8; - *p = aes->aes_utf8.s; - return (0);/* success. */ - } else - return (-1);/* failure. */ - } - return (0);/* success. */ -} - -int -archive_mstring_get_mbs(struct archive *a, struct archive_mstring *aes, - const char **p) -{ - struct archive_string_conv *sc; - int r, ret = 0; - - /* If we already have an MBS form, return that immediately. */ - if (aes->aes_set & AES_SET_MBS) { - *p = aes->aes_mbs.s; - return (ret); - } - - *p = NULL; - /* If there's a WCS form, try converting with the native locale. */ - if (aes->aes_set & AES_SET_WCS) { - archive_string_empty(&(aes->aes_mbs)); - r = archive_string_append_from_wcs(&(aes->aes_mbs), - aes->aes_wcs.s, aes->aes_wcs.length); - *p = aes->aes_mbs.s; - if (r == 0) { - aes->aes_set |= AES_SET_MBS; - return (ret); - } else - ret = -1; - } - - /* If there's a UTF-8 form, try converting with the native locale. */ - if (aes->aes_set & AES_SET_UTF8) { - archive_string_empty(&(aes->aes_mbs)); - sc = archive_string_conversion_from_charset(a, "UTF-8", 1); - if (sc == NULL) - return (-1);/* Couldn't allocate memory for sc. */ - r = archive_strncpy_l(&(aes->aes_mbs), - aes->aes_utf8.s, aes->aes_utf8.length, sc); - if (a == NULL) - free_sconv_object(sc); - *p = aes->aes_mbs.s; - if (r == 0) { - aes->aes_set |= AES_SET_MBS; - ret = 0;/* success; overwrite previous error. */ - } else - ret = -1;/* failure. */ - } - return (ret); -} - -int -archive_mstring_get_wcs(struct archive *a, struct archive_mstring *aes, - const wchar_t **wp) -{ - int r, ret = 0; - - (void)a;/* UNUSED */ - /* Return WCS form if we already have it. */ - if (aes->aes_set & AES_SET_WCS) { - *wp = aes->aes_wcs.s; - return (ret); - } - - *wp = NULL; - /* Try converting UTF8 to MBS first if MBS does not exist yet. */ - if ((aes->aes_set & AES_SET_MBS) == 0) { - const char *p; /* unused */ - archive_mstring_get_mbs(a, aes, &p); /* ignore errors, we'll handle it later */ - } - /* Try converting MBS to WCS using native locale. */ - if (aes->aes_set & AES_SET_MBS) { - archive_wstring_empty(&(aes->aes_wcs)); - r = archive_wstring_append_from_mbs(&(aes->aes_wcs), - aes->aes_mbs.s, aes->aes_mbs.length); - if (r == 0) { - aes->aes_set |= AES_SET_WCS; - *wp = aes->aes_wcs.s; - } else - ret = -1;/* failure. */ - } - return (ret); -} - -int -archive_mstring_get_mbs_l(struct archive *a, struct archive_mstring *aes, - const char **p, size_t *length, struct archive_string_conv *sc) -{ - int ret = 0; -#if defined(_WIN32) && !defined(__CYGWIN__) - int r; - - /* - * Internationalization programming on Windows must use Wide - * characters because Windows platform cannot make locale UTF-8. - */ - if (sc != NULL && (aes->aes_set & AES_SET_WCS) != 0) { - archive_string_empty(&(aes->aes_mbs_in_locale)); - r = archive_string_append_from_wcs_in_codepage( - &(aes->aes_mbs_in_locale), aes->aes_wcs.s, - aes->aes_wcs.length, sc); - if (r == 0) { - *p = aes->aes_mbs_in_locale.s; - if (length != NULL) - *length = aes->aes_mbs_in_locale.length; - return (0); - } else if (errno == ENOMEM) - return (-1); - else - ret = -1; - } -#endif - - /* If there is not an MBS form but there is a WCS or UTF8 form, try converting - * with the native locale to be used for translating it to specified - * character-set. */ - if ((aes->aes_set & AES_SET_MBS) == 0) { - const char *pm; /* unused */ - archive_mstring_get_mbs(a, aes, &pm); /* ignore errors, we'll handle it later */ - } - /* If we already have an MBS form, use it to be translated to - * specified character-set. */ - if (aes->aes_set & AES_SET_MBS) { - if (sc == NULL) { - /* Conversion is unneeded. */ - *p = aes->aes_mbs.s; - if (length != NULL) - *length = aes->aes_mbs.length; - return (0); - } - ret = archive_strncpy_l(&(aes->aes_mbs_in_locale), - aes->aes_mbs.s, aes->aes_mbs.length, sc); - *p = aes->aes_mbs_in_locale.s; - if (length != NULL) - *length = aes->aes_mbs_in_locale.length; - } else { - *p = NULL; - if (length != NULL) - *length = 0; - } - return (ret); -} - -int -archive_mstring_copy_mbs(struct archive_mstring *aes, const char *mbs) -{ - if (mbs == NULL) { - aes->aes_set = 0; - return (0); - } - return (archive_mstring_copy_mbs_len(aes, mbs, strlen(mbs))); -} - -int -archive_mstring_copy_mbs_len(struct archive_mstring *aes, const char *mbs, - size_t len) -{ - if (mbs == NULL) { - aes->aes_set = 0; - return (0); - } - aes->aes_set = AES_SET_MBS; /* Only MBS form is set now. */ - archive_strncpy(&(aes->aes_mbs), mbs, len); - archive_string_empty(&(aes->aes_utf8)); - archive_wstring_empty(&(aes->aes_wcs)); - return (0); -} - -int -archive_mstring_copy_wcs(struct archive_mstring *aes, const wchar_t *wcs) -{ - return archive_mstring_copy_wcs_len(aes, wcs, - wcs == NULL ? 0 : wcslen(wcs)); -} - -int -archive_mstring_copy_utf8(struct archive_mstring *aes, const char *utf8) -{ - if (utf8 == NULL) { - aes->aes_set = 0; - return (0); - } - aes->aes_set = AES_SET_UTF8; - archive_string_empty(&(aes->aes_mbs)); - archive_string_empty(&(aes->aes_wcs)); - archive_strncpy(&(aes->aes_utf8), utf8, strlen(utf8)); - return (int)strlen(utf8); -} - -int -archive_mstring_copy_wcs_len(struct archive_mstring *aes, const wchar_t *wcs, - size_t len) -{ - if (wcs == NULL) { - aes->aes_set = 0; - return (0); - } - aes->aes_set = AES_SET_WCS; /* Only WCS form set. */ - archive_string_empty(&(aes->aes_mbs)); - archive_string_empty(&(aes->aes_utf8)); - archive_wstrncpy(&(aes->aes_wcs), wcs, len); - return (0); -} - -int -archive_mstring_copy_mbs_len_l(struct archive_mstring *aes, - const char *mbs, size_t len, struct archive_string_conv *sc) -{ - int r; - - if (mbs == NULL) { - aes->aes_set = 0; - return (0); - } - archive_string_empty(&(aes->aes_mbs)); - archive_wstring_empty(&(aes->aes_wcs)); - archive_string_empty(&(aes->aes_utf8)); -#if defined(_WIN32) && !defined(__CYGWIN__) - /* - * Internationalization programming on Windows must use Wide - * characters because Windows platform cannot make locale UTF-8. - */ - if (sc == NULL) { - if (archive_string_append(&(aes->aes_mbs), - mbs, mbsnbytes(mbs, len)) == NULL) { - aes->aes_set = 0; - r = -1; - } else { - aes->aes_set = AES_SET_MBS; - r = 0; - } -#if defined(HAVE_ICONV) - } else if (sc != NULL && sc->cd_w != (iconv_t)-1) { - /* - * This case happens only when MultiByteToWideChar() cannot - * handle sc->from_cp, and we have to iconv in order to - * translate character-set to wchar_t,UTF-16. - */ - iconv_t cd = sc->cd; - unsigned from_cp; - int flag; - - /* - * Translate multi-bytes from some character-set to UTF-8. - */ - sc->cd = sc->cd_w; - r = archive_strncpy_l(&(aes->aes_utf8), mbs, len, sc); - sc->cd = cd; - if (r != 0) { - aes->aes_set = 0; - return (r); - } - aes->aes_set = AES_SET_UTF8; - - /* - * Append the UTF-8 string into wstring. - */ - flag = sc->flag; - sc->flag &= ~(SCONV_NORMALIZATION_C - | SCONV_TO_UTF16| SCONV_FROM_UTF16); - from_cp = sc->from_cp; - sc->from_cp = CP_UTF8; - r = archive_wstring_append_from_mbs_in_codepage(&(aes->aes_wcs), - aes->aes_utf8.s, aes->aes_utf8.length, sc); - sc->flag = flag; - sc->from_cp = from_cp; - if (r == 0) - aes->aes_set |= AES_SET_WCS; -#endif - } else { - r = archive_wstring_append_from_mbs_in_codepage( - &(aes->aes_wcs), mbs, len, sc); - if (r == 0) - aes->aes_set = AES_SET_WCS; - else - aes->aes_set = 0; - } -#else - r = archive_strncpy_l(&(aes->aes_mbs), mbs, len, sc); - if (r == 0) - aes->aes_set = AES_SET_MBS; /* Only MBS form is set now. */ - else - aes->aes_set = 0; -#endif - return (r); -} - -/* - * The 'update' form tries to proactively update all forms of - * this string (WCS and MBS) and returns an error if any of - * them fail. This is used by the 'pax' handler, for instance, - * to detect and report character-conversion failures early while - * still allowing clients to get potentially useful values from - * the more tolerant lazy conversions. (get_mbs and get_wcs will - * strive to give the user something useful, so you can get hopefully - * usable values even if some of the character conversions are failing.) - */ -int -archive_mstring_update_utf8(struct archive *a, struct archive_mstring *aes, - const char *utf8) -{ - struct archive_string_conv *sc; - int r; - - if (utf8 == NULL) { - aes->aes_set = 0; - return (0); /* Succeeded in clearing everything. */ - } - - /* Save the UTF8 string. */ - archive_strcpy(&(aes->aes_utf8), utf8); - - /* Empty the mbs and wcs strings. */ - archive_string_empty(&(aes->aes_mbs)); - archive_wstring_empty(&(aes->aes_wcs)); - - aes->aes_set = AES_SET_UTF8; /* Only UTF8 is set now. */ - - /* Try converting UTF-8 to MBS, return false on failure. */ - sc = archive_string_conversion_from_charset(a, "UTF-8", 1); - if (sc == NULL) - return (-1);/* Couldn't allocate memory for sc. */ - r = archive_strcpy_l(&(aes->aes_mbs), utf8, sc); - if (a == NULL) - free_sconv_object(sc); - if (r != 0) - return (-1); - aes->aes_set = AES_SET_UTF8 | AES_SET_MBS; /* Both UTF8 and MBS set. */ - - /* Try converting MBS to WCS, return false on failure. */ - if (archive_wstring_append_from_mbs(&(aes->aes_wcs), aes->aes_mbs.s, - aes->aes_mbs.length)) - return (-1); - aes->aes_set = AES_SET_UTF8 | AES_SET_WCS | AES_SET_MBS; - - /* All conversions succeeded. */ - return (0); -} diff --git a/thirdparty/libarchive/libarchive/archive_string.h b/thirdparty/libarchive/libarchive/archive_string.h deleted file mode 100644 index 49d7d3064..000000000 --- a/thirdparty/libarchive/libarchive/archive_string.h +++ /dev/null @@ -1,243 +0,0 @@ -/*- - * Copyright (c) 2003-2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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: head/lib/libarchive/archive_string.h 201092 2009-12-28 02:26:06Z kientzle $ - * - */ - -#ifndef ARCHIVE_STRING_H_INCLUDED -#define ARCHIVE_STRING_H_INCLUDED - -#ifndef __LIBARCHIVE_BUILD -#ifndef __LIBARCHIVE_TEST -#error This header is only to be used internally to libarchive. -#endif -#endif - -#include -#ifdef HAVE_STDLIB_H -#include /* required for wchar_t on some systems */ -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_WCHAR_H -#include -#endif - -#include "archive.h" - -/* - * Basic resizable/reusable string support similar to Java's "StringBuffer." - * - * Unlike sbuf(9), the buffers here are fully reusable and track the - * length throughout. - */ - -struct archive_string { - char *s; /* Pointer to the storage */ - size_t length; /* Length of 's' in characters */ - size_t buffer_length; /* Length of malloc-ed storage in bytes. */ -}; - -struct archive_wstring { - wchar_t *s; /* Pointer to the storage */ - size_t length; /* Length of 's' in characters */ - size_t buffer_length; /* Length of malloc-ed storage in bytes. */ -}; - -struct archive_string_conv; - -/* Initialize an archive_string object on the stack or elsewhere. */ -#define archive_string_init(a) \ - do { (a)->s = NULL; (a)->length = 0; (a)->buffer_length = 0; } while(0) - -/* Append a C char to an archive_string, resizing as necessary. */ -struct archive_string * -archive_strappend_char(struct archive_string *, char); - -/* Ditto for a wchar_t and an archive_wstring. */ -struct archive_wstring * -archive_wstrappend_wchar(struct archive_wstring *, wchar_t); - -/* Append a raw array to an archive_string, resizing as necessary */ -struct archive_string * -archive_array_append(struct archive_string *, const char *, size_t); - -/* Convert a Unicode string to current locale and append the result. */ -/* Returns -1 if conversion fails. */ -int -archive_string_append_from_wcs(struct archive_string *, const wchar_t *, size_t); - - -/* Create a string conversion object. - * Return NULL and set a error message if the conversion is not supported - * on the platform. */ -struct archive_string_conv * -archive_string_conversion_to_charset(struct archive *, const char *, int); -struct archive_string_conv * -archive_string_conversion_from_charset(struct archive *, const char *, int); -/* Create the default string conversion object for reading/writing an archive. - * Return NULL if the conversion is unneeded. - * Note: On non Windows platform this always returns NULL. - */ -struct archive_string_conv * -archive_string_default_conversion_for_read(struct archive *); -struct archive_string_conv * -archive_string_default_conversion_for_write(struct archive *); -/* Dispose of a string conversion object. */ -void -archive_string_conversion_free(struct archive *); -const char * -archive_string_conversion_charset_name(struct archive_string_conv *); -void -archive_string_conversion_set_opt(struct archive_string_conv *, int); -#define SCONV_SET_OPT_UTF8_LIBARCHIVE2X 1 -#define SCONV_SET_OPT_NORMALIZATION_C 2 -#define SCONV_SET_OPT_NORMALIZATION_D 4 - - -/* Copy one archive_string to another in locale conversion. - * Return -1 if conversion fails. */ -int -archive_strncpy_l(struct archive_string *, const void *, size_t, - struct archive_string_conv *); - -/* Copy one archive_string to another in locale conversion. - * Return -1 if conversion fails. */ -int -archive_strncat_l(struct archive_string *, const void *, size_t, - struct archive_string_conv *); - - -/* Copy one archive_string to another */ -#define archive_string_copy(dest, src) \ - ((dest)->length = 0, archive_string_concat((dest), (src))) -#define archive_wstring_copy(dest, src) \ - ((dest)->length = 0, archive_wstring_concat((dest), (src))) - -/* Concatenate one archive_string to another */ -void archive_string_concat(struct archive_string *dest, struct archive_string *src); -void archive_wstring_concat(struct archive_wstring *dest, struct archive_wstring *src); - -/* Ensure that the underlying buffer is at least as large as the request. */ -struct archive_string * -archive_string_ensure(struct archive_string *, size_t); -struct archive_wstring * -archive_wstring_ensure(struct archive_wstring *, size_t); - -/* Append C string, which may lack trailing \0. */ -/* The source is declared void * here because this gets used with - * "signed char *", "unsigned char *" and "char *" arguments. - * Declaring it "char *" as with some of the other functions just - * leads to a lot of extra casts. */ -struct archive_string * -archive_strncat(struct archive_string *, const void *, size_t); -struct archive_wstring * -archive_wstrncat(struct archive_wstring *, const wchar_t *, size_t); - -/* Append a C string to an archive_string, resizing as necessary. */ -struct archive_string * -archive_strcat(struct archive_string *, const void *); -struct archive_wstring * -archive_wstrcat(struct archive_wstring *, const wchar_t *); - -/* Copy a C string to an archive_string, resizing as necessary. */ -#define archive_strcpy(as,p) \ - archive_strncpy((as), (p), ((p) == NULL ? 0 : strlen(p))) -#define archive_wstrcpy(as,p) \ - archive_wstrncpy((as), (p), ((p) == NULL ? 0 : wcslen(p))) -#define archive_strcpy_l(as,p,lo) \ - archive_strncpy_l((as), (p), ((p) == NULL ? 0 : strlen(p)), (lo)) - -/* Copy a C string to an archive_string with limit, resizing as necessary. */ -#define archive_strncpy(as,p,l) \ - ((as)->length=0, archive_strncat((as), (p), (l))) -#define archive_wstrncpy(as,p,l) \ - ((as)->length = 0, archive_wstrncat((as), (p), (l))) - -/* Return length of string. */ -#define archive_strlen(a) ((a)->length) - -/* Set string length to zero. */ -#define archive_string_empty(a) ((a)->length = 0) -#define archive_wstring_empty(a) ((a)->length = 0) - -/* Release any allocated storage resources. */ -void archive_string_free(struct archive_string *); -void archive_wstring_free(struct archive_wstring *); - -/* Like 'vsprintf', but resizes the underlying string as necessary. */ -/* Note: This only implements a small subset of standard printf functionality. */ -void archive_string_vsprintf(struct archive_string *, const char *, - va_list) __LA_PRINTF(2, 0); -void archive_string_sprintf(struct archive_string *, const char *, ...) - __LA_PRINTF(2, 3); - -/* Translates from MBS to Unicode. */ -/* Returns non-zero if conversion failed in any way. */ -int archive_wstring_append_from_mbs(struct archive_wstring *dest, - const char *, size_t); - - -/* A "multistring" can hold Unicode, UTF8, or MBS versions of - * the string. If you set and read the same version, no translation - * is done. If you set and read different versions, the library - * will attempt to transparently convert. - */ -struct archive_mstring { - struct archive_string aes_mbs; - struct archive_string aes_utf8; - struct archive_wstring aes_wcs; - struct archive_string aes_mbs_in_locale; - /* Bitmap of which of the above are valid. Because we're lazy - * about malloc-ing and reusing the underlying storage, we - * can't rely on NULL pointers to indicate whether a string - * has been set. */ - int aes_set; -#define AES_SET_MBS 1 -#define AES_SET_UTF8 2 -#define AES_SET_WCS 4 -}; - -void archive_mstring_clean(struct archive_mstring *); -void archive_mstring_copy(struct archive_mstring *dest, struct archive_mstring *src); -int archive_mstring_get_mbs(struct archive *, struct archive_mstring *, const char **); -int archive_mstring_get_utf8(struct archive *, struct archive_mstring *, const char **); -int archive_mstring_get_wcs(struct archive *, struct archive_mstring *, const wchar_t **); -int archive_mstring_get_mbs_l(struct archive *, struct archive_mstring *, const char **, - size_t *, struct archive_string_conv *); -int archive_mstring_copy_mbs(struct archive_mstring *, const char *mbs); -int archive_mstring_copy_mbs_len(struct archive_mstring *, const char *mbs, - size_t); -int archive_mstring_copy_utf8(struct archive_mstring *, const char *utf8); -int archive_mstring_copy_wcs(struct archive_mstring *, const wchar_t *wcs); -int archive_mstring_copy_wcs_len(struct archive_mstring *, - const wchar_t *wcs, size_t); -int archive_mstring_copy_mbs_len_l(struct archive_mstring *, - const char *mbs, size_t, struct archive_string_conv *); -int archive_mstring_update_utf8(struct archive *, struct archive_mstring *aes, const char *utf8); - - -#endif diff --git a/thirdparty/libarchive/libarchive/archive_string_composition.h b/thirdparty/libarchive/libarchive/archive_string_composition.h deleted file mode 100644 index d0ac34096..000000000 --- a/thirdparty/libarchive/libarchive/archive_string_composition.h +++ /dev/null @@ -1,2292 +0,0 @@ -/*- - * Copyright (c) 2011-2012 libarchive Project - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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(S) 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$ - * - */ - -/* - * ATTENTION! - * This file is generated by build/utils/gen_archive_string_composition_h.sh - * from http://unicode.org/Public/6.0.0/ucd/UnicodeData.txt - * - * See also http://unicode.org/report/tr15/ - */ - -#ifndef ARCHIVE_STRING_COMPOSITION_H_INCLUDED -#define ARCHIVE_STRING_COMPOSITION_H_INCLUDED - -#ifndef __LIBARCHIVE_BUILD -#error This header is only to be used internally to libarchive. -#endif - -struct unicode_composition_table { - uint32_t cp1; - uint32_t cp2; - uint32_t nfc; -}; - -static const struct unicode_composition_table u_composition_table[] = { - { 0x0003C , 0x00338 , 0x0226E }, - { 0x0003D , 0x00338 , 0x02260 }, - { 0x0003E , 0x00338 , 0x0226F }, - { 0x00041 , 0x00300 , 0x000C0 }, - { 0x00041 , 0x00301 , 0x000C1 }, - { 0x00041 , 0x00302 , 0x000C2 }, - { 0x00041 , 0x00303 , 0x000C3 }, - { 0x00041 , 0x00304 , 0x00100 }, - { 0x00041 , 0x00306 , 0x00102 }, - { 0x00041 , 0x00307 , 0x00226 }, - { 0x00041 , 0x00308 , 0x000C4 }, - { 0x00041 , 0x00309 , 0x01EA2 }, - { 0x00041 , 0x0030A , 0x000C5 }, - { 0x00041 , 0x0030C , 0x001CD }, - { 0x00041 , 0x0030F , 0x00200 }, - { 0x00041 , 0x00311 , 0x00202 }, - { 0x00041 , 0x00323 , 0x01EA0 }, - { 0x00041 , 0x00325 , 0x01E00 }, - { 0x00041 , 0x00328 , 0x00104 }, - { 0x00042 , 0x00307 , 0x01E02 }, - { 0x00042 , 0x00323 , 0x01E04 }, - { 0x00042 , 0x00331 , 0x01E06 }, - { 0x00043 , 0x00301 , 0x00106 }, - { 0x00043 , 0x00302 , 0x00108 }, - { 0x00043 , 0x00307 , 0x0010A }, - { 0x00043 , 0x0030C , 0x0010C }, - { 0x00043 , 0x00327 , 0x000C7 }, - { 0x00044 , 0x00307 , 0x01E0A }, - { 0x00044 , 0x0030C , 0x0010E }, - { 0x00044 , 0x00323 , 0x01E0C }, - { 0x00044 , 0x00327 , 0x01E10 }, - { 0x00044 , 0x0032D , 0x01E12 }, - { 0x00044 , 0x00331 , 0x01E0E }, - { 0x00045 , 0x00300 , 0x000C8 }, - { 0x00045 , 0x00301 , 0x000C9 }, - { 0x00045 , 0x00302 , 0x000CA }, - { 0x00045 , 0x00303 , 0x01EBC }, - { 0x00045 , 0x00304 , 0x00112 }, - { 0x00045 , 0x00306 , 0x00114 }, - { 0x00045 , 0x00307 , 0x00116 }, - { 0x00045 , 0x00308 , 0x000CB }, - { 0x00045 , 0x00309 , 0x01EBA }, - { 0x00045 , 0x0030C , 0x0011A }, - { 0x00045 , 0x0030F , 0x00204 }, - { 0x00045 , 0x00311 , 0x00206 }, - { 0x00045 , 0x00323 , 0x01EB8 }, - { 0x00045 , 0x00327 , 0x00228 }, - { 0x00045 , 0x00328 , 0x00118 }, - { 0x00045 , 0x0032D , 0x01E18 }, - { 0x00045 , 0x00330 , 0x01E1A }, - { 0x00046 , 0x00307 , 0x01E1E }, - { 0x00047 , 0x00301 , 0x001F4 }, - { 0x00047 , 0x00302 , 0x0011C }, - { 0x00047 , 0x00304 , 0x01E20 }, - { 0x00047 , 0x00306 , 0x0011E }, - { 0x00047 , 0x00307 , 0x00120 }, - { 0x00047 , 0x0030C , 0x001E6 }, - { 0x00047 , 0x00327 , 0x00122 }, - { 0x00048 , 0x00302 , 0x00124 }, - { 0x00048 , 0x00307 , 0x01E22 }, - { 0x00048 , 0x00308 , 0x01E26 }, - { 0x00048 , 0x0030C , 0x0021E }, - { 0x00048 , 0x00323 , 0x01E24 }, - { 0x00048 , 0x00327 , 0x01E28 }, - { 0x00048 , 0x0032E , 0x01E2A }, - { 0x00049 , 0x00300 , 0x000CC }, - { 0x00049 , 0x00301 , 0x000CD }, - { 0x00049 , 0x00302 , 0x000CE }, - { 0x00049 , 0x00303 , 0x00128 }, - { 0x00049 , 0x00304 , 0x0012A }, - { 0x00049 , 0x00306 , 0x0012C }, - { 0x00049 , 0x00307 , 0x00130 }, - { 0x00049 , 0x00308 , 0x000CF }, - { 0x00049 , 0x00309 , 0x01EC8 }, - { 0x00049 , 0x0030C , 0x001CF }, - { 0x00049 , 0x0030F , 0x00208 }, - { 0x00049 , 0x00311 , 0x0020A }, - { 0x00049 , 0x00323 , 0x01ECA }, - { 0x00049 , 0x00328 , 0x0012E }, - { 0x00049 , 0x00330 , 0x01E2C }, - { 0x0004A , 0x00302 , 0x00134 }, - { 0x0004B , 0x00301 , 0x01E30 }, - { 0x0004B , 0x0030C , 0x001E8 }, - { 0x0004B , 0x00323 , 0x01E32 }, - { 0x0004B , 0x00327 , 0x00136 }, - { 0x0004B , 0x00331 , 0x01E34 }, - { 0x0004C , 0x00301 , 0x00139 }, - { 0x0004C , 0x0030C , 0x0013D }, - { 0x0004C , 0x00323 , 0x01E36 }, - { 0x0004C , 0x00327 , 0x0013B }, - { 0x0004C , 0x0032D , 0x01E3C }, - { 0x0004C , 0x00331 , 0x01E3A }, - { 0x0004D , 0x00301 , 0x01E3E }, - { 0x0004D , 0x00307 , 0x01E40 }, - { 0x0004D , 0x00323 , 0x01E42 }, - { 0x0004E , 0x00300 , 0x001F8 }, - { 0x0004E , 0x00301 , 0x00143 }, - { 0x0004E , 0x00303 , 0x000D1 }, - { 0x0004E , 0x00307 , 0x01E44 }, - { 0x0004E , 0x0030C , 0x00147 }, - { 0x0004E , 0x00323 , 0x01E46 }, - { 0x0004E , 0x00327 , 0x00145 }, - { 0x0004E , 0x0032D , 0x01E4A }, - { 0x0004E , 0x00331 , 0x01E48 }, - { 0x0004F , 0x00300 , 0x000D2 }, - { 0x0004F , 0x00301 , 0x000D3 }, - { 0x0004F , 0x00302 , 0x000D4 }, - { 0x0004F , 0x00303 , 0x000D5 }, - { 0x0004F , 0x00304 , 0x0014C }, - { 0x0004F , 0x00306 , 0x0014E }, - { 0x0004F , 0x00307 , 0x0022E }, - { 0x0004F , 0x00308 , 0x000D6 }, - { 0x0004F , 0x00309 , 0x01ECE }, - { 0x0004F , 0x0030B , 0x00150 }, - { 0x0004F , 0x0030C , 0x001D1 }, - { 0x0004F , 0x0030F , 0x0020C }, - { 0x0004F , 0x00311 , 0x0020E }, - { 0x0004F , 0x0031B , 0x001A0 }, - { 0x0004F , 0x00323 , 0x01ECC }, - { 0x0004F , 0x00328 , 0x001EA }, - { 0x00050 , 0x00301 , 0x01E54 }, - { 0x00050 , 0x00307 , 0x01E56 }, - { 0x00052 , 0x00301 , 0x00154 }, - { 0x00052 , 0x00307 , 0x01E58 }, - { 0x00052 , 0x0030C , 0x00158 }, - { 0x00052 , 0x0030F , 0x00210 }, - { 0x00052 , 0x00311 , 0x00212 }, - { 0x00052 , 0x00323 , 0x01E5A }, - { 0x00052 , 0x00327 , 0x00156 }, - { 0x00052 , 0x00331 , 0x01E5E }, - { 0x00053 , 0x00301 , 0x0015A }, - { 0x00053 , 0x00302 , 0x0015C }, - { 0x00053 , 0x00307 , 0x01E60 }, - { 0x00053 , 0x0030C , 0x00160 }, - { 0x00053 , 0x00323 , 0x01E62 }, - { 0x00053 , 0x00326 , 0x00218 }, - { 0x00053 , 0x00327 , 0x0015E }, - { 0x00054 , 0x00307 , 0x01E6A }, - { 0x00054 , 0x0030C , 0x00164 }, - { 0x00054 , 0x00323 , 0x01E6C }, - { 0x00054 , 0x00326 , 0x0021A }, - { 0x00054 , 0x00327 , 0x00162 }, - { 0x00054 , 0x0032D , 0x01E70 }, - { 0x00054 , 0x00331 , 0x01E6E }, - { 0x00055 , 0x00300 , 0x000D9 }, - { 0x00055 , 0x00301 , 0x000DA }, - { 0x00055 , 0x00302 , 0x000DB }, - { 0x00055 , 0x00303 , 0x00168 }, - { 0x00055 , 0x00304 , 0x0016A }, - { 0x00055 , 0x00306 , 0x0016C }, - { 0x00055 , 0x00308 , 0x000DC }, - { 0x00055 , 0x00309 , 0x01EE6 }, - { 0x00055 , 0x0030A , 0x0016E }, - { 0x00055 , 0x0030B , 0x00170 }, - { 0x00055 , 0x0030C , 0x001D3 }, - { 0x00055 , 0x0030F , 0x00214 }, - { 0x00055 , 0x00311 , 0x00216 }, - { 0x00055 , 0x0031B , 0x001AF }, - { 0x00055 , 0x00323 , 0x01EE4 }, - { 0x00055 , 0x00324 , 0x01E72 }, - { 0x00055 , 0x00328 , 0x00172 }, - { 0x00055 , 0x0032D , 0x01E76 }, - { 0x00055 , 0x00330 , 0x01E74 }, - { 0x00056 , 0x00303 , 0x01E7C }, - { 0x00056 , 0x00323 , 0x01E7E }, - { 0x00057 , 0x00300 , 0x01E80 }, - { 0x00057 , 0x00301 , 0x01E82 }, - { 0x00057 , 0x00302 , 0x00174 }, - { 0x00057 , 0x00307 , 0x01E86 }, - { 0x00057 , 0x00308 , 0x01E84 }, - { 0x00057 , 0x00323 , 0x01E88 }, - { 0x00058 , 0x00307 , 0x01E8A }, - { 0x00058 , 0x00308 , 0x01E8C }, - { 0x00059 , 0x00300 , 0x01EF2 }, - { 0x00059 , 0x00301 , 0x000DD }, - { 0x00059 , 0x00302 , 0x00176 }, - { 0x00059 , 0x00303 , 0x01EF8 }, - { 0x00059 , 0x00304 , 0x00232 }, - { 0x00059 , 0x00307 , 0x01E8E }, - { 0x00059 , 0x00308 , 0x00178 }, - { 0x00059 , 0x00309 , 0x01EF6 }, - { 0x00059 , 0x00323 , 0x01EF4 }, - { 0x0005A , 0x00301 , 0x00179 }, - { 0x0005A , 0x00302 , 0x01E90 }, - { 0x0005A , 0x00307 , 0x0017B }, - { 0x0005A , 0x0030C , 0x0017D }, - { 0x0005A , 0x00323 , 0x01E92 }, - { 0x0005A , 0x00331 , 0x01E94 }, - { 0x00061 , 0x00300 , 0x000E0 }, - { 0x00061 , 0x00301 , 0x000E1 }, - { 0x00061 , 0x00302 , 0x000E2 }, - { 0x00061 , 0x00303 , 0x000E3 }, - { 0x00061 , 0x00304 , 0x00101 }, - { 0x00061 , 0x00306 , 0x00103 }, - { 0x00061 , 0x00307 , 0x00227 }, - { 0x00061 , 0x00308 , 0x000E4 }, - { 0x00061 , 0x00309 , 0x01EA3 }, - { 0x00061 , 0x0030A , 0x000E5 }, - { 0x00061 , 0x0030C , 0x001CE }, - { 0x00061 , 0x0030F , 0x00201 }, - { 0x00061 , 0x00311 , 0x00203 }, - { 0x00061 , 0x00323 , 0x01EA1 }, - { 0x00061 , 0x00325 , 0x01E01 }, - { 0x00061 , 0x00328 , 0x00105 }, - { 0x00062 , 0x00307 , 0x01E03 }, - { 0x00062 , 0x00323 , 0x01E05 }, - { 0x00062 , 0x00331 , 0x01E07 }, - { 0x00063 , 0x00301 , 0x00107 }, - { 0x00063 , 0x00302 , 0x00109 }, - { 0x00063 , 0x00307 , 0x0010B }, - { 0x00063 , 0x0030C , 0x0010D }, - { 0x00063 , 0x00327 , 0x000E7 }, - { 0x00064 , 0x00307 , 0x01E0B }, - { 0x00064 , 0x0030C , 0x0010F }, - { 0x00064 , 0x00323 , 0x01E0D }, - { 0x00064 , 0x00327 , 0x01E11 }, - { 0x00064 , 0x0032D , 0x01E13 }, - { 0x00064 , 0x00331 , 0x01E0F }, - { 0x00065 , 0x00300 , 0x000E8 }, - { 0x00065 , 0x00301 , 0x000E9 }, - { 0x00065 , 0x00302 , 0x000EA }, - { 0x00065 , 0x00303 , 0x01EBD }, - { 0x00065 , 0x00304 , 0x00113 }, - { 0x00065 , 0x00306 , 0x00115 }, - { 0x00065 , 0x00307 , 0x00117 }, - { 0x00065 , 0x00308 , 0x000EB }, - { 0x00065 , 0x00309 , 0x01EBB }, - { 0x00065 , 0x0030C , 0x0011B }, - { 0x00065 , 0x0030F , 0x00205 }, - { 0x00065 , 0x00311 , 0x00207 }, - { 0x00065 , 0x00323 , 0x01EB9 }, - { 0x00065 , 0x00327 , 0x00229 }, - { 0x00065 , 0x00328 , 0x00119 }, - { 0x00065 , 0x0032D , 0x01E19 }, - { 0x00065 , 0x00330 , 0x01E1B }, - { 0x00066 , 0x00307 , 0x01E1F }, - { 0x00067 , 0x00301 , 0x001F5 }, - { 0x00067 , 0x00302 , 0x0011D }, - { 0x00067 , 0x00304 , 0x01E21 }, - { 0x00067 , 0x00306 , 0x0011F }, - { 0x00067 , 0x00307 , 0x00121 }, - { 0x00067 , 0x0030C , 0x001E7 }, - { 0x00067 , 0x00327 , 0x00123 }, - { 0x00068 , 0x00302 , 0x00125 }, - { 0x00068 , 0x00307 , 0x01E23 }, - { 0x00068 , 0x00308 , 0x01E27 }, - { 0x00068 , 0x0030C , 0x0021F }, - { 0x00068 , 0x00323 , 0x01E25 }, - { 0x00068 , 0x00327 , 0x01E29 }, - { 0x00068 , 0x0032E , 0x01E2B }, - { 0x00068 , 0x00331 , 0x01E96 }, - { 0x00069 , 0x00300 , 0x000EC }, - { 0x00069 , 0x00301 , 0x000ED }, - { 0x00069 , 0x00302 , 0x000EE }, - { 0x00069 , 0x00303 , 0x00129 }, - { 0x00069 , 0x00304 , 0x0012B }, - { 0x00069 , 0x00306 , 0x0012D }, - { 0x00069 , 0x00308 , 0x000EF }, - { 0x00069 , 0x00309 , 0x01EC9 }, - { 0x00069 , 0x0030C , 0x001D0 }, - { 0x00069 , 0x0030F , 0x00209 }, - { 0x00069 , 0x00311 , 0x0020B }, - { 0x00069 , 0x00323 , 0x01ECB }, - { 0x00069 , 0x00328 , 0x0012F }, - { 0x00069 , 0x00330 , 0x01E2D }, - { 0x0006A , 0x00302 , 0x00135 }, - { 0x0006A , 0x0030C , 0x001F0 }, - { 0x0006B , 0x00301 , 0x01E31 }, - { 0x0006B , 0x0030C , 0x001E9 }, - { 0x0006B , 0x00323 , 0x01E33 }, - { 0x0006B , 0x00327 , 0x00137 }, - { 0x0006B , 0x00331 , 0x01E35 }, - { 0x0006C , 0x00301 , 0x0013A }, - { 0x0006C , 0x0030C , 0x0013E }, - { 0x0006C , 0x00323 , 0x01E37 }, - { 0x0006C , 0x00327 , 0x0013C }, - { 0x0006C , 0x0032D , 0x01E3D }, - { 0x0006C , 0x00331 , 0x01E3B }, - { 0x0006D , 0x00301 , 0x01E3F }, - { 0x0006D , 0x00307 , 0x01E41 }, - { 0x0006D , 0x00323 , 0x01E43 }, - { 0x0006E , 0x00300 , 0x001F9 }, - { 0x0006E , 0x00301 , 0x00144 }, - { 0x0006E , 0x00303 , 0x000F1 }, - { 0x0006E , 0x00307 , 0x01E45 }, - { 0x0006E , 0x0030C , 0x00148 }, - { 0x0006E , 0x00323 , 0x01E47 }, - { 0x0006E , 0x00327 , 0x00146 }, - { 0x0006E , 0x0032D , 0x01E4B }, - { 0x0006E , 0x00331 , 0x01E49 }, - { 0x0006F , 0x00300 , 0x000F2 }, - { 0x0006F , 0x00301 , 0x000F3 }, - { 0x0006F , 0x00302 , 0x000F4 }, - { 0x0006F , 0x00303 , 0x000F5 }, - { 0x0006F , 0x00304 , 0x0014D }, - { 0x0006F , 0x00306 , 0x0014F }, - { 0x0006F , 0x00307 , 0x0022F }, - { 0x0006F , 0x00308 , 0x000F6 }, - { 0x0006F , 0x00309 , 0x01ECF }, - { 0x0006F , 0x0030B , 0x00151 }, - { 0x0006F , 0x0030C , 0x001D2 }, - { 0x0006F , 0x0030F , 0x0020D }, - { 0x0006F , 0x00311 , 0x0020F }, - { 0x0006F , 0x0031B , 0x001A1 }, - { 0x0006F , 0x00323 , 0x01ECD }, - { 0x0006F , 0x00328 , 0x001EB }, - { 0x00070 , 0x00301 , 0x01E55 }, - { 0x00070 , 0x00307 , 0x01E57 }, - { 0x00072 , 0x00301 , 0x00155 }, - { 0x00072 , 0x00307 , 0x01E59 }, - { 0x00072 , 0x0030C , 0x00159 }, - { 0x00072 , 0x0030F , 0x00211 }, - { 0x00072 , 0x00311 , 0x00213 }, - { 0x00072 , 0x00323 , 0x01E5B }, - { 0x00072 , 0x00327 , 0x00157 }, - { 0x00072 , 0x00331 , 0x01E5F }, - { 0x00073 , 0x00301 , 0x0015B }, - { 0x00073 , 0x00302 , 0x0015D }, - { 0x00073 , 0x00307 , 0x01E61 }, - { 0x00073 , 0x0030C , 0x00161 }, - { 0x00073 , 0x00323 , 0x01E63 }, - { 0x00073 , 0x00326 , 0x00219 }, - { 0x00073 , 0x00327 , 0x0015F }, - { 0x00074 , 0x00307 , 0x01E6B }, - { 0x00074 , 0x00308 , 0x01E97 }, - { 0x00074 , 0x0030C , 0x00165 }, - { 0x00074 , 0x00323 , 0x01E6D }, - { 0x00074 , 0x00326 , 0x0021B }, - { 0x00074 , 0x00327 , 0x00163 }, - { 0x00074 , 0x0032D , 0x01E71 }, - { 0x00074 , 0x00331 , 0x01E6F }, - { 0x00075 , 0x00300 , 0x000F9 }, - { 0x00075 , 0x00301 , 0x000FA }, - { 0x00075 , 0x00302 , 0x000FB }, - { 0x00075 , 0x00303 , 0x00169 }, - { 0x00075 , 0x00304 , 0x0016B }, - { 0x00075 , 0x00306 , 0x0016D }, - { 0x00075 , 0x00308 , 0x000FC }, - { 0x00075 , 0x00309 , 0x01EE7 }, - { 0x00075 , 0x0030A , 0x0016F }, - { 0x00075 , 0x0030B , 0x00171 }, - { 0x00075 , 0x0030C , 0x001D4 }, - { 0x00075 , 0x0030F , 0x00215 }, - { 0x00075 , 0x00311 , 0x00217 }, - { 0x00075 , 0x0031B , 0x001B0 }, - { 0x00075 , 0x00323 , 0x01EE5 }, - { 0x00075 , 0x00324 , 0x01E73 }, - { 0x00075 , 0x00328 , 0x00173 }, - { 0x00075 , 0x0032D , 0x01E77 }, - { 0x00075 , 0x00330 , 0x01E75 }, - { 0x00076 , 0x00303 , 0x01E7D }, - { 0x00076 , 0x00323 , 0x01E7F }, - { 0x00077 , 0x00300 , 0x01E81 }, - { 0x00077 , 0x00301 , 0x01E83 }, - { 0x00077 , 0x00302 , 0x00175 }, - { 0x00077 , 0x00307 , 0x01E87 }, - { 0x00077 , 0x00308 , 0x01E85 }, - { 0x00077 , 0x0030A , 0x01E98 }, - { 0x00077 , 0x00323 , 0x01E89 }, - { 0x00078 , 0x00307 , 0x01E8B }, - { 0x00078 , 0x00308 , 0x01E8D }, - { 0x00079 , 0x00300 , 0x01EF3 }, - { 0x00079 , 0x00301 , 0x000FD }, - { 0x00079 , 0x00302 , 0x00177 }, - { 0x00079 , 0x00303 , 0x01EF9 }, - { 0x00079 , 0x00304 , 0x00233 }, - { 0x00079 , 0x00307 , 0x01E8F }, - { 0x00079 , 0x00308 , 0x000FF }, - { 0x00079 , 0x00309 , 0x01EF7 }, - { 0x00079 , 0x0030A , 0x01E99 }, - { 0x00079 , 0x00323 , 0x01EF5 }, - { 0x0007A , 0x00301 , 0x0017A }, - { 0x0007A , 0x00302 , 0x01E91 }, - { 0x0007A , 0x00307 , 0x0017C }, - { 0x0007A , 0x0030C , 0x0017E }, - { 0x0007A , 0x00323 , 0x01E93 }, - { 0x0007A , 0x00331 , 0x01E95 }, - { 0x000A8 , 0x00300 , 0x01FED }, - { 0x000A8 , 0x00301 , 0x00385 }, - { 0x000A8 , 0x00342 , 0x01FC1 }, - { 0x000C2 , 0x00300 , 0x01EA6 }, - { 0x000C2 , 0x00301 , 0x01EA4 }, - { 0x000C2 , 0x00303 , 0x01EAA }, - { 0x000C2 , 0x00309 , 0x01EA8 }, - { 0x000C4 , 0x00304 , 0x001DE }, - { 0x000C5 , 0x00301 , 0x001FA }, - { 0x000C6 , 0x00301 , 0x001FC }, - { 0x000C6 , 0x00304 , 0x001E2 }, - { 0x000C7 , 0x00301 , 0x01E08 }, - { 0x000CA , 0x00300 , 0x01EC0 }, - { 0x000CA , 0x00301 , 0x01EBE }, - { 0x000CA , 0x00303 , 0x01EC4 }, - { 0x000CA , 0x00309 , 0x01EC2 }, - { 0x000CF , 0x00301 , 0x01E2E }, - { 0x000D4 , 0x00300 , 0x01ED2 }, - { 0x000D4 , 0x00301 , 0x01ED0 }, - { 0x000D4 , 0x00303 , 0x01ED6 }, - { 0x000D4 , 0x00309 , 0x01ED4 }, - { 0x000D5 , 0x00301 , 0x01E4C }, - { 0x000D5 , 0x00304 , 0x0022C }, - { 0x000D5 , 0x00308 , 0x01E4E }, - { 0x000D6 , 0x00304 , 0x0022A }, - { 0x000D8 , 0x00301 , 0x001FE }, - { 0x000DC , 0x00300 , 0x001DB }, - { 0x000DC , 0x00301 , 0x001D7 }, - { 0x000DC , 0x00304 , 0x001D5 }, - { 0x000DC , 0x0030C , 0x001D9 }, - { 0x000E2 , 0x00300 , 0x01EA7 }, - { 0x000E2 , 0x00301 , 0x01EA5 }, - { 0x000E2 , 0x00303 , 0x01EAB }, - { 0x000E2 , 0x00309 , 0x01EA9 }, - { 0x000E4 , 0x00304 , 0x001DF }, - { 0x000E5 , 0x00301 , 0x001FB }, - { 0x000E6 , 0x00301 , 0x001FD }, - { 0x000E6 , 0x00304 , 0x001E3 }, - { 0x000E7 , 0x00301 , 0x01E09 }, - { 0x000EA , 0x00300 , 0x01EC1 }, - { 0x000EA , 0x00301 , 0x01EBF }, - { 0x000EA , 0x00303 , 0x01EC5 }, - { 0x000EA , 0x00309 , 0x01EC3 }, - { 0x000EF , 0x00301 , 0x01E2F }, - { 0x000F4 , 0x00300 , 0x01ED3 }, - { 0x000F4 , 0x00301 , 0x01ED1 }, - { 0x000F4 , 0x00303 , 0x01ED7 }, - { 0x000F4 , 0x00309 , 0x01ED5 }, - { 0x000F5 , 0x00301 , 0x01E4D }, - { 0x000F5 , 0x00304 , 0x0022D }, - { 0x000F5 , 0x00308 , 0x01E4F }, - { 0x000F6 , 0x00304 , 0x0022B }, - { 0x000F8 , 0x00301 , 0x001FF }, - { 0x000FC , 0x00300 , 0x001DC }, - { 0x000FC , 0x00301 , 0x001D8 }, - { 0x000FC , 0x00304 , 0x001D6 }, - { 0x000FC , 0x0030C , 0x001DA }, - { 0x00102 , 0x00300 , 0x01EB0 }, - { 0x00102 , 0x00301 , 0x01EAE }, - { 0x00102 , 0x00303 , 0x01EB4 }, - { 0x00102 , 0x00309 , 0x01EB2 }, - { 0x00103 , 0x00300 , 0x01EB1 }, - { 0x00103 , 0x00301 , 0x01EAF }, - { 0x00103 , 0x00303 , 0x01EB5 }, - { 0x00103 , 0x00309 , 0x01EB3 }, - { 0x00112 , 0x00300 , 0x01E14 }, - { 0x00112 , 0x00301 , 0x01E16 }, - { 0x00113 , 0x00300 , 0x01E15 }, - { 0x00113 , 0x00301 , 0x01E17 }, - { 0x0014C , 0x00300 , 0x01E50 }, - { 0x0014C , 0x00301 , 0x01E52 }, - { 0x0014D , 0x00300 , 0x01E51 }, - { 0x0014D , 0x00301 , 0x01E53 }, - { 0x0015A , 0x00307 , 0x01E64 }, - { 0x0015B , 0x00307 , 0x01E65 }, - { 0x00160 , 0x00307 , 0x01E66 }, - { 0x00161 , 0x00307 , 0x01E67 }, - { 0x00168 , 0x00301 , 0x01E78 }, - { 0x00169 , 0x00301 , 0x01E79 }, - { 0x0016A , 0x00308 , 0x01E7A }, - { 0x0016B , 0x00308 , 0x01E7B }, - { 0x0017F , 0x00307 , 0x01E9B }, - { 0x001A0 , 0x00300 , 0x01EDC }, - { 0x001A0 , 0x00301 , 0x01EDA }, - { 0x001A0 , 0x00303 , 0x01EE0 }, - { 0x001A0 , 0x00309 , 0x01EDE }, - { 0x001A0 , 0x00323 , 0x01EE2 }, - { 0x001A1 , 0x00300 , 0x01EDD }, - { 0x001A1 , 0x00301 , 0x01EDB }, - { 0x001A1 , 0x00303 , 0x01EE1 }, - { 0x001A1 , 0x00309 , 0x01EDF }, - { 0x001A1 , 0x00323 , 0x01EE3 }, - { 0x001AF , 0x00300 , 0x01EEA }, - { 0x001AF , 0x00301 , 0x01EE8 }, - { 0x001AF , 0x00303 , 0x01EEE }, - { 0x001AF , 0x00309 , 0x01EEC }, - { 0x001AF , 0x00323 , 0x01EF0 }, - { 0x001B0 , 0x00300 , 0x01EEB }, - { 0x001B0 , 0x00301 , 0x01EE9 }, - { 0x001B0 , 0x00303 , 0x01EEF }, - { 0x001B0 , 0x00309 , 0x01EED }, - { 0x001B0 , 0x00323 , 0x01EF1 }, - { 0x001B7 , 0x0030C , 0x001EE }, - { 0x001EA , 0x00304 , 0x001EC }, - { 0x001EB , 0x00304 , 0x001ED }, - { 0x00226 , 0x00304 , 0x001E0 }, - { 0x00227 , 0x00304 , 0x001E1 }, - { 0x00228 , 0x00306 , 0x01E1C }, - { 0x00229 , 0x00306 , 0x01E1D }, - { 0x0022E , 0x00304 , 0x00230 }, - { 0x0022F , 0x00304 , 0x00231 }, - { 0x00292 , 0x0030C , 0x001EF }, - { 0x00391 , 0x00300 , 0x01FBA }, - { 0x00391 , 0x00301 , 0x00386 }, - { 0x00391 , 0x00304 , 0x01FB9 }, - { 0x00391 , 0x00306 , 0x01FB8 }, - { 0x00391 , 0x00313 , 0x01F08 }, - { 0x00391 , 0x00314 , 0x01F09 }, - { 0x00391 , 0x00345 , 0x01FBC }, - { 0x00395 , 0x00300 , 0x01FC8 }, - { 0x00395 , 0x00301 , 0x00388 }, - { 0x00395 , 0x00313 , 0x01F18 }, - { 0x00395 , 0x00314 , 0x01F19 }, - { 0x00397 , 0x00300 , 0x01FCA }, - { 0x00397 , 0x00301 , 0x00389 }, - { 0x00397 , 0x00313 , 0x01F28 }, - { 0x00397 , 0x00314 , 0x01F29 }, - { 0x00397 , 0x00345 , 0x01FCC }, - { 0x00399 , 0x00300 , 0x01FDA }, - { 0x00399 , 0x00301 , 0x0038A }, - { 0x00399 , 0x00304 , 0x01FD9 }, - { 0x00399 , 0x00306 , 0x01FD8 }, - { 0x00399 , 0x00308 , 0x003AA }, - { 0x00399 , 0x00313 , 0x01F38 }, - { 0x00399 , 0x00314 , 0x01F39 }, - { 0x0039F , 0x00300 , 0x01FF8 }, - { 0x0039F , 0x00301 , 0x0038C }, - { 0x0039F , 0x00313 , 0x01F48 }, - { 0x0039F , 0x00314 , 0x01F49 }, - { 0x003A1 , 0x00314 , 0x01FEC }, - { 0x003A5 , 0x00300 , 0x01FEA }, - { 0x003A5 , 0x00301 , 0x0038E }, - { 0x003A5 , 0x00304 , 0x01FE9 }, - { 0x003A5 , 0x00306 , 0x01FE8 }, - { 0x003A5 , 0x00308 , 0x003AB }, - { 0x003A5 , 0x00314 , 0x01F59 }, - { 0x003A9 , 0x00300 , 0x01FFA }, - { 0x003A9 , 0x00301 , 0x0038F }, - { 0x003A9 , 0x00313 , 0x01F68 }, - { 0x003A9 , 0x00314 , 0x01F69 }, - { 0x003A9 , 0x00345 , 0x01FFC }, - { 0x003AC , 0x00345 , 0x01FB4 }, - { 0x003AE , 0x00345 , 0x01FC4 }, - { 0x003B1 , 0x00300 , 0x01F70 }, - { 0x003B1 , 0x00301 , 0x003AC }, - { 0x003B1 , 0x00304 , 0x01FB1 }, - { 0x003B1 , 0x00306 , 0x01FB0 }, - { 0x003B1 , 0x00313 , 0x01F00 }, - { 0x003B1 , 0x00314 , 0x01F01 }, - { 0x003B1 , 0x00342 , 0x01FB6 }, - { 0x003B1 , 0x00345 , 0x01FB3 }, - { 0x003B5 , 0x00300 , 0x01F72 }, - { 0x003B5 , 0x00301 , 0x003AD }, - { 0x003B5 , 0x00313 , 0x01F10 }, - { 0x003B5 , 0x00314 , 0x01F11 }, - { 0x003B7 , 0x00300 , 0x01F74 }, - { 0x003B7 , 0x00301 , 0x003AE }, - { 0x003B7 , 0x00313 , 0x01F20 }, - { 0x003B7 , 0x00314 , 0x01F21 }, - { 0x003B7 , 0x00342 , 0x01FC6 }, - { 0x003B7 , 0x00345 , 0x01FC3 }, - { 0x003B9 , 0x00300 , 0x01F76 }, - { 0x003B9 , 0x00301 , 0x003AF }, - { 0x003B9 , 0x00304 , 0x01FD1 }, - { 0x003B9 , 0x00306 , 0x01FD0 }, - { 0x003B9 , 0x00308 , 0x003CA }, - { 0x003B9 , 0x00313 , 0x01F30 }, - { 0x003B9 , 0x00314 , 0x01F31 }, - { 0x003B9 , 0x00342 , 0x01FD6 }, - { 0x003BF , 0x00300 , 0x01F78 }, - { 0x003BF , 0x00301 , 0x003CC }, - { 0x003BF , 0x00313 , 0x01F40 }, - { 0x003BF , 0x00314 , 0x01F41 }, - { 0x003C1 , 0x00313 , 0x01FE4 }, - { 0x003C1 , 0x00314 , 0x01FE5 }, - { 0x003C5 , 0x00300 , 0x01F7A }, - { 0x003C5 , 0x00301 , 0x003CD }, - { 0x003C5 , 0x00304 , 0x01FE1 }, - { 0x003C5 , 0x00306 , 0x01FE0 }, - { 0x003C5 , 0x00308 , 0x003CB }, - { 0x003C5 , 0x00313 , 0x01F50 }, - { 0x003C5 , 0x00314 , 0x01F51 }, - { 0x003C5 , 0x00342 , 0x01FE6 }, - { 0x003C9 , 0x00300 , 0x01F7C }, - { 0x003C9 , 0x00301 , 0x003CE }, - { 0x003C9 , 0x00313 , 0x01F60 }, - { 0x003C9 , 0x00314 , 0x01F61 }, - { 0x003C9 , 0x00342 , 0x01FF6 }, - { 0x003C9 , 0x00345 , 0x01FF3 }, - { 0x003CA , 0x00300 , 0x01FD2 }, - { 0x003CA , 0x00301 , 0x00390 }, - { 0x003CA , 0x00342 , 0x01FD7 }, - { 0x003CB , 0x00300 , 0x01FE2 }, - { 0x003CB , 0x00301 , 0x003B0 }, - { 0x003CB , 0x00342 , 0x01FE7 }, - { 0x003CE , 0x00345 , 0x01FF4 }, - { 0x003D2 , 0x00301 , 0x003D3 }, - { 0x003D2 , 0x00308 , 0x003D4 }, - { 0x00406 , 0x00308 , 0x00407 }, - { 0x00410 , 0x00306 , 0x004D0 }, - { 0x00410 , 0x00308 , 0x004D2 }, - { 0x00413 , 0x00301 , 0x00403 }, - { 0x00415 , 0x00300 , 0x00400 }, - { 0x00415 , 0x00306 , 0x004D6 }, - { 0x00415 , 0x00308 , 0x00401 }, - { 0x00416 , 0x00306 , 0x004C1 }, - { 0x00416 , 0x00308 , 0x004DC }, - { 0x00417 , 0x00308 , 0x004DE }, - { 0x00418 , 0x00300 , 0x0040D }, - { 0x00418 , 0x00304 , 0x004E2 }, - { 0x00418 , 0x00306 , 0x00419 }, - { 0x00418 , 0x00308 , 0x004E4 }, - { 0x0041A , 0x00301 , 0x0040C }, - { 0x0041E , 0x00308 , 0x004E6 }, - { 0x00423 , 0x00304 , 0x004EE }, - { 0x00423 , 0x00306 , 0x0040E }, - { 0x00423 , 0x00308 , 0x004F0 }, - { 0x00423 , 0x0030B , 0x004F2 }, - { 0x00427 , 0x00308 , 0x004F4 }, - { 0x0042B , 0x00308 , 0x004F8 }, - { 0x0042D , 0x00308 , 0x004EC }, - { 0x00430 , 0x00306 , 0x004D1 }, - { 0x00430 , 0x00308 , 0x004D3 }, - { 0x00433 , 0x00301 , 0x00453 }, - { 0x00435 , 0x00300 , 0x00450 }, - { 0x00435 , 0x00306 , 0x004D7 }, - { 0x00435 , 0x00308 , 0x00451 }, - { 0x00436 , 0x00306 , 0x004C2 }, - { 0x00436 , 0x00308 , 0x004DD }, - { 0x00437 , 0x00308 , 0x004DF }, - { 0x00438 , 0x00300 , 0x0045D }, - { 0x00438 , 0x00304 , 0x004E3 }, - { 0x00438 , 0x00306 , 0x00439 }, - { 0x00438 , 0x00308 , 0x004E5 }, - { 0x0043A , 0x00301 , 0x0045C }, - { 0x0043E , 0x00308 , 0x004E7 }, - { 0x00443 , 0x00304 , 0x004EF }, - { 0x00443 , 0x00306 , 0x0045E }, - { 0x00443 , 0x00308 , 0x004F1 }, - { 0x00443 , 0x0030B , 0x004F3 }, - { 0x00447 , 0x00308 , 0x004F5 }, - { 0x0044B , 0x00308 , 0x004F9 }, - { 0x0044D , 0x00308 , 0x004ED }, - { 0x00456 , 0x00308 , 0x00457 }, - { 0x00474 , 0x0030F , 0x00476 }, - { 0x00475 , 0x0030F , 0x00477 }, - { 0x004D8 , 0x00308 , 0x004DA }, - { 0x004D9 , 0x00308 , 0x004DB }, - { 0x004E8 , 0x00308 , 0x004EA }, - { 0x004E9 , 0x00308 , 0x004EB }, - { 0x00627 , 0x00653 , 0x00622 }, - { 0x00627 , 0x00654 , 0x00623 }, - { 0x00627 , 0x00655 , 0x00625 }, - { 0x00648 , 0x00654 , 0x00624 }, - { 0x0064A , 0x00654 , 0x00626 }, - { 0x006C1 , 0x00654 , 0x006C2 }, - { 0x006D2 , 0x00654 , 0x006D3 }, - { 0x006D5 , 0x00654 , 0x006C0 }, - { 0x00928 , 0x0093C , 0x00929 }, - { 0x00930 , 0x0093C , 0x00931 }, - { 0x00933 , 0x0093C , 0x00934 }, - { 0x009C7 , 0x009BE , 0x009CB }, - { 0x009C7 , 0x009D7 , 0x009CC }, - { 0x00B47 , 0x00B3E , 0x00B4B }, - { 0x00B47 , 0x00B56 , 0x00B48 }, - { 0x00B47 , 0x00B57 , 0x00B4C }, - { 0x00B92 , 0x00BD7 , 0x00B94 }, - { 0x00BC6 , 0x00BBE , 0x00BCA }, - { 0x00BC6 , 0x00BD7 , 0x00BCC }, - { 0x00BC7 , 0x00BBE , 0x00BCB }, - { 0x00C46 , 0x00C56 , 0x00C48 }, - { 0x00CBF , 0x00CD5 , 0x00CC0 }, - { 0x00CC6 , 0x00CC2 , 0x00CCA }, - { 0x00CC6 , 0x00CD5 , 0x00CC7 }, - { 0x00CC6 , 0x00CD6 , 0x00CC8 }, - { 0x00CCA , 0x00CD5 , 0x00CCB }, - { 0x00D46 , 0x00D3E , 0x00D4A }, - { 0x00D46 , 0x00D57 , 0x00D4C }, - { 0x00D47 , 0x00D3E , 0x00D4B }, - { 0x00DD9 , 0x00DCA , 0x00DDA }, - { 0x00DD9 , 0x00DCF , 0x00DDC }, - { 0x00DD9 , 0x00DDF , 0x00DDE }, - { 0x00DDC , 0x00DCA , 0x00DDD }, - { 0x01025 , 0x0102E , 0x01026 }, - { 0x01B05 , 0x01B35 , 0x01B06 }, - { 0x01B07 , 0x01B35 , 0x01B08 }, - { 0x01B09 , 0x01B35 , 0x01B0A }, - { 0x01B0B , 0x01B35 , 0x01B0C }, - { 0x01B0D , 0x01B35 , 0x01B0E }, - { 0x01B11 , 0x01B35 , 0x01B12 }, - { 0x01B3A , 0x01B35 , 0x01B3B }, - { 0x01B3C , 0x01B35 , 0x01B3D }, - { 0x01B3E , 0x01B35 , 0x01B40 }, - { 0x01B3F , 0x01B35 , 0x01B41 }, - { 0x01B42 , 0x01B35 , 0x01B43 }, - { 0x01E36 , 0x00304 , 0x01E38 }, - { 0x01E37 , 0x00304 , 0x01E39 }, - { 0x01E5A , 0x00304 , 0x01E5C }, - { 0x01E5B , 0x00304 , 0x01E5D }, - { 0x01E62 , 0x00307 , 0x01E68 }, - { 0x01E63 , 0x00307 , 0x01E69 }, - { 0x01EA0 , 0x00302 , 0x01EAC }, - { 0x01EA0 , 0x00306 , 0x01EB6 }, - { 0x01EA1 , 0x00302 , 0x01EAD }, - { 0x01EA1 , 0x00306 , 0x01EB7 }, - { 0x01EB8 , 0x00302 , 0x01EC6 }, - { 0x01EB9 , 0x00302 , 0x01EC7 }, - { 0x01ECC , 0x00302 , 0x01ED8 }, - { 0x01ECD , 0x00302 , 0x01ED9 }, - { 0x01F00 , 0x00300 , 0x01F02 }, - { 0x01F00 , 0x00301 , 0x01F04 }, - { 0x01F00 , 0x00342 , 0x01F06 }, - { 0x01F00 , 0x00345 , 0x01F80 }, - { 0x01F01 , 0x00300 , 0x01F03 }, - { 0x01F01 , 0x00301 , 0x01F05 }, - { 0x01F01 , 0x00342 , 0x01F07 }, - { 0x01F01 , 0x00345 , 0x01F81 }, - { 0x01F02 , 0x00345 , 0x01F82 }, - { 0x01F03 , 0x00345 , 0x01F83 }, - { 0x01F04 , 0x00345 , 0x01F84 }, - { 0x01F05 , 0x00345 , 0x01F85 }, - { 0x01F06 , 0x00345 , 0x01F86 }, - { 0x01F07 , 0x00345 , 0x01F87 }, - { 0x01F08 , 0x00300 , 0x01F0A }, - { 0x01F08 , 0x00301 , 0x01F0C }, - { 0x01F08 , 0x00342 , 0x01F0E }, - { 0x01F08 , 0x00345 , 0x01F88 }, - { 0x01F09 , 0x00300 , 0x01F0B }, - { 0x01F09 , 0x00301 , 0x01F0D }, - { 0x01F09 , 0x00342 , 0x01F0F }, - { 0x01F09 , 0x00345 , 0x01F89 }, - { 0x01F0A , 0x00345 , 0x01F8A }, - { 0x01F0B , 0x00345 , 0x01F8B }, - { 0x01F0C , 0x00345 , 0x01F8C }, - { 0x01F0D , 0x00345 , 0x01F8D }, - { 0x01F0E , 0x00345 , 0x01F8E }, - { 0x01F0F , 0x00345 , 0x01F8F }, - { 0x01F10 , 0x00300 , 0x01F12 }, - { 0x01F10 , 0x00301 , 0x01F14 }, - { 0x01F11 , 0x00300 , 0x01F13 }, - { 0x01F11 , 0x00301 , 0x01F15 }, - { 0x01F18 , 0x00300 , 0x01F1A }, - { 0x01F18 , 0x00301 , 0x01F1C }, - { 0x01F19 , 0x00300 , 0x01F1B }, - { 0x01F19 , 0x00301 , 0x01F1D }, - { 0x01F20 , 0x00300 , 0x01F22 }, - { 0x01F20 , 0x00301 , 0x01F24 }, - { 0x01F20 , 0x00342 , 0x01F26 }, - { 0x01F20 , 0x00345 , 0x01F90 }, - { 0x01F21 , 0x00300 , 0x01F23 }, - { 0x01F21 , 0x00301 , 0x01F25 }, - { 0x01F21 , 0x00342 , 0x01F27 }, - { 0x01F21 , 0x00345 , 0x01F91 }, - { 0x01F22 , 0x00345 , 0x01F92 }, - { 0x01F23 , 0x00345 , 0x01F93 }, - { 0x01F24 , 0x00345 , 0x01F94 }, - { 0x01F25 , 0x00345 , 0x01F95 }, - { 0x01F26 , 0x00345 , 0x01F96 }, - { 0x01F27 , 0x00345 , 0x01F97 }, - { 0x01F28 , 0x00300 , 0x01F2A }, - { 0x01F28 , 0x00301 , 0x01F2C }, - { 0x01F28 , 0x00342 , 0x01F2E }, - { 0x01F28 , 0x00345 , 0x01F98 }, - { 0x01F29 , 0x00300 , 0x01F2B }, - { 0x01F29 , 0x00301 , 0x01F2D }, - { 0x01F29 , 0x00342 , 0x01F2F }, - { 0x01F29 , 0x00345 , 0x01F99 }, - { 0x01F2A , 0x00345 , 0x01F9A }, - { 0x01F2B , 0x00345 , 0x01F9B }, - { 0x01F2C , 0x00345 , 0x01F9C }, - { 0x01F2D , 0x00345 , 0x01F9D }, - { 0x01F2E , 0x00345 , 0x01F9E }, - { 0x01F2F , 0x00345 , 0x01F9F }, - { 0x01F30 , 0x00300 , 0x01F32 }, - { 0x01F30 , 0x00301 , 0x01F34 }, - { 0x01F30 , 0x00342 , 0x01F36 }, - { 0x01F31 , 0x00300 , 0x01F33 }, - { 0x01F31 , 0x00301 , 0x01F35 }, - { 0x01F31 , 0x00342 , 0x01F37 }, - { 0x01F38 , 0x00300 , 0x01F3A }, - { 0x01F38 , 0x00301 , 0x01F3C }, - { 0x01F38 , 0x00342 , 0x01F3E }, - { 0x01F39 , 0x00300 , 0x01F3B }, - { 0x01F39 , 0x00301 , 0x01F3D }, - { 0x01F39 , 0x00342 , 0x01F3F }, - { 0x01F40 , 0x00300 , 0x01F42 }, - { 0x01F40 , 0x00301 , 0x01F44 }, - { 0x01F41 , 0x00300 , 0x01F43 }, - { 0x01F41 , 0x00301 , 0x01F45 }, - { 0x01F48 , 0x00300 , 0x01F4A }, - { 0x01F48 , 0x00301 , 0x01F4C }, - { 0x01F49 , 0x00300 , 0x01F4B }, - { 0x01F49 , 0x00301 , 0x01F4D }, - { 0x01F50 , 0x00300 , 0x01F52 }, - { 0x01F50 , 0x00301 , 0x01F54 }, - { 0x01F50 , 0x00342 , 0x01F56 }, - { 0x01F51 , 0x00300 , 0x01F53 }, - { 0x01F51 , 0x00301 , 0x01F55 }, - { 0x01F51 , 0x00342 , 0x01F57 }, - { 0x01F59 , 0x00300 , 0x01F5B }, - { 0x01F59 , 0x00301 , 0x01F5D }, - { 0x01F59 , 0x00342 , 0x01F5F }, - { 0x01F60 , 0x00300 , 0x01F62 }, - { 0x01F60 , 0x00301 , 0x01F64 }, - { 0x01F60 , 0x00342 , 0x01F66 }, - { 0x01F60 , 0x00345 , 0x01FA0 }, - { 0x01F61 , 0x00300 , 0x01F63 }, - { 0x01F61 , 0x00301 , 0x01F65 }, - { 0x01F61 , 0x00342 , 0x01F67 }, - { 0x01F61 , 0x00345 , 0x01FA1 }, - { 0x01F62 , 0x00345 , 0x01FA2 }, - { 0x01F63 , 0x00345 , 0x01FA3 }, - { 0x01F64 , 0x00345 , 0x01FA4 }, - { 0x01F65 , 0x00345 , 0x01FA5 }, - { 0x01F66 , 0x00345 , 0x01FA6 }, - { 0x01F67 , 0x00345 , 0x01FA7 }, - { 0x01F68 , 0x00300 , 0x01F6A }, - { 0x01F68 , 0x00301 , 0x01F6C }, - { 0x01F68 , 0x00342 , 0x01F6E }, - { 0x01F68 , 0x00345 , 0x01FA8 }, - { 0x01F69 , 0x00300 , 0x01F6B }, - { 0x01F69 , 0x00301 , 0x01F6D }, - { 0x01F69 , 0x00342 , 0x01F6F }, - { 0x01F69 , 0x00345 , 0x01FA9 }, - { 0x01F6A , 0x00345 , 0x01FAA }, - { 0x01F6B , 0x00345 , 0x01FAB }, - { 0x01F6C , 0x00345 , 0x01FAC }, - { 0x01F6D , 0x00345 , 0x01FAD }, - { 0x01F6E , 0x00345 , 0x01FAE }, - { 0x01F6F , 0x00345 , 0x01FAF }, - { 0x01F70 , 0x00345 , 0x01FB2 }, - { 0x01F74 , 0x00345 , 0x01FC2 }, - { 0x01F7C , 0x00345 , 0x01FF2 }, - { 0x01FB6 , 0x00345 , 0x01FB7 }, - { 0x01FBF , 0x00300 , 0x01FCD }, - { 0x01FBF , 0x00301 , 0x01FCE }, - { 0x01FBF , 0x00342 , 0x01FCF }, - { 0x01FC6 , 0x00345 , 0x01FC7 }, - { 0x01FF6 , 0x00345 , 0x01FF7 }, - { 0x01FFE , 0x00300 , 0x01FDD }, - { 0x01FFE , 0x00301 , 0x01FDE }, - { 0x01FFE , 0x00342 , 0x01FDF }, - { 0x02190 , 0x00338 , 0x0219A }, - { 0x02192 , 0x00338 , 0x0219B }, - { 0x02194 , 0x00338 , 0x021AE }, - { 0x021D0 , 0x00338 , 0x021CD }, - { 0x021D2 , 0x00338 , 0x021CF }, - { 0x021D4 , 0x00338 , 0x021CE }, - { 0x02203 , 0x00338 , 0x02204 }, - { 0x02208 , 0x00338 , 0x02209 }, - { 0x0220B , 0x00338 , 0x0220C }, - { 0x02223 , 0x00338 , 0x02224 }, - { 0x02225 , 0x00338 , 0x02226 }, - { 0x0223C , 0x00338 , 0x02241 }, - { 0x02243 , 0x00338 , 0x02244 }, - { 0x02245 , 0x00338 , 0x02247 }, - { 0x02248 , 0x00338 , 0x02249 }, - { 0x0224D , 0x00338 , 0x0226D }, - { 0x02261 , 0x00338 , 0x02262 }, - { 0x02264 , 0x00338 , 0x02270 }, - { 0x02265 , 0x00338 , 0x02271 }, - { 0x02272 , 0x00338 , 0x02274 }, - { 0x02273 , 0x00338 , 0x02275 }, - { 0x02276 , 0x00338 , 0x02278 }, - { 0x02277 , 0x00338 , 0x02279 }, - { 0x0227A , 0x00338 , 0x02280 }, - { 0x0227B , 0x00338 , 0x02281 }, - { 0x0227C , 0x00338 , 0x022E0 }, - { 0x0227D , 0x00338 , 0x022E1 }, - { 0x02282 , 0x00338 , 0x02284 }, - { 0x02283 , 0x00338 , 0x02285 }, - { 0x02286 , 0x00338 , 0x02288 }, - { 0x02287 , 0x00338 , 0x02289 }, - { 0x02291 , 0x00338 , 0x022E2 }, - { 0x02292 , 0x00338 , 0x022E3 }, - { 0x022A2 , 0x00338 , 0x022AC }, - { 0x022A8 , 0x00338 , 0x022AD }, - { 0x022A9 , 0x00338 , 0x022AE }, - { 0x022AB , 0x00338 , 0x022AF }, - { 0x022B2 , 0x00338 , 0x022EA }, - { 0x022B3 , 0x00338 , 0x022EB }, - { 0x022B4 , 0x00338 , 0x022EC }, - { 0x022B5 , 0x00338 , 0x022ED }, - { 0x03046 , 0x03099 , 0x03094 }, - { 0x0304B , 0x03099 , 0x0304C }, - { 0x0304D , 0x03099 , 0x0304E }, - { 0x0304F , 0x03099 , 0x03050 }, - { 0x03051 , 0x03099 , 0x03052 }, - { 0x03053 , 0x03099 , 0x03054 }, - { 0x03055 , 0x03099 , 0x03056 }, - { 0x03057 , 0x03099 , 0x03058 }, - { 0x03059 , 0x03099 , 0x0305A }, - { 0x0305B , 0x03099 , 0x0305C }, - { 0x0305D , 0x03099 , 0x0305E }, - { 0x0305F , 0x03099 , 0x03060 }, - { 0x03061 , 0x03099 , 0x03062 }, - { 0x03064 , 0x03099 , 0x03065 }, - { 0x03066 , 0x03099 , 0x03067 }, - { 0x03068 , 0x03099 , 0x03069 }, - { 0x0306F , 0x03099 , 0x03070 }, - { 0x0306F , 0x0309A , 0x03071 }, - { 0x03072 , 0x03099 , 0x03073 }, - { 0x03072 , 0x0309A , 0x03074 }, - { 0x03075 , 0x03099 , 0x03076 }, - { 0x03075 , 0x0309A , 0x03077 }, - { 0x03078 , 0x03099 , 0x03079 }, - { 0x03078 , 0x0309A , 0x0307A }, - { 0x0307B , 0x03099 , 0x0307C }, - { 0x0307B , 0x0309A , 0x0307D }, - { 0x0309D , 0x03099 , 0x0309E }, - { 0x030A6 , 0x03099 , 0x030F4 }, - { 0x030AB , 0x03099 , 0x030AC }, - { 0x030AD , 0x03099 , 0x030AE }, - { 0x030AF , 0x03099 , 0x030B0 }, - { 0x030B1 , 0x03099 , 0x030B2 }, - { 0x030B3 , 0x03099 , 0x030B4 }, - { 0x030B5 , 0x03099 , 0x030B6 }, - { 0x030B7 , 0x03099 , 0x030B8 }, - { 0x030B9 , 0x03099 , 0x030BA }, - { 0x030BB , 0x03099 , 0x030BC }, - { 0x030BD , 0x03099 , 0x030BE }, - { 0x030BF , 0x03099 , 0x030C0 }, - { 0x030C1 , 0x03099 , 0x030C2 }, - { 0x030C4 , 0x03099 , 0x030C5 }, - { 0x030C6 , 0x03099 , 0x030C7 }, - { 0x030C8 , 0x03099 , 0x030C9 }, - { 0x030CF , 0x03099 , 0x030D0 }, - { 0x030CF , 0x0309A , 0x030D1 }, - { 0x030D2 , 0x03099 , 0x030D3 }, - { 0x030D2 , 0x0309A , 0x030D4 }, - { 0x030D5 , 0x03099 , 0x030D6 }, - { 0x030D5 , 0x0309A , 0x030D7 }, - { 0x030D8 , 0x03099 , 0x030D9 }, - { 0x030D8 , 0x0309A , 0x030DA }, - { 0x030DB , 0x03099 , 0x030DC }, - { 0x030DB , 0x0309A , 0x030DD }, - { 0x030EF , 0x03099 , 0x030F7 }, - { 0x030F0 , 0x03099 , 0x030F8 }, - { 0x030F1 , 0x03099 , 0x030F9 }, - { 0x030F2 , 0x03099 , 0x030FA }, - { 0x030FD , 0x03099 , 0x030FE }, - { 0x11099 , 0x110BA , 0x1109A }, - { 0x1109B , 0x110BA , 0x1109C }, - { 0x110A5 , 0x110BA , 0x110AB }, -}; - -#define CANONICAL_CLASS_MIN 0x0300 -#define CANONICAL_CLASS_MAX 0x1D244 - -#define IS_DECOMPOSABLE_BLOCK(uc) \ - (((uc)>>8) <= 0x1D2 && u_decomposable_blocks[(uc)>>8]) -static const char u_decomposable_blocks[0x1D2+1] = { - 0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,1,1,1,1,1,1,1,0,0, - 1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,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,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,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,1,0,0,1,0, - 0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,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,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,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,0,0,0,1,1, -}; - -/* Get Canonical Combining Class(CCC). */ -#define CCC(uc) \ - (((uc) > 0x1D244)?0:\ - ccc_val[ccc_val_index[ccc_index[(uc)>>8]][((uc)>>4)&0x0F]][(uc)&0x0F]) - -/* The table of the value of Canonical Combining Class */ -static const unsigned char ccc_val[][16] = { - /* idx=0: XXXX0 - XXXXF */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=1: 00300 - 0030F */ - {230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230 }, - /* idx=2: 00310 - 0031F */ - {230, 230, 230, 230, 230, 232, 220, 220, 220, 220, 232, 216, 220, 220, 220, 220 }, - /* idx=3: 00320 - 0032F */ - {220, 202, 202, 220, 220, 220, 220, 202, 202, 220, 220, 220, 220, 220, 220, 220 }, - /* idx=4: 00330 - 0033F */ - {220, 220, 220, 220, 1, 1, 1, 1, 1, 220, 220, 220, 220, 230, 230, 230 }, - /* idx=5: 00340 - 0034F */ - {230, 230, 230, 230, 230, 240, 230, 220, 220, 220, 230, 230, 230, 220, 220, 0 }, - /* idx=6: 00350 - 0035F */ - {230, 230, 230, 220, 220, 220, 220, 230, 232, 220, 220, 230, 233, 234, 234, 233 }, - /* idx=7: 00360 - 0036F */ - {234, 234, 233, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230 }, - /* idx=8: 00480 - 0048F */ - {0, 0, 0, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=9: 00590 - 0059F */ - {0, 220, 230, 230, 230, 230, 220, 230, 230, 230, 222, 220, 230, 230, 230, 230 }, - /* idx=10: 005A0 - 005AF */ - {230, 230, 220, 220, 220, 220, 220, 220, 230, 230, 220, 230, 230, 222, 228, 230 }, - /* idx=11: 005B0 - 005BF */ - {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23 }, - /* idx=12: 005C0 - 005CF */ - {0, 24, 25, 0, 230, 220, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=13: 00610 - 0061F */ - {230, 230, 230, 230, 230, 230, 230, 230, 30, 31, 32, 0, 0, 0, 0, 0 }, - /* idx=14: 00640 - 0064F */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 28, 29, 30, 31 }, - /* idx=15: 00650 - 0065F */ - {32, 33, 34, 230, 230, 220, 220, 230, 230, 230, 230, 230, 220, 230, 230, 220 }, - /* idx=16: 00670 - 0067F */ - {35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=17: 006D0 - 006DF */ - {0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 230, 0, 0, 230 }, - /* idx=18: 006E0 - 006EF */ - {230, 230, 230, 220, 230, 0, 0, 230, 230, 0, 220, 230, 230, 220, 0, 0 }, - /* idx=19: 00710 - 0071F */ - {0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=20: 00730 - 0073F */ - {230, 220, 230, 230, 220, 230, 230, 220, 220, 220, 230, 220, 220, 230, 220, 230 }, - /* idx=21: 00740 - 0074F */ - {230, 230, 220, 230, 220, 230, 220, 230, 220, 230, 230, 0, 0, 0, 0, 0 }, - /* idx=22: 007E0 - 007EF */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230 }, - /* idx=23: 007F0 - 007FF */ - {230, 230, 220, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=24: 00810 - 0081F */ - {0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 0, 230, 230, 230, 230, 230 }, - /* idx=25: 00820 - 0082F */ - {230, 230, 230, 230, 0, 230, 230, 230, 0, 230, 230, 230, 230, 230, 0, 0 }, - /* idx=26: 00850 - 0085F */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220, 0, 0, 0, 0 }, - /* idx=27: 00930 - 0093F */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0 }, - /* idx=28: 00940 - 0094F */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 }, - /* idx=29: 00950 - 0095F */ - {0, 230, 220, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=30: 009B0 - 009BF */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0 }, - /* idx=31: 009C0 - 009CF */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 }, - /* idx=32: 00A30 - 00A3F */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0 }, - /* idx=33: 00A40 - 00A4F */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 }, - /* idx=34: 00AB0 - 00ABF */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0 }, - /* idx=35: 00AC0 - 00ACF */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 }, - /* idx=36: 00B30 - 00B3F */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0 }, - /* idx=37: 00B40 - 00B4F */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 }, - /* idx=38: 00BC0 - 00BCF */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 }, - /* idx=39: 00C40 - 00C4F */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 }, - /* idx=40: 00C50 - 00C5F */ - {0, 0, 0, 0, 0, 84, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=41: 00CB0 - 00CBF */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0 }, - /* idx=42: 00CC0 - 00CCF */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 }, - /* idx=43: 00D40 - 00D4F */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 }, - /* idx=44: 00DC0 - 00DCF */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0 }, - /* idx=45: 00E30 - 00E3F */ - {0, 0, 0, 0, 0, 0, 0, 0, 103, 103, 9, 0, 0, 0, 0, 0 }, - /* idx=46: 00E40 - 00E4F */ - {0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 0, 0, 0, 0 }, - /* idx=47: 00EB0 - 00EBF */ - {0, 0, 0, 0, 0, 0, 0, 0, 118, 118, 0, 0, 0, 0, 0, 0 }, - /* idx=48: 00EC0 - 00ECF */ - {0, 0, 0, 0, 0, 0, 0, 0, 122, 122, 122, 122, 0, 0, 0, 0 }, - /* idx=49: 00F10 - 00F1F */ - {0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 0, 0, 0, 0, 0, 0 }, - /* idx=50: 00F30 - 00F3F */ - {0, 0, 0, 0, 0, 220, 0, 220, 0, 216, 0, 0, 0, 0, 0, 0 }, - /* idx=51: 00F70 - 00F7F */ - {0, 129, 130, 0, 132, 0, 0, 0, 0, 0, 130, 130, 130, 130, 0, 0 }, - /* idx=52: 00F80 - 00F8F */ - {130, 0, 230, 230, 9, 0, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=53: 00FC0 - 00FCF */ - {0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=54: 01030 - 0103F */ - {0, 0, 0, 0, 0, 0, 0, 7, 0, 9, 9, 0, 0, 0, 0, 0 }, - /* idx=55: 01080 - 0108F */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0 }, - /* idx=56: 01350 - 0135F */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230 }, - /* idx=57: 01710 - 0171F */ - {0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=58: 01730 - 0173F */ - {0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=59: 017D0 - 017DF */ - {0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 0, 0 }, - /* idx=60: 018A0 - 018AF */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0 }, - /* idx=61: 01930 - 0193F */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 222, 230, 220, 0, 0, 0, 0 }, - /* idx=62: 01A10 - 01A1F */ - {0, 0, 0, 0, 0, 0, 0, 230, 220, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=63: 01A60 - 01A6F */ - {9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=64: 01A70 - 01A7F */ - {0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 230, 230, 0, 0, 220 }, - /* idx=65: 01B30 - 01B3F */ - {0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=66: 01B40 - 01B4F */ - {0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=67: 01B60 - 01B6F */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 220, 230, 230, 230 }, - /* idx=68: 01B70 - 01B7F */ - {230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=69: 01BA0 - 01BAF */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0 }, - /* idx=70: 01BE0 - 01BEF */ - {0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=71: 01BF0 - 01BFF */ - {0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=72: 01C30 - 01C3F */ - {0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=73: 01CD0 - 01CDF */ - {230, 230, 230, 0, 1, 220, 220, 220, 220, 220, 230, 230, 220, 220, 220, 220 }, - /* idx=74: 01CE0 - 01CEF */ - {230, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 220, 0, 0 }, - /* idx=75: 01DC0 - 01DCF */ - {230, 230, 220, 230, 230, 230, 230, 230, 230, 230, 220, 230, 230, 234, 214, 220 }, - /* idx=76: 01DD0 - 01DDF */ - {202, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230 }, - /* idx=77: 01DE0 - 01DEF */ - {230, 230, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=78: 01DF0 - 01DFF */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 233, 220, 230, 220 }, - /* idx=79: 020D0 - 020DF */ - {230, 230, 1, 1, 230, 230, 230, 230, 1, 1, 1, 230, 230, 0, 0, 0 }, - /* idx=80: 020E0 - 020EF */ - {0, 230, 0, 0, 0, 1, 1, 230, 220, 230, 1, 1, 220, 220, 220, 220 }, - /* idx=81: 020F0 - 020FF */ - {230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=82: 02CE0 - 02CEF */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230 }, - /* idx=83: 02CF0 - 02CFF */ - {230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=84: 02D70 - 02D7F */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9 }, - /* idx=85: 02DE0 - 02DEF */ - {230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230 }, - /* idx=86: 02DF0 - 02DFF */ - {230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230 }, - /* idx=87: 03020 - 0302F */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 218, 228, 232, 222, 224, 224 }, - /* idx=88: 03090 - 0309F */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0 }, - /* idx=89: 0A660 - 0A66F */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230 }, - /* idx=90: 0A670 - 0A67F */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 0, 0 }, - /* idx=91: 0A6F0 - 0A6FF */ - {230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=92: 0A800 - 0A80F */ - {0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=93: 0A8C0 - 0A8CF */ - {0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=94: 0A8E0 - 0A8EF */ - {230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230 }, - /* idx=95: 0A8F0 - 0A8FF */ - {230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=96: 0A920 - 0A92F */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220, 0, 0 }, - /* idx=97: 0A950 - 0A95F */ - {0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=98: 0A9B0 - 0A9BF */ - {0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=99: 0A9C0 - 0A9CF */ - {9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=100: 0AAB0 - 0AABF */ - {230, 0, 230, 230, 220, 0, 0, 230, 230, 0, 0, 0, 0, 0, 230, 230 }, - /* idx=101: 0AAC0 - 0AACF */ - {0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=102: 0ABE0 - 0ABEF */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0 }, - /* idx=103: 0FB10 - 0FB1F */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0 }, - /* idx=104: 0FE20 - 0FE2F */ - {230, 230, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=105: 101F0 - 101FF */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0 }, - /* idx=106: 10A00 - 10A0F */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 230 }, - /* idx=107: 10A30 - 10A3F */ - {0, 0, 0, 0, 0, 0, 0, 0, 230, 1, 220, 0, 0, 0, 0, 9 }, - /* idx=108: 11040 - 1104F */ - {0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=109: 110B0 - 110BF */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 7, 0, 0, 0, 0, 0 }, - /* idx=110: 1D160 - 1D16F */ - {0, 0, 0, 0, 0, 216, 216, 1, 1, 1, 0, 0, 0, 226, 216, 216 }, - /* idx=111: 1D170 - 1D17F */ - {216, 216, 216, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220, 220, 220 }, - /* idx=112: 1D180 - 1D18F */ - {220, 220, 220, 0, 0, 230, 230, 230, 230, 230, 220, 220, 0, 0, 0, 0 }, - /* idx=113: 1D1A0 - 1D1AF */ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 0, 0 }, - /* idx=114: 1D240 - 1D24F */ - {0, 0, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, -}; - -/* The index table to ccc_val[*][16] */ -static const unsigned char ccc_val_index[][16] = { - /* idx=0: XXX00 - XXXFF */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=1: 00300 - 003FF */ - { 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=2: 00400 - 004FF */ - { 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=3: 00500 - 005FF */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,10,11,12, 0, 0, 0 }, - /* idx=4: 00600 - 006FF */ - { 0,13, 0, 0,14,15, 0,16, 0, 0, 0, 0, 0,17,18, 0 }, - /* idx=5: 00700 - 007FF */ - { 0,19, 0,20,21, 0, 0, 0, 0, 0, 0, 0, 0, 0,22,23 }, - /* idx=6: 00800 - 008FF */ - { 0,24,25, 0, 0,26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=7: 00900 - 009FF */ - { 0, 0, 0,27,28,29, 0, 0, 0, 0, 0,30,31, 0, 0, 0 }, - /* idx=8: 00A00 - 00AFF */ - { 0, 0, 0,32,33, 0, 0, 0, 0, 0, 0,34,35, 0, 0, 0 }, - /* idx=9: 00B00 - 00BFF */ - { 0, 0, 0,36,37, 0, 0, 0, 0, 0, 0, 0,38, 0, 0, 0 }, - /* idx=10: 00C00 - 00CFF */ - { 0, 0, 0, 0,39,40, 0, 0, 0, 0, 0,41,42, 0, 0, 0 }, - /* idx=11: 00D00 - 00DFF */ - { 0, 0, 0, 0,43, 0, 0, 0, 0, 0, 0, 0,44, 0, 0, 0 }, - /* idx=12: 00E00 - 00EFF */ - { 0, 0, 0,45,46, 0, 0, 0, 0, 0, 0,47,48, 0, 0, 0 }, - /* idx=13: 00F00 - 00FFF */ - { 0,49, 0,50, 0, 0, 0,51,52, 0, 0, 0,53, 0, 0, 0 }, - /* idx=14: 01000 - 010FF */ - { 0, 0, 0,54, 0, 0, 0, 0,55, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=15: 01300 - 013FF */ - { 0, 0, 0, 0, 0,56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=16: 01700 - 017FF */ - { 0,57, 0,58, 0, 0, 0, 0, 0, 0, 0, 0, 0,59, 0, 0 }, - /* idx=17: 01800 - 018FF */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,60, 0, 0, 0, 0, 0 }, - /* idx=18: 01900 - 019FF */ - { 0, 0, 0,61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=19: 01A00 - 01AFF */ - { 0,62, 0, 0, 0, 0,63,64, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=20: 01B00 - 01BFF */ - { 0, 0, 0,65,66, 0,67,68, 0, 0,69, 0, 0, 0,70,71 }, - /* idx=21: 01C00 - 01CFF */ - { 0, 0, 0,72, 0, 0, 0, 0, 0, 0, 0, 0, 0,73,74, 0 }, - /* idx=22: 01D00 - 01DFF */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,75,76,77,78 }, - /* idx=23: 02000 - 020FF */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,79,80,81 }, - /* idx=24: 02C00 - 02CFF */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,82,83 }, - /* idx=25: 02D00 - 02DFF */ - { 0, 0, 0, 0, 0, 0, 0,84, 0, 0, 0, 0, 0, 0,85,86 }, - /* idx=26: 03000 - 030FF */ - { 0, 0,87, 0, 0, 0, 0, 0, 0,88, 0, 0, 0, 0, 0, 0 }, - /* idx=27: 0A600 - 0A6FF */ - { 0, 0, 0, 0, 0, 0,89,90, 0, 0, 0, 0, 0, 0, 0,91 }, - /* idx=28: 0A800 - 0A8FF */ - {92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,93, 0,94,95 }, - /* idx=29: 0A900 - 0A9FF */ - { 0, 0,96, 0, 0,97, 0, 0, 0, 0, 0,98,99, 0, 0, 0 }, - /* idx=30: 0AA00 - 0AAFF */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100,101, 0, 0, 0 }, - /* idx=31: 0AB00 - 0ABFF */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,102, 0 }, - /* idx=32: 0FB00 - 0FBFF */ - { 0,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=33: 0FE00 - 0FEFF */ - { 0, 0,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=34: 10100 - 101FF */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105 }, - /* idx=35: 10A00 - 10AFF */ - {106, 0, 0,107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - /* idx=36: 11000 - 110FF */ - { 0, 0, 0, 0,108, 0, 0, 0, 0, 0, 0,109, 0, 0, 0, 0 }, - /* idx=37: 1D100 - 1D1FF */ - { 0, 0, 0, 0, 0, 0,110,111,112, 0,113, 0, 0, 0, 0, 0 }, - /* idx=38: 1D200 - 1D2FF */ - { 0, 0, 0, 0,114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, -}; - -/* The index table to ccc_val_index[*][16] */ -static const unsigned char ccc_index[] = { - 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, 0, 0,15, 0, 0, 0,16, - 17,18,19,20,21,22, 0, 0,23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,24,25, 0, 0, - 26, 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, 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,27, 0, - 28,29,30,31, 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, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,32, 0, 0,33, 0, 0,34, 0, 0, 0, 0, 0, 0, - 0, 0,35, 0, 0, 0, 0, 0,36, 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, - 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, 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, 0, 0, 0,37,38,}; - -struct unicode_decomposition_table { - uint32_t nfc; - uint32_t cp1; - uint32_t cp2; -}; - -static const struct unicode_decomposition_table u_decomposition_table[] = { - { 0x000C0 , 0x00041 , 0x00300 }, - { 0x000C1 , 0x00041 , 0x00301 }, - { 0x000C2 , 0x00041 , 0x00302 }, - { 0x000C3 , 0x00041 , 0x00303 }, - { 0x000C4 , 0x00041 , 0x00308 }, - { 0x000C5 , 0x00041 , 0x0030A }, - { 0x000C7 , 0x00043 , 0x00327 }, - { 0x000C8 , 0x00045 , 0x00300 }, - { 0x000C9 , 0x00045 , 0x00301 }, - { 0x000CA , 0x00045 , 0x00302 }, - { 0x000CB , 0x00045 , 0x00308 }, - { 0x000CC , 0x00049 , 0x00300 }, - { 0x000CD , 0x00049 , 0x00301 }, - { 0x000CE , 0x00049 , 0x00302 }, - { 0x000CF , 0x00049 , 0x00308 }, - { 0x000D1 , 0x0004E , 0x00303 }, - { 0x000D2 , 0x0004F , 0x00300 }, - { 0x000D3 , 0x0004F , 0x00301 }, - { 0x000D4 , 0x0004F , 0x00302 }, - { 0x000D5 , 0x0004F , 0x00303 }, - { 0x000D6 , 0x0004F , 0x00308 }, - { 0x000D9 , 0x00055 , 0x00300 }, - { 0x000DA , 0x00055 , 0x00301 }, - { 0x000DB , 0x00055 , 0x00302 }, - { 0x000DC , 0x00055 , 0x00308 }, - { 0x000DD , 0x00059 , 0x00301 }, - { 0x000E0 , 0x00061 , 0x00300 }, - { 0x000E1 , 0x00061 , 0x00301 }, - { 0x000E2 , 0x00061 , 0x00302 }, - { 0x000E3 , 0x00061 , 0x00303 }, - { 0x000E4 , 0x00061 , 0x00308 }, - { 0x000E5 , 0x00061 , 0x0030A }, - { 0x000E7 , 0x00063 , 0x00327 }, - { 0x000E8 , 0x00065 , 0x00300 }, - { 0x000E9 , 0x00065 , 0x00301 }, - { 0x000EA , 0x00065 , 0x00302 }, - { 0x000EB , 0x00065 , 0x00308 }, - { 0x000EC , 0x00069 , 0x00300 }, - { 0x000ED , 0x00069 , 0x00301 }, - { 0x000EE , 0x00069 , 0x00302 }, - { 0x000EF , 0x00069 , 0x00308 }, - { 0x000F1 , 0x0006E , 0x00303 }, - { 0x000F2 , 0x0006F , 0x00300 }, - { 0x000F3 , 0x0006F , 0x00301 }, - { 0x000F4 , 0x0006F , 0x00302 }, - { 0x000F5 , 0x0006F , 0x00303 }, - { 0x000F6 , 0x0006F , 0x00308 }, - { 0x000F9 , 0x00075 , 0x00300 }, - { 0x000FA , 0x00075 , 0x00301 }, - { 0x000FB , 0x00075 , 0x00302 }, - { 0x000FC , 0x00075 , 0x00308 }, - { 0x000FD , 0x00079 , 0x00301 }, - { 0x000FF , 0x00079 , 0x00308 }, - { 0x00100 , 0x00041 , 0x00304 }, - { 0x00101 , 0x00061 , 0x00304 }, - { 0x00102 , 0x00041 , 0x00306 }, - { 0x00103 , 0x00061 , 0x00306 }, - { 0x00104 , 0x00041 , 0x00328 }, - { 0x00105 , 0x00061 , 0x00328 }, - { 0x00106 , 0x00043 , 0x00301 }, - { 0x00107 , 0x00063 , 0x00301 }, - { 0x00108 , 0x00043 , 0x00302 }, - { 0x00109 , 0x00063 , 0x00302 }, - { 0x0010A , 0x00043 , 0x00307 }, - { 0x0010B , 0x00063 , 0x00307 }, - { 0x0010C , 0x00043 , 0x0030C }, - { 0x0010D , 0x00063 , 0x0030C }, - { 0x0010E , 0x00044 , 0x0030C }, - { 0x0010F , 0x00064 , 0x0030C }, - { 0x00112 , 0x00045 , 0x00304 }, - { 0x00113 , 0x00065 , 0x00304 }, - { 0x00114 , 0x00045 , 0x00306 }, - { 0x00115 , 0x00065 , 0x00306 }, - { 0x00116 , 0x00045 , 0x00307 }, - { 0x00117 , 0x00065 , 0x00307 }, - { 0x00118 , 0x00045 , 0x00328 }, - { 0x00119 , 0x00065 , 0x00328 }, - { 0x0011A , 0x00045 , 0x0030C }, - { 0x0011B , 0x00065 , 0x0030C }, - { 0x0011C , 0x00047 , 0x00302 }, - { 0x0011D , 0x00067 , 0x00302 }, - { 0x0011E , 0x00047 , 0x00306 }, - { 0x0011F , 0x00067 , 0x00306 }, - { 0x00120 , 0x00047 , 0x00307 }, - { 0x00121 , 0x00067 , 0x00307 }, - { 0x00122 , 0x00047 , 0x00327 }, - { 0x00123 , 0x00067 , 0x00327 }, - { 0x00124 , 0x00048 , 0x00302 }, - { 0x00125 , 0x00068 , 0x00302 }, - { 0x00128 , 0x00049 , 0x00303 }, - { 0x00129 , 0x00069 , 0x00303 }, - { 0x0012A , 0x00049 , 0x00304 }, - { 0x0012B , 0x00069 , 0x00304 }, - { 0x0012C , 0x00049 , 0x00306 }, - { 0x0012D , 0x00069 , 0x00306 }, - { 0x0012E , 0x00049 , 0x00328 }, - { 0x0012F , 0x00069 , 0x00328 }, - { 0x00130 , 0x00049 , 0x00307 }, - { 0x00134 , 0x0004A , 0x00302 }, - { 0x00135 , 0x0006A , 0x00302 }, - { 0x00136 , 0x0004B , 0x00327 }, - { 0x00137 , 0x0006B , 0x00327 }, - { 0x00139 , 0x0004C , 0x00301 }, - { 0x0013A , 0x0006C , 0x00301 }, - { 0x0013B , 0x0004C , 0x00327 }, - { 0x0013C , 0x0006C , 0x00327 }, - { 0x0013D , 0x0004C , 0x0030C }, - { 0x0013E , 0x0006C , 0x0030C }, - { 0x00143 , 0x0004E , 0x00301 }, - { 0x00144 , 0x0006E , 0x00301 }, - { 0x00145 , 0x0004E , 0x00327 }, - { 0x00146 , 0x0006E , 0x00327 }, - { 0x00147 , 0x0004E , 0x0030C }, - { 0x00148 , 0x0006E , 0x0030C }, - { 0x0014C , 0x0004F , 0x00304 }, - { 0x0014D , 0x0006F , 0x00304 }, - { 0x0014E , 0x0004F , 0x00306 }, - { 0x0014F , 0x0006F , 0x00306 }, - { 0x00150 , 0x0004F , 0x0030B }, - { 0x00151 , 0x0006F , 0x0030B }, - { 0x00154 , 0x00052 , 0x00301 }, - { 0x00155 , 0x00072 , 0x00301 }, - { 0x00156 , 0x00052 , 0x00327 }, - { 0x00157 , 0x00072 , 0x00327 }, - { 0x00158 , 0x00052 , 0x0030C }, - { 0x00159 , 0x00072 , 0x0030C }, - { 0x0015A , 0x00053 , 0x00301 }, - { 0x0015B , 0x00073 , 0x00301 }, - { 0x0015C , 0x00053 , 0x00302 }, - { 0x0015D , 0x00073 , 0x00302 }, - { 0x0015E , 0x00053 , 0x00327 }, - { 0x0015F , 0x00073 , 0x00327 }, - { 0x00160 , 0x00053 , 0x0030C }, - { 0x00161 , 0x00073 , 0x0030C }, - { 0x00162 , 0x00054 , 0x00327 }, - { 0x00163 , 0x00074 , 0x00327 }, - { 0x00164 , 0x00054 , 0x0030C }, - { 0x00165 , 0x00074 , 0x0030C }, - { 0x00168 , 0x00055 , 0x00303 }, - { 0x00169 , 0x00075 , 0x00303 }, - { 0x0016A , 0x00055 , 0x00304 }, - { 0x0016B , 0x00075 , 0x00304 }, - { 0x0016C , 0x00055 , 0x00306 }, - { 0x0016D , 0x00075 , 0x00306 }, - { 0x0016E , 0x00055 , 0x0030A }, - { 0x0016F , 0x00075 , 0x0030A }, - { 0x00170 , 0x00055 , 0x0030B }, - { 0x00171 , 0x00075 , 0x0030B }, - { 0x00172 , 0x00055 , 0x00328 }, - { 0x00173 , 0x00075 , 0x00328 }, - { 0x00174 , 0x00057 , 0x00302 }, - { 0x00175 , 0x00077 , 0x00302 }, - { 0x00176 , 0x00059 , 0x00302 }, - { 0x00177 , 0x00079 , 0x00302 }, - { 0x00178 , 0x00059 , 0x00308 }, - { 0x00179 , 0x0005A , 0x00301 }, - { 0x0017A , 0x0007A , 0x00301 }, - { 0x0017B , 0x0005A , 0x00307 }, - { 0x0017C , 0x0007A , 0x00307 }, - { 0x0017D , 0x0005A , 0x0030C }, - { 0x0017E , 0x0007A , 0x0030C }, - { 0x001A0 , 0x0004F , 0x0031B }, - { 0x001A1 , 0x0006F , 0x0031B }, - { 0x001AF , 0x00055 , 0x0031B }, - { 0x001B0 , 0x00075 , 0x0031B }, - { 0x001CD , 0x00041 , 0x0030C }, - { 0x001CE , 0x00061 , 0x0030C }, - { 0x001CF , 0x00049 , 0x0030C }, - { 0x001D0 , 0x00069 , 0x0030C }, - { 0x001D1 , 0x0004F , 0x0030C }, - { 0x001D2 , 0x0006F , 0x0030C }, - { 0x001D3 , 0x00055 , 0x0030C }, - { 0x001D4 , 0x00075 , 0x0030C }, - { 0x001D5 , 0x000DC , 0x00304 }, - { 0x001D6 , 0x000FC , 0x00304 }, - { 0x001D7 , 0x000DC , 0x00301 }, - { 0x001D8 , 0x000FC , 0x00301 }, - { 0x001D9 , 0x000DC , 0x0030C }, - { 0x001DA , 0x000FC , 0x0030C }, - { 0x001DB , 0x000DC , 0x00300 }, - { 0x001DC , 0x000FC , 0x00300 }, - { 0x001DE , 0x000C4 , 0x00304 }, - { 0x001DF , 0x000E4 , 0x00304 }, - { 0x001E0 , 0x00226 , 0x00304 }, - { 0x001E1 , 0x00227 , 0x00304 }, - { 0x001E2 , 0x000C6 , 0x00304 }, - { 0x001E3 , 0x000E6 , 0x00304 }, - { 0x001E6 , 0x00047 , 0x0030C }, - { 0x001E7 , 0x00067 , 0x0030C }, - { 0x001E8 , 0x0004B , 0x0030C }, - { 0x001E9 , 0x0006B , 0x0030C }, - { 0x001EA , 0x0004F , 0x00328 }, - { 0x001EB , 0x0006F , 0x00328 }, - { 0x001EC , 0x001EA , 0x00304 }, - { 0x001ED , 0x001EB , 0x00304 }, - { 0x001EE , 0x001B7 , 0x0030C }, - { 0x001EF , 0x00292 , 0x0030C }, - { 0x001F0 , 0x0006A , 0x0030C }, - { 0x001F4 , 0x00047 , 0x00301 }, - { 0x001F5 , 0x00067 , 0x00301 }, - { 0x001F8 , 0x0004E , 0x00300 }, - { 0x001F9 , 0x0006E , 0x00300 }, - { 0x001FA , 0x000C5 , 0x00301 }, - { 0x001FB , 0x000E5 , 0x00301 }, - { 0x001FC , 0x000C6 , 0x00301 }, - { 0x001FD , 0x000E6 , 0x00301 }, - { 0x001FE , 0x000D8 , 0x00301 }, - { 0x001FF , 0x000F8 , 0x00301 }, - { 0x00200 , 0x00041 , 0x0030F }, - { 0x00201 , 0x00061 , 0x0030F }, - { 0x00202 , 0x00041 , 0x00311 }, - { 0x00203 , 0x00061 , 0x00311 }, - { 0x00204 , 0x00045 , 0x0030F }, - { 0x00205 , 0x00065 , 0x0030F }, - { 0x00206 , 0x00045 , 0x00311 }, - { 0x00207 , 0x00065 , 0x00311 }, - { 0x00208 , 0x00049 , 0x0030F }, - { 0x00209 , 0x00069 , 0x0030F }, - { 0x0020A , 0x00049 , 0x00311 }, - { 0x0020B , 0x00069 , 0x00311 }, - { 0x0020C , 0x0004F , 0x0030F }, - { 0x0020D , 0x0006F , 0x0030F }, - { 0x0020E , 0x0004F , 0x00311 }, - { 0x0020F , 0x0006F , 0x00311 }, - { 0x00210 , 0x00052 , 0x0030F }, - { 0x00211 , 0x00072 , 0x0030F }, - { 0x00212 , 0x00052 , 0x00311 }, - { 0x00213 , 0x00072 , 0x00311 }, - { 0x00214 , 0x00055 , 0x0030F }, - { 0x00215 , 0x00075 , 0x0030F }, - { 0x00216 , 0x00055 , 0x00311 }, - { 0x00217 , 0x00075 , 0x00311 }, - { 0x00218 , 0x00053 , 0x00326 }, - { 0x00219 , 0x00073 , 0x00326 }, - { 0x0021A , 0x00054 , 0x00326 }, - { 0x0021B , 0x00074 , 0x00326 }, - { 0x0021E , 0x00048 , 0x0030C }, - { 0x0021F , 0x00068 , 0x0030C }, - { 0x00226 , 0x00041 , 0x00307 }, - { 0x00227 , 0x00061 , 0x00307 }, - { 0x00228 , 0x00045 , 0x00327 }, - { 0x00229 , 0x00065 , 0x00327 }, - { 0x0022A , 0x000D6 , 0x00304 }, - { 0x0022B , 0x000F6 , 0x00304 }, - { 0x0022C , 0x000D5 , 0x00304 }, - { 0x0022D , 0x000F5 , 0x00304 }, - { 0x0022E , 0x0004F , 0x00307 }, - { 0x0022F , 0x0006F , 0x00307 }, - { 0x00230 , 0x0022E , 0x00304 }, - { 0x00231 , 0x0022F , 0x00304 }, - { 0x00232 , 0x00059 , 0x00304 }, - { 0x00233 , 0x00079 , 0x00304 }, - { 0x00385 , 0x000A8 , 0x00301 }, - { 0x00386 , 0x00391 , 0x00301 }, - { 0x00388 , 0x00395 , 0x00301 }, - { 0x00389 , 0x00397 , 0x00301 }, - { 0x0038A , 0x00399 , 0x00301 }, - { 0x0038C , 0x0039F , 0x00301 }, - { 0x0038E , 0x003A5 , 0x00301 }, - { 0x0038F , 0x003A9 , 0x00301 }, - { 0x00390 , 0x003CA , 0x00301 }, - { 0x003AA , 0x00399 , 0x00308 }, - { 0x003AB , 0x003A5 , 0x00308 }, - { 0x003AC , 0x003B1 , 0x00301 }, - { 0x003AD , 0x003B5 , 0x00301 }, - { 0x003AE , 0x003B7 , 0x00301 }, - { 0x003AF , 0x003B9 , 0x00301 }, - { 0x003B0 , 0x003CB , 0x00301 }, - { 0x003CA , 0x003B9 , 0x00308 }, - { 0x003CB , 0x003C5 , 0x00308 }, - { 0x003CC , 0x003BF , 0x00301 }, - { 0x003CD , 0x003C5 , 0x00301 }, - { 0x003CE , 0x003C9 , 0x00301 }, - { 0x003D3 , 0x003D2 , 0x00301 }, - { 0x003D4 , 0x003D2 , 0x00308 }, - { 0x00400 , 0x00415 , 0x00300 }, - { 0x00401 , 0x00415 , 0x00308 }, - { 0x00403 , 0x00413 , 0x00301 }, - { 0x00407 , 0x00406 , 0x00308 }, - { 0x0040C , 0x0041A , 0x00301 }, - { 0x0040D , 0x00418 , 0x00300 }, - { 0x0040E , 0x00423 , 0x00306 }, - { 0x00419 , 0x00418 , 0x00306 }, - { 0x00439 , 0x00438 , 0x00306 }, - { 0x00450 , 0x00435 , 0x00300 }, - { 0x00451 , 0x00435 , 0x00308 }, - { 0x00453 , 0x00433 , 0x00301 }, - { 0x00457 , 0x00456 , 0x00308 }, - { 0x0045C , 0x0043A , 0x00301 }, - { 0x0045D , 0x00438 , 0x00300 }, - { 0x0045E , 0x00443 , 0x00306 }, - { 0x00476 , 0x00474 , 0x0030F }, - { 0x00477 , 0x00475 , 0x0030F }, - { 0x004C1 , 0x00416 , 0x00306 }, - { 0x004C2 , 0x00436 , 0x00306 }, - { 0x004D0 , 0x00410 , 0x00306 }, - { 0x004D1 , 0x00430 , 0x00306 }, - { 0x004D2 , 0x00410 , 0x00308 }, - { 0x004D3 , 0x00430 , 0x00308 }, - { 0x004D6 , 0x00415 , 0x00306 }, - { 0x004D7 , 0x00435 , 0x00306 }, - { 0x004DA , 0x004D8 , 0x00308 }, - { 0x004DB , 0x004D9 , 0x00308 }, - { 0x004DC , 0x00416 , 0x00308 }, - { 0x004DD , 0x00436 , 0x00308 }, - { 0x004DE , 0x00417 , 0x00308 }, - { 0x004DF , 0x00437 , 0x00308 }, - { 0x004E2 , 0x00418 , 0x00304 }, - { 0x004E3 , 0x00438 , 0x00304 }, - { 0x004E4 , 0x00418 , 0x00308 }, - { 0x004E5 , 0x00438 , 0x00308 }, - { 0x004E6 , 0x0041E , 0x00308 }, - { 0x004E7 , 0x0043E , 0x00308 }, - { 0x004EA , 0x004E8 , 0x00308 }, - { 0x004EB , 0x004E9 , 0x00308 }, - { 0x004EC , 0x0042D , 0x00308 }, - { 0x004ED , 0x0044D , 0x00308 }, - { 0x004EE , 0x00423 , 0x00304 }, - { 0x004EF , 0x00443 , 0x00304 }, - { 0x004F0 , 0x00423 , 0x00308 }, - { 0x004F1 , 0x00443 , 0x00308 }, - { 0x004F2 , 0x00423 , 0x0030B }, - { 0x004F3 , 0x00443 , 0x0030B }, - { 0x004F4 , 0x00427 , 0x00308 }, - { 0x004F5 , 0x00447 , 0x00308 }, - { 0x004F8 , 0x0042B , 0x00308 }, - { 0x004F9 , 0x0044B , 0x00308 }, - { 0x00622 , 0x00627 , 0x00653 }, - { 0x00623 , 0x00627 , 0x00654 }, - { 0x00624 , 0x00648 , 0x00654 }, - { 0x00625 , 0x00627 , 0x00655 }, - { 0x00626 , 0x0064A , 0x00654 }, - { 0x006C0 , 0x006D5 , 0x00654 }, - { 0x006C2 , 0x006C1 , 0x00654 }, - { 0x006D3 , 0x006D2 , 0x00654 }, - { 0x00929 , 0x00928 , 0x0093C }, - { 0x00931 , 0x00930 , 0x0093C }, - { 0x00934 , 0x00933 , 0x0093C }, - { 0x009CB , 0x009C7 , 0x009BE }, - { 0x009CC , 0x009C7 , 0x009D7 }, - { 0x00B48 , 0x00B47 , 0x00B56 }, - { 0x00B4B , 0x00B47 , 0x00B3E }, - { 0x00B4C , 0x00B47 , 0x00B57 }, - { 0x00B94 , 0x00B92 , 0x00BD7 }, - { 0x00BCA , 0x00BC6 , 0x00BBE }, - { 0x00BCB , 0x00BC7 , 0x00BBE }, - { 0x00BCC , 0x00BC6 , 0x00BD7 }, - { 0x00C48 , 0x00C46 , 0x00C56 }, - { 0x00CC0 , 0x00CBF , 0x00CD5 }, - { 0x00CC7 , 0x00CC6 , 0x00CD5 }, - { 0x00CC8 , 0x00CC6 , 0x00CD6 }, - { 0x00CCA , 0x00CC6 , 0x00CC2 }, - { 0x00CCB , 0x00CCA , 0x00CD5 }, - { 0x00D4A , 0x00D46 , 0x00D3E }, - { 0x00D4B , 0x00D47 , 0x00D3E }, - { 0x00D4C , 0x00D46 , 0x00D57 }, - { 0x00DDA , 0x00DD9 , 0x00DCA }, - { 0x00DDC , 0x00DD9 , 0x00DCF }, - { 0x00DDD , 0x00DDC , 0x00DCA }, - { 0x00DDE , 0x00DD9 , 0x00DDF }, - { 0x01026 , 0x01025 , 0x0102E }, - { 0x01B06 , 0x01B05 , 0x01B35 }, - { 0x01B08 , 0x01B07 , 0x01B35 }, - { 0x01B0A , 0x01B09 , 0x01B35 }, - { 0x01B0C , 0x01B0B , 0x01B35 }, - { 0x01B0E , 0x01B0D , 0x01B35 }, - { 0x01B12 , 0x01B11 , 0x01B35 }, - { 0x01B3B , 0x01B3A , 0x01B35 }, - { 0x01B3D , 0x01B3C , 0x01B35 }, - { 0x01B40 , 0x01B3E , 0x01B35 }, - { 0x01B41 , 0x01B3F , 0x01B35 }, - { 0x01B43 , 0x01B42 , 0x01B35 }, - { 0x01E00 , 0x00041 , 0x00325 }, - { 0x01E01 , 0x00061 , 0x00325 }, - { 0x01E02 , 0x00042 , 0x00307 }, - { 0x01E03 , 0x00062 , 0x00307 }, - { 0x01E04 , 0x00042 , 0x00323 }, - { 0x01E05 , 0x00062 , 0x00323 }, - { 0x01E06 , 0x00042 , 0x00331 }, - { 0x01E07 , 0x00062 , 0x00331 }, - { 0x01E08 , 0x000C7 , 0x00301 }, - { 0x01E09 , 0x000E7 , 0x00301 }, - { 0x01E0A , 0x00044 , 0x00307 }, - { 0x01E0B , 0x00064 , 0x00307 }, - { 0x01E0C , 0x00044 , 0x00323 }, - { 0x01E0D , 0x00064 , 0x00323 }, - { 0x01E0E , 0x00044 , 0x00331 }, - { 0x01E0F , 0x00064 , 0x00331 }, - { 0x01E10 , 0x00044 , 0x00327 }, - { 0x01E11 , 0x00064 , 0x00327 }, - { 0x01E12 , 0x00044 , 0x0032D }, - { 0x01E13 , 0x00064 , 0x0032D }, - { 0x01E14 , 0x00112 , 0x00300 }, - { 0x01E15 , 0x00113 , 0x00300 }, - { 0x01E16 , 0x00112 , 0x00301 }, - { 0x01E17 , 0x00113 , 0x00301 }, - { 0x01E18 , 0x00045 , 0x0032D }, - { 0x01E19 , 0x00065 , 0x0032D }, - { 0x01E1A , 0x00045 , 0x00330 }, - { 0x01E1B , 0x00065 , 0x00330 }, - { 0x01E1C , 0x00228 , 0x00306 }, - { 0x01E1D , 0x00229 , 0x00306 }, - { 0x01E1E , 0x00046 , 0x00307 }, - { 0x01E1F , 0x00066 , 0x00307 }, - { 0x01E20 , 0x00047 , 0x00304 }, - { 0x01E21 , 0x00067 , 0x00304 }, - { 0x01E22 , 0x00048 , 0x00307 }, - { 0x01E23 , 0x00068 , 0x00307 }, - { 0x01E24 , 0x00048 , 0x00323 }, - { 0x01E25 , 0x00068 , 0x00323 }, - { 0x01E26 , 0x00048 , 0x00308 }, - { 0x01E27 , 0x00068 , 0x00308 }, - { 0x01E28 , 0x00048 , 0x00327 }, - { 0x01E29 , 0x00068 , 0x00327 }, - { 0x01E2A , 0x00048 , 0x0032E }, - { 0x01E2B , 0x00068 , 0x0032E }, - { 0x01E2C , 0x00049 , 0x00330 }, - { 0x01E2D , 0x00069 , 0x00330 }, - { 0x01E2E , 0x000CF , 0x00301 }, - { 0x01E2F , 0x000EF , 0x00301 }, - { 0x01E30 , 0x0004B , 0x00301 }, - { 0x01E31 , 0x0006B , 0x00301 }, - { 0x01E32 , 0x0004B , 0x00323 }, - { 0x01E33 , 0x0006B , 0x00323 }, - { 0x01E34 , 0x0004B , 0x00331 }, - { 0x01E35 , 0x0006B , 0x00331 }, - { 0x01E36 , 0x0004C , 0x00323 }, - { 0x01E37 , 0x0006C , 0x00323 }, - { 0x01E38 , 0x01E36 , 0x00304 }, - { 0x01E39 , 0x01E37 , 0x00304 }, - { 0x01E3A , 0x0004C , 0x00331 }, - { 0x01E3B , 0x0006C , 0x00331 }, - { 0x01E3C , 0x0004C , 0x0032D }, - { 0x01E3D , 0x0006C , 0x0032D }, - { 0x01E3E , 0x0004D , 0x00301 }, - { 0x01E3F , 0x0006D , 0x00301 }, - { 0x01E40 , 0x0004D , 0x00307 }, - { 0x01E41 , 0x0006D , 0x00307 }, - { 0x01E42 , 0x0004D , 0x00323 }, - { 0x01E43 , 0x0006D , 0x00323 }, - { 0x01E44 , 0x0004E , 0x00307 }, - { 0x01E45 , 0x0006E , 0x00307 }, - { 0x01E46 , 0x0004E , 0x00323 }, - { 0x01E47 , 0x0006E , 0x00323 }, - { 0x01E48 , 0x0004E , 0x00331 }, - { 0x01E49 , 0x0006E , 0x00331 }, - { 0x01E4A , 0x0004E , 0x0032D }, - { 0x01E4B , 0x0006E , 0x0032D }, - { 0x01E4C , 0x000D5 , 0x00301 }, - { 0x01E4D , 0x000F5 , 0x00301 }, - { 0x01E4E , 0x000D5 , 0x00308 }, - { 0x01E4F , 0x000F5 , 0x00308 }, - { 0x01E50 , 0x0014C , 0x00300 }, - { 0x01E51 , 0x0014D , 0x00300 }, - { 0x01E52 , 0x0014C , 0x00301 }, - { 0x01E53 , 0x0014D , 0x00301 }, - { 0x01E54 , 0x00050 , 0x00301 }, - { 0x01E55 , 0x00070 , 0x00301 }, - { 0x01E56 , 0x00050 , 0x00307 }, - { 0x01E57 , 0x00070 , 0x00307 }, - { 0x01E58 , 0x00052 , 0x00307 }, - { 0x01E59 , 0x00072 , 0x00307 }, - { 0x01E5A , 0x00052 , 0x00323 }, - { 0x01E5B , 0x00072 , 0x00323 }, - { 0x01E5C , 0x01E5A , 0x00304 }, - { 0x01E5D , 0x01E5B , 0x00304 }, - { 0x01E5E , 0x00052 , 0x00331 }, - { 0x01E5F , 0x00072 , 0x00331 }, - { 0x01E60 , 0x00053 , 0x00307 }, - { 0x01E61 , 0x00073 , 0x00307 }, - { 0x01E62 , 0x00053 , 0x00323 }, - { 0x01E63 , 0x00073 , 0x00323 }, - { 0x01E64 , 0x0015A , 0x00307 }, - { 0x01E65 , 0x0015B , 0x00307 }, - { 0x01E66 , 0x00160 , 0x00307 }, - { 0x01E67 , 0x00161 , 0x00307 }, - { 0x01E68 , 0x01E62 , 0x00307 }, - { 0x01E69 , 0x01E63 , 0x00307 }, - { 0x01E6A , 0x00054 , 0x00307 }, - { 0x01E6B , 0x00074 , 0x00307 }, - { 0x01E6C , 0x00054 , 0x00323 }, - { 0x01E6D , 0x00074 , 0x00323 }, - { 0x01E6E , 0x00054 , 0x00331 }, - { 0x01E6F , 0x00074 , 0x00331 }, - { 0x01E70 , 0x00054 , 0x0032D }, - { 0x01E71 , 0x00074 , 0x0032D }, - { 0x01E72 , 0x00055 , 0x00324 }, - { 0x01E73 , 0x00075 , 0x00324 }, - { 0x01E74 , 0x00055 , 0x00330 }, - { 0x01E75 , 0x00075 , 0x00330 }, - { 0x01E76 , 0x00055 , 0x0032D }, - { 0x01E77 , 0x00075 , 0x0032D }, - { 0x01E78 , 0x00168 , 0x00301 }, - { 0x01E79 , 0x00169 , 0x00301 }, - { 0x01E7A , 0x0016A , 0x00308 }, - { 0x01E7B , 0x0016B , 0x00308 }, - { 0x01E7C , 0x00056 , 0x00303 }, - { 0x01E7D , 0x00076 , 0x00303 }, - { 0x01E7E , 0x00056 , 0x00323 }, - { 0x01E7F , 0x00076 , 0x00323 }, - { 0x01E80 , 0x00057 , 0x00300 }, - { 0x01E81 , 0x00077 , 0x00300 }, - { 0x01E82 , 0x00057 , 0x00301 }, - { 0x01E83 , 0x00077 , 0x00301 }, - { 0x01E84 , 0x00057 , 0x00308 }, - { 0x01E85 , 0x00077 , 0x00308 }, - { 0x01E86 , 0x00057 , 0x00307 }, - { 0x01E87 , 0x00077 , 0x00307 }, - { 0x01E88 , 0x00057 , 0x00323 }, - { 0x01E89 , 0x00077 , 0x00323 }, - { 0x01E8A , 0x00058 , 0x00307 }, - { 0x01E8B , 0x00078 , 0x00307 }, - { 0x01E8C , 0x00058 , 0x00308 }, - { 0x01E8D , 0x00078 , 0x00308 }, - { 0x01E8E , 0x00059 , 0x00307 }, - { 0x01E8F , 0x00079 , 0x00307 }, - { 0x01E90 , 0x0005A , 0x00302 }, - { 0x01E91 , 0x0007A , 0x00302 }, - { 0x01E92 , 0x0005A , 0x00323 }, - { 0x01E93 , 0x0007A , 0x00323 }, - { 0x01E94 , 0x0005A , 0x00331 }, - { 0x01E95 , 0x0007A , 0x00331 }, - { 0x01E96 , 0x00068 , 0x00331 }, - { 0x01E97 , 0x00074 , 0x00308 }, - { 0x01E98 , 0x00077 , 0x0030A }, - { 0x01E99 , 0x00079 , 0x0030A }, - { 0x01E9B , 0x0017F , 0x00307 }, - { 0x01EA0 , 0x00041 , 0x00323 }, - { 0x01EA1 , 0x00061 , 0x00323 }, - { 0x01EA2 , 0x00041 , 0x00309 }, - { 0x01EA3 , 0x00061 , 0x00309 }, - { 0x01EA4 , 0x000C2 , 0x00301 }, - { 0x01EA5 , 0x000E2 , 0x00301 }, - { 0x01EA6 , 0x000C2 , 0x00300 }, - { 0x01EA7 , 0x000E2 , 0x00300 }, - { 0x01EA8 , 0x000C2 , 0x00309 }, - { 0x01EA9 , 0x000E2 , 0x00309 }, - { 0x01EAA , 0x000C2 , 0x00303 }, - { 0x01EAB , 0x000E2 , 0x00303 }, - { 0x01EAC , 0x01EA0 , 0x00302 }, - { 0x01EAD , 0x01EA1 , 0x00302 }, - { 0x01EAE , 0x00102 , 0x00301 }, - { 0x01EAF , 0x00103 , 0x00301 }, - { 0x01EB0 , 0x00102 , 0x00300 }, - { 0x01EB1 , 0x00103 , 0x00300 }, - { 0x01EB2 , 0x00102 , 0x00309 }, - { 0x01EB3 , 0x00103 , 0x00309 }, - { 0x01EB4 , 0x00102 , 0x00303 }, - { 0x01EB5 , 0x00103 , 0x00303 }, - { 0x01EB6 , 0x01EA0 , 0x00306 }, - { 0x01EB7 , 0x01EA1 , 0x00306 }, - { 0x01EB8 , 0x00045 , 0x00323 }, - { 0x01EB9 , 0x00065 , 0x00323 }, - { 0x01EBA , 0x00045 , 0x00309 }, - { 0x01EBB , 0x00065 , 0x00309 }, - { 0x01EBC , 0x00045 , 0x00303 }, - { 0x01EBD , 0x00065 , 0x00303 }, - { 0x01EBE , 0x000CA , 0x00301 }, - { 0x01EBF , 0x000EA , 0x00301 }, - { 0x01EC0 , 0x000CA , 0x00300 }, - { 0x01EC1 , 0x000EA , 0x00300 }, - { 0x01EC2 , 0x000CA , 0x00309 }, - { 0x01EC3 , 0x000EA , 0x00309 }, - { 0x01EC4 , 0x000CA , 0x00303 }, - { 0x01EC5 , 0x000EA , 0x00303 }, - { 0x01EC6 , 0x01EB8 , 0x00302 }, - { 0x01EC7 , 0x01EB9 , 0x00302 }, - { 0x01EC8 , 0x00049 , 0x00309 }, - { 0x01EC9 , 0x00069 , 0x00309 }, - { 0x01ECA , 0x00049 , 0x00323 }, - { 0x01ECB , 0x00069 , 0x00323 }, - { 0x01ECC , 0x0004F , 0x00323 }, - { 0x01ECD , 0x0006F , 0x00323 }, - { 0x01ECE , 0x0004F , 0x00309 }, - { 0x01ECF , 0x0006F , 0x00309 }, - { 0x01ED0 , 0x000D4 , 0x00301 }, - { 0x01ED1 , 0x000F4 , 0x00301 }, - { 0x01ED2 , 0x000D4 , 0x00300 }, - { 0x01ED3 , 0x000F4 , 0x00300 }, - { 0x01ED4 , 0x000D4 , 0x00309 }, - { 0x01ED5 , 0x000F4 , 0x00309 }, - { 0x01ED6 , 0x000D4 , 0x00303 }, - { 0x01ED7 , 0x000F4 , 0x00303 }, - { 0x01ED8 , 0x01ECC , 0x00302 }, - { 0x01ED9 , 0x01ECD , 0x00302 }, - { 0x01EDA , 0x001A0 , 0x00301 }, - { 0x01EDB , 0x001A1 , 0x00301 }, - { 0x01EDC , 0x001A0 , 0x00300 }, - { 0x01EDD , 0x001A1 , 0x00300 }, - { 0x01EDE , 0x001A0 , 0x00309 }, - { 0x01EDF , 0x001A1 , 0x00309 }, - { 0x01EE0 , 0x001A0 , 0x00303 }, - { 0x01EE1 , 0x001A1 , 0x00303 }, - { 0x01EE2 , 0x001A0 , 0x00323 }, - { 0x01EE3 , 0x001A1 , 0x00323 }, - { 0x01EE4 , 0x00055 , 0x00323 }, - { 0x01EE5 , 0x00075 , 0x00323 }, - { 0x01EE6 , 0x00055 , 0x00309 }, - { 0x01EE7 , 0x00075 , 0x00309 }, - { 0x01EE8 , 0x001AF , 0x00301 }, - { 0x01EE9 , 0x001B0 , 0x00301 }, - { 0x01EEA , 0x001AF , 0x00300 }, - { 0x01EEB , 0x001B0 , 0x00300 }, - { 0x01EEC , 0x001AF , 0x00309 }, - { 0x01EED , 0x001B0 , 0x00309 }, - { 0x01EEE , 0x001AF , 0x00303 }, - { 0x01EEF , 0x001B0 , 0x00303 }, - { 0x01EF0 , 0x001AF , 0x00323 }, - { 0x01EF1 , 0x001B0 , 0x00323 }, - { 0x01EF2 , 0x00059 , 0x00300 }, - { 0x01EF3 , 0x00079 , 0x00300 }, - { 0x01EF4 , 0x00059 , 0x00323 }, - { 0x01EF5 , 0x00079 , 0x00323 }, - { 0x01EF6 , 0x00059 , 0x00309 }, - { 0x01EF7 , 0x00079 , 0x00309 }, - { 0x01EF8 , 0x00059 , 0x00303 }, - { 0x01EF9 , 0x00079 , 0x00303 }, - { 0x01F00 , 0x003B1 , 0x00313 }, - { 0x01F01 , 0x003B1 , 0x00314 }, - { 0x01F02 , 0x01F00 , 0x00300 }, - { 0x01F03 , 0x01F01 , 0x00300 }, - { 0x01F04 , 0x01F00 , 0x00301 }, - { 0x01F05 , 0x01F01 , 0x00301 }, - { 0x01F06 , 0x01F00 , 0x00342 }, - { 0x01F07 , 0x01F01 , 0x00342 }, - { 0x01F08 , 0x00391 , 0x00313 }, - { 0x01F09 , 0x00391 , 0x00314 }, - { 0x01F0A , 0x01F08 , 0x00300 }, - { 0x01F0B , 0x01F09 , 0x00300 }, - { 0x01F0C , 0x01F08 , 0x00301 }, - { 0x01F0D , 0x01F09 , 0x00301 }, - { 0x01F0E , 0x01F08 , 0x00342 }, - { 0x01F0F , 0x01F09 , 0x00342 }, - { 0x01F10 , 0x003B5 , 0x00313 }, - { 0x01F11 , 0x003B5 , 0x00314 }, - { 0x01F12 , 0x01F10 , 0x00300 }, - { 0x01F13 , 0x01F11 , 0x00300 }, - { 0x01F14 , 0x01F10 , 0x00301 }, - { 0x01F15 , 0x01F11 , 0x00301 }, - { 0x01F18 , 0x00395 , 0x00313 }, - { 0x01F19 , 0x00395 , 0x00314 }, - { 0x01F1A , 0x01F18 , 0x00300 }, - { 0x01F1B , 0x01F19 , 0x00300 }, - { 0x01F1C , 0x01F18 , 0x00301 }, - { 0x01F1D , 0x01F19 , 0x00301 }, - { 0x01F20 , 0x003B7 , 0x00313 }, - { 0x01F21 , 0x003B7 , 0x00314 }, - { 0x01F22 , 0x01F20 , 0x00300 }, - { 0x01F23 , 0x01F21 , 0x00300 }, - { 0x01F24 , 0x01F20 , 0x00301 }, - { 0x01F25 , 0x01F21 , 0x00301 }, - { 0x01F26 , 0x01F20 , 0x00342 }, - { 0x01F27 , 0x01F21 , 0x00342 }, - { 0x01F28 , 0x00397 , 0x00313 }, - { 0x01F29 , 0x00397 , 0x00314 }, - { 0x01F2A , 0x01F28 , 0x00300 }, - { 0x01F2B , 0x01F29 , 0x00300 }, - { 0x01F2C , 0x01F28 , 0x00301 }, - { 0x01F2D , 0x01F29 , 0x00301 }, - { 0x01F2E , 0x01F28 , 0x00342 }, - { 0x01F2F , 0x01F29 , 0x00342 }, - { 0x01F30 , 0x003B9 , 0x00313 }, - { 0x01F31 , 0x003B9 , 0x00314 }, - { 0x01F32 , 0x01F30 , 0x00300 }, - { 0x01F33 , 0x01F31 , 0x00300 }, - { 0x01F34 , 0x01F30 , 0x00301 }, - { 0x01F35 , 0x01F31 , 0x00301 }, - { 0x01F36 , 0x01F30 , 0x00342 }, - { 0x01F37 , 0x01F31 , 0x00342 }, - { 0x01F38 , 0x00399 , 0x00313 }, - { 0x01F39 , 0x00399 , 0x00314 }, - { 0x01F3A , 0x01F38 , 0x00300 }, - { 0x01F3B , 0x01F39 , 0x00300 }, - { 0x01F3C , 0x01F38 , 0x00301 }, - { 0x01F3D , 0x01F39 , 0x00301 }, - { 0x01F3E , 0x01F38 , 0x00342 }, - { 0x01F3F , 0x01F39 , 0x00342 }, - { 0x01F40 , 0x003BF , 0x00313 }, - { 0x01F41 , 0x003BF , 0x00314 }, - { 0x01F42 , 0x01F40 , 0x00300 }, - { 0x01F43 , 0x01F41 , 0x00300 }, - { 0x01F44 , 0x01F40 , 0x00301 }, - { 0x01F45 , 0x01F41 , 0x00301 }, - { 0x01F48 , 0x0039F , 0x00313 }, - { 0x01F49 , 0x0039F , 0x00314 }, - { 0x01F4A , 0x01F48 , 0x00300 }, - { 0x01F4B , 0x01F49 , 0x00300 }, - { 0x01F4C , 0x01F48 , 0x00301 }, - { 0x01F4D , 0x01F49 , 0x00301 }, - { 0x01F50 , 0x003C5 , 0x00313 }, - { 0x01F51 , 0x003C5 , 0x00314 }, - { 0x01F52 , 0x01F50 , 0x00300 }, - { 0x01F53 , 0x01F51 , 0x00300 }, - { 0x01F54 , 0x01F50 , 0x00301 }, - { 0x01F55 , 0x01F51 , 0x00301 }, - { 0x01F56 , 0x01F50 , 0x00342 }, - { 0x01F57 , 0x01F51 , 0x00342 }, - { 0x01F59 , 0x003A5 , 0x00314 }, - { 0x01F5B , 0x01F59 , 0x00300 }, - { 0x01F5D , 0x01F59 , 0x00301 }, - { 0x01F5F , 0x01F59 , 0x00342 }, - { 0x01F60 , 0x003C9 , 0x00313 }, - { 0x01F61 , 0x003C9 , 0x00314 }, - { 0x01F62 , 0x01F60 , 0x00300 }, - { 0x01F63 , 0x01F61 , 0x00300 }, - { 0x01F64 , 0x01F60 , 0x00301 }, - { 0x01F65 , 0x01F61 , 0x00301 }, - { 0x01F66 , 0x01F60 , 0x00342 }, - { 0x01F67 , 0x01F61 , 0x00342 }, - { 0x01F68 , 0x003A9 , 0x00313 }, - { 0x01F69 , 0x003A9 , 0x00314 }, - { 0x01F6A , 0x01F68 , 0x00300 }, - { 0x01F6B , 0x01F69 , 0x00300 }, - { 0x01F6C , 0x01F68 , 0x00301 }, - { 0x01F6D , 0x01F69 , 0x00301 }, - { 0x01F6E , 0x01F68 , 0x00342 }, - { 0x01F6F , 0x01F69 , 0x00342 }, - { 0x01F70 , 0x003B1 , 0x00300 }, - { 0x01F72 , 0x003B5 , 0x00300 }, - { 0x01F74 , 0x003B7 , 0x00300 }, - { 0x01F76 , 0x003B9 , 0x00300 }, - { 0x01F78 , 0x003BF , 0x00300 }, - { 0x01F7A , 0x003C5 , 0x00300 }, - { 0x01F7C , 0x003C9 , 0x00300 }, - { 0x01F80 , 0x01F00 , 0x00345 }, - { 0x01F81 , 0x01F01 , 0x00345 }, - { 0x01F82 , 0x01F02 , 0x00345 }, - { 0x01F83 , 0x01F03 , 0x00345 }, - { 0x01F84 , 0x01F04 , 0x00345 }, - { 0x01F85 , 0x01F05 , 0x00345 }, - { 0x01F86 , 0x01F06 , 0x00345 }, - { 0x01F87 , 0x01F07 , 0x00345 }, - { 0x01F88 , 0x01F08 , 0x00345 }, - { 0x01F89 , 0x01F09 , 0x00345 }, - { 0x01F8A , 0x01F0A , 0x00345 }, - { 0x01F8B , 0x01F0B , 0x00345 }, - { 0x01F8C , 0x01F0C , 0x00345 }, - { 0x01F8D , 0x01F0D , 0x00345 }, - { 0x01F8E , 0x01F0E , 0x00345 }, - { 0x01F8F , 0x01F0F , 0x00345 }, - { 0x01F90 , 0x01F20 , 0x00345 }, - { 0x01F91 , 0x01F21 , 0x00345 }, - { 0x01F92 , 0x01F22 , 0x00345 }, - { 0x01F93 , 0x01F23 , 0x00345 }, - { 0x01F94 , 0x01F24 , 0x00345 }, - { 0x01F95 , 0x01F25 , 0x00345 }, - { 0x01F96 , 0x01F26 , 0x00345 }, - { 0x01F97 , 0x01F27 , 0x00345 }, - { 0x01F98 , 0x01F28 , 0x00345 }, - { 0x01F99 , 0x01F29 , 0x00345 }, - { 0x01F9A , 0x01F2A , 0x00345 }, - { 0x01F9B , 0x01F2B , 0x00345 }, - { 0x01F9C , 0x01F2C , 0x00345 }, - { 0x01F9D , 0x01F2D , 0x00345 }, - { 0x01F9E , 0x01F2E , 0x00345 }, - { 0x01F9F , 0x01F2F , 0x00345 }, - { 0x01FA0 , 0x01F60 , 0x00345 }, - { 0x01FA1 , 0x01F61 , 0x00345 }, - { 0x01FA2 , 0x01F62 , 0x00345 }, - { 0x01FA3 , 0x01F63 , 0x00345 }, - { 0x01FA4 , 0x01F64 , 0x00345 }, - { 0x01FA5 , 0x01F65 , 0x00345 }, - { 0x01FA6 , 0x01F66 , 0x00345 }, - { 0x01FA7 , 0x01F67 , 0x00345 }, - { 0x01FA8 , 0x01F68 , 0x00345 }, - { 0x01FA9 , 0x01F69 , 0x00345 }, - { 0x01FAA , 0x01F6A , 0x00345 }, - { 0x01FAB , 0x01F6B , 0x00345 }, - { 0x01FAC , 0x01F6C , 0x00345 }, - { 0x01FAD , 0x01F6D , 0x00345 }, - { 0x01FAE , 0x01F6E , 0x00345 }, - { 0x01FAF , 0x01F6F , 0x00345 }, - { 0x01FB0 , 0x003B1 , 0x00306 }, - { 0x01FB1 , 0x003B1 , 0x00304 }, - { 0x01FB2 , 0x01F70 , 0x00345 }, - { 0x01FB3 , 0x003B1 , 0x00345 }, - { 0x01FB4 , 0x003AC , 0x00345 }, - { 0x01FB6 , 0x003B1 , 0x00342 }, - { 0x01FB7 , 0x01FB6 , 0x00345 }, - { 0x01FB8 , 0x00391 , 0x00306 }, - { 0x01FB9 , 0x00391 , 0x00304 }, - { 0x01FBA , 0x00391 , 0x00300 }, - { 0x01FBC , 0x00391 , 0x00345 }, - { 0x01FC1 , 0x000A8 , 0x00342 }, - { 0x01FC2 , 0x01F74 , 0x00345 }, - { 0x01FC3 , 0x003B7 , 0x00345 }, - { 0x01FC4 , 0x003AE , 0x00345 }, - { 0x01FC6 , 0x003B7 , 0x00342 }, - { 0x01FC7 , 0x01FC6 , 0x00345 }, - { 0x01FC8 , 0x00395 , 0x00300 }, - { 0x01FCA , 0x00397 , 0x00300 }, - { 0x01FCC , 0x00397 , 0x00345 }, - { 0x01FCD , 0x01FBF , 0x00300 }, - { 0x01FCE , 0x01FBF , 0x00301 }, - { 0x01FCF , 0x01FBF , 0x00342 }, - { 0x01FD0 , 0x003B9 , 0x00306 }, - { 0x01FD1 , 0x003B9 , 0x00304 }, - { 0x01FD2 , 0x003CA , 0x00300 }, - { 0x01FD6 , 0x003B9 , 0x00342 }, - { 0x01FD7 , 0x003CA , 0x00342 }, - { 0x01FD8 , 0x00399 , 0x00306 }, - { 0x01FD9 , 0x00399 , 0x00304 }, - { 0x01FDA , 0x00399 , 0x00300 }, - { 0x01FDD , 0x01FFE , 0x00300 }, - { 0x01FDE , 0x01FFE , 0x00301 }, - { 0x01FDF , 0x01FFE , 0x00342 }, - { 0x01FE0 , 0x003C5 , 0x00306 }, - { 0x01FE1 , 0x003C5 , 0x00304 }, - { 0x01FE2 , 0x003CB , 0x00300 }, - { 0x01FE4 , 0x003C1 , 0x00313 }, - { 0x01FE5 , 0x003C1 , 0x00314 }, - { 0x01FE6 , 0x003C5 , 0x00342 }, - { 0x01FE7 , 0x003CB , 0x00342 }, - { 0x01FE8 , 0x003A5 , 0x00306 }, - { 0x01FE9 , 0x003A5 , 0x00304 }, - { 0x01FEA , 0x003A5 , 0x00300 }, - { 0x01FEC , 0x003A1 , 0x00314 }, - { 0x01FED , 0x000A8 , 0x00300 }, - { 0x01FF2 , 0x01F7C , 0x00345 }, - { 0x01FF3 , 0x003C9 , 0x00345 }, - { 0x01FF4 , 0x003CE , 0x00345 }, - { 0x01FF6 , 0x003C9 , 0x00342 }, - { 0x01FF7 , 0x01FF6 , 0x00345 }, - { 0x01FF8 , 0x0039F , 0x00300 }, - { 0x01FFA , 0x003A9 , 0x00300 }, - { 0x01FFC , 0x003A9 , 0x00345 }, - { 0x0219A , 0x02190 , 0x00338 }, - { 0x0219B , 0x02192 , 0x00338 }, - { 0x021AE , 0x02194 , 0x00338 }, - { 0x021CD , 0x021D0 , 0x00338 }, - { 0x021CE , 0x021D4 , 0x00338 }, - { 0x021CF , 0x021D2 , 0x00338 }, - { 0x02204 , 0x02203 , 0x00338 }, - { 0x02209 , 0x02208 , 0x00338 }, - { 0x0220C , 0x0220B , 0x00338 }, - { 0x02224 , 0x02223 , 0x00338 }, - { 0x02226 , 0x02225 , 0x00338 }, - { 0x02241 , 0x0223C , 0x00338 }, - { 0x02244 , 0x02243 , 0x00338 }, - { 0x02247 , 0x02245 , 0x00338 }, - { 0x02249 , 0x02248 , 0x00338 }, - { 0x02260 , 0x0003D , 0x00338 }, - { 0x02262 , 0x02261 , 0x00338 }, - { 0x0226D , 0x0224D , 0x00338 }, - { 0x0226E , 0x0003C , 0x00338 }, - { 0x0226F , 0x0003E , 0x00338 }, - { 0x02270 , 0x02264 , 0x00338 }, - { 0x02271 , 0x02265 , 0x00338 }, - { 0x02274 , 0x02272 , 0x00338 }, - { 0x02275 , 0x02273 , 0x00338 }, - { 0x02278 , 0x02276 , 0x00338 }, - { 0x02279 , 0x02277 , 0x00338 }, - { 0x02280 , 0x0227A , 0x00338 }, - { 0x02281 , 0x0227B , 0x00338 }, - { 0x02284 , 0x02282 , 0x00338 }, - { 0x02285 , 0x02283 , 0x00338 }, - { 0x02288 , 0x02286 , 0x00338 }, - { 0x02289 , 0x02287 , 0x00338 }, - { 0x022AC , 0x022A2 , 0x00338 }, - { 0x022AD , 0x022A8 , 0x00338 }, - { 0x022AE , 0x022A9 , 0x00338 }, - { 0x022AF , 0x022AB , 0x00338 }, - { 0x022E0 , 0x0227C , 0x00338 }, - { 0x022E1 , 0x0227D , 0x00338 }, - { 0x022E2 , 0x02291 , 0x00338 }, - { 0x022E3 , 0x02292 , 0x00338 }, - { 0x022EA , 0x022B2 , 0x00338 }, - { 0x022EB , 0x022B3 , 0x00338 }, - { 0x022EC , 0x022B4 , 0x00338 }, - { 0x022ED , 0x022B5 , 0x00338 }, - { 0x0304C , 0x0304B , 0x03099 }, - { 0x0304E , 0x0304D , 0x03099 }, - { 0x03050 , 0x0304F , 0x03099 }, - { 0x03052 , 0x03051 , 0x03099 }, - { 0x03054 , 0x03053 , 0x03099 }, - { 0x03056 , 0x03055 , 0x03099 }, - { 0x03058 , 0x03057 , 0x03099 }, - { 0x0305A , 0x03059 , 0x03099 }, - { 0x0305C , 0x0305B , 0x03099 }, - { 0x0305E , 0x0305D , 0x03099 }, - { 0x03060 , 0x0305F , 0x03099 }, - { 0x03062 , 0x03061 , 0x03099 }, - { 0x03065 , 0x03064 , 0x03099 }, - { 0x03067 , 0x03066 , 0x03099 }, - { 0x03069 , 0x03068 , 0x03099 }, - { 0x03070 , 0x0306F , 0x03099 }, - { 0x03071 , 0x0306F , 0x0309A }, - { 0x03073 , 0x03072 , 0x03099 }, - { 0x03074 , 0x03072 , 0x0309A }, - { 0x03076 , 0x03075 , 0x03099 }, - { 0x03077 , 0x03075 , 0x0309A }, - { 0x03079 , 0x03078 , 0x03099 }, - { 0x0307A , 0x03078 , 0x0309A }, - { 0x0307C , 0x0307B , 0x03099 }, - { 0x0307D , 0x0307B , 0x0309A }, - { 0x03094 , 0x03046 , 0x03099 }, - { 0x0309E , 0x0309D , 0x03099 }, - { 0x030AC , 0x030AB , 0x03099 }, - { 0x030AE , 0x030AD , 0x03099 }, - { 0x030B0 , 0x030AF , 0x03099 }, - { 0x030B2 , 0x030B1 , 0x03099 }, - { 0x030B4 , 0x030B3 , 0x03099 }, - { 0x030B6 , 0x030B5 , 0x03099 }, - { 0x030B8 , 0x030B7 , 0x03099 }, - { 0x030BA , 0x030B9 , 0x03099 }, - { 0x030BC , 0x030BB , 0x03099 }, - { 0x030BE , 0x030BD , 0x03099 }, - { 0x030C0 , 0x030BF , 0x03099 }, - { 0x030C2 , 0x030C1 , 0x03099 }, - { 0x030C5 , 0x030C4 , 0x03099 }, - { 0x030C7 , 0x030C6 , 0x03099 }, - { 0x030C9 , 0x030C8 , 0x03099 }, - { 0x030D0 , 0x030CF , 0x03099 }, - { 0x030D1 , 0x030CF , 0x0309A }, - { 0x030D3 , 0x030D2 , 0x03099 }, - { 0x030D4 , 0x030D2 , 0x0309A }, - { 0x030D6 , 0x030D5 , 0x03099 }, - { 0x030D7 , 0x030D5 , 0x0309A }, - { 0x030D9 , 0x030D8 , 0x03099 }, - { 0x030DA , 0x030D8 , 0x0309A }, - { 0x030DC , 0x030DB , 0x03099 }, - { 0x030DD , 0x030DB , 0x0309A }, - { 0x030F4 , 0x030A6 , 0x03099 }, - { 0x030F7 , 0x030EF , 0x03099 }, - { 0x030F8 , 0x030F0 , 0x03099 }, - { 0x030F9 , 0x030F1 , 0x03099 }, - { 0x030FA , 0x030F2 , 0x03099 }, - { 0x030FE , 0x030FD , 0x03099 }, - { 0x1109A , 0x11099 , 0x110BA }, - { 0x1109C , 0x1109B , 0x110BA }, - { 0x110AB , 0x110A5 , 0x110BA }, -}; - -#endif /* ARCHIVE_STRING_COMPOSITION_H_INCLUDED */ - diff --git a/thirdparty/libarchive/libarchive/archive_string_sprintf.c b/thirdparty/libarchive/libarchive/archive_string_sprintf.c deleted file mode 100644 index 969a5603a..000000000 --- a/thirdparty/libarchive/libarchive/archive_string_sprintf.c +++ /dev/null @@ -1,192 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_string_sprintf.c 189435 2009-03-06 05:14:55Z kientzle $"); - -/* - * The use of printf()-family functions can be troublesome - * for space-constrained applications. In addition, correctly - * implementing this function in terms of vsnprintf() requires - * two calls (one to determine the size, another to format the - * result), which in turn requires duplicating the argument list - * using va_copy, which isn't yet universally available. - * - * So, I've implemented a bare minimum of printf()-like capability - * here. This is only used to format error messages, so doesn't - * require any floating-point support or field-width handling. - */ -#ifdef HAVE_ERRNO_H -#include -#endif -#include - -#include "archive_string.h" -#include "archive_private.h" - -/* - * Utility functions to format signed/unsigned integers and append - * them to an archive_string. - */ -static void -append_uint(struct archive_string *as, uintmax_t d, unsigned base) -{ - static const char digits[] = "0123456789abcdef"; - if (d >= base) - append_uint(as, d/base, base); - archive_strappend_char(as, digits[d % base]); -} - -static void -append_int(struct archive_string *as, intmax_t d, unsigned base) -{ - uintmax_t ud; - - if (d < 0) { - archive_strappend_char(as, '-'); - ud = (d == INTMAX_MIN) ? (uintmax_t)(INTMAX_MAX) + 1 : (uintmax_t)(-d); - } else - ud = d; - append_uint(as, ud, base); -} - - -void -archive_string_sprintf(struct archive_string *as, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - archive_string_vsprintf(as, fmt, ap); - va_end(ap); -} - -/* - * Like 'vsprintf', but ensures the target is big enough, resizing if - * necessary. - */ -void -archive_string_vsprintf(struct archive_string *as, const char *fmt, - va_list ap) -{ - char long_flag; - intmax_t s; /* Signed integer temp. */ - uintmax_t u; /* Unsigned integer temp. */ - const char *p, *p2; - const wchar_t *pw; - - if (archive_string_ensure(as, 64) == NULL) - __archive_errx(1, "Out of memory"); - - if (fmt == NULL) { - as->s[0] = 0; - return; - } - - for (p = fmt; *p != '\0'; p++) { - const char *saved_p = p; - - if (*p != '%') { - archive_strappend_char(as, *p); - continue; - } - - p++; - - long_flag = '\0'; - switch(*p) { - case 'j': - case 'l': - case 'z': - long_flag = *p; - p++; - break; - } - - switch (*p) { - case '%': - archive_strappend_char(as, '%'); - break; - case 'c': - s = va_arg(ap, int); - archive_strappend_char(as, (char)s); - break; - case 'd': - switch(long_flag) { - case 'j': s = va_arg(ap, intmax_t); break; - case 'l': s = va_arg(ap, long); break; - case 'z': s = va_arg(ap, ssize_t); break; - default: s = va_arg(ap, int); break; - } - append_int(as, s, 10); - break; - case 's': - switch(long_flag) { - case 'l': - pw = va_arg(ap, wchar_t *); - if (pw == NULL) - pw = L"(null)"; - if (archive_string_append_from_wcs(as, pw, - wcslen(pw)) != 0 && errno == ENOMEM) - __archive_errx(1, "Out of memory"); - break; - default: - p2 = va_arg(ap, char *); - if (p2 == NULL) - p2 = "(null)"; - archive_strcat(as, p2); - break; - } - break; - case 'S': - pw = va_arg(ap, wchar_t *); - if (pw == NULL) - pw = L"(null)"; - if (archive_string_append_from_wcs(as, pw, - wcslen(pw)) != 0 && errno == ENOMEM) - __archive_errx(1, "Out of memory"); - break; - case 'o': case 'u': case 'x': case 'X': - /* Common handling for unsigned integer formats. */ - switch(long_flag) { - case 'j': u = va_arg(ap, uintmax_t); break; - case 'l': u = va_arg(ap, unsigned long); break; - case 'z': u = va_arg(ap, size_t); break; - default: u = va_arg(ap, unsigned int); break; - } - /* Format it in the correct base. */ - switch (*p) { - case 'o': append_uint(as, u, 8); break; - case 'u': append_uint(as, u, 10); break; - default: append_uint(as, u, 16); break; - } - break; - default: - /* Rewind and print the initial '%' literally. */ - p = saved_p; - archive_strappend_char(as, *p); - } - } -} diff --git a/thirdparty/libarchive/libarchive/archive_util.3 b/thirdparty/libarchive/libarchive/archive_util.3 deleted file mode 100644 index d5d4e7dfd..000000000 --- a/thirdparty/libarchive/libarchive/archive_util.3 +++ /dev/null @@ -1,224 +0,0 @@ -.\" Copyright (c) 2003-2007 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd February 2, 2012 -.Dt ARCHIVE_UTIL 3 -.Os -.Sh NAME -.Nm archive_clear_error , -.Nm archive_compression , -.Nm archive_compression_name , -.Nm archive_copy_error , -.Nm archive_errno , -.Nm archive_error_string , -.Nm archive_file_count , -.Nm archive_filter_code , -.Nm archive_filter_count , -.Nm archive_filter_name , -.Nm archive_format , -.Nm archive_format_name , -.Nm archive_position , -.Nm archive_set_error -.Nd libarchive utility functions -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive.h -.Ft void -.Fn archive_clear_error "struct archive *" -.Ft int -.Fn archive_compression "struct archive *" -.Ft const char * -.Fn archive_compression_name "struct archive *" -.Ft void -.Fn archive_copy_error "struct archive *" "struct archive *" -.Ft int -.Fn archive_errno "struct archive *" -.Ft const char * -.Fn archive_error_string "struct archive *" -.Ft int -.Fn archive_file_count "struct archive *" -.Ft int -.Fn archive_filter_code "struct archive *" "int" -.Ft int -.Fn archive_filter_count "struct archive *" "int" -.Ft const char * -.Fn archive_filter_name "struct archive *" "int" -.Ft int -.Fn archive_format "struct archive *" -.Ft const char * -.Fn archive_format_name "struct archive *" -.Ft int64_t -.Fn archive_position "struct archive *" "int" -.Ft void -.Fo archive_set_error -.Fa "struct archive *" -.Fa "int error_code" -.Fa "const char *fmt" -.Fa "..." -.Fc -.Sh DESCRIPTION -These functions provide access to various information about the -.Tn struct archive -object used in the -.Xr libarchive 3 -library. -.Bl -tag -compact -width indent -.It Fn archive_clear_error -Clears any error information left over from a previous call. -Not generally used in client code. -.It Fn archive_compression -Synonym for -.Fn archive_filter_code a 0 . -.It Fn archive_compression_name -Synonym for -.Fn archive_filter_name a 0 . -.It Fn archive_copy_error -Copies error information from one archive to another. -.It Fn archive_errno -Returns a numeric error code (see -.Xr errno 2 ) -indicating the reason for the most recent error return. -Note that this can not be reliably used to detect whether an -error has occurred. -It should be used only after another libarchive function -has returned an error status. -.It Fn archive_error_string -Returns a textual error message suitable for display. -The error message here is usually more specific than that -obtained from passing the result of -.Fn archive_errno -to -.Xr strerror 3 . -.It Fn archive_file_count -Returns a count of the number of files processed by this archive object. -The count is incremented by calls to -.Xr archive_write_header 3 -or -.Xr archive_read_next_header 3 . -.It Fn archive_filter_code -Returns a numeric code identifying the indicated filter. -See -.Fn archive_filter_count -for details of the numbering. -.It Fn archive_filter_count -Returns the number of filters in the current pipeline. -For read archive handles, these filters are added automatically -by the automatic format detection. -For write archive handles, these filters are added by calls to the various -.Fn archive_write_add_filter_XXX -functions. -Filters in the resulting pipeline are numbered so that filter 0 -is the filter closest to the format handler. -As a convenience, functions that expect a filter number will -accept -1 as a synonym for the highest-numbered filter. -.Pp -For example, when reading a uuencoded gzipped tar archive, there -are three filters: -filter 0 is the gunzip filter, -filter 1 is the uudecode filter, -and filter 2 is the pseudo-filter that wraps the archive read functions. -In this case, requesting -.Fn archive_position a -1 -would be a synonym for -.Fn archive_position a 2 -which would return the number of bytes currently read from the archive, while -.Fn archive_position a 1 -would return the number of bytes after uudecoding, and -.Fn archive_position a 0 -would return the number of bytes after decompression. -.It Fn archive_filter_name -Returns a textual name identifying the indicated filter. -See -.Fn archive_filter_count -for details of the numbering. -.It Fn archive_format -Returns a numeric code indicating the format of the current -archive entry. -This value is set by a successful call to -.Fn archive_read_next_header . -Note that it is common for this value to change from -entry to entry. -For example, a tar archive might have several entries that -utilize GNU tar extensions and several entries that do not. -These entries will have different format codes. -.It Fn archive_format_name -A textual description of the format of the current entry. -.It Fn archive_position -Returns the number of bytes read from or written to the indicated filter. -In particular, -.Fn archive_position a 0 -returns the number of bytes read or written by the format handler, while -.Fn archive_position a -1 -returns the number of bytes read or written to the archive. -See -.Fn archive_filter_count -for details of the numbering here. -.It Fn archive_set_error -Sets the numeric error code and error description that will be returned -by -.Fn archive_errno -and -.Fn archive_error_string . -This function should be used within I/O callbacks to set system-specific -error codes and error descriptions. -This function accepts a printf-like format string and arguments. -However, you should be careful to use only the following printf -format specifiers: -.Dq %c , -.Dq %d , -.Dq %jd , -.Dq %jo , -.Dq %ju , -.Dq %jx , -.Dq %ld , -.Dq %lo , -.Dq %lu , -.Dq %lx , -.Dq %o , -.Dq %u , -.Dq %s , -.Dq %x , -.Dq %% . -Field-width specifiers and other printf features are -not uniformly supported and should not be used. -.El -.Sh SEE ALSO -.Xr archive_read 3 , -.Xr archive_write 3 , -.Xr libarchive 3 , -.Xr printf 3 -.Sh HISTORY -The -.Nm libarchive -library first appeared in -.Fx 5.3 . -.Sh AUTHORS -.An -nosplit -The -.Nm libarchive -library was written by -.An Tim Kientzle Aq kientzle@acm.org . diff --git a/thirdparty/libarchive/libarchive/archive_util.c b/thirdparty/libarchive/libarchive/archive_util.c deleted file mode 100644 index 40603c483..000000000 --- a/thirdparty/libarchive/libarchive/archive_util.c +++ /dev/null @@ -1,704 +0,0 @@ -/*- - * Copyright (c) 2009-2012,2014 Michihiro NAKAJIMA - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:14Z kientzle $"); - -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#if defined(_WIN32) && !defined(__CYGWIN__) -#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA -/* don't use bcrypt when XP needs to be supported */ -#include - -/* Common in other bcrypt implementations, but missing from VS2008. */ -#ifndef BCRYPT_SUCCESS -#define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS) -#endif - -#elif defined(HAVE_WINCRYPT_H) -#include -#endif -#endif -#ifdef HAVE_ZLIB_H -#include -#endif -#ifdef HAVE_LZMA_H -#include -#endif -#ifdef HAVE_BZLIB_H -#include -#endif -#ifdef HAVE_LZ4_H -#include -#endif - -#include "archive.h" -#include "archive_private.h" -#include "archive_random_private.h" -#include "archive_string.h" - -#ifndef O_CLOEXEC -#define O_CLOEXEC 0 -#endif - -static int archive_utility_string_sort_helper(char **, unsigned int); - -/* Generic initialization of 'struct archive' objects. */ -int -__archive_clean(struct archive *a) -{ - archive_string_conversion_free(a); - return (ARCHIVE_OK); -} - -int -archive_version_number(void) -{ - return (ARCHIVE_VERSION_NUMBER); -} - -const char * -archive_version_string(void) -{ - return (ARCHIVE_VERSION_STRING); -} - -int -archive_errno(struct archive *a) -{ - return (a->archive_error_number); -} - -const char * -archive_error_string(struct archive *a) -{ - - if (a->error != NULL && *a->error != '\0') - return (a->error); - else - return (NULL); -} - -int -archive_file_count(struct archive *a) -{ - return (a->file_count); -} - -int -archive_format(struct archive *a) -{ - return (a->archive_format); -} - -const char * -archive_format_name(struct archive *a) -{ - return (a->archive_format_name); -} - - -int -archive_compression(struct archive *a) -{ - return archive_filter_code(a, 0); -} - -const char * -archive_compression_name(struct archive *a) -{ - return archive_filter_name(a, 0); -} - - -/* - * Return a count of the number of compressed bytes processed. - */ -la_int64_t -archive_position_compressed(struct archive *a) -{ - return archive_filter_bytes(a, -1); -} - -/* - * Return a count of the number of uncompressed bytes processed. - */ -la_int64_t -archive_position_uncompressed(struct archive *a) -{ - return archive_filter_bytes(a, 0); -} - -void -archive_clear_error(struct archive *a) -{ - archive_string_empty(&a->error_string); - a->error = NULL; - a->archive_error_number = 0; -} - -void -archive_set_error(struct archive *a, int error_number, const char *fmt, ...) -{ - va_list ap; - - a->archive_error_number = error_number; - if (fmt == NULL) { - a->error = NULL; - return; - } - - archive_string_empty(&(a->error_string)); - va_start(ap, fmt); - archive_string_vsprintf(&(a->error_string), fmt, ap); - va_end(ap); - a->error = a->error_string.s; -} - -void -archive_copy_error(struct archive *dest, struct archive *src) -{ - dest->archive_error_number = src->archive_error_number; - - archive_string_copy(&dest->error_string, &src->error_string); - dest->error = dest->error_string.s; -} - -void -__archive_errx(int retvalue, const char *msg) -{ - static const char msg1[] = "Fatal Internal Error in libarchive: "; - size_t s; - - s = write(2, msg1, strlen(msg1)); - (void)s; /* UNUSED */ - s = write(2, msg, strlen(msg)); - (void)s; /* UNUSED */ - s = write(2, "\n", 1); - (void)s; /* UNUSED */ - exit(retvalue); -} - -/* - * Create a temporary file - */ -#if defined(_WIN32) && !defined(__CYGWIN__) - -/* - * Do not use Windows tmpfile() function. - * It will make a temporary file under the root directory - * and it'll cause permission error if a user who is - * non-Administrator creates temporary files. - * Also Windows version of mktemp family including _mktemp_s - * are not secure. - */ -static int -__archive_mktempx(const char *tmpdir, wchar_t *template) -{ - static const wchar_t prefix[] = L"libarchive_"; - static const wchar_t suffix[] = L"XXXXXXXXXX"; - static const wchar_t num[] = { - L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7', - L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F', - L'G', L'H', L'I', L'J', L'K', L'L', L'M', L'N', - L'O', L'P', L'Q', L'R', L'S', L'T', L'U', L'V', - L'W', L'X', L'Y', L'Z', L'a', L'b', L'c', L'd', - L'e', L'f', L'g', L'h', L'i', L'j', L'k', L'l', - L'm', L'n', L'o', L'p', L'q', L'r', L's', L't', - L'u', L'v', L'w', L'x', L'y', L'z' - }; - struct archive_wstring temp_name; - wchar_t *ws; - DWORD attr; - wchar_t *xp, *ep; - int fd; -#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA - BCRYPT_ALG_HANDLE hAlg = NULL; -#else - HCRYPTPROV hProv = (HCRYPTPROV)NULL; -#endif - fd = -1; - ws = NULL; - - if (template == NULL) { - archive_string_init(&temp_name); - - /* Get a temporary directory. */ - if (tmpdir == NULL) { - size_t l; - wchar_t *tmp; - - l = GetTempPathW(0, NULL); - if (l == 0) { - la_dosmaperr(GetLastError()); - goto exit_tmpfile; - } - tmp = malloc(l*sizeof(wchar_t)); - if (tmp == NULL) { - errno = ENOMEM; - goto exit_tmpfile; - } - GetTempPathW((DWORD)l, tmp); - archive_wstrcpy(&temp_name, tmp); - free(tmp); - } else { - if (archive_wstring_append_from_mbs(&temp_name, tmpdir, - strlen(tmpdir)) < 0) - goto exit_tmpfile; - if (temp_name.s[temp_name.length-1] != L'/') - archive_wstrappend_wchar(&temp_name, L'/'); - } - - /* Check if temp_name is a directory. */ - attr = GetFileAttributesW(temp_name.s); - if (attr == (DWORD)-1) { - if (GetLastError() != ERROR_FILE_NOT_FOUND) { - la_dosmaperr(GetLastError()); - goto exit_tmpfile; - } - ws = __la_win_permissive_name_w(temp_name.s); - if (ws == NULL) { - errno = EINVAL; - goto exit_tmpfile; - } - attr = GetFileAttributesW(ws); - if (attr == (DWORD)-1) { - la_dosmaperr(GetLastError()); - goto exit_tmpfile; - } - } - if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) { - errno = ENOTDIR; - goto exit_tmpfile; - } - - /* - * Create a temporary file. - */ - archive_wstrcat(&temp_name, prefix); - archive_wstrcat(&temp_name, suffix); - ep = temp_name.s + archive_strlen(&temp_name); - xp = ep - wcslen(suffix); - template = temp_name.s; - } else { - xp = wcschr(template, L'X'); - if (xp == NULL) /* No X, programming error */ - abort(); - for (ep = xp; *ep == L'X'; ep++) - continue; - if (*ep) /* X followed by non X, programming error */ - abort(); - } - -#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA - if (!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_RNG_ALGORITHM, - NULL, 0))) { - la_dosmaperr(GetLastError()); - goto exit_tmpfile; - } -#else - if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT)) { - la_dosmaperr(GetLastError()); - goto exit_tmpfile; - } -#endif - - for (;;) { - wchar_t *p; - HANDLE h; -# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */ - CREATEFILE2_EXTENDED_PARAMETERS createExParams; -#endif - - /* Generate a random file name through CryptGenRandom(). */ - p = xp; -#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA - if (!BCRYPT_SUCCESS(BCryptGenRandom(hAlg, (PUCHAR)p, - (DWORD)(ep - p)*sizeof(wchar_t), 0))) { - la_dosmaperr(GetLastError()); - goto exit_tmpfile; - } -#else - if (!CryptGenRandom(hProv, (DWORD)(ep - p)*sizeof(wchar_t), - (BYTE*)p)) { - la_dosmaperr(GetLastError()); - goto exit_tmpfile; - } -#endif - for (; p < ep; p++) - *p = num[((DWORD)*p) % (sizeof(num)/sizeof(num[0]))]; - - free(ws); - ws = __la_win_permissive_name_w(template); - if (ws == NULL) { - errno = EINVAL; - goto exit_tmpfile; - } - if (template == temp_name.s) { - attr = FILE_ATTRIBUTE_TEMPORARY | - FILE_FLAG_DELETE_ON_CLOSE; - } else { - /* mkstemp */ - attr = FILE_ATTRIBUTE_NORMAL; - } -# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */ - ZeroMemory(&createExParams, sizeof(createExParams)); - createExParams.dwSize = sizeof(createExParams); - createExParams.dwFileAttributes = attr & 0xFFFF; - createExParams.dwFileFlags = attr & 0xFFF00000; - h = CreateFile2(ws, - GENERIC_READ | GENERIC_WRITE | DELETE, - 0,/* Not share */ - CREATE_NEW, - &createExParams); -#else - h = CreateFileW(ws, - GENERIC_READ | GENERIC_WRITE | DELETE, - 0,/* Not share */ - NULL, - CREATE_NEW,/* Create a new file only */ - attr, - NULL); -#endif - if (h == INVALID_HANDLE_VALUE) { - /* The same file already exists. retry with - * a new filename. */ - if (GetLastError() == ERROR_FILE_EXISTS) - continue; - /* Otherwise, fail creation temporary file. */ - la_dosmaperr(GetLastError()); - goto exit_tmpfile; - } - fd = _open_osfhandle((intptr_t)h, _O_BINARY | _O_RDWR); - if (fd == -1) { - la_dosmaperr(GetLastError()); - CloseHandle(h); - goto exit_tmpfile; - } else - break;/* success! */ - } -exit_tmpfile: -#if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA - if (hAlg != NULL) - BCryptCloseAlgorithmProvider(hAlg, 0); -#else - if (hProv != (HCRYPTPROV)NULL) - CryptReleaseContext(hProv, 0); -#endif - free(ws); - if (template == temp_name.s) - archive_wstring_free(&temp_name); - return (fd); -} - -int -__archive_mktemp(const char *tmpdir) -{ - return __archive_mktempx(tmpdir, NULL); -} - -int -__archive_mkstemp(wchar_t *template) -{ - return __archive_mktempx(NULL, template); -} - -#else - -static int -get_tempdir(struct archive_string *temppath) -{ - const char *tmp; - - tmp = getenv("TMPDIR"); - if (tmp == NULL) -#ifdef _PATH_TMP - tmp = _PATH_TMP; -#else - tmp = "/tmp"; -#endif - archive_strcpy(temppath, tmp); - if (temppath->s[temppath->length-1] != '/') - archive_strappend_char(temppath, '/'); - return (ARCHIVE_OK); -} - -#if defined(HAVE_MKSTEMP) - -/* - * We can use mkstemp(). - */ - -int -__archive_mktemp(const char *tmpdir) -{ - struct archive_string temp_name; - int fd = -1; - - archive_string_init(&temp_name); - if (tmpdir == NULL) { - if (get_tempdir(&temp_name) != ARCHIVE_OK) - goto exit_tmpfile; - } else { - archive_strcpy(&temp_name, tmpdir); - if (temp_name.s[temp_name.length-1] != '/') - archive_strappend_char(&temp_name, '/'); - } -#ifdef O_TMPFILE - fd = open(temp_name.s, O_RDWR|O_CLOEXEC|O_TMPFILE|O_EXCL, 0600); - if(fd >= 0) - goto exit_tmpfile; -#endif - archive_strcat(&temp_name, "libarchive_XXXXXX"); - fd = mkstemp(temp_name.s); - if (fd < 0) - goto exit_tmpfile; - __archive_ensure_cloexec_flag(fd); - unlink(temp_name.s); -exit_tmpfile: - archive_string_free(&temp_name); - return (fd); -} - -int -__archive_mkstemp(char *template) -{ - int fd = -1; - fd = mkstemp(template); - if (fd >= 0) - __archive_ensure_cloexec_flag(fd); - return (fd); -} - -#else /* !HAVE_MKSTEMP */ - -/* - * We use a private routine. - */ - -static int -__archive_mktempx(const char *tmpdir, char *template) -{ - static const char num[] = { - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', - 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', - 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', - 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', - 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', - 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', - 'u', 'v', 'w', 'x', 'y', 'z' - }; - struct archive_string temp_name; - struct stat st; - int fd; - char *tp, *ep; - - fd = -1; - if (template == NULL) { - archive_string_init(&temp_name); - if (tmpdir == NULL) { - if (get_tempdir(&temp_name) != ARCHIVE_OK) - goto exit_tmpfile; - } else - archive_strcpy(&temp_name, tmpdir); - if (temp_name.s[temp_name.length-1] == '/') { - temp_name.s[temp_name.length-1] = '\0'; - temp_name.length --; - } - if (la_stat(temp_name.s, &st) < 0) - goto exit_tmpfile; - if (!S_ISDIR(st.st_mode)) { - errno = ENOTDIR; - goto exit_tmpfile; - } - archive_strcat(&temp_name, "/libarchive_"); - tp = temp_name.s + archive_strlen(&temp_name); - archive_strcat(&temp_name, "XXXXXXXXXX"); - ep = temp_name.s + archive_strlen(&temp_name); - template = temp_name.s; - } else { - tp = strchr(template, 'X'); - if (tp == NULL) /* No X, programming error */ - abort(); - for (ep = tp; *ep == 'X'; ep++) - continue; - if (*ep) /* X followed by non X, programming error */ - abort(); - } - - do { - char *p; - - p = tp; - archive_random(p, ep - p); - while (p < ep) { - int d = *((unsigned char *)p) % sizeof(num); - *p++ = num[d]; - } - fd = open(template, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC, - 0600); - } while (fd < 0 && errno == EEXIST); - if (fd < 0) - goto exit_tmpfile; - __archive_ensure_cloexec_flag(fd); - if (template == temp_name.s) - unlink(temp_name.s); -exit_tmpfile: - if (template == temp_name.s) - archive_string_free(&temp_name); - return (fd); -} - -int -__archive_mktemp(const char *tmpdir) -{ - return __archive_mktempx(tmpdir, NULL); -} - -int -__archive_mkstemp(char *template) -{ - return __archive_mktempx(NULL, template); -} - -#endif /* !HAVE_MKSTEMP */ -#endif /* !_WIN32 || __CYGWIN__ */ - -/* - * Set FD_CLOEXEC flag to a file descriptor if it is not set. - * We have to set the flag if the platform does not provide O_CLOEXEC - * or F_DUPFD_CLOEXEC flags. - * - * Note: This function is absolutely called after creating a new file - * descriptor even if the platform seemingly provides O_CLOEXEC or - * F_DUPFD_CLOEXEC macros because it is possible that the platform - * merely declares those macros, especially Linux 2.6.18 - 2.6.24 do it. - */ -void -__archive_ensure_cloexec_flag(int fd) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - (void)fd; /* UNUSED */ -#else - int flags; - - if (fd >= 0) { - flags = fcntl(fd, F_GETFD); - if (flags != -1 && (flags & FD_CLOEXEC) == 0) - fcntl(fd, F_SETFD, flags | FD_CLOEXEC); - } -#endif -} - -/* - * Utility function to sort a group of strings using quicksort. - */ -static int -archive_utility_string_sort_helper(char **strings, unsigned int n) -{ - unsigned int i, lesser_count, greater_count; - char **lesser, **greater, **tmp, *pivot; - int retval1, retval2; - - /* A list of 0 or 1 elements is already sorted */ - if (n <= 1) - return (ARCHIVE_OK); - - lesser_count = greater_count = 0; - lesser = greater = NULL; - pivot = strings[0]; - for (i = 1; i < n; i++) - { - if (strcmp(strings[i], pivot) < 0) - { - lesser_count++; - tmp = (char **)realloc(lesser, - lesser_count * sizeof(char *)); - if (!tmp) { - free(greater); - free(lesser); - return (ARCHIVE_FATAL); - } - lesser = tmp; - lesser[lesser_count - 1] = strings[i]; - } - else - { - greater_count++; - tmp = (char **)realloc(greater, - greater_count * sizeof(char *)); - if (!tmp) { - free(greater); - free(lesser); - return (ARCHIVE_FATAL); - } - greater = tmp; - greater[greater_count - 1] = strings[i]; - } - } - - /* quicksort(lesser) */ - retval1 = archive_utility_string_sort_helper(lesser, lesser_count); - for (i = 0; i < lesser_count; i++) - strings[i] = lesser[i]; - free(lesser); - - /* pivot */ - strings[lesser_count] = pivot; - - /* quicksort(greater) */ - retval2 = archive_utility_string_sort_helper(greater, greater_count); - for (i = 0; i < greater_count; i++) - strings[lesser_count + 1 + i] = greater[i]; - free(greater); - - return (retval1 < retval2) ? retval1 : retval2; -} - -int -archive_utility_string_sort(char **strings) -{ - unsigned int size = 0; - while (strings[size] != NULL) - size++; - return archive_utility_string_sort_helper(strings, size); -} diff --git a/thirdparty/libarchive/libarchive/archive_version_details.c b/thirdparty/libarchive/libarchive/archive_version_details.c deleted file mode 100644 index bfb20eab2..000000000 --- a/thirdparty/libarchive/libarchive/archive_version_details.c +++ /dev/null @@ -1,151 +0,0 @@ -/*- - * Copyright (c) 2009-2012,2014 Michihiro NAKAJIMA - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:14Z kientzle $"); - -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_ZLIB_H -#include -#endif -#ifdef HAVE_LZMA_H -#include -#endif -#ifdef HAVE_BZLIB_H -#include -#endif -#ifdef HAVE_LZ4_H -#include -#endif -#ifdef HAVE_ZSTD_H -#include -#endif - -#include "archive.h" -#include "archive_private.h" -#include "archive_string.h" - -const char * -archive_version_details(void) -{ - static struct archive_string str; - static int init = 0; - const char *zlib = archive_zlib_version(); - const char *liblzma = archive_liblzma_version(); - const char *bzlib = archive_bzlib_version(); - const char *liblz4 = archive_liblz4_version(); - const char *libzstd = archive_libzstd_version(); - - if (!init) { - archive_string_init(&str); - - archive_strcat(&str, ARCHIVE_VERSION_STRING); - if (zlib != NULL) { - archive_strcat(&str, " zlib/"); - archive_strcat(&str, zlib); - } - if (liblzma) { - archive_strcat(&str, " liblzma/"); - archive_strcat(&str, liblzma); - } - if (bzlib) { - const char *p = bzlib; - const char *sep = strchr(p, ','); - if (sep == NULL) - sep = p + strlen(p); - archive_strcat(&str, " bz2lib/"); - archive_strncat(&str, p, sep - p); - } - if (liblz4) { - archive_strcat(&str, " liblz4/"); - archive_strcat(&str, liblz4); - } - if (libzstd) { - archive_strcat(&str, " libzstd/"); - archive_strcat(&str, libzstd); - } - } - return str.s; -} - -const char * -archive_zlib_version(void) -{ -#ifdef HAVE_ZLIB_H - return ZLIB_VERSION; -#else - return NULL; -#endif -} - -const char * -archive_liblzma_version(void) -{ -#ifdef HAVE_LZMA_H - return LZMA_VERSION_STRING; -#else - return NULL; -#endif -} - -const char * -archive_bzlib_version(void) -{ -#ifdef HAVE_BZLIB_H - return BZ2_bzlibVersion(); -#else - return NULL; -#endif -} - -const char * -archive_liblz4_version(void) -{ -#if defined(HAVE_LZ4_H) && defined(HAVE_LIBLZ4) -#define str(s) #s -#define NUMBER(x) str(x) - return NUMBER(LZ4_VERSION_MAJOR) "." NUMBER(LZ4_VERSION_MINOR) "." NUMBER(LZ4_VERSION_RELEASE); -#undef NUMBER -#undef str -#else - return NULL; -#endif -} - -const char * -archive_libzstd_version(void) -{ -#if HAVE_ZSTD_H && HAVE_LIBZSTD - return ZSTD_VERSION_STRING; -#else - return NULL; -#endif -} diff --git a/thirdparty/libarchive/libarchive/archive_virtual.c b/thirdparty/libarchive/libarchive/archive_virtual.c deleted file mode 100644 index f509ee5c6..000000000 --- a/thirdparty/libarchive/libarchive/archive_virtual.c +++ /dev/null @@ -1,163 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_virtual.c 201098 2009-12-28 02:58:14Z kientzle $"); - -#include "archive.h" -#include "archive_entry.h" -#include "archive_private.h" - -int -archive_filter_code(struct archive *a, int n) -{ - return ((a->vtable->archive_filter_code)(a, n)); -} - -int -archive_filter_count(struct archive *a) -{ - return ((a->vtable->archive_filter_count)(a)); -} - -const char * -archive_filter_name(struct archive *a, int n) -{ - return ((a->vtable->archive_filter_name)(a, n)); -} - -la_int64_t -archive_filter_bytes(struct archive *a, int n) -{ - return ((a->vtable->archive_filter_bytes)(a, n)); -} - -int -archive_free(struct archive *a) -{ - if (a == NULL) - return (ARCHIVE_OK); - return ((a->vtable->archive_free)(a)); -} - -int -archive_write_close(struct archive *a) -{ - return ((a->vtable->archive_close)(a)); -} - -int -archive_read_close(struct archive *a) -{ - return ((a->vtable->archive_close)(a)); -} - -int -archive_write_fail(struct archive *a) -{ - a->state = ARCHIVE_STATE_FATAL; - return a->state; -} - -int -archive_write_free(struct archive *a) -{ - return archive_free(a); -} - -#if ARCHIVE_VERSION_NUMBER < 4000000 -/* For backwards compatibility; will be removed with libarchive 4.0. */ -int -archive_write_finish(struct archive *a) -{ - return archive_write_free(a); -} -#endif - -int -archive_read_free(struct archive *a) -{ - return archive_free(a); -} - -#if ARCHIVE_VERSION_NUMBER < 4000000 -/* For backwards compatibility; will be removed with libarchive 4.0. */ -int -archive_read_finish(struct archive *a) -{ - return archive_read_free(a); -} -#endif - -int -archive_write_header(struct archive *a, struct archive_entry *entry) -{ - ++a->file_count; - return ((a->vtable->archive_write_header)(a, entry)); -} - -int -archive_write_finish_entry(struct archive *a) -{ - return ((a->vtable->archive_write_finish_entry)(a)); -} - -la_ssize_t -archive_write_data(struct archive *a, const void *buff, size_t s) -{ - return ((a->vtable->archive_write_data)(a, buff, s)); -} - -la_ssize_t -archive_write_data_block(struct archive *a, const void *buff, size_t s, - la_int64_t o) -{ - if (a->vtable->archive_write_data_block == NULL) { - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "archive_write_data_block not supported"); - a->state = ARCHIVE_STATE_FATAL; - return (ARCHIVE_FATAL); - } - return ((a->vtable->archive_write_data_block)(a, buff, s, o)); -} - -int -archive_read_next_header(struct archive *a, struct archive_entry **entry) -{ - return ((a->vtable->archive_read_next_header)(a, entry)); -} - -int -archive_read_next_header2(struct archive *a, struct archive_entry *entry) -{ - return ((a->vtable->archive_read_next_header2)(a, entry)); -} - -int -archive_read_data_block(struct archive *a, - const void **buff, size_t *s, la_int64_t *o) -{ - return ((a->vtable->archive_read_data_block)(a, buff, s, o)); -} diff --git a/thirdparty/libarchive/libarchive/archive_windows.c b/thirdparty/libarchive/libarchive/archive_windows.c deleted file mode 100644 index ebc5eefb8..000000000 --- a/thirdparty/libarchive/libarchive/archive_windows.c +++ /dev/null @@ -1,938 +0,0 @@ -/*- - * Copyright (c) 2009-2011 Michihiro NAKAJIMA - * Copyright (c) 2003-2007 Kees Zeelenberg - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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$ - */ - -/* - * A set of compatibility glue for building libarchive on Windows platforms. - * - * Originally created as "libarchive-nonposix.c" by Kees Zeelenberg - * for the GnuWin32 project, trimmed significantly by Tim Kientzle. - * - * Much of the original file was unnecessary for libarchive, because - * many of the features it emulated were not strictly necessary for - * libarchive. I hope for this to shrink further as libarchive - * internals are gradually reworked to sit more naturally on both - * POSIX and Windows. Any ideas for this are greatly appreciated. - * - * The biggest remaining issue is the dev/ino emulation; libarchive - * has a couple of public APIs that rely on dev/ino uniquely - * identifying a file. This doesn't match well with Windows. I'm - * considering alternative APIs. - */ - -#if defined(_WIN32) && !defined(__CYGWIN__) - -#include "archive_platform.h" -#include "archive_private.h" -#include "archive_entry.h" -#include -#include -#include -#ifdef HAVE_SYS_UTIME_H -#include -#endif -#include -#include -#include -#include -#include -#include -#include - -#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000) - -#if defined(__LA_LSEEK_NEEDED) -static BOOL SetFilePointerEx_perso(HANDLE hFile, - LARGE_INTEGER liDistanceToMove, - PLARGE_INTEGER lpNewFilePointer, - DWORD dwMoveMethod) -{ - LARGE_INTEGER li; - li.QuadPart = liDistanceToMove.QuadPart; - li.LowPart = SetFilePointer( - hFile, li.LowPart, &li.HighPart, dwMoveMethod); - if(lpNewFilePointer) { - lpNewFilePointer->QuadPart = li.QuadPart; - } - return li.LowPart != -1 || GetLastError() == NO_ERROR; -} -#endif - -struct ustat { - int64_t st_atime; - uint32_t st_atime_nsec; - int64_t st_ctime; - uint32_t st_ctime_nsec; - int64_t st_mtime; - uint32_t st_mtime_nsec; - gid_t st_gid; - /* 64bits ino */ - int64_t st_ino; - mode_t st_mode; - uint32_t st_nlink; - uint64_t st_size; - uid_t st_uid; - dev_t st_dev; - dev_t st_rdev; -}; - -/* Transform 64-bits ino into 32-bits by hashing. - * You do not forget that really unique number size is 64-bits. - */ -#define INOSIZE (8*sizeof(ino_t)) /* 32 */ -static __inline ino_t -getino(struct ustat *ub) -{ - ULARGE_INTEGER ino64; - ino64.QuadPart = ub->st_ino; - /* I don't know this hashing is correct way */ - return ((ino_t)(ino64.LowPart ^ (ino64.LowPart >> INOSIZE))); -} - -/* - * Prepend "\\?\" to the path name and convert it to unicode to permit - * an extended-length path for a maximum total path length of 32767 - * characters. - * see also http://msdn.microsoft.com/en-us/library/aa365247.aspx - */ -wchar_t * -__la_win_permissive_name(const char *name) -{ - wchar_t *wn; - wchar_t *ws; - size_t ll; - - ll = strlen(name); - wn = malloc((ll + 1) * sizeof(wchar_t)); - if (wn == NULL) - return (NULL); - ll = mbstowcs(wn, name, ll); - if (ll == (size_t)-1) { - free(wn); - return (NULL); - } - wn[ll] = L'\0'; - ws = __la_win_permissive_name_w(wn); - free(wn); - return (ws); -} - -wchar_t * -__la_win_permissive_name_w(const wchar_t *wname) -{ - wchar_t *wn, *wnp; - wchar_t *ws, *wsp; - DWORD l, len, slen; - int unc; - - /* Get a full-pathname. */ - l = GetFullPathNameW(wname, 0, NULL, NULL); - if (l == 0) - return (NULL); - /* NOTE: GetFullPathNameW has a bug that if the length of the file - * name is just 1 then it returns incomplete buffer size. Thus, we - * have to add three to the size to allocate a sufficient buffer - * size for the full-pathname of the file name. */ - l += 3; - wnp = malloc(l * sizeof(wchar_t)); - if (wnp == NULL) - return (NULL); - len = GetFullPathNameW(wname, l, wnp, NULL); - wn = wnp; - - if (wnp[0] == L'\\' && wnp[1] == L'\\' && - wnp[2] == L'?' && wnp[3] == L'\\') - /* We have already a permissive name. */ - return (wn); - - if (wnp[0] == L'\\' && wnp[1] == L'\\' && - wnp[2] == L'.' && wnp[3] == L'\\') { - /* This is a device name */ - if (((wnp[4] >= L'a' && wnp[4] <= L'z') || - (wnp[4] >= L'A' && wnp[4] <= L'Z')) && - wnp[5] == L':' && wnp[6] == L'\\') - wnp[2] = L'?';/* Not device name. */ - return (wn); - } - - unc = 0; - if (wnp[0] == L'\\' && wnp[1] == L'\\' && wnp[2] != L'\\') { - wchar_t *p = &wnp[2]; - - /* Skip server-name letters. */ - while (*p != L'\\' && *p != L'\0') - ++p; - if (*p == L'\\') { - wchar_t *rp = ++p; - /* Skip share-name letters. */ - while (*p != L'\\' && *p != L'\0') - ++p; - if (*p == L'\\' && p != rp) { - /* Now, match patterns such as - * "\\server-name\share-name\" */ - wnp += 2; - len -= 2; - unc = 1; - } - } - } - - slen = 4 + (unc * 4) + len + 1; - ws = wsp = malloc(slen * sizeof(wchar_t)); - if (ws == NULL) { - free(wn); - return (NULL); - } - /* prepend "\\?\" */ - wcsncpy(wsp, L"\\\\?\\", 4); - wsp += 4; - slen -= 4; - if (unc) { - /* append "UNC\" ---> "\\?\UNC\" */ - wcsncpy(wsp, L"UNC\\", 4); - wsp += 4; - slen -= 4; - } - wcsncpy(wsp, wnp, slen); - wsp[slen - 1] = L'\0'; /* Ensure null termination. */ - free(wn); - return (ws); -} - -/* - * Create a file handle. - * This can exceed MAX_PATH limitation. - */ -static HANDLE -la_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode, - LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, - DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) -{ - wchar_t *wpath; - HANDLE handle; -# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */ - CREATEFILE2_EXTENDED_PARAMETERS createExParams; -#endif - -#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP) - handle = CreateFileA(path, dwDesiredAccess, dwShareMode, - lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, - hTemplateFile); - if (handle != INVALID_HANDLE_VALUE) - return (handle); - if (GetLastError() != ERROR_PATH_NOT_FOUND) - return (handle); -#endif - wpath = __la_win_permissive_name(path); - if (wpath == NULL) - return INVALID_HANDLE_VALUE; -# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */ - ZeroMemory(&createExParams, sizeof(createExParams)); - createExParams.dwSize = sizeof(createExParams); - createExParams.dwFileAttributes = dwFlagsAndAttributes & 0xFFFF; - createExParams.dwFileFlags = dwFlagsAndAttributes & 0xFFF00000; - createExParams.dwSecurityQosFlags = dwFlagsAndAttributes & 0x000F00000; - createExParams.lpSecurityAttributes = lpSecurityAttributes; - createExParams.hTemplateFile = hTemplateFile; - handle = CreateFile2(wpath, dwDesiredAccess, dwShareMode, - dwCreationDisposition, &createExParams); -#else /* !WINAPI_PARTITION_DESKTOP */ - handle = CreateFileW(wpath, dwDesiredAccess, dwShareMode, - lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, - hTemplateFile); -#endif /* !WINAPI_PARTITION_DESKTOP */ - free(wpath); - return (handle); -} - -#if defined(__LA_LSEEK_NEEDED) -__int64 -__la_lseek(int fd, __int64 offset, int whence) -{ - LARGE_INTEGER distance; - LARGE_INTEGER newpointer; - HANDLE handle; - - if (fd < 0) { - errno = EBADF; - return (-1); - } - handle = (HANDLE)_get_osfhandle(fd); - if (GetFileType(handle) != FILE_TYPE_DISK) { - errno = EBADF; - return (-1); - } - distance.QuadPart = offset; - if (!SetFilePointerEx_perso(handle, distance, &newpointer, whence)) { - DWORD lasterr; - - lasterr = GetLastError(); - if (lasterr == ERROR_BROKEN_PIPE) - return (0); - if (lasterr == ERROR_ACCESS_DENIED) - errno = EBADF; - else - la_dosmaperr(lasterr); - return (-1); - } - return (newpointer.QuadPart); -} -#endif - -/* This can exceed MAX_PATH limitation. */ -int -__la_open(const char *path, int flags, ...) -{ - va_list ap; - wchar_t *ws; - int r, pmode; - DWORD attr; - - va_start(ap, flags); - pmode = va_arg(ap, int); - va_end(ap); - ws = NULL; - if ((flags & ~O_BINARY) == O_RDONLY) { - /* - * When we open a directory, _open function returns - * "Permission denied" error. - */ - attr = GetFileAttributesA(path); -#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP) - if (attr == (DWORD)-1 && GetLastError() == ERROR_PATH_NOT_FOUND) -#endif - { - ws = __la_win_permissive_name(path); - if (ws == NULL) { - errno = EINVAL; - return (-1); - } - attr = GetFileAttributesW(ws); - } - if (attr == (DWORD)-1) { - la_dosmaperr(GetLastError()); - free(ws); - return (-1); - } - if (attr & FILE_ATTRIBUTE_DIRECTORY) { - HANDLE handle; -#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP) - if (ws != NULL) - handle = CreateFileW(ws, 0, 0, NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | - FILE_ATTRIBUTE_READONLY, - NULL); - else - handle = CreateFileA(path, 0, 0, NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | - FILE_ATTRIBUTE_READONLY, - NULL); -#else /* !WINAPI_PARTITION_DESKTOP */ - CREATEFILE2_EXTENDED_PARAMETERS createExParams; - ZeroMemory(&createExParams, sizeof(createExParams)); - createExParams.dwSize = sizeof(createExParams); - createExParams.dwFileAttributes = FILE_ATTRIBUTE_READONLY; - createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS; - handle = CreateFile2(ws, 0, 0, - OPEN_EXISTING, &createExParams); -#endif /* !WINAPI_PARTITION_DESKTOP */ - free(ws); - if (handle == INVALID_HANDLE_VALUE) { - la_dosmaperr(GetLastError()); - return (-1); - } - r = _open_osfhandle((intptr_t)handle, _O_RDONLY); - return (r); - } - } - if (ws == NULL) { -#if defined(__BORLANDC__) - /* Borland has no mode argument. - TODO: Fix mode of new file. */ - r = _open(path, flags); -#else - r = _open(path, flags, pmode); -#endif - if (r < 0 && errno == EACCES && (flags & O_CREAT) != 0) { - /* Simulate other POSIX system action to pass our test suite. */ - attr = GetFileAttributesA(path); - if (attr == (DWORD)-1) - la_dosmaperr(GetLastError()); - else if (attr & FILE_ATTRIBUTE_DIRECTORY) - errno = EISDIR; - else - errno = EACCES; - return (-1); - } - if (r >= 0 || errno != ENOENT) - return (r); - ws = __la_win_permissive_name(path); - if (ws == NULL) { - errno = EINVAL; - return (-1); - } - } - r = _wopen(ws, flags, pmode); - if (r < 0 && errno == EACCES && (flags & O_CREAT) != 0) { - /* Simulate other POSIX system action to pass our test suite. */ - attr = GetFileAttributesW(ws); - if (attr == (DWORD)-1) - la_dosmaperr(GetLastError()); - else if (attr & FILE_ATTRIBUTE_DIRECTORY) - errno = EISDIR; - else - errno = EACCES; - } - free(ws); - return (r); -} - -ssize_t -__la_read(int fd, void *buf, size_t nbytes) -{ - HANDLE handle; - DWORD bytes_read, lasterr; - int r; - -#ifdef _WIN64 - if (nbytes > UINT32_MAX) - nbytes = UINT32_MAX; -#endif - if (fd < 0) { - errno = EBADF; - return (-1); - } - /* Do not pass 0 to third parameter of ReadFile(), read bytes. - * This will not return to application side. */ - if (nbytes == 0) - return (0); - handle = (HANDLE)_get_osfhandle(fd); - r = ReadFile(handle, buf, (uint32_t)nbytes, - &bytes_read, NULL); - if (r == 0) { - lasterr = GetLastError(); - if (lasterr == ERROR_NO_DATA) { - errno = EAGAIN; - return (-1); - } - if (lasterr == ERROR_BROKEN_PIPE) - return (0); - if (lasterr == ERROR_ACCESS_DENIED) - errno = EBADF; - else - la_dosmaperr(lasterr); - return (-1); - } - return ((ssize_t)bytes_read); -} - -/* Convert Windows FILETIME to UTC */ -__inline static void -fileTimeToUTC(const FILETIME *filetime, time_t *t, long *ns) -{ - ULARGE_INTEGER utc; - - utc.HighPart = filetime->dwHighDateTime; - utc.LowPart = filetime->dwLowDateTime; - if (utc.QuadPart >= EPOC_TIME) { - utc.QuadPart -= EPOC_TIME; - *t = (time_t)(utc.QuadPart / 10000000); /* milli seconds base */ - *ns = (long)(utc.QuadPart % 10000000) * 100;/* nano seconds base */ - } else { - *t = 0; - *ns = 0; - } -} - -/* Stat by handle - * Windows' stat() does not accept the path added "\\?\" especially "?" - * character. - * It means we cannot access the long name path longer than MAX_PATH. - * So I've implemented a function similar to Windows' stat() to access the - * long name path. - * And I've added some feature. - * 1. set st_ino by nFileIndexHigh and nFileIndexLow of - * BY_HANDLE_FILE_INFORMATION. - * 2. set st_nlink by nNumberOfLinks of BY_HANDLE_FILE_INFORMATION. - * 3. set st_dev by dwVolumeSerialNumber by BY_HANDLE_FILE_INFORMATION. - */ -static int -__hstat(HANDLE handle, struct ustat *st) -{ - BY_HANDLE_FILE_INFORMATION info; - ULARGE_INTEGER ino64; - DWORD ftype; - mode_t mode; - time_t t; - long ns; - - switch (ftype = GetFileType(handle)) { - case FILE_TYPE_UNKNOWN: - errno = EBADF; - return (-1); - case FILE_TYPE_CHAR: - case FILE_TYPE_PIPE: - if (ftype == FILE_TYPE_CHAR) { - st->st_mode = S_IFCHR; - st->st_size = 0; - } else { - DWORD avail; - - st->st_mode = S_IFIFO; - if (PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL)) - st->st_size = avail; - else - st->st_size = 0; - } - st->st_atime = 0; - st->st_atime_nsec = 0; - st->st_mtime = 0; - st->st_mtime_nsec = 0; - st->st_ctime = 0; - st->st_ctime_nsec = 0; - st->st_ino = 0; - st->st_nlink = 1; - st->st_uid = 0; - st->st_gid = 0; - st->st_rdev = 0; - st->st_dev = 0; - return (0); - case FILE_TYPE_DISK: - break; - default: - /* This ftype is undocumented type. */ - la_dosmaperr(GetLastError()); - return (-1); - } - - ZeroMemory(&info, sizeof(info)); - if (!GetFileInformationByHandle (handle, &info)) { - la_dosmaperr(GetLastError()); - return (-1); - } - - mode = S_IRUSR | S_IRGRP | S_IROTH; - if ((info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0) - mode |= S_IWUSR | S_IWGRP | S_IWOTH; - if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH; - else - mode |= S_IFREG; - st->st_mode = mode; - - fileTimeToUTC(&info.ftLastAccessTime, &t, &ns); - st->st_atime = t; - st->st_atime_nsec = ns; - fileTimeToUTC(&info.ftLastWriteTime, &t, &ns); - st->st_mtime = t; - st->st_mtime_nsec = ns; - fileTimeToUTC(&info.ftCreationTime, &t, &ns); - st->st_ctime = t; - st->st_ctime_nsec = ns; - st->st_size = - ((int64_t)(info.nFileSizeHigh) * ((int64_t)MAXDWORD + 1)) - + (int64_t)(info.nFileSizeLow); -#ifdef SIMULATE_WIN_STAT - st->st_ino = 0; - st->st_nlink = 1; - st->st_dev = 0; -#else - /* Getting FileIndex as i-node. We should remove a sequence which - * is high-16-bits of nFileIndexHigh. */ - ino64.HighPart = info.nFileIndexHigh & 0x0000FFFFUL; - ino64.LowPart = info.nFileIndexLow; - st->st_ino = ino64.QuadPart; - st->st_nlink = info.nNumberOfLinks; - if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - ++st->st_nlink;/* Add parent directory. */ - st->st_dev = info.dwVolumeSerialNumber; -#endif - st->st_uid = 0; - st->st_gid = 0; - st->st_rdev = 0; - return (0); -} - -static void -copy_stat(struct stat *st, struct ustat *us) -{ - st->st_atime = us->st_atime; - st->st_ctime = us->st_ctime; - st->st_mtime = us->st_mtime; - st->st_gid = us->st_gid; - st->st_ino = getino(us); - st->st_mode = us->st_mode; - st->st_nlink = us->st_nlink; - st->st_size = (off_t)us->st_size; - st->st_uid = us->st_uid; - st->st_dev = us->st_dev; - st->st_rdev = us->st_rdev; -} - -/* - * TODO: Remove a use of __la_fstat and __la_stat. - * We should use GetFileInformationByHandle in place - * where We still use the *stat functions. - */ -int -__la_fstat(int fd, struct stat *st) -{ - struct ustat u; - int ret; - - if (fd < 0) { - errno = EBADF; - return (-1); - } - ret = __hstat((HANDLE)_get_osfhandle(fd), &u); - if (ret >= 0) { - copy_stat(st, &u); - if (u.st_mode & (S_IFCHR | S_IFIFO)) { - st->st_dev = fd; - st->st_rdev = fd; - } - } - return (ret); -} - -/* This can exceed MAX_PATH limitation. */ -int -__la_stat(const char *path, struct stat *st) -{ - HANDLE handle; - struct ustat u; - int ret; - - handle = la_CreateFile(path, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, - NULL); - if (handle == INVALID_HANDLE_VALUE) { - la_dosmaperr(GetLastError()); - return (-1); - } - ret = __hstat(handle, &u); - CloseHandle(handle); - if (ret >= 0) { - char *p; - - copy_stat(st, &u); - p = strrchr(path, '.'); - if (p != NULL && strlen(p) == 4) { - char exttype[4]; - - ++ p; - exttype[0] = toupper(*p++); - exttype[1] = toupper(*p++); - exttype[2] = toupper(*p++); - exttype[3] = '\0'; - if (!strcmp(exttype, "EXE") || !strcmp(exttype, "CMD") || - !strcmp(exttype, "BAT") || !strcmp(exttype, "COM")) - st->st_mode |= S_IXUSR | S_IXGRP | S_IXOTH; - } - } - return (ret); -} - -/* - * This waitpid is limited implementation. - */ -pid_t -__la_waitpid(HANDLE child, int *status, int option) -{ - DWORD cs; - - (void)option;/* UNUSED */ - do { - if (GetExitCodeProcess(child, &cs) == 0) { - CloseHandle(child); - la_dosmaperr(GetLastError()); - *status = 0; - return (-1); - } - } while (cs == STILL_ACTIVE); - - *status = (int)(cs & 0xff); - return (0); -} - -ssize_t -__la_write(int fd, const void *buf, size_t nbytes) -{ - DWORD bytes_written; - -#ifdef _WIN64 - if (nbytes > UINT32_MAX) - nbytes = UINT32_MAX; -#endif - if (fd < 0) { - errno = EBADF; - return (-1); - } - if (!WriteFile((HANDLE)_get_osfhandle(fd), buf, (uint32_t)nbytes, - &bytes_written, NULL)) { - DWORD lasterr; - - lasterr = GetLastError(); - if (lasterr == ERROR_ACCESS_DENIED) - errno = EBADF; - else - la_dosmaperr(lasterr); - return (-1); - } - return (bytes_written); -} - -/* - * Replace the Windows path separator '\' with '/'. - */ -static int -replace_pathseparator(struct archive_wstring *ws, const wchar_t *wp) -{ - wchar_t *w; - size_t path_length; - - if (wp == NULL) - return(0); - if (wcschr(wp, L'\\') == NULL) - return(0); - path_length = wcslen(wp); - if (archive_wstring_ensure(ws, path_length) == NULL) - return(-1); - archive_wstrncpy(ws, wp, path_length); - for (w = ws->s; *w; w++) { - if (*w == L'\\') - *w = L'/'; - } - return(1); -} - -static int -fix_pathseparator(struct archive_entry *entry) -{ - struct archive_wstring ws; - const wchar_t *wp; - int ret = ARCHIVE_OK; - - archive_string_init(&ws); - wp = archive_entry_pathname_w(entry); - switch (replace_pathseparator(&ws, wp)) { - case 0: /* Not replaced. */ - break; - case 1: /* Replaced. */ - archive_entry_copy_pathname_w(entry, ws.s); - break; - default: - ret = ARCHIVE_FAILED; - } - wp = archive_entry_hardlink_w(entry); - switch (replace_pathseparator(&ws, wp)) { - case 0: /* Not replaced. */ - break; - case 1: /* Replaced. */ - archive_entry_copy_hardlink_w(entry, ws.s); - break; - default: - ret = ARCHIVE_FAILED; - } - wp = archive_entry_symlink_w(entry); - switch (replace_pathseparator(&ws, wp)) { - case 0: /* Not replaced. */ - break; - case 1: /* Replaced. */ - archive_entry_copy_symlink_w(entry, ws.s); - break; - default: - ret = ARCHIVE_FAILED; - } - archive_wstring_free(&ws); - return(ret); -} - -struct archive_entry * -__la_win_entry_in_posix_pathseparator(struct archive_entry *entry) -{ - struct archive_entry *entry_main; - const wchar_t *wp; - int has_backslash = 0; - int ret; - - wp = archive_entry_pathname_w(entry); - if (wp != NULL && wcschr(wp, L'\\') != NULL) - has_backslash = 1; - if (!has_backslash) { - wp = archive_entry_hardlink_w(entry); - if (wp != NULL && wcschr(wp, L'\\') != NULL) - has_backslash = 1; - } - if (!has_backslash) { - wp = archive_entry_symlink_w(entry); - if (wp != NULL && wcschr(wp, L'\\') != NULL) - has_backslash = 1; - } - /* - * If there is no backslash chars, return the original. - */ - if (!has_backslash) - return (entry); - - /* Copy entry so we can modify it as needed. */ - entry_main = archive_entry_clone(entry); - if (entry_main == NULL) - return (NULL); - /* Replace the Windows path-separator '\' with '/'. */ - ret = fix_pathseparator(entry_main); - if (ret < ARCHIVE_WARN) { - archive_entry_free(entry_main); - return (NULL); - } - return (entry_main); -} - - -/* - * The following function was modified from PostgreSQL sources and is - * subject to the copyright below. - */ -/*------------------------------------------------------------------------- - * - * win32error.c - * Map win32 error codes to errno values - * - * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/port/win32error.c,v 1.4 2008/01/01 19:46:00 momjian Exp $ - * - *------------------------------------------------------------------------- - */ -/* -PostgreSQL Database Management System -(formerly known as Postgres, then as Postgres95) - -Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group - -Portions Copyright (c) 1994, The Regents of the University of California - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose, without fee, and without a written agreement -is hereby granted, provided that the above copyright notice and this -paragraph and the following two paragraphs appear in all copies. - -IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR -DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING -LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS -DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO -PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -*/ - -static const struct { - DWORD winerr; - int doserr; -} doserrors[] = -{ - { ERROR_INVALID_FUNCTION, EINVAL }, - { ERROR_FILE_NOT_FOUND, ENOENT }, - { ERROR_PATH_NOT_FOUND, ENOENT }, - { ERROR_TOO_MANY_OPEN_FILES, EMFILE }, - { ERROR_ACCESS_DENIED, EACCES }, - { ERROR_INVALID_HANDLE, EBADF }, - { ERROR_ARENA_TRASHED, ENOMEM }, - { ERROR_NOT_ENOUGH_MEMORY, ENOMEM }, - { ERROR_INVALID_BLOCK, ENOMEM }, - { ERROR_BAD_ENVIRONMENT, E2BIG }, - { ERROR_BAD_FORMAT, ENOEXEC }, - { ERROR_INVALID_ACCESS, EINVAL }, - { ERROR_INVALID_DATA, EINVAL }, - { ERROR_INVALID_DRIVE, ENOENT }, - { ERROR_CURRENT_DIRECTORY, EACCES }, - { ERROR_NOT_SAME_DEVICE, EXDEV }, - { ERROR_NO_MORE_FILES, ENOENT }, - { ERROR_LOCK_VIOLATION, EACCES }, - { ERROR_SHARING_VIOLATION, EACCES }, - { ERROR_BAD_NETPATH, ENOENT }, - { ERROR_NETWORK_ACCESS_DENIED, EACCES }, - { ERROR_BAD_NET_NAME, ENOENT }, - { ERROR_FILE_EXISTS, EEXIST }, - { ERROR_CANNOT_MAKE, EACCES }, - { ERROR_FAIL_I24, EACCES }, - { ERROR_INVALID_PARAMETER, EINVAL }, - { ERROR_NO_PROC_SLOTS, EAGAIN }, - { ERROR_DRIVE_LOCKED, EACCES }, - { ERROR_BROKEN_PIPE, EPIPE }, - { ERROR_DISK_FULL, ENOSPC }, - { ERROR_INVALID_TARGET_HANDLE, EBADF }, - { ERROR_INVALID_HANDLE, EINVAL }, - { ERROR_WAIT_NO_CHILDREN, ECHILD }, - { ERROR_CHILD_NOT_COMPLETE, ECHILD }, - { ERROR_DIRECT_ACCESS_HANDLE, EBADF }, - { ERROR_NEGATIVE_SEEK, EINVAL }, - { ERROR_SEEK_ON_DEVICE, EACCES }, - { ERROR_DIR_NOT_EMPTY, ENOTEMPTY }, - { ERROR_NOT_LOCKED, EACCES }, - { ERROR_BAD_PATHNAME, ENOENT }, - { ERROR_MAX_THRDS_REACHED, EAGAIN }, - { ERROR_LOCK_FAILED, EACCES }, - { ERROR_ALREADY_EXISTS, EEXIST }, - { ERROR_FILENAME_EXCED_RANGE, ENOENT }, - { ERROR_NESTING_NOT_ALLOWED, EAGAIN }, - { ERROR_NOT_ENOUGH_QUOTA, ENOMEM } -}; - -void -__la_dosmaperr(unsigned long e) -{ - int i; - - if (e == 0) - { - errno = 0; - return; - } - - for (i = 0; i < (int)(sizeof(doserrors)/sizeof(doserrors[0])); i++) - { - if (doserrors[i].winerr == e) - { - errno = doserrors[i].doserr; - return; - } - } - - /* fprintf(stderr, "unrecognized win32 error code: %lu", e); */ - errno = EINVAL; - return; -} - -#endif /* _WIN32 && !__CYGWIN__ */ diff --git a/thirdparty/libarchive/libarchive/archive_windows.h b/thirdparty/libarchive/libarchive/archive_windows.h deleted file mode 100644 index 47b7cb8e3..000000000 --- a/thirdparty/libarchive/libarchive/archive_windows.h +++ /dev/null @@ -1,315 +0,0 @@ -/*- - * Copyright (c) 2009-2011 Michihiro NAKAJIMA - * Copyright (c) 2003-2006 Tim Kientzle - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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$ - */ - -/* - * TODO: A lot of stuff in here isn't actually used by libarchive and - * can be trimmed out. Note that this file is used by libarchive and - * libarchive_test but nowhere else. (But note that it gets compiled - * with many different Windows environments, including MinGW, Visual - * Studio, and Cygwin. Significant changes should be tested in all three.) - */ - -/* - * TODO: Don't use off_t in here. Use __int64 instead. Note that - * Visual Studio and the Windows SDK define off_t as 32 bits; Win32's - * more modern file handling APIs all use __int64 instead of off_t. - */ - -#ifndef LIBARCHIVE_ARCHIVE_WINDOWS_H_INCLUDED -#define LIBARCHIVE_ARCHIVE_WINDOWS_H_INCLUDED - -#ifndef __LIBARCHIVE_BUILD -#error This header is only to be used internally to libarchive. -#endif - -/* Start of configuration for native Win32 */ -#ifndef MINGW_HAS_SECURE_API -#define MINGW_HAS_SECURE_API 1 -#endif - -#include -#define set_errno(val) ((errno)=val) -#include -#include //brings in NULL -#if defined(HAVE_STDINT_H) -#include -#endif -#include -#include -#include -#include -#include -#if defined(__MINGW32__) && defined(HAVE_UNISTD_H) -/* Prevent build error from a type mismatch of ftruncate(). - * This unistd.h defines it as ftruncate(int, off_t). */ -#include -#endif -#define NOCRYPT -#include -//#define EFTYPE 7 - -#if defined(__BORLANDC__) -#pragma warn -8068 /* Constant out of range in comparison. */ -#pragma warn -8072 /* Suspicious pointer arithmetic. */ -#endif - -#ifndef NULL -#ifdef __cplusplus -#define NULL 0 -#else -#define NULL ((void *)0) -#endif -#endif - -/* Alias the Windows _function to the POSIX equivalent. */ -#define close _close -#define fcntl(fd, cmd, flg) /* No operation. */ -#ifndef fileno -#define fileno _fileno -#endif -#ifdef fstat -#undef fstat -#endif -#define fstat __la_fstat -#if !defined(__BORLANDC__) -#ifdef lseek -#undef lseek -#endif -#define lseek _lseeki64 -#else -#define lseek __la_lseek -#define __LA_LSEEK_NEEDED -#endif -#define lstat __la_stat -#define open __la_open -#define read __la_read -#if !defined(__BORLANDC__) && !defined(__WATCOMC__) -#define setmode _setmode -#endif -#define la_stat(path,stref) __la_stat(path,stref) -#if !defined(__WATCOMC__) -#if !defined(__BORLANDC__) -#define strdup _strdup -#endif -#define tzset _tzset -#if !defined(__BORLANDC__) -#define umask _umask -#endif -#endif -#define waitpid __la_waitpid -#define write __la_write - -#if !defined(__WATCOMC__) - -#ifndef O_RDONLY -#define O_RDONLY _O_RDONLY -#define O_WRONLY _O_WRONLY -#define O_TRUNC _O_TRUNC -#define O_CREAT _O_CREAT -#define O_EXCL _O_EXCL -#define O_BINARY _O_BINARY -#endif - -#ifndef _S_IFIFO - #define _S_IFIFO 0010000 /* pipe */ -#endif -#ifndef _S_IFCHR - #define _S_IFCHR 0020000 /* character special */ -#endif -#ifndef _S_IFDIR - #define _S_IFDIR 0040000 /* directory */ -#endif -#ifndef _S_IFBLK - #define _S_IFBLK 0060000 /* block special */ -#endif -#ifndef _S_IFLNK - #define _S_IFLNK 0120000 /* symbolic link */ -#endif -#ifndef _S_IFSOCK - #define _S_IFSOCK 0140000 /* socket */ -#endif -#ifndef _S_IFREG - #define _S_IFREG 0100000 /* regular */ -#endif -#ifndef _S_IFMT - #define _S_IFMT 0170000 /* file type mask */ -#endif - -#ifndef S_IFIFO -#define S_IFIFO _S_IFIFO -#endif -//#define S_IFCHR _S_IFCHR -//#define S_IFDIR _S_IFDIR -#ifndef S_IFBLK -#define S_IFBLK _S_IFBLK -#endif -#ifndef S_IFLNK -#define S_IFLNK _S_IFLNK -#endif -#ifndef S_IFSOCK -#define S_IFSOCK _S_IFSOCK -#endif -//#define S_IFREG _S_IFREG -//#define S_IFMT _S_IFMT - -#ifndef S_ISBLK -#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) /* block special */ -#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) /* fifo or socket */ -#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) /* char special */ -#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) /* directory */ -#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) /* regular file */ -#endif -#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) /* Symbolic link */ -#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) /* Socket */ - -#define _S_ISUID 0004000 /* set user id on execution */ -#define _S_ISGID 0002000 /* set group id on execution */ -#define _S_ISVTX 0001000 /* save swapped text even after use */ - -#define S_ISUID _S_ISUID -#define S_ISGID _S_ISGID -#define S_ISVTX _S_ISVTX - -#define _S_IRWXU (_S_IREAD | _S_IWRITE | _S_IEXEC) -#define _S_IXUSR _S_IEXEC /* read permission, user */ -#define _S_IWUSR _S_IWRITE /* write permission, user */ -#define _S_IRUSR _S_IREAD /* execute/search permission, user */ -#define _S_IRWXG (_S_IRWXU >> 3) -#define _S_IXGRP (_S_IXUSR >> 3) /* read permission, group */ -#define _S_IWGRP (_S_IWUSR >> 3) /* write permission, group */ -#define _S_IRGRP (_S_IRUSR >> 3) /* execute/search permission, group */ -#define _S_IRWXO (_S_IRWXG >> 3) -#define _S_IXOTH (_S_IXGRP >> 3) /* read permission, other */ -#define _S_IWOTH (_S_IWGRP >> 3) /* write permission, other */ -#define _S_IROTH (_S_IRGRP >> 3) /* execute/search permission, other */ - -#ifndef S_IRWXU -#define S_IRWXU _S_IRWXU -#define S_IXUSR _S_IXUSR -#define S_IWUSR _S_IWUSR -#define S_IRUSR _S_IRUSR -#endif -#ifndef S_IRWXG -#define S_IRWXG _S_IRWXG -#define S_IXGRP _S_IXGRP -#define S_IWGRP _S_IWGRP -#endif -#ifndef S_IRGRP -#define S_IRGRP _S_IRGRP -#endif -#ifndef S_IRWXO -#define S_IRWXO _S_IRWXO -#define S_IXOTH _S_IXOTH -#define S_IWOTH _S_IWOTH -#define S_IROTH _S_IROTH -#endif - -#endif - -#define F_DUPFD 0 /* Duplicate file descriptor. */ -#define F_GETFD 1 /* Get file descriptor flags. */ -#define F_SETFD 2 /* Set file descriptor flags. */ -#define F_GETFL 3 /* Get file status flags. */ -#define F_SETFL 4 /* Set file status flags. */ -#define F_GETOWN 5 /* Get owner (receiver of SIGIO). */ -#define F_SETOWN 6 /* Set owner (receiver of SIGIO). */ -#define F_GETLK 7 /* Get record locking info. */ -#define F_SETLK 8 /* Set record locking info (non-blocking). */ -#define F_SETLKW 9 /* Set record locking info (blocking). */ - -/* XXX missing */ -#define F_GETLK64 7 /* Get record locking info. */ -#define F_SETLK64 8 /* Set record locking info (non-blocking). */ -#define F_SETLKW64 9 /* Set record locking info (blocking). */ - -/* File descriptor flags used with F_GETFD and F_SETFD. */ -#define FD_CLOEXEC 1 /* Close on exec. */ - -//NOT SURE IF O_NONBLOCK is OK here but at least the 0x0004 flag is not used by anything else... -#define O_NONBLOCK 0x0004 /* Non-blocking I/O. */ -//#define O_NDELAY O_NONBLOCK - -/* Symbolic constants for the access() function */ -#if !defined(F_OK) - #define R_OK 4 /* Test for read permission */ - #define W_OK 2 /* Test for write permission */ - #define X_OK 1 /* Test for execute permission */ - #define F_OK 0 /* Test for existence of file */ -#endif - - -/* Replacement POSIX function */ -extern int __la_fstat(int fd, struct stat *st); -extern int __la_lstat(const char *path, struct stat *st); -#if defined(__LA_LSEEK_NEEDED) -extern __int64 __la_lseek(int fd, __int64 offset, int whence); -#endif -extern int __la_open(const char *path, int flags, ...); -extern ssize_t __la_read(int fd, void *buf, size_t nbytes); -extern int __la_stat(const char *path, struct stat *st); -extern pid_t __la_waitpid(HANDLE child, int *status, int option); -extern ssize_t __la_write(int fd, const void *buf, size_t nbytes); - -#define _stat64i32(path, st) __la_stat(path, st) -#define _stat64(path, st) __la_stat(path, st) -/* for status returned by la_waitpid */ -#define WIFEXITED(sts) ((sts & 0x100) == 0) -#define WEXITSTATUS(sts) (sts & 0x0FF) - -extern wchar_t *__la_win_permissive_name(const char *name); -extern wchar_t *__la_win_permissive_name_w(const wchar_t *wname); -extern void __la_dosmaperr(unsigned long e); -#define la_dosmaperr(e) __la_dosmaperr(e) -extern struct archive_entry *__la_win_entry_in_posix_pathseparator( - struct archive_entry *); - -#if defined(HAVE_WCRTOMB) && defined(__BORLANDC__) -typedef int mbstate_t; -size_t wcrtomb(char *, wchar_t, mbstate_t *); -#endif - -#if defined(_MSC_VER) && _MSC_VER < 1300 -WINBASEAPI BOOL WINAPI GetVolumePathNameW( - LPCWSTR lpszFileName, - LPWSTR lpszVolumePathName, - DWORD cchBufferLength - ); -# if _WIN32_WINNT < 0x0500 /* windows.h not providing 0x500 API */ -typedef struct _FILE_ALLOCATED_RANGE_BUFFER { - LARGE_INTEGER FileOffset; - LARGE_INTEGER Length; -} FILE_ALLOCATED_RANGE_BUFFER, *PFILE_ALLOCATED_RANGE_BUFFER; -# define FSCTL_SET_SPARSE \ - CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 49, METHOD_BUFFERED, FILE_WRITE_DATA) -# define FSCTL_QUERY_ALLOCATED_RANGES \ - CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 51, METHOD_NEITHER, FILE_READ_DATA) -# endif -#endif - -#endif /* LIBARCHIVE_ARCHIVE_WINDOWS_H_INCLUDED */ diff --git a/thirdparty/libarchive/libarchive/archive_write.3 b/thirdparty/libarchive/libarchive/archive_write.3 deleted file mode 100644 index e7f7f1384..000000000 --- a/thirdparty/libarchive/libarchive/archive_write.3 +++ /dev/null @@ -1,268 +0,0 @@ -.\" Copyright (c) 2003-2011 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd February 2, 2012 -.Dt ARCHIVE_WRITE 3 -.Os -.Sh NAME -.Nm archive_write -.Nd functions for creating archives -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive.h -.Sh DESCRIPTION -These functions provide a complete API for creating streaming -archive files. -The general process is to first create the -.Tn struct archive -object, set any desired options, initialize the archive, append entries, then -close the archive and release all resources. -.\" -.Ss Create archive object -See -.Xr archive_write_new 3 . -.Pp -To write an archive, you must first obtain an initialized -.Tn struct archive -object from -.Fn archive_write_new . -.\" -.Ss Enable filters and formats, configure block size and padding -See -.Xr archive_write_filter 3 , -.Xr archive_write_format 3 -and -.Xr archive_write_blocksize 3 . -.Pp -You can then modify this object for the desired operations with the -various -.Fn archive_write_set_XXX -functions. -In particular, you will need to invoke appropriate -.Fn archive_write_add_XXX -and -.Fn archive_write_set_XXX -functions to enable the corresponding compression and format -support. -.\" -.Ss Set options -See -.Xr archive_write_set_options 3 . -.\" -.Ss Open archive -See -.Xr archive_write_open 3 . -.Pp -Once you have prepared the -.Tn struct archive -object, you call -.Fn archive_write_open -to actually open the archive and prepare it for writing. -There are several variants of this function; -the most basic expects you to provide pointers to several -functions that can provide blocks of bytes from the archive. -There are convenience forms that allow you to -specify a filename, file descriptor, -.Ft "FILE *" -object, or a block of memory from which to write the archive data. -.\" -.Ss Produce archive -See -.Xr archive_write_header 3 -and -.Xr archive_write_data 3 . -.Pp -Individual archive entries are written in a three-step -process: -You first initialize a -.Tn struct archive_entry -structure with information about the new entry. -At a minimum, you should set the pathname of the -entry and provide a -.Va struct stat -with a valid -.Va st_mode -field, which specifies the type of object and -.Va st_size -field, which specifies the size of the data portion of the object. -.\" -.Ss Release resources -See -.Xr archive_write_free 3 . -.Pp -After all entries have been written, use the -.Fn archive_write_free -function to release all resources. -.\" -.Sh EXAMPLES -The following sketch illustrates basic usage of the library. -In this example, -the callback functions are simply wrappers around the standard -.Xr open 2 , -.Xr write 2 , -and -.Xr close 2 -system calls. -.Bd -literal -offset indent -#ifdef __linux__ -#define _FILE_OFFSET_BITS 64 -#endif -#include -#include -#include -#include -#include -#include - -struct mydata { - const char *name; - int fd; -}; - -int -myopen(struct archive *a, void *client_data) -{ - struct mydata *mydata = client_data; - - mydata->fd = open(mydata->name, O_WRONLY | O_CREAT, 0644); - if (mydata->fd >= 0) - return (ARCHIVE_OK); - else - return (ARCHIVE_FATAL); -} - -la_ssize_t -mywrite(struct archive *a, void *client_data, const void *buff, size_t n) -{ - struct mydata *mydata = client_data; - - return (write(mydata->fd, buff, n)); -} - -int -myclose(struct archive *a, void *client_data) -{ - struct mydata *mydata = client_data; - - if (mydata->fd > 0) - close(mydata->fd); - return (0); -} - -void -write_archive(const char *outname, const char **filename) -{ - struct mydata *mydata = malloc(sizeof(struct mydata)); - struct archive *a; - struct archive_entry *entry; - struct stat st; - char buff[8192]; - int len; - int fd; - - a = archive_write_new(); - mydata->name = outname; - /* Set archive format and filter according to output file extension. - * If it fails, set default format. Platform depended function. - * See supported formats in archive_write_set_format_filter_by_ext.c */ - if (archive_write_set_format_filter_by_ext(a, outname) != ARCHIVE_OK) { - archive_write_add_filter_gzip(a); - archive_write_set_format_ustar(a); - } - archive_write_open(a, mydata, myopen, mywrite, myclose); - while (*filename) { - stat(*filename, &st); - entry = archive_entry_new(); - archive_entry_copy_stat(entry, &st); - archive_entry_set_pathname(entry, *filename); - archive_write_header(a, entry); - if ((fd = open(*filename, O_RDONLY)) != -1) { - len = read(fd, buff, sizeof(buff)); - while (len > 0) { - archive_write_data(a, buff, len); - len = read(fd, buff, sizeof(buff)); - } - close(fd); - } - archive_entry_free(entry); - filename++; - } - archive_write_free(a); -} - -int main(int argc, const char **argv) -{ - const char *outname; - argv++; - outname = *argv++; - write_archive(outname, argv); - return 0; -} -.Ed -.Sh SEE ALSO -.Xr tar 1 , -.Xr archive_write_set_options 3 , -.Xr libarchive 3 , -.Xr cpio 5 , -.Xr mtree 5 , -.Xr tar 5 -.Sh HISTORY -The -.Nm libarchive -library first appeared in -.Fx 5.3 . -.Sh AUTHORS -.An -nosplit -The -.Nm libarchive -library was written by -.An Tim Kientzle Aq kientzle@acm.org . -.Sh BUGS -There are many peculiar bugs in historic tar implementations that may cause -certain programs to reject archives written by this library. -For example, several historic implementations calculated header checksums -incorrectly and will thus reject valid archives; GNU tar does not fully support -pax interchange format; some old tar implementations required specific -field terminations. -.Pp -The default pax interchange format eliminates most of the historic -tar limitations and provides a generic key/value attribute facility -for vendor-defined extensions. -One oversight in POSIX is the failure to provide a standard attribute -for large device numbers. -This library uses -.Dq SCHILY.devminor -and -.Dq SCHILY.devmajor -for device numbers that exceed the range supported by the backwards-compatible -ustar header. -These keys are compatible with Joerg Schilling's -.Nm star -archiver. -Other implementations may not recognize these keys and will thus be unable -to correctly restore device nodes with large device numbers from archives -created by this library. diff --git a/thirdparty/libarchive/libarchive/archive_write.c b/thirdparty/libarchive/libarchive/archive_write.c deleted file mode 100644 index ec3c95c56..000000000 --- a/thirdparty/libarchive/libarchive/archive_write.c +++ /dev/null @@ -1,859 +0,0 @@ -/*- - * Copyright (c) 2003-2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_write.c 201099 2009-12-28 03:03:00Z kientzle $"); - -/* - * This file contains the "essential" portions of the write API, that - * is, stuff that will essentially always be used by any client that - * actually needs to write an archive. Optional pieces have been, as - * far as possible, separated out into separate files to reduce - * needlessly bloating statically-linked clients. - */ - -#ifdef HAVE_SYS_WAIT_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_LIMITS_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#include -#ifdef HAVE_UNISTD_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" -#include "archive_private.h" -#include "archive_write_private.h" - -static int _archive_filter_code(struct archive *, int); -static const char *_archive_filter_name(struct archive *, int); -static int64_t _archive_filter_bytes(struct archive *, int); -static int _archive_write_filter_count(struct archive *); -static int _archive_write_close(struct archive *); -static int _archive_write_free(struct archive *); -static int _archive_write_header(struct archive *, struct archive_entry *); -static int _archive_write_finish_entry(struct archive *); -static ssize_t _archive_write_data(struct archive *, const void *, size_t); - -struct archive_none { - size_t buffer_size; - size_t avail; - char *buffer; - char *next; -}; - -static const struct archive_vtable -archive_write_vtable = { - .archive_close = _archive_write_close, - .archive_filter_bytes = _archive_filter_bytes, - .archive_filter_code = _archive_filter_code, - .archive_filter_name = _archive_filter_name, - .archive_filter_count = _archive_write_filter_count, - .archive_free = _archive_write_free, - .archive_write_header = _archive_write_header, - .archive_write_finish_entry = _archive_write_finish_entry, - .archive_write_data = _archive_write_data, -}; - -/* - * Allocate, initialize and return an archive object. - */ -struct archive * -archive_write_new(void) -{ - struct archive_write *a; - unsigned char *nulls; - - a = (struct archive_write *)calloc(1, sizeof(*a)); - if (a == NULL) - return (NULL); - a->archive.magic = ARCHIVE_WRITE_MAGIC; - a->archive.state = ARCHIVE_STATE_NEW; - a->archive.vtable = &archive_write_vtable; - /* - * The value 10240 here matches the traditional tar default, - * but is otherwise arbitrary. - * TODO: Set the default block size from the format selected. - */ - a->bytes_per_block = 10240; - a->bytes_in_last_block = -1; /* Default */ - - /* Initialize a block of nulls for padding purposes. */ - a->null_length = 1024; - nulls = (unsigned char *)calloc(1, a->null_length); - if (nulls == NULL) { - free(a); - return (NULL); - } - a->nulls = nulls; - return (&a->archive); -} - -/* - * Set the block size. Returns 0 if successful. - */ -int -archive_write_set_bytes_per_block(struct archive *_a, int bytes_per_block) -{ - struct archive_write *a = (struct archive_write *)_a; - archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_set_bytes_per_block"); - a->bytes_per_block = bytes_per_block; - return (ARCHIVE_OK); -} - -/* - * Get the current block size. -1 if it has never been set. - */ -int -archive_write_get_bytes_per_block(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_ANY, "archive_write_get_bytes_per_block"); - return (a->bytes_per_block); -} - -/* - * Set the size for the last block. - * Returns 0 if successful. - */ -int -archive_write_set_bytes_in_last_block(struct archive *_a, int bytes) -{ - struct archive_write *a = (struct archive_write *)_a; - archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_ANY, "archive_write_set_bytes_in_last_block"); - a->bytes_in_last_block = bytes; - return (ARCHIVE_OK); -} - -/* - * Return the value set above. -1 indicates it has not been set. - */ -int -archive_write_get_bytes_in_last_block(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_ANY, "archive_write_get_bytes_in_last_block"); - return (a->bytes_in_last_block); -} - -/* - * dev/ino of a file to be rejected. Used to prevent adding - * an archive to itself recursively. - */ -int -archive_write_set_skip_file(struct archive *_a, la_int64_t d, la_int64_t i) -{ - struct archive_write *a = (struct archive_write *)_a; - archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_ANY, "archive_write_set_skip_file"); - a->skip_file_set = 1; - a->skip_file_dev = d; - a->skip_file_ino = i; - return (ARCHIVE_OK); -} - -/* - * Allocate and return the next filter structure. - */ -struct archive_write_filter * -__archive_write_allocate_filter(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - struct archive_write_filter *f; - - f = calloc(1, sizeof(*f)); - - if (f == NULL) - return (NULL); - - f->archive = _a; - f->state = ARCHIVE_WRITE_FILTER_STATE_NEW; - if (a->filter_first == NULL) - a->filter_first = f; - else - a->filter_last->next_filter = f; - a->filter_last = f; - return f; -} - -/* - * Write data to a particular filter. - */ -int -__archive_write_filter(struct archive_write_filter *f, - const void *buff, size_t length) -{ - int r; - /* Never write to non-open filters */ - if (f->state != ARCHIVE_WRITE_FILTER_STATE_OPEN) - return(ARCHIVE_FATAL); - if (length == 0) - return(ARCHIVE_OK); - if (f->write == NULL) - /* If unset, a fatal error has already occurred, so this filter - * didn't open. We cannot write anything. */ - return(ARCHIVE_FATAL); - r = (f->write)(f, buff, length); - f->bytes_written += length; - return (r); -} - -/* - * Recursive function for opening the filter chain - * Last filter is opened first - */ -static int -__archive_write_open_filter(struct archive_write_filter *f) -{ - int ret; - - ret = ARCHIVE_OK; - if (f->next_filter != NULL) - ret = __archive_write_open_filter(f->next_filter); - if (ret != ARCHIVE_OK) - return (ret); - if (f->state != ARCHIVE_WRITE_FILTER_STATE_NEW) - return (ARCHIVE_FATAL); - if (f->open == NULL) { - f->state = ARCHIVE_WRITE_FILTER_STATE_OPEN; - return (ARCHIVE_OK); - } - ret = (f->open)(f); - if (ret == ARCHIVE_OK) - f->state = ARCHIVE_WRITE_FILTER_STATE_OPEN; - else - f->state = ARCHIVE_WRITE_FILTER_STATE_FATAL; - return (ret); -} - -/* - * Open all filters - */ -static int -__archive_write_filters_open(struct archive_write *a) -{ - return (__archive_write_open_filter(a->filter_first)); -} - -/* - * Close all filtes - */ -static int -__archive_write_filters_close(struct archive_write *a) -{ - struct archive_write_filter *f; - int ret, ret1; - ret = ARCHIVE_OK; - for (f = a->filter_first; f != NULL; f = f->next_filter) { - /* Do not close filters that are not open */ - if (f->state == ARCHIVE_WRITE_FILTER_STATE_OPEN) { - if (f->close != NULL) { - ret1 = (f->close)(f); - if (ret1 < ret) - ret = ret1; - if (ret1 == ARCHIVE_OK) { - f->state = - ARCHIVE_WRITE_FILTER_STATE_CLOSED; - } else { - f->state = - ARCHIVE_WRITE_FILTER_STATE_FATAL; - } - } else - f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED; - } - } - return (ret); -} - -int -__archive_write_output(struct archive_write *a, const void *buff, size_t length) -{ - return (__archive_write_filter(a->filter_first, buff, length)); -} - -static int -__archive_write_filters_flush(struct archive_write *a) -{ - struct archive_write_filter *f; - int ret, ret1; - - ret = ARCHIVE_OK; - for (f = a->filter_first; f != NULL; f = f->next_filter) { - if (f->flush != NULL && f->bytes_written > 0) { - ret1 = (f->flush)(f); - if (ret1 < ret) - ret = ret1; - if (ret1 < ARCHIVE_WARN) - f->state = ARCHIVE_WRITE_FILTER_STATE_FATAL; - } - } - return (ret); -} - -int -__archive_write_nulls(struct archive_write *a, size_t length) -{ - if (length == 0) - return (ARCHIVE_OK); - - while (length > 0) { - size_t to_write = length < a->null_length ? length : a->null_length; - int r = __archive_write_output(a, a->nulls, to_write); - if (r < ARCHIVE_OK) - return (r); - length -= to_write; - } - return (ARCHIVE_OK); -} - -static int -archive_write_client_open(struct archive_write_filter *f) -{ - struct archive_write *a = (struct archive_write *)f->archive; - struct archive_none *state; - void *buffer; - size_t buffer_size; - int ret; - - f->bytes_per_block = archive_write_get_bytes_per_block(f->archive); - f->bytes_in_last_block = - archive_write_get_bytes_in_last_block(f->archive); - buffer_size = f->bytes_per_block; - - state = (struct archive_none *)calloc(1, sizeof(*state)); - buffer = (char *)malloc(buffer_size); - if (state == NULL || buffer == NULL) { - free(state); - free(buffer); - archive_set_error(f->archive, ENOMEM, - "Can't allocate data for output buffering"); - return (ARCHIVE_FATAL); - } - - state->buffer_size = buffer_size; - state->buffer = buffer; - state->next = state->buffer; - state->avail = state->buffer_size; - f->data = state; - - if (a->client_opener == NULL) - return (ARCHIVE_OK); - ret = a->client_opener(f->archive, a->client_data); - if (ret != ARCHIVE_OK) { - free(state->buffer); - free(state); - f->data = NULL; - } - return (ret); -} - -static int -archive_write_client_write(struct archive_write_filter *f, - const void *_buff, size_t length) -{ - struct archive_write *a = (struct archive_write *)f->archive; - struct archive_none *state = (struct archive_none *)f->data; - const char *buff = (const char *)_buff; - ssize_t remaining, to_copy; - ssize_t bytes_written; - - remaining = length; - - /* - * If there is no buffer for blocking, just pass the data - * straight through to the client write callback. In - * particular, this supports "no write delay" operation for - * special applications. Just set the block size to zero. - */ - if (state->buffer_size == 0) { - while (remaining > 0) { - bytes_written = (a->client_writer)(&a->archive, - a->client_data, buff, remaining); - if (bytes_written <= 0) - return (ARCHIVE_FATAL); - remaining -= bytes_written; - buff += bytes_written; - } - return (ARCHIVE_OK); - } - - /* If the copy buffer isn't empty, try to fill it. */ - if (state->avail < state->buffer_size) { - /* If buffer is not empty... */ - /* ... copy data into buffer ... */ - to_copy = ((size_t)remaining > state->avail) ? - state->avail : (size_t)remaining; - memcpy(state->next, buff, to_copy); - state->next += to_copy; - state->avail -= to_copy; - buff += to_copy; - remaining -= to_copy; - /* ... if it's full, write it out. */ - if (state->avail == 0) { - char *p = state->buffer; - size_t to_write = state->buffer_size; - while (to_write > 0) { - bytes_written = (a->client_writer)(&a->archive, - a->client_data, p, to_write); - if (bytes_written <= 0) - return (ARCHIVE_FATAL); - if ((size_t)bytes_written > to_write) { - archive_set_error(&(a->archive), - -1, "write overrun"); - return (ARCHIVE_FATAL); - } - p += bytes_written; - to_write -= bytes_written; - } - state->next = state->buffer; - state->avail = state->buffer_size; - } - } - - while ((size_t)remaining >= state->buffer_size) { - /* Write out full blocks directly to client. */ - bytes_written = (a->client_writer)(&a->archive, - a->client_data, buff, state->buffer_size); - if (bytes_written <= 0) - return (ARCHIVE_FATAL); - buff += bytes_written; - remaining -= bytes_written; - } - - if (remaining > 0) { - /* Copy last bit into copy buffer. */ - memcpy(state->next, buff, remaining); - state->next += remaining; - state->avail -= remaining; - } - return (ARCHIVE_OK); -} - -static int -archive_write_client_free(struct archive_write_filter *f) -{ - struct archive_write *a = (struct archive_write *)f->archive; - - if (a->client_freer) - (*a->client_freer)(&a->archive, a->client_data); - a->client_data = NULL; - - /* Clear passphrase. */ - if (a->passphrase != NULL) { - memset(a->passphrase, 0, strlen(a->passphrase)); - free(a->passphrase); - a->passphrase = NULL; - } - - return (ARCHIVE_OK); -} - -static int -archive_write_client_close(struct archive_write_filter *f) -{ - struct archive_write *a = (struct archive_write *)f->archive; - struct archive_none *state = (struct archive_none *)f->data; - ssize_t block_length; - ssize_t target_block_length; - ssize_t bytes_written; - size_t to_write; - char *p; - int ret = ARCHIVE_OK; - - /* If there's pending data, pad and write the last block */ - if (state->next != state->buffer) { - block_length = state->buffer_size - state->avail; - - /* Tricky calculation to determine size of last block */ - if (a->bytes_in_last_block <= 0) - /* Default or Zero: pad to full block */ - target_block_length = a->bytes_per_block; - else - /* Round to next multiple of bytes_in_last_block. */ - target_block_length = a->bytes_in_last_block * - ( (block_length + a->bytes_in_last_block - 1) / - a->bytes_in_last_block); - if (target_block_length > a->bytes_per_block) - target_block_length = a->bytes_per_block; - if (block_length < target_block_length) { - memset(state->next, 0, - target_block_length - block_length); - block_length = target_block_length; - } - p = state->buffer; - to_write = block_length; - while (to_write > 0) { - bytes_written = (a->client_writer)(&a->archive, - a->client_data, p, to_write); - if (bytes_written <= 0) { - ret = ARCHIVE_FATAL; - break; - } - if ((size_t)bytes_written > to_write) { - archive_set_error(&(a->archive), - -1, "write overrun"); - ret = ARCHIVE_FATAL; - break; - } - p += bytes_written; - to_write -= bytes_written; - } - } - if (a->client_closer) - (*a->client_closer)(&a->archive, a->client_data); - free(state->buffer); - free(state); - - /* Clear the close handler myself not to be called again. */ - f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED; - return (ret); -} - -/* - * Open the archive using the current settings. - */ -int -archive_write_open2(struct archive *_a, void *client_data, - archive_open_callback *opener, archive_write_callback *writer, - archive_close_callback *closer, archive_free_callback *freer) -{ - struct archive_write *a = (struct archive_write *)_a; - struct archive_write_filter *client_filter; - int ret, r1; - - archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_open"); - archive_clear_error(&a->archive); - - a->client_writer = writer; - a->client_opener = opener; - a->client_closer = closer; - a->client_freer = freer; - a->client_data = client_data; - - client_filter = __archive_write_allocate_filter(_a); - - if (client_filter == NULL) - return (ARCHIVE_FATAL); - - client_filter->open = archive_write_client_open; - client_filter->write = archive_write_client_write; - client_filter->close = archive_write_client_close; - client_filter->free = archive_write_client_free; - - ret = __archive_write_filters_open(a); - if (ret < ARCHIVE_WARN) { - r1 = __archive_write_filters_close(a); - __archive_write_filters_free(_a); - return (r1 < ret ? r1 : ret); - } - - a->archive.state = ARCHIVE_STATE_HEADER; - if (a->format_init) - ret = (a->format_init)(a); - return (ret); -} - -int -archive_write_open(struct archive *_a, void *client_data, - archive_open_callback *opener, archive_write_callback *writer, - archive_close_callback *closer) -{ - return archive_write_open2(_a, client_data, opener, writer, - closer, NULL); -} - -/* - * Close out the archive. - */ -static int -_archive_write_close(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - int r = ARCHIVE_OK, r1 = ARCHIVE_OK; - - archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, - "archive_write_close"); - if (a->archive.state == ARCHIVE_STATE_NEW - || a->archive.state == ARCHIVE_STATE_CLOSED) - return (ARCHIVE_OK); /* Okay to close() when not open. */ - - archive_clear_error(&a->archive); - - /* Finish the last entry if a finish callback is specified */ - if (a->archive.state == ARCHIVE_STATE_DATA - && a->format_finish_entry != NULL) - r = ((a->format_finish_entry)(a)); - - /* Finish off the archive. */ - /* TODO: have format closers invoke compression close. */ - if (a->format_close != NULL) { - r1 = (a->format_close)(a); - if (r1 < r) - r = r1; - } - - /* Finish the compression and close the stream. */ - r1 = __archive_write_filters_close(a); - if (r1 < r) - r = r1; - - if (a->archive.state != ARCHIVE_STATE_FATAL) - a->archive.state = ARCHIVE_STATE_CLOSED; - return (r); -} - -static int -_archive_write_filter_count(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - struct archive_write_filter *p = a->filter_first; - int count = 0; - while(p) { - count++; - p = p->next_filter; - } - return count; -} - -void -__archive_write_filters_free(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - int r = ARCHIVE_OK, r1; - - while (a->filter_first != NULL) { - struct archive_write_filter *next - = a->filter_first->next_filter; - if (a->filter_first->free != NULL) { - r1 = (*a->filter_first->free)(a->filter_first); - if (r > r1) - r = r1; - } - free(a->filter_first); - a->filter_first = next; - } - a->filter_last = NULL; -} - -/* - * Destroy the archive structure. - * - * Be careful: user might just call write_new and then write_free. - * Don't assume we actually wrote anything or performed any non-trivial - * initialization. - */ -static int -_archive_write_free(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - int r = ARCHIVE_OK, r1; - - if (_a == NULL) - return (ARCHIVE_OK); - /* It is okay to call free() in state FATAL. */ - archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_free"); - if (a->archive.state != ARCHIVE_STATE_FATAL) - r = archive_write_close(&a->archive); - - /* Release format resources. */ - if (a->format_free != NULL) { - r1 = (a->format_free)(a); - if (r1 < r) - r = r1; - } - - __archive_write_filters_free(_a); - - /* Release various dynamic buffers. */ - free((void *)(uintptr_t)(const void *)a->nulls); - archive_string_free(&a->archive.error_string); - if (a->passphrase != NULL) { - /* A passphrase should be cleaned. */ - memset(a->passphrase, 0, strlen(a->passphrase)); - free(a->passphrase); - } - a->archive.magic = 0; - __archive_clean(&a->archive); - free(a); - return (r); -} - -/* - * Write the appropriate header. - */ -static int -_archive_write_header(struct archive *_a, struct archive_entry *entry) -{ - struct archive_write *a = (struct archive_write *)_a; - int ret, r2; - - archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_DATA | ARCHIVE_STATE_HEADER, "archive_write_header"); - archive_clear_error(&a->archive); - - if (a->format_write_header == NULL) { - archive_set_error(&(a->archive), -1, - "Format must be set before you can write to an archive."); - a->archive.state = ARCHIVE_STATE_FATAL; - return (ARCHIVE_FATAL); - } - - /* In particular, "retry" and "fatal" get returned immediately. */ - ret = archive_write_finish_entry(&a->archive); - if (ret == ARCHIVE_FATAL) { - a->archive.state = ARCHIVE_STATE_FATAL; - return (ARCHIVE_FATAL); - } - if (ret < ARCHIVE_OK && ret != ARCHIVE_WARN) - return (ret); - - if (a->skip_file_set && - archive_entry_dev_is_set(entry) && - archive_entry_ino_is_set(entry) && - archive_entry_dev(entry) == (dev_t)a->skip_file_dev && - archive_entry_ino64(entry) == a->skip_file_ino) { - archive_set_error(&a->archive, 0, - "Can't add archive to itself"); - return (ARCHIVE_FAILED); - } - - /* Flush filters at boundary. */ - r2 = __archive_write_filters_flush(a); - if (r2 == ARCHIVE_FAILED) { - return (ARCHIVE_FAILED); - } - if (r2 == ARCHIVE_FATAL) { - a->archive.state = ARCHIVE_STATE_FATAL; - return (ARCHIVE_FATAL); - } - if (r2 < ret) - ret = r2; - - /* Format and write header. */ - r2 = ((a->format_write_header)(a, entry)); - if (r2 == ARCHIVE_FAILED) { - return (ARCHIVE_FAILED); - } - if (r2 == ARCHIVE_FATAL) { - a->archive.state = ARCHIVE_STATE_FATAL; - return (ARCHIVE_FATAL); - } - if (r2 < ret) - ret = r2; - - a->archive.state = ARCHIVE_STATE_DATA; - return (ret); -} - -static int -_archive_write_finish_entry(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - int ret = ARCHIVE_OK; - - archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, - "archive_write_finish_entry"); - if (a->archive.state & ARCHIVE_STATE_DATA - && a->format_finish_entry != NULL) - ret = (a->format_finish_entry)(a); - a->archive.state = ARCHIVE_STATE_HEADER; - return (ret); -} - -/* - * Note that the compressor is responsible for blocking. - */ -static ssize_t -_archive_write_data(struct archive *_a, const void *buff, size_t s) -{ - struct archive_write *a = (struct archive_write *)_a; - const size_t max_write = INT_MAX; - - archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_DATA, "archive_write_data"); - /* In particular, this catches attempts to pass negative values. */ - if (s > max_write) - s = max_write; - archive_clear_error(&a->archive); - return ((a->format_write_data)(a, buff, s)); -} - -static struct archive_write_filter * -filter_lookup(struct archive *_a, int n) -{ - struct archive_write *a = (struct archive_write *)_a; - struct archive_write_filter *f = a->filter_first; - if (n == -1) - return a->filter_last; - if (n < 0) - return NULL; - while (n > 0 && f != NULL) { - f = f->next_filter; - --n; - } - return f; -} - -static int -_archive_filter_code(struct archive *_a, int n) -{ - struct archive_write_filter *f = filter_lookup(_a, n); - return f == NULL ? -1 : f->code; -} - -static const char * -_archive_filter_name(struct archive *_a, int n) -{ - struct archive_write_filter *f = filter_lookup(_a, n); - return f != NULL ? f->name : NULL; -} - -static int64_t -_archive_filter_bytes(struct archive *_a, int n) -{ - struct archive_write_filter *f = filter_lookup(_a, n); - return f == NULL ? -1 : f->bytes_written; -} diff --git a/thirdparty/libarchive/libarchive/archive_write_add_filter.c b/thirdparty/libarchive/libarchive/archive_write_add_filter.c deleted file mode 100644 index 203f4142b..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_add_filter.c +++ /dev/null @@ -1,72 +0,0 @@ -/*- - * Copyright (c) 2012 Ondrej Holy - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#ifdef HAVE_ERRNO_H -#include -#endif - -#include "archive.h" -#include "archive_private.h" - -/* A table that maps filter codes to functions. */ -static const -struct { int code; int (*setter)(struct archive *); } codes[] = -{ - { ARCHIVE_FILTER_NONE, archive_write_add_filter_none }, - { ARCHIVE_FILTER_GZIP, archive_write_add_filter_gzip }, - { ARCHIVE_FILTER_BZIP2, archive_write_add_filter_bzip2 }, - { ARCHIVE_FILTER_COMPRESS, archive_write_add_filter_compress }, - { ARCHIVE_FILTER_GRZIP, archive_write_add_filter_grzip }, - { ARCHIVE_FILTER_LRZIP, archive_write_add_filter_lrzip }, - { ARCHIVE_FILTER_LZ4, archive_write_add_filter_lz4 }, - { ARCHIVE_FILTER_LZIP, archive_write_add_filter_lzip }, - { ARCHIVE_FILTER_LZMA, archive_write_add_filter_lzma }, - { ARCHIVE_FILTER_LZOP, archive_write_add_filter_lzip }, - { ARCHIVE_FILTER_UU, archive_write_add_filter_uuencode }, - { ARCHIVE_FILTER_XZ, archive_write_add_filter_xz }, - { ARCHIVE_FILTER_ZSTD, archive_write_add_filter_zstd }, - { -1, NULL } -}; - -int -archive_write_add_filter(struct archive *a, int code) -{ - int i; - - for (i = 0; codes[i].code != -1; i++) { - if (code == codes[i].code) - return ((codes[i].setter)(a)); - } - - archive_set_error(a, EINVAL, "No such filter"); - return (ARCHIVE_FATAL); -} diff --git a/thirdparty/libarchive/libarchive/archive_write_add_filter_b64encode.c b/thirdparty/libarchive/libarchive/archive_write_add_filter_b64encode.c deleted file mode 100644 index 87fdb73ec..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_add_filter_b64encode.c +++ /dev/null @@ -1,304 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "archive.h" -#include "archive_private.h" -#include "archive_string.h" -#include "archive_write_private.h" - -#define LBYTES 57 - -struct private_b64encode { - int mode; - struct archive_string name; - struct archive_string encoded_buff; - size_t bs; - size_t hold_len; - unsigned char hold[LBYTES]; -}; - -static int archive_filter_b64encode_options(struct archive_write_filter *, - const char *, const char *); -static int archive_filter_b64encode_open(struct archive_write_filter *); -static int archive_filter_b64encode_write(struct archive_write_filter *, - const void *, size_t); -static int archive_filter_b64encode_close(struct archive_write_filter *); -static int archive_filter_b64encode_free(struct archive_write_filter *); -static void la_b64_encode(struct archive_string *, const unsigned char *, size_t); -static int64_t atol8(const char *, size_t); - -static const char base64[] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', - 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', - 'w', 'x', 'y', 'z', '0', '1', '2', '3', - '4', '5', '6', '7', '8', '9', '+', '/' -}; - -/* - * Add a compress filter to this write handle. - */ -int -archive_write_add_filter_b64encode(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - struct archive_write_filter *f = __archive_write_allocate_filter(_a); - struct private_b64encode *state; - - archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_add_filter_uu"); - - state = (struct private_b64encode *)calloc(1, sizeof(*state)); - if (state == NULL) { - archive_set_error(f->archive, ENOMEM, - "Can't allocate data for b64encode filter"); - return (ARCHIVE_FATAL); - } - archive_strcpy(&state->name, "-"); - state->mode = 0644; - - f->data = state; - f->name = "b64encode"; - f->code = ARCHIVE_FILTER_UU; - f->open = archive_filter_b64encode_open; - f->options = archive_filter_b64encode_options; - f->write = archive_filter_b64encode_write; - f->close = archive_filter_b64encode_close; - f->free = archive_filter_b64encode_free; - - return (ARCHIVE_OK); -} - -/* - * Set write options. - */ -static int -archive_filter_b64encode_options(struct archive_write_filter *f, const char *key, - const char *value) -{ - struct private_b64encode *state = (struct private_b64encode *)f->data; - - if (strcmp(key, "mode") == 0) { - if (value == NULL) { - archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, - "mode option requires octal digits"); - return (ARCHIVE_FAILED); - } - state->mode = (int)atol8(value, strlen(value)) & 0777; - return (ARCHIVE_OK); - } else if (strcmp(key, "name") == 0) { - if (value == NULL) { - archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, - "name option requires a string"); - return (ARCHIVE_FAILED); - } - archive_strcpy(&state->name, value); - return (ARCHIVE_OK); - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -/* - * Setup callback. - */ -static int -archive_filter_b64encode_open(struct archive_write_filter *f) -{ - struct private_b64encode *state = (struct private_b64encode *)f->data; - size_t bs = 65536, bpb; - - if (f->archive->magic == ARCHIVE_WRITE_MAGIC) { - /* Buffer size should be a multiple number of the of bytes - * per block for performance. */ - bpb = archive_write_get_bytes_per_block(f->archive); - if (bpb > bs) - bs = bpb; - else if (bpb != 0) - bs -= bs % bpb; - } - - state->bs = bs; - if (archive_string_ensure(&state->encoded_buff, bs + 512) == NULL) { - archive_set_error(f->archive, ENOMEM, - "Can't allocate data for b64encode buffer"); - return (ARCHIVE_FATAL); - } - - archive_string_sprintf(&state->encoded_buff, "begin-base64 %o %s\n", - state->mode, state->name.s); - - f->data = state; - return (0); -} - -static void -la_b64_encode(struct archive_string *as, const unsigned char *p, size_t len) -{ - int c; - - for (; len >= 3; p += 3, len -= 3) { - c = p[0] >> 2; - archive_strappend_char(as, base64[c]); - c = ((p[0] & 0x03) << 4) | ((p[1] & 0xf0) >> 4); - archive_strappend_char(as, base64[c]); - c = ((p[1] & 0x0f) << 2) | ((p[2] & 0xc0) >> 6); - archive_strappend_char(as, base64[c]); - c = p[2] & 0x3f; - archive_strappend_char(as, base64[c]); - } - if (len > 0) { - c = p[0] >> 2; - archive_strappend_char(as, base64[c]); - c = (p[0] & 0x03) << 4; - if (len == 1) { - archive_strappend_char(as, base64[c]); - archive_strappend_char(as, '='); - archive_strappend_char(as, '='); - } else { - c |= (p[1] & 0xf0) >> 4; - archive_strappend_char(as, base64[c]); - c = (p[1] & 0x0f) << 2; - archive_strappend_char(as, base64[c]); - archive_strappend_char(as, '='); - } - } - archive_strappend_char(as, '\n'); -} - -/* - * Write data to the encoded stream. - */ -static int -archive_filter_b64encode_write(struct archive_write_filter *f, const void *buff, - size_t length) -{ - struct private_b64encode *state = (struct private_b64encode *)f->data; - const unsigned char *p = buff; - int ret = ARCHIVE_OK; - - if (length == 0) - return (ret); - - if (state->hold_len) { - while (state->hold_len < LBYTES && length > 0) { - state->hold[state->hold_len++] = *p++; - length--; - } - if (state->hold_len < LBYTES) - return (ret); - la_b64_encode(&state->encoded_buff, state->hold, LBYTES); - state->hold_len = 0; - } - - for (; length >= LBYTES; length -= LBYTES, p += LBYTES) - la_b64_encode(&state->encoded_buff, p, LBYTES); - - /* Save remaining bytes. */ - if (length > 0) { - memcpy(state->hold, p, length); - state->hold_len = length; - } - while (archive_strlen(&state->encoded_buff) >= state->bs) { - ret = __archive_write_filter(f->next_filter, - state->encoded_buff.s, state->bs); - memmove(state->encoded_buff.s, - state->encoded_buff.s + state->bs, - state->encoded_buff.length - state->bs); - state->encoded_buff.length -= state->bs; - } - - return (ret); -} - - -/* - * Finish the compression... - */ -static int -archive_filter_b64encode_close(struct archive_write_filter *f) -{ - struct private_b64encode *state = (struct private_b64encode *)f->data; - - /* Flush remaining bytes. */ - if (state->hold_len != 0) - la_b64_encode(&state->encoded_buff, state->hold, state->hold_len); - archive_string_sprintf(&state->encoded_buff, "====\n"); - /* Write the last block */ - archive_write_set_bytes_in_last_block(f->archive, 1); - return __archive_write_filter(f->next_filter, - state->encoded_buff.s, archive_strlen(&state->encoded_buff)); -} - -static int -archive_filter_b64encode_free(struct archive_write_filter *f) -{ - struct private_b64encode *state = (struct private_b64encode *)f->data; - - archive_string_free(&state->name); - archive_string_free(&state->encoded_buff); - free(state); - return (ARCHIVE_OK); -} - -static int64_t -atol8(const char *p, size_t char_cnt) -{ - int64_t l; - int digit; - - l = 0; - while (char_cnt-- > 0) { - if (*p >= '0' && *p <= '7') - digit = *p - '0'; - else - break; - p++; - l <<= 3; - l |= digit; - } - return (l); -} - diff --git a/thirdparty/libarchive/libarchive/archive_write_add_filter_by_name.c b/thirdparty/libarchive/libarchive/archive_write_add_filter_by_name.c deleted file mode 100644 index ffa633c96..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_add_filter_by_name.c +++ /dev/null @@ -1,77 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "archive.h" -#include "archive_private.h" - -/* A table that maps names to functions. */ -static const -struct { const char *name; int (*setter)(struct archive *); } names[] = -{ - { "b64encode", archive_write_add_filter_b64encode }, - { "bzip2", archive_write_add_filter_bzip2 }, - { "compress", archive_write_add_filter_compress }, - { "grzip", archive_write_add_filter_grzip }, - { "gzip", archive_write_add_filter_gzip }, - { "lrzip", archive_write_add_filter_lrzip }, - { "lz4", archive_write_add_filter_lz4 }, - { "lzip", archive_write_add_filter_lzip }, - { "lzma", archive_write_add_filter_lzma }, - { "lzop", archive_write_add_filter_lzop }, - { "uuencode", archive_write_add_filter_uuencode }, - { "xz", archive_write_add_filter_xz }, - { "zstd", archive_write_add_filter_zstd }, - { NULL, NULL } -}; - -int -archive_write_add_filter_by_name(struct archive *a, const char *name) -{ - int i; - - for (i = 0; names[i].name != NULL; i++) { - if (strcmp(name, names[i].name) == 0) - return ((names[i].setter)(a)); - } - - archive_set_error(a, EINVAL, "No such filter '%s'", name); - a->state = ARCHIVE_STATE_FATAL; - return (ARCHIVE_FATAL); -} diff --git a/thirdparty/libarchive/libarchive/archive_write_add_filter_bzip2.c b/thirdparty/libarchive/libarchive/archive_write_add_filter_bzip2.c deleted file mode 100644 index 3e5c0891a..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_add_filter_bzip2.c +++ /dev/null @@ -1,401 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_bzip2.c 201091 2009-12-28 02:22:41Z kientzle $"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_BZLIB_H -#include -#endif - -#include "archive.h" -#include "archive_private.h" -#include "archive_write_private.h" - -#if ARCHIVE_VERSION_NUMBER < 4000000 -int -archive_write_set_compression_bzip2(struct archive *a) -{ - __archive_write_filters_free(a); - return (archive_write_add_filter_bzip2(a)); -} -#endif - -struct private_data { - int compression_level; -#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) - bz_stream stream; - int64_t total_in; - char *compressed; - size_t compressed_buffer_size; -#else - struct archive_write_program_data *pdata; -#endif -}; - -static int archive_compressor_bzip2_close(struct archive_write_filter *); -static int archive_compressor_bzip2_free(struct archive_write_filter *); -static int archive_compressor_bzip2_open(struct archive_write_filter *); -static int archive_compressor_bzip2_options(struct archive_write_filter *, - const char *, const char *); -static int archive_compressor_bzip2_write(struct archive_write_filter *, - const void *, size_t); - -/* - * Add a bzip2 compression filter to this write handle. - */ -int -archive_write_add_filter_bzip2(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - struct archive_write_filter *f = __archive_write_allocate_filter(_a); - struct private_data *data; - - archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_add_filter_bzip2"); - - data = calloc(1, sizeof(*data)); - if (data == NULL) { - archive_set_error(&a->archive, ENOMEM, "Out of memory"); - return (ARCHIVE_FATAL); - } - data->compression_level = 9; /* default */ - - f->data = data; - f->options = &archive_compressor_bzip2_options; - f->close = &archive_compressor_bzip2_close; - f->free = &archive_compressor_bzip2_free; - f->open = &archive_compressor_bzip2_open; - f->code = ARCHIVE_FILTER_BZIP2; - f->name = "bzip2"; -#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) - return (ARCHIVE_OK); -#else - data->pdata = __archive_write_program_allocate("bzip2"); - if (data->pdata == NULL) { - free(data); - archive_set_error(&a->archive, ENOMEM, "Out of memory"); - return (ARCHIVE_FATAL); - } - data->compression_level = 0; - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Using external bzip2 program"); - return (ARCHIVE_WARN); -#endif -} - -/* - * Set write options. - */ -static int -archive_compressor_bzip2_options(struct archive_write_filter *f, - const char *key, const char *value) -{ - struct private_data *data = (struct private_data *)f->data; - - if (strcmp(key, "compression-level") == 0) { - if (value == NULL || !(value[0] >= '0' && value[0] <= '9') || - value[1] != '\0') - return (ARCHIVE_WARN); - data->compression_level = value[0] - '0'; - /* Make '0' be a synonym for '1'. */ - /* This way, bzip2 compressor supports the same 0..9 - * range of levels as gzip. */ - if (data->compression_level < 1) - data->compression_level = 1; - return (ARCHIVE_OK); - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) -/* Don't compile this if we don't have bzlib. */ - -/* - * Yuck. bzlib.h is not const-correct, so I need this one bit - * of ugly hackery to convert a const * pointer to a non-const pointer. - */ -#define SET_NEXT_IN(st,src) \ - (st)->stream.next_in = (char *)(uintptr_t)(const void *)(src) -static int drive_compressor(struct archive_write_filter *, - struct private_data *, int finishing); - -/* - * Setup callback. - */ -static int -archive_compressor_bzip2_open(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; - int ret; - - if (data->compressed == NULL) { - size_t bs = 65536, bpb; - if (f->archive->magic == ARCHIVE_WRITE_MAGIC) { - /* Buffer size should be a multiple number of the of bytes - * per block for performance. */ - bpb = archive_write_get_bytes_per_block(f->archive); - if (bpb > bs) - bs = bpb; - else if (bpb != 0) - bs -= bs % bpb; - } - data->compressed_buffer_size = bs; - data->compressed - = (char *)malloc(data->compressed_buffer_size); - if (data->compressed == NULL) { - archive_set_error(f->archive, ENOMEM, - "Can't allocate data for compression buffer"); - return (ARCHIVE_FATAL); - } - } - - memset(&data->stream, 0, sizeof(data->stream)); - data->stream.next_out = data->compressed; - data->stream.avail_out = (uint32_t)data->compressed_buffer_size; - f->write = archive_compressor_bzip2_write; - - /* Initialize compression library */ - ret = BZ2_bzCompressInit(&(data->stream), - data->compression_level, 0, 30); - if (ret == BZ_OK) { - f->data = data; - return (ARCHIVE_OK); - } - - /* Library setup failed: clean up. */ - archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, - "Internal error initializing compression library"); - - /* Override the error message if we know what really went wrong. */ - switch (ret) { - case BZ_PARAM_ERROR: - archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, - "Internal error initializing compression library: " - "invalid setup parameter"); - break; - case BZ_MEM_ERROR: - archive_set_error(f->archive, ENOMEM, - "Internal error initializing compression library: " - "out of memory"); - break; - case BZ_CONFIG_ERROR: - archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, - "Internal error initializing compression library: " - "mis-compiled library"); - break; - } - - return (ARCHIVE_FATAL); - -} - -/* - * Write data to the compressed stream. - * - * Returns ARCHIVE_OK if all data written, error otherwise. - */ -static int -archive_compressor_bzip2_write(struct archive_write_filter *f, - const void *buff, size_t length) -{ - struct private_data *data = (struct private_data *)f->data; - - /* Update statistics */ - data->total_in += length; - - /* Compress input data to output buffer */ - SET_NEXT_IN(data, buff); - data->stream.avail_in = (uint32_t)length; - if (drive_compressor(f, data, 0)) - return (ARCHIVE_FATAL); - return (ARCHIVE_OK); -} - - -/* - * Finish the compression. - */ -static int -archive_compressor_bzip2_close(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; - int ret; - - /* Finish compression cycle. */ - ret = drive_compressor(f, data, 1); - if (ret == ARCHIVE_OK) { - /* Write the last block */ - ret = __archive_write_filter(f->next_filter, - data->compressed, - data->compressed_buffer_size - data->stream.avail_out); - } - - switch (BZ2_bzCompressEnd(&(data->stream))) { - case BZ_OK: - break; - default: - archive_set_error(f->archive, ARCHIVE_ERRNO_PROGRAMMER, - "Failed to clean up compressor"); - ret = ARCHIVE_FATAL; - } - return ret; -} - -static int -archive_compressor_bzip2_free(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; - free(data->compressed); - free(data); - f->data = NULL; - return (ARCHIVE_OK); -} - -/* - * Utility function to push input data through compressor, writing - * full output blocks as necessary. - * - * Note that this handles both the regular write case (finishing == - * false) and the end-of-archive case (finishing == true). - */ -static int -drive_compressor(struct archive_write_filter *f, - struct private_data *data, int finishing) -{ - int ret; - - for (;;) { - if (data->stream.avail_out == 0) { - ret = __archive_write_filter(f->next_filter, - data->compressed, - data->compressed_buffer_size); - if (ret != ARCHIVE_OK) { - /* TODO: Handle this write failure */ - return (ARCHIVE_FATAL); - } - data->stream.next_out = data->compressed; - data->stream.avail_out = (uint32_t)data->compressed_buffer_size; - } - - /* If there's nothing to do, we're done. */ - if (!finishing && data->stream.avail_in == 0) - return (ARCHIVE_OK); - - ret = BZ2_bzCompress(&(data->stream), - finishing ? BZ_FINISH : BZ_RUN); - - switch (ret) { - case BZ_RUN_OK: - /* In non-finishing case, did compressor - * consume everything? */ - if (!finishing && data->stream.avail_in == 0) - return (ARCHIVE_OK); - break; - case BZ_FINISH_OK: /* Finishing: There's more work to do */ - break; - case BZ_STREAM_END: /* Finishing: all done */ - /* Only occurs in finishing case */ - return (ARCHIVE_OK); - default: - /* Any other return value indicates an error */ - archive_set_error(f->archive, - ARCHIVE_ERRNO_PROGRAMMER, - "Bzip2 compression failed;" - " BZ2_bzCompress() returned %d", - ret); - return (ARCHIVE_FATAL); - } - } -} - -#else /* HAVE_BZLIB_H && BZ_CONFIG_ERROR */ - -static int -archive_compressor_bzip2_open(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; - struct archive_string as; - int r; - - archive_string_init(&as); - archive_strcpy(&as, "bzip2"); - - /* Specify compression level. */ - if (data->compression_level > 0) { - archive_strcat(&as, " -"); - archive_strappend_char(&as, '0' + data->compression_level); - } - f->write = archive_compressor_bzip2_write; - - r = __archive_write_program_open(f, data->pdata, as.s); - archive_string_free(&as); - return (r); -} - -static int -archive_compressor_bzip2_write(struct archive_write_filter *f, const void *buff, - size_t length) -{ - struct private_data *data = (struct private_data *)f->data; - - return __archive_write_program_write(f, data->pdata, buff, length); -} - -static int -archive_compressor_bzip2_close(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; - - return __archive_write_program_close(f, data->pdata); -} - -static int -archive_compressor_bzip2_free(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; - - __archive_write_program_free(data->pdata); - free(data); - return (ARCHIVE_OK); -} - -#endif /* HAVE_BZLIB_H && BZ_CONFIG_ERROR */ diff --git a/thirdparty/libarchive/libarchive/archive_write_add_filter_compress.c b/thirdparty/libarchive/libarchive/archive_write_add_filter_compress.c deleted file mode 100644 index 3ed269fce..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_add_filter_compress.c +++ /dev/null @@ -1,447 +0,0 @@ -/*- - * Copyright (c) 2008 Joerg Sonnenberger - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -/*- - * Copyright (c) 1985, 1986, 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Diomidis Spinellis and James A. Woods, derived from original - * work by Spencer Thomas and Joseph Orost. - * - * 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. - * 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. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. - */ - -#include "archive_platform.h" - -__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_compress.c 201111 2009-12-28 03:33:05Z kientzle $"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "archive.h" -#include "archive_private.h" -#include "archive_write_private.h" - -#define HSIZE 69001 /* 95% occupancy */ -#define HSHIFT 8 /* 8 - trunc(log2(HSIZE / 65536)) */ -#define CHECK_GAP 10000 /* Ratio check interval. */ - -#define MAXCODE(bits) ((1 << (bits)) - 1) - -/* - * the next two codes should not be changed lightly, as they must not - * lie within the contiguous general code space. - */ -#define FIRST 257 /* First free entry. */ -#define CLEAR 256 /* Table clear output code. */ - -struct private_data { - int64_t in_count, out_count, checkpoint; - - int code_len; /* Number of bits/code. */ - int cur_maxcode; /* Maximum code, given n_bits. */ - int max_maxcode; /* Should NEVER generate this code. */ - int hashtab [HSIZE]; - unsigned short codetab [HSIZE]; - int first_free; /* First unused entry. */ - int compress_ratio; - - int cur_code, cur_fcode; - - int bit_offset; - unsigned char bit_buf; - - unsigned char *compressed; - size_t compressed_buffer_size; - size_t compressed_offset; -}; - -static int archive_compressor_compress_open(struct archive_write_filter *); -static int archive_compressor_compress_write(struct archive_write_filter *, - const void *, size_t); -static int archive_compressor_compress_close(struct archive_write_filter *); -static int archive_compressor_compress_free(struct archive_write_filter *); - -#if ARCHIVE_VERSION_NUMBER < 4000000 -int -archive_write_set_compression_compress(struct archive *a) -{ - __archive_write_filters_free(a); - return (archive_write_add_filter_compress(a)); -} -#endif - -/* - * Add a compress filter to this write handle. - */ -int -archive_write_add_filter_compress(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - struct archive_write_filter *f = __archive_write_allocate_filter(_a); - - archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_add_filter_compress"); - f->open = &archive_compressor_compress_open; - f->code = ARCHIVE_FILTER_COMPRESS; - f->name = "compress"; - return (ARCHIVE_OK); -} - -/* - * Setup callback. - */ -static int -archive_compressor_compress_open(struct archive_write_filter *f) -{ - struct private_data *state; - size_t bs = 65536, bpb; - - f->code = ARCHIVE_FILTER_COMPRESS; - f->name = "compress"; - - state = (struct private_data *)calloc(1, sizeof(*state)); - if (state == NULL) { - archive_set_error(f->archive, ENOMEM, - "Can't allocate data for compression"); - return (ARCHIVE_FATAL); - } - - if (f->archive->magic == ARCHIVE_WRITE_MAGIC) { - /* Buffer size should be a multiple number of the of bytes - * per block for performance. */ - bpb = archive_write_get_bytes_per_block(f->archive); - if (bpb > bs) - bs = bpb; - else if (bpb != 0) - bs -= bs % bpb; - } - state->compressed_buffer_size = bs; - state->compressed = malloc(state->compressed_buffer_size); - - if (state->compressed == NULL) { - archive_set_error(f->archive, ENOMEM, - "Can't allocate data for compression buffer"); - free(state); - return (ARCHIVE_FATAL); - } - - f->write = archive_compressor_compress_write; - f->close = archive_compressor_compress_close; - f->free = archive_compressor_compress_free; - - state->max_maxcode = 0x10000; /* Should NEVER generate this code. */ - state->in_count = 0; /* Length of input. */ - state->bit_buf = 0; - state->bit_offset = 0; - state->out_count = 3; /* Includes 3-byte header mojo. */ - state->compress_ratio = 0; - state->checkpoint = CHECK_GAP; - state->code_len = 9; - state->cur_maxcode = MAXCODE(state->code_len); - state->first_free = FIRST; - - memset(state->hashtab, 0xff, sizeof(state->hashtab)); - - /* Prime output buffer with a gzip header. */ - state->compressed[0] = 0x1f; /* Compress */ - state->compressed[1] = 0x9d; - state->compressed[2] = 0x90; /* Block mode, 16bit max */ - state->compressed_offset = 3; - - f->data = state; - return (0); -} - -/*- - * Output the given code. - * Inputs: - * code: A n_bits-bit integer. If == -1, then EOF. This assumes - * that n_bits <= (long)wordsize - 1. - * Outputs: - * Outputs code to the file. - * Assumptions: - * Chars are 8 bits long. - * Algorithm: - * Maintain a BITS character long buffer (so that 8 codes will - * fit in it exactly). Use the VAX insv instruction to insert each - * code in turn. When the buffer fills up empty it and start over. - */ - -static const unsigned char rmask[9] = - {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; - -static int -output_byte(struct archive_write_filter *f, unsigned char c) -{ - struct private_data *state = f->data; - - state->compressed[state->compressed_offset++] = c; - ++state->out_count; - - if (state->compressed_buffer_size == state->compressed_offset) { - int ret = __archive_write_filter(f->next_filter, - state->compressed, state->compressed_buffer_size); - if (ret != ARCHIVE_OK) - return ARCHIVE_FATAL; - state->compressed_offset = 0; - } - - return ARCHIVE_OK; -} - -static int -output_code(struct archive_write_filter *f, int ocode) -{ - struct private_data *state = f->data; - int bits, ret, clear_flg, bit_offset; - - clear_flg = ocode == CLEAR; - - /* - * Since ocode is always >= 8 bits, only need to mask the first - * hunk on the left. - */ - bit_offset = state->bit_offset % 8; - state->bit_buf |= (ocode << bit_offset) & 0xff; - output_byte(f, state->bit_buf); - - bits = state->code_len - (8 - bit_offset); - ocode >>= 8 - bit_offset; - /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */ - if (bits >= 8) { - output_byte(f, ocode & 0xff); - ocode >>= 8; - bits -= 8; - } - /* Last bits. */ - state->bit_offset += state->code_len; - state->bit_buf = ocode & rmask[bits]; - if (state->bit_offset == state->code_len * 8) - state->bit_offset = 0; - - /* - * If the next entry is going to be too big for the ocode size, - * then increase it, if possible. - */ - if (clear_flg || state->first_free > state->cur_maxcode) { - /* - * Write the whole buffer, because the input side won't - * discover the size increase until after it has read it. - */ - if (state->bit_offset > 0) { - while (state->bit_offset < state->code_len * 8) { - ret = output_byte(f, state->bit_buf); - if (ret != ARCHIVE_OK) - return ret; - state->bit_offset += 8; - state->bit_buf = 0; - } - } - state->bit_buf = 0; - state->bit_offset = 0; - - if (clear_flg) { - state->code_len = 9; - state->cur_maxcode = MAXCODE(state->code_len); - } else { - state->code_len++; - if (state->code_len == 16) - state->cur_maxcode = state->max_maxcode; - else - state->cur_maxcode = MAXCODE(state->code_len); - } - } - - return (ARCHIVE_OK); -} - -static int -output_flush(struct archive_write_filter *f) -{ - struct private_data *state = f->data; - int ret; - - /* At EOF, write the rest of the buffer. */ - if (state->bit_offset % 8) { - state->code_len = (state->bit_offset % 8 + 7) / 8; - ret = output_byte(f, state->bit_buf); - if (ret != ARCHIVE_OK) - return ret; - } - - return (ARCHIVE_OK); -} - -/* - * Write data to the compressed stream. - */ -static int -archive_compressor_compress_write(struct archive_write_filter *f, - const void *buff, size_t length) -{ - struct private_data *state = (struct private_data *)f->data; - int i; - int ratio; - int c, disp, ret; - const unsigned char *bp; - - if (length == 0) - return ARCHIVE_OK; - - bp = buff; - - if (state->in_count == 0) { - state->cur_code = *bp++; - ++state->in_count; - --length; - } - - while (length--) { - c = *bp++; - state->in_count++; - state->cur_fcode = (c << 16) | state->cur_code; - i = ((c << HSHIFT) ^ state->cur_code); /* Xor hashing. */ - - if (state->hashtab[i] == state->cur_fcode) { - state->cur_code = state->codetab[i]; - continue; - } - if (state->hashtab[i] < 0) /* Empty slot. */ - goto nomatch; - /* Secondary hash (after G. Knott). */ - if (i == 0) - disp = 1; - else - disp = HSIZE - i; - probe: - if ((i -= disp) < 0) - i += HSIZE; - - if (state->hashtab[i] == state->cur_fcode) { - state->cur_code = state->codetab[i]; - continue; - } - if (state->hashtab[i] >= 0) - goto probe; - nomatch: - ret = output_code(f, state->cur_code); - if (ret != ARCHIVE_OK) - return ret; - state->cur_code = c; - if (state->first_free < state->max_maxcode) { - state->codetab[i] = state->first_free++; /* code -> hashtable */ - state->hashtab[i] = state->cur_fcode; - continue; - } - if (state->in_count < state->checkpoint) - continue; - - state->checkpoint = state->in_count + CHECK_GAP; - - if (state->in_count <= 0x007fffff && state->out_count != 0) - ratio = (int)(state->in_count * 256 / state->out_count); - else if ((ratio = (int)(state->out_count / 256)) == 0) - ratio = 0x7fffffff; - else - ratio = (int)(state->in_count / ratio); - - if (ratio > state->compress_ratio) - state->compress_ratio = ratio; - else { - state->compress_ratio = 0; - memset(state->hashtab, 0xff, sizeof(state->hashtab)); - state->first_free = FIRST; - ret = output_code(f, CLEAR); - if (ret != ARCHIVE_OK) - return ret; - } - } - - return (ARCHIVE_OK); -} - - -/* - * Finish the compression... - */ -static int -archive_compressor_compress_close(struct archive_write_filter *f) -{ - struct private_data *state = (struct private_data *)f->data; - int ret; - - ret = output_code(f, state->cur_code); - if (ret != ARCHIVE_OK) - return ret; - ret = output_flush(f); - if (ret != ARCHIVE_OK) - return ret; - - /* Write the last block */ - ret = __archive_write_filter(f->next_filter, - state->compressed, state->compressed_offset); - return (ret); -} - -static int -archive_compressor_compress_free(struct archive_write_filter *f) -{ - struct private_data *state = (struct private_data *)f->data; - - free(state->compressed); - free(state); - return (ARCHIVE_OK); -} diff --git a/thirdparty/libarchive/libarchive/archive_write_add_filter_grzip.c b/thirdparty/libarchive/libarchive/archive_write_add_filter_grzip.c deleted file mode 100644 index 371102d74..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_add_filter_grzip.c +++ /dev/null @@ -1,135 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif - -#include "archive.h" -#include "archive_write_private.h" - -struct write_grzip { - struct archive_write_program_data *pdata; -}; - -static int archive_write_grzip_open(struct archive_write_filter *); -static int archive_write_grzip_options(struct archive_write_filter *, - const char *, const char *); -static int archive_write_grzip_write(struct archive_write_filter *, - const void *, size_t); -static int archive_write_grzip_close(struct archive_write_filter *); -static int archive_write_grzip_free(struct archive_write_filter *); - -int -archive_write_add_filter_grzip(struct archive *_a) -{ - struct archive_write_filter *f = __archive_write_allocate_filter(_a); - struct write_grzip *data; - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_add_filter_grzip"); - - data = calloc(1, sizeof(*data)); - if (data == NULL) { - archive_set_error(_a, ENOMEM, "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - data->pdata = __archive_write_program_allocate("grzip"); - if (data->pdata == NULL) { - free(data); - archive_set_error(_a, ENOMEM, "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - - f->name = "grzip"; - f->code = ARCHIVE_FILTER_GRZIP; - f->data = data; - f->open = archive_write_grzip_open; - f->options = archive_write_grzip_options; - f->write = archive_write_grzip_write; - f->close = archive_write_grzip_close; - f->free = archive_write_grzip_free; - - /* Note: This filter always uses an external program, so we - * return "warn" to inform of the fact. */ - archive_set_error(_a, ARCHIVE_ERRNO_MISC, - "Using external grzip program for grzip compression"); - return (ARCHIVE_WARN); -} - -static int -archive_write_grzip_options(struct archive_write_filter *f, const char *key, - const char *value) -{ - (void)f; /* UNUSED */ - (void)key; /* UNUSED */ - (void)value; /* UNUSED */ - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -static int -archive_write_grzip_open(struct archive_write_filter *f) -{ - struct write_grzip *data = (struct write_grzip *)f->data; - - return __archive_write_program_open(f, data->pdata, "grzip"); -} - -static int -archive_write_grzip_write(struct archive_write_filter *f, - const void *buff, size_t length) -{ - struct write_grzip *data = (struct write_grzip *)f->data; - - return __archive_write_program_write(f, data->pdata, buff, length); -} - -static int -archive_write_grzip_close(struct archive_write_filter *f) -{ - struct write_grzip *data = (struct write_grzip *)f->data; - - return __archive_write_program_close(f, data->pdata); -} - -static int -archive_write_grzip_free(struct archive_write_filter *f) -{ - struct write_grzip *data = (struct write_grzip *)f->data; - - __archive_write_program_free(data->pdata); - free(data); - return (ARCHIVE_OK); -} diff --git a/thirdparty/libarchive/libarchive/archive_write_add_filter_gzip.c b/thirdparty/libarchive/libarchive/archive_write_add_filter_gzip.c deleted file mode 100644 index 8670d5ca7..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_add_filter_gzip.c +++ /dev/null @@ -1,442 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_gzip.c 201081 2009-12-28 02:04:42Z kientzle $"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#include -#ifdef HAVE_ZLIB_H -#include -#endif - -#include "archive.h" -#include "archive_private.h" -#include "archive_string.h" -#include "archive_write_private.h" - -#if ARCHIVE_VERSION_NUMBER < 4000000 -int -archive_write_set_compression_gzip(struct archive *a) -{ - __archive_write_filters_free(a); - return (archive_write_add_filter_gzip(a)); -} -#endif - -/* Don't compile this if we don't have zlib. */ - -struct private_data { - int compression_level; - int timestamp; -#ifdef HAVE_ZLIB_H - z_stream stream; - int64_t total_in; - unsigned char *compressed; - size_t compressed_buffer_size; - unsigned long crc; -#else - struct archive_write_program_data *pdata; -#endif -}; - -/* - * Yuck. zlib.h is not const-correct, so I need this one bit - * of ugly hackery to convert a const * pointer to a non-const pointer. - */ -#define SET_NEXT_IN(st,src) \ - (st)->stream.next_in = (Bytef *)(uintptr_t)(const void *)(src) - -static int archive_compressor_gzip_options(struct archive_write_filter *, - const char *, const char *); -static int archive_compressor_gzip_open(struct archive_write_filter *); -static int archive_compressor_gzip_write(struct archive_write_filter *, - const void *, size_t); -static int archive_compressor_gzip_close(struct archive_write_filter *); -static int archive_compressor_gzip_free(struct archive_write_filter *); -#ifdef HAVE_ZLIB_H -static int drive_compressor(struct archive_write_filter *, - struct private_data *, int finishing); -#endif - - -/* - * Add a gzip compression filter to this write handle. - */ -int -archive_write_add_filter_gzip(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - struct archive_write_filter *f = __archive_write_allocate_filter(_a); - struct private_data *data; - archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_add_filter_gzip"); - - data = calloc(1, sizeof(*data)); - if (data == NULL) { - archive_set_error(&a->archive, ENOMEM, "Out of memory"); - return (ARCHIVE_FATAL); - } - f->data = data; - f->open = &archive_compressor_gzip_open; - f->options = &archive_compressor_gzip_options; - f->close = &archive_compressor_gzip_close; - f->free = &archive_compressor_gzip_free; - f->code = ARCHIVE_FILTER_GZIP; - f->name = "gzip"; -#ifdef HAVE_ZLIB_H - data->compression_level = Z_DEFAULT_COMPRESSION; - return (ARCHIVE_OK); -#else - data->pdata = __archive_write_program_allocate("gzip"); - if (data->pdata == NULL) { - free(data); - archive_set_error(&a->archive, ENOMEM, "Out of memory"); - return (ARCHIVE_FATAL); - } - data->compression_level = 0; - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Using external gzip program"); - return (ARCHIVE_WARN); -#endif -} - -static int -archive_compressor_gzip_free(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; - -#ifdef HAVE_ZLIB_H - free(data->compressed); -#else - __archive_write_program_free(data->pdata); -#endif - free(data); - f->data = NULL; - return (ARCHIVE_OK); -} - -/* - * Set write options. - */ -static int -archive_compressor_gzip_options(struct archive_write_filter *f, const char *key, - const char *value) -{ - struct private_data *data = (struct private_data *)f->data; - - if (strcmp(key, "compression-level") == 0) { - if (value == NULL || !(value[0] >= '0' && value[0] <= '9') || - value[1] != '\0') - return (ARCHIVE_WARN); - data->compression_level = value[0] - '0'; - return (ARCHIVE_OK); - } - if (strcmp(key, "timestamp") == 0) { - data->timestamp = (value == NULL)?-1:1; - return (ARCHIVE_OK); - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -#ifdef HAVE_ZLIB_H -/* - * Setup callback. - */ -static int -archive_compressor_gzip_open(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; - int ret; - - if (data->compressed == NULL) { - size_t bs = 65536, bpb; - if (f->archive->magic == ARCHIVE_WRITE_MAGIC) { - /* Buffer size should be a multiple number of - * the of bytes per block for performance. */ - bpb = archive_write_get_bytes_per_block(f->archive); - if (bpb > bs) - bs = bpb; - else if (bpb != 0) - bs -= bs % bpb; - } - data->compressed_buffer_size = bs; - data->compressed - = (unsigned char *)malloc(data->compressed_buffer_size); - if (data->compressed == NULL) { - archive_set_error(f->archive, ENOMEM, - "Can't allocate data for compression buffer"); - return (ARCHIVE_FATAL); - } - } - - data->crc = crc32(0L, NULL, 0); - data->stream.next_out = data->compressed; - data->stream.avail_out = (uInt)data->compressed_buffer_size; - - /* Prime output buffer with a gzip header. */ - data->compressed[0] = 0x1f; /* GZip signature bytes */ - data->compressed[1] = 0x8b; - data->compressed[2] = 0x08; /* "Deflate" compression */ - data->compressed[3] = 0; /* No options */ - if (data->timestamp >= 0) { - time_t t = time(NULL); - data->compressed[4] = (uint8_t)(t)&0xff; /* Timestamp */ - data->compressed[5] = (uint8_t)(t>>8)&0xff; - data->compressed[6] = (uint8_t)(t>>16)&0xff; - data->compressed[7] = (uint8_t)(t>>24)&0xff; - } else - memset(&data->compressed[4], 0, 4); - if (data->compression_level == 9) - data->compressed[8] = 2; - else if(data->compression_level == 1) - data->compressed[8] = 4; - else - data->compressed[8] = 0; - data->compressed[9] = 3; /* OS=Unix */ - data->stream.next_out += 10; - data->stream.avail_out -= 10; - - f->write = archive_compressor_gzip_write; - - /* Initialize compression library. */ - ret = deflateInit2(&(data->stream), - data->compression_level, - Z_DEFLATED, - -15 /* < 0 to suppress zlib header */, - 8, - Z_DEFAULT_STRATEGY); - - if (ret == Z_OK) { - f->data = data; - return (ARCHIVE_OK); - } - - /* Library setup failed: clean up. */ - archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, "Internal error " - "initializing compression library"); - - /* Override the error message if we know what really went wrong. */ - switch (ret) { - case Z_STREAM_ERROR: - archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, - "Internal error initializing " - "compression library: invalid setup parameter"); - break; - case Z_MEM_ERROR: - archive_set_error(f->archive, ENOMEM, - "Internal error initializing compression library"); - break; - case Z_VERSION_ERROR: - archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, - "Internal error initializing " - "compression library: invalid library version"); - break; - } - - return (ARCHIVE_FATAL); -} - -/* - * Write data to the compressed stream. - */ -static int -archive_compressor_gzip_write(struct archive_write_filter *f, const void *buff, - size_t length) -{ - struct private_data *data = (struct private_data *)f->data; - int ret; - - /* Update statistics */ - data->crc = crc32(data->crc, (const Bytef *)buff, (uInt)length); - data->total_in += length; - - /* Compress input data to output buffer */ - SET_NEXT_IN(data, buff); - data->stream.avail_in = (uInt)length; - if ((ret = drive_compressor(f, data, 0)) != ARCHIVE_OK) - return (ret); - - return (ARCHIVE_OK); -} - -/* - * Finish the compression... - */ -static int -archive_compressor_gzip_close(struct archive_write_filter *f) -{ - unsigned char trailer[8]; - struct private_data *data = (struct private_data *)f->data; - int ret; - - /* Finish compression cycle */ - ret = drive_compressor(f, data, 1); - if (ret == ARCHIVE_OK) { - /* Write the last compressed data. */ - ret = __archive_write_filter(f->next_filter, - data->compressed, - data->compressed_buffer_size - data->stream.avail_out); - } - if (ret == ARCHIVE_OK) { - /* Build and write out 8-byte trailer. */ - trailer[0] = (uint8_t)(data->crc)&0xff; - trailer[1] = (uint8_t)(data->crc >> 8)&0xff; - trailer[2] = (uint8_t)(data->crc >> 16)&0xff; - trailer[3] = (uint8_t)(data->crc >> 24)&0xff; - trailer[4] = (uint8_t)(data->total_in)&0xff; - trailer[5] = (uint8_t)(data->total_in >> 8)&0xff; - trailer[6] = (uint8_t)(data->total_in >> 16)&0xff; - trailer[7] = (uint8_t)(data->total_in >> 24)&0xff; - ret = __archive_write_filter(f->next_filter, trailer, 8); - } - - switch (deflateEnd(&(data->stream))) { - case Z_OK: - break; - default: - archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, - "Failed to clean up compressor"); - ret = ARCHIVE_FATAL; - } - return ret; -} - -/* - * Utility function to push input data through compressor, - * writing full output blocks as necessary. - * - * Note that this handles both the regular write case (finishing == - * false) and the end-of-archive case (finishing == true). - */ -static int -drive_compressor(struct archive_write_filter *f, - struct private_data *data, int finishing) -{ - int ret; - - for (;;) { - if (data->stream.avail_out == 0) { - ret = __archive_write_filter(f->next_filter, - data->compressed, - data->compressed_buffer_size); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - data->stream.next_out = data->compressed; - data->stream.avail_out = - (uInt)data->compressed_buffer_size; - } - - /* If there's nothing to do, we're done. */ - if (!finishing && data->stream.avail_in == 0) - return (ARCHIVE_OK); - - ret = deflate(&(data->stream), - finishing ? Z_FINISH : Z_NO_FLUSH ); - - switch (ret) { - case Z_OK: - /* In non-finishing case, check if compressor - * consumed everything */ - if (!finishing && data->stream.avail_in == 0) - return (ARCHIVE_OK); - /* In finishing case, this return always means - * there's more work */ - break; - case Z_STREAM_END: - /* This return can only occur in finishing case. */ - return (ARCHIVE_OK); - default: - /* Any other return value indicates an error. */ - archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, - "GZip compression failed:" - " deflate() call returned status %d", - ret); - return (ARCHIVE_FATAL); - } - } -} - -#else /* HAVE_ZLIB_H */ - -static int -archive_compressor_gzip_open(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; - struct archive_string as; - int r; - - archive_string_init(&as); - archive_strcpy(&as, "gzip"); - - /* Specify compression level. */ - if (data->compression_level > 0) { - archive_strcat(&as, " -"); - archive_strappend_char(&as, '0' + data->compression_level); - } - if (data->timestamp < 0) - /* Do not save timestamp. */ - archive_strcat(&as, " -n"); - else if (data->timestamp > 0) - /* Save timestamp. */ - archive_strcat(&as, " -N"); - - f->write = archive_compressor_gzip_write; - r = __archive_write_program_open(f, data->pdata, as.s); - archive_string_free(&as); - return (r); -} - -static int -archive_compressor_gzip_write(struct archive_write_filter *f, const void *buff, - size_t length) -{ - struct private_data *data = (struct private_data *)f->data; - - return __archive_write_program_write(f, data->pdata, buff, length); -} - -static int -archive_compressor_gzip_close(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; - - return __archive_write_program_close(f, data->pdata); -} - -#endif /* HAVE_ZLIB_H */ diff --git a/thirdparty/libarchive/libarchive/archive_write_add_filter_lrzip.c b/thirdparty/libarchive/libarchive/archive_write_add_filter_lrzip.c deleted file mode 100644 index e215f8903..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_add_filter_lrzip.c +++ /dev/null @@ -1,197 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "archive.h" -#include "archive_string.h" -#include "archive_write_private.h" - -struct write_lrzip { - struct archive_write_program_data *pdata; - int compression_level; - enum { lzma = 0, bzip2, gzip, lzo, none, zpaq } compression; -}; - -static int archive_write_lrzip_open(struct archive_write_filter *); -static int archive_write_lrzip_options(struct archive_write_filter *, - const char *, const char *); -static int archive_write_lrzip_write(struct archive_write_filter *, - const void *, size_t); -static int archive_write_lrzip_close(struct archive_write_filter *); -static int archive_write_lrzip_free(struct archive_write_filter *); - -int -archive_write_add_filter_lrzip(struct archive *_a) -{ - struct archive_write_filter *f = __archive_write_allocate_filter(_a); - struct write_lrzip *data; - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_add_filter_lrzip"); - - data = calloc(1, sizeof(*data)); - if (data == NULL) { - archive_set_error(_a, ENOMEM, "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - data->pdata = __archive_write_program_allocate("lrzip"); - if (data->pdata == NULL) { - free(data); - archive_set_error(_a, ENOMEM, "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - - f->name = "lrzip"; - f->code = ARCHIVE_FILTER_LRZIP; - f->data = data; - f->open = archive_write_lrzip_open; - f->options = archive_write_lrzip_options; - f->write = archive_write_lrzip_write; - f->close = archive_write_lrzip_close; - f->free = archive_write_lrzip_free; - - /* Note: This filter always uses an external program, so we - * return "warn" to inform of the fact. */ - archive_set_error(_a, ARCHIVE_ERRNO_MISC, - "Using external lrzip program for lrzip compression"); - return (ARCHIVE_WARN); -} - -static int -archive_write_lrzip_options(struct archive_write_filter *f, const char *key, - const char *value) -{ - struct write_lrzip *data = (struct write_lrzip *)f->data; - - if (strcmp(key, "compression") == 0) { - if (value == NULL) - return (ARCHIVE_WARN); - else if (strcmp(value, "bzip2") == 0) - data->compression = bzip2; - else if (strcmp(value, "gzip") == 0) - data->compression = gzip; - else if (strcmp(value, "lzo") == 0) - data->compression = lzo; - else if (strcmp(value, "none") == 0) - data->compression = none; - else if (strcmp(value, "zpaq") == 0) - data->compression = zpaq; - else - return (ARCHIVE_WARN); - return (ARCHIVE_OK); - } else if (strcmp(key, "compression-level") == 0) { - if (value == NULL || !(value[0] >= '1' && value[0] <= '9') || - value[1] != '\0') - return (ARCHIVE_WARN); - data->compression_level = value[0] - '0'; - return (ARCHIVE_OK); - } - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -static int -archive_write_lrzip_open(struct archive_write_filter *f) -{ - struct write_lrzip *data = (struct write_lrzip *)f->data; - struct archive_string as; - int r; - - archive_string_init(&as); - archive_strcpy(&as, "lrzip -q"); - - /* Specify compression type. */ - switch (data->compression) { - case lzma:/* default compression */ - break; - case bzip2: - archive_strcat(&as, " -b"); - break; - case gzip: - archive_strcat(&as, " -g"); - break; - case lzo: - archive_strcat(&as, " -l"); - break; - case none: - archive_strcat(&as, " -n"); - break; - case zpaq: - archive_strcat(&as, " -z"); - break; - } - - /* Specify compression level. */ - if (data->compression_level > 0) { - archive_strcat(&as, " -L "); - archive_strappend_char(&as, '0' + data->compression_level); - } - - r = __archive_write_program_open(f, data->pdata, as.s); - archive_string_free(&as); - return (r); -} - -static int -archive_write_lrzip_write(struct archive_write_filter *f, - const void *buff, size_t length) -{ - struct write_lrzip *data = (struct write_lrzip *)f->data; - - return __archive_write_program_write(f, data->pdata, buff, length); -} - -static int -archive_write_lrzip_close(struct archive_write_filter *f) -{ - struct write_lrzip *data = (struct write_lrzip *)f->data; - - return __archive_write_program_close(f, data->pdata); -} - -static int -archive_write_lrzip_free(struct archive_write_filter *f) -{ - struct write_lrzip *data = (struct write_lrzip *)f->data; - - __archive_write_program_free(data->pdata); - free(data); - return (ARCHIVE_OK); -} diff --git a/thirdparty/libarchive/libarchive/archive_write_add_filter_lz4.c b/thirdparty/libarchive/libarchive/archive_write_add_filter_lz4.c deleted file mode 100644 index 6ac450357..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_add_filter_lz4.c +++ /dev/null @@ -1,700 +0,0 @@ -/*- - * Copyright (c) 2014 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_LZ4_H -#include -#endif -#ifdef HAVE_LZ4HC_H -#include -#endif - -#include "archive.h" -#include "archive_endian.h" -#include "archive_private.h" -#include "archive_write_private.h" -#include "archive_xxhash.h" - -#define LZ4_MAGICNUMBER 0x184d2204 - -struct private_data { - int compression_level; - unsigned header_written:1; - unsigned version_number:1; - unsigned block_independence:1; - unsigned block_checksum:1; - unsigned stream_size:1; - unsigned stream_checksum:1; - unsigned preset_dictionary:1; - unsigned block_maximum_size:3; -#if defined(HAVE_LIBLZ4) && LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 2 - int64_t total_in; - char *out; - char *out_buffer; - size_t out_buffer_size; - size_t out_block_size; - char *in; - char *in_buffer_allocated; - char *in_buffer; - size_t in_buffer_size; - size_t block_size; - - void *xxh32_state; - void *lz4_stream; -#else - struct archive_write_program_data *pdata; -#endif -}; - -static int archive_filter_lz4_close(struct archive_write_filter *); -static int archive_filter_lz4_free(struct archive_write_filter *); -static int archive_filter_lz4_open(struct archive_write_filter *); -static int archive_filter_lz4_options(struct archive_write_filter *, - const char *, const char *); -static int archive_filter_lz4_write(struct archive_write_filter *, - const void *, size_t); - -/* - * Add a lz4 compression filter to this write handle. - */ -int -archive_write_add_filter_lz4(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - struct archive_write_filter *f = __archive_write_allocate_filter(_a); - struct private_data *data; - - archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_add_filter_lz4"); - - data = calloc(1, sizeof(*data)); - if (data == NULL) { - archive_set_error(&a->archive, ENOMEM, "Out of memory"); - return (ARCHIVE_FATAL); - } - - /* - * Setup default settings. - */ - data->compression_level = 1; - data->version_number = 0x01; - data->block_independence = 1; - data->block_checksum = 0; - data->stream_size = 0; - data->stream_checksum = 1; - data->preset_dictionary = 0; - data->block_maximum_size = 7; - - /* - * Setup a filter setting. - */ - f->data = data; - f->options = &archive_filter_lz4_options; - f->close = &archive_filter_lz4_close; - f->free = &archive_filter_lz4_free; - f->open = &archive_filter_lz4_open; - f->code = ARCHIVE_FILTER_LZ4; - f->name = "lz4"; -#if defined(HAVE_LIBLZ4) && LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 2 - return (ARCHIVE_OK); -#else - /* - * We don't have lz4 library, and execute external lz4 program - * instead. - */ - data->pdata = __archive_write_program_allocate("lz4"); - if (data->pdata == NULL) { - free(data); - archive_set_error(&a->archive, ENOMEM, "Out of memory"); - return (ARCHIVE_FATAL); - } - data->compression_level = 0; - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Using external lz4 program"); - return (ARCHIVE_WARN); -#endif -} - -/* - * Set write options. - */ -static int -archive_filter_lz4_options(struct archive_write_filter *f, - const char *key, const char *value) -{ - struct private_data *data = (struct private_data *)f->data; - - if (strcmp(key, "compression-level") == 0) { - int val; - if (value == NULL || !((val = value[0] - '0') >= 1 && val <= 9) || - value[1] != '\0') - return (ARCHIVE_WARN); - -#ifndef HAVE_LZ4HC_H - if(val >= 3) - { - archive_set_error(f->archive, ARCHIVE_ERRNO_PROGRAMMER, - "High compression not included in this build"); - return (ARCHIVE_FATAL); - } -#endif - data->compression_level = val; - return (ARCHIVE_OK); - } - if (strcmp(key, "stream-checksum") == 0) { - data->stream_checksum = value != NULL; - return (ARCHIVE_OK); - } - if (strcmp(key, "block-checksum") == 0) { - data->block_checksum = value != NULL; - return (ARCHIVE_OK); - } - if (strcmp(key, "block-size") == 0) { - if (value == NULL || !(value[0] >= '4' && value[0] <= '7') || - value[1] != '\0') - return (ARCHIVE_WARN); - data->block_maximum_size = value[0] - '0'; - return (ARCHIVE_OK); - } - if (strcmp(key, "block-dependence") == 0) { - data->block_independence = value == NULL; - return (ARCHIVE_OK); - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -#if defined(HAVE_LIBLZ4) && LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 2 -/* Don't compile this if we don't have liblz4. */ - -static int drive_compressor(struct archive_write_filter *, const char *, - size_t); -static int drive_compressor_independence(struct archive_write_filter *, - const char *, size_t); -static int drive_compressor_dependence(struct archive_write_filter *, - const char *, size_t); -static int lz4_write_stream_descriptor(struct archive_write_filter *); -static ssize_t lz4_write_one_block(struct archive_write_filter *, const char *, - size_t); - - -/* - * Setup callback. - */ -static int -archive_filter_lz4_open(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; - size_t required_size; - static size_t const bkmap[] = { 64 * 1024, 256 * 1024, 1 * 1024 * 1024, - 4 * 1024 * 1024 }; - size_t pre_block_size; - - if (data->block_maximum_size < 4) - data->block_size = bkmap[0]; - else - data->block_size = bkmap[data->block_maximum_size - 4]; - - required_size = 4 + 15 + 4 + data->block_size + 4 + 4; - if (data->out_buffer_size < required_size) { - size_t bs = required_size, bpb; - free(data->out_buffer); - if (f->archive->magic == ARCHIVE_WRITE_MAGIC) { - /* Buffer size should be a multiple number of - * the of bytes per block for performance. */ - bpb = archive_write_get_bytes_per_block(f->archive); - if (bpb > bs) - bs = bpb; - else if (bpb != 0) { - bs += bpb; - bs -= bs % bpb; - } - } - data->out_block_size = bs; - bs += required_size; - data->out_buffer = malloc(bs); - data->out = data->out_buffer; - data->out_buffer_size = bs; - } - - pre_block_size = (data->block_independence)? 0: 64 * 1024; - if (data->in_buffer_size < data->block_size + pre_block_size) { - free(data->in_buffer_allocated); - data->in_buffer_size = data->block_size; - data->in_buffer_allocated = - malloc(data->in_buffer_size + pre_block_size); - data->in_buffer = data->in_buffer_allocated + pre_block_size; - if (!data->block_independence && data->compression_level >= 3) - data->in_buffer = data->in_buffer_allocated; - data->in = data->in_buffer; - data->in_buffer_size = data->block_size; - } - - if (data->out_buffer == NULL || data->in_buffer_allocated == NULL) { - archive_set_error(f->archive, ENOMEM, - "Can't allocate data for compression buffer"); - return (ARCHIVE_FATAL); - } - - f->write = archive_filter_lz4_write; - - return (ARCHIVE_OK); -} - -/* - * Write data to the out stream. - * - * Returns ARCHIVE_OK if all data written, error otherwise. - */ -static int -archive_filter_lz4_write(struct archive_write_filter *f, - const void *buff, size_t length) -{ - struct private_data *data = (struct private_data *)f->data; - int ret = ARCHIVE_OK; - const char *p; - size_t remaining; - ssize_t size; - - /* If we haven't written a stream descriptor, we have to do it first. */ - if (!data->header_written) { - ret = lz4_write_stream_descriptor(f); - if (ret != ARCHIVE_OK) - return (ret); - data->header_written = 1; - } - - /* Update statistics */ - data->total_in += length; - - p = (const char *)buff; - remaining = length; - while (remaining) { - size_t l; - /* Compress input data to output buffer */ - size = lz4_write_one_block(f, p, remaining); - if (size < ARCHIVE_OK) - return (ARCHIVE_FATAL); - l = data->out - data->out_buffer; - if (l >= data->out_block_size) { - ret = __archive_write_filter(f->next_filter, - data->out_buffer, data->out_block_size); - l -= data->out_block_size; - memcpy(data->out_buffer, - data->out_buffer + data->out_block_size, l); - data->out = data->out_buffer + l; - if (ret < ARCHIVE_WARN) - break; - } - p += size; - remaining -= size; - } - - return (ret); -} - -/* - * Finish the compression. - */ -static int -archive_filter_lz4_close(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; - int ret; - - /* Finish compression cycle. */ - ret = (int)lz4_write_one_block(f, NULL, 0); - if (ret >= 0) { - /* - * Write the last block and the end of the stream data. - */ - - /* Write End Of Stream. */ - memset(data->out, 0, 4); data->out += 4; - /* Write Stream checksum if needed. */ - if (data->stream_checksum) { - unsigned int checksum; - checksum = __archive_xxhash.XXH32_digest( - data->xxh32_state); - data->xxh32_state = NULL; - archive_le32enc(data->out, checksum); - data->out += 4; - } - ret = __archive_write_filter(f->next_filter, - data->out_buffer, data->out - data->out_buffer); - } - return ret; -} - -static int -archive_filter_lz4_free(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; - - if (data->lz4_stream != NULL) { -#ifdef HAVE_LZ4HC_H - if (data->compression_level >= 3) -#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7 - LZ4_freeStreamHC(data->lz4_stream); -#else - LZ4_freeHC(data->lz4_stream); -#endif - else -#endif -#if LZ4_VERSION_MINOR >= 3 - LZ4_freeStream(data->lz4_stream); -#else - LZ4_free(data->lz4_stream); -#endif - } - free(data->out_buffer); - free(data->in_buffer_allocated); - free(data->xxh32_state); - free(data); - f->data = NULL; - return (ARCHIVE_OK); -} - -static int -lz4_write_stream_descriptor(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; - uint8_t *sd; - - sd = (uint8_t *)data->out; - /* Write Magic Number. */ - archive_le32enc(&sd[0], LZ4_MAGICNUMBER); - /* FLG */ - sd[4] = (data->version_number << 6) - | (data->block_independence << 5) - | (data->block_checksum << 4) - | (data->stream_size << 3) - | (data->stream_checksum << 2) - | (data->preset_dictionary << 0); - /* BD */ - sd[5] = (data->block_maximum_size << 4); - sd[6] = (__archive_xxhash.XXH32(&sd[4], 2, 0) >> 8) & 0xff; - data->out += 7; - if (data->stream_checksum) - data->xxh32_state = __archive_xxhash.XXH32_init(0); - else - data->xxh32_state = NULL; - return (ARCHIVE_OK); -} - -static ssize_t -lz4_write_one_block(struct archive_write_filter *f, const char *p, - size_t length) -{ - struct private_data *data = (struct private_data *)f->data; - ssize_t r; - - if (p == NULL) { - /* Compress remaining uncompressed data. */ - if (data->in_buffer == data->in) - return 0; - else { - size_t l = data->in - data->in_buffer; - r = drive_compressor(f, data->in_buffer, l); - if (r == ARCHIVE_OK) - r = (ssize_t)l; - } - } else if ((data->block_independence || data->compression_level < 3) && - data->in_buffer == data->in && length >= data->block_size) { - r = drive_compressor(f, p, data->block_size); - if (r == ARCHIVE_OK) - r = (ssize_t)data->block_size; - } else { - size_t remaining_size = data->in_buffer_size - - (data->in - data->in_buffer); - size_t l = (remaining_size > length)? length: remaining_size; - memcpy(data->in, p, l); - data->in += l; - if (l == remaining_size) { - r = drive_compressor(f, data->in_buffer, - data->block_size); - if (r == ARCHIVE_OK) - r = (ssize_t)l; - data->in = data->in_buffer; - } else - r = (ssize_t)l; - } - - return (r); -} - - -/* - * Utility function to push input data through compressor, writing - * full output blocks as necessary. - * - * Note that this handles both the regular write case (finishing == - * false) and the end-of-archive case (finishing == true). - */ -static int -drive_compressor(struct archive_write_filter *f, const char *p, size_t length) -{ - struct private_data *data = (struct private_data *)f->data; - - if (data->stream_checksum) - __archive_xxhash.XXH32_update(data->xxh32_state, - p, (int)length); - if (data->block_independence) - return drive_compressor_independence(f, p, length); - else - return drive_compressor_dependence(f, p, length); -} - -static int -drive_compressor_independence(struct archive_write_filter *f, const char *p, - size_t length) -{ - struct private_data *data = (struct private_data *)f->data; - unsigned int outsize; - -#ifdef HAVE_LZ4HC_H - if (data->compression_level >= 3) -#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7 - outsize = LZ4_compress_HC(p, data->out + 4, - (int)length, (int)data->block_size, - data->compression_level); -#else - outsize = LZ4_compressHC2_limitedOutput(p, data->out + 4, - (int)length, (int)data->block_size, - data->compression_level); -#endif - else -#endif -#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7 - outsize = LZ4_compress_default(p, data->out + 4, - (int)length, (int)data->block_size); -#else - outsize = LZ4_compress_limitedOutput(p, data->out + 4, - (int)length, (int)data->block_size); -#endif - - if (outsize) { - /* The buffer is compressed. */ - archive_le32enc(data->out, outsize); - data->out += 4; - } else { - /* The buffer is not compressed. The compressed size was - * bigger than its uncompressed size. */ - archive_le32enc(data->out, (uint32_t)(length | 0x80000000)); - data->out += 4; - memcpy(data->out, p, length); - outsize = (uint32_t)length; - } - data->out += outsize; - if (data->block_checksum) { - unsigned int checksum = - __archive_xxhash.XXH32(data->out - outsize, outsize, 0); - archive_le32enc(data->out, checksum); - data->out += 4; - } - return (ARCHIVE_OK); -} - -static int -drive_compressor_dependence(struct archive_write_filter *f, const char *p, - size_t length) -{ - struct private_data *data = (struct private_data *)f->data; - int outsize; - -#define DICT_SIZE (64 * 1024) -#ifdef HAVE_LZ4HC_H - if (data->compression_level >= 3) { - if (data->lz4_stream == NULL) { -#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7 - data->lz4_stream = LZ4_createStreamHC(); - LZ4_resetStreamHC(data->lz4_stream, data->compression_level); -#else - data->lz4_stream = - LZ4_createHC(data->in_buffer_allocated); -#endif - if (data->lz4_stream == NULL) { - archive_set_error(f->archive, ENOMEM, - "Can't allocate data for compression" - " buffer"); - return (ARCHIVE_FATAL); - } - } - else - LZ4_loadDictHC(data->lz4_stream, data->in_buffer_allocated, DICT_SIZE); - -#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7 - outsize = LZ4_compress_HC_continue( - data->lz4_stream, p, data->out + 4, (int)length, - (int)data->block_size); -#else - outsize = LZ4_compressHC2_limitedOutput_continue( - data->lz4_stream, p, data->out + 4, (int)length, - (int)data->block_size, data->compression_level); -#endif - } else -#endif - { - if (data->lz4_stream == NULL) { - data->lz4_stream = LZ4_createStream(); - if (data->lz4_stream == NULL) { - archive_set_error(f->archive, ENOMEM, - "Can't allocate data for compression" - " buffer"); - return (ARCHIVE_FATAL); - } - } - else - LZ4_loadDict(data->lz4_stream, data->in_buffer_allocated, DICT_SIZE); - -#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7 - outsize = LZ4_compress_fast_continue( - data->lz4_stream, p, data->out + 4, (int)length, - (int)data->block_size, 1); -#else - outsize = LZ4_compress_limitedOutput_continue( - data->lz4_stream, p, data->out + 4, (int)length, - (int)data->block_size); -#endif - } - - if (outsize) { - /* The buffer is compressed. */ - archive_le32enc(data->out, outsize); - data->out += 4; - } else { - /* The buffer is not compressed. The compressed size was - * bigger than its uncompressed size. */ - archive_le32enc(data->out, (uint32_t)(length | 0x80000000)); - data->out += 4; - memcpy(data->out, p, length); - outsize = (uint32_t)length; - } - data->out += outsize; - if (data->block_checksum) { - unsigned int checksum = - __archive_xxhash.XXH32(data->out - outsize, outsize, 0); - archive_le32enc(data->out, checksum); - data->out += 4; - } - - if (length == data->block_size) { -#ifdef HAVE_LZ4HC_H - if (data->compression_level >= 3) { -#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7 - LZ4_saveDictHC(data->lz4_stream, data->in_buffer_allocated, DICT_SIZE); -#else - LZ4_slideInputBufferHC(data->lz4_stream); -#endif - data->in_buffer = data->in_buffer_allocated + DICT_SIZE; - } - else -#endif - LZ4_saveDict(data->lz4_stream, - data->in_buffer_allocated, DICT_SIZE); -#undef DICT_SIZE - } - return (ARCHIVE_OK); -} - -#else /* HAVE_LIBLZ4 */ - -static int -archive_filter_lz4_open(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; - struct archive_string as; - int r; - - archive_string_init(&as); - archive_strcpy(&as, "lz4 -z -q -q"); - - /* Specify a compression level. */ - if (data->compression_level > 0) { - archive_strcat(&as, " -"); - archive_strappend_char(&as, '0' + data->compression_level); - } - /* Specify a block size. */ - archive_strcat(&as, " -B"); - archive_strappend_char(&as, '0' + data->block_maximum_size); - - if (data->block_checksum) - archive_strcat(&as, " -BX"); - if (data->stream_checksum == 0) - archive_strcat(&as, " --no-frame-crc"); - if (data->block_independence == 0) - archive_strcat(&as, " -BD"); - - f->write = archive_filter_lz4_write; - - r = __archive_write_program_open(f, data->pdata, as.s); - archive_string_free(&as); - return (r); -} - -static int -archive_filter_lz4_write(struct archive_write_filter *f, const void *buff, - size_t length) -{ - struct private_data *data = (struct private_data *)f->data; - - return __archive_write_program_write(f, data->pdata, buff, length); -} - -static int -archive_filter_lz4_close(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; - - return __archive_write_program_close(f, data->pdata); -} - -static int -archive_filter_lz4_free(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; - - __archive_write_program_free(data->pdata); - free(data); - return (ARCHIVE_OK); -} - -#endif /* HAVE_LIBLZ4 */ diff --git a/thirdparty/libarchive/libarchive/archive_write_add_filter_lzop.c b/thirdparty/libarchive/libarchive/archive_write_add_filter_lzop.c deleted file mode 100644 index 3bd9062e4..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_add_filter_lzop.c +++ /dev/null @@ -1,478 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -__FBSDID("$FreeBSD$"); -//#undef HAVE_LZO_LZOCONF_H -//#undef HAVE_LZO_LZO1X_H - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#include -#ifdef HAVE_LZO_LZOCONF_H -#include -#endif -#ifdef HAVE_LZO_LZO1X_H -#include -#endif - -#include "archive.h" -#include "archive_string.h" -#include "archive_endian.h" -#include "archive_write_private.h" - -enum lzo_method { - METHOD_LZO1X_1 = 1, - METHOD_LZO1X_1_15 = 2, - METHOD_LZO1X_999 = 3 -}; -struct write_lzop { - int compression_level; -#if defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H) - unsigned char *uncompressed; - size_t uncompressed_buffer_size; - size_t uncompressed_avail_bytes; - unsigned char *compressed; - size_t compressed_buffer_size; - enum lzo_method method; - unsigned char level; - lzo_voidp work_buffer; - lzo_uint32 work_buffer_size; - char header_written; -#else - struct archive_write_program_data *pdata; -#endif -}; - -static int archive_write_lzop_open(struct archive_write_filter *); -static int archive_write_lzop_options(struct archive_write_filter *, - const char *, const char *); -static int archive_write_lzop_write(struct archive_write_filter *, - const void *, size_t); -static int archive_write_lzop_close(struct archive_write_filter *); -static int archive_write_lzop_free(struct archive_write_filter *); - -#if defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H) -/* Maximum block size. */ -#define BLOCK_SIZE (256 * 1024) -/* Block information is composed of uncompressed size(4 bytes), - * compressed size(4 bytes) and the checksum of uncompressed data(4 bytes) - * in this lzop writer. */ -#define BLOCK_INfO_SIZE 12 - -#define HEADER_VERSION 9 -#define HEADER_LIBVERSION 11 -#define HEADER_METHOD 15 -#define HEADER_LEVEL 16 -#define HEADER_MTIME_LOW 25 -#define HEADER_MTIME_HIGH 29 -#define HEADER_H_CHECKSUM 34 - -/* - * Header template. - */ -static const unsigned char header[] = { - /* LZOP Magic code 9 bytes */ - 0x89, 0x4c, 0x5a, 0x4f, 0x00, 0x0d, 0x0a, 0x1a, 0x0a, - /* LZOP utility version(fake data) 2 bytes */ - 0x10, 0x30, - /* LZO library version 2 bytes */ - 0x09, 0x40, - /* Minimum required LZO library version 2 bytes */ - 0x09, 0x40, - /* Method */ - 1, - /* Level */ - 5, - /* Flags 4 bytes - * -OS Unix - * -Stdout - * -Stdin - * -Adler32 used for uncompressed data 4 bytes */ - 0x03, 0x00, 0x00, 0x0d, - /* Mode (AE_IFREG | 0644) 4 bytes */ - 0x00, 0x00, 0x81, 0xa4, - /* Mtime low 4 bytes */ - 0x00, 0x00, 0x00, 0x00, - /* Mtime high 4 bytes */ - 0x00, 0x00, 0x00, 0x00, - /* Filename length */ - 0x00, - /* Header checksum 4 bytes */ - 0x00, 0x00, 0x00, 0x00, -}; -#endif - -int -archive_write_add_filter_lzop(struct archive *_a) -{ - struct archive_write_filter *f = __archive_write_allocate_filter(_a); - struct write_lzop *data; - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_add_filter_lzop"); - - data = calloc(1, sizeof(*data)); - if (data == NULL) { - archive_set_error(_a, ENOMEM, "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - - f->name = "lzop"; - f->code = ARCHIVE_FILTER_LZOP; - f->data = data; - f->open = archive_write_lzop_open; - f->options = archive_write_lzop_options; - f->write = archive_write_lzop_write; - f->close = archive_write_lzop_close; - f->free = archive_write_lzop_free; -#if defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H) - if (lzo_init() != LZO_E_OK) { - free(data); - archive_set_error(_a, ARCHIVE_ERRNO_MISC, - "lzo_init(type check) failed"); - return (ARCHIVE_FATAL); - } - if (lzo_version() < 0x940) { - free(data); - archive_set_error(_a, ARCHIVE_ERRNO_MISC, - "liblzo library is too old(%s < 0.940)", - lzo_version_string()); - return (ARCHIVE_FATAL); - } - data->compression_level = 5; - return (ARCHIVE_OK); -#else - data->pdata = __archive_write_program_allocate("lzop"); - if (data->pdata == NULL) { - free(data); - archive_set_error(_a, ENOMEM, "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - data->compression_level = 0; - /* Note: We return "warn" to inform of using an external lzop - * program. */ - archive_set_error(_a, ARCHIVE_ERRNO_MISC, - "Using external lzop program for lzop compression"); - return (ARCHIVE_WARN); -#endif -} - -static int -archive_write_lzop_free(struct archive_write_filter *f) -{ - struct write_lzop *data = (struct write_lzop *)f->data; - -#if defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H) - free(data->uncompressed); - free(data->compressed); - free(data->work_buffer); -#else - __archive_write_program_free(data->pdata); -#endif - free(data); - return (ARCHIVE_OK); -} - -static int -archive_write_lzop_options(struct archive_write_filter *f, const char *key, - const char *value) -{ - struct write_lzop *data = (struct write_lzop *)f->data; - - if (strcmp(key, "compression-level") == 0) { - if (value == NULL || !(value[0] >= '1' && value[0] <= '9') || - value[1] != '\0') - return (ARCHIVE_WARN); - data->compression_level = value[0] - '0'; - return (ARCHIVE_OK); - } - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -#if defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H) -static int -archive_write_lzop_open(struct archive_write_filter *f) -{ - struct write_lzop *data = (struct write_lzop *)f->data; - - switch (data->compression_level) { - case 1: - data->method = METHOD_LZO1X_1_15; data->level = 1; break; - default: - case 2: case 3: case 4: case 5: case 6: - data->method = METHOD_LZO1X_1; data->level = 5; break; - case 7: - data->method = METHOD_LZO1X_999; data->level = 7; break; - case 8: - data->method = METHOD_LZO1X_999; data->level = 8; break; - case 9: - data->method = METHOD_LZO1X_999; data->level = 9; break; - } - switch (data->method) { - case METHOD_LZO1X_1: - data->work_buffer_size = LZO1X_1_MEM_COMPRESS; break; - case METHOD_LZO1X_1_15: - data->work_buffer_size = LZO1X_1_15_MEM_COMPRESS; break; - case METHOD_LZO1X_999: - data->work_buffer_size = LZO1X_999_MEM_COMPRESS; break; - } - if (data->work_buffer == NULL) { - data->work_buffer = (lzo_voidp)malloc(data->work_buffer_size); - if (data->work_buffer == NULL) { - archive_set_error(f->archive, ENOMEM, - "Can't allocate data for compression buffer"); - return (ARCHIVE_FATAL); - } - } - if (data->compressed == NULL) { - data->compressed_buffer_size = sizeof(header) + - BLOCK_SIZE + (BLOCK_SIZE >> 4) + 64 + 3; - data->compressed = (unsigned char *) - malloc(data->compressed_buffer_size); - if (data->compressed == NULL) { - archive_set_error(f->archive, ENOMEM, - "Can't allocate data for compression buffer"); - return (ARCHIVE_FATAL); - } - } - if (data->uncompressed == NULL) { - data->uncompressed_buffer_size = BLOCK_SIZE; - data->uncompressed = (unsigned char *) - malloc(data->uncompressed_buffer_size); - if (data->uncompressed == NULL) { - archive_set_error(f->archive, ENOMEM, - "Can't allocate data for compression buffer"); - return (ARCHIVE_FATAL); - } - data->uncompressed_avail_bytes = BLOCK_SIZE; - } - return (ARCHIVE_OK); -} - -static int -make_header(struct archive_write_filter *f) -{ - struct write_lzop *data = (struct write_lzop *)f->data; - int64_t t; - uint32_t checksum; - - memcpy(data->compressed, header, sizeof(header)); - /* Overwrite library version. */ - data->compressed[HEADER_LIBVERSION] = (unsigned char ) - (lzo_version() >> 8) & 0xff; - data->compressed[HEADER_LIBVERSION + 1] = (unsigned char ) - lzo_version() & 0xff; - /* Overwrite method and level. */ - data->compressed[HEADER_METHOD] = (unsigned char)data->method; - data->compressed[HEADER_LEVEL] = data->level; - /* Overwrite mtime with current time. */ - t = (int64_t)time(NULL); - archive_be32enc(&data->compressed[HEADER_MTIME_LOW], - (uint32_t)(t & 0xffffffff)); - archive_be32enc(&data->compressed[HEADER_MTIME_HIGH], - (uint32_t)((t >> 32) & 0xffffffff)); - /* Overwrite header checksum with calculated value. */ - checksum = lzo_adler32(1, data->compressed + HEADER_VERSION, - (lzo_uint)(HEADER_H_CHECKSUM - HEADER_VERSION)); - archive_be32enc(&data->compressed[HEADER_H_CHECKSUM], checksum); - return (sizeof(header)); -} - -static int -drive_compressor(struct archive_write_filter *f) -{ - struct write_lzop *data = (struct write_lzop *)f->data; - unsigned char *p; - const int block_info_bytes = 12; - int header_bytes, r; - lzo_uint usize, csize; - uint32_t checksum; - - if (!data->header_written) { - header_bytes = make_header(f); - data->header_written = 1; - } else - header_bytes = 0; - p = data->compressed; - - usize = (lzo_uint) - (data->uncompressed_buffer_size - data->uncompressed_avail_bytes); - csize = 0; - switch (data->method) { - default: - case METHOD_LZO1X_1: - r = lzo1x_1_compress(data->uncompressed, usize, - p + header_bytes + block_info_bytes, &csize, - data->work_buffer); - break; - case METHOD_LZO1X_1_15: - r = lzo1x_1_15_compress(data->uncompressed, usize, - p + header_bytes + block_info_bytes, &csize, - data->work_buffer); - break; - case METHOD_LZO1X_999: - r = lzo1x_999_compress_level(data->uncompressed, usize, - p + header_bytes + block_info_bytes, &csize, - data->work_buffer, NULL, 0, 0, data->level); - break; - } - if (r != LZO_E_OK) { - archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, - "Lzop compression failed: returned status %d", r); - return (ARCHIVE_FATAL); - } - - /* Store uncompressed size. */ - archive_be32enc(p + header_bytes, (uint32_t)usize); - /* Store the checksum of the uncompressed data. */ - checksum = lzo_adler32(1, data->uncompressed, usize); - archive_be32enc(p + header_bytes + 8, checksum); - - if (csize < usize) { - /* Store compressed size. */ - archive_be32enc(p + header_bytes + 4, (uint32_t)csize); - r = __archive_write_filter(f->next_filter, data->compressed, - header_bytes + block_info_bytes + csize); - } else { - /* - * This case, we output uncompressed data instead. - */ - /* Store uncompressed size as compressed size. */ - archive_be32enc(p + header_bytes + 4, (uint32_t)usize); - r = __archive_write_filter(f->next_filter, data->compressed, - header_bytes + block_info_bytes); - if (r != ARCHIVE_OK) - return (ARCHIVE_FATAL); - r = __archive_write_filter(f->next_filter, data->uncompressed, - usize); - } - - if (r != ARCHIVE_OK) - return (ARCHIVE_FATAL); - return (ARCHIVE_OK); -} - -static int -archive_write_lzop_write(struct archive_write_filter *f, - const void *buff, size_t length) -{ - struct write_lzop *data = (struct write_lzop *)f->data; - const char *p = buff; - int r; - - do { - if (data->uncompressed_avail_bytes > length) { - memcpy(data->uncompressed - + data->uncompressed_buffer_size - - data->uncompressed_avail_bytes, - p, length); - data->uncompressed_avail_bytes -= length; - return (ARCHIVE_OK); - } - - memcpy(data->uncompressed + data->uncompressed_buffer_size - - data->uncompressed_avail_bytes, - p, data->uncompressed_avail_bytes); - length -= data->uncompressed_avail_bytes; - p += data->uncompressed_avail_bytes; - data->uncompressed_avail_bytes = 0; - - r = drive_compressor(f); - if (r != ARCHIVE_OK) return (r); - data->uncompressed_avail_bytes = BLOCK_SIZE; - } while (length); - - return (ARCHIVE_OK); -} - -static int -archive_write_lzop_close(struct archive_write_filter *f) -{ - struct write_lzop *data = (struct write_lzop *)f->data; - const uint32_t endmark = 0; - int r; - - if (data->uncompressed_avail_bytes < BLOCK_SIZE) { - /* Compress and output remaining data. */ - r = drive_compressor(f); - if (r != ARCHIVE_OK) - return (r); - } - /* Write a zero uncompressed size as the end mark of the series of - * compressed block. */ - return __archive_write_filter(f->next_filter, &endmark, sizeof(endmark)); -} - -#else -static int -archive_write_lzop_open(struct archive_write_filter *f) -{ - struct write_lzop *data = (struct write_lzop *)f->data; - struct archive_string as; - int r; - - archive_string_init(&as); - archive_strcpy(&as, "lzop"); - /* Specify compression level. */ - if (data->compression_level > 0) { - archive_strappend_char(&as, ' '); - archive_strappend_char(&as, '-'); - archive_strappend_char(&as, '0' + data->compression_level); - } - - r = __archive_write_program_open(f, data->pdata, as.s); - archive_string_free(&as); - return (r); -} - -static int -archive_write_lzop_write(struct archive_write_filter *f, - const void *buff, size_t length) -{ - struct write_lzop *data = (struct write_lzop *)f->data; - - return __archive_write_program_write(f, data->pdata, buff, length); -} - -static int -archive_write_lzop_close(struct archive_write_filter *f) -{ - struct write_lzop *data = (struct write_lzop *)f->data; - - return __archive_write_program_close(f, data->pdata); -} -#endif diff --git a/thirdparty/libarchive/libarchive/archive_write_add_filter_none.c b/thirdparty/libarchive/libarchive/archive_write_add_filter_none.c deleted file mode 100644 index 3c06c642e..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_add_filter_none.c +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * Copyright (c) 2003-2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_none.c 201080 2009-12-28 02:03:54Z kientzle $"); - -#include "archive.h" - -int -archive_write_set_compression_none(struct archive *a) -{ - (void)a; /* UNUSED */ - return (ARCHIVE_OK); -} - -int -archive_write_add_filter_none(struct archive *a) -{ - (void)a; /* UNUSED */ - return (ARCHIVE_OK); -} diff --git a/thirdparty/libarchive/libarchive/archive_write_add_filter_program.c b/thirdparty/libarchive/libarchive/archive_write_add_filter_program.c deleted file mode 100644 index c096e7227..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_add_filter_program.c +++ /dev/null @@ -1,391 +0,0 @@ -/*- - * Copyright (c) 2007 Joerg Sonnenberger - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_program.c 201104 2009-12-28 03:14:30Z kientzle $"); - -#ifdef HAVE_SYS_WAIT_H -# include -#endif -#ifdef HAVE_ERRNO_H -# include -#endif -#ifdef HAVE_FCNTL_H -# include -#endif -#ifdef HAVE_STDLIB_H -# include -#endif -#ifdef HAVE_STRING_H -# include -#endif - -#include "archive.h" -#include "archive_private.h" -#include "archive_string.h" -#include "archive_write_private.h" -#include "filter_fork.h" - -#if ARCHIVE_VERSION_NUMBER < 4000000 -int -archive_write_set_compression_program(struct archive *a, const char *cmd) -{ - __archive_write_filters_free(a); - return (archive_write_add_filter_program(a, cmd)); -} -#endif - -struct archive_write_program_data { -#if defined(_WIN32) && !defined(__CYGWIN__) - HANDLE child; -#else - pid_t child; -#endif - int child_stdin, child_stdout; - - char *child_buf; - size_t child_buf_len, child_buf_avail; - char *program_name; -}; - -struct private_data { - struct archive_write_program_data *pdata; - struct archive_string description; - char *cmd; -}; - -static int archive_compressor_program_open(struct archive_write_filter *); -static int archive_compressor_program_write(struct archive_write_filter *, - const void *, size_t); -static int archive_compressor_program_close(struct archive_write_filter *); -static int archive_compressor_program_free(struct archive_write_filter *); - -/* - * Add a filter to this write handle that passes all data through an - * external program. - */ -int -archive_write_add_filter_program(struct archive *_a, const char *cmd) -{ - struct archive_write_filter *f = __archive_write_allocate_filter(_a); - struct private_data *data; - static const char prefix[] = "Program: "; - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_add_filter_program"); - - f->data = calloc(1, sizeof(*data)); - if (f->data == NULL) - goto memerr; - data = (struct private_data *)f->data; - - data->cmd = strdup(cmd); - if (data->cmd == NULL) - goto memerr; - - data->pdata = __archive_write_program_allocate(cmd); - if (data->pdata == NULL) - goto memerr; - - /* Make up a description string. */ - if (archive_string_ensure(&data->description, - strlen(prefix) + strlen(cmd) + 1) == NULL) - goto memerr; - archive_strcpy(&data->description, prefix); - archive_strcat(&data->description, cmd); - - f->name = data->description.s; - f->code = ARCHIVE_FILTER_PROGRAM; - f->open = archive_compressor_program_open; - f->write = archive_compressor_program_write; - f->close = archive_compressor_program_close; - f->free = archive_compressor_program_free; - return (ARCHIVE_OK); -memerr: - archive_compressor_program_free(f); - archive_set_error(_a, ENOMEM, - "Can't allocate memory for filter program"); - return (ARCHIVE_FATAL); -} - -static int -archive_compressor_program_open(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; - - return __archive_write_program_open(f, data->pdata, data->cmd); -} - -static int -archive_compressor_program_write(struct archive_write_filter *f, - const void *buff, size_t length) -{ - struct private_data *data = (struct private_data *)f->data; - - return __archive_write_program_write(f, data->pdata, buff, length); -} - -static int -archive_compressor_program_close(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; - - return __archive_write_program_close(f, data->pdata); -} - -static int -archive_compressor_program_free(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; - - if (data) { - free(data->cmd); - archive_string_free(&data->description); - __archive_write_program_free(data->pdata); - free(data); - f->data = NULL; - } - return (ARCHIVE_OK); -} - -/* - * Allocate resources for executing an external program. - */ -struct archive_write_program_data * -__archive_write_program_allocate(const char *program) -{ - struct archive_write_program_data *data; - - data = calloc(1, sizeof(struct archive_write_program_data)); - if (data == NULL) - return (data); - data->child_stdin = -1; - data->child_stdout = -1; - data->program_name = strdup(program); - return (data); -} - -/* - * Release the resources. - */ -int -__archive_write_program_free(struct archive_write_program_data *data) -{ - - if (data) { - free(data->program_name); - free(data->child_buf); - free(data); - } - return (ARCHIVE_OK); -} - -int -__archive_write_program_open(struct archive_write_filter *f, - struct archive_write_program_data *data, const char *cmd) -{ - int ret; - - if (data->child_buf == NULL) { - data->child_buf_len = 65536; - data->child_buf_avail = 0; - data->child_buf = malloc(data->child_buf_len); - - if (data->child_buf == NULL) { - archive_set_error(f->archive, ENOMEM, - "Can't allocate compression buffer"); - return (ARCHIVE_FATAL); - } - } - - ret = __archive_create_child(cmd, &data->child_stdin, - &data->child_stdout, &data->child); - if (ret != ARCHIVE_OK) { - archive_set_error(f->archive, EINVAL, - "Can't launch external program: %s", cmd); - return (ARCHIVE_FATAL); - } - return (ARCHIVE_OK); -} - -static ssize_t -child_write(struct archive_write_filter *f, - struct archive_write_program_data *data, const char *buf, size_t buf_len) -{ - ssize_t ret; - - if (data->child_stdin == -1) - return (-1); - - if (buf_len == 0) - return (-1); - - for (;;) { - do { - ret = write(data->child_stdin, buf, buf_len); - } while (ret == -1 && errno == EINTR); - - if (ret > 0) - return (ret); - if (ret == 0) { - close(data->child_stdin); - data->child_stdin = -1; - fcntl(data->child_stdout, F_SETFL, 0); - return (0); - } - if (ret == -1 && errno != EAGAIN) - return (-1); - - if (data->child_stdout == -1) { - fcntl(data->child_stdin, F_SETFL, 0); - __archive_check_child(data->child_stdin, - data->child_stdout); - continue; - } - - do { - ret = read(data->child_stdout, - data->child_buf + data->child_buf_avail, - data->child_buf_len - data->child_buf_avail); - } while (ret == -1 && errno == EINTR); - - if (ret == 0 || (ret == -1 && errno == EPIPE)) { - close(data->child_stdout); - data->child_stdout = -1; - fcntl(data->child_stdin, F_SETFL, 0); - continue; - } - if (ret == -1 && errno == EAGAIN) { - __archive_check_child(data->child_stdin, - data->child_stdout); - continue; - } - if (ret == -1) - return (-1); - - data->child_buf_avail += ret; - - ret = __archive_write_filter(f->next_filter, - data->child_buf, data->child_buf_avail); - if (ret != ARCHIVE_OK) - return (-1); - data->child_buf_avail = 0; - } -} - -/* - * Write data to the filter stream. - */ -int -__archive_write_program_write(struct archive_write_filter *f, - struct archive_write_program_data *data, const void *buff, size_t length) -{ - ssize_t ret; - const char *buf; - - if (data->child == 0) - return (ARCHIVE_OK); - - buf = buff; - while (length > 0) { - ret = child_write(f, data, buf, length); - if (ret == -1 || ret == 0) { - archive_set_error(f->archive, EIO, - "Can't write to program: %s", data->program_name); - return (ARCHIVE_FATAL); - } - length -= ret; - buf += ret; - } - return (ARCHIVE_OK); -} - -/* - * Finish the filtering... - */ -int -__archive_write_program_close(struct archive_write_filter *f, - struct archive_write_program_data *data) -{ - int ret, status; - ssize_t bytes_read; - - if (data->child == 0) - return ARCHIVE_OK; - - ret = 0; - close(data->child_stdin); - data->child_stdin = -1; - fcntl(data->child_stdout, F_SETFL, 0); - - for (;;) { - do { - bytes_read = read(data->child_stdout, - data->child_buf + data->child_buf_avail, - data->child_buf_len - data->child_buf_avail); - } while (bytes_read == -1 && errno == EINTR); - - if (bytes_read == 0 || (bytes_read == -1 && errno == EPIPE)) - break; - - if (bytes_read == -1) { - archive_set_error(f->archive, errno, - "Error reading from program: %s", data->program_name); - ret = ARCHIVE_FATAL; - goto cleanup; - } - data->child_buf_avail += bytes_read; - - ret = __archive_write_filter(f->next_filter, - data->child_buf, data->child_buf_avail); - if (ret != ARCHIVE_OK) { - ret = ARCHIVE_FATAL; - goto cleanup; - } - data->child_buf_avail = 0; - } - -cleanup: - /* Shut down the child. */ - if (data->child_stdin != -1) - close(data->child_stdin); - if (data->child_stdout != -1) - close(data->child_stdout); - while (waitpid(data->child, &status, 0) == -1 && errno == EINTR) - continue; -#if defined(_WIN32) && !defined(__CYGWIN__) - CloseHandle(data->child); -#endif - data->child = 0; - - if (status != 0) { - archive_set_error(f->archive, EIO, - "Error closing program: %s", data->program_name); - ret = ARCHIVE_FATAL; - } - return ret; -} - diff --git a/thirdparty/libarchive/libarchive/archive_write_add_filter_uuencode.c b/thirdparty/libarchive/libarchive/archive_write_add_filter_uuencode.c deleted file mode 100644 index 1ad458921..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_add_filter_uuencode.c +++ /dev/null @@ -1,295 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "archive.h" -#include "archive_private.h" -#include "archive_string.h" -#include "archive_write_private.h" - -#define LBYTES 45 - -struct private_uuencode { - int mode; - struct archive_string name; - struct archive_string encoded_buff; - size_t bs; - size_t hold_len; - unsigned char hold[LBYTES]; -}; - -static int archive_filter_uuencode_options(struct archive_write_filter *, - const char *, const char *); -static int archive_filter_uuencode_open(struct archive_write_filter *); -static int archive_filter_uuencode_write(struct archive_write_filter *, - const void *, size_t); -static int archive_filter_uuencode_close(struct archive_write_filter *); -static int archive_filter_uuencode_free(struct archive_write_filter *); -static void uu_encode(struct archive_string *, const unsigned char *, size_t); -static int64_t atol8(const char *, size_t); - -/* - * Add a compress filter to this write handle. - */ -int -archive_write_add_filter_uuencode(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - struct archive_write_filter *f = __archive_write_allocate_filter(_a); - struct private_uuencode *state; - - archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_add_filter_uu"); - - state = (struct private_uuencode *)calloc(1, sizeof(*state)); - if (state == NULL) { - archive_set_error(f->archive, ENOMEM, - "Can't allocate data for uuencode filter"); - return (ARCHIVE_FATAL); - } - archive_strcpy(&state->name, "-"); - state->mode = 0644; - - f->data = state; - f->name = "uuencode"; - f->code = ARCHIVE_FILTER_UU; - f->open = archive_filter_uuencode_open; - f->options = archive_filter_uuencode_options; - f->write = archive_filter_uuencode_write; - f->close = archive_filter_uuencode_close; - f->free = archive_filter_uuencode_free; - - return (ARCHIVE_OK); -} - -/* - * Set write options. - */ -static int -archive_filter_uuencode_options(struct archive_write_filter *f, const char *key, - const char *value) -{ - struct private_uuencode *state = (struct private_uuencode *)f->data; - - if (strcmp(key, "mode") == 0) { - if (value == NULL) { - archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, - "mode option requires octal digits"); - return (ARCHIVE_FAILED); - } - state->mode = (int)atol8(value, strlen(value)) & 0777; - return (ARCHIVE_OK); - } else if (strcmp(key, "name") == 0) { - if (value == NULL) { - archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, - "name option requires a string"); - return (ARCHIVE_FAILED); - } - archive_strcpy(&state->name, value); - return (ARCHIVE_OK); - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -/* - * Setup callback. - */ -static int -archive_filter_uuencode_open(struct archive_write_filter *f) -{ - struct private_uuencode *state = (struct private_uuencode *)f->data; - size_t bs = 65536, bpb; - - if (f->archive->magic == ARCHIVE_WRITE_MAGIC) { - /* Buffer size should be a multiple number of the of bytes - * per block for performance. */ - bpb = archive_write_get_bytes_per_block(f->archive); - if (bpb > bs) - bs = bpb; - else if (bpb != 0) - bs -= bs % bpb; - } - - state->bs = bs; - if (archive_string_ensure(&state->encoded_buff, bs + 512) == NULL) { - archive_set_error(f->archive, ENOMEM, - "Can't allocate data for uuencode buffer"); - return (ARCHIVE_FATAL); - } - - archive_string_sprintf(&state->encoded_buff, "begin %o %s\n", - state->mode, state->name.s); - - f->data = state; - return (0); -} - -static void -uu_encode(struct archive_string *as, const unsigned char *p, size_t len) -{ - int c; - - c = (int)len; - archive_strappend_char(as, c?c + 0x20:'`'); - for (; len >= 3; p += 3, len -= 3) { - c = p[0] >> 2; - archive_strappend_char(as, c?c + 0x20:'`'); - c = ((p[0] & 0x03) << 4) | ((p[1] & 0xf0) >> 4); - archive_strappend_char(as, c?c + 0x20:'`'); - c = ((p[1] & 0x0f) << 2) | ((p[2] & 0xc0) >> 6); - archive_strappend_char(as, c?c + 0x20:'`'); - c = p[2] & 0x3f; - archive_strappend_char(as, c?c + 0x20:'`'); - } - if (len > 0) { - c = p[0] >> 2; - archive_strappend_char(as, c?c + 0x20:'`'); - c = (p[0] & 0x03) << 4; - if (len == 1) { - archive_strappend_char(as, c?c + 0x20:'`'); - archive_strappend_char(as, '`'); - archive_strappend_char(as, '`'); - } else { - c |= (p[1] & 0xf0) >> 4; - archive_strappend_char(as, c?c + 0x20:'`'); - c = (p[1] & 0x0f) << 2; - archive_strappend_char(as, c?c + 0x20:'`'); - archive_strappend_char(as, '`'); - } - } - archive_strappend_char(as, '\n'); -} - -/* - * Write data to the encoded stream. - */ -static int -archive_filter_uuencode_write(struct archive_write_filter *f, const void *buff, - size_t length) -{ - struct private_uuencode *state = (struct private_uuencode *)f->data; - const unsigned char *p = buff; - int ret = ARCHIVE_OK; - - if (length == 0) - return (ret); - - if (state->hold_len) { - while (state->hold_len < LBYTES && length > 0) { - state->hold[state->hold_len++] = *p++; - length--; - } - if (state->hold_len < LBYTES) - return (ret); - uu_encode(&state->encoded_buff, state->hold, LBYTES); - state->hold_len = 0; - } - - for (; length >= LBYTES; length -= LBYTES, p += LBYTES) - uu_encode(&state->encoded_buff, p, LBYTES); - - /* Save remaining bytes. */ - if (length > 0) { - memcpy(state->hold, p, length); - state->hold_len = length; - } - while (archive_strlen(&state->encoded_buff) >= state->bs) { - ret = __archive_write_filter(f->next_filter, - state->encoded_buff.s, state->bs); - memmove(state->encoded_buff.s, - state->encoded_buff.s + state->bs, - state->encoded_buff.length - state->bs); - state->encoded_buff.length -= state->bs; - } - - return (ret); -} - - -/* - * Finish the compression... - */ -static int -archive_filter_uuencode_close(struct archive_write_filter *f) -{ - struct private_uuencode *state = (struct private_uuencode *)f->data; - - /* Flush remaining bytes. */ - if (state->hold_len != 0) - uu_encode(&state->encoded_buff, state->hold, state->hold_len); - archive_string_sprintf(&state->encoded_buff, "`\nend\n"); - /* Write the last block */ - archive_write_set_bytes_in_last_block(f->archive, 1); - return __archive_write_filter(f->next_filter, - state->encoded_buff.s, archive_strlen(&state->encoded_buff)); -} - -static int -archive_filter_uuencode_free(struct archive_write_filter *f) -{ - struct private_uuencode *state = (struct private_uuencode *)f->data; - - archive_string_free(&state->name); - archive_string_free(&state->encoded_buff); - free(state); - return (ARCHIVE_OK); -} - -static int64_t -atol8(const char *p, size_t char_cnt) -{ - int64_t l; - int digit; - - l = 0; - while (char_cnt-- > 0) { - if (*p >= '0' && *p <= '7') - digit = *p - '0'; - else - break; - p++; - l <<= 3; - l |= digit; - } - return (l); -} - diff --git a/thirdparty/libarchive/libarchive/archive_write_add_filter_xz.c b/thirdparty/libarchive/libarchive/archive_write_add_filter_xz.c deleted file mode 100644 index 04bee90ef..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_add_filter_xz.c +++ /dev/null @@ -1,545 +0,0 @@ -/*- - * Copyright (c) 2003-2010 Tim Kientzle - * Copyright (c) 2009-2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_compression_xz.c 201108 2009-12-28 03:28:21Z kientzle $"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#include -#ifdef HAVE_LZMA_H -#include -#endif - -#include "archive.h" -#include "archive_endian.h" -#include "archive_private.h" -#include "archive_write_private.h" - -#if ARCHIVE_VERSION_NUMBER < 4000000 -int -archive_write_set_compression_lzip(struct archive *a) -{ - __archive_write_filters_free(a); - return (archive_write_add_filter_lzip(a)); -} - -int -archive_write_set_compression_lzma(struct archive *a) -{ - __archive_write_filters_free(a); - return (archive_write_add_filter_lzma(a)); -} - -int -archive_write_set_compression_xz(struct archive *a) -{ - __archive_write_filters_free(a); - return (archive_write_add_filter_xz(a)); -} - -#endif - -#ifndef HAVE_LZMA_H -int -archive_write_add_filter_xz(struct archive *a) -{ - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "xz compression not supported on this platform"); - return (ARCHIVE_FATAL); -} - -int -archive_write_add_filter_lzma(struct archive *a) -{ - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "lzma compression not supported on this platform"); - return (ARCHIVE_FATAL); -} - -int -archive_write_add_filter_lzip(struct archive *a) -{ - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "lzma compression not supported on this platform"); - return (ARCHIVE_FATAL); -} -#else -/* Don't compile this if we don't have liblzma. */ - -struct private_data { - int compression_level; - uint32_t threads; - lzma_stream stream; - lzma_filter lzmafilters[2]; - lzma_options_lzma lzma_opt; - int64_t total_in; - unsigned char *compressed; - size_t compressed_buffer_size; - int64_t total_out; - /* the CRC32 value of uncompressed data for lzip */ - uint32_t crc32; -}; - -static int archive_compressor_xz_options(struct archive_write_filter *, - const char *, const char *); -static int archive_compressor_xz_open(struct archive_write_filter *); -static int archive_compressor_xz_write(struct archive_write_filter *, - const void *, size_t); -static int archive_compressor_xz_close(struct archive_write_filter *); -static int archive_compressor_xz_free(struct archive_write_filter *); -static int drive_compressor(struct archive_write_filter *, - struct private_data *, int finishing); - -struct option_value { - uint32_t dict_size; - uint32_t nice_len; - lzma_match_finder mf; -}; -static const struct option_value option_values[] = { - { 1 << 16, 32, LZMA_MF_HC3}, - { 1 << 20, 32, LZMA_MF_HC3}, - { 3 << 19, 32, LZMA_MF_HC4}, - { 1 << 21, 32, LZMA_MF_BT4}, - { 3 << 20, 32, LZMA_MF_BT4}, - { 1 << 22, 32, LZMA_MF_BT4}, - { 1 << 23, 64, LZMA_MF_BT4}, - { 1 << 24, 64, LZMA_MF_BT4}, - { 3 << 23, 64, LZMA_MF_BT4}, - { 1 << 25, 64, LZMA_MF_BT4} -}; - -static int -common_setup(struct archive_write_filter *f) -{ - struct private_data *data; - struct archive_write *a = (struct archive_write *)f->archive; - data = calloc(1, sizeof(*data)); - if (data == NULL) { - archive_set_error(&a->archive, ENOMEM, "Out of memory"); - return (ARCHIVE_FATAL); - } - f->data = data; - data->compression_level = LZMA_PRESET_DEFAULT; - data->threads = 1; - f->open = &archive_compressor_xz_open; - f->close = archive_compressor_xz_close; - f->free = archive_compressor_xz_free; - f->options = &archive_compressor_xz_options; - return (ARCHIVE_OK); -} - -/* - * Add an xz compression filter to this write handle. - */ -int -archive_write_add_filter_xz(struct archive *_a) -{ - struct archive_write_filter *f; - int r; - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_add_filter_xz"); - f = __archive_write_allocate_filter(_a); - r = common_setup(f); - if (r == ARCHIVE_OK) { - f->code = ARCHIVE_FILTER_XZ; - f->name = "xz"; - } - return (r); -} - -/* LZMA is handled identically, we just need a different compression - * code set. (The liblzma setup looks at the code to determine - * the one place that XZ and LZMA require different handling.) */ -int -archive_write_add_filter_lzma(struct archive *_a) -{ - struct archive_write_filter *f; - int r; - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_add_filter_lzma"); - f = __archive_write_allocate_filter(_a); - r = common_setup(f); - if (r == ARCHIVE_OK) { - f->code = ARCHIVE_FILTER_LZMA; - f->name = "lzma"; - } - return (r); -} - -int -archive_write_add_filter_lzip(struct archive *_a) -{ - struct archive_write_filter *f; - int r; - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_add_filter_lzip"); - f = __archive_write_allocate_filter(_a); - r = common_setup(f); - if (r == ARCHIVE_OK) { - f->code = ARCHIVE_FILTER_LZIP; - f->name = "lzip"; - } - return (r); -} - -static int -archive_compressor_xz_init_stream(struct archive_write_filter *f, - struct private_data *data) -{ - static const lzma_stream lzma_stream_init_data = LZMA_STREAM_INIT; - int ret; -#ifdef HAVE_LZMA_STREAM_ENCODER_MT - lzma_mt mt_options; -#endif - - data->stream = lzma_stream_init_data; - data->stream.next_out = data->compressed; - data->stream.avail_out = data->compressed_buffer_size; - if (f->code == ARCHIVE_FILTER_XZ) { -#ifdef HAVE_LZMA_STREAM_ENCODER_MT - if (data->threads != 1) { - memset(&mt_options, 0, sizeof(mt_options)); - mt_options.threads = data->threads; - mt_options.timeout = 300; - mt_options.filters = data->lzmafilters; - mt_options.check = LZMA_CHECK_CRC64; - ret = lzma_stream_encoder_mt(&(data->stream), - &mt_options); - } else -#endif - ret = lzma_stream_encoder(&(data->stream), - data->lzmafilters, LZMA_CHECK_CRC64); - } else if (f->code == ARCHIVE_FILTER_LZMA) { - ret = lzma_alone_encoder(&(data->stream), &data->lzma_opt); - } else { /* ARCHIVE_FILTER_LZIP */ - int dict_size = data->lzma_opt.dict_size; - int ds, log2dic, wedges; - - /* Calculate a coded dictionary size */ - if (dict_size < (1 << 12) || dict_size > (1 << 29)) { - archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, - "Unacceptable dictionary size for lzip: %d", - dict_size); - return (ARCHIVE_FATAL); - } - for (log2dic = 29; log2dic >= 12; log2dic--) { - if (dict_size & (1 << log2dic)) - break; - } - if (dict_size > (1 << log2dic)) { - log2dic++; - wedges = - ((1 << log2dic) - dict_size) / (1 << (log2dic - 4)); - } else - wedges = 0; - ds = ((wedges << 5) & 0xe0) | (log2dic & 0x1f); - - data->crc32 = 0; - /* Make a header */ - data->compressed[0] = 0x4C; - data->compressed[1] = 0x5A; - data->compressed[2] = 0x49; - data->compressed[3] = 0x50; - data->compressed[4] = 1;/* Version */ - data->compressed[5] = (unsigned char)ds; - data->stream.next_out += 6; - data->stream.avail_out -= 6; - - ret = lzma_raw_encoder(&(data->stream), data->lzmafilters); - } - if (ret == LZMA_OK) - return (ARCHIVE_OK); - - switch (ret) { - case LZMA_MEM_ERROR: - archive_set_error(f->archive, ENOMEM, - "Internal error initializing compression library: " - "Cannot allocate memory"); - break; - default: - archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, - "Internal error initializing compression library: " - "It's a bug in liblzma"); - break; - } - return (ARCHIVE_FATAL); -} - -/* - * Setup callback. - */ -static int -archive_compressor_xz_open(struct archive_write_filter *f) -{ - struct private_data *data = f->data; - int ret; - - if (data->compressed == NULL) { - size_t bs = 65536, bpb; - if (f->archive->magic == ARCHIVE_WRITE_MAGIC) { - /* Buffer size should be a multiple number of the of bytes - * per block for performance. */ - bpb = archive_write_get_bytes_per_block(f->archive); - if (bpb > bs) - bs = bpb; - else if (bpb != 0) - bs -= bs % bpb; - } - data->compressed_buffer_size = bs; - data->compressed - = (unsigned char *)malloc(data->compressed_buffer_size); - if (data->compressed == NULL) { - archive_set_error(f->archive, ENOMEM, - "Can't allocate data for compression buffer"); - return (ARCHIVE_FATAL); - } - } - - f->write = archive_compressor_xz_write; - - /* Initialize compression library. */ - if (f->code == ARCHIVE_FILTER_LZIP) { - const struct option_value *val = - &option_values[data->compression_level]; - - data->lzma_opt.dict_size = val->dict_size; - data->lzma_opt.preset_dict = NULL; - data->lzma_opt.preset_dict_size = 0; - data->lzma_opt.lc = LZMA_LC_DEFAULT; - data->lzma_opt.lp = LZMA_LP_DEFAULT; - data->lzma_opt.pb = LZMA_PB_DEFAULT; - data->lzma_opt.mode = - data->compression_level<= 2? LZMA_MODE_FAST:LZMA_MODE_NORMAL; - data->lzma_opt.nice_len = val->nice_len; - data->lzma_opt.mf = val->mf; - data->lzma_opt.depth = 0; - data->lzmafilters[0].id = LZMA_FILTER_LZMA1; - data->lzmafilters[0].options = &data->lzma_opt; - data->lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */ - } else { - if (lzma_lzma_preset(&data->lzma_opt, data->compression_level)) { - archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, - "Internal error initializing compression library"); - } - data->lzmafilters[0].id = LZMA_FILTER_LZMA2; - data->lzmafilters[0].options = &data->lzma_opt; - data->lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */ - } - ret = archive_compressor_xz_init_stream(f, data); - if (ret == LZMA_OK) { - f->data = data; - return (0); - } - return (ARCHIVE_FATAL); -} - -/* - * Set write options. - */ -static int -archive_compressor_xz_options(struct archive_write_filter *f, - const char *key, const char *value) -{ - struct private_data *data = (struct private_data *)f->data; - - if (strcmp(key, "compression-level") == 0) { - if (value == NULL || !(value[0] >= '0' && value[0] <= '9') || - value[1] != '\0') - return (ARCHIVE_WARN); - data->compression_level = value[0] - '0'; - if (data->compression_level > 9) - data->compression_level = 9; - return (ARCHIVE_OK); - } else if (strcmp(key, "threads") == 0) { - char *endptr; - - if (value == NULL) - return (ARCHIVE_WARN); - errno = 0; - data->threads = (int)strtoul(value, &endptr, 10); - if (errno != 0 || *endptr != '\0') { - data->threads = 1; - return (ARCHIVE_WARN); - } - if (data->threads == 0) { -#ifdef HAVE_LZMA_STREAM_ENCODER_MT - data->threads = lzma_cputhreads(); -#else - data->threads = 1; -#endif - } - return (ARCHIVE_OK); - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -/* - * Write data to the compressed stream. - */ -static int -archive_compressor_xz_write(struct archive_write_filter *f, - const void *buff, size_t length) -{ - struct private_data *data = (struct private_data *)f->data; - int ret; - - /* Update statistics */ - data->total_in += length; - if (f->code == ARCHIVE_FILTER_LZIP) - data->crc32 = lzma_crc32(buff, length, data->crc32); - - /* Compress input data to output buffer */ - data->stream.next_in = buff; - data->stream.avail_in = length; - if ((ret = drive_compressor(f, data, 0)) != ARCHIVE_OK) - return (ret); - - return (ARCHIVE_OK); -} - - -/* - * Finish the compression... - */ -static int -archive_compressor_xz_close(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; - int ret; - - ret = drive_compressor(f, data, 1); - if (ret == ARCHIVE_OK) { - data->total_out += - data->compressed_buffer_size - data->stream.avail_out; - ret = __archive_write_filter(f->next_filter, - data->compressed, - data->compressed_buffer_size - data->stream.avail_out); - if (f->code == ARCHIVE_FILTER_LZIP && ret == ARCHIVE_OK) { - archive_le32enc(data->compressed, data->crc32); - archive_le64enc(data->compressed+4, data->total_in); - archive_le64enc(data->compressed+12, data->total_out + 20); - ret = __archive_write_filter(f->next_filter, - data->compressed, 20); - } - } - lzma_end(&(data->stream)); - return ret; -} - -static int -archive_compressor_xz_free(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; - free(data->compressed); - free(data); - f->data = NULL; - return (ARCHIVE_OK); -} - -/* - * Utility function to push input data through compressor, - * writing full output blocks as necessary. - * - * Note that this handles both the regular write case (finishing == - * false) and the end-of-archive case (finishing == true). - */ -static int -drive_compressor(struct archive_write_filter *f, - struct private_data *data, int finishing) -{ - int ret; - - for (;;) { - if (data->stream.avail_out == 0) { - data->total_out += data->compressed_buffer_size; - ret = __archive_write_filter(f->next_filter, - data->compressed, - data->compressed_buffer_size); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - data->stream.next_out = data->compressed; - data->stream.avail_out = data->compressed_buffer_size; - } - - /* If there's nothing to do, we're done. */ - if (!finishing && data->stream.avail_in == 0) - return (ARCHIVE_OK); - - ret = lzma_code(&(data->stream), - finishing ? LZMA_FINISH : LZMA_RUN ); - - switch (ret) { - case LZMA_OK: - /* In non-finishing case, check if compressor - * consumed everything */ - if (!finishing && data->stream.avail_in == 0) - return (ARCHIVE_OK); - /* In finishing case, this return always means - * there's more work */ - break; - case LZMA_STREAM_END: - /* This return can only occur in finishing case. */ - if (finishing) - return (ARCHIVE_OK); - archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, - "lzma compression data error"); - return (ARCHIVE_FATAL); - case LZMA_MEMLIMIT_ERROR: - archive_set_error(f->archive, ENOMEM, - "lzma compression error: " - "%ju MiB would have been needed", - (uintmax_t)((lzma_memusage(&(data->stream)) - + 1024 * 1024 -1) - / (1024 * 1024))); - return (ARCHIVE_FATAL); - default: - /* Any other return value indicates an error. */ - archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, - "lzma compression failed:" - " lzma_code() call returned status %d", - ret); - return (ARCHIVE_FATAL); - } - } -} - -#endif /* HAVE_LZMA_H */ diff --git a/thirdparty/libarchive/libarchive/archive_write_add_filter_zstd.c b/thirdparty/libarchive/libarchive/archive_write_add_filter_zstd.c deleted file mode 100644 index c78e840d8..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_add_filter_zstd.c +++ /dev/null @@ -1,503 +0,0 @@ -/*- - * Copyright (c) 2017 Sean Purcell - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -__FBSDID("$FreeBSD$"); - - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDINT_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_ZSTD_H -#include -#endif - -#include "archive.h" -#include "archive_private.h" -#include "archive_string.h" -#include "archive_write_private.h" - -/* Don't compile this if we don't have zstd.h */ - -struct private_data { - int compression_level; - int threads; - int long_distance; -#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR - enum { - running, - finishing, - resetting, - } state; - int frame_per_file; - size_t min_frame_size; - size_t max_frame_size; - size_t cur_frame; - size_t cur_frame_in; - size_t cur_frame_out; - size_t total_in; - ZSTD_CStream *cstream; - ZSTD_outBuffer out; -#else - struct archive_write_program_data *pdata; -#endif -}; - -/* If we don't have the library use default range values (zstdcli.c v1.4.0) */ -#define CLEVEL_MIN -99 -#define CLEVEL_STD_MIN 0 /* prior to 1.3.4 and more recent without using --fast */ -#define CLEVEL_DEFAULT 3 -#define CLEVEL_STD_MAX 19 /* without using --ultra */ -#define CLEVEL_MAX 22 - -#define LONG_STD 27 - -#define MINVER_NEGCLEVEL 10304 -#define MINVER_MINCLEVEL 10306 -#define MINVER_LONG 10302 - -static int archive_compressor_zstd_options(struct archive_write_filter *, - const char *, const char *); -static int archive_compressor_zstd_open(struct archive_write_filter *); -static int archive_compressor_zstd_write(struct archive_write_filter *, - const void *, size_t); -static int archive_compressor_zstd_flush(struct archive_write_filter *); -static int archive_compressor_zstd_close(struct archive_write_filter *); -static int archive_compressor_zstd_free(struct archive_write_filter *); -#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR -static int drive_compressor(struct archive_write_filter *, - struct private_data *, int, const void *, size_t); -#endif - - -/* - * Add a zstd compression filter to this write handle. - */ -int -archive_write_add_filter_zstd(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - struct archive_write_filter *f = __archive_write_allocate_filter(_a); - struct private_data *data; - archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_add_filter_zstd"); - - data = calloc(1, sizeof(*data)); - if (data == NULL) { - archive_set_error(&a->archive, ENOMEM, "Out of memory"); - return (ARCHIVE_FATAL); - } - f->data = data; - f->open = &archive_compressor_zstd_open; - f->options = &archive_compressor_zstd_options; - f->flush = &archive_compressor_zstd_flush; - f->close = &archive_compressor_zstd_close; - f->free = &archive_compressor_zstd_free; - f->code = ARCHIVE_FILTER_ZSTD; - f->name = "zstd"; - data->compression_level = CLEVEL_DEFAULT; - data->threads = 0; - data->long_distance = 0; -#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR - data->frame_per_file = 0; - data->min_frame_size = 0; - data->max_frame_size = SIZE_MAX; - data->cur_frame_in = 0; - data->cur_frame_out = 0; - data->cstream = ZSTD_createCStream(); - if (data->cstream == NULL) { - free(data); - archive_set_error(&a->archive, ENOMEM, - "Failed to allocate zstd compressor object"); - return (ARCHIVE_FATAL); - } - - return (ARCHIVE_OK); -#else - data->pdata = __archive_write_program_allocate("zstd"); - if (data->pdata == NULL) { - free(data); - archive_set_error(&a->archive, ENOMEM, "Out of memory"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Using external zstd program"); - return (ARCHIVE_WARN); -#endif -} - -static int -archive_compressor_zstd_free(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; -#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR - ZSTD_freeCStream(data->cstream); - free(data->out.dst); -#else - __archive_write_program_free(data->pdata); -#endif - free(data); - f->data = NULL; - return (ARCHIVE_OK); -} - -static int string_to_number(const char *string, intmax_t *numberp) -{ - char *end; - - if (string == NULL || *string == '\0') - return (ARCHIVE_WARN); - *numberp = strtoimax(string, &end, 10); - if (end == string || *end != '\0' || errno == EOVERFLOW) { - *numberp = 0; - return (ARCHIVE_WARN); - } - return (ARCHIVE_OK); -} - -/* - * Set write options. - */ -static int -archive_compressor_zstd_options(struct archive_write_filter *f, const char *key, - const char *value) -{ - struct private_data *data = (struct private_data *)f->data; - - if (strcmp(key, "compression-level") == 0) { - intmax_t level; - if (string_to_number(value, &level) != ARCHIVE_OK) { - return (ARCHIVE_WARN); - } - /* If we don't have the library, hard-code the max level */ - int minimum = CLEVEL_MIN; - int maximum = CLEVEL_MAX; -#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR - maximum = ZSTD_maxCLevel(); -#if ZSTD_VERSION_NUMBER >= MINVER_MINCLEVEL - if (ZSTD_versionNumber() >= MINVER_MINCLEVEL) { - minimum = ZSTD_minCLevel(); - } - else -#endif - if (ZSTD_versionNumber() < MINVER_NEGCLEVEL) { - minimum = CLEVEL_STD_MIN; - } -#endif - if (level < minimum || level > maximum) { - return (ARCHIVE_WARN); - } - data->compression_level = (int)level; - return (ARCHIVE_OK); - } else if (strcmp(key, "threads") == 0) { - intmax_t threads; - if (string_to_number(value, &threads) != ARCHIVE_OK) { - return (ARCHIVE_WARN); - } - if (threads < 0) { - return (ARCHIVE_WARN); - } - data->threads = (int)threads; - return (ARCHIVE_OK); -#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR - } else if (strcmp(key, "frame-per-file") == 0) { - data->frame_per_file = 1; - return (ARCHIVE_OK); - } else if (strcmp(key, "min-frame-size") == 0) { - intmax_t min_frame_size; - if (string_to_number(value, &min_frame_size) != ARCHIVE_OK) { - return (ARCHIVE_WARN); - } - if (min_frame_size < 0) { - return (ARCHIVE_WARN); - } - data->min_frame_size = min_frame_size; - return (ARCHIVE_OK); - } else if (strcmp(key, "max-frame-size") == 0) { - intmax_t max_frame_size; - if (string_to_number(value, &max_frame_size) != ARCHIVE_OK) { - return (ARCHIVE_WARN); - } - if (max_frame_size < 1024) { - return (ARCHIVE_WARN); - } - data->max_frame_size = max_frame_size; - return (ARCHIVE_OK); -#endif - } - else if (strcmp(key, "long") == 0) { - intmax_t long_distance; - if (string_to_number(value, &long_distance) != ARCHIVE_OK) { - return (ARCHIVE_WARN); - } -#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR && ZSTD_VERSION_NUMBER >= MINVER_LONG - ZSTD_bounds bounds = ZSTD_cParam_getBounds(ZSTD_c_windowLog); - if (ZSTD_isError(bounds.error)) { - int max_distance = ((int)(sizeof(size_t) == 4 ? 30 : 31)); - if (((int)long_distance) < 10 || (int)long_distance > max_distance) - return (ARCHIVE_WARN); - } else { - if ((int)long_distance < bounds.lowerBound || (int)long_distance > bounds.upperBound) - return (ARCHIVE_WARN); - } -#else - int max_distance = ((int)(sizeof(size_t) == 4 ? 30 : 31)); - if (((int)long_distance) < 10 || (int)long_distance > max_distance) - return (ARCHIVE_WARN); -#endif - data->long_distance = (int)long_distance; - return (ARCHIVE_OK); - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR -/* - * Setup callback. - */ -static int -archive_compressor_zstd_open(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; - - if (data->out.dst == NULL) { - size_t bs = ZSTD_CStreamOutSize(), bpb; - if (f->archive->magic == ARCHIVE_WRITE_MAGIC) { - /* Buffer size should be a multiple number of - * the of bytes per block for performance. */ - bpb = archive_write_get_bytes_per_block(f->archive); - if (bpb > bs) - bs = bpb; - else if (bpb != 0) - bs -= bs % bpb; - } - data->out.size = bs; - data->out.pos = 0; - data->out.dst - = (unsigned char *)malloc(data->out.size); - if (data->out.dst == NULL) { - archive_set_error(f->archive, ENOMEM, - "Can't allocate data for compression buffer"); - return (ARCHIVE_FATAL); - } - } - - f->write = archive_compressor_zstd_write; - - if (ZSTD_isError(ZSTD_initCStream(data->cstream, - data->compression_level))) { - archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, - "Internal error initializing zstd compressor object"); - return (ARCHIVE_FATAL); - } - - ZSTD_CCtx_setParameter(data->cstream, ZSTD_c_nbWorkers, data->threads); - -#if ZSTD_VERSION_NUMBER >= MINVER_LONG - ZSTD_CCtx_setParameter(data->cstream, ZSTD_c_windowLog, data->long_distance); -#endif - - return (ARCHIVE_OK); -} - -/* - * Write data to the compressed stream. - */ -static int -archive_compressor_zstd_write(struct archive_write_filter *f, const void *buff, - size_t length) -{ - struct private_data *data = (struct private_data *)f->data; - - return (drive_compressor(f, data, 0, buff, length)); -} - -/* - * Flush the compressed stream. - */ -static int -archive_compressor_zstd_flush(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; - - if (data->frame_per_file && data->state == running && - data->cur_frame_out > data->min_frame_size) - data->state = finishing; - return (drive_compressor(f, data, 1, NULL, 0)); -} - -/* - * Finish the compression... - */ -static int -archive_compressor_zstd_close(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; - - if (data->state == running) - data->state = finishing; - return (drive_compressor(f, data, 1, NULL, 0)); -} - -/* - * Utility function to push input data through compressor, - * writing full output blocks as necessary. - */ -static int -drive_compressor(struct archive_write_filter *f, - struct private_data *data, int flush, const void *src, size_t length) -{ - ZSTD_inBuffer in = { .src = src, .size = length, .pos = 0 }; - size_t ipos, opos, zstdret = 0; - int ret; - - for (;;) { - ipos = in.pos; - opos = data->out.pos; - switch (data->state) { - case running: - if (in.pos == in.size) - return (ARCHIVE_OK); - zstdret = ZSTD_compressStream(data->cstream, - &data->out, &in); - if (ZSTD_isError(zstdret)) - goto zstd_fatal; - break; - case finishing: - zstdret = ZSTD_endStream(data->cstream, &data->out); - if (ZSTD_isError(zstdret)) - goto zstd_fatal; - if (zstdret == 0) - data->state = resetting; - break; - case resetting: - ZSTD_CCtx_reset(data->cstream, ZSTD_reset_session_only); - data->cur_frame++; - data->cur_frame_in = 0; - data->cur_frame_out = 0; - data->state = running; - break; - } - data->total_in += in.pos - ipos; - data->cur_frame_in += in.pos - ipos; - data->cur_frame_out += data->out.pos - opos; - if (data->state == running && - data->cur_frame_in >= data->max_frame_size) { - data->state = finishing; - } - if (data->out.pos == data->out.size || - (flush && data->out.pos > 0)) { - ret = __archive_write_filter(f->next_filter, - data->out.dst, data->out.pos); - if (ret != ARCHIVE_OK) - goto fatal; - data->out.pos = 0; - } - } -zstd_fatal: - archive_set_error(f->archive, ARCHIVE_ERRNO_MISC, - "Zstd compression failed: %s", - ZSTD_getErrorName(zstdret)); -fatal: - return (ARCHIVE_FATAL); -} - -#else /* HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR */ - -static int -archive_compressor_zstd_open(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; - struct archive_string as; - int r; - - archive_string_init(&as); - /* --no-check matches library default */ - archive_strcpy(&as, "zstd --no-check"); - - if (data->compression_level < CLEVEL_STD_MIN) { - archive_string_sprintf(&as, " --fast=%d", -data->compression_level); - } else { - archive_string_sprintf(&as, " -%d", data->compression_level); - } - - if (data->compression_level > CLEVEL_STD_MAX) { - archive_strcat(&as, " --ultra"); - } - - if (data->threads != 0) { - archive_string_sprintf(&as, " --threads=%d", data->threads); - } - - if (data->long_distance != 0) { - archive_string_sprintf(&as, " --long=%d", data->long_distance); - } - - f->write = archive_compressor_zstd_write; - r = __archive_write_program_open(f, data->pdata, as.s); - archive_string_free(&as); - return (r); -} - -static int -archive_compressor_zstd_write(struct archive_write_filter *f, const void *buff, - size_t length) -{ - struct private_data *data = (struct private_data *)f->data; - - return __archive_write_program_write(f, data->pdata, buff, length); -} - -static int -archive_compressor_zstd_flush(struct archive_write_filter *f) -{ - (void)f; /* UNUSED */ - - return (ARCHIVE_OK); -} - -static int -archive_compressor_zstd_close(struct archive_write_filter *f) -{ - struct private_data *data = (struct private_data *)f->data; - - return __archive_write_program_close(f, data->pdata); -} - -#endif /* HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR */ diff --git a/thirdparty/libarchive/libarchive/archive_write_blocksize.3 b/thirdparty/libarchive/libarchive/archive_write_blocksize.3 deleted file mode 100644 index 4973f9990..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_blocksize.3 +++ /dev/null @@ -1,114 +0,0 @@ -.\" Copyright (c) 2003-2011 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd February 2, 2012 -.Dt ARCHIVE_WRITE_BLOCKSIZE 3 -.Os -.Sh NAME -.Nm archive_write_get_bytes_per_block , -.Nm archive_write_set_bytes_per_block , -.Nm archive_write_get_bytes_in_last_block , -.Nm archive_write_set_bytes_in_last_block -.Nd functions for creating archives -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive.h -.Ft int -.Fn archive_write_get_bytes_per_block "struct archive *" -.Ft int -.Fn archive_write_set_bytes_per_block "struct archive *" "int bytes_per_block" -.Ft int -.Fn archive_write_get_bytes_in_last_block "struct archive *" -.Ft int -.Fn archive_write_set_bytes_in_last_block "struct archive *" "int" -.Sh DESCRIPTION -.Bl -tag -width indent -.It Fn archive_write_set_bytes_per_block -Sets the block size used for writing the archive data. -Every call to the write callback function, except possibly the last one, will -use this value for the length. -The default is to use a block size of 10240 bytes. -Note that a block size of zero will suppress internal blocking -and cause writes to be sent directly to the write callback as they occur. -.It Fn archive_write_get_bytes_per_block -Retrieve the block size to be used for writing. -A value of -1 here indicates that the library should use default values. -A value of zero indicates that internal blocking is suppressed. -.It Fn archive_write_set_bytes_in_last_block -Sets the block size used for writing the last block. -If this value is zero, the last block will be padded to the same size -as the other blocks. -Otherwise, the final block will be padded to a multiple of this size. -In particular, setting it to 1 will cause the final block to not be padded. -For compressed output, any padding generated by this option -is applied only after the compression. -The uncompressed data is always unpadded. -The default is to pad the last block to the full block size (note that -.Fn archive_write_open_filename -will set this based on the file type). -Unlike the other -.Dq set -functions, this function can be called after the archive is opened. -.It Fn archive_write_get_bytes_in_last_block -Retrieve the currently-set value for last block size. -A value of -1 here indicates that the library should use default values. -.El -.\" .Sh EXAMPLE -.Sh RETURN VALUES -.Fn archive_write_set_bytes_per_block -and -.Fn archive_write_set_bytes_in_last_block -return -.Cm ARCHIVE_OK -on success, or -.Cm ARCHIVE_FATAL . -.Pp -.Fn archive_write_get_bytes_per_block -and -.Fn archive_write_get_bytes_in_last_block -return currently configured block size -.Po -.Li -1 -indicates the default block size -.Pc , -or -.Cm ARCHIVE_FATAL . -.\" -.Sh ERRORS -Detailed error codes and textual descriptions are available from the -.Fn archive_errno -and -.Fn archive_error_string -functions. -.\" -.Sh SEE ALSO -.Xr tar 1 , -.Xr archive_write_set_options 3 , -.Xr libarchive 3 , -.Xr cpio 5 , -.Xr mtree 5 , -.Xr tar 5 diff --git a/thirdparty/libarchive/libarchive/archive_write_data.3 b/thirdparty/libarchive/libarchive/archive_write_data.3 deleted file mode 100644 index bc208b45d..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_data.3 +++ /dev/null @@ -1,90 +0,0 @@ -.\" Copyright (c) 2003-2011 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd February 28, 2017 -.Dt ARCHIVE_WRITE_DATA 3 -.Os -.Sh NAME -.Nm archive_write_data , -.Nm archive_write_data_block -.Nd functions for creating archives -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive.h -.Ft la_ssize_t -.Fn archive_write_data "struct archive *" "const void *" "size_t" -.Ft la_ssize_t -.Fn archive_write_data_block "struct archive *" "const void *" "size_t size" "int64_t offset" -.Sh DESCRIPTION -.Bl -tag -width indent -.It Fn archive_write_data -Write data corresponding to the header just written. -.It Fn archive_write_data_block -Write data corresponding to the header just written. -This is like -.Fn archive_write_data -except that it performs a seek on the file being -written to the specified offset before writing the data. -This is useful when restoring sparse files from archive -formats that support sparse files. -Returns number of bytes written or -1 on error. -(Note: This is currently not supported for -.Tn archive_write -handles, only for -.Tn archive_write_disk -handles. -.El -.\" .Sh EXAMPLE -.\" -.Sh RETURN VALUES -This function returns the number of bytes actually written, or -a negative error code on error. -.\" -.Sh ERRORS -Detailed error codes and textual descriptions are available from the -.Fn archive_errno -and -.Fn archive_error_string -functions. -.\" -.Sh BUGS -In libarchive 3.x, this function sometimes returns -zero on success instead of returning the number of bytes written. -Specifically, this occurs when writing to an -.Vt archive_write_disk -handle. -Clients should treat any value less than zero as an error -and consider any non-negative value as success. -.\" -.Sh SEE ALSO -.Xr tar 1 , -.Xr archive_write_finish_entry 3 , -.Xr archive_write_set_options 3 , -.Xr libarchive 3 , -.Xr cpio 5 , -.Xr mtree 5 , -.Xr tar 5 diff --git a/thirdparty/libarchive/libarchive/archive_write_disk.3 b/thirdparty/libarchive/libarchive/archive_write_disk.3 deleted file mode 100644 index 97f3fcde9..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_disk.3 +++ /dev/null @@ -1,362 +0,0 @@ -.\" Copyright (c) 2003-2007 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd January 19, 2020 -.Dt ARCHIVE_WRITE_DISK 3 -.Os -.Sh NAME -.Nm archive_write_disk_new , -.Nm archive_write_disk_set_options , -.Nm archive_write_disk_set_skip_file , -.Nm archive_write_disk_set_group_lookup , -.Nm archive_write_disk_set_standard_lookup , -.Nm archive_write_disk_set_user_lookup -.Nd functions for creating objects on disk -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive.h -.Ft struct archive * -.Fn archive_write_disk_new "void" -.Ft int -.Fn archive_write_disk_set_options "struct archive *" "int flags" -.Ft int -.Fn archive_write_disk_set_skip_file "struct archive *" "dev_t" "ino_t" -.Ft int -.Fo archive_write_disk_set_group_lookup -.Fa "struct archive *" -.Fa "void *" -.Fa "gid_t (*)(void *, const char *gname, gid_t gid)" -.Fa "void (*cleanup)(void *)" -.Fc -.Ft int -.Fn archive_write_disk_set_standard_lookup "struct archive *" -.Ft int -.Fo archive_write_disk_set_user_lookup -.Fa "struct archive *" -.Fa "void *" -.Fa "uid_t (*)(void *, const char *uname, uid_t uid)" -.Fa "void (*cleanup)(void *)" -.Fc -.Sh DESCRIPTION -These functions provide a complete API for creating objects on -disk from -.Tn struct archive_entry -descriptions. -They are most naturally used when extracting objects from an archive -using the -.Fn archive_read -interface. -The general process is to read -.Tn struct archive_entry -objects from an archive, then write those objects to a -.Tn struct archive -object created using the -.Fn archive_write_disk -family functions. -This interface is deliberately very similar to the -.Fn archive_write -interface used to write objects to a streaming archive. -.Bl -tag -width indent -.It Fn archive_write_disk_new -Allocates and initializes a -.Tn struct archive -object suitable for writing objects to disk. -.It Fn archive_write_disk_set_skip_file -Records the device and inode numbers of a file that should not be -overwritten. -This is typically used to ensure that an extraction process does not -overwrite the archive from which objects are being read. -This capability is technically unnecessary but can be a significant -performance optimization in practice. -.It Fn archive_write_disk_set_options -The options field consists of a bitwise OR of one or more of the -following values: -.Bl -tag -compact -width "indent" -.It Cm ARCHIVE_EXTRACT_ACL -Attempt to restore Access Control Lists. -By default, extended ACLs are ignored. -.It Cm ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS -Before removing a file system object prior to replacing it, clear -platform-specific file flags which might prevent its removal. -.It Cm ARCHIVE_EXTRACT_FFLAGS -Attempt to restore file attributes (file flags). -By default, file attributes are ignored. -See -.Xr chattr 1 -.Pq Linux -or -.Xr chflags 1 -.Pq FreeBSD, Mac OS X -for more information on file attributes. -.It Cm ARCHIVE_EXTRACT_MAC_METADATA -Mac OS X specific. -Restore metadata using -.Xr copyfile 3 . -By default, -.Xr copyfile 3 -metadata is ignored. -.It Cm ARCHIVE_EXTRACT_NO_OVERWRITE -Existing files on disk will not be overwritten. -By default, existing regular files are truncated and overwritten; -existing directories will have their permissions updated; -other pre-existing objects are unlinked and recreated from scratch. -.It Cm ARCHIVE_EXTRACT_OWNER -The user and group IDs should be set on the restored file. -By default, the user and group IDs are not restored. -.It Cm ARCHIVE_EXTRACT_PERM -Full permissions (including SGID, SUID, and sticky bits) should -be restored exactly as specified, without obeying the -current umask. -Note that SUID and SGID bits can only be restored if the -user and group ID of the object on disk are correct. -If -.Cm ARCHIVE_EXTRACT_OWNER -is not specified, then SUID and SGID bits will only be restored -if the default user and group IDs of newly-created objects on disk -happen to match those specified in the archive entry. -By default, only basic permissions are restored, and umask is obeyed. -.It Cm ARCHIVE_EXTRACT_SAFE_WRITES -Extract files atomically, by first creating a unique temporary file and then -renaming it to its required destination name. -This avoids a race where an application might see a partial file (or no -file) during extraction. -.It Cm ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS -Refuse to extract an absolute path. -The default is to not refuse such paths. -.It Cm ARCHIVE_EXTRACT_SECURE_NODOTDOT -Refuse to extract a path that contains a -.Pa .. -element anywhere within it. -The default is to not refuse such paths. -Note that paths ending in -.Pa .. -always cause an error, regardless of this flag. -.It Cm ARCHIVE_EXTRACT_SECURE_SYMLINKS -Refuse to extract any object whose final location would be altered -by a symlink on disk. -This is intended to help guard against a variety of mischief -caused by archives that (deliberately or otherwise) extract -files outside of the current directory. -The default is not to perform this check. -If -.Cm ARCHIVE_EXTRACT_UNLINK -is specified together with this option, the library will -remove any intermediate symlinks it finds and return an -error only if such symlink could not be removed. -.It Cm ARCHIVE_EXTRACT_SPARSE -Scan data for blocks of NUL bytes and try to recreate them with holes. -This results in sparse files, independent of whether the archive format -supports or uses them. -.It Cm ARCHIVE_EXTRACT_TIME -The timestamps (mtime, ctime, and atime) should be restored. -By default, they are ignored. -Note that restoring of atime is not currently supported. -.It Cm ARCHIVE_EXTRACT_UNLINK -Existing files on disk will be unlinked before any attempt to -create them. -In some cases, this can prove to be a significant performance improvement. -By default, existing files are truncated and rewritten, but -the file is not recreated. -In particular, the default behavior does not break existing hard links. -.It Cm ARCHIVE_EXTRACT_XATTR -Attempt to restore extended file attributes. -By default, they are ignored. -See -.Xr xattr 7 -.Pq Linux , -.Xr xattr 2 -.Pq Mac OS X , -or -.Xr getextattr 8 -.Pq FreeBSD -for more information on extended file attributes. -.El -.It Xo -.Fn archive_write_disk_set_group_lookup , -.Fn archive_write_disk_set_user_lookup -.Xc -The -.Tn struct archive_entry -objects contain both names and ids that can be used to identify users -and groups. -These names and ids describe the ownership of the file itself and -also appear in ACL lists. -By default, the library uses the ids and ignores the names, but -this can be overridden by registering user and group lookup functions. -To register, you must provide a lookup function which -accepts both a name and id and returns a suitable id. -You may also provide a -.Tn void * -pointer to a private data structure and a cleanup function for -that data. -The cleanup function will be invoked when the -.Tn struct archive -object is destroyed. -.It Fn archive_write_disk_set_standard_lookup -This convenience function installs a standard set of user -and group lookup functions. -These functions use -.Xr getpwnam 3 -and -.Xr getgrnam 3 -to convert names to ids, defaulting to the ids if the names cannot -be looked up. -These functions also implement a simple memory cache to reduce -the number of calls to -.Xr getpwnam 3 -and -.Xr getgrnam 3 . -.El -More information about the -.Va struct archive -object and the overall design of the library can be found in the -.Xr libarchive 3 -overview. -Many of these functions are also documented under -.Xr archive_write 3 . -.Sh RETURN VALUES -Most functions return -.Cm ARCHIVE_OK -(zero) on success, or one of several non-zero -error codes for errors. -Specific error codes include: -.Cm ARCHIVE_RETRY -for operations that might succeed if retried, -.Cm ARCHIVE_WARN -for unusual conditions that do not prevent further operations, and -.Cm ARCHIVE_FATAL -for serious errors that make remaining operations impossible. -.Pp -.Fn archive_write_disk_new -returns a pointer to a newly-allocated -.Tn struct archive -object. -.Pp -.Fn archive_write_data -returns a count of the number of bytes actually written, -or -.Li -1 -on error. -.\" -.Sh ERRORS -Detailed error codes and textual descriptions are available from the -.Fn archive_errno -and -.Fn archive_error_string -functions. -.\" -.Sh SEE ALSO -.Xr tar 1 , -.Xr archive_read 3 , -.Xr archive_write 3 , -.Xr libarchive 3 -.Sh HISTORY -The -.Nm libarchive -library first appeared in -.Fx 5.3 . -The -.Nm archive_write_disk -interface was added to -.Nm libarchive 2.0 -and first appeared in -.Fx 6.3 . -.Sh AUTHORS -.An -nosplit -The -.Nm libarchive -library was written by -.An Tim Kientzle Aq kientzle@acm.org . -.Sh BUGS -Directories are actually extracted in two distinct phases. -Directories are created during -.Fn archive_write_header , -but final permissions are not set until -.Fn archive_write_close . -This separation is necessary to correctly handle borderline -cases such as a non-writable directory containing -files, but can cause unexpected results. -In particular, directory permissions are not fully -restored until the archive is closed. -If you use -.Xr chdir 2 -to change the current directory between calls to -.Fn archive_read_extract -or before calling -.Fn archive_read_close , -you may confuse the permission-setting logic with -the result that directory permissions are restored -incorrectly. -.Pp -The library attempts to create objects with filenames longer than -.Cm PATH_MAX -by creating prefixes of the full path and changing the current directory. -Currently, this logic is limited in scope; the fixup pass does -not work correctly for such objects and the symlink security check -option disables the support for very long pathnames. -.Pp -Restoring the path -.Pa aa/../bb -does create each intermediate directory. -In particular, the directory -.Pa aa -is created as well as the final object -.Pa bb . -In theory, this can be exploited to create an entire directory hierarchy -with a single request. -Of course, this does not work if the -.Cm ARCHIVE_EXTRACT_NODOTDOT -option is specified. -.Pp -Implicit directories are always created obeying the current umask. -Explicit objects are created obeying the current umask unless -.Cm ARCHIVE_EXTRACT_PERM -is specified, in which case they current umask is ignored. -.Pp -SGID and SUID bits are restored only if the correct user and -group could be set. -If -.Cm ARCHIVE_EXTRACT_OWNER -is not specified, then no attempt is made to set the ownership. -In this case, SGID and SUID bits are restored only if the -user and group of the final object happen to match those specified -in the entry. -.Pp -The -.Dq standard -user-id and group-id lookup functions are not the defaults because -.Xr getgrnam 3 -and -.Xr getpwnam 3 -are sometimes too large for particular applications. -The current design allows the application author to use a more -compact implementation when appropriate. -.Pp -There should be a corresponding -.Nm archive_read_disk -interface that walks a directory hierarchy and returns archive -entry objects. diff --git a/thirdparty/libarchive/libarchive/archive_write_disk_posix.c b/thirdparty/libarchive/libarchive/archive_write_disk_posix.c deleted file mode 100644 index c8c2e1058..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_disk_posix.c +++ /dev/null @@ -1,4759 +0,0 @@ -/*- - * Copyright (c) 2003-2010 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#if !defined(_WIN32) || defined(__CYGWIN__) - -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_ACL_H -#include -#endif -#ifdef HAVE_SYS_EXTATTR_H -#include -#endif -#if HAVE_SYS_XATTR_H -#include -#elif HAVE_ATTR_XATTR_H -#include -#endif -#ifdef HAVE_SYS_EA_H -#include -#endif -#ifdef HAVE_SYS_IOCTL_H -#include -#endif -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_SYS_TIME_H -#include -#endif -#ifdef HAVE_SYS_UTIME_H -#include -#endif -#ifdef HAVE_COPYFILE_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif -#ifdef HAVE_GRP_H -#include -#endif -#ifdef HAVE_LANGINFO_H -#include -#endif -#ifdef HAVE_LINUX_FS_H -#include /* for Linux file flags */ -#endif -/* - * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h. - * As the include guards don't agree, the order of include is important. - */ -#ifdef HAVE_LINUX_EXT2_FS_H -#include /* for Linux file flags */ -#endif -#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__) -#include /* Linux file flags, broken on Cygwin */ -#endif -#ifdef HAVE_LIMITS_H -#include -#endif -#ifdef HAVE_PWD_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_UTIME_H -#include -#endif -#ifdef F_GETTIMES /* Tru64 specific */ -#include -#endif - -/* - * Macro to cast st_mtime and time_t to an int64 so that 2 numbers can reliably be compared. - * - * It assumes that the input is an integer type of no more than 64 bits. - * If the number is less than zero, t must be a signed type, so it fits in - * int64_t. Otherwise, it's a nonnegative value so we can cast it to uint64_t - * without loss. But it could be a large unsigned value, so we have to clip it - * to INT64_MAX.* - */ -#define to_int64_time(t) \ - ((t) < 0 ? (int64_t)(t) : (uint64_t)(t) > (uint64_t)INT64_MAX ? INT64_MAX : (int64_t)(t)) - -#if __APPLE__ -#include -#if TARGET_OS_MAC && !TARGET_OS_EMBEDDED && HAVE_QUARANTINE_H -#include -#define HAVE_QUARANTINE 1 -#endif -#endif - -#ifdef HAVE_ZLIB_H -#include -#endif - -/* TODO: Support Mac OS 'quarantine' feature. This is really just a - * standard tag to mark files that have been downloaded as "tainted". - * On Mac OS, we should mark the extracted files as tainted if the - * archive being read was tainted. Windows has a similar feature; we - * should investigate ways to support this generically. */ - -#include "archive.h" -#include "archive_acl_private.h" -#include "archive_string.h" -#include "archive_endian.h" -#include "archive_entry.h" -#include "archive_private.h" -#include "archive_write_disk_private.h" - -#ifndef O_BINARY -#define O_BINARY 0 -#endif -#ifndef O_CLOEXEC -#define O_CLOEXEC 0 -#endif - -/* Ignore non-int O_NOFOLLOW constant. */ -/* gnulib's fcntl.h does this on AIX, but it seems practical everywhere */ -#if defined O_NOFOLLOW && !(INT_MIN <= O_NOFOLLOW && O_NOFOLLOW <= INT_MAX) -#undef O_NOFOLLOW -#endif - -#ifndef O_NOFOLLOW -#define O_NOFOLLOW 0 -#endif - -#ifndef AT_FDCWD -#define AT_FDCWD -100 -#endif - -struct fixup_entry { - struct fixup_entry *next; - struct archive_acl acl; - mode_t mode; - __LA_MODE_T filetype; - int64_t atime; - int64_t birthtime; - int64_t mtime; - int64_t ctime; - unsigned long atime_nanos; - unsigned long birthtime_nanos; - unsigned long mtime_nanos; - unsigned long ctime_nanos; - unsigned long fflags_set; - size_t mac_metadata_size; - void *mac_metadata; - int fixup; /* bitmask of what needs fixing */ - char *name; -}; - -/* - * We use a bitmask to track which operations remain to be done for - * this file. In particular, this helps us avoid unnecessary - * operations when it's possible to take care of one step as a - * side-effect of another. For example, mkdir() can specify the mode - * for the newly-created object but symlink() cannot. This means we - * can skip chmod() if mkdir() succeeded, but we must explicitly - * chmod() if we're trying to create a directory that already exists - * (mkdir() failed) or if we're restoring a symlink. Similarly, we - * need to verify UID/GID before trying to restore SUID/SGID bits; - * that verification can occur explicitly through a stat() call or - * implicitly because of a successful chown() call. - */ -#define TODO_MODE_FORCE 0x40000000 -#define TODO_MODE_BASE 0x20000000 -#define TODO_SUID 0x10000000 -#define TODO_SUID_CHECK 0x08000000 -#define TODO_SGID 0x04000000 -#define TODO_SGID_CHECK 0x02000000 -#define TODO_APPLEDOUBLE 0x01000000 -#define TODO_MODE (TODO_MODE_BASE|TODO_SUID|TODO_SGID) -#define TODO_TIMES ARCHIVE_EXTRACT_TIME -#define TODO_OWNER ARCHIVE_EXTRACT_OWNER -#define TODO_FFLAGS ARCHIVE_EXTRACT_FFLAGS -#define TODO_ACLS ARCHIVE_EXTRACT_ACL -#define TODO_XATTR ARCHIVE_EXTRACT_XATTR -#define TODO_MAC_METADATA ARCHIVE_EXTRACT_MAC_METADATA -#define TODO_HFS_COMPRESSION ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED - -struct archive_write_disk { - struct archive archive; - - mode_t user_umask; - struct fixup_entry *fixup_list; - struct fixup_entry *current_fixup; - int64_t user_uid; - int skip_file_set; - int64_t skip_file_dev; - int64_t skip_file_ino; - time_t start_time; - - int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid); - void (*cleanup_gid)(void *private); - void *lookup_gid_data; - int64_t (*lookup_uid)(void *private, const char *uname, int64_t uid); - void (*cleanup_uid)(void *private); - void *lookup_uid_data; - - /* - * Full path of last file to satisfy symlink checks. - */ - struct archive_string path_safe; - - /* - * Cached stat data from disk for the current entry. - * If this is valid, pst points to st. Otherwise, - * pst is null. - */ - struct stat st; - struct stat *pst; - - /* Information about the object being restored right now. */ - struct archive_entry *entry; /* Entry being extracted. */ - char *name; /* Name of entry, possibly edited. */ - struct archive_string _name_data; /* backing store for 'name' */ - char *tmpname; /* Temporary name * */ - struct archive_string _tmpname_data; /* backing store for 'tmpname' */ - /* Tasks remaining for this object. */ - int todo; - /* Tasks deferred until end-of-archive. */ - int deferred; - /* Options requested by the client. */ - int flags; - /* Handle for the file we're restoring. */ - int fd; - /* Current offset for writing data to the file. */ - int64_t offset; - /* Last offset actually written to disk. */ - int64_t fd_offset; - /* Total bytes actually written to files. */ - int64_t total_bytes_written; - /* Maximum size of file, -1 if unknown. */ - int64_t filesize; - /* Dir we were in before this restore; only for deep paths. */ - int restore_pwd; - /* Mode we should use for this entry; affected by _PERM and umask. */ - mode_t mode; - /* UID/GID to use in restoring this entry. */ - int64_t uid; - int64_t gid; - /* - * HFS+ Compression. - */ - /* Xattr "com.apple.decmpfs". */ - uint32_t decmpfs_attr_size; - unsigned char *decmpfs_header_p; - /* ResourceFork set options used for fsetxattr. */ - int rsrc_xattr_options; - /* Xattr "com.apple.ResourceFork". */ - unsigned char *resource_fork; - size_t resource_fork_allocated_size; - unsigned int decmpfs_block_count; - uint32_t *decmpfs_block_info; - /* Buffer for compressed data. */ - unsigned char *compressed_buffer; - size_t compressed_buffer_size; - size_t compressed_buffer_remaining; - /* The offset of the ResourceFork where compressed data will - * be placed. */ - uint32_t compressed_rsrc_position; - uint32_t compressed_rsrc_position_v; - /* Buffer for uncompressed data. */ - char *uncompressed_buffer; - size_t block_remaining_bytes; - size_t file_remaining_bytes; -#ifdef HAVE_ZLIB_H - z_stream stream; - int stream_valid; - int decmpfs_compression_level; -#endif -}; - -/* - * Default mode for dirs created automatically (will be modified by umask). - * Note that POSIX specifies 0777 for implicitly-created dirs, "modified - * by the process' file creation mask." - */ -#define DEFAULT_DIR_MODE 0777 -/* - * Dir modes are restored in two steps: During the extraction, the permissions - * in the archive are modified to match the following limits. During - * the post-extract fixup pass, the permissions from the archive are - * applied. - */ -#define MINIMUM_DIR_MODE 0700 -#define MAXIMUM_DIR_MODE 0775 - -/* - * Maximum uncompressed size of a decmpfs block. - */ -#define MAX_DECMPFS_BLOCK_SIZE (64 * 1024) -/* - * HFS+ compression type. - */ -#define CMP_XATTR 3/* Compressed data in xattr. */ -#define CMP_RESOURCE_FORK 4/* Compressed data in resource fork. */ -/* - * HFS+ compression resource fork. - */ -#define RSRC_H_SIZE 260 /* Base size of Resource fork header. */ -#define RSRC_F_SIZE 50 /* Size of Resource fork footer. */ -/* Size to write compressed data to resource fork. */ -#define COMPRESSED_W_SIZE (64 * 1024) -/* decmpfs definitions. */ -#define MAX_DECMPFS_XATTR_SIZE 3802 -#ifndef DECMPFS_XATTR_NAME -#define DECMPFS_XATTR_NAME "com.apple.decmpfs" -#endif -#define DECMPFS_MAGIC 0x636d7066 -#define DECMPFS_COMPRESSION_MAGIC 0 -#define DECMPFS_COMPRESSION_TYPE 4 -#define DECMPFS_UNCOMPRESSED_SIZE 8 -#define DECMPFS_HEADER_SIZE 16 - -#define HFS_BLOCKS(s) ((s) >> 12) - - -static int la_opendirat(int, const char *); -static int la_mktemp(struct archive_write_disk *); -static int la_verify_filetype(mode_t, __LA_MODE_T); -static void fsobj_error(int *, struct archive_string *, int, const char *, - const char *); -static int check_symlinks_fsobj(char *, int *, struct archive_string *, - int, int); -static int check_symlinks(struct archive_write_disk *); -static int create_filesystem_object(struct archive_write_disk *); -static struct fixup_entry *current_fixup(struct archive_write_disk *, - const char *pathname); -#if defined(HAVE_FCHDIR) && defined(PATH_MAX) -static void edit_deep_directories(struct archive_write_disk *ad); -#endif -static int cleanup_pathname_fsobj(char *, int *, struct archive_string *, - int); -static int cleanup_pathname(struct archive_write_disk *); -static int create_dir(struct archive_write_disk *, char *); -static int create_parent_dir(struct archive_write_disk *, char *); -static ssize_t hfs_write_data_block(struct archive_write_disk *, - const char *, size_t); -static int fixup_appledouble(struct archive_write_disk *, const char *); -static int older(struct stat *, struct archive_entry *); -static int restore_entry(struct archive_write_disk *); -static int set_mac_metadata(struct archive_write_disk *, const char *, - const void *, size_t); -static int set_xattrs(struct archive_write_disk *); -static int clear_nochange_fflags(struct archive_write_disk *); -static int set_fflags(struct archive_write_disk *); -static int set_fflags_platform(struct archive_write_disk *, int fd, - const char *name, mode_t mode, - unsigned long fflags_set, unsigned long fflags_clear); -static int set_ownership(struct archive_write_disk *); -static int set_mode(struct archive_write_disk *, int mode); -static int set_time(int, int, const char *, time_t, long, time_t, long); -static int set_times(struct archive_write_disk *, int, int, const char *, - time_t, long, time_t, long, time_t, long, time_t, long); -static int set_times_from_entry(struct archive_write_disk *); -static struct fixup_entry *sort_dir_list(struct fixup_entry *p); -static ssize_t write_data_block(struct archive_write_disk *, - const char *, size_t); -static void close_file_descriptor(struct archive_write_disk *); - -static int _archive_write_disk_close(struct archive *); -static int _archive_write_disk_free(struct archive *); -static int _archive_write_disk_header(struct archive *, - struct archive_entry *); -static int64_t _archive_write_disk_filter_bytes(struct archive *, int); -static int _archive_write_disk_finish_entry(struct archive *); -static ssize_t _archive_write_disk_data(struct archive *, const void *, - size_t); -static ssize_t _archive_write_disk_data_block(struct archive *, const void *, - size_t, int64_t); - -static int -la_mktemp(struct archive_write_disk *a) -{ - int oerrno, fd; - mode_t mode; - - archive_string_empty(&a->_tmpname_data); - archive_string_sprintf(&a->_tmpname_data, "%s.XXXXXX", a->name); - a->tmpname = a->_tmpname_data.s; - - fd = __archive_mkstemp(a->tmpname); - if (fd == -1) - return -1; - - mode = a->mode & 0777 & ~a->user_umask; - if (fchmod(fd, mode) == -1) { - oerrno = errno; - close(fd); - errno = oerrno; - return -1; - } - return fd; -} - -static int -la_opendirat(int fd, const char *path) { - const int flags = O_CLOEXEC -#if defined(O_BINARY) - | O_BINARY -#endif -#if defined(O_DIRECTORY) - | O_DIRECTORY -#endif -#if defined(O_PATH) - | O_PATH -#elif defined(O_SEARCH) - | O_SEARCH -#elif defined(__FreeBSD__) && defined(O_EXEC) - | O_EXEC -#else - | O_RDONLY -#endif - ; - -#if !defined(HAVE_OPENAT) - if (fd != AT_FDCWD) { - errno = ENOTSUP; - return (-1); - } else - return (open(path, flags)); -#else - return (openat(fd, path, flags)); -#endif -} - -static int -la_verify_filetype(mode_t mode, __LA_MODE_T filetype) { - int ret = 0; - - switch (filetype) { - case AE_IFREG: - ret = (S_ISREG(mode)); - break; - case AE_IFDIR: - ret = (S_ISDIR(mode)); - break; - case AE_IFLNK: - ret = (S_ISLNK(mode)); - break; - case AE_IFSOCK: - ret = (S_ISSOCK(mode)); - break; - case AE_IFCHR: - ret = (S_ISCHR(mode)); - break; - case AE_IFBLK: - ret = (S_ISBLK(mode)); - break; - case AE_IFIFO: - ret = (S_ISFIFO(mode)); - break; - default: - break; - } - - return (ret); -} - -static int -lazy_stat(struct archive_write_disk *a) -{ - if (a->pst != NULL) { - /* Already have stat() data available. */ - return (ARCHIVE_OK); - } -#ifdef HAVE_FSTAT - if (a->fd >= 0 && fstat(a->fd, &a->st) == 0) { - a->pst = &a->st; - return (ARCHIVE_OK); - } -#endif - /* - * XXX At this point, symlinks should not be hit, otherwise - * XXX a race occurred. Do we want to check explicitly for that? - */ -#ifdef HAVE_LSTAT - if (lstat(a->name, &a->st) == 0) -#else - if (la_stat(a->name, &a->st) == 0) -#endif - { - a->pst = &a->st; - return (ARCHIVE_OK); - } - archive_set_error(&a->archive, errno, "Couldn't stat file"); - return (ARCHIVE_WARN); -} - -static const struct archive_vtable -archive_write_disk_vtable = { - .archive_close = _archive_write_disk_close, - .archive_filter_bytes = _archive_write_disk_filter_bytes, - .archive_free = _archive_write_disk_free, - .archive_write_header = _archive_write_disk_header, - .archive_write_finish_entry = _archive_write_disk_finish_entry, - .archive_write_data = _archive_write_disk_data, - .archive_write_data_block = _archive_write_disk_data_block, -}; - -static int64_t -_archive_write_disk_filter_bytes(struct archive *_a, int n) -{ - struct archive_write_disk *a = (struct archive_write_disk *)_a; - (void)n; /* UNUSED */ - if (n == -1 || n == 0) - return (a->total_bytes_written); - return (-1); -} - - -int -archive_write_disk_set_options(struct archive *_a, int flags) -{ - struct archive_write_disk *a = (struct archive_write_disk *)_a; - - a->flags = flags; - return (ARCHIVE_OK); -} - - -/* - * Extract this entry to disk. - * - * TODO: Validate hardlinks. According to the standards, we're - * supposed to check each extracted hardlink and squawk if it refers - * to a file that we didn't restore. I'm not entirely convinced this - * is a good idea, but more importantly: Is there any way to validate - * hardlinks without keeping a complete list of filenames from the - * entire archive?? Ugh. - * - */ -static int -_archive_write_disk_header(struct archive *_a, struct archive_entry *entry) -{ - struct archive_write_disk *a = (struct archive_write_disk *)_a; - struct fixup_entry *fe; - const char *linkname; - int ret, r; - - archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, - ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, - "archive_write_disk_header"); - archive_clear_error(&a->archive); - if (a->archive.state & ARCHIVE_STATE_DATA) { - r = _archive_write_disk_finish_entry(&a->archive); - if (r == ARCHIVE_FATAL) - return (r); - } - - /* Set up for this particular entry. */ - a->pst = NULL; - a->current_fixup = NULL; - a->deferred = 0; - if (a->entry) { - archive_entry_free(a->entry); - a->entry = NULL; - } - a->entry = archive_entry_clone(entry); - a->fd = -1; - a->fd_offset = 0; - a->offset = 0; - a->restore_pwd = -1; - a->uid = a->user_uid; - a->mode = archive_entry_mode(a->entry); - if (archive_entry_size_is_set(a->entry)) - a->filesize = archive_entry_size(a->entry); - else - a->filesize = -1; - archive_strcpy(&(a->_name_data), archive_entry_pathname(a->entry)); - a->name = a->_name_data.s; - archive_clear_error(&a->archive); - - /* - * Clean up the requested path. This is necessary for correct - * dir restores; the dir restore logic otherwise gets messed - * up by nonsense like "dir/.". - */ - ret = cleanup_pathname(a); - if (ret != ARCHIVE_OK) - return (ret); - - /* - * Check if we have a hardlink that points to itself. - */ - linkname = archive_entry_hardlink(a->entry); - if (linkname != NULL && strcmp(a->name, linkname) == 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Skipping hardlink pointing to itself: %s", - a->name); - return (ARCHIVE_WARN); - } - - /* - * Query the umask so we get predictable mode settings. - * This gets done on every call to _write_header in case the - * user edits their umask during the extraction for some - * reason. - */ - umask(a->user_umask = umask(0)); - - /* Figure out what we need to do for this entry. */ - a->todo = TODO_MODE_BASE; - if (a->flags & ARCHIVE_EXTRACT_PERM) { - a->todo |= TODO_MODE_FORCE; /* Be pushy about permissions. */ - /* - * SGID requires an extra "check" step because we - * cannot easily predict the GID that the system will - * assign. (Different systems assign GIDs to files - * based on a variety of criteria, including process - * credentials and the gid of the enclosing - * directory.) We can only restore the SGID bit if - * the file has the right GID, and we only know the - * GID if we either set it (see set_ownership) or if - * we've actually called stat() on the file after it - * was restored. Since there are several places at - * which we might verify the GID, we need a TODO bit - * to keep track. - */ - if (a->mode & S_ISGID) - a->todo |= TODO_SGID | TODO_SGID_CHECK; - /* - * Verifying the SUID is simpler, but can still be - * done in multiple ways, hence the separate "check" bit. - */ - if (a->mode & S_ISUID) - a->todo |= TODO_SUID | TODO_SUID_CHECK; - } else { - /* - * User didn't request full permissions, so don't - * restore SUID, SGID bits and obey umask. - */ - a->mode &= ~S_ISUID; - a->mode &= ~S_ISGID; - a->mode &= ~S_ISVTX; - a->mode &= ~a->user_umask; - } - if (a->flags & ARCHIVE_EXTRACT_OWNER) - a->todo |= TODO_OWNER; - if (a->flags & ARCHIVE_EXTRACT_TIME) - a->todo |= TODO_TIMES; - if (a->flags & ARCHIVE_EXTRACT_ACL) { -#if ARCHIVE_ACL_DARWIN - /* - * On MacOS, platform ACLs get stored in mac_metadata, too. - * If we intend to extract mac_metadata and it is present - * we skip extracting libarchive NFSv4 ACLs. - */ - size_t metadata_size; - - if ((a->flags & ARCHIVE_EXTRACT_MAC_METADATA) == 0 || - archive_entry_mac_metadata(a->entry, - &metadata_size) == NULL || metadata_size == 0) -#endif -#if ARCHIVE_ACL_LIBRICHACL - /* - * RichACLs are stored in an extended attribute. - * If we intend to extract extended attributes and have this - * attribute we skip extracting libarchive NFSv4 ACLs. - */ - short extract_acls = 1; - if (a->flags & ARCHIVE_EXTRACT_XATTR && ( - archive_entry_acl_types(a->entry) & - ARCHIVE_ENTRY_ACL_TYPE_NFS4)) { - const char *attr_name; - const void *attr_value; - size_t attr_size; - int i = archive_entry_xattr_reset(a->entry); - while (i--) { - archive_entry_xattr_next(a->entry, &attr_name, - &attr_value, &attr_size); - if (attr_name != NULL && attr_value != NULL && - attr_size > 0 && strcmp(attr_name, - "trusted.richacl") == 0) { - extract_acls = 0; - break; - } - } - } - if (extract_acls) -#endif -#if ARCHIVE_ACL_DARWIN || ARCHIVE_ACL_LIBRICHACL - { -#endif - if (archive_entry_filetype(a->entry) == AE_IFDIR) - a->deferred |= TODO_ACLS; - else - a->todo |= TODO_ACLS; -#if ARCHIVE_ACL_DARWIN || ARCHIVE_ACL_LIBRICHACL - } -#endif - } - if (a->flags & ARCHIVE_EXTRACT_MAC_METADATA) { - if (archive_entry_filetype(a->entry) == AE_IFDIR) - a->deferred |= TODO_MAC_METADATA; - else - a->todo |= TODO_MAC_METADATA; - } -#if defined(__APPLE__) && defined(UF_COMPRESSED) && defined(HAVE_ZLIB_H) - if ((a->flags & ARCHIVE_EXTRACT_NO_HFS_COMPRESSION) == 0) { - unsigned long set, clear; - archive_entry_fflags(a->entry, &set, &clear); - if ((set & ~clear) & UF_COMPRESSED) { - a->todo |= TODO_HFS_COMPRESSION; - a->decmpfs_block_count = (unsigned)-1; - } - } - if ((a->flags & ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED) != 0 && - (a->mode & AE_IFMT) == AE_IFREG && a->filesize > 0) { - a->todo |= TODO_HFS_COMPRESSION; - a->decmpfs_block_count = (unsigned)-1; - } - { - const char *p; - - /* Check if the current file name is a type of the - * resource fork file. */ - p = strrchr(a->name, '/'); - if (p == NULL) - p = a->name; - else - p++; - if (p[0] == '.' && p[1] == '_') { - /* Do not compress "._XXX" files. */ - a->todo &= ~TODO_HFS_COMPRESSION; - if (a->filesize > 0) - a->todo |= TODO_APPLEDOUBLE; - } - } -#endif - - if (a->flags & ARCHIVE_EXTRACT_XATTR) { -#if ARCHIVE_XATTR_DARWIN - /* - * On MacOS, extended attributes get stored in mac_metadata, - * too. If we intend to extract mac_metadata and it is present - * we skip extracting extended attributes. - */ - size_t metadata_size; - - if ((a->flags & ARCHIVE_EXTRACT_MAC_METADATA) == 0 || - archive_entry_mac_metadata(a->entry, - &metadata_size) == NULL || metadata_size == 0) -#endif - a->todo |= TODO_XATTR; - } - if (a->flags & ARCHIVE_EXTRACT_FFLAGS) - a->todo |= TODO_FFLAGS; - if (a->flags & ARCHIVE_EXTRACT_SECURE_SYMLINKS) { - ret = check_symlinks(a); - if (ret != ARCHIVE_OK) - return (ret); - } -#if defined(HAVE_FCHDIR) && defined(PATH_MAX) - /* If path exceeds PATH_MAX, shorten the path. */ - edit_deep_directories(a); -#endif - - ret = restore_entry(a); - -#if defined(__APPLE__) && defined(UF_COMPRESSED) && defined(HAVE_ZLIB_H) - /* - * Check if the filesystem the file is restoring on supports - * HFS+ Compression. If not, cancel HFS+ Compression. - */ - if (a->todo | TODO_HFS_COMPRESSION) { - /* - * NOTE: UF_COMPRESSED is ignored even if the filesystem - * supports HFS+ Compression because the file should - * have at least an extended attribute "com.apple.decmpfs" - * before the flag is set to indicate that the file have - * been compressed. If the filesystem does not support - * HFS+ Compression the system call will fail. - */ - if (a->fd < 0 || fchflags(a->fd, UF_COMPRESSED) != 0) - a->todo &= ~TODO_HFS_COMPRESSION; - } -#endif - - /* - * TODO: There are rumours that some extended attributes must - * be restored before file data is written. If this is true, - * then we either need to write all extended attributes both - * before and after restoring the data, or find some rule for - * determining which must go first and which last. Due to the - * many ways people are using xattrs, this may prove to be an - * intractable problem. - */ - -#ifdef HAVE_FCHDIR - /* If we changed directory above, restore it here. */ - if (a->restore_pwd >= 0) { - r = fchdir(a->restore_pwd); - if (r != 0) { - archive_set_error(&a->archive, errno, - "chdir() failure"); - ret = ARCHIVE_FATAL; - } - close(a->restore_pwd); - a->restore_pwd = -1; - } -#endif - - /* - * Fixup uses the unedited pathname from archive_entry_pathname(), - * because it is relative to the base dir and the edited path - * might be relative to some intermediate dir as a result of the - * deep restore logic. - */ - if (a->deferred & TODO_MODE) { - fe = current_fixup(a, archive_entry_pathname(entry)); - if (fe == NULL) - return (ARCHIVE_FATAL); - fe->filetype = archive_entry_filetype(entry); - fe->fixup |= TODO_MODE_BASE; - fe->mode = a->mode; - } - - if ((a->deferred & TODO_TIMES) - && (archive_entry_mtime_is_set(entry) - || archive_entry_atime_is_set(entry))) { - fe = current_fixup(a, archive_entry_pathname(entry)); - if (fe == NULL) - return (ARCHIVE_FATAL); - fe->filetype = archive_entry_filetype(entry); - fe->mode = a->mode; - fe->fixup |= TODO_TIMES; - if (archive_entry_atime_is_set(entry)) { - fe->atime = archive_entry_atime(entry); - fe->atime_nanos = archive_entry_atime_nsec(entry); - } else { - /* If atime is unset, use start time. */ - fe->atime = a->start_time; - fe->atime_nanos = 0; - } - if (archive_entry_mtime_is_set(entry)) { - fe->mtime = archive_entry_mtime(entry); - fe->mtime_nanos = archive_entry_mtime_nsec(entry); - } else { - /* If mtime is unset, use start time. */ - fe->mtime = a->start_time; - fe->mtime_nanos = 0; - } - if (archive_entry_birthtime_is_set(entry)) { - fe->birthtime = archive_entry_birthtime(entry); - fe->birthtime_nanos = archive_entry_birthtime_nsec( - entry); - } else { - /* If birthtime is unset, use mtime. */ - fe->birthtime = fe->mtime; - fe->birthtime_nanos = fe->mtime_nanos; - } - } - - if (a->deferred & TODO_ACLS) { - fe = current_fixup(a, archive_entry_pathname(entry)); - if (fe == NULL) - return (ARCHIVE_FATAL); - fe->filetype = archive_entry_filetype(entry); - fe->fixup |= TODO_ACLS; - archive_acl_copy(&fe->acl, archive_entry_acl(entry)); - } - - if (a->deferred & TODO_MAC_METADATA) { - const void *metadata; - size_t metadata_size; - metadata = archive_entry_mac_metadata(a->entry, &metadata_size); - if (metadata != NULL && metadata_size > 0) { - fe = current_fixup(a, archive_entry_pathname(entry)); - if (fe == NULL) - return (ARCHIVE_FATAL); - fe->filetype = archive_entry_filetype(entry); - fe->mac_metadata = malloc(metadata_size); - if (fe->mac_metadata != NULL) { - memcpy(fe->mac_metadata, metadata, - metadata_size); - fe->mac_metadata_size = metadata_size; - fe->fixup |= TODO_MAC_METADATA; - } - } - } - - if (a->deferred & TODO_FFLAGS) { - fe = current_fixup(a, archive_entry_pathname(entry)); - if (fe == NULL) - return (ARCHIVE_FATAL); - fe->filetype = archive_entry_filetype(entry); - fe->fixup |= TODO_FFLAGS; - /* TODO: Complete this.. defer fflags from below. */ - } - - /* We've created the object and are ready to pour data into it. */ - if (ret >= ARCHIVE_WARN) - a->archive.state = ARCHIVE_STATE_DATA; - /* - * If it's not open, tell our client not to try writing. - * In particular, dirs, links, etc, don't get written to. - */ - if (a->fd < 0) { - archive_entry_set_size(entry, 0); - a->filesize = 0; - } - - return (ret); -} - -int -archive_write_disk_set_skip_file(struct archive *_a, la_int64_t d, la_int64_t i) -{ - struct archive_write_disk *a = (struct archive_write_disk *)_a; - archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_write_disk_set_skip_file"); - a->skip_file_set = 1; - a->skip_file_dev = d; - a->skip_file_ino = i; - return (ARCHIVE_OK); -} - -static ssize_t -write_data_block(struct archive_write_disk *a, const char *buff, size_t size) -{ - uint64_t start_size = size; - ssize_t bytes_written = 0; - ssize_t block_size = 0, bytes_to_write; - - if (size == 0) - return (ARCHIVE_OK); - - if (a->filesize == 0 || a->fd < 0) { - archive_set_error(&a->archive, 0, - "Attempt to write to an empty file"); - return (ARCHIVE_WARN); - } - - if (a->flags & ARCHIVE_EXTRACT_SPARSE) { -#if HAVE_STRUCT_STAT_ST_BLKSIZE - int r; - if ((r = lazy_stat(a)) != ARCHIVE_OK) - return (r); - block_size = a->pst->st_blksize; -#else - /* XXX TODO XXX Is there a more appropriate choice here ? */ - /* This needn't match the filesystem allocation size. */ - block_size = 16*1024; -#endif - } - - /* If this write would run beyond the file size, truncate it. */ - if (a->filesize >= 0 && (int64_t)(a->offset + size) > a->filesize) - start_size = size = (size_t)(a->filesize - a->offset); - - /* Write the data. */ - while (size > 0) { - if (block_size == 0) { - bytes_to_write = size; - } else { - /* We're sparsifying the file. */ - const char *p, *end; - int64_t block_end; - - /* Skip leading zero bytes. */ - for (p = buff, end = buff + size; p < end; ++p) { - if (*p != '\0') - break; - } - a->offset += p - buff; - size -= p - buff; - buff = p; - if (size == 0) - break; - - /* Calculate next block boundary after offset. */ - block_end - = (a->offset / block_size + 1) * block_size; - - /* If the adjusted write would cross block boundary, - * truncate it to the block boundary. */ - bytes_to_write = size; - if (a->offset + bytes_to_write > block_end) - bytes_to_write = block_end - a->offset; - } - /* Seek if necessary to the specified offset. */ - if (a->offset != a->fd_offset) { - if (lseek(a->fd, a->offset, SEEK_SET) < 0) { - archive_set_error(&a->archive, errno, - "Seek failed"); - return (ARCHIVE_FATAL); - } - a->fd_offset = a->offset; - } - bytes_written = write(a->fd, buff, bytes_to_write); - if (bytes_written < 0) { - archive_set_error(&a->archive, errno, "Write failed"); - return (ARCHIVE_WARN); - } - buff += bytes_written; - size -= bytes_written; - a->total_bytes_written += bytes_written; - a->offset += bytes_written; - a->fd_offset = a->offset; - } - return (start_size - size); -} - -#if defined(__APPLE__) && defined(UF_COMPRESSED) && defined(HAVE_SYS_XATTR_H)\ - && defined(HAVE_ZLIB_H) - -/* - * Set UF_COMPRESSED file flag. - * This have to be called after hfs_write_decmpfs() because if the - * file does not have "com.apple.decmpfs" xattr the flag is ignored. - */ -static int -hfs_set_compressed_fflag(struct archive_write_disk *a) -{ - int r; - - if ((r = lazy_stat(a)) != ARCHIVE_OK) - return (r); - - a->st.st_flags |= UF_COMPRESSED; - if (fchflags(a->fd, a->st.st_flags) != 0) { - archive_set_error(&a->archive, errno, - "Failed to set UF_COMPRESSED file flag"); - return (ARCHIVE_WARN); - } - return (ARCHIVE_OK); -} - -/* - * HFS+ Compression decmpfs - * - * +------------------------------+ +0 - * | Magic(LE 4 bytes) | - * +------------------------------+ - * | Type(LE 4 bytes) | - * +------------------------------+ - * | Uncompressed size(LE 8 bytes)| - * +------------------------------+ +16 - * | | - * | Compressed data | - * | (Placed only if Type == 3) | - * | | - * +------------------------------+ +3802 = MAX_DECMPFS_XATTR_SIZE - * - * Type is 3: decmpfs has compressed data. - * Type is 4: Resource Fork has compressed data. - */ -/* - * Write "com.apple.decmpfs" - */ -static int -hfs_write_decmpfs(struct archive_write_disk *a) -{ - int r; - uint32_t compression_type; - - r = fsetxattr(a->fd, DECMPFS_XATTR_NAME, a->decmpfs_header_p, - a->decmpfs_attr_size, 0, 0); - if (r < 0) { - archive_set_error(&a->archive, errno, - "Cannot restore xattr:%s", DECMPFS_XATTR_NAME); - compression_type = archive_le32dec( - &a->decmpfs_header_p[DECMPFS_COMPRESSION_TYPE]); - if (compression_type == CMP_RESOURCE_FORK) - fremovexattr(a->fd, XATTR_RESOURCEFORK_NAME, - XATTR_SHOWCOMPRESSION); - return (ARCHIVE_WARN); - } - return (ARCHIVE_OK); -} - -/* - * HFS+ Compression Resource Fork - * - * +-----------------------------+ - * | Header(260 bytes) | - * +-----------------------------+ - * | Block count(LE 4 bytes) | - * +-----------------------------+ --+ - * +-- | Offset (LE 4 bytes) | | - * | | [distance from Block count] | | Block 0 - * | +-----------------------------+ | - * | | Compressed size(LE 4 bytes) | | - * | +-----------------------------+ --+ - * | | | - * | | .................. | - * | | | - * | +-----------------------------+ --+ - * | | Offset (LE 4 bytes) | | - * | +-----------------------------+ | Block (Block count -1) - * | | Compressed size(LE 4 bytes) | | - * +-> +-----------------------------+ --+ - * | Compressed data(n bytes) | Block 0 - * +-----------------------------+ - * | | - * | .................. | - * | | - * +-----------------------------+ - * | Compressed data(n bytes) | Block (Block count -1) - * +-----------------------------+ - * | Footer(50 bytes) | - * +-----------------------------+ - * - */ -/* - * Write the header of "com.apple.ResourceFork" - */ -static int -hfs_write_resource_fork(struct archive_write_disk *a, unsigned char *buff, - size_t bytes, uint32_t position) -{ - int ret; - - ret = fsetxattr(a->fd, XATTR_RESOURCEFORK_NAME, buff, bytes, - position, a->rsrc_xattr_options); - if (ret < 0) { - archive_set_error(&a->archive, errno, - "Cannot restore xattr: %s at %u pos %u bytes", - XATTR_RESOURCEFORK_NAME, - (unsigned)position, - (unsigned)bytes); - return (ARCHIVE_WARN); - } - a->rsrc_xattr_options &= ~XATTR_CREATE; - return (ARCHIVE_OK); -} - -static int -hfs_write_compressed_data(struct archive_write_disk *a, size_t bytes_compressed) -{ - int ret; - - ret = hfs_write_resource_fork(a, a->compressed_buffer, - bytes_compressed, a->compressed_rsrc_position); - if (ret == ARCHIVE_OK) - a->compressed_rsrc_position += bytes_compressed; - return (ret); -} - -static int -hfs_write_resource_fork_header(struct archive_write_disk *a) -{ - unsigned char *buff; - uint32_t rsrc_bytes; - uint32_t rsrc_header_bytes; - - /* - * Write resource fork header + block info. - */ - buff = a->resource_fork; - rsrc_bytes = a->compressed_rsrc_position - RSRC_F_SIZE; - rsrc_header_bytes = - RSRC_H_SIZE + /* Header base size. */ - 4 + /* Block count. */ - (a->decmpfs_block_count * 8);/* Block info */ - archive_be32enc(buff, 0x100); - archive_be32enc(buff + 4, rsrc_bytes); - archive_be32enc(buff + 8, rsrc_bytes - 256); - archive_be32enc(buff + 12, 0x32); - memset(buff + 16, 0, 240); - archive_be32enc(buff + 256, rsrc_bytes - 260); - return hfs_write_resource_fork(a, buff, rsrc_header_bytes, 0); -} - -static size_t -hfs_set_resource_fork_footer(unsigned char *buff, size_t buff_size) -{ - static const char rsrc_footer[RSRC_F_SIZE] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x1c, 0x00, 0x32, 0x00, 0x00, 'c', 'm', - 'p', 'f', 0x00, 0x00, 0x00, 0x0a, 0x00, 0x01, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00 - }; - if (buff_size < sizeof(rsrc_footer)) - return (0); - memcpy(buff, rsrc_footer, sizeof(rsrc_footer)); - return (sizeof(rsrc_footer)); -} - -static int -hfs_reset_compressor(struct archive_write_disk *a) -{ - int ret; - - if (a->stream_valid) - ret = deflateReset(&a->stream); - else - ret = deflateInit(&a->stream, a->decmpfs_compression_level); - - if (ret != Z_OK) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Failed to initialize compressor"); - return (ARCHIVE_FATAL); - } else - a->stream_valid = 1; - - return (ARCHIVE_OK); -} - -static int -hfs_decompress(struct archive_write_disk *a) -{ - uint32_t *block_info; - unsigned int block_count; - uint32_t data_pos, data_size; - ssize_t r; - ssize_t bytes_written, bytes_to_write; - unsigned char *b; - - block_info = (uint32_t *)(a->resource_fork + RSRC_H_SIZE); - block_count = archive_le32dec(block_info++); - while (block_count--) { - data_pos = RSRC_H_SIZE + archive_le32dec(block_info++); - data_size = archive_le32dec(block_info++); - r = fgetxattr(a->fd, XATTR_RESOURCEFORK_NAME, - a->compressed_buffer, data_size, data_pos, 0); - if (r != data_size) { - archive_set_error(&a->archive, - (r < 0)?errno:ARCHIVE_ERRNO_MISC, - "Failed to read resource fork"); - return (ARCHIVE_WARN); - } - if (a->compressed_buffer[0] == 0xff) { - bytes_to_write = data_size -1; - b = a->compressed_buffer + 1; - } else { - uLong dest_len = MAX_DECMPFS_BLOCK_SIZE; - int zr; - - zr = uncompress((Bytef *)a->uncompressed_buffer, - &dest_len, a->compressed_buffer, data_size); - if (zr != Z_OK) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Failed to decompress resource fork"); - return (ARCHIVE_WARN); - } - bytes_to_write = dest_len; - b = (unsigned char *)a->uncompressed_buffer; - } - do { - bytes_written = write(a->fd, b, bytes_to_write); - if (bytes_written < 0) { - archive_set_error(&a->archive, errno, - "Write failed"); - return (ARCHIVE_WARN); - } - bytes_to_write -= bytes_written; - b += bytes_written; - } while (bytes_to_write > 0); - } - r = fremovexattr(a->fd, XATTR_RESOURCEFORK_NAME, 0); - if (r == -1) { - archive_set_error(&a->archive, errno, - "Failed to remove resource fork"); - return (ARCHIVE_WARN); - } - return (ARCHIVE_OK); -} - -static int -hfs_drive_compressor(struct archive_write_disk *a, const char *buff, - size_t size) -{ - unsigned char *buffer_compressed; - size_t bytes_compressed; - size_t bytes_used; - int ret; - - ret = hfs_reset_compressor(a); - if (ret != ARCHIVE_OK) - return (ret); - - if (a->compressed_buffer == NULL) { - size_t block_size; - - block_size = COMPRESSED_W_SIZE + RSRC_F_SIZE + - + compressBound(MAX_DECMPFS_BLOCK_SIZE); - a->compressed_buffer = malloc(block_size); - if (a->compressed_buffer == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Resource Fork"); - return (ARCHIVE_FATAL); - } - a->compressed_buffer_size = block_size; - a->compressed_buffer_remaining = block_size; - } - - buffer_compressed = a->compressed_buffer + - a->compressed_buffer_size - a->compressed_buffer_remaining; - a->stream.next_in = (Bytef *)(uintptr_t)(const void *)buff; - a->stream.avail_in = size; - a->stream.next_out = buffer_compressed; - a->stream.avail_out = a->compressed_buffer_remaining; - do { - ret = deflate(&a->stream, Z_FINISH); - switch (ret) { - case Z_OK: - case Z_STREAM_END: - break; - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Failed to compress data"); - return (ARCHIVE_FAILED); - } - } while (ret == Z_OK); - bytes_compressed = a->compressed_buffer_remaining - a->stream.avail_out; - - /* - * If the compressed size is larger than the original size, - * throw away compressed data, use uncompressed data instead. - */ - if (bytes_compressed > size) { - buffer_compressed[0] = 0xFF;/* uncompressed marker. */ - memcpy(buffer_compressed + 1, buff, size); - bytes_compressed = size + 1; - } - a->compressed_buffer_remaining -= bytes_compressed; - - /* - * If the compressed size is smaller than MAX_DECMPFS_XATTR_SIZE - * and the block count in the file is only one, store compressed - * data to decmpfs xattr instead of the resource fork. - */ - if (a->decmpfs_block_count == 1 && - (a->decmpfs_attr_size + bytes_compressed) - <= MAX_DECMPFS_XATTR_SIZE) { - archive_le32enc(&a->decmpfs_header_p[DECMPFS_COMPRESSION_TYPE], - CMP_XATTR); - memcpy(a->decmpfs_header_p + DECMPFS_HEADER_SIZE, - buffer_compressed, bytes_compressed); - a->decmpfs_attr_size += bytes_compressed; - a->compressed_buffer_remaining = a->compressed_buffer_size; - /* - * Finish HFS+ Compression. - * - Write the decmpfs xattr. - * - Set the UF_COMPRESSED file flag. - */ - ret = hfs_write_decmpfs(a); - if (ret == ARCHIVE_OK) - ret = hfs_set_compressed_fflag(a); - return (ret); - } - - /* Update block info. */ - archive_le32enc(a->decmpfs_block_info++, - a->compressed_rsrc_position_v - RSRC_H_SIZE); - archive_le32enc(a->decmpfs_block_info++, bytes_compressed); - a->compressed_rsrc_position_v += bytes_compressed; - - /* - * Write the compressed data to the resource fork. - */ - bytes_used = a->compressed_buffer_size - a->compressed_buffer_remaining; - while (bytes_used >= COMPRESSED_W_SIZE) { - ret = hfs_write_compressed_data(a, COMPRESSED_W_SIZE); - if (ret != ARCHIVE_OK) - return (ret); - bytes_used -= COMPRESSED_W_SIZE; - if (bytes_used > COMPRESSED_W_SIZE) - memmove(a->compressed_buffer, - a->compressed_buffer + COMPRESSED_W_SIZE, - bytes_used); - else - memcpy(a->compressed_buffer, - a->compressed_buffer + COMPRESSED_W_SIZE, - bytes_used); - } - a->compressed_buffer_remaining = a->compressed_buffer_size - bytes_used; - - /* - * If the current block is the last block, write the remaining - * compressed data and the resource fork footer. - */ - if (a->file_remaining_bytes == 0) { - size_t rsrc_size; - int64_t bk; - - /* Append the resource footer. */ - rsrc_size = hfs_set_resource_fork_footer( - a->compressed_buffer + bytes_used, - a->compressed_buffer_remaining); - ret = hfs_write_compressed_data(a, bytes_used + rsrc_size); - a->compressed_buffer_remaining = a->compressed_buffer_size; - - /* If the compressed size is not enough smaller than - * the uncompressed size. cancel HFS+ compression. - * TODO: study a behavior of ditto utility and improve - * the condition to fall back into no HFS+ compression. */ - bk = HFS_BLOCKS(a->compressed_rsrc_position); - bk += bk >> 7; - if (bk > HFS_BLOCKS(a->filesize)) - return hfs_decompress(a); - /* - * Write the resourcefork header. - */ - if (ret == ARCHIVE_OK) - ret = hfs_write_resource_fork_header(a); - /* - * Finish HFS+ Compression. - * - Write the decmpfs xattr. - * - Set the UF_COMPRESSED file flag. - */ - if (ret == ARCHIVE_OK) - ret = hfs_write_decmpfs(a); - if (ret == ARCHIVE_OK) - ret = hfs_set_compressed_fflag(a); - } - return (ret); -} - -static ssize_t -hfs_write_decmpfs_block(struct archive_write_disk *a, const char *buff, - size_t size) -{ - const char *buffer_to_write; - size_t bytes_to_write; - int ret; - - if (a->decmpfs_block_count == (unsigned)-1) { - void *new_block; - size_t new_size; - unsigned int block_count; - - if (a->decmpfs_header_p == NULL) { - new_block = malloc(MAX_DECMPFS_XATTR_SIZE - + sizeof(uint32_t)); - if (new_block == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for decmpfs"); - return (ARCHIVE_FATAL); - } - a->decmpfs_header_p = new_block; - } - a->decmpfs_attr_size = DECMPFS_HEADER_SIZE; - archive_le32enc(&a->decmpfs_header_p[DECMPFS_COMPRESSION_MAGIC], - DECMPFS_MAGIC); - archive_le32enc(&a->decmpfs_header_p[DECMPFS_COMPRESSION_TYPE], - CMP_RESOURCE_FORK); - archive_le64enc(&a->decmpfs_header_p[DECMPFS_UNCOMPRESSED_SIZE], - a->filesize); - - /* Calculate a block count of the file. */ - block_count = - (a->filesize + MAX_DECMPFS_BLOCK_SIZE -1) / - MAX_DECMPFS_BLOCK_SIZE; - /* - * Allocate buffer for resource fork. - * Set up related pointers; - */ - new_size = - RSRC_H_SIZE + /* header */ - 4 + /* Block count */ - (block_count * sizeof(uint32_t) * 2) + - RSRC_F_SIZE; /* footer */ - if (new_size > a->resource_fork_allocated_size) { - new_block = realloc(a->resource_fork, new_size); - if (new_block == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for ResourceFork"); - return (ARCHIVE_FATAL); - } - a->resource_fork_allocated_size = new_size; - a->resource_fork = new_block; - } - - /* Allocate uncompressed buffer */ - if (a->uncompressed_buffer == NULL) { - new_block = malloc(MAX_DECMPFS_BLOCK_SIZE); - if (new_block == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for decmpfs"); - return (ARCHIVE_FATAL); - } - a->uncompressed_buffer = new_block; - } - a->block_remaining_bytes = MAX_DECMPFS_BLOCK_SIZE; - a->file_remaining_bytes = a->filesize; - a->compressed_buffer_remaining = a->compressed_buffer_size; - - /* - * Set up a resource fork. - */ - a->rsrc_xattr_options = XATTR_CREATE; - /* Get the position where we are going to set a bunch - * of block info. */ - a->decmpfs_block_info = - (uint32_t *)(a->resource_fork + RSRC_H_SIZE); - /* Set the block count to the resource fork. */ - archive_le32enc(a->decmpfs_block_info++, block_count); - /* Get the position where we are going to set compressed - * data. */ - a->compressed_rsrc_position = - RSRC_H_SIZE + 4 + (block_count * 8); - a->compressed_rsrc_position_v = a->compressed_rsrc_position; - a->decmpfs_block_count = block_count; - } - - /* Ignore redundant bytes. */ - if (a->file_remaining_bytes == 0) - return ((ssize_t)size); - - /* Do not overrun a block size. */ - if (size > a->block_remaining_bytes) - bytes_to_write = a->block_remaining_bytes; - else - bytes_to_write = size; - /* Do not overrun the file size. */ - if (bytes_to_write > a->file_remaining_bytes) - bytes_to_write = a->file_remaining_bytes; - - /* For efficiency, if a copy length is full of the uncompressed - * buffer size, do not copy writing data to it. */ - if (bytes_to_write == MAX_DECMPFS_BLOCK_SIZE) - buffer_to_write = buff; - else { - memcpy(a->uncompressed_buffer + - MAX_DECMPFS_BLOCK_SIZE - a->block_remaining_bytes, - buff, bytes_to_write); - buffer_to_write = a->uncompressed_buffer; - } - a->block_remaining_bytes -= bytes_to_write; - a->file_remaining_bytes -= bytes_to_write; - - if (a->block_remaining_bytes == 0 || a->file_remaining_bytes == 0) { - ret = hfs_drive_compressor(a, buffer_to_write, - MAX_DECMPFS_BLOCK_SIZE - a->block_remaining_bytes); - if (ret < 0) - return (ret); - a->block_remaining_bytes = MAX_DECMPFS_BLOCK_SIZE; - } - /* Ignore redundant bytes. */ - if (a->file_remaining_bytes == 0) - return ((ssize_t)size); - return (bytes_to_write); -} - -static ssize_t -hfs_write_data_block(struct archive_write_disk *a, const char *buff, - size_t size) -{ - uint64_t start_size = size; - ssize_t bytes_written = 0; - ssize_t bytes_to_write; - - if (size == 0) - return (ARCHIVE_OK); - - if (a->filesize == 0 || a->fd < 0) { - archive_set_error(&a->archive, 0, - "Attempt to write to an empty file"); - return (ARCHIVE_WARN); - } - - /* If this write would run beyond the file size, truncate it. */ - if (a->filesize >= 0 && (int64_t)(a->offset + size) > a->filesize) - start_size = size = (size_t)(a->filesize - a->offset); - - /* Write the data. */ - while (size > 0) { - bytes_to_write = size; - /* Seek if necessary to the specified offset. */ - if (a->offset < a->fd_offset) { - /* Can't support backward move. */ - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Seek failed"); - return (ARCHIVE_FATAL); - } else if (a->offset > a->fd_offset) { - uint64_t skip = a->offset - a->fd_offset; - char nullblock[1024]; - - memset(nullblock, 0, sizeof(nullblock)); - while (skip > 0) { - if (skip > sizeof(nullblock)) - bytes_written = hfs_write_decmpfs_block( - a, nullblock, sizeof(nullblock)); - else - bytes_written = hfs_write_decmpfs_block( - a, nullblock, skip); - if (bytes_written < 0) { - archive_set_error(&a->archive, errno, - "Write failed"); - return (ARCHIVE_WARN); - } - skip -= bytes_written; - } - - a->fd_offset = a->offset; - } - bytes_written = - hfs_write_decmpfs_block(a, buff, bytes_to_write); - if (bytes_written < 0) - return (bytes_written); - buff += bytes_written; - size -= bytes_written; - a->total_bytes_written += bytes_written; - a->offset += bytes_written; - a->fd_offset = a->offset; - } - return (start_size - size); -} -#else -static ssize_t -hfs_write_data_block(struct archive_write_disk *a, const char *buff, - size_t size) -{ - return (write_data_block(a, buff, size)); -} -#endif - -static ssize_t -_archive_write_disk_data_block(struct archive *_a, - const void *buff, size_t size, int64_t offset) -{ - struct archive_write_disk *a = (struct archive_write_disk *)_a; - ssize_t r; - - archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, - ARCHIVE_STATE_DATA, "archive_write_data_block"); - - a->offset = offset; - if (a->todo & TODO_HFS_COMPRESSION) - r = hfs_write_data_block(a, buff, size); - else - r = write_data_block(a, buff, size); - if (r < ARCHIVE_OK) - return (r); - if ((size_t)r < size) { - archive_set_error(&a->archive, 0, - "Too much data: Truncating file at %ju bytes", - (uintmax_t)a->filesize); - return (ARCHIVE_WARN); - } -#if ARCHIVE_VERSION_NUMBER < 3999000 - return (ARCHIVE_OK); -#else - return (size); -#endif -} - -static ssize_t -_archive_write_disk_data(struct archive *_a, const void *buff, size_t size) -{ - struct archive_write_disk *a = (struct archive_write_disk *)_a; - - archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, - ARCHIVE_STATE_DATA, "archive_write_data"); - - if (a->todo & TODO_HFS_COMPRESSION) - return (hfs_write_data_block(a, buff, size)); - return (write_data_block(a, buff, size)); -} - -static int -_archive_write_disk_finish_entry(struct archive *_a) -{ - struct archive_write_disk *a = (struct archive_write_disk *)_a; - int ret = ARCHIVE_OK; - - archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, - ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, - "archive_write_finish_entry"); - if (a->archive.state & ARCHIVE_STATE_HEADER) - return (ARCHIVE_OK); - archive_clear_error(&a->archive); - - /* Pad or truncate file to the right size. */ - if (a->fd < 0) { - /* There's no file. */ - } else if (a->filesize < 0) { - /* File size is unknown, so we can't set the size. */ - } else if (a->fd_offset == a->filesize) { - /* Last write ended at exactly the filesize; we're done. */ - /* Hopefully, this is the common case. */ -#if defined(__APPLE__) && defined(UF_COMPRESSED) && defined(HAVE_ZLIB_H) - } else if (a->todo & TODO_HFS_COMPRESSION) { - char null_d[1024]; - ssize_t r; - - if (a->file_remaining_bytes) - memset(null_d, 0, sizeof(null_d)); - while (a->file_remaining_bytes) { - if (a->file_remaining_bytes > sizeof(null_d)) - r = hfs_write_data_block( - a, null_d, sizeof(null_d)); - else - r = hfs_write_data_block( - a, null_d, a->file_remaining_bytes); - if (r < 0) { - close_file_descriptor(a); - return ((int)r); - } - } -#endif - } else { -#if HAVE_FTRUNCATE - if (ftruncate(a->fd, a->filesize) == -1 && - a->filesize == 0) { - archive_set_error(&a->archive, errno, - "File size could not be restored"); - close_file_descriptor(a); - return (ARCHIVE_FAILED); - } -#endif - /* - * Not all platforms implement the XSI option to - * extend files via ftruncate. Stat() the file again - * to see what happened. - */ - a->pst = NULL; - if ((ret = lazy_stat(a)) != ARCHIVE_OK) { - close_file_descriptor(a); - return (ret); - } - /* We can use lseek()/write() to extend the file if - * ftruncate didn't work or isn't available. */ - if (a->st.st_size < a->filesize) { - const char nul = '\0'; - if (lseek(a->fd, a->filesize - 1, SEEK_SET) < 0) { - archive_set_error(&a->archive, errno, - "Seek failed"); - close_file_descriptor(a); - return (ARCHIVE_FATAL); - } - if (write(a->fd, &nul, 1) < 0) { - archive_set_error(&a->archive, errno, - "Write to restore size failed"); - close_file_descriptor(a); - return (ARCHIVE_FATAL); - } - a->pst = NULL; - } - } - - /* Restore metadata. */ - - /* - * This is specific to Mac OS X. - * If the current file is an AppleDouble file, it should be - * linked with the data fork file and remove it. - */ - if (a->todo & TODO_APPLEDOUBLE) { - int r2 = fixup_appledouble(a, a->name); - if (r2 == ARCHIVE_EOF) { - /* The current file has been successfully linked - * with the data fork file and removed. So there - * is nothing to do on the current file. */ - goto finish_metadata; - } - if (r2 < ret) ret = r2; - } - - /* - * Look up the "real" UID only if we're going to need it. - * TODO: the TODO_SGID condition can be dropped here, can't it? - */ - if (a->todo & (TODO_OWNER | TODO_SUID | TODO_SGID)) { - a->uid = archive_write_disk_uid(&a->archive, - archive_entry_uname(a->entry), - archive_entry_uid(a->entry)); - } - /* Look up the "real" GID only if we're going to need it. */ - /* TODO: the TODO_SUID condition can be dropped here, can't it? */ - if (a->todo & (TODO_OWNER | TODO_SGID | TODO_SUID)) { - a->gid = archive_write_disk_gid(&a->archive, - archive_entry_gname(a->entry), - archive_entry_gid(a->entry)); - } - - /* - * Restore ownership before set_mode tries to restore suid/sgid - * bits. If we set the owner, we know what it is and can skip - * a stat() call to examine the ownership of the file on disk. - */ - if (a->todo & TODO_OWNER) { - int r2 = set_ownership(a); - if (r2 < ret) ret = r2; - } - - /* - * HYPOTHESIS: - * If we're not root, we won't be setting any security - * attributes that may be wiped by the set_mode() routine - * below. We also can't set xattr on non-owner-writable files, - * which may be the state after set_mode(). Perform - * set_xattrs() first based on these constraints. - */ - if (a->user_uid != 0 && - (a->todo & TODO_XATTR)) { - int r2 = set_xattrs(a); - if (r2 < ret) ret = r2; - } - - /* - * set_mode must precede ACLs on systems such as Solaris and - * FreeBSD where setting the mode implicitly clears extended ACLs - */ - if (a->todo & TODO_MODE) { - int r2 = set_mode(a, a->mode); - if (r2 < ret) ret = r2; - } - - /* - * Security-related extended attributes (such as - * security.capability on Linux) have to be restored last, - * since they're implicitly removed by other file changes. - * We do this last only when root. - */ - if (a->user_uid == 0 && - (a->todo & TODO_XATTR)) { - int r2 = set_xattrs(a); - if (r2 < ret) ret = r2; - } - - /* - * Some flags prevent file modification; they must be restored after - * file contents are written. - */ - if (a->todo & TODO_FFLAGS) { - int r2 = set_fflags(a); - if (r2 < ret) ret = r2; - } - - /* - * Time must follow most other metadata; - * otherwise atime will get changed. - */ - if (a->todo & TODO_TIMES) { - int r2 = set_times_from_entry(a); - if (r2 < ret) ret = r2; - } - - /* - * Mac extended metadata includes ACLs. - */ - if (a->todo & TODO_MAC_METADATA) { - const void *metadata; - size_t metadata_size; - metadata = archive_entry_mac_metadata(a->entry, &metadata_size); - if (metadata != NULL && metadata_size > 0) { - int r2 = set_mac_metadata(a, archive_entry_pathname( - a->entry), metadata, metadata_size); - if (r2 < ret) ret = r2; - } - } - - /* - * ACLs must be restored after timestamps because there are - * ACLs that prevent attribute changes (including time). - */ - if (a->todo & TODO_ACLS) { - int r2; - r2 = archive_write_disk_set_acls(&a->archive, a->fd, - archive_entry_pathname(a->entry), - archive_entry_acl(a->entry), - archive_entry_mode(a->entry)); - if (r2 < ret) ret = r2; - } - -finish_metadata: - /* If there's an fd, we can close it now. */ - if (a->fd >= 0) { - close(a->fd); - a->fd = -1; - if (a->tmpname) { - if (rename(a->tmpname, a->name) == -1) { - archive_set_error(&a->archive, errno, - "Failed to rename temporary file"); - ret = ARCHIVE_FAILED; - unlink(a->tmpname); - } - a->tmpname = NULL; - } - } - /* If there's an entry, we can release it now. */ - archive_entry_free(a->entry); - a->entry = NULL; - a->archive.state = ARCHIVE_STATE_HEADER; - return (ret); -} - -int -archive_write_disk_set_group_lookup(struct archive *_a, - void *private_data, - la_int64_t (*lookup_gid)(void *private, const char *gname, la_int64_t gid), - void (*cleanup_gid)(void *private)) -{ - struct archive_write_disk *a = (struct archive_write_disk *)_a; - archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_write_disk_set_group_lookup"); - - if (a->cleanup_gid != NULL && a->lookup_gid_data != NULL) - (a->cleanup_gid)(a->lookup_gid_data); - - a->lookup_gid = lookup_gid; - a->cleanup_gid = cleanup_gid; - a->lookup_gid_data = private_data; - return (ARCHIVE_OK); -} - -int -archive_write_disk_set_user_lookup(struct archive *_a, - void *private_data, - int64_t (*lookup_uid)(void *private, const char *uname, int64_t uid), - void (*cleanup_uid)(void *private)) -{ - struct archive_write_disk *a = (struct archive_write_disk *)_a; - archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_write_disk_set_user_lookup"); - - if (a->cleanup_uid != NULL && a->lookup_uid_data != NULL) - (a->cleanup_uid)(a->lookup_uid_data); - - a->lookup_uid = lookup_uid; - a->cleanup_uid = cleanup_uid; - a->lookup_uid_data = private_data; - return (ARCHIVE_OK); -} - -int64_t -archive_write_disk_gid(struct archive *_a, const char *name, la_int64_t id) -{ - struct archive_write_disk *a = (struct archive_write_disk *)_a; - archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_write_disk_gid"); - if (a->lookup_gid) - return (a->lookup_gid)(a->lookup_gid_data, name, id); - return (id); -} - -int64_t -archive_write_disk_uid(struct archive *_a, const char *name, la_int64_t id) -{ - struct archive_write_disk *a = (struct archive_write_disk *)_a; - archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_write_disk_uid"); - if (a->lookup_uid) - return (a->lookup_uid)(a->lookup_uid_data, name, id); - return (id); -} - -/* - * Create a new archive_write_disk object and initialize it with global state. - */ -struct archive * -archive_write_disk_new(void) -{ - struct archive_write_disk *a; - - a = (struct archive_write_disk *)calloc(1, sizeof(*a)); - if (a == NULL) - return (NULL); - a->archive.magic = ARCHIVE_WRITE_DISK_MAGIC; - /* We're ready to write a header immediately. */ - a->archive.state = ARCHIVE_STATE_HEADER; - a->archive.vtable = &archive_write_disk_vtable; - a->start_time = time(NULL); - /* Query and restore the umask. */ - umask(a->user_umask = umask(0)); -#ifdef HAVE_GETEUID - a->user_uid = geteuid(); -#endif /* HAVE_GETEUID */ - if (archive_string_ensure(&a->path_safe, 512) == NULL) { - free(a); - return (NULL); - } - a->path_safe.s[0] = 0; - -#ifdef HAVE_ZLIB_H - a->decmpfs_compression_level = 5; -#endif - return (&a->archive); -} - - -/* - * If pathname is longer than PATH_MAX, chdir to a suitable - * intermediate dir and edit the path down to a shorter suffix. Note - * that this routine never returns an error; if the chdir() attempt - * fails for any reason, we just go ahead with the long pathname. The - * object creation is likely to fail, but any error will get handled - * at that time. - */ -#if defined(HAVE_FCHDIR) && defined(PATH_MAX) -static void -edit_deep_directories(struct archive_write_disk *a) -{ - int ret; - char *tail = a->name; - - /* If path is short, avoid the open() below. */ - if (strlen(tail) < PATH_MAX) - return; - - /* Try to record our starting dir. */ - a->restore_pwd = la_opendirat(AT_FDCWD, "."); - __archive_ensure_cloexec_flag(a->restore_pwd); - if (a->restore_pwd < 0) - return; - - /* As long as the path is too long... */ - while (strlen(tail) >= PATH_MAX) { - /* Locate a dir prefix shorter than PATH_MAX. */ - tail += PATH_MAX - 8; - while (tail > a->name && *tail != '/') - tail--; - /* Exit if we find a too-long path component. */ - if (tail <= a->name) - return; - /* Create the intermediate dir and chdir to it. */ - *tail = '\0'; /* Terminate dir portion */ - ret = create_dir(a, a->name); - if (ret == ARCHIVE_OK && chdir(a->name) != 0) - ret = ARCHIVE_FAILED; - *tail = '/'; /* Restore the / we removed. */ - if (ret != ARCHIVE_OK) - return; - tail++; - /* The chdir() succeeded; we've now shortened the path. */ - a->name = tail; - } - return; -} -#endif - -/* - * The main restore function. - */ -static int -restore_entry(struct archive_write_disk *a) -{ - int ret = ARCHIVE_OK, en; - - if (a->flags & ARCHIVE_EXTRACT_UNLINK && !S_ISDIR(a->mode)) { - /* - * TODO: Fix this. Apparently, there are platforms - * that still allow root to hose the entire filesystem - * by unlinking a dir. The S_ISDIR() test above - * prevents us from using unlink() here if the new - * object is a dir, but that doesn't mean the old - * object isn't a dir. - */ - if (a->flags & ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS) - (void)clear_nochange_fflags(a); - if (unlink(a->name) == 0) { - /* We removed it, reset cached stat. */ - a->pst = NULL; - } else if (errno == ENOENT) { - /* File didn't exist, that's just as good. */ - } else if (rmdir(a->name) == 0) { - /* It was a dir, but now it's gone. */ - a->pst = NULL; - } else { - /* We tried, but couldn't get rid of it. */ - archive_set_error(&a->archive, errno, - "Could not unlink"); - return(ARCHIVE_FAILED); - } - } - - /* Try creating it first; if this fails, we'll try to recover. */ - en = create_filesystem_object(a); - - if ((en == ENOTDIR || en == ENOENT) - && !(a->flags & ARCHIVE_EXTRACT_NO_AUTODIR)) { - /* If the parent dir doesn't exist, try creating it. */ - create_parent_dir(a, a->name); - /* Now try to create the object again. */ - en = create_filesystem_object(a); - } - - if ((en == ENOENT) && (archive_entry_hardlink(a->entry) != NULL)) { - archive_set_error(&a->archive, en, - "Hard-link target '%s' does not exist.", - archive_entry_hardlink(a->entry)); - return (ARCHIVE_FAILED); - } - - if ((en == EISDIR || en == EEXIST) - && (a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) { - /* If we're not overwriting, we're done. */ - if (S_ISDIR(a->mode)) { - /* Don't overwrite any settings on existing directories. */ - a->todo = 0; - } - archive_entry_unset_size(a->entry); - return (ARCHIVE_OK); - } - - /* - * Some platforms return EISDIR if you call - * open(O_WRONLY | O_EXCL | O_CREAT) on a directory, some - * return EEXIST. POSIX is ambiguous, requiring EISDIR - * for open(O_WRONLY) on a dir and EEXIST for open(O_EXCL | O_CREAT) - * on an existing item. - */ - if (en == EISDIR) { - /* A dir is in the way of a non-dir, rmdir it. */ - if (rmdir(a->name) != 0) { - archive_set_error(&a->archive, errno, - "Can't remove already-existing dir"); - return (ARCHIVE_FAILED); - } - a->pst = NULL; - /* Try again. */ - en = create_filesystem_object(a); - } else if (en == EEXIST) { - /* - * We know something is in the way, but we don't know what; - * we need to find out before we go any further. - */ - int r = 0; - /* - * The SECURE_SYMLINKS logic has already removed a - * symlink to a dir if the client wants that. So - * follow the symlink if we're creating a dir. - */ - if (S_ISDIR(a->mode)) - r = la_stat(a->name, &a->st); - /* - * If it's not a dir (or it's a broken symlink), - * then don't follow it. - */ - if (r != 0 || !S_ISDIR(a->mode)) -#ifdef HAVE_LSTAT - r = lstat(a->name, &a->st); -#else - r = la_stat(a->name, &a->st); -#endif - if (r != 0) { - archive_set_error(&a->archive, errno, - "Can't stat existing object"); - return (ARCHIVE_FAILED); - } - - /* - * NO_OVERWRITE_NEWER doesn't apply to directories. - */ - if ((a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER) - && !S_ISDIR(a->st.st_mode)) { - if (!older(&(a->st), a->entry)) { - archive_entry_unset_size(a->entry); - return (ARCHIVE_OK); - } - } - - /* If it's our archive, we're done. */ - if (a->skip_file_set && - a->st.st_dev == (dev_t)a->skip_file_dev && - a->st.st_ino == (ino_t)a->skip_file_ino) { - archive_set_error(&a->archive, 0, - "Refusing to overwrite archive"); - return (ARCHIVE_FAILED); - } - - if (!S_ISDIR(a->st.st_mode)) { - if (a->flags & ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS) - (void)clear_nochange_fflags(a); - - if ((a->flags & ARCHIVE_EXTRACT_SAFE_WRITES) && - S_ISREG(a->st.st_mode)) { - /* Use a temporary file to extract */ - if ((a->fd = la_mktemp(a)) == -1) { - archive_set_error(&a->archive, errno, - "Can't create temporary file"); - return ARCHIVE_FAILED; - } - a->pst = NULL; - en = 0; - } else { - /* A non-dir is in the way, unlink it. */ - if (unlink(a->name) != 0) { - archive_set_error(&a->archive, errno, - "Can't unlink already-existing " - "object"); - return (ARCHIVE_FAILED); - } - a->pst = NULL; - /* Try again. */ - en = create_filesystem_object(a); - } - } else if (!S_ISDIR(a->mode)) { - /* A dir is in the way of a non-dir, rmdir it. */ - if (a->flags & ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS) - (void)clear_nochange_fflags(a); - if (rmdir(a->name) != 0) { - archive_set_error(&a->archive, errno, - "Can't replace existing directory with non-directory"); - return (ARCHIVE_FAILED); - } - /* Try again. */ - en = create_filesystem_object(a); - } else { - /* - * There's a dir in the way of a dir. Don't - * waste time with rmdir()/mkdir(), just fix - * up the permissions on the existing dir. - * Note that we don't change perms on existing - * dirs unless _EXTRACT_PERM is specified. - */ - if ((a->mode != a->st.st_mode) - && (a->todo & TODO_MODE_FORCE)) - a->deferred |= (a->todo & TODO_MODE); - /* Ownership doesn't need deferred fixup. */ - en = 0; /* Forget the EEXIST. */ - } - } - - if (en) { - /* Everything failed; give up here. */ - if ((&a->archive)->error == NULL) - archive_set_error(&a->archive, en, "Can't create '%s'", - a->name); - return (ARCHIVE_FAILED); - } - - a->pst = NULL; /* Cached stat data no longer valid. */ - return (ret); -} - -/* - * Returns 0 if creation succeeds, or else returns errno value from - * the failed system call. Note: This function should only ever perform - * a single system call. - */ -static int -create_filesystem_object(struct archive_write_disk *a) -{ - /* Create the entry. */ - const char *linkname; - mode_t final_mode, mode; - int r; - /* these for check_symlinks_fsobj */ - char *linkname_copy; /* non-const copy of linkname */ - struct stat st; - struct archive_string error_string; - int error_number; - - /* We identify hard/symlinks according to the link names. */ - /* Since link(2) and symlink(2) don't handle modes, we're done here. */ - linkname = archive_entry_hardlink(a->entry); - if (linkname != NULL) { -#if !HAVE_LINK - return (EPERM); -#else - archive_string_init(&error_string); - linkname_copy = strdup(linkname); - if (linkname_copy == NULL) { - return (EPERM); - } - /* - * TODO: consider using the cleaned-up path as the link - * target? - */ - r = cleanup_pathname_fsobj(linkname_copy, &error_number, - &error_string, a->flags); - if (r != ARCHIVE_OK) { - archive_set_error(&a->archive, error_number, "%s", - error_string.s); - free(linkname_copy); - archive_string_free(&error_string); - /* - * EPERM is more appropriate than error_number for our - * callers - */ - return (EPERM); - } - r = check_symlinks_fsobj(linkname_copy, &error_number, - &error_string, a->flags, 1); - if (r != ARCHIVE_OK) { - archive_set_error(&a->archive, error_number, "%s", - error_string.s); - free(linkname_copy); - archive_string_free(&error_string); - /* - * EPERM is more appropriate than error_number for our - * callers - */ - return (EPERM); - } - free(linkname_copy); - archive_string_free(&error_string); - /* - * Unlinking and linking here is really not atomic, - * but doing it right, would require us to construct - * an mktemplink() function, and then use rename(2). - */ - if (a->flags & ARCHIVE_EXTRACT_SAFE_WRITES) - unlink(a->name); -#ifdef HAVE_LINKAT - r = linkat(AT_FDCWD, linkname, AT_FDCWD, a->name, - 0) ? errno : 0; -#else - r = link(linkname, a->name) ? errno : 0; -#endif - /* - * New cpio and pax formats allow hardlink entries - * to carry data, so we may have to open the file - * for hardlink entries. - * - * If the hardlink was successfully created and - * the archive doesn't have carry data for it, - * consider it to be non-authoritative for meta data. - * This is consistent with GNU tar and BSD pax. - * If the hardlink does carry data, let the last - * archive entry decide ownership. - */ - if (r == 0 && a->filesize <= 0) { - a->todo = 0; - a->deferred = 0; - } else if (r == 0 && a->filesize > 0) { -#ifdef HAVE_LSTAT - r = lstat(a->name, &st); -#else - r = la_stat(a->name, &st); -#endif - if (r != 0) - r = errno; - else if ((st.st_mode & AE_IFMT) == AE_IFREG) { - a->fd = open(a->name, O_WRONLY | O_TRUNC | - O_BINARY | O_CLOEXEC | O_NOFOLLOW); - __archive_ensure_cloexec_flag(a->fd); - if (a->fd < 0) - r = errno; - } - } - return (r); -#endif - } - linkname = archive_entry_symlink(a->entry); - if (linkname != NULL) { -#if HAVE_SYMLINK - /* - * Unlinking and linking here is really not atomic, - * but doing it right, would require us to construct - * an mktempsymlink() function, and then use rename(2). - */ - if (a->flags & ARCHIVE_EXTRACT_SAFE_WRITES) - unlink(a->name); - return symlink(linkname, a->name) ? errno : 0; -#else - return (EPERM); -#endif - } - - /* - * The remaining system calls all set permissions, so let's - * try to take advantage of that to avoid an extra chmod() - * call. (Recall that umask is set to zero right now!) - */ - - /* Mode we want for the final restored object (w/o file type bits). */ - final_mode = a->mode & 07777; - /* - * The mode that will actually be restored in this step. Note - * that SUID, SGID, etc, require additional work to ensure - * security, so we never restore them at this point. - */ - mode = final_mode & 0777 & ~a->user_umask; - - /* - * Always create writable such that [f]setxattr() works if we're not - * root. - */ - if (a->user_uid != 0 && - a->todo & (TODO_HFS_COMPRESSION | TODO_XATTR)) { - mode |= 0200; - } - - switch (a->mode & AE_IFMT) { - default: - /* POSIX requires that we fall through here. */ - /* FALLTHROUGH */ - case AE_IFREG: - a->tmpname = NULL; - a->fd = open(a->name, - O_WRONLY | O_CREAT | O_EXCL | O_BINARY | O_CLOEXEC, mode); - __archive_ensure_cloexec_flag(a->fd); - r = (a->fd < 0); - break; - case AE_IFCHR: -#ifdef HAVE_MKNOD - /* Note: we use AE_IFCHR for the case label, and - * S_IFCHR for the mknod() call. This is correct. */ - r = mknod(a->name, mode | S_IFCHR, - archive_entry_rdev(a->entry)); - break; -#else - /* TODO: Find a better way to warn about our inability - * to restore a char device node. */ - return (EINVAL); -#endif /* HAVE_MKNOD */ - case AE_IFBLK: -#ifdef HAVE_MKNOD - r = mknod(a->name, mode | S_IFBLK, - archive_entry_rdev(a->entry)); - break; -#else - /* TODO: Find a better way to warn about our inability - * to restore a block device node. */ - return (EINVAL); -#endif /* HAVE_MKNOD */ - case AE_IFDIR: - mode = (mode | MINIMUM_DIR_MODE) & MAXIMUM_DIR_MODE; - r = mkdir(a->name, mode); - if (r == 0) { - /* Defer setting dir times. */ - a->deferred |= (a->todo & TODO_TIMES); - a->todo &= ~TODO_TIMES; - /* Never use an immediate chmod(). */ - /* We can't avoid the chmod() entirely if EXTRACT_PERM - * because of SysV SGID inheritance. */ - if ((mode != final_mode) - || (a->flags & ARCHIVE_EXTRACT_PERM)) - a->deferred |= (a->todo & TODO_MODE); - a->todo &= ~TODO_MODE; - } - break; - case AE_IFIFO: -#ifdef HAVE_MKFIFO - r = mkfifo(a->name, mode); - break; -#else - /* TODO: Find a better way to warn about our inability - * to restore a fifo. */ - return (EINVAL); -#endif /* HAVE_MKFIFO */ - } - - /* All the system calls above set errno on failure. */ - if (r) - return (errno); - - /* If we managed to set the final mode, we've avoided a chmod(). */ - if (mode == final_mode) - a->todo &= ~TODO_MODE; - return (0); -} - -/* - * Cleanup function for archive_extract. Mostly, this involves processing - * the fixup list, which is used to address a number of problems: - * * Dir permissions might prevent us from restoring a file in that - * dir, so we restore the dir with minimum 0700 permissions first, - * then correct the mode at the end. - * * Similarly, the act of restoring a file touches the directory - * and changes the timestamp on the dir, so we have to touch-up dir - * timestamps at the end as well. - * * Some file flags can interfere with the restore by, for example, - * preventing the creation of hardlinks to those files. - * * Mac OS extended metadata includes ACLs, so must be deferred on dirs. - * - * Note that tar/cpio do not require that archives be in a particular - * order; there is no way to know when the last file has been restored - * within a directory, so there's no way to optimize the memory usage - * here by fixing up the directory any earlier than the - * end-of-archive. - * - * XXX TODO: Directory ACLs should be restored here, for the same - * reason we set directory perms here. XXX - */ -static int -_archive_write_disk_close(struct archive *_a) -{ - struct archive_write_disk *a = (struct archive_write_disk *)_a; - struct fixup_entry *next, *p; - struct stat st; - char *c; - int fd, ret, openflags; - - archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, - ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, - "archive_write_disk_close"); - ret = _archive_write_disk_finish_entry(&a->archive); - - /* Sort dir list so directories are fixed up in depth-first order. */ - p = sort_dir_list(a->fixup_list); - - while (p != NULL) { - fd = -1; - a->pst = NULL; /* Mark stat cache as out-of-date. */ - - /* We must strip trailing slashes from the path to avoid - dereferencing symbolic links to directories */ - c = p->name; - while (*c != '\0') - c++; - while (c != p->name && *(c - 1) == '/') { - c--; - *c = '\0'; - } - - if (p->fixup == 0) - goto skip_fixup_entry; - else { - /* - * We need to verify if the type of the file - * we are going to open matches the file type - * of the fixup entry. - */ - openflags = O_BINARY | O_NOFOLLOW | O_RDONLY - | O_CLOEXEC; -#if defined(O_DIRECTORY) - if (p->filetype == AE_IFDIR) - openflags |= O_DIRECTORY; -#endif - fd = open(p->name, openflags); - -#if defined(O_DIRECTORY) - /* - * If we support O_DIRECTORY and open was - * successful we can skip the file type check - * for directories. For other file types - * we need to verify via fstat() or lstat() - */ - if (fd == -1 || p->filetype != AE_IFDIR) { -#if HAVE_FSTAT - if (fd > 0 && ( - fstat(fd, &st) != 0 || - la_verify_filetype(st.st_mode, - p->filetype) == 0)) { - goto skip_fixup_entry; - } else -#endif - if ( -#ifdef HAVE_LSTAT - lstat(p->name, &st) != 0 || -#else - la_stat(p->name, &st) != 0 || -#endif - la_verify_filetype(st.st_mode, - p->filetype) == 0) { - goto skip_fixup_entry; - } - } -#else -#if HAVE_FSTAT - if (fd > 0 && ( - fstat(fd, &st) != 0 || - la_verify_filetype(st.st_mode, - p->filetype) == 0)) { - goto skip_fixup_entry; - } else -#endif - if ( -#ifdef HAVE_LSTAT - lstat(p->name, &st) != 0 || -#else - la_stat(p->name, &st) != 0 || -#endif - la_verify_filetype(st.st_mode, - p->filetype) == 0) { - goto skip_fixup_entry; - } -#endif - } - if (p->fixup & TODO_TIMES) { - set_times(a, fd, p->mode, p->name, - p->atime, p->atime_nanos, - p->birthtime, p->birthtime_nanos, - p->mtime, p->mtime_nanos, - p->ctime, p->ctime_nanos); - } - if (p->fixup & TODO_MODE_BASE) { -#ifdef HAVE_FCHMOD - if (fd >= 0) - fchmod(fd, p->mode & 07777); - else -#endif -#ifdef HAVE_LCHMOD - lchmod(p->name, p->mode & 07777); -#else - chmod(p->name, p->mode & 07777); -#endif - } - if (p->fixup & TODO_ACLS) - archive_write_disk_set_acls(&a->archive, fd, - p->name, &p->acl, p->mode); - if (p->fixup & TODO_FFLAGS) - set_fflags_platform(a, fd, p->name, - p->mode, p->fflags_set, 0); - if (p->fixup & TODO_MAC_METADATA) - set_mac_metadata(a, p->name, p->mac_metadata, - p->mac_metadata_size); -skip_fixup_entry: - next = p->next; - archive_acl_clear(&p->acl); - free(p->mac_metadata); - free(p->name); - if (fd >= 0) - close(fd); - free(p); - p = next; - } - a->fixup_list = NULL; - return (ret); -} - -static int -_archive_write_disk_free(struct archive *_a) -{ - struct archive_write_disk *a; - int ret; - if (_a == NULL) - return (ARCHIVE_OK); - archive_check_magic(_a, ARCHIVE_WRITE_DISK_MAGIC, - ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_disk_free"); - a = (struct archive_write_disk *)_a; - ret = _archive_write_disk_close(&a->archive); - archive_write_disk_set_group_lookup(&a->archive, NULL, NULL, NULL); - archive_write_disk_set_user_lookup(&a->archive, NULL, NULL, NULL); - archive_entry_free(a->entry); - archive_string_free(&a->_name_data); - archive_string_free(&a->_tmpname_data); - archive_string_free(&a->archive.error_string); - archive_string_free(&a->path_safe); - a->archive.magic = 0; - __archive_clean(&a->archive); - free(a->decmpfs_header_p); - free(a->resource_fork); - free(a->compressed_buffer); - free(a->uncompressed_buffer); -#if defined(__APPLE__) && defined(UF_COMPRESSED) && defined(HAVE_SYS_XATTR_H)\ - && defined(HAVE_ZLIB_H) - if (a->stream_valid) { - switch (deflateEnd(&a->stream)) { - case Z_OK: - break; - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Failed to clean up compressor"); - ret = ARCHIVE_FATAL; - break; - } - } -#endif - free(a); - return (ret); -} - -/* - * Simple O(n log n) merge sort to order the fixup list. In - * particular, we want to restore dir timestamps depth-first. - */ -static struct fixup_entry * -sort_dir_list(struct fixup_entry *p) -{ - struct fixup_entry *a, *b, *t; - - if (p == NULL) - return (NULL); - /* A one-item list is already sorted. */ - if (p->next == NULL) - return (p); - - /* Step 1: split the list. */ - t = p; - a = p->next->next; - while (a != NULL) { - /* Step a twice, t once. */ - a = a->next; - if (a != NULL) - a = a->next; - t = t->next; - } - /* Now, t is at the mid-point, so break the list here. */ - b = t->next; - t->next = NULL; - a = p; - - /* Step 2: Recursively sort the two sub-lists. */ - a = sort_dir_list(a); - b = sort_dir_list(b); - - /* Step 3: Merge the returned lists. */ - /* Pick the first element for the merged list. */ - if (strcmp(a->name, b->name) > 0) { - t = p = a; - a = a->next; - } else { - t = p = b; - b = b->next; - } - - /* Always put the later element on the list first. */ - while (a != NULL && b != NULL) { - if (strcmp(a->name, b->name) > 0) { - t->next = a; - a = a->next; - } else { - t->next = b; - b = b->next; - } - t = t->next; - } - - /* Only one list is non-empty, so just splice it on. */ - if (a != NULL) - t->next = a; - if (b != NULL) - t->next = b; - - return (p); -} - -/* - * Returns a new, initialized fixup entry. - * - * TODO: Reduce the memory requirements for this list by using a tree - * structure rather than a simple list of names. - */ -static struct fixup_entry * -new_fixup(struct archive_write_disk *a, const char *pathname) -{ - struct fixup_entry *fe; - - fe = (struct fixup_entry *)calloc(1, sizeof(struct fixup_entry)); - if (fe == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for a fixup"); - return (NULL); - } - fe->next = a->fixup_list; - a->fixup_list = fe; - fe->fixup = 0; - fe->filetype = 0; - fe->name = strdup(pathname); - return (fe); -} - -/* - * Returns a fixup structure for the current entry. - */ -static struct fixup_entry * -current_fixup(struct archive_write_disk *a, const char *pathname) -{ - if (a->current_fixup == NULL) - a->current_fixup = new_fixup(a, pathname); - return (a->current_fixup); -} - -/* Error helper for new *_fsobj functions */ -static void -fsobj_error(int *a_eno, struct archive_string *a_estr, - int err, const char *errstr, const char *path) -{ - if (a_eno) - *a_eno = err; - if (a_estr) - archive_string_sprintf(a_estr, "%s%s", errstr, path); -} - -/* - * TODO: Someday, integrate this with the deep dir support; they both - * scan the path and both can be optimized by comparing against other - * recent paths. - */ -/* - * Checks the given path to see if any elements along it are symlinks. Returns - * ARCHIVE_OK if there are none, otherwise puts an error in errmsg. - */ -static int -check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr, - int flags, int checking_linkname) -{ -#if !defined(HAVE_LSTAT) && \ - !(defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT)) - /* Platform doesn't have lstat, so we can't look for symlinks. */ - (void)path; /* UNUSED */ - (void)a_eno; /* UNUSED */ - (void)a_estr; /* UNUSED */ - (void)flags; /* UNUSED */ - (void)checking_linkname; /* UNUSED */ - return (ARCHIVE_OK); -#else - int res = ARCHIVE_OK; - char *tail; - char *head; - int last; - char c = '\0'; - int r; - struct stat st; - int chdir_fd; -#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT) - int fd; -#endif - - /* Nothing to do here if name is empty */ - if(path[0] == '\0') - return (ARCHIVE_OK); - - /* - * Guard against symlink tricks. Reject any archive entry whose - * destination would be altered by a symlink. - * - * Walk the filename in chunks separated by '/'. For each segment: - * - if it doesn't exist, continue - * - if it's symlink, abort or remove it - * - if it's a directory and it's not the last chunk, cd into it - * As we go: - * head points to the current (relative) path - * tail points to the temporary \0 terminating the segment we're - * currently examining - * c holds what used to be in *tail - * last is 1 if this is the last tail - */ - chdir_fd = la_opendirat(AT_FDCWD, "."); - __archive_ensure_cloexec_flag(chdir_fd); - if (chdir_fd < 0) { - fsobj_error(a_eno, a_estr, errno, - "Could not open ", path); - return (ARCHIVE_FATAL); - } - head = path; - tail = path; - last = 0; - /* TODO: reintroduce a safe cache here? */ - /* Skip the root directory if the path is absolute. */ - if(tail == path && tail[0] == '/') - ++tail; - /* Keep going until we've checked the entire name. - * head, tail, path all alias the same string, which is - * temporarily zeroed at tail, so be careful restoring the - * stashed (c=tail[0]) for error messages. - * Exiting the loop with break is okay; continue is not. - */ - while (!last) { - /* - * Skip the separator we just consumed, plus any adjacent ones - */ - while (*tail == '/') - ++tail; - /* Skip the next path element. */ - while (*tail != '\0' && *tail != '/') - ++tail; - /* is this the last path component? */ - last = (tail[0] == '\0') || (tail[0] == '/' && tail[1] == '\0'); - /* temporarily truncate the string here */ - c = tail[0]; - tail[0] = '\0'; - /* Check that we haven't hit a symlink. */ -#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT) - r = fstatat(chdir_fd, head, &st, AT_SYMLINK_NOFOLLOW); -#elif defined(HAVE_LSTAT) - r = lstat(head, &st); -#else - r = la_stat(head, &st); -#endif - if (r != 0) { - tail[0] = c; - /* We've hit a dir that doesn't exist; stop now. */ - if (errno == ENOENT) { - break; - } else { - /* - * Treat any other error as fatal - best to be - * paranoid here. - * Note: This effectively disables deep - * directory support when security checks are - * enabled. Otherwise, very long pathnames that - * trigger an error here could evade the - * sandbox. - * TODO: We could do better, but it would - * probably require merging the symlink checks - * with the deep-directory editing. - */ - fsobj_error(a_eno, a_estr, errno, - "Could not stat ", path); - res = ARCHIVE_FAILED; - break; - } - } else if (S_ISDIR(st.st_mode)) { - if (!last) { -#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT) - fd = la_opendirat(chdir_fd, head); - if (fd < 0) - r = -1; - else { - r = 0; - close(chdir_fd); - chdir_fd = fd; - } -#else - r = chdir(head); -#endif - if (r != 0) { - tail[0] = c; - fsobj_error(a_eno, a_estr, errno, - "Could not chdir ", path); - res = (ARCHIVE_FATAL); - break; - } - /* Our view is now from inside this dir: */ - head = tail + 1; - } - } else if (S_ISLNK(st.st_mode)) { - if (last && checking_linkname) { -#ifdef HAVE_LINKAT - /* - * Hardlinks to symlinks are safe to write - * if linkat() is supported as it does not - * follow symlinks. - */ - res = ARCHIVE_OK; -#else - /* - * We return ARCHIVE_FAILED here as we are - * not able to safely write hardlinks - * to symlinks. - */ - tail[0] = c; - fsobj_error(a_eno, a_estr, errno, - "Cannot write hardlink to symlink ", - path); - res = ARCHIVE_FAILED; -#endif - break; - } else - if (last) { - /* - * Last element is symlink; remove it - * so we can overwrite it with the - * item being extracted. - */ -#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT) - r = unlinkat(chdir_fd, head, 0); -#else - r = unlink(head); -#endif - if (r != 0) { - tail[0] = c; - fsobj_error(a_eno, a_estr, errno, - "Could not remove symlink ", - path); - res = ARCHIVE_FAILED; - break; - } - /* - * Even if we did remove it, a warning - * is in order. The warning is silly, - * though, if we're just replacing one - * symlink with another symlink. - */ - tail[0] = c; - /* - * FIXME: not sure how important this is to - * restore - */ - /* - if (!S_ISLNK(path)) { - fsobj_error(a_eno, a_estr, 0, - "Removing symlink ", path); - } - */ - /* Symlink gone. No more problem! */ - res = ARCHIVE_OK; - break; - } else if (flags & ARCHIVE_EXTRACT_UNLINK) { - /* User asked us to remove problems. */ -#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT) - r = unlinkat(chdir_fd, head, 0); -#else - r = unlink(head); -#endif - if (r != 0) { - tail[0] = c; - fsobj_error(a_eno, a_estr, 0, - "Cannot remove intervening " - "symlink ", path); - res = ARCHIVE_FAILED; - break; - } - tail[0] = c; - } else if ((flags & - ARCHIVE_EXTRACT_SECURE_SYMLINKS) == 0) { - /* - * We are not the last element and we want to - * follow symlinks if they are a directory. - * - * This is needed to extract hardlinks over - * symlinks. - */ -#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT) - r = fstatat(chdir_fd, head, &st, 0); -#else - r = la_stat(head, &st); -#endif - if (r != 0) { - tail[0] = c; - if (errno == ENOENT) { - break; - } else { - fsobj_error(a_eno, a_estr, - errno, - "Could not stat ", path); - res = (ARCHIVE_FAILED); - break; - } - } else if (S_ISDIR(st.st_mode)) { -#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT) - fd = la_opendirat(chdir_fd, head); - if (fd < 0) - r = -1; - else { - r = 0; - close(chdir_fd); - chdir_fd = fd; - } -#else - r = chdir(head); -#endif - if (r != 0) { - tail[0] = c; - fsobj_error(a_eno, a_estr, - errno, - "Could not chdir ", path); - res = (ARCHIVE_FATAL); - break; - } - /* - * Our view is now from inside - * this dir: - */ - head = tail + 1; - } else { - tail[0] = c; - fsobj_error(a_eno, a_estr, 0, - "Cannot extract through " - "symlink ", path); - res = ARCHIVE_FAILED; - break; - } - } else { - tail[0] = c; - fsobj_error(a_eno, a_estr, 0, - "Cannot extract through symlink ", path); - res = ARCHIVE_FAILED; - break; - } - } - /* be sure to always maintain this */ - tail[0] = c; - if (tail[0] != '\0') - tail++; /* Advance to the next segment. */ - } - /* Catches loop exits via break */ - tail[0] = c; -#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT) && defined(HAVE_UNLINKAT) - /* If we operate with openat(), fstatat() and unlinkat() there was - * no chdir(), so just close the fd */ - if (chdir_fd >= 0) - close(chdir_fd); -#elif HAVE_FCHDIR - /* If we changed directory above, restore it here. */ - if (chdir_fd >= 0) { - r = fchdir(chdir_fd); - if (r != 0) { - fsobj_error(a_eno, a_estr, errno, - "chdir() failure", ""); - } - close(chdir_fd); - chdir_fd = -1; - if (r != 0) { - res = (ARCHIVE_FATAL); - } - } -#endif - /* TODO: reintroduce a safe cache here? */ - return res; -#endif -} - -/* - * Check a->name for symlinks, returning ARCHIVE_OK if its clean, otherwise - * calls archive_set_error and returns ARCHIVE_{FATAL,FAILED} - */ -static int -check_symlinks(struct archive_write_disk *a) -{ - struct archive_string error_string; - int error_number; - int rc; - archive_string_init(&error_string); - rc = check_symlinks_fsobj(a->name, &error_number, &error_string, - a->flags, 0); - if (rc != ARCHIVE_OK) { - archive_set_error(&a->archive, error_number, "%s", - error_string.s); - } - archive_string_free(&error_string); - a->pst = NULL; /* to be safe */ - return rc; -} - - -#if defined(__CYGWIN__) -/* - * 1. Convert a path separator from '\' to '/' . - * We shouldn't check multibyte character directly because some - * character-set have been using the '\' character for a part of - * its multibyte character code. - * 2. Replace unusable characters in Windows with underscore('_'). - * See also : http://msdn.microsoft.com/en-us/library/aa365247.aspx - */ -static void -cleanup_pathname_win(char *path) -{ - wchar_t wc; - char *p; - size_t alen, l; - int mb, complete, utf8; - - alen = 0; - mb = 0; - complete = 1; - utf8 = (strcmp(nl_langinfo(CODESET), "UTF-8") == 0)? 1: 0; - for (p = path; *p != '\0'; p++) { - ++alen; - if (*p == '\\') { - /* If previous byte is smaller than 128, - * this is not second byte of multibyte characters, - * so we can replace '\' with '/'. */ - if (utf8 || !mb) - *p = '/'; - else - complete = 0;/* uncompleted. */ - } else if (*(unsigned char *)p > 127) - mb = 1; - else - mb = 0; - /* Rewrite the path name if its next character is unusable. */ - if (*p == ':' || *p == '*' || *p == '?' || *p == '"' || - *p == '<' || *p == '>' || *p == '|') - *p = '_'; - } - if (complete) - return; - - /* - * Convert path separator in wide-character. - */ - p = path; - while (*p != '\0' && alen) { - l = mbtowc(&wc, p, alen); - if (l == (size_t)-1) { - while (*p != '\0') { - if (*p == '\\') - *p = '/'; - ++p; - } - break; - } - if (l == 1 && wc == L'\\') - *p = '/'; - p += l; - alen -= l; - } -} -#endif - -/* - * Canonicalize the pathname. In particular, this strips duplicate - * '/' characters, '.' elements, and trailing '/'. It also raises an - * error for an empty path, a trailing '..', (if _SECURE_NODOTDOT is - * set) any '..' in the path or (if ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS - * is set) if the path is absolute. - */ -static int -cleanup_pathname_fsobj(char *path, int *a_eno, struct archive_string *a_estr, - int flags) -{ - char *dest, *src; - char separator = '\0'; - - dest = src = path; - if (*src == '\0') { - fsobj_error(a_eno, a_estr, ARCHIVE_ERRNO_MISC, - "Invalid empty ", "pathname"); - return (ARCHIVE_FAILED); - } - -#if defined(__CYGWIN__) - cleanup_pathname_win(path); -#endif - /* Skip leading '/'. */ - if (*src == '/') { - if (flags & ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS) { - fsobj_error(a_eno, a_estr, ARCHIVE_ERRNO_MISC, - "Path is ", "absolute"); - return (ARCHIVE_FAILED); - } - - separator = *src++; - } - - /* Scan the pathname one element at a time. */ - for (;;) { - /* src points to first char after '/' */ - if (src[0] == '\0') { - break; - } else if (src[0] == '/') { - /* Found '//', ignore second one. */ - src++; - continue; - } else if (src[0] == '.') { - if (src[1] == '\0') { - /* Ignore trailing '.' */ - break; - } else if (src[1] == '/') { - /* Skip './'. */ - src += 2; - continue; - } else if (src[1] == '.') { - if (src[2] == '/' || src[2] == '\0') { - /* Conditionally warn about '..' */ - if (flags - & ARCHIVE_EXTRACT_SECURE_NODOTDOT) { - fsobj_error(a_eno, a_estr, - ARCHIVE_ERRNO_MISC, - "Path contains ", "'..'"); - return (ARCHIVE_FAILED); - } - } - /* - * Note: Under no circumstances do we - * remove '..' elements. In - * particular, restoring - * '/foo/../bar/' should create the - * 'foo' dir as a side-effect. - */ - } - } - - /* Copy current element, including leading '/'. */ - if (separator) - *dest++ = '/'; - while (*src != '\0' && *src != '/') { - *dest++ = *src++; - } - - if (*src == '\0') - break; - - /* Skip '/' separator. */ - separator = *src++; - } - /* - * We've just copied zero or more path elements, not including the - * final '/'. - */ - if (dest == path) { - /* - * Nothing got copied. The path must have been something - * like '.' or '/' or './' or '/././././/./'. - */ - if (separator) - *dest++ = '/'; - else - *dest++ = '.'; - } - /* Terminate the result. */ - *dest = '\0'; - return (ARCHIVE_OK); -} - -static int -cleanup_pathname(struct archive_write_disk *a) -{ - struct archive_string error_string; - int error_number; - int rc; - archive_string_init(&error_string); - rc = cleanup_pathname_fsobj(a->name, &error_number, &error_string, - a->flags); - if (rc != ARCHIVE_OK) { - archive_set_error(&a->archive, error_number, "%s", - error_string.s); - } - archive_string_free(&error_string); - return rc; -} - -/* - * Create the parent directory of the specified path, assuming path - * is already in mutable storage. - */ -static int -create_parent_dir(struct archive_write_disk *a, char *path) -{ - char *slash; - int r; - - /* Remove tail element to obtain parent name. */ - slash = strrchr(path, '/'); - if (slash == NULL) - return (ARCHIVE_OK); - *slash = '\0'; - r = create_dir(a, path); - *slash = '/'; - return (r); -} - -/* - * Create the specified dir, recursing to create parents as necessary. - * - * Returns ARCHIVE_OK if the path exists when we're done here. - * Otherwise, returns ARCHIVE_FAILED. - * Assumes path is in mutable storage; path is unchanged on exit. - */ -static int -create_dir(struct archive_write_disk *a, char *path) -{ - struct stat st; - struct fixup_entry *le; - char *slash, *base; - mode_t mode_final, mode; - int r; - - /* Check for special names and just skip them. */ - slash = strrchr(path, '/'); - if (slash == NULL) - base = path; - else - base = slash + 1; - - if (base[0] == '\0' || - (base[0] == '.' && base[1] == '\0') || - (base[0] == '.' && base[1] == '.' && base[2] == '\0')) { - /* Don't bother trying to create null path, '.', or '..'. */ - if (slash != NULL) { - *slash = '\0'; - r = create_dir(a, path); - *slash = '/'; - return (r); - } - return (ARCHIVE_OK); - } - - /* - * Yes, this should be stat() and not lstat(). Using lstat() - * here loses the ability to extract through symlinks. Also note - * that this should not use the a->st cache. - */ - if (la_stat(path, &st) == 0) { - if (S_ISDIR(st.st_mode)) - return (ARCHIVE_OK); - if ((a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) { - archive_set_error(&a->archive, EEXIST, - "Can't create directory '%s'", path); - return (ARCHIVE_FAILED); - } - if (unlink(path) != 0) { - archive_set_error(&a->archive, errno, - "Can't create directory '%s': " - "Conflicting file cannot be removed", - path); - return (ARCHIVE_FAILED); - } - } else if (errno != ENOENT && errno != ENOTDIR) { - /* Stat failed? */ - archive_set_error(&a->archive, errno, - "Can't test directory '%s'", path); - return (ARCHIVE_FAILED); - } else if (slash != NULL) { - *slash = '\0'; - r = create_dir(a, path); - *slash = '/'; - if (r != ARCHIVE_OK) - return (r); - } - - /* - * Mode we want for the final restored directory. Per POSIX, - * implicitly-created dirs must be created obeying the umask. - * There's no mention whether this is different for privileged - * restores (which the rest of this code handles by pretending - * umask=0). I've chosen here to always obey the user's umask for - * implicit dirs, even if _EXTRACT_PERM was specified. - */ - mode_final = DEFAULT_DIR_MODE & ~a->user_umask; - /* Mode we want on disk during the restore process. */ - mode = mode_final; - mode |= MINIMUM_DIR_MODE; - mode &= MAXIMUM_DIR_MODE; - if (mkdir(path, mode) == 0) { - if (mode != mode_final) { - le = new_fixup(a, path); - if (le == NULL) - return (ARCHIVE_FATAL); - le->fixup |=TODO_MODE_BASE; - le->mode = mode_final; - } - return (ARCHIVE_OK); - } - - /* - * Without the following check, a/b/../b/c/d fails at the - * second visit to 'b', so 'd' can't be created. Note that we - * don't add it to the fixup list here, as it's already been - * added. - */ - if (la_stat(path, &st) == 0 && S_ISDIR(st.st_mode)) - return (ARCHIVE_OK); - - archive_set_error(&a->archive, errno, "Failed to create dir '%s'", - path); - return (ARCHIVE_FAILED); -} - -/* - * Note: Although we can skip setting the user id if the desired user - * id matches the current user, we cannot skip setting the group, as - * many systems set the gid based on the containing directory. So - * we have to perform a chown syscall if we want to set the SGID - * bit. (The alternative is to stat() and then possibly chown(); it's - * more efficient to skip the stat() and just always chown().) Note - * that a successful chown() here clears the TODO_SGID_CHECK bit, which - * allows set_mode to skip the stat() check for the GID. - */ -static int -set_ownership(struct archive_write_disk *a) -{ -#if !defined(__CYGWIN__) && !defined(__linux__) -/* - * On Linux, a process may have the CAP_CHOWN capability. - * On Windows there is no 'root' user with uid 0. - * Elsewhere we can skip calling chown if we are not root and the desired - * user id does not match the current user. - */ - if (a->user_uid != 0 && a->user_uid != a->uid) { - archive_set_error(&a->archive, errno, - "Can't set UID=%jd", (intmax_t)a->uid); - return (ARCHIVE_WARN); - } -#endif - -#ifdef HAVE_FCHOWN - /* If we have an fd, we can avoid a race. */ - if (a->fd >= 0 && fchown(a->fd, a->uid, a->gid) == 0) { - /* We've set owner and know uid/gid are correct. */ - a->todo &= ~(TODO_OWNER | TODO_SGID_CHECK | TODO_SUID_CHECK); - return (ARCHIVE_OK); - } -#endif - - /* We prefer lchown() but will use chown() if that's all we have. */ - /* Of course, if we have neither, this will always fail. */ -#ifdef HAVE_LCHOWN - if (lchown(a->name, a->uid, a->gid) == 0) { - /* We've set owner and know uid/gid are correct. */ - a->todo &= ~(TODO_OWNER | TODO_SGID_CHECK | TODO_SUID_CHECK); - return (ARCHIVE_OK); - } -#elif HAVE_CHOWN - if (!S_ISLNK(a->mode) && chown(a->name, a->uid, a->gid) == 0) { - /* We've set owner and know uid/gid are correct. */ - a->todo &= ~(TODO_OWNER | TODO_SGID_CHECK | TODO_SUID_CHECK); - return (ARCHIVE_OK); - } -#endif - - archive_set_error(&a->archive, errno, - "Can't set user=%jd/group=%jd for %s", - (intmax_t)a->uid, (intmax_t)a->gid, a->name); - return (ARCHIVE_WARN); -} - -/* - * Note: Returns 0 on success, non-zero on failure. - */ -static int -set_time(int fd, int mode, const char *name, - time_t atime, long atime_nsec, - time_t mtime, long mtime_nsec) -{ - /* Select the best implementation for this platform. */ -#if defined(HAVE_UTIMENSAT) && defined(HAVE_FUTIMENS) - /* - * utimensat() and futimens() are defined in - * POSIX.1-2008. They support ns resolution and setting times - * on fds and symlinks. - */ - struct timespec ts[2]; - (void)mode; /* UNUSED */ - ts[0].tv_sec = atime; - ts[0].tv_nsec = atime_nsec; - ts[1].tv_sec = mtime; - ts[1].tv_nsec = mtime_nsec; - if (fd >= 0) - return futimens(fd, ts); - return utimensat(AT_FDCWD, name, ts, AT_SYMLINK_NOFOLLOW); - -#elif HAVE_UTIMES - /* - * The utimes()-family functions support µs-resolution and - * setting times fds and symlinks. utimes() is documented as - * LEGACY by POSIX, futimes() and lutimes() are not described - * in POSIX. - */ - struct timeval times[2]; - - times[0].tv_sec = atime; - times[0].tv_usec = atime_nsec / 1000; - times[1].tv_sec = mtime; - times[1].tv_usec = mtime_nsec / 1000; - -#ifdef HAVE_FUTIMES - if (fd >= 0) - return (futimes(fd, times)); -#else - (void)fd; /* UNUSED */ -#endif -#ifdef HAVE_LUTIMES - (void)mode; /* UNUSED */ - return (lutimes(name, times)); -#else - if (S_ISLNK(mode)) - return (0); - return (utimes(name, times)); -#endif - -#elif defined(HAVE_UTIME) - /* - * utime() is POSIX-standard but only supports 1s resolution and - * does not support fds or symlinks. - */ - struct utimbuf times; - (void)fd; /* UNUSED */ - (void)name; /* UNUSED */ - (void)atime_nsec; /* UNUSED */ - (void)mtime_nsec; /* UNUSED */ - times.actime = atime; - times.modtime = mtime; - if (S_ISLNK(mode)) - return (ARCHIVE_OK); - return (utime(name, ×)); - -#else - /* - * We don't know how to set the time on this platform. - */ - (void)fd; /* UNUSED */ - (void)mode; /* UNUSED */ - (void)name; /* UNUSED */ - (void)atime; /* UNUSED */ - (void)atime_nsec; /* UNUSED */ - (void)mtime; /* UNUSED */ - (void)mtime_nsec; /* UNUSED */ - return (ARCHIVE_WARN); -#endif -} - -#ifdef F_SETTIMES -static int -set_time_tru64(int fd, int mode, const char *name, - time_t atime, long atime_nsec, - time_t mtime, long mtime_nsec, - time_t ctime, long ctime_nsec) -{ - struct attr_timbuf tstamp; - tstamp.atime.tv_sec = atime; - tstamp.mtime.tv_sec = mtime; - tstamp.ctime.tv_sec = ctime; -#if defined (__hpux) && defined (__ia64) - tstamp.atime.tv_nsec = atime_nsec; - tstamp.mtime.tv_nsec = mtime_nsec; - tstamp.ctime.tv_nsec = ctime_nsec; -#else - tstamp.atime.tv_usec = atime_nsec / 1000; - tstamp.mtime.tv_usec = mtime_nsec / 1000; - tstamp.ctime.tv_usec = ctime_nsec / 1000; -#endif - return (fcntl(fd,F_SETTIMES,&tstamp)); -} -#endif /* F_SETTIMES */ - -static int -set_times(struct archive_write_disk *a, - int fd, int mode, const char *name, - time_t atime, long atime_nanos, - time_t birthtime, long birthtime_nanos, - time_t mtime, long mtime_nanos, - time_t cctime, long ctime_nanos) -{ - /* Note: set_time doesn't use libarchive return conventions! - * It uses syscall conventions. So 0 here instead of ARCHIVE_OK. */ - int r1 = 0, r2 = 0; - -#ifdef F_SETTIMES - /* - * on Tru64 try own fcntl first which can restore even the - * ctime, fall back to default code path below if it fails - * or if we are not running as root - */ - if (a->user_uid == 0 && - set_time_tru64(fd, mode, name, - atime, atime_nanos, mtime, - mtime_nanos, cctime, ctime_nanos) == 0) { - return (ARCHIVE_OK); - } -#else /* Tru64 */ - (void)cctime; /* UNUSED */ - (void)ctime_nanos; /* UNUSED */ -#endif /* Tru64 */ - -#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME - /* - * If you have struct stat.st_birthtime, we assume BSD - * birthtime semantics, in which {f,l,}utimes() updates - * birthtime to earliest mtime. So we set the time twice, - * first using the birthtime, then using the mtime. If - * birthtime == mtime, this isn't necessary, so we skip it. - * If birthtime > mtime, then this won't work, so we skip it. - */ - if (birthtime < mtime - || (birthtime == mtime && birthtime_nanos < mtime_nanos)) - r1 = set_time(fd, mode, name, - atime, atime_nanos, - birthtime, birthtime_nanos); -#else - (void)birthtime; /* UNUSED */ - (void)birthtime_nanos; /* UNUSED */ -#endif - r2 = set_time(fd, mode, name, - atime, atime_nanos, - mtime, mtime_nanos); - if (r1 != 0 || r2 != 0) { - archive_set_error(&a->archive, errno, - "Can't restore time"); - return (ARCHIVE_WARN); - } - return (ARCHIVE_OK); -} - -static int -set_times_from_entry(struct archive_write_disk *a) -{ - time_t atime, birthtime, mtime, cctime; - long atime_nsec, birthtime_nsec, mtime_nsec, ctime_nsec; - - /* Suitable defaults. */ - atime = birthtime = mtime = cctime = a->start_time; - atime_nsec = birthtime_nsec = mtime_nsec = ctime_nsec = 0; - - /* If no time was provided, we're done. */ - if (!archive_entry_atime_is_set(a->entry) -#if HAVE_STRUCT_STAT_ST_BIRTHTIME - && !archive_entry_birthtime_is_set(a->entry) -#endif - && !archive_entry_mtime_is_set(a->entry)) - return (ARCHIVE_OK); - - if (archive_entry_atime_is_set(a->entry)) { - atime = archive_entry_atime(a->entry); - atime_nsec = archive_entry_atime_nsec(a->entry); - } - if (archive_entry_birthtime_is_set(a->entry)) { - birthtime = archive_entry_birthtime(a->entry); - birthtime_nsec = archive_entry_birthtime_nsec(a->entry); - } - if (archive_entry_mtime_is_set(a->entry)) { - mtime = archive_entry_mtime(a->entry); - mtime_nsec = archive_entry_mtime_nsec(a->entry); - } - if (archive_entry_ctime_is_set(a->entry)) { - cctime = archive_entry_ctime(a->entry); - ctime_nsec = archive_entry_ctime_nsec(a->entry); - } - - return set_times(a, a->fd, a->mode, a->name, - atime, atime_nsec, - birthtime, birthtime_nsec, - mtime, mtime_nsec, - cctime, ctime_nsec); -} - -static int -set_mode(struct archive_write_disk *a, int mode) -{ - int r = ARCHIVE_OK; - int r2; - mode &= 07777; /* Strip off file type bits. */ - - if (a->todo & TODO_SGID_CHECK) { - /* - * If we don't know the GID is right, we must stat() - * to verify it. We can't just check the GID of this - * process, since systems sometimes set GID from - * the enclosing dir or based on ACLs. - */ - if ((r = lazy_stat(a)) != ARCHIVE_OK) - return (r); - if (a->pst->st_gid != a->gid) { - mode &= ~ S_ISGID; - if (a->flags & ARCHIVE_EXTRACT_OWNER) { - /* - * This is only an error if you - * requested owner restore. If you - * didn't, we'll try to restore - * sgid/suid, but won't consider it a - * problem if we can't. - */ - archive_set_error(&a->archive, -1, - "Can't restore SGID bit"); - r = ARCHIVE_WARN; - } - } - /* While we're here, double-check the UID. */ - if (a->pst->st_uid != a->uid - && (a->todo & TODO_SUID)) { - mode &= ~ S_ISUID; - if (a->flags & ARCHIVE_EXTRACT_OWNER) { - archive_set_error(&a->archive, -1, - "Can't restore SUID bit"); - r = ARCHIVE_WARN; - } - } - a->todo &= ~TODO_SGID_CHECK; - a->todo &= ~TODO_SUID_CHECK; - } else if (a->todo & TODO_SUID_CHECK) { - /* - * If we don't know the UID is right, we can just check - * the user, since all systems set the file UID from - * the process UID. - */ - if (a->user_uid != a->uid) { - mode &= ~ S_ISUID; - if (a->flags & ARCHIVE_EXTRACT_OWNER) { - archive_set_error(&a->archive, -1, - "Can't make file SUID"); - r = ARCHIVE_WARN; - } - } - a->todo &= ~TODO_SUID_CHECK; - } - - if (S_ISLNK(a->mode)) { -#ifdef HAVE_LCHMOD - /* - * If this is a symlink, use lchmod(). If the - * platform doesn't support lchmod(), just skip it. A - * platform that doesn't provide a way to set - * permissions on symlinks probably ignores - * permissions on symlinks, so a failure here has no - * impact. - */ - if (lchmod(a->name, mode) != 0) { - switch (errno) { - case ENOTSUP: - case ENOSYS: -#if ENOTSUP != EOPNOTSUPP - case EOPNOTSUPP: -#endif - /* - * if lchmod is defined but the platform - * doesn't support it, silently ignore - * error - */ - break; - default: - archive_set_error(&a->archive, errno, - "Can't set permissions to 0%o", (int)mode); - r = ARCHIVE_WARN; - } - } -#endif - } else if (!S_ISDIR(a->mode)) { - /* - * If it's not a symlink and not a dir, then use - * fchmod() or chmod(), depending on whether we have - * an fd. Dirs get their perms set during the - * post-extract fixup, which is handled elsewhere. - */ -#ifdef HAVE_FCHMOD - if (a->fd >= 0) - r2 = fchmod(a->fd, mode); - else -#endif - /* If this platform lacks fchmod(), then - * we'll just use chmod(). */ - r2 = chmod(a->name, mode); - - if (r2 != 0) { - archive_set_error(&a->archive, errno, - "Can't set permissions to 0%o", (int)mode); - r = ARCHIVE_WARN; - } - } - return (r); -} - -static int -set_fflags(struct archive_write_disk *a) -{ - struct fixup_entry *le; - unsigned long set, clear; - int r; - mode_t mode = archive_entry_mode(a->entry); - /* - * Make 'critical_flags' hold all file flags that can't be - * immediately restored. For example, on BSD systems, - * SF_IMMUTABLE prevents hardlinks from being created, so - * should not be set until after any hardlinks are created. To - * preserve some semblance of portability, this uses #ifdef - * extensively. Ugly, but it works. - * - * Yes, Virginia, this does create a security race. It's mitigated - * somewhat by the practice of creating dirs 0700 until the extract - * is done, but it would be nice if we could do more than that. - * People restoring critical file systems should be wary of - * other programs that might try to muck with files as they're - * being restored. - */ - const int critical_flags = 0 -#ifdef SF_IMMUTABLE - | SF_IMMUTABLE -#endif -#ifdef UF_IMMUTABLE - | UF_IMMUTABLE -#endif -#ifdef SF_APPEND - | SF_APPEND -#endif -#ifdef UF_APPEND - | UF_APPEND -#endif -#if defined(FS_APPEND_FL) - | FS_APPEND_FL -#elif defined(EXT2_APPEND_FL) - | EXT2_APPEND_FL -#endif -#if defined(FS_IMMUTABLE_FL) - | FS_IMMUTABLE_FL -#elif defined(EXT2_IMMUTABLE_FL) - | EXT2_IMMUTABLE_FL -#endif -#ifdef FS_JOURNAL_DATA_FL - | FS_JOURNAL_DATA_FL -#endif - ; - - if (a->todo & TODO_FFLAGS) { - archive_entry_fflags(a->entry, &set, &clear); - - /* - * The first test encourages the compiler to eliminate - * all of this if it's not necessary. - */ - if ((critical_flags != 0) && (set & critical_flags)) { - le = current_fixup(a, a->name); - if (le == NULL) - return (ARCHIVE_FATAL); - le->filetype = archive_entry_filetype(a->entry); - le->fixup |= TODO_FFLAGS; - le->fflags_set = set; - /* Store the mode if it's not already there. */ - if ((le->fixup & TODO_MODE) == 0) - le->mode = mode; - } else { - r = set_fflags_platform(a, a->fd, - a->name, mode, set, clear); - if (r != ARCHIVE_OK) - return (r); - } - } - return (ARCHIVE_OK); -} - -static int -clear_nochange_fflags(struct archive_write_disk *a) -{ - mode_t mode = archive_entry_mode(a->entry); - const int nochange_flags = 0 -#ifdef SF_IMMUTABLE - | SF_IMMUTABLE -#endif -#ifdef UF_IMMUTABLE - | UF_IMMUTABLE -#endif -#ifdef SF_APPEND - | SF_APPEND -#endif -#ifdef UF_APPEND - | UF_APPEND -#endif -#ifdef EXT2_APPEND_FL - | EXT2_APPEND_FL -#endif -#ifdef EXT2_IMMUTABLE_FL - | EXT2_IMMUTABLE_FL -#endif - ; - - return (set_fflags_platform(a, a->fd, a->name, mode, 0, - nochange_flags)); -} - - -#if ( defined(HAVE_LCHFLAGS) || defined(HAVE_CHFLAGS) || defined(HAVE_FCHFLAGS) ) && defined(HAVE_STRUCT_STAT_ST_FLAGS) -/* - * BSD reads flags using stat() and sets them with one of {f,l,}chflags() - */ -static int -set_fflags_platform(struct archive_write_disk *a, int fd, const char *name, - mode_t mode, unsigned long set, unsigned long clear) -{ - int r; - const int sf_mask = 0 -#ifdef SF_APPEND - | SF_APPEND -#endif -#ifdef SF_ARCHIVED - | SF_ARCHIVED -#endif -#ifdef SF_IMMUTABLE - | SF_IMMUTABLE -#endif -#ifdef SF_NOUNLINK - | SF_NOUNLINK -#endif - ; - (void)mode; /* UNUSED */ - - if (set == 0 && clear == 0) - return (ARCHIVE_OK); - - /* - * XXX Is the stat here really necessary? Or can I just use - * the 'set' flags directly? In particular, I'm not sure - * about the correct approach if we're overwriting an existing - * file that already has flags on it. XXX - */ - if ((r = lazy_stat(a)) != ARCHIVE_OK) - return (r); - - a->st.st_flags &= ~clear; - a->st.st_flags |= set; - - /* Only super-user may change SF_* flags */ - - if (a->user_uid != 0) - a->st.st_flags &= ~sf_mask; - -#ifdef HAVE_FCHFLAGS - /* If platform has fchflags() and we were given an fd, use it. */ - if (fd >= 0 && fchflags(fd, a->st.st_flags) == 0) - return (ARCHIVE_OK); -#endif - /* - * If we can't use the fd to set the flags, we'll use the - * pathname to set flags. We prefer lchflags() but will use - * chflags() if we must. - */ -#ifdef HAVE_LCHFLAGS - if (lchflags(name, a->st.st_flags) == 0) - return (ARCHIVE_OK); -#elif defined(HAVE_CHFLAGS) - if (S_ISLNK(a->st.st_mode)) { - archive_set_error(&a->archive, errno, - "Can't set file flags on symlink."); - return (ARCHIVE_WARN); - } - if (chflags(name, a->st.st_flags) == 0) - return (ARCHIVE_OK); -#endif - archive_set_error(&a->archive, errno, - "Failed to set file flags"); - return (ARCHIVE_WARN); -} - -#elif (defined(FS_IOC_GETFLAGS) && defined(FS_IOC_SETFLAGS) && \ - defined(HAVE_WORKING_FS_IOC_GETFLAGS)) || \ - (defined(EXT2_IOC_GETFLAGS) && defined(EXT2_IOC_SETFLAGS) && \ - defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)) -/* - * Linux uses ioctl() to read and write file flags. - */ -static int -set_fflags_platform(struct archive_write_disk *a, int fd, const char *name, - mode_t mode, unsigned long set, unsigned long clear) -{ - int ret; - int myfd = fd; - int newflags, oldflags; - /* - * Linux has no define for the flags that are only settable by - * the root user. This code may seem a little complex, but - * there seem to be some Linux systems that lack these - * defines. (?) The code below degrades reasonably gracefully - * if sf_mask is incomplete. - */ - const int sf_mask = 0 -#if defined(FS_IMMUTABLE_FL) - | FS_IMMUTABLE_FL -#elif defined(EXT2_IMMUTABLE_FL) - | EXT2_IMMUTABLE_FL -#endif -#if defined(FS_APPEND_FL) - | FS_APPEND_FL -#elif defined(EXT2_APPEND_FL) - | EXT2_APPEND_FL -#endif -#if defined(FS_JOURNAL_DATA_FL) - | FS_JOURNAL_DATA_FL -#endif - ; - - if (set == 0 && clear == 0) - return (ARCHIVE_OK); - /* Only regular files and dirs can have flags. */ - if (!S_ISREG(mode) && !S_ISDIR(mode)) - return (ARCHIVE_OK); - - /* If we weren't given an fd, open it ourselves. */ - if (myfd < 0) { - myfd = open(name, O_RDONLY | O_NONBLOCK | O_BINARY | - O_CLOEXEC | O_NOFOLLOW); - __archive_ensure_cloexec_flag(myfd); - } - if (myfd < 0) - return (ARCHIVE_OK); - - /* - * XXX As above, this would be way simpler if we didn't have - * to read the current flags from disk. XXX - */ - ret = ARCHIVE_OK; - - /* Read the current file flags. */ - if (ioctl(myfd, -#ifdef FS_IOC_GETFLAGS - FS_IOC_GETFLAGS, -#else - EXT2_IOC_GETFLAGS, -#endif - &oldflags) < 0) - goto fail; - - /* Try setting the flags as given. */ - newflags = (oldflags & ~clear) | set; - if (ioctl(myfd, -#ifdef FS_IOC_SETFLAGS - FS_IOC_SETFLAGS, -#else - EXT2_IOC_SETFLAGS, -#endif - &newflags) >= 0) - goto cleanup; - if (errno != EPERM) - goto fail; - - /* If we couldn't set all the flags, try again with a subset. */ - newflags &= ~sf_mask; - oldflags &= sf_mask; - newflags |= oldflags; - if (ioctl(myfd, -#ifdef FS_IOC_SETFLAGS - FS_IOC_SETFLAGS, -#else - EXT2_IOC_SETFLAGS, -#endif - &newflags) >= 0) - goto cleanup; - - /* We couldn't set the flags, so report the failure. */ -fail: - archive_set_error(&a->archive, errno, - "Failed to set file flags"); - ret = ARCHIVE_WARN; -cleanup: - if (fd < 0) - close(myfd); - return (ret); -} - -#else - -/* - * Of course, some systems have neither BSD chflags() nor Linux' flags - * support through ioctl(). - */ -static int -set_fflags_platform(struct archive_write_disk *a, int fd, const char *name, - mode_t mode, unsigned long set, unsigned long clear) -{ - (void)a; /* UNUSED */ - (void)fd; /* UNUSED */ - (void)name; /* UNUSED */ - (void)mode; /* UNUSED */ - (void)set; /* UNUSED */ - (void)clear; /* UNUSED */ - return (ARCHIVE_OK); -} - -#endif /* __linux */ - -#ifndef HAVE_COPYFILE_H -/* Default is to simply drop Mac extended metadata. */ -static int -set_mac_metadata(struct archive_write_disk *a, const char *pathname, - const void *metadata, size_t metadata_size) -{ - (void)a; /* UNUSED */ - (void)pathname; /* UNUSED */ - (void)metadata; /* UNUSED */ - (void)metadata_size; /* UNUSED */ - return (ARCHIVE_OK); -} - -static int -fixup_appledouble(struct archive_write_disk *a, const char *pathname) -{ - (void)a; /* UNUSED */ - (void)pathname; /* UNUSED */ - return (ARCHIVE_OK); -} -#else - -/* - * On Mac OS, we use copyfile() to unpack the metadata and - * apply it to the target file. - */ - -#if defined(HAVE_SYS_XATTR_H) -static int -copy_xattrs(struct archive_write_disk *a, int tmpfd, int dffd) -{ - ssize_t xattr_size; - char *xattr_names = NULL, *xattr_val = NULL; - int ret = ARCHIVE_OK, xattr_i; - - xattr_size = flistxattr(tmpfd, NULL, 0, 0); - if (xattr_size == -1) { - archive_set_error(&a->archive, errno, - "Failed to read metadata(xattr)"); - ret = ARCHIVE_WARN; - goto exit_xattr; - } - xattr_names = malloc(xattr_size); - if (xattr_names == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for metadata(xattr)"); - ret = ARCHIVE_FATAL; - goto exit_xattr; - } - xattr_size = flistxattr(tmpfd, xattr_names, xattr_size, 0); - if (xattr_size == -1) { - archive_set_error(&a->archive, errno, - "Failed to read metadata(xattr)"); - ret = ARCHIVE_WARN; - goto exit_xattr; - } - for (xattr_i = 0; xattr_i < xattr_size; - xattr_i += strlen(xattr_names + xattr_i) + 1) { - char *xattr_val_saved; - ssize_t s; - int f; - - s = fgetxattr(tmpfd, xattr_names + xattr_i, NULL, 0, 0, 0); - if (s == -1) { - archive_set_error(&a->archive, errno, - "Failed to get metadata(xattr)"); - ret = ARCHIVE_WARN; - goto exit_xattr; - } - xattr_val_saved = xattr_val; - xattr_val = realloc(xattr_val, s); - if (xattr_val == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Failed to get metadata(xattr)"); - ret = ARCHIVE_WARN; - free(xattr_val_saved); - goto exit_xattr; - } - s = fgetxattr(tmpfd, xattr_names + xattr_i, xattr_val, s, 0, 0); - if (s == -1) { - archive_set_error(&a->archive, errno, - "Failed to get metadata(xattr)"); - ret = ARCHIVE_WARN; - goto exit_xattr; - } - f = fsetxattr(dffd, xattr_names + xattr_i, xattr_val, s, 0, 0); - if (f == -1) { - archive_set_error(&a->archive, errno, - "Failed to get metadata(xattr)"); - ret = ARCHIVE_WARN; - goto exit_xattr; - } - } -exit_xattr: - free(xattr_names); - free(xattr_val); - return (ret); -} -#endif - -static int -copy_acls(struct archive_write_disk *a, int tmpfd, int dffd) -{ -#ifndef HAVE_SYS_ACL_H - return 0; -#else - acl_t acl, dfacl = NULL; - int acl_r, ret = ARCHIVE_OK; - - acl = acl_get_fd(tmpfd); - if (acl == NULL) { - if (errno == ENOENT) - /* There are not any ACLs. */ - return (ret); - archive_set_error(&a->archive, errno, - "Failed to get metadata(acl)"); - ret = ARCHIVE_WARN; - goto exit_acl; - } - dfacl = acl_dup(acl); - acl_r = acl_set_fd(dffd, dfacl); - if (acl_r == -1) { - archive_set_error(&a->archive, errno, - "Failed to get metadata(acl)"); - ret = ARCHIVE_WARN; - goto exit_acl; - } -exit_acl: - if (acl) - acl_free(acl); - if (dfacl) - acl_free(dfacl); - return (ret); -#endif -} - -static int -create_tempdatafork(struct archive_write_disk *a, const char *pathname) -{ - struct archive_string tmpdatafork; - int tmpfd; - - archive_string_init(&tmpdatafork); - archive_strcpy(&tmpdatafork, "tar.md.XXXXXX"); - tmpfd = mkstemp(tmpdatafork.s); - if (tmpfd < 0) { - archive_set_error(&a->archive, errno, - "Failed to mkstemp"); - archive_string_free(&tmpdatafork); - return (-1); - } - if (copyfile(pathname, tmpdatafork.s, 0, - COPYFILE_UNPACK | COPYFILE_NOFOLLOW - | COPYFILE_ACL | COPYFILE_XATTR) < 0) { - archive_set_error(&a->archive, errno, - "Failed to restore metadata"); - close(tmpfd); - tmpfd = -1; - } - unlink(tmpdatafork.s); - archive_string_free(&tmpdatafork); - return (tmpfd); -} - -static int -copy_metadata(struct archive_write_disk *a, const char *metadata, - const char *datafork, int datafork_compressed) -{ - int ret = ARCHIVE_OK; - - if (datafork_compressed) { - int dffd, tmpfd; - - tmpfd = create_tempdatafork(a, metadata); - if (tmpfd == -1) - return (ARCHIVE_WARN); - - /* - * Do not open the data fork compressed by HFS+ compression - * with at least a writing mode(O_RDWR or O_WRONLY). it - * makes the data fork uncompressed. - */ - dffd = open(datafork, 0); - if (dffd == -1) { - archive_set_error(&a->archive, errno, - "Failed to open the data fork for metadata"); - close(tmpfd); - return (ARCHIVE_WARN); - } - -#if defined(HAVE_SYS_XATTR_H) - ret = copy_xattrs(a, tmpfd, dffd); - if (ret == ARCHIVE_OK) -#endif - ret = copy_acls(a, tmpfd, dffd); - close(tmpfd); - close(dffd); - } else { - if (copyfile(metadata, datafork, 0, - COPYFILE_UNPACK | COPYFILE_NOFOLLOW - | COPYFILE_ACL | COPYFILE_XATTR) < 0) { - archive_set_error(&a->archive, errno, - "Failed to restore metadata"); - ret = ARCHIVE_WARN; - } - } - return (ret); -} - -static int -set_mac_metadata(struct archive_write_disk *a, const char *pathname, - const void *metadata, size_t metadata_size) -{ - struct archive_string tmp; - ssize_t written; - int fd; - int ret = ARCHIVE_OK; - - /* This would be simpler if copyfile() could just accept the - * metadata as a block of memory; then we could sidestep this - * silly dance of writing the data to disk just so that - * copyfile() can read it back in again. */ - archive_string_init(&tmp); - archive_strcpy(&tmp, pathname); - archive_strcat(&tmp, ".XXXXXX"); - fd = mkstemp(tmp.s); - - if (fd < 0) { - archive_set_error(&a->archive, errno, - "Failed to restore metadata"); - archive_string_free(&tmp); - return (ARCHIVE_WARN); - } - written = write(fd, metadata, metadata_size); - close(fd); - if ((size_t)written != metadata_size) { - archive_set_error(&a->archive, errno, - "Failed to restore metadata"); - ret = ARCHIVE_WARN; - } else { - int compressed; - -#if defined(UF_COMPRESSED) - if ((a->todo & TODO_HFS_COMPRESSION) != 0 && - (ret = lazy_stat(a)) == ARCHIVE_OK) - compressed = a->st.st_flags & UF_COMPRESSED; - else -#endif - compressed = 0; - ret = copy_metadata(a, tmp.s, pathname, compressed); - } - unlink(tmp.s); - archive_string_free(&tmp); - return (ret); -} - -static int -fixup_appledouble(struct archive_write_disk *a, const char *pathname) -{ - char buff[8]; - struct stat st; - const char *p; - struct archive_string datafork; - int fd = -1, ret = ARCHIVE_OK; - - archive_string_init(&datafork); - /* Check if the current file name is a type of the resource - * fork file. */ - p = strrchr(pathname, '/'); - if (p == NULL) - p = pathname; - else - p++; - if (p[0] != '.' || p[1] != '_') - goto skip_appledouble; - - /* - * Check if the data fork file exists. - * - * TODO: Check if this write disk object has handled it. - */ - archive_strncpy(&datafork, pathname, p - pathname); - archive_strcat(&datafork, p + 2); - if ( -#ifdef HAVE_LSTAT - lstat(datafork.s, &st) == -1 || -#else - la_stat(datafork.s, &st) == -1 || -#endif - (st.st_mode & AE_IFMT) != AE_IFREG) - goto skip_appledouble; - - /* - * Check if the file is in the AppleDouble form. - */ - fd = open(pathname, O_RDONLY | O_BINARY | O_CLOEXEC); - __archive_ensure_cloexec_flag(fd); - if (fd == -1) { - archive_set_error(&a->archive, errno, - "Failed to open a restoring file"); - ret = ARCHIVE_WARN; - goto skip_appledouble; - } - if (read(fd, buff, 8) == -1) { - archive_set_error(&a->archive, errno, - "Failed to read a restoring file"); - close(fd); - ret = ARCHIVE_WARN; - goto skip_appledouble; - } - close(fd); - /* Check AppleDouble Magic Code. */ - if (archive_be32dec(buff) != 0x00051607) - goto skip_appledouble; - /* Check AppleDouble Version. */ - if (archive_be32dec(buff+4) != 0x00020000) - goto skip_appledouble; - - ret = copy_metadata(a, pathname, datafork.s, -#if defined(UF_COMPRESSED) - st.st_flags & UF_COMPRESSED); -#else - 0); -#endif - if (ret == ARCHIVE_OK) { - unlink(pathname); - ret = ARCHIVE_EOF; - } -skip_appledouble: - archive_string_free(&datafork); - return (ret); -} -#endif - -#if ARCHIVE_XATTR_LINUX || ARCHIVE_XATTR_DARWIN || ARCHIVE_XATTR_AIX -/* - * Restore extended attributes - Linux, Darwin and AIX implementations: - * AIX' ea interface is syntaxwise identical to the Linux xattr interface. - */ -static int -set_xattrs(struct archive_write_disk *a) -{ - struct archive_entry *entry = a->entry; - struct archive_string errlist; - int ret = ARCHIVE_OK; - int i = archive_entry_xattr_reset(entry); - short fail = 0; - - archive_string_init(&errlist); - - while (i--) { - const char *name; - const void *value; - size_t size; - int e; - - archive_entry_xattr_next(entry, &name, &value, &size); - - if (name == NULL) - continue; -#if ARCHIVE_XATTR_LINUX - /* Linux: quietly skip POSIX.1e ACL extended attributes */ - if (strncmp(name, "system.", 7) == 0 && - (strcmp(name + 7, "posix_acl_access") == 0 || - strcmp(name + 7, "posix_acl_default") == 0)) - continue; - if (strncmp(name, "trusted.SGI_", 12) == 0 && - (strcmp(name + 12, "ACL_DEFAULT") == 0 || - strcmp(name + 12, "ACL_FILE") == 0)) - continue; - - /* Linux: xfsroot namespace is obsolete and unsupported */ - if (strncmp(name, "xfsroot.", 8) == 0) { - fail = 1; - archive_strcat(&errlist, name); - archive_strappend_char(&errlist, ' '); - continue; - } -#endif - - if (a->fd >= 0) { -#if ARCHIVE_XATTR_LINUX - e = fsetxattr(a->fd, name, value, size, 0); -#elif ARCHIVE_XATTR_DARWIN - e = fsetxattr(a->fd, name, value, size, 0, 0); -#elif ARCHIVE_XATTR_AIX - e = fsetea(a->fd, name, value, size, 0); -#endif - } else { -#if ARCHIVE_XATTR_LINUX - e = lsetxattr(archive_entry_pathname(entry), - name, value, size, 0); -#elif ARCHIVE_XATTR_DARWIN - e = setxattr(archive_entry_pathname(entry), - name, value, size, 0, XATTR_NOFOLLOW); -#elif ARCHIVE_XATTR_AIX - e = lsetea(archive_entry_pathname(entry), - name, value, size, 0); -#endif - } - if (e == -1) { - ret = ARCHIVE_WARN; - archive_strcat(&errlist, name); - archive_strappend_char(&errlist, ' '); - if (errno != ENOTSUP && errno != ENOSYS) - fail = 1; - } - } - - if (ret == ARCHIVE_WARN) { - if (fail && errlist.length > 0) { - errlist.length--; - errlist.s[errlist.length] = '\0'; - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Cannot restore extended attributes: %s", - errlist.s); - } else - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Cannot restore extended " - "attributes on this file system."); - } - - archive_string_free(&errlist); - return (ret); -} -#elif ARCHIVE_XATTR_FREEBSD -/* - * Restore extended attributes - FreeBSD implementation - */ -static int -set_xattrs(struct archive_write_disk *a) -{ - struct archive_entry *entry = a->entry; - struct archive_string errlist; - int ret = ARCHIVE_OK; - int i = archive_entry_xattr_reset(entry); - short fail = 0; - - archive_string_init(&errlist); - - while (i--) { - const char *name; - const void *value; - size_t size; - archive_entry_xattr_next(entry, &name, &value, &size); - if (name != NULL) { - int e; - int namespace; - - namespace = EXTATTR_NAMESPACE_USER; - - if (strncmp(name, "user.", 5) == 0) { - /* "user." attributes go to user namespace */ - name += 5; - namespace = EXTATTR_NAMESPACE_USER; - } else if (strncmp(name, "system.", 7) == 0) { - name += 7; - namespace = EXTATTR_NAMESPACE_SYSTEM; - if (!strcmp(name, "nfs4.acl") || - !strcmp(name, "posix1e.acl_access") || - !strcmp(name, "posix1e.acl_default")) - continue; - } else { - /* Other namespaces are unsupported */ - archive_strcat(&errlist, name); - archive_strappend_char(&errlist, ' '); - fail = 1; - ret = ARCHIVE_WARN; - continue; - } - - if (a->fd >= 0) { - /* - * On FreeBSD, extattr_set_fd does not - * return the same as - * extattr_set_file. It returns zero - * on success, non-zero on failure. - * - * We can detect the failure by - * manually setting errno prior to the - * call and checking after. - * - * If errno remains zero, fake the - * return value by setting e to size. - * - * This is a hack for now until I - * (Shawn Webb) get FreeBSD to fix the - * issue, if that's even possible. - */ - errno = 0; - e = extattr_set_fd(a->fd, namespace, name, - value, size); - if (e == 0 && errno == 0) { - e = size; - } - } else { - e = extattr_set_link( - archive_entry_pathname(entry), namespace, - name, value, size); - } - if (e != (int)size) { - archive_strcat(&errlist, name); - archive_strappend_char(&errlist, ' '); - ret = ARCHIVE_WARN; - if (errno != ENOTSUP && errno != ENOSYS) - fail = 1; - } - } - } - - if (ret == ARCHIVE_WARN) { - if (fail && errlist.length > 0) { - errlist.length--; - errlist.s[errlist.length] = '\0'; - - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Cannot restore extended attributes: %s", - errlist.s); - } else - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Cannot restore extended " - "attributes on this file system."); - } - - archive_string_free(&errlist); - return (ret); -} -#else -/* - * Restore extended attributes - stub implementation for unsupported systems - */ -static int -set_xattrs(struct archive_write_disk *a) -{ - static int warning_done = 0; - - /* If there aren't any extended attributes, then it's okay not - * to extract them, otherwise, issue a single warning. */ - if (archive_entry_xattr_count(a->entry) != 0 && !warning_done) { - warning_done = 1; - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Cannot restore extended attributes on this system"); - return (ARCHIVE_WARN); - } - /* Warning was already emitted; suppress further warnings. */ - return (ARCHIVE_OK); -} -#endif - -/* - * Test if file on disk is older than entry. - */ -static int -older(struct stat *st, struct archive_entry *entry) -{ - /* First, test the seconds and return if we have a definite answer. */ - /* Definitely older. */ - if (to_int64_time(st->st_mtime) < to_int64_time(archive_entry_mtime(entry))) - return (1); - /* Definitely younger. */ - if (to_int64_time(st->st_mtime) > to_int64_time(archive_entry_mtime(entry))) - return (0); - /* If this platform supports fractional seconds, try those. */ -#if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC - /* Definitely older. */ - if (st->st_mtimespec.tv_nsec < archive_entry_mtime_nsec(entry)) - return (1); -#elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC - /* Definitely older. */ - if (st->st_mtim.tv_nsec < archive_entry_mtime_nsec(entry)) - return (1); -#elif HAVE_STRUCT_STAT_ST_MTIME_N - /* older. */ - if (st->st_mtime_n < archive_entry_mtime_nsec(entry)) - return (1); -#elif HAVE_STRUCT_STAT_ST_UMTIME - /* older. */ - if (st->st_umtime * 1000 < archive_entry_mtime_nsec(entry)) - return (1); -#elif HAVE_STRUCT_STAT_ST_MTIME_USEC - /* older. */ - if (st->st_mtime_usec * 1000 < archive_entry_mtime_nsec(entry)) - return (1); -#else - /* This system doesn't have high-res timestamps. */ -#endif - /* Same age or newer, so not older. */ - return (0); -} - -#ifndef ARCHIVE_ACL_SUPPORT -int -archive_write_disk_set_acls(struct archive *a, int fd, const char *name, - struct archive_acl *abstract_acl, __LA_MODE_T mode) -{ - (void)a; /* UNUSED */ - (void)fd; /* UNUSED */ - (void)name; /* UNUSED */ - (void)abstract_acl; /* UNUSED */ - (void)mode; /* UNUSED */ - return (ARCHIVE_OK); -} -#endif - -/* - * Close the file descriptor if one is open. - */ -static void close_file_descriptor(struct archive_write_disk* a) -{ - if (a->fd >= 0) { - close(a->fd); - a->fd = -1; - } -} - - -#endif /* !_WIN32 || __CYGWIN__ */ - diff --git a/thirdparty/libarchive/libarchive/archive_write_disk_private.h b/thirdparty/libarchive/libarchive/archive_write_disk_private.h deleted file mode 100644 index 557d7e2bf..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_disk_private.h +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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: head/lib/libarchive/archive_write_disk_private.h 201086 2009-12-28 02:17:53Z kientzle $ - */ - -#ifndef ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED -#define ARCHIVE_WRITE_DISK_PRIVATE_H_INCLUDED - -#ifndef __LIBARCHIVE_BUILD -#error This header is only to be used internally to libarchive. -#endif - -#include "archive_platform_acl.h" -#include "archive_acl_private.h" -#include "archive_entry.h" - -struct archive_write_disk; - -int archive_write_disk_set_acls(struct archive *, int, const char *, - struct archive_acl *, __LA_MODE_T); - -#endif diff --git a/thirdparty/libarchive/libarchive/archive_write_disk_set_standard_lookup.c b/thirdparty/libarchive/libarchive/archive_write_disk_set_standard_lookup.c deleted file mode 100644 index 5fccdb9dc..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_disk_set_standard_lookup.c +++ /dev/null @@ -1,263 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_disk_set_standard_lookup.c 201083 2009-12-28 02:09:57Z kientzle $"); - -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_GRP_H -#include -#endif -#ifdef HAVE_PWD_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "archive.h" -#include "archive_private.h" -#include "archive_read_private.h" -#include "archive_write_disk_private.h" - -struct bucket { - char *name; - int hash; - id_t id; -}; - -static const size_t cache_size = 127; -static unsigned int hash(const char *); -static int64_t lookup_gid(void *, const char *uname, int64_t); -static int64_t lookup_uid(void *, const char *uname, int64_t); -static void cleanup(void *); - -/* - * Installs functions that use getpwnam()/getgrnam()---along with - * a simple cache to accelerate such lookups---into the archive_write_disk - * object. This is in a separate file because getpwnam()/getgrnam() - * can pull in a LOT of library code (including NIS/LDAP functions, which - * pull in DNS resolvers, etc). This can easily top 500kB, which makes - * it inappropriate for some space-constrained applications. - * - * Applications that are size-sensitive may want to just use the - * real default functions (defined in archive_write_disk.c) that just - * use the uid/gid without the lookup. Or define your own custom functions - * if you prefer. - * - * TODO: Replace these hash tables with simpler move-to-front LRU - * lists with a bounded size (128 items?). The hash is a bit faster, - * but has a bad pathology in which it thrashes a single bucket. Even - * walking a list of 128 items is a lot faster than calling - * getpwnam()! - */ -int -archive_write_disk_set_standard_lookup(struct archive *a) -{ - struct bucket *ucache = calloc(cache_size, sizeof(struct bucket)); - struct bucket *gcache = calloc(cache_size, sizeof(struct bucket)); - if (ucache == NULL || gcache == NULL) { - free(ucache); - free(gcache); - return (ARCHIVE_FATAL); - } - archive_write_disk_set_group_lookup(a, gcache, lookup_gid, cleanup); - archive_write_disk_set_user_lookup(a, ucache, lookup_uid, cleanup); - return (ARCHIVE_OK); -} - -static int64_t -lookup_gid(void *private_data, const char *gname, int64_t gid) -{ - int h; - struct bucket *b; - struct bucket *gcache = (struct bucket *)private_data; - - /* If no gname, just use the gid provided. */ - if (gname == NULL || *gname == '\0') - return (gid); - - /* Try to find gname in the cache. */ - h = hash(gname); - b = &gcache[h % cache_size ]; - if (b->name != NULL && b->hash == h && strcmp(gname, b->name) == 0) - return ((gid_t)b->id); - - /* Free the cache slot for a new entry. */ - free(b->name); - b->name = strdup(gname); - /* Note: If strdup fails, that's okay; we just won't cache. */ - b->hash = h; -#if HAVE_GRP_H -# if HAVE_GETGRNAM_R - { - char _buffer[128]; - size_t bufsize = 128; - char *buffer = _buffer; - char *allocated = NULL; - struct group grent, *result; - int r; - - for (;;) { - result = &grent; /* Old getgrnam_r ignores last arg. */ - r = getgrnam_r(gname, &grent, buffer, bufsize, &result); - if (r == 0) - break; - if (r != ERANGE) - break; - bufsize *= 2; - free(allocated); - allocated = malloc(bufsize); - if (allocated == NULL) - break; - buffer = allocated; - } - if (result != NULL) - gid = result->gr_gid; - free(allocated); - } -# else /* HAVE_GETGRNAM_R */ - { - struct group *result; - - result = getgrnam(gname); - if (result != NULL) - gid = result->gr_gid; - } -# endif /* HAVE_GETGRNAM_R */ -#elif defined(_WIN32) && !defined(__CYGWIN__) - /* TODO: do a gname->gid lookup for Windows. */ -#else - #error No way to perform gid lookups on this platform -#endif - b->id = (gid_t)gid; - - return (gid); -} - -static int64_t -lookup_uid(void *private_data, const char *uname, int64_t uid) -{ - int h; - struct bucket *b; - struct bucket *ucache = (struct bucket *)private_data; - - /* If no uname, just use the uid provided. */ - if (uname == NULL || *uname == '\0') - return (uid); - - /* Try to find uname in the cache. */ - h = hash(uname); - b = &ucache[h % cache_size ]; - if (b->name != NULL && b->hash == h && strcmp(uname, b->name) == 0) - return ((uid_t)b->id); - - /* Free the cache slot for a new entry. */ - free(b->name); - b->name = strdup(uname); - /* Note: If strdup fails, that's okay; we just won't cache. */ - b->hash = h; -#if HAVE_PWD_H -# if HAVE_GETPWNAM_R - { - char _buffer[128]; - size_t bufsize = 128; - char *buffer = _buffer; - char *allocated = NULL; - struct passwd pwent, *result; - int r; - - for (;;) { - result = &pwent; /* Old getpwnam_r ignores last arg. */ - r = getpwnam_r(uname, &pwent, buffer, bufsize, &result); - if (r == 0) - break; - if (r != ERANGE) - break; - bufsize *= 2; - free(allocated); - allocated = malloc(bufsize); - if (allocated == NULL) - break; - buffer = allocated; - } - if (result != NULL) - uid = result->pw_uid; - free(allocated); - } -# else /* HAVE_GETPWNAM_R */ - { - struct passwd *result; - - result = getpwnam(uname); - if (result != NULL) - uid = result->pw_uid; - } -#endif /* HAVE_GETPWNAM_R */ -#elif defined(_WIN32) && !defined(__CYGWIN__) - /* TODO: do a uname->uid lookup for Windows. */ -#else - #error No way to look up uids on this platform -#endif - b->id = (uid_t)uid; - - return (uid); -} - -static void -cleanup(void *private) -{ - size_t i; - struct bucket *cache = (struct bucket *)private; - - for (i = 0; i < cache_size; i++) - free(cache[i].name); - free(cache); -} - - -static unsigned int -hash(const char *p) -{ - /* A 32-bit version of Peter Weinberger's (PJW) hash algorithm, - as used by ELF for hashing function names. */ - unsigned g, h = 0; - while (*p != '\0') { - h = (h << 4) + *p++; - if ((g = h & 0xF0000000) != 0) { - h ^= g >> 24; - h &= 0x0FFFFFFF; - } - } - return h; -} diff --git a/thirdparty/libarchive/libarchive/archive_write_disk_windows.c b/thirdparty/libarchive/libarchive/archive_write_disk_windows.c deleted file mode 100644 index 7b9ea7493..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_disk_windows.c +++ /dev/null @@ -1,2911 +0,0 @@ -/*- - * Copyright (c) 2003-2010 Tim Kientzle - * Copyright (c) 2011-2012 Michihiro NAKAJIMA - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#if defined(_WIN32) && !defined(__CYGWIN__) - -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_UTIME_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif -#ifdef HAVE_LIMITS_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#include - -/* TODO: Support Mac OS 'quarantine' feature. This is really just a - * standard tag to mark files that have been downloaded as "tainted". - * On Mac OS, we should mark the extracted files as tainted if the - * archive being read was tainted. Windows has a similar feature; we - * should investigate ways to support this generically. */ - -#include "archive.h" -#include "archive_acl_private.h" -#include "archive_string.h" -#include "archive_entry.h" -#include "archive_private.h" - -#ifndef O_BINARY -#define O_BINARY 0 -#endif -#ifndef IO_REPARSE_TAG_SYMLINK -/* Old SDKs do not provide IO_REPARSE_TAG_SYMLINK */ -#define IO_REPARSE_TAG_SYMLINK 0xA000000CL -#endif - -static BOOL SetFilePointerEx_perso(HANDLE hFile, - LARGE_INTEGER liDistanceToMove, - PLARGE_INTEGER lpNewFilePointer, - DWORD dwMoveMethod) -{ - LARGE_INTEGER li; - li.QuadPart = liDistanceToMove.QuadPart; - li.LowPart = SetFilePointer( - hFile, li.LowPart, &li.HighPart, dwMoveMethod); - if(lpNewFilePointer) { - lpNewFilePointer->QuadPart = li.QuadPart; - } - return li.LowPart != (DWORD)-1 || GetLastError() == NO_ERROR; -} - -struct fixup_entry { - struct fixup_entry *next; - struct archive_acl acl; - mode_t mode; - int64_t atime; - int64_t birthtime; - int64_t mtime; - int64_t ctime; - unsigned long atime_nanos; - unsigned long birthtime_nanos; - unsigned long mtime_nanos; - unsigned long ctime_nanos; - unsigned long fflags_set; - int fixup; /* bitmask of what needs fixing */ - wchar_t *name; -}; - -/* - * We use a bitmask to track which operations remain to be done for - * this file. In particular, this helps us avoid unnecessary - * operations when it's possible to take care of one step as a - * side-effect of another. For example, mkdir() can specify the mode - * for the newly-created object but symlink() cannot. This means we - * can skip chmod() if mkdir() succeeded, but we must explicitly - * chmod() if we're trying to create a directory that already exists - * (mkdir() failed) or if we're restoring a symlink. Similarly, we - * need to verify UID/GID before trying to restore SUID/SGID bits; - * that verification can occur explicitly through a stat() call or - * implicitly because of a successful chown() call. - */ -#define TODO_MODE_FORCE 0x40000000 -#define TODO_MODE_BASE 0x20000000 -#define TODO_SUID 0x10000000 -#define TODO_SUID_CHECK 0x08000000 -#define TODO_SGID 0x04000000 -#define TODO_SGID_CHECK 0x02000000 -#define TODO_MODE (TODO_MODE_BASE|TODO_SUID|TODO_SGID) -#define TODO_TIMES ARCHIVE_EXTRACT_TIME -#define TODO_OWNER ARCHIVE_EXTRACT_OWNER -#define TODO_FFLAGS ARCHIVE_EXTRACT_FFLAGS -#define TODO_ACLS ARCHIVE_EXTRACT_ACL -#define TODO_XATTR ARCHIVE_EXTRACT_XATTR -#define TODO_MAC_METADATA ARCHIVE_EXTRACT_MAC_METADATA - -struct archive_write_disk { - struct archive archive; - - mode_t user_umask; - struct fixup_entry *fixup_list; - struct fixup_entry *current_fixup; - int64_t user_uid; - int skip_file_set; - int64_t skip_file_dev; - int64_t skip_file_ino; - time_t start_time; - - int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid); - void (*cleanup_gid)(void *private); - void *lookup_gid_data; - int64_t (*lookup_uid)(void *private, const char *uname, int64_t uid); - void (*cleanup_uid)(void *private); - void *lookup_uid_data; - - /* - * Full path of last file to satisfy symlink checks. - */ - struct archive_wstring path_safe; - - /* - * Cached stat data from disk for the current entry. - * If this is valid, pst points to st. Otherwise, - * pst is null. - */ - BY_HANDLE_FILE_INFORMATION st; - BY_HANDLE_FILE_INFORMATION *pst; - - /* Information about the object being restored right now. */ - struct archive_entry *entry; /* Entry being extracted. */ - wchar_t *name; /* Name of entry, possibly edited. */ - struct archive_wstring _name_data; /* backing store for 'name' */ - wchar_t *tmpname; /* Temporary name */ - struct archive_wstring _tmpname_data; /* backing store for 'tmpname' */ - /* Tasks remaining for this object. */ - int todo; - /* Tasks deferred until end-of-archive. */ - int deferred; - /* Options requested by the client. */ - int flags; - /* Handle for the file we're restoring. */ - HANDLE fh; - /* Current offset for writing data to the file. */ - int64_t offset; - /* Last offset actually written to disk. */ - int64_t fd_offset; - /* Total bytes actually written to files. */ - int64_t total_bytes_written; - /* Maximum size of file, -1 if unknown. */ - int64_t filesize; - /* Dir we were in before this restore; only for deep paths. */ - int restore_pwd; - /* Mode we should use for this entry; affected by _PERM and umask. */ - mode_t mode; - /* UID/GID to use in restoring this entry. */ - int64_t uid; - int64_t gid; -}; - -/* - * Default mode for dirs created automatically (will be modified by umask). - * Note that POSIX specifies 0777 for implicitly-created dirs, "modified - * by the process' file creation mask." - */ -#define DEFAULT_DIR_MODE 0777 -/* - * Dir modes are restored in two steps: During the extraction, the permissions - * in the archive are modified to match the following limits. During - * the post-extract fixup pass, the permissions from the archive are - * applied. - */ -#define MINIMUM_DIR_MODE 0700 -#define MAXIMUM_DIR_MODE 0775 - -static int disk_unlink(const wchar_t *); -static int disk_rmdir(const wchar_t *); -static int check_symlinks(struct archive_write_disk *); -static int create_filesystem_object(struct archive_write_disk *); -static struct fixup_entry *current_fixup(struct archive_write_disk *, - const wchar_t *pathname); -static int cleanup_pathname(struct archive_write_disk *, wchar_t *); -static int create_dir(struct archive_write_disk *, wchar_t *); -static int create_parent_dir(struct archive_write_disk *, wchar_t *); -static int la_chmod(const wchar_t *, mode_t); -static int la_mktemp(struct archive_write_disk *); -static int older(BY_HANDLE_FILE_INFORMATION *, struct archive_entry *); -static int permissive_name_w(struct archive_write_disk *); -static int restore_entry(struct archive_write_disk *); -static int set_acls(struct archive_write_disk *, HANDLE h, - const wchar_t *, struct archive_acl *); -static int set_xattrs(struct archive_write_disk *); -static int clear_nochange_fflags(struct archive_write_disk *); -static int set_fflags(struct archive_write_disk *); -static int set_fflags_platform(const wchar_t *, unsigned long, - unsigned long); -static int set_ownership(struct archive_write_disk *); -static int set_mode(struct archive_write_disk *, int mode); -static int set_times(struct archive_write_disk *, HANDLE, int, - const wchar_t *, time_t, long, time_t, long, time_t, - long, time_t, long); -static int set_times_from_entry(struct archive_write_disk *); -static struct fixup_entry *sort_dir_list(struct fixup_entry *p); -static ssize_t write_data_block(struct archive_write_disk *, - const char *, size_t); - -static int _archive_write_disk_close(struct archive *); -static int _archive_write_disk_free(struct archive *); -static int _archive_write_disk_header(struct archive *, - struct archive_entry *); -static int64_t _archive_write_disk_filter_bytes(struct archive *, int); -static int _archive_write_disk_finish_entry(struct archive *); -static ssize_t _archive_write_disk_data(struct archive *, const void *, - size_t); -static ssize_t _archive_write_disk_data_block(struct archive *, const void *, - size_t, int64_t); - -#define bhfi_dev(bhfi) ((bhfi)->dwVolumeSerialNumber) -/* Treat FileIndex as i-node. We should remove a sequence number - * which is high-16-bits of nFileIndexHigh. */ -#define bhfi_ino(bhfi) \ - ((((int64_t)((bhfi)->nFileIndexHigh & 0x0000FFFFUL)) << 32) \ - | (bhfi)->nFileIndexLow) -#define bhfi_size(bhfi) \ - ((((int64_t)(bhfi)->nFileSizeHigh) << 32) | (bhfi)->nFileSizeLow) - -static int -file_information(struct archive_write_disk *a, wchar_t *path, - BY_HANDLE_FILE_INFORMATION *st, mode_t *mode, int sim_lstat) -{ - HANDLE h; - int r; - DWORD flag = FILE_FLAG_BACKUP_SEMANTICS; - WIN32_FIND_DATAW findData; -# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */ - CREATEFILE2_EXTENDED_PARAMETERS createExParams; -#endif - - if (sim_lstat || mode != NULL) { - h = FindFirstFileW(path, &findData); - if (h == INVALID_HANDLE_VALUE && - GetLastError() == ERROR_INVALID_NAME) { - wchar_t *full; - full = __la_win_permissive_name_w(path); - h = FindFirstFileW(full, &findData); - free(full); - } - if (h == INVALID_HANDLE_VALUE) { - la_dosmaperr(GetLastError()); - return (-1); - } - FindClose(h); - } - - /* Is symlink file ? */ - if (sim_lstat && - ((findData.dwFileAttributes - & FILE_ATTRIBUTE_REPARSE_POINT) && - (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK))) - flag |= FILE_FLAG_OPEN_REPARSE_POINT; - -# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */ - ZeroMemory(&createExParams, sizeof(createExParams)); - createExParams.dwSize = sizeof(createExParams); - createExParams.dwFileFlags = flag; - h = CreateFile2(a->name, 0, 0, - OPEN_EXISTING, &createExParams); -#else - h = CreateFileW(a->name, 0, 0, NULL, - OPEN_EXISTING, flag, NULL); -#endif - if (h == INVALID_HANDLE_VALUE && - GetLastError() == ERROR_INVALID_NAME) { - wchar_t *full; - full = __la_win_permissive_name_w(path); -# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */ - h = CreateFile2(full, 0, 0, - OPEN_EXISTING, &createExParams); -#else - h = CreateFileW(full, 0, 0, NULL, - OPEN_EXISTING, flag, NULL); -#endif - free(full); - } - if (h == INVALID_HANDLE_VALUE) { - la_dosmaperr(GetLastError()); - return (-1); - } - r = GetFileInformationByHandle(h, st); - CloseHandle(h); - if (r == 0) { - la_dosmaperr(GetLastError()); - return (-1); - } - - if (mode == NULL) - return (0); - - *mode = S_IRUSR | S_IRGRP | S_IROTH; - if ((st->dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0) - *mode |= S_IWUSR | S_IWGRP | S_IWOTH; - if ((st->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) && - findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK) - *mode |= S_IFLNK; - else if (st->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - *mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH; - else { - const wchar_t *p; - - *mode |= S_IFREG; - p = wcsrchr(path, L'.'); - if (p != NULL && wcslen(p) == 4) { - switch (p[1]) { - case L'B': case L'b': - if ((p[2] == L'A' || p[2] == L'a' ) && - (p[3] == L'T' || p[3] == L't' )) - *mode |= S_IXUSR | S_IXGRP | S_IXOTH; - break; - case L'C': case L'c': - if (((p[2] == L'M' || p[2] == L'm' ) && - (p[3] == L'D' || p[3] == L'd' ))) - *mode |= S_IXUSR | S_IXGRP | S_IXOTH; - break; - case L'E': case L'e': - if ((p[2] == L'X' || p[2] == L'x' ) && - (p[3] == L'E' || p[3] == L'e' )) - *mode |= S_IXUSR | S_IXGRP | S_IXOTH; - break; - default: - break; - } - } - } - return (0); -} - -/* - * Note: The path, for example, "aa/a/../b../c" will be converted to "aa/c" - * by GetFullPathNameW() W32 API, which __la_win_permissive_name_w uses. - * It means we cannot handle multiple dirs in one archive_entry. - * So we have to make the full-pathname in another way, which does not - * break "../" path string. - */ -static int -permissive_name_w(struct archive_write_disk *a) -{ - wchar_t *wn, *wnp; - wchar_t *ws, *wsp; - DWORD l; - - wnp = a->name; - if (wnp[0] == L'\\' && wnp[1] == L'\\' && - wnp[2] == L'?' && wnp[3] == L'\\') - /* We have already a permissive name. */ - return (0); - - if (wnp[0] == L'\\' && wnp[1] == L'\\' && - wnp[2] == L'.' && wnp[3] == L'\\') { - /* This is a device name */ - if (((wnp[4] >= L'a' && wnp[4] <= L'z') || - (wnp[4] >= L'A' && wnp[4] <= L'Z')) && - wnp[5] == L':' && wnp[6] == L'\\') { - wnp[2] = L'?';/* Not device name. */ - return (0); - } - } - - /* - * A full-pathname starting with a drive name like "C:\abc". - */ - if (((wnp[0] >= L'a' && wnp[0] <= L'z') || - (wnp[0] >= L'A' && wnp[0] <= L'Z')) && - wnp[1] == L':' && wnp[2] == L'\\') { - wn = _wcsdup(wnp); - if (wn == NULL) - return (-1); - archive_wstring_ensure(&(a->_name_data), 4 + wcslen(wn) + 1); - a->name = a->_name_data.s; - /* Prepend "\\?\" */ - archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4); - archive_wstrcat(&(a->_name_data), wn); - free(wn); - return (0); - } - - /* - * A full-pathname pointing to a network drive - * like "\\\\file". - */ - if (wnp[0] == L'\\' && wnp[1] == L'\\' && wnp[2] != L'\\') { - const wchar_t *p = &wnp[2]; - - /* Skip server-name letters. */ - while (*p != L'\\' && *p != L'\0') - ++p; - if (*p == L'\\') { - const wchar_t *rp = ++p; - /* Skip share-name letters. */ - while (*p != L'\\' && *p != L'\0') - ++p; - if (*p == L'\\' && p != rp) { - /* Now, match patterns such as - * "\\server-name\share-name\" */ - wn = _wcsdup(wnp); - if (wn == NULL) - return (-1); - archive_wstring_ensure(&(a->_name_data), - 8 + wcslen(wn) + 1); - a->name = a->_name_data.s; - /* Prepend "\\?\UNC\" */ - archive_wstrncpy(&(a->_name_data), - L"\\\\?\\UNC\\", 8); - archive_wstrcat(&(a->_name_data), wn+2); - free(wn); - return (0); - } - } - return (0); - } - - /* - * Get current working directory. - */ - l = GetCurrentDirectoryW(0, NULL); - if (l == 0) - return (-1); - ws = malloc(l * sizeof(wchar_t)); - l = GetCurrentDirectoryW(l, ws); - if (l == 0) { - free(ws); - return (-1); - } - wsp = ws; - - /* - * A full-pathname starting without a drive name like "\abc". - */ - if (wnp[0] == L'\\') { - wn = _wcsdup(wnp); - if (wn == NULL) - return (-1); - archive_wstring_ensure(&(a->_name_data), - 4 + 2 + wcslen(wn) + 1); - a->name = a->_name_data.s; - /* Prepend "\\?\" and drive name. */ - archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4); - archive_wstrncat(&(a->_name_data), wsp, 2); - archive_wstrcat(&(a->_name_data), wn); - free(wsp); - free(wn); - return (0); - } - - wn = _wcsdup(wnp); - if (wn == NULL) - return (-1); - archive_wstring_ensure(&(a->_name_data), 4 + l + 1 + wcslen(wn) + 1); - a->name = a->_name_data.s; - /* Prepend "\\?\" and drive name if not already added. */ - if (l > 3 && wsp[0] == L'\\' && wsp[1] == L'\\' && - wsp[2] == L'?' && wsp[3] == L'\\') - { - archive_wstrncpy(&(a->_name_data), wsp, l); - } - else if (l > 2 && wsp[0] == L'\\' && wsp[1] == L'\\' && wsp[2] != L'\\') - { - archive_wstrncpy(&(a->_name_data), L"\\\\?\\UNC\\", 8); - archive_wstrncat(&(a->_name_data), wsp+2, l-2); - } - else - { - archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4); - archive_wstrncat(&(a->_name_data), wsp, l); - } - archive_wstrncat(&(a->_name_data), L"\\", 1); - archive_wstrcat(&(a->_name_data), wn); - a->name = a->_name_data.s; - free(wsp); - free(wn); - return (0); -} - -static int -la_chmod(const wchar_t *path, mode_t mode) -{ - DWORD attr; - BOOL r; - wchar_t *fullname; - int ret = 0; - - fullname = NULL; - attr = GetFileAttributesW(path); - if (attr == (DWORD)-1 && - GetLastError() == ERROR_INVALID_NAME) { - fullname = __la_win_permissive_name_w(path); - attr = GetFileAttributesW(fullname); - } - if (attr == (DWORD)-1) { - la_dosmaperr(GetLastError()); - ret = -1; - goto exit_chmode; - } - if (mode & _S_IWRITE) - attr &= ~FILE_ATTRIBUTE_READONLY; - else - attr |= FILE_ATTRIBUTE_READONLY; - if (fullname != NULL) - r = SetFileAttributesW(fullname, attr); - else - r = SetFileAttributesW(path, attr); - if (r == 0) { - la_dosmaperr(GetLastError()); - ret = -1; - } -exit_chmode: - free(fullname); - return (ret); -} - -static int -la_mktemp(struct archive_write_disk *a) -{ - int fd; - mode_t mode; - - archive_wstring_empty(&(a->_tmpname_data)); - archive_wstrcpy(&(a->_tmpname_data), a->name); - archive_wstrcat(&(a->_tmpname_data), L".XXXXXX"); - a->tmpname = a->_tmpname_data.s; - - fd = __archive_mkstemp(a->tmpname); - if (fd == -1) - return -1; - - mode = a->mode & 0777 & ~a->user_umask; - if (la_chmod(a->tmpname, mode) == -1) { - la_dosmaperr(GetLastError()); - _close(fd); - return -1; - } - return (fd); -} - -#if _WIN32_WINNT < _WIN32_WINNT_VISTA -static void * -la_GetFunctionKernel32(const char *name) -{ - static HINSTANCE lib; - static int set; - if (!set) { - set = 1; - lib = LoadLibrary(TEXT("kernel32.dll")); - } - if (lib == NULL) { - fprintf(stderr, "Can't load kernel32.dll?!\n"); - exit(1); - } - return (void *)GetProcAddress(lib, name); -} -#endif - -static int -la_CreateHardLinkW(wchar_t *linkname, wchar_t *target) -{ - static BOOL (WINAPI *f)(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES); - BOOL ret; - -#if _WIN32_WINNT < _WIN32_WINNT_XP - static int set; -/* CreateHardLinkW is available since XP and always loaded */ - if (!set) { - set = 1; - f = la_GetFunctionKernel32("CreateHardLinkW"); - } -#else - f = CreateHardLinkW; -#endif - if (!f) { - errno = ENOTSUP; - return (0); - } - ret = (*f)(linkname, target, NULL); - if (!ret) { - /* Under windows 2000, it is necessary to remove - * the "\\?\" prefix. */ -#define IS_UNC(name) ((name[0] == L'U' || name[0] == L'u') && \ - (name[1] == L'N' || name[1] == L'n') && \ - (name[2] == L'C' || name[2] == L'c') && \ - name[3] == L'\\') - if (!wcsncmp(linkname,L"\\\\?\\", 4)) { - linkname += 4; - if (IS_UNC(linkname)) - linkname += 4; - } - if (!wcsncmp(target,L"\\\\?\\", 4)) { - target += 4; - if (IS_UNC(target)) - target += 4; - } -#undef IS_UNC - ret = (*f)(linkname, target, NULL); - } - return (ret); -} - -/* - * Create file or directory symolic link - * - * If linktype is AE_SYMLINK_TYPE_UNDEFINED (or unknown), guess linktype from - * the link target - */ -static int -la_CreateSymbolicLinkW(const wchar_t *linkname, const wchar_t *target, - int linktype) { - static BOOLEAN (WINAPI *f)(LPCWSTR, LPCWSTR, DWORD); - wchar_t *ttarget, *p; - size_t len; - DWORD attrs = 0; - DWORD flags = 0; - DWORD newflags = 0; - BOOL ret = 0; - -#if _WIN32_WINNT < _WIN32_WINNT_VISTA -/* CreateSymbolicLinkW is available since Vista and always loaded */ - static int set; - if (!set) { - set = 1; - f = la_GetFunctionKernel32("CreateSymbolicLinkW"); - } -#else -# if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) - f = CreateSymbolicLinkW; -# else - f = NULL; -# endif -#endif - if (!f) - return (0); - - len = wcslen(target); - if (len == 0) { - errno = EINVAL; - return(0); - } - /* - * When writing path targets, we need to translate slashes - * to backslashes - */ - ttarget = malloc((len + 1) * sizeof(wchar_t)); - if (ttarget == NULL) - return(0); - - p = ttarget; - - while(*target != L'\0') { - if (*target == L'/') - *p = L'\\'; - else - *p = *target; - target++; - p++; - } - *p = L'\0'; - - /* - * In case of undefined symlink type we guess it from the target. - * If the target equals ".", "..", ends with a backslash or a - * backslash followed by "." or ".." we assume it is a directory - * symlink. In all other cases we assume a file symlink. - */ - if (linktype != AE_SYMLINK_TYPE_FILE && ( - linktype == AE_SYMLINK_TYPE_DIRECTORY || - *(p - 1) == L'\\' || (*(p - 1) == L'.' && ( - len == 1 || *(p - 2) == L'\\' || ( *(p - 2) == L'.' && ( - len == 2 || *(p - 3) == L'\\')))))) { -#if defined(SYMBOLIC_LINK_FLAG_DIRECTORY) - flags |= SYMBOLIC_LINK_FLAG_DIRECTORY; -#else - flags |= 0x1; -#endif - } - -#if defined(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE) - newflags = flags | SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE; -#else - newflags = flags | 0x2; -#endif - - /* - * Windows won't overwrite existing links - */ - attrs = GetFileAttributesW(linkname); - if (attrs != INVALID_FILE_ATTRIBUTES) { - if (attrs & FILE_ATTRIBUTE_DIRECTORY) - disk_rmdir(linkname); - else - disk_unlink(linkname); - } - - ret = (*f)(linkname, ttarget, newflags); - /* - * Prior to Windows 10 calling CreateSymbolicLinkW() will fail - * if SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE is set - */ - if (!ret) { - ret = (*f)(linkname, ttarget, flags); - } - free(ttarget); - return (ret); -} - -static int -la_ftruncate(HANDLE handle, int64_t length) -{ - LARGE_INTEGER distance; - - if (GetFileType(handle) != FILE_TYPE_DISK) { - errno = EBADF; - return (-1); - } - distance.QuadPart = length; - if (!SetFilePointerEx_perso(handle, distance, NULL, FILE_BEGIN)) { - la_dosmaperr(GetLastError()); - return (-1); - } - if (!SetEndOfFile(handle)) { - la_dosmaperr(GetLastError()); - return (-1); - } - return (0); -} - -static int -lazy_stat(struct archive_write_disk *a) -{ - if (a->pst != NULL) { - /* Already have stat() data available. */ - return (ARCHIVE_OK); - } - if (a->fh != INVALID_HANDLE_VALUE && - GetFileInformationByHandle(a->fh, &a->st) == 0) { - a->pst = &a->st; - return (ARCHIVE_OK); - } - - /* - * XXX At this point, symlinks should not be hit, otherwise - * XXX a race occurred. Do we want to check explicitly for that? - */ - if (file_information(a, a->name, &a->st, NULL, 1) == 0) { - a->pst = &a->st; - return (ARCHIVE_OK); - } - archive_set_error(&a->archive, errno, "Couldn't stat file"); - return (ARCHIVE_WARN); -} - -static const struct archive_vtable -archive_write_disk_vtable = { - .archive_close = _archive_write_disk_close, - .archive_filter_bytes = _archive_write_disk_filter_bytes, - .archive_free = _archive_write_disk_free, - .archive_write_header = _archive_write_disk_header, - .archive_write_finish_entry = _archive_write_disk_finish_entry, - .archive_write_data = _archive_write_disk_data, - .archive_write_data_block = _archive_write_disk_data_block, -}; - -static int64_t -_archive_write_disk_filter_bytes(struct archive *_a, int n) -{ - struct archive_write_disk *a = (struct archive_write_disk *)_a; - (void)n; /* UNUSED */ - if (n == -1 || n == 0) - return (a->total_bytes_written); - return (-1); -} - - -int -archive_write_disk_set_options(struct archive *_a, int flags) -{ - struct archive_write_disk *a = (struct archive_write_disk *)_a; - - a->flags = flags; - return (ARCHIVE_OK); -} - - -/* - * Extract this entry to disk. - * - * TODO: Validate hardlinks. According to the standards, we're - * supposed to check each extracted hardlink and squawk if it refers - * to a file that we didn't restore. I'm not entirely convinced this - * is a good idea, but more importantly: Is there any way to validate - * hardlinks without keeping a complete list of filenames from the - * entire archive?? Ugh. - * - */ -static int -_archive_write_disk_header(struct archive *_a, struct archive_entry *entry) -{ - struct archive_write_disk *a = (struct archive_write_disk *)_a; - struct fixup_entry *fe; - int ret, r; - - archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, - ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, - "archive_write_disk_header"); - archive_clear_error(&a->archive); - if (a->archive.state & ARCHIVE_STATE_DATA) { - r = _archive_write_disk_finish_entry(&a->archive); - if (r == ARCHIVE_FATAL) - return (r); - } - - /* Set up for this particular entry. */ - a->pst = NULL; - a->current_fixup = NULL; - a->deferred = 0; - archive_entry_free(a->entry); - a->entry = NULL; - a->entry = archive_entry_clone(entry); - a->fh = INVALID_HANDLE_VALUE; - a->fd_offset = 0; - a->offset = 0; - a->restore_pwd = -1; - a->uid = a->user_uid; - a->mode = archive_entry_mode(a->entry); - if (archive_entry_size_is_set(a->entry)) - a->filesize = archive_entry_size(a->entry); - else - a->filesize = -1; - archive_wstrcpy(&(a->_name_data), archive_entry_pathname_w(a->entry)); - a->name = a->_name_data.s; - archive_clear_error(&a->archive); - - /* - * Clean up the requested path. This is necessary for correct - * dir restores; the dir restore logic otherwise gets messed - * up by nonsense like "dir/.". - */ - ret = cleanup_pathname(a, a->name); - if (ret != ARCHIVE_OK) - return (ret); - - /* - * Generate a full-pathname and use it from here. - */ - if (permissive_name_w(a) < 0) { - errno = EINVAL; - return (ARCHIVE_FAILED); - } - - /* - * Query the umask so we get predictable mode settings. - * This gets done on every call to _write_header in case the - * user edits their umask during the extraction for some - * reason. - */ - umask(a->user_umask = umask(0)); - - /* Figure out what we need to do for this entry. */ - a->todo = TODO_MODE_BASE; - if (a->flags & ARCHIVE_EXTRACT_PERM) { - a->todo |= TODO_MODE_FORCE; /* Be pushy about permissions. */ - /* - * SGID requires an extra "check" step because we - * cannot easily predict the GID that the system will - * assign. (Different systems assign GIDs to files - * based on a variety of criteria, including process - * credentials and the gid of the enclosing - * directory.) We can only restore the SGID bit if - * the file has the right GID, and we only know the - * GID if we either set it (see set_ownership) or if - * we've actually called stat() on the file after it - * was restored. Since there are several places at - * which we might verify the GID, we need a TODO bit - * to keep track. - */ - if (a->mode & S_ISGID) - a->todo |= TODO_SGID | TODO_SGID_CHECK; - /* - * Verifying the SUID is simpler, but can still be - * done in multiple ways, hence the separate "check" bit. - */ - if (a->mode & S_ISUID) - a->todo |= TODO_SUID | TODO_SUID_CHECK; - } else { - /* - * User didn't request full permissions, so don't - * restore SUID, SGID bits and obey umask. - */ - a->mode &= ~S_ISUID; - a->mode &= ~S_ISGID; - a->mode &= ~S_ISVTX; - a->mode &= ~a->user_umask; - } -#if 0 - if (a->flags & ARCHIVE_EXTRACT_OWNER) - a->todo |= TODO_OWNER; -#endif - if (a->flags & ARCHIVE_EXTRACT_TIME) - a->todo |= TODO_TIMES; - if (a->flags & ARCHIVE_EXTRACT_ACL) { - if (archive_entry_filetype(a->entry) == AE_IFDIR) - a->deferred |= TODO_ACLS; - else - a->todo |= TODO_ACLS; - } - if (a->flags & ARCHIVE_EXTRACT_XATTR) - a->todo |= TODO_XATTR; - if (a->flags & ARCHIVE_EXTRACT_FFLAGS) - a->todo |= TODO_FFLAGS; - if (a->flags & ARCHIVE_EXTRACT_SECURE_SYMLINKS) { - ret = check_symlinks(a); - if (ret != ARCHIVE_OK) - return (ret); - } - - ret = restore_entry(a); - - /* - * TODO: There are rumours that some extended attributes must - * be restored before file data is written. If this is true, - * then we either need to write all extended attributes both - * before and after restoring the data, or find some rule for - * determining which must go first and which last. Due to the - * many ways people are using xattrs, this may prove to be an - * intractable problem. - */ - - /* - * Fixup uses the unedited pathname from archive_entry_pathname(), - * because it is relative to the base dir and the edited path - * might be relative to some intermediate dir as a result of the - * deep restore logic. - */ - if (a->deferred & TODO_MODE) { - fe = current_fixup(a, archive_entry_pathname_w(entry)); - fe->fixup |= TODO_MODE_BASE; - fe->mode = a->mode; - } - - if ((a->deferred & TODO_TIMES) - && (archive_entry_mtime_is_set(entry) - || archive_entry_atime_is_set(entry))) { - fe = current_fixup(a, archive_entry_pathname_w(entry)); - fe->mode = a->mode; - fe->fixup |= TODO_TIMES; - if (archive_entry_atime_is_set(entry)) { - fe->atime = archive_entry_atime(entry); - fe->atime_nanos = archive_entry_atime_nsec(entry); - } else { - /* If atime is unset, use start time. */ - fe->atime = a->start_time; - fe->atime_nanos = 0; - } - if (archive_entry_mtime_is_set(entry)) { - fe->mtime = archive_entry_mtime(entry); - fe->mtime_nanos = archive_entry_mtime_nsec(entry); - } else { - /* If mtime is unset, use start time. */ - fe->mtime = a->start_time; - fe->mtime_nanos = 0; - } - if (archive_entry_birthtime_is_set(entry)) { - fe->birthtime = archive_entry_birthtime(entry); - fe->birthtime_nanos = archive_entry_birthtime_nsec(entry); - } else { - /* If birthtime is unset, use mtime. */ - fe->birthtime = fe->mtime; - fe->birthtime_nanos = fe->mtime_nanos; - } - } - - if (a->deferred & TODO_ACLS) { - fe = current_fixup(a, archive_entry_pathname_w(entry)); - archive_acl_copy(&fe->acl, archive_entry_acl(entry)); - } - - if (a->deferred & TODO_FFLAGS) { - unsigned long set, clear; - - fe = current_fixup(a, archive_entry_pathname_w(entry)); - archive_entry_fflags(entry, &set, &clear); - fe->fflags_set = set; - } - - /* - * On Windows, A creating sparse file requires a special mark. - */ - if (a->fh != INVALID_HANDLE_VALUE && - archive_entry_sparse_count(entry) > 0) { - int64_t base = 0, offset, length; - int i, cnt = archive_entry_sparse_reset(entry); - int sparse = 0; - - for (i = 0; i < cnt; i++) { - archive_entry_sparse_next(entry, &offset, &length); - if (offset - base >= 4096) { - sparse = 1;/* we have a hole. */ - break; - } - base = offset + length; - } - if (sparse) { - DWORD dmy; - /* Mark this file as sparse. */ - DeviceIoControl(a->fh, FSCTL_SET_SPARSE, - NULL, 0, NULL, 0, &dmy, NULL); - } - } - - /* We've created the object and are ready to pour data into it. */ - if (ret >= ARCHIVE_WARN) - a->archive.state = ARCHIVE_STATE_DATA; - /* - * If it's not open, tell our client not to try writing. - * In particular, dirs, links, etc, don't get written to. - */ - if (a->fh == INVALID_HANDLE_VALUE) { - archive_entry_set_size(entry, 0); - a->filesize = 0; - } - - return (ret); -} - -int -archive_write_disk_set_skip_file(struct archive *_a, la_int64_t d, la_int64_t i) -{ - struct archive_write_disk *a = (struct archive_write_disk *)_a; - archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_write_disk_set_skip_file"); - a->skip_file_set = 1; - a->skip_file_dev = d; - a->skip_file_ino = i; - return (ARCHIVE_OK); -} - -static ssize_t -write_data_block(struct archive_write_disk *a, const char *buff, size_t size) -{ - OVERLAPPED ol; - uint64_t start_size = size; - DWORD bytes_written = 0; - ssize_t block_size = 0, bytes_to_write; - - if (size == 0) - return (ARCHIVE_OK); - - if (a->filesize == 0 || a->fh == INVALID_HANDLE_VALUE) { - archive_set_error(&a->archive, 0, - "Attempt to write to an empty file"); - return (ARCHIVE_WARN); - } - - if (a->flags & ARCHIVE_EXTRACT_SPARSE) { - /* XXX TODO XXX Is there a more appropriate choice here ? */ - /* This needn't match the filesystem allocation size. */ - block_size = 16*1024; - } - - /* If this write would run beyond the file size, truncate it. */ - if (a->filesize >= 0 && (int64_t)(a->offset + size) > a->filesize) - start_size = size = (size_t)(a->filesize - a->offset); - - /* Write the data. */ - while (size > 0) { - if (block_size == 0) { - bytes_to_write = size; - } else { - /* We're sparsifying the file. */ - const char *p, *end; - int64_t block_end; - - /* Skip leading zero bytes. */ - for (p = buff, end = buff + size; p < end; ++p) { - if (*p != '\0') - break; - } - a->offset += p - buff; - size -= p - buff; - buff = p; - if (size == 0) - break; - - /* Calculate next block boundary after offset. */ - block_end - = (a->offset / block_size + 1) * block_size; - - /* If the adjusted write would cross block boundary, - * truncate it to the block boundary. */ - bytes_to_write = size; - if (a->offset + bytes_to_write > block_end) - bytes_to_write = (DWORD)(block_end - a->offset); - } - memset(&ol, 0, sizeof(ol)); - ol.Offset = (DWORD)(a->offset & 0xFFFFFFFF); - ol.OffsetHigh = (DWORD)(a->offset >> 32); - if (!WriteFile(a->fh, buff, (uint32_t)bytes_to_write, - &bytes_written, &ol)) { - DWORD lasterr; - - lasterr = GetLastError(); - if (lasterr == ERROR_ACCESS_DENIED) - errno = EBADF; - else - la_dosmaperr(lasterr); - archive_set_error(&a->archive, errno, "Write failed"); - return (ARCHIVE_WARN); - } - buff += bytes_written; - size -= bytes_written; - a->total_bytes_written += bytes_written; - a->offset += bytes_written; - a->fd_offset = a->offset; - } - return ((ssize_t)(start_size - size)); -} - -static ssize_t -_archive_write_disk_data_block(struct archive *_a, - const void *buff, size_t size, int64_t offset) -{ - struct archive_write_disk *a = (struct archive_write_disk *)_a; - ssize_t r; - - archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, - ARCHIVE_STATE_DATA, "archive_write_data_block"); - - a->offset = offset; - r = write_data_block(a, buff, size); - if (r < ARCHIVE_OK) - return (r); - if ((size_t)r < size) { - archive_set_error(&a->archive, 0, - "Write request too large"); - return (ARCHIVE_WARN); - } -#if ARCHIVE_VERSION_NUMBER < 3999000 - return (ARCHIVE_OK); -#else - return (size); -#endif -} - -static ssize_t -_archive_write_disk_data(struct archive *_a, const void *buff, size_t size) -{ - struct archive_write_disk *a = (struct archive_write_disk *)_a; - - archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, - ARCHIVE_STATE_DATA, "archive_write_data"); - - return (write_data_block(a, buff, size)); -} - -static int -_archive_write_disk_finish_entry(struct archive *_a) -{ - struct archive_write_disk *a = (struct archive_write_disk *)_a; - int ret = ARCHIVE_OK; - - archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, - ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, - "archive_write_finish_entry"); - if (a->archive.state & ARCHIVE_STATE_HEADER) - return (ARCHIVE_OK); - archive_clear_error(&a->archive); - - /* Pad or truncate file to the right size. */ - if (a->fh == INVALID_HANDLE_VALUE) { - /* There's no file. */ - } else if (a->filesize < 0) { - /* File size is unknown, so we can't set the size. */ - } else if (a->fd_offset == a->filesize) { - /* Last write ended at exactly the filesize; we're done. */ - /* Hopefully, this is the common case. */ - } else { - if (la_ftruncate(a->fh, a->filesize) == -1) { - archive_set_error(&a->archive, errno, - "File size could not be restored"); - CloseHandle(a->fh); - a->fh = INVALID_HANDLE_VALUE; - return (ARCHIVE_FAILED); - } - } - - /* Restore metadata. */ - - /* - * Look up the "real" UID only if we're going to need it. - * TODO: the TODO_SGID condition can be dropped here, can't it? - */ - if (a->todo & (TODO_OWNER | TODO_SUID | TODO_SGID)) { - a->uid = archive_write_disk_uid(&a->archive, - archive_entry_uname(a->entry), - archive_entry_uid(a->entry)); - } - /* Look up the "real" GID only if we're going to need it. */ - /* TODO: the TODO_SUID condition can be dropped here, can't it? */ - if (a->todo & (TODO_OWNER | TODO_SGID | TODO_SUID)) { - a->gid = archive_write_disk_gid(&a->archive, - archive_entry_gname(a->entry), - archive_entry_gid(a->entry)); - } - - /* - * Restore ownership before set_mode tries to restore suid/sgid - * bits. If we set the owner, we know what it is and can skip - * a stat() call to examine the ownership of the file on disk. - */ - if (a->todo & TODO_OWNER) - ret = set_ownership(a); - - /* - * set_mode must precede ACLs on systems such as Solaris and - * FreeBSD where setting the mode implicitly clears extended ACLs - */ - if (a->todo & TODO_MODE) { - int r2 = set_mode(a, a->mode); - if (r2 < ret) ret = r2; - } - - /* - * Security-related extended attributes (such as - * security.capability on Linux) have to be restored last, - * since they're implicitly removed by other file changes. - */ - if (a->todo & TODO_XATTR) { - int r2 = set_xattrs(a); - if (r2 < ret) ret = r2; - } - - /* - * Some flags prevent file modification; they must be restored after - * file contents are written. - */ - if (a->todo & TODO_FFLAGS) { - int r2 = set_fflags(a); - if (r2 < ret) ret = r2; - } - - /* - * Time must follow most other metadata; - * otherwise atime will get changed. - */ - if (a->todo & TODO_TIMES) { - int r2 = set_times_from_entry(a); - if (r2 < ret) ret = r2; - } - - /* - * ACLs must be restored after timestamps because there are - * ACLs that prevent attribute changes (including time). - */ - if (a->todo & TODO_ACLS) { - int r2 = set_acls(a, a->fh, - archive_entry_pathname_w(a->entry), - archive_entry_acl(a->entry)); - if (r2 < ret) ret = r2; - } - - /* If there's an fd, we can close it now. */ - if (a->fh != INVALID_HANDLE_VALUE) { - CloseHandle(a->fh); - a->fh = INVALID_HANDLE_VALUE; - if (a->tmpname) { - /* Windows does not support atomic rename */ - disk_unlink(a->name); - if (_wrename(a->tmpname, a->name) != 0) { - la_dosmaperr(GetLastError()); - archive_set_error(&a->archive, errno, - "Failed to rename temporary file"); - ret = ARCHIVE_FAILED; - disk_unlink(a->tmpname); - } - a->tmpname = NULL; - } - } - /* If there's an entry, we can release it now. */ - archive_entry_free(a->entry); - a->entry = NULL; - a->archive.state = ARCHIVE_STATE_HEADER; - return (ret); -} - -int -archive_write_disk_set_group_lookup(struct archive *_a, - void *private_data, - la_int64_t (*lookup_gid)(void *private, const char *gname, la_int64_t gid), - void (*cleanup_gid)(void *private)) -{ - struct archive_write_disk *a = (struct archive_write_disk *)_a; - archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_write_disk_set_group_lookup"); - - if (a->cleanup_gid != NULL && a->lookup_gid_data != NULL) - (a->cleanup_gid)(a->lookup_gid_data); - - a->lookup_gid = lookup_gid; - a->cleanup_gid = cleanup_gid; - a->lookup_gid_data = private_data; - return (ARCHIVE_OK); -} - -int -archive_write_disk_set_user_lookup(struct archive *_a, - void *private_data, - int64_t (*lookup_uid)(void *private, const char *uname, int64_t uid), - void (*cleanup_uid)(void *private)) -{ - struct archive_write_disk *a = (struct archive_write_disk *)_a; - archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_write_disk_set_user_lookup"); - - if (a->cleanup_uid != NULL && a->lookup_uid_data != NULL) - (a->cleanup_uid)(a->lookup_uid_data); - - a->lookup_uid = lookup_uid; - a->cleanup_uid = cleanup_uid; - a->lookup_uid_data = private_data; - return (ARCHIVE_OK); -} - -int64_t -archive_write_disk_gid(struct archive *_a, const char *name, la_int64_t id) -{ - struct archive_write_disk *a = (struct archive_write_disk *)_a; - archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_write_disk_gid"); - if (a->lookup_gid) - return (a->lookup_gid)(a->lookup_gid_data, name, id); - return (id); -} - -int64_t -archive_write_disk_uid(struct archive *_a, const char *name, la_int64_t id) -{ - struct archive_write_disk *a = (struct archive_write_disk *)_a; - archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, - ARCHIVE_STATE_ANY, "archive_write_disk_uid"); - if (a->lookup_uid) - return (a->lookup_uid)(a->lookup_uid_data, name, id); - return (id); -} - -/* - * Create a new archive_write_disk object and initialize it with global state. - */ -struct archive * -archive_write_disk_new(void) -{ - struct archive_write_disk *a; - - a = (struct archive_write_disk *)calloc(1, sizeof(*a)); - if (a == NULL) - return (NULL); - a->archive.magic = ARCHIVE_WRITE_DISK_MAGIC; - /* We're ready to write a header immediately. */ - a->archive.state = ARCHIVE_STATE_HEADER; - a->archive.vtable = &archive_write_disk_vtable; - a->start_time = time(NULL); - /* Query and restore the umask. */ - umask(a->user_umask = umask(0)); - if (archive_wstring_ensure(&a->path_safe, 512) == NULL) { - free(a); - return (NULL); - } - a->path_safe.s[0] = 0; - return (&a->archive); -} - -static int -disk_unlink(const wchar_t *path) -{ - wchar_t *fullname; - int r; - - r = _wunlink(path); - if (r != 0 && GetLastError() == ERROR_INVALID_NAME) { - fullname = __la_win_permissive_name_w(path); - r = _wunlink(fullname); - free(fullname); - } - return (r); -} - -static int -disk_rmdir(const wchar_t *path) -{ - wchar_t *fullname; - int r; - - r = _wrmdir(path); - if (r != 0 && GetLastError() == ERROR_INVALID_NAME) { - fullname = __la_win_permissive_name_w(path); - r = _wrmdir(fullname); - free(fullname); - } - return (r); -} - -/* - * The main restore function. - */ -static int -restore_entry(struct archive_write_disk *a) -{ - int ret = ARCHIVE_OK, en; - - if (a->flags & ARCHIVE_EXTRACT_UNLINK && !S_ISDIR(a->mode)) { - /* - * TODO: Fix this. Apparently, there are platforms - * that still allow root to hose the entire filesystem - * by unlinking a dir. The S_ISDIR() test above - * prevents us from using unlink() here if the new - * object is a dir, but that doesn't mean the old - * object isn't a dir. - */ - if (a->flags & ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS) - (void)clear_nochange_fflags(a); - if (disk_unlink(a->name) == 0) { - /* We removed it, reset cached stat. */ - a->pst = NULL; - } else if (errno == ENOENT) { - /* File didn't exist, that's just as good. */ - } else if (disk_rmdir(a->name) == 0) { - /* It was a dir, but now it's gone. */ - a->pst = NULL; - } else { - /* We tried, but couldn't get rid of it. */ - archive_set_error(&a->archive, errno, - "Could not unlink"); - return(ARCHIVE_FAILED); - } - } - - /* Try creating it first; if this fails, we'll try to recover. */ - en = create_filesystem_object(a); - - if ((en == ENOTDIR || en == ENOENT) - && !(a->flags & ARCHIVE_EXTRACT_NO_AUTODIR)) { - wchar_t *full; - /* If the parent dir doesn't exist, try creating it. */ - create_parent_dir(a, a->name); - /* Now try to create the object again. */ - full = __la_win_permissive_name_w(a->name); - if (full == NULL) { - en = EINVAL; - } else { - /* Remove multiple directories such as "a/../b../c" */ - archive_wstrcpy(&(a->_name_data), full); - a->name = a->_name_data.s; - free(full); - en = create_filesystem_object(a); - } - } - - if ((en == ENOENT) && (archive_entry_hardlink(a->entry) != NULL)) { - archive_set_error(&a->archive, en, - "Hard-link target '%s' does not exist.", - archive_entry_hardlink(a->entry)); - return (ARCHIVE_FAILED); - } - - if ((en == EISDIR || en == EEXIST) - && (a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) { - /* If we're not overwriting, we're done. */ - if (S_ISDIR(a->mode)) { - /* Don't overwrite any settings on existing directories. */ - a->todo = 0; - } - archive_entry_unset_size(a->entry); - return (ARCHIVE_OK); - } - - /* - * Some platforms return EISDIR if you call - * open(O_WRONLY | O_EXCL | O_CREAT) on a directory, some - * return EEXIST. POSIX is ambiguous, requiring EISDIR - * for open(O_WRONLY) on a dir and EEXIST for open(O_EXCL | O_CREAT) - * on an existing item. - */ - if (en == EISDIR) { - /* A dir is in the way of a non-dir, rmdir it. */ - if (disk_rmdir(a->name) != 0) { - archive_set_error(&a->archive, errno, - "Can't remove already-existing dir"); - return (ARCHIVE_FAILED); - } - a->pst = NULL; - /* Try again. */ - en = create_filesystem_object(a); - } else if (en == EEXIST) { - mode_t st_mode; - mode_t lst_mode; - BY_HANDLE_FILE_INFORMATION lst; - /* - * We know something is in the way, but we don't know what; - * we need to find out before we go any further. - */ - int r = 0; - int dirlnk = 0; - - /* - * The SECURE_SYMLINK logic has already removed a - * symlink to a dir if the client wants that. So - * follow the symlink if we're creating a dir. - * If it's not a dir (or it's a broken symlink), - * then don't follow it. - * - * Windows distinguishes file and directory symlinks. - * A file symlink may erroneously point to a directory - * and a directory symlink to a file. Windows does not follow - * such symlinks. We always need both source and target - * information. - */ - r = file_information(a, a->name, &lst, &lst_mode, 1); - if (r != 0) { - archive_set_error(&a->archive, errno, - "Can't stat existing object"); - return (ARCHIVE_FAILED); - } else if (S_ISLNK(lst_mode)) { - if (lst.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - dirlnk = 1; - /* In case of a symlink we need target information */ - r = file_information(a, a->name, &a->st, &st_mode, 0); - if (r != 0) { - a->st = lst; - st_mode = lst_mode; - } - } else { - a->st = lst; - st_mode = lst_mode; - } - - /* - * NO_OVERWRITE_NEWER doesn't apply to directories. - */ - if ((a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER) - && !S_ISDIR(st_mode)) { - if (!older(&(a->st), a->entry)) { - archive_entry_unset_size(a->entry); - return (ARCHIVE_OK); - } - } - - /* If it's our archive, we're done. */ - if (a->skip_file_set && - bhfi_dev(&a->st) == a->skip_file_dev && - bhfi_ino(&a->st) == a->skip_file_ino) { - archive_set_error(&a->archive, 0, - "Refusing to overwrite archive"); - return (ARCHIVE_FAILED); - } - - if (!S_ISDIR(st_mode)) { - if (a->flags & - ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS) { - (void)clear_nochange_fflags(a); - } - if ((a->flags & ARCHIVE_EXTRACT_SAFE_WRITES) && - S_ISREG(st_mode)) { - int fd = la_mktemp(a); - - if (fd == -1) { - la_dosmaperr(GetLastError()); - archive_set_error(&a->archive, errno, - "Can't create temporary file"); - return (ARCHIVE_FAILED); - } - a->fh = (HANDLE)_get_osfhandle(fd); - if (a->fh == INVALID_HANDLE_VALUE) { - la_dosmaperr(GetLastError()); - return (ARCHIVE_FAILED); - } - a->pst = NULL; - en = 0; - } else { - if (dirlnk) { - /* Edge case: dir symlink pointing - * to a file */ - if (disk_rmdir(a->name) != 0) { - archive_set_error(&a->archive, - errno, "Can't unlink " - "directory symlink"); - return (ARCHIVE_FAILED); - } - } else { - if (disk_unlink(a->name) != 0) { - /* A non-dir is in the way, - * unlink it. */ - archive_set_error(&a->archive, - errno, "Can't unlink " - "already-existing object"); - return (ARCHIVE_FAILED); - } - } - a->pst = NULL; - /* Try again. */ - en = create_filesystem_object(a); - } - } else if (!S_ISDIR(a->mode)) { - /* A dir is in the way of a non-dir, rmdir it. */ - if (a->flags & ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS) - (void)clear_nochange_fflags(a); - if (disk_rmdir(a->name) != 0) { - archive_set_error(&a->archive, errno, - "Can't remove already-existing dir"); - return (ARCHIVE_FAILED); - } - /* Try again. */ - en = create_filesystem_object(a); - } else { - /* - * There's a dir in the way of a dir. Don't - * waste time with rmdir()/mkdir(), just fix - * up the permissions on the existing dir. - * Note that we don't change perms on existing - * dirs unless _EXTRACT_PERM is specified. - */ - if ((a->mode != st_mode) - && (a->todo & TODO_MODE_FORCE)) - a->deferred |= (a->todo & TODO_MODE); - /* Ownership doesn't need deferred fixup. */ - en = 0; /* Forget the EEXIST. */ - } - } - - if (en) { - /* Everything failed; give up here. */ - archive_set_error(&a->archive, en, "Can't create '%ls'", - a->name); - return (ARCHIVE_FAILED); - } - - a->pst = NULL; /* Cached stat data no longer valid. */ - return (ret); -} - -/* - * Returns 0 if creation succeeds, or else returns errno value from - * the failed system call. Note: This function should only ever perform - * a single system call. - */ -static int -create_filesystem_object(struct archive_write_disk *a) -{ - /* Create the entry. */ - const wchar_t *linkname; - wchar_t *fullname; - mode_t final_mode, mode; - int r; - DWORD attrs = 0; -# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */ - CREATEFILE2_EXTENDED_PARAMETERS createExParams; -#endif - - /* We identify hard/symlinks according to the link names. */ - /* Since link(2) and symlink(2) don't handle modes, we're done here. */ - linkname = archive_entry_hardlink_w(a->entry); - if (linkname != NULL) { - wchar_t *linksanitized, *linkfull, *namefull; - size_t l = (wcslen(linkname) + 1) * sizeof(wchar_t); - linksanitized = malloc(l); - if (linksanitized == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for hardlink target"); - return (-1); - } - memcpy(linksanitized, linkname, l); - r = cleanup_pathname(a, linksanitized); - if (r != ARCHIVE_OK) { - free(linksanitized); - return (r); - } - linkfull = __la_win_permissive_name_w(linksanitized); - free(linksanitized); - namefull = __la_win_permissive_name_w(a->name); - if (linkfull == NULL || namefull == NULL) { - errno = EINVAL; - r = -1; - } else { - /* - * Unlinking and linking here is really not atomic, - * but doing it right, would require us to construct - * an mktemplink() function, and then use _wrename(). - */ - if (a->flags & ARCHIVE_EXTRACT_SAFE_WRITES) { - attrs = GetFileAttributesW(namefull); - if (attrs != INVALID_FILE_ATTRIBUTES) { - if (attrs & FILE_ATTRIBUTE_DIRECTORY) - disk_rmdir(namefull); - else - disk_unlink(namefull); - } - } - r = la_CreateHardLinkW(namefull, linkfull); - if (r == 0) { - la_dosmaperr(GetLastError()); - r = errno; - } else - r = 0; - } - /* - * New cpio and pax formats allow hardlink entries - * to carry data, so we may have to open the file - * for hardlink entries. - * - * If the hardlink was successfully created and - * the archive doesn't have carry data for it, - * consider it to be non-authoritative for meta data. - * This is consistent with GNU tar and BSD pax. - * If the hardlink does carry data, let the last - * archive entry decide ownership. - */ - if (r == 0 && a->filesize <= 0) { - a->todo = 0; - a->deferred = 0; - } else if (r == 0 && a->filesize > 0) { -# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */ - ZeroMemory(&createExParams, sizeof(createExParams)); - createExParams.dwSize = sizeof(createExParams); - createExParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; - a->fh = CreateFile2(namefull, GENERIC_WRITE, 0, - TRUNCATE_EXISTING, &createExParams); -#else - a->fh = CreateFileW(namefull, GENERIC_WRITE, 0, NULL, - TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); -#endif - if (a->fh == INVALID_HANDLE_VALUE) { - la_dosmaperr(GetLastError()); - r = errno; - } - } - free(linkfull); - free(namefull); - return (r); - } - linkname = archive_entry_symlink_w(a->entry); - if (linkname != NULL) { - /* - * Unlinking and linking here is really not atomic, - * but doing it right, would require us to construct - * an mktemplink() function, and then use _wrename(). - */ - attrs = GetFileAttributesW(a->name); - if (attrs != INVALID_FILE_ATTRIBUTES) { - if (attrs & FILE_ATTRIBUTE_DIRECTORY) - disk_rmdir(a->name); - else - disk_unlink(a->name); - } -#if HAVE_SYMLINK - return symlink(linkname, a->name) ? errno : 0; -#else - errno = 0; - r = la_CreateSymbolicLinkW((const wchar_t *)a->name, linkname, - archive_entry_symlink_type(a->entry)); - if (r == 0) { - if (errno == 0) - la_dosmaperr(GetLastError()); - r = errno; - } else - r = 0; - return (r); -#endif - } - - /* - * The remaining system calls all set permissions, so let's - * try to take advantage of that to avoid an extra chmod() - * call. (Recall that umask is set to zero right now!) - */ - - /* Mode we want for the final restored object (w/o file type bits). */ - final_mode = a->mode & 07777; - /* - * The mode that will actually be restored in this step. Note - * that SUID, SGID, etc, require additional work to ensure - * security, so we never restore them at this point. - */ - mode = final_mode & 0777 & ~a->user_umask; - - switch (a->mode & AE_IFMT) { - default: - /* POSIX requires that we fall through here. */ - /* FALLTHROUGH */ - case AE_IFREG: - a->tmpname = NULL; - fullname = a->name; - /* O_WRONLY | O_CREAT | O_EXCL */ -# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */ - ZeroMemory(&createExParams, sizeof(createExParams)); - createExParams.dwSize = sizeof(createExParams); - createExParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; - a->fh = CreateFile2(fullname, GENERIC_WRITE, 0, - CREATE_NEW, &createExParams); -#else - a->fh = CreateFileW(fullname, GENERIC_WRITE, 0, NULL, - CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); -#endif - if (a->fh == INVALID_HANDLE_VALUE && - GetLastError() == ERROR_INVALID_NAME && - fullname == a->name) { - fullname = __la_win_permissive_name_w(a->name); -# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */ - a->fh = CreateFile2(fullname, GENERIC_WRITE, 0, - CREATE_NEW, &createExParams); -#else - a->fh = CreateFileW(fullname, GENERIC_WRITE, 0, NULL, - CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); -#endif - } - if (a->fh == INVALID_HANDLE_VALUE) { - if (GetLastError() == ERROR_ACCESS_DENIED) { - DWORD attr; - /* Simulate an errno of POSIX system. */ - attr = GetFileAttributesW(fullname); - if (attr == (DWORD)-1) - la_dosmaperr(GetLastError()); - else if (attr & FILE_ATTRIBUTE_DIRECTORY) - errno = EISDIR; - else - errno = EACCES; - } else - la_dosmaperr(GetLastError()); - r = 1; - } else - r = 0; - if (fullname != a->name) - free(fullname); - break; - case AE_IFCHR: - case AE_IFBLK: - /* TODO: Find a better way to warn about our inability - * to restore a block device node. */ - return (EINVAL); - case AE_IFDIR: - mode = (mode | MINIMUM_DIR_MODE) & MAXIMUM_DIR_MODE; - fullname = a->name; - r = CreateDirectoryW(fullname, NULL); - if (r == 0 && GetLastError() == ERROR_INVALID_NAME && - fullname == a->name) { - fullname = __la_win_permissive_name_w(a->name); - r = CreateDirectoryW(fullname, NULL); - } - if (r != 0) { - r = 0; - /* Defer setting dir times. */ - a->deferred |= (a->todo & TODO_TIMES); - a->todo &= ~TODO_TIMES; - /* Never use an immediate chmod(). */ - /* We can't avoid the chmod() entirely if EXTRACT_PERM - * because of SysV SGID inheritance. */ - if ((mode != final_mode) - || (a->flags & ARCHIVE_EXTRACT_PERM)) - a->deferred |= (a->todo & TODO_MODE); - a->todo &= ~TODO_MODE; - } else { - la_dosmaperr(GetLastError()); - r = -1; - } - if (fullname != a->name) - free(fullname); - break; - case AE_IFIFO: - /* TODO: Find a better way to warn about our inability - * to restore a fifo. */ - return (EINVAL); - } - - /* All the system calls above set errno on failure. */ - if (r) - return (errno); - - /* If we managed to set the final mode, we've avoided a chmod(). */ - if (mode == final_mode) - a->todo &= ~TODO_MODE; - return (0); -} - -/* - * Cleanup function for archive_extract. Mostly, this involves processing - * the fixup list, which is used to address a number of problems: - * * Dir permissions might prevent us from restoring a file in that - * dir, so we restore the dir with minimum 0700 permissions first, - * then correct the mode at the end. - * * Similarly, the act of restoring a file touches the directory - * and changes the timestamp on the dir, so we have to touch-up dir - * timestamps at the end as well. - * * Some file flags can interfere with the restore by, for example, - * preventing the creation of hardlinks to those files. - * * Mac OS extended metadata includes ACLs, so must be deferred on dirs. - * - * Note that tar/cpio do not require that archives be in a particular - * order; there is no way to know when the last file has been restored - * within a directory, so there's no way to optimize the memory usage - * here by fixing up the directory any earlier than the - * end-of-archive. - * - * XXX TODO: Directory ACLs should be restored here, for the same - * reason we set directory perms here. XXX - */ -static int -_archive_write_disk_close(struct archive *_a) -{ - struct archive_write_disk *a = (struct archive_write_disk *)_a; - struct fixup_entry *next, *p; - int ret; - - archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, - ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, - "archive_write_disk_close"); - ret = _archive_write_disk_finish_entry(&a->archive); - - /* Sort dir list so directories are fixed up in depth-first order. */ - p = sort_dir_list(a->fixup_list); - - while (p != NULL) { - a->pst = NULL; /* Mark stat cache as out-of-date. */ - if (p->fixup & TODO_TIMES) { - set_times(a, INVALID_HANDLE_VALUE, p->mode, p->name, - p->atime, p->atime_nanos, - p->birthtime, p->birthtime_nanos, - p->mtime, p->mtime_nanos, - p->ctime, p->ctime_nanos); - } - if (p->fixup & TODO_MODE_BASE) - la_chmod(p->name, p->mode); - if (p->fixup & TODO_ACLS) - set_acls(a, INVALID_HANDLE_VALUE, p->name, &p->acl); - if (p->fixup & TODO_FFLAGS) - set_fflags_platform(p->name, p->fflags_set, 0); - next = p->next; - archive_acl_clear(&p->acl); - free(p->name); - free(p); - p = next; - } - a->fixup_list = NULL; - return (ret); -} - -static int -_archive_write_disk_free(struct archive *_a) -{ - struct archive_write_disk *a; - int ret; - if (_a == NULL) - return (ARCHIVE_OK); - archive_check_magic(_a, ARCHIVE_WRITE_DISK_MAGIC, - ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_disk_free"); - a = (struct archive_write_disk *)_a; - ret = _archive_write_disk_close(&a->archive); - archive_write_disk_set_group_lookup(&a->archive, NULL, NULL, NULL); - archive_write_disk_set_user_lookup(&a->archive, NULL, NULL, NULL); - archive_entry_free(a->entry); - archive_wstring_free(&a->_name_data); - archive_wstring_free(&a->_tmpname_data); - archive_string_free(&a->archive.error_string); - archive_wstring_free(&a->path_safe); - a->archive.magic = 0; - __archive_clean(&a->archive); - free(a); - return (ret); -} - -/* - * Simple O(n log n) merge sort to order the fixup list. In - * particular, we want to restore dir timestamps depth-first. - */ -static struct fixup_entry * -sort_dir_list(struct fixup_entry *p) -{ - struct fixup_entry *a, *b, *t; - - if (p == NULL) - return (NULL); - /* A one-item list is already sorted. */ - if (p->next == NULL) - return (p); - - /* Step 1: split the list. */ - t = p; - a = p->next->next; - while (a != NULL) { - /* Step a twice, t once. */ - a = a->next; - if (a != NULL) - a = a->next; - t = t->next; - } - /* Now, t is at the mid-point, so break the list here. */ - b = t->next; - t->next = NULL; - a = p; - - /* Step 2: Recursively sort the two sub-lists. */ - a = sort_dir_list(a); - b = sort_dir_list(b); - - /* Step 3: Merge the returned lists. */ - /* Pick the first element for the merged list. */ - if (wcscmp(a->name, b->name) > 0) { - t = p = a; - a = a->next; - } else { - t = p = b; - b = b->next; - } - - /* Always put the later element on the list first. */ - while (a != NULL && b != NULL) { - if (wcscmp(a->name, b->name) > 0) { - t->next = a; - a = a->next; - } else { - t->next = b; - b = b->next; - } - t = t->next; - } - - /* Only one list is non-empty, so just splice it on. */ - if (a != NULL) - t->next = a; - if (b != NULL) - t->next = b; - - return (p); -} - -/* - * Returns a new, initialized fixup entry. - * - * TODO: Reduce the memory requirements for this list by using a tree - * structure rather than a simple list of names. - */ -static struct fixup_entry * -new_fixup(struct archive_write_disk *a, const wchar_t *pathname) -{ - struct fixup_entry *fe; - - fe = (struct fixup_entry *)calloc(1, sizeof(struct fixup_entry)); - if (fe == NULL) - return (NULL); - fe->next = a->fixup_list; - a->fixup_list = fe; - fe->fixup = 0; - fe->name = _wcsdup(pathname); - fe->fflags_set = 0; - return (fe); -} - -/* - * Returns a fixup structure for the current entry. - */ -static struct fixup_entry * -current_fixup(struct archive_write_disk *a, const wchar_t *pathname) -{ - if (a->current_fixup == NULL) - a->current_fixup = new_fixup(a, pathname); - return (a->current_fixup); -} - -/* - * TODO: The deep-directory support bypasses this; disable deep directory - * support if we're doing symlink checks. - */ -/* - * TODO: Someday, integrate this with the deep dir support; they both - * scan the path and both can be optimized by comparing against other - * recent paths. - */ -static int -check_symlinks(struct archive_write_disk *a) -{ - wchar_t *pn, *p; - wchar_t c; - int r; - BY_HANDLE_FILE_INFORMATION st; - mode_t st_mode; - - /* - * Guard against symlink tricks. Reject any archive entry whose - * destination would be altered by a symlink. - */ - /* Whatever we checked last time doesn't need to be re-checked. */ - pn = a->name; - p = a->path_safe.s; - while ((*pn != '\0') && (*p == *pn)) - ++p, ++pn; - /* Skip leading backslashes */ - while (*pn == '\\') - ++pn; - c = pn[0]; - /* Keep going until we've checked the entire name. */ - while (pn[0] != '\0' && (pn[0] != '\\' || pn[1] != '\0')) { - /* Skip the next path element. */ - while (*pn != '\0' && *pn != '\\') - ++pn; - c = pn[0]; - pn[0] = '\0'; - /* Check that we haven't hit a symlink. */ - r = file_information(a, a->name, &st, &st_mode, 1); - if (r != 0) { - /* We've hit a dir that doesn't exist; stop now. */ - if (errno == ENOENT) - break; - } else if (S_ISLNK(st_mode)) { - if (c == '\0') { - /* - * Last element is a file or directory symlink. - * Remove it so we can overwrite it with the - * item being extracted. - */ - if (a->flags & - ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS) { - (void)clear_nochange_fflags(a); - } - if (st.dwFileAttributes & - FILE_ATTRIBUTE_DIRECTORY) { - r = disk_rmdir(a->name); - } else { - r = disk_unlink(a->name); - } - if (r) { - archive_set_error(&a->archive, errno, - "Could not remove symlink %ls", - a->name); - pn[0] = c; - return (ARCHIVE_FAILED); - } - a->pst = NULL; - /* - * Even if we did remove it, a warning - * is in order. The warning is silly, - * though, if we're just replacing one - * symlink with another symlink. - */ - if (!S_ISLNK(a->mode)) { - archive_set_error(&a->archive, 0, - "Removing symlink %ls", - a->name); - } - /* Symlink gone. No more problem! */ - pn[0] = c; - return (0); - } else if (a->flags & ARCHIVE_EXTRACT_UNLINK) { - /* User asked us to remove problems. */ - if (a->flags & - ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS) { - (void)clear_nochange_fflags(a); - } - if (st.dwFileAttributes & - FILE_ATTRIBUTE_DIRECTORY) { - r = disk_rmdir(a->name); - } else { - r = disk_unlink(a->name); - } - if (r != 0) { - archive_set_error(&a->archive, 0, - "Cannot remove intervening " - "symlink %ls", a->name); - pn[0] = c; - return (ARCHIVE_FAILED); - } - a->pst = NULL; - } else { - archive_set_error(&a->archive, 0, - "Cannot extract through symlink %ls", - a->name); - pn[0] = c; - return (ARCHIVE_FAILED); - } - } - if (!c) - break; - pn[0] = c; - pn++; - } - pn[0] = c; - /* We've checked and/or cleaned the whole path, so remember it. */ - archive_wstrcpy(&a->path_safe, a->name); - return (ARCHIVE_OK); -} - -static int -guidword(wchar_t *p, int n) -{ - int i; - - for (i = 0; i < n; i++) { - if ((*p >= L'0' && *p <= L'9') || - (*p >= L'a' && *p <= L'f') || - (*p >= L'A' && *p <= L'F')) - p++; - else - return (-1); - } - return (0); -} - -/* - * Canonicalize the pathname. In particular, this strips duplicate - * '\' characters, '.' elements, and trailing '\'. It also raises an - * error for an empty path, a trailing '..' or (if _SECURE_NODOTDOT is - * set) any '..' in the path. - */ -static int -cleanup_pathname(struct archive_write_disk *a, wchar_t *name) -{ - wchar_t *dest, *src, *p, *top; - wchar_t separator = L'\0'; - - p = name; - if (*p == L'\0') { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Invalid empty pathname"); - return (ARCHIVE_FAILED); - } - - /* Replace '/' by '\' */ - for (; *p != L'\0'; p++) { - if (*p == L'/') - *p = L'\\'; - } - p = name; - - /* Skip leading "\\.\" or "\\?\" or "\\?\UNC\" or - * "\\?\Volume{GUID}\" - * (absolute path prefixes used by Windows API) */ - if (p[0] == L'\\' && p[1] == L'\\' && - (p[2] == L'.' || p[2] == L'?') && p[3] == L'\\') - { - /* A path begin with "\\?\UNC\" */ - if (p[2] == L'?' && - (p[4] == L'U' || p[4] == L'u') && - (p[5] == L'N' || p[5] == L'n') && - (p[6] == L'C' || p[6] == L'c') && - p[7] == L'\\') - p += 8; - /* A path begin with "\\?\Volume{GUID}\" */ - else if (p[2] == L'?' && - (p[4] == L'V' || p[4] == L'v') && - (p[5] == L'O' || p[5] == L'o') && - (p[6] == L'L' || p[6] == L'l') && - (p[7] == L'U' || p[7] == L'u') && - (p[8] == L'M' || p[8] == L'm') && - (p[9] == L'E' || p[9] == L'e') && - p[10] == L'{') { - if (guidword(p+11, 8) == 0 && p[19] == L'-' && - guidword(p+20, 4) == 0 && p[24] == L'-' && - guidword(p+25, 4) == 0 && p[29] == L'-' && - guidword(p+30, 4) == 0 && p[34] == L'-' && - guidword(p+35, 12) == 0 && p[47] == L'}' && - p[48] == L'\\') - p += 49; - else - p += 4; - /* A path begin with "\\.\PhysicalDriveX" */ - } else if (p[2] == L'.' && - (p[4] == L'P' || p[4] == L'p') && - (p[5] == L'H' || p[5] == L'h') && - (p[6] == L'Y' || p[6] == L'y') && - (p[7] == L'S' || p[7] == L's') && - (p[8] == L'I' || p[8] == L'i') && - (p[9] == L'C' || p[9] == L'c') && - (p[9] == L'A' || p[9] == L'a') && - (p[9] == L'L' || p[9] == L'l') && - (p[9] == L'D' || p[9] == L'd') && - (p[9] == L'R' || p[9] == L'r') && - (p[9] == L'I' || p[9] == L'i') && - (p[9] == L'V' || p[9] == L'v') && - (p[9] == L'E' || p[9] == L'e') && - (p[10] >= L'0' && p[10] <= L'9') && - p[11] == L'\0') { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Path is a physical drive name"); - return (ARCHIVE_FAILED); - } else - p += 4; - /* Network drive path like "\\\\file" */ - } else if (p[0] == L'\\' && p[1] == L'\\') { - p += 2; - } - - /* Skip leading drive letter from archives created - * on Windows. */ - if (((p[0] >= L'a' && p[0] <= L'z') || - (p[0] >= L'A' && p[0] <= L'Z')) && - p[1] == L':') { - if (p[2] == L'\0') { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Path is a drive name"); - return (ARCHIVE_FAILED); - } - if (p[2] == L'\\') - p += 2; - } - - top = dest = src = p; - /* Rewrite the path name if its character is a unusable. */ - for (; *p != L'\0'; p++) { - if (*p == L':' || *p == L'*' || *p == L'?' || *p == L'"' || - *p == L'<' || *p == L'>' || *p == L'|') - *p = L'_'; - } - /* Skip leading '\'. */ - if (*src == L'\\') - separator = *src++; - - /* Scan the pathname one element at a time. */ - for (;;) { - /* src points to first char after '\' */ - if (src[0] == L'\0') { - break; - } else if (src[0] == L'\\') { - /* Found '\\'('//'), ignore second one. */ - src++; - continue; - } else if (src[0] == L'.') { - if (src[1] == L'\0') { - /* Ignore trailing '.' */ - break; - } else if (src[1] == L'\\') { - /* Skip '.\'. */ - src += 2; - continue; - } else if (src[1] == L'.') { - if (src[2] == L'\\' || src[2] == L'\0') { - /* Conditionally warn about '..' */ - if (a->flags & - ARCHIVE_EXTRACT_SECURE_NODOTDOT) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Path contains '..'"); - return (ARCHIVE_FAILED); - } - } - /* - * Note: Under no circumstances do we - * remove '..' elements. In - * particular, restoring - * '\foo\..\bar\' should create the - * 'foo' dir as a side-effect. - */ - } - } - - /* Copy current element, including leading '\'. */ - if (separator) - *dest++ = L'\\'; - while (*src != L'\0' && *src != L'\\') { - *dest++ = *src++; - } - - if (*src == L'\0') - break; - - /* Skip '\' separator. */ - separator = *src++; - } - /* - * We've just copied zero or more path elements, not including the - * final '\'. - */ - if (dest == top) { - /* - * Nothing got copied. The path must have been something - * like '.' or '\' or './' or '/././././/./'. - */ - if (separator) - *dest++ = L'\\'; - else - *dest++ = L'.'; - } - /* Terminate the result. */ - *dest = L'\0'; - return (ARCHIVE_OK); -} - -/* - * Create the parent directory of the specified path, assuming path - * is already in mutable storage. - */ -static int -create_parent_dir(struct archive_write_disk *a, wchar_t *path) -{ - wchar_t *slash; - int r; - - /* Remove tail element to obtain parent name. */ - slash = wcsrchr(path, L'\\'); - if (slash == NULL) - return (ARCHIVE_OK); - *slash = L'\0'; - r = create_dir(a, path); - *slash = L'\\'; - return (r); -} - -/* - * Create the specified dir, recursing to create parents as necessary. - * - * Returns ARCHIVE_OK if the path exists when we're done here. - * Otherwise, returns ARCHIVE_FAILED. - * Assumes path is in mutable storage; path is unchanged on exit. - */ -static int -create_dir(struct archive_write_disk *a, wchar_t *path) -{ - BY_HANDLE_FILE_INFORMATION st; - struct fixup_entry *le; - wchar_t *slash, *base, *full; - mode_t mode_final, mode, st_mode; - int r; - - /* Check for special names and just skip them. */ - slash = wcsrchr(path, L'\\'); - if (slash == NULL) - base = path; - else - base = slash + 1; - - if (base[0] == L'\0' || - (base[0] == L'.' && base[1] == L'\0') || - (base[0] == L'.' && base[1] == L'.' && base[2] == L'\0')) { - /* Don't bother trying to create null path, '.', or '..'. */ - if (slash != NULL) { - *slash = L'\0'; - r = create_dir(a, path); - *slash = L'\\'; - return (r); - } - return (ARCHIVE_OK); - } - - /* - * Yes, this should be stat() and not lstat(). Using lstat() - * here loses the ability to extract through symlinks. Also note - * that this should not use the a->st cache. - */ - if (file_information(a, path, &st, &st_mode, 0) == 0) { - if (S_ISDIR(st_mode)) - return (ARCHIVE_OK); - if ((a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) { - archive_set_error(&a->archive, EEXIST, - "Can't create directory '%ls'", path); - return (ARCHIVE_FAILED); - } - if (disk_unlink(path) != 0) { - archive_set_error(&a->archive, errno, - "Can't create directory '%ls': " - "Conflicting file cannot be removed", - path); - return (ARCHIVE_FAILED); - } - } else if (errno != ENOENT && errno != ENOTDIR) { - /* Stat failed? */ - archive_set_error(&a->archive, errno, - "Can't test directory '%ls'", path); - return (ARCHIVE_FAILED); - } else if (slash != NULL) { - *slash = '\0'; - r = create_dir(a, path); - *slash = '\\'; - if (r != ARCHIVE_OK) - return (r); - } - - /* - * Mode we want for the final restored directory. Per POSIX, - * implicitly-created dirs must be created obeying the umask. - * There's no mention whether this is different for privileged - * restores (which the rest of this code handles by pretending - * umask=0). I've chosen here to always obey the user's umask for - * implicit dirs, even if _EXTRACT_PERM was specified. - */ - mode_final = DEFAULT_DIR_MODE & ~a->user_umask; - /* Mode we want on disk during the restore process. */ - mode = mode_final; - mode |= MINIMUM_DIR_MODE; - mode &= MAXIMUM_DIR_MODE; - /* - * Apply __la_win_permissive_name_w to path in order to - * remove '../' path string. - */ - full = __la_win_permissive_name_w(path); - if (full == NULL) - errno = EINVAL; - else if (CreateDirectoryW(full, NULL) != 0) { - if (mode != mode_final) { - le = new_fixup(a, path); - le->fixup |=TODO_MODE_BASE; - le->mode = mode_final; - } - free(full); - return (ARCHIVE_OK); - } else { - la_dosmaperr(GetLastError()); - } - free(full); - - /* - * Without the following check, a/b/../b/c/d fails at the - * second visit to 'b', so 'd' can't be created. Note that we - * don't add it to the fixup list here, as it's already been - * added. - */ - if (file_information(a, path, &st, &st_mode, 0) == 0 && - S_ISDIR(st_mode)) - return (ARCHIVE_OK); - - archive_set_error(&a->archive, errno, "Failed to create dir '%ls'", - path); - return (ARCHIVE_FAILED); -} - -/* - * Note: Although we can skip setting the user id if the desired user - * id matches the current user, we cannot skip setting the group, as - * many systems set the gid based on the containing directory. So - * we have to perform a chown syscall if we want to set the SGID - * bit. (The alternative is to stat() and then possibly chown(); it's - * more efficient to skip the stat() and just always chown().) Note - * that a successful chown() here clears the TODO_SGID_CHECK bit, which - * allows set_mode to skip the stat() check for the GID. - */ -static int -set_ownership(struct archive_write_disk *a) -{ -/* unfortunately, on win32 there is no 'root' user with uid 0, - so we just have to try the chown and see if it works */ - - /* If we know we can't change it, don't bother trying. */ - if (a->user_uid != 0 && a->user_uid != a->uid) { - archive_set_error(&a->archive, errno, - "Can't set UID=%jd", (intmax_t)a->uid); - return (ARCHIVE_WARN); - } - - archive_set_error(&a->archive, errno, - "Can't set user=%jd/group=%jd for %ls", - (intmax_t)a->uid, (intmax_t)a->gid, a->name); - return (ARCHIVE_WARN); -} - -static int -set_times(struct archive_write_disk *a, - HANDLE h, int mode, const wchar_t *name, - time_t atime, long atime_nanos, - time_t birthtime, long birthtime_nanos, - time_t mtime, long mtime_nanos, - time_t ctime_sec, long ctime_nanos) -{ -#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000) -#define WINTIME(sec, nsec) ((Int32x32To64(sec, 10000000) + EPOC_TIME)\ - + (((nsec)/1000)*10)) - - HANDLE hw = 0; - ULARGE_INTEGER wintm; - FILETIME *pfbtime; - FILETIME fatime, fbtime, fmtime; - - (void)ctime_sec; /* UNUSED */ - (void)ctime_nanos; /* UNUSED */ - - if (h != INVALID_HANDLE_VALUE) { - hw = NULL; - } else { - wchar_t *ws; -# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */ - CREATEFILE2_EXTENDED_PARAMETERS createExParams; -#endif - - if (S_ISLNK(mode)) - return (ARCHIVE_OK); - ws = __la_win_permissive_name_w(name); - if (ws == NULL) - goto settimes_failed; -# if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */ - ZeroMemory(&createExParams, sizeof(createExParams)); - createExParams.dwSize = sizeof(createExParams); - createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS; - hw = CreateFile2(ws, FILE_WRITE_ATTRIBUTES, 0, - OPEN_EXISTING, &createExParams); -#else - hw = CreateFileW(ws, FILE_WRITE_ATTRIBUTES, - 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); -#endif - free(ws); - if (hw == INVALID_HANDLE_VALUE) - goto settimes_failed; - h = hw; - } - - wintm.QuadPart = WINTIME(atime, atime_nanos); - fatime.dwLowDateTime = wintm.LowPart; - fatime.dwHighDateTime = wintm.HighPart; - wintm.QuadPart = WINTIME(mtime, mtime_nanos); - fmtime.dwLowDateTime = wintm.LowPart; - fmtime.dwHighDateTime = wintm.HighPart; - /* - * SetFileTime() supports birthtime. - */ - if (birthtime > 0 || birthtime_nanos > 0) { - wintm.QuadPart = WINTIME(birthtime, birthtime_nanos); - fbtime.dwLowDateTime = wintm.LowPart; - fbtime.dwHighDateTime = wintm.HighPart; - pfbtime = &fbtime; - } else - pfbtime = NULL; - if (SetFileTime(h, pfbtime, &fatime, &fmtime) == 0) - goto settimes_failed; - CloseHandle(hw); - return (ARCHIVE_OK); - -settimes_failed: - CloseHandle(hw); - archive_set_error(&a->archive, EINVAL, "Can't restore time"); - return (ARCHIVE_WARN); -} - -static int -set_times_from_entry(struct archive_write_disk *a) -{ - time_t atime, birthtime, mtime, ctime_sec; - long atime_nsec, birthtime_nsec, mtime_nsec, ctime_nsec; - - /* Suitable defaults. */ - atime = birthtime = mtime = ctime_sec = a->start_time; - atime_nsec = birthtime_nsec = mtime_nsec = ctime_nsec = 0; - - /* If no time was provided, we're done. */ - if (!archive_entry_atime_is_set(a->entry) - && !archive_entry_birthtime_is_set(a->entry) - && !archive_entry_mtime_is_set(a->entry)) - return (ARCHIVE_OK); - - if (archive_entry_atime_is_set(a->entry)) { - atime = archive_entry_atime(a->entry); - atime_nsec = archive_entry_atime_nsec(a->entry); - } - if (archive_entry_birthtime_is_set(a->entry)) { - birthtime = archive_entry_birthtime(a->entry); - birthtime_nsec = archive_entry_birthtime_nsec(a->entry); - } - if (archive_entry_mtime_is_set(a->entry)) { - mtime = archive_entry_mtime(a->entry); - mtime_nsec = archive_entry_mtime_nsec(a->entry); - } - if (archive_entry_ctime_is_set(a->entry)) { - ctime_sec = archive_entry_ctime(a->entry); - ctime_nsec = archive_entry_ctime_nsec(a->entry); - } - - return set_times(a, a->fh, a->mode, a->name, - atime, atime_nsec, - birthtime, birthtime_nsec, - mtime, mtime_nsec, - ctime_sec, ctime_nsec); -} - -static int -set_mode(struct archive_write_disk *a, int mode) -{ - int r = ARCHIVE_OK; - mode &= 07777; /* Strip off file type bits. */ - - if (a->todo & TODO_SGID_CHECK) { - /* - * If we don't know the GID is right, we must stat() - * to verify it. We can't just check the GID of this - * process, since systems sometimes set GID from - * the enclosing dir or based on ACLs. - */ - if ((r = lazy_stat(a)) != ARCHIVE_OK) - return (r); - if (0 != a->gid) { - mode &= ~ S_ISGID; - } - /* While we're here, double-check the UID. */ - if (0 != a->uid - && (a->todo & TODO_SUID)) { - mode &= ~ S_ISUID; - } - a->todo &= ~TODO_SGID_CHECK; - a->todo &= ~TODO_SUID_CHECK; - } else if (a->todo & TODO_SUID_CHECK) { - /* - * If we don't know the UID is right, we can just check - * the user, since all systems set the file UID from - * the process UID. - */ - if (a->user_uid != a->uid) { - mode &= ~ S_ISUID; - } - a->todo &= ~TODO_SUID_CHECK; - } - - if (S_ISLNK(a->mode)) { -#ifdef HAVE_LCHMOD - /* - * If this is a symlink, use lchmod(). If the - * platform doesn't support lchmod(), just skip it. A - * platform that doesn't provide a way to set - * permissions on symlinks probably ignores - * permissions on symlinks, so a failure here has no - * impact. - */ - if (lchmod(a->name, mode) != 0) { - archive_set_error(&a->archive, errno, - "Can't set permissions to 0%o", (int)mode); - r = ARCHIVE_WARN; - } -#endif - } else if (!S_ISDIR(a->mode)) { - /* - * If it's not a symlink and not a dir, then use - * fchmod() or chmod(), depending on whether we have - * an fd. Dirs get their perms set during the - * post-extract fixup, which is handled elsewhere. - */ -#ifdef HAVE_FCHMOD - if (a->fd >= 0) { - if (fchmod(a->fd, mode) != 0) { - archive_set_error(&a->archive, errno, - "Can't set permissions to 0%o", (int)mode); - r = ARCHIVE_WARN; - } - } else -#endif - /* If this platform lacks fchmod(), then - * we'll just use chmod(). */ - if (la_chmod(a->name, mode) != 0) { - archive_set_error(&a->archive, errno, - "Can't set permissions to 0%o", (int)mode); - r = ARCHIVE_WARN; - } - } - return (r); -} - -static int set_fflags_platform(const wchar_t *name, unsigned long fflags_set, - unsigned long fflags_clear) -{ - DWORD oldflags, newflags; - wchar_t *fullname; - - const DWORD settable_flags = - FILE_ATTRIBUTE_ARCHIVE | - FILE_ATTRIBUTE_HIDDEN | - FILE_ATTRIBUTE_NORMAL | - FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | - FILE_ATTRIBUTE_OFFLINE | - FILE_ATTRIBUTE_READONLY | - FILE_ATTRIBUTE_SYSTEM | - FILE_ATTRIBUTE_TEMPORARY; - - oldflags = GetFileAttributesW(name); - if (oldflags == (DWORD)-1 && - GetLastError() == ERROR_INVALID_NAME) { - fullname = __la_win_permissive_name_w(name); - oldflags = GetFileAttributesW(fullname); - } - if (oldflags == (DWORD)-1) { - la_dosmaperr(GetLastError()); - return (ARCHIVE_WARN); - } - newflags = ((oldflags & ~fflags_clear) | fflags_set) & settable_flags; - if(SetFileAttributesW(name, newflags) == 0) - return (ARCHIVE_WARN); - return (ARCHIVE_OK); -} - -static int -clear_nochange_fflags(struct archive_write_disk *a) -{ - return (set_fflags_platform(a->name, 0, FILE_ATTRIBUTE_READONLY)); -} - -static int -set_fflags(struct archive_write_disk *a) -{ - unsigned long set, clear; - - if (a->todo & TODO_FFLAGS) { - archive_entry_fflags(a->entry, &set, &clear); - if (set == 0 && clear == 0) - return (ARCHIVE_OK); - return (set_fflags_platform(a->name, set, clear)); - - } - return (ARCHIVE_OK); -} - -/* Default empty function body to satisfy mainline code. */ -static int -set_acls(struct archive_write_disk *a, HANDLE h, const wchar_t *name, - struct archive_acl *acl) -{ - (void)a; /* UNUSED */ - (void)h; /* UNUSED */ - (void)name; /* UNUSED */ - (void)acl; /* UNUSED */ - return (ARCHIVE_OK); -} - -/* - * Restore extended attributes - stub implementation for unsupported systems - */ -static int -set_xattrs(struct archive_write_disk *a) -{ - static int warning_done = 0; - - /* If there aren't any extended attributes, then it's okay not - * to extract them, otherwise, issue a single warning. */ - if (archive_entry_xattr_count(a->entry) != 0 && !warning_done) { - warning_done = 1; - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Cannot restore extended attributes on this system"); - return (ARCHIVE_WARN); - } - /* Warning was already emitted; suppress further warnings. */ - return (ARCHIVE_OK); -} - -static void -fileTimeToUtc(const FILETIME *filetime, time_t *t, long *ns) -{ - ULARGE_INTEGER utc; - - utc.HighPart = filetime->dwHighDateTime; - utc.LowPart = filetime->dwLowDateTime; - if (utc.QuadPart >= EPOC_TIME) { - utc.QuadPart -= EPOC_TIME; - /* milli seconds base */ - *t = (time_t)(utc.QuadPart / 10000000); - /* nano seconds base */ - *ns = (long)(utc.QuadPart % 10000000) * 100; - } else { - *t = 0; - *ns = 0; - } -} -/* - * Test if file on disk is older than entry. - */ -static int -older(BY_HANDLE_FILE_INFORMATION *st, struct archive_entry *entry) -{ - time_t sec; - long nsec; - - fileTimeToUtc(&st->ftLastWriteTime, &sec, &nsec); - /* First, test the seconds and return if we have a definite answer. */ - /* Definitely older. */ - if (sec < archive_entry_mtime(entry)) - return (1); - /* Definitely younger. */ - if (sec > archive_entry_mtime(entry)) - return (0); - if (nsec < archive_entry_mtime_nsec(entry)) - return (1); - /* Same age or newer, so not older. */ - return (0); -} - -#endif /* _WIN32 && !__CYGWIN__ */ - diff --git a/thirdparty/libarchive/libarchive/archive_write_filter.3 b/thirdparty/libarchive/libarchive/archive_write_filter.3 deleted file mode 100644 index c83eb77b6..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_filter.3 +++ /dev/null @@ -1,134 +0,0 @@ -.\" Copyright (c) 2003-2011 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd August 14, 2014 -.Dt ARCHIVE_WRITE_FILTER 3 -.Os -.Sh NAME -.Nm archive_write_add_filter_b64encode , -.Nm archive_write_add_filter_by_name , -.Nm archive_write_add_filter_bzip2 , -.Nm archive_write_add_filter_compress , -.Nm archive_write_add_filter_grzip , -.Nm archive_write_add_filter_gzip , -.Nm archive_write_add_filter_lrzip , -.Nm archive_write_add_filter_lz4 , -.Nm archive_write_add_filter_lzip , -.Nm archive_write_add_filter_lzma , -.Nm archive_write_add_filter_lzop , -.Nm archive_write_add_filter_none , -.Nm archive_write_add_filter_program , -.Nm archive_write_add_filter_uuencode , -.Nm archive_write_add_filter_xz , -.Nm archive_write_add_filter_zstd -.Nd functions enabling output filters -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive.h -.Ft int -.Fn archive_write_add_filter_b64encode "struct archive *" -.Ft int -.Fn archive_write_add_filter_bzip2 "struct archive *" -.Ft int -.Fn archive_write_add_filter_compress "struct archive *" -.Ft int -.Fn archive_write_add_filter_grzip "struct archive *" -.Ft int -.Fn archive_write_add_filter_gzip "struct archive *" -.Ft int -.Fn archive_write_add_filter_lrzip "struct archive *" -.Ft int -.Fn archive_write_add_filter_lz4 "struct archive *" -.Ft int -.Fn archive_write_add_filter_lzip "struct archive *" -.Ft int -.Fn archive_write_add_filter_lzma "struct archive *" -.Ft int -.Fn archive_write_add_filter_lzop "struct archive *" -.Ft int -.Fn archive_write_add_filter_none "struct archive *" -.Ft int -.Fn archive_write_add_filter_program "struct archive *" "const char * cmd" -.Ft int -.Fn archive_write_add_filter_uuencode "struct archive *" -.Ft int -.Fn archive_write_add_filter_xz "struct archive *" -.Ft int -.Fn archive_write_add_filter_zstd "struct archive *" -.Sh DESCRIPTION -.Bl -tag -width indent -.It Xo -.Fn archive_write_add_filter_bzip2 , -.Fn archive_write_add_filter_compress , -.Fn archive_write_add_filter_grzip , -.Fn archive_write_add_filter_gzip , -.Fn archive_write_add_filter_lrzip , -.Fn archive_write_add_filter_lz4 , -.Fn archive_write_add_filter_lzip , -.Fn archive_write_add_filter_lzma , -.Fn archive_write_add_filter_lzop , -.Fn archive_write_add_filter_xz , -.Fn archive_write_add_filter_zstd , -.Xc -The resulting archive will be compressed as specified. -Note that the compressed output is always properly blocked. -.It Xo -.Fn archive_write_add_filter_b64encode , -.Fn archive_write_add_filter_uuencode , -.Xc -The output will be encoded as specified. -The encoded output is always properly blocked. -.It Fn archive_write_add_filter_none -This is never necessary. -It is provided only for backwards compatibility. -.It Fn archive_write_add_filter_program -The archive will be fed into the specified compression program. -The output of that program is blocked and written to the client -write callbacks. -.El -.Sh RETURN VALUES -These functions return -.Cm ARCHIVE_OK -on success, or -.Cm ARCHIVE_FATAL . -.\" -.Sh ERRORS -Detailed error codes and textual descriptions are available from the -.Fn archive_errno -and -.Fn archive_error_string -functions. -.\" -.Sh SEE ALSO -.Xr tar 1 , -.Xr archive_write 3 , -.Xr archive_write_format 3 , -.Xr archive_write_set_options 3 , -.Xr libarchive 3 , -.Xr cpio 5 , -.Xr mtree 5 , -.Xr tar 5 diff --git a/thirdparty/libarchive/libarchive/archive_write_finish_entry.3 b/thirdparty/libarchive/libarchive/archive_write_finish_entry.3 deleted file mode 100644 index 5797e16a6..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_finish_entry.3 +++ /dev/null @@ -1,79 +0,0 @@ -.\" Copyright (c) 2003-2011 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd February 28, 2017 -.Dt ARCHIVE_WRITE_FINISH_ENTRY 3 -.Os -.Sh NAME -.Nm archive_write_finish_entry -.Nd functions for creating archives -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive.h -.Ft int -.Fn archive_write_finish_entry "struct archive *" -.Sh DESCRIPTION -Close out the entry just written. -In particular, this writes out the final padding required by some formats. -Ordinarily, clients never need to call this, as it -is called automatically by -.Fn archive_write_header -and -.Fn archive_write_close -as needed. -For -.Tn archive_write_disk -handles, this flushes pending file attribute changes like modification time. -.\" .Sh EXAMPLE -.Sh RETURN VALUES -This function returns -.Cm ARCHIVE_OK -on success, or one of several non-zero -error codes for errors. -Specific error codes include: -.Cm ARCHIVE_RETRY -for operations that might succeed if retried, -.Cm ARCHIVE_WARN -for unusual conditions that do not prevent further operations, and -.Cm ARCHIVE_FATAL -for serious errors that make remaining operations impossible. -.\" -.Sh ERRORS -Detailed error codes and textual descriptions are available from the -.Fn archive_errno -and -.Fn archive_error_string -functions. -.\" -.Sh SEE ALSO -.Xr tar 1 , -.Xr archive_write_data 3 , -.Xr archive_write_set_options 3 , -.Xr libarchive 3 , -.Xr cpio 5 , -.Xr mtree 5 , -.Xr tar 5 diff --git a/thirdparty/libarchive/libarchive/archive_write_format.3 b/thirdparty/libarchive/libarchive/archive_write_format.3 deleted file mode 100644 index 653089f77..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_format.3 +++ /dev/null @@ -1,187 +0,0 @@ -.\" Copyright (c) 2003-2011 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd February 14, 2013 -.Dt ARCHIVE_WRITE_FORMAT 3 -.Os -.Sh NAME -.Nm archive_write_set_format , -.Nm archive_write_set_format_7zip , -.Nm archive_write_set_format_ar , -.Nm archive_write_set_format_ar_bsd , -.Nm archive_write_set_format_ar_svr4 , -.Nm archive_write_set_format_by_name , -.Nm archive_write_set_format_cpio , -.Nm archive_write_set_format_cpio_bin , -.Nm archive_write_set_format_cpio_newc , -.Nm archive_write_set_format_cpio_odc , -.Nm archive_write_set_format_cpio_pwb , -.Nm archive_write_set_format_filter_by_ext , -.Nm archive_write_set_format_filter_by_ext_def , -.Nm archive_write_set_format_gnutar , -.Nm archive_write_set_format_iso9660 , -.Nm archive_write_set_format_mtree , -.Nm archive_write_set_format_mtree_classic , -.Nm archive_write_set_format_mtree_default , -.Nm archive_write_set_format_pax , -.Nm archive_write_set_format_pax_restricted , -.Nm archive_write_set_format_raw , -.Nm archive_write_set_format_shar , -.Nm archive_write_set_format_shar_dump , -.Nm archive_write_set_format_ustar , -.Nm archive_write_set_format_v7tar , -.Nm archive_write_set_format_warc , -.Nm archive_write_set_format_xar , -.Nm archive_write_set_format_zip -.Nd functions for creating archives -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive.h -.Ft int -.Fn archive_write_set_format "struct archive *" "int code" -.Ft int -.Fn archive_write_set_format_7zip "struct archive *" -.Ft int -.Fn archive_write_set_format_ar "struct archive *" -.Ft int -.Fn archive_write_set_format_ar_bsd "struct archive *" -.Ft int -.Fn archive_write_set_format_ar_svr4 "struct archive *" -.Ft int -.Fn archive_write_set_format_by_name "struct archive *" "const char *name" -.Ft int -.Fn archive_write_set_format_cpio "struct archive *" -.Ft int -.Fn archive_write_set_format_cpio_bin "struct archive *" -.Ft int -.Fn archive_write_set_format_cpio_newc "struct archive *" -.Ft int -.Fn archive_write_set_format_cpio_odc "struct archive *" -.Ft int -.Fn archive_write_set_format_cpio_pwb "struct archive *" -.Ft int -.Fn archive_write_set_format_filter_by_ext "struct archive *" "const char *filename" -.Ft int -.Fn archive_write_set_format_filter_by_ext_def "struct archive *" "const char *filename" "const char *def_ext" -.Ft int -.Fn archive_write_set_format_gnutar "struct archive *" -.Ft int -.Fn archive_write_set_format_iso9660 "struct archive *" -.Ft int -.Fn archive_write_set_format_mtree "struct archive *" -.Ft int -.Fn archive_write_set_format_pax "struct archive *" -.Ft int -.Fn archive_write_set_format_pax_restricted "struct archive *" -.Ft int -.Fn archive_write_set_format_raw "struct archive *" -.Ft int -.Fn archive_write_set_format_shar "struct archive *" -.Ft int -.Fn archive_write_set_format_shar_dump "struct archive *" -.Ft int -.Fn archive_write_set_format_ustar "struct archive *" -.Ft int -.Fn archive_write_set_format_v7tar "struct archive *" -.Ft int -.Fn archive_write_set_format_warc "struct archive *" -.Ft int -.Fn archive_write_set_format_xar "struct archive *" -.Ft int -.Fn archive_write_set_format_zip "struct archive *" -.Sh DESCRIPTION -These functions set the format that will be used for the archive. -.Pp -The library can write a variety of common archive formats. -.Bl -tag -width indent -.It Fn archive_write_set_format -Sets the format based on the format code (see -.Pa archive.h -for the full list of format codes). -In particular, this can be used in conjunction with -.Fn archive_format -to create a new archive with the same format as an existing archive. -.It Fn archive_write_set_format_by_name -Sets the corresponding format based on the common name. -.It Xo -.Fn archive_write_set_format_filter_by_ext -.Fn archive_write_set_format_filter_by_ext_def -.Xc -Sets both filters and format based on the output filename. -Supported extensions: .7z, .zip, .jar, .cpio, .iso, .a, .ar, .tar, .tgz, .tar.gz, .tar.bz2, .tar.xz -.It Xo -.Fn archive_write_set_format_7zip -.Fn archive_write_set_format_ar_bsd -.Fn archive_write_set_format_ar_svr4 -.Fn archive_write_set_format_cpio -.Fn archive_write_set_format_cpio_bin -.Fn archive_write_set_format_cpio_newc -.Fn archive_write_set_format_cpio_odc -.Fn archive_write_set_format_cpio_pwb -.Fn archive_write_set_format_gnutar -.Fn archive_write_set_format_iso9660 -.Fn archive_write_set_format_mtree -.Fn archive_write_set_format_mtree_classic -.Fn archive_write_set_format_pax -.Fn archive_write_set_format_pax_restricted -.Fn archive_write_set_format_raw -.Fn archive_write_set_format_shar -.Fn archive_write_set_format_shar_dump -.Fn archive_write_set_format_ustar -.Fn archive_write_set_format_v7tar -.Fn archive_write_set_format_warc -.Fn archive_write_set_format_xar -.Fn archive_write_set_format_zip -.Xc -Set the format as specified. -More details on the formats supported by libarchive can be found in the -.Xr libarchive-formats 5 -manual page. -.El -.\" -.Sh RETURN VALUES -These functions return -.Cm ARCHIVE_OK -on success, or -.Cm ARCHIVE_FATAL . -.\" -.Sh ERRORS -Detailed error codes and textual descriptions are available from the -.Fn archive_errno -and -.Fn archive_error_string -functions. -.\" -.Sh SEE ALSO -.Xr tar 1 , -.Xr archive_write 3 , -.Xr archive_write_set_options 3 , -.Xr libarchive 3 , -.Xr cpio 5 , -.Xr libarchive-formats 5 , -.Xr mtree 5 , -.Xr tar 5 diff --git a/thirdparty/libarchive/libarchive/archive_write_free.3 b/thirdparty/libarchive/libarchive/archive_write_free.3 deleted file mode 100644 index 5210e2a63..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_free.3 +++ /dev/null @@ -1,96 +0,0 @@ -.\" Copyright (c) 2003-2011 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd February 2, 2012 -.Dt ARCHIVE_WRITE_FREE 3 -.Os -.Sh NAME -.Nm archive_write_fail , -.Nm archive_write_close , -.Nm archive_write_finish , -.Nm archive_write_free -.Nd functions for creating archives -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive.h -.Ft int -.Fn archive_write_fail "struct archive *" -.Ft int -.Fn archive_write_close "struct archive *" -.Ft int -.Fn archive_write_finish "struct archive *" -.Ft int -.Fn archive_write_free "struct archive *" -.Sh DESCRIPTION -.Bl -tag -width indent -.It Fn archive_write_fail -Always returns -.Cm ARCHIVE_FATAL . -This marks the archive object as being unusable; -after calling this function, the only call that can succeed is -.Fn archive_write_free -to release the resources. -This can be used to speed recovery when the archive creation -must be aborted. -Note that the created archive is likely to be malformed in this case; -.It Fn archive_write_close -Complete the archive and invoke the close callback. -.It Fn archive_write_finish -This is a deprecated synonym for -.Fn archive_write_free . -.It Fn archive_write_free -Invokes -.Fn archive_write_close -if necessary, then releases all resources. -If you need detailed information about -.Fn archive_write_close -failures, you should be careful to call it separately, as -you cannot obtain error information after -.Fn archive_write_free -returns. -.El -.\" .Sh EXAMPLE -.Sh RETURN VALUES -These functions return -.Cm ARCHIVE_OK -on success, or -.Cm ARCHIVE_FATAL . -.\" -.Sh ERRORS -Detailed error codes and textual descriptions are available from the -.Fn archive_errno -and -.Fn archive_error_string -functions. -.\" -.Sh SEE ALSO -.Xr tar 1 , -.Xr archive_write_set_options 3 , -.Xr libarchive 3 , -.Xr cpio 5 , -.Xr mtree 5 , -.Xr tar 5 diff --git a/thirdparty/libarchive/libarchive/archive_write_header.3 b/thirdparty/libarchive/libarchive/archive_write_header.3 deleted file mode 100644 index 2217b1871..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_header.3 +++ /dev/null @@ -1,73 +0,0 @@ -.\" Copyright (c) 2003-2011 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd February 2, 2012 -.Dt ARCHIVE_WRITE_HEADER 3 -.Os -.Sh NAME -.Nm archive_write_header -.Nd functions for creating archives -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive.h -.Ft int -.Fn archive_write_header "struct archive *" "struct archive_entry *" -.Sh DESCRIPTION -Build and write a header using the data in the provided -.Tn struct archive_entry -structure. -See -.Xr archive_entry 3 -for information on creating and populating -.Tn struct archive_entry -objects. -.\" .Sh EXAMPLE -.Sh RETURN VALUES -This function returns -.Cm ARCHIVE_OK -on success, or one of the following on error: -.Cm ARCHIVE_RETRY -for operations that might succeed if retried, -.Cm ARCHIVE_WARN -for unusual conditions that do not prevent further operations, and -.Cm ARCHIVE_FATAL -for serious errors that make remaining operations impossible. -.\" -.Sh ERRORS -Detailed error codes and textual descriptions are available from the -.Fn archive_errno -and -.Fn archive_error_string -functions. -.\" -.Sh SEE ALSO -.Xr tar 1 , -.Xr archive_write_set_options 3 , -.Xr libarchive 3 , -.Xr cpio 5 , -.Xr mtree 5 , -.Xr tar 5 diff --git a/thirdparty/libarchive/libarchive/archive_write_new.3 b/thirdparty/libarchive/libarchive/archive_write_new.3 deleted file mode 100644 index 788cbb855..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_new.3 +++ /dev/null @@ -1,58 +0,0 @@ -.\" Copyright (c) 2003-2011 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd February 2, 2012 -.Dt ARCHIVE_WRITE_NEW 3 -.Os -.Sh NAME -.Nm archive_write_new -.Nd functions for creating archives -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive.h -.Ft struct archive * -.Fn archive_write_new "void" -.Sh DESCRIPTION -Allocates and initializes a -.Tn struct archive -object suitable for writing a tar archive. -.Dv NULL -is returned on error. -.Pp -A complete description of the -.Tn struct archive -object can be found in the overview manual page for -.Xr libarchive 3 . -.\" .Sh ERRORS -.Sh SEE ALSO -.Xr tar 1 , -.Xr archive_write 3 , -.Xr archive_write_set_options 3 , -.Xr libarchive 3 , -.Xr cpio 5 , -.Xr mtree 5 , -.Xr tar 5 diff --git a/thirdparty/libarchive/libarchive/archive_write_open.3 b/thirdparty/libarchive/libarchive/archive_write_open.3 deleted file mode 100644 index 6bceb964f..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_open.3 +++ /dev/null @@ -1,272 +0,0 @@ -.\" Copyright (c) 2003-2011 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd November 12, 2020 -.Dt ARCHIVE_WRITE_OPEN 3 -.Os -.Sh NAME -.Nm archive_write_open , -.Nm archive_write_open2 , -.Nm archive_write_open_fd , -.Nm archive_write_open_FILE , -.Nm archive_write_open_filename , -.Nm archive_write_open_memory -.Nd functions for creating archives -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive.h -.Ft int -.Fo archive_write_open -.Fa "struct archive *" -.Fa "void *client_data" -.Fa "archive_open_callback *" -.Fa "archive_write_callback *" -.Fa "archive_close_callback *" -.Fc -.Ft int -.Fo archive_write_open2 -.Fa "struct archive *" -.Fa "void *client_data" -.Fa "archive_open_callback *" -.Fa "archive_write_callback *" -.Fa "archive_close_callback *" -.Fa "archive_free_callback *" -.Fc -.Ft int -.Fn archive_write_open_fd "struct archive *" "int fd" -.Ft int -.Fn archive_write_open_FILE "struct archive *" "FILE *file" -.Ft int -.Fn archive_write_open_filename "struct archive *" "const char *filename" -.Ft int -.Fo archive_write_open_memory -.Fa "struct archive *" -.Fa "void *buffer" -.Fa "size_t bufferSize" -.Fa "size_t *outUsed" -.Fc -.Sh DESCRIPTION -.Bl -tag -width indent -.It Fn archive_write_open -Freeze the settings, open the archive, and prepare for writing entries. -This is the most generic form of this function, which accepts -pointers to three callback functions which will be invoked by -the compression layer to write the constructed archive. -This does not alter the default archive padding. -.It Fn archive_write_open2 -Same as -.Fn archive_write_open -with an additional fourth free callback. This function should be preferred to -.Fn archive_write_open . -.It Fn archive_write_open_fd -A convenience form of -.Fn archive_write_open -that accepts a file descriptor. -The -.Fn archive_write_open_fd -function is safe for use with tape drives or other -block-oriented devices. -.It Fn archive_write_open_FILE -A convenience form of -.Fn archive_write_open -that accepts a -.Ft "FILE *" -pointer. -Note that -.Fn archive_write_open_FILE -is not safe for writing to tape drives or other devices -that require correct blocking. -.It Fn archive_write_open_file -A deprecated synonym for -.Fn archive_write_open_filename . -.It Fn archive_write_open_filename -A convenience form of -.Fn archive_write_open -that accepts a filename. -A NULL argument indicates that the output should be written to standard output; -an argument of -.Dq - -will open a file with that name. -If you have not invoked -.Fn archive_write_set_bytes_in_last_block , -then -.Fn archive_write_open_filename -will adjust the last-block padding depending on the file: -it will enable padding when writing to standard output or -to a character or block device node, it will disable padding otherwise. -You can override this by manually invoking -.Fn archive_write_set_bytes_in_last_block -before calling -.Fn archive_write_open2 . -The -.Fn archive_write_open_filename -function is safe for use with tape drives or other -block-oriented devices. -.It Fn archive_write_open_memory -A convenience form of -.Fn archive_write_open2 -that accepts a pointer to a block of memory that will receive -the archive. -The final -.Ft "size_t *" -argument points to a variable that will be updated -after each write to reflect how much of the buffer -is currently in use. -You should be careful to ensure that this variable -remains allocated until after the archive is -closed. -This function will disable padding unless you -have specifically set the block size. -.El -More information about the -.Va struct archive -object and the overall design of the library can be found in the -.Xr libarchive 3 -overview. -.Pp -Note that the convenience forms above vary in how -they block the output. -See -.Xr archive_write_blocksize 3 -if you need to control the block size used for writes -or the end-of-file padding behavior. -.\" -.Sh CLIENT CALLBACKS -To use this library, you will need to define and register -callback functions that will be invoked to write data to the -resulting archive. -These functions are registered by calling -.Fn archive_write_open2 : -.Bl -item -offset indent -.It -.Ft typedef int -.Fn archive_open_callback "struct archive *" "void *client_data" -.El -.Pp -The open callback is invoked by -.Fn archive_write_open . -It should return -.Cm ARCHIVE_OK -if the underlying file or data source is successfully -opened. -If the open fails, it should call -.Fn archive_set_error -to register an error code and message and return -.Cm ARCHIVE_FATAL . -Please note that if open fails, close is not called and resources must be -freed inside the open callback or with the free callback. -.Bl -item -offset indent -.It -.Ft typedef la_ssize_t -.Fo archive_write_callback -.Fa "struct archive *" -.Fa "void *client_data" -.Fa "const void *buffer" -.Fa "size_t length" -.Fc -.El -.Pp -The write callback is invoked whenever the library -needs to write raw bytes to the archive. -For correct blocking, each call to the write callback function -should translate into a single -.Xr write 2 -system call. -This is especially critical when writing archives to tape drives. -On success, the write callback should return the -number of bytes actually written. -On error, the callback should invoke -.Fn archive_set_error -to register an error code and message and return -1. -.Bl -item -offset indent -.It -.Ft typedef int -.Fn archive_close_callback "struct archive *" "void *client_data" -.El -.Pp -The close callback is invoked by archive_close when -the archive processing is complete. If the open callback fails, the close -callback is not invoked. -The callback should return -.Cm ARCHIVE_OK -on success. -On failure, the callback should invoke -.Fn archive_set_error -to register an error code and message and -return -.Cm ARCHIVE_FATAL . -.Bl -item -offset indent -.It -.Ft typedef int -.Fn archive_free_callback "struct archive *" "void *client_data" -.El -.Pp -The free callback is always invoked on archive_free. -The return code of this callback is not processed. -.Pp -Note that if the client-provided write callback function -returns a non-zero value, that error will be propagated back to the caller -through whatever API function resulted in that call, which -may include -.Fn archive_write_header , -.Fn archive_write_data , -.Fn archive_write_close , -.Fn archive_write_finish , -or -.Fn archive_write_free . -The client callback can call -.Fn archive_set_error -to provide values that can then be retrieved by -.Fn archive_errno -and -.Fn archive_error_string . -.\" .Sh EXAMPLE -.Sh RETURN VALUES -These functions return -.Cm ARCHIVE_OK -on success, or -.Cm ARCHIVE_FATAL . -.\" -.Sh ERRORS -Detailed error codes and textual descriptions are available from the -.Fn archive_errno -and -.Fn archive_error_string -functions. -.\" -.Sh SEE ALSO -.Xr tar 1 , -.Xr archive_write 3 , -.Xr archive_write_blocksize 3 , -.Xr archive_write_filter 3 , -.Xr archive_write_format 3 , -.Xr archive_write_new 3 , -.Xr archive_write_set_options 3 , -.Xr libarchive 3 , -.Xr cpio 5 , -.Xr mtree 5 , -.Xr tar 5 diff --git a/thirdparty/libarchive/libarchive/archive_write_open_fd.c b/thirdparty/libarchive/libarchive/archive_write_open_fd.c deleted file mode 100644 index b8d491faa..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_open_fd.c +++ /dev/null @@ -1,146 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_open_fd.c 201093 2009-12-28 02:28:44Z kientzle $"); - -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif -#ifdef HAVE_IO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif - -#include "archive.h" - -struct write_fd_data { - int fd; -}; - -static int file_free(struct archive *, void *); -static int file_open(struct archive *, void *); -static ssize_t file_write(struct archive *, void *, const void *buff, size_t); - -int -archive_write_open_fd(struct archive *a, int fd) -{ - struct write_fd_data *mine; - - mine = (struct write_fd_data *)malloc(sizeof(*mine)); - if (mine == NULL) { - archive_set_error(a, ENOMEM, "No memory"); - return (ARCHIVE_FATAL); - } - mine->fd = fd; -#if defined(__CYGWIN__) || defined(_WIN32) - setmode(mine->fd, O_BINARY); -#endif - return (archive_write_open2(a, mine, - file_open, file_write, NULL, file_free)); -} - -static int -file_open(struct archive *a, void *client_data) -{ - struct write_fd_data *mine; - struct stat st; - - mine = (struct write_fd_data *)client_data; - - if (fstat(mine->fd, &st) != 0) { - archive_set_error(a, errno, "Couldn't stat fd %d", mine->fd); - return (ARCHIVE_FATAL); - } - - /* - * If this is a regular file, don't add it to itself. - */ - if (S_ISREG(st.st_mode)) - archive_write_set_skip_file(a, st.st_dev, st.st_ino); - - /* - * If client hasn't explicitly set the last block handling, - * then set it here. - */ - if (archive_write_get_bytes_in_last_block(a) < 0) { - /* If the output is a block or character device, fifo, - * or stdout, pad the last block, otherwise leave it - * unpadded. */ - if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode) || - S_ISFIFO(st.st_mode) || (mine->fd == 1)) - /* Last block will be fully padded. */ - archive_write_set_bytes_in_last_block(a, 0); - else - archive_write_set_bytes_in_last_block(a, 1); - } - - return (ARCHIVE_OK); -} - -static ssize_t -file_write(struct archive *a, void *client_data, const void *buff, size_t length) -{ - struct write_fd_data *mine; - ssize_t bytesWritten; - - mine = (struct write_fd_data *)client_data; - for (;;) { - bytesWritten = write(mine->fd, buff, length); - if (bytesWritten <= 0) { - if (errno == EINTR) - continue; - archive_set_error(a, errno, "Write error"); - return (-1); - } - return (bytesWritten); - } -} - -static int -file_free(struct archive *a, void *client_data) -{ - struct write_fd_data *mine = (struct write_fd_data *)client_data; - - (void)a; /* UNUSED */ - if (mine == NULL) - return (ARCHIVE_OK); - free(mine); - return (ARCHIVE_OK); -} diff --git a/thirdparty/libarchive/libarchive/archive_write_open_file.c b/thirdparty/libarchive/libarchive/archive_write_open_file.c deleted file mode 100644 index bf5b55a67..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_open_file.c +++ /dev/null @@ -1,111 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_open_file.c,v 1.19 2007/01/09 08:05:56 kientzle Exp $"); - -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif - -#include "archive.h" - -struct write_FILE_data { - FILE *f; -}; - -static int file_free(struct archive *, void *); -static int file_open(struct archive *, void *); -static ssize_t file_write(struct archive *, void *, const void *buff, size_t); - -int -archive_write_open_FILE(struct archive *a, FILE *f) -{ - struct write_FILE_data *mine; - - mine = (struct write_FILE_data *)malloc(sizeof(*mine)); - if (mine == NULL) { - archive_set_error(a, ENOMEM, "No memory"); - return (ARCHIVE_FATAL); - } - mine->f = f; - return (archive_write_open2(a, mine, file_open, file_write, - NULL, file_free)); -} - -static int -file_open(struct archive *a, void *client_data) -{ - (void)a; /* UNUSED */ - (void)client_data; /* UNUSED */ - - return (ARCHIVE_OK); -} - -static ssize_t -file_write(struct archive *a, void *client_data, const void *buff, size_t length) -{ - struct write_FILE_data *mine; - size_t bytesWritten; - - mine = client_data; - for (;;) { - bytesWritten = fwrite(buff, 1, length, mine->f); - if (bytesWritten <= 0) { - if (errno == EINTR) - continue; - archive_set_error(a, errno, "Write error"); - return (-1); - } - return (bytesWritten); - } -} - -static int -file_free(struct archive *a, void *client_data) -{ - struct write_FILE_data *mine = client_data; - - (void)a; /* UNUSED */ - if (mine == NULL) - return (ARCHIVE_OK); - free(mine); - return (ARCHIVE_OK); -} diff --git a/thirdparty/libarchive/libarchive/archive_write_open_filename.c b/thirdparty/libarchive/libarchive/archive_write_open_filename.c deleted file mode 100644 index 9ceefb19b..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_open_filename.c +++ /dev/null @@ -1,270 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_open_filename.c 191165 2009-04-17 00:39:35Z kientzle $"); - -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif - -#include "archive.h" -#include "archive_private.h" -#include "archive_string.h" - -#ifndef O_BINARY -#define O_BINARY 0 -#endif -#ifndef O_CLOEXEC -#define O_CLOEXEC 0 -#endif - -struct write_file_data { - int fd; - struct archive_mstring filename; -}; - -static int file_close(struct archive *, void *); -static int file_free(struct archive *, void *); -static int file_open(struct archive *, void *); -static ssize_t file_write(struct archive *, void *, const void *buff, size_t); -static int open_filename(struct archive *, int, const void *); - -int -archive_write_open_file(struct archive *a, const char *filename) -{ - return (archive_write_open_filename(a, filename)); -} - -int -archive_write_open_filename(struct archive *a, const char *filename) -{ - - if (filename == NULL || filename[0] == '\0') - return (archive_write_open_fd(a, 1)); - - return (open_filename(a, 1, filename)); -} - -int -archive_write_open_filename_w(struct archive *a, const wchar_t *filename) -{ - - if (filename == NULL || filename[0] == L'\0') - return (archive_write_open_fd(a, 1)); - - return (open_filename(a, 0, filename)); -} - -static int -open_filename(struct archive *a, int mbs_fn, const void *filename) -{ - struct write_file_data *mine; - int r; - - mine = (struct write_file_data *)calloc(1, sizeof(*mine)); - if (mine == NULL) { - archive_set_error(a, ENOMEM, "No memory"); - return (ARCHIVE_FATAL); - } - if (mbs_fn) - r = archive_mstring_copy_mbs(&mine->filename, filename); - else - r = archive_mstring_copy_wcs(&mine->filename, filename); - if (r < 0) { - if (errno == ENOMEM) { - archive_set_error(a, ENOMEM, "No memory"); - return (ARCHIVE_FATAL); - } - if (mbs_fn) - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Can't convert '%s' to WCS", - (const char *)filename); - else - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Can't convert '%S' to MBS", - (const wchar_t *)filename); - return (ARCHIVE_FAILED); - } - mine->fd = -1; - return (archive_write_open2(a, mine, - file_open, file_write, file_close, file_free)); -} - -static int -file_open(struct archive *a, void *client_data) -{ - int flags; - struct write_file_data *mine; - struct stat st; -#if defined(_WIN32) && !defined(__CYGWIN__) - wchar_t *fullpath; -#endif - const wchar_t *wcs; - const char *mbs; - - mine = (struct write_file_data *)client_data; - flags = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_CLOEXEC; - - /* - * Open the file. - */ - mbs = NULL; wcs = NULL; -#if defined(_WIN32) && !defined(__CYGWIN__) - if (archive_mstring_get_wcs(a, &mine->filename, &wcs) != 0) { - if (errno == ENOMEM) - archive_set_error(a, errno, "No memory"); - else { - archive_mstring_get_mbs(a, &mine->filename, &mbs); - archive_set_error(a, errno, - "Can't convert '%s' to WCS", mbs); - } - return (ARCHIVE_FATAL); - } - fullpath = __la_win_permissive_name_w(wcs); - if (fullpath != NULL) { - mine->fd = _wopen(fullpath, flags, 0666); - free(fullpath); - } else - mine->fd = _wopen(wcs, flags, 0666); -#else - if (archive_mstring_get_mbs(a, &mine->filename, &mbs) != 0) { - if (errno == ENOMEM) - archive_set_error(a, errno, "No memory"); - else { - archive_mstring_get_wcs(a, &mine->filename, &wcs); - archive_set_error(a, errno, - "Can't convert '%S' to MBS", wcs); - } - return (ARCHIVE_FATAL); - } - mine->fd = open(mbs, flags, 0666); - __archive_ensure_cloexec_flag(mine->fd); -#endif - if (mine->fd < 0) { - if (mbs != NULL) - archive_set_error(a, errno, "Failed to open '%s'", mbs); - else - archive_set_error(a, errno, "Failed to open '%S'", wcs); - return (ARCHIVE_FATAL); - } - - if (fstat(mine->fd, &st) != 0) { - if (mbs != NULL) - archive_set_error(a, errno, "Couldn't stat '%s'", mbs); - else - archive_set_error(a, errno, "Couldn't stat '%S'", wcs); - return (ARCHIVE_FATAL); - } - - /* - * Set up default last block handling. - */ - if (archive_write_get_bytes_in_last_block(a) < 0) { - if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode) || - S_ISFIFO(st.st_mode)) - /* Pad last block when writing to device or FIFO. */ - archive_write_set_bytes_in_last_block(a, 0); - else - /* Don't pad last block otherwise. */ - archive_write_set_bytes_in_last_block(a, 1); - } - - /* - * If the output file is a regular file, don't add it to - * itself. If it's a device file, it's okay to add the device - * entry to the output archive. - */ - if (S_ISREG(st.st_mode)) - archive_write_set_skip_file(a, st.st_dev, st.st_ino); - - return (ARCHIVE_OK); -} - -static ssize_t -file_write(struct archive *a, void *client_data, const void *buff, - size_t length) -{ - struct write_file_data *mine; - ssize_t bytesWritten; - - mine = (struct write_file_data *)client_data; - for (;;) { - bytesWritten = write(mine->fd, buff, length); - if (bytesWritten <= 0) { - if (errno == EINTR) - continue; - archive_set_error(a, errno, "Write error"); - return (-1); - } - return (bytesWritten); - } -} - -static int -file_close(struct archive *a, void *client_data) -{ - struct write_file_data *mine = (struct write_file_data *)client_data; - - (void)a; /* UNUSED */ - - if (mine == NULL) - return (ARCHIVE_FATAL); - - if (mine->fd >= 0) - close(mine->fd); - - return (ARCHIVE_OK); -} - -static int -file_free(struct archive *a, void *client_data) -{ - struct write_file_data *mine = (struct write_file_data *)client_data; - - (void)a; /* UNUSED */ - - if (mine == NULL) - return (ARCHIVE_OK); - - archive_mstring_clean(&mine->filename); - free(mine); - return (ARCHIVE_OK); -} diff --git a/thirdparty/libarchive/libarchive/archive_write_open_memory.c b/thirdparty/libarchive/libarchive/archive_write_open_memory.c deleted file mode 100644 index a8a0b817f..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_open_memory.c +++ /dev/null @@ -1,115 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_open_memory.c,v 1.3 2007/01/09 08:05:56 kientzle Exp $"); - -#include -#include -#include - -#include "archive.h" - -struct write_memory_data { - size_t used; - size_t size; - size_t * client_size; - unsigned char * buff; -}; - -static int memory_write_free(struct archive *, void *); -static int memory_write_open(struct archive *, void *); -static ssize_t memory_write(struct archive *, void *, const void *buff, size_t); - -/* - * Client provides a pointer to a block of memory to receive - * the data. The 'size' param both tells us the size of the - * client buffer and lets us tell the client the final size. - */ -int -archive_write_open_memory(struct archive *a, void *buff, size_t buffSize, size_t *used) -{ - struct write_memory_data *mine; - - mine = (struct write_memory_data *)calloc(1, sizeof(*mine)); - if (mine == NULL) { - archive_set_error(a, ENOMEM, "No memory"); - return (ARCHIVE_FATAL); - } - mine->buff = buff; - mine->size = buffSize; - mine->client_size = used; - return (archive_write_open2(a, mine, - memory_write_open, memory_write, NULL, memory_write_free)); -} - -static int -memory_write_open(struct archive *a, void *client_data) -{ - struct write_memory_data *mine; - mine = client_data; - mine->used = 0; - if (mine->client_size != NULL) - *mine->client_size = mine->used; - /* Disable padding if it hasn't been set explicitly. */ - if (-1 == archive_write_get_bytes_in_last_block(a)) - archive_write_set_bytes_in_last_block(a, 1); - return (ARCHIVE_OK); -} - -/* - * Copy the data into the client buffer. - * Note that we update mine->client_size on every write. - * In particular, this means the client can follow exactly - * how much has been written into their buffer at any time. - */ -static ssize_t -memory_write(struct archive *a, void *client_data, const void *buff, size_t length) -{ - struct write_memory_data *mine; - mine = client_data; - - if (mine->used + length > mine->size) { - archive_set_error(a, ENOMEM, "Buffer exhausted"); - return (ARCHIVE_FATAL); - } - memcpy(mine->buff + mine->used, buff, length); - mine->used += length; - if (mine->client_size != NULL) - *mine->client_size = mine->used; - return (length); -} - -static int -memory_write_free(struct archive *a, void *client_data) -{ - struct write_memory_data *mine; - (void)a; /* UNUSED */ - mine = client_data; - if (mine == NULL) - return (ARCHIVE_OK); - free(mine); - return (ARCHIVE_OK); -} diff --git a/thirdparty/libarchive/libarchive/archive_write_private.h b/thirdparty/libarchive/libarchive/archive_write_private.h deleted file mode 100644 index 6522e6521..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_private.h +++ /dev/null @@ -1,166 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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: head/lib/libarchive/archive_write_private.h 201155 2009-12-29 05:20:12Z kientzle $ - */ - -#ifndef ARCHIVE_WRITE_PRIVATE_H_INCLUDED -#define ARCHIVE_WRITE_PRIVATE_H_INCLUDED - -#ifndef __LIBARCHIVE_BUILD -#ifndef __LIBARCHIVE_TEST -#error This header is only to be used internally to libarchive. -#endif -#endif - -#include "archive.h" -#include "archive_string.h" -#include "archive_private.h" - -#define ARCHIVE_WRITE_FILTER_STATE_NEW 1U -#define ARCHIVE_WRITE_FILTER_STATE_OPEN 2U -#define ARCHIVE_WRITE_FILTER_STATE_CLOSED 4U -#define ARCHIVE_WRITE_FILTER_STATE_FATAL 0x8000U - -struct archive_write; - -struct archive_write_filter { - int64_t bytes_written; - struct archive *archive; /* Associated archive. */ - struct archive_write_filter *next_filter; /* Who I write to. */ - int (*options)(struct archive_write_filter *, - const char *key, const char *value); - int (*open)(struct archive_write_filter *); - int (*write)(struct archive_write_filter *, const void *, size_t); - int (*flush)(struct archive_write_filter *); - int (*close)(struct archive_write_filter *); - int (*free)(struct archive_write_filter *); - void *data; - const char *name; - int code; - int bytes_per_block; - int bytes_in_last_block; - int state; -}; - -#if ARCHIVE_VERSION < 4000000 -void __archive_write_filters_free(struct archive *); -#endif - -struct archive_write_filter *__archive_write_allocate_filter(struct archive *); - -int __archive_write_output(struct archive_write *, const void *, size_t); -int __archive_write_nulls(struct archive_write *, size_t); -int __archive_write_filter(struct archive_write_filter *, const void *, size_t); - -struct archive_write { - struct archive archive; - - /* Dev/ino of the archive being written. */ - int skip_file_set; - int64_t skip_file_dev; - int64_t skip_file_ino; - - /* Utility: Pointer to a block of nulls. */ - const unsigned char *nulls; - size_t null_length; - - /* Callbacks to open/read/write/close archive stream. */ - archive_open_callback *client_opener; - archive_write_callback *client_writer; - archive_close_callback *client_closer; - archive_free_callback *client_freer; - void *client_data; - - /* - * Blocking information. Note that bytes_in_last_block is - * misleadingly named; I should find a better name. These - * control the final output from all compressors, including - * compression_none. - */ - int bytes_per_block; - int bytes_in_last_block; - - /* - * First and last write filters in the pipeline. - */ - struct archive_write_filter *filter_first; - struct archive_write_filter *filter_last; - - /* - * Pointers to format-specific functions for writing. They're - * initialized by archive_write_set_format_XXX() calls. - */ - void *format_data; - const char *format_name; - int (*format_init)(struct archive_write *); - int (*format_options)(struct archive_write *, - const char *key, const char *value); - int (*format_finish_entry)(struct archive_write *); - int (*format_write_header)(struct archive_write *, - struct archive_entry *); - ssize_t (*format_write_data)(struct archive_write *, - const void *buff, size_t); - int (*format_close)(struct archive_write *); - int (*format_free)(struct archive_write *); - - - /* - * Encryption passphrase. - */ - char *passphrase; - archive_passphrase_callback *passphrase_callback; - void *passphrase_client_data; -}; - -/* - * Utility function to format a USTAR header into a buffer. If - * "strict" is set, this tries to create the absolutely most portable - * version of a ustar header. If "strict" is set to 0, then it will - * relax certain requirements. - * - * Generally, format-specific declarations don't belong in this - * header; this is a rare example of a function that is shared by - * two very similar formats (ustar and pax). - */ -int -__archive_write_format_header_ustar(struct archive_write *, char buff[512], - struct archive_entry *, int tartype, int strict, - struct archive_string_conv *); - -struct archive_write_program_data; -struct archive_write_program_data * __archive_write_program_allocate(const char *program_name); -int __archive_write_program_free(struct archive_write_program_data *); -int __archive_write_program_open(struct archive_write_filter *, - struct archive_write_program_data *, const char *); -int __archive_write_program_close(struct archive_write_filter *, - struct archive_write_program_data *); -int __archive_write_program_write(struct archive_write_filter *, - struct archive_write_program_data *, const void *, size_t); - -/* - * Get a encryption passphrase. - */ -const char * __archive_write_get_passphrase(struct archive_write *a); -#endif diff --git a/thirdparty/libarchive/libarchive/archive_write_set_format.c b/thirdparty/libarchive/libarchive/archive_write_set_format.c deleted file mode 100644 index 1f65fa4a7..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_set_format.c +++ /dev/null @@ -1,125 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format.c 201168 2009-12-29 06:15:32Z kientzle $"); - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#ifdef HAVE_ERRNO_H -#include -#endif - -#include "archive.h" -#include "archive_private.h" -#include "archive_write_set_format_private.h" - -/* A table that maps format codes to functions. */ -static const -struct { int code; int (*setter)(struct archive *); } codes[] = -{ - { ARCHIVE_FORMAT_7ZIP, archive_write_set_format_7zip }, - { ARCHIVE_FORMAT_CPIO, archive_write_set_format_cpio }, - { ARCHIVE_FORMAT_CPIO_BIN_LE, archive_write_set_format_cpio_bin }, - { ARCHIVE_FORMAT_CPIO_PWB, archive_write_set_format_cpio_pwb }, - { ARCHIVE_FORMAT_CPIO_POSIX, archive_write_set_format_cpio_odc }, - { ARCHIVE_FORMAT_CPIO_SVR4_NOCRC, archive_write_set_format_cpio_newc }, - { ARCHIVE_FORMAT_ISO9660, archive_write_set_format_iso9660 }, - { ARCHIVE_FORMAT_MTREE, archive_write_set_format_mtree }, - { ARCHIVE_FORMAT_RAW, archive_write_set_format_raw }, - { ARCHIVE_FORMAT_SHAR, archive_write_set_format_shar }, - { ARCHIVE_FORMAT_SHAR_BASE, archive_write_set_format_shar }, - { ARCHIVE_FORMAT_SHAR_DUMP, archive_write_set_format_shar_dump }, - { ARCHIVE_FORMAT_TAR, archive_write_set_format_pax_restricted }, - { ARCHIVE_FORMAT_TAR_GNUTAR, archive_write_set_format_gnutar }, - { ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE, archive_write_set_format_pax }, - { ARCHIVE_FORMAT_TAR_PAX_RESTRICTED, - archive_write_set_format_pax_restricted }, - { ARCHIVE_FORMAT_TAR_USTAR, archive_write_set_format_ustar }, - { ARCHIVE_FORMAT_WARC, archive_write_set_format_warc }, - { ARCHIVE_FORMAT_XAR, archive_write_set_format_xar }, - { ARCHIVE_FORMAT_ZIP, archive_write_set_format_zip }, - { 0, NULL } -}; - -int -archive_write_set_format(struct archive *a, int code) -{ - int i; - - for (i = 0; codes[i].code != 0; i++) { - if (code == codes[i].code) - return ((codes[i].setter)(a)); - } - - archive_set_error(a, EINVAL, "No such format"); - return (ARCHIVE_FATAL); -} - -void -__archive_write_entry_filetype_unsupported(struct archive *a, - struct archive_entry *entry, const char *format) -{ - const char *name = NULL; - - switch (archive_entry_filetype(entry)) { - /* - * All formats should be able to archive regular files (AE_IFREG) - */ - case AE_IFDIR: - name = "directories"; - break; - case AE_IFLNK: - name = "symbolic links"; - break; - case AE_IFCHR: - name = "character devices"; - break; - case AE_IFBLK: - name = "block devices"; - break; - case AE_IFIFO: - name = "named pipes"; - break; - case AE_IFSOCK: - name = "sockets"; - break; - default: - break; - } - - if (name != NULL) { - archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT, - "%s: %s format cannot archive %s", - archive_entry_pathname(entry), format, name); - } else { - archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT, - "%s: %s format cannot archive files with mode 0%lo", - archive_entry_pathname(entry), format, - (unsigned long)archive_entry_mode(entry)); - } -} diff --git a/thirdparty/libarchive/libarchive/archive_write_set_format_7zip.c b/thirdparty/libarchive/libarchive/archive_write_set_format_7zip.c deleted file mode 100644 index bca48ba9b..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_set_format_7zip.c +++ /dev/null @@ -1,2347 +0,0 @@ -/*- - * Copyright (c) 2011-2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#include -#ifdef HAVE_BZLIB_H -#include -#endif -#if HAVE_LZMA_H -#include -#endif -#ifdef HAVE_ZLIB_H -#include -#endif - -#include "archive.h" -#ifndef HAVE_ZLIB_H -#include "archive_crc32.h" -#endif -#include "archive_endian.h" -#include "archive_entry.h" -#include "archive_entry_locale.h" -#include "archive_ppmd7_private.h" -#include "archive_private.h" -#include "archive_rb.h" -#include "archive_string.h" -#include "archive_write_private.h" -#include "archive_write_set_format_private.h" - -/* - * Codec ID - */ -#define _7Z_COPY 0 -#define _7Z_LZMA1 0x030101 -#define _7Z_LZMA2 0x21 -#define _7Z_DEFLATE 0x040108 -#define _7Z_BZIP2 0x040202 -#define _7Z_PPMD 0x030401 - -/* - * 7-Zip header property IDs. - */ -#define kEnd 0x00 -#define kHeader 0x01 -#define kArchiveProperties 0x02 -#define kAdditionalStreamsInfo 0x03 -#define kMainStreamsInfo 0x04 -#define kFilesInfo 0x05 -#define kPackInfo 0x06 -#define kUnPackInfo 0x07 -#define kSubStreamsInfo 0x08 -#define kSize 0x09 -#define kCRC 0x0A -#define kFolder 0x0B -#define kCodersUnPackSize 0x0C -#define kNumUnPackStream 0x0D -#define kEmptyStream 0x0E -#define kEmptyFile 0x0F -#define kAnti 0x10 -#define kName 0x11 -#define kCTime 0x12 -#define kATime 0x13 -#define kMTime 0x14 -#define kAttributes 0x15 -#define kEncodedHeader 0x17 - -// Check that some windows file attribute constants are defined. -// Reference: https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants -#ifndef FILE_ATTRIBUTE_READONLY -#define FILE_ATTRIBUTE_READONLY 0x00000001 -#endif - -#ifndef FILE_ATTRIBUTE_DIRECTORY -#define FILE_ATTRIBUTE_DIRECTORY 0x00000010 -#endif - -#ifndef FILE_ATTRIBUTE_ARCHIVE -#define FILE_ATTRIBUTE_ARCHIVE 0x00000020 -#endif - -// This value is defined in 7zip with the comment "trick for Unix". -// -// 7z archives created on unix have this bit set in the high 16 bits of -// the attr field along with the unix permissions. -#define FILE_ATTRIBUTE_UNIX_EXTENSION 0x8000 - -enum la_zaction { - ARCHIVE_Z_FINISH, - ARCHIVE_Z_RUN -}; - -/* - * A stream object of universal compressor. - */ -struct la_zstream { - const uint8_t *next_in; - size_t avail_in; - uint64_t total_in; - - uint8_t *next_out; - size_t avail_out; - uint64_t total_out; - - uint32_t prop_size; - uint8_t *props; - - int valid; - void *real_stream; - int (*code) (struct archive *a, - struct la_zstream *lastrm, - enum la_zaction action); - int (*end)(struct archive *a, - struct la_zstream *lastrm); -}; - -#define PPMD7_DEFAULT_ORDER 6 -#define PPMD7_DEFAULT_MEM_SIZE (1 << 24) - -struct ppmd_stream { - int stat; - CPpmd7 ppmd7_context; - CPpmd7z_RangeEnc range_enc; - IByteOut byteout; - uint8_t *buff; - uint8_t *buff_ptr; - uint8_t *buff_end; - size_t buff_bytes; -}; - -struct coder { - unsigned codec; - size_t prop_size; - uint8_t *props; -}; - -struct file { - struct archive_rb_node rbnode; - - struct file *next; - unsigned name_len; - uint8_t *utf16name;/* UTF16-LE name. */ - uint64_t size; - unsigned flg; -#define MTIME_IS_SET (1<<0) -#define ATIME_IS_SET (1<<1) -#define CTIME_IS_SET (1<<2) -#define CRC32_IS_SET (1<<3) -#define HAS_STREAM (1<<4) - - struct { - time_t time; - long time_ns; - } times[3]; -#define MTIME 0 -#define ATIME 1 -#define CTIME 2 - - mode_t mode; - uint32_t crc32; - - unsigned dir:1; -}; - -struct _7zip { - int temp_fd; - uint64_t temp_offset; - - struct file *cur_file; - size_t total_number_entry; - size_t total_number_nonempty_entry; - size_t total_number_empty_entry; - size_t total_number_dir_entry; - size_t total_bytes_entry_name; - size_t total_number_time_defined[3]; - uint64_t total_bytes_compressed; - uint64_t total_bytes_uncompressed; - uint64_t entry_bytes_remaining; - uint32_t entry_crc32; - uint32_t precode_crc32; - uint32_t encoded_crc32; - int crc32flg; -#define PRECODE_CRC32 1 -#define ENCODED_CRC32 2 - - unsigned opt_compression; - int opt_compression_level; - - struct la_zstream stream; - struct coder coder; - - struct archive_string_conv *sconv; - - /* - * Compressed data buffer. - */ - unsigned char wbuff[512 * 20 * 6]; - size_t wbuff_remaining; - - /* - * The list of the file entries which has its contents is used to - * manage struct file objects. - * We use 'next' (a member of struct file) to chain. - */ - struct { - struct file *first; - struct file **last; - } file_list, empty_list; - struct archive_rb_tree rbtree;/* for empty files */ -}; - -static int _7z_options(struct archive_write *, - const char *, const char *); -static int _7z_write_header(struct archive_write *, - struct archive_entry *); -static ssize_t _7z_write_data(struct archive_write *, - const void *, size_t); -static int _7z_finish_entry(struct archive_write *); -static int _7z_close(struct archive_write *); -static int _7z_free(struct archive_write *); -static int file_cmp_node(const struct archive_rb_node *, - const struct archive_rb_node *); -static int file_cmp_key(const struct archive_rb_node *, const void *); -static int file_new(struct archive_write *a, struct archive_entry *, - struct file **); -static void file_free(struct file *); -static void file_register(struct _7zip *, struct file *); -static void file_register_empty(struct _7zip *, struct file *); -static void file_init_register(struct _7zip *); -static void file_init_register_empty(struct _7zip *); -static void file_free_register(struct _7zip *); -static ssize_t compress_out(struct archive_write *, const void *, size_t , - enum la_zaction); -static int compression_init_encoder_copy(struct archive *, - struct la_zstream *); -static int compression_code_copy(struct archive *, - struct la_zstream *, enum la_zaction); -static int compression_end_copy(struct archive *, struct la_zstream *); -static int compression_init_encoder_deflate(struct archive *, - struct la_zstream *, int, int); -#ifdef HAVE_ZLIB_H -static int compression_code_deflate(struct archive *, - struct la_zstream *, enum la_zaction); -static int compression_end_deflate(struct archive *, struct la_zstream *); -#endif -static int compression_init_encoder_bzip2(struct archive *, - struct la_zstream *, int); -#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) -static int compression_code_bzip2(struct archive *, - struct la_zstream *, enum la_zaction); -static int compression_end_bzip2(struct archive *, struct la_zstream *); -#endif -static int compression_init_encoder_lzma1(struct archive *, - struct la_zstream *, int); -static int compression_init_encoder_lzma2(struct archive *, - struct la_zstream *, int); -#if defined(HAVE_LZMA_H) -static int compression_code_lzma(struct archive *, - struct la_zstream *, enum la_zaction); -static int compression_end_lzma(struct archive *, struct la_zstream *); -#endif -static int compression_init_encoder_ppmd(struct archive *, - struct la_zstream *, unsigned, uint32_t); -static int compression_code_ppmd(struct archive *, - struct la_zstream *, enum la_zaction); -static int compression_end_ppmd(struct archive *, struct la_zstream *); -static int _7z_compression_init_encoder(struct archive_write *, unsigned, - int); -static int compression_code(struct archive *, - struct la_zstream *, enum la_zaction); -static int compression_end(struct archive *, - struct la_zstream *); -static int enc_uint64(struct archive_write *, uint64_t); -static int make_header(struct archive_write *, uint64_t, uint64_t, - uint64_t, int, struct coder *); -static int make_streamsInfo(struct archive_write *, uint64_t, uint64_t, - uint64_t, int, struct coder *, int, uint32_t); - -int -archive_write_set_format_7zip(struct archive *_a) -{ - static const struct archive_rb_tree_ops rb_ops = { - file_cmp_node, file_cmp_key - }; - struct archive_write *a = (struct archive_write *)_a; - struct _7zip *zip; - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_set_format_7zip"); - - /* If another format was already registered, unregister it. */ - if (a->format_free != NULL) - (a->format_free)(a); - - zip = calloc(1, sizeof(*zip)); - if (zip == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate 7-Zip data"); - return (ARCHIVE_FATAL); - } - zip->temp_fd = -1; - __archive_rb_tree_init(&(zip->rbtree), &rb_ops); - file_init_register(zip); - file_init_register_empty(zip); - - /* Set default compression type and its level. */ -#if HAVE_LZMA_H - zip->opt_compression = _7Z_LZMA1; -#elif defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) - zip->opt_compression = _7Z_BZIP2; -#elif defined(HAVE_ZLIB_H) - zip->opt_compression = _7Z_DEFLATE; -#else - zip->opt_compression = _7Z_COPY; -#endif - zip->opt_compression_level = 6; - - a->format_data = zip; - - a->format_name = "7zip"; - a->format_options = _7z_options; - a->format_write_header = _7z_write_header; - a->format_write_data = _7z_write_data; - a->format_finish_entry = _7z_finish_entry; - a->format_close = _7z_close; - a->format_free = _7z_free; - a->archive.archive_format = ARCHIVE_FORMAT_7ZIP; - a->archive.archive_format_name = "7zip"; - - return (ARCHIVE_OK); -} - -static int -_7z_options(struct archive_write *a, const char *key, const char *value) -{ - struct _7zip *zip; - - zip = (struct _7zip *)a->format_data; - - if (strcmp(key, "compression") == 0) { - const char *name = NULL; - - if (value == NULL || strcmp(value, "copy") == 0 || - strcmp(value, "COPY") == 0 || - strcmp(value, "store") == 0 || - strcmp(value, "STORE") == 0) - zip->opt_compression = _7Z_COPY; - else if (strcmp(value, "deflate") == 0 || - strcmp(value, "DEFLATE") == 0) -#if HAVE_ZLIB_H - zip->opt_compression = _7Z_DEFLATE; -#else - name = "deflate"; -#endif - else if (strcmp(value, "bzip2") == 0 || - strcmp(value, "BZIP2") == 0) -#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) - zip->opt_compression = _7Z_BZIP2; -#else - name = "bzip2"; -#endif - else if (strcmp(value, "lzma1") == 0 || - strcmp(value, "LZMA1") == 0) -#if HAVE_LZMA_H - zip->opt_compression = _7Z_LZMA1; -#else - name = "lzma1"; -#endif - else if (strcmp(value, "lzma2") == 0 || - strcmp(value, "LZMA2") == 0) -#if HAVE_LZMA_H - zip->opt_compression = _7Z_LZMA2; -#else - name = "lzma2"; -#endif - else if (strcmp(value, "ppmd") == 0 || - strcmp(value, "PPMD") == 0 || - strcmp(value, "PPMd") == 0) - zip->opt_compression = _7Z_PPMD; - else { - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, - "Unknown compression name: `%s'", - value); - return (ARCHIVE_FAILED); - } - if (name != NULL) { - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, - "`%s' compression not supported " - "on this platform", - name); - return (ARCHIVE_FAILED); - } - return (ARCHIVE_OK); - } - if (strcmp(key, "compression-level") == 0) { - if (value == NULL || - !(value[0] >= '0' && value[0] <= '9') || - value[1] != '\0') { - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, - "Illegal value `%s'", - value); - return (ARCHIVE_FAILED); - } - zip->opt_compression_level = value[0] - '0'; - return (ARCHIVE_OK); - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -static int -_7z_write_header(struct archive_write *a, struct archive_entry *entry) -{ - struct _7zip *zip; - struct file *file; - int r; - - zip = (struct _7zip *)a->format_data; - zip->cur_file = NULL; - zip->entry_bytes_remaining = 0; - - if (zip->sconv == NULL) { - zip->sconv = archive_string_conversion_to_charset( - &a->archive, "UTF-16LE", 1); - if (zip->sconv == NULL) - return (ARCHIVE_FATAL); - } - - r = file_new(a, entry, &file); - if (r < ARCHIVE_WARN) { - if (file != NULL) - file_free(file); - return (r); - } - if (file->size == 0 && file->dir) { - if (!__archive_rb_tree_insert_node(&(zip->rbtree), - (struct archive_rb_node *)file)) { - /* We have already had the same file. */ - file_free(file); - return (ARCHIVE_OK); - } - } - - if (file->flg & MTIME_IS_SET) - zip->total_number_time_defined[MTIME]++; - if (file->flg & CTIME_IS_SET) - zip->total_number_time_defined[CTIME]++; - if (file->flg & ATIME_IS_SET) - zip->total_number_time_defined[ATIME]++; - - zip->total_number_entry++; - zip->total_bytes_entry_name += file->name_len + 2; - if (file->size == 0) { - /* Count up the number of empty files. */ - zip->total_number_empty_entry++; - if (file->dir) - zip->total_number_dir_entry++; - else - file_register_empty(zip, file); - return (r); - } - - /* - * Init compression. - */ - if ((zip->total_number_entry - zip->total_number_empty_entry) == 1) { - r = _7z_compression_init_encoder(a, zip->opt_compression, - zip->opt_compression_level); - if (r < 0) { - file_free(file); - return (ARCHIVE_FATAL); - } - } - - /* Register a non-empty file. */ - file_register(zip, file); - - /* - * Set the current file to cur_file to read its contents. - */ - zip->cur_file = file; - - - /* Save a offset of current file in temporary file. */ - zip->entry_bytes_remaining = file->size; - zip->entry_crc32 = 0; - - /* - * Store a symbolic link name as file contents. - */ - if (archive_entry_filetype(entry) == AE_IFLNK) { - ssize_t bytes; - const void *p = (const void *)archive_entry_symlink(entry); - bytes = compress_out(a, p, (size_t)file->size, ARCHIVE_Z_RUN); - if (bytes < 0) - return ((int)bytes); - zip->entry_crc32 = crc32(zip->entry_crc32, p, (unsigned)bytes); - zip->entry_bytes_remaining -= bytes; - } - - return (r); -} - -/* - * Write data to a temporary file. - */ -static int -write_to_temp(struct archive_write *a, const void *buff, size_t s) -{ - struct _7zip *zip; - const unsigned char *p; - ssize_t ws; - - zip = (struct _7zip *)a->format_data; - - /* - * Open a temporary file. - */ - if (zip->temp_fd == -1) { - zip->temp_offset = 0; - zip->temp_fd = __archive_mktemp(NULL); - if (zip->temp_fd < 0) { - archive_set_error(&a->archive, errno, - "Couldn't create temporary file"); - return (ARCHIVE_FATAL); - } - } - - p = (const unsigned char *)buff; - while (s) { - ws = write(zip->temp_fd, p, s); - if (ws < 0) { - archive_set_error(&(a->archive), errno, - "fwrite function failed"); - return (ARCHIVE_FATAL); - } - s -= ws; - p += ws; - zip->temp_offset += ws; - } - return (ARCHIVE_OK); -} - -static ssize_t -compress_out(struct archive_write *a, const void *buff, size_t s, - enum la_zaction run) -{ - struct _7zip *zip = (struct _7zip *)a->format_data; - int r; - - if (run == ARCHIVE_Z_FINISH && zip->stream.total_in == 0 && s == 0) - return (0); - - if ((zip->crc32flg & PRECODE_CRC32) && s) - zip->precode_crc32 = crc32(zip->precode_crc32, buff, - (unsigned)s); - zip->stream.next_in = (const unsigned char *)buff; - zip->stream.avail_in = s; - for (;;) { - /* Compress file data. */ - r = compression_code(&(a->archive), &(zip->stream), run); - if (r != ARCHIVE_OK && r != ARCHIVE_EOF) - return (ARCHIVE_FATAL); - if (zip->stream.avail_out == 0) { - if (write_to_temp(a, zip->wbuff, sizeof(zip->wbuff)) - != ARCHIVE_OK) - return (ARCHIVE_FATAL); - zip->stream.next_out = zip->wbuff; - zip->stream.avail_out = sizeof(zip->wbuff); - if (zip->crc32flg & ENCODED_CRC32) - zip->encoded_crc32 = crc32(zip->encoded_crc32, - zip->wbuff, sizeof(zip->wbuff)); - if (run == ARCHIVE_Z_FINISH && r != ARCHIVE_EOF) - continue; - } - if (zip->stream.avail_in == 0) - break; - } - if (run == ARCHIVE_Z_FINISH) { - uint64_t bytes = sizeof(zip->wbuff) - zip->stream.avail_out; - if (write_to_temp(a, zip->wbuff, (size_t)bytes) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - if ((zip->crc32flg & ENCODED_CRC32) && bytes) - zip->encoded_crc32 = crc32(zip->encoded_crc32, - zip->wbuff, (unsigned)bytes); - } - - return (s); -} - -static ssize_t -_7z_write_data(struct archive_write *a, const void *buff, size_t s) -{ - struct _7zip *zip; - ssize_t bytes; - - zip = (struct _7zip *)a->format_data; - - if (s > zip->entry_bytes_remaining) - s = (size_t)zip->entry_bytes_remaining; - if (s == 0 || zip->cur_file == NULL) - return (0); - bytes = compress_out(a, buff, s, ARCHIVE_Z_RUN); - if (bytes < 0) - return (bytes); - zip->entry_crc32 = crc32(zip->entry_crc32, buff, (unsigned)bytes); - zip->entry_bytes_remaining -= bytes; - return (bytes); -} - -static int -_7z_finish_entry(struct archive_write *a) -{ - struct _7zip *zip; - size_t s; - ssize_t r; - - zip = (struct _7zip *)a->format_data; - if (zip->cur_file == NULL) - return (ARCHIVE_OK); - - while (zip->entry_bytes_remaining > 0) { - s = (size_t)zip->entry_bytes_remaining; - if (s > a->null_length) - s = a->null_length; - r = _7z_write_data(a, a->nulls, s); - if (r < 0) - return ((int)r); - } - zip->total_bytes_compressed += zip->stream.total_in; - zip->total_bytes_uncompressed += zip->stream.total_out; - zip->cur_file->crc32 = zip->entry_crc32; - zip->cur_file = NULL; - - return (ARCHIVE_OK); -} - -static int -flush_wbuff(struct archive_write *a) -{ - struct _7zip *zip; - int r; - size_t s; - - zip = (struct _7zip *)a->format_data; - s = sizeof(zip->wbuff) - zip->wbuff_remaining; - r = __archive_write_output(a, zip->wbuff, s); - if (r != ARCHIVE_OK) - return (r); - zip->wbuff_remaining = sizeof(zip->wbuff); - return (r); -} - -static int -copy_out(struct archive_write *a, uint64_t offset, uint64_t length) -{ - struct _7zip *zip; - int r; - - zip = (struct _7zip *)a->format_data; - if (zip->temp_offset > 0 && - lseek(zip->temp_fd, offset, SEEK_SET) < 0) { - archive_set_error(&(a->archive), errno, "lseek failed"); - return (ARCHIVE_FATAL); - } - while (length) { - size_t rsize; - ssize_t rs; - unsigned char *wb; - - if (length > zip->wbuff_remaining) - rsize = zip->wbuff_remaining; - else - rsize = (size_t)length; - wb = zip->wbuff + (sizeof(zip->wbuff) - zip->wbuff_remaining); - rs = read(zip->temp_fd, wb, rsize); - if (rs < 0) { - archive_set_error(&(a->archive), errno, - "Can't read temporary file(%jd)", - (intmax_t)rs); - return (ARCHIVE_FATAL); - } - if (rs == 0) { - archive_set_error(&(a->archive), 0, - "Truncated 7-Zip archive"); - return (ARCHIVE_FATAL); - } - zip->wbuff_remaining -= rs; - length -= rs; - if (zip->wbuff_remaining == 0) { - r = flush_wbuff(a); - if (r != ARCHIVE_OK) - return (r); - } - } - return (ARCHIVE_OK); -} - -static int -_7z_close(struct archive_write *a) -{ - struct _7zip *zip; - unsigned char *wb; - uint64_t header_offset, header_size, header_unpacksize; - uint64_t length; - uint32_t header_crc32; - int r; - - zip = (struct _7zip *)a->format_data; - - if (zip->total_number_entry > 0) { - struct archive_rb_node *n; - uint64_t data_offset, data_size, data_unpacksize; - unsigned header_compression; - - r = (int)compress_out(a, NULL, 0, ARCHIVE_Z_FINISH); - if (r < 0) - return (r); - data_offset = 0; - data_size = zip->stream.total_out; - data_unpacksize = zip->stream.total_in; - zip->coder.codec = zip->opt_compression; - zip->coder.prop_size = zip->stream.prop_size; - zip->coder.props = zip->stream.props; - zip->stream.prop_size = 0; - zip->stream.props = NULL; - zip->total_number_nonempty_entry = - zip->total_number_entry - zip->total_number_empty_entry; - - /* Connect an empty file list. */ - if (zip->empty_list.first != NULL) { - *zip->file_list.last = zip->empty_list.first; - zip->file_list.last = zip->empty_list.last; - } - /* Connect a directory file list. */ - ARCHIVE_RB_TREE_FOREACH(n, &(zip->rbtree)) { - file_register(zip, (struct file *)n); - } - - /* - * NOTE: 7z command supports just LZMA1, LZMA2 and COPY for - * the compression type for encoding the header. - */ -#if HAVE_LZMA_H - header_compression = _7Z_LZMA1; - if(zip->opt_compression == _7Z_LZMA2 || - zip->opt_compression == _7Z_COPY) - header_compression = zip->opt_compression; - - /* If the stored file is only one, do not encode the header. - * This is the same way 7z command does. */ - if (zip->total_number_entry == 1) - header_compression = _7Z_COPY; -#else - header_compression = _7Z_COPY; -#endif - r = _7z_compression_init_encoder(a, header_compression, - zip->opt_compression_level); - if (r < 0) - return (r); - zip->crc32flg = PRECODE_CRC32; - zip->precode_crc32 = 0; - r = make_header(a, data_offset, data_size, data_unpacksize, - 1, &(zip->coder)); - if (r < 0) - return (r); - r = (int)compress_out(a, NULL, 0, ARCHIVE_Z_FINISH); - if (r < 0) - return (r); - header_offset = data_offset + data_size; - header_size = zip->stream.total_out; - header_crc32 = zip->precode_crc32; - header_unpacksize = zip->stream.total_in; - - if (header_compression != _7Z_COPY) { - /* - * Encode the header in order to reduce the size - * of the archive. - */ - free(zip->coder.props); - zip->coder.codec = header_compression; - zip->coder.prop_size = zip->stream.prop_size; - zip->coder.props = zip->stream.props; - zip->stream.prop_size = 0; - zip->stream.props = NULL; - - r = _7z_compression_init_encoder(a, _7Z_COPY, 0); - if (r < 0) - return (r); - zip->crc32flg = ENCODED_CRC32; - zip->encoded_crc32 = 0; - - /* - * Make EncodedHeader. - */ - r = enc_uint64(a, kEncodedHeader); - if (r < 0) - return (r); - r = make_streamsInfo(a, header_offset, header_size, - header_unpacksize, 1, &(zip->coder), 0, - header_crc32); - if (r < 0) - return (r); - r = (int)compress_out(a, NULL, 0, ARCHIVE_Z_FINISH); - if (r < 0) - return (r); - header_offset = header_offset + header_size; - header_size = zip->stream.total_out; - header_crc32 = zip->encoded_crc32; - } - zip->crc32flg = 0; - } else { - header_offset = header_size = 0; - header_crc32 = 0; - } - - length = zip->temp_offset; - - /* - * Make the zip header on wbuff(write buffer). - */ - wb = zip->wbuff; - zip->wbuff_remaining = sizeof(zip->wbuff); - memcpy(&wb[0], "7z\xBC\xAF\x27\x1C", 6); - wb[6] = 0;/* Major version. */ - wb[7] = 3;/* Minor version. */ - archive_le64enc(&wb[12], header_offset);/* Next Header Offset */ - archive_le64enc(&wb[20], header_size);/* Next Header Size */ - archive_le32enc(&wb[28], header_crc32);/* Next Header CRC */ - archive_le32enc(&wb[8], crc32(0, &wb[12], 20));/* Start Header CRC */ - zip->wbuff_remaining -= 32; - - /* - * Read all file contents and an encoded header from the temporary - * file and write out it. - */ - r = copy_out(a, 0, length); - if (r != ARCHIVE_OK) - return (r); - r = flush_wbuff(a); - return (r); -} - -/* - * Encode 64 bits value into 7-Zip's encoded UINT64 value. - */ -static int -enc_uint64(struct archive_write *a, uint64_t val) -{ - unsigned mask = 0x80; - uint8_t numdata[9]; - int i; - - numdata[0] = 0; - for (i = 1; i < (int)sizeof(numdata); i++) { - if (val < mask) { - numdata[0] |= (uint8_t)val; - break; - } - numdata[i] = (uint8_t)val; - val >>= 8; - numdata[0] |= mask; - mask >>= 1; - } - return ((int)compress_out(a, numdata, i, ARCHIVE_Z_RUN)); -} - -static int -make_substreamsInfo(struct archive_write *a, struct coder *coders) -{ - struct _7zip *zip = (struct _7zip *)a->format_data; - struct file *file; - int r; - - /* - * Make SubStreamsInfo. - */ - r = enc_uint64(a, kSubStreamsInfo); - if (r < 0) - return (r); - - if (zip->total_number_nonempty_entry > 1 && coders->codec != _7Z_COPY) { - /* - * Make NumUnPackStream. - */ - r = enc_uint64(a, kNumUnPackStream); - if (r < 0) - return (r); - - /* Write numUnpackStreams */ - r = enc_uint64(a, zip->total_number_nonempty_entry); - if (r < 0) - return (r); - - /* - * Make kSize. - */ - r = enc_uint64(a, kSize); - if (r < 0) - return (r); - file = zip->file_list.first; - for (;file != NULL; file = file->next) { - if (file->next == NULL || - file->next->size == 0) - break; - r = enc_uint64(a, file->size); - if (r < 0) - return (r); - } - } - - /* - * Make CRC. - */ - r = enc_uint64(a, kCRC); - if (r < 0) - return (r); - - - /* All are defined */ - r = enc_uint64(a, 1); - if (r < 0) - return (r); - file = zip->file_list.first; - for (;file != NULL; file = file->next) { - uint8_t crc[4]; - if (file->size == 0) - break; - archive_le32enc(crc, file->crc32); - r = (int)compress_out(a, crc, 4, ARCHIVE_Z_RUN); - if (r < 0) - return (r); - } - - /* Write End. */ - r = enc_uint64(a, kEnd); - if (r < 0) - return (r); - return (ARCHIVE_OK); -} - -static int -make_streamsInfo(struct archive_write *a, uint64_t offset, uint64_t pack_size, - uint64_t unpack_size, int num_coder, struct coder *coders, int substrm, - uint32_t header_crc) -{ - struct _7zip *zip = (struct _7zip *)a->format_data; - uint8_t codec_buff[8]; - int numFolders, fi; - int codec_size; - int i, r; - - if (coders->codec == _7Z_COPY) - numFolders = (int)zip->total_number_nonempty_entry; - else - numFolders = 1; - - /* - * Make PackInfo. - */ - r = enc_uint64(a, kPackInfo); - if (r < 0) - return (r); - - /* Write PackPos. */ - r = enc_uint64(a, offset); - if (r < 0) - return (r); - - /* Write NumPackStreams. */ - r = enc_uint64(a, numFolders); - if (r < 0) - return (r); - - /* Make Size. */ - r = enc_uint64(a, kSize); - if (r < 0) - return (r); - - if (numFolders > 1) { - struct file *file = zip->file_list.first; - for (;file != NULL; file = file->next) { - if (file->size == 0) - break; - r = enc_uint64(a, file->size); - if (r < 0) - return (r); - } - } else { - /* Write size. */ - r = enc_uint64(a, pack_size); - if (r < 0) - return (r); - } - - r = enc_uint64(a, kEnd); - if (r < 0) - return (r); - - /* - * Make UnPackInfo. - */ - r = enc_uint64(a, kUnPackInfo); - if (r < 0) - return (r); - - /* - * Make Folder. - */ - r = enc_uint64(a, kFolder); - if (r < 0) - return (r); - - /* Write NumFolders. */ - r = enc_uint64(a, numFolders); - if (r < 0) - return (r); - - /* Write External. */ - r = enc_uint64(a, 0); - if (r < 0) - return (r); - - for (fi = 0; fi < numFolders; fi++) { - /* Write NumCoders. */ - r = enc_uint64(a, num_coder); - if (r < 0) - return (r); - - for (i = 0; i < num_coder; i++) { - unsigned codec_id = coders[i].codec; - - /* Write Codec flag. */ - archive_be64enc(codec_buff, codec_id); - for (codec_size = 8; codec_size > 0; codec_size--) { - if (codec_buff[8 - codec_size]) - break; - } - if (codec_size == 0) - codec_size = 1; - if (coders[i].prop_size) - r = enc_uint64(a, codec_size | 0x20); - else - r = enc_uint64(a, codec_size); - if (r < 0) - return (r); - - /* Write Codec ID. */ - codec_size &= 0x0f; - r = (int)compress_out(a, &codec_buff[8-codec_size], - codec_size, ARCHIVE_Z_RUN); - if (r < 0) - return (r); - - if (coders[i].prop_size) { - /* Write Codec property size. */ - r = enc_uint64(a, coders[i].prop_size); - if (r < 0) - return (r); - - /* Write Codec properties. */ - r = (int)compress_out(a, coders[i].props, - coders[i].prop_size, ARCHIVE_Z_RUN); - if (r < 0) - return (r); - } - } - } - - /* - * Make CodersUnPackSize. - */ - r = enc_uint64(a, kCodersUnPackSize); - if (r < 0) - return (r); - - if (numFolders > 1) { - struct file *file = zip->file_list.first; - for (;file != NULL; file = file->next) { - if (file->size == 0) - break; - r = enc_uint64(a, file->size); - if (r < 0) - return (r); - } - - } else { - /* Write UnPackSize. */ - r = enc_uint64(a, unpack_size); - if (r < 0) - return (r); - } - - if (!substrm) { - uint8_t crc[4]; - /* - * Make CRC. - */ - r = enc_uint64(a, kCRC); - if (r < 0) - return (r); - - /* All are defined */ - r = enc_uint64(a, 1); - if (r < 0) - return (r); - archive_le32enc(crc, header_crc); - r = (int)compress_out(a, crc, 4, ARCHIVE_Z_RUN); - if (r < 0) - return (r); - } - - /* Write End. */ - r = enc_uint64(a, kEnd); - if (r < 0) - return (r); - - if (substrm) { - /* - * Make SubStreamsInfo. - */ - r = make_substreamsInfo(a, coders); - if (r < 0) - return (r); - } - - - /* Write End. */ - r = enc_uint64(a, kEnd); - if (r < 0) - return (r); - - return (ARCHIVE_OK); -} - - -#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000) -static uint64_t -utcToFiletime(time_t t, long ns) -{ - uint64_t fileTime; - - fileTime = t; - fileTime *= 10000000; - fileTime += ns / 100; - fileTime += EPOC_TIME; - return (fileTime); -} - -static int -make_time(struct archive_write *a, uint8_t type, unsigned flg, int ti) -{ - uint8_t filetime[8]; - struct _7zip *zip = (struct _7zip *)a->format_data; - struct file *file; - int r; - uint8_t b, mask; - - /* - * Make Time Bools. - */ - if (zip->total_number_time_defined[ti] == zip->total_number_entry) { - /* Write Time Type. */ - r = enc_uint64(a, type); - if (r < 0) - return (r); - /* Write EmptyStream Size. */ - r = enc_uint64(a, 2 + zip->total_number_entry * 8); - if (r < 0) - return (r); - /* All are defined. */ - r = enc_uint64(a, 1); - if (r < 0) - return (r); - } else { - if (zip->total_number_time_defined[ti] == 0) - return (ARCHIVE_OK); - - /* Write Time Type. */ - r = enc_uint64(a, type); - if (r < 0) - return (r); - /* Write EmptyStream Size. */ - r = enc_uint64(a, 2 + ((zip->total_number_entry + 7) >> 3) - + zip->total_number_time_defined[ti] * 8); - if (r < 0) - return (r); - - /* All are not defined. */ - r = enc_uint64(a, 0); - if (r < 0) - return (r); - - b = 0; - mask = 0x80; - file = zip->file_list.first; - for (;file != NULL; file = file->next) { - if (file->flg & flg) - b |= mask; - mask >>= 1; - if (mask == 0) { - r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN); - if (r < 0) - return (r); - mask = 0x80; - b = 0; - } - } - if (mask != 0x80) { - r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN); - if (r < 0) - return (r); - } - } - - /* External. */ - r = enc_uint64(a, 0); - if (r < 0) - return (r); - - - /* - * Make Times. - */ - file = zip->file_list.first; - for (;file != NULL; file = file->next) { - if ((file->flg & flg) == 0) - continue; - archive_le64enc(filetime, utcToFiletime(file->times[ti].time, - file->times[ti].time_ns)); - r = (int)compress_out(a, filetime, 8, ARCHIVE_Z_RUN); - if (r < 0) - return (r); - } - - return (ARCHIVE_OK); -} - -static int -make_header(struct archive_write *a, uint64_t offset, uint64_t pack_size, - uint64_t unpack_size, int codernum, struct coder *coders) -{ - struct _7zip *zip = (struct _7zip *)a->format_data; - struct file *file; - int r; - uint8_t b, mask; - - /* - * Make FilesInfo. - */ - r = enc_uint64(a, kHeader); - if (r < 0) - return (r); - - /* - * If there are empty files only, do not write MainStreamInfo. - */ - if (zip->total_number_nonempty_entry) { - /* - * Make MainStreamInfo. - */ - r = enc_uint64(a, kMainStreamsInfo); - if (r < 0) - return (r); - r = make_streamsInfo(a, offset, pack_size, unpack_size, - codernum, coders, 1, 0); - if (r < 0) - return (r); - } - - /* - * Make FilesInfo. - */ - r = enc_uint64(a, kFilesInfo); - if (r < 0) - return (r); - - /* Write numFiles. */ - r = enc_uint64(a, zip->total_number_entry); - if (r < 0) - return (r); - - if (zip->total_number_empty_entry > 0) { - /* Make EmptyStream. */ - r = enc_uint64(a, kEmptyStream); - if (r < 0) - return (r); - - /* Write EmptyStream Size. */ - r = enc_uint64(a, (zip->total_number_entry+7)>>3); - if (r < 0) - return (r); - - b = 0; - mask = 0x80; - file = zip->file_list.first; - for (;file != NULL; file = file->next) { - if (file->size == 0) - b |= mask; - mask >>= 1; - if (mask == 0) { - r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN); - if (r < 0) - return (r); - mask = 0x80; - b = 0; - } - } - if (mask != 0x80) { - r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN); - if (r < 0) - return (r); - } - } - - if (zip->total_number_empty_entry > zip->total_number_dir_entry) { - /* Make EmptyFile. */ - r = enc_uint64(a, kEmptyFile); - if (r < 0) - return (r); - - /* Write EmptyFile Size. */ - r = enc_uint64(a, (zip->total_number_empty_entry + 7) >> 3); - if (r < 0) - return (r); - - b = 0; - mask = 0x80; - file = zip->file_list.first; - for (;file != NULL; file = file->next) { - if (file->size) - continue; - if (!file->dir) - b |= mask; - mask >>= 1; - if (mask == 0) { - r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN); - if (r < 0) - return (r); - mask = 0x80; - b = 0; - } - } - if (mask != 0x80) { - r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN); - if (r < 0) - return (r); - } - } - - /* Make Name. */ - r = enc_uint64(a, kName); - if (r < 0) - return (r); - - /* Write Name size. */ - r = enc_uint64(a, zip->total_bytes_entry_name+1); - if (r < 0) - return (r); - - /* Write dmy byte. */ - r = enc_uint64(a, 0); - if (r < 0) - return (r); - - file = zip->file_list.first; - for (;file != NULL; file = file->next) { - r = (int)compress_out(a, file->utf16name, file->name_len+2, - ARCHIVE_Z_RUN); - if (r < 0) - return (r); - } - - /* Make MTime. */ - r = make_time(a, kMTime, MTIME_IS_SET, MTIME); - if (r < 0) - return (r); - - /* Make CTime. */ - r = make_time(a, kCTime, CTIME_IS_SET, CTIME); - if (r < 0) - return (r); - - /* Make ATime. */ - r = make_time(a, kATime, ATIME_IS_SET, ATIME); - if (r < 0) - return (r); - - /* Make Attributes. */ - r = enc_uint64(a, kAttributes); - if (r < 0) - return (r); - - /* Write Attributes size. */ - r = enc_uint64(a, 2 + zip->total_number_entry * 4); - if (r < 0) - return (r); - - /* Write "All Are Defined". */ - r = enc_uint64(a, 1); - if (r < 0) - return (r); - - /* Write dmy byte. */ - r = enc_uint64(a, 0); - if (r < 0) - return (r); - - file = zip->file_list.first; - for (;file != NULL; file = file->next) { - /* - * High 16bits is unix mode. - * Low 16bits is Windows attributes. - */ - uint32_t encattr, attr = 0; - - if (file->dir) - attr |= FILE_ATTRIBUTE_DIRECTORY; - else - attr |= FILE_ATTRIBUTE_ARCHIVE; - - if ((file->mode & 0222) == 0) - attr |= FILE_ATTRIBUTE_READONLY; - - attr |= FILE_ATTRIBUTE_UNIX_EXTENSION; - attr |= ((uint32_t)file->mode) << 16; - - archive_le32enc(&encattr, attr); - r = (int)compress_out(a, &encattr, 4, ARCHIVE_Z_RUN); - if (r < 0) - return (r); - } - - /* Write End. */ - r = enc_uint64(a, kEnd); - if (r < 0) - return (r); - - /* Write End. */ - r = enc_uint64(a, kEnd); - if (r < 0) - return (r); - - return (ARCHIVE_OK); -} - - -static int -_7z_free(struct archive_write *a) -{ - struct _7zip *zip = (struct _7zip *)a->format_data; - - /* Close the temporary file. */ - if (zip->temp_fd >= 0) - close(zip->temp_fd); - - file_free_register(zip); - compression_end(&(a->archive), &(zip->stream)); - free(zip->coder.props); - free(zip); - - return (ARCHIVE_OK); -} - -static int -file_cmp_node(const struct archive_rb_node *n1, - const struct archive_rb_node *n2) -{ - const struct file *f1 = (const struct file *)n1; - const struct file *f2 = (const struct file *)n2; - - if (f1->name_len == f2->name_len) - return (memcmp(f1->utf16name, f2->utf16name, f1->name_len)); - return (f1->name_len > f2->name_len)?1:-1; -} - -static int -file_cmp_key(const struct archive_rb_node *n, const void *key) -{ - const struct file *f = (const struct file *)n; - - return (f->name_len - *(const char *)key); -} - -static int -file_new(struct archive_write *a, struct archive_entry *entry, - struct file **newfile) -{ - struct _7zip *zip; - struct file *file; - const char *u16; - size_t u16len; - int ret = ARCHIVE_OK; - - zip = (struct _7zip *)a->format_data; - *newfile = NULL; - - file = calloc(1, sizeof(*file)); - if (file == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - - if (0 > archive_entry_pathname_l(entry, &u16, &u16len, zip->sconv)) { - if (errno == ENOMEM) { - free(file); - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for UTF-16LE"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "A filename cannot be converted to UTF-16LE;" - "You should disable making Joliet extension"); - ret = ARCHIVE_WARN; - } - file->utf16name = malloc(u16len + 2); - if (file->utf16name == NULL) { - free(file); - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Name"); - return (ARCHIVE_FATAL); - } - memcpy(file->utf16name, u16, u16len); - file->utf16name[u16len+0] = 0; - file->utf16name[u16len+1] = 0; - file->name_len = (unsigned)u16len; - file->mode = archive_entry_mode(entry); - if (archive_entry_filetype(entry) == AE_IFREG) - file->size = archive_entry_size(entry); - else - archive_entry_set_size(entry, 0); - if (archive_entry_filetype(entry) == AE_IFDIR) - file->dir = 1; - else if (archive_entry_filetype(entry) == AE_IFLNK) - file->size = strlen(archive_entry_symlink(entry)); - if (archive_entry_mtime_is_set(entry)) { - file->flg |= MTIME_IS_SET; - file->times[MTIME].time = archive_entry_mtime(entry); - file->times[MTIME].time_ns = archive_entry_mtime_nsec(entry); - } - if (archive_entry_atime_is_set(entry)) { - file->flg |= ATIME_IS_SET; - file->times[ATIME].time = archive_entry_atime(entry); - file->times[ATIME].time_ns = archive_entry_atime_nsec(entry); - } - if (archive_entry_ctime_is_set(entry)) { - file->flg |= CTIME_IS_SET; - file->times[CTIME].time = archive_entry_ctime(entry); - file->times[CTIME].time_ns = archive_entry_ctime_nsec(entry); - } - - *newfile = file; - return (ret); -} - -static void -file_free(struct file *file) -{ - free(file->utf16name); - free(file); -} - -static void -file_register(struct _7zip *zip, struct file *file) -{ - file->next = NULL; - *zip->file_list.last = file; - zip->file_list.last = &(file->next); -} - -static void -file_init_register(struct _7zip *zip) -{ - zip->file_list.first = NULL; - zip->file_list.last = &(zip->file_list.first); -} - -static void -file_free_register(struct _7zip *zip) -{ - struct file *file, *file_next; - - file = zip->file_list.first; - while (file != NULL) { - file_next = file->next; - file_free(file); - file = file_next; - } -} - -static void -file_register_empty(struct _7zip *zip, struct file *file) -{ - file->next = NULL; - *zip->empty_list.last = file; - zip->empty_list.last = &(file->next); -} - -static void -file_init_register_empty(struct _7zip *zip) -{ - zip->empty_list.first = NULL; - zip->empty_list.last = &(zip->empty_list.first); -} - -#if !defined(HAVE_ZLIB_H) || !defined(HAVE_BZLIB_H) ||\ - !defined(BZ_CONFIG_ERROR) || !defined(HAVE_LZMA_H) -static int -compression_unsupported_encoder(struct archive *a, - struct la_zstream *lastrm, const char *name) -{ - - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "%s compression not supported on this platform", name); - lastrm->valid = 0; - lastrm->real_stream = NULL; - return (ARCHIVE_FAILED); -} -#endif - -/* - * _7_COPY compressor. - */ -static int -compression_init_encoder_copy(struct archive *a, struct la_zstream *lastrm) -{ - - if (lastrm->valid) - compression_end(a, lastrm); - lastrm->valid = 1; - lastrm->code = compression_code_copy; - lastrm->end = compression_end_copy; - return (ARCHIVE_OK); -} - -static int -compression_code_copy(struct archive *a, - struct la_zstream *lastrm, enum la_zaction action) -{ - size_t bytes; - - (void)a; /* UNUSED */ - if (lastrm->avail_out > lastrm->avail_in) - bytes = lastrm->avail_in; - else - bytes = lastrm->avail_out; - if (bytes) { - memcpy(lastrm->next_out, lastrm->next_in, bytes); - lastrm->next_in += bytes; - lastrm->avail_in -= bytes; - lastrm->total_in += bytes; - lastrm->next_out += bytes; - lastrm->avail_out -= bytes; - lastrm->total_out += bytes; - } - if (action == ARCHIVE_Z_FINISH && lastrm->avail_in == 0) - return (ARCHIVE_EOF); - return (ARCHIVE_OK); -} - -static int -compression_end_copy(struct archive *a, struct la_zstream *lastrm) -{ - (void)a; /* UNUSED */ - lastrm->valid = 0; - return (ARCHIVE_OK); -} - -/* - * _7_DEFLATE compressor. - */ -#ifdef HAVE_ZLIB_H -static int -compression_init_encoder_deflate(struct archive *a, - struct la_zstream *lastrm, int level, int withheader) -{ - z_stream *strm; - - if (lastrm->valid) - compression_end(a, lastrm); - strm = calloc(1, sizeof(*strm)); - if (strm == NULL) { - archive_set_error(a, ENOMEM, - "Can't allocate memory for gzip stream"); - return (ARCHIVE_FATAL); - } - /* zlib.h is not const-correct, so we need this one bit - * of ugly hackery to convert a const * pointer to - * a non-const pointer. */ - strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in; - strm->avail_in = (uInt)lastrm->avail_in; - strm->total_in = (uLong)lastrm->total_in; - strm->next_out = lastrm->next_out; - strm->avail_out = (uInt)lastrm->avail_out; - strm->total_out = (uLong)lastrm->total_out; - if (deflateInit2(strm, level, Z_DEFLATED, - (withheader)?15:-15, - 8, Z_DEFAULT_STRATEGY) != Z_OK) { - free(strm); - lastrm->real_stream = NULL; - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Internal error initializing compression library"); - return (ARCHIVE_FATAL); - } - lastrm->real_stream = strm; - lastrm->valid = 1; - lastrm->code = compression_code_deflate; - lastrm->end = compression_end_deflate; - return (ARCHIVE_OK); -} - -static int -compression_code_deflate(struct archive *a, - struct la_zstream *lastrm, enum la_zaction action) -{ - z_stream *strm; - int r; - - strm = (z_stream *)lastrm->real_stream; - /* zlib.h is not const-correct, so we need this one bit - * of ugly hackery to convert a const * pointer to - * a non-const pointer. */ - strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in; - strm->avail_in = (uInt)lastrm->avail_in; - strm->total_in = (uLong)lastrm->total_in; - strm->next_out = lastrm->next_out; - strm->avail_out = (uInt)lastrm->avail_out; - strm->total_out = (uLong)lastrm->total_out; - r = deflate(strm, - (action == ARCHIVE_Z_FINISH)? Z_FINISH: Z_NO_FLUSH); - lastrm->next_in = strm->next_in; - lastrm->avail_in = strm->avail_in; - lastrm->total_in = strm->total_in; - lastrm->next_out = strm->next_out; - lastrm->avail_out = strm->avail_out; - lastrm->total_out = strm->total_out; - switch (r) { - case Z_OK: - return (ARCHIVE_OK); - case Z_STREAM_END: - return (ARCHIVE_EOF); - default: - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "GZip compression failed:" - " deflate() call returned status %d", r); - return (ARCHIVE_FATAL); - } -} - -static int -compression_end_deflate(struct archive *a, struct la_zstream *lastrm) -{ - z_stream *strm; - int r; - - strm = (z_stream *)lastrm->real_stream; - r = deflateEnd(strm); - free(strm); - lastrm->real_stream = NULL; - lastrm->valid = 0; - if (r != Z_OK) { - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Failed to clean up compressor"); - return (ARCHIVE_FATAL); - } - return (ARCHIVE_OK); -} -#else -static int -compression_init_encoder_deflate(struct archive *a, - struct la_zstream *lastrm, int level, int withheader) -{ - - (void) level; /* UNUSED */ - (void) withheader; /* UNUSED */ - if (lastrm->valid) - compression_end(a, lastrm); - return (compression_unsupported_encoder(a, lastrm, "deflate")); -} -#endif - -/* - * _7_BZIP2 compressor. - */ -#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) -static int -compression_init_encoder_bzip2(struct archive *a, - struct la_zstream *lastrm, int level) -{ - bz_stream *strm; - - if (lastrm->valid) - compression_end(a, lastrm); - strm = calloc(1, sizeof(*strm)); - if (strm == NULL) { - archive_set_error(a, ENOMEM, - "Can't allocate memory for bzip2 stream"); - return (ARCHIVE_FATAL); - } - /* bzlib.h is not const-correct, so we need this one bit - * of ugly hackery to convert a const * pointer to - * a non-const pointer. */ - strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in; - strm->avail_in = (uint32_t)lastrm->avail_in; - strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff); - strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32); - strm->next_out = (char *)lastrm->next_out; - strm->avail_out = (uint32_t)lastrm->avail_out; - strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff); - strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32); - if (BZ2_bzCompressInit(strm, level, 0, 30) != BZ_OK) { - free(strm); - lastrm->real_stream = NULL; - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Internal error initializing compression library"); - return (ARCHIVE_FATAL); - } - lastrm->real_stream = strm; - lastrm->valid = 1; - lastrm->code = compression_code_bzip2; - lastrm->end = compression_end_bzip2; - return (ARCHIVE_OK); -} - -static int -compression_code_bzip2(struct archive *a, - struct la_zstream *lastrm, enum la_zaction action) -{ - bz_stream *strm; - int r; - - strm = (bz_stream *)lastrm->real_stream; - /* bzlib.h is not const-correct, so we need this one bit - * of ugly hackery to convert a const * pointer to - * a non-const pointer. */ - strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in; - strm->avail_in = (uint32_t)lastrm->avail_in; - strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff); - strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32); - strm->next_out = (char *)lastrm->next_out; - strm->avail_out = (uint32_t)lastrm->avail_out; - strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff); - strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32); - r = BZ2_bzCompress(strm, - (action == ARCHIVE_Z_FINISH)? BZ_FINISH: BZ_RUN); - lastrm->next_in = (const unsigned char *)strm->next_in; - lastrm->avail_in = strm->avail_in; - lastrm->total_in = - (((uint64_t)(uint32_t)strm->total_in_hi32) << 32) - + (uint64_t)(uint32_t)strm->total_in_lo32; - lastrm->next_out = (unsigned char *)strm->next_out; - lastrm->avail_out = strm->avail_out; - lastrm->total_out = - (((uint64_t)(uint32_t)strm->total_out_hi32) << 32) - + (uint64_t)(uint32_t)strm->total_out_lo32; - switch (r) { - case BZ_RUN_OK: /* Non-finishing */ - case BZ_FINISH_OK: /* Finishing: There's more work to do */ - return (ARCHIVE_OK); - case BZ_STREAM_END: /* Finishing: all done */ - /* Only occurs in finishing case */ - return (ARCHIVE_EOF); - default: - /* Any other return value indicates an error */ - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Bzip2 compression failed:" - " BZ2_bzCompress() call returned status %d", r); - return (ARCHIVE_FATAL); - } -} - -static int -compression_end_bzip2(struct archive *a, struct la_zstream *lastrm) -{ - bz_stream *strm; - int r; - - strm = (bz_stream *)lastrm->real_stream; - r = BZ2_bzCompressEnd(strm); - free(strm); - lastrm->real_stream = NULL; - lastrm->valid = 0; - if (r != BZ_OK) { - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Failed to clean up compressor"); - return (ARCHIVE_FATAL); - } - return (ARCHIVE_OK); -} - -#else -static int -compression_init_encoder_bzip2(struct archive *a, - struct la_zstream *lastrm, int level) -{ - - (void) level; /* UNUSED */ - if (lastrm->valid) - compression_end(a, lastrm); - return (compression_unsupported_encoder(a, lastrm, "bzip2")); -} -#endif - -/* - * _7_LZMA1, _7_LZMA2 compressor. - */ -#if defined(HAVE_LZMA_H) -static int -compression_init_encoder_lzma(struct archive *a, - struct la_zstream *lastrm, int level, uint64_t filter_id) -{ - static const lzma_stream lzma_init_data = LZMA_STREAM_INIT; - lzma_stream *strm; - lzma_filter *lzmafilters; - lzma_options_lzma lzma_opt; - int r; - - if (lastrm->valid) - compression_end(a, lastrm); - strm = calloc(1, sizeof(*strm) + sizeof(*lzmafilters) * 2); - if (strm == NULL) { - archive_set_error(a, ENOMEM, - "Can't allocate memory for lzma stream"); - return (ARCHIVE_FATAL); - } - lzmafilters = (lzma_filter *)(strm+1); - if (level > 9) - level = 9; - if (lzma_lzma_preset(&lzma_opt, level)) { - free(strm); - lastrm->real_stream = NULL; - archive_set_error(a, ENOMEM, - "Internal error initializing compression library"); - return (ARCHIVE_FATAL); - } - lzmafilters[0].id = filter_id; - lzmafilters[0].options = &lzma_opt; - lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */ - - r = lzma_properties_size(&(lastrm->prop_size), lzmafilters); - if (r != LZMA_OK) { - free(strm); - lastrm->real_stream = NULL; - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "lzma_properties_size failed"); - return (ARCHIVE_FATAL); - } - if (lastrm->prop_size) { - lastrm->props = malloc(lastrm->prop_size); - if (lastrm->props == NULL) { - free(strm); - lastrm->real_stream = NULL; - archive_set_error(a, ENOMEM, - "Cannot allocate memory"); - return (ARCHIVE_FATAL); - } - r = lzma_properties_encode(lzmafilters, lastrm->props); - if (r != LZMA_OK) { - free(strm); - lastrm->real_stream = NULL; - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "lzma_properties_encode failed"); - return (ARCHIVE_FATAL); - } - } - - *strm = lzma_init_data; - r = lzma_raw_encoder(strm, lzmafilters); - switch (r) { - case LZMA_OK: - lastrm->real_stream = strm; - lastrm->valid = 1; - lastrm->code = compression_code_lzma; - lastrm->end = compression_end_lzma; - r = ARCHIVE_OK; - break; - case LZMA_MEM_ERROR: - free(strm); - lastrm->real_stream = NULL; - archive_set_error(a, ENOMEM, - "Internal error initializing compression library: " - "Cannot allocate memory"); - r = ARCHIVE_FATAL; - break; - default: - free(strm); - lastrm->real_stream = NULL; - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Internal error initializing compression library: " - "It's a bug in liblzma"); - r = ARCHIVE_FATAL; - break; - } - return (r); -} - -static int -compression_init_encoder_lzma1(struct archive *a, - struct la_zstream *lastrm, int level) -{ - return compression_init_encoder_lzma(a, lastrm, level, - LZMA_FILTER_LZMA1); -} - -static int -compression_init_encoder_lzma2(struct archive *a, - struct la_zstream *lastrm, int level) -{ - return compression_init_encoder_lzma(a, lastrm, level, - LZMA_FILTER_LZMA2); -} - -static int -compression_code_lzma(struct archive *a, - struct la_zstream *lastrm, enum la_zaction action) -{ - lzma_stream *strm; - int r; - - strm = (lzma_stream *)lastrm->real_stream; - strm->next_in = lastrm->next_in; - strm->avail_in = lastrm->avail_in; - strm->total_in = lastrm->total_in; - strm->next_out = lastrm->next_out; - strm->avail_out = lastrm->avail_out; - strm->total_out = lastrm->total_out; - r = lzma_code(strm, - (action == ARCHIVE_Z_FINISH)? LZMA_FINISH: LZMA_RUN); - lastrm->next_in = strm->next_in; - lastrm->avail_in = strm->avail_in; - lastrm->total_in = strm->total_in; - lastrm->next_out = strm->next_out; - lastrm->avail_out = strm->avail_out; - lastrm->total_out = strm->total_out; - switch (r) { - case LZMA_OK: - /* Non-finishing case */ - return (ARCHIVE_OK); - case LZMA_STREAM_END: - /* This return can only occur in finishing case. */ - return (ARCHIVE_EOF); - case LZMA_MEMLIMIT_ERROR: - archive_set_error(a, ENOMEM, - "lzma compression error:" - " %ju MiB would have been needed", - (uintmax_t)((lzma_memusage(strm) + 1024 * 1024 -1) - / (1024 * 1024))); - return (ARCHIVE_FATAL); - default: - /* Any other return value indicates an error */ - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "lzma compression failed:" - " lzma_code() call returned status %d", r); - return (ARCHIVE_FATAL); - } -} - -static int -compression_end_lzma(struct archive *a, struct la_zstream *lastrm) -{ - lzma_stream *strm; - - (void)a; /* UNUSED */ - strm = (lzma_stream *)lastrm->real_stream; - lzma_end(strm); - free(strm); - lastrm->valid = 0; - lastrm->real_stream = NULL; - return (ARCHIVE_OK); -} -#else -static int -compression_init_encoder_lzma1(struct archive *a, - struct la_zstream *lastrm, int level) -{ - - (void) level; /* UNUSED */ - if (lastrm->valid) - compression_end(a, lastrm); - return (compression_unsupported_encoder(a, lastrm, "lzma")); -} -static int -compression_init_encoder_lzma2(struct archive *a, - struct la_zstream *lastrm, int level) -{ - - (void) level; /* UNUSED */ - if (lastrm->valid) - compression_end(a, lastrm); - return (compression_unsupported_encoder(a, lastrm, "lzma")); -} -#endif - -/* - * _7_PPMD compressor. - */ -static void -ppmd_write(void *p, Byte b) -{ - struct archive_write *a = ((IByteOut *)p)->a; - struct _7zip *zip = (struct _7zip *)(a->format_data); - struct la_zstream *lastrm = &(zip->stream); - struct ppmd_stream *strm; - - if (lastrm->avail_out) { - *lastrm->next_out++ = b; - lastrm->avail_out--; - lastrm->total_out++; - return; - } - strm = (struct ppmd_stream *)lastrm->real_stream; - if (strm->buff_ptr < strm->buff_end) { - *strm->buff_ptr++ = b; - strm->buff_bytes++; - } -} - -static int -compression_init_encoder_ppmd(struct archive *a, - struct la_zstream *lastrm, unsigned maxOrder, uint32_t msize) -{ - struct ppmd_stream *strm; - uint8_t *props; - int r; - - if (lastrm->valid) - compression_end(a, lastrm); - strm = calloc(1, sizeof(*strm)); - if (strm == NULL) { - archive_set_error(a, ENOMEM, - "Can't allocate memory for PPMd"); - return (ARCHIVE_FATAL); - } - strm->buff = malloc(32); - if (strm->buff == NULL) { - free(strm); - archive_set_error(a, ENOMEM, - "Can't allocate memory for PPMd"); - return (ARCHIVE_FATAL); - } - strm->buff_ptr = strm->buff; - strm->buff_end = strm->buff + 32; - - props = malloc(1+4); - if (props == NULL) { - free(strm->buff); - free(strm); - archive_set_error(a, ENOMEM, - "Coludn't allocate memory for PPMd"); - return (ARCHIVE_FATAL); - } - props[0] = maxOrder; - archive_le32enc(props+1, msize); - __archive_ppmd7_functions.Ppmd7_Construct(&strm->ppmd7_context); - r = __archive_ppmd7_functions.Ppmd7_Alloc( - &strm->ppmd7_context, msize); - if (r == 0) { - free(strm->buff); - free(strm); - free(props); - archive_set_error(a, ENOMEM, - "Coludn't allocate memory for PPMd"); - return (ARCHIVE_FATAL); - } - __archive_ppmd7_functions.Ppmd7_Init(&(strm->ppmd7_context), maxOrder); - strm->byteout.a = (struct archive_write *)a; - strm->byteout.Write = ppmd_write; - strm->range_enc.Stream = &(strm->byteout); - __archive_ppmd7_functions.Ppmd7z_RangeEnc_Init(&(strm->range_enc)); - strm->stat = 0; - - lastrm->real_stream = strm; - lastrm->valid = 1; - lastrm->code = compression_code_ppmd; - lastrm->end = compression_end_ppmd; - lastrm->prop_size = 5; - lastrm->props = props; - return (ARCHIVE_OK); -} - -static int -compression_code_ppmd(struct archive *a, - struct la_zstream *lastrm, enum la_zaction action) -{ - struct ppmd_stream *strm; - - (void)a; /* UNUSED */ - - strm = (struct ppmd_stream *)lastrm->real_stream; - - /* Copy encoded data if there are remaining bytes from previous call. */ - if (strm->buff_bytes) { - uint8_t *p = strm->buff_ptr - strm->buff_bytes; - while (lastrm->avail_out && strm->buff_bytes) { - *lastrm->next_out++ = *p++; - lastrm->avail_out--; - lastrm->total_out++; - strm->buff_bytes--; - } - if (strm->buff_bytes) - return (ARCHIVE_OK); - if (strm->stat == 1) - return (ARCHIVE_EOF); - strm->buff_ptr = strm->buff; - } - while (lastrm->avail_in && lastrm->avail_out) { - __archive_ppmd7_functions.Ppmd7_EncodeSymbol( - &(strm->ppmd7_context), &(strm->range_enc), - *lastrm->next_in++); - lastrm->avail_in--; - lastrm->total_in++; - } - if (lastrm->avail_in == 0 && action == ARCHIVE_Z_FINISH) { - __archive_ppmd7_functions.Ppmd7z_RangeEnc_FlushData( - &(strm->range_enc)); - strm->stat = 1; - /* Return EOF if there are no remaining bytes. */ - if (strm->buff_bytes == 0) - return (ARCHIVE_EOF); - } - return (ARCHIVE_OK); -} - -static int -compression_end_ppmd(struct archive *a, struct la_zstream *lastrm) -{ - struct ppmd_stream *strm; - - (void)a; /* UNUSED */ - - strm = (struct ppmd_stream *)lastrm->real_stream; - __archive_ppmd7_functions.Ppmd7_Free(&strm->ppmd7_context); - free(strm->buff); - free(strm); - lastrm->real_stream = NULL; - lastrm->valid = 0; - return (ARCHIVE_OK); -} - -/* - * Universal compressor initializer. - */ -static int -_7z_compression_init_encoder(struct archive_write *a, unsigned compression, - int compression_level) -{ - struct _7zip *zip; - int r; - - zip = (struct _7zip *)a->format_data; - switch (compression) { - case _7Z_DEFLATE: - r = compression_init_encoder_deflate( - &(a->archive), &(zip->stream), - compression_level, 0); - break; - case _7Z_BZIP2: - r = compression_init_encoder_bzip2( - &(a->archive), &(zip->stream), - compression_level); - break; - case _7Z_LZMA1: - r = compression_init_encoder_lzma1( - &(a->archive), &(zip->stream), - compression_level); - break; - case _7Z_LZMA2: - r = compression_init_encoder_lzma2( - &(a->archive), &(zip->stream), - compression_level); - break; - case _7Z_PPMD: - r = compression_init_encoder_ppmd( - &(a->archive), &(zip->stream), - PPMD7_DEFAULT_ORDER, PPMD7_DEFAULT_MEM_SIZE); - break; - case _7Z_COPY: - default: - r = compression_init_encoder_copy( - &(a->archive), &(zip->stream)); - break; - } - if (r == ARCHIVE_OK) { - zip->stream.total_in = 0; - zip->stream.next_out = zip->wbuff; - zip->stream.avail_out = sizeof(zip->wbuff); - zip->stream.total_out = 0; - } - - return (r); -} - -static int -compression_code(struct archive *a, struct la_zstream *lastrm, - enum la_zaction action) -{ - if (lastrm->valid) - return (lastrm->code(a, lastrm, action)); - return (ARCHIVE_OK); -} - -static int -compression_end(struct archive *a, struct la_zstream *lastrm) -{ - if (lastrm->valid) { - lastrm->prop_size = 0; - free(lastrm->props); - lastrm->props = NULL; - return (lastrm->end(a, lastrm)); - } - return (ARCHIVE_OK); -} - - diff --git a/thirdparty/libarchive/libarchive/archive_write_set_format_ar.c b/thirdparty/libarchive/libarchive/archive_write_set_format_ar.c deleted file mode 100644 index fc0de1e9f..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_set_format_ar.c +++ /dev/null @@ -1,570 +0,0 @@ -/*- - * Copyright (c) 2007 Kai Wang - * Copyright (c) 2007 Tim Kientzle - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_ar.c 201108 2009-12-28 03:28:21Z kientzle $"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" -#include "archive_private.h" -#include "archive_write_private.h" -#include "archive_write_set_format_private.h" - -struct ar_w { - uint64_t entry_bytes_remaining; - uint64_t entry_padding; - int is_strtab; - int has_strtab; - char wrote_global_header; - char *strtab; -}; - -/* - * Define structure of the "ar" header. - */ -#define AR_name_offset 0 -#define AR_name_size 16 -#define AR_date_offset 16 -#define AR_date_size 12 -#define AR_uid_offset 28 -#define AR_uid_size 6 -#define AR_gid_offset 34 -#define AR_gid_size 6 -#define AR_mode_offset 40 -#define AR_mode_size 8 -#define AR_size_offset 48 -#define AR_size_size 10 -#define AR_fmag_offset 58 -#define AR_fmag_size 2 - -static int archive_write_set_format_ar(struct archive_write *); -static int archive_write_ar_header(struct archive_write *, - struct archive_entry *); -static ssize_t archive_write_ar_data(struct archive_write *, - const void *buff, size_t s); -static int archive_write_ar_free(struct archive_write *); -static int archive_write_ar_close(struct archive_write *); -static int archive_write_ar_finish_entry(struct archive_write *); -static const char *ar_basename(const char *path); -static int format_octal(int64_t v, char *p, int s); -static int format_decimal(int64_t v, char *p, int s); - -int -archive_write_set_format_ar_bsd(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - int r; - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_set_format_ar_bsd"); - r = archive_write_set_format_ar(a); - if (r == ARCHIVE_OK) { - a->archive.archive_format = ARCHIVE_FORMAT_AR_BSD; - a->archive.archive_format_name = "ar (BSD)"; - } - return (r); -} - -int -archive_write_set_format_ar_svr4(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - int r; - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_set_format_ar_svr4"); - r = archive_write_set_format_ar(a); - if (r == ARCHIVE_OK) { - a->archive.archive_format = ARCHIVE_FORMAT_AR_GNU; - a->archive.archive_format_name = "ar (GNU/SVR4)"; - } - return (r); -} - -/* - * Generic initialization. - */ -static int -archive_write_set_format_ar(struct archive_write *a) -{ - struct ar_w *ar; - - /* If someone else was already registered, unregister them. */ - if (a->format_free != NULL) - (a->format_free)(a); - - ar = (struct ar_w *)calloc(1, sizeof(*ar)); - if (ar == NULL) { - archive_set_error(&a->archive, ENOMEM, "Can't allocate ar data"); - return (ARCHIVE_FATAL); - } - a->format_data = ar; - - a->format_name = "ar"; - a->format_write_header = archive_write_ar_header; - a->format_write_data = archive_write_ar_data; - a->format_close = archive_write_ar_close; - a->format_free = archive_write_ar_free; - a->format_finish_entry = archive_write_ar_finish_entry; - return (ARCHIVE_OK); -} - -static int -archive_write_ar_header(struct archive_write *a, struct archive_entry *entry) -{ - int ret, append_fn; - char buff[60]; - char *ss, *se; - struct ar_w *ar; - const char *pathname; - const char *filename; - int64_t size; - - append_fn = 0; - ar = (struct ar_w *)a->format_data; - ar->is_strtab = 0; - filename = NULL; - size = archive_entry_size(entry); - - - /* - * Reject files with empty name. - */ - pathname = archive_entry_pathname(entry); - if (pathname == NULL || *pathname == '\0') { - archive_set_error(&a->archive, EINVAL, - "Invalid filename"); - return (ARCHIVE_WARN); - } - - /* - * If we are now at the beginning of the archive, - * we need first write the ar global header. - */ - if (!ar->wrote_global_header) { - __archive_write_output(a, "!\n", 8); - ar->wrote_global_header = 1; - } - - memset(buff, ' ', 60); - memcpy(&buff[AR_fmag_offset], "`\n", 2); - - if (strcmp(pathname, "/") == 0 ) { - /* Entry is archive symbol table in GNU format */ - buff[AR_name_offset] = '/'; - goto stat; - } - if (strcmp(pathname, "/SYM64/") == 0) { - /* Entry is archive symbol table in GNU 64-bit format */ - memcpy(buff + AR_name_offset, "/SYM64/", 7); - goto stat; - } - if (strcmp(pathname, "__.SYMDEF") == 0) { - /* Entry is archive symbol table in BSD format */ - memcpy(buff + AR_name_offset, "__.SYMDEF", 9); - goto stat; - } - if (strcmp(pathname, "//") == 0) { - /* - * Entry is archive filename table, inform that we should - * collect strtab in next _data call. - */ - ar->is_strtab = 1; - buff[AR_name_offset] = buff[AR_name_offset + 1] = '/'; - /* - * For archive string table, only ar_size field should - * be set. - */ - goto size; - } - - /* - * Otherwise, entry is a normal archive member. - * Strip leading paths from filenames, if any. - */ - if ((filename = ar_basename(pathname)) == NULL) { - /* Reject filenames with trailing "/" */ - archive_set_error(&a->archive, EINVAL, - "Invalid filename"); - return (ARCHIVE_WARN); - } - - if (a->archive.archive_format == ARCHIVE_FORMAT_AR_GNU) { - /* - * SVR4/GNU variant use a "/" to mark then end of the filename, - * make it possible to have embedded spaces in the filename. - * So, the longest filename here (without extension) is - * actually 15 bytes. - */ - if (strlen(filename) <= 15) { - memcpy(&buff[AR_name_offset], - filename, strlen(filename)); - buff[AR_name_offset + strlen(filename)] = '/'; - } else { - /* - * For filename longer than 15 bytes, GNU variant - * makes use of a string table and instead stores the - * offset of the real filename to in the ar_name field. - * The string table should have been written before. - */ - if (ar->has_strtab <= 0) { - archive_set_error(&a->archive, EINVAL, - "Can't find string table"); - return (ARCHIVE_WARN); - } - - se = (char *)malloc(strlen(filename) + 3); - if (se == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate filename buffer"); - return (ARCHIVE_FATAL); - } - - memcpy(se, filename, strlen(filename)); - strcpy(se + strlen(filename), "/\n"); - - ss = strstr(ar->strtab, se); - free(se); - - if (ss == NULL) { - archive_set_error(&a->archive, EINVAL, - "Invalid string table"); - return (ARCHIVE_WARN); - } - - /* - * GNU variant puts "/" followed by digits into - * ar_name field. These digits indicates the real - * filename string's offset to the string table. - */ - buff[AR_name_offset] = '/'; - if (format_decimal(ss - ar->strtab, - buff + AR_name_offset + 1, - AR_name_size - 1)) { - archive_set_error(&a->archive, ERANGE, - "string table offset too large"); - return (ARCHIVE_WARN); - } - } - } else if (a->archive.archive_format == ARCHIVE_FORMAT_AR_BSD) { - /* - * BSD variant: for any file name which is more than - * 16 chars or contains one or more embedded space(s), the - * string "#1/" followed by the ASCII length of the name is - * put into the ar_name field. The file size (stored in the - * ar_size field) is incremented by the length of the name. - * The name is then written immediately following the - * archive header. - */ - if (strlen(filename) <= 16 && strchr(filename, ' ') == NULL) { - memcpy(&buff[AR_name_offset], filename, strlen(filename)); - buff[AR_name_offset + strlen(filename)] = ' '; - } - else { - memcpy(buff + AR_name_offset, "#1/", 3); - if (format_decimal(strlen(filename), - buff + AR_name_offset + 3, - AR_name_size - 3)) { - archive_set_error(&a->archive, ERANGE, - "File name too long"); - return (ARCHIVE_WARN); - } - append_fn = 1; - size += strlen(filename); - } - } - -stat: - if (format_decimal(archive_entry_mtime(entry), buff + AR_date_offset, AR_date_size)) { - archive_set_error(&a->archive, ERANGE, - "File modification time too large"); - return (ARCHIVE_WARN); - } - if (format_decimal(archive_entry_uid(entry), buff + AR_uid_offset, AR_uid_size)) { - archive_set_error(&a->archive, ERANGE, - "Numeric user ID too large"); - return (ARCHIVE_WARN); - } - if (format_decimal(archive_entry_gid(entry), buff + AR_gid_offset, AR_gid_size)) { - archive_set_error(&a->archive, ERANGE, - "Numeric group ID too large"); - return (ARCHIVE_WARN); - } - if (format_octal(archive_entry_mode(entry), buff + AR_mode_offset, AR_mode_size)) { - archive_set_error(&a->archive, ERANGE, - "Numeric mode too large"); - return (ARCHIVE_WARN); - } - /* - * Sanity Check: A non-pseudo archive member should always be - * a regular file. - */ - if (filename != NULL && archive_entry_filetype(entry) != AE_IFREG) { - archive_set_error(&a->archive, EINVAL, - "Regular file required for non-pseudo member"); - return (ARCHIVE_WARN); - } - -size: - if (format_decimal(size, buff + AR_size_offset, AR_size_size)) { - archive_set_error(&a->archive, ERANGE, - "File size out of range"); - return (ARCHIVE_WARN); - } - - ret = __archive_write_output(a, buff, 60); - if (ret != ARCHIVE_OK) - return (ret); - - ar->entry_bytes_remaining = size; - ar->entry_padding = ar->entry_bytes_remaining % 2; - - if (append_fn > 0) { - ret = __archive_write_output(a, filename, strlen(filename)); - if (ret != ARCHIVE_OK) - return (ret); - ar->entry_bytes_remaining -= strlen(filename); - } - - return (ARCHIVE_OK); -} - -static ssize_t -archive_write_ar_data(struct archive_write *a, const void *buff, size_t s) -{ - struct ar_w *ar; - int ret; - - ar = (struct ar_w *)a->format_data; - if (s > ar->entry_bytes_remaining) - s = (size_t)ar->entry_bytes_remaining; - - if (ar->is_strtab > 0) { - if (ar->has_strtab > 0) { - archive_set_error(&a->archive, EINVAL, - "More than one string tables exist"); - return (ARCHIVE_WARN); - } - - ar->strtab = (char *)malloc(s + 1); - if (ar->strtab == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate strtab buffer"); - return (ARCHIVE_FATAL); - } - memcpy(ar->strtab, buff, s); - ar->strtab[s] = '\0'; - ar->has_strtab = 1; - } - - ret = __archive_write_output(a, buff, s); - if (ret != ARCHIVE_OK) - return (ret); - - ar->entry_bytes_remaining -= s; - return (s); -} - -static int -archive_write_ar_free(struct archive_write *a) -{ - struct ar_w *ar; - - ar = (struct ar_w *)a->format_data; - - if (ar == NULL) - return (ARCHIVE_OK); - - if (ar->has_strtab > 0) { - free(ar->strtab); - ar->strtab = NULL; - } - - free(ar); - a->format_data = NULL; - return (ARCHIVE_OK); -} - -static int -archive_write_ar_close(struct archive_write *a) -{ - struct ar_w *ar; - int ret; - - /* - * If we haven't written anything yet, we need to write - * the ar global header now to make it a valid ar archive. - */ - ar = (struct ar_w *)a->format_data; - if (!ar->wrote_global_header) { - ar->wrote_global_header = 1; - ret = __archive_write_output(a, "!\n", 8); - return (ret); - } - - return (ARCHIVE_OK); -} - -static int -archive_write_ar_finish_entry(struct archive_write *a) -{ - struct ar_w *ar; - int ret; - - ar = (struct ar_w *)a->format_data; - - if (ar->entry_bytes_remaining != 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Entry remaining bytes larger than 0"); - return (ARCHIVE_WARN); - } - - if (ar->entry_padding == 0) { - return (ARCHIVE_OK); - } - - if (ar->entry_padding != 1) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Padding wrong size: %ju should be 1 or 0", - (uintmax_t)ar->entry_padding); - return (ARCHIVE_WARN); - } - - ret = __archive_write_output(a, "\n", 1); - return (ret); -} - -/* - * Format a number into the specified field using base-8. - * NB: This version is slightly different from the one in - * _ustar.c - */ -static int -format_octal(int64_t v, char *p, int s) -{ - int len; - char *h; - - len = s; - h = p; - - /* Octal values can't be negative, so use 0. */ - if (v < 0) { - while (len-- > 0) - *p++ = '0'; - return (-1); - } - - p += s; /* Start at the end and work backwards. */ - do { - *--p = (char)('0' + (v & 7)); - v >>= 3; - } while (--s > 0 && v > 0); - - if (v == 0) { - memmove(h, p, len - s); - p = h + len - s; - while (s-- > 0) - *p++ = ' '; - return (0); - } - /* If it overflowed, fill field with max value. */ - while (len-- > 0) - *p++ = '7'; - - return (-1); -} - -/* - * Format a number into the specified field using base-10. - */ -static int -format_decimal(int64_t v, char *p, int s) -{ - int len; - char *h; - - len = s; - h = p; - - /* Negative values in ar header are meaningless, so use 0. */ - if (v < 0) { - while (len-- > 0) - *p++ = '0'; - return (-1); - } - - p += s; - do { - *--p = (char)('0' + (v % 10)); - v /= 10; - } while (--s > 0 && v > 0); - - if (v == 0) { - memmove(h, p, len - s); - p = h + len - s; - while (s-- > 0) - *p++ = ' '; - return (0); - } - /* If it overflowed, fill field with max value. */ - while (len-- > 0) - *p++ = '9'; - - return (-1); -} - -static const char * -ar_basename(const char *path) -{ - const char *endp, *startp; - - endp = path + strlen(path) - 1; - /* - * For filename with trailing slash(es), we return - * NULL indicating an error. - */ - if (*endp == '/') - return (NULL); - - /* Find the start of the base */ - startp = endp; - while (startp > path && *(startp - 1) != '/') - startp--; - - return (startp); -} diff --git a/thirdparty/libarchive/libarchive/archive_write_set_format_by_name.c b/thirdparty/libarchive/libarchive/archive_write_set_format_by_name.c deleted file mode 100644 index bfb4b3545..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_set_format_by_name.c +++ /dev/null @@ -1,94 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_by_name.c 201168 2009-12-29 06:15:32Z kientzle $"); - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "archive.h" -#include "archive_private.h" - -/* A table that maps names to functions. */ -static const -struct { const char *name; int (*setter)(struct archive *); } names[] = -{ - { "7zip", archive_write_set_format_7zip }, - { "ar", archive_write_set_format_ar_bsd }, - { "arbsd", archive_write_set_format_ar_bsd }, - { "argnu", archive_write_set_format_ar_svr4 }, - { "arsvr4", archive_write_set_format_ar_svr4 }, - { "bin", archive_write_set_format_cpio_bin }, - { "bsdtar", archive_write_set_format_pax_restricted }, - { "cd9660", archive_write_set_format_iso9660 }, - { "cpio", archive_write_set_format_cpio }, - { "gnutar", archive_write_set_format_gnutar }, - { "iso", archive_write_set_format_iso9660 }, - { "iso9660", archive_write_set_format_iso9660 }, - { "mtree", archive_write_set_format_mtree }, - { "mtree-classic", archive_write_set_format_mtree_classic }, - { "newc", archive_write_set_format_cpio_newc }, - { "odc", archive_write_set_format_cpio_odc }, - { "oldtar", archive_write_set_format_v7tar }, - { "pax", archive_write_set_format_pax }, - { "paxr", archive_write_set_format_pax_restricted }, - { "posix", archive_write_set_format_pax }, - { "pwb", archive_write_set_format_cpio_pwb }, - { "raw", archive_write_set_format_raw }, - { "rpax", archive_write_set_format_pax_restricted }, - { "shar", archive_write_set_format_shar }, - { "shardump", archive_write_set_format_shar_dump }, - { "ustar", archive_write_set_format_ustar }, - { "v7tar", archive_write_set_format_v7tar }, - { "v7", archive_write_set_format_v7tar }, - { "warc", archive_write_set_format_warc }, - { "xar", archive_write_set_format_xar }, - { "zip", archive_write_set_format_zip }, - { NULL, NULL } -}; - -int -archive_write_set_format_by_name(struct archive *a, const char *name) -{ - int i; - - for (i = 0; names[i].name != NULL; i++) { - if (strcmp(name, names[i].name) == 0) - return ((names[i].setter)(a)); - } - - archive_set_error(a, EINVAL, "No such format '%s'", name); - a->state = ARCHIVE_STATE_FATAL; - return (ARCHIVE_FATAL); -} diff --git a/thirdparty/libarchive/libarchive/archive_write_set_format_cpio.c b/thirdparty/libarchive/libarchive/archive_write_set_format_cpio.c deleted file mode 100644 index 47152cc6a..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_set_format_cpio.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "archive_platform.h" -#include "archive.h" - -/* - * Set output format to the default 'cpio' format. - */ -int -archive_write_set_format_cpio(struct archive *_a) -{ - return archive_write_set_format_cpio_odc(_a); -} diff --git a/thirdparty/libarchive/libarchive/archive_write_set_format_cpio_binary.c b/thirdparty/libarchive/libarchive/archive_write_set_format_cpio_binary.c deleted file mode 100644 index d6ce35a7b..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_set_format_cpio_binary.c +++ /dev/null @@ -1,610 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2011-2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_cpio.c 201170 2009-12-29 06:34:23Z kientzle $"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" -#include "archive_entry_locale.h" -#include "archive_private.h" -#include "archive_write_private.h" -#include "archive_write_set_format_private.h" - -static ssize_t archive_write_binary_data(struct archive_write *, - const void *buff, size_t s); -static int archive_write_binary_close(struct archive_write *); -static int archive_write_binary_free(struct archive_write *); -static int archive_write_binary_finish_entry(struct archive_write *); -static int archive_write_binary_header(struct archive_write *, - struct archive_entry *); -static int archive_write_binary_options(struct archive_write *, - const char *, const char *); -static int write_header(struct archive_write *, struct archive_entry *); - -struct cpio { - uint64_t entry_bytes_remaining; - - int64_t ino_next; - - struct { int64_t old; int new;} *ino_list; - size_t ino_list_size; - size_t ino_list_next; - - struct archive_string_conv *opt_sconv; - struct archive_string_conv *sconv_default; - int init_default_conversion; -}; - -/* This struct needs to be packed to get the header right */ - -#if defined(__GNUC__) -#define PACKED(x) x __attribute__((packed)) -#elif defined(_MSC_VER) -#define PACKED(x) __pragma(pack(push, 1)) x __pragma(pack(pop)) -#else -#define PACKED(x) x -#endif - -#define HSIZE 26 - -PACKED(struct cpio_binary_header { - uint16_t h_magic; - uint16_t h_dev; - uint16_t h_ino; - uint16_t h_mode; - uint16_t h_uid; - uint16_t h_gid; - uint16_t h_nlink; - uint16_t h_majmin; - uint32_t h_mtime; - uint16_t h_namesize; - uint32_t h_filesize; -}); - -/* Back in the day, the 7th Edition cpio.c had this, to - * adapt to, as the comment said, "VAX, Interdata, ...": - * - * union { long l; short s[2]; char c[4]; } U; - * #define MKSHORT(v,lv) {U.l=1L;if(U.c[0]) U.l=lv,v[0]=U.s[1],v[1]=U.s[0]; else U.l=lv,v[0]=U.s[0],v[1]=U.s[1];} - * long mklong(v) - * short v[]; - * { - * U.l = 1; - * if(U.c[0]) - * U.s[0] = v[1], U.s[1] = v[0]; - * else - * U.s[0] = v[0], U.s[1] = v[1]; - * return U.l; - * } - * - * Of course, that assumes that all machines have little-endian shorts, - * and just adapts the others to the special endianness of the PDP-11. - * - * Now, we could do this: - * - * union { uint32_t l; uint16_t s[2]; uint8_t c[4]; } U; - * #define PUTI16(v,sv) {U.s[0]=1;if(U.c[0]) v=sv; else U.s[0]=sv,U.c[2]=U.c[1],U.c[3]=U.c[0],v=U.s[1];} - * #define PUTI32(v,lv) {char_t Ut;U.l=1;if(U.c[0]) U.l=lv,v[0]=U.s[1],v[1]=U.s[0]; else U.l=lv,Ut=U.c[0],U.c[0]=U.c[1],U.c[1]=Ut,Ut=U.c[2],U.c[2]=U.c[3],U.c[3]=Ut,v[0]=U.s[0],v[1]=U.s[1];} - * - * ...but it feels a little better to do it like this: - */ - -static uint16_t la_swap16(uint16_t in) { - union { - uint16_t s[2]; - uint8_t c[4]; - } U; - U.s[0] = 1; - if (U.c[0]) - return in; - else { - U.s[0] = in; - U.c[2] = U.c[1]; - U.c[3] = U.c[0]; - return U.s[1]; - } - /* NOTREACHED */ -} - -static uint32_t la_swap32(uint32_t in) { - union { - uint32_t l; - uint16_t s[2]; - uint8_t c[4]; - } U; - U.l = 1; - if (U.c[0]) { /* Little-endian */ - uint16_t t; - U.l = in; - t = U.s[0]; - U.s[0] = U.s[1]; - U.s[1] = t; - } else if (U.c[3]) { /* Big-endian */ - U.l = in; - U.s[0] = la_swap16(U.s[0]); - U.s[1] = la_swap16(U.s[1]); - } else { /* PDP-endian */ - U.l = in; - } - return U.l; -} - -/* - * Set output format to the selected binary variant - */ -static int -archive_write_set_format_cpio_binary(struct archive *_a, int format) -{ - struct archive_write *a = (struct archive_write *)_a; - struct cpio *cpio; - - if (sizeof(struct cpio_binary_header) != HSIZE) { - archive_set_error(&a->archive, EINVAL, - "Binary cpio format not supported on this platform"); - return (ARCHIVE_FATAL); - } - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_set_format_cpio_binary"); - - /* If someone else was already registered, unregister them. */ - if (a->format_free != NULL) - (a->format_free)(a); - - cpio = (struct cpio *)calloc(1, sizeof(*cpio)); - if (cpio == NULL) { - archive_set_error(&a->archive, ENOMEM, "Can't allocate cpio data"); - return (ARCHIVE_FATAL); - } - a->format_data = cpio; - a->format_name = "cpio"; - a->format_options = archive_write_binary_options; - a->format_write_header = archive_write_binary_header; - a->format_write_data = archive_write_binary_data; - a->format_finish_entry = archive_write_binary_finish_entry; - a->format_close = archive_write_binary_close; - a->format_free = archive_write_binary_free; - a->archive.archive_format = format; - switch (format) { - case ARCHIVE_FORMAT_CPIO_PWB: - a->archive.archive_format_name = "PWB cpio"; - break; - case ARCHIVE_FORMAT_CPIO_BIN_LE: - a->archive.archive_format_name = "7th Edition cpio"; - break; - default: - archive_set_error(&a->archive, EINVAL, "binary format must be 'pwb' or 'bin'"); - return (ARCHIVE_FATAL); - } - return (ARCHIVE_OK); -} - -/* - * Set output format to PWB (6th Edition) binary format - */ -int -archive_write_set_format_cpio_pwb(struct archive *_a) -{ - return archive_write_set_format_cpio_binary(_a, ARCHIVE_FORMAT_CPIO_PWB); -} - -/* - * Set output format to 7th Edition binary format - */ -int -archive_write_set_format_cpio_bin(struct archive *_a) -{ - return archive_write_set_format_cpio_binary(_a, ARCHIVE_FORMAT_CPIO_BIN_LE); -} - -static int -archive_write_binary_options(struct archive_write *a, const char *key, - const char *val) -{ - struct cpio *cpio = (struct cpio *)a->format_data; - int ret = ARCHIVE_FAILED; - - if (strcmp(key, "hdrcharset") == 0) { - if (val == NULL || val[0] == 0) - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "%s: hdrcharset option needs a character-set name", - a->format_name); - else { - cpio->opt_sconv = archive_string_conversion_to_charset( - &a->archive, val, 0); - if (cpio->opt_sconv != NULL) - ret = ARCHIVE_OK; - else - ret = ARCHIVE_FATAL; - } - return (ret); - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -/* - * Ino values are as long as 64 bits on some systems; cpio format - * only allows 16 bits and relies on the ino values to identify hardlinked - * files. So, we can't merely "hash" the ino numbers since collisions - * would corrupt the archive. Instead, we generate synthetic ino values - * to store in the archive and maintain a map of original ino values to - * synthetic ones so we can preserve hardlink information. - * - * TODO: Make this more efficient. It's not as bad as it looks (most - * files don't have any hardlinks and we don't do any work here for those), - * but it wouldn't be hard to do better. - * - * TODO: Work with dev/ino pairs here instead of just ino values. - */ -static int -synthesize_ino_value(struct cpio *cpio, struct archive_entry *entry) -{ - int64_t ino = archive_entry_ino64(entry); - int ino_new; - size_t i; - - /* - * If no index number was given, don't assign one. In - * particular, this handles the end-of-archive marker - * correctly by giving it a zero index value. (This is also - * why we start our synthetic index numbers with one below.) - */ - if (ino == 0) - return (0); - - /* Don't store a mapping if we don't need to. */ - if (archive_entry_nlink(entry) < 2) { - return (int)(++cpio->ino_next); - } - - /* Look up old ino; if we have it, this is a hardlink - * and we reuse the same value. */ - for (i = 0; i < cpio->ino_list_next; ++i) { - if (cpio->ino_list[i].old == ino) - return (cpio->ino_list[i].new); - } - - /* Assign a new index number. */ - ino_new = (int)(++cpio->ino_next); - - /* Ensure space for the new mapping. */ - if (cpio->ino_list_size <= cpio->ino_list_next) { - size_t newsize = cpio->ino_list_size < 512 - ? 512 : cpio->ino_list_size * 2; - void *newlist = realloc(cpio->ino_list, - sizeof(cpio->ino_list[0]) * newsize); - if (newlist == NULL) - return (-1); - - cpio->ino_list_size = newsize; - cpio->ino_list = newlist; - } - - /* Record and return the new value. */ - cpio->ino_list[cpio->ino_list_next].old = ino; - cpio->ino_list[cpio->ino_list_next].new = ino_new; - ++cpio->ino_list_next; - return (ino_new); -} - - -static struct archive_string_conv * -get_sconv(struct archive_write *a) -{ - struct cpio *cpio; - struct archive_string_conv *sconv; - - cpio = (struct cpio *)a->format_data; - sconv = cpio->opt_sconv; - if (sconv == NULL) { - if (!cpio->init_default_conversion) { - cpio->sconv_default = - archive_string_default_conversion_for_write( - &(a->archive)); - cpio->init_default_conversion = 1; - } - sconv = cpio->sconv_default; - } - return (sconv); -} - -static int -archive_write_binary_header(struct archive_write *a, struct archive_entry *entry) -{ - const char *path; - size_t len; - - if (archive_entry_filetype(entry) == 0 && archive_entry_hardlink(entry) == NULL) { - archive_set_error(&a->archive, -1, "Filetype required"); - return (ARCHIVE_FAILED); - } - - if (archive_entry_pathname_l(entry, &path, &len, get_sconv(a)) != 0 - && errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Pathname"); - return (ARCHIVE_FATAL); - } - if (len == 0 || path == NULL || path[0] == '\0') { - archive_set_error(&a->archive, -1, "Pathname required"); - return (ARCHIVE_FAILED); - } - - if (!archive_entry_size_is_set(entry) || archive_entry_size(entry) < 0) { - archive_set_error(&a->archive, -1, "Size required"); - return (ARCHIVE_FAILED); - } - return write_header(a, entry); -} - -static int -write_header(struct archive_write *a, struct archive_entry *entry) -{ - struct cpio *cpio; - const char *p, *path; - int pathlength, ret, ret_final; - int64_t ino; - struct cpio_binary_header h; - struct archive_string_conv *sconv; - struct archive_entry *entry_main; - size_t len; - - cpio = (struct cpio *)a->format_data; - ret_final = ARCHIVE_OK; - sconv = get_sconv(a); - -#if defined(_WIN32) && !defined(__CYGWIN__) - /* Make sure the path separators in pathname, hardlink and symlink - * are all slash '/', not the Windows path separator '\'. */ - entry_main = __la_win_entry_in_posix_pathseparator(entry); - if (entry_main == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate ustar data"); - return(ARCHIVE_FATAL); - } - if (entry != entry_main) - entry = entry_main; - else - entry_main = NULL; -#else - entry_main = NULL; -#endif - - ret = archive_entry_pathname_l(entry, &path, &len, sconv); - if (ret != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Pathname"); - ret_final = ARCHIVE_FATAL; - goto exit_write_header; - } - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate pathname '%s' to %s", - archive_entry_pathname(entry), - archive_string_conversion_charset_name(sconv)); - ret_final = ARCHIVE_WARN; - } - /* Include trailing null */ - pathlength = (int)len + 1; - - h.h_magic = la_swap16(070707); - h.h_dev = la_swap16(archive_entry_dev(entry)); - - ino = synthesize_ino_value(cpio, entry); - if (ino < 0) { - archive_set_error(&a->archive, ENOMEM, - "No memory for ino translation table"); - ret_final = ARCHIVE_FATAL; - goto exit_write_header; - } else if (ino > 077777) { - archive_set_error(&a->archive, ERANGE, - "Too many files for this cpio format"); - ret_final = ARCHIVE_FATAL; - goto exit_write_header; - } - h.h_ino = la_swap16((uint16_t)ino); - - h.h_mode = archive_entry_mode(entry); - if (((h.h_mode & AE_IFMT) == AE_IFSOCK) || ((h.h_mode & AE_IFMT) == AE_IFIFO)) { - archive_set_error(&a->archive, EINVAL, - "sockets and fifos cannot be represented in the binary cpio formats"); - ret_final = ARCHIVE_FATAL; - goto exit_write_header; - } - if (a->archive.archive_format == ARCHIVE_FORMAT_CPIO_PWB) { - if ((h.h_mode & AE_IFMT) == AE_IFLNK) { - archive_set_error(&a->archive, EINVAL, - "symbolic links cannot be represented in the PWB cpio format"); - ret_final = ARCHIVE_FATAL; - goto exit_write_header; - } - /* we could turn off AE_IFREG here, but it does no harm, */ - /* and allows v7 cpio to read the entry without confusion */ - } - h.h_mode = la_swap16(h.h_mode); - - h.h_uid = la_swap16((uint16_t)archive_entry_uid(entry)); - h.h_gid = la_swap16((uint16_t)archive_entry_gid(entry)); - h.h_nlink = la_swap16((uint16_t)archive_entry_nlink(entry)); - - if (archive_entry_filetype(entry) == AE_IFBLK - || archive_entry_filetype(entry) == AE_IFCHR) - h.h_majmin = la_swap16(archive_entry_rdev(entry)); - else - h.h_majmin = 0; - - h.h_mtime = la_swap32((uint32_t)archive_entry_mtime(entry)); - h.h_namesize = la_swap16(pathlength); - - /* Non-regular files don't store bodies. */ - if (archive_entry_filetype(entry) != AE_IFREG) - archive_entry_set_size(entry, 0); - - /* Symlinks get the link written as the body of the entry. */ - ret = archive_entry_symlink_l(entry, &p, &len, sconv); - if (ret != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Linkname"); - ret_final = ARCHIVE_FATAL; - goto exit_write_header; - } - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate linkname '%s' to %s", - archive_entry_symlink(entry), - archive_string_conversion_charset_name(sconv)); - ret_final = ARCHIVE_WARN; - } - - if (len > 0 && p != NULL && *p != '\0') { - if (a->archive.archive_format == ARCHIVE_FORMAT_CPIO_PWB) { - archive_set_error(&a->archive, EINVAL, - "symlinks are not supported by UNIX V6 or by PWB cpio"); - ret_final = ARCHIVE_FATAL; - goto exit_write_header; - } - h.h_filesize = la_swap32((uint32_t)strlen(p)); /* symlink */ - } else { - if ((a->archive.archive_format == ARCHIVE_FORMAT_CPIO_PWB) && - (archive_entry_size(entry) > 256*256*256-1)) { - archive_set_error(&a->archive, ERANGE, - "File is too large for PWB binary cpio format."); - ret_final = ARCHIVE_FAILED; - goto exit_write_header; - } else if (archive_entry_size(entry) > INT32_MAX) { - archive_set_error(&a->archive, ERANGE, - "File is too large for binary cpio format."); - ret_final = ARCHIVE_FAILED; - goto exit_write_header; - } - h.h_filesize = la_swap32((uint32_t)archive_entry_size(entry)); /* file */ - } - - ret = __archive_write_output(a, &h, HSIZE); - if (ret != ARCHIVE_OK) { - ret_final = ARCHIVE_FATAL; - goto exit_write_header; - } - - ret = __archive_write_output(a, path, pathlength); - if ((ret == ARCHIVE_OK) && ((pathlength % 2) != 0)) - ret = __archive_write_nulls(a, 1); - if (ret != ARCHIVE_OK) { - ret_final = ARCHIVE_FATAL; - goto exit_write_header; - } - - cpio->entry_bytes_remaining = archive_entry_size(entry); - if ((cpio->entry_bytes_remaining % 2) != 0) - cpio->entry_bytes_remaining++; - - /* Write the symlink now. */ - if (p != NULL && *p != '\0') { - ret = __archive_write_output(a, p, strlen(p)); - if ((ret == ARCHIVE_OK) && ((strlen(p) % 2) != 0)) - ret = __archive_write_nulls(a, 1); - if (ret != ARCHIVE_OK) { - ret_final = ARCHIVE_FATAL; - goto exit_write_header; - } - } - -exit_write_header: - archive_entry_free(entry_main); - return (ret_final); -} - -static ssize_t -archive_write_binary_data(struct archive_write *a, const void *buff, size_t s) -{ - struct cpio *cpio; - int ret; - - cpio = (struct cpio *)a->format_data; - if (s > cpio->entry_bytes_remaining) - s = (size_t)cpio->entry_bytes_remaining; - - ret = __archive_write_output(a, buff, s); - cpio->entry_bytes_remaining -= s; - if (ret >= 0) - return (s); - else - return (ret); -} - -static int -archive_write_binary_close(struct archive_write *a) -{ - int er; - struct archive_entry *trailer; - - trailer = archive_entry_new2(NULL); - /* nlink = 1 here for GNU cpio compat. */ - archive_entry_set_nlink(trailer, 1); - archive_entry_set_size(trailer, 0); - archive_entry_set_pathname(trailer, "TRAILER!!!"); - er = write_header(a, trailer); - archive_entry_free(trailer); - return (er); -} - -static int -archive_write_binary_free(struct archive_write *a) -{ - struct cpio *cpio; - - cpio = (struct cpio *)a->format_data; - free(cpio->ino_list); - free(cpio); - a->format_data = NULL; - return (ARCHIVE_OK); -} - -static int -archive_write_binary_finish_entry(struct archive_write *a) -{ - struct cpio *cpio; - - cpio = (struct cpio *)a->format_data; - return (__archive_write_nulls(a, - (size_t)cpio->entry_bytes_remaining)); -} diff --git a/thirdparty/libarchive/libarchive/archive_write_set_format_cpio_newc.c b/thirdparty/libarchive/libarchive/archive_write_set_format_cpio_newc.c deleted file mode 100644 index f0f39809d..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_set_format_cpio_newc.c +++ /dev/null @@ -1,457 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2006 Rudolf Marek SYSGO s.r.o. - * Copyright (c) 2011-2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_cpio_newc.c 201160 2009-12-29 05:41:57Z kientzle $"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" -#include "archive_entry_locale.h" -#include "archive_private.h" -#include "archive_write_private.h" -#include "archive_write_set_format_private.h" - -static ssize_t archive_write_newc_data(struct archive_write *, - const void *buff, size_t s); -static int archive_write_newc_close(struct archive_write *); -static int archive_write_newc_free(struct archive_write *); -static int archive_write_newc_finish_entry(struct archive_write *); -static int archive_write_newc_header(struct archive_write *, - struct archive_entry *); -static int archive_write_newc_options(struct archive_write *, - const char *, const char *); -static int format_hex(int64_t, void *, int); -static int64_t format_hex_recursive(int64_t, char *, int); -static int write_header(struct archive_write *, struct archive_entry *); - -struct cpio { - uint64_t entry_bytes_remaining; - int padding; - - struct archive_string_conv *opt_sconv; - struct archive_string_conv *sconv_default; - int init_default_conversion; -}; - -#define c_magic_offset 0 -#define c_magic_size 6 -#define c_ino_offset 6 -#define c_ino_size 8 -#define c_mode_offset 14 -#define c_mode_size 8 -#define c_uid_offset 22 -#define c_uid_size 8 -#define c_gid_offset 30 -#define c_gid_size 8 -#define c_nlink_offset 38 -#define c_nlink_size 8 -#define c_mtime_offset 46 -#define c_mtime_size 8 -#define c_filesize_offset 54 -#define c_filesize_size 8 -#define c_devmajor_offset 62 -#define c_devmajor_size 8 -#define c_devminor_offset 70 -#define c_devminor_size 8 -#define c_rdevmajor_offset 78 -#define c_rdevmajor_size 8 -#define c_rdevminor_offset 86 -#define c_rdevminor_size 8 -#define c_namesize_offset 94 -#define c_namesize_size 8 -#define c_checksum_offset 102 -#define c_checksum_size 8 -#define c_header_size 110 - -/* Logic trick: difference between 'n' and next multiple of 4 */ -#define PAD4(n) (3 & (1 + ~(n))) - -/* - * Set output format to 'cpio' format. - */ -int -archive_write_set_format_cpio_newc(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - struct cpio *cpio; - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_set_format_cpio_newc"); - - /* If someone else was already registered, unregister them. */ - if (a->format_free != NULL) - (a->format_free)(a); - - cpio = (struct cpio *)calloc(1, sizeof(*cpio)); - if (cpio == NULL) { - archive_set_error(&a->archive, ENOMEM, "Can't allocate cpio data"); - return (ARCHIVE_FATAL); - } - a->format_data = cpio; - a->format_name = "cpio"; - a->format_options = archive_write_newc_options; - a->format_write_header = archive_write_newc_header; - a->format_write_data = archive_write_newc_data; - a->format_finish_entry = archive_write_newc_finish_entry; - a->format_close = archive_write_newc_close; - a->format_free = archive_write_newc_free; - a->archive.archive_format = ARCHIVE_FORMAT_CPIO_SVR4_NOCRC; - a->archive.archive_format_name = "SVR4 cpio nocrc"; - return (ARCHIVE_OK); -} - -static int -archive_write_newc_options(struct archive_write *a, const char *key, - const char *val) -{ - struct cpio *cpio = (struct cpio *)a->format_data; - int ret = ARCHIVE_FAILED; - - if (strcmp(key, "hdrcharset") == 0) { - if (val == NULL || val[0] == 0) - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "%s: hdrcharset option needs a character-set name", - a->format_name); - else { - cpio->opt_sconv = archive_string_conversion_to_charset( - &a->archive, val, 0); - if (cpio->opt_sconv != NULL) - ret = ARCHIVE_OK; - else - ret = ARCHIVE_FATAL; - } - return (ret); - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -static struct archive_string_conv * -get_sconv(struct archive_write *a) -{ - struct cpio *cpio; - struct archive_string_conv *sconv; - - cpio = (struct cpio *)a->format_data; - sconv = cpio->opt_sconv; - if (sconv == NULL) { - if (!cpio->init_default_conversion) { - cpio->sconv_default = - archive_string_default_conversion_for_write( - &(a->archive)); - cpio->init_default_conversion = 1; - } - sconv = cpio->sconv_default; - } - return (sconv); -} - -static int -archive_write_newc_header(struct archive_write *a, struct archive_entry *entry) -{ - const char *path; - size_t len; - - if (archive_entry_filetype(entry) == 0 && archive_entry_hardlink(entry) == NULL) { - archive_set_error(&a->archive, -1, "Filetype required"); - return (ARCHIVE_FAILED); - } - - if (archive_entry_pathname_l(entry, &path, &len, get_sconv(a)) != 0 - && errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Pathname"); - return (ARCHIVE_FATAL); - } - if (len == 0 || path == NULL || path[0] == '\0') { - archive_set_error(&a->archive, -1, "Pathname required"); - return (ARCHIVE_FAILED); - } - - if (archive_entry_hardlink(entry) == NULL - && (!archive_entry_size_is_set(entry) || archive_entry_size(entry) < 0)) { - archive_set_error(&a->archive, -1, "Size required"); - return (ARCHIVE_FAILED); - } - return write_header(a, entry); -} - -static int -write_header(struct archive_write *a, struct archive_entry *entry) -{ - int64_t ino; - struct cpio *cpio; - const char *p, *path; - int pathlength, ret, ret_final; - char h[c_header_size]; - struct archive_string_conv *sconv; - struct archive_entry *entry_main; - size_t len; - int pad; - - cpio = (struct cpio *)a->format_data; - ret_final = ARCHIVE_OK; - sconv = get_sconv(a); - -#if defined(_WIN32) && !defined(__CYGWIN__) - /* Make sure the path separators in pathname, hardlink and symlink - * are all slash '/', not the Windows path separator '\'. */ - entry_main = __la_win_entry_in_posix_pathseparator(entry); - if (entry_main == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate ustar data"); - return(ARCHIVE_FATAL); - } - if (entry != entry_main) - entry = entry_main; - else - entry_main = NULL; -#else - entry_main = NULL; -#endif - - ret = archive_entry_pathname_l(entry, &path, &len, sconv); - if (ret != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Pathname"); - ret_final = ARCHIVE_FATAL; - goto exit_write_header; - } - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate pathname '%s' to %s", - archive_entry_pathname(entry), - archive_string_conversion_charset_name(sconv)); - ret_final = ARCHIVE_WARN; - } - pathlength = (int)len + 1; /* Include trailing null. */ - - memset(h, 0, c_header_size); - format_hex(0x070701, h + c_magic_offset, c_magic_size); - format_hex(archive_entry_devmajor(entry), h + c_devmajor_offset, - c_devmajor_size); - format_hex(archive_entry_devminor(entry), h + c_devminor_offset, - c_devminor_size); - - ino = archive_entry_ino64(entry); - if (ino > 0xffffffff) { - archive_set_error(&a->archive, ERANGE, - "large inode number truncated"); - ret_final = ARCHIVE_WARN; - } - - /* TODO: Set ret_final to ARCHIVE_WARN if any of these overflow. */ - format_hex(ino & 0xffffffff, h + c_ino_offset, c_ino_size); - format_hex(archive_entry_mode(entry), h + c_mode_offset, c_mode_size); - format_hex(archive_entry_uid(entry), h + c_uid_offset, c_uid_size); - format_hex(archive_entry_gid(entry), h + c_gid_offset, c_gid_size); - format_hex(archive_entry_nlink(entry), h + c_nlink_offset, c_nlink_size); - if (archive_entry_filetype(entry) == AE_IFBLK - || archive_entry_filetype(entry) == AE_IFCHR) { - format_hex(archive_entry_rdevmajor(entry), h + c_rdevmajor_offset, c_rdevmajor_size); - format_hex(archive_entry_rdevminor(entry), h + c_rdevminor_offset, c_rdevminor_size); - } else { - format_hex(0, h + c_rdevmajor_offset, c_rdevmajor_size); - format_hex(0, h + c_rdevminor_offset, c_rdevminor_size); - } - format_hex(archive_entry_mtime(entry), h + c_mtime_offset, c_mtime_size); - format_hex(pathlength, h + c_namesize_offset, c_namesize_size); - format_hex(0, h + c_checksum_offset, c_checksum_size); - - /* Non-regular files don't store bodies. */ - if (archive_entry_filetype(entry) != AE_IFREG) - archive_entry_set_size(entry, 0); - - /* Symlinks get the link written as the body of the entry. */ - ret = archive_entry_symlink_l(entry, &p, &len, sconv); - if (ret != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Likname"); - ret_final = ARCHIVE_FATAL; - goto exit_write_header; - } - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate linkname '%s' to %s", - archive_entry_symlink(entry), - archive_string_conversion_charset_name(sconv)); - ret_final = ARCHIVE_WARN; - } - if (len > 0 && p != NULL && *p != '\0') - ret = format_hex(strlen(p), h + c_filesize_offset, - c_filesize_size); - else - ret = format_hex(archive_entry_size(entry), - h + c_filesize_offset, c_filesize_size); - if (ret) { - archive_set_error(&a->archive, ERANGE, - "File is too large for this format."); - ret_final = ARCHIVE_FAILED; - goto exit_write_header; - } - - ret = __archive_write_output(a, h, c_header_size); - if (ret != ARCHIVE_OK) { - ret_final = ARCHIVE_FATAL; - goto exit_write_header; - } - - /* Pad pathname to even length. */ - ret = __archive_write_output(a, path, pathlength); - if (ret != ARCHIVE_OK) { - ret_final = ARCHIVE_FATAL; - goto exit_write_header; - } - pad = PAD4(pathlength + c_header_size); - if (pad) { - ret = __archive_write_output(a, "\0\0\0", pad); - if (ret != ARCHIVE_OK) { - ret_final = ARCHIVE_FATAL; - goto exit_write_header; - } - } - - cpio->entry_bytes_remaining = archive_entry_size(entry); - cpio->padding = (int)PAD4(cpio->entry_bytes_remaining); - - /* Write the symlink now. */ - if (p != NULL && *p != '\0') { - ret = __archive_write_output(a, p, strlen(p)); - if (ret != ARCHIVE_OK) { - ret_final = ARCHIVE_FATAL; - goto exit_write_header; - } - pad = PAD4(strlen(p)); - ret = __archive_write_output(a, "\0\0\0", pad); - if (ret != ARCHIVE_OK) { - ret_final = ARCHIVE_FATAL; - goto exit_write_header; - } - } -exit_write_header: - archive_entry_free(entry_main); - return (ret_final); -} - -static ssize_t -archive_write_newc_data(struct archive_write *a, const void *buff, size_t s) -{ - struct cpio *cpio; - int ret; - - cpio = (struct cpio *)a->format_data; - if (s > cpio->entry_bytes_remaining) - s = (size_t)cpio->entry_bytes_remaining; - - ret = __archive_write_output(a, buff, s); - cpio->entry_bytes_remaining -= s; - if (ret >= 0) - return (s); - else - return (ret); -} - -/* - * Format a number into the specified field. - */ -static int -format_hex(int64_t v, void *p, int digits) -{ - int64_t max; - int ret; - - max = (((int64_t)1) << (digits * 4)) - 1; - if (v >= 0 && v <= max) { - format_hex_recursive(v, (char *)p, digits); - ret = 0; - } else { - format_hex_recursive(max, (char *)p, digits); - ret = -1; - } - return (ret); -} - -static int64_t -format_hex_recursive(int64_t v, char *p, int s) -{ - if (s == 0) - return (v); - v = format_hex_recursive(v, p+1, s-1); - *p = "0123456789abcdef"[v & 0xf]; - return (v >> 4); -} - -static int -archive_write_newc_close(struct archive_write *a) -{ - int er; - struct archive_entry *trailer; - - trailer = archive_entry_new(); - archive_entry_set_nlink(trailer, 1); - archive_entry_set_size(trailer, 0); - archive_entry_set_pathname(trailer, "TRAILER!!!"); - /* Bypass the required data checks. */ - er = write_header(a, trailer); - archive_entry_free(trailer); - return (er); -} - -static int -archive_write_newc_free(struct archive_write *a) -{ - struct cpio *cpio; - - cpio = (struct cpio *)a->format_data; - free(cpio); - a->format_data = NULL; - return (ARCHIVE_OK); -} - -static int -archive_write_newc_finish_entry(struct archive_write *a) -{ - struct cpio *cpio; - - cpio = (struct cpio *)a->format_data; - return (__archive_write_nulls(a, - (size_t)cpio->entry_bytes_remaining + cpio->padding)); -} diff --git a/thirdparty/libarchive/libarchive/archive_write_set_format_cpio_odc.c b/thirdparty/libarchive/libarchive/archive_write_set_format_cpio_odc.c deleted file mode 100644 index 091925a2f..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_set_format_cpio_odc.c +++ /dev/null @@ -1,500 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2011-2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_cpio.c 201170 2009-12-29 06:34:23Z kientzle $"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" -#include "archive_entry_locale.h" -#include "archive_private.h" -#include "archive_write_private.h" -#include "archive_write_set_format_private.h" - -static ssize_t archive_write_odc_data(struct archive_write *, - const void *buff, size_t s); -static int archive_write_odc_close(struct archive_write *); -static int archive_write_odc_free(struct archive_write *); -static int archive_write_odc_finish_entry(struct archive_write *); -static int archive_write_odc_header(struct archive_write *, - struct archive_entry *); -static int archive_write_odc_options(struct archive_write *, - const char *, const char *); -static int format_octal(int64_t, void *, int); -static int64_t format_octal_recursive(int64_t, char *, int); -static int write_header(struct archive_write *, struct archive_entry *); - -struct cpio { - uint64_t entry_bytes_remaining; - - int64_t ino_next; - - struct { int64_t old; int new;} *ino_list; - size_t ino_list_size; - size_t ino_list_next; - - struct archive_string_conv *opt_sconv; - struct archive_string_conv *sconv_default; - int init_default_conversion; -}; - -#define c_magic_offset 0 -#define c_magic_size 6 -#define c_dev_offset 6 -#define c_dev_size 6 -#define c_ino_offset 12 -#define c_ino_size 6 -#define c_mode_offset 18 -#define c_mode_size 6 -#define c_uid_offset 24 -#define c_uid_size 6 -#define c_gid_offset 30 -#define c_gid_size 6 -#define c_nlink_offset 36 -#define c_nlink_size 6 -#define c_rdev_offset 42 -#define c_rdev_size 6 -#define c_mtime_offset 48 -#define c_mtime_size 11 -#define c_namesize_offset 59 -#define c_namesize_size 6 -#define c_filesize_offset 65 -#define c_filesize_size 11 - -/* - * Set output format to 'cpio' format. - */ -int -archive_write_set_format_cpio_odc(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - struct cpio *cpio; - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_set_format_cpio_odc"); - - /* If someone else was already registered, unregister them. */ - if (a->format_free != NULL) - (a->format_free)(a); - - cpio = (struct cpio *)calloc(1, sizeof(*cpio)); - if (cpio == NULL) { - archive_set_error(&a->archive, ENOMEM, "Can't allocate cpio data"); - return (ARCHIVE_FATAL); - } - a->format_data = cpio; - a->format_name = "cpio"; - a->format_options = archive_write_odc_options; - a->format_write_header = archive_write_odc_header; - a->format_write_data = archive_write_odc_data; - a->format_finish_entry = archive_write_odc_finish_entry; - a->format_close = archive_write_odc_close; - a->format_free = archive_write_odc_free; - a->archive.archive_format = ARCHIVE_FORMAT_CPIO_POSIX; - a->archive.archive_format_name = "POSIX cpio"; - return (ARCHIVE_OK); -} - -static int -archive_write_odc_options(struct archive_write *a, const char *key, - const char *val) -{ - struct cpio *cpio = (struct cpio *)a->format_data; - int ret = ARCHIVE_FAILED; - - if (strcmp(key, "hdrcharset") == 0) { - if (val == NULL || val[0] == 0) - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "%s: hdrcharset option needs a character-set name", - a->format_name); - else { - cpio->opt_sconv = archive_string_conversion_to_charset( - &a->archive, val, 0); - if (cpio->opt_sconv != NULL) - ret = ARCHIVE_OK; - else - ret = ARCHIVE_FATAL; - } - return (ret); - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -/* - * Ino values are as long as 64 bits on some systems; cpio format - * only allows 18 bits and relies on the ino values to identify hardlinked - * files. So, we can't merely "hash" the ino numbers since collisions - * would corrupt the archive. Instead, we generate synthetic ino values - * to store in the archive and maintain a map of original ino values to - * synthetic ones so we can preserve hardlink information. - * - * TODO: Make this more efficient. It's not as bad as it looks (most - * files don't have any hardlinks and we don't do any work here for those), - * but it wouldn't be hard to do better. - * - * TODO: Work with dev/ino pairs here instead of just ino values. - */ -static int -synthesize_ino_value(struct cpio *cpio, struct archive_entry *entry) -{ - int64_t ino = archive_entry_ino64(entry); - int ino_new; - size_t i; - - /* - * If no index number was given, don't assign one. In - * particular, this handles the end-of-archive marker - * correctly by giving it a zero index value. (This is also - * why we start our synthetic index numbers with one below.) - */ - if (ino == 0) - return (0); - - /* Don't store a mapping if we don't need to. */ - if (archive_entry_nlink(entry) < 2) { - return (int)(++cpio->ino_next); - } - - /* Look up old ino; if we have it, this is a hardlink - * and we reuse the same value. */ - for (i = 0; i < cpio->ino_list_next; ++i) { - if (cpio->ino_list[i].old == ino) - return (cpio->ino_list[i].new); - } - - /* Assign a new index number. */ - ino_new = (int)(++cpio->ino_next); - - /* Ensure space for the new mapping. */ - if (cpio->ino_list_size <= cpio->ino_list_next) { - size_t newsize = cpio->ino_list_size < 512 - ? 512 : cpio->ino_list_size * 2; - void *newlist = realloc(cpio->ino_list, - sizeof(cpio->ino_list[0]) * newsize); - if (newlist == NULL) - return (-1); - - cpio->ino_list_size = newsize; - cpio->ino_list = newlist; - } - - /* Record and return the new value. */ - cpio->ino_list[cpio->ino_list_next].old = ino; - cpio->ino_list[cpio->ino_list_next].new = ino_new; - ++cpio->ino_list_next; - return (ino_new); -} - - -static struct archive_string_conv * -get_sconv(struct archive_write *a) -{ - struct cpio *cpio; - struct archive_string_conv *sconv; - - cpio = (struct cpio *)a->format_data; - sconv = cpio->opt_sconv; - if (sconv == NULL) { - if (!cpio->init_default_conversion) { - cpio->sconv_default = - archive_string_default_conversion_for_write( - &(a->archive)); - cpio->init_default_conversion = 1; - } - sconv = cpio->sconv_default; - } - return (sconv); -} - -static int -archive_write_odc_header(struct archive_write *a, struct archive_entry *entry) -{ - const char *path; - size_t len; - - if (archive_entry_filetype(entry) == 0 && archive_entry_hardlink(entry) == NULL) { - archive_set_error(&a->archive, -1, "Filetype required"); - return (ARCHIVE_FAILED); - } - - if (archive_entry_pathname_l(entry, &path, &len, get_sconv(a)) != 0 - && errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Pathname"); - return (ARCHIVE_FATAL); - } - if (len == 0 || path == NULL || path[0] == '\0') { - archive_set_error(&a->archive, -1, "Pathname required"); - return (ARCHIVE_FAILED); - } - - if (!archive_entry_size_is_set(entry) || archive_entry_size(entry) < 0) { - archive_set_error(&a->archive, -1, "Size required"); - return (ARCHIVE_FAILED); - } - return write_header(a, entry); -} - -static int -write_header(struct archive_write *a, struct archive_entry *entry) -{ - struct cpio *cpio; - const char *p, *path; - int pathlength, ret, ret_final; - int64_t ino; - char h[76]; - struct archive_string_conv *sconv; - struct archive_entry *entry_main; - size_t len; - - cpio = (struct cpio *)a->format_data; - ret_final = ARCHIVE_OK; - sconv = get_sconv(a); - -#if defined(_WIN32) && !defined(__CYGWIN__) - /* Make sure the path separators in pathname, hardlink and symlink - * are all slash '/', not the Windows path separator '\'. */ - entry_main = __la_win_entry_in_posix_pathseparator(entry); - if (entry_main == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate ustar data"); - return(ARCHIVE_FATAL); - } - if (entry != entry_main) - entry = entry_main; - else - entry_main = NULL; -#else - entry_main = NULL; -#endif - - ret = archive_entry_pathname_l(entry, &path, &len, sconv); - if (ret != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Pathname"); - ret_final = ARCHIVE_FATAL; - goto exit_write_header; - } - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate pathname '%s' to %s", - archive_entry_pathname(entry), - archive_string_conversion_charset_name(sconv)); - ret_final = ARCHIVE_WARN; - } - /* Include trailing null. */ - pathlength = (int)len + 1; - - memset(h, 0, sizeof(h)); - format_octal(070707, h + c_magic_offset, c_magic_size); - format_octal(archive_entry_dev(entry), h + c_dev_offset, c_dev_size); - - ino = synthesize_ino_value(cpio, entry); - if (ino < 0) { - archive_set_error(&a->archive, ENOMEM, - "No memory for ino translation table"); - ret_final = ARCHIVE_FATAL; - goto exit_write_header; - } else if (ino > 0777777) { - archive_set_error(&a->archive, ERANGE, - "Too many files for this cpio format"); - ret_final = ARCHIVE_FATAL; - goto exit_write_header; - } - format_octal(ino & 0777777, h + c_ino_offset, c_ino_size); - - /* TODO: Set ret_final to ARCHIVE_WARN if any of these overflow. */ - format_octal(archive_entry_mode(entry), h + c_mode_offset, c_mode_size); - format_octal(archive_entry_uid(entry), h + c_uid_offset, c_uid_size); - format_octal(archive_entry_gid(entry), h + c_gid_offset, c_gid_size); - format_octal(archive_entry_nlink(entry), h + c_nlink_offset, c_nlink_size); - if (archive_entry_filetype(entry) == AE_IFBLK - || archive_entry_filetype(entry) == AE_IFCHR) - format_octal(archive_entry_rdev(entry), h + c_rdev_offset, c_rdev_size); - else - format_octal(0, h + c_rdev_offset, c_rdev_size); - format_octal(archive_entry_mtime(entry), h + c_mtime_offset, c_mtime_size); - format_octal(pathlength, h + c_namesize_offset, c_namesize_size); - - /* Non-regular files don't store bodies. */ - if (archive_entry_filetype(entry) != AE_IFREG) - archive_entry_set_size(entry, 0); - - /* Symlinks get the link written as the body of the entry. */ - ret = archive_entry_symlink_l(entry, &p, &len, sconv); - if (ret != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Linkname"); - ret_final = ARCHIVE_FATAL; - goto exit_write_header; - } - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate linkname '%s' to %s", - archive_entry_symlink(entry), - archive_string_conversion_charset_name(sconv)); - ret_final = ARCHIVE_WARN; - } - if (len > 0 && p != NULL && *p != '\0') - ret = format_octal(strlen(p), h + c_filesize_offset, - c_filesize_size); - else - ret = format_octal(archive_entry_size(entry), - h + c_filesize_offset, c_filesize_size); - if (ret) { - archive_set_error(&a->archive, ERANGE, - "File is too large for cpio format."); - ret_final = ARCHIVE_FAILED; - goto exit_write_header; - } - - ret = __archive_write_output(a, h, sizeof(h)); - if (ret != ARCHIVE_OK) { - ret_final = ARCHIVE_FATAL; - goto exit_write_header; - } - - ret = __archive_write_output(a, path, pathlength); - if (ret != ARCHIVE_OK) { - ret_final = ARCHIVE_FATAL; - goto exit_write_header; - } - - cpio->entry_bytes_remaining = archive_entry_size(entry); - - /* Write the symlink now. */ - if (p != NULL && *p != '\0') { - ret = __archive_write_output(a, p, strlen(p)); - if (ret != ARCHIVE_OK) { - ret_final = ARCHIVE_FATAL; - goto exit_write_header; - } - } -exit_write_header: - archive_entry_free(entry_main); - return (ret_final); -} - -static ssize_t -archive_write_odc_data(struct archive_write *a, const void *buff, size_t s) -{ - struct cpio *cpio; - int ret; - - cpio = (struct cpio *)a->format_data; - if (s > cpio->entry_bytes_remaining) - s = (size_t)cpio->entry_bytes_remaining; - - ret = __archive_write_output(a, buff, s); - cpio->entry_bytes_remaining -= s; - if (ret >= 0) - return (s); - else - return (ret); -} - -/* - * Format a number into the specified field. - */ -static int -format_octal(int64_t v, void *p, int digits) -{ - int64_t max; - int ret; - - max = (((int64_t)1) << (digits * 3)) - 1; - if (v >= 0 && v <= max) { - format_octal_recursive(v, (char *)p, digits); - ret = 0; - } else { - format_octal_recursive(max, (char *)p, digits); - ret = -1; - } - return (ret); -} - -static int64_t -format_octal_recursive(int64_t v, char *p, int s) -{ - if (s == 0) - return (v); - v = format_octal_recursive(v, p+1, s-1); - *p = '0' + ((char)v & 7); - return (v >> 3); -} - -static int -archive_write_odc_close(struct archive_write *a) -{ - int er; - struct archive_entry *trailer; - - trailer = archive_entry_new2(NULL); - /* nlink = 1 here for GNU cpio compat. */ - archive_entry_set_nlink(trailer, 1); - archive_entry_set_size(trailer, 0); - archive_entry_set_pathname(trailer, "TRAILER!!!"); - er = write_header(a, trailer); - archive_entry_free(trailer); - return (er); -} - -static int -archive_write_odc_free(struct archive_write *a) -{ - struct cpio *cpio; - - cpio = (struct cpio *)a->format_data; - free(cpio->ino_list); - free(cpio); - a->format_data = NULL; - return (ARCHIVE_OK); -} - -static int -archive_write_odc_finish_entry(struct archive_write *a) -{ - struct cpio *cpio; - - cpio = (struct cpio *)a->format_data; - return (__archive_write_nulls(a, - (size_t)cpio->entry_bytes_remaining)); -} diff --git a/thirdparty/libarchive/libarchive/archive_write_set_format_filter_by_ext.c b/thirdparty/libarchive/libarchive/archive_write_set_format_filter_by_ext.c deleted file mode 100644 index 9fe21e454..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_set_format_filter_by_ext.c +++ /dev/null @@ -1,142 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2015 Okhotnikov Kirill - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_by_name.c 201168 2009-12-29 06:15:32Z kientzle $"); - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "archive.h" -#include "archive_private.h" - -/* A table that maps names to functions. */ -static const -struct { const char *name; int (*format)(struct archive *); int (*filter)(struct archive *); } names[] = -{ - { ".7z", archive_write_set_format_7zip, archive_write_add_filter_none}, - { ".zip", archive_write_set_format_zip, archive_write_add_filter_none}, - { ".jar", archive_write_set_format_zip, archive_write_add_filter_none}, - { ".cpio", archive_write_set_format_cpio, archive_write_add_filter_none}, - { ".iso", archive_write_set_format_iso9660, archive_write_add_filter_none}, -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) - { ".a", archive_write_set_format_ar_bsd, archive_write_add_filter_none}, - { ".ar", archive_write_set_format_ar_bsd, archive_write_add_filter_none}, -#else - { ".a", archive_write_set_format_ar_svr4, archive_write_add_filter_none}, - { ".ar", archive_write_set_format_ar_svr4, archive_write_add_filter_none}, -#endif - { ".tar", archive_write_set_format_pax_restricted, archive_write_add_filter_none}, - { ".tgz", archive_write_set_format_pax_restricted, archive_write_add_filter_gzip}, - { ".tar.gz", archive_write_set_format_pax_restricted, archive_write_add_filter_gzip}, - { ".tar.bz2", archive_write_set_format_pax_restricted, archive_write_add_filter_bzip2}, - { ".tar.xz", archive_write_set_format_pax_restricted, archive_write_add_filter_xz}, - { NULL, NULL, NULL } -}; - -static -int cmpsuff(const char *str, const char *suffix) -{ - size_t length_str, length_suffix; - - if ((str == NULL) || (suffix == NULL)) - return -1; - - length_str = strlen(str); - length_suffix = strlen(suffix); - - if (length_str >= length_suffix) { - return strcmp(str + (length_str - length_suffix), suffix); - } else { - return -1; - } -} - -static int get_array_index(const char *name) -{ - int i; - - for (i = 0; names[i].name != NULL; i++) - { - if (cmpsuff(name, names[i].name) == 0) - return i; - } - return -1; - -} - -int -archive_write_set_format_filter_by_ext(struct archive *a, const char *filename) -{ - int names_index = get_array_index(filename); - - if (names_index >= 0) - { - int format_state = (names[names_index].format)(a); - if (format_state == ARCHIVE_OK) - return ((names[names_index].filter)(a)); - else - return format_state; - } - - archive_set_error(a, EINVAL, "No such format '%s'", filename); - a->state = ARCHIVE_STATE_FATAL; - return (ARCHIVE_FATAL); -} - -int -archive_write_set_format_filter_by_ext_def(struct archive *a, const char *filename, const char * def_ext) -{ - int names_index = get_array_index(filename); - - if (names_index < 0) - names_index = get_array_index(def_ext); - - if (names_index >= 0) - { - int format_state = (names[names_index].format)(a); - if (format_state == ARCHIVE_OK) - return ((names[names_index].filter)(a)); - else - return format_state; - } - - archive_set_error(a, EINVAL, "No such format '%s'", filename); - a->state = ARCHIVE_STATE_FATAL; - return (ARCHIVE_FATAL); -} - - - - diff --git a/thirdparty/libarchive/libarchive/archive_write_set_format_gnutar.c b/thirdparty/libarchive/libarchive/archive_write_set_format_gnutar.c deleted file mode 100644 index ec29c5c41..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_set_format_gnutar.c +++ /dev/null @@ -1,755 +0,0 @@ -/*- - * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). - * Author: Jonas Gastal - * Copyright (c) 2011-2012 Michihiro NAKAJIMA - * - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_gnu_tar.c 191579 2009-04-27 18:35:03Z gastal $"); - - -#ifdef HAVE_ERRNO_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" -#include "archive_entry_locale.h" -#include "archive_private.h" -#include "archive_write_private.h" -#include "archive_write_set_format_private.h" - -struct gnutar { - uint64_t entry_bytes_remaining; - uint64_t entry_padding; - const char * linkname; - size_t linkname_length; - const char * pathname; - size_t pathname_length; - const char * uname; - size_t uname_length; - const char * gname; - size_t gname_length; - struct archive_string_conv *opt_sconv; - struct archive_string_conv *sconv_default; - int init_default_conversion; -}; - -/* - * Define structure of GNU tar header. - */ -#define GNUTAR_name_offset 0 -#define GNUTAR_name_size 100 -#define GNUTAR_mode_offset 100 -#define GNUTAR_mode_size 7 -#define GNUTAR_mode_max_size 8 -#define GNUTAR_uid_offset 108 -#define GNUTAR_uid_size 7 -#define GNUTAR_uid_max_size 8 -#define GNUTAR_gid_offset 116 -#define GNUTAR_gid_size 7 -#define GNUTAR_gid_max_size 8 -#define GNUTAR_size_offset 124 -#define GNUTAR_size_size 11 -#define GNUTAR_size_max_size 12 -#define GNUTAR_mtime_offset 136 -#define GNUTAR_mtime_size 11 -#define GNUTAR_mtime_max_size 11 -#define GNUTAR_checksum_offset 148 -#define GNUTAR_checksum_size 8 -#define GNUTAR_typeflag_offset 156 -#define GNUTAR_typeflag_size 1 -#define GNUTAR_linkname_offset 157 -#define GNUTAR_linkname_size 100 -#define GNUTAR_magic_offset 257 -#define GNUTAR_magic_size 6 -#define GNUTAR_version_offset 263 -#define GNUTAR_version_size 2 -#define GNUTAR_uname_offset 265 -#define GNUTAR_uname_size 32 -#define GNUTAR_gname_offset 297 -#define GNUTAR_gname_size 32 -#define GNUTAR_rdevmajor_offset 329 -#define GNUTAR_rdevmajor_size 6 -#define GNUTAR_rdevmajor_max_size 8 -#define GNUTAR_rdevminor_offset 337 -#define GNUTAR_rdevminor_size 6 -#define GNUTAR_rdevminor_max_size 8 - -/* - * A filled-in copy of the header for initialization. - */ -static const char template_header[] = { - /* name: 100 bytes */ - 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,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, - /* Mode, null termination: 8 bytes */ - '0','0','0','0','0','0', '0','\0', - /* uid, null termination: 8 bytes */ - '0','0','0','0','0','0', '0','\0', - /* gid, null termination: 8 bytes */ - '0','0','0','0','0','0', '0','\0', - /* size, space termination: 12 bytes */ - '0','0','0','0','0','0','0','0','0','0','0', '\0', - /* mtime, space termination: 12 bytes */ - '0','0','0','0','0','0','0','0','0','0','0', '\0', - /* Initial checksum value: 8 spaces */ - ' ',' ',' ',' ',' ',' ',' ',' ', - /* Typeflag: 1 byte */ - '0', /* '0' = regular file */ - /* Linkname: 100 bytes */ - 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,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, - /* Magic: 8 bytes */ - 'u','s','t','a','r',' ', ' ','\0', - /* Uname: 32 bytes */ - 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, - /* Gname: 32 bytes */ - 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, - /* rdevmajor + null padding: 8 bytes */ - '\0','\0','\0','\0','\0','\0', '\0','\0', - /* rdevminor + null padding: 8 bytes */ - '\0','\0','\0','\0','\0','\0', '\0','\0', - /* Padding: 167 bytes */ - 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,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,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 -}; - -static int archive_write_gnutar_options(struct archive_write *, - const char *, const char *); -static int archive_format_gnutar_header(struct archive_write *, char h[512], - struct archive_entry *, int tartype); -static int archive_write_gnutar_header(struct archive_write *, - struct archive_entry *entry); -static ssize_t archive_write_gnutar_data(struct archive_write *a, const void *buff, - size_t s); -static int archive_write_gnutar_free(struct archive_write *); -static int archive_write_gnutar_close(struct archive_write *); -static int archive_write_gnutar_finish_entry(struct archive_write *); -static int format_256(int64_t, char *, int); -static int format_number(int64_t, char *, int size, int maxsize); -static int format_octal(int64_t, char *, int); - -/* - * Set output format to 'GNU tar' format. - */ -int -archive_write_set_format_gnutar(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - struct gnutar *gnutar; - - gnutar = (struct gnutar *)calloc(1, sizeof(*gnutar)); - if (gnutar == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate gnutar data"); - return (ARCHIVE_FATAL); - } - a->format_data = gnutar; - a->format_name = "gnutar"; - a->format_options = archive_write_gnutar_options; - a->format_write_header = archive_write_gnutar_header; - a->format_write_data = archive_write_gnutar_data; - a->format_close = archive_write_gnutar_close; - a->format_free = archive_write_gnutar_free; - a->format_finish_entry = archive_write_gnutar_finish_entry; - a->archive.archive_format = ARCHIVE_FORMAT_TAR_GNUTAR; - a->archive.archive_format_name = "GNU tar"; - return (ARCHIVE_OK); -} - -static int -archive_write_gnutar_options(struct archive_write *a, const char *key, - const char *val) -{ - struct gnutar *gnutar = (struct gnutar *)a->format_data; - int ret = ARCHIVE_FAILED; - - if (strcmp(key, "hdrcharset") == 0) { - if (val == NULL || val[0] == 0) - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "%s: hdrcharset option needs a character-set name", - a->format_name); - else { - gnutar->opt_sconv = archive_string_conversion_to_charset( - &a->archive, val, 0); - if (gnutar->opt_sconv != NULL) - ret = ARCHIVE_OK; - else - ret = ARCHIVE_FATAL; - } - return (ret); - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -static int -archive_write_gnutar_close(struct archive_write *a) -{ - return (__archive_write_nulls(a, 512*2)); -} - -static int -archive_write_gnutar_free(struct archive_write *a) -{ - struct gnutar *gnutar; - - gnutar = (struct gnutar *)a->format_data; - free(gnutar); - a->format_data = NULL; - return (ARCHIVE_OK); -} - -static int -archive_write_gnutar_finish_entry(struct archive_write *a) -{ - struct gnutar *gnutar; - int ret; - - gnutar = (struct gnutar *)a->format_data; - ret = __archive_write_nulls(a, (size_t) - (gnutar->entry_bytes_remaining + gnutar->entry_padding)); - gnutar->entry_bytes_remaining = gnutar->entry_padding = 0; - return (ret); -} - -static ssize_t -archive_write_gnutar_data(struct archive_write *a, const void *buff, size_t s) -{ - struct gnutar *gnutar; - int ret; - - gnutar = (struct gnutar *)a->format_data; - if (s > gnutar->entry_bytes_remaining) - s = (size_t)gnutar->entry_bytes_remaining; - ret = __archive_write_output(a, buff, s); - gnutar->entry_bytes_remaining -= s; - if (ret != ARCHIVE_OK) - return (ret); - return (s); -} - -static int -archive_write_gnutar_header(struct archive_write *a, - struct archive_entry *entry) -{ - char buff[512]; - int r, ret, ret2 = ARCHIVE_OK; - int tartype; - struct gnutar *gnutar; - struct archive_string_conv *sconv; - struct archive_entry *entry_main; - - gnutar = (struct gnutar *)a->format_data; - - /* Setup default string conversion. */ - if (gnutar->opt_sconv == NULL) { - if (!gnutar->init_default_conversion) { - gnutar->sconv_default = - archive_string_default_conversion_for_write( - &(a->archive)); - gnutar->init_default_conversion = 1; - } - sconv = gnutar->sconv_default; - } else - sconv = gnutar->opt_sconv; - - /* Only regular files (not hardlinks) have data. */ - if (archive_entry_hardlink(entry) != NULL || - archive_entry_symlink(entry) != NULL || - !(archive_entry_filetype(entry) == AE_IFREG)) - archive_entry_set_size(entry, 0); - - if (AE_IFDIR == archive_entry_filetype(entry)) { - const char *p; - size_t path_length; - /* - * Ensure a trailing '/'. Modify the entry so - * the client sees the change. - */ -#if defined(_WIN32) && !defined(__CYGWIN__) - const wchar_t *wp; - - wp = archive_entry_pathname_w(entry); - if (wp != NULL && wp[wcslen(wp) -1] != L'/') { - struct archive_wstring ws; - - archive_string_init(&ws); - path_length = wcslen(wp); - if (archive_wstring_ensure(&ws, - path_length + 2) == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate ustar data"); - archive_wstring_free(&ws); - return(ARCHIVE_FATAL); - } - /* Should we keep '\' ? */ - if (wp[path_length -1] == L'\\') - path_length--; - archive_wstrncpy(&ws, wp, path_length); - archive_wstrappend_wchar(&ws, L'/'); - archive_entry_copy_pathname_w(entry, ws.s); - archive_wstring_free(&ws); - p = NULL; - } else -#endif - p = archive_entry_pathname(entry); - /* - * On Windows, this is a backup operation just in - * case getting WCS failed. On POSIX, this is a - * normal operation. - */ - if (p != NULL && p[0] != '\0' && p[strlen(p) - 1] != '/') { - struct archive_string as; - - archive_string_init(&as); - path_length = strlen(p); - if (archive_string_ensure(&as, - path_length + 2) == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate ustar data"); - archive_string_free(&as); - return(ARCHIVE_FATAL); - } -#if defined(_WIN32) && !defined(__CYGWIN__) - /* NOTE: This might break the pathname - * if the current code page is CP932 and - * the pathname includes a character '\' - * as a part of its multibyte pathname. */ - if (p[strlen(p) -1] == '\\') - path_length--; - else -#endif - archive_strncpy(&as, p, path_length); - archive_strappend_char(&as, '/'); - archive_entry_copy_pathname(entry, as.s); - archive_string_free(&as); - } - } - -#if defined(_WIN32) && !defined(__CYGWIN__) - /* Make sure the path separators in pathname, hardlink and symlink - * are all slash '/', not the Windows path separator '\'. */ - entry_main = __la_win_entry_in_posix_pathseparator(entry); - if (entry_main == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate ustar data"); - return(ARCHIVE_FATAL); - } - if (entry != entry_main) - entry = entry_main; - else - entry_main = NULL; -#else - entry_main = NULL; -#endif - r = archive_entry_pathname_l(entry, &(gnutar->pathname), - &(gnutar->pathname_length), sconv); - if (r != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Pathame"); - ret = ARCHIVE_FATAL; - goto exit_write_header; - } - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate pathname '%s' to %s", - archive_entry_pathname(entry), - archive_string_conversion_charset_name(sconv)); - ret2 = ARCHIVE_WARN; - } - r = archive_entry_uname_l(entry, &(gnutar->uname), - &(gnutar->uname_length), sconv); - if (r != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Uname"); - ret = ARCHIVE_FATAL; - goto exit_write_header; - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate uname '%s' to %s", - archive_entry_uname(entry), - archive_string_conversion_charset_name(sconv)); - ret2 = ARCHIVE_WARN; - } - r = archive_entry_gname_l(entry, &(gnutar->gname), - &(gnutar->gname_length), sconv); - if (r != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Gname"); - ret = ARCHIVE_FATAL; - goto exit_write_header; - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate gname '%s' to %s", - archive_entry_gname(entry), - archive_string_conversion_charset_name(sconv)); - ret2 = ARCHIVE_WARN; - } - - /* If linkname is longer than 100 chars we need to add a 'K' header. */ - r = archive_entry_hardlink_l(entry, &(gnutar->linkname), - &(gnutar->linkname_length), sconv); - if (r != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Linkname"); - ret = ARCHIVE_FATAL; - goto exit_write_header; - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate linkname '%s' to %s", - archive_entry_hardlink(entry), - archive_string_conversion_charset_name(sconv)); - ret2 = ARCHIVE_WARN; - } - if (gnutar->linkname_length == 0) { - r = archive_entry_symlink_l(entry, &(gnutar->linkname), - &(gnutar->linkname_length), sconv); - if (r != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Linkname"); - ret = ARCHIVE_FATAL; - goto exit_write_header; - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate linkname '%s' to %s", - archive_entry_hardlink(entry), - archive_string_conversion_charset_name(sconv)); - ret2 = ARCHIVE_WARN; - } - } - if (gnutar->linkname_length > GNUTAR_linkname_size) { - size_t length = gnutar->linkname_length + 1; - struct archive_entry *temp = archive_entry_new2(&a->archive); - - /* Uname/gname here don't really matter since no one reads them; - * these are the values that GNU tar happens to use on FreeBSD. */ - archive_entry_set_uname(temp, "root"); - archive_entry_set_gname(temp, "wheel"); - - archive_entry_set_pathname(temp, "././@LongLink"); - archive_entry_set_size(temp, length); - ret = archive_format_gnutar_header(a, buff, temp, 'K'); - archive_entry_free(temp); - if (ret < ARCHIVE_WARN) - goto exit_write_header; - ret = __archive_write_output(a, buff, 512); - if (ret < ARCHIVE_WARN) - goto exit_write_header; - /* Write name and trailing null byte. */ - ret = __archive_write_output(a, gnutar->linkname, length); - if (ret < ARCHIVE_WARN) - goto exit_write_header; - /* Pad to 512 bytes */ - ret = __archive_write_nulls(a, 0x1ff & (-(ssize_t)length)); - if (ret < ARCHIVE_WARN) - goto exit_write_header; - } - - /* If pathname is longer than 100 chars we need to add an 'L' header. */ - if (gnutar->pathname_length > GNUTAR_name_size) { - const char *pathname = gnutar->pathname; - size_t length = gnutar->pathname_length + 1; - struct archive_entry *temp = archive_entry_new2(&a->archive); - - /* Uname/gname here don't really matter since no one reads them; - * these are the values that GNU tar happens to use on FreeBSD. */ - archive_entry_set_uname(temp, "root"); - archive_entry_set_gname(temp, "wheel"); - - archive_entry_set_pathname(temp, "././@LongLink"); - archive_entry_set_size(temp, length); - ret = archive_format_gnutar_header(a, buff, temp, 'L'); - archive_entry_free(temp); - if (ret < ARCHIVE_WARN) - goto exit_write_header; - ret = __archive_write_output(a, buff, 512); - if(ret < ARCHIVE_WARN) - goto exit_write_header; - /* Write pathname + trailing null byte. */ - ret = __archive_write_output(a, pathname, length); - if(ret < ARCHIVE_WARN) - goto exit_write_header; - /* Pad to multiple of 512 bytes. */ - ret = __archive_write_nulls(a, 0x1ff & (-(ssize_t)length)); - if (ret < ARCHIVE_WARN) - goto exit_write_header; - } - - if (archive_entry_hardlink(entry) != NULL) { - tartype = '1'; - } else - switch (archive_entry_filetype(entry)) { - case AE_IFREG: tartype = '0' ; break; - case AE_IFLNK: tartype = '2' ; break; - case AE_IFCHR: tartype = '3' ; break; - case AE_IFBLK: tartype = '4' ; break; - case AE_IFDIR: tartype = '5' ; break; - case AE_IFIFO: tartype = '6' ; break; - default: /* AE_IFSOCK and unknown */ - __archive_write_entry_filetype_unsupported( - &a->archive, entry, "gnutar"); - ret = ARCHIVE_FAILED; - goto exit_write_header; - } - - ret = archive_format_gnutar_header(a, buff, entry, tartype); - if (ret < ARCHIVE_WARN) - goto exit_write_header; - if (ret2 < ret) - ret = ret2; - ret2 = __archive_write_output(a, buff, 512); - if (ret2 < ARCHIVE_WARN) { - ret = ret2; - goto exit_write_header; - } - if (ret2 < ret) - ret = ret2; - - gnutar->entry_bytes_remaining = archive_entry_size(entry); - gnutar->entry_padding = 0x1ff & (-(int64_t)gnutar->entry_bytes_remaining); -exit_write_header: - archive_entry_free(entry_main); - return (ret); -} - -static int -archive_format_gnutar_header(struct archive_write *a, char h[512], - struct archive_entry *entry, int tartype) -{ - unsigned int checksum; - int i, ret; - size_t copy_length; - const char *p; - struct gnutar *gnutar; - - gnutar = (struct gnutar *)a->format_data; - - ret = 0; - - /* - * The "template header" already includes the signature, - * various end-of-field markers, and other required elements. - */ - memcpy(h, &template_header, 512); - - /* - * Because the block is already null-filled, and strings - * are allowed to exactly fill their destination (without null), - * I use memcpy(dest, src, strlen()) here a lot to copy strings. - */ - - if (tartype == 'K' || tartype == 'L') { - p = archive_entry_pathname(entry); - copy_length = strlen(p); - } else { - p = gnutar->pathname; - copy_length = gnutar->pathname_length; - } - if (copy_length > GNUTAR_name_size) - copy_length = GNUTAR_name_size; - memcpy(h + GNUTAR_name_offset, p, copy_length); - - if ((copy_length = gnutar->linkname_length) > 0) { - if (copy_length > GNUTAR_linkname_size) - copy_length = GNUTAR_linkname_size; - memcpy(h + GNUTAR_linkname_offset, gnutar->linkname, - copy_length); - } - - /* TODO: How does GNU tar handle unames longer than GNUTAR_uname_size? */ - if (tartype == 'K' || tartype == 'L') { - p = archive_entry_uname(entry); - copy_length = strlen(p); - } else { - p = gnutar->uname; - copy_length = gnutar->uname_length; - } - if (copy_length > 0) { - if (copy_length > GNUTAR_uname_size) - copy_length = GNUTAR_uname_size; - memcpy(h + GNUTAR_uname_offset, p, copy_length); - } - - /* TODO: How does GNU tar handle gnames longer than GNUTAR_gname_size? */ - if (tartype == 'K' || tartype == 'L') { - p = archive_entry_gname(entry); - copy_length = strlen(p); - } else { - p = gnutar->gname; - copy_length = gnutar->gname_length; - } - if (copy_length > 0) { - if (strlen(p) > GNUTAR_gname_size) - copy_length = GNUTAR_gname_size; - memcpy(h + GNUTAR_gname_offset, p, copy_length); - } - - /* By truncating the mode here, we ensure it always fits. */ - format_octal(archive_entry_mode(entry) & 07777, - h + GNUTAR_mode_offset, GNUTAR_mode_size); - - /* GNU tar supports base-256 here, so should never overflow. */ - if (format_number(archive_entry_uid(entry), h + GNUTAR_uid_offset, - GNUTAR_uid_size, GNUTAR_uid_max_size)) { - archive_set_error(&a->archive, ERANGE, - "Numeric user ID %jd too large", - (intmax_t)archive_entry_uid(entry)); - ret = ARCHIVE_FAILED; - } - - /* GNU tar supports base-256 here, so should never overflow. */ - if (format_number(archive_entry_gid(entry), h + GNUTAR_gid_offset, - GNUTAR_gid_size, GNUTAR_gid_max_size)) { - archive_set_error(&a->archive, ERANGE, - "Numeric group ID %jd too large", - (intmax_t)archive_entry_gid(entry)); - ret = ARCHIVE_FAILED; - } - - /* GNU tar supports base-256 here, so should never overflow. */ - if (format_number(archive_entry_size(entry), h + GNUTAR_size_offset, - GNUTAR_size_size, GNUTAR_size_max_size)) { - archive_set_error(&a->archive, ERANGE, - "File size out of range"); - ret = ARCHIVE_FAILED; - } - - /* Shouldn't overflow before 2106, since mtime field is 33 bits. */ - format_octal(archive_entry_mtime(entry), - h + GNUTAR_mtime_offset, GNUTAR_mtime_size); - - if (archive_entry_filetype(entry) == AE_IFBLK - || archive_entry_filetype(entry) == AE_IFCHR) { - if (format_octal(archive_entry_rdevmajor(entry), - h + GNUTAR_rdevmajor_offset, - GNUTAR_rdevmajor_size)) { - archive_set_error(&a->archive, ERANGE, - "Major device number too large"); - ret = ARCHIVE_FAILED; - } - - if (format_octal(archive_entry_rdevminor(entry), - h + GNUTAR_rdevminor_offset, - GNUTAR_rdevminor_size)) { - archive_set_error(&a->archive, ERANGE, - "Minor device number too large"); - ret = ARCHIVE_FAILED; - } - } - - h[GNUTAR_typeflag_offset] = tartype; - - checksum = 0; - for (i = 0; i < 512; i++) - checksum += 255 & (unsigned int)h[i]; - h[GNUTAR_checksum_offset + 6] = '\0'; /* Can't be pre-set in the template. */ - /* h[GNUTAR_checksum_offset + 7] = ' '; */ /* This is pre-set in the template. */ - format_octal(checksum, h + GNUTAR_checksum_offset, 6); - return (ret); -} - -/* - * Format a number into a field, falling back to base-256 if necessary. - */ -static int -format_number(int64_t v, char *p, int s, int maxsize) -{ - int64_t limit = ((int64_t)1 << (s*3)); - - if (v < limit) - return (format_octal(v, p, s)); - return (format_256(v, p, maxsize)); -} - -/* - * Format a number into the specified field using base-256. - */ -static int -format_256(int64_t v, char *p, int s) -{ - p += s; - while (s-- > 0) { - *--p = (char)(v & 0xff); - v >>= 8; - } - *p |= 0x80; /* Set the base-256 marker bit. */ - return (0); -} - -/* - * Format a number into the specified field using octal. - */ -static int -format_octal(int64_t v, char *p, int s) -{ - int len = s; - - /* Octal values can't be negative, so use 0. */ - if (v < 0) - v = 0; - - p += s; /* Start at the end and work backwards. */ - while (s-- > 0) { - *--p = (char)('0' + (v & 7)); - v >>= 3; - } - - if (v == 0) - return (0); - - /* If it overflowed, fill field with max value. */ - while (len-- > 0) - *p++ = '7'; - - return (-1); -} diff --git a/thirdparty/libarchive/libarchive/archive_write_set_format_iso9660.c b/thirdparty/libarchive/libarchive/archive_write_set_format_iso9660.c deleted file mode 100644 index 2a3ae07fa..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_set_format_iso9660.c +++ /dev/null @@ -1,8161 +0,0 @@ -/*- - * Copyright (c) 2009-2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_UTSNAME_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_LIMITS_H -#include -#endif -#include -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_ZLIB_H -#include -#endif - -#include "archive.h" -#include "archive_endian.h" -#include "archive_entry.h" -#include "archive_entry_locale.h" -#include "archive_private.h" -#include "archive_rb.h" -#include "archive_write_private.h" - -#if defined(_WIN32) && !defined(__CYGWIN__) -#define getuid() 0 -#define getgid() 0 -#endif - -/*#define DEBUG 1*/ -#ifdef DEBUG -/* To compare to the ISO image file made by mkisofs. */ -#define COMPAT_MKISOFS 1 -#endif - -#define LOGICAL_BLOCK_BITS 11 -#define LOGICAL_BLOCK_SIZE 2048 -#define PATH_TABLE_BLOCK_SIZE 4096 - -#define SYSTEM_AREA_BLOCK 16 -#define PRIMARY_VOLUME_DESCRIPTOR_BLOCK 1 -#define SUPPLEMENTARY_VOLUME_DESCRIPTOR_BLOCK 1 -#define BOOT_RECORD_DESCRIPTOR_BLOCK 1 -#define VOLUME_DESCRIPTOR_SET_TERMINATOR_BLOCK 1 -#define NON_ISO_FILE_SYSTEM_INFORMATION_BLOCK 1 -#define RRIP_ER_BLOCK 1 -#define PADDING_BLOCK 150 - -#define FD_1_2M_SIZE (1024 * 1200) -#define FD_1_44M_SIZE (1024 * 1440) -#define FD_2_88M_SIZE (1024 * 2880) -#define MULTI_EXTENT_SIZE (ARCHIVE_LITERAL_LL(1) << 32) /* 4Gi bytes. */ -#define MAX_DEPTH 8 -#define RR_CE_SIZE 28 /* SUSP "CE" extension size */ - -#define FILE_FLAG_EXISTENCE 0x01 -#define FILE_FLAG_DIRECTORY 0x02 -#define FILE_FLAG_ASSOCIATED 0x04 -#define FILE_FLAG_RECORD 0x08 -#define FILE_FLAG_PROTECTION 0x10 -#define FILE_FLAG_MULTI_EXTENT 0x80 - -static const char rrip_identifier[] = - "RRIP_1991A"; -static const char rrip_descriptor[] = - "THE ROCK RIDGE INTERCHANGE PROTOCOL PROVIDES SUPPORT FOR " - "POSIX FILE SYSTEM SEMANTICS"; -static const char rrip_source[] = - "PLEASE CONTACT DISC PUBLISHER FOR SPECIFICATION SOURCE. " - "SEE PUBLISHER IDENTIFIER IN PRIMARY VOLUME DESCRIPTOR FOR " - "CONTACT INFORMATION."; -#define RRIP_ER_ID_SIZE (sizeof(rrip_identifier)-1) -#define RRIP_ER_DSC_SIZE (sizeof(rrip_descriptor)-1) -#define RRIP_ER_SRC_SIZE (sizeof(rrip_source)-1) -#define RRIP_ER_SIZE (8 + RRIP_ER_ID_SIZE + \ - RRIP_ER_DSC_SIZE + RRIP_ER_SRC_SIZE) - -static const unsigned char zisofs_magic[8] = { - 0x37, 0xE4, 0x53, 0x96, 0xC9, 0xDB, 0xD6, 0x07 -}; - -#define ZF_HEADER_SIZE 16 /* zisofs header size. */ -#define ZF_LOG2_BS 15 /* log2 block size; 32K bytes. */ -#define ZF_BLOCK_SIZE (1UL << ZF_LOG2_BS) - -/* - * Manage extra records. - */ -struct extr_rec { - int location; - int offset; - unsigned char buf[LOGICAL_BLOCK_SIZE]; - struct extr_rec *next; -}; - -struct ctl_extr_rec { - int use_extr; - unsigned char *bp; - struct isoent *isoent; - unsigned char *ce_ptr; - int cur_len; - int dr_len; - int limit; - int extr_off; - int extr_loc; -}; -#define DR_SAFETY RR_CE_SIZE -#define DR_LIMIT (254 - DR_SAFETY) - -/* - * The relation of struct isofile and isoent and archive_entry. - * - * Primary volume tree --> struct isoent - * | - * v - * struct isofile --> archive_entry - * ^ - * | - * Joliet volume tree --> struct isoent - * - * struct isoent has specific information for volume. - */ - -struct isofile { - /* Used for managing struct isofile list. */ - struct isofile *allnext; - struct isofile *datanext; - /* Used for managing a hardlinked struct isofile list. */ - struct isofile *hlnext; - struct isofile *hardlink_target; - - struct archive_entry *entry; - - /* - * Used for making a directory tree. - */ - struct archive_string parentdir; - struct archive_string basename; - struct archive_string basename_utf16; - struct archive_string symlink; - int dircnt; /* The number of elements of - * its parent directory */ - - /* - * Used for a Directory Record. - */ - struct content { - int64_t offset_of_temp; - int64_t size; - int blocks; - uint32_t location; - /* - * One extent equals one content. - * If this entry has multi extent, `next' variable points - * next content data. - */ - struct content *next; /* next content */ - } content, *cur_content; - int write_content; - - enum { - NO = 0, - BOOT_CATALOG, - BOOT_IMAGE - } boot; - - /* - * Used for a zisofs. - */ - struct { - unsigned char header_size; - unsigned char log2_bs; - uint32_t uncompressed_size; - } zisofs; -}; - -struct isoent { - /* Keep `rbnode' at the first member of struct isoent. */ - struct archive_rb_node rbnode; - - struct isofile *file; - - struct isoent *parent; - /* A list of children.(use chnext) */ - struct { - struct isoent *first; - struct isoent **last; - int cnt; - } children; - struct archive_rb_tree rbtree; - - /* A list of sub directories.(use drnext) */ - struct { - struct isoent *first; - struct isoent **last; - int cnt; - } subdirs; - /* A sorted list of sub directories. */ - struct isoent **children_sorted; - /* Used for managing struct isoent list. */ - struct isoent *chnext; - struct isoent *drnext; - struct isoent *ptnext; - - /* - * Used for making a Directory Record. - */ - int dir_number; - struct { - int vd; - int self; - int parent; - int normal; - } dr_len; - uint32_t dir_location; - int dir_block; - - /* - * Identifier: - * on primary, ISO9660 file/directory name. - * on joliet, UCS2 file/directory name. - * ext_off : offset of identifier extension. - * ext_len : length of identifier extension. - * id_len : byte size of identifier. - * on primary, this is ext_off + ext_len + version length. - * on joliet, this is ext_off + ext_len. - * mb_len : length of multibyte-character of identifier. - * on primary, mb_len and id_len are always the same. - * on joliet, mb_len and id_len are different. - */ - char *identifier; - int ext_off; - int ext_len; - int id_len; - int mb_len; - - /* - * Used for making a Rockridge extension. - * This is a part of Directory Records. - */ - struct isoent *rr_parent; - struct isoent *rr_child; - - /* Extra Record.(which we call in this source file) - * A maximum size of the Directory Record is 254. - * so, if generated RRIP data of a file cannot into a Directory - * Record because of its size, that surplus data relocate this - * Extra Record. - */ - struct { - struct extr_rec *first; - struct extr_rec **last; - struct extr_rec *current; - } extr_rec_list; - - unsigned int virtual:1; - /* If set to one, this file type is a directory. - * A convenience flag to be used as - * "archive_entry_filetype(isoent->file->entry) == AE_IFDIR". - */ - unsigned int dir:1; -}; - -struct hardlink { - struct archive_rb_node rbnode; - int nlink; - struct { - struct isofile *first; - struct isofile **last; - } file_list; -}; - -/* - * ISO writer options - */ -struct iso_option { - /* - * Usage : abstract-file= - * Type : string, max 37 bytes - * Default: Not specified - * COMPAT : mkisofs -abstract - * - * Specifies Abstract Filename. - * This file shall be described in the Root Directory - * and containing a abstract statement. - */ - unsigned int abstract_file:1; -#define OPT_ABSTRACT_FILE_DEFAULT 0 /* Not specified */ -#define ABSTRACT_FILE_SIZE 37 - - /* - * Usage : application-id= - * Type : string, max 128 bytes - * Default: Not specified - * COMPAT : mkisofs -A/-appid . - * - * Specifies Application Identifier. - * If the first byte is set to '_'(5F), the remaining - * bytes of this option shall specify an identifier - * for a file containing the identification of the - * application. - * This file shall be described in the Root Directory. - */ - unsigned int application_id:1; -#define OPT_APPLICATION_ID_DEFAULT 0 /* Use default identifier */ -#define APPLICATION_IDENTIFIER_SIZE 128 - - /* - * Usage : !allow-vernum - * Type : boolean - * Default: Enabled - * : Violates the ISO9660 standard if disable. - * COMPAT: mkisofs -N - * - * Allow filenames to use version numbers. - */ - unsigned int allow_vernum:1; -#define OPT_ALLOW_VERNUM_DEFAULT 1 /* Enabled */ - - /* - * Usage : biblio-file= - * Type : string, max 37 bytes - * Default: Not specified - * COMPAT : mkisofs -biblio - * - * Specifies Bibliographic Filename. - * This file shall be described in the Root Directory - * and containing bibliographic records. - */ - unsigned int biblio_file:1; -#define OPT_BIBLIO_FILE_DEFAULT 0 /* Not specified */ -#define BIBLIO_FILE_SIZE 37 - - /* - * Usage : boot= - * Type : string - * Default: Not specified - * COMPAT : mkisofs -b/-eltorito-boot - * - * Specifies "El Torito" boot image file to make - * a bootable CD. - */ - unsigned int boot:1; -#define OPT_BOOT_DEFAULT 0 /* Not specified */ - - /* - * Usage : boot-catalog= - * Type : string - * Default: "boot.catalog" - * COMPAT : mkisofs -c/-eltorito-catalog - * - * Specifies a fullpath of El Torito boot catalog. - */ - unsigned int boot_catalog:1; -#define OPT_BOOT_CATALOG_DEFAULT 0 /* Not specified */ - - /* - * Usage : boot-info-table - * Type : boolean - * Default: Disabled - * COMPAT : mkisofs -boot-info-table - * - * Modify the boot image file specified by `boot' - * option; ISO writer stores boot file information - * into the boot file in ISO image at offset 8 - * through offset 64. - */ - unsigned int boot_info_table:1; -#define OPT_BOOT_INFO_TABLE_DEFAULT 0 /* Disabled */ - - /* - * Usage : boot-load-seg= - * Type : hexadecimal - * Default: Not specified - * COMPAT : mkisofs -boot-load-seg - * - * Specifies a load segment for boot image. - * This is used with no-emulation mode. - */ - unsigned int boot_load_seg:1; -#define OPT_BOOT_LOAD_SEG_DEFAULT 0 /* Not specified */ - - /* - * Usage : boot-load-size= - * Type : decimal - * Default: Not specified - * COMPAT : mkisofs -boot-load-size - * - * Specifies a sector count for boot image. - * This is used with no-emulation mode. - */ - unsigned int boot_load_size:1; -#define OPT_BOOT_LOAD_SIZE_DEFAULT 0 /* Not specified */ - - /* - * Usage : boot-type= - * : 'no-emulation' : 'no emulation' image - * : 'fd' : floppy disk image - * : 'hard-disk' : hard disk image - * Type : string - * Default: Auto detect - * : We check a size of boot image; - * : If the size is just 1.22M/1.44M/2.88M, - * : we assume boot_type is 'fd'; - * : otherwise boot_type is 'no-emulation'. - * COMPAT : - * boot=no-emulation - * mkisofs -no-emul-boot - * boot=fd - * This is a default on the mkisofs. - * boot=hard-disk - * mkisofs -hard-disk-boot - * - * Specifies a type of "El Torito" boot image. - */ - unsigned int boot_type:2; -#define OPT_BOOT_TYPE_AUTO 0 /* auto detect */ -#define OPT_BOOT_TYPE_NO_EMU 1 /* ``no emulation'' image */ -#define OPT_BOOT_TYPE_FD 2 /* floppy disk image */ -#define OPT_BOOT_TYPE_HARD_DISK 3 /* hard disk image */ -#define OPT_BOOT_TYPE_DEFAULT OPT_BOOT_TYPE_AUTO - - /* - * Usage : compression-level= - * Type : decimal - * Default: Not specified - * COMPAT : NONE - * - * Specifies compression level for option zisofs=direct. - */ - unsigned int compression_level:1; -#define OPT_COMPRESSION_LEVEL_DEFAULT 0 /* Not specified */ - - /* - * Usage : copyright-file= - * Type : string, max 37 bytes - * Default: Not specified - * COMPAT : mkisofs -copyright - * - * Specifies Copyright Filename. - * This file shall be described in the Root Directory - * and containing a copyright statement. - */ - unsigned int copyright_file:1; -#define OPT_COPYRIGHT_FILE_DEFAULT 0 /* Not specified */ -#define COPYRIGHT_FILE_SIZE 37 - - /* - * Usage : gid= - * Type : decimal - * Default: Not specified - * COMPAT : mkisofs -gid - * - * Specifies a group id to rewrite the group id of all files. - */ - unsigned int gid:1; -#define OPT_GID_DEFAULT 0 /* Not specified */ - - /* - * Usage : iso-level=[1234] - * Type : decimal - * Default: 1 - * COMPAT : mkisofs -iso-level - * - * Specifies ISO9600 Level. - * Level 1: [DEFAULT] - * - limits each file size less than 4Gi bytes; - * - a File Name shall not contain more than eight - * d-characters or eight d1-characters; - * - a File Name Extension shall not contain more than - * three d-characters or three d1-characters; - * - a Directory Identifier shall not contain more - * than eight d-characters or eight d1-characters. - * Level 2: - * - limits each file size less than 4Giga bytes; - * - a File Name shall not contain more than thirty - * d-characters or thirty d1-characters; - * - a File Name Extension shall not contain more than - * thirty d-characters or thirty d1-characters; - * - a Directory Identifier shall not contain more - * than thirty-one d-characters or thirty-one - * d1-characters. - * Level 3: - * - no limit of file size; use multi extent. - * Level 4: - * - this level 4 simulates mkisofs option - * '-iso-level 4'; - * - crate a enhanced volume as mkisofs doing; - * - allow a File Name to have leading dot; - * - allow a File Name to have all ASCII letters; - * - allow a File Name to have multiple dots; - * - allow more then 8 depths of directory trees; - * - disable a version number to a File Name; - * - disable a forced period to the tail of a File Name; - * - the maximum length of files and directories is raised to 193. - * if rockridge option is disabled, raised to 207. - */ - unsigned int iso_level:3; -#define OPT_ISO_LEVEL_DEFAULT 1 /* ISO Level 1 */ - - /* - * Usage : joliet[=long] - * : !joliet - * : Do not generate Joliet Volume and Records. - * : joliet [DEFAULT] - * : Generates Joliet Volume and Directory Records. - * : [COMPAT: mkisofs -J/-joliet] - * : joliet=long - * : The joliet filenames are up to 103 Unicode - * : characters. - * : This option breaks the Joliet specification. - * : [COMPAT: mkisofs -J -joliet-long] - * Type : boolean/string - * Default: Enabled - * COMPAT : mkisofs -J / -joliet-long - * - * Generates Joliet Volume and Directory Records. - */ - unsigned int joliet:2; -#define OPT_JOLIET_DISABLE 0 /* Not generate Joliet Records. */ -#define OPT_JOLIET_ENABLE 1 /* Generate Joliet Records. */ -#define OPT_JOLIET_LONGNAME 2 /* Use long joliet filenames.*/ -#define OPT_JOLIET_DEFAULT OPT_JOLIET_ENABLE - - /* - * Usage : !limit-depth - * Type : boolean - * Default: Enabled - * : Violates the ISO9660 standard if disable. - * COMPAT : mkisofs -D/-disable-deep-relocation - * - * The number of levels in hierarchy cannot exceed eight. - */ - unsigned int limit_depth:1; -#define OPT_LIMIT_DEPTH_DEFAULT 1 /* Enabled */ - - /* - * Usage : !limit-dirs - * Type : boolean - * Default: Enabled - * : Violates the ISO9660 standard if disable. - * COMPAT : mkisofs -no-limit-pathtables - * - * Limits the number of directories less than 65536 due - * to the size of the Parent Directory Number of Path - * Table. - */ - unsigned int limit_dirs:1; -#define OPT_LIMIT_DIRS_DEFAULT 1 /* Enabled */ - - /* - * Usage : !pad - * Type : boolean - * Default: Enabled - * COMPAT : -pad/-no-pad - * - * Pads the end of the ISO image by null of 300Ki bytes. - */ - unsigned int pad:1; -#define OPT_PAD_DEFAULT 1 /* Enabled */ - - /* - * Usage : publisher= - * Type : string, max 128 bytes - * Default: Not specified - * COMPAT : mkisofs -publisher - * - * Specifies Publisher Identifier. - * If the first byte is set to '_'(5F), the remaining - * bytes of this option shall specify an identifier - * for a file containing the identification of the user. - * This file shall be described in the Root Directory. - */ - unsigned int publisher:1; -#define OPT_PUBLISHER_DEFAULT 0 /* Not specified */ -#define PUBLISHER_IDENTIFIER_SIZE 128 - - /* - * Usage : rockridge - * : !rockridge - * : disable to generate SUSP and RR records. - * : rockridge - * : the same as 'rockridge=useful'. - * : rockridge=strict - * : generate SUSP and RR records. - * : [COMPAT: mkisofs -R] - * : rockridge=useful [DEFAULT] - * : generate SUSP and RR records. - * : [COMPAT: mkisofs -r] - * : NOTE Our rockridge=useful option does not set a zero - * : to uid and gid, you should use application - * : option such as --gid,--gname,--uid and --uname - * : bsdtar options instead. - * Type : boolean/string - * Default: Enabled as rockridge=useful - * COMPAT : mkisofs -r / -R - * - * Generates SUSP and RR records. - */ - unsigned int rr:2; -#define OPT_RR_DISABLED 0 -#define OPT_RR_STRICT 1 -#define OPT_RR_USEFUL 2 -#define OPT_RR_DEFAULT OPT_RR_USEFUL - - /* - * Usage : volume-id= - * Type : string, max 32 bytes - * Default: Not specified - * COMPAT : mkisofs -V - * - * Specifies Volume Identifier. - */ - unsigned int volume_id:1; -#define OPT_VOLUME_ID_DEFAULT 0 /* Use default identifier */ -#define VOLUME_IDENTIFIER_SIZE 32 - - /* - * Usage : !zisofs [DEFAULT] - * : Disable to generate RRIP 'ZF' extension. - * : zisofs - * : Make files zisofs file and generate RRIP 'ZF' - * : extension. So you do not need mkzftree utility - * : for making zisofs. - * : When the file size is less than one Logical Block - * : size, that file will not zisofs'ed since it does - * : reduce an ISO-image size. - * : - * : When you specify option 'boot=', that - * : 'boot-image' file won't be converted to zisofs file. - * Type : boolean - * Default: Disabled - * - * Generates RRIP 'ZF' System Use Entry. - */ - unsigned int zisofs:1; -#define OPT_ZISOFS_DISABLED 0 -#define OPT_ZISOFS_DIRECT 1 -#define OPT_ZISOFS_DEFAULT OPT_ZISOFS_DISABLED - -}; - -struct iso9660 { - /* The creation time of ISO image. */ - time_t birth_time; - /* A file stream of a temporary file, which file contents - * save to until ISO image can be created. */ - int temp_fd; - - struct isofile *cur_file; - struct isoent *cur_dirent; - struct archive_string cur_dirstr; - uint64_t bytes_remaining; - int need_multi_extent; - - /* Temporary string buffer for Joliet extension. */ - struct archive_string utf16be; - struct archive_string mbs; - - struct archive_string_conv *sconv_to_utf16be; - struct archive_string_conv *sconv_from_utf16be; - - /* A list of all of struct isofile entries. */ - struct { - struct isofile *first; - struct isofile **last; - } all_file_list; - - /* A list of struct isofile entries which have its - * contents and are not a directory, a hardlinked file - * and a symlink file. */ - struct { - struct isofile *first; - struct isofile **last; - } data_file_list; - - /* Used for managing to find hardlinking files. */ - struct archive_rb_tree hardlink_rbtree; - - /* Used for making the Path Table Record. */ - struct vdd { - /* the root of entry tree. */ - struct isoent *rootent; - enum vdd_type { - VDD_PRIMARY, - VDD_JOLIET, - VDD_ENHANCED - } vdd_type; - - struct path_table { - struct isoent *first; - struct isoent **last; - struct isoent **sorted; - int cnt; - } *pathtbl; - int max_depth; - - int path_table_block; - int path_table_size; - int location_type_L_path_table; - int location_type_M_path_table; - int total_dir_block; - } primary, joliet; - - /* Used for making a Volume Descriptor. */ - int volume_space_size; - int volume_sequence_number; - int total_file_block; - struct archive_string volume_identifier; - struct archive_string publisher_identifier; - struct archive_string data_preparer_identifier; - struct archive_string application_identifier; - struct archive_string copyright_file_identifier; - struct archive_string abstract_file_identifier; - struct archive_string bibliographic_file_identifier; - - /* Used for making rockridge extensions. */ - int location_rrip_er; - - /* Used for making zisofs. */ - struct { - unsigned int detect_magic:1; - unsigned int making:1; - unsigned int allzero:1; - unsigned char magic_buffer[64]; - int magic_cnt; - -#ifdef HAVE_ZLIB_H - /* - * Copy a compressed file to iso9660.zisofs.temp_fd - * and also copy a uncompressed file(original file) to - * iso9660.temp_fd . If the number of logical block - * of the compressed file is less than the number of - * logical block of the uncompressed file, use it and - * remove the copy of the uncompressed file. - * but if not, we use uncompressed file and remove - * the copy of the compressed file. - */ - uint32_t *block_pointers; - size_t block_pointers_allocated; - int block_pointers_cnt; - int block_pointers_idx; - int64_t total_size; - int64_t block_offset; - - z_stream stream; - int stream_valid; - int64_t remaining; - int compression_level; -#endif - } zisofs; - - struct isoent *directories_too_deep; - int dircnt_max; - - /* Write buffer. */ -#define wb_buffmax() (LOGICAL_BLOCK_SIZE * 32) -#define wb_remaining(a) (((struct iso9660 *)(a)->format_data)->wbuff_remaining) -#define wb_offset(a) (((struct iso9660 *)(a)->format_data)->wbuff_offset \ - + wb_buffmax() - wb_remaining(a)) - unsigned char wbuff[LOGICAL_BLOCK_SIZE * 32]; - size_t wbuff_remaining; - enum { - WB_TO_STREAM, - WB_TO_TEMP - } wbuff_type; - int64_t wbuff_offset; - int64_t wbuff_written; - int64_t wbuff_tail; - - /* 'El Torito' boot data. */ - struct { - /* boot catalog file */ - struct archive_string catalog_filename; - struct isoent *catalog; - /* boot image file */ - struct archive_string boot_filename; - struct isoent *boot; - - unsigned char platform_id; -#define BOOT_PLATFORM_X86 0 -#define BOOT_PLATFORM_PPC 1 -#define BOOT_PLATFORM_MAC 2 - struct archive_string id; - unsigned char media_type; -#define BOOT_MEDIA_NO_EMULATION 0 -#define BOOT_MEDIA_1_2M_DISKETTE 1 -#define BOOT_MEDIA_1_44M_DISKETTE 2 -#define BOOT_MEDIA_2_88M_DISKETTE 3 -#define BOOT_MEDIA_HARD_DISK 4 - unsigned char system_type; - uint16_t boot_load_seg; - uint16_t boot_load_size; -#define BOOT_LOAD_SIZE 4 - } el_torito; - - struct iso_option opt; -}; - -/* - * Types of Volume Descriptor - */ -enum VD_type { - VDT_BOOT_RECORD=0, /* Boot Record Volume Descriptor */ - VDT_PRIMARY=1, /* Primary Volume Descriptor */ - VDT_SUPPLEMENTARY=2, /* Supplementary Volume Descriptor */ - VDT_TERMINATOR=255 /* Volume Descriptor Set Terminator */ -}; - -/* - * Types of Directory Record - */ -enum dir_rec_type { - DIR_REC_VD, /* Stored in Volume Descriptor. */ - DIR_REC_SELF, /* Stored as Current Directory. */ - DIR_REC_PARENT, /* Stored as Parent Directory. */ - DIR_REC_NORMAL /* Stored as Child. */ -}; - -/* - * Kinds of Volume Descriptor Character - */ -enum vdc { - VDC_STD, - VDC_LOWERCASE, - VDC_UCS2, - VDC_UCS2_DIRECT -}; - -/* - * IDentifier Resolver. - * Used for resolving duplicated filenames. - */ -struct idr { - struct idrent { - struct archive_rb_node rbnode; - /* Used in wait_list. */ - struct idrent *wnext; - struct idrent *avail; - - struct isoent *isoent; - int weight; - int noff; - int rename_num; - } *idrent_pool; - - struct archive_rb_tree rbtree; - - struct { - struct idrent *first; - struct idrent **last; - } wait_list; - - int pool_size; - int pool_idx; - int num_size; - int null_size; - - char char_map[0x80]; -}; - -enum char_type { - A_CHAR, - D_CHAR -}; - - -static int iso9660_options(struct archive_write *, - const char *, const char *); -static int iso9660_write_header(struct archive_write *, - struct archive_entry *); -static ssize_t iso9660_write_data(struct archive_write *, - const void *, size_t); -static int iso9660_finish_entry(struct archive_write *); -static int iso9660_close(struct archive_write *); -static int iso9660_free(struct archive_write *); - -static void get_system_identitier(char *, size_t); -static void set_str(unsigned char *, const char *, size_t, char, - const char *); -static inline int joliet_allowed_char(unsigned char, unsigned char); -static int set_str_utf16be(struct archive_write *, unsigned char *, - const char *, size_t, uint16_t, enum vdc); -static int set_str_a_characters_bp(struct archive_write *, - unsigned char *, int, int, const char *, enum vdc); -static int set_str_d_characters_bp(struct archive_write *, - unsigned char *, int, int, const char *, enum vdc); -static void set_VD_bp(unsigned char *, enum VD_type, unsigned char); -static inline void set_unused_field_bp(unsigned char *, int, int); - -static unsigned char *extra_open_record(unsigned char *, int, - struct isoent *, struct ctl_extr_rec *); -static void extra_close_record(struct ctl_extr_rec *, int); -static unsigned char * extra_next_record(struct ctl_extr_rec *, int); -static unsigned char *extra_get_record(struct isoent *, int *, int *, int *); -static void extra_tell_used_size(struct ctl_extr_rec *, int); -static int extra_setup_location(struct isoent *, int); -static int set_directory_record_rr(unsigned char *, int, - struct isoent *, struct iso9660 *, enum dir_rec_type); -static int set_directory_record(unsigned char *, size_t, - struct isoent *, struct iso9660 *, enum dir_rec_type, - enum vdd_type); -static inline int get_dir_rec_size(struct iso9660 *, struct isoent *, - enum dir_rec_type, enum vdd_type); -static inline unsigned char *wb_buffptr(struct archive_write *); -static int wb_write_out(struct archive_write *); -static int wb_consume(struct archive_write *, size_t); -#ifdef HAVE_ZLIB_H -static int wb_set_offset(struct archive_write *, int64_t); -#endif -static int write_null(struct archive_write *, size_t); -static int write_VD_terminator(struct archive_write *); -static int set_file_identifier(unsigned char *, int, int, enum vdc, - struct archive_write *, struct vdd *, - struct archive_string *, const char *, int, - enum char_type); -static int write_VD(struct archive_write *, struct vdd *); -static int write_VD_boot_record(struct archive_write *); -static int write_information_block(struct archive_write *); -static int write_path_table(struct archive_write *, int, - struct vdd *); -static int write_directory_descriptors(struct archive_write *, - struct vdd *); -static int write_file_descriptors(struct archive_write *); -static int write_rr_ER(struct archive_write *); -static void calculate_path_table_size(struct vdd *); - -static void isofile_init_entry_list(struct iso9660 *); -static void isofile_add_entry(struct iso9660 *, struct isofile *); -static void isofile_free_all_entries(struct iso9660 *); -static void isofile_init_entry_data_file_list(struct iso9660 *); -static void isofile_add_data_file(struct iso9660 *, struct isofile *); -static struct isofile * isofile_new(struct archive_write *, - struct archive_entry *); -static void isofile_free(struct isofile *); -static int isofile_gen_utility_names(struct archive_write *, - struct isofile *); -static int isofile_register_hardlink(struct archive_write *, - struct isofile *); -static void isofile_connect_hardlink_files(struct iso9660 *); -static void isofile_init_hardlinks(struct iso9660 *); -static void isofile_free_hardlinks(struct iso9660 *); - -static struct isoent *isoent_new(struct isofile *); -static int isoent_clone_tree(struct archive_write *, - struct isoent **, struct isoent *); -static void _isoent_free(struct isoent *isoent); -static void isoent_free_all(struct isoent *); -static struct isoent * isoent_create_virtual_dir(struct archive_write *, - struct iso9660 *, const char *); -static int isoent_cmp_node(const struct archive_rb_node *, - const struct archive_rb_node *); -static int isoent_cmp_key(const struct archive_rb_node *, - const void *); -static int isoent_add_child_head(struct isoent *, struct isoent *); -static int isoent_add_child_tail(struct isoent *, struct isoent *); -static void isoent_remove_child(struct isoent *, struct isoent *); -static void isoent_setup_directory_location(struct iso9660 *, - int, struct vdd *); -static void isoent_setup_file_location(struct iso9660 *, int); -static int get_path_component(char *, size_t, const char *); -static int isoent_tree(struct archive_write *, struct isoent **); -static struct isoent *isoent_find_child(struct isoent *, const char *); -static struct isoent *isoent_find_entry(struct isoent *, const char *); -static void idr_relaxed_filenames(char *); -static void idr_init(struct iso9660 *, struct vdd *, struct idr *); -static void idr_cleanup(struct idr *); -static int idr_ensure_poolsize(struct archive_write *, struct idr *, - int); -static int idr_start(struct archive_write *, struct idr *, - int, int, int, int, const struct archive_rb_tree_ops *); -static void idr_register(struct idr *, struct isoent *, int, - int); -static void idr_extend_identifier(struct idrent *, int, int); -static void idr_resolve(struct idr *, void (*)(unsigned char *, int)); -static void idr_set_num(unsigned char *, int); -static void idr_set_num_beutf16(unsigned char *, int); -static int isoent_gen_iso9660_identifier(struct archive_write *, - struct isoent *, struct idr *); -static int isoent_gen_joliet_identifier(struct archive_write *, - struct isoent *, struct idr *); -static int isoent_cmp_iso9660_identifier(const struct isoent *, - const struct isoent *); -static int isoent_cmp_node_iso9660(const struct archive_rb_node *, - const struct archive_rb_node *); -static int isoent_cmp_key_iso9660(const struct archive_rb_node *, - const void *); -static int isoent_cmp_joliet_identifier(const struct isoent *, - const struct isoent *); -static int isoent_cmp_node_joliet(const struct archive_rb_node *, - const struct archive_rb_node *); -static int isoent_cmp_key_joliet(const struct archive_rb_node *, - const void *); -static inline void path_table_add_entry(struct path_table *, struct isoent *); -static inline struct isoent * path_table_last_entry(struct path_table *); -static int isoent_make_path_table(struct archive_write *); -static int isoent_find_out_boot_file(struct archive_write *, - struct isoent *); -static int isoent_create_boot_catalog(struct archive_write *, - struct isoent *); -static size_t fd_boot_image_size(int); -static int make_boot_catalog(struct archive_write *); -static int setup_boot_information(struct archive_write *); - -static int zisofs_init(struct archive_write *, struct isofile *); -static void zisofs_detect_magic(struct archive_write *, - const void *, size_t); -static int zisofs_write_to_temp(struct archive_write *, - const void *, size_t); -static int zisofs_finish_entry(struct archive_write *); -static int zisofs_rewind_boot_file(struct archive_write *); -static int zisofs_free(struct archive_write *); - -int -archive_write_set_format_iso9660(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - struct iso9660 *iso9660; - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_set_format_iso9660"); - - /* If another format was already registered, unregister it. */ - if (a->format_free != NULL) - (a->format_free)(a); - - iso9660 = calloc(1, sizeof(*iso9660)); - if (iso9660 == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate iso9660 data"); - return (ARCHIVE_FATAL); - } - iso9660->birth_time = 0; - iso9660->temp_fd = -1; - iso9660->cur_file = NULL; - iso9660->primary.max_depth = 0; - iso9660->primary.vdd_type = VDD_PRIMARY; - iso9660->primary.pathtbl = NULL; - iso9660->joliet.rootent = NULL; - iso9660->joliet.max_depth = 0; - iso9660->joliet.vdd_type = VDD_JOLIET; - iso9660->joliet.pathtbl = NULL; - isofile_init_entry_list(iso9660); - isofile_init_entry_data_file_list(iso9660); - isofile_init_hardlinks(iso9660); - iso9660->directories_too_deep = NULL; - iso9660->dircnt_max = 1; - iso9660->wbuff_remaining = wb_buffmax(); - iso9660->wbuff_type = WB_TO_TEMP; - iso9660->wbuff_offset = 0; - iso9660->wbuff_written = 0; - iso9660->wbuff_tail = 0; - archive_string_init(&(iso9660->utf16be)); - archive_string_init(&(iso9660->mbs)); - - /* - * Init Identifiers used for PVD and SVD. - */ - archive_string_init(&(iso9660->volume_identifier)); - archive_strcpy(&(iso9660->volume_identifier), "CDROM"); - archive_string_init(&(iso9660->publisher_identifier)); - archive_string_init(&(iso9660->data_preparer_identifier)); - archive_string_init(&(iso9660->application_identifier)); - archive_strcpy(&(iso9660->application_identifier), - archive_version_string()); - archive_string_init(&(iso9660->copyright_file_identifier)); - archive_string_init(&(iso9660->abstract_file_identifier)); - archive_string_init(&(iso9660->bibliographic_file_identifier)); - - /* - * Init El Torito bootable CD variables. - */ - archive_string_init(&(iso9660->el_torito.catalog_filename)); - iso9660->el_torito.catalog = NULL; - /* Set default file name of boot catalog */ - archive_strcpy(&(iso9660->el_torito.catalog_filename), - "boot.catalog"); - archive_string_init(&(iso9660->el_torito.boot_filename)); - iso9660->el_torito.boot = NULL; - iso9660->el_torito.platform_id = BOOT_PLATFORM_X86; - archive_string_init(&(iso9660->el_torito.id)); - iso9660->el_torito.boot_load_seg = 0; - iso9660->el_torito.boot_load_size = BOOT_LOAD_SIZE; - - /* - * Init zisofs variables. - */ -#ifdef HAVE_ZLIB_H - iso9660->zisofs.block_pointers = NULL; - iso9660->zisofs.block_pointers_allocated = 0; - iso9660->zisofs.stream_valid = 0; - iso9660->zisofs.compression_level = 9; - memset(&(iso9660->zisofs.stream), 0, - sizeof(iso9660->zisofs.stream)); -#endif - - /* - * Set default value of iso9660 options. - */ - iso9660->opt.abstract_file = OPT_ABSTRACT_FILE_DEFAULT; - iso9660->opt.application_id = OPT_APPLICATION_ID_DEFAULT; - iso9660->opt.allow_vernum = OPT_ALLOW_VERNUM_DEFAULT; - iso9660->opt.biblio_file = OPT_BIBLIO_FILE_DEFAULT; - iso9660->opt.boot = OPT_BOOT_DEFAULT; - iso9660->opt.boot_catalog = OPT_BOOT_CATALOG_DEFAULT; - iso9660->opt.boot_info_table = OPT_BOOT_INFO_TABLE_DEFAULT; - iso9660->opt.boot_load_seg = OPT_BOOT_LOAD_SEG_DEFAULT; - iso9660->opt.boot_load_size = OPT_BOOT_LOAD_SIZE_DEFAULT; - iso9660->opt.boot_type = OPT_BOOT_TYPE_DEFAULT; - iso9660->opt.compression_level = OPT_COMPRESSION_LEVEL_DEFAULT; - iso9660->opt.copyright_file = OPT_COPYRIGHT_FILE_DEFAULT; - iso9660->opt.iso_level = OPT_ISO_LEVEL_DEFAULT; - iso9660->opt.joliet = OPT_JOLIET_DEFAULT; - iso9660->opt.limit_depth = OPT_LIMIT_DEPTH_DEFAULT; - iso9660->opt.limit_dirs = OPT_LIMIT_DIRS_DEFAULT; - iso9660->opt.pad = OPT_PAD_DEFAULT; - iso9660->opt.publisher = OPT_PUBLISHER_DEFAULT; - iso9660->opt.rr = OPT_RR_DEFAULT; - iso9660->opt.volume_id = OPT_VOLUME_ID_DEFAULT; - iso9660->opt.zisofs = OPT_ZISOFS_DEFAULT; - - /* Create the root directory. */ - iso9660->primary.rootent = - isoent_create_virtual_dir(a, iso9660, ""); - if (iso9660->primary.rootent == NULL) { - free(iso9660); - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - iso9660->primary.rootent->parent = iso9660->primary.rootent; - iso9660->cur_dirent = iso9660->primary.rootent; - archive_string_init(&(iso9660->cur_dirstr)); - archive_string_ensure(&(iso9660->cur_dirstr), 1); - iso9660->cur_dirstr.s[0] = 0; - iso9660->sconv_to_utf16be = NULL; - iso9660->sconv_from_utf16be = NULL; - - a->format_data = iso9660; - a->format_name = "iso9660"; - a->format_options = iso9660_options; - a->format_write_header = iso9660_write_header; - a->format_write_data = iso9660_write_data; - a->format_finish_entry = iso9660_finish_entry; - a->format_close = iso9660_close; - a->format_free = iso9660_free; - a->archive.archive_format = ARCHIVE_FORMAT_ISO9660; - a->archive.archive_format_name = "ISO9660"; - - return (ARCHIVE_OK); -} - -static int -get_str_opt(struct archive_write *a, struct archive_string *s, - size_t maxsize, const char *key, const char *value) -{ - - if (strlen(value) > maxsize) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Value is longer than %zu characters " - "for option ``%s''", maxsize, key); - return (ARCHIVE_FATAL); - } - archive_strcpy(s, value); - return (ARCHIVE_OK); -} - -static int -get_num_opt(struct archive_write *a, int *num, int high, int low, - const char *key, const char *value) -{ - const char *p = value; - int data = 0; - int neg = 0; - - if (p == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Invalid value(empty) for option ``%s''", key); - return (ARCHIVE_FATAL); - } - if (*p == '-') { - neg = 1; - p++; - } - while (*p) { - if (*p >= '0' && *p <= '9') - data = data * 10 + *p - '0'; - else { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Invalid value for option ``%s''", key); - return (ARCHIVE_FATAL); - } - if (data > high) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Invalid value(over %d) for " - "option ``%s''", high, key); - return (ARCHIVE_FATAL); - } - if (data < low) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Invalid value(under %d) for " - "option ``%s''", low, key); - return (ARCHIVE_FATAL); - } - p++; - } - if (neg) - data *= -1; - *num = data; - - return (ARCHIVE_OK); -} - -static int -iso9660_options(struct archive_write *a, const char *key, const char *value) -{ - struct iso9660 *iso9660 = a->format_data; - const char *p; - int r; - - switch (key[0]) { - case 'a': - if (strcmp(key, "abstract-file") == 0) { - r = get_str_opt(a, - &(iso9660->abstract_file_identifier), - ABSTRACT_FILE_SIZE, key, value); - iso9660->opt.abstract_file = r == ARCHIVE_OK; - return (r); - } - if (strcmp(key, "application-id") == 0) { - r = get_str_opt(a, - &(iso9660->application_identifier), - APPLICATION_IDENTIFIER_SIZE, key, value); - iso9660->opt.application_id = r == ARCHIVE_OK; - return (r); - } - if (strcmp(key, "allow-vernum") == 0) { - iso9660->opt.allow_vernum = value != NULL; - return (ARCHIVE_OK); - } - break; - case 'b': - if (strcmp(key, "biblio-file") == 0) { - r = get_str_opt(a, - &(iso9660->bibliographic_file_identifier), - BIBLIO_FILE_SIZE, key, value); - iso9660->opt.biblio_file = r == ARCHIVE_OK; - return (r); - } - if (strcmp(key, "boot") == 0) { - if (value == NULL) - iso9660->opt.boot = 0; - else { - iso9660->opt.boot = 1; - archive_strcpy( - &(iso9660->el_torito.boot_filename), - value); - } - return (ARCHIVE_OK); - } - if (strcmp(key, "boot-catalog") == 0) { - r = get_str_opt(a, - &(iso9660->el_torito.catalog_filename), - 1024, key, value); - iso9660->opt.boot_catalog = r == ARCHIVE_OK; - return (r); - } - if (strcmp(key, "boot-info-table") == 0) { - iso9660->opt.boot_info_table = value != NULL; - return (ARCHIVE_OK); - } - if (strcmp(key, "boot-load-seg") == 0) { - uint32_t seg; - - iso9660->opt.boot_load_seg = 0; - if (value == NULL) - goto invalid_value; - seg = 0; - p = value; - if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) - p += 2; - while (*p) { - if (seg) - seg <<= 4; - if (*p >= 'A' && *p <= 'F') - seg += *p - 'A' + 0x0a; - else if (*p >= 'a' && *p <= 'f') - seg += *p - 'a' + 0x0a; - else if (*p >= '0' && *p <= '9') - seg += *p - '0'; - else - goto invalid_value; - if (seg > 0xffff) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Invalid value(over 0xffff) for " - "option ``%s''", key); - return (ARCHIVE_FATAL); - } - p++; - } - iso9660->el_torito.boot_load_seg = (uint16_t)seg; - iso9660->opt.boot_load_seg = 1; - return (ARCHIVE_OK); - } - if (strcmp(key, "boot-load-size") == 0) { - int num = 0; - r = get_num_opt(a, &num, 0xffff, 1, key, value); - iso9660->opt.boot_load_size = r == ARCHIVE_OK; - if (r != ARCHIVE_OK) - return (ARCHIVE_FATAL); - iso9660->el_torito.boot_load_size = (uint16_t)num; - return (ARCHIVE_OK); - } - if (strcmp(key, "boot-type") == 0) { - if (value == NULL) - goto invalid_value; - if (strcmp(value, "no-emulation") == 0) - iso9660->opt.boot_type = OPT_BOOT_TYPE_NO_EMU; - else if (strcmp(value, "fd") == 0) - iso9660->opt.boot_type = OPT_BOOT_TYPE_FD; - else if (strcmp(value, "hard-disk") == 0) - iso9660->opt.boot_type = OPT_BOOT_TYPE_HARD_DISK; - else - goto invalid_value; - return (ARCHIVE_OK); - } - break; - case 'c': - if (strcmp(key, "compression-level") == 0) { -#ifdef HAVE_ZLIB_H - if (value == NULL || - !(value[0] >= '0' && value[0] <= '9') || - value[1] != '\0') - goto invalid_value; - iso9660->zisofs.compression_level = value[0] - '0'; - iso9660->opt.compression_level = 1; - return (ARCHIVE_OK); -#else - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Option ``%s'' " - "is not supported on this platform.", key); - return (ARCHIVE_FATAL); -#endif - } - if (strcmp(key, "copyright-file") == 0) { - r = get_str_opt(a, - &(iso9660->copyright_file_identifier), - COPYRIGHT_FILE_SIZE, key, value); - iso9660->opt.copyright_file = r == ARCHIVE_OK; - return (r); - } -#ifdef DEBUG - /* Specifies Volume creation date and time; - * year(4),month(2),day(2),hour(2),minute(2),second(2). - * e.g. "20090929033757" - */ - if (strcmp(key, "creation") == 0) { - struct tm tm; - char buf[5]; - - p = value; - if (p == NULL || strlen(p) < 14) - goto invalid_value; - memset(&tm, 0, sizeof(tm)); - memcpy(buf, p, 4); buf[4] = '\0'; p += 4; - tm.tm_year = strtol(buf, NULL, 10) - 1900; - memcpy(buf, p, 2); buf[2] = '\0'; p += 2; - tm.tm_mon = strtol(buf, NULL, 10) - 1; - memcpy(buf, p, 2); buf[2] = '\0'; p += 2; - tm.tm_mday = strtol(buf, NULL, 10); - memcpy(buf, p, 2); buf[2] = '\0'; p += 2; - tm.tm_hour = strtol(buf, NULL, 10); - memcpy(buf, p, 2); buf[2] = '\0'; p += 2; - tm.tm_min = strtol(buf, NULL, 10); - memcpy(buf, p, 2); buf[2] = '\0'; - tm.tm_sec = strtol(buf, NULL, 10); - iso9660->birth_time = mktime(&tm); - return (ARCHIVE_OK); - } -#endif - break; - case 'i': - if (strcmp(key, "iso-level") == 0) { - if (value != NULL && value[1] == '\0' && - (value[0] >= '1' && value[0] <= '4')) { - iso9660->opt.iso_level = value[0]-'0'; - return (ARCHIVE_OK); - } - goto invalid_value; - } - break; - case 'j': - if (strcmp(key, "joliet") == 0) { - if (value == NULL) - iso9660->opt.joliet = OPT_JOLIET_DISABLE; - else if (strcmp(value, "1") == 0) - iso9660->opt.joliet = OPT_JOLIET_ENABLE; - else if (strcmp(value, "long") == 0) - iso9660->opt.joliet = OPT_JOLIET_LONGNAME; - else - goto invalid_value; - return (ARCHIVE_OK); - } - break; - case 'l': - if (strcmp(key, "limit-depth") == 0) { - iso9660->opt.limit_depth = value != NULL; - return (ARCHIVE_OK); - } - if (strcmp(key, "limit-dirs") == 0) { - iso9660->opt.limit_dirs = value != NULL; - return (ARCHIVE_OK); - } - break; - case 'p': - if (strcmp(key, "pad") == 0) { - iso9660->opt.pad = value != NULL; - return (ARCHIVE_OK); - } - if (strcmp(key, "publisher") == 0) { - r = get_str_opt(a, - &(iso9660->publisher_identifier), - PUBLISHER_IDENTIFIER_SIZE, key, value); - iso9660->opt.publisher = r == ARCHIVE_OK; - return (r); - } - break; - case 'r': - if (strcmp(key, "rockridge") == 0 || - strcmp(key, "Rockridge") == 0) { - if (value == NULL) - iso9660->opt.rr = OPT_RR_DISABLED; - else if (strcmp(value, "1") == 0) - iso9660->opt.rr = OPT_RR_USEFUL; - else if (strcmp(value, "strict") == 0) - iso9660->opt.rr = OPT_RR_STRICT; - else if (strcmp(value, "useful") == 0) - iso9660->opt.rr = OPT_RR_USEFUL; - else - goto invalid_value; - return (ARCHIVE_OK); - } - break; - case 'v': - if (strcmp(key, "volume-id") == 0) { - r = get_str_opt(a, &(iso9660->volume_identifier), - VOLUME_IDENTIFIER_SIZE, key, value); - iso9660->opt.volume_id = r == ARCHIVE_OK; - return (r); - } - break; - case 'z': - if (strcmp(key, "zisofs") == 0) { - if (value == NULL) - iso9660->opt.zisofs = OPT_ZISOFS_DISABLED; - else { -#ifdef HAVE_ZLIB_H - iso9660->opt.zisofs = OPT_ZISOFS_DIRECT; -#else - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "``zisofs'' " - "is not supported on this platform."); - return (ARCHIVE_FATAL); -#endif - } - return (ARCHIVE_OK); - } - break; - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); - -invalid_value: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Invalid value for option ``%s''", key); - return (ARCHIVE_FAILED); -} - -static int -iso9660_write_header(struct archive_write *a, struct archive_entry *entry) -{ - struct iso9660 *iso9660; - struct isofile *file; - struct isoent *isoent; - int r, ret = ARCHIVE_OK; - - iso9660 = a->format_data; - - iso9660->cur_file = NULL; - iso9660->bytes_remaining = 0; - iso9660->need_multi_extent = 0; - if (archive_entry_filetype(entry) == AE_IFLNK - && iso9660->opt.rr == OPT_RR_DISABLED) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Ignore symlink file."); - iso9660->cur_file = NULL; - return (ARCHIVE_WARN); - } - if (archive_entry_filetype(entry) == AE_IFREG && - archive_entry_size(entry) >= MULTI_EXTENT_SIZE) { - if (iso9660->opt.iso_level < 3) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Ignore over %lld bytes file. " - "This file too large.", - MULTI_EXTENT_SIZE); - iso9660->cur_file = NULL; - return (ARCHIVE_WARN); - } - iso9660->need_multi_extent = 1; - } - - file = isofile_new(a, entry); - if (file == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate data"); - return (ARCHIVE_FATAL); - } - r = isofile_gen_utility_names(a, file); - if (r < ARCHIVE_WARN) { - isofile_free(file); - return (r); - } - else if (r < ret) - ret = r; - - /* - * Ignore a path which looks like the top of directory name - * since we have already made the root directory of an ISO image. - */ - if (archive_strlen(&(file->parentdir)) == 0 && - archive_strlen(&(file->basename)) == 0) { - isofile_free(file); - return (r); - } - - isofile_add_entry(iso9660, file); - isoent = isoent_new(file); - if (isoent == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate data"); - return (ARCHIVE_FATAL); - } - if (isoent->file->dircnt > iso9660->dircnt_max) - iso9660->dircnt_max = isoent->file->dircnt; - - /* Add the current file into tree */ - r = isoent_tree(a, &isoent); - if (r != ARCHIVE_OK) - return (r); - - /* If there is the same file in tree and - * the current file is older than the file in tree. - * So we don't need the current file data anymore. */ - if (isoent->file != file) - return (ARCHIVE_OK); - - /* Non regular files contents are unneeded to be saved to - * temporary files. */ - if (archive_entry_filetype(file->entry) != AE_IFREG) - return (ret); - - /* - * Set the current file to cur_file to read its contents. - */ - iso9660->cur_file = file; - - if (archive_entry_nlink(file->entry) > 1) { - r = isofile_register_hardlink(a, file); - if (r != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } - - /* - * Prepare to save the contents of the file. - */ - if (iso9660->temp_fd < 0) { - iso9660->temp_fd = __archive_mktemp(NULL); - if (iso9660->temp_fd < 0) { - archive_set_error(&a->archive, errno, - "Couldn't create temporary file"); - return (ARCHIVE_FATAL); - } - } - - /* Save an offset of current file in temporary file. */ - file->content.offset_of_temp = wb_offset(a); - file->cur_content = &(file->content); - r = zisofs_init(a, file); - if (r < ret) - ret = r; - iso9660->bytes_remaining = archive_entry_size(file->entry); - - return (ret); -} - -static int -write_to_temp(struct archive_write *a, const void *buff, size_t s) -{ - struct iso9660 *iso9660 = a->format_data; - ssize_t written; - const unsigned char *b; - - b = (const unsigned char *)buff; - while (s) { - written = write(iso9660->temp_fd, b, s); - if (written < 0) { - archive_set_error(&a->archive, errno, - "Can't write to temporary file"); - return (ARCHIVE_FATAL); - } - s -= written; - b += written; - } - return (ARCHIVE_OK); -} - -static int -wb_write_to_temp(struct archive_write *a, const void *buff, size_t s) -{ - const char *xp = buff; - size_t xs = s; - - /* - * If a written data size is big enough to use system-call - * and there is no waiting data, this calls write_to_temp() in - * order to reduce a extra memory copy. - */ - if (wb_remaining(a) == wb_buffmax() && s > (1024 * 16)) { - struct iso9660 *iso9660 = (struct iso9660 *)a->format_data; - xs = s % LOGICAL_BLOCK_SIZE; - iso9660->wbuff_offset += s - xs; - if (write_to_temp(a, buff, s - xs) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - if (xs == 0) - return (ARCHIVE_OK); - xp += s - xs; - } - - while (xs) { - size_t size = xs; - if (size > wb_remaining(a)) - size = wb_remaining(a); - memcpy(wb_buffptr(a), xp, size); - if (wb_consume(a, size) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - xs -= size; - xp += size; - } - return (ARCHIVE_OK); -} - -static int -wb_write_padding_to_temp(struct archive_write *a, int64_t csize) -{ - size_t ns; - int ret; - - ns = (size_t)(csize % LOGICAL_BLOCK_SIZE); - if (ns != 0) - ret = write_null(a, LOGICAL_BLOCK_SIZE - ns); - else - ret = ARCHIVE_OK; - return (ret); -} - -static ssize_t -write_iso9660_data(struct archive_write *a, const void *buff, size_t s) -{ - struct iso9660 *iso9660 = a->format_data; - size_t ws; - - if (iso9660->temp_fd < 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Couldn't create temporary file"); - return (ARCHIVE_FATAL); - } - - ws = s; - if (iso9660->need_multi_extent && - (iso9660->cur_file->cur_content->size + ws) >= - (MULTI_EXTENT_SIZE - LOGICAL_BLOCK_SIZE)) { - struct content *con; - size_t ts; - - ts = (size_t)(MULTI_EXTENT_SIZE - LOGICAL_BLOCK_SIZE - - iso9660->cur_file->cur_content->size); - - if (iso9660->zisofs.detect_magic) - zisofs_detect_magic(a, buff, ts); - - if (iso9660->zisofs.making) { - if (zisofs_write_to_temp(a, buff, ts) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } else { - if (wb_write_to_temp(a, buff, ts) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - iso9660->cur_file->cur_content->size += ts; - } - - /* Write padding. */ - if (wb_write_padding_to_temp(a, - iso9660->cur_file->cur_content->size) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - /* Compute the logical block number. */ - iso9660->cur_file->cur_content->blocks = (int) - ((iso9660->cur_file->cur_content->size - + LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS); - - /* - * Make next extent. - */ - ws -= ts; - buff = (const void *)(((const unsigned char *)buff) + ts); - /* Make a content for next extent. */ - con = calloc(1, sizeof(*con)); - if (con == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate content data"); - return (ARCHIVE_FATAL); - } - con->offset_of_temp = wb_offset(a); - iso9660->cur_file->cur_content->next = con; - iso9660->cur_file->cur_content = con; -#ifdef HAVE_ZLIB_H - iso9660->zisofs.block_offset = 0; -#endif - } - - if (iso9660->zisofs.detect_magic) - zisofs_detect_magic(a, buff, ws); - - if (iso9660->zisofs.making) { - if (zisofs_write_to_temp(a, buff, ws) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } else { - if (wb_write_to_temp(a, buff, ws) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - iso9660->cur_file->cur_content->size += ws; - } - - return (s); -} - -static ssize_t -iso9660_write_data(struct archive_write *a, const void *buff, size_t s) -{ - struct iso9660 *iso9660 = a->format_data; - ssize_t r; - - if (iso9660->cur_file == NULL) - return (0); - if (archive_entry_filetype(iso9660->cur_file->entry) != AE_IFREG) - return (0); - if (s > iso9660->bytes_remaining) - s = (size_t)iso9660->bytes_remaining; - if (s == 0) - return (0); - - r = write_iso9660_data(a, buff, s); - if (r > 0) - iso9660->bytes_remaining -= r; - return (r); -} - -static int -iso9660_finish_entry(struct archive_write *a) -{ - struct iso9660 *iso9660 = a->format_data; - - if (iso9660->cur_file == NULL) - return (ARCHIVE_OK); - if (archive_entry_filetype(iso9660->cur_file->entry) != AE_IFREG) - return (ARCHIVE_OK); - if (iso9660->cur_file->content.size == 0) - return (ARCHIVE_OK); - - /* If there are unwritten data, write null data instead. */ - while (iso9660->bytes_remaining > 0) { - size_t s; - - s = (iso9660->bytes_remaining > a->null_length)? - a->null_length: (size_t)iso9660->bytes_remaining; - if (write_iso9660_data(a, a->nulls, s) < 0) - return (ARCHIVE_FATAL); - iso9660->bytes_remaining -= s; - } - - if (iso9660->zisofs.making && zisofs_finish_entry(a) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - /* Write padding. */ - if (wb_write_padding_to_temp(a, iso9660->cur_file->cur_content->size) - != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - /* Compute the logical block number. */ - iso9660->cur_file->cur_content->blocks = (int) - ((iso9660->cur_file->cur_content->size - + LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS); - - /* Add the current file to data file list. */ - isofile_add_data_file(iso9660, iso9660->cur_file); - - return (ARCHIVE_OK); -} - -static int -iso9660_close(struct archive_write *a) -{ - struct iso9660 *iso9660; - int ret, blocks; - - iso9660 = a->format_data; - - /* - * Write remaining data out to the temporary file. - */ - if (wb_remaining(a) > 0) { - ret = wb_write_out(a); - if (ret < 0) - return (ret); - } - - /* - * Preparations... - */ -#ifdef DEBUG - if (iso9660->birth_time == 0) -#endif - time(&(iso9660->birth_time)); - - /* - * Prepare a bootable ISO image. - */ - if (iso9660->opt.boot) { - /* Find out the boot file entry. */ - ret = isoent_find_out_boot_file(a, iso9660->primary.rootent); - if (ret < 0) - return (ret); - /* Reconvert the boot file from zisofs'ed form to - * plain form. */ - ret = zisofs_rewind_boot_file(a); - if (ret < 0) - return (ret); - /* Write remaining data out to the temporary file. */ - if (wb_remaining(a) > 0) { - ret = wb_write_out(a); - if (ret < 0) - return (ret); - } - /* Create the boot catalog. */ - ret = isoent_create_boot_catalog(a, iso9660->primary.rootent); - if (ret < 0) - return (ret); - } - - /* - * Prepare joliet extensions. - */ - if (iso9660->opt.joliet) { - /* Make a new tree for joliet. */ - ret = isoent_clone_tree(a, &(iso9660->joliet.rootent), - iso9660->primary.rootent); - if (ret < 0) - return (ret); - /* Make sure we have UTF-16BE converters. - * if there is no file entry, converters are still - * uninitialized. */ - if (iso9660->sconv_to_utf16be == NULL) { - iso9660->sconv_to_utf16be = - archive_string_conversion_to_charset( - &(a->archive), "UTF-16BE", 1); - if (iso9660->sconv_to_utf16be == NULL) - /* Couldn't allocate memory */ - return (ARCHIVE_FATAL); - iso9660->sconv_from_utf16be = - archive_string_conversion_from_charset( - &(a->archive), "UTF-16BE", 1); - if (iso9660->sconv_from_utf16be == NULL) - /* Couldn't allocate memory */ - return (ARCHIVE_FATAL); - } - } - - /* - * Make Path Tables. - */ - ret = isoent_make_path_table(a); - if (ret < 0) - return (ret); - - /* - * Calculate a total volume size and setup all locations of - * contents of an iso9660 image. - */ - blocks = SYSTEM_AREA_BLOCK - + PRIMARY_VOLUME_DESCRIPTOR_BLOCK - + VOLUME_DESCRIPTOR_SET_TERMINATOR_BLOCK - + NON_ISO_FILE_SYSTEM_INFORMATION_BLOCK; - if (iso9660->opt.boot) - blocks += BOOT_RECORD_DESCRIPTOR_BLOCK; - if (iso9660->opt.joliet) - blocks += SUPPLEMENTARY_VOLUME_DESCRIPTOR_BLOCK; - if (iso9660->opt.iso_level == 4) - blocks += SUPPLEMENTARY_VOLUME_DESCRIPTOR_BLOCK; - - /* Setup the locations of Path Table. */ - iso9660->primary.location_type_L_path_table = blocks; - blocks += iso9660->primary.path_table_block; - iso9660->primary.location_type_M_path_table = blocks; - blocks += iso9660->primary.path_table_block; - if (iso9660->opt.joliet) { - iso9660->joliet.location_type_L_path_table = blocks; - blocks += iso9660->joliet.path_table_block; - iso9660->joliet.location_type_M_path_table = blocks; - blocks += iso9660->joliet.path_table_block; - } - - /* Setup the locations of directories. */ - isoent_setup_directory_location(iso9660, blocks, - &(iso9660->primary)); - blocks += iso9660->primary.total_dir_block; - if (iso9660->opt.joliet) { - isoent_setup_directory_location(iso9660, blocks, - &(iso9660->joliet)); - blocks += iso9660->joliet.total_dir_block; - } - - if (iso9660->opt.rr) { - iso9660->location_rrip_er = blocks; - blocks += RRIP_ER_BLOCK; - } - - /* Setup the locations of all file contents. */ - isoent_setup_file_location(iso9660, blocks); - blocks += iso9660->total_file_block; - if (iso9660->opt.boot && iso9660->opt.boot_info_table) { - ret = setup_boot_information(a); - if (ret < 0) - return (ret); - } - - /* Now we have a total volume size. */ - iso9660->volume_space_size = blocks; - if (iso9660->opt.pad) - iso9660->volume_space_size += PADDING_BLOCK; - iso9660->volume_sequence_number = 1; - - - /* - * Write an ISO 9660 image. - */ - - /* Switch to start using wbuff as file buffer. */ - iso9660->wbuff_remaining = wb_buffmax(); - iso9660->wbuff_type = WB_TO_STREAM; - iso9660->wbuff_offset = 0; - iso9660->wbuff_written = 0; - iso9660->wbuff_tail = 0; - - /* Write The System Area */ - ret = write_null(a, SYSTEM_AREA_BLOCK * LOGICAL_BLOCK_SIZE); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - /* Write Primary Volume Descriptor */ - ret = write_VD(a, &(iso9660->primary)); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - if (iso9660->opt.boot) { - /* Write Boot Record Volume Descriptor */ - ret = write_VD_boot_record(a); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } - - if (iso9660->opt.iso_level == 4) { - /* Write Enhanced Volume Descriptor */ - iso9660->primary.vdd_type = VDD_ENHANCED; - ret = write_VD(a, &(iso9660->primary)); - iso9660->primary.vdd_type = VDD_PRIMARY; - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } - - if (iso9660->opt.joliet) { - ret = write_VD(a, &(iso9660->joliet)); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } - - /* Write Volume Descriptor Set Terminator */ - ret = write_VD_terminator(a); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - /* Write Non-ISO File System Information */ - ret = write_information_block(a); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - /* Write Type L Path Table */ - ret = write_path_table(a, 0, &(iso9660->primary)); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - /* Write Type M Path Table */ - ret = write_path_table(a, 1, &(iso9660->primary)); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - if (iso9660->opt.joliet) { - /* Write Type L Path Table */ - ret = write_path_table(a, 0, &(iso9660->joliet)); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - /* Write Type M Path Table */ - ret = write_path_table(a, 1, &(iso9660->joliet)); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } - - /* Write Directory Descriptors */ - ret = write_directory_descriptors(a, &(iso9660->primary)); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - if (iso9660->opt.joliet) { - ret = write_directory_descriptors(a, &(iso9660->joliet)); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } - - if (iso9660->opt.rr) { - /* Write Rockridge ER(Extensions Reference) */ - ret = write_rr_ER(a); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } - - /* Write File Descriptors */ - ret = write_file_descriptors(a); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - /* Write Padding */ - if (iso9660->opt.pad) { - ret = write_null(a, PADDING_BLOCK * LOGICAL_BLOCK_SIZE); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } - - if (iso9660->directories_too_deep != NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "%s: Directories too deep.", - archive_entry_pathname( - iso9660->directories_too_deep->file->entry)); - return (ARCHIVE_WARN); - } - - /* Write remaining data out. */ - ret = wb_write_out(a); - - return (ret); -} - -static int -iso9660_free(struct archive_write *a) -{ - struct iso9660 *iso9660; - int i, ret; - - iso9660 = a->format_data; - - /* Close the temporary file. */ - if (iso9660->temp_fd >= 0) - close(iso9660->temp_fd); - - /* Free some stuff for zisofs operations. */ - ret = zisofs_free(a); - - /* Remove directory entries in tree which includes file entries. */ - isoent_free_all(iso9660->primary.rootent); - for (i = 0; i < iso9660->primary.max_depth; i++) - free(iso9660->primary.pathtbl[i].sorted); - free(iso9660->primary.pathtbl); - - if (iso9660->opt.joliet) { - isoent_free_all(iso9660->joliet.rootent); - for (i = 0; i < iso9660->joliet.max_depth; i++) - free(iso9660->joliet.pathtbl[i].sorted); - free(iso9660->joliet.pathtbl); - } - - /* Remove isofile entries. */ - isofile_free_all_entries(iso9660); - isofile_free_hardlinks(iso9660); - - archive_string_free(&(iso9660->cur_dirstr)); - archive_string_free(&(iso9660->volume_identifier)); - archive_string_free(&(iso9660->publisher_identifier)); - archive_string_free(&(iso9660->data_preparer_identifier)); - archive_string_free(&(iso9660->application_identifier)); - archive_string_free(&(iso9660->copyright_file_identifier)); - archive_string_free(&(iso9660->abstract_file_identifier)); - archive_string_free(&(iso9660->bibliographic_file_identifier)); - archive_string_free(&(iso9660->el_torito.catalog_filename)); - archive_string_free(&(iso9660->el_torito.boot_filename)); - archive_string_free(&(iso9660->el_torito.id)); - archive_string_free(&(iso9660->utf16be)); - archive_string_free(&(iso9660->mbs)); - - free(iso9660); - a->format_data = NULL; - - return (ret); -} - -/* - * Get the System Identifier - */ -static void -get_system_identitier(char *system_id, size_t size) -{ -#if defined(HAVE_SYS_UTSNAME_H) - struct utsname u; - - uname(&u); - strncpy(system_id, u.sysname, size-1); - system_id[size-1] = '\0'; -#elif defined(_WIN32) && !defined(__CYGWIN__) - strncpy(system_id, "Windows", size-1); - system_id[size-1] = '\0'; -#else - strncpy(system_id, "Unknown", size-1); - system_id[size-1] = '\0'; -#endif -} - -static void -set_str(unsigned char *p, const char *s, size_t l, char f, const char *map) -{ - unsigned char c; - - if (s == NULL) - s = ""; - while ((c = *s++) != 0 && l > 0) { - if (c >= 0x80 || map[c] == 0) - { - /* illegal character */ - if (c >= 'a' && c <= 'z') { - /* convert c from a-z to A-Z */ - c -= 0x20; - } else - c = 0x5f; - } - *p++ = c; - l--; - } - /* If l isn't zero, fill p buffer by the character - * which indicated by f. */ - if (l > 0) - memset(p , f, l); -} - -static inline int -joliet_allowed_char(unsigned char high, unsigned char low) -{ - int utf16 = (high << 8) | low; - - if (utf16 <= 0x001F) - return (0); - - switch (utf16) { - case 0x002A: /* '*' */ - case 0x002F: /* '/' */ - case 0x003A: /* ':' */ - case 0x003B: /* ';' */ - case 0x003F: /* '?' */ - case 0x005C: /* '\' */ - return (0);/* Not allowed. */ - } - return (1); -} - -static int -set_str_utf16be(struct archive_write *a, unsigned char *p, const char *s, - size_t l, uint16_t uf, enum vdc vdc) -{ - size_t size, i; - int onepad; - - if (s == NULL) - s = ""; - if (l & 0x01) { - onepad = 1; - l &= ~1; - } else - onepad = 0; - if (vdc == VDC_UCS2) { - struct iso9660 *iso9660 = a->format_data; - if (archive_strncpy_l(&iso9660->utf16be, s, strlen(s), - iso9660->sconv_to_utf16be) != 0 && errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for UTF-16BE"); - return (ARCHIVE_FATAL); - } - size = iso9660->utf16be.length; - if (size > l) - size = l; - memcpy(p, iso9660->utf16be.s, size); - } else { - const uint16_t *u16 = (const uint16_t *)s; - - size = 0; - while (*u16++) - size += 2; - if (size > l) - size = l; - memcpy(p, s, size); - } - for (i = 0; i < size; i += 2, p += 2) { - if (!joliet_allowed_char(p[0], p[1])) - archive_be16enc(p, 0x005F);/* '_' */ - } - l -= size; - while (l > 0) { - archive_be16enc(p, uf); - p += 2; - l -= 2; - } - if (onepad) - *p = 0; - return (ARCHIVE_OK); -} - -static const char a_characters_map[0x80] = { -/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */ - 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 20-2F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 30-3F */ - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 60-6F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 70-7F */ -}; - -static const char a1_characters_map[0x80] = { -/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */ - 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 20-2F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 30-3F */ - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */ - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 60-6F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,/* 70-7F */ -}; - -static const char d_characters_map[0x80] = { -/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 20-2F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,/* 30-3F */ - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 60-6F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 70-7F */ -}; - -static const char d1_characters_map[0x80] = { -/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 20-2F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,/* 30-3F */ - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */ - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 60-6F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,/* 70-7F */ -}; - -static int -set_str_a_characters_bp(struct archive_write *a, unsigned char *bp, - int from, int to, const char *s, enum vdc vdc) -{ - int r; - - switch (vdc) { - case VDC_STD: - set_str(bp+from, s, to - from + 1, 0x20, - a_characters_map); - r = ARCHIVE_OK; - break; - case VDC_LOWERCASE: - set_str(bp+from, s, to - from + 1, 0x20, - a1_characters_map); - r = ARCHIVE_OK; - break; - case VDC_UCS2: - case VDC_UCS2_DIRECT: - r = set_str_utf16be(a, bp+from, s, to - from + 1, - 0x0020, vdc); - break; - default: - r = ARCHIVE_FATAL; - } - return (r); -} - -static int -set_str_d_characters_bp(struct archive_write *a, unsigned char *bp, - int from, int to, const char *s, enum vdc vdc) -{ - int r; - - switch (vdc) { - case VDC_STD: - set_str(bp+from, s, to - from + 1, 0x20, - d_characters_map); - r = ARCHIVE_OK; - break; - case VDC_LOWERCASE: - set_str(bp+from, s, to - from + 1, 0x20, - d1_characters_map); - r = ARCHIVE_OK; - break; - case VDC_UCS2: - case VDC_UCS2_DIRECT: - r = set_str_utf16be(a, bp+from, s, to - from + 1, - 0x0020, vdc); - break; - default: - r = ARCHIVE_FATAL; - } - return (r); -} - -static void -set_VD_bp(unsigned char *bp, enum VD_type type, unsigned char ver) -{ - - /* Volume Descriptor Type */ - bp[1] = (unsigned char)type; - /* Standard Identifier */ - memcpy(bp + 2, "CD001", 5); - /* Volume Descriptor Version */ - bp[7] = ver; -} - -static inline void -set_unused_field_bp(unsigned char *bp, int from, int to) -{ - memset(bp + from, 0, to - from + 1); -} - -/* - * 8-bit unsigned numerical values. - * ISO9660 Standard 7.1.1 - */ -static inline void -set_num_711(unsigned char *p, unsigned char value) -{ - *p = value; -} - -/* - * 8-bit signed numerical values. - * ISO9660 Standard 7.1.2 - */ -static inline void -set_num_712(unsigned char *p, char value) -{ - *((char *)p) = value; -} - -/* - * Least significant byte first. - * ISO9660 Standard 7.2.1 - */ -static inline void -set_num_721(unsigned char *p, uint16_t value) -{ - archive_le16enc(p, value); -} - -/* - * Most significant byte first. - * ISO9660 Standard 7.2.2 - */ -static inline void -set_num_722(unsigned char *p, uint16_t value) -{ - archive_be16enc(p, value); -} - -/* - * Both-byte orders. - * ISO9660 Standard 7.2.3 - */ -static void -set_num_723(unsigned char *p, uint16_t value) -{ - archive_le16enc(p, value); - archive_be16enc(p+2, value); -} - -/* - * Least significant byte first. - * ISO9660 Standard 7.3.1 - */ -static inline void -set_num_731(unsigned char *p, uint32_t value) -{ - archive_le32enc(p, value); -} - -/* - * Most significant byte first. - * ISO9660 Standard 7.3.2 - */ -static inline void -set_num_732(unsigned char *p, uint32_t value) -{ - archive_be32enc(p, value); -} - -/* - * Both-byte orders. - * ISO9660 Standard 7.3.3 - */ -static inline void -set_num_733(unsigned char *p, uint32_t value) -{ - archive_le32enc(p, value); - archive_be32enc(p+4, value); -} - -static void -set_digit(unsigned char *p, size_t s, int value) -{ - - while (s--) { - p[s] = '0' + (value % 10); - value /= 10; - } -} - -#if defined(HAVE_STRUCT_TM_TM_GMTOFF) -#define get_gmoffset(tm) ((tm)->tm_gmtoff) -#elif defined(HAVE_STRUCT_TM___TM_GMTOFF) -#define get_gmoffset(tm) ((tm)->__tm_gmtoff) -#else -static long -get_gmoffset(struct tm *tm) -{ - long offset; - -#if defined(HAVE__GET_TIMEZONE) - _get_timezone(&offset); -#elif defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__) - offset = _timezone; -#else - offset = timezone; -#endif - offset *= -1; - if (tm->tm_isdst) - offset += 3600; - return (offset); -} -#endif - -static void -get_tmfromtime(struct tm *tm, time_t *t) -{ -#if HAVE_LOCALTIME_S - localtime_s(tm, t); -#elif HAVE_LOCALTIME_R - tzset(); - localtime_r(t, tm); -#else - memcpy(tm, localtime(t), sizeof(*tm)); -#endif -} - -/* - * Date and Time Format. - * ISO9660 Standard 8.4.26.1 - */ -static void -set_date_time(unsigned char *p, time_t t) -{ - struct tm tm; - - get_tmfromtime(&tm, &t); - set_digit(p, 4, tm.tm_year + 1900); - set_digit(p+4, 2, tm.tm_mon + 1); - set_digit(p+6, 2, tm.tm_mday); - set_digit(p+8, 2, tm.tm_hour); - set_digit(p+10, 2, tm.tm_min); - set_digit(p+12, 2, tm.tm_sec); - set_digit(p+14, 2, 0); - set_num_712(p+16, (char)(get_gmoffset(&tm)/(60*15))); -} - -static void -set_date_time_null(unsigned char *p) -{ - memset(p, (int)'0', 16); - p[16] = 0; -} - -static void -set_time_915(unsigned char *p, time_t t) -{ - struct tm tm; - - get_tmfromtime(&tm, &t); - set_num_711(p+0, tm.tm_year); - set_num_711(p+1, tm.tm_mon+1); - set_num_711(p+2, tm.tm_mday); - set_num_711(p+3, tm.tm_hour); - set_num_711(p+4, tm.tm_min); - set_num_711(p+5, tm.tm_sec); - set_num_712(p+6, (char)(get_gmoffset(&tm)/(60*15))); -} - - -/* - * Write SUSP "CE" System Use Entry. - */ -static int -set_SUSP_CE(unsigned char *p, int location, int offset, int size) -{ - unsigned char *bp = p -1; - /* Extend the System Use Area - * "CE" Format: - * len ver - * +----+----+----+----+-----------+-----------+ - * | 'C'| 'E'| 1C | 01 | LOCATION1 | LOCATION2 | - * +----+----+----+----+-----------+-----------+ - * 0 1 2 3 4 12 20 - * +-----------+ - * | LOCATION3 | - * +-----------+ - * 20 28 - * LOCATION1 : Location of Continuation of System Use Area. - * LOCATION2 : Offset to Start of Continuation. - * LOCATION3 : Length of the Continuation. - */ - - bp[1] = 'C'; - bp[2] = 'E'; - bp[3] = RR_CE_SIZE; /* length */ - bp[4] = 1; /* version */ - set_num_733(bp+5, location); - set_num_733(bp+13, offset); - set_num_733(bp+21, size); - return (RR_CE_SIZE); -} - -/* - * The functions, which names are beginning with extra_, are used to - * control extra records. - * The maximum size of a Directory Record is 254. When a filename is - * very long, all of RRIP data of a file won't stored to the Directory - * Record and so remaining RRIP data store to an extra record instead. - */ -static unsigned char * -extra_open_record(unsigned char *bp, int dr_len, struct isoent *isoent, - struct ctl_extr_rec *ctl) -{ - ctl->bp = bp; - if (bp != NULL) - bp += dr_len; - ctl->use_extr = 0; - ctl->isoent = isoent; - ctl->ce_ptr = NULL; - ctl->cur_len = ctl->dr_len = dr_len; - ctl->limit = DR_LIMIT; - - return (bp); -} - -static void -extra_close_record(struct ctl_extr_rec *ctl, int ce_size) -{ - int padding = 0; - - if (ce_size > 0) - extra_tell_used_size(ctl, ce_size); - /* Padding. */ - if (ctl->cur_len & 0x01) { - ctl->cur_len++; - if (ctl->bp != NULL) - ctl->bp[ctl->cur_len] = 0; - padding = 1; - } - if (ctl->use_extr) { - if (ctl->ce_ptr != NULL) - set_SUSP_CE(ctl->ce_ptr, ctl->extr_loc, - ctl->extr_off, ctl->cur_len - padding); - } else - ctl->dr_len = ctl->cur_len; -} - -#define extra_space(ctl) ((ctl)->limit - (ctl)->cur_len) - -static unsigned char * -extra_next_record(struct ctl_extr_rec *ctl, int length) -{ - int cur_len = ctl->cur_len;/* save cur_len */ - - /* Close the current extra record or Directory Record. */ - extra_close_record(ctl, RR_CE_SIZE); - - /* Get a next extra record. */ - ctl->use_extr = 1; - if (ctl->bp != NULL) { - /* Storing data into an extra record. */ - unsigned char *p; - - /* Save the pointer where a CE extension will be - * stored to. */ - ctl->ce_ptr = &ctl->bp[cur_len+1]; - p = extra_get_record(ctl->isoent, - &ctl->limit, &ctl->extr_off, &ctl->extr_loc); - ctl->bp = p - 1;/* the base of bp offset is 1. */ - } else - /* Calculating the size of an extra record. */ - (void)extra_get_record(ctl->isoent, - &ctl->limit, NULL, NULL); - ctl->cur_len = 0; - /* Check if an extra record is almost full. - * If so, get a next one. */ - if (extra_space(ctl) < length) - (void)extra_next_record(ctl, length); - - return (ctl->bp); -} - -static inline struct extr_rec * -extra_last_record(struct isoent *isoent) -{ - if (isoent->extr_rec_list.first == NULL) - return (NULL); - return ((struct extr_rec *)(void *) - ((char *)(isoent->extr_rec_list.last) - - offsetof(struct extr_rec, next))); -} - -static unsigned char * -extra_get_record(struct isoent *isoent, int *space, int *off, int *loc) -{ - struct extr_rec *rec; - - isoent = isoent->parent; - if (off != NULL) { - /* Storing data into an extra record. */ - rec = isoent->extr_rec_list.current; - if (DR_SAFETY > LOGICAL_BLOCK_SIZE - rec->offset) - rec = rec->next; - } else { - /* Calculating the size of an extra record. */ - rec = extra_last_record(isoent); - if (rec == NULL || - DR_SAFETY > LOGICAL_BLOCK_SIZE - rec->offset) { - rec = malloc(sizeof(*rec)); - if (rec == NULL) - return (NULL); - rec->location = 0; - rec->offset = 0; - /* Insert `rec` into the tail of isoent->extr_rec_list */ - rec->next = NULL; - /* - * Note: testing isoent->extr_rec_list.last == NULL - * here is really unneeded since it has been already - * initialized at isoent_new function but Clang Static - * Analyzer claims that it is dereference of null - * pointer. - */ - if (isoent->extr_rec_list.last == NULL) - isoent->extr_rec_list.last = - &(isoent->extr_rec_list.first); - *isoent->extr_rec_list.last = rec; - isoent->extr_rec_list.last = &(rec->next); - } - } - *space = LOGICAL_BLOCK_SIZE - rec->offset - DR_SAFETY; - if (*space & 0x01) - *space -= 1;/* Keep padding space. */ - if (off != NULL) - *off = rec->offset; - if (loc != NULL) - *loc = rec->location; - isoent->extr_rec_list.current = rec; - - return (&rec->buf[rec->offset]); -} - -static void -extra_tell_used_size(struct ctl_extr_rec *ctl, int size) -{ - struct isoent *isoent; - struct extr_rec *rec; - - if (ctl->use_extr) { - isoent = ctl->isoent->parent; - rec = isoent->extr_rec_list.current; - if (rec != NULL) - rec->offset += size; - } - ctl->cur_len += size; -} - -static int -extra_setup_location(struct isoent *isoent, int location) -{ - struct extr_rec *rec; - int cnt; - - cnt = 0; - rec = isoent->extr_rec_list.first; - isoent->extr_rec_list.current = rec; - while (rec) { - cnt++; - rec->location = location++; - rec->offset = 0; - rec = rec->next; - } - return (cnt); -} - -/* - * Create the RRIP entries. - */ -static int -set_directory_record_rr(unsigned char *bp, int dr_len, - struct isoent *isoent, struct iso9660 *iso9660, enum dir_rec_type t) -{ - /* Flags(BP 5) of the Rockridge "RR" System Use Field */ - unsigned char rr_flag; -#define RR_USE_PX 0x01 -#define RR_USE_PN 0x02 -#define RR_USE_SL 0x04 -#define RR_USE_NM 0x08 -#define RR_USE_CL 0x10 -#define RR_USE_PL 0x20 -#define RR_USE_RE 0x40 -#define RR_USE_TF 0x80 - int length; - struct ctl_extr_rec ctl; - struct isoent *rr_parent, *pxent; - struct isofile *file; - - bp = extra_open_record(bp, dr_len, isoent, &ctl); - - if (t == DIR_REC_PARENT) { - rr_parent = isoent->rr_parent; - pxent = isoent->parent; - if (rr_parent != NULL) - isoent = rr_parent; - else - isoent = isoent->parent; - } else { - rr_parent = NULL; - pxent = isoent; - } - file = isoent->file; - - if (t != DIR_REC_NORMAL) { - rr_flag = RR_USE_PX | RR_USE_TF; - if (rr_parent != NULL) - rr_flag |= RR_USE_PL; - } else { - rr_flag = RR_USE_PX | RR_USE_NM | RR_USE_TF; - if (archive_entry_filetype(file->entry) == AE_IFLNK) - rr_flag |= RR_USE_SL; - if (isoent->rr_parent != NULL) - rr_flag |= RR_USE_RE; - if (isoent->rr_child != NULL) - rr_flag |= RR_USE_CL; - if (archive_entry_filetype(file->entry) == AE_IFCHR || - archive_entry_filetype(file->entry) == AE_IFBLK) - rr_flag |= RR_USE_PN; -#ifdef COMPAT_MKISOFS - /* - * mkisofs 2.01.01a63 records "RE" extension to - * the entry of "rr_moved" directory. - * I don't understand this behavior. - */ - if (isoent->virtual && - isoent->parent == iso9660->primary.rootent && - strcmp(isoent->file->basename.s, "rr_moved") == 0) - rr_flag |= RR_USE_RE; -#endif - } - - /* Write "SP" System Use Entry. */ - if (t == DIR_REC_SELF && isoent == isoent->parent) { - length = 7; - if (bp != NULL) { - bp[1] = 'S'; - bp[2] = 'P'; - bp[3] = length; - bp[4] = 1; /* version */ - bp[5] = 0xBE; /* Check Byte */ - bp[6] = 0xEF; /* Check Byte */ - bp[7] = 0; - bp += length; - } - extra_tell_used_size(&ctl, length); - } - - /* Write "RR" System Use Entry. */ - length = 5; - if (extra_space(&ctl) < length) - bp = extra_next_record(&ctl, length); - if (bp != NULL) { - bp[1] = 'R'; - bp[2] = 'R'; - bp[3] = length; - bp[4] = 1; /* version */ - bp[5] = rr_flag; - bp += length; - } - extra_tell_used_size(&ctl, length); - - /* Write "NM" System Use Entry. */ - if (rr_flag & RR_USE_NM) { - /* - * "NM" Format: - * e.g. a basename is 'foo' - * len ver flg - * +----+----+----+----+----+----+----+----+ - * | 'N'| 'M'| 08 | 01 | 00 | 'f'| 'o'| 'o'| - * +----+----+----+----+----+----+----+----+ - * <----------------- len -----------------> - */ - size_t nmlen = file->basename.length; - const char *nm = file->basename.s; - size_t nmmax; - - if (extra_space(&ctl) < 6) - bp = extra_next_record(&ctl, 6); - if (bp != NULL) { - bp[1] = 'N'; - bp[2] = 'M'; - bp[4] = 1; /* version */ - } - nmmax = extra_space(&ctl); - if (nmmax > 0xff) - nmmax = 0xff; - while (nmlen + 5 > nmmax) { - length = (int)nmmax; - if (bp != NULL) { - bp[3] = length; - bp[5] = 0x01;/* Alternate Name continues - * in next "NM" field */ - memcpy(bp+6, nm, length - 5); - bp += length; - } - nmlen -= length - 5; - nm += length - 5; - extra_tell_used_size(&ctl, length); - if (extra_space(&ctl) < 6) { - bp = extra_next_record(&ctl, 6); - nmmax = extra_space(&ctl); - if (nmmax > 0xff) - nmmax = 0xff; - } - if (bp != NULL) { - bp[1] = 'N'; - bp[2] = 'M'; - bp[4] = 1; /* version */ - } - } - length = 5 + (int)nmlen; - if (bp != NULL) { - bp[3] = length; - bp[5] = 0; - memcpy(bp+6, nm, nmlen); - bp += length; - } - extra_tell_used_size(&ctl, length); - } - - /* Write "PX" System Use Entry. */ - if (rr_flag & RR_USE_PX) { - /* - * "PX" Format: - * len ver - * +----+----+----+----+-----------+-----------+ - * | 'P'| 'X'| 2C | 01 | FILE MODE | LINKS | - * +----+----+----+----+-----------+-----------+ - * 0 1 2 3 4 12 20 - * +-----------+-----------+------------------+ - * | USER ID | GROUP ID |FILE SERIAL NUMBER| - * +-----------+-----------+------------------+ - * 20 28 36 44 - */ - length = 44; - if (extra_space(&ctl) < length) - bp = extra_next_record(&ctl, length); - if (bp != NULL) { - mode_t mode; - int64_t uid; - int64_t gid; - - mode = archive_entry_mode(file->entry); - uid = archive_entry_uid(file->entry); - gid = archive_entry_gid(file->entry); - if (iso9660->opt.rr == OPT_RR_USEFUL) { - /* - * This action is similar to mkisofs -r option - * but our rockridge=useful option does not - * set a zero to uid and gid. - */ - /* set all read bit ON */ - mode |= 0444; -#if !defined(_WIN32) && !defined(__CYGWIN__) - if (mode & 0111) -#endif - /* set all exec bit ON */ - mode |= 0111; - /* clear all write bits. */ - mode &= ~0222; - /* clear setuid,setgid,sticky bits. */ - mode &= ~07000; - } - - bp[1] = 'P'; - bp[2] = 'X'; - bp[3] = length; - bp[4] = 1; /* version */ - /* file mode */ - set_num_733(bp+5, mode); - /* file links (stat.st_nlink) */ - set_num_733(bp+13, - archive_entry_nlink(file->entry)); - set_num_733(bp+21, (uint32_t)uid); - set_num_733(bp+29, (uint32_t)gid); - /* File Serial Number */ - if (pxent->dir) - set_num_733(bp+37, pxent->dir_location); - else if (file->hardlink_target != NULL) - set_num_733(bp+37, - file->hardlink_target->cur_content->location); - else - set_num_733(bp+37, - file->cur_content->location); - bp += length; - } - extra_tell_used_size(&ctl, length); - } - - /* Write "SL" System Use Entry. */ - if (rr_flag & RR_USE_SL) { - /* - * "SL" Format: - * e.g. a symbolic name is 'foo/bar' - * len ver flg - * +----+----+----+----+----+------------+ - * | 'S'| 'L'| 0F | 01 | 00 | components | - * +----+----+----+----+----+-----+------+ - * 0 1 2 3 4 5 ...|... 15 - * <----------------- len --------+------> - * components : | - * cflg clen | - * +----+----+----+----+----+ | - * | 00 | 03 | 'f'| 'o'| 'o'| <---+ - * +----+----+----+----+----+ | - * 5 6 7 8 9 10 | - * cflg clen | - * +----+----+----+----+----+ | - * | 00 | 03 | 'b'| 'a'| 'r'| <---+ - * +----+----+----+----+----+ - * 10 11 12 13 14 15 - * - * - cflg : flag of component - * - clen : length of component - */ - const char *sl; - char sl_last; - - if (extra_space(&ctl) < 7) - bp = extra_next_record(&ctl, 7); - sl = file->symlink.s; - sl_last = '\0'; - if (bp != NULL) { - bp[1] = 'S'; - bp[2] = 'L'; - bp[4] = 1; /* version */ - } - for (;;) { - unsigned char *nc, *cf, *cl, cldmy = 0; - int sllen, slmax; - - slmax = extra_space(&ctl); - if (slmax > 0xff) - slmax = 0xff; - if (bp != NULL) - nc = &bp[6]; - else - nc = NULL; - cf = cl = NULL; - sllen = 0; - while (*sl && sllen + 11 < slmax) { - if (sl_last == '\0' && sl[0] == '/') { - /* - * flg len - * +----+----+ - * | 08 | 00 | ROOT component. - * +----+----+ ("/") - * - * Root component has to appear - * at the first component only. - */ - if (nc != NULL) { - cf = nc++; - *cf = 0x08; /* ROOT */ - *nc++ = 0; - } - sllen += 2; - sl++; - sl_last = '/'; - cl = NULL; - continue; - } - if (((sl_last == '\0' || sl_last == '/') && - sl[0] == '.' && sl[1] == '.' && - (sl[2] == '/' || sl[2] == '\0')) || - (sl[0] == '/' && - sl[1] == '.' && sl[2] == '.' && - (sl[3] == '/' || sl[3] == '\0'))) { - /* - * flg len - * +----+----+ - * | 04 | 00 | PARENT component. - * +----+----+ ("..") - */ - if (nc != NULL) { - cf = nc++; - *cf = 0x04; /* PARENT */ - *nc++ = 0; - } - sllen += 2; - if (sl[0] == '/') - sl += 3;/* skip "/.." */ - else - sl += 2;/* skip ".." */ - sl_last = '.'; - cl = NULL; - continue; - } - if (((sl_last == '\0' || sl_last == '/') && - sl[0] == '.' && - (sl[1] == '/' || sl[1] == '\0')) || - (sl[0] == '/' && sl[1] == '.' && - (sl[2] == '/' || sl[2] == '\0'))) { - /* - * flg len - * +----+----+ - * | 02 | 00 | CURRENT component. - * +----+----+ (".") - */ - if (nc != NULL) { - cf = nc++; - *cf = 0x02; /* CURRENT */ - *nc++ = 0; - } - sllen += 2; - if (sl[0] == '/') - sl += 2;/* skip "/." */ - else - sl ++; /* skip "." */ - sl_last = '.'; - cl = NULL; - continue; - } - if (sl[0] == '/' || cl == NULL) { - if (nc != NULL) { - cf = nc++; - *cf = 0; - cl = nc++; - *cl = 0; - } else - cl = &cldmy; - sllen += 2; - if (sl[0] == '/') { - sl_last = *sl++; - continue; - } - } - sl_last = *sl++; - if (nc != NULL) { - *nc++ = sl_last; - (*cl) ++; - } - sllen++; - } - if (*sl) { - length = 5 + sllen; - if (bp != NULL) { - /* - * Mark flg as CONTINUE component. - */ - *cf |= 0x01; - /* - * len ver flg - * +----+----+----+----+----+- - * | 'S'| 'L'| XX | 01 | 01 | - * +----+----+----+----+----+- - * ^ - * continues in next "SL" - */ - bp[3] = length; - bp[5] = 0x01;/* This Symbolic Link - * continues in next - * "SL" field */ - bp += length; - } - extra_tell_used_size(&ctl, length); - if (extra_space(&ctl) < 11) - bp = extra_next_record(&ctl, 11); - if (bp != NULL) { - /* Next 'SL' */ - bp[1] = 'S'; - bp[2] = 'L'; - bp[4] = 1; /* version */ - } - } else { - length = 5 + sllen; - if (bp != NULL) { - bp[3] = length; - bp[5] = 0; - bp += length; - } - extra_tell_used_size(&ctl, length); - break; - } - } - } - - /* Write "TF" System Use Entry. */ - if (rr_flag & RR_USE_TF) { - /* - * "TF" Format: - * len ver - * +----+----+----+----+-----+-------------+ - * | 'T'| 'F'| XX | 01 |FLAGS| TIME STAMPS | - * +----+----+----+----+-----+-------------+ - * 0 1 2 3 4 5 XX - * TIME STAMPS : ISO 9660 Standard 9.1.5. - * If TF_LONG_FORM FLAGS is set, - * use ISO9660 Standard 8.4.26.1. - */ -#define TF_CREATION 0x01 /* Creation time recorded */ -#define TF_MODIFY 0x02 /* Modification time recorded */ -#define TF_ACCESS 0x04 /* Last Access time recorded */ -#define TF_ATTRIBUTES 0x08 /* Last Attribute Change time recorded */ -#define TF_BACKUP 0x10 /* Last Backup time recorded */ -#define TF_EXPIRATION 0x20 /* Expiration time recorded */ -#define TF_EFFECTIVE 0x40 /* Effective time recorded */ -#define TF_LONG_FORM 0x80 /* ISO 9660 17-byte time format used */ - unsigned char tf_flags; - - length = 5; - tf_flags = 0; -#ifndef COMPAT_MKISOFS - if (archive_entry_birthtime_is_set(file->entry) && - archive_entry_birthtime(file->entry) <= - archive_entry_mtime(file->entry)) { - length += 7; - tf_flags |= TF_CREATION; - } -#endif - if (archive_entry_mtime_is_set(file->entry)) { - length += 7; - tf_flags |= TF_MODIFY; - } - if (archive_entry_atime_is_set(file->entry)) { - length += 7; - tf_flags |= TF_ACCESS; - } - if (archive_entry_ctime_is_set(file->entry)) { - length += 7; - tf_flags |= TF_ATTRIBUTES; - } - if (extra_space(&ctl) < length) - bp = extra_next_record(&ctl, length); - if (bp != NULL) { - bp[1] = 'T'; - bp[2] = 'F'; - bp[3] = length; - bp[4] = 1; /* version */ - bp[5] = tf_flags; - bp += 5; - /* Creation time */ - if (tf_flags & TF_CREATION) { - set_time_915(bp+1, - archive_entry_birthtime(file->entry)); - bp += 7; - } - /* Modification time */ - if (tf_flags & TF_MODIFY) { - set_time_915(bp+1, - archive_entry_mtime(file->entry)); - bp += 7; - } - /* Last Access time */ - if (tf_flags & TF_ACCESS) { - set_time_915(bp+1, - archive_entry_atime(file->entry)); - bp += 7; - } - /* Last Attribute Change time */ - if (tf_flags & TF_ATTRIBUTES) { - set_time_915(bp+1, - archive_entry_ctime(file->entry)); - bp += 7; - } - } - extra_tell_used_size(&ctl, length); - } - - /* Write "RE" System Use Entry. */ - if (rr_flag & RR_USE_RE) { - /* - * "RE" Format: - * len ver - * +----+----+----+----+ - * | 'R'| 'E'| 04 | 01 | - * +----+----+----+----+ - * 0 1 2 3 4 - */ - length = 4; - if (extra_space(&ctl) < length) - bp = extra_next_record(&ctl, length); - if (bp != NULL) { - bp[1] = 'R'; - bp[2] = 'E'; - bp[3] = length; - bp[4] = 1; /* version */ - bp += length; - } - extra_tell_used_size(&ctl, length); - } - - /* Write "PL" System Use Entry. */ - if (rr_flag & RR_USE_PL) { - /* - * "PL" Format: - * len ver - * +----+----+----+----+------------+ - * | 'P'| 'L'| 0C | 01 | *LOCATION | - * +----+----+----+----+------------+ - * 0 1 2 3 4 12 - * *LOCATION: location of parent directory - */ - length = 12; - if (extra_space(&ctl) < length) - bp = extra_next_record(&ctl, length); - if (bp != NULL) { - bp[1] = 'P'; - bp[2] = 'L'; - bp[3] = length; - bp[4] = 1; /* version */ - set_num_733(bp + 5, - rr_parent->dir_location); - bp += length; - } - extra_tell_used_size(&ctl, length); - } - - /* Write "CL" System Use Entry. */ - if (rr_flag & RR_USE_CL) { - /* - * "CL" Format: - * len ver - * +----+----+----+----+------------+ - * | 'C'| 'L'| 0C | 01 | *LOCATION | - * +----+----+----+----+------------+ - * 0 1 2 3 4 12 - * *LOCATION: location of child directory - */ - length = 12; - if (extra_space(&ctl) < length) - bp = extra_next_record(&ctl, length); - if (bp != NULL) { - bp[1] = 'C'; - bp[2] = 'L'; - bp[3] = length; - bp[4] = 1; /* version */ - set_num_733(bp + 5, - isoent->rr_child->dir_location); - bp += length; - } - extra_tell_used_size(&ctl, length); - } - - /* Write "PN" System Use Entry. */ - if (rr_flag & RR_USE_PN) { - /* - * "PN" Format: - * len ver - * +----+----+----+----+------------+------------+ - * | 'P'| 'N'| 14 | 01 | dev_t high | dev_t low | - * +----+----+----+----+------------+------------+ - * 0 1 2 3 4 12 20 - */ - length = 20; - if (extra_space(&ctl) < length) - bp = extra_next_record(&ctl, length); - if (bp != NULL) { - uint64_t dev; - - bp[1] = 'P'; - bp[2] = 'N'; - bp[3] = length; - bp[4] = 1; /* version */ - dev = (uint64_t)archive_entry_rdev(file->entry); - set_num_733(bp + 5, (uint32_t)(dev >> 32)); - set_num_733(bp + 13, (uint32_t)(dev & 0xFFFFFFFF)); - bp += length; - } - extra_tell_used_size(&ctl, length); - } - - /* Write "ZF" System Use Entry. */ - if (file->zisofs.header_size) { - /* - * "ZF" Format: - * len ver - * +----+----+----+----+----+----+-------------+ - * | 'Z'| 'F'| 10 | 01 | 'p'| 'z'| Header Size | - * +----+----+----+----+----+----+-------------+ - * 0 1 2 3 4 5 6 7 - * +--------------------+-------------------+ - * | Log2 of block Size | Uncompressed Size | - * +--------------------+-------------------+ - * 7 8 16 - */ - length = 16; - if (extra_space(&ctl) < length) - bp = extra_next_record(&ctl, length); - if (bp != NULL) { - bp[1] = 'Z'; - bp[2] = 'F'; - bp[3] = length; - bp[4] = 1; /* version */ - bp[5] = 'p'; - bp[6] = 'z'; - bp[7] = file->zisofs.header_size; - bp[8] = file->zisofs.log2_bs; - set_num_733(bp + 9, file->zisofs.uncompressed_size); - bp += length; - } - extra_tell_used_size(&ctl, length); - } - - /* Write "CE" System Use Entry. */ - if (t == DIR_REC_SELF && isoent == isoent->parent) { - length = RR_CE_SIZE; - if (bp != NULL) - set_SUSP_CE(bp+1, iso9660->location_rrip_er, - 0, RRIP_ER_SIZE); - extra_tell_used_size(&ctl, length); - } - - extra_close_record(&ctl, 0); - - return (ctl.dr_len); -} - -/* - * Write data of a Directory Record or calculate writing bytes itself. - * If parameter `p' is NULL, calculates the size of writing data, which - * a Directory Record needs to write, then it saved and return - * the calculated size. - * Parameter `n' is a remaining size of buffer. when parameter `p' is - * not NULL, check whether that `n' is not less than the saved size. - * if that `n' is small, return zero. - * - * This format of the Directory Record is according to - * ISO9660 Standard 9.1 - */ -static int -set_directory_record(unsigned char *p, size_t n, struct isoent *isoent, - struct iso9660 *iso9660, enum dir_rec_type t, - enum vdd_type vdd_type) -{ - unsigned char *bp; - size_t dr_len; - size_t fi_len; - - if (p != NULL) { - /* - * Check whether a write buffer size is less than the - * saved size which is needed to write this Directory - * Record. - */ - switch (t) { - case DIR_REC_VD: - dr_len = isoent->dr_len.vd; break; - case DIR_REC_SELF: - dr_len = isoent->dr_len.self; break; - case DIR_REC_PARENT: - dr_len = isoent->dr_len.parent; break; - case DIR_REC_NORMAL: - default: - dr_len = isoent->dr_len.normal; break; - } - if (dr_len > n) - return (0);/* Needs more buffer size. */ - } - - if (t == DIR_REC_NORMAL && isoent->identifier != NULL) - fi_len = isoent->id_len; - else - fi_len = 1; - - if (p != NULL) { - struct isoent *xisoent; - struct isofile *file; - unsigned char flag; - - if (t == DIR_REC_PARENT) - xisoent = isoent->parent; - else - xisoent = isoent; - file = isoent->file; - if (file->hardlink_target != NULL) - file = file->hardlink_target; - /* Make a file flag. */ - if (xisoent->dir) - flag = FILE_FLAG_DIRECTORY; - else { - if (file->cur_content->next != NULL) - flag = FILE_FLAG_MULTI_EXTENT; - else - flag = 0; - } - - bp = p -1; - /* Extended Attribute Record Length */ - set_num_711(bp+2, 0); - /* Location of Extent */ - if (xisoent->dir) - set_num_733(bp+3, xisoent->dir_location); - else - set_num_733(bp+3, file->cur_content->location); - /* Data Length */ - if (xisoent->dir) - set_num_733(bp+11, - xisoent->dir_block * LOGICAL_BLOCK_SIZE); - else - set_num_733(bp+11, (uint32_t)file->cur_content->size); - /* Recording Date and Time */ - /* NOTE: - * If a file type is symbolic link, you are seeing this - * field value is different from a value mkisofs makes. - * libarchive uses lstat to get this one, but it - * seems mkisofs uses stat to get. - */ - set_time_915(bp+19, - archive_entry_mtime(xisoent->file->entry)); - /* File Flags */ - bp[26] = flag; - /* File Unit Size */ - set_num_711(bp+27, 0); - /* Interleave Gap Size */ - set_num_711(bp+28, 0); - /* Volume Sequence Number */ - set_num_723(bp+29, iso9660->volume_sequence_number); - /* Length of File Identifier */ - set_num_711(bp+33, (unsigned char)fi_len); - /* File Identifier */ - switch (t) { - case DIR_REC_VD: - case DIR_REC_SELF: - set_num_711(bp+34, 0); - break; - case DIR_REC_PARENT: - set_num_711(bp+34, 1); - break; - case DIR_REC_NORMAL: - if (isoent->identifier != NULL) - memcpy(bp+34, isoent->identifier, fi_len); - else - set_num_711(bp+34, 0); - break; - } - } else - bp = NULL; - dr_len = 33 + fi_len; - /* Padding Field */ - if (dr_len & 0x01) { - dr_len ++; - if (p != NULL) - bp[dr_len] = 0; - } - - /* Volume Descriptor does not record extension. */ - if (t == DIR_REC_VD) { - if (p != NULL) - /* Length of Directory Record */ - set_num_711(p, (unsigned char)dr_len); - else - isoent->dr_len.vd = (int)dr_len; - return ((int)dr_len); - } - - /* Rockridge */ - if (iso9660->opt.rr && vdd_type != VDD_JOLIET) - dr_len = set_directory_record_rr(bp, (int)dr_len, - isoent, iso9660, t); - - if (p != NULL) - /* Length of Directory Record */ - set_num_711(p, (unsigned char)dr_len); - else { - /* - * Save the size which is needed to write this - * Directory Record. - */ - switch (t) { - case DIR_REC_VD: - /* This case does not come, but compiler - * complains that DIR_REC_VD not handled - * in switch .... */ - break; - case DIR_REC_SELF: - isoent->dr_len.self = (int)dr_len; break; - case DIR_REC_PARENT: - isoent->dr_len.parent = (int)dr_len; break; - case DIR_REC_NORMAL: - isoent->dr_len.normal = (int)dr_len; break; - } - } - - return ((int)dr_len); -} - -/* - * Calculate the size of a directory record. - */ -static inline int -get_dir_rec_size(struct iso9660 *iso9660, struct isoent *isoent, - enum dir_rec_type t, enum vdd_type vdd_type) -{ - - return (set_directory_record(NULL, SIZE_MAX, - isoent, iso9660, t, vdd_type)); -} - -/* - * Manage to write ISO-image data with wbuff to reduce calling - * __archive_write_output() for performance. - */ - - -static inline unsigned char * -wb_buffptr(struct archive_write *a) -{ - struct iso9660 *iso9660 = (struct iso9660 *)a->format_data; - - return (&(iso9660->wbuff[sizeof(iso9660->wbuff) - - iso9660->wbuff_remaining])); -} - -static int -wb_write_out(struct archive_write *a) -{ - struct iso9660 *iso9660 = (struct iso9660 *)a->format_data; - size_t wsize, nw; - int r; - - wsize = sizeof(iso9660->wbuff) - iso9660->wbuff_remaining; - nw = wsize % LOGICAL_BLOCK_SIZE; - if (iso9660->wbuff_type == WB_TO_STREAM) - r = __archive_write_output(a, iso9660->wbuff, wsize - nw); - else - r = write_to_temp(a, iso9660->wbuff, wsize - nw); - /* Increase the offset. */ - iso9660->wbuff_offset += wsize - nw; - if (iso9660->wbuff_offset > iso9660->wbuff_written) - iso9660->wbuff_written = iso9660->wbuff_offset; - iso9660->wbuff_remaining = sizeof(iso9660->wbuff); - if (nw) { - iso9660->wbuff_remaining -= nw; - memmove(iso9660->wbuff, iso9660->wbuff + wsize - nw, nw); - } - return (r); -} - -static int -wb_consume(struct archive_write *a, size_t size) -{ - struct iso9660 *iso9660 = (struct iso9660 *)a->format_data; - - if (size > iso9660->wbuff_remaining || - iso9660->wbuff_remaining == 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Internal Programming error: iso9660:wb_consume()" - " size=%jd, wbuff_remaining=%jd", - (intmax_t)size, (intmax_t)iso9660->wbuff_remaining); - return (ARCHIVE_FATAL); - } - iso9660->wbuff_remaining -= size; - if (iso9660->wbuff_remaining < LOGICAL_BLOCK_SIZE) - return (wb_write_out(a)); - return (ARCHIVE_OK); -} - -#ifdef HAVE_ZLIB_H - -static int -wb_set_offset(struct archive_write *a, int64_t off) -{ - struct iso9660 *iso9660 = (struct iso9660 *)a->format_data; - int64_t used, ext_bytes; - - if (iso9660->wbuff_type != WB_TO_TEMP) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Internal Programming error: iso9660:wb_set_offset()"); - return (ARCHIVE_FATAL); - } - - used = sizeof(iso9660->wbuff) - iso9660->wbuff_remaining; - if (iso9660->wbuff_offset + used > iso9660->wbuff_tail) - iso9660->wbuff_tail = iso9660->wbuff_offset + used; - if (iso9660->wbuff_offset < iso9660->wbuff_written) { - if (used > 0 && - write_to_temp(a, iso9660->wbuff, (size_t)used) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - iso9660->wbuff_offset = iso9660->wbuff_written; - lseek(iso9660->temp_fd, iso9660->wbuff_offset, SEEK_SET); - iso9660->wbuff_remaining = sizeof(iso9660->wbuff); - used = 0; - } - if (off < iso9660->wbuff_offset) { - /* - * Write out waiting data. - */ - if (used > 0) { - if (wb_write_out(a) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } - lseek(iso9660->temp_fd, off, SEEK_SET); - iso9660->wbuff_offset = off; - iso9660->wbuff_remaining = sizeof(iso9660->wbuff); - } else if (off <= iso9660->wbuff_tail) { - iso9660->wbuff_remaining = (size_t) - (sizeof(iso9660->wbuff) - (off - iso9660->wbuff_offset)); - } else { - ext_bytes = off - iso9660->wbuff_tail; - iso9660->wbuff_remaining = (size_t)(sizeof(iso9660->wbuff) - - (iso9660->wbuff_tail - iso9660->wbuff_offset)); - while (ext_bytes >= (int64_t)iso9660->wbuff_remaining) { - if (write_null(a, (size_t)iso9660->wbuff_remaining) - != ARCHIVE_OK) - return (ARCHIVE_FATAL); - ext_bytes -= iso9660->wbuff_remaining; - } - if (ext_bytes > 0) { - if (write_null(a, (size_t)ext_bytes) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } - } - return (ARCHIVE_OK); -} - -#endif /* HAVE_ZLIB_H */ - -static int -write_null(struct archive_write *a, size_t size) -{ - size_t remaining; - unsigned char *p, *old; - int r; - - remaining = wb_remaining(a); - p = wb_buffptr(a); - if (size <= remaining) { - memset(p, 0, size); - return (wb_consume(a, size)); - } - memset(p, 0, remaining); - r = wb_consume(a, remaining); - if (r != ARCHIVE_OK) - return (r); - size -= remaining; - old = p; - p = wb_buffptr(a); - memset(p, 0, old - p); - remaining = wb_remaining(a); - while (size) { - size_t wsize = size; - - if (wsize > remaining) - wsize = remaining; - r = wb_consume(a, wsize); - if (r != ARCHIVE_OK) - return (r); - size -= wsize; - } - return (ARCHIVE_OK); -} - -/* - * Write Volume Descriptor Set Terminator - */ -static int -write_VD_terminator(struct archive_write *a) -{ - unsigned char *bp; - - bp = wb_buffptr(a) -1; - set_VD_bp(bp, VDT_TERMINATOR, 1); - set_unused_field_bp(bp, 8, LOGICAL_BLOCK_SIZE); - - return (wb_consume(a, LOGICAL_BLOCK_SIZE)); -} - -static int -set_file_identifier(unsigned char *bp, int from, int to, enum vdc vdc, - struct archive_write *a, struct vdd *vdd, struct archive_string *id, - const char *label, int leading_under, enum char_type char_type) -{ - char identifier[256]; - struct isoent *isoent; - const char *ids; - size_t len; - int r; - - if (id->length > 0 && leading_under && id->s[0] != '_') { - if (char_type == A_CHAR) - r = set_str_a_characters_bp(a, bp, from, to, id->s, vdc); - else - r = set_str_d_characters_bp(a, bp, from, to, id->s, vdc); - } else if (id->length > 0) { - ids = id->s; - if (leading_under) - ids++; - isoent = isoent_find_entry(vdd->rootent, ids); - if (isoent == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Not Found %s `%s'.", - label, ids); - return (ARCHIVE_FATAL); - } - len = isoent->ext_off + isoent->ext_len; - if (vdd->vdd_type == VDD_JOLIET) { - if (len > sizeof(identifier)-2) - len = sizeof(identifier)-2; - } else { - if (len > sizeof(identifier)-1) - len = sizeof(identifier)-1; - } - memcpy(identifier, isoent->identifier, len); - identifier[len] = '\0'; - if (vdd->vdd_type == VDD_JOLIET) { - identifier[len+1] = 0; - vdc = VDC_UCS2_DIRECT; - } - if (char_type == A_CHAR) - r = set_str_a_characters_bp(a, bp, from, to, - identifier, vdc); - else - r = set_str_d_characters_bp(a, bp, from, to, - identifier, vdc); - } else { - if (char_type == A_CHAR) - r = set_str_a_characters_bp(a, bp, from, to, NULL, vdc); - else - r = set_str_d_characters_bp(a, bp, from, to, NULL, vdc); - } - return (r); -} - -/* - * Write Primary/Supplementary Volume Descriptor - */ -static int -write_VD(struct archive_write *a, struct vdd *vdd) -{ - struct iso9660 *iso9660; - unsigned char *bp; - uint16_t volume_set_size = 1; - char identifier[256]; - enum VD_type vdt; - enum vdc vdc; - unsigned char vd_ver, fst_ver; - int r; - - iso9660 = a->format_data; - switch (vdd->vdd_type) { - case VDD_JOLIET: - vdt = VDT_SUPPLEMENTARY; - vd_ver = fst_ver = 1; - vdc = VDC_UCS2; - break; - case VDD_ENHANCED: - vdt = VDT_SUPPLEMENTARY; - vd_ver = fst_ver = 2; - vdc = VDC_LOWERCASE; - break; - case VDD_PRIMARY: - default: - vdt = VDT_PRIMARY; - vd_ver = fst_ver = 1; -#ifdef COMPAT_MKISOFS - vdc = VDC_LOWERCASE; -#else - vdc = VDC_STD; -#endif - break; - } - - bp = wb_buffptr(a) -1; - /* Volume Descriptor Type */ - set_VD_bp(bp, vdt, vd_ver); - /* Unused Field */ - set_unused_field_bp(bp, 8, 8); - /* System Identifier */ - get_system_identitier(identifier, sizeof(identifier)); - r = set_str_a_characters_bp(a, bp, 9, 40, identifier, vdc); - if (r != ARCHIVE_OK) - return (r); - /* Volume Identifier */ - r = set_str_d_characters_bp(a, bp, 41, 72, - iso9660->volume_identifier.s, vdc); - if (r != ARCHIVE_OK) - return (r); - /* Unused Field */ - set_unused_field_bp(bp, 73, 80); - /* Volume Space Size */ - set_num_733(bp+81, iso9660->volume_space_size); - if (vdd->vdd_type == VDD_JOLIET) { - /* Escape Sequences */ - bp[89] = 0x25;/* UCS-2 Level 3 */ - bp[90] = 0x2F; - bp[91] = 0x45; - memset(bp + 92, 0, 120 - 92 + 1); - } else { - /* Unused Field */ - set_unused_field_bp(bp, 89, 120); - } - /* Volume Set Size */ - set_num_723(bp+121, volume_set_size); - /* Volume Sequence Number */ - set_num_723(bp+125, iso9660->volume_sequence_number); - /* Logical Block Size */ - set_num_723(bp+129, LOGICAL_BLOCK_SIZE); - /* Path Table Size */ - set_num_733(bp+133, vdd->path_table_size); - /* Location of Occurrence of Type L Path Table */ - set_num_731(bp+141, vdd->location_type_L_path_table); - /* Location of Optional Occurrence of Type L Path Table */ - set_num_731(bp+145, 0); - /* Location of Occurrence of Type M Path Table */ - set_num_732(bp+149, vdd->location_type_M_path_table); - /* Location of Optional Occurrence of Type M Path Table */ - set_num_732(bp+153, 0); - /* Directory Record for Root Directory(BP 157 to 190) */ - set_directory_record(bp+157, 190-157+1, vdd->rootent, - iso9660, DIR_REC_VD, vdd->vdd_type); - /* Volume Set Identifier */ - r = set_str_d_characters_bp(a, bp, 191, 318, "", vdc); - if (r != ARCHIVE_OK) - return (r); - /* Publisher Identifier */ - r = set_file_identifier(bp, 319, 446, vdc, a, vdd, - &(iso9660->publisher_identifier), - "Publisher File", 1, A_CHAR); - if (r != ARCHIVE_OK) - return (r); - /* Data Preparer Identifier */ - r = set_file_identifier(bp, 447, 574, vdc, a, vdd, - &(iso9660->data_preparer_identifier), - "Data Preparer File", 1, A_CHAR); - if (r != ARCHIVE_OK) - return (r); - /* Application Identifier */ - r = set_file_identifier(bp, 575, 702, vdc, a, vdd, - &(iso9660->application_identifier), - "Application File", 1, A_CHAR); - if (r != ARCHIVE_OK) - return (r); - /* Copyright File Identifier */ - r = set_file_identifier(bp, 703, 739, vdc, a, vdd, - &(iso9660->copyright_file_identifier), - "Copyright File", 0, D_CHAR); - if (r != ARCHIVE_OK) - return (r); - /* Abstract File Identifier */ - r = set_file_identifier(bp, 740, 776, vdc, a, vdd, - &(iso9660->abstract_file_identifier), - "Abstract File", 0, D_CHAR); - if (r != ARCHIVE_OK) - return (r); - /* Bibliographic File Identifier */ - r = set_file_identifier(bp, 777, 813, vdc, a, vdd, - &(iso9660->bibliographic_file_identifier), - "Bibliongraphic File", 0, D_CHAR); - if (r != ARCHIVE_OK) - return (r); - /* Volume Creation Date and Time */ - set_date_time(bp+814, iso9660->birth_time); - /* Volume Modification Date and Time */ - set_date_time(bp+831, iso9660->birth_time); - /* Volume Expiration Date and Time(obsolete) */ - set_date_time_null(bp+848); - /* Volume Effective Date and Time */ - set_date_time(bp+865, iso9660->birth_time); - /* File Structure Version */ - bp[882] = fst_ver; - /* Reserved */ - bp[883] = 0; - /* Application Use */ - memset(bp + 884, 0x20, 1395 - 884 + 1); - /* Reserved */ - set_unused_field_bp(bp, 1396, LOGICAL_BLOCK_SIZE); - - return (wb_consume(a, LOGICAL_BLOCK_SIZE)); -} - -/* - * Write Boot Record Volume Descriptor - */ -static int -write_VD_boot_record(struct archive_write *a) -{ - struct iso9660 *iso9660; - unsigned char *bp; - - iso9660 = a->format_data; - bp = wb_buffptr(a) -1; - /* Volume Descriptor Type */ - set_VD_bp(bp, VDT_BOOT_RECORD, 1); - /* Boot System Identifier */ - memcpy(bp+8, "EL TORITO SPECIFICATION", 23); - set_unused_field_bp(bp, 8+23, 39); - /* Unused */ - set_unused_field_bp(bp, 40, 71); - /* Absolute pointer to first sector of Boot Catalog */ - set_num_731(bp+72, - iso9660->el_torito.catalog->file->content.location); - /* Unused */ - set_unused_field_bp(bp, 76, LOGICAL_BLOCK_SIZE); - - return (wb_consume(a, LOGICAL_BLOCK_SIZE)); -} - -enum keytype { - KEY_FLG, - KEY_STR, - KEY_INT, - KEY_HEX -}; -static void -set_option_info(struct archive_string *info, int *opt, const char *key, - enum keytype type, ...) -{ - va_list ap; - char prefix; - const char *s; - int d; - - prefix = (*opt==0)? ' ':','; - va_start(ap, type); - switch (type) { - case KEY_FLG: - d = va_arg(ap, int); - archive_string_sprintf(info, "%c%s%s", - prefix, (d == 0)?"!":"", key); - break; - case KEY_STR: - s = va_arg(ap, const char *); - archive_string_sprintf(info, "%c%s=%s", - prefix, key, s); - break; - case KEY_INT: - d = va_arg(ap, int); - archive_string_sprintf(info, "%c%s=%d", - prefix, key, d); - break; - case KEY_HEX: - d = va_arg(ap, int); - archive_string_sprintf(info, "%c%s=%x", - prefix, key, d); - break; - } - va_end(ap); - - *opt = 1; -} - -/* - * Make Non-ISO File System Information - */ -static int -write_information_block(struct archive_write *a) -{ - struct iso9660 *iso9660; - char buf[128]; - const char *v; - int opt, r; - struct archive_string info; - size_t info_size = LOGICAL_BLOCK_SIZE * - NON_ISO_FILE_SYSTEM_INFORMATION_BLOCK; - - iso9660 = (struct iso9660 *)a->format_data; - if (info_size > wb_remaining(a)) { - r = wb_write_out(a); - if (r != ARCHIVE_OK) - return (r); - } - archive_string_init(&info); - if (archive_string_ensure(&info, info_size) == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - memset(info.s, 0, info_size); - opt = 0; -#if defined(HAVE_CTIME_S) - ctime_s(buf, sizeof(buf), &(iso9660->birth_time)); -#elif defined(HAVE_CTIME_R) - ctime_r(&(iso9660->birth_time), buf); -#else - strncpy(buf, ctime(&(iso9660->birth_time)), sizeof(buf)-1); - buf[sizeof(buf)-1] = '\0'; -#endif - archive_string_sprintf(&info, - "INFO %s%s", buf, archive_version_string()); - if (iso9660->opt.abstract_file != OPT_ABSTRACT_FILE_DEFAULT) - set_option_info(&info, &opt, "abstract-file", - KEY_STR, iso9660->abstract_file_identifier.s); - if (iso9660->opt.application_id != OPT_APPLICATION_ID_DEFAULT) - set_option_info(&info, &opt, "application-id", - KEY_STR, iso9660->application_identifier.s); - if (iso9660->opt.allow_vernum != OPT_ALLOW_VERNUM_DEFAULT) - set_option_info(&info, &opt, "allow-vernum", - KEY_FLG, iso9660->opt.allow_vernum); - if (iso9660->opt.biblio_file != OPT_BIBLIO_FILE_DEFAULT) - set_option_info(&info, &opt, "biblio-file", - KEY_STR, iso9660->bibliographic_file_identifier.s); - if (iso9660->opt.boot != OPT_BOOT_DEFAULT) - set_option_info(&info, &opt, "boot", - KEY_STR, iso9660->el_torito.boot_filename.s); - if (iso9660->opt.boot_catalog != OPT_BOOT_CATALOG_DEFAULT) - set_option_info(&info, &opt, "boot-catalog", - KEY_STR, iso9660->el_torito.catalog_filename.s); - if (iso9660->opt.boot_info_table != OPT_BOOT_INFO_TABLE_DEFAULT) - set_option_info(&info, &opt, "boot-info-table", - KEY_FLG, iso9660->opt.boot_info_table); - if (iso9660->opt.boot_load_seg != OPT_BOOT_LOAD_SEG_DEFAULT) - set_option_info(&info, &opt, "boot-load-seg", - KEY_HEX, iso9660->el_torito.boot_load_seg); - if (iso9660->opt.boot_load_size != OPT_BOOT_LOAD_SIZE_DEFAULT) - set_option_info(&info, &opt, "boot-load-size", - KEY_INT, iso9660->el_torito.boot_load_size); - if (iso9660->opt.boot_type != OPT_BOOT_TYPE_DEFAULT) { - v = "no-emulation"; - if (iso9660->opt.boot_type == OPT_BOOT_TYPE_FD) - v = "fd"; - if (iso9660->opt.boot_type == OPT_BOOT_TYPE_HARD_DISK) - v = "hard-disk"; - set_option_info(&info, &opt, "boot-type", - KEY_STR, v); - } -#ifdef HAVE_ZLIB_H - if (iso9660->opt.compression_level != OPT_COMPRESSION_LEVEL_DEFAULT) - set_option_info(&info, &opt, "compression-level", - KEY_INT, iso9660->zisofs.compression_level); -#endif - if (iso9660->opt.copyright_file != OPT_COPYRIGHT_FILE_DEFAULT) - set_option_info(&info, &opt, "copyright-file", - KEY_STR, iso9660->copyright_file_identifier.s); - if (iso9660->opt.iso_level != OPT_ISO_LEVEL_DEFAULT) - set_option_info(&info, &opt, "iso-level", - KEY_INT, iso9660->opt.iso_level); - if (iso9660->opt.joliet != OPT_JOLIET_DEFAULT) { - if (iso9660->opt.joliet == OPT_JOLIET_LONGNAME) - set_option_info(&info, &opt, "joliet", - KEY_STR, "long"); - else - set_option_info(&info, &opt, "joliet", - KEY_FLG, iso9660->opt.joliet); - } - if (iso9660->opt.limit_depth != OPT_LIMIT_DEPTH_DEFAULT) - set_option_info(&info, &opt, "limit-depth", - KEY_FLG, iso9660->opt.limit_depth); - if (iso9660->opt.limit_dirs != OPT_LIMIT_DIRS_DEFAULT) - set_option_info(&info, &opt, "limit-dirs", - KEY_FLG, iso9660->opt.limit_dirs); - if (iso9660->opt.pad != OPT_PAD_DEFAULT) - set_option_info(&info, &opt, "pad", - KEY_FLG, iso9660->opt.pad); - if (iso9660->opt.publisher != OPT_PUBLISHER_DEFAULT) - set_option_info(&info, &opt, "publisher", - KEY_STR, iso9660->publisher_identifier.s); - if (iso9660->opt.rr != OPT_RR_DEFAULT) { - if (iso9660->opt.rr == OPT_RR_DISABLED) - set_option_info(&info, &opt, "rockridge", - KEY_FLG, iso9660->opt.rr); - else if (iso9660->opt.rr == OPT_RR_STRICT) - set_option_info(&info, &opt, "rockridge", - KEY_STR, "strict"); - else if (iso9660->opt.rr == OPT_RR_USEFUL) - set_option_info(&info, &opt, "rockridge", - KEY_STR, "useful"); - } - if (iso9660->opt.volume_id != OPT_VOLUME_ID_DEFAULT) - set_option_info(&info, &opt, "volume-id", - KEY_STR, iso9660->volume_identifier.s); - if (iso9660->opt.zisofs != OPT_ZISOFS_DEFAULT) - set_option_info(&info, &opt, "zisofs", - KEY_FLG, iso9660->opt.zisofs); - - memcpy(wb_buffptr(a), info.s, info_size); - archive_string_free(&info); - return (wb_consume(a, info_size)); -} - -static int -write_rr_ER(struct archive_write *a) -{ - unsigned char *p; - - p = wb_buffptr(a); - - memset(p, 0, LOGICAL_BLOCK_SIZE); - p[0] = 'E'; - p[1] = 'R'; - p[3] = 0x01; - p[2] = RRIP_ER_SIZE; - p[4] = RRIP_ER_ID_SIZE; - p[5] = RRIP_ER_DSC_SIZE; - p[6] = RRIP_ER_SRC_SIZE; - p[7] = 0x01; - memcpy(&p[8], rrip_identifier, p[4]); - memcpy(&p[8+p[4]], rrip_descriptor, p[5]); - memcpy(&p[8+p[4]+p[5]], rrip_source, p[6]); - - return (wb_consume(a, LOGICAL_BLOCK_SIZE)); -} - -static void -calculate_path_table_size(struct vdd *vdd) -{ - int depth, size; - struct path_table *pt; - - pt = vdd->pathtbl; - size = 0; - for (depth = 0; depth < vdd->max_depth; depth++) { - struct isoent **ptbl; - int i, cnt; - - if ((cnt = pt[depth].cnt) == 0) - break; - - ptbl = pt[depth].sorted; - for (i = 0; i < cnt; i++) { - int len; - - if (ptbl[i]->identifier == NULL) - len = 1; /* root directory */ - else - len = ptbl[i]->id_len; - if (len & 0x01) - len++; /* Padding Field */ - size += 8 + len; - } - } - vdd->path_table_size = size; - vdd->path_table_block = - ((size + PATH_TABLE_BLOCK_SIZE -1) / - PATH_TABLE_BLOCK_SIZE) * - (PATH_TABLE_BLOCK_SIZE / LOGICAL_BLOCK_SIZE); -} - -static int -_write_path_table(struct archive_write *a, int type_m, int depth, - struct vdd *vdd) -{ - unsigned char *bp, *wb; - struct isoent **ptbl; - size_t wbremaining; - int i, r, wsize; - - if (vdd->pathtbl[depth].cnt == 0) - return (0); - - wsize = 0; - wb = wb_buffptr(a); - wbremaining = wb_remaining(a); - bp = wb - 1; - ptbl = vdd->pathtbl[depth].sorted; - for (i = 0; i < vdd->pathtbl[depth].cnt; i++) { - struct isoent *np; - size_t len; - - np = ptbl[i]; - if (np->identifier == NULL) - len = 1; /* root directory */ - else - len = np->id_len; - if (wbremaining - ((bp+1) - wb) < (len + 1 + 8)) { - r = wb_consume(a, (bp+1) - wb); - if (r < 0) - return (r); - wb = wb_buffptr(a); - wbremaining = wb_remaining(a); - bp = wb -1; - } - /* Length of Directory Identifier */ - set_num_711(bp+1, (unsigned char)len); - /* Extended Attribute Record Length */ - set_num_711(bp+2, 0); - /* Location of Extent */ - if (type_m) - set_num_732(bp+3, np->dir_location); - else - set_num_731(bp+3, np->dir_location); - /* Parent Directory Number */ - if (type_m) - set_num_722(bp+7, np->parent->dir_number); - else - set_num_721(bp+7, np->parent->dir_number); - /* Directory Identifier */ - if (np->identifier == NULL) - bp[9] = 0; - else - memcpy(&bp[9], np->identifier, len); - if (len & 0x01) { - /* Padding Field */ - bp[9+len] = 0; - len++; - } - wsize += 8 + (int)len; - bp += 8 + len; - } - if ((bp + 1) > wb) { - r = wb_consume(a, (bp+1)-wb); - if (r < 0) - return (r); - } - return (wsize); -} - -static int -write_path_table(struct archive_write *a, int type_m, struct vdd *vdd) -{ - int depth, r; - size_t path_table_size; - - r = ARCHIVE_OK; - path_table_size = 0; - for (depth = 0; depth < vdd->max_depth; depth++) { - r = _write_path_table(a, type_m, depth, vdd); - if (r < 0) - return (r); - path_table_size += r; - } - - /* Write padding data. */ - path_table_size = path_table_size % PATH_TABLE_BLOCK_SIZE; - if (path_table_size > 0) - r = write_null(a, PATH_TABLE_BLOCK_SIZE - path_table_size); - return (r); -} - -static int -calculate_directory_descriptors(struct iso9660 *iso9660, struct vdd *vdd, - struct isoent *isoent, int depth) -{ - struct isoent **enttbl; - int bs, block, i; - - block = 1; - bs = get_dir_rec_size(iso9660, isoent, DIR_REC_SELF, vdd->vdd_type); - bs += get_dir_rec_size(iso9660, isoent, DIR_REC_PARENT, vdd->vdd_type); - - if (isoent->children.cnt <= 0 || (vdd->vdd_type != VDD_JOLIET && - !iso9660->opt.rr && depth + 1 >= vdd->max_depth)) - return (block); - - enttbl = isoent->children_sorted; - for (i = 0; i < isoent->children.cnt; i++) { - struct isoent *np = enttbl[i]; - struct isofile *file; - - file = np->file; - if (file->hardlink_target != NULL) - file = file->hardlink_target; - file->cur_content = &(file->content); - do { - int dr_l; - - dr_l = get_dir_rec_size(iso9660, np, DIR_REC_NORMAL, - vdd->vdd_type); - if ((bs + dr_l) > LOGICAL_BLOCK_SIZE) { - block ++; - bs = dr_l; - } else - bs += dr_l; - file->cur_content = file->cur_content->next; - } while (file->cur_content != NULL); - } - return (block); -} - -static int -_write_directory_descriptors(struct archive_write *a, struct vdd *vdd, - struct isoent *isoent, int depth) -{ - struct iso9660 *iso9660 = a->format_data; - struct isoent **enttbl; - unsigned char *p, *wb; - int i, r; - int dr_l; - - p = wb = wb_buffptr(a); -#define WD_REMAINING (LOGICAL_BLOCK_SIZE - (p - wb)) - p += set_directory_record(p, WD_REMAINING, isoent, - iso9660, DIR_REC_SELF, vdd->vdd_type); - p += set_directory_record(p, WD_REMAINING, isoent, - iso9660, DIR_REC_PARENT, vdd->vdd_type); - - if (isoent->children.cnt <= 0 || (vdd->vdd_type != VDD_JOLIET && - !iso9660->opt.rr && depth + 1 >= vdd->max_depth)) { - memset(p, 0, WD_REMAINING); - return (wb_consume(a, LOGICAL_BLOCK_SIZE)); - } - - enttbl = isoent->children_sorted; - for (i = 0; i < isoent->children.cnt; i++) { - struct isoent *np = enttbl[i]; - struct isofile *file = np->file; - - if (file->hardlink_target != NULL) - file = file->hardlink_target; - file->cur_content = &(file->content); - do { - dr_l = set_directory_record(p, WD_REMAINING, - np, iso9660, DIR_REC_NORMAL, - vdd->vdd_type); - if (dr_l == 0) { - memset(p, 0, WD_REMAINING); - r = wb_consume(a, LOGICAL_BLOCK_SIZE); - if (r < 0) - return (r); - p = wb = wb_buffptr(a); - dr_l = set_directory_record(p, - WD_REMAINING, np, iso9660, - DIR_REC_NORMAL, vdd->vdd_type); - } - p += dr_l; - file->cur_content = file->cur_content->next; - } while (file->cur_content != NULL); - } - memset(p, 0, WD_REMAINING); - return (wb_consume(a, LOGICAL_BLOCK_SIZE)); -} - -static int -write_directory_descriptors(struct archive_write *a, struct vdd *vdd) -{ - struct isoent *np; - int depth, r; - - depth = 0; - np = vdd->rootent; - do { - struct extr_rec *extr; - - r = _write_directory_descriptors(a, vdd, np, depth); - if (r < 0) - return (r); - if (vdd->vdd_type != VDD_JOLIET) { - /* - * This extract record is used by SUSP,RRIP. - * Not for joliet. - */ - for (extr = np->extr_rec_list.first; - extr != NULL; - extr = extr->next) { - unsigned char *wb; - - wb = wb_buffptr(a); - memcpy(wb, extr->buf, extr->offset); - memset(wb + extr->offset, 0, - LOGICAL_BLOCK_SIZE - extr->offset); - r = wb_consume(a, LOGICAL_BLOCK_SIZE); - if (r < 0) - return (r); - } - } - - if (np->subdirs.first != NULL && depth + 1 < vdd->max_depth) { - /* Enter to sub directories. */ - np = np->subdirs.first; - depth++; - continue; - } - while (np != np->parent) { - if (np->drnext == NULL) { - /* Return to the parent directory. */ - np = np->parent; - depth--; - } else { - np = np->drnext; - break; - } - } - } while (np != np->parent); - - return (ARCHIVE_OK); -} - -/* - * Read file contents from the temporary file, and write it. - */ -static int -write_file_contents(struct archive_write *a, int64_t offset, int64_t size) -{ - struct iso9660 *iso9660 = a->format_data; - int r; - - lseek(iso9660->temp_fd, offset, SEEK_SET); - - while (size) { - size_t rsize; - ssize_t rs; - unsigned char *wb; - - wb = wb_buffptr(a); - rsize = wb_remaining(a); - if (rsize > (size_t)size) - rsize = (size_t)size; - rs = read(iso9660->temp_fd, wb, rsize); - if (rs <= 0) { - archive_set_error(&a->archive, errno, - "Can't read temporary file(%jd)", (intmax_t)rs); - return (ARCHIVE_FATAL); - } - size -= rs; - r = wb_consume(a, rs); - if (r < 0) - return (r); - } - return (ARCHIVE_OK); -} - -static int -write_file_descriptors(struct archive_write *a) -{ - struct iso9660 *iso9660 = a->format_data; - struct isofile *file; - int64_t blocks, offset; - int r; - - blocks = 0; - offset = 0; - - /* Make the boot catalog contents, and write it. */ - if (iso9660->el_torito.catalog != NULL) { - r = make_boot_catalog(a); - if (r < 0) - return (r); - } - - /* Write the boot file contents. */ - if (iso9660->el_torito.boot != NULL) { - file = iso9660->el_torito.boot->file; - blocks = file->content.blocks; - offset = file->content.offset_of_temp; - if (offset != 0) { - r = write_file_contents(a, offset, - blocks << LOGICAL_BLOCK_BITS); - if (r < 0) - return (r); - blocks = 0; - offset = 0; - } - } - - /* Write out all file contents. */ - for (file = iso9660->data_file_list.first; - file != NULL; file = file->datanext) { - - if (!file->write_content) - continue; - - if ((offset + (blocks << LOGICAL_BLOCK_BITS)) < - file->content.offset_of_temp) { - if (blocks > 0) { - r = write_file_contents(a, offset, - blocks << LOGICAL_BLOCK_BITS); - if (r < 0) - return (r); - } - blocks = 0; - offset = file->content.offset_of_temp; - } - - file->cur_content = &(file->content); - do { - blocks += file->cur_content->blocks; - /* Next fragment */ - file->cur_content = file->cur_content->next; - } while (file->cur_content != NULL); - } - - /* Flush out remaining blocks. */ - if (blocks > 0) { - r = write_file_contents(a, offset, - blocks << LOGICAL_BLOCK_BITS); - if (r < 0) - return (r); - } - - return (ARCHIVE_OK); -} - -static void -isofile_init_entry_list(struct iso9660 *iso9660) -{ - iso9660->all_file_list.first = NULL; - iso9660->all_file_list.last = &(iso9660->all_file_list.first); -} - -static void -isofile_add_entry(struct iso9660 *iso9660, struct isofile *file) -{ - file->allnext = NULL; - *iso9660->all_file_list.last = file; - iso9660->all_file_list.last = &(file->allnext); -} - -static void -isofile_free_all_entries(struct iso9660 *iso9660) -{ - struct isofile *file, *file_next; - - file = iso9660->all_file_list.first; - while (file != NULL) { - file_next = file->allnext; - isofile_free(file); - file = file_next; - } -} - -static void -isofile_init_entry_data_file_list(struct iso9660 *iso9660) -{ - iso9660->data_file_list.first = NULL; - iso9660->data_file_list.last = &(iso9660->data_file_list.first); -} - -static void -isofile_add_data_file(struct iso9660 *iso9660, struct isofile *file) -{ - file->datanext = NULL; - *iso9660->data_file_list.last = file; - iso9660->data_file_list.last = &(file->datanext); -} - - -static struct isofile * -isofile_new(struct archive_write *a, struct archive_entry *entry) -{ - struct isofile *file; - - file = calloc(1, sizeof(*file)); - if (file == NULL) - return (NULL); - - if (entry != NULL) - file->entry = archive_entry_clone(entry); - else - file->entry = archive_entry_new2(&a->archive); - if (file->entry == NULL) { - free(file); - return (NULL); - } - archive_string_init(&(file->parentdir)); - archive_string_init(&(file->basename)); - archive_string_init(&(file->basename_utf16)); - archive_string_init(&(file->symlink)); - file->cur_content = &(file->content); - - return (file); -} - -static void -isofile_free(struct isofile *file) -{ - struct content *con, *tmp; - - con = file->content.next; - while (con != NULL) { - tmp = con; - con = con->next; - free(tmp); - } - archive_entry_free(file->entry); - archive_string_free(&(file->parentdir)); - archive_string_free(&(file->basename)); - archive_string_free(&(file->basename_utf16)); - archive_string_free(&(file->symlink)); - free(file); -} - -#if defined(_WIN32) || defined(__CYGWIN__) -static int -cleanup_backslash_1(char *p) -{ - int mb, dos; - - mb = dos = 0; - while (*p) { - if (*(unsigned char *)p > 127) - mb = 1; - if (*p == '\\') { - /* If we have not met any multi-byte characters, - * we can replace '\' with '/'. */ - if (!mb) - *p = '/'; - dos = 1; - } - p++; - } - if (!mb || !dos) - return (0); - return (-1); -} - -static void -cleanup_backslash_2(wchar_t *p) -{ - - /* Convert a path-separator from '\' to '/' */ - while (*p != L'\0') { - if (*p == L'\\') - *p = L'/'; - p++; - } -} -#endif - -/* - * Generate a parent directory name and a base name from a pathname. - */ -static int -isofile_gen_utility_names(struct archive_write *a, struct isofile *file) -{ - struct iso9660 *iso9660; - const char *pathname; - char *p, *dirname, *slash; - size_t len; - int ret = ARCHIVE_OK; - - iso9660 = a->format_data; - - archive_string_empty(&(file->parentdir)); - archive_string_empty(&(file->basename)); - archive_string_empty(&(file->basename_utf16)); - archive_string_empty(&(file->symlink)); - - pathname = archive_entry_pathname(file->entry); - if (pathname == NULL || pathname[0] == '\0') {/* virtual root */ - file->dircnt = 0; - return (ret); - } - - /* - * Make a UTF-16BE basename if Joliet extension enabled. - */ - if (iso9660->opt.joliet) { - const char *u16, *ulast; - size_t u16len, ulen_last; - - if (iso9660->sconv_to_utf16be == NULL) { - iso9660->sconv_to_utf16be = - archive_string_conversion_to_charset( - &(a->archive), "UTF-16BE", 1); - if (iso9660->sconv_to_utf16be == NULL) - /* Couldn't allocate memory */ - return (ARCHIVE_FATAL); - iso9660->sconv_from_utf16be = - archive_string_conversion_from_charset( - &(a->archive), "UTF-16BE", 1); - if (iso9660->sconv_from_utf16be == NULL) - /* Couldn't allocate memory */ - return (ARCHIVE_FATAL); - } - - /* - * Convert a filename to UTF-16BE. - */ - if (0 > archive_entry_pathname_l(file->entry, &u16, &u16len, - iso9660->sconv_to_utf16be)) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for UTF-16BE"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "A filename cannot be converted to UTF-16BE;" - "You should disable making Joliet extension"); - ret = ARCHIVE_WARN; - } - - /* - * Make sure a path separator is not in the last; - * Remove trailing '/'. - */ - while (u16len >= 2) { -#if defined(_WIN32) || defined(__CYGWIN__) - if (u16[u16len-2] == 0 && - (u16[u16len-1] == '/' || u16[u16len-1] == '\\')) -#else - if (u16[u16len-2] == 0 && u16[u16len-1] == '/') -#endif - { - u16len -= 2; - } else - break; - } - - /* - * Find a basename in UTF-16BE. - */ - ulast = u16; - u16len >>= 1; - ulen_last = u16len; - while (u16len > 0) { -#if defined(_WIN32) || defined(__CYGWIN__) - if (u16[0] == 0 && (u16[1] == '/' || u16[1] == '\\')) -#else - if (u16[0] == 0 && u16[1] == '/') -#endif - { - ulast = u16 + 2; - ulen_last = u16len -1; - } - u16 += 2; - u16len --; - } - ulen_last <<= 1; - if (archive_string_ensure(&(file->basename_utf16), - ulen_last) == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for UTF-16BE"); - return (ARCHIVE_FATAL); - } - - /* - * Set UTF-16BE basename. - */ - memcpy(file->basename_utf16.s, ulast, ulen_last); - file->basename_utf16.length = ulen_last; - } - - archive_strcpy(&(file->parentdir), pathname); -#if defined(_WIN32) || defined(__CYGWIN__) - /* - * Convert a path-separator from '\' to '/' - */ - if (cleanup_backslash_1(file->parentdir.s) != 0) { - const wchar_t *wp = archive_entry_pathname_w(file->entry); - struct archive_wstring ws; - - if (wp != NULL) { - int r; - archive_string_init(&ws); - archive_wstrcpy(&ws, wp); - cleanup_backslash_2(ws.s); - archive_string_empty(&(file->parentdir)); - r = archive_string_append_from_wcs(&(file->parentdir), - ws.s, ws.length); - archive_wstring_free(&ws); - if (r < 0 && errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - } - } -#endif - - len = file->parentdir.length; - p = dirname = file->parentdir.s; - - /* - * Remove leading '/', '../' and './' elements - */ - while (*p) { - if (p[0] == '/') { - p++; - len--; - } else if (p[0] != '.') - break; - else if (p[1] == '.' && p[2] == '/') { - p += 3; - len -= 3; - } else if (p[1] == '/' || (p[1] == '.' && p[2] == '\0')) { - p += 2; - len -= 2; - } else if (p[1] == '\0') { - p++; - len--; - } else - break; - } - if (p != dirname) { - memmove(dirname, p, len+1); - p = dirname; - } - /* - * Remove "/","/." and "/.." elements from tail. - */ - while (len > 0) { - size_t ll = len; - - if (len > 0 && p[len-1] == '/') { - p[len-1] = '\0'; - len--; - } - if (len > 1 && p[len-2] == '/' && p[len-1] == '.') { - p[len-2] = '\0'; - len -= 2; - } - if (len > 2 && p[len-3] == '/' && p[len-2] == '.' && - p[len-1] == '.') { - p[len-3] = '\0'; - len -= 3; - } - if (ll == len) - break; - } - while (*p) { - if (p[0] == '/') { - if (p[1] == '/') - /* Convert '//' --> '/' */ - memmove(p, p+1, strlen(p+1) + 1); - else if (p[1] == '.' && p[2] == '/') - /* Convert '/./' --> '/' */ - memmove(p, p+2, strlen(p+2) + 1); - else if (p[1] == '.' && p[2] == '.' && p[3] == '/') { - /* Convert 'dir/dir1/../dir2/' - * --> 'dir/dir2/' - */ - char *rp = p -1; - while (rp >= dirname) { - if (*rp == '/') - break; - --rp; - } - if (rp > dirname) { - strcpy(rp, p+3); - p = rp; - } else { - strcpy(dirname, p+4); - p = dirname; - } - } else - p++; - } else - p++; - } - p = dirname; - len = strlen(p); - - if (archive_entry_filetype(file->entry) == AE_IFLNK) { - /* Convert symlink name too. */ - pathname = archive_entry_symlink(file->entry); - archive_strcpy(&(file->symlink), pathname); -#if defined(_WIN32) || defined(__CYGWIN__) - /* - * Convert a path-separator from '\' to '/' - */ - if (archive_strlen(&(file->symlink)) > 0 && - cleanup_backslash_1(file->symlink.s) != 0) { - const wchar_t *wp = - archive_entry_symlink_w(file->entry); - struct archive_wstring ws; - - if (wp != NULL) { - int r; - archive_string_init(&ws); - archive_wstrcpy(&ws, wp); - cleanup_backslash_2(ws.s); - archive_string_empty(&(file->symlink)); - r = archive_string_append_from_wcs( - &(file->symlink), - ws.s, ws.length); - archive_wstring_free(&ws); - if (r < 0 && errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - } - } -#endif - } - /* - * - Count up directory elements. - * - Find out the position which points the last position of - * path separator('/'). - */ - slash = NULL; - file->dircnt = 0; - for (; *p != '\0'; p++) - if (*p == '/') { - slash = p; - file->dircnt++; - } - if (slash == NULL) { - /* The pathname doesn't have a parent directory. */ - file->parentdir.length = len; - archive_string_copy(&(file->basename), &(file->parentdir)); - archive_string_empty(&(file->parentdir)); - *file->parentdir.s = '\0'; - return (ret); - } - - /* Make a basename from dirname and slash */ - *slash = '\0'; - file->parentdir.length = slash - dirname; - archive_strcpy(&(file->basename), slash + 1); - if (archive_entry_filetype(file->entry) == AE_IFDIR) - file->dircnt ++; - return (ret); -} - -/* - * Register a entry to get a hardlink target. - */ -static int -isofile_register_hardlink(struct archive_write *a, struct isofile *file) -{ - struct iso9660 *iso9660 = a->format_data; - struct hardlink *hl; - const char *pathname; - - archive_entry_set_nlink(file->entry, 1); - pathname = archive_entry_hardlink(file->entry); - if (pathname == NULL) { - /* This `file` is a hardlink target. */ - hl = malloc(sizeof(*hl)); - if (hl == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - hl->nlink = 1; - /* A hardlink target must be the first position. */ - file->hlnext = NULL; - hl->file_list.first = file; - hl->file_list.last = &(file->hlnext); - __archive_rb_tree_insert_node(&(iso9660->hardlink_rbtree), - (struct archive_rb_node *)hl); - } else { - hl = (struct hardlink *)__archive_rb_tree_find_node( - &(iso9660->hardlink_rbtree), pathname); - if (hl != NULL) { - /* Insert `file` entry into the tail. */ - file->hlnext = NULL; - *hl->file_list.last = file; - hl->file_list.last = &(file->hlnext); - hl->nlink++; - } - archive_entry_unset_size(file->entry); - } - - return (ARCHIVE_OK); -} - -/* - * Hardlinked files have to have the same location of extent. - * We have to find out hardlink target entries for the entries - * which have a hardlink target name. - */ -static void -isofile_connect_hardlink_files(struct iso9660 *iso9660) -{ - struct archive_rb_node *n; - struct hardlink *hl; - struct isofile *target, *nf; - - ARCHIVE_RB_TREE_FOREACH(n, &(iso9660->hardlink_rbtree)) { - hl = (struct hardlink *)n; - - /* The first entry must be a hardlink target. */ - target = hl->file_list.first; - archive_entry_set_nlink(target->entry, hl->nlink); - /* Set a hardlink target to reference entries. */ - for (nf = target->hlnext; - nf != NULL; nf = nf->hlnext) { - nf->hardlink_target = target; - archive_entry_set_nlink(nf->entry, hl->nlink); - } - } -} - -static int -isofile_hd_cmp_node(const struct archive_rb_node *n1, - const struct archive_rb_node *n2) -{ - const struct hardlink *h1 = (const struct hardlink *)n1; - const struct hardlink *h2 = (const struct hardlink *)n2; - - return (strcmp(archive_entry_pathname(h1->file_list.first->entry), - archive_entry_pathname(h2->file_list.first->entry))); -} - -static int -isofile_hd_cmp_key(const struct archive_rb_node *n, const void *key) -{ - const struct hardlink *h = (const struct hardlink *)n; - - return (strcmp(archive_entry_pathname(h->file_list.first->entry), - (const char *)key)); -} - -static void -isofile_init_hardlinks(struct iso9660 *iso9660) -{ - static const struct archive_rb_tree_ops rb_ops = { - isofile_hd_cmp_node, isofile_hd_cmp_key, - }; - - __archive_rb_tree_init(&(iso9660->hardlink_rbtree), &rb_ops); -} - -static void -isofile_free_hardlinks(struct iso9660 *iso9660) -{ - struct archive_rb_node *n, *tmp; - - ARCHIVE_RB_TREE_FOREACH_SAFE(n, &(iso9660->hardlink_rbtree), tmp) { - __archive_rb_tree_remove_node(&(iso9660->hardlink_rbtree), n); - free(n); - } -} - -static struct isoent * -isoent_new(struct isofile *file) -{ - struct isoent *isoent; - static const struct archive_rb_tree_ops rb_ops = { - isoent_cmp_node, isoent_cmp_key, - }; - - isoent = calloc(1, sizeof(*isoent)); - if (isoent == NULL) - return (NULL); - isoent->file = file; - isoent->children.first = NULL; - isoent->children.last = &(isoent->children.first); - __archive_rb_tree_init(&(isoent->rbtree), &rb_ops); - isoent->subdirs.first = NULL; - isoent->subdirs.last = &(isoent->subdirs.first); - isoent->extr_rec_list.first = NULL; - isoent->extr_rec_list.last = &(isoent->extr_rec_list.first); - isoent->extr_rec_list.current = NULL; - if (archive_entry_filetype(file->entry) == AE_IFDIR) - isoent->dir = 1; - - return (isoent); -} - -static inline struct isoent * -isoent_clone(struct isoent *src) -{ - return (isoent_new(src->file)); -} - -static void -_isoent_free(struct isoent *isoent) -{ - struct extr_rec *er, *er_next; - - free(isoent->children_sorted); - free(isoent->identifier); - er = isoent->extr_rec_list.first; - while (er != NULL) { - er_next = er->next; - free(er); - er = er_next; - } - free(isoent); -} - -static void -isoent_free_all(struct isoent *isoent) -{ - struct isoent *np, *np_temp; - - if (isoent == NULL) - return; - np = isoent; - for (;;) { - if (np->dir) { - if (np->children.first != NULL) { - /* Enter to sub directories. */ - np = np->children.first; - continue; - } - } - for (;;) { - np_temp = np; - if (np->chnext == NULL) { - /* Return to the parent directory. */ - np = np->parent; - _isoent_free(np_temp); - if (np == np_temp) - return; - } else { - np = np->chnext; - _isoent_free(np_temp); - break; - } - } - } -} - -static struct isoent * -isoent_create_virtual_dir(struct archive_write *a, struct iso9660 *iso9660, const char *pathname) -{ - struct isofile *file; - struct isoent *isoent; - - file = isofile_new(a, NULL); - if (file == NULL) - return (NULL); - archive_entry_set_pathname(file->entry, pathname); - archive_entry_unset_mtime(file->entry); - archive_entry_unset_atime(file->entry); - archive_entry_unset_ctime(file->entry); - archive_entry_set_uid(file->entry, getuid()); - archive_entry_set_gid(file->entry, getgid()); - archive_entry_set_mode(file->entry, 0555 | AE_IFDIR); - archive_entry_set_nlink(file->entry, 2); - if (isofile_gen_utility_names(a, file) < ARCHIVE_WARN) { - isofile_free(file); - return (NULL); - } - isofile_add_entry(iso9660, file); - - isoent = isoent_new(file); - if (isoent == NULL) - return (NULL); - isoent->dir = 1; - isoent->virtual = 1; - - return (isoent); -} - -static int -isoent_cmp_node(const struct archive_rb_node *n1, - const struct archive_rb_node *n2) -{ - const struct isoent *e1 = (const struct isoent *)n1; - const struct isoent *e2 = (const struct isoent *)n2; - - return (strcmp(e1->file->basename.s, e2->file->basename.s)); -} - -static int -isoent_cmp_key(const struct archive_rb_node *n, const void *key) -{ - const struct isoent *e = (const struct isoent *)n; - - return (strcmp(e->file->basename.s, (const char *)key)); -} - -static int -isoent_add_child_head(struct isoent *parent, struct isoent *child) -{ - - if (!__archive_rb_tree_insert_node( - &(parent->rbtree), (struct archive_rb_node *)child)) - return (0); - if ((child->chnext = parent->children.first) == NULL) - parent->children.last = &(child->chnext); - parent->children.first = child; - parent->children.cnt++; - child->parent = parent; - - /* Add a child to a sub-directory chain */ - if (child->dir) { - if ((child->drnext = parent->subdirs.first) == NULL) - parent->subdirs.last = &(child->drnext); - parent->subdirs.first = child; - parent->subdirs.cnt++; - child->parent = parent; - } else - child->drnext = NULL; - return (1); -} - -static int -isoent_add_child_tail(struct isoent *parent, struct isoent *child) -{ - - if (!__archive_rb_tree_insert_node( - &(parent->rbtree), (struct archive_rb_node *)child)) - return (0); - child->chnext = NULL; - *parent->children.last = child; - parent->children.last = &(child->chnext); - parent->children.cnt++; - child->parent = parent; - - /* Add a child to a sub-directory chain */ - child->drnext = NULL; - if (child->dir) { - *parent->subdirs.last = child; - parent->subdirs.last = &(child->drnext); - parent->subdirs.cnt++; - child->parent = parent; - } - return (1); -} - -static void -isoent_remove_child(struct isoent *parent, struct isoent *child) -{ - struct isoent *ent; - - /* Remove a child entry from children chain. */ - ent = parent->children.first; - while (ent->chnext != child) - ent = ent->chnext; - if ((ent->chnext = ent->chnext->chnext) == NULL) - parent->children.last = &(ent->chnext); - parent->children.cnt--; - - if (child->dir) { - /* Remove a child entry from sub-directory chain. */ - ent = parent->subdirs.first; - while (ent->drnext != child) - ent = ent->drnext; - if ((ent->drnext = ent->drnext->drnext) == NULL) - parent->subdirs.last = &(ent->drnext); - parent->subdirs.cnt--; - } - - __archive_rb_tree_remove_node(&(parent->rbtree), - (struct archive_rb_node *)child); -} - -static int -isoent_clone_tree(struct archive_write *a, struct isoent **nroot, - struct isoent *root) -{ - struct isoent *np, *xroot, *newent; - - np = root; - xroot = NULL; - do { - newent = isoent_clone(np); - if (newent == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - if (xroot == NULL) { - *nroot = xroot = newent; - newent->parent = xroot; - } else - isoent_add_child_tail(xroot, newent); - if (np->dir && np->children.first != NULL) { - /* Enter to sub directories. */ - np = np->children.first; - xroot = newent; - continue; - } - while (np != np->parent) { - if (np->chnext == NULL) { - /* Return to the parent directory. */ - np = np->parent; - xroot = xroot->parent; - } else { - np = np->chnext; - break; - } - } - } while (np != np->parent); - - return (ARCHIVE_OK); -} - -/* - * Setup directory locations. - */ -static void -isoent_setup_directory_location(struct iso9660 *iso9660, int location, - struct vdd *vdd) -{ - struct isoent *np; - int depth; - - vdd->total_dir_block = 0; - depth = 0; - np = vdd->rootent; - do { - int block; - - np->dir_block = calculate_directory_descriptors( - iso9660, vdd, np, depth); - vdd->total_dir_block += np->dir_block; - np->dir_location = location; - location += np->dir_block; - block = extra_setup_location(np, location); - vdd->total_dir_block += block; - location += block; - - if (np->subdirs.first != NULL && depth + 1 < vdd->max_depth) { - /* Enter to sub directories. */ - np = np->subdirs.first; - depth++; - continue; - } - while (np != np->parent) { - if (np->drnext == NULL) { - /* Return to the parent directory. */ - np = np->parent; - depth--; - } else { - np = np->drnext; - break; - } - } - } while (np != np->parent); -} - -static void -_isoent_file_location(struct iso9660 *iso9660, struct isoent *isoent, - int *symlocation) -{ - struct isoent **children; - int n; - - if (isoent->children.cnt == 0) - return; - - children = isoent->children_sorted; - for (n = 0; n < isoent->children.cnt; n++) { - struct isoent *np; - struct isofile *file; - - np = children[n]; - if (np->dir) - continue; - if (np == iso9660->el_torito.boot) - continue; - file = np->file; - if (file->boot || file->hardlink_target != NULL) - continue; - if (archive_entry_filetype(file->entry) == AE_IFLNK || - file->content.size == 0) { - /* - * Do not point a valid location. - * Make sure entry is not hardlink file. - */ - file->content.location = (*symlocation)--; - continue; - } - - file->write_content = 1; - } -} - -/* - * Setup file locations. - */ -static void -isoent_setup_file_location(struct iso9660 *iso9660, int location) -{ - struct isoent *isoent; - struct isoent *np; - struct isofile *file; - size_t size; - int block; - int depth; - int joliet; - int symlocation; - int total_block; - - iso9660->total_file_block = 0; - if ((isoent = iso9660->el_torito.catalog) != NULL) { - isoent->file->content.location = location; - block = (int)((archive_entry_size(isoent->file->entry) + - LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS); - location += block; - iso9660->total_file_block += block; - } - if ((isoent = iso9660->el_torito.boot) != NULL) { - isoent->file->content.location = location; - size = fd_boot_image_size(iso9660->el_torito.media_type); - if (size == 0) - size = (size_t)archive_entry_size(isoent->file->entry); - block = ((int)size + LOGICAL_BLOCK_SIZE -1) - >> LOGICAL_BLOCK_BITS; - location += block; - iso9660->total_file_block += block; - isoent->file->content.blocks = block; - } - - depth = 0; - symlocation = -16; - if (!iso9660->opt.rr && iso9660->opt.joliet) { - joliet = 1; - np = iso9660->joliet.rootent; - } else { - joliet = 0; - np = iso9660->primary.rootent; - } - do { - _isoent_file_location(iso9660, np, &symlocation); - - if (np->subdirs.first != NULL && - (joliet || - ((iso9660->opt.rr == OPT_RR_DISABLED && - depth + 2 < iso9660->primary.max_depth) || - (iso9660->opt.rr && - depth + 1 < iso9660->primary.max_depth)))) { - /* Enter to sub directories. */ - np = np->subdirs.first; - depth++; - continue; - } - while (np != np->parent) { - if (np->drnext == NULL) { - /* Return to the parent directory. */ - np = np->parent; - depth--; - } else { - np = np->drnext; - break; - } - } - } while (np != np->parent); - - total_block = 0; - for (file = iso9660->data_file_list.first; - file != NULL; file = file->datanext) { - - if (!file->write_content) - continue; - - file->cur_content = &(file->content); - do { - file->cur_content->location = location; - location += file->cur_content->blocks; - total_block += file->cur_content->blocks; - /* Next fragment */ - file->cur_content = file->cur_content->next; - } while (file->cur_content != NULL); - } - iso9660->total_file_block += total_block; -} - -static int -get_path_component(char *name, size_t n, const char *fn) -{ - char *p; - size_t l; - - p = strchr(fn, '/'); - if (p == NULL) { - if ((l = strlen(fn)) == 0) - return (0); - } else - l = p - fn; - if (l > n -1) - return (-1); - memcpy(name, fn, l); - name[l] = '\0'; - - return ((int)l); -} - -/* - * Add a new entry into the tree. - */ -static int -isoent_tree(struct archive_write *a, struct isoent **isoentpp) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - char name[_MAX_FNAME];/* Included null terminator size. */ -#elif defined(NAME_MAX) && NAME_MAX >= 255 - char name[NAME_MAX+1]; -#else - char name[256]; -#endif - struct iso9660 *iso9660 = a->format_data; - struct isoent *dent, *isoent, *np; - struct isofile *f1, *f2; - const char *fn, *p; - int l; - - isoent = *isoentpp; - dent = iso9660->primary.rootent; - if (isoent->file->parentdir.length > 0) - fn = p = isoent->file->parentdir.s; - else - fn = p = ""; - - /* - * If the path of the parent directory of `isoent' entry is - * the same as the path of `cur_dirent', add isoent to - * `cur_dirent'. - */ - if (archive_strlen(&(iso9660->cur_dirstr)) - == archive_strlen(&(isoent->file->parentdir)) && - strcmp(iso9660->cur_dirstr.s, fn) == 0) { - if (!isoent_add_child_tail(iso9660->cur_dirent, isoent)) { - np = (struct isoent *)__archive_rb_tree_find_node( - &(iso9660->cur_dirent->rbtree), - isoent->file->basename.s); - goto same_entry; - } - return (ARCHIVE_OK); - } - - for (;;) { - l = get_path_component(name, sizeof(name), fn); - if (l == 0) { - np = NULL; - break; - } - if (l < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "A name buffer is too small"); - _isoent_free(isoent); - return (ARCHIVE_FATAL); - } - - np = isoent_find_child(dent, name); - if (np == NULL || fn[0] == '\0') - break; - - /* Find next subdirectory. */ - if (!np->dir) { - /* NOT Directory! */ - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "`%s' is not directory, we cannot insert `%s' ", - archive_entry_pathname(np->file->entry), - archive_entry_pathname(isoent->file->entry)); - _isoent_free(isoent); - *isoentpp = NULL; - return (ARCHIVE_FAILED); - } - fn += l; - if (fn[0] == '/') - fn++; - dent = np; - } - if (np == NULL) { - /* - * Create virtual parent directories. - */ - while (fn[0] != '\0') { - struct isoent *vp; - struct archive_string as; - - archive_string_init(&as); - archive_strncat(&as, p, fn - p + l); - if (as.s[as.length-1] == '/') { - as.s[as.length-1] = '\0'; - as.length--; - } - vp = isoent_create_virtual_dir(a, iso9660, as.s); - if (vp == NULL) { - archive_string_free(&as); - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - _isoent_free(isoent); - *isoentpp = NULL; - return (ARCHIVE_FATAL); - } - archive_string_free(&as); - - if (vp->file->dircnt > iso9660->dircnt_max) - iso9660->dircnt_max = vp->file->dircnt; - isoent_add_child_tail(dent, vp); - np = vp; - - fn += l; - if (fn[0] == '/') - fn++; - l = get_path_component(name, sizeof(name), fn); - if (l < 0) { - archive_string_free(&as); - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "A name buffer is too small"); - _isoent_free(isoent); - *isoentpp = NULL; - return (ARCHIVE_FATAL); - } - dent = np; - } - - /* Found out the parent directory where isoent can be - * inserted. */ - iso9660->cur_dirent = dent; - archive_string_empty(&(iso9660->cur_dirstr)); - archive_string_ensure(&(iso9660->cur_dirstr), - archive_strlen(&(dent->file->parentdir)) + - archive_strlen(&(dent->file->basename)) + 2); - if (archive_strlen(&(dent->file->parentdir)) + - archive_strlen(&(dent->file->basename)) == 0) - iso9660->cur_dirstr.s[0] = 0; - else { - if (archive_strlen(&(dent->file->parentdir)) > 0) { - archive_string_copy(&(iso9660->cur_dirstr), - &(dent->file->parentdir)); - archive_strappend_char(&(iso9660->cur_dirstr), '/'); - } - archive_string_concat(&(iso9660->cur_dirstr), - &(dent->file->basename)); - } - - if (!isoent_add_child_tail(dent, isoent)) { - np = (struct isoent *)__archive_rb_tree_find_node( - &(dent->rbtree), isoent->file->basename.s); - goto same_entry; - } - return (ARCHIVE_OK); - } - -same_entry: - /* - * We have already has the entry the filename of which is - * the same. - */ - f1 = np->file; - f2 = isoent->file; - - /* If the file type of entries is different, - * we cannot handle it. */ - if (archive_entry_filetype(f1->entry) != - archive_entry_filetype(f2->entry)) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Found duplicate entries `%s' and its file type is " - "different", - archive_entry_pathname(f1->entry)); - _isoent_free(isoent); - *isoentpp = NULL; - return (ARCHIVE_FAILED); - } - - /* Swap file entries. */ - np->file = f2; - isoent->file = f1; - np->virtual = 0; - - _isoent_free(isoent); - *isoentpp = np; - return (ARCHIVE_OK); -} - -/* - * Find a entry from `isoent' - */ -static struct isoent * -isoent_find_child(struct isoent *isoent, const char *child_name) -{ - struct isoent *np; - - np = (struct isoent *)__archive_rb_tree_find_node( - &(isoent->rbtree), child_name); - return (np); -} - -/* - * Find a entry full-path of which is specified by `fn' parameter, - * in the tree. - */ -static struct isoent * -isoent_find_entry(struct isoent *rootent, const char *fn) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - char name[_MAX_FNAME];/* Included null terminator size. */ -#elif defined(NAME_MAX) && NAME_MAX >= 255 - char name[NAME_MAX+1]; -#else - char name[256]; -#endif - struct isoent *isoent, *np; - int l; - - isoent = rootent; - np = NULL; - for (;;) { - l = get_path_component(name, sizeof(name), fn); - if (l == 0) - break; - fn += l; - if (fn[0] == '/') - fn++; - - np = isoent_find_child(isoent, name); - if (np == NULL) - break; - if (fn[0] == '\0') - break;/* We found out the entry */ - - /* Try sub directory. */ - isoent = np; - np = NULL; - if (!isoent->dir) - break;/* Not directory */ - } - - return (np); -} - -/* - * Following idr_* functions are used for resolving duplicated filenames - * and unreceivable filenames to generate ISO9660/Joliet Identifiers. - */ - -static void -idr_relaxed_filenames(char *map) -{ - int i; - - for (i = 0x21; i <= 0x2F; i++) - map[i] = 1; - for (i = 0x3A; i <= 0x41; i++) - map[i] = 1; - for (i = 0x5B; i <= 0x5E; i++) - map[i] = 1; - map[0x60] = 1; - for (i = 0x7B; i <= 0x7E; i++) - map[i] = 1; -} - -static void -idr_init(struct iso9660 *iso9660, struct vdd *vdd, struct idr *idr) -{ - - idr->idrent_pool = NULL; - idr->pool_size = 0; - if (vdd->vdd_type != VDD_JOLIET) { - if (iso9660->opt.iso_level <= 3) { - memcpy(idr->char_map, d_characters_map, - sizeof(idr->char_map)); - } else { - memcpy(idr->char_map, d1_characters_map, - sizeof(idr->char_map)); - idr_relaxed_filenames(idr->char_map); - } - } -} - -static void -idr_cleanup(struct idr *idr) -{ - free(idr->idrent_pool); -} - -static int -idr_ensure_poolsize(struct archive_write *a, struct idr *idr, - int cnt) -{ - - if (idr->pool_size < cnt) { - void *p; - const int bk = (1 << 7) - 1; - int psize; - - psize = (cnt + bk) & ~bk; - p = realloc(idr->idrent_pool, sizeof(struct idrent) * psize); - if (p == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - idr->idrent_pool = (struct idrent *)p; - idr->pool_size = psize; - } - return (ARCHIVE_OK); -} - -static int -idr_start(struct archive_write *a, struct idr *idr, int cnt, int ffmax, - int num_size, int null_size, const struct archive_rb_tree_ops *rbt_ops) -{ - int r; - - (void)ffmax; /* UNUSED */ - - r = idr_ensure_poolsize(a, idr, cnt); - if (r != ARCHIVE_OK) - return (r); - __archive_rb_tree_init(&(idr->rbtree), rbt_ops); - idr->wait_list.first = NULL; - idr->wait_list.last = &(idr->wait_list.first); - idr->pool_idx = 0; - idr->num_size = num_size; - idr->null_size = null_size; - return (ARCHIVE_OK); -} - -static void -idr_register(struct idr *idr, struct isoent *isoent, int weight, int noff) -{ - struct idrent *idrent, *n; - - idrent = &(idr->idrent_pool[idr->pool_idx++]); - idrent->wnext = idrent->avail = NULL; - idrent->isoent = isoent; - idrent->weight = weight; - idrent->noff = noff; - idrent->rename_num = 0; - - if (!__archive_rb_tree_insert_node(&(idr->rbtree), &(idrent->rbnode))) { - n = (struct idrent *)__archive_rb_tree_find_node( - &(idr->rbtree), idrent->isoent); - if (n != NULL) { - /* this `idrent' needs to rename. */ - idrent->avail = n; - *idr->wait_list.last = idrent; - idr->wait_list.last = &(idrent->wnext); - } - } -} - -static void -idr_extend_identifier(struct idrent *wnp, int numsize, int nullsize) -{ - unsigned char *p; - int wnp_ext_off; - - wnp_ext_off = wnp->isoent->ext_off; - if (wnp->noff + numsize != wnp_ext_off) { - p = (unsigned char *)wnp->isoent->identifier; - /* Extend the filename; foo.c --> foo___.c */ - memmove(p + wnp->noff + numsize, p + wnp_ext_off, - wnp->isoent->ext_len + nullsize); - wnp->isoent->ext_off = wnp_ext_off = wnp->noff + numsize; - wnp->isoent->id_len = wnp_ext_off + wnp->isoent->ext_len; - } -} - -static void -idr_resolve(struct idr *idr, void (*fsetnum)(unsigned char *p, int num)) -{ - struct idrent *n; - unsigned char *p; - - for (n = idr->wait_list.first; n != NULL; n = n->wnext) { - idr_extend_identifier(n, idr->num_size, idr->null_size); - p = (unsigned char *)n->isoent->identifier + n->noff; - do { - fsetnum(p, n->avail->rename_num++); - } while (!__archive_rb_tree_insert_node( - &(idr->rbtree), &(n->rbnode))); - } -} - -static void -idr_set_num(unsigned char *p, int num) -{ - static const char xdig[] = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', - 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', - 'U', 'V', 'W', 'X', 'Y', 'Z' - }; - - num %= sizeof(xdig) * sizeof(xdig) * sizeof(xdig); - p[0] = xdig[(num / (sizeof(xdig) * sizeof(xdig)))]; - num %= sizeof(xdig) * sizeof(xdig); - p[1] = xdig[ (num / sizeof(xdig))]; - num %= sizeof(xdig); - p[2] = xdig[num]; -} - -static void -idr_set_num_beutf16(unsigned char *p, int num) -{ - static const uint16_t xdig[] = { - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, - 0x0036, 0x0037, 0x0038, 0x0039, - 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, - 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, - 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, - 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, - 0x0059, 0x005A - }; -#define XDIG_CNT (sizeof(xdig)/sizeof(xdig[0])) - - num %= XDIG_CNT * XDIG_CNT * XDIG_CNT; - archive_be16enc(p, xdig[(num / (XDIG_CNT * XDIG_CNT))]); - num %= XDIG_CNT * XDIG_CNT; - archive_be16enc(p+2, xdig[ (num / XDIG_CNT)]); - num %= XDIG_CNT; - archive_be16enc(p+4, xdig[num]); -} - -/* - * Generate ISO9660 Identifier. - */ -static int -isoent_gen_iso9660_identifier(struct archive_write *a, struct isoent *isoent, - struct idr *idr) -{ - struct iso9660 *iso9660; - struct isoent *np; - char *p; - int l, r; - const char *char_map; - char allow_ldots, allow_multidot, allow_period, allow_vernum; - int fnmax, ffmax, dnmax; - static const struct archive_rb_tree_ops rb_ops = { - isoent_cmp_node_iso9660, isoent_cmp_key_iso9660 - }; - - if (isoent->children.cnt == 0) - return (0); - - iso9660 = a->format_data; - char_map = idr->char_map; - if (iso9660->opt.iso_level <= 3) { - allow_ldots = 0; - allow_multidot = 0; - allow_period = 1; - allow_vernum = iso9660->opt.allow_vernum; - if (iso9660->opt.iso_level == 1) { - fnmax = 8; - ffmax = 12;/* fnmax + '.' + 3 */ - dnmax = 8; - } else { - fnmax = 30; - ffmax = 31; - dnmax = 31; - } - } else { - allow_ldots = allow_multidot = 1; - allow_period = allow_vernum = 0; - if (iso9660->opt.rr) - /* - * MDR : The maximum size of Directory Record(254). - * DRL : A Directory Record Length(33). - * CE : A size of SUSP CE System Use Entry(28). - * MDR - DRL - CE = 254 - 33 - 28 = 193. - */ - fnmax = ffmax = dnmax = 193; - else - /* - * XA : CD-ROM XA System Use Extension - * Information(14). - * MDR - DRL - XA = 254 - 33 -14 = 207. - */ - fnmax = ffmax = dnmax = 207; - } - - r = idr_start(a, idr, isoent->children.cnt, ffmax, 3, 1, &rb_ops); - if (r < 0) - return (r); - - for (np = isoent->children.first; np != NULL; np = np->chnext) { - char *dot, *xdot; - int ext_off, noff, weight; - - l = (int)np->file->basename.length; - p = malloc(l+31+2+1); - if (p == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - memcpy(p, np->file->basename.s, l); - p[l] = '\0'; - np->identifier = p; - - dot = xdot = NULL; - if (!allow_ldots) { - /* - * If there is a '.' character at the first byte, - * it has to be replaced by '_' character. - */ - if (*p == '.') - *p++ = '_'; - } - for (;*p; p++) { - if (*p & 0x80) { - *p = '_'; - continue; - } - if (char_map[(unsigned char)*p]) { - /* if iso-level is '4', a character '.' is - * allowed by char_map. */ - if (*p == '.') { - xdot = dot; - dot = p; - } - continue; - } - if (*p >= 'a' && *p <= 'z') { - *p -= 'a' - 'A'; - continue; - } - if (*p == '.') { - xdot = dot; - dot = p; - if (allow_multidot) - continue; - } - *p = '_'; - } - p = np->identifier; - weight = -1; - if (dot == NULL) { - int nammax; - - if (np->dir) - nammax = dnmax; - else - nammax = fnmax; - - if (l > nammax) { - p[nammax] = '\0'; - weight = nammax; - ext_off = nammax; - } else - ext_off = l; - } else { - *dot = '.'; - ext_off = (int)(dot - p); - - if (iso9660->opt.iso_level == 1) { - if (dot - p <= 8) { - if (strlen(dot) > 4) { - /* A length of a file extension - * must be less than 4 */ - dot[4] = '\0'; - weight = 0; - } - } else { - p[8] = dot[0]; - p[9] = dot[1]; - p[10] = dot[2]; - p[11] = dot[3]; - p[12] = '\0'; - weight = 8; - ext_off = 8; - } - } else if (np->dir) { - if (l > dnmax) { - p[dnmax] = '\0'; - weight = dnmax; - if (ext_off > dnmax) - ext_off = dnmax; - } - } else if (l > ffmax) { - int extlen = (int)strlen(dot); - int xdoff; - - if (xdot != NULL) - xdoff = (int)(xdot - p); - else - xdoff = 0; - - if (extlen > 1 && xdoff < fnmax-1) { - int off; - - if (extlen > ffmax) - extlen = ffmax; - off = ffmax - extlen; - if (off == 0) { - /* A dot('.') character - * doesn't place to the first - * byte of identifier. */ - off ++; - extlen --; - } - memmove(p+off, dot, extlen); - p[ffmax] = '\0'; - ext_off = off; - weight = off; -#ifdef COMPAT_MKISOFS - } else if (xdoff >= fnmax-1) { - /* Simulate a bug(?) of mkisofs. */ - p[fnmax-1] = '\0'; - ext_off = fnmax-1; - weight = fnmax-1; -#endif - } else { - p[fnmax] = '\0'; - ext_off = fnmax; - weight = fnmax; - } - } - } - /* Save an offset of a file name extension to sort files. */ - np->ext_off = ext_off; - np->ext_len = (int)strlen(&p[ext_off]); - np->id_len = l = ext_off + np->ext_len; - - /* Make an offset of the number which is used to be set - * hexadecimal number to avoid duplicate identifier. */ - if (iso9660->opt.iso_level == 1) { - if (ext_off >= 5) - noff = 5; - else - noff = ext_off; - } else { - if (l == ffmax) - noff = ext_off - 3; - else if (l == ffmax-1) - noff = ext_off - 2; - else if (l == ffmax-2) - noff = ext_off - 1; - else - noff = ext_off; - } - /* Register entry to the identifier resolver. */ - idr_register(idr, np, weight, noff); - } - - /* Resolve duplicate identifier. */ - idr_resolve(idr, idr_set_num); - - /* Add a period and a version number to identifiers. */ - for (np = isoent->children.first; np != NULL; np = np->chnext) { - if (!np->dir && np->rr_child == NULL) { - p = np->identifier + np->ext_off + np->ext_len; - if (np->ext_len == 0 && allow_period) { - *p++ = '.'; - np->ext_len = 1; - } - if (np->ext_len == 1 && !allow_period) { - *--p = '\0'; - np->ext_len = 0; - } - np->id_len = np->ext_off + np->ext_len; - if (allow_vernum) { - *p++ = ';'; - *p++ = '1'; - np->id_len += 2; - } - *p = '\0'; - } else - np->id_len = np->ext_off + np->ext_len; - np->mb_len = np->id_len; - } - return (ARCHIVE_OK); -} - -/* - * Generate Joliet Identifier. - */ -static int -isoent_gen_joliet_identifier(struct archive_write *a, struct isoent *isoent, - struct idr *idr) -{ - struct iso9660 *iso9660; - struct isoent *np; - unsigned char *p; - size_t l; - int r; - size_t ffmax, parent_len; - static const struct archive_rb_tree_ops rb_ops = { - isoent_cmp_node_joliet, isoent_cmp_key_joliet - }; - - if (isoent->children.cnt == 0) - return (0); - - iso9660 = a->format_data; - if (iso9660->opt.joliet == OPT_JOLIET_LONGNAME) - ffmax = 206; - else - ffmax = 128; - - r = idr_start(a, idr, isoent->children.cnt, (int)ffmax, 6, 2, &rb_ops); - if (r < 0) - return (r); - - parent_len = 1; - for (np = isoent; np->parent != np; np = np->parent) - parent_len += np->mb_len + 1; - - for (np = isoent->children.first; np != NULL; np = np->chnext) { - unsigned char *dot; - int ext_off, noff, weight; - size_t lt; - - if ((l = np->file->basename_utf16.length) > ffmax) - l = ffmax; - - p = malloc((l+1)*2); - if (p == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - memcpy(p, np->file->basename_utf16.s, l); - p[l] = 0; - p[l+1] = 0; - - np->identifier = (char *)p; - lt = l; - dot = p + l; - weight = 0; - while (lt > 0) { - if (!joliet_allowed_char(p[0], p[1])) - archive_be16enc(p, 0x005F); /* '_' */ - else if (p[0] == 0 && p[1] == 0x2E) /* '.' */ - dot = p; - p += 2; - lt -= 2; - } - ext_off = (int)(dot - (unsigned char *)np->identifier); - np->ext_off = ext_off; - np->ext_len = (int)l - ext_off; - np->id_len = (int)l; - - /* - * Get a length of MBS of a full-pathname. - */ - if (np->file->basename_utf16.length > ffmax) { - if (archive_strncpy_l(&iso9660->mbs, - (const char *)np->identifier, l, - iso9660->sconv_from_utf16be) != 0 && - errno == ENOMEM) { - archive_set_error(&a->archive, errno, - "No memory"); - return (ARCHIVE_FATAL); - } - np->mb_len = (int)iso9660->mbs.length; - if (np->mb_len != (int)np->file->basename.length) - weight = np->mb_len; - } else - np->mb_len = (int)np->file->basename.length; - - /* If a length of full-pathname is longer than 240 bytes, - * it violates Joliet extensions regulation. */ - if (parent_len > 240 - || np->mb_len > 240 - || parent_len + np->mb_len > 240) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "The regulation of Joliet extensions;" - " A length of a full-pathname of `%s' is " - "longer than 240 bytes, (p=%d, b=%d)", - archive_entry_pathname(np->file->entry), - (int)parent_len, (int)np->mb_len); - return (ARCHIVE_FATAL); - } - - /* Make an offset of the number which is used to be set - * hexadecimal number to avoid duplicate identifier. */ - if (l == ffmax) - noff = ext_off - 6; - else if (l == ffmax-2) - noff = ext_off - 4; - else if (l == ffmax-4) - noff = ext_off - 2; - else - noff = ext_off; - /* Register entry to the identifier resolver. */ - idr_register(idr, np, weight, noff); - } - - /* Resolve duplicate identifier with Joliet Volume. */ - idr_resolve(idr, idr_set_num_beutf16); - - return (ARCHIVE_OK); -} - -/* - * This comparing rule is according to ISO9660 Standard 9.3 - */ -static int -isoent_cmp_iso9660_identifier(const struct isoent *p1, const struct isoent *p2) -{ - const char *s1, *s2; - int cmp; - int l; - - s1 = p1->identifier; - s2 = p2->identifier; - - /* Compare File Name */ - l = p1->ext_off; - if (l > p2->ext_off) - l = p2->ext_off; - cmp = memcmp(s1, s2, l); - if (cmp != 0) - return (cmp); - if (p1->ext_off < p2->ext_off) { - s2 += l; - l = p2->ext_off - p1->ext_off; - while (l--) - if (0x20 != *s2++) - return (0x20 - - *(const unsigned char *)(s2 - 1)); - } else if (p1->ext_off > p2->ext_off) { - s1 += l; - l = p1->ext_off - p2->ext_off; - while (l--) - if (0x20 != *s1++) - return (*(const unsigned char *)(s1 - 1) - - 0x20); - } - /* Compare File Name Extension */ - if (p1->ext_len == 0 && p2->ext_len == 0) - return (0); - if (p1->ext_len == 1 && p2->ext_len == 1) - return (0); - if (p1->ext_len <= 1) - return (-1); - if (p2->ext_len <= 1) - return (1); - l = p1->ext_len; - if (l > p2->ext_len) - l = p2->ext_len; - s1 = p1->identifier + p1->ext_off; - s2 = p2->identifier + p2->ext_off; - if (l > 1) { - cmp = memcmp(s1, s2, l); - if (cmp != 0) - return (cmp); - } - if (p1->ext_len < p2->ext_len) { - s2 += l; - l = p2->ext_len - p1->ext_len; - while (l--) - if (0x20 != *s2++) - return (0x20 - - *(const unsigned char *)(s2 - 1)); - } else if (p1->ext_len > p2->ext_len) { - s1 += l; - l = p1->ext_len - p2->ext_len; - while (l--) - if (0x20 != *s1++) - return (*(const unsigned char *)(s1 - 1) - - 0x20); - } - /* Compare File Version Number */ - /* No operation. The File Version Number is always one. */ - - return (cmp); -} - -static int -isoent_cmp_node_iso9660(const struct archive_rb_node *n1, - const struct archive_rb_node *n2) -{ - const struct idrent *e1 = (const struct idrent *)n1; - const struct idrent *e2 = (const struct idrent *)n2; - - return (isoent_cmp_iso9660_identifier(e2->isoent, e1->isoent)); -} - -static int -isoent_cmp_key_iso9660(const struct archive_rb_node *node, const void *key) -{ - const struct isoent *isoent = (const struct isoent *)key; - const struct idrent *idrent = (const struct idrent *)node; - - return (isoent_cmp_iso9660_identifier(isoent, idrent->isoent)); -} - -static int -isoent_cmp_joliet_identifier(const struct isoent *p1, const struct isoent *p2) -{ - const unsigned char *s1, *s2; - int cmp; - int l; - - s1 = (const unsigned char *)p1->identifier; - s2 = (const unsigned char *)p2->identifier; - - /* Compare File Name */ - l = p1->ext_off; - if (l > p2->ext_off) - l = p2->ext_off; - cmp = memcmp(s1, s2, l); - if (cmp != 0) - return (cmp); - if (p1->ext_off < p2->ext_off) { - s2 += l; - l = p2->ext_off - p1->ext_off; - while (l--) - if (0 != *s2++) - return (- *(const unsigned char *)(s2 - 1)); - } else if (p1->ext_off > p2->ext_off) { - s1 += l; - l = p1->ext_off - p2->ext_off; - while (l--) - if (0 != *s1++) - return (*(const unsigned char *)(s1 - 1)); - } - /* Compare File Name Extension */ - if (p1->ext_len == 0 && p2->ext_len == 0) - return (0); - if (p1->ext_len == 2 && p2->ext_len == 2) - return (0); - if (p1->ext_len <= 2) - return (-1); - if (p2->ext_len <= 2) - return (1); - l = p1->ext_len; - if (l > p2->ext_len) - l = p2->ext_len; - s1 = (unsigned char *)(p1->identifier + p1->ext_off); - s2 = (unsigned char *)(p2->identifier + p2->ext_off); - if (l > 1) { - cmp = memcmp(s1, s2, l); - if (cmp != 0) - return (cmp); - } - if (p1->ext_len < p2->ext_len) { - s2 += l; - l = p2->ext_len - p1->ext_len; - while (l--) - if (0 != *s2++) - return (- *(const unsigned char *)(s2 - 1)); - } else if (p1->ext_len > p2->ext_len) { - s1 += l; - l = p1->ext_len - p2->ext_len; - while (l--) - if (0 != *s1++) - return (*(const unsigned char *)(s1 - 1)); - } - /* Compare File Version Number */ - /* No operation. The File Version Number is always one. */ - - return (cmp); -} - -static int -isoent_cmp_node_joliet(const struct archive_rb_node *n1, - const struct archive_rb_node *n2) -{ - const struct idrent *e1 = (const struct idrent *)n1; - const struct idrent *e2 = (const struct idrent *)n2; - - return (isoent_cmp_joliet_identifier(e2->isoent, e1->isoent)); -} - -static int -isoent_cmp_key_joliet(const struct archive_rb_node *node, const void *key) -{ - const struct isoent *isoent = (const struct isoent *)key; - const struct idrent *idrent = (const struct idrent *)node; - - return (isoent_cmp_joliet_identifier(isoent, idrent->isoent)); -} - -static int -isoent_make_sorted_files(struct archive_write *a, struct isoent *isoent, - struct idr *idr) -{ - struct archive_rb_node *rn; - struct isoent **children; - - children = malloc(isoent->children.cnt * sizeof(struct isoent *)); - if (children == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - isoent->children_sorted = children; - - ARCHIVE_RB_TREE_FOREACH(rn, &(idr->rbtree)) { - struct idrent *idrent = (struct idrent *)rn; - *children ++ = idrent->isoent; - } - return (ARCHIVE_OK); -} - -/* - * - Generate ISO9660 and Joliet identifiers from basenames. - * - Sort files by each directory. - */ -static int -isoent_traverse_tree(struct archive_write *a, struct vdd* vdd) -{ - struct iso9660 *iso9660 = a->format_data; - struct isoent *np; - struct idr idr; - int depth; - int r; - int (*genid)(struct archive_write *, struct isoent *, struct idr *); - - idr_init(iso9660, vdd, &idr); - np = vdd->rootent; - depth = 0; - if (vdd->vdd_type == VDD_JOLIET) - genid = isoent_gen_joliet_identifier; - else - genid = isoent_gen_iso9660_identifier; - do { - if (np->virtual && - !archive_entry_mtime_is_set(np->file->entry)) { - /* Set properly times to virtual directory */ - archive_entry_set_mtime(np->file->entry, - iso9660->birth_time, 0); - archive_entry_set_atime(np->file->entry, - iso9660->birth_time, 0); - archive_entry_set_ctime(np->file->entry, - iso9660->birth_time, 0); - } - if (np->children.first != NULL) { - if (vdd->vdd_type != VDD_JOLIET && - !iso9660->opt.rr && depth + 1 >= vdd->max_depth) { - if (np->children.cnt > 0) - iso9660->directories_too_deep = np; - } else { - /* Generate Identifier */ - r = genid(a, np, &idr); - if (r < 0) - goto exit_traverse_tree; - r = isoent_make_sorted_files(a, np, &idr); - if (r < 0) - goto exit_traverse_tree; - - if (np->subdirs.first != NULL && - depth + 1 < vdd->max_depth) { - /* Enter to sub directories. */ - np = np->subdirs.first; - depth++; - continue; - } - } - } - while (np != np->parent) { - if (np->drnext == NULL) { - /* Return to the parent directory. */ - np = np->parent; - depth--; - } else { - np = np->drnext; - break; - } - } - } while (np != np->parent); - - r = ARCHIVE_OK; -exit_traverse_tree: - idr_cleanup(&idr); - - return (r); -} - -/* - * Collect directory entries into path_table by a directory depth. - */ -static int -isoent_collect_dirs(struct vdd *vdd, struct isoent *rootent, int depth) -{ - struct isoent *np; - - if (rootent == NULL) - rootent = vdd->rootent; - np = rootent; - do { - /* Register current directory to pathtable. */ - path_table_add_entry(&(vdd->pathtbl[depth]), np); - - if (np->subdirs.first != NULL && depth + 1 < vdd->max_depth) { - /* Enter to sub directories. */ - np = np->subdirs.first; - depth++; - continue; - } - while (np != rootent) { - if (np->drnext == NULL) { - /* Return to the parent directory. */ - np = np->parent; - depth--; - } else { - np = np->drnext; - break; - } - } - } while (np != rootent); - - return (ARCHIVE_OK); -} - -/* - * The entry whose number of levels in a directory hierarchy is - * large than eight relocate to rr_move directory. - */ -static int -isoent_rr_move_dir(struct archive_write *a, struct isoent **rr_moved, - struct isoent *curent, struct isoent **newent) -{ - struct iso9660 *iso9660 = a->format_data; - struct isoent *rrmoved, *mvent, *np; - - if ((rrmoved = *rr_moved) == NULL) { - struct isoent *rootent = iso9660->primary.rootent; - /* There isn't rr_move entry. - * Create rr_move entry and insert it into the root entry. - */ - rrmoved = isoent_create_virtual_dir(a, iso9660, "rr_moved"); - if (rrmoved == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - /* Add "rr_moved" entry to the root entry. */ - isoent_add_child_head(rootent, rrmoved); - archive_entry_set_nlink(rootent->file->entry, - archive_entry_nlink(rootent->file->entry) + 1); - /* Register "rr_moved" entry to second level pathtable. */ - path_table_add_entry(&(iso9660->primary.pathtbl[1]), rrmoved); - /* Save rr_moved. */ - *rr_moved = rrmoved; - } - /* - * Make a clone of curent which is going to be relocated - * to rr_moved. - */ - mvent = isoent_clone(curent); - if (mvent == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - /* linking.. and use for creating "CL", "PL" and "RE" */ - mvent->rr_parent = curent->parent; - curent->rr_child = mvent; - /* - * Move subdirectories from the curent to mvent - */ - if (curent->children.first != NULL) { - *mvent->children.last = curent->children.first; - mvent->children.last = curent->children.last; - } - for (np = mvent->children.first; np != NULL; np = np->chnext) - np->parent = mvent; - mvent->children.cnt = curent->children.cnt; - curent->children.cnt = 0; - curent->children.first = NULL; - curent->children.last = &curent->children.first; - - if (curent->subdirs.first != NULL) { - *mvent->subdirs.last = curent->subdirs.first; - mvent->subdirs.last = curent->subdirs.last; - } - mvent->subdirs.cnt = curent->subdirs.cnt; - curent->subdirs.cnt = 0; - curent->subdirs.first = NULL; - curent->subdirs.last = &curent->subdirs.first; - - /* - * The mvent becomes a child of the rr_moved entry. - */ - isoent_add_child_tail(rrmoved, mvent); - archive_entry_set_nlink(rrmoved->file->entry, - archive_entry_nlink(rrmoved->file->entry) + 1); - /* - * This entry which relocated to the rr_moved directory - * has to set the flag as a file. - * See also RRIP 4.1.5.1 Description of the "CL" System Use Entry. - */ - curent->dir = 0; - - *newent = mvent; - - return (ARCHIVE_OK); -} - -static int -isoent_rr_move(struct archive_write *a) -{ - struct iso9660 *iso9660 = a->format_data; - struct path_table *pt; - struct isoent *rootent, *rr_moved; - struct isoent *np, *last; - int r; - - pt = &(iso9660->primary.pathtbl[MAX_DEPTH-1]); - /* There aren't level 8 directories reaching a deeper level. */ - if (pt->cnt == 0) - return (ARCHIVE_OK); - - rootent = iso9660->primary.rootent; - /* If "rr_moved" directory is already existing, - * we have to use it. */ - rr_moved = isoent_find_child(rootent, "rr_moved"); - if (rr_moved != NULL && - rr_moved != rootent->children.first) { - /* - * It's necessary that rr_move is the first entry - * of the root. - */ - /* Remove "rr_moved" entry from children chain. */ - isoent_remove_child(rootent, rr_moved); - - /* Add "rr_moved" entry into the head of children chain. */ - isoent_add_child_head(rootent, rr_moved); - } - - /* - * Check level 8 path_table. - * If find out sub directory entries, that entries move to rr_move. - */ - np = pt->first; - while (np != NULL) { - last = path_table_last_entry(pt); - for (; np != NULL; np = np->ptnext) { - struct isoent *mvent; - struct isoent *newent; - - if (!np->dir) - continue; - for (mvent = np->subdirs.first; - mvent != NULL; mvent = mvent->drnext) { - r = isoent_rr_move_dir(a, &rr_moved, - mvent, &newent); - if (r < 0) - return (r); - isoent_collect_dirs(&(iso9660->primary), - newent, 2); - } - } - /* If new entries are added to level 8 path_talbe, - * its sub directory entries move to rr_move too. - */ - np = last->ptnext; - } - - return (ARCHIVE_OK); -} - -/* - * This comparing rule is according to ISO9660 Standard 6.9.1 - */ -static int -__LA_LIBC_CC -_compare_path_table(const void *v1, const void *v2) -{ - const struct isoent *p1, *p2; - const char *s1, *s2; - int cmp, l; - - p1 = *((const struct isoent **)(uintptr_t)v1); - p2 = *((const struct isoent **)(uintptr_t)v2); - - /* Compare parent directory number */ - cmp = p1->parent->dir_number - p2->parent->dir_number; - if (cmp != 0) - return (cmp); - - /* Compare identifier */ - s1 = p1->identifier; - s2 = p2->identifier; - l = p1->ext_off; - if (l > p2->ext_off) - l = p2->ext_off; - cmp = strncmp(s1, s2, l); - if (cmp != 0) - return (cmp); - if (p1->ext_off < p2->ext_off) { - s2 += l; - l = p2->ext_off - p1->ext_off; - while (l--) - if (0x20 != *s2++) - return (0x20 - - *(const unsigned char *)(s2 - 1)); - } else if (p1->ext_off > p2->ext_off) { - s1 += l; - l = p1->ext_off - p2->ext_off; - while (l--) - if (0x20 != *s1++) - return (*(const unsigned char *)(s1 - 1) - - 0x20); - } - return (0); -} - -static int -__LA_LIBC_CC -_compare_path_table_joliet(const void *v1, const void *v2) -{ - const struct isoent *p1, *p2; - const unsigned char *s1, *s2; - int cmp, l; - - p1 = *((const struct isoent **)(uintptr_t)v1); - p2 = *((const struct isoent **)(uintptr_t)v2); - - /* Compare parent directory number */ - cmp = p1->parent->dir_number - p2->parent->dir_number; - if (cmp != 0) - return (cmp); - - /* Compare identifier */ - s1 = (const unsigned char *)p1->identifier; - s2 = (const unsigned char *)p2->identifier; - l = p1->ext_off; - if (l > p2->ext_off) - l = p2->ext_off; - cmp = memcmp(s1, s2, l); - if (cmp != 0) - return (cmp); - if (p1->ext_off < p2->ext_off) { - s2 += l; - l = p2->ext_off - p1->ext_off; - while (l--) - if (0 != *s2++) - return (- *(const unsigned char *)(s2 - 1)); - } else if (p1->ext_off > p2->ext_off) { - s1 += l; - l = p1->ext_off - p2->ext_off; - while (l--) - if (0 != *s1++) - return (*(const unsigned char *)(s1 - 1)); - } - return (0); -} - -static inline void -path_table_add_entry(struct path_table *pathtbl, struct isoent *ent) -{ - ent->ptnext = NULL; - *pathtbl->last = ent; - pathtbl->last = &(ent->ptnext); - pathtbl->cnt ++; -} - -static inline struct isoent * -path_table_last_entry(struct path_table *pathtbl) -{ - if (pathtbl->first == NULL) - return (NULL); - return (((struct isoent *)(void *) - ((char *)(pathtbl->last) - offsetof(struct isoent, ptnext)))); -} - -/* - * Sort directory entries in path_table - * and assign directory number to each entries. - */ -static int -isoent_make_path_table_2(struct archive_write *a, struct vdd *vdd, - int depth, int *dir_number) -{ - struct isoent *np; - struct isoent **enttbl; - struct path_table *pt; - int i; - - pt = &vdd->pathtbl[depth]; - if (pt->cnt == 0) { - pt->sorted = NULL; - return (ARCHIVE_OK); - } - enttbl = malloc(pt->cnt * sizeof(struct isoent *)); - if (enttbl == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - pt->sorted = enttbl; - for (np = pt->first; np != NULL; np = np->ptnext) - *enttbl ++ = np; - enttbl = pt->sorted; - - switch (vdd->vdd_type) { - case VDD_PRIMARY: - case VDD_ENHANCED: -#ifdef __COMPAR_FN_T - qsort(enttbl, pt->cnt, sizeof(struct isoent *), - (__compar_fn_t)_compare_path_table); -#else - qsort(enttbl, pt->cnt, sizeof(struct isoent *), - _compare_path_table); -#endif - break; - case VDD_JOLIET: -#ifdef __COMPAR_FN_T - qsort(enttbl, pt->cnt, sizeof(struct isoent *), - (__compar_fn_t)_compare_path_table_joliet); -#else - qsort(enttbl, pt->cnt, sizeof(struct isoent *), - _compare_path_table_joliet); -#endif - break; - } - for (i = 0; i < pt->cnt; i++) - enttbl[i]->dir_number = (*dir_number)++; - - return (ARCHIVE_OK); -} - -static int -isoent_alloc_path_table(struct archive_write *a, struct vdd *vdd, - int max_depth) -{ - int i; - - vdd->max_depth = max_depth; - vdd->pathtbl = malloc(sizeof(*vdd->pathtbl) * vdd->max_depth); - if (vdd->pathtbl == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - for (i = 0; i < vdd->max_depth; i++) { - vdd->pathtbl[i].first = NULL; - vdd->pathtbl[i].last = &(vdd->pathtbl[i].first); - vdd->pathtbl[i].sorted = NULL; - vdd->pathtbl[i].cnt = 0; - } - return (ARCHIVE_OK); -} - -/* - * Make Path Tables - */ -static int -isoent_make_path_table(struct archive_write *a) -{ - struct iso9660 *iso9660 = a->format_data; - int depth, r; - int dir_number; - - /* - * Init Path Table. - */ - if (iso9660->dircnt_max >= MAX_DEPTH && - (!iso9660->opt.limit_depth || iso9660->opt.iso_level == 4)) - r = isoent_alloc_path_table(a, &(iso9660->primary), - iso9660->dircnt_max + 1); - else - /* The number of levels in the hierarchy cannot exceed - * eight. */ - r = isoent_alloc_path_table(a, &(iso9660->primary), - MAX_DEPTH); - if (r < 0) - return (r); - if (iso9660->opt.joliet) { - r = isoent_alloc_path_table(a, &(iso9660->joliet), - iso9660->dircnt_max + 1); - if (r < 0) - return (r); - } - - /* Step 0. - * - Collect directories for primary and joliet. - */ - isoent_collect_dirs(&(iso9660->primary), NULL, 0); - if (iso9660->opt.joliet) - isoent_collect_dirs(&(iso9660->joliet), NULL, 0); - /* - * Rockridge; move deeper depth directories to rr_moved. - */ - if (iso9660->opt.rr) { - r = isoent_rr_move(a); - if (r < 0) - return (r); - } - - /* Update nlink. */ - isofile_connect_hardlink_files(iso9660); - - /* Step 1. - * - Renew a value of the depth of that directories. - * - Resolve hardlinks. - * - Convert pathnames to ISO9660 name or UCS2(joliet). - * - Sort files by each directory. - */ - r = isoent_traverse_tree(a, &(iso9660->primary)); - if (r < 0) - return (r); - if (iso9660->opt.joliet) { - r = isoent_traverse_tree(a, &(iso9660->joliet)); - if (r < 0) - return (r); - } - - /* Step 2. - * - Sort directories. - * - Assign all directory number. - */ - dir_number = 1; - for (depth = 0; depth < iso9660->primary.max_depth; depth++) { - r = isoent_make_path_table_2(a, &(iso9660->primary), - depth, &dir_number); - if (r < 0) - return (r); - } - if (iso9660->opt.joliet) { - dir_number = 1; - for (depth = 0; depth < iso9660->joliet.max_depth; depth++) { - r = isoent_make_path_table_2(a, &(iso9660->joliet), - depth, &dir_number); - if (r < 0) - return (r); - } - } - if (iso9660->opt.limit_dirs && dir_number > 0xffff) { - /* - * Maximum number of directories is 65535(0xffff) - * doe to size(16bit) of Parent Directory Number of - * the Path Table. - * See also ISO9660 Standard 9.4. - */ - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Too many directories(%d) over 65535.", dir_number); - return (ARCHIVE_FATAL); - } - - /* Get the size of the Path Table. */ - calculate_path_table_size(&(iso9660->primary)); - if (iso9660->opt.joliet) - calculate_path_table_size(&(iso9660->joliet)); - - return (ARCHIVE_OK); -} - -static int -isoent_find_out_boot_file(struct archive_write *a, struct isoent *rootent) -{ - struct iso9660 *iso9660 = a->format_data; - - /* Find a isoent of the boot file. */ - iso9660->el_torito.boot = isoent_find_entry(rootent, - iso9660->el_torito.boot_filename.s); - if (iso9660->el_torito.boot == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Can't find the boot image file ``%s''", - iso9660->el_torito.boot_filename.s); - return (ARCHIVE_FATAL); - } - iso9660->el_torito.boot->file->boot = BOOT_IMAGE; - return (ARCHIVE_OK); -} - -static int -isoent_create_boot_catalog(struct archive_write *a, struct isoent *rootent) -{ - struct iso9660 *iso9660 = a->format_data; - struct isofile *file; - struct isoent *isoent; - struct archive_entry *entry; - - (void)rootent; /* UNUSED */ - /* - * Create the entry which is the "boot.catalog" file. - */ - file = isofile_new(a, NULL); - if (file == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - archive_entry_set_pathname(file->entry, - iso9660->el_torito.catalog_filename.s); - archive_entry_set_size(file->entry, LOGICAL_BLOCK_SIZE); - archive_entry_set_mtime(file->entry, iso9660->birth_time, 0); - archive_entry_set_atime(file->entry, iso9660->birth_time, 0); - archive_entry_set_ctime(file->entry, iso9660->birth_time, 0); - archive_entry_set_uid(file->entry, getuid()); - archive_entry_set_gid(file->entry, getgid()); - archive_entry_set_mode(file->entry, AE_IFREG | 0444); - archive_entry_set_nlink(file->entry, 1); - - if (isofile_gen_utility_names(a, file) < ARCHIVE_WARN) { - isofile_free(file); - return (ARCHIVE_FATAL); - } - file->boot = BOOT_CATALOG; - file->content.size = LOGICAL_BLOCK_SIZE; - isofile_add_entry(iso9660, file); - - isoent = isoent_new(file); - if (isoent == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - isoent->virtual = 1; - - /* Add the "boot.catalog" entry into tree */ - if (isoent_tree(a, &isoent) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - iso9660->el_torito.catalog = isoent; - /* - * Get a boot media type. - */ - switch (iso9660->opt.boot_type) { - default: - case OPT_BOOT_TYPE_AUTO: - /* Try detecting a media type of the boot image. */ - entry = iso9660->el_torito.boot->file->entry; - if (archive_entry_size(entry) == FD_1_2M_SIZE) - iso9660->el_torito.media_type = - BOOT_MEDIA_1_2M_DISKETTE; - else if (archive_entry_size(entry) == FD_1_44M_SIZE) - iso9660->el_torito.media_type = - BOOT_MEDIA_1_44M_DISKETTE; - else if (archive_entry_size(entry) == FD_2_88M_SIZE) - iso9660->el_torito.media_type = - BOOT_MEDIA_2_88M_DISKETTE; - else - /* We cannot decide whether the boot image is - * hard-disk. */ - iso9660->el_torito.media_type = - BOOT_MEDIA_NO_EMULATION; - break; - case OPT_BOOT_TYPE_NO_EMU: - iso9660->el_torito.media_type = BOOT_MEDIA_NO_EMULATION; - break; - case OPT_BOOT_TYPE_HARD_DISK: - iso9660->el_torito.media_type = BOOT_MEDIA_HARD_DISK; - break; - case OPT_BOOT_TYPE_FD: - entry = iso9660->el_torito.boot->file->entry; - if (archive_entry_size(entry) <= FD_1_2M_SIZE) - iso9660->el_torito.media_type = - BOOT_MEDIA_1_2M_DISKETTE; - else if (archive_entry_size(entry) <= FD_1_44M_SIZE) - iso9660->el_torito.media_type = - BOOT_MEDIA_1_44M_DISKETTE; - else if (archive_entry_size(entry) <= FD_2_88M_SIZE) - iso9660->el_torito.media_type = - BOOT_MEDIA_2_88M_DISKETTE; - else { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Boot image file(``%s'') size is too big " - "for fd type.", - iso9660->el_torito.boot_filename.s); - return (ARCHIVE_FATAL); - } - break; - } - - /* - * Get a system type. - * TODO: `El Torito' specification says "A copy of byte 5 from the - * Partition Table found in the boot image". - */ - iso9660->el_torito.system_type = 0; - - /* - * Get an ID. - */ - if (iso9660->opt.publisher) - archive_string_copy(&(iso9660->el_torito.id), - &(iso9660->publisher_identifier)); - - - return (ARCHIVE_OK); -} - -/* - * If a media type is floppy, return its image size. - * otherwise return 0. - */ -static size_t -fd_boot_image_size(int media_type) -{ - switch (media_type) { - case BOOT_MEDIA_1_2M_DISKETTE: - return (FD_1_2M_SIZE); - case BOOT_MEDIA_1_44M_DISKETTE: - return (FD_1_44M_SIZE); - case BOOT_MEDIA_2_88M_DISKETTE: - return (FD_2_88M_SIZE); - default: - return (0); - } -} - -/* - * Make a boot catalog image data. - */ -static int -make_boot_catalog(struct archive_write *a) -{ - struct iso9660 *iso9660 = a->format_data; - unsigned char *block; - unsigned char *p; - uint16_t sum, *wp; - - block = wb_buffptr(a); - memset(block, 0, LOGICAL_BLOCK_SIZE); - p = block; - /* - * Validation Entry - */ - /* Header ID */ - p[0] = 1; - /* Platform ID */ - p[1] = iso9660->el_torito.platform_id; - /* Reserved */ - p[2] = p[3] = 0; - /* ID */ - if (archive_strlen(&(iso9660->el_torito.id)) > 0) - strncpy((char *)p+4, iso9660->el_torito.id.s, 23); - p[27] = 0; - /* Checksum */ - p[28] = p[29] = 0; - /* Key */ - p[30] = 0x55; - p[31] = 0xAA; - - sum = 0; - wp = (uint16_t *)block; - while (wp < (uint16_t *)&block[32]) - sum += archive_le16dec(wp++); - set_num_721(&block[28], (~sum) + 1); - - /* - * Initial/Default Entry - */ - p = &block[32]; - /* Boot Indicator */ - p[0] = 0x88; - /* Boot media type */ - p[1] = iso9660->el_torito.media_type; - /* Load Segment */ - if (iso9660->el_torito.media_type == BOOT_MEDIA_NO_EMULATION) - set_num_721(&p[2], iso9660->el_torito.boot_load_seg); - else - set_num_721(&p[2], 0); - /* System Type */ - p[4] = iso9660->el_torito.system_type; - /* Unused */ - p[5] = 0; - /* Sector Count */ - if (iso9660->el_torito.media_type == BOOT_MEDIA_NO_EMULATION) - set_num_721(&p[6], iso9660->el_torito.boot_load_size); - else - set_num_721(&p[6], 1); - /* Load RBA */ - set_num_731(&p[8], - iso9660->el_torito.boot->file->content.location); - /* Unused */ - memset(&p[12], 0, 20); - - return (wb_consume(a, LOGICAL_BLOCK_SIZE)); -} - -static int -setup_boot_information(struct archive_write *a) -{ - struct iso9660 *iso9660 = a->format_data; - struct isoent *np; - int64_t size; - uint32_t sum; - unsigned char buff[4096]; - - np = iso9660->el_torito.boot; - lseek(iso9660->temp_fd, - np->file->content.offset_of_temp + 64, SEEK_SET); - size = archive_entry_size(np->file->entry) - 64; - if (size <= 0) { - archive_set_error(&a->archive, errno, - "Boot file(%jd) is too small", (intmax_t)size + 64); - return (ARCHIVE_FATAL); - } - sum = 0; - while (size > 0) { - size_t rsize; - ssize_t i, rs; - - if (size > (int64_t)sizeof(buff)) - rsize = sizeof(buff); - else - rsize = (size_t)size; - - rs = read(iso9660->temp_fd, buff, rsize); - if (rs <= 0) { - archive_set_error(&a->archive, errno, - "Can't read temporary file(%jd)", - (intmax_t)rs); - return (ARCHIVE_FATAL); - } - for (i = 0; i < rs; i += 4) - sum += archive_le32dec(buff + i); - size -= rs; - } - /* Set the location of Primary Volume Descriptor. */ - set_num_731(buff, SYSTEM_AREA_BLOCK); - /* Set the location of the boot file. */ - set_num_731(buff+4, np->file->content.location); - /* Set the size of the boot file. */ - size = fd_boot_image_size(iso9660->el_torito.media_type); - if (size == 0) - size = archive_entry_size(np->file->entry); - set_num_731(buff+8, (uint32_t)size); - /* Set the sum of the boot file. */ - set_num_731(buff+12, sum); - /* Clear reserved bytes. */ - memset(buff+16, 0, 40); - - /* Overwrite the boot file. */ - lseek(iso9660->temp_fd, - np->file->content.offset_of_temp + 8, SEEK_SET); - return (write_to_temp(a, buff, 56)); -} - -#ifdef HAVE_ZLIB_H - -static int -zisofs_init_zstream(struct archive_write *a) -{ - struct iso9660 *iso9660 = a->format_data; - int r; - - iso9660->zisofs.stream.next_in = NULL; - iso9660->zisofs.stream.avail_in = 0; - iso9660->zisofs.stream.total_in = 0; - iso9660->zisofs.stream.total_out = 0; - if (iso9660->zisofs.stream_valid) - r = deflateReset(&(iso9660->zisofs.stream)); - else { - r = deflateInit(&(iso9660->zisofs.stream), - iso9660->zisofs.compression_level); - iso9660->zisofs.stream_valid = 1; - } - switch (r) { - case Z_OK: - break; - default: - case Z_STREAM_ERROR: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Internal error initializing " - "compression library: invalid setup parameter"); - return (ARCHIVE_FATAL); - case Z_MEM_ERROR: - archive_set_error(&a->archive, ENOMEM, - "Internal error initializing " - "compression library"); - return (ARCHIVE_FATAL); - case Z_VERSION_ERROR: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Internal error initializing " - "compression library: invalid library version"); - return (ARCHIVE_FATAL); - } - return (ARCHIVE_OK); -} - -#endif /* HAVE_ZLIB_H */ - -static int -zisofs_init(struct archive_write *a, struct isofile *file) -{ - struct iso9660 *iso9660 = a->format_data; -#ifdef HAVE_ZLIB_H - uint64_t tsize; - size_t _ceil, bpsize; - int r; -#endif - - iso9660->zisofs.detect_magic = 0; - iso9660->zisofs.making = 0; - - if (!iso9660->opt.rr || !iso9660->opt.zisofs) - return (ARCHIVE_OK); - - if (archive_entry_size(file->entry) >= 24 && - archive_entry_size(file->entry) < MULTI_EXTENT_SIZE) { - /* Acceptable file size for zisofs. */ - iso9660->zisofs.detect_magic = 1; - iso9660->zisofs.magic_cnt = 0; - } - if (!iso9660->zisofs.detect_magic) - return (ARCHIVE_OK); - -#ifdef HAVE_ZLIB_H - /* The number of Logical Blocks which uncompressed data - * will use in iso-image file is the same as the number of - * Logical Blocks which zisofs(compressed) data will use - * in ISO-image file. It won't reduce iso-image file size. */ - if (archive_entry_size(file->entry) <= LOGICAL_BLOCK_SIZE) - return (ARCHIVE_OK); - - /* Initialize compression library */ - r = zisofs_init_zstream(a); - if (r != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - /* Mark file->zisofs to create RRIP 'ZF' Use Entry. */ - file->zisofs.header_size = ZF_HEADER_SIZE >> 2; - file->zisofs.log2_bs = ZF_LOG2_BS; - file->zisofs.uncompressed_size = - (uint32_t)archive_entry_size(file->entry); - - /* Calculate a size of Block Pointers of zisofs. */ - _ceil = (file->zisofs.uncompressed_size + ZF_BLOCK_SIZE -1) - >> file->zisofs.log2_bs; - iso9660->zisofs.block_pointers_cnt = (int)_ceil + 1; - iso9660->zisofs.block_pointers_idx = 0; - - /* Ensure a buffer size used for Block Pointers */ - bpsize = iso9660->zisofs.block_pointers_cnt * - sizeof(iso9660->zisofs.block_pointers[0]); - if (iso9660->zisofs.block_pointers_allocated < bpsize) { - free(iso9660->zisofs.block_pointers); - iso9660->zisofs.block_pointers = malloc(bpsize); - if (iso9660->zisofs.block_pointers == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate data"); - return (ARCHIVE_FATAL); - } - iso9660->zisofs.block_pointers_allocated = bpsize; - } - - /* - * Skip zisofs header and Block Pointers, which we will write - * after all compressed data of a file written to the temporary - * file. - */ - tsize = ZF_HEADER_SIZE + bpsize; - if (write_null(a, (size_t)tsize) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - /* - * Initialize some variables to make zisofs. - */ - archive_le32enc(&(iso9660->zisofs.block_pointers[0]), - (uint32_t)tsize); - iso9660->zisofs.remaining = file->zisofs.uncompressed_size; - iso9660->zisofs.making = 1; - iso9660->zisofs.allzero = 1; - iso9660->zisofs.block_offset = tsize; - iso9660->zisofs.total_size = tsize; - iso9660->cur_file->cur_content->size = tsize; -#endif - - return (ARCHIVE_OK); -} - -static void -zisofs_detect_magic(struct archive_write *a, const void *buff, size_t s) -{ - struct iso9660 *iso9660 = a->format_data; - struct isofile *file = iso9660->cur_file; - const unsigned char *p, *endp; - const unsigned char *magic_buff; - uint32_t uncompressed_size; - unsigned char header_size; - unsigned char log2_bs; - size_t _ceil, doff; - uint32_t bst, bed; - int magic_max; - int64_t entry_size; - - entry_size = archive_entry_size(file->entry); - if ((int64_t)sizeof(iso9660->zisofs.magic_buffer) > entry_size) - magic_max = (int)entry_size; - else - magic_max = sizeof(iso9660->zisofs.magic_buffer); - - if (iso9660->zisofs.magic_cnt == 0 && s >= (size_t)magic_max) - /* It's unnecessary we copy buffer. */ - magic_buff = buff; - else { - if (iso9660->zisofs.magic_cnt < magic_max) { - size_t l; - - l = sizeof(iso9660->zisofs.magic_buffer) - - iso9660->zisofs.magic_cnt; - if (l > s) - l = s; - memcpy(iso9660->zisofs.magic_buffer - + iso9660->zisofs.magic_cnt, buff, l); - iso9660->zisofs.magic_cnt += (int)l; - if (iso9660->zisofs.magic_cnt < magic_max) - return; - } - magic_buff = iso9660->zisofs.magic_buffer; - } - iso9660->zisofs.detect_magic = 0; - p = magic_buff; - - /* Check the magic code of zisofs. */ - if (memcmp(p, zisofs_magic, sizeof(zisofs_magic)) != 0) - /* This is not zisofs file which made by mkzftree. */ - return; - p += sizeof(zisofs_magic); - - /* Read a zisofs header. */ - uncompressed_size = archive_le32dec(p); - header_size = p[4]; - log2_bs = p[5]; - if (uncompressed_size < 24 || header_size != 4 || - log2_bs > 30 || log2_bs < 7) - return;/* Invalid or not supported header. */ - - /* Calculate a size of Block Pointers of zisofs. */ - _ceil = (uncompressed_size + - (ARCHIVE_LITERAL_LL(1) << log2_bs) -1) >> log2_bs; - doff = (_ceil + 1) * 4 + 16; - if (entry_size < (int64_t)doff) - return;/* Invalid data. */ - - /* Check every Block Pointer has valid value. */ - p = magic_buff + 16; - endp = magic_buff + magic_max; - while (_ceil && p + 8 <= endp) { - bst = archive_le32dec(p); - if (bst != doff) - return;/* Invalid data. */ - p += 4; - bed = archive_le32dec(p); - if (bed < bst || bed > entry_size) - return;/* Invalid data. */ - doff += bed - bst; - _ceil--; - } - - file->zisofs.uncompressed_size = uncompressed_size; - file->zisofs.header_size = header_size; - file->zisofs.log2_bs = log2_bs; - - /* Disable making a zisofs image. */ - iso9660->zisofs.making = 0; -} - -#ifdef HAVE_ZLIB_H - -/* - * Compress data and write it to a temporary file. - */ -static int -zisofs_write_to_temp(struct archive_write *a, const void *buff, size_t s) -{ - struct iso9660 *iso9660 = a->format_data; - struct isofile *file = iso9660->cur_file; - const unsigned char *b; - z_stream *zstrm; - size_t avail, csize; - int flush, r; - - zstrm = &(iso9660->zisofs.stream); - zstrm->next_out = wb_buffptr(a); - zstrm->avail_out = (uInt)wb_remaining(a); - b = (const unsigned char *)buff; - do { - avail = ZF_BLOCK_SIZE - zstrm->total_in; - if (s < avail) { - avail = s; - flush = Z_NO_FLUSH; - } else - flush = Z_FINISH; - iso9660->zisofs.remaining -= avail; - if (iso9660->zisofs.remaining <= 0) - flush = Z_FINISH; - - zstrm->next_in = (Bytef *)(uintptr_t)(const void *)b; - zstrm->avail_in = (uInt)avail; - - /* - * Check if current data block are all zero. - */ - if (iso9660->zisofs.allzero) { - const unsigned char *nonzero = b; - const unsigned char *nonzeroend = b + avail; - - while (nonzero < nonzeroend) - if (*nonzero++) { - iso9660->zisofs.allzero = 0; - break; - } - } - b += avail; - s -= avail; - - /* - * If current data block are all zero, we do not use - * compressed data. - */ - if (flush == Z_FINISH && iso9660->zisofs.allzero && - avail + zstrm->total_in == ZF_BLOCK_SIZE) { - if (iso9660->zisofs.block_offset != - file->cur_content->size) { - int64_t diff; - - r = wb_set_offset(a, - file->cur_content->offset_of_temp + - iso9660->zisofs.block_offset); - if (r != ARCHIVE_OK) - return (r); - diff = file->cur_content->size - - iso9660->zisofs.block_offset; - file->cur_content->size -= diff; - iso9660->zisofs.total_size -= diff; - } - zstrm->avail_in = 0; - } - - /* - * Compress file data. - */ - while (zstrm->avail_in > 0) { - csize = zstrm->total_out; - r = deflate(zstrm, flush); - switch (r) { - case Z_OK: - case Z_STREAM_END: - csize = zstrm->total_out - csize; - if (wb_consume(a, csize) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - iso9660->zisofs.total_size += csize; - iso9660->cur_file->cur_content->size += csize; - zstrm->next_out = wb_buffptr(a); - zstrm->avail_out = (uInt)wb_remaining(a); - break; - default: - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Compression failed:" - " deflate() call returned status %d", - r); - return (ARCHIVE_FATAL); - } - } - - if (flush == Z_FINISH) { - /* - * Save the information of one zisofs block. - */ - iso9660->zisofs.block_pointers_idx ++; - archive_le32enc(&(iso9660->zisofs.block_pointers[ - iso9660->zisofs.block_pointers_idx]), - (uint32_t)iso9660->zisofs.total_size); - r = zisofs_init_zstream(a); - if (r != ARCHIVE_OK) - return (ARCHIVE_FATAL); - iso9660->zisofs.allzero = 1; - iso9660->zisofs.block_offset = file->cur_content->size; - } - } while (s); - - return (ARCHIVE_OK); -} - -static int -zisofs_finish_entry(struct archive_write *a) -{ - struct iso9660 *iso9660 = a->format_data; - struct isofile *file = iso9660->cur_file; - unsigned char buff[16]; - size_t s; - int64_t tail; - - /* Direct temp file stream to zisofs temp file stream. */ - archive_entry_set_size(file->entry, iso9660->zisofs.total_size); - - /* - * Save a file pointer which points the end of current zisofs data. - */ - tail = wb_offset(a); - - /* - * Make a header. - * - * +-----------------+----------------+-----------------+ - * | Header 16 bytes | Block Pointers | Compressed data | - * +-----------------+----------------+-----------------+ - * 0 16 +X - * Block Pointers : - * 4 * (((Uncompressed file size + block_size -1) / block_size) + 1) - * - * Write zisofs header. - * Magic number - * +----+----+----+----+----+----+----+----+ - * | 37 | E4 | 53 | 96 | C9 | DB | D6 | 07 | - * +----+----+----+----+----+----+----+----+ - * 0 1 2 3 4 5 6 7 8 - * - * +------------------------+------------------+ - * | Uncompressed file size | header_size >> 2 | - * +------------------------+------------------+ - * 8 12 13 - * - * +-----------------+----------------+ - * | log2 block_size | Reserved(0000) | - * +-----------------+----------------+ - * 13 14 16 - */ - memcpy(buff, zisofs_magic, 8); - set_num_731(buff+8, file->zisofs.uncompressed_size); - buff[12] = file->zisofs.header_size; - buff[13] = file->zisofs.log2_bs; - buff[14] = buff[15] = 0;/* Reserved */ - - /* Move to the right position to write the header. */ - wb_set_offset(a, file->content.offset_of_temp); - - /* Write the header. */ - if (wb_write_to_temp(a, buff, 16) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - /* - * Write zisofs Block Pointers. - */ - s = iso9660->zisofs.block_pointers_cnt * - sizeof(iso9660->zisofs.block_pointers[0]); - if (wb_write_to_temp(a, iso9660->zisofs.block_pointers, s) - != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - /* Set a file pointer back to the end of the temporary file. */ - wb_set_offset(a, tail); - - return (ARCHIVE_OK); -} - -static int -zisofs_free(struct archive_write *a) -{ - struct iso9660 *iso9660 = a->format_data; - int ret = ARCHIVE_OK; - - free(iso9660->zisofs.block_pointers); - if (iso9660->zisofs.stream_valid && - deflateEnd(&(iso9660->zisofs.stream)) != Z_OK) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Failed to clean up compressor"); - ret = ARCHIVE_FATAL; - } - iso9660->zisofs.block_pointers = NULL; - iso9660->zisofs.stream_valid = 0; - return (ret); -} - -struct zisofs_extract { - int pz_log2_bs; /* Log2 of block size */ - uint64_t pz_uncompressed_size; - size_t uncompressed_buffer_size; - - unsigned int initialized:1; - unsigned int header_passed:1; - - uint32_t pz_offset; - unsigned char *block_pointers; - size_t block_pointers_size; - size_t block_pointers_avail; - size_t block_off; - uint32_t block_avail; - - z_stream stream; - int stream_valid; -}; - -static ssize_t -zisofs_extract_init(struct archive_write *a, struct zisofs_extract *zisofs, - const unsigned char *p, size_t bytes) -{ - size_t avail = bytes; - size_t _ceil, xsize; - - /* Allocate block pointers buffer. */ - _ceil = (size_t)((zisofs->pz_uncompressed_size + - (((int64_t)1) << zisofs->pz_log2_bs) - 1) - >> zisofs->pz_log2_bs); - xsize = (_ceil + 1) * 4; - if (zisofs->block_pointers == NULL) { - size_t alloc = ((xsize >> 10) + 1) << 10; - zisofs->block_pointers = malloc(alloc); - if (zisofs->block_pointers == NULL) { - archive_set_error(&a->archive, ENOMEM, - "No memory for zisofs decompression"); - return (ARCHIVE_FATAL); - } - } - zisofs->block_pointers_size = xsize; - - /* Allocate uncompressed data buffer. */ - zisofs->uncompressed_buffer_size = (size_t)1UL << zisofs->pz_log2_bs; - - /* - * Read the file header, and check the magic code of zisofs. - */ - if (!zisofs->header_passed) { - int err = 0; - if (avail < 16) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Illegal zisofs file body"); - return (ARCHIVE_FATAL); - } - - if (memcmp(p, zisofs_magic, sizeof(zisofs_magic)) != 0) - err = 1; - else if (archive_le32dec(p + 8) != zisofs->pz_uncompressed_size) - err = 1; - else if (p[12] != 4 || p[13] != zisofs->pz_log2_bs) - err = 1; - if (err) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Illegal zisofs file body"); - return (ARCHIVE_FATAL); - } - avail -= 16; - p += 16; - zisofs->header_passed = 1; - } - - /* - * Read block pointers. - */ - if (zisofs->header_passed && - zisofs->block_pointers_avail < zisofs->block_pointers_size) { - xsize = zisofs->block_pointers_size - - zisofs->block_pointers_avail; - if (avail < xsize) - xsize = avail; - memcpy(zisofs->block_pointers - + zisofs->block_pointers_avail, p, xsize); - zisofs->block_pointers_avail += xsize; - avail -= xsize; - if (zisofs->block_pointers_avail - == zisofs->block_pointers_size) { - /* We've got all block pointers and initialize - * related variables. */ - zisofs->block_off = 0; - zisofs->block_avail = 0; - /* Complete a initialization */ - zisofs->initialized = 1; - } - } - return ((ssize_t)avail); -} - -static ssize_t -zisofs_extract(struct archive_write *a, struct zisofs_extract *zisofs, - const unsigned char *p, size_t bytes) -{ - size_t avail; - int r; - - if (!zisofs->initialized) { - ssize_t rs = zisofs_extract_init(a, zisofs, p, bytes); - if (rs < 0) - return (rs); - if (!zisofs->initialized) { - /* We need more data. */ - zisofs->pz_offset += (uint32_t)bytes; - return (bytes); - } - avail = rs; - p += bytes - avail; - } else - avail = bytes; - - /* - * Get block offsets from block pointers. - */ - if (zisofs->block_avail == 0) { - uint32_t bst, bed; - - if (zisofs->block_off + 4 >= zisofs->block_pointers_size) { - /* There isn't a pair of offsets. */ - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Illegal zisofs block pointers"); - return (ARCHIVE_FATAL); - } - bst = archive_le32dec( - zisofs->block_pointers + zisofs->block_off); - if (bst != zisofs->pz_offset + (bytes - avail)) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Illegal zisofs block pointers(cannot seek)"); - return (ARCHIVE_FATAL); - } - bed = archive_le32dec( - zisofs->block_pointers + zisofs->block_off + 4); - if (bed < bst) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Illegal zisofs block pointers"); - return (ARCHIVE_FATAL); - } - zisofs->block_avail = bed - bst; - zisofs->block_off += 4; - - /* Initialize compression library for new block. */ - if (zisofs->stream_valid) - r = inflateReset(&zisofs->stream); - else - r = inflateInit(&zisofs->stream); - if (r != Z_OK) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Can't initialize zisofs decompression."); - return (ARCHIVE_FATAL); - } - zisofs->stream_valid = 1; - zisofs->stream.total_in = 0; - zisofs->stream.total_out = 0; - } - - /* - * Make uncompressed data. - */ - if (zisofs->block_avail == 0) { - /* - * It's basically 32K bytes NUL data. - */ - unsigned char *wb; - size_t size, wsize; - - size = zisofs->uncompressed_buffer_size; - while (size) { - wb = wb_buffptr(a); - if (size > wb_remaining(a)) - wsize = wb_remaining(a); - else - wsize = size; - memset(wb, 0, wsize); - r = wb_consume(a, wsize); - if (r < 0) - return (r); - size -= wsize; - } - } else { - zisofs->stream.next_in = (Bytef *)(uintptr_t)(const void *)p; - if (avail > zisofs->block_avail) - zisofs->stream.avail_in = zisofs->block_avail; - else - zisofs->stream.avail_in = (uInt)avail; - zisofs->stream.next_out = wb_buffptr(a); - zisofs->stream.avail_out = (uInt)wb_remaining(a); - - r = inflate(&zisofs->stream, 0); - switch (r) { - case Z_OK: /* Decompressor made some progress.*/ - case Z_STREAM_END: /* Found end of stream. */ - break; - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "zisofs decompression failed (%d)", r); - return (ARCHIVE_FATAL); - } - avail -= zisofs->stream.next_in - p; - zisofs->block_avail -= (uint32_t)(zisofs->stream.next_in - p); - r = wb_consume(a, wb_remaining(a) - zisofs->stream.avail_out); - if (r < 0) - return (r); - } - zisofs->pz_offset += (uint32_t)bytes; - return (bytes - avail); -} - -static int -zisofs_rewind_boot_file(struct archive_write *a) -{ - struct iso9660 *iso9660 = a->format_data; - struct isofile *file; - unsigned char *rbuff; - ssize_t r; - size_t remaining, rbuff_size; - struct zisofs_extract zext; - int64_t read_offset, write_offset, new_offset; - int fd, ret = ARCHIVE_OK; - - file = iso9660->el_torito.boot->file; - /* - * There is nothing to do if this boot file does not have - * zisofs header. - */ - if (file->zisofs.header_size == 0) - return (ARCHIVE_OK); - - /* - * Uncompress the zisofs'ed file contents. - */ - memset(&zext, 0, sizeof(zext)); - zext.pz_uncompressed_size = file->zisofs.uncompressed_size; - zext.pz_log2_bs = file->zisofs.log2_bs; - - fd = iso9660->temp_fd; - new_offset = wb_offset(a); - read_offset = file->content.offset_of_temp; - remaining = (size_t)file->content.size; - if (remaining > 1024 * 32) - rbuff_size = 1024 * 32; - else - rbuff_size = remaining; - - rbuff = malloc(rbuff_size); - if (rbuff == NULL) { - archive_set_error(&a->archive, ENOMEM, "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - while (remaining) { - size_t rsize; - ssize_t rs; - - /* Get the current file pointer. */ - write_offset = lseek(fd, 0, SEEK_CUR); - - /* Change the file pointer to read. */ - lseek(fd, read_offset, SEEK_SET); - - rsize = rbuff_size; - if (rsize > remaining) - rsize = remaining; - rs = read(iso9660->temp_fd, rbuff, rsize); - if (rs <= 0) { - archive_set_error(&a->archive, errno, - "Can't read temporary file(%jd)", (intmax_t)rs); - ret = ARCHIVE_FATAL; - break; - } - remaining -= rs; - read_offset += rs; - - /* Put the file pointer back to write. */ - lseek(fd, write_offset, SEEK_SET); - - r = zisofs_extract(a, &zext, rbuff, rs); - if (r < 0) { - ret = (int)r; - break; - } - } - - if (ret == ARCHIVE_OK) { - /* - * Change the boot file content from zisofs'ed data - * to plain data. - */ - file->content.offset_of_temp = new_offset; - file->content.size = file->zisofs.uncompressed_size; - archive_entry_set_size(file->entry, file->content.size); - /* Set to be no zisofs. */ - file->zisofs.header_size = 0; - file->zisofs.log2_bs = 0; - file->zisofs.uncompressed_size = 0; - r = wb_write_padding_to_temp(a, file->content.size); - if (r < 0) - ret = ARCHIVE_FATAL; - } - - /* - * Free the resource we used in this function only. - */ - free(rbuff); - free(zext.block_pointers); - if (zext.stream_valid && inflateEnd(&(zext.stream)) != Z_OK) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Failed to clean up compressor"); - ret = ARCHIVE_FATAL; - } - - return (ret); -} - -#else - -static int -zisofs_write_to_temp(struct archive_write *a, const void *buff, size_t s) -{ - (void)buff; /* UNUSED */ - (void)s; /* UNUSED */ - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Programming error"); - return (ARCHIVE_FATAL); -} - -static int -zisofs_rewind_boot_file(struct archive_write *a) -{ - struct iso9660 *iso9660 = a->format_data; - - if (iso9660->el_torito.boot->file->zisofs.header_size != 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "We cannot extract the zisofs imaged boot file;" - " this may not boot in being zisofs imaged"); - return (ARCHIVE_FAILED); - } - return (ARCHIVE_OK); -} - -static int -zisofs_finish_entry(struct archive_write *a) -{ - (void)a; /* UNUSED */ - return (ARCHIVE_OK); -} - -static int -zisofs_free(struct archive_write *a) -{ - (void)a; /* UNUSED */ - return (ARCHIVE_OK); -} - -#endif /* HAVE_ZLIB_H */ - diff --git a/thirdparty/libarchive/libarchive/archive_write_set_format_mtree.c b/thirdparty/libarchive/libarchive/archive_write_set_format_mtree.c deleted file mode 100644 index 619b7714e..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_set_format_mtree.c +++ /dev/null @@ -1,2217 +0,0 @@ -/*- - * Copyright (c) 2008 Joerg Sonnenberger - * Copyright (c) 2009-2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_mtree.c 201171 2009-12-29 06:39:07Z kientzle $"); - -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#include -#include -#include - -#include "archive.h" -#include "archive_digest_private.h" -#include "archive_entry.h" -#include "archive_entry_private.h" -#include "archive_private.h" -#include "archive_rb.h" -#include "archive_string.h" -#include "archive_write_private.h" - -#define INDENTNAMELEN 15 -#define MAXLINELEN 80 -#define SET_KEYS \ - (F_FLAGS | F_GID | F_GNAME | F_MODE | F_TYPE | F_UID | F_UNAME) - -struct attr_counter { - struct attr_counter *prev; - struct attr_counter *next; - struct mtree_entry *m_entry; - int count; -}; - -struct att_counter_set { - struct attr_counter *uid_list; - struct attr_counter *gid_list; - struct attr_counter *mode_list; - struct attr_counter *flags_list; -}; - -struct mtree_chain { - struct mtree_entry *first; - struct mtree_entry **last; -}; - -/* - * The Data only for a directory file. - */ -struct dir_info { - struct archive_rb_tree rbtree; - struct mtree_chain children; - struct mtree_entry *chnext; - int virtual; -}; - -/* - * The Data only for a regular file. - */ -struct reg_info { - int compute_sum; - uint32_t crc; - struct ae_digest digest; -}; - -struct mtree_entry { - struct archive_rb_node rbnode; - struct mtree_entry *next; - struct mtree_entry *parent; - struct dir_info *dir_info; - struct reg_info *reg_info; - - struct archive_string parentdir; - struct archive_string basename; - struct archive_string pathname; - struct archive_string symlink; - struct archive_string uname; - struct archive_string gname; - struct archive_string fflags_text; - unsigned int nlink; - mode_t filetype; - mode_t mode; - int64_t size; - int64_t uid; - int64_t gid; - time_t mtime; - long mtime_nsec; - unsigned long fflags_set; - unsigned long fflags_clear; - dev_t rdevmajor; - dev_t rdevminor; - dev_t devmajor; - dev_t devminor; - int64_t ino; -}; - -struct mtree_writer { - struct mtree_entry *mtree_entry; - struct mtree_entry *root; - struct mtree_entry *cur_dirent; - struct archive_string cur_dirstr; - struct mtree_chain file_list; - - struct archive_string ebuf; - struct archive_string buf; - int first; - uint64_t entry_bytes_remaining; - - /* - * Set global value. - */ - struct { - int processing; - mode_t type; - int keys; - int64_t uid; - int64_t gid; - mode_t mode; - unsigned long fflags_set; - unsigned long fflags_clear; - } set; - struct att_counter_set acs; - int classic; - int depth; - - /* check sum */ - int compute_sum; - uint32_t crc; - uint64_t crc_len; -#ifdef ARCHIVE_HAS_MD5 - archive_md5_ctx md5ctx; -#endif -#ifdef ARCHIVE_HAS_RMD160 - archive_rmd160_ctx rmd160ctx; -#endif -#ifdef ARCHIVE_HAS_SHA1 - archive_sha1_ctx sha1ctx; -#endif -#ifdef ARCHIVE_HAS_SHA256 - archive_sha256_ctx sha256ctx; -#endif -#ifdef ARCHIVE_HAS_SHA384 - archive_sha384_ctx sha384ctx; -#endif -#ifdef ARCHIVE_HAS_SHA512 - archive_sha512_ctx sha512ctx; -#endif - /* Keyword options */ - int keys; -#define F_CKSUM 0x00000001 /* checksum */ -#define F_DEV 0x00000002 /* device type */ -#define F_DONE 0x00000004 /* directory done */ -#define F_FLAGS 0x00000008 /* file flags */ -#define F_GID 0x00000010 /* gid */ -#define F_GNAME 0x00000020 /* group name */ -#define F_IGN 0x00000040 /* ignore */ -#define F_MAGIC 0x00000080 /* name has magic chars */ -#define F_MD5 0x00000100 /* MD5 digest */ -#define F_MODE 0x00000200 /* mode */ -#define F_NLINK 0x00000400 /* number of links */ -#define F_NOCHANGE 0x00000800 /* If owner/mode "wrong", do - * not change */ -#define F_OPT 0x00001000 /* existence optional */ -#define F_RMD160 0x00002000 /* RIPEMD160 digest */ -#define F_SHA1 0x00004000 /* SHA-1 digest */ -#define F_SIZE 0x00008000 /* size */ -#define F_SLINK 0x00010000 /* symbolic link */ -#define F_TAGS 0x00020000 /* tags */ -#define F_TIME 0x00040000 /* modification time */ -#define F_TYPE 0x00080000 /* file type */ -#define F_UID 0x00100000 /* uid */ -#define F_UNAME 0x00200000 /* user name */ -#define F_VISIT 0x00400000 /* file visited */ -#define F_SHA256 0x00800000 /* SHA-256 digest */ -#define F_SHA384 0x01000000 /* SHA-384 digest */ -#define F_SHA512 0x02000000 /* SHA-512 digest */ -#define F_INO 0x04000000 /* inode number */ -#define F_RESDEV 0x08000000 /* device ID on which the - * entry resides */ - - /* Options */ - int dironly; /* If it is set, ignore all files except - * directory files, like mtree(8) -d option. */ - int indent; /* If it is set, indent output data. */ - int output_global_set; /* If it is set, use /set keyword to set - * global values. When generating mtree - * classic format, it is set by default. */ -}; - -#define DEFAULT_KEYS (F_DEV | F_FLAGS | F_GID | F_GNAME | F_SLINK | F_MODE\ - | F_NLINK | F_SIZE | F_TIME | F_TYPE | F_UID\ - | F_UNAME) -#define attr_counter_set_reset attr_counter_set_free - -static void attr_counter_free(struct attr_counter **); -static int attr_counter_inc(struct attr_counter **, struct attr_counter *, - struct attr_counter *, struct mtree_entry *); -static struct attr_counter * attr_counter_new(struct mtree_entry *, - struct attr_counter *); -static int attr_counter_set_collect(struct mtree_writer *, - struct mtree_entry *); -static void attr_counter_set_free(struct mtree_writer *); -static int get_global_set_keys(struct mtree_writer *, struct mtree_entry *); -static int mtree_entry_add_child_tail(struct mtree_entry *, - struct mtree_entry *); -static int mtree_entry_create_virtual_dir(struct archive_write *, const char *, - struct mtree_entry **); -static int mtree_entry_cmp_node(const struct archive_rb_node *, - const struct archive_rb_node *); -static int mtree_entry_cmp_key(const struct archive_rb_node *, const void *); -static int mtree_entry_exchange_same_entry(struct archive_write *, - struct mtree_entry *, struct mtree_entry *); -static void mtree_entry_free(struct mtree_entry *); -static int mtree_entry_new(struct archive_write *, struct archive_entry *, - struct mtree_entry **); -static void mtree_entry_register_free(struct mtree_writer *); -static void mtree_entry_register_init(struct mtree_writer *); -static int mtree_entry_setup_filenames(struct archive_write *, - struct mtree_entry *, struct archive_entry *); -static int mtree_entry_tree_add(struct archive_write *, struct mtree_entry **); -static void sum_init(struct mtree_writer *); -static void sum_update(struct mtree_writer *, const void *, size_t); -static void sum_final(struct mtree_writer *, struct reg_info *); -static void sum_write(struct archive_string *, struct reg_info *); -static int write_mtree_entry(struct archive_write *, struct mtree_entry *); -static int write_dot_dot_entry(struct archive_write *, struct mtree_entry *); - -#define COMPUTE_CRC(var, ch) (var) = (var) << 8 ^ crctab[(var) >> 24 ^ (ch)] -static const uint32_t crctab[] = { - 0x0, - 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, - 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, - 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, - 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, - 0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f, - 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, - 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, - 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, - 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, - 0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe, - 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, - 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, - 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, - 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, - 0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, - 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07, - 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, - 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, - 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, - 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, - 0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, - 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, - 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, - 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f, - 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, - 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, - 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, - 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, - 0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629, - 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, - 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, - 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, - 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, - 0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8, - 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, - 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, - 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, - 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, - 0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, - 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21, - 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, - 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087, - 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, - 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, - 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, - 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, - 0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, - 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09, - 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, - 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, - 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 -}; - -static const unsigned char safe_char[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 0F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */ - /* !"$%&'()*+,-./ EXCLUSION:0x20( ) 0x23(#) */ - 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */ - /* 0123456789:;<>? EXCLUSION:0x3d(=) */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, /* 30 - 3F */ - /* @ABCDEFGHIJKLMNO */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */ - /* PQRSTUVWXYZ[]^_ EXCLUSION:0x5c(\) */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, /* 50 - 5F */ - /* `abcdefghijklmno */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */ - /* pqrstuvwxyz{|}~ */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* 70 - 7F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F0 - FF */ -}; - -static void -mtree_quote(struct archive_string *s, const char *str) -{ - const char *start; - char buf[4]; - unsigned char c; - - for (start = str; *str != '\0'; ++str) { - if (safe_char[*(const unsigned char *)str]) - continue; - if (start != str) - archive_strncat(s, start, str - start); - c = (unsigned char)*str; - buf[0] = '\\'; - buf[1] = (c / 64) + '0'; - buf[2] = (c / 8 % 8) + '0'; - buf[3] = (c % 8) + '0'; - archive_strncat(s, buf, 4); - start = str + 1; - } - - if (start != str) - archive_strncat(s, start, str - start); -} - -/* - * Indent a line as the mtree utility does so it is readable for people. - */ -static void -mtree_indent(struct mtree_writer *mtree) -{ - int i, fn, nd, pd; - const char *r, *s, *x; - - if (mtree->classic) { - if (mtree->indent) { - nd = 0; - pd = mtree->depth * 4; - } else { - nd = mtree->depth?4:0; - pd = 0; - } - } else - nd = pd = 0; - fn = 1; - s = r = mtree->ebuf.s; - x = NULL; - while (*r == ' ') - r++; - while ((r = strchr(r, ' ')) != NULL) { - if (fn) { - fn = 0; - for (i = 0; i < nd + pd; i++) - archive_strappend_char(&mtree->buf, ' '); - archive_strncat(&mtree->buf, s, r - s); - if (nd + (r -s) > INDENTNAMELEN) { - archive_strncat(&mtree->buf, " \\\n", 3); - for (i = 0; i < (INDENTNAMELEN + 1 + pd); i++) - archive_strappend_char(&mtree->buf, ' '); - } else { - for (i = (int)(r -s + nd); - i < (INDENTNAMELEN + 1); i++) - archive_strappend_char(&mtree->buf, ' '); - } - s = ++r; - x = NULL; - continue; - } - if (pd + (r - s) <= MAXLINELEN - 3 - INDENTNAMELEN) - x = r++; - else { - if (x == NULL) - x = r; - archive_strncat(&mtree->buf, s, x - s); - archive_strncat(&mtree->buf, " \\\n", 3); - for (i = 0; i < (INDENTNAMELEN + 1 + pd); i++) - archive_strappend_char(&mtree->buf, ' '); - s = r = ++x; - x = NULL; - } - } - if (fn) { - for (i = 0; i < nd + pd; i++) - archive_strappend_char(&mtree->buf, ' '); - archive_strcat(&mtree->buf, s); - s += strlen(s); - } - if (x != NULL && pd + strlen(s) > MAXLINELEN - 3 - INDENTNAMELEN) { - /* Last keyword is longer. */ - archive_strncat(&mtree->buf, s, x - s); - archive_strncat(&mtree->buf, " \\\n", 3); - for (i = 0; i < (INDENTNAMELEN + 1 + pd); i++) - archive_strappend_char(&mtree->buf, ' '); - s = ++x; - } - archive_strcat(&mtree->buf, s); - archive_string_empty(&mtree->ebuf); -} - -/* - * Write /set keyword. - * Set the most used value of uid, gid, mode and fflags, which are - * collected by the attr_counter_set_collect() function. - */ -static void -write_global(struct mtree_writer *mtree) -{ - struct archive_string setstr; - struct archive_string unsetstr; - struct att_counter_set *acs; - int keys, oldkeys, effkeys; - - archive_string_init(&setstr); - archive_string_init(&unsetstr); - keys = mtree->keys & SET_KEYS; - oldkeys = mtree->set.keys; - effkeys = keys; - acs = &mtree->acs; - if (mtree->set.processing) { - /* - * Check if the global data needs updating. - */ - effkeys &= ~F_TYPE; - if (acs->uid_list == NULL) - effkeys &= ~(F_UNAME | F_UID); - else if (oldkeys & (F_UNAME | F_UID)) { - if (acs->uid_list->count < 2 || - mtree->set.uid == acs->uid_list->m_entry->uid) - effkeys &= ~(F_UNAME | F_UID); - } - if (acs->gid_list == NULL) - effkeys &= ~(F_GNAME | F_GID); - else if (oldkeys & (F_GNAME | F_GID)) { - if (acs->gid_list->count < 2 || - mtree->set.gid == acs->gid_list->m_entry->gid) - effkeys &= ~(F_GNAME | F_GID); - } - if (acs->mode_list == NULL) - effkeys &= ~F_MODE; - else if (oldkeys & F_MODE) { - if (acs->mode_list->count < 2 || - mtree->set.mode == acs->mode_list->m_entry->mode) - effkeys &= ~F_MODE; - } - if (acs->flags_list == NULL) - effkeys &= ~F_FLAGS; - else if ((oldkeys & F_FLAGS) != 0) { - if (acs->flags_list->count < 2 || - (acs->flags_list->m_entry->fflags_set == - mtree->set.fflags_set && - acs->flags_list->m_entry->fflags_clear == - mtree->set.fflags_clear)) - effkeys &= ~F_FLAGS; - } - } else { - if (acs->uid_list == NULL) - keys &= ~(F_UNAME | F_UID); - if (acs->gid_list == NULL) - keys &= ~(F_GNAME | F_GID); - if (acs->mode_list == NULL) - keys &= ~F_MODE; - if (acs->flags_list == NULL) - keys &= ~F_FLAGS; - } - if ((keys & effkeys & F_TYPE) != 0) { - if (mtree->dironly) { - archive_strcat(&setstr, " type=dir"); - mtree->set.type = AE_IFDIR; - } else { - archive_strcat(&setstr, " type=file"); - mtree->set.type = AE_IFREG; - } - } - if ((keys & effkeys & F_UNAME) != 0) { - if (archive_strlen(&(acs->uid_list->m_entry->uname)) > 0) { - archive_strcat(&setstr, " uname="); - mtree_quote(&setstr, acs->uid_list->m_entry->uname.s); - } else { - keys &= ~F_UNAME; - if ((oldkeys & F_UNAME) != 0) - archive_strcat(&unsetstr, " uname"); - } - } - if ((keys & effkeys & F_UID) != 0) { - mtree->set.uid = acs->uid_list->m_entry->uid; - archive_string_sprintf(&setstr, " uid=%jd", - (intmax_t)mtree->set.uid); - } - if ((keys & effkeys & F_GNAME) != 0) { - if (archive_strlen(&(acs->gid_list->m_entry->gname)) > 0) { - archive_strcat(&setstr, " gname="); - mtree_quote(&setstr, acs->gid_list->m_entry->gname.s); - } else { - keys &= ~F_GNAME; - if ((oldkeys & F_GNAME) != 0) - archive_strcat(&unsetstr, " gname"); - } - } - if ((keys & effkeys & F_GID) != 0) { - mtree->set.gid = acs->gid_list->m_entry->gid; - archive_string_sprintf(&setstr, " gid=%jd", - (intmax_t)mtree->set.gid); - } - if ((keys & effkeys & F_MODE) != 0) { - mtree->set.mode = acs->mode_list->m_entry->mode; - archive_string_sprintf(&setstr, " mode=%o", - (unsigned int)mtree->set.mode); - } - if ((keys & effkeys & F_FLAGS) != 0) { - if (archive_strlen( - &(acs->flags_list->m_entry->fflags_text)) > 0) { - archive_strcat(&setstr, " flags="); - mtree_quote(&setstr, - acs->flags_list->m_entry->fflags_text.s); - mtree->set.fflags_set = - acs->flags_list->m_entry->fflags_set; - mtree->set.fflags_clear = - acs->flags_list->m_entry->fflags_clear; - } else { - keys &= ~F_FLAGS; - if ((oldkeys & F_FLAGS) != 0) - archive_strcat(&unsetstr, " flags"); - } - } - if (unsetstr.length > 0) - archive_string_sprintf(&mtree->buf, "/unset%s\n", unsetstr.s); - archive_string_free(&unsetstr); - if (setstr.length > 0) - archive_string_sprintf(&mtree->buf, "/set%s\n", setstr.s); - archive_string_free(&setstr); - mtree->set.keys = keys; - mtree->set.processing = 1; -} - -static struct attr_counter * -attr_counter_new(struct mtree_entry *me, struct attr_counter *prev) -{ - struct attr_counter *ac; - - ac = malloc(sizeof(*ac)); - if (ac != NULL) { - ac->prev = prev; - ac->next = NULL; - ac->count = 1; - ac->m_entry = me; - } - return (ac); -} - -static void -attr_counter_free(struct attr_counter **top) -{ - struct attr_counter *ac, *tac; - - if (*top == NULL) - return; - ac = *top; - while (ac != NULL) { - tac = ac->next; - free(ac); - ac = tac; - } - *top = NULL; -} - -static int -attr_counter_inc(struct attr_counter **top, struct attr_counter *ac, - struct attr_counter *last, struct mtree_entry *me) -{ - struct attr_counter *pac; - - if (ac != NULL) { - ac->count++; - if (*top == ac || ac->prev->count >= ac->count) - return (0); - for (pac = ac->prev; pac; pac = pac->prev) { - if (pac->count >= ac->count) - break; - } - ac->prev->next = ac->next; - if (ac->next != NULL) - ac->next->prev = ac->prev; - if (pac != NULL) { - ac->prev = pac; - ac->next = pac->next; - pac->next = ac; - if (ac->next != NULL) - ac->next->prev = ac; - } else { - ac->prev = NULL; - ac->next = *top; - *top = ac; - ac->next->prev = ac; - } - } else if (last != NULL) { - ac = attr_counter_new(me, last); - if (ac == NULL) - return (-1); - last->next = ac; - } - return (0); -} - -/* - * Tabulate uid, gid, mode and fflags of a entry in order to be used for /set. - */ -static int -attr_counter_set_collect(struct mtree_writer *mtree, struct mtree_entry *me) -{ - struct attr_counter *ac, *last; - struct att_counter_set *acs = &mtree->acs; - int keys = mtree->keys; - - if (keys & (F_UNAME | F_UID)) { - if (acs->uid_list == NULL) { - acs->uid_list = attr_counter_new(me, NULL); - if (acs->uid_list == NULL) - return (-1); - } else { - last = NULL; - for (ac = acs->uid_list; ac; ac = ac->next) { - if (ac->m_entry->uid == me->uid) - break; - last = ac; - } - if (attr_counter_inc(&acs->uid_list, ac, last, me) < 0) - return (-1); - } - } - if (keys & (F_GNAME | F_GID)) { - if (acs->gid_list == NULL) { - acs->gid_list = attr_counter_new(me, NULL); - if (acs->gid_list == NULL) - return (-1); - } else { - last = NULL; - for (ac = acs->gid_list; ac; ac = ac->next) { - if (ac->m_entry->gid == me->gid) - break; - last = ac; - } - if (attr_counter_inc(&acs->gid_list, ac, last, me) < 0) - return (-1); - } - } - if (keys & F_MODE) { - if (acs->mode_list == NULL) { - acs->mode_list = attr_counter_new(me, NULL); - if (acs->mode_list == NULL) - return (-1); - } else { - last = NULL; - for (ac = acs->mode_list; ac; ac = ac->next) { - if (ac->m_entry->mode == me->mode) - break; - last = ac; - } - if (attr_counter_inc(&acs->mode_list, ac, last, me) < 0) - return (-1); - } - } - if (keys & F_FLAGS) { - if (acs->flags_list == NULL) { - acs->flags_list = attr_counter_new(me, NULL); - if (acs->flags_list == NULL) - return (-1); - } else { - last = NULL; - for (ac = acs->flags_list; ac; ac = ac->next) { - if (ac->m_entry->fflags_set == me->fflags_set && - ac->m_entry->fflags_clear == - me->fflags_clear) - break; - last = ac; - } - if (attr_counter_inc(&acs->flags_list, ac, last, me) < 0) - return (-1); - } - } - - return (0); -} - -static void -attr_counter_set_free(struct mtree_writer *mtree) -{ - struct att_counter_set *acs = &mtree->acs; - - attr_counter_free(&acs->uid_list); - attr_counter_free(&acs->gid_list); - attr_counter_free(&acs->mode_list); - attr_counter_free(&acs->flags_list); -} - -static int -get_global_set_keys(struct mtree_writer *mtree, struct mtree_entry *me) -{ - int keys; - - keys = mtree->keys; - - /* - * If a keyword has been set by /set, we do not need to - * output it. - */ - if (mtree->set.keys == 0) - return (keys);/* /set is not used. */ - - if ((mtree->set.keys & (F_GNAME | F_GID)) != 0 && - mtree->set.gid == me->gid) - keys &= ~(F_GNAME | F_GID); - if ((mtree->set.keys & (F_UNAME | F_UID)) != 0 && - mtree->set.uid == me->uid) - keys &= ~(F_UNAME | F_UID); - if (mtree->set.keys & F_FLAGS) { - if (mtree->set.fflags_set == me->fflags_set && - mtree->set.fflags_clear == me->fflags_clear) - keys &= ~F_FLAGS; - } - if ((mtree->set.keys & F_MODE) != 0 && mtree->set.mode == me->mode) - keys &= ~F_MODE; - - switch (me->filetype) { - case AE_IFLNK: case AE_IFSOCK: case AE_IFCHR: - case AE_IFBLK: case AE_IFIFO: - break; - case AE_IFDIR: - if ((mtree->set.keys & F_TYPE) != 0 && - mtree->set.type == AE_IFDIR) - keys &= ~F_TYPE; - break; - case AE_IFREG: - default: /* Handle unknown file types as regular files. */ - if ((mtree->set.keys & F_TYPE) != 0 && - mtree->set.type == AE_IFREG) - keys &= ~F_TYPE; - break; - } - - return (keys); -} - -static int -mtree_entry_new(struct archive_write *a, struct archive_entry *entry, - struct mtree_entry **m_entry) -{ - struct mtree_entry *me; - const char *s; - int r; - static const struct archive_rb_tree_ops rb_ops = { - mtree_entry_cmp_node, mtree_entry_cmp_key - }; - - me = calloc(1, sizeof(*me)); - if (me == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for a mtree entry"); - *m_entry = NULL; - return (ARCHIVE_FATAL); - } - - r = mtree_entry_setup_filenames(a, me, entry); - if (r < ARCHIVE_WARN) { - mtree_entry_free(me); - *m_entry = NULL; - return (r); - } - - if ((s = archive_entry_symlink(entry)) != NULL) - archive_strcpy(&me->symlink, s); - me->nlink = archive_entry_nlink(entry); - me->filetype = archive_entry_filetype(entry); - me->mode = archive_entry_mode(entry) & 07777; - me->uid = archive_entry_uid(entry); - me->gid = archive_entry_gid(entry); - if ((s = archive_entry_uname(entry)) != NULL) - archive_strcpy(&me->uname, s); - if ((s = archive_entry_gname(entry)) != NULL) - archive_strcpy(&me->gname, s); - if ((s = archive_entry_fflags_text(entry)) != NULL) - archive_strcpy(&me->fflags_text, s); - archive_entry_fflags(entry, &me->fflags_set, &me->fflags_clear); - me->mtime = archive_entry_mtime(entry); - me->mtime_nsec = archive_entry_mtime_nsec(entry); - me->rdevmajor = archive_entry_rdevmajor(entry); - me->rdevminor = archive_entry_rdevminor(entry); - me->devmajor = archive_entry_devmajor(entry); - me->devminor = archive_entry_devminor(entry); - me->ino = archive_entry_ino(entry); - me->size = archive_entry_size(entry); - if (me->filetype == AE_IFDIR) { - me->dir_info = calloc(1, sizeof(*me->dir_info)); - if (me->dir_info == NULL) { - mtree_entry_free(me); - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for a mtree entry"); - *m_entry = NULL; - return (ARCHIVE_FATAL); - } - __archive_rb_tree_init(&me->dir_info->rbtree, &rb_ops); - me->dir_info->children.first = NULL; - me->dir_info->children.last = &(me->dir_info->children.first); - me->dir_info->chnext = NULL; - } else if (me->filetype == AE_IFREG) { - me->reg_info = calloc(1, sizeof(*me->reg_info)); - if (me->reg_info == NULL) { - mtree_entry_free(me); - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for a mtree entry"); - *m_entry = NULL; - return (ARCHIVE_FATAL); - } - me->reg_info->compute_sum = 0; - } - - *m_entry = me; - return (ARCHIVE_OK); -} - -static void -mtree_entry_free(struct mtree_entry *me) -{ - archive_string_free(&me->parentdir); - archive_string_free(&me->basename); - archive_string_free(&me->pathname); - archive_string_free(&me->symlink); - archive_string_free(&me->uname); - archive_string_free(&me->gname); - archive_string_free(&me->fflags_text); - free(me->dir_info); - free(me->reg_info); - free(me); -} - -static int -archive_write_mtree_header(struct archive_write *a, - struct archive_entry *entry) -{ - struct mtree_writer *mtree= a->format_data; - struct mtree_entry *mtree_entry; - int r, r2; - - if (mtree->first) { - mtree->first = 0; - archive_strcat(&mtree->buf, "#mtree\n"); - if ((mtree->keys & SET_KEYS) == 0) - mtree->output_global_set = 0;/* Disabled. */ - } - - mtree->entry_bytes_remaining = archive_entry_size(entry); - - /* While directory only mode, we do not handle non directory files. */ - if (mtree->dironly && archive_entry_filetype(entry) != AE_IFDIR) - return (ARCHIVE_OK); - - r2 = mtree_entry_new(a, entry, &mtree_entry); - if (r2 < ARCHIVE_WARN) - return (r2); - r = mtree_entry_tree_add(a, &mtree_entry); - if (r < ARCHIVE_WARN) { - mtree_entry_free(mtree_entry); - return (r); - } - mtree->mtree_entry = mtree_entry; - - /* If the current file is a regular file, we have to - * compute the sum of its content. - * Initialize a bunch of checksum context. */ - if (mtree_entry->reg_info) - sum_init(mtree); - - return (r2); -} - -static int -write_mtree_entry(struct archive_write *a, struct mtree_entry *me) -{ - struct mtree_writer *mtree = a->format_data; - struct archive_string *str; - int keys, ret; - - if (me->dir_info) { - if (mtree->classic) { - /* - * Output a comment line to describe the full - * pathname of the entry as mtree utility does - * while generating classic format. - */ - if (!mtree->dironly) - archive_strappend_char(&mtree->buf, '\n'); - if (me->parentdir.s) - archive_string_sprintf(&mtree->buf, - "# %s/%s\n", - me->parentdir.s, me->basename.s); - else - archive_string_sprintf(&mtree->buf, - "# %s\n", - me->basename.s); - } - if (mtree->output_global_set) - write_global(mtree); - } - archive_string_empty(&mtree->ebuf); - str = (mtree->indent || mtree->classic)? &mtree->ebuf : &mtree->buf; - - if (!mtree->classic && me->parentdir.s) { - /* - * If generating format is not classic one(v1), output - * a full pathname. - */ - mtree_quote(str, me->parentdir.s); - archive_strappend_char(str, '/'); - } - mtree_quote(str, me->basename.s); - - keys = get_global_set_keys(mtree, me); - if ((keys & F_NLINK) != 0 && - me->nlink != 1 && me->filetype != AE_IFDIR) - archive_string_sprintf(str, " nlink=%u", me->nlink); - - if ((keys & F_GNAME) != 0 && archive_strlen(&me->gname) > 0) { - archive_strcat(str, " gname="); - mtree_quote(str, me->gname.s); - } - if ((keys & F_UNAME) != 0 && archive_strlen(&me->uname) > 0) { - archive_strcat(str, " uname="); - mtree_quote(str, me->uname.s); - } - if ((keys & F_FLAGS) != 0) { - if (archive_strlen(&me->fflags_text) > 0) { - archive_strcat(str, " flags="); - mtree_quote(str, me->fflags_text.s); - } else if (mtree->set.processing && - (mtree->set.keys & F_FLAGS) != 0) - /* Overwrite the global parameter. */ - archive_strcat(str, " flags=none"); - } - if ((keys & F_TIME) != 0) - archive_string_sprintf(str, " time=%jd.%jd", - (intmax_t)me->mtime, (intmax_t)me->mtime_nsec); - if ((keys & F_MODE) != 0) - archive_string_sprintf(str, " mode=%o", (unsigned int)me->mode); - if ((keys & F_GID) != 0) - archive_string_sprintf(str, " gid=%jd", (intmax_t)me->gid); - if ((keys & F_UID) != 0) - archive_string_sprintf(str, " uid=%jd", (intmax_t)me->uid); - - if ((keys & F_INO) != 0) - archive_string_sprintf(str, " inode=%jd", (intmax_t)me->ino); - if ((keys & F_RESDEV) != 0) { - archive_string_sprintf(str, - " resdevice=native,%ju,%ju", - (uintmax_t)me->devmajor, - (uintmax_t)me->devminor); - } - - switch (me->filetype) { - case AE_IFLNK: - if ((keys & F_TYPE) != 0) - archive_strcat(str, " type=link"); - if ((keys & F_SLINK) != 0) { - archive_strcat(str, " link="); - mtree_quote(str, me->symlink.s); - } - break; - case AE_IFSOCK: - if ((keys & F_TYPE) != 0) - archive_strcat(str, " type=socket"); - break; - case AE_IFCHR: - if ((keys & F_TYPE) != 0) - archive_strcat(str, " type=char"); - if ((keys & F_DEV) != 0) { - archive_string_sprintf(str, - " device=native,%ju,%ju", - (uintmax_t)me->rdevmajor, - (uintmax_t)me->rdevminor); - } - break; - case AE_IFBLK: - if ((keys & F_TYPE) != 0) - archive_strcat(str, " type=block"); - if ((keys & F_DEV) != 0) { - archive_string_sprintf(str, - " device=native,%ju,%ju", - (uintmax_t)me->rdevmajor, - (uintmax_t)me->rdevminor); - } - break; - case AE_IFDIR: - if ((keys & F_TYPE) != 0) - archive_strcat(str, " type=dir"); - break; - case AE_IFIFO: - if ((keys & F_TYPE) != 0) - archive_strcat(str, " type=fifo"); - break; - case AE_IFREG: - default: /* Handle unknown file types as regular files. */ - if ((keys & F_TYPE) != 0) - archive_strcat(str, " type=file"); - if ((keys & F_SIZE) != 0) - archive_string_sprintf(str, " size=%jd", - (intmax_t)me->size); - break; - } - - /* Write a bunch of sum. */ - if (me->reg_info) - sum_write(str, me->reg_info); - - archive_strappend_char(str, '\n'); - if (mtree->indent || mtree->classic) - mtree_indent(mtree); - - if (mtree->buf.length > 32768) { - ret = __archive_write_output( - a, mtree->buf.s, mtree->buf.length); - archive_string_empty(&mtree->buf); - } else - ret = ARCHIVE_OK; - return (ret); -} - -static int -write_dot_dot_entry(struct archive_write *a, struct mtree_entry *n) -{ - struct mtree_writer *mtree = a->format_data; - int ret; - - if (n->parentdir.s) { - if (mtree->indent) { - int i, pd = mtree->depth * 4; - for (i = 0; i < pd; i++) - archive_strappend_char(&mtree->buf, ' '); - } - archive_string_sprintf(&mtree->buf, "# %s/%s\n", - n->parentdir.s, n->basename.s); - } - - if (mtree->indent) { - archive_string_empty(&mtree->ebuf); - archive_strncat(&mtree->ebuf, "..\n\n", (mtree->dironly)?3:4); - mtree_indent(mtree); - } else - archive_strncat(&mtree->buf, "..\n\n", (mtree->dironly)?3:4); - - if (mtree->buf.length > 32768) { - ret = __archive_write_output( - a, mtree->buf.s, mtree->buf.length); - archive_string_empty(&mtree->buf); - } else - ret = ARCHIVE_OK; - return (ret); -} - -/* - * Write mtree entries saved at attr_counter_set_collect() function. - */ -static int -write_mtree_entry_tree(struct archive_write *a) -{ - struct mtree_writer *mtree = a->format_data; - struct mtree_entry *np = mtree->root; - struct archive_rb_node *n; - int ret; - - do { - if (mtree->output_global_set) { - /* - * Collect attribute information to know which value - * is frequently used among the children. - */ - attr_counter_set_reset(mtree); - ARCHIVE_RB_TREE_FOREACH(n, &(np->dir_info->rbtree)) { - struct mtree_entry *e = (struct mtree_entry *)n; - if (attr_counter_set_collect(mtree, e) < 0) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - } - } - if (!np->dir_info->virtual || mtree->classic) { - ret = write_mtree_entry(a, np); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } else { - /* Whenever output_global_set is enabled - * output global value(/set keywords) - * even if the directory entry is not allowed - * to be written because the global values - * can be used for the children. */ - if (mtree->output_global_set) - write_global(mtree); - } - /* - * Output the attribute of all files except directory files. - */ - mtree->depth++; - ARCHIVE_RB_TREE_FOREACH(n, &(np->dir_info->rbtree)) { - struct mtree_entry *e = (struct mtree_entry *)n; - - if (e->dir_info) - mtree_entry_add_child_tail(np, e); - else { - ret = write_mtree_entry(a, e); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } - } - mtree->depth--; - - if (np->dir_info->children.first != NULL) { - /* - * Descend the tree. - */ - np = np->dir_info->children.first; - if (mtree->indent) - mtree->depth++; - continue; - } else if (mtree->classic) { - /* - * While printing mtree classic, if there are not - * any directory files(except "." and "..") in the - * directory, output two dots ".." as returning - * the parent directory. - */ - ret = write_dot_dot_entry(a, np); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } - - while (np != np->parent) { - if (np->dir_info->chnext == NULL) { - /* - * Ascend the tree; go back to the parent. - */ - if (mtree->indent) - mtree->depth--; - if (mtree->classic) { - ret = write_dot_dot_entry(a, - np->parent); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } - np = np->parent; - } else { - /* - * Switch to next mtree entry in the directory. - */ - np = np->dir_info->chnext; - break; - } - } - } while (np != np->parent); - - return (ARCHIVE_OK); -} - -static int -archive_write_mtree_finish_entry(struct archive_write *a) -{ - struct mtree_writer *mtree = a->format_data; - struct mtree_entry *me; - - if ((me = mtree->mtree_entry) == NULL) - return (ARCHIVE_OK); - mtree->mtree_entry = NULL; - - if (me->reg_info) - sum_final(mtree, me->reg_info); - - return (ARCHIVE_OK); -} - -static int -archive_write_mtree_close(struct archive_write *a) -{ - struct mtree_writer *mtree= a->format_data; - int ret; - - if (mtree->root != NULL) { - ret = write_mtree_entry_tree(a); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } - - archive_write_set_bytes_in_last_block(&a->archive, 1); - - return __archive_write_output(a, mtree->buf.s, mtree->buf.length); -} - -static ssize_t -archive_write_mtree_data(struct archive_write *a, const void *buff, size_t n) -{ - struct mtree_writer *mtree= a->format_data; - - if (n > mtree->entry_bytes_remaining) - n = (size_t)mtree->entry_bytes_remaining; - mtree->entry_bytes_remaining -= n; - - /* We don't need to compute a regular file sum */ - if (mtree->mtree_entry == NULL) - return (n); - - if (mtree->mtree_entry->filetype == AE_IFREG) - sum_update(mtree, buff, n); - - return (n); -} - -static int -archive_write_mtree_free(struct archive_write *a) -{ - struct mtree_writer *mtree= a->format_data; - - if (mtree == NULL) - return (ARCHIVE_OK); - - /* Make sure we do not leave any entries. */ - mtree_entry_register_free(mtree); - archive_string_free(&mtree->cur_dirstr); - archive_string_free(&mtree->ebuf); - archive_string_free(&mtree->buf); - attr_counter_set_free(mtree); - free(mtree); - a->format_data = NULL; - return (ARCHIVE_OK); -} - -static int -archive_write_mtree_options(struct archive_write *a, const char *key, - const char *value) -{ - struct mtree_writer *mtree= a->format_data; - int keybit = 0; - - switch (key[0]) { - case 'a': - if (strcmp(key, "all") == 0) - keybit = ~0; - break; - case 'c': - if (strcmp(key, "cksum") == 0) - keybit = F_CKSUM; - break; - case 'd': - if (strcmp(key, "device") == 0) - keybit = F_DEV; - else if (strcmp(key, "dironly") == 0) { - mtree->dironly = (value != NULL)? 1: 0; - return (ARCHIVE_OK); - } - break; - case 'f': - if (strcmp(key, "flags") == 0) - keybit = F_FLAGS; - break; - case 'g': - if (strcmp(key, "gid") == 0) - keybit = F_GID; - else if (strcmp(key, "gname") == 0) - keybit = F_GNAME; - break; - case 'i': - if (strcmp(key, "indent") == 0) { - mtree->indent = (value != NULL)? 1: 0; - return (ARCHIVE_OK); - } else if (strcmp(key, "inode") == 0) { - keybit = F_INO; - } - break; - case 'l': - if (strcmp(key, "link") == 0) - keybit = F_SLINK; - break; - case 'm': - if (strcmp(key, "md5") == 0 || - strcmp(key, "md5digest") == 0) - keybit = F_MD5; - if (strcmp(key, "mode") == 0) - keybit = F_MODE; - break; - case 'n': - if (strcmp(key, "nlink") == 0) - keybit = F_NLINK; - break; - case 'r': - if (strcmp(key, "resdevice") == 0) { - keybit = F_RESDEV; - } else if (strcmp(key, "ripemd160digest") == 0 || - strcmp(key, "rmd160") == 0 || - strcmp(key, "rmd160digest") == 0) - keybit = F_RMD160; - break; - case 's': - if (strcmp(key, "sha1") == 0 || - strcmp(key, "sha1digest") == 0) - keybit = F_SHA1; - if (strcmp(key, "sha256") == 0 || - strcmp(key, "sha256digest") == 0) - keybit = F_SHA256; - if (strcmp(key, "sha384") == 0 || - strcmp(key, "sha384digest") == 0) - keybit = F_SHA384; - if (strcmp(key, "sha512") == 0 || - strcmp(key, "sha512digest") == 0) - keybit = F_SHA512; - if (strcmp(key, "size") == 0) - keybit = F_SIZE; - break; - case 't': - if (strcmp(key, "time") == 0) - keybit = F_TIME; - else if (strcmp(key, "type") == 0) - keybit = F_TYPE; - break; - case 'u': - if (strcmp(key, "uid") == 0) - keybit = F_UID; - else if (strcmp(key, "uname") == 0) - keybit = F_UNAME; - else if (strcmp(key, "use-set") == 0) { - mtree->output_global_set = (value != NULL)? 1: 0; - return (ARCHIVE_OK); - } - break; - } - if (keybit != 0) { - if (value != NULL) - mtree->keys |= keybit; - else - mtree->keys &= ~keybit; - return (ARCHIVE_OK); - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -static int -archive_write_set_format_mtree_default(struct archive *_a, const char *fn) -{ - struct archive_write *a = (struct archive_write *)_a; - struct mtree_writer *mtree; - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_NEW, fn); - - if (a->format_free != NULL) - (a->format_free)(a); - - if ((mtree = calloc(1, sizeof(*mtree))) == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate mtree data"); - return (ARCHIVE_FATAL); - } - - mtree->mtree_entry = NULL; - mtree->first = 1; - memset(&(mtree->set), 0, sizeof(mtree->set)); - mtree->keys = DEFAULT_KEYS; - mtree->dironly = 0; - mtree->indent = 0; - archive_string_init(&mtree->ebuf); - archive_string_init(&mtree->buf); - mtree_entry_register_init(mtree); - a->format_data = mtree; - a->format_free = archive_write_mtree_free; - a->format_name = "mtree"; - a->format_options = archive_write_mtree_options; - a->format_write_header = archive_write_mtree_header; - a->format_close = archive_write_mtree_close; - a->format_write_data = archive_write_mtree_data; - a->format_finish_entry = archive_write_mtree_finish_entry; - a->archive.archive_format = ARCHIVE_FORMAT_MTREE; - a->archive.archive_format_name = "mtree"; - - return (ARCHIVE_OK); -} - -int -archive_write_set_format_mtree(struct archive *_a) -{ - return archive_write_set_format_mtree_default(_a, - "archive_write_set_format_mtree"); -} - -int -archive_write_set_format_mtree_classic(struct archive *_a) -{ - int r; - - r = archive_write_set_format_mtree_default(_a, - "archive_write_set_format_mtree_classic"); - if (r == ARCHIVE_OK) { - struct archive_write *a = (struct archive_write *)_a; - struct mtree_writer *mtree; - - mtree = (struct mtree_writer *)a->format_data; - - /* Set to output a mtree archive in classic format. */ - mtree->classic = 1; - /* Basically, mtree classic format uses '/set' global - * value. */ - mtree->output_global_set = 1; - } - return (r); -} - -static void -sum_init(struct mtree_writer *mtree) -{ - - mtree->compute_sum = 0; - - if (mtree->keys & F_CKSUM) { - mtree->compute_sum |= F_CKSUM; - mtree->crc = 0; - mtree->crc_len = 0; - } -#ifdef ARCHIVE_HAS_MD5 - if (mtree->keys & F_MD5) { - if (archive_md5_init(&mtree->md5ctx) == ARCHIVE_OK) - mtree->compute_sum |= F_MD5; - else - mtree->keys &= ~F_MD5;/* Not supported. */ - } -#endif -#ifdef ARCHIVE_HAS_RMD160 - if (mtree->keys & F_RMD160) { - if (archive_rmd160_init(&mtree->rmd160ctx) == ARCHIVE_OK) - mtree->compute_sum |= F_RMD160; - else - mtree->keys &= ~F_RMD160;/* Not supported. */ - } -#endif -#ifdef ARCHIVE_HAS_SHA1 - if (mtree->keys & F_SHA1) { - if (archive_sha1_init(&mtree->sha1ctx) == ARCHIVE_OK) - mtree->compute_sum |= F_SHA1; - else - mtree->keys &= ~F_SHA1;/* Not supported. */ - } -#endif -#ifdef ARCHIVE_HAS_SHA256 - if (mtree->keys & F_SHA256) { - if (archive_sha256_init(&mtree->sha256ctx) == ARCHIVE_OK) - mtree->compute_sum |= F_SHA256; - else - mtree->keys &= ~F_SHA256;/* Not supported. */ - } -#endif -#ifdef ARCHIVE_HAS_SHA384 - if (mtree->keys & F_SHA384) { - if (archive_sha384_init(&mtree->sha384ctx) == ARCHIVE_OK) - mtree->compute_sum |= F_SHA384; - else - mtree->keys &= ~F_SHA384;/* Not supported. */ - } -#endif -#ifdef ARCHIVE_HAS_SHA512 - if (mtree->keys & F_SHA512) { - if (archive_sha512_init(&mtree->sha512ctx) == ARCHIVE_OK) - mtree->compute_sum |= F_SHA512; - else - mtree->keys &= ~F_SHA512;/* Not supported. */ - } -#endif -} - -static void -sum_update(struct mtree_writer *mtree, const void *buff, size_t n) -{ - if (mtree->compute_sum & F_CKSUM) { - /* - * Compute a POSIX 1003.2 checksum - */ - const unsigned char *p; - size_t nn; - - for (nn = n, p = buff; nn--; ++p) - COMPUTE_CRC(mtree->crc, *p); - mtree->crc_len += n; - } -#ifdef ARCHIVE_HAS_MD5 - if (mtree->compute_sum & F_MD5) - archive_md5_update(&mtree->md5ctx, buff, n); -#endif -#ifdef ARCHIVE_HAS_RMD160 - if (mtree->compute_sum & F_RMD160) - archive_rmd160_update(&mtree->rmd160ctx, buff, n); -#endif -#ifdef ARCHIVE_HAS_SHA1 - if (mtree->compute_sum & F_SHA1) - archive_sha1_update(&mtree->sha1ctx, buff, n); -#endif -#ifdef ARCHIVE_HAS_SHA256 - if (mtree->compute_sum & F_SHA256) - archive_sha256_update(&mtree->sha256ctx, buff, n); -#endif -#ifdef ARCHIVE_HAS_SHA384 - if (mtree->compute_sum & F_SHA384) - archive_sha384_update(&mtree->sha384ctx, buff, n); -#endif -#ifdef ARCHIVE_HAS_SHA512 - if (mtree->compute_sum & F_SHA512) - archive_sha512_update(&mtree->sha512ctx, buff, n); -#endif -} - -static void -sum_final(struct mtree_writer *mtree, struct reg_info *reg) -{ - - if (mtree->compute_sum & F_CKSUM) { - uint64_t len; - /* Include the length of the file. */ - for (len = mtree->crc_len; len != 0; len >>= 8) - COMPUTE_CRC(mtree->crc, len & 0xff); - reg->crc = ~mtree->crc; - } -#ifdef ARCHIVE_HAS_MD5 - if (mtree->compute_sum & F_MD5) - archive_md5_final(&mtree->md5ctx, reg->digest.md5); -#endif -#ifdef ARCHIVE_HAS_RMD160 - if (mtree->compute_sum & F_RMD160) - archive_rmd160_final(&mtree->rmd160ctx, reg->digest.rmd160); -#endif -#ifdef ARCHIVE_HAS_SHA1 - if (mtree->compute_sum & F_SHA1) - archive_sha1_final(&mtree->sha1ctx, reg->digest.sha1); -#endif -#ifdef ARCHIVE_HAS_SHA256 - if (mtree->compute_sum & F_SHA256) - archive_sha256_final(&mtree->sha256ctx, reg->digest.sha256); -#endif -#ifdef ARCHIVE_HAS_SHA384 - if (mtree->compute_sum & F_SHA384) - archive_sha384_final(&mtree->sha384ctx, reg->digest.sha384); -#endif -#ifdef ARCHIVE_HAS_SHA512 - if (mtree->compute_sum & F_SHA512) - archive_sha512_final(&mtree->sha512ctx, reg->digest.sha512); -#endif - /* Save what types of sum are computed. */ - reg->compute_sum = mtree->compute_sum; -} - -#if defined(ARCHIVE_HAS_MD5) || defined(ARCHIVE_HAS_RMD160) || \ - defined(ARCHIVE_HAS_SHA1) || defined(ARCHIVE_HAS_SHA256) || \ - defined(ARCHIVE_HAS_SHA384) || defined(ARCHIVE_HAS_SHA512) -static void -strappend_bin(struct archive_string *s, const unsigned char *bin, int n) -{ - static const char hex[] = "0123456789abcdef"; - int i; - - for (i = 0; i < n; i++) { - archive_strappend_char(s, hex[bin[i] >> 4]); - archive_strappend_char(s, hex[bin[i] & 0x0f]); - } -} -#endif - -static void -sum_write(struct archive_string *str, struct reg_info *reg) -{ - - if (reg->compute_sum & F_CKSUM) { - archive_string_sprintf(str, " cksum=%ju", - (uintmax_t)reg->crc); - } - -#define append_digest(_s, _r, _t) \ - strappend_bin(_s, _r->digest._t, sizeof(_r->digest._t)) - -#ifdef ARCHIVE_HAS_MD5 - if (reg->compute_sum & F_MD5) { - archive_strcat(str, " md5digest="); - append_digest(str, reg, md5); - } -#endif -#ifdef ARCHIVE_HAS_RMD160 - if (reg->compute_sum & F_RMD160) { - archive_strcat(str, " rmd160digest="); - append_digest(str, reg, rmd160); - } -#endif -#ifdef ARCHIVE_HAS_SHA1 - if (reg->compute_sum & F_SHA1) { - archive_strcat(str, " sha1digest="); - append_digest(str, reg, sha1); - } -#endif -#ifdef ARCHIVE_HAS_SHA256 - if (reg->compute_sum & F_SHA256) { - archive_strcat(str, " sha256digest="); - append_digest(str, reg, sha256); - } -#endif -#ifdef ARCHIVE_HAS_SHA384 - if (reg->compute_sum & F_SHA384) { - archive_strcat(str, " sha384digest="); - append_digest(str, reg, sha384); - } -#endif -#ifdef ARCHIVE_HAS_SHA512 - if (reg->compute_sum & F_SHA512) { - archive_strcat(str, " sha512digest="); - append_digest(str, reg, sha512); - } -#endif -#undef append_digest -} - -static int -mtree_entry_cmp_node(const struct archive_rb_node *n1, - const struct archive_rb_node *n2) -{ - const struct mtree_entry *e1 = (const struct mtree_entry *)n1; - const struct mtree_entry *e2 = (const struct mtree_entry *)n2; - - return (strcmp(e2->basename.s, e1->basename.s)); -} - -static int -mtree_entry_cmp_key(const struct archive_rb_node *n, const void *key) -{ - const struct mtree_entry *e = (const struct mtree_entry *)n; - - return (strcmp((const char *)key, e->basename.s)); -} - -#if defined(_WIN32) || defined(__CYGWIN__) -static int -cleanup_backslash_1(char *p) -{ - int mb, dos; - - mb = dos = 0; - while (*p) { - if (*(unsigned char *)p > 127) - mb = 1; - if (*p == '\\') { - /* If we have not met any multi-byte characters, - * we can replace '\' with '/'. */ - if (!mb) - *p = '/'; - dos = 1; - } - p++; - } - if (!mb || !dos) - return (0); - return (-1); -} - -static void -cleanup_backslash_2(wchar_t *p) -{ - - /* Convert a path-separator from '\' to '/' */ - while (*p != L'\0') { - if (*p == L'\\') - *p = L'/'; - p++; - } -} -#endif - -/* - * Generate a parent directory name and a base name from a pathname. - */ -static int -mtree_entry_setup_filenames(struct archive_write *a, struct mtree_entry *file, - struct archive_entry *entry) -{ - const char *pathname; - char *p, *dirname, *slash; - size_t len; - int ret = ARCHIVE_OK; - - archive_strcpy(&file->pathname, archive_entry_pathname(entry)); -#if defined(_WIN32) || defined(__CYGWIN__) - /* - * Convert a path-separator from '\' to '/' - */ - if (cleanup_backslash_1(file->pathname.s) != 0) { - const wchar_t *wp = archive_entry_pathname_w(entry); - struct archive_wstring ws; - - if (wp != NULL) { - int r; - archive_string_init(&ws); - archive_wstrcpy(&ws, wp); - cleanup_backslash_2(ws.s); - archive_string_empty(&(file->pathname)); - r = archive_string_append_from_wcs(&(file->pathname), - ws.s, ws.length); - archive_wstring_free(&ws); - if (r < 0 && errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - } - } -#else - (void)a; /* UNUSED */ -#endif - pathname = file->pathname.s; - if (strcmp(pathname, ".") == 0) { - archive_strcpy(&file->basename, "."); - return (ARCHIVE_OK); - } - - archive_strcpy(&(file->parentdir), pathname); - - len = file->parentdir.length; - p = dirname = file->parentdir.s; - - /* - * Remove leading '/' and '../' elements - */ - while (*p) { - if (p[0] == '/') { - p++; - len--; - } else if (p[0] != '.') - break; - else if (p[1] == '.' && p[2] == '/') { - p += 3; - len -= 3; - } else - break; - } - if (p != dirname) { - memmove(dirname, p, len+1); - p = dirname; - } - /* - * Remove "/","/." and "/.." elements from tail. - */ - while (len > 0) { - size_t ll = len; - - if (len > 0 && p[len-1] == '/') { - p[len-1] = '\0'; - len--; - } - if (len > 1 && p[len-2] == '/' && p[len-1] == '.') { - p[len-2] = '\0'; - len -= 2; - } - if (len > 2 && p[len-3] == '/' && p[len-2] == '.' && - p[len-1] == '.') { - p[len-3] = '\0'; - len -= 3; - } - if (ll == len) - break; - } - while (*p) { - if (p[0] == '/') { - if (p[1] == '/') - /* Convert '//' --> '/' */ - memmove(p, p+1, strlen(p+1) + 1); - else if (p[1] == '.' && p[2] == '/') - /* Convert '/./' --> '/' */ - memmove(p, p+2, strlen(p+2) + 1); - else if (p[1] == '.' && p[2] == '.' && p[3] == '/') { - /* Convert 'dir/dir1/../dir2/' - * --> 'dir/dir2/' - */ - char *rp = p -1; - while (rp >= dirname) { - if (*rp == '/') - break; - --rp; - } - if (rp > dirname) { - strcpy(rp, p+3); - p = rp; - } else { - strcpy(dirname, p+4); - p = dirname; - } - } else - p++; - } else - p++; - } - p = dirname; - len = strlen(p); - - /* - * Add "./" prefix. - * NOTE: If the pathname does not have a path separator, we have - * to add "./" to the head of the pathname because mtree reader - * will suppose that it is v1(a.k.a classic) mtree format and - * change the directory unexpectedly and so it will make a wrong - * path. - */ - if (strcmp(p, ".") != 0 && strncmp(p, "./", 2) != 0) { - struct archive_string as; - archive_string_init(&as); - archive_strcpy(&as, "./"); - archive_strncat(&as, p, len); - archive_string_empty(&file->parentdir); - archive_string_concat(&file->parentdir, &as); - archive_string_free(&as); - p = file->parentdir.s; - len = archive_strlen(&file->parentdir); - } - - /* - * Find out the position which points the last position of - * path separator('/'). - */ - slash = NULL; - for (; *p != '\0'; p++) { - if (*p == '/') - slash = p; - } - if (slash == NULL) { - /* The pathname doesn't have a parent directory. */ - file->parentdir.length = len; - archive_string_copy(&(file->basename), &(file->parentdir)); - archive_string_empty(&(file->parentdir)); - *file->parentdir.s = '\0'; - return (ret); - } - - /* Make a basename from file->parentdir.s and slash */ - *slash = '\0'; - file->parentdir.length = slash - file->parentdir.s; - archive_strcpy(&(file->basename), slash + 1); - return (ret); -} - -static int -mtree_entry_create_virtual_dir(struct archive_write *a, const char *pathname, - struct mtree_entry **m_entry) -{ - struct archive_entry *entry; - struct mtree_entry *file; - int r; - - entry = archive_entry_new(); - if (entry == NULL) { - *m_entry = NULL; - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - archive_entry_copy_pathname(entry, pathname); - archive_entry_set_mode(entry, AE_IFDIR | 0755); - archive_entry_set_mtime(entry, time(NULL), 0); - - r = mtree_entry_new(a, entry, &file); - archive_entry_free(entry); - if (r < ARCHIVE_WARN) { - *m_entry = NULL; - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - - file->dir_info->virtual = 1; - - *m_entry = file; - return (ARCHIVE_OK); -} - -static void -mtree_entry_register_add(struct mtree_writer *mtree, struct mtree_entry *file) -{ - file->next = NULL; - *mtree->file_list.last = file; - mtree->file_list.last = &(file->next); -} - -static void -mtree_entry_register_init(struct mtree_writer *mtree) -{ - mtree->file_list.first = NULL; - mtree->file_list.last = &(mtree->file_list.first); -} - -static void -mtree_entry_register_free(struct mtree_writer *mtree) -{ - struct mtree_entry *file, *file_next; - - file = mtree->file_list.first; - while (file != NULL) { - file_next = file->next; - mtree_entry_free(file); - file = file_next; - } -} - -static int -mtree_entry_add_child_tail(struct mtree_entry *parent, - struct mtree_entry *child) -{ - child->dir_info->chnext = NULL; - *parent->dir_info->children.last = child; - parent->dir_info->children.last = &(child->dir_info->chnext); - return (1); -} - -/* - * Find a entry from a parent entry with the name. - */ -static struct mtree_entry * -mtree_entry_find_child(struct mtree_entry *parent, const char *child_name) -{ - struct mtree_entry *np; - - if (parent == NULL) - return (NULL); - np = (struct mtree_entry *)__archive_rb_tree_find_node( - &(parent->dir_info->rbtree), child_name); - return (np); -} - -static int -get_path_component(char *name, size_t n, const char *fn) -{ - char *p; - size_t l; - - p = strchr(fn, '/'); - if (p == NULL) { - if ((l = strlen(fn)) == 0) - return (0); - } else - l = p - fn; - if (l > n -1) - return (-1); - memcpy(name, fn, l); - name[l] = '\0'; - - return ((int)l); -} - -/* - * Add a new entry into the tree. - */ -static int -mtree_entry_tree_add(struct archive_write *a, struct mtree_entry **filep) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - char name[_MAX_FNAME];/* Included null terminator size. */ -#elif defined(NAME_MAX) && NAME_MAX >= 255 - char name[NAME_MAX+1]; -#else - char name[256]; -#endif - struct mtree_writer *mtree = (struct mtree_writer *)a->format_data; - struct mtree_entry *dent, *file, *np; - const char *fn, *p; - int l, r; - - file = *filep; - if (file->parentdir.length == 0 && file->basename.length == 1 && - file->basename.s[0] == '.') { - file->parent = file; - if (mtree->root != NULL) { - np = mtree->root; - goto same_entry; - } - mtree->root = file; - mtree_entry_register_add(mtree, file); - return (ARCHIVE_OK); - } - - if (file->parentdir.length == 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Internal programming error " - "in generating canonical name for %s", - file->pathname.s); - return (ARCHIVE_FAILED); - } - - fn = p = file->parentdir.s; - - /* - * If the path of the parent directory of `file' entry is - * the same as the path of `cur_dirent', add `file' entry to - * `cur_dirent'. - */ - if (archive_strlen(&(mtree->cur_dirstr)) - == archive_strlen(&(file->parentdir)) && - strcmp(mtree->cur_dirstr.s, fn) == 0) { - if (!__archive_rb_tree_insert_node( - &(mtree->cur_dirent->dir_info->rbtree), - (struct archive_rb_node *)file)) { - /* There is the same name in the tree. */ - np = (struct mtree_entry *)__archive_rb_tree_find_node( - &(mtree->cur_dirent->dir_info->rbtree), - file->basename.s); - goto same_entry; - } - file->parent = mtree->cur_dirent; - mtree_entry_register_add(mtree, file); - return (ARCHIVE_OK); - } - - dent = mtree->root; - for (;;) { - l = get_path_component(name, sizeof(name), fn); - if (l == 0) { - np = NULL; - break; - } - if (l < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "A name buffer is too small"); - return (ARCHIVE_FATAL); - } - if (l == 1 && name[0] == '.' && dent != NULL && - dent == mtree->root) { - fn += l; - if (fn[0] == '/') - fn++; - continue; - } - - np = mtree_entry_find_child(dent, name); - if (np == NULL || fn[0] == '\0') - break; - - /* Find next sub directory. */ - if (!np->dir_info) { - /* NOT Directory! */ - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "`%s' is not directory, we cannot insert `%s' ", - np->pathname.s, file->pathname.s); - return (ARCHIVE_FAILED); - } - fn += l; - if (fn[0] == '/') - fn++; - dent = np; - } - if (np == NULL) { - /* - * Create virtual parent directories. - */ - while (fn[0] != '\0') { - struct mtree_entry *vp; - struct archive_string as; - - archive_string_init(&as); - archive_strncat(&as, p, fn - p + l); - if (as.s[as.length-1] == '/') { - as.s[as.length-1] = '\0'; - as.length--; - } - r = mtree_entry_create_virtual_dir(a, as.s, &vp); - archive_string_free(&as); - if (r < ARCHIVE_WARN) - return (r); - - if (strcmp(vp->pathname.s, ".") == 0) { - vp->parent = vp; - mtree->root = vp; - } else { - __archive_rb_tree_insert_node( - &(dent->dir_info->rbtree), - (struct archive_rb_node *)vp); - vp->parent = dent; - } - mtree_entry_register_add(mtree, vp); - np = vp; - - fn += l; - if (fn[0] == '/') - fn++; - l = get_path_component(name, sizeof(name), fn); - if (l < 0) { - archive_string_free(&as); - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "A name buffer is too small"); - return (ARCHIVE_FATAL); - } - dent = np; - } - - /* Found out the parent directory where `file' can be - * inserted. */ - mtree->cur_dirent = dent; - archive_string_empty(&(mtree->cur_dirstr)); - archive_string_ensure(&(mtree->cur_dirstr), - archive_strlen(&(dent->parentdir)) + - archive_strlen(&(dent->basename)) + 2); - if (archive_strlen(&(dent->parentdir)) + - archive_strlen(&(dent->basename)) == 0) - mtree->cur_dirstr.s[0] = 0; - else { - if (archive_strlen(&(dent->parentdir)) > 0) { - archive_string_copy(&(mtree->cur_dirstr), - &(dent->parentdir)); - archive_strappend_char( - &(mtree->cur_dirstr), '/'); - } - archive_string_concat(&(mtree->cur_dirstr), - &(dent->basename)); - } - - if (!__archive_rb_tree_insert_node( - &(dent->dir_info->rbtree), - (struct archive_rb_node *)file)) { - np = (struct mtree_entry *)__archive_rb_tree_find_node( - &(dent->dir_info->rbtree), file->basename.s); - goto same_entry; - } - file->parent = dent; - mtree_entry_register_add(mtree, file); - return (ARCHIVE_OK); - } - -same_entry: - /* - * We have already has the entry the filename of which is - * the same. - */ - r = mtree_entry_exchange_same_entry(a, np, file); - if (r < ARCHIVE_WARN) - return (r); - if (np->dir_info) - np->dir_info->virtual = 0; - *filep = np; - mtree_entry_free(file); - return (ARCHIVE_WARN); -} - -static int -mtree_entry_exchange_same_entry(struct archive_write *a, struct mtree_entry *np, - struct mtree_entry *file) -{ - - if ((np->mode & AE_IFMT) != (file->mode & AE_IFMT)) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Found duplicate entries `%s' and its file type is " - "different", - np->pathname.s); - return (ARCHIVE_FAILED); - } - - /* Update the existent mtree entry's attributes by the new one's. */ - archive_string_empty(&np->symlink); - archive_string_concat(&np->symlink, &file->symlink); - archive_string_empty(&np->uname); - archive_string_concat(&np->uname, &file->uname); - archive_string_empty(&np->gname); - archive_string_concat(&np->gname, &file->gname); - archive_string_empty(&np->fflags_text); - archive_string_concat(&np->fflags_text, &file->fflags_text); - np->nlink = file->nlink; - np->filetype = file->filetype; - np->mode = file->mode; - np->size = file->size; - np->uid = file->uid; - np->gid = file->gid; - np->fflags_set = file->fflags_set; - np->fflags_clear = file->fflags_clear; - np->mtime = file->mtime; - np->mtime_nsec = file->mtime_nsec; - np->rdevmajor = file->rdevmajor; - np->rdevminor = file->rdevminor; - np->devmajor = file->devmajor; - np->devminor = file->devminor; - np->ino = file->ino; - - return (ARCHIVE_WARN); -} diff --git a/thirdparty/libarchive/libarchive/archive_write_set_format_pax.c b/thirdparty/libarchive/libarchive/archive_write_set_format_pax.c deleted file mode 100644 index 1eb9a9a4b..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_set_format_pax.c +++ /dev/null @@ -1,2078 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2010-2012 Michihiro NAKAJIMA - * Copyright (c) 2016 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_pax.c 201162 2009-12-29 05:47:46Z kientzle $"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" -#include "archive_entry_locale.h" -#include "archive_private.h" -#include "archive_write_private.h" -#include "archive_write_set_format_private.h" - -struct sparse_block { - struct sparse_block *next; - int is_hole; - uint64_t offset; - uint64_t remaining; -}; - -struct pax { - uint64_t entry_bytes_remaining; - uint64_t entry_padding; - struct archive_string l_url_encoded_name; - struct archive_string pax_header; - struct archive_string sparse_map; - size_t sparse_map_padding; - struct sparse_block *sparse_list; - struct sparse_block *sparse_tail; - struct archive_string_conv *sconv_utf8; - int opt_binary; - - unsigned flags; -#define WRITE_SCHILY_XATTR (1 << 0) -#define WRITE_LIBARCHIVE_XATTR (1 << 1) -}; - -static void add_pax_attr(struct archive_string *, const char *key, - const char *value); -static void add_pax_attr_binary(struct archive_string *, - const char *key, - const char *value, size_t value_len); -static void add_pax_attr_int(struct archive_string *, - const char *key, int64_t value); -static void add_pax_attr_time(struct archive_string *, - const char *key, int64_t sec, - unsigned long nanos); -static int add_pax_acl(struct archive_write *, - struct archive_entry *, struct pax *, int); -static ssize_t archive_write_pax_data(struct archive_write *, - const void *, size_t); -static int archive_write_pax_close(struct archive_write *); -static int archive_write_pax_free(struct archive_write *); -static int archive_write_pax_finish_entry(struct archive_write *); -static int archive_write_pax_header(struct archive_write *, - struct archive_entry *); -static int archive_write_pax_options(struct archive_write *, - const char *, const char *); -static char *base64_encode(const char *src, size_t len); -static char *build_gnu_sparse_name(char *dest, const char *src); -static char *build_pax_attribute_name(char *dest, const char *src); -static char *build_ustar_entry_name(char *dest, const char *src, - size_t src_length, const char *insert); -static char *format_int(char *dest, int64_t); -static int has_non_ASCII(const char *); -static void sparse_list_clear(struct pax *); -static int sparse_list_add(struct pax *, int64_t, int64_t); -static char *url_encode(const char *in); -static time_t get_ustar_max_mtime(void); - -/* - * Set output format to 'restricted pax' format. - * - * This is the same as normal 'pax', but tries to suppress - * the pax header whenever possible. This is the default for - * bsdtar, for instance. - */ -int -archive_write_set_format_pax_restricted(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - int r; - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_set_format_pax_restricted"); - - r = archive_write_set_format_pax(&a->archive); - a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED; - a->archive.archive_format_name = "restricted POSIX pax interchange"; - return (r); -} - -/* - * Set output format to 'pax' format. - */ -int -archive_write_set_format_pax(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - struct pax *pax; - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_set_format_pax"); - - if (a->format_free != NULL) - (a->format_free)(a); - - pax = (struct pax *)calloc(1, sizeof(*pax)); - if (pax == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate pax data"); - return (ARCHIVE_FATAL); - } - pax->flags = WRITE_LIBARCHIVE_XATTR | WRITE_SCHILY_XATTR; - - a->format_data = pax; - a->format_name = "pax"; - a->format_options = archive_write_pax_options; - a->format_write_header = archive_write_pax_header; - a->format_write_data = archive_write_pax_data; - a->format_close = archive_write_pax_close; - a->format_free = archive_write_pax_free; - a->format_finish_entry = archive_write_pax_finish_entry; - a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE; - a->archive.archive_format_name = "POSIX pax interchange"; - return (ARCHIVE_OK); -} - -static int -archive_write_pax_options(struct archive_write *a, const char *key, - const char *val) -{ - struct pax *pax = (struct pax *)a->format_data; - int ret = ARCHIVE_FAILED; - - if (strcmp(key, "hdrcharset") == 0) { - /* - * The character-set we can use are defined in - * IEEE Std 1003.1-2001 - */ - if (val == NULL || val[0] == 0) - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "pax: hdrcharset option needs a character-set name"); - else if (strcmp(val, "BINARY") == 0 || - strcmp(val, "binary") == 0) { - /* - * Specify binary mode. We will not convert - * filenames, uname and gname to any charsets. - */ - pax->opt_binary = 1; - ret = ARCHIVE_OK; - } else if (strcmp(val, "UTF-8") == 0) { - /* - * Specify UTF-8 character-set to be used for - * filenames. This is almost the test that - * running platform supports the string conversion. - * Especially libarchive_test needs this trick for - * its test. - */ - pax->sconv_utf8 = archive_string_conversion_to_charset( - &(a->archive), "UTF-8", 0); - if (pax->sconv_utf8 == NULL) - ret = ARCHIVE_FATAL; - else - ret = ARCHIVE_OK; - } else - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "pax: invalid charset name"); - return (ret); - } else if (strcmp(key, "xattrheader") == 0) { - if (val == NULL || val[0] == 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "pax: xattrheader requires a value"); - } else if (strcmp(val, "ALL") == 0 || - strcmp(val, "all") == 0) { - pax->flags |= WRITE_LIBARCHIVE_XATTR | WRITE_SCHILY_XATTR; - ret = ARCHIVE_OK; - } else if (strcmp(val, "SCHILY") == 0 || - strcmp(val, "schily") == 0) { - pax->flags |= WRITE_SCHILY_XATTR; - pax->flags &= ~WRITE_LIBARCHIVE_XATTR; - ret = ARCHIVE_OK; - } else if (strcmp(val, "LIBARCHIVE") == 0 || - strcmp(val, "libarchive") == 0) { - pax->flags |= WRITE_LIBARCHIVE_XATTR; - pax->flags &= ~WRITE_SCHILY_XATTR; - ret = ARCHIVE_OK; - } else - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "pax: invalid xattr header name"); - return (ret); - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -/* - * Note: This code assumes that 'nanos' has the same sign as 'sec', - * which implies that sec=-1, nanos=200000000 represents -1.2 seconds - * and not -0.8 seconds. This is a pretty pedantic point, as we're - * unlikely to encounter many real files created before Jan 1, 1970, - * much less ones with timestamps recorded to sub-second resolution. - */ -static void -add_pax_attr_time(struct archive_string *as, const char *key, - int64_t sec, unsigned long nanos) -{ - int digit, i; - char *t; - /* - * Note that each byte contributes fewer than 3 base-10 - * digits, so this will always be big enough. - */ - char tmp[1 + 3*sizeof(sec) + 1 + 3*sizeof(nanos)]; - - tmp[sizeof(tmp) - 1] = 0; - t = tmp + sizeof(tmp) - 1; - - /* Skip trailing zeros in the fractional part. */ - for (digit = 0, i = 10; i > 0 && digit == 0; i--) { - digit = nanos % 10; - nanos /= 10; - } - - /* Only format the fraction if it's non-zero. */ - if (i > 0) { - while (i > 0) { - *--t = "0123456789"[digit]; - digit = nanos % 10; - nanos /= 10; - i--; - } - *--t = '.'; - } - t = format_int(t, sec); - - add_pax_attr(as, key, t); -} - -static char * -format_int(char *t, int64_t i) -{ - uint64_t ui; - - if (i < 0) - ui = (i == INT64_MIN) ? (uint64_t)(INT64_MAX) + 1 : (uint64_t)(-i); - else - ui = i; - - do { - *--t = "0123456789"[ui % 10]; - } while (ui /= 10); - if (i < 0) - *--t = '-'; - return (t); -} - -static void -add_pax_attr_int(struct archive_string *as, const char *key, int64_t value) -{ - char tmp[1 + 3 * sizeof(value)]; - - tmp[sizeof(tmp) - 1] = 0; - add_pax_attr(as, key, format_int(tmp + sizeof(tmp) - 1, value)); -} - -/* - * Add a key/value attribute to the pax header. This function handles - * the length field and various other syntactic requirements. - */ -static void -add_pax_attr(struct archive_string *as, const char *key, const char *value) -{ - add_pax_attr_binary(as, key, value, strlen(value)); -} - -/* - * Add a key/value attribute to the pax header. This function handles - * binary values. - */ -static void -add_pax_attr_binary(struct archive_string *as, const char *key, - const char *value, size_t value_len) -{ - int digits, i, len, next_ten; - char tmp[1 + 3 * sizeof(int)]; /* < 3 base-10 digits per byte */ - - /*- - * PAX attributes have the following layout: - * <=> - */ - len = 1 + (int)strlen(key) + 1 + (int)value_len + 1; - - /* - * The field includes the length of the field, so - * computing the correct length is tricky. I start by - * counting the number of base-10 digits in 'len' and - * computing the next higher power of 10. - */ - next_ten = 1; - digits = 0; - i = len; - while (i > 0) { - i = i / 10; - digits++; - next_ten = next_ten * 10; - } - /* - * For example, if string without the length field is 99 - * chars, then adding the 2 digit length "99" will force the - * total length past 100, requiring an extra digit. The next - * statement adjusts for this effect. - */ - if (len + digits >= next_ten) - digits++; - - /* Now, we have the right length so we can build the line. */ - tmp[sizeof(tmp) - 1] = 0; /* Null-terminate the work area. */ - archive_strcat(as, format_int(tmp + sizeof(tmp) - 1, len + digits)); - archive_strappend_char(as, ' '); - archive_strcat(as, key); - archive_strappend_char(as, '='); - archive_array_append(as, value, value_len); - archive_strappend_char(as, '\n'); -} - -static void -archive_write_pax_header_xattr(struct pax *pax, const char *encoded_name, - const void *value, size_t value_len) -{ - struct archive_string s; - char *encoded_value; - - if (encoded_name == NULL) - return; - - if (pax->flags & WRITE_LIBARCHIVE_XATTR) { - encoded_value = base64_encode((const char *)value, value_len); - if (encoded_value != NULL) { - archive_string_init(&s); - archive_strcpy(&s, "LIBARCHIVE.xattr."); - archive_strcat(&s, encoded_name); - add_pax_attr(&(pax->pax_header), s.s, encoded_value); - archive_string_free(&s); - } - free(encoded_value); - } - if (pax->flags & WRITE_SCHILY_XATTR) { - archive_string_init(&s); - archive_strcpy(&s, "SCHILY.xattr."); - archive_strcat(&s, encoded_name); - add_pax_attr_binary(&(pax->pax_header), s.s, value, value_len); - archive_string_free(&s); - } -} - -static int -archive_write_pax_header_xattrs(struct archive_write *a, - struct pax *pax, struct archive_entry *entry) -{ - int i = archive_entry_xattr_reset(entry); - - while (i--) { - const char *name; - const void *value; - char *url_encoded_name = NULL, *encoded_name = NULL; - size_t size; - int r; - - archive_entry_xattr_next(entry, &name, &value, &size); - url_encoded_name = url_encode(name); - if (url_encoded_name == NULL) - goto malloc_error; - else { - /* Convert narrow-character to UTF-8. */ - r = archive_strcpy_l(&(pax->l_url_encoded_name), - url_encoded_name, pax->sconv_utf8); - free(url_encoded_name); /* Done with this. */ - if (r == 0) - encoded_name = pax->l_url_encoded_name.s; - else if (r == -1) - goto malloc_error; - else { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Error encoding pax extended attribute"); - return (ARCHIVE_FAILED); - } - } - - archive_write_pax_header_xattr(pax, encoded_name, - value, size); - - } - return (ARCHIVE_OK); -malloc_error: - archive_set_error(&a->archive, ENOMEM, "Can't allocate memory"); - return (ARCHIVE_FATAL); -} - -static int -get_entry_hardlink(struct archive_write *a, struct archive_entry *entry, - const char **name, size_t *length, struct archive_string_conv *sc) -{ - int r; - - r = archive_entry_hardlink_l(entry, name, length, sc); - if (r != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Linkname"); - return (ARCHIVE_FATAL); - } - return (ARCHIVE_WARN); - } - return (ARCHIVE_OK); -} - -static int -get_entry_pathname(struct archive_write *a, struct archive_entry *entry, - const char **name, size_t *length, struct archive_string_conv *sc) -{ - int r; - - r = archive_entry_pathname_l(entry, name, length, sc); - if (r != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Pathname"); - return (ARCHIVE_FATAL); - } - return (ARCHIVE_WARN); - } - return (ARCHIVE_OK); -} - -static int -get_entry_uname(struct archive_write *a, struct archive_entry *entry, - const char **name, size_t *length, struct archive_string_conv *sc) -{ - int r; - - r = archive_entry_uname_l(entry, name, length, sc); - if (r != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Uname"); - return (ARCHIVE_FATAL); - } - return (ARCHIVE_WARN); - } - return (ARCHIVE_OK); -} - -static int -get_entry_gname(struct archive_write *a, struct archive_entry *entry, - const char **name, size_t *length, struct archive_string_conv *sc) -{ - int r; - - r = archive_entry_gname_l(entry, name, length, sc); - if (r != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Gname"); - return (ARCHIVE_FATAL); - } - return (ARCHIVE_WARN); - } - return (ARCHIVE_OK); -} - -static int -get_entry_symlink(struct archive_write *a, struct archive_entry *entry, - const char **name, size_t *length, struct archive_string_conv *sc) -{ - int r; - - r = archive_entry_symlink_l(entry, name, length, sc); - if (r != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Linkname"); - return (ARCHIVE_FATAL); - } - return (ARCHIVE_WARN); - } - return (ARCHIVE_OK); -} - -/* Add ACL to pax header */ -static int -add_pax_acl(struct archive_write *a, - struct archive_entry *entry, struct pax *pax, int flags) -{ - char *p; - const char *attr; - int acl_types; - - acl_types = archive_entry_acl_types(entry); - - if ((acl_types & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) - attr = "SCHILY.acl.ace"; - else if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) - attr = "SCHILY.acl.access"; - else if ((flags & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0) - attr = "SCHILY.acl.default"; - else - return (ARCHIVE_FATAL); - - p = archive_entry_acl_to_text_l(entry, NULL, flags, pax->sconv_utf8); - if (p == NULL) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, "%s %s", - "Can't allocate memory for ", attr); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, "%s %s %s", - "Can't translate ", attr, " to UTF-8"); - return(ARCHIVE_WARN); - } - - if (*p != '\0') { - add_pax_attr(&(pax->pax_header), - attr, p); - } - free(p); - return(ARCHIVE_OK); -} - -/* - * TODO: Consider adding 'comment' and 'charset' fields to - * archive_entry so that clients can specify them. Also, consider - * adding generic key/value tags so clients can add arbitrary - * key/value data. - * - * TODO: Break up this 700-line function!!!! Yowza! - */ -static int -archive_write_pax_header(struct archive_write *a, - struct archive_entry *entry_original) -{ - struct archive_entry *entry_main; - const char *p; - const char *suffix; - int need_extension, r, ret; - int acl_types; - int sparse_count; - uint64_t sparse_total, real_size; - struct pax *pax; - const char *hardlink; - const char *path = NULL, *linkpath = NULL; - const char *uname = NULL, *gname = NULL; - const void *mac_metadata; - size_t mac_metadata_size; - struct archive_string_conv *sconv; - size_t hardlink_length, path_length, linkpath_length; - size_t uname_length, gname_length; - - char paxbuff[512]; - char ustarbuff[512]; - char ustar_entry_name[256]; - char pax_entry_name[256]; - char gnu_sparse_name[256]; - struct archive_string entry_name; - - ret = ARCHIVE_OK; - need_extension = 0; - pax = (struct pax *)a->format_data; - - const time_t ustar_max_mtime = get_ustar_max_mtime(); - - /* Sanity check. */ - if (archive_entry_pathname(entry_original) == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Can't record entry in tar file without pathname"); - return (ARCHIVE_FAILED); - } - - /* - * Choose a header encoding. - */ - if (pax->opt_binary) - sconv = NULL;/* Binary mode. */ - else { - /* Header encoding is UTF-8. */ - if (pax->sconv_utf8 == NULL) { - /* Initialize the string conversion object - * we must need */ - pax->sconv_utf8 = archive_string_conversion_to_charset( - &(a->archive), "UTF-8", 1); - if (pax->sconv_utf8 == NULL) - /* Couldn't allocate memory */ - return (ARCHIVE_FAILED); - } - sconv = pax->sconv_utf8; - } - - r = get_entry_hardlink(a, entry_original, &hardlink, - &hardlink_length, sconv); - if (r == ARCHIVE_FATAL) - return (r); - else if (r != ARCHIVE_OK) { - r = get_entry_hardlink(a, entry_original, &hardlink, - &hardlink_length, NULL); - if (r == ARCHIVE_FATAL) - return (r); - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate linkname '%s' to %s", hardlink, - archive_string_conversion_charset_name(sconv)); - ret = ARCHIVE_WARN; - sconv = NULL;/* The header charset switches to binary mode. */ - } - - /* Make sure this is a type of entry that we can handle here */ - if (hardlink == NULL) { - switch (archive_entry_filetype(entry_original)) { - case AE_IFBLK: - case AE_IFCHR: - case AE_IFIFO: - case AE_IFLNK: - case AE_IFREG: - break; - case AE_IFDIR: - { - /* - * Ensure a trailing '/'. Modify the original - * entry so the client sees the change. - */ -#if defined(_WIN32) && !defined(__CYGWIN__) - const wchar_t *wp; - - wp = archive_entry_pathname_w(entry_original); - if (wp != NULL && wp[wcslen(wp) -1] != L'/') { - struct archive_wstring ws; - - archive_string_init(&ws); - path_length = wcslen(wp); - if (archive_wstring_ensure(&ws, - path_length + 2) == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate pax data"); - archive_wstring_free(&ws); - return(ARCHIVE_FATAL); - } - /* Should we keep '\' ? */ - if (wp[path_length -1] == L'\\') - path_length--; - archive_wstrncpy(&ws, wp, path_length); - archive_wstrappend_wchar(&ws, L'/'); - archive_entry_copy_pathname_w( - entry_original, ws.s); - archive_wstring_free(&ws); - p = NULL; - } else -#endif - p = archive_entry_pathname(entry_original); - /* - * On Windows, this is a backup operation just in - * case getting WCS failed. On POSIX, this is a - * normal operation. - */ - if (p != NULL && p[0] != '\0' && p[strlen(p) - 1] != '/') { - struct archive_string as; - - archive_string_init(&as); - path_length = strlen(p); - if (archive_string_ensure(&as, - path_length + 2) == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate pax data"); - archive_string_free(&as); - return(ARCHIVE_FATAL); - } -#if defined(_WIN32) && !defined(__CYGWIN__) - /* NOTE: This might break the pathname - * if the current code page is CP932 and - * the pathname includes a character '\' - * as a part of its multibyte pathname. */ - if (p[strlen(p) -1] == '\\') - path_length--; - else -#endif - archive_strncpy(&as, p, path_length); - archive_strappend_char(&as, '/'); - archive_entry_copy_pathname( - entry_original, as.s); - archive_string_free(&as); - } - break; - } - default: /* AE_IFSOCK and unknown */ - __archive_write_entry_filetype_unsupported( - &a->archive, entry_original, "pax"); - return (ARCHIVE_FAILED); - } - } - - /* - * If Mac OS metadata blob is here, recurse to write that - * as a separate entry. This is really a pretty poor design: - * In particular, it doubles the overhead for long filenames. - * TODO: Help Apple folks design something better and figure - * out how to transition from this legacy format. - * - * Note that this code is present on every platform; clients - * on non-Mac are unlikely to ever provide this data, but - * applications that copy entries from one archive to another - * should not lose data just because the local filesystem - * can't store it. - */ - mac_metadata = - archive_entry_mac_metadata(entry_original, &mac_metadata_size); - if (mac_metadata != NULL) { - const char *oname; - char *name, *bname; - size_t name_length; - struct archive_entry *extra = archive_entry_new2(&a->archive); - - oname = archive_entry_pathname(entry_original); - name_length = strlen(oname); - name = malloc(name_length + 3); - if (name == NULL || extra == NULL) { - /* XXX error message */ - archive_entry_free(extra); - free(name); - return (ARCHIVE_FAILED); - } - strcpy(name, oname); - /* Find last '/'; strip trailing '/' characters */ - bname = strrchr(name, '/'); - while (bname != NULL && bname[1] == '\0') { - *bname = '\0'; - bname = strrchr(name, '/'); - } - if (bname == NULL) { - memmove(name + 2, name, name_length + 1); - memmove(name, "._", 2); - } else { - bname += 1; - memmove(bname + 2, bname, strlen(bname) + 1); - memmove(bname, "._", 2); - } - archive_entry_copy_pathname(extra, name); - free(name); - - archive_entry_set_size(extra, mac_metadata_size); - archive_entry_set_filetype(extra, AE_IFREG); - archive_entry_set_perm(extra, - archive_entry_perm(entry_original)); - archive_entry_set_mtime(extra, - archive_entry_mtime(entry_original), - archive_entry_mtime_nsec(entry_original)); - archive_entry_set_gid(extra, - archive_entry_gid(entry_original)); - archive_entry_set_gname(extra, - archive_entry_gname(entry_original)); - archive_entry_set_uid(extra, - archive_entry_uid(entry_original)); - archive_entry_set_uname(extra, - archive_entry_uname(entry_original)); - - /* Recurse to write the special copyfile entry. */ - r = archive_write_pax_header(a, extra); - archive_entry_free(extra); - if (r < ARCHIVE_WARN) - return (r); - if (r < ret) - ret = r; - r = (int)archive_write_pax_data(a, mac_metadata, - mac_metadata_size); - if (r < ARCHIVE_WARN) - return (r); - if (r < ret) - ret = r; - r = archive_write_pax_finish_entry(a); - if (r < ARCHIVE_WARN) - return (r); - if (r < ret) - ret = r; - } - - /* Copy entry so we can modify it as needed. */ -#if defined(_WIN32) && !defined(__CYGWIN__) - /* Make sure the path separators in pathname, hardlink and symlink - * are all slash '/', not the Windows path separator '\'. */ - entry_main = __la_win_entry_in_posix_pathseparator(entry_original); - if (entry_main == entry_original) - entry_main = archive_entry_clone(entry_original); -#else - entry_main = archive_entry_clone(entry_original); -#endif - if (entry_main == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate pax data"); - return(ARCHIVE_FATAL); - } - archive_string_empty(&(pax->pax_header)); /* Blank our work area. */ - archive_string_empty(&(pax->sparse_map)); - sparse_total = 0; - sparse_list_clear(pax); - - if (hardlink == NULL && - archive_entry_filetype(entry_main) == AE_IFREG) - sparse_count = archive_entry_sparse_reset(entry_main); - else - sparse_count = 0; - if (sparse_count) { - int64_t offset, length, last_offset = 0; - /* Get the last entry of sparse block. */ - while (archive_entry_sparse_next( - entry_main, &offset, &length) == ARCHIVE_OK) - last_offset = offset + length; - - /* If the last sparse block does not reach the end of file, - * We have to add a empty sparse block as the last entry to - * manage storing file data. */ - if (last_offset < archive_entry_size(entry_main)) - archive_entry_sparse_add_entry(entry_main, - archive_entry_size(entry_main), 0); - sparse_count = archive_entry_sparse_reset(entry_main); - } - - /* - * First, check the name fields and see if any of them - * require binary coding. If any of them does, then all of - * them do. - */ - r = get_entry_pathname(a, entry_main, &path, &path_length, sconv); - if (r == ARCHIVE_FATAL) { - archive_entry_free(entry_main); - return (r); - } else if (r != ARCHIVE_OK) { - r = get_entry_pathname(a, entry_main, &path, - &path_length, NULL); - if (r == ARCHIVE_FATAL) { - archive_entry_free(entry_main); - return (r); - } - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate pathname '%s' to %s", path, - archive_string_conversion_charset_name(sconv)); - ret = ARCHIVE_WARN; - sconv = NULL;/* The header charset switches to binary mode. */ - } - r = get_entry_uname(a, entry_main, &uname, &uname_length, sconv); - if (r == ARCHIVE_FATAL) { - archive_entry_free(entry_main); - return (r); - } else if (r != ARCHIVE_OK) { - r = get_entry_uname(a, entry_main, &uname, &uname_length, NULL); - if (r == ARCHIVE_FATAL) { - archive_entry_free(entry_main); - return (r); - } - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate uname '%s' to %s", uname, - archive_string_conversion_charset_name(sconv)); - ret = ARCHIVE_WARN; - sconv = NULL;/* The header charset switches to binary mode. */ - } - r = get_entry_gname(a, entry_main, &gname, &gname_length, sconv); - if (r == ARCHIVE_FATAL) { - archive_entry_free(entry_main); - return (r); - } else if (r != ARCHIVE_OK) { - r = get_entry_gname(a, entry_main, &gname, &gname_length, NULL); - if (r == ARCHIVE_FATAL) { - archive_entry_free(entry_main); - return (r); - } - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate gname '%s' to %s", gname, - archive_string_conversion_charset_name(sconv)); - ret = ARCHIVE_WARN; - sconv = NULL;/* The header charset switches to binary mode. */ - } - linkpath = hardlink; - linkpath_length = hardlink_length; - if (linkpath == NULL) { - r = get_entry_symlink(a, entry_main, &linkpath, - &linkpath_length, sconv); - if (r == ARCHIVE_FATAL) { - archive_entry_free(entry_main); - return (r); - } else if (r != ARCHIVE_OK) { - r = get_entry_symlink(a, entry_main, &linkpath, - &linkpath_length, NULL); - if (r == ARCHIVE_FATAL) { - archive_entry_free(entry_main); - return (r); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate linkname '%s' to %s", linkpath, - archive_string_conversion_charset_name(sconv)); - ret = ARCHIVE_WARN; - sconv = NULL; - } - } - - /* If any string conversions failed, get all attributes - * in binary-mode. */ - if (sconv == NULL && !pax->opt_binary) { - if (hardlink != NULL) { - r = get_entry_hardlink(a, entry_main, &hardlink, - &hardlink_length, NULL); - if (r == ARCHIVE_FATAL) { - archive_entry_free(entry_main); - return (r); - } - linkpath = hardlink; - linkpath_length = hardlink_length; - } - r = get_entry_pathname(a, entry_main, &path, - &path_length, NULL); - if (r == ARCHIVE_FATAL) { - archive_entry_free(entry_main); - return (r); - } - r = get_entry_uname(a, entry_main, &uname, &uname_length, NULL); - if (r == ARCHIVE_FATAL) { - archive_entry_free(entry_main); - return (r); - } - r = get_entry_gname(a, entry_main, &gname, &gname_length, NULL); - if (r == ARCHIVE_FATAL) { - archive_entry_free(entry_main); - return (r); - } - } - - /* Store the header encoding first, to be nice to readers. */ - if (sconv == NULL) - add_pax_attr(&(pax->pax_header), "hdrcharset", "BINARY"); - - - /* - * If name is too long, or has non-ASCII characters, add - * 'path' to pax extended attrs. (Note that an unconvertible - * name must have non-ASCII characters.) - */ - if (has_non_ASCII(path)) { - /* We have non-ASCII characters. */ - add_pax_attr(&(pax->pax_header), "path", path); - archive_entry_set_pathname(entry_main, - build_ustar_entry_name(ustar_entry_name, - path, path_length, NULL)); - need_extension = 1; - } else { - /* We have an all-ASCII path; we'd like to just store - * it in the ustar header if it will fit. Yes, this - * duplicates some of the logic in - * archive_write_set_format_ustar.c - */ - if (path_length <= 100) { - /* Fits in the old 100-char tar name field. */ - } else { - /* Find largest suffix that will fit. */ - /* Note: strlen() > 100, so strlen() - 100 - 1 >= 0 */ - suffix = strchr(path + path_length - 100 - 1, '/'); - /* Don't attempt an empty prefix. */ - if (suffix == path) - suffix = strchr(suffix + 1, '/'); - /* We can put it in the ustar header if it's - * all ASCII and it's either <= 100 characters - * or can be split at a '/' into a prefix <= - * 155 chars and a suffix <= 100 chars. (Note - * the strchr() above will return NULL exactly - * when the path can't be split.) - */ - if (suffix == NULL /* Suffix > 100 chars. */ - || suffix[1] == '\0' /* empty suffix */ - || suffix - path > 155) /* Prefix > 155 chars */ - { - add_pax_attr(&(pax->pax_header), "path", path); - archive_entry_set_pathname(entry_main, - build_ustar_entry_name(ustar_entry_name, - path, path_length, NULL)); - need_extension = 1; - } - } - } - - if (linkpath != NULL) { - /* If link name is too long or has non-ASCII characters, add - * 'linkpath' to pax extended attrs. */ - if (linkpath_length > 100 || has_non_ASCII(linkpath)) { - add_pax_attr(&(pax->pax_header), "linkpath", linkpath); - if (linkpath_length > 100) { - if (hardlink != NULL) - archive_entry_set_hardlink(entry_main, - "././@LongHardLink"); - else - archive_entry_set_symlink(entry_main, - "././@LongSymLink"); - } - need_extension = 1; - } - } - /* Save a pathname since it will be renamed if `entry_main` has - * sparse blocks. */ - archive_string_init(&entry_name); - archive_strcpy(&entry_name, archive_entry_pathname(entry_main)); - - /* If file size is too large, we need pax extended attrs. */ - if (archive_entry_size(entry_main) >= (((int64_t)1) << 33)) { - need_extension = 1; - } - - /* If numeric GID is too large, add 'gid' to pax extended attrs. */ - if ((unsigned int)archive_entry_gid(entry_main) >= (1 << 18)) { - add_pax_attr_int(&(pax->pax_header), "gid", - archive_entry_gid(entry_main)); - need_extension = 1; - } - - /* If group name is too large or has non-ASCII characters, add - * 'gname' to pax extended attrs. */ - if (gname != NULL) { - if (gname_length > 31 || has_non_ASCII(gname)) { - add_pax_attr(&(pax->pax_header), "gname", gname); - need_extension = 1; - } - } - - /* If numeric UID is too large, add 'uid' to pax extended attrs. */ - if ((unsigned int)archive_entry_uid(entry_main) >= (1 << 18)) { - add_pax_attr_int(&(pax->pax_header), "uid", - archive_entry_uid(entry_main)); - need_extension = 1; - } - - /* Add 'uname' to pax extended attrs if necessary. */ - if (uname != NULL) { - if (uname_length > 31 || has_non_ASCII(uname)) { - add_pax_attr(&(pax->pax_header), "uname", uname); - need_extension = 1; - } - } - - /* - * POSIX/SUSv3 doesn't provide a standard key for large device - * numbers. I use the same keys here that Joerg Schilling - * used for 'star.' (Which, somewhat confusingly, are called - * "devXXX" even though they code "rdev" values.) No doubt, - * other implementations use other keys. Note that there's no - * reason we can't write the same information into a number of - * different keys. - * - * Of course, this is only needed for block or char device entries. - */ - if (archive_entry_filetype(entry_main) == AE_IFBLK - || archive_entry_filetype(entry_main) == AE_IFCHR) { - /* - * If rdevmajor is too large, add 'SCHILY.devmajor' to - * extended attributes. - */ - int rdevmajor, rdevminor; - rdevmajor = archive_entry_rdevmajor(entry_main); - rdevminor = archive_entry_rdevminor(entry_main); - if (rdevmajor >= (1 << 18)) { - add_pax_attr_int(&(pax->pax_header), "SCHILY.devmajor", - rdevmajor); - /* - * Non-strict formatting below means we don't - * have to truncate here. Not truncating improves - * the chance that some more modern tar archivers - * (such as GNU tar 1.13) can restore the full - * value even if they don't understand the pax - * extended attributes. See my rant below about - * file size fields for additional details. - */ - /* archive_entry_set_rdevmajor(entry_main, - rdevmajor & ((1 << 18) - 1)); */ - need_extension = 1; - } - - /* - * If devminor is too large, add 'SCHILY.devminor' to - * extended attributes. - */ - if (rdevminor >= (1 << 18)) { - add_pax_attr_int(&(pax->pax_header), "SCHILY.devminor", - rdevminor); - /* Truncation is not necessary here, either. */ - /* archive_entry_set_rdevminor(entry_main, - rdevminor & ((1 << 18) - 1)); */ - need_extension = 1; - } - } - - /* - * Yes, this check is duplicated just below; this helps to - * avoid writing an mtime attribute just to handle a - * high-resolution timestamp in "restricted pax" mode. - */ - if (!need_extension && - ((archive_entry_mtime(entry_main) < 0) - || (archive_entry_mtime(entry_main) >= ustar_max_mtime))) - need_extension = 1; - - /* I use a star-compatible file flag attribute. */ - p = archive_entry_fflags_text(entry_main); - if (!need_extension && p != NULL && *p != '\0') - need_extension = 1; - - /* If there are extended attributes, we need an extension */ - if (!need_extension && archive_entry_xattr_count(entry_original) > 0) - need_extension = 1; - - /* If there are sparse info, we need an extension */ - if (!need_extension && sparse_count > 0) - need_extension = 1; - - acl_types = archive_entry_acl_types(entry_original); - - /* If there are any ACL entries, we need an extension */ - if (!need_extension && acl_types != 0) - need_extension = 1; - - /* If the symlink type is defined, we need an extension */ - if (!need_extension && archive_entry_symlink_type(entry_main) > 0) - need_extension = 1; - - /* - * Libarchive used to include these in extended headers for - * restricted pax format, but that confused people who - * expected ustar-like time semantics. So now we only include - * them in full pax format. - */ - if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_RESTRICTED) { - if (archive_entry_ctime(entry_main) != 0 || - archive_entry_ctime_nsec(entry_main) != 0) - add_pax_attr_time(&(pax->pax_header), "ctime", - archive_entry_ctime(entry_main), - archive_entry_ctime_nsec(entry_main)); - - if (archive_entry_atime(entry_main) != 0 || - archive_entry_atime_nsec(entry_main) != 0) - add_pax_attr_time(&(pax->pax_header), "atime", - archive_entry_atime(entry_main), - archive_entry_atime_nsec(entry_main)); - - /* Store birth/creationtime only if it's earlier than mtime */ - if (archive_entry_birthtime_is_set(entry_main) && - archive_entry_birthtime(entry_main) - < archive_entry_mtime(entry_main)) - add_pax_attr_time(&(pax->pax_header), - "LIBARCHIVE.creationtime", - archive_entry_birthtime(entry_main), - archive_entry_birthtime_nsec(entry_main)); - } - - /* - * The following items are handled differently in "pax - * restricted" format. In particular, in "pax restricted" - * format they won't be added unless need_extension is - * already set (we're already generating an extended header, so - * may as well include these). - */ - if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_RESTRICTED || - need_extension) { - if (archive_entry_mtime(entry_main) < 0 || - archive_entry_mtime(entry_main) >= ustar_max_mtime || - archive_entry_mtime_nsec(entry_main) != 0) - add_pax_attr_time(&(pax->pax_header), "mtime", - archive_entry_mtime(entry_main), - archive_entry_mtime_nsec(entry_main)); - - /* I use a star-compatible file flag attribute. */ - p = archive_entry_fflags_text(entry_main); - if (p != NULL && *p != '\0') - add_pax_attr(&(pax->pax_header), "SCHILY.fflags", p); - - /* I use star-compatible ACL attributes. */ - if ((acl_types & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) { - ret = add_pax_acl(a, entry_original, pax, - ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID | - ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA | - ARCHIVE_ENTRY_ACL_STYLE_COMPACT); - if (ret == ARCHIVE_FATAL) { - archive_entry_free(entry_main); - archive_string_free(&entry_name); - return (ARCHIVE_FATAL); - } - } - if (acl_types & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) { - ret = add_pax_acl(a, entry_original, pax, - ARCHIVE_ENTRY_ACL_TYPE_ACCESS | - ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID | - ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA); - if (ret == ARCHIVE_FATAL) { - archive_entry_free(entry_main); - archive_string_free(&entry_name); - return (ARCHIVE_FATAL); - } - } - if (acl_types & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) { - ret = add_pax_acl(a, entry_original, pax, - ARCHIVE_ENTRY_ACL_TYPE_DEFAULT | - ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID | - ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA); - if (ret == ARCHIVE_FATAL) { - archive_entry_free(entry_main); - archive_string_free(&entry_name); - return (ARCHIVE_FATAL); - } - } - - /* We use GNU-tar-compatible sparse attributes. */ - if (sparse_count > 0) { - int64_t soffset, slength; - - add_pax_attr_int(&(pax->pax_header), - "GNU.sparse.major", 1); - add_pax_attr_int(&(pax->pax_header), - "GNU.sparse.minor", 0); - /* - * Make sure to store the original path, since - * truncation to ustar limit happened already. - */ - add_pax_attr(&(pax->pax_header), - "GNU.sparse.name", path); - add_pax_attr_int(&(pax->pax_header), - "GNU.sparse.realsize", - archive_entry_size(entry_main)); - - /* Rename the file name which will be used for - * ustar header to a special name, which GNU - * PAX Format 1.0 requires */ - archive_entry_set_pathname(entry_main, - build_gnu_sparse_name(gnu_sparse_name, - entry_name.s)); - - /* - * - Make a sparse map, which will precede a file data. - * - Get the total size of available data of sparse. - */ - archive_string_sprintf(&(pax->sparse_map), "%d\n", - sparse_count); - while (archive_entry_sparse_next(entry_main, - &soffset, &slength) == ARCHIVE_OK) { - archive_string_sprintf(&(pax->sparse_map), - "%jd\n%jd\n", - (intmax_t)soffset, - (intmax_t)slength); - sparse_total += slength; - if (sparse_list_add(pax, soffset, slength) - != ARCHIVE_OK) { - archive_set_error(&a->archive, - ENOMEM, - "Can't allocate memory"); - archive_entry_free(entry_main); - archive_string_free(&entry_name); - return (ARCHIVE_FATAL); - } - } - } - - /* Store extended attributes */ - if (archive_write_pax_header_xattrs(a, pax, entry_original) - == ARCHIVE_FATAL) { - archive_entry_free(entry_main); - archive_string_free(&entry_name); - return (ARCHIVE_FATAL); - } - - /* Store extended symlink information */ - if (archive_entry_symlink_type(entry_main) == - AE_SYMLINK_TYPE_FILE) { - add_pax_attr(&(pax->pax_header), - "LIBARCHIVE.symlinktype", "file"); - } else if (archive_entry_symlink_type(entry_main) == - AE_SYMLINK_TYPE_DIRECTORY) { - add_pax_attr(&(pax->pax_header), - "LIBARCHIVE.symlinktype", "dir"); - } - } - - /* Only regular files have data. */ - if (archive_entry_filetype(entry_main) != AE_IFREG) - archive_entry_set_size(entry_main, 0); - - /* - * Pax-restricted does not store data for hardlinks, in order - * to improve compatibility with ustar. - */ - if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE && - hardlink != NULL) - archive_entry_set_size(entry_main, 0); - - /* - * XXX Full pax interchange format does permit a hardlink - * entry to have data associated with it. I'm not supporting - * that here because the client expects me to tell them whether - * or not this format expects data for hardlinks. If I - * don't check here, then every pax archive will end up with - * duplicated data for hardlinks. Someday, there may be - * need to select this behavior, in which case the following - * will need to be revisited. XXX - */ - if (hardlink != NULL) - archive_entry_set_size(entry_main, 0); - - /* Save a real file size. */ - real_size = archive_entry_size(entry_main); - /* - * Overwrite a file size by the total size of sparse blocks and - * the size of sparse map info. That file size is the length of - * the data, which we will exactly store into an archive file. - */ - if (archive_strlen(&(pax->sparse_map))) { - size_t mapsize = archive_strlen(&(pax->sparse_map)); - pax->sparse_map_padding = 0x1ff & (-(ssize_t)mapsize); - archive_entry_set_size(entry_main, - mapsize + pax->sparse_map_padding + sparse_total); - } - - /* If file size is too large, add 'size' to pax extended attrs. */ - if (archive_entry_size(entry_main) >= (((int64_t)1) << 33)) { - add_pax_attr_int(&(pax->pax_header), "size", - archive_entry_size(entry_main)); - } - - /* Format 'ustar' header for main entry. - * - * The trouble with file size: If the reader can't understand - * the file size, they may not be able to locate the next - * entry and the rest of the archive is toast. Pax-compliant - * readers are supposed to ignore the file size in the main - * header, so the question becomes how to maximize portability - * for readers that don't support pax attribute extensions. - * For maximum compatibility, I permit numeric extensions in - * the main header so that the file size stored will always be - * correct, even if it's in a format that only some - * implementations understand. The technique used here is: - * - * a) If possible, follow the standard exactly. This handles - * files up to 8 gigabytes minus 1. - * - * b) If that fails, try octal but omit the field terminator. - * That handles files up to 64 gigabytes minus 1. - * - * c) Otherwise, use base-256 extensions. That handles files - * up to 2^63 in this implementation, with the potential to - * go up to 2^94. That should hold us for a while. ;-) - * - * The non-strict formatter uses similar logic for other - * numeric fields, though they're less critical. - */ - if (__archive_write_format_header_ustar(a, ustarbuff, entry_main, -1, 0, - NULL) == ARCHIVE_FATAL) { - archive_entry_free(entry_main); - archive_string_free(&entry_name); - return (ARCHIVE_FATAL); - } - - /* If we built any extended attributes, write that entry first. */ - if (archive_strlen(&(pax->pax_header)) > 0) { - struct archive_entry *pax_attr_entry; - time_t s; - int64_t uid, gid; - int mode; - - pax_attr_entry = archive_entry_new2(&a->archive); - p = entry_name.s; - archive_entry_set_pathname(pax_attr_entry, - build_pax_attribute_name(pax_entry_name, p)); - archive_entry_set_size(pax_attr_entry, - archive_strlen(&(pax->pax_header))); - /* Copy uid/gid (but clip to ustar limits). */ - uid = archive_entry_uid(entry_main); - if (uid >= 1 << 18) - uid = (1 << 18) - 1; - archive_entry_set_uid(pax_attr_entry, uid); - gid = archive_entry_gid(entry_main); - if (gid >= 1 << 18) - gid = (1 << 18) - 1; - archive_entry_set_gid(pax_attr_entry, gid); - /* Copy mode over (but not setuid/setgid bits) */ - mode = archive_entry_mode(entry_main); -#ifdef S_ISUID - mode &= ~S_ISUID; -#endif -#ifdef S_ISGID - mode &= ~S_ISGID; -#endif -#ifdef S_ISVTX - mode &= ~S_ISVTX; -#endif - archive_entry_set_mode(pax_attr_entry, mode); - - /* Copy uname/gname. */ - archive_entry_set_uname(pax_attr_entry, - archive_entry_uname(entry_main)); - archive_entry_set_gname(pax_attr_entry, - archive_entry_gname(entry_main)); - - /* Copy mtime, but clip to ustar limits. */ - s = archive_entry_mtime(entry_main); - if (s < 0) { s = 0; } - if (s > ustar_max_mtime) { s = ustar_max_mtime; } - archive_entry_set_mtime(pax_attr_entry, s, 0); - - /* Standard ustar doesn't support atime. */ - archive_entry_set_atime(pax_attr_entry, 0, 0); - - /* Standard ustar doesn't support ctime. */ - archive_entry_set_ctime(pax_attr_entry, 0, 0); - - r = __archive_write_format_header_ustar(a, paxbuff, - pax_attr_entry, 'x', 1, NULL); - - archive_entry_free(pax_attr_entry); - - /* Note that the 'x' header shouldn't ever fail to format */ - if (r < ARCHIVE_WARN) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "archive_write_pax_header: " - "'x' header failed?! This can't happen.\n"); - archive_entry_free(entry_main); - archive_string_free(&entry_name); - return (ARCHIVE_FATAL); - } else if (r < ret) - ret = r; - r = __archive_write_output(a, paxbuff, 512); - if (r != ARCHIVE_OK) { - sparse_list_clear(pax); - pax->entry_bytes_remaining = 0; - pax->entry_padding = 0; - archive_entry_free(entry_main); - archive_string_free(&entry_name); - return (ARCHIVE_FATAL); - } - - pax->entry_bytes_remaining = archive_strlen(&(pax->pax_header)); - pax->entry_padding = - 0x1ff & (-(int64_t)pax->entry_bytes_remaining); - - r = __archive_write_output(a, pax->pax_header.s, - archive_strlen(&(pax->pax_header))); - if (r != ARCHIVE_OK) { - /* If a write fails, we're pretty much toast. */ - archive_entry_free(entry_main); - archive_string_free(&entry_name); - return (ARCHIVE_FATAL); - } - /* Pad out the end of the entry. */ - r = __archive_write_nulls(a, (size_t)pax->entry_padding); - if (r != ARCHIVE_OK) { - /* If a write fails, we're pretty much toast. */ - archive_entry_free(entry_main); - archive_string_free(&entry_name); - return (ARCHIVE_FATAL); - } - pax->entry_bytes_remaining = pax->entry_padding = 0; - } - - /* Write the header for main entry. */ - r = __archive_write_output(a, ustarbuff, 512); - if (r != ARCHIVE_OK) { - archive_entry_free(entry_main); - archive_string_free(&entry_name); - return (r); - } - - /* - * Inform the client of the on-disk size we're using, so - * they can avoid unnecessarily writing a body for something - * that we're just going to ignore. - */ - archive_entry_set_size(entry_original, real_size); - if (pax->sparse_list == NULL && real_size > 0) { - /* This is not a sparse file but we handle its data as - * a sparse block. */ - sparse_list_add(pax, 0, real_size); - sparse_total = real_size; - } - pax->entry_padding = 0x1ff & (-(int64_t)sparse_total); - archive_entry_free(entry_main); - archive_string_free(&entry_name); - - return (ret); -} - -/* - * We need a valid name for the regular 'ustar' entry. This routine - * tries to hack something more-or-less reasonable. - * - * The approach here tries to preserve leading dir names. We do so by - * working with four sections: - * 1) "prefix" directory names, - * 2) "suffix" directory names, - * 3) inserted dir name (optional), - * 4) filename. - * - * These sections must satisfy the following requirements: - * * Parts 1 & 2 together form an initial portion of the dir name. - * * Part 3 is specified by the caller. (It should not contain a leading - * or trailing '/'.) - * * Part 4 forms an initial portion of the base filename. - * * The filename must be <= 99 chars to fit the ustar 'name' field. - * * Parts 2, 3, 4 together must be <= 99 chars to fit the ustar 'name' fld. - * * Part 1 must be <= 155 chars to fit the ustar 'prefix' field. - * * If the original name ends in a '/', the new name must also end in a '/' - * * Trailing '/.' sequences may be stripped. - * - * Note: Recall that the ustar format does not store the '/' separating - * parts 1 & 2, but does store the '/' separating parts 2 & 3. - */ -static char * -build_ustar_entry_name(char *dest, const char *src, size_t src_length, - const char *insert) -{ - const char *prefix, *prefix_end; - const char *suffix, *suffix_end; - const char *filename, *filename_end; - char *p; - int need_slash = 0; /* Was there a trailing slash? */ - size_t suffix_length = 99; - size_t insert_length; - - /* Length of additional dir element to be added. */ - if (insert == NULL) - insert_length = 0; - else - /* +2 here allows for '/' before and after the insert. */ - insert_length = strlen(insert) + 2; - - /* Step 0: Quick bailout in a common case. */ - if (src_length < 100 && insert == NULL) { - strncpy(dest, src, src_length); - dest[src_length] = '\0'; - return (dest); - } - - /* Step 1: Locate filename and enforce the length restriction. */ - filename_end = src + src_length; - /* Remove trailing '/' chars and '/.' pairs. */ - for (;;) { - if (filename_end > src && filename_end[-1] == '/') { - filename_end --; - need_slash = 1; /* Remember to restore trailing '/'. */ - continue; - } - if (filename_end > src + 1 && filename_end[-1] == '.' - && filename_end[-2] == '/') { - filename_end -= 2; - need_slash = 1; /* "foo/." will become "foo/" */ - continue; - } - break; - } - if (need_slash) - suffix_length--; - /* Find start of filename. */ - filename = filename_end - 1; - while ((filename > src) && (*filename != '/')) - filename --; - if ((*filename == '/') && (filename < filename_end - 1)) - filename ++; - /* Adjust filename_end so that filename + insert fits in 99 chars. */ - suffix_length -= insert_length; - if (filename_end > filename + suffix_length) - filename_end = filename + suffix_length; - /* Calculate max size for "suffix" section (#3 above). */ - suffix_length -= filename_end - filename; - - /* Step 2: Locate the "prefix" section of the dirname, including - * trailing '/'. */ - prefix = src; - prefix_end = prefix + 155; - if (prefix_end > filename) - prefix_end = filename; - while (prefix_end > prefix && *prefix_end != '/') - prefix_end--; - if ((prefix_end < filename) && (*prefix_end == '/')) - prefix_end++; - - /* Step 3: Locate the "suffix" section of the dirname, - * including trailing '/'. */ - suffix = prefix_end; - suffix_end = suffix + suffix_length; /* Enforce limit. */ - if (suffix_end > filename) - suffix_end = filename; - if (suffix_end < suffix) - suffix_end = suffix; - while (suffix_end > suffix && *suffix_end != '/') - suffix_end--; - if ((suffix_end < filename) && (*suffix_end == '/')) - suffix_end++; - - /* Step 4: Build the new name. */ - /* The OpenBSD strlcpy function is safer, but less portable. */ - /* Rather than maintain two versions, just use the strncpy version. */ - p = dest; - if (prefix_end > prefix) { - strncpy(p, prefix, prefix_end - prefix); - p += prefix_end - prefix; - } - if (suffix_end > suffix) { - strncpy(p, suffix, suffix_end - suffix); - p += suffix_end - suffix; - } - if (insert != NULL) { - /* Note: assume insert does not have leading or trailing '/' */ - strcpy(p, insert); - p += strlen(insert); - *p++ = '/'; - } - strncpy(p, filename, filename_end - filename); - p += filename_end - filename; - if (need_slash) - *p++ = '/'; - *p = '\0'; - - return (dest); -} - -/* - * The ustar header for the pax extended attributes must have a - * reasonable name: SUSv3 requires 'dirname'/PaxHeader.'pid'/'filename' - * where 'pid' is the PID of the archiving process. Unfortunately, - * that makes testing a pain since the output varies for each run, - * so I'm sticking with the simpler 'dirname'/PaxHeader/'filename' - * for now. (Someday, I'll make this settable. Then I can use the - * SUS recommendation as default and test harnesses can override it - * to get predictable results.) - * - * Joerg Schilling has argued that this is unnecessary because, in - * practice, if the pax extended attributes get extracted as regular - * files, no one is going to bother reading those attributes to - * manually restore them. Based on this, 'star' uses - * /tmp/PaxHeader/'basename' as the ustar header name. This is a - * tempting argument, in part because it's simpler than the SUSv3 - * recommendation, but I'm not entirely convinced. I'm also - * uncomfortable with the fact that "/tmp" is a Unix-ism. - * - * The following routine leverages build_ustar_entry_name() above and - * so is simpler than you might think. It just needs to provide the - * additional path element and handle a few pathological cases). - */ -static char * -build_pax_attribute_name(char *dest, const char *src) -{ - char buff[64]; - const char *p; - - /* Handle the null filename case. */ - if (src == NULL || *src == '\0') { - strcpy(dest, "PaxHeader/blank"); - return (dest); - } - - /* Prune final '/' and other unwanted final elements. */ - p = src + strlen(src); - for (;;) { - /* Ends in "/", remove the '/' */ - if (p > src && p[-1] == '/') { - --p; - continue; - } - /* Ends in "/.", remove the '.' */ - if (p > src + 1 && p[-1] == '.' - && p[-2] == '/') { - --p; - continue; - } - break; - } - - /* Pathological case: After above, there was nothing left. - * This includes "/." "/./." "/.//./." etc. */ - if (p == src) { - strcpy(dest, "/PaxHeader/rootdir"); - return (dest); - } - - /* Convert unadorned "." into a suitable filename. */ - if (*src == '.' && p == src + 1) { - strcpy(dest, "PaxHeader/currentdir"); - return (dest); - } - - /* - * TODO: Push this string into the 'pax' structure to avoid - * recomputing it every time. That will also open the door - * to having clients override it. - */ -#if HAVE_GETPID && 0 /* Disable this for now; see above comment. */ - snprintf(buff, sizeof(buff), "PaxHeader.%d", getpid()); -#else - /* If the platform can't fetch the pid, don't include it. */ - strcpy(buff, "PaxHeader"); -#endif - /* General case: build a ustar-compatible name adding - * "/PaxHeader/". */ - build_ustar_entry_name(dest, src, p - src, buff); - - return (dest); -} - -/* - * GNU PAX Format 1.0 requires the special name, which pattern is: - * /GNUSparseFile./ - * - * Since reproducible archives are more important, use 0 as pid. - * - * This function is used for only Sparse file, a file type of which - * is regular file. - */ -static char * -build_gnu_sparse_name(char *dest, const char *src) -{ - const char *p; - - /* Handle the null filename case. */ - if (src == NULL || *src == '\0') { - strcpy(dest, "GNUSparseFile/blank"); - return (dest); - } - - /* Prune final '/' and other unwanted final elements. */ - p = src + strlen(src); - for (;;) { - /* Ends in "/", remove the '/' */ - if (p > src && p[-1] == '/') { - --p; - continue; - } - /* Ends in "/.", remove the '.' */ - if (p > src + 1 && p[-1] == '.' - && p[-2] == '/') { - --p; - continue; - } - break; - } - - /* General case: build a ustar-compatible name adding - * "/GNUSparseFile/". */ - build_ustar_entry_name(dest, src, p - src, "GNUSparseFile.0"); - - return (dest); -} - -/* Write two null blocks for the end of archive */ -static int -archive_write_pax_close(struct archive_write *a) -{ - return (__archive_write_nulls(a, 512 * 2)); -} - -static int -archive_write_pax_free(struct archive_write *a) -{ - struct pax *pax; - - pax = (struct pax *)a->format_data; - if (pax == NULL) - return (ARCHIVE_OK); - - archive_string_free(&pax->pax_header); - archive_string_free(&pax->sparse_map); - archive_string_free(&pax->l_url_encoded_name); - sparse_list_clear(pax); - free(pax); - a->format_data = NULL; - return (ARCHIVE_OK); -} - -static int -archive_write_pax_finish_entry(struct archive_write *a) -{ - struct pax *pax; - uint64_t remaining; - int ret; - - pax = (struct pax *)a->format_data; - remaining = pax->entry_bytes_remaining; - if (remaining == 0) { - while (pax->sparse_list) { - struct sparse_block *sb; - if (!pax->sparse_list->is_hole) - remaining += pax->sparse_list->remaining; - sb = pax->sparse_list->next; - free(pax->sparse_list); - pax->sparse_list = sb; - } - } - ret = __archive_write_nulls(a, (size_t)(remaining + pax->entry_padding)); - pax->entry_bytes_remaining = pax->entry_padding = 0; - return (ret); -} - -static ssize_t -archive_write_pax_data(struct archive_write *a, const void *buff, size_t s) -{ - struct pax *pax; - size_t ws; - size_t total; - int ret; - - pax = (struct pax *)a->format_data; - - /* - * According to GNU PAX format 1.0, write a sparse map - * before the body. - */ - if (archive_strlen(&(pax->sparse_map))) { - ret = __archive_write_output(a, pax->sparse_map.s, - archive_strlen(&(pax->sparse_map))); - if (ret != ARCHIVE_OK) - return (ret); - ret = __archive_write_nulls(a, pax->sparse_map_padding); - if (ret != ARCHIVE_OK) - return (ret); - archive_string_empty(&(pax->sparse_map)); - } - - total = 0; - while (total < s) { - const unsigned char *p; - - while (pax->sparse_list != NULL && - pax->sparse_list->remaining == 0) { - struct sparse_block *sb = pax->sparse_list->next; - free(pax->sparse_list); - pax->sparse_list = sb; - } - - if (pax->sparse_list == NULL) - return (total); - - p = ((const unsigned char *)buff) + total; - ws = s - total; - if (ws > pax->sparse_list->remaining) - ws = (size_t)pax->sparse_list->remaining; - - if (pax->sparse_list->is_hole) { - /* Current block is hole thus we do not write - * the body. */ - pax->sparse_list->remaining -= ws; - total += ws; - continue; - } - - ret = __archive_write_output(a, p, ws); - pax->sparse_list->remaining -= ws; - total += ws; - if (ret != ARCHIVE_OK) - return (ret); - } - return (total); -} - -static int -has_non_ASCII(const char *_p) -{ - const unsigned char *p = (const unsigned char *)_p; - - if (p == NULL) - return (1); - while (*p != '\0' && *p < 128) - p++; - return (*p != '\0'); -} - -/* - * Used by extended attribute support; encodes the name - * so that there will be no '=' characters in the result. - */ -static char * -url_encode(const char *in) -{ - const char *s; - char *d; - size_t out_len = 0; - char *out; - - for (s = in; *s != '\0'; s++) { - if (*s < 33 || *s > 126 || *s == '%' || *s == '=') { - if (SIZE_MAX - out_len < 4) - return (NULL); - out_len += 3; - } else { - if (SIZE_MAX - out_len < 2) - return (NULL); - out_len++; - } - } - - out = (char *)malloc(out_len + 1); - if (out == NULL) - return (NULL); - - for (s = in, d = out; *s != '\0'; s++) { - /* encode any non-printable ASCII character or '%' or '=' */ - if (*s < 33 || *s > 126 || *s == '%' || *s == '=') { - /* URL encoding is '%' followed by two hex digits */ - *d++ = '%'; - *d++ = "0123456789ABCDEF"[0x0f & (*s >> 4)]; - *d++ = "0123456789ABCDEF"[0x0f & *s]; - } else { - *d++ = *s; - } - } - *d = '\0'; - return (out); -} - -/* - * Encode a sequence of bytes into a C string using base-64 encoding. - * - * Returns a null-terminated C string allocated with malloc(); caller - * is responsible for freeing the result. - */ -static char * -base64_encode(const char *s, size_t len) -{ - static const char digits[64] = - { 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O', - 'P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d', - 'e','f','g','h','i','j','k','l','m','n','o','p','q','r','s', - 't','u','v','w','x','y','z','0','1','2','3','4','5','6','7', - '8','9','+','/' }; - int v; - char *d, *out; - - /* 3 bytes becomes 4 chars, but round up and allow for trailing NUL */ - out = (char *)malloc((len * 4 + 2) / 3 + 1); - if (out == NULL) - return (NULL); - d = out; - - /* Convert each group of 3 bytes into 4 characters. */ - while (len >= 3) { - v = (((int)s[0] << 16) & 0xff0000) - | (((int)s[1] << 8) & 0xff00) - | (((int)s[2]) & 0x00ff); - s += 3; - len -= 3; - *d++ = digits[(v >> 18) & 0x3f]; - *d++ = digits[(v >> 12) & 0x3f]; - *d++ = digits[(v >> 6) & 0x3f]; - *d++ = digits[(v) & 0x3f]; - } - /* Handle final group of 1 byte (2 chars) or 2 bytes (3 chars). */ - switch (len) { - case 0: break; - case 1: - v = (((int)s[0] << 16) & 0xff0000); - *d++ = digits[(v >> 18) & 0x3f]; - *d++ = digits[(v >> 12) & 0x3f]; - break; - case 2: - v = (((int)s[0] << 16) & 0xff0000) - | (((int)s[1] << 8) & 0xff00); - *d++ = digits[(v >> 18) & 0x3f]; - *d++ = digits[(v >> 12) & 0x3f]; - *d++ = digits[(v >> 6) & 0x3f]; - break; - } - /* Add trailing NUL character so output is a valid C string. */ - *d = '\0'; - return (out); -} - -static void -sparse_list_clear(struct pax *pax) -{ - while (pax->sparse_list != NULL) { - struct sparse_block *sb = pax->sparse_list; - pax->sparse_list = sb->next; - free(sb); - } - pax->sparse_tail = NULL; -} - -static int -_sparse_list_add_block(struct pax *pax, int64_t offset, int64_t length, - int is_hole) -{ - struct sparse_block *sb; - - sb = (struct sparse_block *)malloc(sizeof(*sb)); - if (sb == NULL) - return (ARCHIVE_FATAL); - sb->next = NULL; - sb->is_hole = is_hole; - sb->offset = offset; - sb->remaining = length; - if (pax->sparse_list == NULL || pax->sparse_tail == NULL) - pax->sparse_list = pax->sparse_tail = sb; - else { - pax->sparse_tail->next = sb; - pax->sparse_tail = sb; - } - return (ARCHIVE_OK); -} - -static int -sparse_list_add(struct pax *pax, int64_t offset, int64_t length) -{ - int64_t last_offset; - int r; - - if (pax->sparse_tail == NULL) - last_offset = 0; - else { - last_offset = pax->sparse_tail->offset + - pax->sparse_tail->remaining; - } - if (last_offset < offset) { - /* Add a hole block. */ - r = _sparse_list_add_block(pax, last_offset, - offset - last_offset, 1); - if (r != ARCHIVE_OK) - return (r); - } - /* Add data block. */ - return (_sparse_list_add_block(pax, offset, length, 0)); -} - -static time_t -get_ustar_max_mtime(void) -{ - /* - * Technically, the mtime field in the ustar header can - * support 33 bits. We are using all of them to keep - * tar/test/test_option_C_mtree.c simple and passing after 2038. - * For platforms that use signed 32-bit time values we - * use the 32-bit maximum. - */ - if (sizeof(time_t) > sizeof(int32_t)) - return (time_t)0x1ffffffff; - else - return (time_t)0x7fffffff; -} diff --git a/thirdparty/libarchive/libarchive/archive_write_set_format_private.h b/thirdparty/libarchive/libarchive/archive_write_set_format_private.h deleted file mode 100644 index e20022755..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_set_format_private.h +++ /dev/null @@ -1,42 +0,0 @@ -/*- - * Copyright (c) 2020 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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$ - */ - -#ifndef ARCHIVE_WRITE_SET_FORMAT_PRIVATE_H_INCLUDED -#define ARCHIVE_WRITE_SET_FORMAT_PRIVATE_H_INCLUDED - -#ifndef __LIBARCHIVE_BUILD -#ifndef __LIBARCHIVE_TEST -#error This header is only to be used internally to libarchive. -#endif -#endif - -#include "archive.h" -#include "archive_entry.h" - -void __archive_write_entry_filetype_unsupported(struct archive *a, - struct archive_entry *entry, const char *format); -#endif diff --git a/thirdparty/libarchive/libarchive/archive_write_set_format_raw.c b/thirdparty/libarchive/libarchive/archive_write_set_format_raw.c deleted file mode 100644 index feff93697..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_set_format_raw.c +++ /dev/null @@ -1,125 +0,0 @@ -/*- - * Copyright (c) 2013 Marek Kubica - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -#ifdef HAVE_ERRNO_H -#include -#endif - -#include "archive_entry.h" -#include "archive_write_private.h" - -static ssize_t archive_write_raw_data(struct archive_write *, - const void *buff, size_t s); -static int archive_write_raw_free(struct archive_write *); -static int archive_write_raw_header(struct archive_write *, - struct archive_entry *); - -struct raw { - int entries_written; -}; - -/* - * Set output format to 'raw' format. - */ -int -archive_write_set_format_raw(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - struct raw *raw; - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_set_format_raw"); - - /* If someone else was already registered, unregister them. */ - if (a->format_free != NULL) - (a->format_free)(a); - - raw = (struct raw *)calloc(1, sizeof(*raw)); - if (raw == NULL) { - archive_set_error(&a->archive, ENOMEM, "Can't allocate raw data"); - return (ARCHIVE_FATAL); - } - raw->entries_written = 0; - a->format_data = raw; - a->format_name = "raw"; - /* no options exist for this format */ - a->format_options = NULL; - a->format_write_header = archive_write_raw_header; - a->format_write_data = archive_write_raw_data; - a->format_finish_entry = NULL; - /* nothing needs to be done on closing */ - a->format_close = NULL; - a->format_free = archive_write_raw_free; - a->archive.archive_format = ARCHIVE_FORMAT_RAW; - a->archive.archive_format_name = "RAW"; - return (ARCHIVE_OK); -} - -static int -archive_write_raw_header(struct archive_write *a, struct archive_entry *entry) -{ - struct raw *raw = (struct raw *)a->format_data; - - if (archive_entry_filetype(entry) != AE_IFREG) { - archive_set_error(&a->archive, ERANGE, - "Raw format only supports filetype AE_IFREG"); - return (ARCHIVE_FATAL); - } - - - if (raw->entries_written > 0) { - archive_set_error(&a->archive, ERANGE, - "Raw format only supports one entry per archive"); - return (ARCHIVE_FATAL); - } - raw->entries_written++; - - return (ARCHIVE_OK); -} - -static ssize_t -archive_write_raw_data(struct archive_write *a, const void *buff, size_t s) -{ - int ret; - - ret = __archive_write_output(a, buff, s); - if (ret >= 0) - return (s); - else - return (ret); -} - -static int -archive_write_raw_free(struct archive_write *a) -{ - struct raw *raw; - - raw = (struct raw *)a->format_data; - free(raw); - a->format_data = NULL; - return (ARCHIVE_OK); -} diff --git a/thirdparty/libarchive/libarchive/archive_write_set_format_shar.c b/thirdparty/libarchive/libarchive/archive_write_set_format_shar.c deleted file mode 100644 index 9e4931c95..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_set_format_shar.c +++ /dev/null @@ -1,641 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2008 Joerg Sonnenberger - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_shar.c 189438 2009-03-06 05:58:56Z kientzle $"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" -#include "archive_private.h" -#include "archive_write_private.h" -#include "archive_write_set_format_private.h" - -struct shar { - int dump; - int end_of_line; - struct archive_entry *entry; - int has_data; - char *last_dir; - - /* Line buffer for uuencoded dump format */ - char outbuff[45]; - size_t outpos; - - int wrote_header; - struct archive_string work; - struct archive_string quoted_name; -}; - -static int archive_write_shar_close(struct archive_write *); -static int archive_write_shar_free(struct archive_write *); -static int archive_write_shar_header(struct archive_write *, - struct archive_entry *); -static ssize_t archive_write_shar_data_sed(struct archive_write *, - const void * buff, size_t); -static ssize_t archive_write_shar_data_uuencode(struct archive_write *, - const void * buff, size_t); -static int archive_write_shar_finish_entry(struct archive_write *); - -/* - * Copy the given string to the buffer, quoting all shell meta characters - * found. - */ -static void -shar_quote(struct archive_string *buf, const char *str, int in_shell) -{ - static const char meta[] = "\n \t'`\";&<>()|*?{}[]\\$!#^~"; - size_t len; - - while (*str != '\0') { - if ((len = strcspn(str, meta)) != 0) { - archive_strncat(buf, str, len); - str += len; - } else if (*str == '\n') { - if (in_shell) - archive_strcat(buf, "\"\n\""); - else - archive_strcat(buf, "\\n"); - ++str; - } else { - archive_strappend_char(buf, '\\'); - archive_strappend_char(buf, *str); - ++str; - } - } -} - -/* - * Set output format to 'shar' format. - */ -int -archive_write_set_format_shar(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - struct shar *shar; - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_set_format_shar"); - - /* If someone else was already registered, unregister them. */ - if (a->format_free != NULL) - (a->format_free)(a); - - shar = (struct shar *)calloc(1, sizeof(*shar)); - if (shar == NULL) { - archive_set_error(&a->archive, ENOMEM, "Can't allocate shar data"); - return (ARCHIVE_FATAL); - } - archive_string_init(&shar->work); - archive_string_init(&shar->quoted_name); - a->format_data = shar; - a->format_name = "shar"; - a->format_write_header = archive_write_shar_header; - a->format_close = archive_write_shar_close; - a->format_free = archive_write_shar_free; - a->format_write_data = archive_write_shar_data_sed; - a->format_finish_entry = archive_write_shar_finish_entry; - a->archive.archive_format = ARCHIVE_FORMAT_SHAR_BASE; - a->archive.archive_format_name = "shar"; - return (ARCHIVE_OK); -} - -/* - * An alternate 'shar' that uses uudecode instead of 'sed' to encode - * file contents and can therefore be used to archive binary files. - * In addition, this variant also attempts to restore ownership, file modes, - * and other extended file information. - */ -int -archive_write_set_format_shar_dump(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - struct shar *shar; - - archive_write_set_format_shar(&a->archive); - shar = (struct shar *)a->format_data; - shar->dump = 1; - a->format_write_data = archive_write_shar_data_uuencode; - a->archive.archive_format = ARCHIVE_FORMAT_SHAR_DUMP; - a->archive.archive_format_name = "shar dump"; - return (ARCHIVE_OK); -} - -static int -archive_write_shar_header(struct archive_write *a, struct archive_entry *entry) -{ - const char *linkname; - const char *name; - char *p, *pp; - struct shar *shar; - - shar = (struct shar *)a->format_data; - if (!shar->wrote_header) { - archive_strcat(&shar->work, "#!/bin/sh\n"); - archive_strcat(&shar->work, "# This is a shell archive\n"); - shar->wrote_header = 1; - } - - /* Save the entry for the closing. */ - archive_entry_free(shar->entry); - shar->entry = archive_entry_clone(entry); - name = archive_entry_pathname(entry); - - /* Handle some preparatory issues. */ - switch(archive_entry_filetype(entry)) { - case AE_IFREG: - /* Only regular files have non-zero size. */ - break; - case AE_IFDIR: - archive_entry_set_size(entry, 0); - /* Don't bother trying to recreate '.' */ - if (strcmp(name, ".") == 0 || strcmp(name, "./") == 0) - return (ARCHIVE_OK); - break; - case AE_IFIFO: - case AE_IFCHR: - case AE_IFBLK: - /* All other file types have zero size in the archive. */ - archive_entry_set_size(entry, 0); - break; - default: - archive_entry_set_size(entry, 0); - if (archive_entry_hardlink(entry) == NULL && - archive_entry_symlink(entry) == NULL) { - __archive_write_entry_filetype_unsupported( - &a->archive, entry, "shar"); - return (ARCHIVE_WARN); - } - } - - archive_string_empty(&shar->quoted_name); - shar_quote(&shar->quoted_name, name, 1); - - /* Stock preparation for all file types. */ - archive_string_sprintf(&shar->work, "echo x %s\n", shar->quoted_name.s); - - if (archive_entry_filetype(entry) != AE_IFDIR) { - /* Try to create the dir. */ - p = strdup(name); - pp = strrchr(p, '/'); - /* If there is a / character, try to create the dir. */ - if (pp != NULL) { - *pp = '\0'; - - /* Try to avoid a lot of redundant mkdir commands. */ - if (strcmp(p, ".") == 0) { - /* Don't try to "mkdir ." */ - free(p); - } else if (shar->last_dir == NULL) { - archive_strcat(&shar->work, "mkdir -p "); - shar_quote(&shar->work, p, 1); - archive_strcat(&shar->work, - " > /dev/null 2>&1\n"); - shar->last_dir = p; - } else if (strcmp(p, shar->last_dir) == 0) { - /* We've already created this exact dir. */ - free(p); - } else if (strlen(p) < strlen(shar->last_dir) && - strncmp(p, shar->last_dir, strlen(p)) == 0) { - /* We've already created a subdir. */ - free(p); - } else { - archive_strcat(&shar->work, "mkdir -p "); - shar_quote(&shar->work, p, 1); - archive_strcat(&shar->work, - " > /dev/null 2>&1\n"); - shar->last_dir = p; - } - } else { - free(p); - } - } - - /* Handle file-type specific issues. */ - shar->has_data = 0; - if ((linkname = archive_entry_hardlink(entry)) != NULL) { - archive_strcat(&shar->work, "ln -f "); - shar_quote(&shar->work, linkname, 1); - archive_string_sprintf(&shar->work, " %s\n", - shar->quoted_name.s); - } else if ((linkname = archive_entry_symlink(entry)) != NULL) { - archive_strcat(&shar->work, "ln -fs "); - shar_quote(&shar->work, linkname, 1); - archive_string_sprintf(&shar->work, " %s\n", - shar->quoted_name.s); - } else { - switch(archive_entry_filetype(entry)) { - case AE_IFREG: - if (archive_entry_size(entry) == 0) { - /* More portable than "touch." */ - archive_string_sprintf(&shar->work, - "test -e \"%s\" || :> \"%s\"\n", - shar->quoted_name.s, shar->quoted_name.s); - } else { - if (shar->dump) { - unsigned int mode = archive_entry_mode(entry) & 0777; - archive_string_sprintf(&shar->work, - "uudecode -p > %s << 'SHAR_END'\n", - shar->quoted_name.s); - archive_string_sprintf(&shar->work, - "begin %o ", mode); - shar_quote(&shar->work, name, 0); - archive_strcat(&shar->work, "\n"); - } else { - archive_string_sprintf(&shar->work, - "sed 's/^X//' > %s << 'SHAR_END'\n", - shar->quoted_name.s); - } - shar->has_data = 1; - shar->end_of_line = 1; - shar->outpos = 0; - } - break; - case AE_IFDIR: - archive_string_sprintf(&shar->work, - "mkdir -p %s > /dev/null 2>&1\n", - shar->quoted_name.s); - /* Record that we just created this directory. */ - free(shar->last_dir); - - shar->last_dir = strdup(name); - /* Trim a trailing '/'. */ - pp = strrchr(shar->last_dir, '/'); - if (pp != NULL && pp[1] == '\0') - *pp = '\0'; - /* - * TODO: Put dir name/mode on a list to be fixed - * up at end of archive. - */ - break; - case AE_IFIFO: - archive_string_sprintf(&shar->work, - "mkfifo %s\n", shar->quoted_name.s); - break; - case AE_IFCHR: - archive_string_sprintf(&shar->work, - "mknod %s c %ju %ju\n", shar->quoted_name.s, - (uintmax_t)archive_entry_rdevmajor(entry), - (uintmax_t)archive_entry_rdevminor(entry)); - break; - case AE_IFBLK: - archive_string_sprintf(&shar->work, - "mknod %s b %ju %ju\n", shar->quoted_name.s, - (uintmax_t)archive_entry_rdevmajor(entry), - (uintmax_t)archive_entry_rdevminor(entry)); - break; - default: - return (ARCHIVE_WARN); - } - } - - return (ARCHIVE_OK); -} - -static ssize_t -archive_write_shar_data_sed(struct archive_write *a, const void *buff, size_t n) -{ - static const size_t ensured = 65533; - struct shar *shar; - const char *src; - char *buf, *buf_end; - int ret; - size_t written = n; - - shar = (struct shar *)a->format_data; - if (!shar->has_data || n == 0) - return (0); - - src = (const char *)buff; - - /* - * ensure is the number of bytes in buffer before expanding the - * current character. Each operation writes the current character - * and optionally the start-of-new-line marker. This can happen - * twice before entering the loop, so make sure three additional - * bytes can be written. - */ - if (archive_string_ensure(&shar->work, ensured + 3) == NULL) { - archive_set_error(&a->archive, ENOMEM, "Out of memory"); - return (ARCHIVE_FATAL); - } - - if (shar->work.length > ensured) { - ret = __archive_write_output(a, shar->work.s, - shar->work.length); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - archive_string_empty(&shar->work); - } - buf = shar->work.s + shar->work.length; - buf_end = shar->work.s + ensured; - - if (shar->end_of_line) { - *buf++ = 'X'; - shar->end_of_line = 0; - } - - while (n-- != 0) { - if ((*buf++ = *src++) == '\n') { - if (n == 0) - shar->end_of_line = 1; - else - *buf++ = 'X'; - } - - if (buf >= buf_end) { - shar->work.length = buf - shar->work.s; - ret = __archive_write_output(a, shar->work.s, - shar->work.length); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - archive_string_empty(&shar->work); - buf = shar->work.s; - } - } - - shar->work.length = buf - shar->work.s; - - return (written); -} - -#define UUENC(c) (((c)!=0) ? ((c) & 077) + ' ': '`') - -static void -uuencode_group(const char _in[3], char out[4]) -{ - const unsigned char *in = (const unsigned char *)_in; - int t; - - t = (in[0] << 16) | (in[1] << 8) | in[2]; - out[0] = UUENC( 0x3f & (t >> 18) ); - out[1] = UUENC( 0x3f & (t >> 12) ); - out[2] = UUENC( 0x3f & (t >> 6) ); - out[3] = UUENC( 0x3f & t ); -} - -static int -_uuencode_line(struct archive_write *a, struct shar *shar, const char *inbuf, size_t len) -{ - char *buf; - size_t alloc_len; - - /* len <= 45 -> expanded to 60 + len byte + new line */ - alloc_len = shar->work.length + 62; - if (archive_string_ensure(&shar->work, alloc_len) == NULL) { - archive_set_error(&a->archive, ENOMEM, "Out of memory"); - return (ARCHIVE_FATAL); - } - - buf = shar->work.s + shar->work.length; - *buf++ = UUENC(len); - while (len >= 3) { - uuencode_group(inbuf, buf); - len -= 3; - inbuf += 3; - buf += 4; - } - if (len != 0) { - char tmp_buf[3]; - tmp_buf[0] = inbuf[0]; - if (len == 1) - tmp_buf[1] = '\0'; - else - tmp_buf[1] = inbuf[1]; - tmp_buf[2] = '\0'; - uuencode_group(tmp_buf, buf); - buf += 4; - } - *buf++ = '\n'; - if ((buf - shar->work.s) > (ptrdiff_t)(shar->work.length + 62)) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, "Buffer overflow"); - return (ARCHIVE_FATAL); - } - shar->work.length = buf - shar->work.s; - return (ARCHIVE_OK); -} - -#define uuencode_line(__a, __shar, __inbuf, __len) \ - do { \ - int r = _uuencode_line(__a, __shar, __inbuf, __len); \ - if (r != ARCHIVE_OK) \ - return (ARCHIVE_FATAL); \ - } while (0) - -static ssize_t -archive_write_shar_data_uuencode(struct archive_write *a, const void *buff, - size_t length) -{ - struct shar *shar; - const char *src; - size_t n; - int ret; - - shar = (struct shar *)a->format_data; - if (!shar->has_data) - return (ARCHIVE_OK); - src = (const char *)buff; - - if (shar->outpos != 0) { - n = 45 - shar->outpos; - if (n > length) - n = length; - memcpy(shar->outbuff + shar->outpos, src, n); - if (shar->outpos + n < 45) { - shar->outpos += n; - return length; - } - uuencode_line(a, shar, shar->outbuff, 45); - src += n; - n = length - n; - } else { - n = length; - } - - while (n >= 45) { - uuencode_line(a, shar, src, 45); - src += 45; - n -= 45; - - if (shar->work.length < 65536) - continue; - ret = __archive_write_output(a, shar->work.s, - shar->work.length); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - archive_string_empty(&shar->work); - } - if (n != 0) { - memcpy(shar->outbuff, src, n); - shar->outpos = n; - } - return (length); -} - -static int -archive_write_shar_finish_entry(struct archive_write *a) -{ - const char *g, *p, *u; - struct shar *shar; - int ret; - - shar = (struct shar *)a->format_data; - if (shar->entry == NULL) - return (0); - - if (shar->dump) { - /* Finish uuencoded data. */ - if (shar->has_data) { - if (shar->outpos > 0) - uuencode_line(a, shar, shar->outbuff, - shar->outpos); - archive_strcat(&shar->work, "`\nend\n"); - archive_strcat(&shar->work, "SHAR_END\n"); - } - /* Restore file mode, owner, flags. */ - /* - * TODO: Don't immediately restore mode for - * directories; defer that to end of script. - */ - archive_string_sprintf(&shar->work, "chmod %o ", - (unsigned int)(archive_entry_mode(shar->entry) & 07777)); - shar_quote(&shar->work, archive_entry_pathname(shar->entry), 1); - archive_strcat(&shar->work, "\n"); - - u = archive_entry_uname(shar->entry); - g = archive_entry_gname(shar->entry); - if (u != NULL || g != NULL) { - archive_strcat(&shar->work, "chown "); - if (u != NULL) - shar_quote(&shar->work, u, 1); - if (g != NULL) { - archive_strcat(&shar->work, ":"); - shar_quote(&shar->work, g, 1); - } - archive_strcat(&shar->work, " "); - shar_quote(&shar->work, - archive_entry_pathname(shar->entry), 1); - archive_strcat(&shar->work, "\n"); - } - - if ((p = archive_entry_fflags_text(shar->entry)) != NULL) { - archive_string_sprintf(&shar->work, "chflags %s ", p); - shar_quote(&shar->work, - archive_entry_pathname(shar->entry), 1); - archive_strcat(&shar->work, "\n"); - } - - /* TODO: restore ACLs */ - - } else { - if (shar->has_data) { - /* Finish sed-encoded data: ensure last line ends. */ - if (!shar->end_of_line) - archive_strappend_char(&shar->work, '\n'); - archive_strcat(&shar->work, "SHAR_END\n"); - } - } - - archive_entry_free(shar->entry); - shar->entry = NULL; - - if (shar->work.length < 65536) - return (ARCHIVE_OK); - - ret = __archive_write_output(a, shar->work.s, shar->work.length); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - archive_string_empty(&shar->work); - - return (ARCHIVE_OK); -} - -static int -archive_write_shar_close(struct archive_write *a) -{ - struct shar *shar; - int ret; - - /* - * TODO: Accumulate list of directory names/modes and - * fix them all up at end-of-archive. - */ - - shar = (struct shar *)a->format_data; - - /* - * Only write the end-of-archive markers if the archive was - * actually started. This avoids problems if someone sets - * shar format, then sets another format (which would invoke - * shar_finish to free the format-specific data). - */ - if (shar->wrote_header == 0) - return (ARCHIVE_OK); - - archive_strcat(&shar->work, "exit\n"); - - ret = __archive_write_output(a, shar->work.s, shar->work.length); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - - /* Shar output is never padded. */ - archive_write_set_bytes_in_last_block(&a->archive, 1); - /* - * TODO: shar should also suppress padding of - * uncompressed data within gzip/bzip2 streams. - */ - - return (ARCHIVE_OK); -} - -static int -archive_write_shar_free(struct archive_write *a) -{ - struct shar *shar; - - shar = (struct shar *)a->format_data; - if (shar == NULL) - return (ARCHIVE_OK); - - archive_entry_free(shar->entry); - free(shar->last_dir); - archive_string_free(&(shar->work)); - archive_string_free(&(shar->quoted_name)); - free(shar); - a->format_data = NULL; - return (ARCHIVE_OK); -} diff --git a/thirdparty/libarchive/libarchive/archive_write_set_format_ustar.c b/thirdparty/libarchive/libarchive/archive_write_set_format_ustar.c deleted file mode 100644 index d1a06bc4f..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_set_format_ustar.c +++ /dev/null @@ -1,758 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2011-2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_ustar.c 191579 2009-04-27 18:35:03Z kientzle $"); - - -#ifdef HAVE_ERRNO_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" -#include "archive_entry_locale.h" -#include "archive_private.h" -#include "archive_write_private.h" -#include "archive_write_set_format_private.h" - -struct ustar { - uint64_t entry_bytes_remaining; - uint64_t entry_padding; - - struct archive_string_conv *opt_sconv; - struct archive_string_conv *sconv_default; - int init_default_conversion; -}; - -/* - * Define structure of POSIX 'ustar' tar header. - */ -#define USTAR_name_offset 0 -#define USTAR_name_size 100 -#define USTAR_mode_offset 100 -#define USTAR_mode_size 6 -#define USTAR_mode_max_size 8 -#define USTAR_uid_offset 108 -#define USTAR_uid_size 6 -#define USTAR_uid_max_size 8 -#define USTAR_gid_offset 116 -#define USTAR_gid_size 6 -#define USTAR_gid_max_size 8 -#define USTAR_size_offset 124 -#define USTAR_size_size 11 -#define USTAR_size_max_size 12 -#define USTAR_mtime_offset 136 -#define USTAR_mtime_size 11 -#define USTAR_mtime_max_size 11 -#define USTAR_checksum_offset 148 -#define USTAR_checksum_size 8 -#define USTAR_typeflag_offset 156 -#define USTAR_typeflag_size 1 -#define USTAR_linkname_offset 157 -#define USTAR_linkname_size 100 -#define USTAR_magic_offset 257 -#define USTAR_magic_size 6 -#define USTAR_version_offset 263 -#define USTAR_version_size 2 -#define USTAR_uname_offset 265 -#define USTAR_uname_size 32 -#define USTAR_gname_offset 297 -#define USTAR_gname_size 32 -#define USTAR_rdevmajor_offset 329 -#define USTAR_rdevmajor_size 6 -#define USTAR_rdevmajor_max_size 8 -#define USTAR_rdevminor_offset 337 -#define USTAR_rdevminor_size 6 -#define USTAR_rdevminor_max_size 8 -#define USTAR_prefix_offset 345 -#define USTAR_prefix_size 155 -#define USTAR_padding_offset 500 -#define USTAR_padding_size 12 - -/* - * A filled-in copy of the header for initialization. - */ -static const char template_header[] = { - /* name: 100 bytes */ - 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,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, - /* Mode, space-null termination: 8 bytes */ - '0','0','0','0','0','0', ' ','\0', - /* uid, space-null termination: 8 bytes */ - '0','0','0','0','0','0', ' ','\0', - /* gid, space-null termination: 8 bytes */ - '0','0','0','0','0','0', ' ','\0', - /* size, space termination: 12 bytes */ - '0','0','0','0','0','0','0','0','0','0','0', ' ', - /* mtime, space termination: 12 bytes */ - '0','0','0','0','0','0','0','0','0','0','0', ' ', - /* Initial checksum value: 8 spaces */ - ' ',' ',' ',' ',' ',' ',' ',' ', - /* Typeflag: 1 byte */ - '0', /* '0' = regular file */ - /* Linkname: 100 bytes */ - 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,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, - /* Magic: 6 bytes, Version: 2 bytes */ - 'u','s','t','a','r','\0', '0','0', - /* Uname: 32 bytes */ - 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, - /* Gname: 32 bytes */ - 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, - /* rdevmajor + space/null padding: 8 bytes */ - '0','0','0','0','0','0', ' ','\0', - /* rdevminor + space/null padding: 8 bytes */ - '0','0','0','0','0','0', ' ','\0', - /* Prefix: 155 bytes */ - 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,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,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, - /* Padding: 12 bytes */ - 0,0,0,0,0,0,0,0, 0,0,0,0 -}; - -static ssize_t archive_write_ustar_data(struct archive_write *a, const void *buff, - size_t s); -static int archive_write_ustar_free(struct archive_write *); -static int archive_write_ustar_close(struct archive_write *); -static int archive_write_ustar_finish_entry(struct archive_write *); -static int archive_write_ustar_header(struct archive_write *, - struct archive_entry *entry); -static int archive_write_ustar_options(struct archive_write *, - const char *, const char *); -static int format_256(int64_t, char *, int); -static int format_number(int64_t, char *, int size, int max, int strict); -static int format_octal(int64_t, char *, int); - -/* - * Set output format to 'ustar' format. - */ -int -archive_write_set_format_ustar(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - struct ustar *ustar; - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_set_format_ustar"); - - /* If someone else was already registered, unregister them. */ - if (a->format_free != NULL) - (a->format_free)(a); - - /* Basic internal sanity test. */ - if (sizeof(template_header) != 512) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Internal: template_header wrong size: %zu should be 512", - sizeof(template_header)); - return (ARCHIVE_FATAL); - } - - ustar = (struct ustar *)calloc(1, sizeof(*ustar)); - if (ustar == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate ustar data"); - return (ARCHIVE_FATAL); - } - a->format_data = ustar; - a->format_name = "ustar"; - a->format_options = archive_write_ustar_options; - a->format_write_header = archive_write_ustar_header; - a->format_write_data = archive_write_ustar_data; - a->format_close = archive_write_ustar_close; - a->format_free = archive_write_ustar_free; - a->format_finish_entry = archive_write_ustar_finish_entry; - a->archive.archive_format = ARCHIVE_FORMAT_TAR_USTAR; - a->archive.archive_format_name = "POSIX ustar"; - return (ARCHIVE_OK); -} - -static int -archive_write_ustar_options(struct archive_write *a, const char *key, - const char *val) -{ - struct ustar *ustar = (struct ustar *)a->format_data; - int ret = ARCHIVE_FAILED; - - if (strcmp(key, "hdrcharset") == 0) { - if (val == NULL || val[0] == 0) - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "%s: hdrcharset option needs a character-set name", - a->format_name); - else { - ustar->opt_sconv = archive_string_conversion_to_charset( - &a->archive, val, 0); - if (ustar->opt_sconv != NULL) - ret = ARCHIVE_OK; - else - ret = ARCHIVE_FATAL; - } - return (ret); - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -static int -archive_write_ustar_header(struct archive_write *a, struct archive_entry *entry) -{ - char buff[512]; - int ret, ret2; - struct ustar *ustar; - struct archive_entry *entry_main; - struct archive_string_conv *sconv; - - ustar = (struct ustar *)a->format_data; - - /* Setup default string conversion. */ - if (ustar->opt_sconv == NULL) { - if (!ustar->init_default_conversion) { - ustar->sconv_default = - archive_string_default_conversion_for_write(&(a->archive)); - ustar->init_default_conversion = 1; - } - sconv = ustar->sconv_default; - } else - sconv = ustar->opt_sconv; - - /* Sanity check. */ - if (archive_entry_pathname(entry) == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Can't record entry in tar file without pathname"); - return (ARCHIVE_FAILED); - } - - /* Only regular files (not hardlinks) have data. */ - if (archive_entry_hardlink(entry) != NULL || - archive_entry_symlink(entry) != NULL || - !(archive_entry_filetype(entry) == AE_IFREG)) - archive_entry_set_size(entry, 0); - - if (AE_IFDIR == archive_entry_filetype(entry)) { - const char *p; - size_t path_length; - /* - * Ensure a trailing '/'. Modify the entry so - * the client sees the change. - */ -#if defined(_WIN32) && !defined(__CYGWIN__) - const wchar_t *wp; - - wp = archive_entry_pathname_w(entry); - if (wp != NULL && wp[wcslen(wp) -1] != L'/') { - struct archive_wstring ws; - - archive_string_init(&ws); - path_length = wcslen(wp); - if (archive_wstring_ensure(&ws, - path_length + 2) == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate ustar data"); - archive_wstring_free(&ws); - return(ARCHIVE_FATAL); - } - /* Should we keep '\' ? */ - if (wp[path_length -1] == L'\\') - path_length--; - archive_wstrncpy(&ws, wp, path_length); - archive_wstrappend_wchar(&ws, L'/'); - archive_entry_copy_pathname_w(entry, ws.s); - archive_wstring_free(&ws); - p = NULL; - } else -#endif - p = archive_entry_pathname(entry); - /* - * On Windows, this is a backup operation just in - * case getting WCS failed. On POSIX, this is a - * normal operation. - */ - if (p != NULL && p[0] != '\0' && p[strlen(p) - 1] != '/') { - struct archive_string as; - - archive_string_init(&as); - path_length = strlen(p); - if (archive_string_ensure(&as, - path_length + 2) == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate ustar data"); - archive_string_free(&as); - return(ARCHIVE_FATAL); - } -#if defined(_WIN32) && !defined(__CYGWIN__) - /* NOTE: This might break the pathname - * if the current code page is CP932 and - * the pathname includes a character '\' - * as a part of its multibyte pathname. */ - if (p[strlen(p) -1] == '\\') - path_length--; - else -#endif - archive_strncpy(&as, p, path_length); - archive_strappend_char(&as, '/'); - archive_entry_copy_pathname(entry, as.s); - archive_string_free(&as); - } - } - -#if defined(_WIN32) && !defined(__CYGWIN__) - /* Make sure the path separators in pathname, hardlink and symlink - * are all slash '/', not the Windows path separator '\'. */ - entry_main = __la_win_entry_in_posix_pathseparator(entry); - if (entry_main == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate ustar data"); - return(ARCHIVE_FATAL); - } - if (entry != entry_main) - entry = entry_main; - else - entry_main = NULL; -#else - entry_main = NULL; -#endif - ret = __archive_write_format_header_ustar(a, buff, entry, -1, 1, sconv); - if (ret < ARCHIVE_WARN) { - archive_entry_free(entry_main); - return (ret); - } - ret2 = __archive_write_output(a, buff, 512); - if (ret2 < ARCHIVE_WARN) { - archive_entry_free(entry_main); - return (ret2); - } - if (ret2 < ret) - ret = ret2; - - ustar->entry_bytes_remaining = archive_entry_size(entry); - ustar->entry_padding = 0x1ff & (-(int64_t)ustar->entry_bytes_remaining); - archive_entry_free(entry_main); - return (ret); -} - -/* - * Format a basic 512-byte "ustar" header. - * - * Returns -1 if format failed (due to field overflow). - * Note that this always formats as much of the header as possible. - * If "strict" is set to zero, it will extend numeric fields as - * necessary (overwriting terminators or using base-256 extensions). - * - * This is exported so that other 'tar' formats can use it. - */ -int -__archive_write_format_header_ustar(struct archive_write *a, char h[512], - struct archive_entry *entry, int tartype, int strict, - struct archive_string_conv *sconv) -{ - unsigned int checksum; - int i, r, ret; - size_t copy_length; - const char *p, *pp; - int mytartype; - - ret = 0; - mytartype = -1; - /* - * The "template header" already includes the "ustar" - * signature, various end-of-field markers and other required - * elements. - */ - memcpy(h, &template_header, 512); - - /* - * Because the block is already null-filled, and strings - * are allowed to exactly fill their destination (without null), - * I use memcpy(dest, src, strlen()) here a lot to copy strings. - */ - r = archive_entry_pathname_l(entry, &pp, ©_length, sconv); - if (r != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Pathname"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate pathname '%s' to %s", - pp, archive_string_conversion_charset_name(sconv)); - ret = ARCHIVE_WARN; - } - if (copy_length <= USTAR_name_size) - memcpy(h + USTAR_name_offset, pp, copy_length); - else { - /* Store in two pieces, splitting at a '/'. */ - p = strchr(pp + copy_length - USTAR_name_size - 1, '/'); - /* - * Look for the next '/' if we chose the first character - * as the separator. (ustar format doesn't permit - * an empty prefix.) - */ - if (p == pp) - p = strchr(p + 1, '/'); - /* Fail if the name won't fit. */ - if (!p) { - /* No separator. */ - archive_set_error(&a->archive, ENAMETOOLONG, - "Pathname too long"); - ret = ARCHIVE_FAILED; - } else if (p[1] == '\0') { - /* - * The only feasible separator is a final '/'; - * this would result in a non-empty prefix and - * an empty name, which POSIX doesn't - * explicitly forbid, but it just feels wrong. - */ - archive_set_error(&a->archive, ENAMETOOLONG, - "Pathname too long"); - ret = ARCHIVE_FAILED; - } else if (p > pp + USTAR_prefix_size) { - /* Prefix is too long. */ - archive_set_error(&a->archive, ENAMETOOLONG, - "Pathname too long"); - ret = ARCHIVE_FAILED; - } else { - /* Copy prefix and remainder to appropriate places */ - memcpy(h + USTAR_prefix_offset, pp, p - pp); - memcpy(h + USTAR_name_offset, p + 1, - pp + copy_length - p - 1); - } - } - - r = archive_entry_hardlink_l(entry, &p, ©_length, sconv); - if (r != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Linkname"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate linkname '%s' to %s", - p, archive_string_conversion_charset_name(sconv)); - ret = ARCHIVE_WARN; - } - if (copy_length > 0) - mytartype = '1'; - else { - r = archive_entry_symlink_l(entry, &p, ©_length, sconv); - if (r != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Linkname"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate linkname '%s' to %s", - p, archive_string_conversion_charset_name(sconv)); - ret = ARCHIVE_WARN; - } - } - if (copy_length > 0) { - if (copy_length > USTAR_linkname_size) { - archive_set_error(&a->archive, ENAMETOOLONG, - "Link contents too long"); - ret = ARCHIVE_FAILED; - copy_length = USTAR_linkname_size; - } - memcpy(h + USTAR_linkname_offset, p, copy_length); - } - - r = archive_entry_uname_l(entry, &p, ©_length, sconv); - if (r != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Uname"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate uname '%s' to %s", - p, archive_string_conversion_charset_name(sconv)); - ret = ARCHIVE_WARN; - } - if (copy_length > 0) { - if (copy_length > USTAR_uname_size) { - if (tartype != 'x') { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, "Username too long"); - ret = ARCHIVE_FAILED; - } - copy_length = USTAR_uname_size; - } - memcpy(h + USTAR_uname_offset, p, copy_length); - } - - r = archive_entry_gname_l(entry, &p, ©_length, sconv); - if (r != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Gname"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate gname '%s' to %s", - p, archive_string_conversion_charset_name(sconv)); - ret = ARCHIVE_WARN; - } - if (copy_length > 0) { - if (strlen(p) > USTAR_gname_size) { - if (tartype != 'x') { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, "Group name too long"); - ret = ARCHIVE_FAILED; - } - copy_length = USTAR_gname_size; - } - memcpy(h + USTAR_gname_offset, p, copy_length); - } - - if (format_number(archive_entry_mode(entry) & 07777, - h + USTAR_mode_offset, USTAR_mode_size, USTAR_mode_max_size, strict)) { - archive_set_error(&a->archive, ERANGE, - "Numeric mode too large"); - ret = ARCHIVE_FAILED; - } - - if (format_number(archive_entry_uid(entry), - h + USTAR_uid_offset, USTAR_uid_size, USTAR_uid_max_size, strict)) { - archive_set_error(&a->archive, ERANGE, - "Numeric user ID too large"); - ret = ARCHIVE_FAILED; - } - - if (format_number(archive_entry_gid(entry), - h + USTAR_gid_offset, USTAR_gid_size, USTAR_gid_max_size, strict)) { - archive_set_error(&a->archive, ERANGE, - "Numeric group ID too large"); - ret = ARCHIVE_FAILED; - } - - if (format_number(archive_entry_size(entry), - h + USTAR_size_offset, USTAR_size_size, USTAR_size_max_size, strict)) { - archive_set_error(&a->archive, ERANGE, - "File size out of range"); - ret = ARCHIVE_FAILED; - } - - if (format_number(archive_entry_mtime(entry), - h + USTAR_mtime_offset, USTAR_mtime_size, USTAR_mtime_max_size, strict)) { - archive_set_error(&a->archive, ERANGE, - "File modification time too large"); - ret = ARCHIVE_FAILED; - } - - if (archive_entry_filetype(entry) == AE_IFBLK - || archive_entry_filetype(entry) == AE_IFCHR) { - if (format_number(archive_entry_rdevmajor(entry), - h + USTAR_rdevmajor_offset, USTAR_rdevmajor_size, - USTAR_rdevmajor_max_size, strict)) { - archive_set_error(&a->archive, ERANGE, - "Major device number too large"); - ret = ARCHIVE_FAILED; - } - - if (format_number(archive_entry_rdevminor(entry), - h + USTAR_rdevminor_offset, USTAR_rdevminor_size, - USTAR_rdevminor_max_size, strict)) { - archive_set_error(&a->archive, ERANGE, - "Minor device number too large"); - ret = ARCHIVE_FAILED; - } - } - - if (tartype >= 0) { - h[USTAR_typeflag_offset] = tartype; - } else if (mytartype >= 0) { - h[USTAR_typeflag_offset] = mytartype; - } else { - switch (archive_entry_filetype(entry)) { - case AE_IFREG: h[USTAR_typeflag_offset] = '0' ; break; - case AE_IFLNK: h[USTAR_typeflag_offset] = '2' ; break; - case AE_IFCHR: h[USTAR_typeflag_offset] = '3' ; break; - case AE_IFBLK: h[USTAR_typeflag_offset] = '4' ; break; - case AE_IFDIR: h[USTAR_typeflag_offset] = '5' ; break; - case AE_IFIFO: h[USTAR_typeflag_offset] = '6' ; break; - default: /* AE_IFSOCK and unknown */ - __archive_write_entry_filetype_unsupported( - &a->archive, entry, "ustar"); - ret = ARCHIVE_FAILED; - } - } - - checksum = 0; - for (i = 0; i < 512; i++) - checksum += 255 & (unsigned int)h[i]; - h[USTAR_checksum_offset + 6] = '\0'; /* Can't be pre-set in the template. */ - /* h[USTAR_checksum_offset + 7] = ' '; */ /* This is pre-set in the template. */ - format_octal(checksum, h + USTAR_checksum_offset, 6); - return (ret); -} - -/* - * Format a number into a field, with some intelligence. - */ -static int -format_number(int64_t v, char *p, int s, int maxsize, int strict) -{ - int64_t limit; - - limit = ((int64_t)1 << (s*3)); - - /* "Strict" only permits octal values with proper termination. */ - if (strict) - return (format_octal(v, p, s)); - - /* - * In non-strict mode, we allow the number to overwrite one or - * more bytes of the field termination. Even old tar - * implementations should be able to handle this with no - * problem. - */ - if (v >= 0) { - while (s <= maxsize) { - if (v < limit) - return (format_octal(v, p, s)); - s++; - limit <<= 3; - } - } - - /* Base-256 can handle any number, positive or negative. */ - return (format_256(v, p, maxsize)); -} - -/* - * Format a number into the specified field using base-256. - */ -static int -format_256(int64_t v, char *p, int s) -{ - p += s; - while (s-- > 0) { - *--p = (char)(v & 0xff); - v >>= 8; - } - *p |= 0x80; /* Set the base-256 marker bit. */ - return (0); -} - -/* - * Format a number into the specified field. - */ -static int -format_octal(int64_t v, char *p, int s) -{ - int len; - - len = s; - - /* Octal values can't be negative, so use 0. */ - if (v < 0) { - while (len-- > 0) - *p++ = '0'; - return (-1); - } - - p += s; /* Start at the end and work backwards. */ - while (s-- > 0) { - *--p = (char)('0' + (v & 7)); - v >>= 3; - } - - if (v == 0) - return (0); - - /* If it overflowed, fill field with max value. */ - while (len-- > 0) - *p++ = '7'; - - return (-1); -} - -static int -archive_write_ustar_close(struct archive_write *a) -{ - return (__archive_write_nulls(a, 512*2)); -} - -static int -archive_write_ustar_free(struct archive_write *a) -{ - struct ustar *ustar; - - ustar = (struct ustar *)a->format_data; - free(ustar); - a->format_data = NULL; - return (ARCHIVE_OK); -} - -static int -archive_write_ustar_finish_entry(struct archive_write *a) -{ - struct ustar *ustar; - int ret; - - ustar = (struct ustar *)a->format_data; - ret = __archive_write_nulls(a, - (size_t)(ustar->entry_bytes_remaining + ustar->entry_padding)); - ustar->entry_bytes_remaining = ustar->entry_padding = 0; - return (ret); -} - -static ssize_t -archive_write_ustar_data(struct archive_write *a, const void *buff, size_t s) -{ - struct ustar *ustar; - int ret; - - ustar = (struct ustar *)a->format_data; - if (s > ustar->entry_bytes_remaining) - s = (size_t)ustar->entry_bytes_remaining; - ret = __archive_write_output(a, buff, s); - ustar->entry_bytes_remaining -= s; - if (ret != ARCHIVE_OK) - return (ret); - return (s); -} diff --git a/thirdparty/libarchive/libarchive/archive_write_set_format_v7tar.c b/thirdparty/libarchive/libarchive/archive_write_set_format_v7tar.c deleted file mode 100644 index 599407144..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_set_format_v7tar.c +++ /dev/null @@ -1,638 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2011-2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - - -#ifdef HAVE_ERRNO_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" -#include "archive_entry_locale.h" -#include "archive_private.h" -#include "archive_write_private.h" -#include "archive_write_set_format_private.h" - -struct v7tar { - uint64_t entry_bytes_remaining; - uint64_t entry_padding; - - struct archive_string_conv *opt_sconv; - struct archive_string_conv *sconv_default; - int init_default_conversion; -}; - -/* - * Define structure of POSIX 'v7tar' tar header. - */ -#define V7TAR_name_offset 0 -#define V7TAR_name_size 100 -#define V7TAR_mode_offset 100 -#define V7TAR_mode_size 6 -#define V7TAR_mode_max_size 8 -#define V7TAR_uid_offset 108 -#define V7TAR_uid_size 6 -#define V7TAR_uid_max_size 8 -#define V7TAR_gid_offset 116 -#define V7TAR_gid_size 6 -#define V7TAR_gid_max_size 8 -#define V7TAR_size_offset 124 -#define V7TAR_size_size 11 -#define V7TAR_size_max_size 12 -#define V7TAR_mtime_offset 136 -#define V7TAR_mtime_size 11 -#define V7TAR_mtime_max_size 12 -#define V7TAR_checksum_offset 148 -#define V7TAR_checksum_size 8 -#define V7TAR_typeflag_offset 156 -#define V7TAR_typeflag_size 1 -#define V7TAR_linkname_offset 157 -#define V7TAR_linkname_size 100 -#define V7TAR_padding_offset 257 -#define V7TAR_padding_size 255 - -/* - * A filled-in copy of the header for initialization. - */ -static const char template_header[] = { - /* name: 100 bytes */ - 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,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, - /* Mode, space-null termination: 8 bytes */ - '0','0','0','0','0','0', ' ','\0', - /* uid, space-null termination: 8 bytes */ - '0','0','0','0','0','0', ' ','\0', - /* gid, space-null termination: 8 bytes */ - '0','0','0','0','0','0', ' ','\0', - /* size, space termination: 12 bytes */ - '0','0','0','0','0','0','0','0','0','0','0', ' ', - /* mtime, space termination: 12 bytes */ - '0','0','0','0','0','0','0','0','0','0','0', ' ', - /* Initial checksum value: 8 spaces */ - ' ',' ',' ',' ',' ',' ',' ',' ', - /* Typeflag: 1 byte */ - 0, - /* Linkname: 100 bytes */ - 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,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, - /* Padding: 255 bytes */ - 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,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,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,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,0,0,0 -}; - -static ssize_t archive_write_v7tar_data(struct archive_write *a, const void *buff, - size_t s); -static int archive_write_v7tar_free(struct archive_write *); -static int archive_write_v7tar_close(struct archive_write *); -static int archive_write_v7tar_finish_entry(struct archive_write *); -static int archive_write_v7tar_header(struct archive_write *, - struct archive_entry *entry); -static int archive_write_v7tar_options(struct archive_write *, - const char *, const char *); -static int format_256(int64_t, char *, int); -static int format_number(int64_t, char *, int size, int max, int strict); -static int format_octal(int64_t, char *, int); -static int format_header_v7tar(struct archive_write *, char h[512], - struct archive_entry *, int, struct archive_string_conv *); - -/* - * Set output format to 'v7tar' format. - */ -int -archive_write_set_format_v7tar(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - struct v7tar *v7tar; - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_set_format_v7tar"); - - /* If someone else was already registered, unregister them. */ - if (a->format_free != NULL) - (a->format_free)(a); - - /* Basic internal sanity test. */ - if (sizeof(template_header) != 512) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Internal: template_header wrong size: %zu should be 512", - sizeof(template_header)); - return (ARCHIVE_FATAL); - } - - v7tar = (struct v7tar *)calloc(1, sizeof(*v7tar)); - if (v7tar == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate v7tar data"); - return (ARCHIVE_FATAL); - } - a->format_data = v7tar; - a->format_name = "tar (non-POSIX)"; - a->format_options = archive_write_v7tar_options; - a->format_write_header = archive_write_v7tar_header; - a->format_write_data = archive_write_v7tar_data; - a->format_close = archive_write_v7tar_close; - a->format_free = archive_write_v7tar_free; - a->format_finish_entry = archive_write_v7tar_finish_entry; - a->archive.archive_format = ARCHIVE_FORMAT_TAR; - a->archive.archive_format_name = "tar (non-POSIX)"; - return (ARCHIVE_OK); -} - -static int -archive_write_v7tar_options(struct archive_write *a, const char *key, - const char *val) -{ - struct v7tar *v7tar = (struct v7tar *)a->format_data; - int ret = ARCHIVE_FAILED; - - if (strcmp(key, "hdrcharset") == 0) { - if (val == NULL || val[0] == 0) - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "%s: hdrcharset option needs a character-set name", - a->format_name); - else { - v7tar->opt_sconv = archive_string_conversion_to_charset( - &a->archive, val, 0); - if (v7tar->opt_sconv != NULL) - ret = ARCHIVE_OK; - else - ret = ARCHIVE_FATAL; - } - return (ret); - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -static int -archive_write_v7tar_header(struct archive_write *a, struct archive_entry *entry) -{ - char buff[512]; - int ret, ret2; - struct v7tar *v7tar; - struct archive_entry *entry_main; - struct archive_string_conv *sconv; - - v7tar = (struct v7tar *)a->format_data; - - /* Setup default string conversion. */ - if (v7tar->opt_sconv == NULL) { - if (!v7tar->init_default_conversion) { - v7tar->sconv_default = - archive_string_default_conversion_for_write( - &(a->archive)); - v7tar->init_default_conversion = 1; - } - sconv = v7tar->sconv_default; - } else - sconv = v7tar->opt_sconv; - - /* Sanity check. */ - if (archive_entry_pathname(entry) == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Can't record entry in tar file without pathname"); - return (ARCHIVE_FAILED); - } - - /* Only regular files (not hardlinks) have data. */ - if (archive_entry_hardlink(entry) != NULL || - archive_entry_symlink(entry) != NULL || - !(archive_entry_filetype(entry) == AE_IFREG)) - archive_entry_set_size(entry, 0); - - if (AE_IFDIR == archive_entry_filetype(entry)) { - const char *p; - size_t path_length; - /* - * Ensure a trailing '/'. Modify the entry so - * the client sees the change. - */ -#if defined(_WIN32) && !defined(__CYGWIN__) - const wchar_t *wp; - - wp = archive_entry_pathname_w(entry); - if (wp != NULL && wp[wcslen(wp) -1] != L'/') { - struct archive_wstring ws; - - archive_string_init(&ws); - path_length = wcslen(wp); - if (archive_wstring_ensure(&ws, - path_length + 2) == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate v7tar data"); - archive_wstring_free(&ws); - return(ARCHIVE_FATAL); - } - /* Should we keep '\' ? */ - if (wp[path_length -1] == L'\\') - path_length--; - archive_wstrncpy(&ws, wp, path_length); - archive_wstrappend_wchar(&ws, L'/'); - archive_entry_copy_pathname_w(entry, ws.s); - archive_wstring_free(&ws); - p = NULL; - } else -#endif - p = archive_entry_pathname(entry); - /* - * On Windows, this is a backup operation just in - * case getting WCS failed. On POSIX, this is a - * normal operation. - */ - if (p != NULL && p[0] != '\0' && p[strlen(p) - 1] != '/') { - struct archive_string as; - - archive_string_init(&as); - path_length = strlen(p); - if (archive_string_ensure(&as, - path_length + 2) == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate v7tar data"); - archive_string_free(&as); - return(ARCHIVE_FATAL); - } -#if defined(_WIN32) && !defined(__CYGWIN__) - /* NOTE: This might break the pathname - * if the current code page is CP932 and - * the pathname includes a character '\' - * as a part of its multibyte pathname. */ - if (p[strlen(p) -1] == '\\') - path_length--; - else -#endif - archive_strncpy(&as, p, path_length); - archive_strappend_char(&as, '/'); - archive_entry_copy_pathname(entry, as.s); - archive_string_free(&as); - } - } - -#if defined(_WIN32) && !defined(__CYGWIN__) - /* Make sure the path separators in pathname, hardlink and symlink - * are all slash '/', not the Windows path separator '\'. */ - entry_main = __la_win_entry_in_posix_pathseparator(entry); - if (entry_main == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate v7tar data"); - return(ARCHIVE_FATAL); - } - if (entry != entry_main) - entry = entry_main; - else - entry_main = NULL; -#else - entry_main = NULL; -#endif - ret = format_header_v7tar(a, buff, entry, 1, sconv); - if (ret < ARCHIVE_WARN) { - archive_entry_free(entry_main); - return (ret); - } - ret2 = __archive_write_output(a, buff, 512); - if (ret2 < ARCHIVE_WARN) { - archive_entry_free(entry_main); - return (ret2); - } - if (ret2 < ret) - ret = ret2; - - v7tar->entry_bytes_remaining = archive_entry_size(entry); - v7tar->entry_padding = 0x1ff & (-(int64_t)v7tar->entry_bytes_remaining); - archive_entry_free(entry_main); - return (ret); -} - -/* - * Format a basic 512-byte "v7tar" header. - * - * Returns -1 if format failed (due to field overflow). - * Note that this always formats as much of the header as possible. - * If "strict" is set to zero, it will extend numeric fields as - * necessary (overwriting terminators or using base-256 extensions). - * - */ -static int -format_header_v7tar(struct archive_write *a, char h[512], - struct archive_entry *entry, int strict, - struct archive_string_conv *sconv) -{ - unsigned int checksum; - int i, r, ret; - size_t copy_length; - const char *p, *pp; - int mytartype; - - ret = 0; - mytartype = -1; - /* - * The "template header" already includes the "v7tar" - * signature, various end-of-field markers and other required - * elements. - */ - memcpy(h, &template_header, 512); - - /* - * Because the block is already null-filled, and strings - * are allowed to exactly fill their destination (without null), - * I use memcpy(dest, src, strlen()) here a lot to copy strings. - */ - r = archive_entry_pathname_l(entry, &pp, ©_length, sconv); - if (r != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Pathname"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate pathname '%s' to %s", - pp, archive_string_conversion_charset_name(sconv)); - ret = ARCHIVE_WARN; - } - if (strict && copy_length < V7TAR_name_size) - memcpy(h + V7TAR_name_offset, pp, copy_length); - else if (!strict && copy_length <= V7TAR_name_size) - memcpy(h + V7TAR_name_offset, pp, copy_length); - else { - /* Prefix is too long. */ - archive_set_error(&a->archive, ENAMETOOLONG, - "Pathname too long"); - ret = ARCHIVE_FAILED; - } - - r = archive_entry_hardlink_l(entry, &p, ©_length, sconv); - if (r != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Linkname"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate linkname '%s' to %s", - p, archive_string_conversion_charset_name(sconv)); - ret = ARCHIVE_WARN; - } - if (copy_length > 0) - mytartype = '1'; - else { - r = archive_entry_symlink_l(entry, &p, ©_length, sconv); - if (r != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Linkname"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate linkname '%s' to %s", - p, archive_string_conversion_charset_name(sconv)); - ret = ARCHIVE_WARN; - } - } - if (copy_length > 0) { - if (copy_length >= V7TAR_linkname_size) { - archive_set_error(&a->archive, ENAMETOOLONG, - "Link contents too long"); - ret = ARCHIVE_FAILED; - copy_length = V7TAR_linkname_size; - } - memcpy(h + V7TAR_linkname_offset, p, copy_length); - } - - if (format_number(archive_entry_mode(entry) & 07777, - h + V7TAR_mode_offset, V7TAR_mode_size, - V7TAR_mode_max_size, strict)) { - archive_set_error(&a->archive, ERANGE, - "Numeric mode too large"); - ret = ARCHIVE_FAILED; - } - - if (format_number(archive_entry_uid(entry), - h + V7TAR_uid_offset, V7TAR_uid_size, V7TAR_uid_max_size, strict)) { - archive_set_error(&a->archive, ERANGE, - "Numeric user ID too large"); - ret = ARCHIVE_FAILED; - } - - if (format_number(archive_entry_gid(entry), - h + V7TAR_gid_offset, V7TAR_gid_size, V7TAR_gid_max_size, strict)) { - archive_set_error(&a->archive, ERANGE, - "Numeric group ID too large"); - ret = ARCHIVE_FAILED; - } - - if (format_number(archive_entry_size(entry), - h + V7TAR_size_offset, V7TAR_size_size, - V7TAR_size_max_size, strict)) { - archive_set_error(&a->archive, ERANGE, - "File size out of range"); - ret = ARCHIVE_FAILED; - } - - if (format_number(archive_entry_mtime(entry), - h + V7TAR_mtime_offset, V7TAR_mtime_size, - V7TAR_mtime_max_size, strict)) { - archive_set_error(&a->archive, ERANGE, - "File modification time too large"); - ret = ARCHIVE_FAILED; - } - - if (mytartype >= 0) { - h[V7TAR_typeflag_offset] = mytartype; - } else { - switch (archive_entry_filetype(entry)) { - case AE_IFREG: case AE_IFDIR: - break; - case AE_IFLNK: - h[V7TAR_typeflag_offset] = '2'; - break; - default: - /* AE_IFBLK, AE_IFCHR, AE_IFIFO, AE_IFSOCK - * and unknown */ - __archive_write_entry_filetype_unsupported( - &a->archive, entry, "v7tar"); - ret = ARCHIVE_FAILED; - } - } - - checksum = 0; - for (i = 0; i < 512; i++) - checksum += 255 & (unsigned int)h[i]; - format_octal(checksum, h + V7TAR_checksum_offset, 6); - /* Can't be pre-set in the template. */ - h[V7TAR_checksum_offset + 6] = '\0'; - return (ret); -} - -/* - * Format a number into a field, with some intelligence. - */ -static int -format_number(int64_t v, char *p, int s, int maxsize, int strict) -{ - int64_t limit; - - limit = ((int64_t)1 << (s*3)); - - /* "Strict" only permits octal values with proper termination. */ - if (strict) - return (format_octal(v, p, s)); - - /* - * In non-strict mode, we allow the number to overwrite one or - * more bytes of the field termination. Even old tar - * implementations should be able to handle this with no - * problem. - */ - if (v >= 0) { - while (s <= maxsize) { - if (v < limit) - return (format_octal(v, p, s)); - s++; - limit <<= 3; - } - } - - /* Base-256 can handle any number, positive or negative. */ - return (format_256(v, p, maxsize)); -} - -/* - * Format a number into the specified field using base-256. - */ -static int -format_256(int64_t v, char *p, int s) -{ - p += s; - while (s-- > 0) { - *--p = (char)(v & 0xff); - v >>= 8; - } - *p |= 0x80; /* Set the base-256 marker bit. */ - return (0); -} - -/* - * Format a number into the specified field. - */ -static int -format_octal(int64_t v, char *p, int s) -{ - int len; - - len = s; - - /* Octal values can't be negative, so use 0. */ - if (v < 0) { - while (len-- > 0) - *p++ = '0'; - return (-1); - } - - p += s; /* Start at the end and work backwards. */ - while (s-- > 0) { - *--p = (char)('0' + (v & 7)); - v >>= 3; - } - - if (v == 0) - return (0); - - /* If it overflowed, fill field with max value. */ - while (len-- > 0) - *p++ = '7'; - - return (-1); -} - -static int -archive_write_v7tar_close(struct archive_write *a) -{ - return (__archive_write_nulls(a, 512*2)); -} - -static int -archive_write_v7tar_free(struct archive_write *a) -{ - struct v7tar *v7tar; - - v7tar = (struct v7tar *)a->format_data; - free(v7tar); - a->format_data = NULL; - return (ARCHIVE_OK); -} - -static int -archive_write_v7tar_finish_entry(struct archive_write *a) -{ - struct v7tar *v7tar; - int ret; - - v7tar = (struct v7tar *)a->format_data; - ret = __archive_write_nulls(a, - (size_t)(v7tar->entry_bytes_remaining + v7tar->entry_padding)); - v7tar->entry_bytes_remaining = v7tar->entry_padding = 0; - return (ret); -} - -static ssize_t -archive_write_v7tar_data(struct archive_write *a, const void *buff, size_t s) -{ - struct v7tar *v7tar; - int ret; - - v7tar = (struct v7tar *)a->format_data; - if (s > v7tar->entry_bytes_remaining) - s = (size_t)v7tar->entry_bytes_remaining; - ret = __archive_write_output(a, buff, s); - v7tar->entry_bytes_remaining -= s; - if (ret != ARCHIVE_OK) - return (ret); - return (s); -} diff --git a/thirdparty/libarchive/libarchive/archive_write_set_format_warc.c b/thirdparty/libarchive/libarchive/archive_write_set_format_warc.c deleted file mode 100644 index 0ef003e2f..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_set_format_warc.c +++ /dev/null @@ -1,444 +0,0 @@ -/*- - * Copyright (c) 2014 Sebastian Freundt - * Author: Sebastian Freundt - * - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_TIME_H -#include -#endif - -#include "archive.h" -#include "archive_entry.h" -#include "archive_entry_locale.h" -#include "archive_private.h" -#include "archive_random_private.h" -#include "archive_write_private.h" -#include "archive_write_set_format_private.h" - -struct warc_s { - unsigned int omit_warcinfo:1; - - time_t now; - mode_t typ; - unsigned int rng; - /* populated size */ - uint64_t populz; -}; - -static const char warcinfo[] = - "software: libarchive/" ARCHIVE_VERSION_ONLY_STRING "\r\n" - "format: WARC file version 1.0\r\n"; - -typedef enum { - WT_NONE, - /* warcinfo */ - WT_INFO, - /* metadata */ - WT_META, - /* resource */ - WT_RSRC, - /* request, unsupported */ - WT_REQ, - /* response, unsupported */ - WT_RSP, - /* revisit, unsupported */ - WT_RVIS, - /* conversion, unsupported */ - WT_CONV, - /* continuation, unsupported at the moment */ - WT_CONT, - /* invalid type */ - LAST_WT -} warc_type_t; - -typedef struct { - warc_type_t type; - const char *tgturi; - const char *recid; - time_t rtime; - time_t mtime; - const char *cnttyp; - uint64_t cntlen; -} warc_essential_hdr_t; - -typedef struct { - unsigned int u[4U]; -} warc_uuid_t; - -static int _warc_options(struct archive_write*, const char *key, const char *v); -static int _warc_header(struct archive_write *a, struct archive_entry *entry); -static ssize_t _warc_data(struct archive_write *a, const void *buf, size_t sz); -static int _warc_finish_entry(struct archive_write *a); -static int _warc_close(struct archive_write *a); -static int _warc_free(struct archive_write *a); - -/* private routines */ -static ssize_t _popul_ehdr(struct archive_string *t, size_t z, warc_essential_hdr_t); -static int _gen_uuid(warc_uuid_t *tgt); - - -/* - * Set output format to ISO 28500 (aka WARC) format. - */ -int -archive_write_set_format_warc(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - struct warc_s *w; - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_set_format_warc"); - - /* If another format was already registered, unregister it. */ - if (a->format_free != NULL) { - (a->format_free)(a); - } - - w = malloc(sizeof(*w)); - if (w == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate warc data"); - return (ARCHIVE_FATAL); - } - /* by default we're emitting a file wide header */ - w->omit_warcinfo = 0U; - /* obtain current time for date fields */ - w->now = time(NULL); - /* reset file type info */ - w->typ = 0; - /* also initialise our rng */ - w->rng = (unsigned int)w->now; - - a->format_data = w; - a->format_name = "WARC/1.0"; - a->format_options = _warc_options; - a->format_write_header = _warc_header; - a->format_write_data = _warc_data; - a->format_close = _warc_close; - a->format_free = _warc_free; - a->format_finish_entry = _warc_finish_entry; - a->archive.archive_format = ARCHIVE_FORMAT_WARC; - a->archive.archive_format_name = "WARC/1.0"; - return (ARCHIVE_OK); -} - - -/* archive methods */ -static int -_warc_options(struct archive_write *a, const char *key, const char *val) -{ - struct warc_s *w = a->format_data; - - if (strcmp(key, "omit-warcinfo") == 0) { - if (val == NULL || strcmp(val, "true") == 0) { - /* great */ - w->omit_warcinfo = 1U; - return (ARCHIVE_OK); - } - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -static int -_warc_header(struct archive_write *a, struct archive_entry *entry) -{ - struct warc_s *w = a->format_data; - struct archive_string hdr; -#define MAX_HDR_SIZE 512 - - /* check whether warcinfo record needs outputting */ - if (!w->omit_warcinfo) { - ssize_t r; - warc_essential_hdr_t wi = { - WT_INFO, - /*uri*/NULL, - /*urn*/NULL, - /*rtm*/0, - /*mtm*/0, - /*cty*/"application/warc-fields", - /*len*/sizeof(warcinfo) - 1U, - }; - wi.rtime = w->now; - wi.mtime = w->now; - - archive_string_init(&hdr); - r = _popul_ehdr(&hdr, MAX_HDR_SIZE, wi); - if (r >= 0) { - /* jackpot! */ - /* now also use HDR buffer for the actual warcinfo */ - archive_strncat(&hdr, warcinfo, sizeof(warcinfo) -1); - - /* append end-of-record indicator */ - archive_strncat(&hdr, "\r\n\r\n", 4); - - /* write to output stream */ - __archive_write_output(a, hdr.s, archive_strlen(&hdr)); - } - /* indicate we're done with file header writing */ - w->omit_warcinfo = 1U; - archive_string_free(&hdr); - } - - if (archive_entry_pathname(entry) == NULL) { - archive_set_error(&a->archive, EINVAL, - "Invalid filename"); - return (ARCHIVE_WARN); - } - - w->typ = archive_entry_filetype(entry); - w->populz = 0U; - if (w->typ == AE_IFREG) { - warc_essential_hdr_t rh = { - WT_RSRC, - /*uri*/NULL, - /*urn*/NULL, - /*rtm*/0, - /*mtm*/0, - /*cty*/NULL, - /*len*/0, - }; - ssize_t r; - rh.tgturi = archive_entry_pathname(entry); - rh.rtime = w->now; - rh.mtime = archive_entry_mtime(entry); - rh.cntlen = (size_t)archive_entry_size(entry); - - archive_string_init(&hdr); - r = _popul_ehdr(&hdr, MAX_HDR_SIZE, rh); - if (r < 0) { - /* don't bother */ - archive_set_error( - &a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "cannot archive file"); - return (ARCHIVE_WARN); - } - /* otherwise append to output stream */ - __archive_write_output(a, hdr.s, r); - /* and let subsequent calls to _data() know about the size */ - w->populz = rh.cntlen; - archive_string_free(&hdr); - return (ARCHIVE_OK); - } - /* just resort to erroring as per Tim's advice */ - __archive_write_entry_filetype_unsupported( - &a->archive, entry, "WARC"); - return (ARCHIVE_FAILED); -} - -static ssize_t -_warc_data(struct archive_write *a, const void *buf, size_t len) -{ - struct warc_s *w = a->format_data; - - if (w->typ == AE_IFREG) { - int rc; - - /* never write more bytes than announced */ - if (len > w->populz) { - len = (size_t)w->populz; - } - - /* now then, out we put the whole shebang */ - rc = __archive_write_output(a, buf, len); - if (rc != ARCHIVE_OK) { - return rc; - } - } - return len; -} - -static int -_warc_finish_entry(struct archive_write *a) -{ - static const char _eor[] = "\r\n\r\n"; - struct warc_s *w = a->format_data; - - if (w->typ == AE_IFREG) { - int rc = __archive_write_output(a, _eor, sizeof(_eor) - 1U); - - if (rc != ARCHIVE_OK) { - return rc; - } - } - /* reset type info */ - w->typ = 0; - return (ARCHIVE_OK); -} - -static int -_warc_close(struct archive_write *a) -{ - (void)a; /* UNUSED */ - return (ARCHIVE_OK); -} - -static int -_warc_free(struct archive_write *a) -{ - struct warc_s *w = a->format_data; - - free(w); - a->format_data = NULL; - return (ARCHIVE_OK); -} - - -/* private routines */ -static void -xstrftime(struct archive_string *as, const char *fmt, time_t t) -{ -/** like strftime(3) but for time_t objects */ - struct tm *rt; -#if defined(HAVE_GMTIME_R) || defined(HAVE_GMTIME_S) - struct tm timeHere; -#endif - char strtime[100]; - size_t len; - -#if defined(HAVE_GMTIME_S) - rt = gmtime_s(&timeHere, &t) ? NULL : &timeHere; -#elif defined(HAVE_GMTIME_R) - rt = gmtime_r(&t, &timeHere); -#else - rt = gmtime(&t); -#endif - if (!rt) - return; - /* leave the hard yacker to our role model strftime() */ - len = strftime(strtime, sizeof(strtime)-1, fmt, rt); - archive_strncat(as, strtime, len); -} - -static ssize_t -_popul_ehdr(struct archive_string *tgt, size_t tsz, warc_essential_hdr_t hdr) -{ - static const char _ver[] = "WARC/1.0\r\n"; - static const char * const _typ[LAST_WT] = { - NULL, "warcinfo", "metadata", "resource", NULL - }; - char std_uuid[48U]; - - if (hdr.type == WT_NONE || hdr.type > WT_RSRC) { - /* brilliant, how exactly did we get here? */ - return -1; - } - - archive_strcpy(tgt, _ver); - - archive_string_sprintf(tgt, "WARC-Type: %s\r\n", _typ[hdr.type]); - - if (hdr.tgturi != NULL) { - /* check if there's a xyz:// */ - static const char _uri[] = ""; - static const char _fil[] = "file://"; - const char *u; - char *chk = strchr(hdr.tgturi, ':'); - - if (chk != NULL && chk[1U] == '/' && chk[2U] == '/') { - /* yep, it's definitely a URI */ - u = _uri; - } else { - /* hm, best to prepend file:// then */ - u = _fil; - } - archive_string_sprintf(tgt, - "WARC-Target-URI: %s%s\r\n", u, hdr.tgturi); - } - - /* record time is usually when the http is sent off, - * just treat the archive writing as such for a moment */ - xstrftime(tgt, "WARC-Date: %Y-%m-%dT%H:%M:%SZ\r\n", hdr.rtime); - - /* while we're at it, record the mtime */ - xstrftime(tgt, "Last-Modified: %Y-%m-%dT%H:%M:%SZ\r\n", hdr.mtime); - - if (hdr.recid == NULL) { - /* generate one, grrrr */ - warc_uuid_t u; - - _gen_uuid(&u); - /* Unfortunately, archive_string_sprintf does not - * handle the minimum number following '%'. - * So we have to use snprintf function here instead - * of archive_string_snprintf function. */ -#if defined(_WIN32) && !defined(__CYGWIN__) && !( defined(_MSC_VER) && _MSC_VER >= 1900) -#define snprintf _snprintf -#endif - snprintf( - std_uuid, sizeof(std_uuid), - "", - u.u[0U], - u.u[1U] >> 16U, u.u[1U] & 0xffffU, - u.u[2U] >> 16U, u.u[2U] & 0xffffU, - u.u[3U]); - hdr.recid = std_uuid; - } - - /* record-id is mandatory, fingers crossed we won't fail */ - archive_string_sprintf(tgt, "WARC-Record-ID: %s\r\n", hdr.recid); - - if (hdr.cnttyp != NULL) { - archive_string_sprintf(tgt, "Content-Type: %s\r\n", hdr.cnttyp); - } - - /* next one is mandatory */ - archive_string_sprintf(tgt, "Content-Length: %ju\r\n", (uintmax_t)hdr.cntlen); - /**/ - archive_strncat(tgt, "\r\n", 2); - - return (archive_strlen(tgt) >= tsz)? -1: (ssize_t)archive_strlen(tgt); -} - -static int -_gen_uuid(warc_uuid_t *tgt) -{ - archive_random(tgt->u, sizeof(tgt->u)); - /* obey uuid version 4 rules */ - tgt->u[1U] &= 0xffff0fffU; - tgt->u[1U] |= 0x4000U; - tgt->u[2U] &= 0x3fffffffU; - tgt->u[2U] |= 0x80000000U; - return 0; -} - -/* archive_write_set_format_warc.c ends here */ diff --git a/thirdparty/libarchive/libarchive/archive_write_set_format_xar.c b/thirdparty/libarchive/libarchive/archive_write_set_format_xar.c deleted file mode 100644 index 7307757d3..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_set_format_xar.c +++ /dev/null @@ -1,3255 +0,0 @@ -/*- - * Copyright (c) 2010-2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_LIMITS_H -#include -#endif -#include -#if HAVE_LIBXML_XMLWRITER_H -#include -#endif -#ifdef HAVE_BZLIB_H -#include -#endif -#if HAVE_LZMA_H -#include -#endif -#ifdef HAVE_ZLIB_H -#include -#endif - -#include "archive.h" -#include "archive_digest_private.h" -#include "archive_endian.h" -#include "archive_entry.h" -#include "archive_entry_locale.h" -#include "archive_private.h" -#include "archive_rb.h" -#include "archive_string.h" -#include "archive_write_private.h" - -/* - * Differences to xar utility. - * - Subdocument is not supported yet. - * - ACL is not supported yet. - * - When writing an XML element , - * which is a file type a symbolic link is referencing is always marked - * as "broken". Xar utility uses stat(2) to get the file type, but, in - * libarchive format writer, we should not use it; if it is needed, we - * should get about it at archive_read_disk.c. - * - It is possible to appear both and elements. - * Xar utility generates on BSD platform and on Linux - * platform. - * - */ - -#if !(defined(HAVE_LIBXML_XMLWRITER_H) && defined(LIBXML_VERSION) &&\ - LIBXML_VERSION >= 20703) ||\ - !defined(HAVE_ZLIB_H) || \ - !defined(ARCHIVE_HAS_MD5) || !defined(ARCHIVE_HAS_SHA1) -/* - * xar needs several external libraries. - * o libxml2 - * o openssl or MD5/SHA1 hash function - * o zlib - * o bzlib2 (option) - * o liblzma (option) - */ -int -archive_write_set_format_xar(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Xar not supported on this platform"); - return (ARCHIVE_WARN); -} - -#else /* Support xar format */ - -/*#define DEBUG_PRINT_TOC 1 */ - -#define BAD_CAST_CONST (const xmlChar *) - -#define HEADER_MAGIC 0x78617221 -#define HEADER_SIZE 28 -#define HEADER_VERSION 1 - -enum sumalg { - CKSUM_NONE = 0, - CKSUM_SHA1 = 1, - CKSUM_MD5 = 2 -}; - -#define MD5_SIZE 16 -#define SHA1_SIZE 20 -#define MAX_SUM_SIZE 20 -#define MD5_NAME "md5" -#define SHA1_NAME "sha1" - -enum enctype { - NONE, - GZIP, - BZIP2, - LZMA, - XZ, -}; - -struct chksumwork { - enum sumalg alg; -#ifdef ARCHIVE_HAS_MD5 - archive_md5_ctx md5ctx; -#endif -#ifdef ARCHIVE_HAS_SHA1 - archive_sha1_ctx sha1ctx; -#endif -}; - -enum la_zaction { - ARCHIVE_Z_FINISH, - ARCHIVE_Z_RUN -}; - -/* - * Universal zstream. - */ -struct la_zstream { - const unsigned char *next_in; - size_t avail_in; - uint64_t total_in; - - unsigned char *next_out; - size_t avail_out; - uint64_t total_out; - - int valid; - void *real_stream; - int (*code) (struct archive *a, - struct la_zstream *lastrm, - enum la_zaction action); - int (*end)(struct archive *a, - struct la_zstream *lastrm); -}; - -struct chksumval { - enum sumalg alg; - size_t len; - unsigned char val[MAX_SUM_SIZE]; -}; - -struct heap_data { - int id; - struct heap_data *next; - uint64_t temp_offset; - uint64_t length; /* archived size. */ - uint64_t size; /* extracted size. */ - enum enctype compression; - struct chksumval a_sum; /* archived checksum. */ - struct chksumval e_sum; /* extracted checksum. */ -}; - -struct file { - struct archive_rb_node rbnode; - - int id; - struct archive_entry *entry; - - struct archive_rb_tree rbtree; - struct file *next; - struct file *chnext; - struct file *hlnext; - /* For hardlinked files. - * Use only when archive_entry_nlink() > 1 */ - struct file *hardlink_target; - struct file *parent; /* parent directory entry */ - /* - * To manage sub directory files. - * We use 'chnext' (a member of struct file) to chain. - */ - struct { - struct file *first; - struct file **last; - } children; - - /* For making a directory tree. */ - struct archive_string parentdir; - struct archive_string basename; - struct archive_string symlink; - - int ea_idx; - struct { - struct heap_data *first; - struct heap_data **last; - } xattr; - struct heap_data data; - struct archive_string script; - - unsigned int virtual:1; - unsigned int dir:1; -}; - -struct hardlink { - struct archive_rb_node rbnode; - int nlink; - struct { - struct file *first; - struct file **last; - } file_list; -}; - -struct xar { - int temp_fd; - uint64_t temp_offset; - - int file_idx; - struct file *root; - struct file *cur_dirent; - struct archive_string cur_dirstr; - struct file *cur_file; - uint64_t bytes_remaining; - struct archive_string tstr; - struct archive_string vstr; - - enum sumalg opt_toc_sumalg; - enum sumalg opt_sumalg; - enum enctype opt_compression; - int opt_compression_level; - uint32_t opt_threads; - - struct chksumwork a_sumwrk; /* archived checksum. */ - struct chksumwork e_sumwrk; /* extracted checksum. */ - struct la_zstream stream; - struct archive_string_conv *sconv; - /* - * Compressed data buffer. - */ - unsigned char wbuff[1024 * 64]; - size_t wbuff_remaining; - - struct heap_data toc; - /* - * The list of all file entries is used to manage struct file - * objects. - * We use 'next' (a member of struct file) to chain. - */ - struct { - struct file *first; - struct file **last; - } file_list; - /* - * The list of hard-linked file entries. - * We use 'hlnext' (a member of struct file) to chain. - */ - struct archive_rb_tree hardlink_rbtree; -}; - -static int xar_options(struct archive_write *, - const char *, const char *); -static int xar_write_header(struct archive_write *, - struct archive_entry *); -static ssize_t xar_write_data(struct archive_write *, - const void *, size_t); -static int xar_finish_entry(struct archive_write *); -static int xar_close(struct archive_write *); -static int xar_free(struct archive_write *); - -static struct file *file_new(struct archive_write *a, struct archive_entry *); -static void file_free(struct file *); -static struct file *file_create_virtual_dir(struct archive_write *a, struct xar *, - const char *); -static int file_add_child_tail(struct file *, struct file *); -static struct file *file_find_child(struct file *, const char *); -static int file_gen_utility_names(struct archive_write *, - struct file *); -static int get_path_component(char *, int, const char *); -static int file_tree(struct archive_write *, struct file **); -static void file_register(struct xar *, struct file *); -static void file_init_register(struct xar *); -static void file_free_register(struct xar *); -static int file_register_hardlink(struct archive_write *, - struct file *); -static void file_connect_hardlink_files(struct xar *); -static void file_init_hardlinks(struct xar *); -static void file_free_hardlinks(struct xar *); - -static void checksum_init(struct chksumwork *, enum sumalg); -static void checksum_update(struct chksumwork *, const void *, size_t); -static void checksum_final(struct chksumwork *, struct chksumval *); -static int compression_init_encoder_gzip(struct archive *, - struct la_zstream *, int, int); -static int compression_code_gzip(struct archive *, - struct la_zstream *, enum la_zaction); -static int compression_end_gzip(struct archive *, struct la_zstream *); -static int compression_init_encoder_bzip2(struct archive *, - struct la_zstream *, int); -#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) -static int compression_code_bzip2(struct archive *, - struct la_zstream *, enum la_zaction); -static int compression_end_bzip2(struct archive *, struct la_zstream *); -#endif -static int compression_init_encoder_lzma(struct archive *, - struct la_zstream *, int); -static int compression_init_encoder_xz(struct archive *, - struct la_zstream *, int, int); -#if defined(HAVE_LZMA_H) -static int compression_code_lzma(struct archive *, - struct la_zstream *, enum la_zaction); -static int compression_end_lzma(struct archive *, struct la_zstream *); -#endif -static int xar_compression_init_encoder(struct archive_write *); -static int compression_code(struct archive *, - struct la_zstream *, enum la_zaction); -static int compression_end(struct archive *, - struct la_zstream *); -static int save_xattrs(struct archive_write *, struct file *); -static int getalgsize(enum sumalg); -static const char *getalgname(enum sumalg); - -int -archive_write_set_format_xar(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - struct xar *xar; - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_set_format_xar"); - - /* If another format was already registered, unregister it. */ - if (a->format_free != NULL) - (a->format_free)(a); - - xar = calloc(1, sizeof(*xar)); - if (xar == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate xar data"); - return (ARCHIVE_FATAL); - } - xar->temp_fd = -1; - file_init_register(xar); - file_init_hardlinks(xar); - archive_string_init(&(xar->tstr)); - archive_string_init(&(xar->vstr)); - - /* - * Create the root directory. - */ - xar->root = file_create_virtual_dir(a, xar, ""); - if (xar->root == NULL) { - free(xar); - archive_set_error(&a->archive, ENOMEM, - "Can't allocate xar data"); - return (ARCHIVE_FATAL); - } - xar->root->parent = xar->root; - file_register(xar, xar->root); - xar->cur_dirent = xar->root; - archive_string_init(&(xar->cur_dirstr)); - archive_string_ensure(&(xar->cur_dirstr), 1); - xar->cur_dirstr.s[0] = 0; - - /* - * Initialize option. - */ - /* Set default checksum type. */ - xar->opt_toc_sumalg = CKSUM_SHA1; - xar->opt_sumalg = CKSUM_SHA1; - /* Set default compression type, level, and number of threads. */ - xar->opt_compression = GZIP; - xar->opt_compression_level = 6; - xar->opt_threads = 1; - - a->format_data = xar; - - a->format_name = "xar"; - a->format_options = xar_options; - a->format_write_header = xar_write_header; - a->format_write_data = xar_write_data; - a->format_finish_entry = xar_finish_entry; - a->format_close = xar_close; - a->format_free = xar_free; - a->archive.archive_format = ARCHIVE_FORMAT_XAR; - a->archive.archive_format_name = "xar"; - - return (ARCHIVE_OK); -} - -static int -xar_options(struct archive_write *a, const char *key, const char *value) -{ - struct xar *xar; - - xar = (struct xar *)a->format_data; - - if (strcmp(key, "checksum") == 0) { - if (value == NULL) - xar->opt_sumalg = CKSUM_NONE; - else if (strcmp(value, "none") == 0) - xar->opt_sumalg = CKSUM_NONE; - else if (strcmp(value, "sha1") == 0) - xar->opt_sumalg = CKSUM_SHA1; - else if (strcmp(value, "md5") == 0) - xar->opt_sumalg = CKSUM_MD5; - else { - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, - "Unknown checksum name: `%s'", - value); - return (ARCHIVE_FAILED); - } - return (ARCHIVE_OK); - } - if (strcmp(key, "compression") == 0) { - const char *name = NULL; - - if (value == NULL) - xar->opt_compression = NONE; - else if (strcmp(value, "none") == 0) - xar->opt_compression = NONE; - else if (strcmp(value, "gzip") == 0) - xar->opt_compression = GZIP; - else if (strcmp(value, "bzip2") == 0) -#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) - xar->opt_compression = BZIP2; -#else - name = "bzip2"; -#endif - else if (strcmp(value, "lzma") == 0) -#if HAVE_LZMA_H - xar->opt_compression = LZMA; -#else - name = "lzma"; -#endif - else if (strcmp(value, "xz") == 0) -#if HAVE_LZMA_H - xar->opt_compression = XZ; -#else - name = "xz"; -#endif - else { - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, - "Unknown compression name: `%s'", - value); - return (ARCHIVE_FAILED); - } - if (name != NULL) { - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, - "`%s' compression not supported " - "on this platform", - name); - return (ARCHIVE_FAILED); - } - return (ARCHIVE_OK); - } - if (strcmp(key, "compression-level") == 0) { - if (value == NULL || - !(value[0] >= '0' && value[0] <= '9') || - value[1] != '\0') { - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, - "Illegal value `%s'", - value); - return (ARCHIVE_FAILED); - } - xar->opt_compression_level = value[0] - '0'; - return (ARCHIVE_OK); - } - if (strcmp(key, "toc-checksum") == 0) { - if (value == NULL) - xar->opt_toc_sumalg = CKSUM_NONE; - else if (strcmp(value, "none") == 0) - xar->opt_toc_sumalg = CKSUM_NONE; - else if (strcmp(value, "sha1") == 0) - xar->opt_toc_sumalg = CKSUM_SHA1; - else if (strcmp(value, "md5") == 0) - xar->opt_toc_sumalg = CKSUM_MD5; - else { - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, - "Unknown checksum name: `%s'", - value); - return (ARCHIVE_FAILED); - } - return (ARCHIVE_OK); - } - if (strcmp(key, "threads") == 0) { - char *endptr; - - if (value == NULL) - return (ARCHIVE_FAILED); - errno = 0; - xar->opt_threads = (int)strtoul(value, &endptr, 10); - if (errno != 0 || *endptr != '\0') { - xar->opt_threads = 1; - archive_set_error(&(a->archive), - ARCHIVE_ERRNO_MISC, - "Illegal value `%s'", - value); - return (ARCHIVE_FAILED); - } - if (xar->opt_threads == 0) { -#ifdef HAVE_LZMA_STREAM_ENCODER_MT - xar->opt_threads = lzma_cputhreads(); -#else - xar->opt_threads = 1; -#endif - } - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -static int -xar_write_header(struct archive_write *a, struct archive_entry *entry) -{ - struct xar *xar; - struct file *file; - struct archive_entry *file_entry; - int r, r2; - - xar = (struct xar *)a->format_data; - xar->cur_file = NULL; - xar->bytes_remaining = 0; - - if (xar->sconv == NULL) { - xar->sconv = archive_string_conversion_to_charset( - &a->archive, "UTF-8", 1); - if (xar->sconv == NULL) - return (ARCHIVE_FATAL); - } - - file = file_new(a, entry); - if (file == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate data"); - return (ARCHIVE_FATAL); - } - r2 = file_gen_utility_names(a, file); - if (r2 < ARCHIVE_WARN) - return (r2); - - /* - * Ignore a path which looks like the top of directory name - * since we have already made the root directory of an Xar archive. - */ - if (archive_strlen(&(file->parentdir)) == 0 && - archive_strlen(&(file->basename)) == 0) { - file_free(file); - return (r2); - } - - /* Add entry into tree */ - file_entry = file->entry; - r = file_tree(a, &file); - if (r != ARCHIVE_OK) - return (r); - /* There is the same file in tree and - * the current file is older than the file in tree. - * So we don't need the current file data anymore. */ - if (file->entry != file_entry) - return (r2); - if (file->id == 0) - file_register(xar, file); - - /* A virtual file, which is a directory, does not have - * any contents and we won't store it into a archive - * file other than its name. */ - if (file->virtual) - return (r2); - - /* - * Prepare to save the contents of the file. - */ - if (xar->temp_fd == -1) { - int algsize; - xar->temp_offset = 0; - xar->temp_fd = __archive_mktemp(NULL); - if (xar->temp_fd < 0) { - archive_set_error(&a->archive, errno, - "Couldn't create temporary file"); - return (ARCHIVE_FATAL); - } - algsize = getalgsize(xar->opt_toc_sumalg); - if (algsize > 0) { - if (lseek(xar->temp_fd, algsize, SEEK_SET) < 0) { - archive_set_error(&(a->archive), errno, - "lseek failed"); - return (ARCHIVE_FATAL); - } - xar->temp_offset = algsize; - } - } - - if (archive_entry_hardlink(file->entry) == NULL) { - r = save_xattrs(a, file); - if (r != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } - - /* Non regular files contents are unneeded to be saved to - * a temporary file. */ - if (archive_entry_filetype(file->entry) != AE_IFREG) - return (r2); - - /* - * Set the current file to cur_file to read its contents. - */ - xar->cur_file = file; - - if (archive_entry_nlink(file->entry) > 1) { - r = file_register_hardlink(a, file); - if (r != ARCHIVE_OK) - return (r); - if (archive_entry_hardlink(file->entry) != NULL) { - archive_entry_unset_size(file->entry); - return (r2); - } - } - - /* Save a offset of current file in temporary file. */ - file->data.temp_offset = xar->temp_offset; - file->data.size = archive_entry_size(file->entry); - file->data.compression = xar->opt_compression; - xar->bytes_remaining = archive_entry_size(file->entry); - checksum_init(&(xar->a_sumwrk), xar->opt_sumalg); - checksum_init(&(xar->e_sumwrk), xar->opt_sumalg); - r = xar_compression_init_encoder(a); - - if (r != ARCHIVE_OK) - return (r); - else - return (r2); -} - -static int -write_to_temp(struct archive_write *a, const void *buff, size_t s) -{ - struct xar *xar; - const unsigned char *p; - ssize_t ws; - - xar = (struct xar *)a->format_data; - p = (const unsigned char *)buff; - while (s) { - ws = write(xar->temp_fd, p, s); - if (ws < 0) { - archive_set_error(&(a->archive), errno, - "fwrite function failed"); - return (ARCHIVE_FATAL); - } - s -= ws; - p += ws; - xar->temp_offset += ws; - } - return (ARCHIVE_OK); -} - -static ssize_t -xar_write_data(struct archive_write *a, const void *buff, size_t s) -{ - struct xar *xar; - enum la_zaction run; - size_t size = 0; - size_t rsize; - int r; - - xar = (struct xar *)a->format_data; - - if (s > xar->bytes_remaining) - s = (size_t)xar->bytes_remaining; - if (s == 0 || xar->cur_file == NULL) - return (0); - if (xar->cur_file->data.compression == NONE) { - checksum_update(&(xar->e_sumwrk), buff, s); - checksum_update(&(xar->a_sumwrk), buff, s); - size = rsize = s; - } else { - xar->stream.next_in = (const unsigned char *)buff; - xar->stream.avail_in = s; - if (xar->bytes_remaining > s) - run = ARCHIVE_Z_RUN; - else - run = ARCHIVE_Z_FINISH; - /* Compress file data. */ - for (;;) { - r = compression_code(&(a->archive), &(xar->stream), - run); - if (r != ARCHIVE_OK && r != ARCHIVE_EOF) - return (ARCHIVE_FATAL); - if (xar->stream.avail_out == 0 || - run == ARCHIVE_Z_FINISH) { - size = sizeof(xar->wbuff) - - xar->stream.avail_out; - checksum_update(&(xar->a_sumwrk), xar->wbuff, - size); - xar->cur_file->data.length += size; - if (write_to_temp(a, xar->wbuff, - size) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - if (r == ARCHIVE_OK) { - /* Output buffer was full */ - xar->stream.next_out = xar->wbuff; - xar->stream.avail_out = - sizeof(xar->wbuff); - } else { - /* ARCHIVE_EOF - We are done */ - break; - } - } else { - /* Compressor wants more input */ - break; - } - } - rsize = s - xar->stream.avail_in; - checksum_update(&(xar->e_sumwrk), buff, rsize); - } -#if !defined(_WIN32) || defined(__CYGWIN__) - if (xar->bytes_remaining == - (uint64_t)archive_entry_size(xar->cur_file->entry)) { - /* - * Get the path of a shell script if so. - */ - const unsigned char *b = (const unsigned char *)buff; - - archive_string_empty(&(xar->cur_file->script)); - if (rsize > 2 && b[0] == '#' && b[1] == '!') { - size_t i, end, off; - - off = 2; - if (b[off] == ' ') - off++; -#ifdef PATH_MAX - if ((rsize - off) > PATH_MAX) - end = off + PATH_MAX; - else -#endif - end = rsize; - /* Find the end of a script path. */ - for (i = off; i < end && b[i] != '\0' && - b[i] != '\n' && b[i] != '\r' && - b[i] != ' ' && b[i] != '\t'; i++) - ; - archive_strncpy(&(xar->cur_file->script), b + off, - i - off); - } - } -#endif - - if (xar->cur_file->data.compression == NONE) { - if (write_to_temp(a, buff, size) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - xar->cur_file->data.length += size; - } - xar->bytes_remaining -= rsize; - - return (rsize); -} - -static int -xar_finish_entry(struct archive_write *a) -{ - struct xar *xar; - struct file *file; - size_t s; - ssize_t w; - - xar = (struct xar *)a->format_data; - if (xar->cur_file == NULL) - return (ARCHIVE_OK); - - while (xar->bytes_remaining > 0) { - s = (size_t)xar->bytes_remaining; - if (s > a->null_length) - s = a->null_length; - w = xar_write_data(a, a->nulls, s); - if (w > 0) - xar->bytes_remaining -= w; - else - return (w); - } - file = xar->cur_file; - checksum_final(&(xar->e_sumwrk), &(file->data.e_sum)); - checksum_final(&(xar->a_sumwrk), &(file->data.a_sum)); - xar->cur_file = NULL; - - return (ARCHIVE_OK); -} - -static int -xmlwrite_string_attr(struct archive_write *a, xmlTextWriterPtr writer, - const char *key, const char *value, - const char *attrkey, const char *attrvalue) -{ - int r; - - r = xmlTextWriterStartElement(writer, BAD_CAST_CONST(key)); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterStartElement() failed: %d", r); - return (ARCHIVE_FATAL); - } - if (attrkey != NULL && attrvalue != NULL) { - r = xmlTextWriterWriteAttribute(writer, - BAD_CAST_CONST(attrkey), BAD_CAST_CONST(attrvalue)); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterWriteAttribute() failed: %d", r); - return (ARCHIVE_FATAL); - } - } - if (value != NULL) { - r = xmlTextWriterWriteString(writer, BAD_CAST_CONST(value)); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterWriteString() failed: %d", r); - return (ARCHIVE_FATAL); - } - } - r = xmlTextWriterEndElement(writer); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterEndElement() failed: %d", r); - return (ARCHIVE_FATAL); - } - return (ARCHIVE_OK); -} - -static int -xmlwrite_string(struct archive_write *a, xmlTextWriterPtr writer, - const char *key, const char *value) -{ - int r; - - if (value == NULL) - return (ARCHIVE_OK); - - r = xmlTextWriterStartElement(writer, BAD_CAST_CONST(key)); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterStartElement() failed: %d", r); - return (ARCHIVE_FATAL); - } - if (value != NULL) { - r = xmlTextWriterWriteString(writer, BAD_CAST_CONST(value)); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterWriteString() failed: %d", r); - return (ARCHIVE_FATAL); - } - } - r = xmlTextWriterEndElement(writer); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterEndElement() failed: %d", r); - return (ARCHIVE_FATAL); - } - return (ARCHIVE_OK); -} - -static int -xmlwrite_fstring(struct archive_write *a, xmlTextWriterPtr writer, - const char *key, const char *fmt, ...) -{ - struct xar *xar; - va_list ap; - - xar = (struct xar *)a->format_data; - va_start(ap, fmt); - archive_string_empty(&xar->vstr); - archive_string_vsprintf(&xar->vstr, fmt, ap); - va_end(ap); - return (xmlwrite_string(a, writer, key, xar->vstr.s)); -} - -static int -xmlwrite_time(struct archive_write *a, xmlTextWriterPtr writer, - const char *key, time_t t, int z) -{ - char timestr[100]; - struct tm tm; - -#if defined(HAVE_GMTIME_S) - gmtime_s(&tm, &t); -#elif defined(HAVE_GMTIME_R) - gmtime_r(&t, &tm); -#else - memcpy(&tm, gmtime(&t), sizeof(tm)); -#endif - memset(×tr, 0, sizeof(timestr)); - /* Do not use %F and %T for portability. */ - strftime(timestr, sizeof(timestr), "%Y-%m-%dT%H:%M:%S", &tm); - if (z) - strcat(timestr, "Z"); - return (xmlwrite_string(a, writer, key, timestr)); -} - -static int -xmlwrite_mode(struct archive_write *a, xmlTextWriterPtr writer, - const char *key, mode_t mode) -{ - char ms[5]; - - ms[0] = '0'; - ms[1] = '0' + ((mode >> 6) & 07); - ms[2] = '0' + ((mode >> 3) & 07); - ms[3] = '0' + (mode & 07); - ms[4] = '\0'; - - return (xmlwrite_string(a, writer, key, ms)); -} - -static int -xmlwrite_sum(struct archive_write *a, xmlTextWriterPtr writer, - const char *key, struct chksumval *sum) -{ - const char *algname; - int algsize; - char buff[MAX_SUM_SIZE*2 + 1]; - char *p; - unsigned char *s; - int i, r; - - if (sum->len > 0) { - algname = getalgname(sum->alg); - algsize = getalgsize(sum->alg); - if (algname != NULL) { - const char *hex = "0123456789abcdef"; - p = buff; - s = sum->val; - for (i = 0; i < algsize; i++) { - *p++ = hex[(*s >> 4)]; - *p++ = hex[(*s & 0x0f)]; - s++; - } - *p = '\0'; - r = xmlwrite_string_attr(a, writer, - key, buff, - "style", algname); - if (r < 0) - return (ARCHIVE_FATAL); - } - } - return (ARCHIVE_OK); -} - -static int -xmlwrite_heap(struct archive_write *a, xmlTextWriterPtr writer, - struct heap_data *heap) -{ - const char *encname; - int r; - - r = xmlwrite_fstring(a, writer, "length", "%ju", heap->length); - if (r < 0) - return (ARCHIVE_FATAL); - r = xmlwrite_fstring(a, writer, "offset", "%ju", heap->temp_offset); - if (r < 0) - return (ARCHIVE_FATAL); - r = xmlwrite_fstring(a, writer, "size", "%ju", heap->size); - if (r < 0) - return (ARCHIVE_FATAL); - switch (heap->compression) { - case GZIP: - encname = "application/x-gzip"; break; - case BZIP2: - encname = "application/x-bzip2"; break; - case LZMA: - encname = "application/x-lzma"; break; - case XZ: - encname = "application/x-xz"; break; - default: - encname = "application/octet-stream"; break; - } - r = xmlwrite_string_attr(a, writer, "encoding", NULL, - "style", encname); - if (r < 0) - return (ARCHIVE_FATAL); - r = xmlwrite_sum(a, writer, "archived-checksum", &(heap->a_sum)); - if (r < 0) - return (ARCHIVE_FATAL); - r = xmlwrite_sum(a, writer, "extracted-checksum", &(heap->e_sum)); - if (r < 0) - return (ARCHIVE_FATAL); - return (ARCHIVE_OK); -} - -/* - * xar utility records fflags as following xml elements: - * - * - * ..... - * - * or - * - * - * ..... - * - * If xar is running on BSD platform, records ..; - * if xar is running on linux platform, records ..; - * otherwise does not record. - * - * Our implements records both and if it's necessary. - */ -static int -make_fflags_entry(struct archive_write *a, xmlTextWriterPtr writer, - const char *element, const char *fflags_text) -{ - static const struct flagentry { - const char *name; - const char *xarname; - } - flagbsd[] = { - { "sappnd", "SystemAppend"}, - { "sappend", "SystemAppend"}, - { "arch", "SystemArchived"}, - { "archived", "SystemArchived"}, - { "schg", "SystemImmutable"}, - { "schange", "SystemImmutable"}, - { "simmutable", "SystemImmutable"}, - { "nosunlnk", "SystemNoUnlink"}, - { "nosunlink", "SystemNoUnlink"}, - { "snapshot", "SystemSnapshot"}, - { "uappnd", "UserAppend"}, - { "uappend", "UserAppend"}, - { "uchg", "UserImmutable"}, - { "uchange", "UserImmutable"}, - { "uimmutable", "UserImmutable"}, - { "nodump", "UserNoDump"}, - { "noopaque", "UserOpaque"}, - { "nouunlnk", "UserNoUnlink"}, - { "nouunlink", "UserNoUnlink"}, - { NULL, NULL} - }, - flagext2[] = { - { "sappnd", "AppendOnly"}, - { "sappend", "AppendOnly"}, - { "schg", "Immutable"}, - { "schange", "Immutable"}, - { "simmutable", "Immutable"}, - { "nodump", "NoDump"}, - { "nouunlnk", "Undelete"}, - { "nouunlink", "Undelete"}, - { "btree", "BTree"}, - { "comperr", "CompError"}, - { "compress", "Compress"}, - { "noatime", "NoAtime"}, - { "compdirty", "CompDirty"}, - { "comprblk", "CompBlock"}, - { "dirsync", "DirSync"}, - { "hashidx", "HashIndexed"}, - { "imagic", "iMagic"}, - { "journal", "Journaled"}, - { "securedeletion", "SecureDeletion"}, - { "sync", "Synchronous"}, - { "notail", "NoTail"}, - { "topdir", "TopDir"}, - { "reserved", "Reserved"}, - { NULL, NULL} - }; - const struct flagentry *fe, *flagentry; -#define FLAGENTRY_MAXSIZE ((sizeof(flagbsd)+sizeof(flagext2))/sizeof(flagbsd)) - const struct flagentry *avail[FLAGENTRY_MAXSIZE]; - const char *p; - int i, n, r; - - if (strcmp(element, "ext2") == 0) - flagentry = flagext2; - else - flagentry = flagbsd; - n = 0; - p = fflags_text; - do { - const char *cp; - - cp = strchr(p, ','); - if (cp == NULL) - cp = p + strlen(p); - - for (fe = flagentry; fe->name != NULL; fe++) { - if (fe->name[cp - p] != '\0' - || p[0] != fe->name[0]) - continue; - if (strncmp(p, fe->name, cp - p) == 0) { - avail[n++] = fe; - break; - } - } - if (*cp == ',') - p = cp + 1; - else - p = NULL; - } while (p != NULL); - - if (n > 0) { - r = xmlTextWriterStartElement(writer, BAD_CAST_CONST(element)); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterStartElement() failed: %d", r); - return (ARCHIVE_FATAL); - } - for (i = 0; i < n; i++) { - r = xmlwrite_string(a, writer, - avail[i]->xarname, NULL); - if (r != ARCHIVE_OK) - return (r); - } - - r = xmlTextWriterEndElement(writer); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterEndElement() failed: %d", r); - return (ARCHIVE_FATAL); - } - } - return (ARCHIVE_OK); -} - -static int -make_file_entry(struct archive_write *a, xmlTextWriterPtr writer, - struct file *file) -{ - struct xar *xar; - const char *filetype, *filelink, *fflags; - struct archive_string linkto; - struct heap_data *heap; - unsigned char *tmp; - const char *p; - size_t len; - int r, r2, l, ll; - - xar = (struct xar *)a->format_data; - r2 = ARCHIVE_OK; - - /* - * Make a file name entry, "". - */ - l = ll = archive_strlen(&(file->basename)); - tmp = malloc(l); - if (tmp == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - r = UTF8Toisolat1(tmp, &l, BAD_CAST(file->basename.s), &ll); - free(tmp); - if (r < 0) { - r = xmlTextWriterStartElement(writer, BAD_CAST("name")); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterStartElement() failed: %d", r); - return (ARCHIVE_FATAL); - } - r = xmlTextWriterWriteAttribute(writer, - BAD_CAST("enctype"), BAD_CAST("base64")); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterWriteAttribute() failed: %d", r); - return (ARCHIVE_FATAL); - } - r = xmlTextWriterWriteBase64(writer, file->basename.s, - 0, archive_strlen(&(file->basename))); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterWriteBase64() failed: %d", r); - return (ARCHIVE_FATAL); - } - r = xmlTextWriterEndElement(writer); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterEndElement() failed: %d", r); - return (ARCHIVE_FATAL); - } - } else { - r = xmlwrite_string(a, writer, "name", file->basename.s); - if (r < 0) - return (ARCHIVE_FATAL); - } - - /* - * Make a file type entry, "". - */ - filelink = NULL; - archive_string_init(&linkto); - switch (archive_entry_filetype(file->entry)) { - case AE_IFDIR: - filetype = "directory"; break; - case AE_IFLNK: - filetype = "symlink"; break; - case AE_IFCHR: - filetype = "character special"; break; - case AE_IFBLK: - filetype = "block special"; break; - case AE_IFSOCK: - filetype = "socket"; break; - case AE_IFIFO: - filetype = "fifo"; break; - case AE_IFREG: - default: - if (file->hardlink_target != NULL) { - filetype = "hardlink"; - filelink = "link"; - if (file->hardlink_target == file) - archive_strcpy(&linkto, "original"); - else - archive_string_sprintf(&linkto, "%d", - file->hardlink_target->id); - } else - filetype = "file"; - break; - } - r = xmlwrite_string_attr(a, writer, "type", filetype, - filelink, linkto.s); - archive_string_free(&linkto); - if (r < 0) - return (ARCHIVE_FATAL); - - /* - * On a virtual directory, we record "name" and "type" only. - */ - if (file->virtual) - return (ARCHIVE_OK); - - switch (archive_entry_filetype(file->entry)) { - case AE_IFLNK: - /* - * xar utility has checked a file type, which - * a symbolic-link file has referenced. - * For example: - * ../ref/ - * The symlink target file is "../ref/" and its - * file type is a directory. - * - * ../f - * The symlink target file is "../f" and its - * file type is a regular file. - * - * But our implementation cannot do it, and then we - * always record that a attribute "type" is "broken", - * for example: - * foo/bar - * It means "foo/bar" is not reachable. - */ - r = xmlwrite_string_attr(a, writer, "link", - file->symlink.s, - "type", "broken"); - if (r < 0) - return (ARCHIVE_FATAL); - break; - case AE_IFCHR: - case AE_IFBLK: - r = xmlTextWriterStartElement(writer, BAD_CAST("device")); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterStartElement() failed: %d", r); - return (ARCHIVE_FATAL); - } - r = xmlwrite_fstring(a, writer, "major", - "%d", archive_entry_rdevmajor(file->entry)); - if (r < 0) - return (ARCHIVE_FATAL); - r = xmlwrite_fstring(a, writer, "minor", - "%d", archive_entry_rdevminor(file->entry)); - if (r < 0) - return (ARCHIVE_FATAL); - r = xmlTextWriterEndElement(writer); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterEndElement() failed: %d", r); - return (ARCHIVE_FATAL); - } - break; - default: - break; - } - - /* - * Make a inode entry, "". - */ - r = xmlwrite_fstring(a, writer, "inode", - "%jd", archive_entry_ino64(file->entry)); - if (r < 0) - return (ARCHIVE_FATAL); - if (archive_entry_dev(file->entry) != 0) { - r = xmlwrite_fstring(a, writer, "deviceno", - "%d", archive_entry_dev(file->entry)); - if (r < 0) - return (ARCHIVE_FATAL); - } - - /* - * Make a file mode entry, "". - */ - r = xmlwrite_mode(a, writer, "mode", - archive_entry_mode(file->entry)); - if (r < 0) - return (ARCHIVE_FATAL); - - /* - * Make a user entry, "" and ". - */ - r = xmlwrite_fstring(a, writer, "uid", - "%d", archive_entry_uid(file->entry)); - if (r < 0) - return (ARCHIVE_FATAL); - r = archive_entry_uname_l(file->entry, &p, &len, xar->sconv); - if (r != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Uname"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate uname '%s' to UTF-8", - archive_entry_uname(file->entry)); - r2 = ARCHIVE_WARN; - } - if (len > 0) { - r = xmlwrite_string(a, writer, "user", p); - if (r < 0) - return (ARCHIVE_FATAL); - } - - /* - * Make a group entry, "" and ". - */ - r = xmlwrite_fstring(a, writer, "gid", - "%d", archive_entry_gid(file->entry)); - if (r < 0) - return (ARCHIVE_FATAL); - r = archive_entry_gname_l(file->entry, &p, &len, xar->sconv); - if (r != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Gname"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate gname '%s' to UTF-8", - archive_entry_gname(file->entry)); - r2 = ARCHIVE_WARN; - } - if (len > 0) { - r = xmlwrite_string(a, writer, "group", p); - if (r < 0) - return (ARCHIVE_FATAL); - } - - /* - * Make a ctime entry, "". - */ - if (archive_entry_ctime_is_set(file->entry)) { - r = xmlwrite_time(a, writer, "ctime", - archive_entry_ctime(file->entry), 1); - if (r < 0) - return (ARCHIVE_FATAL); - } - - /* - * Make a mtime entry, "". - */ - if (archive_entry_mtime_is_set(file->entry)) { - r = xmlwrite_time(a, writer, "mtime", - archive_entry_mtime(file->entry), 1); - if (r < 0) - return (ARCHIVE_FATAL); - } - - /* - * Make a atime entry, "". - */ - if (archive_entry_atime_is_set(file->entry)) { - r = xmlwrite_time(a, writer, "atime", - archive_entry_atime(file->entry), 1); - if (r < 0) - return (ARCHIVE_FATAL); - } - - /* - * Make fflags entries, "" and "". - */ - fflags = archive_entry_fflags_text(file->entry); - if (fflags != NULL) { - r = make_fflags_entry(a, writer, "flags", fflags); - if (r < 0) - return (r); - r = make_fflags_entry(a, writer, "ext2", fflags); - if (r < 0) - return (r); - } - - /* - * Make extended attribute entries, "". - */ - archive_entry_xattr_reset(file->entry); - for (heap = file->xattr.first; heap != NULL; heap = heap->next) { - const char *name; - const void *value; - size_t size; - - archive_entry_xattr_next(file->entry, - &name, &value, &size); - r = xmlTextWriterStartElement(writer, BAD_CAST("ea")); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterStartElement() failed: %d", r); - return (ARCHIVE_FATAL); - } - r = xmlTextWriterWriteFormatAttribute(writer, - BAD_CAST("id"), "%d", heap->id); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterWriteAttribute() failed: %d", r); - return (ARCHIVE_FATAL); - } - r = xmlwrite_heap(a, writer, heap); - if (r < 0) - return (ARCHIVE_FATAL); - r = xmlwrite_string(a, writer, "name", name); - if (r < 0) - return (ARCHIVE_FATAL); - - r = xmlTextWriterEndElement(writer); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterEndElement() failed: %d", r); - return (ARCHIVE_FATAL); - } - } - - /* - * Make a file data entry, "". - */ - if (file->data.length > 0) { - r = xmlTextWriterStartElement(writer, BAD_CAST("data")); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterStartElement() failed: %d", r); - return (ARCHIVE_FATAL); - } - - r = xmlwrite_heap(a, writer, &(file->data)); - if (r < 0) - return (ARCHIVE_FATAL); - - r = xmlTextWriterEndElement(writer); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterEndElement() failed: %d", r); - return (ARCHIVE_FATAL); - } - } - - if (archive_strlen(&file->script) > 0) { - r = xmlTextWriterStartElement(writer, BAD_CAST("content")); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterStartElement() failed: %d", r); - return (ARCHIVE_FATAL); - } - - r = xmlwrite_string(a, writer, - "interpreter", file->script.s); - if (r < 0) - return (ARCHIVE_FATAL); - - r = xmlwrite_string(a, writer, "type", "script"); - if (r < 0) - return (ARCHIVE_FATAL); - - r = xmlTextWriterEndElement(writer); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterEndElement() failed: %d", r); - return (ARCHIVE_FATAL); - } - } - - return (r2); -} - -/* - * Make the TOC - */ -static int -make_toc(struct archive_write *a) -{ - struct xar *xar; - struct file *np; - xmlBufferPtr bp; - xmlTextWriterPtr writer; - int algsize; - int r, ret; - - xar = (struct xar *)a->format_data; - - ret = ARCHIVE_FATAL; - - /* - * Initialize xml writer. - */ - writer = NULL; - bp = xmlBufferCreate(); - if (bp == NULL) { - archive_set_error(&a->archive, ENOMEM, - "xmlBufferCreate() " - "couldn't create xml buffer"); - goto exit_toc; - } - writer = xmlNewTextWriterMemory(bp, 0); - if (writer == NULL) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlNewTextWriterMemory() " - "couldn't create xml writer"); - goto exit_toc; - } - r = xmlTextWriterStartDocument(writer, "1.0", "UTF-8", NULL); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterStartDocument() failed: %d", r); - goto exit_toc; - } - r = xmlTextWriterSetIndent(writer, 4); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterSetIndent() failed: %d", r); - goto exit_toc; - } - - /* - * Start recording TOC - */ - r = xmlTextWriterStartElement(writer, BAD_CAST("xar")); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterStartElement() failed: %d", r); - goto exit_toc; - } - r = xmlTextWriterStartElement(writer, BAD_CAST("toc")); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterStartDocument() failed: %d", r); - goto exit_toc; - } - - /* - * Record the creation time of the archive file. - */ - r = xmlwrite_time(a, writer, "creation-time", time(NULL), 0); - if (r < 0) - goto exit_toc; - - /* - * Record the checksum value of TOC - */ - algsize = getalgsize(xar->opt_toc_sumalg); - if (algsize) { - /* - * Record TOC checksum - */ - r = xmlTextWriterStartElement(writer, BAD_CAST("checksum")); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterStartElement() failed: %d", r); - goto exit_toc; - } - r = xmlTextWriterWriteAttribute(writer, BAD_CAST("style"), - BAD_CAST_CONST(getalgname(xar->opt_toc_sumalg))); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterWriteAttribute() failed: %d", r); - goto exit_toc; - } - - /* - * Record the offset of the value of checksum of TOC - */ - r = xmlwrite_string(a, writer, "offset", "0"); - if (r < 0) - goto exit_toc; - - /* - * Record the size of the value of checksum of TOC - */ - r = xmlwrite_fstring(a, writer, "size", "%d", algsize); - if (r < 0) - goto exit_toc; - - r = xmlTextWriterEndElement(writer); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterEndElement() failed: %d", r); - goto exit_toc; - } - } - - np = xar->root; - do { - if (np != np->parent) { - r = make_file_entry(a, writer, np); - if (r != ARCHIVE_OK) - goto exit_toc; - } - - if (np->dir && np->children.first != NULL) { - /* Enter to sub directories. */ - np = np->children.first; - r = xmlTextWriterStartElement(writer, - BAD_CAST("file")); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterStartElement() " - "failed: %d", r); - goto exit_toc; - } - r = xmlTextWriterWriteFormatAttribute( - writer, BAD_CAST("id"), "%d", np->id); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterWriteAttribute() " - "failed: %d", r); - goto exit_toc; - } - continue; - } - while (np != np->parent) { - r = xmlTextWriterEndElement(writer); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterEndElement() " - "failed: %d", r); - goto exit_toc; - } - if (np->chnext == NULL) { - /* Return to the parent directory. */ - np = np->parent; - } else { - np = np->chnext; - r = xmlTextWriterStartElement(writer, - BAD_CAST("file")); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterStartElement() " - "failed: %d", r); - goto exit_toc; - } - r = xmlTextWriterWriteFormatAttribute( - writer, BAD_CAST("id"), "%d", np->id); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterWriteAttribute() " - "failed: %d", r); - goto exit_toc; - } - break; - } - } - } while (np != np->parent); - - r = xmlTextWriterEndDocument(writer); - if (r < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "xmlTextWriterEndDocument() failed: %d", r); - goto exit_toc; - } -#if DEBUG_PRINT_TOC - fprintf(stderr, "\n---TOC-- %d bytes --\n%s\n", - strlen((const char *)bp->content), bp->content); -#endif - - /* - * Compress the TOC and calculate the sum of the TOC. - */ - xar->toc.temp_offset = xar->temp_offset; - xar->toc.size = bp->use; - checksum_init(&(xar->a_sumwrk), xar->opt_toc_sumalg); - - r = compression_init_encoder_gzip(&(a->archive), - &(xar->stream), 6, 1); - if (r != ARCHIVE_OK) - goto exit_toc; - xar->stream.next_in = bp->content; - xar->stream.avail_in = bp->use; - xar->stream.total_in = 0; - xar->stream.next_out = xar->wbuff; - xar->stream.avail_out = sizeof(xar->wbuff); - xar->stream.total_out = 0; - for (;;) { - size_t size; - - r = compression_code(&(a->archive), - &(xar->stream), ARCHIVE_Z_FINISH); - if (r != ARCHIVE_OK && r != ARCHIVE_EOF) - goto exit_toc; - size = sizeof(xar->wbuff) - xar->stream.avail_out; - checksum_update(&(xar->a_sumwrk), xar->wbuff, size); - if (write_to_temp(a, xar->wbuff, size) != ARCHIVE_OK) - goto exit_toc; - if (r == ARCHIVE_EOF) - break; - xar->stream.next_out = xar->wbuff; - xar->stream.avail_out = sizeof(xar->wbuff); - } - r = compression_end(&(a->archive), &(xar->stream)); - if (r != ARCHIVE_OK) - goto exit_toc; - xar->toc.length = xar->stream.total_out; - xar->toc.compression = GZIP; - checksum_final(&(xar->a_sumwrk), &(xar->toc.a_sum)); - - ret = ARCHIVE_OK; -exit_toc: - if (writer) - xmlFreeTextWriter(writer); - if (bp) - xmlBufferFree(bp); - - return (ret); -} - -static int -flush_wbuff(struct archive_write *a) -{ - struct xar *xar; - int r; - size_t s; - - xar = (struct xar *)a->format_data; - s = sizeof(xar->wbuff) - xar->wbuff_remaining; - r = __archive_write_output(a, xar->wbuff, s); - if (r != ARCHIVE_OK) - return (r); - xar->wbuff_remaining = sizeof(xar->wbuff); - return (r); -} - -static int -copy_out(struct archive_write *a, uint64_t offset, uint64_t length) -{ - struct xar *xar; - int r; - - xar = (struct xar *)a->format_data; - if (lseek(xar->temp_fd, offset, SEEK_SET) < 0) { - archive_set_error(&(a->archive), errno, "lseek failed"); - return (ARCHIVE_FATAL); - } - while (length) { - size_t rsize; - ssize_t rs; - unsigned char *wb; - - if (length > xar->wbuff_remaining) - rsize = xar->wbuff_remaining; - else - rsize = (size_t)length; - wb = xar->wbuff + (sizeof(xar->wbuff) - xar->wbuff_remaining); - rs = read(xar->temp_fd, wb, rsize); - if (rs < 0) { - archive_set_error(&(a->archive), errno, - "Can't read temporary file(%jd)", - (intmax_t)rs); - return (ARCHIVE_FATAL); - } - if (rs == 0) { - archive_set_error(&(a->archive), 0, - "Truncated xar archive"); - return (ARCHIVE_FATAL); - } - xar->wbuff_remaining -= rs; - length -= rs; - if (xar->wbuff_remaining == 0) { - r = flush_wbuff(a); - if (r != ARCHIVE_OK) - return (r); - } - } - return (ARCHIVE_OK); -} - -static int -xar_close(struct archive_write *a) -{ - struct xar *xar; - unsigned char *wb; - uint64_t length; - int r; - - xar = (struct xar *)a->format_data; - - /* Empty! */ - if (xar->root->children.first == NULL) - return (ARCHIVE_OK); - - /* Save the length of all file extended attributes and contents. */ - length = xar->temp_offset; - - /* Connect hardlinked files */ - file_connect_hardlink_files(xar); - - /* Make the TOC */ - r = make_toc(a); - if (r != ARCHIVE_OK) - return (r); - /* - * Make the xar header on wbuff(write buffer). - */ - wb = xar->wbuff; - xar->wbuff_remaining = sizeof(xar->wbuff); - archive_be32enc(&wb[0], HEADER_MAGIC); - archive_be16enc(&wb[4], HEADER_SIZE); - archive_be16enc(&wb[6], HEADER_VERSION); - archive_be64enc(&wb[8], xar->toc.length); - archive_be64enc(&wb[16], xar->toc.size); - archive_be32enc(&wb[24], xar->toc.a_sum.alg); - xar->wbuff_remaining -= HEADER_SIZE; - - /* - * Write the TOC - */ - r = copy_out(a, xar->toc.temp_offset, xar->toc.length); - if (r != ARCHIVE_OK) - return (r); - - /* Write the checksum value of the TOC. */ - if (xar->toc.a_sum.len) { - if (xar->wbuff_remaining < xar->toc.a_sum.len) { - r = flush_wbuff(a); - if (r != ARCHIVE_OK) - return (r); - } - wb = xar->wbuff + (sizeof(xar->wbuff) - xar->wbuff_remaining); - memcpy(wb, xar->toc.a_sum.val, xar->toc.a_sum.len); - xar->wbuff_remaining -= xar->toc.a_sum.len; - } - - /* - * Write all file extended attributes and contents. - */ - r = copy_out(a, xar->toc.a_sum.len, length); - if (r != ARCHIVE_OK) - return (r); - r = flush_wbuff(a); - return (r); -} - -static int -xar_free(struct archive_write *a) -{ - struct xar *xar; - - xar = (struct xar *)a->format_data; - - /* Close the temporary file. */ - if (xar->temp_fd >= 0) - close(xar->temp_fd); - - archive_string_free(&(xar->cur_dirstr)); - archive_string_free(&(xar->tstr)); - archive_string_free(&(xar->vstr)); - file_free_hardlinks(xar); - file_free_register(xar); - compression_end(&(a->archive), &(xar->stream)); - free(xar); - - return (ARCHIVE_OK); -} - -static int -file_cmp_node(const struct archive_rb_node *n1, - const struct archive_rb_node *n2) -{ - const struct file *f1 = (const struct file *)n1; - const struct file *f2 = (const struct file *)n2; - - return (strcmp(f1->basename.s, f2->basename.s)); -} - -static int -file_cmp_key(const struct archive_rb_node *n, const void *key) -{ - const struct file *f = (const struct file *)n; - - return (strcmp(f->basename.s, (const char *)key)); -} - -static struct file * -file_new(struct archive_write *a, struct archive_entry *entry) -{ - struct file *file; - static const struct archive_rb_tree_ops rb_ops = { - file_cmp_node, file_cmp_key - }; - - file = calloc(1, sizeof(*file)); - if (file == NULL) - return (NULL); - - if (entry != NULL) - file->entry = archive_entry_clone(entry); - else - file->entry = archive_entry_new2(&a->archive); - if (file->entry == NULL) { - free(file); - return (NULL); - } - __archive_rb_tree_init(&(file->rbtree), &rb_ops); - file->children.first = NULL; - file->children.last = &(file->children.first); - file->xattr.first = NULL; - file->xattr.last = &(file->xattr.first); - archive_string_init(&(file->parentdir)); - archive_string_init(&(file->basename)); - archive_string_init(&(file->symlink)); - archive_string_init(&(file->script)); - if (entry != NULL && archive_entry_filetype(entry) == AE_IFDIR) - file->dir = 1; - - return (file); -} - -static void -file_free(struct file *file) -{ - struct heap_data *heap, *next_heap; - - heap = file->xattr.first; - while (heap != NULL) { - next_heap = heap->next; - free(heap); - heap = next_heap; - } - archive_string_free(&(file->parentdir)); - archive_string_free(&(file->basename)); - archive_string_free(&(file->symlink)); - archive_string_free(&(file->script)); - archive_entry_free(file->entry); - free(file); -} - -static struct file * -file_create_virtual_dir(struct archive_write *a, struct xar *xar, - const char *pathname) -{ - struct file *file; - - (void)xar; /* UNUSED */ - - file = file_new(a, NULL); - if (file == NULL) - return (NULL); - archive_entry_set_pathname(file->entry, pathname); - archive_entry_set_mode(file->entry, 0555 | AE_IFDIR); - - file->dir = 1; - file->virtual = 1; - - return (file); -} - -static int -file_add_child_tail(struct file *parent, struct file *child) -{ - if (!__archive_rb_tree_insert_node( - &(parent->rbtree), (struct archive_rb_node *)child)) - return (0); - child->chnext = NULL; - *parent->children.last = child; - parent->children.last = &(child->chnext); - child->parent = parent; - return (1); -} - -/* - * Find a entry from `parent' - */ -static struct file * -file_find_child(struct file *parent, const char *child_name) -{ - struct file *np; - - np = (struct file *)__archive_rb_tree_find_node( - &(parent->rbtree), child_name); - return (np); -} - -#if defined(_WIN32) || defined(__CYGWIN__) -static void -cleanup_backslash(char *utf8, size_t len) -{ - - /* Convert a path-separator from '\' to '/' */ - while (*utf8 != '\0' && len) { - if (*utf8 == '\\') - *utf8 = '/'; - ++utf8; - --len; - } -} -#else -#define cleanup_backslash(p, len) /* nop */ -#endif - -/* - * Generate a parent directory name and a base name from a pathname. - */ -static int -file_gen_utility_names(struct archive_write *a, struct file *file) -{ - struct xar *xar; - const char *pp; - char *p, *dirname, *slash; - size_t len; - int r = ARCHIVE_OK; - - xar = (struct xar *)a->format_data; - archive_string_empty(&(file->parentdir)); - archive_string_empty(&(file->basename)); - archive_string_empty(&(file->symlink)); - - if (file->parent == file)/* virtual root */ - return (ARCHIVE_OK); - - if (archive_entry_pathname_l(file->entry, &pp, &len, xar->sconv) - != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Pathname"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate pathname '%s' to UTF-8", - archive_entry_pathname(file->entry)); - r = ARCHIVE_WARN; - } - archive_strncpy(&(file->parentdir), pp, len); - len = file->parentdir.length; - p = dirname = file->parentdir.s; - /* - * Convert a path-separator from '\' to '/' - */ - cleanup_backslash(p, len); - - /* - * Remove leading '/', '../' and './' elements - */ - while (*p) { - if (p[0] == '/') { - p++; - len--; - } else if (p[0] != '.') - break; - else if (p[1] == '.' && p[2] == '/') { - p += 3; - len -= 3; - } else if (p[1] == '/' || (p[1] == '.' && p[2] == '\0')) { - p += 2; - len -= 2; - } else if (p[1] == '\0') { - p++; - len--; - } else - break; - } - if (p != dirname) { - memmove(dirname, p, len+1); - p = dirname; - } - /* - * Remove "/","/." and "/.." elements from tail. - */ - while (len > 0) { - size_t ll = len; - - if (p[len-1] == '/') { - p[len-1] = '\0'; - len--; - } - if (len > 1 && p[len-2] == '/' && p[len-1] == '.') { - p[len-2] = '\0'; - len -= 2; - } - if (len > 2 && p[len-3] == '/' && p[len-2] == '.' && - p[len-1] == '.') { - p[len-3] = '\0'; - len -= 3; - } - if (ll == len) - break; - } - while (*p) { - if (p[0] == '/') { - if (p[1] == '/') - /* Convert '//' --> '/' */ - memmove(p, p+1, strlen(p+1) + 1); - else if (p[1] == '.' && p[2] == '/') - /* Convert '/./' --> '/' */ - memmove(p, p+2, strlen(p+2) + 1); - else if (p[1] == '.' && p[2] == '.' && p[3] == '/') { - /* Convert 'dir/dir1/../dir2/' - * --> 'dir/dir2/' - */ - char *rp = p -1; - while (rp >= dirname) { - if (*rp == '/') - break; - --rp; - } - if (rp > dirname) { - strcpy(rp, p+3); - p = rp; - } else { - strcpy(dirname, p+4); - p = dirname; - } - } else - p++; - } else - p++; - } - p = dirname; - len = strlen(p); - - if (archive_entry_filetype(file->entry) == AE_IFLNK) { - size_t len2; - /* Convert symlink name too. */ - if (archive_entry_symlink_l(file->entry, &pp, &len2, - xar->sconv) != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Linkname"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate symlink '%s' to UTF-8", - archive_entry_symlink(file->entry)); - r = ARCHIVE_WARN; - } - archive_strncpy(&(file->symlink), pp, len2); - cleanup_backslash(file->symlink.s, file->symlink.length); - } - /* - * - Count up directory elements. - * - Find out the position which points the last position of - * path separator('/'). - */ - slash = NULL; - for (; *p != '\0'; p++) - if (*p == '/') - slash = p; - if (slash == NULL) { - /* The pathname doesn't have a parent directory. */ - file->parentdir.length = len; - archive_string_copy(&(file->basename), &(file->parentdir)); - archive_string_empty(&(file->parentdir)); - *file->parentdir.s = '\0'; - return (r); - } - - /* Make a basename from dirname and slash */ - *slash = '\0'; - file->parentdir.length = slash - dirname; - archive_strcpy(&(file->basename), slash + 1); - return (r); -} - -static int -get_path_component(char *name, int n, const char *fn) -{ - char *p; - int l; - - p = strchr(fn, '/'); - if (p == NULL) { - if ((l = strlen(fn)) == 0) - return (0); - } else - l = p - fn; - if (l > n -1) - return (-1); - memcpy(name, fn, l); - name[l] = '\0'; - - return (l); -} - -/* - * Add a new entry into the tree. - */ -static int -file_tree(struct archive_write *a, struct file **filepp) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - char name[_MAX_FNAME];/* Included null terminator size. */ -#elif defined(NAME_MAX) && NAME_MAX >= 255 - char name[NAME_MAX+1]; -#else - char name[256]; -#endif - struct xar *xar = (struct xar *)a->format_data; - struct file *dent, *file, *np; - struct archive_entry *ent; - const char *fn, *p; - int l; - - file = *filepp; - dent = xar->root; - if (file->parentdir.length > 0) - fn = p = file->parentdir.s; - else - fn = p = ""; - - /* - * If the path of the parent directory of `file' entry is - * the same as the path of `cur_dirent', add isoent to - * `cur_dirent'. - */ - if (archive_strlen(&(xar->cur_dirstr)) - == archive_strlen(&(file->parentdir)) && - strcmp(xar->cur_dirstr.s, fn) == 0) { - if (!file_add_child_tail(xar->cur_dirent, file)) { - np = (struct file *)__archive_rb_tree_find_node( - &(xar->cur_dirent->rbtree), - file->basename.s); - goto same_entry; - } - return (ARCHIVE_OK); - } - - for (;;) { - l = get_path_component(name, sizeof(name), fn); - if (l == 0) { - np = NULL; - break; - } - if (l < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "A name buffer is too small"); - file_free(file); - *filepp = NULL; - return (ARCHIVE_FATAL); - } - - np = file_find_child(dent, name); - if (np == NULL || fn[0] == '\0') - break; - - /* Find next subdirectory. */ - if (!np->dir) { - /* NOT Directory! */ - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "`%s' is not directory, we cannot insert `%s' ", - archive_entry_pathname(np->entry), - archive_entry_pathname(file->entry)); - file_free(file); - *filepp = NULL; - return (ARCHIVE_FAILED); - } - fn += l; - if (fn[0] == '/') - fn++; - dent = np; - } - if (np == NULL) { - /* - * Create virtual parent directories. - */ - while (fn[0] != '\0') { - struct file *vp; - struct archive_string as; - - archive_string_init(&as); - archive_strncat(&as, p, fn - p + l); - if (as.s[as.length-1] == '/') { - as.s[as.length-1] = '\0'; - as.length--; - } - vp = file_create_virtual_dir(a, xar, as.s); - if (vp == NULL) { - archive_string_free(&as); - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - file_free(file); - *filepp = NULL; - return (ARCHIVE_FATAL); - } - archive_string_free(&as); - if (file_gen_utility_names(a, vp) <= ARCHIVE_FAILED) - return (ARCHIVE_FATAL); - file_add_child_tail(dent, vp); - file_register(xar, vp); - np = vp; - - fn += l; - if (fn[0] == '/') - fn++; - l = get_path_component(name, sizeof(name), fn); - if (l < 0) { - archive_string_free(&as); - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "A name buffer is too small"); - file_free(file); - *filepp = NULL; - return (ARCHIVE_FATAL); - } - dent = np; - } - - /* Found out the parent directory where isoent can be - * inserted. */ - xar->cur_dirent = dent; - archive_string_empty(&(xar->cur_dirstr)); - archive_string_ensure(&(xar->cur_dirstr), - archive_strlen(&(dent->parentdir)) + - archive_strlen(&(dent->basename)) + 2); - if (archive_strlen(&(dent->parentdir)) + - archive_strlen(&(dent->basename)) == 0) - xar->cur_dirstr.s[0] = 0; - else { - if (archive_strlen(&(dent->parentdir)) > 0) { - archive_string_copy(&(xar->cur_dirstr), - &(dent->parentdir)); - archive_strappend_char(&(xar->cur_dirstr), '/'); - } - archive_string_concat(&(xar->cur_dirstr), - &(dent->basename)); - } - - if (!file_add_child_tail(dent, file)) { - np = (struct file *)__archive_rb_tree_find_node( - &(dent->rbtree), file->basename.s); - goto same_entry; - } - return (ARCHIVE_OK); - } - -same_entry: - /* - * We have already has the entry the filename of which is - * the same. - */ - if (archive_entry_filetype(np->entry) != - archive_entry_filetype(file->entry)) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Found duplicate entries `%s' and its file type is " - "different", - archive_entry_pathname(np->entry)); - file_free(file); - *filepp = NULL; - return (ARCHIVE_FAILED); - } - - /* Swap files. */ - ent = np->entry; - np->entry = file->entry; - file->entry = ent; - np->virtual = 0; - - file_free(file); - *filepp = np; - return (ARCHIVE_OK); -} - -static void -file_register(struct xar *xar, struct file *file) -{ - file->id = xar->file_idx++; - file->next = NULL; - *xar->file_list.last = file; - xar->file_list.last = &(file->next); -} - -static void -file_init_register(struct xar *xar) -{ - xar->file_list.first = NULL; - xar->file_list.last = &(xar->file_list.first); -} - -static void -file_free_register(struct xar *xar) -{ - struct file *file, *file_next; - - file = xar->file_list.first; - while (file != NULL) { - file_next = file->next; - file_free(file); - file = file_next; - } -} - -/* - * Register entry to get a hardlink target. - */ -static int -file_register_hardlink(struct archive_write *a, struct file *file) -{ - struct xar *xar = (struct xar *)a->format_data; - struct hardlink *hl; - const char *pathname; - - archive_entry_set_nlink(file->entry, 1); - pathname = archive_entry_hardlink(file->entry); - if (pathname == NULL) { - /* This `file` is a hardlink target. */ - hl = malloc(sizeof(*hl)); - if (hl == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory"); - return (ARCHIVE_FATAL); - } - hl->nlink = 1; - /* A hardlink target must be the first position. */ - file->hlnext = NULL; - hl->file_list.first = file; - hl->file_list.last = &(file->hlnext); - __archive_rb_tree_insert_node(&(xar->hardlink_rbtree), - (struct archive_rb_node *)hl); - } else { - hl = (struct hardlink *)__archive_rb_tree_find_node( - &(xar->hardlink_rbtree), pathname); - if (hl != NULL) { - /* Insert `file` entry into the tail. */ - file->hlnext = NULL; - *hl->file_list.last = file; - hl->file_list.last = &(file->hlnext); - hl->nlink++; - } - archive_entry_unset_size(file->entry); - } - - return (ARCHIVE_OK); -} - -/* - * Hardlinked files have to have the same location of extent. - * We have to find out hardlink target entries for entries which - * have a hardlink target name. - */ -static void -file_connect_hardlink_files(struct xar *xar) -{ - struct archive_rb_node *n; - struct hardlink *hl; - struct file *target, *nf; - - ARCHIVE_RB_TREE_FOREACH(n, &(xar->hardlink_rbtree)) { - hl = (struct hardlink *)n; - - /* The first entry must be a hardlink target. */ - target = hl->file_list.first; - archive_entry_set_nlink(target->entry, hl->nlink); - if (hl->nlink > 1) - /* It means this file is a hardlink - * target itself. */ - target->hardlink_target = target; - for (nf = target->hlnext; - nf != NULL; nf = nf->hlnext) { - nf->hardlink_target = target; - archive_entry_set_nlink(nf->entry, hl->nlink); - } - } -} - -static int -file_hd_cmp_node(const struct archive_rb_node *n1, - const struct archive_rb_node *n2) -{ - const struct hardlink *h1 = (const struct hardlink *)n1; - const struct hardlink *h2 = (const struct hardlink *)n2; - - return (strcmp(archive_entry_pathname(h1->file_list.first->entry), - archive_entry_pathname(h2->file_list.first->entry))); -} - -static int -file_hd_cmp_key(const struct archive_rb_node *n, const void *key) -{ - const struct hardlink *h = (const struct hardlink *)n; - - return (strcmp(archive_entry_pathname(h->file_list.first->entry), - (const char *)key)); -} - - -static void -file_init_hardlinks(struct xar *xar) -{ - static const struct archive_rb_tree_ops rb_ops = { - file_hd_cmp_node, file_hd_cmp_key, - }; - - __archive_rb_tree_init(&(xar->hardlink_rbtree), &rb_ops); -} - -static void -file_free_hardlinks(struct xar *xar) -{ - struct archive_rb_node *n, *tmp; - - ARCHIVE_RB_TREE_FOREACH_SAFE(n, &(xar->hardlink_rbtree), tmp) { - __archive_rb_tree_remove_node(&(xar->hardlink_rbtree), n); - free(n); - } -} - -static void -checksum_init(struct chksumwork *sumwrk, enum sumalg sum_alg) -{ - sumwrk->alg = sum_alg; - switch (sum_alg) { - case CKSUM_NONE: - break; - case CKSUM_SHA1: - archive_sha1_init(&(sumwrk->sha1ctx)); - break; - case CKSUM_MD5: - archive_md5_init(&(sumwrk->md5ctx)); - break; - } -} - -static void -checksum_update(struct chksumwork *sumwrk, const void *buff, size_t size) -{ - - switch (sumwrk->alg) { - case CKSUM_NONE: - break; - case CKSUM_SHA1: - archive_sha1_update(&(sumwrk->sha1ctx), buff, size); - break; - case CKSUM_MD5: - archive_md5_update(&(sumwrk->md5ctx), buff, size); - break; - } -} - -static void -checksum_final(struct chksumwork *sumwrk, struct chksumval *sumval) -{ - - switch (sumwrk->alg) { - case CKSUM_NONE: - sumval->len = 0; - break; - case CKSUM_SHA1: - archive_sha1_final(&(sumwrk->sha1ctx), sumval->val); - sumval->len = SHA1_SIZE; - break; - case CKSUM_MD5: - archive_md5_final(&(sumwrk->md5ctx), sumval->val); - sumval->len = MD5_SIZE; - break; - } - sumval->alg = sumwrk->alg; -} - -#if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR) || !defined(HAVE_LZMA_H) -static int -compression_unsupported_encoder(struct archive *a, - struct la_zstream *lastrm, const char *name) -{ - - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "%s compression not supported on this platform", name); - lastrm->valid = 0; - lastrm->real_stream = NULL; - return (ARCHIVE_FAILED); -} -#endif - -static int -compression_init_encoder_gzip(struct archive *a, - struct la_zstream *lastrm, int level, int withheader) -{ - z_stream *strm; - - if (lastrm->valid) - compression_end(a, lastrm); - strm = calloc(1, sizeof(*strm)); - if (strm == NULL) { - archive_set_error(a, ENOMEM, - "Can't allocate memory for gzip stream"); - return (ARCHIVE_FATAL); - } - /* zlib.h is not const-correct, so we need this one bit - * of ugly hackery to convert a const * pointer to - * a non-const pointer. */ - strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in; - strm->avail_in = lastrm->avail_in; - strm->total_in = (uLong)lastrm->total_in; - strm->next_out = lastrm->next_out; - strm->avail_out = lastrm->avail_out; - strm->total_out = (uLong)lastrm->total_out; - if (deflateInit2(strm, level, Z_DEFLATED, - (withheader)?15:-15, - 8, Z_DEFAULT_STRATEGY) != Z_OK) { - free(strm); - lastrm->real_stream = NULL; - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Internal error initializing compression library"); - return (ARCHIVE_FATAL); - } - lastrm->real_stream = strm; - lastrm->valid = 1; - lastrm->code = compression_code_gzip; - lastrm->end = compression_end_gzip; - return (ARCHIVE_OK); -} - -static int -compression_code_gzip(struct archive *a, - struct la_zstream *lastrm, enum la_zaction action) -{ - z_stream *strm; - int r; - - strm = (z_stream *)lastrm->real_stream; - /* zlib.h is not const-correct, so we need this one bit - * of ugly hackery to convert a const * pointer to - * a non-const pointer. */ - strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in; - strm->avail_in = lastrm->avail_in; - strm->total_in = (uLong)lastrm->total_in; - strm->next_out = lastrm->next_out; - strm->avail_out = lastrm->avail_out; - strm->total_out = (uLong)lastrm->total_out; - r = deflate(strm, - (action == ARCHIVE_Z_FINISH)? Z_FINISH: Z_NO_FLUSH); - lastrm->next_in = strm->next_in; - lastrm->avail_in = strm->avail_in; - lastrm->total_in = strm->total_in; - lastrm->next_out = strm->next_out; - lastrm->avail_out = strm->avail_out; - lastrm->total_out = strm->total_out; - switch (r) { - case Z_OK: - return (ARCHIVE_OK); - case Z_STREAM_END: - return (ARCHIVE_EOF); - default: - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "GZip compression failed:" - " deflate() call returned status %d", r); - return (ARCHIVE_FATAL); - } -} - -static int -compression_end_gzip(struct archive *a, struct la_zstream *lastrm) -{ - z_stream *strm; - int r; - - strm = (z_stream *)lastrm->real_stream; - r = deflateEnd(strm); - free(strm); - lastrm->real_stream = NULL; - lastrm->valid = 0; - if (r != Z_OK) { - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Failed to clean up compressor"); - return (ARCHIVE_FATAL); - } - return (ARCHIVE_OK); -} - -#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) -static int -compression_init_encoder_bzip2(struct archive *a, - struct la_zstream *lastrm, int level) -{ - bz_stream *strm; - - if (lastrm->valid) - compression_end(a, lastrm); - strm = calloc(1, sizeof(*strm)); - if (strm == NULL) { - archive_set_error(a, ENOMEM, - "Can't allocate memory for bzip2 stream"); - return (ARCHIVE_FATAL); - } - /* bzlib.h is not const-correct, so we need this one bit - * of ugly hackery to convert a const * pointer to - * a non-const pointer. */ - strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in; - strm->avail_in = lastrm->avail_in; - strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff); - strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32); - strm->next_out = (char *)lastrm->next_out; - strm->avail_out = lastrm->avail_out; - strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff); - strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32); - if (BZ2_bzCompressInit(strm, level, 0, 30) != BZ_OK) { - free(strm); - lastrm->real_stream = NULL; - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Internal error initializing compression library"); - return (ARCHIVE_FATAL); - } - lastrm->real_stream = strm; - lastrm->valid = 1; - lastrm->code = compression_code_bzip2; - lastrm->end = compression_end_bzip2; - return (ARCHIVE_OK); -} - -static int -compression_code_bzip2(struct archive *a, - struct la_zstream *lastrm, enum la_zaction action) -{ - bz_stream *strm; - int r; - - strm = (bz_stream *)lastrm->real_stream; - /* bzlib.h is not const-correct, so we need this one bit - * of ugly hackery to convert a const * pointer to - * a non-const pointer. */ - strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in; - strm->avail_in = lastrm->avail_in; - strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff); - strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32); - strm->next_out = (char *)lastrm->next_out; - strm->avail_out = lastrm->avail_out; - strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff); - strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32); - r = BZ2_bzCompress(strm, - (action == ARCHIVE_Z_FINISH)? BZ_FINISH: BZ_RUN); - lastrm->next_in = (const unsigned char *)strm->next_in; - lastrm->avail_in = strm->avail_in; - lastrm->total_in = - (((uint64_t)(uint32_t)strm->total_in_hi32) << 32) - + (uint64_t)(uint32_t)strm->total_in_lo32; - lastrm->next_out = (unsigned char *)strm->next_out; - lastrm->avail_out = strm->avail_out; - lastrm->total_out = - (((uint64_t)(uint32_t)strm->total_out_hi32) << 32) - + (uint64_t)(uint32_t)strm->total_out_lo32; - switch (r) { - case BZ_RUN_OK: /* Non-finishing */ - case BZ_FINISH_OK: /* Finishing: There's more work to do */ - return (ARCHIVE_OK); - case BZ_STREAM_END: /* Finishing: all done */ - /* Only occurs in finishing case */ - return (ARCHIVE_EOF); - default: - /* Any other return value indicates an error */ - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Bzip2 compression failed:" - " BZ2_bzCompress() call returned status %d", r); - return (ARCHIVE_FATAL); - } -} - -static int -compression_end_bzip2(struct archive *a, struct la_zstream *lastrm) -{ - bz_stream *strm; - int r; - - strm = (bz_stream *)lastrm->real_stream; - r = BZ2_bzCompressEnd(strm); - free(strm); - lastrm->real_stream = NULL; - lastrm->valid = 0; - if (r != BZ_OK) { - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Failed to clean up compressor"); - return (ARCHIVE_FATAL); - } - return (ARCHIVE_OK); -} - -#else -static int -compression_init_encoder_bzip2(struct archive *a, - struct la_zstream *lastrm, int level) -{ - - (void) level; /* UNUSED */ - if (lastrm->valid) - compression_end(a, lastrm); - return (compression_unsupported_encoder(a, lastrm, "bzip2")); -} -#endif - -#if defined(HAVE_LZMA_H) -static int -compression_init_encoder_lzma(struct archive *a, - struct la_zstream *lastrm, int level) -{ - static const lzma_stream lzma_init_data = LZMA_STREAM_INIT; - lzma_stream *strm; - lzma_options_lzma lzma_opt; - int r; - - if (lastrm->valid) - compression_end(a, lastrm); - if (lzma_lzma_preset(&lzma_opt, level)) { - lastrm->real_stream = NULL; - archive_set_error(a, ENOMEM, - "Internal error initializing compression library"); - return (ARCHIVE_FATAL); - } - strm = calloc(1, sizeof(*strm)); - if (strm == NULL) { - archive_set_error(a, ENOMEM, - "Can't allocate memory for lzma stream"); - return (ARCHIVE_FATAL); - } - *strm = lzma_init_data; - r = lzma_alone_encoder(strm, &lzma_opt); - switch (r) { - case LZMA_OK: - lastrm->real_stream = strm; - lastrm->valid = 1; - lastrm->code = compression_code_lzma; - lastrm->end = compression_end_lzma; - r = ARCHIVE_OK; - break; - case LZMA_MEM_ERROR: - free(strm); - lastrm->real_stream = NULL; - archive_set_error(a, ENOMEM, - "Internal error initializing compression library: " - "Cannot allocate memory"); - r = ARCHIVE_FATAL; - break; - default: - free(strm); - lastrm->real_stream = NULL; - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Internal error initializing compression library: " - "It's a bug in liblzma"); - r = ARCHIVE_FATAL; - break; - } - return (r); -} - -static int -compression_init_encoder_xz(struct archive *a, - struct la_zstream *lastrm, int level, int threads) -{ - static const lzma_stream lzma_init_data = LZMA_STREAM_INIT; - lzma_stream *strm; - lzma_filter *lzmafilters; - lzma_options_lzma lzma_opt; - int r; -#ifdef HAVE_LZMA_STREAM_ENCODER_MT - lzma_mt mt_options; -#endif - - (void)threads; /* UNUSED (if multi-threaded LZMA library not avail) */ - - if (lastrm->valid) - compression_end(a, lastrm); - strm = calloc(1, sizeof(*strm) + sizeof(*lzmafilters) * 2); - if (strm == NULL) { - archive_set_error(a, ENOMEM, - "Can't allocate memory for xz stream"); - return (ARCHIVE_FATAL); - } - lzmafilters = (lzma_filter *)(strm+1); - if (level > 9) - level = 9; - if (lzma_lzma_preset(&lzma_opt, level)) { - free(strm); - lastrm->real_stream = NULL; - archive_set_error(a, ENOMEM, - "Internal error initializing compression library"); - return (ARCHIVE_FATAL); - } - lzmafilters[0].id = LZMA_FILTER_LZMA2; - lzmafilters[0].options = &lzma_opt; - lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */ - - *strm = lzma_init_data; -#ifdef HAVE_LZMA_STREAM_ENCODER_MT - if (threads > 1) { - memset(&mt_options, 0, sizeof(mt_options)); - mt_options.threads = threads; - mt_options.timeout = 300; - mt_options.filters = lzmafilters; - mt_options.check = LZMA_CHECK_CRC64; - r = lzma_stream_encoder_mt(strm, &mt_options); - } else -#endif - r = lzma_stream_encoder(strm, lzmafilters, LZMA_CHECK_CRC64); - switch (r) { - case LZMA_OK: - lastrm->real_stream = strm; - lastrm->valid = 1; - lastrm->code = compression_code_lzma; - lastrm->end = compression_end_lzma; - r = ARCHIVE_OK; - break; - case LZMA_MEM_ERROR: - free(strm); - lastrm->real_stream = NULL; - archive_set_error(a, ENOMEM, - "Internal error initializing compression library: " - "Cannot allocate memory"); - r = ARCHIVE_FATAL; - break; - default: - free(strm); - lastrm->real_stream = NULL; - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "Internal error initializing compression library: " - "It's a bug in liblzma"); - r = ARCHIVE_FATAL; - break; - } - return (r); -} - -static int -compression_code_lzma(struct archive *a, - struct la_zstream *lastrm, enum la_zaction action) -{ - lzma_stream *strm; - int r; - - strm = (lzma_stream *)lastrm->real_stream; - strm->next_in = lastrm->next_in; - strm->avail_in = lastrm->avail_in; - strm->total_in = lastrm->total_in; - strm->next_out = lastrm->next_out; - strm->avail_out = lastrm->avail_out; - strm->total_out = lastrm->total_out; - r = lzma_code(strm, - (action == ARCHIVE_Z_FINISH)? LZMA_FINISH: LZMA_RUN); - lastrm->next_in = strm->next_in; - lastrm->avail_in = strm->avail_in; - lastrm->total_in = strm->total_in; - lastrm->next_out = strm->next_out; - lastrm->avail_out = strm->avail_out; - lastrm->total_out = strm->total_out; - switch (r) { - case LZMA_OK: - /* Non-finishing case */ - return (ARCHIVE_OK); - case LZMA_STREAM_END: - /* This return can only occur in finishing case. */ - return (ARCHIVE_EOF); - case LZMA_MEMLIMIT_ERROR: - archive_set_error(a, ENOMEM, - "lzma compression error:" - " %ju MiB would have been needed", - (uintmax_t)((lzma_memusage(strm) + 1024 * 1024 -1) - / (1024 * 1024))); - return (ARCHIVE_FATAL); - default: - /* Any other return value indicates an error */ - archive_set_error(a, ARCHIVE_ERRNO_MISC, - "lzma compression failed:" - " lzma_code() call returned status %d", r); - return (ARCHIVE_FATAL); - } -} - -static int -compression_end_lzma(struct archive *a, struct la_zstream *lastrm) -{ - lzma_stream *strm; - - (void)a; /* UNUSED */ - strm = (lzma_stream *)lastrm->real_stream; - lzma_end(strm); - free(strm); - lastrm->valid = 0; - lastrm->real_stream = NULL; - return (ARCHIVE_OK); -} -#else -static int -compression_init_encoder_lzma(struct archive *a, - struct la_zstream *lastrm, int level) -{ - - (void) level; /* UNUSED */ - if (lastrm->valid) - compression_end(a, lastrm); - return (compression_unsupported_encoder(a, lastrm, "lzma")); -} -static int -compression_init_encoder_xz(struct archive *a, - struct la_zstream *lastrm, int level, int threads) -{ - - (void) level; /* UNUSED */ - (void) threads; /* UNUSED */ - if (lastrm->valid) - compression_end(a, lastrm); - return (compression_unsupported_encoder(a, lastrm, "xz")); -} -#endif - -static int -xar_compression_init_encoder(struct archive_write *a) -{ - struct xar *xar; - int r; - - xar = (struct xar *)a->format_data; - switch (xar->opt_compression) { - case GZIP: - r = compression_init_encoder_gzip( - &(a->archive), &(xar->stream), - xar->opt_compression_level, 1); - break; - case BZIP2: - r = compression_init_encoder_bzip2( - &(a->archive), &(xar->stream), - xar->opt_compression_level); - break; - case LZMA: - r = compression_init_encoder_lzma( - &(a->archive), &(xar->stream), - xar->opt_compression_level); - break; - case XZ: - r = compression_init_encoder_xz( - &(a->archive), &(xar->stream), - xar->opt_compression_level, xar->opt_threads); - break; - default: - r = ARCHIVE_OK; - break; - } - if (r == ARCHIVE_OK) { - xar->stream.total_in = 0; - xar->stream.next_out = xar->wbuff; - xar->stream.avail_out = sizeof(xar->wbuff); - xar->stream.total_out = 0; - } - - return (r); -} - -static int -compression_code(struct archive *a, struct la_zstream *lastrm, - enum la_zaction action) -{ - if (lastrm->valid) - return (lastrm->code(a, lastrm, action)); - return (ARCHIVE_OK); -} - -static int -compression_end(struct archive *a, struct la_zstream *lastrm) -{ - if (lastrm->valid) - return (lastrm->end(a, lastrm)); - return (ARCHIVE_OK); -} - - -static int -save_xattrs(struct archive_write *a, struct file *file) -{ - struct xar *xar; - const char *name; - const void *value; - struct heap_data *heap; - size_t size; - int count, r; - - xar = (struct xar *)a->format_data; - count = archive_entry_xattr_reset(file->entry); - if (count == 0) - return (ARCHIVE_OK); - while (count--) { - archive_entry_xattr_next(file->entry, - &name, &value, &size); - checksum_init(&(xar->a_sumwrk), xar->opt_sumalg); - checksum_init(&(xar->e_sumwrk), xar->opt_sumalg); - - heap = calloc(1, sizeof(*heap)); - if (heap == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for xattr"); - return (ARCHIVE_FATAL); - } - heap->id = file->ea_idx++; - heap->temp_offset = xar->temp_offset; - heap->size = size;/* save a extracted size */ - heap->compression = xar->opt_compression; - /* Get a extracted sumcheck value. */ - checksum_update(&(xar->e_sumwrk), value, size); - checksum_final(&(xar->e_sumwrk), &(heap->e_sum)); - - /* - * Not compression to xattr is simple way. - */ - if (heap->compression == NONE) { - checksum_update(&(xar->a_sumwrk), value, size); - checksum_final(&(xar->a_sumwrk), &(heap->a_sum)); - if (write_to_temp(a, value, size) - != ARCHIVE_OK) { - free(heap); - return (ARCHIVE_FATAL); - } - heap->length = size; - /* Add heap to the tail of file->xattr. */ - heap->next = NULL; - *file->xattr.last = heap; - file->xattr.last = &(heap->next); - /* Next xattr */ - continue; - } - - /* - * Init compression library. - */ - r = xar_compression_init_encoder(a); - if (r != ARCHIVE_OK) { - free(heap); - return (ARCHIVE_FATAL); - } - - xar->stream.next_in = (const unsigned char *)value; - xar->stream.avail_in = size; - for (;;) { - r = compression_code(&(a->archive), - &(xar->stream), ARCHIVE_Z_FINISH); - if (r != ARCHIVE_OK && r != ARCHIVE_EOF) { - free(heap); - return (ARCHIVE_FATAL); - } - size = sizeof(xar->wbuff) - xar->stream.avail_out; - checksum_update(&(xar->a_sumwrk), - xar->wbuff, size); - if (write_to_temp(a, xar->wbuff, size) - != ARCHIVE_OK) { - free(heap); - return (ARCHIVE_FATAL); - } - if (r == ARCHIVE_OK) { - xar->stream.next_out = xar->wbuff; - xar->stream.avail_out = sizeof(xar->wbuff); - } else { - checksum_final(&(xar->a_sumwrk), - &(heap->a_sum)); - heap->length = xar->stream.total_out; - /* Add heap to the tail of file->xattr. */ - heap->next = NULL; - *file->xattr.last = heap; - file->xattr.last = &(heap->next); - break; - } - } - /* Clean up compression library. */ - r = compression_end(&(a->archive), &(xar->stream)); - if (r != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } - return (ARCHIVE_OK); -} - -static int -getalgsize(enum sumalg sumalg) -{ - switch (sumalg) { - default: - case CKSUM_NONE: - return (0); - case CKSUM_SHA1: - return (SHA1_SIZE); - case CKSUM_MD5: - return (MD5_SIZE); - } -} - -static const char * -getalgname(enum sumalg sumalg) -{ - switch (sumalg) { - default: - case CKSUM_NONE: - return (NULL); - case CKSUM_SHA1: - return (SHA1_NAME); - case CKSUM_MD5: - return (MD5_NAME); - } -} - -#endif /* Support xar format */ diff --git a/thirdparty/libarchive/libarchive/archive_write_set_format_zip.c b/thirdparty/libarchive/libarchive/archive_write_set_format_zip.c deleted file mode 100644 index 6821049c9..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_set_format_zip.c +++ /dev/null @@ -1,1693 +0,0 @@ -/*- - * Copyright (c) 2008 Anselm Strauss - * Copyright (c) 2009 Joerg Sonnenberger - * Copyright (c) 2011-2012,2014 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -/* - * Development supported by Google Summer of Code 2008. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_zip.c 201168 2009-12-29 06:15:32Z kientzle $"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_LANGINFO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_ZLIB_H -#include -#endif - -#include "archive.h" -#include "archive_cryptor_private.h" -#include "archive_endian.h" -#include "archive_entry.h" -#include "archive_entry_locale.h" -#include "archive_hmac_private.h" -#include "archive_private.h" -#include "archive_random_private.h" -#include "archive_write_private.h" -#include "archive_write_set_format_private.h" - -#ifndef HAVE_ZLIB_H -#include "archive_crc32.h" -#endif - -#define ZIP_ENTRY_FLAG_ENCRYPTED (1<<0) -#define ZIP_ENTRY_FLAG_LENGTH_AT_END (1<<3) -#define ZIP_ENTRY_FLAG_UTF8_NAME (1 << 11) - -#define ZIP_4GB_MAX ARCHIVE_LITERAL_LL(0xffffffff) -#define ZIP_4GB_MAX_UNCOMPRESSED ARCHIVE_LITERAL_LL(0xff000000) - -enum compression { - COMPRESSION_UNSPECIFIED = -1, - COMPRESSION_STORE = 0, - COMPRESSION_DEFLATE = 8 -}; - -#ifdef HAVE_ZLIB_H -#define COMPRESSION_DEFAULT COMPRESSION_DEFLATE -#else -#define COMPRESSION_DEFAULT COMPRESSION_STORE -#endif - -enum encryption { - ENCRYPTION_NONE = 0, - ENCRYPTION_TRADITIONAL, /* Traditional PKWARE encryption. */ - ENCRYPTION_WINZIP_AES128, /* WinZIP AES-128 encryption. */ - ENCRYPTION_WINZIP_AES256, /* WinZIP AES-256 encryption. */ -}; - -#define TRAD_HEADER_SIZE 12 -/* - * See "WinZip - AES Encryption Information" - * http://www.winzip.com/aes_info.htm - */ -/* Value used in compression method. */ -#define WINZIP_AES_ENCRYPTION 99 -/* A WinZip AES header size which is stored at the beginning of - * file contents. */ -#define WINZIP_AES128_HEADER_SIZE (8 + 2) -#define WINZIP_AES256_HEADER_SIZE (16 + 2) -/* AES vendor version. */ -#define AES_VENDOR_AE_1 0x0001 -#define AES_VENDOR_AE_2 0x0002 -/* Authentication code size. */ -#define AUTH_CODE_SIZE 10 -/**/ -#define MAX_DERIVED_KEY_BUF_SIZE (AES_MAX_KEY_SIZE * 2 + 2) - -struct cd_segment { - struct cd_segment *next; - size_t buff_size; - unsigned char *buff; - unsigned char *p; -}; - -struct trad_enc_ctx { - uint32_t keys[3]; -}; - -struct zip { - - int64_t entry_offset; - int64_t entry_compressed_size; - int64_t entry_uncompressed_size; - int64_t entry_compressed_written; - int64_t entry_uncompressed_written; - int64_t entry_uncompressed_limit; - struct archive_entry *entry; - uint32_t entry_crc32; - enum compression entry_compression; - enum encryption entry_encryption; - int entry_flags; - int entry_uses_zip64; - int experiments; - struct trad_enc_ctx tctx; - char tctx_valid; - unsigned char trad_chkdat; - unsigned aes_vendor; - archive_crypto_ctx cctx; - char cctx_valid; - archive_hmac_sha1_ctx hctx; - char hctx_valid; - - unsigned char *file_header; - size_t file_header_extra_offset; - unsigned long (*crc32func)(unsigned long crc, const void *buff, size_t len); - - struct cd_segment *central_directory; - struct cd_segment *central_directory_last; - size_t central_directory_bytes; - size_t central_directory_entries; - - int64_t written_bytes; /* Overall position in file. */ - - struct archive_string_conv *opt_sconv; - struct archive_string_conv *sconv_default; - enum compression requested_compression; - int deflate_compression_level; - int init_default_conversion; - enum encryption encryption_type; - -#define ZIP_FLAG_AVOID_ZIP64 1 -#define ZIP_FLAG_FORCE_ZIP64 2 -#define ZIP_FLAG_EXPERIMENT_xl 4 - int flags; - -#ifdef HAVE_ZLIB_H - z_stream stream; -#endif - size_t len_buf; - unsigned char *buf; -}; - -/* Don't call this min or MIN, since those are already defined - on lots of platforms (but not all). */ -#define zipmin(a, b) ((a) > (b) ? (b) : (a)) - -static ssize_t archive_write_zip_data(struct archive_write *, - const void *buff, size_t s); -static int archive_write_zip_close(struct archive_write *); -static int archive_write_zip_free(struct archive_write *); -static int archive_write_zip_finish_entry(struct archive_write *); -static int archive_write_zip_header(struct archive_write *, - struct archive_entry *); -static int archive_write_zip_options(struct archive_write *, - const char *, const char *); -static unsigned int dos_time(const time_t); -static size_t path_length(struct archive_entry *); -static int write_path(struct archive_entry *, struct archive_write *); -static void copy_path(struct archive_entry *, unsigned char *); -static struct archive_string_conv *get_sconv(struct archive_write *, struct zip *); -static int trad_enc_init(struct trad_enc_ctx *, const char *, size_t); -static unsigned trad_enc_encrypt_update(struct trad_enc_ctx *, const uint8_t *, - size_t, uint8_t *, size_t); -static int init_traditional_pkware_encryption(struct archive_write *); -static int is_traditional_pkware_encryption_supported(void); -static int init_winzip_aes_encryption(struct archive_write *); -static int is_winzip_aes_encryption_supported(int encryption); - -static unsigned char * -cd_alloc(struct zip *zip, size_t length) -{ - unsigned char *p; - - if (zip->central_directory == NULL - || (zip->central_directory_last->p + length - > zip->central_directory_last->buff + zip->central_directory_last->buff_size)) { - struct cd_segment *segment = calloc(1, sizeof(*segment)); - if (segment == NULL) - return NULL; - segment->buff_size = 64 * 1024; - segment->buff = malloc(segment->buff_size); - if (segment->buff == NULL) { - free(segment); - return NULL; - } - segment->p = segment->buff; - - if (zip->central_directory == NULL) { - zip->central_directory - = zip->central_directory_last - = segment; - } else { - zip->central_directory_last->next = segment; - zip->central_directory_last = segment; - } - } - - p = zip->central_directory_last->p; - zip->central_directory_last->p += length; - zip->central_directory_bytes += length; - return (p); -} - -static unsigned long -real_crc32(unsigned long crc, const void *buff, size_t len) -{ - return crc32(crc, buff, (unsigned int)len); -} - -static unsigned long -fake_crc32(unsigned long crc, const void *buff, size_t len) -{ - (void)crc; /* UNUSED */ - (void)buff; /* UNUSED */ - (void)len; /* UNUSED */ - return 0; -} - -static int -archive_write_zip_options(struct archive_write *a, const char *key, - const char *val) -{ - struct zip *zip = a->format_data; - int ret = ARCHIVE_FAILED; - - if (strcmp(key, "compression") == 0) { - /* - * Set compression to use on all future entries. - * This only affects regular files. - */ - if (val == NULL || val[0] == 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "%s: compression option needs a compression name", - a->format_name); - } else if (strcmp(val, "deflate") == 0) { -#ifdef HAVE_ZLIB_H - zip->requested_compression = COMPRESSION_DEFLATE; - ret = ARCHIVE_OK; -#else - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "deflate compression not supported"); -#endif - } else if (strcmp(val, "store") == 0) { - zip->requested_compression = COMPRESSION_STORE; - ret = ARCHIVE_OK; - } - return (ret); - } else if (strcmp(key, "compression-level") == 0) { - if (val == NULL || !(val[0] >= '0' && val[0] <= '9') || val[1] != '\0') { - return ARCHIVE_WARN; - } - - if (val[0] == '0') { - zip->requested_compression = COMPRESSION_STORE; - return ARCHIVE_OK; - } else { -#ifdef HAVE_ZLIB_H - zip->requested_compression = COMPRESSION_DEFLATE; - zip->deflate_compression_level = val[0] - '0'; - return ARCHIVE_OK; -#else - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "deflate compression not supported"); -#endif - } - } else if (strcmp(key, "encryption") == 0) { - if (val == NULL) { - zip->encryption_type = ENCRYPTION_NONE; - ret = ARCHIVE_OK; - } else if (val[0] == '1' || strcmp(val, "traditional") == 0 - || strcmp(val, "zipcrypt") == 0 - || strcmp(val, "ZipCrypt") == 0) { - if (is_traditional_pkware_encryption_supported()) { - zip->encryption_type = ENCRYPTION_TRADITIONAL; - ret = ARCHIVE_OK; - } else { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "encryption not supported"); - } - } else if (strcmp(val, "aes128") == 0) { - if (is_winzip_aes_encryption_supported( - ENCRYPTION_WINZIP_AES128)) { - zip->encryption_type = ENCRYPTION_WINZIP_AES128; - ret = ARCHIVE_OK; - } else { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "encryption not supported"); - } - } else if (strcmp(val, "aes256") == 0) { - if (is_winzip_aes_encryption_supported( - ENCRYPTION_WINZIP_AES256)) { - zip->encryption_type = ENCRYPTION_WINZIP_AES256; - ret = ARCHIVE_OK; - } else { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "encryption not supported"); - } - } else { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "%s: unknown encryption '%s'", - a->format_name, val); - } - return (ret); - } else if (strcmp(key, "experimental") == 0) { - if (val == NULL || val[0] == 0) { - zip->flags &= ~ ZIP_FLAG_EXPERIMENT_xl; - } else { - zip->flags |= ZIP_FLAG_EXPERIMENT_xl; - } - return (ARCHIVE_OK); - } else if (strcmp(key, "fakecrc32") == 0) { - /* - * FOR TESTING ONLY: disable CRC calculation to speed up - * certain complex tests. - */ - if (val == NULL || val[0] == 0) { - zip->crc32func = real_crc32; - } else { - zip->crc32func = fake_crc32; - } - return (ARCHIVE_OK); - } else if (strcmp(key, "hdrcharset") == 0) { - /* - * Set the character set used in translating filenames. - */ - if (val == NULL || val[0] == 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "%s: hdrcharset option needs a character-set name", - a->format_name); - } else { - zip->opt_sconv = archive_string_conversion_to_charset( - &a->archive, val, 0); - if (zip->opt_sconv != NULL) - ret = ARCHIVE_OK; - else - ret = ARCHIVE_FATAL; - } - return (ret); - } else if (strcmp(key, "zip64") == 0) { - /* - * Bias decisions about Zip64: force them to be - * generated in certain cases where they are not - * forbidden or avoid them in certain cases where they - * are not strictly required. - */ - if (val != NULL && *val != '\0') { - zip->flags |= ZIP_FLAG_FORCE_ZIP64; - zip->flags &= ~ZIP_FLAG_AVOID_ZIP64; - } else { - zip->flags &= ~ZIP_FLAG_FORCE_ZIP64; - zip->flags |= ZIP_FLAG_AVOID_ZIP64; - } - return (ARCHIVE_OK); - } - - /* Note: The "warn" return is just to inform the options - * supervisor that we didn't handle it. It will generate - * a suitable error if no one used this option. */ - return (ARCHIVE_WARN); -} - -int -archive_write_zip_set_compression_deflate(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - int ret = ARCHIVE_FAILED; - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW | ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, - "archive_write_zip_set_compression_deflate"); - if (a->archive.archive_format != ARCHIVE_FORMAT_ZIP) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Can only use archive_write_zip_set_compression_deflate" - " with zip format"); - ret = ARCHIVE_FATAL; - } else { -#ifdef HAVE_ZLIB_H - struct zip *zip = a->format_data; - zip->requested_compression = COMPRESSION_DEFLATE; - ret = ARCHIVE_OK; -#else - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "deflate compression not supported"); - ret = ARCHIVE_FAILED; -#endif - } - return (ret); -} - -int -archive_write_zip_set_compression_store(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - struct zip *zip = a->format_data; - int ret = ARCHIVE_FAILED; - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW | ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, - "archive_write_zip_set_compression_deflate"); - if (a->archive.archive_format != ARCHIVE_FORMAT_ZIP) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Can only use archive_write_zip_set_compression_store" - " with zip format"); - ret = ARCHIVE_FATAL; - } else { - zip->requested_compression = COMPRESSION_STORE; - ret = ARCHIVE_OK; - } - return (ret); -} - -int -archive_write_set_format_zip(struct archive *_a) -{ - struct archive_write *a = (struct archive_write *)_a; - struct zip *zip; - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, - ARCHIVE_STATE_NEW, "archive_write_set_format_zip"); - - /* If another format was already registered, unregister it. */ - if (a->format_free != NULL) - (a->format_free)(a); - - zip = (struct zip *) calloc(1, sizeof(*zip)); - if (zip == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate zip data"); - return (ARCHIVE_FATAL); - } - - /* "Unspecified" lets us choose the appropriate compression. */ - zip->requested_compression = COMPRESSION_UNSPECIFIED; -#ifdef HAVE_ZLIB_H - zip->deflate_compression_level = Z_DEFAULT_COMPRESSION; -#endif - zip->crc32func = real_crc32; - - /* A buffer used for both compression and encryption. */ - zip->len_buf = 65536; - zip->buf = malloc(zip->len_buf); - if (zip->buf == NULL) { - free(zip); - archive_set_error(&a->archive, ENOMEM, - "Can't allocate compression buffer"); - return (ARCHIVE_FATAL); - } - - a->format_data = zip; - a->format_name = "zip"; - a->format_options = archive_write_zip_options; - a->format_write_header = archive_write_zip_header; - a->format_write_data = archive_write_zip_data; - a->format_finish_entry = archive_write_zip_finish_entry; - a->format_close = archive_write_zip_close; - a->format_free = archive_write_zip_free; - a->archive.archive_format = ARCHIVE_FORMAT_ZIP; - a->archive.archive_format_name = "ZIP"; - - return (ARCHIVE_OK); -} - -static int -is_all_ascii(const char *p) -{ - const unsigned char *pp = (const unsigned char *)p; - - while (*pp) { - if (*pp++ > 127) - return (0); - } - return (1); -} - -static int -archive_write_zip_header(struct archive_write *a, struct archive_entry *entry) -{ - unsigned char local_header[32]; - unsigned char local_extra[144]; - struct zip *zip = a->format_data; - unsigned char *e; - unsigned char *cd_extra; - size_t filename_length; - const char *slink = NULL; - size_t slink_size = 0; - struct archive_string_conv *sconv = get_sconv(a, zip); - int ret, ret2 = ARCHIVE_OK; - mode_t type; - int version_needed = 10; - - /* Ignore types of entries that we don't support. */ - type = archive_entry_filetype(entry); - if (type != AE_IFREG && type != AE_IFDIR && type != AE_IFLNK) { - __archive_write_entry_filetype_unsupported( - &a->archive, entry, "zip"); - return ARCHIVE_FAILED; - }; - - /* If we're not using Zip64, reject large files. */ - if (zip->flags & ZIP_FLAG_AVOID_ZIP64) { - /* Reject entries over 4GB. */ - if (archive_entry_size_is_set(entry) - && (archive_entry_size(entry) > ZIP_4GB_MAX)) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Files > 4GB require Zip64 extensions"); - return ARCHIVE_FAILED; - } - /* Reject entries if archive is > 4GB. */ - if (zip->written_bytes > ZIP_4GB_MAX) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Archives > 4GB require Zip64 extensions"); - return ARCHIVE_FAILED; - } - } - - /* Only regular files can have size > 0. */ - if (type != AE_IFREG) - archive_entry_set_size(entry, 0); - - - /* Reset information from last entry. */ - zip->entry_offset = zip->written_bytes; - zip->entry_uncompressed_limit = INT64_MAX; - zip->entry_compressed_size = 0; - zip->entry_uncompressed_size = 0; - zip->entry_compressed_written = 0; - zip->entry_uncompressed_written = 0; - zip->entry_flags = 0; - zip->entry_uses_zip64 = 0; - zip->entry_crc32 = zip->crc32func(0, NULL, 0); - zip->entry_encryption = 0; - archive_entry_free(zip->entry); - zip->entry = NULL; - - if (zip->cctx_valid) - archive_encrypto_aes_ctr_release(&zip->cctx); - if (zip->hctx_valid) - archive_hmac_sha1_cleanup(&zip->hctx); - zip->tctx_valid = zip->cctx_valid = zip->hctx_valid = 0; - - if (type == AE_IFREG - &&(!archive_entry_size_is_set(entry) - || archive_entry_size(entry) > 0)) { - switch (zip->encryption_type) { - case ENCRYPTION_TRADITIONAL: - case ENCRYPTION_WINZIP_AES128: - case ENCRYPTION_WINZIP_AES256: - zip->entry_flags |= ZIP_ENTRY_FLAG_ENCRYPTED; - zip->entry_encryption = zip->encryption_type; - break; - case ENCRYPTION_NONE: - default: - break; - } - } - - -#if defined(_WIN32) && !defined(__CYGWIN__) - /* Make sure the path separators in pathname, hardlink and symlink - * are all slash '/', not the Windows path separator '\'. */ - zip->entry = __la_win_entry_in_posix_pathseparator(entry); - if (zip->entry == entry) - zip->entry = archive_entry_clone(entry); -#else - zip->entry = archive_entry_clone(entry); -#endif - if (zip->entry == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate zip header data"); - return (ARCHIVE_FATAL); - } - - if (sconv != NULL) { - const char *p; - size_t len; - - if (archive_entry_pathname_l(entry, &p, &len, sconv) != 0) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory for Pathname"); - return (ARCHIVE_FATAL); - } - archive_set_error(&a->archive, - ARCHIVE_ERRNO_FILE_FORMAT, - "Can't translate Pathname '%s' to %s", - archive_entry_pathname(entry), - archive_string_conversion_charset_name(sconv)); - ret2 = ARCHIVE_WARN; - } - if (len > 0) - archive_entry_set_pathname(zip->entry, p); - - /* - * There is no standard for symlink handling; we convert - * it using the same character-set translation that we use - * for filename. - */ - if (type == AE_IFLNK) { - if (archive_entry_symlink_l(entry, &p, &len, sconv)) { - if (errno == ENOMEM) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate memory " - " for Symlink"); - return (ARCHIVE_FATAL); - } - /* No error if we can't convert. */ - } else if (len > 0) - archive_entry_set_symlink(zip->entry, p); - } - } - - /* If filename isn't ASCII and we can use UTF-8, set the UTF-8 flag. */ - if (!is_all_ascii(archive_entry_pathname(zip->entry))) { - if (zip->opt_sconv != NULL) { - if (strcmp(archive_string_conversion_charset_name( - zip->opt_sconv), "UTF-8") == 0) - zip->entry_flags |= ZIP_ENTRY_FLAG_UTF8_NAME; -#if HAVE_NL_LANGINFO - } else if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0) { - zip->entry_flags |= ZIP_ENTRY_FLAG_UTF8_NAME; -#endif - } - } - filename_length = path_length(zip->entry); - - /* Determine appropriate compression and size for this entry. */ - if (type == AE_IFLNK) { - slink = archive_entry_symlink(zip->entry); - if (slink != NULL) - slink_size = strlen(slink); - else - slink_size = 0; - zip->entry_uncompressed_limit = slink_size; - zip->entry_compressed_size = slink_size; - zip->entry_uncompressed_size = slink_size; - zip->entry_crc32 = zip->crc32func(zip->entry_crc32, - (const unsigned char *)slink, slink_size); - zip->entry_compression = COMPRESSION_STORE; - version_needed = 20; - } else if (type != AE_IFREG) { - zip->entry_compression = COMPRESSION_STORE; - zip->entry_uncompressed_limit = 0; - version_needed = 20; - } else if (archive_entry_size_is_set(zip->entry)) { - int64_t size = archive_entry_size(zip->entry); - int64_t additional_size = 0; - - zip->entry_uncompressed_limit = size; - zip->entry_compression = zip->requested_compression; - if (zip->entry_compression == COMPRESSION_UNSPECIFIED) { - zip->entry_compression = COMPRESSION_DEFAULT; - } - if (zip->entry_compression == COMPRESSION_STORE) { - zip->entry_compressed_size = size; - zip->entry_uncompressed_size = size; - version_needed = 10; - } else { - zip->entry_uncompressed_size = size; - version_needed = 20; - } - - if (zip->entry_flags & ZIP_ENTRY_FLAG_ENCRYPTED) { - switch (zip->entry_encryption) { - case ENCRYPTION_TRADITIONAL: - additional_size = TRAD_HEADER_SIZE; - version_needed = 20; - break; - case ENCRYPTION_WINZIP_AES128: - additional_size = WINZIP_AES128_HEADER_SIZE - + AUTH_CODE_SIZE; - version_needed = 20; - break; - case ENCRYPTION_WINZIP_AES256: - additional_size = WINZIP_AES256_HEADER_SIZE - + AUTH_CODE_SIZE; - version_needed = 20; - break; - case ENCRYPTION_NONE: - default: - break; - } - if (zip->entry_compression == COMPRESSION_STORE) - zip->entry_compressed_size += additional_size; - } - - /* - * Set Zip64 extension in any of the following cases - * (this was suggested by discussion on info-zip-dev - * mailing list): - * = Zip64 is being forced by user - * = File is over 4GiB uncompressed - * (including encryption header, if any) - * = File is close to 4GiB and is being compressed - * (compression might make file larger) - */ - if ((zip->flags & ZIP_FLAG_FORCE_ZIP64) - || (zip->entry_uncompressed_size + additional_size > ZIP_4GB_MAX) - || (zip->entry_uncompressed_size > ZIP_4GB_MAX_UNCOMPRESSED - && zip->entry_compression != COMPRESSION_STORE)) { - zip->entry_uses_zip64 = 1; - version_needed = 45; - } - - /* We may know the size, but never the CRC. */ - zip->entry_flags |= ZIP_ENTRY_FLAG_LENGTH_AT_END; - } else { - /* We don't know the size. Use the default - * compression unless specified otherwise. - * We enable Zip64 extensions unless we're told not to. - */ - - zip->entry_compression = zip->requested_compression; - if(zip->entry_compression == COMPRESSION_UNSPECIFIED){ - zip->entry_compression = COMPRESSION_DEFAULT; - } - - zip->entry_flags |= ZIP_ENTRY_FLAG_LENGTH_AT_END; - if ((zip->flags & ZIP_FLAG_AVOID_ZIP64) == 0) { - zip->entry_uses_zip64 = 1; - version_needed = 45; - } else if (zip->entry_compression == COMPRESSION_STORE) { - version_needed = 10; - } else { - version_needed = 20; - } - - if (zip->entry_flags & ZIP_ENTRY_FLAG_ENCRYPTED) { - switch (zip->entry_encryption) { - case ENCRYPTION_TRADITIONAL: - case ENCRYPTION_WINZIP_AES128: - case ENCRYPTION_WINZIP_AES256: - if (version_needed < 20) - version_needed = 20; - break; - case ENCRYPTION_NONE: - default: - break; - } - } - } - - /* Format the local header. */ - memset(local_header, 0, sizeof(local_header)); - memcpy(local_header, "PK\003\004", 4); - archive_le16enc(local_header + 4, version_needed); - archive_le16enc(local_header + 6, zip->entry_flags); - if (zip->entry_encryption == ENCRYPTION_WINZIP_AES128 - || zip->entry_encryption == ENCRYPTION_WINZIP_AES256) - archive_le16enc(local_header + 8, WINZIP_AES_ENCRYPTION); - else - archive_le16enc(local_header + 8, zip->entry_compression); - archive_le32enc(local_header + 10, - dos_time(archive_entry_mtime(zip->entry))); - archive_le32enc(local_header + 14, zip->entry_crc32); - if (zip->entry_uses_zip64) { - /* Zip64 data in the local header "must" include both - * compressed and uncompressed sizes AND those fields - * are included only if these are 0xffffffff; - * THEREFORE these must be set this way, even if we - * know one of them is smaller. */ - archive_le32enc(local_header + 18, ZIP_4GB_MAX); - archive_le32enc(local_header + 22, ZIP_4GB_MAX); - } else { - archive_le32enc(local_header + 18, (uint32_t)zip->entry_compressed_size); - archive_le32enc(local_header + 22, (uint32_t)zip->entry_uncompressed_size); - } - archive_le16enc(local_header + 26, (uint16_t)filename_length); - - if (zip->entry_encryption == ENCRYPTION_TRADITIONAL) { - if (zip->entry_flags & ZIP_ENTRY_FLAG_LENGTH_AT_END) - zip->trad_chkdat = local_header[11]; - else - zip->trad_chkdat = local_header[17]; - } - - /* Format as much of central directory file header as we can: */ - zip->file_header = cd_alloc(zip, 46); - /* If (zip->file_header == NULL) XXXX */ - ++zip->central_directory_entries; - memset(zip->file_header, 0, 46); - memcpy(zip->file_header, "PK\001\002", 4); - /* "Made by PKZip 2.0 on Unix." */ - archive_le16enc(zip->file_header + 4, 3 * 256 + version_needed); - archive_le16enc(zip->file_header + 6, version_needed); - archive_le16enc(zip->file_header + 8, zip->entry_flags); - if (zip->entry_encryption == ENCRYPTION_WINZIP_AES128 - || zip->entry_encryption == ENCRYPTION_WINZIP_AES256) - archive_le16enc(zip->file_header + 10, WINZIP_AES_ENCRYPTION); - else - archive_le16enc(zip->file_header + 10, zip->entry_compression); - archive_le32enc(zip->file_header + 12, - dos_time(archive_entry_mtime(zip->entry))); - archive_le16enc(zip->file_header + 28, (uint16_t)filename_length); - /* Following Info-Zip, store mode in the "external attributes" field. */ - archive_le32enc(zip->file_header + 38, - ((uint32_t)archive_entry_mode(zip->entry)) << 16); - e = cd_alloc(zip, filename_length); - /* If (e == NULL) XXXX */ - copy_path(zip->entry, e); - - /* Format extra data. */ - memset(local_extra, 0, sizeof(local_extra)); - e = local_extra; - - /* First, extra blocks that are the same between - * the local file header and the central directory. - * We format them once and then duplicate them. */ - - /* UT timestamp, length depends on what timestamps are set. */ - memcpy(e, "UT", 2); - archive_le16enc(e + 2, - 1 - + (archive_entry_mtime_is_set(entry) ? 4 : 0) - + (archive_entry_atime_is_set(entry) ? 4 : 0) - + (archive_entry_ctime_is_set(entry) ? 4 : 0)); - e += 4; - *e++ = - (archive_entry_mtime_is_set(entry) ? 1 : 0) - | (archive_entry_atime_is_set(entry) ? 2 : 0) - | (archive_entry_ctime_is_set(entry) ? 4 : 0); - if (archive_entry_mtime_is_set(entry)) { - archive_le32enc(e, (uint32_t)archive_entry_mtime(entry)); - e += 4; - } - if (archive_entry_atime_is_set(entry)) { - archive_le32enc(e, (uint32_t)archive_entry_atime(entry)); - e += 4; - } - if (archive_entry_ctime_is_set(entry)) { - archive_le32enc(e, (uint32_t)archive_entry_ctime(entry)); - e += 4; - } - - /* ux Unix extra data, length 11, version 1 */ - /* TODO: If uid < 64k, use 2 bytes, ditto for gid. */ - memcpy(e, "ux\013\000\001", 5); - e += 5; - *e++ = 4; /* Length of following UID */ - archive_le32enc(e, (uint32_t)archive_entry_uid(entry)); - e += 4; - *e++ = 4; /* Length of following GID */ - archive_le32enc(e, (uint32_t)archive_entry_gid(entry)); - e += 4; - - /* AES extra data field: WinZIP AES information, ID=0x9901 */ - if ((zip->entry_flags & ZIP_ENTRY_FLAG_ENCRYPTED) - && (zip->entry_encryption == ENCRYPTION_WINZIP_AES128 - || zip->entry_encryption == ENCRYPTION_WINZIP_AES256)) { - - memcpy(e, "\001\231\007\000\001\000AE", 8); - /* AES vendor version AE-2 does not store a CRC. - * WinZip 11 uses AE-1, which does store the CRC, - * but it does not store the CRC when the file size - * is less than 20 bytes. So we simulate what - * WinZip 11 does. - * NOTE: WinZip 9.0 and 10.0 uses AE-2 by default. */ - if (archive_entry_size_is_set(zip->entry) - && archive_entry_size(zip->entry) < 20) { - archive_le16enc(e+4, AES_VENDOR_AE_2); - zip->aes_vendor = AES_VENDOR_AE_2;/* no CRC. */ - } else - zip->aes_vendor = AES_VENDOR_AE_1; - e += 8; - /* AES encryption strength. */ - *e++ = (zip->entry_encryption == ENCRYPTION_WINZIP_AES128)?1:3; - /* Actual compression method. */ - archive_le16enc(e, zip->entry_compression); - e += 2; - } - - /* Copy UT ,ux, and AES-extra into central directory as well. */ - zip->file_header_extra_offset = zip->central_directory_bytes; - cd_extra = cd_alloc(zip, e - local_extra); - memcpy(cd_extra, local_extra, e - local_extra); - - /* - * Following extra blocks vary between local header and - * central directory. These are the local header versions. - * Central directory versions get formatted in - * archive_write_zip_finish_entry() below. - */ - - /* "[Zip64 entry] in the local header MUST include BOTH - * original [uncompressed] and compressed size fields." */ - if (zip->entry_uses_zip64) { - unsigned char *zip64_start = e; - memcpy(e, "\001\000\020\000", 4); - e += 4; - archive_le64enc(e, zip->entry_uncompressed_size); - e += 8; - archive_le64enc(e, zip->entry_compressed_size); - e += 8; - archive_le16enc(zip64_start + 2, (uint16_t)(e - (zip64_start + 4))); - } - - if (zip->flags & ZIP_FLAG_EXPERIMENT_xl) { - /* Experimental 'xl' extension to improve streaming. */ - unsigned char *external_info = e; - int included = 7; - memcpy(e, "xl\000\000", 4); // 0x6c65 + 2-byte length - e += 4; - e[0] = included; /* bitmap of included fields */ - e += 1; - if (included & 1) { - archive_le16enc(e, /* "Version created by" */ - 3 * 256 + version_needed); - e += 2; - } - if (included & 2) { - archive_le16enc(e, 0); /* internal file attributes */ - e += 2; - } - if (included & 4) { - archive_le32enc(e, /* external file attributes */ - ((uint32_t)archive_entry_mode(zip->entry)) << 16); - e += 4; - } - if (included & 8) { - // Libarchive does not currently support file comments. - } - archive_le16enc(external_info + 2, (uint16_t)(e - (external_info + 4))); - } - - /* Update local header with size of extra data and write it all out: */ - archive_le16enc(local_header + 28, (uint16_t)(e - local_extra)); - - ret = __archive_write_output(a, local_header, 30); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - zip->written_bytes += 30; - - ret = write_path(zip->entry, a); - if (ret <= ARCHIVE_OK) - return (ARCHIVE_FATAL); - zip->written_bytes += ret; - - ret = __archive_write_output(a, local_extra, e - local_extra); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - zip->written_bytes += e - local_extra; - - /* For symlinks, write the body now. */ - if (slink != NULL) { - ret = __archive_write_output(a, slink, slink_size); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - zip->entry_compressed_written += slink_size; - zip->entry_uncompressed_written += slink_size; - zip->written_bytes += slink_size; - } - -#ifdef HAVE_ZLIB_H - if (zip->entry_compression == COMPRESSION_DEFLATE) { - zip->stream.zalloc = Z_NULL; - zip->stream.zfree = Z_NULL; - zip->stream.opaque = Z_NULL; - zip->stream.next_out = zip->buf; - zip->stream.avail_out = (uInt)zip->len_buf; - if (deflateInit2(&zip->stream, zip->deflate_compression_level, - Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY) != Z_OK) { - archive_set_error(&a->archive, ENOMEM, - "Can't init deflate compressor"); - return (ARCHIVE_FATAL); - } - } -#endif - - return (ret2); -} - -static ssize_t -archive_write_zip_data(struct archive_write *a, const void *buff, size_t s) -{ - int ret; - struct zip *zip = a->format_data; - - if ((int64_t)s > zip->entry_uncompressed_limit) - s = (size_t)zip->entry_uncompressed_limit; - zip->entry_uncompressed_written += s; - - if (s == 0) return 0; - - if (zip->entry_flags & ZIP_ENTRY_FLAG_ENCRYPTED) { - switch (zip->entry_encryption) { - case ENCRYPTION_TRADITIONAL: - /* Initialize traditional PKWARE encryption context. */ - if (!zip->tctx_valid) { - ret = init_traditional_pkware_encryption(a); - if (ret != ARCHIVE_OK) - return (ret); - zip->tctx_valid = 1; - } - break; - case ENCRYPTION_WINZIP_AES128: - case ENCRYPTION_WINZIP_AES256: - if (!zip->cctx_valid) { - ret = init_winzip_aes_encryption(a); - if (ret != ARCHIVE_OK) - return (ret); - zip->cctx_valid = zip->hctx_valid = 1; - } - break; - case ENCRYPTION_NONE: - default: - break; - } - } - - switch (zip->entry_compression) { - case COMPRESSION_STORE: - if (zip->tctx_valid || zip->cctx_valid) { - const uint8_t *rb = (const uint8_t *)buff; - const uint8_t * const re = rb + s; - - while (rb < re) { - size_t l; - - if (zip->tctx_valid) { - l = trad_enc_encrypt_update(&zip->tctx, - rb, re - rb, - zip->buf, zip->len_buf); - } else { - l = zip->len_buf; - ret = archive_encrypto_aes_ctr_update( - &zip->cctx, - rb, re - rb, zip->buf, &l); - if (ret < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Failed to encrypt file"); - return (ARCHIVE_FAILED); - } - archive_hmac_sha1_update(&zip->hctx, - zip->buf, l); - } - ret = __archive_write_output(a, zip->buf, l); - if (ret != ARCHIVE_OK) - return (ret); - zip->entry_compressed_written += l; - zip->written_bytes += l; - rb += l; - } - } else { - ret = __archive_write_output(a, buff, s); - if (ret != ARCHIVE_OK) - return (ret); - zip->written_bytes += s; - zip->entry_compressed_written += s; - } - break; -#if HAVE_ZLIB_H - case COMPRESSION_DEFLATE: - zip->stream.next_in = (unsigned char*)(uintptr_t)buff; - zip->stream.avail_in = (uInt)s; - do { - ret = deflate(&zip->stream, Z_NO_FLUSH); - if (ret == Z_STREAM_ERROR) - return (ARCHIVE_FATAL); - if (zip->stream.avail_out == 0) { - if (zip->tctx_valid) { - trad_enc_encrypt_update(&zip->tctx, - zip->buf, zip->len_buf, - zip->buf, zip->len_buf); - } else if (zip->cctx_valid) { - size_t outl = zip->len_buf; - ret = archive_encrypto_aes_ctr_update( - &zip->cctx, - zip->buf, zip->len_buf, - zip->buf, &outl); - if (ret < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Failed to encrypt file"); - return (ARCHIVE_FAILED); - } - archive_hmac_sha1_update(&zip->hctx, - zip->buf, zip->len_buf); - } - ret = __archive_write_output(a, zip->buf, - zip->len_buf); - if (ret != ARCHIVE_OK) - return (ret); - zip->entry_compressed_written += zip->len_buf; - zip->written_bytes += zip->len_buf; - zip->stream.next_out = zip->buf; - zip->stream.avail_out = (uInt)zip->len_buf; - } - } while (zip->stream.avail_in != 0); - break; -#endif - - case COMPRESSION_UNSPECIFIED: - default: - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Invalid ZIP compression type"); - return ARCHIVE_FATAL; - } - - zip->entry_uncompressed_limit -= s; - if (!zip->cctx_valid || zip->aes_vendor != AES_VENDOR_AE_2) - zip->entry_crc32 = - zip->crc32func(zip->entry_crc32, buff, (unsigned)s); - return (s); - -} - -static int -archive_write_zip_finish_entry(struct archive_write *a) -{ - struct zip *zip = a->format_data; - int ret; - -#if HAVE_ZLIB_H - if (zip->entry_compression == COMPRESSION_DEFLATE) { - for (;;) { - size_t remainder; - - ret = deflate(&zip->stream, Z_FINISH); - if (ret == Z_STREAM_ERROR) - return (ARCHIVE_FATAL); - remainder = zip->len_buf - zip->stream.avail_out; - if (zip->tctx_valid) { - trad_enc_encrypt_update(&zip->tctx, - zip->buf, remainder, zip->buf, remainder); - } else if (zip->cctx_valid) { - size_t outl = remainder; - ret = archive_encrypto_aes_ctr_update( - &zip->cctx, zip->buf, remainder, - zip->buf, &outl); - if (ret < 0) { - archive_set_error(&a->archive, - ARCHIVE_ERRNO_MISC, - "Failed to encrypt file"); - return (ARCHIVE_FAILED); - } - archive_hmac_sha1_update(&zip->hctx, - zip->buf, remainder); - } - ret = __archive_write_output(a, zip->buf, remainder); - if (ret != ARCHIVE_OK) - return (ret); - zip->entry_compressed_written += remainder; - zip->written_bytes += remainder; - zip->stream.next_out = zip->buf; - if (zip->stream.avail_out != 0) - break; - zip->stream.avail_out = (uInt)zip->len_buf; - } - deflateEnd(&zip->stream); - } -#endif - if (zip->hctx_valid) { - uint8_t hmac[20]; - size_t hmac_len = 20; - - archive_hmac_sha1_final(&zip->hctx, hmac, &hmac_len); - ret = __archive_write_output(a, hmac, AUTH_CODE_SIZE); - if (ret != ARCHIVE_OK) - return (ret); - zip->entry_compressed_written += AUTH_CODE_SIZE; - zip->written_bytes += AUTH_CODE_SIZE; - } - - /* Write trailing data descriptor. */ - if ((zip->entry_flags & ZIP_ENTRY_FLAG_LENGTH_AT_END) != 0) { - char d[24]; - memcpy(d, "PK\007\010", 4); - if (zip->cctx_valid && zip->aes_vendor == AES_VENDOR_AE_2) - archive_le32enc(d + 4, 0);/* no CRC.*/ - else - archive_le32enc(d + 4, zip->entry_crc32); - if (zip->entry_uses_zip64) { - archive_le64enc(d + 8, - (uint64_t)zip->entry_compressed_written); - archive_le64enc(d + 16, - (uint64_t)zip->entry_uncompressed_written); - ret = __archive_write_output(a, d, 24); - zip->written_bytes += 24; - } else { - archive_le32enc(d + 8, - (uint32_t)zip->entry_compressed_written); - archive_le32enc(d + 12, - (uint32_t)zip->entry_uncompressed_written); - ret = __archive_write_output(a, d, 16); - zip->written_bytes += 16; - } - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - } - - /* Append Zip64 extra data to central directory information. */ - if (zip->entry_compressed_written > ZIP_4GB_MAX - || zip->entry_uncompressed_written > ZIP_4GB_MAX - || zip->entry_offset > ZIP_4GB_MAX) { - unsigned char zip64[32]; - unsigned char *z = zip64, *zd; - memcpy(z, "\001\000\000\000", 4); - z += 4; - if (zip->entry_uncompressed_written >= ZIP_4GB_MAX) { - archive_le64enc(z, zip->entry_uncompressed_written); - z += 8; - } - if (zip->entry_compressed_written >= ZIP_4GB_MAX) { - archive_le64enc(z, zip->entry_compressed_written); - z += 8; - } - if (zip->entry_offset >= ZIP_4GB_MAX) { - archive_le64enc(z, zip->entry_offset); - z += 8; - } - archive_le16enc(zip64 + 2, (uint16_t)(z - (zip64 + 4))); - zd = cd_alloc(zip, z - zip64); - if (zd == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate zip data"); - return (ARCHIVE_FATAL); - } - memcpy(zd, zip64, z - zip64); - /* Zip64 means version needs to be set to at least 4.5 */ - if (archive_le16dec(zip->file_header + 6) < 45) - archive_le16enc(zip->file_header + 6, 45); - } - - /* Fix up central directory file header. */ - if (zip->cctx_valid && zip->aes_vendor == AES_VENDOR_AE_2) - archive_le32enc(zip->file_header + 16, 0);/* no CRC.*/ - else - archive_le32enc(zip->file_header + 16, zip->entry_crc32); - archive_le32enc(zip->file_header + 20, - (uint32_t)zipmin(zip->entry_compressed_written, - ZIP_4GB_MAX)); - archive_le32enc(zip->file_header + 24, - (uint32_t)zipmin(zip->entry_uncompressed_written, - ZIP_4GB_MAX)); - archive_le16enc(zip->file_header + 30, - (uint16_t)(zip->central_directory_bytes - zip->file_header_extra_offset)); - archive_le32enc(zip->file_header + 42, - (uint32_t)zipmin(zip->entry_offset, - ZIP_4GB_MAX)); - - return (ARCHIVE_OK); -} - -static int -archive_write_zip_close(struct archive_write *a) -{ - uint8_t buff[64]; - int64_t offset_start, offset_end; - struct zip *zip = a->format_data; - struct cd_segment *segment; - int ret; - - offset_start = zip->written_bytes; - segment = zip->central_directory; - while (segment != NULL) { - ret = __archive_write_output(a, - segment->buff, segment->p - segment->buff); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - zip->written_bytes += segment->p - segment->buff; - segment = segment->next; - } - offset_end = zip->written_bytes; - - /* If central dir info is too large, write Zip64 end-of-cd */ - if (offset_end - offset_start > ZIP_4GB_MAX - || offset_start > ZIP_4GB_MAX - || zip->central_directory_entries > 0xffffUL - || (zip->flags & ZIP_FLAG_FORCE_ZIP64)) { - /* Zip64 end-of-cd record */ - memset(buff, 0, 56); - memcpy(buff, "PK\006\006", 4); - archive_le64enc(buff + 4, 44); - archive_le16enc(buff + 12, 45); - archive_le16enc(buff + 14, 45); - /* This is disk 0 of 0. */ - archive_le64enc(buff + 24, zip->central_directory_entries); - archive_le64enc(buff + 32, zip->central_directory_entries); - archive_le64enc(buff + 40, offset_end - offset_start); - archive_le64enc(buff + 48, offset_start); - ret = __archive_write_output(a, buff, 56); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - zip->written_bytes += 56; - - /* Zip64 end-of-cd locator record. */ - memset(buff, 0, 20); - memcpy(buff, "PK\006\007", 4); - archive_le32enc(buff + 4, 0); - archive_le64enc(buff + 8, offset_end); - archive_le32enc(buff + 16, 1); - ret = __archive_write_output(a, buff, 20); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - zip->written_bytes += 20; - - } - - /* Format and write end of central directory. */ - memset(buff, 0, sizeof(buff)); - memcpy(buff, "PK\005\006", 4); - archive_le16enc(buff + 8, (uint16_t)zipmin(0xffffU, - zip->central_directory_entries)); - archive_le16enc(buff + 10, (uint16_t)zipmin(0xffffU, - zip->central_directory_entries)); - archive_le32enc(buff + 12, - (uint32_t)zipmin(ZIP_4GB_MAX, (offset_end - offset_start))); - archive_le32enc(buff + 16, - (uint32_t)zipmin(ZIP_4GB_MAX, offset_start)); - ret = __archive_write_output(a, buff, 22); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - zip->written_bytes += 22; - return (ARCHIVE_OK); -} - -static int -archive_write_zip_free(struct archive_write *a) -{ - struct zip *zip; - struct cd_segment *segment; - - zip = a->format_data; - while (zip->central_directory != NULL) { - segment = zip->central_directory; - zip->central_directory = segment->next; - free(segment->buff); - free(segment); - } - free(zip->buf); - archive_entry_free(zip->entry); - if (zip->cctx_valid) - archive_encrypto_aes_ctr_release(&zip->cctx); - if (zip->hctx_valid) - archive_hmac_sha1_cleanup(&zip->hctx); - /* TODO: Free opt_sconv, sconv_default */ - - free(zip); - a->format_data = NULL; - return (ARCHIVE_OK); -} - -/* Convert into MSDOS-style date/time. */ -static unsigned int -dos_time(const time_t unix_time) -{ - struct tm *t; - unsigned int dt; -#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S) - struct tm tmbuf; -#endif - -#if defined(HAVE_LOCALTIME_S) - t = localtime_s(&tmbuf, &unix_time) ? NULL : &tmbuf; -#elif defined(HAVE_LOCALTIME_R) - t = localtime_r(&unix_time, &tmbuf); -#else - t = localtime(&unix_time); -#endif - - /* MSDOS-style date/time is only between 1980-01-01 and 2107-12-31 */ - if (t->tm_year < 1980 - 1900) - /* Set minimum date/time '1980-01-01 00:00:00'. */ - dt = 0x00210000U; - else if (t->tm_year > 2107 - 1900) - /* Set maximum date/time '2107-12-31 23:59:58'. */ - dt = 0xff9fbf7dU; - else { - dt = 0; - dt += ((t->tm_year - 80) & 0x7f) << 9; - dt += ((t->tm_mon + 1) & 0x0f) << 5; - dt += (t->tm_mday & 0x1f); - dt <<= 16; - dt += (t->tm_hour & 0x1f) << 11; - dt += (t->tm_min & 0x3f) << 5; - dt += (t->tm_sec & 0x3e) >> 1; /* Only counting every 2 seconds. */ - } - return dt; -} - -static size_t -path_length(struct archive_entry *entry) -{ - mode_t type; - const char *path; - size_t len; - - type = archive_entry_filetype(entry); - path = archive_entry_pathname(entry); - - if (path == NULL) - return (0); - len = strlen(path); - if (type == AE_IFDIR && (path[0] == '\0' || path[len - 1] != '/')) - ++len; /* Space for the trailing / */ - return len; -} - -static int -write_path(struct archive_entry *entry, struct archive_write *archive) -{ - int ret; - const char *path; - mode_t type; - size_t written_bytes; - - path = archive_entry_pathname(entry); - type = archive_entry_filetype(entry); - written_bytes = 0; - - if (path == NULL) - return (ARCHIVE_FATAL); - - ret = __archive_write_output(archive, path, strlen(path)); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - written_bytes += strlen(path); - - /* Folders are recognized by a trailing slash. */ - if ((type == AE_IFDIR) & (path[strlen(path) - 1] != '/')) { - ret = __archive_write_output(archive, "/", 1); - if (ret != ARCHIVE_OK) - return (ARCHIVE_FATAL); - written_bytes += 1; - } - - return ((int)written_bytes); -} - -static void -copy_path(struct archive_entry *entry, unsigned char *p) -{ - const char *path; - size_t pathlen; - mode_t type; - - path = archive_entry_pathname(entry); - pathlen = strlen(path); - type = archive_entry_filetype(entry); - - memcpy(p, path, pathlen); - - /* Folders are recognized by a trailing slash. */ - if ((type == AE_IFDIR) && (path[pathlen - 1] != '/')) - p[pathlen] = '/'; -} - - -static struct archive_string_conv * -get_sconv(struct archive_write *a, struct zip *zip) -{ - if (zip->opt_sconv != NULL) - return (zip->opt_sconv); - - if (!zip->init_default_conversion) { - zip->sconv_default = - archive_string_default_conversion_for_write(&(a->archive)); - zip->init_default_conversion = 1; - } - return (zip->sconv_default); -} - -/* - Traditional PKWARE Decryption functions. - */ - -static void -trad_enc_update_keys(struct trad_enc_ctx *ctx, uint8_t c) -{ - uint8_t t; -#define CRC32(c, b) (crc32(c ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL) - - ctx->keys[0] = CRC32(ctx->keys[0], c); - ctx->keys[1] = (ctx->keys[1] + (ctx->keys[0] & 0xff)) * 134775813L + 1; - t = (ctx->keys[1] >> 24) & 0xff; - ctx->keys[2] = CRC32(ctx->keys[2], t); -#undef CRC32 -} - -static uint8_t -trad_enc_decrypt_byte(struct trad_enc_ctx *ctx) -{ - unsigned temp = ctx->keys[2] | 2; - return (uint8_t)((temp * (temp ^ 1)) >> 8) & 0xff; -} - -static unsigned -trad_enc_encrypt_update(struct trad_enc_ctx *ctx, const uint8_t *in, - size_t in_len, uint8_t *out, size_t out_len) -{ - unsigned i, max; - - max = (unsigned)((in_len < out_len)? in_len: out_len); - - for (i = 0; i < max; i++) { - uint8_t t = in[i]; - out[i] = t ^ trad_enc_decrypt_byte(ctx); - trad_enc_update_keys(ctx, t); - } - return i; -} - -static int -trad_enc_init(struct trad_enc_ctx *ctx, const char *pw, size_t pw_len) -{ - - ctx->keys[0] = 305419896L; - ctx->keys[1] = 591751049L; - ctx->keys[2] = 878082192L; - - for (;pw_len; --pw_len) - trad_enc_update_keys(ctx, *pw++); - return 0; -} - -static int -is_traditional_pkware_encryption_supported(void) -{ - uint8_t key[TRAD_HEADER_SIZE]; - - if (archive_random(key, sizeof(key)-1) != ARCHIVE_OK) - return (0); - return (1); -} - -static int -init_traditional_pkware_encryption(struct archive_write *a) -{ - struct zip *zip = a->format_data; - const char *passphrase; - uint8_t key[TRAD_HEADER_SIZE]; - uint8_t key_encrypted[TRAD_HEADER_SIZE]; - int ret; - - passphrase = __archive_write_get_passphrase(a); - if (passphrase == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Encryption needs passphrase"); - return ARCHIVE_FAILED; - } - if (archive_random(key, sizeof(key)-1) != ARCHIVE_OK) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Can't generate random number for encryption"); - return ARCHIVE_FATAL; - } - trad_enc_init(&zip->tctx, passphrase, strlen(passphrase)); - /* Set the last key code which will be used as a check code - * for verifying passphrase in decryption. */ - key[TRAD_HEADER_SIZE-1] = zip->trad_chkdat; - trad_enc_encrypt_update(&zip->tctx, key, TRAD_HEADER_SIZE, - key_encrypted, TRAD_HEADER_SIZE); - /* Write encrypted keys in the top of the file content. */ - ret = __archive_write_output(a, key_encrypted, TRAD_HEADER_SIZE); - if (ret != ARCHIVE_OK) - return (ret); - zip->written_bytes += TRAD_HEADER_SIZE; - zip->entry_compressed_written += TRAD_HEADER_SIZE; - return (ret); -} - -static int -init_winzip_aes_encryption(struct archive_write *a) -{ - struct zip *zip = a->format_data; - const char *passphrase; - size_t key_len, salt_len; - uint8_t salt[16 + 2]; - uint8_t derived_key[MAX_DERIVED_KEY_BUF_SIZE]; - int ret; - - passphrase = __archive_write_get_passphrase(a); - if (passphrase == NULL) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Encryption needs passphrase"); - return (ARCHIVE_FAILED); - } - if (zip->entry_encryption == ENCRYPTION_WINZIP_AES128) { - salt_len = 8; - key_len = 16; - } else { - /* AES 256 */ - salt_len = 16; - key_len = 32; - } - if (archive_random(salt, salt_len) != ARCHIVE_OK) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Can't generate random number for encryption"); - return (ARCHIVE_FATAL); - } - archive_pbkdf2_sha1(passphrase, strlen(passphrase), - salt, salt_len, 1000, derived_key, key_len * 2 + 2); - - ret = archive_encrypto_aes_ctr_init(&zip->cctx, derived_key, key_len); - if (ret != 0) { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Decryption is unsupported due to lack of crypto library"); - return (ARCHIVE_FAILED); - } - ret = archive_hmac_sha1_init(&zip->hctx, derived_key + key_len, - key_len); - if (ret != 0) { - archive_encrypto_aes_ctr_release(&zip->cctx); - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Failed to initialize HMAC-SHA1"); - return (ARCHIVE_FAILED); - } - - /* Set a password verification value after the 'salt'. */ - salt[salt_len] = derived_key[key_len * 2]; - salt[salt_len + 1] = derived_key[key_len * 2 + 1]; - - /* Write encrypted keys in the top of the file content. */ - ret = __archive_write_output(a, salt, salt_len + 2); - if (ret != ARCHIVE_OK) - return (ret); - zip->written_bytes += salt_len + 2; - zip->entry_compressed_written += salt_len + 2; - - return (ARCHIVE_OK); -} - -static int -is_winzip_aes_encryption_supported(int encryption) -{ - size_t key_len, salt_len; - uint8_t salt[16 + 2]; - uint8_t derived_key[MAX_DERIVED_KEY_BUF_SIZE]; - archive_crypto_ctx cctx; - archive_hmac_sha1_ctx hctx; - int ret; - - if (encryption == ENCRYPTION_WINZIP_AES128) { - salt_len = 8; - key_len = 16; - } else { - /* AES 256 */ - salt_len = 16; - key_len = 32; - } - if (archive_random(salt, salt_len) != ARCHIVE_OK) - return (0); - ret = archive_pbkdf2_sha1("p", 1, salt, salt_len, 1000, - derived_key, key_len * 2 + 2); - if (ret != 0) - return (0); - - ret = archive_encrypto_aes_ctr_init(&cctx, derived_key, key_len); - if (ret != 0) - return (0); - ret = archive_hmac_sha1_init(&hctx, derived_key + key_len, - key_len); - archive_encrypto_aes_ctr_release(&cctx); - if (ret != 0) - return (0); - archive_hmac_sha1_cleanup(&hctx); - return (1); -} diff --git a/thirdparty/libarchive/libarchive/archive_write_set_options.3 b/thirdparty/libarchive/libarchive/archive_write_set_options.3 deleted file mode 100644 index f4b5081e2..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_set_options.3 +++ /dev/null @@ -1,729 +0,0 @@ -.\" Copyright (c) 2003-2010 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd January 31, 2020 -.Dt ARCHIVE_WRITE_OPTIONS 3 -.Os -.Sh NAME -.Nm archive_write_set_filter_option , -.Nm archive_write_set_format_option , -.Nm archive_write_set_option , -.Nm archive_write_set_options -.Nd functions controlling options for writing archives -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.Ft int -.Fo archive_write_set_filter_option -.Fa "struct archive *" -.Fa "const char *module" -.Fa "const char *option" -.Fa "const char *value" -.Fc -.Ft int -.Fo archive_write_set_format_option -.Fa "struct archive *" -.Fa "const char *module" -.Fa "const char *option" -.Fa "const char *value" -.Fc -.Ft int -.Fo archive_write_set_option -.Fa "struct archive *" -.Fa "const char *module" -.Fa "const char *option" -.Fa "const char *value" -.Fc -.Ft int -.Fo archive_write_set_options -.Fa "struct archive *" -.Fa "const char *options" -.Fc -.Sh DESCRIPTION -These functions provide a way for libarchive clients to configure -specific write modules. -.Bl -tag -width indent -.It Xo -.Fn archive_write_set_filter_option , -.Fn archive_write_set_format_option -.Xc -Specifies an option that will be passed to the currently-registered -filters (including decompression filters) or format readers. -.Pp -If -.Ar option -and -.Ar value -are both -.Dv NULL , -these functions will do nothing and -.Cm ARCHIVE_OK -will be returned. -If -.Ar option -is -.Dv NULL -but -.Ar value -is not, these functions will do nothing and -.Cm ARCHIVE_FAILED -will be returned. -.Pp -If -.Ar module -is not -.Dv NULL , -.Ar option -and -.Ar value -will be provided to the filter or reader named -.Ar module . -The return value will be either -.Cm ARCHIVE_OK -if the option was successfully handled or -.Cm ARCHIVE_WARN -if the option was unrecognized by the module or could otherwise -not be handled. -If there is no such module, -.Cm ARCHIVE_FAILED -will be returned. -.Pp -If -.Ar module -is -.Dv NULL , -.Ar option -and -.Ar value -will be provided to every registered module. -If any module returns -.Cm ARCHIVE_FATAL , -this value will be returned immediately. -Otherwise, -.Cm ARCHIVE_OK -will be returned if any module accepts the option, and -.Cm ARCHIVE_FAILED -in all other cases. -.\" -.It Fn archive_write_set_option -Calls -.Fn archive_write_set_format_option , -then -.Fn archive_write_set_filter_option . -If either function returns -.Cm ARCHIVE_FATAL , -.Cm ARCHIVE_FATAL -will be returned -immediately. -Otherwise, the greater of the two values will be returned. -.\" -.It Fn archive_write_set_options -.Ar options -is a comma-separated list of options. -If -.Ar options -is -.Dv NULL -or empty, -.Cm ARCHIVE_OK -will be returned immediately. -.Pp -Individual options have one of the following forms: -.Bl -tag -compact -width indent -.It Ar option=value -The option/value pair will be provided to every module. -Modules that do not accept an option with this name will ignore it. -.It Ar option -The option will be provided to every module with a value of -.Dq 1 . -.It Ar !option -The option will be provided to every module with a NULL value. -.It Ar module:option=value , Ar module:option , Ar module:!option -As above, but the corresponding option and value will be provided -only to modules whose name matches -.Ar module . -.El -.El -.\" -.Sh OPTIONS -.Bl -tag -compact -width indent -.It Filter b64encode -.Bl -tag -compact -width indent -.It Cm mode -The value is interpreted as octal digits specifying the file mode. -.It Cm name -The value specifies the file name. -.El -.It Filter bzip2 -.Bl -tag -compact -width indent -.It Cm compression-level -The value is interpreted as a decimal integer specifying the -bzip2 compression level. Supported values are from 1 to 9. -.El -.It Filter gzip -.Bl -tag -compact -width indent -.It Cm compression-level -The value is interpreted as a decimal integer specifying the -gzip compression level. Supported values are from 0 to 9. -.It Cm timestamp -Store timestamp. This is enabled by default. -.El -.It Filter lrzip -.Bl -tag -compact -width indent -.It Cm compression Ns = Ns Ar type -Use -.Ar type -as compression method. -Supported values are -.Dq bzip2 , -.Dq gzipi , -.Dq lzo -.Pq ultra fast , -and -.Dq zpaq -.Pq best, extremely slow . -.It Cm compression-level -The value is interpreted as a decimal integer specifying the -lrzip compression level. Supported values are from 1 to 9. -.El -.It Filter lz4 -.Bl -tag -compact -width indent -.It Cm compression-level -The value is interpreted as a decimal integer specifying the -lz4 compression level. Supported values are from 0 to 9. -.It Cm stream-checksum -Enable stream checksum. This is enabled by default. -.It Cm block-checksum -Enable block checksum. This is disabled by default. -.It Cm block-size -The value is interpreted as a decimal integer specifying the -lz4 compression block size. Supported values are from 4 to 7 -.Pq default . -.It Cm block-dependence -Use the previous block of the block being compressed for -a compression dictionary to improve compression ratio. -This is disabled by default. -.El -.It Filter lzop -.Bl -tag -compact -width indent -.It Cm compression-level -The value is interpreted as a decimal integer specifying the -lzop compression level. Supported values are from 1 to 9. -.El -.It Filter uuencode -.Bl -tag -compact -width indent -.It Cm mode -The value is interpreted as octal digits specifying the file mode. -.It Cm name -The value specifies the file name. -.El -.It Filter xz -.Bl -tag -compact -width indent -.It Cm compression-level -The value is interpreted as a decimal integer specifying the -compression level. Supported values are from 0 to 9. -.It Cm threads -The value is interpreted as a decimal integer specifying the -number of threads for multi-threaded lzma compression. -If supported, the default value is read from -.Fn lzma_cputhreads . -.El -.It Filter zstd -.Bl -tag -compact -width indent -.It Cm compression-level -The value is interpreted as a decimal integer specifying the -compression level. Supported values depend on the library version, -common values are from 1 to 22. -.It Cm long -Enables long distance matching. The value is interpreted as a -decimal integer specifying log2 window size in bytes. Values from -10 to 30 for 32 bit, or 31 for 64 bit, are supported. -.It Cm threads -The value is interpreted as a decimal integer specifying the -number of threads for multi-threaded zstd compression. -If set to 0, zstd will attempt to detect and use the number -of physical CPU cores. -.El -.It Format 7zip -.Bl -tag -compact -width indent -.It Cm compression -The value is one of -.Dq store , -.Dq deflate , -.Dq bzip2 , -.Dq lzma1 , -.Dq lzma2 -or -.Dq ppmd -to indicate how the following entries should be compressed. -Note that this setting is ignored for directories, symbolic links, -and other special entries. -.It Cm compression-level -The value is interpreted as a decimal integer specifying the -compression level. -Values between 0 and 9 are supported. -The interpretation of the compression level depends on the chosen -compression method. -.El -.It Format bin -.Bl -tag -compact -width indent -.It Cm hdrcharset -The value is used as a character set name that will be -used when translating file names. -.El -.It Format gnutar -.Bl -tag -compact -width indent -.It Cm hdrcharset -The value is used as a character set name that will be -used when translating file, group and user names. -.El -.It Format iso9660 - volume metadata -These options are used to set standard ISO9660 metadata. -.Bl -tag -compact -width indent -.It Cm abstract-file Ns = Ns Ar filename -The file with the specified name will be identified in the ISO9660 metadata -as holding the abstract for this volume. -Default: none. -.It Cm application-id Ns = Ns Ar filename -The file with the specified name will be identified in the ISO9660 metadata -as holding the application identifier for this volume. -Default: none. -.It Cm biblio-file Ns = Ns Ar filename -The file with the specified name will be identified in the ISO9660 metadata -as holding the bibliography for this volume. -Default: none. -.It Cm copyright-file Ns = Ns Ar filename -The file with the specified name will be identified in the ISO9660 metadata -as holding the copyright for this volume. -Default: none. -.It Cm publisher Ns = Ns Ar filename -The file with the specified name will be identified in the ISO9660 metadata -as holding the publisher information for this volume. -Default: none. -.It Cm volume-id Ns = Ns Ar string -The specified string will be used as the Volume Identifier in the ISO9660 metadata. -It is limited to 32 bytes. -Default: none. -.El -.It Format iso9660 - boot support -These options are used to make an ISO9660 image that can be directly -booted on various systems. -.Bl -tag -compact -width indent -.It Cm boot Ns = Ns Ar filename -The file matching this name will be used as the El Torito boot image file. -.It Cm boot-catalog Ns = Ns Ar name -The name that will be used for the El Torito boot catalog. -Default: -.Ar boot.catalog -.It Cm boot-info-table -The boot image file provided by the -.Cm boot Ns = Ns Ar filename -option will be edited with appropriate boot information in bytes 8 through 64. -Default: disabled -.It Cm boot-load-seg Ns = Ns Ar hexadecimal-number -The load segment for a no-emulation boot image. -.It Cm boot-load-size Ns = Ns Ar decimal-number -The number of "virtual" 512-byte sectors to be loaded from a no-emulation boot image. -Some very old BIOSes can only load very small images, setting this -value to 4 will often allow such BIOSes to load the first part of -the boot image (which will then need to be intelligent enough to -load the rest of itself). -This should not be needed unless you are trying to support systems with very old BIOSes. -This defaults to the full size of the image. -.It Cm boot-type Ns = Ns Ar value -Specifies the boot semantics used by the El Torito boot image: -If the -.Ar value -is -.Cm fd , -then the boot image is assumed to be a bootable floppy image. -If the -.Ar value -is -.Cm hd , -then the boot image is assumed to be a bootable hard disk image. -If the -.Ar value -is -.Cm no-emulation , -the boot image is used without floppy or hard disk emulation. -If the boot image is exactly 1.2MB, 1.44MB, or 2.88MB, then -the default is -.Cm fd , -otherwise the default is -.Cm no-emulation . -.El -.It Format iso9660 - filename and size extensions -Various extensions to the base ISO9660 format. -.Bl -tag -compact -width indent -.It Cm allow-ldots -If enabled, allows filenames to begin with a leading period. -If disabled, filenames that begin with a leading period will have -that period replaced by an underscore character in the standard ISO9660 -namespace. -This does not impact names stored in the Rockridge or Joliet extension area. -Default: disabled. -.It Cm allow-lowercase -If enabled, allows filenames to contain lowercase characters. -If disabled, filenames will be forced to uppercase. -This does not impact names stored in the Rockridge or Joliet extension area. -Default: disabled. -.It Cm allow-multidot -If enabled, allows filenames to contain multiple period characters, in violation of the ISO9660 specification. -If disabled, additional periods will be converted to underscore characters. -This does not impact names stored in the Rockridge or Joliet extension area. -Default: disabled. -.It Cm allow-period -If enabled, allows filenames to contain trailing period characters, in violation of the ISO9660 specification. -If disabled, trailing periods will be converted to underscore characters. -This does not impact names stored in the Rockridge or Joliet extension area. -Default: disabled. -.It Cm allow-pvd-lowercase -If enabled, the Primary Volume Descriptor may contain lowercase ASCII characters, in violation of the ISO9660 specification. -If disabled, characters will be converted to uppercase ASCII. -Default: disabled. -.It Cm allow-sharp-tilde -If enabled, sharp and tilde characters will be permitted in filenames, in violation if the ISO9660 specification. -If disabled, such characters will be converted to underscore characters. -Default: disabled. -.It Cm allow-vernum -If enabled, version numbers will be included with files. -If disabled, version numbers will be suppressed, in violation of the ISO9660 standard. -This does not impact names stored in the Rockridge or Joliet extension area. -Default: enabled. -.It Cm iso-level -This enables support for file size and file name extensions in the -core ISO9660 area. -The name extensions specified here do not affect the names stored in the Rockridge or Joliet extension areas. -.Bl -tag -compact -width indent -.It Cm iso-level=1 -The most compliant form of ISO9660 image. -Filenames are limited to 8.3 uppercase format, -directory names are limited to 8 uppercase characters, -files are limited to 4 GiB, -the complete ISO9660 image cannot exceed 4 GiB. -.It Cm iso-level=2 -Filenames are limited to 30 uppercase characters with a 30-character extension, -directory names are limited to 30 characters, -files are limited to 4 GiB. -.It Cm iso-level=3 -As with -.Cm iso-level=2 , -except that files may exceed 4 GiB. -.It Cm iso-level=4 -As with -.Cm iso-level=3 , -except that filenames may be up to 193 characters -and may include arbitrary 8-bit characters. -.El -.It Cm joliet -Microsoft's Joliet extensions store a completely separate set of directory information about each file. -In particular, this information includes Unicode filenames of up to 255 characters. -Default: enabled. -.It Cm limit-depth -If enabled, libarchive will use directory relocation records to ensure that -no pathname exceeds the ISO9660 limit of 8 directory levels. -If disabled, no relocation will occur. -Default: enabled. -.It Cm limit-dirs -If enabled, libarchive will cause an error if there are more than -65536 directories. -If disabled, there is no limit on the number of directories. -Default: enabled -.It Cm pad -If enabled, 300 kiB of zero bytes will be appended to the end of the archive. -Default: enabled -.It Cm relaxed-filenames -If enabled, all 7-bit ASCII characters are permitted in filenames -(except lowercase characters unless -.Cm allow-lowercase -is also specified). -This violates ISO9660 standards. -This does not impact names stored in the Rockridge or Joliet extension area. -Default: disabled. -.It Cm rockridge -The Rockridge extensions store an additional set of POSIX-style file -information with each file, including mtime, atime, ctime, permissions, -and long filenames with arbitrary 8-bit characters. -These extensions also support symbolic links and other POSIX file types. -Default: enabled. -.El -.It Format iso9660 - zisofs support -The zisofs extensions permit each file to be independently compressed -using a gzip-compatible compression. -This can provide significant size savings, but requires the reading -system to have support for these extensions. -These extensions are disabled by default. -.Bl -tag -compact -width indent -.It Cm compression-level Ns = Ns number -The compression level used by the deflate compressor. -Ranges from 0 (least effort) to 9 (most effort). -Default: 6 -.It Cm zisofs -Synonym for -.Cm zisofs=direct . -.It Cm zisofs=direct -Compress each file in the archive. -Unlike -.Cm zisofs=indirect , -this is handled entirely within libarchive and does not require a -separate utility. -For best results, libarchive tests each file and will store -the file uncompressed if the compression does not actually save any space. -In particular, files under 2k will never be compressed. -Note that boot image files are never compressed. -.It Cm zisofs=indirect -Recognizes files that have already been compressed with the -.Cm mkzftree -utility and sets up the necessary file metadata so that -readers will correctly identify these as zisofs-compressed files. -.It Cm zisofs-exclude Ns = Ns Ar filename -Specifies a filename that should not be compressed when using -.Cm zisofs=direct . -This option can be provided multiple times to suppress compression -on many files. -.El -.It Format mtree -.Bl -tag -compact -width indent -.It Cm cksum , Cm device , Cm flags , Cm gid , Cm gname , Cm indent , Cm link , Cm md5 , Cm mode , Cm nlink , Cm rmd160 , Cm sha1 , Cm sha256 , Cm sha384 , Cm sha512 , Cm size , Cm time , Cm uid , Cm uname -Enable a particular keyword in the mtree output. -Prefix with an exclamation mark to disable the corresponding keyword. -The default is equivalent to -.Dq device, flags, gid, gname, link, mode, nlink, size, time, type, uid, uname . -.It Cm all -Enables all of the above keywords. -.It Cm use-set -Enables generation of -.Cm /set -lines that specify default values for the following files and/or directories. -.It Cm indent -XXX needs explanation XXX -.El -.It Format newc -.Bl -tag -compact -width indent -.It Cm hdrcharset -The value is used as a character set name that will be -used when translating file names. -.El -.It Format odc -.Bl -tag -compact -width indent -.It Cm hdrcharset -The value is used as a character set name that will be -used when translating file names. -.El -.It Format pwb -.Bl -tag -compact -width indent -.It Cm hdrcharset -The value is used as a character set name that will be -used when translating file names. -.El -.It Format pax -.Bl -tag -compact -width indent -.It Cm hdrcharset -The value is used as a character set name that will be -used when translating file, group and user names. -The value is one of -.Dq BINARY -or -.Dq UTF-8 . -With -.Dq BINARY -there is no character conversion, with -.Dq UTF-8 -names are converted to UTF-8. -.It Cm xattrheader -When storing extended attributes, this option configures which -headers should be written. The value is one of -.Dq all , -.Dq LIBARCHIVE , -or -.Dq SCHILY . -By default, both -.Dq LIBARCHIVE.xattr -and -.Dq SCHILY.xattr -headers are written. -.El -.It Format ustar -.Bl -tag -compact -width indent -.It Cm hdrcharset -The value is used as a character set name that will be -used when translating file, group and user names. -.El -.It Format v7tar -.Bl -tag -compact -width indent -.It Cm hdrcharset -The value is used as a character set name that will be -used when translating file, group and user names. -.El -.It Format warc -.Bl -tag -compact -width indent -.It Cm omit-warcinfo -Set to -.Dq true -to disable output of the warcinfo record. -.El -.It Format xar -.Bl -tag -compact -width indent -.It Cm checksum Ns = Ns Ar type -Use -.Ar type -as file checksum method. -Supported values are -.Dq none , -.Dq md5 , -and -.Dq sha1 -.Pq default . -.It Cm compression Ns = Ns Ar type -Use -.Ar type -as compression method. -Supported values are -.Dq none , -.Dq bzip2 , -.Dq gzip -.Pq default , -.Dq lzma -and -.Dq xz . -.It Cm compression_level -The value is a decimal integer from 1 to 9 specifying the compression level. -.It Cm toc-checksum Ns = Ns Ar type -Use -.Ar type -as table of contents checksum method. -Supported values are -.Dq none , -.Dq md5 -and -.Dq sha1 -.Pq default . -.El -.It Format zip -.Bl -tag -compact -width indent -.It Cm compression -The value is either -.Dq store -or -.Dq deflate -to indicate how the following entries should be compressed. -Note that this setting is ignored for directories, symbolic links, -and other special entries. -.It Cm compression-level -The value is interpreted as a decimal integer specifying the -compression level. -Values between 0 and 9 are supported. -A compression level of 0 switches the compression method to -.Dq store , -other values will enable -.Dq deflate -compression with the given level. -.It Cm encryption -Enable encryption using traditional zip encryption. -.It Cm encryption Ns = Ns Ar type -Use -.Ar type -as encryption type. -Supported values are -.Dq zipcrypt -.Pq traditional zip encryption , -.Dq aes128 -.Pq WinZip AES-128 encryption -and -.Dq aes256 -.Pq WinZip AES-256 encryption . -.It Cm experimental -This boolean option enables or disables experimental Zip features -that may not be compatible with other Zip implementations. -.It Cm fakecrc32 -This boolean option disables CRC calculations. -All CRC fields are set to zero. -It should not be used except for testing purposes. -.It Cm hdrcharset -The value is used as a character set name that will be -used when translating file names. -.It Cm zip64 -Zip64 extensions provide additional file size information -for entries larger than 4 GiB. -They also provide extended file offset and archive size information -when archives exceed 4 GiB. -By default, the Zip writer selectively enables these extensions only as needed. -In particular, if the file size is unknown, the Zip writer will -include Zip64 extensions to guard against the possibility that the -file might be larger than 4 GiB. -.Pp -Setting this boolean option will force the writer to use Zip64 extensions -even for small files that would not otherwise require them. -This is primarily useful for testing. -.Pp -Disabling this option with -.Cm !zip64 -will force the Zip writer to avoid Zip64 extensions: -It will reject files with size greater than 4 GiB, -it will reject any new entries once the total archive size reaches 4 GiB, -and it will not use Zip64 extensions for files with unknown size. -In particular, this can improve compatibility when generating archives -where the entry sizes are not known in advance. -.El -.El -.Sh EXAMPLES -The following example creates an archive write handle to -create a gzip-compressed ISO9660 format image. -The two options here specify that the ISO9660 archive will use -.Ar kernel.img -as the boot image for El Torito booting, and that the gzip -compressor should use the maximum compression level. -.Bd -literal -offset indent -a = archive_write_new(); -archive_write_add_filter_gzip(a); -archive_write_set_format_iso9660(a); -archive_write_set_options(a, "boot=kernel.img,compression=9"); -archive_write_open_filename(a, filename, blocksize); -.Ed -.\" -.Sh ERRORS -More detailed error codes and textual descriptions are available from the -.Fn archive_errno -and -.Fn archive_error_string -functions. -.\" -.Sh SEE ALSO -.Xr tar 1 , -.Xr archive_read_set_options 3 , -.Xr archive_write 3 , -.Xr libarchive 3 -.Sh HISTORY -The -.Nm libarchive -library first appeared in -.Fx 5.3 . -.Sh AUTHORS -.An -nosplit -The options support for libarchive was originally implemented by -.An Michihiro NAKAJIMA . -.Sh BUGS diff --git a/thirdparty/libarchive/libarchive/archive_write_set_options.c b/thirdparty/libarchive/libarchive/archive_write_set_options.c deleted file mode 100644 index 962309ada..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_set_options.c +++ /dev/null @@ -1,130 +0,0 @@ -/*- - * Copyright (c) 2003-2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#include "archive_write_private.h" -#include "archive_options_private.h" - -static int archive_set_format_option(struct archive *a, - const char *m, const char *o, const char *v); -static int archive_set_filter_option(struct archive *a, - const char *m, const char *o, const char *v); -static int archive_set_option(struct archive *a, - const char *m, const char *o, const char *v); - -int -archive_write_set_format_option(struct archive *a, const char *m, const char *o, - const char *v) -{ - return _archive_set_option(a, m, o, v, - ARCHIVE_WRITE_MAGIC, "archive_write_set_format_option", - archive_set_format_option); -} - -int -archive_write_set_filter_option(struct archive *a, const char *m, const char *o, - const char *v) -{ - return _archive_set_option(a, m, o, v, - ARCHIVE_WRITE_MAGIC, "archive_write_set_filter_option", - archive_set_filter_option); -} - -int -archive_write_set_option(struct archive *a, const char *m, const char *o, - const char *v) -{ - return _archive_set_option(a, m, o, v, - ARCHIVE_WRITE_MAGIC, "archive_write_set_option", - archive_set_option); -} - -int -archive_write_set_options(struct archive *a, const char *options) -{ - return _archive_set_options(a, options, - ARCHIVE_WRITE_MAGIC, "archive_write_set_options", - archive_set_option); -} - -static int -archive_set_format_option(struct archive *_a, const char *m, const char *o, - const char *v) -{ - struct archive_write *a = (struct archive_write *)_a; - - if (a->format_name == NULL) - return (m == NULL)?ARCHIVE_FAILED:ARCHIVE_WARN - 1; - /* If the format name didn't match, return a special code for - * _archive_set_option[s]. */ - if (m != NULL && strcmp(m, a->format_name) != 0) - return (ARCHIVE_WARN - 1); - if (a->format_options == NULL) - return (ARCHIVE_WARN); - return a->format_options(a, o, v); -} - -static int -archive_set_filter_option(struct archive *_a, const char *m, const char *o, - const char *v) -{ - struct archive_write *a = (struct archive_write *)_a; - struct archive_write_filter *filter; - int r, rv = ARCHIVE_WARN; - - for (filter = a->filter_first; filter != NULL; filter = filter->next_filter) { - if (filter->options == NULL) - continue; - if (m != NULL && strcmp(filter->name, m) != 0) - continue; - - r = filter->options(filter, o, v); - - if (r == ARCHIVE_FATAL) - return (ARCHIVE_FATAL); - - if (m != NULL) - return (r); - - if (r == ARCHIVE_OK) - rv = ARCHIVE_OK; - } - /* If the filter name didn't match, return a special code for - * _archive_set_option[s]. */ - if (rv == ARCHIVE_WARN && m != NULL) - rv = ARCHIVE_WARN - 1; - return (rv); -} - -static int -archive_set_option(struct archive *a, const char *m, const char *o, - const char *v) -{ - return _archive_set_either_option(a, m, o, v, - archive_set_format_option, - archive_set_filter_option); -} diff --git a/thirdparty/libarchive/libarchive/archive_write_set_passphrase.3 b/thirdparty/libarchive/libarchive/archive_write_set_passphrase.3 deleted file mode 100644 index 2db77034c..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_set_passphrase.3 +++ /dev/null @@ -1,74 +0,0 @@ -.\" Copyright (c) 2014 Michihiro NAKAJIMA -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd September 21, 2014 -.Dt ARCHIVE_WRITE_SET_PASSPHRASE 3 -.Os -.Sh NAME -.Nm archive_write_set_passphrase , -.Nm archive_write_set_passphrase_callback -.Nd functions for writing encrypted archives -.Sh LIBRARY -Streaming Archive Library (libarchive, -larchive) -.Sh SYNOPSIS -.In archive.h -.Ft int -.Fo archive_write_set_passphrase -.Fa "struct archive *" -.Fa "const char *passphrase" -.Fc -.Ft int -.Fo archive_write_set_passphrase_callback -.Fa "struct archive *" -.Fa "void *client_data" -.Fa "archive_passphrase_callback *" -.Fc -.Sh DESCRIPTION -.Bl -tag -width indent -.It Fn archive_write_set_passphrase -Set a passphrase for writing an encrypted archive. -If -.Ar passphrase -is -.Dv NULL -or empty, this function will do nothing and -.Cm ARCHIVE_FAILED -will be returned. -Otherwise, -.Cm ARCHIVE_OK -will be returned. -.It Fn archive_write_set_passphrase_callback -Register a callback function that will be invoked to get a passphrase -for encryption if the passphrase was not set by the -.Fn archive_write_set_passphrase -function. -.El -.\" .Sh ERRORS -.Sh SEE ALSO -.Xr tar 1 , -.Xr archive_write 3 , -.Xr archive_write_set_options 3 , -.Xr libarchive 3 diff --git a/thirdparty/libarchive/libarchive/archive_write_set_passphrase.c b/thirdparty/libarchive/libarchive/archive_write_set_passphrase.c deleted file mode 100644 index 710ecba52..000000000 --- a/thirdparty/libarchive/libarchive/archive_write_set_passphrase.c +++ /dev/null @@ -1,95 +0,0 @@ -/*- - * Copyright (c) 2014 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#include "archive_write_private.h" - -int -archive_write_set_passphrase(struct archive *_a, const char *p) -{ - struct archive_write *a = (struct archive_write *)_a; - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_NEW, - "archive_write_set_passphrase"); - - if (p == NULL || p[0] == '\0') { - archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, - "Empty passphrase is unacceptable"); - return (ARCHIVE_FAILED); - } - free(a->passphrase); - a->passphrase = strdup(p); - if (a->passphrase == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate data for passphrase"); - return (ARCHIVE_FATAL); - } - return (ARCHIVE_OK); -} - - -int -archive_write_set_passphrase_callback(struct archive *_a, void *client_data, - archive_passphrase_callback *cb) -{ - struct archive_write *a = (struct archive_write *)_a; - - archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_NEW, - "archive_write_set_passphrase_callback"); - - a->passphrase_callback = cb; - a->passphrase_client_data = client_data; - return (ARCHIVE_OK); -} - - -const char * -__archive_write_get_passphrase(struct archive_write *a) -{ - - if (a->passphrase != NULL) - return (a->passphrase); - - if (a->passphrase_callback != NULL) { - const char *p; - p = a->passphrase_callback(&a->archive, - a->passphrase_client_data); - if (p != NULL) { - a->passphrase = strdup(p); - if (a->passphrase == NULL) { - archive_set_error(&a->archive, ENOMEM, - "Can't allocate data for passphrase"); - return (NULL); - } - return (a->passphrase); - } - } - return (NULL); -} diff --git a/thirdparty/libarchive/libarchive/archive_xxhash.h b/thirdparty/libarchive/libarchive/archive_xxhash.h deleted file mode 100644 index 1c7131ca1..000000000 --- a/thirdparty/libarchive/libarchive/archive_xxhash.h +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2014 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - * - */ - -#ifndef ARCHIVE_XXHASH_H_INCLUDED -#define ARCHIVE_XXHASH_H_INCLUDED - -#ifndef __LIBARCHIVE_BUILD -#error This header is only to be used internally to libarchive. -#endif - - -typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; - -struct archive_xxhash { - unsigned int (*XXH32)(const void* input, unsigned int len, - unsigned int seed); - void* (*XXH32_init)(unsigned int seed); - XXH_errorcode (*XXH32_update)(void* state, const void* input, - unsigned int len); - unsigned int (*XXH32_digest)(void* state); -}; - -extern const struct archive_xxhash __archive_xxhash; - -#endif diff --git a/thirdparty/libarchive/libarchive/config_freebsd.h b/thirdparty/libarchive/libarchive/config_freebsd.h deleted file mode 100644 index 669f27246..000000000 --- a/thirdparty/libarchive/libarchive/config_freebsd.h +++ /dev/null @@ -1,276 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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$ - */ -#define __LIBARCHIVE_CONFIG_H_INCLUDED 1 - -#include - -/* FreeBSD 5.0 and later has ACL and extattr support. */ -#if __FreeBSD__ > 4 -#define ARCHIVE_ACL_FREEBSD 1 -#define HAVE_ACL_GET_PERM_NP 1 -#define HAVE_ARC4RANDOM_BUF 1 -#define HAVE_EXTATTR_GET_FILE 1 -#define HAVE_EXTATTR_LIST_FILE 1 -#define HAVE_EXTATTR_SET_FD 1 -#define HAVE_EXTATTR_SET_FILE 1 -#define HAVE_STRUCT_XVFSCONF 1 -#define HAVE_SYS_ACL_H 1 -#define HAVE_SYS_EXTATTR_H 1 -#if __FreeBSD__ > 7 -/* FreeBSD 8.0 and later has NFSv4 ACL support */ -#define ARCHIVE_ACL_FREEBSD_NFS4 1 -#define HAVE_ACL_GET_LINK_NP 1 -#define HAVE_ACL_IS_TRIVIAL_NP 1 -#define HAVE_ACL_SET_LINK_NP 1 -#endif /* __FreeBSD__ > 7 */ -#endif /* __FreeBSD__ > 4 */ - -#ifdef WITH_OPENSSL -#define HAVE_LIBCRYPTO 1 -#define HAVE_OPENSSL_EVP_H 1 -#define HAVE_OPENSSL_MD5_H 1 -#define HAVE_OPENSSL_RIPEMD_H 1 -#define HAVE_OPENSSL_SHA_H 1 -#define HAVE_OPENSSL_SHA256_INIT 1 -#define HAVE_OPENSSL_SHA384_INIT 1 -#define HAVE_OPENSSL_SHA512_INIT 1 -#define HAVE_PKCS5_PBKDF2_HMAC_SHA1 1 -#define HAVE_SHA256 1 -#define HAVE_SHA384 1 -#define HAVE_SHA512 1 -#else -#define HAVE_LIBMD 1 -#define HAVE_MD5_H 1 -#define HAVE_MD5INIT 1 -#define HAVE_RIPEMD_H 1 -#define HAVE_SHA_H 1 -#define HAVE_SHA1 1 -#define HAVE_SHA1_INIT 1 -#define HAVE_SHA256 1 -#define HAVE_SHA256_H 1 -#define HAVE_SHA256_INIT 1 -#define HAVE_SHA512 1 -#define HAVE_SHA512_H 1 -#define HAVE_SHA512_INIT 1 -#endif - -#define HAVE_BSDXML_H 1 -#define HAVE_BZLIB_H 1 -#define HAVE_CHFLAGS 1 -#define HAVE_CHOWN 1 -#define HAVE_CHROOT 1 -#define HAVE_CTIME_R 1 -#define HAVE_CTYPE_H 1 -#define HAVE_DECL_EXTATTR_NAMESPACE_USER 1 -#define HAVE_DECL_INT32_MAX 1 -#define HAVE_DECL_INT32_MIN 1 -#define HAVE_DECL_INT64_MAX 1 -#define HAVE_DECL_INT64_MIN 1 -#define HAVE_DECL_INTMAX_MAX 1 -#define HAVE_DECL_INTMAX_MIN 1 -#define HAVE_DECL_SIZE_MAX 1 -#define HAVE_DECL_SSIZE_MAX 1 -#define HAVE_DECL_STRERROR_R 1 -#define HAVE_DECL_UINT32_MAX 1 -#define HAVE_DECL_UINT64_MAX 1 -#define HAVE_DECL_UINTMAX_MAX 1 -#define HAVE_DIRENT_H 1 -#define HAVE_DLFCN_H 1 -#define HAVE_D_MD_ORDER 1 -#define HAVE_EFTYPE 1 -#define HAVE_EILSEQ 1 -#define HAVE_ERRNO_H 1 -#define HAVE_FCHDIR 1 -#define HAVE_FCHFLAGS 1 -#define HAVE_FCHMOD 1 -#define HAVE_FCHOWN 1 -#define HAVE_FCNTL 1 -#define HAVE_FCNTL_H 1 -#define HAVE_FDOPENDIR 1 -#define HAVE_FNMATCH 1 -#define HAVE_FNMATCH_H 1 -#define HAVE_FORK 1 -#define HAVE_FSEEKO 1 -#define HAVE_FSTAT 1 -#define HAVE_FSTATAT 1 -#define HAVE_FSTATFS 1 -#define HAVE_FSTATVFS 1 -#define HAVE_FTRUNCATE 1 -#define HAVE_FUTIMES 1 -#define HAVE_FUTIMESAT 1 -#define HAVE_GETEUID 1 -#define HAVE_GETGRGID_R 1 -#define HAVE_GETGRNAM_R 1 -#define HAVE_GETLINE 1 -#define HAVE_GETOPT_OPTRESET 1 -#define HAVE_GETPID 1 -#define HAVE_GETPWNAM_R 1 -#define HAVE_GETPWUID_R 1 -#define HAVE_GETVFSBYNAME 1 -#define HAVE_GMTIME_R 1 -#define HAVE_GRP_H 1 -#define HAVE_INTMAX_T 1 -#define HAVE_INTTYPES_H 1 -#define HAVE_LANGINFO_H 1 -#define HAVE_LCHFLAGS 1 -#define HAVE_LCHMOD 1 -#define HAVE_LCHOWN 1 -#define HAVE_LIBZ 1 -#define HAVE_LIMITS_H 1 -#define HAVE_LINK 1 -#define HAVE_LINKAT 1 -#define HAVE_LOCALE_H 1 -#define HAVE_LOCALTIME_R 1 -#define HAVE_LONG_LONG_INT 1 -#define HAVE_LSTAT 1 -#define HAVE_LUTIMES 1 -#define HAVE_MBRTOWC 1 -#define HAVE_MEMMOVE 1 -#define HAVE_MEMORY_H 1 -#define HAVE_MEMSET 1 -#define HAVE_MKDIR 1 -#define HAVE_MKFIFO 1 -#define HAVE_MKNOD 1 -#define HAVE_MKSTEMP 1 -#define HAVE_NL_LANGINFO 1 -#define HAVE_OPENAT 1 -#define HAVE_PATHS_H 1 -#define HAVE_PIPE 1 -#define HAVE_POLL 1 -#define HAVE_POLL_H 1 -#define HAVE_POSIX_SPAWNP 1 -#define HAVE_PTHREAD_H 1 -#define HAVE_PWD_H 1 -#define HAVE_READDIR_R 1 -#define HAVE_READLINK 1 -#define HAVE_READLINKAT 1 -#define HAVE_READPASSPHRASE 1 -#define HAVE_READPASSPHRASE_H 1 -#define HAVE_REGEX_H 1 -#define HAVE_SELECT 1 -#define HAVE_SETENV 1 -#define HAVE_SETLOCALE 1 -#define HAVE_SIGACTION 1 -#define HAVE_SIGNAL_H 1 -#define HAVE_SPAWN_H 1 -#define HAVE_STATFS 1 -#define HAVE_STATVFS 1 -#define HAVE_STDARG_H 1 -#define HAVE_STDINT_H 1 -#define HAVE_STDLIB_H 1 -#define HAVE_STRCHR 1 -#define HAVE_STRDUP 1 -#define HAVE_STRERROR 1 -#define HAVE_STRERROR_R 1 -#define HAVE_STRFTIME 1 -#define HAVE_STRINGS_H 1 -#define HAVE_STRING_H 1 -#define HAVE_STRNLEN 1 -#define HAVE_STRRCHR 1 -#define HAVE_STRUCT_STATFS_F_NAMEMAX 1 -#define HAVE_STRUCT_STAT_ST_BIRTHTIME 1 -#define HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC 1 -#define HAVE_STRUCT_STAT_ST_BLKSIZE 1 -#define HAVE_STRUCT_STAT_ST_FLAGS 1 -#define HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC 1 -#define HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 1 -#define HAVE_STRUCT_TM_TM_GMTOFF 1 -#define HAVE_SYMLINK 1 -#define HAVE_SYS_CDEFS_H 1 -#define HAVE_SYS_IOCTL_H 1 -#define HAVE_SYS_MOUNT_H 1 -#define HAVE_SYS_PARAM_H 1 -#define HAVE_SYS_POLL_H 1 -#define HAVE_SYS_QUEUE_H 1 -#define HAVE_SYS_SELECT_H 1 -#define HAVE_SYS_STATVFS_H 1 -#define HAVE_SYS_STAT_H 1 -#define HAVE_SYS_TIME_H 1 -#define HAVE_SYS_TYPES_H 1 -#define HAVE_SYS_UTSNAME_H 1 -#define HAVE_SYS_WAIT_H 1 -#define HAVE_TIMEGM 1 -#define HAVE_TIME_H 1 -#define HAVE_TZSET 1 -#define HAVE_UINTMAX_T 1 -#define HAVE_UNISTD_H 1 -#define HAVE_UNLINKAT 1 -#define HAVE_UNSETENV 1 -#define HAVE_UNSIGNED_LONG_LONG 1 -#define HAVE_UNSIGNED_LONG_LONG_INT 1 -#define HAVE_UTIME 1 -#define HAVE_UTIMES 1 -#define HAVE_UTIME_H 1 -#define HAVE_VFORK 1 -#define HAVE_VPRINTF 1 -#define HAVE_WCHAR_H 1 -#define HAVE_WCHAR_T 1 -#define HAVE_WCRTOMB 1 -#define HAVE_WCSCMP 1 -#define HAVE_WCSCPY 1 -#define HAVE_WCSLEN 1 -#define HAVE_WCTOMB 1 -#define HAVE_WCTYPE_H 1 -#define HAVE_WMEMCMP 1 -#define HAVE_WMEMCPY 1 -#define HAVE_WMEMMOVE 1 -#define HAVE_ZLIB_H 1 -#define HAVE_SYS_TIME_H 1 - -#if __FreeBSD_version >= 800505 -#define HAVE_LIBLZMA 1 -#define HAVE_LZMA_H 1 -#if __FreeBSD_version >= 1002504 -#define HAVE_LZMA_STREAM_ENCODER_MT 1 -#endif -#endif - -#if __FreeBSD_version >= 1100056 -#define HAVE_FUTIMENS 1 -#define HAVE_UTIMENSAT 1 -#endif - -/* FreeBSD 4 and earlier lack intmax_t/uintmax_t */ -#if __FreeBSD__ < 5 -#define intmax_t int64_t -#define uintmax_t uint64_t -#endif - -/* FreeBSD defines for archive_hash.h */ -#ifdef WITH_OPENSSL -#define ARCHIVE_CRYPTO_MD5_OPENSSL 1 -#define ARCHIVE_CRYPTO_RMD160_OPENSSL 1 -#define ARCHIVE_CRYPTO_SHA1_OPENSSL -#define ARCHIVE_CRYPTO_SHA256_OPENSSL 1 -#define ARCHIVE_CRYPTO_SHA384_OPENSSL 1 -#define ARCHIVE_CRYPTO_SHA512_OPENSSL 1 -#else -#define ARCHIVE_CRYPTO_MD5_LIBMD 1 -#define ARCHIVE_CRYPTO_SHA1_LIBMD 1 -#define ARCHIVE_CRYPTO_SHA256_LIBMD 1 -#define ARCHIVE_CRYPTO_SHA512_LIBMD 1 -#endif diff --git a/thirdparty/libarchive/libarchive/cpio.5 b/thirdparty/libarchive/libarchive/cpio.5 deleted file mode 100644 index c71018b19..000000000 --- a/thirdparty/libarchive/libarchive/cpio.5 +++ /dev/null @@ -1,391 +0,0 @@ -.\" Copyright (c) 2007 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd December 23, 2011 -.Dt CPIO 5 -.Os -.Sh NAME -.Nm cpio -.Nd format of cpio archive files -.Sh DESCRIPTION -The -.Nm -archive format collects any number of files, directories, and other -file system objects (symbolic links, device nodes, etc.) into a single -stream of bytes. -.Ss General Format -Each file system object in a -.Nm -archive comprises a header record with basic numeric metadata -followed by the full pathname of the entry and the file data. -The header record stores a series of integer values that generally -follow the fields in -.Va struct stat . -(See -.Xr stat 2 -for details.) -The variants differ primarily in how they store those integers -(binary, octal, or hexadecimal). -The header is followed by the pathname of the -entry (the length of the pathname is stored in the header) -and any file data. -The end of the archive is indicated by a special record with -the pathname -.Dq TRAILER!!! . -.Ss PWB format -The PWB binary -.Nm -format is the original format, when cpio was introduced as part of the -Programmer's Work Bench system, a variant of 6th Edition UNIX. It -stores numbers as 2-byte and 4-byte binary values. -Each entry begins with a header in the following format: -.Pp -.Bd -literal -offset indent -struct header_pwb_cpio { - short h_magic; - short h_dev; - short h_ino; - short h_mode; - short h_uid; - short h_gid; - short h_nlink; - short h_majmin; - long h_mtime; - short h_namesize; - long h_filesize; -}; -.Ed -.Pp -The -.Va short -fields here are 16-bit integer values, while the -.Va long -fields are 32 bit integers. Since PWB UNIX, like the 6th Edition UNIX -it was based on, only ran on PDP-11 computers, they -are in PDP-endian format, which has little-endian shorts, and -big-endian longs. That is, the long integer whose hexadecimal -representation is 0x12345678 would be stored in four successive bytes -as 0x34, 0x12, 0x78, 0x56. -The fields are as follows: -.Bl -tag -width indent -.It Va h_magic -The integer value octal 070707. -.It Va h_dev , Va h_ino -The device and inode numbers from the disk. -These are used by programs that read -.Nm -archives to determine when two entries refer to the same file. -Programs that synthesize -.Nm -archives should be careful to set these to distinct values for each entry. -.It Va h_mode -The mode specifies both the regular permissions and the file type, and -it also holds a couple of bits that are irrelevant to the cpio format, -because the field is actually a raw copy of the mode field in the inode -representing the file. These are the IALLOC flag, which shows that -the inode entry is in use, and the ILARG flag, which shows that the -file it represents is large enough to have indirect blocks pointers in -the inode. -The mode is decoded as follows: -.Pp -.Bl -tag -width "MMMMMMM" -compact -.It 0100000 -IALLOC flag - irrelevant to cpio. -.It 0060000 -This masks the file type bits. -.It 0040000 -File type value for directories. -.It 0020000 -File type value for character special devices. -.It 0060000 -File type value for block special devices. -.It 0010000 -ILARG flag - irrelevant to cpio. -.It 0004000 -SUID bit. -.It 0002000 -SGID bit. -.It 0001000 -Sticky bit. -.It 0000777 -The lower 9 bits specify read/write/execute permissions -for world, group, and user following standard POSIX conventions. -.El -.It Va h_uid , Va h_gid -The numeric user id and group id of the owner. -.It Va h_nlink -The number of links to this file. -Directories always have a value of at least two here. -Note that hardlinked files include file data with every copy in the archive. -.It Va h_majmin -For block special and character special entries, -this field contains the associated device number, with the major -number in the high byte, and the minor number in the low byte. -For all other entry types, it should be set to zero by writers -and ignored by readers. -.It Va h_mtime -Modification time of the file, indicated as the number -of seconds since the start of the epoch, -00:00:00 UTC January 1, 1970. -.It Va h_namesize -The number of bytes in the pathname that follows the header. -This count includes the trailing NUL byte. -.It Va h_filesize -The size of the file. Note that this archive format is limited to 16 -megabyte file sizes, because PWB UNIX, like 6th Edition, only used -an unsigned 24 bit integer for the file size internally. -.El -.Pp -The pathname immediately follows the fixed header. -If -.Cm h_namesize -is odd, an additional NUL byte is added after the pathname. -The file data is then appended, again with an additional NUL -appended if needed to get the next header at an even offset. -.Pp -Hardlinked files are not given special treatment; -the full file contents are included with each copy of the -file. -.Ss New Binary Format -The new binary -.Nm -format showed up when cpio was adopted into late 7th Edition UNIX. -It is exactly like the PWB binary format, described above, except for -three changes: -.Pp -First, UNIX now ran on more than one hardware type, so the endianness -of 16 bit integers must be determined by observing the magic number at -the start of the header. The 32 bit integers are still always stored -with the most significant word first, though, so each of those two, in -the struct shown above, was stored as an array of two 16 bit integers, -in the traditional order. Those 16 bit integers, like all the others -in the struct, were accessed using a macro that byte swapped them if -necessary. -.Pp -Next, 7th Edition had more file types to store, and the IALLOC and ILARG -flag bits were re-purposed to accommodate these. The revised use of the -various bits is as follows: -.Pp -.Bl -tag -width "MMMMMMM" -compact -.It 0170000 -This masks the file type bits. -.It 0140000 -File type value for sockets. -.It 0120000 -File type value for symbolic links. -For symbolic links, the link body is stored as file data. -.It 0100000 -File type value for regular files. -.It 0060000 -File type value for block special devices. -.It 0040000 -File type value for directories. -.It 0020000 -File type value for character special devices. -.It 0010000 -File type value for named pipes or FIFOs. -.It 0004000 -SUID bit. -.It 0002000 -SGID bit. -.It 0001000 -Sticky bit. -.It 0000777 -The lower 9 bits specify read/write/execute permissions -for world, group, and user following standard POSIX conventions. -.El -.Pp -Finally, the file size field now represents a signed 32 bit integer in -the underlying file system, so the maximum file size has increased to -2 gigabytes. -.Pp -Note that there is no obvious way to tell which of the two binary -formats an archive uses, other than to see which one makes more -sense. The typical error scenario is that a PWB format archive -unpacked as if it were in the new format will create named sockets -instead of directories, and then fail to unpack files that should -go in those directories. Running -.Va bsdcpio -itv -on an unknown archive will make it obvious which it is: if it's -PWB format, directories will be listed with an 's' instead of -a 'd' as the first character of the mode string, and the larger -files will have a '?' in that position. -.Ss Portable ASCII Format -.St -susv2 -standardized an ASCII variant that is portable across all -platforms. -It is commonly known as the -.Dq old character -format or as the -.Dq odc -format. -It stores the same numeric fields as the old binary format, but -represents them as 6-character or 11-character octal values. -.Pp -.Bd -literal -offset indent -struct cpio_odc_header { - char c_magic[6]; - char c_dev[6]; - char c_ino[6]; - char c_mode[6]; - char c_uid[6]; - char c_gid[6]; - char c_nlink[6]; - char c_rdev[6]; - char c_mtime[11]; - char c_namesize[6]; - char c_filesize[11]; -}; -.Ed -.Pp -The fields are identical to those in the new binary format. -The name and file body follow the fixed header. -Unlike the binary formats, there is no additional padding -after the pathname or file contents. -If the files being archived are themselves entirely ASCII, then -the resulting archive will be entirely ASCII, except for the -NUL byte that terminates the name field. -.Ss New ASCII Format -The "new" ASCII format uses 8-byte hexadecimal fields for -all numbers and separates device numbers into separate fields -for major and minor numbers. -.Pp -.Bd -literal -offset indent -struct cpio_newc_header { - char c_magic[6]; - char c_ino[8]; - char c_mode[8]; - char c_uid[8]; - char c_gid[8]; - char c_nlink[8]; - char c_mtime[8]; - char c_filesize[8]; - char c_devmajor[8]; - char c_devminor[8]; - char c_rdevmajor[8]; - char c_rdevminor[8]; - char c_namesize[8]; - char c_check[8]; -}; -.Ed -.Pp -Except as specified below, the fields here match those specified -for the new binary format above. -.Bl -tag -width indent -.It Va magic -The string -.Dq 070701 . -.It Va check -This field is always set to zero by writers and ignored by readers. -See the next section for more details. -.El -.Pp -The pathname is followed by NUL bytes so that the total size -of the fixed header plus pathname is a multiple of four. -Likewise, the file data is padded to a multiple of four bytes. -Note that this format supports only 4 gigabyte files (unlike the -older ASCII format, which supports 8 gigabyte files). -.Pp -In this format, hardlinked files are handled by setting the -filesize to zero for each entry except the first one that -appears in the archive. -.Ss New CRC Format -The CRC format is identical to the new ASCII format described -in the previous section except that the magic field is set -to -.Dq 070702 -and the -.Va check -field is set to the sum of all bytes in the file data. -This sum is computed treating all bytes as unsigned values -and using unsigned arithmetic. -Only the least-significant 32 bits of the sum are stored. -.Ss HP variants -The -.Nm cpio -implementation distributed with HPUX used XXXX but stored -device numbers differently XXX. -.Ss Other Extensions and Variants -Sun Solaris uses additional file types to store extended file -data, including ACLs and extended attributes, as special -entries in cpio archives. -.Pp -XXX Others? XXX -.Sh SEE ALSO -.Xr cpio 1 , -.Xr tar 5 -.Sh STANDARDS -The -.Nm cpio -utility is no longer a part of POSIX or the Single Unix Standard. -It last appeared in -.St -susv2 . -It has been supplanted in subsequent standards by -.Xr pax 1 . -The portable ASCII format is currently part of the specification for the -.Xr pax 1 -utility. -.Sh HISTORY -The original cpio utility was written by Dick Haight -while working in AT&T's Unix Support Group. -It appeared in 1977 as part of PWB/UNIX 1.0, the -.Dq Programmer's Work Bench -derived from -.At v6 -that was used internally at AT&T. -Both the new binary and old character formats were in use -by 1980, according to the System III source released -by SCO under their -.Dq Ancient Unix -license. -The character format was adopted as part of -.St -p1003.1-88 . -XXX when did "newc" appear? Who invented it? When did HP come out with their variant? When did Sun introduce ACLs and extended attributes? XXX -.Sh BUGS -The -.Dq CRC -format is mis-named, as it uses a simple checksum and -not a cyclic redundancy check. -.Pp -The binary formats are limited to 16 bits for user id, group id, -device, and inode numbers. They are limited to 16 megabyte and 2 -gigabyte file sizes for the older and newer variants, respectively. -.Pp -The old ASCII format is limited to 18 bits for -the user id, group id, device, and inode numbers. -It is limited to 8 gigabyte file sizes. -.Pp -The new ASCII format is limited to 4 gigabyte file sizes. -.Pp -None of the cpio formats store user or group names, -which are essential when moving files between systems with -dissimilar user or group numbering. -.Pp -Especially when writing older cpio variants, it may be necessary -to map actual device/inode values to synthesized values that -fit the available fields. -With very large filesystems, this may be necessary even for -the newer formats. diff --git a/thirdparty/libarchive/libarchive/filter_fork.h b/thirdparty/libarchive/libarchive/filter_fork.h deleted file mode 100644 index 2bf290c4d..000000000 --- a/thirdparty/libarchive/libarchive/filter_fork.h +++ /dev/null @@ -1,46 +0,0 @@ -/*- - * Copyright (c) 2007 Joerg Sonnenberger - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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: head/lib/libarchive/filter_fork.h 201087 2009-12-28 02:18:26Z kientzle $ - */ - -#ifndef FILTER_FORK_H -#define FILTER_FORK_H - -#ifndef __LIBARCHIVE_BUILD -#error This header is only to be used internally to libarchive. -#endif - -int -__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout, -#if defined(_WIN32) && !defined(__CYGWIN__) - HANDLE *out_child); -#else - pid_t *out_child); -#endif - -void -__archive_check_child(int in, int out); - -#endif diff --git a/thirdparty/libarchive/libarchive/filter_fork_posix.c b/thirdparty/libarchive/libarchive/filter_fork_posix.c deleted file mode 100644 index 62085a709..000000000 --- a/thirdparty/libarchive/libarchive/filter_fork_posix.c +++ /dev/null @@ -1,240 +0,0 @@ -/*- - * Copyright (c) 2007 Joerg Sonnenberger - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -/* This capability is only available on POSIX systems. */ -#if defined(HAVE_PIPE) && defined(HAVE_FCNTL) && \ - (defined(HAVE_FORK) || defined(HAVE_VFORK) || defined(HAVE_POSIX_SPAWNP)) - -__FBSDID("$FreeBSD: head/lib/libarchive/filter_fork.c 182958 2008-09-12 05:33:00Z kientzle $"); - -#if defined(HAVE_SYS_TYPES_H) -# include -#endif -#ifdef HAVE_ERRNO_H -# include -#endif -#ifdef HAVE_STRING_H -# include -#endif -#if defined(HAVE_POLL) && (defined(HAVE_POLL_H) || defined(HAVE_SYS_POLL_H)) -# if defined(HAVE_POLL_H) -# include -# elif defined(HAVE_SYS_POLL_H) -# include -# endif -#elif defined(HAVE_SELECT) -# if defined(HAVE_SYS_SELECT_H) -# include -# elif defined(HAVE_UNISTD_H) -# include -# endif -#endif -#ifdef HAVE_FCNTL_H -# include -#endif -#ifdef HAVE_SPAWN_H -# include -#endif -#ifdef HAVE_STDLIB_H -# include -#endif -#ifdef HAVE_UNISTD_H -# include -#endif - -#include "archive.h" -#include "archive_cmdline_private.h" - -#include "filter_fork.h" - -int -__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout, - pid_t *out_child) -{ - pid_t child = -1; - int stdin_pipe[2], stdout_pipe[2], tmp; -#if HAVE_POSIX_SPAWNP - posix_spawn_file_actions_t actions; - int r; -#endif - struct archive_cmdline *cmdline; - - cmdline = __archive_cmdline_allocate(); - if (cmdline == NULL) - goto state_allocated; - if (__archive_cmdline_parse(cmdline, cmd) != ARCHIVE_OK) - goto state_allocated; - - if (pipe(stdin_pipe) == -1) - goto state_allocated; - if (stdin_pipe[0] == 1 /* stdout */) { - if ((tmp = dup(stdin_pipe[0])) == -1) - goto stdin_opened; - close(stdin_pipe[0]); - stdin_pipe[0] = tmp; - } - if (pipe(stdout_pipe) == -1) - goto stdin_opened; - if (stdout_pipe[1] == 0 /* stdin */) { - if ((tmp = dup(stdout_pipe[1])) == -1) - goto stdout_opened; - close(stdout_pipe[1]); - stdout_pipe[1] = tmp; - } - -#if HAVE_POSIX_SPAWNP - - r = posix_spawn_file_actions_init(&actions); - if (r != 0) { - errno = r; - goto stdout_opened; - } - r = posix_spawn_file_actions_addclose(&actions, stdin_pipe[1]); - if (r != 0) - goto actions_inited; - r = posix_spawn_file_actions_addclose(&actions, stdout_pipe[0]); - if (r != 0) - goto actions_inited; - /* Setup for stdin. */ - r = posix_spawn_file_actions_adddup2(&actions, stdin_pipe[0], 0); - if (r != 0) - goto actions_inited; - if (stdin_pipe[0] != 0 /* stdin */) { - r = posix_spawn_file_actions_addclose(&actions, stdin_pipe[0]); - if (r != 0) - goto actions_inited; - } - /* Setup for stdout. */ - r = posix_spawn_file_actions_adddup2(&actions, stdout_pipe[1], 1); - if (r != 0) - goto actions_inited; - if (stdout_pipe[1] != 1 /* stdout */) { - r = posix_spawn_file_actions_addclose(&actions, stdout_pipe[1]); - if (r != 0) - goto actions_inited; - } - r = posix_spawnp(&child, cmdline->path, &actions, NULL, - cmdline->argv, NULL); - if (r != 0) - goto actions_inited; - posix_spawn_file_actions_destroy(&actions); - -#else /* HAVE_POSIX_SPAWNP */ - -#if HAVE_VFORK - child = vfork(); -#else - child = fork(); -#endif - if (child == -1) - goto stdout_opened; - if (child == 0) { - close(stdin_pipe[1]); - close(stdout_pipe[0]); - if (dup2(stdin_pipe[0], 0 /* stdin */) == -1) - _exit(254); - if (stdin_pipe[0] != 0 /* stdin */) - close(stdin_pipe[0]); - if (dup2(stdout_pipe[1], 1 /* stdout */) == -1) - _exit(254); - if (stdout_pipe[1] != 1 /* stdout */) - close(stdout_pipe[1]); - execvp(cmdline->path, cmdline->argv); - _exit(254); - } -#endif /* HAVE_POSIX_SPAWNP */ - - close(stdin_pipe[0]); - close(stdout_pipe[1]); - - *child_stdin = stdin_pipe[1]; - fcntl(*child_stdin, F_SETFL, O_NONBLOCK); - *child_stdout = stdout_pipe[0]; - fcntl(*child_stdout, F_SETFL, O_NONBLOCK); - __archive_cmdline_free(cmdline); - - *out_child = child; - return ARCHIVE_OK; - -#if HAVE_POSIX_SPAWNP -actions_inited: - errno = r; - posix_spawn_file_actions_destroy(&actions); -#endif -stdout_opened: - close(stdout_pipe[0]); - close(stdout_pipe[1]); -stdin_opened: - close(stdin_pipe[0]); - close(stdin_pipe[1]); -state_allocated: - __archive_cmdline_free(cmdline); - return ARCHIVE_FAILED; -} - -void -__archive_check_child(int in, int out) -{ -#if defined(HAVE_POLL) && (defined(HAVE_POLL_H) || defined(HAVE_SYS_POLL_H)) - struct pollfd fds[2]; - int idx; - - idx = 0; - if (in != -1) { - fds[idx].fd = in; - fds[idx].events = POLLOUT; - ++idx; - } - if (out != -1) { - fds[idx].fd = out; - fds[idx].events = POLLIN; - ++idx; - } - - poll(fds, idx, -1); /* -1 == INFTIM, wait forever */ -#elif defined(HAVE_SELECT) - fd_set fds_in, fds_out, fds_error; - - FD_ZERO(&fds_in); - FD_ZERO(&fds_out); - FD_ZERO(&fds_error); - if (out != -1) { - FD_SET(out, &fds_in); - FD_SET(out, &fds_error); - } - if (in != -1) { - FD_SET(in, &fds_out); - FD_SET(in, &fds_error); - } - select(in < out ? out + 1 : in + 1, &fds_in, &fds_out, &fds_error, NULL); -#else - sleep(1); -#endif -} - -#endif /* defined(HAVE_PIPE) && defined(HAVE_VFORK) && defined(HAVE_FCNTL) */ diff --git a/thirdparty/libarchive/libarchive/filter_fork_windows.c b/thirdparty/libarchive/libarchive/filter_fork_windows.c deleted file mode 100644 index 9e49c5655..000000000 --- a/thirdparty/libarchive/libarchive/filter_fork_windows.c +++ /dev/null @@ -1,245 +0,0 @@ -/*- - * Copyright (c) 2009-2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "archive_platform.h" - -#if defined(_WIN32) && !defined(__CYGWIN__) -#include "archive_cmdline_private.h" -#include "archive_string.h" - -#include "filter_fork.h" - -#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) -/* There are some editions of Windows ("nano server," for example) that - * do not host user32.dll. If we want to keep running on those editions, - * we need to delay-load WaitForInputIdle. */ -static void * -la_GetFunctionUser32(const char *name) -{ - static HINSTANCE lib; - static int set; - if (!set) { - set = 1; - lib = LoadLibrary(TEXT("user32.dll")); - } - if (lib == NULL) { - return NULL; - } - return (void *)GetProcAddress(lib, name); -} - -static int -la_WaitForInputIdle(HANDLE hProcess, DWORD dwMilliseconds) -{ - static DWORD (WINAPI *f)(HANDLE, DWORD); - static int set; - - if (!set) { - set = 1; - f = la_GetFunctionUser32("WaitForInputIdle"); - } - - if (!f) { - /* An inability to wait for input idle is - * not _good_, but it is not catastrophic. */ - return WAIT_FAILED; - } - return (*f)(hProcess, dwMilliseconds); -} - -int -__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout, - HANDLE *out_child) -{ - HANDLE childStdout[2], childStdin[2],childStderr; - SECURITY_ATTRIBUTES secAtts; - STARTUPINFOA staInfo; - PROCESS_INFORMATION childInfo; - struct archive_string cmdline; - struct archive_string fullpath; - struct archive_cmdline *acmd; - char *arg0, *ext; - int i, l; - DWORD fl, fl_old; - HANDLE child; - - childStdout[0] = childStdout[1] = INVALID_HANDLE_VALUE; - childStdin[0] = childStdin[1] = INVALID_HANDLE_VALUE; - childStderr = INVALID_HANDLE_VALUE; - archive_string_init(&cmdline); - archive_string_init(&fullpath); - - acmd = __archive_cmdline_allocate(); - if (acmd == NULL) - goto fail; - if (__archive_cmdline_parse(acmd, cmd) != ARCHIVE_OK) - goto fail; - - /* - * Search the full path of 'path'. - * NOTE: This does not need if we give CreateProcessA 'path' as - * a part of the cmdline and give CreateProcessA NULL as first - * parameter, but I do not like that way. - */ - ext = strrchr(acmd->path, '.'); - if (ext == NULL || strlen(ext) > 4) - /* 'path' does not have a proper extension, so we have to - * give SearchPath() ".exe" as the extension. */ - ext = ".exe"; - else - ext = NULL;/* 'path' has an extension. */ - - fl = MAX_PATH; - do { - if (archive_string_ensure(&fullpath, fl) == NULL) - goto fail; - fl_old = fl; - fl = SearchPathA(NULL, acmd->path, ext, fl, fullpath.s, - &arg0); - } while (fl != 0 && fl > fl_old); - if (fl == 0) - goto fail; - - /* - * Make a command line. - */ - for (l = 0, i = 0; acmd->argv[i] != NULL; i++) { - if (i == 0) - continue; - l += (int)strlen(acmd->argv[i]) + 1; - } - if (archive_string_ensure(&cmdline, l + 1) == NULL) - goto fail; - for (i = 0; acmd->argv[i] != NULL; i++) { - if (i == 0) { - const char *p, *sp; - - if ((p = strchr(acmd->argv[i], '/')) != NULL || - (p = strchr(acmd->argv[i], '\\')) != NULL) - p++; - else - p = acmd->argv[i]; - if ((sp = strchr(p, ' ')) != NULL) - archive_strappend_char(&cmdline, '"'); - archive_strcat(&cmdline, p); - if (sp != NULL) - archive_strappend_char(&cmdline, '"'); - } else { - archive_strappend_char(&cmdline, ' '); - archive_strcat(&cmdline, acmd->argv[i]); - } - } - if (i <= 1) { - const char *sp; - - if ((sp = strchr(arg0, ' ')) != NULL) - archive_strappend_char(&cmdline, '"'); - archive_strcat(&cmdline, arg0); - if (sp != NULL) - archive_strappend_char(&cmdline, '"'); - } - - secAtts.nLength = sizeof(SECURITY_ATTRIBUTES); - secAtts.bInheritHandle = TRUE; - secAtts.lpSecurityDescriptor = NULL; - if (CreatePipe(&childStdout[0], &childStdout[1], &secAtts, 0) == 0) - goto fail; - if (!SetHandleInformation(childStdout[0], HANDLE_FLAG_INHERIT, 0)) - goto fail; - if (CreatePipe(&childStdin[0], &childStdin[1], &secAtts, 0) == 0) - goto fail; - if (!SetHandleInformation(childStdin[1], HANDLE_FLAG_INHERIT, 0)) - goto fail; - if (DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_ERROR_HANDLE), - GetCurrentProcess(), &childStderr, 0, TRUE, - DUPLICATE_SAME_ACCESS) == 0) - goto fail; - - memset(&staInfo, 0, sizeof(staInfo)); - staInfo.cb = sizeof(staInfo); - staInfo.hStdError = childStderr; - staInfo.hStdOutput = childStdout[1]; - staInfo.hStdInput = childStdin[0]; - staInfo.wShowWindow = SW_HIDE; - staInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; - if (CreateProcessA(fullpath.s, cmdline.s, NULL, NULL, TRUE, 0, - NULL, NULL, &staInfo, &childInfo) == 0) - goto fail; - la_WaitForInputIdle(childInfo.hProcess, INFINITE); - CloseHandle(childInfo.hProcess); - CloseHandle(childInfo.hThread); - - *child_stdout = _open_osfhandle((intptr_t)childStdout[0], _O_RDONLY); - *child_stdin = _open_osfhandle((intptr_t)childStdin[1], _O_WRONLY); - - child = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, - childInfo.dwProcessId); - if (child == NULL) // INVALID_HANDLE_VALUE ? - goto fail; - - *out_child = child; - - CloseHandle(childStdout[1]); - CloseHandle(childStdin[0]); - - archive_string_free(&cmdline); - archive_string_free(&fullpath); - __archive_cmdline_free(acmd); - return ARCHIVE_OK; - -fail: - if (childStdout[0] != INVALID_HANDLE_VALUE) - CloseHandle(childStdout[0]); - if (childStdout[1] != INVALID_HANDLE_VALUE) - CloseHandle(childStdout[1]); - if (childStdin[0] != INVALID_HANDLE_VALUE) - CloseHandle(childStdin[0]); - if (childStdin[1] != INVALID_HANDLE_VALUE) - CloseHandle(childStdin[1]); - if (childStderr != INVALID_HANDLE_VALUE) - CloseHandle(childStderr); - archive_string_free(&cmdline); - archive_string_free(&fullpath); - __archive_cmdline_free(acmd); - return ARCHIVE_FAILED; -} -#else /* !WINAPI_PARTITION_DESKTOP */ -int -__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout, HANDLE *out_child) -{ - (void)cmd; (void)child_stdin; (void) child_stdout; (void) out_child; - return ARCHIVE_FAILED; -} -#endif /* !WINAPI_PARTITION_DESKTOP */ - -void -__archive_check_child(int in, int out) -{ - (void)in; /* UNUSED */ - (void)out; /* UNUSED */ - Sleep(100); -} - -#endif /* _WIN32 && !__CYGWIN__ */ diff --git a/thirdparty/libarchive/libarchive/libarchive-formats.5 b/thirdparty/libarchive/libarchive/libarchive-formats.5 deleted file mode 100644 index 5a118ff5d..000000000 --- a/thirdparty/libarchive/libarchive/libarchive-formats.5 +++ /dev/null @@ -1,464 +0,0 @@ -.\" Copyright (c) 2003-2009 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd December 27, 2016 -.Dt LIBARCHIVE-FORMATS 5 -.Os -.Sh NAME -.Nm libarchive-formats -.Nd archive formats supported by the libarchive library -.Sh DESCRIPTION -The -.Xr libarchive 3 -library reads and writes a variety of streaming archive formats. -Generally speaking, all of these archive formats consist of a series of -.Dq entries . -Each entry stores a single file system object, such as a file, directory, -or symbolic link. -.Pp -The following provides a brief description of each format supported -by libarchive, with some information about recognized extensions or -limitations of the current library support. -Note that just because a format is supported by libarchive does not -imply that a program that uses libarchive will support that format. -Applications that use libarchive specify which formats they wish -to support, though many programs do use libarchive convenience -functions to enable all supported formats. -.Ss Tar Formats -The -.Xr libarchive 3 -library can read most tar archives. -It can write POSIX-standard -.Dq ustar -and -.Dq pax interchange -formats as well as v7 tar format and a subset of the legacy GNU tar format. -.Pp -All tar formats store each entry in one or more 512-byte records. -The first record is used for file metadata, including filename, -timestamp, and mode information, and the file data is stored in -subsequent records. -Later variants have extended this by either appropriating undefined -areas of the header record, extending the header to multiple records, -or by storing special entries that modify the interpretation of -subsequent entries. -.Bl -tag -width indent -.It Cm gnutar -The -.Xr libarchive 3 -library can read most GNU-format tar archives. -It currently supports the most popular GNU extensions, including -modern long filename and linkname support, as well as atime and ctime data. -The libarchive library does not support multi-volume -archives, nor the old GNU long filename format. -It can read GNU sparse file entries, including the new POSIX-based -formats. -.Pp -The -.Xr libarchive 3 -library can write GNU tar format, including long filename -and linkname support, as well as atime and ctime data. -.It Cm pax -The -.Xr libarchive 3 -library can read and write POSIX-compliant pax interchange format -archives. -Pax interchange format archives are an extension of the older ustar -format that adds a separate entry with additional attributes stored -as key/value pairs immediately before each regular entry. -The presence of these additional entries is the only difference between -pax interchange format and the older ustar format. -The extended attributes are of unlimited length and are stored -as UTF-8 Unicode strings. -Keywords defined in the standard are in all lowercase; vendors are allowed -to define custom keys by preceding them with the vendor name in all uppercase. -When writing pax archives, libarchive uses many of the SCHILY keys -defined by Joerg Schilling's -.Dq star -archiver and a few LIBARCHIVE keys. -The libarchive library can read most of the SCHILY keys -and most of the GNU keys introduced by GNU tar. -It silently ignores any keywords that it does not understand. -.Pp -The pax interchange format converts filenames to Unicode -and stores them using the UTF-8 encoding. -Prior to libarchive 3.0, libarchive erroneously assumed -that the system wide-character routines natively supported -Unicode. -This caused it to mis-handle non-ASCII filenames on systems -that did not satisfy this assumption. -.It Cm restricted pax -The libarchive library can also write pax archives in which it -attempts to suppress the extended attributes entry whenever -possible. -The result will be identical to a ustar archive unless the -extended attributes entry is required to store a long file -name, long linkname, extended ACL, file flags, or if any of the standard -ustar data (user name, group name, UID, GID, etc) cannot be fully -represented in the ustar header. -In all cases, the result can be dearchived by any program that -can read POSIX-compliant pax interchange format archives. -Programs that correctly read ustar format (see below) will also be -able to read this format; any extended attributes will be extracted as -separate files stored in -.Pa PaxHeader -directories. -.It Cm ustar -The libarchive library can both read and write this format. -This format has the following limitations: -.Bl -bullet -compact -.It -Device major and minor numbers are limited to 21 bits. -Nodes with larger numbers will not be added to the archive. -.It -Path names in the archive are limited to 255 bytes. -(Shorter if there is no / character in exactly the right place.) -.It -Symbolic links and hard links are stored in the archive with -the name of the referenced file. -This name is limited to 100 bytes. -.It -Extended attributes, file flags, and other extended -security information cannot be stored. -.It -Archive entries are limited to 8 gigabytes in size. -.El -Note that the pax interchange format has none of these restrictions. -The ustar format is old and widely supported. -It is recommended when compatibility is the primary concern. -.It Cm v7 -The libarchive library can read and write the legacy v7 tar format. -This format has the following limitations: -.Bl -bullet -compact -.It -Only regular files, directories, and symbolic links can be archived. -Block and character device nodes, FIFOs, and sockets cannot be archived. -.It -Path names in the archive are limited to 100 bytes. -.It -Symbolic links and hard links are stored in the archive with -the name of the referenced file. -This name is limited to 100 bytes. -.It -User and group information are stored as numeric IDs; there -is no provision for storing user or group names. -.It -Extended attributes, file flags, and other extended -security information cannot be stored. -.It -Archive entries are limited to 8 gigabytes in size. -.El -Generally, users should prefer the ustar format for portability -as the v7 tar format is both less useful and less portable. -.El -.Pp -The libarchive library also reads a variety of commonly-used extensions to -the basic tar format. -These extensions are recognized automatically whenever they appear. -.Bl -tag -width indent -.It Numeric extensions. -The POSIX standards require fixed-length numeric fields to be written with -some character position reserved for terminators. -Libarchive allows these fields to be written without terminator characters. -This extends the allowable range; in particular, ustar archives with this -extension can support entries up to 64 gigabytes in size. -Libarchive also recognizes base-256 values in most numeric fields. -This essentially removes all limitations on file size, modification time, -and device numbers. -.It Solaris extensions -Libarchive recognizes ACL and extended attribute records written -by Solaris tar. -.El -.Pp -The first tar program appeared in Seventh Edition Unix in 1979. -The first official standard for the tar file format was the -.Dq ustar -(Unix Standard Tar) format defined by POSIX in 1988. -POSIX.1-2001 extended the ustar format to create the -.Dq pax interchange -format. -.Ss Cpio Formats -The libarchive library can read and write a number of common cpio -variants. A cpio archive stores each entry as a fixed-size header -followed by a variable-length filename and variable-length data. -Unlike the tar format, the cpio format does only minimal padding of -the header or file data. There are several cpio variants, which -differ primarily in how they store the initial header: some store the -values as octal or hexadecimal numbers in ASCII, others as binary -values of varying byte order and length. -.Bl -tag -width indent -.It Cm binary -The libarchive library transparently reads both big-endian and -little-endian variants of the the two binary cpio formats; the -original one from PWB/UNIX, and the later, more widely used, variant. -This format used 32-bit binary values for file size and mtime, and -16-bit binary values for the other fields. The formats support only -the file types present in UNIX at the time of their creation. File -sizes are limited to 24 bits in the PWB format, because of the limits -of the file system, and to 31 bits in the newer binary format, where -signed 32 bit longs were used. -.It Cm odc -This is the POSIX standardized format, which is officially known as the -.Dq cpio interchange format -or the -.Dq octet-oriented cpio archive format -and sometimes unofficially referred to as the -.Dq old character format . -This format stores the header contents as octal values in ASCII. -It is standard, portable, and immune from byte-order confusion. -File sizes and mtime are limited to 33 bits (8GB file size), -other fields are limited to 18 bits. -.It Cm SVR4/newc -The libarchive library can read both CRC and non-CRC variants of -this format. -The SVR4 format uses eight-digit hexadecimal values for -all header fields. -This limits file size to 4GB, and also limits the mtime and -other fields to 32 bits. -The SVR4 format can optionally include a CRC of the file -contents, although libarchive does not currently verify this CRC. -.El -.Pp -Cpio first appeared in PWB/UNIX 1.0, which was released within -AT&T in 1977. -PWB/UNIX 1.0 formed the basis of System III Unix, released outside -of AT&T in 1981. -This makes cpio older than tar, although cpio was not included -in Version 7 AT&T Unix. -As a result, the tar command became much better known in universities -and research groups that used Version 7. -The combination of the -.Nm find -and -.Nm cpio -utilities provided very precise control over file selection. -Unfortunately, the format has many limitations that make it unsuitable -for widespread use. -Only the POSIX format permits files over 4GB, and its 18-bit -limit for most other fields makes it unsuitable for modern systems. -In addition, cpio formats only store numeric UID/GID values (not -usernames and group names), which can make it very difficult to correctly -transfer archives across systems with dissimilar user numbering. -.Ss Shar Formats -A -.Dq shell archive -is a shell script that, when executed on a POSIX-compliant -system, will recreate a collection of file system objects. -The libarchive library can write two different kinds of shar archives: -.Bl -tag -width indent -.It Cm shar -The traditional shar format uses a limited set of POSIX -commands, including -.Xr echo 1 , -.Xr mkdir 1 , -and -.Xr sed 1 . -It is suitable for portably archiving small collections of plain text files. -However, it is not generally well-suited for large archives -(many implementations of -.Xr sh 1 -have limits on the size of a script) nor should it be used with non-text files. -.It Cm shardump -This format is similar to shar but encodes files using -.Xr uuencode 1 -so that the result will be a plain text file regardless of the file contents. -It also includes additional shell commands that attempt to reproduce as -many file attributes as possible, including owner, mode, and flags. -The additional commands used to restore file attributes make -shardump archives less portable than plain shar archives. -.El -.Ss ISO9660 format -Libarchive can read and extract from files containing ISO9660-compliant -CDROM images. -In many cases, this can remove the need to burn a physical CDROM -just in order to read the files contained in an ISO9660 image. -It also avoids security and complexity issues that come with -virtual mounts and loopback devices. -Libarchive supports the most common Rockridge extensions and has partial -support for Joliet extensions. -If both extensions are present, the Joliet extensions will be -used and the Rockridge extensions will be ignored. -In particular, this can create problems with hardlinks and symlinks, -which are supported by Rockridge but not by Joliet. -.Pp -Libarchive reads ISO9660 images using a streaming strategy. -This allows it to read compressed images directly -(decompressing on the fly) and allows it to read images -directly from network sockets, pipes, and other non-seekable -data sources. -This strategy works well for optimized ISO9660 images created -by many popular programs. -Such programs collect all directory information at the beginning -of the ISO9660 image so it can be read from a physical disk -with a minimum of seeking. -However, not all ISO9660 images can be read in this fashion. -.Pp -Libarchive can also write ISO9660 images. -Such images are fully optimized with the directory information -preceding all file data. -This is done by storing all file data to a temporary file -while collecting directory information in memory. -When the image is finished, libarchive writes out the -directory structure followed by the file data. -The location used for the temporary file can be changed -by the usual environment variables. -.Ss Zip format -Libarchive can read and write zip format archives that have -uncompressed entries and entries compressed with the -.Dq deflate -algorithm. -Other zip compression algorithms are not supported. -It can extract jar archives, archives that use Zip64 extensions and -self-extracting zip archives. -Libarchive can use either of two different strategies for -reading Zip archives: -a streaming strategy which is fast and can handle extremely -large archives, and a seeking strategy which can correctly -process self-extracting Zip archives and archives with -deleted members or other in-place modifications. -.Pp -The streaming reader processes Zip archives as they are read. -It can read archives of arbitrary size from tape or -network sockets, and can decode Zip archives that have -been separately compressed or encoded. -However, self-extracting Zip archives and archives with -certain types of modifications cannot be correctly -handled. -Such archives require that the reader first process the -Central Directory, which is ordinarily located -at the end of a Zip archive and is thus inaccessible -to the streaming reader. -If the program using libarchive has enabled seek support, then -libarchive will use this to processes the central directory first. -.Pp -In particular, the seeking reader must be used to -correctly handle self-extracting archives. -Such archives consist of a program followed by a regular -Zip archive. -The streaming reader cannot parse the initial program -portion, but the seeking reader starts by reading the -Central Directory from the end of the archive. -Similarly, Zip archives that have been modified in-place -can have deleted entries or other garbage data that -can only be accurately detected by first reading the -Central Directory. -.Ss Archive (library) file format -The Unix archive format (commonly created by the -.Xr ar 1 -archiver) is a general-purpose format which is -used almost exclusively for object files to be -read by the link editor -.Xr ld 1 . -The ar format has never been standardised. -There are two common variants: -the GNU format derived from SVR4, -and the BSD format, which first appeared in 4.4BSD. -The two differ primarily in their handling of filenames -longer than 15 characters: -the GNU/SVR4 variant writes a filename table at the beginning of the archive; -the BSD format stores each long filename in an extension -area adjacent to the entry. -Libarchive can read both extensions, -including archives that may include both types of long filenames. -Programs using libarchive can write GNU/SVR4 format -if they provide an entry called -.Pa // -containing a filename table to be written into the archive -before any of the entries. -Any entries whose names are not in the filename table -will be written using BSD-style long filenames. -This can cause problems for programs such as -GNU ld that do not support the BSD-style long filenames. -.Ss mtree -Libarchive can read and write files in -.Xr mtree 5 -format. -This format is not a true archive format, but rather a textual description -of a file hierarchy in which each line specifies the name of a file and -provides specific metadata about that file. -Libarchive can read all of the keywords supported by both -the NetBSD and FreeBSD versions of -.Xr mtree 8 , -although many of the keywords cannot currently be stored in an -.Tn archive_entry -object. -When writing, libarchive supports use of the -.Xr archive_write_set_options 3 -interface to specify which keywords should be included in the -output. -If libarchive was compiled with access to suitable -cryptographic libraries (such as the OpenSSL libraries), -it can compute hash entries such as -.Cm sha512 -or -.Cm md5 -from file data being written to the mtree writer. -.Pp -When reading an mtree file, libarchive will locate the corresponding -files on disk using the -.Cm contents -keyword if present or the regular filename. -If it can locate and open the file on disk, it will use that -to fill in any metadata that is missing from the mtree file -and will read the file contents and return those to the program -using libarchive. -If it cannot locate and open the file on disk, libarchive -will return an error for any attempt to read the entry -body. -.Ss 7-Zip -Libarchive can read and write 7-Zip format archives. -TODO: Need more information -.Ss CAB -Libarchive can read Microsoft Cabinet ( -.Dq CAB ) -format archives. -TODO: Need more information. -.Ss LHA -TODO: Information about libarchive's LHA support -.Ss RAR -Libarchive has limited support for reading RAR format archives. -Currently, libarchive can read RARv3 format archives -which have been either created uncompressed, or compressed using -any of the compression methods supported by the RARv3 format. -Libarchive can also read self-extracting RAR archives. -.Ss Warc -Libarchive can read and write -.Dq web archives . -TODO: Need more information -.Ss XAR -Libarchive can read and write the XAR format used by many Apple tools. -TODO: Need more information -.Sh SEE ALSO -.Xr ar 1 , -.Xr cpio 1 , -.Xr mkisofs 1 , -.Xr shar 1 , -.Xr tar 1 , -.Xr zip 1 , -.Xr zlib 3 , -.Xr cpio 5 , -.Xr mtree 5 , -.Xr tar 5 diff --git a/thirdparty/libarchive/libarchive/libarchive.3 b/thirdparty/libarchive/libarchive/libarchive.3 deleted file mode 100644 index 649056242..000000000 --- a/thirdparty/libarchive/libarchive/libarchive.3 +++ /dev/null @@ -1,299 +0,0 @@ -.\" Copyright (c) 2003-2007 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd March 18, 2012 -.Dt LIBARCHIVE 3 -.Os -.Sh NAME -.Nm libarchive -.Nd functions for reading and writing streaming archives -.Sh OVERVIEW -The -.Nm -library provides a flexible interface for reading and writing -archives in various formats such as tar and cpio. -.Nm -also supports reading and writing archives compressed using -various compression filters such as gzip and bzip2. -The library is inherently stream-oriented; readers serially iterate through -the archive, writers serially add things to the archive. -In particular, note that there is currently no built-in support for -random access nor for in-place modification. -.Pp -When reading an archive, the library automatically detects the -format and the compression. -The library currently has read support for: -.Bl -bullet -compact -.It -old-style tar archives, -.It -most variants of the POSIX -.Dq ustar -format, -.It -the POSIX -.Dq pax interchange -format, -.It -GNU-format tar archives, -.It -most common cpio archive formats, -.It -7-Zip archives, -.It -ar archives (including GNU/SysV and BSD extensions), -.It -Microsoft CAB archives, -.It -ISO9660 CD images (including RockRidge and Joliet extensions), -.It -LHA archives, -.It -mtree file tree descriptions, -.It -RAR and most RAR5 archives, -.It -WARC archives, -.It -XAR archives, -.It -Zip archives. -.El -The library automatically detects archives compressed with -.Xr compress 1 , -.Xr bzip2 1 , -.Xr grzip 1 , -.Xr gzip 1 , -.Xr lrzip 1 , -.Xr lz4 1 , -.Xr lzip 1 , -.Xr lzop 1 , -.Xr xz 1 , -or -.Xr zstd 1 -and decompresses them transparently. Decompression of some formats -requires external decompressor utilities. -It can similarly detect and decode archives processed with -.Xr uuencode 1 -or which have an -.Xr rpm 1 -header. -.Pp -When writing an archive, you can specify the compression -to be used and the format to use. -The library can write -.Bl -bullet -compact -.It -POSIX-standard -.Dq ustar -archives, -.It -POSIX -.Dq pax interchange format -archives, -.It -cpio archives, -.It -7-Zip archives, -.It -ar archives, -.It -two different variants of shar archives, -.It -ISO9660 CD images, -.It -mtree file tree descriptions, -.It -XAR archives, -.It -Zip archive. -.El -Pax interchange format is an extension of the tar archive format that -eliminates essentially all of the limitations of historic tar formats -in a standard fashion that is supported -by POSIX-compliant -.Xr pax 1 -implementations on many systems as well as several newer implementations of -.Xr tar 1 . -Note that the default write format will suppress the pax extended -attributes for most entries; explicitly requesting pax format will -enable those attributes for all entries. -.Pp -The read and write APIs are accessed through the -.Fn archive_read_XXX -functions and the -.Fn archive_write_XXX -functions, respectively, and either can be used independently -of the other. -.Pp -The rest of this manual page provides an overview of the library -operation. -More detailed information can be found in the individual manual -pages for each API or utility function. -.\" -.Sh READING AN ARCHIVE -See -.Xr archive_read 3 . -.\" -.Sh WRITING AN ARCHIVE -See -.Xr archive_write 3 . -.\" -.Sh WRITING ENTRIES TO DISK -The -.Xr archive_write_disk 3 -API allows you to write -.Xr archive_entry 3 -objects to disk using the same API used by -.Xr archive_write 3 . -The -.Xr archive_write_disk 3 -API is used internally by -.Fn archive_read_extract ; -using it directly can provide greater control over how entries -get written to disk. -This API also makes it possible to share code between -archive-to-archive copy and archive-to-disk extraction -operations. -.Sh READING ENTRIES FROM DISK -The -.Xr archive_read_disk 3 -supports for populating -.Xr archive_entry 3 -objects from information in the filesystem. -This includes the information accessible from the -.Xr stat 2 -system call as well as ACLs, extended attributes, -and other metadata. -The -.Xr archive_read_disk 3 -API also supports iterating over directory trees, -which allows directories of files to be read using -an API compatible with -the -.Xr archive_read 3 -API. -.Sh DESCRIPTION -Detailed descriptions of each function are provided by the -corresponding manual pages. -.Pp -All of the functions utilize an opaque -.Tn struct archive -datatype that provides access to the archive contents. -.Pp -The -.Tn struct archive_entry -structure contains a complete description of a single archive -entry. -It uses an opaque interface that is fully documented in -.Xr archive_entry 3 . -.Pp -Users familiar with historic formats should be aware that the newer -variants have eliminated most restrictions on the length of textual fields. -Clients should not assume that filenames, link names, user names, or -group names are limited in length. -In particular, pax interchange format can easily accommodate pathnames -in arbitrary character sets that exceed -.Va PATH_MAX . -.Sh RETURN VALUES -Most functions return -.Cm ARCHIVE_OK -(zero) on success, non-zero on error. -The return value indicates the general severity of the error, ranging -from -.Cm ARCHIVE_WARN , -which indicates a minor problem that should probably be reported -to the user, to -.Cm ARCHIVE_FATAL , -which indicates a serious problem that will prevent any further -operations on this archive. -On error, the -.Fn archive_errno -function can be used to retrieve a numeric error code (see -.Xr errno 2 ) . -The -.Fn archive_error_string -returns a textual error message suitable for display. -.Pp -.Fn archive_read_new -and -.Fn archive_write_new -return pointers to an allocated and initialized -.Tn struct archive -object. -.Pp -.Fn archive_read_data -and -.Fn archive_write_data -return a count of the number of bytes actually read or written. -A value of zero indicates the end of the data for this entry. -A negative value indicates an error, in which case the -.Fn archive_errno -and -.Fn archive_error_string -functions can be used to obtain more information. -.Sh ENVIRONMENT -There are character set conversions within the -.Xr archive_entry 3 -functions that are impacted by the currently-selected locale. -.Sh SEE ALSO -.Xr tar 1 , -.Xr archive_entry 3 , -.Xr archive_read 3 , -.Xr archive_util 3 , -.Xr archive_write 3 , -.Xr tar 5 -.Sh HISTORY -The -.Nm libarchive -library first appeared in -.Fx 5.3 . -.Sh AUTHORS -.An -nosplit -The -.Nm libarchive -library was originally written by -.An Tim Kientzle Aq kientzle@acm.org . -.Sh BUGS -Some archive formats support information that is not supported by -.Tn struct archive_entry . -Such information cannot be fully archived or restored using this library. -This includes, for example, comments, character sets, -or the arbitrary key/value pairs that can appear in -pax interchange format archives. -.Pp -Conversely, of course, not all of the information that can be -stored in an -.Tn struct archive_entry -is supported by all formats. -For example, cpio formats do not support nanosecond timestamps; -old tar formats do not support large device numbers. -.Pp -The ISO9660 reader cannot yet read all ISO9660 images; -it should learn how to seek. -.Pp -The AR writer requires the client program to use -two passes, unlike all other libarchive writers. diff --git a/thirdparty/libarchive/libarchive/libarchive_changes.3 b/thirdparty/libarchive/libarchive/libarchive_changes.3 deleted file mode 100644 index 6bf8db038..000000000 --- a/thirdparty/libarchive/libarchive/libarchive_changes.3 +++ /dev/null @@ -1,341 +0,0 @@ -.\" Copyright (c) 2011 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd December 23, 2011 -.Dt LIBARCHIVE_CHANGES 3 -.Os -.Sh NAME -.Nm libarchive_changes -.Nd changes in libarchive interface -.\" -.Sh CHANGES IN LIBARCHIVE 3 -This page describes user-visible changes in libarchive3, and lists -public functions and other symbols changed, deprecated or removed -in libarchive3, along with their replacements if any. -.\" -.Ss Multiple Filters -.\" -Libarchive2 permitted a single (input or output) filter active -on an archive. -Libarchive3 extends this into a variable-length stack. -Where -.Fn archive_write_set_compression_XXX -would replace any existing filter, -.Fn archive_write_add_filter_XXX -extends the write pipeline with another filter. -.\" -.Ss Character Set Handling -.\" -Libarchive2 assumed that the local platform uses -.Tn Unicode -as the native -.Tn wchar_t -encoding, which is true on -.Tn Windows , -modern -.Tn Linux , -and a few other systems, but is certainly not universal. -As a result, pax format archives were written incorrectly on some -systems, since pax format requires -.Tn UTF-8 -and libarchive 2 incorrectly -assumed that -.Tn wchar_t -strings can be easily converted to -.Tn UTF-8 . -.Pp -Libarchive3 uses the standard iconv library to convert between character -sets and is introducing the notion of a -.Dq default character set for the archive . -To support this, -.Tn archive_entry -objects can now be bound to a particular archive when they are created. -The automatic character set conversions performed by -.Tn archive_entry -objects when reading and writing filenames, usernames, and other strings -will now use an appropriate default character set: -.Pp -If the -.Tn archive_entry -object is bound to an archive, it will use the -default character set for that archive. -.Pp -The platform default character encoding (as returned by -.Fn nl_langinfo CHARSET ) -will be used if nothing else is specified. -.Pp -Libarchive3 also introduces charset options to many of the archive -readers and writers to control the character set that will be used for -filenames written in those archives. -When possible, this will be set automatically based on information in -the archive itself. -Combining this with the notion of a default character set for the -archive should allow you to configure libarchive to read archives from -other platforms and have the filenames and other information -transparently converted to the character encoding suitable for your -application. -.\" -.Ss Prototype Changes -.\" -These changes break binary compatibility; libarchive3 has a new shared -library version to reflect these changes. -The library now uses portable wide types such as -.Tn int64_t -instead of less-portable types such as -.Tn off_t , -.Tn gid_t , -.Tn uid_t , -and -.Tn ino_t . -.Pp -There are a few cases where these changes will affect your source code: -.Bl -bullet -width ind -.It -In some cases, libarchive's wider types will introduce the possibility -of truncation: for example, on a system with a 16-bit -.Tn uid_t , you risk having uid -.Li 65536 -be truncated to uid -.Li 0 , -which can cause serious security problems. -.It -Typedef function pointer types will be incompatible. -For example, if you define custom skip callbacks, you may have to use -code similar to the following if you want to support building against -libarchive2 and libarchive3: -.Bd -literal -#if ARCHIVE_VERSION_NUMBER < 3000000 -typedef off_t myoff_t; -#else -typedef int64_t myoff_t; -#endif - -myoff_t -my_skip_function(struct archive *a, void *v, myoff_t o) -{ - ... implementation ... -} -.Ed -.El -.Pp -Affected functions: -.Pp -.Bl -bullet -compact -.It -.Xo -.Fn archive_entry_gid , -.Fn archive_entry_set_gid -.Xc -.It -.Xo -.Fn archive_entry_uid , -.Fn archive_entry_set_uid -.Xc -.It -.Xo -.Fn archive_entry_ino , -.Fn archive_entry_set_ino -.Xc -.It -.Xo -.Fn archive_read_data_block , -.Fn archive_write_data_block -.Xc -.It -.Xo -.Fn archive_read_disk_gname , -.Fn archive_read_disk_uname -.Xc -.It -.Xo -.Fn archive_read_disk_set_gname_lookup , -.Fn archive_read_disk_set_group_lookup , -.Fn archive_read_disk_set_uname_lookup , -.Fn archive_read_disk_set_user_lookup -.Xc -.It -.Fn archive_skip_callback -.It -.Xo -.Fn archive_read_extract_set_skip_file , -.Fn archive_write_disk_set_skip_file , -.Fn archive_write_set_skip_file -.Xc -.It -.Xo -.Fn archive_write_disk_set_group_lookup , -.Fn archive_write_disk_set_user_lookup -.Xc -.El -.Pp -Where these functions or their arguments took or returned -.Tn gid_t , -.Tn ino_t , -.Tn off_t , -or -.Tn uid_t -they now take or return -.Tn int64_t -or equivalent. -.\" -.Ss Deprecated Symbols -.\" -Symbols deprecated in libarchive3 will be removed in libarchive4. -These symbols, along with their replacements if any, are listed below: -.\" -.Bl -tag -width ind -.It Fn archive_position_compressed , Fn archive_position_uncompressed -.Fn archive_filter_bytes -.It Fn archive_compression -.Fn archive_filter_code -.It Fn archive_compression_name -.Fn archive_filter_name -.It Fn archive_read_finish , Fn archive_write_finish -.Fn archive_read_free , -.Fn archive_write_free -.It Fn archive_read_open_file , Fn archive_write_open_file -.Fn archive_read_open_filename , -.Fn archive_write_open_filename -.It Fn archive_read_support_compression_all -.\" archive_read_support_compression_* -> archive_read_support_filter_* -.Fn archive_read_support_filter_all -.It Fn archive_read_support_compression_bzip2 -.Fn archive_read_support_filter_bzip2 -.It Fn archive_read_support_compression_compress -.Fn archive_read_support_filter_compress -.It Fn archive_read_support_compression_gzip -.Fn archive_read_support_filter_gzip -.It Fn archive_read_support_compression_lzip -.Fn archive_read_support_filter_lzip -.It Fn archive_read_support_compression_lzma -.Fn archive_read_support_filter_lzma -.It Fn archive_read_support_compression_none -.Fn archive_read_support_filter_none -.It Fn archive_read_support_compression_program -.Fn archive_read_support_filter_program -.It Fn archive_read_support_compression_program_signature -.Fn archive_read_support_filter_program_signature -.It Fn archive_read_support_compression_rpm -.Fn archive_read_support_filter_rpm -.It Fn archive_read_support_compression_uu -.Fn archive_read_support_filter_uu -.It Fn archive_read_support_compression_xz -.Fn archive_read_support_filter_xz -.\" archive_write_set_compression_* -> archive_write_add_filter_* -.It Fn archive_write_set_compression_bzip2 -.Fn archive_write_add_filter_bzip2 -.It Fn archive_write_set_compression_compress -.Fn archive_write_add_filter_compress -.It Fn archive_write_set_compression_gzip -.Fn archive_write_add_filter_gzip -.It Fn archive_write_set_compression_lzip -.Fn archive_write_add_filter_lzip -.It Fn archive_write_set_compression_lzma -.Fn archive_write_add_filter_lzma -.It Fn archive_write_set_compression_none -.Fn archive_write_add_filter_none -.It Fn archive_write_set_compression_program -.Fn archive_write_add_filter_program -.It Fn archive_write_set_compression_filter -.Fn archive_write_add_filter_filter -.El -.\" -.Ss Removed Symbols -.\" -These symbols, listed below along with their replacements if any, -were deprecated in libarchive2, and are not part of libarchive3. -.\" -.Bl -tag -width ind -.It Fn archive_api_feature -.Fn archive_version_number -.It Fn archive_api_version -.Fn archive_version_number -.It Fn archive_version -.Fn archive_version_string -.It Fn archive_version_stamp -.Fn archive_version_number -.It Fn archive_read_set_filter_options -.Fn archive_read_set_options -or -.Fn archive_read_set_filter_option -.It Fn archive_read_set_format_options -.Fn archive_read_set_options -or -.Fn archive_read_set_format_option -.It Fn archive_write_set_filter_options -.Fn archive_write_set_options -or -.Fn archive_write_set_filter_option -.It Fn archive_write_set_format_options -.Fn archive_write_set_options -or -.Fn archive_write_set_format_option -.It Dv ARCHIVE_API_FEATURE -.Dv ARCHIVE_VERSION_NUMBER -.It Dv ARCHIVE_API_VERSION -.Dv ARCHIVE_VERSION_NUMBER -.It Dv ARCHIVE_VERSION_STAMP -.Dv ARCHIVE_VERSION_NUMBER -.It Dv ARCHIVE_LIBRARY_VERSION -.Dv ARCHIVE_VERSION_STRING -.\" -.It Dv ARCHIVE_COMPRESSION_NONE -.Dv ARCHIVE_FILTER_NONE -.It Dv ARCHIVE_COMPRESSION_GZIP -.Dv ARCHIVE_FILTER_GZIP -.It Dv ARCHIVE_COMPRESSION_BZIP2 -.Dv ARCHIVE_FILTER_BZIP2 -.It Dv ARCHIVE_COMPRESSION_COMPRESS -.Dv ARCHIVE_FILTER_COMPRESS -.It Dv ARCHIVE_COMPRESSION_PROGRAM -.Dv ARCHIVE_FILTER_PROGRAM -.It Dv ARCHIVE_COMPRESSION_LZMA -.Dv ARCHIVE_FILTER_LZMA -.It Dv ARCHIVE_COMPRESSION_XZ -.Dv ARCHIVE_FILTER_XZ -.It Dv ARCHIVE_COMPRESSION_UU -.Dv ARCHIVE_FILTER_UU -.It Dv ARCHIVE_COMPRESSION_RPM -.Dv ARCHIVE_FILTER_RPM -.It Dv ARCHIVE_COMPRESSION_LZIP -.Dv ARCHIVE_FILTER_LZIP -.\" -.It Dv ARCHIVE_BYTES_PER_RECORD -.Li 512 -.It Dv ARCHIVE_DEFAULT_BYTES_PER_BLOCK -.Li 10240 -.El -.Sh SEE ALSO -.Xr archive_read 3 , -.Xr archive_read_filter 3 , -.Xr archive_read_format 3 , -.Xr archive_read_set_options 3 , -.Xr archive_util 3 , -.Xr archive_write 3 , -.Xr archive_write_filter 3 , -.Xr archive_write_format 3 , -.Xr archive_write_set_options 3 , -.Xr libarchive 3 diff --git a/thirdparty/libarchive/libarchive/libarchive_internals.3 b/thirdparty/libarchive/libarchive/libarchive_internals.3 deleted file mode 100644 index d672f3e8a..000000000 --- a/thirdparty/libarchive/libarchive/libarchive_internals.3 +++ /dev/null @@ -1,365 +0,0 @@ -.\" Copyright (c) 2003-2007 Tim Kientzle -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd January 26, 2011 -.Dt LIBARCHIVE_INTERNALS 3 -.Os -.Sh NAME -.Nm libarchive_internals -.Nd description of libarchive internal interfaces -.Sh OVERVIEW -The -.Nm libarchive -library provides a flexible interface for reading and writing -streaming archive files such as tar and cpio. -Internally, it follows a modular layered design that should -make it easy to add new archive and compression formats. -.Sh GENERAL ARCHITECTURE -Externally, libarchive exposes most operations through an -opaque, object-style interface. -The -.Xr archive_entry 3 -objects store information about a single filesystem object. -The rest of the library provides facilities to write -.Xr archive_entry 3 -objects to archive files, -read them from archive files, -and write them to disk. -(There are plans to add a facility to read -.Xr archive_entry 3 -objects from disk as well.) -.Pp -The read and write APIs each have four layers: a public API -layer, a format layer that understands the archive file format, -a compression layer, and an I/O layer. -The I/O layer is completely exposed to clients who can replace -it entirely with their own functions. -.Pp -In order to provide as much consistency as possible for clients, -some public functions are virtualized. -Eventually, it should be possible for clients to open -an archive or disk writer, and then use a single set of -code to select and write entries, regardless of the target. -.Sh READ ARCHITECTURE -From the outside, clients use the -.Xr archive_read 3 -API to manipulate an -.Nm archive -object to read entries and bodies from an archive stream. -Internally, the -.Nm archive -object is cast to an -.Nm archive_read -object, which holds all read-specific data. -The API has four layers: -The lowest layer is the I/O layer. -This layer can be overridden by clients, but most clients use -the packaged I/O callbacks provided, for example, by -.Xr archive_read_open_memory 3 , -and -.Xr archive_read_open_fd 3 . -The compression layer calls the I/O layer to -read bytes and decompresses them for the format layer. -The format layer unpacks a stream of uncompressed bytes and -creates -.Nm archive_entry -objects from the incoming data. -The API layer tracks overall state -(for example, it prevents clients from reading data before reading a header) -and invokes the format and compression layer operations -through registered function pointers. -In particular, the API layer drives the format-detection process: -When opening the archive, it reads an initial block of data -and offers it to each registered compression handler. -The one with the highest bid is initialized with the first block. -Similarly, the format handlers are polled to see which handler -is the best for each archive. -(Prior to 2.4.0, the format bidders were invoked for each -entry, but this design hindered error recovery.) -.Ss I/O Layer and Client Callbacks -The read API goes to some lengths to be nice to clients. -As a result, there are few restrictions on the behavior of -the client callbacks. -.Pp -The client read callback is expected to provide a block -of data on each call. -A zero-length return does indicate end of file, but otherwise -blocks may be as small as one byte or as large as the entire file. -In particular, blocks may be of different sizes. -.Pp -The client skip callback returns the number of bytes actually -skipped, which may be much smaller than the skip requested. -The only requirement is that the skip not be larger. -In particular, clients are allowed to return zero for any -skip that they don't want to handle. -The skip callback must never be invoked with a negative value. -.Pp -Keep in mind that not all clients are reading from disk: -clients reading from networks may provide different-sized -blocks on every request and cannot skip at all; -advanced clients may use -.Xr mmap 2 -to read the entire file into memory at once and return the -entire file to libarchive as a single block; -other clients may begin asynchronous I/O operations for the -next block on each request. -.Ss Decompresssion Layer -The decompression layer not only handles decompression, -it also buffers data so that the format handlers see a -much nicer I/O model. -The decompression API is a two stage peek/consume model. -A read_ahead request specifies a minimum read amount; -the decompression layer must provide a pointer to at least -that much data. -If more data is immediately available, it should return more: -the format layer handles bulk data reads by asking for a minimum -of one byte and then copying as much data as is available. -.Pp -A subsequent call to the -.Fn consume -function advances the read pointer. -Note that data returned from a -.Fn read_ahead -call is guaranteed to remain in place until -the next call to -.Fn read_ahead . -Intervening calls to -.Fn consume -should not cause the data to move. -.Pp -Skip requests must always be handled exactly. -Decompression handlers that cannot seek forward should -not register a skip handler; -the API layer fills in a generic skip handler that reads and discards data. -.Pp -A decompression handler has a specific lifecycle: -.Bl -tag -compact -width indent -.It Registration/Configuration -When the client invokes the public support function, -the decompression handler invokes the internal -.Fn __archive_read_register_compression -function to provide bid and initialization functions. -This function returns -.Cm NULL -on error or else a pointer to a -.Cm struct decompressor_t . -This structure contains a -.Va void * config -slot that can be used for storing any customization information. -.It Bid -The bid function is invoked with a pointer and size of a block of data. -The decompressor can access its config data -through the -.Va decompressor -element of the -.Cm archive_read -object. -The bid function is otherwise stateless. -In particular, it must not perform any I/O operations. -.Pp -The value returned by the bid function indicates its suitability -for handling this data stream. -A bid of zero will ensure that this decompressor is never invoked. -Return zero if magic number checks fail. -Otherwise, your initial implementation should return the number of bits -actually checked. -For example, if you verify two full bytes and three bits of another -byte, bid 19. -Note that the initial block may be very short; -be careful to only inspect the data you are given. -(The current decompressors require two bytes for correct bidding.) -.It Initialize -The winning bidder will have its init function called. -This function should initialize the remaining slots of the -.Va struct decompressor_t -object pointed to by the -.Va decompressor -element of the -.Va archive_read -object. -In particular, it should allocate any working data it needs -in the -.Va data -slot of that structure. -The init function is called with the block of data that -was used for tasting. -At this point, the decompressor is responsible for all I/O -requests to the client callbacks. -The decompressor is free to read more data as and when -necessary. -.It Satisfy I/O requests -The format handler will invoke the -.Va read_ahead , -.Va consume , -and -.Va skip -functions as needed. -.It Finish -The finish method is called only once when the archive is closed. -It should release anything stored in the -.Va data -and -.Va config -slots of the -.Va decompressor -object. -It should not invoke the client close callback. -.El -.Ss Format Layer -The read formats have a similar lifecycle to the decompression handlers: -.Bl -tag -compact -width indent -.It Registration -Allocate your private data and initialize your pointers. -.It Bid -Formats bid by invoking the -.Fn read_ahead -decompression method but not calling the -.Fn consume -method. -This allows each bidder to look ahead in the input stream. -Bidders should not look further ahead than necessary, as long -look aheads put pressure on the decompression layer to buffer -lots of data. -Most formats only require a few hundred bytes of look ahead; -look aheads of a few kilobytes are reasonable. -(The ISO9660 reader sometimes looks ahead by 48k, which -should be considered an upper limit.) -.It Read header -The header read is usually the most complex part of any format. -There are a few strategies worth mentioning: -For formats such as tar or cpio, reading and parsing the header is -straightforward since headers alternate with data. -For formats that store all header data at the beginning of the file, -the first header read request may have to read all headers into -memory and store that data, sorted by the location of the file -data. -Subsequent header read requests will skip forward to the -beginning of the file data and return the corresponding header. -.It Read Data -The read data interface supports sparse files; this requires that -each call return a block of data specifying the file offset and -size. -This may require you to carefully track the location so that you -can return accurate file offsets for each read. -Remember that the decompressor will return as much data as it has. -Generally, you will want to request one byte, -examine the return value to see how much data is available, and -possibly trim that to the amount you can use. -You should invoke consume for each block just before you return it. -.It Skip All Data -The skip data call should skip over all file data and trailing padding. -This is called automatically by the API layer just before each -header read. -It is also called in response to the client calling the public -.Fn data_skip -function. -.It Cleanup -On cleanup, the format should release all of its allocated memory. -.El -.Ss API Layer -XXX to do XXX -.Sh WRITE ARCHITECTURE -The write API has a similar set of four layers: -an API layer, a format layer, a compression layer, and an I/O layer. -The registration here is much simpler because only -one format and one compression can be registered at a time. -.Ss I/O Layer and Client Callbacks -XXX To be written XXX -.Ss Compression Layer -XXX To be written XXX -.Ss Format Layer -XXX To be written XXX -.Ss API Layer -XXX To be written XXX -.Sh WRITE_DISK ARCHITECTURE -The write_disk API is intended to look just like the write API -to clients. -Since it does not handle multiple formats or compression, it -is not layered internally. -.Sh GENERAL SERVICES -The -.Nm archive_read , -.Nm archive_write , -and -.Nm archive_write_disk -objects all contain an initial -.Nm archive -object which provides common support for a set of standard services. -(Recall that ANSI/ISO C90 guarantees that you can cast freely between -a pointer to a structure and a pointer to the first element of that -structure.) -The -.Nm archive -object has a magic value that indicates which API this object -is associated with, -slots for storing error information, -and function pointers for virtualized API functions. -.Sh MISCELLANEOUS NOTES -Connecting existing archiving libraries into libarchive is generally -quite difficult. -In particular, many existing libraries strongly assume that you -are reading from a file; they seek forwards and backwards as necessary -to locate various pieces of information. -In contrast, libarchive never seeks backwards in its input, which -sometimes requires very different approaches. -.Pp -For example, libarchive's ISO9660 support operates very differently -from most ISO9660 readers. -The libarchive support utilizes a work-queue design that -keeps a list of known entries sorted by their location in the input. -Whenever libarchive's ISO9660 implementation is asked for the next -header, checks this list to find the next item on the disk. -Directories are parsed when they are encountered and new -items are added to the list. -This design relies heavily on the ISO9660 image being optimized so that -directories always occur earlier on the disk than the files they -describe. -.Pp -Depending on the specific format, such approaches may not be possible. -The ZIP format specification, for example, allows archivers to store -key information only at the end of the file. -In theory, it is possible to create ZIP archives that cannot -be read without seeking. -Fortunately, such archives are very rare, and libarchive can read -most ZIP archives, though it cannot always extract as much information -as a dedicated ZIP program. -.Sh SEE ALSO -.Xr archive_entry 3 , -.Xr archive_read 3 , -.Xr archive_write 3 , -.Xr archive_write_disk 3 , -.Xr libarchive 3 -.Sh HISTORY -The -.Nm libarchive -library first appeared in -.Fx 5.3 . -.Sh AUTHORS -.An -nosplit -The -.Nm libarchive -library was written by -.An Tim Kientzle Aq kientzle@acm.org . diff --git a/thirdparty/libarchive/libarchive/mtree.5 b/thirdparty/libarchive/libarchive/mtree.5 deleted file mode 100644 index 8147796f3..000000000 --- a/thirdparty/libarchive/libarchive/mtree.5 +++ /dev/null @@ -1,324 +0,0 @@ -.\" Copyright (c) 1989, 1990, 1993 -.\" The Regents of the University of California. 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. -.\" 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. -.\" 4. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. -.\" -.\" From: @(#)mtree.8 8.2 (Berkeley) 12/11/93 -.\" $FreeBSD$ -.\" -.Dd September 4, 2013 -.Dt MTREE 5 -.Os -.Sh NAME -.Nm mtree -.Nd format of mtree dir hierarchy files -.Sh DESCRIPTION -The -.Nm -format is a textual format that describes a collection of filesystem objects. -Such files are typically used to create or verify directory hierarchies. -.Ss General Format -An -.Nm -file consists of a series of lines, each providing information -about a single filesystem object. -Leading whitespace is always ignored. -.Pp -When encoding file or pathnames, any backslash character or -character outside of the 95 printable ASCII characters must be -encoded as a backslash followed by three -octal digits. -When reading mtree files, any appearance of a backslash -followed by three octal digits should be converted into the -corresponding character. -.Pp -Each line is interpreted independently as one of the following types: -.Bl -tag -width Cm -.It Blank -Blank lines are ignored. -.It Comment -Lines beginning with -.Cm # -are ignored. -.It Special -Lines beginning with -.Cm / -are special commands that influence -the interpretation of later lines. -.It Relative -If the first whitespace-delimited word has no -.Cm / -characters, -it is the name of a file in the current directory. -Any relative entry that describes a directory changes the -current directory. -.It dot-dot -As a special case, a relative entry with the filename -.Pa .. -changes the current directory to the parent directory. -Options on dot-dot entries are always ignored. -.It Full -If the first whitespace-delimited word has a -.Cm / -character after -the first character, it is the pathname of a file relative to the -starting directory. -There can be multiple full entries describing the same file. -.El -.Pp -Some tools that process -.Nm -files may require that multiple lines describing the same file -occur consecutively. -It is not permitted for the same file to be mentioned using -both a relative and a full file specification. -.Ss Special commands -Two special commands are currently defined: -.Bl -tag -width Cm -.It Cm /set -This command defines default values for one or more keywords. -It is followed on the same line by one or more whitespace-separated -keyword definitions. -These definitions apply to all following files that do not specify -a value for that keyword. -.It Cm /unset -This command removes any default value set by a previous -.Cm /set -command. -It is followed on the same line by one or more keywords -separated by whitespace. -.El -.Ss Keywords -After the filename, a full or relative entry consists of zero -or more whitespace-separated keyword definitions. -Each such definition consists of a key from the following -list immediately followed by an '=' sign -and a value. -Software programs reading mtree files should warn about -unrecognized keywords. -.Pp -Currently supported keywords are as follows: -.Bl -tag -width Cm -.It Cm cksum -The checksum of the file using the default algorithm specified by -the -.Xr cksum 1 -utility. -.It Cm device -The device number for -.Sy block -or -.Sy char -file types. -The value must be one of the following forms: -.Bl -tag -width 4n -.It Ar format , Ns Ar major , Ns Ar minor Ns Bo , Ns Ar subunit Bc -A device with -.Ar major , minor -and optional -.Ar subunit -fields. -Their meaning is specified by the operating's system -.Ar format . -See below for valid formats. -.It Ar number -Opaque number (as stored on the file system). -.El -.Pp -The following values for -.Ar format -are recognized: -.Sy native , -.Sy 386bsd , -.Sy 4bsd , -.Sy bsdos , -.Sy freebsd , -.Sy hpux , -.Sy isc , -.Sy linux , -.Sy netbsd , -.Sy osf1 , -.Sy sco , -.Sy solaris , -.Sy sunos , -.Sy svr3 , -.Sy svr4 , -and -.Sy ultrix . -.Pp -See -.Xr mknod 8 -for more details. -.It Cm contents -The full pathname of a file that holds the contents of this file. -.It Cm flags -The file flags as a symbolic name. -See -.Xr chflags 1 -for information on these names. -If no flags are to be set the string -.Dq none -may be used to override the current default. -.It Cm gid -The file group as a numeric value. -.It Cm gname -The file group as a symbolic name. -.It Cm ignore -Ignore any file hierarchy below this file. -.It Cm inode -The inode number. -.It Cm link -The target of the symbolic link when type=link. -.It Cm md5 -The MD5 message digest of the file. -.It Cm md5digest -A synonym for -.Cm md5 . -.It Cm mode -The current file's permissions as a numeric (octal) or symbolic -value. -.It Cm nlink -The number of hard links the file is expected to have. -.It Cm nochange -Make sure this file or directory exists but otherwise ignore all attributes. -.It Cm optional -The file is optional; do not complain about the file if it is not in -the file hierarchy. -.It Cm resdevice -The -.Dq resident -device number of the file, e.g. the ID of the device that -contains the file. -Its format is the same as the one for -.Cm device . -.It Cm ripemd160digest -The -.Tn RIPEMD160 -message digest of the file. -.It Cm rmd160 -A synonym for -.Cm ripemd160digest . -.It Cm rmd160digest -A synonym for -.Cm ripemd160digest . -.It Cm sha1 -The -.Tn FIPS -160-1 -.Pq Dq Tn SHA-1 -message digest of the file. -.It Cm sha1digest -A synonym for -.Cm sha1 . -.It Cm sha256 -The -.Tn FIPS -180-2 -.Pq Dq Tn SHA-256 -message digest of the file. -.It Cm sha256digest -A synonym for -.Cm sha256 . -.It Cm sha384 -The -.Tn FIPS -180-2 -.Pq Dq Tn SHA-384 -message digest of the file. -.It Cm sha384digest -A synonym for -.Cm sha384 . -.It Cm sha512 -The -.Tn FIPS -180-2 -.Pq Dq Tn SHA-512 -message digest of the file. -.It Cm sha512digest -A synonym for -.Cm sha512 . -.It Cm size -The size, in bytes, of the file. -.It Cm time -The last modification time of the file. -.It Cm type -The type of the file; may be set to any one of the following: -.Pp -.Bl -tag -width Cm -compact -.It Cm block -block special device -.It Cm char -character special device -.It Cm dir -directory -.It Cm fifo -fifo -.It Cm file -regular file -.It Cm link -symbolic link -.It Cm socket -socket -.El -.It Cm uid -The file owner as a numeric value. -.It Cm uname -The file owner as a symbolic name. -.El -.Sh SEE ALSO -.Xr cksum 1 , -.Xr find 1 , -.Xr mtree 8 -.Sh HISTORY -The -.Nm -utility appeared in -.Bx 4.3 Reno . -The -.Tn MD5 -digest capability was added in -.Fx 2.1 , -in response to the widespread use of programs which can spoof -.Xr cksum 1 . -The -.Tn SHA-1 -and -.Tn RIPEMD160 -digests were added in -.Fx 4.0 , -as new attacks have demonstrated weaknesses in -.Tn MD5 . -The -.Tn SHA-256 -digest was added in -.Fx 6.0 . -Support for file flags was added in -.Fx 4.0 , -and mostly comes from -.Nx . -The -.Dq full -entry format was added by -.Nx . diff --git a/thirdparty/libarchive/libarchive/tar.5 b/thirdparty/libarchive/libarchive/tar.5 deleted file mode 100644 index 34ad4f793..000000000 --- a/thirdparty/libarchive/libarchive/tar.5 +++ /dev/null @@ -1,949 +0,0 @@ -.\" Copyright (c) 2003-2009 Tim Kientzle -.\" Copyright (c) 2016 Martin Matuska -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd December 27, 2016 -.Dt TAR 5 -.Os -.Sh NAME -.Nm tar -.Nd format of tape archive files -.Sh DESCRIPTION -The -.Nm -archive format collects any number of files, directories, and other -file system objects (symbolic links, device nodes, etc.) into a single -stream of bytes. -The format was originally designed to be used with -tape drives that operate with fixed-size blocks, but is widely used as -a general packaging mechanism. -.Ss General Format -A -.Nm -archive consists of a series of 512-byte records. -Each file system object requires a header record which stores basic metadata -(pathname, owner, permissions, etc.) and zero or more records containing any -file data. -The end of the archive is indicated by two records consisting -entirely of zero bytes. -.Pp -For compatibility with tape drives that use fixed block sizes, -programs that read or write tar files always read or write a fixed -number of records with each I/O operation. -These -.Dq blocks -are always a multiple of the record size. -The maximum block size supported by early -implementations was 10240 bytes or 20 records. -This is still the default for most implementations -although block sizes of 1MiB (2048 records) or larger are -commonly used with modern high-speed tape drives. -(Note: the terms -.Dq block -and -.Dq record -here are not entirely standard; this document follows the -convention established by John Gilmore in documenting -.Nm pdtar . ) -.Ss Old-Style Archive Format -The original tar archive format has been extended many times to -include additional information that various implementors found -necessary. -This section describes the variant implemented by the tar command -included in -.At v7 , -which seems to be the earliest widely-used version of the tar program. -.Pp -The header record for an old-style -.Nm -archive consists of the following: -.Bd -literal -offset indent -struct header_old_tar { - char name[100]; - char mode[8]; - char uid[8]; - char gid[8]; - char size[12]; - char mtime[12]; - char checksum[8]; - char linkflag[1]; - char linkname[100]; - char pad[255]; -}; -.Ed -All unused bytes in the header record are filled with nulls. -.Bl -tag -width indent -.It Va name -Pathname, stored as a null-terminated string. -Early tar implementations only stored regular files (including -hardlinks to those files). -One common early convention used a trailing "/" character to indicate -a directory name, allowing directory permissions and owner information -to be archived and restored. -.It Va mode -File mode, stored as an octal number in ASCII. -.It Va uid , Va gid -User id and group id of owner, as octal numbers in ASCII. -.It Va size -Size of file, as octal number in ASCII. -For regular files only, this indicates the amount of data -that follows the header. -In particular, this field was ignored by early tar implementations -when extracting hardlinks. -Modern writers should always store a zero length for hardlink entries. -.It Va mtime -Modification time of file, as an octal number in ASCII. -This indicates the number of seconds since the start of the epoch, -00:00:00 UTC January 1, 1970. -Note that negative values should be avoided -here, as they are handled inconsistently. -.It Va checksum -Header checksum, stored as an octal number in ASCII. -To compute the checksum, set the checksum field to all spaces, -then sum all bytes in the header using unsigned arithmetic. -This field should be stored as six octal digits followed by a null and a space -character. -Note that many early implementations of tar used signed arithmetic -for the checksum field, which can cause interoperability problems -when transferring archives between systems. -Modern robust readers compute the checksum both ways and accept the -header if either computation matches. -.It Va linkflag , Va linkname -In order to preserve hardlinks and conserve tape, a file -with multiple links is only written to the archive the first -time it is encountered. -The next time it is encountered, the -.Va linkflag -is set to an ASCII -.Sq 1 -and the -.Va linkname -field holds the first name under which this file appears. -(Note that regular files have a null value in the -.Va linkflag -field.) -.El -.Pp -Early tar implementations varied in how they terminated these fields. -The tar command in -.At v7 -used the following conventions (this is also documented in early BSD manpages): -the pathname must be null-terminated; -the mode, uid, and gid fields must end in a space and a null byte; -the size and mtime fields must end in a space; -the checksum is terminated by a null and a space. -Early implementations filled the numeric fields with leading spaces. -This seems to have been common practice until the -.St -p1003.1-88 -standard was released. -For best portability, modern implementations should fill the numeric -fields with leading zeros. -.Ss Pre-POSIX Archives -An early draft of -.St -p1003.1-88 -served as the basis for John Gilmore's -.Nm pdtar -program and many system implementations from the late 1980s -and early 1990s. -These archives generally follow the POSIX ustar -format described below with the following variations: -.Bl -bullet -compact -width indent -.It -The magic value consists of the five characters -.Dq ustar -followed by a space. -The version field contains a space character followed by a null. -.It -The numeric fields are generally filled with leading spaces -(not leading zeros as recommended in the final standard). -.It -The prefix field is often not used, limiting pathnames to -the 100 characters of old-style archives. -.El -.Ss POSIX ustar Archives -.St -p1003.1-88 -defined a standard tar file format to be read and written -by compliant implementations of -.Xr tar 1 . -This format is often called the -.Dq ustar -format, after the magic value used -in the header. -(The name is an acronym for -.Dq Unix Standard TAR . ) -It extends the historic format with new fields: -.Bd -literal -offset indent -struct header_posix_ustar { - char name[100]; - char mode[8]; - char uid[8]; - char gid[8]; - char size[12]; - char mtime[12]; - char checksum[8]; - char typeflag[1]; - char linkname[100]; - char magic[6]; - char version[2]; - char uname[32]; - char gname[32]; - char devmajor[8]; - char devminor[8]; - char prefix[155]; - char pad[12]; -}; -.Ed -.Bl -tag -width indent -.It Va typeflag -Type of entry. -POSIX extended the earlier -.Va linkflag -field with several new type values: -.Bl -tag -width indent -compact -.It Dq 0 -Regular file. -NUL should be treated as a synonym, for compatibility purposes. -.It Dq 1 -Hard link. -.It Dq 2 -Symbolic link. -.It Dq 3 -Character device node. -.It Dq 4 -Block device node. -.It Dq 5 -Directory. -.It Dq 6 -FIFO node. -.It Dq 7 -Reserved. -.It Other -A POSIX-compliant implementation must treat any unrecognized typeflag value -as a regular file. -In particular, writers should ensure that all entries -have a valid filename so that they can be restored by readers that do not -support the corresponding extension. -Uppercase letters "A" through "Z" are reserved for custom extensions. -Note that sockets and whiteout entries are not archivable. -.El -It is worth noting that the -.Va size -field, in particular, has different meanings depending on the type. -For regular files, of course, it indicates the amount of data -following the header. -For directories, it may be used to indicate the total size of all -files in the directory, for use by operating systems that pre-allocate -directory space. -For all other types, it should be set to zero by writers and ignored -by readers. -.It Va magic -Contains the magic value -.Dq ustar -followed by a NUL byte to indicate that this is a POSIX standard archive. -Full compliance requires the uname and gname fields be properly set. -.It Va version -Version. -This should be -.Dq 00 -(two copies of the ASCII digit zero) for POSIX standard archives. -.It Va uname , Va gname -User and group names, as null-terminated ASCII strings. -These should be used in preference to the uid/gid values -when they are set and the corresponding names exist on -the system. -.It Va devmajor , Va devminor -Major and minor numbers for character device or block device entry. -.It Va name , Va prefix -If the pathname is too long to fit in the 100 bytes provided by the standard -format, it can be split at any -.Pa / -character with the first portion going into the prefix field. -If the prefix field is not empty, the reader will prepend -the prefix value and a -.Pa / -character to the regular name field to obtain the full pathname. -The standard does not require a trailing -.Pa / -character on directory names, though most implementations still -include this for compatibility reasons. -.El -.Pp -Note that all unused bytes must be set to -.Dv NUL . -.Pp -Field termination is specified slightly differently by POSIX -than by previous implementations. -The -.Va magic , -.Va uname , -and -.Va gname -fields must have a trailing -.Dv NUL . -The -.Va pathname , -.Va linkname , -and -.Va prefix -fields must have a trailing -.Dv NUL -unless they fill the entire field. -(In particular, it is possible to store a 256-character pathname if it -happens to have a -.Pa / -as the 156th character.) -POSIX requires numeric fields to be zero-padded in the front, and requires -them to be terminated with either space or -.Dv NUL -characters. -.Pp -Currently, most tar implementations comply with the ustar -format, occasionally extending it by adding new fields to the -blank area at the end of the header record. -.Ss Numeric Extensions -There have been several attempts to extend the range of sizes -or times supported by modifying how numbers are stored in the -header. -.Pp -One obvious extension to increase the size of files is to -eliminate the terminating characters from the various -numeric fields. -For example, the standard only allows the size field to contain -11 octal digits, reserving the twelfth byte for a trailing -NUL character. -Allowing 12 octal digits allows file sizes up to 64 GB. -.Pp -Another extension, utilized by GNU tar, star, and other newer -.Nm -implementations, permits binary numbers in the standard numeric fields. -This is flagged by setting the high bit of the first byte. -The remainder of the field is treated as a signed twos-complement -value. -This permits 95-bit values for the length and time fields -and 63-bit values for the uid, gid, and device numbers. -In particular, this provides a consistent way to handle -negative time values. -GNU tar supports this extension for the -length, mtime, ctime, and atime fields. -Joerg Schilling's star program and the libarchive library support -this extension for all numeric fields. -Note that this extension is largely obsoleted by the extended -attribute record provided by the pax interchange format. -.Pp -Another early GNU extension allowed base-64 values rather than octal. -This extension was short-lived and is no longer supported by any -implementation. -.Ss Pax Interchange Format -There are many attributes that cannot be portably stored in a -POSIX ustar archive. -.St -p1003.1-2001 -defined a -.Dq pax interchange format -that uses two new types of entries to hold text-formatted -metadata that applies to following entries. -Note that a pax interchange format archive is a ustar archive in every -respect. -The new data is stored in ustar-compatible archive entries that use the -.Dq x -or -.Dq g -typeflag. -In particular, older implementations that do not fully support these -extensions will extract the metadata into regular files, where the -metadata can be examined as necessary. -.Pp -An entry in a pax interchange format archive consists of one or -two standard ustar entries, each with its own header and data. -The first optional entry stores the extended attributes -for the following entry. -This optional first entry has an "x" typeflag and a size field that -indicates the total size of the extended attributes. -The extended attributes themselves are stored as a series of text-format -lines encoded in the portable UTF-8 encoding. -Each line consists of a decimal number, a space, a key string, an equals -sign, a value string, and a new line. -The decimal number indicates the length of the entire line, including the -initial length field and the trailing newline. -An example of such a field is: -.Dl 25 ctime=1084839148.1212\en -Keys in all lowercase are standard keys. -Vendors can add their own keys by prefixing them with an all uppercase -vendor name and a period. -Note that, unlike the historic header, numeric values are stored using -decimal, not octal. -A description of some common keys follows: -.Bl -tag -width indent -.It Cm atime , Cm ctime , Cm mtime -File access, inode change, and modification times. -These fields can be negative or include a decimal point and a fractional value. -.It Cm hdrcharset -The character set used by the pax extension values. -By default, all textual values in the pax extended attributes -are assumed to be in UTF-8, including pathnames, user names, -and group names. -In some cases, it is not possible to translate local -conventions into UTF-8. -If this key is present and the value is the six-character ASCII string -.Dq BINARY , -then all textual values are assumed to be in a platform-dependent -multi-byte encoding. -Note that there are only two valid values for this key: -.Dq BINARY -or -.Dq ISO-IR\ 10646\ 2000\ UTF-8 . -No other values are permitted by the standard, and -the latter value should generally not be used as it is the -default when this key is not specified. -In particular, this flag should not be used as a general -mechanism to allow filenames to be stored in arbitrary -encodings. -.It Cm uname , Cm uid , Cm gname , Cm gid -User name, group name, and numeric UID and GID values. -The user name and group name stored here are encoded in UTF8 -and can thus include non-ASCII characters. -The UID and GID fields can be of arbitrary length. -.It Cm linkpath -The full path of the linked-to file. -Note that this is encoded in UTF8 and can thus include non-ASCII characters. -.It Cm path -The full pathname of the entry. -Note that this is encoded in UTF8 and can thus include non-ASCII characters. -.It Cm realtime.* , Cm security.* -These keys are reserved and may be used for future standardization. -.It Cm size -The size of the file. -Note that there is no length limit on this field, allowing conforming -archives to store files much larger than the historic 8GB limit. -.It Cm SCHILY.* -Vendor-specific attributes used by Joerg Schilling's -.Nm star -implementation. -.It Cm SCHILY.acl.access , Cm SCHILY.acl.default , Cm SCHILY.acl.ace -Stores the access, default and NFSv4 ACLs as textual strings in a format -that is an extension of the format specified by POSIX.1e draft 17. -In particular, each user or group access specification can include -an additional colon-separated field with the numeric UID or GID. -This allows ACLs to be restored on systems that may not have complete -user or group information available (such as when NIS/YP or LDAP services -are temporarily unavailable). -.It Cm SCHILY.devminor , Cm SCHILY.devmajor -The full minor and major numbers for device nodes. -.It Cm SCHILY.fflags -The file flags. -.It Cm SCHILY.realsize -The full size of the file on disk. -XXX explain? XXX -.It Cm SCHILY.dev , Cm SCHILY.ino , Cm SCHILY.nlinks -The device number, inode number, and link count for the entry. -In particular, note that a pax interchange format archive using Joerg -Schilling's -.Cm SCHILY.* -extensions can store all of the data from -.Va struct stat . -.It Cm LIBARCHIVE.* -Vendor-specific attributes used by the -.Nm libarchive -library and programs that use it. -.It Cm LIBARCHIVE.creationtime -The time when the file was created. -(This should not be confused with the POSIX -.Dq ctime -attribute, which refers to the time when the file -metadata was last changed.) -.It Cm LIBARCHIVE.xattr . Ns Ar namespace . Ns Ar key -Libarchive stores POSIX.1e-style extended attributes using -keys of this form. -The -.Ar key -value is URL-encoded: -All non-ASCII characters and the two special characters -.Dq = -and -.Dq % -are encoded as -.Dq % -followed by two uppercase hexadecimal digits. -The value of this key is the extended attribute value -encoded in base 64. -XXX Detail the base-64 format here XXX -.It Cm VENDOR.* -XXX document other vendor-specific extensions XXX -.El -.Pp -Any values stored in an extended attribute override the corresponding -values in the regular tar header. -Note that compliant readers should ignore the regular fields when they -are overridden. -This is important, as existing archivers are known to store non-compliant -values in the standard header fields in this situation. -There are no limits on length for any of these fields. -In particular, numeric fields can be arbitrarily large. -All text fields are encoded in UTF8. -Compliant writers should store only portable 7-bit ASCII characters in -the standard ustar header and use extended -attributes whenever a text value contains non-ASCII characters. -.Pp -In addition to the -.Cm x -entry described above, the pax interchange format -also supports a -.Cm g -entry. -The -.Cm g -entry is identical in format, but specifies attributes that serve as -defaults for all subsequent archive entries. -The -.Cm g -entry is not widely used. -.Pp -Besides the new -.Cm x -and -.Cm g -entries, the pax interchange format has a few other minor variations -from the earlier ustar format. -The most troubling one is that hardlinks are permitted to have -data following them. -This allows readers to restore any hardlink to a file without -having to rewind the archive to find an earlier entry. -However, it creates complications for robust readers, as it is no longer -clear whether or not they should ignore the size field for hardlink entries. -.Ss GNU Tar Archives -The GNU tar program started with a pre-POSIX format similar to that -described earlier and has extended it using several different mechanisms: -It added new fields to the empty space in the header (some of which was later -used by POSIX for conflicting purposes); -it allowed the header to be continued over multiple records; -and it defined new entries that modify following entries -(similar in principle to the -.Cm x -entry described above, but each GNU special entry is single-purpose, -unlike the general-purpose -.Cm x -entry). -As a result, GNU tar archives are not POSIX compatible, although -more lenient POSIX-compliant readers can successfully extract most -GNU tar archives. -.Bd -literal -offset indent -struct header_gnu_tar { - char name[100]; - char mode[8]; - char uid[8]; - char gid[8]; - char size[12]; - char mtime[12]; - char checksum[8]; - char typeflag[1]; - char linkname[100]; - char magic[6]; - char version[2]; - char uname[32]; - char gname[32]; - char devmajor[8]; - char devminor[8]; - char atime[12]; - char ctime[12]; - char offset[12]; - char longnames[4]; - char unused[1]; - struct { - char offset[12]; - char numbytes[12]; - } sparse[4]; - char isextended[1]; - char realsize[12]; - char pad[17]; -}; -.Ed -.Bl -tag -width indent -.It Va typeflag -GNU tar uses the following special entry types, in addition to -those defined by POSIX: -.Bl -tag -width indent -.It "7" -GNU tar treats type "7" records identically to type "0" records, -except on one obscure RTOS where they are used to indicate the -pre-allocation of a contiguous file on disk. -.It "D" -This indicates a directory entry. -Unlike the POSIX-standard "5" -typeflag, the header is followed by data records listing the names -of files in this directory. -Each name is preceded by an ASCII "Y" -if the file is stored in this archive or "N" if the file is not -stored in this archive. -Each name is terminated with a null, and -an extra null marks the end of the name list. -The purpose of this -entry is to support incremental backups; a program restoring from -such an archive may wish to delete files on disk that did not exist -in the directory when the archive was made. -.Pp -Note that the "D" typeflag specifically violates POSIX, which requires -that unrecognized typeflags be restored as normal files. -In this case, restoring the "D" entry as a file could interfere -with subsequent creation of the like-named directory. -.It "K" -The data for this entry is a long linkname for the following regular entry. -.It "L" -The data for this entry is a long pathname for the following regular entry. -.It "M" -This is a continuation of the last file on the previous volume. -GNU multi-volume archives guarantee that each volume begins with a valid -entry header. -To ensure this, a file may be split, with part stored at the end of one volume, -and part stored at the beginning of the next volume. -The "M" typeflag indicates that this entry continues an existing file. -Such entries can only occur as the first or second entry -in an archive (the latter only if the first entry is a volume label). -The -.Va size -field specifies the size of this entry. -The -.Va offset -field at bytes 369-380 specifies the offset where this file fragment -begins. -The -.Va realsize -field specifies the total size of the file (which must equal -.Va size -plus -.Va offset ) . -When extracting, GNU tar checks that the header file name is the one it is -expecting, that the header offset is in the correct sequence, and that -the sum of offset and size is equal to realsize. -.It "N" -Type "N" records are no longer generated by GNU tar. -They contained a -list of files to be renamed or symlinked after extraction; this was -originally used to support long names. -The contents of this record -are a text description of the operations to be done, in the form -.Dq Rename %s to %s\en -or -.Dq Symlink %s to %s\en ; -in either case, both -filenames are escaped using K&R C syntax. -Due to security concerns, "N" records are now generally ignored -when reading archives. -.It "S" -This is a -.Dq sparse -regular file. -Sparse files are stored as a series of fragments. -The header contains a list of fragment offset/length pairs. -If more than four such entries are required, the header is -extended as necessary with -.Dq extra -header extensions (an older format that is no longer used), or -.Dq sparse -extensions. -.It "V" -The -.Va name -field should be interpreted as a tape/volume header name. -This entry should generally be ignored on extraction. -.El -.It Va magic -The magic field holds the five characters -.Dq ustar -followed by a space. -Note that POSIX ustar archives have a trailing null. -.It Va version -The version field holds a space character followed by a null. -Note that POSIX ustar archives use two copies of the ASCII digit -.Dq 0 . -.It Va atime , Va ctime -The time the file was last accessed and the time of -last change of file information, stored in octal as with -.Va mtime . -.It Va longnames -This field is apparently no longer used. -.It Sparse Va offset / Va numbytes -Each such structure specifies a single fragment of a sparse -file. -The two fields store values as octal numbers. -The fragments are each padded to a multiple of 512 bytes -in the archive. -On extraction, the list of fragments is collected from the -header (including any extension headers), and the data -is then read and written to the file at appropriate offsets. -.It Va isextended -If this is set to non-zero, the header will be followed by additional -.Dq sparse header -records. -Each such record contains information about as many as 21 additional -sparse blocks as shown here: -.Bd -literal -offset indent -struct gnu_sparse_header { - struct { - char offset[12]; - char numbytes[12]; - } sparse[21]; - char isextended[1]; - char padding[7]; -}; -.Ed -.It Va realsize -A binary representation of the file's complete size, with a much larger range -than the POSIX file size. -In particular, with -.Cm M -type files, the current entry is only a portion of the file. -In that case, the POSIX size field will indicate the size of this -entry; the -.Va realsize -field will indicate the total size of the file. -.El -.Ss GNU tar pax archives -GNU tar 1.14 (XXX check this XXX) and later will write -pax interchange format archives when you specify the -.Fl -posix -flag. -This format follows the pax interchange format closely, -using some -.Cm SCHILY -tags and introducing new keywords to store sparse file information. -There have been three iterations of the sparse file support, referred to -as -.Dq 0.0 , -.Dq 0.1 , -and -.Dq 1.0 . -.Bl -tag -width indent -.It Cm GNU.sparse.numblocks , Cm GNU.sparse.offset , Cm GNU.sparse.numbytes , Cm GNU.sparse.size -The -.Dq 0.0 -format used an initial -.Cm GNU.sparse.numblocks -attribute to indicate the number of blocks in the file, a pair of -.Cm GNU.sparse.offset -and -.Cm GNU.sparse.numbytes -to indicate the offset and size of each block, -and a single -.Cm GNU.sparse.size -to indicate the full size of the file. -This is not the same as the size in the tar header because the -latter value does not include the size of any holes. -This format required that the order of attributes be preserved and -relied on readers accepting multiple appearances of the same attribute -names, which is not officially permitted by the standards. -.It Cm GNU.sparse.map -The -.Dq 0.1 -format used a single attribute that stored a comma-separated -list of decimal numbers. -Each pair of numbers indicated the offset and size, respectively, -of a block of data. -This does not work well if the archive is extracted by an archiver -that does not recognize this extension, since many pax implementations -simply discard unrecognized attributes. -.It Cm GNU.sparse.major , Cm GNU.sparse.minor , Cm GNU.sparse.name , Cm GNU.sparse.realsize -The -.Dq 1.0 -format stores the sparse block map in one or more 512-byte blocks -prepended to the file data in the entry body. -The pax attributes indicate the existence of this map -(via the -.Cm GNU.sparse.major -and -.Cm GNU.sparse.minor -fields) -and the full size of the file. -The -.Cm GNU.sparse.name -holds the true name of the file. -To avoid confusion, the name stored in the regular tar header -is a modified name so that extraction errors will be apparent -to users. -.El -.Ss Solaris Tar -XXX More Details Needed XXX -.Pp -Solaris tar (beginning with SunOS XXX 5.7 ?? XXX) supports an -.Dq extended -format that is fundamentally similar to pax interchange format, -with the following differences: -.Bl -bullet -compact -width indent -.It -Extended attributes are stored in an entry whose type is -.Cm X , -not -.Cm x , -as used by pax interchange format. -The detailed format of this entry appears to be the same -as detailed above for the -.Cm x -entry. -.It -An additional -.Cm A -header is used to store an ACL for the following regular entry. -The body of this entry contains a seven-digit octal number -followed by a zero byte, followed by the -textual ACL description. -The octal value is the number of ACL entries -plus a constant that indicates the ACL type: 01000000 -for POSIX.1e ACLs and 03000000 for NFSv4 ACLs. -.El -.Ss AIX Tar -XXX More details needed XXX -.Pp -AIX Tar uses a ustar-formatted header with the type -.Cm A -for storing coded ACL information. -Unlike the Solaris format, AIX tar writes this header after the -regular file body to which it applies. -The pathname in this header is either -.Cm NFS4 -or -.Cm AIXC -to indicate the type of ACL stored. -The actual ACL is stored in platform-specific binary format. -.Ss Mac OS X Tar -The tar distributed with Apple's Mac OS X stores most regular files -as two separate files in the tar archive. -The two files have the same name except that the first -one has -.Dq ._ -prepended to the last path element. -This special file stores an AppleDouble-encoded -binary blob with additional metadata about the second file, -including ACL, extended attributes, and resources. -To recreate the original file on disk, each -separate file can be extracted and the Mac OS X -.Fn copyfile -function can be used to unpack the separate -metadata file and apply it to th regular file. -Conversely, the same function provides a -.Dq pack -option to encode the extended metadata from -a file into a separate file whose contents -can then be put into a tar archive. -.Pp -Note that the Apple extended attributes interact -badly with long filenames. -Since each file is stored with the full name, -a separate set of extensions needs to be included -in the archive for each one, doubling the overhead -required for files with long names. -.Ss Summary of tar type codes -The following list is a condensed summary of the type codes -used in tar header records generated by different tar implementations. -More details about specific implementations can be found above: -.Bl -tag -compact -width XXX -.It NUL -Early tar programs stored a zero byte for regular files. -.It Cm 0 -POSIX standard type code for a regular file. -.It Cm 1 -POSIX standard type code for a hard link description. -.It Cm 2 -POSIX standard type code for a symbolic link description. -.It Cm 3 -POSIX standard type code for a character device node. -.It Cm 4 -POSIX standard type code for a block device node. -.It Cm 5 -POSIX standard type code for a directory. -.It Cm 6 -POSIX standard type code for a FIFO. -.It Cm 7 -POSIX reserved. -.It Cm 7 -GNU tar used for pre-allocated files on some systems. -.It Cm A -Solaris tar ACL description stored prior to a regular file header. -.It Cm A -AIX tar ACL description stored after the file body. -.It Cm D -GNU tar directory dump. -.It Cm K -GNU tar long linkname for the following header. -.It Cm L -GNU tar long pathname for the following header. -.It Cm M -GNU tar multivolume marker, indicating the file is a continuation of a file from the previous volume. -.It Cm N -GNU tar long filename support. -Deprecated. -.It Cm S -GNU tar sparse regular file. -.It Cm V -GNU tar tape/volume header name. -.It Cm X -Solaris tar general-purpose extension header. -.It Cm g -POSIX pax interchange format global extensions. -.It Cm x -POSIX pax interchange format per-file extensions. -.El -.Sh SEE ALSO -.Xr ar 1 , -.Xr pax 1 , -.Xr tar 1 -.Sh STANDARDS -The -.Nm tar -utility is no longer a part of POSIX or the Single Unix Standard. -It last appeared in -.St -susv2 . -It has been supplanted in subsequent standards by -.Xr pax 1 . -The ustar format is currently part of the specification for the -.Xr pax 1 -utility. -The pax interchange file format is new with -.St -p1003.1-2001 . -.Sh HISTORY -A -.Nm tar -command appeared in Seventh Edition Unix, which was released in January, 1979. -It replaced the -.Nm tp -program from Fourth Edition Unix which in turn replaced the -.Nm tap -program from First Edition Unix. -John Gilmore's -.Nm pdtar -public-domain implementation (circa 1987) was highly influential -and formed the basis of -.Nm GNU tar -(circa 1988). -Joerg Shilling's -.Nm star -archiver is another open-source (CDDL) archiver (originally developed -circa 1985) which features complete support for pax interchange -format. -.Pp -This documentation was written as part of the -.Nm libarchive -and -.Nm bsdtar -project by -.An Tim Kientzle Aq kientzle@FreeBSD.org . diff --git a/thirdparty/libarchive/libarchive/test/CMakeLists.txt b/thirdparty/libarchive/libarchive/test/CMakeLists.txt deleted file mode 100644 index 5e17d62fd..000000000 --- a/thirdparty/libarchive/libarchive/test/CMakeLists.txt +++ /dev/null @@ -1,331 +0,0 @@ -############################################ -# -# How to build libarchive_test -# -############################################ -IF(ENABLE_TEST) - SET(libarchive_test_SOURCES - ../../test_utils/test_utils.c - ../../test_utils/test_main.c - read_open_memory.c - test.h - test_acl_nfs4.c - test_acl_pax.c - test_acl_platform_nfs4.c - test_acl_platform_posix1e.c - test_acl_posix1e.c - test_acl_text.c - test_archive_api_feature.c - test_archive_clear_error.c - test_archive_cmdline.c - test_archive_digest.c - test_archive_getdate.c - test_archive_match_owner.c - test_archive_match_path.c - test_archive_match_time.c - test_archive_pathmatch.c - test_archive_read_add_passphrase.c - test_archive_read_close_twice.c - test_archive_read_close_twice_open_fd.c - test_archive_read_close_twice_open_filename.c - test_archive_read_multiple_data_objects.c - test_archive_read_next_header_empty.c - test_archive_read_next_header_raw.c - test_archive_read_open2.c - test_archive_read_set_filter_option.c - test_archive_read_set_format_option.c - test_archive_read_set_option.c - test_archive_read_set_options.c - test_archive_read_support.c - test_archive_set_error.c - test_archive_string.c - test_archive_string_conversion.c - test_archive_write_add_filter_by_name.c - test_archive_write_set_filter_option.c - test_archive_write_set_format_by_name.c - test_archive_write_set_format_filter_by_ext.c - test_archive_write_set_format_option.c - test_archive_write_set_option.c - test_archive_write_set_options.c - test_archive_write_set_passphrase.c - test_bad_fd.c - test_compat_bzip2.c - test_compat_cpio.c - test_compat_gtar.c - test_compat_gzip.c - test_compat_lz4.c - test_compat_lzip.c - test_compat_lzma.c - test_compat_lzop.c - test_compat_mac.c - test_compat_perl_archive_tar.c - test_compat_plexus_archiver_tar.c - test_compat_solaris_pax_sparse.c - test_compat_solaris_tar_acl.c - test_compat_star_acl.c - test_compat_tar_directory.c - test_compat_tar_hardlink.c - test_compat_uudecode.c - test_compat_uudecode_large.c - test_compat_xz.c - test_compat_zip.c - test_compat_zstd.c - test_empty_write.c - test_entry.c - test_entry_strmode.c - test_extattr_freebsd.c - test_filter_count.c - test_fuzz.c - test_gnutar_filename_encoding.c - test_link_resolver.c - test_open_failure.c - test_open_fd.c - test_open_file.c - test_open_filename.c - test_pax_filename_encoding.c - test_pax_xattr_header.c - test_read_data_large.c - test_read_disk.c - test_read_disk_directory_traversals.c - test_read_disk_entry_from_file.c - test_read_extract.c - test_read_file_nonexistent.c - test_read_filter_compress.c - test_read_filter_grzip.c - test_read_filter_lrzip.c - test_read_filter_lzop.c - test_read_filter_lzop_multiple_parts.c - test_read_filter_program.c - test_read_filter_program_signature.c - test_read_filter_uudecode.c - test_read_filter_uudecode_raw.c - test_read_format_7zip.c - test_read_format_7zip_encryption_data.c - test_read_format_7zip_encryption_header.c - test_read_format_7zip_encryption_partially.c - test_read_format_7zip_malformed.c - test_read_format_7zip_packinfo_digests.c - test_read_format_ar.c - test_read_format_cab.c - test_read_format_cab_filename.c - test_read_format_cpio_afio.c - test_read_format_cpio_bin.c - test_read_format_cpio_bin_Z.c - test_read_format_cpio_bin_be.c - test_read_format_cpio_bin_bz2.c - test_read_format_cpio_bin_gz.c - test_read_format_cpio_bin_le.c - test_read_format_cpio_bin_lzip.c - test_read_format_cpio_bin_lzma.c - test_read_format_cpio_bin_xz.c - test_read_format_cpio_filename.c - test_read_format_cpio_odc.c - test_read_format_cpio_svr4_bzip2_rpm.c - test_read_format_cpio_svr4_gzip.c - test_read_format_cpio_svr4_gzip_rpm.c - test_read_format_cpio_svr4c_Z.c - test_read_format_empty.c - test_read_format_gtar_filename.c - test_read_format_gtar_gz.c - test_read_format_gtar_lzma.c - test_read_format_gtar_sparse.c - test_read_format_gtar_sparse_skip_entry.c - test_read_format_iso_Z.c - test_read_format_iso_multi_extent.c - test_read_format_iso_xorriso.c - test_read_format_isojoliet_bz2.c - test_read_format_isojoliet_long.c - test_read_format_isojoliet_rr.c - test_read_format_isojoliet_versioned.c - test_read_format_isorr_bz2.c - test_read_format_isorr_ce.c - test_read_format_isorr_new_bz2.c - test_read_format_isorr_rr_moved.c - test_read_format_isozisofs_bz2.c - test_read_format_lha.c - test_read_format_lha_bugfix_0.c - test_read_format_lha_filename.c - test_read_format_lha_filename_utf16.c - test_read_format_mtree.c - test_read_format_mtree_crash747.c - test_read_format_pax_bz2.c - test_read_format_rar.c - test_read_format_rar_encryption_data.c - test_read_format_rar_encryption_header.c - test_read_format_rar_encryption_partially.c - test_read_format_rar_invalid1.c - test_read_format_rar_filter.c - test_read_format_rar5.c - test_read_format_raw.c - test_read_format_tar.c - test_read_format_tar_concatenated.c - test_read_format_tar_empty_filename.c - test_read_format_tar_empty_with_gnulabel.c - test_read_format_tar_empty_pax.c - test_read_format_tar_filename.c - test_read_format_tar_invalid_pax_size.c - test_read_format_tbz.c - test_read_format_tgz.c - test_read_format_tlz.c - test_read_format_txz.c - test_read_format_tz.c - test_read_format_ustar_filename.c - test_read_format_warc.c - test_read_format_xar.c - test_read_format_zip.c - test_read_format_zip_7075_utf8_paths.c - test_read_format_zip_comment_stored.c - test_read_format_zip_encryption_data.c - test_read_format_zip_encryption_header.c - test_read_format_zip_encryption_partially.c - test_read_format_zip_extra_padding.c - test_read_format_zip_filename.c - test_read_format_zip_high_compression.c - test_read_format_zip_jar.c - test_read_format_zip_mac_metadata.c - test_read_format_zip_malformed.c - test_read_format_zip_msdos.c - test_read_format_zip_nested.c - test_read_format_zip_nofiletype.c - test_read_format_zip_padded.c - test_read_format_zip_sfx.c - test_read_format_zip_traditional_encryption_data.c - test_read_format_zip_winzip_aes.c - test_read_format_zip_winzip_aes_large.c - test_read_format_zip_zip64.c - test_read_format_zip_with_invalid_traditional_eocd.c - test_read_large.c - test_read_pax_xattr_rht_security_selinux.c - test_read_pax_xattr_schily.c - test_read_pax_truncated.c - test_read_position.c - test_read_set_format.c - test_read_too_many_filters.c - test_read_truncated.c - test_read_truncated_filter.c - test_short_writes.c - test_sparse_basic.c - test_tar_filenames.c - test_tar_large.c - test_ustar_filename_encoding.c - test_ustar_filenames.c - test_warn_missing_hardlink_target.c - test_write_disk.c - test_write_disk_appledouble.c - test_write_disk_failures.c - test_write_disk_fixup.c - test_write_disk_hardlink.c - test_write_disk_hfs_compression.c - test_write_disk_lookup.c - test_write_disk_mac_metadata.c - test_write_disk_no_hfs_compression.c - test_write_disk_perms.c - test_write_disk_secure.c - test_write_disk_secure744.c - test_write_disk_secure745.c - test_write_disk_secure746.c - test_write_disk_sparse.c - test_write_disk_symlink.c - test_write_disk_times.c - test_write_filter_b64encode.c - test_write_filter_bzip2.c - test_write_filter_compress.c - test_write_filter_gzip.c - test_write_filter_gzip_timestamp.c - test_write_filter_lrzip.c - test_write_filter_lz4.c - test_write_filter_lzip.c - test_write_filter_lzma.c - test_write_filter_lzop.c - test_write_filter_program.c - test_write_filter_uuencode.c - test_write_filter_xz.c - test_write_filter_zstd.c - test_write_format_7zip.c - test_write_format_7zip_empty.c - test_write_format_7zip_large.c - test_write_format_ar.c - test_write_format_cpio.c - test_write_format_cpio_empty.c - test_write_format_cpio_newc.c - test_write_format_cpio_odc.c - test_write_format_gnutar.c - test_write_format_gnutar_filenames.c - test_write_format_iso9660.c - test_write_format_iso9660_boot.c - test_write_format_iso9660_empty.c - test_write_format_iso9660_filename.c - test_write_format_iso9660_zisofs.c - test_write_format_mtree.c - test_write_format_mtree_absolute_path.c - test_write_format_mtree_classic.c - test_write_format_mtree_classic_indent.c - test_write_format_mtree_fflags.c - test_write_format_mtree_no_separator.c - test_write_format_mtree_quoted_filename.c - test_write_format_pax.c - test_write_format_raw.c - test_write_format_raw_b64.c - test_write_format_shar_empty.c - test_write_format_tar.c - test_write_format_tar_empty.c - test_write_format_tar_sparse.c - test_write_format_tar_ustar.c - test_write_format_tar_v7tar.c - test_write_format_warc.c - test_write_format_warc_empty.c - test_write_format_xar.c - test_write_format_xar_empty.c - test_write_format_zip.c - test_write_format_zip_compression_store.c - test_write_format_zip_empty.c - test_write_format_zip_empty_zip64.c - test_write_format_zip_entry_size_unset.c - test_write_format_zip_file.c - test_write_format_zip_file_zip64.c - test_write_format_zip_large.c - test_write_format_zip_zip64.c - test_write_open_memory.c - test_write_read_format_zip.c - test_xattr_platform.c - test_zip_filename_encoding.c - ) - - # - # Register target - # - ADD_EXECUTABLE(libarchive_test ${libarchive_test_SOURCES}) - TARGET_LINK_LIBRARIES(libarchive_test archive_static ${ADDITIONAL_LIBS}) - SET_PROPERTY(TARGET libarchive_test PROPERTY COMPILE_DEFINITIONS - LIBARCHIVE_STATIC LIST_H) - - # - # Generate list.h by grepping DEFINE_TEST() lines out of the C sources. - # - GENERATE_LIST_H(${CMAKE_CURRENT_BINARY_DIR}/list.h - ${CMAKE_CURRENT_LIST_FILE} ${libarchive_test_SOURCES}) - SET_PROPERTY(DIRECTORY APPEND PROPERTY INCLUDE_DIRECTORIES - ${CMAKE_CURRENT_BINARY_DIR}) - - # list.h has a line DEFINE_TEST(testname) for every - # test. We can use that to define the tests for cmake by - # defining a DEFINE_TEST macro and reading list.h in. - MACRO (DEFINE_TEST _testname) - ADD_TEST( - NAME libarchive_${_testname} - COMMAND libarchive_test -vv - -r ${CMAKE_CURRENT_SOURCE_DIR} - ${_testname}) - ENDMACRO (DEFINE_TEST _testname) - - INCLUDE(${CMAKE_CURRENT_BINARY_DIR}/list.h) - INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) - INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/test_utils) - INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/libarchive/test) - - # Experimental new test handling - ADD_CUSTOM_TARGET(run_libarchive_test - COMMAND libarchive_test -r ${CMAKE_CURRENT_SOURCE_DIR} -vv) - ADD_DEPENDENCIES(run_all_tests run_libarchive_test) -ENDIF(ENABLE_TEST) - diff --git a/thirdparty/libarchive/libarchive/test/README b/thirdparty/libarchive/libarchive/test/README deleted file mode 100644 index 1b70c7adb..000000000 --- a/thirdparty/libarchive/libarchive/test/README +++ /dev/null @@ -1,63 +0,0 @@ -$FreeBSD: src/lib/libarchive/test/README,v 1.3 2008/01/01 22:28:04 kientzle Exp $ - -This is the test harness for libarchive. - -It compiles into a single program "libarchive_test" that is intended -to exercise as much of the library as possible. It is, of course, -very much a work in progress. - -Each test is a function named test_foo in a file named test_foo.c. -Note that the file name is the same as the function name. -Each file must start with this line: - - #include "test.h" - -The test function must be declared with a line of this form - - DEFINE_TEST(test_foo) - -Nothing else should appear on that line. - -When you add a test, please update the top-level Makefile.am and the -CMakeLists.txt in this directory to add your file to the list of -tests. The Makefile and main.c use various macro trickery to -automatically collect a list of test functions to be invoked. - -Each test function can rely on the following: - - * The current directory will be a freshly-created empty directory - suitable for that test. (The top-level main() creates a - directory for each separate test and chdir()s to that directory - before running the test.) - - * The test function should use assert(), assertA() and similar macros - defined in test.h. If you need to add new macros of this form, feel - free to do so. The current macro set includes assertEqualInt() and - assertEqualString() that print out additional detail about their - arguments if the assertion does fail. 'A' versions also accept - a struct archive * and display any error message from there on - failure. - - * You are encouraged to document each assertion with a failure() call - just before the assert. The failure() function is a printf-like - function whose text is displayed only if the assertion fails. It - can be used to display additional information relevant to the failure: - - failure("The data read from file %s did not match the data written to that file.", filename); - assert(strcmp(buff1, buff2) == 0); - - * Tests are encouraged to be economical with their memory and disk usage, - though this is not essential. The test is occasionally run under - a memory debugger to try to locate memory leaks in the library; - as a result, tests should be careful to release any memory they - allocate. - - * Disable tests on specific platforms as necessary. Please avoid - using config.h to adjust feature requirements, as I want the tests - to also serve as a check on the configure process. The following - form is usually more appropriate: - -#if !defined(__PLATFORM) && !defined(__Platform2__) - assert(xxxx) -#endif - diff --git a/thirdparty/libarchive/libarchive/test/list.h b/thirdparty/libarchive/libarchive/test/list.h deleted file mode 100644 index 557feb5fb..000000000 --- a/thirdparty/libarchive/libarchive/test/list.h +++ /dev/null @@ -1,601 +0,0 @@ -DEFINE_TEST(test_acl_nfs4) -DEFINE_TEST(test_acl_pax_posix1e) -DEFINE_TEST(test_acl_pax_nfs4) -DEFINE_TEST(test_acl_platform_nfs4) -DEFINE_TEST(test_acl_platform_posix1e_restore) -DEFINE_TEST(test_acl_platform_posix1e_read) -DEFINE_TEST(test_acl_posix1e) -DEFINE_TEST(test_acl_from_text) -DEFINE_TEST(test_acl_to_text) -DEFINE_TEST(test_archive_api_feature) -DEFINE_TEST(test_archive_clear_error) -DEFINE_TEST(test_archive_cmdline) -DEFINE_TEST(test_archive_md5) -DEFINE_TEST(test_archive_rmd160) -DEFINE_TEST(test_archive_sha1) -DEFINE_TEST(test_archive_sha256) -DEFINE_TEST(test_archive_sha384) -DEFINE_TEST(test_archive_sha512) -DEFINE_TEST(test_archive_getdate) -DEFINE_TEST(test_archive_match_owner) -DEFINE_TEST(test_archive_match_path) -DEFINE_TEST(test_archive_match_time) -DEFINE_TEST(test_archive_pathmatch) -DEFINE_TEST(test_archive_read_add_passphrase) -DEFINE_TEST(test_archive_read_add_passphrase_incorrect_sequance) -DEFINE_TEST(test_archive_read_add_passphrase_single) -DEFINE_TEST(test_archive_read_add_passphrase_multiple) -DEFINE_TEST(test_archive_read_add_passphrase_set_callback1) -DEFINE_TEST(test_archive_read_add_passphrase_set_callback2) -DEFINE_TEST(test_archive_read_add_passphrase_set_callback3) -DEFINE_TEST(test_archive_read_add_passphrase_multiple_with_callback) -DEFINE_TEST(test_archive_read_add_passphrase_multiple_with_callback2) -DEFINE_TEST(test_archive_read_close_twice) -DEFINE_TEST(test_archive_read_close_twice_open_fd) -DEFINE_TEST(test_archive_read_close_twice_open_filename) -DEFINE_TEST(test_archive_read_multiple_data_objects) -DEFINE_TEST(test_archive_read_next_header_empty) -DEFINE_TEST(test_archive_read_next_header_raw) -DEFINE_TEST(test_archive_read_open2) -DEFINE_TEST(test_archive_read_set_filter_option) -DEFINE_TEST(test_archive_read_set_format_option) -DEFINE_TEST(test_archive_read_set_option) -DEFINE_TEST(test_archive_read_set_options) -DEFINE_TEST(test_archive_read_support) -DEFINE_TEST(test_archive_set_error) -DEFINE_TEST(test_archive_string) -DEFINE_TEST(test_archive_string_sort) -DEFINE_TEST(test_archive_string_conversion) -DEFINE_TEST(test_archive_write_add_filter_by_name_b64encode) -DEFINE_TEST(test_archive_write_add_filter_by_name_bzip2) -DEFINE_TEST(test_archive_write_add_filter_by_name_compress) -DEFINE_TEST(test_archive_write_add_filter_by_name_grzip) -DEFINE_TEST(test_archive_write_add_filter_by_name_gzip) -DEFINE_TEST(test_archive_write_add_filter_by_name_lrzip) -DEFINE_TEST(test_archive_write_add_filter_by_name_lz4) -DEFINE_TEST(test_archive_write_add_filter_by_name_lzip) -DEFINE_TEST(test_archive_write_add_filter_by_name_lzma) -DEFINE_TEST(test_archive_write_add_filter_by_name_lzop) -DEFINE_TEST(test_archive_write_add_filter_by_name_uuencode) -DEFINE_TEST(test_archive_write_add_filter_by_name_xz) -DEFINE_TEST(test_archive_write_add_filter_by_name_zstd) -DEFINE_TEST(test_archive_write_set_filter_option) -DEFINE_TEST(test_archive_write_set_format_by_name_7zip) -DEFINE_TEST(test_archive_write_set_format_by_name_ar) -DEFINE_TEST(test_archive_write_set_format_by_name_arbsd) -DEFINE_TEST(test_archive_write_set_format_by_name_argnu) -DEFINE_TEST(test_archive_write_set_format_by_name_arsvr4) -DEFINE_TEST(test_archive_write_set_format_by_name_bsdtar) -DEFINE_TEST(test_archive_write_set_format_by_name_cd9660) -DEFINE_TEST(test_archive_write_set_format_by_name_cpio) -DEFINE_TEST(test_archive_write_set_format_by_name_gnutar) -DEFINE_TEST(test_archive_write_set_format_by_name_iso) -DEFINE_TEST(test_archive_write_set_format_by_name_iso9660) -DEFINE_TEST(test_archive_write_set_format_by_name_mtree) -DEFINE_TEST(test_archive_write_set_format_by_name_mtree_classic) -DEFINE_TEST(test_archive_write_set_format_by_name_newc) -DEFINE_TEST(test_archive_write_set_format_by_name_odc) -DEFINE_TEST(test_archive_write_set_format_by_name_oldtar) -DEFINE_TEST(test_archive_write_set_format_by_name_pax) -DEFINE_TEST(test_archive_write_set_format_by_name_paxr) -DEFINE_TEST(test_archive_write_set_format_by_name_posix) -DEFINE_TEST(test_archive_write_set_format_by_name_rpax) -DEFINE_TEST(test_archive_write_set_format_by_name_shar) -DEFINE_TEST(test_archive_write_set_format_by_name_shardump) -DEFINE_TEST(test_archive_write_set_format_by_name_ustar) -DEFINE_TEST(test_archive_write_set_format_by_name_v7tar) -DEFINE_TEST(test_archive_write_set_format_by_name_v7) -DEFINE_TEST(test_archive_write_set_format_by_name_warc) -DEFINE_TEST(test_archive_write_set_format_by_name_xar) -DEFINE_TEST(test_archive_write_set_format_by_name_zip) -DEFINE_TEST(test_archive_write_set_format_filter_by_ext_7zip) -DEFINE_TEST(test_archive_write_set_format_filter_by_ext_zip) -DEFINE_TEST(test_archive_write_set_format_filter_by_ext_jar) -DEFINE_TEST(test_archive_write_set_format_filter_by_ext_a) -DEFINE_TEST(test_archive_write_set_format_filter_by_ext_ar) -DEFINE_TEST(test_archive_write_set_format_filter_by_ext_cpio) -DEFINE_TEST(test_archive_write_set_format_filter_by_ext_iso) -DEFINE_TEST(test_archive_write_set_format_filter_by_ext_tar) -DEFINE_TEST(test_archive_write_set_format_filter_by_ext_tar_gz) -DEFINE_TEST(test_archive_write_set_format_filter_by_ext_tar_bz2) -DEFINE_TEST(test_archive_write_set_format_filter_by_ext_tar_xz) -DEFINE_TEST(test_archive_write_set_format_filter_by_no_ext_def_zip) -DEFINE_TEST(test_archive_write_set_format_filter_by_ext_tar_bz2_def_zip) -DEFINE_TEST(test_archive_write_set_format_option) -DEFINE_TEST(test_archive_write_set_option) -DEFINE_TEST(test_archive_write_set_options) -DEFINE_TEST(test_archive_write_set_passphrase) -DEFINE_TEST(test_archive_write_set_passphrase_callback) -DEFINE_TEST(test_bad_fd) -DEFINE_TEST(test_compat_bzip2) -DEFINE_TEST(test_compat_cpio) -DEFINE_TEST(test_compat_gtar) -DEFINE_TEST(test_compat_gzip) -DEFINE_TEST(test_compat_lz4) -DEFINE_TEST(test_compat_lzip) -DEFINE_TEST(test_compat_lzma) -DEFINE_TEST(test_compat_lzop) -DEFINE_TEST(test_compat_mac) -DEFINE_TEST(test_compat_perl_archive_tar) -DEFINE_TEST(test_compat_plexus_archiver_tar) -DEFINE_TEST(test_compat_solaris_pax_sparse) -DEFINE_TEST(test_compat_solaris_tar_acl) -DEFINE_TEST(test_compat_star_acl_posix1e) -DEFINE_TEST(test_compat_star_acl_nfs4) -DEFINE_TEST(test_compat_tar_directory) -DEFINE_TEST(test_compat_tar_hardlink) -DEFINE_TEST(test_compat_uudecode) -DEFINE_TEST(test_compat_uudecode_large) -DEFINE_TEST(test_compat_xz) -DEFINE_TEST(test_compat_zip_1) -DEFINE_TEST(test_compat_zip_2) -DEFINE_TEST(test_compat_zip_3) -DEFINE_TEST(test_compat_zip_4) -DEFINE_TEST(test_compat_zip_5) -DEFINE_TEST(test_compat_zip_6) -DEFINE_TEST(test_compat_zip_7) -DEFINE_TEST(test_compat_zip_8) -DEFINE_TEST(test_compat_zstd) -DEFINE_TEST(test_empty_write) -DEFINE_TEST(test_entry) -DEFINE_TEST(test_entry_strmode) -DEFINE_TEST(test_extattr_freebsd) -DEFINE_TEST(test_filter_count) -DEFINE_TEST(test_fuzz_ar) -DEFINE_TEST(test_fuzz_cab) -DEFINE_TEST(test_fuzz_cpio) -DEFINE_TEST(test_fuzz_iso9660) -DEFINE_TEST(test_fuzz_lzh) -DEFINE_TEST(test_fuzz_mtree) -DEFINE_TEST(test_fuzz_rar) -DEFINE_TEST(test_fuzz_tar) -DEFINE_TEST(test_fuzz_zip) -DEFINE_TEST(test_gnutar_filename_encoding_UTF8_CP866) -DEFINE_TEST(test_gnutar_filename_encoding_KOI8R_UTF8) -DEFINE_TEST(test_gnutar_filename_encoding_KOI8R_CP866) -DEFINE_TEST(test_gnutar_filename_encoding_CP1251_UTF8) -DEFINE_TEST(test_gnutar_filename_encoding_ru_RU_CP1251) -DEFINE_TEST(test_gnutar_filename_encoding_Russian_Russia) -DEFINE_TEST(test_gnutar_filename_encoding_EUCJP_UTF8) -DEFINE_TEST(test_gnutar_filename_encoding_EUCJP_CP932) -DEFINE_TEST(test_gnutar_filename_encoding_CP932_UTF8) -DEFINE_TEST(test_link_resolver) -DEFINE_TEST(test_open_failure) -DEFINE_TEST(test_open_fd) -DEFINE_TEST(test_open_file) -DEFINE_TEST(test_open_filename) -DEFINE_TEST(test_pax_filename_encoding_KOI8R) -DEFINE_TEST(test_pax_filename_encoding_CP1251) -DEFINE_TEST(test_pax_filename_encoding_EUCJP) -DEFINE_TEST(test_pax_filename_encoding_CP932) -DEFINE_TEST(test_pax_filename_encoding_KOI8R_BINARY) -DEFINE_TEST(test_pax_filename_encoding_KOI8R_CP1251) -DEFINE_TEST(test_pax_filename_encoding) -DEFINE_TEST(test_pax_xattr_header) -DEFINE_TEST(test_read_data_large) -DEFINE_TEST(test_read_disk) -DEFINE_TEST(test_read_disk_directory_traversals) -DEFINE_TEST(test_read_disk_entry_from_file) -DEFINE_TEST(test_read_extract) -DEFINE_TEST(test_read_file_nonexistent) -DEFINE_TEST(test_read_filter_compress_truncated) -DEFINE_TEST(test_read_filter_compress_empty2) -DEFINE_TEST(test_read_filter_compress_invalid) -DEFINE_TEST(test_read_filter_grzip) -DEFINE_TEST(test_read_filter_lrzip) -DEFINE_TEST(test_read_filter_lzop) -DEFINE_TEST(test_read_filter_lzop_multiple_parts) -DEFINE_TEST(test_read_filter_program) -DEFINE_TEST(test_read_filter_program_signature) -DEFINE_TEST(test_read_filter_uudecode) -DEFINE_TEST(test_read_filter_uudecode_base64) -DEFINE_TEST(test_read_filter_uudecode_raw) -DEFINE_TEST(test_read_filter_uudecode_base64_raw) -DEFINE_TEST(test_read_format_7zip) -DEFINE_TEST(test_read_format_7zip_bzip2) -DEFINE_TEST(test_read_format_7zip_from_fd) -DEFINE_TEST(test_read_format_7zip_copy) -DEFINE_TEST(test_read_format_7zip_deflate) -DEFINE_TEST(test_read_format_7zip_zstd) -DEFINE_TEST(test_read_format_7zip_zstd_solid) -DEFINE_TEST(test_read_format_7zip_zstd_bcj) -DEFINE_TEST(test_read_format_7zip_zstd_nobcj) -DEFINE_TEST(test_read_format_7zip_empty) -DEFINE_TEST(test_read_format_7zip_lzma1) -DEFINE_TEST(test_read_format_7zip_lzma2) -DEFINE_TEST(test_read_format_7zip_zstd_arm) -DEFINE_TEST(test_read_format_7zip_lzma2_arm) -DEFINE_TEST(test_read_format_7zip_ppmd) -DEFINE_TEST(test_read_format_7zip_lzma2_arm64) -DEFINE_TEST(test_read_format_7zip_deflate_arm64) -DEFINE_TEST(test_read_format_7zip_win_attrib) -DEFINE_TEST(test_read_format_7zip_encryption_data) -DEFINE_TEST(test_read_format_7zip_encryption_header) -DEFINE_TEST(test_read_format_7zip_encryption_partially) -DEFINE_TEST(test_read_format_7zip_malformed) -DEFINE_TEST(test_read_format_7zip_packinfo_digests) -DEFINE_TEST(test_read_format_ar) -DEFINE_TEST(test_read_format_cab) -DEFINE_TEST(test_read_format_cab_filename) -DEFINE_TEST(test_read_format_cpio_afio) -DEFINE_TEST(test_read_format_cpio_bin_be) -DEFINE_TEST(test_read_format_cpio_bin_bz2) -DEFINE_TEST(test_read_format_cpio_bin) -DEFINE_TEST(test_read_format_cpio_bin_gz) -DEFINE_TEST(test_read_format_cpio_bin_le) -DEFINE_TEST(test_read_format_cpio_bin_lzip) -DEFINE_TEST(test_read_format_cpio_bin_lzma) -DEFINE_TEST(test_read_format_cpio_bin_xz) -DEFINE_TEST(test_read_format_cpio_bin_Z) -DEFINE_TEST(test_read_format_cpio_filename_eucJP_UTF8) -DEFINE_TEST(test_read_format_cpio_filename_UTF8_eucJP) -DEFINE_TEST(test_read_format_cpio_filename_UTF8_UTF8_jp) -DEFINE_TEST(test_read_format_cpio_filename_CP866_KOI8R) -DEFINE_TEST(test_read_format_cpio_filename_CP866_UTF8) -DEFINE_TEST(test_read_format_cpio_filename_KOI8R_CP866) -DEFINE_TEST(test_read_format_cpio_filename_KOI8R_UTF8) -DEFINE_TEST(test_read_format_cpio_filename_UTF8_KOI8R) -DEFINE_TEST(test_read_format_cpio_filename_UTF8_CP866) -DEFINE_TEST(test_read_format_cpio_filename_UTF8_UTF8_ru) -DEFINE_TEST(test_read_format_cpio_filename_eucJP_CP932) -DEFINE_TEST(test_read_format_cpio_filename_UTF8_CP932) -DEFINE_TEST(test_read_format_cpio_filename_CP866_CP1251) -DEFINE_TEST(test_read_format_cpio_filename_CP866_CP1251_win) -DEFINE_TEST(test_read_format_cpio_filename_KOI8R_CP1251) -DEFINE_TEST(test_read_format_cpio_filename_UTF8_CP1251) -DEFINE_TEST(test_read_format_cpio_odc) -DEFINE_TEST(test_read_format_cpio_svr4_bzip2_rpm) -DEFINE_TEST(test_read_format_cpio_svr4c_Z) -DEFINE_TEST(test_read_format_cpio_svr4_gzip) -DEFINE_TEST(test_read_format_cpio_svr4_gzip_rpm) -DEFINE_TEST(test_read_format_empty) -DEFINE_TEST(test_read_format_gtar_filename_eucJP_UTF8) -DEFINE_TEST(test_read_format_gtar_filename_CP866_KOI8R) -DEFINE_TEST(test_read_format_gtar_filename_CP866_UTF8) -DEFINE_TEST(test_read_format_gtar_filename_KOI8R_CP866) -DEFINE_TEST(test_read_format_gtar_filename_KOI8R_UTF8) -DEFINE_TEST(test_read_format_gtar_filename_eucJP_CP932) -DEFINE_TEST(test_read_format_gtar_filename_CP866_CP1251) -DEFINE_TEST(test_read_format_gtar_filename_CP866_CP1251_win) -DEFINE_TEST(test_read_format_gtar_filename_KOI8R_CP1251) -DEFINE_TEST(test_read_format_gtar_gz) -DEFINE_TEST(test_read_format_gtar_lzma) -DEFINE_TEST(test_read_format_gtar_sparse) -DEFINE_TEST(test_read_format_gtar_sparse_skip_entry) -DEFINE_TEST(test_read_format_isojoliet_bz2) -DEFINE_TEST(test_read_format_isojoliet_long) -DEFINE_TEST(test_read_format_isojoliet_rr) -DEFINE_TEST(test_read_format_isojoliet_versioned) -DEFINE_TEST(test_read_format_iso_multi_extent) -DEFINE_TEST(test_read_format_isorr_bz2) -DEFINE_TEST(test_read_format_isorr_ce) -DEFINE_TEST(test_read_format_isorr_new_bz2) -DEFINE_TEST(test_read_format_isorr_rr_moved) -DEFINE_TEST(test_read_format_iso_xorriso) -DEFINE_TEST(test_read_format_iso_Z) -DEFINE_TEST(test_read_format_isozisofs_bz2) -DEFINE_TEST(test_read_format_lha_bugfix_0) -DEFINE_TEST(test_read_format_lha) -DEFINE_TEST(test_read_format_lha_filename) -DEFINE_TEST(test_read_format_lha_filename_UTF16) -DEFINE_TEST(test_read_format_mtree) -DEFINE_TEST(test_read_format_mtree_filenames_only) -DEFINE_TEST(test_read_format_mtree_nochange) -DEFINE_TEST(test_read_format_mtree_nomagic_v1_form) -DEFINE_TEST(test_read_format_mtree_nomagic_v2_form) -DEFINE_TEST(test_read_format_mtree_nomagic_v2_netbsd_form) -DEFINE_TEST(test_read_format_mtree_nonexistent_contents_file) -DEFINE_TEST(test_read_format_mtree_noprint) -DEFINE_TEST(test_read_format_mtree_tab) -DEFINE_TEST(test_read_format_mtree_crash747) -DEFINE_TEST(test_read_format_pax_bz2) -DEFINE_TEST(test_read_format_rar5_set_format) -DEFINE_TEST(test_read_format_rar5_stored) -DEFINE_TEST(test_read_format_rar5_compressed) -DEFINE_TEST(test_read_format_rar5_multiple_files) -DEFINE_TEST(test_read_format_rar5_multiple_files_solid) -DEFINE_TEST(test_read_format_rar5_multiarchive_skip_all) -DEFINE_TEST(test_read_format_rar5_multiarchive_skip_all_but_first) -DEFINE_TEST(test_read_format_rar5_multiarchive_skip_all_but_second) -DEFINE_TEST(test_read_format_rar5_blake2) -DEFINE_TEST(test_read_format_rar5_arm_filter) -DEFINE_TEST(test_read_format_rar5_stored_skip_all) -DEFINE_TEST(test_read_format_rar5_stored_skip_in_part) -DEFINE_TEST(test_read_format_rar5_stored_skip_all_but_first) -DEFINE_TEST(test_read_format_rar5_stored_skip_all_in_part) -DEFINE_TEST(test_read_format_rar5_multiarchive_solid_extr_all) -DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip_all) -DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip_all_but_first) -DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip_all_but_scnd) -DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip_all_but_third) -DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip_all_but_last) -DEFINE_TEST(test_read_format_rar5_solid_skip_all) -DEFINE_TEST(test_read_format_rar5_solid_skip_all_but_first) -DEFINE_TEST(test_read_format_rar5_solid_skip_all_but_second) -DEFINE_TEST(test_read_format_rar5_solid_skip_all_but_last) -DEFINE_TEST(test_read_format_rar5_extract_win32) -DEFINE_TEST(test_read_format_rar5_block_by_block) -DEFINE_TEST(test_read_format_rar5_owner) -DEFINE_TEST(test_read_format_rar5_symlink) -DEFINE_TEST(test_read_format_rar5_hardlink) -DEFINE_TEST(test_read_format_rar5_extra_field_version) -DEFINE_TEST(test_read_format_rar5_readtables_overflow) -DEFINE_TEST(test_read_format_rar5_leftshift1) -DEFINE_TEST(test_read_format_rar5_leftshift2) -DEFINE_TEST(test_read_format_rar5_truncated_huff) -DEFINE_TEST(test_read_format_rar5_invalid_dict_reference) -DEFINE_TEST(test_read_format_rar5_distance_overflow) -DEFINE_TEST(test_read_format_rar5_nonempty_dir_stream) -DEFINE_TEST(test_read_format_rar5_fileattr) -DEFINE_TEST(test_read_format_rar5_different_window_size) -DEFINE_TEST(test_read_format_rar5_window_buf_and_size_desync) -DEFINE_TEST(test_read_format_rar5_arm_filter_on_window_boundary) -DEFINE_TEST(test_read_format_rar5_different_solid_window_size) -DEFINE_TEST(test_read_format_rar5_different_winsize_on_merge) -DEFINE_TEST(test_read_format_rar5_block_size_is_too_small) -DEFINE_TEST(test_read_format_rar5_sfx) -DEFINE_TEST(test_read_format_rar5_decode_number_out_of_bounds_read) -DEFINE_TEST(test_read_format_rar5_bad_window_size_in_multiarchive_file) -DEFINE_TEST(test_read_format_rar5_read_data_block_uninitialized_offset) -DEFINE_TEST(test_read_format_rar_set_format) -DEFINE_TEST(test_read_format_rar_basic) -DEFINE_TEST(test_read_format_rar_subblock) -DEFINE_TEST(test_read_format_rar_noeof) -DEFINE_TEST(test_read_format_rar_unicode_UTF8) -DEFINE_TEST(test_read_format_rar_unicode_CP932) -DEFINE_TEST(test_read_format_rar_compress_normal) -DEFINE_TEST(test_read_format_rar_multi_lzss_blocks) -DEFINE_TEST(test_read_format_rar_compress_best) -DEFINE_TEST(test_read_format_rar_ppmd_lzss_conversion) -DEFINE_TEST(test_read_format_rar_binary) -DEFINE_TEST(test_read_format_rar_windows) -DEFINE_TEST(test_read_format_rar_multivolume) -DEFINE_TEST(test_read_format_rar_multivolume_skip) -DEFINE_TEST(test_read_format_rar_sfx) -DEFINE_TEST(test_read_format_rar_multivolume_stored_file) -DEFINE_TEST(test_read_format_rar_multivolume_stored_file_skip) -DEFINE_TEST(test_read_format_rar_multivolume_seek_data) -DEFINE_TEST(test_read_format_rar_multivolume_seek_multiple_files) -DEFINE_TEST(test_read_format_rar_multivolume_uncompressed_files) -DEFINE_TEST(test_read_format_rar_ppmd_use_after_free) -DEFINE_TEST(test_read_format_rar_ppmd_use_after_free2) -DEFINE_TEST(test_read_format_rar_encryption_data) -DEFINE_TEST(test_read_format_rar_encryption_header) -DEFINE_TEST(test_read_format_rar_encryption_partially) -DEFINE_TEST(test_read_format_rar_filter) -DEFINE_TEST(test_read_format_rar_invalid1) -DEFINE_TEST(test_read_format_raw) -DEFINE_TEST(test_read_format_tar) -DEFINE_TEST(test_read_format_tar_concatenated) -DEFINE_TEST(test_read_format_tar_empty_filename) -DEFINE_TEST(test_read_format_tar_empty_pax) -DEFINE_TEST(test_read_format_tar_empty_with_gnulabel) -DEFINE_TEST(test_read_format_tar_filename) -DEFINE_TEST(test_read_format_tar_invalid_pax_size) -DEFINE_TEST(test_read_format_tbz) -DEFINE_TEST(test_read_format_tgz) -DEFINE_TEST(test_read_format_tlz) -DEFINE_TEST(test_read_format_txz) -DEFINE_TEST(test_read_format_tz) -DEFINE_TEST(test_read_format_ustar_filename) -DEFINE_TEST(test_read_format_warc) -DEFINE_TEST(test_read_format_xar) -DEFINE_TEST(test_read_format_zip_utf8_paths) -DEFINE_TEST(test_read_format_zip) -DEFINE_TEST(test_read_format_zip_ppmd_one_file) -DEFINE_TEST(test_read_format_zip_ppmd_one_file_blockread) -DEFINE_TEST(test_read_format_zip_ppmd_multi) -DEFINE_TEST(test_read_format_zip_ppmd_multi_blockread) -DEFINE_TEST(test_read_format_zip_lzma_one_file) -DEFINE_TEST(test_read_format_zip_lzma_one_file_blockread) -DEFINE_TEST(test_read_format_zip_lzma_multi) -DEFINE_TEST(test_read_format_zip_lzma_multi_blockread) -DEFINE_TEST(test_read_format_zip_bzip2_one_file) -DEFINE_TEST(test_read_format_zip_bzip2_one_file_blockread) -DEFINE_TEST(test_read_format_zip_bzip2_multi) -DEFINE_TEST(test_read_format_zip_bzip2_multi_blockread) -DEFINE_TEST(test_read_format_zip_zstd_one_file) -DEFINE_TEST(test_read_format_zip_zstd_one_file_blockread) -DEFINE_TEST(test_read_format_zip_zstd_multi) -DEFINE_TEST(test_read_format_zip_zstd_multi_blockread) -DEFINE_TEST(test_read_format_zip_xz_multi) -DEFINE_TEST(test_read_format_zip_xz_multi_blockread) -DEFINE_TEST(test_read_format_zip_ppmd8_crash_1) -DEFINE_TEST(test_read_format_zip_bz2_hang_on_invalid) -DEFINE_TEST(test_read_format_zip_ppmd8_crash_2) -DEFINE_TEST(test_read_format_zip_lzma_alone_leak) -DEFINE_TEST(test_read_format_zip_lzma_stream_end) -DEFINE_TEST(test_read_format_zip_lzma_stream_end_blockread) -DEFINE_TEST(test_read_format_zip_7z_lzma) -DEFINE_TEST(test_read_format_zip_7z_deflate) -DEFINE_TEST(test_read_format_zip_comment_stored) -DEFINE_TEST(test_read_format_zip_encryption_data) -DEFINE_TEST(test_read_format_zip_encryption_header) -DEFINE_TEST(test_read_format_zip_encryption_partially) -DEFINE_TEST(test_read_format_zip_extra_padding) -DEFINE_TEST(test_read_format_zip_filename_CP932_eucJP) -DEFINE_TEST(test_read_format_zip_filename_CP932_UTF8) -DEFINE_TEST(test_read_format_zip_filename_UTF8_eucJP) -DEFINE_TEST(test_read_format_zip_filename_UTF8_UTF8) -DEFINE_TEST(test_read_format_zip_filename_CP866_KOI8R) -DEFINE_TEST(test_read_format_zip_filename_CP866_UTF8) -DEFINE_TEST(test_read_format_zip_filename_KOI8R_CP866) -DEFINE_TEST(test_read_format_zip_filename_KOI8R_UTF8) -DEFINE_TEST(test_read_format_zip_filename_UTF8_KOI8R) -DEFINE_TEST(test_read_format_zip_filename_UTF8_CP866) -DEFINE_TEST(test_read_format_zip_filename_UTF8_UTF8_ru) -DEFINE_TEST(test_read_format_zip_filename_CP932_CP932) -DEFINE_TEST(test_read_format_zip_filename_UTF8_CP932) -DEFINE_TEST(test_read_format_zip_filename_CP866_CP1251) -DEFINE_TEST(test_read_format_zip_filename_CP866_CP1251_win) -DEFINE_TEST(test_read_format_zip_filename_KOI8R_CP1251) -DEFINE_TEST(test_read_format_zip_filename_UTF8_CP1251) -DEFINE_TEST(test_read_format_zip_filename_KOI8R_UTF8_2) -DEFINE_TEST(test_read_format_zip_high_compression) -DEFINE_TEST(test_read_format_zip_high_compression2) -DEFINE_TEST(test_read_format_zip_jar) -DEFINE_TEST(test_read_format_zip_mac_metadata) -DEFINE_TEST(test_read_format_zip_malformed) -DEFINE_TEST(test_read_format_zip_msdos) -DEFINE_TEST(test_read_format_zip_nested) -DEFINE_TEST(test_read_format_zip_nofiletype) -DEFINE_TEST(test_read_format_zip_padded1) -DEFINE_TEST(test_read_format_zip_padded2) -DEFINE_TEST(test_read_format_zip_padded3) -DEFINE_TEST(test_read_format_zip_sfx) -DEFINE_TEST(test_read_format_zip_traditional_encryption_data) -DEFINE_TEST(test_read_format_zip_winzip_aes128) -DEFINE_TEST(test_read_format_zip_winzip_aes256) -DEFINE_TEST(test_read_format_zip_winzip_aes256_stored) -DEFINE_TEST(test_read_format_zip_winzip_aes256_large) -DEFINE_TEST(test_read_format_zip_with_invalid_traditional_eocd) -DEFINE_TEST(test_read_format_zip_zip64a) -DEFINE_TEST(test_read_format_zip_zip64b) -DEFINE_TEST(test_read_large) -DEFINE_TEST(test_read_pax_truncated) -DEFINE_TEST(test_read_pax_xattr_rht_security_selinux) -DEFINE_TEST(test_read_pax_xattr_schily) -DEFINE_TEST(test_read_position) -DEFINE_TEST(test_read_set_format) -DEFINE_TEST(test_read_set_wrong_format) -DEFINE_TEST(test_read_append_filter) -DEFINE_TEST(test_read_append_wrong_filter) -DEFINE_TEST(test_read_append_filter_program) -DEFINE_TEST(test_read_append_filter_wrong_program) -DEFINE_TEST(test_read_too_many_filters) -DEFINE_TEST(test_read_truncated) -DEFINE_TEST(test_read_truncated_filter_bzip2) -DEFINE_TEST(test_read_truncated_filter_compress) -DEFINE_TEST(test_read_truncated_filter_gzip) -DEFINE_TEST(test_read_truncated_filter_lzip) -DEFINE_TEST(test_read_truncated_filter_lzma) -DEFINE_TEST(test_read_truncated_filter_lzop) -DEFINE_TEST(test_read_truncated_filter_xz) -DEFINE_TEST(test_short_writes) -DEFINE_TEST(test_sparse_basic) -DEFINE_TEST(test_fully_sparse_files) -DEFINE_TEST(test_tar_filenames) -DEFINE_TEST(test_tar_large) -DEFINE_TEST(test_ustar_filename_encoding_UTF8_CP866) -DEFINE_TEST(test_ustar_filename_encoding_KOI8R_UTF8) -DEFINE_TEST(test_ustar_filename_encoding_KOI8R_CP866) -DEFINE_TEST(test_ustar_filename_encoding_CP1251_UTF8) -DEFINE_TEST(test_ustar_filename_encoding_ru_RU_CP1251) -DEFINE_TEST(test_ustar_filename_encoding_Russian_Russia) -DEFINE_TEST(test_ustar_filename_encoding_EUCJP_UTF8) -DEFINE_TEST(test_ustar_filename_encoding_EUCJP_CP932) -DEFINE_TEST(test_ustar_filename_encoding_CP932_UTF8) -DEFINE_TEST(test_ustar_filenames) -DEFINE_TEST(test_warn_missing_hardlink_target) -DEFINE_TEST(test_write_disk_appledouble) -DEFINE_TEST(test_write_disk) -DEFINE_TEST(test_write_disk_failures) -DEFINE_TEST(test_write_disk_fixup) -DEFINE_TEST(test_write_disk_hardlink) -DEFINE_TEST(test_write_disk_hfs_compression) -DEFINE_TEST(test_write_disk_lookup) -DEFINE_TEST(test_write_disk_mac_metadata) -DEFINE_TEST(test_write_disk_no_hfs_compression) -DEFINE_TEST(test_write_disk_perms) -DEFINE_TEST(test_write_disk_secure744) -DEFINE_TEST(test_write_disk_secure745) -DEFINE_TEST(test_write_disk_secure746a) -DEFINE_TEST(test_write_disk_secure746b) -DEFINE_TEST(test_write_disk_secure) -DEFINE_TEST(test_write_disk_sparse) -DEFINE_TEST(test_write_disk_symlink) -DEFINE_TEST(test_write_disk_times) -DEFINE_TEST(test_write_filter_b64encode) -DEFINE_TEST(test_write_filter_bzip2) -DEFINE_TEST(test_write_filter_compress) -DEFINE_TEST(test_write_filter_gzip) -DEFINE_TEST(test_write_filter_gzip_timestamp) -DEFINE_TEST(test_write_filter_lrzip) -DEFINE_TEST(test_write_filter_lz4) -DEFINE_TEST(test_write_filter_lz4_disable_stream_checksum) -DEFINE_TEST(test_write_filter_lz4_enable_block_checksum) -DEFINE_TEST(test_write_filter_lz4_block_size_4) -DEFINE_TEST(test_write_filter_lz4_block_size_5) -DEFINE_TEST(test_write_filter_lz4_block_size_6) -DEFINE_TEST(test_write_filter_lz4_block_dependence) -DEFINE_TEST(test_write_filter_lzip) -DEFINE_TEST(test_write_filter_lzma) -DEFINE_TEST(test_write_filter_lzop) -DEFINE_TEST(test_write_filter_program) -DEFINE_TEST(test_write_filter_uuencode) -DEFINE_TEST(test_write_filter_xz) -DEFINE_TEST(test_write_filter_zstd) -DEFINE_TEST(test_write_format_7zip) -DEFINE_TEST(test_write_format_7zip_basic_bzip2) -DEFINE_TEST(test_write_format_7zip_basic_copy) -DEFINE_TEST(test_write_format_7zip_basic_deflate) -DEFINE_TEST(test_write_format_7zip_basic_lzma1) -DEFINE_TEST(test_write_format_7zip_basic_lzma2) -DEFINE_TEST(test_write_format_7zip_basic_ppmd) -DEFINE_TEST(test_write_format_7zip_empty_archive) -DEFINE_TEST(test_write_format_7zip_empty_files) -DEFINE_TEST(test_write_format_7zip_large_bzip2) -DEFINE_TEST(test_write_format_7zip_large_copy) -DEFINE_TEST(test_write_format_7zip_large_deflate) -DEFINE_TEST(test_write_format_7zip_large_lzma1) -DEFINE_TEST(test_write_format_7zip_large_lzma2) -DEFINE_TEST(test_write_format_7zip_large_ppmd) -DEFINE_TEST(test_write_format_ar) -DEFINE_TEST(test_write_format_cpio) -DEFINE_TEST(test_write_format_cpio_empty) -DEFINE_TEST(test_write_format_cpio_newc) -DEFINE_TEST(test_write_format_cpio_odc) -DEFINE_TEST(test_write_format_gnutar) -DEFINE_TEST(test_write_format_gnutar_filenames) -DEFINE_TEST(test_write_format_gnutar_linknames) -DEFINE_TEST(test_write_format_iso9660_boot) -DEFINE_TEST(test_write_format_iso9660) -DEFINE_TEST(test_write_format_iso9660_empty) -DEFINE_TEST(test_write_format_iso9660_filename) -DEFINE_TEST(test_write_format_iso9660_zisofs) -DEFINE_TEST(test_write_format_mtree_absolute_path) -DEFINE_TEST(test_write_format_mtree) -DEFINE_TEST(test_write_format_mtree_no_leading_dotslash) -DEFINE_TEST(test_write_format_mtree_classic) -DEFINE_TEST(test_write_format_mtree_classic_indent) -DEFINE_TEST(test_write_format_mtree_fflags) -DEFINE_TEST(test_write_format_mtree_no_separator) -DEFINE_TEST(test_write_format_mtree_quoted_filename) -DEFINE_TEST(test_write_format_pax) -DEFINE_TEST(test_write_format_raw_b64) -DEFINE_TEST(test_write_format_raw) -DEFINE_TEST(test_write_format_shar_empty) -DEFINE_TEST(test_write_format_tar) -DEFINE_TEST(test_write_format_tar_empty) -DEFINE_TEST(test_write_format_tar_sparse) -DEFINE_TEST(test_write_format_tar_ustar) -DEFINE_TEST(test_write_format_tar_v7tar) -DEFINE_TEST(test_write_format_warc) -DEFINE_TEST(test_write_format_warc_empty) -DEFINE_TEST(test_write_format_xar) -DEFINE_TEST(test_write_format_xar_empty) -DEFINE_TEST(test_write_format_zip) -DEFINE_TEST(test_write_format_zip64) -DEFINE_TEST(test_write_format_zip_traditional_pkware_encryption) -DEFINE_TEST(test_write_format_zip_winzip_aes128_encryption) -DEFINE_TEST(test_write_format_zip_winzip_aes256_encryption) -DEFINE_TEST(test_write_format_zip_compression_store) -DEFINE_TEST(test_write_format_zip_empty) -DEFINE_TEST(test_write_format_zip_empty_zip64) -DEFINE_TEST(test_write_format_zip_size_unset) -DEFINE_TEST(test_write_format_zip_file) -DEFINE_TEST(test_write_format_zip_file_zip64) -DEFINE_TEST(test_write_format_zip_large) -DEFINE_TEST(test_write_format_zip_zip64_oversize) -DEFINE_TEST(test_write_open_memory) -DEFINE_TEST(test_write_read_format_zip) -DEFINE_TEST(test_write_read_format_zip_improved_streaming) -DEFINE_TEST(test_write_read_format_zip64) -DEFINE_TEST(test_write_read_format_zip64_improved_streaming) -DEFINE_TEST(test_xattr_platform) -DEFINE_TEST(test_zip_filename_encoding_UTF8) -DEFINE_TEST(test_zip_filename_encoding_KOI8R) -DEFINE_TEST(test_zip_filename_encoding_ru_RU_CP1251) -DEFINE_TEST(test_zip_filename_encoding_Russian_Russia) -DEFINE_TEST(test_zip_filename_encoding_EUCJP) -DEFINE_TEST(test_zip_filename_encoding_CP932) diff --git a/thirdparty/libarchive/libarchive/test/read_open_memory.c b/thirdparty/libarchive/libarchive/test/read_open_memory.c deleted file mode 100644 index daa3c3a1f..000000000 --- a/thirdparty/libarchive/libarchive/test/read_open_memory.c +++ /dev/null @@ -1,222 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/read_open_memory.c 191183 2009-04-17 01:06:31Z kientzle $"); - -#include -#include -#include - -/* - * Read an archive from a block of memory. - * - * This is identical to archive_read_open_memory(), except - * that it goes out of its way to be a little bit unpleasant, - * in order to better test the libarchive internals. - */ - -struct read_memory_data { - const unsigned char *start; - const unsigned char *p; - const unsigned char *end; - size_t read_size; - size_t copy_buff_size; - size_t copy_buff_offset; - char *copy_buff; -}; - -static int memory_read_close(struct archive *, void *); -static int memory_read_open(struct archive *, void *); -static int64_t memory_read_seek(struct archive *, void *, int64_t request, int whence); -static int64_t memory_read_skip(struct archive *, void *, int64_t request); -static ssize_t memory_read(struct archive *, void *, const void **buff); -static int read_open_memory_internal(struct archive *a, const void *buff, - size_t size, size_t read_size, int fullapi); - - -int -read_open_memory(struct archive *a, const void *buff, size_t size, size_t read_size) -{ - return read_open_memory_internal(a, buff, size, read_size, 2); -} - -/* - * As above, but don't register any optional part of the API, to verify - * that internals work correctly with just the minimal entry points. - */ -int -read_open_memory_minimal(struct archive *a, const void *buff, size_t size, size_t read_size) -{ - return read_open_memory_internal(a, buff, size, read_size, 1); -} - -/* - * Include a seek callback as well. - */ -int -read_open_memory_seek(struct archive *a, const void *buff, size_t size, size_t read_size) -{ - return read_open_memory_internal(a, buff, size, read_size, 3); -} - -static int -read_open_memory_internal(struct archive *a, const void *buff, - size_t size, size_t read_size, int level) -{ - struct read_memory_data *mine = NULL; - - switch (level) { - case 3: - archive_read_set_seek_callback(a, memory_read_seek); - __LA_FALLTHROUGH; - case 2: - archive_read_set_open_callback(a, memory_read_open); - archive_read_set_skip_callback(a, memory_read_skip); - __LA_FALLTHROUGH; - case 1: - mine = malloc(sizeof(*mine)); - if (mine == NULL) { - archive_set_error(a, ENOMEM, "No memory"); - return (ARCHIVE_FATAL); - } - memset(mine, 0, sizeof(*mine)); - mine->start = mine->p = (const unsigned char *)buff; - mine->end = mine->start + size; - mine->read_size = read_size; - mine->copy_buff_offset = 32; - mine->copy_buff_size = read_size + mine->copy_buff_offset * 2; - mine->copy_buff = malloc(mine->copy_buff_size); - memset(mine->copy_buff, 0xA5, mine->copy_buff_size); - - archive_read_set_read_callback(a, memory_read); - archive_read_set_close_callback(a, memory_read_close); - archive_read_set_callback_data(a, mine); - } - return archive_read_open1(a); -} - -/* - * There's nothing to open. - */ -static int -memory_read_open(struct archive *a, void *client_data) -{ - (void)a; /* UNUSED */ - (void)client_data; /* UNUSED */ - return (ARCHIVE_OK); -} - -/* - * In order to exercise libarchive's internal read-combining logic, - * we deliberately copy data for each read to a separate buffer. - * That way, code that runs off the end of the provided data - * will screw up. - */ -static ssize_t -memory_read(struct archive *a, void *client_data, const void **buff) -{ - struct read_memory_data *mine = (struct read_memory_data *)client_data; - ssize_t size; - - (void)a; /* UNUSED */ - size = mine->end - mine->p; - if (size < 0) { - buff = NULL; - return 0; - } - if ((size_t)size > mine->read_size) - size = mine->read_size; - else - memset(mine->copy_buff, 0xA5, mine->copy_buff_size); - memcpy(mine->copy_buff + mine->copy_buff_offset, mine->p, size); - *buff = mine->copy_buff + mine->copy_buff_offset; - - mine->p += size; - return ((ssize_t)size); -} - -/* - * How mean can a skip() routine be? Let's try to find out. - */ -static int64_t -memory_read_skip(struct archive *a, void *client_data, int64_t skip) -{ - struct read_memory_data *mine = (struct read_memory_data *)client_data; - - (void)a; /* UNUSED */ - /* We can't skip by more than is available. */ - if ((off_t)skip > (off_t)(mine->end - mine->p)) - skip = mine->end - mine->p; - /* Always do small skips by prime amounts. */ - if (skip > 71) - skip = 71; - mine->p += skip; - return (skip); -} - -/* - */ -static int64_t -memory_read_seek(struct archive *a, void *client_data, int64_t offset, int whence) -{ - struct read_memory_data *mine = (struct read_memory_data *)client_data; - - (void)a; /* UNUSED */ - switch (whence) { - case SEEK_SET: - mine->p = mine->start + offset; - break; - case SEEK_END: - mine->p = mine->end + offset; - break; - case SEEK_CUR: - mine->p += offset; - break; - } - if (mine->p < mine->start) { - mine->p = mine->start; - return ARCHIVE_FAILED; - } - if (mine->p > mine->end) { - mine->p = mine->end; - return ARCHIVE_FAILED; - } - return (mine->p - mine->start); -} - -/* - * Close is just cleaning up our one small bit of data. - */ -static int -memory_read_close(struct archive *a, void *client_data) -{ - struct read_memory_data *mine = (struct read_memory_data *)client_data; - (void)a; /* UNUSED */ - if (mine != NULL) - free(mine->copy_buff); - free(mine); - return (ARCHIVE_OK); -} diff --git a/thirdparty/libarchive/libarchive/test/test.h b/thirdparty/libarchive/libarchive/test/test.h deleted file mode 100644 index c0a0c0d87..000000000 --- a/thirdparty/libarchive/libarchive/test/test.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2003-2017 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -/* Every test program should #include "test.h" as the first thing. */ - -#define KNOWNREF "test_compat_gtar_1.tar.uu" -#define ENVBASE "LIBARCHIVE" /* Prefix for environment variables. */ -#undef PROGRAM /* Testing a library, not a program. */ -#define LIBRARY "libarchive" -#define EXTRA_DUMP(x) archive_error_string((struct archive *)(x)) -#define EXTRA_ERRNO(x) archive_errno((struct archive *)(x)) -#define EXTRA_VERSION archive_version_details() - -#if defined(__GNUC__) && (__GNUC__ >= 7) -#define __LA_FALLTHROUGH __attribute__((fallthrough)) -#else -#define __LA_FALLTHROUGH -#endif - -#include "test_common.h" diff --git a/thirdparty/libarchive/libarchive/test/test_acl_nfs4.c b/thirdparty/libarchive/libarchive/test/test_acl_nfs4.c deleted file mode 100644 index fdc019151..000000000 --- a/thirdparty/libarchive/libarchive/test/test_acl_nfs4.c +++ /dev/null @@ -1,208 +0,0 @@ -/*- - * Copyright (c) 2003-2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* - * Exercise the system-independent portion of the ACL support. - * Check that archive_entry objects can save and restore NFS4 ACL data. - * - * This should work on all systems, regardless of whether local - * filesystems support ACLs or not. - */ - -static struct archive_test_acl_t acls1[] = { - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_READ_DATA, - ARCHIVE_ENTRY_ACL_USER, 77, "user77" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_DATA, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_WRITE_DATA, - ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }, -}; - -static struct archive_test_acl_t acls2[] = { - /* An entry for each type. */ - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 0, - ARCHIVE_ENTRY_ACL_USER, 108, "user108" }, - { ARCHIVE_ENTRY_ACL_TYPE_DENY, 0, - ARCHIVE_ENTRY_ACL_USER, 109, "user109" }, - { ARCHIVE_ENTRY_ACL_TYPE_AUDIT, 0, - ARCHIVE_ENTRY_ACL_USER, 110, "user110" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALARM, 0, - ARCHIVE_ENTRY_ACL_USER, 111, "user111" }, - - /* An entry for each permission. */ - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_USER, 112, "user112" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_DATA, - ARCHIVE_ENTRY_ACL_USER, 113, "user113" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, - ARCHIVE_ENTRY_ACL_USER, 114, "user114" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_DATA, - ARCHIVE_ENTRY_ACL_USER, 115, "user115" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_ADD_FILE, - ARCHIVE_ENTRY_ACL_USER, 116, "user116" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_APPEND_DATA, - ARCHIVE_ENTRY_ACL_USER, 117, "user117" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, - ARCHIVE_ENTRY_ACL_USER, 118, "user118" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, - ARCHIVE_ENTRY_ACL_USER, 119, "user119" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, - ARCHIVE_ENTRY_ACL_USER, 120, "user120" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE_CHILD, - ARCHIVE_ENTRY_ACL_USER, 121, "user121" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, - ARCHIVE_ENTRY_ACL_USER, 122, "user122" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, - ARCHIVE_ENTRY_ACL_USER, 123, "user123" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE, - ARCHIVE_ENTRY_ACL_USER, 124, "user124" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ACL, - ARCHIVE_ENTRY_ACL_USER, 125, "user125" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ACL, - ARCHIVE_ENTRY_ACL_USER, 126, "user126" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_OWNER, - ARCHIVE_ENTRY_ACL_USER, 127, "user127" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_USER, 128, "user128" }, - - /* One entry with each inheritance value. */ - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, - ARCHIVE_ENTRY_ACL_USER, 129, "user129" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, - ARCHIVE_ENTRY_ACL_USER, 130, "user130" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, - ARCHIVE_ENTRY_ACL_USER, 131, "user131" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, - ARCHIVE_ENTRY_ACL_USER, 132, "user132" }, - { ARCHIVE_ENTRY_ACL_TYPE_AUDIT, - ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, - ARCHIVE_ENTRY_ACL_USER, 133, "user133" }, - { ARCHIVE_ENTRY_ACL_TYPE_AUDIT, - ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, - ARCHIVE_ENTRY_ACL_USER, 134, "user134" }, - - /* One entry for each qualifier. */ - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_USER, 135, "user135" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_GROUP, 136, "group136" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }, -}; - -/* - * Entries that should be rejected when we attempt to set them - * on an ACL that already has NFS4 entries. - */ -static struct archive_test_acl_t acls_bad[] = { - /* POSIX.1e ACL types */ - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_USER, 78, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_USER, 78, "" }, - - /* POSIX.1e tags */ - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_OTHER, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_MASK, -1, "" }, - - /* POSIX.1e permissions */ - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE, - ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }, -}; - -DEFINE_TEST(test_acl_nfs4) -{ - struct archive_entry *ae; - int i; - - /* Create a simple archive_entry. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_pathname(ae, "file"); - archive_entry_set_mode(ae, S_IFREG | 0777); - - /* Store and read back some basic ACL entries. */ - assertEntrySetAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0])); - - /* Check that entry contains only NFSv4 types */ - assert((archive_entry_acl_types(ae) & - ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) == 0); - assert((archive_entry_acl_types(ae) & - ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0); - - assertEqualInt(4, - archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_NFS4)); - assertEntryCompareAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]), - ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0); - - /* A more extensive set of ACLs. */ - assertEntrySetAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0])); - assertEqualInt(32, - archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_NFS4)); - assertEntryCompareAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]), - ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0); - - /* - * Check that clearing ACLs gets rid of them all by repeating - * the first test. - */ - assertEntrySetAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0])); - failure("Basic ACLs shouldn't be stored as extended ACLs"); - assertEqualInt(4, - archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_NFS4)); - - /* - * Different types of malformed ACL entries that should - * fail when added to existing NFS4 ACLs. - */ - assertEntrySetAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0])); - for (i = 0; i < (int)(sizeof(acls_bad)/sizeof(acls_bad[0])); ++i) { - struct archive_test_acl_t *p = &acls_bad[i]; - failure("Malformed ACL test #%d", i); - assertEqualInt(ARCHIVE_FAILED, - archive_entry_acl_add_entry(ae, - p->type, p->permset, p->tag, p->qual, p->name)); - failure("Malformed ACL test #%d", i); - assertEqualInt(32, - archive_entry_acl_reset(ae, - ARCHIVE_ENTRY_ACL_TYPE_NFS4)); - } - archive_entry_free(ae); -} diff --git a/thirdparty/libarchive/libarchive/test/test_acl_pax.c b/thirdparty/libarchive/libarchive/test/test_acl_pax.c deleted file mode 100644 index 8566f55a5..000000000 --- a/thirdparty/libarchive/libarchive/test/test_acl_pax.c +++ /dev/null @@ -1,415 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2016 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* - * Exercise the system-independent portion of the ACL support. - * Check that pax archive can save and restore POSIX.1e ACL data. - * - * This should work on all systems, regardless of whether local - * filesystems support ACLs or not. - */ - -static unsigned char buff[16384]; - -static struct archive_test_acl_t acls0[] = { - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_WRITE, - ARCHIVE_ENTRY_ACL_OTHER, 0, "" }, -}; - -static struct archive_test_acl_t acls1[] = { - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_USER, 77, "user77" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_WRITE, - ARCHIVE_ENTRY_ACL_OTHER, -1, "" }, -}; - -static struct archive_test_acl_t acls2[] = { - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE | ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_USER, 77, "user77" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0, - ARCHIVE_ENTRY_ACL_USER, 78, "user78" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0007, - ARCHIVE_ENTRY_ACL_GROUP, 78, "group78" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_OTHER, -1, "" }, -}; - -static struct archive_test_acl_t acls3[] = { - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_WRITE_DATA | - ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_APPEND_DATA | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_WRITE_ACL | - ARCHIVE_ENTRY_ACL_WRITE_OWNER | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_WRITE_DATA | - ARCHIVE_ENTRY_ACL_APPEND_DATA | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" }, -}; - -static struct archive_test_acl_t acls4[] = { - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_WRITE_DATA | - ARCHIVE_ENTRY_ACL_APPEND_DATA | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_WRITE_ACL | - ARCHIVE_ENTRY_ACL_WRITE_OWNER | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE | - ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, - ARCHIVE_ENTRY_ACL_USER, 77, "user77" }, - { ARCHIVE_ENTRY_ACL_TYPE_DENY, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_WRITE_DATA | - ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_USER, 78, "user78" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_WRITE_DATA | - ARCHIVE_ENTRY_ACL_APPEND_DATA | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_DENY, - ARCHIVE_ENTRY_ACL_WRITE_DATA | - ARCHIVE_ENTRY_ACL_APPEND_DATA | - ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_WRITE_ACL | - ARCHIVE_ENTRY_ACL_WRITE_OWNER, - ARCHIVE_ENTRY_ACL_GROUP, 78, "group78" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" }, -}; - -static struct archive_test_acl_t acls5[] = { - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_WRITE_DATA | - ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_APPEND_DATA | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_WRITE_ACL | - ARCHIVE_ENTRY_ACL_WRITE_OWNER | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_WRITE_DATA | - ARCHIVE_ENTRY_ACL_APPEND_DATA | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_WRITE_OWNER | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_USER, 77, "user77" }, - { ARCHIVE_ENTRY_ACL_TYPE_AUDIT, - ARCHIVE_ENTRY_ACL_WRITE_DATA | - ARCHIVE_ENTRY_ACL_APPEND_DATA | - ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, - ARCHIVE_ENTRY_ACL_USER, 77, "user77" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_WRITE_DATA | - ARCHIVE_ENTRY_ACL_APPEND_DATA | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALARM, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, - ARCHIVE_ENTRY_ACL_GROUP, 78, "group78" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" }, -}; - -DEFINE_TEST(test_acl_pax_posix1e) -{ - struct archive *a; - struct archive_entry *ae; - size_t used; - FILE *f; - void *reference; - size_t reference_size; - - /* Write an archive to memory. */ - assert(NULL != (a = archive_write_new())); - assertA(0 == archive_write_set_format_pax(a)); - assertA(0 == archive_write_add_filter_none(a)); - assertA(0 == archive_write_set_bytes_per_block(a, 1)); - assertA(0 == archive_write_set_bytes_in_last_block(a, 1)); - assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used)); - - /* Write a series of files to the archive with different ACL info. */ - - /* Create a simple archive_entry. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_pathname(ae, "file"); - archive_entry_set_mode(ae, S_IFREG | 0777); - - /* Basic owner/owning group should just update mode bits. */ - assertEntrySetAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0])); - assertA(0 == archive_write_header(a, ae)); - - /* With any extended ACL entry, we should read back a full set. */ - assertEntrySetAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0])); - assertA(0 == archive_write_header(a, ae)); - - /* A more extensive set of ACLs. */ - assertEntrySetAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0])); - assertA(0 == archive_write_header(a, ae)); - - /* - * Check that clearing ACLs gets rid of them all by repeating - * the first test. - */ - assertEntrySetAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0])); - assertA(0 == archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Write out the data we generated to a file for manual inspection. */ - assert(NULL != (f = fopen("testout", "wb"))); - assertEqualInt(used, (size_t)fwrite(buff, 1, (unsigned int)used, f)); - fclose(f); - - /* Write out the reference data to a file for manual inspection. */ - extract_reference_file("test_acl_pax_posix1e.tar"); - reference = slurpfile(&reference_size, "test_acl_pax_posix1e.tar"); - - /* Assert that the generated data matches the built-in reference data.*/ - failure("Generated pax archive does not match reference; compare 'testout' to 'test_acl_pax_posix1e.tar' reference file."); - assertEqualMem(buff, reference, reference_size); - failure("Generated pax archive does not match reference; compare 'testout' to 'test_acl_pax_posix1e.tar' reference file."); - assertEqualInt((int)used, reference_size); - free(reference); - - /* Read back each entry and check that the ACL data is right. */ - assert(NULL != (a = archive_read_new())); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_open_memory(a, buff, used)); - - /* First item has no ACLs */ - assertA(0 == archive_read_next_header(a, &ae)); - failure("Basic ACLs shouldn't be stored as extended ACLs"); - assert(0 == archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); - failure("Basic ACLs should set mode to 0142, not %04o", - archive_entry_mode(ae)&0777); - assert((archive_entry_mode(ae) & 0777) == 0142); - - /* Second item has a few ACLs */ - assertA(0 == archive_read_next_header(a, &ae)); - failure("One extended ACL should flag all ACLs to be returned."); - assert(4 == archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); - assertEntryCompareAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]), - ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0142); - failure("Basic ACLs should set mode to 0142, not %04o", - archive_entry_mode(ae)&0777); - assert((archive_entry_mode(ae) & 0777) == 0142); - - /* Third item has pretty extensive ACLs */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualInt(6, archive_entry_acl_reset(ae, - ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); - assertEntryCompareAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]), - ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0543); - failure("Basic ACLs should set mode to 0543, not %04o", - archive_entry_mode(ae)&0777); - assert((archive_entry_mode(ae) & 0777) == 0543); - - /* Fourth item has no ACLs */ - assertA(0 == archive_read_next_header(a, &ae)); - failure("Basic ACLs shouldn't be stored as extended ACLs"); - assert(0 == archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); - failure("Basic ACLs should set mode to 0142, not %04o", - archive_entry_mode(ae)&0777); - assert((archive_entry_mode(ae) & 0777) == 0142); - - /* Close the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_acl_pax_nfs4) -{ - struct archive *a; - struct archive_entry *ae; - size_t used; - FILE *f; - void *reference; - size_t reference_size; - - /* Write an archive to memory. */ - assert(NULL != (a = archive_write_new())); - assertA(0 == archive_write_set_format_pax(a)); - assertA(0 == archive_write_add_filter_none(a)); - assertA(0 == archive_write_set_bytes_per_block(a, 1)); - assertA(0 == archive_write_set_bytes_in_last_block(a, 1)); - assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used)); - - /* Write a series of files to the archive with different ACL info. */ - - /* Create a simple archive_entry. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_pathname(ae, "file"); - archive_entry_set_mode(ae, S_IFREG | 0777); - - /* NFS4 ACLs mirroring 0754 file mode */ - assertEntrySetAcls(ae, acls3, sizeof(acls3)/sizeof(acls3[0])); - assertA(0 == archive_write_header(a, ae)); - - /* A more extensive set of NFS4 ACLs. */ - assertEntrySetAcls(ae, acls4, sizeof(acls4)/sizeof(acls4[0])); - assertA(0 == archive_write_header(a, ae)); - - /* Set with special (audit, alarm) NFS4 ACLs. */ - assertEntrySetAcls(ae, acls5, sizeof(acls5)/sizeof(acls5[0])); - assertA(0 == archive_write_header(a, ae)); - - archive_entry_free(ae); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Write out the data we generated to a file for manual inspection. */ - assert(NULL != (f = fopen("testout", "wb"))); - assertEqualInt(used, (size_t)fwrite(buff, 1, (unsigned int)used, f)); - fclose(f); - - /* Write out the reference data to a file for manual inspection. */ - extract_reference_file("test_acl_pax_nfs4.tar"); - reference = slurpfile(&reference_size, "test_acl_pax_nfs4.tar"); - - /* Assert that the generated data matches the built-in reference data.*/ - failure("Generated pax archive does not match reference; compare 'testout' to 'test_acl_pax_nfs4.tar' reference file."); - assertEqualMem(buff, reference, reference_size); - failure("Generated pax archive does not match reference; compare 'testout' to 'test_acl_pax_nfs4.tar' reference file."); - assertEqualInt((int)used, reference_size); - free(reference); - - /* Read back each entry and check that the ACL data is right. */ - assert(NULL != (a = archive_read_new())); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_open_memory(a, buff, used)); - - /* First item has NFS4 ACLs mirroring file mode */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualInt(3, archive_entry_acl_reset(ae, - ARCHIVE_ENTRY_ACL_TYPE_ALLOW)); - assertEntryCompareAcls(ae, acls3, sizeof(acls3)/sizeof(acls3[0]), - ARCHIVE_ENTRY_ACL_TYPE_ALLOW, 0); - - /* Second item has has more fine-grained NFS4 ACLs */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualInt(6, archive_entry_acl_reset(ae, - ARCHIVE_ENTRY_ACL_TYPE_NFS4)); - assertEntryCompareAcls(ae, acls4, sizeof(acls4)/sizeof(acls4[0]), - ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0); - - /* Third item has has audit and alarm NFS4 ACLs */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualInt(6, archive_entry_acl_reset(ae, - ARCHIVE_ENTRY_ACL_TYPE_NFS4)); - assertEntryCompareAcls(ae, acls5, sizeof(acls5)/sizeof(acls5[0]), - ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0); - - /* Close the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_acl_pax_nfs4.tar.uu b/thirdparty/libarchive/libarchive/test/test_acl_pax_nfs4.tar.uu deleted file mode 100644 index ffc5cc279..000000000 --- a/thirdparty/libarchive/libarchive/test/test_acl_pax_nfs4.tar.uu +++ /dev/null @@ -1,129 +0,0 @@ -begin 644 test_acl_pax_nfs4.tar -M4&%X2&5A9&5R+V9I;&4````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````#`P,#``````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````!U``````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````````````!U#HZ9&5N>3HW."QG``````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````````````````````!U -M'!A05)78T-O"QG -#endif -#if HAVE_SYS_RICHACL_H -#include -#endif -#if HAVE_MEMBERSHIP_H -#include -#endif - -struct myacl_t { - int type; - int permset; - int tag; - int qual; /* GID or UID of user/group, depending on tag. */ - const char *name; /* Name of user/group, depending on tag. */ -}; - -static struct myacl_t acls_reg[] = { -#if !ARCHIVE_ACL_DARWIN - /* For this test, we need the file owner to be able to read and write the ACL. */ - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_READ_ACL | ARCHIVE_ENTRY_ACL_WRITE_ACL | ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, - ARCHIVE_ENTRY_ACL_USER_OBJ, -1, ""}, -#endif - /* An entry for each type. */ - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_USER, 108, "user108" }, - { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_USER, 109, "user109" }, - - /* An entry for each permission. */ - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_USER, 112, "user112" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_DATA, - ARCHIVE_ENTRY_ACL_USER, 113, "user113" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_DATA, - ARCHIVE_ENTRY_ACL_USER, 115, "user115" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_APPEND_DATA, - ARCHIVE_ENTRY_ACL_USER, 117, "user117" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, - ARCHIVE_ENTRY_ACL_USER, 119, "user119" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, - ARCHIVE_ENTRY_ACL_USER, 120, "user120" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, - ARCHIVE_ENTRY_ACL_USER, 122, "user122" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, - ARCHIVE_ENTRY_ACL_USER, 123, "user123" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE, - ARCHIVE_ENTRY_ACL_USER, 124, "user124" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ACL, - ARCHIVE_ENTRY_ACL_USER, 125, "user125" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ACL, - ARCHIVE_ENTRY_ACL_USER, 126, "user126" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_OWNER, - ARCHIVE_ENTRY_ACL_USER, 127, "user127" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_USER, 128, "user128" }, - - /* One entry for each qualifier. */ - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_USER, 135, "user135" }, -// { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, -// ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_GROUP, 136, "group136" }, -#if !ARCHIVE_ACL_DARWIN - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" } -#else /* MacOS - mode 0654 */ - { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_WRITE_DATA | - ARCHIVE_ENTRY_ACL_APPEND_DATA | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_WRITE_ACL | - ARCHIVE_ENTRY_ACL_WRITE_OWNER | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" } -#endif -}; - -static const int acls_reg_cnt = (int)(sizeof(acls_reg)/sizeof(acls_reg[0])); - -static struct myacl_t acls_dir[] = { - /* For this test, we need to be able to read and write the ACL. */ -#if !ARCHIVE_ACL_DARWIN - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_READ_ACL, - ARCHIVE_ENTRY_ACL_USER_OBJ, -1, ""}, -#endif - - /* An entry for each type. */ - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, - ARCHIVE_ENTRY_ACL_USER, 101, "user101" }, - { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, - ARCHIVE_ENTRY_ACL_USER, 102, "user102" }, - - /* An entry for each permission. */ - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, - ARCHIVE_ENTRY_ACL_USER, 201, "user201" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_ADD_FILE, - ARCHIVE_ENTRY_ACL_USER, 202, "user202" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, - ARCHIVE_ENTRY_ACL_USER, 203, "user203" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, - ARCHIVE_ENTRY_ACL_USER, 204, "user204" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, - ARCHIVE_ENTRY_ACL_USER, 205, "user205" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE_CHILD, - ARCHIVE_ENTRY_ACL_USER, 206, "user206" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, - ARCHIVE_ENTRY_ACL_USER, 207, "user207" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, - ARCHIVE_ENTRY_ACL_USER, 208, "user208" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_DELETE, - ARCHIVE_ENTRY_ACL_USER, 209, "user209" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_ACL, - ARCHIVE_ENTRY_ACL_USER, 210, "user210" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_ACL, - ARCHIVE_ENTRY_ACL_USER, 211, "user211" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_WRITE_OWNER, - ARCHIVE_ENTRY_ACL_USER, 212, "user212" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_USER, 213, "user213" }, - - /* One entry with each inheritance value. */ - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, - ARCHIVE_ENTRY_ACL_USER, 301, "user301" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, - ARCHIVE_ENTRY_ACL_USER, 302, "user302" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT | - ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, - ARCHIVE_ENTRY_ACL_USER, 303, "user303" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT | - ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, - ARCHIVE_ENTRY_ACL_USER, 304, "user304" }, -#if !defined(ARCHIVE_ACL_SUNOS_NFS4) || defined(ACE_INHERITED_ACE) - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, - ARCHIVE_ENTRY_ACL_USER, 305, "user305" }, -#endif - -#if 0 - /* FreeBSD does not support audit entries. */ - { ARCHIVE_ENTRY_ACL_TYPE_AUDIT, - ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, - ARCHIVE_ENTRY_ACL_USER, 401, "user401" }, - { ARCHIVE_ENTRY_ACL_TYPE_AUDIT, - ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, - ARCHIVE_ENTRY_ACL_USER, 402, "user402" }, -#endif - - /* One entry for each qualifier. */ - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, - ARCHIVE_ENTRY_ACL_USER, 501, "user501" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, - ARCHIVE_ENTRY_ACL_GROUP, 502, "group502" }, -#if !ARCHIVE_ACL_DARWIN - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, - ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" } -#else /* MacOS - mode 0654 */ - { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_WRITE_DATA | - ARCHIVE_ENTRY_ACL_APPEND_DATA | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_WRITE_ACL | - ARCHIVE_ENTRY_ACL_WRITE_OWNER | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" } -#endif -}; - -static const int acls_dir_cnt = (int)(sizeof(acls_dir)/sizeof(acls_dir[0])); - -static void -set_acls(struct archive_entry *ae, struct myacl_t *acls, int start, int end) -{ - int i; - - archive_entry_acl_clear(ae); -#if !ARCHIVE_ACL_DARWIN - if (start > 0) { - assertEqualInt(ARCHIVE_OK, - archive_entry_acl_add_entry(ae, - acls[0].type, acls[0].permset, acls[0].tag, - acls[0].qual, acls[0].name)); - } -#endif - for (i = start; i < end; i++) { - assertEqualInt(ARCHIVE_OK, - archive_entry_acl_add_entry(ae, - acls[i].type, acls[i].permset, acls[i].tag, - acls[i].qual, acls[i].name)); - } -} - -static int -#if ARCHIVE_ACL_SUNOS_NFS4 -acl_permset_to_bitmap(uint32_t mask) -#elif ARCHIVE_ACL_LIBRICHACL -acl_permset_to_bitmap(unsigned int mask) -#else -acl_permset_to_bitmap(acl_permset_t opaque_ps) -#endif -{ - static struct { int portable; int machine; } perms[] = { -#ifdef ARCHIVE_ACL_SUNOS_NFS4 /* Solaris NFSv4 ACL permissions */ - {ARCHIVE_ENTRY_ACL_EXECUTE, ACE_EXECUTE}, - {ARCHIVE_ENTRY_ACL_READ_DATA, ACE_READ_DATA}, - {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACE_LIST_DIRECTORY}, - {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACE_WRITE_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_FILE, ACE_ADD_FILE}, - {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACE_APPEND_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACE_ADD_SUBDIRECTORY}, - {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACE_READ_NAMED_ATTRS}, - {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACE_WRITE_NAMED_ATTRS}, - {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACE_DELETE_CHILD}, - {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACE_READ_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACE_WRITE_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_DELETE, ACE_DELETE}, - {ARCHIVE_ENTRY_ACL_READ_ACL, ACE_READ_ACL}, - {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACE_WRITE_ACL}, - {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACE_WRITE_OWNER}, - {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACE_SYNCHRONIZE} -#elif ARCHIVE_ACL_DARWIN /* MacOS NFSv4 ACL permissions */ - {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA}, - {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY}, - {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE}, - {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE}, - {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE}, - {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY}, - {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD}, - {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_EXTATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_EXTATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_SECURITY}, - {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_SECURITY}, - {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_CHANGE_OWNER}, -#if HAVE_DECL_ACL_SYNCHRONIZE - {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE} -#endif -#elif ARCHIVE_ACL_LIBRICHACL - {ARCHIVE_ENTRY_ACL_EXECUTE, RICHACE_EXECUTE}, - {ARCHIVE_ENTRY_ACL_READ_DATA, RICHACE_READ_DATA}, - {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, RICHACE_LIST_DIRECTORY}, - {ARCHIVE_ENTRY_ACL_WRITE_DATA, RICHACE_WRITE_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_FILE, RICHACE_ADD_FILE}, - {ARCHIVE_ENTRY_ACL_APPEND_DATA, RICHACE_APPEND_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, RICHACE_ADD_SUBDIRECTORY}, - {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, RICHACE_READ_NAMED_ATTRS}, - {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, RICHACE_WRITE_NAMED_ATTRS}, - {ARCHIVE_ENTRY_ACL_DELETE_CHILD, RICHACE_DELETE_CHILD}, - {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, RICHACE_READ_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, RICHACE_WRITE_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_DELETE, RICHACE_DELETE}, - {ARCHIVE_ENTRY_ACL_READ_ACL, RICHACE_READ_ACL}, - {ARCHIVE_ENTRY_ACL_WRITE_ACL, RICHACE_WRITE_ACL}, - {ARCHIVE_ENTRY_ACL_WRITE_OWNER, RICHACE_WRITE_OWNER}, - {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, RICHACE_SYNCHRONIZE} -#else /* FreeBSD NFSv4 ACL permissions */ - {ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE}, - {ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA}, - {ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY}, - {ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE}, - {ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA}, - {ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY}, - {ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS}, - {ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS}, - {ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD}, - {ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES}, - {ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE}, - {ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL}, - {ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL}, - {ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER}, - {ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE} -#endif - }; - int i, permset = 0; - - for (i = 0; i < (int)(sizeof(perms)/sizeof(perms[0])); ++i) -#if ARCHIVE_ACL_SUNOS_NFS4 || ARCHIVE_ACL_LIBRICHACL - if (mask & perms[i].machine) -#else - if (acl_get_perm_np(opaque_ps, perms[i].machine)) -#endif - permset |= perms[i].portable; - return permset; -} - -static int -#if ARCHIVE_ACL_SUNOS_NFS4 -acl_flagset_to_bitmap(uint16_t flags) -#elif ARCHIVE_ACL_LIBRICHACL -acl_flagset_to_bitmap(int flags) -#else -acl_flagset_to_bitmap(acl_flagset_t opaque_fs) -#endif -{ - static struct { int portable; int machine; } perms[] = { -#if ARCHIVE_ACL_SUNOS_NFS4 /* Solaris NFSv4 ACL inheritance flags */ - {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE}, - {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACE_DIRECTORY_INHERIT_ACE}, - {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACE_NO_PROPAGATE_INHERIT_ACE}, - {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACE_INHERIT_ONLY_ACE}, - {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACE_SUCCESSFUL_ACCESS_ACE_FLAG}, - {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACE_FAILED_ACCESS_ACE_FLAG}, -#ifdef ACE_INHERITED_ACE - {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE} -#endif -#elif ARCHIVE_ACL_DARWIN /* MacOS NFSv4 ACL inheritance flags */ - {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}, - {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT}, - {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT}, - {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_LIMIT_INHERIT}, - {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_ONLY_INHERIT} -#elif ARCHIVE_ACL_LIBRICHACL - {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, RICHACE_FILE_INHERIT_ACE}, - {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, RICHACE_DIRECTORY_INHERIT_ACE}, - {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, RICHACE_NO_PROPAGATE_INHERIT_ACE}, - {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, RICHACE_INHERIT_ONLY_ACE}, - {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, RICHACE_INHERITED_ACE} -#else /* FreeBSD NFSv4 ACL inheritance flags */ -#ifdef ACL_ENTRY_INHERITED - {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}, -#endif - {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT}, - {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT}, - {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT}, - {ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS}, - {ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS}, - {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY} -#endif - }; - int i, flagset = 0; - - for (i = 0; i < (int)(sizeof(perms)/sizeof(perms[0])); ++i) -#if ARCHIVE_ACL_SUNOS_NFS4 || ARCHIVE_ACL_LIBRICHACL - if (flags & perms[i].machine) -#else - if (acl_get_flag_np(opaque_fs, perms[i].machine)) -#endif - flagset |= perms[i].portable; - return flagset; -} - -#if ARCHIVE_ACL_SUNOS_NFS4 -static int -acl_match(ace_t *ace, struct myacl_t *myacl) -{ - int perms; - - perms = acl_permset_to_bitmap(ace->a_access_mask) | acl_flagset_to_bitmap(ace->a_flags); - - if (perms != myacl->permset) - return (0); - - switch (ace->a_type) { - case ACE_ACCESS_ALLOWED_ACE_TYPE: - if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW) - return (0); - break; - case ACE_ACCESS_DENIED_ACE_TYPE: - if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_DENY) - return (0); - break; - case ACE_SYSTEM_AUDIT_ACE_TYPE: - if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_AUDIT) - return (0); - break; - case ACE_SYSTEM_ALARM_ACE_TYPE: - if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALARM) - return (0); - break; - default: - return (0); - } - - if (ace->a_flags & ACE_OWNER) { - if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) - return (0); - } else if (ace->a_flags & ACE_GROUP) { - if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ) - return (0); - } else if (ace->a_flags & ACE_EVERYONE) { - if (myacl->tag != ARCHIVE_ENTRY_ACL_EVERYONE) - return (0); - } else if (ace->a_flags & ACE_IDENTIFIER_GROUP) { - if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP) - return (0); - if ((gid_t)myacl->qual != ace->a_who) - return (0); - } else { - if (myacl->tag != ARCHIVE_ENTRY_ACL_USER) - return (0); - if ((uid_t)myacl->qual != ace->a_who) - return (0); - } - return (1); -} -#elif ARCHIVE_ACL_LIBRICHACL -static int -acl_match(struct richace *richace, struct myacl_t *myacl) -{ - int perms; - - perms = acl_permset_to_bitmap(richace->e_mask) | - acl_flagset_to_bitmap(richace->e_flags); - - if (perms != myacl->permset) - return (0); - - switch (richace->e_type) { - case RICHACE_ACCESS_ALLOWED_ACE_TYPE: - if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW) - return (0); - break; - case RICHACE_ACCESS_DENIED_ACE_TYPE: - if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_DENY) - return (0); - break; - default: - return (0); - } - - if (richace->e_flags & RICHACE_SPECIAL_WHO) { - switch (richace->e_id) { - case RICHACE_OWNER_SPECIAL_ID: - if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) - return (0); - break; - case RICHACE_GROUP_SPECIAL_ID: - if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ) - return (0); - break; - case RICHACE_EVERYONE_SPECIAL_ID: - if (myacl->tag != ARCHIVE_ENTRY_ACL_EVERYONE) - return (0); - break; - default: - /* Invalid e_id */ - return (0); - } - } else if (richace->e_flags & RICHACE_IDENTIFIER_GROUP) { - if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP) - return (0); - if ((gid_t)myacl->qual != richace->e_id) - return (0); - } else { - if (myacl->tag != ARCHIVE_ENTRY_ACL_USER) - return (0); - if ((uid_t)myacl->qual != richace->e_id) - return (0); - } - return (1); -} -#elif ARCHIVE_ACL_DARWIN -static int -acl_match(acl_entry_t aclent, struct myacl_t *myacl) -{ - void *q; - uid_t ugid; - int r, idtype; - acl_tag_t tag_type; - acl_permset_t opaque_ps; - acl_flagset_t opaque_fs; - int perms; - - acl_get_tag_type(aclent, &tag_type); - - /* translate the silly opaque permset to a bitmap */ - acl_get_permset(aclent, &opaque_ps); - acl_get_flagset_np(aclent, &opaque_fs); - perms = acl_permset_to_bitmap(opaque_ps) | acl_flagset_to_bitmap(opaque_fs); - if (perms != myacl->permset) - return (0); - - r = 0; - switch (tag_type) { - case ACL_EXTENDED_ALLOW: - if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW) - return (0); - break; - case ACL_EXTENDED_DENY: - if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_DENY) - return (0); - break; - default: - return (0); - } - q = acl_get_qualifier(aclent); - if (q == NULL) - return (0); - r = mbr_uuid_to_id((const unsigned char *)q, &ugid, &idtype); - acl_free(q); - if (r != 0) - return (0); - switch (idtype) { - case ID_TYPE_UID: - if (myacl->tag != ARCHIVE_ENTRY_ACL_USER) - return (0); - if ((uid_t)myacl->qual != ugid) - return (0); - break; - case ID_TYPE_GID: - if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP) - return (0); - if ((gid_t)myacl->qual != ugid) - return (0); - break; - default: - return (0); - } - return (1); -} -#else /* ARCHIVE_ACL_FREEBSD_NFS4 */ -static int -acl_match(acl_entry_t aclent, struct myacl_t *myacl) -{ - gid_t g, *gp; - uid_t u, *up; - acl_entry_type_t entry_type; - acl_tag_t tag_type; - acl_permset_t opaque_ps; - acl_flagset_t opaque_fs; - int perms; - - acl_get_tag_type(aclent, &tag_type); - acl_get_entry_type_np(aclent, &entry_type); - - /* translate the silly opaque permset to a bitmap */ - acl_get_permset(aclent, &opaque_ps); - acl_get_flagset_np(aclent, &opaque_fs); - perms = acl_permset_to_bitmap(opaque_ps) | acl_flagset_to_bitmap(opaque_fs); - if (perms != myacl->permset) - return (0); - - switch (entry_type) { - case ACL_ENTRY_TYPE_ALLOW: - if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW) - return (0); - break; - case ACL_ENTRY_TYPE_DENY: - if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_DENY) - return (0); - break; - case ACL_ENTRY_TYPE_AUDIT: - if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_AUDIT) - return (0); - break; - case ACL_ENTRY_TYPE_ALARM: - if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALARM) - return (0); - break; - default: - return (0); - } - - switch (tag_type) { - case ACL_USER_OBJ: - if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) return (0); - break; - case ACL_USER: - if (myacl->tag != ARCHIVE_ENTRY_ACL_USER) - return (0); - up = acl_get_qualifier(aclent); - u = *up; - acl_free(up); - if ((uid_t)myacl->qual != u) - return (0); - break; - case ACL_GROUP_OBJ: - if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ) return (0); - break; - case ACL_GROUP: - if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP) - return (0); - gp = acl_get_qualifier(aclent); - g = *gp; - acl_free(gp); - if ((gid_t)myacl->qual != g) - return (0); - break; - case ACL_MASK: - if (myacl->tag != ARCHIVE_ENTRY_ACL_MASK) return (0); - break; - case ACL_EVERYONE: - if (myacl->tag != ARCHIVE_ENTRY_ACL_EVERYONE) return (0); - break; - } - return (1); -} -#endif /* various ARCHIVE_ACL_NFS4 implementations */ - -static void -compare_acls( -#if ARCHIVE_ACL_SUNOS_NFS4 - void *aclp, - int aclcnt, -#elif ARCHIVE_ACL_LIBRICHACL - struct richacl *richacl, -#else - acl_t acl, -#endif - struct myacl_t *myacls, const char *filename, int start, int end) -{ - int *marker; - int matched; - int i, n; -#if ARCHIVE_ACL_SUNOS_NFS4 - int e; - ace_t *acl_entry; -#elif ARCHIVE_ACL_LIBRICHACL - int e; - struct richace *acl_entry; - int aclcnt; -#else - int entry_id = ACL_FIRST_ENTRY; - acl_entry_t acl_entry; -#if ARCHIVE_ACL_DARWIN - const int acl_get_entry_ret = 0; -#else - const int acl_get_entry_ret = 1; -#endif -#endif - -#if ARCHIVE_ACL_SUNOS_NFS4 - if (aclp == NULL) - return; -#elif ARCHIVE_ACL_LIBRICHACL - if (richacl == NULL) - return; - aclcnt = richacl->a_count; -#else - if (acl == NULL) - return; -#endif - - n = end - start; - marker = malloc(sizeof(marker[0]) * (n + 1)); - for (i = 0; i < n; i++) - marker[i] = i + start; -#if !ARCHIVE_ACL_DARWIN - /* Always include the first ACE. */ - if (start > 0) { - marker[n] = 0; - ++n; - } -#endif - - /* - * Iterate over acls in system acl object, try to match each - * one with an item in the myacls array. - */ -#if ARCHIVE_ACL_SUNOS_NFS4 || ARCHIVE_ACL_LIBRICHACL - for (e = 0; e < aclcnt; e++) -#else - while (acl_get_entry_ret == acl_get_entry(acl, entry_id, &acl_entry)) -#endif - { -#if ARCHIVE_ACL_SUNOS_NFS4 - acl_entry = &((ace_t *)aclp)[e]; -#elif ARCHIVE_ACL_LIBRICHACL - acl_entry = &(richacl->a_entries[e]); -#else - /* After the first time... */ - entry_id = ACL_NEXT_ENTRY; -#endif - /* Search for a matching entry (tag and qualifier) */ - for (i = 0, matched = 0; i < n && !matched; i++) { - if (acl_match(acl_entry, &myacls[marker[i]])) { - /* We found a match; remove it. */ - marker[i] = marker[n - 1]; - n--; - matched = 1; - } - } - - failure("ACL entry on file %s that shouldn't be there", - filename); - assert(matched == 1); - } - - /* Dump entries in the myacls array that weren't in the system acl. */ - for (i = 0; i < n; ++i) { - failure(" ACL entry %d missing from %s: " - "type=%#010x,permset=%#010x,tag=%d,qual=%d,name=``%s''\n", - marker[i], filename, - myacls[marker[i]].type, myacls[marker[i]].permset, - myacls[marker[i]].tag, myacls[marker[i]].qual, - myacls[marker[i]].name); - assert(0); /* Record this as a failure. */ - } - free(marker); -} - -static void -compare_entry_acls(struct archive_entry *ae, struct myacl_t *myacls, const char *filename, int start, int end) -{ - int *marker; - int matched; - int i, n; - int type, permset, tag, qual; - const char *name; - - /* Count ACL entries in myacls array and allocate an indirect array. */ - n = end - start; - marker = malloc(sizeof(marker[0]) * (n + 1)); - for (i = 0; i < n; i++) - marker[i] = i + start; - /* Always include the first ACE. */ - if (start > 0) { - marker[n] = 0; - ++n; - } - - /* - * Iterate over acls in entry, try to match each - * one with an item in the myacls array. - */ - assertEqualInt(n, archive_entry_acl_reset(ae, - ARCHIVE_ENTRY_ACL_TYPE_NFS4)); - while (ARCHIVE_OK == archive_entry_acl_next(ae, - ARCHIVE_ENTRY_ACL_TYPE_NFS4, &type, &permset, &tag, &qual, &name)) { - - /* Search for a matching entry (tag and qualifier) */ - for (i = 0, matched = 0; i < n && !matched; i++) { - if (tag == myacls[marker[i]].tag - && qual == myacls[marker[i]].qual - && permset == myacls[marker[i]].permset - && type == myacls[marker[i]].type) { - /* We found a match; remove it. */ - marker[i] = marker[n - 1]; - n--; - matched = 1; - } - } - - failure("ACL entry on file that shouldn't be there: " - "type=%#010x,permset=%#010x,tag=%d,qual=%d", - type,permset,tag,qual); - assert(matched == 1); - } - - /* Dump entries in the myacls array that weren't in the system acl. */ - for (i = 0; i < n; ++i) { - failure(" ACL entry %d missing from %s: " - "type=%#010x,permset=%#010x,tag=%d,qual=%d,name=``%s''\n", - marker[i], filename, - myacls[marker[i]].type, myacls[marker[i]].permset, - myacls[marker[i]].tag, myacls[marker[i]].qual, - myacls[marker[i]].name); - assert(0); /* Record this as a failure. */ - } - free(marker); -} -#endif /* ARCHIVE_ACL_NFS4 */ - -/* - * Verify ACL restore-to-disk. This test is Platform-specific. - */ - -DEFINE_TEST(test_acl_platform_nfs4) -{ -#if !ARCHIVE_ACL_NFS4 - skipping("NFS4 ACLs are not supported on this platform"); -#else /* ARCHIVE_ACL_NFS4 */ - char buff[64]; - int i; - struct stat st; - struct archive *a; - struct archive_entry *ae; -#if ARCHIVE_ACL_DARWIN /* On MacOS we skip trivial ACLs in some tests */ - const int regcnt = acls_reg_cnt - 4; - const int dircnt = acls_dir_cnt - 4; -#else - const int regcnt = acls_reg_cnt; - const int dircnt = acls_dir_cnt; -#endif -#if ARCHIVE_ACL_SUNOS_NFS4 - void *aclp; - int aclcnt; -#elif ARCHIVE_ACL_LIBRICHACL - struct richacl *richacl; -#else /* !ARCHIVE_ACL_SUNOS_NFS4 */ - acl_t acl; -#endif - - assertMakeFile("pretest", 0644, "a"); - - if (setTestAcl("pretest") != ARCHIVE_TEST_ACL_TYPE_NFS4) { - skipping("NFS4 ACLs are not writable on this filesystem"); - return; - } - - /* Create a write-to-disk object. */ - assert(NULL != (a = archive_write_disk_new())); - archive_write_disk_set_options(a, - ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL); - - /* Populate an archive entry with some metadata, including ACL info */ - ae = archive_entry_new(); - assert(ae != NULL); - archive_entry_set_pathname(ae, "testall"); - archive_entry_set_filetype(ae, AE_IFREG); - archive_entry_set_perm(ae, 0654); - archive_entry_set_mtime(ae, 123456, 7890); - archive_entry_set_size(ae, 0); - set_acls(ae, acls_reg, 0, acls_reg_cnt); - - /* Write the entry to disk, including ACLs. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - - /* Likewise for a dir. */ - archive_entry_set_pathname(ae, "dirall"); - archive_entry_set_filetype(ae, AE_IFDIR); - archive_entry_set_perm(ae, 0654); - archive_entry_set_mtime(ae, 123456, 7890); - set_acls(ae, acls_dir, 0, acls_dir_cnt); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - - for (i = 0; i < acls_dir_cnt; ++i) { - snprintf(buff, sizeof(buff), "dir%d", i); - archive_entry_set_pathname(ae, buff); - archive_entry_set_filetype(ae, AE_IFDIR); - archive_entry_set_perm(ae, 0654); - archive_entry_set_mtime(ae, 123456 + i, 7891 + i); - set_acls(ae, acls_dir, i, i + 1); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - } - - archive_entry_free(ae); - - /* Close the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Verify the data on disk. */ - assertEqualInt(0, stat("testall", &st)); - assertEqualInt(st.st_mtime, 123456); -#if ARCHIVE_ACL_SUNOS_NFS4 - aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, "testall"); - failure("acl(\"%s\"): errno = %d (%s)", "testall", errno, - strerror(errno)); - assert(aclp != NULL); -#elif ARCHIVE_ACL_LIBRICHACL - richacl = richacl_get_file("testall"); - failure("richacl_get_file(\"%s\"): errno = %d (%s)", "testall", errno, - strerror(errno)); - assert(richacl != NULL); -#else -#if ARCHIVE_ACL_DARWIN - acl = acl_get_file("testall", ACL_TYPE_EXTENDED); -#else - acl = acl_get_file("testall", ACL_TYPE_NFS4); -#endif - failure("acl_get_file(\"%s\"): errno = %d (%s)", "testall", errno, - strerror(errno)); - assert(acl != (acl_t)NULL); -#endif -#if ARCHIVE_ACL_SUNOS_NFS4 - compare_acls(aclp, aclcnt, acls_reg, "testall", 0, regcnt); - free(aclp); - aclp = NULL; -#elif ARCHIVE_ACL_LIBRICHACL - compare_acls(richacl, acls_reg, "testall", 0, regcnt); - richacl_free(richacl); -#else - compare_acls(acl, acls_reg, "testall", 0, regcnt); - acl_free(acl); -#endif - - - /* Verify single-permission dirs on disk. */ - for (i = 0; i < dircnt; ++i) { - snprintf(buff, sizeof(buff), "dir%d", i); - assertEqualInt(0, stat(buff, &st)); - assertEqualInt(st.st_mtime, 123456 + i); -#if ARCHIVE_ACL_SUNOS_NFS4 - aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, buff); - failure("acl(\"%s\"): errno = %d (%s)", buff, errno, - strerror(errno)); - assert(aclp != NULL); -#elif ARCHIVE_ACL_LIBRICHACL - richacl = richacl_get_file(buff); - /* First and last two dir do not return a richacl */ - if ((i == 0 || i >= dircnt - 2) && richacl == NULL && - errno == ENODATA) - continue; - failure("richacl_get_file(\"%s\"): errno = %d (%s)", buff, - errno, strerror(errno)); - assert(richacl != NULL); -#else -#if ARCHIVE_ACL_DARWIN - acl = acl_get_file(buff, ACL_TYPE_EXTENDED); -#else - acl = acl_get_file(buff, ACL_TYPE_NFS4); -#endif - failure("acl_get_file(\"%s\"): errno = %d (%s)", buff, errno, - strerror(errno)); - assert(acl != (acl_t)NULL); -#endif -#if ARCHIVE_ACL_SUNOS_NFS4 - compare_acls(aclp, aclcnt, acls_dir, buff, i, i + 1); - free(aclp); - aclp = NULL; -#elif ARCHIVE_ACL_LIBRICHACL - compare_acls(richacl, acls_dir, buff, i, i + 1); - richacl_free(richacl); -#else - compare_acls(acl, acls_dir, buff, i, i + 1); - acl_free(acl); -#endif - } - - /* Verify "dirall" on disk. */ - assertEqualInt(0, stat("dirall", &st)); - assertEqualInt(st.st_mtime, 123456); -#if ARCHIVE_ACL_SUNOS_NFS4 - aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, "dirall"); - failure("acl(\"%s\"): errno = %d (%s)", "dirall", errno, - strerror(errno)); - assert(aclp != NULL); -#elif ARCHIVE_ACL_LIBRICHACL - richacl = richacl_get_file("dirall"); - failure("richacl_get_file(\"%s\"): errno = %d (%s)", "dirall", - errno, strerror(errno)); - assert(richacl != NULL); -#else -#if ARCHIVE_ACL_DARWIN - acl = acl_get_file("dirall", ACL_TYPE_EXTENDED); -#else - acl = acl_get_file("dirall", ACL_TYPE_NFS4); -#endif - failure("acl_get_file(\"%s\"): errno = %d (%s)", "dirall", errno, - strerror(errno)); - assert(acl != (acl_t)NULL); -#endif -#if ARCHIVE_ACL_SUNOS_NFS4 - compare_acls(aclp, aclcnt, acls_dir, "dirall", 0, dircnt); - free(aclp); - aclp = NULL; -#elif ARCHIVE_ACL_LIBRICHACL - compare_acls(richacl, acls_dir, "dirall", 0, dircnt); - richacl_free(richacl); -#else - compare_acls(acl, acls_dir, "dirall", 0, dircnt); - acl_free(acl); -#endif - - /* Read and compare ACL via archive_read_disk */ - a = archive_read_disk_new(); - assert(a != NULL); - ae = archive_entry_new(); - assert(ae != NULL); - archive_entry_set_pathname(ae, "testall"); - assertEqualInt(ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - compare_entry_acls(ae, acls_reg, "testall", 0, acls_reg_cnt); - archive_entry_free(ae); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* Read and compare ACL via archive_read_disk */ - a = archive_read_disk_new(); - assert(a != NULL); - ae = archive_entry_new(); - assert(ae != NULL); - archive_entry_set_pathname(ae, "dirall"); - assertEqualInt(ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - compare_entry_acls(ae, acls_dir, "dirall", 0, acls_dir_cnt); - archive_entry_free(ae); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -#endif /* ARCHIVE_ACL_NFS4 */ -} diff --git a/thirdparty/libarchive/libarchive/test/test_acl_platform_posix1e.c b/thirdparty/libarchive/libarchive/test/test_acl_platform_posix1e.c deleted file mode 100644 index c34f7c2e2..000000000 --- a/thirdparty/libarchive/libarchive/test/test_acl_platform_posix1e.c +++ /dev/null @@ -1,606 +0,0 @@ -/*- - * Copyright (c) 2003-2008 Tim Kientzle - * Copyright (c) 2017 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_acl_freebsd.c 189427 2009-03-06 04:21:23Z kientzle $"); - -#if ARCHIVE_ACL_POSIX1E -#include -#if HAVE_ACL_GET_PERM -#include -#define ACL_GET_PERM acl_get_perm -#elif HAVE_ACL_GET_PERM_NP -#define ACL_GET_PERM acl_get_perm_np -#endif - -static struct archive_test_acl_t acls2[] = { - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE | ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_USER, 77, "user77" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0, - ARCHIVE_ENTRY_ACL_USER, 78, "user78" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0007, - ARCHIVE_ENTRY_ACL_GROUP, 78, "group78" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_OTHER, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ | ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_MASK, -1, "" }, -}; - -static int -#if ARCHIVE_ACL_SUNOS -acl_entry_get_perm(aclent_t *aclent) -#else -acl_entry_get_perm(acl_entry_t aclent) -#endif -{ - int permset = 0; -#if ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_LIBACL - acl_permset_t opaque_ps; -#endif - -#if ARCHIVE_ACL_SUNOS - if (aclent->a_perm & 1) - permset |= ARCHIVE_ENTRY_ACL_EXECUTE; - if (aclent->a_perm & 2) - permset |= ARCHIVE_ENTRY_ACL_WRITE; - if (aclent->a_perm & 4) - permset |= ARCHIVE_ENTRY_ACL_READ; -#else - /* translate the silly opaque permset to a bitmap */ - acl_get_permset(aclent, &opaque_ps); - if (ACL_GET_PERM(opaque_ps, ACL_EXECUTE)) - permset |= ARCHIVE_ENTRY_ACL_EXECUTE; - if (ACL_GET_PERM(opaque_ps, ACL_WRITE)) - permset |= ARCHIVE_ENTRY_ACL_WRITE; - if (ACL_GET_PERM(opaque_ps, ACL_READ)) - permset |= ARCHIVE_ENTRY_ACL_READ; -#endif - return permset; -} - -#if 0 -static int -acl_get_specific_entry(acl_t acl, acl_tag_t requested_tag_type, int requested_tag) { - int entry_id = ACL_FIRST_ENTRY; - acl_entry_t acl_entry; - acl_tag_t acl_tag_type; - - while (1 == acl_get_entry(acl, entry_id, &acl_entry)) { - /* After the first time... */ - entry_id = ACL_NEXT_ENTRY; - - /* If this matches, return perm mask */ - acl_get_tag_type(acl_entry, &acl_tag_type); - if (acl_tag_type == requested_tag_type) { - switch (acl_tag_type) { - case ACL_USER_OBJ: - if ((uid_t)requested_tag == *(uid_t *)(acl_get_qualifier(acl_entry))) { - return acl_entry_get_perm(acl_entry); - } - break; - case ACL_GROUP_OBJ: - if ((gid_t)requested_tag == *(gid_t *)(acl_get_qualifier(acl_entry))) { - return acl_entry_get_perm(acl_entry); - } - break; - case ACL_USER: - case ACL_GROUP: - case ACL_OTHER: - return acl_entry_get_perm(acl_entry); - default: - failure("Unexpected ACL tag type"); - assert(0); - } - } - - - } - return -1; -} -#endif - -#if ARCHIVE_ACL_SUNOS -static int -acl_match(aclent_t *aclent, struct archive_test_acl_t *myacl) -{ - - if (myacl->permset != acl_entry_get_perm(aclent)) - return (0); - - switch (aclent->a_type) { - case DEF_USER_OBJ: - case USER_OBJ: - if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) return (0); - break; - if (myacl->tag != ARCHIVE_ENTRY_ACL_USER) - return (0); - if ((uid_t)myacl->qual != aclent->a_id) - return (0); - break; - case DEF_GROUP_OBJ: - case GROUP_OBJ: - if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ) return (0); - break; - case DEF_GROUP: - case GROUP: - if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP) - return (0); - if ((gid_t)myacl->qual != aclent->a_id) - return (0); - break; - case DEF_CLASS_OBJ: - case CLASS_OBJ: - if (myacl->tag != ARCHIVE_ENTRY_ACL_MASK) return (0); - break; - case DEF_OTHER_OBJ: - case OTHER_OBJ: - if (myacl->tag != ARCHIVE_ENTRY_ACL_OTHER) return (0); - break; - } - return (1); -} - -#else /* ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_LIBACL */ -static int -acl_match(acl_entry_t aclent, struct archive_test_acl_t *myacl) -{ - gid_t g, *gp; - uid_t u, *up; - acl_tag_t tag_type; - - if (myacl->permset != acl_entry_get_perm(aclent)) - return (0); - - acl_get_tag_type(aclent, &tag_type); - switch (tag_type) { - case ACL_USER_OBJ: - if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) return (0); - break; - case ACL_USER: - if (myacl->tag != ARCHIVE_ENTRY_ACL_USER) - return (0); - up = acl_get_qualifier(aclent); - u = *up; - acl_free(up); - if ((uid_t)myacl->qual != u) - return (0); - break; - case ACL_GROUP_OBJ: - if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ) return (0); - break; - case ACL_GROUP: - if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP) - return (0); - gp = acl_get_qualifier(aclent); - g = *gp; - acl_free(gp); - if ((gid_t)myacl->qual != g) - return (0); - break; - case ACL_MASK: - if (myacl->tag != ARCHIVE_ENTRY_ACL_MASK) return (0); - break; - case ACL_OTHER: - if (myacl->tag != ARCHIVE_ENTRY_ACL_OTHER) return (0); - break; - } - return (1); -} -#endif - -static void -compare_acls( -#if ARCHIVE_ACL_SUNOS - void *aclp, int aclcnt, -#else - acl_t acl, -#endif - struct archive_test_acl_t *myacls, int n) -{ - int *marker; - int matched; - int i; -#if ARCHIVE_ACL_SUNOS - int e; - aclent_t *acl_entry; -#else - int entry_id = ACL_FIRST_ENTRY; - acl_entry_t acl_entry; -#endif - - /* Count ACL entries in myacls array and allocate an indirect array. */ - marker = malloc(sizeof(marker[0]) * n); - if (marker == NULL) - return; - for (i = 0; i < n; i++) - marker[i] = i; - - /* - * Iterate over acls in system acl object, try to match each - * one with an item in the myacls array. - */ -#if ARCHIVE_ACL_SUNOS - for(e = 0; e < aclcnt; e++) { - acl_entry = &((aclent_t *)aclp)[e]; -#else - while (1 == acl_get_entry(acl, entry_id, &acl_entry)) { - /* After the first time... */ - entry_id = ACL_NEXT_ENTRY; -#endif - - /* Search for a matching entry (tag and qualifier) */ - for (i = 0, matched = 0; i < n && !matched; i++) { - if (acl_match(acl_entry, &myacls[marker[i]])) { - /* We found a match; remove it. */ - marker[i] = marker[n - 1]; - n--; - matched = 1; - } - } - - /* TODO: Print out more details in this case. */ - failure("ACL entry on file that shouldn't be there"); - assert(matched == 1); - } - - /* Dump entries in the myacls array that weren't in the system acl. */ - for (i = 0; i < n; ++i) { - failure(" ACL entry missing from file: " - "type=%#010x,permset=%#010x,tag=%d,qual=%d,name=``%s''\n", - myacls[marker[i]].type, myacls[marker[i]].permset, - myacls[marker[i]].tag, myacls[marker[i]].qual, - myacls[marker[i]].name); - assert(0); /* Record this as a failure. */ - } - free(marker); -} -#endif - -/* - * Verify ACL restore-to-disk. This test is Platform-specific. - */ - -DEFINE_TEST(test_acl_platform_posix1e_restore) -{ -#if !ARCHIVE_ACL_POSIX1E - skipping("POSIX.1e ACLs are not supported on this platform"); -#else /* ARCHIVE_ACL_POSIX1E */ - struct stat st; - struct archive *a; - struct archive_entry *ae; -#if ARCHIVE_ACL_SUNOS - void *aclp; - int aclcnt; -#else - acl_t acl; -#endif - - assertMakeFile("pretest", 0644, "a"); - - if (setTestAcl("pretest") != ARCHIVE_TEST_ACL_TYPE_POSIX1E) { - skipping("POSIX.1e ACLs are not writable on this filesystem"); - return; - } - - /* Create a write-to-disk object. */ - assert(NULL != (a = archive_write_disk_new())); - archive_write_disk_set_options(a, - ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL); - - /* Populate an archive entry with some metadata, including ACL info */ - ae = archive_entry_new(); - assert(ae != NULL); - archive_entry_set_pathname(ae, "test0"); - archive_entry_set_mtime(ae, 123456, 7890); - archive_entry_set_size(ae, 0); - assertEntrySetAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0])); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Close the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Verify the data on disk. */ - assertEqualInt(0, stat("test0", &st)); - assertEqualInt(st.st_mtime, 123456); -#if ARCHIVE_ACL_SUNOS - aclp = sunacl_get(GETACL, &aclcnt, 0, "test0"); - failure("acl(): errno = %d (%s)", errno, strerror(errno)); - assert(aclp != NULL); -#else - acl = acl_get_file("test0", ACL_TYPE_ACCESS); - failure("acl_get_file(): errno = %d (%s)", errno, strerror(errno)); - assert(acl != (acl_t)NULL); -#endif -#if ARCHIVE_ACL_SUNOS - compare_acls(aclp, aclcnt, acls2, sizeof(acls2)/sizeof(acls2[0])); - free(aclp); - aclp = NULL; -#else - compare_acls(acl, acls2, sizeof(acls2)/sizeof(acls2[0])); - acl_free(acl); -#endif - -#endif /* ARCHIVE_ACL_POSIX1E */ -} - -/* - * Verify ACL read-from-disk. This test is Platform-specific. - */ -DEFINE_TEST(test_acl_platform_posix1e_read) -{ -#if !ARCHIVE_ACL_POSIX1E - skipping("POSIX.1e ACLs are not supported on this platform"); -#else /* ARCHIVE_ACL_POSIX1E */ - struct archive *a; - struct archive_entry *ae; - int n, fd, flags, dflags; - char *acl_text; - const char *func, *acl1_text, *acl2_text, *acl3_text; -#if ARCHIVE_ACL_SUNOS - void *aclp; - int aclcnt; -#else - acl_t acl1, acl2, acl3; -#endif - - /* - * Manually construct a directory and two files with - * different ACLs. This also serves to verify that ACLs - * are supported on the local filesystem. - */ - - /* Create a test file f1 with acl1 */ -#if ARCHIVE_ACL_SUNOS - acl1_text = "user::rwx," - "group::rwx," - "other:rwx," - "user:1:rw-," - "group:15:r-x," - "mask:rwx"; - aclent_t aclp1[] = { - { USER_OBJ, -1, 4 | 2 | 1 }, - { USER, 1, 4 | 2 }, - { GROUP_OBJ, -1, 4 | 2 | 1 }, - { GROUP, 15, 4 | 1 }, - { CLASS_OBJ, -1, 4 | 2 | 1 }, - { OTHER_OBJ, -1, 4 | 2 | 1 } - }; -#else - acl1_text = "user::rwx\n" - "group::rwx\n" - "other::rwx\n" - "user:1:rw-\n" - "group:15:r-x\n" - "mask::rwx"; - acl1 = acl_from_text(acl1_text); - failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno)); - assert((void *)acl1 != NULL); -#endif - fd = open("f1", O_WRONLY | O_CREAT | O_EXCL, 0777); - failure("Could not create test file?!"); - if (!assert(fd >= 0)) { -#if !ARCHIVE_ACL_SUNOS - acl_free(acl1); -#endif - return; - } -#if ARCHIVE_ACL_SUNOS - /* Check if Solaris filesystem supports POSIX.1e ACLs */ - aclp = sunacl_get(GETACL, &aclcnt, fd, NULL); - if (aclp == 0) - close(fd); - if (errno == ENOSYS || errno == ENOTSUP) { - skipping("POSIX.1e ACLs are not supported on this filesystem"); - return; - } - failure("facl(): errno = %d (%s)", errno, strerror(errno)); - assert(aclp != NULL); - - func = "facl()"; - n = facl(fd, SETACL, (int)(sizeof(aclp1)/sizeof(aclp1[0])), aclp1); -#else - func = "acl_set_fd()"; - n = acl_set_fd(fd, acl1); -#endif -#if !ARCHIVE_ACL_SUNOS - acl_free(acl1); -#endif - - if (n != 0) { -#if ARCHIVE_ACL_SUNOS - if (errno == ENOSYS || errno == ENOTSUP) -#else - if (errno == EOPNOTSUPP || errno == EINVAL) -#endif - { - close(fd); - skipping("POSIX.1e ACLs are not supported on this filesystem"); - return; - } - } - failure("%s: errno = %d (%s)", func, errno, strerror(errno)); - assertEqualInt(0, n); - - close(fd); - - assertMakeDir("d", 0700); - - /* - * Create file d/f1 with acl2 - * - * This differs from acl1 in the u:1: and g:15: permissions. - * - * This file deliberately has the same name but a different ACL. - * Github Issue #777 explains how libarchive's directory traversal - * did not always correctly enter directories before attempting - * to read ACLs, resulting in reading the ACL from a like-named - * file in the wrong directory. - */ -#if ARCHIVE_ACL_SUNOS - acl2_text = "user::rwx," - "group::rwx," - "other:---," - "user:1:r--," - "group:15:r--," - "mask:rwx"; - aclent_t aclp2[] = { - { USER_OBJ, -1, 4 | 2 | 1 }, - { USER, 1, 4 }, - { GROUP_OBJ, -1, 4 | 2 | 1}, - { GROUP, 15, 4 }, - { CLASS_OBJ, -1, 4 | 2 | 1}, - { OTHER_OBJ, -1, 0 } - }; -#else - acl2_text = "user::rwx\n" - "group::rwx\n" - "other::---\n" - "user:1:r--\n" - "group:15:r--\n" - "mask::rwx"; - acl2 = acl_from_text(acl2_text); - failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno)); - assert((void *)acl2 != NULL); -#endif - fd = open("d/f1", O_WRONLY | O_CREAT | O_EXCL, 0777); - failure("Could not create test file?!"); - if (!assert(fd >= 0)) { -#if !ARCHIVE_ACL_SUNOS - acl_free(acl2); -#endif - return; - } -#if ARCHIVE_ACL_SUNOS - func = "facl()"; - n = facl(fd, SETACL, (int)(sizeof(aclp2) / sizeof(aclp2[0])), aclp2); -#else - func = "acl_set_fd()"; - n = acl_set_fd(fd, acl2); - acl_free(acl2); -#endif - if (n != 0) - close(fd); - failure("%s: errno = %d (%s)", func, errno, strerror(errno)); - assertEqualInt(0, n); - close(fd); - - /* Create nested directory d2 with default ACLs */ - assertMakeDir("d/d2", 0755); - -#if ARCHIVE_ACL_SUNOS - acl3_text = "user::rwx," - "group::r-x," - "other:r-x," - "user:2:r--," - "group:16:-w-," - "mask:rwx," - "default:user::rwx," - "default:user:1:r--," - "default:group::r-x," - "default:group:15:r--," - "default:mask:rwx," - "default:other:r-x"; - aclent_t aclp3[] = { - { USER_OBJ, -1, 4 | 2 | 1 }, - { USER, 2, 4 }, - { GROUP_OBJ, -1, 4 | 1 }, - { GROUP, 16, 2 }, - { CLASS_OBJ, -1, 4 | 2 | 1 }, - { OTHER_OBJ, -1, 4 | 1 }, - { USER_OBJ | ACL_DEFAULT, -1, 4 | 2 | 1 }, - { USER | ACL_DEFAULT, 1, 4 }, - { GROUP_OBJ | ACL_DEFAULT, -1, 4 | 1 }, - { GROUP | ACL_DEFAULT, 15, 4 }, - { CLASS_OBJ | ACL_DEFAULT, -1, 4 | 2 | 1}, - { OTHER_OBJ | ACL_DEFAULT, -1, 4 | 1 } - }; -#else - acl3_text = "user::rwx\n" - "user:1:r--\n" - "group::r-x\n" - "group:15:r--\n" - "mask::rwx\n" - "other::r-x"; - acl3 = acl_from_text(acl3_text); - failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno)); - assert((void *)acl3 != NULL); -#endif - -#if ARCHIVE_ACL_SUNOS - func = "acl()"; - n = acl("d/d2", SETACL, (int)(sizeof(aclp3) / sizeof(aclp3[0])), aclp3); -#else - func = "acl_set_file()"; - n = acl_set_file("d/d2", ACL_TYPE_DEFAULT, acl3); - acl_free(acl3); -#endif - failure("%s: errno = %d (%s)", func, errno, strerror(errno)); - assertEqualInt(0, n); - - /* Create a read-from-disk object. */ - assert(NULL != (a = archive_read_disk_new())); - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, ".")); - assert(NULL != (ae = archive_entry_new())); - -#if ARCHIVE_ACL_SUNOS - flags = ARCHIVE_ENTRY_ACL_TYPE_POSIX1E - | ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA - | ARCHIVE_ENTRY_ACL_STYLE_SOLARIS; - dflags = flags; -#else - flags = ARCHIVE_ENTRY_ACL_TYPE_ACCESS; - dflags = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT; -#endif - - /* Walk the dir until we see both of the files */ - while (ARCHIVE_OK == archive_read_next_header2(a, ae)) { - archive_read_disk_descend(a); - if (strcmp(archive_entry_pathname(ae), "./f1") == 0) { - acl_text = archive_entry_acl_to_text(ae, NULL, flags); - assertEqualString(acl_text, acl1_text); - free(acl_text); - } else if (strcmp(archive_entry_pathname(ae), "./d/f1") == 0) { - acl_text = archive_entry_acl_to_text(ae, NULL, flags); - assertEqualString(acl_text, acl2_text); - free(acl_text); - } else if (strcmp(archive_entry_pathname(ae), "./d/d2") == 0) { - acl_text = archive_entry_acl_to_text(ae, NULL, dflags); - assertEqualString(acl_text, acl3_text); - free(acl_text); - } - } - - archive_entry_free(ae); - assertEqualInt(ARCHIVE_OK, archive_free(a)); -#endif /* ARCHIVE_ACL_POSIX1E */ -} diff --git a/thirdparty/libarchive/libarchive/test/test_acl_posix1e.c b/thirdparty/libarchive/libarchive/test/test_acl_posix1e.c deleted file mode 100644 index fa2628dbe..000000000 --- a/thirdparty/libarchive/libarchive/test/test_acl_posix1e.c +++ /dev/null @@ -1,180 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/lib/libarchive/test/test_acl_basic.c,v 1.6 2008/10/19 00:13:57 kientzle Exp $"); - -/* - * Exercise the system-independent portion of the ACL support. - * Check that archive_entry objects can save and restore POSIX.1e-style - * ACL data. - * - * This should work on all systems, regardless of whether local - * filesystems support ACLs or not. - */ - -static struct archive_test_acl_t acls0[] = { - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_WRITE, - ARCHIVE_ENTRY_ACL_OTHER, 0, "" }, -}; - -static struct archive_test_acl_t acls1[] = { - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_USER, 77, "user77" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_WRITE, - ARCHIVE_ENTRY_ACL_OTHER, -1, "" }, -}; - -static struct archive_test_acl_t acls2[] = { - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE | ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_USER, 77, "user77" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0, - ARCHIVE_ENTRY_ACL_USER, 78, "user78" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0007, - ARCHIVE_ENTRY_ACL_GROUP, 78, "group78" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_OTHER, -1, "" }, -}; - -/* - * NFS4 entry types; attempts to set these on top of POSIX.1e - * attributes should fail. - */ -static struct archive_test_acl_t acls_nfs4[] = { - /* NFS4 types */ - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_USER, 78, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_USER, 78, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_AUDIT, ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_USER, 78, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALARM, ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_USER, 78, "" }, - - /* NFS4 tags */ - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }, - - /* NFS4 inheritance markers */ - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - ARCHIVE_ENTRY_ACL_READ | ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, - ARCHIVE_ENTRY_ACL_USER, 79, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - ARCHIVE_ENTRY_ACL_READ | ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, - ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, -}; - -DEFINE_TEST(test_acl_posix1e) -{ - struct archive_entry *ae; - int i; - - /* Create a simple archive_entry. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_pathname(ae, "file"); - archive_entry_set_mode(ae, S_IFREG | 0777); - - /* Basic owner/owning group should just update mode bits. */ - - /* - * Note: This features of libarchive's ACL implementation - * shouldn't be relied on and should probably be removed. It - * was done to identify trivial ACLs so we could avoid - * triggering unnecessary extensions. It's better to identify - * trivial ACLs at the point they are being read from disk. - */ - assertEntrySetAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0])); - failure("Basic ACLs shouldn't be stored as extended ACLs"); - assert(0 == archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); - failure("Basic ACLs should set mode to 0142, not %04o", - archive_entry_mode(ae)&0777); - assert((archive_entry_mode(ae) & 0777) == 0142); - - /* With any extended ACL entry, we should read back a full set. */ - assertEntrySetAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0])); - failure("One extended ACL should flag all ACLs to be returned."); - - /* Check that entry contains only POSIX.1e types */ - assert((archive_entry_acl_types(ae) & - ARCHIVE_ENTRY_ACL_TYPE_NFS4) == 0); - assert((archive_entry_acl_types(ae) & - ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0); - - assert(4 == archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); - assertEntryCompareAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]), - ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0142); - failure("Basic ACLs should set mode to 0142, not %04o", - archive_entry_mode(ae)&0777); - assert((archive_entry_mode(ae) & 0777) == 0142); - - - /* A more extensive set of ACLs. */ - assertEntrySetAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0])); - assertEqualInt(6, archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); - assertEntryCompareAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]), - ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0543); - failure("Basic ACLs should set mode to 0543, not %04o", - archive_entry_mode(ae)&0777); - assert((archive_entry_mode(ae) & 0777) == 0543); - - /* - * Check that clearing ACLs gets rid of them all by repeating - * the first test. - */ - assertEntrySetAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0])); - failure("Basic ACLs shouldn't be stored as extended ACLs"); - assert(0 == archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); - failure("Basic ACLs should set mode to 0142, not %04o", - archive_entry_mode(ae)&0777); - assert((archive_entry_mode(ae) & 0777) == 0142); - - /* - * Different types of malformed ACL entries that should - * fail when added to existing POSIX.1e ACLs. - */ - assertEntrySetAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0])); - for (i = 0; i < (int)(sizeof(acls_nfs4)/sizeof(acls_nfs4[0])); ++i) { - struct archive_test_acl_t *p = &acls_nfs4[i]; - failure("Malformed ACL test #%d", i); - assertEqualInt(ARCHIVE_FAILED, - archive_entry_acl_add_entry(ae, - p->type, p->permset, p->tag, p->qual, p->name)); - assertEqualInt(6, - archive_entry_acl_reset(ae, - ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); - } - archive_entry_free(ae); -} diff --git a/thirdparty/libarchive/libarchive/test/test_acl_text.c b/thirdparty/libarchive/libarchive/test/test_acl_text.c deleted file mode 100644 index 80728932c..000000000 --- a/thirdparty/libarchive/libarchive/test/test_acl_text.c +++ /dev/null @@ -1,473 +0,0 @@ -/*- - * Copyright (c) 2016 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* - * Test converting ACLs to text, both wide and non-wide - * - * This should work on all systems, regardless of whether local - * filesystems support ACLs or not. - */ - -static struct archive_test_acl_t acls0[] = { - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_READ | - ARCHIVE_ENTRY_ACL_WRITE, - ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_USER, 100, "user100" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0, - ARCHIVE_ENTRY_ACL_USER, 1000, "user1000" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_READ | - ARCHIVE_ENTRY_ACL_WRITE, - ARCHIVE_ENTRY_ACL_GROUP, 78, "group78" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - ARCHIVE_ENTRY_ACL_READ | - ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_OTHER, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, - ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, - ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0, - ARCHIVE_ENTRY_ACL_OTHER, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, - ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_USER, 101, "user101"}, - { ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, - ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_GROUP, 79, "group79" }, -}; - -static struct archive_test_acl_t acls1[] = { - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_WRITE_DATA | - ARCHIVE_ENTRY_ACL_APPEND_DATA | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_WRITE_OWNER, - ARCHIVE_ENTRY_ACL_USER, 77, "user77" }, - { ARCHIVE_ENTRY_ACL_TYPE_DENY, - ARCHIVE_ENTRY_ACL_WRITE_DATA | - ARCHIVE_ENTRY_ACL_APPEND_DATA | - ARCHIVE_ENTRY_ACL_DELETE_CHILD | - ARCHIVE_ENTRY_ACL_DELETE | - ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT | - ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT | - ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY | - ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, - ARCHIVE_ENTRY_ACL_USER, 101, "user101" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, - ARCHIVE_ENTRY_ACL_GROUP, 78, "group78" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_WRITE_DATA | - ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_APPEND_DATA | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_WRITE_ACL | - ARCHIVE_ENTRY_ACL_WRITE_OWNER, - ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_WRITE_DATA | - ARCHIVE_ENTRY_ACL_APPEND_DATA | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" }, -}; - -const char* acltext[] = { - "user::rwx\n" - "group::r-x\n" - "other::r-x\n" - "user:user100:r-x\n" - "user:user1000:---\n" - "group:group78:rwx\n" - "default:user::r-x\n" - "default:group::r-x\n" - "default:other::---\n" - "default:user:user101:r-x\n" - "default:group:group79:--x", - - "user::rwx\n" - "group::r-x\n" - "other::r-x\n" - "user:user100:r-x:100\n" - "user:user1000:---:1000\n" - "group:group78:rwx:78\n" - "default:user::r-x\n" - "default:group::r-x\n" - "default:other::---\n" - "default:user:user101:r-x:101\n" - "default:group:group79:--x:79", - - "u::rwx\n" - "g::r-x\n" - "o::r-x\n" - "u:user100:r-x:100\n" - "u:user1000:---:1000\n" - "g:group78:rwx:78\n" - "d:user::r-x\n" - "d:group::r-x\n" - "d:other::---\n" - "d:user:user101:r-x:101\n" - "d:group:group79:--x:79", - - "user::rwx\n" - "group::r-x\n" - "other::r-x\n" - "user:user100:r-x\n" - "user:user1000:---\n" - "group:group78:rwx", - - "user::rwx," - "group::r-x," - "other::r-x," - "user:user100:r-x," - "user:user1000:---," - "group:group78:rwx", - - "user::rwx\n" - "group::r-x\n" - "other::r-x\n" - "user:user100:r-x:100\n" - "user:user1000:---:1000\n" - "group:group78:rwx:78", - - "user::r-x\n" - "group::r-x\n" - "other::---\n" - "user:user101:r-x\n" - "group:group79:--x", - - "user::r-x\n" - "group::r-x\n" - "other::---\n" - "user:user101:r-x:101\n" - "group:group79:--x:79", - - "default:user::r-x\n" - "default:group::r-x\n" - "default:other::---\n" - "default:user:user101:r-x\n" - "default:group:group79:--x", - - "user:user77:rw-p--a-R-c-o-:-------:allow\n" - "user:user101:-w-pdD--------:fdin---:deny\n" - "group:group78:r-----a-R-c---:------I:allow\n" - "owner@:rwxp--aARWcCo-:-------:allow\n" - "group@:rw-p--a-R-c---:-------:allow\n" - "everyone@:r-----a-R-c--s:-------:allow", - - "user:user77:rw-p--a-R-c-o-:-------:allow:77\n" - "user:user101:-w-pdD--------:fdin---:deny:101\n" - "group:group78:r-----a-R-c---:------I:allow:78\n" - "owner@:rwxp--aARWcCo-:-------:allow\n" - "group@:rw-p--a-R-c---:-------:allow\n" - "everyone@:r-----a-R-c--s:-------:allow", - - "user:user77:rwpaRco::allow:77\n" - "user:user101:wpdD:fdin:deny:101\n" - "group:group78:raRc:I:allow:78\n" - "owner@:rwxpaARWcCo::allow\n" - "group@:rwpaRc::allow\n" - "everyone@:raRcs::allow" -}; - -static wchar_t * -convert_s_to_ws(const char *s) -{ - size_t len; - wchar_t *ws = NULL; - - if (s != NULL) { - len = strlen(s) + 1; - ws = malloc(len * sizeof(wchar_t)); - assert(mbstowcs(ws, s, len) != (size_t)-1); - } - - return (ws); -} - -static void -compare_acl_text(struct archive_entry *ae, int flags, const char *s) -{ - char *text; - wchar_t *wtext; - wchar_t *ws; - ssize_t slen; - - ws = convert_s_to_ws(s); - - text = archive_entry_acl_to_text(ae, &slen, flags); - assertEqualString(text, s); - if (text != NULL) - assertEqualInt(strlen(text), slen); - wtext = archive_entry_acl_to_text_w(ae, &slen, flags); - assertEqualWString(wtext, ws); - if (wtext != NULL) { - assertEqualInt(wcslen(wtext), slen); - } - free(text); - free(wtext); - free(ws); -} - -DEFINE_TEST(test_acl_from_text) -{ - struct archive_entry *ae; - wchar_t *ws = NULL; - - /* Create an empty archive_entry. */ - assert((ae = archive_entry_new()) != NULL); - - /* 1a. Read POSIX.1e access ACLs from text */ - assertEqualInt(ARCHIVE_OK, - archive_entry_acl_from_text(ae, acltext[5], - ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); - assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]), - ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0755); - assertEqualInt(6, archive_entry_acl_reset(ae, - ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); - - /* 1b. Now read POSIX.1e default ACLs and append them */ - assertEqualInt(ARCHIVE_OK, - archive_entry_acl_from_text(ae, acltext[7], - ARCHIVE_ENTRY_ACL_TYPE_DEFAULT)); - assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]), - ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, 0755); - assertEqualInt(11, archive_entry_acl_reset(ae, - ARCHIVE_ENTRY_ACL_TYPE_POSIX1E)); - archive_entry_acl_clear(ae); - - /* 1a and 1b with wide strings */ - ws = convert_s_to_ws(acltext[5]); - - assertEqualInt(ARCHIVE_OK, - archive_entry_acl_from_text_w(ae, ws, - ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); - assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]), - ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0755); - assertEqualInt(6, archive_entry_acl_reset(ae, - ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); - - free(ws); - ws = convert_s_to_ws(acltext[7]); - - assertEqualInt(ARCHIVE_OK, - archive_entry_acl_from_text_w(ae, ws, - ARCHIVE_ENTRY_ACL_TYPE_DEFAULT)); - assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]), - ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, 0755); - assertEqualInt(11, archive_entry_acl_reset(ae, - ARCHIVE_ENTRY_ACL_TYPE_POSIX1E)); - archive_entry_acl_clear(ae); - - /* 2. Read POSIX.1e default ACLs from text */ - assertEqualInt(ARCHIVE_OK, - archive_entry_acl_from_text(ae, acltext[7], - ARCHIVE_ENTRY_ACL_TYPE_DEFAULT)); - assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]), - ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0); - assertEqualInt(5, archive_entry_acl_reset(ae, - ARCHIVE_ENTRY_ACL_TYPE_DEFAULT)); - archive_entry_acl_clear(ae); - - /* ws is still acltext[7] */ - assertEqualInt(ARCHIVE_OK, - archive_entry_acl_from_text_w(ae, ws, - ARCHIVE_ENTRY_ACL_TYPE_DEFAULT)); - assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]), - ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0); - assertEqualInt(5, archive_entry_acl_reset(ae, - ARCHIVE_ENTRY_ACL_TYPE_DEFAULT)); - archive_entry_acl_clear(ae); - - /* 3. Read POSIX.1e access and default ACLs from text */ - assertEqualInt(ARCHIVE_OK, - archive_entry_acl_from_text(ae, acltext[1], - ARCHIVE_ENTRY_ACL_TYPE_POSIX1E)); - assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]), - ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, 0755); - assertEqualInt(11, archive_entry_acl_reset(ae, - ARCHIVE_ENTRY_ACL_TYPE_POSIX1E)); - archive_entry_acl_clear(ae); - - free(ws); - ws = convert_s_to_ws(acltext[1]); - assertEqualInt(ARCHIVE_OK, - archive_entry_acl_from_text_w(ae, ws, - ARCHIVE_ENTRY_ACL_TYPE_POSIX1E)); - assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]), - ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, 0755); - assertEqualInt(11, archive_entry_acl_reset(ae, - ARCHIVE_ENTRY_ACL_TYPE_POSIX1E)); - archive_entry_acl_clear(ae); - - /* 4. Read POSIX.1e access and default ACLs from text (short form) */ - assertEqualInt(ARCHIVE_OK, - archive_entry_acl_from_text(ae, acltext[2], - ARCHIVE_ENTRY_ACL_TYPE_POSIX1E)); - assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]), - ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, 0755); - assertEqualInt(11, archive_entry_acl_reset(ae, - ARCHIVE_ENTRY_ACL_TYPE_POSIX1E)); - archive_entry_acl_clear(ae); - - free(ws); - ws = convert_s_to_ws(acltext[2]); - assertEqualInt(ARCHIVE_OK, - archive_entry_acl_from_text_w(ae, ws, - ARCHIVE_ENTRY_ACL_TYPE_POSIX1E)); - assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]), - ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, 0755); - assertEqualInt(11, archive_entry_acl_reset(ae, - ARCHIVE_ENTRY_ACL_TYPE_POSIX1E)); - archive_entry_acl_clear(ae); - - /* 5. Read NFSv4 ACLs from text */ - assertEqualInt(ARCHIVE_OK, - archive_entry_acl_from_text(ae, acltext[10], - ARCHIVE_ENTRY_ACL_TYPE_NFS4)); - assertEntryCompareAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]), - ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0); - assertEqualInt(6, archive_entry_acl_reset(ae, - ARCHIVE_ENTRY_ACL_TYPE_NFS4)); - archive_entry_acl_clear(ae); - - free(ws); - ws = convert_s_to_ws(acltext[10]); - - assertEqualInt(ARCHIVE_OK, - archive_entry_acl_from_text_w(ae, ws, - ARCHIVE_ENTRY_ACL_TYPE_NFS4)); - assertEntryCompareAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]), - ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0); - assertEqualInt(6, archive_entry_acl_reset(ae, - ARCHIVE_ENTRY_ACL_TYPE_NFS4)); - archive_entry_acl_clear(ae); - - free(ws); - archive_entry_free(ae); -} - -DEFINE_TEST(test_acl_to_text) -{ - struct archive_entry *ae; - - /* Create an empty archive_entry. */ - assert((ae = archive_entry_new()) != NULL); - - /* Write POSIX.1e ACLs */ - assertEntrySetAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0])); - - /* No flags should give output like getfacl(1) on linux */ - compare_acl_text(ae, 0, acltext[0]); - - /* This should give the same output as previous test */ - compare_acl_text(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS | - ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, acltext[0]); - - /* This should give the same output as previous two tests */ - compare_acl_text(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS | - ARCHIVE_ENTRY_ACL_TYPE_DEFAULT | - ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT, acltext[0]); - - /* POSIX.1e access and default ACLs with appended ID */ - compare_acl_text(ae, ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID, acltext[1]); - - /* POSIX.1e access acls only, like getfacl(1) on FreeBSD */ - compare_acl_text(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, acltext[3]); - - /* POSIX.1e access acls separated with comma */ - compare_acl_text(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS | - ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA, - acltext[4]); - - /* POSIX.1e access acls with appended user or group ID */ - compare_acl_text(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS | - ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID, acltext[5]); - - /* POSIX.1e default acls */ - compare_acl_text(ae, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, acltext[6]); - - /* POSIX.1e default acls with appended user or group ID */ - compare_acl_text(ae, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT | - ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID, acltext[7]); - - /* POSIX.1e default acls prefixed with default: */ - compare_acl_text(ae, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT | - ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT, acltext[8]); - - /* Write NFSv4 ACLs */ - assertEntrySetAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0])); - - /* NFSv4 ACLs like getfacl(1) on FreeBSD */ - compare_acl_text(ae, 0, acltext[9]); - - /* NFSv4 ACLs like "getfacl -i" on FreeBSD */ - compare_acl_text(ae, ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID, acltext[10]); - - /* NFSv4 ACLs like "getfacl -i" on FreeBSD with stripped minus chars */ - compare_acl_text(ae, ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID | - ARCHIVE_ENTRY_ACL_STYLE_COMPACT, acltext[11]); - - archive_entry_free(ae); -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_api_feature.c b/thirdparty/libarchive/libarchive/test/test_archive_api_feature.c deleted file mode 100644 index d7d1a2d5f..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_api_feature.c +++ /dev/null @@ -1,54 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/lib/libarchive/test/test_archive_api_feature.c,v 1.5 2008/05/26 17:00:24 kientzle Exp $"); - -DEFINE_TEST(test_archive_api_feature) -{ - char buff[128]; - const char *p; - - /* This is the (hopefully) final versioning API. */ - assertEqualInt(ARCHIVE_VERSION_NUMBER, archive_version_number()); - snprintf(buff, sizeof(buff), "libarchive %d.%d.%d", - archive_version_number() / 1000000, - (archive_version_number() / 1000) % 1000, - archive_version_number() % 1000); - failure("Version string is: %s, computed is: %s", - archive_version_string(), buff); - assertEqualMem(buff, archive_version_string(), strlen(buff)); - if (strlen(buff) < strlen(archive_version_string())) { - p = archive_version_string() + strlen(buff); - failure("Version string is: %s", archive_version_string()); - if (p[0] == 'd'&& p[1] == 'e' && p[2] == 'v') - p += 3; - else { - assert(*p == 'a' || *p == 'b' || *p == 'c' || *p == 'd'); - ++p; - } - failure("Version string is: %s", archive_version_string()); - assert(*p == '\0'); - } -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_clear_error.c b/thirdparty/libarchive/libarchive/test/test_archive_clear_error.c deleted file mode 100644 index 66dbe93ec..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_clear_error.c +++ /dev/null @@ -1,42 +0,0 @@ -/*- - * Copyright (c) 2003-2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_archive_clear_error) -{ - struct archive* a = archive_read_new(); - - archive_set_error(a, 12, "abcdefgh"); - assertEqualInt(12, archive_errno(a)); - assertEqualString("abcdefgh", archive_error_string(a)); - - archive_clear_error(a); - assertEqualInt(0, archive_errno(a)); - assertEqualString(NULL, archive_error_string(a)); - - archive_read_free(a); -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_cmdline.c b/thirdparty/libarchive/libarchive/test/test_archive_cmdline.c deleted file mode 100644 index a8236105a..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_cmdline.c +++ /dev/null @@ -1,141 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -#define __LIBARCHIVE_TEST -#include "archive_cmdline_private.h" - -DEFINE_TEST(test_archive_cmdline) -{ - struct archive_cmdline *cl; - - /* Command name only. */ - assert((cl = __archive_cmdline_allocate()) != NULL); - if (cl == NULL) - return; - assertEqualInt(ARCHIVE_OK, __archive_cmdline_parse(cl, "gzip")); - assertEqualInt(1, cl->argc); - assertEqualString("gzip", cl->path); - assertEqualString("gzip", cl->argv[0]); - assertEqualInt(ARCHIVE_OK, __archive_cmdline_free(cl)); - - assert((cl = __archive_cmdline_allocate()) != NULL); - if (cl == NULL) - return; - assertEqualInt(ARCHIVE_OK, __archive_cmdline_parse(cl, "gzip ")); - assertEqualInt(1, cl->argc); - failure("path should not include a space character"); - assertEqualString("gzip", cl->path); - failure("arg0 should not include a space character"); - assertEqualString("gzip", cl->argv[0]); - assertEqualInt(ARCHIVE_OK, __archive_cmdline_free(cl)); - - assert((cl = __archive_cmdline_allocate()) != NULL); - if (cl == NULL) - return; - assertEqualInt(ARCHIVE_OK, __archive_cmdline_parse(cl, - "/usr/bin/gzip ")); - assertEqualInt(1, cl->argc); - failure("path should be a full path"); - assertEqualString("/usr/bin/gzip", cl->path); - failure("arg0 should not be a full path"); - assertEqualString("gzip", cl->argv[0]); - assertEqualInt(ARCHIVE_OK, __archive_cmdline_free(cl)); - - /* A command line includes space character. */ - assert((cl = __archive_cmdline_allocate()) != NULL); - if (cl == NULL) - return; - assertEqualInt(ARCHIVE_OK, __archive_cmdline_parse(cl, "\"gzip \"")); - assertEqualInt(1, cl->argc); - failure("path should include a space character"); - assertEqualString("gzip ", cl->path); - failure("arg0 should include a space character"); - assertEqualString("gzip ", cl->argv[0]); - assertEqualInt(ARCHIVE_OK, __archive_cmdline_free(cl)); - - /* A command line includes space character: pattern 2.*/ - assert((cl = __archive_cmdline_allocate()) != NULL); - if (cl == NULL) - return; - assertEqualInt(ARCHIVE_OK, __archive_cmdline_parse(cl, "\"gzip \"x")); - assertEqualInt(1, cl->argc); - failure("path should include a space character"); - assertEqualString("gzip x", cl->path); - failure("arg0 should include a space character"); - assertEqualString("gzip x", cl->argv[0]); - assertEqualInt(ARCHIVE_OK, __archive_cmdline_free(cl)); - - /* A command line includes space character: pattern 3.*/ - assert((cl = __archive_cmdline_allocate()) != NULL); - if (cl == NULL) - return; - assertEqualInt(ARCHIVE_OK, __archive_cmdline_parse(cl, - "\"gzip \"x\" s \"")); - assertEqualInt(1, cl->argc); - failure("path should include a space character"); - assertEqualString("gzip x s ", cl->path); - failure("arg0 should include a space character"); - assertEqualString("gzip x s ", cl->argv[0]); - assertEqualInt(ARCHIVE_OK, __archive_cmdline_free(cl)); - - /* A command line includes space character: pattern 4.*/ - assert((cl = __archive_cmdline_allocate()) != NULL); - if (cl == NULL) - return; - assertEqualInt(ARCHIVE_OK, __archive_cmdline_parse(cl, - "\"gzip\\\" \"")); - assertEqualInt(1, cl->argc); - failure("path should include a space character"); - assertEqualString("gzip\" ", cl->path); - failure("arg0 should include a space character"); - assertEqualString("gzip\" ", cl->argv[0]); - assertEqualInt(ARCHIVE_OK, __archive_cmdline_free(cl)); - - /* A command name with a argument. */ - assert((cl = __archive_cmdline_allocate()) != NULL); - if (cl == NULL) - return; - assertEqualInt(ARCHIVE_OK, __archive_cmdline_parse(cl, "gzip -d")); - assertEqualInt(2, cl->argc); - assertEqualString("gzip", cl->path); - assertEqualString("gzip", cl->argv[0]); - assertEqualString("-d", cl->argv[1]); - assertEqualInt(ARCHIVE_OK, __archive_cmdline_free(cl)); - - /* A command name with two arguments. */ - assert((cl = __archive_cmdline_allocate()) != NULL); - if (cl == NULL) - return; - assertEqualInt(ARCHIVE_OK, __archive_cmdline_parse(cl, "gzip -d -q")); - assertEqualInt(3, cl->argc); - assertEqualString("gzip", cl->path); - assertEqualString("gzip", cl->argv[0]); - assertEqualString("-d", cl->argv[1]); - assertEqualString("-q", cl->argv[2]); - assertEqualInt(ARCHIVE_OK, __archive_cmdline_free(cl)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_digest.c b/thirdparty/libarchive/libarchive/test/test_archive_digest.c deleted file mode 100644 index a8654ae1f..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_digest.c +++ /dev/null @@ -1,145 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2011 Andres Mejia - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -/* Sanity test of internal digest functionality */ - -#define __LIBARCHIVE_BUILD 1 -#include "archive_digest_private.h" - -DEFINE_TEST(test_archive_md5) -{ - archive_md5_ctx ctx; - unsigned char buf[] = ""; - unsigned char md[16]; - unsigned char actualmd[] = "\x93\xb8\x85\xad\xfe\x0d\xa0\x89" - "\xcd\xf6\x34\x90\x4f\xd5\x9f\x71"; - - if (ARCHIVE_OK != archive_md5_init(&ctx)) { - skipping("This platform does not support MD5"); - return; - } - assertEqualInt(ARCHIVE_OK, archive_md5_update(&ctx, buf, sizeof(buf))); - assertEqualInt(ARCHIVE_OK, archive_md5_final(&ctx, md)); - assertEqualMem(md, actualmd, sizeof(md)); -} - -DEFINE_TEST(test_archive_rmd160) -{ - archive_rmd160_ctx ctx; - unsigned char buf[] = ""; - unsigned char md[20]; - unsigned char actualmd[] = "\xc8\x1b\x94\x93\x34\x20\x22\x1a\x7a\xc0" - "\x04\xa9\x02\x42\xd8\xb1\xd3\xe5\x07\x0d"; - - if (ARCHIVE_OK != archive_rmd160_init(&ctx)) { - skipping("This platform does not support RMD160"); - return; - } - assertEqualInt(ARCHIVE_OK, archive_rmd160_update(&ctx, buf, sizeof(buf))); - assertEqualInt(ARCHIVE_OK, archive_rmd160_final(&ctx, md)); - assertEqualMem(md, actualmd, sizeof(md)); -} - -DEFINE_TEST(test_archive_sha1) -{ - archive_sha1_ctx ctx; - unsigned char buf[] = ""; - unsigned char md[20]; - unsigned char actualmd[] = "\x5b\xa9\x3c\x9d\xb0\xcf\xf9\x3f\x52\xb5" - "\x21\xd7\x42\x0e\x43\xf6\xed\xa2\x78\x4f"; - - if (ARCHIVE_OK != archive_sha1_init(&ctx)) { - skipping("This platform does not support SHA1"); - return; - } - assertEqualInt(ARCHIVE_OK, archive_sha1_update(&ctx, buf, sizeof(buf))); - assertEqualInt(ARCHIVE_OK, archive_sha1_final(&ctx, md)); - assertEqualMem(md, actualmd, sizeof(md)); -} - -DEFINE_TEST(test_archive_sha256) -{ - archive_sha256_ctx ctx; - unsigned char buf[] = ""; - unsigned char md[32]; - unsigned char actualmd[] = "\x6e\x34\x0b\x9c\xff\xb3\x7a\x98" - "\x9c\xa5\x44\xe6\xbb\x78\x0a\x2c" - "\x78\x90\x1d\x3f\xb3\x37\x38\x76" - "\x85\x11\xa3\x06\x17\xaf\xa0\x1d"; - - if (ARCHIVE_OK != archive_sha256_init(&ctx)) { - skipping("This platform does not support SHA256"); - return; - } - assertEqualInt(ARCHIVE_OK, archive_sha256_update(&ctx, buf, sizeof(buf))); - assertEqualInt(ARCHIVE_OK, archive_sha256_final(&ctx, md)); - assertEqualMem(md, actualmd, sizeof(md)); -} - -DEFINE_TEST(test_archive_sha384) -{ - archive_sha384_ctx ctx; - unsigned char buf[] = ""; - unsigned char md[48]; - unsigned char actualmd[] = "\xbe\xc0\x21\xb4\xf3\x68\xe3\x06" - "\x91\x34\xe0\x12\xc2\xb4\x30\x70" - "\x83\xd3\xa9\xbd\xd2\x06\xe2\x4e" - "\x5f\x0d\x86\xe1\x3d\x66\x36\x65" - "\x59\x33\xec\x2b\x41\x34\x65\x96" - "\x68\x17\xa9\xc2\x08\xa1\x17\x17"; - - if (ARCHIVE_OK != archive_sha384_init(&ctx)) { - skipping("This platform does not support SHA384"); - return; - } - assertEqualInt(ARCHIVE_OK, archive_sha384_update(&ctx, buf, sizeof(buf))); - assertEqualInt(ARCHIVE_OK, archive_sha384_final(&ctx, md)); - assertEqualMem(md, actualmd, sizeof(md)); -} - -DEFINE_TEST(test_archive_sha512) -{ - archive_sha512_ctx ctx; - unsigned char buf[] = ""; - unsigned char md[64]; - unsigned char actualmd[] = "\xb8\x24\x4d\x02\x89\x81\xd6\x93" - "\xaf\x7b\x45\x6a\xf8\xef\xa4\xca" - "\xd6\x3d\x28\x2e\x19\xff\x14\x94" - "\x2c\x24\x6e\x50\xd9\x35\x1d\x22" - "\x70\x4a\x80\x2a\x71\xc3\x58\x0b" - "\x63\x70\xde\x4c\xeb\x29\x3c\x32" - "\x4a\x84\x23\x34\x25\x57\xd4\xe5" - "\xc3\x84\x38\xf0\xe3\x69\x10\xee"; - - if (ARCHIVE_OK != archive_sha512_init(&ctx)) { - skipping("This platform does not support SHA512"); - return; - } - assertEqualInt(ARCHIVE_OK, archive_sha512_update(&ctx, buf, sizeof(buf))); - assertEqualInt(ARCHIVE_OK, archive_sha512_final(&ctx, md)); - assertEqualMem(md, actualmd, sizeof(md)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_getdate.c b/thirdparty/libarchive/libarchive/test/test_archive_getdate.c deleted file mode 100644 index 9e91b83ba..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_getdate.c +++ /dev/null @@ -1,89 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -#include - -#define __LIBARCHIVE_BUILD 1 -#include "archive_getdate.h" - -/* - * Verify that the getdate() function works. - */ - -#define get_date __archive_get_date - -DEFINE_TEST(test_archive_getdate) -{ - time_t now = time(NULL); - - assertEqualInt(get_date(now, "Jan 1, 1970 UTC"), 0); - assertEqualInt(get_date(now, "7:12:18-0530 4 May 1983"), 420900138); - assertEqualInt(get_date(now, "2004/01/29 513 mest"), 1075345980); - assertEqualInt(get_date(now, "99/02/17 7pm utc"), 919278000); - assertEqualInt(get_date(now, "02/17/99 7:11am est"), 919253460); - assertEqualInt(get_date(now, "now - 2 hours"), - get_date(now, "2 hours ago")); - assertEqualInt(get_date(now, "2 hours ago"), - get_date(now, "+2 hours ago")); - assertEqualInt(get_date(now, "now - 2 hours"), - get_date(now, "-2 hours")); - /* It's important that we handle ctime() format. */ - assertEqualInt(get_date(now, "Sun Feb 22 17:38:26 PST 2009"), - 1235353106); - /* Basic relative offsets. */ - /* If we use the actual current time as the reference, then - * these tests break around DST changes, so it's actually - * important to use a specific reference time here. */ - assertEqualInt(get_date(0, "tomorrow"), 24 * 60 * 60); - assertEqualInt(get_date(0, "yesterday"), - 24 * 60 * 60); - assertEqualInt(get_date(0, "now + 1 hour"), 60 * 60); - assertEqualInt(get_date(0, "now + 1 hour + 1 minute"), 60 * 60 + 60); - /* Repeat the above for a different start time. */ - now = 1231113600; /* Jan 5, 2009 00:00 UTC */ - assertEqualInt(get_date(0, "Jan 5, 2009 00:00 UTC"), now); - assertEqualInt(get_date(now, "tomorrow"), now + 24 * 60 * 60); - assertEqualInt(get_date(now, "yesterday"), now - 24 * 60 * 60); - assertEqualInt(get_date(now, "now + 1 hour"), now + 60 * 60); - assertEqualInt(get_date(now, "now + 1 hour + 1 minute"), - now + 60 * 60 + 60); - assertEqualInt(get_date(now, "tomorrow 5:16am UTC"), - now + 24 * 60 * 60 + 5 * 60 * 60 + 16 * 60); - assertEqualInt(get_date(now, "UTC 5:16am tomorrow"), - now + 24 * 60 * 60 + 5 * 60 * 60 + 16 * 60); - - /* Jan 5, 2009 was a Monday. */ - assertEqualInt(get_date(now, "monday UTC"), now); - assertEqualInt(get_date(now, "sunday UTC"), now + 6 * 24 * 60 * 60); - assertEqualInt(get_date(now, "tuesday UTC"), now + 24 * 60 * 60); - /* "next tuesday" is one week after "tuesday" */ - assertEqualInt(get_date(now, "UTC next tuesday"), - now + 8 * 24 * 60 * 60); - /* "last tuesday" is one week before "tuesday" */ - assertEqualInt(get_date(now, "last tuesday UTC"), - now - 6 * 24 * 60 * 60); - /* TODO: Lots more tests here. */ -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_match_owner.c b/thirdparty/libarchive/libarchive/test/test_archive_match_owner.c deleted file mode 100644 index 6bf9c6f08..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_match_owner.c +++ /dev/null @@ -1,289 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -static void -test_uid(void) -{ - struct archive_entry *ae; - struct archive *m; - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - - assertEqualIntA(m, 0, archive_match_include_uid(m, 1000)); - assertEqualIntA(m, 0, archive_match_include_uid(m, 1002)); - - archive_entry_set_uid(ae, 0); - failure("uid 0 should be excluded"); - assertEqualInt(1, archive_match_owner_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - archive_entry_set_uid(ae, 1000); - failure("uid 1000 should not be excluded"); - assertEqualInt(0, archive_match_owner_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - archive_entry_set_uid(ae, 1001); - failure("uid 1001 should be excluded"); - assertEqualInt(1, archive_match_owner_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - archive_entry_set_uid(ae, 1002); - failure("uid 1002 should not be excluded"); - assertEqualInt(0, archive_match_owner_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - archive_entry_set_uid(ae, 1003); - failure("uid 1003 should be excluded"); - assertEqualInt(1, archive_match_owner_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Clean up. */ - archive_entry_free(ae); - archive_match_free(m); -} - -static void -test_gid(void) -{ - struct archive_entry *ae; - struct archive *m; - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - - assertEqualIntA(m, 0, archive_match_include_gid(m, 1000)); - assertEqualIntA(m, 0, archive_match_include_gid(m, 1002)); - - archive_entry_set_gid(ae, 0); - failure("uid 0 should be excluded"); - assertEqualInt(1, archive_match_owner_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - archive_entry_set_gid(ae, 1000); - failure("uid 1000 should not be excluded"); - assertEqualInt(0, archive_match_owner_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - archive_entry_set_gid(ae, 1001); - failure("uid 1001 should be excluded"); - assertEqualInt(1, archive_match_owner_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - archive_entry_set_gid(ae, 1002); - failure("uid 1002 should not be excluded"); - assertEqualInt(0, archive_match_owner_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - archive_entry_set_gid(ae, 1003); - failure("uid 1003 should be excluded"); - assertEqualInt(1, archive_match_owner_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Clean up. */ - archive_entry_free(ae); - archive_match_free(m); -} - -static void -test_uname_mbs(void) -{ - struct archive_entry *ae; - struct archive *m; - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - - assertEqualIntA(m, 0, archive_match_include_uname(m, "foo")); - assertEqualIntA(m, 0, archive_match_include_uname(m, "bar")); - - archive_entry_copy_uname(ae, "unknown"); - failure("User 'unknown' should be excluded"); - assertEqualInt(1, archive_match_owner_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - archive_entry_copy_uname(ae, "foo"); - failure("User 'foo' should not be excluded"); - assertEqualInt(0, archive_match_owner_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - archive_entry_copy_uname(ae, "foo1"); - failure("User 'foo1' should be excluded"); - assertEqualInt(1, archive_match_owner_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - archive_entry_copy_uname(ae, "bar"); - failure("User 'bar' should not be excluded"); - assertEqualInt(0, archive_match_owner_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - archive_entry_copy_uname(ae, "bar1"); - failure("User 'bar1' should be excluded"); - assertEqualInt(1, archive_match_owner_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Clean up. */ - archive_entry_free(ae); - archive_match_free(m); -} - -static void -test_uname_wcs(void) -{ - struct archive_entry *ae; - struct archive *m; - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - - assertEqualIntA(m, 0, archive_match_include_uname_w(m, L"foo")); - assertEqualIntA(m, 0, archive_match_include_uname_w(m, L"bar")); - - archive_entry_copy_uname_w(ae, L"unknown"); - failure("User 'unknown' should be excluded"); - assertEqualInt(1, archive_match_owner_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - archive_entry_copy_uname_w(ae, L"foo"); - failure("User 'foo' should not be excluded"); - assertEqualInt(0, archive_match_owner_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - archive_entry_copy_uname_w(ae, L"foo1"); - failure("User 'foo1' should be excluded"); - assertEqualInt(1, archive_match_owner_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - archive_entry_copy_uname_w(ae, L"bar"); - failure("User 'bar' should not be excluded"); - assertEqualInt(0, archive_match_owner_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - archive_entry_copy_uname_w(ae, L"bar1"); - failure("User 'bar1' should be excluded"); - assertEqualInt(1, archive_match_owner_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Clean up. */ - archive_entry_free(ae); - archive_match_free(m); -} - -static void -test_gname_mbs(void) -{ - struct archive_entry *ae; - struct archive *m; - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - - assertEqualIntA(m, 0, archive_match_include_gname(m, "foo")); - assertEqualIntA(m, 0, archive_match_include_gname(m, "bar")); - - archive_entry_copy_gname(ae, "unknown"); - failure("Group 'unknown' should be excluded"); - assertEqualInt(1, archive_match_owner_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - archive_entry_copy_gname(ae, "foo"); - failure("Group 'foo' should not be excluded"); - assertEqualInt(0, archive_match_owner_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - archive_entry_copy_gname(ae, "foo1"); - failure("Group 'foo1' should be excluded"); - assertEqualInt(1, archive_match_owner_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - archive_entry_copy_gname(ae, "bar"); - failure("Group 'bar' should not be excluded"); - assertEqualInt(0, archive_match_owner_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - archive_entry_copy_gname(ae, "bar1"); - failure("Group 'bar1' should be excluded"); - assertEqualInt(1, archive_match_owner_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Clean up. */ - archive_entry_free(ae); - archive_match_free(m); -} - -static void -test_gname_wcs(void) -{ - struct archive_entry *ae; - struct archive *m; - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - - assertEqualIntA(m, 0, archive_match_include_gname_w(m, L"foo")); - assertEqualIntA(m, 0, archive_match_include_gname_w(m, L"bar")); - - archive_entry_copy_gname_w(ae, L"unknown"); - failure("Group 'unknown' should be excluded"); - assertEqualInt(1, archive_match_owner_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - archive_entry_copy_gname_w(ae, L"foo"); - failure("Group 'foo' should not be excluded"); - assertEqualInt(0, archive_match_owner_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - archive_entry_copy_gname_w(ae, L"foo1"); - failure("Group 'foo1' should be excluded"); - assertEqualInt(1, archive_match_owner_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - archive_entry_copy_gname_w(ae, L"bar"); - failure("Group 'bar' should not be excluded"); - assertEqualInt(0, archive_match_owner_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - archive_entry_copy_gname_w(ae, L"bar1"); - failure("Group 'bar1' should be excluded"); - assertEqualInt(1, archive_match_owner_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Clean up. */ - archive_entry_free(ae); - archive_match_free(m); -} - -DEFINE_TEST(test_archive_match_owner) -{ - test_uid(); - test_gid(); - test_uname_mbs(); - test_uname_wcs(); - test_gname_mbs(); - test_gname_wcs(); -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_match_path.c b/thirdparty/libarchive/libarchive/test/test_archive_match_path.c deleted file mode 100644 index 5e9b9a8cb..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_match_path.c +++ /dev/null @@ -1,450 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -static void -test_exclusion_mbs(void) -{ - struct archive_entry *ae; - struct archive *m; - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - - /* Test for pattern "^aa*" */ - assertEqualIntA(m, 0, archive_match_exclude_pattern(m, "^aa*")); - - /* Test with 'aa1234', which should be excluded. */ - archive_entry_copy_pathname(ae, "aa1234"); - failure("'aa1234' should be excluded"); - assertEqualInt(1, archive_match_path_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - archive_entry_clear(ae); - archive_entry_copy_pathname_w(ae, L"aa1234"); - failure("'aa1234' should be excluded"); - assertEqualInt(1, archive_match_path_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Test with 'a1234', which should not be excluded. */ - archive_entry_copy_pathname(ae, "a1234"); - failure("'a1234' should not be excluded"); - assertEqualInt(0, archive_match_path_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - archive_entry_clear(ae); - archive_entry_copy_pathname_w(ae, L"a1234"); - failure("'a1234' should not be excluded"); - assertEqualInt(0, archive_match_path_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - /* Clean up. */ - archive_entry_free(ae); - archive_match_free(m); -} - -static void -test_exclusion_wcs(void) -{ - struct archive_entry *ae; - struct archive *m; - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - - /* Test for pattern "^aa*" */ - assertEqualIntA(m, 0, archive_match_exclude_pattern_w(m, L"^aa*")); - - /* Test with 'aa1234', which should be excluded. */ - archive_entry_copy_pathname(ae, "aa1234"); - failure("'aa1234' should be excluded"); - assertEqualInt(1, archive_match_path_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - archive_entry_clear(ae); - archive_entry_copy_pathname_w(ae, L"aa1234"); - failure("'aa1234' should be excluded"); - assertEqualInt(1, archive_match_path_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Test with 'a1234', which should not be excluded. */ - archive_entry_copy_pathname(ae, "a1234"); - failure("'a1234' should not be excluded"); - assertEqualInt(0, archive_match_path_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - archive_entry_clear(ae); - archive_entry_copy_pathname_w(ae, L"a1234"); - failure("'a1234' should not be excluded"); - assertEqualInt(0, archive_match_path_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - /* Clean up. */ - archive_entry_free(ae); - archive_match_free(m); -} - -static void -exclusion_from_file(struct archive *m) -{ - struct archive_entry *ae; - - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - - /* Test with 'first', which should not be excluded. */ - archive_entry_copy_pathname(ae, "first"); - failure("'first' should not be excluded"); - assertEqualInt(0, archive_match_path_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - archive_entry_clear(ae); - archive_entry_copy_pathname_w(ae, L"first"); - failure("'first' should not be excluded"); - assertEqualInt(0, archive_match_path_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - /* Test with 'second', which should be excluded. */ - archive_entry_copy_pathname(ae, "second"); - failure("'second' should be excluded"); - assertEqualInt(1, archive_match_path_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - archive_entry_clear(ae); - archive_entry_copy_pathname_w(ae, L"second"); - failure("'second' should be excluded"); - assertEqualInt(1, archive_match_path_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Test with 'third', which should not be excluded. */ - archive_entry_copy_pathname(ae, "third"); - failure("'third' should not be excluded"); - assertEqualInt(0, archive_match_path_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - archive_entry_clear(ae); - archive_entry_copy_pathname_w(ae, L"third"); - failure("'third' should not be excluded"); - assertEqualInt(0, archive_match_path_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - /* Test with 'four', which should be excluded. */ - archive_entry_copy_pathname(ae, "four"); - failure("'four' should be excluded"); - assertEqualInt(1, archive_match_path_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - archive_entry_clear(ae); - archive_entry_copy_pathname_w(ae, L"four"); - failure("'four' should be excluded"); - assertEqualInt(1, archive_match_path_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Clean up. */ - archive_entry_free(ae); -} - -static void -test_exclusion_from_file_mbs(void) -{ - struct archive *m; - - /* Test1: read exclusion patterns from file */ - if (!assert((m = archive_match_new()) != NULL)) - return; - assertEqualIntA(m, 0, - archive_match_exclude_pattern_from_file(m, "exclusion", 0)); - exclusion_from_file(m); - /* Clean up. */ - archive_match_free(m); - - /* Test2: read exclusion patterns in a null separator from file */ - if (!assert((m = archive_match_new()) != NULL)) - return; - /* Test for pattern reading from file */ - assertEqualIntA(m, 0, - archive_match_exclude_pattern_from_file(m, "exclusion_null", 1)); - exclusion_from_file(m); - /* Clean up. */ - archive_match_free(m); -} - -static void -test_exclusion_from_file_wcs(void) -{ - struct archive *m; - - /* Test1: read exclusion patterns from file */ - if (!assert((m = archive_match_new()) != NULL)) - return; - assertEqualIntA(m, 0, - archive_match_exclude_pattern_from_file_w(m, L"exclusion", 0)); - exclusion_from_file(m); - /* Clean up. */ - archive_match_free(m); - - /* Test2: read exclusion patterns in a null separator from file */ - if (!assert((m = archive_match_new()) != NULL)) - return; - /* Test for pattern reading from file */ - assertEqualIntA(m, 0, - archive_match_exclude_pattern_from_file_w(m, L"exclusion_null", 1)); - exclusion_from_file(m); - /* Clean up. */ - archive_match_free(m); -} - -static void -test_inclusion_mbs(void) -{ - struct archive_entry *ae; - struct archive *m; - const char *mp; - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - - /* Test for pattern "^aa*" */ - assertEqualIntA(m, 0, archive_match_include_pattern(m, "^aa*")); - - /* Test with 'aa1234', which should not be excluded. */ - archive_entry_copy_pathname(ae, "aa1234"); - failure("'aa1234' should not be excluded"); - assertEqualInt(0, archive_match_path_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - archive_entry_clear(ae); - archive_entry_copy_pathname_w(ae, L"aa1234"); - failure("'aa1234' should not be excluded"); - assertEqualInt(0, archive_match_path_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - /* Test with 'a1234', which should be excluded. */ - archive_entry_copy_pathname(ae, "a1234"); - failure("'a1234' should be excluded"); - assertEqualInt(1, archive_match_path_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - archive_entry_clear(ae); - archive_entry_copy_pathname_w(ae, L"a1234"); - failure("'a1234' should be excluded"); - assertEqualInt(1, archive_match_path_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Verify unmatched_inclusions. */ - assertEqualInt(0, archive_match_path_unmatched_inclusions(m)); - assertEqualIntA(m, ARCHIVE_EOF, - archive_match_path_unmatched_inclusions_next(m, &mp)); - - /* Clean up. */ - archive_entry_free(ae); - archive_match_free(m); -} - -static void -test_inclusion_wcs(void) -{ - struct archive_entry *ae; - struct archive *m; - const char *mp; - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - - /* Test for pattern "^aa*" */ - assertEqualIntA(m, 0, archive_match_include_pattern_w(m, L"^aa*")); - - /* Test with 'aa1234', which should not be excluded. */ - archive_entry_copy_pathname(ae, "aa1234"); - failure("'aa1234' should not be excluded"); - assertEqualInt(0, archive_match_path_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - archive_entry_clear(ae); - archive_entry_copy_pathname_w(ae, L"aa1234"); - failure("'aa1234' should not be excluded"); - assertEqualInt(0, archive_match_path_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - /* Test with 'a1234', which should be excluded. */ - archive_entry_copy_pathname(ae, "a1234"); - failure("'a1234' should be excluded"); - assertEqualInt(1, archive_match_path_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - archive_entry_clear(ae); - archive_entry_copy_pathname_w(ae, L"a1234"); - failure("'a1234' should be excluded"); - assertEqualInt(1, archive_match_path_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Verify unmatched_inclusions. */ - assertEqualInt(0, archive_match_path_unmatched_inclusions(m)); - assertEqualIntA(m, ARCHIVE_EOF, - archive_match_path_unmatched_inclusions_next(m, &mp)); - - /* Clean up. */ - archive_entry_free(ae); - archive_match_free(m); -} - -static void -test_inclusion_from_file_mbs(void) -{ - struct archive *m; - - /* Test1: read inclusion patterns from file */ - if (!assert((m = archive_match_new()) != NULL)) - return; - assertEqualIntA(m, 0, - archive_match_include_pattern_from_file(m, "inclusion", 0)); - exclusion_from_file(m); - /* Clean up. */ - archive_match_free(m); - - /* Test2: read inclusion patterns in a null separator from file */ - if (!assert((m = archive_match_new()) != NULL)) - return; - assertEqualIntA(m, 0, - archive_match_include_pattern_from_file(m, "inclusion_null", 1)); - exclusion_from_file(m); - /* Clean up. */ - archive_match_free(m); -} - -static void -test_inclusion_from_file_wcs(void) -{ - struct archive *m; - - /* Test1: read inclusion patterns from file */ - if (!assert((m = archive_match_new()) != NULL)) - return; - /* Test for pattern reading from file */ - assertEqualIntA(m, 0, - archive_match_include_pattern_from_file_w(m, L"inclusion", 0)); - exclusion_from_file(m); - /* Clean up. */ - archive_match_free(m); - - /* Test2: read inclusion patterns in a null separator from file */ - if (!assert((m = archive_match_new()) != NULL)) - return; - /* Test for pattern reading from file */ - assertEqualIntA(m, 0, - archive_match_include_pattern_from_file_w(m, L"inclusion_null", 1)); - exclusion_from_file(m); - /* Clean up. */ - archive_match_free(m); -} - -static void -test_exclusion_and_inclusion(void) -{ - struct archive_entry *ae; - struct archive *m; - const char *mp; - const wchar_t *wp; - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - - assertEqualIntA(m, 0, archive_match_exclude_pattern(m, "^aaa*")); - assertEqualIntA(m, 0, archive_match_include_pattern_w(m, L"^aa*")); - assertEqualIntA(m, 0, archive_match_include_pattern(m, "^a1*")); - - /* Test with 'aa1234', which should not be excluded. */ - archive_entry_copy_pathname(ae, "aa1234"); - failure("'aa1234' should not be excluded"); - assertEqualInt(0, archive_match_path_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - archive_entry_clear(ae); - archive_entry_copy_pathname_w(ae, L"aa1234"); - failure("'aa1234' should not be excluded"); - assertEqualInt(0, archive_match_path_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - /* Test with 'aaa1234', which should be excluded. */ - archive_entry_copy_pathname(ae, "aaa1234"); - failure("'aaa1234' should be excluded"); - assertEqualInt(1, archive_match_path_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - archive_entry_clear(ae); - archive_entry_copy_pathname_w(ae, L"aaa1234"); - failure("'aaa1234' should be excluded"); - assertEqualInt(1, archive_match_path_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Verify unmatched_inclusions. */ - assertEqualInt(1, archive_match_path_unmatched_inclusions(m)); - /* Verify unmatched inclusion patterns. */ - assertEqualIntA(m, ARCHIVE_OK, - archive_match_path_unmatched_inclusions_next(m, &mp)); - assertEqualString("^a1*", mp); - assertEqualIntA(m, ARCHIVE_EOF, - archive_match_path_unmatched_inclusions_next(m, &mp)); - /* Verify unmatched inclusion patterns again in Wide-Char. */ - assertEqualIntA(m, ARCHIVE_OK, - archive_match_path_unmatched_inclusions_next_w(m, &wp)); - assertEqualWString(L"^a1*", wp); - assertEqualIntA(m, ARCHIVE_EOF, - archive_match_path_unmatched_inclusions_next_w(m, &wp)); - - /* Clean up. */ - archive_entry_free(ae); - archive_match_free(m); -} - -DEFINE_TEST(test_archive_match_path) -{ - /* Make exclusion sample files which contain exclusion patterns. */ - assertMakeFile("exclusion", 0666, "second\nfour\n"); - assertMakeBinFile("exclusion_null", 0666, 12, "second\0four\0"); - /* Make inclusion sample files which contain inclusion patterns. */ - assertMakeFile("inclusion", 0666, "first\nthird\n"); - assertMakeBinFile("inclusion_null", 0666, 12, "first\0third\0"); - - test_exclusion_mbs(); - test_exclusion_wcs(); - test_exclusion_from_file_mbs(); - test_exclusion_from_file_wcs(); - test_inclusion_mbs(); - test_inclusion_wcs(); - test_inclusion_from_file_mbs(); - test_inclusion_from_file_wcs(); - test_exclusion_and_inclusion(); -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_match_time.c b/thirdparty/libarchive/libarchive/test/test_archive_match_time.c deleted file mode 100644 index 23754a153..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_match_time.c +++ /dev/null @@ -1,1389 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -#define __LIBARCHIVE_BUILD 1 -#include "archive_getdate.h" - -static void -test_newer_time(void) -{ - struct archive_entry *ae; - struct archive *m; - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - - assertEqualIntA(m, 0, archive_match_include_time(m, - ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME | - ARCHIVE_MATCH_NEWER, 7880, 0)); - - archive_entry_copy_pathname(ae, "file1"); - archive_entry_set_mtime(ae, 7880, 0); - archive_entry_set_ctime(ae, 7880, 0); - failure("Both Its mtime and ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - archive_entry_set_mtime(ae, 7879, 999); - archive_entry_set_ctime(ae, 7879, 999); - failure("Both Its mtime and ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - archive_entry_set_mtime(ae, 7881, 0); - archive_entry_set_ctime(ae, 7881, 0); - failure("Both Its mtime and ctime should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - archive_entry_set_mtime(ae, 7880, 1); - archive_entry_set_ctime(ae, 7880, 0); - failure("Its mtime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - archive_entry_set_mtime(ae, 7880, 0); - archive_entry_set_ctime(ae, 7880, 1); - failure("Its ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Clean up. */ - archive_entry_free(ae); - archive_match_free(m); -} - -static void -test_newer_time_str(void) -{ - struct archive_entry *ae; - struct archive *m; - time_t now, t; - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - - time(&now); - - assertEqualIntA(m, 0, archive_match_include_date(m, - ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME | - ARCHIVE_MATCH_NEWER, "1980/2/1 0:0:0 UTC")); - - /* Test1: Allow newer time. */ - archive_entry_copy_pathname(ae, "file1"); - t = __archive_get_date(now, "1980/2/1 0:0:0 UTC"); - archive_entry_set_mtime(ae, t, 0); - archive_entry_set_ctime(ae, t, 0); - failure("Both Its mtime and ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - t = __archive_get_date(now, "1980/1/1 0:0:0 UTC"); - archive_entry_set_mtime(ae, t, 0); - archive_entry_set_ctime(ae, t, 0); - failure("Both Its mtime and ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - t = __archive_get_date(now, "1980/2/1 0:0:1 UTC"); - archive_entry_set_mtime(ae, t, 0); - archive_entry_set_ctime(ae, t, 0); - failure("Both Its mtime and ctime should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - t = __archive_get_date(now, "1980/2/1 0:0:0 UTC"); - archive_entry_set_mtime(ae, t, 1); - archive_entry_set_ctime(ae, t, 0); - failure("Its mtime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - archive_entry_set_mtime(ae, t, 0); - archive_entry_set_ctime(ae, t, 1); - failure("Its ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - - /* Test2: Allow equal or newer time. */ - assertEqualIntA(m, 0, archive_match_include_date(m, - ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME | - ARCHIVE_MATCH_NEWER | ARCHIVE_MATCH_EQUAL, - "1980/2/1 0:0:0 UTC")); - - archive_entry_copy_pathname(ae, "file1"); - t = __archive_get_date(now, "1980/2/1 0:0:0 UTC"); - archive_entry_set_mtime(ae, t, 0); - archive_entry_set_ctime(ae, t, 0); - failure("Both Its mtime and ctime should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - t = __archive_get_date(now, "1980/1/1 0:0:0 UTC"); - archive_entry_set_mtime(ae, t, 0); - archive_entry_set_ctime(ae, t, 0); - failure("Both Its mtime and ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - t = __archive_get_date(now, "1980/2/1 0:0:1 UTC"); - archive_entry_set_mtime(ae, t, 0); - archive_entry_set_ctime(ae, t, 0); - failure("Both Its mtime and ctime should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - /* Clean up. */ - archive_entry_free(ae); - archive_match_free(m); -} - -static void -test_newer_time_str_w(void) -{ - struct archive_entry *ae; - struct archive *m; - time_t now, t; - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - - time(&now); - - assertEqualIntA(m, 0, archive_match_include_date_w(m, - ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME | - ARCHIVE_MATCH_NEWER, L"1980/2/1 0:0:0 UTC")); - - /* Test1: Allow newer time. */ - archive_entry_copy_pathname(ae, "file1"); - t = __archive_get_date(now, "1980/2/1 0:0:0 UTC"); - archive_entry_set_mtime(ae, t, 0); - archive_entry_set_ctime(ae, t, 0); - failure("Both Its mtime and ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - t = __archive_get_date(now, "1980/1/1 0:0:0 UTC"); - archive_entry_set_mtime(ae, t, 0); - archive_entry_set_ctime(ae, t, 0); - failure("Both Its mtime and ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - t = __archive_get_date(now, "1980/2/1 0:0:1 UTC"); - archive_entry_set_mtime(ae, t, 0); - archive_entry_set_ctime(ae, t, 0); - failure("Both Its mtime and ctime should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - t = __archive_get_date(now, "1980/2/1 0:0:0 UTC"); - archive_entry_set_mtime(ae, t, 1); - archive_entry_set_ctime(ae, t, 0); - failure("Its mtime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - archive_entry_set_mtime(ae, t, 0); - archive_entry_set_ctime(ae, t, 1); - failure("Its ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - - /* Test2: Allow equal or newer time. */ - assertEqualIntA(m, 0, archive_match_include_date_w(m, - ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME | - ARCHIVE_MATCH_NEWER | ARCHIVE_MATCH_EQUAL, - L"1980/2/1 0:0:0 UTC")); - - archive_entry_copy_pathname(ae, "file1"); - t = __archive_get_date(now, "1980/2/1 0:0:0 UTC"); - archive_entry_set_mtime(ae, t, 0); - archive_entry_set_ctime(ae, t, 0); - failure("Both Its mtime and ctime should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - t = __archive_get_date(now, "1980/1/1 0:0:0 UTC"); - archive_entry_set_mtime(ae, t, 0); - archive_entry_set_ctime(ae, t, 0); - failure("Both Its mtime and ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - t = __archive_get_date(now, "1980/2/1 0:0:1 UTC"); - archive_entry_set_mtime(ae, t, 0); - archive_entry_set_ctime(ae, t, 0); - failure("Both Its mtime and ctime should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - /* Clean up. */ - archive_entry_free(ae); - archive_match_free(m); -} - -static void -test_newer_mtime_than_file_mbs(void) -{ - struct archive *a; - struct archive_entry *ae; - struct archive *m; - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - if (!assert((a = archive_read_disk_new()) != NULL)) { - archive_match_free(m); - archive_entry_free(ae); - return; - } - - /* - * Test: newer mtime than a file specified in MBS file name. - */ - assertEqualIntA(m, 0, archive_match_include_file_time(m, - ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_NEWER, "mid_mtime")); - - /* Verify 'old_mtime' file. */ - archive_entry_copy_pathname(ae, "old_mtime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("old_mtime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Verify 'mid_mtime' file. */ - archive_entry_clear(ae); - archive_entry_copy_pathname(ae, "mid_mtime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("mid_mtime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Verify 'new_mtime' file. */ - archive_entry_clear(ae); - archive_entry_copy_pathname(ae, "new_mtime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("new_mtime should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - /* Clean up. */ - archive_read_free(a); - archive_entry_free(ae); - archive_match_free(m); -} - -static void -test_newer_ctime_than_file_mbs(void) -{ - struct archive *a; - struct archive_entry *ae; - struct archive *m; - -#if defined(_WIN32) && !defined(__CYGWIN__) - skipping("Can't set ctime on Windows"); - return; -#endif - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - if (!assert((a = archive_read_disk_new()) != NULL)) { - archive_match_free(m); - archive_entry_free(ae); - return; - } - - /* - * Test: newer ctime than a file specified in MBS file name. - */ - assertEqualIntA(m, 0, archive_match_include_file_time(m, - ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_NEWER, "mid_ctime")); - - /* Verify 'old_ctime' file. */ - archive_entry_copy_pathname(ae, "old_ctime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("old_ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Verify 'mid_ctime' file. */ - archive_entry_clear(ae); - archive_entry_copy_pathname(ae, "mid_ctime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("mid_ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Verify 'new_ctime' file. */ - archive_entry_clear(ae); - archive_entry_copy_pathname(ae, "new_ctime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("new_ctime should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - /* Clean up. */ - archive_read_free(a); - archive_entry_free(ae); - archive_match_free(m); -} - -static void -test_newer_mtime_than_file_wcs(void) -{ - struct archive *a; - struct archive_entry *ae; - struct archive *m; - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - if (!assert((a = archive_read_disk_new()) != NULL)) { - archive_match_free(m); - archive_entry_free(ae); - return; - } - - /* - * Test: newer mtime than a file specified in WCS file name. - */ - assertEqualIntA(m, 0, archive_match_include_file_time_w(m, - ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_NEWER, L"mid_mtime")); - - /* Verify 'old_mtime' file. */ - archive_entry_copy_pathname(ae, "old_mtime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("old_mtime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Verify 'mid_mtime' file. */ - archive_entry_clear(ae); - archive_entry_copy_pathname(ae, "mid_mtime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("mid_mtime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Verify 'new_mtime' file. */ - archive_entry_clear(ae); - archive_entry_copy_pathname(ae, "new_mtime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("new_mtime should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - /* Clean up. */ - archive_read_free(a); - archive_entry_free(ae); - archive_match_free(m); -} - -static void -test_newer_ctime_than_file_wcs(void) -{ - struct archive *a; - struct archive_entry *ae; - struct archive *m; - -#if defined(_WIN32) && !defined(__CYGWIN__) - skipping("Can't set ctime on Windows"); - return; -#endif - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - if (!assert((a = archive_read_disk_new()) != NULL)) { - archive_match_free(m); - archive_entry_free(ae); - return; - } - - /* - * Test: newer ctime than a file specified in WCS file name. - */ - assertEqualIntA(m, 0, archive_match_include_file_time_w(m, - ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_NEWER, L"mid_ctime")); - - /* Verify 'old_ctime' file. */ - archive_entry_clear(ae); - archive_entry_copy_pathname(ae, "old_ctime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("old_ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Verify 'mid_ctime' file. */ - archive_entry_clear(ae); - archive_entry_copy_pathname(ae, "mid_ctime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("mid_ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Verify 'new_ctime' file. */ - archive_entry_clear(ae); - archive_entry_copy_pathname(ae, "new_ctime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("new_ctime should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - /* Clean up. */ - archive_read_free(a); - archive_entry_free(ae); - archive_match_free(m); -} - -static void -test_older_time(void) -{ - struct archive_entry *ae; - struct archive *m; - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - - assertEqualIntA(m, 0, archive_match_include_time(m, - ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME | - ARCHIVE_MATCH_OLDER, 7880, 0)); - - archive_entry_copy_pathname(ae, "file1"); - archive_entry_set_mtime(ae, 7880, 0); - archive_entry_set_ctime(ae, 7880, 0); - failure("Both Its mtime and ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - archive_entry_set_mtime(ae, 7879, 999); - archive_entry_set_ctime(ae, 7879, 999); - failure("Both Its mtime and ctime should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - archive_entry_set_mtime(ae, 7881, 0); - archive_entry_set_ctime(ae, 7881, 0); - failure("Both Its mtime and ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - archive_entry_set_mtime(ae, 7880, 1); - archive_entry_set_ctime(ae, 7879, 0); - failure("Its mtime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - archive_entry_set_mtime(ae, 7879, 0); - archive_entry_set_ctime(ae, 7880, 1); - failure("Its ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Clean up. */ - archive_entry_free(ae); - archive_match_free(m); -} - -static void -test_older_time_str(void) -{ - struct archive_entry *ae; - struct archive *m; - time_t now, t; - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - - time(&now); - - /* Test1: Allow newer time. */ - assertEqualIntA(m, 0, archive_match_include_date(m, - ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME | - ARCHIVE_MATCH_OLDER, "1980/2/1 0:0:0 UTC")); - - archive_entry_copy_pathname(ae, "file1"); - t = __archive_get_date(now, "1980/2/1 0:0:0 UTC"); - archive_entry_set_mtime(ae, t, 0); - archive_entry_set_ctime(ae, t, 0); - failure("Both Its mtime and ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - t = __archive_get_date(now, "1980/1/1 0:0:0 UTC"); - archive_entry_set_mtime(ae, t, 0); - archive_entry_set_ctime(ae, t, 0); - failure("Both Its mtime and ctime should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - t = __archive_get_date(now, "1980/3/1 0:0:0 UTC"); - archive_entry_set_mtime(ae, t, 0); - archive_entry_set_ctime(ae, t, 0); - failure("Both Its mtime and ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - t = __archive_get_date(now, "1980/3/1 0:0:0 UTC"); - archive_entry_set_mtime(ae, t, 0); - t = __archive_get_date(now, "1980/1/1 0:0:0 UTC"); - archive_entry_set_ctime(ae, t, 0); - failure("Its mtime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - t = __archive_get_date(now, "1980/1/1 0:0:0 UTC"); - archive_entry_set_mtime(ae, t, 0); - t = __archive_get_date(now, "1980/3/1 0:0:0 UTC"); - archive_entry_set_ctime(ae, t, 0); - failure("Its ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Test2: Allow equal or newer time. */ - assertEqualIntA(m, 0, archive_match_include_date(m, - ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME | - ARCHIVE_MATCH_OLDER | ARCHIVE_MATCH_EQUAL, - "1980/2/1 0:0:0 UTC")); - - archive_entry_copy_pathname(ae, "file1"); - t = __archive_get_date(now, "1980/2/1 0:0:0 UTC"); - archive_entry_set_mtime(ae, t, 0); - archive_entry_set_ctime(ae, t, 0); - failure("Both Its mtime and ctime should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - t = __archive_get_date(now, "1980/1/1 0:0:0 UTC"); - archive_entry_set_mtime(ae, t, 0); - archive_entry_set_ctime(ae, t, 0); - failure("Both Its mtime and ctime should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - t = __archive_get_date(now, "1980/3/1 0:0:0 UTC"); - archive_entry_set_mtime(ae, t, 0); - archive_entry_set_ctime(ae, t, 0); - failure("Both Its mtime and ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Clean up. */ - archive_entry_free(ae); - archive_match_free(m); -} - -static void -test_older_time_str_w(void) -{ - struct archive_entry *ae; - struct archive *m; - time_t now, t; - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - - time(&now); - - /* Test1: Allow newer time. */ - assertEqualIntA(m, 0, archive_match_include_date_w(m, - ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME | - ARCHIVE_MATCH_OLDER, L"1980/2/1 0:0:0 UTC")); - - archive_entry_copy_pathname(ae, "file1"); - t = __archive_get_date(now, "1980/2/1 0:0:0 UTC"); - archive_entry_set_mtime(ae, t, 0); - archive_entry_set_ctime(ae, t, 0); - failure("Both Its mtime and ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - t = __archive_get_date(now, "1980/1/1 0:0:0 UTC"); - archive_entry_set_mtime(ae, t, 0); - archive_entry_set_ctime(ae, t, 0); - failure("Both Its mtime and ctime should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - t = __archive_get_date(now, "1980/3/1 0:0:0 UTC"); - archive_entry_set_mtime(ae, t, 0); - archive_entry_set_ctime(ae, t, 0); - failure("Both Its mtime and ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - t = __archive_get_date(now, "1980/3/1 0:0:0 UTC"); - archive_entry_set_mtime(ae, t, 0); - t = __archive_get_date(now, "1980/1/1 0:0:0 UTC"); - archive_entry_set_ctime(ae, t, 0); - failure("Its mtime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - t = __archive_get_date(now, "1980/1/1 0:0:0 UTC"); - archive_entry_set_mtime(ae, t, 0); - t = __archive_get_date(now, "1980/3/1 0:0:0 UTC"); - archive_entry_set_ctime(ae, t, 0); - failure("Its ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Test2: Allow equal or newer time. */ - assertEqualIntA(m, 0, archive_match_include_date_w(m, - ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME | - ARCHIVE_MATCH_OLDER | ARCHIVE_MATCH_EQUAL, - L"1980/2/1 0:0:0 UTC")); - - archive_entry_copy_pathname(ae, "file1"); - t = __archive_get_date(now, "1980/2/1 0:0:0 UTC"); - archive_entry_set_mtime(ae, t, 0); - archive_entry_set_ctime(ae, t, 0); - failure("Both Its mtime and ctime should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - t = __archive_get_date(now, "1980/1/1 0:0:0 UTC"); - archive_entry_set_mtime(ae, t, 0); - archive_entry_set_ctime(ae, t, 0); - failure("Both Its mtime and ctime should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - t = __archive_get_date(now, "1980/3/1 0:0:0 UTC"); - archive_entry_set_mtime(ae, t, 0); - archive_entry_set_ctime(ae, t, 0); - failure("Both Its mtime and ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Clean up. */ - archive_entry_free(ae); - archive_match_free(m); -} - -static void -test_older_mtime_than_file_mbs(void) -{ - struct archive *a; - struct archive_entry *ae; - struct archive *m; - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - if (!assert((a = archive_read_disk_new()) != NULL)) { - archive_match_free(m); - archive_entry_free(ae); - return; - } - - /* - * Test: older mtime than a file specified in MBS file name. - */ - assertEqualIntA(m, 0, archive_match_include_file_time(m, - ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER, "mid_mtime")); - - /* Verify 'old_mtime' file. */ - archive_entry_copy_pathname(ae, "old_mtime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("old_mtime should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - /* Verify 'mid_mtime' file. */ - archive_entry_clear(ae); - archive_entry_copy_pathname(ae, "mid_mtime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("mid_mtime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Verify 'new_mtime' file. */ - archive_entry_clear(ae); - archive_entry_copy_pathname(ae, "new_mtime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("new_mtime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Clean up. */ - archive_read_free(a); - archive_entry_free(ae); - archive_match_free(m); -} - -static void -test_older_ctime_than_file_mbs(void) -{ - struct archive *a; - struct archive_entry *ae; - struct archive *m; - -#if defined(_WIN32) && !defined(__CYGWIN__) - skipping("Can't set ctime on Windows"); - return; -#endif - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - if (!assert((a = archive_read_disk_new()) != NULL)) { - archive_match_free(m); - archive_entry_free(ae); - return; - } - - /* - * Test: older ctime than a file specified in MBS file name. - */ - assertEqualIntA(m, 0, archive_match_include_file_time(m, - ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_OLDER, "mid_ctime")); - - /* Verify 'old_ctime' file. */ - archive_entry_clear(ae); - archive_entry_copy_pathname(ae, "old_ctime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("old_ctime should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - /* Verify 'mid_ctime' file. */ - archive_entry_clear(ae); - archive_entry_copy_pathname(ae, "mid_ctime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("mid_ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Verify 'new_ctime' file. */ - archive_entry_clear(ae); - archive_entry_copy_pathname(ae, "new_ctime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("new_ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Clean up. */ - archive_read_free(a); - archive_entry_free(ae); - archive_match_free(m); -} - -static void -test_older_mtime_than_file_wcs(void) -{ - struct archive *a; - struct archive_entry *ae; - struct archive *m; - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - if (!assert((a = archive_read_disk_new()) != NULL)) { - archive_match_free(m); - archive_entry_free(ae); - return; - } - - /* - * Test: older mtime than a file specified in WCS file name. - */ - assertEqualIntA(m, 0, archive_match_include_file_time_w(m, - ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER, L"mid_mtime")); - - /* Verify 'old_mtime' file. */ - archive_entry_copy_pathname(ae, "old_mtime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("old_mtime should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - /* Verify 'mid_mtime' file. */ - archive_entry_clear(ae); - archive_entry_copy_pathname(ae, "mid_mtime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("mid_mtime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Verify 'new_mtime' file. */ - archive_entry_clear(ae); - archive_entry_copy_pathname(ae, "new_mtime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("new_mtime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Clean up. */ - archive_read_free(a); - archive_entry_free(ae); - archive_match_free(m); -} - -static void -test_older_ctime_than_file_wcs(void) -{ - struct archive *a; - struct archive_entry *ae; - struct archive *m; - -#if defined(_WIN32) && !defined(__CYGWIN__) - skipping("Can't set ctime on Windows"); - return; -#endif - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - if (!assert((a = archive_read_disk_new()) != NULL)) { - archive_match_free(m); - archive_entry_free(ae); - return; - } - - /* - * Test: older ctime than a file specified in WCS file name. - */ - assertEqualIntA(m, 0, archive_match_include_file_time_w(m, - ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_OLDER, L"mid_ctime")); - - /* Verify 'old_ctime' file. */ - archive_entry_clear(ae); - archive_entry_copy_pathname(ae, "old_ctime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("old_ctime should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - /* Verify 'mid_ctime' file. */ - archive_entry_clear(ae); - archive_entry_copy_pathname(ae, "mid_ctime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("mid_ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Verify 'new_ctime' file. */ - archive_entry_clear(ae); - archive_entry_copy_pathname(ae, "new_ctime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("new_ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Clean up. */ - archive_read_free(a); - archive_entry_free(ae); - archive_match_free(m); -} - -static void -test_mtime_between_files_mbs(void) -{ - struct archive *a; - struct archive_entry *ae; - struct archive *m; - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - if (!assert((a = archive_read_disk_new()) != NULL)) { - archive_match_free(m); - archive_entry_free(ae); - return; - } - - /* - * Test: mtime between file specified in MBS file name. - */ - assertEqualIntA(m, 0, archive_match_include_file_time(m, - ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_NEWER, "old_mtime")); - assertEqualIntA(m, 0, archive_match_include_file_time(m, - ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER, "new_mtime")); - - /* Verify 'old_mtime' file. */ - archive_entry_copy_pathname(ae, "old_mtime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("old_mtime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Verify 'mid_mtime' file. */ - archive_entry_clear(ae); - archive_entry_copy_pathname(ae, "mid_mtime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("mid_mtime should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - /* Verify 'new_mtime' file. */ - archive_entry_clear(ae); - archive_entry_copy_pathname(ae, "new_mtime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("new_mtime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Clean up. */ - archive_read_free(a); - archive_entry_free(ae); - archive_match_free(m); -} - -static void -test_mtime_between_files_wcs(void) -{ - struct archive *a; - struct archive_entry *ae; - struct archive *m; - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - if (!assert((a = archive_read_disk_new()) != NULL)) { - archive_match_free(m); - archive_entry_free(ae); - return; - } - - /* - * Test: mtime between file specified in WCS file name. - */ - assertEqualIntA(m, 0, archive_match_include_file_time_w(m, - ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_NEWER, L"old_mtime")); - assertEqualIntA(m, 0, archive_match_include_file_time_w(m, - ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER, L"new_mtime")); - - /* Verify 'old_mtime' file. */ - archive_entry_copy_pathname(ae, "old_mtime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("old_mtime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Verify 'mid_mtime' file. */ - archive_entry_clear(ae); - archive_entry_copy_pathname(ae, "mid_mtime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("mid_mtime should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - /* Verify 'new_mtime' file. */ - archive_entry_clear(ae); - archive_entry_copy_pathname(ae, "new_mtime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("new_mtime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Clean up. */ - archive_read_free(a); - archive_entry_free(ae); - archive_match_free(m); -} - -static void -test_ctime_between_files_mbs(void) -{ - struct archive *a; - struct archive_entry *ae; - struct archive *m; - -#if defined(_WIN32) && !defined(__CYGWIN__) - skipping("Can't set ctime on Windows"); - return; -#endif - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - if (!assert((a = archive_read_disk_new()) != NULL)) { - archive_match_free(m); - archive_entry_free(ae); - return; - } - - /* - * Test: ctime between files specified in MBS file name. - */ - assertEqualIntA(m, 0, archive_match_include_file_time(m, - ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_NEWER, "old_ctime")); - assertEqualIntA(m, 0, archive_match_include_file_time(m, - ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_OLDER, "new_ctime")); - - /* Verify 'old_ctime' file. */ - archive_entry_copy_pathname(ae, "old_ctime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("old_ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Verify 'mid_ctime' file. */ - archive_entry_clear(ae); - archive_entry_copy_pathname(ae, "mid_ctime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("mid_ctime should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - /* Verify 'new_ctime' file. */ - archive_entry_clear(ae); - archive_entry_copy_pathname(ae, "new_ctime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("new_ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Clean up. */ - archive_read_free(a); - archive_entry_free(ae); - archive_match_free(m); -} - -static void -test_ctime_between_files_wcs(void) -{ - struct archive *a; - struct archive_entry *ae; - struct archive *m; - -#if defined(_WIN32) && !defined(__CYGWIN__) - skipping("Can't set ctime on Windows"); - return; -#endif - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - if (!assert((a = archive_read_disk_new()) != NULL)) { - archive_match_free(m); - archive_entry_free(ae); - return; - } - - /* - * Test: ctime between files specified in WCS file name. - */ - assertEqualIntA(m, 0, archive_match_include_file_time_w(m, - ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_NEWER, L"old_ctime")); - assertEqualIntA(m, 0, archive_match_include_file_time_w(m, - ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_OLDER, L"new_ctime")); - - /* Verify 'old_ctime' file. */ - archive_entry_copy_pathname(ae, "old_ctime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("old_ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Verify 'mid_ctime' file. */ - archive_entry_clear(ae); - archive_entry_copy_pathname(ae, "mid_ctime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("mid_ctime should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - /* Verify 'new_ctime' file. */ - archive_entry_clear(ae); - archive_entry_copy_pathname(ae, "new_ctime"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - failure("new_ctime should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* Clean up. */ - archive_read_free(a); - archive_entry_free(ae); - archive_match_free(m); -} - -static void -excluded(struct archive *m) -{ - struct archive_entry *ae; - - if (!assert((ae = archive_entry_new()) != NULL)) - return; - - archive_entry_copy_pathname(ae, "file1"); - archive_entry_set_mtime(ae, 7879, 999); - failure("It should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - archive_entry_set_mtime(ae, 7880, 0); - failure("It should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - archive_entry_set_mtime(ae, 7880, 1); - failure("It should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - archive_entry_copy_pathname(ae, "file2"); - archive_entry_set_mtime(ae, 7879, 999); - failure("It should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - archive_entry_set_mtime(ae, 7880, 0); - failure("It should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - archive_entry_set_mtime(ae, 7880, 1); - failure("It should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - archive_entry_copy_pathname(ae, "file3"); - archive_entry_set_mtime(ae, 7879, 999); - failure("It should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - archive_entry_set_mtime(ae, 7880, 0); - failure("It should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - archive_entry_set_mtime(ae, 7880, 1); - failure("It should be excluded"); - assertEqualInt(1, archive_match_time_excluded(m, ae)); - assertEqualInt(1, archive_match_excluded(m, ae)); - - /* - * "file4" is not registered, that sort of a file should not be - * excluded with any mtime. - */ - archive_entry_copy_pathname(ae, "file4"); - archive_entry_set_mtime(ae, 7879, 999); - failure("It should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - archive_entry_set_mtime(ae, 7880, 0); - failure("It should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - archive_entry_set_mtime(ae, 7880, 1); - failure("It should not be excluded"); - assertEqualInt(0, archive_match_time_excluded(m, ae)); - assertEqualInt(0, archive_match_excluded(m, ae)); - - - /* Clean up. */ - archive_entry_free(ae); -} - -static void -test_pathname_newer_mtime(void) -{ - struct archive_entry *ae; - struct archive *m; - - if (!assert((m = archive_match_new()) != NULL)) - return; - if (!assert((ae = archive_entry_new()) != NULL)) { - archive_match_free(m); - return; - } - - archive_entry_copy_pathname(ae, "file1"); - archive_entry_set_mtime(ae, 7880, 0); - assertEqualIntA(m, 0, archive_match_exclude_entry(m, - ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER | - ARCHIVE_MATCH_EQUAL, ae)); - archive_entry_copy_pathname(ae, "file2"); - archive_entry_set_mtime(ae, 1, 0); - assertEqualIntA(m, 0, archive_match_exclude_entry(m, - ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER | - ARCHIVE_MATCH_EQUAL, ae)); - archive_entry_copy_pathname(ae, "file3"); - archive_entry_set_mtime(ae, 99999, 0); - assertEqualIntA(m, 0, archive_match_exclude_entry(m, - ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER | - ARCHIVE_MATCH_EQUAL, ae)); - - excluded(m); - - /* Clean up. */ - archive_entry_free(ae); - archive_match_free(m); -} - -DEFINE_TEST(test_archive_match_time) -{ - struct stat st; - - /* Test: matching newer times. */ - test_newer_time(); - test_newer_time_str(); - test_newer_time_str_w(); - /* Test: matching older times. */ - test_older_time(); - test_older_time_str(); - test_older_time_str_w(); - - /* - * Create sample files for tests matching mtime. - * ctimes of those files may be all the same or the ctime of - * new_mtime may be older than old_mtime. - */ - assertMakeFile("new_mtime", 0666, "new"); - assertUtimes("new_mtime", 10002, 0, 10002, 0); - assertMakeFile("mid_mtime", 0666, "mid"); - assertUtimes("mid_mtime", 10001, 0, 10001, 0); - assertMakeFile("old_mtime", 0666, "old"); - assertUtimes("old_mtime", 10000, 0, 10000, 0); - - /* - * Create sample files for tests matching ctime. - * the mtime of mid_ctime is older than old_ctime and also the mtime - * of new_ctime is older than both mid_ctime and old_ctime. - */ - assertMakeFile("old_ctime", 0666, "old"); - assertUtimes("old_ctime", 10002, 0, 10002, 0); - assertEqualInt(0, stat("old_ctime", &st)); - sleepUntilAfter(st.st_ctime); - assertMakeFile("mid_ctime", 0666, "mid"); - assertUtimes("mid_ctime", 10001, 0, 10001, 0); - assertEqualInt(0, stat("mid_ctime", &st)); - sleepUntilAfter(st.st_ctime); - assertMakeFile("new_ctime", 0666, "new"); - assertUtimes("new_ctime", 10000, 0, 10000, 0); - - /* - * Test: matching mtime which indicated by files on the disk. - */ - test_newer_mtime_than_file_mbs(); - test_newer_mtime_than_file_wcs(); - test_older_mtime_than_file_mbs(); - test_older_mtime_than_file_wcs(); - test_mtime_between_files_mbs(); - test_mtime_between_files_wcs(); - - /* - * Test: matching ctime which indicated by files on the disk. - */ - test_newer_ctime_than_file_mbs(); - test_newer_ctime_than_file_wcs(); - test_older_ctime_than_file_mbs(); - test_older_ctime_than_file_wcs(); - test_ctime_between_files_mbs(); - test_ctime_between_files_wcs(); - - /* Test: matching both pathname and mtime. */ - test_pathname_newer_mtime(); -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_pathmatch.c b/thirdparty/libarchive/libarchive/test/test_archive_pathmatch.c deleted file mode 100644 index 0116df028..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_pathmatch.c +++ /dev/null @@ -1,289 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -#define __LIBARCHIVE_TEST -#include "archive_pathmatch.h" - -/* - * Verify that the pattern matcher implements the wildcard logic specified - * in SUSv2 for the cpio command. This is essentially the - * shell glob syntax: - * * - matches any sequence of chars, including '/' - * ? - matches any single char, including '/' - * [...] - matches any of a set of chars, '-' specifies a range, - * initial '!' is undefined - * - * The specification in SUSv2 is a bit incomplete, I assume the following: - * Trailing '-' in [...] is not special. - * - * TODO: Figure out if there's a good way to extend this to handle - * Windows paths that use '\' as a path separator. - */ - -DEFINE_TEST(test_archive_pathmatch) -{ - assertEqualInt(1, archive_pathmatch("a/b/c", "a/b/c", 0)); - assertEqualInt(0, archive_pathmatch("a/b/", "a/b/c", 0)); - assertEqualInt(0, archive_pathmatch("a/b", "a/b/c", 0)); - assertEqualInt(0, archive_pathmatch("a/b/c", "a/b/", 0)); - assertEqualInt(0, archive_pathmatch("a/b/c", "a/b", 0)); - - /* Null string and non-empty pattern returns false. */ - assertEqualInt(0, archive_pathmatch("a/b/c", NULL, 0)); - assertEqualInt(0, archive_pathmatch_w(L"a/b/c", NULL, 0)); - - /* Empty pattern only matches empty string. */ - assertEqualInt(1, archive_pathmatch("","", 0)); - assertEqualInt(0, archive_pathmatch("","a", 0)); - assertEqualInt(1, archive_pathmatch("*","", 0)); - assertEqualInt(1, archive_pathmatch("*","a", 0)); - assertEqualInt(1, archive_pathmatch("*","abcd", 0)); - /* SUSv2: * matches / */ - assertEqualInt(1, archive_pathmatch("*","abcd/efgh/ijkl", 0)); - assertEqualInt(1, archive_pathmatch("abcd*efgh/ijkl","abcd/efgh/ijkl", 0)); - assertEqualInt(1, archive_pathmatch("abcd***efgh/ijkl","abcd/efgh/ijkl", 0)); - assertEqualInt(1, archive_pathmatch("abcd***/efgh/ijkl","abcd/efgh/ijkl", 0)); - assertEqualInt(0, archive_pathmatch("?", "", 0)); - assertEqualInt(0, archive_pathmatch("?", "\0", 0)); - assertEqualInt(1, archive_pathmatch("?", "a", 0)); - assertEqualInt(0, archive_pathmatch("?", "ab", 0)); - assertEqualInt(1, archive_pathmatch("?", ".", 0)); - assertEqualInt(1, archive_pathmatch("?", "?", 0)); - assertEqualInt(1, archive_pathmatch("a", "a", 0)); - assertEqualInt(0, archive_pathmatch("a", "ab", 0)); - assertEqualInt(0, archive_pathmatch("a", "ab", 0)); - assertEqualInt(1, archive_pathmatch("a?c", "abc", 0)); - /* SUSv2: ? matches / */ - assertEqualInt(1, archive_pathmatch("a?c", "a/c", 0)); - assertEqualInt(1, archive_pathmatch("a?*c*", "a/c", 0)); - assertEqualInt(1, archive_pathmatch("*a*", "a/c", 0)); - assertEqualInt(1, archive_pathmatch("*a*", "/a/c", 0)); - assertEqualInt(1, archive_pathmatch("*a*", "defaaaaaaa", 0)); - assertEqualInt(0, archive_pathmatch("a*", "defghi", 0)); - assertEqualInt(0, archive_pathmatch("*a*", "defghi", 0)); - - /* Character classes */ - assertEqualInt(1, archive_pathmatch("abc[def", "abc[def", 0)); - assertEqualInt(0, archive_pathmatch("abc[def]", "abc[def", 0)); - assertEqualInt(0, archive_pathmatch("abc[def", "abcd", 0)); - assertEqualInt(1, archive_pathmatch("abc[def]", "abcd", 0)); - assertEqualInt(1, archive_pathmatch("abc[def]", "abce", 0)); - assertEqualInt(1, archive_pathmatch("abc[def]", "abcf", 0)); - assertEqualInt(0, archive_pathmatch("abc[def]", "abcg", 0)); - assertEqualInt(1, archive_pathmatch("abc[d*f]", "abcd", 0)); - assertEqualInt(1, archive_pathmatch("abc[d*f]", "abc*", 0)); - assertEqualInt(0, archive_pathmatch("abc[d*f]", "abcdefghi", 0)); - assertEqualInt(0, archive_pathmatch("abc[d*", "abcdefghi", 0)); - assertEqualInt(1, archive_pathmatch("abc[d*", "abc[defghi", 0)); - assertEqualInt(1, archive_pathmatch("abc[d-f]", "abcd", 0)); - assertEqualInt(1, archive_pathmatch("abc[d-f]", "abce", 0)); - assertEqualInt(1, archive_pathmatch("abc[d-f]", "abcf", 0)); - assertEqualInt(0, archive_pathmatch("abc[d-f]", "abcg", 0)); - assertEqualInt(0, archive_pathmatch("abc[d-fh-k]", "abca", 0)); - assertEqualInt(1, archive_pathmatch("abc[d-fh-k]", "abcd", 0)); - assertEqualInt(1, archive_pathmatch("abc[d-fh-k]", "abce", 0)); - assertEqualInt(1, archive_pathmatch("abc[d-fh-k]", "abcf", 0)); - assertEqualInt(0, archive_pathmatch("abc[d-fh-k]", "abcg", 0)); - assertEqualInt(1, archive_pathmatch("abc[d-fh-k]", "abch", 0)); - assertEqualInt(1, archive_pathmatch("abc[d-fh-k]", "abci", 0)); - assertEqualInt(1, archive_pathmatch("abc[d-fh-k]", "abcj", 0)); - assertEqualInt(1, archive_pathmatch("abc[d-fh-k]", "abck", 0)); - assertEqualInt(0, archive_pathmatch("abc[d-fh-k]", "abcl", 0)); - assertEqualInt(0, archive_pathmatch("abc[d-fh-k]", "abc-", 0)); - - /* [] matches nothing, [!] is the same as ? */ - assertEqualInt(0, archive_pathmatch("abc[]efg", "abcdefg", 0)); - assertEqualInt(0, archive_pathmatch("abc[]efg", "abcqefg", 0)); - assertEqualInt(0, archive_pathmatch("abc[]efg", "abcefg", 0)); - assertEqualInt(1, archive_pathmatch("abc[!]efg", "abcdefg", 0)); - assertEqualInt(1, archive_pathmatch("abc[!]efg", "abcqefg", 0)); - assertEqualInt(0, archive_pathmatch("abc[!]efg", "abcefg", 0)); - - /* I assume: Trailing '-' is non-special. */ - assertEqualInt(0, archive_pathmatch("abc[d-fh-]", "abcl", 0)); - assertEqualInt(1, archive_pathmatch("abc[d-fh-]", "abch", 0)); - assertEqualInt(1, archive_pathmatch("abc[d-fh-]", "abc-", 0)); - assertEqualInt(1, archive_pathmatch("abc[d-fh-]", "abc-", 0)); - - /* ']' can be backslash-quoted within a character class. */ - assertEqualInt(1, archive_pathmatch("abc[\\]]", "abc]", 0)); - assertEqualInt(1, archive_pathmatch("abc[\\]d]", "abc]", 0)); - assertEqualInt(1, archive_pathmatch("abc[\\]d]", "abcd", 0)); - assertEqualInt(1, archive_pathmatch("abc[d\\]]", "abc]", 0)); - assertEqualInt(1, archive_pathmatch("abc[d\\]]", "abcd", 0)); - assertEqualInt(1, archive_pathmatch("abc[d]e]", "abcde]", 0)); - assertEqualInt(1, archive_pathmatch("abc[d\\]e]", "abc]", 0)); - assertEqualInt(0, archive_pathmatch("abc[d\\]e]", "abcd]e", 0)); - assertEqualInt(0, archive_pathmatch("abc[d]e]", "abc]", 0)); - - /* backslash-quoted chars can appear as either end of a range. */ - assertEqualInt(1, archive_pathmatch("abc[\\d-f]gh", "abcegh", 0)); - assertEqualInt(0, archive_pathmatch("abc[\\d-f]gh", "abcggh", 0)); - assertEqualInt(0, archive_pathmatch("abc[\\d-f]gh", "abc\\gh", 0)); - assertEqualInt(1, archive_pathmatch("abc[d-\\f]gh", "abcegh", 0)); - assertEqualInt(1, archive_pathmatch("abc[\\d-\\f]gh", "abcegh", 0)); - assertEqualInt(1, archive_pathmatch("abc[\\d-\\f]gh", "abcegh", 0)); - /* backslash-quoted '-' isn't special. */ - assertEqualInt(0, archive_pathmatch("abc[d\\-f]gh", "abcegh", 0)); - assertEqualInt(1, archive_pathmatch("abc[d\\-f]gh", "abc-gh", 0)); - - /* Leading '!' negates a character class. */ - assertEqualInt(0, archive_pathmatch("abc[!d]", "abcd", 0)); - assertEqualInt(1, archive_pathmatch("abc[!d]", "abce", 0)); - assertEqualInt(1, archive_pathmatch("abc[!d]", "abcc", 0)); - assertEqualInt(0, archive_pathmatch("abc[!d-z]", "abcq", 0)); - assertEqualInt(1, archive_pathmatch("abc[!d-gi-z]", "abch", 0)); - assertEqualInt(1, archive_pathmatch("abc[!fgijkl]", "abch", 0)); - assertEqualInt(0, archive_pathmatch("abc[!fghijkl]", "abch", 0)); - - /* Backslash quotes next character. */ - assertEqualInt(0, archive_pathmatch("abc\\[def]", "abc\\d", 0)); - assertEqualInt(1, archive_pathmatch("abc\\[def]", "abc[def]", 0)); - assertEqualInt(0, archive_pathmatch("abc\\\\[def]", "abc[def]", 0)); - assertEqualInt(0, archive_pathmatch("abc\\\\[def]", "abc\\[def]", 0)); - assertEqualInt(1, archive_pathmatch("abc\\\\[def]", "abc\\d", 0)); - assertEqualInt(1, archive_pathmatch("abcd\\", "abcd\\", 0)); - assertEqualInt(0, archive_pathmatch("abcd\\", "abcd\\[", 0)); - assertEqualInt(0, archive_pathmatch("abcd\\", "abcde", 0)); - assertEqualInt(0, archive_pathmatch("abcd\\[", "abcd\\", 0)); - - /* - * Because '.' and '/' have special meanings, we can - * identify many equivalent paths even if they're expressed - * differently. (But quoting a character with '\\' suppresses - * special meanings!) - */ - assertEqualInt(0, archive_pathmatch("a/b/", "a/bc", 0)); - assertEqualInt(1, archive_pathmatch("a/./b", "a/b", 0)); - assertEqualInt(0, archive_pathmatch("a\\/./b", "a/b", 0)); - assertEqualInt(0, archive_pathmatch("a/\\./b", "a/b", 0)); - assertEqualInt(0, archive_pathmatch("a/.\\/b", "a/b", 0)); - assertEqualInt(0, archive_pathmatch("a\\/\\.\\/b", "a/b", 0)); - assertEqualInt(1, archive_pathmatch("./abc/./def/", "abc/def/", 0)); - assertEqualInt(1, archive_pathmatch("abc/def", "./././abc/./def", 0)); - assertEqualInt(1, archive_pathmatch("abc/def/././//", "./././abc/./def/", 0)); - assertEqualInt(1, archive_pathmatch(".////abc/.//def", "./././abc/./def", 0)); - assertEqualInt(1, archive_pathmatch("./abc?def/", "abc/def/", 0)); - failure("\"?./\" is not the same as \"/./\""); - assertEqualInt(0, archive_pathmatch("./abc?./def/", "abc/def/", 0)); - failure("Trailing '/' should match no trailing '/'"); - assertEqualInt(1, archive_pathmatch("./abc/./def/", "abc/def", 0)); - failure("Trailing '/./' is still the same directory."); - assertEqualInt(1, archive_pathmatch("./abc/./def/./", "abc/def", 0)); - failure("Trailing '/.' is still the same directory."); - assertEqualInt(1, archive_pathmatch("./abc/./def/.", "abc/def", 0)); - assertEqualInt(1, archive_pathmatch("./abc/./def", "abc/def/", 0)); - failure("Trailing '/./' is still the same directory."); - assertEqualInt(1, archive_pathmatch("./abc/./def", "abc/def/./", 0)); - failure("Trailing '/.' is still the same directory."); - assertEqualInt(1, archive_pathmatch("./abc*/./def", "abc/def/.", 0)); - - /* Matches not anchored at beginning. */ - assertEqualInt(0, - archive_pathmatch("bcd", "abcd", PATHMATCH_NO_ANCHOR_START)); - assertEqualInt(1, - archive_pathmatch("abcd", "abcd", PATHMATCH_NO_ANCHOR_START)); - assertEqualInt(0, - archive_pathmatch("^bcd", "abcd", PATHMATCH_NO_ANCHOR_START)); - assertEqualInt(1, - archive_pathmatch("b/c/d", "a/b/c/d", PATHMATCH_NO_ANCHOR_START)); - assertEqualInt(0, - archive_pathmatch("^b/c/d", "a/b/c/d", PATHMATCH_NO_ANCHOR_START)); - assertEqualInt(0, - archive_pathmatch("/b/c/d", "a/b/c/d", PATHMATCH_NO_ANCHOR_START)); - assertEqualInt(0, - archive_pathmatch("a/b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START)); - assertEqualInt(1, - archive_pathmatch("a/b/c/d", "a/b/c/d", PATHMATCH_NO_ANCHOR_START)); - assertEqualInt(0, - archive_pathmatch("b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START)); - assertEqualInt(0, - archive_pathmatch("^b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START)); - - - assertEqualInt(1, - archive_pathmatch("b/c/d", "a/b/c/d", PATHMATCH_NO_ANCHOR_START)); - assertEqualInt(1, - archive_pathmatch("b/c/d", "/a/b/c/d", PATHMATCH_NO_ANCHOR_START)); - - - /* Matches not anchored at end. */ - assertEqualInt(0, - archive_pathmatch("bcd", "abcd", PATHMATCH_NO_ANCHOR_END)); - assertEqualInt(1, - archive_pathmatch("abcd", "abcd", PATHMATCH_NO_ANCHOR_END)); - assertEqualInt(1, - archive_pathmatch("abcd", "abcd/", PATHMATCH_NO_ANCHOR_END)); - assertEqualInt(1, - archive_pathmatch("abcd", "abcd/.", PATHMATCH_NO_ANCHOR_END)); - assertEqualInt(0, - archive_pathmatch("abc", "abcd", PATHMATCH_NO_ANCHOR_END)); - assertEqualInt(1, - archive_pathmatch("a/b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_END)); - assertEqualInt(0, - archive_pathmatch("a/b/c$", "a/b/c/d", PATHMATCH_NO_ANCHOR_END)); - assertEqualInt(1, - archive_pathmatch("a/b/c$", "a/b/c", PATHMATCH_NO_ANCHOR_END)); - assertEqualInt(1, - archive_pathmatch("a/b/c$", "a/b/c/", PATHMATCH_NO_ANCHOR_END)); - assertEqualInt(1, - archive_pathmatch("a/b/c/", "a/b/c/d", PATHMATCH_NO_ANCHOR_END)); - assertEqualInt(0, - archive_pathmatch("a/b/c/$", "a/b/c/d", PATHMATCH_NO_ANCHOR_END)); - assertEqualInt(1, - archive_pathmatch("a/b/c/$", "a/b/c/", PATHMATCH_NO_ANCHOR_END)); - assertEqualInt(1, - archive_pathmatch("a/b/c/$", "a/b/c", PATHMATCH_NO_ANCHOR_END)); - assertEqualInt(0, - archive_pathmatch("b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_END)); - - /* Matches not anchored at either end. */ - assertEqualInt(1, - archive_pathmatch("b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END)); - assertEqualInt(0, - archive_pathmatch("/b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END)); - assertEqualInt(0, - archive_pathmatch("/a/b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END)); - assertEqualInt(1, - archive_pathmatch("/a/b/c", "/a/b/c/d", PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END)); - assertEqualInt(0, - archive_pathmatch("/a/b/c$", "a/b/c/d", PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END)); - assertEqualInt(0, - archive_pathmatch("/a/b/c/d$", "a/b/c/d", PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END)); - assertEqualInt(0, - archive_pathmatch("/a/b/c/d$", "/a/b/c/d/e", PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END)); - assertEqualInt(1, - archive_pathmatch("/a/b/c/d$", "/a/b/c/d", PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END)); - assertEqualInt(1, - archive_pathmatch("^a/b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END)); - assertEqualInt(0, - archive_pathmatch("^a/b/c$", "a/b/c/d", PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END)); - assertEqualInt(0, - archive_pathmatch("a/b/c$", "a/b/c/d", PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END)); - assertEqualInt(1, - archive_pathmatch("b/c/d$", "a/b/c/d", PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_read_add_passphrase.c b/thirdparty/libarchive/libarchive/test/test_archive_read_add_passphrase.c deleted file mode 100644 index 0ce5a76ae..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_read_add_passphrase.c +++ /dev/null @@ -1,260 +0,0 @@ -/*- - * Copyright (c) 2011 Tim Kientzle - * Copyright (c) 2014 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -struct archive_read; -extern void __archive_read_reset_passphrase(struct archive_read *); -extern const char * __archive_read_next_passphrase(struct archive_read *); - -static void -test(int pristine) -{ - struct archive* a = archive_read_new(); - - if (!pristine) { - archive_read_support_filter_all(a); - archive_read_support_format_all(a); - } - - assertEqualInt(ARCHIVE_OK, archive_read_add_passphrase(a, "pass1")); - /* An empty passphrase cannot be accepted. */ - assertEqualInt(ARCHIVE_FAILED, archive_read_add_passphrase(a, "")); - /* NULL passphrases cannot be accepted. */ - assertEqualInt(ARCHIVE_FAILED, archive_read_add_passphrase(a, NULL)); - - archive_read_free(a); -} - -DEFINE_TEST(test_archive_read_add_passphrase) -{ - test(1); - test(0); -} - -DEFINE_TEST(test_archive_read_add_passphrase_incorrect_sequance) -{ - struct archive* a = archive_read_new(); - struct archive_read *ar = (struct archive_read *)a; - - assertEqualInt(ARCHIVE_OK, archive_read_add_passphrase(a, "pass1")); - - /* No call of __archive_read_reset_passphrase() leads to - * get NULL even if a user has passed a passphrases. */ - assertEqualString(NULL, __archive_read_next_passphrase(ar)); - - archive_read_free(a); -} - -DEFINE_TEST(test_archive_read_add_passphrase_single) -{ - struct archive* a = archive_read_new(); - struct archive_read *ar = (struct archive_read *)a; - - assertEqualInt(ARCHIVE_OK, archive_read_add_passphrase(a, "pass1")); - - __archive_read_reset_passphrase(ar); - /* Fist call, we should get "pass1" as a passphrase. */ - assertEqualString("pass1", __archive_read_next_passphrase(ar)); - /* Second call, we should get NULL which means all the passphrases - * are passed already. */ - assertEqualString(NULL, __archive_read_next_passphrase(ar)); - - archive_read_free(a); -} - -DEFINE_TEST(test_archive_read_add_passphrase_multiple) -{ - struct archive* a = archive_read_new(); - struct archive_read *ar = (struct archive_read *)a; - - assertEqualInt(ARCHIVE_OK, archive_read_add_passphrase(a, "pass1")); - assertEqualInt(ARCHIVE_OK, archive_read_add_passphrase(a, "pass2")); - - __archive_read_reset_passphrase(ar); - /* Fist call, we should get "pass1" as a passphrase. */ - assertEqualString("pass1", __archive_read_next_passphrase(ar)); - /* Second call, we should get "pass2" as a passphrase. */ - assertEqualString("pass2", __archive_read_next_passphrase(ar)); - /* Third call, we should get NULL which means all the passphrases - * are passed already. */ - assertEqualString(NULL, __archive_read_next_passphrase(ar)); - - archive_read_free(a); -} - -static const char * -callback1(struct archive *a, void *_client_data) -{ - (void)a; /* UNUSED */ - (void)_client_data; /* UNUSED */ - return ("passCallBack"); -} - -DEFINE_TEST(test_archive_read_add_passphrase_set_callback1) -{ - struct archive* a = archive_read_new(); - struct archive_read *ar = (struct archive_read *)a; - - assertEqualInt(ARCHIVE_OK, - archive_read_set_passphrase_callback(a, NULL, callback1)); - - __archive_read_reset_passphrase(ar); - /* Fist call, we should get "passCallBack" as a passphrase. */ - assertEqualString("passCallBack", __archive_read_next_passphrase(ar)); - /* Second call, we still get "passCallBack" as a passphrase. */ - assertEqualString("passCallBack", __archive_read_next_passphrase(ar)); - - archive_read_free(a); - - /* Without __archive_read_reset_passphrase call, the callback - * should work fine. */ - a = archive_read_new(); - ar = (struct archive_read *)a; - assertEqualInt(ARCHIVE_OK, - archive_read_set_passphrase_callback(a, NULL, callback1)); - /* Fist call, we should get "passCallBack" as a passphrase. */ - assertEqualString("passCallBack", __archive_read_next_passphrase(ar)); - /* Second call, we still get "passCallBack" as a passphrase. */ - assertEqualString("passCallBack", __archive_read_next_passphrase(ar)); - - archive_read_free(a); -} - -static const char * -callback2(struct archive *a, void *_client_data) -{ - int *cd = (int *)_client_data; - - (void)a; /* UNUSED */ - - if (*cd == 0) { - *cd = 1; - return ("passCallBack"); - } - return (NULL); -} - -DEFINE_TEST(test_archive_read_add_passphrase_set_callback2) -{ - struct archive* a = archive_read_new(); - struct archive_read *ar = (struct archive_read *)a; - int client_data = 0; - - assertEqualInt(ARCHIVE_OK, - archive_read_set_passphrase_callback(a, &client_data, callback2)); - - __archive_read_reset_passphrase(ar); - /* Fist call, we should get "passCallBack" as a passphrase. */ - assertEqualString("passCallBack", __archive_read_next_passphrase(ar)); - /* Second call, we should get NULL which means all the passphrases - * are passed already. */ - assertEqualString(NULL, __archive_read_next_passphrase(ar)); - - archive_read_free(a); -} - -DEFINE_TEST(test_archive_read_add_passphrase_set_callback3) -{ - struct archive* a = archive_read_new(); - struct archive_read *ar = (struct archive_read *)a; - int client_data = 0; - - assertEqualInt(ARCHIVE_OK, - archive_read_set_passphrase_callback(a, &client_data, callback2)); - - __archive_read_reset_passphrase(ar); - /* Fist call, we should get "passCallBack" as a passphrase. */ - assertEqualString("passCallBack", __archive_read_next_passphrase(ar)); - __archive_read_reset_passphrase(ar); - /* After reset passphrase, we should get "passCallBack" passphrase. */ - assertEqualString("passCallBack", __archive_read_next_passphrase(ar)); - /* Second call, we should get NULL which means all the passphrases - * are passed already. */ - assertEqualString(NULL, __archive_read_next_passphrase(ar)); - - archive_read_free(a); -} - -DEFINE_TEST(test_archive_read_add_passphrase_multiple_with_callback) -{ - struct archive* a = archive_read_new(); - struct archive_read *ar = (struct archive_read *)a; - int client_data = 0; - - assertEqualInt(ARCHIVE_OK, archive_read_add_passphrase(a, "pass1")); - assertEqualInt(ARCHIVE_OK, archive_read_add_passphrase(a, "pass2")); - assertEqualInt(ARCHIVE_OK, - archive_read_set_passphrase_callback(a, &client_data, callback2)); - - __archive_read_reset_passphrase(ar); - /* Fist call, we should get "pass1" as a passphrase. */ - assertEqualString("pass1", __archive_read_next_passphrase(ar)); - /* Second call, we should get "pass2" as a passphrase. */ - assertEqualString("pass2", __archive_read_next_passphrase(ar)); - /* Third call, we should get "passCallBack" as a passphrase. */ - assertEqualString("passCallBack", __archive_read_next_passphrase(ar)); - /* Fourth call, we should get NULL which means all the passphrases - * are passed already. */ - assertEqualString(NULL, __archive_read_next_passphrase(ar)); - - archive_read_free(a); -} - -DEFINE_TEST(test_archive_read_add_passphrase_multiple_with_callback2) -{ - struct archive* a = archive_read_new(); - struct archive_read *ar = (struct archive_read *)a; - int client_data = 0; - - assertEqualInt(ARCHIVE_OK, archive_read_add_passphrase(a, "pass1")); - assertEqualInt(ARCHIVE_OK, archive_read_add_passphrase(a, "pass2")); - assertEqualInt(ARCHIVE_OK, - archive_read_set_passphrase_callback(a, &client_data, callback2)); - - __archive_read_reset_passphrase(ar); - /* Fist call, we should get "pass1" as a passphrase. */ - assertEqualString("pass1", __archive_read_next_passphrase(ar)); - /* Second call, we should get "pass2" as a passphrase. */ - assertEqualString("pass2", __archive_read_next_passphrase(ar)); - /* Third call, we should get "passCallBack" as a passphrase. */ - assertEqualString("passCallBack", __archive_read_next_passphrase(ar)); - - __archive_read_reset_passphrase(ar); - /* After reset passphrase, we should get "passCallBack" passphrase. */ - assertEqualString("passCallBack", __archive_read_next_passphrase(ar)); - /* Second call, we should get "pass1" as a passphrase. */ - assertEqualString("pass1", __archive_read_next_passphrase(ar)); - /* Third call, we should get "passCallBack" as a passphrase. */ - assertEqualString("pass2", __archive_read_next_passphrase(ar)); - /* Fourth call, we should get NULL which means all the passphrases - * are passed already. */ - assertEqualString(NULL, __archive_read_next_passphrase(ar)); - - archive_read_free(a); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_archive_read_close_twice.c b/thirdparty/libarchive/libarchive/test/test_archive_read_close_twice.c deleted file mode 100644 index 16cc805fe..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_read_close_twice.c +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * Copyright (c) 2003-2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - - -DEFINE_TEST(test_archive_read_close_twice) -{ - struct archive* a = archive_read_new(); - - assertEqualInt(0, archive_read_close(a)); - assertEqualInt(0, archive_errno(a)); - assertEqualString(NULL, archive_error_string(a)); - - assertEqualInt(0, archive_read_close(a)); - assertEqualInt(0, archive_errno(a)); - assertEqualString(NULL, archive_error_string(a)); - - archive_read_free(a); -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_read_close_twice_open_fd.c b/thirdparty/libarchive/libarchive/test/test_archive_read_close_twice_open_fd.c deleted file mode 100644 index 3aba31791..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_read_close_twice_open_fd.c +++ /dev/null @@ -1,47 +0,0 @@ -/*- - * Copyright (c) 2011 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_archive_read_close_twice_open_fd) -{ - struct archive* a = archive_read_new(); - - assertEqualInt(ARCHIVE_OK, archive_read_support_format_empty(a)); - assertEqualInt(ARCHIVE_OK, archive_read_open_fd(a, 0, 0)); - assertEqualInt(0, archive_errno(a)); - assertEqualString(NULL, archive_error_string(a)); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(0, archive_errno(a)); - assertEqualString(NULL, archive_error_string(a)); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(0, archive_errno(a)); - assertEqualString(NULL, archive_error_string(a)); - - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_read_close_twice_open_filename.c b/thirdparty/libarchive/libarchive/test/test_archive_read_close_twice_open_filename.c deleted file mode 100644 index 9a194fdc4..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_read_close_twice_open_filename.c +++ /dev/null @@ -1,49 +0,0 @@ -/*- - * Copyright (c) 2011 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_archive_read_close_twice_open_filename) -{ - const char *filename = "empty.file"; - struct archive* a = archive_read_new(); - - assertMakeFile(filename, 0644, ""); - assertEqualInt(ARCHIVE_OK, archive_read_support_format_empty(a)); - assertEqualInt(ARCHIVE_OK, archive_read_open_filename(a, filename, 0)); - assertEqualInt(0, archive_errno(a)); - assertEqualString(NULL, archive_error_string(a)); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(0, archive_errno(a)); - assertEqualString(NULL, archive_error_string(a)); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(0, archive_errno(a)); - assertEqualString(NULL, archive_error_string(a)); - - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_read_multiple_data_objects.c b/thirdparty/libarchive/libarchive/test/test_archive_read_multiple_data_objects.c deleted file mode 100644 index 9962cf7fd..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_read_multiple_data_objects.c +++ /dev/null @@ -1,372 +0,0 @@ -/*- - * Copyright (c) 2011 Tim Kientzle - * Copyright (c) 2011-2012 Andres Mejia - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -#if defined(_WIN32) && !defined(__CYGWIN__) -#define open _open -#define close _close -#define read _read -#if !defined(__BORLANDC__) -#ifdef lseek -#undef lseek -#endif -#define lseek(f, o, w) _lseek(f, (long)(o), (int)(w)) -#endif -#endif - -static void -test_splitted_file(void) -{ - char buff[64]; - static const char *reffiles[] = - { - "test_read_splitted_rar_aa", - "test_read_splitted_rar_ab", - "test_read_splitted_rar_ac", - "test_read_splitted_rar_ad", - NULL - }; - const char test_txt[] = "test text document\r\n"; - int size = sizeof(test_txt)-1; - struct archive_entry *ae; - struct archive *a; - - extract_reference_files(reffiles); - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_open_filenames(a, reffiles, 10240)); - - /* First header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.txt", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(20, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertA(size == archive_read_data(a, buff, size)); - assertEqualMem(buff, test_txt, size); - - /* Second header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testlink", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(41471, archive_entry_mode(ae)); - assertEqualString("test.txt", archive_entry_symlink(ae)); - assertEqualIntA(a, 0, archive_read_data(a, buff, sizeof(buff))); - - /* Third header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testdir/test.txt", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(20, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertA(size == archive_read_data(a, buff, size)); - assertEqualMem(buff, test_txt, size); - - /* Fourth header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testdir", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(16877, archive_entry_mode(ae)); - - /* Fifth header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testemptydir", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(16877, archive_entry_mode(ae)); - - /* Test EOF */ - assertA(1 == archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_file_count(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -static void -test_large_splitted_file(void) -{ - static const char *reffiles[] = - { - "test_read_large_splitted_rar_aa", - "test_read_large_splitted_rar_ab", - "test_read_large_splitted_rar_ac", - "test_read_large_splitted_rar_ad", - "test_read_large_splitted_rar_ae", - NULL - }; - const char test_txt[] = "gin-bottom: 0in\">
    \n

    \n\n"; - int size = 241647978, offset = 0; - char buff[64]; - struct archive_entry *ae; - struct archive *a; - - extract_reference_files(reffiles); - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_open_filenames(a, reffiles, 10240)); - - /* First header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("ppmd_lzss_conversion_test.txt", - archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(size, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - while (offset + (int)sizeof(buff) < size) - { - assertA(sizeof(buff) == archive_read_data(a, buff, sizeof(buff))); - offset += sizeof(buff); - } - assertA(size - offset == archive_read_data(a, buff, size - offset)); - assertEqualMem(buff, test_txt, size - offset); - - /* Test EOF */ - assertA(1 == archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_file_count(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -#define BLOCK_SIZE 10240 -struct mydata { - char *filename; - void *buffer; - int fd; -}; - -static int -file_open(struct archive *a, void *data) -{ - struct mydata *mydata = (struct mydata *)data; - (void)a; - if (mydata->fd < 0) - { - mydata->fd = open(mydata->filename, O_RDONLY | O_BINARY); - if (mydata->fd >= 0) - { - if ((mydata->buffer = (void*)calloc(1, BLOCK_SIZE)) == NULL) - return (ARCHIVE_FAILED); - } - } - return (ARCHIVE_OK); -} -static ssize_t -file_read(struct archive *a, void *data, const void **buff) -{ - struct mydata *mydata = (struct mydata *)data; - (void)a; - *buff = mydata->buffer; - return read(mydata->fd, mydata->buffer, BLOCK_SIZE); -} -static int64_t -file_skip(struct archive *a, void *data, int64_t request) -{ - struct mydata *mydata = (struct mydata *)data; - int64_t result = lseek(mydata->fd, SEEK_CUR, request); - if (result >= 0) - return result; - archive_set_error(a, errno, "Error seeking in '%s'", mydata->filename); - return -1; -} -static int -file_switch(struct archive *a, void *data1, void *data2) -{ - struct mydata *mydata1 = (struct mydata *)data1; - struct mydata *mydata2 = (struct mydata *)data2; - int r = (ARCHIVE_OK); - - (void)a; - if (mydata1 && mydata1->fd >= 0) - { - close(mydata1->fd); - free(mydata1->buffer); - mydata1->buffer = NULL; - mydata1->fd = -1; - } - if (mydata2) - { - r = file_open(a, mydata2); - } - return (r); -} -static int -file_close(struct archive *a, void *data) -{ - struct mydata *mydata = (struct mydata *)data; - if (mydata == NULL) - return (ARCHIVE_FATAL); - file_switch(a, mydata, NULL); - free(mydata->filename); - free(mydata); - return (ARCHIVE_OK); -} -static int64_t -file_seek(struct archive *a, void *data, int64_t request, int whence) -{ - struct mydata *mine = (struct mydata *)data; - int64_t r; - - (void)a; - r = lseek(mine->fd, request, whence); - if (r >= 0) - return r; - return (ARCHIVE_FATAL); -} - -static void -test_customized_multiple_data_objects(void) -{ - char buff[64]; - static const char *reffiles[] = - { - "test_read_splitted_rar_aa", - "test_read_splitted_rar_ab", - "test_read_splitted_rar_ac", - "test_read_splitted_rar_ad", - NULL - }; - const char test_txt[] = "test text document\r\n"; - int size = sizeof(test_txt)-1; - struct archive_entry *ae; - struct archive *a; - struct mydata *mydata; - const char *filename = *reffiles; - int i; - - extract_reference_files(reffiles); - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_support_format_all(a)); - - for (i = 0; filename != NULL;) - { - assert((mydata = (struct mydata *)calloc(1, sizeof(*mydata))) != NULL); - if (mydata == NULL) { - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - assert((mydata->filename = - (char *)calloc(1, strlen(filename) + 1)) != NULL); - if (mydata->filename == NULL) { - free(mydata); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - strcpy(mydata->filename, filename); - mydata->fd = -1; - filename = reffiles[++i]; - assertA(0 == archive_read_append_callback_data(a, mydata)); - } - assertA(0 == archive_read_set_open_callback(a, file_open)); - assertA(0 == archive_read_set_read_callback(a, file_read)); - assertA(0 == archive_read_set_skip_callback(a, file_skip)); - assertA(0 == archive_read_set_close_callback(a, file_close)); - assertA(0 == archive_read_set_switch_callback(a, file_switch)); - assertA(0 == archive_read_set_seek_callback(a, file_seek)); - assertA(0 == archive_read_open1(a)); - - /* First header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.txt", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(20, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertA(size == archive_read_data(a, buff, size)); - assertEqualMem(buff, test_txt, size); - - /* Second header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testlink", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(41471, archive_entry_mode(ae)); - assertEqualString("test.txt", archive_entry_symlink(ae)); - assertEqualIntA(a, 0, archive_read_data(a, buff, sizeof(buff))); - - /* Third header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testdir/test.txt", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(20, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertA(size == archive_read_data(a, buff, size)); - assertEqualMem(buff, test_txt, size); - - /* Fourth header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testdir", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(16877, archive_entry_mode(ae)); - - /* Fifth header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testemptydir", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(16877, archive_entry_mode(ae)); - - /* Test EOF */ - assertA(1 == archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_file_count(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_archive_read_multiple_data_objects) -{ - test_splitted_file(); - test_large_splitted_file(); - test_customized_multiple_data_objects(); -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_read_next_header_empty.c b/thirdparty/libarchive/libarchive/test/test_archive_read_next_header_empty.c deleted file mode 100644 index f43cbd934..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_read_next_header_empty.c +++ /dev/null @@ -1,125 +0,0 @@ -/*- - * Copyright (c) 2003-2011 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -static void -test_empty_file1(void) -{ - struct archive* a = archive_read_new(); - - /* Try opening an empty file with the raw handler. */ - assertEqualInt(ARCHIVE_OK, archive_read_support_format_raw(a)); - assertEqualInt(0, archive_errno(a)); - assertEqualString(NULL, archive_error_string(a)); - - /* Raw handler doesn't support empty files. */ - assertEqualInt(ARCHIVE_FATAL, archive_read_open_filename(a, "emptyfile", 0)); - assert(NULL != archive_error_string(a)); - - archive_read_free(a); -} - -static void -test_empty_file2_check(struct archive* a) -{ - struct archive_entry* e; - assertEqualInt(0, archive_errno(a)); - assertEqualString(NULL, archive_error_string(a)); - - assertEqualInt(ARCHIVE_OK, archive_read_open_filename(a, "emptyfile", 0)); - assertEqualInt(0, archive_errno(a)); - assertEqualString(NULL, archive_error_string(a)); - - assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &e)); - assertEqualInt(0, archive_errno(a)); - assertEqualString(NULL, archive_error_string(a)); - - archive_read_free(a); -} - -static void -test_empty_file2(void) -{ - struct archive* a = archive_read_new(); - - /* Try opening an empty file with raw and empty handlers. */ - assertEqualInt(ARCHIVE_OK, archive_read_support_format_raw(a)); - assertEqualInt(ARCHIVE_OK, archive_read_support_format_empty(a)); - test_empty_file2_check(a); - - a = archive_read_new(); - assertEqualInt(ARCHIVE_OK, archive_read_support_format_by_code(a, ARCHIVE_FORMAT_EMPTY)); - test_empty_file2_check(a); - - a = archive_read_new(); - assertEqualInt(ARCHIVE_OK, archive_read_set_format(a, ARCHIVE_FORMAT_EMPTY)); - test_empty_file2_check(a); -} - -static void -test_empty_tarfile(void) -{ - struct archive* a = archive_read_new(); - struct archive_entry* e; - - /* Try opening an empty file with raw and empty handlers. */ - assertEqualInt(ARCHIVE_OK, archive_read_support_format_tar(a)); - assertEqualInt(0, archive_errno(a)); - assertEqualString(NULL, archive_error_string(a)); - - assertEqualInt(ARCHIVE_OK, archive_read_open_filename(a, "empty.tar", 0)); - assertEqualInt(0, archive_errno(a)); - assertEqualString(NULL, archive_error_string(a)); - - assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &e)); - assertEqualInt(0, archive_errno(a)); - assertEqualString(NULL, archive_error_string(a)); - - archive_read_free(a); -} - -/* 512 zero bytes. */ -static char nulls[512]; - -DEFINE_TEST(test_archive_read_next_header_empty) -{ - FILE *f; - - /* Create an empty file. */ - f = fopen("emptyfile", "wb"); - fclose(f); - - /* Create a file with 512 zero bytes. */ - f = fopen("empty.tar", "wb"); - assertEqualInt(512, fwrite(nulls, 1, 512, f)); - fclose(f); - - test_empty_file1(); - test_empty_file2(); - test_empty_tarfile(); - -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_read_next_header_raw.c b/thirdparty/libarchive/libarchive/test/test_archive_read_next_header_raw.c deleted file mode 100644 index 1c8af20f8..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_read_next_header_raw.c +++ /dev/null @@ -1,65 +0,0 @@ -/*- - * Copyright (c) 2011 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -#define DATA "random garbage for testing purposes" - -static const char data[sizeof(DATA)] = DATA; - -static void -test(int skip_explicitely) -{ - struct archive* a = archive_read_new(); - struct archive_entry* e; - - assertEqualInt(ARCHIVE_OK, archive_read_support_format_raw(a)); - assertEqualInt(0, archive_errno(a)); - assertEqualString(NULL, archive_error_string(a)); - - assertEqualInt(ARCHIVE_OK, archive_read_open_memory(a, - (void *)(uintptr_t) data, sizeof(data))); - assertEqualString(NULL, archive_error_string(a)); - - assertEqualInt(ARCHIVE_OK, archive_read_next_header(a, &e)); - assertEqualInt(0, archive_errno(a)); - assertEqualString(NULL, archive_error_string(a)); - - if (skip_explicitely) - assertEqualInt(ARCHIVE_OK, archive_read_data_skip(a)); - - assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &e)); - assertEqualInt(0, archive_errno(a)); - assertEqualString(NULL, archive_error_string(a)); - - archive_read_free(a); -} - -DEFINE_TEST(test_archive_read_next_header_raw) -{ - test(1); - test(0); -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_read_open2.c b/thirdparty/libarchive/libarchive/test/test_archive_read_open2.c deleted file mode 100644 index 0a801ac5d..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_read_open2.c +++ /dev/null @@ -1,109 +0,0 @@ -/*- - * Copyright (c) 2011 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -static int -open_cb(struct archive *a, void *client) -{ - (void)a; /* UNUSED */ - (void)client; /* UNUSED */ - return 0; -} -static ssize_t -read_cb(struct archive *a, void *client, const void **buff) -{ - (void)a; /* UNUSED */ - (void)client; /* UNUSED */ - (void)buff; /* UNUSED */ - return (ssize_t)0; -} -static int64_t -skip_cb(struct archive *a, void *client, int64_t request) -{ - (void)a; /* UNUSED */ - (void)client; /* UNUSED */ - (void)request; /* UNUSED */ - return (int64_t)0; -} -static int -close_cb(struct archive *a, void *client) -{ - (void)a; /* UNUSED */ - (void)client; /* UNUSED */ - return 0; -} - -static void -test(int formatted, archive_open_callback *o, archive_read_callback *r, - archive_skip_callback *s, archive_close_callback *c, - int rv, const char *msg) -{ - struct archive* a = archive_read_new(); - if (formatted) - assertEqualInt(ARCHIVE_OK, - archive_read_support_format_empty(a)); - assertEqualInt(rv, - archive_read_open2(a, NULL, o, r, s, c)); - assertEqualString(msg, archive_error_string(a)); - archive_read_free(a); -} - -DEFINE_TEST(test_archive_read_open2) -{ - const char *no_reader = - "No reader function provided to archive_read_open"; - const char *no_formats = "No formats registered"; - - test(1, NULL, NULL, NULL, NULL, - ARCHIVE_FATAL, no_reader); - test(1, open_cb, NULL, NULL, NULL, - ARCHIVE_FATAL, no_reader); - test(1, open_cb, read_cb, NULL, NULL, - ARCHIVE_OK, NULL); - test(1, open_cb, read_cb, skip_cb, NULL, - ARCHIVE_OK, NULL); - test(1, open_cb, read_cb, skip_cb, close_cb, - ARCHIVE_OK, NULL); - test(1, NULL, read_cb, skip_cb, close_cb, - ARCHIVE_OK, NULL); - test(1, open_cb, read_cb, skip_cb, NULL, - ARCHIVE_OK, NULL); - test(1, NULL, read_cb, skip_cb, NULL, - ARCHIVE_OK, NULL); - test(1, NULL, read_cb, NULL, NULL, - ARCHIVE_OK, NULL); - - test(0, NULL, NULL, NULL, NULL, - ARCHIVE_FATAL, no_reader); - test(0, open_cb, NULL, NULL, NULL, - ARCHIVE_FATAL, no_reader); - test(0, open_cb, read_cb, NULL, NULL, - ARCHIVE_FATAL, no_formats); - test(0, open_cb, read_cb, skip_cb, NULL, - ARCHIVE_FATAL, no_formats); - test(0, open_cb, read_cb, skip_cb, close_cb, - ARCHIVE_FATAL, no_formats); -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_read_set_filter_option.c b/thirdparty/libarchive/libarchive/test/test_archive_read_set_filter_option.c deleted file mode 100644 index 31d575fc7..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_read_set_filter_option.c +++ /dev/null @@ -1,55 +0,0 @@ -/*- - * Copyright (c) 2011 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -#define should(__a, __code, __m, __o, __v) \ -assertEqualInt(__code, archive_read_set_filter_option(__a, __m, __o, __v)) - -static void -test(int pristine) -{ - struct archive* a = archive_read_new(); - - if (!pristine) - archive_read_support_filter_all(a); - - should(a, ARCHIVE_OK, NULL, NULL, NULL); - should(a, ARCHIVE_OK, "", "", ""); - - should(a, ARCHIVE_FAILED, NULL, "fubar", NULL); - should(a, ARCHIVE_FAILED, NULL, "fubar", "snafu"); - should(a, ARCHIVE_FAILED, "fubar", "snafu", NULL); - should(a, ARCHIVE_FAILED, "fubar", "snafu", "betcha"); - - archive_read_free(a); -} - -DEFINE_TEST(test_archive_read_set_filter_option) -{ - test(1); - test(0); -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_read_set_format_option.c b/thirdparty/libarchive/libarchive/test/test_archive_read_set_format_option.c deleted file mode 100644 index 2d7acf3a0..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_read_set_format_option.c +++ /dev/null @@ -1,67 +0,0 @@ -/*- - * Copyright (c) 2011 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -#define should(__a, __code, __m, __o, __v) \ -assertEqualInt(__code, archive_read_set_format_option(__a, __m, __o, __v)) - -static void -test(int pristine) -{ - struct archive* a = archive_read_new(); - int known_option_rv = pristine ? ARCHIVE_FAILED : ARCHIVE_OK; - - if (!pristine) - archive_read_support_format_all(a); - - /* NULL and "" denote `no option', so they're ok no matter - * what, if any, formats are registered */ - should(a, ARCHIVE_OK, NULL, NULL, NULL); - should(a, ARCHIVE_OK, "", "", ""); - - /* unknown modules and options */ - should(a, ARCHIVE_FAILED, "fubar", "snafu", NULL); - should(a, ARCHIVE_FAILED, "fubar", "snafu", "betcha"); - - /* unknown modules and options */ - should(a, ARCHIVE_FAILED, NULL, "snafu", NULL); - should(a, ARCHIVE_FAILED, NULL, "snafu", "betcha"); - - /* ARCHIVE_OK with iso9660 loaded, ARCHIVE_WARN otherwise */ - should(a, known_option_rv, "iso9660", "joliet", NULL); - should(a, known_option_rv, "iso9660", "joliet", NULL); - should(a, known_option_rv, NULL, "joliet", NULL); - should(a, known_option_rv, NULL, "joliet", NULL); - - archive_read_free(a); -} - -DEFINE_TEST(test_archive_read_set_format_option) -{ - test(1); - test(0); -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_read_set_option.c b/thirdparty/libarchive/libarchive/test/test_archive_read_set_option.c deleted file mode 100644 index 0b816b7cd..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_read_set_option.c +++ /dev/null @@ -1,69 +0,0 @@ -/*- - * Copyright (c) 2011 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -#define should(__a, __code, __m, __o, __v) \ -assertEqualInt(__code, archive_read_set_option(__a, __m, __o, __v)) - -static void -test(int pristine) -{ - struct archive* a = archive_read_new(); - int known_option_rv = pristine ? ARCHIVE_FAILED : ARCHIVE_OK; - - if (!pristine) { - archive_read_support_filter_all(a); - archive_read_support_format_all(a); - } - - /* NULL and "" denote `no option', so they're ok no matter - * what, if any, formats are registered */ - should(a, ARCHIVE_OK, NULL, NULL, NULL); - should(a, ARCHIVE_OK, "", "", ""); - - /* unknown modules and options */ - should(a, ARCHIVE_FAILED, "fubar", "snafu", NULL); - should(a, ARCHIVE_FAILED, "fubar", "snafu", "betcha"); - - /* unknown modules and options */ - should(a, ARCHIVE_FAILED, NULL, "snafu", NULL); - should(a, ARCHIVE_FAILED, NULL, "snafu", "betcha"); - - /* ARCHIVE_OK with iso9660 loaded, ARCHIVE_WARN otherwise */ - should(a, known_option_rv, "iso9660", "joliet", NULL); - should(a, known_option_rv, "iso9660", "joliet", NULL); - should(a, known_option_rv, NULL, "joliet", NULL); - should(a, known_option_rv, NULL, "joliet", NULL); - - archive_read_free(a); -} - -DEFINE_TEST(test_archive_read_set_option) -{ - test(1); - test(0); -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_read_set_options.c b/thirdparty/libarchive/libarchive/test/test_archive_read_set_options.c deleted file mode 100644 index a8c68d7dd..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_read_set_options.c +++ /dev/null @@ -1,126 +0,0 @@ -/*- - * Copyright (c) 2011 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -#define should(__a, __code, __opts) \ -assertEqualInt(__code, archive_read_set_options(__a, __opts)) - -static void -test(int pristine) -{ - struct archive* a = archive_read_new(); - int halfempty_options_rv = pristine ? ARCHIVE_FAILED : ARCHIVE_OK; - int known_option_rv = pristine ? ARCHIVE_FAILED : ARCHIVE_OK; - - if (!pristine) { - archive_read_support_filter_all(a); - archive_read_support_format_all(a); - } - - /* NULL and "" denote `no option', so they're ok no matter - * what, if any, formats are registered */ - should(a, ARCHIVE_OK, NULL); - should(a, ARCHIVE_OK, ""); - - /* unknown modules and options */ - should(a, ARCHIVE_FAILED, "fubar:snafu"); - assertEqualString("Unknown module name: `fubar'", - archive_error_string(a)); - should(a, ARCHIVE_FAILED, "fubar:snafu=betcha"); - assertEqualString("Unknown module name: `fubar'", - archive_error_string(a)); - - /* unknown modules and options */ - should(a, ARCHIVE_FAILED, "snafu"); - assertEqualString("Undefined option: `snafu'", - archive_error_string(a)); - should(a, ARCHIVE_FAILED, "snafu=betcha"); - assertEqualString("Undefined option: `snafu'", - archive_error_string(a)); - - /* ARCHIVE_OK with iso9660 loaded, ARCHIVE_FAILED otherwise */ - should(a, known_option_rv, "iso9660:joliet"); - if (pristine) { - assertEqualString("Unknown module name: `iso9660'", - archive_error_string(a)); - } - should(a, known_option_rv, "iso9660:joliet"); - if (pristine) { - assertEqualString("Unknown module name: `iso9660'", - archive_error_string(a)); - } - should(a, known_option_rv, "joliet"); - if (pristine) { - assertEqualString("Undefined option: `joliet'", - archive_error_string(a)); - } - should(a, known_option_rv, "!joliet"); - if (pristine) { - assertEqualString("Undefined option: `joliet'", - archive_error_string(a)); - } - - should(a, ARCHIVE_OK, ","); - should(a, ARCHIVE_OK, ",,"); - - should(a, halfempty_options_rv, ",joliet"); - if (pristine) { - assertEqualString("Undefined option: `joliet'", - archive_error_string(a)); - } - should(a, halfempty_options_rv, "joliet,"); - if (pristine) { - assertEqualString("Undefined option: `joliet'", - archive_error_string(a)); - } - - should(a, ARCHIVE_FAILED, "joliet,snafu"); - if (pristine) { - assertEqualString("Undefined option: `joliet'", - archive_error_string(a)); - } else { - assertEqualString("Undefined option: `snafu'", - archive_error_string(a)); - } - - should(a, ARCHIVE_FAILED, "iso9660:snafu"); - if (pristine) { - assertEqualString("Unknown module name: `iso9660'", - archive_error_string(a)); - } else { - assertEqualString("Undefined option: `iso9660:snafu'", - archive_error_string(a)); - } - - archive_read_free(a); -} - -DEFINE_TEST(test_archive_read_set_options) -{ - test(1); - test(0); -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_read_support.c b/thirdparty/libarchive/libarchive/test/test_archive_read_support.c deleted file mode 100644 index c6eb9346c..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_read_support.c +++ /dev/null @@ -1,147 +0,0 @@ -/*- - * Copyright (c) 2011 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* - * Verify that the various archive_read_support_* functions - * return appropriate errors when invoked on the wrong kind of - * archive handle. - */ - -typedef struct archive *constructor(void); -typedef int enabler(struct archive *); -typedef int destructor(struct archive *); - -static int format_code = 0; -static int format_code_enabler(struct archive *a) -{ - return archive_read_support_format_by_code(a, format_code); -} - -static int format_code_setter(struct archive *a) -{ - return archive_read_set_format(a, format_code); -} - -static void -test_success(constructor new_, enabler enable_, destructor free_) -{ - struct archive *a = new_(); - int result = enable_(a); - if (result == ARCHIVE_WARN) { - assert(NULL != archive_error_string(a)); - assertEqualIntA(a, -1, archive_errno(a)); - } else { - assertEqualIntA(a, ARCHIVE_OK, result); - assert(NULL == archive_error_string(a)); - assertEqualIntA(a, 0, archive_errno(a)); - } - free_(a); -} - -static void -test_failure(constructor new_, enabler enable_, destructor free_) -{ - struct archive *a = new_(); - assertEqualIntA(a, ARCHIVE_FATAL, enable_(a)); - assert(NULL != archive_error_string(a)); - assertEqualIntA(a, -1, archive_errno(a)); - free_(a); -} - -static void -test_filter_or_format(enabler enable) -{ - test_success(archive_read_new, enable, archive_read_free); - test_failure(archive_write_new, enable, archive_write_free); - test_failure(archive_read_disk_new, enable, archive_read_free); - test_failure(archive_write_disk_new, enable, archive_write_free); -} - -DEFINE_TEST(test_archive_read_support) -{ - test_filter_or_format(archive_read_support_format_7zip); - test_filter_or_format(archive_read_support_format_all); - test_filter_or_format(archive_read_support_format_ar); - test_filter_or_format(archive_read_support_format_cab); - test_filter_or_format(archive_read_support_format_cpio); - test_filter_or_format(archive_read_support_format_empty); - test_filter_or_format(archive_read_support_format_iso9660); - test_filter_or_format(archive_read_support_format_lha); - test_filter_or_format(archive_read_support_format_mtree); - test_filter_or_format(archive_read_support_format_tar); - test_filter_or_format(archive_read_support_format_xar); - test_filter_or_format(archive_read_support_format_zip); - - int format_codes[] = { - ARCHIVE_FORMAT_CPIO, - ARCHIVE_FORMAT_CPIO_POSIX, - ARCHIVE_FORMAT_CPIO_BIN_LE, - ARCHIVE_FORMAT_CPIO_BIN_BE, - ARCHIVE_FORMAT_CPIO_SVR4_NOCRC, - ARCHIVE_FORMAT_CPIO_SVR4_CRC, - ARCHIVE_FORMAT_CPIO_AFIO_LARGE, - ARCHIVE_FORMAT_TAR, - ARCHIVE_FORMAT_TAR_USTAR, - ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE, - ARCHIVE_FORMAT_TAR_PAX_RESTRICTED, - ARCHIVE_FORMAT_TAR_GNUTAR, - ARCHIVE_FORMAT_ISO9660, - ARCHIVE_FORMAT_ISO9660_ROCKRIDGE, - ARCHIVE_FORMAT_ZIP, - ARCHIVE_FORMAT_EMPTY, - ARCHIVE_FORMAT_AR, - ARCHIVE_FORMAT_AR_GNU, - ARCHIVE_FORMAT_AR_BSD, - ARCHIVE_FORMAT_MTREE, - ARCHIVE_FORMAT_RAW, - ARCHIVE_FORMAT_XAR, - ARCHIVE_FORMAT_LHA, - ARCHIVE_FORMAT_CAB, - ARCHIVE_FORMAT_RAR, - ARCHIVE_FORMAT_7ZIP, - ARCHIVE_FORMAT_WARC, - ARCHIVE_FORMAT_RAR_V5, - }; - unsigned int i; - - for (i = 0; i < sizeof(format_codes) / sizeof(int); i++) { - format_code = format_codes[i]; - test_filter_or_format(format_code_enabler); - test_filter_or_format(format_code_setter); - } - - test_filter_or_format(archive_read_support_filter_all); - test_filter_or_format(archive_read_support_filter_bzip2); - test_filter_or_format(archive_read_support_filter_compress); - test_filter_or_format(archive_read_support_filter_gzip); - test_filter_or_format(archive_read_support_filter_lzip); - test_filter_or_format(archive_read_support_filter_lzma); - test_filter_or_format(archive_read_support_filter_none); - test_filter_or_format(archive_read_support_filter_rpm); - test_filter_or_format(archive_read_support_filter_uu); - test_filter_or_format(archive_read_support_filter_xz); -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_set_error.c b/thirdparty/libarchive/libarchive/test/test_archive_set_error.c deleted file mode 100644 index b83c08c88..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_set_error.c +++ /dev/null @@ -1,51 +0,0 @@ -/*- - * Copyright (c) 2011 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -static void -test(struct archive *a, int code, const char *msg) -{ - archive_set_error(a, code, "%s", msg); - - assertEqualInt(code, archive_errno(a)); - assertEqualString(msg, archive_error_string(a)); -} - -DEFINE_TEST(test_archive_set_error) -{ - struct archive* a = archive_read_new(); - - /* unlike printf("%s", NULL), - * archive_set_error(a, code, "%s", NULL) - * segfaults, so it's not tested here */ - test(a, 12, "abcdefgh"); - test(a, 0, "123456"); - test(a, -1, "tuvw"); - test(a, 34, "XYZ"); - - archive_read_free(a); -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_string.c b/thirdparty/libarchive/libarchive/test/test_archive_string.c deleted file mode 100644 index 7fa743ba9..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_string.c +++ /dev/null @@ -1,431 +0,0 @@ -/*- - * Copyright (c) 2011 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -#define __LIBARCHIVE_TEST -#include "archive_string.h" - -#define EXTENT 32 - -#define assertStringSizes(strlen, buflen, as) \ - assertEqualInt(strlen, (as).length); \ - assertEqualInt(buflen, (as).buffer_length); - -#define assertExactString(strlen, buflen, data, as) \ - do { \ - assertStringSizes(strlen, buflen, as); \ - assertEqualString(data, (as).s); \ - } while (0) - -#define assertNonNULLString(strlen, buflen, as) \ - do { \ - assertStringSizes(strlen, buflen, as); \ - assert(NULL != (as).s); \ - } while (0) - -static void -test_archive_string_ensure(void) -{ - struct archive_string s; - - archive_string_init(&s); - assertExactString(0, 0, NULL, s); - - /* single-extent allocation */ - assert(&s == archive_string_ensure(&s, 5)); - assertNonNULLString(0, EXTENT, s); - - /* what happens around extent boundaries? */ - assert(&s == archive_string_ensure(&s, EXTENT - 1)); - assertNonNULLString(0, EXTENT, s); - - assert(&s == archive_string_ensure(&s, EXTENT)); - assertNonNULLString(0, EXTENT, s); - - assert(&s == archive_string_ensure(&s, EXTENT + 1)); - assertNonNULLString(0, 2 * EXTENT, s); - - archive_string_free(&s); -} - -static void -test_archive_strcat(void) -{ - struct archive_string s; - - archive_string_init(&s); - assertExactString(0, 0, NULL, s); - - /* null target, empty source */ - assert(&s == archive_strcat(&s, "")); - assertExactString(0, EXTENT, "", s); - - /* empty target, empty source */ - assert(&s == archive_strcat(&s, "")); - assertExactString(0, EXTENT, "", s); - - /* empty target, non-empty source */ - assert(&s == archive_strcat(&s, "fubar")); - assertExactString(5, EXTENT, "fubar", s); - - /* non-empty target, non-empty source */ - assert(&s == archive_strcat(&s, "baz")); - assertExactString(8, EXTENT, "fubarbaz", s); - - archive_string_free(&s); -} - -static void -test_archive_strappend_char(void) -{ - struct archive_string s; - - archive_string_init(&s); - assertExactString(0, 0, NULL, s); - - /* null target */ - archive_strappend_char(&s, 'X'); - assertExactString(1, EXTENT, "X", s); - - /* non-empty target */ - archive_strappend_char(&s, 'Y'); - assertExactString(2, EXTENT, "XY", s); - - archive_string_free(&s); -} - -/* archive_strnXXX() tests focus on length handling. - * other behaviors are tested by proxy through archive_strXXX() - */ - -static void -test_archive_strncat(void) -{ - struct archive_string s; - - archive_string_init(&s); - assertExactString(0, 0, NULL, s); - - /* perfect length */ - assert(&s == archive_strncat(&s, "snafu", 5)); - assertExactString(5, EXTENT, "snafu", s); - - /* short read */ - assert(&s == archive_strncat(&s, "barbazqux", 3)); - assertExactString(8, EXTENT, "snafubar", s); - - /* long read is ok too! */ - assert(&s == archive_strncat(&s, "snafu", 8)); - assertExactString(13, EXTENT, "snafubarsnafu", s); - - archive_string_free(&s); -} - -static void -test_archive_strncpy(void) -{ - struct archive_string s; - - archive_string_init(&s); - assertExactString(0, 0, NULL, s); - - /* perfect length */ - assert(&s == archive_strncpy(&s, "fubar", 5)); - assertExactString(5, EXTENT, "fubar", s); - - /* short read */ - assert(&s == archive_strncpy(&s, "snafubar", 5)); - assertExactString(5, EXTENT, "snafu", s); - - /* long read is ok too! */ - assert(&s == archive_strncpy(&s, "snafu", 8)); - assertExactString(5, EXTENT, "snafu", s); - - archive_string_free(&s); -} - -static void -test_archive_strcpy(void) -{ - struct archive_string s; - - archive_string_init(&s); - assertExactString(0, 0, NULL, s); - - /* null target */ - assert(&s == archive_strcpy(&s, "snafu")); - assertExactString(5, EXTENT, "snafu", s); - - /* dirty target */ - assert(&s == archive_strcpy(&s, "foo")); - assertExactString(3, EXTENT, "foo", s); - - /* dirty target, empty source */ - assert(&s == archive_strcpy(&s, "")); - assertExactString(0, EXTENT, "", s); - - archive_string_free(&s); -} - -static void -test_archive_string_concat(void) -{ - struct archive_string s, t, u, v; - - archive_string_init(&s); - assertExactString(0, 0, NULL, s); - archive_string_init(&t); - assertExactString(0, 0, NULL, t); - archive_string_init(&u); - assertExactString(0, 0, NULL, u); - archive_string_init(&v); - assertExactString(0, 0, NULL, v); - - /* null target, null source */ - archive_string_concat(&t, &s); - assertExactString(0, 0, NULL, s); - assertExactString(0, EXTENT, "", t); - - /* null target, empty source */ - assert(&s == archive_strcpy(&s, "")); - archive_string_concat(&u, &s); - assertExactString(0, EXTENT, "", s); - assertExactString(0, EXTENT, "", u); - - /* null target, non-empty source */ - assert(&s == archive_strcpy(&s, "foo")); - archive_string_concat(&v, &s); - assertExactString(3, EXTENT, "foo", s); - assertExactString(3, EXTENT, "foo", v); - - /* empty target, empty source */ - assert(&s == archive_strcpy(&s, "")); - assert(&t == archive_strcpy(&t, "")); - archive_string_concat(&t, &s); - assertExactString(0, EXTENT, "", s); - assertExactString(0, EXTENT, "", t); - - /* empty target, non-empty source */ - assert(&s == archive_strcpy(&s, "snafu")); - assert(&t == archive_strcpy(&t, "")); - archive_string_concat(&t, &s); - assertExactString(5, EXTENT, "snafu", s); - assertExactString(5, EXTENT, "snafu", t); - - archive_string_free(&v); - archive_string_free(&u); - archive_string_free(&t); - archive_string_free(&s); -} - -static void -test_archive_string_copy(void) -{ - struct archive_string s, t, u, v; - - archive_string_init(&s); - assertExactString(0, 0, NULL, s); - archive_string_init(&t); - assertExactString(0, 0, NULL, t); - archive_string_init(&u); - assertExactString(0, 0, NULL, u); - archive_string_init(&v); - assertExactString(0, 0, NULL, v); - - /* null target, null source */ - archive_string_copy(&t, &s); - assertExactString(0, 0, NULL, s); - assertExactString(0, EXTENT, "", t); - - /* null target, empty source */ - archive_string_copy(&u, &t); - assertExactString(0, EXTENT, "", t); - assertExactString(0, EXTENT, "", u); - - /* empty target, empty source */ - archive_string_copy(&u, &t); - assertExactString(0, EXTENT, "", t); - assertExactString(0, EXTENT, "", u); - - /* null target, non-empty source */ - assert(NULL != archive_strcpy(&s, "snafubar")); - assertExactString(8, EXTENT, "snafubar", s); - - archive_string_copy(&v, &s); - assertExactString(8, EXTENT, "snafubar", s); - assertExactString(8, EXTENT, "snafubar", v); - - /* empty target, non-empty source */ - assertExactString(0, EXTENT, "", t); - archive_string_copy(&t, &s); - assertExactString(8, EXTENT, "snafubar", s); - assertExactString(8, EXTENT, "snafubar", t); - - /* non-empty target, non-empty source */ - assert(NULL != archive_strcpy(&s, "fubar")); - assertExactString(5, EXTENT, "fubar", s); - - archive_string_copy(&t, &s); - assertExactString(5, EXTENT, "fubar", s); - assertExactString(5, EXTENT, "fubar", t); - - archive_string_free(&v); - archive_string_free(&u); - archive_string_free(&t); - archive_string_free(&s); -} - -static void -test_archive_string_sprintf(void) -{ - struct archive_string s; -#define S16 "0123456789abcdef" -#define S32 S16 S16 -#define S64 S32 S32 -#define S128 S64 S64 - const char *s32 = S32; - const char *s33 = S32 "0"; - const char *s64 = S64; - const char *s65 = S64 "0"; - const char *s128 = S128; - const char *s129 = S128 "0"; -#undef S16 -#undef S32 -#undef S64 -#undef S128 - - archive_string_init(&s); - assertExactString(0, 0, NULL, s); - - archive_string_sprintf(&s, "%s", ""); - assertExactString(0, 2 * EXTENT, "", s); - - archive_string_empty(&s); - archive_string_sprintf(&s, "%s", s32); - assertExactString(32, 2 * EXTENT, s32, s); - - archive_string_empty(&s); - archive_string_sprintf(&s, "%s", s33); - assertExactString(33, 2 * EXTENT, s33, s); - - archive_string_empty(&s); - archive_string_sprintf(&s, "%s", s64); - assertExactString(64, 4 * EXTENT, s64, s); - - archive_string_empty(&s); - archive_string_sprintf(&s, "%s", s65); - assertExactString(65, 4 * EXTENT, s65, s); - - archive_string_empty(&s); - archive_string_sprintf(&s, "%s", s128); - assertExactString(128, 8 * EXTENT, s128, s); - - archive_string_empty(&s); - archive_string_sprintf(&s, "%s", s129); - assertExactString(129, 8 * EXTENT, s129, s); - - archive_string_empty(&s); - archive_string_sprintf(&s, "%d", 1234567890); - assertExactString(10, 8 * EXTENT, "1234567890", s); - - archive_string_free(&s); -} - -DEFINE_TEST(test_archive_string) -{ - test_archive_string_ensure(); - test_archive_strcat(); - test_archive_strappend_char(); - test_archive_strncat(); - test_archive_strncpy(); - test_archive_strcpy(); - test_archive_string_concat(); - test_archive_string_copy(); - test_archive_string_sprintf(); -} - -static const char *strings[] = -{ - "dir/path", - "dir/path2", - "dir/path3", - "dir/path4", - "dir/path5", - "dir/path6", - "dir/path7", - "dir/path8", - "dir/path9", - "dir/subdir/path", - "dir/subdir/path2", - "dir/subdir/path3", - "dir/subdir/path4", - "dir/subdir/path5", - "dir/subdir/path6", - "dir/subdir/path7", - "dir/subdir/path8", - "dir/subdir/path9", - "dir2/path", - "dir2/path2", - "dir2/path3", - "dir2/path4", - "dir2/path5", - "dir2/path6", - "dir2/path7", - "dir2/path8", - "dir2/path9", - NULL -}; - -DEFINE_TEST(test_archive_string_sort) -{ - unsigned int i, j, size; - char **test_strings, *tmp; - - srand((unsigned int)time(NULL)); - size = sizeof(strings) / sizeof(char *); - assert((test_strings = (char **)calloc(1, sizeof(strings))) != NULL); - for (i = 0; i < (size - 1); i++) - assert((test_strings[i] = strdup(strings[i])) != NULL); - - /* Shuffle the test strings */ - for (i = 0; i < (size - 1); i++) - { - j = rand() % ((size - 1) - i); - j += i; - tmp = test_strings[i]; - test_strings[i] = test_strings[j]; - test_strings[j] = tmp; - } - - /* Sort and test */ - assertEqualInt(ARCHIVE_OK, archive_utility_string_sort(test_strings)); - for (i = 0; i < (size - 1); i++) - assertEqualString(test_strings[i], strings[i]); - - for (i = 0; i < (size - 1); i++) - free(test_strings[i]); - free(test_strings); -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_string_conversion.c b/thirdparty/libarchive/libarchive/test/test_archive_string_conversion.c deleted file mode 100644 index 7faf58bfa..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_string_conversion.c +++ /dev/null @@ -1,886 +0,0 @@ -/*- - * Copyright (c) 2011-2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -#include - -#define __LIBARCHIVE_TEST -#include "archive_string.h" - -/* -Execute the following to rebuild the data for this program: - tail -n +36 test_archive_string_conversion.c | /bin/sh -# -# This requires http://unicode.org/Public/6.0.0/ucd/NormalizationTest.txt -# -if="NormalizationTest.txt" -if [ ! -f ${if} ]; then - echo "Not found: \"${if}\"" - exit 0 -fi -of=test_archive_string_conversion.txt.Z -echo "\$FreeBSD\$" > ${of}.uu -awk -F ';' '$0 ~/^[0-9A-F]+/ {printf "%s;%s\n", $2, $3}' ${if} | compress | uuencode ${of} >> ${of}.uu -exit 1 -*/ - -static int -unicode_to_utf8(char *p, uint32_t uc) -{ - char *_p = p; - - /* Translate code point to UTF8 */ - if (uc <= 0x7f) { - *p++ = (char)uc; - } else if (uc <= 0x7ff) { - *p++ = 0xc0 | ((uc >> 6) & 0x1f); - *p++ = 0x80 | (uc & 0x3f); - } else if (uc <= 0xffff) { - *p++ = 0xe0 | ((uc >> 12) & 0x0f); - *p++ = 0x80 | ((uc >> 6) & 0x3f); - *p++ = 0x80 | (uc & 0x3f); - } else { - *p++ = 0xf0 | ((uc >> 18) & 0x07); - *p++ = 0x80 | ((uc >> 12) & 0x3f); - *p++ = 0x80 | ((uc >> 6) & 0x3f); - *p++ = 0x80 | (uc & 0x3f); - } - return ((int)(p - _p)); -} - -static void -archive_be16enc(void *pp, uint16_t u) -{ - unsigned char *p = (unsigned char *)pp; - - p[0] = (u >> 8) & 0xff; - p[1] = u & 0xff; -} - -static int -unicode_to_utf16be(char *p, uint32_t uc) -{ - char *utf16 = p; - - if (uc > 0xffff) { - /* We have a code point that won't fit into a - * wchar_t; convert it to a surrogate pair. */ - uc -= 0x10000; - archive_be16enc(utf16, ((uc >> 10) & 0x3ff) + 0xD800); - archive_be16enc(utf16+2, (uc & 0x3ff) + 0xDC00); - return (4); - } else { - archive_be16enc(utf16, uc); - return (2); - } -} - -static void -archive_le16enc(void *pp, uint16_t u) -{ - unsigned char *p = (unsigned char *)pp; - - p[0] = u & 0xff; - p[1] = (u >> 8) & 0xff; -} - -static size_t -unicode_to_utf16le(char *p, uint32_t uc) -{ - char *utf16 = p; - - if (uc > 0xffff) { - /* We have a code point that won't fit into a - * wchar_t; convert it to a surrogate pair. */ - uc -= 0x10000; - archive_le16enc(utf16, ((uc >> 10) & 0x3ff) + 0xD800); - archive_le16enc(utf16+2, (uc & 0x3ff) + 0xDC00); - return (4); - } else { - archive_le16enc(utf16, uc); - return (2); - } -} - -static int -wc_size(void) -{ - return (sizeof(wchar_t)); -} - -static int -unicode_to_wc(wchar_t *wp, uint32_t uc) -{ - if (wc_size() == 4) { - *wp = (wchar_t)uc; - return (1); - } - if (uc > 0xffff) { - /* We have a code point that won't fit into a - * wchar_t; convert it to a surrogate pair. */ - uc -= 0x10000; - *wp++ = (wchar_t)(((uc >> 10) & 0x3ff) + 0xD800); - *wp = (wchar_t)((uc & 0x3ff) + 0xDC00); - return (2); - } else { - *wp = (wchar_t)uc; - return (1); - } -} - -/* - * Note: U+2000 - U+2FFF, U+F900 - U+FAFF and U+2F800 - U+2FAFF are not - * converted to NFD on Mac OS. - * see also http://developer.apple.com/library/mac/#qa/qa2001/qa1173.html - */ -static int -scan_unicode_pattern(char *out, wchar_t *wout, char *u16be, char *u16le, - const char *pattern, int mac_nfd) -{ - unsigned uc = 0; - const char *p = pattern; - char *op = out; - wchar_t *owp = wout; - char *op16be = u16be; - char *op16le = u16le; - int ret = 0; - - for (;;) { - if (*p >= '0' && *p <= '9') - uc = (uc << 4) + (*p - '0'); - else if (*p >= 'A' && *p <= 'F') - uc = (uc << 4) + (*p - 'A' + 0x0a); - else { - if (mac_nfd && op == out) { - /* - * These are not converted to NFD on Mac OS. - * U+2000 - U+2FFF - * U+F900 - U+FAFF - * U+2F800 - U+2FAFF - */ - switch (uc) { - case 0x2194: case 0x219A: case 0x219B: - case 0x21AE: case 0x21CD: case 0x21CE: - case 0x21CF: case 0x2204: case 0x2209: - case 0x220C: case 0x2224: case 0x2226: - case 0x2241: case 0x2244: case 0x2247: - case 0x2249: case 0x2260: case 0x2262: - case 0x226D: case 0x226E: case 0x226F: - case 0x2270: case 0x2271: case 0x2274: - case 0x2275: case 0x2276: case 0x2278: - case 0x2279: case 0x227A: case 0x227B: - case 0x2280: case 0x2281: case 0x2284: - case 0x2285: case 0x2288: case 0x2289: - case 0x22AC: case 0x22AD: case 0x22AE: - case 0x22AF: case 0x22E0: case 0x22E1: - case 0x22E2: case 0x22E3: case 0x22EA: - case 0x22EB: case 0x22EC: case 0x22ED: - - /* - * Those code points are not converted to - * NFD on Mac OS. I do not know the reason - * because it is undocumented. - * NFC NFD - * 1109A ==> 11099 110BA - * 1109C ==> 1109B 110BA - * 110AB ==> 110A5 110BA - */ - case 0x1109A: case 0x1109C: case 0x110AB: - ret = 1; - break; - } - } - op16be += unicode_to_utf16be(op16be, uc); - op16le += unicode_to_utf16le(op16le, uc); - owp += unicode_to_wc(owp, uc); - op += unicode_to_utf8(op, uc); - if (!*p) { - *op16be++ = 0; - *op16be = 0; - *op16le++ = 0; - *op16le = 0; - *owp = L'\0'; - *op = '\0'; - break; - } - uc = 0; - } - p++; - } - return (ret); -} - -static int -is_wc_unicode(void) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - return (1); -#else - return (0); -#endif -} - -/* - * A conversion test that we correctly normalize UTF-8 and UTF-16BE characters. - * On Mac OS, the characters to be Form D. - * On other platforms, the characters to be Form C. - */ -static void -test_archive_string_normalization_nfc(const char *testdata) -{ - struct archive *a, *a2; - struct archive_string utf8; - struct archive_mstring mstr; - struct archive_string_conv *f_sconv8, *t_sconv8; - struct archive_string_conv *f_sconv16be, *f_sconv16le; - FILE *fp; - char buff[512]; - int line = 0; - int locale_is_utf8, wc_is_unicode; - int sconv_opt = SCONV_SET_OPT_NORMALIZATION_C; - - locale_is_utf8 = (NULL != setlocale(LC_ALL, "en_US.UTF-8")); - wc_is_unicode = is_wc_unicode(); - /* If it doesn't exist, just warn and return. */ - if (!locale_is_utf8 && !wc_is_unicode) { - skipping("A test of string normalization for NFC requires " - "a suitable locale; en_US.UTF-8 not available on this " - "system"); - return; - } - - archive_string_init(&utf8); - memset(&mstr, 0, sizeof(mstr)); - - /* - * Create string conversion objects. - */ - assert((a = archive_read_new()) != NULL); - assertA(NULL != (f_sconv8 = - archive_string_conversion_from_charset(a, "UTF-8", 0))); - assertA(NULL != (f_sconv16be = - archive_string_conversion_from_charset(a, "UTF-16BE", 0))); - assertA(NULL != (f_sconv16le = - archive_string_conversion_from_charset(a, "UTF-16LE", 0))); - assert((a2 = archive_write_new()) != NULL); - assertA(NULL != (t_sconv8 = - archive_string_conversion_to_charset(a2, "UTF-8", 0))); - if (f_sconv8 == NULL || f_sconv16be == NULL || f_sconv16le == NULL || - t_sconv8 == NULL) { - /* We cannot continue this test. */ - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - archive_string_conversion_set_opt(f_sconv8, sconv_opt); - archive_string_conversion_set_opt(f_sconv16be, sconv_opt); - archive_string_conversion_set_opt(f_sconv16le, sconv_opt); - archive_string_conversion_set_opt(t_sconv8, sconv_opt); - - /* Open a test pattern file. */ - assert((fp = fopen(testdata, "r")) != NULL); - - /* - * Read test data. - * Test data format: - * ';' '\n' - * Unicode pattern format: - * [0-9A-F]{4,5}([ ][0-9A-F]{4,5}){0,} - */ - while (fgets(buff, sizeof(buff), fp) != NULL) { - char nfc[80], nfd[80]; - char utf8_nfc[80], utf8_nfd[80]; - char utf16be_nfc[80], utf16be_nfd[80]; - char utf16le_nfc[80], utf16le_nfd[80]; - wchar_t wc_nfc[40], wc_nfd[40]; - char *e, *p; - const wchar_t *wp; - const char *mp; - size_t mplen; - - line++; - if (buff[0] == '#') - continue; - p = strchr(buff, ';'); - if (p == NULL) - continue; - *p++ = '\0'; - /* Copy an NFC pattern */ - strncpy(nfc, buff, sizeof(nfc)-1); - nfc[sizeof(nfc)-1] = '\0'; - e = p; - p = strchr(p, '\n'); - if (p == NULL) - continue; - *p = '\0'; - /* Copy an NFD pattern */ - strncpy(nfd, e, sizeof(nfd)-1); - nfd[sizeof(nfd)-1] = '\0'; - - /* - * Get an NFC patterns. - */ - scan_unicode_pattern(utf8_nfc, wc_nfc, utf16be_nfc, utf16le_nfc, - nfc, 0); - - /* - * Get an NFD patterns. - */ - scan_unicode_pattern(utf8_nfd, wc_nfd, utf16be_nfd, utf16le_nfd, - nfd, 0); - - if (locale_is_utf8) { - /* - * Normalize an NFD string for import. - */ - assertEqualInt(0, archive_strcpy_l( - &utf8, utf8_nfd, f_sconv8)); - failure("NFD(%s) should be converted to NFC(%s):%d", - nfd, nfc, line); - assertEqualUTF8String(utf8_nfc, utf8.s); - - /* - * Normalize an NFC string for import. - */ - assertEqualInt(0, archive_strcpy_l( - &utf8, utf8_nfc, f_sconv8)); - failure("NFC(%s) should not be any changed:%d", - nfc, line); - assertEqualUTF8String(utf8_nfc, utf8.s); - - /* - * Copy an NFC string for export. - */ - assertEqualInt(0, archive_strcpy_l( - &utf8, utf8_nfc, t_sconv8)); - failure("NFC(%s) should not be any changed:%d", - nfc, line); - assertEqualUTF8String(utf8_nfc, utf8.s); - - /* - * Normalize an NFD string in UTF-16BE for import. - */ - assertEqualInt(0, archive_strncpy_l( - &utf8, utf16be_nfd, 100000, f_sconv16be)); - failure("NFD(%s) should be converted to NFC(%s):%d", - nfd, nfc, line); - assertEqualUTF8String(utf8_nfc, utf8.s); - - /* - * Normalize an NFD string in UTF-16LE for import. - */ - assertEqualInt(0, archive_strncpy_l( - &utf8, utf16le_nfd, 100000, f_sconv16le)); - failure("NFD(%s) should be converted to NFC(%s):%d", - nfd, nfc, line); - assertEqualUTF8String(utf8_nfc, utf8.s); - } - - /* - * Test for archive_mstring interface. - * In specific, Windows platform UTF-16BE is directly - * converted to/from wide-character to avoid the effect of - * current locale since windows platform cannot make - * locale UTF-8. - */ - if (locale_is_utf8 || wc_is_unicode) { - /* - * Normalize an NFD string in UTF-8 for import. - */ - assertEqualInt(0, archive_mstring_copy_mbs_len_l( - &mstr, utf8_nfd, 100000, f_sconv8)); - assertEqualInt(0, - archive_mstring_get_wcs(a, &mstr, &wp)); - failure("UTF-8 NFD(%s) should be converted " - "to WCS NFC(%s):%d", nfd, nfc, line); - assertEqualWString(wc_nfc, wp); - - /* - * Normalize an NFD string in UTF-16BE for import. - */ - assertEqualInt(0, archive_mstring_copy_mbs_len_l( - &mstr, utf16be_nfd, 100000, f_sconv16be)); - assertEqualInt(0, - archive_mstring_get_wcs(a, &mstr, &wp)); - failure("UTF-8 NFD(%s) should be converted " - "to WCS NFC(%s):%d", nfd, nfc, line); - assertEqualWString(wc_nfc, wp); - - /* - * Normalize an NFD string in UTF-16LE for import. - */ - assertEqualInt(0, archive_mstring_copy_mbs_len_l( - &mstr, utf16le_nfd, 100000, f_sconv16le)); - assertEqualInt(0, - archive_mstring_get_wcs(a, &mstr, &wp)); - failure("UTF-8 NFD(%s) should be converted " - "to WCS NFC(%s):%d", nfd, nfc, line); - assertEqualWString(wc_nfc, wp); - - /* - * Copy an NFC wide-string for export. - */ - assertEqualInt(0, - archive_mstring_copy_wcs(&mstr, wc_nfc)); - assertEqualInt(0, archive_mstring_get_mbs_l( - a, &mstr, &mp, &mplen, t_sconv8)); - failure("WCS NFC(%s) should be UTF-8 NFC:%d" - ,nfc, line); - assertEqualUTF8String(utf8_nfc, mp); - } - } - - archive_string_free(&utf8); - archive_mstring_clean(&mstr); - fclose(fp); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a2)); -} - -static void -test_archive_string_normalization_mac_nfd(const char *testdata) -{ - struct archive *a, *a2; - struct archive_string utf8; - struct archive_mstring mstr; - struct archive_string_conv *f_sconv8, *t_sconv8; - struct archive_string_conv *f_sconv16be, *f_sconv16le; - FILE *fp; - char buff[512]; - int line = 0; - int locale_is_utf8, wc_is_unicode; - int sconv_opt = SCONV_SET_OPT_NORMALIZATION_D; - - locale_is_utf8 = (NULL != setlocale(LC_ALL, "en_US.UTF-8")); - wc_is_unicode = is_wc_unicode(); - /* If it doesn't exist, just warn and return. */ - if (!locale_is_utf8 && !wc_is_unicode) { - skipping("A test of string normalization for NFD requires " - "a suitable locale; en_US.UTF-8 not available on this " - "system"); - return; - } - - archive_string_init(&utf8); - memset(&mstr, 0, sizeof(mstr)); - - /* - * Create string conversion objects. - */ - assert((a = archive_read_new()) != NULL); - assertA(NULL != (f_sconv8 = - archive_string_conversion_from_charset(a, "UTF-8", 0))); - assertA(NULL != (f_sconv16be = - archive_string_conversion_from_charset(a, "UTF-16BE", 0))); - assertA(NULL != (f_sconv16le = - archive_string_conversion_from_charset(a, "UTF-16LE", 0))); - assert((a2 = archive_write_new()) != NULL); - assertA(NULL != (t_sconv8 = - archive_string_conversion_to_charset(a2, "UTF-8", 0))); - if (f_sconv8 == NULL || f_sconv16be == NULL || f_sconv16le == NULL || - t_sconv8 == NULL) { - /* We cannot continue this test. */ - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - archive_string_conversion_set_opt(f_sconv8, sconv_opt); - archive_string_conversion_set_opt(f_sconv16be, sconv_opt); - archive_string_conversion_set_opt(f_sconv16le, sconv_opt); - archive_string_conversion_set_opt(t_sconv8, sconv_opt); - - /* Open a test pattern file. */ - assert((fp = fopen(testdata, "r")) != NULL); - - /* - * Read test data. - * Test data format: - * ';' '\n' - * Unicode pattern format: - * [0-9A-F]{4,5}([ ][0-9A-F]{4,5}){0,} - */ - while (fgets(buff, sizeof(buff), fp) != NULL) { - char nfc[80], nfd[80]; - char utf8_nfc[80], utf8_nfd[80]; - char utf16be_nfc[80], utf16be_nfd[80]; - char utf16le_nfc[80], utf16le_nfd[80]; - wchar_t wc_nfc[40], wc_nfd[40]; - char *e, *p; - const wchar_t *wp; - const char *mp; - size_t mplen; - int should_be_nfc; - - line++; - if (buff[0] == '#') - continue; - p = strchr(buff, ';'); - if (p == NULL) - continue; - *p++ = '\0'; - /* Copy an NFC pattern */ - strncpy(nfc, buff, sizeof(nfc)-1); - nfc[sizeof(nfc)-1] = '\0'; - e = p; - p = strchr(p, '\n'); - if (p == NULL) - continue; - *p = '\0'; - /* Copy an NFD pattern */ - strncpy(nfd, e, sizeof(nfd)-1); - nfd[sizeof(nfd)-1] = '\0'; - - /* - * Get an NFC patterns. - */ - should_be_nfc = scan_unicode_pattern(utf8_nfc, wc_nfc, - utf16be_nfc, utf16le_nfc, nfc, 1); - - /* - * Get an NFD patterns. - */ - scan_unicode_pattern(utf8_nfd, wc_nfd, utf16be_nfd, utf16le_nfd, - nfd, 0); - - if (locale_is_utf8) { - /* - * Normalize an NFC string for import. - */ - assertEqualInt(0, archive_strcpy_l( - &utf8, utf8_nfc, f_sconv8)); - if (should_be_nfc) { - failure("NFC(%s) should not be converted to" - " NFD(%s):%d", nfc, nfd, line); - assertEqualUTF8String(utf8_nfc, utf8.s); - } else { - failure("NFC(%s) should be converted to" - " NFD(%s):%d", nfc, nfd, line); - assertEqualUTF8String(utf8_nfd, utf8.s); - } - - /* - * Normalize an NFD string for import. - */ - assertEqualInt(0, archive_strcpy_l( - &utf8, utf8_nfd, f_sconv8)); - failure("NFD(%s) should not be any changed:%d", - nfd, line); - assertEqualUTF8String(utf8_nfd, utf8.s); - - /* - * Copy an NFD string for export. - */ - assertEqualInt(0, archive_strcpy_l( - &utf8, utf8_nfd, t_sconv8)); - failure("NFD(%s) should not be any changed:%d", - nfd, line); - assertEqualUTF8String(utf8_nfd, utf8.s); - - /* - * Normalize an NFC string in UTF-16BE for import. - */ - assertEqualInt(0, archive_strncpy_l( - &utf8, utf16be_nfc, 100000, f_sconv16be)); - if (should_be_nfc) { - failure("NFC(%s) should not be converted to" - " NFD(%s):%d", nfc, nfd, line); - assertEqualUTF8String(utf8_nfc, utf8.s); - } else { - failure("NFC(%s) should be converted to" - " NFD(%s):%d", nfc, nfd, line); - assertEqualUTF8String(utf8_nfd, utf8.s); - } - - /* - * Normalize an NFC string in UTF-16LE for import. - */ - assertEqualInt(0, archive_strncpy_l( - &utf8, utf16le_nfc, 100000, f_sconv16le)); - if (should_be_nfc) { - failure("NFC(%s) should not be converted to" - " NFD(%s):%d", nfc, nfd, line); - assertEqualUTF8String(utf8_nfc, utf8.s); - } else { - failure("NFC(%s) should be converted to" - " NFD(%s):%d", nfc, nfd, line); - assertEqualUTF8String(utf8_nfd, utf8.s); - } - } - - /* - * Test for archive_mstring interface. - * In specific, Windows platform UTF-16BE is directly - * converted to/from wide-character to avoid the effect of - * current locale since windows platform cannot make - * locale UTF-8. - */ - if (locale_is_utf8 || wc_is_unicode) { - /* - * Normalize an NFD string in UTF-8 for import. - */ - assertEqualInt(0, archive_mstring_copy_mbs_len_l( - &mstr, utf8_nfc, 100000, f_sconv8)); - assertEqualInt(0, - archive_mstring_get_wcs(a, &mstr, &wp)); - if (should_be_nfc) { - failure("UTF-8 NFC(%s) should not be converted " - "to WCS NFD(%s):%d", nfc, nfd, line); - assertEqualWString(wc_nfc, wp); - } else { - failure("UTF-8 NFC(%s) should be converted " - "to WCS NFD(%s):%d", nfc, nfd, line); - assertEqualWString(wc_nfd, wp); - } - - /* - * Normalize an NFD string in UTF-16BE for import. - */ - assertEqualInt(0, archive_mstring_copy_mbs_len_l( - &mstr, utf16be_nfc, 100000, f_sconv16be)); - assertEqualInt(0, - archive_mstring_get_wcs(a, &mstr, &wp)); - if (should_be_nfc) { - failure("UTF-16BE NFC(%s) should not be " - "converted to WCS NFD(%s):%d", - nfc, nfd, line); - assertEqualWString(wc_nfc, wp); - } else { - failure("UTF-16BE NFC(%s) should be converted " - "to WCS NFD(%s):%d", nfc, nfd, line); - assertEqualWString(wc_nfd, wp); - } - - /* - * Normalize an NFD string in UTF-16LE for import. - */ - assertEqualInt(0, archive_mstring_copy_mbs_len_l( - &mstr, utf16le_nfc, 100000, f_sconv16le)); - assertEqualInt(0, - archive_mstring_get_wcs(a, &mstr, &wp)); - if (should_be_nfc) { - failure("UTF-16LE NFC(%s) should not be " - "converted to WCS NFD(%s):%d", - nfc, nfd, line); - assertEqualWString(wc_nfc, wp); - } else { - failure("UTF-16LE NFC(%s) should be converted " - "to WCS NFD(%s):%d", nfc, nfd, line); - assertEqualWString(wc_nfd, wp); - } - - /* - * Copy an NFD wide-string for export. - */ - assertEqualInt(0, archive_mstring_copy_wcs( - &mstr, wc_nfd)); - assertEqualInt(0, archive_mstring_get_mbs_l( - a, &mstr, &mp, &mplen, t_sconv8)); - failure("WCS NFD(%s) should be UTF-8 NFD:%d" - ,nfd, line); - assertEqualUTF8String(utf8_nfd, mp); - } - } - - archive_string_free(&utf8); - archive_mstring_clean(&mstr); - fclose(fp); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a2)); -} - -static void -test_archive_string_canonicalization(void) -{ - struct archive *a; - struct archive_string_conv *sconv; - - setlocale(LC_ALL, "en_US.UTF-8"); - - assert((a = archive_read_new()) != NULL); - - assertA(NULL != (sconv = - archive_string_conversion_to_charset(a, "UTF-8", 1))); - failure("Charset name should be UTF-8"); - assertEqualString("UTF-8", - archive_string_conversion_charset_name(sconv)); - - assertA(NULL != (sconv = - archive_string_conversion_to_charset(a, "UTF8", 1))); - failure("Charset name should be UTF-8"); - assertEqualString("UTF-8", - archive_string_conversion_charset_name(sconv)); - - assertA(NULL != (sconv = - archive_string_conversion_to_charset(a, "utf8", 1))); - failure("Charset name should be UTF-8"); - assertEqualString("UTF-8", - archive_string_conversion_charset_name(sconv)); - - assertA(NULL != (sconv = - archive_string_conversion_to_charset(a, "UTF-16BE", 1))); - failure("Charset name should be UTF-16BE"); - assertEqualString("UTF-16BE", - archive_string_conversion_charset_name(sconv)); - - assertA(NULL != (sconv = - archive_string_conversion_to_charset(a, "UTF16BE", 1))); - failure("Charset name should be UTF-16BE"); - assertEqualString("UTF-16BE", - archive_string_conversion_charset_name(sconv)); - - assertA(NULL != (sconv = - archive_string_conversion_to_charset(a, "utf16be", 1))); - failure("Charset name should be UTF-16BE"); - assertEqualString("UTF-16BE", - archive_string_conversion_charset_name(sconv)); - - assertA(NULL != (sconv = - archive_string_conversion_to_charset(a, "UTF-16LE", 1))); - failure("Charset name should be UTF-16LE"); - assertEqualString("UTF-16LE", - archive_string_conversion_charset_name(sconv)); - - assertA(NULL != (sconv = - archive_string_conversion_to_charset(a, "UTF16LE", 1))); - failure("Charset name should be UTF-16LE"); - assertEqualString("UTF-16LE", - archive_string_conversion_charset_name(sconv)); - - assertA(NULL != (sconv = - archive_string_conversion_to_charset(a, "utf16le", 1))); - failure("Charset name should be UTF-16LE"); - assertEqualString("UTF-16LE", - archive_string_conversion_charset_name(sconv)); - - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - -} - -static void -check_string(struct archive *a, struct archive_mstring *mstr, struct archive_string_conv *sc, - const char *exp, const wchar_t *wexp) -{ - /* Do all the tests on a copy so that we can have a clear initial state every time */ - struct archive_mstring mstr2; - const char *p = NULL; - const wchar_t *wp = NULL; - size_t len = 0; - - memset(&mstr2, 0, sizeof(mstr2)); - - archive_mstring_copy(&mstr2, mstr); - assertEqualInt(0, archive_mstring_get_mbs(a, &mstr2, &p)); - assertEqualString(exp, p); - p = NULL; - - archive_mstring_copy(&mstr2, mstr); - assertEqualInt(0, archive_mstring_get_utf8(a, &mstr2, &p)); - assertEqualString(exp, p); - p = NULL; - - archive_mstring_copy(&mstr2, mstr); - assertEqualInt(0, archive_mstring_get_wcs(a, &mstr2, &wp)); - assertEqualWString(wexp, wp); - wp = NULL; - - archive_mstring_copy(&mstr2, mstr); - assertEqualInt(0, archive_mstring_get_mbs_l(a, &mstr2, &p, &len, sc)); - assertEqualString(exp, p); - assertEqualInt(len, strlen(exp)); - p = NULL; - len = 0; - - archive_mstring_clean(&mstr2); -} - -/* - * Make sure no matter what the input encoding is, the string can be - * converted too all the output encodings. - */ -static void -test_archive_string_set_get(void) -{ - struct archive *a; - struct archive_mstring mstr; - struct archive_string_conv *sc; - - setlocale(LC_ALL, "en_US.UTF-8"); - - assert((a = archive_read_new()) != NULL); - memset(&mstr, 0, sizeof(mstr)); - - assertA(NULL != (sc = - archive_string_conversion_to_charset(a, "UTF-8", 1))); - failure("Charset name should be UTF-8"); - assertEqualString("UTF-8", - archive_string_conversion_charset_name(sc)); - - assertEqualInt(0, archive_mstring_copy_mbs(&mstr, "AAA")); - check_string(a, &mstr, sc, "AAA", L"AAA"); - assertEqualInt(4, archive_mstring_copy_utf8(&mstr, "BBBB")); - check_string(a, &mstr, sc, "BBBB", L"BBBB"); - assertEqualInt(0, archive_mstring_copy_wcs(&mstr, L"CCC12")); - check_string(a, &mstr, sc, "CCC12", L"CCC12"); - assertEqualInt(0, archive_mstring_copy_mbs_len_l(&mstr, "DDDD-l", 6, sc)); - check_string(a, &mstr, sc, "DDDD-l", L"DDDD-l"); - assertEqualInt(0, archive_mstring_update_utf8(a, &mstr, "EEEEE---H")); - check_string(a, &mstr, sc, "EEEEE---H", L"EEEEE---H"); - - archive_mstring_clean(&mstr); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - -} - -DEFINE_TEST(test_archive_string_conversion) -{ - static const char reffile[] = "test_archive_string_conversion.txt.Z"; - static const char testdata[] = "testdata.txt"; - struct archive *a; - struct archive_entry *ae; - char buff[512]; - ssize_t size; - FILE *fp; - - /* - * Extract a test pattern file. - */ - extract_reference_file(reffile); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_raw(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, reffile, 512)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assert((fp = fopen(testdata, "w")) != NULL); - while ((size = archive_read_data(a, buff, 512)) > 0) - assertEqualInt(size, fwrite(buff, 1, size, fp)); - assertEqualInt(0, fclose(fp)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - test_archive_string_normalization_nfc(testdata); - test_archive_string_normalization_mac_nfd(testdata); - test_archive_string_canonicalization(); - test_archive_string_set_get(); -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_string_conversion.txt.Z.uu b/thirdparty/libarchive/libarchive/test/test_archive_string_conversion.txt.Z.uu deleted file mode 100644 index 33c2e03bf..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_string_conversion.txt.Z.uu +++ /dev/null @@ -1,2605 +0,0 @@ -$FreeBSD$ -begin 644 test_archive_string_conversion.txt.Z -M'YV0,8K`"+(#!@P:-$#`F`'CAH*`,(84/)APH8P9#P4.4FG&ET -MIG185$70IUY5&-775RS^?NK2S9 -M\6"_>R7#V`RCAI`8"DWC2"TD1^H6"%F,,5P8H9/CG1C -M1$H=!"4,00[1X4'"1>D6B"F5*:-;)*:IY8GZD3E2D$2\F%(1._9%!(TT&$&9 -M043D>)"?5>KI(Z$,;4G$D(/F":@-'R$*IIY3EO;E9T1D6,.75@+:Y:9O`CHF -MJ##1B>9P(W4*@T`3V1#C9T78"8.KJ?95!(VTPK1E$8+FRA"/JR+HZZ0&%<'H -ML$86@:0-2C*YJGPV7&IKI='66FR&U>IJ:Y?9,A1D$6/:H":LIXIK[:IMSJKF -MKG&:6VI?1LAJ`YXP`6L$KI)^9D2ODJIJA+"2;FG$L9+:"ZE!-D@:I!&5WB"M -M049DZ/"Y1G0YL;80CWFQM_">>H.:_L;Y\9QUQ6`0C*29+&^,ZIG,9XPVE+Q0 -MJS#+[..*,DQH\K$XZSSK1U:M:?*R07=JLI-!WV@RM4G+C&703)K,+=0RCTE# -MT$/(7"[6,J>K$D-9VP5#NXZ%?1>?7[8<0Z]IEQP9E0S%3-BQ7\I]U\%>MD38 -MLE]&'8.34.;L-K6!ZQP#EE^:+52KB;MM-7B)NETNY#`H'=!'E-L=0[N9ERQ# -MB@=1'K4,\HKN.9^0+^EYKZF/[N-J&.-U+.R1VY7S1VKRB!>UN7N.I9HMR\`M -M\)Y;K:;=,I1[O.=>ERFX[>TZKS-#N.N]]G_7ESQ#CFOK/H./0,4^P['AU[XV -MWC1H95'4,RRK/DWL5TI#3D+/@"W]1L_0Y?PAL1]N3JJSRPQ.Q3^8F&T&Z;(! -M_0ZHG[7Q1S$I@F#)KO81>C'$:`AIE06%]J0*]F^">)O7!^U"`R318(-FHP&T -M4#C!*2GF0B2TFJ1:1H-RS7""7I.4W?K4*AV6K`:@Z]-(A/!#>4F*B':I`8)J -M4)X+_I!1-VBBT&J`-R:.,`8U0%(4KU@#^5C1@#]LF!3-EIR)U*!H/[08&I,X -MJJ8ET6-NQ&*ZSLA%D36K9#8`'1W!:!=73>0&7.LCC91X16;]<28!C($-EE@V -M/$*QD7WTXI=T)ZX_3A*/FFI;'RVF246.JFYX]!@H^SC'+VU(D2(S9#[#*$@_G3;D-`B3^C]I:"^%-G -M0W!A1/=I'W^><@A*\>10,>V3@#$RVQ`2&-)]QHD&:C(;$4#G+K"5K$[K -MY&,,]M3#8$H9$?`V2]H=Y*5(`JI1C48$^1356C.M -ME%)M.E.)?#6874&KIC2Q*@M*X(- -M0P)9M+9)*'VU2Q'T(P/R4-4(+(6FV>+ET'B5[%ZE5=J^2JN[?V$.J@/C*VR= -MM,'!;(Y:M3TMEF)$S=-RB[>P'9-<"V47(YRJKK!-5U-A&R6?> -M]?XN*.\='G[#*\/Z?FZR\@UO#O>[WG8A2KVDTZ,4J7N7/RX8NH4QR!>GPMVU -M.9C`I%OBEQ@,Q0U#N(KNA;`60URYOYE127(C7<-0#&%-(3+%BS/(#5X,8:]A -M%<+MNG'E9("^&#%)!DMRJT]V#+@1`IEP1I:!8>=$&B`KELEGW7%_Z]7DY-64 -MRE$&\H"'#&0#Z^TB0904Y=1SD7?:I,DT,2/Q*K>]/ZY9>"F",W1/4Q#A<=<_ -M=?;/G',D/!X)[S)_GO.0A#=0X1W,T'-&B?!^+*$\3RAY?X$T=(DPI>3!,'GV -MP?2DE9(\)":O0Y^>-)J2)Z+*I54&`H%N6TW-W5O5^5:JYC.O5`WH(JB'104Q -MTP5SO::IY,C7=?%6JGC]W,JU)L\P;)]]E-T7_4U$?\'&P65F(.UH,RH^UJ+V -MP69`'.(F"$G?B?9?N,VI:$^)VY3K%+67G0.01;M#W.Y7M-MDOW(O!`?ZL9^[ -M%Y*#%.F/F=D.`KN9&>P@**7>)%L(;G)]FH"C27_VMA^]OQ/P?+"6JK[W+54OW5LJ3Y0 -MJ9^;876APHEOU]M\:$[6`D=PY\2OGV6K7>1XQ6)^OG]YVIQCUO8:5XCV^C^ -M(#B_FN\##_S;FXSR.$W2\"=40]5CL?9$>/OD87+X3#E^N7(G@E)J2'#@TYWV -MV1=][HE50[_#$OGZN1KEF._J&E7V(+QR_.@;$W9;S]ZH[!_2U?!??^=OD/W2 -M]W_U9Q\GQ'_PMWU%T'TG1'?)0WF2Y7@UY(!^!WCJ<4+I=WI1UB!F+!#M)V(,R,"1'."N;`H4'LTCA\X2S -M`DQ;.%`V<`-7"(8]>`,H\85,\H5_@88]B")`N"A(J$1K^!\*%!M::`/)9X?E -MH87D,27D`3LY<')U\8=V\H>V\8=A\X>7\8<]88B!^'PP8(@%`1N!P8B/"'Z0 -M6(EQ1XFP`1Z7N(D*H8G^](DG%XFA^(B`^(BD(XH=0AZQH8E`IHJ1^(JF>(@U -M.(NQJ#ZN2"B=*`.Z>(HY@%&1F%"?*`0F\H@H]XN<&'V!Z$[#N(K,^(A"<(A! -M4!XY$(V1.(W-N(RZ:(V/*$_9.!`TH1!!,(K@6![C&#;C"#OG6!#I*(ZGZ$YQ -MMXX#`7[G6!?N!![R>(_NB(ZEF(_]^(ZUF(\!>8H*\A<*`AY"0$5UH2!*<9`* -M,2#%J"`=XI`,PB3^$1L#,I&IF"`$*8L961#^41X9N9`Y4UI8?EY9$L)9SB7=#P!]PB29P*1QW22AWN2%PV29_ -MV99$P!^\DB.+61>)Q9@&LBIW61"2%3:2A2:761>@U2&;J9E_IQ`5@Q+_4AZA -MZ9DO$9H%\2^G&6YC$WF@^1VIZ9ICPYH#$W>HV9JV29NF\9JBN9NSR23_8AL5 -M,R3!^9H#902Q!)I1E)K).391I)G-B9R7@9RQ(9V:Z1^@B0,I4C&DJ9W0*9ID -M>)T]X5S;.2#9.1C(.27I"9W5J9W,V9[HZ5F_F9KR69IC\XN\29^K"9S/>)L1 -M4YVT&02Y*9H"RIN::7#Y.38(^IN:V6_&29_"F9`/43F0XC)RX3(F8C)&(!$: -MFC5"\3,?>J$#\B`?"AD\<>D]:`:,KNBH[\*': -M8:-"41@]BAH\.B!#D:)`$:0#E*,9"0)!*G9(BD!*.J(K^B--ZB=+2B!"\9D\ -MNB<A.!8J*%NJ85DJ87DJ8M&BCXD:9;"HAI^J6! -M(B)I2B*7NJ:\D:;,,5-,ZJETX:DO(JI=^G=D^G>E2J=74ZIXVI6(T95["JNE -M^J*JAF6:J&JD*EFJA=N:A=V:A>6:I#2I:ENJ7S4ZJ46D.ENJE=V:F+ -M@J;1VJ611Z:11ZUPNBARNBAT>D;4VJIP.%.;8JU]2D76:JMN::V$VD762A_B -MZJNZ0:V-FAS46JRF0:U;VGG42JDU8*F+@JG_2JW.6@/0FD=DFD==ZD+"$:@.&"K()ZZOBDK"-:@./&GV& -MJDQ=6HUD6HTMNZ6_V+*4F@/^F@,`B[,MZZR[T:7J5%6AFBFC*K0^FZW3Z+-T -M.HX^VZI!\*K30:;3X;-_*J`^BZM!0*CQ`;7NFBF^&@3`*G!0F[(&![5$5%5; -MBAL^2ZG9X;,`&P1F*D]0"ZT9-U/WU*5T1K=60K?9JF=T2Z<&0K>MJB!V&ZL2 -M2K=_*@3H"IMT2ZB-1K=;>VQT"ZQ"T*B3:[?%ZI)VNZ71:+>4*@3^2HQD^I)T -MZZPJ5Q+2%1(D*A#691&IFUTI(44W(1"]`KLEX2--=!$E<2RW:Z<"@3Y-Y*80 -ML2R_F[<"@33]4RL0P33'6R@0@26.$;L)TBK/ZQ)2@;L042Z(Q+LX.A;;0[QC -M([T<`;RQ$D2(%+L-AC#E"QE\@DB6&BN]PKZ<`3>3`5:)45Z'01F)@5Z9P;RQ -MPC?[ZT2)4606T;Z#QS@A0<"($[ZA&BO<`B5JFAA6$SB=DQCE(L&+EQA>,W[F -MVRX:G!&?\UIG%1"D(ULA?"M\8E2Q>Q&M@L(>_#H\X<&S\\(BC#[\)\++4L.W -MXB2THSHB3"T[G,)8LL,9>BO<(L0>;#P*[,'*D\0BW#Q0!L"W$CU/+",!03TI -M`5C$RZ8(@\49D697+,.+V2KO8[V\XB/O([[C(\;AF\7H`T"\VSZMXL9=["1N -MO!E53"UU7,+V\Q$Y@<;@QY0+'6MHLA4;&M!Y,BQ -M*Z4((\D98:HIHM!#BBU(: -MM,:7C"6GW+[I$\L#?,E3]BO(:VL`QLO\>T*.M1`D$Q`\A#`%4\S&$F;_^Q@! -M4:W(W,P+S$3#[!C$>T97UAB]K$1F-'S7#$7>G!'F*F'#%[N9)V/E+,Y>1+O/ -M+$9?4482MKOB;#'R_,RCLKMV;"P>@\\E7`-S-+SB+#(`'1`&*V%40]"R=-!U -M-4A*PKN&)&,-G1&+=&*I\A71\D=%8]%5A#46K44<[1,$[44-;=$K5A8@75\]($/4P,>@]95/4>Y1\;H]$=OS;ON*6&4L\`X($MWG1$X,$CIQM>Y]- -M\]ESI":QBV]N]A7]]DQO$A"P\4?0)*<).$CE0\9_Z-I@7)*J[.]Y2 -MA-^[Y=Z_PMV_Y=\+P=U6@S--$Q#9H=V`!]MNZ]VS@MYE97B]G''U/7X+3&?J -M+>'OC6<5?M\9,2#C/7[@K2`.SM8!D9`AGB07T?'M\FK7LG+L#;?>)( -MYA0GGL`P,>(-[.$G'L$JGE@5'.2@*[]21+PJ9\"ZTLML:.3X"R[R\B52M,!9 -M*1G[G1&SH>2)XN/@XB-2'N0;I^7V72]8KK\M'CD!D5!:ON!8[B1J`MX1U2IO -MCN7WA>/@HE]VCG*-DN>_3,8C-"212VGOMJ2M61H -M`<7:E\U4\AAXN`1>E;5D]BSSKNK)NFO3NI%T'[$ -M/L;&SB]A0<;V)V&!8^Q-;>=U]=7@O5=;+>R2=.O$FX"6!.X9$=Y7/>L+G%CC -MGNSI_DFWONVB].[E7DJW;NRI5.\9T734'NV\^X$-D5[.GN^#-"[YGDL$'Q!8 -MARIVOG4-X3S]3DQ@(OTQ!SC`3#^J@Y6\-5Q1V"EI1U_%3@1B@Q7,B -MOS;X"UJ_=O*>\1"@-6TGCT:;4QH,]UW6[/(_DW+?916H.O,HH3\VSQ$]#UKC -MUFW`-O/G9O2*@?/LMO,I'[W\%O3TNYFYIO0R#UH/I_0W/_/T9O5"+Z>@E6]: -M__4N;S(,EUX??[X0%Q0D'V%K[_$I;V$IEUXMOSEO\_:^AKSQ9_^Y/!^D<0J@$GQH==`*BKZ) -ME@$6O(,_3^:@P:$'LL2@'30"E43AZ,$[N&R\EB/\ -M@V;P`?Y!>.,)81_RLT.6T`KF+4Q(;THA":2$^<85.L&AM]-TWI^P'_!&Y%W! -MY33W;F&"ZX61+ZG1/EW3X(;A+G1_OM#BN)O-8=4FX"U$.2-P%RX;)/@86$X6 -MU'O:I!&2'IBC#9%?70-ZCO!)N+R\5O.^((ER+B;/Z0D&H7<.<<#*DWHL@AV. -M0YBG#B^(/-P<.(#OP4.[<`^=B^NKAY\I]K7#G\?ROEX_Q`%%#R"VPZ0'#\4A -M/FQZG]#W.$3GHOCVH41LA\6O'O)#@3@.L]X^7!$3$0=T/8#81$*BV&N()?$< -MIK9AB/(XXFT)>=)/)7Z^B-@/:QM+]`PU$?5]0I"H$E>?*JR)KN_YI4279_P8 -MCO0;BK<%]X5#E;C[S"%1]'TTT24R#,6W_`Q"32Q^QV\C?@^5J/Q^HE3$6<(O -M'")%AA']ON!8M&Z!T!1.Q.R6"-N@5.QN;;$EQL.WR`1%X45T>4VK&\I%K;@6 -MCXXD=(OV\"UNF[\H%P/B5L2+D?`!&L:U.&YD(<\[A_E-$SK%S0&V)*,IM(IO -M,10*PGZX<"QC$N2)>'$-BD+02!E;(0,\B[%0,8Y%"@<.7=SFP'"MD?Z\QG2H -M&:0BB+.%MI$>5C3;^`_K'VS"C1"P'S::J'?!*@9#M&,5`R)NP\56]6+$*N1& -MW(8T5HPO-1V#S;$)?RXOR;W&3K6AT%1W='FR9SW0CJ%7Y8SA7=P<66X83D1^ -M8A1WXV%$CT&Q_JDY]3@6F1*YN84(\?'I/:B$;O!C4XQ\T-#X]<.AE*,J1KX` -MCYC*0.['3:4@Y:#+XSW=+_!L#IP3(4E>HXN0>R?8K$0,J?>&BOFK?]'G0Y8* -M$'G_BB.E68#(,2YQ&X)W;P9.AZ2.1B"W3,@$&2,[)(.LD0YR'=R+,Z@%[@<BQBI<#FFQD-)"LN$..P/"$)P -M;8X862!CI`*(+GD!4UY*@T`@H@M&P)0[0%-ZRE#)*3>E>(DN?"&Z-`A5:2HA -M172)&='%(\1*4PD7H@M]B"X5`E>:2H(07?!#=7D1OW)3PA)2"4LVI0Q8#)_C -M6!K+55DY'D2R=)44RECRAF3)'+I+IW1EF[+\=9=4N1"@9?O+EK)R(3B$[B(1 -MR&6V)!'=Q41\CA)"*DO(IF1EZ_)6DHEV>2$^1^:QE^.R-$Q+?;DI=]KG8"7] -M$E@V!"OQ+Y%E0^"6P.1?.LN&`"W%T+\,E^'I7];*AB`OG"68*S+SF,C,EF`@0 -M,/-:ND.7:3"K#8RPR4.R)?Y$6;*2QR0*\$$QL0!&A-JNLR. -M"28^)I@(F3A@9(*)DKDU72;*%(F;,K5]CGX3-@4F;`B;-I,\A,UK^8?"IL$L -M26&36?*VL`DM@5O8#)?&+VQ.S.,6-IMFNPF;&O.YA4VJ";/&9LB<69\C:R7. -M6VDRVD."H0L)!EBJC$OI,D*ERZ"<,R/!?,J=83E+`^9TE28#5@Z-SCDNET;G -MK)F3LS9,:4&YBR7)F-DFHR2.3LQ)[HT&>I20W7.:GD7'&?OI)P-AG2` -M%^&9*<\&\.R4=V%S8A'+B46`)^A4),`S5]X%U'DXF*>OO`NM4Y\(3]CI3X`G -M[9PIE/.#D8[/$3XE)^D(G\43R(1/9(D7;DUDU#?ALU;BA2!QRZ[8B6`4/V(D -M7$\9`#OY9_BDG6%J?$Y+O,`[J0?I4%,'5'*ZJ0.*/+<'Y=26:R-5KHU5.4$? -M*.C\E@=45JZ-TDEM+">U>:#2D]L\T-8);0XH[`1$!Y1V#I`'>CL1R`,=H%*' -MZHBR3SAT1"EH%3JBH%,A'5$-FD6*J/SL(D54>L:K(ZHZZ=41;9WW -MZHC"3GUU1&EGORJBM].?%=$!2K`HI\$B'0@+CTI.AH5'B^?#PJ/(4V+A4?99 -ML?`H!<58>!1T;BP[JD&_D!V5GR(+CTK/DH5'52?*LJ.MTP9\3$]B.16(':6= -M=LB.WLYY84<':,*@G/X2EM306&(Y8PDJ+9[/B70`DE:Z.9.:+)6@"1.6.$M8 -M`CH=)BS1H!$3ELA/EB5+I>?'0*6J4YJ@TM9I35`I[-0FJ)1VJC54>CO%"2H= -MH"V3=#!-R\DT*>=SLYP.RI4Q3I>E8GX7XVQP*J:F,4X"23I62OA:I[>S*[U3 -MRKF7+"?1V1ZW(Q" -M=6`(M:#ZSX9:,H&,B&BHT[++#%0#"F8&JI0",B>GGQY+9'DLK0)#/9:R\EA" -M5(^:*X^E<,NG!2WGB%0^"&1\Q4E%A4`F`HG3@3HOGDT?@ZEQPDGM5"#C+WF, -M.AVHK+2FKE2B2E*WR%!=$JMR29C4?&K5B&KN.:D6$;\NGY)"H -M'M2!2MB`3%\3J?EPG[I#M%HK<\95!:LM]6B*U(4#9+#14TUP=?6E#E1TJF3* -MQ$F%6W5UK&H9Q[DD?NI`;2M$59&=5%=S9%;$8NV4G<6<'E9>*3PDJY;IF'U& -MI#86)W-4M4Q%[7L[E47`!=&J`%A$A3"ME[)6.4[5FEK]R+'DH[4J4\;6UMHI -M:]6GK%7($K>VUE59JYQEK7*5O[6URLI:-2YK5:TTKJTU5]:J>EFK>&5S;:T= -MLU9]S%I5+JEK:RV9M>JBUBITN5U;Z[2L5=6RA*Q6@(E2@64)(9@E1+;&TA)2 -M6P%):K6EJ^>]\E:'\5Z!J\-T/:'2];S7XTI,2XAR/:8HU;DJ4Y0:79LI2JVN -MT!2E8M=IBE*YJS5%J=\UFZJ0U1HS58AYI9DN5;;VM=3J#O/KSG2IN=5GJA#> -M&C1=*G`EFBYUN!Y-#GM<$2*'5:[=U*4Z5ZGI4J,K#IBN6=/#CDP5@EU!&X?E -MKF#3I7Y7?)-:Q29*@9PHQ;R>S6-)'O*KVF2RM;5M,MG<"C>9+&^=FTP6N-I- -M)CM<\R:3/:Y\D\DJU[_)9)VKX&2RT;5PHI3JBCA1"G:U6466N^HL)OM=>]:Q -M5"=W%LEFMSN+7KO;G<697JFV*JT[FUN;5FI]6G?6MPJH_$JU[NQPO5J']KC& -MAT.K7+W6H76N`N?01E>#I->,J':[A9M4>5PF1:I5K:TBUSK5R -MK=KHBKE6;77=7*L6NWJN5,M=7]*J_:ZEZUBR(6V+9&6/MD6O54[;`MHLIVUO -M*WO4MJER?O#6C9-:"TI^+2CM=K@FE'9[7-]"NU6N$T7;.M>ZI&VC*T9IM]75 -MHVA;[#J4VBUW'2GM]KONI=1*ZE3$#3$O#^W=6":O;%I=QXH7+C'5Z[ -MD'AE!"_*+H\79ZJ\QOLI7U[C396@955FWL7K*D$+K`0MLA+T+MY:2?06;ZX$ -M+?42M/!*U;MX.R9H^9A4[_&.3*S7>"\J:$&7MW?Q3LNP=WC-'B\R&;T76,8+ -M@ADO,F7Q[;V=,EY4WLCP>S'O\OR]SC)>=%[H^7M#;['\O:3W;_3>TSMX>N_J -M/1R]U_5JSWA1+LEO[RV9DJ_WXMZ`T'MW[^8XO.+S7D#.>R%\SR1/J_<6\42CQ1B'XVWEY#/P-O:KC_I)>P7%_3V]G@;^K5\G`7]J^.+TB]`2O7OLA@EUO"=T7Y1>%[@OTNT)/ -M,.YUH2=X]\907C1#@]/A_:C_@OB:*BHL>2D(%:Z\&80*8]X.0H6C;ZU*O#N4 -M"H=>'_HO2&\0_1>GEXA2X=4[K*BPZTT?5[C\)BLJC'Z9%17&O2?D"N_>/G%X -MC>C`F+_5BALUH&4R\:71@E%\VJ@91L>WU9ZC8`[]!15PM,:'CM,6'U[5B0N)+ -M4S&AY#4DO$B08D(87$@QH>9%I)BP\R[28!QZ'6DP)KV1%!.>7DJ*"5?O)0W& -MKE>3YN+RZTF#,?H-I<$8]Y+28+Q[3RDO\I?(:?XF5>IT>)?3.9:\L_0<5UY; -M:IW.L>:EK^>X\SI,Y!1Z(R9R(KW$-#TE7@"+G%;O@$5.KM?`(J?RFV"1$_IE -ML,@)]SY8Y+1[LREY2KPQT[D(7PR+#C&RY.VPO.C#.A<8[#.=B^8ML?X0(W_> -MHXF1.W'2="ZWTKFC1CS=\_^I\/K9R.& -MY!5OO&C01@P8;&@#L^:-6H&Y\S;:B!%Z(6U@)KV3-C"?7DL;F%=OI@W,KI?3 -M!N;R^VDC!OH5M1$#]Y;:P+Q[42TO4K458_[2F=-,?/',:9:\(.XT5UX2=YHQ -M+XH[S=$7<25>7WN:0V^PK1BDE]B>YM-[;$_SZE6V%V<>E>2=O:5&\KU_EOM7'X%[H9"OP57.^->A*N==^_"Y44- -MU[C,7YB"H(DO34'0DA>G(.C*6^D0-.;-=`CZ0;"(]K"A2VNWW`&_(F;\BM%Z -M;SPTMP'1_,9$$X1?@1\:@T1H#%KANUV(QD`B&H-VD-$>NO$T!C^!HQD"-?/1 -MJ*%'EX;%X*-9@I`V5SY:+AQI$IU%0,"17M&HXDB_:._@I!_1C"X--;HTW&@K -M[:$-EH_FT5PZ;N2%N!&DPS050M&+I$K_S;CA$>*&71'2E21NK`8AO=/B!IA> -MTP,33=_I%MT0"$1'L`YTFD@W!$#=C3ST4^L(2MI,DR$4/3&^&Y]V)AUA3BMJ -M**U,U/2CGM+61$U?:;7&J&-TH?YN@KI6:6H/[;*^&Q'Y;E-Z9GVW+&VS1O5W -MXPVOVD,O'(:`H(1T@Z/56QI/9QQ:?:>O-)Y)065:5PMJ\R2D=7,*2M2ZFD13 -MG&(-I2].L9[2+LE5)X@L[;FD-1M*0;W:0U-K*]TB.37\=I= -MGU:\DZ[]-91>+OG:74]I[2.MX1**9M@)>VP(Z@(EI"4>0]@LTGH&,030DK$' -M=KS(V%#Z7F3L+&U<,C:L'AO,P=>\")5=6J\'B,X>OL9/=X^67?Y\#5_P-0T" -M9]/L?7T^:':;WJ`T>[2N#?K@:T[KVIC1:V-%)VV:/11\S:E>&R\::M-L$.%K -M1(2OJ=%KPT3X&ECM0%HVDQIY=&'DK6S%8"5&WIA6#`%BY,GL537RB+1BN-DV -M]&6+PY''LW?HR/O9[G+D"6U>-?*,-A$=>4I[6(V\IJT8GO;\D-M98^11;<5@ -MM14#U@[$(X]K$^*IH*.Q2-C&(F/[6E'NL^U$*;?,]E:4VVW#(Z?W44IM]`&HY3;:,G@I=6))?;CQCOLJU(SO;#,MXR6V(9;[==L8QWZ<98QIMG+U+C_;,=J?$6 -MVB++>!OMDF6\E?8E-=Z$6QL;[ZCM28WWX@ZEQAMKDU+CS;5/Z52HTZJT9;/2 -M^\V\E]/]3MNP1&:[U_OMMF>,_B[=]/5^\VPQ=+]_=GBZWT*;9=UOHWU,[[?2 -M5J;WFW`WT_L=M:'I_5[K^Y=LN<"NX)A5]N]D;%H7+ -M[)V)PMUVM4'AI3MHHG">3311^,]>L2A<:+M8%&ZTNRD*5]I2$X43[AO;LG,L -M"D_V*XX1KKC;AIM7O'3/S2O.L^WF%?_9>?.* -M"VV^><6-]IH>/$I;<%YQP@VSKGC45M6#9W'#V2N.M776%>?:/8LFG`Q!'K:K -M"XBN+J4U61[RRI'(9X8@[^+Z5)#?;'NYR#7TY]C7E[R1M^E_V6G -M7)_@/7%Y*P>?N!R6LU^:\,'(>2$?8>2\;#?40ZX^R7DPQUWDG)@K2W)^ -MS``@YZ'\`9-S4BZ!R?DIK\#D7)7[3W+>RL,4.8?E -MJ":1\R)VGK+!S"%74U5AE[NIJN#+5W!5".8.M"H0\^^1R--85;#D-K@JB.B+ -ML,EW<%7PY!^T*H1R$5H52#D1K@JG'-I4!54.B*I"*U^A50&6N]"J0,MC*$WX -MVL>RD$NIHZ[.3=513]LE]9"S[9$JU2=Y!SGJEOP,'_65SBZ/ND.@"3HZ"A7R -M:@76U?F/CD)0'9N!=4C.S<#Z)!]78-V2(^DHM-(S#UC_ZE'(D\/N*!3*9W<4 -M(N6V.PJ=\MP=A50Y[XY"K?QW1R%8+KRC$"TOWCR&0T?V1*Z\>8PZYX,TX7GS -MF&`NO8WJ(:_>/.:88V\>@\FW-X_9Y-Z;QWCR\,UC0CGYYC&D_'SSF%.NOGF, -M*F_?/*:5PV\>`\OG-X^AY?9[24AV@`D_=KDKA1^^_#G!CV`^P)<$,3?@\..8 -M)_`E@,Z0[-[IL>QRFOE8?'D,SQG!G(;G#&)^PW/&,=?A;O60]_",[PY$,\ -M9X1R(YXS2'D2SQFGG(D_%E6>-1.Y3WXL5CMGP'(KGC-H.9&E":D-Q!?RU@;B -MU3D6CZR)?(MW%DB.VT#\).=MAWR,=Q9,;L8[RR9/XYW%D[/QSA+*UW1G(>5R -MO+.<\CK>652YJNXLK7R/=Q98[L<["RT/Y$I&LK\'FI#=J+PZ[VY4'JJ+-RH/ -MR?,BE9_D3XO*6_)%2^57^M4ZY)"6RGOR24OE0[FEI?*D/--2^5/.::F\*D=; -M5+Z5KRTJ#\M++96GY:B6)NQJ.2/H=_FK%?2^7,\(^F!N(`0],1=<@OZ82RA! -MC\E]K:#?Y.%&T'MR8BOH0_FQ%?2DO'()^E..N02]*M]<@KZ53UM!#\M?DJ"G -MY:6+)EQK_EG(98^L5^?;FG]"]2PGZR$Y>Y3UD_Q;\T]+[FYE_4H?U_P3KS<4 -M64^T^6Z@^KY,')*]TXWZ29[IQ;\D]Y+A?Z?\Z>>#UIG+(3^ZX#^4J=]R3 -M\I8[[D\YS!WWJGSFCOM6;G/'/2S/N8D5\6KY9$GG3H0E/!^GOB'IMKNV_#7Z8EM^6+VQ#?\MGPIA -MF\(@?O#2O?8^7C#]?C_S=:_`O_2Z%^%OGMUK7QMOT[_XG3D*7_U$^XJO_AD] -M%2C_-:\GJS_S.[[NE;BG@N<'YU,A](_SJ4#ZW^_V*.>"W/"C'_7P?[/!>OC7T)D]_(MH^!'^O_IC"?_!O[.$?^*O9,)_BQ;TX3_S\\_P -MW_RMS/6WVA9?^*>U(7WA7\I&]R%^&%WW@@"6;=Y -M?0^DW^0V/G!H9Z#A1]:-#PS@CS8^/(!JW?C0Q8T/@=_H-CX0?E7(]H"DC0_K -MGUTW/KA_[(H>&/R%07H@\5=&Z('WGVF`^.5NX\,6R+N-#Y[?[S8^A'["V_A` -M^A5O[0\:B+!L#\I;^\,`8G;MSP-H2'""<^!$PPF6?Q<-)XC^,4*_M3^AW_S6_I!^]EO[ -M@`82=^T#WG?M0$`!F7XU`!HVN!3!F"(QVVD?B1>=&3X87'< -MQ@.XQ7$;]C#&<1NZGQF';B!^:1RWX?BQ<2L24$C\?5,ZX?U7 -MJG$;F=\O`A0V?S8+4`@`@D4ZX0"X&P"%!J`ZL3U,>?8#WN=.&'Y8GOWP`&YY -M]L,?H&XO?FV0^4GYQG/V"!=1XN -M9!OJ# -MY[?JZ0^AGZMW`:6&!N"U=G*D?K;>R<$`;FLGQP/(ZYT<<^"O=W*4?]\:$63X -M%7LGQ_HWKIT<[M^R=W($?^=:';0<4G[3WLF!!5I[)\<6F.V=')X?M\<-;0_? -MWLE!^HE[`P0::'-L#^_:`,$`JGL]A^$WK_T<\F'@MW&QAX0?4<(>ZGY+!WNX -M^"DC[*'CY^\-$)%?P#=`4'X$WP"!!1Y\`\06J/`-$)Y?PS=`A'X0'WM(^O5< -MVT/%AT"D?FU%AL@`NAH9X@,8?V2(/1) -M':D?:;$],'U2Q][W]#V)?I_4)W4$?E7?DTCX87U/HNZW]3V)BY_7]R0Z?F'? -MDQCYD7U2!^5W]CV)6*#:]R1N@6W?D^CYP7U/8N@W]TD=I%^=I`!<+3L-GT@7 -MX`8G0^\T&MP-5@*@.*HT3DJ*(@&D'`[T`:`(IR"*A&*B:&D!BE8*I*@H2HKX -M`:"(IUB*M,)=P&D!BGL*I[@HHBV`8H4B*DJ*(@*@**B#5BCIYBIC@;<(V3HZ3H-AXI&B/E>#C(C0I0Z1@SXHT?(^=X..R+GPJG:#KN -MC/P$W!@Z8D]`HZFB.A*-UB(%L3L*!0YC!O$[&@BX00##IXCNW)`?HH;Q_6H2"0$GJ+<6$8LD/:B(KA`LH^@X]T` -M0.3JF%`\CW2D -MS8@;6#5K)`CH%DCY)&;HZ-I)XQ2&:0B@09$\Z3<^+>&D_+AHI92[XIF74CJ,68O&6$KF-S(E -M&HD;@"TU)1MY4R:4B@2*HDU^')3D%U)'WI3.Y+3H4^J1#4Y.>3B$E->D4"E( -M8A1K8[EX5/J-=PNGZ%.*D'B&4OEJX08@CE;I,)(X6B7DB.)HE15Z3E:(UJEV^BYY)7PHMP( -MNFB5]J)V)%>^)+@!&Z)5^HVRAU(I/U8YCN6NF.4XE@XC>Z0Q1JH%,:)9UER)A8]I.*A&=I,EJ+<8YF&4&BE@5E:>E'`B.JY>N(6@:5IB7M -M2"#%EB+DGX-;2I9-I6DI20XE427-Z%M"CC`%;HD\TA2X9=6(4^"66F.E@UN6 -MDID.;LDM>DBX9<<8(N&6GB._AUNZC2<2;BDW6A^XI;T8Z^"6^^)D@EOZC0Y; -M;"D_YERAI3%I+0([ZJ7#R"IHC!UC6T%?;I:NQGWY6<8?^N5/:7_TEPQDDP1@ -MRHW9#H!I+^X5`.:^*","F'ZCN--?BI#FSH.Y*ZH[#Z9\&52^*/_D2%%4W@T8 -MYD`)]#V852.2^&!JC4W'@UE*DA8/)K>(6CR8'>-J\6!ZCJ[%@^DVQA8/IMS8 -M)SV8]J+$\V#NBS/(@^DW8CS]I?R(*`69NV+%4$]BF(PC;K"AU),PYH:I2!0I -MC**U2"EIC%#FI+B7-)559J:X4@27TV*5>3*N%*68*DBM%.[EF&I(KQ1WY9MZ**P4?.6<6BBM%/CEG_HHK!6DI9F)/P^)*@4A" -MF9KD2M%:_IE"P;*X4O"4B&;TN%($E80F#[E2.)F-9J.X4G"2=P.A*2ZN%%@F -MO*AE1HN<(J'Y93885&9@26;Z**$FO)@JU@EJ9J/I*M8);F:C.2O6"7(FHCDX -MU@EVIJV)9PY+I>;AR&>:&!KCJ(E(UBA19G90,'**Q.:D6"T*LN6X&F@'8N8D]'8M[0JZY;BJ:1N.XF36&FW[FNBEIRG_RYEP9;AZ: -MZ^:F&?P$G.>BEK)MMHWAIK1I:I:;UJ8FI6J&FTWENOEJ4@\(YZS)I@2>FR2Y5G5HF*U-U -M?IFP3-5);6Z/7.>JZ3URG:]F^,AUSIKD(]9Y:YZ/>B>>J3[JG7QF^\@IKIKP -MX^!I4VHK]>2.XG*2F?BCX=DY,IZQIN+Y*2X*M:;D26T*D([G4LEXZIEVB*3X -M:BJ0F>?.N"@@DHHGG3E!9IY;Y:+`:):>@6=067H&FAZDQEAZTINPF.P)+RJ: -M;Y#M&4J2F2PDZBEI*BRHIZ5)0Z*>F^8-B7IJF3HDZOEE^I"H)[491**>JR81 -MB7J^FD"84J7LVC+QG4$E]4IIX@LK917**Y>?BF1V` -MD>BG:!E]<)EW0_HY>9J1[>=JF1VHD?6GYGE_MIKRYZN9U&B,\N>L"4P`H$?G -M_9EKII^IYZ)&@.Z3]Z>?B8`&FL[$`@HUWI^')@*J:%H3]20"^BQ&'^(GO"AI -M8I+YI]@8?42<".BF&==(H`GG*!F"?IGD$`I*;:Z2(>BJZ4J&H*]F+!F"SIJT -M9/YY:]Z2.BB>J4OJH'QF+\DIXJ"())52;#85AZ81JFPBDT.H^[E,-J'>))GI -MDVF,2N@+&G$JH3)H4ZF$OIK<)!0*9X*37BB=24Z&H7AF;4.%PHM\)FYSA@*: -M9&8\&8;2F_3D&IIU9@=%D1SJ:!XW]:01ZC52&D5H*MF&)J'PXJ;ILMBA6B9# -M&89^F0]E&$IM2I1AZ*I948:AKR9&62[JH;,F1^F%WIH?Y26*9XJ4ERB?65): -MB@!3=H!2@J(OXZ0EBMJ9K$0UF2GHF:GHXRF*DI:MZ&DIBCJ0L2BIF"FTEK7H -MJCFV+(RU:"1*2=:BE:B3&8O2F4DE*8IN9@K7Y##*9\XMQB@;FAU4E=_B,$IO -M9I7-Z!RJ?:B9P^@&"E96HWOH6,F-6IIF)3>Z:::5T>C+F'"VE>4HP_F,TJ+F -M*+595W*CJR9>R8N:HZ\F7\F-SII_Y3PJ./Z)VH>U&8LBCL]H,OHRCIR*)2B* -M9S:6!NGA"5DFI#KE78*-CHI:IF7)D,JB=XF.9XF97RF>8E*`J6"J,ZHU#JC^J,16DRJC-JF?.E -M6'ISVI=N*4::7\:E^F?.A8WJC*_F?TF7BIX")EU*9Q:8?BF>B6#ZI7SF@NF7 -M!IH.IE]*;T:8?JFB26'ZI1MH8\&+VHV2Y@,RF?JAV<&'Z9=NFB*F7ZIEEIA^ -MZ9>)8OJEU.:*Z9>NFBZF7_IJQIA^Z:Q)8]*EM^:-"9OBF3HF;,IG]IB@:*`) -M9.:FA^>0R9LVI$8F+SH[?J:_Z.PHF@JCLV-IZH_.CJAI,CH[NHH"`?P9P(VD -MJ@LQ"4@4H`*!F7F=+IVRBW7*//Z*`H&;N9W^DP*!1^Z)`@$K -MRCP^B\6+>OI6LJ?_E'"*F0H$N"CS*"X*!"PI\Y@I:@3RJ5!P,@H$R.G#*1`L -MIQ.GV_*]V*?8$W0*:D:CS..L&"NF(T#JO@2H26:L()ZBI\L3 -M+[I!FJ*Q`BHZHNZGO"8H.J+^I\"FBCI4Q@JTZ(C*,L8*N.B(FBHR,-;IB.J@ -M_J(CJH0Z,8JHV&G&Z*)RI]HFD,J`W@K2Z8P!+PZ+MP*%&D*BI^;FD#J'W@K8 -M:`@)GR941FKU>"M8I"%DHW@KF*B!*'N:;T:C(>1_JC1*J>SBK1"C&JCU7Y9Z -M-Q(Q.>H4*:;RJ/"BA&IE9*D6ZIB"IQ:*44RZ,O`(M -M:DG^B;P"+FI)\JD_)Z4J2?(*OZ@ER:06G9NJ#`FH^J.6Y*#*R#"J:R5["G6^ -MC!/#?.JV4)VJJI=Z=<:JX:*NBHU:DO^IUTFL"JBZJD5J2J>J.>G:HJ -M=*IVJJH2:MM)J5JH<.>RJJ'.G=XJ>&IW\D.$HJX*-BZ*U"*)RG>2JPSCI&AK -M?(SH*D3*G@J>[&JZ.J`6GO7JJ#BC4C.]4[RZ.AH+Y**_*D@:"^FBP&I(&@ON -MHL%Z*QH+\Z+"RJ<:D"K#M+@N@J>@9[ZZI,ZK`:/"BIZ>GA8KU3BO7HT**WS: -M>2B/"BL/J<^0K!+K?5I[1JP'X['EMN2>+"O#>"[6%5&EPCJ@`I\=JU`PHPZ? -M.>N;:GSVK-!I\MFS2JC,9\YJH3Z?1BN?*GT:K>!I]5FO-JT9J^%8;*(T*.O= -M@):RI]YGS%HS:I-U!<2(KNJ,-^NY*K62BG4%V?BU_JOLY]/J>;*G8Z36JC-* -MJ/2GVDIN!C55*\S(GJV#*!]Z[S)MC:L>NN@JH`&KOOF -MW]HOGJV^JK(0M5JM]ZE7D[="KL7JWPJRZJW_:38TN=JMS.K?*K92KCHKVVJV -MZJTWZ@F*N"*6BDW-JK=*J"THXFJAPJ!R*\+(GLZ@L6N':H/6JTQJ#HJ[VI2* -M#>%:/^J4B@V^B*X.I[/KXDH]?HJ*S>.J2"2GLZO4.+S^JTSH[CJP/J'2Z\$Z -MA6JMS".I.DUBK^BF8@.O4H^K:A=:O1*/"0BV^+P*KF[+&#J^#JIF*/>Z>Z:O -M!2OX:K*ZH>.KEQJ'NJ]"P7Y:A^*O,RL>NKDR"^KH6:+TZHGJIF:@'JZAR -MHB*L*QK>Q*]7I"P:WB2L4J3]&=[XK@_DO^I2:JTZ*GL:4]*PU"E-B[6_WJJLJ<=Z2;KDCJR -M;6P@2[Z6I)#L!`HN.*^=)"A[N2:RT2.XX+5&DB;K;2G*BHW@`B";2.:OH"PA -MN\O.K#WI+3N@`J6I;+PH67B+Z*HE>:,:I<4L=)J4%K,2*E.:REJH3^DTRZ=* -MI=,L>%J5UJOP*5;*S?*N6^DW"[QZI>(LUQJ6EK/(:WJIM:J3,RI[^;^JD\NL -M+ZM.0J=M*3HKH<*EY>S".I?FLWPJ?[G.HJ'LJ5Z:SS*I?6D^BYX"IOGLH#J8 -MYK/PJ6&:SYJLB6D^ZZ4RIOGL?OJ8YK/_J63ZSV)/`ZIENM&&KFZ+9IK/WJB= -M:3X+G8*F^:R$.IJ6LQ:J:*F/BWRNIL&M3.J;QK4WJC!J=9Z5)ZTL^S=,%6RI\;%`'M5DJI3IE+;O=9) -M4BU`*T\$BE:M,PKR9+7H:\D#ULZAD]?_>E4^BY:76>N![HF9UU@K-GI>;JVX -M"'JYM9DBT>/6GHRHEUO+,JI>;FVJ^'JYM:XBU:/68I%L+=XQU@Z.M]=A6RB& -M/8?MKQ@O(+*E)5M+:FJMM66C6'P-L+6E7&MA_*^U95T;&7"V0^7>@]DVLM+7 -M:!O)2K;"Z[186P:V+6J]6EO.BO&"\@JR%*#Q`BM[-_B6BZW"2-EJM>27:?M/ -M2CZ^K289+^BRON6R&"_XLKXE6NMMNK9KK3PA;C*WVR);&Z5"M[RL -MIG1[RM@_GO0##Z92M__BO2#;FI:(;9NZ -MV[J7SNTKZUK^J-MA+K::*KK:83JVGNJ& -M^]N>:/]KAWDL[@NV[7Z[GLH3J:J)&STB81=N<[N$U;C1+8PKX(:I,&Z!F]W* -M$U"GB*N.9F$X+D@[FA2Y=^._,.&ZN&LLD+O==IBP;=AIXB*VT>J4N]A2JU.N -M8WNMUJMUK;;*Y=J4_T*+BVA.BO^"?3OF=KGZ[9B+U^:=7Z[]^2_HLE6F7_MW -MMKFRI3Q!KZ*K529LBZ_BN;0MOZJU$IJ+;>-)YTJ2DM@`2V@.BY68H:O$8D'_ -M*Z%IW$*L@RY:6['RN;[JP"#;$IJ6+<=*Z5:WIUBC^^.J8HIN=VOG?JYSYEZ[ -ML@ZZ?BW,.N@&MKWGH`O;XJR;+F++L\:ZB^W/&NLZMD(KNHK7%JVZ+IB+M/:Z -M.B4FE-K># -MFY@I%IQL[>$*[YZ+_UBY*^H*9/_KNKG72J[L;H**D/F[^F*^2^W6J?GN -MM4ML(K;B!,(+D%)D$J]CJX+6JWMMZXKQ@KFP*[HJ<\JUM*O'*UJ.9`.LS(G7 -MZJXBKYO+@VZ\IZT\\8.RO'4N3%;RCJ0RV2[\ZO7OM_4KT^K7[*]$;V/JO7"_#R_3*MBTG8GO`IKWT+5JF].*W -M:]D`2_9>NY(GU:O+2IY7KR\K>=:U&NRT*'GBM1TLNFIYLK4AK.$;X9*PBJ\@ -M.9C9O33O*%JOEIY_8L0PWI:>B^T,._GRMC?LYNO5ZK">[P0:,8BYI:=Q&\2& -MOC,N$:NUEIX\I&<&^>:XH=GKR^G"+?]KZ5G73K&-;^=:,42]=T/IN==FL;EO -MDMM5KKYRJCP!Q@:_L.T8F_LBMF;L\KO8IK&"K^#HV**CZ&I@"\=6OV#N'(O] -M!KMV;+TJ?]Z^::[\B=?RL=XO:3M8:JWRIU]K6):_CF]!ROX:DMS9`(N`5KZ/ -M[/;[PXIG\B]O*Y&^O\3CAC+OBA!A;2>+_KZX&\JPJTAHH&QM2#H`5[JHK/W[ -MUJ*D"S"G"UM&P/PN3$H!X[6V+/^[U]ZD_*]?JY-2P(%M,,O_PK;$K/V+V`ZE -M[^_$R\R:P([M,XNNDL#_KQ)JV5:S+W`U:5P8P`G#R+O-UL"1JG$AVU:A;&TX -MRP/KG\:%F;N%!L%IKA)*`E^[>FCEZ\YJK7KH8@M?0L&\;3T[!/>_^.P5O.+N -MLU>P<>O/UJMZ*%HKT%[!K6]!>P5;M@CM%2S7+K17<%WKT%[!>&U$>P7OM13M -M%>S77K17<&"KT8+!:F^,Q`3OHVRM2#L$3[PE[2#LV**TBV(H6B?QOJH4F.O2 -M)L*EJ%P;TT+"(R]-2PGWP#?M)5RIUDDP;"[*UO:TFO`Z62>5LL#H)ZR\#J.5 -MKU&K"6^5=9)]JXQ^POKM,(KH1K6;JS3Z"0.RPZAQB]76PN9HS'!/<+7LZC#J -M$/S"C/`P2A_\PLALHCB,7@B_\)([C.('O_`E.XP2$;_PO#N,9@V_<"=LCHH( -MO[`!/(R:"+\P*6R.,@>_\"D\D-(%OW"+^X]:";^P*SR0!@B_<"S,#@,*=6M+ -M.FG]PKCPJ,@,0PSUL+QZ3SRHB?"H2`T3!OWPF/D/)\-W@3W,#0L0!;'-^`]+ -MPZ,B.9Q$-,0?B@+P#W?"Z^(\G*(&PQ.K16P7D,+K(D;P#Y_"-:E'?&QRQ.OI -M/^P*KXN^,$%!$8<;_S"IVY(26_]P/ARF_L.$[$P,#:\7+_%`_-P&Q*;F/3'= -M`L7UHD>LPM3"ZR(X7#E`Q`RO4&P-+XH#HU",$=N/1K$W#!7#PY4#*8P5`YPQ -MZQ91.0K%ZO#5*A2[PFNI41P+@ZU&L4RL,V+#ID8]K#,NQ&=C5XR7>L0(;B+\ -MMM+%Q;#=B`Y;!&[Q/7E/A)S!L-V(%3^J@?'%^A=;PW8C7_`7=\)VXX/P%WO# -M=F-+7.+:Q6OM7WP*VXW'L,+1%Q>K?S%9G-W^Q6_&P2AF[EZVQ,UPR,HZML30L$GL)]?#LF!E7 -MN8GP[+@/8[G%<RZKE,4(\G7JLY;$S_)YZQ/MC5\P\ -M#L.60G#LAY;'G;!^2A][P_XI?QI'P/"Y?%W3!67QSEQAHH5M[J)L&(\*Q3#'ZQ'/.LJPR>JB.P,KZ@BLC0\ -MH@[$O"Z);!#/"IVPC2HB>\,U[#UQ[+K(GJ)$C'T&PR'D7KQ]\LA^\:S@"JN0 -M(G(L;,2*R#+QDRHBX\(AI&.LZ-3#5JI''.YVR)5QGE8+=ZE2LGNLI'+&?1J4 -M_!D?3%YR=WM/`*Y`\H$\)L?("G)#0",WR(1D5QQ"2L01J)M,(6=,8;+L.B8/ -MR=*OE!P+.\D@:##LQX[)N'`>N0^;KGZR<@PF0+:]ZFEY3VB\B7`>R19WO,HP -MINH1A[R1\MJZ*$O#>:1$C/)6RHKDHMP)?[*+LC=L26+%0FBAS(8NRJ>P)>DA -MX[Q=<:TZ*;O"EF1+3+TVRE7RT$LK1[>+,W?*HF!F_O?;-P6AI#VR.#DLDXWQ\MHR+'^, -M];)2+(G6RQ)Q!QLOURTLBK?X+\_#).R_C!5_HN6RS/H;2[[_LH>\4KH,*2M\ -M/!#@B_]R2]SY_LOX,>C[+V?&/6S";"[NPZ?OO[P3J[X>\[HX$".Q$'/+RA87 -MHR5SFDS[ILPRJU(\Q?[+$C$T&B]3RUGLS3P/#[\M\Y]*HZ2+W3)6/,8&S6@D -MC3(O$LUL)(U",8^M.S$ZBC0KR@D"N#RVLL5S[--L+R<(Z?+8*C-#C%9SS0PO -MZZU[\?GK,=N-.S.^K+=BQ>[OTVP@R"C8HMKL(3^R:K.3/,F.S;FJC`(TZZWX -ML29+-^/*$<'1K+?NPZ'LWBP4[,0*L.",N<@H4C/HNKG(*%*CVKP03\"&LU)L -M`1O.$G$&_#13RQSPY3P/?\"",V^,=T25W?)O3,R&SD4SWB$P'Z_[,#-+.C^> -M]\0SNSI#S=+LZXRVM,Y^\^^J>;;.2[/M7&JUSMSR\2H1>[.O,\",=S3.X.L\ -M3,X&SUCQ.1L\B\Y?L^TLN+3.]#+XZB1/P1[S?'Q/U+/!,WZ,SP;/F?$^&SSO -MPU]P\+P3"[3!\T!1]\1*NT!'QV/#Z4Q` -M+\0Q[0,M6S;0=S,!+1'?M!:T\*S3=M#S<$_;06/%0&T'_1L/M1VTAVS4=M!. -M_",'.:ACU!PXV3\MA!4\,J@Q`] -M0R_.E5/OU$%SPR8#N=A!@\,F0P9]0T/(%C'GI$3/T%%QZ&1$I["(XVD0$US1 -M7#0\?#1LT95D%5V?]M!_M`W-1F/#N-,; -M'3-ZT0=T(0M%/ZC=XJB-#.,/8G20+3C`T:;LD3T -MCPI)F\EWP0!MRC+11>HKG?">!LLM)4W8XM)M$'MC$UFCKBT)FU/LL[STQJM3A+17+''S,Y6T?*M-KU'XP59 -MLS^Y.^,%0R?#P4U+TM/2],")1!=XMK3 -MHO'1UE`CT7N,/RU0,M$Q+D6]QM+3Y;0\30ZO#>DTA9RU-=1=M`.!4HO14&>W -M#$K+QBXU,SVLQM1)LV)`3#NURO';MD8?E42TE$M3R\N*@3/M5-[.BH$TO=16 -MT5ON3XUJG09>[D\-,"L&Q#-.S3LRU>%T3PG0,M4A]56)3[.Y3C4_O:XZU0#U -MG.M4<]+TJE,-2N.K3O5"[>=ZS%>E*2WH.M5`='W,5E?4_F,/?57BT9CG7%T4 -MGP:0KE,-15>L3O5('0;YTSYE%LVQ_M0IM05I5VO+6$1(K5;;T95M%7WJ=LN9 -MK60=3W>V572K2UDST(KB&EU;XM$\ZV9]VIX&/ZMH?4$_D)XUN$E:(]3@;:>, -M3:;64W5/"5N3QZ7E;+TV[[>V-3_](YO6$@II7563M[X6:>U85\:*!&2]'Q_` -MMK4IG;;RUD!TN,M;$]%Q*V^-1Y^[O#43O>YZS.EM%?WN\M8C-9EL6F?13XT_ -M#=\JTOKN=RU&M\D>LRD=)Z?7S#3!RU[7U!BH/VW@:M,X5;1&J^`?72>!K"K@1U;TZX*-FU]NS;8M[7N"F'STRLO -MA`U0O[P0-B==*D/8H#0PV4-WF`LUJ_Q>.]1_PV_=80+1U"N$340/O1`V'FWT -M0MA,=-+[8;/&@P?H/"U"N54TL=Q@9]'JZXZM2&.].[88[2QWRT`T_4ID,]-B -M[Y%=4Y>]2G8<>1J@O1ZSEYEC)\YOYNP,QZW1<6Z._5M7F5`TN]QEJM9Y')9] -M8`\>[32@FV/'TX2F&+TO?]FG\N&@3\^9_'0(VV3WUH?#33UG1H\S%'V37PX2-.$)A!],??9A[/+*6;#TAWSG,U$A\R(-A1-,L_9(S7* -M'&C3QE4TR]QDI]0O\Z4-?IX&,_.T2$3;S*(V,YTSE]HU-<_<+1>[H+84C>TJ -MRHGF&LWL@MI"];,+:DO3TBZH[4G3N^!FGSL`T3(XS2]B@--UO;IO3<_&P/SE7T_OMM -M)]IZ\[B-1PO`'O.ZR40'SN,V%%TXC]LC-2K[;6?1$'"Z?2%K%-(V;^Q/A-3G -MMATM;#3QKW,]S57%Q0]O',\K-22O/ -M*#\\H-Q,=/J/<4#3Y -MC'*/U.>SQIU%J\].MR+=/CO=8C3\+/A6T?-S]/L5(SAK--^+=?_6?R_6'5(/ -MOEBW'7WX]MSMM.1I=,?3DB<4K4!KW1SD:>!`P]U/M4O;+6.^570%37>+T33M -MW1U)<]!T-S_]0=/=`+4(37=STB4TW0U*H]!T]T*]0M/=IK0+[7?_T'GWV%U1 -MT\(]M.^;=Z?="O*DU'6SQM'%Y[U+&W+^M.(9%2MRI?>%W%V(WI^V/N5/@\.4 -MW.M=-%]R:[3\R0S_2[6W<@PSY=[N\MC$>\O+B=/O;2\;5,(W[!T1"-_D\'_Q -M>P/,L=SRS0[/-3R?7MOQ-TR`@H-:U/+-S6L8BS?V##I$%4?P`HRZ?!;(Z"PMRK=0R.@R;WD/I_J]ZU]`#N,_M3:W3R_=QVRS*P1;S.^=-*Z.U]%/?02NCZ?4Q[ -MS$JH^ZU,8^`&<4V5@._11-4'[A";52)XW'UDE.#,=S?-@/O%3@8*+GWO?Q"X -M86Q1H>#8MYY*@:?$708*[GW7T].B'AI^,[@<.*Y\$2#2.3!G?!%,W'KH^DT8 -MK^!B\D7`6J,20?%%(%3KH=PP2X>"P]X3=0_>%%\$O[81>GIGU# -MN/0M=,+,`)-_`*N6C+4H^9UT)LRUZ.VM&L/AI>CZW5(KPZ6H^PU3X^$=^$S- -MAX_64=TJW8LZX,HJ&UZ*)M\^]1^^<;]69/0P^GQCN8;X5>U2->+F:/7=5"OB -MS_.=18GCX.!J)+Y[^@?CJB=.0SMW6(V)K]]E-2;N?J/5F'C\ -MO5:+XM.6?_!68^*PMUQ-BR??=34=3B'3=:6XG1R%:-+_J/0-6"O#S_=@C8:+ -MRP[X88V,0]."72/N#Q=VTC@#C=A5X]'Q8H>-W\Z.W3:^.T=VWGCRC;.RX>LB -M.LQC(-(S\?-=6C_CC;1G)XB'Q`YXT4J.L\>DW3;>6Y]V]KCW[;3.XP9U:V>/ -MD]^[-3ON4,]V]OCZ746^XZ)Q;F>/Q]_:+C]>WL;C??1,#'L[UP(YM+PDO-DM -MZ>E-70OD7;14M8WSQLY=(RY]>]>O\>P=7J/A8O%U)XB7Q?X!>LV&H\4M.97M -M%0/?[O5+#H+'URBYI6S>K>2J=7HGDA_8[-U//E4O"1&Y8.R`!]@E^:F<,V#D -MB?%1CHXWQD>YG3V3!]?[G5`^BDO82;F?'>#QY$8XAIV55R[^P8;]E;O?'C8< -M;C?&WR*V3;Y70WA6^4L2EI?34WGRS6)GY:?WBTV7/]\RMEFN+7<6-G9"7'WK -MV.OQ5QQ9->+&L0,.9`?F3G9G(46/IW1T9_&$,^;Q=Y*-F`_?3/9D#GM#V6RX -M=FR8R^3=L7]`+F?F+/@""X=_IX8Y7(X>&^8V]'B:B5.PH#E\[.01YG5SE`>; -M]^/^,F).$RL9Z+A_[!\4S+;Y^IUGV^;N-Y_MET?A@'9K_I#OYL0X\PA[']K# -M^>BM,2/FIW>C#9T_WY!V<]YZ3]HDL@-N:;/A`;22(4MOR8OG;AZ1H\C^0:B= -M$*_(#CBI?9YWX*?V>@Z(J]HX\@7]9S3B/6IZ_ICWR.FY,PV>OUKE.3%.))?G -MN_9^7GW#L=PY/2YLN^>8M/!05>_GWG<>6Z#WX\MV?'Z;.]L2^NV]_C[H/#>M -M1Y\GY(LLAKXXZWH;^EKN;4OHL+>X+:$GW^5V?'YZH]L8>D?.;JOHTO>['2D[ -MX/)VL'P/\T_S=Z)\+O-/"SH<[1],SFQX'NE^6\XV>OP=<"?$DO*/'I%SJ@XX -MPFVC)]\,-Y(.E*/`03H+KCH'R_-T\K"8NZI-^F.N*C?I^KFK[!]@LU7Z)PYI -M-.*69/A]O(==,OIIS?13:@_WT,:KB+C3HS[A\@M)$Z-+[05NJL,ZK1 -M+V+JBC*J$3!RZK,SJB$U@NI5^$4+JL/>>S"H+JB#C9PZ\RW2MNJ(^L?8JDO? -M*&VK7GVOM*TZ]NW2MNK;=TS;JGO?-&VK'G[?M*TZ^:W3MNJW=T_;JJ_?0&VK -M[GX/M:UZ_&W4MNI5N`O=JL/>2V;OU*HGWY@W,7,PGMXY-*?>D?/0WCK#R!OC -M&MIZW6@1[QKI.NAZ#R<*RF.C+A;_"O$ZT[RNBQ?M.N=*1_MH];J[C@T??OGZ -MUFHOZP0!^UP\(,`7!;MJ_=WTZYPKP$RK,>Q;*W^>@D#L1OG!#C'*ZX:QNT:Q -ML\<7V\8.'V]L'ONTC?J%[#"QZI>PX\I3@;>(L7/&O@;)#@V//"0[-4RYD>S_ -MNB)!LG/#]QO)#@[_?B<[%3T@%#`]>U1<_(7L733R%[3#PU/!Q3XYKNO^=Z,N -M'#/M9*/3#DU3?Q`[\3H@++=2N[N,RU7M!C$YQ[6/UN!?P'X=7^WI8M8>=YM_ -M8ON!G?ZE[5,U^\>VD\?OW]N^-H-X7SO4>+6/ZM+SNGYP-M'@JR\LZ]7M)7M_ -M6ZX3L'YV`"BW,\,$H-S^LB.X9OOAK`#*[?_Z@]NXX^R`<>.^LQ/&C3LYK`?6 -M[4*[#?:V%^V:JME^KI>XC;IBK!-"[`'T5HBZ3^TQ;NFN').'J[O6#JNZ[M%Q -MAAB[W\Y/XNV^.^.`NKOF+AO3[ALW!'2[2^Q;Y^#^GPN!P[M(O!4-[Z9[E0N\ -M]]9+X/#NMV^YS_LP'`4.[\#_WFM#@A)\\'[J,O`2NZJ+P2/M -MK2X&K[SCK!B\Z];ZP'_4OF`%#RT'@Q6\T*[M,O!%>]J*Q"/MX6ZC[K?' -MK4Y\T0P-0NSJ).)^74?QK+,U2,4ST-G@%E^[G^2#.SR[KNN[6/P%+0YZ\6?[ -M>EW&.^SN]1I/O^/D8?Q5[0ZB\7-[G[S&F^X1;\`N4.KOA/(:[[=?O&N\]:[Q -MKO'9.^RZQB/NM.L:_[+?KFN\S*Z[KO'_^LJ[QN/L+^\:O[.7RFN\YEZ6E_%" -MNXC-R=/OT2LGC[13KXVZ(,^J&Y52O-%;RD_M>?DJG\6+KZZ\HAP=0>Q'Y;^N -MOL;R`SO6B\OO[,XR+J^YTZ^QO,,N]@;S]'O9&\PC[5!V,*^\MQNT/,=.+@?S -M^KMH'LS[[0YL,&^]1[#!?/9.P0;SB/L%&\R_[))H,"^S=[#!_+\>P@;S.#L) -M&\SO[`AS,*^Y2[ZQO-`.:,?S]+OF&\\C[9UOHYZ]@[[ZO!3?,??S2?->"+%C -MU@,"R0S0R_*6]D$_.TL<`_T>;3_(ZMBM0YP8-O03/#1ZT#OL6>Q%3[_SS!<] -MT@[&7O3*^QA[T9ON9NQ%K[^3HQ>]WXZ.7O36.QQ[T6?O<^Q%C[AWOQ?]RY[' -M7O0R._E[T?_K8O-%C[.OOQ?]SN[^7O2:^R)[T`OMC^Q13[_/S4<]TK[_-NJ( -MN]X,U4OQZ/94']`'SE:]DST=0NSV=4;RJ=_877N]G=4/[)#S6"_4*^T4[@2? -M`6?U#CL'S-8O]1!]6@^WB\!LO?).S++UICL*S-;K[\PL6^^W/[-LO?4NS;+U -MV7LUR]8C[M@L6_^R;[-LO8^ -MSMG3[]0S9X^TU[.-^LN.SY;V4OP^B]H']%_P:J_5,^I]]KY>T+KV"SVE'MOC -M[)=Z;+^S.[2TO>8>T;KV#CM%"]S3[Z8ZHCW:H_5SIO+^/P/WIONKCFCK[R4M -M<.^WU^J(MO6.JR/:V?NNCF@C[KXZHOVR!^N(MLQ.K"/:__JQCFCC[,IZI+VN -M-^N(MN8.K??90ONT#M_3[]8Z?(^T9^M\.[&[WI_RQ*X4'ZX/V^`;Q&*'R@[@<\-B![EXX%O*8D?9#N"3PV('I&YMH\-PQX(_ -M5;L='CYY+'9LZM:V2"QV?/7]O>"J(`P$(7YO+79(SPV)'7(_C@^4_@H%O;5/#/P*V&.,;RS^"@Y_B'^<_@H1O;8/#/X*% -MO^1#RVA'B!\5_PCSXI'?1?\(^**6#P_K'1`[-OPCH/B>1-%<=X3YT/2/`.-K -MW)F6@J!_#^X*MYM_XU/?V#_'4I^ -MF?_A3^!P_E7]=TCYAC[3J"!LX(*^BO]W9/DHMV/<@J#Y,OYZ&^G3T'\'F4_G -MY_C=]*9_;#WZ:_[=X'1"PW\'J^M3^KUOFA^ZP]UM_OX! -ML9/=Q[ZG?W9?#7A[LS]:7PVE?G%-X9_A@[ODB>'/[G0WA_^&)_M^\=50Z[.> -M"3[4B>Z?R@B!D1]XM_N%?N<)'R,$P;ZW+^,KJ^\^IR_E]OLT,4+`[.O[#C5" -MT.73W:@^]4YW$_E>+L`OYG>K`#^$W[W3W5`^^$YW8_CC.]Q]Y9OO&C\[C!"L -M^\,^^SXM0OGO^\AOYLOO)G_27'E`[-]O@H^_I_R*\I.@X<>?#'Y>W:BGOR[_ -MP4_S.\1/`HF_\\?=3X*G/_^Z_-D^_?WA._`WOZ(_L@;L#ZC+/^)\X6A -M%$A_PC#Z'YG/&$;_X_Z9HWA\TKQ5'/U/_&>.(O)A\V)Q]#_TWS:,_K?^HT1`#U^ZCP2X)>OG8>,^P#._&`)DCJOQ,#/'L;CL^<) -MY*)]^;P;()&/GW<#%//]\VZ`$+[3E_SO(_4!%/]%Q#Z`Y;]RW`<0_9<1^P"N -M_SIB#`DA7T(,'L>0Z/K!`-ECZ8-"WTS,TL?1J\@9`#]Z%;D:GTBO(O?U*^E5 -MY'A\*+V*'*IOI5>1(_*Y]"IR8KZ87D4.PD?3J\A!^6YZ%3D,GTZ/(\?AZ^EQ -MY#Q^0#V.W)=OJ/<:2_`9];)RVK^D'B*0Q\?40P2B^IYZB$`BGU0/$2CFJ^HA -M`B%\6#U$()2O<";_NXM))!:`>C%#(/>/;&8(_/Y5[.8'XC^[D8EOK?>5B_JY -M];YREC[.62>P;E9#D`+"$BA3";Z[WE?NZZ?7^\KQ^/IZ7SE4'V!O+)<+?`%. -MY<1\AKVO'(0OL?>5@_(Q]KYR&+[''EV.PR?9N\OE`DV!PS[,WGDL%UC^>]HI -M"#Q[D[E?X/K/:G="L`4RYHA\I[W)G)A/M3>9@_"U]BQS"3[8GG5NJ79",`9V -MYDX(,T#P6#Q0Y_<>$_'Q]FQS)K[?GFTNZB?;2_!1]Q*"1+[K7D)0S*?=2PA"^+I["4$H'W@O(8CA&^]9 -MYZY\YKV3H,>HZ/U -M"`3;*MX!D8%,L\F`%!,]% -MQ2(/4<$+6>2A*KA!XHU%'K*"CK'(@S'P3Q9YF`$*RK:"&S'YGX\N\H``%-)A -M!A>`";R$Q$E,,[A'BSQ\_YATHD'QGR!--%C^,Z2)!M%_H++(P_IO5+85]//5 -MZ41B3(3"X)]'+Q -M!P^#W:HCX5007'4DO`J.J]B#3D*P$92P:*9$`!&.K9B#*31@9=."Q"4N$2S\'H>),+2@AFPPHSEB$IRXV(7-0U<4FI!&V -MNMB$=T&<%9MP1\BS8A-F!W]6;$($H="*30@>+%IU"0^#2*M/X51P:?4IO`HZ -MK=B#N,$=&:J02O@C6Q4FS:@(%L+CE:,P0WB\BA1*"8]7E$(KH>[L4O@Q -MT+(()T+?V58P;N4K;!.>NXJ%4\'K6K'P*OCN*A;B!LEDQ4(/(1BO6!@9U'<5 -M"TN$Z+5BH5IPO58L9!&ZUXJ%S$$X7K&01JBY$A0NKZ:#?;)BX8XPCV!6]7[$$/H>XJ8$@E7'D1 -M#%^%+Z^#H9.MBZ`@G*'1T;H(`2.%88!0Q"8QS`Y&KR2&\T):H09M*SCT4ABV -M"8U>'D-^8;RPB745%%]Y#'&#Q#*/H8=0?>4QC`QBO3R&)4)GF<=0+4B_\ABR -M",5>'D/F8-G+8T@CA+)Y#.^"S+S>B<=P1T@N\QAF!T5S'D,$H0/+8P@>C&`I -M#`^#%*RGX53P@O4TO`I*HMB#D<$.%M:02AC"VAJ^"DE87L.%(<(L;/@PE'R1 -M#7>$@#:R8790\T4V1!!VOLB&X$'05]BP3=@QFQM.!4]?:&:D%HU-R019C%FALR!WEF$9JRY87:0'#4W1!"BH^:&X$$X5MCP,#C'&AU.!;M?H\.K8!Z+/5@B)'^Q -M#JF$8K/7X:MP_24[7!BZOVJ'#\-%%NYP1_C(PAUF!^=FN$,$X?X+=P@>U)O5 -M#MN$Z+;CX50P<'8\O`H6SHZ'N$%4UO'00UAO.QY&!B%GQ\,2X>3L>*@6S(`= -M#UF$'+#C(7.0`@>E&;5 -M#@^#U:S[X500FW4_O`INL]B#:D%O%@"12AC.&B"^"LE9!L2%X3DK@?@PG+DQ -M$-F'ND*KVFBM7T$X'*KMSOP9P4*I6MS-G_$>1.5UROP9+D(-(H7P"Y9`G*?Y -M,VR$(D3<8$&KA.@A1&B5$".#"ZT28HG0H55"5`M&M$J(+$**5@F1.7C1*B'2 -M"/=@)<2[X/^LA+@C%&F5$+.#):T2(H(0I55"!`^NM!*(AT&7%A1Q*AC3@B)> -M!6E:[$$6X4TKBT@EU&EQ$5^%/:TOXL(0J"5&?!@.M&Y*VE&L'B5MA:@Q#FT,2(%$)R'1X1'I9'R"#>MQQ]>80.8AWQ>99'""'^ -M$7MK>009X2#1%Y9'0"$>$H=A>83_8$3/SY9'>!,>$IEA>01\$1X1&I9':!@. -M$JEA>82(X21Q<99'D!".$KEA>818X2`1')9'@"/ZELAA>00ZXA\Q*I9'B""2 -MM[IH>80*(GR+C_B@8@]B$@EIOL2BF:O`D&@N2)JY"A2)3"XGFZO`D5A,5)2Y -M"B2)Y"C2)8#V'F*O`DYA,7*JY"D2)Y -M"E2)R<1YFJL`CMAA$HFY"F2)S41"H@`NF`@?"Y980RB.#(BAQ`V=0Q(;Y(*B)'294XIC*H,A*7&\9 -M%&&)V;1](BVQFZ91-"?N[0R%R43>F`\"CLA)%-RQ!ZM,`,58WTD1FN:#J"!F -MF2QBS`(_HIH+I@B$6RE&QY@%Q,0L&^(",&93O*`Q"YB)>2Z:(C1QSH0.8Q90 -M$\UL.T5L8J;IJL8LX"8VFMR)#4*08J-),<8L("?.F1QCS`)T8J.)D0CNZRG" -MQ)@%\$1,%TW1EJAIHBFZ%#]CBP29HJ@)IJ@B).^Q%7.*"K)%`C+1U<16!"HV -MQ18)0T5;4U&QRM53Q"4"">U[;$6G(BC12`C@`R@F"0%\F$0F(8"/D_@D!/`- -M%N&)L[9%@BW1UK9(J"#FVJ(%,L5J%TSQ2[CAVRP2$[E=F\6YXK=KL\A,?#=M -M%O.*ZR:J8EZ-/7AOVBPJ%7]\C,0ZH;4-DH@GM+8!%/>$W+;-HE9QW<1)#!1* -M%==-H,1"(6LQ*!8MF"S&%1F%3SZ8XJ/0V@9+E!0.VVB)E<+GHCD14_ARL6\XK]-N4A-_'@I%U^+G[XVW\;"J1CGVUB`$QM]TL16(9Y/N:A5Y/,I -M%^&(,J?F(CS1Z514U':Q!W5>RL4*HL@-IACNNB\:QKX0_L15'U7Q6%CIXR_. -M%9U.C,1F8AT*RJR"Z6*;2]S(J',O^@S`UG(%%&)]T)H'T!17PCMPR3V -M"Z%]G$2`(;0/E#@PA/8Y%`V&T#X8(WBQ[093+)6Q!\5]1<8,(^6KR&A5M/>] -MTT`66D5V'^*">G5D_"]V#.=]4T9;8NFKR%A!+#TQ$DV&BC>88LJP\29F)":6 -MGC")+T.$GYB1F5AZ`B76#.EN#D6<(=T-E;@SI/B)&9V*I2=88M"P76AZ*RH6 -M#3M^8L8HH[9,7`!'9"4Z#6%^]S!Q@2W1]B9FK""V_!`75T-$(RA1:XAH="AV -M#1&-J$2P(:*1E3@V1#3"$LV&5[^B8MKPZF=.9!M>_?B(;\.KGSM1;GCUHRK6 -M#:]^6$6\X=6/D4@R8P\BH"")?L.K'T`Q<'CUPR1VVFR-:,7#X=4/E*@X5/O! -M%!N';;]CXUP1_W9L9";RWXZ->44`7%$Q4/EJ@[#/T5 -M%7N'H3]S(O`P],=''!Z&_MR)QD/4'TPQ>;CZ&SB"%\-@`T>GHNP/<2$]#/T! -M%*N'H3],(O9P]S=P-#>*QA0(Z4;B8OB0^#=PK"#JH5B)YT/E'TQ1?=C\*RJV -M#Z%_(\>Y8AENY.A(3,/9(8:*;;B1HR6Q^X>XX!]F_SB)_\/L'RA1@)C] -M%Z]A5$>KXC`*E=A#Q,51'8N.XS"J(]+Q'$9U7#H.I,R)2405($R1B=@"1%P\ -M$6^``$4IX@T0DUA%O`%R$K&(.L#!(\Q17S5XG#ENI`:/:4Y8Q/0\(A.G(GQ$7>"4DQ*<9*^#Q2R%@)HL<+&2NA]'@50SX6'>%AK`2D8UD*^;AT%(NQ -M$IR.++E8@NT1)A=+T#VNQ6B/J":0XDS.7A9+Z#H:[&()+4=/8"P!YA@*_`[8 -M[)2/"3%2H/\Q[5BQBR6P'56!\,>W8U/._RAWA,KY'TN/D3'XX_>Q,A9+$#_N -MQV()Y<>;6"P!_?@9BR*L'T5C403W8U`LBN![1(W1'@N*S<`39/Z1^LA0G`:> -M(&>.NS%V6!2!`*DMBR*P'45B482WHSK712AZ-@<^T$B -M'9E7/\BE(W7L!^ET'-L!$FR/FKGO0$W1-H<.`R3X'O6!4LBN(VE."MER/,U) -M(6&.YRG:H^?.7*B:(,%P\D?='""A]!@@DT(2 -M(4&0'$+;'#8,D*"$=#Z."&USX+`9`Q22^MA6/`E6(8=5;DC0A\6<(#=LQE!ZK)'- -M&(J.2L$9`](1/]>)7#I*!6F/64()'?B12RBAPT%R%A%TSS.'@>\Q+/@=*!-* -MZ'QA#H.68UJ0]K@FE-#Q'E>+%3IB)":R`RE;Q$52PQP&;\<0TAX2MXB+'$7Z -M"4ETQ$A4)/51N*BBJT(F"E5T,DCD(H*.-P:&L#V:(9V+DI+-+1'D.%-KI1)*G01A>(/!4^Z>Z1;T?7(!A"[@@J`T.4 -M'FF#[LBB(Y?.'8ETW`V"(9:.8CHPA--1./@=Z"]BZ7"/Q$(L'>^1P%BG`SXJ -M"[%TQ$<%8YWN&0DMQ-+M(:>%V$':H[402Q>(M#`&ZE22`2/$C6 -M(,N%I0&)E4H2;`1'2E=M),E&/4E]F$KR8Q245(XI$Z)*14EWF3(!6Y24E);FM)/%1?+65?$82 -MR[:2>TCUU59R%(GUVDH&(IUE6TFL)/VJ*1D5^QAX)1^$7;2/`;Z(,0E^A++U -M)"N3`:/+9-'L8R`UTDPFS3X&5R//I)/M8P`Q$DW2T3X&/,FI&>V1@F6:)$P2 -M);5FM$=)E&D2*]G!$DUR)4-8MDD9)`G+-@E^1)C9)G&0DB_;)"02T&:;-$-J -MOFR3P,C.EVT2]PCZLDWR'CMFMDG@X^G+-DE\))G9)I^1EC;;Y!Z296:;'$5V -MVFR3@<@IEFT2*PF-$DTV)K-8YDD9),_,/`E^!&/U)'&08ZSWY&;2C"6?_$R2 -MH^J3HTET%'[R-`G'VD_N(>=8^\E19/=K/QF>+$T*"[\#Y"_\)%=2;*:@5$^^ -M)IUGX$?WEX(2![G(4E!"(A]9"DHSY-Q,00F,W'\I*'&/>C,%)>\1W::@!#X& -MSA24Q,?"F8+R&8G*4E#N(>MM"LI1).1,01F(G)PI*+&2&3#\9&.2`Z:CE$%R -MSG24X$<16$\2$DG,&E)N)E%@1LK/)#,K23F:?&8Q*4^3TJPGY1ZRFO6D'$5B -MLYZ4@6E'$4N -MM+R4@4B'EI<2*QG18E(V)BE:CDH9Y$7+40E^W(/U),V0_[-+Y692I*6I_$R6 -MM#J5HTF4%JCR-+G2&E7N(5U:H\I19$QK5!F(I&F-*K&2-RU0)5=2IR6KE$'V -MM&25X$>@EJP2!SG4DE5"(HU:LDHSI`M-5@F,W`G**G&/W3I9)>\QAR:K!#Z2 -MZV25T##M!%(RDD0-TTXP)2-)V##M!%0RDL0-TTZ0BV25X##M1+I(5DD.TTYH -M)7UIZ##MQ&,RD=5%TTY,)HMI%C'M1+^H)^D+TTYD)A-J13/M1&<27YDTTTZ$ -M)OF53C;MA)G2G*8HTTZD)L5IV4H<1>^$7KE'TTX\*`F6N[.\QK12G%:N)*0Q -M+#ME>8UMI4&)'9;7^%8"+.=I>8UQY<=2));7.%?NT^*5_\>=P%R_H:+DL)8L!RO16V9*#U-6J6:LO965\C9QFW[%9^ -M%-N6#K&^QL#2@ABU)%H.U0!F?0VDI=J2/]?7>%C^+;>6""Z\I://'7*M%"$J -MQMPA5LN_)4R6EGBJEQ6 -M*Z.*E -M+&5COLM\Y;`J>-FO+-X1+P.6RJKC)1U-VF"R_"/*+:M1FNW'(I -M+\N57J[C)>"R6Z6]Y%B"J[27O,N]Y7`I7LGFTEX^+M=5VDN6Y9Q+>UFOI%=I -M+V>6^"KMYQFNK%AI -M+\N5![SC)=628Z7`Y%@Z\!286TO?8D_2?NFW_&_-+P67U43[I>%ROB8A:'5- -M,-V6.*L/9G1LL1&YY*_%*W]6(LP+VF(#V3"?.++5(1 -MSHXFADLN6[SRXN7'7*HA1!J71,5!9N02J8@0\5@N%1MI"!$6YJ%KD-F\G"H. -M,M>55\5!9MIRJSC(C%D^,FEH")$VIEA10J"6W.X-,NF8C:9H)5PRO#?(]%L2 -MFK*5=LGSWB`SD,D:8YH\+65-\&-.$A5FM7$P6 -M%G.9F,Q7V]FR[-639+4Q33R9.+[EY9[QC/W%NN -MF\J5V6TOQ)'910E">9//=+-&3;+Z=Y7J2S1>M=$^R -M^:J5\4DV7[:2/KE>Y&AN,MV+'$UH9GBQ7-F?1+FE*P&4*#>.Y8`2Y9;1W%L& -MO3B:?DNGT^.205E@Y&@:+A&,\4H)Y8)10E"A1+G=+#&4*+>=Y8:2PIC49&%V -MO9*:EETZE:>*)%N24V9IM.I7-FB+#$F-1&:*<:D)BJS[;6UM%%> -MW9B:?DME'U,3@^EU8VH:+L-N$@(AY8XQ7EFD]#'R-2.7:C>^)C#3R1BQ=%)" -M^\J54 -M_%B;E62C`(I]^R"0;AQ&!&P2"I![J&`8;\'#>Q#8144Z*XY*3Q"D:@PV< -M.(-BL`$5IX(,-M#B9(W!!F"<33'8P(R30@8;L'%>R&`#.4YM&7G@:9F&8T5D -M.1-BI2@JYW0+CD1S)`\`,\%_",X+')\S#Q?H;%Z:_P*=F,ST'WD@;H%LR'4\2=,RG(WE@8#EU/$D0+6UA)PG!92XLT/FP]#JV -M!A*7F+AAF"!BTFF.HG(^N`:=5T[*I03PU(FY;#N>.@V=[2@$I^<2UKE7^T,P -M.CV`ITYHYC`JPXFZ)`&BP_X0ELZ_HZXST_D.TW5R.MEA?XA/IZ3N#R'J%$J> -M.DN=_K"2!)U3((;@!%[V`+N=5DN%6+?SSZEY+$G4.CN/)0E#)^BQ))'H'#V6 -M)!B=4,"2A+"3"EB2@%O.Q(:SE[;`V,J_B -M.=>7:D`$I_NR#:CP1&3.Q+!AO(UPY[J(&\;;('>:.?67>4"%I[J3S0G`_`,J -M/.&=;\XM)EUNQ^G%W`:F/0V=WD#C1Z+3!VG\8'1: -M[8P?PLXBI/'#WHF$-'Y8.I>0QH],Y]C.^,'IC$(:/SZ=G3GCAZ@3"VG\*'5N -M(8\;=$XOY''#X1F&;`W`KOBAS/W; -M.<.2%4'/9^"SRWF6U$.F/@^?8\ZV)"`R]=GX3'/.):%SQ\Y8IDHP]6GYE'/R -M);-SK0%=9DZ0RMG+S`EJ/0N3\;DV7[NAULF);#<8.H."R<]$)U&PW<#HK)&U -M&X2=2L%V@[V3%=ENL'2^(I.?F<[_7+N!TWDD2WY^.KV"[091)R^RW5#JC)*U -M!M29N$A59SL3%TGEA&?B(K6>\TQ<)#3LN4']['(&)R5T$$]^9C42P?G/Q$6" -MPYX;X,\T9W.R&\D`-7^^.1>:X\@=IW5R1G?__'3^R9X;HLYVY'.CU.FCJT;0 -M.3V#K8&.9CH2X@G23$=2/$>:Z<@'J$DS'9GA3&G6Z8Z=+,TZ';3S/HFEVW'J -M)[%T/\Z:9IUNR(G3K-,=.7>:=;K29QZ+SYFF0W`F*#623M`0Z)5S_<4$[7HJ -M-4>2",ZF9IT.X@G5K--1/*>:=;H'J(<22Y?A#%$&RZ)BOXA$Y[0,VOG55-1E -M0?M%V21OV2\B8!0'G7;6V^J@T+1?Q-4(#\HZ^T5`C/B@BK)?!-@($#H[^T60 -MC0BA7]"/$2'T`2H"(X1F.(E9@%"`F>KI(*,63>A8)?8#6LR*A&4Y\%B`4#;K/&H9".[]@P]`=IT`K#JH,=1<+JUVZ)$SIM4.+7W2 -MM-JAJLZ;5CN4RJG3:H=J/7M:[=`!*%"K'4H+'6JU0R&>1JUV*,73A=8.?8#N -M!-NA&Q -M!^B@X"MT&'M`:E03Y<^Q!_:@X"N1Z/&M=](4-8D:MJBBX"O%&'O@$)JWFUPL -MJ'BBSC-?F#N!)"J_<8,H3W8@U186BK:VFJ%$4:`<6/1=BVB87)[&::!?-G0`5M9WQ -MQMP)YE`-DEDT'3I%NX>Y$[BB!+2V:`$N#DJ>FT:010EH=='G%F?4(#:-6(M6 -M1GVBB+[1J$-L&C$7W1A.+C9PJM&-VS1"&GI$8X=-(X"B)$.7Z'HK-KHVFT8@ -M19M86M%N&F_4,3:-:(Q.T8)KTXC(Z'%T&#:-H(SZT/QLTPC,Z'&T+7H>Y(W& -M11%J%"4,,8;-8IJN&*C4;%Q!&V4BV8;U52A -M1T6B):XX*'$TJB@?58G"(>NC2;-QA'&4C78=58ZRT;2CSM'0X#A".LI&`X_" -M0^=H0E&H$WXT[M:T0(E&DI2BPZH%J5.T>"*@8M%>'))4)9I76Y+F -M1R%=3E(GVW2`*`JQK(L>\**DL[/I`%,48&DOFP[L1^=9+E'?(I:T1^H<5:>% -M20FD`J4AZ8&T:"D2;75%27NC.*LWJ5:49_4F)8[^K-ZD8E&AU9N4.5JT>I.F -M19%6;]*VZ-+J31H7=5J]2>NB.[(W:5[T1_8F]8GZ\-ZD0E$BYH/#H&04#7M& -M2=.CVJY+J6TT;74I%8F&N^*@S-&X%:A4)7KN&I7F1Z]KIE(IZ;LK54I'0[OL -M13V(\K*VRZO4;.D3U7>Q2H6BZ#56J5%TO98J!9A=+;:D(D3;*!RO5^HI]8]J -MU5RB?;)>J5;TQ-@K)8X2RGJE8M&+5Z^4.:KQZI6F16%7O=*V*.VJ5QH7O5WU -M2NNBNJM>:5YTY=4K]8F^O'JE0M%26:_4*%J62Y6F1T5L[E+;:/3*72H2I5[% -M0:^ESM'(VN3"Z'4OA:;%!]:D<<2XJ/BJ7^HN\UHX2.N(65+U%<'T=N:U>(LB -M3(6BSK*%Z5+-:W$7/20J1<5>"U.G:-DK8RH2A;)E3$VBT\R,J5:47)8Q)8Z* -MYC*F8E$'5L:4.1K!RIBF12E8&=.VZ`4K8QH7E41E3.NB':R,:5XTA)4Q]8F2 -ML#*F0E&$6<;4*"KY6IBF1P%M1E/;J.;+:"H2[7S%0=NBH*^GJ4JT8R8US8^> -MOJJF4E*2&=:T56IIVYKN3`FD)LS)1:=M:RH4G6)M38VBT"BLJ:\TBZ4VM8WR -MS-2F(E$PEMK4)#K&4IMJ1I39FC<"RU:5ITCJ4V;8MV -MO]2F<=$\EMJT+DK^4IOF1<5F:E.?Z/I+;2H4=7^I38VBBRRL:7KTD:4YM8W. -MS32G(M']5QPT+JHW&YVJ1-%MIM/\:.`L=2HE+9RQ3ENEJ*S7:5[T#GK;82;80BVDRBD%!$FU84!>8[)8Y> -M0A%M8E%-:'6O>%HQK3053]>C.HFURBPM!CYN2B&(I8Q)\Z -M3*.9<=%EJ&,1?UH]G;6Y+;"GRDR?Z$(K#IIKAUC:1Z!Z,@6H8Y1.>A]\S)A3W4MGA"-8T" -MV]JB_%"`Y@FU-?KCJXL*1*UM>=&"J+7-)XH096BZO.RGP#:CJ$-4HGE"!9;B -M^!:C%-'JX@G5/YI#=8YN%U6H!%+OH@H58&IPLXC]PH"H<;Y_&!;5("84VZ*. -MUOYB7M0+6FLLC+I4*X^%40%F-K(S*CML3'9&A8 -M4C]C/SI@:B)5<'=--9--ZH"IC]3JJ)W1)8$=O6V24P^F!#],JG<4T$A._9\Z -M&7EC`P(:*BF%G%H]+6Y:43V7<5!&(SD5-VKT<[(-"+RGXJ][*C0UNGE/-:)V -M-^UE0@H@ZG63G.H?#4#=4YVC0S]R*H$TO'E/!9@BH-RH"E)5HQ55-I9/98\] -M^A2J*;%C'TCU$Z<@D*?>&C>J]=3]V.!OI.I0.TBP5,%R!8F7:B+51!K@5!`8 -M5`F<&]7]*+/1)?$BG?MM5"&J%#(%P43U0G839*G"4W>DVT:7A(^T\@=(#9)6 -M_@:I1-+*GR'U2%KY2Z0J22M_C-0F:;O1B@HEA3=R5;VG,4ZE*C25QJE4-:C> -M.)6J^U$=)U?5/^KCY*HZ1X6<7%4"J9&3JPHP57(B+CZCN#^8&.("G>KDE*;2 -M22..5M0[J983<2%/U4,E4ONDP;_`*@*5"A=8Y:?V526IAE*1HTLB45IR#*R: -M58FJC]+I7V!5.9J&JSG:3V..DU7I*,W1\/A9K<-943^E.L?3*CKUT.F2*)4" -M'4^K_U/V7R>RM*I:ZT725CME[LC;ZCNM(JE;#:;F2OE_IU4)*JCS.V!$'76V -M5HVCIL[O`&=:.J2PN/YLS/JJ3.GRE?-:7. -M2QV/V57.*K?3NNI/%U;]JFBL-=!?#8JU!@"L"K+6P("5->859;!64G.F?$`K*L_4X^F2^)D* -M`G6LXU4W:M'4Y*ECQ9[.'P>I2U-'H(Z52CI_3*1&32F!.M;B:LVSQXI<-=CQ -M3C^KGL#Q*9;UP+8_W;).U52H7E;RF$L"KSJ5BZ.F396>+@FV:=,SS1I;A7KR -M5,.L>M6ZZ2[0BHHW]07263>L=B-#JM^4&)AF%:Z>Y>BL4M88Z^$4[>F2X*S" -MQNBLSM7=&'H5-&*\6 -M(:,1YE4D9#3"R+J$C$9L6,=VT0@F:Q0R&B%<[F22)XF!`&IS%/;W"#U>9H0-*1* -M3S&"5M1.J.VSV$IJC;%N3T."T595:U/,<]%J#:J23X>?Q=99J[;,<\%9I:/. -MW"JL`33/A6C5)NBYH*Z2YX@19%9.)#%BM8K])$9T5XF"Q(C8:HV,&#%>50H2 -M(\RKK$ABA)'U_$F,V+#^YX@13-;V)S%"N.H5)$845WF1Q`CDJOV3&%%NK8P1 -M(YRK6#*7!#LT&:EQ=;=B4U&HSD@KZ@H5%\E(S8=*Z!ZI,50'J,BUW[IMO:&. -M(]&K.M1QY!JUAYH!%;DR6>^H0]1T)"`U(FJC&Z0F4>&1(E?.*@I4Y>!<#0VJ -M'$2K23J5`W45-8@B(+.N!E$$JU77((J@NPHJ0Q'$5A&2*(+QZD(216!>W0VB -M"(RL8CH4P8:5(HDBN+E6QE`$PE5+TC$,15!<70Y:Q'A%GU5?631B*EH8?0Y2 -MPU`$1=>@&(H`Z:H@0Q$L75EC+@*G:U/L6A1WI9!UBPJON#$7P=556^8B2!?Y -ME+QE+@)WT>-54N65=<8OTKP^".EH+H*`T>957N8BD!J- -M7NUE+H*KT>D5'/8P\KR:R\AA+@*PT>@58.8B(!O-7MEA'B/7J\P*'I:5B"K- -M7D5B60ELT>Q5,9:5\!;-7AUC60ERT>S5%Y:5<+R^"(=A60G)ZXMP[4JV;`B\ -M")EA60E\T>P5&I:5Z!?-7N^NV;39*S8L*V%Z]1&^73^*LU?6:W?0^MJR@KT* -M[D:O4;&LA.T5,HE[/0_"7WFO"*['*_Y5^#JV6KL^N/2OF%?`&`"6\TH8&\`J -MROY&NE>!W?C5!1;[.X2RPS%>HDP46^BH;L\"N78=5%ECL:_'.`LM]5599 -M8.^N4BX+[/BURF6!Y8;Q$[2O>BO6ZY;+`@M[]7(98..OW:HC+.X57'6$Y;V. -MJQZOP%57J6%/<#BJ[JPL[/Y40)V";EQ4+X& -M1=^N%I;WFU=JPN%=(5QN6]UJQ:L,"7P]X;5CB*\>J#8M\=>"U -M89FOOL4V+/2U4-B&7;N>NMJPV%=55QN6^]KJ:L/>77%6;=CQ*\^J#>N#_5FU -M85FO0JLV+.RU:-6%C;\BK3JQN->E52>6]^JT>KP27W=DIE@J[(\L%9LT*RBH -M7AV&C%@/K,/P$2M[=1A*8JVPI]&W:]J*%7M!2RCX7AV&L->X%2^6]GKN&L;B -M7J]KPUC>Z[MK&`M\)9,-8XFO8+QA+/)5WS6,9;ZBUX:QT-?UVC!V[>I>&\9B -M7^%XPUCN*TYR&'MW[9,-8\>O)\9AK`^64#:,9;U>O(:QL%>-%R\V_@J[FL?B -M7FE7\UC>Z^WJ\8I\U5WQ8ZFP*Z]_;"OVY260=;*]!;ROC230:UFN(!N&%;$Q -M9'VPT2N&K#M6%CM'B\?68F%9Z+"W`"[VEW6/S<)&DGBOXJN"[-HLHL!_A641 -M7]57(EGD*]9+),M\=9:)9*&O]"N1[-I5["62Q;Z6O42RW%L)2RO%=)U..5^=K!FLI2 -M84-85ME6+`DK*VN019AQ94&ODJ^O[/@5T/:5]<%JOKZRK-?.UU<6]@KZXLK2 -M7CMF;EG:61;YVVMRRS-^N8RRW[/C5C.66]<&2H]RRK%=TE%L6]@K'XLK& -M7^=8GEG<:_?+,\M[S6,]7@FS%]FXY6%V(WM44LQZ9,V6W%?WUVF6@28F*,G& -M+<>OCZS9[&A-3&"&-5NR7O=?NMFXFYA`^BI"S,BBVX*S_#G04N\$.NWJS_+!4VG"6@;<62LPJT!MES%H(6]#IS6]"N9S>RM27W[&O6>UUGZ6AQ;U^P32TO%>!EH86^%K0TM`27Q%:&EKDZT)+0\M\=6AI -M:*&O$2T-[=J5HJ6AQ;Y>M#2TW-<]F(;V[OH_T]".7T5:&EH?;$E+0\MZ16EI -M:&&O*RT$;?S5I:6DQ;W&M)2TO%>:UN,5^WK3FM)2875:5MI6;$\K2VN0!6IQ -M:4&O0ZTO[?C5J/6E]<&ZT+ZT15J[;`OS[=JMX]+27G-H;EHG[80VG@@/VS(E -M8-N)%C$PTYV6/59FVM/"Q]),?MII6YLI4`L3BS,1:H]A=29"+3,LST2HA8;U -MF0BUU#!!$Z$6&V9H(M1RPQ9-A%IPV*.)4$L.FS0%:J-BEZ9/+3N,T_2IK=,^ -MJ!ZOCEI"&JJV:%8G,+[&]A:UFZVA06PO5>M\_632T6A-"=@J$Z4V9M#:[M"7ZQS=IAV)[`-FL]]5Q,M[JUBUI$7[?647N!Z]9& -M:C=PW5I*;?6U6WNI'5-U:S6UZZUN;:[PFF]*U/;:\M4$"GE<"N,RVVHE=WYLF66?OC=H6+`XU:;NQ_?%= -M:F>P#$U7AKF-J":GFP%4W/!98+8^LSZTH0:ST)2=N8K;#O*Q:L2,!* -M4LNZTHH;'5.2=N-;,1-:SNGA6E&*]BV<;=%`;F6OIBG7:L] -M7O&+G@M!U]\V6IN&1;F)Q"A/>-OGV:+`\EK43%<<;,>V@MHZ[%)S])2X1=3N -M8:.:?5N<[:K/41N(O3`&;M^V0;%_1>+V4JN(!6MZ+AJQN;[3[=Z60C94:-I^ -M^@*VEMA.ZNFV5EM -M;FFVA,U+K0_O\4ID/-VJ:7&I0P6%[9+Q=+N1;6SR71*P4L;W$_;6,!9](-=: -M-CT7Q5C"6YX6&7MX&]_2;J.IXEIG+)D1?*N[)?B-^J(/OMMHJJ/V&KOP&]^* -M;=VWE-IN[)QQ?*NYI6V.;Y^W3;'H@_26=9N.9:=&'^:TIKGE<:@FRF\8&KO#6H9K!O=]V -M-P%F2*@$+$4U@ZNYO:@V<-6TY\VF@L(6ZM?`W">#V -M9.U^REJ@[(23TM#"U991&M2TG=JD+%-UB;N1_7!2&N:T(LY,`0^WQ"FT2,"J -M&S,%KML59Z;`B.OBS!2<;\.JF8*2;5]564N6S3?F:<^R_,8_KO"VK>JY:,L* -M'`NYR-NY:B%7JO<+:#SDVN7'?]Q8".^$2R=R\H^;ZP^`2L=S]ZE]BF.M?A4O< -M<@.L<`E=KN81+M'+[3SV)2BZ![;"!$AWJ@:7,.9"`7,NR5PJ8,Z%F=MZS+D\ -M=H/;;\SYU+0#7C&=!&Z^[&`,5V-+BE71YOQ5+<"(::4>>B0EF[OBQW?K,%8LE -M)@2Z++G$1$$7)I>8P.;*/!,3"]TI:V+"FVNP2TS$>U:G'[2UP/Y:=.NS> -MQ+I3BMVI'#0L/.78%9.5IRJ[QK+T5&37!`EO9>NRQN)3F]VFF$!`KDLAPT]A -M=KMH_*G3+CP,0!79%8D1J(:YWL`#%6P7FB80,.9:[<87LUUWV80JMRLONU#Q -M=NUE&ZK6KJ7,0_7;)8?%"K"YG;D2%6^7/]>_6.ZN=EM;/B75G&OW6!O=[7S2 -MJ):[CC$5=J^ -M7)N\(MX+F:U!H-L87.W:8#F@M@9L[I_,UK#0;4?:&KRY/CI;0RP7!6IKH.6& -M!FT-M]PDG:U!EXL:M#7T#OHQAKFO0UC#/!96]J^2\5[5E!I[W5&8L8.;N -M!HT%SUPQ'F%B"*M#[S&,877H9889"\"\Z5W)+1;TWVKF#8H9 -M"]*\1EX_+$MRO-NY?4G^6X&YTS(0[R'V#/K?+=VZ006N4273DK>LKH`M4O5* -MZA8:RB-7+VWW9R7K99W5%=)%M5Y%65W!793KG9W5%>9%O5[Y[M*JUUO?=5KU -M>HV[.[)<+\",:M4[4?;^=WUXRM[5KJ14V>O:#7LJ>PN\VBYE;W8W;:7L]84I -M"U*]S]?Q;MQ*V;OH/7QV]US5E[V3WW:7L9>^2R92][UTPGK)7OJOO4O;6 -M=]%KRE[C[GHMUQL54Q9(C?B]_UTX'K]WM8N35/42?,%&!M^BF;*`;)3P39HI -M"SY\G6^HJUKL-'>]JO"*^OE[8%<97ODN[POC6=V]7&%_CKNXJXKOL77F1 -M?/^[+R^2[VJW5$;R=>V6Y4B^!5X1&\DWNQN](OEZ>ZE7)-]AF&(#X:NW6O0: -MO4B^CMZ\',EWLBN^(OFR=XEE)-_WKOJ*Y"O?Q7J1?.N[SC*2KW&7?A7Q[?>* -MO:J^_]VR5]5WM0ME4_6Z=J>97E^%+[DL[.OP%^2L/2^JUV$F=[7M2OYTOL6 -M>`%M>M_LKN9+[^OM[7SI?76^H"^][Z*W8Z;W=?2>OO2^DUV2F=Z7O6MIT_N^ -M=UEF>E_Y;J=-[UO?G6+I?8V[T*BS;[\WBZ7Z_>_RS%2_JUTPEJJWP#O&FOTJ -M?,U8ME^'+SDJ]ROQ14?Q?M>^<*S?[WMWCO7[E>]VOWZ_I5^(T>\7]=OV/8Z" -M>,5FO%_F[OHK^KO:=7]%?UV[BZSH;X'WD17]S>[.S:*_WM[]5_17YZLWB_XN -M>M%MT5]';^`L^CO9+9Q%?]F[J*SH[WNWWA;]E>]"SJ*_]=W)6?37N)L!X_WV -M>SE@_M__+N?,_[O:%8&I>K.[Q*P#L,(7!:8`=O@RLQK`$M]G%@1X[2O-F@"_ -M=ZM9$V#Y+C9K`ES?W69-@(V[WBP(\+(WG"4"_N^2LT3`!6#E;R3)M3MS$P$7 -M>/5T(F`$,,0WDN3MK6>)@'6^^"P1\*)WGR4"=O1^P43`DUV!E@B8O5O0$@&_ -M=Q%:(F#Y[D)+!%S?=6B)@(V[$2T(<+^7HB4%_N]>M*3`J]T]F*JW!MS\=:?= -MPY8=<%]QF@]X!BQ.F^RBM+;`#+3-0JN72_K>=6FA@4=KFP5RT1OX@K99P/5R -M28V[-ZTY\+)7IZ4'_N_VM/3`JUV@EA[8M3O4T@,7>(U:>N#LK@M-#^SMW0GJ -M@76^W3H]\*(WAZ8'=O22Z_3`T##$2[/W8TD-^VIM@@U*V#"QUB>X:,D-*VL= -M#3Z6X+"TUBF84FH1:VN-@MUI43&XUBLXF]1%FVO-@K5E=JU7\#`LKZ4++IKQ -MM7K!2;._%C#8R2;86@7'+3O!5U%CL`4Q%*RP5`8?E4K!7]&@@F^V%?R@4O4^ -MM50.A#1K\('MLC4,YL\I7RB^(D1X6+S`#IQ"I`;S>F&ES[/25C?8,18OP!=I -M@S]Q\8)^T3N8AA;;`@`"W#\X%;S<^@>3P^@O^N#"&CKL7N`MF@?7@A%]%F%Q\`5.U8L/WL!Q -MA'W!U=>/<#!X3"42)@:OMTK"=#3WEC[XL]8*[J:AA$O!'T64,$-8!8PP?0@+ -M[DK"`+,`UTK8+_:!V0DWTD@P/F%'W[Y@#3Q(5(RE8(+"O34)%U+8%V;A>@7[ -MEG;!&BZ<,#[8`2%TZX$QQ5Q`F'@N&0..%2<(P+)YP*!O?A -MA!_"L*J2<"SX#:<69H?M"\C`LT1Q,-1)U*<7)@8K -MJ_K"*6$I%V`X%%SE`@R7@K%<@.%4\)8+,/P0]G+UA7/"W:K'L%L87/48E@O3 -MA-.)(K%_01=8Q=4*7E<]AMG!@QG -M@N5JC^%.<"_N,1P*SJL]ADO!D*['<"JX8O48?@@?\/K"L6".%7#8+>S``PZ+ -M@WV+JM[7@Z[RW8Q^F!=+76X(EP[53G0 -M>G5[U&%R<)7M(5RTL@YOW)(QV6&>\+#7N$<=E@Z&GU.'+<*-I%VSMQ>Y1A\/`V5/JL'2XT-8*#G?)ASO!XU[Q*7*".]RL+06G -M>]5[*@=V[_HT0GP.)MA.A.6]\5-^3'K89];O>@4CB./#^M."C#[X85L@]@:$8,*<:./)F;YHA3S@Q>_5$V5@^/7:GF)%,84L]A4IQHU%#*3#;,U6L.GWK;G[T@?+-;D3QF+H\.L7QR@L%@\/ -M;X7%HF+"9B@8]QMD%!;?B7^WJ6#?[V%36.PJ=M].A(F_=#>W\/%W[R8LU@]/ -M-E4.Y"]5[_>V8M`ESFP:2)+%\&#KKS,U_O4*+CWA@[F_D+=6\/=7S:AR$/_6 -M;_O%T6+-6[^83KR[K<45P.#%M[0-Q9+8??L0CO]J_";"]%]V:GX&8=PFUO\R -M -M75_&3;$8B]A,9*@,>[O7!8C,1'? -M#42<,1+]<(G3#Z8/5C?&2+K$*\X8B738Q5DGH1K/C1_"*RU5+UFU3J(U[JNZ -MA6-:BF-),4TK:<5^5'?P'#OTQA07!H;]=<"'8X=@*1@0# -M5I6N=N.\:B;8$;S)5;IV@?50H6!*<"BW3C(XEE,U70W'?57F0-.U9.R%HPLT -M71O'K%P%0--U98S[8QPU7<7#`).FJZ@XYMATK1EW_YJNUV)`9]-U8>S+;;IV -MBP^=35>YL2>LZ9HZ'L0U72_#I;"F:_-W_M=T!1`S'9NN<.%7&-35<#QUA+J: -MB6UA4%>M\:@3ZDH\]CI"79''S%6HZ_*XG`MU=1Y+5Z&NT>-UKO#X(V8/;CM" -M7:_'N4ZHJ_9X`PAU[1Y[`*&NX..\(]1U?,QWA+J:CY6=4-?T<;-SZLH^MA), -M7=_'S+BIJ_Q8*#EUK1_+JZ:NR&-NY]1U>4QYG+HZCR^/4]?H,1%PZDH]/@). -M7:_'2L"IJ_:X"3AU[1YWQ*:NX&-XW-1U?%P2F[J:CV&Z4]?T,4ML@(S@,BW= -M'IG((&0_E-5UA!RFLKJ:D+-;5M<4,L/)ZLI"-C5975_($R>KJPS9=GQO*""O -MBW3'_`8S,B#,ZKI#IHI977W(>3*K*_@X0&!U'1^/'ZVNYN.KE=4U?5P6R[JR -MC]%B6=?W\?LQZRH_KGEF7>O'<[&L*_+X+I9U71Z'`K.NSF-28-8U>FR4R[I2 -MCQ&06=?K<5,NZZH]ALIE7;O'$$/!>2LYP`Y-!P,'""3 -MAHF!7%=!LA>Y-%!(#B.7!A#)9&38\-J3Z^I(7B.7!B+);N32`"4YCEP:H!YC -M!+BNU^.G'==5>UR8X[IVCXE77%?P<7.,ZSH^9EYQ75F5Q%%I+ED['(LP)I\A9Y5E!-GB5G>VUS(H*OZS:9C&P@MLVA -MD1/$AL@!LKEW.B=1/B<3DR7$,$&QZ_(X1"9V=1Z7R,2NT6,4F=B5>HR>$[M> -MCX."8E?ML8Q,[-H]KF&)7<'']3FQZ_@8/R=V-1^_(L6NZ6,B6=F5?7PD*[N^ -MCY5D95?Y<5BP[%H_CI*579''P\BRZT;YE%PD_G\.D%.^$CK\0-F5I#Q0=A*3 -M7)_**F5;7,$=OU8Q173$J\(6Y1<1EOP -MBKQ%S>6$,D=">=1<-A'PBM)%S64T\A@KN5RWX!7-B[C+'N1O`W7Y14A'3A#T -MB[C+Q^2HV7BY9<47X!5)C;C+#P)>T=6(NQPSX!5!C+C+#@%>$6]Y^CI`%IMQ -MER\$O"+B\HQP@.S^XBX3$5`$BRSN9_DI@QA=AF,O+A;/<,H@Y8"1B1B,AF-_+5T("\WS97H=@OB]7 -M?!',^V5_'8$9N#RVDBYSSDK,-B.\*W+Y'#I`)F;AF"MB>-<&,YRPQPQACH?B -M72G,BK/TLC3KQRRXP+MNF!5G\66\@X=9;U5?)MBLEQMV^66\`XFYY]MC1C$K -MS@#,>(<5L^),JJR7N#)'[`[,<@DS\Y\5[TIC5IQ)EZEG3&8)U9$7V`5N#5TWP#4W -MLP%YC=#G4K/Y[3&:]59GN8[1MN8F=.D^.;B'>[9)=5X13G? -MTX+/+.>/I;BYRC5\EE`T7M'.\K3/\Y:K^'/X9Z9Q7VS^SD2*OT.>CTM.Y8N5_5BYC$03.RV!\,\>J`+VVB+Q" -MFX]JD=?5\U,K\LIWGFHIH&//5Z7Y,^WYJN1M;G45H`T$E=?=\U5)W,RS^D!7 -MG']6'^C/L]#J`\UQ+EI]H,W-2*L/M+IY:?6!?CH[K3[04^<=V0>:WOPC^T#+ -MG'UX'VA^LZ3T`YUS#GL6H'G.VJXC],\Y;76$]C:'NW++YN:X%10:Z7SNFD+_ -MGP,X9F;,VKT(Y5Q;FCJ3R:S0XJ1[$;`Y0HMOUG>!H3G-PI0L-+CI7H2`]BWU -MGMUK8.A7R[T(VNQ;7]R*^LV])W'QBC$-7G`EE<>C/\\4K#LUQUGC% -MH<6A^O6)]C93KW++BVB^LP43WVST0D6;GO-RKFCCNV@Y].`!^CSBRD7? -MG,.)#N=I9C):W$PN2T97G$5SR>C/LP,K&EU]2QE*[WRG;7#I=?8+)?UTSF.QI*?.Y"^6-+W9ORS+3+U6 -MI&W'_@2,-*$IYYQ@[M<^C&3-[M.?\]S,)&T\]B>@G*?.%^9CYL,(V$PB?AA! -MGXM=#R.9M#(3*XV`9G8]C`K2SZZ'$;19VO4P6CUK%A]&?&=Q)KZ9`Y9;!BT^ -MC&C/H\78*T;:M!A[W3V#4&.OLN;68NQ5)&U"C;U>I4G)X@HS\\\V]LJ5'CEC -ML^K26.29@E@:N(AO]F9!IEW.*C=_L[JM,KV61DJ?LR[35+38:UQZC3Q3B#T_ -MO'[.<&8E:NT5(TUOMC/+B6NOLF;O8NU5)%U%K;VBG!5NM==B-'JQ-0ULCKC5 -M7J'/[L7:JU@:45Q[14#S;6NO!6G\8NT5VKQ?K+VNGH->M5>^LU`3WRS2RBT[ -MG2K.)2WK-$QZYF%F=CIQG%=:VNGHELP6^\5(TUVZ[WNG@]?O5=9JVXZFNH[IKWY -MF_%NO5?H,[NO]RJ6GFSV7A'0ELW>:T%ZR]A[A39S-GNOJ^?/9N^5[VPO%AXW -MWS[4563H&XZ:\A9\95!OD:UO.^K05?!50AU&YKX%J5\2P5<,]5=9_!:DSC"7 -MWYK4'F192H`ZCLQ^\S=;E]]O5FH3L_S-S,QH#+Y"FUM^P=?5A7_%5UDQ1+;Z*I%VXQ5>4<].O^+JAIN$6 -M7X'-[#YP)E\=5,OJ1'/6%P;]>*YVIA\O5-3J2//V\;DZX:Z`9=\!3:' -M&Y.OT&=R8_)5+'UN3+XBH(%@R=>"M.0O^0IM/H(E7U?/,<[D*]^9QIE\C3W? -M.).OM&>U:O,5(]U6;;[NGN&JS5=9\URU^2J21C@V7U'.LK_FZZI:BLR(\S?K -MH0#,*!4SQ^=JKMAUK6\352VKQAR%R#57CZ,0NFGL,3!.W[P]'L8! -MK$M15VH"]/O/1GW`PS"1C_\Z#VM3MB5=!H8"U`#AH9K"N`-FH7-`8P:(1H]JX& -MC=#.W["U7BUE7_7,XL[LZ\!ZAAR28UC;D*$J76L@,W4G;2V'5LG) -MFZ^`^Z3LZ]!:B-S=85NWE\$[9NOU5/:5:;U$SKX^K4G)/KF\M7@Z*">XYF5E -M7YO..C$;]2":X=E][5<7=1778.N)I^)Z;.VN?D1G/+NO"6NHKN*Z9PT5BU)C -MHG^LW=>A-1U9P0.POB,W>$K7PF6V',.ZCYPS^%@#DG,&H>;YXX)9PX.ZQC1W -M>&K7LJ6LA/C*8LU([BSTJQ_)@[G5M<8:Z\6[5C@KYG#7(&C''/+Z;HV,;GKJ -MKH'6H>0<#_(ZO\SC05ZWE7\\R&MP-3:ZE:R[=EW_J+W17[G9=3A:&6BC)D>G -M(,FO4>>XG(U:'>V")+^"K6.0Z^N!-:1U?6VP/B8K&1+6RF0E0\^ZF:QD`%I# -MDY4,0^MIP1GU:C?#7W.J5M++51DV.LF!' -MJM%1+NSNEM7(:,T\FEWCI!'*+&P%MKO:)^U09F%#L-?(PH.2M7^7A8VX%O!N -MC=+7=^NF]/+31OW(LEA_E/DG`VN1,O_$8%U2'O8`K%'*_).>]4HYV7/%[CKS -M3X;6,65G3Q=[[(RC&V,[DK9&3&N=,O_D8]U3YI_$KH'*_).2]5"9?X*X-BJ7 -M>\S8>F=T#Q[[>HT"M98.CWU@3AXDK*61-NIJ5B#[(9>5>$QS -ME<]T#.LW62+;:-T8[%"'LQ;9?.9.@QG;>/QI`%C'E^]T#&L_5B.[9`U73AX@ -MKN?*J(;TM5T9U="OSBNC&L#6?&54P\#ZKXQJ,%@+EA]UGNRCD_RU9XU81C4` -MK1?+FKIO.LOR5E)VCSDZ# -M)&W4JV8L72$;/&V2Q&;#LHO4YNDP*#;;EKVDYC6?03O4.BV+]1H4F_W+IE(# -MM:!,NN6EC/((GAU"#LS,LS^OX&H7&CU;(:V=N6>;R[;98*-]MM>:%T$V$FCS -MHGD1'R.#-J<979V6E>\87M<[,6C+H>EU%6WRLO"X,>#/5IAM -MM)./$6V957L98!?2-A?%EPEV)>V^M;>@HVTNRB\O[#+:+:NV\L,.IBVS`C!/ -M[&C:YB*ILN8'IWU\5!L%M&^A'^V"MH,99,?3MAV/[(K:A*VW$;;(H)UA3MFQ -MM#O7&^U8[4``,DE'AMGAM*O:(:J2]AW9>,/2UB/G[*[:"FF>G58[TBS\`6M[ -MK8=V9FU>M-%NK)UC3MIUM=?0SI^W]M@Y^B/7/F-3[=+:>H:Y450)GHU)WMKA -MM4?:TRV^MMXZ;,?6WC?-C=)%@NWYU-S(7938%CC-C>9%C>UCR]P(7Q39UFFO -MMR+;!V:Z'5Y[P4SEJ6M/6^9&5Z/(MG7Y;X?7?F@+[AK;3>U8'VK;@YRX*VP; -MCP]`..UC\N.NI*U,;@#%MH7+$""6-C1Y`J3;)FMKN.#9UF1.4&\;T[P]H&R? -M86<#)2[@-EP[JJC/M-EG(:[N^R_PVG? -ME/]`%NZX]?B@7S3BEFT?\$;<(VV.U8C[I.W`&W'7ER-X)FY2,@4OQRV>G@2E -MN`W7EJ`?=^5B-M#J&G%GMG%6(V[.-L]JQ%W?_EF-N$?;0JL1]T.[:*7A;FHC -MK:K?M'=D7FX%]X\LS/U_W@6QM.?*03R1N3E(LX&XU9V;Q'WNVG.SMJ]K>^ZJ]KMKSRW;)I/M -MN4?:8+P]]TE;W[7GOG&CU_;<+NWUVIY;INU>VW/;M.%X>VZ=-DYRSYW9[I/M -MN3G;)\8]=WV;4+;G'FU?O/;<#VV-UYV[J0V[6G6SMFE7J^ZJ]NT*GGWCUEW1 -MNA7<*Z];=YG[Y:7KCB/-!DIEO6Y.RZ\[8!3LYFR+V(+=]>WH5;#;U`TQ"G:G -MNG_:!J6)MM&KUWW1SLM1NZO:XBMJMVR;6$;M'FFKKZC=)VVL%[7[QNTLHW:[ -MM.E7U&Z9MMB+VFW3+GM1NW7:4#9J=V9[FDGMYFR3RZC=]6W1'+5[M.W`HG8_ -MM"-8O>ZF-@4KX,W:OF`%O*O:DBAXMDN[@Z7P5G"'L!K>96X2%L3;UXT68FGS -MU#;:DJ^)MW/9?@#9AI4VH.T'QNUI\&R@\Z7Q?FB#OB;>).Z.&,NTL%LK;ILTS0WGK -MM,%8*._,]A@+Y3>TY%M:;M=W]PGI7 -MM?-8\.R@-[3;>1GT9G`[+XG>9^U'%MQ;K3TWFWLO -MM/=?=N^'MMYL[DWB1K?QO5G;@3.^=U6[<,;WEFVCLOC>(^UZ&]_[I`TYXWO? -MN"=G?&^7=@:,[RW3YH#QO6W:G#.^MTY;!,;WSFP3L_C>G&T4&-^[OLW,XGN/ -MMI]9?.^'MC1K[MW4KF:QOEG;V"S6=U5[FP7/MFE[LVK?"NYP%NZ[S$W.VGU3 -MO,]9OF]A-X2(I8V+G@WHZ8+?I.^T]R]ZHUW/"GX_M/%9OF\2]SXK^LW:_H)% -MOZO:`JWHMVR[H!7]'FDCM*+?)^V%5O3[QNW0BGZ[M"-:T6^9-D4K^FW3OFA% -MOW7:>[#H=V;[?Q;]YFR+M*+?]>V25O1[M(W2BGX_M%=:ON^FMDLK`,[:CFD% -MP*O:-"UXMD[[IJ4`5W#KM!K@9>Z>%@2# -MAV<#.\$,^/][[)VLW6CGT";@%VUR'0J47WP_@H$KOVU-+/`'%3S[P%SD8VDG -MF]K*23XSN'"YR:<&-RY'^=K@RN4J'T[;+(WE@X,WH+E\=G`J>&MK#+Z&'O/! -MP;O+9[XYN*E9S?<'#X/#O*=\Q^0?`0G\+VWG^X/'EW\$7_#"]-]AKWW/Y"<\ -MM_C@XFE"WQ^<"([HPX2;G!=]?W`R^`;.$[ZYL(0+P9VVPN-+GR!\C64)3X)/ -M^73'G3XXN!:\F^8)YS/_'4+;JNE4'TM[P=SJVX6;F/\.9N_P(B?\"UZ;%C[X -MPJ-0_`0@'#P;;IL,SW"O%Y/AY*)E>->9V'<,QW,_'JKA@'#/I32<=Y0,#WF/ -MBEG@R6W#;2J,TM&1X,Q[F- -MPXGA6&2$`"7\54P&)V\+W5+AY^T.(S]!O0W6'(@CMG-]`W'&MEES('X*?]UZ -MD`U^U7#C,4+`%5Z['8@SP7>WDY:!^!.\Q@@05X?_;J7*"`%W^+-X($X"AU`C -M!(+A$^J/'TO;0OTDV(?_;F'A^"IX]I*1G[!6DXD/PCG,?[$[<9@P/-W3K -M&B_C#7%']0^V+IX/?W0K<7^P%W&;,2^\TIUL_,%ZQ$^X5/!-MT_U!TL"?W#^ -M8(/A`+B'.*G;[L<"/W6GJBTL+&U6M0JA,CXW)H+#NJ6JJ?!9=U4U.?X6GQOS -MPG/=6]6+.:Q](=CSBK -M$(+ATVH5PA?<6GUD*8_WP+G=I&-^PK<;L"H?3XO?C?/AY6YS-4JA.=Y7Y86O -MN]?5*(7IN.WX`.@>MT^C%%+C3DXM^+T;Y2@??XVO'.7C[O#DL9NEH\T\1BF8 -MO9_'*`7EM_38*^$2KQY[)23C>$Z^^,/[M3TP2E<:2TE]X8WK=,'-_*'^-5;:BTE[Y$S=*7D0?(3DQ%8[WEK`R -MREOD1>3YP9@<':7)2\OQ`1RYB992[R7FZC/(X>3X<\LVXGA_< -MR;'BEF^D+C\A\VT'3(5SOB_7-81!>4;.=UQ#((YGY![BI6_0=0VA2\X"7WT3 -M6?D)KN^4)[#<3-Y'KB'0:0H203`J]<4\[]GK-6 -M8D3@K5\C7Q"N)## -MKZNP&O+Y-3^A_[T-7)C+RI7)?0);>3.Y3Z`HAR:O("CDT^0^08ON>&:*B@T'W)C!8OF!V:N8-%\P0Q$\)B' -MD8$((7/;\5FP:*X[7@L*S3/,;L&KN04)Y,?@VMRX_!M_F5?.LM@R\+#AVK@RR -MS>70D00.:B:`A_RN?$3KD@F7WX/&\NRP?G)YOS0%CQ'.%LWYP>FXX_VUC -MZ<+FVG`L7>Y<4Y4]QS@G"*?G^>4S@HYH?((@GXVQW)1T-7F6ZX+>MOM*<3!9(9YJ#\0+I"Z17S==K;72LN7LMEKXUA^/% -MTKWF.$D&NN&\3Z9+YYV?&'OI:G1"&3#=C7[Q&J;+T35>QG2F.>S*F#XWIUT9 -MT^WFMRMC>M5<=S5,IYZOO*KI6_.75S7=:UXJJZ8;SLMRU?2PN8BMFIX[CUY5 -MTQ_GU*MJ>OI\Z%5-%Z(;O:KIFO.\7#6]M69#G7>.;DLHJY&%\U1 -MU-WH#JR+NAP]@J51UZ>3C33J_?2/D4;=;BZ)TJA7S3M8%W7J>0@KI;XU)V&E -MU+WF"+.4NN%<\I52#YL#VE+JN7/-5TK]<=[Y2JFGST%?*74A>LM+18KJ[XUYYEE -MU;WF8"P&>NY\C"56YYV;L%8;G6F^1S+K3XW[WZY -MU:GJB?2$[%4=A?X@#9V+S=;J@//U%V#=:^[^`JP;SA=9@/6P^2,+L)X[GYL! -MUA_G^R_`>OI<;P98%Z*CVP#KFO/`&6"];T-L#XWAYP! -MUNWFDS/`>M4\`[96QYISP%KK6W/.66O=:RX"8Z`_SHE9MG7>.0HLMZY&9V;Q -MUMWHSZS?NAQ=FB5<9YI7LX3K3@KNKXU)V=% -MUVGK>76#DN%\YA9=#YOKZ:+KN7/J673]<5[/BJZGS_%9T74A^CXKNJXY_X)% -MUSOG`JWH>M*\H!5=9YHCM*+K<_.%5G3=;N[0BJY7S2-:OW6L.44KP+XUOV@% -MV+WF>S`&^GF=KVZV5*]_U#W>[761NL>[508I0]LN9EEQJAV87+J<0UNT*ZE2AG1X;'$NOL8>A:(IZ]`9U+W+-? -MV1]4;_;W[YFXAH3[.?Q`+MANMS(J+]R/[F`[6KG-^)B/8GNP#.U#YE+\"9 -MVJ_LRRU3N^ZXGXAGSS`'%&OM'N0B1*V=T7Z!8Z`#F'T0)_9N8IJ]^NIKA[./ -MJ8KMQF4?Q)D]FZA<]D$$C)#M>?9N&K2=S_Y1G+;#VK/KW<19N^`.VMY=]D$\ -MV,N)PN.68I2]&5U00'!QVQ_M0#ANNZ3]P<5MK[0#QKCMF';"&+=]TZ[AXK:G -MV3V7W/9?NZ:*VWYD+W%QVY?L445N^Y,=#LEMG[+'N+CM5W9P'[=]U@ZK@K;; -MVM]P#O=<^QS.X`MTKC_G^6*4?:78D%A@6X!#[=+ -MN3SN>?8J%\J=SVY!_X`W(4+N:^A%PK,=T69H_Z`CVG+M(G3V\,@=V_Y4-+DS -MV.%L)O=O>R9SY"YA;]9BVF/HT]."`@W=/ZQT[[B;,I7N(/9F[9&]AZX$CQ8$ -MVQM-3_:\&LK]LQTMP!=MW:_L2O3UJ=)]YFXA#K=#T7V92O>K$!PMX+DO -MV;/H6NGB8I2]*QTM*+H#4,/M8O0!:D$!9\5`-TMO+)SN'-LI^\^J[]YUWEC` -MT2]\>/>KNUQZ[WY'3]GNW;WN/N*]^[(=$8YW)[O_^"3M@W0C\=Y=[9XDWKN[ -MW4G)&XN?.[`MS?Y(SRWNW>WNP+8C>R5]H%E0P*0O;5OO@'=4>.L]ZO[CN[*' -MTLG$K7?%^QKYP3AW=R-+&'LGA/<_5>M]\@ZV;;U;WL.+:?99>IVX]GTY6]GHX0%Q<0VAM]MO9]^J^OH.!/[Z12 -MX-'O%7%QP=5=V4>!=[__;G_M"G5F,06>^#X2%Q< -MV9/JM\TB_`Q^]_Y4/XNC+'+P<61-"@^^+:Y)`<+;4UVQXOUM=N^F*/;[+J;^-4?8ZM2:E"X^GUJ3P -MW/?4FA31NY]:DV)]#U1K4E#OA&H%PAJ>ZK=I1ZQ_Q@L*BW7\)BB>#K_?!,4G -MX?V;X7;*NK$1%-^'#R,K$`#Q-N,K>V=]-JY`,,3OWD?KI&H%`B,^#9]:3U5C -M'*/LK&H%@O7]5:U`0+W+JNT0F_BY\9(=MXY5#;?OUJ/C=@@ZO*_:#I&$#U:_ -M'('QNFP[Q!/^6&V'@,7W51GMS?5_HS/^^`ZMMD.HX/.JE7;KNN?8&<]SSU;; -M(43OD]R"PG>=/FZ',,9CD><%R?B^ZI(=O9Y8+2BLU]?57$=L/"M\7E"-U[+3 -MU^?5\X)MO.]=OZY9]<<3WY/'\P++._-X7G".?Q[/"_KOTN-Y`;:]>CPO^+EC -MC^<%0O?M\;S`[NX]3A@DX\/'"8,'//DX81![/Q\G#&COZN.$`0:^?9PP"+;# -MCQ,&'OCY<<(`%F\_3A@\Y//'"0.)//\X85"1_Q\G###R->N$P48^2KYZ;++# -M'0L*0G9,W)2]R&YW],6>Y"7(N4>G?`6Y]ZB5=R,''[ORPO?BHU/>@\Q*L,F' -MD%D).7D2\O-Q+*^0ECZRY9'AU<>W?!@:^RB7;T!O'^ORUF56PD;>AAQ^E,MW -MEUD)(7D>\OG1+T]'5C_ZY8_)[4>_?'LYEM"21R+7'_WR]67\HU\^O[Q_],NW -ME6,):?DJ!Q+V,M_ -ME2N0D#R#_,WGF&V0SGD\=PXR.O^7E[9_YX&X-3"@>`_J-/&*^X3Z9N\Q# -MW,.!`WJ2/#19$.F4GR;/&%3RUN090TL^F[R(K-!WG6<,,_EO"K'F;>T(PODR*5-%'YDOH#,$8O4=>GSQC",G[ -MQQ(*+O2*8$(!Z0YM'=)CZ._S-W0<]I`>)J^<8\U3W4F"3GJ;?(;*=^PPR,D/ -ML8?T/'DCML/@(;^8;Z)'/R_S9W?GIY,>(R]2=AALY$O*#@.//$K981"27RD[ -M#$CR+N5RI%,^I@R&4,G3E->1>E`R&D,A7S@>2>7J9M4$R4F]R!D.GSC/0A[QZI3:^?EZ1S -ME%:F5"KC\_3 -MWTO+RH1=_7U^G*Y:5B8$ZVW'R@1B_6N>G7[.WM8KZ[WR\O0S:&%>?-5RTBU_ -M#+!%_?JSO/HJ8`^N?PQ[X8Q`P6MC_Y@N6QI]%? -ML#SVD7E)E,>>,M_!\MA?YD-8'GOW/`G+8R]5EB8H[&^$K'G)E\=^P2Q-F!=Y -M["GVFB^/?5Z^\^6QW]B#OA;VLOF.&=2>+'_Z@MH7YDEF_?JK/=@H:V]BEB:0 -MC;CV_V=IPL<(;._KMB9$EC(6VW]B/ -ML+$^.PML7YM%1>'O$/!P+;[^8GV/A[6GTW2^\?60^CX6WI\R3 -MO_#VEWFQ&=[>/;_^PMOW[-U?>'O1_"(+;T^T?V3A[2GV+!\X0]T7Y@MG_7K$/"HK=M^UK[?1[L/VD+/;?=E^>4:E1X'I[N70:@URT?.^,/_,>MXC -MYJ59S_O%?#7K>4^CQV8][R/SVZSG/67>F_6\O\R'LY[W[GERUO.^9W_.>MZ+ -MYF=NSWNBO9[N>4^QIYX][_/R]:SG_<8>GZ6[E\WOL_KW9/DO6/^^,"_0ZM[VF%\'OV0*T0OFA^J!7")]H;M4+X%'L76@@_+[\3#.%O -M[+MU#WS9?`XMBD^6)]=%\>G(TDJ+/1Y)>&RMU.(7LMK*VDHO/AL-P.RM%.// -ME<659OQ(L[DRC>^U5E>R\7G1[LHW/J=97BG'UQW;*]_XW65])1[?@^ROQ.-C -M\>FN)@%8UC'98(G';R]K)X3WL*SXLL,2CU]?EECB\?/+>8WEO2D+C!]_[->[ -M74U)TOM(DE0Y9(G'/S"7+/'X"^:\AM&>6\G%WXA9\FW'>8U^T2D_J4VS?.-G -MF'&6KGP^OFXKD!_(,A[G-3KXZ:12_M:>2TK)1^1#+,GX!;A^?>J9B[_<$N:K -M\9];QOPV_G0KF0_'1_0Q\^?X%[AGOAU_`\?,S^-77ZOY?/PQ534?B[_>JN8/ -M\K-IU7Q#?C>MFJ_(_RA6\QOYZ]=J/B1?<%?-!^/'^JKY9/SS8#5_DX_@JN9[ -M\H%PU?Q0_H.KFI]0=H=D\@U*UN7+I1A?H&3'UW`Q\U_YGLN#/A]?4W70Q^*7 -MN/KUD/RH(D3?Q.P.D1I-]/_/[I"KT47?U^T.P>4?@[GXL*J-OG/9'>++MR#V -M\^=P(OV`/M1)I&_'EXUM]//XPZJ7/A^_>/?2Q^(KJU[Z@WPIUTO?D%_E>NDK -M\K%<+_U&_I;KI0_)]W*]],'XW:J7/AD?7/72W^2/JU[ZGGPVUTL_E+^N>NGW -M\^=<+_V`/KWJI6_'QU=M]%_Y:[6O/A]?T/75Q^++U?KU8/Q>'%J?HI]76^MC -M]"%=;GV.?L4JKB_LSH=T[">)(WV.%5V_G^_`H^MK]3WZ<<2N_BZ_T,[%/W7% -M]>70^1`3_B$1B]_J.NP/\G%6AWU#/L_JL*_(_UD=]AOY0JO#/B2_:'78!^,C -MK0[[9/REU6%_D^^T.NQ[\G=DA_U0_H_LL-_/]^$=]@/ZDM+#OAT_[!G7?^5K -MNVK[?/RT56T?BQ_NZM>3\>-6OGV*_KDKN(_1OZX1]SGZ[Z[C?EV?3*;<#^6# -M\93[_7Q]EW(_H(]>4^[;\==KQ_T\OGLMN\_'A^-E]WG[@'T\[5N@3Y;=-^2? -M&+/[BGQ"67:_D7_QRNY#\C5>V7TP/NPJNT_&IUUE]S?YMZOLOB=?=Y7=#^6O -MO++[_?R75W8_H%\JR^[;\*PI[ES -M\<5>*GYN.-,$7Q3C)SX_,\7X+W"FR5U_!O[BM^@_]U[\&GW\,(O%3 -M^*VG'/X+?Q69::+A/X)#39#WS5I/?LV^"0XU<=L7I:$F)GZZXEL`85;CMT]# -M35K\9?+W[3OO-Y8T/Y/8TL_F'[U;^GW\4SXR?N)>A@KI!^Q3 -MIB']>'XO\HUESQ]&OK'X^5'YF'O<>]8$Q/_P\AUG31#]1U0^?NA>-9TU^Y[L!^P3 -MI[,F1_[C=-:DI*^)/+N;U"+ -M1(+]TF(N_@*_6JR1Q?=CBT7^FOZ7N,B_TS\3%XE`^Z.I?'P-?DY<)`+8-U&+ -M1([\*6J12$F?12T2T?"_J/$-XGX9-;X!Q%^C?@N\\//%1O\LO^V+BU_#K]\: -M_4'^FC>C/Z4_FMK/]^';&8W^*?^P.-.?Y:_P/^*?Q?$-`_]W*A:_B=\6QS<< -M^=_P^(:2?I<:WZ#A!U,G.,7X8^I^`XC?3-UON/BGJ?L-67XV=;_AW?^FUG#" -M_779'\WV#R/^'2D?L-6?\]=;^AT^^G3G$*_D'8_8:P/Z&ZWP#8/U3W -M&\[^4N1^@]J_BMQO:/MCD7F)7S\<]GQG+"_GGCPF/80-9?=^SE%..SJL.>/8Y`([G_A8]%.(H!C9]1.*X!G;'\(BGWJ8]I.+H`@:"4)DGSP8R4)N'[S -M8R4))G[V8^9.-(#Y9>E.-(#P?SU]9T<1!4!]$D!'@!R`47+U3C2`I7])?5)Y -MN7],?55Y)0D>?41K)0D4?D=K1X"^?&1R)0DQ@!MDO`V!?JX4$05>?6QR$4\0 -M@"1D%4]H@`IIO`V^?O8P!V:\#1.`+62\#1:`,&2\#29_]C"K?W-]-T"\?P<\ -M+2\#5R`2&2\#3&`?6LY -M3XV`+&L\3Y:`0'`_3YF`\W^6?0E/$069?8QKP`UR@%YDP`UU@&%DP`UX@*MY -MH(`<@&=DN7^H?3E6H("#@%!MH(`E@-U'H(!6@(=_M'V_%KN7_S?>1K$07V?>=KID_B@+Q__'WM:ZU/WX"U?P)^ -M"'KZ@!R`QV3'#1^`RF3'#8.`S63'#26`T&3'#5:`TV3'#5F`UF3'#5R`V63' -M#3&`W&3M!F*`WV3M!C>`XF3M!CJ`Y63M!CV`Z&333Q"`ZV363RR!(VOM!A:` -M\63<3R^!&&??3S6!EX#33'^`^F3E3SB!DFWM!A&!GW\.+#N!6V3M!A>!I8`L -M>TIZ]$\^@:M_,GL];`0E(X%K9,\-)H$+@#M[T#F'?UQ^V3D$)1.`'&7/#1:` -M'V7/#7B`(F404!"`)67/#1^`*&7/#8.`*V7/#26`+F7/#5:`,67/#5F`-&4@ -M4&6!IF8C4'>!<6LF4'J!K6;5"#>`0&75"#J`0V75"#V`1F75"&Z`2675"%R! -MF7]Z>\E(""5B@9]_@'L2.G"`@WN:>M4(:X&H@*-^*E<()7&!KG^/>Q10""5< -M@*AZ""4Q@%5>N7^Q?FEE$06;>[!ZJX$Z@'!EOP@]@'-EOPAN@'9EOP@3@'EE -M:5`0@'QER`B[@5UGOP@<@()EE#$@<1G?E#*@36`OWO? -M(#,,N:!P8&N?^1[]7KC@8.`ZVSC@26`Z4'F@1`CBB>Z -M9;50RB/\@2%D-@MD(P""PG_4,P2"Q7_U+`>"R'_X+`J"RW_[+`V"J']?,`V" -MJW\"+0V"O'\%+0J"W6714/^!+T+(@0LM&8*'?PXM&8()@1$M&8+M93@+4B,9 -M@O%E.`M7(QF"Z'][,!F"08#_,QF"\'\B+1F"\W\E+1F"4F6[`5$E&8)P@"LM -M&8*E?RXM&8*H?S$M&8*K?S0M&8*\?S"18(?(V>" -MUF4C41R"[CJZ8R=1<((-.[YC*U%T@A$['F0O47B"E60S47R"%RL?!R!M>`=Z -M*^UE[`%0@H4KPF,_47^"&&=#48N"+&M'48Z"0'!+49&"`&9/49&"4F5A%Y&" -M!V;L`6`C9(*E<%M1D8()9>P!;()!6(F"#RJ>@G*"A#1D@AEF:E&.@GQF;E&N -M@G1DE&]$_R!S63W"+>"QF7N!/TBNX*19NX$68(Y41\' -M)S'"@IAFC%&^@KEKD%',@@!G[@2=@DE1IH(#@L4SIH*D@JEF'P?++."E8)C*N"" -MF(+K+>""FX+9-."""V;3"%V"SC.B@A]%X()N@NM7X()R@H([W(*L@K$^!X-Z -M@N=!!X.R@@@N_(&%@D`X$(.X@@\N$X/_9^,(YH*P6(F"A#$6@\IEXPCM@K98 -M&X.'@O=F'P>:*AV#G&;I"'B",67C",6"32QV@G!('8-R:/I1*H,*9^L(NH)' -M-+6"L"HQ@Q&#U8)-+/%EXPC8@L=1Z()0)S&#ZX*R,3&#[X+#*C&#E8+%.S&# -MF(+**C&#FX)2+C&#^X)5+C&#HH)8+C&#;H);+C&#+AV#K(+=*F"#>H+@ -M*F"#LH+C*OR!/X-L+FF#N(+K*FR#%X-S+F^#OF[3`3V""5F;@O@J#>H)+*[>#LH). -M*_R!Z(([,L"#N((_,L.#%X,^/,:#)@N$NS(-R@G$KR8.'@^((F3$`E&8/11&Z"^R_,A+EGN`$@@\9HB8+H-M:$9VR#),^$-8.%,]V$ -M(&C;)."$$6:$(&Q<)>F$MV:))>R$ZX(9,..$[X(<,..$E8*<,^.$F((B -M,..$FX+$+..$^X(H,..$HH+,+..$;H+/+..$H+8+`J% -MLH+;+/R!^80M@Q5^B8+A+!.%PF7/*'B"(G%29A=9E>U29 -MA;IC?E26A1EF@52QA1YDA%2QA71DAU2)A::%JH*O:8U4NH7"99!4OX7&99-4 -MPH7*9994Q87.99E4R(6IA1LQ_('!:0@V>(+$::%4Q87=9:14U(6UA;-\SH6' -MA6\^VH4:;*U4U(7M9;!4U(7Q97(WT84P:?X!R(3O<,)C%PGFA>)I(0GMA89K -MOU34A:"%%SC=A-]4B84':OX!U8,*:@<[>((-:C\[&887;E<[ -M'(:89@,",X6$3:R%'(,Q>",*'X9`9@,"/(4@:@,"^"+\@2-J_U0HAB!H`P)R -MA2EJ!3TRAN2%,2XOAN>%X#X[AHIM`P(0AE)D$`DRAIV%")5$X:V8R55,H:OA5.#9'%.ABN&;F0N55*&PG#LW%[57&&LH6M@Z1J.T6KAKB%LX.I:H@+AH9O8VUEB`L\A:]JB`LN -MALAQIX:/ANM_QH7"@\UXIX;]@G-CJ87(@]!_#$=X@L%JGE6)A<1J4$?+AJ9F -MI%7.AH>%V(/B>!@%VX,"1]B&?(,%1]B&(H;6:K-5U(8_AN>#\7&Y5>*&\87M -M@Q1'V(:_AGE5HX7S@_UXQ%71ALYF"$KRAC5GRE7UAO9IWP&_A+UCZX4"A`QR -MWP'5@P]R$@+IA'$&L0A^R&X6/Q51J'NFST52"'W'`<372"ZF-,32:'E3@0AR^$ -M\&,2`L*$\V/H32F'YX4XA*E.ZX4[A&1'-H?9Y/1H>OA5.$_5P8!5:$`%U/AYF&/G+&8ZT!385C@"Q6 -M)H'A'+)A6Z$0$#KA7&$-T"LA72$?(!J -MAQ2'.623"XF#A(!AA[R&4T"'A8"$CG)AAQ6%%E9AA\6&6T!JAU.''%9JAU>' -M-EUAARR'G7)AAR^'H')AAT&#B6L8!9B$C&LN"66'#T_KA9Z$JG+D5%V'K'!O -M5A>'KH"1AW&':V2359N'_&FM5:2'58>PA(5`D8=]AW=D/58FAWID:5:OAPII -MA5:RA\APQ5:UAV%H&E>XAPUH+@F/AXED[AZ^%RX1?.;YCEU:XAW)HFE;' -MA[B%U81?.8N%>C.*)U,YX87'H(63,^"'08?QA/:`WH^AU.&^H2[9-5:N(>RA0"%!7H6 -M6_.'N(4&A0US@5LFA\IDIUO]A\"%#X63.:"%$H63.:.%WBS0A]9DA5P`B""& -MY"P)B'6&YRP/B+EG^UP,B"F&>CH2B&=L[585B'EM\%8;B(N%+84)0>&%,(4S -M>NN%$H*D3R6(@X8)09&&.87'5B6(=(<_>@57&XB@A2*"P#DEB'V'-6PEB("' -M"2PEB(.'37H8!3""3X$75Q6(LH4V@A1E/XB/AT9L*@<$A^&%0()?>NN%0X+1 -M3YV%884Y0:"%28+13Z.%9H6?2$^(=('/65$5VB(369'5W"(Y(6%A;](PF--5W"(^6505W"(;653 -M5W"(`&965W"(4F595W"(!V9<5W"("V9?5W"("65B5W"(UF5E5W"(NF-H5VB( -M&69L5Y2('F1P5Q>'IX$_"5>'\65X5R:'HFQ[5Z"(PF5^5Z.(QF6!5Z:(RF6$ -M5Q>'>66'5ZR(<6Z*5ZF(G&:-5[*(DHAZ<]"'A6655ZF(F>Q5[N(?8@".+B(562Y5\V(@XC; -M@N6!4PF5A\\J=XC3+=.(SF;)5[N(CXCUA610W8@4AZ%>W8ATA_:!V5>IB,9C -MW5?*(^DGNF6Z:_"(GU=]B-TT\8@D9%8C](CF,M>($"/XB)%FC6S[B.TJB8BQ -M/O^(F&99"1\C!HFY:VHC`HGI*I*(0#@*B=UEB)HJ$8G+B"4N$8EZB%%%$8E]B'!($8F`B#$N$8F# -MB.`^$8F&B+`J$8F)B&\X$8F,B',X$8F/B%`G$8F2B+(Q"HF5B,,J0XF8B,4[ -M0XET9`-Q#8E*B5(N\8AW9,DC'HE>@C]83(D*:3D)58G((@BYSB35SB8"(D"YSB8.(%2MSB8:(!SQS -MB8F('"MSB8R(#CQSB8^(OD5SB9*(A4)PB96(IRZ8B9B(JBZ8B4J)K2[QB!R) -M."NAB29F!07>(J2)_V?E=@V)T&0C=ZN)`(E%*ZB)7(E(*[&)7XE+*[2)CXA. -M*[2)DH@[,K&)$HD_,KV)F(@^/+V)GXECBHAQ*[V)?8CG+KV)@(C7-;V)@XCO+KV)AHAD,KV)B8A@/+V)C(CZ -M+KV)CXCH-;V)DHCK-;&)E8CN->V)F(AP/.V)2HDX2?&(Q8A],O:)I8DG1OF) -MJ8F$,OR)OFYO`5$E_XG";J8D#8DH96\!IXD.0XR(M"L#BH^(MRL#BI*(NBO_ -MB1*)*R\3BIB(+R\3BDJ)I3(3BAR)93D3BL6((C83BIZ(T2L3BLN(U"L3BGJ( -M0R\3BGV(1B\3BH"(>3D3BH.(XBL3BH:(Q#(3BHF(ZBL3BHR(6"\3BH^(SC(3 -MBI*(]"O_B96(8B]#BIB(92]#BDJ)4#;QB)Z(TTQ,BJ6)Y#)/BJF)HCE2B@"* -M#BQ5B@2*$2Q8BCB*9"-8BCN*"8ET;G>(DBA8BI*('2Q5BA*)(2QGBIB()"QG -MBDJ)"#-GBAR)DB]GBL6(@#9GBIZ(FB]GBLN(G2]GBGJ(H"]GBGV('3-GBH"( -MIR]GBH.()#-GBH:(EC9GBHF(+#-GBHR(G39GBH^(4RQGBI*(T"A5BI6(62R7 -MBIB(/#.7BDJ)8"SQB,N(8RR@BJ6)9BRCBJF)Y"BFB@"*Z"BIB@2*<"RLBHF( -MHC$+/6*I8DH,/B*J8G,+/N*`(K/+/Z*!(K2+`&+B8C5+`&+C(C8+`&+ -MCXC;+`&+DHC>+/Z*$HGA+!"+F(CD+!"+\XJWBG]+'(DS-Q"+Q8AZ.A"+GHC4 -M,Q"+RXCU+!"+>HCX+!"+?8C[+!"+@(A?,!"+@X@"+1"+AH@%+1"+B8@(+1"+ -MC(@++1"+CX@.+1"+DH@1+?Z*E8@4+4"+F(@7+4"+2HE[,/&(*8NZB@A3*8M= -MBGA]+(O!BLY+@X@H+4F+`(DK+56+7FM["0F*"%.,B#$M6(L+B30M7XL`9WL) -M[B)?BQ*).BUFBYB(/2UFBTJ)0"UFBQR)0RUFB\6(1BUFBYZ(+C1FB\N(.T%F -MBWJ(W3IFBWV(.31FBX"(Y#IFBU)E=EIVB8=$!V9Z6H>+P#4+9GU:BXN^)0EE -M@%J/B[9C@UJ3BTEMAEJ6BTEIPF.)6IF+?&:,6IV+=&2/6HN+`&:26J.+)F:5 -M6J:+_V>86JF+OFZ;6JR+PFZ>6J^+C8O-8*L"S'8-:*1:KXO6974"`HJVB[IC -M=0+8(O&('2:^8ZU:#8D?+IN+4FW!BPIGL";%BX""N%JLBTUFN";,B]=Z=0+X -M(LF+&&?#6M*++&MU`@$CUHN.;P);BR%%'F1[`N0B]HNABQ()'X"6PV)%FD&6[@3 -ML3WTB^F+)7!#"06),84=C%&+(VF;BP@N"HP@:($"P(LZA1I;%8QZ:QY;BXN$ -M)O5E(5LNC*1D)%LKC.)I*R%."<^C*5PC@I!C)&+ -M,(E6A8$"&(M+:2.,&XSN4\.+.8EH=X$"(8SN4Z&+/XEJ?ET)*(P<6VUE70GY -MB\I,I(M(B2=B0PG**O&("#YAC&6+`#Z-BU4N8XQQ;F8)#8EL:5Y;;8QK:+\* -M<(QC9V5;BXMV:6A;=HS*B^,J:HP:;&Y;EN&C%J,:S5\C(9KW`J&C(6+?(FL=XA;B8Q":HM;AHR1BX6)R45;"?TB -MCXSV:91;EXSWBXZ)%4U;"5)KVFB6XN+LFF+`B&,M6E# -M!;R+>&*)BZ.)*DV;BSPK\8B^:4,%_8O4?D,)0BN^C'&,L(G@=\.,\R+%C-QP -MO5L-B=IVENQC%MDW5O1C"YGT0=8IN+L"L8C:9F307!C`5CH8L/BG0W -MQV1-!?B,[EOM94T%RHQ$>$T%.XP%8S",&XIA1A:-W(M->"E'A\*`V)9FJ4!@:-+&.1 -MBU2*(5Q#"5>*A'B4!AN,)D"+8U4/Z2+>(I7/X6+>XJG<5P+A8U"C(&*K7&9 -M`CR-L'&;BX>*LW&17(6-]XN-BJ1JEUR+BQ9.0PF3BJEJV@=-C:QJV@=*C<:&FXNHBM!_V@>?C--_I8TVC<"&W66V -M7+*-S(RTBN!QV@<8B\UJV@<;C-!JPER+B]-JQ5S%C89MR%S3C7IGRUS6C5J, -MCRSQB-]JFXMS,]R-6&1W"?6,PHV)B].*_7C:7-"-863=7-:-NHO* -M/4>;B_J*)')P"5.-WF-P">.-/G(`9W`)*8WD8PI=!8[,C`F+^3\)CKZ-.X*"4!#"1N+.(.)F31=-(Z^BS.+3HDG86M47?R-,V2)";>, -M9H>^BU>+%3G#BRXM6XX\9%]=7H[*BV&+>X=E76N.$6=H77".V(QKB[-'0PEN -MBQ]6=XY+CHJ'=%USCN&+=XN?@'I=?HZ)BWV+RT=WCO^-J'F#77Z.UF6&78>+ -M,S&Z8XE=&(QXAUUVC5V.CK2`D%V2CH1RQF.478Z.=&2779V.)F::79F.1U;" -M8^TI_(U]9*!=HXZ`9*-=IXX7;J9=H(Z89JE=L(ZY:ZQ=JHYK:*]=LX[=9;)= -MN8X>9+5=K8YQ:[A=N8['9+M=N8[M9;Y=N8[Q9<%=MHX89\1=N8[Y9<==OXZ. -M;CI". -M_C=;C@)Z(P7LBP5ZYUW1CIN.\HL-<^U=CH[*9/!=]8["9?-=^([&9?9=_(W3 -M9%LJ_HZNC@:,[4"EC@F,\$`C!0R,DSF0C@^,5$@%CR*.JCF]CA]%6X[H9`]> -M`8\:;!)>%H]P9Q5>&8_.9QA>HX[T9+P"88ZJ.<^.$(D/0:6.#RX3CU5D)%ZU -MB\U6)X\0CJHY!V:\`A2..(@C!2&)2GHQ7AR/C(XGB4^!-U[[CIJ+-8\/CU=Z -M/%X9CYN.,XE:@;P"5XX<9;P"_XT?94=>_(TB99`,3X^19K8&&XT]00MFM@;Y -MBSU!XHY?C#E!C(YBC!Q>I8Y.B1]>88^XC?LYO8Y8+EN..F5B7E*/%X]>+FF/ -M(VMH7FR/(&QK7G*/MV9N7G6/SXYFB<9(88],CRJ/;(E19:6.;XF4@8&/58^( -M;",%CHRF/#8Y)7H&/+X^LCHZO/98^D@8]>_7L"/.W(BSCZN/861U!:Z/[H$C -M!=&)Y8C@CU6/Z(C@CUF/]H%%#<./FX[O+D8HNF5,#CA/(C8,D.*.T2L,D(R.U"L, -MD)".0R_[CQEFB@UD(SV0O8YY.3V0GH[B*^V/19#8(D>0H8[J*TJ0_V<)".0B -M39"^;@D((9`O9@D([B)1D,YE"0CTCS5FI8YE+UB0C(Y0-EB0D([33%&0NH[D -M,F60O8ZB.66019`0(V60PXX1+&60QHX4+&60R8X7+&60'Y"2*&60SXX=+&60 -MS8\A+&60U8XD+&60V(X(,V60,8^2+V605X^`-F60XHZ:+V60C(Z=+V60D(Z@ -M+U&0/I`=,Y60O8ZG+Y60GHXD,^V/PXZ6-IZ0H8XL,Z&03I"=-J204I!3+*>0 -MPFZ)!4F0QH*)!=XBJI#BCCPSJI",CF`LJI"0CF,LIY"ZCF8LNI"]CN0HNI"> -MCN@HNI##CG`LNI#&CG,LNI#)CMTONI`?D'DLNI#/CN0ONI#-CV(SNI#5CNLO -MNI#8CNXONI`QCXLLNI!7CX\LNI#BCG,SNI",COLONI"0CGHSIY`^D.@VZI"] -MCH$SZI">CH4S[8_&CJ@L\Y"ACO4V]I!.D)`S^9!2D),S_)"KD!DP_Y#?D$"0 -M"HJECIPS_Y",CB(P_Y"0CL0L_)"ZCB@P#I&]CLPL#I&>CL\L#I'#CM(L#I'& -MCM4L#I')CM@L#I$?D-LL#I'/CMXL#I'-C^$L#I'5CN0L#I'8CNC@(M[8_) -MC@4M1Y&AC@@M2I%.D`LM39%2D`XM4)&KD!$M4Y%7CQ0M4Y'BCAG6ECO\S4)&ZCB(M8I%"D1\C8I&>CB@M8I'#CBLM8I'&CBXM8I')CC$M8I$? -MD#0M8I'/CC(T;66B -M8)^1OWR=D3,#O1/MC\-\>PGX.J.1K&>ED5>0;&"ED5N0XC0)9;9@K)%@4JJ1 -M_2*HD6MHO&"VD;ILOV"]D=QPPF#`D<1GQ6!C`R-+I9%@([J1$6>)+:>1*TNE -MD6>1'TOU98\M_H\&)?EEPQ?4D45+H9'Q1\J1AFO?8,V1/DN=D4Q.W)$J9Z(M -MWY%%2PMFZF##D9]M[6#8D?(TUF7Q8.V1!'WAD0$CW)$99OE@YI&P8!YD_6#Q -MD7%D`6&LD=:1_C?MCV)+X9$$D69+`&;'+>V1`FB=D;[21B#X-DCEFIP\)DKN1&S@7DD!FXBT:DL&18RH=DGEM]P*YD3%O"Y+T -MD>A@[67W`E(C(Y+Q9?<"!9#H8-*1ZU2YT$CDE)E -M0&$0DEMD0V$@DD)J1V%!DLYF2F%'DC5G36'_D5]E^P*OD1I$]I&>2QV2?&8Y -M&$22QF/V#^V1H9%11>V/;'8L+EJ2PF7[`C&2:F^=D>`^79(.DK`J9Y)>:_L" -M!9+.2[21Y(ODE@N>Y+2D5LN>Y+6D5XN>Y*AD=TJ>Y('DN`J>Y(_DN,J -M>Y('9IIA?I*E<&\NG9*TD7,N>Y+OD?0J>Y*Z8P,#K9!U1/:1:S5QDE62@BZM -MDIF12O3BSDB9FC"ZLD0,NG9&0+K:2QF6>&.V1M6B6+L"2%VZD&,.2 -MF&:=+KF276>@+OB1`S9DB\F1S';=90,#;9+Q1/J1JBZ]DL21K2[7DB!HV&', -MDB-KOAC&DB!LF!!0D-"2TI%"*]J2UI%%*]J2H9%(*]J2!Y)+*]J2/Y).*]J2 -MFY([,MJ2Z)$_,MJ2M)$^/-J2[Y&24MJ2IY)A3]>2]I':+@*3^I%I*P*3F9'A -M+NV//Y)Q*PN3MY+G+@Z3_V?(">.2MEH,DU20MEJ;DF0R$9-A:/8N[9$3:1IB -M^)$6:1UBK)%!17L)ZS4;D]&2`9`?C`=D120272,)!.:349,)-=<%-B))/]D3F0:G[.!<^268PZD].276G. -M!3B3=W=["4:0>G=0+^V19FE-&6N3<6YK8OB1;&EN8G&3NY'T*^V/BW=9&6Z3 -MP9%>D)%W>F)TDQIL?6)_DW!G@&*"D\YG@V+&D5,^TI$.+'>3I&1N&7J3/Y-S -MD*9WD&*LD;Q%G9%YD*QWEF*%D^B1?Y`[5):31)/`-N^1A9"X=Z%BCY/VD8N0 -MIHR,&:63F9&1D-A%>PF4D*]IL6+XD;)I$0-CDNA%/Y*=D,M^KI-?D[MIEI/3 -MDKYIOV+MD<%IJ1G!D[N1T"CMC\=IR&*RDZ9F%0.?D\UI%0,7DZ-B@I*YD-2, -M%0.RD:-B+Y*_D/)WP!G$DXIMQA'23IY+=D`MQWQG?DU62XY`6>.49[9&TD>F0!&H;"M:3 -M&'^=D>^0(G@*8_R3#I+UD'Y->PGXD"1_$V/XD19J&PI>D1AQ\Y.[DQQJ`Y33 -MDB!J'F,'E'%K(6,/E#&3#9$_<<8%$Y(%8R^2$Y%'>"YC&Y0L:S%C*91`<#1C -M+)0'DA^14G'&!2:2!6.;DB6138;&!2V26WA%,"R4[Y$ND6%XQ@45E+I->PDT -MD6=Q4&,IE%B2.I%M<3X2[9%O>%EC391ADD.1RTV=D4:1>'AB8U"4:Y),D=1- -M>PE/D6R-6!)8E'AN;6-@E-&26)&D1E24M9.&?U24$I0V8X*289&3<7]C8Y0O -MDB4M[8^$:H5C8Y36D6V1GWB,8V.4!Y)SD8Z-G9%VD:=QEF-CE.B1?)&M<742 -M^")TE+9CHS!CE*>2A9&A:E0&DF#I5:EMZ5")6%.74F"Y7$*WDF0%&5])A66H95@`O64Q91.$W:5(3)])OR4 -M)3)])O^4*#)])@*5Z#E])@6504%])@B5,C)])@N5-2R")G*5]3F")A*5^#F" -M)A65KTB")AB51#*")AN51S*")AZ52C*")B&584&")E:543*")D26U)5DD'N/ -M@B9*EH:5:I"`CX(F4)8OEH\(4Y8REI&3"U"")EF6E967D[A(0I7S"$>6[I6< -MDS)7M)2"D*MZAB8;E0\"AB8>E7XLAB8AE9=!AB96E7`TAB;UE)Y!AB8KE0D\ -MAB;\E)(RAB;_E$PZAB8"E8(TAB8%E88TAB8(E9\LAB8+E;1!BR9RE5PZBR82 -ME5\ZBR85E:XRBR88E<)!BR:4EM25TY/,C[24O)!8.A<"BR:=EMDMBR:@EG^6 -MQ9#=;(LFII;FE6JR6/)J8B -M^Y::)X\FJR+_EJ46CR:P(@.7BI8E*?^6=0N/)KDB"I=.E5P"%",*EZ252PD1 -MES0C\#B/)L4B"I=%EC5EA$!S2(*ER:5GS,5E^%>DR;HEA:7@Y5#*0J7 -M\)9&*0J76)5)*0J71`23)OJ6*)<',I,F_I8UEP\YDR8"ESF7+PF3)@:7/9>* -MEE@I_Y8#(Y,F#9Z639<9ET\CDQ:3)LDB3Y>9(Y,F -M()=2EUB5;2E6EU$HER8GEZI)ER;MEE*7(@*7)O*64I#*6^7>@:7)D"7>BMTE8DI=I=%EHPI=I<>EX\I=I*,XJ6KREOET67OV:AEWMF#Y>U*:67$Y>X*>Z6=)6[*:^7 -M:"2<)D>7+5&<)DN7KB.9%IPFP2*REUZ78P.)EY1FG":,EW%?G"99EV=8NXMK -M([V7'"2[BY:7HF;LE.=FRI>O%KN+9Y=14:J4[F8=9]`CP93Q9M&7Q93U9KT3 -M>3N[BSR7?3O6EP@[WY?.,X>7IA/8E^`K^I1J-.J7;%'DE[B7<%'DE[R7T",R -MEP]G[I>B9IB7>33XE^Y"99<69^:7HF9IE[T3J)?N0D*5'6<$F%-ZUI>H)LJ7 -M299>@40J8M2+N -MEE26/660&SM'F`DOK5HLF&XL19@OF,]1 -M19?L-#F8[B6M6L:78336EX$J[I:5EODT!)B8EOTT#YB;E@$U_)>>E@0U>9CX -MEA,4P -M+,N6-C66F.`VL"83F+`L]I=A)XF869C1*K28.I=%-:V8/I>*`1^8IBP&F-HJ -MMYAGF'`GP9@TF',GP9B4F'8G[I8FE8P;!)BB9]:7?"?*F%>7B@&?F%Y@4IB" -M)]&87I>8&\V8@)A8!*F8$$O^EXTGV)BR);0FL)BXBM:7=37BF`N7J!O;F+PC -MM":%F`(EE)B@)^F8VI?*..F8W9>G)^F8<9B*->F8RYB!0NF8Z)<2,NF8[)YDGF3PH?IEL),-:A9B8-<-:O9AQ1/:7'C:! -MF>(DPUJ/F'%$_I=,*(N9!)=_`S"9@7W6E]%K+6F68 -MG&'+6C:9\41QF"\SXIF^%LLF/)GA1.B7524"FNR7U"@"FJN8PR\"FE*8VR@" -MFO:7WB@"FOJ7X2@"FOZ7:24"F@*8;24"F@:8<27BF6>8[R@AFC28=BPAFI28 -M]BCNEA":99C,8D76ET\I1)H-F%(I?9J4F%4I -M[I9JFE.:;7Y[FHZ9)&+HB_69RDQGFI69"#[HBV68S"[HB_Z9SR[HB]28TB[5 -M)C::?876EW`I@YI(FG,IGII+FOXLH9I.FL8,!)BF1=4F>9H@5-4F@IBM1=4F -MA9@F5-4FAYD\6]4FA9J>?M4FB)IDFH*7-".5D]4FCIHOEI@.IYKCE0$!E)J2 -ME0@/PIIK+'4"DI>\FIB5=@_(FIJ+RIK>F*\V#9B=E\R:?RK*FMZ9^I>DES0C -MVT7*FH*8WD7*FH68553*FH>9"C?*FK::<%O*FHZ9$3?*FHN:[D7*FI69B&+* -MFF68?%O*FOZ9^$7*FM28^T7?6IJ:02_?6CR8TVG?6M*:UVFJE*LW_)=(3=]: -MV9J`E;$W#Y@U-]]:WYK5E+@W!YO.EKLW$YO=+=]:Z)KCE<$W%ILZE\0W')L^ -MEP05!)BX8M]:])J;E3=J#9OOE#IJ*)O7FM,W_)=EET!J#YC*/N-:TII>-^-: -M0)IA-^-:WIED-^-:>9J'+^-:@IB!3>-:A9A$1N-:AYE(1N-:MII+1N-:CIEX -M-^-:BYKL/N-:E9F33>-:99B63>-:_IE;1N-:U)B<3?B+FIJ?3?B+/)@U:OB+ -M-)L1FQ,X[I9+?_B+.ILOED`&/9L:FV1+9YN2E2$X+IOEE"0X9I#/_R+@I@45?R+A9@N7/R+AYE- -M/_R+MIHT7/R+CIGM3?R+BYH(,/R+@IL+FT4G[I:*:OR+B)L1FZHQM9L4F[$C -MNYL7F\<2D9L:FUF6U5\YMYFG!5\YN" -MF'-5\YN%F,R4>1WXF]4B\YNVFI-<\YOP(_F2N.4^4=1G$:<196$:W2<*9MKF5.<+)MNF;PJ3I5+.2Z<494Y`U:<5)7X -M'8.<-)I5.32B9PV(XZ<:)QGE:1KC)RWE*=K -MG)SMF*IKDYP`+8Z<,)ESE06;F)F0G((KCIPVF8&'CIQ,G'V5?#F6G`BP*GF:F<5Y>O.32":7#VS]G/J4$FP` -MG;J<2@9,G'E6!9O,*/&<:YL(FNF:)IV!G!J:)IW5G!V:O"K!E,(#.IQ/.P);CYB,.V<$Y90;$*= -M^9M3;%*=3"-:"E^<')99;%6=$@I:"F6<(I9?;%N="IT)ER^=TI1E;$B=$9M9 -MFF2=E#=:"CR=:YNV+$^=&IL==YMZ;'F=T)K)`U:< -M0VQ>"KR<`EY>"ERV<5Y::;#2<6I:=;)J=[YOJ+)>=G9Q/,*"=H)Q3,*.=^YQV6=0YVKE[PJJI8A -M&>B=RY?R;#2=EY@(&OJ=AIU5+>N=G9@(;?J= -M)I4,;0.>")P0;0F>MIP4;6Z<;E=G"KRRY9$;2Z>_(@7GJ`F=P&?5S*7)CLYG@.).Y[MEC*>'9ZQ6CV>YC(@ -MGH\T2)[M*D*5,SLUGB]"[)1<;5">+2M.E5]M09[F(J258FU,GN8BP91E;5B> -M)3$GC`V7"BN5EFMM7)Y]E6YM5)XR*X>7<6UJGN8B^I1T;6Z>H'(GC""7"BO9 -ME((<$9>XB9GGN.57CMRGI*5A&U]GLF:XQ^`GG>;:#M@GB:>;YL&*TF7 -M;CN)GM>:<3M8GEJ>7#%5G6UNGJJ5^!^8GC2:I&V2GOB6XQYYGF&7ACN> -MGNJ>J2K'GI4+=0J\ -ME\&>/YZTF\&>F)?;;;">'9ZZF\&>()Z]F\&>3I[`*L>>19?".[:>C9[&F[V> -M\Y3(.VZ>7IZSF.MI?V;5B>_I5.(*&>NC,_GL"8[9YH"R0GRIZ[ -M0A>>QICZGMR>T9["0B0G,9[3@B0G59?MGK&>?R=U90H;B"?SYXK;A:?[D(_ -MGO68"I_6GOB8"I\=GON8"I\@GOZ8"I].G@&9[9[BG@29.9]6G@>9.9]:G@J9 -M&RP7G@V9:BSNGJ$@*9]+ENT/\I9%G[J7[0_VEDR?/YX9F4R?UIXQU%6GBR97Y]`GP.?9TI#GP:?P%%#GPF? -M;4I#GW6>1S0'GFTK7)[#2#J,Z)9?GW">^"=UGR2?ZRY\GVN=6CQNGE6873R" -MGWZ>4)E?GQV>4YE?GR">5IE?GTZ>69E%G^*>7)F1GU:>7YF1GUJ>8IG)+!>> -M99G)++.7]"`IGYN6]R"@GYR>;IF=GUZ7_2"CG_R6`"&IGP"7`R&LGP27!B&O -MGTZ>?9FFGW"7#"%NGK.6#R&LGW>7$B&[GUZ>BIFUG[J>&"&XGT&8U`9+E\&? -M!YY/*%R>I)@B(;N?<)Z;F<&?-YXR-LN?SI8K(;N?/YZDF<&?UIZGF<&?'9ZJ -MF<&?()ZMF<&?3IZPF;6?XIZSF>:?5IZVF>:?6IZYF>@J!YZ\F>^?GI^_F?*? -M@IE,(2F?PWPX)VB?55(7GLB9]9^,F=P&;I^SD?V?<9_B-"">T9G_GQ"572'X -MG[>48B$,H.V892$/H$Z:%6]NGL=GC@KZEO^?PI\/,UR>>SP7GC,L'*!:G'(A -M$J!>FG4A%:#2E'@A(Z`WGD$L(*"`GZHO+*#,*HX*:Y_GD1Z@`J"D8!Z@!:!% -M2R">%9T9H$Z>")K_G^*>"YH_H%:>#IH_H%J>$9KH*FR>%)I(H)Z?%YI+H/:? -M&II.H'$D-UL&EU&@G!8W6R*85:#6GB.:5:`=GB::5:`ZH/N??$L7GGPL7)X6 -M:#=;-:!_2T.@.*"'2Q>>Y)91H$N9OB$IGR-H;:!$GNA@99Z3+&6@(:!#FF^@ -M;)Z:+'F@N9W-(7*@))^A+'^@KIA;/6Z>5R4_G@F7;Z#6GA`PA:`=G=HA@J"$ -MGA8PCZ!.GF^=4:#BGAR7F*!6GG6=F*!:GFB:Z"T7GFN:Z"V>GRJ7I*#VGRV7 -MIZ!2H`,$3Y]X?3^>3"E*;&@HYP-(BF?XTN5"C*@P#7%E!,BQZ#%GZ6=OJ`'GER7OJ!LGIV: -MOJ!PGJ":OJ`WGJ.:OJ!WGGHIQ*`7FP@$&*"C1-:>@"G@H#J7"`2WH*M$%YZ& -M*>>@(YY\EZJ@XIY_E_&@5IZ"E_&@6IZ%ER(N[*#*H*MH8@EHH+J28@EKH-R9 -M3"(IG_8U48QXG[:+UIZF*5R>YIE2!TN?MHL@GN2=0BY$G%('XZ#:A%&,M*#I -M1%:>JY<3H1.@KI<=H7"@L9<@H'28REPH^.:'CE35P/:%%,49;#Z'A1&F7.W!` -MH50T1EL6H2%%[)0=/D>A29=%<%B>2":DE2,^*9_9E"<^5:&SEV('8I\&::J4 -M4G!NGB]%1EMAH%(V1EO*H-IA1EMHH#Z:/3Y8H9><03YKH4:7!Q -MH>V8;'!TH4Z:;W!WH4N9:T57C&6A/J%"*I.ADI60<&ZA/I>3<)RA0I5_ -M!PBA97=;C'6@9'Y=H6:;MRZGH:V@^CU;C$JA"UNGH1FA78RGH>J@=W=;C%2@ -M`U1;C%B@9XRGH5NAE9JW<"F?F)JZ<&Z>FD5;C,J@^4ZC[XH5.AW9[81:X*HJ'"?EVAPYL]+Y86K@K9H>%%5J')FP>B.Z'LGKN, -MK@JQH>R:$'%NGN^:$W$IG_*:"`&ZH:]B3*'#F$XO3I4(`<>?YG>N"F&@_IH( -M`B88"\ZHA.BFJ$0*UR>"G@ZHK>AKV*@H2R?9DVP"ENA:4VP"B.B^8Q3 -MH36?5S>P"LJ@,IM9<6Z>-9M<<2F?.)M9/URB^)9Z%>G_,^8`E;H5F;@'%Z -MHH6A1$Q%HHZA[">+HN>A=)_!+SNA/YG!+YB7Z15WHF67 -M[!5WHD6A29G(+UVA@"N.HM":)02QH:8W(:**GVIQGJ)*H@ID.,,&4(Q;'HJV=*@2QH:V;*@2TH2=)U5> -M6ZRB)UR+H:PRVJ*.H9&9#C!6H6[ZBY93M<<2B -MF)5)%M"B^:'"=:AFV-=H>R<5S"%H?"<9#`GHZZA"YPO<@BCCJ$?H&TP)Z.I -MHOIX)Z/=HOQ_P0I;H1J<0'(BHT6A+J!7,*"A*#-(I5\S'+#HYV8SW+)H_LF;EO[GT]D;ELRH+M' -MJ:.DHW.>.Q?,HS>ATZ`,3X&,K:,^H=F@2%V!C+.CJWF!C+:CKH"!C(JCFFN! -MC(VC4&V!C,"CH94%"%:C4Z'PH$16@8QJHZJ5)P1MHZV5_W)3H["5`G/QHV:B -MFBEVH[:5%@C_HVRADI>W,6^AHRD"I'*A"Z$(I-*7%',%I'BA$J'-AUVAI)<. -MI'^AZIT.I(*A'*%?.86A'Z%?.8BA(J%S5L\*]J..H2BA#J16H?@]"Z07FS]! -M$:3%G35S+J28HC6A#J1IESMS_*.8E3YS$:1%ET%S-Z1JF$1S/:2`FT=S4Z/! -ME$IS0Z2SETUS5J/[E5!S2:0TFE-S1J1>EU9S3Z2,F5ES4J1K"]$*;:,*EE]S -M3*1$G&)S4J0+EV5S7J1.E6AS7J2DE6MS7J1$I),M=J,FM)SOJ3Z -ME-5SOJ1ZI"$GQ*1KG=MSOJ2`I-^AHZ07G`)"QZ2&I.6AUJ0^E^=SOJ1"E>IS -MM:0[I&`XT*2R*]P*;:/7G6<$SZ-NI-2>L'K<"J2CFY9G!*>CGI;_854)6HQ">2@3SI,Z6FP+) -ME[E[Y2;`@JE -MH96;`@:7X3*JE)L"(ICU,LND^)CU,GJD^YCU,MF4FP*\E_4R@*0!F?4R@Z0$ -MF?4RAJ0'F?DR0*4*F?PR5Z7HEO\R[)14!.V6`S-7I?*6!C-7I?:6_S)$I!F9 -M#3-7I?Z6_S)NI!^9%3-7I3ZE)9=4!$*E_&6+6PV7_S)ZI"R9(C-7I4RE0'N+ -M6QF7_S*#I(JB_S*&I(VB_S(UI'2?-#-`I3^9-S-=I7N?.C.+I6*E5&V+I66E -MZCIN"?J65C/+I%"95C-ZI%.95C-*I5:95C.`I%F95C.#I%R95C.&I%^95C.( -MI7VE<8*+I8"E8#.+I567:C-BI&N9:C-EI&Z9:C-$I'&9;C-`I729<3.^I9*E -MBC-QI'J9:C-TI'V9:C/+I("9:C-ZI#\H>`&8*[ZE<:6*,X"DBIEJ,X.DX**. -M,[ZE2Y=J,S6DRI]J,^"DF)F7,UVEFYF:,[ZE()>7,V6DH9FA,T"EI)FR,\ND -MIYFR,WJDJIFR,TJEK9FR,X"DL)FR,X.DLYFR,X:DMIFR,S6DN9FR,^"DO)G! -M,UVEOYG!,V*DPIG(,^REK:6B9D2DR)G!,YBDRYG!,VZDSIG!,W&DT9G9,T"E -MU)G<,QRF7Z7@*WJD[)SB,QRFE:7.,X"DX9GH,QRF:Z7@*X:D'Z#N,QRFTJ6B -M9N"D.BS/I8Y17:4]+#:FB6:2I"N@^C,J3#H+*F -M2J5.E[*F@*2?G;*F@Z2BG;*FAJ2EG;*F-:1J2KEPNG2J6NEPNG -M@*2QEPNG@Z0EH0NGAJ0HH0NG-:0JI`NGX*0OH>ZF.Z0"GCFG8J0UH3FGI)5( -M=AUG+C6JE$QV0J<>;_J44'9&IP:21*>FD6<#$W9,IR:F,9E;=DJGMUE,I_&F -M-YFVC/2F(79,IV6F3RVVC/NF?TOLE*5$$9=.-4Z5<794IVR@MHQ`IL=2MHP' -MIW]+Q91Z=FBG5R65EGUV7@W9DI^A@2*<+F$XURY:*=G:G -M:YV-=H2G,*"0=H>GQ9V3=HJG99>6=HJG:9>9=HJG0I6<=H>G19?C1'VG49)F -MI[HMD*:%-4"GDJ&4-42GKC20II$U0P68H:8U"*+V1)FG4HM$I]XFI*?XEK1V -M:*>RH+=VLJ<^G+IVM:>7G`A%N*?+E\!VJZ?`-6*G;YN\-6:G^2:OI_F;RG:^ -MI\B@SG;(IU2F+PU)I4C1ZG.)V -MNZ?/GC%%U:>(I]*ATC5$IX@JW*<=G(F`(VYJ=@I_V@546^IP"A644!J#2:S`)`I@:A8$4$J/R6 -MS`*HIM5$CJ>ZFPTV!)=I10JHO*?@GA`V8J?#FQ`V9J?&FQ`V0*?)FQ`VP91X -M112HNIZ+!%>G_YE$I]*;&38HJ&6F+:$HJ/ZGTI18"".H@J?&F!`VV92+!`>H -M+Y:+!&ZG'2:8EY)%(ZB.IPR?$#:1I]>8$#:4IX4GD*9()F*G])L^-D2GX9A! -M-DVH4:>7%$,%Z)A--E.7T0(FJ#":4ZCXIW5,3:AEIF.AT0)@IV:AT0+.I[Y: -M3:B@IB=^3:A`ID%%4ZANIX0F2J@-J&8V4Z@.IS2%0P58I>]A=:A;I2EI=:@@ -MILU:=*<3F7,VTZ<6F7HV1*=HI?YA=:A8J-64&PM;J*E,A*A>J#FH)9ES-CVH -MVR>0IG":A*AGJ'1%=:AJJ)B5H7>^ITV,A*APJ.^4&PMSJ&!P1*>)I0A;O5MY -MJ&"3O5M\J-%,@J=^G]\VNI=?"%&HCYI?")BENZ&]6R:HE9J_=TZG'%N1IZ&E -MB'>]6V"GQZ%?"&2H@X6EJ)>HS:$A1KZGJ)K2=\NHS*=HF>,V=*>VI4EBP5MY -MIYM^P5NIJ#\^2*>_I;E%P5OKI[V:(`NSJ#FHR*5+6\%;N:B2E2`+BZAA8L%; -M9:8/342GU:5$5,%;Q:BG:>^HR*BAE2`+0*8]J.&EH")N$1B"IUJ<1IO-^$*G^J(FH%Z8\ -MHCMX**F(IQVF_W!#!=>9.S?IIR.F8$TVJ5&H(YLH"Q2I$'ABIQN@.S?VIR^F -MG50VJ66FCJH.)LH"T"F.YLH"VZG/ILH"PVH09MG -M>+ZG1)MJ>%ZIBIAM>&&I]9R:%`NI39MS>&2I3IJ:%%&H4YN:%$"I07A$IU^F -MXEO9C(NH7)N:%$FI@)6:%&"G8IN(>&BG.HW9C%*ISI:.>&JIF`O9C%BIXY64 -M>(6ICJ=ZIG9&W(P$J5I_W(S9J$Z-1*>#IH!&W(SKIPE,FPH$9::/F[5XI*F`F`H$Q:B5F[IXJJFYIY2@Z3=BJ:6FH4:5 -MJ0VHH9O%>+"I:ZFNIAI5T5N3J:J;>`B[J5R=T7C#J=.GNJ:0AD2GO::?<=%; -MH:F)J,.F?Y316Z>I.:C)IL9&T5NMJ>BHSZ8'3M%;0*;/1M%;;J?.FW8(N*FA -MJ-NFN'_BC)"IE*?AI@"C\P(+J=V;`7EHIZ*4!'F^IZ:4\P)PJ4`PXHPFJ.F; -M\P*+J+"4\P)EIC%.XHQ@I_*;%'GSJ429%WD%JL:GA9=,.%:='7D(JJV=('D. -MJL2ICY<+J@.:)GD1JGNG%*>D8WP7[:F)J!JG%$=\%U&H^7]\%_:IB:DCI^*4 -M.WD1JI&G*:52G+YP)`ZBF_90) -M`W.H`)6U1ZNG`Y59>3FJI2B8EUQY1:H^G%]Y2:J7G&)Y3*K+EV5Y0JKF*.R4 -M:'E2JD29:WE/JG>7;GE9JL&4<7E9JL64='E9JI66=WE9JB:5>GE6JDB8?7E9 -MJOJ4@'EHJKJ<@WE9JMF4AGE9JC*7B7E9JD>J@*=1@-U;AJ9!:]U;4:?D5=U; -M0*E':]U;5Z=*:]U;6Z@#7=U;,J:N%-U;^Z9,CJJ4L01DJ*6CL01GJ*BCW5LV -MJHVCD*I\G@XY"Y>^>9ZJ[9C!>4*J -M<)7$>:ZJ.IC'>;&JJIS*>;2JOI[->:NJS:/0>;JJ7IK3>;VJ;*I[FZBJRY91 -M!)6JB95#2+>JAJG>>;VJ0I6`!-FHLW*0JN>G -M#CE)E^]YMZKSE/)Y0JJDE?5YXJJSE_AYY:J"F?MY.:JME6I(Z*JG)=$'QIYJ -M.8R9@`22JK:5NNJ -MLJH6J$I/](RLJ%,Y8ZH5)GH(JV.<*7H9JZZ8+'H< -MJ\JJP)CRJL6=,P;UJI*5-7H?J].JR9@BJ]:J>2<"JYN5/7KNJMVJ0:CSE0X# -MI*I=JD>HQCE3E[I(0JK[E0X#?*K^E<%(/*OXE@X#@JH$EE5Z0JOJG`X#B*H* -MEEMZ2*M0JO68QCFIJD6EMCE.E0X#E:H6EF9Z3JM+F6EZ6JM@JE*E!D&0JE6E -M)XC1!W:H*HB0J@V94:MLJA"94:O$JG^H+)9^>EJK=:J%J!M!9ZN%JC66AWI: -MJ].J(IE1J]:JD*C[762KDJJ`G9-Z.:J#G99Z0JI@JDA,H:I(E@])AZM7EQ)) -MC:LNF:!ZD*OOJJ-ZDZO[GJ9ZEJO0JJ^HT4_3JDF9&#H0E60(@JI@EF0(A:IC -MEK1ZDZM:JK^HN$A=JJ2E$CI@JJ>E$CICJJJE=HCP6S:J=I_&>JBK;*K0J,E( -M\%L_JEXL*@NDJE68TGHYJHAL*@L-J\B=*@M\JHR/*@M_JLZ=64F3JT67X7K$ -MJ^^4Y'K0J^.JV:)!.I"J\*@Z5]JKDJJ;ENYZ0JJ>EO%ZX:M#J_NHJ8\J"SRJ -MIY;*!#^JJI8?`Z2JK9;_>N2K]9P?`PVKLY8?`WRJMI8)>_*K5IT->_NKNIX1 -M>SFJOY85>P&L6IP?`XNJI)@<>_ZK;*HBJ:!ET0<+IM=L#JPVJA:>#JS^JMR( -M#JSIJR:K+ZGB;`6-[ZN8E=($V*KHB`6-]:O4JSJI;E"]?G`!)ZP*`**HBP$K -MK`H`-'\$`2^L+JQB`BBL,ZPJK)(%+P(=>58"YW)Y`3NL"@`?0@T"/ZP*`+L! -M3B%#K%D#1:P[`$6L/JR\#2\"N@'7"FI.+P)/K#ZL.@@[`#VE#@&Z`:P,5ZST -M`?9$D`);K`H`A'H5`E^L7JQ"8N@$01.+#8P,9JS,`7-,,*S6!/@!"!$S"&ZL -M]`&(?[P!".W@!`G8(BP-YK$0$X4=@K%IF7JS-H/VJ)@+2!D<*A*PB -M`E5.!`&(K$*LNP%0K(RL"@`%"#RLB@T!`F<$P`24K`\":G@LK*TQ7JSV-SL` -M(4A$!"1,(`*@K$*LY%U(K.1=/JQW6_T*2!0[JD,!JZPNK)T'H:ROK"ZL14\[ -M`$P3%0LC114"MZPNK))IM*R2:2ZL>0V\`8=,S`'^#"L)PZSX`0!&'@''K"JL -M-JD[`-IX^`'D>1(!SZQ"K!$!)`*4?R8"(W.0`M>L/JPN::9!5JS)`R0"X4$F -M`C>H+*SS`WP!5ZD$`N:LFZQF#R%(=`$/21X![:PNK`8!+P+22E8"BPT_`_6L -M,0.+#2,K^:Q9`Z--P*Q474*L['G,@`$"U0@W#02MS`$V"X@2"*W.K`@1T*P, -MK5ZLE4^=K)5/7JQZC6H-[P$=?14"%ZU"K!QMA`A\`=50TK.LG -M/JRF352LIDT^K)87!`M'!=H$!@LMK70![DHD`C&MFZQ\$,IY`0+Q>@0!.*TR -MK%4.61.,(\"`'@$_K26M_!Y=!"<7G0=\$$:M>*RP@C]X&`'O>`0!3:TJK(PM -M)GG,`6H-$QU4K5.M.(_B!#L814]#`5NM/JQ^G52L?IWPK!LA\DI$!)-S$@%F -MK=JL'`60TK`.' -M*JQT;,RL=&QUK-D%=ZPAK902?7[6K#=>YW(7`J8!>P6-K0X!@41Y`9&M@*PL -M&6I(#@%*J^T!F*T^K#D[[D&7K6!_G:Q@?X^L[V)]`J4+!`OY#::M%P+E0"`" -MJJTJK&("$@$*!!X%77=P`;*M$ZT_"%2MDZS$(52LQ"$EK;`8701R%*!Z+P+` -MK2ZL&Z*TK!NB(:U@"U`3F1:+>$ZM/58NK,.38']T`::ILZT'67^ME!(M18.L -MN&R!2Y>L]@/M`55%[*QS=)VLP7SK0X!?0TW#?>M::SE)B.M%1=G3G.L!#=>K;$%S',/`C5" -M>0$%KDJLLQ2Z`>X5_@R-!0RN60-M=PT"$*Y0K=:MG90/K?4?]*OX`8*`(`(: -MKD*L`@J)K!ZNHZQ%$3@+>1,X"W\.):[GK4(>8*TP"QL+[A8LKC$#?WC(K!5) -MSJU\$/@&#PO^#$D--Z[EK+-HWT31K:$W/@B/`3)W3JTH!<:LHP_,K*,/7JPO -M!)VL+P1>K"H$8*Q-K@^M*PFD20"M -MK`S/@'&LJ7Q(K*E\HJT;(2-S?*QV@9Q))@)D3K.N4"-;3W`!RJXJK*L".*S. -MKN.MS!$%"#$#>$$$`=6NF:Y`'XVMYZT@<%2L('`JK+H!N*S@KH.MDJTK44BN -M?PZM>8JN''>=K!QWPZU+)M(&;1^$?Q(!\:Y"K%Z32*Q>DRJL[ZW,K.^M0JS> -M=K>N$1W10>FM"AXJK,!ZS*S`>@.OJP5?"(87U'@XK%>,-JQ.(1%Y;*U7H8)( -MJ:Y!I>&M\0I=24,!&*\3K>JLNXM"K/D0U*P?K]JLJ!"502("`44D`B:O_*Y6 -M#:F`]`%004,!+:^GK`4,_0K=%^*I3JTY%VVL+)*TK"R2*:T;(00+3!S+1"RL -M;QLJK"U+S*PM2Y2M[JP/(?RNS!'`#403G*0!KP\8)D*\`5"O/JQ*=]VN&`L; -M"Q8&5Z],K3"KLJCAK%`3LZU>KZVM31+">`\"@DB0`F6O7JP@1.&ML`;H!,X$ -M;*\7`@RMP*S>?KZL;04($4079T[RKOLV_*ZN!KV`N*V,#/9!S`$7>4ZMB05G -MKHIP5*R*<$BN-`<52.RL!'(S!GP3B7TPK*:M_*[B#<`-2@NW@4"M&P<.`2.N -M'ZT]"U\(11&=KY"M]HUV"/\61TLHK(,-7JSKA-($_Q9M>YFMZ(5>K-%_G:S1 -M?YNL;`A#2.RL5AITKG\3-Q;L"KFO]`$+".T!O:\NK,)M_GS4KAG&`':!!X2TJ_4KA("0*S6K\JLEP-YK.&L;*GZ -MKH(+^`;.!N"OGZS2!A(!D4Q&K#JHMZ[,"L],0P'KKSZLD@4$`OX,&!>/0>T! -M\Z]2K&P(2Z5T`;ZMUJ[Y$,:LLJCZK@87JRLJ>NN=0GW -MJ]"LC`@->R0"#K`/K1<-CDEDKQR!$:U$%M*`D`(8L*ZO<:T_B&*L?R7H!-,6 -MBPV%`2*P`0)]?BBL+B_2K!T4>']QK+^72*R_EQZO2"(9@0>M^`;RKC2PBZRW -M`R6!<:RQC38+@@LT0>6MH1D^K*L"::Y"L-JL7B"/02("NJ0!KQ,%Y$&+`4RP -MFZW5"OY!5@)!I7"NN@%(L)5$EZZ!!U0$E1!:L"ROT@;TKUZP):U9"UT$DQ9& -MK4VP(W=3KST51JWAK(\(+*QLL"JLM3731%JL?P,GKW.P;["H!?9$>*PAIIYD56`N^M$:X($9>L_8S=>)"MUUWS`N`7+'F2K11A2*X] -M%9AYBJXM."1(?*R:S$##7L@`J^P#ZT^&0:L(@(&K`^P&8&GKTP*/GOLK/$!P:V] -ML%ZLP(?6!`,C:@VN!<2P?`'B!/\4R+"IKE2/G:Q4CV*LRPELKR6PM9322@\" -M1TNAK)@.+JQU:VA+;Z_:L-T=PZV9!\Q+]JV@?YNP,*TQ@;2L,8%[K8P7@'[T -MK#2&?:TB%-A^!`+PL"ZLCUKA?O0!8'^0`O>P*;#+KB4:O8!BKEQ'`*U8+95/ -M,[#.!L<-T`:91!&N_PZI%:@&W!4+L=FP)@9]#=H7Y'+8K%\JVJPH#J9!!*ZU -M-95!O*\7&2-S^:]Q&X]!&+'N"9Q!^:]<;+JDW:R($LQS9ZY5L%2L5;!2K.,* -MFP)5"$&EZ:WBKIL"K@8UL9.L_*\GK?0*700@#CRQ;JX_@%>L?`%-K$VP;8`^ -MK`(*!JY'L9FNMP.F`8(#\:\&KL -ML41RL,(,RT3AK&,T>*=RL$$9VT1AL08+TT31K9L#DJUKL7^MY0]%".6LQR&% -MKO\$BP2.#W6Q#ZY/`I*M>;'?KN8*5GH>NS@1_>.ZMKH?+K40$&GFLK'<.4*T_"(ZPP81]0$\`(";*?K%I4Z["&K3*M -M\@2#K!Y4(ZV2!7NM)QHW%N^P]%69?FVL]+!])LZM'13@KRRPRPF$?P.M@P<5 -M`EY.%P*+3AFPU!TIK_*N(49ZK_ZPLP88L$BLB[&/3URM`;LO3`+]"L(!I@'<`7D)GK+-`2(;W@$["*.RI@$.`=P)=+*MK]P)+P*L -MLG:R/PC<"0$"W`D$`K.RK[*"LJ`XK[*3L@,8W`F6L@88W`F9LBTYK[)P`=P) -M]`'<"14"QK+-`0D(Q0%V`OX,G;*((U@:SK+_`6R%0'] -MLEH:![,`LVX(X0'HLM0!"[-Q!PBS_0H1LPNSL`,2L]@'W[+ELIVR`[.@L@NS -MX0,7LQ^S"[/J`Q>S([,+L[D!'+,GL_6R.1?WLOT*]`(9LU@:]++9LO2RR;+Y -MLAT"'$0%LU@:`K,VL[P".+,G1"RSM@8]L\@%#;-8&A2S];+*`C^SX`$OL_>F -M/[,6LP"SVK(2LT^S3K,ALSNS4[/EL@^S4P*IK,$!Y;+YLOH!]K+>`?P!GJZL -M`5VS#!M?L\FR"K-=LT"S9;//D[P!:[-VLHT'PPET`<,)K;*B06ZS>[*\06ZS -MM+)_AFZSM[)P",,)D[)5",,)EK(*"<,)P+)=%,,)P[*.AFZSQ[*2AFZS!`'# -M"?@!PPE#`9&S;K,2`<,)60/#"2`"F+-NLR0"PPDF`L,);+.DAG:R!@O5DW&S -MJH;5DWFRB`MVLP\+U9-YLQ(+U9.WLA4+U9.3LA@+U9.6LHL4U9/`LHX4U9.( -MLR(+U9.+LR4+U9..LY!&HK.2L^M&HK.5LPQ'HK.9LS5'HK.P!G+LSX6 -MP!G.LV`3P!F@LT06QA&JLF03QA%SLV<3QA%VLVH3QA%YLVT3QA&WLG`3QA&3 -MLG,3QA&6LG83QA'`LGD3QA&(LWP3QA&+LW\3QA'"LX(3QA'%LS`+QA'(LS,+ -MQA'+LW`6QA'.LSH+QA&@LST+R1&JLN\!R1%SLU\AR1%VLT<+R1%YLTH+R1&W -MLH86R1&3LE$+R1&6LE0+R1'`LI`6R1&(LY,6R1&+LY86R1'"LYD6R1'%LYP6 -MR1'(LV@+R1'+LVL+R1'.LZ46R1&@LZ@6R1FJLG4+R1ESLZ\6TQ%YLQ@7TQ&W -MLAL7TQ&3LD0)TQ&6LDL'TQ'`LLH(TQ&(LR<7TQ&+LRH7TQ'"LRT7TQ'%LS`7 -MTQ'(LS,7TQ'+LS87TQ'.LQ`?TQ&@LST7[&*JLJD&[&)SLT07[&)VL[`&[&)Y -ML[,&[&*WLDT7[&*3LE`7[&*6LE,7[&+`LE87[&*(LUD7[&*+LUP7[&+"LU\7 -M[&+%LS@?[&+(LT`B[&++LQ6R[&+.LT(?[&*@LT4?!A*JLD\'!A)SLZ8%!A)V -MLT\?!A)YLX87!A*WLE4?!A*3LE@?!A*6LEL?!A+`LEX?!A*(LV$?!A*+LV`' -M!A+"LV;)^B-T1LK*!B-T1@+*$B-T1D;*'B-T1A[**B-T1,0/=$9FR8E5M>17B+5$M148WQE'M?X3WQE* -MM6$*WQE-M1$=WQE0M2$8XADAM6H*XAF&M6X*XAE[LG,C([5M!N(9++7E#^(9 -M+[5I#.(9,K4V&.(9E[5P#.(9FK4=%.(9/+4G&N(9H+5[#.(9D+.S`42UT`;B -M&4>U@`CB&4JU*Q3B&4VU+A3B&5"U,13E&2&U8@P2Y1F:M:P,Y1D\M;`,Y1F@M3(0Y1G4 -MM;<,Y1E$!.491[7)"N492K7,"N493;6!&.494+6$&/XO(;5(%/XOAK77"OXO -MNK5.%/XOC+7>"OXO7[5]LQL'8K6`LST)HK6#LYBO*+::M>P*_B\\M6$0_B^@ -MM64$_B_4M8H@_B\(MAL'1[7Z"OXO2K5O%/XO3;5R%/XO4+5U%`"4(;4("P"4 -MAK4,"P"4NK6KLZJ)`)0LM1,-`)0OM1<-`)0RM8P0`)27M1T+`)2:M940`)0\ -MM94$`)2@M;@@`)34M5`D`)0XME4D`)27L_)XHK6A%`"43;6D%`"44+72L[Y8 -MHK75LYYY=K8FMMAI9 -MHK4OM$9_T+:DMA$%(;4UM"19HK4XM*^O&PH[M`:`V;8LM;@-W+8OM3`>W+8R -MM?0DW+:7M441W+::M7@HW+8\MLU^"V;;4MNH$&PIEM,>"HK5HM-J"";(-!K7M6<>!K>:M5D+!K<\M?D-!K>@M6`+!K?4M6,+!KP1$90OM6$.$90RM>X6$927M6H.$92:M0T%$90\M7$.$92@M2L) -M$934M<`($90XMAP%$91KM@02$93.MG\.$90!M_44$934MC0'_QE5M3`%_QDF -MM30%_QDIM3@%_QDLM94._QDOM9D._QDRM1X2_QF7M2$2_QF:M?P>_QD\M2<2 -M_QF@M=8'_QG4M;$._QDXMI,)_QEKM@X;_QG.MNPE_QD!M\`._QG4MJP"&PK" -MM.R.HK7%M`B/R;7M7L%QK>:M3(B -MQK<\M>(.QK>@M>8.QK?4M>H.QK -MMJ%:"AJ>LZ1:"AHDN%.U':_&!0T&5[@JN%FUK5IRLJPFE;6L)EVXD0%7N#.X -MRQ-7N#:X-CM7N#FXPQ)7N#RX)@97N#^X!0Q7N$*XU1-7N$6XBP-7N$BXC@]7 -MN$NX$R-7N$ZXEP-7N%&XVB97N"2X'PPBE">X(PPBE"JXL++XBUVX*@PBE#"X -M"14BE#.X`1@BE#:X#A4BE#FX008BE#RXMP,BE#^XGK6WG(ZXCK/KG(ZXDK," -M6XZXE;-<"B*4F;->"HZXG+-E"HZX;+/8G5VXU`/&!;6U)XQ?N+BU*HRWN"VX -MO;5U"K6X@K(D)[6XA;(D6[6XB;*`"K>XF;(ZC+6XP[*'"K>XQ[(X)[6XI+A$ -M&+>XI[C7M4B,NKA+N$<*M[A.N&^STPHQ8ZVR>EM=N-0,,6,MN-@,,6,PN-P, -M,6,SN.,*,6,VN.8*,6,YN)D',6,\N"VVBP(_N#"VHR?DN*2X]`HQ8Z>X]PHQ -M8ZJX.[:+`JVX/K:B6S%C4;AO$#%C)+BCL[:,7;A^!#1C*KA\$#1C+;B&!#1C -M,+A1MD,%,[A4ME.H$+G(N+>SS8PT8SRX7;;!6Q"YT;C`L\NL-&-%N&:VV8P0 -MN:JXGA0T8ZVX;K;BC%^X<;;76S1C)+@[#3X]K,< -M*$JY2[BXY!`SE"JXJ[9-!2VXKK8AC5VX -ML;9-!3.XM+8HC7*YR+@7M"^-7[@:M$T%SK@=M$T%T;@@M"E<,Y1%N,:V305( -MN,FV305+N,RV,EQRN;"X+[1&C7RY)+A-%CXP+;BU#3XP,+CAMI0&,[CDMEB- -M7;CGMDYY)+@%MVI<7;C9#3F4*KC=#3F4+;@.MW-5Q?N'2T -MB8W+N3FX&K>K*+ZYSKA]M)*-.91"N".WMRB^N:>XAK2.7,NY2[@LMY%X.+>HC5VX.[>KC>VYM++7*.VYPKB""T4PQ;@2"D4P -MR+B^%D4PR[CA!D4PSKC$%D4PT;C'%D4PI+B5"T4PI[B8"T4PJKB;"T4PK;C3 -M%D4PL+@O"44PL[BE"\8%9;?(7%VX:+?+7!JZ>[+.7!JZ\;FS`1JZPKC_!!>Z -MQ;CL%A>ZR+CP%A>ZR[CS%E!C=+)@CEVX^+=973*Z'KKXM&J.4&,PN`&X5JY0 -M8\6X`;5RCE!C.;@*N&M=,KK.N`JU<5U?N`VU?8Y08T6X%KAW73*ZJK@6M;A= -M/A)QL[M=/A)YLKY=/A*RLALJ/A*`LL1=/A*1LM"./A*'LLI=/A(UM;JTLHT)>;J"LF4, -M;KK#M3*/@;J)LBY>@;J9LC%>@;K#LC1>@;K'LJ$J@;J.LZ4J@;J2LSQ>@;J5 -MLZPJ@;J9LTB/@;J;KI,"C$2YK6DNJVRSK"DNGNR6(^BNGRZ -MJPJDNG^Z1""DNHBZ[A*DNHNZO`JDNHZZ1!2DNI&ZPPJDNI2Z>!BDNI>Z"[9Q -M7J2ZGK9T7FRZ$;9W7J2ZI+9Z7F)C5;K5"F)C6+KEN(!>;KKKN`0KU;J%L@@K -MU;J%NH.SEH]B8VJZ+;;&`L6RQ@*.NO$*8F.1NOZXH8]LN@&YQ@*7NCNV)RMB -M8\:ZL!AB8YZSK8_KNLRZH[,T*VZZ$;FL7ONZJKJKLW4%?+JNL[R/,1*QL[^/ -M!;MDNE>VOU[[NHNZO;-U!8ZZP+-4*P6[D+/1CVRZVAAG8W2RWUYNNCZYR@)8 -MNGNV00T;NW^ZX;/SCVRZY[/*`HBZZK/*`HNZ[;/]CV=C<;J3MOY>&[N4NO:S -M9@TENY>SR@*:NORS"U\EN_6Z<0UG8\RZ9[FI*VZZ:KF*#5BZJ[:2K$.[?+H. -MM""0;+H1M(H-V;H4M+TK3;MGNKJVP2M#NXNZ';3)*TV[<;K#MHH-%+O&MHH- -M"+:=#4V[-[O,MCM?0[N=NB^TWBM-N\RZJ0UM8U6ZK0UM8UBZE;FQ#6ZZF+E/ -MD':[?[I!M%:0;+I$M%J0?;MGNNJV"0AJNNVV"0CCNO"VRPUVNY&Z4[0)")2Z -M5K0)")>Z6;1L7WV[QKK_M@D(];I7(6UCS+H%M^$-5;J_N>$-6+K"N>$-6[H. -MM^$-7KH1MRT\`ULNGJTX0V+NGVTX0V.NH"TX0V1NH.T -MX0V4NH:TX0V7NHFTX0V:NHRTY*VQN_6Z,K=/+&ZZ-;>)!56Z.+>LD,J[JKIZ -M!G5C?+H&`G5C?[KUN8D%V;KXN8D%A;K[N8D%B+K^N8D%B[H!NHD%CKH$NH.O -M;+H'NHD%E+H*NHD%E[H-ND(.Z;O&NE^WB07UNF*W@RQNNF6WARSYNZ>ZB"-Y -M8ZJZC"-Y8WRZ(KIY8W^Z);K@`MFZ*+K@`H6Z*[K@`HBZ+KK@`HNZ]A9Y8XZZ -M$P5Y8Y&Z=0EY8Y2Z_Q9Y8Y>Z'@5Y8YJZ!1=Y8YVZ"!=Y8Z"Z"Q=^,!F[-@=^ -M,*>Z.@=^,*JZ%1=^,'RZF[22!7^ZGK22!=FZH;22!86ZI+22!8BZI[22!8NZ -MJK2I#FRZK;2M#D6\%+NVMY(%8KNYMY4);KJ\MYD)?C"=NKRTD@6@NK^TRPX9 -MN\*TRPZGNL6TRPZJNLBTRPY\NLNTRPY_NLZTRP[9NM&TRPZ%NM2TRPZ(NM>T -MRPZ+NMJTRPZ.NMVTRPZ1NN"TRPZ4NN.TRPZ7NN:TRPZ:NNFT8&!LNNRTRPZ@ -MNN^TFP49N_*T:F!LNO6TFP6JNOBT<6",O%ZZ`;AU8&ZZ!+B;!62Z![B;!6>Z -M"KB;!6JZ#;B;!>.Z$+B;!7&Z$[B;!12[%KB;!6*[&;B;!9>S7RV%8WFR8BV% -M8[*RDQ>%8X"REA>%8Y&R;2V%8X>R<"V%8S6U2V%8S^U -M?"V%8Y"S?RV%8PBV5`^%8ZZ\ABV%8YZVB2V%8YZSC"V%8Z2VTY&+,'&SUY&+ -M,+&\6;7'%XLPM++*%W*RXV"5M>-@Y[QEN'L/Z[R)LM(7Z[R9LNU@Z[S#LO%@ -MZ[S'LK$MZ[R.L[4MZ[R2L_U@Z[R5L^87BS"9L^D7BS"\;`IU$KBU1V%`O;2\O;42+CZ]&;TD'4"]'+TJ"D"][[S?$D"] -M\KP[&$"]];P?%$"]^+PB%$"]^[S5N&*2Z;S7M30N0+VNO-RX2Q@^O0>]X+5O -M85V]V[RCNE88=1+HM5D8Y[SKM:,);[WEO*ZZ_P(9O;&Z@Y+IO.(0;+WOO#L4 -M;+WRO+2Z;1AYO<:\`+9P&&^]^[R]NF4N>;W/O(<;;+VNO%X@;+W5O,(,;+W8 -MO#P$;+W;O&^SAQCGO-"ZJ)*:O1.]';9+$.F\(+:%+I9CNKSNN)48FKWOO(.S -MG!BAO<.\+;:>&)J]^+SFNL62EF/,O#:V91":O0&].[:M&)9CU;SSNM*2FKT* -MO42VMACIO$>VV&&<,+&\%+F^&.>\%[GBDLN]&;VQL\88Q+V]O%>VR1C+O?*\ -MNK.8$/6\O;/*+IPPR;QCMM48R[W^O!>[F!`!O3&YF!`$O6ZVK!#$O=B\-PV< -M,-N\.[GI&.>\/KGL&(B4$[W;LQ.3Z;S>L]()^;VZO(2V\B[RO>^\Y[,:8HB4 -MP[R-MO\8\KWXO/"S(F*(E,R\EK8(&?*]`;WYLRMBB)35O!$OB)38O#Z[%!GG -MO&>YY`D;OA"]"+0=&:,PM+RNMD.3&[X9O1&T0F*C,+V\M[;^$!N^\KP:M#(O -MHS#&O,"V,AD;OON\([0X&:,PS[S)MC\O&[X$O2RT;[+IO"^T9)-"OMN\;KM( -M&>>\<;M0+TF^$[T[M&MB=1(^M&YB4+ZZO.2V5AE)ON^\1[1<&>F\2K1Z8E"^ -MQKSPMF(92;[[O%.T:!E0OL^\^;9K&4F^!+U!GG -MO+^Y>QEU$L*Y?AEUON6\;K2/+WB^NKP4MZ%B=;[OO'>TJ9-XOL.\';<1`\:\ -M(+>M8G6^^[R#M+23Z;R&M+9BDKZNO"RW6K%XO@>]C[3`DWB^V[PUMZD9Y[PX -MM[LOH;X3O=*[S)/IO-6[SY.HOKJ\1+?#":&^[[S[N:@)K3##O$VWP!FAOOB\ -M!+K)$:B^S+Q6M\D9H;X!O0VZSQFM,-6\7[?L8N>\:[??&<>^Y;P$O/N3=1(E -MNOXOZ;PHN@"4T;[`O'JW!3#'OON\&;P38\Z^S[R)MQ&4Q[X$O2*\QK?1OMB\ -MDK<>8^>\F[M"N4[[Z]O*>W-&/HOO*\I[0YE.F\L+0\ -ME.^^S[RYMQ>ZY[S%MU-C`;\0O<6T3Y2=E+2\SK=YN@&_&;W.M%>4G92]O->W -M!;L!O_6\VK1BE)V4R;SCMW%C`;_^O..T>6/IO.:T?&.=E-6\[[=_8P\!2P/O -M91@F&@(GO\8(U&7$)BN_%6VA;7`D,+_NF$H*N":Q"E@$*`HWOUT*6`2>)3>_ -M9`H]OS:_930S!4&_1+^))#690+]=!$*_1[^JHD2_2K]&OQ<*N";."D6_-[]+ -MO]`*5+_%)#N92;\^OUF_^1M.OUR_3+]F)+0F8+]1OS!`/+]/OU6_1+]J)&._ -M2[]EO\\)1+\7!U"_0+]QOSN_<+]%"C^_=K]MOSR_=+]=OUTDRR8O"FF_-9E[ -MOW>_?;\`"X,S;;]+OV8*^2N(OT:_4[]\OTR_IQ1YOU"_5K]SOX2_D+_0"CBA -M1EM!"SRA1EMY"T9;V0H-/J4*II%"H:*_K0H5/J*_L0H9/J*_M`H2$D9;N`IN -M!Z*_NPJ3`J`*O@HG/J*_P@H#`:*_Q0HO/J*_R`J!!:`*RPIX!Z*_``M]!Z*_ -MS@H]/J4*T2)7C)N_I"97C)Z__(1B>"A@GSJ&;OQLGSJ'/OQXGSJ'2OWDCV*&I -M"J:_)!TKP*F_*@HKP+0*WQ(KP*^_.Q@KP+L*'Q0KP+6_(A0KP,(*1!@KP+N_ -MT`8KP,@*D@K.H_,12>"I\*K@J;OU0G`J*L"J"_/0\) -MHJ<*JPI;P*:_1"!;P*F_#A$2HF7`Z`H5HJX*A`H8HEO`6PO$K5O`P`H(`<(* -MPPI;P+N_>!A;P,@*R0I;P,L*S`I;P,2_@1A;P,>_A!B>"NTCL`J;O_`CL`K/ -MO_PJL`K2O_@CL`H&P/LC/:*E"@(DL`IOP`8DL`IRP`HDL`IUP(,UL`IXP!,D -M3Z*:P+N_]PJ+P,@*^@J+P,L*;Q2+P,2__=12>"BPD8`F;OPH+8`G/ -MOS0D8`G2OS_D;]F"=(*XA6E -M"F*_M;&W"J"_;[]F":H*[A6W"J:_!ARW"JF_]!6W"K0*8@BW"J^_X0FW"KL* -M+`NW"K6_QQ2W"L(*RA2W"KN_S12W"L@*T!2W"LL*TQ2W"L2_UA2W"L>_+1.> -M"J,D7EN;ORTH7EO/OZLD7EO2OZXD7EL&P+$D7EL)P+0D7EO*P+_1!:>"MPDOPJ;O^`DOPK/O^0DOPK2OV8H^:*]"J:_1-(P;L*?!-(P;6_?Q-(P<(*@A-(P;N_,`M(P<@*,PM(P<2_.@M( -MP<>_/0N>"A\EP0K2OR@EP0K*P"LEP0IOP#0EP0IXP#@E.Z.E"KLHP0IE"\$* -MR`IH"W7!Q+^E%G7!Q[^H%IX*!;O!RPH%%[O! -MQ+\(%[O!Q[\+%YX*/2EN6YN_Q26LH\H*H+\5%^C!J@H8%^C!IK\;%^C!J;]$ -M">C!M`I+!^C!K[_*".C!NPHG%^C!M;\J%^C!P@HM%^C!N[\P%^C!R`HS%^C! -MRPHV%^C!Q+\0'^C!Q[\]%YX*\R6!C)N_]B7Z3B"N&_>EN&"IQ!I<+P"N>_>EOS"NJ_>EOV"NV_>EOY"O"_ -M>EL`"Y$'G,)%*GI;G\+[OYYSV`I#"[E!V`K9"IRDV`K="M8+V@K@"LH2X@KQ -M)MH*Y0K)0=H*L<)&(]H*ZPI*(]H*D,(`)]H*D\)M*MH*EL(')]H*A\&ZI-8* -M(<#:"OP*),#:"L7")\#:"@,+*L#<"M(*SW/4"B_`[D'^PM'"*QCB"C7`]D'^ -MPN`*.<#<"K$*_D'^PG\*`D+^PK@*E*S^PK;"1<#<"O`*2,#GI-8*3L#<"OD* -M4I=0*PL!K='W#X`H5"W?#"\,8"W?##L.+%'?#$<..%'?#ML(B -M"W?#\`HE"W?#\PJ7%'?#]@K;P(M;^0K>P'^EYPJ9PGZ_5`2"FX)_`H1P6X)Q<(4P6X) -M`PL7P?BX_,+>">(*',%=!'["'\%=!('"(L%=!(3")<%=!(?"*,&^K=0**\%= -M!+'"+L$\"-?#ML(N%M?#\`K=%-?#\PHXP?BX]@H[P?BX^0H^P?BX_`I!P?BX -MQ<)$P?BX`PM'P:,G_,)D$^\*SL)G$^\*T<)J$^\*W0IM$^\*X`I6P:,G"\-9 -MP:,G#L-(*'"5"IG["=L')`8'"(B5"IH3")25" -MIH?"><')`>4*?,')`;'"+B5"INL*,25"II#"?\')`9/"@L')`9;"A<')`>[" -M1"Q"ILK#R0'\"FL+-\3%PHW!0J8#"Y#!3*;6"G4+X@J5P;X!]0K1PIG!I@'= -M"IS!GK)FQ(?"8R6J)^4*9B6J)['"B@NJ)^L*C0NJ)Y#"D`NJ)Y/"=26J)Y;" -M\BAMIO4*^0J;"VC$_`JTP7:F9L2?PKS!G0=[PK_!G0=^PL+!G0>! -MPL7!G0>$PI8EJXR'PLC!G0?E"ITLJXRQPATIJXSK"B$IJXR0PJDEJXR3PB@I -MJXR6PK`EJXSNPC`IJXQ;Q+OTFGMHS;"E1V"PND#K:,%`M>$K:,%PN>$U[% -M&@NMOV-V7L4?"X["G416Q20+Y`U>Q2<+N;]>Q<4*J416Q5L*K416Q90*L416 -MQ0`+M416Q*>#Q4,+@W:#Q0X+KQ\+"ZG"QT2#Q10+V+^FIQ<+ -MV[^FIQH+WK^FI[@*UT2#Q2$+Y+^FIR0+NL*8IXS%*0NB=HS%A\'K1`<+P\*H -M=HS%_@JN`G[%]K^FIX'%^;^M6U3%Y!,+"_Z__40-"PX+ZA.VQ1$+U<*ZIZU; -MKPJ]I[;%?0H/10<+#\"M6YG%$L#'I[;%6PO*I[;%P`K-I\;%H\7LPCX(IL4P -M.*U;RL/7I\;%K,5Z*JU;9@K>IZU;!0LLP#%%$`N'Q<`+P(P."P/#P(P1"PX4 -M"PM\(\",P<4G)\",Q,6>.\",'`N*(\",'PLU)\",S<4H+L",T,49-<",H\4_ -M)\",IL5")\",V<6D(\",K,6I(\",W\6W*L",!0MH=<8<"\[`BJ@9"R$+CL-U -MJ"0+D<-UJ"<+E,-UJ'7%E\,LKG7&V<5:)'6HK,5^OQL+W\6APZ*H"0NDPU\( -M00L`1AX+6<5KOU\(7,6MPU\('L:PP[*HG\87"_G`N*@>"QP+N<-F")_&(0L" -MP<&H'@O0Q<+#Q*B?QG7%"\&]6WC%#L&]6WO%S&HS\87"T$3"PLKP2`+'`LNP>FHS\8A -M"^[#P5LD"_'#\J@'"_3#4$;KQJ;%RR3!6]G%4RC!6ZS%TR3]J,_&@<4#Q`.I -M!PL&Q!"IA\4)Q!"I#@L,Q!"I$0L/Q!"I%`L2Q!IX_,;$Q7$H$*D<"W4H$*D? -M"_XK$*G-Q4%#$*G0Q0`D+ -ME<%M>%7'#@N9P6FI"PN'Q8@C"PO"P0H$7,7%P0H$'L:@Q`H$P<7(P0H$Q,6FQ`H$'`NIQ*]X@,'!W(Q^Q>3!W(R!Q>?! -MT5M4Q38'"POLP7FL"0O*Q'@(ML<1"_/!T5L4"_;!T5L7"_G!S:D'"_S!T5N9 -MQ?_!TJG#Q\W%W\1V"-#%XL3F>+;'=<4+PMRIP\?9Q>O$[WBVQW[%%,+16X'% -M%\+GJ0<+J08+"QS"C+`)"Q_"[*GDQQ$+LP;AQQ0+)L+BC!<+*<+XJ=_''`L) -MQ?NIY,>3'=<4[PN*,>,4^PN*,>\5!PN*,?L5$PN*, -M@<5'PGP75,5/!PL+3,(I>0D+3\(L>1+($0N&%P_(%`LQQ2.J!PLTQ7P7&@LW -MQ7P7F<4ZQ7P7(0L]Q2VJ',C0Q6?"1'D2R'7%1L5*>1S(V<6T,'P7K,53)GP7 -MW\6[,'P7T`I!JB`WS@SO)T,+N4=="DBJ[R?;"DNJ[R?5OTZJ[R>O"E&J/,A] -M"E6J/,CH"EBJ[R>$"ENJ[R=;"UZJ[R?`"F&J[R'P6>J/,C*PVJJ -M[R?^"FVJ/,AF"G"J[R60*HWENR(T*D:INR,4*B+$@-ZHT -MEZINR)0*%4ANR``+&$ANR,X*&TA!R/N_'DB;R#_(YQ,@-P'`)$B;R'7(U<*P -MJJ'(2LC:PL=YF\A^R,?%N:KNC%/(X\(V2)O(O@HY2)O(BL@;P.Z,C<@>P.Z, -M6PI#2)O(D\CTPN%YA\CWPM&JH<@ZR"S`3TA!R"_`UZK+R'+(ZL7>JB`W[<7P -MJGC("OC(3<@SPY1(^\B!R"K&](PK"RW&](RUR##&](R*R#?#)ZOTC%_( -MX2/TC&+(.L:J2/O(ELA#PS,&F,/\A'QO>,\A3QO>,?LA6QO>,@,8LBQ)_>,9,:,AOQF]Z0E')*PN*QHUZ8D'( -MQ<,&KW_)OLC#QKBK?\EER'D\\%MHR,K&S'I!R!G!1TFLR3_(-!,@-Q_!3TFL -MR77(.Q.RR7C(U0:RR7O(W<8J"W[(1!.RR8'(*Q:RR2L+YL;I>H?(Z<;*!(K( -M],/@J[+)7\CPQO%ZK,F3R/W#R@26R`#$ZZO(R3K(2<'NJT'(3,'_>MW)KA\@&Q_JK(#<2Q/VKY\E-R`W'CDG=R8'(&\0&K.3)5L@6QQQ[WT'(><'2!$W(?,%%>Q;*@,B^Q^*QDLI-R-;$:@U0R-G$:@U3R-S$:@U6R-_$ -M:@U9R.+$%:U!R.7$.+(@-^C$:@UBR.O$:@UER.[$:@UHR/'$Q+!!R!G"R+#` -MRC_(1!<@-Q_"X@1$R"+"6:W`RGC([,?B!'O([\?B!'[(+,(C*('(+\(C*"L+ -M]\?B!+7(-<(C*(K(.,(C*(W(_\?B!+[(`LAGLH?(!`HMRR/+>PJ/+><0 -M]6:/+;8*CRV""C?+(\LF"H\M[@J/+8D*/LLCRRT*CRV/"L,7(2/*%VD/?"/*%VT/)R?*%S/+ -MGCO*%UK+BB/*%Y++-2?*%Y7+*"[*%V3+21M^RTO`RA>=RT[`RA>@RY(*RA=P -MRU3`RA=TRU?`RA=WRUK`XV`AR^:U=@]4)^-@)LNZ(^-@*B#T!J]!>K$-DW:[&+Q?075@H@S)H/4LO%'![,,S%W+56KT%SW+6&KT%V3+6VH>S$3+G*P>S&O+I`-MRSS,(\S4$>T4 -M(\P)$J0#&0KT%PP2I`/<$0@X:[&UQ11AK,M`!AS,YB8481;,A,L@%9X/+LLY -M%9X/)\P,P!1A*LPU%9X/.,M$%9X/.\MF%9X//\M'!IX/0LMU%9X/:NMJ]K08RM0K!4K$2P7W-1 -MKQ^7I146P5*R,&]JLW`R204*QJ#650>_,BQJ!<_D2 -MD'.D$I!SX.M'`4+"%D#BG-GK>(D%['JS+L6:D[3$A?-VJP"KD(0QZ_PK]T%X7JUQ#DFP7JWV -M!TZP*;%@K6MGQ:.&^P3ZG(EK:@%701/'^#-::[X!E:L@7^Z`5FPP'^Z`>`7U0$& -MKN0!DZR;@+H!?Q1/)I`4D1D',)847Q>Z`0VN):Y&L8L#R0'Z!#S$::ZW44JL -M0ZTV"RRO`@I"S0?.I140JL0@6ALOR,<@$,UO5+4!+*]#AF[$YZT4SA`)WA3P -M&8,']A;?LO"OFE:9KD.M&5S8KFFN!5>9KJL%I@&&%_8W)@8JSA/.6"THSL*L -MBHB5Q-2NH+TF=FZNQ5?=KNT6L1P+0SO,6RT2SK;R8;["'&\M$#ZZ.&\RLCAOJSV-W^M'B3`=B6O=@:!K:\6UZ*Q$$'.QVZWY#55%,QK142`:T5$JSY4$):CNK;JBBP36%#)W -M(`(^SRK/BQH\SU\=`@HO&D7/WZX\!$D(@*]4!*^M3,^FSNL!4K+K`7VPYZS^ -MQ/BN,PBBJ%JL,G?ZKG\;H51`#^ZM@;`.>%2R\`6)(40;ORHUSTO.@P<&KFG/ -M!LU`K,1H`Z\G`Z'&T:TGJ>9%_*P#`:&L=L^/K`0BR\P$(@.OPQ+)K(:QA+&8 -ML2%(!:_G$[6H)Z]L>HFQYZPNR4@$QJS/JV@( -MEZSY$)*MFL]"KVD5A+"FSH9QLJZA%.^M)Z]UKT*OVB;1QH"OK'_,K*Q_5+)1 -M(5:R*JPY@*S/J`HI>.>LSPU,K2B"K,]?%TZILZT"![<289^=$L#/=:R6L<\H -MI16=5[XA6JSLA6:I!!/K!K(2S<^'KMP,;ZDW&VF)QR'AK#](S*P_2(>N5R%[ -MJ8"OD+'-K8MXK*QI5J;.\0$E$W(A%Q4S!=$+[12T!,2OB!+LS\:L:8F.Q^H2 -MVB'E$O//K:U)#KIX@*]B`C_/^L^MK1T+E,>@KS8[>:POKF()S*QH"8FP!=#A -M"0NO!=`IP]IXN*P0J%JL*(T%T"46[B'H$A?0RJQOL<.X[*GTSE$, -M-JP]%0EY6AL>6S\'3*UW#LRLF[$:>L4K(WK,JL&`_U>.ZMZKTX -M>?+/TI)2LK^]%P%!OCO0[,[3ODIYKK!I9,%'J:Z:!72N[!>Y1QFO=@&G&DY< -M(!JBN<5'.:T'`4@6G43Y%6W% -M-DB9K>\=FZPP'CE(OA7DJB@5*@HN%NZL!C],KB,KD4@1KZP4L[%,KFD5 -MFDADK_,#.:VIT*45^Y%WS7RLJG/AK05*@89%8,'P['JK(7%]VI[%C1!Z!7;D_=JPAE80<@2S-"LT$LF>")9`P4^ -M6;(&`9O0,GGKKE4?8AV$%WY!GQ)^09D2WM!BLJ$T\)O=%_";;0;ET-&OLWFC -M>HJN&TB=K)K(HWJ\`>_0S;$YK22K6[(G&EVRI;$;(;=Z1`05/MBLL*XG/OW0 -M6Q;XI"43`M'4L<(,R@2!&,H$.18)T6RMU;'Q>M+0JP($`GT'W=#%Q70=!ABM -ML!&M6A1SI;P2&M%BLI''H1),SQ2PI@T&K%.M+((1K3@?23Z\`2C1N;"9K4T+ -MO+#.L4T+SJQ-"_#0,M%BLHQ/']&,3V*R`@>R$E3$XQ(\T1_1.M&GKT`?7GO6 -MK(HN-MLJ7K8U=R+`WK5E>S;#B$)<'DZX3()<2`46U$H+1@='A:NM!@=`K,?1@=&F -ML:$2Q*CC$E\(MQG/T<`26-)FLJ8SH1+A1\;,L$++S+!"+JR81;2L1,;[K&72 -M^@J+#1T+:M+VK>9%9=(E"XL-^0UQTF^O^:Z+#2X61Q,X"GC2@ZSLJ672L`9' -M$\X$?])OK]!Y1Q."`T<34"2&TI^LX7I'$T03H0<>`8W2+JSB!/*LD=*^K.JP -MUDI0TA@/7'%OK_6LM*SUK+ZL#-)FK&:RBJA=TH?&"!$A$J72]JT+?Z72UJP1 -MS\O,$<^^K(@2;JPM&FRCX\S-%LK)Z!*VTF:RIH!=TJ:`CZR*J=(5J])J#M05 -M]JT"!ZC1Q-(AK0\(>GX*TAJR_DPRK.,*P'[.$H7*M1+1TC*L8PO/?I^LQXH] -MK?2LSUJ@#?H$]WX>`=[29K(]840Y(1@P$Z<2AS)\`:`-"K(K*?.PU@@"?_RL -M8(ZTK#&Z,!/L)?/2@ZPUO+2L-;P?LBBL]@^7$OD0#QK^TC@3'Z\E$P+3TJRX -M#8M_':V5ERZPI@5`3E"L'6?]TL/(!!X1'4!.7*W8$[&N*K`7`7&LC9WD`TJ$2X-(69<2 -MK'^K$DK32=-;:I$5X!P)[)["(NL9Q[E3YFOOPAVTX/3BZR4$O1/UJR[5GK3!!J% -M@8X3C=-#LH4!1;)"K#!P2*PP<)/342W4@5>R8@+EK9O3CZP:)LO,&B9"K,V, -M-@O.&&$7Z!*FTY[3,PCS`V$?2@:<$ZW3G]&>4:?3L1Q@%[2T^#3?!`9 -M#KTUH1Y=.[`MS3Z=.4&_+3 -MYM,?,JD!W=/PT^K3_-,(`[L"[].'#@34\]/GT_73`]2;#OC3W`U)LP'4"=3^ -MT[D"#-0(U)@1$]0&U`#4&P16`?C3]-,2U!C4Q`SKT_W3NP*T`2#4O@<>U`O4 -M(-2A#_'3!=3BTQO4_PLIU/_3Z-/VTTP![--*`QL1%M08U#+4%=0@U#@1(]0N -MU.[3,-0P`>D%-]0?U/O3.4E`U.'3*M0;!)<"+=0*U#/4.M1.U$K4[=/5TT/4 -M<0-/U!34^M/VT[D'#]0G#EO45-3;TU?4#PX#U`_40M0TU&<&8=1'U/;3F`\W -MU-`%2P)CU"C41M1,U&\%9=1NU&?4.M2T`SS48-1S$@$59M3!`G'46=1BU&C4 -M1!+?TW?45M2$U(\(@M1KU`W4X@]NU`@.)M3[TWO48]3C`H+4+]2)U.4#D]2) -MU,,'F=2'U,8"@=1JU'3410+DTY[4!]1@=J'44=0GU$,$EM2BU"D(I-0DU(S4 -MKM1VU"34E]0ZU#D!FM0ZU,,'M]1WU&*:H-09U+'49P&&U+34>-0@U(H,N-2J -MU#`!QM2'U#W4&P2.#'+4L-2MU(."L]1!U(C4.M06!,?42-37U,O4?-2UB]/4 -M4-3,U",!DM2EU&/4!P9SU*G42-3EU,/4U06^U-C4UP6OU-34`@%7U,<'J-3@ -MU&74S]34U/74J!_OU-_4?-3SU,+4\-0'U#V>]-3$##M6T`HD"F=17U<,!6=49U5S53]5CU5_5 -M)-5;U94#7=5!`4FS4M5'U1D.8M56U6K56-5FU535F=28#U'58-5BU&_5]QMD -MU;H!>-5]`6?55=7&&T$!%K-LU?S43=5IU44!A-5^U6[5:-6#U7S5A=5AU8W5 -MB=6/U8O5_]-ZU>`'5QQRU6W5EM62U8+510&=LI#56P*`U9G4X@]WU5/5A]5! -M`:75FM4.U4/5.]6'`QP!2]6&U=/4Q1^PU2\!K-4HU)W4M=6GU674N=4+`;'5 -M5=2=(OZ-80%&`6_5AM5=!=?4[P/$U9+56M5`"L+5KP[*U575QM7.U;X.9`'% -MU<#5=-5DU4D[J]61U8'5F-6E"'W5<]6HU44!M]2FU9O5H]5!`>35V]6BU=C5 -M<-5%`>@!X-7FU>S5GM7.'^K5?]7RU3,%E-6GU9?5QM3EU=9VUBS6\]51"'+6>]9TUN,!?M40`6G6@M9_ -MUH'6"]8'UG/6[=69'8G6B-86`6[6CM:0UHS6>-4PUK,-7M5CU@C60=9,UNL# -M5-9%UC;6QPM:UA'6GM;P`U[6/]9;UN4+J=95UJ;65]8]`Z'6\=7*":/6%@$^ -MOZK6[=,J2Z?6J0BEUH/45]8[##C6KM;KU1+6(0&@U9C6E=:8U9T%?M;RUU9S6R-9O#1^S)M;4UB$!UM8KULS6B-5CUIG6V=8SUF#6*-8A -M`2.SU]:#UH_6M0C3UN?6@A[AUF36LPW)U936Z];)UKD!YM9_UO/6R];_U?P3 -M[=;?UA8!Z=5EU2+6X]8##)'6Q-8"U__6_M5ZU0T(SM:SU@C7_-7XUG#6J`8# -MUP_7!M;;UOG6#]81U]#6%M<&U^+69=8A`136]=:2UD@?#M?0UAS6%]M53`?O6E=9!UPK7!]$(+]=#UQ35>M9_UDO7,]<_UT?7 -MVP-)UX_65==,U^O66-=2U\_6@=5;US?7C=8SU!,@X0L5`88(N]5CUZX,9=S"&?7 -MTP=NUWC7IM9ZUYD(A->#U(;7<]=LU^T/?]=\UQG5K@Q7%6K7MM6%U]\#X0N< -M"(C7V@V6UZX,F->4U\/6G->.UYG7Y]/%;:'7GM>=UGK7?@BBUV+7F]?X%(O7 -M?=?S!YO7C]>)U[#7D]?AU2K7QM9=URW7N-<`UU[7JM4HU_S6.B'MUC#7'->N -M#-K6N==*U\;7O->^#=W6/-U_#6T]?5UT77 -M&]VUS'7_M;>UD/7Y==AUT/5%M0#!`K5-M48U.S7*M6M -MU/#7&-6#U.O7SM0K7$M1"%375(=6^!_O7%=5\U/O7.-6[U>O7XM1"U0?4 -M4@?MU_W7X0OIU$#6Z]?Y`@K8`=@0V/'7'=7[U)#7N=06V!K4"=42U1O8]-S(-0JV!S8>=3N$338?=?]"NP05MAPUY`@5]A;$7376=@"$5?8>==5V%[8 -M8M@YV(34HAI0V"/89M@EV*W4:=A3V!?8$M1LV$38*=='US$(O]?8UK$/:]70 -MU^4#=-A=C9U2H$T]>8U8/86==_UH;8?-@-UG[8>M3QUCG7 -M0@^[UXO8T=MB^U^;7Z]:4V-O7&M@VV+W5LM48V+$/GMBFUIW80=AK -MV-`$<=@?V$(/R=4@U2?8L0^KV'37-MB[#BC89=BRV!381MA"#[O4(MC[TP4$ -M:M@VU;S8;=CUUV_8]`.HV';8WP/OUU&[8 -M%@3GV![8Q-3JV"'8/-C[T[()O=CFV$_8_-=\U/+8P-BIV+[5%-6LV+[4$P8_ -MV(34$P;`V+'4`MG$V.#7L-6T`S8==_UA79$-G`UQS9@-CCU]'7I`*8V!?9=R"5V+#5Z05/U_+5]`0@ -MVM4PV1W9E=8VV2W99-@6U$T:9]CQV&W4L-@2U#W9 -M]-<$V7<-*]@MU"MNNM58V#382=F^U:;79]1-V4#5GM=(U;#5>M10`K_5==*U3D!2]5_V877@=E^ -MV6'8@-E7V8+9@MGH`538C-FPU8H,60)8V(/98=A=V%O8;->4V8H,E=F2V6#8 -MC]F^U9'9,=A.V9#9L-46!)S9D-=&U9;9_@Q?V(77E-GJV*#99]>MV:/98]B% -MV8K9L-6(`HC9I]F&V;[5M]F-V;39MMF'V;W9B==*U;?9GMF.V;+9F2"KV8G7 -MF=D<`7D$R=FGUX/9S=F?V/8K]F8V9[9GB#3V:/7R]G=$CP17-C0 -MV2L"F]G]V*+9WMG'V:;9G]=]V=T2302XV<+9M=GKV;+9?==%U1LCY=F$V>[9 -MS-GLV<791=@'U``L/MG>T_W9\]A\U`#:`]FMU`/:!MG?V$Z?L]B@V`G:%-CY -MU&D:Z-C!V!8$#]KLV!78W1)%U+K8_]D7VG;9$MI3U'G9%M3=`OG8[=C,V5W4 -MY-D+VO8D#=H"VA8."MH2U"?:%-H(VD(E_MD#U##:`=I7U#/:!-HVU3;:!]K\ -MV5;9&-HRVCS:&]K,V7L'*]H2VD+:MMC\V8[4/=IS$BT%`-D?VI74,=JV(!G8 -M^MAAGT/:_]FBV)_7']JGV%3:W1)9VD;:-=IUV9_8(]@2)RC:7MJEV#C:>]DY -MU1_:N=CPV/_9:MHTUFG:9=H.VL/81]F$U)TG3]H8U'7:--ITVO?73]IXVB': -M%=K$(%K:2MK:U$'9$MH&V&O:W1*&VCO9+-H-V&#:^],Y,&/:=-H3V![:B]I1 -MVB+:!P%K%7;:M@$J!#O8;MH!U)O:<-I@U)_:$-KZV"H$,=6-VK41I=KEV*': -MT@:@VD/4J=JCVI;:(Q:!VI@1LMJ0V@S4M=I$V:+4N-I^VM_8TJ*SVIK:BPVJ -MVJ[:P=H0VHS4OMJPVA7:U:*_V@H!RMJVVI[:+5UMJ;V/K8U0'+VL,!_-B$VJ\!&]4QVN+:R-K?V+H!G-KI -MV+41[=K"VFC4\=K1VB_5]-HNVN_35ZSCVOK:SMH&UC35+MC\VOC:0]1-K/O: -MBP_]VJ\!'=H`VP;;U-J2UO'-U]K#`8[8[-4.VVW9CM83VQ#9X=H"$IG:KP%` -MV4#:PP%&V>G:&=L"V_/:QPT%VS_:G=H&UD7:D]HHVY7:%=K@K@7;2-H=VR[; -M]=KUU#+;#-LAUN#5B0+"UMH-+=DXVZ8&7-@\VU+5.=MGUT#;0`%"VR[9C-;E -MUM_7U=K5"%_9N@'8UVC9;]5.VQ/9+=OX"1K;PP%MVJ/8`=2Z`7+:(-M\V_#;OMN2U53$0M>WVV_9`-4#VPL*Z]MS -M$5?$Z-OCVV?:/=K^V^O:^=K*`6+;!MQYVHO;7MN3VPO`>RR[+)"W*;61-S=`4O<'0]#W#H53-Q'W+#8]P2L`?FR^;+E -M`9_84]Q!W%3 -M`8#<7MR"W''`9/`7$'6-P*LP^S#[.FW%[W-7`>+W/+<[]QWW/?O;R]VQW<3=3A"IW;8! -MRT3,W=;=P]T,U-C=QMVGW1K:I]KJT\]$U]U%U3?:]=3AW='=VMW>U;:'S(JVJ_=F-6[W;+=YP=6V]=$XMT?V\_=]-TVV[,".A7;1*?=3@B#![O5 -M.JC_W03>'S*`-ZI]T'WN?3$-[?1!+>I]VQ -MVQ'>!MX7WA\R%-<:WA;>&]X=W@+>?P,XT1TUR;>K]4BWE0(2-R#U"G> -M60@JWK?-*-X!WBO>)]XLWB/>P@$VWCK>L@G^U7;=-,9("#@(_-T9W?_3/MY! -MWC_>0M[AU47>Z@-'WC>HI]5*WD#>2]X%!#363-X%!$W>_-TLW3/45-XO`5;> -M"=Y3WD;>5=Y@WEC>N0):WD#>6]XZ%5[>9M[H`0_>)-YPUUS>_=W]W6S>:-Y` -MWFK><-ZP`[+5;MYTWFK><=ZFUFO>3@C6V"#>=]YUWD#>Q]T3WEG>;]['W0S> -M`MZ'W@7>@-Y\WFS>)MY"!"O>=]Z/WC3>E448WC/>?MZ$`B_>(]Z9WB7>*MY3 -MWI7>,=[GV#+>;=ZAWED(H]X\WH[>.=ZCWJ+>+=X.WI7>K-ZGWBW>"-ZMWF\( -M=`A?!)/>LMZVWF\(8]RTWKK>-]Y4"%C=%-ZUWL#>2L8HWK()QM[!WD@(J2AM -MWLC>7P3)WJ'&Q]ZWWGD(S][,WG?>SM[4WGD(UMXQW,3=#]G4W6\([MI7V@'4 -M0PBMVMW>SMU_U-_820BTW1_9F-SCWAS9Y-U@U.K>/-R2UE9W#]OUWO/;5=7W -MWI[;+-;ZWL';6=F(U5>H]MXSV8W=;]4!W[;;_-XYV?'6Z=Y#V=_>5`@ -MV=G=[M[MV^+;;PA6VN+8+-\FWUS:S]UGV=S=5`A?VN_:&=\VW^+>P=URV?#> -MLMT\WP;9%]EM=P+?XM='VT+?!]_LU4;?Q-L+W\K42=JJW979P-UO"'O:,M]2 -MW^C>O-VJV?7=5]\)W.[>B=HWW\5%+-M!WP0+`M\>U\O8=7?VVPC?)]<-V -M6PC5W[4<"WM7>;-^V`6[?0-;0WLS>T=X#$Z[>%-YPW\O>';/=IV")K?^=O$W7D)E=^#WR+?W=L$92K?F]^@WR#?VMV9`HS?5MHW -MW)/?,=\3WZO?DM^(WSG?+M\$93G?KM^TW^7>JM\!W)[?JM]8VQC?)-]W"87? -M#=RGW\7?OM^3WS/(7?.=R'VLS?L]]("*W5#=_X>-?=K=4]W\3=U]\Z -MVK+=L0*TW=W?MMW?WQW?\=[AWZG?X]ZW`M[?Y=H=V^RIN]_FW^C:--IAUEQ' -M]MX\L_C>60CSW_O>2-_VW_[>^M@$>=[?IMJDW_S?A]_2WX;=R-_!W4>S]=T& -MX%K?!>"/WYO?".#EWP7@%]_+WXH-UM^=W]_=_JE?W_3>X0WRW\G71M?YWAG@ -M1]_BU11Y4]OIWHD%WM^XWZ+4%WGLWP7@O=]_WQIYWM_`W[G?TM_'WQ7@X`(7 -MX`37'7GRWQ[<1=^2!6;?^-_0V(W=:]\*`7/?<]\DM@+>;=\"U4/@I`)3WD;@ -ML0%(X.39=]]"X`+51.`$X$'@-M?JW7,13TC,W5C@`>!]&J[=[]\!U]>J#]M@ -MX/3?5.#";US39DM5^X!_@;]6#X&C@<.""UPW?]7EWX`G;ZMV+ -MX-'??1J!WX?:5^"-UVW@E>!OX&C4^'DUX&'69TA_X-#;1]N=X(3@@N#M`\[; -M?>"C!XK=G."GX`3?H^"-V&;@\P?ZWW;8`'I_X%O9_]Y4X&39T=NRX-C;%=KT -MJFO@GP>6X+#?CN"^X#;;J>!)V]';GM5S2%_9R."BX%75RN#$VQ?9^JI_X$3? -M'.#A`]#@R^#4X&O7A^"9X//7BN#;X.W>]`+]JBG@5.!4WS'8J>`3U\;@X`=\ -M2,G@_]>0W`TWX)(:^!B!UG@^^#VX/W@ -M^.#Y$U;;%WK\X)+;CN`!X'\LJO@S.`MV.S@U.`0X>_@:>`H -M"(K@%N'>X$'@*`AYX`'4BTB;X`GAL-OGX'$'('K)X%\#_M[\UB3ANN#PX)+9 -MH=\:X=[=I-^12.'@!Q.-X(?=Q^!FV`OAQ->42"7AR]NQVX7@:=BPX+O@?]A6 -MX)@1ETC\X`O@A]I%X7S@G."&V#CAB-6:2"7AK>!0VX+@B=A`X2OAH]_!WT3A -MFM@)X!KAIM](X5KA$OX/3@=^&8X'K@>^%@X6>R:^`[X&W@@N%\X7;A -MX^!PV9G@RPZ!X6[;$-\I$US?&-_JRFKA<.`8&VWA\^`OU>W*,N&8X9#@\,IK -MX!P;;>">X87AW^"@X7_A'QL"X:7A;^'H!`7A:.&GX97;DM;H!`WA/>%?X*:R -M#N'4X*.R]]_BU:_A(N!IX/L"G>'AWC#@*Q/GWH[@O.&0X*)\X]K%X8/;Q^&A -MX0H!R>%@X2U+QN'ZW9C?SN%;X-+A--^I?,_A%]^_X=;AT^%LWM7A--XMX';X73A^MBW?,_A>>'LX:4(RN'' -MSC+@W-X,U$-+S^%,WQW;^^';X8?A4^#'SHSA-]]S$4=+S-T'XMOAC^'PX2#6 -M5MN_K`CB#>+VX0_BQ.$RU@[B%>)OX4Y+,N$9XA3B[]@CWY@1$+$(XAL)$N(B -MXLWA6-8-WU5+(>+NWR[8*.(4XG3@8^'+X6P!T>&`!X;;[.$SXHK;`=1]#2_A -M6.&V`3GB(>(TX8?:/>(4XI+@'N(\XCP&(>+OW>O;]ZWGX?KA<-06X@_?I-]H -M2QKB3>+5X='6)^)5XAGA-Q-=X=_=;TM+XCCBW=5#X47BK=^BU'-+4N)GX0+B -M]='&X;4(&.)JXN3A,.+OX9;:>DMIXO/A]=1QXM/A^M84XOWA1.(PXGGB4.() -MUR/B`>+3X&35=GT/VX/B8^!@`B??M^%OU87BSN"2UOROA.)GV8'@5=6.XM;@ -MR^$SWT#A%]GY$,7@?=C$UYGB7]F=XI3BA^)/VVG?@]G -MXHS7J>*FXE8:J.*+UZ[B[0;CU[/B;+#H`4K<6=R+V+7B1-RXXK8!1M>[XCH5 -MO>+/UL#BM^)/W+GB^>$!U$NLX]K*XH/;S.+VX<[BK>$$UQ%/#]O3XH;BU>*) -MXI+5U^)5X>_3%4_+XM[>6.+=XEO@X>(TWVV`WN+^WSK?GPCOWC3B]=3EXGS@ -M===OU]4(&P&KXGG7L==KU_'BFAIH]?ZXJ7B(17SXN+6Q.*? -M"$,)0-RZXL(!O.(&XT7IXN<(^.)8V/7B -M+P$8XP+CZ=F;UQCCJN*OXAKC%0$AX_SB#>.?"#H530LSW17C'M8$XP,!%.,H -MXS#CQ>(LX\/BP@$KXRGC->.LXHO7!@?RXB/C].(7X^.R'N.GUR#C^^(!XS_C -MI]E%XP#C/N.UXK_B">,JXPOCW0$(XSGCX@A1X\?B,3 -MXSKCK]>IXDD*'N.:UV+C1^--XQ;C#PGVXF?C_>*KUQ4!20HBXVCC6.-/X^@! -MWT!UXG;CMN)WXR?6?>/!XGOC3N-4XRH)8.-=XWGCA^-W -MXS#7?>-?XX#CC-6.XUOC#.-\XXKCP'*0XYS5+^.7XY3CA>,39I/C4N.)XU() -M@^.(XY_73>!2":0"/0F[U:;C0@*!`:GC0-:KXU+@KN.RU;#CJ.,PV336L>,P -MV:[C-%Z[U;CC/`DPV;OC0-:]XZ?C<0?`X[+5PN-"`L3CHP=AXXO7WH<9XT#C -MS.-"XTCC'^,5`-MXS85U.-&XTSCA=YGU9KC5N,MXX'CEN/?XS+C^L^& -MXZ#C>.-8"9_C5^.-XXKC;EN8X]WC[>.$XP/C@`FCX^_CW1IM"?7CG./SXX;C -M@PGVXQGC1-S]X_KC<^-T">$#$.-3XWH)!>3RXY_7NN.C!\#C8EZ\X[_C#>0- -MY(;8M^,1Y+`##N04Y)#7#.07Y!/D=MZFUAOD"@&A*B'D&>2#U"#D$-'"`0_D -MP>,1Y"CD'>00Y,GC+.07Y"3D[..&XZ4J_N.KXD3<->0"Y#/D$-$)Y*3CX>,A -MY+[@!N2FUACD,>07Y`+=LM5$Y"/D1N0>Y)_72>3!`DODN]5.Y"GDXKMTUU+D -MFMA4Y'#75N0HY$?D0^03Y"CDAMA8Y$CD7N1*Y"'D7.1-Y"WDP0+A`V'DD-=6 -MY&KD9N2=UACD:N1@Y&;D0@9QY&3DJP)OY.?35N3J`VOD@]1[Y&7D3.1PY!/D -M?.1SY$SD=>2#Y'?D?>1PY(7D@.0AY&\!4>2,Y'CD%^2/Y$#64^0"W5CD$;R0 -MY%#DDN2.Y('D>N21Y.6[G>2:Y(WD>.0HY)3D--:6Y%ODD^2&Y)_D1N2JY*+D -ME>27Y)3DF>3."7G?,]28Y+/DE.34"57DLN2KY,H)MN2Y`KCDON2UY+SDP^1] -MKK_D4>2]Y([DP@&[Y+'DD^2FY+`#S>1(Y++DT.3(Y,[DL.2K+-;DT^3&Y!\' -MVN1#Y++D:N2ZY,T)V^2.Y.'DT>3CY-_DW.3J`]+D;.3*Y*L"&`7>Y$WDLN1\ -MY.+DP.2Q`;CD].3GY+/>=MCQ8`_;_>2&XO_DV.)5U0'EE^*2UK$M_N0TWI'B -MX0,'Y:#B#.6,X@373Y+^Y-,'"N6@"8G@$>$5Y2G9:]G@!SD8$N6?X('B8P.D -MX`WE(>4/Y4G6U-4_&.+5TM4_UB;EW`8HY1'62=8GY=75R]49U2_E+.4QY='5 -M0^3UY-;D"V)1Y#GEQ.3.";W>>N0]Y5&UE_E<-=EY14!9^5)Y4_E2^4+Y4;63N7*"6[EM-95_Y7SE;.6$Y3_EA>6"Y4?E@.5XY:_6?N7.":<) -M@>6^UH_E"QF)Y9_75.61Y8WED^5/Y9GEEN53Y93E:@V6Y5CEH.7H`4WECN5/ -MY:7E4>5%UJCEY>?3@^5C`]H)HN6OY93ELN6>UH;EL>7"":KE:.71";;E -M:>6(X0S4Z!#CVL+E@]O$Y?;AQN5@X4.3P^68VF_ARN5;X,[E".$OXR,9-N0C -MXT3OE,N'QY4KA`=<`E/[DPP44Y3$T/.'1V_;ENN#8XW/73330 -M`63C_N*UUP'FSN-IXP;FUN.PX@GF)^.5XU3C330;L^#CV>4/YOP&C.,3YA#F -MYN-7XS_D&.;?C.^0^W$TT(;,2YIGC>>,AYA;F).9*"@H'&>8CYO#C*>9! -MY.'EV-9'`SG@DMAIU3+F)]DVYI3B..;9X/73$Q1\XNWE/>:LW4#F`>!"YMS= -M$Q0$XC_FDR!!YDGF0^9+YD7FEB#+VA,4EN'@U%'FX>!4YO3E!.,P0`JS+.;W -MXW_C6>8GYBWF7N8=YAKF%^;X1ROF,N,@YH/@Y^/>Y6CF@.#KXV3FL=<*Y!OF -M@^!"Y`/D7>94K=3E6.9WYMCE*.:P!$0'=.9RYG[F,.85V'WF/N8NWX3F0>:Y -MRE7FB>:QW2K8;V/+9 -MIM6#!RSE&]RYV:#F'H`?W)_F2@JFYAK:XUZ/F=>'E)\A.4.:T -MY@?;H>9FXJ?:N.8?X1S7H>::XC3F8]6^YC?F)(`\X*C5PN8JX>/3;C;LY8;F -M^@BWYLWFRN'*YKSF->;`@M?:;C:*U:?;UN;%YF+5V>;^Y5SF(.8""D;<-N,/ -MYN#F7^;WX^29A0AQYA?FY.9BYBWCJ=B#-CKBS.;Y!!GA[^95YF@77>+E)VT7 -M4.;YYL[F8`CUYOWFT=^#-LOF+^(!YT'F?"+^YD?AIMV#-A#@`^=7"]CA=-0* -MY_[F%.#(XOCF(P,:VX,VX>$/YU<+6N+OVA?G]^9*"K]2^N;D!/SFN>89&OSF=.%KU(,V;^*#YE<+P-_QYG/B6]2#-OCA--PWY]+FP>97 -M"V/?(N$?Y]0-8^"#-FC?8ME#YZ7@[^(A%2D*X1K2XV7C`.;Q5`?FT^-/"AOC -M4.=-YTKG<]=#XQ/F7>8E57CF)>9;YWOF8.9>YW_F%^9AYX+FM]A9(RGG[M># -M(NM&0>9KYT/F;><(X;WF#$?5YG+G0N=TYP+E10IVY]OB,-19(X7F`^/VEOACN=5YH9''N>8 -M!8+G@=27YVSGS-Z+YYSGC>?^1X?GS0F2YZ#G;N>BYY_G3A4MX9@%Z=\0WZKG -ME.>HYZ?G+N)IYT\*URF)Y[3GG>?!X6?F$0B#,R+FXN9:Y_+;'N9CY_+;8N=\ -MYF)39N8[XX#7^B+E&G+C3>?(YP)74.=$XQ`DSN<*YB3C3PI"LPWFG>,@YBH' -M_[);YO_CNN?:Y^7F^.(0,M0(Z>;$YZ.R=.8?YM[GP^%JYEGGV>?JYV[FY>>+ -M".3G8.?#X>?G!.8`YGEN5.?VY\CG^.=8YV[C2@KXY]/GS^/^!"'EU^<3Y__G -MYK*IY\`E0>8*Z$/F#.A%YD,)'>(%XMDB$.@+Z'4"5>84Z`#G'8Q0YAKHM^8< -MZ-#F'NC1XG'7_@3R%(#7U.Y5S9@M5' -MZ$#HU=M2X4[52^A%Z./6(^C7YIOB->86C4#H4>%-X0?H6>BTX<'F;8W5YE_H -M0N=AZ'?G!^BWX%/@(^ABX;+G:.@5Z"3G.>=#"6WH[N:EC1OH9+.2YW+H#>AT -MZ-'B1NA#"=+@2>BNYGOH0.CHU['A3^A_Z%'HO>8JCF#H<`E`Z#[@@NA%"H?H -MA>A6Z"NS3NB0Z.;@+MDCZ-W81>='CJ7@>NB)"8CH/N>5Z'>.-^B#Z)SHR.9[ -MYR,%F.<)U6*:0-\VYZ;H%^C:W_+:8]=BFM0(JM?_Y;'HKMBYZ,;5(P4U#<[HT.?0Z'?70]ZTZ(>/P.C%Z-_HR^C6Z)_4X^@(YK./ -MP.A5Y^CH)>@IZ.OHI.(LZ.[H4^?,Z."/Z>CVYV*:G=?AU??HU>C)Z`C@\NC+ -MXV*:J=?=Z(X5PN@!Z?GH8M'[Z&+4`.D(Z?BC3?IY^(PX%T% -M`^"ZYC[I(NE-$&#B/M8ZXD'I%2D@Z=00V]\TU%T%Y>4_YADI'NG#!3OI2.)5 -MWS7IEMVIY]U<5>D(YQSG7>E&Z0OG:NC@7%7I$N8!Y`_I2NATZ5WH707XV\#F>>FZX5KI:.<+V%T%Z^%3YBLI3>DP -MYV;G=PDSYP/GB.E5Z3CG+N>+Z>[BJ-E5V%T%U]F=V:/9D^G.V=S9*2?9 -MY-D\U9?ITMFSV>G9O-;"U27E30%YUZ/I.=:EZ?SHZ>4GT]6FZ:?9K>FR -MUM35'^5VZ7L)+>FWZ2_IN>DQZ8$)1^=?Y3,%[A2]UJ/EH];`Z8,B7]:7Y5LR -M^%RMUJ+6-K\(Z++I9^AP"1'H4^D6Z";IU.DHZ=;I/>GW%-_>P.FKY]W;W.D@ -MZ?<4V>FQYX#I#(X>Z8$"X.FXY]#I).AOI4-_`Z4/I8.GKZ=GI\.:*Z0RS -MDN<3CN#I/^()YPI=).E!Z//F_.E#Y@#J1>9P"0+G9.F-W]7I7^EHZ0?J`^J7 -MWTCIP.D.YR75#^K@Z6?I[N:'"1;G%NKWZ:C?&^D9Z1CJV>EIZ.3ILM\9ZFWH -MCNDAZMGI?^DGV,#I@NDVYQE=X.F&ZG#WP'J-.H,ZGWG!NH^ -MYDOIB>@UZH#B!NC`Z4?F;.F1Z!GJC^$DZ@OB(MK`Z8_G!NI2YBOJH^C7Z<[? -M^^G3WP[J*%T>Z:[H_MFE:5W@6>E0Z2M=).GAW^[I7.H!ZN3?3^D\YBY=7>K= -MZ>CBI6DJXLG=:>J6YW8I7>J^X0_G;NIAZNGI4>KGXFSI:;/WZ7CJ;>*E:?#I -MLN8VO^7H7.F`ZE_J@.I[ZCD7^ND_ZCI=7>I2Z4OI0K,HZ8WJ(>A]V3,%&PKQ -MV;G9M=F2ZOK9Z=G/!Y?JP-E#VU&_D^KUV>W9#.G!YGU=+>DE&R_IINJ\Z:CJ -M>N=;ZC@27.FMZE_JK>J%ZK'JJN@[Z(-=I>J>Z('BDNI$YXSH-K]U$GWI--3_ -M!1OJU]/!ZJS=Q.H!X,;JW-W_!=+I+M_*ZL7J>`>JX6O:S>J0Z9;7_P6RZ`+I -MJIV/\%].FRY_OJ].J'ZC3<_NK1W_\% -M4NG,ZG@'B^ITU`3KX>`*ZP/K4F;+VO\%[^4)ZP[KQ^H3Z_O=8]?_!07IU.<8 -MZ^CJM`(;Z^OJV^H$&POI]N?_!0GCY.K8ZEIF'.NH`23K".GLZBCKW>K:Z/\% -M!>0FZW'7,>LIZ_?J(>K^Z!G5->LOZR+:_P4GZH'4/NOTZBWG$NMXZ&/JW=/_ -M!8GI_>IZ"?3JC>E$ZSCG^NK.K@_K4>L'V[$`TZZL"W.BPXK$< -M7.M,U5[K+.L@ZX#J.>M1Y[$(UPC69^MBZ^GJAV8BZQ78L1P% -MZ@O8=.O.Z@W@]NIWZ_3E'->Q'%3HP.9PU7[K)]F"ZY3BA.L[YD?KJP)KZ?+J -MB>MXZV_I:]2Q'&_I,.NK`C+K:>L7ZY/K-NNQ'+X-SN@MZQ[@[NIIX[$OOY(/KL>N%Z[/K#^4CUK$< -M,^9]Z'8%N.NRZQ/I%^6\ZX_H8]6Q')3H@.N"UN7Z+SJQ^O!Z[#KE.%U -MZ;0'L1RXZMS7]^J4X63HT>N_ZO73LQSVZNL0VNO.ZJ/A>NMC`UGJ*]]Q;$KJ -M=NLC!4SJ,-3DZPOKY^L>YW1LV^OQ$.[KQ>JJD>OKW^LWXG@"=&S+ZO+J>PG2 -MZ3#@^.OTZU;K^^-_X_H>1-WS*X1/L[>M@ZBWAWJS\ZPGK&NQMXASL&>SGWQ+L9>I4ZR7L%^PG -M['+@WJSCZ2?8*^S%ZG+J*.SVWRKL-%T/ZS3L)NQZZGKK-NS)ZH;J->R"ZAGA -MWJP`ZX_K/.P#ZXGJ).R-ZE#?WJQ8ZPB['7K+>PY%Q'K)=7>K`GJ0NQY -MZ_;KYNHY%V/I=NM9["_L$N#'ZESL1.S:LAOL0UU=[([K'NQB[#/LG>O?WMZL -M8N)2[#:O"^MO[&'L/^L)U=ZL*NKIZSD70^MN[&[A:>Q)ZUOL>^%([%..<.Q^ -MX4;K]^M6CCWL.NIG[#[J`>N&[&'L0>KRZCD71^;]ZY#L@NQ'ZA#LU>MK[%1= -M7>Q0ZN_:WJR;['[JIFSOZU81H.PO[/7K_MFC[$3LI^&8[*GL/^Q977#LK.&$ -M[%CLMN&J[&?JDNRVX2#LB0EJZACIA>S#X6/LO.R`[+SLM^S`[+#LIFSQZOWJ -M8EVD['WJ0NS_`AGL`P,U[,WL)NS/["CLT>PS[)@0SNP(ZV[LU>Q?[-GL.^S( -M"<[L4>S@U*9L5.P>[-WLJ.Q:[$_LS@6D[&?IRNP4ZCWK<5W.[!CGV.QF[/'L -MS.P?ZN?L;>S@['1=KNQPZ.WL%0/.[';L%>S][-KL+NIW[)_JO>PRZ@#M3>O8 -M[$_K_.PXZEOLJNJL[*CJP>R*[/KJ@%W.[)'LX^Q%ZACMS.SEZ^?LZ.L`[9[L -MRNR>[*?7T-5%VP'7@-F>&D[58=;RV2CM)>W$UR?MJ-4J[3';=TXD"`-W3 -MZ)?F--0U[;41EN;>/CKM:-2;YEL:Z=;(U&38_-.)`HO99]<#V$;M2MDYV$KM -M.M58V5393>WJV:CFJ^8-"+'F.]NFU8D"0>W"UB/MY1H)USW;$->MYEWM'MRQ -MYC?<0=L^VT+;*MR?V&;M$-=H[3CM;MIK[7@";>TNW&KM+>UQ[3[;:>VCV'#M -M3=54"F[M%]AZ[8D"?.US[7GM+>U@&A#7>.WUUVOMA>VNZ8+MG]?!V9W6CNW5Y6?>D->6[2_C--::[3WDN]6=[8;CG.UGXR7MF^V9[:/M -MD^VZ["``!\X<[8'4J^VLW:[M`>"P[=S=`@K:!,O:M.T'[?73M^WAX+KMT=^T -M[0WM)]B^[:_MTG>[[TF>;;MQ^T'VP(*I>R-V\OMXNNI[NRY]'M -MPNVO[%3:U.U7YGGC\0%DU.OG*.9_X]OM%+/MYA/FX.W&YU/CY.T,[`[FW^V] -M?ESG5./Q`8#=P.VQ[?_M -ML^TB$=+M"]CY[1WL)=4&[KOM`^X>Y_GM9^HNWPWN_NTC[,KA$.Z][;)-MNT6 -M[LKM&.X3[AKNXQTU![N#.X??Q?N/NSFVOGM0>PD[B?N -M%>Y'[$CI^>W7[.#4,NX*[H_JL.SY[4[LK>V^31'NXNP([CSN+^[F[#ON7NQ; -MX?GMZNPM[D3N'>XB$8KKT^U+[A'N\NPT[D[N+^[U[$/N]^Q;U/GM(^I([OOL -M%=CY[7/L&-A=[A'N>>Q1[GOL..XT?RCNN.W=T_GM">UC[@OM7.XW?RCNB.P_ -M[H3A;>+Y[1/M(MKY[8[L3>Z*X1GN>^X;[GWN2NZ7[#'N/7\1[B#M2.XB[7?N -M0'\7[J#A4-__4L_M:]J-[B;NJ^S[[?]2!^Y1[M;M_MF4[COG<-5>"^G6S-N" -MU9SNO^;3ZZ#NH>A``:/NS.N?[IM.U]J<[J[KHNJK[J3NJNVI[J?NM`><[KGK -MK^NH[E[M7>BT[J_NNNY1Z`3C%%,"LP7LE^W:`;_N">ROXL3N]^VAX\?N#^S_ -MY8#77@O$&DSG^N=FU\[N1AK2X]KHT^Y7Y]#N_N?7[@'H`>P^W%X+*`+L[=_M -MOPCAY@[FW^[HYO3M\>WC[N7M!N@"!UG<+>'M[A3LN>T&!X[NI]KP[@SN8M.V -M[?CNRNWZ[A/N_.X=[@8'+.RM[0#OK^T#[['M!>]PYVG5[>XAX57H8]4*[R?9 -M#N^4XA#OA^MX`NWN.NX)U17O!.^O#_WN&N__[@+=[^X&!Q#J-.X@[[OM(^^] -M[08'>>X%[B?O&>\9[0CN*N\F[T7=&MOM[A[M\NXP[QOOA^Y<[M`B^>Y\&[SOO*NF^[A=7X>[>[D+O7^?WXR?OZN/![K/B2._K[E?:==T]-VK=4._\ -MW3;M4=1/[P'63]X.V%;O>`)8[Y_86N]1[PK61]ZFW5ECH>RC`6/OK-UF[P'@ -M:._.]T[U0JR]I9 -M8W#J)=6`[W+O?N]][W76&MM98T#I=-2)[X3OA^]K[ULJ?^^0[P?;66,L[H+O -MDN^/[T;BB.]?*GGO2NP8VEECG>]'VTKHQ06U[L#7KN:C[S?FI^\YYJGOMNM2 -MZ`,!TM3/Z]`DKN^U[J+JJ1/2U#'ILN_8ZQGIKN^L[:CHN^]!YK[O0^;`[T7F -MX`A"[KWO[0BWYL3O5>;)[]/J$"3@""7KE>N6UZD3->6EZYTBSN]OZ]7O+(-R -MZX_8TN\;X+KK*>;C"-WOM>#<[Z_NX^^][B7FX`@$[+WG(.;H[\7NL^+2[[H( -M\N?FYNSOR.YUYB#F433A[>KONN?W[^WO*K]FV,/G8.;[[_3OZ.>*)U$S0^_Z -M[P7P1N_AYU(#BN/=[0#P"/#+[N7JR.=2`Z3MD.8KZ,!W%/"]Z(DB&@+8[LOG -M]N@3\!SPW./!UE`!D[_6U0GIK^DU"E6_)?#%Z*3I5;\VY;';1-:3OR[P^>@G -M\$N_7>TO\#3P1K\V\#/PJ>FX)EW4+.TLZ"SPSS0R\,SHN";XZ";H1?`VZT:_ -M6Q6;ZS?M5C4\Z_[G1K\9ZP+HN"92\"[E5/#7[Y'FLRU/\+3HN";/[POF7?!) -M\&#P'^LEW&+PGNM9V8OM]CXX[0S4DMAH\#L*:O`LW!O7;?!+OR+<;-U4U7+P -M,^U;[3?M*N5&`4:_=NTWY2;P>_`H\/0W*O!Z\&CPR-4MY8#PAO!0`83P9/"! -M\%:_B/!N!:KIC_",\,'5//!0.$/P*>5H\`<&/_!,U9+P:K^C`27PD?`X\#N9 -MB/`K\);PG.BC\%=`H?"%\"/PU(OLU:[PI_#?!:WP,^5! -M\*+GJ?"=\*_P6P2Q\(WPA_!JOX0:?_"F\(OMJ.>]\)GP0K_)\+GPM>`^Z-2+ -MH>ZV[J[FT?`WYM7P.>;7\*SO<^FP!*[KI>_0)-2+K.Y#Z.#PY._C\++NW_!] -MYBWIZ/`OZ>KPO.GL\`7EM>JP!,3KWN]JO_+PXN_4B\GKQ]?T\)KH*^FP!-+K -MT_#G\$'G%.5JO[OJ^?#4BP3QH>_4\'\#*M8SZ,-:"_&5Z`WQY/`*\?OPV_!Y -M#>GP%?'K\!?Q[?`9\>_P1NC#6K#A#/%_`Q_Q#_$A\1'Q9Q6DZ%OJ?P/\ZN3I -M*?$>Z2SQ`>HN\0/J?P,%ZXKI,O$M\>GEA>HU\2+I?P,6[QSI@YDV\3[N@^D[ -M\6WJ?P/%[SWQ1/$V\4?N$>J&F4/Q3!,DZ7\#\.Q!\4WQ+_%2\0COH^I_`^'O -MWO!"OU`3UO!7\27Q>NG3Z]#P)386\=+PM._#6J+B1>=F\;GOB^WRVUSI""0M -M\6SQ./%P\;#L1+_[V]OI])EO\6+N*^HF(T/Q"-QV\:FBS"3IC?$FZ8_Q*.F1\8SQ&.'[[6`*E?%`VI?Q=.I@ -MZ245;>HC%8[Q)N'_Z9_Q`>JC\>S8R`B.UT4.I_'OXC0)JO%NUR$2Q@A+\)\( -M*0D4"6C70X8)`GO8F]<8SK?QL?$,`@<#M/&Y\0H)N_%_UPD)*`&_\6_C7111 -M,[\+;^.O\2<)P_&S\5;IN?%%#J-6P_$T"=/Q==?@6RP)DM?QC"-1">?QF0[P\6C7Z/'S -M\9O7PXSE\>KQ4@E+!TL)FNO[\4,"[?%3">/Q2@EL"777!-#XZMKQ>`"O)V"GP[A/)"/I'R -M++_8Z*HM$T9Z\NX*#D*$\I)$F_(LOPX,1T993GKRE@H\47KR.%&E\BR_VO$! -M2*]2A/)R"K):>O+E5Z_R++_"#5!"%%]Z\JWR`171[Z@$M?*PZ*@$++\9\D8E -MXV5Z\C.\B27CO(GO_[4N?)TGW'R7K\NGICRH9Z8\OCR@?*Z -M%`#SO/+YP$ZGHO)]IZ+R-PJ?\E+G>PKE,6[R4`HG"A'S)R=C,A3S,0J*U"+H -M)X8N"A?S-PK1\AOS-`H=\SH*%_-("N+RT><\P(XT)/,_"B+S!3TJ\RWS&O,H -M\]C@T>\@\S+S)_,Q"OO7,_,5\SCS-O,K"@G8,/,/\S[SL.@2\X\^+O.&$3GS -M52,`)73R!R4%[;GR>2QSFE/SU";@[DWS_B@# -M\^LD'BIW\F,LJ9U3\X,J6O"\\GDL9RM9\](M?0PZ*C4N7/-"+_SRRB\"-V3S -M03"5\@4L`RSP\HALVS)W\IHV*2MO\]?\\]S8?-Y10/SO37BPX?S$T8Q -M)&KSA%61\Z\CM_/T+G_SA$:Q\[WS(@24\\GM9_-%1[/S_TF$\Q1-]2-_\_)* -MP?,23NXDE//Y$*GS2U!@/;GS0O#&\[9;RO/56]OSL%S[\]%=B[TG'HQ]*FO^_-<>U[TTDH; -M]*=\+/3V[;SR+#/F?DWTNG]H]%HX7O1>3VST)3DL].,(2_0T@S'T\0%/]-WR -M.#5>]-D!2?0?A2ST5H<@]-"'7O.LA:#AI/-BB%[T`W$;]&>)+/1])B#TR8LQ -M]*N,^_/%C%[TZ;F3]';T'O3*`CWT^)&,]`:10?3JE*'SX9'4\YB4L?$N9U-C -M(/2*E&_S3)7[\]R5L_,>EP@1&_3\V*SS_)>I\N.8AP,E].^9L?/6 -ME\OL*O03FVKS`EMD]$*=LO1@`^SS?9YT\WX* 0) { - assertEqualMem(buff, image, image_size); - } - if (format_id > 0) { - /* - * Now, read the data back. - */ - /* With the test memory reader -- seeking mode. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - read_open_memory_seek(a, buff, used, 7)); - - if (dot_stored & 1) { - assertEqualIntA(a, ARCHIVE_OK, - archive_read_next_header(a, &ae)); - assertEqualString(".", archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - } - /* - * Read and verify the file. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - if (dot_stored & 2) { - assertEqualString("./file", archive_entry_pathname(ae)); - } else { - assertEqualString("file", archive_entry_pathname(ae)); - } - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(8, archive_entry_size(ae)); - - /* Verify the end of the archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, - archive_filter_code(a, 0)); - assertEqualIntA(a, format_id, archive_format(a)); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - } - free(buff); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_7zip) -{ - test_format_by_name("7zip", "copy", ARCHIVE_FORMAT_7ZIP, 0, - "\x37\x7a\xbc\xaf\x27\x1c\x00\x03", 8); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_ar) -{ - test_format_by_name("ar", NULL, ARCHIVE_FORMAT_AR, 0, NULL, 0); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_arbsd) -{ - test_format_by_name("arbsd", NULL, ARCHIVE_FORMAT_AR, 0, NULL, 0); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_argnu) -{ - test_format_by_name("argnu", NULL, ARCHIVE_FORMAT_AR_GNU, 0, NULL, 0); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_arsvr4) -{ - test_format_by_name("arsvr4", NULL, ARCHIVE_FORMAT_AR_GNU, 0, NULL, 0); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_bsdtar) -{ - test_format_by_name("bsdtar", NULL, ARCHIVE_FORMAT_TAR_USTAR, 0, NULL, 0); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_cd9660) -{ - test_format_by_name("cd9660", NULL, ARCHIVE_FORMAT_ISO9660_ROCKRIDGE, 1, - NULL, 0); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_cpio) -{ - test_format_by_name("cpio", NULL, ARCHIVE_FORMAT_CPIO_POSIX, 0, NULL, 0); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_gnutar) -{ - test_format_by_name("gnutar", NULL, ARCHIVE_FORMAT_TAR_GNUTAR, 0, - NULL, 0); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_iso) -{ - test_format_by_name("iso", NULL, ARCHIVE_FORMAT_ISO9660_ROCKRIDGE, 1, - NULL, 0); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_iso9660) -{ - test_format_by_name("iso9660", NULL, ARCHIVE_FORMAT_ISO9660_ROCKRIDGE, 1, - NULL, 0); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_mtree) -{ - test_format_by_name("mtree", NULL, ARCHIVE_FORMAT_MTREE, 2, NULL, 0); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_mtree_classic) -{ - test_format_by_name("mtree-classic", NULL, ARCHIVE_FORMAT_MTREE, 1, - NULL, 0); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_newc) -{ - test_format_by_name("newc", NULL, ARCHIVE_FORMAT_CPIO_SVR4_NOCRC, 0, - NULL, 0); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_odc) -{ - test_format_by_name("odc", NULL, ARCHIVE_FORMAT_CPIO_POSIX, 0, NULL, 0); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_oldtar) -{ - test_format_by_name("oldtar", NULL, ARCHIVE_FORMAT_TAR, 0, NULL, 0); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_pax) -{ - test_format_by_name("pax", NULL, ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE, 0, - NULL, 0); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_paxr) -{ - test_format_by_name("paxr", NULL, ARCHIVE_FORMAT_TAR_USTAR, 0, NULL, 0); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_posix) -{ - test_format_by_name("posix", NULL, ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE, 0, - NULL, 0); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_rpax) -{ - test_format_by_name("rpax", NULL, ARCHIVE_FORMAT_TAR_USTAR, 0, NULL, 0); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_shar) -{ - test_format_by_name("shar", NULL, -1, 0, - "#!/bin/sh\n# This is a shell archive\n", 36); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_shardump) -{ - test_format_by_name("shardump", NULL, -1, 0, - "#!/bin/sh\n# This is a shell archive\n", 36); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_ustar) -{ - test_format_by_name("ustar", NULL, ARCHIVE_FORMAT_TAR_USTAR, 0, NULL, 0); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_v7tar) -{ - test_format_by_name("v7tar", NULL, ARCHIVE_FORMAT_TAR, 0, NULL, 0); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_v7) -{ - test_format_by_name("v7", NULL, ARCHIVE_FORMAT_TAR, 0, NULL, 0); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_warc) -{ - test_format_by_name("warc", NULL, ARCHIVE_FORMAT_WARC, 0, NULL, 0); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_xar) -{ - test_format_by_name("xar", "gzip", ARCHIVE_FORMAT_XAR, 0, NULL, 0); -} - -DEFINE_TEST(test_archive_write_set_format_by_name_zip) -{ - test_format_by_name("zip", "store", ARCHIVE_FORMAT_ZIP, 0, NULL, 0); -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_write_set_format_filter_by_ext.c b/thirdparty/libarchive/libarchive/test/test_archive_write_set_format_filter_by_ext.c deleted file mode 100644 index 223450386..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_write_set_format_filter_by_ext.c +++ /dev/null @@ -1,211 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * Copyright (c) 2015 Okhotnikov Kirill - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - - -#include "test.h" -__FBSDID("$FreeBSD$"); - -static void -test_format_filter_by_ext(const char *output_file, - int format_id, int filter_id, int dot_stored, const char * def_ext) -{ - struct archive_entry *ae; - struct archive *a; - size_t used; - size_t buffsize = 1024 * 1024; - char *buff; - int r; - - assert((buff = malloc(buffsize)) != NULL); - if (buff == NULL) - return; - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - if( def_ext == NULL) - r = archive_write_set_format_filter_by_ext(a, output_file); - else - r = archive_write_set_format_filter_by_ext_def(a, output_file, def_ext); - if (r == ARCHIVE_WARN) { - skipping("%s format not fully supported on this platform", - archive_format_name(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - free(buff); - return; - } else if (r == ARCHIVE_FATAL && - (strcmp(archive_error_string(a), - "lzma compression not supported on this platform") == 0 || - strcmp(archive_error_string(a), - "xz compression not supported on this platform") == 0)) { - const char *filter_name = archive_filter_name(a, 0); - skipping("%s filter not supported on this platform", filter_name); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - free(buff); - return; - } else { - if (!assertEqualIntA(a, ARCHIVE_OK, r)) { - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - free(buff); - return; - } - } - - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used)); - - /* - * Write a file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 0); - assertEqualInt(1, archive_entry_mtime(ae)); - archive_entry_set_ctime(ae, 1, 0); - assertEqualInt(1, archive_entry_ctime(ae)); - archive_entry_set_atime(ae, 1, 0); - assertEqualInt(1, archive_entry_atime(ae)); - archive_entry_copy_pathname(ae, "file"); - assertEqualString("file", archive_entry_pathname(ae)); - archive_entry_set_mode(ae, AE_IFREG | 0755); - assertEqualInt((AE_IFREG | 0755), archive_entry_mode(ae)); - archive_entry_set_size(ae, 8); - assertEqualInt(0, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualInt(8, archive_write_data(a, "12345678", 8)); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - if (format_id > 0) { - /* - * Now, read the data back. - */ - /* With the test memory reader -- seeking mode. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - read_open_memory_seek(a, buff, used, 7)); - - if (dot_stored & 1) { - assertEqualIntA(a, ARCHIVE_OK, - archive_read_next_header(a, &ae)); - assertEqualString(".", archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - } - /* - * Read and verify the file. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - if (dot_stored & 2) { - assertEqualString("./file", archive_entry_pathname(ae)); - } else { - assertEqualString("file", archive_entry_pathname(ae)); - } - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(8, archive_entry_size(ae)); - - /* Verify the end of the archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, filter_id, - archive_filter_code(a, 0)); - assertEqualIntA(a, format_id, archive_format(a) & ARCHIVE_FORMAT_BASE_MASK ); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - } - free(buff); -} - -DEFINE_TEST(test_archive_write_set_format_filter_by_ext_7zip) -{ - test_format_filter_by_ext("./data/test.7z", ARCHIVE_FORMAT_7ZIP, ARCHIVE_FILTER_NONE, 0, NULL); -} - -DEFINE_TEST(test_archive_write_set_format_filter_by_ext_zip) -{ - test_format_filter_by_ext("./data/test.zip", ARCHIVE_FORMAT_ZIP, ARCHIVE_FILTER_NONE, 0, NULL); -} - -DEFINE_TEST(test_archive_write_set_format_filter_by_ext_jar) -{ - test_format_filter_by_ext("./data/test.jar", ARCHIVE_FORMAT_ZIP, ARCHIVE_FILTER_NONE, 0, NULL); -} - -DEFINE_TEST(test_archive_write_set_format_filter_by_ext_a) -{ - test_format_filter_by_ext("./data/test.a", ARCHIVE_FORMAT_AR, ARCHIVE_FILTER_NONE, 0, NULL); -} - -DEFINE_TEST(test_archive_write_set_format_filter_by_ext_ar) -{ - test_format_filter_by_ext("./data/test.ar", ARCHIVE_FORMAT_AR, ARCHIVE_FILTER_NONE, 0, NULL); -} - -DEFINE_TEST(test_archive_write_set_format_filter_by_ext_cpio) -{ - test_format_filter_by_ext("./data/test.cpio", ARCHIVE_FORMAT_CPIO, ARCHIVE_FILTER_NONE, 0, NULL); -} - -DEFINE_TEST(test_archive_write_set_format_filter_by_ext_iso) -{ - test_format_filter_by_ext("./data/test.iso", ARCHIVE_FORMAT_ISO9660, ARCHIVE_FILTER_NONE, 1, NULL); -} - -DEFINE_TEST(test_archive_write_set_format_filter_by_ext_tar) -{ - test_format_filter_by_ext("./data/test.tar", ARCHIVE_FORMAT_TAR, ARCHIVE_FILTER_NONE, 0, NULL); -} - -DEFINE_TEST(test_archive_write_set_format_filter_by_ext_tar_gz) -{ - test_format_filter_by_ext("./data/test.tar.gz", ARCHIVE_FORMAT_TAR, ARCHIVE_FILTER_GZIP, 20, NULL); -} - -DEFINE_TEST(test_archive_write_set_format_filter_by_ext_tar_bz2) -{ - test_format_filter_by_ext("./data/test.tar.bz2", ARCHIVE_FORMAT_TAR, ARCHIVE_FILTER_BZIP2, 0, NULL); -} - -DEFINE_TEST(test_archive_write_set_format_filter_by_ext_tar_xz) -{ - test_format_filter_by_ext("./data/test.tar.xz", ARCHIVE_FORMAT_TAR, ARCHIVE_FILTER_XZ, 0, NULL); -} - -DEFINE_TEST(test_archive_write_set_format_filter_by_no_ext_def_zip) -{ - test_format_filter_by_ext("./data/test", ARCHIVE_FORMAT_ZIP, ARCHIVE_FILTER_NONE, 0, ".zip"); -} - -DEFINE_TEST(test_archive_write_set_format_filter_by_ext_tar_bz2_def_zip) -{ - test_format_filter_by_ext("./data/test.tar.bz2", ARCHIVE_FORMAT_TAR, ARCHIVE_FILTER_BZIP2, 0, ".zip"); -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_write_set_format_option.c b/thirdparty/libarchive/libarchive/test/test_archive_write_set_format_option.c deleted file mode 100644 index d964df44d..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_write_set_format_option.c +++ /dev/null @@ -1,67 +0,0 @@ -/*- - * Copyright (c) 2011 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -#define should(__a, __code, __m, __o, __v) \ -assertEqualInt(__code, archive_write_set_format_option(__a, __m, __o, __v)) - -static void -test(int pristine) -{ - struct archive* a = archive_write_new(); - int known_option_rv = pristine ? ARCHIVE_FAILED : ARCHIVE_OK; - - if (!pristine) - archive_write_set_format_iso9660(a); - - /* NULL and "" denote `no option', so they're ok no matter - * what, if any, formats are registered */ - should(a, ARCHIVE_OK, NULL, NULL, NULL); - should(a, ARCHIVE_OK, "", "", ""); - - /* unknown modules and options */ - should(a, ARCHIVE_FAILED, "fubar", "snafu", NULL); - should(a, ARCHIVE_FAILED, "fubar", "snafu", "betcha"); - - /* unknown modules and options */ - should(a, ARCHIVE_FAILED, NULL, "snafu", NULL); - should(a, ARCHIVE_FAILED, NULL, "snafu", "betcha"); - - /* ARCHIVE_OK with iso9660 loaded, ARCHIVE_WARN otherwise */ - should(a, known_option_rv, "iso9660", "joliet", NULL); - should(a, known_option_rv, "iso9660", "joliet", NULL); - should(a, known_option_rv, NULL, "joliet", NULL); - should(a, known_option_rv, NULL, "joliet", NULL); - - archive_write_free(a); -} - -DEFINE_TEST(test_archive_write_set_format_option) -{ - test(1); - test(0); -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_write_set_option.c b/thirdparty/libarchive/libarchive/test/test_archive_write_set_option.c deleted file mode 100644 index 27782342f..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_write_set_option.c +++ /dev/null @@ -1,69 +0,0 @@ -/*- - * Copyright (c) 2011 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -#define should(__a, __code, __m, __o, __v) \ -assertEqualInt(__code, archive_write_set_option(__a, __m, __o, __v)) - -static void -test(int pristine) -{ - struct archive* a = archive_write_new(); - int known_option_rv = pristine ? ARCHIVE_FAILED : ARCHIVE_OK; - - if (!pristine) { - archive_write_add_filter_gzip(a); - archive_write_set_format_iso9660(a); - } - - /* NULL and "" denote `no option', so they're ok no matter - * what, if any, formats are registered */ - should(a, ARCHIVE_OK, NULL, NULL, NULL); - should(a, ARCHIVE_OK, "", "", ""); - - /* unknown modules and options */ - should(a, ARCHIVE_FAILED, "fubar", "snafu", NULL); - should(a, ARCHIVE_FAILED, "fubar", "snafu", "betcha"); - - /* unknown modules and options */ - should(a, ARCHIVE_FAILED, NULL, "snafu", NULL); - should(a, ARCHIVE_FAILED, NULL, "snafu", "betcha"); - - /* ARCHIVE_OK with iso9660 loaded, ARCHIVE_WARN otherwise */ - should(a, known_option_rv, "iso9660", "joliet", NULL); - should(a, known_option_rv, "iso9660", "joliet", NULL); - should(a, known_option_rv, NULL, "joliet", NULL); - should(a, known_option_rv, NULL, "joliet", NULL); - - archive_write_free(a); -} - -DEFINE_TEST(test_archive_write_set_option) -{ - test(1); - test(0); -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_write_set_options.c b/thirdparty/libarchive/libarchive/test/test_archive_write_set_options.c deleted file mode 100644 index db7e50e7f..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_write_set_options.c +++ /dev/null @@ -1,126 +0,0 @@ -/*- - * Copyright (c) 2011 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -#define should(__a, __code, __opts) \ -assertEqualInt(__code, archive_write_set_options(__a, __opts)) - -static void -test(int pristine) -{ - struct archive* a = archive_write_new(); - int halfempty_options_rv = pristine ? ARCHIVE_FAILED : ARCHIVE_OK; - int known_option_rv = pristine ? ARCHIVE_FAILED : ARCHIVE_OK; - - if (!pristine) { - archive_write_add_filter_gzip(a); - archive_write_set_format_iso9660(a); - } - - /* NULL and "" denote `no option', so they're ok no matter - * what, if any, formats are registered */ - should(a, ARCHIVE_OK, NULL); - should(a, ARCHIVE_OK, ""); - - /* unknown modules and options */ - should(a, ARCHIVE_FAILED, "fubar:snafu"); - assertEqualString("Unknown module name: `fubar'", - archive_error_string(a)); - should(a, ARCHIVE_FAILED, "fubar:snafu=betcha"); - assertEqualString("Unknown module name: `fubar'", - archive_error_string(a)); - - /* unknown modules and options */ - should(a, ARCHIVE_FAILED, "snafu"); - assertEqualString("Undefined option: `snafu'", - archive_error_string(a)); - should(a, ARCHIVE_FAILED, "snafu=betcha"); - assertEqualString("Undefined option: `snafu'", - archive_error_string(a)); - - /* ARCHIVE_OK with iso9660 loaded, ARCHIVE_FAILED otherwise */ - should(a, known_option_rv, "iso9660:joliet"); - if (pristine) { - assertEqualString("Unknown module name: `iso9660'", - archive_error_string(a)); - } - should(a, known_option_rv, "iso9660:joliet"); - if (pristine) { - assertEqualString("Unknown module name: `iso9660'", - archive_error_string(a)); - } - should(a, known_option_rv, "joliet"); - if (pristine) { - assertEqualString("Undefined option: `joliet'", - archive_error_string(a)); - } - should(a, known_option_rv, "!joliet"); - if (pristine) { - assertEqualString("Undefined option: `joliet'", - archive_error_string(a)); - } - - should(a, ARCHIVE_OK, ","); - should(a, ARCHIVE_OK, ",,"); - - should(a, halfempty_options_rv, ",joliet"); - if (pristine) { - assertEqualString("Undefined option: `joliet'", - archive_error_string(a)); - } - should(a, halfempty_options_rv, "joliet,"); - if (pristine) { - assertEqualString("Undefined option: `joliet'", - archive_error_string(a)); - } - - should(a, ARCHIVE_FAILED, "joliet,snafu"); - if (pristine) { - assertEqualString("Undefined option: `joliet'", - archive_error_string(a)); - } else { - assertEqualString("Undefined option: `snafu'", - archive_error_string(a)); - } - - should(a, ARCHIVE_FAILED, "iso9660:snafu"); - if (pristine) { - assertEqualString("Unknown module name: `iso9660'", - archive_error_string(a)); - } else { - assertEqualString("Undefined option: `iso9660:snafu'", - archive_error_string(a)); - } - - archive_write_free(a); -} - -DEFINE_TEST(test_archive_write_set_options) -{ - test(1); - test(0); -} diff --git a/thirdparty/libarchive/libarchive/test/test_archive_write_set_passphrase.c b/thirdparty/libarchive/libarchive/test/test_archive_write_set_passphrase.c deleted file mode 100644 index 4bfcbb2c2..000000000 --- a/thirdparty/libarchive/libarchive/test/test_archive_write_set_passphrase.c +++ /dev/null @@ -1,95 +0,0 @@ -/*- - * Copyright (c) 2011 Tim Kientzle - * Copyright (c) 2014 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -struct archive_write; -extern const char * __archive_write_get_passphrase(struct archive_write *); - -static void -test(int pristine) -{ - struct archive* a = archive_write_new(); - struct archive_write* aw = (struct archive_write *)a; - - if (!pristine) { - archive_write_add_filter_gzip(a); - archive_write_set_format_iso9660(a); - } - - assertEqualInt(ARCHIVE_OK, archive_write_set_passphrase(a, "pass1")); - /* An empty passphrase cannot be accepted. */ - assertEqualInt(ARCHIVE_FAILED, archive_write_set_passphrase(a, "")); - /* NULL passphrases cannot be accepted. */ - assertEqualInt(ARCHIVE_FAILED, archive_write_set_passphrase(a, NULL)); - /* Check a passphrase. */ - assertEqualString("pass1", __archive_write_get_passphrase(aw)); - /* Change the passphrase. */ - assertEqualInt(ARCHIVE_OK, archive_write_set_passphrase(a, "pass2")); - assertEqualString("pass2", __archive_write_get_passphrase(aw)); - - archive_write_free(a); -} - -DEFINE_TEST(test_archive_write_set_passphrase) -{ - test(1); - test(0); -} - - -static const char * -callback1(struct archive *a, void *_client_data) -{ - int *cnt; - - (void)a; /* UNUSED */ - - cnt = (int *)_client_data; - *cnt += 1; - return ("passCallBack"); -} - -DEFINE_TEST(test_archive_write_set_passphrase_callback) -{ - struct archive* a = archive_write_new(); - struct archive_write* aw = (struct archive_write *)a; - int cnt = 0; - - archive_write_set_format_zip(a); - - assertEqualInt(ARCHIVE_OK, - archive_write_set_passphrase_callback(a, &cnt, callback1)); - /* Check a passphrase. */ - assertEqualString("passCallBack", __archive_write_get_passphrase(aw)); - assertEqualInt(1, cnt); - /* Callback function should be called just once. */ - assertEqualString("passCallBack", __archive_write_get_passphrase(aw)); - assertEqualInt(1, cnt); - - archive_write_free(a); -} diff --git a/thirdparty/libarchive/libarchive/test/test_bad_fd.c b/thirdparty/libarchive/libarchive/test/test_bad_fd.c deleted file mode 100644 index f8144a3c3..000000000 --- a/thirdparty/libarchive/libarchive/test/test_bad_fd.c +++ /dev/null @@ -1,37 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/lib/libarchive/test/test_bad_fd.c,v 1.2 2008/09/01 05:38:33 kientzle Exp $"); - -/* Verify that attempting to open an invalid fd returns correct error. */ -DEFINE_TEST(test_bad_fd) -{ - struct archive *a; - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(ARCHIVE_FATAL == archive_read_open_fd(a, -1, 1024)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_compat_bzip2.c b/thirdparty/libarchive/libarchive/test/test_compat_bzip2.c deleted file mode 100644 index 7df086ff3..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_bzip2.c +++ /dev/null @@ -1,89 +0,0 @@ -/*- - * Copyright (c) 2003-2008 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_compat_bzip2.c 201247 2009-12-30 05:59:21Z kientzle $"); - -/* - * Verify our ability to read sample files compatibly with bunzip2. - * - * In particular: - * * bunzip2 will read multiple bzip2 streams, concatenating the output - * * bunzip2 will stop at the end of a stream if the following data - * doesn't start with a bzip2 signature. - */ - -/* - * All of the sample files have the same contents; they're just - * compressed in different ways. - */ -static void -compat_bzip2(const char *name) -{ - const char *n[7] = { "f1", "f2", "f3", "d1/f1", "d1/f2", "d1/f3", NULL }; - struct archive_entry *ae; - struct archive *a; - int i; - - assert((a = archive_read_new()) != NULL); - if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) { - skipping("Unsupported bzip2"); - return; - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - extract_reference_file(name); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 2)); - - /* Read entries, match up names with list above. */ - for (i = 0; i < 6; ++i) { - failure("Could not read file %d (%s) from %s", i, n[i], name); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_next_header(a, &ae)); - assertEqualString(n[i], archive_entry_pathname(ae)); - } - - /* Verify the end-of-archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify that the format detection worked. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_BZIP2); - assertEqualString(archive_filter_name(a, 0), "bzip2"); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_BZIP2); - assertEqualString(archive_filter_name(a, 0), "bzip2"); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR); - - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - -DEFINE_TEST(test_compat_bzip2) -{ - compat_bzip2("test_compat_bzip2_1.tbz"); - compat_bzip2("test_compat_bzip2_2.tbz"); -} - - diff --git a/thirdparty/libarchive/libarchive/test/test_compat_bzip2_1.tbz.uu b/thirdparty/libarchive/libarchive/test/test_compat_bzip2_1.tbz.uu deleted file mode 100644 index 989af82b2..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_bzip2_1.tbz.uu +++ /dev/null @@ -1,24 +0,0 @@ -$FreeBSD: head/lib/libarchive/test/test_compat_bzip2_1.tbz.uu 185683 2008-12-06 07:08:08Z kientzle $ - -begin 644 test_compat_bzip2_1.tbz -M0EIH.3%!62936;12^)(``#-;D=$00`!_@``!8RT>$`0`$```""``5#5/*'J> -MD#(&30_5!H4_5-ZH`T``327U4@&L('"(9-%8<7&$I,`:7FXH+*\GV#JF<`PK29-8'OPDG36S\7HR&C(T:/U0:$U'I -MJ!ZC0`#VECO\[$10H'-Z@F*:6A1$H$V("2G0Q(U0(8=(7AK$S04#!)RXOAP% -MP:D%#Q;NO)\4UL23'2[\7````6YC1 -M$$`$?X```6,M'A`$`!````@@`'4-4S*,U!HT!HT?J@T)E-I--!H`![60EIH.3%!629364RNM^,```#?L-$00`#_@`0```AG -M+1X0`!`$```((`!U#5-,:1IH`TT,1^J#)&H]3U`T``!CX[_.[`F40.64EC"D -M()+?KX6,VP?6Y;F%5$XR[Y/D#*9),K3^+N2*<*$@9@ -MX6(`0EIH.3%!62936>ZM4*4```);D-$00`#O@``(9ST>$`0```@@`'0:IFC2 -M&F@!B:/U0:$R&H:&@`"KS^U=Y`BC`#FY2*9-8%%&13E$@%8ZF(&J!##]!#E` -MKVL'2LUW2.*C08`$)::#DQ05DF -?4UDI/)=P````0!!```0`(``A`(*#%W)%.%"0*3R7<``` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_compat_bzip2_2.tbz.uu b/thirdparty/libarchive/libarchive/test/test_compat_bzip2_2.tbz.uu deleted file mode 100644 index 9ba63e877..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_bzip2_2.tbz.uu +++ /dev/null @@ -1,11 +0,0 @@ -$FreeBSD: head/lib/libarchive/test/test_compat_bzip2_2.tbz.uu 185683 2008-12-06 07:08:08Z kientzle $ - -begin 644 test_compat_bzip2_2.tbz -M0EIH.3%!629361HI1P<``4#;D-$00`#_@``)9RT>$`0``!@P`/@#&$Q,F`F` -M`,83$R8"8``1133"1/2-J-#$/U3@;XVF9V'`Y3882XA$*KO6\WTL`]QU&J"8 -M$-=*Q$\@=`=QJ,TQ;3UH,NPT$-(!"HV&!ZO5D&@P-1D&1@'L<8&209QV9'G` -MW&PRZ0Q(-BT%&DG*DE.!U*#J.P]*#%-P9G`W9+34:#S&M`;@^1R^![C]:Y)U -MDF9/(\AR/@?P@^@I_B[DBG"A(#12C@X!3;VUE(&UOV=QL!06ER26`1T2G9F:EY)54XJ -MN>9`/*(`IX<(2#/D&F@GC`(Z``#S57',@'E&`TT,$I!EQ -M#;031@$5`0`Q!<\4Z`,``!^+"`B8OB))``-T97-T+7-P;&ET+G1A$0!3@\1D&;,-=!.&`5D``#7L]HO -MZ`,``!^+"`B8OB))``-T97-T+7-P;&ET+G1A57',@'E&`TT,$I!ER#;031@$>``"Y*#OBZ`,``!^+"`B8 -MOB))``-T97-T+7-P;&ET+G1A@ALXPP`]CXF=Q&A<:-UX>EN)C5M,AL;P -MO@V[0A=_.E39F2.B'*.?5QX2?Z\?XGE&27)F]L0)V>E_'7YY07\>OZ)Y1W6Q\!-J3!?H^Z_J7TG]%_"QK0?\]4[/>HZS^_^T\! -M_;>@@OY[=N2]6E\!JOH/P])_2OC^-X'YOV]+_]97@*K^A4K_C/Y;P/S?MZ5_ -MZRM`7?]<^L?_OR8P_P,`].D%,XR2*0`<``!4:&ES(&ES('5NFQE%0`/ -M`@`@`LL``-T```(`'R!"`"`/`@!B/V8Q"G@`8@\"`/]V+V8RB@%/#P`$&Q(S -M``0?-@`$_U4?,@`$_^T?,P`$?1$V``0O-3(`!/]5'S,`!/_G4``````````` -M`";]7\`$(DT89'"YL@```&]D,2]F,0`!`$OH,#`P-C0T(``P,#$W-3$(``0" -M`/\(,R`Q,3$Q,#4S-C8R-R`P,3$U-38`(#"7`$L"`@#R`75S=&%R`#`P:VEE -M;G1Z;&46``\"`!\"RP``W0```@`?($$`'P\"`&,_9C$*>0!C#P(`_W4```0? -M,HP!3`\`!!HB,S``!!\Q``3_51\R``3_\!\S``1Z$C$`!!\S``3_51\S``3_ -6[`\"`/___^M0````````````;,,BR0`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_compat_lz4_2.tar.lz4.uu b/thirdparty/libarchive/libarchive/test/test_compat_lz4_2.tar.lz4.uu deleted file mode 100644 index 5efdd74a4..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_lz4_2.tar.lz4.uu +++ /dev/null @@ -1,13 +0,0 @@ -begin 644 test_compat_lz4_2.tar.lz4 -M!")-&&1PN:8````_9C$``0!.Z#`P,#8T-"``,#`Q-S4Q"``$`@#_"#,@,3$Q -M,3`U,S8V,3$@,#$Q,C0S`"`PF@!.\00```!UFQE%0`/ -M`@`@`LL``-T```(`'R!"`"`/`@!B/V8Q"G@`8@\"`/]V+V8RB@%/#P`$&Q(S -M``0?-@`$_U4?,@`$_^T?,P`$?1$V``0O-3(`!/]5'S,`!/_G4``````````` -M`";]7\`$(DT89'"YL@```&]D,2]F,0`!`$OH,#`P-C0T(``P,#$W-3$(``0" -M`/\(,R`Q,3$Q,#4S-C8R-R`P,3$U-38`(#"7`$L"`@#R`75S=&%R`#`P:VEE -M;G1Z;&46``\"`!\"RP``W0```@`?($$`'P\"`&,_9C$*>0!C#P(`_W4```0? -M,HP!3`\`!!HB,S``!!\Q``3_51\R``3_\!\S``1Z$C$`!!\S``3_51\S``3_ -M[`\"`/___^M0````````````;,,BR51H:7,@:7,@=6YR96QA=&5D(&IU;FL@ -<9&%T82!A="!T:&4@96YD(&]F('1H92!F:6QE"@`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_compat_lz4_3.tar.lz4.uu b/thirdparty/libarchive/libarchive/test/test_compat_lz4_3.tar.lz4.uu deleted file mode 100644 index 97e79fb6e..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_lz4_3.tar.lz4.uu +++ /dev/null @@ -1,9 +0,0 @@ -begin 644 test_compat_lz4_3.tar.lz4 -M`B%,&/X````_9C$``0!.Z#`P,#8T-"``,#`Q-S4Q"``$`@#_"#,@,3$Q,3`U -M,S8V,3$@,#$Q,C0S`"`PF@!.\00```!UFQE%0`/`@`@ -M`LL``-T```(`'R!"`"`/`@!B/V8Q"G@`8@\"`/]V+V8RB@%/#P`$&Q(S``0? -M-@`$_U4?,@`$_^T?,P`$?1$V``0O-3(`!/]5'S,`!/_L/V0Q+P,,3@\`"!H@ -M,C<`!"\U-0`(_U8/``S_[0``!`\##$T/``0:(C,P``0?,0`(_U4/``S_[0`` -E!`\##$T/``0;`0`4+S4U`!3_5@\`#/_M#P(`____ZU`````````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_compat_lz4_B4.tar.lz4.uu b/thirdparty/libarchive/libarchive/test/test_compat_lz4_B4.tar.lz4.uu deleted file mode 100644 index 329a85349..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_lz4_B4.tar.lz4.uu +++ /dev/null @@ -1,6739 +0,0 @@ -begin 644 test_compat_lz4_B4.tar.lz4 -M!")-&&1`IY41``!O>&9I;&4``0!+X3`P,#8T-"``,#`P-S8U"``B,#(0`"(R -M,`$`_P<@,3(S-3,U-3,U,3(@,#$R,#(S`"`PEP!+`@(`KW5S=&%R`#`P8W4' -M`0M22T`5RH@8V%T:0`K871H`&!S:6UP;&5H`@6U`$!T;V]L -M,P$`0``#`@!R>F-A="P@8@<`$G@'``!)`4!S=6-H)P!0*B!E>&%)`$!S.B!3 -M,@-46]U(&UA>2!F:6YDT`(Q9G5L+P(&10!1 -M+VUI;FF%`1%AXP%186-T('-@`*$@9&5M;VYS=')AP0$`#@,G;V9>`0-)`#!C -M;VY#`O`".B`@5F%R:6]UP``"@+Q`F%U=&AO7-T96TZ"B`J(+@$=2XQ(&5X<&R# -M`@,O`P!"`0(A``2:`P,S``"(!`\T``L`(@`,-0`O870T``PH870S``8!!H`N -M,R!G:79E<]\&@&]V97)V:65W\P(`H``$NP4087$%,'=H;Y$"(RH@V0>%7W)E -M860N,RP0``#1!1UE$0!17V1I]!;!I;@IA(&YU;6)E`D09BP``;<&42H@1TY5=0$" -M-0(F("@$"P`:`$%L;VYG4`9B;F%M97,L$```!0L3(!$``&,`4G-P87)S?`(A -M`@@;W#+`\!A;"!2;V-KB,``!DT%``)"`$```I58W)E873/ -M``%U!`\&`0("J@,#OP,"O`(/'P,8,")R9:`-46-T960B1P,"3P#$+"!W:&EC -M:"!W:6QLB@`!5@`%R@%A(&5X8V5P0`4`N04$:0)1('1H871##C%I\+`OH#`*D"!B($`88!`MH` -M#Y8#!0'(`V$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0%!`);`0&)``]9`P`* -M%@,S5VAE`P((T0X"Y@5A`3AN97>U`P#P!`![``-S!`![``&'"0&C``)*#`!-$2)I -M7-S""IE9(H(`D<`<$DG=F4@870M#0",!S!T;R`A$+)M -M:7IE('-T871I8U((07!O;&PV$E$N("!)9O4(061O;B<<$Y!E>'!L:6-I=&S9 -M"4!V;VMEO!(!ZP`!?PH#SA$@("C2$"4@8?L*`*D`("!AL@$!)Q`"+0`(S0`4 -M;Y4(<"DL(&ET('=P`$$@9V5T&1,!70H`I`0W($EN;@`W+"!IG@`!40$#FP`B -M96[)`07L#$7`U`-%A=&5V97(@8FQO8VMS\```[@2X'<70@ -M82!T:6U7`W%O@``S0)P82!S;V-K9687`CX#27=I4X.``P1$2(A`0!:""`L(E`(H"P@8V%P86)I;&D2%`8# -M`07Q``+S#P&W!`CV!0&7`8`@:6YD:79I9&P.`]L(`(4``#H2`D(``*P+`-$` -M`#8!(71OK`TP9&%TUP``!0X6.BX!`L@)`#T`$F'L`@#)"@$K`#-I;B`G`0"/ -M`C!A9&1T!`!,``CW#`&I"@,>#U%F:7)S=)("`*8!$6%P$A%O\0T`]@`6+G0` -M`]D#`J0#`',*`.$G;71R964G(&9O -M$E33SDV-C`3`%HW+5II<#D`-EA!4A$`Y0I7:&5N(&-R96%T:6YG -M&`#Q&2P@=&AE(')EFEPX0`Q:6]N%0!=8GII<#(6 -M``0'`4TO3%I7'0"Q;'IM82P@;'II<"P4`2EX>B,`P0I.;W1E7-T96TN("!4:&5R92P`@&YO(&1I'!L86EN:6YGR0`P:&]W^``"]0`'+``"*@$A3VZJ`!PL`P$`48!`-T!\@%E9"!A=71O;6%T:6-A;&QY1P"P22=V92!A='1E -M;7#7`>!T;R!M:6YI;6EZ92!S="L`L"!L:6YK('!O;&QUN`'A+B`@268@>6]U -M(&1O;B?L`0"V`/$":6-I=&QY(&EN=F]K92!A('#K`(!U;&%R(&9E85D"0"`H -MD`!RT`!.<#`R("`ID!<"DL(&ET('=P`/``(&=E="!P=6QL -M960@:6XN/@`G26YN`#``%1`0.;`")E;LD!!RT``#X`"W$`*&1E$0`# -MQ@(1+/```H``(FYEC@(`%@$`0`!B86=A:6YS1P*@8V]R7L#$7`U`-%A=&5V97(@8FQO8VMS\``0:%<%(6ETH0!!66]U -M717`F$@82!T:6U7 -M`W%O`+$@(&)S9'1AX`0!V``*4`0"A`P&3``)/!R)L>8<``J,!!H`%,7=A;H@`$'0V!`5%`0!@ -M`!!IA0(`C@%EB!$!GF-A="P@8@<`$G@'``!)`0"2 -M"0`G`%`J(&5X84D`0',Z(%,R`U1S;6%L;!4`!#X!`%(#(6%T'`@@;6'F!"!N -M9-`",69U;"\"!D4`$"]#"@&%`1%AG@I186-T('-@`)(@9&5M;VYS=')*#0`I -M!B=O9EX!`TD`,&-O;D,"\`(Z("!687)I;W5S(&ET96US(#,!`'T#0&UE(&(W -M`3)I0&";8"(FENU@0`I`H`ZP4$O0+P`DY% -M5U,@+2!H:6=H;&EG:'1S7`8PH($',+!0$^`0!U```7`@#Y!`%Q -M``%Q"@B7```\"3-Y+C--``#O!#)E(")K`P6K``$D`!0B"PM9(&-L87-$``$? -M"49N86QSG0`2!Q(M@@0U]!9!I;@IA -M(&YU;6+R#!=FD0<$.P''"@I9;W4@ -M`*%35E(T($%30TE)=`(!%``/,@`+$$)M$1%Y+@"Q("AB:6%T`/ -M"Q<`T$UI8W)O"T4``("`+D%!(D1`@L7`UH7`5$`!>D2,',@*%,*`30$`(0!`S,$`/0#8"P@ -M971C*>\+`OH#`&P$`&T``HT``9L!`MH`#\@#"F$B;F5W8R*;`P$S`"=S:+`` -M`1(`#T8#8P0%!`?.``]9`P`*%@,/9!K_____________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________XE!E=&%I;%H1``#U'G,@=&AE -M(")S=')U8W0@87)C:&EV95]E;G1R>2(@=71I;&ET>2!C;&%SP#S"2P@:6YC;'5D:6YG -M(&AA``"/`/0:("=D;V,G -M(&1I2!I;@IA(&YU;6)E6]U(#\!8"X*"D-U\!`DD` -M-%I)4%8#!$``P'5N8V]M<')EB,``!DT%``) -M"`&58V%N(&-R96%TSP`!=00/!@$"`J\!`[\#`KP"#Q\#&,$B!S>7-T96TN("!4 -M:&5R92P`(VYOX@<`@@(#WP@`DP3R`B!I;BUP;&%C92!M;V1I9FECK0CS`F]R -M(')A;F1O;2!A8V-E0`&@`3R`FES(&1EP`#P`!APD!HP!4(&]N;'D*`P`X"`"R``$>`P"F -M!`(,`B$@8C<)<7)E861A8FP`!D%W48!`-T!*F5DB@@"1P"P22=V92!A='1E;7",!^!T;R!M:6YI -M;6EZ92!S=+4(`E((4'!O;&QU(@=1+B`@26;U"$!D;VXGU@7L#$7`U`-%A=&5V97(@8FQO8VMS\``` -M[@2X'<70@82!T:6U7`P!K"S%M87#X`C!E;G21!@/0`@%1`T!G:79EY@$A=&\B -M``6A`&%T(&]N8V6%`"%/;I`#&V7#``+D`C)P@``P0&%82!S;V-K970^`TEW:7-HN@0!)@\# -M60\`0#`',*T2!S87ES+@I214%$3442!@9)$>$@8G5N9&QE+@H*475E<_H" -MH#\@($ES8$(&YDT`(Q9G5L -M+P(&10`0+T,*`84!$6&>"C1A8W1[$W!D96UO;G-T.14@;F<^``"`!094`@-) -M`#!C;VY#`F$Z("!687+N$V!I=&5M$0(8 -M`&!C;VYF:6=^"Q4M#``"1`"UM`Q$SM@L`$!20(&]V97)V:65W\P(`JP`%P`L`<04P=VAOD0(4*J0* -MA5]R96%D+C,L$``!^`@-$0!17V1I2#R`I!I;VYS+@H*5&B=`?("<"UL979E;"!D:7)E8W1O'2(`#!P=71>`H$@(F-M86ME(B0#:60@ -M=&]O;$T``E8!!NL#`2D!,2!I;DP!#VT!`3!A2!N965D?``Q;6%I]@$C97)<`05P`"1I;F0`\@,N:"YI -M;@H)+2!T96UP;&%T97-G`!%B-`(!9@$39;4`8`H*1W5I9/,`4"!$;V-UF04" -M@0$`Q0$R86QL=0`!MP&R'!L@P(#+P,`0@$" -M(0`$F@,#,P``B`0/-``+`"(`##4`+V%T-``,*&%T,P`&`0:`+C,@9VEV97/? -M!H!O=F5R=FEE=_,"`*``!+L%$&%Q!3!W:&^1`B,J("X'A5]R96%D+C,L$``` -MT04=91$`45]D:7-K%@`@;F30`0@^``,<``"9`!!V7P$"MP)A960@8V%LB0<0 -M<]0&06YC97.M`@"3``!U``%'``-"!FAE($%027.7`'-E;G1R>2XS30`"]P,2 -M(FL#!:L``20`4"(@=71II`59(&-L87-$``'O!49N86QSG0`P] -M!;!I;@IA(&YU;6)E`D09BP``;<&42H@1TY5=0$"-0(B -M("BK"0"Y`0`:`$%L;VYG4`9B;F%M97,L$`!3;&EN:R`1``!C`%)S<&%R'1E;J+``-J -M`0`9`]$J(%!/4TE8('5S=&%R6P`"$``R<&%X-`,"60<#>`('(0#`;V-T970M -M;W)I96YT%P0@<&E^"<8J(%-64C0@05-#24D4``)3``\R``5A0FEN87)Y+@#` -M("AB:6B,``!DT%``)"`$```I58W)E873/ -M``%U!`\&`0("J@,#OP,"O`(/'P,8,")R9:`-46-T960B1P,"3P#$+"!W:&EC -M:"!W:6QLB@`!5@`%R@%A(&5X8V5P0`4`N04$:0)1('1H871##C%I\+`OH#`*D"!B($`88!`MH` -M#Y8#!0'(`V$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0%!`);`0&)``]9`P`* -M%@,S5VAE`P(`?`4#U`(2<^8%87)E`3AN97>U`P#P!`![``.?`0![``&'"0&C``)*#`!- -M$2)IF4@ -M``%1`0.;`")E;LD!!RT``'P`"W$`*&1E$0`#Q@(1+/```H```(T.`)8!`!8! -M`$``,&%G82X.`?$)D6-OP,1<#4`T6%T979E$P$/`P*A%0"V`A!GJA40:2(3 -M`2(`!4H``.,3(6-EA0`A3VZ0`QMEPP`"Y`(R<')O.@$!A0%18W1L>2W,`))E -M9"!O=71P=73O`@!@!/$#;V)J96-T+7-T>6QE(&%P<')OR`,`^10"^@!0=&\@ -M:&$Y%D!U;'1IPQ,$J0`"`00`N0A5(&]P96Z>`!,@%1``:A``"@$`/06#;B!I -M=',@(D`\`!(BO0012!F4X.``P1$2(A`0!:""`L(E`(H"P@8V%P86)I -M;&D2%`8#`07Q``+S#P$_#@CV!0&7`8`@:6YD:79I9&P.`]L(`(4``#H2`D(` -M`*P+`-$``#8!(71OK`TP9&%TUP``!0X6.BX!`L@)`#T`$F'L`@#)"@$K`#-I -M;B`G`0"/`C!A9&1T!`!,``CW#`&I"@,>#U%F:7)S=)("`*8!$6%P$A%O\0T` -M]@`6+G0``]D#`J#B)A;N@"`*4'!C0*$"QC`$!D97-PH@``;`0!Y`,`7,N"B05 -M$6:X#06Y&0*A&$0N"@I1$19`/R`@2:T9(',_4@`4*I491G=W=RXX`$`N;W)G -MDP``2`$0:+@"`%<`0V]N9V]8!Q<@3`<@(&18%B!O<#P%"!D1!+H1`:P(`3<, -M`'$``#H`'VYD&O______________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________:E!I=F4@92@1``#Q$6YT7,@9&5T96-T960@ -M875T;VUA=&EC86QL>4<`L$DG=F4@871T96UP(@#@=&\@;6EN:6UI>F4@6]U(&1O;B=TJ```M@#Q`FEC:71L -M>2!I;G9O:V4@82!PZP#P#G5L87(@9F5A='5R92`H``%1`0.;`%IE;F%B;)L``#X`"W$`*&1E$0`#J@`1 -M+/```H``(FYE)@$`%@$`0`!Q86=A:6YS=,\!V6-O8`0U: -M`)%L:6)R87)I97/#`/$"5&AI3X`!8P``+$!\09P"!I;G1E7,N"E)%041-12X`!^@& -MX2!B=6YD;&4N"@I1=65S^@*@/R`@27-S=65S/U(`UBH@:'1T<#HO+W=W=RY, -M!T`N;W)GDP``2`$0:+@"@V9O0(1.FH` -M$B>7!9`G('!R;V=R86T6`G-A(&9U;&PME@AP9"`G=&%R)WX``P(`4W)E<&QA -M0@%`8G5I;($&`(H``V,``"H`9BH@8W!I;V,```X`"V0`(&1I:P4R96YT,`-# -M9F%C96H#`P(`,&5S`<``$D!`)()`"<` -M4"H@97AA20!`8$(&YDT`(Q -M9G5L+P(&10`0+T,*`84!$6$&"5%A8W0@`0-)`#!C;VY#`O`".B`@5F%R:6]UP``7P%Q875T:&]R<\`%`1\&`?("`DT' -M$`J(!E!T;W`M;`P$`W8%`#`'`4$`$&GD!@FV`B)I;M8$`'$+`.L%!+T"\`). -M15=3("T@:&EG:&QI9VAT=&%R+C54`0CQ!$%A8F]U4P41]!9!I;@IA(&YU;6+R#!=FD0<$.P''"@I9;W4@`D09@82`;<&42H@1TY5=0$"-0(F("@$"P`:`"-L;[P%`*T+(G,L -M$```!0L3(!$``&,`4G-P87)S?`(A`*%35E(T($%30TE)=`(!%``/,@`+$$)M$1%Y -M+@"Q("AB:6`@@;W#+`\!A;"!2;V-K[`@0]`5HW+5II<"8`V$UI8W)OFEP/@$@:6]/$WTJ(&)Z:7`R -M%@`$?`%-+TQ:5QT`HFQZ;6$L(&QZ:7`3`R]X>B,``!DT%``)"`$```H"G!`% -M.@$`=00/!@$"`J\!`[\#`KP"#Q\#&#`B0`&@`0I:7-N%")B98@%`$`$`5X!.&YE -M=[4#`/`$`/T"`Y\!`'L``8<)`,,7$F5*#`!-$2)I2!D971E8W1S(&%N9"!R96%D -MFEP/@$Q:6]N!0%=8GII<#(6``1D`4TO3%I7'0"B -M;'IM82P@;'II0`&EP"0:7,@9&5S:6=NH@9";R!B98@%`$`$`3`$.&YE=[4#`/`$ -M`'L``4,` -M4&EN9&5PJ@`B;G1_`!!R.P0`!``P=&EC0@4D;VZ!`02N`/``5VEK:2!E>'!L -M86EN:6YGB0`P:&]W^``!LP,09)8%`RP``BH!(4]N/P@<+`,!``0$,FUA='`` -M0&QW87E&`0#=`2IE9(H(`D<`L$DG=F4@871T96UPC`?@=&\@;6EN:6UI>F4@ -M2!I -M;G9O:V4@82!PZP`@=6R]"*!E871U``%1 -M`0.;`")E;LD!!RT``'P`"W$`*&1E$0`#J@`1+/```H``(FYEC@(`%@$`0`!Q -M86=A:6YS=,\!D6-OP,1<#4`T6%T979E`%`@(&)S9",' -M(75SO`$`/06#;B!I=',@(D#E`!(BO01&"2`L(E`(<"P@8V%P86)!``'V`@)F!A%E50(!\0!A92!!4$ES -MMP0(]@4!EP&Q(&EN9&EV:61U86QH!1%I0@@`>P`28D(``$X&`-$``#8!(71O -MFPDP9&%TUP!6=7)C93HN`0+("0#"`!)A[`(`R0H!*P`S:6X@)P$`E0LS861D -MC@(88?<,`=<'(6]U]P119FER0"0:7,@97-P96-I;@0!T`$"J@$`.@@P.B`BDPH.V@T3(KD"`-X. -M(F%NZ`(`I0<`$0,"P040+&,`0&1E%E -MF-%#A)B!P`2>`<``$D!`)()`"<`4"H@97AA20!`8$(&YDT`(Q9G5L+P(&10`0+T,* -M`84!$6&>"E%A8W0@'2(`")P==8-(")C-`81(B0#`#@,*6]L30`"5@$&ZP,!*0$` -M%@D`C@$/;0$!`+`,$'4]$P':`31E"B>P`"-E)ZT``#H/,"`J(),``$X`\``N -M86TL(&%C;&]C86PN;30)#0/M`#`N86/_```"`!`MH@(`GP`$J```V0X(H@02 -M+!H.`-<+`%D+$'G*!0'V`2-EH($',+!0$^`0!U```7`@#Y!`%Q``%Q"@B7```\ -M"3!Y+C/T%#!A:6SO!#)E(")K`P6K``$D`!0B"PM9(&-L87-$``$?"49N86QS -MG0`2!Q(M@@0U=H+`#L'`2,)#V0:________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M__________________________________]I4'(*("`@/A$``!(@`0!R>F-A -M="P@8@<`$G@'`/0386YD('-U8V@*("`@*B!E>&%M<&QE'2( -M`#%P=70I`/D#(F-M86ME(B!B=6EL9"!T;V]L30`"5@$&-0$!*0$Q(&EN3`$/ -M;0$!,&%R91`"$F3:`35E"B>\`!,GK0`2.M0``),``$X`]0$N86TL(&%C;&]C -M86PN;30LX0!`92YA8RL```(`$BU4`"1T;Z@``"`!,&1IM`_`$,R!G:79E2XS!`,!JP(2(FL#!:L``20`Z2(@=71I;&ET>2!C;&%S1`"6:6YT97)N86QS -MG0`P`?$#+@H*66]U('-H;W5L9"!A;'-O(@(!3``Q8V]P=@8R8V]M6P%# -M:6X@(KT",BYH(JD`@&AE"G-O=7)C+P`19'4!`!0`!.D&!30'`"P%-&UO<$",&5C=)D#$635 -M``,<`@7"!A!F+``!MP91*B!'3E5U`0*Z`28@*+D!`!H`06QO;F=5`F)N86UE -M'1E -M;J+``-J`0`9`]$J(%!/4TE8('5S=&%R6P`" -M$``P<&%X20,B97)9!P-X`@FEP,A8`!'P!32],6E<=`*)L>FUA+"!L -M>FEP$P,O>'HC```9-!0`"0@!```*56-R96%TSP`!=00/!@$"`JH#`[\#`KP" -M#Q\#&#`B&-E<$`%`+D%!&D"`A4,<7)E<75IP`#GP$`>P`!APD!HP`"2@P#"@,`.`@`L@`Q=&AA+PD#*P`A -M(&(W"0!J"#%A8FP`!@","@$,``$L"P($`0!H``([`$)E86-H/0$A=F5S`Q-Y -M0P!0:6YD97"J`"5N="(!`!@)``\/$&-"!1)O;`T&-0I4(%=I:VE2##!I;F?) -M`#!H;W=1#P&S`Q=DE@H"*@$A3VX_"`#W#`)@!@,#`03-``%P`$!L=V%Y1@$` -MW0$J962*"`)'`'!))W9E(&%T+0T`C`<`P0^0:6YI;6EZ92!S#@T28U((07!O -M;&R4#5$N("!)9O4(4&1O;B=TJ`"097AP;&EC:71LV0EB=F]K92!A^@\18W\* -M,69E830+$"C2$`!U#`@<`A!A00`!)Q`"+0`(S0`4;_D(<"DL(&ET('=P`'$@ -M9V5T('!UG`T0:7H+1R`@26YN`#``%1`0.;`")E;LD!!RT``#X`"W$` -M*&1E$0`#J@`1+/```H```(T.`)8!`!8!`$``(&%G`PX"4`.18V]R0`P&@`A!MV`$32X'<70@82!T:6U7 -M`W%O8!(71O(@`%2@!2="!O;F-\ -M$B)/;AP."\,``N0",G!R;SH!`84!46-T;'DMS`"2960@;W5T<'5T[P(`8`3Q -M`V]B:F5C="US='EL92!A<'!R;\@#`$,2`OH`X'1O(&AA=F4@;75L=&EP)0`` -M(040=A(#0')E86VY"%4@;W!E;IX`$R`5$`!J$``*`0`]!8-N(&ETP"`,D*`2L`,VEN -M("#U%F:7)S=)("`*8!$6%P$A%O61$`]@`6 -M+G0``]D#`J60!`,P` -M`*,!!H`%,7=A;G\%$G0=#P-%`0!@```:!!!TC@0#`',*%E7,@<')O9'5C97,@8V]R6QE(&%P<')O86-H(&%L;&]W^@#@=&\@:&%V92!M=6QT:7`E -M``.I`'%S=')E86USSP`U<&5NG@#S#2`@8G-D=&%R('5S97,@=&AI2!D8737`%9UP",B!O9BL`,VEN(""!I;G1E7,N"E)%041-12X``$0$!&T!T6)U;F1L92X*"E%U97/Z`J`_("!)!D!G`<``$D!0'-U8V@G`%`J(&5X84D`0',Z(%,R`U1S -M;6%L;!4`!#X!`%(#(6%T(`8@;6'F!"!N9-`",69U;"\"!D4`42]M:6YIA0$1 -M8>,!46%C="!S8`"P(&1E;6]N0&";8"(FEN^`0B:6_A!@2]`O`"3D574R`M(&AI9VAL:6=H -M='-M``,D!`"3``!.`/4! -M+F%M+"!A8VQO8V%L+FTT+.$`0&4N86/_```"`!`MH@(`GP`$J``,H@2R+"!O -M;FQY(&YE961\`#%M86GV`2-E7-T96TZ -MIPH"N`1U+C$@97AP;(,"`R\#`$(!`B$`!)H#`S,``(@$#S0`"P`B``PU`"]A -M=#0`#"AA=#,`!@$&(2XSM@L0<]\&@&]V97)V:65W\P(`H``%G@L`<04P=VAO -MD0(4*J0*A5]R96%D+C,L$``!^`@-$0!17V1I``'<`%0P#'`(%>`D09BP``;<&42H@1TY5=0$"-0(F("@$"P`:`$%L;VYG -M50(`K0LB+``-J`0`9`]$J(%!/4TE8('5S=&%R6P`"$``/ -MB@P#!R$`P&]C=&5T+6]R:65N=!<$,7!I;QX`IE-64C0@05-#24D4``)3``\R -M``5A0FEN87)Y+@#`("AB:6FEP/@$Q:6]N -M&`%=8GII<#(6``1\`4TO3%I7'0"B;'IM82P@;'IID2,',@*'T'`30$`(0!`S,$`/0#8"P@971C*>\+`OH#`*D"`&@1 -M`HT``88!`MH`#Y8#!0'(`V$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0%!`?. -M``]9`P`*%@,S5VAE`P(`-0<#U`(2<^8%87)E'!L:6-I=&S9"6)V;VME(&'Z#Q%C?PH#SA$@ -M("C2$`!U#`@<`A!AL@$!)Q`"+0`(S0`4;W,$<"DL(&ET('=P`%`@9V5T(-(2 -M`5T*`*0$-R!);FX`!287`9X``5$!`YL`(F5NR0$'+0``?``+<0`H9&41``.J -M`!$L6!$"@```C0X`E@$`%@$`0``P86=A\P\!7PJ18V]R2!O9B!T:&4@9F]L;&]W:6YG(&)E9F]R92!E=F%L -M=6%T$@``(`#Q#6%R8VAI=F4Z"B`@*B!U=65N8V]D960@9FEL97,4``$*`/$" -M('=I=&@@4E!-('=R87!P97(;`/$!9WII<"!C;VUP'HC```9-!0`"0@!E6-A;B!C -M'1E;DT!L7,@*&9O$E33SDV-C`3`%HW+5II<#D`-EA!4A$`0PI7:&4#`@#8`@1U -M`1$L`@-AT!X'-Y0`&EP#R`FES(&1EP`!S@`4=E@#$G.C`%0@;VYL>0H#0&UE;G2R``$>`P"F!`)G`S`@ -M8F5``(!R96%D86)L9:(`07=R:70,`!!A#`$"!`$!1`0!.P!"96%C:#T!(79E -ME@(3>4,`4&EN9&5PJ@`B;G1_`!!R.P0`!``P=&EC0@4D;VZ!`02N`/``5VEK -M:2!E>'!L86EN:6YGB0`P:&]W^``"]0``E@4#+``"*@$A3VZJ`!PL`P$#V0(" -M<`!`;'=A>48!`-T!\@%E9"!A=71O;6%T:6-A;&QY1P"P22=V92!A='1E;7#$ -M`^!T;R!M:6YI;6EZ92!S="L`L"!L:6YK('!O;&QUN`'A+B`@268@>6]U(&1O -M;B?L`0"V`/$":6-I=&QY(&EN=F]K92!A('#K`"!U;#<$H&5A='5R92`HD`!RT`!^\%`(`!`ID!<"DL(&ET('=P`.`@9V5T('!U;&QE9"!I -M;J0$-R!);FX`-RP@:9X``5$!`YL`(F5NR0$'+0``?``+<0`H9&41``/&`A$L -M\``"@``B;F6.`@`6`0!``&)A9V%I;G-'`J!C;W)R97-P;VYD)P0(20`-6@`" -M>P,Q:65SPP`!;P,!;P=1P,1<#4`T6%T979E`%`@(&)S9",'(75SO`$`/06#;B!I=',@(D#E`!(BO01&"2`L(E`(<"P@8V%P86)!``'V -M`@)F!A%E50(!\0!A92!!4$ESMP0(]@4!EP&Q(&EN9&EV:61U86QH!1%IWP<` -M>P`28D(``"P$`-$``#8!(71OFPDP9&%TUP!6=7)C93HN`0+("0#"`!)A[`(` -MR0H!*P`S:6X@)P$`3P@S861DC@(18?P(!*H!`'D&(6]U]P119FER0#`',*T"!S87ES+@I214%$346[!@?H!N$@8G5N9&QE+@H*475E<_H" -MH#\@($ES8N9V]O9VQE+F-O -M;2]P+VH`$2\Z`"!S+VD``),``6<`47-U8FUI9P!P96YH86YC9;L``*8`!C@` -M@RP@<&QE87-E+```.P``!`,`2P7!1`GH@1`9W)A;18"F-%#A)B -M!P`2>`<``$D!`)()`"<`4"H@97AA20!`8$(&YDT`(Q9G5L+P(&10`0+T,*`84!$6&>"E%A8W0@'2(`")P==8- -M(")C-`81(B0#`#@,*6]L30`"5@$&ZP,!*0$`%@D`C@$/;0$!`+`,('5SW0H` -MV@$T90HGL``C92>M``-G`0"3``!.`/``+F%M+"!A8VQO8V%L+FTT"0T#[0`P -M+F%C%P$``@`0+:("`)\`!*@``-D."*($$BP:#@#7"P)\`#%M86GV`2-EPH"MP(`A1(A86R)!T!S97%UZ@@0!Q(M@@0U``&I`5"`"X!!,B!0XR+F@BJ0`R:&4*7PP0(+`) -M`/H``!0`!.D&`W((`G\"$&T:%P/[`$(N("!0B@FR;&5T('5S"FMN;W<0`0&X -M#&!E2X`H"`H8FEG+65N9&GS!(-R(&QI='1L91$``L<`!%\6D4-$+5)/ -M32!I;;<"$"@X#C`@;W#+`\!A;"!2;V-K%V,/"Q<`T$UI8W)O2!A0A$``/4R2!T:&4*)V-O;F9I9W5R92<@`""(&EN'!L86EN@`/`#;&EB2!A2XS30`"=`%U(G-T2!C;&%S1`"6:6YT97)N -M86QSG0!@2QN``5H`W!U=&]M871I_P(0>68!,&5C=)D#$635``,<`E!O -M;&QO=Y,!$&8L`!!S4`51*B!'3E5U`0(U`B8@*+D!`!H`06QO;F=5`F)N86UE -M`*%3 -M5E(T($%30TE)=`(!%``"4P`/,@`%84)I;F%R>2X`H"`H8FEG+65N9&GS!(-R -M(&QI='1L91$``OH`\0))4T\Y-C8P($-$+5)/32!I;;<"@"AW:71H(&]P^@7` -M86P@4F]C:W)I9&=E10!B2F]L:65T*0$![P$"20`T6DE05@,$0`"0=6YC;VUP -M[`@0]`5HW+5II<"8`V$UI8W)O`,(KP)@:&%N9&QENP(0>;<#`+8$ -M!K@",&)E9DH#<&5V86QU873*`@`@``.9`P+/`A!U]@40;W$"`+8"`D,"`0H` -M$2"#`:)24$T@=W)A<'!E3@)%9WII<#X!,6EO;A@!76)Z:7`R%@`$?`%-+TQ: -M5QT`HFQZ;6$L(&QZ:7`3`R]X>B,``!DT%``)"`&58V%N(&-R96%TSP`!=00/ -M!@$"`J\!`[\#`KP"#Q\#&#`B&-E<$`%`+D%!&D"L"!T:&%T(')E<75IE@4G87C*`B`@ -M*'T'`30$`(0!`S,$`/0#<2P@971C*2YO`0#Z`P"I`@8B!`$7``+:``^6`P4! -MR`-A(FYE=V,BFP,!,P`G?P(-F5A;;4%`A$+@"X@(%1H97)E+``C;F_B!P""`@/?"`"3!/("(&EN+7!L -M86-E(&UO9&EF:6.M"/,";W(@U`P#P!`![``.?`0![``&'"0&C``)*#`,*`P`X -M"`"R``$>`P"F!`(,`B$@8C<)<7)E861A8FP`!@","@$,``$L"P($`0!H``([ -M`$)E86-H/0$A=F5S`Q-Y0P!0:6YD97"J`"5N="(!`!@)4&%R=&EC0@4D;VZ! -M`02N`$17:6MI4@PP:6YGR0`P:&]WFPP"I@<'E@H"*@$A3VX_"`#W#`)X!@$" -M"B-N9/@``8@)8V%L=V%YD`!RT`!"T' -M`,T`%&_Y"'`I+"!I="!W<`!Q(&=E="!P=9P-(&ENI`0W($EN;@`W+"!IG@`( -MFP`B96[)`02UV```S#`#W"!%IAP8`A`!P96YV:7)O;M<",7,@ -M=Y`#`:`"$&W8`1-R6@,%,`(`6P`"?P`1>7L#$7`U`-%A=&5V97(@8FQO8VMS -M\```[@@``S0*%82!S;V-K970^`TEW:7-HN@0!)@\# -M60\`4X.475S92`B(0$`6@@@+")0"+$L(&-A<&%B -M:6QI=/8"!`,!!?$``O,/`;<$"/8%`9P"`,D*`2L` -M,VEN("#U%F:7)S=)("`*8!$6%P$A%O61$` -M]@`6+G0``]D#`J60! -M`,P``*,!!H`%,7=A;G\%$G0=#P$V`@%;`P$:!!!TC@0#`',* -MT2!S87ES+@I214%$3442!@9)$>$@8G5N9&QE+@H*475E<_H"H#\@($ESF-%#A)B!P`2>`<``$D!`)()`"<`02H@97@;$T!S.B!3,@-4X/\`4@*B!.15=3("T@:&EG:&QI9VAT<]P`,')E8]D4`C$%`Z`" -MDD-/4%E)3D<@+0P%`$(4`,H'(F1OGP``AP4`S@"T*B!)3E-404Q,("V2&`&/ -M!`$-``#Y%@"_``(I``-`!1(M1!D`E0`"&``%=QDE("T,``)$``*W&54L('-E -M96<``"@%`JT7`F,(@2H@0TUA:V5,U`0Q='ATB``A<'5G$#`@(F,T!A0BO!DY -M;V]L30`"5@$&-0$`E```L`H!C@$/;0$!`*(&#V0:____________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________________________________________]G4'1O(&%L+1$` -M`/`@;&]W(&EN9&EV:61U86P@96YT2!A;F0@861D(&ET3`#P!2!T87(@87)C -M:&EV92!W:71H;W5T00!19FER2!F:6QE+G0` -M0F%L8<`\01S;V-K970N("!)9B!Y;W4@=V%NB``2=%T`$B\]``,?`0`S`%!D -M:7-K+$X`\!!R92!A0#P*FES(&5S<&5C:6%L;'D@96%S>2X*"B`J($YO=&4Z(")P87@@:6YT97)C -M:&%N9V4@9F]R;6%T(B!I<^```#,``.(`<7AT96YD960X`0(B`!`L8P!`9&5S -M<-\`0'=H8726`/`#(&YA;64@F-A="P@8@<`$G@'``!)`4!S=6-H)P!0*B!E>&%)`$!S.B!3,@-4`0-)`#!C;VY#`O`".B`@5F%R -M:6]UP``7P%Q875T:&]R<\`%`1\&`?("``$%4"X*"E1HG0$P<"UL#`0#=@4` -M"08!00`0:20%";8"(FENU@0Q:6]NZP4$O0+P`DY%5U,@+2!H:6=H;&EG:'1S -M7`8PM``,D!`"3``!. -M`/4!+F%M+"!A8VQO8V%L+FTT+.$`0&4N86/_```"`!`MH@(`GP`$J``,H@2R -M+"!O;FQY(&YE961\`#%M86GV`2-E7-T -M96TZ<`<"N`1U+C$@97AP;(,"`R\#`$(!`B$`!)H#`S,``(@$#S0`"P`B``PU -M`"]A=#0`#"AA=#,`!@$&@"XS(&=I=F5SWP:`;W9EP$2+8($-7,N-:H(`)X%$67[`P#R`(!M871S -M('-U<'\(!&,"!98!`$P```H"D"XU+"!M=')E90D``&\`7G1A`D09BP``;<&42H@1TY5 -M=0$"-0(F("@$"P`:`$%L;VYG50(`K0LB+``-J`0`9`]$J -M(%!/4TE8('5S=&%R6P`"$``/B@P#!R$`P&]C=&5T+6]R:65N=!<$('!IZ`S& -M*B!35E(T($%30TE)%``"4P`/,@`%84)I;F%R>2X`P"`H8FEG+65N9&EA;J(! -M8VQI='1L91$``OH`\0))4T\Y-C8P($-$+5)/32!I;;<"$"@X#C`@;W#+`\!A -M;"!2;V-K[`@0]`5HW+5II<"8`V$UI8W)OFEP/@$Q:6]N&`%=8GII<#(6``1\`4TO3%I7'0"B;'IM -M82P@;'II\+`OH#`*D"`&@1`HT``88!`MH`#Y8#!0'(`V$B;F5W -M8R*;`P$S`"=S:+```1(`#T8#8P0%!`?.``]9`P`*%@,S5VAE`P(`&@T#U`(2 -M<^8%87)E4,`4&EN9&5PJ@`E;G0B`0!$#0`/#Q!C0@42;VP-!C4*5"!7:6MI4@P# -M#!,P:&]W^``"]0``K0$#V@`"*@$A3VX_"`#W#`)@!@#S#@!0!@/-``%P`%-L -M=V%Y'!L:6-I#16":6YV;VME(&'Z#Q%C?PH# -MSA$@("C2$"4@8?L*`*$!("!AL@$!)Q`"+0`(S0`4;W,$<"DL(&ET('=P`%`@ -M9V5T(-(2`5T*`*0$-R!);FX`,BP@:8(5`9X``5$!`YL`(F5NR0$'+0``?``+ -M<0`H9&41``/&`A$LY0D"@```C0X`E@$`%@$`0``P86=A\P\!7PJ18V]R"(&5N=FER;VX/"Q%WD`,!H`(0;=@!$W): -M`P4P`@!;``)_`!%Y>P,1<#4`8F%T979E2!O9B<`H69O;&QO -M=VEN9SJ&`(%U=65N8V]D90T`\0%G>FEP(&-O;7!R97-S:6]N%0!=8GII<#(6 -M``0F`$TO3%I7'0"Q;'IM82P@;'II<"P4`2EX>B,`P0I.;W1E7-T96TN("!4:&5R92P`@&YO(&1IF4@2!I;G9O:V4@82!PZP"`=6QA2!FP`28D(``"P$`-$``#8!(71O>`0#\`)N86UE('-A -M>7,N"E)%041-15``!^@&X2!B=6YD;&4N"@I1=65S^@*@/R`@27-S=65S/U(` -MURH@:'1T<#HO+W=W=RX@!S!O3``!(`1!HN`*#9F]R(&]N9V]8!Q@@9`!P -M9&5V96QO<#P%<2P@:6YC;'6]!4!D;V-U%``!K`@!3@D`<0``.@`A;FM=`0!= -M``9S`%`@;6%I;`<"0FQIF-A="P@8@<`$G@' -M``!)`0"2"0`G`%`J(&5X84D`0',Z(%,R`U1S;6%L;!4`!#X!`%(#(6%T'`@@ -M;6'F!"!N9-`",69U;"\"!D4`$"]#"@&%`1%AG@I186-T('-@`)(@9&5M;VYS -M=')*#0`I!B=O9EX!`TD`,&-O;D,"\`(Z("!687)I;W5S(&ET96US(#,!`'T# -M0&UE(&(W`3)I0&";8"(FENU@0`Q@P`ZP4$ -MO0+P`DY%5U,@+2!H:6=H;&EG:'1S7`8PP -M`"-E)ZT``R0$`),``$X`\``N86TL(&%C;&]C86PN;30)#0/M`#`N86,7`0`" -M`!`MH@(`GP`$J```V0X(H@02+!H.`-<+`GP`,6UA:?8!(V5RK@$%<``D:6YD -M`($N:"YI;@H)+?0'(&QA5@\$NP`%A0`#M0!@"@I'=6ED\P`H($14!@32`0)U -M``&W`0)3#Q`Z&@D"N`0A+C'!#`!A#`$W`0,O`P`+``(A``2:`P,S``"(!`\T -M``L`(@`,-0`O870T``PH870S``8!!B$N,[8+$'-E"H!O=F5R=FEE=_,"`*`` -M!<`+`'$%4'=H;VQEI``#1`6$7W)E860N,RRT"A%?^`@-$0!17V1IH($',+!0$^`0!U```7`@#Y -M!`%Q``%Q"@B7```\"3-Y+C--``#O!#)E(")K`P6K``$D`!0B"PM9(&-L87-$ -M``$?"49N86QSG0`2!Q(M@@0U]!9!I -M;@IA(&YU;6+R#!=FD0<$.P''"@I9;W4@2X`L2`H8FEG+65N9&EA -MU!%C;&ET=&QE$0`"^@`$7Q:10T0M4D]-(&EMMP(0*#@.,"!O<,L#P&%L(%)O -M8VMR:61G9>\!`DD`-%I)4'4$!$``('5N,0L`)18`UA!@ -MC2H`0#E%PD( -M`0``"@*<$`5+`0!U!`\&`0("@P$#OP,"O`(/'P,8,")R9:`-`!`6$2)'`P)/ -M`,(L('=H:6-H('=I;&SK&`!P"``9!`-?`4!S(&5X+10``@(`N04$B1$""Q<# -M6A`'!L:6)R87)Y3`#08W!I;RXU+"!M=')E90D``&\`5'1AP#S -M"2P@:6YC;'5D:6YG(&AA -M``"/`/0:("=D;V,G(&1I2!I;@IA(&YU;6)E6]U(#\!8"X*"D-UFEP,A8`!'P!32],6E<=`*)L>FUA+"!L>FEP -M$P,O>'HC```9-!0`"0@!E6-A;B!C,H"4B`H9F]R-`0`A`$#,P0` -M]`-Q+"!E=&,I+F\!`/H#`*D"!B($`1<``MH`#Y8#!0'(`V$B;F5W8R*;`P$S -M`"=S:+```1(`#T8#8P0%!`);`0&)``]9`P`*%@,S5VAE`P(`V`(#U`(2<^8% -M87)E'!L86EN:6YGR0`P:&]W^``"I@<`K0$#+``" -M*@$A3VX4"1PL`P$#^``!B`E086QW87E&`0#=`2IE9(H(`D<`L$DG=F4@871T -M96UPC`?@=&\@;6EN:6UI>F4@D`!RT`!"T'`,\*%&_Y"'`I+"!I="!W<`""(&=E="!P=6S["@"D!#<@ -M26YN`#``B;`")E;LD!!RT``'P`"W$`*&1E$0`#Q@(1+/```H``(FYE -MC@(`%@$`0`!B86=A:6YS1P*18V]R0`P&@`A!MV`$38!(71O(@`%H0!A="!O;F-EA0`A3VZ0`QMEPP`"Y`(R<')O.@$! -MA0%18W1L>2W,``"."5)U='!U=.\"`&`$\0-O8FIE8W0M60!`,P``*,!!H`%,7=A;G\%$G0=#P$V`@%;`P!C -M#``S`$%D:7-K+`,`L1`0#B)A;N@"`*4'`!$# -M`EH'$"QC`$!D97-PH@``;`0!Y`,`7,N"E)%041-11(&!DD1X2!B -M=6YD;&4N"@I1=65S^@*@/R`@27-S=65S/U(`UBH@:'1T<#HO+W=W=RXX`$`N -M;W)GDP``2`$0:+@"$&:Q#S-N9V]8!Q<@3`>`(&1E=F5L;W`\!0@9$02Z$0&L -M"`$W#`!Q```Z`"%N:UT!`%T`!G,`4"!M86EL!P(P;&ESOQ`!G0`05)D!`.41 -M`.%E8$(&YDT`(Q9G5L+P(&10`0+T,*`84!$6&>"C1A8W1[$W!D96UO;G-T -M.14@;F<^``"`!094`@-)`#!C;VY#`F$Z("!687+N$V!I=&5M$0(8`&!C;VYF:6>R%A4M#``"1`"UM`Q$SM@L`$!20(&]V97)V:65W\P(`JP`% -MP`L`<04P=VAOD0(4*J0*A5]R96%D+C,L$``!^`@-$0!17V1I2#R`I!I;VYS+@H*5&B=`?("<"UL979E -M;"!D:7)E8W1O'2(`#!P=71>`H$@ -M(F-M86ME(B0#:60@=&]O;$T``E8!!NL#`2D!,2!I;DP!#VT!`3!A2!N965D?``Q;6%I]@$C97)<`05P -M`"1I;F0`\@,N:"YI;@H)+2!T96UP;&%T97-G`!%B-`(!9@$39;4`8`H*1W5I -M9/,`4"!$;V-UF04"@0$`Q0$R86QL=0`!MP&R'!L@P(#+P,`0@$"(0`$F@,#,P``B`0/-``+`"(`##4`+V%T-``,*&%T,P`& -M`0:`+C,@9VEV97/?!H!O=F5R=FEE=_,"`*``!+L%$&%Q!3!W:&^1`B,J(,0& -MA5]R96%D+C,L$```T04=91$`45]D:7-K%@`@;F30`0@^``,<``"9`!!V7P$" -MMP)P960@8V%L;!(&$'/4!D%N8V5SK0(`DP``=0`!1P`#0@9H92!!4$ESEP!S -M96YTP$2+8($4W,N-2!D5@("KP``&0,`\@"`;6%T#0#`ED' -M`W@"!R$`P&]C=&5T+6]R:65N=!<$('!I?@G&*B!35E(T($%30TE)%``"4P`/ -M,@`%84)I;F%R>2X`P"`H8FEG+65N9&EA;J(!8VQI='1L91$``OH`\0))4T\Y -M-C8P($-$+5)/32!I;;<"$2AX""!O<,L#P&%L(%)O8VMR:61G944`8DIO;&EE -M="D!`>\!`DD`-%I)4%8#!$``('5N,0LPFEP,A8`!'P!32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9-!0` -M"0@!```*56-R96%TSP`!=00/!@$"`JH#`[\#`KP"#Q\#&#`B&-E<$`%`+D%!&D"42!T -M:&%T0PXQ:7)E40`!\P,!R@(@("@6!0$T!`"$`0,S!`#T`V`L(&5T8RGO"P+Z -M`P"I`@8B!`&&`0+:``^6`P4!R`-A(FYE=V,BFP,!,P`GD#`*4#(71EVP@P -M.@H*'Q$R:&ESD0]P:&5A=FEL>?P(-F5A;;4%`A$+<"X@(%1H97(T$3,@;F_B -M!P""`@/?"`"3!$$@:6XMMP^"(&UO9&EF:6-D"_``;W(@0`&EP``L!!397-I9VXE#!)EB`4`0`0!7@$X;F5WM0,`\`0`>P`#GP$` -M>P`!APD!HP`"2@P`31$B:7*"$1!I>0<280D!`@P"(2!B-PD`:@@Q86)L``8` -M_0H!#``!+`L"U!``:``".P!"96%C:#T!(79E4,`4&EN9&5PJ@`E;G0B -M`0`8"0`/#Q!C0@42;VP-!C4*5"!7:6MI4@PP:6YGR0`P:&]W40\!LP,09$X( -M`]H``BH!(4]N/P@`]PP"8`8`TQ$`4`8#S0`!<`!3;'=A>7-S""IE9(H(`D<` -M<$DG=F4@870M#0",!S!T;R`A$+)M:7IE('-T871I8U((07!O;&PV$E$N("!) -M9O4(061O;B<<$Y!E>'!L:6-I=&S9"4!V;VMEO!(!ZP`!?PH#SA$@("C2$"4@ -M8?L*`*$!("!AZ0`!)Q`"+0`(S0`4;_D(<"DL(&ET('=P`$$@9V5T&1,!70H` -MI`0W($EN;@`W+"!IG@`!40$#FP`B96[)`07L#$7`U -M`-%A=&5V97(@8FQO8VMS\```[@2X'<70@82!T:6U7`W%O8!(71O(@`%2@``XQ,A8V6%`"%/;I`#&V7#``+D`C)P`!,@ -M%1``:A``"@$`/06#;B!I=',@(D`\`!(BO0012!F4X.``P1$2(A`0!: -M""`L(E`(H"P@8V%P86)I;&D2%`8#`07Q``+S#P$_#@CV!0&7`8`@:6YD:79I -M9&P.`]L(`(4``#H2`D(``*P+`-$``#8!(71OK`TP9&%TUP``!0X6.BX!`L@) -M`#T`$F'L`@#)"@$K`#-I;B`G`0!%!3-A9&2.`AAA]PP!J0H#'@]19FER0#`',*'!L86EN:6YG"B`@(&AO=R!T;R!E>'1E;F0L -M`/(6+@H*("H@3VX@0*A2!A8V-E<#4`T6%T -M979E717`G`@82!T:6UEI0!Q;W(@;6UA<-H`065N -M=&D/`P+\`@!I`!!G!0,@:71/``FA`&%T(&]N8V6%`(M/;B!W`+$@(&)S9'1A2!B=69F97(@ -M;W+!``!E``1R`85A('-O8VME=#X#4'=I2UT;RUU"!I;G1E -M7,N"E)%041-12X`!^@&X2!B=6YD;&4N"@I1=65S^@*@ -M/R`@27-S=65S/U(`UBH@:'1T<#HO+W=W=RY,!T`N;W)GDP``2`$0:+@"@V9O -M0(1.FH`$B>7!9`G('!R;V=R86T6`G-A -M(&9U;&PME@AP9"`G=&%R)WX``P(`4W)E<&QA0@%`8G5I;($&`(H``V,``"H` -M9BH@8W!I;V,```X`"V0`(&1I:P4R96YT,`-#9F%C96H#`P(`,&5S`<``$D!`)()`"<`4"H@97AA20!`8$(&YDT`(Q9G5L+P(&10`0+T,*`84!$6$& -M"5%A8W0@`0-)`#!C;VY#`O`".B`@ -M5F%R:6]UP``7P%Q875T:&]R<\`%`1\&`?("`DT'$`J(!E!T;W`M;`P$`W8%`#`' -M`4$`$&GD!@FV`B)I;M8$`'$+`.L%!+T"\`).15=3("T@:&EG:&QI9VAT=&%R+C54`0CQ!$%A8F]U4P41]!9!I;@IA(&YU;6+R#!=F -MD0<$.P''"@I9;W4@`D09@82`;<&42H@ -M1TY5=0$"-0(F("@$"P`:`"-L;[P%`*T+(G,L$```!0L3(!$``&,`4G-P87)S -M?`(A -M`*%35E(T($%30TE)=`(!%``/,@`+$$)M$1%Y+@"Q("AB:6`@@;W#+`\!A;"!2 -M;V-K[`@0]`5HW+5II<"8`V$UI8W)OFEP/@$@:6]/$WTJ(&)Z:7`R%@`$?`%-+TQ:5QT`HFQZ;6$L -M(&QZ:7`3`R]X>B,``!DT%``)"`$```H"G!`%.@$`=00/!@$"`J\!`[\#`KP" -M#Q\#&#`B\+`OH#`*D"`&@1`HT``9L!`MH`#\@#"F$B;F5W8R*;`P$S`"=S -M:+```1(`#T8#8P0%!`?.``]9`P`*%@,S5VAE`P(`OP@#U`(2<^8%87)E`3AN97>U`P#P!`#]`@.?`0![``&'"0$K -M%0)*#`,*`P`X"`!O$!1T[A("#`(A(&(W"0","@&/&`.X%`$,`!!A#`$"U!`` -M:``".P`199P6`#T!(79E4,`4&EN9&5PJ@`E;G0B`0!$#0]D&O______ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M8U!A;F0@'1E;F1E -M9&0`!#-!0TPS`&%/;&0@5C2!O9K@"X&)E9F]R92!E=F%L=6%TI`(`V`(# -M+P("SP)@=75E;F-O<0(`M@("0P(!"@`1((,!HE)032!WFEP -M/@$Q:6]N!0%=8GII<#(6``1D`4TO3%I7'0"B;'IM82P@;'II0`&EP"0:7,@9&5S -M:6=NH@9";R!B98@%`$`$`3`$.&YE=[4#`*,$`'L``4,`4&EN9&5PJ@`B;G1_`!!R.P0` -M!``P=&EC0@4D;VZ!`02N`/``5VEK:2!E>'!L86EN:6YGB0`P:&]W^``!LP,0 -M9)8%`RP``BH!(4]NJ@`<+`,!``0$,FUA='``0&QW87E&`0#=`6!E9"!A=71> -M"&)I8V%L;'E'`+!))W9E(&%T=&5M<(P'X'1O(&UI;FEM:7IE('-T*P`"4@A0 -M<&]L;'6X`>$N("!)9B!Y;W4@9&]N)^P!`+8`\0)I8VET;'D@:6YV;VME(&$@ -M<.L`('5LO0B@96%T=7)E("AS=2\!&7,<`A!AZ0`'+0`$10<#(@("F0%P*2P@ -M:70@=W``X"!G970@<'5L;&5D(&ENI`0W($EN;@`W+"!IG@`!40$#FP`B96[) -M`07L#$7`U`-%A=&5V97(@8FQO8VMS\``` -M[@2X'<70@82!T:6U7`W%O8!(71O -M(@`%H0!A="!O;F-EA0`A3VZ0`QMEPP`"Y`(R<')O.@$!A0%18W1L>2W,``". -M"5)U='!U=.\"`&`$\0-O8FIE8W0M2!B=69F97(@)`@`90`$<@&%82!S;V-K970^`TEW:7-HN@3` -MP"`,D*`2L`,VEN(">D``,P``*,!!H`%,7=A;H@`$'0V -M!`5%`0!@```:!!!TC@7,N"E)%041-1;L&!^@& -MX2!B=6YD;&4N"@I1=65S^@*@/R`@27-S=65S/U(`URH@:'1T<#HO+W=W=RX@ -M!S!O3``!(`1!HN`*#9F]R(&]N9V]8!Q@@9`!P9&5V96QO<#P%)BP@8`]` -M9&]C=10``:P(`3<,`'$``#H`(6YK70$`70`&8N9V]O9VQE+F-O;2]P+VH`$2\Z`"!S+VD``),``6<`47-U8FUI9P!P96YH -M86YC9;L``#8"!C@`@RP@<&QE87-E+```.P``!`,`2PB!$!G0&";8"(FENU@0`I`H`ZP4![@_P!2`J($Y%5U,@+2!H:6=H;&EG:'1S7`8P -MM```Z#S`@*B"3``!.`/``+F%M+"!A -M8VQO8V%L+FTT"0T#[0`P+F%C_P```@`0+:("`)\`!*@``-D."*($$BP:#@#7 -M"P!9"Q!YR@4!]@$C97*N`05P`"1I;F0`@2YH+FEN"@DM]`<`YA,22XS -M]!0P86EL[P0R92`B:P,%JP`!)``4(@L+62!C;&%S1``!'PE&;F%L``'?`5&%M<&QE'2(`#%P=70I -M`/D#(F-M86ME(B!B=6EL9"!T;V]L30`"5@$&-0$!*0$Q(&EN3`$/;0$!,&%R -M91`"$F3:`35E"B>\`!,GK0`2.M0``),``$X`]0$N86TL(&%C;&]C86PN;30L -MX0!`92YA8RL```(`$BU4`"1T;Z@``"`!,&1IM`_`$,R!G:79E2XS!`,! -MJP(2(FL#!:L``20`Z2(@=71I;&ET>2!C;&%S1`"6:6YT97)N86QSG0`PP$2+8($4W,N-2!D5@(#I@0@:6QV`]1R;6%T-50!"/$$4&%B;W5T&@$@P"`+"!I;F-L=62*`8%H87)D+71O+3`&`J@!$G-'``!! -M`&%M;V1E$D#(F5R60<#>`('(0"P;V-T970M;W)I96X!`P!@`@$>`*%35E(T($%30TE) -M=`(!%``"4P`/,@`%,$)I;LH$`$(`H"`H8FEG+65N9&GS!(-R(&QI='1L91$` -M`OH`\0))4T\Y-C8P($-$+5)/32!I;;<"$2AX""!O<,L#P&%L(%)O8VMR:61G -M944`8DIO;&EE="D!`>\!`DD`-%I)4%8#!$``('5N3@DPFEP/@$Q:6]N&`%=8GII<#(6``1\`4TO3%I7'0"B;'IM82P@;'II?P(-F5A;;4%`A$+@"X@(%1H97)E -M+``C;F_B!P""`@/?"`"3!/("(&EN+7!L86-E(&UO9&EF:6-D"_``;W(@0`&@`23:7,@9&5S:6=N)0P298@%`$`$`;,%.&YE=[4# -M`/`$`'L``Y\!`'L``8<)`:,``DH,`PH#`#@(`+(`,71H82\)`RL`(2!B-PD` -M:@@Q86)L``8`C`H!#``!+`L"!`$`:``".P!"96%C:#T!(79E4,`4&EN -M9&5PJ@`E;G0B`0`8"0`/#Q!C0@42;VP-!C4*5"!7:6MI4@PP:6YGR0`P:&]W -M40\!LP,79)8*`BH!(4]N/P@`]PP"8`8#`P$$S0`!<`!`;'=A>48!`-T!*F5D -MB@@"1P!P22=V92!A="T-`(P'`,$/D&EN:6UI>F4@P,1<#4`T6%T979EP"`,D*`2L`,VEN("#U%F:7)S=)("`*8!$6%P$A%O61$`]@`6+G0``]D# -M`J60!`,P``*,!!H`% -M,7=A;G\%$G0=#P-%`0!@```:!!!TC@0#`',*%EF-%#A)B!P`2>`<``$D!`)()`"<`#V0: -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______]?4'(@8FQO)!$``/%/8VMS('EO=2!H86YD(&ET+@H@("!9;W5R(')E -M860@8V%L;&)A8VL@:7,@9G)E92!T;R!P87-S('1H92!L:6)R87)Y(&$@8GET -M92!A="!A('1I;64*("`@;W(@;6UA<"@`\`!E;G1I7,@<')O -M9'5C97,@8V]R`,`@(&)S9'1A&%)`$!S.B!3,@-4`0-)`#!C;VY#`O`".B`@ -M5F%R:6]UP``7P%Q875T:&]R<\`%`1\&`?("`DT'$`H5"%!T;W`M;`P$`W8% -M`#`'`4$`$&GD!@FV`B)I;O@$(FEOX08$O0+P`DY%5U,@+2!H:6=H;&EG:'1S -M7`8P'2(`#!P=71>`C`@(F,T!A$B)`,`J@2!N965D?``Q;6%I]@$C97*N`05P`"1I;F0`@2YH+FEN"@DM]`=2;&%T97-G -M`!%B-`(#<@$"M0!@"@I'=6ED\P`H($14!@32`0)U``&W`7!S>7-T96TZIPH" -MN`1U+C$@97AP;(,"`R\#`$(!`B$`!)H#`S,``(@$#S0`"P`B``PU`"]A=#0` -M#"AA=#,`!@$&(2XSM@L0<]\&@&]V97)V:65W\P(`H``%G@L`<04P=VAOD0(4 -M*J0*A5]R96%D+C,L$``!^`@-$0!17V1I``'<`%0P#'`(%>`D09BP``;<&42H@1TY5=0$"-0(F("@$"P`:`$%L;VYG4`8` -MK0LB+``-J`0`9`]$J(%!/4TE8('5S=&%R6P`"$``/B@P# -M!R$`P&]C=&5T+6]R:65N=!<$,7!I;QX`IE-64C0@05-#24D4``)3``\R``5A -M0FEN87)Y+@#`("AB:6FEP/@$Q:6]N&`%= -M8GII<#(6``1\`4TO3%I7'0"B;'IM82P@;'IID2,',@*'T'`30$`(0!`S,$`/0#8"P@971C*>\+`OH#`*D"`&@1`HT` -M`88!`MH`#Y8#!0'(`V$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0%!`?.``]9 -M`P`*%@,S5VAE`P(`-0<#U`(2<^8%87)E`3AN97>U`P#P!`#]`@.?`0![``&'"0$K%0)*#`!-$2)IE(7`+4(`E(( -M07!O;&PV$@;D%$%D;VXG[`&097AP;&EC:71LV0EB=F]K92!A^@\18W\*`\X1 -M("`HTA``=0P('`(08;(!`2<0`BT`",T`%&]S!'`I+"!I="!W<`!0(&=E="#2 -M$@%="@"D!#<@26YN``4F%P&>``%1`0.;`")E;LD!!RT``'P`"W$`*&1E$0`# -MJ@`1+%@1`H```(T.`)8!`!8!`$``,&%G8?,/`5\*D6-O!<1<_```.X'#V0:________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M__________________________________________]>4'1S(&%N3Q$``/`> -M9"!H86YD;&5S(&%N>2!O9B!T:&4@9F]L;&]W:6YG(&)E9F]R92!E=F%L=6%T -M$@``(`#Q#6%R8VAI=F4Z"B`@*B!U=65N8V]D960@9FEL97,4``$*`/$"('=I -M=&@@4E!-('=R87!P97(;`/$!9WII<"!C;VUPFUA+"!L>FEP+"!A;F0@>'HC```9-!0`]0<*5&AE(&QI -M8G)A"!I;G1E&-E<'0@9F]J`/$'("!E;G1R -M:65S('1H870@.`?$#;F%M -M97,L($%#3',L(&5T8RDND@"P3VQD($=.52!T87)=``2I``+*`/$$;V-T970M -M;W)I96YT960@8W!I;S4`ME-64C0@(FYE=V,B%0`G`'@G;71R964GNP!X25-/.38V,!,`6CT!X'-Y0`&EP#R`FES(&1EP`!S@`4=E@#$G.C`%0@;VYL>0H#0&UE;G2R -M``$>`P"F!`)G`S`@8F5``(!R96%D86)L9:(`07=R:70,`!!A#`$"!`$!1`0! -M.P!$96%C:"8"`98"$WE#`%!I;F1E<*H`(FYT?P`04<`L$DG -M=F4@871T96UPQ`/@=&\@;6EN:6UI>F4@2!I;G9O:V4@82!PZP`@=6PW!"!E -M85D"0"`HD`!RT`!^\%`(`!`ID!<"DL(&ET('=P`.`@9V5T -M('!U;&QE9"!I;J0$-R!);FX`-RP@:9X``5$!`YL`(F5NR0$'+0``?``+<0`H -M9&41``/&`A$L\``"@``B;F6.`@`6`0!``&)A9V%I;G-'`J!C;W)R97-P;VYD -M)P0(20`-6@`">P,Q:65SPP`!;P.A86QS;R!R961U8[D%,&4@`(&5N=FER;V[7`C%S('=N`@&@`A!MV`$3 -M6QE(&%P<')OR`,`R0@"^@#@=&\@:&%V92!M=6QT -M:7`E```A!1!V$@,`!04`N0A5(&]P96Z>`%`@(&)S9",'(75SO`$`/06#;B!I -M=',@(D#E`!(BO01&P`28D(``"P$`-$``#8!(71OFPDP9&%TUP!6=7)C -M93HN`0+("0#"`!)A[`(`R0H!*P`S:6X@)P$`3P@S861DC@(18?P(!*H!`'D& -M(6]U]P119FER0#`',*T"!S87ES+@I214%$346[!@?H!N$@ -M8G5N9&QE+@H*475E<_H"H#\@($ES8N9V]O9VQE+F-O;2]P+VH`$2\Z`"!S+VD``),``6<`47-U8FUI9P!P -M96YH86YC9;L``*8`!C@`@RP@<&QE87-E+```.P``!`,`2P7!1`GH@1` -M9W)A;18"F-%#A)B!P`2>`<``$D!`)()`"<`4"H@97AA20!`8$(&YDT`(Q9G5L+P(&10`0+T,*`84! -M$6&>"E%A8W0@H($',+!0$^`0!U```7`@#Y!`%Q``%Q"@B7```\"3-Y+C-- -M``#O!#)E(")K`P6K``$D`!0B"PM9(&-L87-$``$?"49N86QSG0`2!Q(M@@0U -M"`"X!!,B!0XR+F@BJ0`R -M:&4*7PP0(+`)`/H``!0`!.D&`W((`G\"$&T:%P/[`$(N("!0B@FS;&5T('5S -M"FMN;W>5$P`P%&!E\6`2T5`A``#XH,`P`""(&EN'!L86EN3`1!F+``0'1E;J`*%35E(T($%30TE)=`(!%``"4P`/,@`%84)I -M;F%R>2X`H"`H8FEG+65N9&GS!(-R(&QI='1L91$``OH`\0))4T\Y-C8P($-$ -M+5)/32!I;;<"@"AW:71H(&]P^@7`86P@4F]C:W)I9&=E10!B2F]L:65T*0$! -M[P$"20`T6DE05@,$0`"0=6YC;VUPB,``!DT -M%``)"`&58V%N(&-R96%TSP`!=00/!@$"`NP"`[\#`KP"#Q\#&#`B&-E<$`%`+D%!&D" -ML"!T:&%T(')E<75IE@4G87C*`B`@*'T'`30$`(0!`S,$`/0#<2P@971C*2YO -M`0#Z`P"I`@8B!`$7``+:``^6`P4!R`-A(FYE=V,BFP,!,P`G?P(-F5A;;4%`A$+@"X@(%1H97)E+``C -M;F_B!P""`@/?"`"3!/("(&EN+7!L86-E(&UO9&EF:6.M"/,";W(@U`P#P!`![ -M``.?`0![``&'"0&C``)*#`,*`P`X"`"R``$>`P"F!`(,`B$@8C<)<7)E861A -M8FP`!@","@$,``$L"P($`0!H``([`$)E86-H/0$A=F5S`Q-Y0P!0:6YD97"J -M`"5N="(!`!@)4&%R=&EC0@4D;VZ!`02N`$17:6MI4@PP:6YGR0`P:&]WFPP" -MI@<'E@H"*@$A3VX_"`#W#`)X!@$""B-N9/@``8@)8V%L=V%YD`!RT`!"T'`,T`%&^5"'`I+"!I="!W<`!Q(&=E="!P -M=9P-(&ENI`0W($EN;@`W+"!IG@`(FP`B96[)`02UV```S#`#W -M"!%IAP8`A`!P96YV:7)O;M<",7,@=Y`#`:`"$&W8`1-R6@,%,`(`6P`"?P`1 -M>7L#$7`U`-%A=&5V97(@8FQO8VMS\```[@`A$)P`$`B0`P;6%K>0"0:7,@ -M97-P96-I;@0!T`$"J@$`.@@P.B`BDPH!#A$)V@T3(KD"`-X.(F%NZ`(`I0<& -M-`H0+&,`0&1EF-%#A)B!P`2>`<``$D!`)() -M`"<`02H@97@;$T!S.B!3,@-4'2(`"%P=6<0,"`B8S0&%"*\&3EO;VQ-``)6`08U`0"4``"P"@&.`0]M -M`0$`(`T!$!H!V@$T90HGL``C92>O&0,D!`"3``!.``]D&O______________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________5E`@("!T -M;SL1``#R-B!B92!R96%D(&]R('=R:71T96X@=&\@86YY(&1A=&$@7,N"E)%041-15``1"!L:6)M`=%B=6YD;&4N"@I1=65SK@"@/R`@27-S=65S -M/U(`UBH@:'1T<#HO+W=W=RXX`$`N;W)GDP``2`$Q:&]MIP"`(&]N9V]I;F8$(&YD -MT`(Q9G5L+P(&10!1+VUI;FF%`1%AXP%186-T('-@`+`@9&5M;VYS=')A=+\`!,GK0`#)`0`DP``3@#U`2YA;2P@86-L;V-A;"YM-"SA -M`$!E+F%C_P```@`0+:("`)\`!*@`#*($LBP@;VYL>2!N965D?``Q;6%I]@$C -M97*N`05P`"1I;F0`@2YH+FEN"@DM]`=2;&%T97-G`!%B-`(!9@$39;4`8`H* -M1W5I9/,`*"!$5`8$T@$"=0`!MP%P!1%E^P,`\@"`;6%T``&I`5"`"X!!,B?P(R+F@BJ0`R:&4*7PP0(+`)`'4!`!0`!.D&`W((`G\"-&UO -M2X`P"`H8FEG+65N9&EA;J(!8VQI='1L91$``OH`\0))4T\Y-C8P -M($-$+5)/32!I;;<"$"@X#C`@;W#+`\!A;"!2;V-K[`@0]`5HW+5II<"8` -MV$UI8W)OFEP/@$Q:6]N -M&`%=8GII<#(6``1\`4TO3%I7'0"B;'IM82P@;'II\+`OH#`*D" -M`&@1`HT``88!`MH`#Y8#!0'(`V$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0% -M!`?.``]9`P`*%@,S5VAE`P(`&@T#U`(2<^8%87)E`3AN97>U`P#P!`#]`@.?`0![ -M``&'"0&C``)*#`!-$2)I7-S""IE9(H(`D<`L$DG=F4@ -M871T96UPC```%1`0.;`")E;LD!!RT``'P`"W$`*&1E$0`#Q@(1+.4)`H```(T. -M`)8!`!8!`$``,&%G8?,/`5\*D6-O7L#$7`U`&)A -M=&5V97)X%Q%S\```[@2X'$'1[%R%I;5<#<6]R(&UM87`I`0!>$P'Y%@*Y%P"V`A!G -MPA<0:2(3`2(`!4H``.,3(6-EA0`A3VZ0`QMEPP`"Y`(R<')O.@$!A0$`FA<1 -M+408DF5D(&]U='!U=.\"`&`$\0-O8FIE8W0M$E33SDV-C`3 -M`+0W+5II<"!AFUA+"!L>FEP+"!A;F0@>'HC`,$*3F]T97,@86)O=724 -M`')L:6)R87)YT0#P+G1E8W1U2!S -M=')E86TM;W)I96YT960@4,`4&EN9&5PJ@`B;G1_`$%R92!A!`"4=&EC;&5S(&]N@0$#=@+P -M`2!7:6MI(&5X<&QA:6YI;F?)`#!H;W?X``+U``$N("!)9B!Y -M;W4@9&]N)^P!`+8`\0)I8VET;'D@:6YV;VME(&$@<.L`@'5L87(@9F5A60)` -M("AS=2\!&7,<`A!AZ0`'+0`'!@,`@`$"F0%P*2P@:70@=W``\``@9V5T('!U -M;&QE9"!I;BX^`"=);FX`-RP@:9X``5$!`YL`(F5NR0$'+0``/@`+<0`H9&41 -M``/&`A$L\``"@``B;F6.`@`6`0!``&)A9V%I;G-'`J!C;W)R97-P;VYD)P0( -M20`-6@`">P,Q:65SPP`!;P.P86QS;R!R961U8V6;`C!E('.%`2-O9H@!`+,! -M$"UV`&%E9"!B:6X]`"`@:2P$@"!E;G9IP,1<#4`T6%T979E8!(71O(@`%2@!A="!O -M;F-EA0`A3VZ0`QMEPP`"Y`(R<')O.@$!A0%18W1L>2W,`))E9"!O=71P=73O -M`@!@!/$#;V)J96-T+7-T>6QE(&%P<')OR`,`H`4"^@#@=&\@:&%V92!M=6QT -M:7`E``.E`P(!!`!;!E4@;W!E;IX`L2`@8G-D=&%R('5SO`$`/06#;B!I=',@ -M(D#E`!(BR`-&P"`*`'`2L`,VEN("8<``J,!!H`%,7=A;H@`$'0V -M!`5%`0!@`!!IA0(`C@%EB!$!G&%)`$!S.B!3,@-4`0-)`#!C;VY#`O`".B`@5F%R:6]UP``7P%V875T:&]R,&`4D!A69I9W5R92`M#``"1`"U'2(`")P==8-(")C-`81 -M(B0#`#@,*6]L30`"5@$&ZP,!*0$`%@D`C@$/;0$!`*(&('5SW0H`V@$T90HG -ML``C92>M``,D!`"3``!.`/``+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C%P$` -M`@`0+:("`)\`!*@``-D."*($$BP:#@#7"P)\`#%M86GV`2-EPH"MP(29:`,`!(&0'-E<77J"!!S"P4!/@$`=0``%P(` -M^00!<0`!<0H(EP``/`DS>2XS30``[P0R92`B:P,%JP`!)``4(@L+62!C;&%S -M1``!'PE&;F%L"`"X!!,B!0XR+F@BJ0`R:&4*7PP0(+`)`/H``!0`!.D&`W((`G\"-&UO -M5$P`P%&!E+``-J`0`9`[$J(%!/4TE8('5S=+`1!!``#XH,`P%\``(Q`%9O -M8W1E=*\4`&`"`1X`H5-64C0@05-#24ET`@$4``\R``L00FT1$7DN`+$@*&)I -M9RUE;F1I8=018VQI='1L91$``OH`!%\6D4-$+5)/32!I;;<"$"@X#C`@;W#+ -M`\!A;"!2;V-KC2H`0#E%PD(`0``"@*<$`5+`0!U!`\&`0("@P$#OP," -MO`(/'P,8,")R9:`-`!`6$2)'`P)/`,(L('=H:6-H('=I;&SK&`!P"`###P-? -M`4!S(&5X+10``@(`N04$B1$""Q<#6A4P`T&-P:6\N-2P@;71R964)``!O`%1T87(N-;<`PB!D -M971A:6QE9"!I;E(`D&EO;B!A8F]U=$T`('-EN`"#<&]P=6QA#0#46-H86YG?@$W -M;6%T(0"P;V-T970M;W)I96X!`P!@`@$>`*%35E(T($%30TE)=`(!%``"4P`/ -M,@`%84)I;F%R>2X`P"`H8FEG+65N9&EA;J(!8VQI='1L91$``OH`\0))4T\Y -M-C8P($-$+5)/32!I;;<"@"AW:71H(&]PRP/`86P@4F]C:W)I9&=E10!B2F]L -M:65T*0$![P$"20`T6DE05@,$0`#`=6YC;VUPB,``!DT%``)"`&58V%N(&-R96%TSP`!=00/!@$"`J\!`[\#`KP"#Q\# -M&,$B!S>7-T96TN("!4:&5R92P`(VYOX@<`@@(#WP@`DP3R`B!I;BUP;&%C92!M -M;V1I9FECK0CS`F]R(')A;F1O;2!A8V-E0`&@`3R`FES(&1EP`#P`!APD!HP!4(&]N;'D* -M`P`X"`"R``$>`P"F!`(,`B$@8C<)<7)E861A8FP`!D%W48!`-T!*F5DB@@"1P"P22=V92!A='1E -M;7",!^!T;R!M:6YI;6EZ92!S=+4(`E((4'!O;&QU(@=1+B`@26;U"$!D;VXG -MU@7L#$7`U`-%A=&5V -M97(@8FQO8VMS\```[@2X'<70@82!T:6U7`P!K"S%M87#X`C!E;G21!@/0`@%1 -M`T!G:79EY@$A=&\B``6A`&%T(&]N8V6%`"%/;I`#&V7#``+D`C)P@``P0&%82!S;V-K970^ -M`TEW:7-HN@0!)@]P=71I;&ET>7,"!8P``#\``TP/4"!E87-Y3@Y1=7-E("(A -M`0!:""`L(E`(<"P@8V%P86)!``'V`@0#`07Q`&%E($%027.W!`CV!0&7`8`@ -M:6YD:79I9&P.`]L(`(4``A4&`$(``'(+`-$``#8!(71OK`TP9&%TUP``!0X6 -M.BX!`L@)`#T`$F'L`@#)"@$K`#-I;B`G`0"5"S-A9&2.`AAA]PP!UP<#'@]1 -M9FER0"0:7,@ -M97-P96-I;@0!T`$"J@$`.@@P.B`BDPH!#A$)V@T3(KD"`-X.(F%NZ`(`I0<` -M$0,"6@<0+&,`0&1E8N9V]O -M9VQE+F-O;2]P+VH`$2\Z`"!S+VD``),``6<`47-U8FUI9P!P96YH86YC9<\` -M`*8`!C@`,BP@<-H0`BP``#L```0#`$L'`1<)X65S="!V:6$@1VET2'5BP@`" -MD`"A7!1`GD1(`\A$`%@)S82!F=6QL -M+98(F-%#A)B!P`2>`<` -M`$D!`)()`"<`02H@97@;$T!S.B!3,@-4P``7P%C875T:&]R:1``EPT!\@(`P1,2 -M+NT/4'1O<"UL#`0#Q0P`,`0&";8""',5`.L%`>X/\`4@*B!.15=3 -M("T@:&EG:&QI9VAT<]P`,')E8]D4`C$%`Z`"DD-/4%E)3D<@+0P%`$(4`,H' -M(61O7P8!AP4`S@#`*B!)3E-404Q,("T@9`HQ86QLCP0!#0``BA8`OP`"*0`# -M0`41+3P``5X1`A@`8&-O;F9I9[(6%2T,``)$`+5S8W)I<'0L('-E96<``"@% -M`ED6`F,(@2H@0TUA:V5,U`0Q='ATB``A<'5G$#`@(F,T!A$B)`,`.`PI;VQ- -M``)6`0;K`P$I`0`6"0".`0]M`0$`(`T0=3T3`A`7)`HGL``C92>M``,D!`"3 -M``!.`/``+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C_P```@`0+60"`)\`!*@` -M`-D."*($$BP:#@#7"P!9"Q!YR@4!]@$C97*N`05P`"1I;F0`@2YH+FEN"@DM -M]`<`YA,2\%#V0:____________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________]G4&%N(&ES-1$``/`02#R`I!I;VYS+@H*5&B=`?("<"UL979E;"!D:7)E8W1O'2(`#!P=71>`H$@(F-M86ME(B0#:60@ -M=&]O;$T``E8!!NL#`2D!,2!I;DP!#VT!`3!A2!N965D?``Q;6%I]@$C97)<`05P`"1I;F0`\@,N:"YI -M;@H)+2!T96UP;&%T97-G`!%B-`(!9@$39;4`8`H*1W5I9/,`4"!$;V-UF04" -M@0$`Q0$R86QL=0`!MP&R'!L@P(#+P,`0@$" -M(0`$F@,#,P``B`0/-``+`"(`##4`+V%T-``,*&%T,P`&`0:`+C,@9VEV97-X -M!H!O=F5R=FEE=_,"`*``!+L%$&%Q!3!W:&^1`B,J(,0&A5]R96%D+C,L$``` -MT04=91$`45]D:7-K%@`@;F30`0@^``,<``"9`!!V7P$"MP)P960@8V%L;!(& -M$'/4!D%N8V5SK0(`DP``=0`!1P`#0@9H92!!4$ESEP!S96YTP$2+8($ -M4W,N-2!D5@("KP``&0,`\@#$;6%T=&%R+C54`0CQ!$%A8F]U4P4@P`3+/('`(H!@6AA``%4!%#0#`ED'`W@"!R$`L&]C=&5T -M+6]R:65N`0,`8`(!'@"A4U92-"!!4T-)270"`10``E,`#S(`!6%":6YA`@@;W#+`\!A;"!2;V-KFEP/@$Q:6]N&`%=8GII<#(6 -M``1\`4TO3%I7'0"B;'IM82P@;'II`3AN97>U`P#P!`![``.?`0![``&'"0&C``)* -M#`!-$2)IF4@``%1`0.;`")E;LD!!RT``'P`"W$`*&1E$0`#Q@(1+/```H```(T.`)8! -M`!8!`$``,&%G82X.`?$)D6-OP,1<#4`T6%T979E$P$/`P$W%0%1`T!G:79E -MY@$A=&\B``5*``#C$R%C984`(4]ND`,;9<,``N0",G!R;SH!`84!46-T;'DM -MS`"2960@;W5T<'5T[P(`8`3Q`V]B:F5C="US='EL92!A<'!R;\@#`/D4`OH` -MT'1O(&AA=F4@;75L=&G#$P2I``(!!`"Y"%4@;W!E;IX`$R`5$`!J$``*`1%I -M(0AC:71S(")`/``2(KT$$7,P#@)C!098`&!I='-E;&93`5!R96%D+^8`8'1E -M;B!U@``S0*%82!S;V-K970^`TEW:7-HN@0! -M)@\#60\`7,N"B05 -M$6:X#01/&0.A&$0N"@I1$19`/R`@29X9(',_4@`1*@49=CHO+W=W=RXX`$`N -M;W)GDP``2`$0:+@"`%<`0V]N9V]8!Q<@3`<@(&18%B!O<#P%"!D1!+H1`:P( -M`3<,`'$``#H`(&YK-`$!P0`&7,@9&5T96-T960@875T;VUA -M=&EC86QL>4<`L$DG=F4@871T96UP(@#P(71O(&UI;FEM:7IE('-T871I8R!L -M:6YK('!O;&QU=&EO;BX@($EF('EO=2!D;VXG=*@``+8`\"1I8VET;'D@:6YV -M;VME(&$@<&%R=&EC=6QA!E('-O;64@=71I;&ET>3X`!8P``+$!\09P2!D8737`%9UP",B!O9BL`,VEN("X -M`0!V``*4`0```P&^``7+`0#3``.C`0:`!3%W86Z(`!!T-@0#-@(!6P,`'P$` -MN@!!9&ES:RP#`\0!N6-O;G9E;FEE;F-EP`$`B0`P;6%K>0"0:7,@97-P96-I -M;@0!T`$"J@'S!TYO=&4Z(")P87@@:6YT97)C:&%N9V6?!1,BN0(@;&P\`0+H -M`A!DO@$`_04!C080+&,`0&1E0(1.FH`$B>7!9`G('!R;V=R86T6`G-A(&9U;&PME@AP9"`G=&%R)WX``P(` -M4W)E<&QA0@%`8G5I;($&`(H``V,``"H`9BH@8W!I;V,```X`"V0`(&1I:P4R -M96YT,`-#9F%C96H#`P(`,&5S`<``$D! -M`)()`"<`4"H@97AA20!`8$ -M(&YDT`(Q9G5L+P(&10`0+T,*`84!$6$&"5%A8W0@`0-)`#!C;VY#`O`".B`@5F%R:6]UP``7P%Q875T:&]R<\`%`1\& -M`?("`DT'$`J(!E!T;W`M;`P$`W8%`#`'`4$`$&GD!@FV`B)I;M8$`'$+`.L% -M!+T"\`).15=3("T@:&EG:&QI9VAT=&%R+C54`0CQ!$%A8F]U4P41 -M]!9!I;@IA(&YU;6+R#!=FD0<$.P''"@I9;W4@`D09@82`;<&42H@1TY5=0$"-0(F("@$"P`:`"-L;[P% -M`*T+(G,L$```!0L3(!$``&,`4G-P87)S?`(A`*%35E(T($%30TE)=`(!%``/,@`+ -M$$)M$1%Y+@"Q("AB:6`@@;W#+`\!A;"!2;V-K[`@0]`5HW+5II<"8`V$UI -M8W)OFEP/@$@:6]/$WTJ -M(&)Z:7`R%@`$?`%-+TQ:5QT`HFQZ;6$L(&QZ:7`3`R]X>B,``!DT%``)"`$` -M``H"G!`%.@$`=00/!@$"`J\!`[\#`KP"#Q\#&#`B\+`OH#`*D"`&@1`HT` -M`9L!`MH`#\@#"F$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0%!`?.``]9`P`* -M%@,S5VAE`P(`OP@#U`(2<^8%87)E -M`3AN97>U`P#P!`#]`@.?`0![``&'"0$K%0)*#`,*`P`X"`!O$!1T[A("#`(A -M(&(W"0","@&/&`.X%`$,`!!A#`$"U!``:``".P`199P6`#T!(79E4,` -M4&EN9&5PJ@`E;G0B`0!$#0%Y&0!"!1)O;`T&L`L/9!K_________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_________________________________________________V50=',Z"B`P -M$0``\0T@*B!'3E4@=&%R(&9O`*935E(T($%30TE)%``"8P`/,@`%84)I;F%R>2X`\P<@*&)I -M9RUE;F1I86X@;W(@;&ET=&QE$0`"^@#P'TE33SDV-C`@0T0M4D]-(&EM86=E -MFEP/@$Q:6]N1`!=8GII<#(6``1D`4TO3%I7'0"B -M;'IM82P@;'IID#`*4#`.<#]A)U2!S=')E86VU!>!S>7-T96TN("!4:&5R92P`D&YO(&1I -M-R86YD -M;VT@86-C97-S+GD`!I<`D&ES(&1EU -M`P"C!`![``'.`!!VFP0`-0<2$N("!)9B!Y;W4@ -M9&]N)^P!`+8`\0)I8VET;'D@:6YV;VME(&$@<.L`('5LO0B@96%T=7)E("AS -M=2\!&7,<`A!AZ0`'+0`$10<#(@("F0%P*2P@:70@=W``X"!G970@<'5L;&5D -M(&ENI`0W($EN;@`W+"!IG@`!40$#FP`B96[)`07L#$7`U`-%A=&5V97(@8FQO8VMS\```[@2X'<70@82!T:6U7`W%O8!(71O(@`%H0!A="!O;F-EA0`A3VZ0 -M`QMEPP`"Y`(R<')O.@$!A0%18W1L>2W,``"."5)U='!U=.\"`&`$\0-O8FIE -M8W0M2!B=69F97(@ -M)`@`90`$<@&%82!S;V-K970^`TEW:7-HN@3`P" -M`,D*`2L`,VEN(">D``,P``*,!!H`%,7=A;H@`$'0V!`5%`0!@```:!!!TC@7,N"E)%041-1;L&!^@&X2!B=6YD;&4N"@I1=65S^@*@ -M/R`@27-S=65S/U(`URH@:'1T<#HO+W=W=RX@!S!O3``!(`1!HN`*#9F]R -M(&]N9V]8!Q@@9`!P9&5V96QO<#P%)BP@8`]`9&]C=10``:P(`3<,`'$``#H` -M(6YK70$`70`&8N9V]O9VQE+F-O;2]P+VH` -M$2\Z`"!S+VD``),``6<`47-U8FUI9P!P96YH86YC9;L``#8"!C@`@RP@<&QE -M87-E+```.P``!`,`2PB!$!G0&";8"(FENU@0`I`H`ZP4$ -MO0+P`DY%5U,@+2!H:6=H;&EG:'1S7`8PM```Z#S`@*B"3``!.`/``+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C_P`` -M`@`0+:("`)\`!*@``-D."*($$BP:#@#7"P!9"Q!YR@4!]@$C97*N`05P`"1I -M;F0`@2YH+FEN"@DM]`<`YA,22XS]!0P86EL[P0R92`B:P,%JP`!)``4 -M(@L+62!C;&%S1``!'PE&;F%L``'? -M`5&%M<&QE('!R;V=R86US('1H870@>6]U(&UA>2!F:6YD('5S969U -M;"X*("`@*C``\@=S+VUI;FET87(Z(&$@8V]M<&%C="!S2P#09&5M;VYS=')A -M=&EN9SX`XR!O9B!L:6)AM`_`$ -M,R!G:79E2XS!`,!JP(2(FL#!:L``20`Z2(@=71I;&ET>2!C;&%S -M1`"6:6YT97)N86QSG0!@P$2+8($4W,N-2!D5@(#I@0@:6QV`]1R -M;6%T-50! -M"/$$4&%B;W5T&@$@P"`+"!I;F-L=62*`8%H -M87)D+71O+3`&`J@!$G-'``!!`&%M;V1E$D#(F5R60<#>`('(0"P;V-T970M;W)I96X! -M`P!@`@$>`*%35E(T($%30TE)=`(!%``"4P`/,@`%,$)I;LH$`$(`H"`H8FEG -M+65N9&GS!(-R(&QI='1L91$``OH`\0))4T\Y-C8P($-$+5)/32!I;;<"$2AX -M""!O<,L#P&%L(%)O8VMR:61G944`8DIO;&EE="D!`>\!`DD`-%I)4%8#!$`` -M('5N3@DPFEP/@$Q:6]N&`%=8GII<#(6``1\`4TO -M3%I7'0"B;'IM82P@;'II?P( -M-F5A;;4%`A$+@"X@(%1H97)E+``C;F_B!P""`@/?"`"3!/("(&EN+7!L86-E -M(&UO9&EF:6-D"_``;W(@0`&@`23:7,@9&5S:6=N -M)0P298@%`$`$`;,%.&YE=[4#`/`$`'L``Y\!`'L``8<)`:,``DH,`PH#`#@( -M`+(`,71H82\)`RL`(2!B-PD`:@@Q86)L``8`C`H!#``!+`L"!`$`:``".P!" -M96%C:#T!(79E4,`4&EN9&5PJ@`E;G0B`0`8"0`/#Q!C0@42;VP-!C4* -M5"!7:6MI4@PP:6YGR0`P:&]W40\!LP,79)8*`BH!(4]N/P@`]PP"8`8#`P$$ -MS0`!<`!`;'=A>48!`-T!*F5DB@@"1P!P22=V92!A="T-`(P'`,$/D&EN:6UI -M>F4@P,1<#4`T6%T979EP" -M`,D*`2L`,VEN("#U%F:7)S=)("`*8!$6%P -M$A%O61$`]@`6+G0``]D#`J60!`,P``*,!!H`%,7=A;G\%$G0=#P-%`0!@```:!!!TC@0# -M`',*%EF-%#A)B!P`2 -M>`<``$D!`)()`"<`!A\:,#H@4S(##V0:____________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________________________________]J4'(@71E(&%T -M(&$@=&EM90H@("!O2UB;&]C:V5D(&]U='!U="X*"B`J(%1H92!O8FIE8W0M -M'1E;G-I;VZ*``,<```J`#!E;&93`5!R96%D+^8`EG1E;B!U2!B=69F97(@;W+!``!E``1R`3!A(',K`5%T+"!I9@(!8'=I -M2UT;RUU`@#1```V`:!T;R!A;GD@9&%TUP!6=7)C93HN`5%C`@&^``7+`0#3``.C`4,N("!)I`$A86Z(`!)T70`#10$`8``0 -M:84"86\@9&ES:RP#`\0!N6-O;G9E;FEE;F-EP`$`B0`P;6%K>0#1:7,@97-P -M96-I86QL>=`!`JH!\P].;W1E.B`B<&%X(&EN=&5R8VAA;F=E(&9O7,N"E)%041-12X``$0$!&T!T6)U;F1L92X*"E%U97/Z`J`_("!)0(1.FH`$B>7!1`G'@9`9W)A;18"\`9A(&9U -M;&PM9F5A='5R960@)W1A`<``$D!0'-U8V@G`%`J(&5X84D`0',Z(%,R -M`U1S;6%L;!4`!#X!`%(#(6%T(`8@;6'F!"!N9-`",69U;"\"!D4`42]M:6YI -MA0$18>,!46%C="!S8`"P(&1E;6]N0&";8"(FEN^`0B:6_A!@2]`O`"3D574R`M(&AI9VAL -M:6=H='-M``,D!`"3``!. -M`/4!+F%M+"!A8VQO8V%L+FTT+.$`0&4N86/_```"`!`MH@(`GP`$J``,H@2R -M+"!O;FQY(&YE961\`#%M86GV`2-E'!L@P(#+P,`0@$"(0`$F@,#,P``B`0/-``+`"(`##4` -M+V%T-``,*&%T,P`&`08A+C.V"Q!SWP:`;W9E"P!Q!3!W -M:&^1`A0JI`J%7W)E860N,RP0``'X"`T1`%%?9&ES:Q8``GX'`X(%`3X``QP` -M`)D``7L*`K<"$F6@#`!;!!!SU`80;A$,`-8"`),``'4``!<"`/D$`7$``7$* -M")<``#P),WDN,TT``.\$,F4@(FL#!:L``20`%"(+"UD@8VQA``'<`%`D09BP``;<&42H@1TY5=0$"-0(F("@$"P`:`$%L -M;VYG4`8`K0LB+``-J`0`9`]$J(%!/4TE8('5S=&%R6P`" -M$``/B@P#!R$`P&]C=&5T+6]R:65N=!<$,7!I;QX`IE-64C0@05-#24D4``)3 -M``\R``5A0FEN87)Y+@#`("AB:6B,``!DT -M%``)"`$```H"G!`%.@$`=00/!@$"`J\!`[\#`KP"#Q\#&,$B&-E<$`%`+D%!(D142!T -M:&%T0PX`TQ,`40`%Z1(P?P(-F5A;;4%`A$+!8@40&ES(&[6$C%R96,P$0/?"`"3 -M!$$@:6XM`@^"(&UO9&EF:6/E#/<`;W(@`3AN97>U`P#P!`#]`@.?`0![``&'"0$K%0)*#`!-$2)I -ME(7`+4(`E((07!O;&PV$@;D%$%D;VXG[`&097AP;&EC:71LV0EB=F]K92!A -M^@\18W\*`\X1("`HTA``=0P('`(08;(!`2<0`BT`",T`%&]S!'`I+"!I="!W -M<`!0(&=E="#2$@%="@"D!#<@26YN``4F%P&>``%1`0.;`")E;LD!!RT``'P` -M"W$`*&1E$0`#J@`1+%@1`H```(T.`)8!`!8!`$``,&%G8?,/`5\*D6-O"(&5N=FER;VX/"T!W:&5R+Q9`870@;=@!$W): -M`P4P`@!;``)_`!%Y>P,1<#4`8F%T979EFEP(&-O;7!R97-S:6]N%0!=8GII<#(6``0F -M`$TO3%I7'0#_`VQZ;6$L(&QZ:7`L(&%N9"!X>B,``!DT%`#U!PI4:&4@;&EB -M2!C86X@8W)E873/`+%S(&EN(&%N>2!O9N8`8&9O;&QO=_0``21E9-T` -M$2E%``"=``#5`85"4T0@)V%R)U(``1X`>"=M=')E92>[`'A)4T\Y-C8P$P!: -M-RU::7`Y`#9805(1`$,*5VAE`P(`Y`$#U`(AT!X'-Y -M0`&EP#R`FES(&1E -MP`!S@`4=E@#$G.C -M`%0@;VYL>0H#0&UE;G2R``$>`P"F!`)G`S`@8F5``(!R96%D86)L9:(`07=R -M:70,`!!A#`$"!`$!1`0!.P!$96%C:"8"`98"$WE#`%!I;F1E<*H`(FYT?P`0 -M)`#!H;W?X -M``+U``".!`,L``(J`2%/;JH`'"P#`0/9`@)P`$!L=V%Y1@$`W0'R`65D(&%U -M=&]M871I8V%L;'E'`+!))W9E(&%T=&5M<,0#X'1O(&UI;FEM:7IE('-T*P"P -M(&QI;FL@<&]L;'6X`>$N("!)9B!Y;W4@9&]N)^P!`+8`\0)I8VET;'D@:6YV -M;VME(&$@<.L`('5L-P0@96%9`D`@*'-U+P$9``%1`0.; -M`")E;LD!!RT``'P`"W$`*&1E$0`#Q@(1+/```H``(FYEC@(`%@$`0`!B86=A -M:6YS1P*@8V]RP,1<#4`T6%T979E2!B=69F97(@)`@`90`$<@&%82!S;V-K -M970^`TEW:7-HN@3`P"`,,)`2L`,VEN("0#`',*T"!S87ES -M+@I214%$346[!@?H!N$@8G5N9&QE+@H*475E<_H"H#\@($ES8N9V]O9VQE+F-O;2]P+VH`$2\Z`"!S+VD` -M`),``6<`47-U8FUI9P!P96YH86YC9;L``*8`!C@`@RP@<&QE87-E+```.P`` -M!`,`2P7!1`GH@1`9W)A;18"F-%#A)B!P`2>`<``$D!`)()`"<` -M4"H@97AA20!`8$(&YDT`(Q -M9G5L+P(&10`0+T,*`84!$6&>"E%A8W0@H($',+!0$^`0!U```7`@#Y!`%Q -M``%Q"@B7```\"3-Y+C--``#O!#)E(")K`P6K``$D`!0B"PM9(&-L87-$``$? -M"49N86QSG0`2!Q(M@@0U -M"`"X!!,B!0XR+F@BJ0`R:&4*7PP0(+`)`/H``!0`!.D&`W((`G\"$&T:%P/[ -M`$(N("!0B@FS;&5T('5S"FMN;W>5$P`P%&!E2X`L2`H8FEG+65N -M9&EAU!%C;&ET=&QE$0`"QP`$7Q:10T0M4D]-(&EMMP(0*#@.,"!O<,L#P&%L -M(%)O8VMR:61G9>\!`DD`#QX78P\+%P#036EC84`X"!S8W)I<'0* -M"D=U:61E@@"01&]C=6UE;G1A>`""(&EN'!L86EN3`1!F+``P'1E;J`*%35E(T($%30TE)=`(!%``"4P`/,@`%84)I;F%R>2X` -MH"`H8FEG+65N9&GS!(-R(&QI='1L91$``OH`\0))4T\Y-C8P($-$+5)/32!I -M;;<"@"AW:71H(&]P^@7`86P@4F]C:W)I9&=E10!B2F]L:65T*0$![P$"20`T -M6DE05@,$0`"0=6YC;VUPB,``!DT%``)"`&5 -M8V%N(&-R96%TSP`!=00/!@$"`NP"`[\#`KP"#Q\#&#`B&-E<$`%`+D%!&D"L"!T:&%T -M(')E<75IE@4G87C*`B`@*'T'`30$`(0!`S,$`/0#<2P@971C*2YO`0#Z`P"I -M`@8B!`$7``+:``^6`P4!R`-A(FYE=V,BFP,!,P`G?P(-F5A;;4%`A$+@"X@(%1H97)E+``C;F_B!P"" -M`@/?"`"3!/("(&EN+7!L86-E(&UO9&EF:6.M"/,";W(@U`P#P!`![``.?`0![ -M``&'"0&C``)*#`,*`P`X"`"R``$>`P"F!`(,`B$@8C<)<7)E861A8FP`!@", -M"@$,``$L"P($`0!H``([`$)E86-H/0$A=F5S`Q-Y0P!0:6YD97"J`"5N="(! -M`!@)4&%R=&EC0@4D;VZ!`02N`$17:6MI4@PP:6YGR0`P:&]WFPP"I@<'E@H" -M*@$A3VX_"`#W#`)X!@$""B-N9/@``8@)8V%L=V%YD`!RT`!"T'`,T`%&^5"'`I+"!I="!W<`!Q(&=E="!P=9P-(&EN -MI`0W($EN;@`W+"!IG@`(FP`B96[)`02UV```S#`#W"!%IAP8` -MA`!P96YV:7)O;M<",7,@=Y`#`:`"$&W8`1-R6@,%,`(`6P`"?P`1>7L#$7`U -M`-%A=&5V97(@8FQO8VMS\```[@`A$)P`$`B0`P;6%K>0"0:7,@97-P96-I -M;@0!T`$"J@$`.@@P.B`BDPH!#A$)V@T3(KD"`-X.(F%NZ`(`I0<&-`H0+&,` -M0&1EF-%#A)B!P`2>`<``$D!`)()`"<`02H@ -M97@;$T!S.B!3,@-4'2( -M`"%P=6<0,"`B8S0&%"*\&3EO;VQ-``)6`08U`0"4``"P"@&.`0]M`0$`(`T! -M$!H!V@$T90HGL``C92>O&0,D!`"3``!.`(\N86TL(&%C;&0:____________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________________________________________________]J4&%N -M>2!D,!$``/`<871A('-O=7)C93H@(%EO=2!C86X@8W)E871E"B`@(&$@8FQO -M8VL@;V8@9"L`\!YI;B!M96UO2!E87-Y+@H*("H@3F]T93H@(G!A -M>"!I;G1E'1E;F1E9#@!`B(` -M$"QC`$!D97-PWP!`=VAA=)8`\`,@;F%M92!S87ES+@I214%$3450`$0@;&EB -M;0'18G5N9&QE+@H*475E`<``$D!0'-U8V@G`%`J(&5X84D`0',Z(%,R`U1S -M;6%L;!4`!#X!`%(#(6%T?`0@;6'F!"!N9-`",69U;"\"!D4`42]M:6YIA0$1 -M8>,!46%C="!S8`"A(&1E;6]NM``,D -M!`"3``!.`/4!+F%M+"!A8VQO8V%L+FTT+.$`0&4N86/_```"`!`MH@(`GP`$ -MJ``,H@2R+"!O;FQY(&YE961\`#%M86GV`2-E7-T96TZ<`<"N`1U+C$@97AP;(,"`R\#`$(!`B$`!)H#`S,``(@$#S0` -M"P`B``PU`"]A=#0`#"AA=#,`!@$&@"XS(&=I=F5SWP:`;W9EP$2+8($-7,N-:H(`)X%$67[`P#R -M`(!M871S('-U<'\(!&,"!98!`$P```H"D"XU+"!M=')E90D``&\`7G1A`D09BP``;<& -M42H@1TY5=0$"-0(F("@$"P`:`$%L;VYG50(`K0LB+``-J -M`0`9`]$J(%!/4TE8('5S=&%R6P`"$``/B@P#!R$`P&]C=&5T+6]R:65N=!<$ -M,7!I;QX`IE-64C0@05-#24D4``)3``\R``5A0FEN87)Y+@#`("AB:6FEP,A8`!'P!32],6E<= -M`*)L>FUA+"!L>FEP$P,O>'HC```9-!0`"0@!```*`IP0!3H!`'4$#P8!`@*O -M`0._`P*\`@\?`Q@P(G)EH`U18W1E9")'`P)/`,,L('=H:6-H('=I;&PF$0)U -M`P:0`%%E>&-E<$`%`+D%`?P(-F5A;;4%`A$+ -M<"X@(%1H97(T$2`@;M82,7)E8S`1`]\(`),$02!I;BVW#X(@;6]D:69I8^4, -M\@%OP`!APD!HP`"2@P`31$B:7*"$1!I>0<# -M[A("#`(A(&(W"0","C%A8FP`!@","@$,``$L"P+4$`!H``([`$)E86-H/0$A -M=F5S`Q-Y0P!0:6YD97"J`"5N="(!`$0-``\/$&-"!1)O;`T&-0I4(%=I:VE2 -M#`,,$S!H;W?X``&S`Q!DK0$#V@`"*@$A3VX_"`#W#`)@!@#S#@!0!@/-``%P -M`%-L=V%Y'!L:6-I#16":6YV;VME(&'Z#Q%C -M?PH#SA$@("C2$"4@8?L*`*$!("!AL@$!)Q`"+0`(S0`4;W,$<"DL(&ET('=P -M`%`@9V5T(-(2`5T*`*0$-R!);FX`,BP@:8(5`9X``5$!`YL`(F5NR0$'+0`` -M?``+<0`H9&41``/&`A$LY0D"@```C0X`E@$`%@$`0``P86=A\P\!7PJ18V]R -M"(&5N=FER;VX/"Q%WD`,!H`(0;=@! -M$W):`P4P`@!;``)_`!%Y>P,1<#4`8F%T979E:89`@4.#V0:____________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________________________________________]@4"`@*B!)1!$` -M`/$14T\Y-C8P(&9OFEP,A8`!"8`32],6E<=`/D#;'IM82P@;'II<"P@ -M86YD('AZ(P#!"DYO=&5S(&%B;W5TE`!R;&EB=$`\"YT96-T=7)E.@H* -M("H@5&AI0`&EP#@:7,@9&5S:6=N960@ -M=&]>`61E>'1E;F1>`3AN97?@``#S`#(*("#.`!!V<@$`X0$22!R97%U:7)E;65N=+(`,G1H80D!`BL`("!BCP&0(')E861A8FQEH@!!=W)I -M=`P`$&$,`0($`0!H``([`$5E86-H;P!396YT'!L86EN:6YGR0`P:&]W -M^``"]0`'+``"*@$A3VZJ`!PL`P$`48!`-T!\@%E9"!A -M=71O;6%T:6-A;&QY1P"P22=V92!A='1E;7#7`>!T;R!M:6YI;6EZ92!S="L` -ML"!L:6YK('!O;&QUN`'A+B`@268@>6]U(&1O;B?L`0"V`/$":6-I=&QY(&EN -M=F]K92!A('#K`(!U;&%R(&9E85D"0"`HD`!RT`!P8#`(`! -M`ID!<"DL(&ET('=P`/``(&=E="!P=6QL960@:6XN/@`G26YN`#``%1 -M`0.;`")E;LD!!RT``#X`"W$`*&1E$0`#Q@(1+/```H``(FYEC@(`%@$`0`!B -M86=A:6YS1P*@8V]R7L#$7`U`-%A=&5V -M97(@8FQO8VMS\``0:$,$(6ETH0!!66]U717`F$@82!T:6U7`W%O`+$@ -M(&)S9'1A3X`!8P``0`"\05R;W9I9&4@ -M96%S>2UT;RUUX`0!V``##``"\`Q)EDP`" -M3P0"0:7,@97-P96-I;@0!T`$"J@$`.@CS -M`SH@(G!A>"!I;G1E`<``$D!`)()`"<`4"H@97AA20!`8$(&YDT`(Q9G5L+P(&10`0+T,* -M`84!$6&>"E%A8W0@"`"X!!,B!0XR+F@BJ0`R:&4* -M7PP0(+`)`/H``!0`!.D&`W((`G\"-&UO5$P`P%&!E+``-J`0`9`[$J(%!/ -M4TE8('5S=+`1!!``#XH,`P%\``(Q`%9O8W1E=*\4`&`"`1X`H5-64C0@05-# -M24ET`@$4``\R``L00FT1$7DN`+$@*&)I9RUE;F1I8=018VQI='1L91$``OH` -M$TE?%I%#1"U23TT@:6VW`A`H.`XP(&]PRP/`86P@4F]C:W)I9&=EYP%B2F]L -M:65T*0$![P$"20`T6DE0=00$0``@=6XQ"P`E%@#6$&!R(")D969^!A$B9@D# -M&```H00C:655`0##`0"B`85"4T0@)V%R)U(``?@`$2?]`Q`GNP(/"Q<(V$UI -M8W)OQ=4`)H`-6QZ-*@!`.47"0@! -M```*`IP0!4L!`'4$#P8!`@*O`0._`P*\`@\?`Q@P(G)EH`T`$!81(D<#`D\` -MPBP@=VAI8V@@=VEL;.L8`'`(`,,/`U\!0',@97@M%``"`@"Y!02)$0(+%P-: -M%P%1``7I$C!S("A3"@$T!`"$`0,S!`#T`V`L(&5T8RGO"P+Z`P"I`@!M``*- -M``&;`0+:``_(`PIA(FYE=V,BFP,!,P`G`'!L:6)R -M87)Y3`#08W!I;RXU+"!M=')E90D``&\`\@IT87(N-2!P2!E2QN``/2`>`@875T;VUA -M=&EC86QL>68!065C='.H``#5``,<`E!O;&QO=Y,!$&8L`*%S.@H@("H@1TY5 -M=0$"4@(F("BY`0`:`$%L;VYG50)B;F%M97,L$`!3;&EN:R`1```W`E)S<&%R -M'1E;J+ -M``-J`0`9`]$J(%!/4TE8('5S=&%R6P`"$``R<&%X-`-18VAA;F=^`3=M870A -M`+!O8W1E="UOFEP/@$Q:6]N&`%=8GII<#(6``1\`4TO3%I7'0"B;'IM82P@;'II&-E<$`% -M`+D%!&D"L"!T:&%T(')E<75IE@4G87C*`E(@*&9O?P(-F5A;;4%X'-Y -MU`P#P!`![``-S!`![``&'"0&C`%0@;VYL>0H#`#@( -M`+(``1X#`*8$`@P"(2!B-PEQ4,`4&EN9&5PJ@`E;G0B`0`8"5!AP,1<#4`T6%T979E6QE(&%P<')OR`,`R0@" -M^@#0=&\@:&%V92!M=6QT:3$,!*D``@$$`+D(`/X-%6Z>`%`@(&)S9",'(75S -MO`$`/06#;B!I=',@(D`\`!(BO0012!F -M0"0:7,@97-P -M96-I;@0!T`$"J@$`.@@P.B`BDPH!#A$)V@T3(KD"`-X.(F%NZ`(`I0<`$0," -M6@<0+&,`0&1E8N9V]O9VQE -M+F-O;2]P+VH`$2\Z`"!S+VD``),``6<`47-U8FUI9P!P96YH86YC9<\``*8` -M!C@`,BP@<-H0`BP``#L```0#`$L'`1<)X65S="!V:6$@1VET2'5BP@`"D`"A -M7!1`GD1(`\A$`%@)S82!F=6QL+98( -MF-%#A)B!P`2>`<``$D! -M`)()`"<`02H@97@;$T!S.B!3,@-4P``7P%C875T:&]R:1``EPT!\@(`P1,2+NT/ -M4'1O<"UL#`0#Q0P`,`0&";8""',5`.L%`>X/\`4@*B!.15=3("T@ -M:&EG:&QI9VAT<]P`,')E8]D4`C$%`Z`"DD-/4%E)3D<@+0P%`$(4`,H'(61O -M7P8!AP4`S@#`*B!)3E-404Q,("T@9`HQ86QLCP0!#0``BA8`OP`"*0`#0`41 -M+3P``5X1`A@`8&-O;F9I9[(6%2T,``)$`+5S8W)I<'0L('-E96<``"@%`ED6 -M`F,(@2H@0TUA:V5,U`0Q='ATB``A<'5G$#`@(F,T!A$B)`,`.`PI;VQ-``)6 -M`0;K`P$I`0`6"0".`0]M`0$`(`T0=3T3`A`7)`HGL``C92>M``,D!`"3``!. -M`/``+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C_P```@`0+60"`)\`!*@``-D. -M"*($$BP:#@#7"P!9"Q!YR@4!]@$C97*N`05P`"1I;F0`@2YH+FEN"@DM]`<` -MYA,2\% -M1FYA;'.=`!)S/@M/:6YS:60:____________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________________________]J4&ME2!F;W(@:L`D'-A -M;64@9G5N8S`<``$D!0'-U8V@G`%`J(&5X84D`U',Z(%-O -M;64@6]U(&UA>2!F:6YD('5S969U;"\"!D4` -M42]M:6YIA0$18>,!46%C="!S8`"A(&1E;6]N2#R`I!I -M;VYS+@H*5&B=`?("<"UL979E;"!D:7)E8W1O%#36%K -M94QI\`!,GK0`#)`0`DP``3@#U`2YA -M;2P@86-L;V-A;"YM-"SA`$!E+F%C_P```@`2+50`)'1OJ``,H@2R+"!O;FQY -M(&YE961\`#%M86GV`2-E7-T96TZ"B`J(+@$=2XQ(&5X<&R#`@,O`P!"`0(A``2:`P,S``"(!`\T -M``L`(@`,-0`O870T``PH870S``8!!H`N,R!G:79E2XS30`"]P,2(FL#!:L``20`4"(@ -M=71II`59(&-L87-$``'O!49N86QSG0`P`D09BP``;<&42H@1TY5=0$"-0(B("BK"0"Y`0`:`$%L -M;VYG4`9B;F%M97,L$`!3;&EN:R`1``!C`%)S<&%R'1E;J+``-J`0`9`]$J(%!/4TE8 -M('5S=&%R6P`"$``R<&%X-`,"60<#>`('(0"P;V-T970M;W)I96X!`P!@`@$> -M`*%35E(T($%30TE)=`(!%``"4P`/,@`%84)I;F%R>2X`P"`H8FEG+65N9&EA -M;J(!8VQI='1L91$``OH`\0))4T\Y-C8P($-$+5)/32!I;;<"$2AX""!O<,L# -MP&%L(%)O8VMR:61G944`8DIO;&EE="D!`>\!`DD`-%I)4%8#!$``('5N,0LP -MFEP,A8`!'P!32],6E<=`*)L -M>FUA+"!L>FEP$P,O>'HC```9-!0`"0@!```*56-R96%TSP`!=00/!@$"`JH# -M`[\#`KP"#Q\#&#`B&-E<$`%`+D%!&D"42!T:&%T0PXQ:7)E40`!\P,!R@(@("@6!0$T -M!`"$`0,S!`#T`V`L(&5T8REF"@+Z`P"I`@8B!`&&`0+:``^6`P4!R`-A(FYE -M=V,BFP,!,P`GD#`*4#(71EVPAA.@H*("H@+1`0:2`*<&AE879I;'G\"#9E -M86VU!0(1"X`N("!4:&5R9;T/(VYOX@<`@@(#WP@`DP1!(&EN+;D``2<0`BT`",T`%&_Y -M"'`I+"!I="!W<`!!(&=E=!D3`5T*`*0$-R!);FX`-RP@:9X``5$!`YL`(F5N -MR0$'+0``?``+<0`H9&41``/&`A$L\``"@```C0X`E@$`%@$`0``@86<##A%T -M\0F18V]RP,B:67-#P%O`P/G"B!D=1D-`)\#$'.% -M`2-O9H@!`(X2$"UV```S#`#W"!%IM`\`A`!R96YV:7)O;@\+$7>0`P&@`A!M -MV`$3<3`<0-0&)A8VOR`S%F2W,`))E9"!O=71P=73O -M`@!@!/$#;V)J96-T+7-T>6QE(&%P<')OR`,`^10"^@#0=&\@:&%V92!M=6QT -M:<,3!*D``@$$`+D(52!O<&5NG@`3(!40`&H0``H!$6DA"&-I=',@(D`\`!(B -MO0012!F4X.``P1$2(A`0!:""`L(E`(H"P@8V%P86)I;&D2%`8#`07Q -M``+S#P$_#@CV!0&7`8`@:6YD:79I9&P.`]L(`(4``#H2`D(``*P+`-$``#8! -M(71OK`TP9&%TUP``!0X6.BX!`L@)`#T`$F'L`@#)"@$K`#-I;B`G`0!%!3-A -M9&2.`AAA]PP!J0H#'@]19FER41`.'1E;F0@ -M;&EB87)C:&EV92X*"B`J($]N(')E860L(&-O;7!R97-S:6]N(&%N9"!F;W)M -M870@87)E(&%L=V%Y2!A -M8V-E<#4`T6%T979E2W,`))E9"!O=71P=70&`>!4:&4@ -M;V)J96-T+7-T>1`"4'!P!E -M('-O;64@=71I;&ET>3X`!8P``0`"\05R;W9I9&4@96%S>2UT;RUU"!I;G1E0#\`)N86UE('-A>7,N"E)%041-12X`!^@&X2!B=6YD;&4N -M"@I1=65S^@*@/R`@27-S=65S/U(`URH@:'1T<#HO+W=W=RX@!S!O3``!( -M`1!HN`*P9F]R(&]N9V]I;FH&0&%N(&FW`!`L(00!_``!#P"A('1R86-K97(@8B!$!G -MF-A="P@8@<`$G@'``!)`0"2"0`G`%`J(&5X84D`0',Z -M(%,R`U1S;6%L;!4`!#X!`%(#(6%T'`@@;6'F!"!N9-`",69U;"\"!D4`$"]# -M"@&%`1%A!@E186-T('-@`+`@9&5M;VYS=')A=+'2(`")P=;H+(")C-`81(B0#`#@,*6]L30`"5@$&ZP,` -ME``!%@D`C@$/;0$!`&8(('5SW0H`V@$T90HGL``C92>M``-G`0"3``!.`/`` -M+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C_P```@`0+:("`)\`!*@``&H+"*($ -M82P@;VYL>=<+`GP`,6UA:?8!(V5RK@$%<``D:6YD`($N:"YI;@H)+?0'4FQA -M=&5S9P`18C0"`W(!`K4`8`H*1W5I9/,`*"!$5`8$T@$"=0`!MP%PP`( -M2PE`:&%R9!8,`3`&!%L!`4<``(X!86UO9&5R;H\``.@!`+P'<"!V87)I86Y( -M"0":!3!M86[X"T%P86=E.```,0XD``$=`U=H+`#L'`2,)"=H1`,$",&5C=)D#$62V#P,<`@5X"1!F -M!A(!MP91*B!'3E5U`0(U`B8@*`0+`!H`(VQOO`4`K0LB+ -M``-J`0`9`[$J(%!/4TE8('5S=+`1!!``#XH,`P%\``(Q`+!O8W1E="UO\!`DD`-%I)4'4$!$``('5N -M,0L`[!,`UA!@"T4``("`+D%!(D1`FL4`$,.`-,3`%$``;$6`0`&@`0I:7-N%")B98@%`$`$`5X!.&YE=[4#`/`$`/T"`Y\! -M`'L``8<)`2L5`DH,`PH#`#@(`&\0%'3N$@(,`B$@8C<)`(P*`8\8`[@4`0P` -M$&$,`0+4$`!H``([`!%EG!8`/0$A=F5S`Q-Y0P!0:6YD97"J`"5N="(!`$0- -M`7D9`$(%$F]L#0:P"U0@5VEK:5(,`PP3,&AO=U$/`;,#$&2M`0/:``+W$P4T -M&`3\!`#S#@!0!@/-``%P``*`%P+$!0]D&O__________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M________________________________________'E!U9&EN9RX1``#R!2!' -M3E4@;&]N9R!F:6QE;F%M97,L$`!3;&EN:R`1`*%A;F0@`*935E(T -M($%30TE)%``"8P`/,@`%84)I;F%R>2X`\P<@*&)I9RUE;F1I86X@;W(@;&ET -M=&QE$0`"^@#P'TE33SDV-C`@0T0M4D]-(&EM86=EFEP/@$Q:6]N1`!=8GII<#(6``1D`4TO3%I7'0"B;'IM82P@;'IID#`*4#`.<#]A)U2!S -M=')E86VU!>!S>7-T96TN("!4:&5R92P`D&YO(&1I-R86YD;VT@86-C97-S+GD`!I<` -MD&ES(&1EU`P"C!`![``'.`!!VFP0` -MT082$N("!)9B!Y;W4@9&]N)^P!`+8`\0)I8VET -M;'D@:6YV;VME(&$@<.L`('5L60B@96%T=7)E("AS=2\!&7,<`A!AZ0`'+0`$ -M10<#(@("F0%P*2P@:70@=W``X"!G970@<'5L;&5D(&ENI`0W($EN;@`W+"!I -MG@`!40$#FP`B96[)`07L#$7`U`-%A=&5V -M97(@8FQO8VMS\```[@2X'<70@82!T:6U7`W%O8!(71O(@`%H0!A="!O;F-EA0`A3VZ0`QMEPP`"Y`(R<')O.@$! -MA0%18W1L>2W,``"."5)U='!U=.\"`&`$\0-O8FIE8W0M2!B=69F97(@)`@`90`$<@&%82!S;V-K -M970^`TEW:7-HN@3`P"`,D*`2L`,VEN(">D``,P``*,! -M!H`%,7=A;H@`$'0V!`5%`0!@```:!!!TC@7,N -M"E)%041-1;L&!^@&X2!B=6YD;&4N"@I1=65S^@*@/R`@27-S=65S/U(`URH@ -M:'1T<#HO+W=W=RX@!S!O3``!(`1!HN`*#9F]R(&]N9V]8!Q@@9`!P9&5V -M96QO<#P%)BP@_`Y`9&]C=10``:P(`3<,`'$``#H`(6YK70$`70`&8N9V]O9VQE+F-O;2]P+VH`$2\Z`"!S+VD``),``6<` -M47-U8FUI9P!P96YH86YC9;L``#8"!C@`@RP@<&QE87-E+```.P``!`,`2PB!$!G0&";8"(FENU@0`I`H`ZP4$O0+P`DY%5U,@+2!H:6=H -M;&EG:'1S7`8PM```Z#S`@*B"3``!. -M`/``+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C_P```@`0+:("`)\`!*@``-D. -M"*($$BP:#@#7"P!9"Q!YR@4!]@$C97*N`05P`"1I;F0`@2YH+FEN"@DM]`<` -MYA,22XS]!0P86EL[P0R92`B:P,%JP`!)``4(@L+62!C;&%S1``!'PE& -M;F%L``'?`5P#R*71H92!A=71H;W)S('=I=&@@86YY('%U97-T -M:6]N'2(`#%P=70I`/D#(F-M86ME -M(B!B=6EL9"!T;V]L30`"5@$&-0$!*0$Q(&EN3`$/;0$!,&%R91`"$F3:`35E -M"B>\`!,GK0`#9P$`DP``3@#U`2YA;2P@86-L;V-A;"YM-"SA`$!E+F%C_P`` -M`@`2+50`)'1OJ```(`$P9&ES7P(0=4$!LBP@;VYL>2!N965D?``Q;6%I]@$C -M97)<`05P`"1I;F0`\@,N:"YI;@H)+2!T96UP;&%T97-G`!%B-`(!9@$39;4` -M8`H*1W5I9/,`DB!$;V-U;65N=($!`,4!,F%L;'4``/,!]0H@'!L@P(#+P,`0@$"(0"#('!R;V=R86TS`$]C<&EO-``+ -M`"(`##4`+V%T-``,*&%T,P`'K0/P!#,@9VEV97,@86X@;W9E2!A``"/`&<@)V1O8R>]!;!I;@IA(&YU;6)E2QN``5H`S!U=&^3!@#_`A!YP0(P96-TF0,19-4``QP"!<(&$&8L -M``&W!E$J($=.574!`KH!)B`HN0$`&@!!;&]N9U4"8FYA;65S+!``4VQI;FL@ -M$0``8P!A`@@;W#+`\!A;"!2;V-KB,` -M`!DT%``)"`$```I58W)E873/``%U!`\&`0("J@,#OP,"O`(/'P,8,")R9?X( -M46-T960B1P,"3P#$+"!W:&EC:"!W:6QLB@`!5@`%R@%A(&5X8V5P0`4`N04$ -M:0+1('1H870@U`P#P -M!`![``.?`0![``&'"0&C``)*#`,*`P`X"`"R``$>`P"F!`(,`B$@8C<)`&H( -M,6%B;``&`(P*`0P``2P+`@0!`&@``CL`0F5A8V@]`2%V97,#$WE#`%!I;F1E -M<*H`)6YT(@$`&`D`#P\08T(%$F]L#08U"E0@5VEK:5(,,&EN9\D`,&AO=U$/ -M`;,#%V26"@(J`2%/;C\(`/<,`F`&`P,!`_@``8@)4&%L=V%Y1@$`W0$J962* -M"`)'`'!))W9E(&%T+0T`C`<`P0^0:6YI;6EZ92!S#@T28U((07!O;&R4#5$N -M("!)9O4(4&1O;B=TJ`"097AP;&EC:71LV0EB=F]K92!A^@\18W\*,69E830+ -M,"AS=2\!!?L*`*D`("!A00`!)Q`"+0`(S0`4;_D(<"DL(&ET('=P`'$@9V5T -M('!UG`T0:7H+1R`@26YN`#``%1`0.;`")E;LD!!RT``#X`"W$`*&1E -M$0`#Q@(1+/```H```(T.`)8!`!8!`$``(&%G`PX"4`.18V]R0`P&@`A!MV`$32X'<70@82!T:6U7`W%O -M8!(71O(@`%2@!2="!O;F-\$B)/ -M;AP."\,``N0",G!R;SH!`84!46-T;'DMS`"2960@;W5T<'5T[P(`8`3Q`V]B -M:F5C="US='EL92!A<'!R;\@#`$,2`OH`X'1O(&AA=F4@;75L=&EP)0``(040 -M=A(#0')E86VY"`#^#15NG@`3(!40`&H0``H!`#T%@VX@:71S(")`Y0`2(KT$ -M$7,P#@)C!08!`6!I='-E;&93`0!]!!`O=@1@=&5N('5S;P8`-PP!<@$R9G5N -M6!($DP$!=08`,@`U(&%NI``"(Q-0;'D@9G)@``S0*%82!S;V-K970^`TEW:7-HN@0!)@\#60\`#B)A;N@"`*4'!C0*$"QC`$!D97-PWP``;`0!Y`,`7,N"B05 -M$6:X#01Q%K0@8G5N9&QE+@H*41$6H#\@($ES7,@<')O9'5C97,@8V]R6]U('1O(&AA=F4@;75L=&EP)0`#J0!P`/,-("!B -M!E -M('-O;64@=71I;&ET>3X`!8P`,"!T;WP!\0-V:61E(&5A2!D8737`%9UX`0!V``##`!%EW@(!O@`%RP$` -MTP`#HP%#+B`@2:0!(6%NB``2=%T``38"`5L#`!\!`#L!061I"!I;G1E&%)`$!S.B!3,@-4`0-)`#!C;VY#`O`".B`@5F%R:6]UP`` -M7P%Q875T:&]R<\`%`1\&`?("`DT'$`H5"%!T;W`M;`P$`W8%`#`'`4$`$&DD -M!0FV`B)I;O@$(FEOX08$O0+P`DY%5U,@+2!H:6=H;&EG:'1S7`8P'2(`#!P=71>`C`@(F,T!A$B)`,`J@2!N965D?``Q -M;6%I]@$C97*N`05P`"1I;F0`@2YH+FEN"@DM]`=2;&%T97-G`!%B-`(#<@$" -MM0!@"@I'=6ED\P`H($14!@32`0)U``#S`8`@PH"MP(A960N -M"P!;!!!SU`80;A$,`-8"`),``'4``!<"`/D$`7$``7$*")<``9P)(RXS30`` -M[P0R92`B:P,%JP`!)``4(@L+62!C;&%S1``!'PE&;F%L=H+`#L'`2,)@&%U=&]M871I_P(0><$",&5C=)D#$60Y"0,< -M`@5X"1!F+``!MP91*B!'3E5U`0(U`B8@*`0+`!H`06QO;F=5`@"M"R)S+!`` -M``4+$R`1``!C`%)S<&%RB,``!DT%``)"`$```H"G!`% -M.@$`=00/!@$"`J\!`[\#`KP"#Q\#&#`BP`!APD!*Q4"2@P`31$B:7*"$1!I>0<#[A("#`(A -M(&(W"0","C%A8FP`!@","@$,`!!A#`$"U!``:``".P!"96%C:#T!(79E4,`4&EN9&5PJ@`E;G0B`0!$#0`/#Q!C0@42;VP-!K`+5"!7:6MI4@P##!,P -M:&]W40\!LP,09*T!`]H``O<3(4]N/P@`]PP"8`8`\PX`4`8#S0`!<``"@!<" -MQ`4J962*"`)'`#!))W8-&``A%0",!S!T;R`A$#!M:7I2%P"U"`)2"$%P;VQL -M-A(&Y!1!9&]N)^P!D&5X<&QI8VET;-D)8G9O:V4@8?H/$6-_"@/.$2`@*-(0 -M`'4,"!P"$&&R`0$G$`(M``C-`!1OP,1 -M<#4`8F%T979EFUA+"!L>FEP+"!A -M;F0@>'HC```9-!0`\`P*5&AE(&QI8G)A"!I;G1E'1E;DT!L7,@*&9O$E33SDV-C`3`%HW+5II<#D`-EA!4A$`0PI7 -M:&4#`@#D`00%`A$L_`%A2!S=')E86WM`>!S>7-T96TN("!4:&5R92P`D&YO -M(&1I4,`4&EN9&5PJ@`B;G1_`!!R.P0`!`"4=&EC;&5S(&]N@0$$ -MK@#P`%=I:VD@97AP;&%I;FEN9XD`,&AO=_@``O4``(X$`RP``BH!(4]NJ@`< -M+`,!`]D"`G``0&QW87E&`0#=`?(!960@875T;VUA=&EC86QL>4<`L$DG=F4@ -M871T96UPQ`/@=&\@;6EN:6UI>F4@2!I;G9O:V4@82!PZP`@=6PW!"!E85D" -M0"`HD`!RT`!^\%`(`!`ID!<"DL(&ET('=P`.`@9V5T('!U -M;&QE9"!I;J0$-R!);FX`-RP@:9X``5$!`YL`(F5NR0$'+0``?``+<0`H9&41 -M``.J`!$L\``"@``B;F6.`@`6`0!``&)A9V%I;G-'`J!C;W)R97-P;VYD)P0( -M20`-6@`">P,Q:65SPP`!;P.A86QS;R!R961U8[D%,&4@`(&5N=FER;V[7`C%S('=N`@&@`A!MV`$36QE(&%P<')OR`,`PP<"^@#@=&\@:&%V92!M=6QT:7`E -M```A!1!V$@,`!04`N0A5(&]P96Z>`%`@(&)S9",'(75SO`$`/06#;B!I=',@ -M(D#E`!(BO01&P`28D(``"P$`-$``#8!(71OFPDP9&%TUP!6=7)C93HN -M`0+("0#"`!)A[`(`PPD!*P`S:6X@)P$`^`(@863\`@!B`!%A_`@$J@$`>08A -M;W7W!%%F:7)S=)("`*8!(&$@0P41;S$*`/8`%BYT``/9`P*G`0":"0*<`0&% -M``:X`0!V``##``"\`Q)EDP`"3P7,N"E)%041-1;L&!^@&X2!B=6YD -M;&4N"@I1=65S^@*@/R`@27-S=65S/U(`URH@:'1T<#HO+W=W=RX@!S!O3 -M``!(`1!HN`*#9F]R(&]N9V]8!Q@@9`!P9&5V96QO<#P%<2P@:6YC;'6]!4!D -M;V-U%``!K`@!-PP`<0``.@`A;FM=`0!=``9S`%`@;6%I;`<"0FQI%EB!$!G&%)`$!S.B!3,@-4`0-)`#!C;VY#`O`".B`@5F%R -M:6]UP``7P%V875T:&]RT/4'1O<"UL#`0#Q0P`,`0& -M";8"(FENU@0`=`P`ZP40<],-\`4@*B!.15=3("T@:&EG:&QI9VAT'2(`")P==8-(")C-`81(B0#`#@,*6]L30`"5@$&ZP,!*0$`%@D`C@$/ -M;0$!`+`,('5SW0H`V@$T90HGL``C92>M``-G`0"3``!.`/``+F%M+"!A8VQO -M8V%L+FTT"0T#[0`P+F%C%P$``@`0+:("`)\`!*@``-D."*($$BP:#@#7"P)\ -M`#%M86GV`2-EPH"MP(`A1(A86R) -M!T!S97%UZ@@0=&%R -M+C54`0CQ!`4^$A%S8P0Q<&]PY0\#G`$$>P`(2PE`:&%R9!8,`3`&!%L!`4<` -M`(X!86UO9&5R;H\``.@!`+P'<"!V87)I86Y("0`B##!M86[X"T%P86=E.``` -M,0X`SA0"^@$`G@`!WP%7)V1O8R>]!9!I;@IA(&YU;6+R#!=FD0<$.P''"@I9 -M;W4@`""(&EN'!L86EN3`1!F+``P'1E;J+``-J`0`9`]$J(%!/ -M4TE8('5S=&%R6P`"$``P<&%X20-Q97)C:&%N9WX!-VUA="$`L&]C=&5T+6]R -M:65N`0,`8`(!'@"A4U92-"!!4T-)270"`10``E,`#S(`!6%":6YA\!`DD`-%I) -M4%8#!$``D'5N8V]M<')E<],&<&]R(")D969^!A`BJ0($&```H00C:655`0## -M`0"B`85"4T0@)V%R)U(``?@`$2?]`Q`GNP($/0%:-RU::7`F`-A-:6-R;W-O -M9G0@0T%"+``Q3$A!"@,Z3%I(,@`Z4D%2$0`86!$``=4#!;@"`'@#"*\"8&AA -M;F1L9;L"$'FW`P"V!`:X`C!B969*`W!E=F%L=6%TR@(`(``#F0,"SP(0=?8% -M$&]Q`@"V`@)#`@$*`!$@@P&B4E!-('=R87!P94X"16=Z:7`^`3%I;VX8`5UB -M>FEP,A8`!'P!32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9-!0`"0@!E6-A -M;B!C0`&@`0`#@Q397-I9VXE#!)EO@(`0`0!,`0X;F5WM0,`\`0`>P`#GP$`>P`! -MAPD!HP`"2@P#"@,`.`@`L@`!'@,`I@0"#`(A(&(W"7%R96%D86)L``8`C`H! -M#``!+`L"!`$`:``".P!"96%C:#T!(79E4,`4&EN9&5PJ@`E;G0B`0`8 -M"5!AD` -M!RT`!"T'`,\*%&_Y"'`I+"!I="!W<`!Q(&=E="!P=9P-(&ENI`0W($EN;@`W -M+"!IG@`(FP`B96[)`02UV```S#`#W"!%IAP8`A`!P96YV:7)O -M;M<",7,@=Y`#`:`"$&W8`1-R6@,%,`(`6P`"?P`1>7L#$7`U`-%A=&5V97(@ -M8FQO8VMS\```[@@``S0*%82!S;V-K970^`TEW:7-H -MN@0!)@\#60\`4X.475S92`B(0$`6@@@+")0"+$L -M(&-A<&%B:6QI=/8"!`,!!?$``O,/`;<$"/8%`9P" -M`,D*`2L`,VEN("#U%F:7)S=)("`*8!(&$@ -M0P41;UD1`/8`%BYT``/9`P*G`0"_``*<`0&%``:X`0!V``##``"\`Q)EDP`" -M,0\@;'ED`0#,``"C`0:`!3%W86Y_!1)T'0\!-@(!6P,!&@00=(X'(7-K+`,0 -MA$)P`$`B0`P;6%K>0"0:7,@97-P96-I;@0!T`$"J@$` -M.@@P.B`BDPH!#A$)V@T3(KD"`-X.(F%NZ`(`I0<&-`H0+&,`0&1EF-%#A)B!P`2>`<``$D!`)()`"<`02H@97@;$T!S.B!3 -M,@-42!A;F0@861D(&ET('1O(&$@=&%R(&%R8VAI=F4@=VET:&]U=`H@ -M("!F:7)S="!W2!F8<`\`5S;V-K970N("!)9B!Y;W4@=V%N=$0`$G1=`!(O/0``8``P -M:65S,P!09&ES:RQ.`/`,0#Q+6ES(&5S<&5C:6%L;'D@96%S>2X*"B`J($YO=&4Z(")P87@@ -M:6YT97)C:&%N9V4@9F]R;6%T(B!I7,N"E)%041-15``1"!L:6)M -M`=%B=6YD;&4N"@I1=65SK@"@/R`@27-S=65S/U(`UBH@:'1T<#HO+W=W=RXX -M`$`N;W)GDP``2`$Q:&]MIP"`(&]N9V]I;F8$(&YDT`(Q9G5L+P(&10!1+VUI;FF%`1%A -MXP%186-T('-@`+`@9&5M;VYS=')A=+M``,D -M!`"3``!.`/4!+F%M+"!A8VQO8V%L+FTT+.$`0&4N86/_```"`!`MH@(`GP`$ -MJ``,H@2R+"!O;FQY(&YE961\`#%M86GV`2-E7-T96TZ<`<"N`1U+C$@97AP;(,"`R\#`$(!`B$`!)H#`S,``(@$#S0` -M"P`B``PU`"]A=#0`#"AA=#,`!@$&@"XS(&=I=F5SWP:`;W9EP$2+8($-7,N-:H(`)X%$67[`P#R -M`(!M871S('-U<'\(!&,"!98!`$P```H"D"XU+"!M=')E90D``&\`7G1A``&I`5"`"X!!,B?P(R+F@BJ0"` -M:&4*`D09BP` -M`;<&42H@1TY5=0$"-0(F("@$"P`:`$%L;VYG50(`K0LB+ -M``-J`0`9`]$J(%!/4TE8('5S=&%R6P`"$``/B@P#!R$`P&]C=&5T+6]R:65N -M=!<$,7!I;QX`IE-64C0@05-#24D4``)3``\R``5A0FEN87)Y+@#`("AB:6FEP,A8`!'P! -M32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9-!0`"0@!```*56-R96%TSP`! -M=00/!@$"`JH#`[\#`KP"#Q\#&#`B&-E<$`%`+D%!&D"42!T:&%T0PXQ:7)E40`!`1`! -MR@(@("A3"@$T!`"$`0-$!`#T`V`L(&5T8RGO"P+Z`P"I`@!H$0*-``&&`0+: -M``^6`P4!R`-A(FYE=V,BFP,!,P`G?P(-F5A;;4%`A$+<"X@(%1H97(T$2`@;M82,7)E8S`1`]\(`),$02!I;BVW -M#X(@;6]D:69I8^4,\@%OP`!APD!HP`"2@P` -M31$B:7*"$1!I>0<#[A("#`(A(&(W"0","C%A8FP`!@","@$,``$L"P+4$`!H -M``([`$)E86-H/0$A=F5S`Q-Y0P!0:6YD97"J`"5N="(!`$0-``\/$&-"!1)O -M;`T&-0I4(%=I:VE2#`,,$S!H;W?X``&S`Q!DK0$#V@`"*@$A3VX_"`#W#`)@ -M!@#S#@!0!@/-``%P`%-L=V%YF4@0`P&@`A!MV`$3!<1<_`` -M`.X',2!I=&0!,EEO=><3`<0-0&)A8VNO$S%F6QE(&%P<')OR`,`@0L"^@!0=&\@:&$Y%D!U -M;'1IPQ,$J0`"`00`N0A5(&]P96Z>`!0@]`\A=7-U!Q!IF@%S(&ETFEP,A8`!"8`32],6E<=`/D#;'IM82P@;'II -M<"P@86YD('AZ(P#!"DYO=&5S(&%B;W5TE`!R;&EB=$`\"YT96-T=7)E -M.@H*("H@5&AI48!`-T!\@%E -M9"!A=71O;6%T:6-A;&QY1P"P22=V92!A='1E;7#7`>!T;R!M:6YI;6EZ92!S -M="L`L"!L:6YK('!O;&QUN`'A+B`@268@>6]U(&1O;B?L`0"V`/$":6-I=&QY -M(&EN=F]K92!A('#K`(!U;&%R(&9E85D"0"`HD`!RT`!P8# -M`(`!`ID!<"DL(&ET('=P`/``(&=E="!P=6QL960@:6XN/@`G26YN`# -M``%1`0.;`")E;LD!!RT``#X`"W$`*&1E$0`#Q@(1+/```H``(FYEC@(`%@$` -M0`!B86=A:6YS1P*@8V]R7L#$7`U`-%A -M=&5V97(@8FQO8VMS\``0:$,$(6ETH0!!66]U717`F$@82!T:6U7`W%O -M`+$@(&)S9'1A3X`!8P``0`"\05R;W9I -M9&4@96%S>2UT;RUUX`0!V``##``"\`Q)E -MDP`"3P0"0:7,@97-P96-I;@0!T`$"J@$` -M.@CS`SH@(G!A>"!I;G1E`<``$D!`)()`"<`4"H@97AA20!` -M8$(&YDT`(Q9G5L+P(&10`0 -M+T,*`84!$6&>"E%A8W0@"`"X!!,B!0XR+F@BJ0`R -M:&4*7PP0(+`)`/H``!0`!.D&`W((`G\"-&UO5$P`P%&!E+``-J`0`9`[$J -M(%!/4TE8('5S=+`1!!``#XH,`P%\``(Q`%9O8W1E=*\4`&`"`1X`H5-64C0@ -M05-#24ET`@$4``\R``L00FT1$7DN`+$@*&)I9RUE;F1I8=018VQI='1L91$` -M`OH`\0))4T\Y-C8P($-$+5)/32!I;;<"$"@X#C`@;W#+`\!A;"!2;V-K[ -M`@0]`5HW+5II<"8`V$UI8W)OQ=4 -M`)H`-6QZ-*@!`.47"0@!```*`IP0!4L!`'4$#P8!`@*O`0._`P*\`@\?`Q@P -M(G)EH`T`$!81(D<#`D\`PBP@=VAI8V@@=VEL;.L8`'`(`,,/`U\!0',@97@M -M%``"`@"Y!02)$0(+%P-:%P%1``7I$C!S("A3"@$T!`"$`0,S!`#T`V`L(&5T -M8RGO"P+Z`P"I`@!M``*-``&;`0+:``_(`PIA(FYE=V,BFP,!,P`G4P`T&-P:6\N-2P@;71R964)``!O`/(*=&%R+C4@<')O=FED92!D971A -M:6QE9"!I;E(`D&EO;B!A8F]U=$T`XW-E"B`@('!O<'5L87(@F``2("D`\PIS -M+"!I;F-L=61I;F<@:&%R9"UT;RUF:6YD5``2FEP/@$Q:6]N,`!=8GII<#(6``1\`4TO3%I7'0"B;'IM82P@;'II -M&-E<$`%`+D%!&D"L"!T:&%T(')E<75IE@4G87C*`E(@*&9O?P(-F5A -M;;4%X'-Y`3AN97>U`P#P!`![``-S!`![``&'"0&C`%0@;VYL -M>0H#`#@(`+(``1X#`*8$`@P"(2!B-PEQ4,`4&EN9&5PJ@`E;G0B`0`8"5!A48!`-T!*F5DB@@"1P"P22=V92!A -M='1E;7",!^!T;R!M:6YI;6EZ92!S=+4(`E((4'!O;&QU(@=1+B`@26;U"%!D -M;VXG=*@``+8`4&EC:71LV0F!=F]K92!A('#K``%_"C%F96$T"S`H``%1`0.;`")E;LD!!RT``'P`"W$`*&1E$0`#Q@(1+/`` -M`H``(FYEC@(`%@$`0`!B86=A:6YS1P*18V]R0`P&@`A!MV`$38!(71O(@`%H0!A="!O;F-EA0`A3VZ0`QMEPP`"Y`(R -M<')O.@$!A0%18W1L>2W,``"."5)U='!U=.\"`&`$\0-O8FIE8W0M7,"!8P``#\`!)4.0&5AP"`,D*`2L`,VEN("#U%F:7)S=)("`*8!(&$@0P41;U`'`/8`%BYT``/9`P*G`0"_``*< -M`0&%``:X`0!V``##``"\`Q)EDP`",0\@;'ED`0#,``"C`0:`!3%W86Y_!1)T -M'0\!-@(!6P,`8PP`,P!!9&ES:RP#`+$0$'*?!)EN=F5N:65N8V7``0")`#!M -M86MY`)!I0#`',*T2!S87ES+@I214%$3442 -M!@<4!]%B=6YD;&4N"@I1=65S^@*@/R`@27-S=65S/U(`UBH@:'1T<#HO+W=W -M=RXX`$`N;W)GDP``2`$0:+@"$&:Q#S-N9V]8!Q<@3`>`(&1E=F5L;W`\!0@9 -M$02Z$0&L"`$W#`!Q```Z`"%N:UT!`%T`!G,`4"!M86EL!P(P;&ESOQ`!G0`0 -M5)D!`.41`.%E8$(&YDT`(Q9G5L+P(&10`0+T,*`84!$6&>"C1A8W1[$W!D96UO;G-T -M.14@;F<^``"`!094`@-)`#!C;VY#`F$Z("!687+N$V!I=&5M$0(8`&!C;VYF:6>R%A4M#``"1`"UM`Q$SM@L`$!20(&]V97)V:65W\P(`JP`% -MP`L`<04P=VAOD0(4*J0*A5]R96%D+C,L$``!^`@-$0!17V1I4$`(&EN^``(M@)P -M:6YF;W)M8:D!,"!F:34!`'P`\`0J($Y%5U,@+2!H:6=H;&EG:'1SW``P@`K1#3U!924Y'("T@=U$!8F-A;B!D;Y\`,W1H:2D`\@))3E-4 -M04Q,("T@:6YS=&%L;'4```T`(7)U*@(#*0"!4D5!1$U%("T\``&5``*3`+!C -M;VYF:6=UM``,D!`"3``!. -M`/4!+F%M+"!A8VQO8V%L+FTT+.$`0&4N86/_```"`!(M5``D=&^H``RB!+(L -M(&]N;'D@;F5E9'P`,6UA:?8!(V5R7`$%<``D:6YD`/(#+F@N:6X*"2T@=&5M -M<&QA=&5S9P`18C0"`68!$V6U`&`*"D=U:63S`%`@1&]C=9D%`H$!`,4!,F%L -M;'4``;`:`;W9E]!;!I;@IA -M(&YU;6)E"`"X!!,BO0(R+F@BJ0"`:&4*2R"```[!P$C"4!A=71ODP8`_P(0 -M><$",&5C=)D#$635``,<`@5X"1!F+``!MP91*B!'3E5U`0(U`B(@**L)`+D! -M`!H`06QO;F=0!F)N86UEB,``!DT%``)"`$```I58W)E873/``%U!`\& -M`0("J@,#OP,"O`(/'P,8,")R9:`-46-T960B1P,"3P#$+"!W:&EC:"!W:6QL -MB@`!5@`%R@%A(&5X8V5P0`4`N04$:0)1('1H871##C%I`3AN97>U`P#P!`![``.?`0![``&'"0&C``)*#`!-$2)IF4@``%1`0.; -M`")E;LD!!RT``'P`"W$`*&1E$0`#Q@(1+/```H```(T.`)8!`!8!`$``(&%G -M`PX1=/$)D6-OP,1<#4`T6%T979EP"`,D*`2L`,VEN("#U%F:7)S=)("`*8!$6%P$A%O\0T`]@`6+G0` -M`]D#`J -M#@#G&`Y6#A`L8P!`9&5S<*(``&P$`>0#`',*2!I;G9O:V4@82!P87)T:6-U;&%R(&9E -M871U!E('-O;64@=71I;&ET>3X`!8P``+$!\09P2!D8737`%9UP"`&$# -M`2L`,VEN("7,N"E)%041-15``1"!L:6)M -M`=%B=6YD;&4N"@I1=65S^@*@/R`@27-S=65S/U(`UBH@:'1T<#HO+W=W=RXX -M`$`N;W)GDP``2`$0:+@"L&9OF-A="P@8@<`$G@'``!)`4!S=6-H -M)P!0*B!E>&%)`$!S.B!3,@-40&";8"(FEN8PL`<0L`ZP4$O0+P -M`DY%5U,@+2!H:6=H;&EG:'1S7`8P'2(`#!P=71>`C`@(F,T!A$B)`-I -M9"!T;V]L30`"5@$&ZP,`E``!%@D`C@$/;0$!`&8(('5SW0H`V@$T90HGL``C -M92>M``-G`0"3``!.`/``+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C_P```@`0 -M+:("`)\`!*@``&H+"*($82P@;VYL>=<+`GP`,6UA:?8!(V5RK@$%<``D:6YD -M`($N:"YI;@H)+?0'4FQA=&5S9P`18C0"`W(!`K4`8`H*1W5I9/,`*"!$5`8$ -MT@$"=0`!MP%P=H+`#L'`2,)"=H1`,$",&5C -M=)D#$62V#P,<`@5X"1!F!A(!MP91*B!'3E5U`0(U`B8@*`0+`!H`(VQOO`4` -MK0LB+``-J`0`9`[$J(%!/4TE8('5S=+`1!!``#XH,`P%\ -M``(Q`+!O8W1E="UO`@@;W#+`\!A;"!2;V-K[`@0]`5HW+5II<"8`V$UI -M8W)OFEP/@$@:6]/$WTJ -M(&)Z:7`R%@`$?`%-+TQ:5QT`HFQZ;6$L(&QZ:7`3`R]X>B,``!DT%``)"`$` -M``H"G!`%.@$`=00/!@$"`J\!`[\#`KP"#Q\#&#`BD6$W,*%P!5"`2`!"EIP`!APD!*Q4"2@P#"@,`.`@`W@`4=.X2`@P"(2!B -M-PD`C`H!CQ@#N!0!#``080P!`M00`&@``CL`$66<%@`]`2%V97,#$WE#`%!I -M;F1E<*H`)6YT(@$`1`U087)T:6-"!1)O;`T&L`M4(%=I:VE2#`,,$S!H;W=1 -M#P&S`Q!DK0$#V@`"]Q,%-!@$_`0`\PX`4`8#S0`!<``"@!<"Q`4/9!K_____ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_SI0;F<@;&DN$0``\SUN:R!N86UE'1E;F1E9"!T87(@9F]R;6%T("AI;F-L=61I;F<@04-, -M,P!A3VQD(%8W)P"!87)C:&EV97-+`+=03U-)6"!U"=M=')E92<]`5HW+5II<"8`V$UI8W)O2!A;'-O(&1E=&5C='--`&!H86YD -M;&4,`'!Y(&]F('1HW`'P!VQL;W=I;F<@8F5F;W)E(&5V86QU8702```@``,O -M`A$ZU`!@=75E;F-O<0(!CP(!%``!"@`1((,!HE)032!WFEP -M/@$Q:6]N,`!=8GII<#(6``1D`4TO3%I7'0"B;'IM82P@;'IIP`!S@`0 -M=IL$`-$&$G.C`%0@;VYL>0H#0&UE;G2R``$>`P"F!`(K`#`@8F5``'%R96%D -M86)L``9!=W)I=`P`$&$,`0($`0!H``([`$)E86-H/0$A=F5S`Q-Y0P!0:6YD -M97"J`")N='\`$'([!``$`#!T:6-"!21O;H$!!*X`\`!7:6MI(&5X<&QA:6YI -M;F>)`#!H;W?X``&S`Q!DE@4#+``"*@$A3VZJ`!PL`P$`!`0R;6%T<`!`;'=A -M>48!`-T!\@%E9"!A=71O;6%T:6-A;&QY1P"P22=V92!A='1E;7",!^!T;R!M -M:6YI;6EZ92!S="L`L"!L:6YK('!O;&QUN`'A+B`@268@>6]U(&1O;B?L`0"V -M`/$":6-I=&QY(&EN=F]K92!A('#K`"!U;%D(H&5A='5R92`HD`!RT`!$4'`R("`ID!<"DL(&ET('=P`.`@9V5T('!U;&QE9"!I;J0$-R!) -M;FX`-RP@:9X``5$!`YL`(F5NR0$'+0``?``+<0`H9&41``.J`!$L\``"@``B -M;F6.`@`6`0!``'%A9V%I;G-TSP&18V]RP,Q:65S -MPP`!;P,!;P=16QE -M(&%P<')OR`,`R0@"^@#@=&\@:&%V92!M=6QT:7`E``-3!`(!!`#\"E4@;W!E -M;IX`4"`@8G-D(P2!F)M96UO7,"!8P``0`"\05R;W9I -M9&4@96%S>2UT;RUU0#`',* -MT"!S87ES+@I214%$346[!@?H!N$@8G5N9&QE+@H*475E<_H"H#\@($ES7!1`GH@1`9W)A;18"&%)`$!S.B!3,@-4 -M`0-)`#!C;VY#`O`".B`@5F%R:6]UP``7P%Q875T:&]R<\`%`1\&`?("`-(1$B[M -M#U!T;W`M;`P$`\4,`#`'`4$`$&GD!@FV`B)I;M8$`*0*`.L%!+T"\`).15=3 -M("T@:&EG:&QI9VATPH"MP(`318A86R)!T!S97%UZ@@0=&%R+C54`0CQ!`4^$A%SU@TQ<&]PY0\# -MG`$$>P`(2PE`:&%R9!8,`3`&`J@!`X42`(X!86UO9&5R;H\``.@!`+P'<"!V -M87)I86Y("0`B##!M86[X"Q%PK1] -M!;!I;@IA(&YU;6)E"`"X!!,BXP`R+F@BJ0`R:&4*7PP0(+`)`/H``!0`!.D&`W((`G\" -M$&T:%P/[`$(N("!0B@FR;&5T('5S"FMN;W<0`0&9!F!E`D09@82`;<&`H<8!JH+"``:`/@5#"`6`1````4+#V0:________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M__________________________________________________]H4"`J(&5X -M1!$``/$,86UP;&5S+VUI;FET87(Z(&$@8V]M<&%C="!S&P#T3R!D96UO;G-T -MV`'!I;F9O -M6]U(&-A;B!D;Y\`,W1H:2D`\@)) -M3E-404Q,("T@:6YS=&%L;'4```T`,')U8X$``RD`@%)%041-12`M%`$1`?$#+@H*66]U('-H -M;W5L9"!A;'-O(@(!3``Q8V]P=@8R8V]M6P%#:6X@(KT",BYH(JD`@&AE"G-O -M=7)C+P`19'4!`!0`!.D&`YH#`G\"-&UO68!,&5C=)D#$635``,<`@7"!A!F+``!MP91*B!' -M3E5U`0*Z`28@*+D!`!H`06QO;F=5`F)N86UE'1E;J+``-J`0`9`]$J(%!/4TE8('5S=&%R6P`"$``P<&%X20,B97)9!P-X`@FEP,A8`!'P!32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9-!0`"0@! -M```*56-R96%TSP`!=00/!@$"`JH#`[\#`KP"#Q\#&#`B&-E<$`%`+D%!&D"T2!T:&%T -M(')E<75IP`# -MGP$`>P`!APD!HP`"2@P#"@,`.`@`L@`!'@,`"0$"#`(A(&(W"0!J"#%A8FP` -M!@","@$,``$L"P($`0!H``([`$)E86-H/0$A=F5S`Q-Y0P!0:6YD97"J`"5N -M="(!`!@)``\/$&-"!1)O;`T&-0I4(%=I:VE2##!I;F?)`&-H;W<@=&_U``>6 -M"@(J`2%/;C\(`/<,`F`&`P,!`_@``8@)4&%L=V%Y1@$`W0$J962*"`)'`'!) -M)W9E(&%T+0T`C`<`P0^0:6YI;6EZ92!S#@T28U((07!O;&R4#5$N("!)9O4( -M4&1O;B=TJ`"097AP;&EC:71LV0EB=F]K92!A^@\18W\*,69E830+,"AS=2\! -M!?L*`*D`("!A00`1P,1<#4`T6%T979EP"`,D*`2L`,VEN("#U%F:7)S=)("`*8!$6%P$A%O61$`]@`6+G0``]D#`J60!`,P``*,!!H`%,7=A -M;G\%$G0=#P-%`0!@```:!!!TC@0#`',*F-%#A)B!P`2>`<``$D!`)()`"<`02H@97@$ -M&D!S.B!3,@-48$(&YDT`(Q9G5L+P(&10`/ -M9!K_________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_________V10=&EM90HH$0``\!0@("!O2UB;&]C:V5D(&]U -M='!U="X*"B`J(%1H92!O8FIE8W0M`@#1```V`:!T -M;R!A;GD@9&%TUP!6=7)C93HN`6!C`@&^``7+ -M`0#3``.C`4,N("!)I`$A86Z(`!)T70`!-@(!6P,`'P$`.P%!9&ES:RP#`\0! -MMF-O;G9E;FEE;F-E3`(P('1OB0`P;6%K>0#1:7,@97-P96-I86QL>=`!`JH! -M\P].;W1E.B`B<&%X(&EN=&5R8VAA;F=E(&9O7,N"E)%041-12X` -M1"!L:6)M`=%B=6YD;&4N"@I1=65S^@*@/R`@27-S=65S/U(`UBH@:'1T<#HO -M+W=W=RXX`$`N;W)GDP``:@00:+@"L&9O&%)`$!S.B!3,@-4`0-)`#!C;VY#`O`".B`@5F%R:6]U -MP``7P%Q875T:&]R<\`%`1\&`?("`DT'$`H5"%!T;W`M;`P$`W8%`#`'`4$` -M$&DD!0FV`B)I;O@$(FEOX08$O0+P`DY%5U,@+2!H:6=H;&EG:'1S7`8P'2(`#!P=71>`C`@(F,T!A$B)`,`J@2!N965D -M?``Q;6%I]@$C97*N`05P`"1I;F0`@2YH+FEN"@DM]`=2;&%T97-G`!%B-`(# -M<@$"M0!@"@I'=6ED\P`H($14!@32`0)U``#S`8`@PH"MP(A -M960N"P!;!!!SU`80;A$,`-8"`),``'4``!<"`/D$`7$``7$*")<``9P)(RXS -M30``[P0R92`B:P,%JP`!)``4(@L+62!C;&%S1``!'PE&;F%L=H+`#L'`2,)@&%U=&]M871I_P(0><$",&5C=)D#$60Y -M"0,<`@5X"1!F+``!MP91*B!'3E5U`0(U`B8@*`0+`!H`06QO;F=5`@"M"R)S -M+!````4+$R`1``!C`%)S<&%RB,``!DT%``)"`$```H" -MG!`%.@$`=00/!@$"`J\!`[\#`KP"#Q\#&#`BP`!APD!*Q4"2@P`31$B:7*"$1!I>0<#[A(" -M#`(A(&(W"0","C%A8FP`!@","@$,`!!A#`$"U!``:``".P!"96%C:#T!(79E -M4,`4&EN9&5PJ@`E;G0B`0!$#0`/#Q!C0@42;VP-!K`+5"!7:6MI4@P# -M#!,P:&]W40\!LP,09*T!`]H``O<3(4]N/P@`]PP"8`8`\PX`4`8#S0`!<``" -M@!<"Q`4J962*"`)'`'!))W9E(&%T(14`C`'!L:6-I=&S9"6)V;VME(&'Z#Q%C?PH#SA$@ -M("C2$`!U#`@<`A!AL@$!)Q`"+0`(S0`4;W,$<"DL(&ET('=P`%`@9V5T(-(2 -M`5T*`*0$-R!);FX`!287`9X``5$!`YL`(F5NR0$'+0``?``+<0`H9&41``.J -M`!$L6!$"@```C0X`E@$`%@$`0``P86=A\P\!7PJ18V]R7L#$7`U`&)A=&5V97)X%Q%S\```[@*B!F:6QEFEP(&-O;7!R -M97-S:6]N%0!=8GII<#(6``0F`$TO3%I7'0#_`VQZ;6$L(&QZ:7`L(&%N9"!X -M>B,``!DT%`#Q,@I4:&4@;&EB2!C86X@8W)E871E(&%R8VAI=F5S(&EN -M(&%N>2!O9B!T:&4@9F]L;&]W:6YG(&9O"!I;G1E'1E;DT!L7,@*&9O$E33SDV-C`3`%HW+5II<#D`-EA!4A$`0PI7:&4# -M`@#D`00%`A$L_`%AT!X'-Y -M`>-R86YD;VT@86-C97-S+GD`!I<`\@)I -M`35N97<7`@!2`#!A;F1[``'.`!1V6`,24,`4&EN9&5PJ@`B;G1_`!!R.P0`!``P=&EC\`0D;VZ!`02N -M`/``5VEK:2!E>'!L86EN:6YGR0`P:&]W^``"]0``C@0#+``"*@$A3VZJ`!PL -M`P$#V0("<`!`;'=A>48!`-T!\@%E9"!A=71O;6%T:6-A;&QY1P"P22=V92!A -M='1E;7#$`^!T;R!M:6YI;6EZ92!S="L`L"!L:6YK('!O;&QUN`'A+B`@268@ -M>6]U(&1O;B?L`0"V`/$":6-I=&QY(&EN=F]K92!A('#K`"!U;#<$(&5A60)` -M("AS=2\!&7,<`A!AZ0`'+0`'[P4`@`$"F0%P*2P@:70@=W``X"!G970@<'5L -M;&5D(&ENI`0W($EN;@`W+"!IG@`!40$#FP`B96[)`07L#$7`U`-%A=&5V97(@8FQO8VMS\``0:%<%(6ETH0!!66]U -M2X'<70@82!T:6U7 -M`W%O8!(71O(@`%H0!A="!O;F-E -MA0`A3VZ0`QMEPP`"Y`(R<')O.@$!A0%18W1L>2W,``!(!E)U='!U=.\"`&`$ -M\0-O8FIE8W0M2!F)M96UO -M?\`!8P``0`"\05R;W9I9&4@96%S>2UT;RUU8<``J,!!H`%,7=A;H@`$'0V!`5%`0!@ -M``'Z"0".!R%S:RP#`WX&N6-O;G9E;FEE;F-EP`$`B0`P;6%K>0"0:7,@97-P -M96-I;@0!T`$"J@$`.@@P.B`BDPH.NPH3(KD"(&QL/`$"Z`(`I0<`$0,"P040 -M+&,`0&1EH($',+!0$^`0!U```7`@#Y!`%Q``%Q"@B7```\"3-Y+C--``#O -M!#)E(")K`P6K``$D`!0B"PM9(&-L87-$``$?"49N86QSG0`2!Q(M@@0U"`"X!!,B!0XR+F@BJ0`R:&4* -M7PP0(+`)`/H``!0`!.D&`W((`G\"-&UO5$P"9!F!E2X`L2`H8FEG+65N9&EAU!%C;&ET=&QE$0`"QP`$ -M7Q:10T0M4D]-(&EMMP(0*#@.,"!O<,L#P&%L(%)O8VMR:61G9>\!`DD`#QX78P\+%P#036EC@`/`#;&EB -M2!A2XS30`"=`%U -M(G-T2!C;&%S1`"6:6YT97)N86QSG0!@2!E2QN``5H`W!U=&]M871I_P(0>68!,&5C=)D#$635``,<`E!O;&QO=Y,!$&8L -M`#!S.@K?!#%'3E5U`0(U`B8@*+D!`!H`06QO;F=5`F)N86UE`*%35E(T($%30TE) -M=`(!%``"4P`/,@`%84)I;F%R>2X`H"`H8FEG+65N9&GS!(-R(&QI='1L91$` -M`OH`\0))4T\Y-C8P($-$+5)/32!I;;<"@"AW:71H(&]P^@7`86P@4F]C:W)I -M9&=E10!B2F]L:65T*0$![P$"20`T6DE05@,$0`#`=6YC;VUP[`@0]`5HW+5II<"8`V$UI8W)O`,(KP)@:&%N9&QENP(0>;<#`+8$!K@",&)E9DH# -M<&5V86QU873*`@`@``.9`P+/`A!U]@40;W$"`+8"`D,"`0H`$2"#`:)24$T@ -M=W)A<'!E3@)%9WII<#X!,6EO;A@!76)Z:7`R%@`$?`%-+TQ:5QT`HFQZ;6$L -M(&QZ:7`3`R]X>B,``!DT%``)"`&58V%N(&-R96%TSP`!=00/!@$"`J\!`[\# -M`KP"#Q\#&,$B0`&@`2P:7,@9&5S:6=N962C"R)B -M9;X"`$`$`3`$.&YE=[4#`/`$`'L``Y\!`'L``8<)`:,``DH,`PH#`#@(`+(` -M`1X#`*8$`@P"(2!B-PEQ6"@(J`2%/;C\(`/<,`G@&`0(*(VYD -M^``!B`E086QW87E&`0#=`2IE9(H(`D<`<$DG=F4@870M#0",!]!T;R!M:6YI -M;6EZ92!S#@T28U((07!O;&R4#5$N("!)9O4(0&1O;B?6!P&V`%!I8VET;-D) -M@79O:V4@82!PZP`!?PHQ9F5A-`LP*'-U+P$%^PH`J0`@(&'I``0 -M`P&@`A!MV`$32X'<70@82!T:6U7`W%O8!(71O -M(@`%2@!A="!O;F-EA0`B3VX<#@O#``+D`C)P@``S0*%82!S;V-K970^`TEW:7-HN@0!)@\#60\` -M4X.``P1$2(A`0!:""`L(E`(L2P@8V%P86)I;&ET -M]@($`P$%\0`"\P\!MP0(]@4!EP&`(&EN9&EV:61L#@/;"`"%``(5!@!"``!R -M"P#1```V`2%T;W@',&1A=-<```4.%CHN`0+("0`]`!)A[`(`R0H!*P`S:6X@ -M)P$`CP(S861DC@(88?<,`=<'`QX/469I60!`,P` -M`*,!!H`%,7=A;G\%$G0=#P$V`@%;`P$:!!!TC@0#`',*T2!S -M87ES+@I214%$3442!@9)$>$@8G5N9&QE+@H*475E<_H"H#\@($ES+%1`G -MD1(`\A$`%@)S82!F=6QL+98(F-%#A)B!P`2>`<``$D!`)()`"<`02H@97@;$T!S.B!3,@-4 -MO&0,D!`"3``!.`/``+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C_P`` -M`@`0+60"`)\`!*@``-D."*($$BP:#@#7"P!9"P]D&O__________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M________________________________________________55!E;6]R>341 -M``#P)B!A;F0@861D(&ET('1O(&$@=&%R(&%R8VAI=F4@=VET:&]U=`H@("!F -M:7)S="!W``-:``!V``!-`/($92!T:&4@9&%T82!D -M:7)E8W1L>8<`\01S;V-K970N("!)9B!Y;W4@=V%NB``2=%T`$B\]``!@`#!I -M97,S`%!D:7-K+$X`\`QR92!A2!E87-Y+@H*("H@3F]T93H@(G!A>"!I -M;G1E'1E;F1E9#@!`B(`$"QC -M`$!D97-PWP!`=VAA=)8`\`,@;F%M92!S87ES+@I214%$3450`$0@;&EB;0'1 -M8G5N9&QE+@H*475E6H`)V%T:0`K871H`&ES:6UP;&6U`$!T;V]L,P$`0``# -M`@!R>F-A="P@8@<`$G@'``!)`4!S=6-H)P!0*B!E>&%)`$!S.B!3,@-4P``7P%Q875T:&]R<\`%42!A;GD@\@(``050+@H*5&B=`3!P+6P, -M!`-V!3!O'2(`#!P=71>`C`@(F,T!A$B)`-I9"!T -M;V]L30`"5@$&ZP,`%`=!'!L@P(#+P,`0@$"(0`$F@,#,P``B`0/ -M-``+`"(`##4`+V%T-``,*&%T,P`&`0:`+C,@9VEV97/?!H!O=F5R=FEE=_," -M`*``!+L%$&%Q!3!W:&^1`A0J[`B%7W)E860N,RP0``&["`T1`%%?9&ES:Q8` -M`GX'`RH)`3X``QP``)D`$'9?`0*W`F%E9"!C86R)!Q!SU`9!;F-E2XS!`,!JP(2(FL#!:L``20`4"(@ -M=71II`59(&-L87-$``$?"49N86QSG0`P=H+`#L'`2,)@&%U=&]M871I_P(0><$",&5C=)D#$60Y"0,<`@5X"1!F -M+``!MP91*B!'3E5U`0(U`B8@*`0+`!H`06QO;F=5`@"M"R)S+!````4+`;X+ -M$G,W`E)S<&%RB,``!DT%``)"`$```I58W)E873/``$M -M"0\&`0("J@,#OP,"O`(/'P,8,")R9:`-46-T960B1P,"3P#$+"!W:&EC:"!W -M:6QLB@`!5@`%R@%A(&5X8V5P0`4`N04!RA`!:A`Q:&%T0PXQ:7)E40`!`1`! -MR@(@("A3"@$T!`"$`0-$!`#T`V`L(&5T8RGO"P+Z`P"I`@!H$0*-``&&`0+: -M``^6`P4!R`-A(FYE=V,BFP,!,P`G`3AN97>U`P#P!`#]`@-S!`![``&'"0&C``)*#`!-$2)I -MF4@``%1`0.;`")E -M;LD!!RT``'P`"W$`*&1E$0`#Q@(1+.4)`H```(T.`)8!`!8!`$``,&%G8?,/ -M`5\*D6-O7L#$7`U`-%A=&5V97(@8FQO8VMS\``` -M[@2X' -M$'1[%R%I;5<#<6]R(&UM87`I`0!>$P'Y%@*Y%P"V`A!GPA<0:2(3`2(`!4H` -M`.,3(6-EA0`A3VZ0`QMEPP`"Y`(R<')O.@$!A0$`FA<1+P"`8`.`-$9,VEN("FEP,A8`!"8`32],6E<=`/D#;'IM82P@ -M;'II<"P@86YD('AZ(P#!"DYO=&5S(&%B;W5TE`!R;&EB=$`\"YT96-T -M=7)E.@H*("H@5&AI48!`-T! -M\@%E9"!A=71O;6%T:6-A;&QY1P"P22=V92!A='1E;7#7`>!T;R!M:6YI;6EZ -M92!S="L`L"!L:6YK('!O;&QUN`'A+B`@268@>6]U(&1O;B?L`0"V`/$":6-I -M=&QY(&EN=F]K92!A('#K`(!U;&%R(&9E85D"0"`HD`!RT` -M!P8#`(`!`ID!<"DL(&ET('=P`/``(&=E="!P=6QL960@:6XN/@`G26YN`#``%1`0.;`")E;LD!!RT``#X`"W$`*&1E$0`#Q@(1+/```H``(FYEC@(` -M%@$`0`!B86=A:6YS1P*@8V]R7L#$7`U -M`-%A=&5V97(@8FQO8VMS\``0:$,$(6ETH0!!66]U717`F$@82!T:6U7`W%O`+$@(&)S9'1A3X`!8P``0`"\05R -M;W9I9&4@96%S>2UT;RUUX`0!V``*4`0"A`P&3 -M``)/!R)L>8<``J,!!H`%,7=A;H@`$'0V!`5%`0!@`!!IA0(`C@%EB!$!G -M&%)`$!S -M.B!3,@-4`0-)`#!C;VY# -M`O`".B`@5F%R:6]UP``7P%V875T:&]R,& -M`4D!A69I9W5R92`M#``"1`"U'2(`")P==8-(")C-`81(B0#`#@,*6]L30`"5@$&ZP,!*0$` -M%@D`C@$/;0$!`*(&('5SW0H`V@$T90HGL``C92>M``,D!`"3``!.`/``+F%M -M+"!A8VQO8V%L+FTT"0T#[0`P+F%C%P$``@`0+:("`)\`!*@``-D."*($$BP: -M#@#7"P)\`#%M86GV`2-EPH"MP(29:`, -M`!(&0'-E<77J"!!S"P4!/@$`=0``%P(`^00!<0`!<0H(EP``/`DS>2XS30`` -M[P0R92`B:P,%JP`!)``4(@L+62!C;&%S1``!'PE&;F%L]!9!I;@IA(&YU;6+R#!=FD0<$.P'' -M"@I9;W4@2X`L2`H8FEG+65N9&EAU!%C;&ET=&QE$0`" -M^@#Q`DE33SDV-C`@0T0M4D]-(&EMMP(0*#@.,"!O<,L#P&%L(%)O8VMR:61G -M9>\!`DD`-%I)4'4$!$``('5N,0L`)18`UA!@C2H`0#E%PD(`0``"@*<$`4Z`0!U!`\&`0("KP$#OP,"O`(/'P,8,")R -M9:`-`!`6$2)'`P)/`,0L('=H:6-H('=I;&R*``%6``:0`"!E>"T4``("`+D% -M!(D1`@L7`UH7`5$`!>D2,',@*%,*`30$`(0!`S,$`/0#8"P@971C*>\+`OH# -M`*D"!C`0`9L!`MH`#\@#"F$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0%!`); -M`0&)``]9`P`*%@,S5VAE`P(`OP@#U`(2<^8%#V0:____________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________________________________________]34')A=&EO2A$` -M`/,?;BX*("H@;&EB87)C:&EV92UF;W)M871S+C4@9&]C=6UE;G1S('1H92!F -M:6QE(!T`T2!S=7!P;W)T960@8GD>`'!L:6)R87)Y3`#08W!I;RXU+"!M=')E -M90D`\@YA;F0@=&%R+C4@<')O=FED92!D971A:6QE9"!I;E(`D&EO;B!A8F]U -M=$T`XW-E"B`@('!O<'5L87(@F``$>P#S"2P@:6YC;'5D:6YG(&AA``"/`/0:("=D;V,G(&1I2!I -M;@IA(&YU;6)E6]U(#\! -M8"X*"D-U"!I;G1E`*%35E(T($%30TE)=`(!%``"8P`/,@`%84)I;F%R>2X`P"`H8FEG+65N -M9&EA;J(!8VQI='1L91$``OH`\0))4T\Y-C8P($-$+5)/32!I;;<"\`DH=VET -M:"!O<'1I;VYA;"!2;V-KFEP/@$Q:6]N!0%=8GII -M<#(6``1\`4TO3%I7'0"B;'IM82P@;'II&-E<$`%`+D%!&D"L"!T:&%T(')E -M<75IE@4G87C*`E(@*&9OU`P#P!`![``-S!`![``&'"0&C`%0@;VYL>0H#`#@(`+(``1X#`*8$`@P" -M(2!B-PEQ4,`4&EN9&5PJ@`E;G0B`0`8"5!A``B; -M`")E;LD!!RT``'P`"W$`*&1E$0`#Q@(1+/```H``(FYEC@(`%@$`0`!B86=A -M:6YS1P*18V]R0 -M`P&@`A!MV`$38!(71O -M(@`%H0!A="!O;F-EA0`A3VZ0`QMEPP`"Y`(R<')O.@$!A0%18W1L>2W,``". -M"5)U='!U=.\"`&`$\0-O8FIE8W0M`%`@(&)S9",'(75SO`$`/06# -M;B!I=',@(D`\`!(BO01&2!F60!`,P``*,!!H`%,7=A;G\%$G0=#P-%`0!@```:!!!TC@0"0:7,@97-P96-I;@0! -MT`$"J@$`.@@P.B`BDPH.V@T3(KD"`-X.(F%NZ`(`I0<`$0,"6@<0+&,`0&1E -M8$(&YDT`(Q9G5L+P(& -M10`0+T,*`84!$6&>"C1A8W1[$X)D96UO;G-T$0(8`+5C;VYF -M:6=U'2(`"%P=6<0,"`B8S0&$2(D`P`X#"EO;$T``E8!!NL#`2D!`!8)`(X! -M#VT!`0"B!A!U/1,"$!P`"-E)ZT``R0$`),``$X`\``N86TL(&%C;&]C -M86PN;30)#0/M`#`N86/_```"`!`MH@(`GP`$J```V0X(H@02+!H.`-<+`%D+ -M$'G*!0'V`2-E!Q(M -M6`D/9!K_____________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_____________U-0:7-T"B`O$0``\R,@("H@5&\@2!F;W(@ -M:L`D'-A;64@9G5N8S`<``$D!0'-U8V@G`%`J(&5X84D`U',Z(%-O;64@6]U(&UA>2!F:6YD('5S969U;"\"!D4`42]M:6YIA0$1 -M8>,!46%C="!S8`"A(&1E;6]N2#R`I!I;VYS+@H*5&B= -M`?("<"UL979E;"!D:7)E8W1O%#36%K94QI\`!,GK0`#)`0`DP``3@#U`2YA;2P@86-L;V-A -M;"YM-"SA`$!E+F%C_P```@`2+50`)'1OJ``,H@2R+"!O;FQY(&YE961\`#%M -M86GV`2-E7-T96TZ -M"B`J(+@$=2XQ(&5X<&R#`@,O`P!"`0(A``2:`P,S``"(!`\T``L`(@`,-0`O -M870T``PH870S``8!!H`N,R!G:79E2XS30`"]P,2(FL#!:L``20`4"(@=71II`59(&-L -M87-$``'O!49N86QSG0`P`D09BP``;<&42H@1TY5=0$"-0(B("BK"0"Y`0`:`$%L;VYG4`9B;F%M -M97,L$`!3;&EN:R`1``!C`%)S<&%R'1E -M;J+``-J`0`9`]$J(%!/4TE8('5S=&%R6P`" -M$``R<&%X-`,"60<#>`('(0"P;V-T970M;W)I96X!`P!@`@$>`*%35E(T($%3 -M0TE)=`(!%``"4P`/,@`%84)I;F%R>2X`P"`H8FEG+65N9&EA;J(!8VQI='1L -M91$``OH`\0))4T\Y-C8P($-$+5)/32!I;;<"$2AX""!O<,L#P&%L(%)O8VMR -M:61G944`8DIO;&EE="D!`>\!`DD`-%I)4%8#!$``('5N,0LPFEP,A8`!'P!32],6E<=`*)L>FUA+"!L>FEP -M$P,O>'HC```9-!0`"0@!```*56-R96%TSP`!=00/!@$"`JH#`[\#`KP"#Q\# -M&#`B&-E -M<$`%`+D%!&D"42!T:&%T0PXQ:7)E40`!\P,!R@(@("@6!0$T!`"$`0,S!`#T -M`V`L(&5T8REF"@+Z`P"I`@8B!`&&`0+:``^6`P4!R`-A(FYE=V,BFP,!,P`G -MD#`*4#(71EVP@P.@H*N!`R:&ESD0]P:&5A=FEL>?P(-F5A;;4%`A$+@"X@ -M(%1H97)E+``C;F_B!P""`@/?"`"3!$$@:6XMMP^"(&UO9&EF:6-D"_``;W(@ -M0`&EP``L!!397-I9VXE#!)EB`4`0`0!7@$X;F5W -MM0,`\`0`>P`#GP$`>P`!APD!HP`"2@P`31$B:7*"$1!I>0<280D!`@P"(2!B -M-PD`C`HQ86)L``8`_0H!#``!+`L"U!``:``".P!"96%C:#T!(79E4,` -M4&EN9&5PJ@`E;G0B`0`8"0`/#Q!C0@42;VP-!C4*5"!7:6MI4@PP:6YGR0`P -M:&]W40\!LP,09$X(`]H``BH!(4]N/P@`]PP"8`8`TQ$`4`8#S0`!<`!3;'=A -M>7-S""IE9(H(`D<`<$DG=F4@870M#0",!S!T;R`A$+)M:7IE('-T871I8U(( -M07!O;&PV$E$N("!)9O4(4&1O;B=TJ`"097AP;&EC:71LV0EB=F]K92!A^@\1 -M8W\*`\X1("`HTA`E(&'["@"A`2`@84$``2<0`BT`",T`%&_Y"'`I+"!I="!W -M<`!!(&=E=!D3`5T*`*0$-R!);FX`-RP@:9X``5$!`YL`(F5NR0$'+0``?``+ -M<0`H9&41``/&`A$L\``"@```C0X`E@$`%@$`0``@86<##A%T\0F18V]RP,B:67-#P&<$P/G"B!D=1D-`)\#$'.%`2-O9H@!`(X2 -M$"UV```S#`#W"!%IM`\`A`!R96YV:7)O;@\+$7>0`P&@`A!MV`$3<3 -M`<0-0&)A8VOR`S%F2W,`))E9"!O=71P=73O`@!@!/$#;V)J -M96-T+7-T>6QE(&%P<')OR`,`^10"^@#0=&\@:&%V92!M=6QT:<,3!*D``@$$ -M`+D(52!O<&5NG@`3(!40`&H0``H!`#T%@VX@:71S(")`/``2(KT$$7,P#@)C -M!098`&!I='-E;&93`5!R96%D+^8`8'1E;B!U@``S0*%82!S;V-K970^`TEW:7-HN@0!)@\#60\`7,N"B05$6:X#007&0.A&$0N"@I1$1:@/R`@ -M27-S=65S/U(`$2H%&78Z+R]W=W7,@9&5T96-T960@875T;VUA -M=&EC86QL>2X*"B`J($DG=F4@871T96UP(@#@=&\@;6EN:6UI>F4@6]U(&1O;B=T"B`@(&5X<&QI8VET;'D@ -M:6YV;VME(&$@<&%R=&EC=6QA2!A8V-E<#4` -MT6%T979E717`G`@82!T:6UEI0!Q;W(@;6UA<'\` -M0&5N=&F?`D!R8VAI?P)`;F0@9PD`(&ET3P``2P$%2@!A="!O;F-EA0"+3VX@ -M=W)I=&7#``+D`C)P2!B=69F97(@;W+!``!E``1R`85A('-O8VME=#X#4'=I2UT;RUU0"0:7,@97-P96-I;@0!T`$"J@'S!TYO -M=&4Z(")P87@@:6YT97)C:&%N9V6?!1,BN0(@;&P\`0+H`A!DO@$`_04!P040 -M+&,`0&1EF-A="P@8@<`$G@'``!)`0"2"0`G`%`J -M(&5X84D`0',Z(%,R`U1S;6%L;!4`!#X!`%(#(6%T'`@@;6'F!"!N9-`",69U -M;"\"!D4`$"]#"@&%`1%A!@E186-T('-@`+`@9&5M;VYS=')A=+'2(`")P=;H+(")C-`81(B0#`!(+*6]L -M30`"5@$&ZP,`E``!%@D`C@$/;0$!`&8(('5SW0H`V@$T90HGL``C92>M``-G -M`0"3``!.`/4!+F%M+"!A8VQO8V%L+FTT+.$`0&4N86/_```"`!`MH@(`GP`$ -MJ```:@L(H@1A+"!O;FQYUPL"?``Q;6%I]@$C97*N`05P`"1I;F0`@2YH+FEN -M"@DM]`=2;&%T97-G`!%B-`(#<@$"M0!@"@I'=6ED\P`H($14!@32`0)U``&W -M`7!S>7-T96TZ&@D"N`0A+C'!#`!A#`$W`0,O`P`+``(A``2:`P,S``"(!`\T -M``L`(@`,-0`O870T``PH870S``8!!B$N,[8+$'-E"H!O=F5R=FEE=_,"`*`` -M!<`+`'$%,'=H;Y$"%"JD"H5?PH"MP(29:`,`%L$$'/4!A!N2PT`U@(`DP``=0``%P(` -M^00!<0`!<0H(EP`!G`DC+C--``#O!#)E(")K`P6K``$D`!0B"PM9(&-L87-$ -M``$?"49N86QSG0`2P$2+8($-7,N-:H(`J\``!D#`/T%-6UA=&D/!&,"!98!`+`` -M``H"D"XU+"!M=')E90D``&\`7G1A"`#.#1,BR0TR+F@BJ0`R:&4*7PP0(+`)`/H``!0`!.D&`W((`G\" -M-&UO2X` -ML2`H8FEG+65N9&EAU!%C;&ET=&QE$0`"^@#Q`DE33SDV-C`@0T0M4D]-(&EM -MMP(1*'@((&]PRP/`86P@4F]C:W)I9&=EYP%B2F]L:65T*0$![P$"20`T6DE0 -M=00$0``@=6XQ"P`?$P#6$&!R(")D969^!A$B9@D#&```H00C:655`0##`0"B -M`85"4T0@)V%R)U(``?@`$2?]`Q`GNP($/0%:-RU::7`F`-A-:6-R;W-O9G0@ -M0T%"+``Q3$A!"@,Z3%I(,@`Z4D%2$0`86!$``1D(!2`&`/42"*\"`'82`"H( -M`,,/`TP&!D4(,&)E9DH#4F5V86QU0@H`K@,#+P(`'P@P*B!U]@40;Q@$``L% -M`D,"`0H``EP)L5)032!WFEP,A8` -M!'P!32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9-!0`"0@!```*`IP0!3H! -M`'4$#P8!`@*O`0._`P*\`@\?`Q@P(G)EH`T`$!81(D<#`D\`Q"P@=VAI8V@@ -M=VEL;(H``58`!I``(&5X+10``@(`N04$B1$":Q0`0PX`TQ,`40`%Z1(PA@!+1`0:2`*<&AE879I;'G\"#9E86VU -M!0(1"P6(%$!I0`&@`0I:7-N%")B98@%`$`$`5X!.&YE=[4#`/`$ -M`/T"`Y\!`'L``8<)`2L5`DH,`PH#`#@(`&\0%'3N$@(,`B$@8C<)`(P*`8\8 -M`[@4`0P`$&$,`0+4$`!H``([`!%EG!8`/0$A=F5S`Q-Y0P!0:6YD97"J`"5N -M="(!`$0-`7D9`$(%$F]L#0:P"U0@5VEK:5(,`PP3,&AO=U$/`;,#$&2M`0/: -M``+W$P4T&`3\!`#S#@!0!@/-``%P``*`%P+$!0]D&O__________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M________________________________________________5E!L97,I"BP1 -M``#P)"`@*B!3;VQA -M`*935E(T($%30TE)%``"8P`/,@`%84)I;F%R>2X`\P<@*&)I9RUE;F1I86X@ -M;W(@;&ET=&QE$0`"QP#P'TE33SDV-C`@0T0M4D]-(&EM86=EFEP/@$Q:6]N1`!=8GII<#(6``1D`4TO3%I7'0"Q;'IM82P@ -M;'II<"S'`"]X>B,``!DT%``)"`&58V%N(&-R96%TSP!/&-E<'0"`D0*("`@:0+1('1H870@0`&EP"0:7,@9&5S:6=NH@9";R!B98@%`$`$`3`$ -M.&YE=[4#`-P#`'L``4,`4&EN9&5PJ@`B;G1_`!!R.P0`!``P=&EC0@4D;VZ!`02N -M`/``5VEK:2!E>'!L86EN:6YGB0`P:&]W^``!LP,09)8%`RP``BH!(4]NJ@`< -M+`,!``0$,FUA='``0&QW87E&`0#=`?(!960@875T;VUA=&EC86QL>4<`L$DG -M=F4@871T96UPC`?@=&\@;6EN:6UI>F4@2!I;G9O:V4@82!PZP`@=6Q9"*!E -M871UP,1<#4`T6%T979E`%`@(&)S9",'(75SO`$`/06#;B!I=',@(D#E -M`!(BO01&P`28D(``$X&`-$``#8!(71OFPDP9&%TUP!6=7)C93HN`0+( -M"0#"`!)A[`(`R0H!*P`S:6X@)P$`E0LS861DC@(88?<,`=<'(6]U]P119FER -M0"0:7,@97-P96-I -M;@0!T`$"J@$`.@@P.B`BDPH.V@T3(KD"(&QL/`$"Z`(`I0<`$0,"P040+&,` -M0&1E%EF-%#A)B -M!P`2>`<``$D!`)()`"<`4"H@97AA20!`8$(&YDT`(Q9G5L+P(&10`0+T,*`84!$6&>"E%A8W0@'2(`")P==8- -M(")C-`81(B0#`#@,*6]L30`"5@$&ZP,!*0$`%@D`C@$/;0$!`+`,$'4]$P': -M`31E"B>P`"-E)ZT``#H/,"`J(),``$X`\``N86TL(&%C;&]C86PN;30)#0/M -M`#`N86,7`0`"`!`MH@(`GP`$J```V0X(H@02+!H.`-<+`%D+$'G*!0'V`2-E -MPH"MP(`318A86R)!T!S97%UZ@@0 -M=&%R+C54`0CQ -M!`4^$A%S8P0Q<&]PY0\#G`$$>P`(2PE`:&%R9!8,`3`&`J@!`X42`(X!86UO -M9&5R;H\``.@!`+P'<"!V87)I86Y("0`B##!M86[X"Q%PK1]!;!I;@IA(&YU;6)E"`"X!!,BXP`R+F@BJ0`R:&4*7PP0(+`) -M`/H``!0`!.D&`W((`G\"$&T:%P/[`$(N("!0B@FR;&5T('5S"FMN;W<0`0&9 -M!F!E`D09@82`;<&`H<8!JH+"``:`/@5#"`6`1````4+ -M`;X+$G,W`E)S<&%R%#36%K94QIM``-G`0"3``!.`/4!+F%M+"!A8VQO8V%L+FTT+.$`0&4N86/_```" -M`!(M5``D=&^H```@`3!D:7-?`A!U00&R+"!O;FQY(&YE961\`#%M86GV`2-E -M7-T96TZ"B`J -M(&)S9'1AM`_`$,R!G:79E2XS!`,!JP(2(FL# -M!:L``20`Z2(@=71I;&ET>2!C;&%S1`"6:6YT97)N86QSG0!@P$2 -M+8($4W,N-2!D5@(#I@0@:6QV`]1R;6%T-50!"/$$4&%B;W5T&@$@P"`+"!I;F-L=62*`<5H87)D+71O+69I;F1;`0%'``!!`&%M;V1E -M$D# -M(F5R60<#>`('(0"P;V-T970M;W)I96X!`P!@`@$>`*%35E(T($%30TE)=`(! -M%``"4P`/,@`%,$)I;LH$`$(`H"`H8FEG+65N9&GS!(-R(&QI='1L91$``OH` -M\0))4T\Y-C8P($-$+5)/32!I;;<"$2AX""!O<,L#P&%L(%)O8VMR:61G944` -M8DIO;&EE="D!`>\!`DD`-%I)4%8#!$``D'5N8V]M<')EFEP,A8`!&0!32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC -M```9-!0`"0@!```*56-R96%TSP`!=00/!@$"`JH#`[\#`KP"#Q\#&#`B&-E<$`%`+D% -M!&D"T2!T:&%T(')E<75IP`#GP$`>P`!APD!HP`"2@P#"@,`.`@`L@`!'@,`"0$"#`(A(&(W -M"0!J"#%A8FP`!@","@$,``$L"P($`0!H``([`$)E86-H/0$A=F5S`Q-Y0P!0 -M:6YD97"J`"5N="(!`!@)``\/$&-"!1)O;`T&-0I4(%=I:VE2##!I;F?)`&-H -M;W<@=&_U``>6"@(J`2%/;C\(`/<,`G@&`P,!`_@``8@)4&%L=V%Y1@$`W0$J -M962*"`)'`'!))W9E(&%T+0T`C`<`P0^0:6YI;6EZ92!S#@T28U((07!O;&R4 -M#5$N("!)9O4(4&1O;B=TJ`"097AP;&EC:71LV0EB=F]K92!A^@\18W\*,69E -M830+,"AS=2\!!?L*`*D`("!A00`1P,1<#4`T6%T979EP"`,D*`2L`,VEN("#U%F:7)S=)("`*8!$6%P$A%O61$`]@`6+G0` -M`]D#`J60!`,P``*,! -M!H`%,7=A;G\%$G0=#P-%`0!@```:!!!TC@0#`',*+%1`G-Q,`C!4`%@)S82!F=6QL+98(7,@<')O9'5C97,@8V]R6]U('1O(&AA=F4@;75L=&EP)0`P`/,- -M("!B2!D8737`%9UX`0!V``*4`0`` -M`P&^``7+`0#3``.C`4,N("!)I`$A86Z(`!)T70`!-@(491\!`#L!061I"!I;G1E&%)`$!S.B!3,@-4`0-)`#!C;VY#`O`".B`@5F%R -M:6]UP``7P%Q875T:&]R<\`%`1\&`?("`DT'$`H5"%!T;W`M;`P$`W8%`#`' -M`4$`$&DD!0FV`B)I;O@$(FEOX08$O0+P`DY%5U,@+2!H:6=H;&EG:'1S7`8P -M'2(`#!P=71>`C`@(F,T!A$B)`,`J@2!N -M965D?``Q;6%I]@$C97*N`05P`"1I;F0`@2YH+FEN"@DM]`=2;&%T97-G`!%B -M-`(#<@$"M0!@"@I'=6ED\P`H($14!@32`0)U``#S`8`@PH" -MMP(A960N"P!;!!!SU`80;A$,`-8"`),``'4``!<"`/D$`7$``7$*")<``9P) -M(RXS30``[P0R92`B:P,%JP`!)``4(@L+62!C;&%S1``!'PE&;F%L]!9!I;@IA -M(&YU;6+R#!=FD0<#HP#7+@H*66]U('-H;W5L9*0+`$P`,6-O<'8&0&-O;6V> -M"`#.#1,BR0TR+F@BJ0`R:&4*7PP0(+`)`'4!`!0`!.D&`W((`G\"-&UO@,QBH@4U92-"!!4T-)210``E,`#S(`!6%" -M:6YA`@@;W#+`\!A;"!2;V-K[`@0]`5HW+5II<"8`V$UI -M8W)OFEP/@$Q:6]N&`%= -M8GII<#(6``1\`4TO3%I7'0"B;'IM82P@;'IIP`!APD!*Q4"2@P`31$B:7*"$1!I>0<#[A(" -M#`(A(&(W"0","C%A8FP`!@","@$,`!!A#`$"U!``:``".P!"96%C:#T!(79E -M4,`4&EN9&5PJ@`E;G0B`0!$#0`/#Q!C0@42;VP-!K`+5"!7:6MI4@P# -M#!,P:&]W40\!LP,09*T!`]H``O<3(4]N/P@`]PP"8`8`\PX`4`8#S0`!<``" -M@!<"Q`4J962*"`)'`'!))W9E(&%T(14`C`'!L:6-I=&S9"6)V;VME(&'Z#Q%C?PH#SA$@ -M("C2$`!U#`@<`A!AL@$!)Q`"+0`(S0`4;W,$<"DL(&ET('=P`%`@9V5T(-(2 -M`5T*`*0$-R!);FX`!287`9X``5$!`YL`(F5NR0$'+0``?``+<0`H9&41``.J -M`!$L6!$"@```C0X`E@$`%@$`0``P86=A\P\!7PJ18V]R7L#$7`U`&)A=&5V97)X%Q%S\```[@$P'Y -M%@*[&0"V`A!GQ!D0:2(3`2(`!4H``.,3#V0:________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M__________________________________________](4'(*("`J-Q$``/T, -M(&=Z:7`@8V]M<')EFUA -M+"!L>FEP+"!A;F0@>'HC```9-!0`\3(*5&AE(&QI8G)A&-E<'1_`/$* -M"B`@("!E;G1R:65S('1H870@$E33SDV-C`3`%HW -M+5II<#D`-EA!4A$`0PI7:&4#`@#D`00%`A$L_`%A2!S=')E86WM -M`>!S>7-T96TN("!4:&5R92P`D&YO(&1IP`!S@`4=E@#$G.C -M`%0@;VYL>0H#0&UE;G2R``$>`P+``P"#`R`@8H\!D"!R96%D86)L9:(`07=R -M:70,`!!A#`$"!`$!1`0!.P!$96%C:"8"`98"$WE#`%!I;F1E<*H`(FYT?P`0 -M$N("!)9B!Y;W4@9&]N)^P!`+8`\0)I8VET;'D@:6YV -M;VME(&$@<.L`('5L-P0@96%9`D`@*'-U+P$9``%1`0.; -M`")E;LD!!RT``'P`"W$`*&1E$0`#J@`1+/```H``(FYEC@(`%@$`0`!B86=A -M:6YS1P*@8V]RP,1<#4`T6%T979E2!B=69F97(@)`@`90`$<@&%82!S;V-K -M970^`TEW:7-HN@3`P"`,,)`2L`,VEN("0#`',*T"!S87ES -M+@I214%$346[!@?H!N$@8G5N9&QE+@H*475E<_H"H#\@($ES7!1`GH@1`9W)A;18"F-%#A)B!P`2>`<``$D!`)()`"<` -M4"H@97AA20!`8$(&YDT`(Q -M9G5L+P(&10`0+T,*`84!$6&>"E%A8W0@H($',+!0$^`0!U```7`@#Y!`%Q -M``%Q"@B7```\"3-Y+C--``#O!#)E(")K`P6K``$D`!0B"PM9(&-L87-$``$? -M"49N86QSG0`2!Q(M@@0U -M"`"X!!,B!0XR+F@BJ0`R:&4*7PP0(+`)`/H``!0`!.D&`W((`G\"-&UO5$P`P%&!E2X`L2`H8FEG+65N -M9&EAU!%C;&ET=&QE$0`"QP`$7Q:10T0M4D]-(&EMMP(0*#@.,"!O<,L#P&%L -M(%)O8VMR:61G9>\!`DD`#QX78P\+%P#036EC2$`\AMU7-T96TZ"B`J(&)S9'1A@ -M`/`#;&EB2!A2XS -M30`"=`%U(G-T2!C;&%S1`"6:6YT97)N86QS -MG0!@P"`+"!I;F-L=62*`<5H87)D+71O+69I -M;F1;`0%'``!!`&%M;V1E``"/`/`-("=D;V,G(&1I2!I -M;@IA(&YU;6)E2!E2QN``5H`W!U=&]M871I_P(0>68!,&5C=)D#$635``,<`E!O;&QO -M=Y,!$&8L`#!S.@K?!#%'3E5U`0(U`B8@*+D!`!H`06QO;F=5`F)N86UE`*%35E(T -M($%30TE)=`(!%``"4P`/,@`%84)I;F%R>2X`H"`H8FEG+65N9&GS!(-R(&QI -M='1L91$``OH`\0))4T\Y-C8P($-$+5)/32!I;;<"@"AW:71H(&]P^@7`86P@ -M4F]C:W)I9&=E10!B2F]L:65T*0$![P$"20`T6DE05@,$0`"0=6YC;VUP[`@0]`5HW+5II<"8`V$UI8W)O`,(KP)@:&%N9&QENP(0>;<#`+8$!K@" -M,&)E9DH#<&5V86QU873*`@`@``.9`P+/`A!U]@40;W$"`+8"`D,"`0H`$2"# -M`:)24$T@=W)A<'!E3@)%9WII<#X!,6EO;A@!76)Z:7`R%@`$?`%-+TQ:5QT` -MHFQZ;6$L(&QZ:7`3`R]X>B,``!DT%``)"`&58V%N(&-R96%TSP`!=00/!@$" -M`J\!`[\#`KP"#Q\#&,$B0`&EP"P:7,@9&5S -M:6=N962C"R)B9;X"`$`$`3`$.&YE=[4#`/`$`'L``Y\!`'L``8<)`:,`5"!O -M;FQY"@,`.`@`L@`!'@,`"0$"#`(A(&(W"7%R96%D86)L``8`C`H!#``!+`L" -M!`$`:``".P!"96%C:#T!(79E4,`4&EN9&5PJ@`E;G0B`0`8"5!A`8!`@HC;F3X``&("5!A;'=A>48!`-T!*F5DB@@"1P!P22=V92!A="T- -M`(P'T'1O(&UI;FEM:7IE(',.#1)C4@A0<&]L;'4B!U$N("!)9O4(0&1O;B?6 -M!P&V`%!I8VET;-D)@79O:V4@82!PZP`!?PHQ9F5A-`LP*'-U+P$%^PH`J0`@ -M(&'I``2UV```S#`#W"!%IAP8`A`!P96YV -M:7)O;M<",7,@=Y`#`:`"$&W8`1-R6@,%,`(`6P`"?P`1>7L#$7`U`-%A=&5V -M97(@8FQO8VMS\```[@@``8P2%82!S;V-K970^`TEW -M:7-HN@0!)@\#60\`4X.475S92`B(0$`6@@@+")0 -M"+$L(&-A<&%B:6QI=/8"!`,!!?$``O,/`;<$"/8%`9P"`,D*`2L`,VEN("#U%F:7)S=)("`*8! -M$6%P$A%O61$`]@`6+G0``]D#`J60!`,P``*,!!H`%,7=A;G\%$G0=#P$V`@%;`P$:!!!TC@0#`',*T2!S87ES+@I214%$3442!@9)$>$@8G5N9&QE+@H*475E<_H" -MH#\@($ES+%1`GD1(`\A$`%@)S82!F=6QL+98(F-%#A)B!P`2>`<``$D!`)()`"<`02H@ -M97@;$T!S.B!3,@-4O&0,D!`"3``!.`/``+F%M+"!A8VQO8V%L+FTT -M"0T#[0`P+F%C_P```@`0+60"`)\`!*@``-D."*($$BP:#@#7"P!9"Q!YR@4! -M]@$/9!K_____________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_____________V=08VAI=F4G$0``\#T@=VET:&]U=`H@("!F:7)S="!W2!F6]U('=A;H@`$G1=`!`OB@`196``,&EE -M7,N"E)%041-12X`1"!L:6(3 -M`=%B=6YD;&4N"@I1=65SK@"@/R`@27-S=65S/U(`UBH@:'1T<#HO+W=W=RXX -M`$`N;W)GDP``2`$Q:&]MIP"`(&]N9V]I;F`<``$D!0'-U8V@G`%`J(&5X84D`0',Z(%,R`U1S -M;6%L;!4`!#X!`%(#(6%T?`2`;6%Y(&9I;F30`C%F=6PO`@9%`%$O;6EN:84! -M$6'C`5%A8W0@2#R`@`!!5`N"@I4:)T!,'`M -M;`P$`W8%,&]R>3$%,'1A:20%";8"(FEN^`0Q:6]NZP4$O0+P"4Y%5U,@+2!H -M:6=H;&EG:'1S(&]F(')E8P8"`C$%`Z`"DD-/4%E)3D<@+0P%`,T%`"@&(F1O -MGP``AP4`S@#R!"H@24Y35$%,3"`M(&EN\`!,G -MK0`#)`0`DP``3@#U`2YA;2P@86-L;V-A;"YM-"SA`$!E+F%C_P```@`0+:(" -M`)\`!*@`#*($LBP@;VYL>2!N965D?``Q;6%I]@$C97*N`05P`"1I;F0`@2YH -M+FEN"@DM]`=2;&%T97-G`!%B-`(!9@$39;4`8`H*1W5I9/,`*"!$5`8$T@$" -M=0`!MP%P!1%E -M^P,`\@"`;6%T]!;!I;@IA(&YU;6)E"`"X!!,B?P(R -M+F@BJ0"`:&4*`D09BP``;<&42H@1TY5=0$"-0(F("@$"P`:`$%L;VYG50(`K0LB+``-J`0`9`]$J(%!/4TE8('5S=&%R6P`"$``/B@P#!R$`P&]C=&5T -M+6]R:65N=!<$,7!I;QX`IE-64C0@05-#24D4``)3``\R``5A0FEN87)Y+@#` -M("AB:6FEP,A8` -M!'P!32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9-!0`"0@!```*56-R96%T -MSP`!+0D/!@$"`JH#`[\#`KP"#Q\#&#`B&-E<$`%`+D%!FH0,6AA=$,.$&F6!2=A>,H" -M("`H%@4!-`0`A`$#1`0`]`-@+"!E=&,I[PL"^@,`J0(&,!`!A@$"V@`/E@,% -M`<@#82)N97=C(IL#`3,`)W-HL``!$@`/1@-C!`4$`EL!`8D`#UD#``H6`S-7 -M:&4#`@C1#@+F!6%R97-U;'1-$A%B:`4@=&6[#@%5!`\C`@$*"P,!@``/Z0)4 -M$`HJ$@&G!P(F"`:A!@`^!R%T9=L($3I4$@$M$!!I(`IP:&5A=FEL>?P(-F5A -M;;4%`A$+<"X@(%1H97(T$2`@;M82,7)E8S`1`]\(`),$02!I;BVW#X(@;6]D -M:69I8^4,\`!O`3AN97>U`P#P!`#]`@-S!`![``&'"0&C``)*#`!-$2)I7-S""IE9(H(`D<`<$DG=F4@870A%0",!S!T;R`A$'!M:7IE -M('-TM0@"4@A!<&]L;#82!N04061O;B?L`7!E>'!L:6-I#15@:6YV;VMEO!(! -MZP`!?PH#SA$@("C2$"4@8?L*`*$!("!AL@$!)Q`"+0`(S0`4;_D(<"DL(&ET -M('=P`$$@9V5T&1,!70H`I`0W($EN;@`R+"!I@A4!G@`!40$#FP`B96[)`0"(&5N=FER;VX/"Q%WD`,!H`(0 -M;=@!$W):`P4P`@!;``)_`!%Y>P,1<#4`T6%T979E:89`@4.%CHN`0+("0`]`!)A -M[`(!@`X`T1DS:6X@)P$`104U861D'`$`_`@$J@$`>08/9!K_____________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_____________________________________________________V502!O9B!T:&4@9F]L -M;&]W:6YG.@H@("H@=75E;F-O9&4-`/$!9WII<"!C;VUPFUA+"!L>FEP+"!A;F0@>'HC`,$*3F]T97,@ -M86)O=724`/`[;&EB2!A2!S=')E86TM;W)I96YT960@P`!S@`0=G(!4G)M871SHP#P`B!O;FQY(')E<75I4,`4&EN9&5PJ@`B;G1_`$%R92!A!`"4 -M=&EC;&5S(&]N@0$$K@#P`%=I:VD@97AP;&%I;FEN9\D`,&AO=_@``O4`!RP` -M`BH!(4]NJ@`<+`,!`',!,FUA='``0&QW87E&`0#=`?(!960@875T;VUA=&EC -M86QL>4<`L$DG=F4@871T96UPUP'@=&\@;6EN:6UI>F4@2!I;G9O:V4@82!P -MZP"`=6QA8`0U:``)[`S%I97/#``%O`[!A;'-O(')E9'5C99L" -M,&4@0"0:7,@97-P96-I;@0!T`$"J@$`.@CS`SH@(G!A -M>"!I;G1E7!1`GH@1`9W)A;18"`<``$D!`)()`"<`4"H@97AA20!`8$(&YDT`(Q9G5L+P(&10`0+T,*`84!$6$& -M"5%A8W0@`0-)`#!C;VY#`O`".B`@ -M5F%R:6]UP``7P%V875T:&]R,&`4D!A69I -M9W5R92`M#``"1`"U'2(`")P==8-(")C-`81(B0#`#@,*6]L30`"5@$&ZP,!*0$`%@D`C@$/ -M;0$!`*(&('5SW0H`V@$T90HGL``C92>M``,D!`"3``!.`/``+F%M+"!A8VQO -M8V%L+FTT"0T#[0`P+F%C%P$``@`0+:("`)\`!*@``-D."*($$BP:#@#7"P)\ -M`#%M86GV`2-EPH"MP(29:`,`%L$0'-E -M<77J"!!S"P4!/@$`=0``%P(`^00!<0`!<0H(EP``/`DS>2XS30``[P0R92`B -M:P,%JP`!)``4(@L+62!C;&%S1``!'PE&;F%L]!9!I;@IA(&YU;6+R#!=FD0<$.P''"@I9;W4@ -M2X`L2`H8FEG+65N9&EAU!%C;&ET=&QE$0`"^@#Q`DE3 -M3SDV-C`@0T0M4D]-(&EMMP(0*#@.,"!O<,L#P&%L(%)O8VMR:61G9>\!`DD`-%I)4'4$!$``('5N,0L`)18`UA!@C2H -M`0#E%PD(`0``"@*<$`4Z`0!U!`\&`0("KP$#OP,"O`(/'P,8,")R9:`-`!`6 -M$2)'`P)/`,0L('=H:6-H('=I;&R*``%6``:0`"!E>"T4``("`+D%!(D1`@L7 -M`UH7`5$`!>D2,',@*%,*`30$`(0!`S,$`/0#8"P@971C*>\+`OH#`*D"!C`0 -M`9L!`MH`#\@#"F$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0%!`);`0&)``]9 -M`P`*%@,S5VAE`P(`OP@#U`(2<^8%7W)E1X`\`EL -M:6)R87)Y"B`J(&-P:6\N-2P@;71R964)`/(.86YD('1A3`1!F+`"@FEP,A8`!'P!32],6E<=`*)L>FUA -M+"!L>FEP$P,O>'HC```9-!0`"0@!E6-A;B!C,H"4B`H9F]R-`0` -MA`$#,P0`]`-Q+"!E=&,I+F\!`/H#`*D"!B($`1<``MH`#Y8#!0'(`V$B;F5W -M8R*;`P$S`"=S:+```1(`#T8#8P0%!`);`0&)``]9`P`*%@,S5VAE`P(`V`(# -MU`(2<^8%87)E``B;`")E;LD!!RT``'P`"W$`*&1E$0`# -MQ@(1+/```H``(FYEC@(`%@$`0`!B86=A:6YS1P*18V]RP,Q:65SPP`!;P,#YPHQ9'5CN04P92!SA0$C;V:(`0`]"A`M=@``,PP` -M]P@1:8<&`(0`<&5N=FER;V[7`C%S('=N`@&@`A!MV`$32W,``"."5)U='!U=.\"`&`$\0-O8FIE8W0M`%`@(&)S9",'(75SO`$`/06#;B!I=',@(D`\`!(BO01&2!F#U%F:7)S=)("`*8!(&$@0P40;\,/`=X*%BYT``/9`P*G -M`0"_``*<`0&%``:X`0!V``##``"\`Q)EDP`",0\@;'ED`0#,``"C`0:`!3%W -M86Y_!1)T'0\!-@(!6P,`8PP`,P!!9&ES:RP#`WX&N6-O;G9E;FEE;F-EP`$` -MB0`P;6%K>0"0:7,@97-P96-I;@0!T`$"J@$`.@@P.B`BDPH.V@T3(KD"`-X. -M(F%NZ`(`I0<`$0,"6@<0+&,`0&1E`0-)`#!C;VY#`F$Z("!687+N$V!I=&5MH(`N47`),``'4` -M`!<"`/D$`7$``7$*")<``9P)("XSHQ:L`D'-A;64@9G5N8S`<``$D!0'-U8V@G`%`J(&5X -M84D`U',Z(%-O;64@6]U(&UA>2!F:6YD('5S -M969U;"\"!D4`42]M:6YIA0$18>,!46%C="!S8`"A(&1E;6]N2#R`I!I;VYS+@H*5&B=`?("<"UL979E;"!D:7)E8W1O%#36%K94QI\`!,GK0`#)`0` -MDP``3@#U`2YA;2P@86-L;V-A;"YM-"SA`$!E+F%C_P```@`2+50`)'1OJ``, -MH@2R+"!O;FQY(&YE961\`#%M86GV`2-E7-T96TZ"B`J(+@$=2XQ(&5X<&R#`@,O`P!"`0(A``2: -M`P,S``"(!`\T``L`(@`,-0`O870T``PH870S``8!!O`%+C,@9VEV97,@86X@ -M;W9E] -M!;!I;@IA(&YU;6)E"`"X!!,BO0(R+F@BJ0"`:&4*2R"```[!P$C"4!A=71O -MDP8`_P(0><$",&5C=)D#$635``,<`@5X"1!F+``!MP91*B!'3E5U`0(U`B(@ -M**L)`+D!`!H`06QO;F=0!F)N86UEB,``!DT%``)"`$```I58W)E873/ -M``%U!`\&`0("J@,#OP,"O`(/'P,8,")R9:`-46-T960B1P,"3P#$+"!W:&EC -M:"!W:6QLB@`!5@`%R@%A(&5X8V5P0`4`N04$:0)1('1H871##C%I?P(-F5A;;4%`A$+@"X@(%1H97)EO0\C;F_B!P""`@/?"`"3!$$@ -M:6XMMP^"(&UO9&EF:6-D"_``;W(@0`&EP``L!!3 -M97-I9VXE#!)EB`4`0`0!7@$X;F5WM0,`\`0`>P`#GP$`>P`!APD!HP`"2@P` -M31$B:7)`$!!I>0<280D!`@P"(2!B-PD`C`HQ86)L``8`_0H!#``!+`L"U!`` -M:``".P!"96%C:#T!(79E4,`4&EN9&5PJ@`E;G0B`0`8"0`/#Q!C0@42 -M;VP-!C4*5"!7:6MI4@PP:6YGR0`P:&]W40\!LP,09$X(`]H``BH!(4]N/P@` -M]PP"8`8`TQ$`4`8#S0`!<`!3;'=A>7-S""IE9(H(`D<`<$DG=F4@870M#0", -M!S!T;R`A$+)M:7IE('-T871I8U((07!O;&PV$E$N("!)9O4(061O;B>L$I!E -M>'!L:6-I=&S9"6)V;VME(&'Z#Q%C?PH#SA$@("C2$"4@8?L*`*$!("!AZ0`! -M)Q`"+0`(S0`4;_D(<"DL(&ET('=P`$$@9V5T&1,!70H`I`0W($EN;@`W+"!I -MG@`!40$#FP`B96[)`07L#$7`U`-%A=&5V97(@8FQO -M8VMS\```[@2X'<70@82!T:6U7`W%O8! -M(71O(@`%2@``XQ,A8V6%`"%/;I`#&V7#``+D`C)P`!,@%1``:A``"@$1:2$( -M8VETP"`,D*`2L` -M,VEN("#U%F:7)S=)("`*8!$6%P$A%O\0T` -M]@`6+G0``]D#`J#B)A;N@"`*4'!C0*$"QC`$!D97-PH@``;`0!Y`,`7,N -M"B05$6:X#007&0.A&$0N"@I1$1:@/R`@27-S=65S/U(`$2H%&78Z+R]W=WF4@6]U(&1O;B=T"B`@ -M(&5X<&QI8VET;'D@:6YV;VME(&$@<&%R=&EC=6QA2T`5RH@8V%T:0`K871H`&ES:6UP;&6U`$!T;V]L -M,P$`0``#`@!R>F-A="P@8@<`$G@'``!)`0#^!@`G`%`J(&5X84D`0',Z(%,R -M`U1S;6%L;!4`!#X!`%(#(6%T>`:`;6%Y(&9I;F30`C%F=6PO`@9%`!`OKP2#R`C!I;VZ*!B!4 -M:)T!,'`M;`P$HB!D:7)E8W1O\`!,GK0`#)`0`DP``3@#U`2YA;2P@86-L;V-A;"YM-"SA`$!E -M+F%C_P```@`2+50`)'1OJ```(`$(H@2P+"!O;FQY(&YE963%"!!YR@4!]@$C -M97)<`05P`"1I;F0`D"YH+FEN"@DM(*,*4FQA=&5S9P`18C0"`68!$V6U`&`* -M"D=U:63S`"@@1%0&!-(!`G4``/,!@"!S>7-T96TZ`@L"N`0A+C$M"@#-"0$W -M`0,O`P!"`0(A``2:`P,S``"(!`\T``L`(@`,-0`O870T``PH870S``8!!O`% -M+C,@9VEV97,@86X@;W9E2XS30`"]P,2(FL#!:L``20`4"(@=71II`59(&-L87-$``'O!49N86QS -MG0`PP$2+8($-7,N-:H(`J\``!D#`/T%-6UA=-4,!&,"!98!`$P```H"D"XU -M+"!M=')E90D``&\`7G1AP`(2PF!:&%R9"UT;RTP!@1;`0%'``!!`&%M;V1E``$=`U'1E;J`('(0"P;V-T970M;W)I96Y$$`!@`@$> -M`*%35E(T($%30TE)=`(!%``"4P`/,@`%$$+9#A%Y+@"@("AB:6\+`OH#`*D"!B($`9L!`MH`#Y8#!0'(`V$B;F5W8R*;`P$S -M`"=S:+```1(`#T8#8P0%!`);`0&)``]9`P`*%@,S5VAE`P(`OP@#U`(2<^8% -M87)E0`&EP"2:7,@9&5S:6=N0A4B8F6^`@!`!`%>`3AN -M97>U`P#P!`![``.?`0![``&'"0&C``)*#`,*`P`X"`!O$#)T:&$)`0(,`B$@ -M8C<)`&H(`?L5(6]RSA`!#``080P!`M00`&@``CL`0F5A8V@]`2%V97,#$WE# -M`%!I;F1E<*H`)6YT(@$`1`T!Y18`0@42;VP-!K`+5"!7:6MI4@P##!,P:&]W -M40\"I@<`3@@#V@`+H!4$_`0`\PX`4`8#S0`!<`!`;'=A>48!`-T!*F5DB@@" -M1P`/T!?_X`GZ`Q!C-P8`!1C"871E=F5R(&)L;V-KU0H`[@<3`<0-0&)A8VM``S%F2!FP"`8`.`"L`,VEN("#U%F:7)S=)("`*8!$6%P$A%O_P(`]@`6+G0`!L`.`048`"<&`)P!`84` -M!K@!`'8``,,``H08`;X``NX4`(46`(<``J,!!E`=,7=A;IL8$'3+&`,V`@%; -M`P`G'``S``"C$0$L`P%K`P`+#YEN=F5N:65N8V7``0")```P%`*!$U)E#@#B``Y6#A`L8P!`9&5S -M<*(``&P$`>0#`',*CR!S87ES+@H``0#_B0`[%P^?`4T/`!X+434@("!# -M\2`!F0(#8P``4AT9R965" -M4T0P`#%3>6TW%P3``0.F`P#E`29E`I@`!58!$TDV -M``+=#`!&!`!/``+$`!4GJ1H!U0().`,`R@HR:65S3@`"F@1A,3H@3F5WF@,* -M2``$&P-9$@3("0%!``.) -M!1`P"`(!LB<`>`!V($UA8R!/4ZD"`#P`!ZX$`3H``T(")#`Z4``'ZP``J@D# -M_0(05`T%$CL^ -M+T`@97AI$14"IP0#U`<`&@$`E!T#C0H"8P`&FP`#700!WR$&$`4$!P($&P-@ -M8R!C;4',6UA=`P$`]P%03`Z($0V,$%D97)E)"HS8V4@ -MPP,"``>`!`OX8`0$2%3-4``01`0#?(S,@+5;B -M#@93!`9K"S@R+CBK$3=*86[(`P!V"P',"`8*`P"3`.`G96-H;R!N;VYE>&ES -M=,`0!(`!)S,P`% -M7`$`9``',P`"9P0"H1(`_S-!C```D$#!#```)$Q`I@!02`Q+C=E!Q$Q]0`((0!P;'IM82]X>EL#`^$" -M`&<`!!8@"0((`D`$`)\%$WGR#@!)`!%(R"0@(&?^$@)%``#8"01!`$!/<&5N -ME"5P(F=ZP`%B0)` -M061D:,F -M!#40%&F3#P!/`0#$`B)S=1TB(@H)(P``GC<";2(A -M`X,($CMJ$]-"``!904`*`)`4$1&(!$+`.0Q`-@(,FUA -M;BX(`)D0`,,(`NTU$&60#P&;#P@6,`%-```P#`!*`#!-86JG(P/[#@06"@-# -M!`$!`P!"$4!#:&%R_PM`5VEL@$+60`03I8P`_H.7V9R86UE9``+8$AI -M9V@M`,<'071A;7"6"S!46L6&B^O`P** -M%@"[`0_Y`P(-20`*NPD(NQD"]QP!2@`$6P("^0P08[H!(&5R?B4I=&]V&0!- -M!@!\-`(',0&7!!!I=B@!'P$`!0L`BP50"@EP96^T"P&))0"D`2!I<-H##XH` -M!@VV``M5!P>."`$*$@'Y#0TH`%8U+CDP-3P*`0D!`M(4#RL``ALT*P`#3PH/ -M5@`!%S,K``#^&`/C"`\K``$(#@D!*P`%TP$)U```K``(B@@**P`04S`+`(8& -M1'!R92W<"P"4"``["0!F`0E,`!(VC!@#\P,:.$<#!#0#0#H@5&C^`0`!%P"< -M"@";*4%R;W5T)@/":G5S=`H)8V]NH6`7<``H(1 -M`($"`BT%$SI=!@3G!@8.!P&I)W!G971O<'1?(0=2*"DL"@DR-P":`0-3#@+) -M$@$^```-`A!OS"46;$,5$2XA&@:\`*!*86%K:V\@2&5I@0$0;K$`)6%RCS8# -M%@4(]!@"0``"%`L0.`D1\`9D!P'%"`(<0`#80@)K -M*P"1*5)D(&)U9\4"('-IP@$`5@$A-&*<(A=YKP$+>`$7-$\!`2D`!24##]@! -M`3!F:7CK!0!L`@3\'@JP$P`.-`#-``!&!`$S&`8C!@&^'`%F$0!+(0;V'P)I -M`P`_#@`)"1-AW4-S(E-C;W1T(MP6$"!4```+"@6>`Q-M@SX0<]0&!#4`DDME -M97,@6F5E;-0"`#4`!4$``3T*`;T?`-,4`),.!!L!!?(`2$9I>""Q.I)N;VXM -M97AP;&\!$`!M%A!E9`T";0$"92V5=F5R9FQO=W,L:0`&CP#`1&%V:60@4F5M -M86AL]R("=14!)!TR;VENP!P`QCL`1`L-C0#P"$-O;&EN(%!E`0`O/`*``0..$@(?`P!H -M0Q%SB1%0(&AAFRJ1A(MN`01;"\R`0(`($1IRS$!8`4D.B".`.%R979I9775R;/E&8C0V;61G#H@16YS0T`"P3DP9&ER"AU`CH)$'#L.P#<%P*W -M!`"Z`$`M;F\MN@HC9FF..#1L:6+-1P-O%``G``NH`&(Z(%-K:7"3&`&S`0%C -M!0%*!0/_!`(Q"%`S,BUB:18%,&9?=$<`,&ES;ZD^!"P!$F*[(3!T`*L`""@`!-XC`<8!("URD@8@+74E``87`073``$>'P,\!"PN:+L# -M$%.X$3!I9FD##P`J`#5I;F=0"R`N:,D)!I\&`+`-`7-'(&5DE000:0,($7DX -M2S!I``&8!P#5$P/J"`%\"0()!`8]"P#B -M`@]+``\`)@$`JP``^`@895L"`UH5,"!U=1L1,&1E.PP!$7F0#@*X#0'4#Q`M -M@2XQ96-O@052;&]G:6.Q%0(T`!!S-```3A4"3R(!]A0`=@$!&``"6TD"FQ<# -M?0(&U`@)4P)$-"XQ-'H>0&0[(&E`!@S!$`B"6%*"@!3`0'P -M"!!G2P41+W8C8"!M:7AU<-\I!L@6`K$``,()%&G$+R)D"NT6`&<$`H0I`1X' -M$B[('P;F#@RF`!4SI@`"DQ@%^0(#=AT`G081+$P"`),`$BR:`!`L+`0"G@`! -M.P$@8V%E$!%BF`LQ=F5RVP,$TB).$F7^ -M`4!355,MW0D!K!@'C@``TPL`@0!@(&-L87-HF@H"9RL"*``5,4D4`"@``!<% -M`$8#`ID&":Q#$"R"))$@2V%I(%=A;F?R``8\`!);FP(075\)0&UI="!-*@+L -M4P7@(E!D979I8U8!``@HI``"H`2!B87-.$62(`P$7"0,5 -M`0;#)0-,!0(J(@9U``I+`&1697)I9GE-!`%6"`!)&C%G972:#0*E/`%B"P3- -M50!Q&@&.!44R+CDN@@$".@``2`$2;%0Q$&(3&0';"P?A#R(H+:4/0"UZ*2RK -M`P`A#S$);V:J#3!R;6%>$@">'S)E=L"`9P!!U,'5&ET:`H)@P(4&"%`P+CDN,,8'`($'`LY3('=IH14S -M=7-E)QL%-``@0V^/&P`:"U!I;FET:7P&``\E!#$0`,H!`PD"!)@``L<##I@` -M%3G*!@+```4H``;4!0!C`0*--`!Z!0*)%PED`/`#.B`@+6$L("UQ+"`M3"P@ -M+68LFQ@0=#X8-"!S9?LO`)4`(2UI'0@S+6ETF``#\0\.F``:.)@`!B@``2LD -M`$4`#7](`"`4`OL(<64@>F5R;RWZ0`!Y!`&<)`.,0!`LF@H$C1*A1&%M:65N -M($=O;*H$`*,`$&)Z#0#I``&/`P").!!YR08`*$$`L"`!)@$"I"H/Y@$`%C>V -M``(I``(:$`[?`!8V*0``>`(#61L1-Z@K$"\%"0$%`!!?N!0@+F.A(0"""S!S -M("*B!4`M8R!\*``P("UXTTHE<'GX'0%T``,0&Q(WB05082!C;W64'"-O9I8$ -M!ZTF`.4%`7\``JD/#J<`!_(5"B@``%L``*D#`:<``04`$5]I`1!?WP0A8GG9 -M,0)%`7)E('5M87-KI#\#0`$#^AX.<``&6`D"RP`%'@(`A@<&-%($A`)0+2UD -M:7.G$%(M>&%T='D*!A0`=6%C;"P*"73M`?\`4V%M=6QI(%-U;VUI;F5NC``- -M!SX)`?P`!8P`!C\"P$QA<&\@3'5C:&EN:=4%`'I5`4D"`$X<`55)``4.`=() -M`9HD`TH%`),!(&QD5PD!52X`^AL$;P0P8G5GQ@4!&```0`&P;V8*"2)L96YG -M=&B>%)!E;F0B(&9L86<>"@5A`!)S'P0&5@$"3@`#`@01()L&`5(&`3X"`*D& -M`2\$!#<`!?,#$$:C`4`@8W5T:P!`)!0HH``)X```E"`#Q -M!0`R%`8\`@.Z#%!C:&EL;`<7"SL`$$^0!@#9$`#P`@+W!R(@87M6("!OZ1`J<;`JQ8`LT"`X\;`"T9`$\%`DHT -M`"U7``\($GF&``9S!A!4!`8#,P``%0$`.`03>?,0`%@2`$($`,8E`+LB`^8) -M&#J8`@)M"``U""!E>-06`$)%!#@``>8>,S)'0G\F,S%40F@!`E8Y#0P%&#,N -M&@`M`08H`!)##P@"/P`\T%`*`&4'-K:7!P&`$# -M.@(%L1,!K@T`,12E97AA8W1L>0H)82L@`.87(#1'M`@#X!(':!$!G0$"&PX' -M9P``6P$`9@`'0P)0*#XX1RGC``4^`@#4``#<$D-A($`;D"$V3R -M-`%Z$``!!!$@?AA@"@EI;G-TA`80P"!$`>`$D-`AL$`;H*!.@K,4-64UD? -M`-A()W5LG0$+M``'^0X"*0`/Q@P#&#(;"`%1``4H``93"@HF(A(G3R8`A`H$ -M1"$!E`(19"@%`*`"!.,3,F-R:5@84G-E8W5RN"@@9W.`+0)]8B`@8?\5`/\. -M`!IG$PF5'P0M``DC(%!A9'9I<^9;(W,O"@&F+5-!+3`W.C`U+OH`0BYA``'O``>L!P&*)`'R/0#]"P!Y"`A:$`#@```!#P",`P!E*`#V'`:? -M)A`L#1P!`0PD"@F&%0))$P11.24@=!86`I<$("YH+!XC863%"6-L96%N=7!^ -M*PIB`1(L'14`#`<1P=V]R:V5D(&]K -M87F+'`'.!Y!I="!H96QD(&_#0P"H!0*:``!A&P&J``"]-0"%*@(7(@#Y'2!U -M;4$P`'P5`EP.!/X&`9Q#`/$08"!B`/HP`?@"!)\` -M`6``$%\9`19E^30`E@X`J``"[BP0:'(,`2X=@'-O;F%B;'D@N0$`$A4"EPT` -MR34`IAP7>8(3@5-K96QE=&%L?`L&C`@!70<#[`$&`@4+[`$:,>P!!B@`4$9L -M97-HR1<`U01>>H#0F%C:&73`0*M!0`"$Q!N)`$0;R$@$'*D!@#,`0"_#0!3$3!R -M:7.V4B!E;KH'$&E48P&F&`-R`@!'(#`*"61E`S!M:6QG#@%3!`#Y"@"1.`^! -M#`09,9P7`2D`!58(!!,2!G($`TP``@I+`/D$"2H"`&L!`JT!`TL`!B@``*0! -M`740,7)E8W\.%RVH`042`@$:"@7$.#$*"2A*(``#8P#?+0!1*03B%@#%'`"I -M)`%."0%W-P`:,$%C:"!B="-1+BD*"48%!$,@:7-O*`$0;:,W("@I>6H""`!A -M86ME9&5V1R`%MP,!R@$D+F/I``4$`@OI``<`"@`T`08H``(T`0+/`1%F[R(! -M@@<`H!\!'!4@;V[20T-/4R!82P$%,P<+8@`([`D%!4X`$1"_X`!S8))@E,.Q8`@0``[`0"NB`0 -M;F8=`2HA``D!`'4$``0#`/Y/1&5R:7AC``6E!PMC``CE"`#$`0,:(PQV"R681(N@!#AT` -M`1`"$B`<*P:[``(?#@!U-P&C``0V`#)I;VZY,0(Y,0#7!`%A!B)E9.H=,&QI -M:U@1`-\I!SD"`O4]`&("\`%&965D8F%C:PH)87!PA -M*P8P)@',``5W``)N3@`N"J!N9FEG+F=U97-S"#`!#@`P`1`T!%PH`FD``.0``C\"`,15`HLG -M!2@!`>H#!``7`-@%"3H)(G1O"#T$B`$%-P`,B`$'N04*B`$12`T'!$<-(',[ -MD`T09=`$8&YU>"]F2!O8G:N<@!F!0%K&P/>*P(]$U%T -M:&ES+/,((6UEO"@`C0H(Y0`35Q`$-705). -M&`(&"B`'MP`!:@0'8@8`7`$&*0``*Q0![0$`G@(`>`(QD``/X&`_L7`"8``#X`"?P9,F]W*<2!G;V]D_0$&]0D2,ADD$6_J0P'7&@"_)B!O9NP+%&$' -M*@^]&@-&,&(Q-Y,,`&`H!HD=`7('`*\!-$=)1"<%`@P#$G,`!0-%`R)B>18` -M,6EN9Q@!(7=H="X!MPX#3AL!W5$!YCQ0=&]O(&9,0@##!P#.%J%N>2!P65S(B!0)@TQ;L.R4`(A=&76 -M'P",'063:0'J``/]!@`)`P"'#@#]"#!'96[8``&\`Q,H<2TP(2D@4#L!RQT" -M%@$`1!$!0@`!Z!^R:7,@;&]N9RUS=&%U*C]B=6<*`0X'1`<*"@$`E@<28``?%!@&>``5/`Q%""5P$\10" -MI`(#ODCQ"SH@7T585%)!0U1?4T5#55)%7TY/1$]41$]4E@$`[AL,(0!Q4UE- -M3$E.2XHA-&5S94\``>D-`*M%`;XI`G0&$2Q%``!5%P$Y+B!B9=X!4"!D;W=N -M$PX'7@$@=V@R`0$E``,1"`%/`"%B>4$```A9AAQ``(P$$VQ4-MQ\!&@$`)1H` -MC`(#Y14`\C(!B6<#C&D!0!`"M!4#Q@,`HS0!HA@$9P$!1P`A87+;$2`H:J`2 -M(&9E#1$%'@L##1$$40`@9&6>"1!BH04!%#6]U0P`$2AH""6@2*5=``)L` -M86]V97)R:4(1`'8*06%M92^;,#`M=&^T5!`O.QMB;&]O:W5P'`$3*$E]"M4! -M$6$63@&92T)86%@H@@M29V5T9W(/`%!B;&]A=!P%`*(!+S`YDP(#%V$;!0`H -M``4G``3)`0-^!@3"`0>"$Q`[$@$!VAL`H!X#408!"!T`?$,0;]T^`(0"`"T% -M`C(N`215!HMW`FH)`2M:`]`&$%,B-5!F96%T==\(`O87$&Y[`07*.P"I!@'# -M'@>7`P)'%0%R`0)R`%%I;G9O;-0!!/,!`&$+```"(&]FSQ'B(&]V97)H875L('=I;&S")@&X+P,Q-@*D -M"P%^``**+@9'`0=\>`+9$`#/`@+N&PK=#@C4``+-``)')@&<.P-W!P`<)1`H -M]C@$OTH`L00!@P$`?0(C;V8,)Q!F/1,+B0``RQ\071H -M-`L!8@,`K`,!K`(">``"NQX&F@``V`D+ZP`'EQ<`V@4"@0$`&QLP`WE3@'.'@(:#P.8)1$V[@@0(.MK`7TG$#L&`!%L32D` -M_P4@;VQ/$!)H(R@"V0`!1PH`7P`!B`$`]@<0)Z<6$7)5#S!K967I<0&O)U!L -M92!U<$4'`&,T`CP``'8((&]NRRM"3$1%4G8`HE-534U!4DE%4PK]$`*M!0]D -M`P`:,2$!`R$C$#99#@B9)0!6%R!N9&\!$G390P6(#PF6(S(@ -M``7\`1!)N"8Q<&]RK00+9DH`HV50=&EL;"TP!PQ?-0!B``#E!0X.`1AS(VD! -MV!-\+6]N;'DN*7P`8%)E;W)G81YA$&1M6P)-`0#;!5!P86-K89=+!P)X`-@! -M$&6X"D`N9WH*S&H`:A,!AP0!BAL2<_@4!_8$`.L%`M\,`H@X`W,S`,\!!(X% -M`GL6%#I[!P%2*@"2(0$!40$_.03W!A(LOB``>0`W4&%X^@$!7AP"%G\1+OY- -M`@`;&S7:&0&^`0/V`02U$0E'3P`^#@1=&0`?"P9?&0"[!0!&$P*V!`(?$@!S -M#024!`KI2@)D``+D2@"N```\%%!A@8"\PH5-947`)5*0&5T96-\""1A=*4= -M`:E*`5<5`=@$`JLG`"P3`W(9!<`!"WXZ`0T2`/0``HD``_`%`1`.`F8"`*\` -M$E>/6P")>Q,@P"229VYU=VEN,S(N-H*A9F]R9V4N;F5T+P4>`_H.`2\"`U8$ -ME%II<"]::7`V-.X#"5$!86X@3F5L<\<;02U,+RWI`P#V%P$K$@O``P-P`P*M -M#2HU.C$"`U\&`55%`%X#`2D/$&5>"1%YW1$`/0($[D,Q@.\.@:Y -M`P!Y``,\`?,.>'-N:6PN86YT8F5A:,2$#32`2%N -M>2LJ$"UW"`#%/2%L92\"`=01`$@Y`58#`1M2`U8`(&%L)0X`'0$!U1\#[!8! -M`!H%,3L$&9I;&4``0!+X3`P,#8T-"``,#`P-S8U"``B,#(0`"(R -M,`$`_P<@,3(S-3,U-3,U,3(@,#$R,#(S`"`PEP!+`@(`KW5S=&%R`#`P8W4' -M`0M22T`5RH@8V%T:0`K871H`&!S:6UP;&5H`@6U`$!T;V]L -M,P$`0``#`@!R>F-A="P@8@<`$G@'``!)`4!S=6-H)P!0*B!E>&%)`$!S.B!3 -M,@-46]U(&UA>2!F:6YDT`(Q9G5L+P(&10!1 -M+VUI;FF%`1%AXP%186-T('-@`*$@9&5M;VYS=')AP0$`#@,G;V9>`0-)`#!C -M;VY#`O`".B`@5F%R:6]UP``"@+Q`F%U=&AO7-T96TZ"B`J(+@$=2XQ(&5X<&R# -M`@,O`P!"`0(A``2:`P,S``"(!`\T``L`(@`,-0`O870T``PH870S``8!!H`N -M,R!G:79E<]\&@&]V97)V:65W\P(`H``$NP4087$%,'=H;Y$"(RH@V0>%7W)E -M860N,RP0``#1!1UE$0!17V1I]!;!I;@IA(&YU;6)E`D09BP``;<&42H@1TY5=0$" -M-0(F("@$"P`:`$%L;VYG4`9B;F%M97,L$```!0L3(!$``&,`4G-P87)S?`(A -M`@@;W#+`\!A;"!2;V-KB,``!DT%``)"`$```I58W)E873/ -M``%U!`\&`0("J@,#OP,"O`(/'P,8,")R9:`-46-T960B1P,"3P#$+"!W:&EC -M:"!W:6QLB@`!5@`%R@%A(&5X8V5P0`4`N04$:0)1('1H871##C%I\+`OH#`*D"!B($`88!`MH` -M#Y8#!0'(`V$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0%!`);`0&)``]9`P`* -M%@,S5VAE`P((T0X"Y@5A`3AN97>U`P#P!`![``-S!`![``&'"0&C``)*#`!-$2)I -M7-S""IE9(H(`D<`<$DG=F4@870M#0",!S!T;R`A$+)M -M:7IE('-T871I8U((07!O;&PV$E$N("!)9O4(061O;B<<$Y!E>'!L:6-I=&S9 -M"4!V;VMEO!(!ZP`!?PH#SA$@("C2$"4@8?L*`*D`("!AL@$!)Q`"+0`(S0`4 -M;Y4(<"DL(&ET('=P`$$@9V5T&1,!70H`I`0W($EN;@`W+"!IG@`!40$#FP`B -M96[)`07L#$7`U`-%A=&5V97(@8FQO8VMS\```[@2X'<70@ -M82!T:6U7`W%O@``S0)P82!S;V-K9687`CX#27=I4X.``P1$2(A`0!:""`L(E`(H"P@8V%P86)I;&D2%`8# -M`07Q``+S#P&W!`CV!0&7`8`@:6YD:79I9&P.`]L(`(4``#H2`D(``*P+`-$` -M`#8!(71OK`TP9&%TUP``!0X6.BX!`L@)`#T`$F'L`@#)"@$K`#-I;B`G`0"/ -M`C!A9&1T!`!,``CW#`&I"@,>#U%F:7)S=)("`*8!$6%P$A%O\0T`]@`6+G0` -M`]D#`J0#`',*`.$G;71R964G(&9O -M$E33SDV-C`3`%HW+5II<#D`-EA!4A$`Y0I7:&5N(&-R96%T:6YG -M&`#Q&2P@=&AE(')EFEPX0`Q:6]N%0!=8GII<#(6 -M``0'`4TO3%I7'0"Q;'IM82P@;'II<"P4`2EX>B,`P0I.;W1E7-T96TN("!4:&5R92P`@&YO(&1I'!L86EN:6YGR0`P:&]W^``"]0`'+``"*@$A3VZJ`!PL`P$`48!`-T!\@%E9"!A=71O;6%T:6-A;&QY1P"P22=V92!A='1E -M;7#7`>!T;R!M:6YI;6EZ92!S="L`L"!L:6YK('!O;&QUN`'A+B`@268@>6]U -M(&1O;B?L`0"V`/$":6-I=&QY(&EN=F]K92!A('#K`(!U;&%R(&9E85D"0"`H -MD`!RT`!.<#`R("`ID!<"DL(&ET('=P`/``(&=E="!P=6QL -M960@:6XN/@`G26YN`#``%1`0.;`")E;LD!!RT``#X`"W$`*&1E$0`# -MQ@(1+/```H``(FYEC@(`%@$`0`!B86=A:6YS1P*@8V]R7L#$7`U`-%A=&5V97(@8FQO8VMS\``0:%<%(6ETH0!!66]U -M717`F$@82!T:6U7 -M`W%O`+$@(&)S9'1AX`0!V``*4`0"A`P&3``)/!R)L>8<``J,!!H`%,7=A;H@`$'0V!`5%`0!@ -M`!!IA0(`C@%EB!$!GF-A="P@8@<`$G@'``!)`0"2 -M"0`G`%`J(&5X84D`0',Z(%,R`U1S;6%L;!4`!#X!`%(#(6%T'`@@;6'F!"!N -M9-`",69U;"\"!D4`$"]#"@&%`1%AG@I186-T('-@`)(@9&5M;VYS=')*#0`I -M!B=O9EX!`TD`,&-O;D,"\`(Z("!687)I;W5S(&ET96US(#,!`'T#0&UE(&(W -M`3)I0&";8"(FENU@0`I`H`ZP4$O0+P`DY% -M5U,@+2!H:6=H;&EG:'1S7`8PH($',+!0$^`0!U```7`@#Y!`%Q -M``%Q"@B7```\"3-Y+C--``#O!#)E(")K`P6K``$D`!0B"PM9(&-L87-$``$? -M"49N86QSG0`2!Q(M@@0U]!9!I;@IA -M(&YU;6+R#!=FD0<$.P''"@I9;W4@ -M`*%35E(T($%30TE)=`(!%``/,@`+$$)M$1%Y+@"Q("AB:6%T`/ -M"Q<`T$UI8W)O"T4``("`+D%!(D1`@L7`UH7`5$`!>D2,',@*%,*`30$`(0!`S,$`/0#8"P@ -M971C*>\+`OH#`&P$`&T``HT``9L!`MH`#\@#"F$B;F5W8R*;`P$S`"=S:+`` -M`1(`#T8#8P0%!`?.``]9`P`*%@,/9!K_____________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________XE!E=&%I;%H1``#U'G,@=&AE -M(")S=')U8W0@87)C:&EV95]E;G1R>2(@=71I;&ET>2!C;&%SP#S"2P@:6YC;'5D:6YG -M(&AA``"/`/0:("=D;V,G -M(&1I2!I;@IA(&YU;6)E6]U(#\!8"X*"D-U\!`DD` -M-%I)4%8#!$``P'5N8V]M<')EB,``!DT%``) -M"`&58V%N(&-R96%TSP`!=00/!@$"`J\!`[\#`KP"#Q\#&,$B!S>7-T96TN("!4 -M:&5R92P`(VYOX@<`@@(#WP@`DP3R`B!I;BUP;&%C92!M;V1I9FECK0CS`F]R -M(')A;F1O;2!A8V-E0`&@`3R`FES(&1EP`#P`!APD!HP!4(&]N;'D*`P`X"`"R``$>`P"F -M!`(,`B$@8C<)<7)E861A8FP`!D%W48!`-T!*F5DB@@"1P"P22=V92!A='1E;7",!^!T;R!M:6YI -M;6EZ92!S=+4(`E((4'!O;&QU(@=1+B`@26;U"$!D;VXGU@7L#$7`U`-%A=&5V97(@8FQO8VMS\``` -M[@2X'<70@82!T:6U7`P!K"S%M87#X`C!E;G21!@/0`@%1`T!G:79EY@$A=&\B -M``6A`&%T(&]N8V6%`"%/;I`#&V7#``+D`C)P@``P0&%82!S;V-K970^`TEW:7-HN@0!)@\# -M60\`0#`',*T2!S87ES+@I214%$3442!@9)$>$@8G5N9&QE+@H*475E<_H" -MH#\@($ES8$(&YDT`(Q9G5L -M+P(&10`0+T,*`84!$6&>"C1A8W1[$W!D96UO;G-T.14@;F<^``"`!094`@-) -M`#!C;VY#`F$Z("!687+N$V!I=&5M$0(8 -M`&!C;VYF:6=^"Q4M#``"1`"UM`Q$SM@L`$!20(&]V97)V:65W\P(`JP`%P`L`<04P=VAOD0(4*J0* -MA5]R96%D+C,L$``!^`@-$0!17V1I2#R`I!I;VYS+@H*5&B=`?("<"UL979E;"!D:7)E8W1O'2(`#!P=71>`H$@(F-M86ME(B0#:60@ -M=&]O;$T``E8!!NL#`2D!,2!I;DP!#VT!`3!A2!N965D?``Q;6%I]@$C97)<`05P`"1I;F0`\@,N:"YI -M;@H)+2!T96UP;&%T97-G`!%B-`(!9@$39;4`8`H*1W5I9/,`4"!$;V-UF04" -M@0$`Q0$R86QL=0`!MP&R'!L@P(#+P,`0@$" -M(0`$F@,#,P``B`0/-``+`"(`##4`+V%T-``,*&%T,P`&`0:`+C,@9VEV97/? -M!H!O=F5R=FEE=_,"`*``!+L%$&%Q!3!W:&^1`B,J("X'A5]R96%D+C,L$``` -MT04=91$`45]D:7-K%@`@;F30`0@^``,<``"9`!!V7P$"MP)A960@8V%LB0<0 -M<]0&06YC97.M`@"3``!U``%'``-"!FAE($%027.7`'-E;G1R>2XS30`"]P,2 -M(FL#!:L``20`4"(@=71II`59(&-L87-$``'O!49N86QSG0`P] -M!;!I;@IA(&YU;6)E`D09BP``;<&42H@1TY5=0$"-0(B -M("BK"0"Y`0`:`$%L;VYG4`9B;F%M97,L$`!3;&EN:R`1``!C`%)S<&%R'1E;J+``-J -M`0`9`]$J(%!/4TE8('5S=&%R6P`"$``R<&%X-`,"60<#>`('(0#`;V-T970M -M;W)I96YT%P0@<&E^"<8J(%-64C0@05-#24D4``)3``\R``5A0FEN87)Y+@#` -M("AB:6B,``!DT%``)"`$```I58W)E873/ -M``%U!`\&`0("J@,#OP,"O`(/'P,8,")R9:`-46-T960B1P,"3P#$+"!W:&EC -M:"!W:6QLB@`!5@`%R@%A(&5X8V5P0`4`N04$:0)1('1H871##C%I\+`OH#`*D"!B($`88!`MH` -M#Y8#!0'(`V$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0%!`);`0&)``]9`P`* -M%@,S5VAE`P(`?`4#U`(2<^8%87)E`3AN97>U`P#P!`![``.?`0![``&'"0&C``)*#`!- -M$2)IF4@ -M``%1`0.;`")E;LD!!RT``'P`"W$`*&1E$0`#Q@(1+/```H```(T.`)8!`!8! -M`$``,&%G82X.`?$)D6-OP,1<#4`T6%T979E$P$/`P*A%0"V`A!GJA40:2(3 -M`2(`!4H``.,3(6-EA0`A3VZ0`QMEPP`"Y`(R<')O.@$!A0%18W1L>2W,`))E -M9"!O=71P=73O`@!@!/$#;V)J96-T+7-T>6QE(&%P<')OR`,`^10"^@!0=&\@ -M:&$Y%D!U;'1IPQ,$J0`"`00`N0A5(&]P96Z>`!,@%1``:A``"@$`/06#;B!I -M=',@(D`\`!(BO0012!F4X.``P1$2(A`0!:""`L(E`(H"P@8V%P86)I -M;&D2%`8#`07Q``+S#P$_#@CV!0&7`8`@:6YD:79I9&P.`]L(`(4``#H2`D(` -M`*P+`-$``#8!(71OK`TP9&%TUP``!0X6.BX!`L@)`#T`$F'L`@#)"@$K`#-I -M;B`G`0"/`C!A9&1T!`!,``CW#`&I"@,>#U%F:7)S=)("`*8!$6%P$A%O\0T` -M]@`6+G0``]D#`J#B)A;N@"`*4'!C0*$"QC`$!D97-PH@``;`0!Y`,`7,N"B05 -M$6:X#06Y&0*A&$0N"@I1$19`/R`@2:T9(',_4@`4*I491G=W=RXX`$`N;W)G -MDP``2`$0:+@"`%<`0V]N9V]8!Q<@3`<@(&18%B!O<#P%"!D1!+H1`:P(`3<, -M`'$``#H`'VYD&O______________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________:E!I=F4@92@1``#Q$6YT7,@9&5T96-T960@ -M875T;VUA=&EC86QL>4<`L$DG=F4@871T96UP(@#@=&\@;6EN:6UI>F4@6]U(&1O;B=TJ```M@#Q`FEC:71L -M>2!I;G9O:V4@82!PZP#P#G5L87(@9F5A='5R92`H``%1`0.;`%IE;F%B;)L``#X`"W$`*&1E$0`#J@`1 -M+/```H``(FYE)@$`%@$`0`!Q86=A:6YS=,\!V6-O8`0U: -M`)%L:6)R87)I97/#`/$"5&AI3X`!8P``+$!\09P"!I;G1E7,N"E)%041-12X`!^@& -MX2!B=6YD;&4N"@I1=65S^@*@/R`@27-S=65S/U(`UBH@:'1T<#HO+W=W=RY, -M!T`N;W)GDP``2`$0:+@"@V9O0(1.FH` -M$B>7!9`G('!R;V=R86T6`G-A(&9U;&PME@AP9"`G=&%R)WX``P(`4W)E<&QA -M0@%`8G5I;($&`(H``V,``"H`9BH@8W!I;V,```X`"V0`(&1I:P4R96YT,`-# -M9F%C96H#`P(`,&5S`<``$D!`)()`"<` -M4"H@97AA20!`8$(&YDT`(Q -M9G5L+P(&10`0+T,*`84!$6$&"5%A8W0@`0-)`#!C;VY#`O`".B`@5F%R:6]UP``7P%Q875T:&]R<\`%`1\&`?("`DT' -M$`J(!E!T;W`M;`P$`W8%`#`'`4$`$&GD!@FV`B)I;M8$`'$+`.L%!+T"\`). -M15=3("T@:&EG:&QI9VAT=&%R+C54`0CQ!$%A8F]U4P41]!9!I;@IA(&YU;6+R#!=FD0<$.P''"@I9;W4@`D09@82`;<&42H@1TY5=0$"-0(F("@$"P`:`"-L;[P%`*T+(G,L -M$```!0L3(!$``&,`4G-P87)S?`(A`*%35E(T($%30TE)=`(!%``/,@`+$$)M$1%Y -M+@"Q("AB:6`@@;W#+`\!A;"!2;V-K[`@0]`5HW+5II<"8`V$UI8W)OFEP/@$@:6]/$WTJ(&)Z:7`R -M%@`$?`%-+TQ:5QT`HFQZ;6$L(&QZ:7`3`R]X>B,``!DT%``)"`$```H"G!`% -M.@$`=00/!@$"`J\!`[\#`KP"#Q\#&#`B0`&@`0I:7-N%")B98@%`$`$`5X!.&YE -M=[4#`/`$`/T"`Y\!`'L``8<)`,,7$F5*#`!-$2)I2!D971E8W1S(&%N9"!R96%D -MFEP/@$Q:6]N!0%=8GII<#(6``1D`4TO3%I7'0"B -M;'IM82P@;'II0`&EP"0:7,@9&5S:6=NH@9";R!B98@%`$`$`3`$.&YE=[4#`/`$ -M`'L``4,` -M4&EN9&5PJ@`B;G1_`!!R.P0`!``P=&EC0@4D;VZ!`02N`/``5VEK:2!E>'!L -M86EN:6YGB0`P:&]W^``!LP,09)8%`RP``BH!(4]N/P@<+`,!``0$,FUA='`` -M0&QW87E&`0#=`2IE9(H(`D<`L$DG=F4@871T96UPC`?@=&\@;6EN:6UI>F4@ -M2!I -M;G9O:V4@82!PZP`@=6R]"*!E871U``%1 -M`0.;`")E;LD!!RT``'P`"W$`*&1E$0`#J@`1+/```H``(FYEC@(`%@$`0`!Q -M86=A:6YS=,\!D6-OP,1<#4`T6%T979E`%`@(&)S9",' -M(75SO`$`/06#;B!I=',@(D#E`!(BO01&"2`L(E`(<"P@8V%P86)!``'V`@)F!A%E50(!\0!A92!!4$ES -MMP0(]@4!EP&Q(&EN9&EV:61U86QH!1%I0@@`>P`28D(``$X&`-$``#8!(71O -MFPDP9&%TUP!6=7)C93HN`0+("0#"`!)A[`(`R0H!*P`S:6X@)P$`E0LS861D -MC@(88?<,`=<'(6]U]P119FER0"0:7,@97-P96-I;@0!T`$"J@$`.@@P.B`BDPH.V@T3(KD"`-X. -M(F%NZ`(`I0<`$0,"P040+&,`0&1E%E -MF-%#A)B!P`2>`<``$D!`)()`"<`4"H@97AA20!`8$(&YDT`(Q9G5L+P(&10`0+T,* -M`84!$6&>"E%A8W0@'2(`")P==8-(")C-`81(B0#`#@,*6]L30`"5@$&ZP,!*0$` -M%@D`C@$/;0$!`+`,$'4]$P':`31E"B>P`"-E)ZT``#H/,"`J(),``$X`\``N -M86TL(&%C;&]C86PN;30)#0/M`#`N86/_```"`!`MH@(`GP`$J```V0X(H@02 -M+!H.`-<+`%D+$'G*!0'V`2-EH($',+!0$^`0!U```7`@#Y!`%Q``%Q"@B7```\ -M"3!Y+C/T%#!A:6SO!#)E(")K`P6K``$D`!0B"PM9(&-L87-$``$?"49N86QS -MG0`2!Q(M@@0U=H+`#L'`2,)#V0:________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M__________________________________]I4'(*("`@/A$``!(@`0!R>F-A -M="P@8@<`$G@'`/0386YD('-U8V@*("`@*B!E>&%M<&QE'2( -M`#%P=70I`/D#(F-M86ME(B!B=6EL9"!T;V]L30`"5@$&-0$!*0$Q(&EN3`$/ -M;0$!,&%R91`"$F3:`35E"B>\`!,GK0`2.M0``),``$X`]0$N86TL(&%C;&]C -M86PN;30LX0!`92YA8RL```(`$BU4`"1T;Z@``"`!,&1IM`_`$,R!G:79E2XS!`,!JP(2(FL#!:L``20`Z2(@=71I;&ET>2!C;&%S1`"6:6YT97)N86QS -MG0`P`?$#+@H*66]U('-H;W5L9"!A;'-O(@(!3``Q8V]P=@8R8V]M6P%# -M:6X@(KT",BYH(JD`@&AE"G-O=7)C+P`19'4!`!0`!.D&!30'`"P%-&UO<$",&5C=)D#$635 -M``,<`@7"!A!F+``!MP91*B!'3E5U`0*Z`28@*+D!`!H`06QO;F=5`F)N86UE -M'1E -M;J+``-J`0`9`]$J(%!/4TE8('5S=&%R6P`" -M$``P<&%X20,B97)9!P-X`@FEP,A8`!'P!32],6E<=`*)L>FUA+"!L -M>FEP$P,O>'HC```9-!0`"0@!```*56-R96%TSP`!=00/!@$"`JH#`[\#`KP" -M#Q\#&#`B&-E<$`%`+D%!&D"`A4,<7)E<75IP`#GP$`>P`!APD!HP`"2@P#"@,`.`@`L@`Q=&AA+PD#*P`A -M(&(W"0!J"#%A8FP`!@","@$,``$L"P($`0!H``([`$)E86-H/0$A=F5S`Q-Y -M0P!0:6YD97"J`"5N="(!`!@)``\/$&-"!1)O;`T&-0I4(%=I:VE2##!I;F?) -M`#!H;W=1#P&S`Q=DE@H"*@$A3VX_"`#W#`)@!@,#`03-``%P`$!L=V%Y1@$` -MW0$J962*"`)'`'!))W9E(&%T+0T`C`<`P0^0:6YI;6EZ92!S#@T28U((07!O -M;&R4#5$N("!)9O4(4&1O;B=TJ`"097AP;&EC:71LV0EB=F]K92!A^@\18W\* -M,69E830+$"C2$`!U#`@<`A!A00`!)Q`"+0`(S0`4;_D(<"DL(&ET('=P`'$@ -M9V5T('!UG`T0:7H+1R`@26YN`#``%1`0.;`")E;LD!!RT``#X`"W$` -M*&1E$0`#J@`1+/```H```(T.`)8!`!8!`$``(&%G`PX"4`.18V]R0`P&@`A!MV`$32X'<70@82!T:6U7 -M`W%O8!(71O(@`%2@!2="!O;F-\ -M$B)/;AP."\,``N0",G!R;SH!`84!46-T;'DMS`"2960@;W5T<'5T[P(`8`3Q -M`V]B:F5C="US='EL92!A<'!R;\@#`$,2`OH`X'1O(&AA=F4@;75L=&EP)0`` -M(040=A(#0')E86VY"%4@;W!E;IX`$R`5$`!J$``*`0`]!8-N(&ETP"`,D*`2L`,VEN -M("#U%F:7)S=)("`*8!$6%P$A%O61$`]@`6 -M+G0``]D#`J60!`,P` -M`*,!!H`%,7=A;G\%$G0=#P-%`0!@```:!!!TC@0#`',*%E7,@<')O9'5C97,@8V]R6QE(&%P<')O86-H(&%L;&]W^@#@=&\@:&%V92!M=6QT:7`E -M``.I`'%S=')E86USSP`U<&5NG@#S#2`@8G-D=&%R('5S97,@=&AI2!D8737`%9UP",B!O9BL`,VEN(""!I;G1E7,N"E)%041-12X``$0$!&T!T6)U;F1L92X*"E%U97/Z`J`_("!)!D!G`<``$D!0'-U8V@G`%`J(&5X84D`0',Z(%,R`U1S -M;6%L;!4`!#X!`%(#(6%T(`8@;6'F!"!N9-`",69U;"\"!D4`42]M:6YIA0$1 -M8>,!46%C="!S8`"P(&1E;6]N0&";8"(FEN^`0B:6_A!@2]`O`"3D574R`M(&AI9VAL:6=H -M='-M``,D!`"3``!.`/4! -M+F%M+"!A8VQO8V%L+FTT+.$`0&4N86/_```"`!`MH@(`GP`$J``,H@2R+"!O -M;FQY(&YE961\`#%M86GV`2-E7-T96TZ -MIPH"N`1U+C$@97AP;(,"`R\#`$(!`B$`!)H#`S,``(@$#S0`"P`B``PU`"]A -M=#0`#"AA=#,`!@$&(2XSM@L0<]\&@&]V97)V:65W\P(`H``%G@L`<04P=VAO -MD0(4*J0*A5]R96%D+C,L$``!^`@-$0!17V1I``'<`%0P#'`(%>`D09BP``;<&42H@1TY5=0$"-0(F("@$"P`:`$%L;VYG -M50(`K0LB+``-J`0`9`]$J(%!/4TE8('5S=&%R6P`"$``/ -MB@P#!R$`P&]C=&5T+6]R:65N=!<$,7!I;QX`IE-64C0@05-#24D4``)3``\R -M``5A0FEN87)Y+@#`("AB:6FEP/@$Q:6]N -M&`%=8GII<#(6``1\`4TO3%I7'0"B;'IM82P@;'IID2,',@*'T'`30$`(0!`S,$`/0#8"P@971C*>\+`OH#`*D"`&@1 -M`HT``88!`MH`#Y8#!0'(`V$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0%!`?. -M``]9`P`*%@,S5VAE`P(`-0<#U`(2<^8%87)E'!L:6-I=&S9"6)V;VME(&'Z#Q%C?PH#SA$@ -M("C2$`!U#`@<`A!AL@$!)Q`"+0`(S0`4;W,$<"DL(&ET('=P`%`@9V5T(-(2 -M`5T*`*0$-R!);FX`!287`9X``5$!`YL`(F5NR0$'+0``?``+<0`H9&41``.J -M`!$L6!$"@```C0X`E@$`%@$`0``P86=A\P\!7PJ18V]R2!O9B!T:&4@9F]L;&]W:6YG(&)E9F]R92!E=F%L -M=6%T$@``(`#Q#6%R8VAI=F4Z"B`@*B!U=65N8V]D960@9FEL97,4``$*`/$" -M('=I=&@@4E!-('=R87!P97(;`/$!9WII<"!C;VUP'HC```9-!0`"0@!E6-A;B!C -M'1E;DT!L7,@*&9O$E33SDV-C`3`%HW+5II<#D`-EA!4A$`0PI7:&4#`@#8`@1U -M`1$L`@-AT!X'-Y0`&EP#R`FES(&1EP`!S@`4=E@#$G.C`%0@;VYL>0H#0&UE;G2R``$>`P"F!`)G`S`@ -M8F5``(!R96%D86)L9:(`07=R:70,`!!A#`$"!`$!1`0!.P!"96%C:#T!(79E -ME@(3>4,`4&EN9&5PJ@`B;G1_`!!R.P0`!``P=&EC0@4D;VZ!`02N`/``5VEK -M:2!E>'!L86EN:6YGB0`P:&]W^``"]0``E@4#+``"*@$A3VZJ`!PL`P$#V0(" -M<`!`;'=A>48!`-T!\@%E9"!A=71O;6%T:6-A;&QY1P"P22=V92!A='1E;7#$ -M`^!T;R!M:6YI;6EZ92!S="L`L"!L:6YK('!O;&QUN`'A+B`@268@>6]U(&1O -M;B?L`0"V`/$":6-I=&QY(&EN=F]K92!A('#K`"!U;#<$H&5A='5R92`HD`!RT`!^\%`(`!`ID!<"DL(&ET('=P`.`@9V5T('!U;&QE9"!I -M;J0$-R!);FX`-RP@:9X``5$!`YL`(F5NR0$'+0``?``+<0`H9&41``/&`A$L -M\``"@``B;F6.`@`6`0!``&)A9V%I;G-'`J!C;W)R97-P;VYD)P0(20`-6@`" -M>P,Q:65SPP`!;P,!;P=1P,1<#4`T6%T979E`%`@(&)S9",'(75SO`$`/06#;B!I=',@(D#E`!(BO01&"2`L(E`(<"P@8V%P86)!``'V -M`@)F!A%E50(!\0!A92!!4$ESMP0(]@4!EP&Q(&EN9&EV:61U86QH!1%IWP<` -M>P`28D(``"P$`-$``#8!(71OFPDP9&%TUP!6=7)C93HN`0+("0#"`!)A[`(` -MR0H!*P`S:6X@)P$`3P@S861DC@(18?P(!*H!`'D&(6]U]P119FER0#`',*T"!S87ES+@I214%$346[!@?H!N$@8G5N9&QE+@H*475E<_H" -MH#\@($ES8N9V]O9VQE+F-O -M;2]P+VH`$2\Z`"!S+VD``),``6<`47-U8FUI9P!P96YH86YC9;L``*8`!C@` -M@RP@<&QE87-E+```.P``!`,`2P7!1`GH@1`9W)A;18"F-%#A)B -M!P`2>`<``$D!`)()`"<`4"H@97AA20!`8$(&YDT`(Q9G5L+P(&10`0+T,*`84!$6&>"E%A8W0@'2(`")P==8- -M(")C-`81(B0#`#@,*6]L30`"5@$&ZP,!*0$`%@D`C@$/;0$!`+`,('5SW0H` -MV@$T90HGL``C92>M``-G`0"3``!.`/``+F%M+"!A8VQO8V%L+FTT"0T#[0`P -M+F%C%P$``@`0+:("`)\`!*@``-D."*($$BP:#@#7"P)\`#%M86GV`2-EPH"MP(`A1(A86R)!T!S97%UZ@@0!Q(M@@0U``&I`5"`"X!!,B!0XR+F@BJ0`R:&4*7PP0(+`) -M`/H``!0`!.D&`W((`G\"$&T:%P/[`$(N("!0B@FR;&5T('5S"FMN;W<0`0&X -M#&!E2X`H"`H8FEG+65N9&GS!(-R(&QI='1L91$``L<`!%\6D4-$+5)/ -M32!I;;<"$"@X#C`@;W#+`\!A;"!2;V-K%V,/"Q<`T$UI8W)O2!A0A$``/4R2!T:&4*)V-O;F9I9W5R92<@`""(&EN'!L86EN@`/`#;&EB2!A2XS30`"=`%U(G-T2!C;&%S1`"6:6YT97)N -M86QSG0!@2QN``5H`W!U=&]M871I_P(0>68!,&5C=)D#$635``,<`E!O -M;&QO=Y,!$&8L`!!S4`51*B!'3E5U`0(U`B8@*+D!`!H`06QO;F=5`F)N86UE -M`*%3 -M5E(T($%30TE)=`(!%``"4P`/,@`%84)I;F%R>2X`H"`H8FEG+65N9&GS!(-R -M(&QI='1L91$``OH`\0))4T\Y-C8P($-$+5)/32!I;;<"@"AW:71H(&]P^@7` -M86P@4F]C:W)I9&=E10!B2F]L:65T*0$![P$"20`T6DE05@,$0`"0=6YC;VUP -M[`@0]`5HW+5II<"8`V$UI8W)O`,(KP)@:&%N9&QENP(0>;<#`+8$ -M!K@",&)E9DH#<&5V86QU873*`@`@``.9`P+/`A!U]@40;W$"`+8"`D,"`0H` -M$2"#`:)24$T@=W)A<'!E3@)%9WII<#X!,6EO;A@!76)Z:7`R%@`$?`%-+TQ: -M5QT`HFQZ;6$L(&QZ:7`3`R]X>B,``!DT%``)"`&58V%N(&-R96%TSP`!=00/ -M!@$"`J\!`[\#`KP"#Q\#&#`B&-E<$`%`+D%!&D"L"!T:&%T(')E<75IE@4G87C*`B`@ -M*'T'`30$`(0!`S,$`/0#<2P@971C*2YO`0#Z`P"I`@8B!`$7``+:``^6`P4! -MR`-A(FYE=V,BFP,!,P`G?P(-F5A;;4%`A$+@"X@(%1H97)E+``C;F_B!P""`@/?"`"3!/("(&EN+7!L -M86-E(&UO9&EF:6.M"/,";W(@U`P#P!`![``.?`0![``&'"0&C``)*#`,*`P`X -M"`"R``$>`P"F!`(,`B$@8C<)<7)E861A8FP`!@","@$,``$L"P($`0!H``([ -M`$)E86-H/0$A=F5S`Q-Y0P!0:6YD97"J`"5N="(!`!@)4&%R=&EC0@4D;VZ! -M`02N`$17:6MI4@PP:6YGR0`P:&]WFPP"I@<'E@H"*@$A3VX_"`#W#`)X!@$" -M"B-N9/@``8@)8V%L=V%YD`!RT`!"T' -M`,T`%&_Y"'`I+"!I="!W<`!Q(&=E="!P=9P-(&ENI`0W($EN;@`W+"!IG@`( -MFP`B96[)`02UV```S#`#W"!%IAP8`A`!P96YV:7)O;M<",7,@ -M=Y`#`:`"$&W8`1-R6@,%,`(`6P`"?P`1>7L#$7`U`-%A=&5V97(@8FQO8VMS -M\```[@@``S0*%82!S;V-K970^`TEW:7-HN@0!)@\# -M60\`4X.475S92`B(0$`6@@@+")0"+$L(&-A<&%B -M:6QI=/8"!`,!!?$``O,/`;<$"/8%`9P"`,D*`2L` -M,VEN("#U%F:7)S=)("`*8!$6%P$A%O61$` -M]@`6+G0``]D#`J60! -M`,P``*,!!H`%,7=A;G\%$G0=#P$V`@%;`P$:!!!TC@0#`',* -MT2!S87ES+@I214%$3442!@9)$>$@8G5N9&QE+@H*475E<_H"H#\@($ESF-%#A)B!P`2>`<``$D!`)()`"<`02H@97@;$T!S.B!3,@-4X/\`4@*B!.15=3("T@:&EG:&QI9VAT<]P`,')E8]D4`C$%`Z`" -MDD-/4%E)3D<@+0P%`$(4`,H'(F1OGP``AP4`S@"T*B!)3E-404Q,("V2&`&/ -M!`$-``#Y%@"_``(I``-`!1(M1!D`E0`"&``%=QDE("T,``)$``*W&54L('-E -M96<``"@%`JT7`F,(@2H@0TUA:V5,U`0Q='ATB``A<'5G$#`@(F,T!A0BO!DY -M;V]L30`"5@$&-0$`E```L`H!C@$/;0$!`*(&#V0:____________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________________________________________]G4'1O(&%L+1$` -M`/`@;&]W(&EN9&EV:61U86P@96YT2!A;F0@861D(&ET3`#P!2!T87(@87)C -M:&EV92!W:71H;W5T00!19FER2!F:6QE+G0` -M0F%L8<`\01S;V-K970N("!)9B!Y;W4@=V%NB``2=%T`$B\]``,?`0`S`%!D -M:7-K+$X`\!!R92!A0#P*FES(&5S<&5C:6%L;'D@96%S>2X*"B`J($YO=&4Z(")P87@@:6YT97)C -M:&%N9V4@9F]R;6%T(B!I<^```#,``.(`<7AT96YD960X`0(B`!`L8P!`9&5S -M<-\`0'=H8726`/`#(&YA;64@F-A="P@8@<`$G@'``!)`4!S=6-H)P!0*B!E>&%)`$!S.B!3,@-4`0-)`#!C;VY#`O`".B`@5F%R -M:6]UP``7P%Q875T:&]R<\`%`1\&`?("``$%4"X*"E1HG0$P<"UL#`0#=@4` -M"08!00`0:20%";8"(FENU@0Q:6]NZP4$O0+P`DY%5U,@+2!H:6=H;&EG:'1S -M7`8PM``,D!`"3``!. -M`/4!+F%M+"!A8VQO8V%L+FTT+.$`0&4N86/_```"`!`MH@(`GP`$J``,H@2R -M+"!O;FQY(&YE961\`#%M86GV`2-E7-T -M96TZ<`<"N`1U+C$@97AP;(,"`R\#`$(!`B$`!)H#`S,``(@$#S0`"P`B``PU -M`"]A=#0`#"AA=#,`!@$&@"XS(&=I=F5SWP:`;W9EP$2+8($-7,N-:H(`)X%$67[`P#R`(!M871S -M('-U<'\(!&,"!98!`$P```H"D"XU+"!M=')E90D``&\`7G1A`D09BP``;<&42H@1TY5 -M=0$"-0(F("@$"P`:`$%L;VYG50(`K0LB+``-J`0`9`]$J -M(%!/4TE8('5S=&%R6P`"$``/B@P#!R$`P&]C=&5T+6]R:65N=!<$('!IZ`S& -M*B!35E(T($%30TE)%``"4P`/,@`%84)I;F%R>2X`P"`H8FEG+65N9&EA;J(! -M8VQI='1L91$``OH`\0))4T\Y-C8P($-$+5)/32!I;;<"$"@X#C`@;W#+`\!A -M;"!2;V-K[`@0]`5HW+5II<"8`V$UI8W)OFEP/@$Q:6]N&`%=8GII<#(6``1\`4TO3%I7'0"B;'IM -M82P@;'II\+`OH#`*D"`&@1`HT``88!`MH`#Y8#!0'(`V$B;F5W -M8R*;`P$S`"=S:+```1(`#T8#8P0%!`?.``]9`P`*%@,S5VAE`P(`&@T#U`(2 -M<^8%87)E4,`4&EN9&5PJ@`E;G0B`0!$#0`/#Q!C0@42;VP-!C4*5"!7:6MI4@P# -M#!,P:&]W^``"]0``K0$#V@`"*@$A3VX_"`#W#`)@!@#S#@!0!@/-``%P`%-L -M=V%Y'!L:6-I#16":6YV;VME(&'Z#Q%C?PH# -MSA$@("C2$"4@8?L*`*$!("!AL@$!)Q`"+0`(S0`4;W,$<"DL(&ET('=P`%`@ -M9V5T(-(2`5T*`*0$-R!);FX`,BP@:8(5`9X``5$!`YL`(F5NR0$'+0``?``+ -M<0`H9&41``/&`A$LY0D"@```C0X`E@$`%@$`0``P86=A\P\!7PJ18V]R"(&5N=FER;VX/"Q%WD`,!H`(0;=@!$W): -M`P4P`@!;``)_`!%Y>P,1<#4`8F%T979E2!O9B<`H69O;&QO -M=VEN9SJ&`(%U=65N8V]D90T`\0%G>FEP(&-O;7!R97-S:6]N%0!=8GII<#(6 -M``0F`$TO3%I7'0"Q;'IM82P@;'II<"P4`2EX>B,`P0I.;W1E7-T96TN("!4:&5R92P`@&YO(&1IF4@2!I;G9O:V4@82!PZP"`=6QA2!FP`28D(``"P$`-$``#8!(71O>`0#\`)N86UE('-A -M>7,N"E)%041-15``!^@&X2!B=6YD;&4N"@I1=65S^@*@/R`@27-S=65S/U(` -MURH@:'1T<#HO+W=W=RX@!S!O3``!(`1!HN`*#9F]R(&]N9V]8!Q@@9`!P -M9&5V96QO<#P%<2P@:6YC;'6]!4!D;V-U%``!K`@!3@D`<0``.@`A;FM=`0!= -M``9S`%`@;6%I;`<"0FQIF-A="P@8@<`$G@' -M``!)`0"2"0`G`%`J(&5X84D`0',Z(%,R`U1S;6%L;!4`!#X!`%(#(6%T'`@@ -M;6'F!"!N9-`",69U;"\"!D4`$"]#"@&%`1%AG@I186-T('-@`)(@9&5M;VYS -M=')*#0`I!B=O9EX!`TD`,&-O;D,"\`(Z("!687)I;W5S(&ET96US(#,!`'T# -M0&UE(&(W`3)I0&";8"(FENU@0`Q@P`ZP4$ -MO0+P`DY%5U,@+2!H:6=H;&EG:'1S7`8PP -M`"-E)ZT``R0$`),``$X`\``N86TL(&%C;&]C86PN;30)#0/M`#`N86,7`0`" -M`!`MH@(`GP`$J```V0X(H@02+!H.`-<+`GP`,6UA:?8!(V5RK@$%<``D:6YD -M`($N:"YI;@H)+?0'(&QA5@\$NP`%A0`#M0!@"@I'=6ED\P`H($14!@32`0)U -M``&W`0)3#Q`Z&@D"N`0A+C'!#`!A#`$W`0,O`P`+``(A``2:`P,S``"(!`\T -M``L`(@`,-0`O870T``PH870S``8!!B$N,[8+$'-E"H!O=F5R=FEE=_,"`*`` -M!<`+`'$%4'=H;VQEI``#1`6$7W)E860N,RRT"A%?^`@-$0!17V1IH($',+!0$^`0!U```7`@#Y -M!`%Q``%Q"@B7```\"3-Y+C--``#O!#)E(")K`P6K``$D`!0B"PM9(&-L87-$ -M``$?"49N86QSG0`2!Q(M@@0U]!9!I -M;@IA(&YU;6+R#!=FD0<$.P''"@I9;W4@2X`L2`H8FEG+65N9&EA -MU!%C;&ET=&QE$0`"^@`$7Q:10T0M4D]-(&EMMP(0*#@.,"!O<,L#P&%L(%)O -M8VMR:61G9>\!`DD`-%I)4'4$!$``('5N,0L`)18`UA!@ -MC2H`0#E%PD( -M`0``"@*<$`5+`0!U!`\&`0("@P$#OP,"O`(/'P,8,")R9:`-`!`6$2)'`P)/ -M`,(L('=H:6-H('=I;&SK&`!P"``9!`-?`4!S(&5X+10``@(`N04$B1$""Q<# -M6A`'!L:6)R87)Y3`#08W!I;RXU+"!M=')E90D``&\`5'1AP#S -M"2P@:6YC;'5D:6YG(&AA -M``"/`/0:("=D;V,G(&1I2!I;@IA(&YU;6)E6]U(#\!8"X*"D-UFEP,A8`!'P!32],6E<=`*)L>FUA+"!L>FEP -M$P,O>'HC```9-!0`"0@!E6-A;B!C,H"4B`H9F]R-`0`A`$#,P0` -M]`-Q+"!E=&,I+F\!`/H#`*D"!B($`1<``MH`#Y8#!0'(`V$B;F5W8R*;`P$S -M`"=S:+```1(`#T8#8P0%!`);`0&)``]9`P`*%@,S5VAE`P(`V`(#U`(2<^8% -M87)E'!L86EN:6YGR0`P:&]W^``"I@<`K0$#+``" -M*@$A3VX4"1PL`P$#^``!B`E086QW87E&`0#=`2IE9(H(`D<`L$DG=F4@871T -M96UPC`?@=&\@;6EN:6UI>F4@D`!RT`!"T'`,\*%&_Y"'`I+"!I="!W<`""(&=E="!P=6S["@"D!#<@ -M26YN`#``B;`")E;LD!!RT``'P`"W$`*&1E$0`#Q@(1+/```H``(FYE -MC@(`%@$`0`!B86=A:6YS1P*18V]R0`P&@`A!MV`$38!(71O(@`%H0!A="!O;F-EA0`A3VZ0`QMEPP`"Y`(R<')O.@$! -MA0%18W1L>2W,``"."5)U='!U=.\"`&`$\0-O8FIE8W0M60!`,P``*,!!H`%,7=A;G\%$G0=#P$V`@%;`P!C -M#``S`$%D:7-K+`,`L1`0#B)A;N@"`*4'`!$# -M`EH'$"QC`$!D97-PH@``;`0!Y`,`7,N"E)%041-11(&!DD1X2!B -M=6YD;&4N"@I1=65S^@*@/R`@27-S=65S/U(`UBH@:'1T<#HO+W=W=RXX`$`N -M;W)GDP``2`$0:+@"$&:Q#S-N9V]8!Q<@3`>`(&1E=F5L;W`\!0@9$02Z$0&L -M"`$W#`!Q```Z`"%N:UT!`%T`!G,`4"!M86EL!P(P;&ESOQ`!G0`05)D!`.41 -M`.%E8$(&YDT`(Q9G5L+P(&10`0+T,*`84!$6&>"C1A8W1[$W!D96UO;G-T -M.14@;F<^``"`!094`@-)`#!C;VY#`F$Z("!687+N$V!I=&5M$0(8`&!C;VYF:6>R%A4M#``"1`"UM`Q$SM@L`$!20(&]V97)V:65W\P(`JP`% -MP`L`<04P=VAOD0(4*J0*A5]R96%D+C,L$``!^`@-$0!17V1I2#R`I!I;VYS+@H*5&B=`?("<"UL979E -M;"!D:7)E8W1O'2(`#!P=71>`H$@ -M(F-M86ME(B0#:60@=&]O;$T``E8!!NL#`2D!,2!I;DP!#VT!`3!A2!N965D?``Q;6%I]@$C97)<`05P -M`"1I;F0`\@,N:"YI;@H)+2!T96UP;&%T97-G`!%B-`(!9@$39;4`8`H*1W5I -M9/,`4"!$;V-UF04"@0$`Q0$R86QL=0`!MP&R'!L@P(#+P,`0@$"(0`$F@,#,P``B`0/-``+`"(`##4`+V%T-``,*&%T,P`& -M`0:`+C,@9VEV97/?!H!O=F5R=FEE=_,"`*``!+L%$&%Q!3!W:&^1`B,J(,0& -MA5]R96%D+C,L$```T04=91$`45]D:7-K%@`@;F30`0@^``,<``"9`!!V7P$" -MMP)P960@8V%L;!(&$'/4!D%N8V5SK0(`DP``=0`!1P`#0@9H92!!4$ESEP!S -M96YTP$2+8($4W,N-2!D5@("KP``&0,`\@"`;6%T#0#`ED' -M`W@"!R$`P&]C=&5T+6]R:65N=!<$('!I?@G&*B!35E(T($%30TE)%``"4P`/ -M,@`%84)I;F%R>2X`P"`H8FEG+65N9&EA;J(!8VQI='1L91$``OH`\0))4T\Y -M-C8P($-$+5)/32!I;;<"$2AX""!O<,L#P&%L(%)O8VMR:61G944`8DIO;&EE -M="D!`>\!`DD`-%I)4%8#!$``('5N,0LPFEP,A8`!'P!32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9-!0` -M"0@!```*56-R96%TSP`!=00/!@$"`JH#`[\#`KP"#Q\#&#`B&-E<$`%`+D%!&D"42!T -M:&%T0PXQ:7)E40`!\P,!R@(@("@6!0$T!`"$`0,S!`#T`V`L(&5T8RGO"P+Z -M`P"I`@8B!`&&`0+:``^6`P4!R`-A(FYE=V,BFP,!,P`GD#`*4#(71EVP@P -M.@H*'Q$R:&ESD0]P:&5A=FEL>?P(-F5A;;4%`A$+<"X@(%1H97(T$3,@;F_B -M!P""`@/?"`"3!$$@:6XMMP^"(&UO9&EF:6-D"_``;W(@0`&EP``L!!397-I9VXE#!)EB`4`0`0!7@$X;F5WM0,`\`0`>P`#GP$` -M>P`!APD!HP`"2@P`31$B:7*"$1!I>0<280D!`@P"(2!B-PD`:@@Q86)L``8` -M_0H!#``!+`L"U!``:``".P!"96%C:#T!(79E4,`4&EN9&5PJ@`E;G0B -M`0`8"0`/#Q!C0@42;VP-!C4*5"!7:6MI4@PP:6YGR0`P:&]W40\!LP,09$X( -M`]H``BH!(4]N/P@`]PP"8`8`TQ$`4`8#S0`!<`!3;'=A>7-S""IE9(H(`D<` -M<$DG=F4@870M#0",!S!T;R`A$+)M:7IE('-T871I8U((07!O;&PV$E$N("!) -M9O4(061O;B<<$Y!E>'!L:6-I=&S9"4!V;VMEO!(!ZP`!?PH#SA$@("C2$"4@ -M8?L*`*$!("!AZ0`!)Q`"+0`(S0`4;_D(<"DL(&ET('=P`$$@9V5T&1,!70H` -MI`0W($EN;@`W+"!IG@`!40$#FP`B96[)`07L#$7`U -M`-%A=&5V97(@8FQO8VMS\```[@2X'<70@82!T:6U7`W%O8!(71O(@`%2@``XQ,A8V6%`"%/;I`#&V7#``+D`C)P`!,@ -M%1``:A``"@$`/06#;B!I=',@(D`\`!(BO0012!F4X.``P1$2(A`0!: -M""`L(E`(H"P@8V%P86)I;&D2%`8#`07Q``+S#P$_#@CV!0&7`8`@:6YD:79I -M9&P.`]L(`(4``#H2`D(``*P+`-$``#8!(71OK`TP9&%TUP``!0X6.BX!`L@) -M`#T`$F'L`@#)"@$K`#-I;B`G`0!%!3-A9&2.`AAA]PP!J0H#'@]19FER0#`',*'!L86EN:6YG"B`@(&AO=R!T;R!E>'1E;F0L -M`/(6+@H*("H@3VX@0*A2!A8V-E<#4`T6%T -M979E717`G`@82!T:6UEI0!Q;W(@;6UA<-H`065N -M=&D/`P+\`@!I`!!G!0,@:71/``FA`&%T(&]N8V6%`(M/;B!W`+$@(&)S9'1A2!B=69F97(@ -M;W+!``!E``1R`85A('-O8VME=#X#4'=I2UT;RUU"!I;G1E -M7,N"E)%041-12X`!^@&X2!B=6YD;&4N"@I1=65S^@*@ -M/R`@27-S=65S/U(`UBH@:'1T<#HO+W=W=RY,!T`N;W)GDP``2`$0:+@"@V9O -M0(1.FH`$B>7!9`G('!R;V=R86T6`G-A -M(&9U;&PME@AP9"`G=&%R)WX``P(`4W)E<&QA0@%`8G5I;($&`(H``V,``"H` -M9BH@8W!I;V,```X`"V0`(&1I:P4R96YT,`-#9F%C96H#`P(`,&5S`<``$D!`)()`"<`4"H@97AA20!`8$(&YDT`(Q9G5L+P(&10`0+T,*`84!$6$& -M"5%A8W0@`0-)`#!C;VY#`O`".B`@ -M5F%R:6]UP``7P%Q875T:&]R<\`%`1\&`?("`DT'$`J(!E!T;W`M;`P$`W8%`#`' -M`4$`$&GD!@FV`B)I;M8$`'$+`.L%!+T"\`).15=3("T@:&EG:&QI9VAT=&%R+C54`0CQ!$%A8F]U4P41]!9!I;@IA(&YU;6+R#!=F -MD0<$.P''"@I9;W4@`D09@82`;<&42H@ -M1TY5=0$"-0(F("@$"P`:`"-L;[P%`*T+(G,L$```!0L3(!$``&,`4G-P87)S -M?`(A -M`*%35E(T($%30TE)=`(!%``/,@`+$$)M$1%Y+@"Q("AB:6`@@;W#+`\!A;"!2 -M;V-K[`@0]`5HW+5II<"8`V$UI8W)OFEP/@$@:6]/$WTJ(&)Z:7`R%@`$?`%-+TQ:5QT`HFQZ;6$L -M(&QZ:7`3`R]X>B,``!DT%``)"`$```H"G!`%.@$`=00/!@$"`J\!`[\#`KP" -M#Q\#&#`B\+`OH#`*D"`&@1`HT``9L!`MH`#\@#"F$B;F5W8R*;`P$S`"=S -M:+```1(`#T8#8P0%!`?.``]9`P`*%@,S5VAE`P(`OP@#U`(2<^8%87)E`3AN97>U`P#P!`#]`@.?`0![``&'"0$K -M%0)*#`,*`P`X"`!O$!1T[A("#`(A(&(W"0","@&/&`.X%`$,`!!A#`$"U!`` -M:``".P`199P6`#T!(79E4,`4&EN9&5PJ@`E;G0B`0!$#0]D&O______ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M8U!A;F0@'1E;F1E -M9&0`!#-!0TPS`&%/;&0@5C2!O9K@"X&)E9F]R92!E=F%L=6%TI`(`V`(# -M+P("SP)@=75E;F-O<0(`M@("0P(!"@`1((,!HE)032!WFEP -M/@$Q:6]N!0%=8GII<#(6``1D`4TO3%I7'0"B;'IM82P@;'II0`&EP"0:7,@9&5S -M:6=NH@9";R!B98@%`$`$`3`$.&YE=[4#`*,$`'L``4,`4&EN9&5PJ@`B;G1_`!!R.P0` -M!``P=&EC0@4D;VZ!`02N`/``5VEK:2!E>'!L86EN:6YGB0`P:&]W^``!LP,0 -M9)8%`RP``BH!(4]NJ@`<+`,!``0$,FUA='``0&QW87E&`0#=`6!E9"!A=71> -M"&)I8V%L;'E'`+!))W9E(&%T=&5M<(P'X'1O(&UI;FEM:7IE('-T*P`"4@A0 -M<&]L;'6X`>$N("!)9B!Y;W4@9&]N)^P!`+8`\0)I8VET;'D@:6YV;VME(&$@ -M<.L`('5LO0B@96%T=7)E("AS=2\!&7,<`A!AZ0`'+0`$10<#(@("F0%P*2P@ -M:70@=W``X"!G970@<'5L;&5D(&ENI`0W($EN;@`W+"!IG@`!40$#FP`B96[) -M`07L#$7`U`-%A=&5V97(@8FQO8VMS\``` -M[@2X'<70@82!T:6U7`W%O8!(71O -M(@`%H0!A="!O;F-EA0`A3VZ0`QMEPP`"Y`(R<')O.@$!A0%18W1L>2W,``". -M"5)U='!U=.\"`&`$\0-O8FIE8W0M2!B=69F97(@)`@`90`$<@&%82!S;V-K970^`TEW:7-HN@3` -MP"`,D*`2L`,VEN(">D``,P``*,!!H`%,7=A;H@`$'0V -M!`5%`0!@```:!!!TC@7,N"E)%041-1;L&!^@& -MX2!B=6YD;&4N"@I1=65S^@*@/R`@27-S=65S/U(`URH@:'1T<#HO+W=W=RX@ -M!S!O3``!(`1!HN`*#9F]R(&]N9V]8!Q@@9`!P9&5V96QO<#P%)BP@8`]` -M9&]C=10``:P(`3<,`'$``#H`(6YK70$`70`&8N9V]O9VQE+F-O;2]P+VH`$2\Z`"!S+VD``),``6<`47-U8FUI9P!P96YH -M86YC9;L``#8"!C@`@RP@<&QE87-E+```.P``!`,`2PB!$!G0&";8"(FENU@0`I`H`ZP4![@_P!2`J($Y%5U,@+2!H:6=H;&EG:'1S7`8P -MM```Z#S`@*B"3``!.`/``+F%M+"!A -M8VQO8V%L+FTT"0T#[0`P+F%C_P```@`0+:("`)\`!*@``-D."*($$BP:#@#7 -M"P!9"Q!YR@4!]@$C97*N`05P`"1I;F0`@2YH+FEN"@DM]`<`YA,22XS -M]!0P86EL[P0R92`B:P,%JP`!)``4(@L+62!C;&%S1``!'PE&;F%L``'?`5&%M<&QE'2(`#%P=70I -M`/D#(F-M86ME(B!B=6EL9"!T;V]L30`"5@$&-0$!*0$Q(&EN3`$/;0$!,&%R -M91`"$F3:`35E"B>\`!,GK0`2.M0``),``$X`]0$N86TL(&%C;&]C86PN;30L -MX0!`92YA8RL```(`$BU4`"1T;Z@``"`!,&1IM`_`$,R!G:79E2XS!`,! -MJP(2(FL#!:L``20`Z2(@=71I;&ET>2!C;&%S1`"6:6YT97)N86QSG0`PP$2+8($4W,N-2!D5@(#I@0@:6QV`]1R;6%T-50!"/$$4&%B;W5T&@$@P"`+"!I;F-L=62*`8%H87)D+71O+3`&`J@!$G-'``!! -M`&%M;V1E$D#(F5R60<#>`('(0"P;V-T970M;W)I96X!`P!@`@$>`*%35E(T($%30TE) -M=`(!%``"4P`/,@`%,$)I;LH$`$(`H"`H8FEG+65N9&GS!(-R(&QI='1L91$` -M`OH`\0))4T\Y-C8P($-$+5)/32!I;;<"$2AX""!O<,L#P&%L(%)O8VMR:61G -M944`8DIO;&EE="D!`>\!`DD`-%I)4%8#!$``('5N3@DPFEP/@$Q:6]N&`%=8GII<#(6``1\`4TO3%I7'0"B;'IM82P@;'II?P(-F5A;;4%`A$+@"X@(%1H97)E -M+``C;F_B!P""`@/?"`"3!/("(&EN+7!L86-E(&UO9&EF:6-D"_``;W(@0`&@`23:7,@9&5S:6=N)0P298@%`$`$`;,%.&YE=[4# -M`/`$`'L``Y\!`'L``8<)`:,``DH,`PH#`#@(`+(`,71H82\)`RL`(2!B-PD` -M:@@Q86)L``8`C`H!#``!+`L"!`$`:``".P!"96%C:#T!(79E4,`4&EN -M9&5PJ@`E;G0B`0`8"0`/#Q!C0@42;VP-!C4*5"!7:6MI4@PP:6YGR0`P:&]W -M40\!LP,79)8*`BH!(4]N/P@`]PP"8`8#`P$$S0`!<`!`;'=A>48!`-T!*F5D -MB@@"1P!P22=V92!A="T-`(P'`,$/D&EN:6UI>F4@P,1<#4`T6%T979EP"`,D*`2L`,VEN("#U%F:7)S=)("`*8!$6%P$A%O61$`]@`6+G0``]D# -M`J60!`,P``*,!!H`% -M,7=A;G\%$G0=#P-%`0!@```:!!!TC@0#`',*%EF-%#A)B!P`2>`<``$D!`)()`"<`#V0: -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______]?4'(@8FQO)!$``/%/8VMS('EO=2!H86YD(&ET+@H@("!9;W5R(')E -M860@8V%L;&)A8VL@:7,@9G)E92!T;R!P87-S('1H92!L:6)R87)Y(&$@8GET -M92!A="!A('1I;64*("`@;W(@;6UA<"@`\`!E;G1I7,@<')O -M9'5C97,@8V]R`,`@(&)S9'1A&%)`$!S.B!3,@-4`0-)`#!C;VY#`O`".B`@ -M5F%R:6]UP``7P%Q875T:&]R<\`%`1\&`?("`DT'$`H5"%!T;W`M;`P$`W8% -M`#`'`4$`$&GD!@FV`B)I;O@$(FEOX08$O0+P`DY%5U,@+2!H:6=H;&EG:'1S -M7`8P'2(`#!P=71>`C`@(F,T!A$B)`,`J@2!N965D?``Q;6%I]@$C97*N`05P`"1I;F0`@2YH+FEN"@DM]`=2;&%T97-G -M`!%B-`(#<@$"M0!@"@I'=6ED\P`H($14!@32`0)U``&W`7!S>7-T96TZIPH" -MN`1U+C$@97AP;(,"`R\#`$(!`B$`!)H#`S,``(@$#S0`"P`B``PU`"]A=#0` -M#"AA=#,`!@$&(2XSM@L0<]\&@&]V97)V:65W\P(`H``%G@L`<04P=VAOD0(4 -M*J0*A5]R96%D+C,L$``!^`@-$0!17V1I``'<`%0P#'`(%>`D09BP``;<&42H@1TY5=0$"-0(F("@$"P`:`$%L;VYG4`8` -MK0LB+``-J`0`9`]$J(%!/4TE8('5S=&%R6P`"$``/B@P# -M!R$`P&]C=&5T+6]R:65N=!<$,7!I;QX`IE-64C0@05-#24D4``)3``\R``5A -M0FEN87)Y+@#`("AB:6FEP/@$Q:6]N&`%= -M8GII<#(6``1\`4TO3%I7'0"B;'IM82P@;'IID2,',@*'T'`30$`(0!`S,$`/0#8"P@971C*>\+`OH#`*D"`&@1`HT` -M`88!`MH`#Y8#!0'(`V$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0%!`?.``]9 -M`P`*%@,S5VAE`P(`-0<#U`(2<^8%87)E`3AN97>U`P#P!`#]`@.?`0![``&'"0$K%0)*#`!-$2)IE(7`+4(`E(( -M07!O;&PV$@;D%$%D;VXG[`&097AP;&EC:71LV0EB=F]K92!A^@\18W\*`\X1 -M("`HTA``=0P('`(08;(!`2<0`BT`",T`%&]S!'`I+"!I="!W<`!0(&=E="#2 -M$@%="@"D!#<@26YN``4F%P&>``%1`0.;`")E;LD!!RT``'P`"W$`*&1E$0`# -MJ@`1+%@1`H```(T.`)8!`!8!`$``,&%G8?,/`5\*D6-O!<1<_```.X'#V0:________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M__________________________________________]>4'1S(&%N3Q$``/`> -M9"!H86YD;&5S(&%N>2!O9B!T:&4@9F]L;&]W:6YG(&)E9F]R92!E=F%L=6%T -M$@``(`#Q#6%R8VAI=F4Z"B`@*B!U=65N8V]D960@9FEL97,4``$*`/$"('=I -M=&@@4E!-('=R87!P97(;`/$!9WII<"!C;VUPFUA+"!L>FEP+"!A;F0@>'HC```9-!0`]0<*5&AE(&QI -M8G)A"!I;G1E&-E<'0@9F]J`/$'("!E;G1R -M:65S('1H870@.`?$#;F%M -M97,L($%#3',L(&5T8RDND@"P3VQD($=.52!T87)=``2I``+*`/$$;V-T970M -M;W)I96YT960@8W!I;S4`ME-64C0@(FYE=V,B%0`G`'@G;71R964GNP!X25-/.38V,!,`6CT!X'-Y0`&EP#R`FES(&1EP`!S@`4=E@#$G.C`%0@;VYL>0H#0&UE;G2R -M``$>`P"F!`)G`S`@8F5``(!R96%D86)L9:(`07=R:70,`!!A#`$"!`$!1`0! -M.P!$96%C:"8"`98"$WE#`%!I;F1E<*H`(FYT?P`04<`L$DG -M=F4@871T96UPQ`/@=&\@;6EN:6UI>F4@2!I;G9O:V4@82!PZP`@=6PW!"!E -M85D"0"`HD`!RT`!^\%`(`!`ID!<"DL(&ET('=P`.`@9V5T -M('!U;&QE9"!I;J0$-R!);FX`-RP@:9X``5$!`YL`(F5NR0$'+0``?``+<0`H -M9&41``/&`A$L\``"@``B;F6.`@`6`0!``&)A9V%I;G-'`J!C;W)R97-P;VYD -M)P0(20`-6@`">P,Q:65SPP`!;P.A86QS;R!R961U8[D%,&4@`(&5N=FER;V[7`C%S('=N`@&@`A!MV`$3 -M6QE(&%P<')OR`,`R0@"^@#@=&\@:&%V92!M=6QT -M:7`E```A!1!V$@,`!04`N0A5(&]P96Z>`%`@(&)S9",'(75SO`$`/06#;B!I -M=',@(D#E`!(BO01&P`28D(``"P$`-$``#8!(71OFPDP9&%TUP!6=7)C -M93HN`0+("0#"`!)A[`(`R0H!*P`S:6X@)P$`3P@S861DC@(18?P(!*H!`'D& -M(6]U]P119FER0#`',*T"!S87ES+@I214%$346[!@?H!N$@ -M8G5N9&QE+@H*475E<_H"H#\@($ES8N9V]O9VQE+F-O;2]P+VH`$2\Z`"!S+VD``),``6<`47-U8FUI9P!P -M96YH86YC9;L``*8`!C@`@RP@<&QE87-E+```.P``!`,`2P7!1`GH@1` -M9W)A;18"F-%#A)B!P`2>`<``$D!`)()`"<`4"H@97AA20!`8$(&YDT`(Q9G5L+P(&10`0+T,*`84! -M$6&>"E%A8W0@H($',+!0$^`0!U```7`@#Y!`%Q``%Q"@B7```\"3-Y+C-- -M``#O!#)E(")K`P6K``$D`!0B"PM9(&-L87-$``$?"49N86QSG0`2!Q(M@@0U -M"`"X!!,B!0XR+F@BJ0`R -M:&4*7PP0(+`)`/H``!0`!.D&`W((`G\"$&T:%P/[`$(N("!0B@FS;&5T('5S -M"FMN;W>5$P`P%&!E\6`2T5`A``#XH,`P`""(&EN'!L86EN3`1!F+``0'1E;J`*%35E(T($%30TE)=`(!%``"4P`/,@`%84)I -M;F%R>2X`H"`H8FEG+65N9&GS!(-R(&QI='1L91$``OH`\0))4T\Y-C8P($-$ -M+5)/32!I;;<"@"AW:71H(&]P^@7`86P@4F]C:W)I9&=E10!B2F]L:65T*0$! -M[P$"20`T6DE05@,$0`"0=6YC;VUPB,``!DT -M%``)"`&58V%N(&-R96%TSP`!=00/!@$"`NP"`[\#`KP"#Q\#&#`B&-E<$`%`+D%!&D" -ML"!T:&%T(')E<75IE@4G87C*`B`@*'T'`30$`(0!`S,$`/0#<2P@971C*2YO -M`0#Z`P"I`@8B!`$7``+:``^6`P4!R`-A(FYE=V,BFP,!,P`G?P(-F5A;;4%`A$+@"X@(%1H97)E+``C -M;F_B!P""`@/?"`"3!/("(&EN+7!L86-E(&UO9&EF:6.M"/,";W(@U`P#P!`![ -M``.?`0![``&'"0&C``)*#`,*`P`X"`"R``$>`P"F!`(,`B$@8C<)<7)E861A -M8FP`!@","@$,``$L"P($`0!H``([`$)E86-H/0$A=F5S`Q-Y0P!0:6YD97"J -M`"5N="(!`!@)4&%R=&EC0@4D;VZ!`02N`$17:6MI4@PP:6YGR0`P:&]WFPP" -MI@<'E@H"*@$A3VX_"`#W#`)X!@$""B-N9/@``8@)8V%L=V%YD`!RT`!"T'`,T`%&^5"'`I+"!I="!W<`!Q(&=E="!P -M=9P-(&ENI`0W($EN;@`W+"!IG@`(FP`B96[)`02UV```S#`#W -M"!%IAP8`A`!P96YV:7)O;M<",7,@=Y`#`:`"$&W8`1-R6@,%,`(`6P`"?P`1 -M>7L#$7`U`-%A=&5V97(@8FQO8VMS\```[@`A$)P`$`B0`P;6%K>0"0:7,@ -M97-P96-I;@0!T`$"J@$`.@@P.B`BDPH!#A$)V@T3(KD"`-X.(F%NZ`(`I0<& -M-`H0+&,`0&1EF-%#A)B!P`2>`<``$D!`)() -M`"<`02H@97@;$T!S.B!3,@-4'2(`"%P=6<0,"`B8S0&%"*\&3EO;VQ-``)6`08U`0"4``"P"@&.`0]M -M`0$`(`T!$!H!V@$T90HGL``C92>O&0,D!`"3``!.``]D&O______________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________5E`@("!T -M;SL1``#R-B!B92!R96%D(&]R('=R:71T96X@=&\@86YY(&1A=&$@7,N"E)%041-15``1"!L:6)M`=%B=6YD;&4N"@I1=65SK@"@/R`@27-S=65S -M/U(`UBH@:'1T<#HO+W=W=RXX`$`N;W)GDP``2`$Q:&]MIP"`(&]N9V]I;F8$(&YD -MT`(Q9G5L+P(&10!1+VUI;FF%`1%AXP%186-T('-@`+`@9&5M;VYS=')A=+\`!,GK0`#)`0`DP``3@#U`2YA;2P@86-L;V-A;"YM-"SA -M`$!E+F%C_P```@`0+:("`)\`!*@`#*($LBP@;VYL>2!N965D?``Q;6%I]@$C -M97*N`05P`"1I;F0`@2YH+FEN"@DM]`=2;&%T97-G`!%B-`(!9@$39;4`8`H* -M1W5I9/,`*"!$5`8$T@$"=0`!MP%P!1%E^P,`\@"`;6%T``&I`5"`"X!!,B?P(R+F@BJ0`R:&4*7PP0(+`)`'4!`!0`!.D&`W((`G\"-&UO -M2X`P"`H8FEG+65N9&EA;J(!8VQI='1L91$``OH`\0))4T\Y-C8P -M($-$+5)/32!I;;<"$"@X#C`@;W#+`\!A;"!2;V-K[`@0]`5HW+5II<"8` -MV$UI8W)OFEP/@$Q:6]N -M&`%=8GII<#(6``1\`4TO3%I7'0"B;'IM82P@;'II\+`OH#`*D" -M`&@1`HT``88!`MH`#Y8#!0'(`V$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0% -M!`?.``]9`P`*%@,S5VAE`P(`&@T#U`(2<^8%87)E`3AN97>U`P#P!`#]`@.?`0![ -M``&'"0&C``)*#`!-$2)I7-S""IE9(H(`D<`L$DG=F4@ -M871T96UPC```%1`0.;`")E;LD!!RT``'P`"W$`*&1E$0`#Q@(1+.4)`H```(T. -M`)8!`!8!`$``,&%G8?,/`5\*D6-O7L#$7`U`&)A -M=&5V97)X%Q%S\```[@2X'$'1[%R%I;5<#<6]R(&UM87`I`0!>$P'Y%@*Y%P"V`A!G -MPA<0:2(3`2(`!4H``.,3(6-EA0`A3VZ0`QMEPP`"Y`(R<')O.@$!A0$`FA<1 -M+408DF5D(&]U='!U=.\"`&`$\0-O8FIE8W0M$E33SDV-C`3 -M`+0W+5II<"!AFUA+"!L>FEP+"!A;F0@>'HC`,$*3F]T97,@86)O=724 -M`')L:6)R87)YT0#P+G1E8W1U2!S -M=')E86TM;W)I96YT960@4,`4&EN9&5PJ@`B;G1_`$%R92!A!`"4=&EC;&5S(&]N@0$#=@+P -M`2!7:6MI(&5X<&QA:6YI;F?)`#!H;W?X``+U``$N("!)9B!Y -M;W4@9&]N)^P!`+8`\0)I8VET;'D@:6YV;VME(&$@<.L`@'5L87(@9F5A60)` -M("AS=2\!&7,<`A!AZ0`'+0`'!@,`@`$"F0%P*2P@:70@=W``\``@9V5T('!U -M;&QE9"!I;BX^`"=);FX`-RP@:9X``5$!`YL`(F5NR0$'+0``/@`+<0`H9&41 -M``/&`A$L\``"@``B;F6.`@`6`0!``&)A9V%I;G-'`J!C;W)R97-P;VYD)P0( -M20`-6@`">P,Q:65SPP`!;P.P86QS;R!R961U8V6;`C!E('.%`2-O9H@!`+,! -M$"UV`&%E9"!B:6X]`"`@:2P$@"!E;G9IP,1<#4`T6%T979E8!(71O(@`%2@!A="!O -M;F-EA0`A3VZ0`QMEPP`"Y`(R<')O.@$!A0%18W1L>2W,`))E9"!O=71P=73O -M`@!@!/$#;V)J96-T+7-T>6QE(&%P<')OR`,`H`4"^@#@=&\@:&%V92!M=6QT -M:7`E``.E`P(!!`!;!E4@;W!E;IX`L2`@8G-D=&%R('5SO`$`/06#;B!I=',@ -M(D#E`!(BR`-&P"`*`'`2L`,VEN("8<``J,!!H`%,7=A;H@`$'0V -M!`5%`0!@`!!IA0(`C@%EB!$!G&%)`$!S.B!3,@-4`0-)`#!C;VY#`O`".B`@5F%R:6]UP``7P%V875T:&]R,&`4D!A69I9W5R92`M#``"1`"U'2(`")P==8-(")C-`81 -M(B0#`#@,*6]L30`"5@$&ZP,!*0$`%@D`C@$/;0$!`*(&('5SW0H`V@$T90HG -ML``C92>M``,D!`"3``!.`/``+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C%P$` -M`@`0+:("`)\`!*@``-D."*($$BP:#@#7"P)\`#%M86GV`2-EPH"MP(29:`,`!(&0'-E<77J"!!S"P4!/@$`=0``%P(` -M^00!<0`!<0H(EP``/`DS>2XS30``[P0R92`B:P,%JP`!)``4(@L+62!C;&%S -M1``!'PE&;F%L"`"X!!,B!0XR+F@BJ0`R:&4*7PP0(+`)`/H``!0`!.D&`W((`G\"-&UO -M5$P`P%&!E+``-J`0`9`[$J(%!/4TE8('5S=+`1!!``#XH,`P%\``(Q`%9O -M8W1E=*\4`&`"`1X`H5-64C0@05-#24ET`@$4``\R``L00FT1$7DN`+$@*&)I -M9RUE;F1I8=018VQI='1L91$``OH`!%\6D4-$+5)/32!I;;<"$"@X#C`@;W#+ -M`\!A;"!2;V-KC2H`0#E%PD(`0``"@*<$`5+`0!U!`\&`0("@P$#OP," -MO`(/'P,8,")R9:`-`!`6$2)'`P)/`,(L('=H:6-H('=I;&SK&`!P"`###P-? -M`4!S(&5X+10``@(`N04$B1$""Q<#6A4P`T&-P:6\N-2P@;71R964)``!O`%1T87(N-;<`PB!D -M971A:6QE9"!I;E(`D&EO;B!A8F]U=$T`('-EN`"#<&]P=6QA#0#46-H86YG?@$W -M;6%T(0"P;V-T970M;W)I96X!`P!@`@$>`*%35E(T($%30TE)=`(!%``"4P`/ -M,@`%84)I;F%R>2X`P"`H8FEG+65N9&EA;J(!8VQI='1L91$``OH`\0))4T\Y -M-C8P($-$+5)/32!I;;<"@"AW:71H(&]PRP/`86P@4F]C:W)I9&=E10!B2F]L -M:65T*0$![P$"20`T6DE05@,$0`#`=6YC;VUPB,``!DT%``)"`&58V%N(&-R96%TSP`!=00/!@$"`J\!`[\#`KP"#Q\# -M&,$B!S>7-T96TN("!4:&5R92P`(VYOX@<`@@(#WP@`DP3R`B!I;BUP;&%C92!M -M;V1I9FECK0CS`F]R(')A;F1O;2!A8V-E0`&@`3R`FES(&1EP`#P`!APD!HP!4(&]N;'D* -M`P`X"`"R``$>`P"F!`(,`B$@8C<)<7)E861A8FP`!D%W48!`-T!*F5DB@@"1P"P22=V92!A='1E -M;7",!^!T;R!M:6YI;6EZ92!S=+4(`E((4'!O;&QU(@=1+B`@26;U"$!D;VXG -MU@7L#$7`U`-%A=&5V -M97(@8FQO8VMS\```[@2X'<70@82!T:6U7`P!K"S%M87#X`C!E;G21!@/0`@%1 -M`T!G:79EY@$A=&\B``6A`&%T(&]N8V6%`"%/;I`#&V7#``+D`C)P@``P0&%82!S;V-K970^ -M`TEW:7-HN@0!)@]P=71I;&ET>7,"!8P``#\``TP/4"!E87-Y3@Y1=7-E("(A -M`0!:""`L(E`(<"P@8V%P86)!``'V`@0#`07Q`&%E($%027.W!`CV!0&7`8`@ -M:6YD:79I9&P.`]L(`(4``A4&`$(``'(+`-$``#8!(71OK`TP9&%TUP``!0X6 -M.BX!`L@)`#T`$F'L`@#)"@$K`#-I;B`G`0"5"S-A9&2.`AAA]PP!UP<#'@]1 -M9FER0"0:7,@ -M97-P96-I;@0!T`$"J@$`.@@P.B`BDPH!#A$)V@T3(KD"`-X.(F%NZ`(`I0<` -M$0,"6@<0+&,`0&1E8N9V]O -M9VQE+F-O;2]P+VH`$2\Z`"!S+VD``),``6<`47-U8FUI9P!P96YH86YC9<\` -M`*8`!C@`,BP@<-H0`BP``#L```0#`$L'`1<)X65S="!V:6$@1VET2'5BP@`" -MD`"A7!1`GD1(`\A$`%@)S82!F=6QL -M+98(F-%#A)B!P`2>`<` -M`$D!`)()`"<`02H@97@;$T!S.B!3,@-4P``7P%C875T:&]R:1``EPT!\@(`P1,2 -M+NT/4'1O<"UL#`0#Q0P`,`0&";8""',5`.L%`>X/\`4@*B!.15=3 -M("T@:&EG:&QI9VAT<]P`,')E8]D4`C$%`Z`"DD-/4%E)3D<@+0P%`$(4`,H' -M(61O7P8!AP4`S@#`*B!)3E-404Q,("T@9`HQ86QLCP0!#0``BA8`OP`"*0`# -M0`41+3P``5X1`A@`8&-O;F9I9[(6%2T,``)$`+5S8W)I<'0L('-E96<``"@% -M`ED6`F,(@2H@0TUA:V5,U`0Q='ATB``A<'5G$#`@(F,T!A$B)`,`.`PI;VQ- -M``)6`0;K`P$I`0`6"0".`0]M`0$`(`T0=3T3`A`7)`HGL``C92>M``,D!`"3 -M``!.`/``+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C_P```@`0+60"`)\`!*@` -M`-D."*($$BP:#@#7"P!9"Q!YR@4!]@$C97*N`05P`"1I;F0`@2YH+FEN"@DM -M]`<`YA,2\%#V0:____________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________]G4&%N(&ES-1$``/`02#R`I!I;VYS+@H*5&B=`?("<"UL979E;"!D:7)E8W1O'2(`#!P=71>`H$@(F-M86ME(B0#:60@ -M=&]O;$T``E8!!NL#`2D!,2!I;DP!#VT!`3!A2!N965D?``Q;6%I]@$C97)<`05P`"1I;F0`\@,N:"YI -M;@H)+2!T96UP;&%T97-G`!%B-`(!9@$39;4`8`H*1W5I9/,`4"!$;V-UF04" -M@0$`Q0$R86QL=0`!MP&R'!L@P(#+P,`0@$" -M(0`$F@,#,P``B`0/-``+`"(`##4`+V%T-``,*&%T,P`&`0:`+C,@9VEV97-X -M!H!O=F5R=FEE=_,"`*``!+L%$&%Q!3!W:&^1`B,J(,0&A5]R96%D+C,L$``` -MT04=91$`45]D:7-K%@`@;F30`0@^``,<``"9`!!V7P$"MP)P960@8V%L;!(& -M$'/4!D%N8V5SK0(`DP``=0`!1P`#0@9H92!!4$ESEP!S96YTP$2+8($ -M4W,N-2!D5@("KP``&0,`\@#$;6%T=&%R+C54`0CQ!$%A8F]U4P4@P`3+/('`(H!@6AA``%4!%#0#`ED'`W@"!R$`L&]C=&5T -M+6]R:65N`0,`8`(!'@"A4U92-"!!4T-)270"`10``E,`#S(`!6%":6YA`@@;W#+`\!A;"!2;V-KFEP/@$Q:6]N&`%=8GII<#(6 -M``1\`4TO3%I7'0"B;'IM82P@;'II`3AN97>U`P#P!`![``.?`0![``&'"0&C``)* -M#`!-$2)IF4@``%1`0.;`")E;LD!!RT``'P`"W$`*&1E$0`#Q@(1+/```H```(T.`)8! -M`!8!`$``,&%G82X.`?$)D6-OP,1<#4`T6%T979E$P$/`P$W%0%1`T!G:79E -MY@$A=&\B``5*``#C$R%C984`(4]ND`,;9<,``N0",G!R;SH!`84!46-T;'DM -MS`"2960@;W5T<'5T[P(`8`3Q`V]B:F5C="US='EL92!A<'!R;\@#`/D4`OH` -MT'1O(&AA=F4@;75L=&G#$P2I``(!!`"Y"%4@;W!E;IX`$R`5$`!J$``*`1%I -M(0AC:71S(")`/``2(KT$$7,P#@)C!098`&!I='-E;&93`5!R96%D+^8`8'1E -M;B!U@``S0*%82!S;V-K970^`TEW:7-HN@0! -M)@\#60\`7,N"B05 -M$6:X#01/&0.A&$0N"@I1$19`/R`@29X9(',_4@`1*@49=CHO+W=W=RXX`$`N -M;W)GDP``2`$0:+@"`%<`0V]N9V]8!Q<@3`<@(&18%B!O<#P%"!D1!+H1`:P( -M`3<,`'$``#H`(&YK-`$!P0`&7,@9&5T96-T960@875T;VUA -M=&EC86QL>4<`L$DG=F4@871T96UP(@#P(71O(&UI;FEM:7IE('-T871I8R!L -M:6YK('!O;&QU=&EO;BX@($EF('EO=2!D;VXG=*@``+8`\"1I8VET;'D@:6YV -M;VME(&$@<&%R=&EC=6QA!E('-O;64@=71I;&ET>3X`!8P``+$!\09P2!D8737`%9UP",B!O9BL`,VEN("X -M`0!V``*4`0```P&^``7+`0#3``.C`0:`!3%W86Z(`!!T-@0#-@(!6P,`'P$` -MN@!!9&ES:RP#`\0!N6-O;G9E;FEE;F-EP`$`B0`P;6%K>0"0:7,@97-P96-I -M;@0!T`$"J@'S!TYO=&4Z(")P87@@:6YT97)C:&%N9V6?!1,BN0(@;&P\`0+H -M`A!DO@$`_04!C080+&,`0&1E0(1.FH`$B>7!9`G('!R;V=R86T6`G-A(&9U;&PME@AP9"`G=&%R)WX``P(` -M4W)E<&QA0@%`8G5I;($&`(H``V,``"H`9BH@8W!I;V,```X`"V0`(&1I:P4R -M96YT,`-#9F%C96H#`P(`,&5S`<``$D! -M`)()`"<`4"H@97AA20!`8$ -M(&YDT`(Q9G5L+P(&10`0+T,*`84!$6$&"5%A8W0@`0-)`#!C;VY#`O`".B`@5F%R:6]UP``7P%Q875T:&]R<\`%`1\& -M`?("`DT'$`J(!E!T;W`M;`P$`W8%`#`'`4$`$&GD!@FV`B)I;M8$`'$+`.L% -M!+T"\`).15=3("T@:&EG:&QI9VAT=&%R+C54`0CQ!$%A8F]U4P41 -M]!9!I;@IA(&YU;6+R#!=FD0<$.P''"@I9;W4@`D09@82`;<&42H@1TY5=0$"-0(F("@$"P`:`"-L;[P% -M`*T+(G,L$```!0L3(!$``&,`4G-P87)S?`(A`*%35E(T($%30TE)=`(!%``/,@`+ -M$$)M$1%Y+@"Q("AB:6`@@;W#+`\!A;"!2;V-K[`@0]`5HW+5II<"8`V$UI -M8W)OFEP/@$@:6]/$WTJ -M(&)Z:7`R%@`$?`%-+TQ:5QT`HFQZ;6$L(&QZ:7`3`R]X>B,``!DT%``)"`$` -M``H"G!`%.@$`=00/!@$"`J\!`[\#`KP"#Q\#&#`B\+`OH#`*D"`&@1`HT` -M`9L!`MH`#\@#"F$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0%!`?.``]9`P`* -M%@,S5VAE`P(`OP@#U`(2<^8%87)E -M`3AN97>U`P#P!`#]`@.?`0![``&'"0$K%0)*#`,*`P`X"`!O$!1T[A("#`(A -M(&(W"0","@&/&`.X%`$,`!!A#`$"U!``:``".P`199P6`#T!(79E4,` -M4&EN9&5PJ@`E;G0B`0!$#0%Y&0!"!1)O;`T&L`L/9!K_________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_________________________________________________V50=',Z"B`P -M$0``\0T@*B!'3E4@=&%R(&9O`*935E(T($%30TE)%``"8P`/,@`%84)I;F%R>2X`\P<@*&)I -M9RUE;F1I86X@;W(@;&ET=&QE$0`"^@#P'TE33SDV-C`@0T0M4D]-(&EM86=E -MFEP/@$Q:6]N1`!=8GII<#(6``1D`4TO3%I7'0"B -M;'IM82P@;'IID#`*4#`.<#]A)U2!S=')E86VU!>!S>7-T96TN("!4:&5R92P`D&YO(&1I -M-R86YD -M;VT@86-C97-S+GD`!I<`D&ES(&1EU -M`P"C!`![``'.`!!VFP0`-0<2$N("!)9B!Y;W4@ -M9&]N)^P!`+8`\0)I8VET;'D@:6YV;VME(&$@<.L`('5LO0B@96%T=7)E("AS -M=2\!&7,<`A!AZ0`'+0`$10<#(@("F0%P*2P@:70@=W``X"!G970@<'5L;&5D -M(&ENI`0W($EN;@`W+"!IG@`!40$#FP`B96[)`07L#$7`U`-%A=&5V97(@8FQO8VMS\```[@2X'<70@82!T:6U7`W%O8!(71O(@`%H0!A="!O;F-EA0`A3VZ0 -M`QMEPP`"Y`(R<')O.@$!A0%18W1L>2W,``"."5)U='!U=.\"`&`$\0-O8FIE -M8W0M2!B=69F97(@ -M)`@`90`$<@&%82!S;V-K970^`TEW:7-HN@3`P" -M`,D*`2L`,VEN(">D``,P``*,!!H`%,7=A;H@`$'0V!`5%`0!@```:!!!TC@7,N"E)%041-1;L&!^@&X2!B=6YD;&4N"@I1=65S^@*@ -M/R`@27-S=65S/U(`URH@:'1T<#HO+W=W=RX@!S!O3``!(`1!HN`*#9F]R -M(&]N9V]8!Q@@9`!P9&5V96QO<#P%)BP@8`]`9&]C=10``:P(`3<,`'$``#H` -M(6YK70$`70`&8N9V]O9VQE+F-O;2]P+VH` -M$2\Z`"!S+VD``),``6<`47-U8FUI9P!P96YH86YC9;L``#8"!C@`@RP@<&QE -M87-E+```.P``!`,`2PB!$!G0&";8"(FENU@0`I`H`ZP4$ -MO0+P`DY%5U,@+2!H:6=H;&EG:'1S7`8PM```Z#S`@*B"3``!.`/``+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C_P`` -M`@`0+:("`)\`!*@``-D."*($$BP:#@#7"P!9"Q!YR@4!]@$C97*N`05P`"1I -M;F0`@2YH+FEN"@DM]`<`YA,22XS]!0P86EL[P0R92`B:P,%JP`!)``4 -M(@L+62!C;&%S1``!'PE&;F%L``'? -M`5&%M<&QE('!R;V=R86US('1H870@>6]U(&UA>2!F:6YD('5S969U -M;"X*("`@*C``\@=S+VUI;FET87(Z(&$@8V]M<&%C="!S2P#09&5M;VYS=')A -M=&EN9SX`XR!O9B!L:6)AM`_`$ -M,R!G:79E2XS!`,!JP(2(FL#!:L``20`Z2(@=71I;&ET>2!C;&%S -M1`"6:6YT97)N86QSG0!@P$2+8($4W,N-2!D5@(#I@0@:6QV`]1R -M;6%T-50! -M"/$$4&%B;W5T&@$@P"`+"!I;F-L=62*`8%H -M87)D+71O+3`&`J@!$G-'``!!`&%M;V1E$D#(F5R60<#>`('(0"P;V-T970M;W)I96X! -M`P!@`@$>`*%35E(T($%30TE)=`(!%``"4P`/,@`%,$)I;LH$`$(`H"`H8FEG -M+65N9&GS!(-R(&QI='1L91$``OH`\0))4T\Y-C8P($-$+5)/32!I;;<"$2AX -M""!O<,L#P&%L(%)O8VMR:61G944`8DIO;&EE="D!`>\!`DD`-%I)4%8#!$`` -M('5N3@DPFEP/@$Q:6]N&`%=8GII<#(6``1\`4TO -M3%I7'0"B;'IM82P@;'II?P( -M-F5A;;4%`A$+@"X@(%1H97)E+``C;F_B!P""`@/?"`"3!/("(&EN+7!L86-E -M(&UO9&EF:6-D"_``;W(@0`&@`23:7,@9&5S:6=N -M)0P298@%`$`$`;,%.&YE=[4#`/`$`'L``Y\!`'L``8<)`:,``DH,`PH#`#@( -M`+(`,71H82\)`RL`(2!B-PD`:@@Q86)L``8`C`H!#``!+`L"!`$`:``".P!" -M96%C:#T!(79E4,`4&EN9&5PJ@`E;G0B`0`8"0`/#Q!C0@42;VP-!C4* -M5"!7:6MI4@PP:6YGR0`P:&]W40\!LP,79)8*`BH!(4]N/P@`]PP"8`8#`P$$ -MS0`!<`!`;'=A>48!`-T!*F5DB@@"1P!P22=V92!A="T-`(P'`,$/D&EN:6UI -M>F4@P,1<#4`T6%T979EP" -M`,D*`2L`,VEN("#U%F:7)S=)("`*8!$6%P -M$A%O61$`]@`6+G0``]D#`J60!`,P``*,!!H`%,7=A;G\%$G0=#P-%`0!@```:!!!TC@0# -M`',*%EF-%#A)B!P`2 -M>`<``$D!`)()`"<`!A\:,#H@4S(##V0:____________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________________________________]J4'(@71E(&%T -M(&$@=&EM90H@("!O2UB;&]C:V5D(&]U='!U="X*"B`J(%1H92!O8FIE8W0M -M'1E;G-I;VZ*``,<```J`#!E;&93`5!R96%D+^8`EG1E;B!U2!B=69F97(@;W+!``!E``1R`3!A(',K`5%T+"!I9@(!8'=I -M2UT;RUU`@#1```V`:!T;R!A;GD@9&%TUP!6=7)C93HN`5%C`@&^``7+`0#3``.C`4,N("!)I`$A86Z(`!)T70`#10$`8``0 -M:84"86\@9&ES:RP#`\0!N6-O;G9E;FEE;F-EP`$`B0`P;6%K>0#1:7,@97-P -M96-I86QL>=`!`JH!\P].;W1E.B`B<&%X(&EN=&5R8VAA;F=E(&9O7,N"E)%041-12X``$0$!&T!T6)U;F1L92X*"E%U97/Z`J`_("!)0(1.FH`$B>7!1`G'@9`9W)A;18"\`9A(&9U -M;&PM9F5A='5R960@)W1A`<``$D!0'-U8V@G`%`J(&5X84D`0',Z(%,R -M`U1S;6%L;!4`!#X!`%(#(6%T(`8@;6'F!"!N9-`",69U;"\"!D4`42]M:6YI -MA0$18>,!46%C="!S8`"P(&1E;6]N0&";8"(FEN^`0B:6_A!@2]`O`"3D574R`M(&AI9VAL -M:6=H='-M``,D!`"3``!. -M`/4!+F%M+"!A8VQO8V%L+FTT+.$`0&4N86/_```"`!`MH@(`GP`$J``,H@2R -M+"!O;FQY(&YE961\`#%M86GV`2-E'!L@P(#+P,`0@$"(0`$F@,#,P``B`0/-``+`"(`##4` -M+V%T-``,*&%T,P`&`08A+C.V"Q!SWP:`;W9E"P!Q!3!W -M:&^1`A0JI`J%7W)E860N,RP0``'X"`T1`%%?9&ES:Q8``GX'`X(%`3X``QP` -M`)D``7L*`K<"$F6@#`!;!!!SU`80;A$,`-8"`),``'4``!<"`/D$`7$``7$* -M")<``#P),WDN,TT``.\$,F4@(FL#!:L``20`%"(+"UD@8VQA``'<`%`D09BP``;<&42H@1TY5=0$"-0(F("@$"P`:`$%L -M;VYG4`8`K0LB+``-J`0`9`]$J(%!/4TE8('5S=&%R6P`" -M$``/B@P#!R$`P&]C=&5T+6]R:65N=!<$,7!I;QX`IE-64C0@05-#24D4``)3 -M``\R``5A0FEN87)Y+@#`("AB:6B,``!DT -M%``)"`$```H"G!`%.@$`=00/!@$"`J\!`[\#`KP"#Q\#&,$B&-E<$`%`+D%!(D142!T -M:&%T0PX`TQ,`40`%Z1(P?P(-F5A;;4%`A$+!8@40&ES(&[6$C%R96,P$0/?"`"3 -M!$$@:6XM`@^"(&UO9&EF:6/E#/<`;W(@`3AN97>U`P#P!`#]`@.?`0![``&'"0$K%0)*#`!-$2)I -ME(7`+4(`E((07!O;&PV$@;D%$%D;VXG[`&097AP;&EC:71LV0EB=F]K92!A -M^@\18W\*`\X1("`HTA``=0P('`(08;(!`2<0`BT`",T`%&]S!'`I+"!I="!W -M<`!0(&=E="#2$@%="@"D!#<@26YN``4F%P&>``%1`0.;`")E;LD!!RT``'P` -M"W$`*&1E$0`#J@`1+%@1`H```(T.`)8!`!8!`$``,&%G8?,/`5\*D6-O"(&5N=FER;VX/"T!W:&5R+Q9`870@;=@!$W): -M`P4P`@!;``)_`!%Y>P,1<#4`8F%T979EFEP(&-O;7!R97-S:6]N%0!=8GII<#(6``0F -M`$TO3%I7'0#_`VQZ;6$L(&QZ:7`L(&%N9"!X>B,``!DT%`#U!PI4:&4@;&EB -M2!C86X@8W)E873/`+%S(&EN(&%N>2!O9N8`8&9O;&QO=_0``21E9-T` -M$2E%``"=``#5`85"4T0@)V%R)U(``1X`>"=M=')E92>[`'A)4T\Y-C8P$P!: -M-RU::7`Y`#9805(1`$,*5VAE`P(`Y`$#U`(AT!X'-Y -M0`&EP#R`FES(&1E -MP`!S@`4=E@#$G.C -M`%0@;VYL>0H#0&UE;G2R``$>`P"F!`)G`S`@8F5``(!R96%D86)L9:(`07=R -M:70,`!!A#`$"!`$!1`0!.P!$96%C:"8"`98"$WE#`%!I;F1E<*H`(FYT?P`0 -M)`#!H;W?X -M``+U``".!`,L``(J`2%/;JH`'"P#`0/9`@)P`$!L=V%Y1@$`W0'R`65D(&%U -M=&]M871I8V%L;'E'`+!))W9E(&%T=&5M<,0#X'1O(&UI;FEM:7IE('-T*P"P -M(&QI;FL@<&]L;'6X`>$N("!)9B!Y;W4@9&]N)^P!`+8`\0)I8VET;'D@:6YV -M;VME(&$@<.L`('5L-P0@96%9`D`@*'-U+P$9``%1`0.; -M`")E;LD!!RT``'P`"W$`*&1E$0`#Q@(1+/```H``(FYEC@(`%@$`0`!B86=A -M:6YS1P*@8V]RP,1<#4`T6%T979E2!B=69F97(@)`@`90`$<@&%82!S;V-K -M970^`TEW:7-HN@3`P"`,,)`2L`,VEN("0#`',*T"!S87ES -M+@I214%$346[!@?H!N$@8G5N9&QE+@H*475E<_H"H#\@($ES8N9V]O9VQE+F-O;2]P+VH`$2\Z`"!S+VD` -M`),``6<`47-U8FUI9P!P96YH86YC9;L``*8`!C@`@RP@<&QE87-E+```.P`` -M!`,`2P7!1`GH@1`9W)A;18"F-%#A)B!P`2>`<``$D!`)()`"<` -M4"H@97AA20!`8$(&YDT`(Q -M9G5L+P(&10`0+T,*`84!$6&>"E%A8W0@H($',+!0$^`0!U```7`@#Y!`%Q -M``%Q"@B7```\"3-Y+C--``#O!#)E(")K`P6K``$D`!0B"PM9(&-L87-$``$? -M"49N86QSG0`2!Q(M@@0U -M"`"X!!,B!0XR+F@BJ0`R:&4*7PP0(+`)`/H``!0`!.D&`W((`G\"$&T:%P/[ -M`$(N("!0B@FS;&5T('5S"FMN;W>5$P`P%&!E2X`L2`H8FEG+65N -M9&EAU!%C;&ET=&QE$0`"QP`$7Q:10T0M4D]-(&EMMP(0*#@.,"!O<,L#P&%L -M(%)O8VMR:61G9>\!`DD`#QX78P\+%P#036EC84`X"!S8W)I<'0* -M"D=U:61E@@"01&]C=6UE;G1A>`""(&EN'!L86EN3`1!F+``P'1E;J`*%35E(T($%30TE)=`(!%``"4P`/,@`%84)I;F%R>2X` -MH"`H8FEG+65N9&GS!(-R(&QI='1L91$``OH`\0))4T\Y-C8P($-$+5)/32!I -M;;<"@"AW:71H(&]P^@7`86P@4F]C:W)I9&=E10!B2F]L:65T*0$![P$"20`T -M6DE05@,$0`"0=6YC;VUPB,``!DT%``)"`&5 -M8V%N(&-R96%TSP`!=00/!@$"`NP"`[\#`KP"#Q\#&#`B&-E<$`%`+D%!&D"L"!T:&%T -M(')E<75IE@4G87C*`B`@*'T'`30$`(0!`S,$`/0#<2P@971C*2YO`0#Z`P"I -M`@8B!`$7``+:``^6`P4!R`-A(FYE=V,BFP,!,P`G?P(-F5A;;4%`A$+@"X@(%1H97)E+``C;F_B!P"" -M`@/?"`"3!/("(&EN+7!L86-E(&UO9&EF:6.M"/,";W(@U`P#P!`![``.?`0![ -M``&'"0&C``)*#`,*`P`X"`"R``$>`P"F!`(,`B$@8C<)<7)E861A8FP`!@", -M"@$,``$L"P($`0!H``([`$)E86-H/0$A=F5S`Q-Y0P!0:6YD97"J`"5N="(! -M`!@)4&%R=&EC0@4D;VZ!`02N`$17:6MI4@PP:6YGR0`P:&]WFPP"I@<'E@H" -M*@$A3VX_"`#W#`)X!@$""B-N9/@``8@)8V%L=V%YD`!RT`!"T'`,T`%&^5"'`I+"!I="!W<`!Q(&=E="!P=9P-(&EN -MI`0W($EN;@`W+"!IG@`(FP`B96[)`02UV```S#`#W"!%IAP8` -MA`!P96YV:7)O;M<",7,@=Y`#`:`"$&W8`1-R6@,%,`(`6P`"?P`1>7L#$7`U -M`-%A=&5V97(@8FQO8VMS\```[@`A$)P`$`B0`P;6%K>0"0:7,@97-P96-I -M;@0!T`$"J@$`.@@P.B`BDPH!#A$)V@T3(KD"`-X.(F%NZ`(`I0<&-`H0+&,` -M0&1EF-%#A)B!P`2>`<``$D!`)()`"<`02H@ -M97@;$T!S.B!3,@-4'2( -M`"%P=6<0,"`B8S0&%"*\&3EO;VQ-``)6`08U`0"4``"P"@&.`0]M`0$`(`T! -M$!H!V@$T90HGL``C92>O&0,D!`"3``!.`(\N86TL(&%C;&0:____________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________________________________________________]J4&%N -M>2!D,!$``/`<871A('-O=7)C93H@(%EO=2!C86X@8W)E871E"B`@(&$@8FQO -M8VL@;V8@9"L`\!YI;B!M96UO2!E87-Y+@H*("H@3F]T93H@(G!A -M>"!I;G1E'1E;F1E9#@!`B(` -M$"QC`$!D97-PWP!`=VAA=)8`\`,@;F%M92!S87ES+@I214%$3450`$0@;&EB -M;0'18G5N9&QE+@H*475E`<``$D!0'-U8V@G`%`J(&5X84D`0',Z(%,R`U1S -M;6%L;!4`!#X!`%(#(6%T?`0@;6'F!"!N9-`",69U;"\"!D4`42]M:6YIA0$1 -M8>,!46%C="!S8`"A(&1E;6]NM``,D -M!`"3``!.`/4!+F%M+"!A8VQO8V%L+FTT+.$`0&4N86/_```"`!`MH@(`GP`$ -MJ``,H@2R+"!O;FQY(&YE961\`#%M86GV`2-E7-T96TZ<`<"N`1U+C$@97AP;(,"`R\#`$(!`B$`!)H#`S,``(@$#S0` -M"P`B``PU`"]A=#0`#"AA=#,`!@$&@"XS(&=I=F5SWP:`;W9EP$2+8($-7,N-:H(`)X%$67[`P#R -M`(!M871S('-U<'\(!&,"!98!`$P```H"D"XU+"!M=')E90D``&\`7G1A`D09BP``;<& -M42H@1TY5=0$"-0(F("@$"P`:`$%L;VYG50(`K0LB+``-J -M`0`9`]$J(%!/4TE8('5S=&%R6P`"$``/B@P#!R$`P&]C=&5T+6]R:65N=!<$ -M,7!I;QX`IE-64C0@05-#24D4``)3``\R``5A0FEN87)Y+@#`("AB:6FEP,A8`!'P!32],6E<= -M`*)L>FUA+"!L>FEP$P,O>'HC```9-!0`"0@!```*`IP0!3H!`'4$#P8!`@*O -M`0._`P*\`@\?`Q@P(G)EH`U18W1E9")'`P)/`,,L('=H:6-H('=I;&PF$0)U -M`P:0`%%E>&-E<$`%`+D%`?P(-F5A;;4%`A$+ -M<"X@(%1H97(T$2`@;M82,7)E8S`1`]\(`),$02!I;BVW#X(@;6]D:69I8^4, -M\@%OP`!APD!HP`"2@P`31$B:7*"$1!I>0<# -M[A("#`(A(&(W"0","C%A8FP`!@","@$,``$L"P+4$`!H``([`$)E86-H/0$A -M=F5S`Q-Y0P!0:6YD97"J`"5N="(!`$0-``\/$&-"!1)O;`T&-0I4(%=I:VE2 -M#`,,$S!H;W?X``&S`Q!DK0$#V@`"*@$A3VX_"`#W#`)@!@#S#@!0!@/-``%P -M`%-L=V%Y'!L:6-I#16":6YV;VME(&'Z#Q%C -M?PH#SA$@("C2$"4@8?L*`*$!("!AL@$!)Q`"+0`(S0`4;W,$<"DL(&ET('=P -M`%`@9V5T(-(2`5T*`*0$-R!);FX`,BP@:8(5`9X``5$!`YL`(F5NR0$'+0`` -M?``+<0`H9&41``/&`A$LY0D"@```C0X`E@$`%@$`0``P86=A\P\!7PJ18V]R -M"(&5N=FER;VX/"Q%WD`,!H`(0;=@! -M$W):`P4P`@!;``)_`!%Y>P,1<#4`8F%T979E:89`@4.#V0:____________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________________________________________]@4"`@*B!)1!$` -M`/$14T\Y-C8P(&9OFEP,A8`!"8`32],6E<=`/D#;'IM82P@;'II<"P@ -M86YD('AZ(P#!"DYO=&5S(&%B;W5TE`!R;&EB=$`\"YT96-T=7)E.@H* -M("H@5&AI0`&EP#@:7,@9&5S:6=N960@ -M=&]>`61E>'1E;F1>`3AN97?@``#S`#(*("#.`!!V<@$`X0$22!R97%U:7)E;65N=+(`,G1H80D!`BL`("!BCP&0(')E861A8FQEH@!!=W)I -M=`P`$&$,`0($`0!H``([`$5E86-H;P!396YT'!L86EN:6YGR0`P:&]W -M^``"]0`'+``"*@$A3VZJ`!PL`P$`48!`-T!\@%E9"!A -M=71O;6%T:6-A;&QY1P"P22=V92!A='1E;7#7`>!T;R!M:6YI;6EZ92!S="L` -ML"!L:6YK('!O;&QUN`'A+B`@268@>6]U(&1O;B?L`0"V`/$":6-I=&QY(&EN -M=F]K92!A('#K`(!U;&%R(&9E85D"0"`HD`!RT`!P8#`(`! -M`ID!<"DL(&ET('=P`/``(&=E="!P=6QL960@:6XN/@`G26YN`#``%1 -M`0.;`")E;LD!!RT``#X`"W$`*&1E$0`#Q@(1+/```H``(FYEC@(`%@$`0`!B -M86=A:6YS1P*@8V]R7L#$7`U`-%A=&5V -M97(@8FQO8VMS\``0:$,$(6ETH0!!66]U717`F$@82!T:6U7`W%O`+$@ -M(&)S9'1A3X`!8P``0`"\05R;W9I9&4@ -M96%S>2UT;RUUX`0!V``##``"\`Q)EDP`" -M3P0"0:7,@97-P96-I;@0!T`$"J@$`.@CS -M`SH@(G!A>"!I;G1E`<``$D!`)()`"<`4"H@97AA20!`8$(&YDT`(Q9G5L+P(&10`0+T,* -M`84!$6&>"E%A8W0@"`"X!!,B!0XR+F@BJ0`R:&4* -M7PP0(+`)`/H``!0`!.D&`W((`G\"-&UO5$P`P%&!E+``-J`0`9`[$J(%!/ -M4TE8('5S=+`1!!``#XH,`P%\``(Q`%9O8W1E=*\4`&`"`1X`H5-64C0@05-# -M24ET`@$4``\R``L00FT1$7DN`+$@*&)I9RUE;F1I8=018VQI='1L91$``OH` -M$TE?%I%#1"U23TT@:6VW`A`H.`XP(&]PRP/`86P@4F]C:W)I9&=EYP%B2F]L -M:65T*0$![P$"20`T6DE0=00$0``@=6XQ"P`E%@#6$&!R(")D969^!A$B9@D# -M&```H00C:655`0##`0"B`85"4T0@)V%R)U(``?@`$2?]`Q`GNP(/"Q<(V$UI -M8W)OQ=4`)H`-6QZ-*@!`.47"0@! -M```*`IP0!4L!`'4$#P8!`@*O`0._`P*\`@\?`Q@P(G)EH`T`$!81(D<#`D\` -MPBP@=VAI8V@@=VEL;.L8`'`(`,,/`U\!0',@97@M%``"`@"Y!02)$0(+%P-: -M%P%1``7I$C!S("A3"@$T!`"$`0,S!`#T`V`L(&5T8RGO"P+Z`P"I`@!M``*- -M``&;`0+:``_(`PIA(FYE=V,BFP,!,P`G`'!L:6)R -M87)Y3`#08W!I;RXU+"!M=')E90D``&\`\@IT87(N-2!P2!E2QN``/2`>`@875T;VUA -M=&EC86QL>68!065C='.H``#5``,<`E!O;&QO=Y,!$&8L`*%S.@H@("H@1TY5 -M=0$"4@(F("BY`0`:`$%L;VYG50)B;F%M97,L$`!3;&EN:R`1```W`E)S<&%R -M'1E;J+ -M``-J`0`9`]$J(%!/4TE8('5S=&%R6P`"$``R<&%X-`-18VAA;F=^`3=M870A -M`+!O8W1E="UOFEP/@$Q:6]N&`%=8GII<#(6``1\`4TO3%I7'0"B;'IM82P@;'II&-E<$`% -M`+D%!&D"L"!T:&%T(')E<75IE@4G87C*`E(@*&9O?P(-F5A;;4%X'-Y -MU`P#P!`![``-S!`![``&'"0&C`%0@;VYL>0H#`#@( -M`+(``1X#`*8$`@P"(2!B-PEQ4,`4&EN9&5PJ@`E;G0B`0`8"5!AP,1<#4`T6%T979E6QE(&%P<')OR`,`R0@" -M^@#0=&\@:&%V92!M=6QT:3$,!*D``@$$`+D(`/X-%6Z>`%`@(&)S9",'(75S -MO`$`/06#;B!I=',@(D`\`!(BO0012!F -M0"0:7,@97-P -M96-I;@0!T`$"J@$`.@@P.B`BDPH!#A$)V@T3(KD"`-X.(F%NZ`(`I0<`$0," -M6@<0+&,`0&1E8N9V]O9VQE -M+F-O;2]P+VH`$2\Z`"!S+VD``),``6<`47-U8FUI9P!P96YH86YC9<\``*8` -M!C@`,BP@<-H0`BP``#L```0#`$L'`1<)X65S="!V:6$@1VET2'5BP@`"D`"A -M7!1`GD1(`\A$`%@)S82!F=6QL+98( -MF-%#A)B!P`2>`<``$D! -M`)()`"<`02H@97@;$T!S.B!3,@-4P``7P%C875T:&]R:1``EPT!\@(`P1,2+NT/ -M4'1O<"UL#`0#Q0P`,`0&";8""',5`.L%`>X/\`4@*B!.15=3("T@ -M:&EG:&QI9VAT<]P`,')E8]D4`C$%`Z`"DD-/4%E)3D<@+0P%`$(4`,H'(61O -M7P8!AP4`S@#`*B!)3E-404Q,("T@9`HQ86QLCP0!#0``BA8`OP`"*0`#0`41 -M+3P``5X1`A@`8&-O;F9I9[(6%2T,``)$`+5S8W)I<'0L('-E96<``"@%`ED6 -M`F,(@2H@0TUA:V5,U`0Q='ATB``A<'5G$#`@(F,T!A$B)`,`.`PI;VQ-``)6 -M`0;K`P$I`0`6"0".`0]M`0$`(`T0=3T3`A`7)`HGL``C92>M``,D!`"3``!. -M`/``+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C_P```@`0+60"`)\`!*@``-D. -M"*($$BP:#@#7"P!9"Q!YR@4!]@$C97*N`05P`"1I;F0`@2YH+FEN"@DM]`<` -MYA,2\% -M1FYA;'.=`!)S/@M/:6YS:60:____________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________________________]J4&ME2!F;W(@:L`D'-A -M;64@9G5N8S`<``$D!0'-U8V@G`%`J(&5X84D`U',Z(%-O -M;64@6]U(&UA>2!F:6YD('5S969U;"\"!D4` -M42]M:6YIA0$18>,!46%C="!S8`"A(&1E;6]N2#R`I!I -M;VYS+@H*5&B=`?("<"UL979E;"!D:7)E8W1O%#36%K -M94QI\`!,GK0`#)`0`DP``3@#U`2YA -M;2P@86-L;V-A;"YM-"SA`$!E+F%C_P```@`2+50`)'1OJ``,H@2R+"!O;FQY -M(&YE961\`#%M86GV`2-E7-T96TZ"B`J(+@$=2XQ(&5X<&R#`@,O`P!"`0(A``2:`P,S``"(!`\T -M``L`(@`,-0`O870T``PH870S``8!!H`N,R!G:79E2XS30`"]P,2(FL#!:L``20`4"(@ -M=71II`59(&-L87-$``'O!49N86QSG0`P`D09BP``;<&42H@1TY5=0$"-0(B("BK"0"Y`0`:`$%L -M;VYG4`9B;F%M97,L$`!3;&EN:R`1``!C`%)S<&%R'1E;J+``-J`0`9`]$J(%!/4TE8 -M('5S=&%R6P`"$``R<&%X-`,"60<#>`('(0"P;V-T970M;W)I96X!`P!@`@$> -M`*%35E(T($%30TE)=`(!%``"4P`/,@`%84)I;F%R>2X`P"`H8FEG+65N9&EA -M;J(!8VQI='1L91$``OH`\0))4T\Y-C8P($-$+5)/32!I;;<"$2AX""!O<,L# -MP&%L(%)O8VMR:61G944`8DIO;&EE="D!`>\!`DD`-%I)4%8#!$``('5N,0LP -MFEP,A8`!'P!32],6E<=`*)L -M>FUA+"!L>FEP$P,O>'HC```9-!0`"0@!```*56-R96%TSP`!=00/!@$"`JH# -M`[\#`KP"#Q\#&#`B&-E<$`%`+D%!&D"42!T:&%T0PXQ:7)E40`!\P,!R@(@("@6!0$T -M!`"$`0,S!`#T`V`L(&5T8REF"@+Z`P"I`@8B!`&&`0+:``^6`P4!R`-A(FYE -M=V,BFP,!,P`GD#`*4#(71EVPAA.@H*("H@+1`0:2`*<&AE879I;'G\"#9E -M86VU!0(1"X`N("!4:&5R9;T/(VYOX@<`@@(#WP@`DP1!(&EN+;D``2<0`BT`",T`%&_Y -M"'`I+"!I="!W<`!!(&=E=!D3`5T*`*0$-R!);FX`-RP@:9X``5$!`YL`(F5N -MR0$'+0``?``+<0`H9&41``/&`A$L\``"@```C0X`E@$`%@$`0``@86<##A%T -M\0F18V]RP,B:67-#P%O`P/G"B!D=1D-`)\#$'.% -M`2-O9H@!`(X2$"UV```S#`#W"!%IM`\`A`!R96YV:7)O;@\+$7>0`P&@`A!M -MV`$3<3`<0-0&)A8VOR`S%F2W,`))E9"!O=71P=73O -M`@!@!/$#;V)J96-T+7-T>6QE(&%P<')OR`,`^10"^@#0=&\@:&%V92!M=6QT -M:<,3!*D``@$$`+D(52!O<&5NG@`3(!40`&H0``H!$6DA"&-I=',@(D`\`!(B -MO0012!F4X.``P1$2(A`0!:""`L(E`(H"P@8V%P86)I;&D2%`8#`07Q -M``+S#P$_#@CV!0&7`8`@:6YD:79I9&P.`]L(`(4``#H2`D(``*P+`-$``#8! -M(71OK`TP9&%TUP``!0X6.BX!`L@)`#T`$F'L`@#)"@$K`#-I;B`G`0!%!3-A -M9&2.`AAA]PP!J0H#'@]19FER41`.'1E;F0@ -M;&EB87)C:&EV92X*"B`J($]N(')E860L(&-O;7!R97-S:6]N(&%N9"!F;W)M -M870@87)E(&%L=V%Y2!A -M8V-E<#4`T6%T979E2W,`))E9"!O=71P=70&`>!4:&4@ -M;V)J96-T+7-T>1`"4'!P!E -M('-O;64@=71I;&ET>3X`!8P``0`"\05R;W9I9&4@96%S>2UT;RUU"!I;G1E0#\`)N86UE('-A>7,N"E)%041-12X`!^@&X2!B=6YD;&4N -M"@I1=65S^@*@/R`@27-S=65S/U(`URH@:'1T<#HO+W=W=RX@!S!O3``!( -M`1!HN`*P9F]R(&]N9V]I;FH&0&%N(&FW`!`L(00!_``!#P"A('1R86-K97(@8B!$!G -MF-A="P@8@<`$G@'``!)`0"2"0`G`%`J(&5X84D`0',Z -M(%,R`U1S;6%L;!4`!#X!`%(#(6%T'`@@;6'F!"!N9-`",69U;"\"!D4`$"]# -M"@&%`1%A!@E186-T('-@`+`@9&5M;VYS=')A=+'2(`")P=;H+(")C-`81(B0#`#@,*6]L30`"5@$&ZP,` -ME``!%@D`C@$/;0$!`&8(('5SW0H`V@$T90HGL``C92>M``-G`0"3``!.`/`` -M+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C_P```@`0+:("`)\`!*@``&H+"*($ -M82P@;VYL>=<+`GP`,6UA:?8!(V5RK@$%<``D:6YD`($N:"YI;@H)+?0'4FQA -M=&5S9P`18C0"`W(!`K4`8`H*1W5I9/,`*"!$5`8$T@$"=0`!MP%PP`( -M2PE`:&%R9!8,`3`&!%L!`4<``(X!86UO9&5R;H\``.@!`+P'<"!V87)I86Y( -M"0":!3!M86[X"T%P86=E.```,0XD``$=`U=H+`#L'`2,)"=H1`,$",&5C=)D#$62V#P,<`@5X"1!F -M!A(!MP91*B!'3E5U`0(U`B8@*`0+`!H`(VQOO`4`K0LB+ -M``-J`0`9`[$J(%!/4TE8('5S=+`1!!``#XH,`P%\``(Q`+!O8W1E="UO\!`DD`-%I)4'4$!$``('5N -M,0L`[!,`UA!@"T4``("`+D%!(D1`FL4`$,.`-,3`%$``;$6`0`&@`0I:7-N%")B98@%`$`$`5X!.&YE=[4#`/`$`/T"`Y\! -M`'L``8<)`2L5`DH,`PH#`#@(`&\0%'3N$@(,`B$@8C<)`(P*`8\8`[@4`0P` -M$&$,`0+4$`!H``([`!%EG!8`/0$A=F5S`Q-Y0P!0:6YD97"J`"5N="(!`$0- -M`7D9`$(%$F]L#0:P"U0@5VEK:5(,`PP3,&AO=U$/`;,#$&2M`0/:``+W$P4T -M&`3\!`#S#@!0!@/-``%P``*`%P+$!0]D&O__________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M________________________________________'E!U9&EN9RX1``#R!2!' -M3E4@;&]N9R!F:6QE;F%M97,L$`!3;&EN:R`1`*%A;F0@`*935E(T -M($%30TE)%``"8P`/,@`%84)I;F%R>2X`\P<@*&)I9RUE;F1I86X@;W(@;&ET -M=&QE$0`"^@#P'TE33SDV-C`@0T0M4D]-(&EM86=EFEP/@$Q:6]N1`!=8GII<#(6``1D`4TO3%I7'0"B;'IM82P@;'IID#`*4#`.<#]A)U2!S -M=')E86VU!>!S>7-T96TN("!4:&5R92P`D&YO(&1I-R86YD;VT@86-C97-S+GD`!I<` -MD&ES(&1EU`P"C!`![``'.`!!VFP0` -MT082$N("!)9B!Y;W4@9&]N)^P!`+8`\0)I8VET -M;'D@:6YV;VME(&$@<.L`('5L60B@96%T=7)E("AS=2\!&7,<`A!AZ0`'+0`$ -M10<#(@("F0%P*2P@:70@=W``X"!G970@<'5L;&5D(&ENI`0W($EN;@`W+"!I -MG@`!40$#FP`B96[)`07L#$7`U`-%A=&5V -M97(@8FQO8VMS\```[@2X'<70@82!T:6U7`W%O8!(71O(@`%H0!A="!O;F-EA0`A3VZ0`QMEPP`"Y`(R<')O.@$! -MA0%18W1L>2W,``"."5)U='!U=.\"`&`$\0-O8FIE8W0M2!B=69F97(@)`@`90`$<@&%82!S;V-K -M970^`TEW:7-HN@3`P"`,D*`2L`,VEN(">D``,P``*,! -M!H`%,7=A;H@`$'0V!`5%`0!@```:!!!TC@7,N -M"E)%041-1;L&!^@&X2!B=6YD;&4N"@I1=65S^@*@/R`@27-S=65S/U(`URH@ -M:'1T<#HO+W=W=RX@!S!O3``!(`1!HN`*#9F]R(&]N9V]8!Q@@9`!P9&5V -M96QO<#P%)BP@_`Y`9&]C=10``:P(`3<,`'$``#H`(6YK70$`70`&8N9V]O9VQE+F-O;2]P+VH`$2\Z`"!S+VD``),``6<` -M47-U8FUI9P!P96YH86YC9;L``#8"!C@`@RP@<&QE87-E+```.P``!`,`2PB!$!G0&";8"(FENU@0`I`H`ZP4$O0+P`DY%5U,@+2!H:6=H -M;&EG:'1S7`8PM```Z#S`@*B"3``!. -M`/``+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C_P```@`0+:("`)\`!*@``-D. -M"*($$BP:#@#7"P!9"Q!YR@4!]@$C97*N`05P`"1I;F0`@2YH+FEN"@DM]`<` -MYA,22XS]!0P86EL[P0R92`B:P,%JP`!)``4(@L+62!C;&%S1``!'PE& -M;F%L``'?`5P#R*71H92!A=71H;W)S('=I=&@@86YY('%U97-T -M:6]N'2(`#%P=70I`/D#(F-M86ME -M(B!B=6EL9"!T;V]L30`"5@$&-0$!*0$Q(&EN3`$/;0$!,&%R91`"$F3:`35E -M"B>\`!,GK0`#9P$`DP``3@#U`2YA;2P@86-L;V-A;"YM-"SA`$!E+F%C_P`` -M`@`2+50`)'1OJ```(`$P9&ES7P(0=4$!LBP@;VYL>2!N965D?``Q;6%I]@$C -M97)<`05P`"1I;F0`\@,N:"YI;@H)+2!T96UP;&%T97-G`!%B-`(!9@$39;4` -M8`H*1W5I9/,`DB!$;V-U;65N=($!`,4!,F%L;'4``/,!]0H@'!L@P(#+P,`0@$"(0"#('!R;V=R86TS`$]C<&EO-``+ -M`"(`##4`+V%T-``,*&%T,P`'K0/P!#,@9VEV97,@86X@;W9E2!A``"/`&<@)V1O8R>]!;!I;@IA(&YU;6)E2QN``5H`S!U=&^3!@#_`A!YP0(P96-TF0,19-4``QP"!<(&$&8L -M``&W!E$J($=.574!`KH!)B`HN0$`&@!!;&]N9U4"8FYA;65S+!``4VQI;FL@ -M$0``8P!A`@@;W#+`\!A;"!2;V-KB,` -M`!DT%``)"`$```I58W)E873/``%U!`\&`0("J@,#OP,"O`(/'P,8,")R9?X( -M46-T960B1P,"3P#$+"!W:&EC:"!W:6QLB@`!5@`%R@%A(&5X8V5P0`4`N04$ -M:0+1('1H870@U`P#P -M!`![``.?`0![``&'"0&C``)*#`,*`P`X"`"R``$>`P"F!`(,`B$@8C<)`&H( -M,6%B;``&`(P*`0P``2P+`@0!`&@``CL`0F5A8V@]`2%V97,#$WE#`%!I;F1E -M<*H`)6YT(@$`&`D`#P\08T(%$F]L#08U"E0@5VEK:5(,,&EN9\D`,&AO=U$/ -M`;,#%V26"@(J`2%/;C\(`/<,`F`&`P,!`_@``8@)4&%L=V%Y1@$`W0$J962* -M"`)'`'!))W9E(&%T+0T`C`<`P0^0:6YI;6EZ92!S#@T28U((07!O;&R4#5$N -M("!)9O4(4&1O;B=TJ`"097AP;&EC:71LV0EB=F]K92!A^@\18W\*,69E830+ -M,"AS=2\!!?L*`*D`("!A00`!)Q`"+0`(S0`4;_D(<"DL(&ET('=P`'$@9V5T -M('!UG`T0:7H+1R`@26YN`#``%1`0.;`")E;LD!!RT``#X`"W$`*&1E -M$0`#Q@(1+/```H```(T.`)8!`!8!`$``(&%G`PX"4`.18V]R0`P&@`A!MV`$32X'<70@82!T:6U7`W%O -M8!(71O(@`%2@!2="!O;F-\$B)/ -M;AP."\,``N0",G!R;SH!`84!46-T;'DMS`"2960@;W5T<'5T[P(`8`3Q`V]B -M:F5C="US='EL92!A<'!R;\@#`$,2`OH`X'1O(&AA=F4@;75L=&EP)0``(040 -M=A(#0')E86VY"`#^#15NG@`3(!40`&H0``H!`#T%@VX@:71S(")`Y0`2(KT$ -M$7,P#@)C!08!`6!I='-E;&93`0!]!!`O=@1@=&5N('5S;P8`-PP!<@$R9G5N -M6!($DP$!=08`,@`U(&%NI``"(Q-0;'D@9G)@``S0*%82!S;V-K970^`TEW:7-HN@0!)@\#60\`#B)A;N@"`*4'!C0*$"QC`$!D97-PWP``;`0!Y`,`7,N"B05 -M$6:X#01Q%K0@8G5N9&QE+@H*41$6H#\@($ES7,@<')O9'5C97,@8V]R6]U('1O(&AA=F4@;75L=&EP)0`#J0!P`/,-("!B -M!E -M('-O;64@=71I;&ET>3X`!8P`,"!T;WP!\0-V:61E(&5A2!D8737`%9UX`0!V``##`!%EW@(!O@`%RP$` -MTP`#HP%#+B`@2:0!(6%NB``2=%T``38"`5L#`!\!`#L!061I"!I;G1E&%)`$!S.B!3,@-4`0-)`#!C;VY#`O`".B`@5F%R:6]UP`` -M7P%Q875T:&]R<\`%`1\&`?("`DT'$`H5"%!T;W`M;`P$`W8%`#`'`4$`$&DD -M!0FV`B)I;O@$(FEOX08$O0+P`DY%5U,@+2!H:6=H;&EG:'1S7`8P'2(`#!P=71>`C`@(F,T!A$B)`,`J@2!N965D?``Q -M;6%I]@$C97*N`05P`"1I;F0`@2YH+FEN"@DM]`=2;&%T97-G`!%B-`(#<@$" -MM0!@"@I'=6ED\P`H($14!@32`0)U``#S`8`@PH"MP(A960N -M"P!;!!!SU`80;A$,`-8"`),``'4``!<"`/D$`7$``7$*")<``9P)(RXS30`` -M[P0R92`B:P,%JP`!)``4(@L+62!C;&%S1``!'PE&;F%L=H+`#L'`2,)@&%U=&]M871I_P(0><$",&5C=)D#$60Y"0,< -M`@5X"1!F+``!MP91*B!'3E5U`0(U`B8@*`0+`!H`06QO;F=5`@"M"R)S+!`` -M``4+$R`1``!C`%)S<&%RB,``!DT%``)"`$```H"G!`% -M.@$`=00/!@$"`J\!`[\#`KP"#Q\#&#`BP`!APD!*Q4"2@P`31$B:7*"$1!I>0<#[A("#`(A -M(&(W"0","C%A8FP`!@","@$,`!!A#`$"U!``:``".P!"96%C:#T!(79E4,`4&EN9&5PJ@`E;G0B`0!$#0`/#Q!C0@42;VP-!K`+5"!7:6MI4@P##!,P -M:&]W40\!LP,09*T!`]H``O<3(4]N/P@`]PP"8`8`\PX`4`8#S0`!<``"@!<" -MQ`4J962*"`)'`#!))W8-&``A%0",!S!T;R`A$#!M:7I2%P"U"`)2"$%P;VQL -M-A(&Y!1!9&]N)^P!D&5X<&QI8VET;-D)8G9O:V4@8?H/$6-_"@/.$2`@*-(0 -M`'4,"!P"$&&R`0$G$`(M``C-`!1OP,1 -M<#4`8F%T979EFUA+"!L>FEP+"!A -M;F0@>'HC```9-!0`\`P*5&AE(&QI8G)A"!I;G1E'1E;DT!L7,@*&9O$E33SDV-C`3`%HW+5II<#D`-EA!4A$`0PI7 -M:&4#`@#D`00%`A$L_`%A2!S=')E86WM`>!S>7-T96TN("!4:&5R92P`D&YO -M(&1I4,`4&EN9&5PJ@`B;G1_`!!R.P0`!`"4=&EC;&5S(&]N@0$$ -MK@#P`%=I:VD@97AP;&%I;FEN9XD`,&AO=_@``O4``(X$`RP``BH!(4]NJ@`< -M+`,!`]D"`G``0&QW87E&`0#=`?(!960@875T;VUA=&EC86QL>4<`L$DG=F4@ -M871T96UPQ`/@=&\@;6EN:6UI>F4@2!I;G9O:V4@82!PZP`@=6PW!"!E85D" -M0"`HD`!RT`!^\%`(`!`ID!<"DL(&ET('=P`.`@9V5T('!U -M;&QE9"!I;J0$-R!);FX`-RP@:9X``5$!`YL`(F5NR0$'+0``?``+<0`H9&41 -M``.J`!$L\``"@``B;F6.`@`6`0!``&)A9V%I;G-'`J!C;W)R97-P;VYD)P0( -M20`-6@`">P,Q:65SPP`!;P.A86QS;R!R961U8[D%,&4@`(&5N=FER;V[7`C%S('=N`@&@`A!MV`$36QE(&%P<')OR`,`PP<"^@#@=&\@:&%V92!M=6QT:7`E -M```A!1!V$@,`!04`N0A5(&]P96Z>`%`@(&)S9",'(75SO`$`/06#;B!I=',@ -M(D#E`!(BO01&P`28D(``"P$`-$``#8!(71OFPDP9&%TUP!6=7)C93HN -M`0+("0#"`!)A[`(`PPD!*P`S:6X@)P$`^`(@863\`@!B`!%A_`@$J@$`>08A -M;W7W!%%F:7)S=)("`*8!(&$@0P41;S$*`/8`%BYT``/9`P*G`0":"0*<`0&% -M``:X`0!V``##``"\`Q)EDP`"3P7,N"E)%041-1;L&!^@&X2!B=6YD -M;&4N"@I1=65S^@*@/R`@27-S=65S/U(`URH@:'1T<#HO+W=W=RX@!S!O3 -M``!(`1!HN`*#9F]R(&]N9V]8!Q@@9`!P9&5V96QO<#P%<2P@:6YC;'6]!4!D -M;V-U%``!K`@!-PP`<0``.@`A;FM=`0!=``9S`%`@;6%I;`<"0FQI%EB!$!G&%)`$!S.B!3,@-4`0-)`#!C;VY#`O`".B`@5F%R -M:6]UP``7P%V875T:&]RT/4'1O<"UL#`0#Q0P`,`0& -M";8"(FENU@0`=`P`ZP40<],-\`4@*B!.15=3("T@:&EG:&QI9VAT'2(`")P==8-(")C-`81(B0#`#@,*6]L30`"5@$&ZP,!*0$`%@D`C@$/ -M;0$!`+`,('5SW0H`V@$T90HGL``C92>M``-G`0"3``!.`/``+F%M+"!A8VQO -M8V%L+FTT"0T#[0`P+F%C%P$``@`0+:("`)\`!*@``-D."*($$BP:#@#7"P)\ -M`#%M86GV`2-EPH"MP(`A1(A86R) -M!T!S97%UZ@@0=&%R -M+C54`0CQ!`4^$A%S8P0Q<&]PY0\#G`$$>P`(2PE`:&%R9!8,`3`&!%L!`4<` -M`(X!86UO9&5R;H\``.@!`+P'<"!V87)I86Y("0`B##!M86[X"T%P86=E.``` -M,0X`SA0"^@$`G@`!WP%7)V1O8R>]!9!I;@IA(&YU;6+R#!=FD0<$.P''"@I9 -M;W4@`""(&EN'!L86EN3`1!F+``P'1E;J+``-J`0`9`]$J(%!/ -M4TE8('5S=&%R6P`"$``P<&%X20-Q97)C:&%N9WX!-VUA="$`L&]C=&5T+6]R -M:65N`0,`8`(!'@"A4U92-"!!4T-)270"`10``E,`#S(`!6%":6YA\!`DD`-%I) -M4%8#!$``D'5N8V]M<')E<],&<&]R(")D969^!A`BJ0($&```H00C:655`0## -M`0"B`85"4T0@)V%R)U(``?@`$2?]`Q`GNP($/0%:-RU::7`F`-A-:6-R;W-O -M9G0@0T%"+``Q3$A!"@,Z3%I(,@`Z4D%2$0`86!$``=4#!;@"`'@#"*\"8&AA -M;F1L9;L"$'FW`P"V!`:X`C!B969*`W!E=F%L=6%TR@(`(``#F0,"SP(0=?8% -M$&]Q`@"V`@)#`@$*`!$@@P&B4E!-('=R87!P94X"16=Z:7`^`3%I;VX8`5UB -M>FEP,A8`!'P!32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9-!0`"0@!E6-A -M;B!C0`&@`0`#@Q397-I9VXE#!)EO@(`0`0!,`0X;F5WM0,`\`0`>P`#GP$`>P`! -MAPD!HP`"2@P#"@,`.`@`L@`!'@,`I@0"#`(A(&(W"7%R96%D86)L``8`C`H! -M#``!+`L"!`$`:``".P!"96%C:#T!(79E4,`4&EN9&5PJ@`E;G0B`0`8 -M"5!AD` -M!RT`!"T'`,\*%&_Y"'`I+"!I="!W<`!Q(&=E="!P=9P-(&ENI`0W($EN;@`W -M+"!IG@`(FP`B96[)`02UV```S#`#W"!%IAP8`A`!P96YV:7)O -M;M<",7,@=Y`#`:`"$&W8`1-R6@,%,`(`6P`"?P`1>7L#$7`U`-%A=&5V97(@ -M8FQO8VMS\```[@@``S0*%82!S;V-K970^`TEW:7-H -MN@0!)@\#60\`4X.475S92`B(0$`6@@@+")0"+$L -M(&-A<&%B:6QI=/8"!`,!!?$``O,/`;<$"/8%`9P" -M`,D*`2L`,VEN("#U%F:7)S=)("`*8!(&$@ -M0P41;UD1`/8`%BYT``/9`P*G`0"_``*<`0&%``:X`0!V``##``"\`Q)EDP`" -M,0\@;'ED`0#,``"C`0:`!3%W86Y_!1)T'0\!-@(!6P,!&@00=(X'(7-K+`,0 -MA$)P`$`B0`P;6%K>0"0:7,@97-P96-I;@0!T`$"J@$` -M.@@P.B`BDPH!#A$)V@T3(KD"`-X.(F%NZ`(`I0<&-`H0+&,`0&1EF-%#A)B!P`2>`<``$D!`)()`"<`02H@97@;$T!S.B!3 -M,@-42!A;F0@861D(&ET('1O(&$@=&%R(&%R8VAI=F4@=VET:&]U=`H@ -M("!F:7)S="!W2!F8<`\`5S;V-K970N("!)9B!Y;W4@=V%N=$0`$G1=`!(O/0``8``P -M:65S,P!09&ES:RQ.`/`,0#Q+6ES(&5S<&5C:6%L;'D@96%S>2X*"B`J($YO=&4Z(")P87@@ -M:6YT97)C:&%N9V4@9F]R;6%T(B!I7,N"E)%041-15``1"!L:6)M -M`=%B=6YD;&4N"@I1=65SK@"@/R`@27-S=65S/U(`UBH@:'1T<#HO+W=W=RXX -M`$`N;W)GDP``2`$Q:&]MIP"`(&]N9V]I;F8$(&YDT`(Q9G5L+P(&10!1+VUI;FF%`1%A -MXP%186-T('-@`+`@9&5M;VYS=')A=+M``,D -M!`"3``!.`/4!+F%M+"!A8VQO8V%L+FTT+.$`0&4N86/_```"`!`MH@(`GP`$ -MJ``,H@2R+"!O;FQY(&YE961\`#%M86GV`2-E7-T96TZ<`<"N`1U+C$@97AP;(,"`R\#`$(!`B$`!)H#`S,``(@$#S0` -M"P`B``PU`"]A=#0`#"AA=#,`!@$&@"XS(&=I=F5SWP:`;W9EP$2+8($-7,N-:H(`)X%$67[`P#R -M`(!M871S('-U<'\(!&,"!98!`$P```H"D"XU+"!M=')E90D``&\`7G1A``&I`5"`"X!!,B?P(R+F@BJ0"` -M:&4*`D09BP` -M`;<&42H@1TY5=0$"-0(F("@$"P`:`$%L;VYG50(`K0LB+ -M``-J`0`9`]$J(%!/4TE8('5S=&%R6P`"$``/B@P#!R$`P&]C=&5T+6]R:65N -M=!<$,7!I;QX`IE-64C0@05-#24D4``)3``\R``5A0FEN87)Y+@#`("AB:6FEP,A8`!'P! -M32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9-!0`"0@!```*56-R96%TSP`! -M=00/!@$"`JH#`[\#`KP"#Q\#&#`B&-E<$`%`+D%!&D"42!T:&%T0PXQ:7)E40`!`1`! -MR@(@("A3"@$T!`"$`0-$!`#T`V`L(&5T8RGO"P+Z`P"I`@!H$0*-``&&`0+: -M``^6`P4!R`-A(FYE=V,BFP,!,P`G?P(-F5A;;4%`A$+<"X@(%1H97(T$2`@;M82,7)E8S`1`]\(`),$02!I;BVW -M#X(@;6]D:69I8^4,\@%OP`!APD!HP`"2@P` -M31$B:7*"$1!I>0<#[A("#`(A(&(W"0","C%A8FP`!@","@$,``$L"P+4$`!H -M``([`$)E86-H/0$A=F5S`Q-Y0P!0:6YD97"J`"5N="(!`$0-``\/$&-"!1)O -M;`T&-0I4(%=I:VE2#`,,$S!H;W?X``&S`Q!DK0$#V@`"*@$A3VX_"`#W#`)@ -M!@#S#@!0!@/-``%P`%-L=V%YF4@0`P&@`A!MV`$3!<1<_`` -M`.X',2!I=&0!,EEO=><3`<0-0&)A8VNO$S%F6QE(&%P<')OR`,`@0L"^@!0=&\@:&$Y%D!U -M;'1IPQ,$J0`"`00`N0A5(&]P96Z>`!0@]`\A=7-U!Q!IF@%S(&ETFEP,A8`!"8`32],6E<=`/D#;'IM82P@;'II -M<"P@86YD('AZ(P#!"DYO=&5S(&%B;W5TE`!R;&EB=$`\"YT96-T=7)E -M.@H*("H@5&AI48!`-T!\@%E -M9"!A=71O;6%T:6-A;&QY1P"P22=V92!A='1E;7#7`>!T;R!M:6YI;6EZ92!S -M="L`L"!L:6YK('!O;&QUN`'A+B`@268@>6]U(&1O;B?L`0"V`/$":6-I=&QY -M(&EN=F]K92!A('#K`(!U;&%R(&9E85D"0"`HD`!RT`!P8# -M`(`!`ID!<"DL(&ET('=P`/``(&=E="!P=6QL960@:6XN/@`G26YN`# -M``%1`0.;`")E;LD!!RT``#X`"W$`*&1E$0`#Q@(1+/```H``(FYEC@(`%@$` -M0`!B86=A:6YS1P*@8V]R7L#$7`U`-%A -M=&5V97(@8FQO8VMS\``0:$,$(6ETH0!!66]U717`F$@82!T:6U7`W%O -M`+$@(&)S9'1A3X`!8P``0`"\05R;W9I -M9&4@96%S>2UT;RUUX`0!V``##``"\`Q)E -MDP`"3P0"0:7,@97-P96-I;@0!T`$"J@$` -M.@CS`SH@(G!A>"!I;G1E`<``$D!`)()`"<`4"H@97AA20!` -M8$(&YDT`(Q9G5L+P(&10`0 -M+T,*`84!$6&>"E%A8W0@"`"X!!,B!0XR+F@BJ0`R -M:&4*7PP0(+`)`/H``!0`!.D&`W((`G\"-&UO5$P`P%&!E+``-J`0`9`[$J -M(%!/4TE8('5S=+`1!!``#XH,`P%\``(Q`%9O8W1E=*\4`&`"`1X`H5-64C0@ -M05-#24ET`@$4``\R``L00FT1$7DN`+$@*&)I9RUE;F1I8=018VQI='1L91$` -M`OH`\0))4T\Y-C8P($-$+5)/32!I;;<"$"@X#C`@;W#+`\!A;"!2;V-K[ -M`@0]`5HW+5II<"8`V$UI8W)OQ=4 -M`)H`-6QZ-*@!`.47"0@!```*`IP0!4L!`'4$#P8!`@*O`0._`P*\`@\?`Q@P -M(G)EH`T`$!81(D<#`D\`PBP@=VAI8V@@=VEL;.L8`'`(`,,/`U\!0',@97@M -M%``"`@"Y!02)$0(+%P-:%P%1``7I$C!S("A3"@$T!`"$`0,S!`#T`V`L(&5T -M8RGO"P+Z`P"I`@!M``*-``&;`0+:``_(`PIA(FYE=V,BFP,!,P`G4P`T&-P:6\N-2P@;71R964)``!O`/(*=&%R+C4@<')O=FED92!D971A -M:6QE9"!I;E(`D&EO;B!A8F]U=$T`XW-E"B`@('!O<'5L87(@F``2("D`\PIS -M+"!I;F-L=61I;F<@:&%R9"UT;RUF:6YD5``2FEP/@$Q:6]N,`!=8GII<#(6``1\`4TO3%I7'0"B;'IM82P@;'II -M&-E<$`%`+D%!&D"L"!T:&%T(')E<75IE@4G87C*`E(@*&9O?P(-F5A -M;;4%X'-Y`3AN97>U`P#P!`![``-S!`![``&'"0&C`%0@;VYL -M>0H#`#@(`+(``1X#`*8$`@P"(2!B-PEQ4,`4&EN9&5PJ@`E;G0B`0`8"5!A48!`-T!*F5DB@@"1P"P22=V92!A -M='1E;7",!^!T;R!M:6YI;6EZ92!S=+4(`E((4'!O;&QU(@=1+B`@26;U"%!D -M;VXG=*@``+8`4&EC:71LV0F!=F]K92!A('#K``%_"C%F96$T"S`H``%1`0.;`")E;LD!!RT``'P`"W$`*&1E$0`#Q@(1+/`` -M`H``(FYEC@(`%@$`0`!B86=A:6YS1P*18V]R0`P&@`A!MV`$38!(71O(@`%H0!A="!O;F-EA0`A3VZ0`QMEPP`"Y`(R -M<')O.@$!A0%18W1L>2W,``"."5)U='!U=.\"`&`$\0-O8FIE8W0M7,"!8P``#\`!)4.0&5AP"`,D*`2L`,VEN("#U%F:7)S=)("`*8!(&$@0P41;U`'`/8`%BYT``/9`P*G`0"_``*< -M`0&%``:X`0!V``##``"\`Q)EDP`",0\@;'ED`0#,``"C`0:`!3%W86Y_!1)T -M'0\!-@(!6P,`8PP`,P!!9&ES:RP#`+$0$'*?!)EN=F5N:65N8V7``0")`#!M -M86MY`)!I0#`',*T2!S87ES+@I214%$3442 -M!@<4!]%B=6YD;&4N"@I1=65S^@*@/R`@27-S=65S/U(`UBH@:'1T<#HO+W=W -M=RXX`$`N;W)GDP``2`$0:+@"$&:Q#S-N9V]8!Q<@3`>`(&1E=F5L;W`\!0@9 -M$02Z$0&L"`$W#`!Q```Z`"%N:UT!`%T`!G,`4"!M86EL!P(P;&ESOQ`!G0`0 -M5)D!`.41`.%E8$(&YDT`(Q9G5L+P(&10`0+T,*`84!$6&>"C1A8W1[$W!D96UO;G-T -M.14@;F<^``"`!094`@-)`#!C;VY#`F$Z("!687+N$V!I=&5M$0(8`&!C;VYF:6>R%A4M#``"1`"UM`Q$SM@L`$!20(&]V97)V:65W\P(`JP`% -MP`L`<04P=VAOD0(4*J0*A5]R96%D+C,L$``!^`@-$0!17V1I4$`(&EN^``(M@)P -M:6YF;W)M8:D!,"!F:34!`'P`\`0J($Y%5U,@+2!H:6=H;&EG:'1SW``P@`K1#3U!924Y'("T@=U$!8F-A;B!D;Y\`,W1H:2D`\@))3E-4 -M04Q,("T@:6YS=&%L;'4```T`(7)U*@(#*0"!4D5!1$U%("T\``&5``*3`+!C -M;VYF:6=UM``,D!`"3``!. -M`/4!+F%M+"!A8VQO8V%L+FTT+.$`0&4N86/_```"`!(M5``D=&^H``RB!+(L -M(&]N;'D@;F5E9'P`,6UA:?8!(V5R7`$%<``D:6YD`/(#+F@N:6X*"2T@=&5M -M<&QA=&5S9P`18C0"`68!$V6U`&`*"D=U:63S`%`@1&]C=9D%`H$!`,4!,F%L -M;'4``;`:`;W9E]!;!I;@IA -M(&YU;6)E"`"X!!,BO0(R+F@BJ0"`:&4*2R"```[!P$C"4!A=71ODP8`_P(0 -M><$",&5C=)D#$635``,<`@5X"1!F+``!MP91*B!'3E5U`0(U`B(@**L)`+D! -M`!H`06QO;F=0!F)N86UEB,``!DT%``)"`$```I58W)E873/``%U!`\& -M`0("J@,#OP,"O`(/'P,8,")R9:`-46-T960B1P,"3P#$+"!W:&EC:"!W:6QL -MB@`!5@`%R@%A(&5X8V5P0`4`N04$:0)1('1H871##C%I`3AN97>U`P#P!`![``.?`0![``&'"0&C``)*#`!-$2)IF4@``%1`0.; -M`")E;LD!!RT``'P`"W$`*&1E$0`#Q@(1+/```H```(T.`)8!`!8!`$``(&%G -M`PX1=/$)D6-OP,1<#4`T6%T979EP"`,D*`2L`,VEN("#U%F:7)S=)("`*8!$6%P$A%O\0T`]@`6+G0` -M`]D#`J -M#@#G&`Y6#A`L8P!`9&5S<*(``&P$`>0#`',*2!I;G9O:V4@82!P87)T:6-U;&%R(&9E -M871U!E('-O;64@=71I;&ET>3X`!8P``+$!\09P2!D8737`%9UP"`&$# -M`2L`,VEN("7,N"E)%041-15``1"!L:6)M -M`=%B=6YD;&4N"@I1=65S^@*@/R`@27-S=65S/U(`UBH@:'1T<#HO+W=W=RXX -M`$`N;W)GDP``2`$0:+@"L&9OF-A="P@8@<`$G@'``!)`4!S=6-H -M)P!0*B!E>&%)`$!S.B!3,@-40&";8"(FEN8PL`<0L`ZP4$O0+P -M`DY%5U,@+2!H:6=H;&EG:'1S7`8P'2(`#!P=71>`C`@(F,T!A$B)`-I -M9"!T;V]L30`"5@$&ZP,`E``!%@D`C@$/;0$!`&8(('5SW0H`V@$T90HGL``C -M92>M``-G`0"3``!.`/``+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C_P```@`0 -M+:("`)\`!*@``&H+"*($82P@;VYL>=<+`GP`,6UA:?8!(V5RK@$%<``D:6YD -M`($N:"YI;@H)+?0'4FQA=&5S9P`18C0"`W(!`K4`8`H*1W5I9/,`*"!$5`8$ -MT@$"=0`!MP%P=H+`#L'`2,)"=H1`,$",&5C -M=)D#$62V#P,<`@5X"1!F!A(!MP91*B!'3E5U`0(U`B8@*`0+`!H`(VQOO`4` -MK0LB+``-J`0`9`[$J(%!/4TE8('5S=+`1!!``#XH,`P%\ -M``(Q`+!O8W1E="UO`@@;W#+`\!A;"!2;V-K[`@0]`5HW+5II<"8`V$UI -M8W)OFEP/@$@:6]/$WTJ -M(&)Z:7`R%@`$?`%-+TQ:5QT`HFQZ;6$L(&QZ:7`3`R]X>B,``!DT%``)"`$` -M``H"G!`%.@$`=00/!@$"`J\!`[\#`KP"#Q\#&#`BD6$W,*%P!5"`2`!"EIP`!APD!*Q4"2@P#"@,`.`@`W@`4=.X2`@P"(2!B -M-PD`C`H!CQ@#N!0!#``080P!`M00`&@``CL`$66<%@`]`2%V97,#$WE#`%!I -M;F1E<*H`)6YT(@$`1`U087)T:6-"!1)O;`T&L`M4(%=I:VE2#`,,$S!H;W=1 -M#P&S`Q!DK0$#V@`"]Q,%-!@$_`0`\PX`4`8#S0`!<``"@!<"Q`4/9!K_____ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_SI0;F<@;&DN$0``\SUN:R!N86UE'1E;F1E9"!T87(@9F]R;6%T("AI;F-L=61I;F<@04-, -M,P!A3VQD(%8W)P"!87)C:&EV97-+`+=03U-)6"!U"=M=')E92<]`5HW+5II<"8`V$UI8W)O2!A;'-O(&1E=&5C='--`&!H86YD -M;&4,`'!Y(&]F('1HW`'P!VQL;W=I;F<@8F5F;W)E(&5V86QU8702```@``,O -M`A$ZU`!@=75E;F-O<0(!CP(!%``!"@`1((,!HE)032!WFEP -M/@$Q:6]N,`!=8GII<#(6``1D`4TO3%I7'0"B;'IM82P@;'IIP`!S@`0 -M=IL$`-$&$G.C`%0@;VYL>0H#0&UE;G2R``$>`P"F!`(K`#`@8F5``'%R96%D -M86)L``9!=W)I=`P`$&$,`0($`0!H``([`$)E86-H/0$A=F5S`Q-Y0P!0:6YD -M97"J`")N='\`$'([!``$`#!T:6-"!21O;H$!!*X`\`!7:6MI(&5X<&QA:6YI -M;F>)`#!H;W?X``&S`Q!DE@4#+``"*@$A3VZJ`!PL`P$`!`0R;6%T<`!`;'=A -M>48!`-T!\@%E9"!A=71O;6%T:6-A;&QY1P"P22=V92!A='1E;7",!^!T;R!M -M:6YI;6EZ92!S="L`L"!L:6YK('!O;&QUN`'A+B`@268@>6]U(&1O;B?L`0"V -M`/$":6-I=&QY(&EN=F]K92!A('#K`"!U;%D(H&5A='5R92`HD`!RT`!$4'`R("`ID!<"DL(&ET('=P`.`@9V5T('!U;&QE9"!I;J0$-R!) -M;FX`-RP@:9X``5$!`YL`(F5NR0$'+0``?``+<0`H9&41``.J`!$L\``"@``B -M;F6.`@`6`0!``'%A9V%I;G-TSP&18V]RP,Q:65S -MPP`!;P,!;P=16QE -M(&%P<')OR`,`R0@"^@#@=&\@:&%V92!M=6QT:7`E``-3!`(!!`#\"E4@;W!E -M;IX`4"`@8G-D(P2!F)M96UO7,"!8P``0`"\05R;W9I -M9&4@96%S>2UT;RUU0#`',* -MT"!S87ES+@I214%$346[!@?H!N$@8G5N9&QE+@H*475E<_H"H#\@($ES7!1`GH@1`9W)A;18"&%)`$!S.B!3,@-4 -M`0-)`#!C;VY#`O`".B`@5F%R:6]UP``7P%Q875T:&]R<\`%`1\&`?("`-(1$B[M -M#U!T;W`M;`P$`\4,`#`'`4$`$&GD!@FV`B)I;M8$`*0*`.L%!+T"\`).15=3 -M("T@:&EG:&QI9VATPH"MP(`318A86R)!T!S97%UZ@@0=&%R+C54`0CQ!`4^$A%SU@TQ<&]PY0\# -MG`$$>P`(2PE`:&%R9!8,`3`&`J@!`X42`(X!86UO9&5R;H\``.@!`+P'<"!V -M87)I86Y("0`B##!M86[X"Q%PK1] -M!;!I;@IA(&YU;6)E"`"X!!,BXP`R+F@BJ0`R:&4*7PP0(+`)`/H``!0`!.D&`W((`G\" -M$&T:%P/[`$(N("!0B@FR;&5T('5S"FMN;W<0`0&9!F!E`D09@82`;<&`H<8!JH+"``:`/@5#"`6`1````4+#V0:________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M__________________________________________________]H4"`J(&5X -M1!$``/$,86UP;&5S+VUI;FET87(Z(&$@8V]M<&%C="!S&P#T3R!D96UO;G-T -MV`'!I;F9O -M6]U(&-A;B!D;Y\`,W1H:2D`\@)) -M3E-404Q,("T@:6YS=&%L;'4```T`,')U8X$``RD`@%)%041-12`M%`$1`?$#+@H*66]U('-H -M;W5L9"!A;'-O(@(!3``Q8V]P=@8R8V]M6P%#:6X@(KT",BYH(JD`@&AE"G-O -M=7)C+P`19'4!`!0`!.D&`YH#`G\"-&UO68!,&5C=)D#$635``,<`@7"!A!F+``!MP91*B!' -M3E5U`0*Z`28@*+D!`!H`06QO;F=5`F)N86UE'1E;J+``-J`0`9`]$J(%!/4TE8('5S=&%R6P`"$``P<&%X20,B97)9!P-X`@FEP,A8`!'P!32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9-!0`"0@! -M```*56-R96%TSP`!=00/!@$"`JH#`[\#`KP"#Q\#&#`B&-E<$`%`+D%!&D"T2!T:&%T -M(')E<75IP`# -MGP$`>P`!APD!HP`"2@P#"@,`.`@`L@`!'@,`"0$"#`(A(&(W"0!J"#%A8FP` -M!@","@$,``$L"P($`0!H``([`$)E86-H/0$A=F5S`Q-Y0P!0:6YD97"J`"5N -M="(!`!@)``\/$&-"!1)O;`T&-0I4(%=I:VE2##!I;F?)`&-H;W<@=&_U``>6 -M"@(J`2%/;C\(`/<,`F`&`P,!`_@``8@)4&%L=V%Y1@$`W0$J962*"`)'`'!) -M)W9E(&%T+0T`C`<`P0^0:6YI;6EZ92!S#@T28U((07!O;&R4#5$N("!)9O4( -M4&1O;B=TJ`"097AP;&EC:71LV0EB=F]K92!A^@\18W\*,69E830+,"AS=2\! -M!?L*`*D`("!A00`1P,1<#4`T6%T979EP"`,D*`2L`,VEN("#U%F:7)S=)("`*8!$6%P$A%O61$`]@`6+G0``]D#`J60!`,P``*,!!H`%,7=A -M;G\%$G0=#P-%`0!@```:!!!TC@0#`',*F-%#A)B!P`2>`<``$D!`)()`"<`02H@97@$ -M&D!S.B!3,@-48$(&YDT`(Q9G5L+P(&10`/ -M9!K_________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_________V10=&EM90HH$0``\!0@("!O2UB;&]C:V5D(&]U -M='!U="X*"B`J(%1H92!O8FIE8W0M`@#1```V`:!T -M;R!A;GD@9&%TUP!6=7)C93HN`6!C`@&^``7+ -M`0#3``.C`4,N("!)I`$A86Z(`!)T70`!-@(!6P,`'P$`.P%!9&ES:RP#`\0! -MMF-O;G9E;FEE;F-E3`(P('1OB0`P;6%K>0#1:7,@97-P96-I86QL>=`!`JH! -M\P].;W1E.B`B<&%X(&EN=&5R8VAA;F=E(&9O7,N"E)%041-12X` -M1"!L:6)M`=%B=6YD;&4N"@I1=65S^@*@/R`@27-S=65S/U(`UBH@:'1T<#HO -M+W=W=RXX`$`N;W)GDP``:@00:+@"L&9O&%)`$!S.B!3,@-4`0-)`#!C;VY#`O`".B`@5F%R:6]U -MP``7P%Q875T:&]R<\`%`1\&`?("`DT'$`H5"%!T;W`M;`P$`W8%`#`'`4$` -M$&DD!0FV`B)I;O@$(FEOX08$O0+P`DY%5U,@+2!H:6=H;&EG:'1S7`8P'2(`#!P=71>`C`@(F,T!A$B)`,`J@2!N965D -M?``Q;6%I]@$C97*N`05P`"1I;F0`@2YH+FEN"@DM]`=2;&%T97-G`!%B-`(# -M<@$"M0!@"@I'=6ED\P`H($14!@32`0)U``#S`8`@PH"MP(A -M960N"P!;!!!SU`80;A$,`-8"`),``'4``!<"`/D$`7$``7$*")<``9P)(RXS -M30``[P0R92`B:P,%JP`!)``4(@L+62!C;&%S1``!'PE&;F%L=H+`#L'`2,)@&%U=&]M871I_P(0><$",&5C=)D#$60Y -M"0,<`@5X"1!F+``!MP91*B!'3E5U`0(U`B8@*`0+`!H`06QO;F=5`@"M"R)S -M+!````4+$R`1``!C`%)S<&%RB,``!DT%``)"`$```H" -MG!`%.@$`=00/!@$"`J\!`[\#`KP"#Q\#&#`BP`!APD!*Q4"2@P`31$B:7*"$1!I>0<#[A(" -M#`(A(&(W"0","C%A8FP`!@","@$,`!!A#`$"U!``:``".P!"96%C:#T!(79E -M4,`4&EN9&5PJ@`E;G0B`0!$#0`/#Q!C0@42;VP-!K`+5"!7:6MI4@P# -M#!,P:&]W40\!LP,09*T!`]H``O<3(4]N/P@`]PP"8`8`\PX`4`8#S0`!<``" -M@!<"Q`4J962*"`)'`'!))W9E(&%T(14`C`'!L:6-I=&S9"6)V;VME(&'Z#Q%C?PH#SA$@ -M("C2$`!U#`@<`A!AL@$!)Q`"+0`(S0`4;W,$<"DL(&ET('=P`%`@9V5T(-(2 -M`5T*`*0$-R!);FX`!287`9X``5$!`YL`(F5NR0$'+0``?``+<0`H9&41``.J -M`!$L6!$"@```C0X`E@$`%@$`0``P86=A\P\!7PJ18V]R7L#$7`U`&)A=&5V97)X%Q%S\```[@*B!F:6QEFEP(&-O;7!R -M97-S:6]N%0!=8GII<#(6``0F`$TO3%I7'0#_`VQZ;6$L(&QZ:7`L(&%N9"!X -M>B,``!DT%`#Q,@I4:&4@;&EB2!C86X@8W)E871E(&%R8VAI=F5S(&EN -M(&%N>2!O9B!T:&4@9F]L;&]W:6YG(&9O"!I;G1E'1E;DT!L7,@*&9O$E33SDV-C`3`%HW+5II<#D`-EA!4A$`0PI7:&4# -M`@#D`00%`A$L_`%AT!X'-Y -M`>-R86YD;VT@86-C97-S+GD`!I<`\@)I -M`35N97<7`@!2`#!A;F1[``'.`!1V6`,24,`4&EN9&5PJ@`B;G1_`!!R.P0`!``P=&EC\`0D;VZ!`02N -M`/``5VEK:2!E>'!L86EN:6YGR0`P:&]W^``"]0``C@0#+``"*@$A3VZJ`!PL -M`P$#V0("<`!`;'=A>48!`-T!\@%E9"!A=71O;6%T:6-A;&QY1P"P22=V92!A -M='1E;7#$`^!T;R!M:6YI;6EZ92!S="L`L"!L:6YK('!O;&QUN`'A+B`@268@ -M>6]U(&1O;B?L`0"V`/$":6-I=&QY(&EN=F]K92!A('#K`"!U;#<$(&5A60)` -M("AS=2\!&7,<`A!AZ0`'+0`'[P4`@`$"F0%P*2P@:70@=W``X"!G970@<'5L -M;&5D(&ENI`0W($EN;@`W+"!IG@`!40$#FP`B96[)`07L#$7`U`-%A=&5V97(@8FQO8VMS\``0:%<%(6ETH0!!66]U -M2X'<70@82!T:6U7 -M`W%O8!(71O(@`%H0!A="!O;F-E -MA0`A3VZ0`QMEPP`"Y`(R<')O.@$!A0%18W1L>2W,``!(!E)U='!U=.\"`&`$ -M\0-O8FIE8W0M2!F)M96UO -M?\`!8P``0`"\05R;W9I9&4@96%S>2UT;RUU8<``J,!!H`%,7=A;H@`$'0V!`5%`0!@ -M``'Z"0".!R%S:RP#`WX&N6-O;G9E;FEE;F-EP`$`B0`P;6%K>0"0:7,@97-P -M96-I;@0!T`$"J@$`.@@P.B`BDPH.NPH3(KD"(&QL/`$"Z`(`I0<`$0,"P040 -M+&,`0&1EH($',+!0$^`0!U```7`@#Y!`%Q``%Q"@B7```\"3-Y+C--``#O -M!#)E(")K`P6K``$D`!0B"PM9(&-L87-$``$?"49N86QSG0`2!Q(M@@0U"`"X!!,B!0XR+F@BJ0`R:&4* -M7PP0(+`)`/H``!0`!.D&`W((`G\"-&UO5$P"9!F!E2X`L2`H8FEG+65N9&EAU!%C;&ET=&QE$0`"QP`$ -M7Q:10T0M4D]-(&EMMP(0*#@.,"!O<,L#P&%L(%)O8VMR:61G9>\!`DD`#QX78P\+%P#036EC@`/`#;&EB -M2!A2XS30`"=`%U -M(G-T2!C;&%S1`"6:6YT97)N86QSG0!@2!E2QN``5H`W!U=&]M871I_P(0>68!,&5C=)D#$635``,<`E!O;&QO=Y,!$&8L -M`#!S.@K?!#%'3E5U`0(U`B8@*+D!`!H`06QO;F=5`F)N86UE`*%35E(T($%30TE) -M=`(!%``"4P`/,@`%84)I;F%R>2X`H"`H8FEG+65N9&GS!(-R(&QI='1L91$` -M`OH`\0))4T\Y-C8P($-$+5)/32!I;;<"@"AW:71H(&]P^@7`86P@4F]C:W)I -M9&=E10!B2F]L:65T*0$![P$"20`T6DE05@,$0`#`=6YC;VUP[`@0]`5HW+5II<"8`V$UI8W)O`,(KP)@:&%N9&QENP(0>;<#`+8$!K@",&)E9DH# -M<&5V86QU873*`@`@``.9`P+/`A!U]@40;W$"`+8"`D,"`0H`$2"#`:)24$T@ -M=W)A<'!E3@)%9WII<#X!,6EO;A@!76)Z:7`R%@`$?`%-+TQ:5QT`HFQZ;6$L -M(&QZ:7`3`R]X>B,``!DT%``)"`&58V%N(&-R96%TSP`!=00/!@$"`J\!`[\# -M`KP"#Q\#&,$B0`&@`2P:7,@9&5S:6=N962C"R)B -M9;X"`$`$`3`$.&YE=[4#`/`$`'L``Y\!`'L``8<)`:,``DH,`PH#`#@(`+(` -M`1X#`*8$`@P"(2!B-PEQ6"@(J`2%/;C\(`/<,`G@&`0(*(VYD -M^``!B`E086QW87E&`0#=`2IE9(H(`D<`<$DG=F4@870M#0",!]!T;R!M:6YI -M;6EZ92!S#@T28U((07!O;&R4#5$N("!)9O4(0&1O;B?6!P&V`%!I8VET;-D) -M@79O:V4@82!PZP`!?PHQ9F5A-`LP*'-U+P$%^PH`J0`@(&'I``0 -M`P&@`A!MV`$32X'<70@82!T:6U7`W%O8!(71O -M(@`%2@!A="!O;F-EA0`B3VX<#@O#``+D`C)P@``S0*%82!S;V-K970^`TEW:7-HN@0!)@\#60\` -M4X.``P1$2(A`0!:""`L(E`(L2P@8V%P86)I;&ET -M]@($`P$%\0`"\P\!MP0(]@4!EP&`(&EN9&EV:61L#@/;"`"%``(5!@!"``!R -M"P#1```V`2%T;W@',&1A=-<```4.%CHN`0+("0`]`!)A[`(`R0H!*P`S:6X@ -M)P$`CP(S861DC@(88?<,`=<'`QX/469I60!`,P` -M`*,!!H`%,7=A;G\%$G0=#P$V`@%;`P$:!!!TC@0#`',*T2!S -M87ES+@I214%$3442!@9)$>$@8G5N9&QE+@H*475E<_H"H#\@($ES+%1`G -MD1(`\A$`%@)S82!F=6QL+98(F-%#A)B!P`2>`<``$D!`)()`"<`02H@97@;$T!S.B!3,@-4 -MO&0,D!`"3``!.`/``+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C_P`` -M`@`0+60"`)\`!*@``-D."*($$BP:#@#7"P!9"P]D&O__________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M________________________________________________55!E;6]R>341 -M``#P)B!A;F0@861D(&ET('1O(&$@=&%R(&%R8VAI=F4@=VET:&]U=`H@("!F -M:7)S="!W``-:``!V``!-`/($92!T:&4@9&%T82!D -M:7)E8W1L>8<`\01S;V-K970N("!)9B!Y;W4@=V%NB``2=%T`$B\]``!@`#!I -M97,S`%!D:7-K+$X`\`QR92!A2!E87-Y+@H*("H@3F]T93H@(G!A>"!I -M;G1E'1E;F1E9#@!`B(`$"QC -M`$!D97-PWP!`=VAA=)8`\`,@;F%M92!S87ES+@I214%$3450`$0@;&EB;0'1 -M8G5N9&QE+@H*475E6H`)V%T:0`K871H`&ES:6UP;&6U`$!T;V]L,P$`0``# -M`@!R>F-A="P@8@<`$G@'``!)`4!S=6-H)P!0*B!E>&%)`$!S.B!3,@-4P``7P%Q875T:&]R<\`%42!A;GD@\@(``050+@H*5&B=`3!P+6P, -M!`-V!3!O'2(`#!P=71>`C`@(F,T!A$B)`-I9"!T -M;V]L30`"5@$&ZP,`%`=!'!L@P(#+P,`0@$"(0`$F@,#,P``B`0/ -M-``+`"(`##4`+V%T-``,*&%T,P`&`0:`+C,@9VEV97/?!H!O=F5R=FEE=_," -M`*``!+L%$&%Q!3!W:&^1`A0J[`B%7W)E860N,RP0``&["`T1`%%?9&ES:Q8` -M`GX'`RH)`3X``QP``)D`$'9?`0*W`F%E9"!C86R)!Q!SU`9!;F-E2XS!`,!JP(2(FL#!:L``20`4"(@ -M=71II`59(&-L87-$``$?"49N86QSG0`P=H+`#L'`2,)@&%U=&]M871I_P(0><$",&5C=)D#$60Y"0,<`@5X"1!F -M+``!MP91*B!'3E5U`0(U`B8@*`0+`!H`06QO;F=5`@"M"R)S+!````4+`;X+ -M$G,W`E)S<&%RB,``!DT%``)"`$```I58W)E873/``$M -M"0\&`0("J@,#OP,"O`(/'P,8,")R9:`-46-T960B1P,"3P#$+"!W:&EC:"!W -M:6QLB@`!5@`%R@%A(&5X8V5P0`4`N04!RA`!:A`Q:&%T0PXQ:7)E40`!`1`! -MR@(@("A3"@$T!`"$`0-$!`#T`V`L(&5T8RGO"P+Z`P"I`@!H$0*-``&&`0+: -M``^6`P4!R`-A(FYE=V,BFP,!,P`G`3AN97>U`P#P!`#]`@-S!`![``&'"0&C``)*#`!-$2)I -MF4@``%1`0.;`")E -M;LD!!RT``'P`"W$`*&1E$0`#Q@(1+.4)`H```(T.`)8!`!8!`$``,&%G8?,/ -M`5\*D6-O7L#$7`U`-%A=&5V97(@8FQO8VMS\``` -M[@2X' -M$'1[%R%I;5<#<6]R(&UM87`I`0!>$P'Y%@*Y%P"V`A!GPA<0:2(3`2(`!4H` -M`.,3(6-EA0`A3VZ0`QMEPP`"Y`(R<')O.@$!A0$`FA<1+P"`8`.`-$9,VEN("FEP,A8`!"8`32],6E<=`/D#;'IM82P@ -M;'II<"P@86YD('AZ(P#!"DYO=&5S(&%B;W5TE`!R;&EB=$`\"YT96-T -M=7)E.@H*("H@5&AI48!`-T! -M\@%E9"!A=71O;6%T:6-A;&QY1P"P22=V92!A='1E;7#7`>!T;R!M:6YI;6EZ -M92!S="L`L"!L:6YK('!O;&QUN`'A+B`@268@>6]U(&1O;B?L`0"V`/$":6-I -M=&QY(&EN=F]K92!A('#K`(!U;&%R(&9E85D"0"`HD`!RT` -M!P8#`(`!`ID!<"DL(&ET('=P`/``(&=E="!P=6QL960@:6XN/@`G26YN`#``%1`0.;`")E;LD!!RT``#X`"W$`*&1E$0`#Q@(1+/```H``(FYEC@(` -M%@$`0`!B86=A:6YS1P*@8V]R7L#$7`U -M`-%A=&5V97(@8FQO8VMS\``0:$,$(6ETH0!!66]U717`F$@82!T:6U7`W%O`+$@(&)S9'1A3X`!8P``0`"\05R -M;W9I9&4@96%S>2UT;RUUX`0!V``*4`0"A`P&3 -M``)/!R)L>8<``J,!!H`%,7=A;H@`$'0V!`5%`0!@`!!IA0(`C@%EB!$!G -M&%)`$!S -M.B!3,@-4`0-)`#!C;VY# -M`O`".B`@5F%R:6]UP``7P%V875T:&]R,& -M`4D!A69I9W5R92`M#``"1`"U'2(`")P==8-(")C-`81(B0#`#@,*6]L30`"5@$&ZP,!*0$` -M%@D`C@$/;0$!`*(&('5SW0H`V@$T90HGL``C92>M``,D!`"3``!.`/``+F%M -M+"!A8VQO8V%L+FTT"0T#[0`P+F%C%P$``@`0+:("`)\`!*@``-D."*($$BP: -M#@#7"P)\`#%M86GV`2-EPH"MP(29:`, -M`!(&0'-E<77J"!!S"P4!/@$`=0``%P(`^00!<0`!<0H(EP``/`DS>2XS30`` -M[P0R92`B:P,%JP`!)``4(@L+62!C;&%S1``!'PE&;F%L]!9!I;@IA(&YU;6+R#!=FD0<$.P'' -M"@I9;W4@2X`L2`H8FEG+65N9&EAU!%C;&ET=&QE$0`" -M^@#Q`DE33SDV-C`@0T0M4D]-(&EMMP(0*#@.,"!O<,L#P&%L(%)O8VMR:61G -M9>\!`DD`-%I)4'4$!$``('5N,0L`)18`UA!@C2H`0#E%PD(`0``"@*<$`4Z`0!U!`\&`0("KP$#OP,"O`(/'P,8,")R -M9:`-`!`6$2)'`P)/`,0L('=H:6-H('=I;&R*``%6``:0`"!E>"T4``("`+D% -M!(D1`@L7`UH7`5$`!>D2,',@*%,*`30$`(0!`S,$`/0#8"P@971C*>\+`OH# -M`*D"!C`0`9L!`MH`#\@#"F$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0%!`); -M`0&)``]9`P`*%@,S5VAE`P(`OP@#U`(2<^8%#V0:____________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________________________________________]34')A=&EO2A$` -M`/,?;BX*("H@;&EB87)C:&EV92UF;W)M871S+C4@9&]C=6UE;G1S('1H92!F -M:6QE(!T`T2!S=7!P;W)T960@8GD>`'!L:6)R87)Y3`#08W!I;RXU+"!M=')E -M90D`\@YA;F0@=&%R+C4@<')O=FED92!D971A:6QE9"!I;E(`D&EO;B!A8F]U -M=$T`XW-E"B`@('!O<'5L87(@F``$>P#S"2P@:6YC;'5D:6YG(&AA``"/`/0:("=D;V,G(&1I2!I -M;@IA(&YU;6)E6]U(#\! -M8"X*"D-U"!I;G1E`*%35E(T($%30TE)=`(!%``"8P`/,@`%84)I;F%R>2X`P"`H8FEG+65N -M9&EA;J(!8VQI='1L91$``OH`\0))4T\Y-C8P($-$+5)/32!I;;<"\`DH=VET -M:"!O<'1I;VYA;"!2;V-KFEP/@$Q:6]N!0%=8GII -M<#(6``1\`4TO3%I7'0"B;'IM82P@;'II&-E<$`%`+D%!&D"L"!T:&%T(')E -M<75IE@4G87C*`E(@*&9OU`P#P!`![``-S!`![``&'"0&C`%0@;VYL>0H#`#@(`+(``1X#`*8$`@P" -M(2!B-PEQ4,`4&EN9&5PJ@`E;G0B`0`8"5!A``B; -M`")E;LD!!RT``'P`"W$`*&1E$0`#Q@(1+/```H``(FYEC@(`%@$`0`!B86=A -M:6YS1P*18V]R0 -M`P&@`A!MV`$38!(71O -M(@`%H0!A="!O;F-EA0`A3VZ0`QMEPP`"Y`(R<')O.@$!A0%18W1L>2W,``". -M"5)U='!U=.\"`&`$\0-O8FIE8W0M`%`@(&)S9",'(75SO`$`/06# -M;B!I=',@(D`\`!(BO01&2!F60!`,P``*,!!H`%,7=A;G\%$G0=#P-%`0!@```:!!!TC@0"0:7,@97-P96-I;@0! -MT`$"J@$`.@@P.B`BDPH.V@T3(KD"`-X.(F%NZ`(`I0<`$0,"6@<0+&,`0&1E -M8$(&YDT`(Q9G5L+P(& -M10`0+T,*`84!$6&>"C1A8W1[$X)D96UO;G-T$0(8`+5C;VYF -M:6=U'2(`"%P=6<0,"`B8S0&$2(D`P`X#"EO;$T``E8!!NL#`2D!`!8)`(X! -M#VT!`0"B!A!U/1,"$!P`"-E)ZT``R0$`),``$X`\``N86TL(&%C;&]C -M86PN;30)#0/M`#`N86/_```"`!`MH@(`GP`$J```V0X(H@02+!H.`-<+`%D+ -M$'G*!0'V`2-E!Q(M -M6`D/9!K_____________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_____________U-0:7-T"B`O$0``\R,@("H@5&\@2!F;W(@ -M:L`D'-A;64@9G5N8S`<``$D!0'-U8V@G`%`J(&5X84D`U',Z(%-O;64@6]U(&UA>2!F:6YD('5S969U;"\"!D4`42]M:6YIA0$1 -M8>,!46%C="!S8`"A(&1E;6]N2#R`I!I;VYS+@H*5&B= -M`?("<"UL979E;"!D:7)E8W1O%#36%K94QI\`!,GK0`#)`0`DP``3@#U`2YA;2P@86-L;V-A -M;"YM-"SA`$!E+F%C_P```@`2+50`)'1OJ``,H@2R+"!O;FQY(&YE961\`#%M -M86GV`2-E7-T96TZ -M"B`J(+@$=2XQ(&5X<&R#`@,O`P!"`0(A``2:`P,S``"(!`\T``L`(@`,-0`O -M870T``PH870S``8!!H`N,R!G:79E2XS30`"]P,2(FL#!:L``20`4"(@=71II`59(&-L -M87-$``'O!49N86QSG0`P`D09BP``;<&42H@1TY5=0$"-0(B("BK"0"Y`0`:`$%L;VYG4`9B;F%M -M97,L$`!3;&EN:R`1``!C`%)S<&%R'1E -M;J+``-J`0`9`]$J(%!/4TE8('5S=&%R6P`" -M$``R<&%X-`,"60<#>`('(0"P;V-T970M;W)I96X!`P!@`@$>`*%35E(T($%3 -M0TE)=`(!%``"4P`/,@`%84)I;F%R>2X`P"`H8FEG+65N9&EA;J(!8VQI='1L -M91$``OH`\0))4T\Y-C8P($-$+5)/32!I;;<"$2AX""!O<,L#P&%L(%)O8VMR -M:61G944`8DIO;&EE="D!`>\!`DD`-%I)4%8#!$``('5N,0LPFEP,A8`!'P!32],6E<=`*)L>FUA+"!L>FEP -M$P,O>'HC```9-!0`"0@!```*56-R96%TSP`!=00/!@$"`JH#`[\#`KP"#Q\# -M&#`B&-E -M<$`%`+D%!&D"42!T:&%T0PXQ:7)E40`!\P,!R@(@("@6!0$T!`"$`0,S!`#T -M`V`L(&5T8REF"@+Z`P"I`@8B!`&&`0+:``^6`P4!R`-A(FYE=V,BFP,!,P`G -MD#`*4#(71EVP@P.@H*N!`R:&ESD0]P:&5A=FEL>?P(-F5A;;4%`A$+@"X@ -M(%1H97)E+``C;F_B!P""`@/?"`"3!$$@:6XMMP^"(&UO9&EF:6-D"_``;W(@ -M0`&EP``L!!397-I9VXE#!)EB`4`0`0!7@$X;F5W -MM0,`\`0`>P`#GP$`>P`!APD!HP`"2@P`31$B:7*"$1!I>0<280D!`@P"(2!B -M-PD`C`HQ86)L``8`_0H!#``!+`L"U!``:``".P!"96%C:#T!(79E4,` -M4&EN9&5PJ@`E;G0B`0`8"0`/#Q!C0@42;VP-!C4*5"!7:6MI4@PP:6YGR0`P -M:&]W40\!LP,09$X(`]H``BH!(4]N/P@`]PP"8`8`TQ$`4`8#S0`!<`!3;'=A -M>7-S""IE9(H(`D<`<$DG=F4@870M#0",!S!T;R`A$+)M:7IE('-T871I8U(( -M07!O;&PV$E$N("!)9O4(4&1O;B=TJ`"097AP;&EC:71LV0EB=F]K92!A^@\1 -M8W\*`\X1("`HTA`E(&'["@"A`2`@84$``2<0`BT`",T`%&_Y"'`I+"!I="!W -M<`!!(&=E=!D3`5T*`*0$-R!);FX`-RP@:9X``5$!`YL`(F5NR0$'+0``?``+ -M<0`H9&41``/&`A$L\``"@```C0X`E@$`%@$`0``@86<##A%T\0F18V]RP,B:67-#P&<$P/G"B!D=1D-`)\#$'.%`2-O9H@!`(X2 -M$"UV```S#`#W"!%IM`\`A`!R96YV:7)O;@\+$7>0`P&@`A!MV`$3<3 -M`<0-0&)A8VOR`S%F2W,`))E9"!O=71P=73O`@!@!/$#;V)J -M96-T+7-T>6QE(&%P<')OR`,`^10"^@#0=&\@:&%V92!M=6QT:<,3!*D``@$$ -M`+D(52!O<&5NG@`3(!40`&H0``H!`#T%@VX@:71S(")`/``2(KT$$7,P#@)C -M!098`&!I='-E;&93`5!R96%D+^8`8'1E;B!U@``S0*%82!S;V-K970^`TEW:7-HN@0!)@\#60\`7,N"B05$6:X#007&0.A&$0N"@I1$1:@/R`@ -M27-S=65S/U(`$2H%&78Z+R]W=W7,@9&5T96-T960@875T;VUA -M=&EC86QL>2X*"B`J($DG=F4@871T96UP(@#@=&\@;6EN:6UI>F4@6]U(&1O;B=T"B`@(&5X<&QI8VET;'D@ -M:6YV;VME(&$@<&%R=&EC=6QA2!A8V-E<#4` -MT6%T979E717`G`@82!T:6UEI0!Q;W(@;6UA<'\` -M0&5N=&F?`D!R8VAI?P)`;F0@9PD`(&ET3P``2P$%2@!A="!O;F-EA0"+3VX@ -M=W)I=&7#``+D`C)P2!B=69F97(@;W+!``!E``1R`85A('-O8VME=#X#4'=I2UT;RUU0"0:7,@97-P96-I;@0!T`$"J@'S!TYO -M=&4Z(")P87@@:6YT97)C:&%N9V6?!1,BN0(@;&P\`0+H`A!DO@$`_04!P040 -M+&,`0&1EF-A="P@8@<`$G@'``!)`0"2"0`G`%`J -M(&5X84D`0',Z(%,R`U1S;6%L;!4`!#X!`%(#(6%T'`@@;6'F!"!N9-`",69U -M;"\"!D4`$"]#"@&%`1%A!@E186-T('-@`+`@9&5M;VYS=')A=+'2(`")P=;H+(")C-`81(B0#`!(+*6]L -M30`"5@$&ZP,`E``!%@D`C@$/;0$!`&8(('5SW0H`V@$T90HGL``C92>M``-G -M`0"3``!.`/4!+F%M+"!A8VQO8V%L+FTT+.$`0&4N86/_```"`!`MH@(`GP`$ -MJ```:@L(H@1A+"!O;FQYUPL"?``Q;6%I]@$C97*N`05P`"1I;F0`@2YH+FEN -M"@DM]`=2;&%T97-G`!%B-`(#<@$"M0!@"@I'=6ED\P`H($14!@32`0)U``&W -M`7!S>7-T96TZ&@D"N`0A+C'!#`!A#`$W`0,O`P`+``(A``2:`P,S``"(!`\T -M``L`(@`,-0`O870T``PH870S``8!!B$N,[8+$'-E"H!O=F5R=FEE=_,"`*`` -M!<`+`'$%,'=H;Y$"%"JD"H5?PH"MP(29:`,`%L$$'/4!A!N2PT`U@(`DP``=0``%P(` -M^00!<0`!<0H(EP`!G`DC+C--``#O!#)E(")K`P6K``$D`!0B"PM9(&-L87-$ -M``$?"49N86QSG0`2P$2+8($-7,N-:H(`J\``!D#`/T%-6UA=&D/!&,"!98!`+`` -M``H"D"XU+"!M=')E90D``&\`7G1A"`#.#1,BR0TR+F@BJ0`R:&4*7PP0(+`)`/H``!0`!.D&`W((`G\" -M-&UO2X` -ML2`H8FEG+65N9&EAU!%C;&ET=&QE$0`"^@#Q`DE33SDV-C`@0T0M4D]-(&EM -MMP(1*'@((&]PRP/`86P@4F]C:W)I9&=EYP%B2F]L:65T*0$![P$"20`T6DE0 -M=00$0``@=6XQ"P`?$P#6$&!R(")D969^!A$B9@D#&```H00C:655`0##`0"B -M`85"4T0@)V%R)U(``?@`$2?]`Q`GNP($/0%:-RU::7`F`-A-:6-R;W-O9G0@ -M0T%"+``Q3$A!"@,Z3%I(,@`Z4D%2$0`86!$``1D(!2`&`/42"*\"`'82`"H( -M`,,/`TP&!D4(,&)E9DH#4F5V86QU0@H`K@,#+P(`'P@P*B!U]@40;Q@$``L% -M`D,"`0H``EP)L5)032!WFEP,A8` -M!'P!32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9-!0`"0@!```*`IP0!3H! -M`'4$#P8!`@*O`0._`P*\`@\?`Q@P(G)EH`T`$!81(D<#`D\`Q"P@=VAI8V@@ -M=VEL;(H``58`!I``(&5X+10``@(`N04$B1$":Q0`0PX`TQ,`40`%Z1(PA@!+1`0:2`*<&AE879I;'G\"#9E86VU -M!0(1"P6(%$!I0`&@`0I:7-N%")B98@%`$`$`5X!.&YE=[4#`/`$ -M`/T"`Y\!`'L``8<)`2L5`DH,`PH#`#@(`&\0%'3N$@(,`B$@8C<)`(P*`8\8 -M`[@4`0P`$&$,`0+4$`!H``([`!%EG!8`/0$A=F5S`Q-Y0P!0:6YD97"J`"5N -M="(!`$0-`7D9`$(%$F]L#0:P"U0@5VEK:5(,`PP3,&AO=U$/`;,#$&2M`0/: -M``+W$P4T&`3\!`#S#@!0!@/-``%P``*`%P+$!0]D&O__________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M________________________________________________5E!L97,I"BP1 -M``#P)"`@*B!3;VQA -M`*935E(T($%30TE)%``"8P`/,@`%84)I;F%R>2X`\P<@*&)I9RUE;F1I86X@ -M;W(@;&ET=&QE$0`"QP#P'TE33SDV-C`@0T0M4D]-(&EM86=EFEP/@$Q:6]N1`!=8GII<#(6``1D`4TO3%I7'0"Q;'IM82P@ -M;'II<"S'`"]X>B,``!DT%``)"`&58V%N(&-R96%TSP!/&-E<'0"`D0*("`@:0+1('1H870@0`&EP"0:7,@9&5S:6=NH@9";R!B98@%`$`$`3`$ -M.&YE=[4#`-P#`'L``4,`4&EN9&5PJ@`B;G1_`!!R.P0`!``P=&EC0@4D;VZ!`02N -M`/``5VEK:2!E>'!L86EN:6YGB0`P:&]W^``!LP,09)8%`RP``BH!(4]NJ@`< -M+`,!``0$,FUA='``0&QW87E&`0#=`?(!960@875T;VUA=&EC86QL>4<`L$DG -M=F4@871T96UPC`?@=&\@;6EN:6UI>F4@2!I;G9O:V4@82!PZP`@=6Q9"*!E -M871UP,1<#4`T6%T979E`%`@(&)S9",'(75SO`$`/06#;B!I=',@(D#E -M`!(BO01&P`28D(``$X&`-$``#8!(71OFPDP9&%TUP!6=7)C93HN`0+( -M"0#"`!)A[`(`R0H!*P`S:6X@)P$`E0LS861DC@(88?<,`=<'(6]U]P119FER -M0"0:7,@97-P96-I -M;@0!T`$"J@$`.@@P.B`BDPH.V@T3(KD"(&QL/`$"Z`(`I0<`$0,"P040+&,` -M0&1E%EF-%#A)B -M!P`2>`<``$D!`)()`"<`4"H@97AA20!`8$(&YDT`(Q9G5L+P(&10`0+T,*`84!$6&>"E%A8W0@'2(`")P==8- -M(")C-`81(B0#`#@,*6]L30`"5@$&ZP,!*0$`%@D`C@$/;0$!`+`,$'4]$P': -M`31E"B>P`"-E)ZT``#H/,"`J(),``$X`\``N86TL(&%C;&]C86PN;30)#0/M -M`#`N86,7`0`"`!`MH@(`GP`$J```V0X(H@02+!H.`-<+`%D+$'G*!0'V`2-E -MPH"MP(`318A86R)!T!S97%UZ@@0 -M=&%R+C54`0CQ -M!`4^$A%S8P0Q<&]PY0\#G`$$>P`(2PE`:&%R9!8,`3`&`J@!`X42`(X!86UO -M9&5R;H\``.@!`+P'<"!V87)I86Y("0`B##!M86[X"Q%PK1]!;!I;@IA(&YU;6)E"`"X!!,BXP`R+F@BJ0`R:&4*7PP0(+`) -M`/H``!0`!.D&`W((`G\"$&T:%P/[`$(N("!0B@FR;&5T('5S"FMN;W<0`0&9 -M!F!E`D09@82`;<&`H<8!JH+"``:`/@5#"`6`1````4+ -M`;X+$G,W`E)S<&%R%#36%K94QIM``-G`0"3``!.`/4!+F%M+"!A8VQO8V%L+FTT+.$`0&4N86/_```" -M`!(M5``D=&^H```@`3!D:7-?`A!U00&R+"!O;FQY(&YE961\`#%M86GV`2-E -M7-T96TZ"B`J -M(&)S9'1AM`_`$,R!G:79E2XS!`,!JP(2(FL# -M!:L``20`Z2(@=71I;&ET>2!C;&%S1`"6:6YT97)N86QSG0!@P$2 -M+8($4W,N-2!D5@(#I@0@:6QV`]1R;6%T-50!"/$$4&%B;W5T&@$@P"`+"!I;F-L=62*`<5H87)D+71O+69I;F1;`0%'``!!`&%M;V1E -M$D# -M(F5R60<#>`('(0"P;V-T970M;W)I96X!`P!@`@$>`*%35E(T($%30TE)=`(! -M%``"4P`/,@`%,$)I;LH$`$(`H"`H8FEG+65N9&GS!(-R(&QI='1L91$``OH` -M\0))4T\Y-C8P($-$+5)/32!I;;<"$2AX""!O<,L#P&%L(%)O8VMR:61G944` -M8DIO;&EE="D!`>\!`DD`-%I)4%8#!$``D'5N8V]M<')EFEP,A8`!&0!32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC -M```9-!0`"0@!```*56-R96%TSP`!=00/!@$"`JH#`[\#`KP"#Q\#&#`B&-E<$`%`+D% -M!&D"T2!T:&%T(')E<75IP`#GP$`>P`!APD!HP`"2@P#"@,`.`@`L@`!'@,`"0$"#`(A(&(W -M"0!J"#%A8FP`!@","@$,``$L"P($`0!H``([`$)E86-H/0$A=F5S`Q-Y0P!0 -M:6YD97"J`"5N="(!`!@)``\/$&-"!1)O;`T&-0I4(%=I:VE2##!I;F?)`&-H -M;W<@=&_U``>6"@(J`2%/;C\(`/<,`G@&`P,!`_@``8@)4&%L=V%Y1@$`W0$J -M962*"`)'`'!))W9E(&%T+0T`C`<`P0^0:6YI;6EZ92!S#@T28U((07!O;&R4 -M#5$N("!)9O4(4&1O;B=TJ`"097AP;&EC:71LV0EB=F]K92!A^@\18W\*,69E -M830+,"AS=2\!!?L*`*D`("!A00`1P,1<#4`T6%T979EP"`,D*`2L`,VEN("#U%F:7)S=)("`*8!$6%P$A%O61$`]@`6+G0` -M`]D#`J60!`,P``*,! -M!H`%,7=A;G\%$G0=#P-%`0!@```:!!!TC@0#`',*+%1`G-Q,`C!4`%@)S82!F=6QL+98(7,@<')O9'5C97,@8V]R6]U('1O(&AA=F4@;75L=&EP)0`P`/,- -M("!B2!D8737`%9UX`0!V``*4`0`` -M`P&^``7+`0#3``.C`4,N("!)I`$A86Z(`!)T70`!-@(491\!`#L!061I"!I;G1E&%)`$!S.B!3,@-4`0-)`#!C;VY#`O`".B`@5F%R -M:6]UP``7P%Q875T:&]R<\`%`1\&`?("`DT'$`H5"%!T;W`M;`P$`W8%`#`' -M`4$`$&DD!0FV`B)I;O@$(FEOX08$O0+P`DY%5U,@+2!H:6=H;&EG:'1S7`8P -M'2(`#!P=71>`C`@(F,T!A$B)`,`J@2!N -M965D?``Q;6%I]@$C97*N`05P`"1I;F0`@2YH+FEN"@DM]`=2;&%T97-G`!%B -M-`(#<@$"M0!@"@I'=6ED\P`H($14!@32`0)U``#S`8`@PH" -MMP(A960N"P!;!!!SU`80;A$,`-8"`),``'4``!<"`/D$`7$``7$*")<``9P) -M(RXS30``[P0R92`B:P,%JP`!)``4(@L+62!C;&%S1``!'PE&;F%L]!9!I;@IA -M(&YU;6+R#!=FD0<#HP#7+@H*66]U('-H;W5L9*0+`$P`,6-O<'8&0&-O;6V> -M"`#.#1,BR0TR+F@BJ0`R:&4*7PP0(+`)`'4!`!0`!.D&`W((`G\"-&UO@,QBH@4U92-"!!4T-)210``E,`#S(`!6%" -M:6YA`@@;W#+`\!A;"!2;V-K[`@0]`5HW+5II<"8`V$UI -M8W)OFEP/@$Q:6]N&`%= -M8GII<#(6``1\`4TO3%I7'0"B;'IM82P@;'IIP`!APD!*Q4"2@P`31$B:7*"$1!I>0<#[A(" -M#`(A(&(W"0","C%A8FP`!@","@$,`!!A#`$"U!``:``".P!"96%C:#T!(79E -M4,`4&EN9&5PJ@`E;G0B`0!$#0`/#Q!C0@42;VP-!K`+5"!7:6MI4@P# -M#!,P:&]W40\!LP,09*T!`]H``O<3(4]N/P@`]PP"8`8`\PX`4`8#S0`!<``" -M@!<"Q`4J962*"`)'`'!))W9E(&%T(14`C`'!L:6-I=&S9"6)V;VME(&'Z#Q%C?PH#SA$@ -M("C2$`!U#`@<`A!AL@$!)Q`"+0`(S0`4;W,$<"DL(&ET('=P`%`@9V5T(-(2 -M`5T*`*0$-R!);FX`!287`9X``5$!`YL`(F5NR0$'+0``?``+<0`H9&41``.J -M`!$L6!$"@```C0X`E@$`%@$`0``P86=A\P\!7PJ18V]R7L#$7`U`&)A=&5V97)X%Q%S\```[@$P'Y -M%@*[&0"V`A!GQ!D0:2(3`2(`!4H``.,3#V0:________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M__________________________________________](4'(*("`J-Q$``/T, -M(&=Z:7`@8V]M<')EFUA -M+"!L>FEP+"!A;F0@>'HC```9-!0`\3(*5&AE(&QI8G)A&-E<'1_`/$* -M"B`@("!E;G1R:65S('1H870@$E33SDV-C`3`%HW -M+5II<#D`-EA!4A$`0PI7:&4#`@#D`00%`A$L_`%A2!S=')E86WM -M`>!S>7-T96TN("!4:&5R92P`D&YO(&1IP`!S@`4=E@#$G.C -M`%0@;VYL>0H#0&UE;G2R``$>`P+``P"#`R`@8H\!D"!R96%D86)L9:(`07=R -M:70,`!!A#`$"!`$!1`0!.P!$96%C:"8"`98"$WE#`%!I;F1E<*H`(FYT?P`0 -M$N("!)9B!Y;W4@9&]N)^P!`+8`\0)I8VET;'D@:6YV -M;VME(&$@<.L`('5L-P0@96%9`D`@*'-U+P$9``%1`0.; -M`")E;LD!!RT``'P`"W$`*&1E$0`#J@`1+/```H``(FYEC@(`%@$`0`!B86=A -M:6YS1P*@8V]RP,1<#4`T6%T979E2!B=69F97(@)`@`90`$<@&%82!S;V-K -M970^`TEW:7-HN@3`P"`,,)`2L`,VEN("0#`',*T"!S87ES -M+@I214%$346[!@?H!N$@8G5N9&QE+@H*475E<_H"H#\@($ES7!1`GH@1`9W)A;18"F-%#A)B!P`2>`<``$D!`)()`"<` -M4"H@97AA20!`8$(&YDT`(Q -M9G5L+P(&10`0+T,*`84!$6&>"E%A8W0@H($',+!0$^`0!U```7`@#Y!`%Q -M``%Q"@B7```\"3-Y+C--``#O!#)E(")K`P6K``$D`!0B"PM9(&-L87-$``$? -M"49N86QSG0`2!Q(M@@0U -M"`"X!!,B!0XR+F@BJ0`R:&4*7PP0(+`)`/H``!0`!.D&`W((`G\"-&UO5$P`P%&!E2X`L2`H8FEG+65N -M9&EAU!%C;&ET=&QE$0`"QP`$7Q:10T0M4D]-(&EMMP(0*#@.,"!O<,L#P&%L -M(%)O8VMR:61G9>\!`DD`#QX78P\+%P#036EC2$`\AMU7-T96TZ"B`J(&)S9'1A@ -M`/`#;&EB2!A2XS -M30`"=`%U(G-T2!C;&%S1`"6:6YT97)N86QS -MG0!@P"`+"!I;F-L=62*`<5H87)D+71O+69I -M;F1;`0%'``!!`&%M;V1E``"/`/`-("=D;V,G(&1I2!I -M;@IA(&YU;6)E2!E2QN``5H`W!U=&]M871I_P(0>68!,&5C=)D#$635``,<`E!O;&QO -M=Y,!$&8L`#!S.@K?!#%'3E5U`0(U`B8@*+D!`!H`06QO;F=5`F)N86UE`*%35E(T -M($%30TE)=`(!%``"4P`/,@`%84)I;F%R>2X`H"`H8FEG+65N9&GS!(-R(&QI -M='1L91$``OH`\0))4T\Y-C8P($-$+5)/32!I;;<"@"AW:71H(&]P^@7`86P@ -M4F]C:W)I9&=E10!B2F]L:65T*0$![P$"20`T6DE05@,$0`"0=6YC;VUP[`@0]`5HW+5II<"8`V$UI8W)O`,(KP)@:&%N9&QENP(0>;<#`+8$!K@" -M,&)E9DH#<&5V86QU873*`@`@``.9`P+/`A!U]@40;W$"`+8"`D,"`0H`$2"# -M`:)24$T@=W)A<'!E3@)%9WII<#X!,6EO;A@!76)Z:7`R%@`$?`%-+TQ:5QT` -MHFQZ;6$L(&QZ:7`3`R]X>B,``!DT%``)"`&58V%N(&-R96%TSP`!=00/!@$" -M`J\!`[\#`KP"#Q\#&,$B0`&EP"P:7,@9&5S -M:6=N962C"R)B9;X"`$`$`3`$.&YE=[4#`/`$`'L``Y\!`'L``8<)`:,`5"!O -M;FQY"@,`.`@`L@`!'@,`"0$"#`(A(&(W"7%R96%D86)L``8`C`H!#``!+`L" -M!`$`:``".P!"96%C:#T!(79E4,`4&EN9&5PJ@`E;G0B`0`8"5!A`8!`@HC;F3X``&("5!A;'=A>48!`-T!*F5DB@@"1P!P22=V92!A="T- -M`(P'T'1O(&UI;FEM:7IE(',.#1)C4@A0<&]L;'4B!U$N("!)9O4(0&1O;B?6 -M!P&V`%!I8VET;-D)@79O:V4@82!PZP`!?PHQ9F5A-`LP*'-U+P$%^PH`J0`@ -M(&'I``2UV```S#`#W"!%IAP8`A`!P96YV -M:7)O;M<",7,@=Y`#`:`"$&W8`1-R6@,%,`(`6P`"?P`1>7L#$7`U`-%A=&5V -M97(@8FQO8VMS\```[@@``8P2%82!S;V-K970^`TEW -M:7-HN@0!)@\#60\`4X.475S92`B(0$`6@@@+")0 -M"+$L(&-A<&%B:6QI=/8"!`,!!?$``O,/`;<$"/8%`9P"`,D*`2L`,VEN("#U%F:7)S=)("`*8! -M$6%P$A%O61$`]@`6+G0``]D#`J60!`,P``*,!!H`%,7=A;G\%$G0=#P$V`@%;`P$:!!!TC@0#`',*T2!S87ES+@I214%$3442!@9)$>$@8G5N9&QE+@H*475E<_H" -MH#\@($ES+%1`GD1(`\A$`%@)S82!F=6QL+98(F-%#A)B!P`2>`<``$D!`)()`"<`02H@ -M97@;$T!S.B!3,@-4O&0,D!`"3``!.`/``+F%M+"!A8VQO8V%L+FTT -M"0T#[0`P+F%C_P```@`0+60"`)\`!*@``-D."*($$BP:#@#7"P!9"Q!YR@4! -M]@$/9!K_____________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_____________V=08VAI=F4G$0``\#T@=VET:&]U=`H@("!F:7)S="!W2!F6]U('=A;H@`$G1=`!`OB@`196``,&EE -M7,N"E)%041-12X`1"!L:6(3 -M`=%B=6YD;&4N"@I1=65SK@"@/R`@27-S=65S/U(`UBH@:'1T<#HO+W=W=RXX -M`$`N;W)GDP``2`$Q:&]MIP"`(&]N9V]I;F`<``$D!0'-U8V@G`%`J(&5X84D`0',Z(%,R`U1S -M;6%L;!4`!#X!`%(#(6%T?`2`;6%Y(&9I;F30`C%F=6PO`@9%`%$O;6EN:84! -M$6'C`5%A8W0@2#R`@`!!5`N"@I4:)T!,'`M -M;`P$`W8%,&]R>3$%,'1A:20%";8"(FEN^`0Q:6]NZP4$O0+P"4Y%5U,@+2!H -M:6=H;&EG:'1S(&]F(')E8P8"`C$%`Z`"DD-/4%E)3D<@+0P%`,T%`"@&(F1O -MGP``AP4`S@#R!"H@24Y35$%,3"`M(&EN\`!,G -MK0`#)`0`DP``3@#U`2YA;2P@86-L;V-A;"YM-"SA`$!E+F%C_P```@`0+:(" -M`)\`!*@`#*($LBP@;VYL>2!N965D?``Q;6%I]@$C97*N`05P`"1I;F0`@2YH -M+FEN"@DM]`=2;&%T97-G`!%B-`(!9@$39;4`8`H*1W5I9/,`*"!$5`8$T@$" -M=0`!MP%P!1%E -M^P,`\@"`;6%T]!;!I;@IA(&YU;6)E"`"X!!,B?P(R -M+F@BJ0"`:&4*`D09BP``;<&42H@1TY5=0$"-0(F("@$"P`:`$%L;VYG50(`K0LB+``-J`0`9`]$J(%!/4TE8('5S=&%R6P`"$``/B@P#!R$`P&]C=&5T -M+6]R:65N=!<$,7!I;QX`IE-64C0@05-#24D4``)3``\R``5A0FEN87)Y+@#` -M("AB:6FEP,A8` -M!'P!32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9-!0`"0@!```*56-R96%T -MSP`!+0D/!@$"`JH#`[\#`KP"#Q\#&#`B&-E<$`%`+D%!FH0,6AA=$,.$&F6!2=A>,H" -M("`H%@4!-`0`A`$#1`0`]`-@+"!E=&,I[PL"^@,`J0(&,!`!A@$"V@`/E@,% -M`<@#82)N97=C(IL#`3,`)W-HL``!$@`/1@-C!`4$`EL!`8D`#UD#``H6`S-7 -M:&4#`@C1#@+F!6%R97-U;'1-$A%B:`4@=&6[#@%5!`\C`@$*"P,!@``/Z0)4 -M$`HJ$@&G!P(F"`:A!@`^!R%T9=L($3I4$@$M$!!I(`IP:&5A=FEL>?P(-F5A -M;;4%`A$+<"X@(%1H97(T$2`@;M82,7)E8S`1`]\(`),$02!I;BVW#X(@;6]D -M:69I8^4,\`!O`3AN97>U`P#P!`#]`@-S!`![``&'"0&C``)*#`!-$2)I7-S""IE9(H(`D<`<$DG=F4@870A%0",!S!T;R`A$'!M:7IE -M('-TM0@"4@A!<&]L;#82!N04061O;B?L`7!E>'!L:6-I#15@:6YV;VMEO!(! -MZP`!?PH#SA$@("C2$"4@8?L*`*$!("!AL@$!)Q`"+0`(S0`4;_D(<"DL(&ET -M('=P`$$@9V5T&1,!70H`I`0W($EN;@`R+"!I@A4!G@`!40$#FP`B96[)`0"(&5N=FER;VX/"Q%WD`,!H`(0 -M;=@!$W):`P4P`@!;``)_`!%Y>P,1<#4`T6%T979E:89`@4.%CHN`0+("0`]`!)A -M[`(!@`X`T1DS:6X@)P$`104U861D'`$`_`@$J@$`>08/9!K_____________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_____________________________________________________V502!O9B!T:&4@9F]L -M;&]W:6YG.@H@("H@=75E;F-O9&4-`/$!9WII<"!C;VUPFUA+"!L>FEP+"!A;F0@>'HC`,$*3F]T97,@ -M86)O=724`/`[;&EB2!A2!S=')E86TM;W)I96YT960@P`!S@`0=G(!4G)M871SHP#P`B!O;FQY(')E<75I4,`4&EN9&5PJ@`B;G1_`$%R92!A!`"4 -M=&EC;&5S(&]N@0$$K@#P`%=I:VD@97AP;&%I;FEN9\D`,&AO=_@``O4`!RP` -M`BH!(4]NJ@`<+`,!`',!,FUA='``0&QW87E&`0#=`?(!960@875T;VUA=&EC -M86QL>4<`L$DG=F4@871T96UPUP'@=&\@;6EN:6UI>F4@2!I;G9O:V4@82!P -MZP"`=6QA8`0U:``)[`S%I97/#``%O`[!A;'-O(')E9'5C99L" -M,&4@0"0:7,@97-P96-I;@0!T`$"J@$`.@CS`SH@(G!A -M>"!I;G1E7!1`GH@1`9W)A;18"`<``$D!`)()`"<`4"H@97AA20!`8$(&YDT`(Q9G5L+P(&10`0+T,*`84!$6$& -M"5%A8W0@`0-)`#!C;VY#`O`".B`@ -M5F%R:6]UP``7P%V875T:&]R,&`4D!A69I -M9W5R92`M#``"1`"U'2(`")P==8-(")C-`81(B0#`#@,*6]L30`"5@$&ZP,!*0$`%@D`C@$/ -M;0$!`*(&('5SW0H`V@$T90HGL``C92>M``,D!`"3``!.`/``+F%M+"!A8VQO -M8V%L+FTT"0T#[0`P+F%C%P$``@`0+:("`)\`!*@``-D."*($$BP:#@#7"P)\ -M`#%M86GV`2-EPH"MP(29:`,`%L$0'-E -M<77J"!!S"P4!/@$`=0``%P(`^00!<0`!<0H(EP``/`DS>2XS30``[P0R92`B -M:P,%JP`!)``4(@L+62!C;&%S1``!'PE&;F%L]!9!I;@IA(&YU;6+R#!=FD0<$.P''"@I9;W4@ -M2X`L2`H8FEG+65N9&EAU!%C;&ET=&QE$0`"^@#Q`DE3 -M3SDV-C`@0T0M4D]-(&EMMP(0*#@.,"!O<,L#P&%L(%)O8VMR:61G9>\!`DD`-%I)4'4$!$``('5N,0L`)18`UA!@C2H -M`0#E%PD(`0``"@*<$`4Z`0!U!`\&`0("KP$#OP,"O`(/'P,8,")R9:`-`!`6 -M$2)'`P)/`,0L('=H:6-H('=I;&R*``%6``:0`"!E>"T4``("`+D%!(D1`@L7 -M`UH7`5$`!>D2,',@*%,*`30$`(0!`S,$`/0#8"P@971C*>\+`OH#`*D"!C`0 -M`9L!`MH`#\@#"F$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0%!`);`0&)``]9 -M`P`*%@,S5VAE`P(`OP@#U`(2<^8%7W)E1X`\`EL -M:6)R87)Y"B`J(&-P:6\N-2P@;71R964)`/(.86YD('1A3`1!F+`"@FEP,A8`!'P!32],6E<=`*)L>FUA -M+"!L>FEP$P,O>'HC```9-!0`"0@!E6-A;B!C,H"4B`H9F]R-`0` -MA`$#,P0`]`-Q+"!E=&,I+F\!`/H#`*D"!B($`1<``MH`#Y8#!0'(`V$B;F5W -M8R*;`P$S`"=S:+```1(`#T8#8P0%!`);`0&)``]9`P`*%@,S5VAE`P(`V`(# -MU`(2<^8%87)E``B;`")E;LD!!RT``'P`"W$`*&1E$0`# -MQ@(1+/```H``(FYEC@(`%@$`0`!B86=A:6YS1P*18V]RP,Q:65SPP`!;P,#YPHQ9'5CN04P92!SA0$C;V:(`0`]"A`M=@``,PP` -M]P@1:8<&`(0`<&5N=FER;V[7`C%S('=N`@&@`A!MV`$32W,``"."5)U='!U=.\"`&`$\0-O8FIE8W0M`%`@(&)S9",'(75SO`$`/06#;B!I=',@(D`\`!(BO01&2!F#U%F:7)S=)("`*8!(&$@0P40;\,/`=X*%BYT``/9`P*G -M`0"_``*<`0&%``:X`0!V``##``"\`Q)EDP`",0\@;'ED`0#,``"C`0:`!3%W -M86Y_!1)T'0\!-@(!6P,`8PP`,P!!9&ES:RP#`WX&N6-O;G9E;FEE;F-EP`$` -MB0`P;6%K>0"0:7,@97-P96-I;@0!T`$"J@$`.@@P.B`BDPH.V@T3(KD"`-X. -M(F%NZ`(`I0<`$0,"6@<0+&,`0&1E`0-)`#!C;VY#`F$Z("!687+N$V!I=&5MH(`N47`),``'4` -M`!<"`/D$`7$``7$*")<``9P)("XSHQ:L`D'-A;64@9G5N8S`<``$D!0'-U8V@G`%`J(&5X -M84D`U',Z(%-O;64@6]U(&UA>2!F:6YD('5S -M969U;"\"!D4`42]M:6YIA0$18>,!46%C="!S8`"A(&1E;6]N2#R`I!I;VYS+@H*5&B=`?("<"UL979E;"!D:7)E8W1O%#36%K94QI\`!,GK0`#)`0` -MDP``3@#U`2YA;2P@86-L;V-A;"YM-"SA`$!E+F%C_P```@`2+50`)'1OJ``, -MH@2R+"!O;FQY(&YE961\`#%M86GV`2-E7-T96TZ"B`J(+@$=2XQ(&5X<&R#`@,O`P!"`0(A``2: -M`P,S``"(!`\T``L`(@`,-0`O870T``PH870S``8!!O`%+C,@9VEV97,@86X@ -M;W9E] -M!;!I;@IA(&YU;6)E"`"X!!,BO0(R+F@BJ0"`:&4*2R"```[!P$C"4!A=71O -MDP8`_P(0><$",&5C=)D#$635``,<`@5X"1!F+``!MP91*B!'3E5U`0(U`B(@ -M**L)`+D!`!H`06QO;F=0!F)N86UEB,``!DT%``)"`$```I58W)E873/ -M``%U!`\&`0("J@,#OP,"O`(/'P,8,")R9:`-46-T960B1P,"3P#$+"!W:&EC -M:"!W:6QLB@`!5@`%R@%A(&5X8V5P0`4`N04$:0)1('1H871##C%I?P(-F5A;;4%`A$+@"X@(%1H97)EO0\C;F_B!P""`@/?"`"3!$$@ -M:6XMMP^"(&UO9&EF:6-D"_``;W(@0`&EP``L!!3 -M97-I9VXE#!)EB`4`0`0!7@$X;F5WM0,`\`0`>P`#GP$`>P`!APD!HP`"2@P` -M31$B:7)`$!!I>0<280D!`@P"(2!B-PD`C`HQ86)L``8`_0H!#``!+`L"U!`` -M:``".P!"96%C:#T!(79E4,`4&EN9&5PJ@`E;G0B`0`8"0`/#Q!C0@42 -M;VP-!C4*5"!7:6MI4@PP:6YGR0`P:&]W40\!LP,09$X(`]H``BH!(4]N/P@` -M]PP"8`8`TQ$`4`8#S0`!<`!3;'=A>7-S""IE9(H(`D<`<$DG=F4@870M#0", -M!S!T;R`A$+)M:7IE('-T871I8U((07!O;&PV$E$N("!)9O4(061O;B>L$I!E -M>'!L:6-I=&S9"6)V;VME(&'Z#Q%C?PH#SA$@("C2$"4@8?L*`*$!("!AZ0`! -M)Q`"+0`(S0`4;_D(<"DL(&ET('=P`$$@9V5T&1,!70H`I`0W($EN;@`W+"!I -MG@`!40$#FP`B96[)`07L#$7`U`-%A=&5V97(@8FQO -M8VMS\```[@2X'<70@82!T:6U7`W%O8! -M(71O(@`%2@``XQ,A8V6%`"%/;I`#&V7#``+D`C)P`!,@%1``:A``"@$1:2$( -M8VETP"`,D*`2L` -M,VEN("#U%F:7)S=)("`*8!$6%P$A%O\0T` -M]@`6+G0``]D#`J#B)A;N@"`*4'!C0*$"QC`$!D97-PH@``;`0!Y`,`7,N -M"B05$6:X#007&0.A&$0N"@I1$1:@/R`@27-S=65S/U(`$2H%&78Z+R]W=WF4@6]U(&1O;B=T"B`@ -M(&5X<&QI8VET;'D@:6YV;VME(&$@<&%R=&EC=6QA2T`5RH@8V%T:0`K871H`&ES:6UP;&6U`$!T;V]L -M,P$`0``#`@!R>F-A="P@8@<`$G@'``!)`0#^!@`G`%`J(&5X84D`0',Z(%,R -M`U1S;6%L;!4`!#X!`%(#(6%T>`:`;6%Y(&9I;F30`C%F=6PO`@9%`!`OKP2#R`C!I;VZ*!B!4 -M:)T!,'`M;`P$HB!D:7)E8W1O\`!,GK0`#)`0`DP``3@#U`2YA;2P@86-L;V-A;"YM-"SA`$!E -M+F%C_P```@`2+50`)'1OJ```(`$(H@2P+"!O;FQY(&YE963%"!!YR@4!]@$C -M97)<`05P`"1I;F0`D"YH+FEN"@DM(*,*4FQA=&5S9P`18C0"`68!$V6U`&`* -M"D=U:63S`"@@1%0&!-(!`G4``/,!@"!S>7-T96TZ`@L"N`0A+C$M"@#-"0$W -M`0,O`P!"`0(A``2:`P,S``"(!`\T``L`(@`,-0`O870T``PH870S``8!!O`% -M+C,@9VEV97,@86X@;W9E2XS30`"]P,2(FL#!:L``20`4"(@=71II`59(&-L87-$``'O!49N86QS -MG0`PP$2+8($-7,N-:H(`J\``!D#`/T%-6UA=-4,!&,"!98!`$P```H"D"XU -M+"!M=')E90D``&\`7G1AP`(2PF!:&%R9"UT;RTP!@1;`0%'``!!`&%M;V1E``$=`U'1E;J`('(0"P;V-T970M;W)I96Y$$`!@`@$> -M`*%35E(T($%30TE)=`(!%``"4P`/,@`%$$+9#A%Y+@"@("AB:6\+`OH#`*D"!B($`9L!`MH`#Y8#!0'(`V$B;F5W8R*;`P$S -M`"=S:+```1(`#T8#8P0%!`);`0&)``]9`P`*%@,S5VAE`P(`OP@#U`(2<^8% -M87)E0`&EP"2:7,@9&5S:6=N0A4B8F6^`@!`!`%>`3AN -M97>U`P#P!`![``.?`0![``&'"0&C``)*#`,*`P`X"`!O$#)T:&$)`0(,`B$@ -M8C<)`&H(`?L5(6]RSA`!#``080P!`M00`&@``CL`0F5A8V@]`2%V97,#$WE# -M`%!I;F1E<*H`)6YT(@$`1`T!Y18`0@42;VP-!K`+5"!7:6MI4@P##!,P:&]W -M40\"I@<`3@@#V@`+H!4$_`0`\PX`4`8#S0`!<`!`;'=A>48!`-T!*F5DB@@" -M1P`/T!?_X`GZ`Q!C-P8`!1C"871E=F5R(&)L;V-KU0H`[@<3`<0-0&)A8VM``S%F2!FP"`8`.`"L`,VEN("#U%F:7)S=)("`*8!$6%P$A%O_P(`]@`6+G0`!L`.`048`"<&`)P!`84` -M!K@!`'8``,,``H08`;X``NX4`(46`(<``J,!!E`=,7=A;IL8$'3+&`,V`@%; -M`P`G'``S``"C$0$L`P%K`P`+#YEN=F5N:65N8V7``0")```P%`*!$U)E#@#B``Y6#A`L8P!`9&5S -M<*(``&P$`>0#`',*CR!S87ES+@H``0#_B0`[%P^?`4T/`!X+434@("!# -M\2`!F0(#8P``4AT9R965" -M4T0P`#%3>6TW%P3``0.F`P#E`29E`I@`!58!$TDV -M``+=#`!&!`!/``+$`!4GJ1H!U0().`,`R@HR:65S3@`"F@1A,3H@3F5WF@,* -M2``$&P-9$@3("0%!``.) -M!1`P"`(!LB<`>`!V($UA8R!/4ZD"`#P`!ZX$`3H``T(")#`Z4``'ZP``J@D# -M_0(05`T%$CL^ -M+T`@97AI$14"IP0#U`<`&@$`E!T#C0H"8P`&FP`#700!WR$&$`4$!P($&P-@ -M8R!C;4',6UA=`P$`]P%03`Z($0V,$%D97)E)"HS8V4@ -MPP,"``>`!`OX8`0$2%3-4``01`0#?(S,@+5;B -M#@93!`9K"S@R+CBK$3=*86[(`P!V"P',"`8*`P"3`.`G96-H;R!N;VYE>&ES -M=,`0!(`!)S,P`% -M7`$`9``',P`"9P0"H1(`_S-!C```D$#!#```)$Q`I@!02`Q+C=E!Q$Q]0`((0!P;'IM82]X>EL#`^$" -M`&<`!!8@"0((`D`$`)\%$WGR#@!)`!%(R"0@(&?^$@)%``#8"01!`$!/<&5N -ME"5P(F=ZP`%B0)` -M061D:,F -M!#40%&F3#P!/`0#$`B)S=1TB(@H)(P``GC<";2(A -M`X,($CMJ$]-"``!904`*`)`4$1&(!$+`.0Q`-@(,FUA -M;BX(`)D0`,,(`NTU$&60#P&;#P@6,`%-```P#`!*`#!-86JG(P/[#@06"@-# -M!`$!`P!"$4!#:&%R_PM`5VEL@$+60`03I8P`_H.7V9R86UE9``+8$AI -M9V@M`,<'071A;7"6"S!46L6&B^O`P** -M%@"[`0_Y`P(-20`*NPD(NQD"]QP!2@`$6P("^0P08[H!(&5R?B4I=&]V&0!- -M!@!\-`(',0&7!!!I=B@!'P$`!0L`BP50"@EP96^T"P&))0"D`2!I<-H##XH` -M!@VV``M5!P>."`$*$@'Y#0TH`%8U+CDP-3P*`0D!`M(4#RL``ALT*P`#3PH/ -M5@`!%S,K``#^&`/C"`\K``$(#@D!*P`%TP$)U```K``(B@@**P`04S`+`(8& -M1'!R92W<"P"4"``["0!F`0E,`!(VC!@#\P,:.$<#!#0#0#H@5&C^`0`!%P"< -M"@";*4%R;W5T)@/":G5S=`H)8V]NH6`7<``H(1 -M`($"`BT%$SI=!@3G!@8.!P&I)W!G971O<'1?(0=2*"DL"@DR-P":`0-3#@+) -M$@$^```-`A!OS"46;$,5$2XA&@:\`*!*86%K:V\@2&5I@0$0;K$`)6%RCS8# -M%@4(]!@"0``"%`L0.`D1\`9D!P'%"`(<0`#80@)K -M*P"1*5)D(&)U9\4"('-IP@$`5@$A-&*<(A=YKP$+>`$7-$\!`2D`!24##]@! -M`3!F:7CK!0!L`@3\'@JP$P`.-`#-``!&!`$S&`8C!@&^'`%F$0!+(0;V'P)I -M`P`_#@`)"1-AW4-S(E-C;W1T(MP6$"!4```+"@6>`Q-M@SX0<]0&!#4`DDME -M97,@6F5E;-0"`#4`!4$``3T*`;T?`-,4`),.!!L!!?(`2$9I>""Q.I)N;VXM -M97AP;&\!$`!M%A!E9`T";0$"92V5=F5R9FQO=W,L:0`&CP#`1&%V:60@4F5M -M86AL]R("=14!)!TR;VENP!P`QCL`1`L-C0#P"$-O;&EN(%!E`0`O/`*``0..$@(?`P!H -M0Q%SB1%0(&AAFRJ1A(MN`01;"\R`0(`($1IRS$!8`4D.B".`.%R979I9775R;/E&8C0V;61G#H@16YS0T`"P3DP9&ER"AU`CH)$'#L.P#<%P*W -M!`"Z`$`M;F\MN@HC9FF..#1L:6+-1P-O%``G``NH`&(Z(%-K:7"3&`&S`0%C -M!0%*!0/_!`(Q"%`S,BUB:18%,&9?=$<`,&ES;ZD^!"P!$F*[(3!T`*L`""@`!-XC`<8!("URD@8@+74E``87`073``$>'P,\!"PN:+L# -M$%.X$3!I9FD##P`J`#5I;F=0"R`N:,D)!I\&`+`-`7-'(&5DE000:0,($7DX -M2S!I``&8!P#5$P/J"`%\"0()!`8]"P#B -M`@]+``\`)@$`JP``^`@895L"`UH5,"!U=1L1,&1E.PP!$7F0#@*X#0'4#Q`M -M@2XQ96-O@052;&]G:6.Q%0(T`!!S-```3A4"3R(!]A0`=@$!&``"6TD"FQ<# -M?0(&U`@)4P)$-"XQ-'H>0&0[(&E`!@S!$`B"6%*"@!3`0'P -M"!!G2P41+W8C8"!M:7AU<-\I!L@6`K$``,()%&G$+R)D"NT6`&<$`H0I`1X' -M$B[('P;F#@RF`!4SI@`"DQ@%^0(#=AT`G081+$P"`),`$BR:`!`L+`0"G@`! -M.P$@8V%E$!%BF`LQ=F5RVP,$TB).$F7^ -M`4!355,MW0D!K!@'C@``TPL`@0!@(&-L87-HF@H"9RL"*``5,4D4`"@``!<% -M`$8#`ID&":Q#$"R"))$@2V%I(%=A;F?R``8\`!);FP(075\)0&UI="!-*@+L -M4P7@(E!D979I8U8!``@HI``"H`2!B87-.$62(`P$7"0,5 -M`0;#)0-,!0(J(@9U``I+`&1697)I9GE-!`%6"`!)&C%G972:#0*E/`%B"P3- -M50!Q&@&.!44R+CDN@@$".@``2`$2;%0Q$&(3&0';"P?A#R(H+:4/0"UZ*2RK -M`P`A#S$);V:J#3!R;6%>$@">'S)E=L"`9P!!U,'5&ET:`H)@P(4&"%`P+CDN,,8'`($'`LY3('=IH14S -M=7-E)QL%-``@0V^/&P`:"U!I;FET:7P&``\E!#$0`,H!`PD"!)@``L<##I@` -M%3G*!@+```4H``;4!0!C`0*--`!Z!0*)%PED`/`#.B`@+6$L("UQ+"`M3"P@ -M+68LFQ@0=#X8-"!S9?LO`)4`(2UI'0@S+6ETF``#\0\.F``:.)@`!B@``2LD -M`$4`#7](`"`4`OL(<64@>F5R;RWZ0`!Y!`&<)`.,0!`LF@H$C1*A1&%M:65N -M($=O;*H$`*,`$&)Z#0#I``&/`P").!!YR08`*$$`L"`!)@$"I"H/Y@$`%C>V -M``(I``(:$`[?`!8V*0``>`(#61L1-Z@K$"\%"0$%`!!?N!0@+F.A(0"""S!S -M("*B!4`M8R!\*``P("UXTTHE<'GX'0%T``,0&Q(WB05082!C;W64'"-O9I8$ -M!ZTF`.4%`7\``JD/#J<`!_(5"B@``%L``*D#`:<``04`$5]I`1!?WP0A8GG9 -M,0)%`7)E('5M87-KI#\#0`$#^AX.<``&6`D"RP`%'@(`A@<&-%($A`)0+2UD -M:7.G$%(M>&%T='D*!A0`=6%C;"P*"73M`?\`4V%M=6QI(%-U;VUI;F5NC``- -M!SX)`?P`!8P`!C\"P$QA<&\@3'5C:&EN:=4%`'I5`4D"`$X<`55)``4.`=() -M`9HD`TH%`),!(&QD5PD!52X`^AL$;P0P8G5GQ@4!&```0`&P;V8*"2)L96YG -M=&B>%)!E;F0B(&9L86<>"@5A`!)S'P0&5@$"3@`#`@01()L&`5(&`3X"`*D& -M`2\$!#<`!?,#$$:C`4`@8W5T:P!`)!0HH``)X```E"`#Q -M!0`R%`8\`@.Z#%!C:&EL;`<7"SL`$$^0!@#9$`#P`@+W!R(@87M6("!OZ1`J<;`JQ8`LT"`X\;`"T9`$\%`DHT -M`"U7``\($GF&``9S!A!4!`8#,P``%0$`.`03>?,0`%@2`$($`,8E`+LB`^8) -M&#J8`@)M"``U""!E>-06`$)%!#@``>8>,S)'0G\F,S%40F@!`E8Y#0P%&#,N -M&@`M`08H`!)##P@"/P`\T%`*`&4'-K:7!P&`$# -M.@(%L1,!K@T`,12E97AA8W1L>0H)82L@`.87(#1'M`@#X!(':!$!G0$"&PX' -M9P``6P$`9@`'0P)0*#XX1RGC``4^`@#4``#<$D-A($`;D"$V3R -M-`%Z$``!!!$@?AA@"@EI;G-TA`80P"!$`>`$D-`AL$`;H*!.@K,4-64UD? -M`-A()W5LG0$+M``'^0X"*0`/Q@P#&#(;"`%1``4H``93"@HF(A(G3R8`A`H$ -M1"$!E`(19"@%`*`"!.,3,F-R:5@84G-E8W5RN"@@9W.`+0)]8B`@8?\5`/\. -M`!IG$PF5'P0M``DC(%!A9'9I<^9;(W,O"@&F+5-!+3`W.C`U+OH`0BYA``'O``>L!P&*)`'R/0#]"P!Y"`A:$`#@```!#P",`P!E*`#V'`:? -M)A`L#1P!`0PD"@F&%0))$P11.24@=!86`I<$("YH+!XC863%"6-L96%N=7!^ -M*PIB`1(L'14`#`<1P=V]R:V5D(&]K -M87F+'`'.!Y!I="!H96QD(&_#0P"H!0*:``!A&P&J``"]-0"%*@(7(@#Y'2!U -M;4$P`'P5`EP.!/X&`9Q#`/$08"!B`/HP`?@"!)\` -M`6``$%\9`19E^30`E@X`J``"[BP0:'(,`2X=@'-O;F%B;'D@N0$`$A4"EPT` -MR34`IAP7>8(3@5-K96QE=&%L?`L&C`@!70<#[`$&`@4+[`$:,>P!!B@`4$9L -M97-HR1<`U01>>H#0F%C:&73`0*M!0`"$Q!N)`$0;R$@$'*D!@#,`0"_#0!3$3!R -M:7.V4B!E;KH'$&E48P&F&`-R`@!'(#`*"61E`S!M:6QG#@%3!`#Y"@"1.`^! -M#`09,9P7`2D`!58(!!,2!G($`TP``@I+`/D$"2H"`&L!`JT!`TL`!B@``*0! -M`740,7)E8W\.%RVH`042`@$:"@7$.#$*"2A*(``#8P#?+0!1*03B%@#%'`"I -M)`%."0%W-P`:,$%C:"!B="-1+BD*"48%!$,@:7-O*`$0;:,W("@I>6H""`!A -M86ME9&5V1R`%MP,!R@$D+F/I``4$`@OI``<`"@`T`08H``(T`0+/`1%F[R(! -M@@<`H!\!'!4@;V[20T-/4R!82P$%,P<+8@`([`D%!4X`$1"_X`!S8))@E,.Q8`@0``[`0"NB`0 -M;F8=`2HA``D!`'4$``0#`/Y/1&5R:7AC``6E!PMC``CE"`#$`0,:(PQV"R681(N@!#AT` -M`1`"$B`<*P:[``(?#@!U-P&C``0V`#)I;VZY,0(Y,0#7!`%A!B)E9.H=,&QI -M:U@1`-\I!SD"`O4]`&("\`%&965D8F%C:PH)87!PA -M*P8P)@',``5W``)N3@`N"J!N9FEG+F=U97-S"#`!#@`P`1`T!%PH`FD``.0``C\"`,15`HLG -M!2@!`>H#!``7`-@%"3H)(G1O"#T$B`$%-P`,B`$'N04*B`$12`T'!$<-(',[ -MD`T09=`$8&YU>"]F2!O8G:N<@!F!0%K&P/>*P(]$U%T -M:&ES+/,((6UEO"@`C0H(Y0`35Q`$-705). -M&`(&"B`'MP`!:@0'8@8`7`$&*0``*Q0![0$`G@(`>`(QD``/X&`_L7`"8``#X`"?P9,F]W*<2!G;V]D_0$&]0D2,ADD$6_J0P'7&@"_)B!O9NP+%&$' -M*@^]&@-&,&(Q-Y,,`&`H!HD=`7('`*\!-$=)1"<%`@P#$G,`!0-%`R)B>18` -M,6EN9Q@!(7=H="X!MPX#3AL!W5$!YCQ0=&]O(&9,0@##!P#.%J%N>2!P65S(B!0)@TQ;L.R4`(A=&76 -M'P",'063:0'J``/]!@`)`P"'#@#]"#!'96[8``&\`Q,H<2TP(2D@4#L!RQT" -M%@$`1!$!0@`!Z!^R:7,@;&]N9RUS=&%U*C]B=6<*`0X'1`<*"@$`E@<28``?%!@&>``5/`Q%""5P$\10" -MI`(#ODCQ"SH@7T585%)!0U1?4T5#55)%7TY/1$]41$]4E@$`[AL,(0!Q4UE- -M3$E.2XHA-&5S94\``>D-`*M%`;XI`G0&$2Q%``!5%P$Y+B!B9=X!4"!D;W=N -M$PX'7@$@=V@R`0$E``,1"`%/`"%B>4$```A9AAQ``(P$$VQ4-MQ\!&@$`)1H` -MC`(#Y14`\C(!B6<#C&D!0!`"M!4#Q@,`HS0!HA@$9P$!1P`A87+;$2`H:J`2 -M(&9E#1$%'@L##1$$40`@9&6>"1!BH04!%#6]U0P`$2AH""6@2*5=``)L` -M86]V97)R:4(1`'8*06%M92^;,#`M=&^T5!`O.QMB;&]O:W5P'`$3*$E]"M4! -M$6$63@&92T)86%@H@@M29V5T9W(/`%!B;&]A=!P%`*(!+S`YDP(#%V$;!0`H -M``4G``3)`0-^!@3"`0>"$Q`[$@$!VAL`H!X#408!"!T`?$,0;]T^`(0"`"T% -M`C(N`215!HMW`FH)`2M:`]`&$%,B-5!F96%T==\(`O87$&Y[`07*.P"I!@'# -M'@>7`P)'%0%R`0)R`%%I;G9O;-0!!/,!`&$+```"(&]FSQ'B(&]V97)H875L('=I;&S")@&X+P,Q-@*D -M"P%^``**+@9'`0=\>`+9$`#/`@+N&PK=#@C4``+-``)')@&<.P-W!P`<)1`H -M]C@$OTH`L00!@P$`?0(C;V8,)Q!F/1,+B0``RQ\071H -M-`L!8@,`K`,!K`(">``"NQX&F@``V`D+ZP`'EQ<`V@4"@0$`&QLP`WE3@'.'@(:#P.8)1$V[@@0(.MK`7TG$#L&`!%L32D` -M_P4@;VQ/$!)H(R@"V0`!1PH`7P`!B`$`]@<0)Z<6$7)5#S!K967I<0&O)U!L -M92!U<$4'`&,T`CP``'8((&]NRRM"3$1%4G8`HE-534U!4DE%4PK]$`*M!0]D -M`P`:,2$!`R$C$#99#@B9)0!6%R!N9&\!$G390P6(#PF6(S(@ -M``7\`1!)N"8Q<&]RK00+9DH`HV50=&EL;"TP!PQ?-0!B``#E!0X.`1AS(VD! -MV!-\+6]N;'DN*7P`8%)E;W)G81YA$&1M6P)-`0#;!5!P86-K89=+!P)X`-@! -M$&6X"D`N9WH*S&H`:A,!AP0!BAL2<_@4!_8$`.L%`M\,`H@X`W,S`,\!!(X% -M`GL6%#I[!P%2*@"2(0$!40$_.03W!A(LOB``>0`W4&%X^@$!7AP"%G\1+OY- -M`@`;&S7:&0&^`0/V`02U$0E'3P`^#@1=&0`?"P9?&0"[!0!&$P*V!`(?$@!S -M#024!`KI2@)D``+D2@"N```\%%!A@8"\PH5-947`)5*0&5T96-\""1A=*4= -M`:E*`5<5`=@$`JLG`"P3`W(9!<`!"WXZ`0T2`/0``HD``_`%`1`.`F8"`*\` -M$E>/6P")>Q,@P"229VYU=VEN,S(N-H*A9F]R9V4N;F5T+P4>`_H.`2\"`U8$ -ME%II<"]::7`V-.X#"5$!86X@3F5L<\<;02U,+RWI`P#V%P$K$@O``P-P`P*M -M#2HU.C$"`U\&`55%`%X#`2D/$&5>"1%YW1$`/0($[D,Q@.\.@:Y -M`P!Y``,\`?,.>'-N:6PN86YT8F5A:,2$#32`2%N -M>2LJ$"UW"`#%/2%L92\"`=01`$@Y`58#`1M2`U8`(&%L)0X`'0$!U1\#[!8! -M`!H%,3L$&9I;&4``0!+X3`P,#8T-"``,#`P-S8U"``B,#(0`"(R -M,`$`_P<@,3(S-3,U-3,U,3(@,#$R,#(S`"`PEP!+`@(`KW5S=&%R`#`P8W4' -M`0M22T`5RH@8V%T:0`K871H`&!S:6UP;&5H`@6U`$!T;V]L -M,P$`0``#`@!R>F-A="P@8@<`$G@'``!)`4!S=6-H)P!0*B!E>&%)`$!S.B!3 -M,@-46]U(&UA>2!F:6YDT`(Q9G5L+P(&10!1 -M+VUI;FF%`1%AXP%186-T('-@`*$@9&5M;VYS=')AP0$`#@,G;V9>`0-)`#!C -M;VY#`O`".B`@5F%R:6]UP``"@+Q`F%U=&AO7-T96TZ"B`J(+@$=2XQ(&5X<&R# -M`@,O`P!"`0(A``2:`P,S``"(!`\T``L`(@`,-0`O870T``PH870S``8!!H`N -M,R!G:79E<]\&@&]V97)V:65W\P(`H``$NP4087$%,'=H;Y$"(RH@V0>%7W)E -M860N,RP0``#1!1UE$0!17V1I]!;!I;@IA(&YU;6)E`D09BP``;<&42H@1TY5=0$" -M-0(F("@$"P`:`$%L;VYG4`9B;F%M97,L$```!0L3(!$``&,`4G-P87)S?`(A -M`@@;W#+`\!A;"!2;V-KB,``!DT%``)"`$```I58W)E873/ -M``%U!`\&`0("J@,#OP,"O`(/'P,8,")R9:`-46-T960B1P,"3P#$+"!W:&EC -M:"!W:6QLB@`!5@`%R@%A(&5X8V5P0`4`N04$:0)1('1H871##C%I\+`OH#`*D"!B($`88!`MH` -M#Y8#!0'(`V$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0%!`);`0&)``]9`P`* -M%@,S5VAE`P((T0X"Y@5A`3AN97>U`P#P!`![``-S!`![``&'"0&C``)*#`!-$2)I -M7-S""IE9(H(`D<`<$DG=F4@870M#0",!S!T;R`A$+)M -M:7IE('-T871I8U((07!O;&PV$E$N("!)9O4(061O;B<<$Y!E>'!L:6-I=&S9 -M"4!V;VMEO!(!ZP`!?PH#SA$@("C2$"4@8?L*`*D`("!AL@$!)Q`"+0`(S0`4 -M;Y4(<"DL(&ET('=P`$$@9V5T&1,!70H`I`0W($EN;@`W+"!IG@`!40$#FP`B -M96[)`07L#$7`U`-%A=&5V97(@8FQO8VMS\```[@2X'<70@ -M82!T:6U7`W%O@``S0)P82!S;V-K9687`CX#27=I4X.``P1$2(A`0!:""`L(E`(H"P@8V%P86)I;&D2%`8# -M`07Q``+S#P&W!`CV!0&7`8`@:6YD:79I9&P.`]L(`(4``#H2`D(``*P+`-$` -M`#8!(71OK`TP9&%TUP``!0X6.BX!`L@)`#T`$F'L`@#)"@$K`#-I;B`G`0"/ -M`C!A9&1T!`!,``CW#`&I"@,>#U%F:7)S=)("`*8!$6%P$A%O\0T`]@`6+G0` -M`]D#`J0#`',*'HC`,$*3F]T97,@86)O -M=724`')L:6)R87)YT0#P+G1E8W1U2!S=')E86TM;W)I96YT960@F4@2!I;G9O:V4@82!PZP"`=6QA2!F3X`!8P``0`"\05R;W9I9&4@96%S>2UT;RUU`0"0 -M:7,@97-P96-I;@0!T`$"J@$`.@CS`SH@(G!A>"!I;G1E7!1`GH@1`9W)A;18"&%)`$!S.B!3,@-4`0-)`#!C;VY#`O`".B`@5F%R:6]UP``7P%V875T:&]R,&`4D!A69I9W5R92`M#``"1`"U'2(`")P==8-(")C-`81(B0# -M`#@,*6]L30`"5@$&ZP,!*0$`%@D`C@$/;0$!`*(&$'7?#P':`31E"B>P`"-E -M)ZT``R0$`),``$X`\``N86TL(&%C;&]C86PN;30)#0/M`#`N86,7`0`"`!`M -MH@(`GP`$J```V0X(H@02+!H.`-<+`%D+$'G*!0'V`2-EPH"MP(29:`,`!(&0'-E<77J"!!S"P4!/@$`=0``%P(` -M^00!<0`!<0H(EP``/`DS>2XS30``[P0R92`B:P,%JP`!)``4(@L+62!C;&%S -M1``!'PE&;F%L"`"X!!,B!0XR+F@BJ0`R:&4*7PP0(+`)`/H``!0`!.D&`W((`G\"-&UO -M5$P`P%&!E2X`L2`H8FEG+65N9&EA -MU!%C;&ET=&QE$0`"D!8$7Q:10T0M4D]-(&EMMP(0*#@.,"!O<,L#P&%L(%)O -M8VMR:61G9>\!`DD`-%I)4'4$!$``('5N,0L#!A<_;W(@ -M'A=`#PL7`-!-:6-R;W-O9G0@0T%"YP($2AQ=4 -M`)H`,6QZ-`X+`,`!`.47`2$)!`@!```*`IP0!4L!`'4$#P8!`@*#`0._`P*\ -M`@\?`Q@P(G)EH`T`$!81(D<#`D\`PBP@=VAI8V@@=VEL;.L8`'`(`!D$`U\! -M0',@97@M%``"`@"Y!02)$0(+%P-:%P%1``7I$C!S("A3"@$T!`"$`0,S!`#T -M`V`L(&5T8RGO"P+Z`P!L!`!M``*-``&;`0+:``_(`PIA(FYE=V,BFP,!,P`G -M#0#46-H86YG?@$W;6%T -M(0"P;V-T970M;W)I96X!`P!@`@$>`*%35E(T($%30TE)=`(!%``"4P`/,@`% -M84)I;F%R>2X`P"`H8FEG+65N9&EA;J(!8VQI='1L91$``OH`\0))4T\Y-C8P -M($-$+5)/32!I;;<"@"AW:71H(&]PRP/`86P@4F]C:W)I9&=E10!B2F]L:65T -M*0$![P$"20`T6DE05@,$0`#`=6YC;VUPFEP/@$Q:6]N&`%=8GII<#(6``1\`4TO3%I7'0"B;'IM82P@;'II&-E<$`% -M`+D%!&D"L"!T:&%T(')E<75IE@4G87C*`E(@*&9O?P(-F5A;;4%X'-Y -MU`P#P!`![``-S!`![``&'"0&C`%0@;VYL>0H#`#@( -M`+(``1X#`*8$`@P"(2!B-PEQ4,`4&EN9&5PJ@`E;G0B`0`8"5!AP,1<#4`T6%T979E6QE(&%P<')OR`,`R0@" -M^@#0=&\@:&%V92!M=6QT:3$,!*D``@$$`+D(`/X-%6Z>`%`@(&)S9",'(75S -MO`$`/06#;B!I=',@(D`\`!(BO0012!F -M4X.475S92`B(0$`6@@@+")0 -M"+$L(&-A<&%B:6QI=/8"!`,!!?$`864@05!)<[<$"/8%`9P"`,D*`2L`,VEN("#U%F:7)S=)(" -M`*8!(&$@0P41;U`'`/8`%BYT``/9`P*G`0"_``*<`0&%``:X`0!V``##``"\ -M`Q)EDP`",0\@;'ED`0#,``"C`0:`!3%W86Y_!1)T'0\!-@(!6P,!&@00=(X' -M(7-K+`,`L1`0#B)A;N@"`*4'`!$#`EH'$"QC -M`$!D97-PH@``;`0!Y`,`7,N"E)%041-11(&!DD1X2!B=6YD;&4N -M"@I1=65S^@*@/R`@27-S=65S/U(`UBH@:'1T<#HO+W=W=RXX`$`N;W)GDP`` -M2`$0:+@"$&:Q#S-N9V]8!Q<@3`>`(&1E=F5L;W`\!0@9$02Z$0&L"`$W#`!Q -M```Z`"%N:UT!`%T`!G,`4"!M86EL!P(P;&ESOQ`!G0`05)D!`.41`.%E7!1`GD1(`\A$`%@)S82!F=6QL+98(F-%#A)B!P`2>`<``$D! -M`)()`"<`02H@97@;$T!S.B!3,@-4P``7P%C875T:&]R:1``EPT!\@(`P1,2+NT/ -M4'1O<"UL#`0#Q0P`,`0&";8""',5`.L%`>X/\`4@*B!.15=3("T@ -M:&EG:&QI9VAT<]P`,')E8]D4`C$%`Z`"DD-/4%E)3D<@+0P%`$(4`,H'(61O -M7P8!AP4`S@#`*B!)3E-404Q,("T@9`HQ86QLCP0!#0``^18`OP`"*0`#0`41 -M+3P``5X1`A@`8&-O;F9I9WX+%2T,``)$`+5S8W)I<'0L('-E96<``"@%`ED6 -M`F,(@2H@0TUA:V5,U`0Q='ATB``A<'5G$#`@(F,T!A$B)`,`.`PI;VQ-``)6 -M`0;K`P$I`0`6"0".`0]M`0$`(`T0=3T3`A`7)`HGL``C92>M``,D!`"3``!. -M`/``+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C_P```@`0+60"`)\`!*@``-D. -M"*($$BP:#@#7"P!9"Q!YR@4!]@$C97*N`05P`"1I;F0`@2YH+FEN"@DM]`<` -MYA,22#R`I!I;VYS+@H*5&B=`?("<"UL979E -M;"!D:7)E8W1O'2(`#!P=71>`H$@ -M(F-M86ME(B0#:60@=&]O;$T``E8!!NL#`2D!,2!I;DP!#VT!`3!A2!N965D?``Q;6%I]@$C97)<`05P -M`"1I;F0`\@,N:"YI;@H)+2!T96UP;&%T97-G`!%B-`(!9@$39;4`8`H*1W5I -M9/,`4"!$;V-UF04"@0$`Q0$R86QL=0`!MP&R'!L@P(#+P,`0@$"(0`$F@,#,P``B`0/-``+`"(`##4`+V%T-``,*&%T,P`& -M`0:`+C,@9VEV97/?!H!O=F5R=FEE=_,"`*``!+L%$&%Q!3!W:&^1`B,J("X' -MA5]R96%D+C,L$```T04=91$`45]D:7-K%@`@;F30`0@^``,<``"9`!!V7P$" -MMP)A960@8V%LB0<0<]0&06YC97.M`@"3``!U``%'``-"!FAE($%027.7`'-E -M;G1R>2XS30`"]P,2(FL#!:L``20`4"(@=71II`59(&-L87-$``'O!49N86QS -MG0`P]!;!I;@IA(&YU;6)E`D09BP``;<& -M42H@1TY5=0$"-0(B("BK"0"Y`0`:`$%L;VYG4`9B;F%M97,L$`!3;&EN:R`1 -M``!C`%)S<&%R'1E;J+``-J`0`9`]$J(%!/4TE8('5S=&%R6P`"$``R<&%X-`,"60<# -M>`('(0#`;V-T970M;W)I96YT%P0@<&E^"<8J(%-64C0@05-#24D4``)3``\R -M``5A0FEN87)Y+@#`("AB:6B,``!DT%``) -M"`$```I58W)E873/``%U!`\&`0("J@,#OP,"O`(/'P,8,")R9:`-46-T960B -M1P,"3P#$+"!W:&EC:"!W:6QLB@`!5@`%R@%A(&5X8V5P0`4`N04$:0)1('1H -M871##C%I\+`OH# -M`*D"!B($`88!`MH`#Y8#!0'(`V$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0% -M!`);`0&)``]9`P`*%@,S5VAE`P(`?`4#U`(2<^8%87)E`3AN97>U`P#P!`![``.?`0![ -M``&'"0&C``)*#`!-$2)IF4@``%1`0.;`")E;LD!!RT``'P`"W$`*&1E$0`#Q@(1+/`` -M`H```(T.`)8!`!8!`$``,&%G82X.`?$)D6-OP,1<#4` -MT6%T979E$P$/`P*A -M%0"V`A!GJA40:2(3`2(`!4H``.,3(6-EA0`A3VZ0`QMEPP`"Y`(R<')O.@$! -MA0%18W1L>2W,`))E9"!O=71P=73O`@!@!/$#;V)J96-T+7-T>6QE(&%P<')O -MR`,`^10"^@!0=&\@:&$Y%D!U;'1IPQ,$J0`"`00`N0A5(&]P96Z>`!,@%1`` -M:A``"@$`/06#;B!I=',@(D`\`!(BO0012!F4X.``P1$2(A`0!:""`L -M(E`(H"P@8V%P86)I;&D2%`8#`07Q``+S#P$_#@CV!0&7`8`@:6YD:79I9&P. -M`]L(`(4``#H2`D(``*P+`-$``#8!(71OK`TP9&%TUP``!0X6.BX!`L@)`#T` -M$F'L`@#)"@$K`#-I;B`G`0"/`C!A9&1T!`!,``CW#`&I"@,>#U%F:7)S=)(" -M`*8!$6%P$A%O\0T`]@`6+G0``]D#`J#B)A;N@"`*4'!C0*$"QC`$!D97-PH@``;`0!Y`,` -M7,N"B05$6:X#06Y&0*A&$0N"@I1$19`/R`@2:T9(',_4@`4*I49 -M1G=W=RXX`$`N;W)GDP``2`$0:+@"`%<`0V]N9V]8!Q<@3`<@(&18%B!O<#P% -M"!D1!+H1`:P(`3<,`'$``#H`'VYD&O______________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________:E!I=F4@95^*JRTH$0``\1%N -M=')Y(&)E"B`@(&EN9&5P96YD96YT+B`@5&AE'!L86EN:6YG1@#7:&]W('1O(&5X=&5N -M9"P`\A8N"@H@*B!/;B!R96%D+"!C;VUP2!A(&)Y=%<"82!A('1I;10#<6]R(&UM87#:`$%E;G1I -M#P,"_`(`:0`09P4#(&ET3P`)H0!A="!O;F-EA0"+3VX@=W)I=&7#``+D`C)P -M0"0 -M:7,@97-P96-I;@0!T`$"J@'S!TYO=&4Z(")P87@@:6YT97)C:&%N9V6?!1,B -MN0(@;&P\`0+H`A!DO@$`_04!C080+&,`0&1EF-A="P@ -M8@<`$G@'``!)`0"2"0`G`%`J(&5X84D`0',Z(%,R`U1S;6%L;!4`!#X!`%(# -M(6%T'`@@;6'F!"!N9-`",69U;"\"!D4`$"]#"@&%`1%A!@E186-T('-@`+`@ -M9&5M;VYS=')A=+P`"-E)ZT``V7-T96TZ&@D"N`0A+C'!#`!A#`$W`0,O -M`P`+``(A``2:`P,S``"(!`\T``L`(@`,-0`O870T``PH870S``8!!B$N,[8+ -M$'-E"H!O=F5R=FEE=_,"`*``!0H,`'$%,'=H;Y$"%"JD"H5?PH"MP(29:`,`%L$$'/4 -M!A!N2PT`U@(`DP``=0``%P(`^00!<0`!<0H(EP`!G`DC+C--``#O!#)E(")K -M`P6K``$D`!0B"PM9(&-L87-$``$?"49N86QSG0`2P$2+8($-7,N-:H(`J\``!D# -M`/T%-6UA=&D/!&,"!98!`+````H"D"XU+"!M=')E90D``&\`7G1A"`#.#1,B!0XR+F@BJ0`R:&4*7PP0 -M(+`)`/H``!0`!.D&`W((`G\"-&UO2X`L2`H8FEG+65N9&EAU!%C;&ET=&QE$0`"^@#Q -M`DE33SDV-C`@0T0M4D]-(&EMMP(1*'@((&]PRP/`86P@4F]C:W)I9&=EYP%B -M2F]L:65T*0$![P$"20`T6DE0=00$0``@=6XQ"P#L$P#6$&!R(")D969^!A$B -M9@D#&```H00C:655`0##`0"B`85"4T0@)V%R)U(``?@`$2?]`Q`GNP($/0%: -M-RU::7`F`-A-:6-R;W-O9G0@0T%"+``Q3$A!"@,Z3%I(,@`Z4D%2$0`86!$` -M`1D(!2`&`/42"*\"`'82`"H(`,,/`TP&!D4(,&)E9DH#4F5V86QU0@H`K@,# -M+P(`'P@P*B!U]@40;Q@$``L%`D,"`0H``EP)L5)032!WFEP,A8`!'P!32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC -M```9-!0`"0@!```*`IP0!3H!`'4$#P8!`@*O`0._`P*\`@\?`Q@P(G)EH`T` -M$!81(D<#`D\`Q"P@=VAI8V@@=VEL;(H``58`!I``(&5X+10``@(`N04$B1%1 -M('1H871##@#3$P!1``&Q%@'*`B`@*'T'`30$`(0!`S,$`/0#8"P@971C*>\+ -M`OH#`*D"`&@1`HT``9L!`MH`#\@#"F$B;F5W8R*;`P$S`"=S:+```1(`#T8# -M8P0%!`?.``]9`P`*%@,S5VAE`P(`OP@#U`(2<^8%87)E`3AN97>U`P#P!`#]`@.?`0![``&'"0##%Q)E2@P`31$B -M:7*"$1!I>0<#[A("#`(#(1H`C`H!CQ@#N!0!#``080P!`M00`&@``CL`$66< -M%@`]`2%V97,##V0:____________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________________]G4&)R87)Y9/.(_"(1``#P(2!A=71O;6%T:6-A -M;&QY(&1E=&5C=',@86YD(')E861S('1H92!F;VQL;W=I;F<@9BP`\`YS.@H@ -M("H@1TY5('1A"!I;G1E -M`*935E(T($%30TE)%``"8P`/,@`%84)I;F%R>2X`\P<@*&)I9RUE;F1I86X@ -M;W(@;&ET=&QE$0`"^@#P'TE33SDV-C`@0T0M4D]-(&EM86=EFEP,A8`!&0!32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9-!0`"0@! -ME6-A;B!C&-E<'0"`D0*("`@:0+1 -M('1H870@P`!S@`4=G<&$G.C`%0@;VYL>0H#0&UE -M;G2R``$>`P"F!`(,`C`@8F5``'%R96%D86)L``9!=W)I=`P`$&$,`0($`0!H -M``([`$)E86-H/0$A=F5S`Q-Y0P!0:6YD97"J`")N='\`$'([!``$`#!T:6-" -M!21O;H$!!*X`\`!7:6MI(&5X<&QA:6YI;F>)`#!H;W?X``&S`Q!DE@4#+``" -M*@$A3VX_"!PL`P$`!`0R;6%T<`!`;'=A>48!`-T!*F5DB@@"1P"P22=V92!A -M='1E;7",!^!T;R!M:6YI;6EZ92!S=+4(`E((4'!O;&QUN`'A+B`@268@>6]U -M(&1O;B?L`0"V`/$":6-I=&QY(&EN=F]K92!A('#K`"!U;+T(H&5A='5R92`H -MD`!RT`!$4'`R("`ID!<"DL(&ET('=P`.`@9V5T('!U;&QE -M9"!I;J0$-R!);FX`-RP@:9X``5$!`YL`(F5NR0$'+0``?``+<0`H9&41``.J -M`!$L\``"@``B;F6.`@`6`0!``'%A9V%I;G-TSP&18V]RP,Q:65SPP`!;P,!;P=16QE(&%P<')OR`,`@0L"^@#@=&\@:&%V92!M=6QT:7`E``-3!`(! -M!`#\"E4@;W!E;IX`4"`@8G-D(P2!F)M96UO7,"!8P` -M`0`"\05R;W9I9&4@96%S>2UT;RUU0#`*8.T"!S87ES+@I214%$346[!@?H!N$@8G5N9&QE+@H*475E<_H" -MH#\@($ES7!1`GH@1`9W)A;18"&%)`$!S.B!3,@-4`0-)`#!C;VY#`O`".B`@5F%R:6]UP``7P%Q875T:&]R<\`%`1\& -M`?("`-(1$B[M#U!T;W`M;`P$`\4,`#`'`4$`$&GD!@FV`B)I;M8$`*0*`.L% -M!+T"\`).15=3("T@:&EG:&QI9VATT3`A@`8&-O;F9I9WX+%2T,``)$`+5S8W)I<'0L -M('-E96<``"@%9&1E=&%I;,,$84--86ME3-0$,71X=(@`(G!UU@T@(F,T!A$B -M)`,`.`PI;VQ-``)6`0;K`P$I`0`6"0".`0]M`0$`L`P0=3T3`=H!-&4*)[`` -M(V4GK0``.@\P("H@DP``3@#P`"YA;2P@86-L;V-A;"YM-`D-`^T`,"YA8_\` -M``(`$"VB`@"?``2H``#9#@BB!!(L&@X`UPL`60L0>PH"MP(`318A86R)!T!S97%UZ@@0=&%R+C54`0CQ!`4^$A%S -MU@TQ<&]PY0\#G`$$>P`(2PE`:&%R9!8,`3`&`J@!`X42`(X!86UO9&5R;H\` -M`.@!`+P'<"!V87)I86Y("0`B##!M86[X"Q%PK1]!;!I;@IA(&YU;6)E"`"X!!,BXP`R+F@BJ0`R:&4*7PP0(+`)`/H``!0` -M!.D&`W((`G\"$&T:%P/[`$(N("!0B@FR;&5T('5S"FMN;W<0`0&9!F!EF-A="P@8@<`$G@'`/0386YD('-U8V@* -M("`@*B!E>&%M<&QE'2(`#%P=70I`/D#(F-M86ME(B!B=6EL -M9"!T;V]L30`"5@$&-0$!*0$Q(&EN3`$/;0$!,&%R91`"$F3:`35E"B>\`!,G -MK0`2.M0``),``$X`]0$N86TL(&%C;&]C86PN;30LX0!`92YA8RL```(`$BU4 -M`"1T;Z@``"`!,&1IM`_`$,R!G:79E2XS!`,!JP(2(FL#!:L``20`Z2(@ -M=71I;&ET>2!C;&%S1`"6:6YT97)N86QSG0`P`?$#+@H*66]U('-H;W5L -M9"!A;'-O(@(!3``Q8V]P=@8R8V]M6P%#:6X@(KT",BYH(JD`@&AE"G-O=7)C -M+P`19'4!`!0`!.D&!30'`"P%-&UO<$",&5C=)D#$635``,<`@7"!A!F+``!MP91*B!'3E5U -M`0*Z`28@*+D!`!H`06QO;F=5`F)N86UE'1E;J+ -M``-J`0`9`]$J(%!/4TE8('5S=&%R6P`"$``P<&%X20,B97)9!P-X`@FEP,A8`!'P!32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9-!0`"0@!```* -M56-R96%TSP`!=00/!@$"`JH#`[\#`KP"#Q\#&#`B&-E<$`%`+D%!&D"`A4,<7)E<75I -MP`#GP$`>P`!APD! -MHP`"2@P#"@,`.`@`L@`Q=&AA+PD#*P`A(&(W"0!J"#%A8FP`!@","@$,``$L -M"P($`0!H``([`$)E86-H/0$A=F5S`Q-Y0P!0:6YD97"J`"5N="(!`!@)``\/ -M$&-"!1)O;`T&-0I4(%=I:VE2##!I;F?)`#!H;W=1#P&S`Q=DE@H"*@$A3VX_ -M"`#W#`)@!@,#`03-``%P`$!L=V%Y1@$`W0$J962*"`)'`'!))W9E(&%T+0T` -MC`<`P0^0:6YI;6EZ92!S#@T28U((07!O;&R4#5$N("!)9O4(4&1O;B=TJ`"0 -M97AP;&EC:71LV0EB=F]K92!A^@\18W\*,69E830+$"C2$`!U#`@<`A!A00`! -M)Q`"+0`(S0`4;_D(<"DL(&ET('=P`'$@9V5T('!UG`T0:7H+1R`@26YN`#``%1`0.;`")E;LD!!RT``#X`"W$`*&1E$0`#J@`1+/```H```(T.`)8! -M`!8!`$``(&%G`PX"4`.18V]R0`P&@`A!MV`$32X'<70@82!T:6U7`W%O8!(71O(@`%2@!2="!O;F-\$B)/;AP."\,``N0",G!R;SH!`84! -M46-T;'DMS`"2960@;W5T<'5T[P(`8`3Q`V]B:F5C="US='EL92!A<'!R;\@# -M`$,2`OH`X'1O(&AA=F4@;75L=&EP)0``(040=A(#0')E86VY"%4@;W!E;IX` -M$R`5$`!J$``*`0`]!8-N(&ETP"`,D*`2L`,VEN(" -M#U%F:7)S=)("`*8!$6%P$A%O61$`]@`6+G0``]D#`J60!`,P``*,!!H`%,7=A;G\%$G0=#P-%`0!@ -M```:!!!TC@0#`',*%E2!A8V-E<'1S -M('=H871E=F5R(&)L;V-K71E(&%T(&$@=&EM -M94,`<6]R(&UM87`H`/``96YT:7)E(&%R8VAI=F4@:0`09PD`(&ET3P`)2@!A -M="!O;F-EA0"13VX@=W)I=&4L1``%PP#Q"FQW87ES('!R;V1U8V5S(&-O2W,`/(?960@;W5T<'5T+@H*("H@5&AE(&]B:F5C="US='EL92!A<'!R -M;V%C:"!A;&QO=_H`X'1O(&AA=F4@;75L=&EP)0`#J0!Q'1E;G-I -M;VZ*``,<```J`#!E;&93`0!D`1`OY@"6=&5N('5S:6YG<@&19G5N8W1I;VYS -M#@%R66]U(&-A;I8!)6%NI``B9&G_`/`-(&9R;VT@86X@:6XM;65M;W)Y(&)U -M9F9E2UT;RUU&%)`$!S.B!3,@-4`0-)`#!C;VY#`O`".B`@5F%R:6]UP``7P%Q875T -M:&]R<\`%`1\&`?("`DT'$`H5"%!T;W`M;`P$`W8%`#`'`4$`$&GD!@FV`B)I -M;O@$(FEOX08$O0+P`DY%5U,@+2!H:6=H;&EG:'1S7`8P'2(`#!P -M=71>`C`@(F,T!A$B)`,`J@2!N965D?``Q;6%I]@$C -M97*N`05P`"1I;F0`@2YH+FEN"@DM]`=2;&%T97-G`!%B-`(#<@$"M0!@"@I' -M=6ED\P`H($14!@32`0)U``#S`8`@PH"MP(29:`,`%L$$'/4 -M!A!N$0P`U@(`DP``=0``%P(`^00!<0`!<0H(EP`!G`DC+C--``#O!#)E(")K -M`P6K``$D`!0B"PM9(&-L87-$``$?"49N86QSG0`2P$2+8($-7,N-:H(`J\``!D# -M`)\#@&UA=',@=&%R -M+C54`0CQ!$%A8F]U4P41]!9!I;@IA(&YU;6+R#!=FD0<# -MHP#7+@H*66]U('-H;W5L9*0+`$P`,6-O<'8&0&-O;6V>"`#.#1,B!0XR+F@B -MJ0`R:&4*7PP0(+`)`'4!`!0`!.D&`W((`G\"-&UO2X`P"`H8FEG -M+65N9&EA;J(!8VQI='1L91$``OH`\0))4T\Y-C8P($-$+5)/32!I;;<"$2AX -M""!O<,L#P&%L(%)O8VMR:61G944`8DIO;&EE="D!`>\!`DD`-%I)4'4$!$`` -M('5N3@DPB,``!DT%``)"`$```H"G!`%.@$`=00/!@$" -M`J\!`[\#`KP"#Q\#&#`B`3AN97>U`P#P!`#]`@.? -M`0![``&'"0$K%0)*#`!-$2)IE(7`+4(`E((07!O;&PV$@;D%$%D;VXG[`&0 -M97AP;&EC:71LV0EB=F]K92!A^@\18W\*`\X1("`HTA``=0P('`(08;(!`2<0 -M`BT`",T`%&]S!'`I+"!I="!W<`!0(&=E="#2$@%="@"D!#<@26YN``4F%P&> -M``%1`0.;`")E;LD!!RT``'P`"W$`*&1E$0`#J@`1+%@1`H```(T.`)8!`!8! -M`$``,&%G8?,/`5\*D6-O2!A;'-O(&1E=&5C=',@86YD(&AA;F1L90P` -M\!)Y(&]F('1H92!F;VQL;W=I;F<@8F5F;W)E(&5V86QU8702```@`/$-87)C -M:&EV93H*("`J('5U96YC;V1E9"!F:6QEFEP(&-O;7!R97-S:6]N%0!=8GII<#(6``0F`$TO3%I7'0"Q -M;'IM82P@;'II<"S'`"]X>B,``!DT%``)"`&58V%N(&-R96%TSP!/"!I;G1E&-E<'0@9F]J`/$'("!E;G1R:65S('1H870@.`?$#;F%M97,L($%#3',L(&5T8RDND@"P3VQD($=. -M52!T87)=``2I``+*`/$$;V-T970M;W)I96YT960@8W!I;S4`ME-64C0@(FYE -M=V,B%0`G`'@G;71R964GNP!X25-/ -M.38V,!,`6C) -M`#!H;W?X``+U``"6!0,L``(J`2%/;JH`'"P#`0/9`@)P`$!L=V%Y1@$`W0'R -M`65D(&%U=&]M871I8V%L;'E'`+!))W9E(&%T=&5M<,0#X'1O(&UI;FEM:7IE -M('-T*P"P(&QI;FL@<&]L;'6X`>$N("!)9B!Y;W4@9&]N)^P!`+8`\0)I8VET -M;'D@:6YV;VME(&$@<.L`('5L-P2@96%T=7)E("AS=2\!&7,<`A!AZ0`'+0`' -M[P4`@`$"F0%P*2P@:70@=W``X"!G970@<'5L;&5D(&ENI`0W($EN;@`W+"!I -MG@`!40$#FP`B96[)`0`(&5N -M=FER;V[7`C%S('=N`@&@`A!MV`$36QE(&%P<')O -MR`,`R0@"^@#@=&\@:&%V92!M=6QT:7`E``-3!`(!!`"Y"%4@;W!E;IX`4"`@ -M8G-D(P2!F)M96UO?<"!8P``0`"\05R;W9I9&4@96%S -M>2UT;RUU08A;W7W!%%F:7)S=)("`*8!(&$@0P41;SD+`/8` -M%BYT``/9`P*G`0":"0*<`0&%``:X`0!V``##``"\`Q)EDP`"3P<@;'GI``#, -M``"C`0:`!3%W86Z(`!!T-@0%10$`8``!^@D`C@7,N"E)%041-1;L&!^@&X2!B=6YD;&4N"@I1=65S^@*@/R`@27-S=65S/U(` -MURH@:'1T<#HO+W=W=RX@!S!O3``!(`1!HN`*#9F]R(&]N9V]8!Q@@9`!P -M9&5V96QO<#P%<2P@:6YC;'6]!4!D;V-U%``!K`@!-PP`<0``.@`A;FM=`0!= -M``9S`%`@;6%I;`<"0FQI%EB!$!G&%)`$!S.B!3,@-4`0-)`#!C;VY#`O`".B`@5F%R:6]UP``7P%V875T:&]RT/ -M4'1O<"UL#`0#Q0P`,`0&";8"(FENU@0`=`P`ZP40<],-\`4@*B!. -M15=3("T@:&EG:&QI9VATP`"-E)ZT` -M`V2XS]!0`!`,!-@`2(FL#!:L``20`%"(+"UD@8VQA!0&`$@!V`T5R;6%T:0\$8P(%E@$` -ML```"@)!+C4L("$3``D``&\`7G1A`=2!T:&4*)V-O -M;F9I9W5R92<@`""(&EN'!L86EN -M@`/`#;&EB -M2!A2XS30`"=`%U -M(G-T2!C;&%S1`"6:6YT97)N86QSG0!@2!E2QN``5H`W!U=&]M871I_P(0>68!,&5C=)D#$635``,<`E!O;&QO=Y,!$&8L -M`!!S4`51*B!'3E5U`0(U`B8@*+D!`!H`06QO;F=5`F)N86UE`*%35E(T($%30TE) -M=`(!%``"4P`/,@`%84)I;F%R>2X`H"`H8FEG+65N9&GS!(-R(&QI='1L91$` -M`OH`\0))4T\Y-C8P($-$+5)/32!I;;<"@"AW:71H(&]P^@7`86P@4F]C:W)I -M9&=E10!B2F]L:65T*0$![P$"20`T6DE05@,$0`"0=6YC;VUP[`@0]`5HW+5II<"8`V$UI8W)O`,(KP)@:&%N9&QENP(0>;<#`+8$!K@",&)E9DH# -M<&5V86QU873*`@`@``.9`P+/`A!U]@40;W$"`+8"`D,"`0H`$2"#`:)24$T@ -M=W)A<'!E3@)%9WII<#X!,6EO;A@!76)Z:7`R%@`$?`%-+TQ:5QT`HFQZ;6$L -M(&QZ:7`3`R]X>B,``!DT%``)"`&58V%N(&-R96%TSP`!=00/!@$"`J\!`[\# -M`KP"#Q\#&#`B&-E<$`%`+D%!&D"L"!T:&%T(')E<75IE@4G87C*`B`@*'T'`30$`(0! -M`S,$`/0#<2P@971C*2YO`0#Z`P"I`@8B!`$7``+:``^6`P4!R`-A(FYE=V,B -MFP,!,P`G?P(-F5A;;4% -M`A$+@"X@(%1H97)E+``C;F_B!P""`@/?"`"3!/("(&EN+7!L86-E(&UO9&EF -M:6.M"/,";W(@U`P#P!`![``.?`0![``&'"0&C``)*#`,*`P`X"`"R``$>`P"F -M!`(,`B$@8C<)<7)E861A8FP`!@","@$,``$L"P($`0!H``([`$)E86-H/0$A -M=F5S`Q-Y0P!0:6YD97"J`"5N="(!`!@)4&%R=&EC0@4D;VZ!`02N`$17:6MI -M4@PP:6YGR0`P:&]WFPP"I@<'E@H"*@$A3VX_"`#W#`)X!@$""B-N9/@``8@) -M8V%L=V%YD`!RT`!"T'`,T`%&_Y"'`I -M+"!I="!W<`!Q(&=E="!P=9P-(&ENI`0W($EN;@`W+"!IG@`(FP`B96[)`02UV```S#`#W"!%IAP8`A`!P96YV:7)O;M<",7,@=Y`#`:`"$&W8 -M`1-R6@,%,`(`6P`"?P`1>7L#$7`U`-%A=&5V97(@8FQO8VMS\```[@@``S0*%82!S;V-K970^`TEW:7-HN@0!)@\#60\`4X.475S92`B(0$`6@@@+")0"+$L(&-A<&%B:6QI=/8"!`,! -M!?$``O,/`;<$"/8%`9P"`,D*`2L`,VEN("#U%F:7)S=)("`*8!$6%P$A%O61$`]@`6+G0``]D# -M`J60!`,P``*,!!H`% -M,7=A;G\%$G0=#P$V`@%;`P$:!!!TC@0#`',*T2!S87ES+@I2 -M14%$3442!@9)$>$@8G5N9&QE+@H*475E<_H"H#\@($ESF-% -M#A)B!P`2>`<``$D!`)()`"<`02H@97@;$T!S.B!3,@-4P``7P%Q875T:&]R<\`% -M`1\&`?("`,$3$B[M#U!T;W`M;`P$`\4,`#`'`4$`!.$7!K8""',5`.L%`>X/ -M\`4@*B!.15=3("T@:&EG:&QI9VAT<]P`,')E8]D4`C$%`Z`"DD-/4%E)3D<@ -M+0P%`$(4`,H'(F1OGP``AP4`S@"T*B!)3E-404Q,("V2&`&/!`$-``#Y%@"_ -M``(I``-`!1(M1!D`E0`"&``%=QDE("T,``)$``*W&54L('-E96<``"@%`JT7 -M`F,(@2H@0TUA:V5,U`0Q='ATB``A<'5G$#`@(F,T!A0BO!DY;V]L30`"5@$& -M-0$`E```L`H!C@$/;0$!`*(&#V0:________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M__________________________________]G4'1O(&%L45J)ART1``#P(&QO -M=R!I;F1I=FED=6%L(&5N=')I97,*("`@=&\@8F4@2!D871A('-O=7)C93H@(%EO=2!C86X@8W)E871E/0"B82!B;&]C -M:R!O9BL`\05I;B!M96UO6]U('=A;H@`$G1=`!(O/0`#'P$`,P!09&ES:RQ. -M`/`07,N"E)%041-15``1"!L:6)M`=%B=6YD;&4N"@I1 -M=65SK@"@/R`@27-S=65S/U(`UBH@:'1T<#HO+W=W=RXX`$`N;W)GDP``2`$Q -M:&]MIP"`(&]N9V]I;F8$(&YDT`(Q9G5L+P(&10!1+VUI;FF%`1%AXP%186-T('-@ -M`+`@9&5M;VYS=')A=+\`!,GK0`#)`0`DP``3@#U`2YA -M;2P@86-L;V-A;"YM-"SA`$!E+F%C_P```@`0+:("`)\`!*@`#*($LBP@;VYL -M>2!N965D?``Q;6%I]@$C97*N`05P`"1I;F0`@2YH+FEN"@DM]`=2;&%T97-G -M`!%B-`(!9@$39;4`8`H*1W5I9/,`*"!$5`8$T@$"=0`!MP%P!1%E^P,`\@"`;6%T -M``&I`5"`"X!!,B?P(R+F@BJ0`R:&4*7PP0(+`)`'4! -M`!0`!.D&`W((`G\"-&UO@,QBH@4U92 -M-"!!4T-)210``E,`#S(`!6%":6YAB,``!DT%``)"`$```H"G!`%.@$`=00/!@$"`J\!`[\#`KP"#Q\# -M&#`B?P(-F5A;;4%`A$+<"X@(%1H -M97(T$2`@;M82,7)E8S`1`]\(`),$02!I;BT"#X(@;6]D:69I8^4,\@%O`3AN -M97>U`P#P!`#]`@.?`0![``&'"0&C``)*#`!-$2)I7-S -M""IE9(H(`D<`L$DG=F4@871T96UPC```%1`0.;`")E;LD!!RT``'P`"W$`*&1E -M$0`#Q@(1+.4)`H```(T.`)8!`!8!`$``,&%G8?,/`5\*D6-O7L#$7`U`&)A=&5V97)X%Q%S\```[@2X'$'1[%R%I;5<#<6]R(&UM87`I -M`0!>$P'Y%@*Y%P"V`A!GPA<0:2(3`2(`!4H``.,3(6-EA0`A3VZ0`QMEPP`" -MY`(R<')O.@$!A0$`FA<1+408DF5D(&]U='!U=.\"`&`$\0-O8FIE8W0MFEP,A8` -M!"8`32],6E<=`+%L>FUA+"!L>FEP+!0!*7AZ(P#!"DYO=&5S(&%B;W5TE`!R -M;&EB=$`\"YT96-T=7)E.@H*("H@5&AI0`&EP#@:7,@9&5S:6=N960@=&]>`61E>'1E;F1>`3AN97?@``#S`#(* -M("#.`!!V<@$`]`$22!R97%U:7)E;65N=+(`,G1H80D!`BL` -M("!BCP&0(')E861A8FQEH@!!=W)I=`P`$&$,`0($`0!H``([`$5E86-H;P!3 -M96YT'!L86EN:6YGR0`P:&]W^``"]0`'+``"*@$A3VZJ`!PL`P$`48!`-T!\@%E9"!A=71O;6%T:6-A;&QY1P"P22=V92!A='1E -M;7#7`>!T;R!M:6YI;6EZ92!S="L`L"!L:6YK('!O;&QUN`'A+B`@268@>6]U -M(&1O;B?L`0"V`/$":6-I=&QY(&EN=F]K92!A('#K`(!U;&%R(&9E85D"0"`H -MD`!RT`!P8#`(`!`ID!<"DL(&ET('=P`/``(&=E="!P=6QL -M960@:6XN/@`G26YN`#``%1`0.;`")E;LD!!RT``#X`"W$`*&1E$0`# -MQ@(1+/```H``(FYEC@(`%@$`0`!B86=A:6YS1P*@8V]R7L#$7`U`-%A=&5V97(@8FQO8VMS\``0:%<%(6ETH0!!66]U -M717`F$@82!T:6U7 -M`W%O`+$@(&)S9'1A3X`!8P``0`"\05R;W9I9&4@96%S>2UT;RUUX`0!V``##``"\`Q)EDP`"3P0"0 -M:7,@97-P96-I;@0!T`$"J@$`.@CS`SH@(G!A>"!I;G1E7!1`GH@1`9W)A;18"`<` -M`$D!`)()`"<`4"H@97AA20!`8$(&YDT`(Q9G5L+P(&10`0+T,*`84!$6&>"E%A8W0@=&%R+C54`0CQ!`4^$A%S8P0Q<&]PY0\#G`$$ -M>P`(2PE`:&%R9!8,`3`&!%L!`4<``(X!86UO9&5R;H\``.@!`+P'<"!V87)I -M86Y("0":!3!M86[X"T%P86=E.```,0XD``'?`5=H+`#L'`2,)"=H1`,$",&5C=)D#$61A#0,<`@2# -M%"`@9@82`;<&`D$5!JH+)B`H!`L`6Q4@;&\O`#!I;&6M"R)S+!````4+$R`1 -M``!C`%)S<&%R`*%35E(T($%30TE)=`(!%``/,@`+$$)M$1%Y+@"Q("AB:6%Q8/"Q<`T$UI8W)OQ=4`)H`-6QZ-*@!`.47"0@! -M```*`IP0!4L!`'4$#P8!`@*#`0._`P*\`@\?`Q@P(G)EH`T`$!81(D<#`D\` -MPBP@=VAI8V@@=VEL;.L8`'`(`!D$`U\!0',@97@M%``"`@"Y!02)$0(+%P-: -M%P%1``7I$C!S("A3"@$T!`"$`0,S!`#T`V`L(&5T8RGO"P+Z`P"I`@!M``*- -M``&;`0+:``_(`PIA(FYE=V,BFP,!,P`G2*5Z4]A61$``/,U('5T:6QI='D@8VQA`'!L:6)R87)Y3`#08W!I;RXU+"!M=')E90D``&\`5'1AP#S"2P@:6YC;'5D:6YG(&AA``"/`/0:("=D;V,G(&1I2!I;@IA(&YU;6)E6]U(#\!8"X*"D-UFEP,A8`!'P!32],6E<=`*)L>FUA+"!L -M>FEP$P,O>'HC```9-!0`"0@!E6-A;B!C,H"4B`H9F]R-`0`A`$# -M,P0`]`-Q+"!E=&,I+F\!`/H#`*D"!B($`1<``MH`#Y8#!0'(`V$B;F5W8R*; -M`P$S`"=S:+```1(`#T8#8P0%!`);`0&)``]9`P`*%@,S5VAE`P(`V`(#U`(2 -M<^8%87)E'!L86EN:6YGR0`P:&]W^``"I@<`K0$# -M+``"*@$A3VX4"1PL`P$#^``!B`E086QW87E&`0#=`2IE9(H(`D<`L$DG=F4@ -M871T96UPC`?@=&\@;6EN:6UI>F4@D`!RT`!"T'`,\*%&_Y"'`I+"!I="!W<`""(&=E="!P=6S["@"D -M!#<@26YN`#``B;`")E;LD!!RT``'P`"W$`*&1E$0`#Q@(1+/```H`` -M(FYEC@(`%@$`0`!B86=A:6YS1P*18V]R0`P&@`A!MV`$38!(71O(@`%H0!A="!O;F-EA0`A3VZ0`QMEPP`"Y`(R<')O -M.@$!A0%18W1L>2W,``"."5)U='!U=.\"`&`$\0-O8FIE8W0M60!`,P``*,!!H`%,7=A;G\%$G0=#P$V`@%; -M`P!C#``S`$%D:7-K+`,`L1`0#B)A;N@"`*4' -M`!$#`EH'$"QC`$!D97-PH@``;`0!Y`,`7,N"E)%041-11(&!DD1 -MX2!B=6YD;&4N"@I1=65S^@*@/R`@27-S=65S/U(`UBH@:'1T<#HO+W=W=RXX -M`$`N;W)GDP``2`$0:+@"$&:Q#S-N9V]8!Q<@3`>`(&1E=F5L;W`\!0@9$02Z -M$0&L"`$W#`!Q```Z`"%N:UT!`%T`!G,`4"!M86EL!P(P;&ESOQ`!G0`05)D! -M`.41`.%E8$(&YDT`(Q9G5L+P(&10`0+T,*`84!$6&>"C1A8W1[$W!D96UO -M;G-T.14@;F<^``"`!094`@-)`#!C;VY#`F$Z("!687+N$V!I=&5M$0(8`&!C;VYF:6>R%A4M#``"1`"UM`Q$SM@L`$!20(&]V97)V:65W\P(` -MJP`%P`L`<04P=VAOD0(4*J0*A5]R96%D+C,L$``!^`@-$0!17V1I:L`D'-A;64@9G5N8S`<``$D!0'-U8V@G`%`J(&5X84D`U',Z(%-O;64@6]U(&UA>2!F:6YDT`(Q9G5L+P(&10!1+VUI;FF%`1%A -MXP%186-T('-@`*$@9&5M;VYS=')AP0$`#@,G;V9>`0-)`#!C;VY#`O`".B`@ -M5F%R:6]UP``=`+Q`F%U=&AO@`K1#3U!9 -M24Y'("T@=U$!8F-A;B!D;Y\`,W1H:2D`\@))3E-404Q,("T@:6YS=&%L;'4` -M``T`(7)U*@(#*0"!4D5!1$U%("T\``&5``*3`+!C;VYF:6=UM``,D!`"3``!.`/4!+F%M+"!A8VQO8V%L+FTT -M+.$`0&4N86/_```"`!(M5``D=&^H``RB!+(L(&]N;'D@;F5E9'P`,6UA:?8! -M(V5R7`$%<``D:6YD`/(#+F@N:6X*"2T@=&5M<&QA=&5S9P`18C0"`68!$V6U -M`&`*"D=U:63S`%`@1&]C=9D%`H$!`,4!,F%L;'4``;\%1FYA;'.=`#!S('-4!6%I;G-I9V@1!@B9!Q$G9P($-P`2(&\``$`"`*$% -M,&]P92L%,&]N+J@`!GL!$BV"!%-S+C4@9%8"`J\``!D#`/(`@&UA=',@=&%R+C54`0CQ!$%A8F]U -M4P4@P`3+/('`(H!@6AA``%4!%"`"X!!,BO0(R+F@B -MJ0"`:&4*2R"```[!P$C"4!A=71ODP8`_P(0><$",&5C=)D#$60Y"0,<`@5X -M"1!F+``!MP91*B!'3E5U`0(U`B(@**L)`+D!`!H`06QO;F=0!F)N86UE`@@;W#+`\!A;"!2;V-KFEP/@$Q:6]N&`%=8GII<#(6``1\`4TO3%I7'0"B;'IM82P@;'IIL``7\*`\X1 -M("`HTA`E(&'["@"A`2`@8>D``2<0`BT`",T`%&_Y"'`I+"!I="!W<`!!(&=E -M=!D3`5T*`*0$-R!);FX`-RP@:9X``5$!`YL`(F5NR0$'+0``?``+<0`H9&41 -M``/&`A$L\``"@```C0X`E@$`%@$`0``P86=A+@X!\0F18V]RP,B:67-#P&<$P/G"B!D=1D-`)\#$'.%`2-O9H@!`(X2$"UV```S -M#`#W"!%IM`\`A`!R96YV:7)O;@\+$7>0`P&@`A!MV`$3<3`<0-0&)A -M8VL>!#%F2W,`))E9"!O=71P=73O`@!@!/$#;V)J96-T+7-T -M>6QE(&%P<')OR`,`^10"^@#0=&\@:&%V92!M=6QT:<,3!*D``@$$`+D(52!O -M<&5NG@`3(!40`&H0``H!`#T%@VX@:71S(")`/``2(KT$$7,P#@)C!098`&!I -M='-E;&93`5!R96%D+^8`8'1E;B!U@``S0*% -M82!S;V-K970^`TEW:7-HN@0!)@\#60\`3``!(`1!HN`(`5P!#;VYG;U@'%R!, -M!R`@9%@6(&]P/`4(&1$$NA$!K`@!-PP`<0``.@`@;FLT`0'!``9S`$$@;6%I -MVQ(`^QD"H`,!_1D/9!K_________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_________________________UI0("!4:&44.]4X*A$``$%R92!A!`#W*G1I -M8VQE2W,`))E9"!O=71P=70&`>!4:&4@ -M;V)J96-T+7-T>1`"4'!P3 -M``!(`1!HN`*#9F]R(&]N9V]8!Q@@9`!P9&5V96QO<#P%<2P@:6YC;'6]!4!D -M;V-U%``087<`$"Q8!P!Q```Z`"%N:UT!`%T`!G,`4"!M86EL!P)";&ES=*`# -M,"H@5)D!`>H&0&%N(&FW`!`L(00!_``!#P"A('1R86-K97(@8&%) -M`$!S.B!3,@-40&";8"(FENU@0`<0L`ZP4$O0+P`DY%5U,@+2!H -M:6=H;&EG:'1S7`8P'2(`")P=;H+(")C-`81(B0#`!(+*6]L30`"5@$& -MZP,`E``!%@D`C@$/;0$!`&8(('5SW0H`V@$T90HGL``C92>M``-G`0"3``!. -M`/``+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C_P```@`0+:("`)\`!*@``&H+ -M"*($82P@;VYL>=<+`GP`,6UA:?8!(V5RK@$%<``D:6YD`($N:"YI;@H)+?0' -M4FQA=&5S9P`18C0"`W(!`K4`8`H*1W5I9/,`*"!$5`8$T@$"=0`!MP%PP`(2PE`:&%R9!8,`3`&!%L!`4<``(X!86UO9&5R;H\``.@!`+P'<"!V87)I -M86Y("0":!3!M86[X"T%P86=E.```L!`D``$=`U=H+`#L'`2,)"=H1`,$",&5C=)D#$62V#P,<`@5X -M"1!F!A(!MP91*B!'3E5U`0(U`B8@*`0+`!H`(VQOO`4`K0LB+``-J`0`9`[$J(%!/4TE8('5S=+`1!!``#XH,`P%\``(Q`+!O8W1E="UO -M\!`DD`-%I)4'4$!$`` -M('5N,0L`[!,`UA!@"T4``("`+D%!(D1`FL4`$,.`-,3`%$``;$6`0`&@`0I:7-N%")B98@%`$`$`5X!.&YE=[4#`/`$`/T" -M`Y\!`'L``8<)`2L5`DH,`PH#`#@(`&\0%'3N$@(,`B$@8C<)`(P*`8\8`[@4 -M`0P`$&$,`0+4$`!H``([`!%EG!8`/0$A=F5S`Q-Y0P!0:6YD97"J`"5N="(! -M`$0-#V0:____________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________]C4&%N9"!RUWE3_3`1``#P)F5A9',@=&AE(&9O;&QO=VEN -M9R!F;VUA=',Z"B`@*B!'3E4@=&%R(&9O'1E;F1E9&0`!#-!0TPS`&%/;&0@5C2!O9K@"X&)E9F]R -M92!E=F%L=6%TI`(`V`(#+P("SP)@=75E;F-O<0(`M@("0P(!"@`1((,!HE)0 -M32!WFEP/@$Q:6]N!0%=8GII<#(6``1D`4TO3%I7'0"B;'IM -M82P@;'II0`&EP"0:7,@9&5S:6=NH@9";R!B98@%`$`$`3`$.&YE=[4#`*,$`'L` -M`4,`4&EN -M9&5PJ@`B;G1_`!!R.P0`!``P=&EC0@4D;VZ!`02N`/``5VEK:2!E>'!L86EN -M:6YGB0`P:&]W^``!LP,09)8%`RP``BH!(4]NJ@`<+`,!``0$,FUA='``0&QW -M87E&`0#=`6!E9"!A=71>"&)I8V%L;'E'`+!))W9E(&%T=&5M<(P'X'1O(&UI -M;FEM:7IE('-T*P`"4@A0<&]L;'6X`>$N("!)9B!Y;W4@9&]N)^P!`+8`\0)I -M8VET;'D@:6YV;VME(&$@<.L`('5LO0B@96%T=7)E("AS=2\!&7,<`A!AZ0`' -M+0`$10<#(@("F0%P*2P@:70@=W``X"!G970@<'5L;&5D(&ENI`0W($EN;@`W -M+"!IG@`!40$#FP`B96[)`07L#$7`U`-%A -M=&5V97(@8FQO8VMS\```[@2X'<70@82!T:6U7`W%O8!(71O(@`%H0!A="!O;F-EA0`A3VZ0`QMEPP`"Y`(R<')O -M.@$!A0%18W1L>2W,``"."5)U='!U=.\"`&`$\0-O8FIE8W0M2!B=69F97(@)`@`90`$<@&%82!S -M;V-K970^`TEW:7-HN@3`P"`,D*`2L`,VEN(">D``,P` -M`*,!!H`%,7=A;H@`$'0V!`5%`0!@```:!!!TC@7,N"E)%041-1;L&!^@&X2!B=6YD;&4N"@I1=65S^@*@/R`@27-S=65S/U(` -MURH@:'1T<#HO+W=W=RX@!S!O3``!(`1!HN`*#9F]R(&]N9V]8!Q@@9`!P -M9&5V96QO<#P%)BP@8`]`9&]C=10``:P(`3<,`'$``#H`(6YK70$`70`&8N9V]O9VQE+F-O;2]P+VH`$2\Z`"!S+VD``),` -M`6<`47-U8FUI9P!P96YH86YC9;L``#8"!C@`@RP@<&QE87-E+```.P``!`,` -M2PB!$!G0&";8"(FENU@0`I`H`ZP4![@_P!2`J($Y%5U,@ -M+2!H:6=H;&EG:'1S7`8PM```Z#S`@ -M*B"3``!.`/``+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C_P```@`0+:("`)\` -M!*@``-D."*($$BP:#@#7"P!9"Q!YR@4!]@$C97*N`05P`"1I;F0`@2YH+FEN -M"@DM]`<`YA,22XS]!0P86EL[P0R92`B:P,%JP`!)``4(@L+62!C;&%S -M1``!'PE&;F%L``'?`56]U(&UA>2!F:6YD -M('5S969U;"Y%`/$&+VUI;FET87(Z(&$@8V]M<&%C="!S8`#@(&1E;6]NP#R*71H92!A=71H;W)S('=I=&@@86YY('%U97-T:6]N7-T96TZ"B`J(&)S9'1A2!A``"/`&<@)V1O8R>]!;!I;@IA -M(&YU;6)E2QN``5H`S!U=&^3!@#_ -M`A!YP0(P96-TF0,19-4``QP"!<(&$&8L``&W!E$J($=.574!`KH!)B`HN0$` -M&@!!;&]N9U4"8FYA;65S+!``4VQI;FL@$0``8P!A`@@;W#+`\!A;"!2;V-KB,``!DT%``)"`$```I58W)E873/``%U -M!`\&`0("J@,#OP,"O`(/'P,8,")R9?X(46-T960B1P,"3P#$+"!W:&EC:"!W -M:6QLB@`!5@`%R@%A(&5X8V5P0`4`N04$:0("%0QQU`P#P!`![``.?`0![``&'"0&C``)*#`,*`P`X -M"`"R`#%T:&$O"0,K`"$@8C<)`&H(,6%B;``&`(P*`0P``2P+`@0!`&@``CL` -M0F5A8V@]`2%V97,#$WE#`%!I;F1E<*H`)6YT(@$`&`D`#P\08T(%$F]L#08U -M"E0@5VEK:5(,,&EN9\D`,&AO=U$/`;,#%V26"@(J`2%/;C\(`/<,`F`&`P,! -M!,T``7``0&QW87E&`0#=`2IE9(H(`D<`<$DG=F4@870M#0",!P#!#Y!I;FEM -M:7IE(',.#1)C4@A!<&]L;)0-42X@($EF]0A09&]N)W2H`)!E>'!L:6-I=&S9 -M"6)V;VME(&'Z#Q%C?PHQ9F5A-`L0*-(0`'4,"!P"$&%!``$G$`(M``C-`!1O -M^0AP*2P@:70@=W``<2!G970@<'6<#1!I>@M'("!);FX`-RP@:9X``5$!`YL` -M(F5NR0$'+0``/@`+<0`H9&41``.J`!$L\``"@```C0X`E@$`%@$`0``@86<# -M#@)0`Y%C;W)R97-P;VY<"PA)``&]#P@1``)D!R)I92UV```S#`#W"!%IM`\`A`!P96YV:7)O;M<",7,@ -M=Y`#`:`"$&W8`1-R6@,%,`(`6P`"?P`1>7L#$7`U`-%A=&5V97(@8FQO8VMS -M\```[@2W,`))E -M9"!O=71P=73O`@!@!/$#;V)J96-T+7-T>6QE(&%P<')OR`,`0Q("^@#@=&\@ -M:&%V92!M=6QT:7`E```A!1!V$@-``!,@%1``:A``"@$` -M/06#;B!I=',@(D#E`!(BO0012!F4X.``P1$2(A`0!:""`L(E`(H"P@ -M8V%P86)I;&D2%`8#`0"_``'Q``+S#P$_#@CV!0&7`8`@:6YD:79I9&P.`]L( -M`(4``#H2`D(``*P+`-$``#8!(71OK`TP9&%TUP``!0X1.L$"`2X!`L@)`#T` -M$F'L`@#)"@$K`#-I;B`G`0"/`C-A9&2.`AAA]PP!UP<#'@]19FERA$)P`$`B0``,!0"@1-@97-P96-I;@0!T`$"J@$` -M.@@P.B`BDPH!#A$)V@T3(KD"`-X.(F%NZ`(`I0<&-`H0+&,`0&1EA<"+```.P``!`,`2P+%1`G-Q,`)AD`%@)S -M82!F=6QL+98(6]U(&AA;F0@:70N"B`@(%EO=7(@71E(&%T(&$@=&EM90H@("!O6QE(&%P<')O86-H(&%L;&]W -M^@#@=&\@:&%V92!M=6QT:7`E``.I`'!S=')E86US$@%%;W!E;IX`P"`@8G-D -M=&%R('5S90H!PVES(&EN(&ET2!B=69F97(@;W+!``!E -M``1R`3!A(',K`5%T+"!I9OP!8'=I2UT;RUU`@#1```V`:!T;R!A;GD@9&%T -MUP!6=7)C93HN`5%CX`0!V``##`!%EW@(!O@`%RP$`TP`#HP%#+B`@ -M2:0!(6%NB``2=%T``38"`5L#`!\!`+H`061I"!I -M;G1E`<``$D!0'-U -M8V@G`%`J(&5X84D`0',Z(%,R`U1S;6%L;!4`!#X!`%(#(6%T(`8@;6'F!"!N -M9-`",69U;"\"!D4`42]M:6YIA0$18>,!46%C="!S8`"P(&1E;6]N0&";8"(FEN^`0B:6_A -M!@2]`O`"3D574R`M(&AI9VAL:6=H='-M``,D!`"3``!.`/4!+F%M+"!A8VQO8V%L+FTT+.$`0&4N86/_ -M```"`!`MH@(`GP`$J``,H@2R+"!O;FQY(&YE961\`#%M86GV`2-E'!L@P(#+P,`0@$"(0`$ -MF@,#,P``B`0/-``+`"(`##4`+V%T-``,*&%T,P`&`08A+C.V"Q!SWP:`;W9E -M"P!Q!3!W:&^1`A0JI`J%7W)E860N,RP0``'X"`T1`%%? -M9&ES:Q8``GX'`X(%`3X``QP``)D``7L*`K<"$F6@#`!;!!!SU`80;A$,`-8" -M`),``'4``!<"`/D$`7$``7$*")<``9P)(RXS30``[P0R92`B:P,%JP`!)``4 -M(@L+62!C;&%S1``!'PE&;F%L=H+`#L' -M`2,)@&%U=&]M871IGP\0><$",&5C=)D#$61Y#`,<`@5X"1!F+``!MP91*B!' -M3E5U`0(U`B8@*`0+`!H`06QO;F=0!@"M"R)S+!````4+$R`1``!C`%)S<&%R -M`@@;W#+`\!A -M;"!2;V-K[`@0]`5HW+5II<"8`V$UI8W)OFEP,A8`!'P!32],6E<=`*)L>FUA -M+"!L>FEP$P,O>'HC```9-!0`"0@!```*`IP0!3H!`'4$#P8!`@*O`0._`P*\ -M`@\?`Q@P(G)EH`U18W1E9")'`P)/`,0L('=H:6-H('=I;&R*``%6``:0`%%E -M>&-E<$`%`+D%!(D142!T:&%T0PX`TQ,`40`%Z1(P?P(-F5A;;4%`A$+!8@40&ES -M(&[6$C%R96,P$0/?"`"3!`#E%`&W#X(@;6]D:69I8^4,]P!O'!L -M:6-I=&S9"6)V;VME(&'Z#Q%C?PH#SA$@("C2$`!U#`@<`A!AL@$!)Q`"+0`( -MS0`4;W,$<"DL(&ET('=P`%`@9V5T(-(2`5T*`*0$-R!);FX`!287`9X``5$! -M`YL`(F5NR0$'+0``?``+<0`H9&41``.J`!$L6!$"@```C0X`E@$`%@$`0``P -M86=A\P\!7PJ18V]R7L#$7`U`&)A=&5V97)X%Q%S\``` -M[@9"!H86YD;&5S(&%N>2!O9B!T -M:&4@9F]L;&]W:6YG(&)E9F]R92!E=F%L=6%T$@``(`#Q#6%R8VAI=F4Z"B`@ -M*B!U=65N8V]D960@9FEL97,4``$*`/$"('=I=&@@4E!-('=R87!P97(;`/$! -M9WII<"!C;VUPFUA+"!L -M>FEP+"!A;F0@>'HC```9-!0`]0<*5&AE(&QI8G)A"!I;G1E&-E<'0@9F]J`/$'("!E;G1R:65S('1H870@.`?$#;F%M97,L($%#3',L(&5T8RDND@"P -M3VQD($=.52!T87)=``2I``+*`/$$;V-T970M;W)I96YT960@8W!I;S4`ME-6 -M4C0@(FYE=V,B%0`G`'@G;71R964G -MNP!X25-/.38V,!,`6CT!X'-Y0`&EP#R`FES(&1EP`!S@`4=E@#$G.C`%0@;VYL>0H#0&UE;G2R``$>`P"F!`)G`S`@8F5``(!R -M96%D86)L9:(`07=R:70,`!!A#`$"!`$!1`0!.P!$96%C:"8"`98"$WE#`%!I -M;F1E<*H`(FYT?P`04<`L$DG=F4@871T96UPQ`/@=&\@;6EN -M:6UI>F4@2!I;G9O:V4@82!PZP`@=6PW!"!E85D"0"`HD` -M!RT`!^\%`(`!`ID!<"DL(&ET('=P`.`@9V5T('!U;&QE9"!I;J0$-R!);FX` -M-RP@:9X``5$!`YL`(F5NR0$'+0``?``+<0`H9&41``/&`A$L\``"@``B;F6. -M`@`6`0!``&)A9V%I;G-'`J!C;W)R97-P;VYD)P0(20`-6@`">P,Q:65SPP`! -M;P.A86QS;R!R961U8[D%,&4@`(&5N=FER;V[7`C%S('=N`@&@`A!MV`$36QE -M(&%P<')OR`,`R0@"^@#@=&\@:&%V92!M=6QT:7`E```A!1!V$@,`!04`N0A5 -M(&]P96Z>`%`@(&)S9",'(75SO`$`/06#;B!I=',@(D#E`!(BO01&"2`L(E`(<"P@8V%P86)!``'V`@)F -M!A%E50(!\0!A92!!4$ESMP0(]@4!EP&Q(&EN9&EV:61U86QH!1%IWP<`>P`2 -M8D(``"P$`-$``#8!(71OFPDP9&%TUP!6=7)C93HN`0+("0#"`!)A[`(`R0H! -M*P`S:6X@)P$`3P@S861DC@(18?P(!*H!`'D&(6]U]P119FER0#`',*T"!S87ES+@I214%$346[!@?H!N$@8G5N9&QE+@H*475E<_H"H#\@ -M($ES8N9V]O9VQE+F-O;2]P -M+VH`$2\Z`"!S+VD``),``6<`47-U8FUI9P!P96YH86YC9;L``*8`!C@`@RP@ -M<&QE87-E+```.P``!`,`2P7!1`GH@1`9W)A;18"F-%#A)B!P`2 -M>`<``$D!`)()`"<`4"H@97AA20!`8$(&YDT`(Q9G5L+P(&10`0+T,*`84!$6&>"E%A8W0@H($',+!0$^ -M`0!U```7`@#Y!`%Q``%Q"@B7```\"3-Y+C--``#O!#)E(")K`P6K``$D`!0B -M"PM9(&-L87-$``$?"49N86QSG0`2!Q(M@@0U"`"X!!,B!0XR+F@BJ0`R:&4*7PP0(+`)`/H``!0`!.D& -M`W((`G\"$&T:%P/[`$(N("!0B@FS;&5T('5S"FMN;W>5$P`P%&!E\6`2T5`A``#XH,`P,!Y1$0``\")C2!N965D960@8GD@;6%I;G1A:6YE84`(2!SM0!P"@I'=6ED98(` -MD$1O8W5M96YT87@`@B!I;G-T86QL=0`!EP#P$7-Y-50!(FEN;P"0 -M:6]N(&%B;W5T4`$@P"`+"!I;F-L=62*`<5H87)D -M+71O+69I;F1;`0%'``!!`&%M;V1E``"/`/`-("=D;V,G(&1I2!I;@IA(&YU;6)E6]U(#\! -M8"X*"D-U+``-J`0`9`]$J(%!/4TE8('5S -M=&%R6P`"$``P<&%X20-Q97)C:&%N9WX!-VUA="$`L&]C=&5T+6]R:65N`0,` -M8`(!'@"A4U92-"!!4T-)270"`10``E,`#S(`!6%":6YAFEP,A8` -M!'P!32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9-!0`"0@!E6-A;B!C0`&@`0` -M#@Q397-I9VXE#!)EO@(`0`0!,`0X;F5WM0,`\`0`>P`#GP$`>P`!APD!HP`" -M2@P#"@,`.`@`L@`!'@,`I@0"#`(A(&(W"7%R96%D86)L``8`C`H!#``!+`L" -M!`$`:``".P!"96%C:#T!(79E4,`4&EN9&5PJ@`E;G0B`0`8"5!A`8!`@HC;F3X``&("6-A;'=A>7-S""IE9(H(`D<`<$DG=F4@870M#0", -M!]!T;R!M:6YI;6EZ92!S#@T28U((07!O;&R4#5$N("!)9O4(0&1O;B?6!P&V -M`%!I8VET;-D)@79O:V4@82!PZP`!?PHQ9F5A-`LP*'-U+P$%^PH`J0`@(&'I -M``0`P&@`A!MV`$32X'<70@82!T:6U7`W%O8!(71O(@`%2@!A="!O;F-EA0`B3VX<#@O#``+D`C)P`!,@%1``!A`` -M"@$`/06#;B!I=',@(D`\`!(BO0012!F -M#B)A;N@"`*4'!C0*$"QC`$!D97-PH@`` -M;`0!Y`,`7,N"E)%041-11(&!DD1X2!B=6YD;&4N"@I1=65S^@*@ -M/R`@27-S=65S/U(`UBH@:'1T<#HO+W=W=RXX`$`N;W)GDP``2`$0:+@"$&:Q -M#S-N9V]8!Q<@3`>`(&1E=F5L;W`\!0@9$02Z$0&L"`$W#`!Q```Z`"%N:UT! -M`%T`!G,``)H4`=L2,&QI<[\0`0T5$%29`0#E$0#G`1!IMP`0+"$$`?P``0\` -MD2!T1$@#R$0`6`G-A(&9U;&PME@AR9"`G=&%R)P\!`0(`(7)EK0H!0@$` -MF!8`@08`B@`#8P``*@`"HA,&8P``P1`+9``&TQ(!,`,P9F%C*@<`/0`#`@`` -M*1`B;G1H`P`5`39S86V6`Q!AP!0`+0!7*B!C871I`"MA=&@`(7-ITA((M0!` -M=&]O;#,!`$```P(`('IC10X28@<`$G@'``!)`0"2"0`G`$$J(&5X&Q-`8$(&YDT`(Q9G5L+P(&10`0+T,* -M`84!$6&A"S1A8W1[$W!D96UO;G-T.14@;F<^``"`!094`@-)`#!C;VX%&&$Z -M("!687+N$V!I=&5MP``7P%Q875T:&]R<\`%`1\&`?("`,$3$B[M#U!T;W`M;`P$`\4,`#`' -M`4$`!.$7!K8""',5`.L%`>X/\`4@*B!.15=3("T@:&EG:&QI9VAT<]P`,')E -M8]D4`C$%`Z`"DD-/4%E)3D<@+0P%`$(4`,H'(F1OGP``AP4`S@"T*B!)3E-4 -M04Q,("V2&`&/!`$-``#Y%@"_``(I``-`!1(M1!D`E0`"&``%=QDE("T,``)$ -M``("&54L('-E96<``"@%`JT7`F,(@2H@0TUA:V5,U`0Q='ATB``A<'5G$#`@ -M(F,T!A0BO!DY;V]L30`"5@$&-0$`E```L`H!C@$/;0$!`"`-`1`:`=H!-&4* -M)[``(V4GKQD#)`0`DP``3@`/9!K_________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_________________________________U90("`@=&^SOU&I.Q$``/(V(&)E -M(')E860@;W(@=W)I='1E;B!T;R!A;GD@9&%T82!S;W5R8V4Z("!9;W4@8V%N -M(&-R96%T90H@("!A(&)L;V-K(&]F*P#Q!6EN(&UE;6]R>2!A;F0@861D(&ET -M3`#P!2!T87(@87)C:&EV92!W:71H;W5T00!19FER2!F:6QE+G0`0F%L6]U('=A;H@`$G1= -M`!(O/0``8``P:65S,P!09&ES:RQ.`/`,0#P*FES(&5S<&5C:6%L;'D@96%S>2X*"B`J($YO -M=&4Z(")P87@@:6YT97)C:&%N9V4@9F]R;6%T(B!I<^```#,``.(`<7AT96YD -M960X`0(B`!`L8P!`9&5S<-\`0'=H8726`/`#(&YA;64@F-A="P@8@<`$G@'``!)`4!S=6-H)P!0*B!E>&%) -M`$!S.B!3,@-4`0-) -M`#!C;VY#`O`".B`@5F%R:6]UP``7P%Q875T:&]R<\`%`1\&`?("``$%4"X* -M"E1HG0$P<"UL#`0#=@4`"08!00`0:20%";8"(FENU@0Q:6]NZP4$O0+P`DY% -M5U,@+2!H:6=H;&EG:'1S7`8PM``,D!`"3``!.`/4!+F%M+"!A8VQO8V%L+FTT+.$`0&4N86/_```" -M`!`MH@(`GP`$J``,H@2R+"!O;FQY(&YE961\`#%M86GV`2-E7-T96TZ<`<"N`1U+C$@97AP;(,"`R\#`$(!`B$`!)H# -M`S,``(@$#S0`"P`B``PU`"]A=#0`#"AA=#,`!@$&@"XS(&=I=F5SWP:`;W9E -MP$2+8($-7,N-:H( -M`)X%$67[`P#R`(!M871S('-U<'\(!&,"!98!`$P```H"D"XU+"!M=')E90D` -M`&\`7G1A`D09BP``;<&42H@1TY5=0$"-0(F("@$"P`:`$%L;VYG50(`K0LB+``-J`0`9`]$J(%!/4TE8('5S=&%R6P`"$``/B@P#!R$`P&]C=&5T -M+6]R:65N=!<$,7!I;QX`IE-64C0@05-#24D4``)3``\R``5A0FEN87)Y+@#` -M("AB:6FEP,A8` -M!'P!32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9-!0`"0@!```*`IP0!3H! -M`'4$#P8!`@*O`0._`P*\`@\?`Q@P(G)EH`U18W1E9")'`P)/`,,L('=H:6-H -M('=I;&PF$0)U`P:0`%%E>&-E<$`%`+D%`4,`4&EN9&5PJ@`E;G0B`0!$#0`/#Q!C0@42 -M;VP-!C4*5"!7:6MI4@P##!,P:&]W^``"]0``K0$#V@`"*@$A3VX_"`#W#`)@ -M!@#S#@!0!@/-``%P`%-L=V%Y'!L:6-I#16" -M:6YV;VME(&'Z#Q%C?PH#SA$@("C2$"4@8?L*`*$!("!AL@$!)Q`"+0`(S0`4 -M;W,$<"DL(&ET('=P`%`@9V5T(-(2`5T*`*0$-R!);FX`,BP@:8(5`9X``5$! -M`YL`(F5NR0$'+0``?``+<0`H9&41``/&`A$LY0D"@```C0X`E@$`%@$`0``P -M86=A\P\!7PJ18V]R"(&5N=FER;VX/ -M"Q%WD`,!H`(0;=@!$W):`P4P`@!;``)_`!%Y>P,1<#4`8F%T979E$E33SDV-C`3`+0W+5II -M<"!AFUA+"!L>FEP+"!A;F0@>'HC`,$*3F]T97,@86)O=724`')L:6)R -M87)YT0#P+G1E8W1U2!S=')E86TM -M;W)I96YT960@4,`4&EN9&5PJ@`B;G1_`$%R92!A!`"4=&EC;&5S(&]N@0$#=@+P`2!7:6MI -M(&5X<&QA:6YI;F?)`#!H;W?X``+U``$N("!)9B!Y;W4@9&]N -M)^P!`+8`\0)I8VET;'D@:6YV;VME(&$@<.L`@'5L87(@9F5A60)`("AS=2\! -M&7,<`A!AZ0`'+0`'!@,`@`$"F0%P*2P@:70@=W``\``@9V5T('!U;&QE9"!I -M;BX^`"=);FX`-RP@:9X``5$!`YL`(F5NR0$'+0``/@`+<0`H9&41``/&`A$L -M\``"@``B;F6.`@`6`0!``&)A9V%I;G-'`J!C;W)R97-P;VYD)P0(20`-6@`" -M>P,Q:65SPP`!;P.P86QS;R!R961U8V6;`C!E('.%`2-O9H@!`+,!$"UV`&%E -M9"!B:6X]`"`@:2P$@"!E;G9IP,1<#4`T6%T979E8!(71O(@`%2@!A="!O;F-EA0`A -M3VZ0`QMEPP`"Y`(R<')O.@$!A0%18W1L>2W,`))E9"!O=71P=73O`@!@!/$# -M;V)J96-T+7-T>6QE(&%P<')OR`,`H`4"^@#@=&\@:&%V92!M=6QT:7`E``.E -M`P(!!`!;!E4@;W!E;IX`L2`@8G-D=&%R('5SO`$`/06#;B!I=',@(D#E`!(B -MR`-&P"`*`'`2L`,VEN("8<``J,!!H`%,7=A;H@`$'0V!`5%`0!@ -M`!!IA0(`C@%EB!$!G&%)`$!S.B!3,@-4`0-)`#!C;VY#`O`".B`@5F%R:6]UP``7P%V875T:&]R,&`4D!A69I9W5R92`M#``"1`"U'2(`")P==8-(")C-`81(B0#`#@, -M*6]L30`"5@$&ZP,!*0$`%@D`C@$/;0$!`*(&('5SW0H`V@$T90HGL``C92>M -M``,D!`"3``!.`/``+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C%P$``@`0+:(" -M`)\`!*@``-D."*($$BP:#@#7"P)\`#%M86GV`2-EPH"MP(29:`,`!(&0'-E<77J"!!S"P4!/@$`=0``%P(`^00!<0`! -M<0H(EP``/`DS>2XS30``[P0R92`B:P,%JP`!)``4(@L+62!C;&%S1``!'PE& -M;F%L"`"X -M!!,B!0XR+F@BJ0`R:&4*7PP0(+`)`/H``!0`!.D&`W((`G\"-&UO5$P`P%&!E+``-J`0`9`[$J(%!/4TE8('5S=+`1!!``#XH,`P%\``(Q`%9O8W1E=*\4 -M`&`"`1X`H5-64C0@05-#24ET`@$4``\R``L00FT1$7DN`+$@*&)I9RUE;F1I -M8=018VQI='1L91$``OH`!%\6D4-$+5)/32!I;;<"$"@X#C`@;W#+`\!A;"!2 -M;V-KC2H`0#E%PD(`0``"@*<$`5+`0!U!`\&`0("@P$#OP,"O`(/'P,8 -M,")R9:`-`!`6$2)'`P)/`,(L('=H:6-H('=I;&SK&`!P"`###P-?`4!S(&5X -M+10``@(`N04$B1$""Q<#6A1X`<&QI8G)AP#S"2P@ -M:6YC;'5D:6YG(&AA``"/ -M`/0:("=D;V,G(&1I2!I;@IA(&YU;6)E6]U(#\!8"X*"D-UFEP,A8`!'P!32],6E<=`*)L>FUA+"!L>FEP$P,O -M>'HC```9-!0`"0@!E6-A;B!C,H"4B`H9F]R-`0`A`$#,P0`]`-Q -M+"!E=&,I+F\!`/H#`*D"!B($`1<``MH`#Y8#!0'(`V$B;F5W8R*;`P$S`"=S -M:+```1(`#T8#8P0%!`);`0&)``]9`P`*%@,S5VAE`P(`V`(#U`(2<^8%87)E -M'!L86EN:6YGR0`P:&]W^``"I@<`K0$#+``"*@$A -M3VX4"1PL`P$#^``!B`E086QW87E&`0#=`2IE9(H(`D<`L$DG=F4@871T96UP -MC`?@=&\@;6EN:6UI>F4@D`!RT`!"T'`,\*%&_Y"'`I+"!I="!W<`""(&=E="!P=6S["@"D!#<@26YN -M`#``B;`")E;LD!!RT``'P`"W$`*&1E$0`#Q@(1+/```H``(FYEC@(` -M%@$`0`!B86=A:6YS1P*18V]R0`P&@`A!MV`$38!(71O(@`%H0!A="!O;F-EA0`A3VZ0`QMEPP`"Y`(R<')O.@$!A0%1 -M8W1L>2W,``"."5)U='!U=.\"`&`$\0-O8FIE8W0M4X.475S92`B(0$` -M6@@@+")0"'`L(&-A<&%B00`!]@($`P$%\0!A92!!4$ESMP0(]@4!EP&`(&EN -M9&EV:61L#@/;"`"%``(5!@!"``!R"P#1```V`2%T;ZP-,&1A=-<```4.%CHN -M`0+("0`]`!)A[`(`R0H!*P`S:6X@)P$`E0LS861DC@(88?<,`=<'`QX/469I -M60!`,P``*,!!H`%,7=A;G\%$G0=#P$V`@%;`P!C -M#``S`$%D:7-K+`,`L1`0#B)A;N@"`*4'`!$# -M`EH'$"QC`$!D97-PH@``;`0!Y`,`7,N"E)%041-11(&!GX1X2!B -M=6YD;&4N"@I1=65S^@*@/R`@27-S=65S/U(`UBH@:'1T<#HO+W=W=RXX`$`N -M;W)GDP``2`$0:+@"$&:Q#S-N9V]8!Q<@3`>`(&1E=F5L;W`\!0@9$02Z$0&L -M"`$W#`!Q```Z`"%N:UT!`%T`!G,`4"!M86EL!P(P;&ESOQ`!G0`05)D!`.41 -M`.%E8$ -M(&YDT`(Q9G5L+P(&10`0+T,*`84!$6&>"C1A8W1[$W!D96UO;G-T.14@;F<^ -M``"`!094`@-)`#!C;VY#`F$Z("!687+N$V!I=&5M$0(8`&!C;VYF:6>R%A4M#``"1`"UM`Q$SM@L`$!20(&]V97)V:65W\P(`JP`%P`L`<04P -M=VAOD0(4*J0*A5]R96%D+C,L$``!^`@-$0!17V1I2T`5RH@8V%T:0`K871H -M`&ES:6UP;&6U`$!T;V]L,P$`0``#`@!R>F-A="P@8@<`$G@'``!)`4!S=6-H -M)P!0*B!E>&%)`-1S.B!3;VUE('-M86QL%0`$/@$`O@'P`&%T('EO=2!M87D@ -M9FEN9-`",69U;"\"!D4`42]M:6YIA0$18>,!46%C="!S8`"A(&1E;6]N4$` -M(&EN^``(M@)P:6YF;W)M8:D!,"!F:34!`'P`\`LJ($Y%5U,@+2!H:6=H;&EG -M:'1S(&]F(')E8P8"5&-H86YGH`*T0T]064E.1R`M('=1`6)C86X@9&^?`#-T -M:&DI`/("24Y35$%,3"`M(&EN%#36%K94QI\`!,G -MK0`#)`0`DP``3@#U`2YA;2P@86-L;V-A;"YM-"SA`$!E+F%C_P```@`2+50` -M)'1OJ``,H@2R+"!O;FQY(&YE961\`#%M86GV`2-E7-T96TZ"B`J(+@$=2XQ(&5X<&R#`@,O`P!" -M`0(A``2:`P,S``"(!`\T``L`(@`,-0`O870T``PH870S``8!!H`N,R!G:79E -M2XS30`" -M]P,2(FL#!:L``20`4"(@=71II`59(&-L87-$``'O!49N86QSG0`P`D09BP``;<&42H@1TY5=0$" -M-0(B("BK"0"Y`0`:`$%L;VYG4`9B;F%M97,L$`!3;&EN:R`1``!C`%)S<&%R -M'1E;J+ -M``-J`0`9`]$J(%!/4TE8('5S=&%R6P`"$``R<&%X-`,"60<#>`('(0"P;V-T -M970M;W)I96X!`P!@`@$>`*%35E(T($%30TE)=`(!%``"4P`/,@`%84)I;F%R -M>2X`P"`H8FEG+65N9&EA;J(!8VQI='1L91$``OH`\0))4T\Y-C8P($-$+5)/ -M32!I;;<"$2AX""!O<,L#P&%L(%)O8VMR:61G944`8DIO;&EE="D!`>\!`DD` -M-%I)4%8#!$``('5N,0LPFEP -M,A8`!'P!32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9-!0`"0@!```*56-R -M96%TSP`!=00/!@$"`JH#`[\#`KP"#Q\#&#`B&-E<$`%`+D%!&D"42!T:&%T0PXQ:7)E -M40`!\P,!R@(@("@6!0$T!`"$`0,S!`#T`V`L(&5T8REF"@+Z`P"I`@8B!`&& -M`0+:``^6`P4!R`-A(FYE=V,BFP,!,P`GD#`*4#(71EVPAA.@H*("H@+1`0 -M:2`*<&AE879I;'G\"#9E86VU!0(1"W`N("!4:&5R-!$S(&YOX@<`@@(#WP@` -MDP1!(&EN+;D``2<0`BT`",T`%&_Y"'`I+"!I="!W<`!!(&=E=!D3`5T*`*0$-R!);FX` -M-RP@:9X``5$!`YL`(F5NR0$'+0``?``+<0`H9&41``/&`A$L\``"@```C0X` -ME@$`%@$`0``P86=A+@X!\0F18V]RP,B:67-#P%O -M`P/G"B!D=1D-`)\#$'.%`2-O9H@!`(X2$"UV```S#`#W"!%IM`\`A`!R96YV -M:7)O;@\+$7>0`P&@`A!MV`$3<3`<0-0&)A8VNO$S%F2W,`))E9"!O=71P=73O`@!@!/$#;V)J96-T+7-T>6QE(&%P<')OR`,`^10" -M^@#0=&\@:&%V92!M=6QT:<,3!*D``@$$`+D(52!O<&5NG@`3(!40`&H0``H! -M$6DA"&-I=',@(D`\`!(BO0012!F4X.``P1$2(A`0!:""`L(E`(H"P@ -M8V%P86)I;&D2%`8#`07Q``+S#P$_#@CV!0&7`8`@:6YD:79I9&P.`]L(`(4` -M`#H2`D(``*P+`-$``#8!(71OK`TP9&%TUP``!0X6.BX!`L@)`#T`$F'L`@#) -M"@$K`#-I;B`G`0!%!3-A9&2.`AAA]PP!J0H#'@]19FER3``!(`1!HN`(`5P!#;VYG;U@'%R!,!R`@9%@6(&]P/`4(&1$$NA$! -MK`@!-PP`<0``.@`@;FLT`0'!``9S`$$@;6%IVQ(`^QD"H`,!_1D@7,@9&5T96-T960@ -M875T;VUA=&EC86QL>4<`L$DG=F4@871T96UP(@#P(71O(&UI;FEM:7IE('-T -M871I8R!L:6YK('!O;&QU=&EO;BX@($EF('EO=2!D;VXG=*@``+8`\"1I8VET -M;'D@:6YV;VME(&$@<&%R=&EC=6QA!E('-O;64@=71I;&ET>3X`!8P``+$!\09P -M2!D8737`%9UP",B!O9BL`,VEN("X`0!V``*4`0```P&^``7+`0#3``.C`0:`!3%W86Z(`!!T-@0#-@(! -M6P,`'P$`N@!!9&ES:RP#`\0!N6-O;G9E;FEE;F-EP`$`B0`P;6%K>0"0:7,@ -M97-P96-I;@0!T`$"J@'S!TYO=&4Z(")P87@@:6YT97)C:&%N9V6?!1,BN0(@ -M;&P\`0+H`A!DO@$`_04!C080+&,`0&1E0(1.FH`$B>7!9`G('!R;V=R86T6`G-A(&9U;&PME@AP9"`G=&%R -M)WX``P(`4W)E<&QA0@%`8G5I;($&`(H``V,``"H`9BH@8W!I;V,```X`"V0` -M(&1I:P4R96YT,`-#9F%C96H#`P(`,&5S`<``$D!`)()`"<`4"H@97AA20!`8$(&YDT`(Q9G5L+P(&10`0+T,*`84!$6$&"5%A8W0@`0-)`#!C;VY#`O`".B`@5F%R:6]UP``7P%Q875T:&]R -M<\`%`1\&`?("`DT'$`J(!E!T;W`M;`P$`W8%`#`'`4$`$&GD!@FV`B)I;M8$ -M`'$+`.L%!+T"\`).15=3("T@:&EG:&QI9VAT=&%R+C54`0CQ!$%A -M8F]U4P41]!9!I;@IA(&YU;6+R#!=FD0<$.P''"@I9;W4@`D09@82`;<&42H@1TY5=0$"-0(F("@$"P`: -M`"-L;[P%`*T+(G,L$```!0L3(!$``&,`4G-P87)S?`(A`*%35E(T($%30TE)=`(! -M%``/,@`+$$)M$1%Y+@"Q("AB:6`@@;W#+`\!A;"!2;V-K[`@0]`5HW+5II -M<"8`V$UI8W)OFEP/@$@ -M:6]/$WTJ(&)Z:7`R%@`$?`%-+TQ:5QT`HFQZ;6$L(&QZ:7`3`R]X>B,``!DT -M%``)"`$```H"G!`%.@$`=00/!@$"`J\!`[\#`KP"#Q\#&#`B\+`OH#`*D" -M`&@1`HT``9L!`MH`#\@#"F$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0%!`?. -M``]9`P`*%@,S5VAE`P(`OP@#U`(2<^8%87)E`3AN97>U`P#P!`#]`@.?`0![``&'"0$K%0)*#`,*`P`X"`!O$!1T -M[A("#`(A(&(W"0","@&/&`.X%`$,`!!A#`$"U!``:``".P`199P6`#T!(79E -M4,`4&EN9&5PJ@`E;G0B`0!$#0%Y&0!"!1)O;`T&L`L/9!K_________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_________________________________________________________V50 -M=',Z"B#V/NS(,!$``/$-("H@1TY5('1A'1E;F1E9&0`!#-!0TPS`&%/;&0@5C"!I;G1E"=M=')E92<]`5HW+5II -M<"8`V$UI8W)O2!A;'-O(&1E=&5C='--`&!H86YD;&4,`'!Y(&]F('1HW`%` -M;&QO=Y("X&)E9F]R92!E=F%L=6%T$@``(``#+P(1.M0`8'5U96YC;W$"`+8" -M`D,"`0H`$2"#`:)24$T@=W)A<'!E3@)%9WII<#X!,6EO;D0`76)Z:7`R%@`$ -M9`%-+TQ:5QT`HFQZ;6$L(&QZ:7`3`R]X>B,``!DT%``)"`&58V%N(&-R96%T -MSP!/&-E<'0"`D0*("`@:0+1('1H870@P`!S@`0=IL$`#4'$G.C`%0@;VYL>0H#0&UE;G2R -M``$>`P"F!`(K`#`@8F5``'%R96%D86)L``9!=W)I=`P`$&$,`0($`0!H``([ -M`$)E86-H/0$A=F5S`Q-Y0P!0:6YD97"J`")N='\`$'([!``$`#!T:6-"!21O -M;H$!!*X`\`!7:6MI(&5X<&QA:6YI;F>)`#!H;W?X``&S`Q!DE@4#+``"*@$A -M3VZJ`!PL`P$`!`0R;6%T<`!`;'=A>48!`-T!\@%E9"!A=71O;6%T:6-A;&QY -M1P"P22=V92!A='1E;7",!^!T;R!M:6YI;6EZ92!S="L``E((4'!O;&QUN`'A -M+B`@268@>6]U(&1O;B?L`0"V`/$":6-I=&QY(&EN=F]K92!A('#K`"!U;+T( -MH&5A='5R92`HD`!RT`!$4'`R("`ID!<"DL(&ET('=P`.`@ -M9V5T('!U;&QE9"!I;J0$-R!);FX`-RP@:9X``5$!`YL`(F5NR0$'+0``?``+ -M<0`H9&41``.J`!$L\``"@``B;F6.`@`6`0!``'%A9V%I;G-TSP&18V]RP,Q:65SPP`!;P,!;P=16QE(&%P<')OR`,`R0@"^@#@=&\@:&%V92!M=6QT -M:7`E``-3!`(!!`"Y"%4@;W!E;IX`4"`@8G-D(P2!F)M96UO -M7,"!8P``0`"\05R;W9I9&4@96%S>2UT;RUU0#`*8.T"!S87ES+@I214%$346[!@?H!N$@8G5N9&QE -M+@H*475E<_H"H#\@($ES7!1`GH@1`9W)A;18"&%)`$!S.B!3,@-4`0-)`#!C;VY#`O`".B`@5F%R:6]UP``7P%Q875T -M:&]R<\`%`1\&`?("`-(1$B[M#U!T;W`M;`P$`\4,`#`'`4$`$&GD!@FV`B)I -M;M8$`*0*`.L%!+T"\`).15=3("T@:&EG:&QI9VATT3`A@`8&-O;F9I9WX+%2T,``)$ -M`+5S8W)I<'0L('-E96<``"@%9&1E=&%I;,,$84--86ME3-0$,71X=(@`(G!U -MU@T@(F,T!A$B)`,`.`PI;VQ-``)6`0;K`P$I`0`6"0".`0]M`0$`L`P0=3T3 -M`=H!-&4*)[``(V4GK0``.@\P("H@DP``3@#P`"YA;2P@86-L;V-A;"YM-`D- -M`^T`,"YA8_\```(`$"VB`@"?``2H``#9#@BB!!(L&@X`UPL`60L0>PH"MP(`318A86R)!T!S97%U -MZ@@0=&%R+C54 -M`0CQ!`4^$A%SU@TQ<&]PY0\#G`$$>P`(2PE`:&%R9!8,`3`&`J@!`X42`(X! -M86UO9&5R;H\``.@!`+P'<"!V87)I86Y("0`B##!M86[X"Q%PK1]!;!I;@IA(&YU;6)E"`"X!!,BXP`R+F@BJ0`R:&4*7PP0 -M(+`)`/H``!0`!.D&`W((`G\"$&T:%P/[`$(N("!0B@FR;&5T('5S"FMN;W<0 -M`0&9!F!E`D09@82`;<&`H<8!JH+#V0:____________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________________________________________________]94%-O -M;64@(HLUAC01``#T)G-M86QL(&5X86UP;&4@<')O9W)A;7,@=&AA="!Y;W4@ -M;6%Y(&9I;F0@=7-E9G5L+@H@("`J,`#R!W,O;6EN:71A2!T:&ER9"!P87)T:65S -M.X,``P(`87!L96%S948``'L`\BET:&4@875T:&]R2!Q=65S -M=&EO;G,N"@I4:&4@=&]P+6QE=F5L(&1I4$`(&EN^`"`92!F;VQL -M;W>V`'!I;F9O'2(`#%P=70I`/D#(F-M86ME(B!B -M=6EL9"!T;V]L30`"5@$&-0$!*0$Q(&EN3`$/;0$!,&%R91`"$F3:`35E"B>\ -M`!,GK0`#9P$`DP``3@#U`2YA;2P@86-L;V-A;"YM-"SA`$!E+F%C_P```@`2 -M+50`)'1OJ```(`$P9&ES7P(0=4$!LBP@;VYL>2!N965D?``Q;6%I]@$C97)< -M`05P`"1I;F0`\@,N:"YI;@H)+2!T96UP;&%T97-G`!%B-`(!9@$39;4`8`H* -M1W5I9/,`DB!$;V-U;65N=($!`,4!,F%L;'4``/,!]0H@'!L@P(#+P,`0@$"(0`$F@,#,P!/8W!I;S0`"P`B``PU`"]A -M=#0`#"AA=#,`!ZT#\`0S(&=I=F5S(&%N(&]V97)V:65W\P(`H`#P`6QI8G)A -M`?$#+@H*66]U('-H -M;W5L9"!A;'-O(@(!3``Q8V]P=@8R8V]M6P%#:6X@(KT",BYH(JD`@&AE"G-O -M=7)C+P`19'4!`!0`!.D&!30'`"P%-&UO<$",&5C=)D#$635``,<`@7"!A!F+``!MP91*B!' -M3E5U`0*Z`28@*+D!`!H`06QO;F=5`F)N86UE'1E;J+``-J`0`9`]$J(%!/4TE8('5S=&%R6P`"$``P<&%X20,B97)9!P-X`@FEP,A8`!'P!32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9-!0`"0@! -M```*56-R96%TSP`!=00/!@$"`JH#`[\#`KP"#Q\#&#`B&-E<$`%`+D%!&D"`A4,<7)E -M<75IP`#GP$`>P`! -MAPD!HP`"2@P#"@,`.`@`L@`Q=&AA+PD#*P`A(&(W"0!J"#%A8FP`!@","@$, -M``$L"P($`0!H``([`$)E86-H/0$A=F5S`Q-Y0P!0:6YD97"J`"5N="(!`!@) -M``\/$&-"!1)O;`T&-0I4(%=I:VE2##!I;F?)`#!H;W=1#P&S`Q=DE@H"*@$A -M3VX_"`#W#`)@!@,#`03-``%P`$!L=V%Y1@$`W0$J962*"`)'`'!))W9E(&%T -M+0T`C`<`P0^0:6YI;6EZ92!S#@T28U((07!O;&R4#5$N("!)9O4(4&1O;B=T -MJ`"097AP;&EC:71LV0EB=F]K92!A^@\18W\*,69E830+,"AS=2\!!?L*`*D` -M("!A00`!)Q`"+0`(S0`4;_D(<"DL(&ET('=P`'$@9V5T('!UG`T0:7H+1R`@ -M26YN`#``%1`0.;`")E;LD!!RT``#X`"W$`*&1E$0`#Q@(1+/```H`` -M`(T.`)8!`!8!`$``(&%G`PX"4`.18V]R0`P&@`A!MV`$32X'<70@82!T:6U7`W%O8!(71O(@`%2@!2="!O;F-\$B)/;AP."\,``N0",G!R -M;SH!`84!46-T;'DMS`"2960@;W5T<'5T[P(`8`3Q`V]B:F5C="US='EL92!A -M<'!R;\@#`$,2`OH`T'1O(&AA=F4@;75L=&EE$P2I``(!!`"Y"`#^#15NG@`3 -M(!40`&H0``H!`#T%@VX@:71S(")`/``2(KT$$7,P#@)C!098`&!I='-E;&93 -M`0!]!!`O=@1@=&5N('5S;P8`-PP!<@$R9G5N6!($DP$!=08`,@`U(&%NB`0" -M(Q-0;'D@9G)@``S0*%82!S;V-K -M970^`TEW:7-HN@0!)@\#60\`#B)A;N@"`*4'!C0*$"QC -M`$!D97-PWP``;`0!Y`,`7,N"B05$6:X#01Q%K0@8G5N9&QE+@H* -M41$6H#\@($ES71E(&%T(&$@=&EM90H@("!O2UB;&]C:V5D(&]U='!U -M="X*"B`J(%1H92!O8FIE8W0M'1E;G-I;VZ*``,<```J`#!E;&93 -M`5!R96%D+^8`EG1E;B!U2!B=69F97(@;W+!``!E``1R -M`3!A(',K`5%T+"!I9@(!8'=I2UT;RUU`@#1```V`:!T;R!A;GD@9&%T -MUP!6=7)C93HN`5%C`@&^``7+`0#3``.C`4,N("!) -MI`$A86Z(`!)T70`#10$`8``0:84"86\@9&ES:RP#`\0!N6-O;G9E;FEE;F-E -MP`$`B0`P;6%K>0#1:7,@97-P96-I86QL>=`!`JH!\P].;W1E.B`B<&%X(&EN -M=&5R8VAA;F=E(&9O7,N"E)%041-12X``$0$!&T!T6)U;F1L92X* -M"E%U97/Z`J`_("!)3``!( -M!!!HN`*P9F]R(&]N9V]I;F`<``$D!0'-U -M8V@G`%`J(&5X84D`0',Z(%,R`U1S;6%L;!4`!#X!`%(#(6%T(`8@;6'F!"!N -M9-`",69U;"\"!D4`42]M:6YIA0$18>,!46%C="!S8`"P(&1E;6]N0&";8"(FEN^`0B:6_A -M!@2]`O`"3D574R`M(&AI9VAL:6=H='-M``,D!`"3``!.`/4!+F%M+"!A8VQO8V%L+FTT+.$`0&4N86/_ -M```"`!`MH@(`GP`$J``,H@2R+"!O;FQY(&YE961\`#%M86GV`2-E'!L@P(#+P,`0@$"(0`$ -MF@,#,P``B`0/-``+`"(`##4`+V%T-``,*&%T,P`&`08A+C.V"Q!SWP:`;W9E -M"P!Q!3!W:&^1`A0JI`J%7W)E860N,RP0``'X"`T1`%%? -M9&ES:Q8``GX'`X(%`3X``QP``)D``7L*`K<"$F6@#`!;!!!SU`80;A$,`-8" -M`),``'4``!<"`/D$`7$``7$*")<``#P),WDN,TT``.\$,F4@(FL#!:L``20` -M%"(+"UD@8VQA``'<`%`D09BP``;<&42H@ -M1TY5=0$"-0(F("@$"P`:`$%L;VYG4`8`K0LB+``-J`0`9 -M`]$J(%!/4TE8('5S=&%R6P`"$``/B@P#!R$`P&]C=&5T+6]R:65N=!<$,7!I -M;QX`IE-64C0@05-#24D4``)3``\R``5A0FEN87)Y+@#`("AB:6B,``!DT%``)"`$```H"G!`%.@$`=00/!@$"`J\!`[\# -M`KP"#Q\#&,$B&-E<$`%`+D%!(D142!T:&%T0PX`TQ,`40`%Z1(P?P(-F5A;;4%`A$+!8@4 -M0&ES(&[6$C%R96,P$0/?"`"3!$$@:6XM`@^"(&UO9&EF:6/E#/<`;W(@`3AN97>U`P#P!`#]`@.? -M`0![``&'"0$K%0)*#`!-$2)IE(7`+4(`E((07!O;&PV$@;D%$%D;VXG[`&0 -M97AP;&EC:71LV0EB=F]K92!A^@\18W\*`\X1("`HTA``=0P('`(08;(!`2<0 -M`BT`",T`%&]S!'`I+"!I="!W<`!0(&=E="#2$@%="@"D!#<@26YN``4F%P&> -M``%1`0.;`")E;LD!!RT``'P`"W$`*&1E$0`#J@`1+%@1`H```(T.`)8!`!8! -M`$``,&%G8?,/`5\*D6-O"(&5N=FER;VX/ -M"T!W:&5R+Q9`870@;=@!$W):`P4P`@!;``)_`!%Y>P,1<#4`8F%T979EFUA+"!L>FEP+"!A -M;F0@>'HC```9-!0`]0<*5&AE(&QI8G)A"!I;G1E&-E<'0@9F]J`/$'("!E;G1R:65S('1H870@ -M.`?$#;F%M97,L($%#3',L -M(&5T8RDND@"P3VQD($=.52!T87)=``2I``+*`/$$;V-T970M;W)I96YT960@ -M8W!I;S4`ME-64C0@(FYE=V,B%0`G -M`'@G;71R964GNP!X25-/.38V,!,`6C2!S=')E86WM`>!S>7-T96TN("!4:&5R92P`\01N;R!D:7)E -M8W0*("`@`>-R86YD -M;VT@86-C97-S+GD`!I<`\@)I'!L86EN:6YGB0`P:&]W^``"]0``C@0#+``"*@$A3VZJ`!PL`P$# -MV0("<`!`;'=A>48!`-T!\@%E9"!A=71O;6%T:6-A;&QY1P"P22=V92!A='1E -M;7#$`^!T;R!M:6YI;6EZ92!S="L`L"!L:6YK('!O;&QUN`'A+B`@268@>6]U -M(&1O;B?L`0"V`/$":6-I=&QY(&EN=F]K92!A('#K`"!U;#<$(&5A60)`("AS -M=2\!&7,<`A!AZ0`'+0`'[P4`@`$"F0%P*2P@:70@=W``X"!G970@<'5L;&5D -M(&ENI`0W($EN;@`W+"!IG@`!40$#FP`B96[)`07L#$7`U`-%A=&5V97(@8FQO8VMS\``0:%<%(6ETH0!!66]U2X'<70@82!T:6U7`W%O -M8!(71O(@`%H0!A="!O;F-EA0`A -M3VZ0`QMEPP`"Y`(R<')O.@$!A0%18W1L>2W,``!(!E)U='!U=.\"`&`$\0-O -M8FIE8W0M2!F)M96UO?<"!8P``0`"\05R;W9I9&4@96%S>2UT;RUU8<``J,!!H`%,7=A;H@`$'0V!`5%`0!@``'Z -M"0".!R%S:RP#`WX&N6-O;G9E;FEE;F-EP`$`B0`P;6%K>0"0:7,@97-P96-I -M;@0!T`$"J@$`.@@P.B`BDPH.NPH3(KD"(&QL/`$"Z`(`I0<`$0,"P040+&,` -M0&1EP`"-E)ZT``V2XS30``[P0R92`B -M:P,%JP`!)``4(@L+62!C;&%S1``!'PE&;F%L``'?`5=H+`#L'`2,) -M"=H1`,$",&5C=)D#$61A#0,<`@>F%@`@`@!0!0)!%0:J"R8@*`0+`%L5#"`6 -M`1````4+`;X+$G,W`E)S<&%R\6`2T5`A``#XH,`P%V,/"Q<`T$UI8W)O2!N965D -M960@8GD@;6%I;G1A:6YE7-T96TZ"B`J(&)S9'1A@`/`#;&EB -M2!A2XS30`"=`%U -M(G-T2!C;&%S1`"6:6YT97)N86QSG0!@2!E2QN``5H`W!U=&]M871I_P(0>68!,&5C=)D#$635``,<`E!O;&QO=Y,!$&8L -M`#!S.@K?!#!'3E7X`0#``%9M870@*+D!`!H`06QO;F=5`F)N86UE$D#<65R8VAA;F=^`3=M870A`+!O8W1E="UOFEP/@$Q:6]N!0%=8GII<#(6``1\`4TO3%I7'0"B -M;'IM82P@;'II,H"("`H?0;#`*F!P>6"@(J`2%/;C\(`/<,`G@&`0(*(VYD -M^``!B`EC86QW87ESF4@``B;`")E -M;LD!!RT``'P`"W$`*&1E$0`#Q@(1+/```H```(T.`)8!`!8!`$``(&%G`PX" -M1P*18V]RP,1<#4`T6%T979E2W,`))E9"!O -M=71P=73O`@!@!/$#;V)J96-T+7-T>6QE(&%P<')OR`,`R0@"^@#0=&\@:&%V -M92!M=6QT:3$,!*D``@$$`+D(52!O<&5NG@`3(!40``80``H!`#T%@VX@:71S -M(")`/``2(KT$$7,P#@)C!098`&!I='-E;&93`0!]!!`O=@1@=&5N('5S;P8% -M<@%`9G5N8Z4*`C0"`"$-(F-A!00U(&%NB`0"9@U0;'D@9G)@``S0*%82!S;V-K970^`TEW:7-HN@0!)@\#60\` -M4X.475S92`B(0$`6@@@+")0"+$L(&-A<&%B:6QI -M=/8"!`,!!?$``O,/`;<$"/8%`9P"`,D*`2L`,VEN -M("#U%F:7)S=)("`*8!$6%P$A%O61$`]@`6 -M+G0``]D#`J60!`,P` -M`*,!!H`%,7=A;G\%$G0=#P$V`@%;`P$:!!!TC@0#`',*T2!S -M87ES+@I214%$3442!@9)$>$@8G5N9&QE+@H*475E<_H"H#\@($ES+%1`GD1(`\A$` -M%@)S82!F=6QL+98(!L30',Z(%,R`U1S;6%L;!4` -M!#X!`%(#(6%T'`@@;6'F!"!N9-`",69U;"\"!D4`$"]#"@&%`1%AH0LT86-T -M>Q-P9&5M;VYS=#D5(&YG/@``@`4&5`(#20`P8V]N!1AA.B`@5F%R[A-@:71E -M;7,@,P$`UP(@;64.&%)T:&ER9,\),&5S.\@``P(``^H"`$8``'L``%\!<6%U -M=&AOP`"-E)Z\9`R0$ -M`),``$X`CRYA;2P@86-L9!K_____________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_____________________________VI086YY(&1:8C!),!$``/`<871A('-O -M=7)C93H@(%EO=2!C86X@8W)E871E"B`@(&$@8FQO8VL@;V8@9"L`\!YI;B!M -M96UO8<`\01S -M;V-K970N("!)9B!Y;W4@=V%NB``2=%T`$B\]``!@`#!I97,S`%!D:7-K+$X` -M\`QR92!A2!E87-Y+@H*("H@3F]T93H@(G!A>"!I;G1E'1E;F1E9#@!`B(`$"QC`$!D97-PWP!`=VAA -M=)8`\`,@;F%M92!S87ES+@I214%$3450`$0@;&EB;0'18G5N9&QE+@H*475E -M`<``$D!0'-U8V@G`%`J(&5X84D`0',Z(%,R`U1S;6%L;!4`!#X!`%(#(6%T -M?`0@;6'F!"!N9-`",69U;"\"!D4`42]M:6YIA0$18>,!46%C="!S8`"A(&1E -M;6]NM``,D!`"3``!.`/4!+F%M+"!A -M8VQO8V%L+FTT+.$`0&4N86/_```"`!`MH@(`GP`$J``,H@2R+"!O;FQY(&YE -M961\`#%M86GV`2-E7-T96TZ<`<"N`1U -M+C$@97AP;(,"`R\#`$(!`B$`!)H#`S,``(@$#S0`"P`B``PU`"]A=#0`#"AA -M=#,`!@$&@"XS(&=I=F5SWP:`;W9EP$2+8($-7,N-:H(`)X%$67[`P#R`(!M871S('-U<'\(!&," -M!98!`$P```H"D"XU+"!M=')E90D``&\`7G1A`D09BP``;<&42H@1TY5=0$"-0(F("@$ -M"P`:`$%L;VYG50(`K0LB+``-J`0`9`]$J(%!/4TE8('5S -M=&%R6P`"$``/B@P#!R$`P&]C=&5T+6]R:65N=!<$,7!I;QX`IE-64C0@05-# -M24D4``)3``\R``5A0FEN87)Y+@#`("AB:6FEP,A8`!'P!32],6E<=`*)L>FUA+"!L>FEP$P,O -M>'HC```9-!0`"0@!```*`IP0!3H!`'4$#P8!`@*O`0._`P*\`@\?`Q@P(G)E -MH`U18W1E9")'`P)/`,,L('=H:6-H('=I;&PF$0)U`P:0`%%E>&-E<$`%`+D% -M`?P(-F5A;;4%`A$+<"X@(%1H97(T$2`@;M82 -M,7)E8S`1`]\(`),$02!I;BVW#X(@;6]D:69I8^4,\@%OP`!APD!HP`"2@P`31$B:7*"$1!I>0<#[A("#`(A(&(W"0","C%A -M8FP`!@","@$,``$L"P+4$`!H``([`$)E86-H/0$A=F5S`Q-Y0P!0:6YD97"J -M`"5N="(!`$0-``\/$&-"!1)O;`T&-0I4(%=I:VE2#`,,$S!H;W?X``&S`Q!D -MK0$#V@`"*@$A3VX_"`#W#`)@!@#S#@!0!@/-``%P`%-L=V%Y'!L:6-I#16":6YV;VME(&'Z#Q%C?PH#SA$@("C2$"4@8?L* -M`*$!("!AL@$!)Q`"+0`(S0`4;W,$<"DL(&ET('=P`%`@9V5T(-(2`5T*`*0$ -M-R!);FX`,BP@:8(5`9X``5$!`YL`(F5NR0$'+0``?``+<0`H9&41``/&`A$L -MY0D"@```C0X`E@$`%@$`0``P86=A\P\!7PJ18V]R"(&5N=FER;VX/"Q%WD`,!H`(0;=@!$W):`P4P`@!;``)_`!%Y -M>P,1<#4`8F%T979E:89`@4.#V0:________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M__________________________]@4"`@*B!)&=+.F401``#Q$5-/.38V,"!F -M;W)M870*("`J(#2!O -M9B<`H69O;&QO=VEN9SI@`(%U=65N8V]D90T`\0%G>FEP(&-O;7!R97-S:6]N -M%0!=8GII<#(6``0F`$TO3%I7'0#Y`VQZ;6$L(&QZ:7`L(&%N9"!X>B,`P0I. -M;W1E7-T96TN("!4:&5R92P`@&YO -M(&1IF4@2!I;G9O:V4@82!PZP"` -M=6QA2!F -MP`28D(``"P$`-$``#8!(71O -M>`0#\`)N86UE('-A>7,N"E)%041-15``!^@&X2!B=6YD;&4N"@I1=65S^@*@ -M/R`@27-S=65S/U(`URH@:'1T<#HO+W=W=RX@!S!O3``!(`1!HN`*#9F]R -M(&]N9V]8!Q@@9`!P9&5V96QO<#P%<2P@:6YC;'6]!4!D;V-U%``!K`@!3@D` -M<0``.@`A;FM=`0!=``9S`%`@;6%I;`<"0FQIF-A="P@8@<`$G@'``!)`0"2"0`G`%`J(&5X84D`0',Z(%,R`U1S;6%L;!4` -M!#X!`%(#(6%T'`@@;6'F!"!N9-`",69U;"\"!D4`$"]#"@&%`1%AG@I186-T -M('-@`)(@9&5M;VYS=')*#0`I!B=O9EX!`TD`,&-O;D,"\`(Z("!687)I;W5S -M(&ET96US(#,!`'T#0&UE(&(W`3)I0&";8" -M(FENU@0`Q@P`ZP4$O0+P`DY%5U,@+2!H:6=H;&EG:'1S7`8PP`"-E)ZT``R0$`),``$X`\``N86TL(&%C;&]C86PN;30) -M#0/M`#`N86,7`0`"`!`MH@(`GP`$J```V0X(H@02+!H.`-<+`GP`,6UA:?8! -M(V5RK@$%<``D:6YD`($N:"YI;@H)+?0'(&QA5@\$NP`%A0`#M0!@"@I'=6ED -M\P`H($14!@32`0)U``&W`0)3#Q`Z&@D"N`0A+C'!#`!A#`$W`0,O`P`+``(A -M``2:`P,S``"(!`\T``L`(@`,-0`O870T``PH870S``8!!B$N,[8+$'-E"H!O -M=F5R=FEE=_,"`*``!<`+`'$%4'=H;VQEI``#1`6$7W)E860N,RRT"A%?^`@- -M$0!17V1IH($',+ -M!0$^`0!U```7`@#Y!`%Q``%Q"@B7```\"3-Y+C--``#O!#)E(")K`P6K``$D -M`!0B"PM9(&-L87-$``$?"49N86QSG0`2!Q(M@@0U=&%R+C54`0CQ!`4^ -M$A%S8P0Q<&]PY0\#G`$$>P`(2PE`:&%R9!8,`3`&!%L!`4<``(X!86UO9&5R -M;H\``.@!`+P'<"!V87)I86Y("0":!3!M86[X"T%P86=E.```,0XD -M``'?`5=H+`#L'`2,)"=H1`,$" -M,&5C=)D#$61A#0,<`@2#%"`@9@82`;<&42H@1TY5=0$"-0(F("@$"P`:`"!L -M;R\`,&EL9:T+(G,L$```!0L3(!$``&,`4G-P87)S?`(A`*%35E(T($%30TE)=`(!%``/,@`+ -M$$)M$1%Y+@"Q("AB:6\!`DD` -M-%I)4'4$!$``('5N,0L`)18`UA!@C2H`0#E%PD(`0``"@*<$`5+`0!U -M!`\&`0("KP$#OP,"O`(/'P,8,")R9:`-`!`6$2)'`P)/`,(L('=H:6-H('=I -M;&SK&`!P"`###P-?`4!S(&5X+10``@(`N04$B1$""Q<#6A1X`<&QI8G)AP#S"2P@:6YC;'5D:6YG -M(&AA``"/`/0:("=D;V,G -M(&1I2!I;@IA(&YU;6)E6]U(#\!8"X*"D-U\!`DD` -M-%I)4%8#!$``P'5N8V]M<')EC`@0]`5HW+5II<"8`V$UI -M8W)O`,( -MKP)@:&%N9&QENP(0>;<#`=0$!;@",&)E9DH#<&5V86QU873*`@`@``.9`P+/ -M`D!U=65ND`,19+8"`D,"`!4%(7,@@P&B4E!-('=R87!P94X"16=Z:7`^`3%I -M;VX8`5UB>FEP,A8`!'P!32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9-!0` -M"0@!E6-A;B!C,H"4B`H9F]R-`0`A`$#,P0`]`-Q+"!E=&,I+F\! -M`/H#`*D"!B($`1<``MH`#Y8#!0'(`V$B;F5W8R*;`P$S`"=S:+```1(`#T8# -M8P0%!`);`0&)``]9`P`*%@,S5VAE`P(`V`(#U`(2<^8%87)E'!L86EN:6YGR0`P:&]W^``"I@<`K0$#+``"*@$A3VX4"1PL`P$# -M^``!B`E086QW87E&`0#=`2IE9(H(`D<`L$DG=F4@871T96UPC`?@=&\@;6EN -M:6UI>F4@D`!RT`!"T' -M`,\*%&_Y"'`I+"!I="!W<`""(&=E="!P=6S["@"D!#<@26YN`#``B; -M`")E;LD!!RT``'P`"W$`*&1E$0`#Q@(1+/```H``(FYEC@(`%@$`0`!B86=A -M:6YS1P*18V]R0 -M`P&@`A!MV`$38!(71O -M(@`%H0!A="!O;F-EA0`A3VZ0`QMEPP`"Y`(R<')O.@$!A0%18W1L>2W,``". -M"5)U='!U=.\"`&`$\0-O8FIE8W0M7,"!8P``#\`!)4.0&5AP"`,D*`2L`,VEN("#U%F:7)S=)("`*8! -M(&$@0P41;U`'`/8`%BYT``/9`P*G`0"_``*<`0&%``:X`0!V``##``"\`Q)E -MDP`",0\@;'ED`0#,``"C`0:`!3%W86Y_!1)T'0\!-@(!6P,`8PP`,P!!9&ES -M:RP#`+$0$'*?!)EN=F5N:65N8V7``0")`#!M86MY`)!I0#`',*T2!S87ES+@I214%$3442!@9^$>$@8G5N9&QE+@H* -M475E<_H"H#\@($ES1$@#R$0`6`G-A(&9U;&PME@AR9"`G=&%R -M)P\!`0(`(7)EK0H!0@%`8G5I;($&`(H``V,``"H``J(3!F,``,$0"V0`!M,2 -M`3`#,&9A8RH'`#T``P(``"D0(FYT:`,`$0(V!L30',Z(%,R`U1S;6%L;!4`!#X!`%(#(6%T'`@@;6'F!"!N9-`",69U -M;"\"!D4`$"]#"@&%`1%AG@HT86-T>Q-P9&5M;VYS=#D5(&YG/@``@`4&5`(# -M20`P8V]N0P)A.B`@5F%R[A-@:71E;7,@,P$`UP(B;64V%3)I'2(`"%P=6<0,"`B8S0&$2(D`P`X#"EO;$T``E8!!NL#`2D! -M`!8)`(X!#VT!`0`@#1!U/1,"$!P`"-E)ZT``R0$`),``$X`\``N86TL -M(&%C;&]C86PN;30)#0/M`#`N86/_```"`!`M9`(`GP`$J```V0X(H@02+!H. -M`-<+`%D+$'G*!0'V`2-E!,"(0`$F@,#,P``B`0/-``+`"(`##4`+V%T-``, -M*&%T,P`'K0,1,[8+`!`4D"!O=F5R=FEE=_,"`*L`!<`+`'$%,'=H;Y$"%"JD -M"H5?H(`N47`),``'4``!<"`/D$`7$``7$*")<``9P) -M("XSHQ2!F;W(@:L`D'-A;64@ -M9G5N8S`<``$D!0'-U8V@G`%`J(&5X84D`U',Z(%-O;64@ -M6]U(&UA>2!F:6YD('5S969U;"\"!D4`42]M -M:6YIA0$18>,!46%C="!S8`"A(&1E;6]N2#R`I!I;VYS -M+@H*5&B=`?("<"UL979E;"!D:7)E8W1O%#36%K94QI -M\`!,GK0`#)`0`DP``3@#U`2YA;2P@ -M86-L;V-A;"YM-"SA`$!E+F%C_P```@`2+50`)'1OJ``,H@2R+"!O;FQY(&YE -M961\`#%M86GV`2-E7-T96TZ"B`J(+@$=2XQ(&5X<&R#`@,O`P!"`0(A``2:`P,S``"(!`\T``L` -M(@`,-0`O870T``PH870S``8!!H`N,R!G:79E2XS30`"]P,2(FL#!:L``20`4"(@=71I -MI`59(&-L87-$``'O!49N86QSG0`P`D09BP``;<&42H@1TY5=0$"-0(B("BK"0"Y`0`:`$%L;VYG -M4`9B;F%M97,L$`!3;&EN:R`1``!C`%)S<&%R'1E;J+``-J`0`9`]$J(%!/4TE8('5S -M=&%R6P`"$``R<&%X-`,"60<#>`('(0"P;V-T970M;W)I96X!`P!@`@$>`*%3 -M5E(T($%30TE)=`(!%``"4P`/,@`%84)I;F%R>2X`P"`H8FEG+65N9&EA;J(! -M8VQI='1L91$``OH`\0))4T\Y-C8P($-$+5)/32!I;;<"$2AX""!O<,L#P&%L -M(%)O8VMR:61G944`8DIO;&EE="D!`>\!`DD`-%I)4%8#!$``('5N,0LPFEP,A8`!'P!32],6E<=`*)L>FUA -M+"!L>FEP$P,O>'HC```9-!0`"0@!```*56-R96%TSP`!=00/!@$"`JH#`[\# -M`KP"#Q\#&#`B&-E<$`%`+D%!&D"42!T:&%T0PXQ:7)E40`!\P,!R@(@("@6!0$T!`"$ -M`0,S!`#T`V`L(&5T8REF"@+Z`P"I`@8B!`&&`0+:``^6`P4!R`-A(FYE=V,B -MFP,!,P`GD#`*4#(71EVPAA.@H*("H@+1`0:2`*<&AE879I;'G\"#9E86VU -M!0(1"X`N("!4:&5R9;T/(VYOX@<`@@(#WP@`DP1!(&EN+;D``2<0`BT`",T`%&_Y"'`I -M+"!I="!W<`!!(&=E=!D3`5T*`*0$-R!);FX`-RP@:9X``5$!`YL`(F5NR0$' -M+0``?``+<0`H9&41``/&`A$L\``"@```C0X`E@$`%@$`0``@86<##A%T\0F1 -M8V]RP,B:67-#P%O`P/G"B!D=1D-`)\#$'.%`2-O -M9H@!`(X2$"UV```S#`#W"!%IM`\`A`!R96YV:7)O;@\+$7>0`P&@`A!MV`$3 -M<3`<0-0&)A8VOR`S%F2W,`))E9"!O=71P=73O`@!@ -M!/$#;V)J96-T+7-T>6QE(&%P<')OR`,`^10"^@#0=&\@:&%V92!M=6QT:<,3 -M!*D``@$$`+D(52!O<&5NG@`3(!40`&H0``H!$6DA"&-I=',@(D`\`!(BO001 -M2!F4X.``P1$2(A`0!:""`L(E`(H"P@8V%P86)I;&D2%`8#`07Q``+S -M#P$_#@CV!0&7`8`@:6YD:79I9&P.`]L(`(4``#H2`D(``*P+`-$``#8!(71O -MK`TP9&%TUP``!0X6.BX!`L@)`#T`$F'L`@#)"@$K`#-I;B`G`0!%!3-A9&2. -M`AAA]PP!J0H#'@]19FER41`.7,@9&5T96-T960@875T;VUA=&EC86QL>4<`X$DG=F4@ -M871T96UP=&5D<`"P;6EN:6UI>F4@6]U(&1O;B=T"B`@(&5X<&QI8VET;'D@:6YV;VME(&$@<&%R=&EC=6QA -M``B;`%IE -M;F%B;)L``#X`"W$`*&1E$0`#J@`1+/```H``(FYE)@$`%@$`0`#Y"F%G86EN -M8`0U:`)%L:6)R87)I97/#`/$"5&AI717`G`@82!T:6UEI0!Q;W(@ -M;6UA<-H`0&5N=&F?`@+0`@&V`D!G:79EY@$A=&\B``5*`&%T(&]N8V6%`(M/ -M;B!W`+$@(&)S9'1A2!D8737`%9UP",B!O9BL`,VEN -M("X`0!V``*4`0"A`P&^``7+ -M`0#3``.C`0:`!3%W86Z(`!!T-@0#-@(!6P,`'P$`N@!!9&ES:RP#`\0!N6-O -M;G9E;FEE;F-EP`$`B0`P;6%K>0"0:7,@97-P96-I;@0!T`$"J@'S!TYO=&4Z -M(")P87@@:6YT97)C:&%N9V6?!1,BN0(@;&P\`0+H`A!DO@$`_04!C080+&,` -M0&1E0(1.FH`$B>7!1`GH@1` -M9W)A;18"&%)`$!S -M.B!3,@-40&";8"(FENU@0`<0L`ZP4$O0+P`DY%5U,@+2!H:6=H -M;&EG:'1S7`8P=&%R+C54`0CQ!$%A8F]U4P41]!9!I;@IA -M(&YU;6+R#!=FD0<$.P''"@I9;W4@`D0 -M9@82`;<&42H@1TY5=0$"-0(F("@$"P`:`"-L;[P%`*T+(G,L$```!0L3(!$` -M`&,`4G-P87)S?`(A`*%35E(T($%30TE)=`(!%``/,@`+$$)M$1%Y+@"Q("AB:6`@@ -M;W#+`\!A;"!2;V-K[`@0]`5HW+5II<"8`V$UI8W)OFEP/@$@:6]/$WTJ(&)Z:7`R%@`$?`%-+TQ: -M5QT`HFQZ;6$L(&QZ:7`3`R]X>B,``!DT%``)"`$```H"G!`%.@$`=00/!@$" -M`J\!`[\#`KP"#Q\#&#`B\+`OH#`*D"`&@1`HT``9L!`MH`#\@#"F$B;F5W -M8R*;`P$S`"=S:+```1(`#T8#8P0%!`?.``]9`P`*%@,S5VAE`P(`OP@#U`(2 -M<^8%87)E`3AN97>U`P#P!`#]`@.? -M`0![``&'"0$K%0)*#`,*`P`X"`!O$!1T[A("#`(A(&(W"0","@&/&`.X%`$, -M`!!A#`$"U!``:``".P`199P6`#T!(79E4,`4&EN9&5PJ@`E;G0B`0!$ -M#0%Y&0!"!1)O;`T&L`M4(%=I:VE2#`,,$S!H;W=1#P&S`Q!DK0$#V@`"]Q,% -M-!@$_`0`\PX`4`8#S0`!<``"@!<"Q`4/9!K_________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_________________________________________QY0=61I;F?\MV+.+A$` -M`/(%($=.52!L;VYG(&9I;&5N86UE'1E;F1E9"!T87(@9F]R;6%T("AI;F-L -M=61I;F<@04-,,P!A3VQD(%8W)P"!87)C:&EV97-+`+=03U-)6"!U2!O9B!T:-P!0&QL;WFEP,A8`!&0!32],6E<=`*)L>FUA+"!L>FEP -M$P,O>'HC```9-!0`"0@!E6-A;B!C0`&EP"0:7,@9&5S:6=NH@9";R!B98@%`$`$`3`$.&YE=[4#`*,$`'L``4,`4&EN -M9&5PJ@`B;G1_`!!R.P0`!``P=&EC0@4D;VZ!`02N`/``5VEK:2!E>'!L86EN -M:6YGB0`P:&]W^``!LP,09)8%`RP``BH!(4]NJ@`<+`,!``0$,FUA='``0&QW -M87E&`0#=`?(!960@875T;VUA=&EC86QL>4<`L$DG=F4@871T96UPC`?@=&\@ -M;6EN:6UI>F4@2!I;G9O:V4@82!PZP`@=6Q9"*!E871U``%1`0.;`")E;LD!!RT``'P`"W$`*&1E$0`#J@`1+/```H``(FYE -MC@(`%@$`0`!Q86=A:6YS=,\!D6-OP,1<#4` -MT6%T979E -M`%`@(&)S9",'(75SO`$`/06#;B!I=',@(D#E`!(BO01&"2`L(E`(<"P@8V%P86)!``'V`@)F!A%E50(! -M\0!A92!!4$ESMP0(]@4!EP&Q(&EN9&EV:61U86QH!1%I0@@`>P`28D(``$X& -M`-$``#8!(71OFPDP9&%TUP!6=7)C93HN`0+("0#"`!)A[`(`R0H!*P`S:6X@ -M)P$`.`LS861DC@(88?<,`=<'(6]U]P119FER0"0:7,@97-P96-I;@0!T`$"J@$`.@@P.B`BDPH. -MV@T3(KD"(&QL/`$"Z`(`I0<`$0,"P040+&,`0&1E%EF-%#A)B!P`2>`<``$D!`)()`"<`4"H@ -M97AA20!`8$(&YDT`(Q9G5L -M+P(&10`0+T,*`84!$6&>"E%A8W0@'2(`")P==8-(")C-`81(B0#`#@,*6]L30`" -M5@$&ZP,!*0$`%@D`C@$/;0$!`+`,$'4]$P':`31E"B>P`"-E)ZT``#H/,"`J -M(),``$X`\``N86TL(&%C;&]C86PN;30)#0/M`#`N86/_```"`!`MH@(`GP`$ -MJ```V0X(H@02+!H.`-<+`%D+$'G*!0'V`2-EH($',+!0$^`0!U```7`@#Y!`%Q -M``%Q"@B7```\"3!Y+C/T%#!A:6SO!#)E(")K`P6K``$D`!0B"PM9(&-L87-$ -M``$?"49N86QSG0`2!Q(M@@0U=H+`#L'`2,)"=H1`,$"!;47`/<"`QP"!7@) -M$&8&$@&W!@*'&`:J"P@`&@#X%0]D&O______________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________95!T:&%T(&%96PM!$0``\2AY -M;W4@;6%Y(&9I;F0@=7-E9G5L+@H@("`J(&5X86UP;&5S+VUI;FET87(Z(&$@ -M8V]M<&%C="!S&P#@(&1E;6]NP#R*71H92!A=71H;W)S('=I=&@@ -M86YY('%U97-T:6]N'2(`#%P=70I -M`/D#(F-M86ME(B!B=6EL9"!T;V]L30`"5@$&-0$!*0$Q(&EN3`$/;0$!,&%R -M91`"$F3:`35E"B>\`!,GK0`#9P$`DP``3@#U`2YA;2P@86-L;V-A;"YM-"SA -M`$!E+F%C_P```@`2+50`)'1OJ```(`$P9&ES7P(0=4$!LBP@;VYL>2!N965D -M?``Q;6%I]@$C97)<`05P`"1I;F0`\@,N:"YI;@H)+2!T96UP;&%T97-G`!%B -M-`(!9@$39;4`8`H*1W5I9/,`DB!$;V-U;65N=($!`,4!,F%L;'4``/,!]0H@ -M'!L@P(#+P,`0@$"(0"#('!R;V=R86TS -M`$]C<&EO-``+`"(`##4`+V%T-``,*&%T,P`'K0/P!#,@9VEV97,@86X@;W9E -M2!A``"/`&<@)V1O8R>]!;!I;@IA(&YU;6)E2QN``5H`S!U=&^3!@#_`A!YP0(P96-TF0,19-4` -M`QP"!<(&$&8L``&W!E$J($=.574!`KH!)B`HN0$`&@!!;&]N9U4"8FYA;65S -M+!``4VQI;FL@$0``8P!A`@@;W#+`\!A;"!2;V-K -MB,``!DT%``)"`$```I58W)E873/``%U!`\&`0("J@,#OP,"O`(/ -M'P,8,")R9?X(46-T960B1P,"3P#$+"!W:&EC:"!W:6QLB@`!5@`%R@%A(&5X -M8V5P0`4`N04$:0+1('1H870@U`P#P!`![``.?`0![``&'"0&C``)*#`,*`P`X"`"R``$>`P"F!`(, -M`B$@8C<)`&H(,6%B;``&`(P*`0P``2P+`@0!`&@``CL`0F5A8V@]`2%V97,# -M$WE#`%!I;F1E<*H`)6YT(@$`&`D`#P\08T(%$F]L#08U"E0@5VEK:5(,,&EN -M9\D`,&AO=U$/`;,#%V26"@(J`2%/;C\(`/<,`F`&`P,!`_@``8@)4&%L=V%Y -M1@$`W0$J962*"`)'`'!))W9E(&%T+0T`C`<`P0^0:6YI;6EZ92!S#@T28U(( -M07!O;&R4#5$N("!)9O4(4&1O;B=TJ`"097AP;&EC:71LV0EB=F]K92!A^@\1 -M8W\*,69E830+,"AS=2\!!?L*`*D`("!A00`!)Q`"+0`(S0`4;_D(<"DL(&ET -M('=P`'$@9V5T('!UG`T0:7H+1R`@26YN`#``%1`0.;`")E;LD!!RT` -M`#X`"W$`*&1E$0`#Q@(1+/```H```(T.`)8!`!8!`$``(&%G`PX"4`.18V]R -M0`P&@`A!M -MV`$32X'<70@ -M82!T:6U7`W%O8!(71O(@`%2@!2 -M="!O;F-\$B)/;AP."\,``N0",G!R;SH!`84!46-T;'DMS`"2960@;W5T<'5T -M[P(`8`3Q`V]B:F5C="US='EL92!A<'!R;\@#`$,2`OH`X'1O(&AA=F4@;75L -M=&EP)0``(040=A(#0')E86VY"`#^#15NG@`3(!40`&H0``H!`#T%@VX@:71S -M(")`Y0`2(KT$$7,P#@)C!08!`6!I='-E;&93`0!]!!`O=@1@=&5N('5S;P8` -M-PP!<@$R9G5N6!($DP$!=08`,@`U(&%NI``"(Q-0;'D@9G)@``S0*%82!S;V-K970^`TEW:7-HN@0!)@\#60\` -M#B)A;N@"`*4'!C0*$"QC`$!D97-PWP``;`0!Y`,`7,N"B05$6:X#01Q%K0@8G5N9&QE+@H*41$6H#\@($ES2UB;&]C:V5D(&]U='!U="X*"B`J(%1H92!O8FIE8W0M`@#1```V`:!T;R!A;GD@9&%TUP!6=7)C93HN`5%CB!$!G8$(&YDT`(Q9G5L+P(&10!1+VUI;FF% -M`1%AXP%186-T('-@`+`@9&5M;VYS=')A=+P`"-E)ZT``R0$`),``$X` -M]0$N86TL(&%C;&]C86PN;30LX0!`92YA8_\```(`$"VB`@"?``2H``RB!+(L -M(&]N;'D@;F5E9'P`,6UA:?8!(V5RK@$%<``D:6YD`($N:"YI;@H)+?0'4FQA -M=&5S9P`18C0"`W(!`K4`8`H*1W5I9/,`*"!$5`8$T@$"=0``\P&`('-Y'!L@P(#+P,`0@$"(0`$F@,#,P``B`0/-``+`"(`##4` -M+V%T-``,*&%T,P`&`08A+C.V"Q!SWP:`;W9E``'<`%`D09BP``;<&42H@1TY5=0$"-0(F("@$"P`:`$%L -M;VYG50(`K0LB+``-J`0`9`]$J(%!/4TE8('5S=&%R6P`" -M$``/B@P#!R$`P&]C=&5T+6]R:65N=!<$('!IZ`S&*B!35E(T($%30TE)%``" -M4P`/,@`%84)I;F%R>2X`P"`H8FEG+65N9&EA;J(!8VQI='1L91$``OH`\0)) -M4T\Y-C8P($-$+5)/32!I;;<"$2AX""!O<,L#P&%L(%)O8VMR:61G944`8DIO -M;&EE="D!`>\!`DD`-%I)4'4$!$``('5N3@DPFEP,A8`!'P!32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9 -M-!0`"0@!```*`IP0!3H!`'4$#P8!`@*O`0._`P*\`@\?`Q@P(G)EH`U18W1E -M9")'`P)/`,0L('=H:6-H('=I;&R*``%6``:0`%%E>&-E<$`%`+D%!(D142!T -M:&%T0PX`TQ,`40`%Z1(P?P(-F5A;;4%`A$+!8@40&ES(&[6$C%R96,P$0/?"`"3 -M!$$@:6XM`@^"(&UO9&EF:6/E#/<`;W(@'!L:6-I=&S9"6)V;VME(&'Z -M#Q%C?PH#SA$@("C2$`!U#`@<`A!AL@$!)Q`"+0`(S0`4;W,$<"DL(&ET('=P -M`%`@9V5T(-(2`5T*`*0$-R!);FX`!287`9X``5$!`YL`(F5NR0$'+0``?``+ -M<0`H9&41``.J`!$L6!$"@```C0X`E@$`%@$`0``P86=A\P\!7PJ18V]R7L#$7`U`&)A=&5V97)X%Q%S\```[@FEP(&-O;7!R97-S:6]N%0!=8GII<#(6``0F`$TO3%I7 -M'0#_`VQZ;6$L(&QZ:7`L(&%N9"!X>B,``!DT%`#P#`I4:&4@;&EB2!C -M86X@8W)E871E(&%R8\\`\A)S(&EN(&%N>2!O9B!T:&4@9F]L;&]W:6YG(&9O -M&-E -M<'1_`/$*"B`@("!E;G1R:65S('1H870@.`?$#;F%M97,L($%#3',L(&5T8RDND@"P3VQD($=.52!T87)= -M``2I``+*`/$$;V-T970M;W)I96YT960@8W!I;S4`ME-64C0@(FYE=V,B%0`G -M`'@G;71R964GNP!X25-/.38V,!,` -M6CT!X'-Y -M`>-R86YD;VT@86-C97-S+GD`!I<`\@)I'!L86EN:6YGB0`P:&]W^``" -M]0``C@0#+``"*@$A3VZJ`!PL`P$#V0("<`!`;'=A>48!`-T!\@%E9"!A=71O -M;6%T:6-A;&QY1P"P22=V92!A='1E;7#$`^!T;R!M:6YI;6EZ92!S="L`L"!L -M:6YK('!O;&QUN`'A+B`@268@>6]U(&1O;B?L`0"V`/$":6-I=&QY(&EN=F]K -M92!A('#K`"!U;#<$(&5A60)`("AS=2\!&7,<`A!AZ0`'+0`'[P4`@`$"F0%P -M*2P@:70@=W``X"!G970@<'5L;&5D(&ENI`0W($EN;@`W+"!IG@`!40$#FP`B -M96[)`07L#$7`U`-%A=&5V97(@8FQO -M8VMS\``0:%<%(6ETH0!!66]U2X'<70@82!T:6U7`W%O8!(71O(@`%H0!A="!O;F-EA0`A3VZ0`QMEPP`"Y`(R<')O.@$!A0%18W1L -M>2W,``!(!E)U='!U=.\"`&`$\0-O8FIE8W0M2!F)M96UO?<"!8P``0`"\05R;W9I9&4@96%S>2UT -M;RUU8<``J,! -M!H`%,7=A;H@`$'0V!`5%`0!@``'Z"0".!R%S:RP#`WX&N6-O;G9E;FEE;F-E -MP`$`B0`P;6%K>0"0:7,@97-P96-I;@0!T`$"J@$`.@@P.B`BDPH.NPH3(KD" -M(&QL/`$"Z`(`I0<`$0,"P040+&,`0&1EP`"-E)ZT``V2XS30``[P0R92`B:P,%JP`!)``4(@L+62!C;&%S1``!'PE& -M;F%L``'?`5=H+`#L'`2,)"=H1`,$",&5C=)D#$61A#0,<`@>F%@`@ -M`@!0!0)!%0:J"R8@*`0+`%L5#"`6`1````4+`;X+$G,W`E)S<&%R\6`2T5 -M`A``#XH,`P%V,/"Q<`T$UI8W)O`"" -M(&EN'!L86EN3`1!F+``P -M'1E;J+``-J`0`9`]$J(%!/4TE8('5S=&%R6P`"$``P<&%X20-Q97)C -M:&%N9WX!-VUA="$`L&]C=&5T+6]R:65N`0,`8`(!'@"A4U92-"!!4T-)270" -M`10``E,`#S(`!6%":6YAFEP,A8`!'P!32],6E<=`*)L>FUA+"!L -M>FEP$P,O>'HC```9-!0`"0@!E6-A;B!C0`&@`0`#@Q397-I9VXE#!)EO@(`0`0! -M,`0X;F5WM0,`\`0`>P`#GP$`>P`!APD!HP`"2@P#"@,`.`@`L@`!'@,`I@0" -M#`(A(&(W"7%R96%D86)L``8`C`H!#``!+`L"!`$`:``".P!"96%C:#T!(79E -M4,`4&EN9&5PJ@`E;G0B`0`8"5!AD`!RT`!"T'`,\*%&_Y"'`I+"!I="!W<`!Q -M(&=E="!P=9P-(&ENI`0W($EN;@`W+"!IG@`(FP`B96[)`02UV -M```S#`#W"!%IAP8`A`!P96YV:7)O;M<",7,@=Y`#`:`"$&W8`1-R6@,%,`(` -M6P`"?P`1>7L#$7`U`-%A=&5V97(@8FQO8VMS\```[@@``S0*%82!S;V-K970^`TEW:7-HN@0!)@\#60\`4X.475S92`B(0$`6@@@+")0"+$L(&-A<&%B:6QI=/8"!`,!!?$``O,/`;<$ -M"/8%`9P"`,D*`2L`,VEN("#U%F:7)S=)("`*8!(&$@0P41;UD1`/8`%BYT``/9`P*G`0"_``*< -M`0&%``:X`0!V``##``"\`Q)EDP`",0\@;'ED`0#,``"C`0:`!3%W86Y_!1)T -M'0\!-@(!6P,!&@00=(X'(7-K+`,0A$)P`$`B0`P;6%K -M>0"0:7,@97-P96-I;@0!T`$"J@$`.@@P.B`BDPH!#A$)V@T3(KD"`-X.(F%N -MZ`(`I0<&-`H0+&,`0&1EF-%#A)B!P`2>`<` -M`$D!`)()`"<`02H@97@;$T!S.B!3,@-4^&G/#D1 -M``#P=2`@(&$@8FQO8VL@;V8@9&%T82!I;B!M96UO2!F:6QE+B`@66]U(&-A;B!A;'-O(')E860@86X@96YT6]U('=A;G1$`!)T70`2+ST``&``,&EE'1E;F1E9#@!`B(`$"QC`$!D97-PWP!`=VAA=)8`\`,@ -M;F%M92!S87ES+@I214%$3450`$0@;&EB;0'18G5N9&QE+@H*475E`<``$D! -M0'-U8V@G`%`J(&5X84D`0',Z(%,R`U1S;6%L;!4`!#X!`%(#(6%T?`0@;6'F -M!"!N9-`",69U;"\"!D4`42]M:6YIA0$18>,!46%C="!S8`"P(&1E;6]N2#R`@`!!5`N"@I4:)T!,'`M;`P$`W8%``D&`4$`$&DD!0FV`B)I -M;M8$,6EO;NL%!+T"\`).15=3("T@:&EG:&QI9VAT'2(`#!P=71>`C`@(F,T!A$B)`-I9"!T;V]L30`"5@$&ZP,!*0$`90<`C@$/ -M;0$!`*(&0G5S963:`35E"B>\`!,GK0`#)`0`DP``3@#U`2YA;2P@86-L;V-A -M;"YM-"SA`$!E+F%C_P```@`0+:("`)\`!*@`#*($LBP@;VYL>2!N965D?``Q -M;6%I]@$C97*N`05P`"1I;F0`@2YH+FEN"@DM]`=2;&%T97-G`!%B-`(!9@$3 -M9;4`8`H*1W5I9/,`*"!$5`8$T@$"=0`!MP%P!1%E^P,`\@"`;6%T]!;!I;@IA(&YU;6)E2X`P"`H8FEG+65N9&EA;J(!8VQI='1L91$``OH` -M\0))4T\Y-C8P($-$+5)/32!I;;<"$"@X#C`@;W#+`\!A;"!2;V-KFEP/@$Q:6]N!0%=8GII<#(6``1\`4TO3%I7'0"B;'IM82P@;'II4,` -M4&EN9&5PJ@`E;G0B`0!$#0`/#Q!C0@42;VP-!C4*5"!7:6MI4@P##!,P:&]W -M^``!LP,09*T!`]H``BH!(4]N/P@`]PP"8`8`\PX`4`8#S0`!<`!3;'=A>7-S -M""IE9(H(`D<`<$DG=F4@870M#0",!S!T;R`A$'!M:7IE('-TM0@"4@A!<&]L -M;#82!N04061O;B?L`7!E>'!L:6-I#16":6YV;VME(&'Z#Q%C?PH#SA$@("C2 -M$"4@8?L*`*$!("!AL@$!)Q`"+0`(S0`4;W,$<"DL(&ET('=P`%`@9V5T(-(2 -M`5T*`*0$-R!);FX`,BP@:8(5`9X``5$!`YL`(F5NR0$'+0``?``+<0`H9&41 -M``/&`A$LY0D"@```C0X`E@$`%@$`0``P86=A\P\!7PJ18V]R"(&5N=FER;VX/"Q%WD`,!H`(0;=@!$W):`P4P`@!; -M``)_`!%Y>P,1<#4`8F%T979E:89`@4.%CHN`0+("0`]``]D&O______________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________9U`@87)C -M:+!C1.Q"$0``\0)I=F5S"B`@*B!805(@87)C:!$`Y0I7:&5N(&-R96%T:6YG -M&`#Q&2P@=&AE(')EFUA+"!L>FEP+"!A;F0@>'HC`,$*3F]T -M97,@86)O=724`')L:6)R87)YT0#P+G1E8W1U2!S=')E86TM;W)I96YT960@P`#MP$`>P!";6%T2!R97%U:7)E;65N -M=+(`,G1H80D!`BL`("!BCP&0(')E861A8FQEH@!!=W)I=`P`$&$,`0($`0!H -M``([`$)E86-H/0&#=F4@96YT$N("!)9B!Y;W4@9&]N)^P!`+8`\0)I8VET;'D@:6YV;VME(&$@<.L`@'5L -M87(@9F5A60)`("AS=2\!&7,<`A!AZ0`'+0`'!@,`@`$"F0%P*2P@:70@=W`` -M\``@9V5T('!U;&QE9"!I;BX^`"=);FX`-RP@:9X``5$!`YL`(F5NR0$'+0`` -M/@`+<0`H9&41``/&`A$L\``"@``B;F6.`@`6`0!``&)A9V%I;G-'`J!C;W)R -M97-P;VYD)P0(20`-6@`">P,Q:65SPP`!;P.P86QS;R!R961U8V6;`C!E('.% -M`2-O9H@!`+,!$"UV`&%E9"!B:6X]`"`@:2P$@"!E;G9IP,1<#4`T6%T979E8!(71O -M(@`%2@!A="!O;F-EA0`A3VZ0`QMEPP`"Y`(R<')O.@$!A0%18W1L>2W,`))E -M9"!O=71P=73O`@!@!/$#;V)J96-T+7-T>6QE(&%P<')OR`,`H`4"^@#@=&\@ -M:&%V92!M=6QT:7`E``-3!`(!!``B!E4@;W!E;IX`L2`@8G-D=&%R('5SO`$` -M/06#;B!I=',@(D#E`!(BR`-&P"`*`'`2L`,VEN("8<``J,!!H`% -M,7=A;H@`$'0V!`5%`0!@`!!IA0(`C@%EB!$!G&%)`$!S.B!3,@-4`0-)`#!C;VY#`O`".B`@5F%R:6]UP``7P%V -M875T:&]R,&`4D!A69I9W5R92`M#``" -M1`"U'2(`")P -M==8-(")C-`81(B0#`#@,*6]L30`"5@$&ZP,!*0$`%@D`C@$/;0$!`*(&('5S -MW0H`V@$T90HGL``C92>M``,D!`"3``!.`/``+F%M+"!A8VQO8V%L+FTT"0T# -M[0`P+F%C%P$``@`0+:("`)\`!*@``-D."*($$BP:#@#7"P)\`#%M86GV`2-E -MPH"MP(29:`,`!(&0'-E<77J"!!S"P4! -M/@$`=0``%P(`^00!<0`!<0H(EP``/`DS>2XS30``[P0R92`B:P,%JP`!)``4 -M(@L+62!C;&%S1``!'PE&;F%L]!9!I;@IA(&YU;6+R#!=FD0<$.P''"@I9;W4@2X`L2`H8FEG+65N9&EAU!%C;&ET=&QE$0`"^@#Q`DE33SDV-C`@0T0M -M4D]-(&EMMP(0*#@.,"!O<,L#P&%L(%)O8VMR:61G9>\! -M`DD`-%I)4'4$!$``('5N,0L`)18`UA!@"T4``("`+D%!(D1`@L7`UH7 -M`5$`!>D2,',@*%,*`30$`(0!`S,$`/0#8"P@971C*>\+`OH#`*D"`&T``HT` -M`9L!`MH`#\@#"F$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0%!`?.``]9`P`* -M%@,/9!K_____________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_____________U-0("!I;G0:SA?#3!$``/,[97)N86P@4P`T&-P:6\N -M-2P@;71R964)``!O`/(*=&%R+C4@<')O=FED92!D971A:6QE9"!I;E(`D&EO -M;B!A8F]U=$T`XW-E"B`@('!O<'5L87(@F``2("D`\PIS+"!I;F-L=61I;F<@ -M:&%R9"UT;RUF:6YD5``2FEP/@$Q -M:6]N,`!=8GII<#(6``1\`4TO3%I7'0"B;'IM82P@;'II&-E<$`%`+D%!&D" -ML"!T:&%T(')E<75IE@4G87C*`E(@*&9O?P(-F5A;;4%X'-Y`3AN97>U`P#P!`![``-S!`![``&'"0&C`%0@;VYL>0H#`#@(`+(``1X# -M`*8$`@P"(2!B-PEQ4,`4&EN9&5PJ@`E;G0B`0`8"5!A48!`-T!*F5DB@@"1P"P22=V92!A='1E;7",!^!T;R!M -M:6YI;6EZ92!S=+4(`E((4'!O;&QU(@=1+B`@26;U"%!D;VXG=*@``+8`4&EC -M:71LV0F!=F]K92!A('#K``%_"C%F96$T"S`H -M``%1`0.;`")E;LD!!RT``'P`"W$`*&1E$0`#Q@(1+/```H``(FYEC@(`%@$` -M0`!B86=A:6YS1P*18V]R0`P&@`A!MV`$38!(71O(@`%H0!A="!O;F-EA0`A3VZ0`QMEPP`"Y`(R<')O.@$!A0%18W1L -M>2W,``"."5)U='!U=.\"`&`$\0-O8FIE8W0M7,"!8P``#\`!)4.0&5AP"`,D*`2L`,VEN("#U%F:7)S -M=)("`*8!(&$@0P41;U`'`/8`%BYT``/9`P*G`0"_``*<`0&%``:X`0!V``## -M``"\`Q)EDP`",0\@;'ED`0#,``"C`0:`!3%W86Y_!1)T'0\!-@(!6P,`8PP` -M,P!!9&ES:RP#`+$0$'*?!)EN=F5N:65N8V7``0")`#!M86MY`)!I0#`',*T2!S87ES+@I214%$3442!@<4!]%B=6YD;&4N -M"@I1=65S^@*@/R`@27-S=65S/U(`UBH@:'1T<#HO+W=W=RXX`$`N;W)GDP`` -M2`$0:+@"$&:Q#S-N9V]8!Q<@3`>`(&1E=F5L;W`\!0@9$02Z$0&L"`$W#`!Q -M```Z`"%N:UT!`%T`!G,`4"!M86EL!P(P;&ESOQ`!G0`05)D!`.41`.%E8$(&YDT`(Q -M9G5L+P(&10`0+T,*`84!$6&>"C1A8W1[$W!D96UO;G-T.14@;F<^``"`!094 -M`@-)`#!C;VY#`F$Z("!687+N$V!I=&5M -M$0(8`&!C;VYF:6>R%A4M#``"1`"UM`Q$SM@L`$!20(&]V97)V:65W\P(`JP`%P`L`<04P=VAOD0(4 -M*J0*A5]R96%D+C,L$``!^`@-$0!17V1I2!F;W(@:L`D'-A;64@ -M9G5N8S`<``$D!0'-U8V@G`%`J(&5X84D`U',Z(%-O;64@ -M6]U(&UA>2!F:6YD('5S969U;"\"!D4`42]M -M:6YIA0$18>,!46%C="!S8`"A(&1E;6]N2#R`I!I;VYS -M+@H*5&B=`?("<"UL979E;"!D:7)E8W1O%#36%K94QI -M\`!,GK0`#)`0`DP``3@#U`2YA;2P@ -M86-L;V-A;"YM-"SA`$!E+F%C_P```@`2+50`)'1OJ``,H@2R+"!O;FQY(&YE -M961\`#%M86GV`2-E7-T96TZ"B`J(+@$=2XQ(&5X<&R#`@,O`P!"`0(A``2:`P,S``"(!`\T``L` -M(@`,-0`O870T``PH870S``;V!8`N,R!G:79E2XS30`"]P,2(FL#!:L``20`4"(@=71I -MI`59(&-L87-$``'O!49N86QSG0`P`D09BP``;<&42H@1TY5=0$"-0(B("BK"0"Y`0`:`$%L;VYG -M4`9B;F%M97,L$`!3;&EN:R`1``!C`%)S<&%R'1E;J+``-J`0`9`]$J(%!/4TE8('5S -M=&%R6P`"$``R<&%X-`,"60<#>`('(0"P;V-T970M;W)I96X!`P!@`@$>`*%3 -M5E(T($%30TE)=`(!%``"4P`/,@`%84)I;F%R>2X`P"`H8FEG+65N9&EA;J(! -M8VQI='1L91$``OH`\0))4T\Y-C8P($-$+5)/32!I;;<"$2AX""!O<,L#P&%L -M(%)O8VMR:61G944`8DIO;&EE="D!`>\!`DD`-%I)4%8#!$``('5N,0LPFEP,A8`!'P!32],6E<=`*)L>FUA -M+"!L>FEP$P,O>'HC```9-!0`"0@!```*56-R96%TSP`!=00/!@$"`JH#`[\# -M`KP"#Q\#&#`B&-E<$`%`+D%!&D"42!T:&%T0PXQ:7)E40`!\P,!R@(@("@6!0$T!`"$ -M`0,S!`#T`V`L(&5T8REF"@+Z`P"I`@8B!`&&`0+:``^6`P4!R`-A(FYE=V,B -MFP,!,P`GD#`*4#(71EVP@P.@H*N!`R:&ESD0]P:&5A=FEL>?P(-F5A;;4% -M`A$+@"X@(%1H97)E+``C;F_B!P""`@/?"`"3!$$@:6XMMP^"(&UO9&EF:6-D -M"_``;W(@0`&EP``L!!397-I9VXE#!)EB`4`0`0! -M7@$X;F5WM0,`\`0`>P`#GP$`>P`!APD!HP`"2@P`31$B:7*"$1!I>0<280D! -M`@P"(2!B-PD`C`HQ86)L``8`_0H!#``!+`L"U!``:``".P!"96%C:#T!(79E -M4,`4&EN9&5PJ@`E;G0B`0`8"0`/#Q!C0@42;VP-!C4*5"!7:6MI4@PP -M:6YGR0`P:&]W40\!LP,09$X(`]H``BH!(4]N/P@`]PP"8`8`TQ$`4`8#S0`! -M<`!3;'=A>7-S""IE9(H(`D<`<$DG=F4@870M#0",!S!T;R`A$+)M:7IE('-T -M871I8U((07!O;&PV$E$N("!)9O4(061O;B?G$I!E>'!L:6-I=&S9"4!V;VME -MO!(!ZP`!?PH#SA$@("C2$"4@8?L*`*$!("!AZ0`!)Q`"+0`(S0`4;_D(<"DL -M(&ET('=P`$$@9V5T&1,!70H`I`0W($EN;@`W+"!IG@`!40$#FP`B96[)`07L#$7`U`-%A=&5V97(@8FQO8VMS\```[@2X'<70@82!T:6U7 -M`W%O8!(71O(@`%2@``XQ,A8V6% -M`"%/;I`#&V7#``+D`C)P`!,@%1``:A``"@$`/06#;B!I=',@(D`\`!(BO001 -M2!F4X.``P1$2(A`0!:""`L(E`(H"P@8V%P86)I;&D2%`8#`07Q``+S -M#P$_#@CV!0&7`8`@:6YD:79I9&P.`]L(`(4``#H2`D(``*P+`-$``#8!(71O -MK`TP9&%TUP``!0X6.BX!`L@)`#T`$F'L`@#)"@$K`#-I;B`G`0!%!3-A9&2. -M`AAA]PP!J0H#'@]19FER41`.7,@9&5T96-T960@875T;VUA=&EC86QL>2X*"B`J($DG=F4@871T96UP=&5D -M('1O(&UI;FEM:7IE('-T871I8R!L:6YK('!O;&QU=&EO;BX@($EF('EO=2!D -M;VXG=`H@("!E>'!L:6-I=&QY(&EN=F]K92!A('!A``B;`%IE;F%B;)L` -M`#X`"W$`*&1E$0`#J@`1+/```H``(FYE)@$`%@$`0`#Y"F%G86EN8`0U:`)%L:6)R87)I97/#`/$"5&AI2W,`))E9"!O=71P=70&`>!4:&4@;V)J -M96-T+7-T>1`"TG!P`+$@(&)S9'1A2!B=69F97(@;W+!``!E``1R`85A('-O8VME=#X#4'=I2UT;RUUX`0!V``*4`0```P&3 -M``7+`0#3``.C`0:`!3%W86Z(`!!T-@0#-@(!6P,`'P$`N@!!9&ES:RP#`\0! -MN6-O;G9E;FEE;F-EP`$`B0`P;6%K>0"0:7,@97-P96-I;@0!T`$"J@'S!TYO -M=&4Z(")P87@@:6YT97)C:&%N9V6?!1,BN0(@;&P\`0+H`A!DO@$48<$%$"QC -M`$!D97-PH@``;`0!!@3P`FYA;64@H&0&%N(&FW`!`L(00!_``!#P"A('1R86-K97(@8`<``$D!0'-U8V@G`%`J -M(&5X84D`0',Z(%,R`U1S;6%L;!4`!#X!`%(#(6%T'`@@;6'F!"!N9-`",69U -M;"\"!D4`$"]#"@&%`1%A!@E186-T('-@`+`@9&5M;VYS=')A=+P`"-E)ZT` -M`V7-T96TZ&@D"N`0A+C'!#`!A#`$W`0,O`P`+``(A``2:`P,S``"( -M!`\T``L`(@`,-0`O870T``PH870S``8!!B$N,[8+$'-E"H!O=F5R=FEE=_," -M`*``!0H,`'$%,'=H;Y$"%"JD"H5?PH"MP(29:`,`%L$$'/4!A!N2PT`U@(`DP``=0`` -M%P(`^00!<0`!<0H(EP`!G`DC+C--``#O!#)E(")K`P6K``$D`!0B"PM9(&-L -M87-$``$?"49N86QSG0`2P$2+8($-7,N-:H(`J\``!D#`)\#-6UA=&D/!&,"!98! -M`+````H"D"XU+"!M=')E90D``&\`7G1A]!9!I;@IA(&YU;6+R#!=FD0<#HP#7+@H*66]U('-H;W5L9*0+`"@!,6-O -M<'8&0&-O;6V>"`#.#1,BR0TR+F@BJ0`R:&4*7PP0(+`)`'4!`!0`!.D&`W(( -M`G\"-&UO\!`DD` -M-%I)4'4$!$``('5N,0L`[!,`UA!@"T4``("`+D%!(D1`FL4`$,.`-,3`%$`!>D2 -M,',@*'T'`30$`(0!`S,$`/0#8"P@971C*>\+`OH#`*D"`&@1`HT``9L!`MH` -M#\@#"F$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0%!`?.``]9`P`*%@,S5VAE -M`P(`OP@#U`(2<^8%87)E`3AN97>U -M`P#P!`#]`@.?`0![``&'"0$K%0)*#`,*`P`X"`#>`!1T[A("#`(A(&(W"0", -M"@&/&`.X%`$,`!!A#`$"U!``:``".P`199P6`#T!(79E4,`4&EN9&5P -MJ@`E;G0B`0!$#5!A'1E;F1E9"!T87(@9F]R;6%T("AI;F-L=61I;F<@04-, -M,P!A3VQD(%8W)P"!87)C:&EV97-+`+=03U-)6"!U"=M=')E92<]`5HW+5II<"8`V$UI8W)O2!A;'-O(&1E=&5C='--`&!H86YD -M;&4,`'!Y(&]F('1HW`'P!VQL;W=I;F<@8F5F;W)E(&5V86QU8702```@``,O -M`A$ZU`!@=75E;F-O<0(!CP(!%``!"@`1((,!HE)032!WFEP -M/@$Q:6]N,`!=8GII<#(6``1D`4TO3%I7'0"B;'IM82P@;'IIP`!S@`0 -M=IL$`-$&$G.C`%0@;VYL>0H#0&UE;G2R``$>`P"F!`(K`#`@8F5``'%R96%D -M86)L``9!=W)I=`P`$&$,`0($`0!H``([`$)E86-H/0$A=F5S`Q-Y0P!0:6YD -M97"J`")N='\`$'([!``$`#!T:6-"!21O;H$!!*X`\`!7:6MI(&5X<&QA:6YI -M;F>)`#!H;W?X``&S`Q!DE@4#+``"*@$A3VZJ`!PL`P$`!`0R;6%T<`!`;'=A -M>48!`-T!\@%E9"!A=71O;6%T:6-A;&QY1P"P22=V92!A='1E;7",!^!T;R!M -M:6YI;6EZ92!S="L`L"!L:6YK('!O;&QUN`'A+B`@268@>6]U(&1O;B?L`0"V -M`/$":6-I=&QY(&EN=F]K92!A('#K`"!U;%D(H&5A='5R92`HD`!RT`!$4'`R("`ID!<"DL(&ET('=P`.`@9V5T('!U;&QE9"!I;J0$-R!) -M;FX`-RP@:9X``5$!`YL`(F5NR0$'+0``?``+<0`H9&41``.J`!$L\``"@``B -M;F6.`@`6`0!``'%A9V%I;G-TSP&18V]RP,Q:65S -MPP`!;P,!;P=16QE -M(&%P<')OR`,`R0@"^@#@=&\@:&%V92!M=6QT:7`E``-3!`(!!`#\"E4@;W!E -M;IX`4"`@8G-D(P2!F)M96UO7,"!8P``0`"\05R;W9I -M9&4@96%S>2UT;RUU0#`',* -MT"!S87ES+@I214%$346[!@?H!N$@8G5N9&QE+@H*475E<_H"H#\@($ES7!1`GH@1`9W)A;18"&%)`$!S.B!3,@-4 -M`0-)`#!C;VY#`O`".B`@5F%R:6]UP``7P%Q875T:&]R<\`%`1\&`?("`-(1$B[M -M#U!T;W`M;`P$`\4,`#`'`4$`$&GD!@FV`B)I;M8$`*0*`.L%!+T"\`).15=3 -M("T@:&EG:&QI9VATPH"MP(`318A86R)!T!S97%UZ@@0=&%R+C54`0CQ!`4^$A%SU@TQ<&]PY0\# -MG`$$>P`(2PE`:&%R9!8,`3`&`J@!`X42`(X!86UO9&5R;H\``.@!`+P'<"!V -M87)I86Y("0`B##!M86[X"Q%PK1] -M!;!I;@IA(&YU;6)E"`"X!!,BXP`R+F@BJ0`R:&4*7PP0(+`)`/H``!0`!.D&`W((`G\" -M$&T:%P/[`$(N("!0B@FR;&5T('5S"FMN;W<0`0&9!F!E`D09@82`;<&`H<8!JH+"``:`/@5#"`6`1````4+#V0:________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M__________________________________________________]H4"`J(&5X -M7K0(.D01``#Q#&%M<&QEP#R*71H92!A=71H;W)S('=I=&@@86YY('%U97-T:6]N -M%#36%K94QIM``-G`0"3``!.`/4!+F%M+"!A8VQO8V%L+FTT+.$`0&4N86/_```"`!(M -M5``D=&^H```@`3!D:7-?`A!U00&R+"!O;FQY(&YE961\`#%M86GV`2-E7-T96TZ"B`J(&)S -M9'1AM`_`$,R!G:79E2XS!`,!JP(2(FL#!:L` -M`20`Z2(@=71I;&ET>2!C;&%S1`"6:6YT97)N86QSG0!@P$2+8($ -M4W,N-2!D5@(#I@0@:6QV`]1R;6%T-50!"/$$4&%B;W5T&@$@P"`+"!I;F-L=62*`<5H87)D+71O+69I;F1;`0%'``!!`&%M;V1E$D#(F5R60<# -M>`('(0"P;V-T970M;W)I96X!`P!@`@$>`*%35E(T($%30TE)=`(!%``"4P`/ -M,@`%,$)I;LH$`$(`H"`H8FEG+65N9&GS!(-R(&QI='1L91$``OH`\0))4T\Y -M-C8P($-$+5)/32!I;;<"$2AX""!O<,L#P&%L(%)O8VMR:61G944`8DIO;&EE -M="D!`>\!`DD`-%I)4%8#!$``('5N3@DPFEP/@$Q -M:6]N&`%=8GII<#(6``1\`4TO3%I7'0"B;'IM82P@;'IID#`*4#(71EVPC` -M.@H*("H@5&AI?P(-F5A;;4%`A$+@"X@(%1H97)E+``C -M;F_B!P""`@/?"`"3!/("(&EN+7!L86-E(&UO9&EF:6-D"_``;W(@0`&EP"3:7,@9&5S:6=N)0P298@%`$`$`;,%.&YE=[4#`/`$ -M`'L``Y\!`'L``8<)`:,``DH,`PH#`#@(`+(``1X#``D!`@P"(2!B-PD`:@@Q -M86)L``8`C`H!#``!+`L"!`$`:``".P!"96%C:#T!(79E4,`4&EN9&5P -MJ@`E;G0B`0`8"0`/#Q!C0@42;VP-!C4*5"!7:6MI4@PP:6YGR0!C:&]W('1O -M]0`'E@H"*@$A3VX_"`#W#`)@!@,#`0/X``&("5!A;'=A>48!`-T!*F5DB@@" -M1P!P22=V92!A="T-`(P'`,$/D&EN:6UI>F4@@M'("!);FX`-RP@:9X``5$!`YL`(F5NR0$'+0``/@`+<0`H9&41 -M``/&`A$L\``"@```C0X`E@$`%@$`0``@86<##@)'`I%C;W)R97-P;VY<"PA) -M``&]#P@1``)[`R)I92UV -M```S#`#W"!%IM`\`A`!P96YV:7)O;M<",7,@=Y`#`:`"$&W8`1-R6@,%,`(` -M6P`"?P`1>7L#$7`U`-%A=&5V97(@8FQO8VMS\```[@2W,`))E9"!O=71P=73O`@!@!/$#;V)J -M96-T+7-T>6QE(&%P<')OR`,`0Q("^@#@=&\@:&%V92!M=6QT:7`E```A!1!V -M$@-``!,@%1``:A``"@$`/06#;B!I=',@(D#E`!(BR`,1 -M2!F4X.``P1$2(A`0!:""`L(E`(H"P@8V%P86)I;&D2%`8#`0"_``'Q -M``+S#P&W!`CV!0&7`8`@:6YD:79I9&P.`]L(`(4``#H2`D(``*P+`-$``#8! -M(71OK`TP9&%TUP``!0X1.L$"`2X!`L@)`#T`$F'L`@#)"@$K`#-I;B`G`0"/ -M`C-A9&2.`AAA]PP!UP<#'@]19FERA$) -MP`$`B0``,!0"@1-@97-P96-I;@0!T`$"J@$`.@@P.B`BDPH!#A$)V@T3(KD" -M`-X.(F%NZ`(`I0<&-`H0+&,`0&1EA<"+```.P``!`,`2P+%1`G-Q,`C!4`%@)S82!F=6QL+98(2!A="!O;F-E -M+@H@("!/;B!W7,@<')O9'5C97,@8V]R6]U('1O(&AA=F4@;75L=&EP)0`#J0!P -M`/,-("!B!E('-O;64@=71I;&ET>3X`!8P``+$!\09P2!D8737`%9U0(1.FH`$B>7!1`G'@9`9W)A;18"\`9A(&9U;&PM -M9F5A='5R960@)W1A`<``$D!0'-U8V@G`%`J(&5X84D`0',Z(%,R`U1S -M;6%L;!4`!#X!`%(#(6%T(`8@;6'F!"!N9-`",69U;"\"!D4`42]M:6YIA0$1 -M8>,!46%C="!S8`"P(&1E;6]NM``,D!`"3``!.`/4! -M+F%M+"!A8VQO8V%L+FTT+.$`0&4N86/_```"`!`MH@(`GP`$J``,H@2R+"!O -M;FQY(&YE961\`#%M86GV`2-E7-T96TZ -MIPH"N`1U+C$@97AP;(,"`R\#`$(!`B$`!)H#`S,``(@$#S0`"P`B``PU`"]A -M=#0`#"AA=#,`!@$&(2XSM@L0<]\&@&]V97)V:65W\P(`H``%P`L`<04P=VAO -MD0(4*J0*A5]R96%D+C,L$``!^`@-$0!17V1IP$2+8($-7,N-:H(`J\``!D#`)\#@&UA=',@=&%R+C54`0CQ!$%A8F]U4P41] -M!9!I;@IA(&YU;6+R#!=FD0<#HP#7+@H*66]U('-H;W5L9*0+`$P`,6-O<'8& -M0&-O;6V>"`#.#1,B!0XR+F@BJ0`R:&4*7PP0(+`)`'4!`!0`!.D&`W((`G\" -M-&UO@,QBH@4U92-"!!4T-)210``E,` -M#S(`!6%":6YA`@@;W#+`\!A;"!2;V-K[`@0]`5HW+5II -M<"8`V$UI8W)OFEP/@$Q -M:6]N&`%=8GII<#(6``1\`4TO3%I7'0"B;'IM82P@;'IID2,',@*'T'`30$`(0!`S,$`/0#8"P@971C*>\+`OH#`*D" -M`&@1`HT``88!`MH`#Y8#!0'(`V$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0% -M!`?.``]9`P`*%@,S5VAE`P(`-0<#U`(2<^8%87)E`3AN97>U`P#P!`#]`@.?`0![``&'"0$K%0)*#`!-$2)IP,1<#4`8F%T979E*B!F:6QEFEP(&-O;7!R97-S:6]N%0!=8GII<#(6``0F`$TO3%I7'0#_`VQZ;6$L -M(&QZ:7`L(&%N9"!X>B,``!DT%`#Q,@I4:&4@;&EB2!C86X@8W)E871E -M(&%R8VAI=F5S(&EN(&%N>2!O9B!T:&4@9F]L;&]W:6YG(&9O"!I;G1E'1E;DT!L7,@*&9O$E33SDV-C`3`%HW+5II<#D` -M-EA!4A$`0PI7:&4#`@#D`00%`A$L_`%AT!X'-Y`>-R86YD;VT@86-C97-S+GD`!I<`\@)I`35N97<7`@!2`#!A;F1[``'.`!1V6`,24,`4&EN9&5PJ@`B;G1_`!!R.P0`!``P -M=&EC\`0D;VZ!`02N`/``5VEK:2!E>'!L86EN:6YGR0`P:&]W^``"]0``C@0# -M+``"*@$A3VZJ`!PL`P$#V0("<`!`;'=A>48!`-T!\@%E9"!A=71O;6%T:6-A -M;&QY1P"P22=V92!A='1E;7#$`^!T;R!M:6YI;6EZ92!S="L`L"!L:6YK('!O -M;&QUN`'A+B`@268@>6]U(&1O;B?L`0"V`/$":6-I=&QY(&EN=F]K92!A('#K -M`"!U;#<$(&5A60)`("AS=2\!&7,<`A!AZ0`'+0`'[P4`@`$"F0%P*2P@:70@ -M=W``X"!G970@<'5L;&5D(&ENI`0W($EN;@`W+"!IG@`!40$#FP`B96[)`07L#$7`U`-%A=&5V97(@8FQO8VMS\``0 -M:%<%(6ETH0!!66]U2X'<70@82!T:6U7`W%O8!(71O -M(@`%H0!A="!O;F-EA0`A3VZ0`QMEPP`"Y`(R<')O.@$!A0%18W1L>2W,``!( -M!E)U='!U=.\"`&`$\0-O8FIE8W0M2!F -M)M96UO?\`!8P``0`"\05R;W9I9&4@96%S>2UT;RUU8<``J,!!H`%,7=A -M;H@`$'0V!`5%`0!@``'Z"0".!R%S:RP#`WX&N6-O;G9E;FEE;F-EP`$`B0`P -M;6%K>0"0:7,@97-P96-I;@0!T`$"J@$`.@@P.B`BDPH.NPH3(KD"(&QL/`$" -MZ`(`I0<`$0,"P040+&,`0&1EH($',+!0$^`0!U```7`@#Y!`%Q``%Q"@B7 -M```\"3-Y+C--``#O!#)E(")K`P6K``$D`!0B"PM9(&-L87-$``$?"49N86QS -MG0`2!Q(M@@0U"`"X!!,B -M!0XR+F@BJ0`R:&4*7PP0(+`)`/H``!0`!.D&`W((`G\"-&UO5$P"9!F!E2X`L2`H8FEG+65N9&EAU!%C -M;&ET=&QE$0`"QP`$7Q:10T0M4D]-(&EMMP(0*#@.,"!O<,L#P&%L(%)O8VMR -M:61G9>\!`DD`#QX78P\+%P#036EC2!M86EN=&%I;F5R`""(&EN7-T96TZ"B`J(&)S -M9'1A3`1!F+``P'1E;J+``-J`0`9`]$J(%!/4TE8('5S -M=&%R6P`"$``P<&%X20-Q97)C:&%N9WX!-VUA="$`L&]C=&5T+6]R:65N`0,` -M8`(!'@"A4U92-"!!4T-)270"`10``E,`#S(`!6%":6YAFEP,A8` -M!'P!32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9-!0`"0@!E6-A;B!C,H"("`H?0U`P#P!`![``.?`0![``&' -M"0&C``)*#`,*`P`X"`"R``$>`P"F!`(,`B$@8C<)<7)E861A8FP`!@","@$, -M``$L"P($`0!H``([`$)E86-H/0$A=F5S`Q-Y0P!0:6YD97"J`"5N="(!`!@) -M4&%R=&EC0@4D;VZ!`02N`$17:6MI4@PP:6YGR0`P:&]W^``"I@<'E@H"*@$A -M3VX_"`#W#`)X!@$""B-N9/@``8@)4&%L=V%Y1@$`W0$J962*"`)'`'!))W9E -M(&%T+0T`C`?0=&\@;6EN:6UI>F4@``B;`")E;LD!!RT``'P`"W$`*&1E$0`#Q@(1+/```H`` -M`(T.`)8!`!8!`$``(&%G`PX"1P*18V]RP,1<#4` -MT6%T979E2W,``"."5)U='!U=.\"`&`$\0-O8FIE8W0MP"`,D*`2L`,VEN("#U%F:7)S=)(" -M`*8!(&$@0P41;UD1`/8`%BYT``/9`P*G`0"_``*<`0&%``:X`0!V``##``"\ -M`Q)EDP`",0\@;'ED`0#,``"C`0:`!3%W86Y_!1)T'0\!-@(!6P,!&@00=(X' -M(7-K+`,0A$)P`$`B0`P;6%K>0"0:7,@97-P96-I;@0! -MT`$"J@$`.@@P.B`BDPH!#A$)V@T3(KD"`-X.(F%NZ`(`I0<&-`H0+&,`0&1E -M8$(&YDT`(Q -M9G5L+P(&10`0+T,*`84!$6&A"S1A8W1[$W!D96UO;G-T.14@;F<^``"`!094 -M`@-)`#!C;VY#`F$Z("!687+N$V!I=&5MP``7P%Q875T:&]R<\`%`1\&`?("`,$3$B[M#U!T -M;W`M;`P$`\4,`#`'`4$`!.$7!K8""',5`.L%`>X/\`4@*B!.15=3("T@:&EG -M:&QI9VAT<]P`,')E8]D4`C$%`Z`"DD-/4%E)3D<@+0P%`$(4`,H'(F1OGP`` -MAP4`S@"T*B!)3E-404Q,("V2&`&/!`$-``#Y%@"_``(I``-`!1$M/``!%!0" -M&``"$QD`?@L5+0P``D0``@(952P@'2(`"%P=6<0,"`B8S0&$2(D`P`X#"EO;$T``E8!!C4!`2D!`!8)`(X! -M#VT!`0"B!@2I&51T:&4*)[``(V4GKQD#)`0`DP``3@#P`"YA;2P@86-L;V-A -M;"YM-`D-`^T`,"YA8_\```(`$"UD`@"?``2H``#9#@BB!!(L&@X`UPL`60L/ -M9!K_________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_________U5096UO7,N"E)%041-15``1"!L:6)M`=%B=6YD;&4N"@I1=65SK@"@/R`@27-S=65S -M/U(`UBH@:'1T<#HO+W=W=RXX`$`N;W)GDP``2`$Q:&]MIP"`(&]N9V]I;F`<``$D!0'-U8V@G -M`%`J(&5X84D`0',Z(%,R`U1S;6%L;!4`!#X!`%(#(6%T?`2`;6%Y(&9I;F30 -M`C%F=6PO`@9%`%$O;6EN:84!$6'C`5%A8W0@2#R`@`!!5`N"@I4:)T!,'`M;`P$`W8%,&]R>3$%,'1A:20%";8"(FENU@0Q -M:6]NZP4$O0+P"4Y%5U,@+2!H:6=H;&EG:'1S(&]F(')E8P8"`C$%`Z`"DD-/ -M4%E)3D<@+0P%`,T%`"@&(F1OGP``AP4`S@#R!"H@24Y35$%,3"`M(&EN\`!,GK0`#)`0`DP``3@#U`2YA;2P@86-L;V-A;"YM -M-"SA`$!E+F%C_P```@`0+:("`)\`!*@`#*($LBP@;VYL>2!N965D?``Q;6%I -M]@$C97*N`05P`"1I;F0`@2YH+FEN"@DM]`=2;&%T97-G`!%B-`(!9@$39;4` -M8`H*1W5I9/,`*"!$5`8$T@$"=0`!MP%P!1%E^P,`\@"`;6%T] -M!;!I;@IA(&YU;6)E2X`P"`H8FEG+65N9&EA;J(!8VQI='1L91$``OH`\0)) -M4T\Y-C8P($-$+5)/32!I;;<"$"@X#C`@;W#+`\!A;"!2;V-KFEP -M/@$Q:6]N!0%=8GII<#(6``1\`4TO3%I7'0"B;'IM82P@;'II\+`OH#`*D"`&@1`HT``88!`MH`#Y8#!0'(`V$B;F5W8R*;`P$S`"=S:+`` -M`1(`#T8#8P0%!`?.``]9`P`*%@,S5VAE`P((T0X"Y@5A4,`4&EN9&5PJ@`E -M;G0B`0!$#0`/#Q!C0@42;VP-!C4*5"!7:6MI4@P##!,P:&]W^``!LP,09*T! -M`]H``BH!(4]N/P@`]PP"8`8`\PX`4`8#S0`!<`!3;'=A>7-S""IE9(H(`D<` -ML$DG=F4@871T96UPC`L``7\*`\X1("`HTA`E(&'["@"A -M`2`@8;(!`2<0`BT`",T`%&]S!'`I+"!I="!W<`!!(&=E=!D3`5T*`*0$-R!) -M;FX`,BP@:8(5`9X``5$!`YL`(F5NR0$'+0``?``+<0`H9&41``/&`A$LY0D" -M@```C0X`E@$`%@$`0``P86=A\P\!7PJ18V]R"(&5N=FER;VX/"Q%WD`,!H`(0;=@!$W):`P4P`@!;``)_`!%Y>P,1 -M<#4`T6%T979E:89`@4.%CHN`0+("0`]`!)A[`(!@`X`T1DS:6X@)P$` -MCP(/9!K_____________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_____________V505VAE;B!$:$ZN-A$``/$J8W)E871I;F<@87)C:&EV97,L -M('1H92!R97-U;'0@8V%N(&)E(&9I;'1EFEP,A8`!"8`32],6E<=`/D#;'IM82P@;'II<"P@86YD('AZ(P#!"DYO=&5S -M(&%B;W5TE`!R;&EB=$`\"YT96-T=7)E.@H*("H@5&AI'!L86EN:6YGR0`P:&]W^``"]0`'+``"*@$A -M3VZJ`!PL`P$#^``"<`!`;'=A>48!`-T!\@%E9"!A=71O;6%T:6-A;&QY1P"P -M22=V92!A='1E;7#7`>!T;R!M:6YI;6EZ92!S="L`L"!L:6YK('!O;&QUN`'A -M+B`@268@>6]U(&1O;B?L`0"V`/$":6-I=&QY(&EN=F]K92!A('#K`(!U;&%R -M(&9E85D"0"`HD`!RT`!P8#`(`!`ID!<"DL(&ET('=P`/`` -M(&=E="!P=6QL960@:6XN/@`G26YN`#``%1`0.;`")E;LD!!RT``#X` -M"W$`*&1E$0`#Q@(1+/```H``(FYEC@(`%@$`0`!B86=A:6YS1P*@8V]R7L#$7`U`-%A=&5V97(@8FQO8VMS\``0:$,$ -M(6ETH0!!66]U717 -M`F$@82!T:6U7`W%O`+$@(&)S9'1A3X`!8P``0`"\05R;W9I9&4@96%S>2UT;RUUX`0!V``*4`0"A`P&3``)/!R)L>8<``J,!!H`%,7=A;H@` -M$'0V!`5%`0!@`!!IA0(`C@%EB!$!G&%)`$!S.B!3,@-4`0-)`#!C;VY#`O`".B`@5F%R:6]UP``7P%V875T:&]R -M,&`4D!A69I9W5R92`M#``"1`"U'2(`")P==8-(")C -M-`81(B0#`#@,*6]L30`"5@$&ZP,!*0$`%@D`C@$/;0$!`*(&('5SW0H`V@$T -M90HGL``C92>M``,D!`"3``!.`/``+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C -M%P$``@`0+:("`)\`!*@``-D."*($$BP:#@#7"P)\`#%M86GV`2-EPH"MP(29:`,`!(&0'-E<77J"!!S"P4!/@$`=0`` -M%P(`^00!<0`!<0H(EP``/`DS>2XS30``[P0R92`B:P,%JP`!)``4(@L+62!C -M;&%S1``!'PE&;F%L]!9!I;@IA(&YU;6+R#!=FD0<$.P''"@I9;W4@2X` -ML2`H8FEG+65N9&EAU!%C;&ET=&QE$0`"^@#Q`DE33SDV-C`@0T0M4D]-(&EM -MMP(0*#@.,"!O<,L#P&%L(%)O8VMR:61G9>\!`DD`-%I) -M4'4$!$``('5N,0L`)18`UA!@C2H`0#E%PD(`0``"@*<$`4Z -M`0!U!`\&`0("KP$#OP,"O`(/'P,8,")R9:`-`!`6$2)'`P)/`,0L('=H:6-H -M('=I;&R*``%6``:0`"!E>"T4``("`+D%!(D1`@L7`UH7`5$`!>D2,',@*%,* -M`30$`(0!`S,$`/0#8"P@971C*>\+`OH#`*D"!C`0`9L!`MH`#\@#"F$B;F5W -M8R*;`P$S`"=S:+```1(`#T8#8P0%!`);`0&)``]9`P`*%@,S5VAE`P(`OP@# -MU`(2<^8%#V0:________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M__________________]34')A=&EO,WL/1TH1``#S'VXN"B`J(&QI8F%R8VAI -M=F4M9F]R;6%T4P`T&-P:6\N-2P@;71R964)`/(.86YD('1AP$R+F@BJ0"`:&4*2!E2QN``/2 -M`>`@875T;VUA=&EC86QL>68!065C='.H``#5``,<`E!O;&QO=Y,!$&8L`*!S -M.@H@("H@1TY5^`$`J`!6;6%T("BY`0`:`$%L;VYG50)B;F%M97,L$`!3;&EN -M:R`1``"T`5)S<&%R'1E;J+``-J`1%S2P"W4$]325@@=7-T87(0`.%P87@@:6YT97)C -M:&%N9WX!-VUA="$`L&]C=&5T+6]R:65N`0,`8`(!'@"A4U92-"!!4T-)270" -M`10``F,`#S(`!6%":6YAB,``!DT%``)"`&58V%N(&-R96%TSP`!=00/!@$"`NP" -M`[\#`KP"#Q\#&,$B2!S=')E86VU!>!S>7-T96TN("!4:&5R92P`(VYOX@<`@@(#WP@`DP3R -M`B!I;BUP;&%C92!M;V1I9FECK0CS`F]R(')A;F1O;2!A8V-E0`&@`3R -M`FES(&1EP`#P`! -MAPD!HP!4(&]N;'D*`P`X"`"R``$>`P"F!`(,`B$@8C<)<7)E861A8FP`!D%W -M48!`-T!*F5DB@@" -M1P"P22=V92!A='1E;7",!^!T;R!M:6YI;6EZ92!S=+4(`E((4'!O;&QU(@=1 -M+B`@26;U"$!D;VXGU@D`!RT`!"T'`,\*(&]R(P"@;6%T*2P@:70@=W`` -M@B!G970@<'5L^PH`I`0W($EN;@`W+"!IG@`(FP`B96[)`0P,1<#4`T6%T979E6QE(&%P<')OR`,`R0@"^@#0=&\@:&%V92!M=6QT:3$,!*D``@$$ -M`+D(52!O<&5NG@!0("!B4X.475S92`B(0$`6@@@+")0"'`L(&-A<&%B00`!]@("9@81954" -M`?$`864@05!)<[<$"/8%`9P"`,D*`2L`,VEN("#U%F:7)S=)("`*8!(&$@0P41;U`'`/8`%BYT -M``/9`P*G`0"_``*<`0&%``:X`0!V``##``"\`Q)EDP`",0\@;'ED`0#,``"C -M`0:`!3%W86Y_!1)T'0\#10$`8```&@00=(X'(7-K+`,0#B)A;N@"`*4'`!$#`EH'$"QC`$!D97-PWP``;`0!Y`,`7,N"E)%041-1>\%!^@&X2!B=6YD;&4N"@I1=65S^@*@/R`@27-S=65S/U(` -MUBH@:'1T<#HO+W=W=RZ!$4`N;W)GDP``2`$0:+@"$&:Q#S-N9V]8!Q@@9`!P -M9&5V96QO<#P%"!D1!+H1`:P(`3<,`'$``#H`(6YK70$`70`&8N9V]O9VQE+F-O;2]P+VH`$2\Z`"!S+VD``),``6<`47-U -M8FUI9P!P96YH86YC9<\``#8"!C@`,BP@<-H0`BP``#L```0#`$L'`1<)X65S -M="!V:6$@1VET2'5BP@`"D`"AB -M!`#R$0`6`G-A(&9U;&PME@AR9"`G=&%R)P\!`0(`(7)EK0H!0@%`8G5I;($& -M`(H``V,``"H``J(3!F,``,$0"V0`!M,2`3`#,&9A8RH'`#T``P(``"D0(FYT -M:`,`%0$V!L30',Z(%,R`U1S;6%L;!4` -M!#X!`%(#(6%T'`@@;6'F!"!N9-`",69U;"\"!D4`$"]#"@&%`1%AG@HT86-T -M>Q."9&5M;VYS=')*#0`.`R=O9EX!`TD`,&-O;D,"83H@(%9AP``7P%C875T:&]R -M:1``EPT!\@(`P1,2+NT/4'1O<"UL#`0#Q0P`,`0&";8""',5`.L% -M`>X/\`4@*B!.15=3("T@:&EG:&QI9VATM``,D!`"3``!.`/``+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C_P`` -M`@`0+:("`)\`!*@``-D."*($$BP:#@#7"P!9"Q!YR@4!]@$C97*N`05P`"1I -M;F0`@2YH+FEN"@DM]`<`YA,22XSHQ4$`(&EN^``(M@)P:6YF;W)M8:D!,"!F:34!`'P`\`0J($Y%5U,@ -M+2!H:6=H;&EG:'1SW``P@`K1#3U!924Y'("T@=U$!8F-A -M;B!D;Y\`,W1H:2D`\@))3E-404Q,("T@:6YS=&%L;'4```T`(7)U*@(#*0"! -M4D5!1$U%("T\``&5``*3`+!C;VYF:6=UM``,D!`"3``!.`/4!+F%M+"!A8VQO8V%L+FTT+.$`0&4N86/_ -M```"`!(M5``D=&^H``RB!+(L(&]N;'D@;F5E9'P`,6UA:?8!(V5R7`$%<``D -M:6YD`/(#+F@N:6X*"2T@=&5M<&QA=&5S9P`18C0"`68!$V6U`&`*"D=U:63S -M`%`@1&]C=9D%`H$!`,4!,F%L;'4``;`:`;W9E]!;!I;@IA(&YU;6)E"`"X!!,BO0(R+F@BJ0"`:&4*2R" -M```[!P$C"4!A=71ODP8`_P(0><$",&5C=)D#$635``,<`@5X"1!F+``!MP91 -M*B!'3E5U`0(U`B(@**L)`+D!`!H`06QO;F=0!F)N86UEB,``!DT%``) -M"`$```I58W)E873/``%U!`\&`0("J@,#OP,"O`(/'P,8,")R9:`-46-T960B -M1P,"3P#$+"!W:&EC:"!W:6QLB@`!5@`%R@%A(&5X8V5P0`4`N04$:0)1('1H -M871##C%I`3AN97>U`P#P!`![``.?`0![ -M``&'"0&C``)*#`!-$2)IF4@'!L:6-I=&S9"6)V;VME(&'Z#Q%C?PH#SA$@("C2$"4@ -M8?L*`*$!("!A00`!)Q`"+0`(S0`4;_D(<"DL(&ET('=P`$$@9V5T&1,!70H` -MI`0W($EN;@`W+"!IG@`!40$#FP`B96[)`07L#$7`U -M`-%A=&5V97(@8FQO8VMS\```[@2X'<70@82!T:6U7`W%O8!(71O(@`%2@``XQ,A8V6%`"%/;I`#&V7#``+D`C)P`!,@ -M%1``:A``"@$`/06#;B!I=',@(D`\`!(BO0012!F4X.``P1$2(A`0!: -M""`L(E`(H"P@8V%P86)I;&D2%`8#`07Q``+S#P$_#@CV!0&7`8`@:6YD:79I -M9&P.`]L(`(4``#H2`D(``*P+`-$``#8!(71OK`TP9&%TUP``!0X6.BX!`L@) -M`#T`$F'L`@#)"@$K`#-I;B`G`0!%!3-A9&2.`AAA]PP!J0H#'@]19FER41`.7,@9&5T96-T960@875T;VUA=&EC86QL>2X* -M"B`J($DG=F4@871T96UP(@#@=&\@;6EN:6UI>F4@6]U(&1O;B=T"B`@(&5X<&QI8VET;'D@:6YV;VME(&$@ -M<&%R=&EC=6QA2!A8V-E<#4`T6%T979E717`G`@82!T:6UEI0!Q;W(@;6UA<'\`0&5N=&F?`D!R -M8VAI?P)`;F0@9PD`(&ET3P``2P$%2@!A="!O;F-EA0"+3VX@=W)I=&7#``+D -M`C)P2!B=69F -M97(@;W+!``!E``1R`85A('-O8VME=#X#4'=I2UT;RUU0"0:7,@97-P96-I;@0!T`$"J@'S!TYO=&4Z(")P87@@ -M:6YT97)C:&%N9V6?!1,BN0(@;&P\`0+H`A!DO@$`_04!P040+&,`0&1EF-A="P@8@<`$G@'``!)`0"2"0`G`%`J(&5X84D`0',Z -M(%,R`U1S;6%L;!4`!#X!`%(#(6%T'`@@;6'F!"!N9-`",69U;"\"!D4`$"]# -M"@&%`1%A!@E186-T('-@`+`@9&5M;VYS=')A=+'2(`")P=;H+(")C-`81(B0#`!(+*6]L30`"5@$&ZP,` -ME``!%@D`C@$/;0$!`&8(('5SW0H`V@$T90HGL``C92>M``-G`0"3``!.`/4! -M+F%M+"!A8VQO8V%L+FTT+.$`0&4N86/_```"`!`MH@(`GP`$J```:@L(H@1A -M+"!O;FQYUPL"?``Q;6%I]@$C97*N`05P`"1I;F0`@2YH+FEN"@DM]`=2;&%T -M97-G`!%B-`(#<@$"M0!@"@I'=6ED\P`H($14!@32`0)U``&W`7!S>7-T96TZ -M&@D"N`0A+C'!#`!A#`$W`0,O`P`+``(A``2:`P,S``"(!`\T``L`(@`,-0`O -M870T``PH870S``8!!B$N,[8+$'-E"H!O=F5R=FEE=_,"`*``!<`+`'$%,'=H -M;Y$"%"JD"H5?PH"MP(29:`,`%L$$'/4!A!N2PT`U@(`DP``=0``%P(`^00!<0`!<0H( -MEP`!G`DC+C--``#O!#)E(")K`P6K``$D`!0B"PM9(&-L87-$``$?"49N86QS -MG0`2P$2+8($-7,N-:H(`J\``!D#`/T%-6UA=&D/!&,"!98!`+````H"D"XU+"!M -M=')E90D``&\`7G1A"`#. -M#1,BR0TR+F@BJ0`R:&4*7PP0(+`)`/H``!0`!.D&`W((`G\"-&UO2X`L2`H8FEG+65N -M9&EAU!%C;&ET=&QE$0`"^@#Q`DE33SDV-C`@0T0M4D]-(&EMMP(1*'@((&]P -MRP/`86P@4F]C:W)I9&=EYP%B2F]L:65T*0$![P$"20`T6DE0=00$0``@=6XQ -M"P`?$P#6$&!R(")D969^!A$B9@D#&```H00C:655`0##`0"B`85"4T0@)V%R -M)U(``?@`$2?]`Q`GNP($/0%:-RU::7`F`-A-:6-R;W-O9G0@0T%"+``Q3$A! -M"@,Z3%I(,@`Z4D%2$0`86!$``1D(!2`&`/42"*\"`'82`"H(`,,/`TP&!D4( -M,&)E9DH#4F5V86QU0@H`K@,#+P(`'P@P*B!U]@40;Q@$``L%`D,"`0H``EP) -ML5)032!WFEP,A8`!'P!32],6E<= -M`*)L>FUA+"!L>FEP$P,O>'HC```9-!0`"0@!```*`IP0!3H!`'4$#P8!`@*O -M`0._`P*\`@\?`Q@P(G)EH`T`$!81(D<#`D\`Q"P@=VAI8V@@=VEL;(H``58` -M!I``(&5X+10``@(`N04$B1$":Q0`0PX`TQ,`40`%Z1(PA@!+1`0:2`*<&AE879I;'G\"#9E86VU!0(1"P6(%$!I -M0`&@`0I:7-N%")B98@%`$`$`5X!.&YE=[4#`/`$`/T"`Y\!`'L` -M`8<)`2L5`DH,`PH#`#@(`&\0%'3N$@(,`B$@8C<)`(P*`8\8`[@4`0P`$&$, -M`0+4$`!H``([`!%EG!8`/0$A=F5S`Q-Y0P!0:6YD97"J`"5N="(!`$0-`7D9 -M`$(%$F]L#0:P"U0@5VEK:5(,`PP3,&AO=U$/`;,#$&2M`0/:``+W$P4T&`3\ -M!`#S#@!0!@/-``%P``*`%P+$!0]D&O______________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________5E!L97,I"MF.+50L$0``\"0@ -M("H@4V]L87)I"!I;G1E"=M=')E92<]`5HW+5II<"8`V$UI8W)O2!A;'-O(&1E=&5C -M='--`&!H86YD;&4,`'!Y(&]F('1HW`%`;&QO=RX"X&)E9F]R92!E=F%L=6%T -M$@``(``#+P(1.M0`8'5U96YC;W$",V9I;.@``0H`$2"#`:)24$T@=W)A<'!E -M3@)%9WII<#X!,6EO;D0`76)Z:7`R%@`$9`%-+TQ:5QT`L6QZ;6$L(&QZ:7`L -MQP`O>'HC```9-!0`"0@!E6-A;B!C$`6%N86UED#`*4#`.<#]A)U2!S=')E86VU!>!S>7-T96TN("!4:&5R92P`D&YO(&1I -M-R86YD -M;VT@86-C97-S+GD`!I<`D&ES(&1EU -M`P#<`P![``'.`!!VFP0`T082$N("!)9B!Y -M;W4@9&]N)^P!`+8`\0)I8VET;'D@:6YV;VME(&$@<.L`('5L60B@96%T=7)E -M("AS=2\!&7,<`A!AZ0`'+0`$10<#(@("F0%P*2P@:70@=W``X"!G970@<'5L -M;&5D(&ENI`0W($EN;@`W+"!IG@`!40$#FP`B96[)`07L#$7`U`-%A=&5V97(@8FQO8VMS\```[@2X'<70@82!T:6U7`W%O -M8!(71O(@`%H0!A="!O;F-EA0`A -M3VZ0`QMEPP`"Y`(R<')O.@$!A0%18W1L>2W,``"."5)U='!U=.\"`&`$\0-O -M8FIE8W0M2!B=69F -M97(@)`@`90`$<@&%82!S;V-K970^`TEW:7-HN@3`P"`,D*`2L`,VEN(">D``,P``*,!!H`%,7=A;H@`$'0V!`5%`0!@```:!!!TC@7,N"E)%041-1;L&!^@&X2!B=6YD;&4N"@I1=65S -M^@*@/R`@27-S=65S/U(`URH@:'1T<#HO+W=W=RX@!S!O3``!(`1!HN`*# -M9F]R(&]N9V]8!Q@@9`!P9&5V96QO<#P%)BP@_`Y`9&]C=10``:P(`3<,`'$` -M`#H`(6YK70$`70`&8N9V]O9VQE+F-O;2]P -M+VH`$2\Z`"!S+VD``),``6<`47-U8FUI9P!P96YH86YC9;L``#8"!C@`@RP@ -M<&QE87-E+```.P``!`,`2PB!$!G0&";8"(FENU@0`I`H` -MZP4$O0+P`DY%5U,@+2!H:6=H;&EG:'1S7`8PM```Z#S`@*B"3``!.`/``+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C -M%P$``@`0+:("`)\`!*@``-D."*($$BP:#@#7"P!9"Q!YR@4!]@$C97*N`05P -M`"1I;F0`@2YH+FEN"@DM]`<`YA,2H($',+!0$^ -M`0!U```7`@#Y!`%Q``%Q"@B7```\"3!Y+C/T%#!A:6SO!#)E(")K`P6K``$D -M`!0B"PM9(&-L87-$``$?"49N86QSG0`2!Q(M@@0U=H+`#L'`2,)"=H1`,$" -M!;47`/<"`QP"!7@)$&8&$@&W!@*'&`:J"P@`&@#X%0P@%@$0```%"P&^"Q)S -M-P)2V -M`'!I;F9O6]U(&-A;B!D;Y\`,W1H -M:2D`\@))3E-404Q,("T@:6YS=&%L;'4```T`,')U8X$``RD`@%)%041-12`M -M%`$1`?$#+@H* -M66]U('-H;W5L9"!A;'-O(@(!3``Q8V]P=@8R8V]M6P%#:6X@(KT",BYH(JD` -M@&AE"G-O=7)C+P`19'4!`!0`,2!S8>D&`YH#`G\"-&UO68!,&5C=)D#$635``,<`@7"!A!F -M+``!MP91*B!'3E5U`0*Z`28@*+D!`!H`06QO;F=5`F)N86UE'1E;J+``-J`0`9`]$J(%!/4TE8('5S=&%R6P`"$``P<&%X20,B -M97)9!P-X`@B,` -M`!DT%``)"`$```I58W)E873/``%U!`\&`0("J@,#OP,"O`(/'P,8,")R9?X( -M46-T960B1P,"3P#$+"!W:&EC:"!W:6QLB@`!5@`%R@%A(&5X8V5P0`4`N04$ -M:0+1('1H870@U -M`P#P!`![``.?`0![``&'"0&C``)*#`,*`P`X"`"R``$>`P`)`0(,`B$@8C<) -M`&H(,6%B;``&`(P*`0P``2P+`@0!`&@``CL`0F5A8V@]`2%V97,#$WE#`%!I -M;F1E<*H`)6YT(@$`&`D`#P\08T(%$F]L#08U"E0@5VEK:5(,,&EN9\D`8VAO -M=R!T;_4`!Y8*`BH!(4]N/P@`]PP">`8#`P$#^``!B`E086QW87E&`0#=`2IE -M9(H(`D<`<$DG=F4@870M#0",!P#!#Y!I;FEM:7IE(',.#1)C4@A!<&]L;)0- -M42X@($EF]0A09&]N)W2H`)!E>'!L:6-I=&S9"6)V;VME(&'Z#Q%C?PHQ9F5A -M-`LP*'-U+P$%^PH`J0`@(&%!`!%P&`$!+0`$10<`S0`4;_D(<"DL(&ET('=P -M`'$@9V5T('!UG`T0:7H+1R`@26YN`#``%1`0.;`")E;LD!!RT``#X` -M"W$`*&1E$0`#Q@(1+/```H```(T.`)8!`!8!`$``(&%G`PX"1P*18V]RP,B:67-#P%O`P/G"B!D=1D-`)8"$'.%`2-O9H@! -M4&%L;'DM=@``,PP`]P@1:;0/`(0`<&5N=FER;V[7`C%S('>0`P&@`A!MV`$3 -M2X'<70@82!T -M:6U7`W%O8!(71O(@`%2@!2="!O -M;F-\$B)/;AP."\,``N0",G!R;SH!`84!46-T;'DMS`"2960@;W5T<'5T[P(` -M8`3Q`V]B:F5C="US='EL92!A<'!R;\@#`$,2`OH`T'1O(&AA=F4@;75L=&D: -M$P2I``(!!`"Y"`#^#15NG@`3(!40`&H0``H!`#T%@VX@:71S(")`/``2(L@# -M$7,P#@)C!098`&!I='-E;&93`0!]!!`O=@1@=&5N('5S;P8`-PP!<@$R9G5N -M6!($DP$!=08`,@`U(&%NB`0"(Q-0;'D@9G)@``S0*%82!S;V-K970^`TEW:7-HN@0!)@\#60\`#B)A;N@"`*4'!C0*$"QC`$!D97-PWP``;`0!Y`,`7,N"B05 -M$6:X#01Q%K0@8G5N9&QE+@H*41$6H#\@($ESF-%#A)B!P`2>`<``$D!`)() -M`"<`02H@97@;$T!S.B!3,@-48$(&YDT`(Q -M9G5L+P(&10!1+VUI;FF%`1%AH0L`Z1D#>Q,/9!K_____________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_____________________________________________V507,@<')O9'5C97,@8V]R6]U('1O(&AA=F4@;75L=&EP)0`P -M`/,-("!B2!D8737`%9UX`0!V``*4 -M`0```P&^``7+`0#3``.C`4,N("!)I`$A86Z(`!)T70`!-@(491\!`#L!061I -M"!I;G1E&%)`$!S.B!3,@-4`0-)`#!C;VY#`O`".B`@ -M5F%R:6]UP``7P%Q875T:&]R<\`%`1\&`?("`DT'$`H5"%!T;W`M;`P$`W8% -M`#`'`4$`$&DD!0FV`B)I;O@$(FEOX08$O0+P`DY%5U,@+2!H:6=H;&EG:'1S -M7`8P'2(`#!P=71>`C`@(F,T!A$B)`,`J@2!N965D?``Q;6%I]@$C97*N`05P`"1I;F0`@2YH+FEN"@DM]`=2;&%T97-G -M`!%B-`(#<@$"M0!@"@I'=6ED\P`H($14!@32`0)U``#S`8`@PH"MP(A960N"P!;!!!SU`80;A$,`-8"`),``'4``!<"`/D$`7$``7$*")<` -M`9P)(RXS30``[P0R92`B:P,%JP`!)``4(@L+62!C;&%S1``!'PE&;F%L]!9!I -M;@IA(&YU;6+R#!=FD0<#HP#7+@H*66]U('-H;W5L9*0+`$P`,6-O<'8&0&-O -M;6V>"`#.#1,BR0TR+F@BJ0`R:&4*7PP0(+`)`'4!`!0`!.D&`W((`G\"-&UO -M@,QBH@4U92-"!!4T-)210``E,`#S(` -M!6%":6YA`@@;W#+`\!A;"!2;V-K[`@0]`5HW+5II<"8` -MV$UI8W)OFEP/@$Q:6]N -M&`%=8GII<#(6``1\`4TO3%I7'0"B;'IM82P@;'IIP`!APD!*Q4"2@P`31$B:7*"$1!I>0<# -M[A("#`(A(&(W"0","C%A8FP`!@","@$,`!!A#`$"U!``:``".P!"96%C:#T! -M(79E4,`4&EN9&5PJ@`E;G0B`0!$#0`/#Q!C0@42;VP-!K`+5"!7:6MI -M4@P##!,P:&]W40\!LP,09*T!`]H``O<3(4]N/P@`]PP"8`8`\PX`4`8#S0`! -M<``"@!<"Q`4J962*"`)'`'!))W9E(&%T(14`C`'!L:6-I=&S9"6)V;VME(&'Z#Q%C?PH# -MSA$@("C2$`!U#`@<`A!AL@$!)Q`"+0`(S0`4;W,$<"DL(&ET('=P`%`@9V5T -M(-(2`5T*`*0$-R!);FX`!287`9X``5$!`YL`(F5NR0$'+0``?``+<0`H9&41 -M``.J`!$L6!$"@```C0X`E@$`%@$`0``P86=A\P\!7PJ18V]R7L#$7`U`&)A=&5V97)X%Q%S\```[@ -M$P'Y%@*[&0"V`A!GQ!D0:2(3`2(`!4H``.,3#V0:____________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________________________________________](4'(*("`J9;G0 -MKS<1``#]#"!G>FEP(&-O;7!R97-S:6]N"B`@*B!B>FEP,A8`!"8`32],6E<= -M`/\#;'IM82P@;'II<"P@86YD('AZ(P``&304`/$R"E1H92!L:6)R87)Y(&-A -M;B!C"!I;G1E'1E;DT!\1-S -M("AF;W(@;&]N9R!F:6QE;F%M97,L($%#3',L(&5T8RDND@"P3VQD($=.52!T -M87)=``2I``+*`/$$;V-T970M;W)I96YT960@8W!I;S4`ME-64C0@(FYE=V,B -M%0`G -M`21E9-T`$2E%``"=``#5`85"4T0@)V%R)U(``1X`>"=M=')E92>[`'A)4T\Y -M-C8P$P!:-RU::7`Y`#9805(1`$,*5VAE`P(`Y`$$!0(1+/P!87)E0`& -MEP#R`FES(&1E'!L86EN:6YG -MR0`P:&]W^``"]0``C@0#+``"*@$A3VZJ`!PL`P$#V0("<`!`;'=A>48!`-T! -M\@%E9"!A=71O;6%T:6-A;&QY1P"P22=V92!A='1E;7#$`^!T;R!M:6YI;6EZ -M92!S="L`L"!L:6YK('!O;&QUN`'A+B`@268@>6]U(&1O;B?L`0"V`/$":6-I -M=&QY(&EN=F]K92!A('#K`"!U;#<$(&5A60)`("AS=2\!&7,<`A!AZ0`'+0`' -M[P4`@`$"F0%P*2P@:70@=W``X"!G970@<'5L;&5D(&ENI`0W($EN;@`W+"!I -MG@`!40$#FP`B96[)`07L#$7`U`-%A -M=&5V97(@8FQO8VMS\``0:%<%(6ETH0!!66]U2X'<70@82!T:6U7`W%O8!(71O(@`%H0!A="!O;F-EA0`A3VZ0`QMEPP`"Y`(R<')O -M.@$!A0%18W1L>2W,``!(!E)U='!U=.\"`&`$\0-O8FIE8W0M2!F)M96UO?\`!8P``0`"\05R;W9I -M9&4@96%S>2UT;RUU8<``J,!!H`%,7=A;H@`$'0V!`5%`0!@``'Z"0".!R%S:RP#`WX&N6-O -M;G9E;FEE;F-EP`$`B0`P;6%K>0"0:7,@97-P96-I;@0!T`$"J@$`.@@P.B`B -MDPH.NPH3(KD"(&QL/`$"Z`(`I0<`$0,"P040+&,`0&1EP -M`"-E)ZT``V2XS30``[P0R92`B:P,%JP`!)``4(@L+62!C -M;&%S1``!'PE&;F%L``'?`5=H+`#L'`2,)"=H1`,$",&5C=)D#$61A -M#0,<`@>F%@`@`@!0!0)!%0:J"R8@*`0+`%L5#"`6`1````4+`;X+$G,W`E)S -M<&%R\6`2T5`A``#XH,`P%V,/"Q<`T$UI -M8W)O-50! -M(FEN;P``MP)086)O=710`2!S94T!='!O<'5L87(?`01[`(`L(&EN8VQU9(H! -MQ6AA6]U(#\!8"X*"D-U$D#<65R8VAA;F=^`3=M870A`+!O8W1E="UOFEP/@$Q:6]N&`%=8GII<#(6 -M``1\`4TO3%I7'0"B;'IM82P@;'II&-E<$`%`+D%!&D"L"!T:&%T(')E<75I -ME@4G87C*`B`@*'T'`30$`(0!`S,$`/0#<2P@971C*2YO`0#Z`P"I`@8B!`$7 -M``+:``^6`P4!R`-A(FYE=V,BFP,!,P`GD#`*4#(71EVPC`.@H*("H@5&AI -M?P(-F5A;;4%`A$+@"X@(%1H97)E+``C;F_B!P""`@/? -M"`"3!/("(&EN+7!L86-E(&UO9&EF:6.M"/,";W(@P`#GP$` -M>P`!APD!HP!4(&]N;'D*`P`X"`"R``$>`P`)`0(,`B$@8C<)<7)E861A8FP` -M!@","@$,``$L"P($`0!H``([`$)E86-H/0$A=F5S`Q-Y0P!0:6YD97"J`"5N -M="(!`!@)4&%R=&EC0@4D;VXB"`2N`$17:6MI4@PP:6YGR0`P:&]W^``"I@<' -ME@H"*@$A3VX_"`#W#`)X!@$""B-N9/@``8@)4&%L=V%Y1@$`W0$J962*"`)' -M`'!))W9E(&%T+0T`C`?0=&\@;6EN:6UI>F4@D`!RT`!"T'`,T`%&_Y"'`I+"!I="!W<`!Q(&=E="!P -M=9P-(&ENI`0W($EN;@`W+"!IG@`(FP`B96[)`0P,Q:65SPP`!;P,#YPH@9'49#0"6`A!SA0$C;V:(`5!A;&QY+78``#,,`/<( -M$6F'!@"$`'!E;G9IP,1<#4`T6%T979E2W,`))E9"!O=71P=73O`@!@!/$#;V)J96-T+7-T -M>6QE(&%P<')OR`,`R0@"^@#0=&\@:&%V92!M=6QT:3$,!*D``@$$`+D(`/X- -M%6Z>`!,@%1``!A``"@$`/06#;B!I=',@(D`\`!(BO0012!F#B)A;N@"`*4'!C0* -M$"QC`$!D97-PH@``;`0!Y`,`7,N"E)%041-11(&!DD1X2!B=6YD -M;&4N"@I1=65S^@*@/R`@27-S=65S/U(`UBH@:'1T<#HO+W=W=RXX`$`N;W)G -MDP``2`$0:+@"$&:Q#S-N9V]8!Q<@3`>`(&1E=F5L;W`\!0@9$02Z$0&L"`$W -M#`!Q```Z`"%N:UT!`%T`!G,`02!M86G;$C!L:7._$`&=%!!4F0$`Y1$`YP$0 -M:;<`$"PA!`'\``$/`)$@=')A8VME1$@#R$0`6`G-A(&9U;&PME@AR9"`G -M=&%R)P\!`0(`(7)EK0H!0@%`8G5I;($&`(H``V,``"H``J(3!F,``,$0"V0` -M!M,2`3`#,&9A8RH'`#T``P(``"D0(FYT:`,`%0$V!L30',Z(%,R`U1S;6%L;!4`!#X!`%(#(6%T'`@@;6'F -M!"!N9-`",69U;"\"!D4`$"]#"@&%`1%AH0LT86-T>Q-P9&5M;VYS=#D5(&YG -M/@``@`4&5`(#20`P8V]N0P)A.B`@5F%R[A-@:71E;7,@,P$`UP(@;67/%U)T -M:&ER9,\),&5S.\@``P(``^H"`$8``'L``%\!<6%U=&AOP`"-E)Z\9`R0$`),``$X`\``N86TL -M(&%C;&]C86PN;30)#0/M`#`N86/_```"`!`M9`(`GP`$J```V0X(H@02+!H. -M`-<+`%D+$'G*!0'V`0]D&O______________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________9U!C:&EV97UVJIXG$0``\#T@=VET:&]U -M=`H@("!F:7)S="!W2!F6]U('=A;H@` -M$G1=`!`OB@`196``,&EE7,N -M"E)%041-12X`1"!L:6(3`=%B=6YD;&4N"@I1=65SK@"@/R`@27-S=65S/U(` -MUBH@:'1T<#HO+W=W=RXX`$`N;W)GDP``2`$Q:&]MIP"`(&]N9V]I;F`<``$D!0'-U8V@G`%`J -M(&5X84D`0',Z(%,R`U1S;6%L;!4`!#X!`%(#(6%T?`2`;6%Y(&9I;F30`C%F -M=6PO`@9%`%$O;6EN:84!$6'C`5%A8W0@2#R -M`@`!!5`N"@I4:)T!,'`M;`P$`W8%,&]R>3$%,'1A:20%";8"(FEN^`0Q:6]N -MZP4$O0+P"4Y%5U,@+2!H:6=H;&EG:'1S(&]F(')E8P8"`C$%`Z`"DD-/4%E) -M3D<@+0P%`,T%`"@&(F1OGP``AP4`S@#R!"H@24Y35$%,3"`M(&EN\`!,GK0`#)`0`DP``3@#U`2YA;2P@86-L;V-A;"YM-"SA -M`$!E+F%C_P```@`0+:("`)\`!*@`#*($LBP@;VYL>2!N965D?``Q;6%I]@$C -M97*N`05P`"1I;F0`@2YH+FEN"@DM]`=2;&%T97-G`!%B-`(!9@$39;4`8`H* -M1W5I9/,`*"!$5`8$T@$"=0`!MP%P!1%E^P,`\@"`;6%T] -M!;!I;@IA(&YU;6)E"`"X!!,B?P(R+F@BJ0"`:&4*`D09BP``;<&42H@1TY5=0$"-0(F("@$"P`:`$%L -M;VYG50(`K0LB+``-J`0`9`]$J(%!/4TE8('5S=&%R6P`" -M$``/B@P#!R$`P&]C=&5T+6]R:65N=!<$,7!I;QX`IE-64C0@05-#24D4``)3 -M``\R``5A0FEN87)Y+@#`("AB:6FEP,A8`!'P!32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9 -M-!0`"0@!```*56-R96%TSP`!+0D/!@$"`JH#`[\#`KP"#Q\#&#`B&-E<$`%`+D%!FH0 -M,6AA=$,.$&F6!2=A>,H"("`H%@4!-`0`A`$#1`0`]`-@+"!E=&,I[PL"^@,` -MJ0(&,!`!A@$"V@`/E@,%`<@#82)N97=C(IL#`3,`)W-HL``!$@`/1@-C!`4$ -M`EL!`8D`#UD#``H6`S-7:&4#`@C1#@+F!6%R97-U;'1-$A%B:`4@=&6[#@%5 -M!`\C`@$*"P,!@``/Z0)4$`HJ$@&G!P(F"`:A!@`^!R%T9=L($3I4$@$M$!!I -M(`IP:&5A=FEL>?P(-F5A;;4%`A$+<"X@(%1H97(T$2`@;M82,7)E8S`1`]\( -M`),$02!I;BVW#X(@;6]D:69I8^4,\`!O`3AN97>U`P#P!`#]`@-S!`![``&' -M"0&C``)*#`!-$2)I7-S""IE9(H(`D<`<$DG=F4@870A -M%0",!S!T;R`A$'!M:7IE('-TM0@"4@A!<&]L;#82!N04061O;B?L`7!E>'!L -M:6-I#15@:6YV;VMEO!(!ZP`!?PH#SA$@("C2$"4@8?L*`*$!("!AL@$!)Q`" -M+0`(S0`4;_D(<"DL(&ET('=P`$$@9V5T&1,!70H`I`0W($EN;@`R+"!I@A4! -MG@`!40$#FP`B96[)`0"(&5N -M=FER;VX/"Q%WD`,!H`(0;=@!$W):`P4P`@!;``)_`!%Y>P,1<#4`T6%T979E -M:89 -M`@4.%CHN`0+("0`]`!)A[`(!@`X`T1DS:6X@)P$`104U861D'`$`_`@$J@$` -M>08/9!K_____________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_____________V50FEP,A8`!"8`32],6E<=`/D#;'IM82P@;'II -M<"P@86YD('AZ(P#!"DYO=&5S(&%B;W5TE`#P.VQI8G)A2!R97%U:7)E;65N=+(`,G1H80D!`BL`("!BCP&0(')E861A -M8FQEH@!!=W)I=`P`$&$,`0($`0!H``([`$)E86-H/0&#=F4@96YT$N("!)9B!Y;W4@9&]N)^P!`+8` -M\0)I8VET;'D@:6YV;VME(&$@<.L`@'5L87(@9F5A60)`("AS=2\!&7,<`A!A -MZ0`'+0`'!@,`@`$"F0%P*2P@:70@=W``\``@9V5T('!U;&QE9"!I;BX^`"=) -M;FX`-RP@:9X``5$!`YL`(F5NR0$'+0``/@`+<0`H9&41``/&`A$L\``"@``B -M;F6.`@`6`0!``&)A9V%I;G-'`MEC;W)R97-P;VYD:6YGF`$-6@`">P,Q:65S -MPP`!;P.P86QS;R!R961U8V6;`C!E('.%`2-O9H@!`+,!$"UV`&%E9"!B:6X] -M`"`@:2P$@"!E;G9IP,1<#4`T6%T979E8!(71O(@`%2@!A="!O;F-EA0`A3VZ0`QME -MPP`"Y`(R<')O.@$!A0%18W1L>2W,`))E9"!O=71P=73O`@!@!/$#;V)J96-T -M+7-T>6QE(&%P<')OR`,`H`4"^@#@=&\@:&%V92!M=6QT:7`E```A!1!V$@,` -M!040<_@!16]P96Z>`+$@(&)S9'1A3X` -M!8P``0`"\05R;W9I9&4@96%S>2UT;RUUP"`*`'`2L`,VEN("0#\`)N86UE('-A>7,N"E)%041- -M15``!^@&X2!B=6YD;&4N"@I1=65S^@*@/R`@27-S=65S/U(`URH@:'1T<#HO -M+W=W=RX@!S!O3``!(`1!HN`*#9F]R(&]N9V]8!Q@@9`!P9&5V96QO<#P% -M<2P@:6YC;'6]!4!D;V-U%``!K`@!3@D`<0``.@`A;FM=`0!=``9S`%`@;6%I -M;`<"0FQIF-A="P@8@<`$G@'``!)`0"2"0`G -M`%`J(&5X84D`0',Z(%,R`U1S;6%L;!4`!#X!`%(#(6%T'`@@;6'F!"!N9-`" -M,69U;"\"!D4`$"]#"@&%`1%A!@E186-T('-@`+`@9&5M;VYS=')A=+"`"X -M!!,B!0XR+F@BJ0`R:&4*7PP0(+`)`/H``!0`!.D&`W((`G\"-&UO5$P`P%&!E+``-J`0`9`[$J(%!/4TE8('5S=+`1!!``#XH,`P%\``(Q`%9O8W1E=*\4 -M`&`"`1X`H5-64C0@05-#24ET`@$4``\R``L00FT1$7DN`+$@*&)I9RUE;F1I -M8=018VQI='1L91$``OH`\0))4T\Y-C8P($-$+5)/32!I;;<"$"@X#C`@;W#+ -M`\!A;"!2;V-K[`@0]`5HW+5II<"8`V$UI8W)OD,1``#Q%V]C=6UE;G1S('1H92!F:6QE(&9O -M2!E2QN``/2`>`@875T;VUA=&EC86QL>68!065C='.H -M``#5``,<`E!O;&QO=Y,!$&8L`*!S.@H@("H@1TY5^`$`J`!6;6%T("BY`0`: -M`$%L;VYG50)B;F%M97,L$`!3;&EN:R`1``"T`5)S<&%R'1E;J+``-J`1%S2P"W4$]3 -M25@@=7-T87(0`.%P87@@:6YT97)C:&%N9WX!-VUA="$`L&]C=&5T+6]R:65N -M`0,`[P(!'@"A4U92-"!!4T-)270"`10``F,`#S(`!6%":6YAB,``!DT%``)"`&5 -M8V%N(&-R96%TSP`!=00/!@$"`NP"`[\#`KP"#Q\#&,$B2!S=')E86VU!>!S>7-T96TN("!4:&5R -M92P`(VYOX@<`@@(#WP@`DP3R`B!I;BUP;&%C92!M;V1I9FECK0CS`F]R(')A -M;F1O;2!A8V-E0`&@`3R`FES(&1EP`!S@`&[P@"HP!4(&]N;'D*`P`X"`"R``$>`P"F!`(,`B$@ -M8C<)<7)E861A8FP`!D%WF4@7L#$7`U`-%A=&5V97(@8FQO8VMS -M\```[@2X'<70@82!T:6U7`P!K"S%M87#X`C!E;G21!@/0`@%1`Q!GH@P@:71/ -M``E*`&%T(&]N8V6%`"%/;I`#&V7#``+D`C)P7,"!8P``+$!!)4.0&5AP"`,D*`2L`,VEN("60!`,P``*,!!H`%,7=A;G\%$G0=#P$V`@%;`P!C#``S`$%D -M:7-K+`,#?@:Y8V]N=F5N:65N8V7``0")`#!M86MY`)!I%E7!1`GD1(`\A$`%@)S82!F=6QL+98(F-%#A)B!P`2>`<``$D!`)()`"<`02H@ -M97@;$T!S.B!3,@-4?42`-`",69U;"\" -M!D4`$"]#"@&%`1%AG@HT86-T>Q."9&5M;VYS=')*#0`.`R=O9EX!`TD`,&-O -M;D,"83H@(%9AP``7P%C875T:&]R:1``EPT!\@(`P1,2+NT/4'1O<"UL#`0#Q0P` -M,`0&";8""',5`.$&`>X/\`4@*B!.15=3("T@:&EG:&QI9VATM``,D!`"3``!.`/``+F%M+"!A8VQO -M8V%L+FTT"0T#[0`P+F%C_P```@`0+:("`)\`!*@``-D."*($$BP:#@#7"P!9 -M"Q!YR@4!]@$C97*N`05P`"1I;F0`@2YH+FEN"@DM]`<`YA,2!Q(M -M6`DU:L`D'-A;64@9G5N8S`<``$D!0'-U8V@G`%`J(&5X84D`U',Z(%-O;64@6]U(&UA>2!F:6YD('5S969U;"\"!D4`42]M:6YIA0$1 -M8>,!46%C="!S8`"A(&1E;6]N2#R`I!I;VYS+@H*5&B= -M`?("<"UL979E;"!D:7)E8W1O%#36%K94QI\`!,GK0`#)`0`DP``3@#U`2YA;2P@86-L;V-A -M;"YM-"SA`$!E+F%C_P```@`2+50`)'1OJ``,H@2R+"!O;FQY(&YE961\`#%M -M86GV`2-E7-T96TZ -M"B`J(+@$=2XQ(&5X<&R#`@,O`P!"`0(A``2:`P,S``"(!`\T``L`(@`,-0`O -M870T``PH870S``8!!O`%+C,@9VEV97,@86X@;W9E]!;!I;@IA(&YU;6)E"`"X!!,B -MO0(R+F@BJ0"`:&4*2R"```[!P$C"4!A=71ODP8`_P(0><$",&5C=)D#$635 -M``,<`@5X"1!F+``!MP91*B!'3E5U`0(U`B(@**L)`+D!`!H`06QO;F=0!F)N -M86UEB,``!DT%``)"`$```I58W)E873/``%U!`\&`0("J@,#OP,"O`(/ -M'P,8,")R9:`-46-T960B1P,"3P#$+"!W:&EC:"!W:6QLB@`!5@`%R@%A(&5X -M8V5P0`4`N04$:0)1('1H871##C%I?P(-F5A;;4%`A$+ -M@"X@(%1H97)EO0\C;F_B!P""`@/?"`"3!$$@:6XMMP^"(&UO9&EF:6-D"_`` -M;W(@0`&EP``L!!397-I9VXE#!)EB`4`0`0!7@$X -M;F5WM0,`\`0`>P`#GP$`>P`!APD!HP`"2@P`31$B:7)`$!!I>0<280D!`@P" -M(2!B-PD`C`HQ86)L``8`_0H!#``!+`L"U!``:``".P!"96%C:#T!(79E4,`4&EN9&5PJ@`E;G0B`0`8"0`/#Q!C0@42;VP-!C4*5"!7:6MI4@PP:6YG -MR0`P:&]W40\!LP,09$X(`]H``BH!(4]N/P@`]PP"8`8`TQ$`4`8#S0`!<`!3 -M;'=A>7-S""IE9(H(`D<`<$DG=F4@870M#0",!S!T;R`A$+)M:7IE('-T871I -M8U((07!O;&PV$E$N("!)9O4(061O;B>L$I!E>'!L:6-I=&S9"6)V;VME(&'Z -M#Q%C?PH#SA$@("C2$"4@8?L*`*$!("!AZ0`!)Q`"+0`(S0`4;_D(<"DL(&ET -M('=P`$$@9V5T&1,!70H`I`0W($EN;@`W+"!IG@`!40$#FP`B96[)`07L#$7`U`-%A=&5V97(@8FQO8VMS\```[@2X'<70@82!T:6U7`W%O -M8!(71O(@`%2@``XQ,A8V6%`"%/ -M;I`#&V7#``+D`C)P`!,@%1``:A``"@$1:2$(8VETP"`,D*`2L`,VEN("#U%F:7)S=)("`*8!$6%P$A%O\0T`]@`6+G0``]D#`J#B)A;N@"`*4'!C0* -M$"QC`$!D97-PH@``;`0!Y`,`7,N"B05$6:X#007&0.A&$0N"@I1 -M$1:@/R`@27-S=65S/U(`$2H%&78Z+R]W=W2X*"B`J($DG=F4@871T96UP=&5D('1O(&UI;FEM:7IE('-T*P#X4R!L -M:6YK('!O;&QU=&EO;BX@($EF('EO=2!D;VXG=`H@("!E>'!L:6-I=&QY(&EN -M=F]K92!A('!A``B;`%IE;F%B;)L``#X`"W$`*&1E -M$0`#J@`1+/```H``(FYE)@$`%@$`0`#X"V%G86EN<`!`"@$`#,`@&%N9"!W&%)`$!S.B!3,@-4P`` -M"@+Q`F%U=&AO@`K!#3U!924Y'("T@=Q,'`+D(8F-A -M;B!D;Y\`,W1H:2D`H$E.4U1!3$P@+2#0!S)A;&QU```-`"%R=2H"`RD``T`% -M$"T4`1%SE0`"DP"P8V]N9FEG=7)E("W.``$,``)$`+5S8W)I<'0L('-E96<` -M`/T(9&1E=&%I;,,$84--86ME3-0$,71X=(@`(G!U)@EQ(F-M86ME(B0#`*0) -M*6]L30`"5@$&ZP,`E`!!2!N965DQ0@0>5L+4&$@=VAOD0(C*B#9!X5?]!;!I;@IA(&YU;6)E<$",&5C=)D#$61A#0,< -M`@5X"1!F+``!MP91*B!'3E5U`0(U`B8@*`0+`!H`06QO;F=0!F)N86UE+``-J`0`9`X$J(%!/4TE8("`-`5L``A``,G!A -M>%H)`ED'`W@"!R$`L&]C=&5T+6]R:65N1!``8`(!'@"A4U92-"!!4T-)270" -M`10``E,`#S(`!1!"V0X1>2X`H"`H8FEG+65N9&GS!(-R(&QI='1L91$``OH` -M\0))4T\Y-C8P($-$+5)/32!I;;<"$2AX""!O<,L#P&%L(%)O8VMR:61G944` -M8DIO;&EE="D!`>\!`DD`-%I)4'4$!$``('5N,0L`BQ`@960Z`$`B9&5F?@81 -M(F8)`Q@``*$$(VEE50$`PP$`H@&%0E-$("=AFEP -M/@$@:6^[$'TJ(&)Z:7`R%@`$?`%-+TQ:5QT`HFQZ;6$L(&QZ:7`3`R]X>B,` -M`!DT%``)"`$```I58W)E873/``$M"0\&`0("J@,#OP,"O`(/'P,8,")R9:`- -M46-T960B1P,"3P#$+"!W:&EC:"!W:6QLB@`!5@`%R@%A(&5X8V5P0`4`N04$ -M:0("UQ$`0PX0:98%)V%XR@(@("@6!0$T!`"$`0,S!`#T`V`L(&5T8RGO"P+Z -M`P"I`@8B!`&;`0+:``^6`P4!R`-A(FYE=V,BFP,!,P`GD#`#X'(71EVP@1 -M.N85`2T0$&D@"G!H96%V:6QY_`@V96%MM04"$0M!+B`@5$`44VES(&YOX@<` -M@@(#"A4`DP1!(&EN+;P`#GP$` -M>P`!APD!HP`"2@P#"@,`.`@`;Q`R=&AA"0$"#`(A(&(W"0!J"`'[%2%O46`$(%$F]L#0:P"U0@5VEK:5(,`PP3,&AO=U$/`J8'`$X(`]H`"Z`5 -M!/P$`/,.`%`&`\T``7``0&QW87E&`0#=`2IE9(H(`D<`#]`7_^`)^@,08S<& -M``48PF%T979E -M$P$/`P),%@"V`A!G5180:2(3`2(`!9L$`.,3(6-EA0`A3VZ0`QMEPP`"Y`(R -M<')O"AFA8V]R>`9 -M07!P4X.``P1$2(A`0!:""`L -M(E`(H"P@8V%P86)I;&D2%`:-`07Q``+S#P$_#@CV!0&7`8`@:6YD:79I9&P. -M`]L(`(4``#H2`D(``'(+`-$``#8!(71OK`TP9&%TUP``!0X6.BX!`L@)`#T` -M$F'L`@&`#@`K`#-I;B`G`0"/`C-A9&2.`AAA]PP!J0H#'@]19FER"U$W,3$W-0`>83$U,34U,@`>+S4Q`![_ -M5==&96(@,#DL(#(P,3,ZAPJ1(#,N,2XR(')E,A.>9`H*2F%N(#(X*0`A)W.K -M"T!W96)S``0R;6]VT0L/(1X&$BY,`"XQ,TP``74`&S%U``\I``87,"D`841E -M8R`P-U(`0#(Z($E2&P$(#`@*!0/0%`#O#!EE&@P`G04"VPT"3A@!D`B$(`I. -M;W8@,3%4`"!!9+8;!JPB@U]?34%#3U-8%PT`@@0$$]@\$90``P@$@(&Q<`6``'E("`@0_$@`9D"`V,``%(7#P(A -M$@]U``@)DR$#=0``3@L#=`!01W)O=7`2$`"U`R$R-!4!&3$5`0`^`0=\!`$H -M``(O!"4Q.ID>H&9I>&5S(&UE`RDQ.D4`"AH`$5/\'P+8`&%T;R!)4T^?``!U`%!T;R!I -M;8H+-F4@2-RQH` -M+PU18V]L;&6((0#C#0!*#S!L92VK(@#`` -M)F]NS0,!W`<&?`$11O0&`"H#,FP@,#4"(3`Z -M_"T`&QH#HR8'0R80968$`=\3`I4$`2X#`M$0``D+,'1R884%(6%L.P0A,CD[ -M!$`P.B!-<`(#R`8%$`,`%04"G``!\!3P``H4!$C"%`4!L87)G -MQQ0!ZA(`V!1B96X@8V]PE!$`#@,!'A($R`D!00`#B040,`@"`;(G`'@`=B!- -M86,@3U.I`@`\``>N!`$Z``-"`B0P.E``!^L``*H)`_T"$'->"0+N`%1S"DUA -M>24-8S`Z(%A!4D,$`1D``T,%$3#'`34@7E0-!1([/B]`(&5X:1$5`J<$`]0' -M`!H!`)0=`XT*`F,`!IL``UT$`=\A!A`%!`<"!!L#8&,@8W)Y<,4$`L$,`8\` -M`_L&(3`Z/1T!`@(`+`8"$`0`)@,`1P4"*@`"!0T2,``(`]0#$CHN!T`M9VED -M!@``*@1!("TM=0X`$'4.``$'!0,R#@/``6!2960M8FQ@%@#\(@&4!P;^`0$9 -M%2!E"!L96=A -M8WFU!S%M870,!`/!4`Q`,`,AT"D`4#=@@#O@$`OP<29"L``)$@.6QD95\(`%T;$&R[`0`5#@%` -M*"%E9,L#!A`!55)E;&%X`P(`P@4@2!!4D-(259% -M7T9!5$%,(')A'`0@=&@;`T,@=FES^Q0#*08`R0L#=0`T7`8P`!H4#$%+(!T5A9FEO#@D!50`%PP400<<=`%8`!_,C -M!3$%(6QY+`\$_0("6P`%NP%@26YT96=R70(@07#Q&`?W!`!+!@@-!0!_'2!A -M=`,L$'5.'@'@`0+^&`$!$A4S5``$$0$`WR,S("U6X@X&4P0&:PLX,BXXJQ$W -M2F%NR`,`=@L!S`@&"@,`DP#@)V5C:&\@;F]N97AI0(O,#G?```?,=\`#P&O#`*'`@]#```6,7P-,TIU -M;#L#`"@````"`/@DL2!B;V=U'HP``)!`P0P``"1 -M,0*8`4$@,2XW90<1,?4`""$`<&QZ;6$O>'I;`P/A`@!G``06(`D""`)`!`"? -M!1-Y\@X`20`12,@D("!G_A("10``V`D$00!`3W!E;I0E<")G>G-I9R+-*`"@ -M,`)%``+#`P!%`)!!=F]I9"!F86P*`@.2!0*(`02I!`&@!#!P:7`F,P!1$@+> -M!P`\``ME`@?\`@+%!@%_!`TI`$<0"%W()`RM!9#L04FYE>'1?;`\T,B@I -MGQ9!:7,@=6$243(U)0H),2M0969F:6-S"`%E``$>'@.#"!([:A/30G)I86X@ -M2&%R2!-:6-H -M:6AI'@#'!T%T86UP -ME@LP5')UY0X!\0X`I@0`L2A02'5R9"R&`,%":L.VF5D!0\2)P/``S!C;W)D -M`D%!;'-O)R0+L0`Q8FED`(5<]<.(`H)E`8A97/-`S!S=&$N*`"(``,. -M!"%S+NH=`XD&)#@ZS@D"&P4)D`D!I@X28)`"P3=@ED;V5S;B?G!PLR`&)W96QL*2RS -M!B)I65T"@E00T%D('5NH@`"K!`")0<#WP`)L1J086QL*"DN("!& -MF`M!;F]W+)0J,&UU2!E;F]U9V@@00=!+"!W -M9<:\!"W@!%S1/`0$I``4E`P_8`0$P9FEXZP4`;`($_!X* -ML!,`#C0`S0``1@0!,Q@&(P8!OAP!9A$`2R$&]A\":0,`/PX`"0D38=U#3H@"?$E$W`=`-`N9G)E96)S9"YO0"@D@(&UE87-U>P,!4P8".0``30(`N@L1:1Q)`5TO0'!A=&@=`&$@9FEE -M;&31`#!U*P%'(F!M;6%R:7HZ"1!P[#L`W!<"MP0`N@!`+6YO+;H*(V9I -MCC@T;&EBS4<#;Q0`)P`+J`!B.B!3:VEPDQ@!LP$!8P4!2@4#_P0",0A0,S(M -M8FD6!3!F7W1'`#!I -M(P'&`2`M!@"AP$`V#0%%",!5P8754-!"8G -M`(H!$&:;!B5L>?,$(`H))0]5:VYO=V[(``"O)4!A=&5G(QD+.0$"7!8`"00" -M+`4"EP(.3P<,G@`!F`<`U1,#Z@@!?`D""00&/0L`X@(/2P`/`"8!`*L``/@( -M&&5;`@-:%3`@=74;$3!D93L,`1%YD`X"N`T!U`\0+8$N,65C;X$%4FQO9VEC -ML14"-``0!Q(NR!\&Y@X,I@`5,Z8` -M`I,8!?D"`W8=`)T&$2Q,`@"3`!(LF@`0+"P$`IX``3L!(&-A91`18I@+,79E -M`A8R7@(**0``J`$@8F%S3A%DB`,!%PD#%0$&PR4#3`4"*B(&=0`* -M2P!D5F5R:69Y300!5@@`21HQ9V5TF@T"I3P!8@L$S54`<1H!C@5%,BXY+H(! -M`CH``$@!$FQ4,1!B$QD!VPL'X0\B*"VE#T`M>BDLJP,`(0\Q"6]FJ@TPA$P%!$P&^ -M!0!G"2$*"8U.`=P(`!0%8&QA*9!`;4E`.@3`O@D!F$!`*<$`;$)!3T/`6H``C\K#VH` -M`0S,&0)A!!8WA@A0,"XY+C#&!P"!!P+.4R!W::$5,W5S92<;!30`($-OCQL` -M&@M0:6YI=&E\!@`/)00Q$`#*`0,)`@28``+'`PZ8`!4YR@8"P``%*``&U`4` -M8P$"C30`>@4"B1<)9`#P`SH@("UA+"`M<2P@+4PL("UF+)L8$'0^�@00!G"0#C$`0+)H*!(T2H41A;6EE;B!';VRJ!`"C`!!B>@T` -MZ0`!CP,`B3@0>H*Q`O!0D!!0`07[@4("YCH2$`@@LP--*)7!Y^!T!=``#$!L2-XD%4&$@8V]UE!PC;V:6!`>M)@#E!0%_``*I#PZG -M``?R%0HH``!;``"I`P&G``$%`!%?:0$07]\$(6)YV3$"10%R92!U;6%S:Z0_ -M`T`!`_H>#G``!E@)`LL`!1X"`(8'!C12!(0"4"TM9&ESIQ!2+7AA='1Y"@84 -M`'5A8VPL"@ET[0'_`%-A;75L:2!3=6]M:6YE;HP`#0<^"0'\``6,``8_`L!, -M87!O($QU8VAI;FG5!0!Z50%)`@!.'`%520`%#@'2"0&:)`-*!0"3`2!L9%<) -M`54N`/H;!&\$,&)U9\8%`1@``$`!L&]F"@DB;&5N9W1HGA2096YD(B!F;&%G -M'@H%80`2@$@"@D4``&Z)`,Z.P_T!08'B04**``">```)0@`\04`,A0&/`(#N@Q08VAI -M;&P'%PL[`!!/D`8`V1``\`("]PT+0$D@<'7P+PF-`@`A$`,D`048+P!, -M`0#!5`&$``4L!Q-)U`@!V0L`V`<097\G``$#4&XM;6%T;P4`%5T`U#XA;W)! -M#(([($D*"6AO<$@-D2!E=F5N='5A;#PE`?%,`!\!`#`+,F1E("<*`$,H`LX) -M`,Y5`Q4_`FL.#)<&&#.7!@"J`!4P+@$@0V\C&A!UD``$K0`$=@4`7`(!F"H2 -M9=\`!C4`$$XM30%85@#E0`"T!!,L]PL!<`@P(DAI[PH@>2*U`0-.`"`N,3@) -M`<\,`*\`%#$Y``/D(09<``"8!Q5Z-#P`EP*1:6UM961I871E#0$!D#@P14]& -MT2H`C!\P=')YSP\!_A4%PQ0`$0XP)(5`EH/!,L+`)T#(6]FA``#H0(`90@`OCL/D04$&#-I!P`H``/0$!`W -MT",!50$334<<("YA)!4!3@<`$@02(,<@$R\#"`1J$D,*"6%C_`$A9&\H`%%R -M:6=H=$$3,6=S+KDA!F,``,0($"VT"`!2"@$-``&$#`2[``?<%`%A!``C`1!I -M]0``B@,,)P$-70`!D`4/E`L``.4+(&ENO2(@8V6](``7$`'0#0`T`@#K.@$` -M*@1](`!&%0",)S!N:6/2`2)H868&4')A9W1A!P,(7#L`00`#M%P1<_L(%'3# -M!R1H88@!!F@#";H'&#.Z!P&(`0\H``40,5(:)&ME6@`@8F5K'`!Z`P5&2P,, -M"@#'!4`H*0H)2PPY!("UP+#X'`6,Z(0H)Q24""1$5 -M;Z,0$"QB$0'Z#00X"U!S96=F8><%`CX"!H$``F@)`U8#`44B`NH2`S\""0A```001('X88`H) -M:6YS=(0&$',C!!!TF08)&&$#IP`%I@0(7"X`T`=T>5]L:6YK7\P2%"S0!0,= -M`#!S=')O6@(N`@/T,0R6`1@RH0T`E@$&P@P&B`$4,@`&`-\"0'-T("A<(S!Y -M972<$!(INP`"ZST"?A(`&SP##`(#/#`.=@`'80U2075G(#,O)!(WXS(`LS(` -MF0,$O`8"*QX`@PLC"`M+7-))P22!Q(N-P`%.`P3 -M4K,:8'-U:60O0@(6A``X````0\`C`,`92@`]AP&GR80+`T<`0$,)`H)AA4" -M21,$43DE('06%@*7!"`N:"P>(V%DQ0EC;&5A;G5P?BL*8@$2+!T5``P'$7,B -M"@`S$A$O+Q(#W`4P;@H)!`E386YO;6$("@',6@`G&@5D#`$%&A=YT@$+"P$6 -M,CH3"B@```L!#MT%$""1`P),(@`$#`*7`U!Y(&-L;Q`.`)4I071R>2#2*P`> -M!R)T;X`<`P,T("!SS`@`8V(`P!@!DB(!EQ91(&ES"@FF!`D.`G(@9FEN:7-H -M.@$!`@T`Y@P$E0``E`$37^45`*`'L'=O0:70@:&5L -M9"!OPT,`J`4"F@``81L!J@``O34`A2H"%R(`^1T@=6U!,`!\%0)<#@3^!@&< -M0P#Q$&`@8G)E86M**@#K#@#Z+`$8'@#Z,`'X`@2?``%@`!!?&0$69?DT`)8. -M`*@``NXL$&AR#`$N'8!S;VYA8FQY(+D!`!(5`I<-`,DU`*8<%WF"$X%3:V5L -M971A;'P+!HP(`5T'`^P!!@(%"^P!&C'L`08H`%!&;&5S:,D7`'(6$&];,!%R -M:Q,`?0("?@$@+F.\`1%AP`008[T,`>TC`.,-`!0E(6-H&P`C:&5_&B`@;MX" -M`2D!$6$A(`'*70)I`@`D`6(\A`CH["@E3 -M``&:"1)WQDX`R0L`7P,#>P("[`,"D@$0;E,R`,QH`'0#!8T.,71O=>P"`$P% -M`()%`V`!%3'A$0O^``R``N`4`GQ`$`2(*^0H!$`0!)`T)-3(!W0@$64<`0`4,XP`'"`0**0``M`8! -M[!$0;BY($6X]+0!^&@12``5N`0Q2`!8TP@(!4@`%2Q($_!]``!_ -M+P%\+0`9`@"8'@$0-`1<*`)I``#D``(_`@#$50*+)P4H`0'J`P0`%P#8!0DZ -M"2)T;P@]!(@!!3<`#(@!![D%"H@!$4@-!P1'#2!S.Y`-$&70!&!N=7@O9G-M -M#0*X"0+B``&Y"`BK&0`-.#%E65T>5,#5S0!I@$C=&\R%@"A"@#-%@"" -M$A`B^0%R(&-H96-K(H4&!%PD`T<)"Y@!!V$!`",%`E$7%W/$24%)3$5$H@H! -M=``!M64`X0(`+04"+TH!'0%`82!W89$T$&&8+0"//2-F9A@"$FG%A4''@!#5T%23A@"!@H@![<``6H$!V(& -M`%P!!BD``"L4`>T!`)X"`'@",7,@**(``'<%`.,"`E,+%RU790'I``#^!@/[ -M%P`F```^``G\&3)O=RG'`09K``+I,@0-#`2$&`"#/S`@;V:*;E)S:R!G;[0P -M`&8!`*(.(69FT0\#Q!`P.R!R5FP!`A$0:4@E$"AX``/4$@!)!`*]`@?]``B4 -M``#Z$D!I;F@`!-@HQ<&%XU0`%[0,`O18B=6ZE`2!E9%8D`38! -M#[D*`S3#`!@ -M*`:)'0%R!P"O`31'240G!0(,`Q)S``4#10,B8GD6`#%I;F<8`2%W:'0N`;<. -M`TX;`=U1`>8\4'1O;R!F3$(`PP<`SA:A;GD@<')I=FEL9;`:`9DI#V`2!#

    @?LFES -M(&QO;F``^'"@$!G@`'Q08!G@`%3P,10@E`5`@9&]W;A,.!UX!('=H,@$!)0`# -M$0@!3P`A8GE!``'.&5$@=&]O;*T$`#<&`N8H!2X``H4&`=L<-6UI>BP!!C4+ -M!VP``2P!!]D%`"P!`P="`C4"`=`H`5\1`/H&`=$H`8T&!D0``)P6`_17`J$` -M)&8@1@%!4$52331H("!ATQ5A97(M9W)A -M^#0!3@\P9F%C7@(688<0`",!!-L5#;`U$&`0@=`'Q#$&_=/@"$`@`M!0(R+@$D50:+=P)J"0$K -M6@/0!A!3(C509F5A='7?"`+V%Q!N>P$%RCL`J08!PQX'EP,"1Q4!<@$"<@!1 -M:6YV;VS4`03S`0'-!@0$50%1#0!3!@`&`@!<8A%)%!T38XH)`8(T$'AA"P`` -M`B!O9L\1XB!O=F5R:&%U;"!W:6QLPB8!N"\#,38"I`L!?@`"BBX&1P$'?'@" -MV1``SP("[AL*W0X(U``"S0`"1R8!G#L#=P<`'"40*/8X!+]*`+$$`8,!`'T" -M(V]F#"<09CT3"XD``,L?$',F!`,D``%&"`!#"`,V)`,!>05$#@,T!`&*``()`(P?!2<`0$)U;7`%*!!SFPL0 -M=&PV$3/C``"+)2!)+SQ6``@S(G)S,2`",1(2-M83`\P;`$$!049)3$4A)`/B -M$`\V``0&1P8"[P$$^2(#-A4`I`,`?%85>19/,6%L._L``?\*,6QO8[`1$6$] -M"C!M:6X:/A)UZ"H!JP85+<@!`=@U`G0>`SX5#!(!-S(N-3X)`'4>!BD`LT]U -M=&QI;F4@04))SD81!IH``-@)"^L`!Y<7`-H%`H$!`!L;,'-E*`!Y42!4:&5YEPD`3BP"C@X` -MZP(`9@\!2P``.BH59N(?"FP`P')E8W5RG%A%R50\P:V5EZ7$!KR=0;&4@=7!%!P!C-`(\``!V -M""!O;LLK0DQ$15)V`*)354U-05))15,*_1`"K04/9`,`&C$A`0,A(Q`V60X( -MF24`5A<@;F1O`1)TV4,%B`\)EB,R(')E;G``RP`!-PT`"64@;W(('0(H$P!. -M`@5@\`V`)0=V]R=&AT`!1S$S@!Q081!D;5L"30$`VP50<&%C:V&72P<">`#8`1!EN`I`+F=Z"LQJ`&H3 -M`8<$`8H;$G/X%`?V!`#K!0+?#`*(.`-S,P#/`02.!0)[%A0Z>P/H!`5X<`A9_$2[^30(`&QLUVAD!O@$#]@$$ -MM1$)1T\`/@X$71D`'PL&7QD`NP4`1A,"M@0"'Q(` -M`P$I#Q!E7@D1>=T1`#T"!.Y#,7,@*`H(`BL<`A`*!AP``IX83#%-0BEQ`*!- -M87)C=7,@1V5I?0<`5AP`'P0`#/`'S#GAS;FEL -M+F%N=&)E87(N;W)G+S(P,#4O,#(O,#4O@@%`+6UI='YI!`\``%H:@')B96ET -M96XO2P`"RA<`9@<$[8H`!Q`"M0`-OA/$%+"!(4"U56"P@56YI>'=A&9I;&4``0!+X3`P,#8T-"``,#`P-S8U"``B,#(0`"(R -M,`$`_P<@,3(S-3,U-3,U,3(@,#$R,#(S`"`PEP!+`@(`KW5S=&%R`#`P8W4' -M`0M2,!46%C="!S8`"A(&1E;6]N4$`(&EN^``(M@)A:6YF;W)M&@00 -M(+@&!+T"\`E.15=3("T@:&EG:&QI9VATP`"-E)ZT``R0$`),``$X`]0$N86TL(&%C;&]C86PN;30L -MX0!`92YA8_\```(`$BU4`"1T;Z@`#*($LBP@;VYL>2!N965D?``Q;6%I]@$C -M97)<`05P`"1I;F0`\@,N:"YI;@H)+2!T96UP;&%T97-G`!%B-`(!9@$39;4` -M<`H*1W5I9&6V`AA$5`8$T@$"=0`!MP&R'!L -M@P(#+P,`0@$"(0`$F@,#,P``B`0/-``+`"(`##4`+V%T-``,*&%T,P`&`0:` -M+C,@9VEV97/?!H!O=F5R=FEE=_,"`*``!+L%$&%Q!3!W:&^1`B,J(-D'A5]R -M96%D+C,L$```T04=91$`45]D:7-K%@`"?@<(/@`#'```F0`0=E\!`K<"865D -M(&-A;(D'$'/4!D%N8V5SK0(`DP``=0``%P(`^00!<0!8($%027.7`'-E;G1R -M>2XS30`"]P,2(FL#!:L``20`4"(@=71II`59(&-L87-$``'O!49N86QSG0!@ -M]!;!I;@IA(&YU;6)E`D09BP``;<&42H@1TY5 -M=0$"N@$F("@$"P`:`$%L;VYG4`9B;F%M97,L$```!0L3(!$``&,`4G-P87)S -M?`(AB,``!DT%``)"`$```I58W)E -M873/``%U!`\&`0("J@,#OP,"O`(/'P,8,")R9:`-46-T960B1P,"3P#$+"!W -M:&EC:"!W:6QLB@`!5@`%R@%A(&5X8V5P0`40"EL)`VD"42!T:&%T0PXQ:7)E -M40`!\P,!R@(@("A3"@$T!`"$`0,S!`#T`V`L(&5T8RGO"P+Z`P"I`@8B!`&& -M`0+:``_(`PIA(FYE=V,BFP,!,P`G0<280D!`BL`(2!B-PEQF4@'!L -M:6-I=&S9"4!V;VMEO!(!ZP`!?PH#SA$@("C2$"4@8?L*`*D`("!AZ0`!)Q`" -M+0`(S0`4;Y4(<"DL(&ET('=P`$$@9V5T&1,!70H`I`0W($EN;@`W+"!IG@`! -M40$#FP`B96[)`0P,1<#4`T6%T979E`!,@%1``:A`` -M"@$`/06#;B!I=',@(D#E`!(BO0012!F4X.``P1$2(A`0!:""`L -M(E`(H"P@8V%P86)I;&D2%`8#`07Q``+S#P&W!`CV!0&7`8`@:6YD:79I9&P. -M`&@%(6EEA`$`.A("0@`$K`4`-@$A=&^L#3!D8737```%#A8Z+@$"R`D`P@`2 -M8>P"`,D*`2L`,VEN("4&EV92!E -M0A0``/$1;G1R>2!B90H@("!I;F1E<&5N9&5N="X@(%1H97)E(&$$`/`9=&EC -M;&5S(&]N('1H92!L:6)A'1E;F0L`/(6+@H*("H@3VX@F4@;V:(`0"S`1`M=@!A960@8FEN/0`P(&ENA`#A -M96YV:7)O;FUE;G1S('=N`F!T:&%T(&W8`2)R<^D!!3`"`WD"H7)A3X`!8P``+$!\09P7,N"E)%041-12X`"!0'T6)U;F1L92X*"E%U97/Z -M`J`_("!)3``!(`1!HN`*# -M9F]R(&]N9V]8!Q@@9`!P9&5V96QO<#P%<2P@:6YC;'6]!4!D;V-U%``087<` -M$"Q8!P!Q```Z`"%N:UT!`%T`!G,`4"!M86EL!P)";&ES=*`#,"H@5)D!`>H& -M0&%N(&FW`!`L(00!_``!#P"A('1R86-K97(@8F-A="P@8@<`$G@'``!)`0"2"0`G`%`J(&5X84D`0',Z(%,R`U1S -M;6%L;!4`!#X!`%(#(6%T'`@@;6'F!"!N9-`",69U;"\"!D4`$"]#"@&%`1%A -MXP%186-T('-@`+`@9&5M;VYS=')A=+\`!,GK0`#9P$`DP``3@#P`"YA;2P@ -M86-L;V-A;"YM-`D-`^T`,"YA8_\```(`$"VB`@"?``2H``RB!&$L(&]N;'G7 -M"P)\`#%M86GV`2-E7-T96TZ&@D"N`0A -M+C'!#`!A#`$W`0,O`P`+``(A``2:`P,S``"(!`\T``L`(@`,-0`O870T``PH -M870S``8!!B$N,[8+$'-E"H!O=F5R=FEE=_,"`*``!0H,`'$%,'=H;Y$"%"JD -M"H5?PH" -MMP(29:`,`%L$$'/4!A!N2PT`U@(`DP``=0``%P(`^00!<0`!<0H(EP`09<,/ -M(RXS30``[P0R92`B:P,%JP`!)``4(@L+62!C;&%S1``!'PE&;F%L`8`>P`( -M2PE`:&%R9!8,`3`&!%L!`4<``(X!86UO9&5R;H\``.@!`+P'<"!V87)I86Y( -M"0!$!+%M86YU86P@<&%G93@``+`0)')EI@``G@`!'0-7)V1O8R>]!9!I;@IA -M(&YU;6+R#!=FD0<#'@'7+@H*66]U('-H;W5L9*0+`"@!,6-O<'8&0&-O;6V> -M"`#.#1,B!0XR+F@BJ0`R:&4*7PQ!(&-O9'4!`!0`!.D&`W((`G\"(6UOU@P" -M6@4R("!0B@FR;&5T('5S"FMN;W<0`0&9!G!E2X`L2`H8FEG -M+65N9&EAU!%C;&ET=&QE$0`"^@#Q`DE33SDV-C`@0T0M4D]-(&EMMP*`*'=I -M=&@@;W#+`\!A;"!2;V-KU`P$3`%HW+5II<"8`V$UI8W)OFEP,A8`!'P! -M32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9-!0`"0@!```*`IP0!3H!`'4$ -M#P8!`@*J`P._`P*\`@\?`Q@P(G)EH`U18W1E9")'`P)/`,0L('=H:6-H('=I -M;&R*``%6``:0`"!E>"T4``("$`I;"0-I`E$@=&AA=$,.$&F6!2=A>,H"("`H -M?0`3AN97>U -M`P#P!`#]`@.?`0![``&'"0##%Q)E2@P`31%`:7)E;?8-$&EY!P/N$@(,`@,A -M&D%R96%DCQ@#N!0!#``080P!`M00`&@``CL`$66<%@`]`2%V9?P4#V0:____ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M__________]J4&EV97,*4!0``/`5"E1H92!L:6)R87)Y(&%LFEP -M,A8`!"8`32],6E<=`+%L>FUA+"!L>FEP+,<`+WAZ(P``&304``D(`95C86X@ -M8W)E873/`$]S(&EN!@$#`21E9-T`$2E%``"=``"<`H5"4T0@)V%R)U(``1X` -M>"=M=')E92>[`'A)4T\Y-C8P$P!:-RU::7`Y`#9805(1`$,*5VAE`P(`V`($ -M=0$1+`(#87)ED#`*4#`.<#]A)U2!S=')E86WM`>!S>7-T96TN("!4:&5R92P`\01N;R!D:7)E8W0* -M("`@`>-R86YD;VT@ -M86-C97-S+GD`!I<`\@)I4<`L$DG=F4@871T96UP -MQ`/@=&\@;6EN:6UI>F4@2!I;G9O:V4@82!PZP`@=6PW!*!E871U``%1`0.;`")E;LD!!RT``'P`"W$`*&1E$0`#Q@(1 -M+/```H``(FYEC@(`%@$`0`!B86=A:6YS1P*@8V]R7L#$7`U`-%A=&5V97(@8FQO8VMS\```[@2X'<70@82!T:6U7`W%O8!(71O(@`%H0!A="!O;F-EA0`A3VZ0 -M`QMEPP`"Y`(R<')O.@$!A0%18W1L>2W,``!(!E)U='!U=.\"`&`$\0-O8FIE -M8W0M2!B=69F97(@ -M)`@`90`$<@&%82!S;V-K970^`TEW:7-HN@3`P" -M`,D*`2L`,VEN(">D``,P``*,!!H`%,7=A;H@`$'0V!`5%`0!@``'Z"0".!S!S -M:RQ.`P-^!KEC;VYV96YI96YC9<`!`(D`,&UA:WD`D&ES(&5S<&5C:6X$`=`! -M`JH!`#H(,#H@(I,*#KL*$R*Y`B!L;#P!`N@"`*4'`!$#`L$%0"P*("#,!Q!P -MWP``;`0`E@`0(',*T"!S87ES+@I214%$346[!@?H!N$@8G5N9&QE+@H*475E -M<_H"H#\@($ES7!1`GH@1`9W)A;18"M``-G`0"3``!.`/``+F%M+"!A8VQO8V%L -M+FTT"0T#[0`P+F%C%P$``@`0+:("`)\`!*@``-D."*($$BP:#@#7"P)\`#%M -M86GV`2-EPH"MP(`A1(A86R)!V!S97%U -M96Y+#0#6`@"3``!U```7`@#Y!`%Q``%Q"@B7`'!E;G1R>2XS]!0`!`,!=`$2 -M(FL#!:L``20`%"(+"UD@8VQA=&%R -M+C54`0CQ!`4^$A%S8P0Q<&]PY0\#G`$`>`8`>P`(2PE`:&%R9!8,`3`&`J@! -M`X42`(X!86UO9&5R;H\``.@!`+P'<"!V87)I86Y("0!$!+%M86YU86P@<&%G -M93@``#$.`,X4`OH!`)X``:D!5R=D;V,GO06P:6X*82!N=6UB97*5`@:1!P,> -M`=%V,/"Q<`TTUI8W)O2)J -M%```\S4@=71I;&ET>2!C;&%S1X`<&QI8G)A#0#46-H86YG?@$W;6%T(0"P;V-T970M;W)I96X! -M`P!@`@$>`*%35E(T($%30TE)=`(!%``"4P`/,@`%84)I;F%R>2X`P"`H8FEG -M+65N9&EA;J(!8VQI='1L91$``OH`\0))4T\Y-C8P($-$+5)/32!I;;<"@"AW -M:71H(&]PRP/`86P@4F]C:W)I9&=E10!B2F]L:65T*0$![P$"20`U6DE0"0$# -M0`#P"G5N8V]M<')EB,``!DT%``)"`&5 -M8V%N(&-R96%TSP`!=00/!@$"`J\!`[\#`KP"#Q\#&,$B,H"4B`H9F]R-`0`A`$#,P0`]`-Q+"!E=&,I+F\!`/H# -M`*D"!B($`1<``MH`#\@#"F$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0%!`); -M`0&)``]9`P`*%@,S5VAE`P(`V`(#U`(2<^8%87)EF4@ -MP,1<#4`T6%T979E6QE(&%P<')OR`,`R0@"^@#@=&\@:&%V92!M -M=6QT:7`E``-3!`(!!`"Y"%4@;W!E;IX`4"`@8G-D(P2!B=6@-$B`D"`!E``!Z``#!`85A('-O8VME=#X#27=I#B)A;N@"`*4'`!$#`KH.0"P*("#,!Q!PH@`` -M;`0`E@`!I@[1('-A>7,N"E)%041-11(&!Q0'T6)U;F1L92X*"E%U97/Z`J`_ -M("!)3``!(`1!HN`(09K$/ -M,VYG;U@')B`@+`"`(&1E=F5L;W`\!0@9$02Z$0&L"!`LH@0`<0``.@`A;FM= -M`0!=``='`$!M86EL!P(P;&ESOQ`!G0`05)D!`.41`.!L30',Z(%,R`U1S;6%L;!4`!#X!`%(#(6%T'`@@;6'F!"!N9-`",69U -M;"\"!D4`$"]#"@&%`1%AXP$T86-T>Q-P9&5M;VYS=#D5(&YG/@``@`4&5`(# -M20`P8V]N0P)A.B`@5F%R[A-@:71E;7,@,P$`UP(B;64V%3)I'2(`"%P=6<0,"`B8S0&$2(D`P`X#"EO;$T`(`H*X0@& -MZP,!*0$`%@D`C@$/;0$!`+`,$'4]$P(0%R4*)[P`$R>M``,D!`"3``!.`/`` -M+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C_P```@`0+60"`)\`!*@``-D."*($ -M$BP:#@#7"P!9"U%Y(&UA:?8!(V5RK@$%<``D:6YD`($N:"YI;@H)+?0'(&QA -M5@\$NP`%A0`#M0!P"@I'=6ED9;8"$T0.&`*!`0/2`0)U``#S`0-3#Q`Z&@D" -MN`0A+C'!#`!A#`$W`0`]!@-X$P(A``2:`P,S``"(!`\T``L`(@`,-0`O870T -M``PH870S``>M`Q$SM@L`$!20(&]V97)V:65W\P(`JP`%P`L`<04P=VAOD0(4 -M*J0*A5]R96%D+C,L$``!^`@-$0!17V1I2XSHQ2!T:&ER9"!P87)T:65S.X,``P(`87!L96%S948``'L`\BET:&4@ -M875T:&]R2!Q=65S=&EO;G,N"@I4:&4@=&]P+6QE=F5L(&1I -M4$`(&EN^`"`92!F;VQL;W>V`'!I;F9O%#36%K94QIM`!(ZU```DP``3@#U`2YA;2P@86-L -M;V-A;"YM-"SA`$!E+F%C*P```@`2+50`)'1OJ```(`&`9&ES=')I8G5!`;(L -M(&]N;'D@;F5E9'P`,6UA:?8!(V5R7`$%<``D:6YD`/(#+F@N:6X*"2T@=&5M -M<&QA=&5S9P`18C0"`68!$V6U`'`*"D=U:61EM@*"1&]C=6UE;G2!`0#%`3)A -M;&QU``#S`?4*('-YM`_`$,R!G:79E2XS!`,!JP(2(FL#!:L``20`Z2(@=71I;&ET>2!C;&%S1`"6:6YT97)N -M86QSG0!@P$2+8($4W,N-2!D5@(#I@0@:6QV`]1R;6%T-50!"/$$4&%B;W5T -M&@$@P"`+"!I;F-L=62*`8%H87)D+71O+3`& -M`J@!$G-'``!!`&%M;V1E$D#(F5R60<#>`('(0"P;V-T970M;W)I96X!`P!@`@$>`*%3 -M5E(T($%30TE)=`(!%``"4P`/,@`%,$)I;LH$`$(`H"`H8FEG+65N9&GS!(-R -M(&QI='1L91$``OH`\0))4T\Y-C8P($-$+5)/32!I;;<"@"AW:71H(&]PRP/` -M86P@4F]C:W)I9&=E10!B2F]L:65T*0$![P$"20`U6DE0"0$#0``@=6Y."3!R -M97,G!W!OB,``!DT%``)"`$```I58W)E873/``%U!`\&`0("J@,#OP," -MO`(/'P,8,")R9?X(46-T960B1P,"3P#$+"!W:&EC:"!W:6QLB@`!5@`%R@%A -M(&5X8V5P0`40"EL)`VD"`A4,<7)E<75IP`#GP$`>P`!APD!HP`"2@P#"@,0;6L($&EY!Q%A+PD#*P`A -M(&(W"7%R96%D86)L``8`C`H!#``!+`L"!`$`:``".P!"96%C:#T!(79E4,`4&EN9&5PJ@`E;G0B`0`8"0`/#Q!C0@42;VP-!C4*5"!7:6MI4@PP:6YG -MR0`P:&]WFPP!LP,79)8*`BH!(4]N/P@`]PP">`8#`P$$S0`!<`!`;'=A>48! -M`-T!*F5DB@@"1P!P22=V92!A="T-`(P'`,$/D&EN:6UI>F4@2UV```S#`#W"!%IAP8`A`!P96YV:7)O;M<",7,@=Y`#`:`"$&W8`1-R -M6@,%,`(`6P`"?P`1>7L#$7`U`-%A=&5V97(@8FQO8VMS\```[@2X'<70@82!T -M:6U7`W%O8!(71O(@`%2@!2="!O -M;F-\$B)/;AP."\,``N0",G!R;SH!`84!46-T;'DMS`"2960@;W5T<'5T[P(` -M8`3Q`V]B:F5C="US='EL92!A<'!R;\@#`$,2`OH`X'1O(&AA=F4@;75L=&EP -M)0``(040=A(#0')E86W\"E4@;W!E;IX`$R`5$`!J$``*`0`]!8-N(&ET2!B=6@-$B`D"`!E``!Z``#-`H5A('-O8VME=#X#27=IP`2 -M8D(`!*P%`#8!(71OK`TP9&%TUP``!0X1.L$"`2X!`L@)`,(`$F'L`@!A`P$K -M`#-I;B`G`0"/`C-A9&2.`AAA]PP!UP<#'@]19FER>D` -M`,P``*,!!H`%,7=A;G\%$G0=#P-%`0!@```:!!!TC@A<"+```.P``!`,`2P+%1`G-Q,`)AD`%@)S82!F=6QL -M+98(F-%#A)B!P`2 -M>`<``'`$`)()`"<`%"I/&@]D&O__________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M________________________________________65`@("!T;U04``#R-B!B -M92!R96%D(&]R('=R:71T96X@=&\@86YY(&1A=&$@F-A="P@8@<`$G@'``!)`4!S=6-H)P!0*B!E -M>&%)`$!S.B!3,@-4 -M`0-)`#!C;VY#`O`".B`@5F%R:6]UP``7P%Q875T:&]R<\`%`1\&`?("``$% -M4"X*"E1HG0$P<"UL#`0#=@4P;W)Y,04P=&%I)`4)M@(B:6[6!#%I;V[K!02] -M`O`"3D574R`M(&AI9VAL:6=H='-'2(`#!P=71>`C`@ -M(F,T!A$B)`-I9"!T;V]L30`"5@$&ZP,`%`=!'!L@P(#+P,`0@$" -M(0`$F@,#,P``B`0/-``+`"(`##4`+V%T-``,*&%T,P`&`0:`+C,@9VEV97/? -M!H!O=F5R=FEE=_,"`*``!+L%$&%Q!3!W:&^1`A0J[`B%7W)E860N,RP0``&[ -M"`T1`%%?9&ES:Q8``GX'`X0)`3X``QP``)D`$'9?`0*W`F%E9"!C86R)!Q!S -MU`9!;F-E``&I`5 -M"`"X!!,B?P(R+F@BJ0`R:&4*7PP0(+`)`'4!`!0`!.D&`W((`G\"-&UOFEP/@$Q:6]N -M&`%=8GII<#(6``1D`4TO3%I7'0"B;'IM82P@;'II\+`OH#`*D" -M`&@1`HT``88!`MH`#\@#"F$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0%!`?. -M``]9`P`*%@,S5VAE`P(`&@T#U`(2<^8%87)E0<#[A("*P`A(&(W"7%R96%D86)L``8` -MC`H!#``!+`L"U!``:``".P!"96%C:#T!(W9E/10"0P!0:6YD97"J`"5N="(! -M`$0-``\/$&-"!1)O;`T&-0I4(%=I:VE2##!I;F?)`#!H;W?X``&S`Q!DK0$# -MV@`"*@$A3VX_"`#W#`)X!@#S#@!0!@/-``%P`%-L=V%YD``2<0`BT`",T`%&]S!'`I+"!I="!W<`!0(&=E="#2$@%="@"D!#<@ -M26YN`#(L(&F"%0&>``%1`0.;`")E;LD!!RT``'P`"W$`*&1E$0`#Q@(1+.4) -M`H```(T.`)8!`!8!`$``,&%G8?,/`5\*D6-O7L#$7`U`&)A=&5V97)X%Q%S\```[@ -M!#%FQF4@ -M6]U(&1O;B=TJ```M@#P)&EC -M:71L>2!I;G9O:V4@82!P87)T:6-U;&%R(&9E871U!E('-O;64@=71I;&ET>3X`!8P``+$! -M\09P2!D8737`%9UP"`&$#`2L`,VEN("X`0!V``*4`0```P&3``7+`0#3``.C`0:`!3%W86Z(`!!T-@0# -M-@(!6P,`'P$`N@!09&ES:RQP`P/$`;EC;VYV96YI96YC9<`!`(D`,&UA:WD` -MD&ES(&5S<&5C:6X$`=`!`JH!\P=.;W1E.B`B<&%X(&EN=&5R8VAA;F=EGP43 -M(KD"(&QL/`$"Z`(09+X!`/T%`8T&D"P*("`@9&5S<*(``&P$`)8`\`,@;F%M -M92!S87ES+@I214%$344N``?H!N$@8G5N9&QE+@H*475E<_H"H#\@($ES`<``$D!`)()`"<`4"H@97AA20!`8$(&YDT`(Q9G5L+P(&10`0+T,*`84!$6'C`5%A8W0@`0-)`#!C;VY#`O`".B`@5F%R:6]UP``7P%Q -M875T:&]R<\`%`1\&`?("`DT'$`J(!E!T;W`M;`P$`W8%`#`'`4$`$&GD!@FV -M`B)I;M8$`'$+`.L%!+T"\`).15=3("T@:&EG:&QI9VAT2XS30``[P0R92`B -M:P,%JP`!)``4(@L+62!C;&%S1``!'PE&;F%L`8`>P`(2PE`:&%R9!8,`3`& -M!%L!`4<``(X!86UO9&5R;H\``.@!`+P'<"!V87)I86Y("0!$!+%M86YU86P@ -M<&%G93@``#$.)')EI@``G@`!'0-7)V1O8R>]!9!I;@IA(&YU;6+R#!=FD0<# -M'@'7+@H*66]U('-H;W5L9*0+`"@!,6-O<'8&0&-O;6V>"`#.#1,B!0XR+F@B -MJ0`R:&4*7PQ!(&-O9'4!`!0`!.D&`W((`G\"-&UO2X`L2`H8FEG+65N9&EAU!%C;&ET -M=&QE$0`"^@#Q`DE33SDV-C`@0T0M4D]-(&EMMP*`*'=I=&@@;W#+`\!A;"!2 -M;V-KU`P$3`%HW+5II<"8`V$UI8W)OFEP,A8`!'P!32],6E<=`*)L>FUA -M+"!L>FEP$P,O>'HC```9-!0`"0@!```*`IP0!3H!`'4$#P8!`@*J`P._`P*\ -M`@\?`Q@P(G)EH`U18W1E9")'`P)/`,0L('=H:6-H('=I;&R*``%6``:0`"!E -M>"T4``("$`I;"0-I`@)K%`!##A!IE@4G87C*`B`@*'T'`30$`(0!`T0$`/0# -M8"P@971C*>\+`OH#`*D"`&@1`HT``9L!`MH`#\@#"F$B;F5W8R*;`P$S`"=S -M:+```1(`#T8#8P0%!`?.``]9`P`*%@,S5VAE`P(`OP@#U`(2<^8%87)EP`! -MAPD!*Q4"2@P#"@,0;?8-$&EY!P/N$@(,`B$@8C<)07)E862/&`.X%`$,`!!A -M#`$"U!``:``".P`199P6`#T!(79E_!03>4,`M6EN9&5P96YD96YT(@$`1`T! -M>1D`0@42;VP-!K`+#V0:________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M__________________________________]H4&QL;W=I410``/$F;F<@8F5F -M;W)E(&5V86QU871I;F<@=&AE(&%R8VAI=F4Z"B`@*B!U=65N8V]D960@9FEL -M97,4``$*`/$"('=I=&@@4E!-('=R87!P97(;`/$!9WII<"!C;VUPFUA+"!L>FEP+"!A;F0@>'HC```9 -M-!0`]0<*5&AE(&QI8G)A"!I;G1E&-E<'0@9F]J`/$'("!E;G1R:65S('1H870@.`?$#;F%M97,L($%#3',L(&5T8RDND@"P -M3VQD($=.52!T87)=``2I``+*`/$$;V-T970M;W)I96YT960@8W!I;S4`ME-6 -M4C0@(FYE=V,B%0`G`'@G;71R964G -MNP!X25-/.38V,!,`6C2!S=')E86WM`>!S>7-T96TN("!4:&5R92P`\01N;R!D:7)E8W0*("`@`>-R86YD;VT@86-C97-S -M+GD`!I<`\@)I'!L -M86EN:6YGB0`P:&]W^``"]0``C@0#+``"*@$A3VZJ`!PL`P$#V0("<`!`;'=A -M>48!`-T!\@%E9"!A=71O;6%T:6-A;&QY1P"P22=V92!A='1E;7#$`^!T;R!M -M:6YI;6EZ92!S="L`L"!L:6YK('!O;&QUN`'A+B`@268@>6]U(&1O;B?L`0"V -M`/$":6-I=&QY(&EN=F]K92!A('#K`"!U;#<$(&5A60)`("AS=2\!&7,<`A!A -MZ0`'+0`'[P4`@`$"F0%P*2P@:70@=W``X"!G970@<'5L;&5D(&ENI`0W($EN -M;@`W+"!IG@`!40$#FP`B96[)`07L# -M$7`U`-%A=&5V97(@8FQO8VMS\``0:%<%(6ETH0!!66]U2X'<70@82!T:6U7`W%O8!(71O(@`%H0!A="!O;F-EA0`A3VZ0`QMEPP`" -MY`(R<')O.@$!A0%18W1L>2W,``!(!E)U='!U=.\"`&`$\0-O8FIE8W0M2!F)M96UO?<"!8P``0`" -M\05R;W9I9&4@96%S>2UT;RUU8<``J,!!H`%,7=A;H@`$'0V!`5%`0!@``'Z"0".!S!S:RQ. -M`P-^!KEC;VYV96YI96YC9<`!`(D`,&UA:WD`D&ES(&5S<&5C:6X$`=`!`JH! -M`#H(,#H@(I,*#KL*$R*Y`B!L;#P!`N@"`*4'`!$#`L$%0"P*("#,!Q!PWP`` -M;`0`E@`0(',*T"!S87ES+@I214%$346[!@?H!N$@8G5N9&QE+@H*475E<_H" -MH#\@($ES7!1`GH@1`9W)A;18"=&%R+C54 -M`0CQ!`4^$A%S8P0Q<&]PY0\#G`$`>`8`>P`(2PE`:&%R9!8,`3`&!%L!`4<` -M`(X!86UO9&5R;H\``.@!`+P'<"!V87)I86Y("0!$!+%M86YU86P@<&%G93@` -M`#$.`,X4`OH!`)X``1T#5R=D;V,GO060:6X*82!N=6UB\@P79I$'`QX!URX* -M"EEO=2!S:&]U;&2D"P`H`3%C;W!V!D!C;VUMG@@`N`03(@4.,BYH(JD`,FAE -M"E\,02!C;V1U`0`4``3I!@-R"`)_`C1M;W*C`E)S+B`@4(H)LVQE="!U=H+ -M`#L'`2,)"=H1`,$",&5C=)D#$60Y"0,<`@>F%@"E`0!0!0)!%0:J"R8@*`0+ -M`%L5#"`6`1````4+`;X+$G,W`E)S<&%R\6`2T5`A``#XH,`P4P`T&-P:6\N-2P@;71R964)``!O`/(*=&%R+C4@<')O=FED -M92!D971A:6QE9"!I;E(`D&EO;B!A8F]U=$T`('-EN`"#<&]P=6QA3`1!F+`"A#0#46-H86YG -M?@$W;6%T(0"P;V-T970M;W)I96X!`P!@`@$>`*%35E(T($%30TE)=`(!%``" -M4P`/,@`%84)I;F%R>2X`P"`H8FEG+65N9&EA;J(!8VQI='1L91$``OH`\0)) -M4T\Y-C8P($-$+5)/32!I;;<"@"AW:71H(&]PRP/`86P@4F]C:W)I9&=E10!B -M2F]L:65T*0$![P$"20`U6DE0"0$#0`#P"G5N8V]M<')EB,``!DT%``)"`&58V%N(&-R96%TSP`!=00/!@$"`J\!`[\# -M`KP"#Q\#&,$B,H"4B`H9F]R-`0` -MA`$#,P0`]`-Q+"!E=&,I+F\!`/H#`*D"!B($`1<``MH`#\@#"F$B;F5W8R*; -M`P$S`"=S:+```1(`#T8#8P0%!`);`0&)``]9`P`*%@,S5VAE`P(`V`(#U`(2 -M<^8%87)EF4@P,1<#4` -MT6%T979E6QE(&%P -M<')OR`,`R0@"^@#@=&\@:&%V92!M=6QT:7`E``-3!`(!!`"Y"%4@;W!E;IX` -M4"`@8G-D(P2!B=6@-$B`D"`!E``!Z``#!`85A -M('-O8VME=#X#27=I#B)A -M;N@"`*4'`!$#`KH.0"P*("#,!Q!PH@``;`0`E@`!I@[1('-A>7,N"E)%041- -M11(&!Q0'T6)U;F1L92X*"E%U97/Z`J`_("!)3``!(`1!HN`(09K$/,VYG;U@')B`@+`"`(&1E=F5L;W`\ -M!0@9$02Z$0&L"!`LH@0`<0``.@`A;FM=`0!=``='`$!M86EL!P(P;&ESOQ`! -MG0`05)D!`.41`.!L30',Z(%,R`U1S;6%L;!4`!#X!`%(# -M(6%T'`@@;6'F!"!N9-`",69U;"\"!D4`$"]#"@&%`1%AXP$T86-T>Q-P9&5M -M;VYS=#D5(&YG/@``@`4&5`(#20`P8V]N0P)A.B`@5F%R[A-@:71E;7,@,P$` -MUP(B;64V%3)I'2(`"%P=6<0,"`B8S0& -M$2(D`P`X#"EO;$T`(`H*X0@&ZP,!*0$`%@D`C@$/;0$!`+`,$'4]$P(0%R4* -M)[P`$R>M``,D!`"3``!.`/``+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C_P`` -M`@`0+60"`)\`!*@``-D."*($$BP:#@#7"P!9"U%Y(&UA:?8!(V5RK@$%<``D -M:6YD`($N:"YI;@H)+?0'(&QA5@\$NP`%A0`#M0!P"@I'=6ED9;8"$T0.&`*! -M`0/2`0)U``#S`0-3#Q`Z&@D"N`0A+C'!#`!A#`$W`0`]!@-X$P(A``2:`P,S -M``"(!`\T``L`(@`,-0`O870T``PH870S``>M`Q$SM@L`$!20(&]V97)V:65W -M\P(`JP`%P`L`<04P=VAOD0(4*J0*A5]R96%D+C,L$``!^`@-$0!17V1I2XSHQP#R*71H -M92!A=71H;W)S('=I=&@@86YY('%U97-T:6]N'2(`#%P=70I`/D#(F-M86ME(B!B=6EL9"!T;V]L30`"5@$&-0$! -M*0$Q(&EN3`$/;0$!,&%R91`"$F3:`35E"B>\`!,GK0`#9P$`DP``3@#U`2YA -M;2P@86-L;V-A;"YM-"SA`$!E+F%C_P```@`2+50`)'1OJ```(`&`9&ES=')I -M8G5!`;(L(&]N;'D@;F5E9'P`,6UA:?8!(V5R7`$%<``D:6YD`/(#+F@N:6X* -M"2T@=&5M<&QA=&5S9P`18C0"`68!$V6U`'`*"D=U:61EM@*"1&]C=6UE;G2! -M`0#%`3)A;&QU``#S`?4*('-Y`?$#+@H*66]U('-H;W5L9"!A;'-O(@(! -M3``Q8V]P=@8R8V]M6P%#:6X@(KT",BYH(JD`@&AE"G-O=7)C+P`19'4!`!0` -M!.D&`YH#`G\"-&UO<$",&5C=)D#$635``,<`@7"!A!F+``!MP91*B!'3E5U`0*Z`28@*+D! -M`!H`06QO;F=5`F)N86UE'1E;J+``-J`0`9`]$J -M(%!/4TE8('5S=&%R6P`"$``P<&%X20,B97)9!P-X`@@` -M`0H``EP)HE)032!WFEP/@$Q:6]N,`!=8GII<#(6``1D`4TO -M3%I7'0"B;'IM82P@;'IIU`P#P!`![``.?`0![``&'"0&C``)*#`,*`Q!M -M:P@0:7D'$6$O"0,K`"$@8C<)<7)E861A8FP`!@","@$,``$L"P($`0!H``([ -M`$)E86-H/0$A=F5S`Q-Y0P!0:6YD97"J`"5N="(!`!@)``\/$&-"!1)O;`T& -M-0I4(%=I:VE2##!I;F?)`#!H;W>;#`&S`Q=DE@H"*@$A3VX_"`#W#`)X!@,# -M`03-``%P`$!L=V%Y1@$`W0$J962*"`)'`'!))W9E(&%T+0T`C`<`P0^0:6YI -M;6EZ92!S#@T28U((07!O;&R4#5$N("!)9O4(4&1O;B=TJ`"097AP;&EC:71L -MV0EB=F]K92!A^@\18W\*,69E830+,"AS=2\!!?L*`*D`("!A00`!)Q`"+0`( -MS0`4;_D(<"DL(&ET('=P`'$@9V5T('!UG`T0:7H+1R`@26YN`#``%1 -M`0.;`")E;LD!!RT``#X`"W$`*&1E$0`#Q@(1+/```H```(T.`)8!`!8!`$`` -M(&%G`PX"4`.18V]RF5H!P*(`5!A;&QY+78``#,,`/<($6F'!@"$`'!E;G9IP,1<#4`T6%T979E2W,`))E9"!O=71P=73O`@!@!/$#;V)J96-T+7-T>6QE(&%P<')OR`,`0Q(" -M^@#@=&\@:&%V92!M=6QT:7`E```A!1!V$@-`4X.``P1$2(A`0!: -M""`L(E`(H"P@8V%P86)I;&D2%`8#`0"_``'Q``+S#P$_#@CV!0&7`8`@:6YD -M:79I9&P.`&@%$6E""`![`!)B0@`$K`4`-@$A=&^L#3!D8737```%#A$ZP0(! -M+@$"R`D`P@`28>P"`&$#`2L`,VEN("#U%F -M:7)S=)("`*8!$6%P$A%O61$`]@`6+G0``]D#`J#B)A;N@"`*4' -M!C0*0"P*("#,!Q!PYP$`;`0`E@`!I@YS('-A>7,N"B05$6:X#01Q%K0@8G5N -M9&QE+@H*41$6H#\@($ES%E2!F -M:6QE+B`@66]U(&-A;B!A;'-O(')E860@86X@96YT6]U('=A -M;G1$`!)T70`2+ST``&``,&EE'1E;F1E9#@!`B(`D"P*("`@9&5S<-\`0'=H8726`/`#(&YA;64@8$(&YDT`(Q -M9G5L+P(&10!1+VUI;FF%`1%AXP%186-T('-@`+`@9&5M;VYS=')A=+'!L@P(# -M+P,`0@$"(0`$F@,#,P``B`0/-``+`"(`##4`+V%T-``,*&%T,P`&`0:`+C,@ -M9VEV97/?!H!O=F5R=FEE=_,"`*``!+L%$&%Q!3!W:&^1`A0J[`B%7W)E860N -M,RP0``&["`T1`%%?9&ES:Q8``GX'`RH)`3X``QP``)D`$'9?`0*W`F%E9"!C -M86R)!Q!SU`9!;F-EP$2+8($4W,N-2!D5@(`G@419?L#`/(`Q&UA=',@``&I`5"`"X!!,B?P(R+F@BJ0"`:&4*`D09BP``;<&42H@1TY5=0$"-0(F("@$"P`: -M`$%L;VYG50(`K0LB+``-J`0`9`]$J(%!/4TE8('5S=&%R -M6P`"$``/B@P#!R$`L&]C=&5T+6]R:65N`0,`8`(!'@"A4U92-"!!4T-)270" -M`10``E,`#S(`!6%":6YAFEP,A8`!&0!32],6E<=`*)L>FUA+"!L>FEP$P,O -M>'HC```9-!0`"0@!```*56-R96%TSP`!=00/!@$"`JH#`[\#`KP"#Q\#&#`B -M&-E<$`% -M$`I;"0-I`E$@=&AA=$,.,6ER95$``0$0`?P(-F5A;;4%`A$+<"X@(%1H97(T -M$2`@;M82,7)E8S`1`]\(`),$02!I;BVW#X(@;6]D:69I8^4,\@%OP`!APD!HP`"2@P`31%`:7)E;?8-$&EY!P/N$@(K`"$@ -M8C<)<7)E861A8FP`!@","@$,``$L"P+4$`!H``([`$)E86-H/0$A=F5S`Q-Y -M0P!0:6YD97"J`"5N="(!`$0-``\/$&-"!1)O;`T&-0I4(%=I:VE2##!I;F?) -M`#!H;W?X``&S`Q!DK0$#V@`"*@$A3VX_"`#W#`)X!@#S#@!0!@/-``%P`%-L -M=V%YF4@'!L:6-I#16":6YV;VME(&'Z#Q%C?PH# -MSA$@("C2$"4@8?L*`*$!("!AZ0`!)Q`"+0`(S0`4;W,$<"DL(&ET('=P`%`@ -M9V5T(-(2`5T*`*0$-R!);FX`,BP@:8(5`9X``5$!`YL`(F5NR0$'+0``?``+ -M<0`H9&41``/&`A$LY0D"@```C0X`E@$`%@$`0``P86=A\P\!7PJ18V]RP,1<#4`8F%T979E2X'$'2B%R%I;5<# -M<6]R(&UM87`I`0!>$P'Y%@([`P"V`A!GPA<0:2(3`2(`!:$``.,3(6-EA0`A -M3VZ0`QMEPP`"Y`(R<')O.@$!A0$`FA"9"!O=71P=73O`@!@!/$# -M;V)J96-T+7-T>6QE(&%P<')OR`,`@0L"^@#@=&\@:&%V92!M=6QT:7`E```A -M!1!V$@-`:89`@4.%CHN`0+( -M"0#"``]D&O__________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M________________________:E`*("H@3U(4``#XNFX@2!I -M;G9O:V4@82!P87)T:6-U;&%R(&9E871U!E('-O;64@=71I;&ET>3X`!8P` -M`+$!\09P2!D8737`%9U -MP"`&$#`2L`,VEN(""!I;G1E7,N"E)%041-15``1"!L:6)M`=%B=6YD;&4N"@I1=65S^@*@/R`@ -M27-S=65S/U(`UBH@:'1T<#HO+W=W=RXX`$`N;W)GDP``2`$0:+@"L&9O`<``$D!0'-U8V@G`%`J(&5X84D`0',Z(%,R`U1S;6%L -M;!4`!#X!`%(#(6%T'`@@;6'F!"!N9-`",69U;"\"!D4`$"]#"@&%`1%AXP%1 -M86-T('-@`+`@9&5M;VYS=')A=+P`"-E)ZT``V7-T96TZ&@D"N`0A+C'! -M#`!A#`$W`0,O`P`+``(A``2:`P,S``"(!`\T``L`(@`,-0`O870T``PH870S -M``8!!B$N,[8+$'-E"H!O=F5R=FEE=_,"`*``!0H,`'$%,'=H;Y$"%"JD"H5? -MPH"MP(2 -M9:`,`%L$$'/4!A!N2PT`U@(`DP``=0``%P(`^00!<0`!<0H(EP!S96YT=H+`#L'`2,)"=H1`,$",&5C=)D#$60Y"0,<`@5X"1!F!A(! -MMP91*B!'3E5U`0+4!B8@*`0+`!H`(VQOO`4`K0LB+``-J -M`0`9`[$J(%!/4TE8('5S=+`1!!``#XH,`P%\``(Q`+!O8W1E="UO\!`DD`-5I)4`D!`T``('5N -M3@D`[!,`UA!@FEP/@$@:6]/$WTJ(&)Z:7`R%@`$?`%-+TQ: -M5QT`HFQZ;6$L(&QZ:7`3`R]X>B,``!DT%``)"`$```H"G!`%.@$`=00/!@$" -M`J\!`[\#`KP"#Q\#&#`B,H"("`H?0?P(-F5A;;4%`A$+!8@4 -M0&ES(&[6$C%R96,P$0/?"`"1`D$@:6XMMP^"(&UO9&EF:6/E#)%O`3AN97>U`P#P -M!`#]`@.?`0![``&'"0$K%0)*#`,*`Q!M]@T0:7D'`^X2`BL`(2!B-PE!FEP,A8`!"8`32],6E<=`/\#;'IM82P@ -M;'II<"P@86YD('AZ(P``&304`/$R"E1H92!L:6)R87)Y(&-A;B!C&-E<'1_`/$*"B`@ -M("!E;G1R:65S('1H870@$ -M`?$#;F%M97,L($%#3',L(&5T8RDND@"P3VQD($=.52!T87)=``2I``+*`/$$ -M;V-T970M;W)I96YT960@8W!I;S4`ME-64C0@(FYE=V,B%0`G`'@G;71R964GNP!X25-/.38V,!,`6C0`&EP#R`FES(&1E$N("!)9B!Y;W4@9&]N)^P!`+8`\0)I8VET;'D@:6YV;VME(&$@<.L` -M('5L-P0@96%9`D`@*'-U+P$9``%1`0.;`")E;LD!!RT` -M`'P`"W$`*&1E$0`#J@`1+/```H``(FYEC@(`%@$`0`!B86=A:6YS1P*@8V]R -MP,1<#4`T6%T979E2!B=69F97(@)`@`90`$<@&%82!S;V-K970^`TEW:7-H -MN@3`P"`,,)`2L`,VEN("0"0:7,@97-P96-I;@0!T`$"J@$`.@@P.B`BDPH.NPH3(KD"(&QL/`$" -MZ`(`I0<`$0,"P05`+`H@(,P'$'#?``!L!`"6`!`@7,N"E)%041- -M1;L&!^@&X2!B=6YD;&4N"@I1=65S^@*@/R`@27-S=65S/U(`UBH@:'1T<#HO -M+W=W=RXX`$`N;W)GDP``2`$0:+@"@V9OB!$!GF-%#A)B!P`2>`<``$D!`)()`"<`4"H@ -M97AA20!`8$(&YDT`(Q9G5L -M+P(&10`0+T,*`84!$6'C`5%A8W0@T/4'1O -M<"UL#`0#Q0P`,`0&";8"(FENU@0`=`P`ZP40<],-\`4@*B!.15=3 -M("T@:&EG:&QI9VAT'2(`")P==8-(")C-`81(B0#`#@,*6]L -M30`@"@K>!P;K`P$I`0`6"0".`0]M`0$`^0<@=7/="@#:`31E"B>P`"-E)ZT` -M`V!Q(M@@13``$=`U`=\!`DD`#QX78P\+%P#3 -M36EC4P`T&-P:6\N-2P@;71R964)`/(. -M86YD('1AP$R+F@BJ0"`:&4*2!E2QN``/2`>`@875T;VUA=&EC86QL>68!065C='.H``#5``,<`E!O -M;&QO=Y,!$&8L`*!S.@H@("H@1TY5^`$`J`!6;6%T("BY`0`:`$%L;VYG50)B -M;F%M97,L$`!3;&EN:R`1``"T`5)S<&%R'1E;J+``-J`1%S2P"W4$]325@@=7-T87(0 -M`.%P87@@:6YT97)C:&%N9WX!-VUA="$`L&]C=&5T+6]R:65N`0,`8`(!'@"A -M4U92-"!!4T-)270"`10``F,`#S(`!6%":6YAB,``!DT%``)"`&58V%N(&-R -M96%TSP`!=00/!@$"`NP"`[\#`KP"#Q\#&,$B,H"4B`H9F]R-`0`A`$#,P0`]`-Q+"!E=&,I+F\!`/H#`*D"!B($ -M`1<``MH`#\@#"F$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0%!`);`0&)``]9 -M`P`*%@,S5VAE`P(`V`(#U`(2<^8%87)EF4@7L#$7`U`-%A=&5V97(@8FQO8VMS\```[@2X' -M<70@82!T:6U7`P!K"S%M87#X`C!E;G21!@/0`@%1`T!G:79EY@$A=&\B``6A -M`&%T(&]N8V6%`"%/;I`#&V7#``+D`C)P`%`@(&)S9",'(75SO`$`/06#;B!I -M=',@(D#E`!(BO01&2!F4X.475S92`B(0$`6@@@+")0"'`L(&-A -M<&%B00`!]@("9@81954"`?$`864@05!)P" -M`,D*`2L`,VEN("#U%F:7)S=)("`*8!(&$@ -M0P41;U`'`/8`%BYT``/9`P*G`0"_``*<`0&%``:X`0!V``*4`0!*`P&3``(Q -M#R!L>60!`,P``*,!!H`%,7=A;G\%$G0=#P-%`0!@```:!!!TC@!L3 -M0',Z(%,R`U1S;6%L;!4`!#X!`%(#(6%T'`@@;6'F!"!N9-`",69U;"\"!D4` -M$"]#"@&%`1%AXP$T86-T>Q."9&5M;VYS=')*#0`.`R=O9EX!`TD`,&-O;D," -M83H@(%9AP``7P%C875T:&]R:1``EPT!\@(`P1,2+NT/4'1O<"UL#`0#Q0P`,`0&";8""',5`.L%`>X/\`4@*B!.15=3("T@:&EG:&QI9VAT\`!,GK0`#)`0`DP``3@#P`"YA;2P@86-L -M;V-A;"YM-`D-`^T`,"YA8_\```(`$"VB`@"?``2H``#9#@BB!!(L&@X`UPL` -M60L0>\%1FYA;'.=`!)S -M/@MA:6YS:6=H$08(F0<1)V<"!#<``&@1,'5C=+(#`*@`,&]P92L%`#0,"1X' -M$BU8"0]D&O__________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M________________________5E!C="!S85<4``#T4VUP;&4@9&5M;VYS=')A -M=&EN9R!U4$`,6EN'2(`#%P=70I`/D#(F-M86ME(B!B=6EL9"!T -M;V]L30`"5@$&-0$!*0$Q(&EN3`$/;0$!,&%R91`"$F3:`35E"B>\`!,GK0`# -M9P$`DP``3@#U`2YA;2P@86-L;V-A;"YM-"SA`$!E+F%C_P```@`2+50`)'1O -MJ```(`&`9&ES=')I8G5!`;(L(&]N;'D@;F5E9'P`,6UA:?8!(V5R7`$%<``D -M:6YD`/(#+F@N:6X*"2T@=&5M<&QA=&5S9P`18C0"`68!$V6U`/($"@I'=6ED -M92!T;R!$;V-U;65N=($!`,4!,F%L;'4``/,!]0H@'!L@P(#+P,`0@$"(0"#('!R;V=R86TS`$]C<&EO-``+`"(`##4` -M+V%T-``,*&%T,P`'K0/P!#,@9VEV97,@86X@;W9E2!A``"/ -M`&<@)V1O8R>]!;!I;@IA(&YU;6)E2QN``5H`S!U=&^3!@#_`A!Y9@$P96-TF0,19-4``QP"!<(&$&8L``&W -M!E$J($=.574!`KH!)B`HN0$`&@!!;&]N9U4"8FYA;65S+!``4VQI;FL@$0`` -M8P!A@``0H``EP)HE)032!WFEP/@$Q -M:6]N,`!=8GII<#(6``1D`4TO3%I7'0"B;'IM82P@;'IIU`P#P!`![ -M``.?`0![``&'"0&C``)*#`,*`Q!M:P@0:7D'$F$)`0(K`"$@8C<)<7)E861A -M8FP`!@","@$,``$L"P($`0!H``([`$)E86-H/0$A=F5S`Q-Y0P!0:6YD97"J -M`"5N="(!`!@)``\/$&-"!1)O;`T&-0I4(%=I:VE2##!I;F?)`#!H;W>;#`&S -M`Q=DE@H"*@$A3VX_"`#W#`)X!@,#`0/X``&("5!A;'=A>48!`-T!*F5DB@@" -M1P!P22=V92!A="T-`(P'`,$/D&EN:6UI>F4@@M'("!);FX`-RP@:9X``5$!`YL`(F5NR0$'+0``/@`+<0`H -M9&41``/&`A$L\``"@```C0X`E@$`%@$`0``@86<##A%T\0F18V]RP,B:67-#P%O`P/G"C%D=6.Y!5%E('-I>H,1`H@!4&%L -M;'DM=@``,PP`]P@1:8<&`(0`<&5N=FER;V[7`C%S('>0`P&@`A!MV`$3`!,@%1``:A``"@$`/06#;B!I=',@(D#E -M`!(BO0012!F@``S0*%82!S;V-K970^`TEW:7-HN@1$!L30',Z(%,R`U1S;6%L;!4`!#X!`%(# -M`Q,9(&UAY@0@;F30`C%F=6PO`@9%`%$O;6EN:84!$6'C`31A8W1[$P]D&O__ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________:%!C:&EV94<4``#P/2!W:71H;W5T"B`@(&9I0#P*FES(&5S<&5C:6%L;'D@96%S>2X*"B`J($YO=&4Z(")P87@@:6YT -M97)C:&%N9V4@9F]R;6%T(B!I<^```#,`\P!A;B!E>'1E;F1E9"!T87(B`)`L -M"B`@(&1E7,N"E)%041-12X`1"!L:6(3 -M`=%B=6YD;&4N"@I1=65SK@"@/R`@27-S=65S/U(`UBH@:'1T<#HO+W=W=RXX -M`$`N;W)GDP``2`$Q:&]MIP"`(&]N9V]I;F6H`)V%T:0`K871H`&ES:6UP;&6U`$!T;V]L,P$` -M0``#`@!R>F-A="P@8@<`$G@'``!)`4!S=6-H)P!0*B!E>&%)`$!S.B!3,@-4 -M2!F:6YDT`(Q9G5L+P(&10!1+VUI;FF% -M`1%AXP%186-T('-@`*$@9&5M;VYS=')A-04`#@,G;V9>`0-)`#!C;VY#`O`" -M.B`@5F%R:6]UP``7P%Q875T:&]R<\`%42!A;GD@\@(``050+@H*5&B=`3!P -M+6P,!`-V!3!O'2(`#!P=71>`C`@(F,T!A$B)`-I -M9"!T;V]L30`"5@$&ZP,`%`=!'!L@P(#+P,`0@$"(0`$F@,#,P`` -MB`0/-``+`"(`##4`+V%T-``,*&%T,P`&`0:`+C,@9VEV97/?!H!O=F5R=FEE -M=_,"`*``!+L%$&%Q!3!W:&^1`A0J[`B%7W)E860N,RP0``&["`T1`%%?9&ES -M:Q8``GX'`Q<(`3X``QP``)D`$'9?`0*W`F%E9"!C86R)!Q!SU`9!;F-EP$2+8($4W,N-2!D5@(` -MG@419?L#`/(`Q&UA=',@``&I`5=H+`#L'`2,)@&%U=&]M871I_P(0><$",&5C=)D#$60Y -M"0,<`@5X"1!F+``!MP91*B!'3E5U`0(U`B8@*`0+`!H`06QO;F=5`@"M"R)S -M+!````4+`;X+$G,W`E)S<&%R`*%35E(T($%30TE)=`(!%``"4P`/,@`%84)I -M;F%R>2X`P"`H8FEG+65N9&EA;J(!8VQI='1L91$``OH`\0))4T\Y-C8P($-$ -M+5)/32!I;;<"@"AW:71H(&]PRP/`86P@4F]C:W)I9&=E10!B2F]L:65T*0$! -M[P$"20`U6DE0"0$#0``@=6Y."3!R97/3!G!OU`P$3`%HW+5II<"8`V$UI -M8W)OB,``!DT%``)"`$` -M``I58W)E873/``$M"0\&`0("J@,#OP,"O`(/'P,8,")R9:`-46-T960B1P," -M3P#$+"!W:&EC:"!W:6QLB@`!5@`%R@%A(&5X8V5P0`40"EL)`VD"42!T:&%T -M0PX0:98%)V%XR@(@("@6!0$T!`"$`0-$!`#T`V`L(&5T8RGO"P+Z`P"I`@8P -M$`&&`0+:``_(`PIA(FYE=V,BFP,!,P`G0`&@`0`L!!0 -M97-I9VZP$D)O(&)EO@(`0`0!7@$X;F5WM0,`\`0`_0(#P`!APD!HP`" -M2@P`31%`:7)E;?8-$&EY!P/N$@(K`"$@8C<)<7)E861A8FP`!@","@$,``$L -M"P+4$`!H``([`$)E86-H/0$2=MT3$WE#`%!I;F1E<*H`)6YT(@$`1`T`#P\0 -M8T(%$F]L#08U"E0@5VEK:5(,,&EN9\D`,&AO=_@``K03`*T!`]H``O<3(4]N -M/P@`]PP">`8`\PX`4`8#S0`!<`!3;'=A>7-S""IE9(H(`D<`<$DG=F4@870A -M%0",!S!T;R`A$'!M:7IE('-TM0@"4@A0<&]L;'4B!P;D%$%D;VXG[`%P97AP -M;&EC:0T58&EN=F]K9;P2`>L``7\*`\X1("`HTA`E(&'["@"A`2`@8>D``2<0 -M`BT`",T`%&_Y"'`I+"!I="!W<`!!(&=E=!D3`5T*`*0$-R!);FX`,BP@:8(5 -M`9X``5$!`YL`(F5NR0$'+0``?``+<0`H9&41``/&`A$LY0D"@```C0X`E@$` -M%@$`0``P86=A\P\`7L#$7`U`-%A -M=&5V97(@8FQO8VMS\```[@!#%FQ6QE(&%P<')OR`,` -M@0L"^@#@=&\@:&%V92!M=6QT:7`E```A!1!V$@-`P",B!O9BL`,VEN("2!I -M;G9O:V4@82!P87)T:6-U;&%R(&9E871U`<``$D!`/X&`"<`4"H@97AA20!`4$`(&EN^``(M@(B:6X#"``0""!F:34!`'P`\`LJ($Y%5U,@+2!H -M:6=H;&EG:'1S(&]F(')E8P8"5&-H86YGH`*P0T]064E.1R`M('<3!P"Y"&)C -M86X@9&^?`#-T:&DI`*!)3E-404Q,("T@T`'2(`")P=28)<2)C;6%K92(D`P"D -M"2EO;$T``E8!!NL#`)0`07,@:6Y,`0]M`0$P87)E3@(29-H!-64*)[P`$R>M -M``,D!`"3``!.`/4!+F%M+"!A8VQO8V%L+FTT+.$`0&4N86/_```"`!(M5``D -M=&^H```@`0BB!+`L(&]N;'D@;F5E9,4($'G*!0'V`2-E%7W)E860N,RP0``#1 -M!1UE$0!17V1I -M=&%R+C54`0CQ!$%A8F]U4P4@"`"X!!,B -MO0(R+F@BJ0"`:&4*2R"```[!P$C"8!A=71O;6%T:?\"$'G!`C!E8W29`Q%D80T# -M'`(%>`D09BP``;<&42H@1TY5=0$"-0(F("@$"P`:`$%L;VYG4`9B;F%M97,L -M$```!0L3(!$``&,`4G-P87)S?`(A`@@;W#+`\!A;"!2;V-KFEP,A8`!'P!32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC -M```9-!0`"0@!```*56-R96%TSP`!+0D/!@$"`JH#`[\#`KP"#Q\#&#`B&-E<$`%`+D% -M!&D"`M<1`$,.$&F6!2=A>,H"("`H%@4!-`0`A`$#,P0`]`-@+"!E=&,I[PL" -M^@,`J0(&(@0!FP$"V@`/E@,%`<@#82)N97=C(IL#`3,`)W-HL``!$@`/1@-C -M!`4$`EL!`8D`#UD#``H6`S-7:&4#`@"_"`/4`A)SY@5A?P(-F5A;;4%`A$+02X@(%1`%%-I4,`4&EN9&5PJ@`E;G0B -M`0!$#0'E%@!"!1)O;`T&L`M4(%=I:VE2#`,,$S!H;W=1#P*F!P!."`/:``N@ -M%03\!`#S#@!0!@/-``%P`$!L=V%Y1@$`W0$J962*"`)'``_0%__@"?H#$&,W -M!@`%&,)A=&5V97(@8FQO8VO5"@#N!S`@:70(!D(@66]UYQ,!Q`U`8F%C:T`# -M,69R93T/,'!A2X'<70@82!T:6U7`W%O2W,``"."5)U='!U=.\"`&`$H&]B:F5C="US='G@ -M&4%P<')OR`,`^10"^@!0=&\@:&$Y%D!U;'1IPQ,$J0`"`00`N0A5(&]P96Z> -M`!0@]`\A=7-U!Q%I(0AC:71S(")`/``2(KT$$',3&P7J!`,<`'`@:71S96QF -M4P$`?000+P(/8'1E;B!U7,N"@`!`/^)`#L7#Y\!30\`'@M1-S$Q-S4`'F$Q-3$U-3(`'B\U,0`> -M_U771F5B(#`Y+"`R,#$S.H<*D2`S+C$N,B!R93(3GF0*"DIA;B`R."D`(2=S -MJPM`=V5B!A(N3``N,3-,``%U`!LQ=0`/*0`&%S`I`&%$ -M96,@,#=2`$`R.B!)4AL!"`P("@4#T!0`[PP991H,`)T%`ML-`DX8`9`(A"`* -M3F]V(#$Q5``@062V&P:L(H-?7TU!0T]36!<-`(('.&EN(,01!-D/(G)EJ08` -M)P4`N`P2:P@','-T;TL.`+@B?PI/8W0@,C!K``4`.08`A@82=J43`@,,`S8` -M`[P!#Z$``"MGF]P5`%64V5P(#*!``VH`0+.&7%T;R!S -M965KD`I&@'5`@DX`P#*"C)I97-.``*:!&$Q.B!.97>:`PI(``0;`UES(%-&6`,% -M"S\`0$)U:6QK!0"Y`:)O;B!7:6YD;W=S(0$#YP4.2P$K,&%+`14P2P$P57!D -MN!5T`P,,RUS._@6"*$9`ADA$F_B'$!H87)D4P(E+W-;`E%B&0"5##!E;747&6D@8G)O:V5B`#`R+GAG!`!W -M$`&O)2%O9K(6<5541BTX(&AH`!)SF04%^P!`4F5F85D'`04/$%]R#B`H*7L: -M`"\-46-O;&QEB"$`XPT`2@\P;&4MJR(`W`<`YR@!EB(#+`$!D`P@;VPA`P,2 -M)!!S'Q\@=W(,`0-W`!(Q$`:!,3H@4W!L:71?#0(`!@`L`0&1!C!P87)N`@(> -M%P`T"`/``@":`Q%L^24";`(!QP`5,30#`X(#`L\AE`=V]R:V(!9')E='5R;JP<`)`B`2$/$&;N -M`@%9`7%A8F]R="@I1``&-04`M0$`>0`W%SM#.3`"`07@ -M`"9O;LT#`=P'!GP!$4;T!@`G`:)!25@L(%12538T]QJ@;W1H97(@<&QA=(4! -M$G/-!@+4`B$P.D`<`\T#`1T'`EP"H3`Z($Q(02],6DAC`P'J`S)L(#`U`B$P -M.OPM`!L:`Z,F!T,F$&5F!`'?$P*5!`$N`P+1$``)"S!TH2`-@48F5N(&-O<)01``X#`1X2!,@)`4$``XD%$#`(`@&R)P!X`'8@ -M36%C($]3J0(`/``'K@0!.@`#0@(D,#I0``?K``"J"0/]`A!S7@D"[@!4&D1%0*G!`/4 -M!P`:`0"4'0.-"@)C``:;``-=!`'?(080!00'`@0;`V!C(&-R>7#%!`+!#`&/ -M``/[!B$P.CT=`0("`"P&`A`$`"8#`$<%`BH``@4-$C``"`/4`Q(Z+@=`+6=I -M9`8``"H$02`M+74.`!!U#@`!!P4#,@X#P`%@4F5D+6)L8!8`_"(!E`<&_@$! -M&14@97)D`P,C`@!4!`#.`@!8*P%.``,)`P!*`F)I;FEM86RM``$3#7@@;&5G -M86-YM0#,O -M`G@5`,0#`#(=`I`%`W8(`[X!`+\'$F0K``"1(#EL9&5?"`!=&Q!LNP$`%0X! -M0"@A963+`P80`55296QA>`,"`,(%('-T7P;09F%I;'5R97,[(&UIF7'`P`M`0!Q`0-7!`!_&"%O;88'#%$``8X%4&YT-C1? -MS`L%``>@;V9F7W0L(&1E=@<`,&EN;P<`,'5I9`<``#\#$&<+``*<``7^!`08 -M*`'"$#9!0TQ%"0)U`!4QN@024SD#!C48`20!!28#`$0!$C`B!P%J!``&$0)\ -M)@.6`@<*"3$Q+G@-%P&,``:%`Q!2R`=%869I;PX)`54`!<,%$$'''0!6``?S -M(P4Q!2%L>2P/!/T"`EL`!;L!8$EN=&5G) -M``9"``+3`P`I`Y!F=71I;65S*"DX+F)#>6=W:6YK$@9%`0>'`78R+CQA`;&5A:U0!"!X!`$@`$G,S``5<`0!D``FUA+WAZ6P,#X0(`9P`$%B`)`@@"0`0` -MGP43>?(.`$D`$4C()"`@9_X2`D4``-@)!$$`0$]P96Z4)7`B9WIS:6`@)[``6)`D!!9&1IR0HP86P@2@!` -M-P)M(B%S98$#!+`=!),-!'4'85=!4DX*"1PK06ES(&/Z -M,Q5OPP<`U1U0861A<'2;."!N91PC,V%R>;L!"=\`55-T=61I8`L`E@`/2@`!-`E!;!$# -M``@!`%HA`5\``_40`/,``.D#,$1E8E\!L4)U9R`C-3$V-34.`?$.`*8$`+$H4$AUA,` -M2P$41:L>!]$(`8(`)&]N*Q8!\0P"]PM`;F]W"?P#`9<2`78,$G11``85!@#0 -M``.@"@8,#A!?*A4@>5\/!A!?;P8P*"D@6"X$[`\`00PQ+`H)2!R7!,@961S(`#/"P"])@!1 -M,#`L"@E4!`"`!P!:#0#B!@!A!0:^`P`\`R!T(",%"7$F`;L`!LHA(@H)?0`4 -M<^@OQ6)E(&UU8V@@96%S:>8-`H\/*RX@HC,`311":&4*"3$8`5\1"$(G%',] -M)P;1#P"#'`-Q`!(N_!`"MP80.$4$)&YY:Q8:+Z\#`HH6`+L!#_D#`@U)``J[ -M"0B[&0+W'`%*``1;`@+Y#!!CN@$@97)^)2ET;W89`$T&`'PT`@2US:7IE9`4/$G.*)3$@*A$)SAH`A@,/[A<"`!<-L2@I(&AAFEPEP2"_`0`P`"`@ -M82D`*RDNM@#@2F]E0,A -M(&*Q'`&[$P%-$P!7!B)A=$H`!9X'`<4(`AQ``-A"`FLK`)$I4F0@8G5GQ0(@ -M.L%`&P"!/P> -M"K`3``XT`,T``$8$`3,8!B,&`;X<`681`$LA!O8?`FD#`#\.``D)$V'=0W,B -M4V-O='0BW!80(%0```L*!9X#$VV#/A!SU`8$-0"22V5E'!L;P$0`&T6$&5D -M#0)M`0)E+95V97)F;&]WPP$_@D$V@Y0"@EP2P!$'26$`&#.%%E(&)O9(L] -M``8-`8D!`#8!,#L*"6T&$FG,$@#0`2%O=:T-P')A;F=E(&)E:&%V:2U/`$0. -M`0L,!!0[`9@)$7)R`0&K`0)],U$M3A+,&ER95<8!&@8,"-I -M9O4,!'@8`H9`.`K@-`=0/$"V!+C%E8V^!!5)L;V=I -M8[$5`C0`$',T``!.%0)/(@'V%`!V`0$8``);20*;%P-]`@;4"`E3`D0T+C$T -M>AY`9#L@:5P\`%)$`)@#`1X`&#,$0"()84H*`%,!`?`($&=+!1$O=B-@(&UI -M>'5PWRD&R!8"L0``P@D4:<0O(F0*[18`9P0"A"D!'@<2+L@?!N8.#*8`%3.F -M``*3&`7Y`@-V'0"=!A$L3`(`DP`2+)H`$"PL!`*>``$[`2!C8640$6*8"S%V -M97+;`P32)P&-`". -M``#3"P"!`&`@8VQA`B4&1E=FEC5@$! -MRR$!32(`B0H`2!@3(G`#&2*)"``6$`(U!D!N97=CM@("<0@#I``6.^0#`O$1 -M`%P"`6,$"$T!`#4"`!`A('1H2PL!>P`"G!LE.#I(#0)E#@-J)P!(`@2;`PDD -M$1PL6PT`.QH'004P26=NR@@$[`I"('-I>ND,`$,-`B@K`#0.$F&[(@#8"P#^ -M(14RC@`,7@(6,EX""BD``*@!(&)A4T$`58(`$D:,6=E=)H-`J4\`6(+!,U5`'$:`8X%13(N.2Z" -M`0(Z``!(`1)L5#$08A,9`=L+!^$/(B@MI0]`+7HI+*L#`"$/,0EO9JH-,')M -M85X2`)X?,F5S'!E -M-\4"%C'%`@HI`#!&:7BF00&U)0#H$P+X)`9A`0"G!`&Q"04]#P%J``(_*P]J -M``$,S!D"8006-X8(4#`N.2XPQ@<`@0<"SE,@=VFA%3-U?@=`70``Q`;$C>)!5!A(&-O=90<(V]FE@0'K28`Y04!?P`"J0\. -MIP`'\A4**```6P``J0,!IP`!!0`17VD!$%_?!"%B>=DQ`D4!`@"&!P8T4@2$`E`M+61I0H& -M%`!U86-L+`H)=.T!_P!386UU;&D@4W5O;6EN96Z,``T'/@D!_``%C``&/P+` -M3&%P;R!,=6-H:6YIU04`>E4!20(`3AP!54D`!0X!T@D!FB0#2@4`DP$@;&17 -M"0%5+@#Z&P1O!#!B=6?&!0$8``!``;!O9@H)(FQE;F=T:)X4D&5N9"(@9FQA -M9QX*!6$`$G,?!`96`0).``,"!!$@FP8!4@8!/@(`J08!+P0$-P`%\P,01J,! -M0"!C=71K`$!R96%L>0<`-```D0(`Z`42;AU(`0\!!38`"Q@(%C+:`@+$`0\I -M``46,2D`"E$`$4W_)@"X!D%S+"!R%Q@`E```P0*@9&]C+71O+6UA;C\.`WX' -M`'H!(`H)%``!NB0#.CL/]`4&!XD%"B@``G@``"4(`/$%`#(4!CP"`[H,4&-H -M:6QL!Q<+.P`03Y`&`-D0`/`"`O<'(B!A>U8@(&_I%P'8"P#Q#S%G:6Y\*2!O -M9L\&(PH)$P(!6!X"IQL"K%@"S0(#CQL`+1D`3P4"2C0`+5<`#P@2>88`!G,& -M$%0$!@,S```5`0`X!!-Y\Q``6!(`0@0`QB4`NR(#Y@D8.I@"`FT(`#4((&5X -MU!8`0D4$.``!YAXS,D="?R8S,51":`$"5CD-#`48,RX:`"T!!B@`$D,/"`(_ -M!R5U;E@G`LP.`%T5`7-#`-H$``,#`+(``"H!$"*:`0#Z$P##'T!N;VYEC@L% -M9!T!?@00;H`,#(O,V(#`7T``-@"`68( -M!M,#D$IA;B!00P`4,#`!`,`-D2`.L( -M,$=.55L!$"><*$%G+71AE`(&[UP`FP`U;W-E,@`!7QA`960@;2\B0'=A&%C=&QY"@EA*R``YA<@-$>T"`/@$@=H$0&=`0(;#@=G``!;`0!F``=#`E`H -M/CA'*>,`!3X"`-0``-P20V%S"@E&.`'M"T!)('!U\"\)C0(`(1`#)`$%&"\` -M3`$`P50!A``%+`<32=0(`=D+`-@'$&5_)P`!`U!N+6UA=&\%`!5=`-0^(6]R -M00R".R!)"@EH;W!(#9$@979E;G1U86P\)0'Q3``?`0`P"S)D92`G"@!#*`+. -M"0#.50,5/P)K#@R7!A@SEP8`J@`5,"X!($-O(QH0=9``!*T`!'8%`%P"`9@J -M$F7?``8U`!!.+4T!6%8`Y4``M`03+/<+`7`(,")(:>\*('DBM0$#3@`@+C$X -M"0'/#`"O`!0Q.0`#Y"$&7```F`<5>C0\`)<"D6EM;65D:6%T90T!`9`X,$5/ -M1M$J`(P?,'1R><\/`?X5!<,4`!$.,')E9V$F`8D+`.(/`%T%`-(D`!4``,\; -M`6X2$'B2%0):#P3+"P"=`R%O9H0``Z$"`&4(`+X[#Y$%!!@S:0<`*``#T!`0 -M-]`C`54!$TU''"`N8205`4X'`!($$B#'(!,O`P@$:A)#"@EA8_P!(61O*`!1 -M@,%1DL# -M#`H`QP5`*"D*"4L'`=$2`+4,$FUJ5B5I;I(+`Y@``P8=#GX#!RD(`)@`!B@` -M`:(X`88"`.D"`RL#4R`P+C,ZO#P&[A`165TG!`2*;L``NL]`GX2`!L\`PP"`SPP#G8`!V$-4D%U9R`S+R02-^,R`+,R -M`)D#!+P&`BL>`(,+(W,L7&,`J@4D86[/6P2`!40*"2A!K1<991L1`*HE(2XI -M;``#310!F`1`860@9QD+\0$Q+C$W("TM<&]S:7@@+2US22<$D@<2+C<`!3@, -M$U*S&F!S=6ED+W.+.00R$03O"T`[(&ET'00%=@0@"@E/&D!RQ,2(M+6`%%"W0`0,R!@&^)0"]*!5RF!,1 -M"ND`!H4&"5@$-C(N-L`#`$@!!B@``0D'"]4-!\`-`ED&`&T&,6%N:QL'`88+ -M*`H)$B4#NP`%[`($0!X`20T"&P0!N@H$Z"LQ0U9361\`V$@G=6R=`0NT``?Y -M#@(I``_&#`,8,AL(`5$`!2@`!E,*"B8B$B=/)@"$"@1$(0&4`A%D*`4`H`($ -MXQ,R8W)I6!A2\`!ZP' -M`8HD`?(]`/T+`'D("%H0`.````$/`(P#`&4H`/8=(!"PL! -M%C(Z$PHH```+`0[=!1`@D0,"3"(`!`P"EP-0>2!C;&\0#@"5*4%T8L<`2"Y`0`2%0*7#0#)-0"F'!=Y@A.!4VME -M;&5T86Q\"P:,"`%=!P/L`08"!0OL`1HQ[`$&*`!01FQE -M`@$I`1%A(2`!RET":0(`)`%B/'-I9V@^VP`&204!<@(!=!D`]P0&.!P`A0-0 -M,BXQ+CDW"A-TMPD":0`A"@EJ``!L`0\7$``#80`%NP803,0*'!`#*,#!U;&00!!!RY0('H0(Z.PH) -M4P`!F@D2=\9.`,D+`%\#`WL"`NP#`I(!$&Y3,@#,:`!T`P6-#C%T;W7L`@!, -M!0""10-@`14QX1$+_@`'-@DF"4P[%@"!``#L!`*Z(!!N9AT!*B$`"0$`=00` -M!`,`_D]$97)I>&,`!:4'"V,`".4(`,0!`QHC#'8+)S%BZP8**```P@D&50`1 -M7PQ%`]9G"KT,`48=`!$:(6%L4$%E+@H)3F]TM@4!3@8$BP$"B0$`IQ8!-&T* -M<@`)NAP1(LH&``\!47)EP1$&XN2!%N/2T`?AH$4@`%;@$,4@`6-,("`5(`!4L2!/P7(6%NPT4@8FS* -M*0#[(!!AM0D!R@4`U1$`'``!"P<`_PX`;VP!NB\!)@`!#D@!3@D188(3!75$ -M`>T70&]R(&>R4@`_#`!N$"1B96T+``L"`P,>`BXO`#4M`2PQ0&]T:"!:!P*< -M!0'##Q-R0PR4;VQEY!0J(`1%(#0<$1PT@W``%J!`=B -M!@!<`08I```K%`'M`0">`@!X`C%S("BB``!W!0#C`@)3"Q``#U!(`200"O0('_0`( -ME```^A)`:6YG+Z,#`%L-`7H``38*,7!A>-4`!>T#`+T6(G5NI0$@9616)`$V -M`0^Y"@,W,"XR8@<`*0`%*`!`($ET)T0*$71)'#)E8W3&`1!I%@"S<')E='1Y -M(&=O;V3]`0;U"1(R&201;^I#`=<:`+\F(&]F[`L480H``_T& -M``D#`(<.`/T(,$=E;M@``;P#$RAQ+3`A*2!0.P'+'0(6`0!$$0%"``'H'[)I -M0@A -M=""X3X1L8VAM;V0H*6L`!245!Q(#`74!!]83`6L`!2D`$47*,`8(`S-E`2!W:#(!`24` -M`Q$(`4\`(6)Y00`!SAE1('1O;VRM!``W!@+F*`4N``*%!@';'#5M:7HL`08U -M"P=L``$L`0?9!0`L`0,'0@(U`@'0*`%?$0#Z!@'1*`&-!@9$``"<%@/T5P*A -M`"1F($8!05!%4DTW`001`&A/5TY%4BRD9")R96<0`3L`<71O(%-5240S`!!3 -M8`0`LQ@`=A<%F4X.B@H78AP,"B@`$4%F"`"J!05@"P"1!A$B!RX4(KL0$'/: -M!Q%A?P`"&S4&D78`YP,`)48Q("!"0Q\`L`0`APD0:;$$`O4``"U=P'D:"`@8=,5865R+6=R -M8?@T`4X/,&9A8UX"%F&'$``C`03;%0VW'P$:`0`E&@",`@/E%0#R,@&)9P., -M:0%`$`*T%0/&`P"C-`&B&`1G`0%'`"%A"P,-$011 -M`"!D99X)$&*A!0$4-S%Y;W5#``1*&@():!(I5T``FP!A;W9E!Y<#`D<5`7(!`G(` -M46EN=F]LU`$$\P$!S08$!%4!40T`4P8`!@(`7&(1210=$V.*"0&"-!!X80L` -M``(@;V;/$>(@;W9E@J`:L&%2W(`0'8-0)T'@,^%0P2`3_`$`R+C`[Z0("PPD`9Q]!<')O=/P+`+,Y]0-I -M;F0@(VEF9&5F)W,@=6YT:6R@-P'#<0+U%@"S$3-Y=&@T"P%B`P"L`P&L`@)X -M``*['@::``#8"0OK``>7%P#:!0*!`0`;&S!S92@`>5$@5&AE>9<)`$XL`HX. -M`.L"`&8/`4L``#HJ%6;B'PIL`,!R96-U`0"S#"%S90($`BD#`$D($&``"I`2`M<",%"W8+`@5.`;%P!!H`$"W6(E!I9FEC"@QX -M#>5.``AH/`Y@E$3;N"!`@ZVL!?2<0.P8`$6Q-*0#_!2!O;$\0$F@C*`+9 -M``%'"@!?``&(`0#V!Q`GIQ81EQ`:\G4&QE('5P10<`8S0"/``` -M=@@@;V[+*T),1$52=@"B4U5-34%22453"OT0`JT%#V0#`!HQ(0$#(2,0-ED. -M")DE`%87(&YD;P$2=-E#!8@/"98C,B!R96YP`,L``3<-``EE(&]R"!T"*!,` -M3@(%7`8@9&5N$P&,+0">`0.3,1`V9R,`Y)`!L!`5X`!?P!$$FX)C%P;W*M -M!`MF2@"C95!T:6QL+3`'#%\U`&(``.4%#@X!&',C:0'8$WPM;VYL>2XI?`!@ -M4F5O@K,:@!J -M$P&'!`&*&Q)S^!0']@0`ZP4"WPP"B#@#Q84.GL'`5(J`)(A -M`0%1`3\Y!/<&$BR^(`!Y`#=087CZ`0%>'`(6?Q$N_DT"`!L;-=H9`;X!`_8! -M!+41"4=/`#X.!%T9`!\+!E\9`+L%`$83`K8$`A\2`',-!)0$"NE*`F0``N1* -M`*X``#P44&%S($DG'`-`="!Q=;@3`)-&`-A:`:P)`)@"`C8``T&``((!G&AE -M=7)I8@,!0@'`1P)5"X*3V-TZ@(2-5A7-$=.5U,`D#`/87`2L2"\`#`W`#`JT-*C4Z,0(#7P8!544` -M7@,!*0\095X)$7G=$0`]`@3N0S%S("@*"`(K'`(0"@8<``*>&$PQ34(I<0"@ -M36%R8W5S($=E:7T'`%8<`!\'`6<1`.,-`;)Z`[PZ!KD#`'D``SP!\PYX(H``$%\0FMT;W!?>P#J&0`O``;'``&%"0*5``!]``". -M!`+*%0`.``$T```J+P.W"P-1#V(U.B!07`F`Z2UW86QK6``!J!\`E@4"DP("70`#X"L1-6!A`/U#`+@'!%4` -M`3(``2%;$#N$(@"4``0/!0"*#`#2`11YHQ(0--(!(6YY*RH0+7<(`,4](6QE -M+P(!U!$`2#D!5@,!&U(#5@`@86PE#@`=`0'5'P/L%@$`&@4Q.P1S``0&.P2_ -M``!]``.'!Q$TBBL`I2H%FW@#;X3Q!2P@2%`M55@L(%5N:7AW87)E+"!S:2D` -JTRH"+@$`?@$1<#T``I(!`'P$'P`!`/______;U````````````",W%#R -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_compat_lz4_B5BD.tar.lz4.uu b/thirdparty/libarchive/libarchive/test/test_compat_lz4_B5BD.tar.lz4.uu deleted file mode 100644 index 5ad546966..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_lz4_B5BD.tar.lz4.uu +++ /dev/null @@ -1,2310 +0,0 @@ -begin 644 test_compat_lz4_B5BD.tar.lz4 -M!")-&&10"+,4``!O>&9I;&4``0!+X3`P,#8T-"``,#`P-S8U"``B,#(0`"(R -M,`$`_P<@,3(S-3,U-3,U,3(@,#$R,#(S`"`PEP!+`@(`KW5S=&%R`#`P8W4' -M`0M2,!46%C="!S8`"A(&1E;6]N4$`(&EN^``(M@)A:6YF;W)M&@00 -M(+@&!+T"\`E.15=3("T@:&EG:&QI9VATP`"-E)ZT``R0$`),``$X`]0$N86TL(&%C;&]C86PN;30L -MX0!`92YA8_\```(`$BU4`"1T;Z@`#*($LBP@;VYL>2!N965D?``Q;6%I]@$C -M97)<`05P`"1I;F0`\@,N:"YI;@H)+2!T96UP;&%T97-G`!%B-`(!9@$39;4` -M<`H*1W5I9&6V`AA$5`8$T@$"=0`!MP&R'!L -M@P(#+P,`0@$"(0`$F@,#,P``B`0/-``+`"(`##4`+V%T-``,*&%T,P`&`0:` -M+C,@9VEV97/?!H!O=F5R=FEE=_,"`*``!+L%$&%Q!3!W:&^1`B,J(-D'A5]R -M96%D+C,L$```T04=91$`45]D:7-K%@`"?@<(/@`#'```F0`0=E\!`K<"865D -M(&-A;(D'$'/4!D%N8V5SK0(`DP``=0``%P(`^00!<0!8($%027.7`'-E;G1R -M>2XS30`"]P,2(FL#!:L``20`4"(@=71II`59(&-L87-$``'O!49N86QSG0!@ -M]!;!I;@IA(&YU;6)E`D09BP``;<&42H@1TY5 -M=0$"N@$F("@$"P`:`$%L;VYG4`9B;F%M97,L$```!0L3(!$``&,`4G-P87)S -M?`(AB,``!DT%``)"`$```I58W)E -M873/``%U!`\&`0("J@,#OP,"O`(/'P,8,")R9:`-46-T960B1P,"3P#$+"!W -M:&EC:"!W:6QLB@`!5@`%R@%A(&5X8V5P0`40"EL)`VD"42!T:&%T0PXQ:7)E -M40`!\P,!R@(@("A3"@$T!`"$`0,S!`#T`V`L(&5T8RGO"P+Z`P"I`@8B!`&& -M`0+:``_(`PIA(FYE=V,BFP,!,P`G0<280D!`BL`(2!B-PEQF4@'!L -M:6-I=&S9"4!V;VMEO!(!ZP`!?PH#SA$@("C2$"4@8?L*`*D`("!AZ0`!)Q`" -M+0`(S0`4;Y4(<"DL(&ET('=P`$$@9V5T&1,!70H`I`0W($EN;@`W+"!IG@`! -M40$#FP`B96[)`0P,1<#4`T6%T979E`!,@%1``:A`` -M"@$`/06#;B!I=',@(D#E`!(BO0012!F4X.``P1$2(A`0!:""`L -M(E`(H"P@8V%P86)I;&D2%`8#`07Q``+S#P&W!`CV!0&7`8`@:6YD:79I9&P. -M`&@%(6EEA`$`.A("0@`$K`4`-@$A=&^L#3!D8737```%#A8Z+@$"R`D`P@`2 -M8>P"`,D*`2L`,VEN("4&EV92!E -M0A0``/$1;G1R>2!B90H@("!I;F1E<&5N9&5N="X@(%1H97)E(&$$`/`9=&EC -M;&5S(&]N('1H92!L:6)A'1E;F0L`/(6+@H*("H@3VX@F4@;V:(`0"S`1`M=@!A960@8FEN/0`P(&ENA`#A -M96YV:7)O;FUE;G1S('=N`F!T:&%T(&W8`2)R<^D!!3`"`WD"H7)A3X`!8P``+$!\09P7,N"E)%041-12X`"!0'T6)U;F1L92X*"E%U97/Z -M`J`_("!)3``!(`1!HN`*# -M9F]R(&]N9V]8!Q@@9`!P9&5V96QO<#P%<2P@:6YC;'6]!4!D;V-U%``087<` -M$"Q8!P!Q```Z`"%N:UT!`%T`!G,`4"!M86EL!P)";&ES=*`#,"H@5)D!`>H& -M0&%N(&FW`!`L(00!_``!#P"A('1R86-K97(@8F-A="P@8@<`$G@'``!)`0"2"0`G`%`J(&5X84D`0',Z(%,R`U1S -M;6%L;!4`!#X!`%(#(6%T'`@@;6'F!"!N9-`",69U;"\"!D4`$"]#"@&%`1%A -MXP%186-T('-@`+`@9&5M;VYS=')A=+\`!,GK0`#9P$`DP``3@#P`"YA;2P@ -M86-L;V-A;"YM-`D-`^T`,"YA8_\```(`$"VB`@"?``2H``RB!&$L(&]N;'G7 -M"P)\`#%M86GV`2-E7-T96TZ&@D"N`0A -M+C'!#`!A#`$W`0,O`P`+``(A``2:`P,S``"(!`\T``L`(@`,-0`O870T``PH -M870S``8!!B$N,[8+$'-E"H!O=F5R=FEE=_,"`*``!0H,`'$%,'=H;Y$"%"JD -M"H5?PH" -MMP(29:`,`%L$$'/4!A!N2PT`U@(`DP``=0``%P(`^00!<0`!<0H(EP`09<,/ -M(RXS30``[P0R92`B:P,%JP`!)``4(@L+62!C;&%S1``!'PE&;F%L`8`>P`( -M2PE`:&%R9!8,`3`&!%L!`4<``(X!86UO9&5R;H\``.@!`+P'<"!V87)I86Y( -M"0!$!+%M86YU86P@<&%G93@``+`0)')EI@``G@`!'0-7)V1O8R>]!9!I;@IA -M(&YU;6+R#!=FD0<#'@'7+@H*66]U('-H;W5L9*0+`"@!,6-O<'8&0&-O;6V> -M"`#.#1,B!0XR+F@BJ0`R:&4*7PQ!(&-O9'4!`!0`!.D&`W((`G\"(6UOU@P" -M6@4R("!0B@FR;&5T('5S"FMN;W<0`0&9!G!E2X`L2`H8FEG -M+65N9&EAU!%C;&ET=&QE$0`"^@#Q`DE33SDV-C`@0T0M4D]-(&EMMP*`*'=I -M=&@@;W#+`\!A;"!2;V-KU`P$3`%HW+5II<"8`V$UI8W)OFEP,A8`!'P! -M32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9-!0`"0@!```*`IP0!3H!`'4$ -M#P8!`@*J`P._`P*\`@\?`Q@P(G)EH`U18W1E9")'`P)/`,0L('=H:6-H('=I -M;&R*``%6``:0`"!E>"T4``("$`I;"0-I`E$@=&AA=$,.$&F6!2=A>,H"("`H -M?0`3AN97>U -M`P#P!`#]`@.?`0![``&'"0##%Q)E2@P`31%`:7)E;?8-$&EY!P/N$@(,`@,A -M&D%R96%DCQ@#N!0!#``080P!`M00`&@``CL`$66<%@`]`2%V9?P4#V0:____ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M__________]J4&EV97,*4!0``/`5"E1H92!L:6)R87)Y(&%LFEP -M,A8`!"8`32],6E<=`+%L>FUA+"!L>FEP+,<`+WAZ(P``&304``D(`95C86X@ -M8W)E873/`$]S(&EN!@$#`21E9-T`$2E%``"=``"<`H5"4T0@)V%R)U(``1X` -M>"=M=')E92>[`'A)4T\Y-C8P$P!:-RU::7`Y`#9805(1`$,*5VAE`P(`V`($ -M=0$1+`(#87)ED#`*4#`.<#]A)U2!S=')E86WM`>!S>7-T96TN("!4:&5R92P`\01N;R!D:7)E8W0* -M("`@`>-R86YD;VT@ -M86-C97-S+GD`!I<`\@)I4<`L$DG=F4@871T96UP -MQ`/@=&\@;6EN:6UI>F4@2!I;G9O:V4@82!PZP`@=6PW!*!E871U``%1`0.;`")E;LD!!RT``'P`"W$`*&1E$0`#Q@(1 -M+/```H``(FYEC@(`%@$`0`!B86=A:6YS1P*@8V]R7L#$7`U`-%A=&5V97(@8FQO8VMS\```[@2X'<70@82!T:6U7`W%O8!(71O(@`%H0!A="!O;F-EA0`A3VZ0 -M`QMEPP`"Y`(R<')O.@$!A0%18W1L>2W,``!(!E)U='!U=.\"`&`$\0-O8FIE -M8W0M2!B=69F97(@ -M)`@`90`$<@&%82!S;V-K970^`TEW:7-HN@3`P" -M`,D*`2L`,VEN(">D``,P``*,!!H`%,7=A;H@`$'0V!`5%`0!@``'Z"0".!S!S -M:RQ.`P-^!KEC;VYV96YI96YC9<`!`(D`,&UA:WD`D&ES(&5S<&5C:6X$`=`! -M`JH!`#H(,#H@(I,*#KL*$R*Y`B!L;#P!`N@"`*4'`!$#`L$%0"P*("#,!Q!P -MWP``;`0`E@`0(',*T"!S87ES+@I214%$346[!@?H!N$@8G5N9&QE+@H*475E -M<_H"H#\@($ES7!1`GH@1`9W)A;18"M``-G`0"3``!.`/``+F%M+"!A8VQO8V%L -M+FTT"0T#[0`P+F%C%P$``@`0+:("`)\`!*@``-D."*($$BP:#@#7"P)\`#%M -M86GV`2-EPH"MP(`A1(A86R)!V!S97%U -M96Y+#0#6`@"3``!U```7`@#Y!`%Q``%Q"@B7`'!E;G1R>2XS]!0`!`,!=`$2 -M(FL#!:L``20`%"(+"UD@8VQA=&%R -M+C54`0CQ!`4^$A%S8P0Q<&]PY0\#G`$`>`8`>P`(2PE`:&%R9!8,`3`&`J@! -M`X42`(X!86UO9&5R;H\``.@!`+P'<"!V87)I86Y("0!$!+%M86YU86P@<&%G -M93@``#$.`,X4`OH!`)X``:D!5R=D;V,GO06P:6X*82!N=6UB97*5`@:1!P,> -M`=%V,/"Q<`TTUI8W)O2)J -M%```\S4@=71I;&ET>2!C;&%S1X`<&QI8G)A#0#46-H86YG?@$W;6%T(0"P;V-T970M;W)I96X! -M`P!@`@$>`*%35E(T($%30TE)=`(!%``"4P`/,@`%84)I;F%R>2X`P"`H8FEG -M+65N9&EA;J(!8VQI='1L91$``OH`\0))4T\Y-C8P($-$+5)/32!I;;<"@"AW -M:71H(&]PRP/`86P@4F]C:W)I9&=E10!B2F]L:65T*0$![P$"20`U6DE0"0$# -M0`#P"G5N8V]M<')EB,``!DT%``)"`&5 -M8V%N(&-R96%TSP`!=00/!@$"`J\!`[\#`KP"#Q\#&,$B,H"4B`H9F]R-`0`A`$#,P0`]`-Q+"!E=&,I+F\!`/H# -M`*D"!B($`1<``MH`#\@#"F$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0%!`); -M`0&)``]9`P`*%@,S5VAE`P(`V`(#U`(2<^8%87)EF4@ -MP,1<#4`T6%T979E6QE(&%P<')OR`,`R0@"^@#@=&\@:&%V92!M -M=6QT:7`E``-3!`(!!`"Y"%4@;W!E;IX`4"`@8G-D(P2!B=6@-$B`D"`!E``!Z``#!`85A('-O8VME=#X#27=I#B)A;N@"`*4'`!$#`KH.0"P*("#,!Q!PH@`` -M;`0`E@`!I@[1('-A>7,N"E)%041-11(&!Q0'T6)U;F1L92X*"E%U97/Z`J`_ -M("!)3``!(`1!HN`(09K$/ -M,VYG;U@')B`@+`"`(&1E=F5L;W`\!0@9$02Z$0&L"!`LH@0`<0``.@`A;FM= -M`0!=``='`$!M86EL!P(P;&ESOQ`!G0`05)D!`.41`.!L30',Z(%,R`U1S;6%L;!4`!#X!`%(#(6%T'`@@;6'F!"!N9-`",69U -M;"\"!D4`$"]#"@&%`1%AXP$T86-T>Q-P9&5M;VYS=#D5(&YG/@``@`4&5`(# -M20`P8V]N0P)A.B`@5F%R[A-@:71E;7,@,P$`UP(B;64V%3)I'2(`"%P=6<0,"`B8S0&$2(D`P`X#"EO;$T`(`H*X0@& -MZP,!*0$`%@D`C@$/;0$!`+`,$'4]$P(0%R4*)[P`$R>M``,D!`"3``!.`/`` -M+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C_P```@`0+60"`)\`!*@``-D."*($ -M$BP:#@#7"P!9"U%Y(&UA:?8!(V5RK@$%<``D:6YD`($N:"YI;@H)+?0'(&QA -M5@\$NP`%A0`#M0!P"@I'=6ED9;8"$T0.&`*!`0/2`0)U``#S`0-3#Q`Z&@D" -MN`0A+C'!#`!A#`$W`0`]!@-X$P(A``2:`P,S``"(!`\T``L`(@`,-0`O870T -M``PH870S``>M`Q$SM@L`$!20(&]V97)V:65W\P(`JP`%P`L`<04P=VAOD0(4 -M*J0*A5]R96%D+C,L$``!^`@-$0!17V1I2XSHQ2!T:&ER9"!P87)T:65S.X,``P(`87!L96%S948``'L`\BET:&4@ -M875T:&]R2!Q=65S=&EO;G,N"@I4:&4@=&]P+6QE=F5L(&1I -M4$`(&EN^`"`92!F;VQL;W>V`'!I;F9O%#36%K94QIM`!(ZU```DP``3@#U`2YA;2P@86-L -M;V-A;"YM-"SA`$!E+F%C*P```@`2+50`)'1OJ```(`&`9&ES=')I8G5!`;(L -M(&]N;'D@;F5E9'P`,6UA:?8!(V5R7`$%<``D:6YD`/(#+F@N:6X*"2T@=&5M -M<&QA=&5S9P`18C0"`68!$V6U`'`*"D=U:61EM@*"1&]C=6UE;G2!`0#%`3)A -M;&QU``#S`?4*('-YM`_`$,R!G:79E2XS!`,!JP(2(FL#!:L``20`Z2(@=71I;&ET>2!C;&%S1`"6:6YT97)N -M86QSG0!@P$2+8($4W,N-2!D5@(#I@0@:6QV`]1R;6%T-50!"/$$4&%B;W5T -M&@$@P"`+"!I;F-L=62*`8%H87)D+71O+3`& -M`J@!$G-'``!!`&%M;V1E$D#(F5R60<#>`('(0"P;V-T970M;W)I96X!`P!@`@$>`*%3 -M5E(T($%30TE)=`(!%``"4P`/,@`%,$)I;LH$`$(`H"`H8FEG+65N9&GS!(-R -M(&QI='1L91$``OH`\0))4T\Y-C8P($-$+5)/32!I;;<"@"AW:71H(&]PRP/` -M86P@4F]C:W)I9&=E10!B2F]L:65T*0$![P$"20`U6DE0"0$#0``@=6Y."3!R -M97,G!W!OB,``!DT%``)"`$```I58W)E873/``%U!`\&`0("J@,#OP," -MO`(/'P,8,")R9?X(46-T960B1P,"3P#$+"!W:&EC:"!W:6QLB@`!5@`%R@%A -M(&5X8V5P0`40"EL)`VD"`A4,<7)E<75IP`#GP$`>P`!APD!HP`"2@P#"@,0;6L($&EY!Q%A+PD#*P`A -M(&(W"7%R96%D86)L``8`C`H!#``!+`L"!`$`:``".P!"96%C:#T!(79E4,`4&EN9&5PJ@`E;G0B`0`8"0`/#Q!C0@42;VP-!C4*5"!7:6MI4@PP:6YG -MR0`P:&]WFPP!LP,79)8*`BH!(4]N/P@`]PP">`8#`P$$S0`!<`!`;'=A>48! -M`-T!*F5DB@@"1P!P22=V92!A="T-`(P'`,$/D&EN:6UI>F4@2UV```S#`#W"!%IAP8`A`!P96YV:7)O;M<",7,@=Y`#`:`"$&W8`1-R -M6@,%,`(`6P`"?P`1>7L#$7`U`-%A=&5V97(@8FQO8VMS\```[@2X'<70@82!T -M:6U7`W%O8!(71O(@`%2@!2="!O -M;F-\$B)/;AP."\,``N0",G!R;SH!`84!46-T;'DMS`"2960@;W5T<'5T[P(` -M8`3Q`V]B:F5C="US='EL92!A<'!R;\@#`$,2`OH`X'1O(&AA=F4@;75L=&EP -M)0``(040=A(#0')E86W\"E4@;W!E;IX`$R`5$`!J$``*`0`]!8-N(&ET2!B=6@-$B`D"`!E``!Z``#-`H5A('-O8VME=#X#27=IP`2 -M8D(`!*P%`#8!(71OK`TP9&%TUP``!0X1.L$"`2X!`L@)`,(`$F'L`@!A`P$K -M`#-I;B`G`0"/`C-A9&2.`AAA]PP!UP<#'@]19FER>D` -M`,P``*,!!H`%,7=A;G\%$G0=#P-%`0!@```:!!!TC@A<"+```.P``!`,`2P+%1`G-Q,`)AD`%@)S82!F=6QL -M+98(F-%#A)B!P`2 -M>`<``'`$`)()`"<`%"I/&@]D&O__________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M________________________________________65`@("!T;U04``#R-B!B -M92!R96%D(&]R('=R:71T96X@=&\@86YY(&1A=&$@F-A="P@8@<`$G@'``!)`4!S=6-H)P!0*B!E -M>&%)`$!S.B!3,@-4 -M`0-)`#!C;VY#`O`".B`@5F%R:6]UP``7P%Q875T:&]R<\`%`1\&`?("``$% -M4"X*"E1HG0$P<"UL#`0#=@4P;W)Y,04P=&%I)`4)M@(B:6[6!#%I;V[K!02] -M`O`"3D574R`M(&AI9VAL:6=H='-'2(`#!P=71>`C`@ -M(F,T!A$B)`-I9"!T;V]L30`"5@$&ZP,`%`=!'!L@P(#+P,`0@$" -M(0`$F@,#,P``B`0/-``+`"(`##4`+V%T-``,*&%T,P`&`0:`+C,@9VEV97/? -M!H!O=F5R=FEE=_,"`*``!+L%$&%Q!3!W:&^1`A0J[`B%7W)E860N,RP0``&[ -M"`T1`%%?9&ES:Q8``GX'`X0)`3X``QP``)D`$'9?`0*W`F%E9"!C86R)!Q!S -MU`9!;F-E``&I`5 -M"`"X!!,B?P(R+F@BJ0`R:&4*7PP0(+`)`'4!`!0`!.D&`W((`G\"-&UOFEP/@$Q:6]N -M&`%=8GII<#(6``1D`4TO3%I7'0"B;'IM82P@;'II\+`OH#`*D" -M`&@1`HT``88!`MH`#\@#"F$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0%!`?. -M``]9`P`*%@,S5VAE`P(`&@T#U`(2<^8%87)E0<#[A("*P`A(&(W"7%R96%D86)L``8` -MC`H!#``!+`L"U!``:``".P!"96%C:#T!(W9E/10"0P!0:6YD97"J`"5N="(! -M`$0-``\/$&-"!1)O;`T&-0I4(%=I:VE2##!I;F?)`#!H;W?X``&S`Q!DK0$# -MV@`"*@$A3VX_"`#W#`)X!@#S#@!0!@/-``%P`%-L=V%YD``2<0`BT`",T`%&]S!'`I+"!I="!W<`!0(&=E="#2$@%="@"D!#<@ -M26YN`#(L(&F"%0&>``%1`0.;`")E;LD!!RT``'P`"W$`*&1E$0`#Q@(1+.4) -M`H```(T.`)8!`!8!`$``,&%G8?,/`5\*D6-O7L#$7`U`&)A=&5V97)X%Q%S\```[@ -M!#%FQF4@ -M6]U(&1O;B=TJ```M@#P)&EC -M:71L>2!I;G9O:V4@82!P87)T:6-U;&%R(&9E871U!E('-O;64@=71I;&ET>3X`!8P``+$! -M\09P2!D8737`%9UP"`&$#`2L`,VEN("X`0!V``*4`0```P&3``7+`0#3``.C`0:`!3%W86Z(`!!T-@0# -M-@(!6P,`'P$`N@!09&ES:RQP`P/$`;EC;VYV96YI96YC9<`!`(D`,&UA:WD` -MD&ES(&5S<&5C:6X$`=`!`JH!\P=.;W1E.B`B<&%X(&EN=&5R8VAA;F=EGP43 -M(KD"(&QL/`$"Z`(09+X!`/T%`8T&D"P*("`@9&5S<*(``&P$`)8`\`,@;F%M -M92!S87ES+@I214%$344N``?H!N$@8G5N9&QE+@H*475E<_H"H#\@($ES`<``$D!`)()`"<`4"H@97AA20!`8$(&YDT`(Q9G5L+P(&10`0+T,*`84!$6'C`5%A8W0@`0-)`#!C;VY#`O`".B`@5F%R:6]UP``7P%Q -M875T:&]R<\`%`1\&`?("`DT'$`J(!E!T;W`M;`P$`W8%`#`'`4$`$&GD!@FV -M`B)I;M8$`'$+`.L%!+T"\`).15=3("T@:&EG:&QI9VAT2XS30``[P0R92`B -M:P,%JP`!)``4(@L+62!C;&%S1``!'PE&;F%L`8`>P`(2PE`:&%R9!8,`3`& -M!%L!`4<``(X!86UO9&5R;H\``.@!`+P'<"!V87)I86Y("0!$!+%M86YU86P@ -M<&%G93@``#$.)')EI@``G@`!'0-7)V1O8R>]!9!I;@IA(&YU;6+R#!=FD0<# -M'@'7+@H*66]U('-H;W5L9*0+`"@!,6-O<'8&0&-O;6V>"`#.#1,B!0XR+F@B -MJ0`R:&4*7PQ!(&-O9'4!`!0`!.D&`W((`G\"-&UO2X`L2`H8FEG+65N9&EAU!%C;&ET -M=&QE$0`"^@#Q`DE33SDV-C`@0T0M4D]-(&EMMP*`*'=I=&@@;W#+`\!A;"!2 -M;V-KU`P$3`%HW+5II<"8`V$UI8W)OFEP,A8`!'P!32],6E<=`*)L>FUA -M+"!L>FEP$P,O>'HC```9-!0`"0@!```*`IP0!3H!`'4$#P8!`@*J`P._`P*\ -M`@\?`Q@P(G)EH`U18W1E9")'`P)/`,0L('=H:6-H('=I;&R*``%6``:0`"!E -M>"T4``("$`I;"0-I`@)K%`!##A!IE@4G87C*`B`@*'T'`30$`(0!`T0$`/0# -M8"P@971C*>\+`OH#`*D"`&@1`HT``9L!`MH`#\@#"F$B;F5W8R*;`P$S`"=S -M:+```1(`#T8#8P0%!`?.``]9`P`*%@,S5VAE`P(`OP@#U`(2<^8%87)EP`! -MAPD!*Q4"2@P#"@,0;?8-$&EY!P/N$@(,`B$@8C<)07)E862/&`.X%`$,`!!A -M#`$"U!``:``".P`199P6`#T!(79E_!03>4,`M6EN9&5P96YD96YT(@$`1`T! -M>1D`0@42;VP-!K`+#V0:________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M__________________________________]H4&QL;W=I410``/$F;F<@8F5F -M;W)E(&5V86QU871I;F<@=&AE(&%R8VAI=F4Z"B`@*B!U=65N8V]D960@9FEL -M97,4``$*`/$"('=I=&@@4E!-('=R87!P97(;`/$!9WII<"!C;VUPFUA+"!L>FEP+"!A;F0@>'HC```9 -M-!0`]0<*5&AE(&QI8G)A"!I;G1E&-E<'0@9F]J`/$'("!E;G1R:65S('1H870@.`?$#;F%M97,L($%#3',L(&5T8RDND@"P -M3VQD($=.52!T87)=``2I``+*`/$$;V-T970M;W)I96YT960@8W!I;S4`ME-6 -M4C0@(FYE=V,B%0`G`'@G;71R964G -MNP!X25-/.38V,!,`6C2!S=')E86WM`>!S>7-T96TN("!4:&5R92P`\01N;R!D:7)E8W0*("`@`>-R86YD;VT@86-C97-S -M+GD`!I<`\@)I'!L -M86EN:6YGB0`P:&]W^``"]0``C@0#+``"*@$A3VZJ`!PL`P$#V0("<`!`;'=A -M>48!`-T!\@%E9"!A=71O;6%T:6-A;&QY1P"P22=V92!A='1E;7#$`^!T;R!M -M:6YI;6EZ92!S="L`L"!L:6YK('!O;&QUN`'A+B`@268@>6]U(&1O;B?L`0"V -M`/$":6-I=&QY(&EN=F]K92!A('#K`"!U;#<$(&5A60)`("AS=2\!&7,<`A!A -MZ0`'+0`'[P4`@`$"F0%P*2P@:70@=W``X"!G970@<'5L;&5D(&ENI`0W($EN -M;@`W+"!IG@`!40$#FP`B96[)`07L# -M$7`U`-%A=&5V97(@8FQO8VMS\``0:%<%(6ETH0!!66]U2X'<70@82!T:6U7`W%O8!(71O(@`%H0!A="!O;F-EA0`A3VZ0`QMEPP`" -MY`(R<')O.@$!A0%18W1L>2W,``!(!E)U='!U=.\"`&`$\0-O8FIE8W0M2!F)M96UO?<"!8P``0`" -M\05R;W9I9&4@96%S>2UT;RUU8<``J,!!H`%,7=A;H@`$'0V!`5%`0!@``'Z"0".!S!S:RQ. -M`P-^!KEC;VYV96YI96YC9<`!`(D`,&UA:WD`D&ES(&5S<&5C:6X$`=`!`JH! -M`#H(,#H@(I,*#KL*$R*Y`B!L;#P!`N@"`*4'`!$#`L$%0"P*("#,!Q!PWP`` -M;`0`E@`0(',*T"!S87ES+@I214%$346[!@?H!N$@8G5N9&QE+@H*475E<_H" -MH#\@($ES7!1`GH@1`9W)A;18"=&%R+C54 -M`0CQ!`4^$A%S8P0Q<&]PY0\#G`$`>`8`>P`(2PE`:&%R9!8,`3`&!%L!`4<` -M`(X!86UO9&5R;H\``.@!`+P'<"!V87)I86Y("0!$!+%M86YU86P@<&%G93@` -M`#$.`,X4`OH!`)X``1T#5R=D;V,GO060:6X*82!N=6UB\@P79I$'`QX!URX* -M"EEO=2!S:&]U;&2D"P`H`3%C;W!V!D!C;VUMG@@`N`03(@4.,BYH(JD`,FAE -M"E\,02!C;V1U`0`4``3I!@-R"`)_`C1M;W*C`E)S+B`@4(H)LVQE="!U=H+ -M`#L'`2,)"=H1`,$",&5C=)D#$60Y"0,<`@>F%@"E`0!0!0)!%0:J"R8@*`0+ -M`%L5#"`6`1````4+`;X+$G,W`E)S<&%R\6`2T5`A``#XH,`P4P`T&-P:6\N-2P@;71R964)``!O`/(*=&%R+C4@<')O=FED -M92!D971A:6QE9"!I;E(`D&EO;B!A8F]U=$T`('-EN`"#<&]P=6QA3`1!F+`"A#0#46-H86YG -M?@$W;6%T(0"P;V-T970M;W)I96X!`P!@`@$>`*%35E(T($%30TE)=`(!%``" -M4P`/,@`%84)I;F%R>2X`P"`H8FEG+65N9&EA;J(!8VQI='1L91$``OH`\0)) -M4T\Y-C8P($-$+5)/32!I;;<"@"AW:71H(&]PRP/`86P@4F]C:W)I9&=E10!B -M2F]L:65T*0$![P$"20`U6DE0"0$#0`#P"G5N8V]M<')EB,``!DT%``)"`&58V%N(&-R96%TSP`!=00/!@$"`J\!`[\# -M`KP"#Q\#&,$B,H"4B`H9F]R-`0` -MA`$#,P0`]`-Q+"!E=&,I+F\!`/H#`*D"!B($`1<``MH`#\@#"F$B;F5W8R*; -M`P$S`"=S:+```1(`#T8#8P0%!`);`0&)``]9`P`*%@,S5VAE`P(`V`(#U`(2 -M<^8%87)EF4@P,1<#4` -MT6%T979E6QE(&%P -M<')OR`,`R0@"^@#@=&\@:&%V92!M=6QT:7`E``-3!`(!!`"Y"%4@;W!E;IX` -M4"`@8G-D(P2!B=6@-$B`D"`!E``!Z``#!`85A -M('-O8VME=#X#27=I#B)A -M;N@"`*4'`!$#`KH.0"P*("#,!Q!PH@``;`0`E@`!I@[1('-A>7,N"E)%041- -M11(&!Q0'T6)U;F1L92X*"E%U97/Z`J`_("!)3``!(`1!HN`(09K$/,VYG;U@')B`@+`"`(&1E=F5L;W`\ -M!0@9$02Z$0&L"!`LH@0`<0``.@`A;FM=`0!=``='`$!M86EL!P(P;&ESOQ`! -MG0`05)D!`.41`.!L30',Z(%,R`U1S;6%L;!4`!#X!`%(# -M(6%T'`@@;6'F!"!N9-`",69U;"\"!D4`$"]#"@&%`1%AXP$T86-T>Q-P9&5M -M;VYS=#D5(&YG/@``@`4&5`(#20`P8V]N0P)A.B`@5F%R[A-@:71E;7,@,P$` -MUP(B;64V%3)I'2(`"%P=6<0,"`B8S0& -M$2(D`P`X#"EO;$T`(`H*X0@&ZP,!*0$`%@D`C@$/;0$!`+`,$'4]$P(0%R4* -M)[P`$R>M``,D!`"3``!.`/``+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C_P`` -M`@`0+60"`)\`!*@``-D."*($$BP:#@#7"P!9"U%Y(&UA:?8!(V5RK@$%<``D -M:6YD`($N:"YI;@H)+?0'(&QA5@\$NP`%A0`#M0!P"@I'=6ED9;8"$T0.&`*! -M`0/2`0)U``#S`0-3#Q`Z&@D"N`0A+C'!#`!A#`$W`0`]!@-X$P(A``2:`P,S -M``"(!`\T``L`(@`,-0`O870T``PH870S``>M`Q$SM@L`$!20(&]V97)V:65W -M\P(`JP`%P`L`<04P=VAOD0(4*J0*A5]R96%D+C,L$``!^`@-$0!17V1I2XSHQP#R*71H -M92!A=71H;W)S('=I=&@@86YY('%U97-T:6]N'2(`#%P=70I`/D#(F-M86ME(B!B=6EL9"!T;V]L30`"5@$&-0$! -M*0$Q(&EN3`$/;0$!,&%R91`"$F3:`35E"B>\`!,GK0`#9P$`DP``3@#U`2YA -M;2P@86-L;V-A;"YM-"SA`$!E+F%C_P```@`2+50`)'1OJ```(`&`9&ES=')I -M8G5!`;(L(&]N;'D@;F5E9'P`,6UA:?8!(V5R7`$%<``D:6YD`/(#+F@N:6X* -M"2T@=&5M<&QA=&5S9P`18C0"`68!$V6U`'`*"D=U:61EM@*"1&]C=6UE;G2! -M`0#%`3)A;&QU``#S`?4*('-Y`?$#+@H*66]U('-H;W5L9"!A;'-O(@(! -M3``Q8V]P=@8R8V]M6P%#:6X@(KT",BYH(JD`@&AE"G-O=7)C+P`19'4!`!0` -M!.D&`YH#`G\"-&UO<$",&5C=)D#$635``,<`@7"!A!F+``!MP91*B!'3E5U`0*Z`28@*+D! -M`!H`06QO;F=5`F)N86UE'1E;J+``-J`0`9`]$J -M(%!/4TE8('5S=&%R6P`"$``P<&%X20,B97)9!P-X`@@` -M`0H``EP)HE)032!WFEP/@$Q:6]N,`!=8GII<#(6``1D`4TO -M3%I7'0"B;'IM82P@;'IIU`P#P!`![``.?`0![``&'"0&C``)*#`,*`Q!M -M:P@0:7D'$6$O"0,K`"$@8C<)<7)E861A8FP`!@","@$,``$L"P($`0!H``([ -M`$)E86-H/0$A=F5S`Q-Y0P!0:6YD97"J`"5N="(!`!@)``\/$&-"!1)O;`T& -M-0I4(%=I:VE2##!I;F?)`#!H;W>;#`&S`Q=DE@H"*@$A3VX_"`#W#`)X!@,# -M`03-``%P`$!L=V%Y1@$`W0$J962*"`)'`'!))W9E(&%T+0T`C`<`P0^0:6YI -M;6EZ92!S#@T28U((07!O;&R4#5$N("!)9O4(4&1O;B=TJ`"097AP;&EC:71L -MV0EB=F]K92!A^@\18W\*,69E830+,"AS=2\!!?L*`*D`("!A00`!)Q`"+0`( -MS0`4;_D(<"DL(&ET('=P`'$@9V5T('!UG`T0:7H+1R`@26YN`#``%1 -M`0.;`")E;LD!!RT``#X`"W$`*&1E$0`#Q@(1+/```H```(T.`)8!`!8!`$`` -M(&%G`PX"4`.18V]RF5H!P*(`5!A;&QY+78``#,,`/<($6F'!@"$`'!E;G9IP,1<#4`T6%T979E2W,`))E9"!O=71P=73O`@!@!/$#;V)J96-T+7-T>6QE(&%P<')OR`,`0Q(" -M^@#@=&\@:&%V92!M=6QT:7`E```A!1!V$@-`4X.``P1$2(A`0!: -M""`L(E`(H"P@8V%P86)I;&D2%`8#`0"_``'Q``+S#P$_#@CV!0&7`8`@:6YD -M:79I9&P.`&@%$6E""`![`!)B0@`$K`4`-@$A=&^L#3!D8737```%#A$ZP0(! -M+@$"R`D`P@`28>P"`&$#`2L`,VEN("#U%F -M:7)S=)("`*8!$6%P$A%O61$`]@`6+G0``]D#`J#B)A;N@"`*4' -M!C0*0"P*("#,!Q!PYP$`;`0`E@`!I@YS('-A>7,N"B05$6:X#01Q%K0@8G5N -M9&QE+@H*41$6H#\@($ES%E2!F -M:6QE+B`@66]U(&-A;B!A;'-O(')E860@86X@96YT6]U('=A -M;G1$`!)T70`2+ST``&``,&EE'1E;F1E9#@!`B(`D"P*("`@9&5S<-\`0'=H8726`/`#(&YA;64@8$(&YDT`(Q -M9G5L+P(&10!1+VUI;FF%`1%AXP%186-T('-@`+`@9&5M;VYS=')A=+'!L@P(# -M+P,`0@$"(0`$F@,#,P``B`0/-``+`"(`##4`+V%T-``,*&%T,P`&`0:`+C,@ -M9VEV97/?!H!O=F5R=FEE=_,"`*``!+L%$&%Q!3!W:&^1`A0J[`B%7W)E860N -M,RP0``&["`T1`%%?9&ES:Q8``GX'`RH)`3X``QP``)D`$'9?`0*W`F%E9"!C -M86R)!Q!SU`9!;F-EP$2+8($4W,N-2!D5@(`G@419?L#`/(`Q&UA=',@``&I`5"`"X!!,B?P(R+F@BJ0"`:&4*`D09BP``;<&42H@1TY5=0$"-0(F("@$"P`: -M`$%L;VYG50(`K0LB+``-J`0`9`]$J(%!/4TE8('5S=&%R -M6P`"$``/B@P#!R$`L&]C=&5T+6]R:65N`0,`8`(!'@"A4U92-"!!4T-)270" -M`10``E,`#S(`!6%":6YAFEP,A8`!&0!32],6E<=`*)L>FUA+"!L>FEP$P,O -M>'HC```9-!0`"0@!```*56-R96%TSP`!=00/!@$"`JH#`[\#`KP"#Q\#&#`B -M&-E<$`% -M$`I;"0-I`E$@=&AA=$,.,6ER95$``0$0`?P(-F5A;;4%`A$+<"X@(%1H97(T -M$2`@;M82,7)E8S`1`]\(`),$02!I;BVW#X(@;6]D:69I8^4,\@%OP`!APD!HP`"2@P`31%`:7)E;?8-$&EY!P/N$@(K`"$@ -M8C<)<7)E861A8FP`!@","@$,``$L"P+4$`!H``([`$)E86-H/0$A=F5S`Q-Y -M0P!0:6YD97"J`"5N="(!`$0-``\/$&-"!1)O;`T&-0I4(%=I:VE2##!I;F?) -M`#!H;W?X``&S`Q!DK0$#V@`"*@$A3VX_"`#W#`)X!@#S#@!0!@/-``%P`%-L -M=V%YF4@'!L:6-I#16":6YV;VME(&'Z#Q%C?PH# -MSA$@("C2$"4@8?L*`*$!("!AZ0`!)Q`"+0`(S0`4;W,$<"DL(&ET('=P`%`@ -M9V5T(-(2`5T*`*0$-R!);FX`,BP@:8(5`9X``5$!`YL`(F5NR0$'+0``?``+ -M<0`H9&41``/&`A$LY0D"@```C0X`E@$`%@$`0``P86=A\P\!7PJ18V]RP,1<#4`8F%T979E2X'$'2B%R%I;5<# -M<6]R(&UM87`I`0!>$P'Y%@([`P"V`A!GPA<0:2(3`2(`!:$``.,3(6-EA0`A -M3VZ0`QMEPP`"Y`(R<')O.@$!A0$`FA"9"!O=71P=73O`@!@!/$# -M;V)J96-T+7-T>6QE(&%P<')OR`,`@0L"^@#@=&\@:&%V92!M=6QT:7`E```A -M!1!V$@-`:89`@4.%CHN`0+( -M"0#"``]D&O__________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M________________________:E`*("H@3U(4``#XNFX@2!I -M;G9O:V4@82!P87)T:6-U;&%R(&9E871U!E('-O;64@=71I;&ET>3X`!8P` -M`+$!\09P2!D8737`%9U -MP"`&$#`2L`,VEN(""!I;G1E7,N"E)%041-15``1"!L:6)M`=%B=6YD;&4N"@I1=65S^@*@/R`@ -M27-S=65S/U(`UBH@:'1T<#HO+W=W=RXX`$`N;W)GDP``2`$0:+@"L&9O`<``$D!0'-U8V@G`%`J(&5X84D`0',Z(%,R`U1S;6%L -M;!4`!#X!`%(#(6%T'`@@;6'F!"!N9-`",69U;"\"!D4`$"]#"@&%`1%AXP%1 -M86-T('-@`+`@9&5M;VYS=')A=+P`"-E)ZT``V7-T96TZ&@D"N`0A+C'! -M#`!A#`$W`0,O`P`+``(A``2:`P,S``"(!`\T``L`(@`,-0`O870T``PH870S -M``8!!B$N,[8+$'-E"H!O=F5R=FEE=_,"`*``!0H,`'$%,'=H;Y$"%"JD"H5? -MPH"MP(2 -M9:`,`%L$$'/4!A!N2PT`U@(`DP``=0``%P(`^00!<0`!<0H(EP!S96YT=H+`#L'`2,)"=H1`,$",&5C=)D#$60Y"0,<`@5X"1!F!A(! -MMP91*B!'3E5U`0+4!B8@*`0+`!H`(VQOO`4`K0LB+``-J -M`0`9`[$J(%!/4TE8('5S=+`1!!``#XH,`P%\``(Q`+!O8W1E="UO\!`DD`-5I)4`D!`T``('5N -M3@D`[!,`UA!@FEP/@$@:6]/$WTJ(&)Z:7`R%@`$?`%-+TQ: -M5QT`HFQZ;6$L(&QZ:7`3`R]X>B,``!DT%``)"`$```H"G!`%.@$`=00/!@$" -M`J\!`[\#`KP"#Q\#&#`B,H"("`H?0?P(-F5A;;4%`A$+!8@4 -M0&ES(&[6$C%R96,P$0/?"`"1`D$@:6XMMP^"(&UO9&EF:6/E#)%O`3AN97>U`P#P -M!`#]`@.?`0![``&'"0$K%0)*#`,*`Q!M]@T0:7D'`^X2`BL`(2!B-PE!FEP,A8`!"8`32],6E<=`/\#;'IM82P@ -M;'II<"P@86YD('AZ(P``&304`/$R"E1H92!L:6)R87)Y(&-A;B!C&-E<'1_`/$*"B`@ -M("!E;G1R:65S('1H870@$ -M`?$#;F%M97,L($%#3',L(&5T8RDND@"P3VQD($=.52!T87)=``2I``+*`/$$ -M;V-T970M;W)I96YT960@8W!I;S4`ME-64C0@(FYE=V,B%0`G`'@G;71R964GNP!X25-/.38V,!,`6C0`&EP#R`FES(&1E$N("!)9B!Y;W4@9&]N)^P!`+8`\0)I8VET;'D@:6YV;VME(&$@<.L` -M('5L-P0@96%9`D`@*'-U+P$9``%1`0.;`")E;LD!!RT` -M`'P`"W$`*&1E$0`#J@`1+/```H``(FYEC@(`%@$`0`!B86=A:6YS1P*@8V]R -MP,1<#4`T6%T979E2!B=69F97(@)`@`90`$<@&%82!S;V-K970^`TEW:7-H -MN@3`P"`,,)`2L`,VEN("0"0:7,@97-P96-I;@0!T`$"J@$`.@@P.B`BDPH.NPH3(KD"(&QL/`$" -MZ`(`I0<`$0,"P05`+`H@(,P'$'#?``!L!`"6`!`@7,N"E)%041- -M1;L&!^@&X2!B=6YD;&4N"@I1=65S^@*@/R`@27-S=65S/U(`UBH@:'1T<#HO -M+W=W=RXX`$`N;W)GDP``2`$0:+@"@V9OB!$!GF-%#A)B!P`2>`<``$D!`)()`"<`4"H@ -M97AA20!`8$(&YDT`(Q9G5L -M+P(&10`0+T,*`84!$6'C`5%A8W0@T/4'1O -M<"UL#`0#Q0P`,`0&";8"(FENU@0`=`P`ZP40<],-\`4@*B!.15=3 -M("T@:&EG:&QI9VAT'2(`")P==8-(")C-`81(B0#`#@,*6]L -M30`@"@K>!P;K`P$I`0`6"0".`0]M`0$`^0<@=7/="@#:`31E"B>P`"-E)ZT` -M`V!Q(M@@13``$=`U`=\!`DD`#QX78P\+%P#3 -M36EC4P`T&-P:6\N-2P@;71R964)`/(. -M86YD('1AP$R+F@BJ0"`:&4*2!E2QN``/2`>`@875T;VUA=&EC86QL>68!065C='.H``#5``,<`E!O -M;&QO=Y,!$&8L`*!S.@H@("H@1TY5^`$`J`!6;6%T("BY`0`:`$%L;VYG50)B -M;F%M97,L$`!3;&EN:R`1``"T`5)S<&%R'1E;J+``-J`1%S2P"W4$]325@@=7-T87(0 -M`.%P87@@:6YT97)C:&%N9WX!-VUA="$`L&]C=&5T+6]R:65N`0,`8`(!'@"A -M4U92-"!!4T-)270"`10``F,`#S(`!6%":6YAB,``!DT%``)"`&58V%N(&-R -M96%TSP`!=00/!@$"`NP"`[\#`KP"#Q\#&,$B,H"4B`H9F]R-`0`A`$#,P0`]`-Q+"!E=&,I+F\!`/H#`*D"!B($ -M`1<``MH`#\@#"F$B;F5W8R*;`P$S`"=S:+```1(`#T8#8P0%!`);`0&)``]9 -M`P`*%@,S5VAE`P(`V`(#U`(2<^8%87)EF4@7L#$7`U`-%A=&5V97(@8FQO8VMS\```[@2X' -M<70@82!T:6U7`P!K"S%M87#X`C!E;G21!@/0`@%1`T!G:79EY@$A=&\B``6A -M`&%T(&]N8V6%`"%/;I`#&V7#``+D`C)P`%`@(&)S9",'(75SO`$`/06#;B!I -M=',@(D#E`!(BO01&2!F4X.475S92`B(0$`6@@@+")0"'`L(&-A -M<&%B00`!]@("9@81954"`?$`864@05!)P" -M`,D*`2L`,VEN("#U%F:7)S=)("`*8!(&$@ -M0P41;U`'`/8`%BYT``/9`P*G`0"_``*<`0&%``:X`0!V``*4`0!*`P&3``(Q -M#R!L>60!`,P``*,!!H`%,7=A;G\%$G0=#P-%`0!@```:!!!TC@!L3 -M0',Z(%,R`U1S;6%L;!4`!#X!`%(#(6%T'`@@;6'F!"!N9-`",69U;"\"!D4` -M$"]#"@&%`1%AXP$T86-T>Q."9&5M;VYS=')*#0`.`R=O9EX!`TD`,&-O;D," -M83H@(%9AP``7P%C875T:&]R:1``EPT!\@(`P1,2+NT/4'1O<"UL#`0#Q0P`,`0&";8""',5`.L%`>X/\`4@*B!.15=3("T@:&EG:&QI9VAT\`!,GK0`#)`0`DP``3@#P`"YA;2P@86-L -M;V-A;"YM-`D-`^T`,"YA8_\```(`$"VB`@"?``2H``#9#@BB!!(L&@X`UPL` -M60L0>\%1FYA;'.=`!)S -M/@MA:6YS:6=H$08(F0<1)V<"!#<``&@1,'5C=+(#`*@`,&]P92L%`#0,"1X' -M$BU8"0]D&O__________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M________________________5E!C="!S85<4``#T4VUP;&4@9&5M;VYS=')A -M=&EN9R!U4$`,6EN'2(`#%P=70I`/D#(F-M86ME(B!B=6EL9"!T -M;V]L30`"5@$&-0$!*0$Q(&EN3`$/;0$!,&%R91`"$F3:`35E"B>\`!,GK0`# -M9P$`DP``3@#U`2YA;2P@86-L;V-A;"YM-"SA`$!E+F%C_P```@`2+50`)'1O -MJ```(`&`9&ES=')I8G5!`;(L(&]N;'D@;F5E9'P`,6UA:?8!(V5R7`$%<``D -M:6YD`/(#+F@N:6X*"2T@=&5M<&QA=&5S9P`18C0"`68!$V6U`/($"@I'=6ED -M92!T;R!$;V-U;65N=($!`,4!,F%L;'4``/,!]0H@'!L@P(#+P,`0@$"(0"#('!R;V=R86TS`$]C<&EO-``+`"(`##4` -M+V%T-``,*&%T,P`'K0/P!#,@9VEV97,@86X@;W9E2!A``"/ -M`&<@)V1O8R>]!;!I;@IA(&YU;6)E2QN``5H`S!U=&^3!@#_`A!Y9@$P96-TF0,19-4``QP"!<(&$&8L``&W -M!E$J($=.574!`KH!)B`HN0$`&@!!;&]N9U4"8FYA;65S+!``4VQI;FL@$0`` -M8P!A@``0H``EP)HE)032!WFEP/@$Q -M:6]N,`!=8GII<#(6``1D`4TO3%I7'0"B;'IM82P@;'IIU`P#P!`![ -M``.?`0![``&'"0&C``)*#`,*`Q!M:P@0:7D'$F$)`0(K`"$@8C<)<7)E861A -M8FP`!@","@$,``$L"P($`0!H``([`$)E86-H/0$A=F5S`Q-Y0P!0:6YD97"J -M`"5N="(!`!@)``\/$&-"!1)O;`T&-0I4(%=I:VE2##!I;F?)`#!H;W>;#`&S -M`Q=DE@H"*@$A3VX_"`#W#`)X!@,#`0/X``&("5!A;'=A>48!`-T!*F5DB@@" -M1P!P22=V92!A="T-`(P'`,$/D&EN:6UI>F4@@M'("!);FX`-RP@:9X``5$!`YL`(F5NR0$'+0``/@`+<0`H -M9&41``/&`A$L\``"@```C0X`E@$`%@$`0``@86<##A%T\0F18V]RP,B:67-#P%O`P/G"C%D=6.Y!5%E('-I>H,1`H@!4&%L -M;'DM=@``,PP`]P@1:8<&`(0`<&5N=FER;V[7`C%S('>0`P&@`A!MV`$3`!,@%1``:A``"@$`/06#;B!I=',@(D#E -M`!(BO0012!F@``S0*%82!S;V-K970^`TEW:7-HN@1$!L30',Z(%,R`U1S;6%L;!4`!#X!`%(# -M`Q,9(&UAY@0@;F30`C%F=6PO`@9%`%$O;6EN:84!$6'C`31A8W1[$P]D&O__ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________:%!C:&EV94<4``#P/2!W:71H;W5T"B`@(&9I0#P*FES(&5S<&5C:6%L;'D@96%S>2X*"B`J($YO=&4Z(")P87@@:6YT -M97)C:&%N9V4@9F]R;6%T(B!I<^```#,`\P!A;B!E>'1E;F1E9"!T87(B`)`L -M"B`@(&1E7,N"E)%041-12X`1"!L:6(3 -M`=%B=6YD;&4N"@I1=65SK@"@/R`@27-S=65S/U(`UBH@:'1T<#HO+W=W=RXX -M`$`N;W)GDP``2`$Q:&]MIP"`(&]N9V]I;F6H`)V%T:0`K871H`&ES:6UP;&6U`$!T;V]L,P$` -M0``#`@!R>F-A="P@8@<`$G@'``!)`4!S=6-H)P!0*B!E>&%)`$!S.B!3,@-4 -M2!F:6YDT`(Q9G5L+P(&10!1+VUI;FF% -M`1%AXP%186-T('-@`*$@9&5M;VYS=')A-04`#@,G;V9>`0-)`#!C;VY#`O`" -M.B`@5F%R:6]UP``7P%Q875T:&]R<\`%42!A;GD@\@(``050+@H*5&B=`3!P -M+6P,!`-V!3!O'2(`#!P=71>`C`@(F,T!A$B)`-I -M9"!T;V]L30`"5@$&ZP,`%`=!'!L@P(#+P,`0@$"(0`$F@,#,P`` -MB`0/-``+`"(`##4`+V%T-``,*&%T,P`&`0:`+C,@9VEV97/?!H!O=F5R=FEE -M=_,"`*``!+L%$&%Q!3!W:&^1`A0J[`B%7W)E860N,RP0``&["`T1`%%?9&ES -M:Q8``GX'`Q<(`3X``QP``)D`$'9?`0*W`F%E9"!C86R)!Q!SU`9!;F-EP$2+8($4W,N-2!D5@(` -MG@419?L#`/(`Q&UA=',@``&I`5=H+`#L'`2,)@&%U=&]M871I_P(0><$",&5C=)D#$60Y -M"0,<`@5X"1!F+``!MP91*B!'3E5U`0(U`B8@*`0+`!H`06QO;F=5`@"M"R)S -M+!````4+`;X+$G,W`E)S<&%R`*%35E(T($%30TE)=`(!%``"4P`/,@`%84)I -M;F%R>2X`P"`H8FEG+65N9&EA;J(!8VQI='1L91$``OH`\0))4T\Y-C8P($-$ -M+5)/32!I;;<"@"AW:71H(&]PRP/`86P@4F]C:W)I9&=E10!B2F]L:65T*0$! -M[P$"20`U6DE0"0$#0``@=6Y."3!R97/3!G!OU`P$3`%HW+5II<"8`V$UI -M8W)OB,``!DT%``)"`$` -M``I58W)E873/``$M"0\&`0("J@,#OP,"O`(/'P,8,")R9:`-46-T960B1P," -M3P#$+"!W:&EC:"!W:6QLB@`!5@`%R@%A(&5X8V5P0`40"EL)`VD"42!T:&%T -M0PX0:98%)V%XR@(@("@6!0$T!`"$`0-$!`#T`V`L(&5T8RGO"P+Z`P"I`@8P -M$`&&`0+:``_(`PIA(FYE=V,BFP,!,P`G0`&@`0`L!!0 -M97-I9VZP$D)O(&)EO@(`0`0!7@$X;F5WM0,`\`0`_0(#P`!APD!HP`" -M2@P`31%`:7)E;?8-$&EY!P/N$@(K`"$@8C<)<7)E861A8FP`!@","@$,``$L -M"P+4$`!H``([`$)E86-H/0$2=MT3$WE#`%!I;F1E<*H`)6YT(@$`1`T`#P\0 -M8T(%$F]L#08U"E0@5VEK:5(,,&EN9\D`,&AO=_@``K03`*T!`]H``O<3(4]N -M/P@`]PP">`8`\PX`4`8#S0`!<`!3;'=A>7-S""IE9(H(`D<`<$DG=F4@870A -M%0",!S!T;R`A$'!M:7IE('-TM0@"4@A0<&]L;'4B!P;D%$%D;VXG[`%P97AP -M;&EC:0T58&EN=F]K9;P2`>L``7\*`\X1("`HTA`E(&'["@"A`2`@8>D``2<0 -M`BT`",T`%&_Y"'`I+"!I="!W<`!!(&=E=!D3`5T*`*0$-R!);FX`,BP@:8(5 -M`9X``5$!`YL`(F5NR0$'+0``?``+<0`H9&41``/&`A$LY0D"@```C0X`E@$` -M%@$`0``P86=A\P\`7L#$7`U`-%A -M=&5V97(@8FQO8VMS\```[@!#%FQ6QE(&%P<')OR`,` -M@0L"^@#@=&\@:&%V92!M=6QT:7`E```A!1!V$@-`P",B!O9BL`,VEN("2!I -M;G9O:V4@82!P87)T:6-U;&%R(&9E871U`<``$D!`/X&`"<`4"H@97AA20!`4$`(&EN^``(M@(B:6X#"``0""!F:34!`'P`\`LJ($Y%5U,@+2!H -M:6=H;&EG:'1S(&]F(')E8P8"5&-H86YGH`*P0T]064E.1R`M('<3!P"Y"&)C -M86X@9&^?`#-T:&DI`*!)3E-404Q,("T@T`'2(`")P=28)<2)C;6%K92(D`P"D -M"2EO;$T``E8!!NL#`)0`07,@:6Y,`0]M`0$P87)E3@(29-H!-64*)[P`$R>M -M``,D!`"3``!.`/4!+F%M+"!A8VQO8V%L+FTT+.$`0&4N86/_```"`!(M5``D -M=&^H```@`0BB!+`L(&]N;'D@;F5E9,4($'G*!0'V`2-E%7W)E860N,RP0``#1 -M!1UE$0!17V1I -M=&%R+C54`0CQ!$%A8F]U4P4@"`"X!!,B -MO0(R+F@BJ0"`:&4*2R"```[!P$C"8!A=71O;6%T:?\"$'G!`C!E8W29`Q%D80T# -M'`(%>`D09BP``;<&42H@1TY5=0$"-0(F("@$"P`:`$%L;VYG4`9B;F%M97,L -M$```!0L3(!$``&,`4G-P87)S?`(A`@@;W#+`\!A;"!2;V-KFEP,A8`!'P!32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC -M```9-!0`"0@!```*56-R96%TSP`!+0D/!@$"`JH#`[\#`KP"#Q\#&#`B&-E<$`%`+D% -M!&D"`M<1`$,.$&F6!2=A>,H"("`H%@4!-`0`A`$#,P0`]`-@+"!E=&,I[PL" -M^@,`J0(&(@0!FP$"V@`/E@,%`<@#82)N97=C(IL#`3,`)W-HL``!$@`/1@-C -M!`4$`EL!`8D`#UD#``H6`S-7:&4#`@"_"`/4`A)SY@5A?P(-F5A;;4%`A$+02X@(%1`%%-I4,`4&EN9&5PJ@`E;G0B -M`0!$#0'E%@!"!1)O;`T&L`M4(%=I:VE2#`,,$S!H;W=1#P*F!P!."`/:``N@ -M%03\!`#S#@!0!@/-``%P`$!L=V%Y1@$`W0$J962*"`)'``_0%__@"?H#$&,W -M!@`%&,)A=&5V97(@8FQO8VO5"@#N!S`@:70(!D(@66]UYQ,!Q`U`8F%C:T`# -M,69R93T/,'!A2X'<70@82!T:6U7`W%O2W,``"."5)U='!U=.\"`&`$H&]B:F5C="US='G@ -M&4%P<')OR`,`^10"^@!0=&\@:&$Y%D!U;'1IPQ,$J0`"`00`N0A5(&]P96Z> -M`!0@]`\A=7-U!Q%I(0AC:71S(")`/``2(KT$$',3&P7J!`,<`'`@:71S96QF -M4P$`?000+P(/8'1E;B!U7,N"@`!`/^)`#L7#Y\!30\`'@M1-S$Q-S4`'F$Q-3$U-3(`'B\U,0`> -M_U771F5B(#`Y+"`R,#$S.H<*D2`S+C$N,B!R93(3GF0*"DIA;B`R."D`(2=S -MJPM`=V5B!A(N3``N,3-,``%U`!LQ=0`/*0`&%S`I`&%$ -M96,@,#=2`$`R.B!)4AL!"`P("@4#T!0`[PP991H,`)T%`ML-`DX8`9`(A"`* -M3F]V(#$Q5``@062V&P:L(H-?7TU!0T]36!<-`(('.&EN(,01!-D/(G)EJ08` -M)P4`N`P2:P@','-T;TL.`+@B?PI/8W0@,C!K``4`.08`A@82=J43`@,,`S8` -M`[P!#Z$``"MGF]P5`%64V5P(#*!``VH`0+.&7%T;R!S -M965KD`I&@'5`@DX`P#*"C)I97-.``*:!&$Q.B!.97>:`PI(``0;`UES(%-&6`,% -M"S\`0$)U:6QK!0"Y`:)O;B!7:6YD;W=S(0$#YP4.2P$K,&%+`14P2P$P57!D -MN!5T`P,,RUS._@6"*$9`ADA$F_B'$!H87)D4P(E+W-;`E%B&0"5##!E;747&6D@8G)O:V5B`#`R+GAG!`!W -M$`&O)2%O9K(6<5541BTX(&AH`!)SF04%^P!`4F5F85D'`04/$%]R#B`H*7L: -M`"\-46-O;&QEB"$`XPT`2@\P;&4MJR(`W`<`YR@!EB(#+`$!D`P@;VPA`P,2 -M)!!S'Q\@=W(,`0-W`!(Q$`:!,3H@4W!L:71?#0(`!@`L`0&1!C!P87)N`@(> -M%P`T"`/``@":`Q%L^24";`(!QP`5,30#`X(#`L\AE`=V]R:V(!9')E='5R;JP<`)`B`2$/$&;N -M`@%9`7%A8F]R="@I1``&-04`M0$`>0`W%SM#.3`"`07@ -M`"9O;LT#`=P'!GP!$4;T!@`G`:)!25@L(%12538T]QJ@;W1H97(@<&QA=(4! -M$G/-!@+4`B$P.D`<`\T#`1T'`EP"H3`Z($Q(02],6DAC`P'J`S)L(#`U`B$P -M.OPM`!L:`Z,F!T,F$&5F!`'?$P*5!`$N`P+1$``)"S!TH2`-@48F5N(&-O<)01``X#`1X2!,@)`4$``XD%$#`(`@&R)P!X`'8@ -M36%C($]3J0(`/``'K@0!.@`#0@(D,#I0``?K``"J"0/]`A!S7@D"[@!4&D1%0*G!`/4 -M!P`:`0"4'0.-"@)C``:;``-=!`'?(080!00'`@0;`V!C(&-R>7#%!`+!#`&/ -M``/[!B$P.CT=`0("`"P&`A`$`"8#`$<%`BH``@4-$C``"`/4`Q(Z+@=`+6=I -M9`8``"H$02`M+74.`!!U#@`!!P4#,@X#P`%@4F5D+6)L8!8`_"(!E`<&_@$! -M&14@97)D`P,C`@!4!`#.`@!8*P%.``,)`P!*`F)I;FEM86RM``$3#7@@;&5G -M86-YM0#,O -M`G@5`,0#`#(=`I`%`W8(`[X!`+\'$F0K``"1(#EL9&5?"`!=&Q!LNP$`%0X! -M0"@A963+`P80`55296QA>`,"`,(%('-T7P;09F%I;'5R97,[(&UIF7'`P`M`0!Q`0-7!`!_&"%O;88'#%$``8X%4&YT-C1? -MS`L%``>@;V9F7W0L(&1E=@<`,&EN;P<`,'5I9`<``#\#$&<+``*<``7^!`08 -M*`'"$#9!0TQ%"0)U`!4QN@024SD#!C48`20!!28#`$0!$C`B!P%J!``&$0)\ -M)@.6`@<*"3$Q+G@-%P&,``:%`Q!2R`=%869I;PX)`54`!<,%$$'''0!6``?S -M(P4Q!2%L>2P/!/T"`EL`!;L!8$EN=&5G) -M``9"``+3`P`I`Y!F=71I;65S*"DX+F)#>6=W:6YK$@9%`0>'`78R+CQA`;&5A:U0!"!X!`$@`$G,S``5<`0!D``FUA+WAZ6P,#X0(`9P`$%B`)`@@"0`0` -MGP43>?(.`$D`$4C()"`@9_X2`D4``-@)!$$`0$]P96Z4)7`B9WIS:6`@)[``6)`D!!9&1IR0HP86P@2@!` -M-P)M(B%S98$#!+`=!),-!'4'85=!4DX*"1PK06ES(&/Z -M,Q5OPP<`U1U0861A<'2;."!N91PC,V%R>;L!"=\`55-T=61I8`L`E@`/2@`!-`E!;!$# -M``@!`%HA`5\``_40`/,``.D#,$1E8E\!L4)U9R`C-3$V-34.`?$.`*8$`+$H4$AUA,` -M2P$41:L>!]$(`8(`)&]N*Q8!\0P"]PM`;F]W"?P#`9<2`78,$G11``85!@#0 -M``.@"@8,#A!?*A4@>5\/!A!?;P8P*"D@6"X$[`\`00PQ+`H)2!R7!,@961S(`#/"P"])@!1 -M,#`L"@E4!`"`!P!:#0#B!@!A!0:^`P`\`R!T(",%"7$F`;L`!LHA(@H)?0`4 -M<^@OQ6)E(&UU8V@@96%S:>8-`H\/*RX@HC,`311":&4*"3$8`5\1"$(G%',] -M)P;1#P"#'`-Q`!(N_!`"MP80.$4$)&YY:Q8:+Z\#`HH6`+L!#_D#`@U)``J[ -M"0B[&0+W'`%*``1;`@+Y#!!CN@$@97)^)2ET;W89`$T&`'PT`@2US:7IE9`4/$G.*)3$@*A$)SAH`A@,/[A<"`!<-L2@I(&AAFEPEP2"_`0`P`"`@ -M82D`*RDNM@#@2F]E0,A -M(&*Q'`&[$P%-$P!7!B)A=$H`!9X'`<4(`AQ``-A"`FLK`)$I4F0@8G5GQ0(@ -M.L%`&P"!/P> -M"K`3``XT`,T``$8$`3,8!B,&`;X<`681`$LA!O8?`FD#`#\.``D)$V'=0W,B -M4V-O='0BW!80(%0```L*!9X#$VV#/A!SU`8$-0"22V5E'!L;P$0`&T6$&5D -M#0)M`0)E+95V97)F;&]WPP$_@D$V@Y0"@EP2P!$'26$`&#.%%E(&)O9(L] -M``8-`8D!`#8!,#L*"6T&$FG,$@#0`2%O=:T-P')A;F=E(&)E:&%V:2U/`$0. -M`0L,!!0[`9@)$7)R`0&K`0)],U$M3A+,&ER95<8!&@8,"-I -M9O4,!'@8`H9`.`K@-`=0/$"V!+C%E8V^!!5)L;V=I -M8[$5`C0`$',T``!.%0)/(@'V%`!V`0$8``);20*;%P-]`@;4"`E3`D0T+C$T -M>AY`9#L@:5P\`%)$`)@#`1X`&#,$0"()84H*`%,!`?`($&=+!1$O=B-@(&UI -M>'5PWRD&R!8"L0``P@D4:<0O(F0*[18`9P0"A"D!'@<2+L@?!N8.#*8`%3.F -M``*3&`7Y`@-V'0"=!A$L3`(`DP`2+)H`$"PL!`*>``$[`2!C8640$6*8"S%V -M97+;`P32)P&-`". -M``#3"P"!`&`@8VQA`B4&1E=FEC5@$! -MRR$!32(`B0H`2!@3(G`#&2*)"``6$`(U!D!N97=CM@("<0@#I``6.^0#`O$1 -M`%P"`6,$"$T!`#4"`!`A('1H2PL!>P`"G!LE.#I(#0)E#@-J)P!(`@2;`PDD -M$1PL6PT`.QH'004P26=NR@@$[`I"('-I>ND,`$,-`B@K`#0.$F&[(@#8"P#^ -M(14RC@`,7@(6,EX""BD``*@!(&)A4T$`58(`$D:,6=E=)H-`J4\`6(+!,U5`'$:`8X%13(N.2Z" -M`0(Z``!(`1)L5#$08A,9`=L+!^$/(B@MI0]`+7HI+*L#`"$/,0EO9JH-,')M -M85X2`)X?,F5S'!E -M-\4"%C'%`@HI`#!&:7BF00&U)0#H$P+X)`9A`0"G!`&Q"04]#P%J``(_*P]J -M``$,S!D"8006-X8(4#`N.2XPQ@<`@0<"SE,@=VFA%3-U?@=`70``Q`;$C>)!5!A(&-O=90<(V]FE@0'K28`Y04!?P`"J0\. -MIP`'\A4**```6P``J0,!IP`!!0`17VD!$%_?!"%B>=DQ`D4!`@"&!P8T4@2$`E`M+61I0H& -M%`!U86-L+`H)=.T!_P!386UU;&D@4W5O;6EN96Z,``T'/@D!_``%C``&/P+` -M3&%P;R!,=6-H:6YIU04`>E4!20(`3AP!54D`!0X!T@D!FB0#2@4`DP$@;&17 -M"0%5+@#Z&P1O!#!B=6?&!0$8``!``;!O9@H)(FQE;F=T:)X4D&5N9"(@9FQA -M9QX*!6$`$G,?!`96`0).``,"!!$@FP8!4@8!/@(`J08!+P0$-P`%\P,01J,! -M0"!C=71K`$!R96%L>0<`-```D0(`Z`42;AU(`0\!!38`"Q@(%C+:`@+$`0\I -M``46,2D`"E$`$4W_)@"X!D%S+"!R%Q@`E```P0*@9&]C+71O+6UA;C\.`WX' -M`'H!(`H)%``!NB0#.CL/]`4&!XD%"B@``G@``"4(`/$%`#(4!CP"`[H,4&-H -M:6QL!Q<+.P`03Y`&`-D0`/`"`O<'(B!A>U8@(&_I%P'8"P#Q#S%G:6Y\*2!O -M9L\&(PH)$P(!6!X"IQL"K%@"S0(#CQL`+1D`3P4"2C0`+5<`#P@2>88`!G,& -M$%0$!@,S```5`0`X!!-Y\Q``6!(`0@0`QB4`NR(#Y@D8.I@"`FT(`#4((&5X -MU!8`0D4$.``!YAXS,D="?R8S,51":`$"5CD-#`48,RX:`"T!!B@`$D,/"`(_ -M!R5U;E@G`LP.`%T5`7-#`-H$``,#`+(``"H!$"*:`0#Z$P##'T!N;VYEC@L% -M9!T!?@00;H`,#(O,V(#`7T``-@"`68( -M!M,#D$IA;B!00P`4,#`!`,`-D2`.L( -M,$=.55L!$"><*$%G+71AE`(&[UP`FP`U;W-E,@`!7QA`960@;2\B0'=A&%C=&QY"@EA*R``YA<@-$>T"`/@$@=H$0&=`0(;#@=G``!;`0!F``=#`E`H -M/CA'*>,`!3X"`-0``-P20V%S"@E&.`'M"T!)('!U\"\)C0(`(1`#)`$%&"\` -M3`$`P50!A``%+`<32=0(`=D+`-@'$&5_)P`!`U!N+6UA=&\%`!5=`-0^(6]R -M00R".R!)"@EH;W!(#9$@979E;G1U86P\)0'Q3``?`0`P"S)D92`G"@!#*`+. -M"0#.50,5/P)K#@R7!A@SEP8`J@`5,"X!($-O(QH0=9``!*T`!'8%`%P"`9@J -M$F7?``8U`!!.+4T!6%8`Y4``M`03+/<+`7`(,")(:>\*('DBM0$#3@`@+C$X -M"0'/#`"O`!0Q.0`#Y"$&7```F`<5>C0\`)<"D6EM;65D:6%T90T!`9`X,$5/ -M1M$J`(P?,'1R><\/`?X5!<,4`!$.,')E9V$F`8D+`.(/`%T%`-(D`!4``,\; -M`6X2$'B2%0):#P3+"P"=`R%O9H0``Z$"`&4(`+X[#Y$%!!@S:0<`*``#T!`0 -M-]`C`54!$TU''"`N8205`4X'`!($$B#'(!,O`P@$:A)#"@EA8_P!(61O*`!1 -M@,%1DL# -M#`H`QP5`*"D*"4L'`=$2`+4,$FUJ5B5I;I(+`Y@``P8=#GX#!RD(`)@`!B@` -M`:(X`88"`.D"`RL#4R`P+C,ZO#P&[A`165TG!`2*;L``NL]`GX2`!L\`PP"`SPP#G8`!V$-4D%U9R`S+R02-^,R`+,R -M`)D#!+P&`BL>`(,+(W,L7&,`J@4D86[/6P2`!40*"2A!K1<991L1`*HE(2XI -M;``#310!F`1`860@9QD+\0$Q+C$W("TM<&]S:7@@+2US22<$D@<2+C<`!3@, -M$U*S&F!S=6ED+W.+.00R$03O"T`[(&ET'00%=@0@"@E/&D!RQ,2(M+6`%%"W0`0,R!@&^)0"]*!5RF!,1 -M"ND`!H4&"5@$-C(N-L`#`$@!!B@``0D'"]4-!\`-`ED&`&T&,6%N:QL'`88+ -M*`H)$B4#NP`%[`($0!X`20T"&P0!N@H$Z"LQ0U9361\`V$@G=6R=`0NT``?Y -M#@(I``_&#`,8,AL(`5$`!2@`!E,*"B8B$B=/)@"$"@1$(0&4`A%D*`4`H`($ -MXQ,R8W)I6!A2\`!ZP' -M`8HD`?(]`/T+`'D("%H0`.````$/`(P#`&4H`/8=(!"PL! -M%C(Z$PHH```+`0[=!1`@D0,"3"(`!`P"EP-0>2!C;&\0#@"5*4%T8L<`2"Y`0`2%0*7#0#)-0"F'!=Y@A.!4VME -M;&5T86Q\"P:,"`%=!P/L`08"!0OL`1HQ[`$&*`!01FQE -M`@$I`1%A(2`!RET":0(`)`%B/'-I9V@^VP`&204!<@(!=!D`]P0&.!P`A0-0 -M,BXQ+CDW"A-TMPD":0`A"@EJ``!L`0\7$``#80`%NP803,0*'!`#*,#!U;&00!!!RY0('H0(Z.PH) -M4P`!F@D2=\9.`,D+`%\#`WL"`NP#`I(!$&Y3,@#,:`!T`P6-#C%T;W7L`@!, -M!0""10-@`14QX1$+_@`'-@DF"4P[%@"!``#L!`*Z(!!N9AT!*B$`"0$`=00` -M!`,`_D]$97)I>&,`!:4'"V,`".4(`,0!`QHC#'8+)S%BZP8**```P@D&50`1 -M7PQ%`]9G"KT,`48=`!$:(6%L4$%E+@H)3F]TM@4!3@8$BP$"B0$`IQ8!-&T* -M<@`)NAP1(LH&``\!47)EP1$&XN2!%N/2T`?AH$4@`%;@$,4@`6-,("`5(`!4L2!/P7(6%NPT4@8FS* -M*0#[(!!AM0D!R@4`U1$`'``!"P<`_PX`;VP!NB\!)@`!#D@!3@D188(3!75$ -M`>T70&]R(&>R4@`_#`!N$"1B96T+``L"`P,>`BXO`#4M`2PQ0&]T:"!:!P*< -M!0'##Q-R0PR4;VQEY!0J(`1%(#0<$1PT@W``%J!`=B -M!@!<`08I```K%`'M`0">`@!X`C%S("BB``!W!0#C`@)3"Q``#U!(`200"O0('_0`( -ME```^A)`:6YG+Z,#`%L-`7H``38*,7!A>-4`!>T#`+T6(G5NI0$@9616)`$V -M`0^Y"@,W,"XR8@<`*0`%*`!`($ET)T0*$71)'#)E8W3&`1!I%@"S<')E='1Y -M(&=O;V3]`0;U"1(R&201;^I#`=<:`+\F(&]F[`L480H``_T& -M``D#`(<.`/T(,$=E;M@``;P#$RAQ+3`A*2!0.P'+'0(6`0!$$0%"``'H'[)I -M0@A -M=""X3X1L8VAM;V0H*6L`!245!Q(#`74!!]83`6L`!2D`$47*,`8(`S-E`2!W:#(!`24` -M`Q$(`4\`(6)Y00`!SAE1('1O;VRM!``W!@+F*`4N``*%!@';'#5M:7HL`08U -M"P=L``$L`0?9!0`L`0,'0@(U`@'0*`%?$0#Z!@'1*`&-!@9$``"<%@/T5P*A -M`"1F($8!05!%4DTW`001`&A/5TY%4BRD9")R96<0`3L`<71O(%-5240S`!!3 -M8`0`LQ@`=A<%F4X.B@H78AP,"B@`$4%F"`"J!05@"P"1!A$B!RX4(KL0$'/: -M!Q%A?P`"&S4&D78`YP,`)48Q("!"0Q\`L`0`APD0:;$$`O4``"U=P'D:"`@8=,5865R+6=R -M8?@T`4X/,&9A8UX"%F&'$``C`03;%0VW'P$:`0`E&@",`@/E%0#R,@&)9P., -M:0%`$`*T%0/&`P"C-`&B&`1G`0%'`"%A"P,-$011 -M`"!D99X)$&*A!0$4-S%Y;W5#``1*&@():!(I5T``FP!A;W9E!Y<#`D<5`7(!`G(` -M46EN=F]LU`$$\P$!S08$!%4!40T`4P8`!@(`7&(1210=$V.*"0&"-!!X80L` -M``(@;V;/$>(@;W9E@J`:L&%2W(`0'8-0)T'@,^%0P2`3_`$`R+C`[Z0("PPD`9Q]!<')O=/P+`+,Y]0-I -M;F0@(VEF9&5F)W,@=6YT:6R@-P'#<0+U%@"S$3-Y=&@T"P%B`P"L`P&L`@)X -M``*['@::``#8"0OK``>7%P#:!0*!`0`;&S!S92@`>5$@5&AE>9<)`$XL`HX. -M`.L"`&8/`4L``#HJ%6;B'PIL`,!R96-U`0"S#"%S90($`BD#`$D($&``"I`2`M<",%"W8+`@5.`;%P!!H`$"W6(E!I9FEC"@QX -M#>5.``AH/`Y@E$3;N"!`@ZVL!?2<0.P8`$6Q-*0#_!2!O;$\0$F@C*`+9 -M``%'"@!?``&(`0#V!Q`GIQ81EQ`:\G4&QE('5P10<`8S0"/``` -M=@@@;V[+*T),1$52=@"B4U5-34%22453"OT0`JT%#V0#`!HQ(0$#(2,0-ED. -M")DE`%87(&YD;P$2=-E#!8@/"98C,B!R96YP`,L``3<-``EE(&]R"!T"*!,` -M3@(%7`8@9&5N$P&,+0">`0.3,1`V9R,`Y)`!L!`5X`!?P!$$FX)C%P;W*M -M!`MF2@"C95!T:6QL+3`'#%\U`&(``.4%#@X!&',C:0'8$WPM;VYL>2XI?`!@ -M4F5O@K,:@!J -M$P&'!`&*&Q)S^!0']@0`ZP4"WPP"B#@#Q84.GL'`5(J`)(A -M`0%1`3\Y!/<&$BR^(`!Y`#=087CZ`0%>'`(6?Q$N_DT"`!L;-=H9`;X!`_8! -M!+41"4=/`#X.!%T9`!\+!E\9`+L%`$83`K8$`A\2`',-!)0$"NE*`F0``N1* -M`*X``#P44&%S($DG'`-`="!Q=;@3`)-&`-A:`:P)`)@"`C8``T&``((!G&AE -M=7)I8@,!0@'`1P)5"X*3V-TZ@(2-5A7-$=.5U,`D#`/87`2L2"\`#`W`#`JT-*C4Z,0(#7P8!544` -M7@,!*0\095X)$7G=$0`]`@3N0S%S("@*"`(K'`(0"@8<``*>&$PQ34(I<0"@ -M36%R8W5S($=E:7T'`%8<`!\'`6<1`.,-`;)Z`[PZ!KD#`'D``SP!\PYX(H``$%\0FMT;W!?>P#J&0`O``;'``&%"0*5``!]``". -M!`+*%0`.``$T```J+P.W"P-1#V(U.B!07`F`Z2UW86QK6``!J!\`E@4"DP("70`#X"L1-6!A`/U#`+@'!%4` -M`3(``2%;$#N$(@"4``0/!0"*#`#2`11YHQ(0--(!(6YY*RH0+7<(`,4](6QE -M+P(!U!$`2#D!5@,!&U(#5@`@86PE#@`=`0'5'P/L%@$`&@4Q.P1S``0&.P2_ -M``!]``.'!Q$TBBL`I2H%FW@#;X3Q!2P@2%`M55@L(%5N:7AW87)E+"!S:2D` -JTRH"+@$`?@$1<#T``I(!`'P$'P`!`/______;U````````````",W%#R -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_compat_lz4_B6.tar.lz4.uu b/thirdparty/libarchive/libarchive/test/test_compat_lz4_B6.tar.lz4.uu deleted file mode 100644 index 97918b91d..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_lz4_B6.tar.lz4.uu +++ /dev/null @@ -1,1197 +0,0 @@ -begin 644 test_compat_lz4_B6.tar.lz4 -M!")-&&1@A;\@``!O>&9I;&4``0!+X3`P,#8T-"``,#`P-S8U"``B,#(0`"(R -M,`$`_P<@,3(S-3,U-3,U,3(@,#$R,#(S`"`PEP!+`@(`KW5S=&%R`#`P8W4' -M`0M2,!46%C="!S8`"A(&1E;6]N4$`(&EN^``(M@)A:6YF;W)M&@00 -M(+@&!+T"\`E.15=3("T@:&EG:&QI9VATP`"-E)ZT``R0$`),``$X`]0$N86TL(&%C;&]C86PN;30L -MX0!`92YA8_\```(`$BU4`"1T;Z@`#*($LBP@;VYL>2!N965D?``Q;6%I]@$C -M97)<`05P`"1I;F0`\@,N:"YI;@H)+2!T96UP;&%T97-G`!%B-`(!9@$39;4` -M<`H*1W5I9&6V`AA$5`8$T@$"=0`!MP&R'!L -M@P(#+P,`0@$"(0`$F@,#,P``B`0/-``+`"(`##4`+V%T-``,*&%T,P`&`0:` -M+C,@9VEV97/?!H!O=F5R=FEE=_,"`*``!+L%$&%Q!3!W:&^1`B,J(-D'A5]R -M96%D+C,L$```T04=91$`45]D:7-K%@`"?@<(/@`#'```F0`0=E\!`K<"865D -M(&-A;(D'$'/4!D%N8V5SK0(`DP``=0``%P(`^00!<0!8($%027.7`'-E;G1R -M>2XS30`"]P,2(FL#!:L``20`4"(@=71II`59(&-L87-$``'O!49N86QSG0!@ -M]!;!I;@IA(&YU;6)E`D09BP``;<&42H@1TY5 -M=0$"N@$F("@$"P`:`$%L;VYG4`9B;F%M97,L$```!0L3(!$``&,`4G-P87)S -M?`(AB,``!DT%``)"`$```I58W)E -M873/``%U!`\&`0("J@,#OP,"O`(/'P,8,")R9:`-46-T960B1P,"3P#$+"!W -M:&EC:"!W:6QLB@`!5@`%R@%A(&5X8V5P0`40"EL)`VD"42!T:&%T0PXQ:7)E -M40`!\P,!R@(@("A3"@$T!`"$`0,S!`#T`V`L(&5T8RGO"P+Z`P"I`@8B!`&& -M`0+:``_(`PIA(FYE=V,BFP,!,P`G0<280D!`BL`(2!B-PEQF4@'!L -M:6-I=&S9"4!V;VMEO!(!ZP`!?PH#SA$@("C2$"4@8?L*`*D`("!AZ0`!)Q`" -M+0`(S0`4;Y4(<"DL(&ET('=P`$$@9V5T&1,!70H`I`0W($EN;@`W+"!IG@`! -M40$#FP`B96[)`0P,1<#4`T6%T979E`!,@%1``:A`` -M"@$`/06#;B!I=',@(D#E`!(BO0012!F4X.``P1$2(A`0!:""`L -M(E`(H"P@8V%P86)I;&D2%`8#`07Q``+S#P&W!`CV!0&7`8`@:6YD:79I9&P. -M`&@%(6EEA`$`.A("0@`$K`4`-@$A=&^L#3!D8737```%#A8Z+@$"R`D`P@`2 -M8>P"`,D*`2L`,VEN("2!T:&ER9"!P87)T:65S.X,``P(`87!L -M96%S948``'L`\BET:&4@875T:&]R2!Q=65S=&EO;G,N"@I4 -M:&4@=&]P+6QE=F5L(&1I4$`(&EN^`"`92!F;VQL;W>V`'!I;F9O -M%#36%K94QIM`!(ZU``` -MDP``3@#U`2YA;2P@86-L;V-A;"YM-"SA`$!E+F%C*P```@`2+50`)'1OJ``` -M(`&`9&ES=')I8G5!`;(L(&]N;'D@;F5E9'P`,6UA:?8!(V5R7`$%<``D:6YD -M`/(#+F@N:6X*"2T@=&5M<&QA=&5S9P`18C0"`68!$V6U`'`*"D=U:61EM@*" -M1&]C=6UE;G2!`0#%`3)A;&QU``#S`?4*('-YM`_`$,R!G:79E2XS!`,!JP(2(FL#!:L``20`Z2(@=71I;&ET -M>2!C;&%S1`"6:6YT97)N86QSG0!@P$2+8($4W,N-2!D5@(#I@0@ -M:6QV`]1R;6%T-50!"/$$4&%B;W5T&@$@P"`+"!I;F-L -M=62*`8%H87)D+71O+3`&`J@!$G-'``!!`&%M;V1E$D#(F5R60<#>`('(0"P;V-T970M -M;W)I96X!`P!@`@$>`*%35E(T($%30TE)=`(!%``"4P`/,@`%,$)I;LH$`$(` -MH"`H8FEG+65N9&GS!(-R(&QI='1L91$``OH`\0))4T\Y-C8P($-$+5)/32!I -M;;<"@"AW:71H(&]PRP/`86P@4F]C:W)I9&=E10!B2F]L:65T*0$![P$"20`U -M6DE0"0$#0``@=6Y."3!R97,G!W!OB,``!DT%``)"`$```I58W)E873/ -M``%U!`\&`0("J@,#OP,"O`(/'P,8,")R9?X(46-T960B1P,"3P#$+"!W:&EC -M:"!W:6QLB@`!5@`%R@%A(&5X8V5P0`40"EL)`VD"`A4,<7)E<75IP`#GP$`>P`!APD!HP`"2@P#"@,0 -M;6L($&EY!Q%A+PD#*P`A(&(W"7%R96%D86)L``8`C`H!#``!+`L"!`$`:``" -M.P!"96%C:#T!(79E4,`4&EN9&5PJ@`E;G0B`0`8"0`/#Q!C0@42;VP- -M!C4*5"!7:6MI4@PP:6YGR0`P:&]WFPP!LP,79)8*`BH!(4]N/P@`]PP">`8# -M`P$$S0`!<`!`;'=A>48!`-T!*F5DB@@"1P!P22=V92!A="T-`(P'`,$/D&EN -M:6UI>F4@2UV```S#`#W"!%IAP8`A`!P96YV:7)O;M<" -M,7,@=Y`#`:`"$&W8`1-R6@,%,`(`6P`"?P`1>7L#$7`U`-%A=&5V97(@8FQO -M8VMS\```[@2X'<70@82!T:6U7`W%O8!(71O(@`%2@!2="!O;F-\$B)/;AP."\,``N0",G!R;SH!`84!46-T;'DM -MS`"2960@;W5T<'5T[P(`8`3Q`V]B:F5C="US='EL92!A<'!R;\@#`$,2`OH` -MX'1O(&AA=F4@;75L=&EP)0``(040=A(#0')E86W\"E4@;W!E;IX`$R`5$`!J -M$``*`0`]!8-N(&ET2!B=6@-$B`D"`!E``!Z``#-`H5A('-O8VME=#X# -M27=IP`28D(`!*P%`#8!(71OK`TP9&%TUP``!0X1.L$"`2X! -M`L@)`,(`$F'L`@!A`P$K`#-I;B`G`0"/`C-A9&2.`AAA]PP!UP<#'@]19FER -M>D``,P``*,!!H`%,7=A;G\%$G0=#P-%`0!@```:!!!T -MC@A<"+``` -M.P``!`,`2P+%1`G -M-Q,`)AD`%@)S82!F=6QL+98(F-%#A)B!P`2>`<``'`$`)()`"<`%"I/&@]D&O______________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M________________________________95`@:6YS:6(@``#P"6=H="!I;G1O -M(&QI8F%R8VAI=F4G1X`<&QI8G)AP#S"2P@:6YC;'5D:6YG(&AA``"/`/0:("=D;V,G(&1I2!I;@IA(&YU -M;6)E6]U(#\!8"X*"D-U -MFEP,A8`!'P! -M32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9-!0`"0@!E6-A;B!C?P(-F5A;;4%X'-YU`P#P!`![``-S -M!`![``&'"0&C`%0@;VYL>0H#$&UK"!!I>0<182\)`RL`(2!B-PEQ4,`4&EN9&5P -MJ@`E;G0B`0`8"5!A7L#$7`U`-%A=&5V97(@8FQO8VMS\```[@2X'<70@82!T:6U7`P!K -M"S%M87#X`C!E;G21!@/0`@%1`T!G:79EY@$A=&\B``6A`&%T(&]N8V6%`"%/ -M;I`#&V7#``+D`C)P`%`@(&)S9",'(75SO`$`/06#;B!I=',@(D#E`!(BO001 -M2!F@``P0&%82!S;V-K970^`TEW:7-HN@3`4X.475S92`B(0$`6@@@+")0"'`L(&-A<&%B00`!]@($ -M`P$%\0!A92!!4$ES/PX(]@4!EP&`(&EN9&EV:61L#@/;"`"%``(5!@!"``2L -M!0`V`2%T;ZP-,&1A=-<```4.%CHN`0+("0`]`!)A[`(`R0H!*P`S:6X@)P$` -ME0LS861DC@(88?<,`=<'`QX/469I1$@#R$0`6`G-A(&9U;&PME@AR9"`G=&%R)P\!`0(`(7)EK0H!0@%` -M8G5I;($&`(H``V,``"H``J(3!F,`2V-P:6]D``;3$@$P`S!F86,J!P`]``," -M```I$")N=&@#`!$"-G-A;98#%&%G!5F-%#A)B!P`2>`<``$D!`)()`"<`02H@97@;$T!S.B!3,@-4 -M,!-&%C='L3<&1E;6]NP`` -M7P%C875T:&]R:1``EPT!\@(`P1,2+NT/4'1O<"UL#`0#Q0P`,`0& -M";8""',5`.L%`>X/\`4@*B!.15=3("T@:&EG:&QI9VAT<]P`,')E8VX,`C$% -M`Z`"DD-/4%E)3D<@+0P%`$(4`,H'(61O7P8!AP4`S@#`*B!)3E-404Q,("T@ -M9`HQ86QLCP0!#0``BA8`OP`"*0`#0`41+3P``5X1`A@`8&-O;F9I9[(6$"W_ -M!0$,``)$`+5S8W)I<'0L('-E96<``"@%`ED6`F,(@2H@0TUA:V5,U`0Q='AT -MB``A<'5G$#`@(F,T!A$B)`,`.`PI;VQ-`"`*"N$(!NL#`2D!`!8)`(X!#VT! -M`0"P#!!U/1,"$!\`!,GK0`#)`0`DP``3@#P`"YA;2P@86-L;V-A;"YM -M-`D-`^T`,"YA8_\```(`$"UD`@"?``2H``#9#@BB!!(L&@X`UPL`60M1>2!M -M86GV`2-E!,"(0`$F@,#,P``B`0/-``+`"(`##4`+V%T-``,*&%T,P`'K0,1,[8+ -M`!`4D"!O=F5R=FEE=_,"`*L`!<`+`'$%,'=H;Y$"%"JD"H5?\%1FYA;'.=`!)S/@M/:6YS -M:60:________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M__________________________________________________]Y4&5S"B`@ -M62```/$>*B!F:6QEFEP(&-O;7!R -M97-S:6]N%0!=8GII<#(6``0F`$TO3%I7'0#_`VQZ;6$L(&QZ:7`L(&%N9"!X -M>B,``!DT%`#Q,@I4:&4@;&EB2!C86X@8W)E871E(&%R8VAI=F5S(&EN -M(&%N>2!O9B!T:&4@9F]L;&]W:6YG(&9O"!I;G1E'1E;DT!L7,@*&9O$E33SDV-C`3`%HW+5II<#D`-EA!4A$`0PI7:&4# -M`@#D`00%`A$L_`%AT!X'-Y -M`>-R86YD;VT@86-C97-S+GD`!I<`\@)I -M`35N97<7`@!2`#!A;F1[``'.`!1V6`,24,`4&EN9&5PJ@`B;G1_`!!R.P0`!``P=&EC\`0D;VZ!`02N -M`/``5VEK:2!E>'!L86EN:6YGR0`P:&]W^``"]0``C@0#+``"*@$A3VZJ`!PL -M`P$#V0("<`!`;'=A>48!`-T!\@%E9"!A=71O;6%T:6-A;&QY1P"P22=V92!A -M='1E;7#$`^!T;R!M:6YI;6EZ92!S="L`L"!L:6YK('!O;&QUN`'A+B`@268@ -M>6]U(&1O;B?L`0"V`/$":6-I=&QY(&EN=F]K92!A('#K`"!U;#<$(&5A60)` -M("AS=2\!&7,<`A!AZ0`'+0`'[P4`@`$"F0%P*2P@:70@=W``X"!G970@<'5L -M;&5D(&ENI`0W($EN;@`W+"!IG@`!40$#FP`B96[)`07L#$7`U`-%A=&5V97(@8FQO8VMS\``0:%<%(6ETH0!!66]U -M2X'<70@82!T:6U7 -M`W%O8!(71O(@`%H0!A="!O;F-E -MA0`A3VZ0`QMEPP`"Y`(R<')O.@$!A0%18W1L>2W,``!(!E)U='!U=.\"`&`$ -M\0-O8FIE8W0M2!F)M96UO -M?\`!8P``0`"\05R;W9I9&4@96%S>2UT;RUU8<``J,!!H`%,7=A;H@`$'0V!`5%`0!@ -M``'Z"0".!S!S:RQ.`P-^!KEC;VYV96YI96YC9<`!`(D`,&UA:WD`D&ES(&5S -M<&5C:6X$`=`!`JH!`#H(,#H@(I,*#KL*$R*Y`B!L;#P!`N@"`*4'`!$#`L$% -M0"P*("#,!Q!PWP``;`0`E@`0(',*T"!S87ES+@I214%$346[!@?H!N$@8G5N -M9&QE+@H*475E<_H"H#\@($ES7!1`GH@1` -M9W)A;18"M``-G`0"3``!.`/`` -M+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C%P$``@`0+:("`)\`!*@``-D."*($ -M$BP:#@#7"P)\`#%M86GV`2-EPH"MP(` -MA1(A86R)!V!S97%U96Y+#0#6`@"3``!U```7`@#Y!`%Q``%Q"@B7`'-E;G1R -M>2XS30``[P0R92`B:P,%JP`!)``4(@L+62!C;&%S1``!'PE&;F%L]!9!I;@IA(&YU -M;6+R#!=FD0<#'@'7+@H*66]U('-H;W5L9*0+`"@!,6-O<'8&0&-O;6V>"`"X -M!!,B!0XR+F@BJ0`R:&4*7PQ!(&-O9'4!`!0`!.D&`W((`G\"-&UO5$P"9!G!E2X`L2`H8FEG+65N9&EA -MU!%C;&ET=&QE$0`"^@`$7Q:10T0M4D]-(&EMMP*`*'=I=&@@;W#+`\!A;"!2 -M;V-K%V,/"Q<`TTUI8W)O2X*"B`J($DG=F4@871T96UP=&5D('1O(&UI -M;FEM:7IE('-T*P#X4R!L:6YK('!O;&QU=&EO;BX@($EF('EO=2!D;VXG=`H@ -M("!E>'!L:6-I=&QY(&EN=F]K92!A('!A``B;`%IE -M;F%B;)L``#X`"W$`*&1E$0`#J@`1+/```H``(FYE)@$`%@$`0`#X"V%G86EN -M<`!`"@$`#,`@&%N9"!W&%)`$!S.B!3 -M,@-42!F:6YDT`(Q9G5L+P(&10`0+Z\' -M`84!$6%R!E%A8W0@P``"@+Q`F%U=&AO@`K!#3U!9 -M24Y'("T@=Q,'`+D(8F-A;B!D;Y\`,W1H:2D`H$E.4U1!3$P@+2#0!S)A;&QU -M```-`"%R=2H"`RD``T`%$"T4`1%SE0`"DP"P8V]N9FEG=7)E("W.``$,``)$ -M`+5S8W)I<'0L('-E96<``/T(9&1E=&%I;,,$84--86ME3-0$,71X=(@`(G!U -M)@EQ(F-M86ME(B0#`*0)*6]L30`"5@$&ZP,`E`!!2!N965DQ0@0>5L+4&$@=VAOD0(C*B#9 -M!X5?] -M!;!I;@IA(&YU;6)E<$",&5C=)D#$61A#0,<`@5X"1!F+``!MP91*B!'3E5U`0(U`B8@*`0+`!H` -M06QO;F=0!F)N86UE+``-J`0`9`X$J(%!/ -M4TE8("`-`5L``A``,G!A>%H)`ED'`W@"!R$`L&]C=&5T+6]R:65N1!``8`(! -M'@"A4U92-"!!4T-)270"`10``E,`#S(`!1!"V0X1>2X`H"`H8FEG+65N9&GS -M!(-R(&QI='1L91$``OH`\0))4T\Y-C8P($-$+5)/32!I;;<"$2AX""!O<,L# -MP&%L(%)O8VMR:61G944`8DIO;&EE="D!`>\!`DD`-%I)4'4$!$``('5N,0L` -MBQ`@960Z`$`B9&5F?@81(F8)`Q@``*$$(VEE50$`PP$`H@&%0E-$("=AFEP/@$@:6^[$'TJ(&)Z:7`R%@`$?`%-+TQ:5QT`HFQZ -M;6$L(&QZ:7`3`R]X>B,``!DT%``)"`$```I58W)E873/``$M"0\&`0("J@,# -MOP,"O`(/'P,8,")R9:`-46-T960B1P,"3P#$+"!W:&EC:"!W:6QLB@`!5@`% -MR@%A(&5X8V5P0`4`N04$:0("UQ$`0PX0:98%)V%XR@(@("@6!0$T!`"$`0,S -M!`#T`V`L(&5T8RGO"P+Z`P"I`@8B!`&;`0+:``^6`P4!R`-A(FYE=V,BFP,! -M,P`GD#`#X'(71EVP@1.N85`2T0$&D@"G!H96%V:6QY_`@V96%MM04"$0M! -M+B`@5$`44VES(&YOX@<`@@(#"A4`DP1!(&EN+;P`#GP$`>P`!APD!HP`"2@P#"@,`.`@`;Q`R=&AA"0$"#`(A -M(&(W"0!J"`'[%2%O$P$/`P),%@"V`A!G5180:2(3`2(`!9L$`.,3(6-E -MA0`A3VZ0`QMEPP`"Y`(R<')O"AFA8V]R>`907!P4X.``P1$2(A`0!:""`L(E`(H"P@8V%P86)I;&D2%`:-`07Q``+S#P$_#@CV -M!0&7`8`@:6YD:79I9&P.`]L(`(4``#H2`D(``'(+`-$``#8!(71OK`TP9&%T -MUP``!0X6.BX!`L@)`#T`$F'L`@&`#@`K`#-I;B`G`0"/`C-A9&2.`AAA]PP! -MJ0H#'@]19FER"U$W,3$W-0`> -M83$U,34U,@`>+S4Q`![_5==&96(@,#DL(#(P,3,ZAPJ1(#,N,2XR(')E,A.> -M9`H*2F%N(#(X*0`A)W.K"T!W96)S``0R;6]VT0L/(1X&$BY,`"XQ,TP``74` -M&S%U``\I``87,"D`841E8R`P-U(`0#(Z($E2&P$(#`@*!0/0%`#O#!EE&@P` -MG04"VPT"3A@!D`B$(`I.;W8@,3%4`"!!9+8;!JPB@U]?34%#3U-8%PT`@@0$$]@\$90`` -MP@$@(&Q<`6``'E("`@ -M0_$@`9D"`V,``%(7#P(A$@]U``@)DR$#=0``3@L#=`!01W)O=7`2$`"U`R$R -M-!4!&3$5`0`^`0=\!`$H``(O!"4Q.ID>H&9I>&5S(&UE`RDQ.D4`"AH`$5/\'P+8`&%T -M;R!)4T^?``!U`%!T;R!I;8H+-F4@2-RQH`+PU18V]L;&6((0#C#0!*#S!L92VK(@#``)F]NS0,!W`<&?`$11O0&`"H#,FP@,#4"(3`Z_"T`&QH#HR8'0R80968$`=\3`I4$`2X#`M$0``D+ -M,'1R884%(6%L.P0A,CD[!$`P.B!-<`(#R`8%$`,`%04"G``!\!3P``H4!$C"%`4!L87)GQQ0!ZA(`V!1B96X@8V]PE!$`#@,!'A($R`D!00`# -MB040,`@"`;(G`'@`=B!-86,@3U.I`@`\``>N!`$Z``-"`B0P.E``!^L``*H) -M`_T"$'->"0+N`%1S"DUA>24-8S`Z(%A!4D,$`1D``T,%$3#'`34@7E0-!1([ -M/B]`(&5X:1$5`J<$`]0'`!H!`)0=`XT*`F,`!IL``UT$`=\A!A`%!`<"!!L# -M8&,@8W)Y<,4$`L$,`8\``_L&(3`Z/1T!`@(`+`8"$`0`)@,`1P4"*@`"!0T2 -M,``(`]0#$CHN!T`M9VED!@``*@1!("TM=0X`$'4.``$'!0,R#@/``6!2960M -M8FQ@%@#\(@&4!P;^`0$9%2!E"!L96=A8WFU!S%M870,!`/!4`Q`,`,AT"D`4#=@@#O@$`OP<29"L``)$@.6QD -M95\(`%T;$&R[`0`5#@%`*"%E9,L#!A`!55)E;&%X`P(`P@4@2!!4D-(259%7T9!5$%,(')A'`0@=&@;`T,@=FES^Q0#*08`R0L# -M=0`T7`8P`!H4#$%+(!T5A9FEO#@D! -M50`%PP400<<=`%8`!_,C!3$%(6QY+`\$_0("6P`%NP%@26YT96=R70(@07#Q -M&`?W!`!+!@@-!0!_'2!A=`,L$'5.'@'@`0+^&`$!$A4S5``$$0$`WR,S("U6 -MX@X&4P0&:PLX,BXXJQ$W2F%NR`,`=@L!S`@&"@,`DP#@)V5C:&\@;F]N97AI -M0(O,#G?```?,=\`#P&O -M#`*'`@]#```6,7P-,TIU;#L#`"@````"`/@DL2!B;V=U'HP``)!`P0P``"1,0*8`4$@,2XW90<1,?4`""$`<&QZ;6$O>'I;`P/A -M`@!G``06(`D""`)`!`"?!1-Y\@X`20`12,@D("!G_A("10``V`D$00!`3W!E -M;I0E<")G>G-I9R+-*`"@,`)%``+#`P!%`)!!=F]I9"!F86P*`@.2!0*(`02I -M!`&@!#!P:7`F,P!1$@+>!P`\``ME`@?\`@+%!@%_!`TI`$<0"%W()`RM! -M9#L04FYE>'1?;`\T,B@IGQ9!:7,@=6$243(U)0H),2M0969F:6-S"`%E``$> -M'@.#"!([:A/30G)I86X@2&%R2!-:6-H:6AI'@#'!T%T86UPE@LP5')UY0X!\0X`I@0`L2A02'5R9"R&`,%":L.V -MF5D!0\2)P/``S!C;W)D`D%!;'-O)R0+L0`Q8FED`(5<]<.(`H)E`8A -M97/-`S!S=&$N*`"(``,.!"%S+NH=`XD&)#@ZS@D"&P4)D`D!I@X28)`"P3=@ED;V5S -M;B?G!PLR`&)W96QL*2RS!B)I65T"@E00T%D('5NH@`"K!`")0<# -MWP`)L1J086QL*"DN("!&F`M!;F]W+)0J,&UU2!E;F]U9V@@00=!+"!W9<:\!"W@!%S1/`0$I``4E`P_8 -M`0$P9FEXZP4`;`($_!X*L!,`#C0`S0``1@0!,Q@&(P8!OAP!9A$`2R$&]A\" -M:0,`/PX`"0D38=U#3H@"?$E$W`=`-`N9G)E96)S9"YO0"@D@(&UE87-U>P,!4P8".0``30(`N@L1:1Q) -M`5TO0'!A=&@=`&$@9FEE;&31`#!U*P%'(F!M;6%R:7HZ"1!P[#L`W!<" -MMP0`N@!`+6YO+;H*(V9ICC@T;&EBS4<#;Q0`)P`+J`!B.B!3:VEPDQ@!LP$! -M8P4!2@4#_P0",0A0,S(M8FD6!3!F7W1'`#!I(P'&`2`M!@"AP$`V#0%%",!5P8754-!"8G`(H!$&:;!B5L>?,$(`H))0]5:VYO=V[(``"O)4!A -M=&5G(QD+.0$"7!8`"00"+`4"EP(.3P<,G@`!F`<`U1,#Z@@!?`D""00&/0L` -MX@(/2P`/`"8!`*L``/@(&&5;`@-:%3`@=74;$3!D93L,`1%YD`X"N`T!U`\0 -M+8$N,65C;X$%4FQO9VECL14"-``0 -M!Q(NR!\&Y@X,I@`5,Z8``I,8!?D"`W8=`)T&$2Q,`@"3`!(LF@`0+"P$`IX` -M`3L!(&-A91`18I@+,79E`A8R7@(**0``J`$@8F%S3A%DB`,!%PD# -M%0$&PR4#3`4"*B(&=0`*2P!D5F5R:69Y300!5@@`21HQ9V5TF@T"I3P!8@L$ -MS54`<1H!C@5%,BXY+H(!`CH``$@!$FQ4,1!B$QD!VPL'X0\B*"VE#T`M>BDL -MJP,`(0\Q"6]FJ@TP'0`F+P%6 -M"0#'``*Y`%!U;F-O=LQ")0H))"``S`%P8V]S;65T:5\<`.Y3`$D$`U<&("P@ -M^@4`V08`*P0<9%@!H$5X<&5R:6UE;G1,2P,O)0#;#0#]/!0M(`T#@#`/G0$% -M`K,;!O@"`^@2!&$&$'G;`@&<`0=3!U1I=&@*"8,"%'-/$P04,@%(`P#W``&B -M"6%S+B`@*%>A$P%!$P&^!0!G"2$*"8U.`=P(`!0%8&QA*9!`;4E`.@3`O@D!F$!`*<$ -M`;$)!3T/`6H``C\K#VH``0S,&0)A!!8WA@A0,"XY+C#&!P"!!P+.4R!W::$5 -M,W5S92<;!30`($-OCQL`&@M0:6YI=&E\!@`/)00Q$`#*`0,)`@28``+'`PZ8 -M`!4YR@8"P``%*``&U`4`8P$"C30`>@4"B1<)9`#P`SH@("UA+"`M<2P@+4PL -M("UF+)L8$'0^�@00!G"0#C$`0+)H*!(T2H41A;6EE -M;B!';VRJ!`"C`!!B>@T`Z0`!CP,`B3@0>H*Q`O!0D!!0`07[@4("YCH2$`@@LP -M--*)7!Y^!T!=``#$!L2-XD%4&$@8V]UE!PC;V:6 -M!`>M)@#E!0%_``*I#PZG``?R%0HH``!;``"I`P&G``$%`!%?:0$07]\$(6)Y -MV3$"10%R92!U;6%S:Z0_`T`!`_H>#G``!E@)`LL`!1X"`(8'!C12!(0"4"TM -M9&ESIQ!2+7AA='1Y"@84`'5A8VPL"@ET[0'_`%-A;75L:2!3=6]M:6YE;HP` -M#0<^"0'\``6,``8_`L!,87!O($QU8VAI;FG5!0!Z50%)`@!.'`%520`%#@'2 -M"0&:)`-*!0"3`2!L9%<)`54N`/H;!&\$,&)U9\8%`1@``$`!L&]F"@DB;&5N -M9W1HGA2096YD(B!F;&%G'@H%80`2@$@"@D4``&Z)`,Z.P_T!08'B04**``">```)0@` -M\04`,A0&/`(#N@Q08VAI;&P'%PL[`!!/D`8`V1``\`("]PT+0$D@<'7P -M+PF-`@`A$`,D`048+P!,`0#!5`&$``4L!Q-)U`@!V0L`V`<097\G``$#4&XM -M;6%T;P4`%5T`U#XA;W)!#(([($D*"6AO<$@-D2!E=F5N='5A;#PE`?%,`!\! -M`#`+,F1E("<*`$,H`LX)`,Y5`Q4_`FL.#)<&&#.7!@"J`!4P+@$@0V\C&A!U -MD``$K0`$=@4`7`(!F"H29=\`!C4`$$XM30%85@#E0`"T!!,L]PL!<`@P(DAI -M[PH@>2*U`0-.`"`N,3@)`<\,`*\`%#$Y``/D(09<``"8!Q5Z-#P`EP*1:6UM -M961I871E#0$!D#@P14]&T2H`C!\P=')YSP\!_A4%PQ0`$0XP)(5`EH/!,L+`)T#(6]FA``#H0(`90@`OCL/ -MD04$&#-I!P`H``/0$!`WT",!50$334<<("YA)!4!3@<`$@02(,<@$R\#"`1J -M$D,*"6%C_`$A9&\H`%%R:6=H=$$3,6=S+KDA!F,``,0($"VT"`!2"@$-``&$ -M#`2[``?<%`%A!``C`1!I]0``B@,,)P$-70`!D`4/E`L``.4+(&ENO2(@8V6] -M(``7$`'0#0`T`@#K.@$`*@1](`!&%0",)S!N:6/2`2)H868&4')A9W1A!P,( -M7#L`00`#M%P1<_L(%'3#!R1H88@!!F@#";H'&#.Z!P&(`0\H``40,5(:)&ME -M6@`@8F5K'`!Z`P5&2P,,"@#'!4`H*0H)2PPY!("UP -M+#X'`6,Z(0H)Q24""1$5;Z,0$"QB$0'Z#00X"U!S96=F8><%`CX"!H$``F@) -M`U8#`44B`NH2`S\""0A```001('X88`H):6YS=(0&$',C!!!TF08)&&$#IP`%I@0(7"X`T`=T -M>5]L:6YK7\P2%"S0!0,=`#!S=')O6@(N`@/T,0R6`1@RH0T`E@$&P@P&B`$4 -M,@`&`-\"0'-T("A<(S!Y972<$!(INP`"ZST"?A(`&SP##`(#/#`.=@`'80U2 -M075G(#,O)!(WXS(`LS(`F0,$O`8"*QX`@PLC"`M -M+7-))P22!Q(N-P`%.`P34K,:8'-U:60O0@(6A``X````0\`C`,`92@`]AP& -MGR80+`T<`0$,)`H)AA4"21,$43DE('06%@*7!"`N:"P>(V%DQ0EC;&5A;G5P -M?BL*8@$2+!T5``P'$7,B"@`S$A$O+Q(#W`4P;@H)!`E386YO;6$("@',6@`G -M&@5D#`$%&A=YT@$+"P$6,CH3"B@```L!#MT%$""1`P),(@`$#`*7`U!Y(&-L -M;Q`.`)4I071R>2#2*P`>!R)T;X`<`P,T("!SS`@`8V(`P!@!DB(!EQ91(&ES -M"@FF!`D.`G(@9FEN:7-H.@$!`@T`Y@P$E0``E`$37^45`*`'L'=O0:70@:&5L9"!OPT,`J`4"F@``81L!J@``O34`A2H"%R(`^1T@ -M=6U!,`!\%0)<#@3^!@&<0P#Q$&`@8G)E86M**@#K#@#Z+`$8'@#Z,`'X`@2? -M``%@`!!?&0$69?DT`)8.`*@``NXL$&AR#`$N'8!S;VYA8FQY(+D!`!(5`I<- -M`,DU`*8<%WF"$X%3:V5L971A;'P+!HP(`5T'`^P!!@(%"^P!&C'L`08H`%!& -M;&5S:,D7`'(6$&];,!%R:Q,`?0("?@$@+F.\`1%AP`008[T,`>TC`.,-`!0E -M(6-H&P`C:&5_&B`@;MX"`2D!$6$A(`'*70)I`@`D`6(\A`CH["@E3``&:"1)WQDX`R0L`7P,#>P("[`,"D@$0;E,R`,QH -M`'0#!8T.,71O=>P"`$P%`()%`V`!%3'A$0O^``R``N`4`GQ`$`2(*^0H!$`0!)`T)-3(!W0@$64<` -M0`4,XP`'"`0**0``M`8![!$0;BY($6X]+0!^&@12``5N`0Q2`!8TP@(!4@`% -M2Q($_!]``!_+P%\+0`9`@"8'@$0-`1<*`)I``#D``(_`@#$50*+ -M)P4H`0'J`P0`%P#8!0DZ"2)T;P@]!(@!!3<`#(@!![D%"H@!$4@-!P1'#2!S -M.Y`-$&70!&!N=7@O9G-M#0*X"0+B``&Y"`BK&0`-.#%E65T>5,#5S0! -MI@$C=&\R%@"A"@#-%@""$A`B^0%R(&-H96-K(H4&!%PD`T<)"Y@!!V$!`",% -M`E$7%W/$24%)3$5$H@H!=``!M64`X0(`+04"+TH!'0%`82!W89$T$&&8+0"/ -M/2-F9A@"$FG%A4''@!#5T%2 -M3A@"!@H@![<``6H$!V(&`%P!!BD``"L4`>T!`)X"`'@",7,@**(``'<%`.," -M`E,+%RU790'I``#^!@/[%P`F```^``G\&3)O=RG'`09K``+I,@0-#`2$&`"# -M/S`@;V:*;E)S:R!G;[0P`&8!`*(.(69FT0\#Q!`P.R!R5FP!`A$0:4@E$"AX -M``/4$@!)!`*]`@?]``B4``#Z$D!I;F@`!-@HQ<&%XU0`%[0,` -MO18B=6ZE`2!E9%8D`38!#[D*`S3#`!@*`:)'0%R!P"O`31'240G!0(,`Q)S``4#10,B8GD6 -M`#%I;F<8`2%W:'0N`;<.`TX;`=U1`>8\4'1O;R!F3$(`PP<`SA:A;GD@<')I -M=FEL9;`:`9DI#V`2!#@?LFES(&QO;F``^'"@$!G@`'Q08!G@`%3P,10@E`5`@9&]W -M;A,.!UX!('=H,@$!)0`#$0@!3P`A8GE!``'.&5$@=&]O;*T$`#<&`N8H!2X` -M`H4&`=L<-6UI>BP!!C4+!VP``2P!!]D%`"P!`P="`C4"`=`H`5\1`/H&`=$H -M`8T&!D0``)P6`_17`J$`)&8@1@%!4$52331H("!ATQ5A97(M9W)A^#0!3@\P9F%C7@(688<0`",!!-L5#;`U$&`0@=`'Q#$&_=/@"$`@`M -M!0(R+@$D50:+=P)J"0$K6@/0!A!3(C509F5A='7?"`+V%Q!N>P$%RCL`J08! -MPQX'EP,"1Q4!<@$"<@!1:6YV;VS4`03S`0'-!@0$50%1#0!3!@`&`@!<8A%) -M%!T38XH)`8(T$'AA"P```B!O9L\1XB!O=F5R:&%U;"!W:6QLPB8!N"\#,38" -MI`L!?@`"BBX&1P$'?'@"V1``SP("[AL*W0X(U``"S0`"1R8!G#L#=P<`'"40 -M*/8X!+]*`+$$`8,!`'T"(V]F#"<09CT3"XD``,L?$',F!`,D``%&"`!#"`,V -M)`,!>05$#@,T!`&*``()`(P? -M!2<`0$)U;7`%*!!SFPL0=&PV$3/C``"+)2!)+SQ6``@S(G)S,2`",1(2-M83 -M`\P;`$$!049)3$4A)`/B$`\V``0&1P8"[P$$^2(#-A4`I`,`?%85>19/,6%L -M._L``?\*,6QO8[`1$6$]"C!M:6X:/A)UZ"H!JP85+<@!`=@U`G0>`SX5#!(! -M-S(N-3X)`'4>!BD`LT]U=&QI;F4@04))SD81!IH``-@)"^L`!Y<7`-H%`H$!`!L;,'-E*`!Y -M42!4:&5YEPD`3BP"C@X`ZP(`9@\!2P``.BH59N(?"FP`P')E8W5RG%A%R50\P:V5EZ7$!KR=0 -M;&4@=7!%!P!C-`(\``!V""!O;LLK0DQ$15)V`*)354U-05))15,*_1`"K04/ -M9`,`&C$A`0,A(Q`V60X(F24`5A<@;F1O`1)TV4,%B`\)EB,R(')E;G``RP`! -M-PT`"64@;W(('0(H$P!.`@5@\`V`)0=V]R=&AT`!1S$S@!Q081!D;5L"30$`VP50<&%C:V&72P<">`#8 -M`1!EN`I`+F=Z"LQJ`&H3`8<$`8H;$G/X%`?V!`#K!0+?#`*(.`-S,P#/`02. -M!0)[%A0Z>P/H!`5X<`A9_$2[^ -M30(`&QLUVAD!O@$#]@$$M1$)1T\`/@X$71D`'PL&7QD`NP4`1A,"M@0"'Q(` -M`P$I#Q!E7@D1>=T1`#T"!.Y#,7,@*`H(`BL<`A`* -M!AP``IX83#%-0BEQ`*!-87)C=7,@1V5I?0<`5AP`'P0`#/`'S#GAS;FEL+F%N=&)E87(N;W)G+S(P,#4O,#(O,#4O@@%`+6UI -M='YI!`\``%H:@')B96ET96XO2P`"RA<`9@<$[8H`!Q`"M0`-OA/$%+"!(4"U56"P@ -M56YI>'=A&9I;&4``0!+X3`P,#8T-"``,#`P-S8U"``B,#(0`"(R -M,`$`_P<@,3(S-3,U-3,U,3(@,#$R,#(S`"`PEP!+`@(`KW5S=&%R`#`P8W4' -M`0M2,!46%C="!S8`"A(&1E;6]N4$`(&EN^``(M@)A:6YF;W)M&@00 -M(+@&!+T"\`E.15=3("T@:&EG:&QI9VATP`"-E)ZT``R0$`),``$X`]0$N86TL(&%C;&]C86PN;30L -MX0!`92YA8_\```(`$BU4`"1T;Z@`#*($LBP@;VYL>2!N965D?``Q;6%I]@$C -M97)<`05P`"1I;F0`\@,N:"YI;@H)+2!T96UP;&%T97-G`!%B-`(!9@$39;4` -M<`H*1W5I9&6V`AA$5`8$T@$"=0`!MP&R'!L -M@P(#+P,`0@$"(0`$F@,#,P``B`0/-``+`"(`##4`+V%T-``,*&%T,P`&`0:` -M+C,@9VEV97/?!H!O=F5R=FEE=_,"`*``!+L%$&%Q!3!W:&^1`B,J(-D'A5]R -M96%D+C,L$```T04=91$`45]D:7-K%@`"?@<(/@`#'```F0`0=E\!`K<"865D -M(&-A;(D'$'/4!D%N8V5SK0(`DP``=0``%P(`^00!<0!8($%027.7`'-E;G1R -M>2XS30`"]P,2(FL#!:L``20`4"(@=71II`59(&-L87-$``'O!49N86QSG0!@ -M]!;!I;@IA(&YU;6)E`D09BP``;<&42H@1TY5 -M=0$"N@$F("@$"P`:`$%L;VYG4`9B;F%M97,L$```!0L3(!$``&,`4G-P87)S -M?`(AB,``!DT%``)"`$```I58W)E -M873/``%U!`\&`0("J@,#OP,"O`(/'P,8,")R9:`-46-T960B1P,"3P#$+"!W -M:&EC:"!W:6QLB@`!5@`%R@%A(&5X8V5P0`40"EL)`VD"42!T:&%T0PXQ:7)E -M40`!\P,!R@(@("A3"@$T!`"$`0,S!`#T`V`L(&5T8RGO"P+Z`P"I`@8B!`&& -M`0+:``_(`PIA(FYE=V,BFP,!,P`G0<280D!`BL`(2!B-PEQF4@'!L -M:6-I=&S9"4!V;VMEO!(!ZP`!?PH#SA$@("C2$"4@8?L*`*D`("!AZ0`!)Q`" -M+0`(S0`4;Y4(<"DL(&ET('=P`$$@9V5T&1,!70H`I`0W($EN;@`W+"!IG@`! -M40$#FP`B96[)`0P,1<#4`T6%T979E`!,@%1``:A`` -M"@$`/06#;B!I=',@(D#E`!(BO0012!F4X.``P1$2(A`0!:""`L -M(E`(H"P@8V%P86)I;&D2%`8#`07Q``+S#P&W!`CV!0&7`8`@:6YD:79I9&P. -M`&@%(6EEA`$`.A("0@`$K`4`-@$A=&^L#3!D8737```%#A8Z+@$"R`D`P@`2 -M8>P"`,D*`2L`,VEN("2!T:&ER9"!P87)T:65S.X,``P(`87!L -M96%S948``'L`\BET:&4@875T:&]R2!Q=65S=&EO;G,N"@I4 -M:&4@=&]P+6QE=F5L(&1I4$`(&EN^`"`92!F;VQL;W>V`'!I;F9O -M%#36%K94QIM`!(ZU``` -MDP``3@#U`2YA;2P@86-L;V-A;"YM-"SA`$!E+F%C*P```@`2+50`)'1OJ``` -M(`&`9&ES=')I8G5!`;(L(&]N;'D@;F5E9'P`,6UA:?8!(V5R7`$%<``D:6YD -M`/(#+F@N:6X*"2T@=&5M<&QA=&5S9P`18C0"`68!$V6U`'`*"D=U:61EM@*" -M1&]C=6UE;G2!`0#%`3)A;&QU``#S`?4*('-YM`_`$,R!G:79E2XS!`,!JP(2(FL#!:L``20`Z2(@=71I;&ET -M>2!C;&%S1`"6:6YT97)N86QSG0!@P$2+8($4W,N-2!D5@(#I@0@ -M:6QV`]1R;6%T-50!"/$$4&%B;W5T&@$@P"`+"!I;F-L -M=62*`8%H87)D+71O+3`&`J@!$G-'``!!`&%M;V1E$D#(F5R60<#>`('(0"P;V-T970M -M;W)I96X!`P!@`@$>`*%35E(T($%30TE)=`(!%``"4P`/,@`%,$)I;LH$`$(` -MH"`H8FEG+65N9&GS!(-R(&QI='1L91$``OH`\0))4T\Y-C8P($-$+5)/32!I -M;;<"@"AW:71H(&]PRP/`86P@4F]C:W)I9&=E10!B2F]L:65T*0$![P$"20`U -M6DE0"0$#0``@=6Y."3!R97,G!W!OB,``!DT%``)"`$```I58W)E873/ -M``%U!`\&`0("J@,#OP,"O`(/'P,8,")R9?X(46-T960B1P,"3P#$+"!W:&EC -M:"!W:6QLB@`!5@`%R@%A(&5X8V5P0`40"EL)`VD"`A4,<7)E<75IP`#GP$`>P`!APD!HP`"2@P#"@,0 -M;6L($&EY!Q%A+PD#*P`A(&(W"7%R96%D86)L``8`C`H!#``!+`L"!`$`:``" -M.P!"96%C:#T!(79E4,`4&EN9&5PJ@`E;G0B`0`8"0`/#Q!C0@42;VP- -M!C4*5"!7:6MI4@PP:6YGR0`P:&]WFPP!LP,79)8*`BH!(4]N/P@`]PP">`8# -M`P$$S0`!<`!`;'=A>48!`-T!*F5DB@@"1P!P22=V92!A="T-`(P'`,$/D&EN -M:6UI>F4@2UV```S#`#W"!%IAP8`A`!P96YV:7)O;M<" -M,7,@=Y`#`:`"$&W8`1-R6@,%,`(`6P`"?P`1>7L#$7`U`-%A=&5V97(@8FQO -M8VMS\```[@2X'<70@82!T:6U7`W%O8!(71O(@`%2@!2="!O;F-\$B)/;AP."\,``N0",G!R;SH!`84!46-T;'DM -MS`"2960@;W5T<'5T[P(`8`3Q`V]B:F5C="US='EL92!A<'!R;\@#`$,2`OH` -MX'1O(&AA=F4@;75L=&EP)0``(040=A(#0')E86W\"E4@;W!E;IX`$R`5$`!J -M$``*`0`]!8-N(&ET2!B=6@-$B`D"`!E``!Z``#-`H5A('-O8VME=#X# -M27=IP`28D(`!*P%`#8!(71OK`TP9&%TUP``!0X1.L$"`2X! -M`L@)`,(`$F'L`@!A`P$K`#-I;B`G`0"/`C-A9&2.`AAA]PP!UP<#'@]19FER -M>D``,P``*,!!H`%,7=A;G\%$G0=#P-%`0!@```:!!!T -MC@A<"+``` -M.P``!`,`2P+%1`G -M-Q,`)AD`%@)S82!F=6QL+98(F-%#A)B!P`2>`<``'`$`)()`"<`%"I/&@]D&O______________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M________________________________95`@:6YS:6(@``#P"6=H="!I;G1O -M(&QI8F%R8VAI=F4G1X`<&QI8G)AP#S"2P@:6YC;'5D:6YG(&AA``"/`/0:("=D;V,G(&1I2!I;@IA(&YU -M;6)E6]U(#\!8"X*"D-U -MFEP,A8`!'P! -M32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9-!0`"0@!E6-A;B!C?P(-F5A;;4%X'-YU`P#P!`![``-S -M!`![``&'"0&C`%0@;VYL>0H#$&UK"!!I>0<182\)`RL`(2!B-PEQ4,`4&EN9&5P -MJ@`E;G0B`0`8"5!A7L#$7`U`-%A=&5V97(@8FQO8VMS\```[@2X'<70@82!T:6U7`P!K -M"S%M87#X`C!E;G21!@/0`@%1`T!G:79EY@$A=&\B``6A`&%T(&]N8V6%`"%/ -M;I`#&V7#``+D`C)P`%`@(&)S9",'(75SO`$`/06#;B!I=',@(D#E`!(BO001 -M2!F@``P0&%82!S;V-K970^`TEW:7-HN@3`4X.475S92`B(0$`6@@@+")0"'`L(&-A<&%B00`!]@($ -M`P$%\0!A92!!4$ES/PX(]@4!EP&`(&EN9&EV:61L#@/;"`"%``(5!@!"``2L -M!0`V`2%T;ZP-,&1A=-<```4.%CHN`0+("0`]`!)A[`(`R0H!*P`S:6X@)P$` -ME0LS861DC@(88?<,`=<'`QX/469I1$@#R$0`6`G-A(&9U;&PME@AR9"`G=&%R)P\!`0(`(7)EK0H!0@%` -M8G5I;($&`(H``V,``"H``J(3!F,`2V-P:6]D``;3$@$P`S!F86,J!P`]``," -M```I$")N=&@#`!$"-G-A;98#%&%G!5F-%#A)B!P`2>`<``$D!`)()`"<`02H@97@;$T!S.B!3,@-4 -M,!-&%C='L3<&1E;6]NP`` -M7P%C875T:&]R:1``EPT!\@(`P1,2+NT/4'1O<"UL#`0#Q0P`,`0& -M";8""',5`.L%`>X/\`4@*B!.15=3("T@:&EG:&QI9VAT<]P`,')E8VX,`C$% -M`Z`"DD-/4%E)3D<@+0P%`$(4`,H'(61O7P8!AP4`S@#`*B!)3E-404Q,("T@ -M9`HQ86QLCP0!#0``BA8`OP`"*0`#0`41+3P``5X1`A@`8&-O;F9I9[(6$"W_ -M!0$,``)$`+5S8W)I<'0L('-E96<``"@%`ED6`F,(@2H@0TUA:V5,U`0Q='AT -MB``A<'5G$#`@(F,T!A$B)`,`.`PI;VQ-`"`*"N$(!NL#`2D!`!8)`(X!#VT! -M`0"P#!!U/1,"$!\`!,GK0`#)`0`DP``3@#P`"YA;2P@86-L;V-A;"YM -M-`D-`^T`,"YA8_\```(`$"UD`@"?``2H``#9#@BB!!(L&@X`UPL`60M1>2!M -M86GV`2-E!,"(0`$F@,#,P``B`0/-``+`"(`##4`+V%T-``,*&%T,P`'K0,1,[8+ -M`!`4D"!O=F5R=FEE=_,"`*L`!<`+`'$%,'=H;Y$"%"JD"H5?\%1FYA;'.=`!)S/@M/:6YS -M:60:________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M__________________________________________________]Y4&5S"B`@ -M62```/$>*B!F:6QEFEP(&-O;7!R -M97-S:6]N%0!=8GII<#(6``0F`$TO3%I7'0#_`VQZ;6$L(&QZ:7`L(&%N9"!X -M>B,``!DT%`#Q,@I4:&4@;&EB2!C86X@8W)E871E(&%R8VAI=F5S(&EN -M(&%N>2!O9B!T:&4@9F]L;&]W:6YG(&9O"!I;G1E'1E;DT!L7,@*&9O$E33SDV-C`3`%HW+5II<#D`-EA!4A$`0PI7:&4# -M`@#D`00%`A$L_`%AT!X'-Y -M`>-R86YD;VT@86-C97-S+GD`!I<`\@)I -M`35N97<7`@!2`#!A;F1[``'.`!1V6`,24,`4&EN9&5PJ@`B;G1_`!!R.P0`!``P=&EC\`0D;VZ!`02N -M`/``5VEK:2!E>'!L86EN:6YGR0`P:&]W^``"]0``C@0#+``"*@$A3VZJ`!PL -M`P$#V0("<`!`;'=A>48!`-T!\@%E9"!A=71O;6%T:6-A;&QY1P"P22=V92!A -M='1E;7#$`^!T;R!M:6YI;6EZ92!S="L`L"!L:6YK('!O;&QUN`'A+B`@268@ -M>6]U(&1O;B?L`0"V`/$":6-I=&QY(&EN=F]K92!A('#K`"!U;#<$(&5A60)` -M("AS=2\!&7,<`A!AZ0`'+0`'[P4`@`$"F0%P*2P@:70@=W``X"!G970@<'5L -M;&5D(&ENI`0W($EN;@`W+"!IG@`!40$#FP`B96[)`07L#$7`U`-%A=&5V97(@8FQO8VMS\``0:%<%(6ETH0!!66]U -M2X'<70@82!T:6U7 -M`W%O8!(71O(@`%H0!A="!O;F-E -MA0`A3VZ0`QMEPP`"Y`(R<')O.@$!A0%18W1L>2W,``!(!E)U='!U=.\"`&`$ -M\0-O8FIE8W0M2!F)M96UO -M?\`!8P``0`"\05R;W9I9&4@96%S>2UT;RUU8<``J,!!H`%,7=A;H@`$'0V!`5%`0!@ -M``'Z"0".!S!S:RQ.`P-^!KEC;VYV96YI96YC9<`!`(D`,&UA:WD`D&ES(&5S -M<&5C:6X$`=`!`JH!`#H(,#H@(I,*#KL*$R*Y`B!L;#P!`N@"`*4'`!$#`L$% -M0"P*("#,!Q!PWP``;`0`E@`0(',*T"!S87ES+@I214%$346[!@?H!N$@8G5N -M9&QE+@H*475E<_H"H#\@($ES7!1`GH@1` -M9W)A;18"M``-G`0"3``!.`/`` -M+F%M+"!A8VQO8V%L+FTT"0T#[0`P+F%C%P$``@`0+:("`)\`!*@``-D."*($ -M$BP:#@#7"P)\`#%M86GV`2-EPH"MP(` -MA1(A86R)!V!S97%U96Y+#0#6`@"3``!U```7`@#Y!`%Q``%Q"@B7`'-E;G1R -M>2XS30``[P0R92`B:P,%JP`!)``4(@L+62!C;&%S1``!'PE&;F%L]!9!I;@IA(&YU -M;6+R#!=FD0<#'@'7+@H*66]U('-H;W5L9*0+`"@!,6-O<'8&0&-O;6V>"`"X -M!!,B!0XR+F@BJ0`R:&4*7PQ!(&-O9'4!`!0`!.D&`W((`G\"-&UO5$P"9!G!E2X`L2`H8FEG+65N9&EA -MU!%C;&ET=&QE$0`"^@`$7Q:10T0M4D]-(&EMMP*`*'=I=&@@;W#+`\!A;"!2 -M;V-K%V,/"Q<`TTUI8W)O2X*"B`J($DG=F4@871T96UP=&5D('1O(&UI -M;FEM:7IE('-T*P#X4R!L:6YK('!O;&QU=&EO;BX@($EF('EO=2!D;VXG=`H@ -M("!E>'!L:6-I=&QY(&EN=F]K92!A('!A``B;`%IE -M;F%B;)L``#X`"W$`*&1E$0`#J@`1+/```H``(FYE)@$`%@$`0`#X"V%G86EN -M<`!`"@$`#,`@&%N9"!W&%)`$!S.B!3 -M,@-42!F:6YDT`(Q9G5L+P(&10`0+Z\' -M`84!$6%R!E%A8W0@P``"@+Q`F%U=&AO@`K!#3U!9 -M24Y'("T@=Q,'`+D(8F-A;B!D;Y\`,W1H:2D`H$E.4U1!3$P@+2#0!S)A;&QU -M```-`"%R=2H"`RD``T`%$"T4`1%SE0`"DP"P8V]N9FEG=7)E("W.``$,``)$ -M`+5S8W)I<'0L('-E96<``/T(9&1E=&%I;,,$84--86ME3-0$,71X=(@`(G!U -M)@EQ(F-M86ME(B0#`*0)*6]L30`"5@$&ZP,`E`!!2!N965DQ0@0>5L+4&$@=VAOD0(C*B#9 -M!X5?] -M!;!I;@IA(&YU;6)E<$",&5C=)D#$61A#0,<`@5X"1!F+``!MP91*B!'3E5U`0(U`B8@*`0+`!H` -M06QO;F=0!F)N86UE+``-J`0`9`X$J(%!/ -M4TE8("`-`5L``A``,G!A>%H)`ED'`W@"!R$`L&]C=&5T+6]R:65N1!``8`(! -M'@"A4U92-"!!4T-)270"`10``E,`#S(`!1!"V0X1>2X`H"`H8FEG+65N9&GS -M!(-R(&QI='1L91$``OH`\0))4T\Y-C8P($-$+5)/32!I;;<"$2AX""!O<,L# -MP&%L(%)O8VMR:61G944`8DIO;&EE="D!`>\!`DD`-%I)4'4$!$``('5N,0L` -MBQ`@960Z`$`B9&5F?@81(F8)`Q@``*$$(VEE50$`PP$`H@&%0E-$("=AFEP/@$@:6^[$'TJ(&)Z:7`R%@`$?`%-+TQ:5QT`HFQZ -M;6$L(&QZ:7`3`R]X>B,``!DT%``)"`$```I58W)E873/``$M"0\&`0("J@,# -MOP,"O`(/'P,8,")R9:`-46-T960B1P,"3P#$+"!W:&EC:"!W:6QLB@`!5@`% -MR@%A(&5X8V5P0`4`N04$:0("UQ$`0PX0:98%)V%XR@(@("@6!0$T!`"$`0,S -M!`#T`V`L(&5T8RGO"P+Z`P"I`@8B!`&;`0+:``^6`P4!R`-A(FYE=V,BFP,! -M,P`GD#`#X'(71EVP@1.N85`2T0$&D@"G!H96%V:6QY_`@V96%MM04"$0M! -M+B`@5$`44VES(&YOX@<`@@(#"A4`DP1!(&EN+;P`#GP$`>P`!APD!HP`"2@P#"@,`.`@`;Q`R=&AA"0$"#`(A -M(&(W"0!J"`'[%2%O$P$/`P),%@"V`A!G5180:2(3`2(`!9L$`.,3(6-E -MA0`A3VZ0`QMEPP`"Y`(R<')O"AFA8V]R>`907!P4X.``P1$2(A`0!:""`L(E`(H"P@8V%P86)I;&D2%`:-`07Q``+S#P$_#@CV -M!0&7`8`@:6YD:79I9&P.`]L(`(4``#H2`D(``'(+`-$``#8!(71OK`TP9&%T -MUP``!0X6.BX!`L@)`#T`$F'L`@&`#@`K`#-I;B`G`0"/`C-A9&2.`AAA]PP! -MJ0H#'@]19FER"U$W,3$W-0`> -M83$U,34U,@`>+S4Q`![_5==&96(@,#DL(#(P,3,ZAPJ1(#,N,2XR(')E,A.> -M9`H*2F%N(#(X*0`A)W.K"T!W96)S``0R;6]VT0L/(1X&$BY,`"XQ,TP``74` -M&S%U``\I``87,"D`841E8R`P-U(`0#(Z($E2&P$(#`@*!0/0%`#O#!EE&@P` -MG04"VPT"3A@!D`B$(`I.;W8@,3%4`"!!9+8;!JPB@U]?34%#3U-8%PT`@@0$$]@\$90`` -MP@$@(&Q<`6``'E("`@ -M0_$@`9D"`V,``%(7#P(A$@]U``@)DR$#=0``3@L#=`!01W)O=7`2$`"U`R$R -M-!4!&3$5`0`^`0=\!`$H``(O!"4Q.ID>H&9I>&5S(&UE`RDQ.D4`"AH`$5/\'P+8`&%T -M;R!)4T^?``!U`%!T;R!I;8H+-F4@2-RQH`+PU18V]L;&6((0#C#0!*#S!L92VK(@#``)F]NS0,!W`<&?`$11O0&`"H#,FP@,#4"(3`Z_"T`&QH#HR8'0R80968$`=\3`I4$`2X#`M$0``D+ -M,'1R884%(6%L.P0A,CD[!$`P.B!-<`(#R`8%$`,`%04"G``!\!3P``H4!$C"%`4!L87)GQQ0!ZA(`V!1B96X@8V]PE!$`#@,!'A($R`D!00`# -MB040,`@"`;(G`'@`=B!-86,@3U.I`@`\``>N!`$Z``-"`B0P.E``!^L``*H) -M`_T"$'->"0+N`%1S"DUA>24-8S`Z(%A!4D,$`1D``T,%$3#'`34@7E0-!1([ -M/B]`(&5X:1$5`J<$`]0'`!H!`)0=`XT*`F,`!IL``UT$`=\A!A`%!`<"!!L# -M8&,@8W)Y<,4$`L$,`8\``_L&(3`Z/1T!`@(`+`8"$`0`)@,`1P4"*@`"!0T2 -M,``(`]0#$CHN!T`M9VED!@``*@1!("TM=0X`$'4.``$'!0,R#@/``6!2960M -M8FQ@%@#\(@&4!P;^`0$9%2!E"!L96=A8WFU!S%M870,!`/!4`Q`,`,AT"D`4#=@@#O@$`OP<29"L``)$@.6QD -M95\(`%T;$&R[`0`5#@%`*"%E9,L#!A`!55)E;&%X`P(`P@4@2!!4D-(259%7T9!5$%,(')A'`0@=&@;`T,@=FES^Q0#*08`R0L# -M=0`T7`8P`!H4#$%+(!T5A9FEO#@D! -M50`%PP400<<=`%8`!_,C!3$%(6QY+`\$_0("6P`%NP%@26YT96=R70(@07#Q -M&`?W!`!+!@@-!0!_'2!A=`,L$'5.'@'@`0+^&`$!$A4S5``$$0$`WR,S("U6 -MX@X&4P0&:PLX,BXXJQ$W2F%NR`,`=@L!S`@&"@,`DP#@)V5C:&\@;F]N97AI -M0(O,#G?```?,=\`#P&O -M#`*'`@]#```6,7P-,TIU;#L#`"@````"`/@DL2!B;V=U'HP``)!`P0P``"1,0*8`4$@,2XW90<1,?4`""$`<&QZ;6$O>'I;`P/A -M`@!G``06(`D""`)`!`"?!1-Y\@X`20`12,@D("!G_A("10``V`D$00!`3W!E -M;I0E<")G>G-I9R+-*`"@,`)%``+#`P!%`)!!=F]I9"!F86P*`@.2!0*(`02I -M!`&@!#!P:7`F,P!1$@+>!P`\``ME`@?\`@+%!@%_!`TI`$<0"%W()`RM! -M9#L04FYE>'1?;`\T,B@IGQ9!:7,@=6$243(U)0H),2M0969F:6-S"`%E``$> -M'@.#"!([:A/30G)I86X@2&%R2!-:6-H:6AI'@#'!T%T86UPE@LP5')UY0X!\0X`I@0`L2A02'5R9"R&`,%":L.V -MF5D!0\2)P/``S!C;W)D`D%!;'-O)R0+L0`Q8FED`(5<]<.(`H)E`8A -M97/-`S!S=&$N*`"(``,.!"%S+NH=`XD&)#@ZS@D"&P4)D`D!I@X28)`"P3=@ED;V5S -M;B?G!PLR`&)W96QL*2RS!B)I65T"@E00T%D('5NH@`"K!`")0<# -MWP`)L1J086QL*"DN("!&F`M!;F]W+)0J,&UU2!E;F]U9V@@00=!+"!W9<:\!"W@!%S1/`0$I``4E`P_8 -M`0$P9FEXZP4`;`($_!X*L!,`#C0`S0``1@0!,Q@&(P8!OAP!9A$`2R$&]A\" -M:0,`/PX`"0D38=U#3H@"?$E$W`=`-`N9G)E96)S9"YO0"@D@(&UE87-U>P,!4P8".0``30(`N@L1:1Q) -M`5TO0'!A=&@=`&$@9FEE;&31`#!U*P%'(F!M;6%R:7HZ"1!P[#L`W!<" -MMP0`N@!`+6YO+;H*(V9ICC@T;&EBS4<#;Q0`)P`+J`!B.B!3:VEPDQ@!LP$! -M8P4!2@4#_P0",0A0,S(M8FD6!3!F7W1'`#!I(P'&`2`M!@"AP$`V#0%%",!5P8754-!"8G`(H!$&:;!B5L>?,$(`H))0]5:VYO=V[(``"O)4!A -M=&5G(QD+.0$"7!8`"00"+`4"EP(.3P<,G@`!F`<`U1,#Z@@!?`D""00&/0L` -MX@(/2P`/`"8!`*L``/@(&&5;`@-:%3`@=74;$3!D93L,`1%YD`X"N`T!U`\0 -M+8$N,65C;X$%4FQO9VECL14"-``0 -M!Q(NR!\&Y@X,I@`5,Z8``I,8!?D"`W8=`)T&$2Q,`@"3`!(LF@`0+"P$`IX` -M`3L!(&-A91`18I@+,79E`A8R7@(**0``J`$@8F%S3A%DB`,!%PD# -M%0$&PR4#3`4"*B(&=0`*2P!D5F5R:69Y300!5@@`21HQ9V5TF@T"I3P!8@L$ -MS54`<1H!C@5%,BXY+H(!`CH``$@!$FQ4,1!B$QD!VPL'X0\B*"VE#T`M>BDL -MJP,`(0\Q"6]FJ@TP'0`F+P%6 -M"0#'``*Y`%!U;F-O=LQ")0H))"``S`%P8V]S;65T:5\<`.Y3`$D$`U<&("P@ -M^@4`V08`*P0<9%@!H$5X<&5R:6UE;G1,2P,O)0#;#0#]/!0M(`T#@#`/G0$% -M`K,;!O@"`^@2!&$&$'G;`@&<`0=3!U1I=&@*"8,"%'-/$P04,@%(`P#W``&B -M"6%S+B`@*%>A$P%!$P&^!0!G"2$*"8U.`=P(`!0%8&QA*9!`;4E`.@3`O@D!F$!`*<$ -M`;$)!3T/`6H``C\K#VH``0S,&0)A!!8WA@A0,"XY+C#&!P"!!P+.4R!W::$5 -M,W5S92<;!30`($-OCQL`&@M0:6YI=&E\!@`/)00Q$`#*`0,)`@28``+'`PZ8 -M`!4YR@8"P``%*``&U`4`8P$"C30`>@4"B1<)9`#P`SH@("UA+"`M<2P@+4PL -M("UF+)L8$'0^�@00!G"0#C$`0+)H*!(T2H41A;6EE -M;B!';VRJ!`"C`!!B>@T`Z0`!CP,`B3@0>H*Q`O!0D!!0`07[@4("YCH2$`@@LP -M--*)7!Y^!T!=``#$!L2-XD%4&$@8V]UE!PC;V:6 -M!`>M)@#E!0%_``*I#PZG``?R%0HH``!;``"I`P&G``$%`!%?:0$07]\$(6)Y -MV3$"10%R92!U;6%S:Z0_`T`!`_H>#G``!E@)`LL`!1X"`(8'!C12!(0"4"TM -M9&ESIQ!2+7AA='1Y"@84`'5A8VPL"@ET[0'_`%-A;75L:2!3=6]M:6YE;HP` -M#0<^"0'\``6,``8_`L!,87!O($QU8VAI;FG5!0!Z50%)`@!.'`%520`%#@'2 -M"0&:)`-*!0"3`2!L9%<)`54N`/H;!&\$,&)U9\8%`1@``$`!L&]F"@DB;&5N -M9W1HGA2096YD(B!F;&%G'@H%80`2@$@"@D4``&Z)`,Z.P_T!08'B04**``">```)0@` -M\04`,A0&/`(#N@Q08VAI;&P'%PL[`!!/D`8`V1``\`("]PT+0$D@<'7P -M+PF-`@`A$`,D`048+P!,`0#!5`&$``4L!Q-)U`@!V0L`V`<097\G``$#4&XM -M;6%T;P4`%5T`U#XA;W)!#(([($D*"6AO<$@-D2!E=F5N='5A;#PE`?%,`!\! -M`#`+,F1E("<*`$,H`LX)`,Y5`Q4_`FL.#)<&&#.7!@"J`!4P+@$@0V\C&A!U -MD``$K0`$=@4`7`(!F"H29=\`!C4`$$XM30%85@#E0`"T!!,L]PL!<`@P(DAI -M[PH@>2*U`0-.`"`N,3@)`<\,`*\`%#$Y``/D(09<``"8!Q5Z-#P`EP*1:6UM -M961I871E#0$!D#@P14]&T2H`C!\P=')YSP\!_A4%PQ0`$0XP)(5`EH/!,L+`)T#(6]FA``#H0(`90@`OCL/ -MD04$&#-I!P`H``/0$!`WT",!50$334<<("YA)!4!3@<`$@02(,<@$R\#"`1J -M$D,*"6%C_`$A9&\H`%%R:6=H=$$3,6=S+KDA!F,``,0($"VT"`!2"@$-``&$ -M#`2[``?<%`%A!``C`1!I]0``B@,,)P$-70`!D`4/E`L``.4+(&ENO2(@8V6] -M(``7$`'0#0`T`@#K.@$`*@1](`!&%0",)S!N:6/2`2)H868&4')A9W1A!P,( -M7#L`00`#M%P1<_L(%'3#!R1H88@!!F@#";H'&#.Z!P&(`0\H``40,5(:)&ME -M6@`@8F5K'`!Z`P5&2P,,"@#'!4`H*0H)2PPY!("UP -M+#X'`6,Z(0H)Q24""1$5;Z,0$"QB$0'Z#00X"U!S96=F8><%`CX"!H$``F@) -M`U8#`44B`NH2`S\""0A```001('X88`H):6YS=(0&$',C!!!TF08)&&$#IP`%I@0(7"X`T`=T -M>5]L:6YK7\P2%"S0!0,=`#!S=')O6@(N`@/T,0R6`1@RH0T`E@$&P@P&B`$4 -M,@`&`-\"0'-T("A<(S!Y972<$!(INP`"ZST"?A(`&SP##`(#/#`.=@`'80U2 -M075G(#,O)!(WXS(`LS(`F0,$O`8"*QX`@PLC"`M -M+7-))P22!Q(N-P`%.`P34K,:8'-U:60O0@(6A``X````0\`C`,`92@`]AP& -MGR80+`T<`0$,)`H)AA4"21,$43DE('06%@*7!"`N:"P>(V%DQ0EC;&5A;G5P -M?BL*8@$2+!T5``P'$7,B"@`S$A$O+Q(#W`4P;@H)!`E386YO;6$("@',6@`G -M&@5D#`$%&A=YT@$+"P$6,CH3"B@```L!#MT%$""1`P),(@`$#`*7`U!Y(&-L -M;Q`.`)4I071R>2#2*P`>!R)T;X`<`P,T("!SS`@`8V(`P!@!DB(!EQ91(&ES -M"@FF!`D.`G(@9FEN:7-H.@$!`@T`Y@P$E0``E`$37^45`*`'L'=O0:70@:&5L9"!OPT,`J`4"F@``81L!J@``O34`A2H"%R(`^1T@ -M=6U!,`!\%0)<#@3^!@&<0P#Q$&`@8G)E86M**@#K#@#Z+`$8'@#Z,`'X`@2? -M``%@`!!?&0$69?DT`)8.`*@``NXL$&AR#`$N'8!S;VYA8FQY(+D!`!(5`I<- -M`,DU`*8<%WF"$X%3:V5L971A;'P+!HP(`5T'`^P!!@(%"^P!&C'L`08H`%!& -M;&5S:,D7`'(6$&];,!%R:Q,`?0("?@$@+F.\`1%AP`008[T,`>TC`.,-`!0E -M(6-H&P`C:&5_&B`@;MX"`2D!$6$A(`'*70)I`@`D`6(\A`CH["@E3``&:"1)WQDX`R0L`7P,#>P("[`,"D@$0;E,R`,QH -M`'0#!8T.,71O=>P"`$P%`()%`V`!%3'A$0O^``R``N`4`GQ`$`2(*^0H!$`0!)`T)-3(!W0@$64<` -M0`4,XP`'"`0**0``M`8![!$0;BY($6X]+0!^&@12``5N`0Q2`!8TP@(!4@`% -M2Q($_!]``!_+P%\+0`9`@"8'@$0-`1<*`)I``#D``(_`@#$50*+ -M)P4H`0'J`P0`%P#8!0DZ"2)T;P@]!(@!!3<`#(@!![D%"H@!$4@-!P1'#2!S -M.Y`-$&70!&!N=7@O9G-M#0*X"0+B``&Y"`BK&0`-.#%E65T>5,#5S0! -MI@$C=&\R%@"A"@#-%@""$A`B^0%R(&-H96-K(H4&!%PD`T<)"Y@!!V$!`",% -M`E$7%W/$24%)3$5$H@H!=``!M64`X0(`+04"+TH!'0%`82!W89$T$&&8+0"/ -M/2-F9A@"$FG%A4''@!#5T%2 -M3A@"!@H@![<``6H$!V(&`%P!!BD``"L4`>T!`)X"`'@",7,@**(``'<%`.," -M`E,+%RU790'I``#^!@/[%P`F```^``G\&3)O=RG'`09K``+I,@0-#`2$&`"# -M/S`@;V:*;E)S:R!G;[0P`&8!`*(.(69FT0\#Q!`P.R!R5FP!`A$0:4@E$"AX -M``/4$@!)!`*]`@?]``B4``#Z$D!I;F@`!-@HQ<&%XU0`%[0,` -MO18B=6ZE`2!E9%8D`38!#[D*`S3#`!@*`:)'0%R!P"O`31'240G!0(,`Q)S``4#10,B8GD6 -M`#%I;F<8`2%W:'0N`;<.`TX;`=U1`>8\4'1O;R!F3$(`PP<`SA:A;GD@<')I -M=FEL9;`:`9DI#V`2!#@?LFES(&QO;F``^'"@$!G@`'Q08!G@`%3P,10@E`5`@9&]W -M;A,.!UX!('=H,@$!)0`#$0@!3P`A8GE!``'.&5$@=&]O;*T$`#<&`N8H!2X` -M`H4&`=L<-6UI>BP!!C4+!VP``2P!!]D%`"P!`P="`C4"`=`H`5\1`/H&`=$H -M`8T&!D0``)P6`_17`J$`)&8@1@%!4$52331H("!ATQ5A97(M9W)A^#0!3@\P9F%C7@(688<0`",!!-L5#;`U$&`0@=`'Q#$&_=/@"$`@`M -M!0(R+@$D50:+=P)J"0$K6@/0!A!3(C509F5A='7?"`+V%Q!N>P$%RCL`J08! -MPQX'EP,"1Q4!<@$"<@!1:6YV;VS4`03S`0'-!@0$50%1#0!3!@`&`@!<8A%) -M%!T38XH)`8(T$'AA"P```B!O9L\1XB!O=F5R:&%U;"!W:6QLPB8!N"\#,38" -MI`L!?@`"BBX&1P$'?'@"V1``SP("[AL*W0X(U``"S0`"1R8!G#L#=P<`'"40 -M*/8X!+]*`+$$`8,!`'T"(V]F#"<09CT3"XD``,L?$',F!`,D``%&"`!#"`,V -M)`,!>05$#@,T!`&*``()`(P? -M!2<`0$)U;7`%*!!SFPL0=&PV$3/C``"+)2!)+SQ6``@S(G)S,2`",1(2-M83 -M`\P;`$$!049)3$4A)`/B$`\V``0&1P8"[P$$^2(#-A4`I`,`?%85>19/,6%L -M._L``?\*,6QO8[`1$6$]"C!M:6X:/A)UZ"H!JP85+<@!`=@U`G0>`SX5#!(! -M-S(N-3X)`'4>!BD`LT]U=&QI;F4@04))SD81!IH``-@)"^L`!Y<7`-H%`H$!`!L;,'-E*`!Y -M42!4:&5YEPD`3BP"C@X`ZP(`9@\!2P``.BH59N(?"FP`P')E8W5RG%A%R50\P:V5EZ7$!KR=0 -M;&4@=7!%!P!C-`(\``!V""!O;LLK0DQ$15)V`*)354U-05))15,*_1`"K04/ -M9`,`&C$A`0,A(Q`V60X(F24`5A<@;F1O`1)TV4,%B`\)EB,R(')E;G``RP`! -M-PT`"64@;W(('0(H$P!.`@5@\`V`)0=V]R=&AT`!1S$S@!Q081!D;5L"30$`VP50<&%C:V&72P<">`#8 -M`1!EN`I`+F=Z"LQJ`&H3`8<$`8H;$G/X%`?V!`#K!0+?#`*(.`-S,P#/`02. -M!0)[%A0Z>P/H!`5X<`A9_$2[^ -M30(`&QLUVAD!O@$#]@$$M1$)1T\`/@X$71D`'PL&7QD`NP4`1A,"M@0"'Q(` -M`P$I#Q!E7@D1>=T1`#T"!.Y#,7,@*`H(`BL<`A`* -M!AP``IX83#%-0BEQ`*!-87)C=7,@1V5I?0<`5AP`'P0`#/`'S#GAS;FEL+F%N=&)E87(N;W)G+S(P,#4O,#(O,#4O@@%`+6UI -M='YI!`\``%H:@')B96ET96XO2P`"RA<`9@<$[8H`!Q`"M0`-OA/$%+"!(4"U56"P@ -M56YI>'=A]0``!O>&9I;&4``0!+X3`P,#8T-"``,#`P-S8U"``B,#(0`"(R -M,`$`_P<@,3(S-3,U-3,U,3(@,#$R,#(S`"`PEP!+`@(`KW5S=&%R`#`P8W4' -M`0M2,!46%C="!S8`"A(&1E;6]N4$`(&EN^``(M@)A:6YF;W)M&@00 -M(+@&!+T"\`E.15=3("T@:&EG:&QI9VATP`"-E)ZT``R0$`),``$X`]0$N86TL(&%C;&]C86PN;30L -MX0!`92YA8_\```(`$BU4`"1T;Z@`#*($LBP@;VYL>2!N965D?``Q;6%I]@$C -M97)<`05P`"1I;F0`\@,N:"YI;@H)+2!T96UP;&%T97-G`!%B-`(!9@$39;4` -M<`H*1W5I9&6V`AA$5`8$T@$"=0`!MP&R'!L -M@P(#+P,`0@$"(0`$F@,#,P``B`0/-``+`"(`##4`+V%T-``,*&%T,P`&`0:` -M+C,@9VEV97/?!H!O=F5R=FEE=_,"`*``!+L%$&%Q!3!W:&^1`B,J(-D'A5]R -M96%D+C,L$```T04=91$`45]D:7-K%@`"?@<(/@`#'```F0`0=E\!`K<"865D -M(&-A;(D'$'/4!D%N8V5SK0(`DP``=0``%P(`^00!<0!8($%027.7`'-E;G1R -M>2XS30`"]P,2(FL#!:L``20`4"(@=71II`59(&-L87-$``'O!49N86QSG0!@ -M]!;!I;@IA(&YU;6)E`D09BP``;<&42H@1TY5 -M=0$"N@$F("@$"P`:`$%L;VYG4`9B;F%M97,L$```!0L3(!$``&,`4G-P87)S -M?`(AB,``!DT%``)"`$```I58W)E -M873/``%U!`\&`0("J@,#OP,"O`(/'P,8,")R9:`-46-T960B1P,"3P#$+"!W -M:&EC:"!W:6QLB@`!5@`%R@%A(&5X8V5P0`40"EL)`VD"42!T:&%T0PXQ:7)E -M40`!\P,!R@(@("A3"@$T!`"$`0,S!`#T`V`L(&5T8RGO"P+Z`P"I`@8B!`&& -M`0+:``_(`PIA(FYE=V,BFP,!,P`G0<280D!`BL`(2!B-PEQF4@'!L -M:6-I=&S9"4!V;VMEO!(!ZP`!?PH#SA$@("C2$"4@8?L*`*D`("!AZ0`!)Q`" -M+0`(S0`4;Y4(<"DL(&ET('=P`$$@9V5T&1,!70H`I`0W($EN;@`W+"!IG@`! -M40$#FP`B96[)`0P,1<#4`T6%T979E`!,@%1``:A`` -M"@$`/06#;B!I=',@(D#E`!(BO0012!F4X.``P1$2(A`0!:""`L -M(E`(H"P@8V%P86)I;&D2%`8#`07Q``+S#P&W!`CV!0&7`8`@:6YD:79I9&P. -M`&@%(6EEA`$`.A("0@`$K`4`-@$A=&^L#3!D8737```%#A8Z+@$"R`D`P@`2 -M8>P"`,D*`2L`,VEN("2!I;G9O:V4@ -M82!P87)T:6-U;&%R(&9E871U`<``$D!`/X&`"<`4"H@97AA20!`4$`(&EN^``(M@(B:6X#"``0""!F:34!`'P`\`LJ($Y%5U,@+2!H:6=H;&EG -M:'1S(&]F(')E8P8"5&-H86YGH`*P0T]064E.1R`M('<3!P"Y"&)C86X@9&^? -M`#-T:&DI`*!)3E-404Q,("T@T`'2(`")P=28)<2)C;6%K92(D`P"D"2EO;$T` -M`E8!!NL#`)0`07,@:6Y,`0]M`0$P87)E3@(29-H!-64*)[P`$R>M``,D!`"3 -M``!.`/4!+F%M+"!A8VQO8V%L+FTT+.$`0&4N86/_```"`!(M5``D=&^H```@ -M`0BB!+`L(&]N;'D@;F5E9,4($'G*!0'V`2-E%7W)E860N,RP0``#1!1UE$0!1 -M7V1I=&%R+C54 -M`0CQ!$%A8F]U4P4@"`"X!!,BO0(R+F@B -MJ0"`:&4*2R"```[!P$C"8!A=71O;6%T:?\"$'G!`C!E8W29`Q%D80T#'`(%>`D0 -M9BP``;<&42H@1TY5=0$"-0(F("@$"P`:`$%L;VYG4`9B;F%M97,L$```!0L3 -M(!$``&,`4G-P87)S?`(A`@@;W#+`\!A;"!2;V-KFEP,A8`!'P!32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9-!0` -M"0@!```*56-R96%TSP`!+0D/!@$"`JH#`[\#`KP"#Q\#&#`B&-E<$`%`+D%!&D"`M<1 -M`$,.$&F6!2=A>,H"("`H%@4!-`0`A`$#,P0`]`-@+"!E=&,I[PL"^@,`J0(& -M(@0!FP$"V@`/E@,%`<@#82)N97=C(IL#`3,`)W-HL``!$@`/1@-C!`4$`EL! -M`8D`#UD#``H6`S-7:&4#`@"_"`/4`A)SY@5A?P(-F5A;;4%`A$+02X@(%1`%%-I4,`4&EN9&5PJ@`E;G0B`0!$#0'E -M%@!"!1)O;`T&L`M4(%=I:VE2#`,,$S!H;W=1#P*F!P!."`/:``N@%03\!`#S -M#@!0!@/-``%P`$!L=V%Y1@$`W0$J962*"`)'``_0%__@"?H#$&,W!@`%&,)A -M=&5V97(@8FQO8VO5"@#N!S`@:70(!D(@66]UYQ,!Q`U`8F%C:T`#,69R93T/ -M,'!A2X'<70@82!T:6U7`W%O2W,``"."5)U='!U=.\"`&`$H&]B:F5C="US='G@&4%P<')O -MR`,`^10"^@!0=&\@:&$Y%D!U;'1IPQ,$J0`"`00`N0A5(&]P96Z>`!0@]`\A -M=7-U!Q%I(0AC:71S(")`/``2(KT$$',3&P7J!`,<`'`@:71S96QF4P$`?000 -M+P(/8'1E;B!U7,N -M"@`!`/^)`#L7#Y\!30\`'@M1-S$Q-S4`'F$Q-3$U-3(`'B\U,0`>_U771F5B -M(#`Y+"`R,#$S.H<*D2`S+C$N,B!R93(3GF0*"DIA;B`R."D`(2=SJPM`=V5B -M!A(N3``N,3-,``%U`!LQ=0`/*0`&%S`I`&%$96,@,#=2 -M`$`R.B!)4AL!"`P("@4#T!0`[PP991H,`)T%`ML-`DX8`9`(A"`*3F]V(#$Q -M5``@062V&P:L(H-?7TU!0T]36!<-`(('.&EN(,01!-D/(G)EJ08`)P4`N`P2 -M:P@','-T;TL.`+@B?PI/8W0@,C!K``4`.08`A@82=J43`@,,`S8``[P!#Z$` -M`"MGF]P5`%64V5P(#*!``VH`0+.&7%T;R!S965KD`I&@'5 -M`@DX`P#*"C)I97-.``*:!&$Q.B!.97>:`PI(``0;`UES(%-&6`,%"S\`0$)U -M:6QK!0"Y`:)O;B!7:6YD;W=S(0$#YP4.2P$K,&%+`14P2P$P57!DN!5T`P, -M,RUS._@6"*$9`ADA$F_B'$!H87)D4P(E+W-;`E%B&0"5##!E;747&6D@8G)O:V5B`#`R+GAG!`!W$`&O)2%O -M9K(6<5541BTX(&AH`!)SF04%^P!`4F5F85D'`04/$%]R#B`H*7L:`"\-46-O -M;&QEB"$`XPT`2@\P;&4MJR(`W`<`YR@!EB(#+`$!D`P@;VPA`P,2)!!S'Q\@ -M=W(,`0-W`!(Q$`:!,3H@4W!L:71?#0(`!@`L`0&1!C!P87)N`@(>%P`T"`/` -M`@":`Q%L^24";`(!QP`5,30#`X(#`L\AE`=V]R:V(!9')E='5R;JP<`)`B`2$/$&;N`@%9`7%A -M8F]R="@I1``&-04`M0$`>0`WH2 -M`-@48F5N(&-O<)01``X#`1X2!,@)`4$``XD%$#`(`@&R)P!X`'8@36%C($]3 -MJ0(`/``'K@0!.@`#0@(D,#I0``?K``"J"0/]`A!S7@D"[@!4&D1%0*G!`/4!P`:`0"4 -M'0.-"@)C``:;``-=!`'?(080!00'`@0;`V!C(&-R>7#%!`+!#`&/``/[!B$P -M.CT=`0("`"P&`A`$`"8#`$<%`BH``@4-$C``"`/4`Q(Z+@=`+6=I9`8``"H$ -M02`M+74.`!!U#@`!!P4#,@X#P`%@4F5D+6)L8!8`_"(!E`<&_@$!&14@97)D -M`P,C`@!4!`#.`@!8*P%.``,)`P!*`F)I;FEM86RM``$3#7@@;&5G86-YM0#,O`G@5`,0# -M`#(=`I`%`W8(`[X!`+\'$F0K``"1(#EL9&5?"`!=&Q!LNP$`%0X!0"@A963+ -M`P80`55296QA>`,"`,(%('-T7P;09F%I;'5R97,[(&UIF7'`P`M`0!Q`0-7!`!_&"%O;88'#%$``8X%4&YT-C1?S`L%``>@ -M;V9F7W0L(&1E=@<`,&EN;P<`,'5I9`<``#\#$&<+``*<``7^!`08*`'"$#9! -M0TQ%"0)U`!4QN@024SD#!C48`20!!28#`$0!$C`B!P%J!``&$0)\)@.6`@<* -M"3$Q+G@-%P&,``:%`Q!2R`=%869I;PX)`54`!<,%$$'''0!6``?S(P4Q!2%L -M>2P/!/T"`EL`!;L!8$EN=&5G)``9"``+3 -M`P`I`Y!F=71I;65S*"DX+F)#>6=W:6YK$@9%`0>'`78R+CQA`;&5A:U0!"!X!`$@`$G,S``5<`0!D``FUA+WAZ6P,#X0(`9P`$%B`)`@@"0`0`GP43>?(. -M`$D`$4C()"`@9_X2`D4``-@)!$$`0$]P96Z4)7`B9WIS:6`@)[``6)`D!!9&1IR0HP86P@2@!`-P)M(B%S98$#!+`=!),-!'4'85=!4DX*"1PK06ES(&/Z,Q5OPP<` -MU1U0861A<'2;."!N91PC,V%R>;L!"=\`55-T=61I8`L`E@`/2@`!-`E!;!$#``@!`%HA -M`5\``_40`/,``.D#,$1E8E\!L4)U9R`C-3$V-34.`?$.`*8$`+$H4$AUA,`2P$41:L> -M!]$(`8(`)&]N*Q8!\0P"]PM`;F]W"?P#`9<2`78,$G11``85!@#0``.@"@8, -M#A!?*A4@>5\/!A!?;P8P*"D@6"X$[`\`00PQ+`H)2!R7!,@961S(`#/"P"])@!1,#`L"@E4 -M!`"`!P!:#0#B!@!A!0:^`P`\`R!T(",%"7$F`;L`!LHA(@H)?0`4<^@OQ6)E -M(&UU8V@@96%S:>8-`H\/*RX@HC,`311":&4*"3$8`5\1"$(G%',])P;1#P"# -M'`-Q`!(N_!`"MP80.$4$)&YY:Q8:+Z\#`HH6`+L!#_D#`@U)``J["0B[&0+W -M'`%*``1;`@+Y#!!CN@$@97)^)2ET;W89`$T&`'PT`@2US:7IE9`4/$G.*)3$@*A$) -MSAH`A@,/[A<"`!<-L2@I(&AAFEPEP2"_`0`P`"`@82D`*RDN -MM@#@2F]E0,A(&*Q'`&[ -M$P%-$P!7!B)A=$H`!9X'`<4(`AQ``-A"`FLK`)$I4F0@8G5GQ0(@.L%`&P"!/P>"K`3``XT -M`,T``$8$`3,8!B,&`;X<`681`$LA!O8?`FD#`#\.``D)$V'=0W,B4V-O='0B -MW!80(%0```L*!9X#$VV#/A!SU`8$-0"22V5E'!L;P$0`&T6$&5D#0)M`0)E -M+95V97)F;&]WPP$_@D$V@Y0"@EP2P!$'26$`&#.%%E(&)O9(L]``8-`8D! -M`#8!,#L*"6T&$FG,$@#0`2%O=:T-P')A;F=E(&)E:&%V:2U/`$0.`0L,!!0[ -M`9@)$7)R`0&K`0)],U$M3A+,&ER95<8!&@8,"-I9O4,!'@8 -M`H9`.`K@-`=0/$"V!+C%E8V^!!5)L;V=I8[$5`C0` -M$',T``!.%0)/(@'V%`!V`0$8``);20*;%P-]`@;4"`E3`D0T+C$T>AY`9#L@ -M:5P\`%)$`)@#`1X`&#,$0"()84H*`%,!`?`($&=+!1$O=B-@(&UI>'5PWRD& -MR!8"L0``P@D4:<0O(F0*[18`9P0"A"D!'@<2+L@?!N8.#*8`%3.F``*3&`7Y -M`@-V'0"=!A$L3`(`DP`2+)H`$"PL!`*>``$[`2!C8640$6*8"S%V97+;`P32 -M)P&-`".``#3"P"! -M`&`@8VQA`B4&1E=FEC5@$!RR$!32(` -MB0H`2!@3(G`#&2*)"``6$`(U!D!N97=CM@("<0@#I``6.^0#`O$1`%P"`6,$ -M"$T!`#4"`!`A('1H2PL!>P`"G!LE.#I(#0)E#@-J)P!(`@2;`PDD$1PL6PT` -M.QH'004P26=NR@@$[`I"('-I>ND,`$,-`B@K`#0.$F&[(@#8"P#^(14RC@`, -M7@(6,EX""BD``*@!(&)A4T$`58(`$D:,6=E=)H-`J4\`6(+!,U5`'$:`8X%13(N.2Z"`0(Z``!( -M`1)L5#$08A,9`=L+!^$/(B@MI0]`+7HI+*L#`"$/,0EO9JH-,')M85X2`)X? -M,F5S'!E-\4"%C'% -M`@HI`#!&:7BF00&U)0#H$P+X)`9A`0"G!`&Q"04]#P%J``(_*P]J``$,S!D" -M8006-X8(4#`N.2XPQ@<`@0<"SE,@=VFA%3-U?@=`70``Q`;$C>)!5!A(&-O=90<(V]FE@0'K28`Y04!?P`"J0\.IP`'\A4* -M*```6P``J0,!IP`!!0`17VD!$%_?!"%B>=DQ`D4!`@"&!P8T4@2$`E`M+61I0H&%`!U86-L -M+`H)=.T!_P!386UU;&D@4W5O;6EN96Z,``T'/@D!_``%C``&/P+`3&%P;R!, -M=6-H:6YIU04`>E4!20(`3AP!54D`!0X!T@D!FB0#2@4`DP$@;&17"0%5+@#Z -M&P1O!#!B=6?&!0$8``!``;!O9@H)(FQE;F=T:)X4D&5N9"(@9FQA9QX*!6$` -M$G,?!`96`0).``,"!!$@FP8!4@8!/@(`J08!+P0$-P`%\P,01J,!0"!C=71K -M`$!R96%L>0<`-```D0(`Z`42;AU(`0\!!38`"Q@(%C+:`@+$`0\I``46,2D` -M"E$`$4W_)@"X!D%S+"!R%Q@`E```P0*@9&]C+71O+6UA;C\.`WX'`'H!(`H) -M%``!NB0#.CL/]`4&!XD%"B@``G@``"4(`/$%`#(4!CP"`[H,4&-H:6QL!Q<+ -M.P`03Y`&`-D0`/`"`O<'(B!A>U8@(&_I%P'8"P#Q#S%G:6Y\*2!O9L\&(PH) -M$P(!6!X"IQL"K%@"S0(#CQL`+1D`3P4"2C0`+5<`#P@2>88`!G,&$%0$!@,S -M```5`0`X!!-Y\Q``6!(`0@0`QB4`NR(#Y@D8.I@"`FT(`#4((&5XU!8`0D4$ -M.``!YAXS,D="?R8S,51":`$"5CD-#`48,RX:`"T!!B@`$D,/"`(_!R5U;E@G -M`LP.`%T5`7-#`-H$``,#`+(``"H!$"*:`0#Z$P##'T!N;VYEC@L%9!T!?@00 -M;H`,#(O,V(#`7T``-@"`68(!M,#D$IA -M;B!00P`4,#`!`,`-D2`.L(,$=.55L! -M$"><*$%G+71AE`(&[UP`FP`U;W-E,@`!7QA`960@;2\B0'=A&%C=&QY -M"@EA*R``YA<@-$>T"`/@$@=H$0&=`0(;#@=G``!;`0!F``=#`E`H/CA'*>,` -M!3X"`-0``-P20V%S"@E&.`'M"T!)('!U\"\)C0(`(1`#)`$%&"\`3`$`P50! -MA``%+`<32=0(`=D+`-@'$&5_)P`!`U!N+6UA=&\%`!5=`-0^(6]R00R".R!) -M"@EH;W!(#9$@979E;G1U86P\)0'Q3``?`0`P"S)D92`G"@!#*`+."0#.50,5 -M/P)K#@R7!A@SEP8`J@`5,"X!($-O(QH0=9``!*T`!'8%`%P"`9@J$F7?``8U -M`!!.+4T!6%8`Y4``M`03+/<+`7`(,")(:>\*('DBM0$#3@`@+C$X"0'/#`"O -M`!0Q.0`#Y"$&7```F`<5>C0\`)<"D6EM;65D:6%T90T!`9`X,$5/1M$J`(P? -M,'1R><\/`?X5!<,4`!$.,')E9V$F`8D+`.(/`%T%`-(D`!4``,\;`6X2$'B2 -M%0):#P3+"P"=`R%O9H0``Z$"`&4(`+X[#Y$%!!@S:0<`*``#T!`0-]`C`54! -M$TU''"`N8205`4X'`!($$B#'(!,O`P@$:A)#"@EA8_P!(61O*`!1@,%1DL##`H`QP5` -M*"D*"4L'`=$2`+4,$FUJ5B5I;I(+`Y@``P8=#GX#!RD(`)@`!B@``:(X`88" -M`.D"`RL#4R`P+C,ZO#P&[A`165TG!`2 -M*;L``NL]`GX2`!L\`PP"`SPP#G8`!V$-4D%U9R`S+R02-^,R`+,R`)D#!+P& -M`BL>`(,+(W,L7&,`J@4D86[/6P2`!40*"2A!K1<991L1`*HE(2XI;``#310! -MF`1`860@9QD+\0$Q+C$W("TM<&]S:7@@+2US22<$D@<2+C<`!3@,$U*S&F!S -M=6ED+W.+.00R$03O"T`[(&ET'00%=@0@"@E/&D!RQ,2(M+6`%%"W0`0,R!@&^)0"]*!5RF!,1"ND`!H4& -M"5@$-C(N-L`#`$@!!B@``0D'"]4-!\`-`ED&`&T&,6%N:QL'`88+*`H)$B4# -MNP`%[`($0!X`20T"&P0!N@H$Z"LQ0U9361\`V$@G=6R=`0NT``?Y#@(I``_& -M#`,8,AL(`5$`!2@`!E,*"B8B$B=/)@"$"@1$(0&4`A%D*`4`H`($XQ,R8W)I -M6!A2\`!ZP'`8HD`?(] -M`/T+`'D("%H0`.````$/`(P#`&4H`/8=(!"PL!%C(Z$PHH -M```+`0[=!1`@D0,"3"(`!`P"EP-0>2!C;&\0#@"5*4%T8L<`2"Y`0`2%0*7#0#)-0"F'!=Y@A.!4VME;&5T86Q\ -M"P:,"`%=!P/L`08"!0OL`1HQ[`$&*`!01FQE`@$I`1%A -M(2`!RET":0(`)`%B/'-I9V@^VP`&204!<@(!=!D`]P0&.!P`A0-0,BXQ+CDW -M"A-TMPD":0`A"@EJ``!L`0\7$``#80`%NP803,0*'!`#*,#!U;&00!!!RY0('H0(Z.PH)4P`!F@D2 -M=\9.`,D+`%\#`WL"`NP#`I(!$&Y3,@#,:`!T`P6-#C%T;W7L`@!,!0""10-@ -M`14QX1$+_@`'-@DF"4P[%@"!``#L!`*Z(!!N9AT!*B$`"0$`=00`!`,`_D]$ -M97)I>&,`!:4'"V,`".4(`,0!`QHC#'8+)S%BZP8**```P@D&50`17PQ%`]9G -M"KT,`48=`!$:(6%L4$%E+@H)3F]TM@4!3@8$BP$"B0$`IQ8!-&T*<@`)NAP1 -M(LH&``\!47)EP1$&XN -M2!%N/2T`?AH$4@`%;@$,4@`6-,("`5(`!4L2!/P7(6%NPT4@8FS**0#[(!!A -MM0D!R@4`U1$`'``!"P<`_PX`;VP!NB\!)@`!#D@!3@D188(3!75$`>T70&]R -M(&>R4@`_#`!N$"1B96T+``L"`P,>`BXO`#4M`2PQ0&]T:"!:!P*Y!0J(`1%(#0<$1PT@W``%J!`=B!@!<`08I -M```K%`'M`0">`@!X`C%S("BB``!W!0#C`@)3"Q``#U!(`200"O0('_0`(E```^A)` -M:6YG+Z,#`%L-`7H``38*,7!A>-4`!>T#`+T6(G5NI0$@9616)`$V`0^Y"@,W -M,"XR8@<`*0`%*`!`($ET)T0*$71)'#)E8W3&`1!I%@"S<')E='1Y(&=O;V3] -M`0;U"1(R&201;^I#`=<:`+\F(&]F[`L480H``_T&``D#`(<. -M`/T(,$=E;M@``;P#$RAQ+3`A*2!0.P'+'0(6`0!$$0%"``'H'[)I0@A=""X3X1L -M8VAM;V0H*6L`!245!Q(#`74!!]83`6L`!2D`$47*,`8(`S-E`2!W:#(!`24``Q$(`4\` -M(6)Y00`!SAE1('1O;VRM!``W!@+F*`4N``*%!@';'#5M:7HL`08U"P=L``$L -M`0?9!0`L`0,'0@(U`@'0*`%?$0#Z!@'1*`&-!@9$``"<%@/T5P*A`"1F($8! -M05!%4DTW`001`&A/5TY%4BRD9")R96<0`3L`<71O(%-5240S`!!38`0`LQ@` -M=A<%F4X.B@H78AP,"B@`$4%F"`"J!05@"P"1!A$B!RX4(KL0$'/:!Q%A?P`" -M&S4&D78`YP,`)48Q("!"0Q\`L`0`APD0:;$$`O4``"U=P'D:"`@8=,5865R+6=R8?@T`4X/ -M,&9A8UX"%F&'$``C`03;%0VW'P$:`0`E&@",`@/E%0#R,@&)9P.,:0%`$`*T -M%0/&`P"C-`&B&`1G`0%'`"%A"P,-$011`"!D99X) -M$&*A!0$4-S%Y;W5#``1*&@():!(I5T``FP!A;W9E!Y<#`D<5`7(!`G(`46EN=F]L -MU`$$\P$!S08$!%4!40T`4P8`!@(`7&(1210=$V.*"0&"-!!X80L```(@;V;/ -M$>(@;W9E@J`:L&%2W(`0'8-0)T'@,^%0P2`3_`$`R+C`[Z0("PPD`9Q]!<')O=/P+`+,Y]0-I;F0@(VEF -M9&5F)W,@=6YT:6R@-P'#<0+U%@"S$3-Y=&@T"P%B`P"L`P&L`@)X``*['@:: -M``#8"0OK``>7%P#:!0*!`0`;&S!S92@`>5$@5&AE>9<)`$XL`HX.`.L"`&8/ -M`4L``#HJ%6;B'PIL`,!R96-U -M`0"S#"%S90($`BD#`$D($&``"I`2`M<",%"W8+`@5.`;%P!!H`$"W6(E!I9FEC"@QX#>5.` -M`AH/`Y@E$3;N"!`@ZVL!?2<0.P8`$6Q-*0#_!2!O;$\0$F@C*`+9``%'"@!? -M``&(`0#V!Q`GIQ81EQ`:\G4&QE('5P10<`8S0"/```=@@@;V[+ -M*T),1$52=@"B4U5-34%22453"OT0`JT%#V0#`!HQ(0$#(2,0-ED.")DE`%87 -M(&YD;P$2=-E#!8@/"98C,B!R96YP`,L``3<-``EE(&]R"!T"*!,`3@(%7`8@ -M9&5N$P&,+0">`0.3,1`V9R,`Y)`!L!`5X`!?P!$$FX)C%P;W*M!`MF2@"C -M95!T:6QL+3`'#%\U`&(``.4%#@X!&',C:0'8$WPM;VYL>2XI?`!@4F5O@K,:@!J$P&'!`&* -M&Q)S^!0']@0`ZP4"WPP"B#@#Q84.GL'`5(J`)(A`0%1`3\Y -M!/<&$BR^(`!Y`#=087CZ`0%>'`(6?Q$N_DT"`!L;-=H9`;X!`_8!!+41"4=/ -M`#X.!%T9`!\+!E\9`+L%`$83`K8$`A\2`',-!)0$"NE*`F0``N1*`*X``#P4 -M4&%S($DG'`-`="!Q=;@3`)-&`-A:`:P)`)@"`C8``T&``((!G&AE=7)I8@,!0@' -M`1P)5"X*3V-TZ@(2-5A7-$=.5U,`D#`/87`2L2"\`#`W`#`JT-*C4Z,0(#7P8!544`7@,!*0\0 -M95X)$7G=$0`]`@3N0S%S("@*"`(K'`(0"@8<``*>&$PQ34(I<0"@36%R8W5S -M($=E:7T'`%8<`!\'`6<1`.,-`;)Z`[PZ!KD#`'D``SP!\PYX(H``$%\0FMT;W!?>P#J&0`O``;'``&%"0*5``!]``".!`+*%0`. -M``$T```J+P.W"P-1#V(U.B!07`F`Z2UW86QK6``!J!\`E@4"DP("70`#X"L1-6!A`/U#`+@'!%4``3(``2%; -M$#N$(@"4``0/!0"*#`#2`11YHQ(0--(!(6YY*RH0+7<(`,4](6QE+P(!U!$` -M2#D!5@,!&U(#5@`@86PE#@`=`0'5'P/L%@$`&@4Q.P1S``0&.P2_``!]``.' -M!Q$TBBL`I2H%FW@#;X3Q!2P@2%`M55@L(%5N:7AW87)E+"!S:2D`TRH"+@$` -D?@$1<#T``I(!`'P$'P`!`/______;U````````````",W%#R -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_compat_lz4_B7BD.tar.lz4.uu b/thirdparty/libarchive/libarchive/test/test_compat_lz4_B7BD.tar.lz4.uu deleted file mode 100644 index ecbd42391..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_lz4_B7BD.tar.lz4.uu +++ /dev/null @@ -1,918 +0,0 @@ -begin 644 test_compat_lz4_B7BD.tar.lz4 -M!")-&&1PN>]0``!O>&9I;&4``0!+X3`P,#8T-"``,#`P-S8U"``B,#(0`"(R -M,`$`_P<@,3(S-3,U-3,U,3(@,#$R,#(S`"`PEP!+`@(`KW5S=&%R`#`P8W4' -M`0M2,!46%C="!S8`"A(&1E;6]N4$`(&EN^``(M@)A:6YF;W)M&@00 -M(+@&!+T"\`E.15=3("T@:&EG:&QI9VATP`"-E)ZT``R0$`),``$X`]0$N86TL(&%C;&]C86PN;30L -MX0!`92YA8_\```(`$BU4`"1T;Z@`#*($LBP@;VYL>2!N965D?``Q;6%I]@$C -M97)<`05P`"1I;F0`\@,N:"YI;@H)+2!T96UP;&%T97-G`!%B-`(!9@$39;4` -M<`H*1W5I9&6V`AA$5`8$T@$"=0`!MP&R'!L -M@P(#+P,`0@$"(0`$F@,#,P``B`0/-``+`"(`##4`+V%T-``,*&%T,P`&`0:` -M+C,@9VEV97/?!H!O=F5R=FEE=_,"`*``!+L%$&%Q!3!W:&^1`B,J(-D'A5]R -M96%D+C,L$```T04=91$`45]D:7-K%@`"?@<(/@`#'```F0`0=E\!`K<"865D -M(&-A;(D'$'/4!D%N8V5SK0(`DP``=0``%P(`^00!<0!8($%027.7`'-E;G1R -M>2XS30`"]P,2(FL#!:L``20`4"(@=71II`59(&-L87-$``'O!49N86QSG0!@ -M]!;!I;@IA(&YU;6)E`D09BP``;<&42H@1TY5 -M=0$"N@$F("@$"P`:`$%L;VYG4`9B;F%M97,L$```!0L3(!$``&,`4G-P87)S -M?`(AB,``!DT%``)"`$```I58W)E -M873/``%U!`\&`0("J@,#OP,"O`(/'P,8,")R9:`-46-T960B1P,"3P#$+"!W -M:&EC:"!W:6QLB@`!5@`%R@%A(&5X8V5P0`40"EL)`VD"42!T:&%T0PXQ:7)E -M40`!\P,!R@(@("A3"@$T!`"$`0,S!`#T`V`L(&5T8RGO"P+Z`P"I`@8B!`&& -M`0+:``_(`PIA(FYE=V,BFP,!,P`G0<280D!`BL`(2!B-PEQF4@'!L -M:6-I=&S9"4!V;VMEO!(!ZP`!?PH#SA$@("C2$"4@8?L*`*D`("!AZ0`!)Q`" -M+0`(S0`4;Y4(<"DL(&ET('=P`$$@9V5T&1,!70H`I`0W($EN;@`W+"!IG@`! -M40$#FP`B96[)`0P,1<#4`T6%T979E`!,@%1``:A`` -M"@$`/06#;B!I=',@(D#E`!(BO0012!F4X.``P1$2(A`0!:""`L -M(E`(H"P@8V%P86)I;&D2%`8#`07Q``+S#P&W!`CV!0&7`8`@:6YD:79I9&P. -M`&@%(6EEA`$`.A("0@`$K`4`-@$A=&^L#3!D8737```%#A8Z+@$"R`D`P@`2 -M8>P"`,D*`2L`,VEN("2!I;G9O:V4@ -M82!P87)T:6-U;&%R(&9E871U`<``$D!`/X&`"<`4"H@97AA20!`4$`(&EN^``(M@(B:6X#"``0""!F:34!`'P`\`LJ($Y%5U,@+2!H:6=H;&EG -M:'1S(&]F(')E8P8"5&-H86YGH`*P0T]064E.1R`M('<3!P"Y"&)C86X@9&^? -M`#-T:&DI`*!)3E-404Q,("T@T`'2(`")P=28)<2)C;6%K92(D`P"D"2EO;$T` -M`E8!!NL#`)0`07,@:6Y,`0]M`0$P87)E3@(29-H!-64*)[P`$R>M``,D!`"3 -M``!.`/4!+F%M+"!A8VQO8V%L+FTT+.$`0&4N86/_```"`!(M5``D=&^H```@ -M`0BB!+`L(&]N;'D@;F5E9,4($'G*!0'V`2-E%7W)E860N,RP0``#1!1UE$0!1 -M7V1I=&%R+C54 -M`0CQ!$%A8F]U4P4@"`"X!!,BO0(R+F@B -MJ0"`:&4*2R"```[!P$C"8!A=71O;6%T:?\"$'G!`C!E8W29`Q%D80T#'`(%>`D0 -M9BP``;<&42H@1TY5=0$"-0(F("@$"P`:`$%L;VYG4`9B;F%M97,L$```!0L3 -M(!$``&,`4G-P87)S?`(A`@@;W#+`\!A;"!2;V-KFEP,A8`!'P!32],6E<=`*)L>FUA+"!L>FEP$P,O>'HC```9-!0` -M"0@!```*56-R96%TSP`!+0D/!@$"`JH#`[\#`KP"#Q\#&#`B&-E<$`%`+D%!&D"`M<1 -M`$,.$&F6!2=A>,H"("`H%@4!-`0`A`$#,P0`]`-@+"!E=&,I[PL"^@,`J0(& -M(@0!FP$"V@`/E@,%`<@#82)N97=C(IL#`3,`)W-HL``!$@`/1@-C!`4$`EL! -M`8D`#UD#``H6`S-7:&4#`@"_"`/4`A)SY@5A?P(-F5A;;4%`A$+02X@(%1`%%-I4,`4&EN9&5PJ@`E;G0B`0!$#0'E -M%@!"!1)O;`T&L`M4(%=I:VE2#`,,$S!H;W=1#P*F!P!."`/:``N@%03\!`#S -M#@!0!@/-``%P`$!L=V%Y1@$`W0$J962*"`)'``_0%__@"?H#$&,W!@`%&,)A -M=&5V97(@8FQO8VO5"@#N!S`@:70(!D(@66]UYQ,!Q`U`8F%C:T`#,69R93T/ -M,'!A2X'<70@82!T:6U7`W%O2W,``"."5)U='!U=.\"`&`$H&]B:F5C="US='G@&4%P<')O -MR`,`^10"^@!0=&\@:&$Y%D!U;'1IPQ,$J0`"`00`N0A5(&]P96Z>`!0@]`\A -M=7-U!Q%I(0AC:71S(")`/``2(KT$$',3&P7J!`,<`'`@:71S96QF4P$`?000 -M+P(/8'1E;B!U7,N -M"@`!`/^)`#L7#Y\!30\`'@M1-S$Q-S4`'F$Q-3$U-3(`'B\U,0`>_U771F5B -M(#`Y+"`R,#$S.H<*D2`S+C$N,B!R93(3GF0*"DIA;B`R."D`(2=SJPM`=V5B -M!A(N3``N,3-,``%U`!LQ=0`/*0`&%S`I`&%$96,@,#=2 -M`$`R.B!)4AL!"`P("@4#T!0`[PP991H,`)T%`ML-`DX8`9`(A"`*3F]V(#$Q -M5``@062V&P:L(H-?7TU!0T]36!<-`(('.&EN(,01!-D/(G)EJ08`)P4`N`P2 -M:P@','-T;TL.`+@B?PI/8W0@,C!K``4`.08`A@82=J43`@,,`S8``[P!#Z$` -M`"MGF]P5`%64V5P(#*!``VH`0+.&7%T;R!S965KD`I&@'5 -M`@DX`P#*"C)I97-.``*:!&$Q.B!.97>:`PI(``0;`UES(%-&6`,%"S\`0$)U -M:6QK!0"Y`:)O;B!7:6YD;W=S(0$#YP4.2P$K,&%+`14P2P$P57!DN!5T`P, -M,RUS._@6"*$9`ADA$F_B'$!H87)D4P(E+W-;`E%B&0"5##!E;747&6D@8G)O:V5B`#`R+GAG!`!W$`&O)2%O -M9K(6<5541BTX(&AH`!)SF04%^P!`4F5F85D'`04/$%]R#B`H*7L:`"\-46-O -M;&QEB"$`XPT`2@\P;&4MJR(`W`<`YR@!EB(#+`$!D`P@;VPA`P,2)!!S'Q\@ -M=W(,`0-W`!(Q$`:!,3H@4W!L:71?#0(`!@`L`0&1!C!P87)N`@(>%P`T"`/` -M`@":`Q%L^24";`(!QP`5,30#`X(#`L\AE`=V]R:V(!9')E='5R;JP<`)`B`2$/$&;N`@%9`7%A -M8F]R="@I1``&-04`M0$`>0`WH2 -M`-@48F5N(&-O<)01``X#`1X2!,@)`4$``XD%$#`(`@&R)P!X`'8@36%C($]3 -MJ0(`/``'K@0!.@`#0@(D,#I0``?K``"J"0/]`A!S7@D"[@!4&D1%0*G!`/4!P`:`0"4 -M'0.-"@)C``:;``-=!`'?(080!00'`@0;`V!C(&-R>7#%!`+!#`&/``/[!B$P -M.CT=`0("`"P&`A`$`"8#`$<%`BH``@4-$C``"`/4`Q(Z+@=`+6=I9`8``"H$ -M02`M+74.`!!U#@`!!P4#,@X#P`%@4F5D+6)L8!8`_"(!E`<&_@$!&14@97)D -M`P,C`@!4!`#.`@!8*P%.``,)`P!*`F)I;FEM86RM``$3#7@@;&5G86-YM0#,O`G@5`,0# -M`#(=`I`%`W8(`[X!`+\'$F0K``"1(#EL9&5?"`!=&Q!LNP$`%0X!0"@A963+ -M`P80`55296QA>`,"`,(%('-T7P;09F%I;'5R97,[(&UIF7'`P`M`0!Q`0-7!`!_&"%O;88'#%$``8X%4&YT-C1?S`L%``>@ -M;V9F7W0L(&1E=@<`,&EN;P<`,'5I9`<``#\#$&<+``*<``7^!`08*`'"$#9! -M0TQ%"0)U`!4QN@024SD#!C48`20!!28#`$0!$C`B!P%J!``&$0)\)@.6`@<* -M"3$Q+G@-%P&,``:%`Q!2R`=%869I;PX)`54`!<,%$$'''0!6``?S(P4Q!2%L -M>2P/!/T"`EL`!;L!8$EN=&5G)``9"``+3 -M`P`I`Y!F=71I;65S*"DX+F)#>6=W:6YK$@9%`0>'`78R+CQA`;&5A:U0!"!X!`$@`$G,S``5<`0!D``FUA+WAZ6P,#X0(`9P`$%B`)`@@"0`0`GP43>?(. -M`$D`$4C()"`@9_X2`D4``-@)!$$`0$]P96Z4)7`B9WIS:6`@)[``6)`D!!9&1IR0HP86P@2@!`-P)M(B%S98$#!+`=!),-!'4'85=!4DX*"1PK06ES(&/Z,Q5OPP<` -MU1U0861A<'2;."!N91PC,V%R>;L!"=\`55-T=61I8`L`E@`/2@`!-`E!;!$#``@!`%HA -M`5\``_40`/,``.D#,$1E8E\!L4)U9R`C-3$V-34.`?$.`*8$`+$H4$AUA,`2P$41:L> -M!]$(`8(`)&]N*Q8!\0P"]PM`;F]W"?P#`9<2`78,$G11``85!@#0``.@"@8, -M#A!?*A4@>5\/!A!?;P8P*"D@6"X$[`\`00PQ+`H)2!R7!,@961S(`#/"P"])@!1,#`L"@E4 -M!`"`!P!:#0#B!@!A!0:^`P`\`R!T(",%"7$F`;L`!LHA(@H)?0`4<^@OQ6)E -M(&UU8V@@96%S:>8-`H\/*RX@HC,`311":&4*"3$8`5\1"$(G%',])P;1#P"# -M'`-Q`!(N_!`"MP80.$4$)&YY:Q8:+Z\#`HH6`+L!#_D#`@U)``J["0B[&0+W -M'`%*``1;`@+Y#!!CN@$@97)^)2ET;W89`$T&`'PT`@2US:7IE9`4/$G.*)3$@*A$) -MSAH`A@,/[A<"`!<-L2@I(&AAFEPEP2"_`0`P`"`@82D`*RDN -MM@#@2F]E0,A(&*Q'`&[ -M$P%-$P!7!B)A=$H`!9X'`<4(`AQ``-A"`FLK`)$I4F0@8G5GQ0(@.L%`&P"!/P>"K`3``XT -M`,T``$8$`3,8!B,&`;X<`681`$LA!O8?`FD#`#\.``D)$V'=0W,B4V-O='0B -MW!80(%0```L*!9X#$VV#/A!SU`8$-0"22V5E'!L;P$0`&T6$&5D#0)M`0)E -M+95V97)F;&]WPP$_@D$V@Y0"@EP2P!$'26$`&#.%%E(&)O9(L]``8-`8D! -M`#8!,#L*"6T&$FG,$@#0`2%O=:T-P')A;F=E(&)E:&%V:2U/`$0.`0L,!!0[ -M`9@)$7)R`0&K`0)],U$M3A+,&ER95<8!&@8,"-I9O4,!'@8 -M`H9`.`K@-`=0/$"V!+C%E8V^!!5)L;V=I8[$5`C0` -M$',T``!.%0)/(@'V%`!V`0$8``);20*;%P-]`@;4"`E3`D0T+C$T>AY`9#L@ -M:5P\`%)$`)@#`1X`&#,$0"()84H*`%,!`?`($&=+!1$O=B-@(&UI>'5PWRD& -MR!8"L0``P@D4:<0O(F0*[18`9P0"A"D!'@<2+L@?!N8.#*8`%3.F``*3&`7Y -M`@-V'0"=!A$L3`(`DP`2+)H`$"PL!`*>``$[`2!C8640$6*8"S%V97+;`P32 -M)P&-`".``#3"P"! -M`&`@8VQA`B4&1E=FEC5@$!RR$!32(` -MB0H`2!@3(G`#&2*)"``6$`(U!D!N97=CM@("<0@#I``6.^0#`O$1`%P"`6,$ -M"$T!`#4"`!`A('1H2PL!>P`"G!LE.#I(#0)E#@-J)P!(`@2;`PDD$1PL6PT` -M.QH'004P26=NR@@$[`I"('-I>ND,`$,-`B@K`#0.$F&[(@#8"P#^(14RC@`, -M7@(6,EX""BD``*@!(&)A4T$`58(`$D:,6=E=)H-`J4\`6(+!,U5`'$:`8X%13(N.2Z"`0(Z``!( -M`1)L5#$08A,9`=L+!^$/(B@MI0]`+7HI+*L#`"$/,0EO9JH-,')M85X2`)X? -M,F5S'!E-\4"%C'% -M`@HI`#!&:7BF00&U)0#H$P+X)`9A`0"G!`&Q"04]#P%J``(_*P]J``$,S!D" -M8006-X8(4#`N.2XPQ@<`@0<"SE,@=VFA%3-U?@=`70``Q`;$C>)!5!A(&-O=90<(V]FE@0'K28`Y04!?P`"J0\.IP`'\A4* -M*```6P``J0,!IP`!!0`17VD!$%_?!"%B>=DQ`D4!`@"&!P8T4@2$`E`M+61I0H&%`!U86-L -M+`H)=.T!_P!386UU;&D@4W5O;6EN96Z,``T'/@D!_``%C``&/P+`3&%P;R!, -M=6-H:6YIU04`>E4!20(`3AP!54D`!0X!T@D!FB0#2@4`DP$@;&17"0%5+@#Z -M&P1O!#!B=6?&!0$8``!``;!O9@H)(FQE;F=T:)X4D&5N9"(@9FQA9QX*!6$` -M$G,?!`96`0).``,"!!$@FP8!4@8!/@(`J08!+P0$-P`%\P,01J,!0"!C=71K -M`$!R96%L>0<`-```D0(`Z`42;AU(`0\!!38`"Q@(%C+:`@+$`0\I``46,2D` -M"E$`$4W_)@"X!D%S+"!R%Q@`E```P0*@9&]C+71O+6UA;C\.`WX'`'H!(`H) -M%``!NB0#.CL/]`4&!XD%"B@``G@``"4(`/$%`#(4!CP"`[H,4&-H:6QL!Q<+ -M.P`03Y`&`-D0`/`"`O<'(B!A>U8@(&_I%P'8"P#Q#S%G:6Y\*2!O9L\&(PH) -M$P(!6!X"IQL"K%@"S0(#CQL`+1D`3P4"2C0`+5<`#P@2>88`!G,&$%0$!@,S -M```5`0`X!!-Y\Q``6!(`0@0`QB4`NR(#Y@D8.I@"`FT(`#4((&5XU!8`0D4$ -M.``!YAXS,D="?R8S,51":`$"5CD-#`48,RX:`"T!!B@`$D,/"`(_!R5U;E@G -M`LP.`%T5`7-#`-H$``,#`+(``"H!$"*:`0#Z$P##'T!N;VYEC@L%9!T!?@00 -M;H`,#(O,V(#`7T``-@"`68(!M,#D$IA -M;B!00P`4,#`!`,`-D2`.L(,$=.55L! -M$"><*$%G+71AE`(&[UP`FP`U;W-E,@`!7QA`960@;2\B0'=A&%C=&QY -M"@EA*R``YA<@-$>T"`/@$@=H$0&=`0(;#@=G``!;`0!F``=#`E`H/CA'*>,` -M!3X"`-0``-P20V%S"@E&.`'M"T!)('!U\"\)C0(`(1`#)`$%&"\`3`$`P50! -MA``%+`<32=0(`=D+`-@'$&5_)P`!`U!N+6UA=&\%`!5=`-0^(6]R00R".R!) -M"@EH;W!(#9$@979E;G1U86P\)0'Q3``?`0`P"S)D92`G"@!#*`+."0#.50,5 -M/P)K#@R7!A@SEP8`J@`5,"X!($-O(QH0=9``!*T`!'8%`%P"`9@J$F7?``8U -M`!!.+4T!6%8`Y4``M`03+/<+`7`(,")(:>\*('DBM0$#3@`@+C$X"0'/#`"O -M`!0Q.0`#Y"$&7```F`<5>C0\`)<"D6EM;65D:6%T90T!`9`X,$5/1M$J`(P? -M,'1R><\/`?X5!<,4`!$.,')E9V$F`8D+`.(/`%T%`-(D`!4``,\;`6X2$'B2 -M%0):#P3+"P"=`R%O9H0``Z$"`&4(`+X[#Y$%!!@S:0<`*``#T!`0-]`C`54! -M$TU''"`N8205`4X'`!($$B#'(!,O`P@$:A)#"@EA8_P!(61O*`!1@,%1DL##`H`QP5` -M*"D*"4L'`=$2`+4,$FUJ5B5I;I(+`Y@``P8=#GX#!RD(`)@`!B@``:(X`88" -M`.D"`RL#4R`P+C,ZO#P&[A`165TG!`2 -M*;L``NL]`GX2`!L\`PP"`SPP#G8`!V$-4D%U9R`S+R02-^,R`+,R`)D#!+P& -M`BL>`(,+(W,L7&,`J@4D86[/6P2`!40*"2A!K1<991L1`*HE(2XI;``#310! -MF`1`860@9QD+\0$Q+C$W("TM<&]S:7@@+2US22<$D@<2+C<`!3@,$U*S&F!S -M=6ED+W.+.00R$03O"T`[(&ET'00%=@0@"@E/&D!RQ,2(M+6`%%"W0`0,R!@&^)0"]*!5RF!,1"ND`!H4& -M"5@$-C(N-L`#`$@!!B@``0D'"]4-!\`-`ED&`&T&,6%N:QL'`88+*`H)$B4# -MNP`%[`($0!X`20T"&P0!N@H$Z"LQ0U9361\`V$@G=6R=`0NT``?Y#@(I``_& -M#`,8,AL(`5$`!2@`!E,*"B8B$B=/)@"$"@1$(0&4`A%D*`4`H`($XQ,R8W)I -M6!A2\`!ZP'`8HD`?(] -M`/T+`'D("%H0`.````$/`(P#`&4H`/8=(!"PL!%C(Z$PHH -M```+`0[=!1`@D0,"3"(`!`P"EP-0>2!C;&\0#@"5*4%T8L<`2"Y`0`2%0*7#0#)-0"F'!=Y@A.!4VME;&5T86Q\ -M"P:,"`%=!P/L`08"!0OL`1HQ[`$&*`!01FQE`@$I`1%A -M(2`!RET":0(`)`%B/'-I9V@^VP`&204!<@(!=!D`]P0&.!P`A0-0,BXQ+CDW -M"A-TMPD":0`A"@EJ``!L`0\7$``#80`%NP803,0*'!`#*,#!U;&00!!!RY0('H0(Z.PH)4P`!F@D2 -M=\9.`,D+`%\#`WL"`NP#`I(!$&Y3,@#,:`!T`P6-#C%T;W7L`@!,!0""10-@ -M`14QX1$+_@`'-@DF"4P[%@"!``#L!`*Z(!!N9AT!*B$`"0$`=00`!`,`_D]$ -M97)I>&,`!:4'"V,`".4(`,0!`QHC#'8+)S%BZP8**```P@D&50`17PQ%`]9G -M"KT,`48=`!$:(6%L4$%E+@H)3F]TM@4!3@8$BP$"B0$`IQ8!-&T*<@`)NAP1 -M(LH&``\!47)EP1$&XN -M2!%N/2T`?AH$4@`%;@$,4@`6-,("`5(`!4L2!/P7(6%NPT4@8FS**0#[(!!A -MM0D!R@4`U1$`'``!"P<`_PX`;VP!NB\!)@`!#D@!3@D188(3!75$`>T70&]R -M(&>R4@`_#`!N$"1B96T+``L"`P,>`BXO`#4M`2PQ0&]T:"!:!P*Y!0J(`1%(#0<$1PT@W``%J!`=B!@!<`08I -M```K%`'M`0">`@!X`C%S("BB``!W!0#C`@)3"Q``#U!(`200"O0('_0`(E```^A)` -M:6YG+Z,#`%L-`7H``38*,7!A>-4`!>T#`+T6(G5NI0$@9616)`$V`0^Y"@,W -M,"XR8@<`*0`%*`!`($ET)T0*$71)'#)E8W3&`1!I%@"S<')E='1Y(&=O;V3] -M`0;U"1(R&201;^I#`=<:`+\F(&]F[`L480H``_T&``D#`(<. -M`/T(,$=E;M@``;P#$RAQ+3`A*2!0.P'+'0(6`0!$$0%"``'H'[)I0@A=""X3X1L -M8VAM;V0H*6L`!245!Q(#`74!!]83`6L`!2D`$47*,`8(`S-E`2!W:#(!`24``Q$(`4\` -M(6)Y00`!SAE1('1O;VRM!``W!@+F*`4N``*%!@';'#5M:7HL`08U"P=L``$L -M`0?9!0`L`0,'0@(U`@'0*`%?$0#Z!@'1*`&-!@9$``"<%@/T5P*A`"1F($8! -M05!%4DTW`001`&A/5TY%4BRD9")R96<0`3L`<71O(%-5240S`!!38`0`LQ@` -M=A<%F4X.B@H78AP,"B@`$4%F"`"J!05@"P"1!A$B!RX4(KL0$'/:!Q%A?P`" -M&S4&D78`YP,`)48Q("!"0Q\`L`0`APD0:;$$`O4``"U=P'D:"`@8=,5865R+6=R8?@T`4X/ -M,&9A8UX"%F&'$``C`03;%0VW'P$:`0`E&@",`@/E%0#R,@&)9P.,:0%`$`*T -M%0/&`P"C-`&B&`1G`0%'`"%A"P,-$011`"!D99X) -M$&*A!0$4-S%Y;W5#``1*&@():!(I5T``FP!A;W9E!Y<#`D<5`7(!`G(`46EN=F]L -MU`$$\P$!S08$!%4!40T`4P8`!@(`7&(1210=$V.*"0&"-!!X80L```(@;V;/ -M$>(@;W9E@J`:L&%2W(`0'8-0)T'@,^%0P2`3_`$`R+C`[Z0("PPD`9Q]!<')O=/P+`+,Y]0-I;F0@(VEF -M9&5F)W,@=6YT:6R@-P'#<0+U%@"S$3-Y=&@T"P%B`P"L`P&L`@)X``*['@:: -M``#8"0OK``>7%P#:!0*!`0`;&S!S92@`>5$@5&AE>9<)`$XL`HX.`.L"`&8/ -M`4L``#HJ%6;B'PIL`,!R96-U -M`0"S#"%S90($`BD#`$D($&``"I`2`M<",%"W8+`@5.`;%P!!H`$"W6(E!I9FEC"@QX#>5.` -M`AH/`Y@E$3;N"!`@ZVL!?2<0.P8`$6Q-*0#_!2!O;$\0$F@C*`+9``%'"@!? -M``&(`0#V!Q`GIQ81EQ`:\G4&QE('5P10<`8S0"/```=@@@;V[+ -M*T),1$52=@"B4U5-34%22453"OT0`JT%#V0#`!HQ(0$#(2,0-ED.")DE`%87 -M(&YD;P$2=-E#!8@/"98C,B!R96YP`,L``3<-``EE(&]R"!T"*!,`3@(%7`8@ -M9&5N$P&,+0">`0.3,1`V9R,`Y)`!L!`5X`!?P!$$FX)C%P;W*M!`MF2@"C -M95!T:6QL+3`'#%\U`&(``.4%#@X!&',C:0'8$WPM;VYL>2XI?`!@4F5O@K,:@!J$P&'!`&* -M&Q)S^!0']@0`ZP4"WPP"B#@#Q84.GL'`5(J`)(A`0%1`3\Y -M!/<&$BR^(`!Y`#=087CZ`0%>'`(6?Q$N_DT"`!L;-=H9`;X!`_8!!+41"4=/ -M`#X.!%T9`!\+!E\9`+L%`$83`K8$`A\2`',-!)0$"NE*`F0``N1*`*X``#P4 -M4&%S($DG'`-`="!Q=;@3`)-&`-A:`:P)`)@"`C8``T&``((!G&AE=7)I8@,!0@' -M`1P)5"X*3V-TZ@(2-5A7-$=.5U,`D#`/87`2L2"\`#`W`#`JT-*C4Z,0(#7P8!544`7@,!*0\0 -M95X)$7G=$0`]`@3N0S%S("@*"`(K'`(0"@8<``*>&$PQ34(I<0"@36%R8W5S -M($=E:7T'`%8<`!\'`6<1`.,-`;)Z`[PZ!KD#`'D``SP!\PYX(H``$%\0FMT;W!?>P#J&0`O``;'``&%"0*5``!]``".!`+*%0`. -M``$T```J+P.W"P-1#V(U.B!07`F`Z2UW86QK6``!J!\`E@4"DP("70`#X"L1-6!A`/U#`+@'!%4``3(``2%; -M$#N$(@"4``0/!0"*#`#2`11YHQ(0--(!(6YY*RH0+7<(`,4](6QE+P(!U!$` -M2#D!5@,!&U(#5@`@86PE#@`=`0'5'P/L%@$`&@4Q.P1S``0&.P2_``!]``.' -M!Q$TBBL`I2H%FW@#;X3Q!2P@2%`M55@L(%5N:7AW87)E+"!S:2D`TRH"+@$` -D?@$1<#T``I(!`'P$'P`!`/______;U````````````",W%#R -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_compat_lzip.c b/thirdparty/libarchive/libarchive/test/test_compat_lzip.c deleted file mode 100644 index 8f4e06d3a..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_lzip.c +++ /dev/null @@ -1,141 +0,0 @@ -/*- - * Copyright (c) 2010 Michihiro NAKAJIMA - * Copyright (c) 2003-2008 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* -Execute the following to rebuild the data for this program: - tail -n +33 test_compat_lzip.c | /bin/sh - -# Use lzip command. -zcmd=lzip -zsuffix=lz -ztar_suffix=tlz -mktarfile() -{ -mkdir $dir -echo "f1" > $dir/f1 -echo "f2" > $dir/f2 -echo "f3" > $dir/f3 -mkdir $dir/d1 -echo "f1" > $dir/d1/f1 -echo "f2" > $dir/d1/f2 -echo "f3" > $dir/d1/f3 -(cd $dir; tar cf ../$name.tar f1 f2 f3 d1/f1 d1/f2 d1/f3) -rm -r $dir -} -# -# Make a lzip file from splitted tar file. -# -name=test_compat_lzip_1 -dir="$name`date +%Y%m%d%H%M%S`.$USER" -mktarfile -split -b 3600 $name.tar $name.tar. -rm $name.tar -$zcmd $name.tar.* -cat $name.tar.*.$zsuffix > $name.$ztar_suffix -rm $name.tar.*.$zsuffix -uuencode $name.$ztar_suffix $name.$ztar_suffix > $name.$ztar_suffix.uu -rm -f $name.$ztar_suffix -# -# Make a lzip file with junk data at the end of the file. -# -name=test_compat_lzip_2 -dir="$name`date +%Y%m%d%H%M%S`.$USER" -mktarfile -$zcmd $name.tar -mv $name.tar.$zsuffix $name.$ztar_suffix -echo "This is unrelated junk data at the end of the file" >> $name.$ztar_suffix -uuencode $name.$ztar_suffix $name.$ztar_suffix > $name.$ztar_suffix.uu -rm -f $name.$ztar_suffix - -exit 0 -*/ - -/* - * Verify our ability to read sample files compatibly with lzip. - * - * In particular: - * * lzip will read multiple lzip streams, concatenating the output - * * lzip will stop at the end of a stream if the following data - * doesn't start with a gzip signature. - * - */ - -/* - * All of the sample files have the same contents; they're just - * compressed in different ways. - */ -static void -compat_lzip(const char *name) -{ - const char *n[7] = { "f1", "f2", "f3", "d1/f1", "d1/f2", "d1/f3", NULL }; - struct archive_entry *ae; - struct archive *a; - int i, r; - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - r = archive_read_support_filter_lzip(a); - if (r == ARCHIVE_WARN) { - skipping("lzip reading not fully supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - extract_reference_file(name); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 2)); - - /* Read entries, match up names with list above. */ - for (i = 0; i < 6; ++i) { - failure("Could not read file %d (%s) from %s", i, n[i], name); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_next_header(a, &ae)); - assertEqualString(n[i], archive_entry_pathname(ae)); - } - - /* Verify the end-of-archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify that the format detection worked. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_LZIP); - assertEqualString(archive_filter_name(a, 0), "lzip"); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - -DEFINE_TEST(test_compat_lzip) -{ - /* This sample has been 'split', each piece compressed separately, - * then concatenated. lzip will emit the concatenated result. */ - compat_lzip("test_compat_lzip_1.tlz"); - /* This sample has been compressed as a single stream, but then - * some unrelated garbage text has been appended to the end. */ - compat_lzip("test_compat_lzip_2.tlz"); -} diff --git a/thirdparty/libarchive/libarchive/test/test_compat_lzip_1.tlz.uu b/thirdparty/libarchive/libarchive/test/test_compat_lzip_1.tlz.uu deleted file mode 100644 index 01e5e3bfa..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_lzip_1.tlz.uu +++ /dev/null @@ -1,10 +0,0 @@ -begin 644 test_compat_lzip_1.tlz -M3%I)4`$,`#,,/!NGC#0&C6L"2_R2/O9*^":#5/GP,U"QL$1\Q:(3S>V*OTP* -M1&9J-1:S\^>DEIOT;'&#"`B6#7ZO7%">,>LZ=:BU,Z7*^>M<3FV:GKO_?W;` -M,N31CE_$<-$(3$J*AB5TTG2\;X[CSPOI6IIPV8\]86+J37::!/_LA^/@O"(1 -MAA`.````````F`````````!,6DE0`0P``&_]_BC86HZ6L8?*M6SC8*JJ7,GS -M0IZA9CQ/^VS2N26K[BXKGC_1Z&JR]S2)5Q",)*$1RS"):7X:?OBQDJXU`>8K -M\2*:_6!:)ZD5FBGJ?II6>-V*OTP* -M1&9J-1:S\^>DEIOT;'&#"`B6#7ZO7%">,>LZ=:BU,Z7*^>M<3FV:GKO_?W;` -M,N31CE_$<-$(3$J*AB5TTG2\;X[CSPOI6IIPV8\]9>BP>V?/L._78%+F2N-; -M6V[`1"7)=_,5LD9U%73FQV-?_X5OKW0_.'N"`!P```````"R`````````%1H -M:7,@:7,@=6YR96QA=&5D(&IU;FL@9&%T82!A="!T:&4@96YD(&]F('1H92!F -$:6QE"@`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_compat_lzma.c b/thirdparty/libarchive/libarchive/test/test_compat_lzma.c deleted file mode 100644 index 7e6e3a89f..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_lzma.c +++ /dev/null @@ -1,155 +0,0 @@ -/*- - * Copyright (c) 2009 Michihiro NAKAJIMA - * Copyright (c) 2003-2008 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_compat_lzma.c 201247 2009-12-30 05:59:21Z kientzle $"); - -/* -Execute the following to rebuild the data for this program: - tail -n +33 test_compat_lzma.c | /bin/sh - -# Use lzma command of XZ Utils. -name=test_compat_lzma_1 -zcmd=lzma -zsuffix=lzma -ztar_suffix=tlz -dir="$name`date +%Y%m%d%H%M%S`.$USER" -mktarfile() -{ -mkdir $dir -echo "f1" > $dir/f1 -echo "f2" > $dir/f2 -echo "f3" > $dir/f3 -mkdir $dir/d1 -echo "f1" > $dir/d1/f1 -echo "f2" > $dir/d1/f2 -echo "f3" > $dir/d1/f3 -(cd $dir; tar cf ../$name.tar f1 f2 f3 d1/f1 d1/f2 d1/f3) -rm -r $dir -} -mktarfile -$zcmd $name.tar -mv $name.tar.$zsuffix $name.$ztar_suffix -echo "This is unrelated junk data at the end of the file" >> $name.$ztar_suffix -uuencode $name.$ztar_suffix $name.$ztar_suffix > $name.$ztar_suffix.uu -rm -f $name.$ztar_suffix -# -# Use option -e -# -name=test_compat_lzma_2 -dir="$name`date +%Y%m%d%H%M%S`.$USER" -mktarfile -$zcmd -e $name.tar -mv $name.tar.$zsuffix $name.$ztar_suffix -uuencode $name.$ztar_suffix $name.$ztar_suffix > $name.$ztar_suffix.uu -rm -f $name.$ztar_suffix -# -# Use lzma command of LZMA SDK with option -d12. -# -name=test_compat_lzma_3 -zcmd=lzmasdk # Change this path to use lzma of LZMA SDK. -dir="$name`date +%Y%m%d%H%M%S`.$USER" -mktarfile -$zcmd e -d12 $name.tar $name.$ztar_suffix -rm -f $name.tar -uuencode $name.$ztar_suffix $name.$ztar_suffix > $name.$ztar_suffix.uu -rm -f $name.$ztar_suffix - -exit 0 -*/ - -/* - * Verify our ability to read sample files compatibly with unlzma. - * - * In particular: - * * unlzma will read multiple lzma streams, concatenating the output - * * unlzma will read lzma streams which is made by lzma with option -e, - * concatenating the output - * - * Verify our ability to read sample files compatibly with lzma of - * LZMA SDK. - * * lzma will read lzma streams which is made by lzma with option -d12, - * concatenating the output - */ - -/* - * All of the sample files have the same contents; they're just - * compressed in different ways. - */ -static void -compat_lzma(const char *name) -{ - const char *n[7] = { "f1", "f2", "f3", "d1/f1", "d1/f2", "d1/f3", NULL }; - struct archive_entry *ae; - struct archive *a; - int i, r; - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - r = archive_read_support_filter_lzma(a); - if (r == ARCHIVE_WARN) { - skipping("lzma reading not fully supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - extract_reference_file(name); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 2)); - - /* Read entries, match up names with list above. */ - for (i = 0; i < 6; ++i) { - failure("Could not read file %d (%s) from %s", i, n[i], name); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_next_header(a, &ae)); - assertEqualString(n[i], archive_entry_pathname(ae)); - } - - /* Verify the end-of-archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify that the format detection worked. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_LZMA); - assertEqualString(archive_filter_name(a, 0), "lzma"); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - -DEFINE_TEST(test_compat_lzma) -{ - /* This sample has been added junk data to its tail. */ - compat_lzma("test_compat_lzma_1.tlz"); - /* This sample has been made by lzma with option -e, - * the first byte of which is 0x5e. - * Not supported in libarchive 2.7.* and earlier */ - compat_lzma("test_compat_lzma_2.tlz"); - /* This sample has been made by lzma of LZMA SDK with - * option -d12, second byte and third byte of which is - * not zero. - * Not supported in libarchive 2.7.* and earlier */ - compat_lzma("test_compat_lzma_3.tlz"); -} diff --git a/thirdparty/libarchive/libarchive/test/test_compat_lzma_1.tlz.uu b/thirdparty/libarchive/libarchive/test/test_compat_lzma_1.tlz.uu deleted file mode 100644 index 57fa501f0..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_lzma_1.tlz.uu +++ /dev/null @@ -1,10 +0,0 @@ -$FreeBSD: head/lib/libarchive/test/test_compat_lzma_1.tlz.uu 201247 2009-12-30 05:59:21Z kientzle $ - -begin 644 test_compat_lzma_1.tlz -M70``@`#__________P`S##P;IXPT!HUK`DO\DC[V2OB%Z^'=ZT59ANYMTD(/ -M^W;\8!%O7<+P&=#(9W<_!$Z.7/Y<&\(8+E0^,_-\Z"D^P'N0J^4-UH"WMJ<& -MV-P6=Y[-FY$IFNZ="RF24TO.B7EP[F]BGMJSP[]OZ_P9/#J'T=;7E&&A@J<[ -MA^C'Q*/Y&I)2^T930'MJTK-98U0D9R*-X2^5__6H:+A4:&ES(&ES('5N`W2"/3R1F1:P:&Q9A -MGH2JJI9$C?8.=WTE:O<1WA@X>DK-Y#SW;I2!P;NYG^2"-(D9/E(D_0XK_H,\ -95*/V"T#E9ZO][@'R,6E&^A([.##_\M#YU@`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_compat_lzma_3.tlz.uu b/thirdparty/libarchive/libarchive/test/test_compat_lzma_3.tlz.uu deleted file mode 100644 index bee82897b..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_lzma_3.tlz.uu +++ /dev/null @@ -1,9 +0,0 @@ -$FreeBSD: head/lib/libarchive/test/test_compat_lzma_3.tlz.uu 201247 2009-12-30 05:59:21Z kientzle $ - -begin 644 test_compat_lzma_3.tlz -M70`0````'``````````S##P;IXPT!HUK`DO\DC[V2OB%Z^'=ZT59ANYMTD(1 -M$Y^=;\4%U_CXKQ*F$OFZKEQUG)1U8="](V<2K"U1\Z6%H(UNQ[Y3.=D'>_G- -MCO71X+M*7WH7$D1&E9Y$XHW,(`[X";GGTO+,'&1?F%<@`.$-OV;8P1?*M$A" -:MA+1XONREMK,1('455L=X1>WC#1YW"('I@`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_compat_lzop.c b/thirdparty/libarchive/libarchive/test/test_compat_lzop.c deleted file mode 100644 index cd43afcf3..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_lzop.c +++ /dev/null @@ -1,131 +0,0 @@ -/*- - * Copyright (c) 2003-2008 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* - * Verify our ability to read sample files compatibly with lzop. - * - * In particular: - * * lzop will stop at the end of a stream if the following data - * doesn't start with a lzop signature. - * - */ - -DEFINE_TEST(test_compat_lzop) -{ - const char *sample1 = "test_compat_lzop_1.tar.lzo"; - const char *sample2 = "test_compat_lzop_2.tar.lzo"; - const char *sample3 = "test_compat_lzop_3.tar.lzo"; - struct archive_entry *ae; - struct archive *a; - int r; - - /* - * Test1: tar ball compressed in one block. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - r = archive_read_support_filter_lzop(a); - if (r == ARCHIVE_WARN) { - skipping("lzop reading not fully supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - extract_reference_file(sample1); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, sample1, 2)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("INSTALL", archive_entry_pathname(ae)); - - /* Verify the end-of-archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify that the format detection worked. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_LZOP); - assertEqualString(archive_filter_name(a, 0), "lzop"); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Test2: tar ball compressed in multi blocks. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - extract_reference_file(sample2); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, sample2, 2)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("file1", archive_entry_pathname(ae)); - assertEqualInt(19, archive_entry_size(ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("file2", archive_entry_pathname(ae)); - assertEqualInt(262144, archive_entry_size(ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("file3", archive_entry_pathname(ae)); - assertEqualInt(19, archive_entry_size(ae)); - - /* Verify the end-of-archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify that the format detection worked. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_LZOP); - assertEqualString(archive_filter_name(a, 0), "lzop"); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Test3: tar ball compressed in one block with junk data. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - extract_reference_file(sample3); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, sample3, 2)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("INSTALL", archive_entry_pathname(ae)); - - /* Verify the end-of-archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify that the format detection worked. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_LZOP); - assertEqualString(archive_filter_name(a, 0), "lzop"); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_compat_lzop_1.tar.lzo.uu b/thirdparty/libarchive/libarchive/test/test_compat_lzop_1.tar.lzo.uu deleted file mode 100644 index 9eeca6a6c..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_lzop_1.tar.lzo.uu +++ /dev/null @@ -1,30 +0,0 @@ -begin 664 test_compat_lzop_1.tar.lzo -MB4Q:3P`-"AH*$#`@8`E``04#```!``"!M%"`FEX`````%G1E2`H82?@"@-F'4"+"!T;PJL!`-W:71H(%AH -M;6!T!$UA8R!/4RQT%@$@8V%N)X`&+',,86YDO#.4(0(@+4<@(H0(`2(@?B\H -M;`D`#2UD;W=N;&]A9"UD:7(O"E1H92!R97-U;'0@=VEL;"!P=01P<')O<')I -M8"A\(I0F`BP@?!\#('1O;VPND!`!9&5F8780;VXP.Q$@:7-L -M*<0K`V4@36%K98P.=!)U(@IW(F%L2`H82?@"@-F'4"+"!T;PJL!`-W:71H(%AH -M;6!T!$UA8R!/4RQT%@$@8V%N)X`&+',,86YDO#.4(0(@+4<@(H0(`2(@?B\H -M;`D`#2UD;W=N;&]A9"UD:7(O"E1H92!R97-U;'0@=VEL;"!P=01P<')O<')I -M8"A\(I0F`BP@?!\#('1O;VPND!`!9&5F8780;VXP.Q$@:7-L -M*<0K`V4@36%K98P.=!)U(@IW(F%L-'C]V%*E1 -MQ@T;(4EJ]!@CQHT8,P"`8(*QILV;.'-*K#.'3A@Y($``D//F#1V=%.^@*5.& -M#=*G4*-*G4JU*M0P8L:0*6/F#)HT:M:P:>/F#9PXH5 -MK%BR9M&J9>L6KMRM7;^&'5OV;%HZ:]N^C9L5<-W!>`WO5>RW,5W!=POK1A"*Q))+X\E$TX(<3C3?3T$-5=1152G%E%,=IJCBBC89Y]QJO2WGHFJ\$>>9 -M9;H)EUQKOS5'XW#*%8?C<3#:V"-HNP')(W-(ZLB:;P)]048:NK90(-,'6DIX(?U`7!??OOU9^BCD$8:40$6'`"```TU$<88(#PQ!0A8!"6J -MJ)BV0*ZY+:"K+KM&B%0###J$048;"NF``[YAL,'&&W?H<(<<:4RK@*0,-^PP -M?`6^0)!!""G$T,-/-:BQA1)F^-U*,+1T0\@:8DP;HB$29915)C9E\LLP1P3F -M7.81C*9(\U%SUSDF7!-*<<+,4==AI%P-WWGV79PSBD?>2GQZEMQZ>[E%-%+*)2[E,N6D\@R[T -MZTO'GCK2'`GJ.-DUQ!GRV71*2`.>>KK=IWIQJU?##83R;I/EB^Z=N_?D/TRI -MI:UJRJFGH(XZ:JD-G=I0J@"LVE"K`.AJ6ZRSUIJ)+[D*5J]^)&=P@NNP%L'WUZU_Y$AC! -M#(8PA97OA3!\BN`.5#$%>6]CBL/A1R;D/+4];V1TVU`,=](3$`E%9=::2LM0 -M-,0F1L5W29.=ZHPGNN*AKHJG"QWQLC@\L''1=5[4FFEN-SXGFO&,L8'BZJ0( -MNRMN48Q@--UPDH>]\;RI;'*"7MI4LK:V\4D&=90;#;@'@D*A$0#@TUNC^G;( -M1OZG0%*B4A/%YB8XF0UMB[M3'_?T)AF`K#O<&50A'9E(1O'-D:B,S_G@I[Y. -M?2I4[@L1_N0'`/K9#W[Y@Y6L:.4!39`A@+L:8$V`%4P#%NM8R5I6L\KPK&A- -MJUH.B2"T)OBM-X1K7!Z4EP;IU4%X:5.$]?K(O?)E0C?X"V`J+-C!$E:&A:7R -MG9US&M3,2$D[6C*/F'S<)MU&GD^BYVPR><\A2RD^1L+SH%6!)!D-6CXZ+N^. -MS;MD]$BBR>IU!P8V:!Q+8""=CHRRD01=)$)'6I55IF]3KFQ?+(4R2U0YY);X -MTU]M^,=+-7P"F``0%@"(A1%BYE28"$SF`IG9P&=",%O3[%8UKWG!;W+S@B"< -M%P9)2$Y^F1.%`1N8.EO83I)Z-6H+/:-#*XG'Y^7S8_N\:$8=UYT9V``E'QUH -M$1,5/I%^]:YXS:M>]\K7OOKUKX`-K&`'2]C"&O:PB$VL8A?+V,8Z]K&0C:QD -M)TO9REKVLIC-K&8WR]G.>O:SH`VM:$=+VM*:]K2H3:UJ5\O:UKKVM;"-K6QG -$2UM(`0`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_compat_mac-2.tar.Z.uu b/thirdparty/libarchive/libarchive/test/test_compat_mac-2.tar.Z.uu deleted file mode 100644 index 09761b973..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_mac-2.tar.Z.uu +++ /dev/null @@ -1,19 +0,0 @@ -begin 644 test_compat_mac-2.tar.Z -M'YV0+EX`&$BPH,&#"!,J7,BPH4.$,"+>J%$#!("(,&[8J'@1HPP:%C&*%`DB -M1@R*-&[0J`$CQ@T0+4W:@`$`1(V'.'/JW,D30)TY=,+(Z4@G39N>"H&&,6,& -MZ<&1,$*.M.BTJM6K6+/V#.CB2YL\9-(,U4JV+$&,$SFBW2@UXL>V(VG$F%'R -M9(V4*UN^;/EQ94V:9@,+)O@SZ-"(18]J5=/&Q1LXR\F4D3/'19@O9L0")1@@`$$#`RTL;_X\^O3J8K[,*;/< -M#9F'RID[A_Y&.G478[Z4:0.'3A[NF@U4'``4C#>?>?>1\04;86P'0';4T;%> -M>V0PZ*!E&&:HX88412!U!A5%=**G$DDLPQ2## -M###04---)/:84&%"$64468PUA=5C+;[HXY),6L655WEDQT8936:(D0TTL+B6 -MBFYIZ:)<=)D48UXT\C73#']5R220A\&0&)%!-7;D5$E&IN:=>"Z$F6:R>0:: -M:*2AAIIJ`[$VD&L#P;:;;[55=EMNN_G!J'$##??0@``$-Q!R`,1''GWV57<= -MA!=V]UUX!I97WWDNI#?A&^[!ERJHK.:W7W__^18@``,6*)^JH;J@H(5T#$2J -MA.S!6F&#Q>;I[+/0[N1AE&E,&:U@5V:)(EM)OE7G8V+>):->-=Y8@PUI7HLA -MFT(JEE61CM&)I+KTUFOOO?CFJ^^^_/;K[[\`!RSPP`07;/#!"">L\,(,-^SP -MPQ!'+/'$%%=L\<489ZSQQAQW[/''((,$``` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_compat_mac.c b/thirdparty/libarchive/libarchive/test/test_compat_mac.c deleted file mode 100644 index 5caa17f83..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_mac.c +++ /dev/null @@ -1,214 +0,0 @@ -/*- - * Copyright (c) 2003-2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* The sample has some files in a directory with a very long name. */ -#define TESTPATH "abcdefghijklmnopqrstuvwxyz/" \ - "abcdefghijklmnopqrstuvwxyz/" \ - "abcdefghijklmnopqrstuvwxyz/" \ - "abcdefghijklmnopqrstuvwxyz/" \ - "abcdefghijklmnopqrstuvwxyz/" \ - "abcdefghijklmnopqrstuvwxyz/" \ - "abcdefghijklmnopqrstuvwxyz/" - -static void test_compat_mac_1(void); -static void test_compat_mac_2(void); - -/* - * Apple shipped an extended version of GNU tar with Mac OS X 10.5 - * and earlier. - */ -static void -test_compat_mac_1(void) -{ - char name[] = "test_compat_mac-1.tar.Z"; - struct archive_entry *ae; - struct archive *a; - const void *attr; - size_t attrSize; - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_set_options(a, "mac-ext")); - extract_reference_file(name); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(TESTPATH, archive_entry_pathname(ae)); - assertEqualInt(1275688109, archive_entry_mtime(ae)); - assertEqualInt(95594, archive_entry_uid(ae)); - assertEqualString("kientzle", archive_entry_uname(ae)); - assertEqualInt(5000, archive_entry_gid(ae)); - assertEqualString("", archive_entry_gname(ae)); - assertEqualInt(040755, archive_entry_mode(ae)); - - attr = archive_entry_mac_metadata(ae, &attrSize); - assert(attr == NULL); - assertEqualInt(0, attrSize); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(TESTPATH "dir/", archive_entry_pathname(ae)); - assertEqualInt(1275687611, archive_entry_mtime(ae)); - assertEqualInt(95594, archive_entry_uid(ae)); - assertEqualString("kientzle", archive_entry_uname(ae)); - assertEqualInt(5000, archive_entry_gid(ae)); - assertEqualString("", archive_entry_gname(ae)); - assertEqualInt(040755, archive_entry_mode(ae)); - - attr = archive_entry_mac_metadata(ae, &attrSize); - assert(attr != NULL); - assertEqualInt(225, attrSize); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(TESTPATH "file", archive_entry_pathname(ae)); - assertEqualInt(1275687588, archive_entry_mtime(ae)); - assertEqualInt(95594, archive_entry_uid(ae)); - assertEqualString("kientzle", archive_entry_uname(ae)); - assertEqualInt(5000, archive_entry_gid(ae)); - assertEqualString("", archive_entry_gname(ae)); - assertEqualInt(0100644, archive_entry_mode(ae)); - - attr = archive_entry_mac_metadata(ae, &attrSize); - assert(attr != NULL); - assertEqualInt(225, attrSize); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("dir/", archive_entry_pathname(ae)); - assertEqualInt(1275688064, archive_entry_mtime(ae)); - assertEqualInt(95594, archive_entry_uid(ae)); - assertEqualString("kientzle", archive_entry_uname(ae)); - assertEqualInt(5000, archive_entry_gid(ae)); - assertEqualString("", archive_entry_gname(ae)); - assertEqualInt(040755, archive_entry_mode(ae)); - - attr = archive_entry_mac_metadata(ae, &attrSize); - assert(attr != NULL); - assertEqualInt(225, attrSize); - assertEqualMem("\x00\x05\x16\x07\x00\x02\x00\x00Mac OS X", attr, 16); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("file", archive_entry_pathname(ae)); - assertEqualInt(1275625860, archive_entry_mtime(ae)); - assertEqualInt(95594, archive_entry_uid(ae)); - assertEqualString("kientzle", archive_entry_uname(ae)); - assertEqualInt(5000, archive_entry_gid(ae)); - assertEqualString("", archive_entry_gname(ae)); - assertEqualInt(0100644, archive_entry_mode(ae)); - - attr = archive_entry_mac_metadata(ae, &attrSize); - assert(attr != NULL); - assertEqualInt(225, attrSize); - assertEqualMem("\x00\x05\x16\x07\x00\x02\x00\x00Mac OS X", attr, 16); - - /* Verify the end-of-archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify that the format detection worked. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_GNUTAR); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* - * Apple shipped a customized version of bsdtar starting with MacOS 10.6. - */ -static void -test_compat_mac_2(void) -{ - char name[] = "test_compat_mac-2.tar.Z"; - struct archive_entry *ae; - struct archive *a; - const void *attr; - size_t attrSize; - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_set_options(a, "mac-ext")); - extract_reference_file(name); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("./", archive_entry_pathname(ae)); - assertEqualInt(1303628303, archive_entry_mtime(ae)); - assertEqualInt(501, archive_entry_uid(ae)); - assertEqualString("tim", archive_entry_uname(ae)); - assertEqualInt(20, archive_entry_gid(ae)); - assertEqualString("staff", archive_entry_gname(ae)); - assertEqualInt(040755, archive_entry_mode(ae)); - - attr = archive_entry_mac_metadata(ae, &attrSize); - assert(attr == NULL); - assertEqualInt(0, attrSize); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("./mydir/", archive_entry_pathname(ae)); - assertEqualInt(1303628303, archive_entry_mtime(ae)); - assertEqualInt(501, archive_entry_uid(ae)); - assertEqualString("tim", archive_entry_uname(ae)); - assertEqualInt(20, archive_entry_gid(ae)); - assertEqualString("staff", archive_entry_gname(ae)); - assertEqualInt(040755, archive_entry_mode(ae)); - - attr = archive_entry_mac_metadata(ae, &attrSize); - assert(attr != NULL); - assertEqualInt(267, attrSize); - assertEqualMem("\x00\x05\x16\x07\x00\x02\x00\x00Mac OS X", attr, 16); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("./myfile", archive_entry_pathname(ae)); - assertEqualInt(1303628303, archive_entry_mtime(ae)); - assertEqualInt(501, archive_entry_uid(ae)); - assertEqualString("tim", archive_entry_uname(ae)); - assertEqualInt(20, archive_entry_gid(ae)); - assertEqualString("staff", archive_entry_gname(ae)); - assertEqualInt(0100644, archive_entry_mode(ae)); - - attr = archive_entry_mac_metadata(ae, &attrSize); - assert(attr != NULL); - assertEqualInt(267, attrSize); - assertEqualMem("\x00\x05\x16\x07\x00\x02\x00\x00Mac OS X", attr, 16); - - /* Verify the end-of-archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify that the format detection worked. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_compat_mac) -{ - test_compat_mac_1(); - test_compat_mac_2(); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_compat_perl_archive_tar.c b/thirdparty/libarchive/libarchive/test/test_compat_perl_archive_tar.c deleted file mode 100644 index 165a519a3..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_perl_archive_tar.c +++ /dev/null @@ -1,66 +0,0 @@ -/*- - * Copyright (c) 2016 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD"); - -/* - * Verify our ability to read sample files created by Perl module Archive::Tar - */ - -DEFINE_TEST(test_compat_perl_archive_tar) -{ - char name[] = "test_compat_perl_archive_tar.tar"; - struct archive_entry *ae; - struct archive *a; - int r; - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - extract_reference_file(name); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, - 10240)); - - /* Read first entry. */ - assertEqualIntA(a, ARCHIVE_OK, r = archive_read_next_header(a, &ae)); - if (r != ARCHIVE_OK) { - archive_read_free(a); - return; - } - assertEqualString("file1", archive_entry_pathname(ae)); - assertEqualInt(1480603099, archive_entry_mtime(ae)); - assertEqualInt(1000, archive_entry_uid(ae)); - assertEqualString("john", archive_entry_uname(ae)); - assertEqualInt(1000, archive_entry_gid(ae)); - assertEqualString("john", archive_entry_gname(ae)); - assertEqualInt(0100644, archive_entry_mode(ae)); - - /* Verify that the format detection worked. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_NONE); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_compat_perl_archive_tar.tar.uu b/thirdparty/libarchive/libarchive/test/test_compat_perl_archive_tar.tar.uu deleted file mode 100644 index ca7bc2a97..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_perl_archive_tar.tar.uu +++ /dev/null @@ -1,49 +0,0 @@ -begin 644 test_compat_perl_archive_tar.tar -M9FEL93$````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````#`P,#8T-```,#`Q-S4P```P,#$W-3```"`@("`@("`@("`U -M`#$S,#(P,#,R-S,S`"`Q,3$R,P`@,``````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````!U= 0 && offset + bytes_read <= 131072) || - (offset >= 393216 && offset + bytes_read <= 393216+131072) || - (offset >= 786432 && offset + bytes_read <= 786432+32775)); - if (offset == 0 && bytes_read >= 1024*8) { - memset(data, 'a', sizeof(data)); - failure("First data block should be 8K bytes of 'a'"); - assertEqualMem(buff, data, sizeof(data)); - } else if (offset + bytes_read == 819207 && bytes_read >= 7) { - const char *last = buff; - last += bytes_read - 7; - memset(data, 'c', 7); - failure("Last seven bytes should be all 'c'"); - assertEqualMem(last, data, 7); - } - } - - /* Verify the end-of-archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify that the format detection worked. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* - * Verify our ability to read sample files created by Solaris pax for - * a sparse file which begin with hole. - */ -static void -test_compat_solaris_pax_sparse_2(void) -{ - char name[] = "test_compat_solaris_pax_sparse_2.pax.Z"; - struct archive_entry *ae; - struct archive *a; - int64_t offset, length; - const void *buff; - size_t bytes_read; - int r; - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - extract_reference_file(name); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240)); - - /* Read first entry. */ - assertEqualIntA(a, ARCHIVE_OK, r = archive_read_next_header(a, &ae)); - if (r != ARCHIVE_OK) { - archive_read_free(a); - return; - } - assertEqualString("hole", archive_entry_pathname(ae)); - assertEqualInt(1310416789, archive_entry_mtime(ae)); - assertEqualInt(101, archive_entry_uid(ae)); - assertEqualString("cue", archive_entry_uname(ae)); - assertEqualInt(10, archive_entry_gid(ae)); - assertEqualString("staff", archive_entry_gname(ae)); - assertEqualInt(0100644, archive_entry_mode(ae)); - - /* Verify the sparse information. */ - failure("This sparse file should have two data blocks"); - assertEqualInt(2, archive_entry_sparse_reset(ae)); - assertEqualInt(ARCHIVE_OK, - archive_entry_sparse_next(ae, &offset, &length)); - assertEqualInt(393216, offset); - assertEqualInt(131072, length); - assertEqualInt(ARCHIVE_OK, - archive_entry_sparse_next(ae, &offset, &length)); - assertEqualInt(786432, offset); - assertEqualInt(32799, length); - while (ARCHIVE_OK == - archive_read_data_block(a, &buff, &bytes_read, &offset)) { - failure("The data blocks should not include the hole"); - assert((offset >= 393216 && offset + bytes_read <= 393216+131072) || - (offset >= 786432 && offset + bytes_read <= 786432+32799)); - if (offset + bytes_read == 819231 && bytes_read >= 31) { - char data[32]; - const char *last = buff; - last += bytes_read - 31; - memset(data, 'c', 31); - failure("Last 31 bytes should be all 'c'"); - assertEqualMem(last, data, 31); - } - } - - /* Verify the end-of-archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify that the format detection worked. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - -DEFINE_TEST(test_compat_solaris_pax_sparse) -{ - test_compat_solaris_pax_sparse_1(); - test_compat_solaris_pax_sparse_2(); -} - - diff --git a/thirdparty/libarchive/libarchive/test/test_compat_solaris_pax_sparse_1.pax.Z.uu b/thirdparty/libarchive/libarchive/test/test_compat_solaris_pax_sparse_1.pax.Z.uu deleted file mode 100644 index 8ab27deb6..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_solaris_pax_sparse_1.pax.Z.uu +++ /dev/null @@ -1,53 +0,0 @@ -begin 644 test_compat_solaris_pax_sparse_1.pax.Z -M'YV0+EY`"8,'29DP9,K(F>,BAL,<+]"\85,&@,6+&#-JW,BQH\>/(&&(A&&# -M!@T`(V'$H%$#9P(^F+'GR -M)H4JDBIO\U>S7JVZ_6NVM.KSQVF -MO?OW\./+GT^_OOW[^//KW\^_O___``8HX(`$%FC@@0@FJ.""##;HX(,01BCA -MA!16:.&%&&:HX88<=NCAAR"&*.*())9HXHDHIJCBBBRVZ.*+,,8HXXPTUFCC -MC3CFJ...//;HXX]`!BGDD$06:>212":IY)),-NGDDU!&*>645%9IY9589JGE -MEEQVZ>678(8IYIADEFGFF6BFJ>:*Z[7IYIMPQBGGG'36:>>=>.:IYYY\]NGG -MGX`&*NB@A!9JZ*&()JKHHHPVZNBCD$8JZ:245FKII9AFJNFFG';JZ:>@ABKJ -MJ*26:NJIJ*:JZJJLMNKJJ[#&*NNLM-9JZZVXYJKKKKSVZNNOP`8K[+#$%FOL -ML<@FJ^RRS#;K[+/01BOMM-16:^VUV&:K[;;<=NOMM^"&*^ZXY)9K[KGHIJON -MNNRVZ^Z[\,8K[[STUFOOO?CFJ^^^_/;K[[\`!RSPP`07;/#!"">L\,(,-^SP -MPQ!'+/'$%%=L\<489ZSQQAQW[/''((L\\X\]^SSST`'+?301!=M]-%()ZWTTDPW[?334$M]MILM^WVVW#'+??<=-=M]]UXYZWW -MWGSW[???@`N^>:<=^[Y -MYZ"'+OKHI)=N^NFHIZ[ZZJRW[OKKL,O_/+,-^_\\]!'+_WTU%=O_?789Z_]]MQW[_WWX(BGK_[Z[+?O_OOPQR___/37;__]^.>O__[\]^___P`,H``'2,`"&O"`"$R@ -M`A?(P`8Z\($0C*`$)TC!"EKP@AC,H`8WR,$.>O"#(`RA"$=(PA*:\(0H3*$* -M5\C"%KKPA3",H0QG2,,:VO"&.,RA#G?(PQ[Z\(=`#*(0ATC$(AKQB$A,HA*7 -MR,0F.O&)4(RB%*=(Q2I:\8I8S*(6M\C%+GKQBV`,HQC'2,8RFO&,:$RC&M?( -MQC:Z\8UPC*,O.;X`RG.,=)SG*:\YSH3*^,RG/O?)SW[Z\Y\`#:A`!TK0@AKTH`A-J$(7RM"&.O2A -M$(VH1"=*T8I:]*(8S:A&-\K1CGKTHR`-J4A'2M*2FO2D*$VI2E?*TI:Z]*4P -MC:E,9TK3FMKTICC-J4YWRM.>^O2G0`VJ4(=*U*(:]:A(3:I2E\K4ICKUJ5"- -MJE2G2M6J6O6J6,VJ5K?*U:YZ]:M@#:M8QTK6LIKUK&A-JUK7RM:VNO6M<(VK -M7.=*U[K:]:YXS:M>]\K7OOKUKX`-K&`'2]C"&O:PB$VL8A?+V,8Z]K&0C:QD -M)TO9REKVLIC-K&8WR]G.>O:SH`VM:$=+VM*:]K2H3:UJ5\O:UKKVM;"-K6QG -M2]O:VO:VN,VM;G?+V][Z-I%B"*YPATOYT(VN=*=+ -MW>I:][K8S:YVM\O=[GKWN^`-KWC'2][RFO>\Z$VO>M?+WO:Z][WPC:]\YTO? -M^MKWOOC-KW[WR]_^^O>_``ZP@`=,X`(;^,`(3K""%\S@!COXP1".L(0G3.$* -M6_C"&,ZPAC?,X0Y[^,,@#K&(1TSB$IOXQ"A.L8I7S.(6N_C%,(ZQC&=,XQK; -M^,8XSK&.=\SC'OOXO[\-LI"'3.0B&_G(2$ZRDI?,Y"8[^_G+8`ZSF,=,YC*;^,ZSGO?,YS[[^<^`#K2@!TWH0AOZT(A.M*(7S>A&._K1D(ZTI"=-Z4I;^M*8 -MSK2F-\WI3GOZTZ`.M:A'3>I2F_K4J$ZUJE?-ZE:[^M6PCK6L9TWK6MOZUKC. -MM:YWS>M>^_K7P`ZVL(=-[&(;^]C(3K:RE\WL9CO[V=".MK2G3>UJ6_O:V,ZV -MMK?-[6Y[^]O@#K>XQTWNYVN_O=\(ZWO.=-[WK;^][XSK>^ -M]\WO?OO[WP`/N,`'3O""&_S@"$^XPA?.\(8[_.$0C[C$)T[QBEO\XAC/N,8W -MSO&.>_SC(`^YR$=.\I*;_.0H3[G*5\[REKO\Y3"/NI8S[K6M\[U -MKGO]ZV`/N]C'3O:RF_WL:$^[VM?.]K:[_>UPC[O^ -M^_WO@`^\X`=/^,(;_O"(3[SB%\_XQCO^\9"/O.0G3_G*6_[RF,^\YC?/^I7S_K6N_[UL(\]Z<=`^]J/0?9$`P`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_compat_solaris_pax_sparse_2.pax.Z.uu b/thirdparty/libarchive/libarchive/test/test_compat_solaris_pax_sparse_2.pax.Z.uu deleted file mode 100644 index 5df385f77..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_solaris_pax_sparse_2.pax.Z.uu +++ /dev/null @@ -1,53 +0,0 @@ -begin 644 test_compat_solaris_pax_sparse_2.pax.Z -M'YV0+EY`"8,'29DP9,K(F>/B1@P;+]"\85,&@,6+&#-JW,BQH\>/(`'`&`G# -M!@T:(DG&H%$CI4H9+DF.C"$#!H`8#TO:J''#AHR6,T_>L(DGI-&C2),JW5AG -M#ITPG8$U>!H$C1@X9O7L&/+GDV[MNV+BZO>WAU2IDF4,E<"#0Y3 -MYER2,V[212":IY)),-NGDDU!&*>645%9IY9589JGE -MEEQVZ>678(8IYIADEFGFF6BFJ>::;+;IYIMPQBGGG'36:>>=>.:IYYY\]NGG -MGX`&*NB@A!9JZ*&()JKHHHPVZNBCD$8JZ:245FKII9AFJNFFG';JZ:>@ABKJ -MJ*26:NJIJ*:JZJJLMNKJJ[#&*NNLM-9JZZVXYJKKKKSVZNNOP`8K[+#$%FOL -ML<@FJ^RRS#;K[+/01BOMM-16:^VUV&:K[;;<=NOMM^"&*^ZXY)9K[KGHIJON -MNNRVZ^Z[\,8K[[STUFOOO?CFJ^^^_/;K[[\`!RSPP`07;/#!"">L\,(,-^SP -MPQ!'+/'$%%=L\<489ZSQQAQW[/''((L\\X\]^SSST`'+?301!=M]-%()ZWTTDPW[?334$M]MILM^WVVW#'+??<=-=M]]UXYZWW -MWGSW[???@`N^>:<=^[Y -MYZ"'+OKHI)=N^NFHIZ[ZZJRW[OKKL,O_/+,-^_\\]!'+_WTU%=O_?789Z_]]MQW[_WWX(BGK_[Z[+?O_OOPQR___/37;__]^.>O__[\]^___P`,H``'2,`"&O"`"$R@ -M`A?(P`8Z\($0C*`$)TC!"EKP@AC,H`8WR,$.>O"#(`RA"$=(PA*:\(0H3*$* -M5\C"%KKPA3",H0QG2,,:VO"&.,RA#G?(PQ[Z\(=`#*(0ATC$(AKQB$A,HA*7 -MR,0F.O&)4(RB%*=(Q2I:\8I8S*(6M\C%+GKQBV`,HQC'2,8RFO&,:$RC&M?( -MQC:Z\8UPC*,O.;X`RG.,=)SG*:\YSH3*^,RG/O?)SW[Z\Y\`#:A`!TK0@AKTH`A-J$(7RM"&.O2A -M$(VH1"=*T8I:]*(8S:A&-\K1CGKTHR`-J4A'2M*2FO2D*$VI2E?*TI:Z]*4P -MC:E,9TK3FMKTICC-J4YWRM.>^O2G0`VJ4(=JRC`8]:A(3:I2E\K4ICKUJ5"- -MJE2G2M6J6O6J6,VJ5K?*U:YZ]:M@#:M8QTK6LIKUK&A-JUK7RM:VNO6M<(VK -M7.=*U[K:]:YXS:M>]\K7OOKUKX`-K&`'2]C"&O:PB$VL8A?+V,8Z]K&0C:QD -M)TO9REKVLIC-K&8WR]G.>O:SH`VM:$=+VM*:]K2H3:UJ5\O:UKKVM;"-K6QG -M2]O:VO:VN,VM;G?+V][Z]K?`#:YPATM8HAKWN,A-KG*7R]SF6D0,T(VN=*=+ -MW>I:][K8S:YVM\O=[GKWN^`-KWC'2][RFO>\Z$VO>M?+WO:Z][WPC:]\YTO? -M^MKWOOC-KW[WR]_^^O>_``ZP@`=,X`(;^,`(3K""%\S@!COXP1".L(0G3.$* -M6_C"&,ZPAC?,X0Y[^,,@#K&(1TSB$IOXQ"A.L8I7S.(6N_C%,(ZQC&=,XQK; -M^,8XSK&.=\SC'OOXQT`.LI"'3.0B&_G(2$ZRDI?,Y"8[V+E0CK*4ITSE*EOY -MREC.LI:WS.4N>_G+8`ZSF,=,YC*;^,ZSGO?,YS[[^<^`#K2@!TWH0AOZT(A.M*(7S>A&._K1D(ZTI"=-Z4I;^M*8 -MSK2F-\WI3GOZTZ`.M:A'3>I2F_K4J$ZUJE?-ZE:[^M6PCK6L9TWK6MOZUKC. -MM:YWS>M>^_K7P`ZVL(=-[&(;^]C(3K:RE\WL9CO[V=".MK2G3>UJ6_O:V,ZV -MMK?-[6Y[^]O@#K>XQTWNYVN_O=\(ZWO.=-[WK;^][XSK>^ -M]\WO?OO[WP`/N,`'3O""&_S@"$^XPA?.\(8[_.$0C[C$)T[QBEO\XAC/N,8W -MSO&.>_SC(`^YR$=.\I*;_.0H3[G*5\[REKO\Y3"/NI8S[K6M\[U -MKGO]ZV`/N]C'3O:RF_WL:$^[VM?.]K:[_>UPC[O^ -M^_WO@`^\X`=/^,(;_O"(3[SB%\_XQCO^\9"/O.0G3_G*6_[RF,^\YC?/^I7S_K6NY[I8XB][&=/^]K;7O:O1Q4` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_compat_solaris_tar_acl.c b/thirdparty/libarchive/libarchive/test/test_compat_solaris_tar_acl.c deleted file mode 100644 index 815977290..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_solaris_tar_acl.c +++ /dev/null @@ -1,267 +0,0 @@ -/*- - * Copyright (c) 2003-2009 Tim Kientzle - * Copyright (c) 2016 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* - * Verify reading entries with POSIX.1e and NFSv4 ACLs from archives created - * with Solaris tar. - * - * This should work on all systems, regardless of whether local filesystems - * support ACLs or not. - */ - -static struct archive_test_acl_t acls0[] = { - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_WRITE | - ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE, - ARCHIVE_ENTRY_ACL_USER, 71, "lp" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_USER, 666, "666" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_USER, 1000, "1000" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_MASK, -1, ""}, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_OTHER, -1, "" }, -}; - -static struct archive_test_acl_t acls1[] = { - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_USER, 2, "bin" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_GROUP, 3, "sys" }, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_MASK, -1, ""}, - { ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0, - ARCHIVE_ENTRY_ACL_OTHER, -1, "" }, -}; - -static struct archive_test_acl_t acls2[] = { - { ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_USER_OBJ, -1 ,"" }, - { ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_USER, 2, "bin" }, - { ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_GROUP, 3, "sys" }, - { ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ, - ARCHIVE_ENTRY_ACL_MASK, -1, ""}, - { ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0, - ARCHIVE_ENTRY_ACL_OTHER, -1, "" }, -}; - -static struct archive_test_acl_t acls3[] = { - { ARCHIVE_ENTRY_ACL_TYPE_DENY, - ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_WRITE_DATA | - ARCHIVE_ENTRY_ACL_APPEND_DATA | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_WRITE_ACL | - ARCHIVE_ENTRY_ACL_WRITE_OWNER | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_GROUP, 12, "daemon" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_WRITE_DATA | - ARCHIVE_ENTRY_ACL_APPEND_DATA | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_GROUP, 2, "bin" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_USER, 4, "adm" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_WRITE_DATA | - ARCHIVE_ENTRY_ACL_APPEND_DATA | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_WRITE_ACL | - ARCHIVE_ENTRY_ACL_WRITE_OWNER | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" }, -}; - -static struct archive_test_acl_t acls4[] = { - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_WRITE_DATA | - ARCHIVE_ENTRY_ACL_APPEND_DATA | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_WRITE_ACL | - ARCHIVE_ENTRY_ACL_WRITE_OWNER | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE | - ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT | - ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT | - ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, - ARCHIVE_ENTRY_ACL_USER, 1100, "1100" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE | - ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT | - ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, - ARCHIVE_ENTRY_ACL_GROUP, 4, "adm" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_WRITE_DATA | - ARCHIVE_ENTRY_ACL_APPEND_DATA | - ARCHIVE_ENTRY_ACL_DELETE_CHILD | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_WRITE_ACL | - ARCHIVE_ENTRY_ACL_WRITE_OWNER | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_EXECUTE | - ARCHIVE_ENTRY_ACL_READ_DATA | - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" }, - { ARCHIVE_ENTRY_ACL_TYPE_ALLOW, - ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES | - ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | - ARCHIVE_ENTRY_ACL_READ_ACL | - ARCHIVE_ENTRY_ACL_SYNCHRONIZE, - ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" }, -}; - -DEFINE_TEST(test_compat_solaris_tar_acl) -{ - char name[] = "test_compat_solaris_tar_acl.tar"; - struct archive *a; - struct archive_entry *ae; - - /* Read archive file */ - assert(NULL != (a = archive_read_new())); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - extract_reference_file(name); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, - 10240)); - - /* First item has access ACLs */ - assertA(0 == archive_read_next_header(a, &ae)); - failure("One extended ACL should flag all ACLs to be returned."); - assertEqualInt(7, archive_entry_acl_reset(ae, - ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); - assertEntryCompareAcls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]), - ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0644); - failure("Basic ACLs should set mode to 0644, not %04o", - archive_entry_mode(ae)&0777); - assert((archive_entry_mode(ae) & 0777) == 0644); - - /* Second item has default and access ACLs */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualInt(6, archive_entry_acl_reset(ae, - ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); - assertEntryCompareAcls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]), - ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0750); - failure("Basic ACLs should set mode to 0750, not %04o", - archive_entry_mode(ae)&0777); - assert((archive_entry_mode(ae) & 0777) == 0750); - assertEqualInt(6, archive_entry_acl_reset(ae, - ARCHIVE_ENTRY_ACL_TYPE_DEFAULT)); - assertEntryCompareAcls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]), - ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0750); - - /* Third item has NFS4 ACLs */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualInt(6, archive_entry_acl_reset(ae, - ARCHIVE_ENTRY_ACL_TYPE_NFS4)); - assertEntryCompareAcls(ae, acls3, sizeof(acls3)/sizeof(acls3[0]), - ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0); - - /* Fourth item has NFS4 ACLs and inheritance flags */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_acl_reset(ae, - ARCHIVE_ENTRY_ACL_TYPE_NFS4)); - assertEntryCompareAcls(ae, acls4, sizeof(acls4)/sizeof(acls0[4]), - ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0); - - /* Close the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_compat_solaris_tar_acl.tar.uu b/thirdparty/libarchive/libarchive/test/test_compat_solaris_tar_acl.tar.uu deleted file mode 100644 index 028dd61a4..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_solaris_tar_acl.tar.uu +++ /dev/null @@ -1,163 +0,0 @@ -begin 644 test_compat_solaris_tar_acl.tar -M9FEL92UW:71H+7!O#HW,2QU"UA8VQS -M P -M,# P-C0T # P,#$W-3 ,# P,# P, P,# P,# P,# P, Q,3$W-#8P-#$U -M-P P,#$T,#

    "QU"QO=&AE"QD969A=6QT=7-E' M+2TM+2TM+2US.BTM+2TM+2TZ86QL;W' M+6%!4E=C0V]S.BTM+2TM+2TZ9&5N>3HQ,BQG -M6]N94 Z+2TM+2TM82U2+6,M+7,Z -M+2TM+2TM+3IA;&QO=P 4 -M -M "HUP@( -, ,S P,# P-0!U' M1&%!4E=C -M0V]S.BTM+2TM+2TZ86QL;W"TM+6$M4BUC+2US.BTM+2TM -M+2TZ86QL;W"TM+2TM+2TM+2TM.BTM+2TM+2TZ9&5N>3HW."QG3HW."QU'`M+6%!4E=C0V]S.BTM+2TM+2TZ86QL;W'`M+6%!4E=C -M+2US.BTM+2TM+2TZ86QL;W"TM+6$M4BUC+2US.BTM -M+2TM+2TZ86QL;W<*```````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````````!D:7(Q+P`````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M,#`P,#"QU -M"QU"QM87-K.CIR+7@L;W1H97(Z.BUW+0H` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````````!D:7(Q+P`````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M,#`P,#$T,B`P,#`P,#`P(#`P,#`P,#`@,#`P,#`P,#`P,#`@,3,P,3(S,34T -M-S8@,#`Q-#8R-B`U```````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````````````'5S=&%R`#`P&UC9"TS+C,N,B]D;V-S7V0O4D5!1$UF```````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````"`@(#0T-"``("`S-#'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX -M>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX -M>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX -M>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX -M>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX -M>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX -M>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'AX -M>'AX>'AX>'AX>'AX>'AX>'AX>'AX>'@````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````````````````````````````'AM8V0M,RXS+C(O -M4D5!1$U%```````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````@ -M("`T-#0@`"`@,S0W,R``("`@("`S(``@("`@("`@(#4P,2`Q,#`T,34T-30S -M-2`@,3(R,#<`(#%X;6-D+3,N,RXR+V1O8W-?9"]214%$368````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -&```````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_compat_uudecode.c b/thirdparty/libarchive/libarchive/test/test_compat_uudecode.c deleted file mode 100644 index cfb17c857..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_uudecode.c +++ /dev/null @@ -1,63 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -static char archive_data[] = { -"begin 644 test_read_uu.Z\n" -"M'YV0+@`('$BPH,&#\"!,J7,BP(4(8$&_4J`$\"`,08$F%4O)AQ(\\2/(#7&@#%C\n" -"M!@T8-##.L`$\"QL@:-F(``%'#H/1A2\n" -"IHU\"0%9=*G4JUJM6K6+-JWO8,.*'4NVK-FS:-.J7O0Z44"4*D21$09M[(`<$FC1BD8]"DL5,& -MA)@Z;L@,=*%`012F1M.\<3/G!P@02>;,`?Q#P6$0*D"@H4,'CHX7+^YH=M'V -MK9RX<\NX4'L&1)HY(.B@J8OF39NZ:=<./O,FC9LSCA^S=0M7+ET09,K09?,& -MSFLW=%B8=C.&31TRMDN3>;/T^%$Z@MTH#Y,W]^.V;M:@IO,F]>K=GD'_;A-& -M8/3=1N?P?1R92GDY9>"HI0."NVG%3"E75%VJU77:8@3*$<88:Y2Q5AAT>'?8 -M9)5=]L(8;P3G`FUOG+$7AFV\`,<+G?46V@L'`D;B:1'2!X)]("PF1AMI\.=? -M&6Z@P=T895B76GDE?N9;&%6 -M'=@-9A=>>AG(G'/!C7=>6E.^<<=[(.KG!HYTF.E=9$&J5X8._:&GH!QYH*56 -ME66$`=UM_>4%PAU^8H=JGZ72B*J<9=SIXE%R<%H@"">(,0<9N)X`I1P=*MC& -M?YV:46<+9I1*1QWXD<%KL!+J=AA^1B[8(Z6#"L2?H)D.>2D(8\`AF*[G]?IK -MN8()"P>Q9QB+[)/02>4@M[;1X:`9VOY8K;6U)HGX8T"(;EWJDE$Q'>["*^]IG-2>7JK2+Q35N&7@D7+*9($SAFI+L30D"T$(/-&RQ"2L*(0AYO%$' -M".R%&I"J`RK+AIB0+1TTR0/-\8*L-2+%Z9.1+L@?PF37%5P;@_4)X7L#@O"& -M&>C1"G9D&"+GIQB<@F`%4H(599J^;:`F,'_D85V7&`;+)8>T<""%7:T[O/Q8 -MR4C6%?A1#9M75QB`MB8':H^JEFJH5];JL'QXGD<>'"T,-!QP:>#7L%JACMX> -M8::+VNBCJ-H6&WL.HR50K3J,ZT015TP!0@N2I7$&&FUM7ZG>?/O.;5SD@ASHT+#NV.DQDQ$(6L\!/-2`+R$`H-IB`G`%:=<%>X#P(K03>;PYC\!,< -M=):DNOPO@`,4U5J"4#5 -M'_R`8$#2HISI%'""$6H/A,)"H0KI$#T7Z;!!8'1!PK;3'.I`S`5MH(%R[/A! -M_`AR#"_#'AQ_Y$0HZHEW??J3PY0S&#:$:E)E"$X<0\6>?`W/01$,VQ_+$$C; -M++*#VG,!&EQ@&P4D`'N,RY:^4#-).3(2A#%*81I6V)>X/!BE1WV,C*^`A107Q$!LV3)@\?*VM^)M$U=/BU?"'*/-=9GK -M#=X$)\K$N2MR\FU7VV17>=X%M3:PTR[K@E`\@19.XM4S2>`S9T#YPT]U^C-L -MX0J-"V8``C31!37^>0-=Y*"E,MPAH;OJS*="A:1.W:$U&PP;K;Z`'U--=#M" -M"LT76%4CT&E._/.2EM*AIZ>YJ<4Y:>6DDG#]DB37!`# -M3VF2%#OFA/&(NR*J4%5%4WV!(`A02,P_5THI4$T4.&6HH9V*)X(^.=!&,:7+ -M%\J:AR8"RCT2(Q?*%#/6N/(T7PYZF)W.JE1DAG$.1X.F]B:SG,A%E"XG2"5@ -MY2#8&#'PK<#DCK2*XR`3S@=3O/$KL]3"//E\9#K5H92B8/,\&98V1G6`@W[D -MH*]IAM0M(_VG/EU0`^6T@8%E$$UO=Y::;GZDL$Q-JU-#N9SE/3,,8K`:Y%:3 -M)._H)THH>Y!?70NA.2C'-LUYSGMT=+D6D(=9MI%64VW8G^@"RCMT"PYER?5. -MXJ+3#HCC3J7XDJ>ZL,<-=8`8E,)@/HQ&]S=(J0MRF6N;XIT`M<)*8QE^Q\9: -M/@G`;1"#@Q):KV;A!SGB=B@.1=5#38!'X -M#0U-U.P<$0LM'I$K0UMI,-C10#0:J5>&MDX(L"A@"M#]/!D\JYK1A&VA]`N>9N -M%2L86O75,(RJBJBK-5X7WY.6TO8Q;$=P0A6*NQ;G\@<%X$74>Q*]:.*@"HP/ -M>XUWV3*;W80'!)FNU794-8?,K8ZU94M!;B)CM.R"+`=BTU=>F(M.1X,`TH<2 -M+ZJ",`0FS$'5$@3!$YYHN!LPNHV:BF!DH/"$*20!"V^$BAQ6#0)F.QO:F<-# -M8QU$OML$F7G4MO:S]=:PM+9`+6F@%'/U2>TI6$$*&`G"%(:0A"305S#A;O:X -MJ:,O.IS;3^J6%KN#+03;("5X]46!&+37`AQ!)Z-KB=B;R]#PO&S)#<`.6Q*F -M\(0W%69'P%*@SAK\1`;SA1D$2F!9NOD# -M-%F+K&X9CXP6D@`%9`\)-2A@.<-<\ZZ`,7=4(@B.&5"FKR9&"C^*86Y9T_UK -M:E.:N$*8`A%XA11AT4K9O/HM?LH@+$=3^P8MT,(PC1X:M#<+-A8<#_D[*:"_GCIX?^Q4'AI. -M^'LZUE%>RL;E;M1ZZ6>O7L8N1.J$R_*"XZBM"D -MU5VU5VWZ!FU%@2OY=FT#IFV3U6TVYW;!)@)8QT!X5UM-E&TAIAPGA7?[\RA* -MDT+.4A<'B!25)S8\LD(R)"%;%T:J,356MXOB%VSD9WYL08OJ!P+L)XS8IP!.\`:[I&6` -M4CSRQT8FPF?/@A_1\T]Y`C(@\R2K$09:XDF6U5)M\(0!%R/6Q#A.]B*KX48@ -M@V6\HT;>L1BRM1](9ALMD"T^%E]I$!`;DQTWIR!YX1K],08\HAAJ%C:85XVA -M`C*)HCV3`D7E(8HS.&O2PG)8V'[.)RB:)53;Y6CR<1B8UTFA\H*]LRT@!C(M -M.%W?-C4:YAU$!5U.,RI=19.G@U'E&"OV)3]+LR#[0RM+(SBA$I./D5[YX7"4 -MTH[]Y48)UD;8T1QA)"AR)I17D`9KD`;R-#S1X1VM\5&1?QURH0Q[,@W=1E0<+&1E)<`((1AD]LD*T -M5AYH0R-ZH"37@7>>M@90PD5W-1CMF`1\0S_XXP8GT"3RA'HN1;,>'..E@+?Q1]W,!B; -M65%I!25UPF!N`#9)<#^FB9O9]5V766+3H9D\AP=&XIEO%BHX@I.E>9M+D5W> -ML9NC$AR[:8^RJ1R8&9S4"6K!19&/*51G,#Q&X6)J@762!XBLY@)!151V9>Y8QL-$D<&!W`TAGV/@2-:0BQN -M,&/Q,2IMP!Z. -MN"N4DI*01UP692"04QYR1F=3,Q@\`C8GVE5$LJ1SUJ)L,)=UR4\'FI`_YF6? -MYTDM4*,R]W2`4D1_Z8YU\09BH`:?UP)&D0=.8WS\!)2;UT4X6F*1HR/K\8G# -ME*C;!2M14Z5P@"/]\2U6U8[G1((#HBC>>#\U@AHB``2TTD07>7U_BGE">:IG -MQ#<@0U29T2JR%FV0$E5#"IG*PARSTZ,E1G]$E2I=*F$-0XY&:I#^H8^O03=L -M=!?V(AO3]AAJNCB4]"2(Q2!I!9UF=C6/XH5,^8ZGXT:(I3!W%3$3\QB_^D!U -M@Z3$LE2MAR1Y8%YOT`)Y(P*<=3]@Q`*L2@=CL$C&!UUX%:!F61_G8:O7"E:) -MT49+)C)G,)'9>CS+`1U+%6!4LH*I%#FB6*PVB:N<&CFI2`80HJU6\QF;Q1B]*S`0URFLJ-AVBGH))3Z(UW>$1"K`YRM\AY/ -MDDMJH7F!I++#ZA\J=A^EDF+W0U=H02P/=1A0NUTZ=JV[4K/TDI+):C#E8;+< -M2@>5&9W@JE_>$3D*NU-#28$LV'E'I:(@^I2!0Q=N`(4^UJZSXR^/L40$ -MD2CFXE4QZI*@EC!*0I>T0T%E<18W&%J:,BBC5Y9^@2409!B(`2"UTA@N0B86 -MHAEWP!FR.R2C(0>EP9+GT1H*P[Y,$S=F@S97W"EM4SIP4S)H13>$P4"96!KV -MU#=^Q;ZC,SB%KZF9!NH-"YR_3RT9-B,)$N3;4NX5)ANR$M),DV_9*[" -M1$P*8$R&I4S,Y$S-LT!1Q5S??$F+>TUMD$T`Q4UR,%#6.4\&=1[/C$^_@DZT -MO$YADT_O9-L%%6B[?1["+1CI9"S_-,EH^TT$A=O&C5#\-SD+M=S`#5KE2Q=G -M]:5^IC<;U5$?5=U*3%(Z>5(L\[*1,513"U0KI:;N[5EQ5O;VTRJY<.M)9*P=8^TQ=II7=ZZ-=S#%8C"E8RX -M(N0+!N#/LZ,"G80""5U;5B#5]3G%D9M=*I+8R\/CA11D8*_HI2H4+HV<&5^! -M=6]EJRKWE5_(03N8]U\8.V`JY^4(%H,GKMA?G2X0IL\4]I#8=V'-I&&RP3=[ -M[&8A5J(KZX560VQ1"Z2[\F*)@QHR5N0U=F,Y9N>KH0`\AK(_EDP(OKJ9_-N- -M@V30NF1J-9+5EL%L49Q5=F59YN73F(H.\F4/+68'4F:8B69JQF9VBAQPQJ9D -M:F=[F6?DZ'E]1ER`YL/^YT6B8FA>IVC'9FNXAN:H\G4X.(K;J6GGUVG@`9D[ -MF(REAA0(Q7MVV&J(@QJP)I:T!KI`/C7?+FF[UFM=%VQ%6&S'-HG!)FX&*&T) -M.&Z3Z\<3'7@%SX3\9F[HEHX#%S;N!F]?-6_U1N<)#VT1[V\3'X4"QX5A4W`/ -MPT;Z=&L+=P85]W#W,RH2-Q`M?W%V:(@>!W(@('(D9W(H1V!A5(:N4QR,3"4Q -MQR`T9W.CDG-M49RM"D%V*(8E"/3[JHH=D -MM\6/&!F`"%QLY_"+&'=S1_"JA'?$LG=]]W=J'QF#5W@Z=GB)Y_831'E\#P*1 -M"(;P5Q<.N7DK)NV@IRHZ2GJI2-X_C.VKIV1+@U_.T_]X$NZ_PDB']`\Z*?G*%TF*`N6`97PJ4RV+F$468H<(.= -MAFFJRX/^_H,`*X34)N`=(7P';J#?OBDW(`_@B#R.%VPNGA7"0EJ(`88-+W3^ -MJEBP@7ID2.GD'J[W=-:0U'%#6Z_JS2&Y]>\0#;?+0V)G[)D="Q@VSM[:&43Y -M3@DA!HYS\Q(1(0HVC*CML<#($/@FD0*H1)Q*^%&Q9&.W2,5B($4=311ID%+$ -M7%A.XT-^6X05W0979."`S"Q"?5R/%P6W7#3[M"#@@'V_*!CQOF$$46P?[DL_ -MND\/=$'QXXR@41CA=:BK\%VCSP-"MA%#NB3?2#*4BG$4*C#5.0IYM44=P;9Q -M!:+B$=VB1X_!/.&C(Z*/-EF2J1=\J7F,"H(T'8Z%BPH8KXI\T1F(5"LD$F"S -M2/1/L6DDC[(&W5)WR&^S2R01PL-VDN`?#.)DR*(E6;L8:!?D&(KB3A\K;=2H -MG!0RI)@E)'53HU2(/Z%DM8S284!*FVK6(`="Z)2:850B/52)?%DEK*25HAM7 -MBEZ/X2M1$K'4XXQ7XSI1:JD4$A>XY)3>%.NR2]JOSN@E/-.7_E1@&DRY)!!V -M,]LP,M(`@W)0CBG=1:8I4=C2%D>;3IO).T0W[`2:W(!H(DT>S#N1.=64C>I" -M:W(@KRG)O:\C4IL^AT+,+N)P5/2FW[0JA!-_,!\,Y3AI.>7$G"XB4O!6F`D@ -M5J?K=+BRTU#B3@EQG'TGI!">QN#+VT_E*3;M!_148M33<$ILE"3=P2?YA+HP -MA)TJ-8-!>^DGM+*;`%2M$%"7)--%"P05:!94H.(;^!#:U:MTQ]HJ%-=9#@+1 -M(/:.P>"A3@J(DH4C"I7\*7`XM8J@'$1(^0%&R8\991=LE'C@:#IJ<0BK'U6L -MH%VO*E)'*G(DJ4`C!YT4E/)94ZI*K84K97R*QY9JAK-+QWPI;!4YQE2+\E1G -MRCNDJ9WB%G_?YH%3J$%.4<4ZI4;PE,R:4'JC3P&*3!BH!E6A.E2)2K80"T85 -M51S%H[H:D4H<^1=*ATAG_B*.%JUE"DLB5P[*/Z(K#.;*A!1[?E6`< -M=/-J<;&Y?!4<^]6_"EA0)7,LG(AAL+A1@C,5MZJF?)6P@E'<2$2*6("M-GZ4 -M]#(7D$F?TUAMJR*9C*EU<[I*KA)9Q@\XE"S[V&-2%@A86?1'^-G"F&47.N]L*O>,9^Z"M)*#85I:2TQR>:TZ@?4*E#DL6H1 -MI:OE&K9*E^I:<.MKS>2-8H-"<5`T?482)>&W&B[(M3$"-;%%V`:[()Y<8QV%0HU\Q=D -M1^Y2DPC,=P4;X(49A!?Q@G''*WD%&N859-X8;>A*UF)Z!8?J91PHQ9GC=]+A -MM%$*[Q54@F7XHB15:;N4$JD"'T2,BX`1V`(?-2O>)2`0"OWB7?;+.VX8"('" -M^)>%^%\;X@UTB`_A&D1$G/`K!PQ!)#`6,2Y@A`.S$5I2@L%"QQ+',)CBTF`S -MHD9T,..D-$+8?")A=\B$A8ER61E4V`M@86HB3+RP./8N-06=F!(S[)+P"1M6 -MV%2ETX@TSR%!14&`]GV&6)Z#:V0IB14^)C:UG!B#JQ$$SA<.P:-CQ=2&).MM -M?3&OP0;"V&HR165LBPVRDY$RV-@Q08+@(HY1##IV,S7&.ZED"4./_2,/ -M@R_\&"`C$&]@D#D=0Z9GADSS*I""94"ZB(U1QYP;U#P6>1"3(3.BN<9`3!19 -M?^8,!)`RFB$S2EG=/&40,941&:+1RI!&5!$;1`:[O3I9B)ER&9KY:[U,;P*S -MLT$/AQG;8#IN8U1FLKE1-YA9[/EK"84L2;/!8,.J&>+`9HNC1VPSMXF8)D?E -MZ!V8XS9QCD&&SO!D]UIGYR$OJ8YWAHIBI#P+5EHMK.V.\\C/.*=\LG92,*`- -M-$%1T*0'];`>V&.A<0\6]]#"QX09'Y6+HH4-B\8^W`?\V&B8B?Y,AX]&3?P' -M2<,B!02E(9#4MLQ8VNQX:6/A=5V0F?8\:AH)P6D_1J^5D.;1TU:(57,AWW.H -MC2P5AS* -MR.XD:SGK*:&U.;+6Y"=^R".AC8]`MD`YU]H`(;%K7P.OQ<_WR=<@B3F3)%:/ -M8R50P;8Q"=LF887L*90P.<;6O1S;ZABA@$2RN9(5&DMF22VY)5"2;,@HSK9# -M/YN2"*'%Y)@DD\BQ3+A78U(@XO.IM#:0\=H8AVS38L1-NHT3Z@8%9YMO,S(/ -MI9TX3<$01G_G0;F*"F6-[A,TVMP62AOU9R*(C,;1C2$X_XGFI"C>S5AI%`5)H+>4`N%R"E&);SD%OMV4$*>F^)M[.X5:2[]-+4MJXC1*:2MJ -MZV;`O0I7"(NNRJCH1*9BP:V*!L"5X[!40 -MMU)&G(HA+`@RQ2F,%><]&LN+HQ61Q3OX4BI1XQHB<S2R[%K,Y1BV5E&:^3LV*&>07Q^1EI4N]-S[0"0M@LV`[#1 -M)*%;`S*UE[C+?SIH_YT[5*$/UQUQ:7>GAMR50%;#,N8="*AWH?#>B55:N.]T -M36GH07-5V!`;*V!L?M8.)$`*:`25OB44_1HEY8*4=0^Q'D`G!`BE$+YI@%4H -MX]$;>U/Q&.MDE7@*,!!V5A!@\N9/PEEY,P_B[`;*(/,<#LTK1#00$>6\D5-R -M3L[(\'E(A^4(O9=#]&3.T0M4:T'I[9Q80X.<7A@B.E%/`]JB#HA$/J#6FWTC -MT$)]O1,8]E(@'R)[?\\%"J+(F@,=T=^[.WE'[N4\NE?]0,#=,SR(I^P%'[]W -M6'M@%1M\Y:VDHL/$)RT6WQN,D8ZOJZH>5B+Y7$_ENYRSQZ]005BD>^2JYY.@ -MW#/TK5)%A7R"S>FK139Q]<$!711A7Q_7"X.E)),D<3\F)!B[7@+R%%2OQL8-JY?)M%^W,_[A:[XP8'&'Y70 -MD>9/NR0;$Q07X6;N[I_,`^M#@2W"EC]7Q`:0H+5"'$[ -M35D`PT;S^WCH:`&.5@>(1"#@%KJL$_`+_3T,2/RDWAO9@")0#377-O1 -MZ43:DH_,E\84\*AK1Q -MNQ1#6X@,E=(R[(]WRQGB'6@84:7A=KE*66DKT4-L."&R3%@*A=U0HGS#M-06 -MQ>%;&JMQR1S6)<2'EZKJ@RH8[E`PG0["1#+D(6*BAXJ),>&9Q[0/G<..4Y-J -M*S,%Q`QUVPBBHCN(IT.3;F#AT:>)C6(KDR29*Q)VH'SUB#G5/ -M0A%FQ:<%0I^.XGV"%&IW?S9%)F6P'@,-DXJA9#0>#'L(1[,BA.**%.KD?<5: -MPOXV%%DLI!?%.N;B1JF+,NHT\JG*L!JWK=YPC0W#4$F,V+BHAN'Q -M$+VY<5*1HDI5KF;7;]14G*I,?:KBB#/7PJ@2;`WF5"$1YJ@IG*//R0ZLL4M1 -M1^N(HN*D=A0904SU$BF_%1Y-[].ZO%3K6)$U986UX)>S#9*#`CZJ!?D(MWYO -MR+B/*+$GG@;^"*CN)(`400)28A#(/FD@Y^A#39#UZKPPR&1([OS5T@!8`DM" -M%JRG:'VQHU=Q7!@DV*!D34!)FD(:(3-_5Q[ -ME7EPRL/@*4V73PJ5JFM46I-2F3XM2.R"<1[3=K7*>488=%=BD)>R,FS0RLRP -M&30G:8B%RRNQ.*_;`+UP@[.$QJ00VW9`;_IAG0GOMB44)J6 -MZ0N`UDOWI2U-%;?$G-\2081+_-6I&&;_NA!`)EVNRP'6+@L8Q8Q?\](H;&/8 -M$C#QY5#2EQ0LX](%?QDZZ#$'LQ8>K$Z\6RPQPK9$PJ0#7V)A6HL4=B;2A`MK -MES",8LJPV@&16(0-%4@YK%`TXQ[&58-GR9P4)W-\MQ?I_(>I8[*R@^&VMJI'?VT-PV,I6?\N!RQ%."PC6$ACRS -M!T-CG@DEHH&BZ"G2SI'[8GRPEIWE.HF31H2#*C2A=5*54J$(TH3CG]6N&9J2S7<&PG!NO3#N=(SO4Q+'#KM8>?*4$`L -MQN+B?G(R/4HS3L`TTQNW63:5CL._TA3&4=/N(N10"Y'#IJ?GR"6AI"N;:G2M -M75=!69SZ%G(Z7`3J.;URH%3+L5,X9SK@:63"+EQXW=;3LIKFRLMYV:>"&L[Y -M4_ERB>J+K5X+^(6@YCG^K)D*9&JJ@@J<.!76 -M23X*UXZ@S+^\=53F3N@ZHNI.C:J70:JC0JFV)=%K[/H"LG,S4O55J\,[[79CM:^:56XW[O2?N>,T;%5"I:Z7?D=<,1+*YJO$NM_Y&CL4\`CKD4RT!O#@/3\ORX0N\:/T-I'URR+`8&M9 -M%['%RZSR9K-*0,_J\:9V91UY:#8RE%:4=UH9CFM5K3&/XIQMC`-;#Q'.TWFU -MM>>I'#>[6P<#S/&MR`3I!5>=P_2>HW&]@,@U`YHA."N'Y"S6`X'0]\U'DG47MEKHH6O -M5@VF6M3M&7.DB25^*!;3PFYLQV)A[(M- -MVC'VL4+M\FIC*1".C;'?C\>*/P_T8\N?8BU!Z:_(CF7V1P*3[$"6?TW6;S]9 -M_'=ITNK+KK(O^,H&0&(35J,VQ//:H;5J4R&,=X4\2@0;*UT%KN0VNZ:>8/7+1"4!,1 -MP>(1:9%@***T]\+2UL[7W9$!6N[^7\.[U&H3+MB\O^"%1;45UGG?/@[;:M-@ -MAFV#T:BH3E6S!AIPK3;2M=Z(U^Y!@=`'?2'5YAGKB-@B7'AT;`_AYU&V2K?9 -M/MM^X8\`TC.QM@7)$F;;$G4'@Z_FX800:P:HW_+SB4+`:PG6>B1500Y/A_*=KR5W'79LQO5/ -MWN'*C8>`+3$17LLR<_6A?N"'-Q8C# -MD%4O0MK4=,NN;LJ[H1A"^":IZW9!(L%\*K8!ZT[SW)2!KX;7'8C/_"6.W:Q+ -MS6MB\;XY:?>>O>=Z5^TZQ1O2'[^1NVZ^ -M57&8EQ/#6S`B5'CHBHH7/QOOH>1X.Q3D]8^3ES"M#LN+HI!OBX*+*Z3SRJC/ -M>QI%;UXLO8_A]`(IO[AZ,TA@W">O=XIW"LIQ&)-68GP,5@KW:BG=6WYYKZJ8 -MC!98IZO?S%A\[X>:,NG6Z):+1CKU?.]4]+6+T]=/65]!1:BR+VP\';+Q#=#& -M[\O1PN]N'+^]\5+Y0N#(@I>Z:&"_M.TXPE]3]3U2U:KJV=#10A9UWULI9A6R -ML,'_ESNR@;](@$ES3$_#:U@HU6$NJ1Z=58_(6=+*P\1':U6!>Y;90I/M_/>( -MJS'^R2/UH,KI[A2\+U:P9S*00;P&$RP*"0-UNO]ET\WK*>D@T-D -M#[8X/SAC+>X460N)\%IPD2$+"E:V.]KKUPD.+21HME3R&D^AL85I4$@U;2;?DKEO,C=B2Z?$-$J-87R -MD)5V2@RYD(C3GK$QP)@U"..(38R!Y31.E-LR6RW)8+HEH/+V(IC9D:.R>5"-I?^*QT','89 -M(MPQC(N7*D*!S>-["<%RQ([8E\?4K_!CA'(O!^8'&\@B#&%V"81\PJY\PVS( -M+4QB0F2*&<( -M=$EY7_2+/]F4"]E3[IK_^FLF8JK\R$SM54X79M/5:ZNN[#1*/043RQ.8+,]- -M4H8S[B:IR9MMV2_SS;@,RP!GJ[/+]KMPTB5=)BVZ!E]6G$,#,*>-7$',(*?[89R!#W)V$>!Y.:LVYXQ%FZET=A$BWCKG5.S\^CQH"''0\U,@ -MU<^?AC^5,Y(AV$?-/`/0]-S4IE$!;<],Y#VK2RD2GWN^`ZW/^O4^3U"$OY\5 -M/K@V:WG45:NU`B=[Z*G:'FHHJ=:1C/GU>9- -MN6@8Q]%+6D -MQD^Y4\O:G!-0V3DD2+1V<8@8>XZUEE#A5EI&H.-0R2O=FD3UK5E4BHZXEE&1 -M:X\.[X"4@1CIF@)0Z;!K*49YEZ_]&/':2@7JU&NB#DQEZNQK>)*J@Z>Q.C<5 -MMJ=3#6R"6L'V4^$Z"MM0Q:OY.@\;F!&QC1DU"$=3L:T94)6RDP=`=22%R<67 -M7%4?V[2C8VQ5R0_WQK%9"F#5EG7A/1I!6VEP5O5O4Y9:!;.5!FV5'5BSN3NH -M1JV0L[D:/!L?][,Q#V15]O(>`%9$VV!56`5K=8?WAO"`;P]>)E9>26V450(' -MMEEMK`;6IO%P5B0/U]:$@%90B&C5"9)6%0K"H=PH'&:;Q8&V94>ME2K(M@4; -M*-S;1EOQ/+?5W*9;N1QV6V]E].1MP!7.P;=5)_<7T'%<57!#EIM%]11N5X]S -M574D;D=6'7*R[5DJD'I5P@%:5M[:TXBH5YF;WK&YC5>=&XUE]Q`>Z-7>AX+I9?B2;[-9Z4#ZU&ZIPNPT)/UR!Q;N%#;Z; -MZP"\C3Z>6A!7Q-D%1%P29\0M;TA<\:9J+7&LEJLEO458U)OF9;V%("5(]L;# -MI8$`"$C58B56CR#3UE@Q(`R/).@-(A$32/9C@:!O.]8&LKX)!.T;1?B^H3]X -M@/HSOQT&@)A/@LC%6$X6\0!E11Q25KDC:GP5_4\`!P`!/`2<&QC.R4"4("A( -M\8R"9%8#EX6<69B@B<$(NF1A`YM5#%YP')#AI@R^(0LY'/>48O5P7$T^ -MZ&F9/J#60#AJ45@*H?)F?3!O!N$Q\KQU6*K"J^5^L$&R%J^FU-U:=-`59R%E -M<9U"K\7%57I?G"#$CG!VR`*R1=:@<1/1J-`(05N/T+05D`@*<%PEM'EA0M97 -MX8/'>4+B5NOQB7%/?]P]%\B5.806=&\57,I0FN3)_4?>"<-EC3U<0'5TEQ3Z'9%1$\91)],TA=$?A./?`3%W$24@T)5Q= -MWL%R0B`^)UQ7?[B>P',!HCR7J&R(9M=A@';Q)_KUDC*)UT%U"U&0MUY\!CM=0C&4;76H=^N25W -M(ER'3KQ?CEC\5=?17T."_55<42;65ZS2UU5'?QV/7;ND016^DQZ7H469A^=+9G=?E1L_4>>7;HB-AT& -MA9TB-OQ)8J8=OH)0Z"LLF&H'A+!V$Q+,]-K5<;&=\]Q((?947#'92AAQ5T3EH;I2%'8:>0CV2Q`$J\8W?4'TUV1Y+-, -MA74!=K1$7L7Y0UW[YU5%]_=1_3= -MVH(<\';X73,XMV`2:X"=Y-_E2898@-98 -MA820E:,AX55*0E*%IU=E(!E>J;'AT5L=7BKVX;4NK=BI%'&D2B6>+%;P%0:P -M$B[&XF%YO-CP\N+I2L4#KX1D/"_?X9"'XXDURQB/MY&]!S_>LG1#[89:8WA0 -MC45+1Q[ZDN192\$&MI0?=&/_P9,'CIT']0N5UR#D+^;8N:3EJ4L"#)O0CE5, -M<`(\MB+(8]=2`[/!/##G'3[&S:1YFL*:!S#]8T[".0?G'4P&V9R7D($-^\N= -MM\(X9'I>B!"1?7D3&?P!Z%UD@D+2N)$9>B1;HD?$B&2-'DGVZ)EDD1Y*]C)= -M3GY02R8]10::'K#7?LUD>="G9Y,Q%T'3"3`T?65M$W]PZB5-,(ZJ]P:43439 -M&\`[ZB2P7A^CE,UZ5EOXLCLOYNU]#>!>V2#N"6;% -MS-N`[CUVB-FZIT$IN5#;/9\:307'RXF<;'(W!\ -MD%)O1CV!?!J-R)>&E7RNP\D'"\YGX5,TH=*43]%9W3"=J4\R'[GC/MTT-Q]W -M1C]Y9TU?`P4^$35-8-#'0PQ]0<0`9?2Q9U&-TK=`19$IWP,5]5-;GW:6]NQ\7U^(%O:94'6-(9%"-6A.%-H'RL!0GQ#;IS%99&]? -MD*>AM2<'>`GXKF1G9]$<)H(T5A32``X@?D -MS6C1A*OF^,$V7U3[1?H]:9;?CT9'17Z;WRG7^1UIIQ_H=TIJ?@+%Y&="]FAE -ME'.CI&DW?H.5=E%@:824EF;YQ7Z*U.SG_=5^[`X(6*T!&"/@0C5(;6L(4@IHZ%!4"U^X-JXY.AS& -MN<8MU(`WX*63`ZX8Q0J\IE)].MA42Z4IR!+XVHY!!*8ZO9)-59?U$\I?DN$A -M-8$^U<$&5.4Z4F!1104".TD5%DCLG!E.E<76!68G8.#&]NP<,JO;&3BUC&QC -M9*%ALGV%@Z"^$P?>(2Q;3^A6C3MY(,U&:MAL?6!@)>_L;'>5S@B*A1B%(+CS -M5_D[B:"T8+095I*;)_B]>80*S\PX_8B$:2'X!F9];5M;T:`):FVC55*8`(6" -M"AS!40K2.2I/*NCRW!QI6VKU"FH<9^%LM?/85BG'SW,+#CW!!]Y6<_2"PE7? -M%@P2!D]/X&;!#6YV5C)(9RV#O:57:`*!A:256#C")99I!]I##H`^P\>");Q]6EB0+&>\#7'(6V)X:@$C0IQBR!!";XWA0Z@0 -M$)FA%\58ZFTE8B>8"18,XZ$Y9M)&$KD6!F(^M:!L(2, -MUH'Y$A(_\1L*,A-ZC'?933C_W)8V2)1%!_J$_(\/(A1B60*046C`*2"3I258 -M63:%9E9E&<&I5U;AT;%R\)8Y37"3FW(96<6" -M:&&@!0(TEZ6;.>@6PG#VA^W(B20X1Q`H8A?B<*;(P`5^ -M*085ADK<&=3$16]/7&0HQ6EL09@A.++%D2-^4&=XHQV+AE!_1AIN -MEU;< -M*Y22!(?VVW`(D]A"CEQ-PBX>!3-(<`US`4'3J,TZ$F9W!9ATW))Y<= -MBG+;X>P"<55#1!HJYY6$AQ7>3T;2A4.8YNZ1'MIRZR')U1[JG -M=3V(]B5ODH1(B,!).5=UB43+@3KG(&9V[URWZ1)M)_/<.@>>G%TW8C[7;NYS -M/!&XTB("-G&7UC)WR8@$'8UH<=B($"*.>,\M=%"10\=3!EYTRN#%H$QT0^+A -M):%@=(B#1J'385>0TN(@KEI19%B>&04E-CQ -M15^B``:9B(F8Y&"T)^YT3\KLE2;:0D%=8S3480>[E_G2>_T&21V=>2=J1GGB -M\?5SRB7GT%3G?-4G5IV@N*<0BM27H0C;<76OT?8%UG5?00E9AYF8=5@#;V2I -M5(KF"%N7?F6*EY_[E20@1V*$_&77-4=X':@&VYF*20*JF+GX82`+JPB`Y2;&#'XE.2 -M+")JH=W?=VE"4++P!B&47ID&,D@)>6/>T&5U-$`7HHG&_8PPBR+9\0X.TZ,2MAB9R9A -MC/RA'K8QIHL=(R!&M]@W(N-_]-\=8BXK(P(7LNH9RQX,&,EYN`YEIC8 -MA!GAI8J'S*7DN;25R4'/6+H$C!Q>7>#AD4HA7M$XXB&-@Y[2^$'68DTC8_`T -M5@BU4B_6[OUBRHN,U[S0>+\2Q?4=;(W$TO6"429+5A2S1#8^)F>CD;=N(7EX -MH#96.&HR<&/\`N45#W7C_7(WEF-VWCF&+FUY[%B7!SB>"(*CF+>#DGF)XYF7 -MCY$ECJ,_)C`!9)*CP90E5(X*$^8H&?`O#A/$])!YCGR>1.;G461[`B")H96. -M&>CIB%9Z9*IC2.8BC&1/0DGF)<:.8QA[%S.Q9#( -M+K/M'4[[8U^V-_V/-M/C1#(09@.D,J/NX0T'9+O'F%$S\1X#F>_!0-@_% -MDXM`F[V0MYGWT#R1"C/D;E9#>GP7C?640PYG.V3^8/+I";9%K"-+'%4XU -M"A33-Y'.9V*D1^9[Y&<_PADY0K*`_YG50U`*:&XD@>;3Q)&*)%]#1RIH=F39 -MA_,Y$GU-VB>A521^Y.@82!HV<1\A.?<9DJ<$(GGWR9%YWXBFUY1H?=^)IDN$ -M$9*DS4=)%GZ8I"8I-AJDG63C5TV`DCE:E2-+HJ.>7]QY2XI^P\U8NDJ:?I]? -MRA/Z.3>C9.7GHZ%^KZ2PJ4O>5^!-+_GZ<6F(E)>6WIR3+$4QJ?O)%<@DF4;? -M]'YK&GL3_$&3N)HZ)>#,::-4-6E*+7\K4BI%?IZ?&]+SUTB=:=ZD+'4>T%)O -MA3@)*I"3CHR'PU<,DW)%H_:FC7\?6#M)J2$'C..0$$\Z2NN?^<2IM1R=!?RG -M3XH6_.0S5N2D:@!E_K?/:7U.CJD%Y)`7Z4S!IH.5)Z@`45M>9?B(!4`K8V:YF`PY]+ -MB3&L@&ED"SA3EFLR(-5$`Q)RZMK5,%*U:Q?G274><#J@$U#Y/0B5QLM+U1SJ -M:S424NFO(8%+I4/15.Y4!%M4V8]-E5'@KM.P7940F[`SL6F!7247F.R`E5.G -M>TA6?I?4SEFYO7E5:^5PR8`&EO?4''B?S97HCLSF5NV!<16\TV[H;*]&IH@-@)>:A:,C_;&%T(^_-7L -M1@^BE[&3@,5I$5B<3WO9NR%8\*7HPV`M5A5%8'AF%H1LYD%X&":$]N5"Z&8Z -MA$\<.EA@PH7#SY!E$8Z9)NFJMA&.&XOED0H2/I8&J)19858@%R9*N"EIF#[6 -M\9E'29]76HCY4:D@^ITL9&+F;RCFK<&_O:AV(``'A`R%9TE1N&CLJ$BAE:H4 -MBEE,86;E%#YPH^".N6;IEEJ(*9CFY:P8;F`\31E\1;KBIJT:H>JZD% -M!N&JC^%]Z5_NJD[<]"9G1I1T)F5H9VX*6!R-H<6)(YMAGTE9_IF@8:"9;"5" -M*J(:YPBU<=06:[AHQG&OH;8%V\F&WU8>]PG9AN16'\>>?!3%)D@RR&V:OJ&[ -M!1SB"\)A_V%OD9K&X2-W:D9RVHJ_Q6I62I<4LE#,\K] -M9"#`KND=JJ#:T,6%*0F;+&?'56P"EB%7LKD.YG(<6[/)RVD<*E>G`LRY)\(< -MM5G,R6SY83_4?DHGV^;7Y6T:1.`FV;5NH@7D)C87$2F(Z:9%)&Z2(%#7N\D1 -M48CFG-4U$F6()='G*@?@FVX7B+AOBETCHK]9(F9$.)':17"V7>O)/U?!!'1R -M%U$T(Q8N-6)^$G"BB.TFQ>D=_%T^8L8))&Z<0J)5A:<@7G:!5R1R-EXD)Y-X -M%CF)*B>4^,I)B2XGYR6-F>7.-,5GCPGDI+3T9EGXM0P=-I> -MC%&6XB82=5^2G,AT]BQ*W=/9U`&+:XI2UR=F"'\BUADH2E]B -M,G;.1MZ7HWAV0HJZ4=J)UJV=Z];Y!=2U=7"G<<0IXD%TW7)TU^6$^1??Z=?] -MG62`_\6IM(J$YZOX'25BLJ+"F-@QG@M8&\:LS&B[(G0G>6Y4OZ+E>3$2BYJG -M!K;978>>9V*A+(*BAF<)]BR6GBK8Z5DMIIX/$K8X@[V>F$?'B(/1=K6G;3Z:+OF>+`7RZBR/+C!0O>I\3H8R2?,H<]^*3D"_:L,\G=5.LX-UMG^1..Z(P@I\)F-62WI&?]2MFZM[U9V62D23?68?99GWW -M?O)A)E4)^X=UJ_-GR-C?V9\D(X!G512QBEC*:.`-2OUG)`:`_A,QXP"ZK!:@ -MX]OE@H!2>((@NSJ*H14^HRD&-$J@0B,%*N*]8D))TL@J+8TJGM/XNT"-+MX( -M"N.5H.#A"2H;U'@JJ-:(C'&-.QY^U*/ZIMW+V/C[E8UW465D@YHO.&BU)"LR -M,#QHD^>-R8WS"]T(+MF-XY+^\H6"H.B8AH"$^HU*J`'3A-)+3^CA:(]%,%+H -MXOB35:%M'A;ZYFFA!5D)0^CK>(=J+W$8[2@S]:&":K"1.V(,,IFP]\7T3+_C(2HT):*H -M*$]V-/ED9(GRR#S*4:5H?>I1.4I+&:UG/=IZV&,GBLGR>A3#K\?1+A0MK=I4 -M[)6TY6/+0'G&3:RHSN"*LCO0WOLH[;$RU-Y<=HL&;(23+IH_[C*LQ+<7[?VB -MPDPP.IB=>Y,3`7F,H@KL'JZTC+H%"R1DYD!.9MW,-`K.5*/D##9ZL&60[(QJ -M`)I=6@3?!AJ.4GT6U$H:GY:0Z.C#M^5$?"LD]$#QU6;*$\8WC^IFY$+'AT-\ -M?/KH]\K1:$_^:`\)D*)\0.1)(T223RZ?$0GS6:!))$-:\SFD.8T'U9WM$=\9 -M$$E%CF=69!EPGOT0&FG1MW094$D?2/HC?)$CJ7)6DJY8"!9**D*B9N4HUA?X -MO:0=%`LEDWI]!EH)=4+EI"I4'MF3[I&!WX1&U?R1%UIAPTD80X)/X?0DFKF5/,:33YG*ZC70[+N@!:%Q0E -MP#CI1(#%&@5XKR!K**Y'>1C(.0"5L[:"J -M%&FO@`%+`>3MOI8M*[L"H,=NG,:/>E7R@7/4'VE5X5=.ZHJIL -MAR!A":0*/'`L15.D+FW*JHP%64J9FF5G.&9=EE3J*-CL4I:CU98*6GJIIF68 -MREJ-J2Y/F>JVA1RS(&M)`M)MN&";*EOJ;;[@TC.GUC_"(`5WI[H.QV`:PJ\2 -MF?YJG_H,AG#1H)_E9"*L.M"A^EPFJN352$A=2@O6I>A6J:(=;>%VZ:MBJMZE -MILJZ<:KWE<4:#X:J\^!Y"6"5JKC;J:J[[1ZJ*C_(JOYN\67P%A!RK/TEFCD0 -MJIG]93'R7S*&ZX>`F:M>JL`/L`HG:G3BY4+[11BKCB"R*UEA&T@JA.>LEH30 -MZO8CK8IBU"K[9JT&6?!;3"B_#;4DIOWVK6H;.6&*R1.NF%164'BNPICJ*@,* -M8]686.J-*:_FF!"*F?E5\%1FDKR"(AG*K)GAGMG%F2-^YN,':)9Q@B;/FL8Q -M0L[6SXIH!JTW497`:!:M4*S&-AN&6Y3$N+6`CD)0*R"7:5J45"OL:;5ZFO$6 -MUAIJ:JW$(==J*AR'P"+86NE1ZZIMA%TPT`=MS[69"ER(J705G`_P3N8@`W1H0(\XG -M#2?P^G`*KQ&GP%FR*C%]5T-'H%R<$!TB$R3.OX)KD0AR(EF,%TTH%G$HUJOD -MA;V*=*\G6X1Y39TOY_=*%V6).4K-N1=-M,;?7Y2^NEYE(OO*TPF=4HJ:>!@4 -MG?)K?H=TSKQ>RIPHS9*Z^NMA8'SI"V$EU1FG^(E4G0";G6B=W$H!6WT=L%U= -MHBAV+HIDY^UY!X!?$*SX-2E2L.:+!;L%8[##T5MGEFZPI8IR-']]L/I;G(O\%V)VP@V<4O'J=C.(1L<(P*F#P7:[X>-:PD-U[-'GFL)7=#IMYYD>; -MYP];:R*+0BSHR:[$BO`*Z4FOF)YU`;68VC&QJQWKF2U:H_F7%#M[4K%*JWLB -M(I&+N1V)V7M6IG+6JIBMQ$C#9XU4?'8T]*)R9R\NGVIL\\G&#DG0Y^59['XT -MU><<2S`Z27;LP0C>=9^S(OW!QY9Y#N,?J[64GT:=('L>I)\QK"D\WSVN&B-G -MTH^+ALAUH[_*!GF.]+*Y$@NY*,]XPFX*F,]2TI1COKLY6B.A:&< -M8T#[.=(*%Y.=8-"Z?6OH_6`ZEE6HXQ@9ARYZK".,X^AI7I`>1:N'KF2Q@I99 -M,Y%[FU[.A$;19&!,2#LM(**D'E"[B)ZTJ%Y*^XBN>J/HT^311H\MCM5$/6I- -M-"TGRNIXHKP5]P@XZ+19#$_KT?JT*]).%M0:6:!,47LSF#+M8RQZU0(S3.W\ -MZ-0";-A>5'LUY&54;>)T&H=[62VY)XQF#EPM,I/N64[(*!R%0-9\C9GA(.\] -MHY*9/'OOK;59EP49-_E[VBC`)]<*?'0M"'`[%6`AY#BJU_:V?*W#-T92N8$M -M&QALO*,67SSJT.1F&Y\]ZFW8D(QM<(8]]:/M4W,3EV169D3(U1`1'BD1XI`@4A3;;BJ3R -MF6T+]9FDN>W;NMO&E+XM@%;J!+=,Y'`K0B62!]H<>=R2?)MU6I0VK>DC:&7R:IWF*V -M!*DG^96^MY&?6`K@ZK>U9'W[EC:/<:F1QI:BIDQ2N$?%):6GJ5O$Y&+:)M.XR86&^YAR -MN))I4XE*ON(UQ -MCHM,I7^!A:;&_MVF[Q^HMIOZ.+VI2_P]'+F3CD!)G#*YQJFLAC4\N0-@E)OA -M%G_<<0)H^4ZG6&YURAN"5%RN=FJL?;D<99C[G8ZY(*5X>N:2I],:?(50M;DJ -M)7L:YZ*D$Q6=BR?-I#,@8LUM^[GZZ4S:R]`FA.Z_]@$A$$'B@#H$):J-[ -M319F#I6#*ND2?TU&I4OX7+H+VQ08(QU5G*[>H%4R55PEJ.M5BKI?8(C*;)ZZ -M9>6?8:)^JB@J6\Q6LJLLJC,FZ[IL/R%=*:/J@;ANC8JSW:B`8%^9RKZ!`;/V -M@@@.NXGMUD"J9=Q6"[J6:VJY>[?M@K-EG/H+YIWM;E6(K_J89F]OF?;^EEPA -MG^K!W;MAH9(I#ZP,MO'QBI@JR -M/;RURSM8^)),Y27M1JK.O.LEQULVN)=A1*LJ7XZ\@&%]N?A^K/EEK3K[((9V -M,^3+Q/&JTQO7#`U?;\)J@DFLKE@X+_B6,3<_$F;'_/-B/T$OAIF^J80;)OGC -M$DH;2:],R/36A.\/O*5@@*MTJM1[!\ZZY:K5^_]@O5K6NOH&;KT(G,D9]BY;"0U";DOSOCL20IEW;[_[-">\B\<+ -M%P1EF1CM10&Q2EJ![Q(T^$;'8W-?J/%NK'%SQSHW'V^DULG;^*Z9(2NFL&$U -MA"DK1+BR*H#Q59W9$-E!"$N>J0?1K'RF%W>SBKXY*^F[LQX&G*MIF/JBAD#K -M:MCZ4D+8EJ.9?R&MK&RXR+$PK;>ON75IZKY\\JPJA^?OW[ILFKKM4./BRQFNT2;B.FW*7/2O,7=MWK^)K`5, -MG31S_&]!!'2%F]X?8IU(T0JL`+O`_@D, -MO"/*P`MC#:QQ%EX=9T4'O1Z)(6>22+T"P1_=]9IR$L'#9L?5O<9%,.<2++XV -MP>3K$WR^JK"L5\^YOI*Z[6N4@AUHP3='_)I[?<&![.IWO]*)Y7,9+&Q$G6CP -MU/F_UL"`XAM,P*9&76?^!79Z=7>PHL+`EIT.+*32!TN*Y%>7(@CCIIAB(0RJ -MU+>(<')D=X**H8&HR.XZPGLG)-QW2L*J8N"IJ[B*@]TE'"MFPO[!"VL>Q<.> -M,`T+@45V."P%IB$)BX=LL=$GL+#P2J)PRF -M"S^QO7`U+7O.=D]E,"PNXIZXG>ZIQ5HHQ[!O!RP&G^^B&$M\DK$&)O(I#2N? -M5!CS^=QE4-BP&VLD;<-RK//P#8MA/DL9-@X;PGNL#H@.+S%N&"`+ATF,Q0,\ -M#-^MGW@8/;PJV'?W<)SD!2-9@1A_5R`08OZPR0@05X\"\8$'B;F,DU@`VN`E -MQ,INLPHA-,2H[&T8$7=*&IXK2Q''LA:Q!4K+;A<:\>UBU^:R'N@N2\Z&Q'[# -M2%PUEL2^4C$&OJC$RE@R6RO#H(F?#/K,TJ"H]/12$^N@;2,WILW&C0$"3XQ7 -M)PCB$MY8A.J-YFQ1G(0>Q>]84NR$UM56Z#MKYED54VB_)!4?;%2QA7'&>YQ67H:#C&2HZIJ'1K:"GPZ#%;RC)M!9[QYLR/N@ZPL6PHUP\ -M.^ZA=7'R?#LR&BLMIS>)$J)]L2'Z%X^T@;%G/!B[,<@CK:#2LGJ*\6T=MNRY -M,.UC3)9MHKC>9'S3JBLYK2@:B8*/>['XZ)7YUIV,4'L^AL9F&;-'&O,,26W8 -M`#].>ZJQTE`_0K4ZY&N\B^J/O(Q5J]1BM8V35AM`/KJ&F5?+&X.UR:A8FT`& -MQX\9Z$3O1:.4F5H[02;'UZAFEHV^3L[Q[%2Q2L=+X\&GG^6UO&VBDQV7UJ[9 -M7ZM"\BL3GSOJ0H;'RY,\2A[7HXGM/;K8YJ/J<7K=T?"0(,UD^T/Z?)8M0;K> -MTL>:K7W,V>+'*<5GRT0^I-J9?VP_@9&F[?Z$VEZD!C)ZUMHFR*\M@^Q%0LA. -M7U8S(>.V7HV%;!U'V/Z9!N62IC4PJV1C$W`M[5-?JLEQU%G5'^+2J:E6;*43-_RMPZ%?XLEJY(![I8\X!K:0NY0 -M>9=^-X,41^%+PGY]J>SWEP+*@:E+(>'N?A$NFHRF\105[FYH)F.XSJF=/$U& -MI@;.9$K#*3@AKFRW*'.FTM\WF>*&D]6FFG*E/23,?Z8%,_LI+PKXWVLQG+*1Q6FL]O\AI\&%0KF< -M,I1PFD-I84.4"J"OU@!JN=BI8(E/W!P8Z[O%01#Y]NFC$O8VSULE(GHI*! -M#J]9:2I0V&I@@WEDRIBP[C([,/MO!7.,:NLBS#P#7JGK,LR\KHX*,0.[0EM@ -M5;0)J>H5QFRD:LR)LY+*[+JK3BJ\"J6265,J)PBEELQ/:E1H[:;,J-7*?#2V -MS&O;RRQ;G:GBKBU8,\.6;NIOI3.KNSQSG>KN"F[P[MF;=6B%1//:*^^VO=15 -MTISODH6^,]WK-&>TD0&B*C4'O'3OP&M>0:I8\\%+;1#/EJK?G.GDR_45Q"LV -MCY<>6=D\JEZ\://TK`]VO)%!/[@__(.OJIEI-YN\^N7VG/)^SP!FR]NK:FQE -M;+#J8PZKT;,:J!'FO!`FU-WS+KO5H/4#])YO&,CC'/Y$SBVAATDYPX26\_F( -M.2M9P._F#/4VPIYSR\9SMYB;QM4[[+ZZ(R'7;75'A3BF`P<54AOVZMC[,Y>] -M6.&^6COOJ;CST:P[X[N\L[[[`AFL=B^_>[DAEY"WY;'W(L]][]&Q/->%9C&8 -M66[M<(.S])RQ=EIR3&3P8)6\BJ]_PO@><8YO8J@W@\^2K_A,^4JGI*[+>C[' -MK%Z,9M@^@[[O\R`4/X,:9ES#,&BBF_;S&M>/K+[Z\T#R^EY"1BNW"$!/FK4O -M`>VSX;[G80*M:2[0OF\#?;5"T,.O!%T<'K]>ZP6=J"R'J^8&W?QVT,_OV9K) -MA=!J*SM-0H=R;FNNJ?UVA]PO"[W*!9OA[RHM)9*_QZ;Y.W+9T.GO+O=L\M#O -MKP\=_]J'U:80;?]2)C*U2H1$MP7QG/]K1EO1OR,4G-6#&P.V)Q2BU^]/(*2*N_.G#B54B#18?TXV5R-HF+=.65MQ[!CW1* -MIP3+G*'7^,JS6-*I%R8]!9.)A!$BU4G37D0GFVATSJ^D]$HM+2!U^*O3:4Q# -MG?QK&OQ*![!VR@`[*-+2!BRW>$O;P0HL'KQ+Z\%\,#[E!P?3OI&E>,&^G<:T -MIBBJS)USG2)\=]9?<7<(*TV/L)02X-DN"IZ"'6&W31M@QJZ70%K-EQ8*MP$!L@O=/,XD]]Q,["26PMC'KBTTWL/NW:Q;[( -ML$T]XM*>`C4/=L46U%FL,VUO,-C4CP,4Z-) -M&>-,O=_ZTG`3)[L.3;#]L$)6,EVS^&1"KC`-Q)TM4K[^."T(<=3/$IZRE -M]!`OH$\U*1950Z"O[,RVNE35U-D%FA%GH+?L5MT1%P8?>+L -M+D84KV,!K9<'%J^SA"-BW13?8T]QSQ(5;V:1M=:2A5[%6VA67.?ULYKCP]05 -M3TQ?'D$K%G_6!VU9G-"2UC;O1^;0$B,0;7P5%TMZX/!4<='FWQGM'XH7!Z*V -M=77MZ16B`K!(*SR2M-BU$X'2*DV'\?)(7!=EQK5+*^E,%C%M)@K*,-=EDDW; -M+.*T5IETO=->R3TML=<90UO'GG:]BG;7ZN-W#5NXC^+U4BL_^DWF]5/;&IO8 -ML'&WUU[SC[.Q_U@;)S'S=<:]&W]J^+5OK(SNU\RH<.R,AD[%,01Y'`_8F%F! -M?4&^M/&I\H=O=$V;+8\7%!VO+!V"[-9AN7=[;Y\1>T'^^D.C;/)T6&9]\D -M>?8_'IDE^C+LI2M]579PBTEB64;MW4DB=QE -MVWPGLFZ0(M>^02EH768+DD4IC)QFR\AV7XU]]W*Y5&DG3VX`=%G;=! -MLE;Z$O_H?/86Y6=#?FJ4D@QI,\F$-N97E]ZW47+6MVB[I8\ZDY9H2^H"[M20 -M^K5[ES8OJ6GOI0JNI\W@FLEF&JE=4Y3JA"F;;-^XR5*K,]FFSS/S5VMXB8"HHH[C5'Z^]XF9_O[9I>FO+N.GD:EKC>G:0\OD'3U+*E`6S -M74^>#O>6* -M.;+R#=Y=K-7OMI<;;^O:8FZ]7>:*E+]R26E0K;G7FINKK0'<+:6<^Y["E"2D -MP:U1.@2RO5[2J-F3IWW0M'[WJ_LJWQVP`JJ]\_LM?V.#47-T -M.35[;E7SHWHU/\U9,_WM>,.\\A7EW0YVJA(O>4GQFI?_E>V&\>*#GG>JNC:O -MJN\ER.NJSI?5,P)>-W?/=S/)JH#7/HOAFQE@OMZ19NP]\R9'>R%&R.K>WH;S -MTXTX/^V*<^]-$C+.P'>C)'SW6$8OD/5A#EG:JI&U?#O0SG?<'7W+E:&SBVE] -M(^T`J]8K64[MVW?57F9YWSKFZ_PTQ\YI^]1C=UL]=SN]F[?GSBKJ[CRP/LT% -MJUD8?Q>J:Z'6_%[=WXV6;+UEKDB`[Y*ZU^6;@GB]GV(%_AM>ASCH:FKZE8:%Y/Q^: -MD%`*WAKVS[#AT>H9S;ZVI^T[@QO0N:]NN/M.K3AX2:*#-]^@IBPD:AJ/QB_) -M$H3?)!CT\CNV'N%="O0K3S+AG!RMZ1]9OR5T%'Y"_P8I=$'1_;;0X^$+71YN -MX3)T^:L&?UO8".`Z5J)<.G3[RW(9)F9X/:2X!M&,ZQ#-AN._VN81_1_"X9/K -M$FVY)L!UN.9:`-?/#P("_'3=B%ATO.F';]$8HB`^`1?B*Q$:_[IJP``P&IU' -MJ]&..!N-NX[`"">,6(FCP)>XPZD4#:^;^*?0B2.O-/"/J"3FOW;HZ2>9 -M8/,T1%Y/2^1++$6>"U<,,MA%WD_+XS?8+QQ0"]!ERVUGL1C4(CDCJR[^GJ](RUT:"Y-?P]*=1OTOUN3<,$[N4>OD!J-([9.3U&G8.7S> -MI<-$>3R_WKG#)5;LGW+3ZW)"DJH -M`4'\E3-XB])8KHF5Y3GCPWP4KK*E&%L^5;LR%*@14`:(`35!#J`'U"&8`4=@ -MCFV0':`2Q`"H/:<0!/2+<#P(\`5\`4T`K]%L0!L!^_V`]\YPD+,11`1*"+'! -M7>1YKA$8H@+P!)0.:'UO_U4`]U-T$?8>V`%,MZ.A9ESW_`$,8-:#`)M]:K_= -M@]>G[Z@0+\BJQ=MX7SIP!-K]VP3J -MO7W/!HL@!/C]+M^7]S:`=O_;L_<9_#%2'.#V4T!^@-X+^.F]:L_:WY1@4YC= -M]$$F^D.#H82U=)@C"H"R>X$XU+:-9,2[=_=ZM;!>%.CJ?Q\$O`OHO0S@X/>+ -M;X'(,`9T*5D29NH\KP7!/1L@!]`B:H8.L1;(`!@^@0_9"R5M/0S@`F`$H7UG -MTQ>(]60]##!<9/B".3+K(TB!K<$UD6+P!Y;C:YXYGF.:DQC:.;X`"@"57Q-< -M^4H^^K=7_\0;1KSU.TT-1X!@G?.D8Q*"9KXW:O4UPZ4OH*E5`@`>$$:\!\K*[-6!&P-JAAWCZI3U+8.FS,GE`&Z`/*8@- -MQC5(5(Q+$N.T\>G+^@/^3<`IQ!QW@5$P*2@IIO['>`/H^E,+\I';7_BS?F?_ -MV7L39'V4'TKT!<^(;B\#-/C!_JB_[,\=N_ZTD>VC]]S^9C_J3P'57K)?C1DB -MQ,4U&#ET9?&*R2"H'"#'/HC^?,46@1"1_>Q7^MV^AJ]4,"9\:&G`[)L*#D)? -M']RS^%W/;C?N9_?]ON-""K4060FJ,/#+%P(E:C`%&`'0QG)/,RW\,$"T+P3, -M4.H^JG>5%"1[,+:O463VT3Y;/^W#`$^"M3_7C_LS0;1?!<`!-8N20%Z$$A&* -MYK517!]!RDSTMUS5LTM;CP]*XI -M<6;$`F1:&DR`ZW_`O_=I&$X,JL/LS -M,VIPZLD13D!:H8?T]6U`5K)WW`EB/]G/Y@O[6=:%N\]]`( -M5C0=&P->\OL9O7P"@T6"-!C3"PTP[=/U>`&Y'^V3@^$^Y<_8E_NBOF_?+UXQ -M;8._(0-H&VSJ-M0&H"9>Q9P1S36B0HD,X`(,_=D0I_H>E!,82!5`!1@!+0`. -ML#[+%W@_C2\#[/VCOA3`2K@-K?47L*^@`"G`^?P;PKL`R:#G3(YU24HB\C\V,OQ:L!-'^%'"=\`<^!?^JP4<.28*I<6`V/SK& -MR#\=[,$H1\FP2?;^WW_'W_"O]O^^D5L>D`_W2RD2+A$&/CKB@:#`_6<;X0L8 -M^4``,P#[7](OKB'Y"$[(`2`3;Y)L1-6"Y,:<^3WQ#69ULX+H`FT!^:<`.``" -M^Q:`#[X0VZGA6U#NHLRD(M048(;(P33#D]$$$`(,`:P'!+,[P0$0)Q#M>P)L -M%'0$4@+F0G#/4S/_B;NU',XG,\`D']^/"B"$$@&Z#38,28*$S>[&2B$&&`,X -M#B@0MX%-PSZG;4&0F`,4I.Q!;X`70*YH0"`',%1`8@("S`44"I7B`&C>N_SQ -M)R(6PQPI!QG)"^-`>Y+D<01@'4`21,ROX5<%0"C@'?(DE(1"#+.%/*`%;,!4 -M`?86-)4%@@6PP/,>>`O8X``$+9#8H!Z@`4H`J@$4@&0&->$=(Q2`$RX,[P:_/QA?L@P%P -M"J9FF;]?GP+0)N`*-*\0'GX1B8?,GQ)`2E`3"/7)!#@%M3%KCV[,OJ;C>(-H -M4N1D]HUE&3-CYP*(H-0^C/+0#:V07> -M#[9]CKU:8!V0\($4,!_0*.YY`A\83G&`^Z31@9%`'IR!9;]PX+"O#.">\Q'H -M$'9\S0;EG1@AI>4-+.O)`R]2`9V7[C/IB9D*`]4`W\#GAKG@E6A*DCCHP&> -M!*%F\2\!`PIPQ%,&B$^,`4(%V+>TT`R0%9@5%)*M)^0+K`0^AH]AZT?D$13T -M$``,V@:S"`(FV.5K,`#*`2."M4"*H&Q+,2A(>2)L&*87#AVB@J*C*V4)).LI -M!-^"PC^4@;9A\3'[:UYY%?@%`@$0PKZ'/K080"CX$I8>V!0ID/E@1M:7^!?4 -MMT`#2 -M`3B`:K[?WS^0W=<0C`[R]MZ"XK^(P;Z-E.`?4$^=?^0R%R+=A)K`;,07L`[^ -M`Z$`^X(`A%7A%1B.\,G8BZPBG1=.A=H/.;=+RA6Y:3J#Z+WK8%]P*Y@OL`A\ -M`1ICUP0O%M]@;V`&^`\J!X8E!L+EP!L@02A%21#V7HH*$8+HX"Q0(BBHXP]L -M)'H0A;_RX"4P!@`-W`D6#7I6I[\)5L`(;@$4Q`_2]T"#CYW?@&=G(&`7#!5, -M+R9[VH9MTJ!/)R@1%/Z9=P("D*)FWP]ET,<7]!`&`2X50C??PS:P1A$J8#F$ -M54R$^D$/H7VO+E@,_"K(%IP&42\DPSU0V&`]$`117FPH[<"*1/N%KN5L/!_#9X_19]KB$C#TA8&20Z==E^#)@ -M!&=WO(()0VL`!#(39H8`>8`S`/*@+X#9$PFD"5,EKK\;@`N@$2@#:/F=$2Q[MX9=`O/-UG%$6!.J -M&BJ%/4*)($405_`"$!6V"F4',X7T@FT$U7-W<`,<`:X`<,*:0*IP3JAM@,`< -M">XBD+]4B:CP3E`I_!+R"B]J;(1?X8<"PT:*0`+B"IX%C@C4X&WNUY?D,^]A -M^F87F<)-H4W`4RC7"Q6*,*Q]2`9385\@[Y<3S.M9"^%6V<)O@LN/\DF$28*-@H!!5F"EB#S]"I,CTPL=`UGB/R@[.!JN!6``6$&*`-!P:=@TS`'D -M`&(`W,(WX=209>CY@P[`EH:%_*),B990CD(WE,>P!>^&",.](::0:>@T9/E% -M#:5\4\/(H58PG3&OT2Q8=.H"'P0W0.XCAY&+$!"X`7`&ID.55PHB`8!':TMT -MB'0Z((-3#QMP,:`+V2`D`"A.OJ$D8&RA\$]AH@(4A.(@*AHJH0%J!<>$!S!@"#4.`J[8^(1W@"Q".D"_( -M`)!_X(\>"\A@=Q@Y^/V5`&P).Q56`D`B%(1D\.PT!T)!J\%(#U<)3@/CC`JWPO`R/JP`IX$^QQ3@60`=L`F^+Y2('(@T0!/1<0%%E")2 -M$8,`?($$0!!`:8`XE`(-1JR(Z#TVW[F0(DC:6SCX!SY^I8$10`T`(E@#N`$8 -M#,V#V4.@81;`11$:`A+,!C8,:#;G%AE`(WA@PBMYB91A#8:Q(9SP!4#EZR'& -M-<""#D#(!!H1--!$M")Z$N54!C`Y0A`@+]!20`T@`7`$?@+Q`&+!$;;8XR2. -M]3R)1<$?8)G!2*&Z""4N-I:(:L2QB"DQD<@I0`(L%EH`6(=<'E2`9!"%(P+6 -M`4:!7P5/(''AZ_`EN!S,#$(%0@`UP##`%C!?J.MQ*_@"A<*\X;FP"'`;NA)J -M$MIF0D1!0:LON"#VR'O8!NH`VH:A2@*`Y1!\2T*`$_T#)T(M8BYQU>93F"L0 -M);X`Z1&`XO/`4;BPJ7SQ!ZHLM@0K(64`2UA]`UC81^PWQA$=PWU+Y\)\TYS9 -M$HXN-QJ8X.%")KBPD2:8#^Z)]P,80*CO7&@C5)OY_VXT>:?A0"L$D$'=2S.H -M209QZR;110*@6/'C@Q(,$\X(C@W#GQ3H>-3K8-GMB[!8&`M;`E#PST52$46< -M_L0?BHMT0UDP_C<0L`ZT(RJ$;YQ1CBVAT2?`H*DD\<0HWB^F(BQD(P$4Y`O\ -M^L2).``?8HR$`+@'>P&`$1<#`H8QHGBA/!#RRQ4!$]>(3\0HXA2QBM@7^"J: -M"\.*6\1@(5I-Q^,C&.RM^@P2Z\0R@-@#/?C'4`OP""Z*A)0-0^2`JN@T&`*D -M8_AHTK("3S`OJ;AAR-C9$C85Q0&G@>M%)C),.##I%14[6KZE1%TQU@=6O!:N -M6UQ_34.B8:?OUZ='Q"LN#6L`VL(:0.#0:/CIDPG<%4V+Y@O7'VRQ$4@#F"U* -M^3Y]:,+LH6MQ%,+_28M"PN`@XO!PB -M%T]^>,/;8M'@69A0:#H@$XN&WA)7"9Z0;VCRT^WE$RD">,62XOV.5,!25`MP -M"C`/K4.>'Z3/51!&4`,<(&P)@8/%@,)`QV!U:B,L')@9?@(\A54DCC!S6H7@ -M!TXC78D$0*YHO_'W"_QA&28%CD(=@=LON,"<@(`AVP(T,\4OD9*A'3%'1"P4 -M0>*+&!F8H11(<($:"!%F\RZ+'X[["L^`='`7H2G6]F@'Y+W\H';QOL4IR"7* -M&#R'X('-V:FAM@'@XP]P"+6+2\)F'0ACDQ(&J!^&V+P-G`)+![.EVN%!W'5, -M`+\,/<::`.(2O7` -M&0V%Z$5.`7J0#$`L2)A(!?`":8`J8^]`-<`H%"@1_2Q\@$8J(]1L#4`<0`T< -M#M0`#P.>('L@&_@@L'/(#MH1H2S$@&6!PQ0INB@F%@('/`+*@D'10W>O0'P( -M)%``AX?B'KDC\,`Z?`/4"M83"J)25PO`U2@HN`.<$=@`XYP50Z>HC#,_2"LD -M%,MHW9Y90TTNU%94:##:1+X`407D7SO""#"!20`,54)@I[_Y!+3#[ZCL)_A"W!_<0?B#46'HH5^YPW(Z0188A73`+@%P0"Y0'TX'W/#B!6S!^= -M^JHQ9$6W7P)%.;"10"SHA[IC_4)PH'!Q;?"K`\&!)810G9<>"STHC'#-PS+0 -M\#@52<`X(@UC-<`&*!/(3>8./8?^WZL1C!`C&.:`##8WG`H1`%Y@8>,&$`$D -M_SX2"8!&XP1"R8!TV!2A%:\JML8YP'HB778W>`T`0':![<(I(UXQY^`@*`T8 -M#=P`(!E'ASE0T)@>S'=P`E*`-D%M<4OD9HV-_D@3'9<_*E!(8JSD!W8:"12J:=6Y,\ -M"7('-!=I(8BN"(`%(`(4`:P`KP0X0).#XR@(3*7T`W^,7$<:8^(09I(+^IRQ -MJ9I*&@:13O0NY1'Z@P>V%NN-M:B_B6RB]917D"B._4)^`!@?0W.1!K`PP0E* -M![F.K\4GG]FQTWHXV!@ZJCJ(_>8^LQ26#^9#6D03P@!"3S8 -M'G^/#$!!1[%@7C@`E!7"_[R&MX%Q!7<@FE4>$`%,`3`$E`$1@.?`T95OE"SR -M'E04V\=JS!(@N(`:T`($%Z8L0D?0&,`IF3#-&$J5*'J/T$>*8+,LH?!@;#C< -M-FH#J"9"C[Y`8NAZE,!L%*8.MI%5EK6@!6$V4B;0K*0%PC_V`/=`.#+C0V8< -M$?0#^0++W0*(EE;DV_;X'K6+CD7P0+6!VS`7@!BP,I(`1X#V@1'@"7!SP!I6 -M`:8`4H!O`L?"2>8GP*;0,N:%KYF^P,709YAYW!V-!T08Y(5ZGY81![%A`.)% -MX3B.:@'Y`@31V05$=RSS20E``61#K. -M&'20VYZ;P-.QYPB7.42Z`>Z0QD!P*!!"`24.\(A3`3\`>2!:F2GR)$L9:"*?"KXC]`[Y, -M!%U]8H?+(K&@#M;7(RS&!GP,V9+`'O"`4Y``V,6D!0V+H@$C17!AFY`K0?,E -M`$0L0@E^0AU,8J7ZVX/A)<19CP',@/0+&O$"X`*^`+(2E`(]P$#`S[>/V`_@ -M)#P'1`"RQF."4^",Q`^(-P(HMH$\`+3@:]`FH`'8`-H`-8=I`TXPN+AVQ"W^ -M!IJ+,X#=XYLP`2!M4R\5#684`H:07PG,N<<&^+R(+*8[U@?"8_T!24!=L"5H -M?I@F^XAVG3YD^9B#N#=Z)!D-(H+N!Z>@"$`8`":\;]((.XBA1+?F!/`".`%` -M_8R*DH^*`7[`:Z"L20",N1074\B0"9\#7T2F0/5@*@$#/A$J,8, -M"$Z2(QDC'XAO^"9^RB1$`9%%:86;Y.D`(3$_.1U@@'R2-8SHP#'!"_$>D`]] -MOJ(#2`<1@,F1L?-F20*^,7X>BH8!@JJ!(4E;\PL.)U((',F;(:I@3L)R,$N" -MSC0-4,DX1N-09Z#%&$S.#)I'@\G"P1A2]-A4^$18"L"2#80U(Y0D/G`@_!2V -M=PH3\P@I8#.A%CG,P1:$('8/-$.LPTFR!8!EF`I*'1P;WP-ODB`!#/*(T -M).4*HD)61E;"$1$Q[`--)C,^)X0N)/=D!B`#R%-P!*4"_\&3Y&G@#5`#X10@ -M"H<3T07D(/;'=L-6U,O@$S($KYL;0(8"O!/0)1TG%`MDXO7@(CA`"[.!1-X1)TGTY+BH*6AK8#FH -M)T<%^(K`I%O,+FD\FJ'<&""10L$X)"N#V#-M86TD4%H1D`=90B-QR_C-.4C5 -M%FP)-(Q0``B)35*R0 -M`HD-`95-1#MB%SB?B&AMNYQ*!`+Q8FE`'F1+F"CV'6LA(((W""?&D1%!3%$" -M&?D'GX90"2DDW?&/R`.$&QUC/H;KC&"!'$&2M"7\34B.(LFNG^6D+FBP>%%J -M%YL`8$$7X[V1+5F(K$02'\V!5G7BRBJ"B:*GT'@N2$T$ZH:CDQ;4_$!3$ -M_>@`>@@\8CR0ZT@1+,XM#::3?[<9CJ<&!+`$:`_$K6@44R1UAQM#1E -M(=*4GX;B7'5RHA@84!HD-JHQH@@]X'RHF^6&-!&&'3D%Y<3"GS!6Y -M&YT*\<:T0KQ".;!^#".X'S^%E\B>8ZY01,EU3`*P(=T(HLB.(X/BB-!_;'X4 -MNTH4F#T9P-425NE-@.O1*G.%>DOMHF2PQ9`YF.X<)3D5'DO"X+-D1^G`$4\) -M*0&7>TLK@(.@2TEX'$PN-D`BEQ,+C"^1P."[^CJD/%Q_.8`XXGW+A#6(:C4.SA>`@N:3!D"'9\MH9FWFKD,!`$X#LH%B\)L86:WV&2<5B%7#IL -M%*Y]"8"T86>!2K!3P1"\,M(*C@EXC!CAOK4=<%IF&9)]*K>\Y=Z2G.BIF5)T -M+Y@I?\CX3'7$_TCEN9QH_.H.(,4:GW:1G'BWBENN',T5:\HS@!W&EQA+NU&F -M"4*1:@XB3R>_)Y$]2%?\M/7PJ3(K#"C%B> -M^E(,WX?6`KML?-D\0O5X=FXTDKY8W[^PAKDTC%6J%M^$O[XA9I6QA^GD"UVF -M!$A86@.;A&%![E262&*:"VN8CL6X0;XO,$,PN$V^VX201P1(W6B1TC=!)&). -M#B5_L(9UX2KPBNGO:RIR,Q(<'9K9WU$0R:!YO!XL<5H`<0#E0`N`":#'-`/( -M%).2ZA_YY>>!H(&?U$KHāJ?:XDC1C,E<=&'J_M28I;U!I`J34W"`DR@F -MX%R'7#Z.X6*"6)"G"#KQK^0URCPX`X12],!]S"1-,3@5=;XG0D;(+E"#7$7* -M'BX)W0R2@A$&_G/"5`F4,5F8X$ICP]>QMI@T9&2.'25_-`%(YHZ/:DC#U!4@ -M!5Z%1@%DYOSPQ>"7V/%M%`J4J`JGWXXO4.CTPP/`(22/-L5-18ZQEGE>Y`@H -M_>B$CY/80DV";\`V7(RX#4L%X@$U`W`Q8^C+W"Z`*S\"PLQR8?:PADD1U"5JT6"YB)S9YG[LDH% -M*IN"C;]=2`L@:+!0)"Y`-$\#.(D6@()&ILB`+&5.`1(&4@*M1)A0J0*2460UZ@B9#U.`,D -M1WB:$A2OXDFSI6G#9&WT,%L`O,OII=./=WF;I!T`%V^9$4N"T5+`1L!\$S`8 -M1Q*52(%ZGTESF(G63&GZ+3M]W,RZYAF3LA?#)&BB-6N%&A&CYJ8!TD=W7&LF -M%`"2U`$VQW\A?I*[))Y4&Q>;ZJD%'RP2I;G7/&(:#6.,,TQO)EQP5!`I.'+0 -M"3N:U9@ZY?=1+F#UXPM@-GN9G`*TQ"&G\C?;0QTT_\P4LQ=\`IL2Z%@:G"/\ -M*J,9?#0NBGNNTPCAVP],&$6/.TS?0::-<1%CE`$H,5\$(HS@WD;!15@.O*DM -M7B(J%K/HP>U0,%F%E`(!#4B0Z+@Y2:Y(!G`$`#SP#\L#,0`J@!!`LHGDHVPV -M,MMZ\,R_97&S6HC%=(,!]`Z1U,.+RK(-C3`C86:JHZ2*"8`D@MKEP<@5"O>) -M!'<*`!D\(XV.@8QO(5WH4U8>"*OT]>X"+`\$1`)@KF84$'#J -M'>AWCLG(!&!!6J`P(`_<"\D`="=^PBZD#5#"C#*6-[F:%,$C@GUCF&`ND*TU -MO60A3PFFP=C"3(G-"Z:5$V@`[P-!`6_2-\E0:#-^*$V;V#T](CUS6-E:^^XY -M")B;JKY;@P\`!W`$2/[=+06<(`,G9).26-`@<.HL6NP-3@T'9_QR(U'`@:N\ -M._!3Q4W4)F*`BRD73"?>#S82@,S``GL$0@`:L!$9@703[P2H7Q(@%,E96!GI -M+9X%AXQ23Z"!IK(4H)?Q,'4T?8$88W:1J[DT;.LA--^$FDXMYRN0<_)._!KZ -M.36254C:H;X`RUG>$W4Z_*!64(Y]&[9&0$#S$V]%#D0`QL0*)HNKG`"I^R:@ -M',$HWP0.(FZ%U;GF,VA2!'N".D)*PLC@-?!PT!=TFGR'18`GP`41%0:I`!78 -M$NYA]$(,)O]Q,/!=_"`07<([7[1[$W[,))D`,(XL,"4A?`-0R]E!S0!GS&RV -M,[&%$P65YM\2SBAPG&1R!7V)VZVHB;`Q`B4B^O-%-&L21T$SI8V#K.2+]!,4 -M4S`(44!UHR.BWEG,I'.<&_:9.@9]`FFR<8E_D$E(481R2,[$X+G^!1L]GIW/2M -M"^F=>LZFYS=!]4>:,(YH&"H&E;EDTF&J9,$!/%4F!DL*]'*0\GGUIO0L`QS%%R3_81R@'A)AIP,=&D[)%8 -M15`]Q3GEP/$QG(G,F.C4!?D%CDF%ITK@[-G5U*JD%:`%]X.%(UO2,)6F`5LX -M"BF#<`1;@A-D37:8.BHX"KL9A,X4F]Q@2-;EP''LU(Z'*`T[C2J"BY**:18I -M/O64!DWXX:\.S"BA"$SY&S<*IC:ZPA>@3R#GZ`O\&1&&[\[3XEO/!?#(G'=: -M^(B9FLV)HI-O^C`03#+,)U``#D>J07$BJI#\(V]<_S1F_:>DI]$/^(GVS!1: -M%_4TY$(OH4$S7ACAFP^>RHX4Y\<7E+$BH?01$'::#VP)*(#"0]H&G#"Y="8P -M4S@<7P-5`[E09=GP5"]"-4D0DSV<@%10/R`RT#8T!>V'J,7OIPVT-&`$M7?:&"=)I;^+)L)`HJG%0#]. -M.,L#A4A;@M2Q4(FG7((6.[F:%3ZU(94`QI`M4>SQ -M`B69#<^EH6Y1"=HO!/\=01N9NDHE:-/1#FKOE'"6,D.0#0;"XN&"\M'7(VN* -M^+8$;,A*&,K1U$>G$8/6'V`F>8;X3*6S-(7BI'60]L)<[T:4P=@E0M",A!HE -M"2:A$@,7@#02L)=F(`V\`$P%6@+$@H6"DX@&;0%,`8(`+0!OII7O5N(W0!)` -M$FR/C$\YJ+R3]^B!9'Q2!'V%Z,RK)G+%OWG*^$*@`+<#P+VC`0!QV/$J>/SL -M_E`)V8I?G2RA,MEBH'0>"0`,<`"A8@,&$'H_$(26()D^.Q7$(;&2%O$"&`P) -M/L&9?9]HYP61.W!G*(@0A%@?($92D2!2KXD'=7K^+7>0:$W](^>S\GE4J#O" -M+%V'+5#!CZ4AP6BU&(P@)R('E93Z(1)P?*&I6X&>W*!3_X&+(OZS/Y`)A8D( -M*_<67@A_HL.(41C!7+6=.[N>H<2GPQI@VW/UA$(&\RB.FX4+XWG`(+KF:##0 -M%68&[P76H3PROTCDL`+Q#2B?J+9^:'"BJ-A26`,((61@M@1$#L?+3RA;TXB" -M"@!_EH8R`/Z06B4%PDX^O,R3GD(D@=V&2/A]F#(D*;6-H0.5H4I`SSD%:!!, -M&00,*8^PYZ`.FG8QG`/:.W6A:L\W85G4%UHVJ%CV.K202$J0`JQ0PK'C6S&D -M*O=_H4]AI*"BJ0B;N,-]+80#-TL07#)ASH#.]'G40E@/E\/W``]@4N,#T(HV -M01N>^D>[0(N!#)HOD%:*$5Q_DSU8@]&3S;EDT!*8*K$,R80YR5?#8N8898`V -M`59*D85PDH-"6+!E$&$6'(TBO!!?XY3`YIFY\"NRDU:/N[!00?T0**%B+(/J -M)'(8/@/9Y050+3`#51ZZ/^`*IP$(U"Z2.S!,0/UIF=X8M@0^`29#($""`&+R -M#&E\[DZT9P#4LHDYQ(YR/S>;WQSZXS4TMG`=/?*Q,[6CFT(EJ%60WV?OI`AZ -M=G0S>(K**'Z/N:#CY(MR3Q8Z\$\B)7\`J%+JVC_95[`5-:=&14?D`5AB)("% -M'DL1/`4L#[`$@(O(/,*,6F)`*+H8E7TK15#.S/`KJ,V^. -M'2=[Q<].WWK4-(IG;#0(-D4%A`*V)/9QJ7D_N`?F`[$`=D/]Y1WT0RHT5(_Z -M_M":18"V@*Q`1I$#HA*\7\H)J=%:RFJ4+8EAM#6$^\P&Y8#J9)`T-#4D-82,-QIHDP042\%Q2]3WH:D@.0>>71.K05S`T',??!QB -M`CVD[DRW7C#S;YD`Z"'`8J1`GHDZT"@H!(@#@4%04:F'X>4!WD6G1Q. -M]M*;>,V>H:MS:5BBO&L*#MN"KLYI"*8^)$4&K09%_6/YZ%68 -M*>6%+:/:PI[T/!HTE'NF1:6&;4%FZ6G4C=!6'!7D2?$`O@7)!^\LE!@CE56B -M2>&=?:*F3SREE6*J%&P.P72`=R,9E)))%=SYE?S$SB0 -M:#X(`8/NUAG`!2`C4%>*`:((,5*S:!QT2N^&C$_>F9$T*J?!2..` -M-BD))4NMQ!6@?,`A53MN3!N9RT]=YCTT1/D=#8-N+X&7@.RT]`J5H4`)H/I1-2/3D54$%#CLRFJMFJW.U] -M2X6?R\]/I]%P!JCG="PJ\XP5&,(:!:%@Y^EE>K^D(C"$H1DVC(3`6Q483`$: -M2?J/0`,SHQ*06E%1@/1E*>T3PHS?>L92K>F`%`]YRN1X*>;&(^6 -M":!^.XLPX#L1#Z`%E`^D*Q5]@Y3$7+((OFF[9",H1%<'R%#%QH6RT%-1"#!< -M#I(C8!0)01$MBM3X$`-H"2!N)(,C1VC2#&J0"&F<'XH3"H.%39Y2SWD%.'6^ -M-9.;(12B0?0S#U"<(!84^Z2:`&8/Z>HN:)L@X0`_P"MQ`M$ -M!9H%VH\>)XIRZ\@Z19J^]<2E>AH/H$$3,<`Q(#;Z0_&HA,EI1(V@K]=TH`R$ -M"C@$*C?=@)L4:8HL(!!Z)@X9K5&^0>@Q#+"MO`1^!ONH:5(6I0!T7.E)S:%N -M$0T\=8$4Y-@A(*H_O8OL5-RG!PC!SVJ`09`U,HLH)_]37Z6_QEH@%[DRP%R- -M-\J"K[T8R;N@1,(B?.UP*P>H!\G/GAA`3ZD$/:9R-8^3^]$7ISJ"Z]>`I`R> -M.W&&!@E#A!?2#UJ-B4?6!;N/1@"4P6N@#,`^G0,T$>2-LH9A@"R@IO)K?`_L -M%ZU<$H*G:41%=F`<1?4<`2@%ZA+[S?W#X%`P"`$D_YX*-4Y?)-;35[/Z1`W@ -M(+0OFH5"X-BOD^H9S(5R3)>I6E,IGS.U/0K.9&6N_KR8@@(/)9#C+J/&@$RP -M`>("\05IHYG0,S@H?:CJ!)JIGE179Q$`9$E'!5%H&+Z&UK22@E_R_"@A8`-Z -M,(@%(TN'P[G!#*#1;,P]``.HAX%-H,H-/_@!?)DB39>IKU.)JB<5K2D$0!(X -M)CZA4\A$V2Q5NC?="25P"KX`C$=0(*^!"O`%F`(4`88`50"QP!?`"?`$(`(\ -M`:@`9E4JP!Q558!5Q0)H58<`7%6O*EA5K#H%R`(T`9@`[8,E`"$DG3%59:)0 -MFAH,5=!XZJN,G%H+&7>\_V8T<*N3D^D@YM7;06M("$J!BL6E3\A&L:JJ#'P! -M4&4#+H>8RU!5S:ISU*E*EEO=0H9-6KB,(&C%4N^`;L,;LC70PV4 -M*74#Y82L:N,!KOH%V!I*`4X..@;9ZE;U"_`$N`),#Z0`/PBOG)XAKM?,6)N6 -M!Q2628"Q@XYA"J!*C5Z)&-:6]M*':KZTTX?9$W]R-1]\S`5T8_Q2!&"6S#$0 -M/Q(I$H*-"7@!KL#"$R@NA-7&B_(W,5"-Q1,*<@+94 -M)A@*P90YJB[#0:`45)=*+,!SLQX6JD@D@/2I"E``]L7Y1+.`P4!>Q;4YC$RLK"QAPI&H-+`>JP/4 -M5/4+>4"7Q3A'Q)IIHSE,C.RHKX&'2:AA08),D,V-)=0E:X!(GX0`!1`,!.>) -M+%Z&Q[BT0O=P\(<%SA$X^;]](P@+CR;XG9.VZ2 -M%3BLD1,K*-%HW^*X'0#6LHLDHMUL\`W8%CDI>0`.$`J@='+IT6Y7)%Z -M,?^L^4LW*YZ+/B61?&E2$KBA+\M!*,1`TIK@*1A<6MU@`SU$QFS24,"C"0`X/4Y6#5#HC`T'Y^ -M0=^%-@`6YF1/LJ<$A3/J$0.NI)5F@B.BL7F$40F<%>B6I)`DP`N`!1(T"UBN)5*D9G*$70;6C+;B@3H$>`%-R.70YH*.,]UF12'2A4OCE`&D`NH -M"BZ49@"I0U\/+\#A$#4B/"$3.[2T0(IT1O&D\+JBQ&0A3\L\8/2$;+AT);I^ -M,Z%>5:">Z^CAOMG@LJDA15^<'$`>$6'5U_AA&$X84"&?3@SM!`50'D1W';J6 -M7.^N]"AH@C*V\AJ7KM\P`B -M#!&N%,&09$;5RKE1M=]X7:YY&M5S1"<+(-',\769$V\81:"RA`(X3C& -M%M@<-3^VI!1('OH$8`(X'A\/[RB%91.@N"<%2`(4`:8`1=,X(_15X#K\'"3> -M4`&@XD2$J]OS1&JW6D"=7P$%)=/SA/K34ZB#J5*4472=AE%;`_J/0/FS1"N@ -M.%V9>0-,`<74RH%UIDS0/OBQL-Q$[!.P`%:)2<8*5R#J,=!%]@W%_$JQJ;%H2PS"'9D;];U: -M`W]3OE8J"N+@?K!`%.M@,%=9Y4RDIK8RRL@'I0B88D$`6T%QAVIRZ<.F5N+M#\`*Q8 -M#[]_V%B2)?MQI_E^Y(+B4T(C^P%\["_OK5D>R#<6,78Q$8LZ`/*`-TDQ)0+% -M!CZ*DP(Z`)IO7PJ0/<7ZNAH1+X!&A$6@^A>./?SX!^)^.,1VQ![S!0#6S.YX -M/QHP6=@M[)V1O^D(VPNV9"]W!_W?[%5!=/)31>C6%LS&I<;>- -MUQ(*Z[P'1J[H"8`HJM:-#0\#N4X&H&T`1BH4(V?1#6P#>("X+!U@+EO;,(6R -MLM8`MX.X57=H5.$=F%Y01.(*DI[_Y7M`;A79!+!Z906-<;UZ2-=NIXEVEEFRSEXA^3>ZT5NG^Q),H -M\PHPO<<)(@T`]?C_[`(."9T&XXY`)::2PI@X#"7@3MD`>]8YJM*@BYH"D4U$ -M]>"LI0-*+,LA>KJ#%"=.9\U2FK`6PU[I-*`<0`)``5H`50`L@'+@#\CTNQ>N -M*:0-[4I<@0*2OQC767=6H.)R0+]U2U8-Q?,JV5WHLF8EO*S#7C1#K+8KL!H- -M8TYB9S70XDK,:]02(WT*DF)BBTM?I%S-,6?-8E^XC=X73IZ\6M8S"-57(T+! -MYHQ0>[Z^49\/*28O48J->=Q991[%$53,L8::Y>00R^"PY3Q=J*_;/&D/Y -M^8ZTH2,:!EFL8W(6*_30W`XZ#2TY%'!N/QG18JU-M(AS(+7:D?SN+E9;TXMU -M,7I'T+E0SVYM.M=;@\\938!KK#^_PG`M,<:=<\Z]>@JF&%9,%&3L<5#3*LL^A,@ITLZBF5G^.-1;I:A4[")F41T!I_2#)>.A-3/T(YY9%IEAL`1H.V5[CRE;<0M#%@S&V+#NB5'P&ZM -MV>JUBR2GE`J\Y16ZJN\[FJ\_W8X(Z!107&5*NM^(,!G"ITN&1M>[)L4D1/,Z4A/7%5 -M4'MUM91>&[`.42.L`TP-VX(IQ;9)3:0L-A4:V''-DS8USC;:I#AT -MRK!UV11MG8J/H-1M.R@!@,)MRBE0C+@NG>)JP]6:Z]1M62Z67KOMGJ)1XDZI -M!"NH\3HR5TBISH%OL]>9I_9M^;IB&9RK7X>[=;<=[=)52;N[)>X-5G6[4XCYO'1WVC=1T-4-VJ5UBPIE -M;SM+)0^46=D&;#=:8IF-[F4MNQW;>N$/GNYK:W4YJYW[8K?SOG4GCE\+:HDC(IW@I>D:H7G[&+4J7`S9B0 -MNE0W)*K0@^6MYJ6[75).[LQF_DS,QP".OZGN`==Z0^#US6!O(ST$$P4W7;O\F-["6*QZY)O?VTFH64GT:NX% -M[]PWQS<0D])+Q'0YZU;9A)IO."'HF[A*Q12\_0F9JT9GUS><6_:-ZN;L6IT] -M0+!W82]ZZ=QMMU1WN]_.66QG>K<6G][N3^6_!;SY[7YG!ROVW?UR4E5_4[0< -MS^)W],&?T-^+>6:_^_%596>XJZXSP.$K=%?"S9ZEWAAPW+,3[LEJ;Q8^&S"- -MSP:K##S,U\L*?>:)XWSIF=AGGZ]80>C+`U?!DY]=\.AG\4M#TPFN@_?&&5JY -MAEAP&+GX"@EO:55IHL%%K>!DOP%5"`.MTZ0YB^'Q.QDY-3SD%PYO"*=JBIKL -M\)Y#/3PE7/0K*=&$`V*QK;!?TRPD'A5.A;;$N\*YT,1:I;PC&!>.%M*WJJ%M -M7<-P@JLQG/L+)#@/.<-]\?(A8;PU7'*B#1>Y.L0)B.9P3;0VGKD)#\?-\5PU -MT4)7,1`&&.GJ#\=%LS>IKOAXDJL_7B).=27([4CCY -MKE)@=;1''B,NDE=(JSC-P$!QECRYY2ANEU.*BUXAB5!Q/K`E42@/Y<0?>!(5 -MP(6OKR='C#/7Y2_6L;MKYXZKK3UD-4)E`E]@8.A1I277B=K'`)+4:1+$^LT -ML&:%#ZR%;).34E3!$L<-PLAQL$UOGLLQ09$(6Z:-\^A4Y;QURSF/A&7"HL=A -MT^QQ[CQ\7.(I`2//ZX3UX^IY_SATX&2G\E0*6\IU*_IYZS1?KI+`G09=@Z<- -M>$9/!3T%240.B3"1(Q)4Y!AZK,<*";?(%P90`Q?1OCQR!+6+7D@N"*/1ZV(E -MP^2EPJ>4'!-F)6>M:LDQ=RIJU3!DX;XH"Z,-TW)UU`2:=:SNCCALIJ?'JNF9 -MU&YZ*+4NB4I-IGN4Z^G1891R0+V8FE"O'L8Q(ID>.2-9_#`WPOW)IQ9/V\IM -MLJ)ZPM7$A4$L;!#*0JJ);Z1N2S6L'@2#:+?5DXA)U8H'%3':0<[2L3?W5/D= -M7>F@>1\#7Z"C0DO$A*@F%/:N3+FIA2"OT#<-#M;JK$LQ=:O?;E -M"M.[U=WUKEL/D#K&-.W5]_Z51@2'W+`LMK?(`;G02RO4)SQXMU*J@98T$NK="-/SM34]7/LX)H7K/P!N_]%B" -M]QA0DDUBYDI`AQK<>^_][]H2(5XA8(%/<#`?M0OL]W0W"C[=0)3QO#CBW7/> -M]YHOD$K^GH(OTSG?BPAN>+E[[;V(@QY@PB76H.3['A%#")WBMJ"D& -M^89\PX2JZ8\3RZ?R<_(E7>=Z@[Z]GWI/6!):!#%P^?0.-5RK\>B)(R/SM -M^S*!+$Q-7XF2#KKPBPAZ^R9^R(=F;_@OW2?LQ0;J&-Q]+41,*2P5V*ND8#G< -M^T""^KZ%7Z@7);A2TM(*_'*]M%.#7_P2RVL,X_A%^W*)$+_W`+07R*%U]^V$5GKU:PUNE5N,>N -M.0H?#->>GW/T79&@-5\(_8R\!,G.GPWSV/#TB_KE!:E^7(0N5]9/+^EJW97$T@G-'^R_=)4UKG%QL5R[E=BM/OM#5*^>K\:(*8#:+O[[#8& -M_KBLO$,J%N*/1VKA8OQA-(\/C[\T[>Q"\N?D"SPJ?%U\G$9XX-,W!`CZ@YR( -M_DA_)<"P1(CPP"1/#1K"_NB>>U=I:XR%7ZG[.Y[2_YR.#3_A7WMQHF7\2X9\ -M*>LC&(*@YQ'5^$IQB/[U,U$)U#\%D?6/V!"G?8/0/%]59]]V+-\O._C`0+$" -M.+^#^0&DP/J/"='^LS[2&/"[)H3`[X1PU(?_B_==`Q^!Y08APR0P\BOR<_Q6 -M*6>8?+_0Z8"4A=@[A'S6"9$JE4=6ZZMM#.,T__`EA0]+9E6+*X`242<$`RX-.7/YBWP/U>Y?:`W%^#!'\V$+C,&`0N -M$0J!EBFM!2)PCKD(;`0:`3._TK__GQ7PF7`R2ED"?T>O2(9.H'[V11`*A":Z -M?Y"#X5=58*QO5_@*I'O$`F-]$\):X-T#%QCU33OZ`FN!P<#ZT8).O,5/[(>2 -MD):!J(1F8#_0N/D/Y%,Z(G]3Y0&Q8+)3:PE=FP%#!C>'Y,#BX\00] -M!1>"E(>&X`[R![SQM0A60"F*H5:?S&3A(Q@(83)*C+S`5F!R+V%OOG)$#;]^ -M?V6"*02:(/I/1320I!'6`EDM0(I=[_T.#FPLQ+U^'IVH4D$):%/071E"P%?` -M#*.FJHLN[Q(8",P57'-X!8D4ZU]K*<>!TT@65':Z$-&"P=(/#0A#F^#JH">U$%PT&/]M!_=M_;8C<.HQ/)C8&CE*=^?!Y\%0\'HPY]$>1/6\ -M!RN&NN"33!Q7EF>0N`\B$O>#=D#D@'\00*@O$!!241.$"$)EUH)09]`@?$7) -MB2"$1-40L'$R1N/7VYS>XSBKY=]:(/D3'V%B#*:5>5^,)D)2,%?0K]B:8A&N -M@N%6,,(1EXG0#SP/O!$J-\R^5LM_X(_0_!(D1+!<9XN$P(+-&O^F`M!G3U'[@29K:,"ZQ'A!*`GQ)L.,?R$UP000Z!P3.@\>N_*A&/!BL*[@J;!42@H:$TV -M(U"%8N&QHZ:04WCP]1;.)\"%I4+BYZD0G\@!WOBR"EV%HL)88<"75F@;N!7F -M"OFH'L)?Z#ESA\!:A<4,"R_#]&#-L`U+64@9-/,^"W>'BL?Z[II7;XCV'`QO -M"[^?AN%1X<$F,8P#,&&2"S.^2L/)H::PO:NG:3HN/8&&Y,^,9'3A@\`ZB&OF -M"[<,^\)![![4;,C*"!A&"F.(!<.#H2>Q*[P?M7TP#-4@#L,\%<2PN7D.A(_` -M![6B[%'6<`.18WB`\SV`#($/(D,<`^VDL%`?#0D_C@JU`*&!"'R]G:%V)25)@QU1P�_$ED,5\?701KP5O#'F -M!3Z'S5/1(1J$="A],!VB#M\LJD-?93S45,&7TKS$#@ECL\-C0@"22C'=S,=R -M6Q44C\]H(2SL\#I?2*`*#[\`Q$,I@/$P`8`\?$(N#_4*V.#GH?&AQ<$WF!X6 -M3QD7F4-/XO90R^H]!!]^6>D`XT/P8?[I?#BU2!\V"T*ASE?WH0XU?MASH!_J -M".^'XYSFWO[P;II'_!^N./LK4@'/Q$UI5&!`;!XF$!LP"\2+PWCX@9A]=+Y. -M$(&&%<0+(L-U'M6,2A1B*@M#B82"X:)6D148K:8-\A*5%QP8=T`L43%`*D(8'Q+O!#G -M$@.5S5:/`L'X6)Q&+"5V!CV)QL3MP7=Q/#"E6"9:'`4%SD1HH@0X&4%-A!:D -M*!8;V<1M8C=17#*<+1&[9$VP5V$4+.O@U$F>5:Y6EW:G!D=JI>N`ARM0N`S' -MA_>)/-]^HNXSH`A&("@.55:-",4$P!F6H6AE>2@:/>M;$L4>)@RT^791)(!E -M%,>OCHF.8BCAHW@9'BD"#=6+9EYG:--#I)/Y%"SRL>[R@*(NDIJ@SQ"D> -M^U:560:>HHW`=LLE5>P&%4^5S4(P0V31J$@`^Y=Z@N5_U"\AF9ZMVH+?Y/1: -M%8>Y3IJLHA/8K]=5K&5^4@>/?,I\HUDQC)A6O!8W)W6F!@ED<:&Q6SQ7A".J -MAJ6+.H0I\*VHSEO1#9ZR)7O&+\MC))4X2(12]C\5&+E&1V+!_>F`8 -MCBV+"0#,(C)CLQB5Z"P&BY2^J^,-[4"3TB==Y!NV">.9#\O!8^ZQ$2A;5(+R -M,D>4Q$5M86_1>DS0?%5.CXV+2M#D(O:XD5E2FR=_4527,(Z$TR`"_ -M/G66.(G(;TJL1*51.(9I#`-H&J.B%#^!RJ?Q,!!JM#)E8ZK:Q%^OS_3;:/L*-9H!QXU!O\29KU*XJ -M75Z?T,>O);QQ!#EO1#V^/46SDV&0U,OSH^!O[)AT/GS#3V2I;3;8;I1P%'\L -M'%VK$:R\*7A2LGQ\O,O;&X(Y9A[&>5M3N6##00HH/@Q][1Q[CR,S@&'F.12TPYBFKO)GH]H!+H -M0Q2/W!/&H^,1\E@$3MM6`"V/E;\?\N!1\TBAA"UE9^>88 -M'O>4J0CP8'J*&[NU=#V>`6"/X`4!*VR1]OB&1/M"+'./M,&6.944U7G*\02V.H-I7R<(%.03H`59`L2!?F"C$'*B.,ZPU0;I,<`![GE`%`N -M/F>,/D@OIJ)224%%]C;L)S8Y1\C60A)R%E!;6 -M#+.0Q($MI&=(=.*%XA$-ELL#8TC*0AE2"G"&G)JJ(1&A6`:1`8@2#CF)%#X6 -ME!.1G`)#!3WFZ]YIA061(T4Y)"5R"RI9QD/R*=6`-^`\AW.9P"MI;"LW -MF#.1HT&Y,B<2/=L\`$4V(S7,H\@(5BG2(;JA2D4://FI2B17))4@LRF+I$5J -M'EZE0L1<9`?9"N,ZKM3L"GK&>E%B)&K`&`F-Y$$I(T$%S$AG9-'Q3#$*I4:: -M0D>9C+G9A3;R\\"-)!9X([]\G@-QY-M()6N.1$B -M$V"245F'@QBA7:J5C(OJ)"6U/F244FDP%2RQV*UL$I:-;&2=(!*LXNB*YEI#DO>!L:2;M>/Y0KA+'F51`&H -M)9-_6T#"P.SW;HP"B$LR`>:2N".;22P8T+P_,'_R)8$/,U7?+ZI91&P4$&LB -M!0R3E&9)/J: -MET63=$G2Y&EGUN``34U>3.FQK,GGL&OR)Y.8+!K,)LNM8IKCX-JN;9#E, -M.?^+%V%.:&1@.%F,!`F;@W>29J41$4\F%LB3`$[S9++9-I:>7`NT`-B30YB?U'L2^7">#$:E -M)WN`]DFZ:7YRVKR?C`7+MOZ3?6#MXA2`!IMNB",<**<@"$2M@1VC9]H*'-!',K$@ADY`\MB1GO"%I>]7TXQ>\RB_,!^ -M_V"4/4P9)31*!4CV%''9/2LU/$I;@H_RF0*D=-8(*0\#^E'7T9$R'*JD/(PJ -M&9J4/2V@M\I(:/_0A7E2[556 -M&X&5^0*N)9*!$7RL3,4D*Y>5)1$=B[/2)P&ME(\V7Z:5SEBRKV^4H6KYHS[_ -M,L.5*%62JG;17*F105>J*\,#[,J*0@"Z52JO]$G0*VEXC$UX*_:2#[BOO/WU -M*]4D2MZ`Y<"2O%"P-%QA"1.6"\N&9;E8<"FQ3,50+%$],U^Q@\92NMBQ!*GY -M)=MOFX@BP88A97JRC%YP5J6++,OVB\N2L,@DP(/A-%FD);U++,[R3(A&SB7V -M+!W//\LF@IYY:)DI=43@OG9\<4NE)>`Y2?-(?KM`+>V5"FCW!-7R'USEVUMF -M+:V^W,`.1UNQ`:-,)@XPD\>6$EFS9619Z+BVQ"DC!MZ6K`$0LT*WKLSMM%N2 -M1L^[W\",\EYS):`'-;!RH+4-(M3"):AYT9*XM`6':)]6.[X@9;(A?^GEA5A* -M+OT$-=C19152CH"Y5$?U+#:7"Z?Y!%59N0&Z%%W.B$48IXR@RA(VEV>$7J7R8A`:\Z59R;G\611++[/-(@SK90X'L>@([5[J'5X#]"_Q)6"U>52^I!)( -M@="7A.CU)2J6%@DJ)>=&`N>7Q-=S[_SMZ!"-WE]B7/R7]V0`9C$P2K^=5I)L?7FEE4KAMO -M,X&+IM3(:%"S\$G.Y!!OAM.9]5W<\`PUF2KYVRC_%KO'UU9M@ST3,@PKK*0< -M+_F94F4-Y#\32>"KT.[,-7N!`=86IN3OSE9%7Y*_M:LI5[8-%>S+#W3E&F: -M5VJ:>XN;IAU-IXG5+,222ZK$0HF@YA-AJ`GQ*FK>,'WY-1?4W.>^-&98LPG8-)'>&_.>\5-RP31B@XA:4&P& -M/TA&JP-"YK1AQ=D='';R>/D#">F4)GWWM-GVS+G&25D+3;_5LF@3-%#:C#(F -MI%6;)PG6)O'+?55$>GE8#?U&_> -M<_B;0FA=;Z\/%VN@&(T8.!F%",XS=:Z2P2E&>'#./".<,FK_@(43&F%SK39J -M.-47N>9+PH=3^'H59;YUF:HQ)DY]8XJ3)D*B7I<^YF+-Y@%IJC>8MAP(":C> -M.'.<[M.F8H\S3@WDY'("^6:31@-0NQKE5K -M&Y"=M%-/,+/3%GM&:(5`.Z6=!CGLS[636I;Q?-UX/.N""Q%PYX>5G3/NW'B: -M.SG,1U1U9_.UW5F0/F_N0M^$]$[&I_`/WVDCTWI^F(YSMAXGFTK'@Z$JW+&$]IR\:3;LGM_'CF -MK/NO1EZOMT):79R@AYBEY$1>OBFBCG*^CHA_G9KG\X7DF -M+'R>!(8?@]R7-71/0)_N$8J>AMCZ%M+3]ZGT+%J/'=MZ#>JXM>4Z34IP?9J: -MI4JB64\$J^5S+GE\;#_C=Y$3X%9_*W%6*FVT/DBS/4&GJ8AGLD9Z[OFX2T.K -MHY\E]LDFCMYS;\'W+'?Z/24ZJ=?;P#E4VT#X%%8G";[*PU\1P^N:HGJ>YA)' -M/E\/L`''TSX4U<;U3/YA/J5\0F,DG*F.'VK?^'R^]@`6HD]KVW/!]`F?)!.G -M/ND4_`?6IZZGI?'Z='7*/@UE1]%TA^U3:.D@R'W^$WF?5A`C+X5Y,RU@71,6 -M7(^?QTV--/-S"[QGO36HDFT$4X+J9QGE^MG\R'Y2KK>?$&KOIXKX!FI=M7=2 -MAY$,YD\U8/KSK>0?8'_*.GT>\$_YIYB*_DF-5L4^DGN<^T]Q8@W3_XE."(`: -M&YJ"!%`ZX0%4Z*:Q\,=&I5?8!QJ)!>VPA/4!A1D&1$F205@,:!59`WKZ+31U -M0)NL/6P*!>C!0X)3+8':#%&@K#D5*)#CC.H")?^Y76*@=X`9:`O4'ZLQU6SJ -M0,.H5%"6YP\4R%H9B58,0;V@CU'6]=@Q"3K!9H(F2@]HN.GF@6XZC$W;L(*6 -M,K.@"0#87$*)0.D0B<>9H.>L2L4%BH+A2UJ -M3FRASF6YM2(;.KTT30CZ0NF$'6)@H7)O&"JHYAD80P&+15@0[6A!@G>LL]TV!H7%8>Z]\BAYE#Q,W?`EJ`.316T -M0Q4=[U!2RY*XK-R.56.G25U_F6M\:&@:9YL330::(A^B`='7X&"`(+HE88F> -M?Q*BR<[$*4.!Q,SS>\U$1+.7$U%QA%/!(JK+V,`810T&4XJ.*,_W(SJ7#(EN -M%D:B18D)@TD46X$2?6/,Q%BB0E0V3*4T.CH3K1O41.=1HFN=**"+,+I#^(DV -MI->BQLZV*"V-)%,KW:E`6HT"%VW"M%VT&K,Q"([6 -M1Z%1X]R_J&=4`M6OH6GO82<'D[LHGV*4,>H855975$6HE%$6[_OY,NK6TXP: -M8CFCU(N;I2T!-)H`G:"\H%6H%E53"6@,'X)"&A^W9\,[,J(W4/+K/?H^6 -MQ^*C>FT$!>8@5@V-@ACJB,R3*("\,W^TJD*:^(\BCLA7`E*GJ."Z28T@G4LN -M2#XDMY(;(:!840HP!5[<4`&IP%?`*@`20`EH -M!9;<6.XLMY:;*P!&V`ELN;_<0($9]T6@RLT1\`B0N77<9VX>MRWSQUWD_CC4 -M`(;<-X$B=T&@)P#FKG,'!9K<%(&E0%,`+!#EG@IX!:C<.6Z*P)7;SDWH+G0; -EN@_=B.Y$MZ)[T?E5&IHH&Q=N>_C&G -M-$G]+L[\,B<7%8&$NO5K31*Y>"D^*ZG,Z=H```"KU50H$1^1S``!GP&@'P`` -MLZ042+'$9_L"``````196OTW>EA:```$YM:T1@(`(0$6````="_EH^`,7P!I -M70``;IBIKOMK%/A?-TZV0266G?2,[/?\,JE6` -M__C/SA[W1?*2J9Z!O$&YKI)!H8*&L&E>0J^FIJ\7+Q<`%!+!PAHTY\490```'$```!02P,$%``(``@`"(2# -M-P````````````````D```!T;7`N8VQA"%3```%!+!P@+ -M(*8V:````'8```!02P$"%``4``@`"``(A(,W:-.?%&4```!Q````%``````` -M````````````````345402U)3D8O34%.249%4U0N34902P$"%``4``@`"``( -MA(,W"R"F-F@```!V````"0````````````````"G````=&UP+F-L87-S4$L% -J!@`````"``(`>0```$8!```7`%!R;T=U87)D+"!V97)S:6]N(#0N,"XQ -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_compat_zip_2.zip.uu b/thirdparty/libarchive/libarchive/test/test_compat_zip_2.zip.uu deleted file mode 100644 index f8ada3116..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_zip_2.zip.uu +++ /dev/null @@ -1,8 +0,0 @@ -begin 644 test_compat_zip_2.zip -M4$L#!`H``````'V59CT````````````````%````9FEL93$M2E5.2RU02P,$ -M"@``````@95F/<>D!,D&````!@````4```!F:6QE,F9I;&4R"E!+`0(>`PH` -M`````'V59CT````````````````%``````````````"D@0````!F:6QE,5!+ -M`0(>`PH``````(&59CW'I`3)!@````8````%``````````````"D@2D```!F -::6QE,E!+!08``````@`"`&8```!2```````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_compat_zip_3.zip.uu b/thirdparty/libarchive/libarchive/test/test_compat_zip_3.zip.uu deleted file mode 100644 index 8e3613985..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_zip_3.zip.uu +++ /dev/null @@ -1,18 +0,0 @@ -begin 644 test_compat_zip_3.zip -M4$L#!`H``````-=0SCX````````````````-````&ULI9/12\,P$,;?!?^'D0??DE1%D+EU0U`<*`RWH6\E -MIK\2%IZ<5+[RQR#V$ -MPMD`G-S]"G5'UK"\A8&)L@B:'!-4;V/_@&E-_X$T&6YHJT25! -M+6H,@E\H^L#HD*!@N;:319%I_+YX7ZT;JA/D-LCXD/,6I731AB<\Q=CZWT\//Y<+1-JL*"1UCLD!?AD -M[@*R^"+:%]PW$#I4V2Z.Q?2M^S`4G?B,L8E0C.@V&?0KY]]"H32P6`A)UY@6 -M;GA]P[<%01/9@W\$3`L``03U`0``!!0```!F;V\*4$L#!`H````` -M`(2N\P$````!`````,`'`!B87I5 -M5`D``PM$QTX+1,=.=7@+``$$]0$```04````8F%Z"E!+`0(>`PH``````(.N -M`L``03U`0``!!0```!02P$"'@,*``````"$KG(_Z;.B!`0````$`````P`8 -M```````!``$`=X%``@``8F%R550%``,'1,=.=7@+``$$]0$```04````4$L! -M`AX#"@``````AJYR/^$Y>\P$````!`````,`&````````0```*2!@0(``&)A -M>E54!0`#"T3'3G5X"P`!!/4!```$%````%!+!08``````P`#`-L```#"`@`` -"```` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_compat_zip_5.zip.uu b/thirdparty/libarchive/libarchive/test/test_compat_zip_5.zip.uu deleted file mode 100644 index 9dce4521d..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_zip_5.zip.uu +++ /dev/null @@ -1,242 +0,0 @@ -begin 644 test_compat_zip_5.zip -M4$L#!!0`"``(`-H0?CX````````````````3````365T861A=&$O2F]B7U!4 -M+GAM;.U7VW*C.!!]WZK]AQ3O8["3FDU<<:9:-OBR2V+9@"]O&!1;:X$H$,') -MUZ]DXTMVXPFIS,[3=/DBB>[3TE&K6]Q^VT3LXHFD&>5Q2ZO7#.V"Q`$/:;QL -M::YC?;G6OMW]_MMMDCTVARF-A4.#-1$7TBS.FG*TI:V$2)JZG@4K$OE9+:)! -MRC/^*&H!C_2"QB$O,KUA&)>Z<:TG"D."[QH[F\?4CTC!T[56PFXR>H`MBJ)6 -M7-9XNE08=7UJ_S7>6GVA<2;\."!'J_!]*^UDL7O#.#.D5%_(5UU^WEK(FCS+ -M9829?C#=)%G(@SPBL2A2*DBJ'9A;_P#F]@ZUN]T&^8I)Z:4?4W$1RW9+VRU. -M/EJ2#GF*>$C&L9]D*RY*(\]G.;ES,$J@:T.P1$_0LV%1H`AZ&/J`9F`!N`4L -MP<1J_&_HN;#`B$'W"D*0XU:@[!*E/\?H&0YBF@"+`*QE!_1KU8>$%NM

    ;*(`G",>5?B -MB-DD9%Z/%=+?GZ[I]9R)MP;SYMF?>'G8M0Q_C9-&X`N<2;6ULC/!LBEC`[A,2N8`=#%CJ+2X']XO&B$&G -M;\QB5'R">5O].-[*]`I3Y:;6K7[,T[OVJT1_/O?+(M,<\$6;)Y1DP%BG+$79 -M:>J_D-6V*9X3J2\K:%/6%K*4=>JN7LFM17R1I^3$H:HT-@FI/Z8OI'3TD`A9 -MDG"8\H2DXOE$Z8`RH:%859ESHZZ*W7\G_MI%5;<]0I,D%XC&YZB$7/`Q8200FOX^:'D=V.+*C63$ -M?Y)WBK>P2\T'R_H@;B0#P)$DBIC%Q?89UC8LA3D?JT -M$@]*?W\A[<*'YKOB&2>FNR=W.U9_[R`'LASG\<.QO=ST7,OKE!O'TW/:&UL -MK9#!:L,P#(9?)?A>RVUAE-"TMYTZ&*R%7H.MM":S%"QOSMY^[KIF.PRVPX0. -M0O!]XM=Z.X;GZA6C>*9&S;51%9)EY^G4J,/^?K92V\UZD*Y^C)[2WML>4U4@ -MDKIL&W5.::@!Q)XQM**#MY&%NZ0M!\B>'&>!A3%+,"L8+HZBO@Y7IHMMP,RQ -M5Y_:4?RDS3GKO-0<3Q?''(X/NZF? -M@O3X5F(X@0D=!W%L7P)2RM$GC&KZ7/\/G[L=5+!Y!U!+!PBV6O$]TP```,@! -M``!02P,$%``(````VA!^/@```````````````"@```!$;V-U;65N=',O,2]- -M971A9&%T82]086=E,5]4:'5M8FYA:6PN2E!'_]C_X``02D9)1@`!`0$`8`!@ -M``#_VP!#``T)"@L*"`T+"@L.#@T/$R`5$Q(2$R<<'A<@+BDQ,"XI+2PS.DH^ -M,S9&-RPM0%=!1DQ.4E-2,CY:85I08$I14D__VP!#`0X.#A,1$R85%29/-2TU -M3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/ -M3T]/3T__P``1"`$``+4#`2(``A$!`Q$!_\0`'P```04!`0$!`0$````````` -M``$"`P0%!@<("0H+_\0`M1```@$#`P($`P4%!`0```%]`0(#``01!1(A,4$& -M$U%A!R)Q%#*!D:$((T*QP152T?`D,V)R@@D*%A<8&1HE)B7J#A(6&AXB)BI*3E)66 -MEYB9FJ*CI*6FIZBIJK*SM+6VM[BYNL+#Q,7&Q\C)RM+3U-76U]C9VN'BX^3E -MYN?HZ>KQ\O/T]?;W^/GZ_\0`'P$``P$!`0$!`0$!`0````````$"`P0%!@<( -M"0H+_\0`M1$``@$"!`0#!`<%!`0``0)W``$"`Q$$!2$Q!A)!40=A<1,B,H$( -M%$*1H;'!"2,S4O`58G+1"A8D-.$E\1<8&1HF)R@I*C4V-S@Y.D-$149'2$E* -M4U155E=865IC9&5F9VAI:G-T=79W>'EZ@H.$A8:'B(F*DI.4E9:7F)F:HJ.D -MI::GJ*FJLK.TM;:WN+FZPL/$Q<;'R,G*TM/4U=;7V-G:XN/DY>;GZ.GJ\O/T -M]?;W^/GZ_]H`#`,!``(1`Q$`/P#TZBBB@`HHHH`****`"BBB@`HHHH`****` -M"BBB@`HHHH`****`"BBB@`HHHH`****`"BBB@`HJ+RG\O;]HESOW;\+G&[.W -MIC&/EZ9QWSS3XD9(D1I&D95`+MC+'U.`!GZ`"@!U%%%`!1110`4444`%4QJE -MF=4;33(RW2J&VM&RA@02,,1M)PK<`D_*W]TXN44`%%%%`!1110`4444`%%%% -M`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444` -M%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4 -M444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!11 -M10`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%% -M`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444` -M%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4 -M444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!11 -M10`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%% -M`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444` -M%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4 -M444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!11 -M10`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%% -M`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444` -M%%%%`!1110`4444`%%%%`!1110`4453FTNSF9FDC;+W"738D90TB!0I(!Y`V -M+QTR`<9H`N4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`44 -M44`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110!__V5!+!PC?FNW> -MUP4``-<%``!02P,$%``(``@`VA!^/@```````````````"0```!$;V-U;65N -M=',O,2]086=E!(7($,8L%CZ=^_?W_VQ]O[;G_2Q^0% -M/2W6E$RD&4O0*#LL9BK9&D9>L/W]Y<6NQZ,,T4/SXBB)0X9*-H?@[@!(S:@E -MI=:AB9W1>BU#+/T$3JHG.2%LLNP:_,\,]CE'>DAU#JJR&DZ,SXQ:^,)_7Q>/`_?=N!F=6^/6"J'P"4$L'"%!53P;H -M````/P$``%!+`P04``@`"`#:$'X^````````````````&0```$1O8W5M96YT -M:SS^/_T>)G(E\HNT$.!: -MYK:,8=CW4!A`<")D4=H84LH8\EUA55?*Q+"T=G&`L[.\+BZ6Y0&)+*J8K@WGY,N($BTLE>-C"&> -MZFQ9"V4-IOA2&+UL,F%P>VZP-TVFXTDT[G&?\AZG">V-(A+UID-5,51/9/WPDEAR(WS(9C9NTK,9+VL4BMUJ^I,*P'!>2,+ -MJ6YBZ(51IWE3N'6MA*,(@E.52_<@1XGTV3XE=!`&W',)&SC9+;8K)3.=BYEM -M!\?P_7']OG[X?'F"`/\K`J&/@N@G`+HALB401/L^'031X#O9;O]`2+OX;P0\ -MA\!GOSS`..(_74"9SWEG`Z]5STB[>JT5./U#X>/U%5#P^?S6@1CB[<\[W/T" -M4$L'"%=?-U>$`0``A@,``%!+`P04``@`"`#:$'X^````````````````1@`` -M`$1O8W5M96YTF^?M]U]]NVLT1]VV3?^^ML'OJ?==WI9>.?SXX]UGSYR3]^!EZ]\ -M[G1#KO3\^#_<.T-RZD$BT=6ZKKRJ]2WE*UP^ -M3$2IS3WM_=\LG?M3$JM>Y;8;-^_:87EFRZ=(M)3R]D]L[>_LN>3`7:^2N&P+ -MC_=UMF_OIP+22/)P/YF=VV[8>M71-XI)K.;MW5_OZFC?\O1K]R=Y7TNXO[:+ -M&R31NHKK.[A>W-6SXWHU3<.\;Y/$RI>V]6UN[Y<'UI"XG-L>'.MIO[Y_0X&X -ME,?OX_%6;WM/1W%:OI$DY2]XFQOZ^[;OR)PD'Q]?M?O[!SKZ7<=;G^/YV?M_ -M:!@GW+[2/MXN/IY&HX?H7[>.1X%:):-<#FP)7!9:\35Z[@>C^D\Z* -M'GOYFK\ERARG#!WCJF&/==C#CG-[\<1X[L\6SFOIM5M2-U,W>9P&B4PJI]F\ -M:3L]E-U'6@R3BTMI#E^][#K-QVG@#81;DX6-VV35_]Z^K]BX;"DER-JW;V(. -M9"_*^1E(F(;+=0G+&O!]WRLH'VL*?\KA-GWZJ[W/A^!_8T8?F(7_TX2=\ -MW/XW.7LS>0<*%5(EM=-@QTB79_?^2%\R'QT01W(K@WAH^6\]F7K?J[')MK_ -M<7GI:G%89&[_2\H_5,4[/)3.WWA8N)=U\4>\Z;!0[))BEUQ.:=DF+ME5Z4)5 -MLJNR797LJFQ7Z4(OV55A5\FNBGB3*)M`E('/-7J`OQOZ>5$RXYG_XKJ;5-+) -M(#^_-R%^>Z+\G.;1#)IIM_S&?A[Q6QQK)N=9?E%F<*3,ZY2D:EI(3_'^$E1' -M%_.;LX2.9UZFR^DR\E*!L]S%/3?R#+=1'[^M%A\IZLS!7NS?UDK\!@L>_S"/ -MSJ.6A_TC;N%^7/P1?\KJIL72?6XW![%(YP:+TMU?7J=3]5TCZ^.9Y;/WSU;Z2&>]<6/ -MQJ-5T651.=A@B!A?//L[VD4JESU"X9(0OD?54(71;T@&3^3HN:-4?VY)_0OG -M*BM$6UTD'*VNYCE45]76\$3B3JENI:[I*S5=<[E"FA%0'MHW,:L;%!=_VE?' -MR]]^NVD7S>9K?7]B_FIE=6R+LBFVR^HO?,GU8MD)U\_+]'FB*%8O5<1:1$)) -MQ*X4:@E%3=.MNP^+6,*T*BLJ$Y6K*_=7NBHK*:H_SA.."OF;Z<+A0JDP_PDQ -MC8IY_O.XF83KH1)WQ6%A/))G%>;)OG_B[[DH_F3]R>-M]2>#(;[PY^Q/7BHKJ*UMXL+7V>=9Y,Z-NN,7;H1]&?@* -M5(?MMA*WN\2IU]6XW96A<,%\S0SZ)4EQ*ZZ\G'!85ER*2U<]JJ0'"[V&%M*+ -M\N2@-Y3K,G2?UZVH+I=F!OR-JJRI?J_;X_$4:`&/IUS)X3NG9WY!OZ;OTGRB -MNGAN;76UV^W)K:VMJXZ$J^U#SII5$W>[X_&BFIKJ$D^\UOFTQX6OVZ)JWA7N -MV77RXBJW%JGQ^35#=DN*41J\(A*\1&F/F`=YQ,7;5;FL,29'OE#3&W09+G]L -M>L3HC`;GY88#JEQ`_$AXG3G\T"[QNW,1-?)9%U=B3/(::_A2L3N=7K"GKI93\HQ7\#8I6I;@\:E7I_'JR\/^:Y7 -MM4KO-'.&G#?-VZK[##-G=I#[HF*.JDWSSY!C`?Y;;8,T:WYN[$]5.6@\HL@> -M0S&\VT,^51YP75EUD9Q7IL[4"B-!/2]H5'KT&;-4N7Z>,C.^JLP=ML]&SYR@ -M-_ELPOPT7D6;J8O/QKET=27GKVW4GG?=^VHE$T,\'OL4)CHB]EGP6;OY_D>B -MD5K&I\RG6AWA]KKL?8C$2]Q\3>(>7FI;%@>-,I\[[,[S2_X'K_.BJ+Y]94+_4+U -MZ_?P[:NK#;@N7[AP^:)&US>"ABG[XV]+PB0_86S;"FY[A\1M5,K_`H7I_DTH+3W'[=,MQ:OLNO\ZW7\\H+7%;8 -M_M$GP-?L-#W/WY@ESI/H/(B>>$F4+\'$Z3KG6^L\#M&)ZU-;PU?+N78!^T%4 -MW'E!(0)=`:$']:5NLR<:7"_4.0M$W9R0YI)*"X*R]:0JAR-:04-,:^_0_-,J -MW`&OD1\.-!8M*C,4;WY5J6>YDCLM,#U(Y"&-Y_0VSTGF/9Y2W2Q^5<\_F.=?F`@W7CB)^(?.L&32:4T\UN5LB1;0 -MRDPA_.5^L5Q1P\+GEW/TT/0%&Z1(V=7A.0$]6&X:*;X`><&OJP&-;\[BH&\# -MUTU^$P.\X6*_J!)RQ)*LF%?58SY=BS\^TY6_Q.W3U4A5KL>E:Y'.F;(>71B5 -M4+^^>R -M>U*[L__2S;.MI7W]-PQT=W;ML*YH;FU9L7&EM6Q;Q^8=`WV]W9NY<[Y5N6A1 -M33BJES7P!+;YP?=1/-]``=5,G==$.;KN"FJF56F@%;:257%]&VZB# -MQ^_@47W4RR,W9[>'/W?RF+6\12>7ME$[;Y7BV@!MYWY[ -M>XNJ>Y7&KDWFZZAI=>ZNPX=.6?MZZ; -M>)8ZC]2<<^N%5++U<;*,W%]Y;2 -MC]CO;R]-;XS[LVNG[#2^E1WO]SOCTY/'^\?-[-HI.XVG -MLN--TQG_X.3QYG@HNW;*3N,;V?$AITO\:/)XWW@@NW;*3N/I[/B`TR4ID\=[ -MQWW9M5-V&G^9'>_C+GO-595<'")[VY!AD&Z\0P:77=,?SC]622TK[5$?&/O' -MO$SS^\GPGR7_)XP]QHMEFN0W1\G\^+%B-Y=GAT)DALY0Z./'2LU9_^@B-I*@P5>& -M=[_RM1OWSQF_5VU;573'"`V>4LFBM"1G1E9+"8V:A#G4>(2?"XN^^BWZ`EGB -MR1/JG/N^-GQ7T=#0_D*>3H,X\UJQI`Z.J%\:-].#IV*)`\;!;VWBPXV:E`Z, -M6M;0GB)UJ(A7:R6KOY]G?S;H>29XT\VFJ_5%9?V:-0.W!^?N^>JH??/KQP1- -M9'!X^[^(4I3FO?)5R]P2C6UR1F6$D9%OV$_ -M4A>/%UM+$L5C2_;2P?&#ZL'2@_,K2ILW[+V4;AN?>%MOR_!UYIU9I`8SX[2? -M2DDG)2TL&K(:56M/14$Z^U*GK?B82EQ-FYWC,TS]'NG>PJ(F]4ZIR3J@%B94 -M:^+M5^A6\Y;QXF;S@,B,"#4P+IFW*C0X)AIH.-&TO]W0, -MI1-%IKI7*J0AIT"7DG6DPN@7V8$-9T:;K()ZI;DA-'S309H=>#W1.+RZ(O/KK[C?EH[>'!-\S\_U;ATJ/F(.6A/ -M:&E&\"N0&!R-"=YF>.CVVT9X)J)>%2-29F'#`^'U!^]L&K*6\M!"\>;==PZF -MBPM&ACQCNG6G>FBOO?MXYE:JOU71K)522IZ^ -MT#^:/)M\)_F_R9/)7R?/I#I26U.=J:Y4=^J:U+6I;:F>5&^J+]6?NBXUD-J> -MVI':F=J5^I/4]:D;4CD9Z5OJ.])+T']*/I6/2&>FL]*Z<*\?D:7*> -MG"_'Y6+YN?\#4$L'".*$;,_\$```%%@#`%!+`P04``@`"`#:$'X^```````` -M````````*0```$1O8W5M96YT&5D1&]C=6UE;G0N9F1O -M8RYR96QS98\[;@(Q$(;[2+F#-7UV%B0B%&$H@"(%4H2VH$,C[^RN!7[(GB`X -M6XH<*5>(Z7B4\_J^?_Y^?F>+LSNJ$Z=L@]\U?$OW-H7%_/5E -MMN4C2=G)@XU9E2.?-0PB\0,QFX$=Y2I$]F72A>1(2IEZC&0.U#..Z_H=TRT# -M'JFJH=2S:,`-"[4DA)O=:KE?NRB7_5=3%32HSU;#MH1L+I&?`CAK4LBAD\H$ -MA^>8K]X)%G5,UHM8````1&]C=6UE;G1S+S$O1FEX961$;V-U -M;65N="YF9&]C58U!"L(P%$3W@GH=Y#7K@U/9TYQ,S? -M>9XL&<#?HF")N9!4=6,R@)G!O]N4?`%02P<(#(8J/94```"S````4$L#!!0` -M"``(`-H0?CX````````````````F````7W)E;',O1FEX961$;V-U;65N=%-E -M<75E;F-E+F9D%W,%HG]&TD%)*G*P;"(0P^Z)Z -M-!XSXP>V&I*S99$C]0IU=GTL)?WZ/NGK>EMOSWY6)\[%Q:#AL6E!<3"Q=\%J -M^)1A^0+;S>)A?>29I&;*Z%)1=2D4#:-(>D4L9F1/I8F)0YT,,7N26F:+B%?BKT]JYQM02P<($KD,RKT````&`0``4$L# -M!!0`"``(`-H0?CX````````````````;````1FEX961$;V-U;65N=%-E<75E -M;F-E+F9D3"HI(8S?B`>P)))W8@,G4_$COYL(C -M>05;H0O!]7O?]][[^:KJP=V*!X5HV2LHA82"O.;6^JN"G,QJ!_5AN:A.=J#V -MR#H[\JFA>QY;5(RPCPJZE/H]8M0=N4L4SNK`D4T2FAT.?<2UE!N46YA,L^1, -MAL+7TG`.FA3@'$4L\6=0F)8UX(3CWR=C\@%02P<(`"(GQI@```#.````4$L# -M!!0`"``(`-H0?CX````````````````+````7W)E;',O+G)E;'.5D,]*Q#`0 -MA^^"[U!RM],*BLC6O8BB("QK[Q*321ML_FQF*O79//A(OH)9M:`K>_"89.;W -M??F]O[XMEI,;BF=,9(-O1%U6HD"O@K:^:\3(YNA,+"\.#Q9K'"3G&>IMI"(O -M>6I$SQS/`4CUZ"25(:+/+R8D)SD?4P=1JB?9(1Q7U2FDGQEB-[5H9>J0&P%7 -M=D)]&=3HT/,];L9LA*71A!M1W.A&K+-E^Q+QCX&S*@4*ADL5'$R1MN`3R&RS -MS4P8$U(._80*V*\PTPEJN$.66K*$5?Y)_=#VHWOTT@[E[>KZVZ?>X_.O1L#- -M()X17XKPJ_Q\\P%02P<(MR#R__,```"Y`0``4$L#!!0`"``(`-H0?CX````` -M```````````3````6T-O;G1E;G1?5'EP97-=+GAM;*62STK$,!"'[X+O4'*5 -M-M6#B&S=@RN")P^^0$PF;=SFSS;3I3Z;!Q_)5W#2"L+"MK+>$F9^WPGD/$#-J=K%B#6*XY3S* -M!JR(A0_@J*)]9P72MZMY$'(K:N!797G-I7<(#G-,#)9H&]"B;S%[&*@PJ3MH -M(\ONI]9DJY@(H352(-7YWJD#3_[C*"@Y]L3&A'A!#8P?<6@58;<@L;_@(<1< -MFP&4\K*WE*!T3].!!8F7_W#,LP-E3H"GV"S8*T3]=[!_U7VD$J@\+24M]B@Z -M:9?!G7%(-U>,#S1R"_.3>'I^/*`:FP[N+4`]A?AXLO3Z!E!+!PA?-651$0$` -M`.<"``!02P$"+0`4``@`"`#:$'X^,JA?,K\#``#G#0``$P`````````````` -M````````365T861A=&$O2F]B7U!4+GAM;%!+`0(M`!0`"``(`-H0?CZV6O$] -MTP```,@!```:```````````````````$``!-971A9&%T82]-6$1#7T5M<'1Y -M7U!4+GAM;%!+`0(M`!0`"````-H0?C[?FNW>UP4``-<%```H```````````` -M`````!L%``!$;V-U;65N=',O,2]-971A9&%T82]086=E,5]4:'5M8FYA:6PN -M2E!'4$L!`BT`%``(``@`VA!^/E!53P;H````/P$``"0````````````````` -M2`L``$1O8W5M96YT&5D1&]C -M=6UE;G1397%U96YC92YF9'-E<2YR96QS4$L!`BT`%``(``@`VA!^/@`B)\:8 -M````S@```!L`````````````````RR(``$9I>&5D1&]C=6UE;G1397%U96YC -M92YF9'-E<5!+`0(M`!0`"``(`-H0?CZW(/+_\P```+D!```+```````````` -M`````*PC``!?7!E&UL4$L%!@`` -0```,``P`I@,``"HF```````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_compat_zip_6.zip.uu b/thirdparty/libarchive/libarchive/test/test_compat_zip_6.zip.uu deleted file mode 100644 index ef6d19126..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_zip_6.zip.uu +++ /dev/null @@ -1,10 +0,0 @@ -begin 755 test_compat_zip_6.zip -M4$L#!`H``````'@3-T`````````````````6````3F5W($9O;&1E'1S;VUE('1E>'0- -M"E!+`0(4"PH``````'@3-T`````````````````6````````````$``````` -M``!.97<@1F]L9&5R+TYE=R!&;VQD97(O4$L!`A0+"@``````?!,W0!5#6+\+ -M````"P```"L``````````0`@````-````$YE=R!&;VQD97(O3F5W($9O;&1E -M'102P4&``````(``@"=````B``````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_compat_zip_7.xps.uu b/thirdparty/libarchive/libarchive/test/test_compat_zip_7.xps.uu deleted file mode 100644 index cfc8ecb23..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_zip_7.xps.uu +++ /dev/null @@ -1,357 +0,0 @@ -begin 644 test_compat_zip_7.xps -M4$L#!!0`"``(`$"K-D`````````````````3````365T861A=&$O2F]B7U!4 -M+GAM;.U7VW*C.!!]WZK]AQ3O$W"2FHU=<:8:&WS9)3$VX,L;!L766B`*1+#S -M]=NR\26[\83,S,[3=/DBB3ZGI5:K6]Q]64?LXIFD&>5Q4ZE=:LH%B0,>TGC1 -M5%S'_'2K?+G__;>[)'MJ#%(:"X<&*R(N$!9G#1QM*DLADH:J9L&21'YV&=$@ -MY1E_$I2[QH[S%/J1Z3@Z4HI:=<9/=`617%9 -M7%_R="$Y:NK$^FNT17VB<2;\."!'5/@^2CE9[!X89QI*]85\5O'SUD)69(/+ -M"#/U`%TG68YX2$:QGV1++DJ0Y[.JM[$/+;OFM%[LW -M`]`!;F$,O98]B.U_\ME4I;V*,8=]A+D6$[H!E@96. -MZG&ODKF6?=HSOFG*O^27_#2Q7W<-&;/FPX-G\+*/XFK@VS(?]&1>>('.+@VV!:,G\8F4@R-9<<%>>,S36%IA>[D_Z+-"&E@-Z?QX/61"MV70R2^91`(XVZR"/ -MF(Y#YG59@?;^=`VOZXR]%1CUC3_V\K!C:OZXGH.I#UPV'-DN<\%X>)YWULL0 -MY[+E,-'&53T+)\-D?G4#SK6^Q5BV;D\G.@O80T(BU#4\US.\T0Y?WSCC^FIF -MP^:ATR^";_.\)7\<;VEXA2%S4_-./>;I7?M5HC^?^['(-/I\WN())1DPUBY+ -M47::^B^PVC;$)D%]K*`-K"UD@77JOE;)K$E\D:?DQ*"L-!8)J3^B+Z0T])@( -M++DG2KW1(]R4#TZ_$W]MHJK9+J&+ -MI:ADM_Y');OJT1EEI_3?.6?B[O7B)!"@C[Y"VA\8'71S%>)]2#VF%"/7EUSG/#'@J4A] -M6LD/4G]_'%J<,5^^\@'+DF5:+Q\WFY[3A^>71!>?6E`="JR`4D'=$U8I6-]\YU^ -M;*<47S?^#[-?\:;ZKW=.ABLA5Z#K;0FLQ0L;\[>?NZZ9CL,ML.$ -M#D+P?>+7>CN&Y^H5HWBF1LVU41629>?IU*C#_GZV4MO->I"N?HR>TM[;'E-5 -M()*Z;!MU3FFH`<2>,;2B@[>1A;ND+0?(GAQG@84Q2S`K&"Z.HKX.5Z:+;<#, -ML5>?VE'\I,TYZ[S4'$\7QQR.#[NG#VKF25)+%K\H]SNEOD6]@22FU-^#W$'I -MGX+T^%9B.($)'0=Q;%\"4LK1)XQJ^ES_#Y^['52P>0=02P<(MEKQ/=,```#( -M`0``4$L#!!0`"````$"K-D`````````````````H````1&]C=6UE;G1S+S$O -M365T861A=&$O4&%G93%?5&AU;6)N86EL+DI01__8_^``$$I&248``0$!`&`` -M8```_]L`0P`-"0H+"@@-"PH+#@X-#Q,@%1,2$A,G'!X7("XI,3`N*2TL,SI* -M/C,V1C'EZ@X2%AH>(B8J2DY25 -MEI>8F9JBHZ2EIJ>HJ:JRL[2UMK>XN;K"P\3%QL?(R;GZ.GJ\?+S]/7V]_CY^O_$`!\!``,!`0$!`0$!`0$````````!`@,$!08' -M"`D*"__$`+41``(!`@0$`P0'!00$``$"=P`!`@,1!`4A,08205$'87$3(C*! -M"!1"D:&QP0DC,U+P%6)RT0H6)#3A)?$7&!D:)BH*#A(6&AXB)BI*3E)66EYB9FJ*C -MI*6FIZBIJK*SM+6VM[BYNL+#Q,7&Q\C)RM+3U-76U]C9VN+CY.7FY^CIZO+S -M]/7V]_CY^O_:``P#`0`"$0,1`#\`].HHHH`****`"BBB@`HHHH`****`"BBB -M@`HHHH`****`"BBB@`HHHH`****`"BBB@`HHHH`**SIM'BE:9A>:A&95<#9= -MOB-G!!903UY&`*V)=[S4+F5FW-)-=OR=V[[H(0#(`P%` -MQQT)S*--B\UI&GNVS*)57[2X"D9.T`$97+$X.1R!T50`"Y15/4=/6_M9H?M5 -MW:M,JJ9;:8HZA6S\O4`GD$XR1P>@Q:2-49V!;+MN.6)`.`.`>@XZ#C.3U)H` -MR]7\2Z-HLOE:G?+!(55@FQF)#;L$``\?*?IQGJ,SG5[1=/DOI/-2%)V@/[LN -MQ<2F+`5:)M(6 -M2XBFBO\`4(`DIE>-+@LLA+*VTALX7Y`,+@8+#H30!+I.IVVL:='?V19K>1G" -M,RX+!6*YQZ'&1WQZ5@'U.3U)-2T`%%%%`! -M1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%% -M%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`444 -M4`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110 -M`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`! -M1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%% -M%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`444 -M4`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110 -M`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`! -M1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%% -M%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`444 -M4`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110 -M`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`! -M1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%%%%`!1110`4444`%% -M%%`!1110`4444`%%%%`!1110`4444`%%%%`!14%U96UXT#74*RFWE$T6[D*X -M!`;'J,G'OSU`J6.-8U*J6(+%OF8L!T`X'%`#J***`"BBB@`HHHH` -M****`"BBB@`HHHH`****`"BBB@`HHHH`****`"BBB@`HHHH`****`"BBB@`H -MHHH`****`"BBB@`HHHH`_]E02P<(%>T[FRH'```J!P``4$L#!!0`"``(`$"K -M-D`````````````````D````1&]C=6UE;G1S+S$O4&%G97,O7W)E;',O,2YF -M<&%G92YR96QS99!-3L0P#(7W2-RARCYU0]NA@Z:,IBHCL:WF`E'J_HA)')(4 -M#6=CP9&X`BEBP<_2S\_/G_WQ]K[;7_0Y>4'G9S(U$VG&$C2*^MF,-5O"P"NV -MO[^^VG5XEB%Z_#1;G\0AXVLVA6#O`+R:4$N?DD43.P,Y+4,LW0A6JB\?L'>I_0S5Y& -M9!/'--^D>R(V*8_S:$=WT8Y+--;>-VO&)VUK/1G;/@R%^:.#E`@Q23@$A7_K -M=6&&4U]Z,\ZJ?HY60_!K,JVQ+QF,DAC)]_5KB"0Q2H.D'[8VX4$9Y(F25$FA -M1++,J1),"0K!P9IJK'7AYXLS>+#>^%[7$.!/!4!PQ-DU`"H1BZ\`S**9DHOZ -M2/%4<:IX'$P1S4Q6(,$D2O+93*1:0P0-VREY!\?G:+FLZ"71/PEEM*2X``^W -M\@^O#P6H#&]!M6D2Z]K\-OX+M2U#9[%>0R'O9X^VV=$@OU7C8PCRJ[+ -MDQ@*KK@$````$``!02P,$%``( -M``@`0*LV0````````````````$8```!$;V-U;65N=',O,2]297-O=7)C97,O -M1F]N=',O0C5!13%!-C$M1#@S,"TT-#%&+3E$,#&JOD=O((0U -M((2R"\KT%?<2J"R$>,>@;V5!M86).S-\+D)"]OF=HHKBLK!GCQ(("4J@W:.X -MM*:H9M;<40B)IB+DZ%5BT!?N-SG'P5@'>!Y9`AVB7D0MM..AW:NDS#)I4KVC -M`MH7$:)NE)H*]&\H5A9\O9##5283( -M5RI,9DM')"H&_*7L\XI*0X5;6Q*T!2P^*\+@$VG1V1+>^.?$`^XB$9_M0!ND -MDWNP]VWEXIG`ED:>HM.@Z6#CAPON=)H5^LC3;),\]>A)YS6&[<%7HKX(Y]HX -MDB`WM!2HTS`O)X,\A34B$O&IE90*VFML=ZP-%>%Q?`$NH@4D1>(X68OPA:#Q -M(]&#@X8R`)I!$^EXZQBTCD[#MD*W[R>?V+!@+)Y']8]>(&/O'Y?R;\]]I1O] -MAOV^PGZ70!7]#AD-]OL:J-.ASH?:!'4*U%U0MW3CW6*_[[+?=]CN6`30[T"M -M[\;K\)_1\L_KS^O/Z\_KW[IP^\GC@@B6PKR@TJCKH"(XGL$@\*DC=?'>?GZC0N&Y-L%+6.B;DQS@.X@? -MX"MV"O!U=`CP%0G#?86THR]%!OH2>+BO@#_`%T/AOCPZW+<@/T><._JB>.RD -MB^))HS/%PV7-XF=D>S!&&R,>(+LECNE_49PA<_9]5N+I&R]I%E>ZGA+G2_+$ -MSTDNBD?"/1ONF5`'0NTOV2F.@KM2Q8X7BU62>K$KM)VA2B5[,*W66RR3O"J6 -MR&2^8I\*GXH>M3U(7]I$OT832FPOUH'XPS)&;L6V8@M&S9S/DK4]1IG-6/#3 -M%_J5OF#60AV7H%Z#^CE%4/[D0#*;.D+=I(,AJZF"O.8P@E,:[87,Z^T.^T4= -M05_2\=C@CM]YH3EHM9TZBNY1$7"Z;T;OH/5H'QF(/+$UZ$ND1/=P7[04JT!3 -M4`&^%K]B/8<:L#Y8+/2^B?JCM6@+;D0[43",'6/=BZ:B9&1"TR`GF@VYR28T -M'5])QZ-[6!^R&:]#2?AG!`&28[$^Z![D'>MQVIH&&AP'GUN")B&<=1KB%,5N -M0!Y"?E(_:2!\8`@_U5Z.I[>_1:%?D):L9?$SE]U.2]#]8UP::"O(J<21&0/SFCP=I`BHQTTCF-DA@E-9)Y -M$IZ#3"C$D$S&AA):*D8.(LA>7;C9XMC9VELEY]O9V:0R37B[0IZKDOHIW=U< -M74B_`$],Q4@C@H*Q*]CJ"\_]U?J^]6;C%*QQV=96BNB3>>OHUU9/?`KF45T$ -M.K[1<8G,I?R1/YJK':$4#1;EN\TE2X[UKO*9X -MSQ+.\9KK+18*^`Z4E[=[SYZ4NP,I]B-D?CP7F1A[U(_B'09*W#%W:F!/J7L` -MASJ!17WFYOG<]NI6#P"M8:LIG57#7/.H!P^5BKD$!C*N+FR].@D(!_H%J -M4J6,5$<$A6-AF#HB4J4D?OQT@_5NX>QIDS!WZ^4?UEKO8_26E]XJ7CWC\(KO -MVK:05S=E[DP<%1[2-__Z]K8AAZK-^J3L&'GBRMHM^]F570%::\#V,A2N=4^@ -MLBE<@&@*-!!)^+A$(L-D;LY=J'-OLJ9N']0*V)Q54A'CWV.[='Q-TN_MMXP6,#_Z"00Q$Y$&83XPV:&L)TM&) -MQZW85]3/H9>XOTCCH!0GH01<1^M$.2@;SZ*S1./@ -M6XF!-HBFH&K<3%>))CM,=*H2ST.S\!?HF:*Y#C/%N\B]CKN=KA*]^22?YR!R -MI"E"C)#80431N(`OQ"1"3"C%))*SDK.Y=IO;_C2>X>$>N6A0ZZ!6UIW89^"^ -MA,K97H@`*"<.K'^%V+M_%_[FTM-GM^';*>*7LX3WP]MDSP?M^.UV,6M7^"Y` -M'N)\>I^VH8K$*$(@\,1<"2]!(-&/ZB<(%&DP-=&?ZB]0BW3$,"I)H!-E$3E4 -MC@#TPPQ$&67@C1,81%7$-&JRH%(T%YM)+*#F"NI%@9A0)!3@`AXXIT#")_B$ -M!,<%&,D3DCCB"V!BT!:G,2')(P4B@A()2#ZB^8XXO;1^!"]M_AKW,IZ]I;AA)&JH7`?-XD`,;VD8FI(7TGU68_6F^=; -M6MO/PV+M/O4GA.;^O5W#I85J%Y*C[&.+\FN>V'IQOH-'^6: -M\_,V#'OC`ZLF?XBPFL'<,-GGJ7FPAFLZKI&IH(LK4FF]'65\@3-@=9,$22(D -M,R2D2,ZZLY3R<.N*?+"I6W.YG.CPA3@VV9@.\ZOI8.0$7[ACM7T] -M,1^/>!'A@2$'!ZE,(("@^PQ!.,$P#YU+E@ON(D6TA,9I3W#JF[GG!PS@MBK\ -M2;@@[*<&V^!JB4RE=($BR3.:<[3>'-YI#.2NL)!%@X#[0L:SP6\`]=Z#NMSYL?FA2\M6%:#\]KO$XN:S%>.!+^B,CXF12QXPDLQB# -MF]F-=I90M,2+D2(DDHAP42"L[K&;YUM;6]IM!@1@[$GA'.4&9UU4UQJK(2S3 -M;%S&I(_<[XSKMN78`,'4[_9];OWPM95[HX=/L3Y8B7T^PKQO810V9,G4AR^?;DM_@0C$-BV]>'3303#.+K"J/_BD%`W1!IK)%TA< -MHB7S:,S!:0`M$")<(!$F(5(JD:`3Z"1D%AZRKMV1"Z:L/N_1SH97\$JOXO(#=C-R:20FU -MRA6/9A.0+^\1&YM^^2L5<>\>R]XEL8=6`K(<$,X)DL!L-"S_,4Y0IQ@\S9J+ -M&ZEE3??;.BT".T+"6L1"S"!PL9;(HS"^XP"*W:1\B2`)$9(NBTB[6Z3UURWR -MFP8A!SYN#ASML%:11IB?C1))VF!G8I@C!`9*@/&E,A&!G!+Y22ZC^#DN)%]J -M#?VQ/CCGK8C;P=AQ>>V$LX'VX`B%T$NV'B.EWE?"Z;1`ZZ>;[3+GXV2.[2`#7KT3PI%G%X:?NH -M"4TAO29LRF4MXVD]MDQHG-;^#(A[!R*5+\S-(),V%G=P["%SZ-$C29`C,'A6 -M>GKXN/$%M$CD1ON0OD[.L`<)F2_10&.=3Z0^`VGD-E#DX=<5$FZV -MVL(7ER[D/I6V`LB'`LJ%N8<'7QQ7IBKBZP0]^YNF[2JG=.W[MP;,71 -M0ZM+ZQ;?;YAH/?M.R/8"?=)S`W1I1YM>#V^.21G\K&J$?.:XE;M!FWK0)H42 -M(WT*@=<)40X2B8!'>7AT+>RQ`:PA6[F#P!:] -M;*1A\F!D,&]J9U62V-/)'&0BO!%3D*Q&^W-\Q0%HB`\B.C' -M#Q;U=5"C2$+#CX&4+AG%TW&B,6@TE2$:#\E,;VE=GU=Y;X/U1FLP7#H?2'\A;>[ZG2".4D -MX468B+VD%SF&G,F5-5`NDY"DZ9L7::1HYHG)WF(0V:R+Y=)@F0 -MXX"V]9/=>"CD@>VQTS3RPD[::1ZJQ*YSM+`;-A$[+SZ&HQVZ]3NQ-%[*T6R6 -MZ81/XFAGH&7X+(YVZ<;ORN&WT6[=^CVYLA2"1_3/KC -MLA^?U\BAT]L1%G-M"R>31Q1"Z`C4UDX>$B-L]XXG^`F40U$8^SO7B]WY*8RTW7^%GZ99?CSM,7[< -MSF]]FI_'8_D)E^[\-$[9[K_"S^<#/\']\L6W_0;'Z4/]T^+TAXH[5Q@H?:$H -MP1N?+'%0AJ%,-`;6L!R\H98K*FR^G@S[:2SLK0EH"IK)E850ED%IAK(>8N9>KAQ\4@>L]G?I -M(/E#Q8LKO:"$08F&'?AD&<:MPG.@@1D]CQK08JZ\"F4=E&U0]J%#Z#A7SCZI -M`Y[]_Z0.]A]M"4@92$+;HKW($1=;:FLY(J^%:>&(YN9FK9VX:.-IUC8W$P0B -MB)8\VSVO-H][P.0UY]DZ6FP=>=J+[%CHN&B75MO2W$SB[(RH1N`\#E^)I!&:Z34Z:9 -MQED(K#9:CN34L1F-?4S9B1:;99N[F]AF?I#,D"0B67B<5A0KG;)K16(4=;'Q -MHDTKRJ85V]<(5Q[%OAQI6+\^+C>B1_^+X=T@K_>>00OZS1HZZYXC -MQL.;Z[VKH&L"CF$*)[D#S;<]P4%!>1XM#*;A&*R/PC&R.5V>)@_IUN/S>L]: -M'WM,386LK#/O8+.*@6R1,X_+(R5#ORC[7".OB#M2$GQK0N"JR\WU$I&\'F^! -MVA=W<9ZS\^.YWZQK?4_]_LOS&X[Z'LW(7B1W?(25_7X@KWM5X2OO01-9I-#9 -M#=)-8X:QN)S)K*PR6Y@4@V6BJ7*\PEWNRC*(G)TZ&4*X7%(1(N]G>Q#0-=)8 -M9F`R+/JR"F-Y,9,!F:ZQ`');D\FBB)`K;=S!*:E,-5H'#R<^]<_8>O_9SP[95+;,#OWM^I,0\;M*'$US;_S;RY[Z;1HY=2K:' -MYDM'UOD<`D"Y\**S88XU9#:V,&=E_E'INMH[N_>[[/XX>\5X?K[N;Z^_^9EZ.N7_964H -M.8M:-U7@MM@E[M8]M^%G>0M>EI2.M`K5RX[.>>T"6?%*O^?U"PY^(YJPD*S^+N^GW2\+(&7..)C0T -M!G[ODO?_GQ-O5O26!]H$]_S',#HU%?VFIO\6Q$[[")^RCU0N9A_PG/F)Y?`M -ML]Q@D=>M>LJEY\$JS&9=>I/^YLXM\QN'-)[?*1UK/"^(RN4_O!ZY*51PX;:I]R;'9_,H=>KTCS)3 -M3^X.&7Q.='+^GK$=NVI/7EZZ<[I_XF!)Z>GE6['L-8=.A+W6_\[T]2/7?N)O -MN/KBIDFOO/OID,$EHT.?;_\+CA&_XM!E>;^L>.X-XX[34RJ"\P-ZQC//OAW@ -M^KX%OY_X8V^O,9MG35#S@W]>^.7%ORS]9MZZ89?-1X8*5FW];-YGKB\=):X* -M`K/I:REO#'GSXQ$)9Z*S[_H=/Q04$QJH_.CEKPYHAUP_5S:D^FJ+?(VX]J/I -MYV*F-=]?TD\1[/K@B,O-+[9^FQ5;D1`:,DU>+ZR4UPL^;R9P#,*>\!/V7^&X^^&)WQ#@XM/Y7K/[;*Z22*VP+WN^11\29RLH,E05&?2F382JR -M3-17&IBTJOQ2H[G$4&EFXF(?N:3<=K$N&B2O5F\V,B@EEAAL+*DUF@-"%(UM? -M:BS46XRF[Q.T7O3M^J^WC6 -MJ\O>#ZV;)_<96>+4'N%YLG'IF/:&AVL.F1H6F%N.OY>:>7C+.Z)GO>JVIXB2 -M#C1^D#-MT=OY>PI2BI(O3/K*/3;W_?@9UE$J=[#V<2ER.YB"7%)$G@ -M5+.\KH%M861=K7Q:K63*TBL?Q[67+/\I^EAYS(^B^M4%_P4?K:?PG9!PR?U8 -M)"2&=9#N\2BZ7"W#\\_)_XW.IZ8D]=/;$SL\1H9@H,E19CD;%`;S$P1LX7V:4VF%F' -MK#04&2H-Y06&$$9?7L@8+6:FRFQ@7\Z9+97&`DMIC=!TE_X6XK&L*AUH64@!O@8F"&TTC"ARF"VF+6/\YDJA<#:R?CXFH8P -M2K5&!46/:#*-AHFAL`2,IH(>81*F)41RW2]*84]J]!H -M(I\0QW`O2=-M+TG3.U^2,G&Z],S8Q!3AB-CT]-B4S$1=!A.?F!&7')LX7!?/ -MQ*;$=SOBDA.')\()%R9DN5,24X;T9S*'ZIBL#!V3F@!D8@8G+C$A,2XV4\=` -M,R,S/3$N,WD4DY$U.$D7E\EDIK)#A-FZ],2,Q"$IW?@34U.8M/38N,S$.!V, -M`P'#=2F9`)N=(C$C(POF8V*S,H>FI@,682?(C$X-F,3A:.T27$<9DZ'1"5D\V%+,RXG7`E9P!EHXSP=XOAR4S -M%3WIBX]>2Y>;REFW*C(:"C-L&R'6`CLCOPHVD-`P"<9SSEVM+ZTR,.82/?A! -MN8;=]IJ$TC`E6,'TB%.J^ -M#)S5H='1*OGCT8#YE\,!\^OA@#7RT^&@V8EVZ+9ZV.K'V[@R[L(S^W -MY<%O%.S+?D//*IOA/N35FTY"?=UK2%TI[[WBL; -M+A]X/;1">>YRZ1)![T4.SZ_C!=>LKN8: -MRZ)0*%2*2'FD6L&Q5$[M>?VF]'"1)BZ^SW,?+*1L$RGEBBB%7*'B6-1.(U_W -MNE;?]^LSJ'GC_1?>M4M1*J+D42J;E+%O%*Q_VX'(F++XR%['TFM[.!8Y`(F6 -M1REL+-GOYUP:6OSB_J@-F;KR)4&[['"C%=&P*6PL(TXWO+(8/%QU^)>_B[[0 -M26Q2%-%*I0+TXEA4;>TC/&\Y'#1OG;ILWZC)']BDR#5*0"RW2='DM[YW)VE3 -MS>[]PLTOMPW3=6)1*M6=<'._V38^=U:.IV!.ID@P>N!4.Y9(1;0J2@Y*,[C8 -MT<2KPD]M,;4P!W]4NWO;A"@U8'V8C1/BX%^T:O3P?"V*5_`BBA8:YO]W5*/92HH -M&\NUS[X9^^&')[[*'310]9:WN$L*>*M-RJ#\U)&]=NZJ6APFS=T]>-U7G/LJ -M6'74X'4]2YI/DD' -M.OB);4%2&XLR6A&ICK1K-*'X]EO*^TL40J-2JVT+?2@ESX[YY6Z<]4#[;)YJ2]]MX1C48+S -M0K!51',L&8E>U47W+_I_,7W?"\^=FB;I9%&R2V1;@*&]IG;H3_=UO1DX>MO; -M@P8.M[$H8;$CY':/BIWZP^&=*"9H[O6/Q:'.R^_:6#B*4?=BPMMFZD:3L6E5*ACK"[E"6Y -M=E+\TFTW]IV-+WGSSO/!=BEJV$B*B`B.19?0N"LS;N'^I)?]?OI^\QI8]N#'M -MKZ5G9T\0UT3P4Y3JE2VB6+07PQQ^S>OPH9;#OO\7+#?QJ*(8/U?87-, -M]V&?)0SN,;IXV<6!'9]>[=W>R0+N':VV+6/2O+^G)6W9>,[MZWUS<9]WW.Q8 -MP!$BX-3E6)3G\VK/OW%,O%ZR_..?SEVUVT7!;K5.*<7."V:$W9_E%3=PZI6O -M1E_ZR`Y7P08I>QSKG6^<.&X5BHYP/WYUJ$CZ\)%U@2O"MHQ$Z9+3'G,.I4WY -MX!Z)3]@_^Y'2@,2^`\;LO+JN^9QZYX*A1W;=SXP<:V>)8H\%-C(_?6H.EN8/ -MGZ1,N2!JO__\MR4WPEVRGIDW\O10^N.Q)8L&*',^OEKY]I>)(RK?#=L0JNE? -MI$LP]^@=*ZZQ##9_-W3*PYB:I6W&U47?)P^:[]YOW^UW;I!FNQ2Y1^-K+M[R-.0&JPS]-6_ONCA?&7!N[<9"B -MGM@AKR?>QB'1J_HOG)._\CKHL=?\S77[Y9Z/K"0@%-V__Y)RGVXMD>*);\=R -MWZZ!I$)&2LHM>_B?WSE^^W3O\-GHZ^AC\OQN[`Z*3'EZ/SPH55[Q9/4:2OF3NFXX/X -MR)EXX&O'UMP,NE^(BY\7F+T*O6]\NOG''MOF-"^YN+"DSXY%+J5WRC;%#ZL> -M=GSNJ:^S)8?.Q!"IYG,;#"]\UY%_XN&2;TJFTV,ZK/3J>NPD)/''NHQ#*^JQ -M]Z!K+[OJ=7O^U[]2_JTWXX][SBBY1W?'$77]3H6!WSQZ0BG$W.N_"!4;8*/9 -MUW]/^LW1^SWNC\T7+G8*U2;N_B9GY]-KVDN[]^^M0WB?_/+S2P_O?EBG^PEG -M%M>5_OV$;^%W6^_I+YSYZG2?P2WE7S4_F.V_(^*]U:$^5ZJN&&^\HQ\P9.%; -M&\>!J^9^O4VG&5CPW=T]\6]JVQS)AWW.2Y[;XQ7^:5OIG6_BZE0ADZ8D6UH7 -MO_IJ1](AT[D3&:L=7'N5]'RIG4CR^'E*\4J1/9E -MTH7D2$J9>HQD#M0SCNOZ'=,M`QZIJJ'4LVC`#0NU)(2;W6JY7[LHE_U74Q4T -MJ,]6P[:$;"Z1GP(X:U+(H9/*!(?GF*_>"19U3-:+6'-@`;R:\>ZATOD'4$L' -M"`0010_%````#0$``%!+`P04``@`"`!`JS9`````````````````'@```$1O -M8W5M96YT&5D1&]C=6UE;G0N9F1O8U6-00K",!1$]X)W*']O?BHH -M(HU=**X%3U#2WS9@\DM_*KV;"X_D%4P6+ES-,,R;^;S>5;WX1_&D21P'`Z72 -M4%"PW+K0&YACMSE`?5JOJJM;J+VPG3V%6"0HB($AQO&(*'8@WXCRSDXLW$5E -MV>,R"FZUWJ'>0UZX-3V=.<3,WWF>+!G`WZ)@B;F05'5C,H"9P;_;E'P!4$L' -M"`R&*CV5````LP```%!+`P04``@`"`!`JS9`````````````````)@```%]R -M96QS+T9I>&5D1&]C=6UE;G1397%U96YC92YF9'-E<2YR96QS98]+:@,Q#(;W -MA=S!:)_1M)!22IRL&PB$,/NB>C0>,^,'MAJ2LV61(_4*=79]+"7]^C[IZWI; -M;\]^5B?.Q<6@X;%I07$PL7?!:OB48?D"V\WB87WDF:1FRNA2474I%`VC2'I% -M+&9D3Z6)B4.=##%[DEIFBXG,1);QJ6V?,?]DP%^JZBA;%@VX9Z&>A'`7/]X/ -M75.9H-YZ#<=Z77=)_,_LG4[D+5UB=*;L@XLS$`GA7XJ]/:N<; -M4$L'"!*Y#,J]````!@$``%!+`P04``@`"`!`JS9`````````````````&P`` -M`$9I>&5D1&]C=6UE;G1397%U96YC92YF9'-E<6V.30K",!"%]X)W*+,WDPJ* -M2&,WX@'L"22=V(#)U/Q([^;"(WD%6Z$+P?5[W_?>^_FJZL'=B@>%:-DK*(6$ -M@KSFUOJK@IS,:@?U8;FH3G:@]L@Z._*IH7L>6U2,L(\*NI3Z/6+4';E+%,[J -MP)%-$IH=#GW$M90;E%N83+/D3(;"U])P#IH4X!Q%+/%G4)B6->"$X]\G8_(! -M4$L'"``B)\:8````S@```%!+`P04``@`"`!`JS9`````````````````"P`` -M`%]R96QS+RYR96QSE9#/2L0P$(?O@N]0@DE2&BSR\F)"U:&7JD!L!5W9"?1G4Z-#S/6[&;(2ET80;4=SH1JRS9?L2 -M\8^!LRH%"H9+%1Q,D;;@$\ALL\U,&!-2#OV$"MBO,-,):KA#EEJRA%7^2?W0 -M]J-[]-(.Y>WJ^MNGWN/SKT;`S2">$5^*\*O\?/,!4$L'"+<@\O_S````N0$` -M`%!+`P04``@`"`!`JS9`````````````````$P```%M#;VYT96YT7U1Y<&5S -M72YX;6REDL]*Q#`0A^^"[U!RE3;5@XALW8,K@B"D5\;5%>M1YS=L -M?7=^MGIY#Q`S:G:Q8@UBN.4\R@:LB(4/X*BB?6<%TK>K>1!R*VK@5V5YS:5W -M"`YS3`R6:!O0HF\Q>QBH,*D[:"/+[J?69*N8"*$U4B#5^=ZI`T_^XR@H.?;$ -MQH1X00V,'W%H%6&W(+&_X"'$7)L!E/*RMY2@=$_3@06)E_]PS+,#94Z`I]@L -MV"M$_7>P?]5]I!*H/"TE+?8H.FF7P9UQ2#=7C`\T<@OSDWAZ?CR@&IL.[BU` -M/87X>++T^@902P<(7S5E41$!``#G`@``4$L!`BT`%``(``@`0*LV0'#&B=;` -M`P``YPT``!,``````````````````````$UE=&%D871A+TIO8E]05"YX;6Q0 -M2P$"+0`4``@`"`!`JS9`MEKQ/=,```#(`0``&@`````````````````!!``` -M365T861A=&$O35A$0U]%;7!T>5]05"YX;6Q02P$"+0`4``@```!`JS9`%>T[ -MFRH'```J!P``*``````````````````&5D -M1&]C=6UE;G0N9F1O8RYR96QS4$L!`BT`%``(``@`0*LV0`R&*CV5````LP`` -M`!X`````````````````(S4``$1O8W5M96YT&5D1&]C=6UE;G0N -M9F1O8U!+`0(M`!0`"``(`$"K-D`2N0S*O0````8!```F```````````````` -M``0V``!?!BP$`4$L!`A0`%`````@`6'QO2_E8(*00````#@````@````````` -H`````````````&%R8UQT97-T4$L%!@`````!``$`-@```#8````````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_compat_zstd.c b/thirdparty/libarchive/libarchive/test/test_compat_zstd.c deleted file mode 100644 index 134775816..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_zstd.c +++ /dev/null @@ -1,85 +0,0 @@ -/*- - * Copyright (c) 2017 Sean Purcell - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* - * Verify our ability to read sample files compatibly with 'zstd -d'. - * - * In particular: - * * zstd -d will read multiple zstd streams, concatenating the output - * * zstd -d will skip over zstd skippable frames - */ - -static void -compat_zstd(const char *name) -{ - const char *n[7] = { "f1", "f2", "f3", "d1/f1", "d1/f2", "d1/f3", NULL }; - struct archive_entry *ae; - struct archive *a; - int i, r; - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - r = archive_read_support_filter_zstd(a); - if (r == ARCHIVE_WARN) { - skipping("zstd reading not fully supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - extract_reference_file(name); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 2)); - - /* Read entries, match up names with list above. */ - for (i = 0; i < 6; ++i) { - failure("Could not read file %d (%s) from %s", i, n[i], name); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_next_header(a, &ae)); - assertEqualString(n[i], archive_entry_pathname(ae)); - } - - /* Verify the end-of-archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify that the format detection worked. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_ZSTD); - assertEqualString(archive_filter_name(a, 0), "zstd"); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - -DEFINE_TEST(test_compat_zstd) -{ - /* This sample was compressed as 3 separate streams with a zstd skippable - * frame placed in the middle */ - compat_zstd("test_compat_zstd_1.tar.zst"); - - /* The same sample compressed with pzstd */ - compat_zstd("test_compat_zstd_2.tar.zst"); -} diff --git a/thirdparty/libarchive/libarchive/test/test_compat_zstd_1.tar.zst.uu b/thirdparty/libarchive/libarchive/test/test_compat_zstd_1.tar.zst.uu deleted file mode 100644 index 4b0b98447..000000000 --- a/thirdparty/libarchive/libarchive/test/test_compat_zstd_1.tar.zst.uu +++ /dev/null @@ -1,12 +0,0 @@ -begin 644 test_compat_zstd_1.tar.zst -M*+4O_010)0,`HL0.%;`Q&>>\/$2[#IQF[<1+Z3T<0CX]!77&0@R.6+/F,0+I -M.$1A$QE2`J!+*_6[_YT9_W_M1KC-EG*V>10.`,M`%3*@#F#\`-FT#J:1#U1" -M`H1!&R#A5\*'"JYIJ;C&4=B2CL(L)*E-IJT/RV?.:A_]_N -MB&[7SDG;/=4&#P";0!5D0`=8T0&R&19,)1^HA`0(@S9`N`G.!0!IP&NM<,K! -M-#8!%A]U]K10*DT8!`````$"`P0HM2_]!%!]`P`B11`6H+$)"%]@,Z6OH`"L -MM$R2MAN&*MSG`W?OJ7+4P*B::VXR`NM(1&$7&58"J*U'_&V^S$/_O]U1N%T[ -M)VW7J'+4!A``_4$%^T`],J`8P.0!L@D63"4?J(0$"(,V0+@)S@4`:,` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_empty_write.c b/thirdparty/libarchive/libarchive/test/test_empty_write.c deleted file mode 100644 index a983df503..000000000 --- a/thirdparty/libarchive/libarchive/test/test_empty_write.c +++ /dev/null @@ -1,126 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_empty_write.c 189308 2009-03-03 17:02:51Z kientzle $"); - -DEFINE_TEST(test_empty_write) -{ - char buff[32768]; - struct archive_entry *ae; - struct archive *a; - size_t used; - int r; - - /* - * Exercise a zero-byte write to a gzip-compressed archive. - */ - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertA(0 == archive_write_set_format_ustar(a)); - r = archive_write_add_filter_gzip(a); - if (r != ARCHIVE_OK && !canGzip()) { - skipping("Empty write to gzip-compressed archive"); - } else { - if (r != ARCHIVE_OK && canGzip()) - assertEqualIntA(a, ARCHIVE_WARN, r); - else - assertEqualIntA(a, ARCHIVE_OK, r); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - /* Write a file to it. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 0); - assertA(0 == archive_write_header(a, ae)); - archive_entry_free(ae); - - /* THE TEST: write zero bytes to this entry. */ - /* This used to crash. */ - assertEqualIntA(a, 0, archive_write_data(a, "", 0)); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - } - - /* - * Again, with bzip2 compression. - */ - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertA(0 == archive_write_set_format_ustar(a)); - r = archive_write_add_filter_bzip2(a); - if (r != ARCHIVE_OK && !canBzip2()) { - skipping("Empty write to bzip2-compressed archive"); - } else { - if (r != ARCHIVE_OK && canBzip2()) - assertEqualIntA(a, ARCHIVE_WARN, r); - else - assertEqualIntA(a, ARCHIVE_OK, r); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - /* Write a file to it. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 0); - assertA(0 == archive_write_header(a, ae)); - archive_entry_free(ae); - - /* THE TEST: write zero bytes to this entry. */ - assertEqualIntA(a, 0, archive_write_data(a, "", 0)); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - } - - /* - * For good measure, one more time with no compression. - */ - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertA(0 == archive_write_set_format_ustar(a)); - assertA(0 == archive_write_add_filter_none(a)); - assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used)); - /* Write a file to it. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 0); - assertA(0 == archive_write_header(a, ae)); - archive_entry_free(ae); - - /* THE TEST: write zero bytes to this entry. */ - assertEqualIntA(a, 0, archive_write_data(a, "", 0)); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_entry.c b/thirdparty/libarchive/libarchive/test/test_entry.c deleted file mode 100644 index f20576490..000000000 --- a/thirdparty/libarchive/libarchive/test/test_entry.c +++ /dev/null @@ -1,974 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_entry.c 201247 2009-12-30 05:59:21Z kientzle $"); - -#include - -#ifdef HAVE_LINUX_FS_H -#include /* for Linux file flags */ -#endif - -#ifndef HAVE_WCSCPY -static wchar_t * wcscpy(wchar_t *s1, const wchar_t *s2) -{ - wchar_t *dest = s1; - while ((*s1 = *s2) != L'\0') - ++s1, ++s2; - return dest; -} -#endif - -/* - * Most of these tests are system-independent, though a few depend on - * features of the local system. Such tests are conditionalized on - * the platform name. On unsupported platforms, only the - * system-independent features will be tested. - * - * No, I don't want to use config.h in the test files because I want - * the tests to also serve as a check on the correctness of config.h. - * A mis-configured library build should cause tests to fail. - */ - -DEFINE_TEST(test_entry) -{ - char buff[128]; - wchar_t wbuff[128]; - struct stat st; - struct archive_entry *e, *e2; - const struct stat *pst; - unsigned long set, clear; /* For fflag testing. */ - int type, permset, tag, qual; /* For ACL testing. */ - const char *name; /* For ACL testing. */ - const char *xname; /* For xattr tests. */ - const void *xval; /* For xattr tests. */ - size_t xsize; /* For xattr tests. */ - wchar_t wc; - long l; - int i; - - assert((e = archive_entry_new()) != NULL); - - /* - * Verify that the AE_IF* defines match S_IF* defines - * on this platform. See comments in archive_entry.h. - */ -#ifdef S_IFREG - assertEqualInt(S_IFREG, AE_IFREG); -#endif -#ifdef S_IFLNK - assertEqualInt(S_IFLNK, AE_IFLNK); -#endif -#ifdef S_IFSOCK - assertEqualInt(S_IFSOCK, AE_IFSOCK); -#endif -#ifdef S_IFCHR - assertEqualInt(S_IFCHR, AE_IFCHR); -#endif -/* Work around MinGW, which defines S_IFBLK wrong. */ -/* sourceforge.net/tracker/?func=detail&atid=102435&aid=1942809&group_id=2435 */ -#if defined(S_IFBLK) && !defined(_WIN32) - assertEqualInt(S_IFBLK, AE_IFBLK); -#endif -#ifdef S_IFDIR - assertEqualInt(S_IFDIR, AE_IFDIR); -#endif -#ifdef S_IFIFO - assertEqualInt(S_IFIFO, AE_IFIFO); -#endif - - /* - * Basic set/read tests for all fields. - * We should be able to set any field and read - * back the same value. - * - * For methods that "copy" a string, we should be able - * to overwrite the original passed-in string without - * changing the value in the entry. - * - * The following tests are ordered alphabetically by the - * name of the field. - */ - - /* atime */ - archive_entry_set_atime(e, 13579, 24680); - assertEqualInt(archive_entry_atime(e), 13579); - assertEqualInt(archive_entry_atime_nsec(e), 24680); - archive_entry_set_atime(e, 13580, 1000000001L); - assertEqualInt(archive_entry_atime(e), 13581); - assertEqualInt(archive_entry_atime_nsec(e), 1); - archive_entry_set_atime(e, 13580, -7); - assertEqualInt(archive_entry_atime(e), 13579); - assertEqualInt(archive_entry_atime_nsec(e), 999999993); - archive_entry_unset_atime(e); - assertEqualInt(archive_entry_atime(e), 0); - assertEqualInt(archive_entry_atime_nsec(e), 0); - assert(!archive_entry_atime_is_set(e)); - - /* birthtime */ - archive_entry_set_birthtime(e, 17579, 24990); - assertEqualInt(archive_entry_birthtime(e), 17579); - assertEqualInt(archive_entry_birthtime_nsec(e), 24990); - archive_entry_set_birthtime(e, 17580, 1234567890L); - assertEqualInt(archive_entry_birthtime(e), 17581); - assertEqualInt(archive_entry_birthtime_nsec(e), 234567890); - archive_entry_set_birthtime(e, 17581, -24990); - assertEqualInt(archive_entry_birthtime(e), 17580); - assertEqualInt(archive_entry_birthtime_nsec(e), 999975010); - archive_entry_unset_birthtime(e); - assertEqualInt(archive_entry_birthtime(e), 0); - assertEqualInt(archive_entry_birthtime_nsec(e), 0); - assert(!archive_entry_birthtime_is_set(e)); - - /* ctime */ - archive_entry_set_ctime(e, 13580, 24681); - assertEqualInt(archive_entry_ctime(e), 13580); - assertEqualInt(archive_entry_ctime_nsec(e), 24681); - archive_entry_set_ctime(e, 13581, 2008182348L); - assertEqualInt(archive_entry_ctime(e), 13583); - assertEqualInt(archive_entry_ctime_nsec(e), 8182348); - archive_entry_set_ctime(e, 13582, -24681); - assertEqualInt(archive_entry_ctime(e), 13581); - assertEqualInt(archive_entry_ctime_nsec(e), 999975319); - archive_entry_unset_ctime(e); - assertEqualInt(archive_entry_ctime(e), 0); - assertEqualInt(archive_entry_ctime_nsec(e), 0); - assert(!archive_entry_ctime_is_set(e)); - - /* dev */ - assert(!archive_entry_dev_is_set(e)); - archive_entry_set_dev(e, 235); - assert(archive_entry_dev_is_set(e)); - assertEqualInt(archive_entry_dev(e), 235); - /* devmajor/devminor are tested specially below. */ - - /* filetype */ - archive_entry_set_filetype(e, AE_IFREG); - assertEqualInt(archive_entry_filetype(e), AE_IFREG); - - /* fflags are tested specially below */ - - /* gid */ - archive_entry_set_gid(e, 204); - assertEqualInt(archive_entry_gid(e), 204); - - /* gname */ - archive_entry_set_gname(e, "group"); - assertEqualString(archive_entry_gname(e), "group"); - assertEqualString(archive_entry_gname_utf8(e), "group"); - assertEqualWString(archive_entry_gname_w(e), L"group"); - wcscpy(wbuff, L"wgroup"); - archive_entry_copy_gname_w(e, wbuff); - assertEqualWString(archive_entry_gname_w(e), L"wgroup"); - memset(wbuff, 0, sizeof(wbuff)); - assertEqualWString(archive_entry_gname_w(e), L"wgroup"); - assertEqualString(archive_entry_gname_utf8(e), "wgroup"); - assertEqualString(archive_entry_gname(e), "wgroup"); - archive_entry_set_gname_utf8(e, "group"); - assertEqualString(archive_entry_gname_utf8(e), "group"); - assertEqualWString(archive_entry_gname_w(e), L"group"); - assertEqualString(archive_entry_gname(e), "group"); - archive_entry_update_gname_utf8(e, "group2"); - assertEqualString(archive_entry_gname_utf8(e), "group2"); - assertEqualWString(archive_entry_gname_w(e), L"group2"); - assertEqualString(archive_entry_gname(e), "group2"); - - /* hardlink */ - archive_entry_set_hardlink(e, "hardlinkname"); - assertEqualString(archive_entry_hardlink(e), "hardlinkname"); - assertEqualString(archive_entry_hardlink_utf8(e), "hardlinkname"); - assertEqualWString(archive_entry_hardlink_w(e), L"hardlinkname"); - strcpy(buff, "hardlinkname2"); - archive_entry_copy_hardlink(e, buff); - assertEqualString(archive_entry_hardlink(e), "hardlinkname2"); - assertEqualWString(archive_entry_hardlink_w(e), L"hardlinkname2"); - assertEqualString(archive_entry_hardlink_utf8(e), "hardlinkname2"); - memset(buff, 0, sizeof(buff)); - assertEqualString(archive_entry_hardlink(e), "hardlinkname2"); - assertEqualString(archive_entry_hardlink_utf8(e), "hardlinkname2"); - assertEqualWString(archive_entry_hardlink_w(e), L"hardlinkname2"); - archive_entry_copy_hardlink(e, NULL); - assertEqualString(archive_entry_hardlink(e), NULL); - assertEqualWString(archive_entry_hardlink_w(e), NULL); - assertEqualString(archive_entry_hardlink_utf8(e), NULL); - wcscpy(wbuff, L"whardlink"); - archive_entry_copy_hardlink_w(e, wbuff); - assertEqualWString(archive_entry_hardlink_w(e), L"whardlink"); - assertEqualString(archive_entry_hardlink_utf8(e), "whardlink"); - assertEqualString(archive_entry_hardlink(e), "whardlink"); - memset(wbuff, 0, sizeof(wbuff)); - assertEqualWString(archive_entry_hardlink_w(e), L"whardlink"); - archive_entry_copy_hardlink_w(e, NULL); - assertEqualString(archive_entry_hardlink(e), NULL); - assertEqualWString(archive_entry_hardlink_w(e), NULL); - archive_entry_set_hardlink_utf8(e, "hardlinkname"); - assertEqualString(archive_entry_hardlink_utf8(e), "hardlinkname"); - assertEqualWString(archive_entry_hardlink_w(e), L"hardlinkname"); - assertEqualString(archive_entry_hardlink(e), "hardlinkname"); - archive_entry_update_hardlink_utf8(e, "hardlinkname2"); - assertEqualString(archive_entry_hardlink_utf8(e), "hardlinkname2"); - assertEqualWString(archive_entry_hardlink_w(e), L"hardlinkname2"); - assertEqualString(archive_entry_hardlink(e), "hardlinkname2"); - - /* ino */ - assert(!archive_entry_ino_is_set(e)); - archive_entry_set_ino(e, 8593); - assert(archive_entry_ino_is_set(e)); - assertEqualInt(archive_entry_ino(e), 8593); - assertEqualInt(archive_entry_ino64(e), 8593); - archive_entry_set_ino64(e, 8594); - assert(archive_entry_ino_is_set(e)); - assertEqualInt(archive_entry_ino(e), 8594); - assertEqualInt(archive_entry_ino64(e), 8594); - - /* link */ - archive_entry_set_hardlink(e, "hardlinkname"); - archive_entry_set_symlink(e, NULL); - archive_entry_set_link(e, "link"); - assertEqualString(archive_entry_hardlink(e), "link"); - assertEqualString(archive_entry_symlink(e), NULL); - archive_entry_copy_link(e, "link2"); - assertEqualString(archive_entry_hardlink(e), "link2"); - assertEqualString(archive_entry_symlink(e), NULL); - archive_entry_copy_link_w(e, L"link3"); - assertEqualString(archive_entry_hardlink(e), "link3"); - assertEqualString(archive_entry_symlink(e), NULL); - archive_entry_set_hardlink(e, NULL); - archive_entry_set_symlink(e, "symlink"); - archive_entry_set_link(e, "link"); - assertEqualString(archive_entry_hardlink(e), NULL); - assertEqualString(archive_entry_symlink(e), "link"); - archive_entry_copy_link(e, "link2"); - assertEqualString(archive_entry_hardlink(e), NULL); - assertEqualString(archive_entry_symlink(e), "link2"); - archive_entry_copy_link_w(e, L"link3"); - assertEqualString(archive_entry_hardlink(e), NULL); - assertEqualString(archive_entry_symlink(e), "link3"); - /* Arbitrarily override symlink if both hardlink and symlink set. */ - archive_entry_set_hardlink(e, "hardlink"); - archive_entry_set_symlink(e, "symlink"); - archive_entry_set_link(e, "link"); - assertEqualString(archive_entry_hardlink(e), "hardlink"); - assertEqualString(archive_entry_symlink(e), "link"); - - /* mode */ - archive_entry_set_mode(e, 0123456); - assertEqualInt(archive_entry_mode(e), 0123456); - - /* mtime */ - archive_entry_set_mtime(e, 13581, 24682); - assertEqualInt(archive_entry_mtime(e), 13581); - assertEqualInt(archive_entry_mtime_nsec(e), 24682); - archive_entry_set_mtime(e, 13582, 1358297468); - assertEqualInt(archive_entry_mtime(e), 13583); - assertEqualInt(archive_entry_mtime_nsec(e), 358297468); - archive_entry_set_mtime(e, 13583, -24682); - assertEqualInt(archive_entry_mtime(e), 13582); - assertEqualInt(archive_entry_mtime_nsec(e), 999975318); - archive_entry_unset_mtime(e); - assertEqualInt(archive_entry_mtime(e), 0); - assertEqualInt(archive_entry_mtime_nsec(e), 0); - assert(!archive_entry_mtime_is_set(e)); - - /* nlink */ - archive_entry_set_nlink(e, 736); - assertEqualInt(archive_entry_nlink(e), 736); - - /* pathname */ - archive_entry_set_pathname(e, "path"); - assertEqualString(archive_entry_pathname(e), "path"); - assertEqualString(archive_entry_pathname_utf8(e), "path"); - assertEqualWString(archive_entry_pathname_w(e), L"path"); - archive_entry_set_pathname(e, "path"); - assertEqualString(archive_entry_pathname(e), "path"); - assertEqualWString(archive_entry_pathname_w(e), L"path"); - assertEqualString(archive_entry_pathname_utf8(e), "path"); - strcpy(buff, "path2"); - archive_entry_copy_pathname(e, buff); - assertEqualString(archive_entry_pathname(e), "path2"); - assertEqualWString(archive_entry_pathname_w(e), L"path2"); - assertEqualString(archive_entry_pathname_utf8(e), "path2"); - memset(buff, 0, sizeof(buff)); - assertEqualString(archive_entry_pathname(e), "path2"); - assertEqualString(archive_entry_pathname_utf8(e), "path2"); - assertEqualWString(archive_entry_pathname_w(e), L"path2"); - wcscpy(wbuff, L"wpath"); - archive_entry_copy_pathname_w(e, wbuff); - assertEqualWString(archive_entry_pathname_w(e), L"wpath"); - assertEqualString(archive_entry_pathname_utf8(e), "wpath"); - assertEqualString(archive_entry_pathname(e), "wpath"); - memset(wbuff, 0, sizeof(wbuff)); - assertEqualWString(archive_entry_pathname_w(e), L"wpath"); - assertEqualString(archive_entry_pathname(e), "wpath"); - assertEqualString(archive_entry_pathname_utf8(e), "wpath"); - archive_entry_set_pathname_utf8(e, "path"); - assertEqualWString(archive_entry_pathname_w(e), L"path"); - assertEqualString(archive_entry_pathname(e), "path"); - assertEqualString(archive_entry_pathname_utf8(e), "path"); - archive_entry_update_pathname_utf8(e, "path2"); - assertEqualWString(archive_entry_pathname_w(e), L"path2"); - assertEqualString(archive_entry_pathname(e), "path2"); - assertEqualString(archive_entry_pathname_utf8(e), "path2"); - - /* rdev */ - archive_entry_set_rdev(e, 532); - assertEqualInt(archive_entry_rdev(e), 532); - /* rdevmajor/rdevminor are tested specially below. */ - - /* size */ - archive_entry_set_size(e, 987654321); - assertEqualInt(archive_entry_size(e), 987654321); - archive_entry_unset_size(e); - assertEqualInt(archive_entry_size(e), 0); - assert(!archive_entry_size_is_set(e)); - - /* sourcepath */ - archive_entry_copy_sourcepath(e, "path1"); - assertEqualString(archive_entry_sourcepath(e), "path1"); - - /* symlink */ - archive_entry_set_symlink(e, "symlinkname"); - assertEqualString(archive_entry_symlink(e), "symlinkname"); - assertEqualString(archive_entry_symlink_utf8(e), "symlinkname"); - assertEqualWString(archive_entry_symlink_w(e), L"symlinkname"); - strcpy(buff, "symlinkname2"); - archive_entry_copy_symlink(e, buff); - assertEqualString(archive_entry_symlink(e), "symlinkname2"); - assertEqualWString(archive_entry_symlink_w(e), L"symlinkname2"); - assertEqualString(archive_entry_symlink_utf8(e), "symlinkname2"); - memset(buff, 0, sizeof(buff)); - assertEqualString(archive_entry_symlink(e), "symlinkname2"); - assertEqualString(archive_entry_symlink_utf8(e), "symlinkname2"); - assertEqualWString(archive_entry_symlink_w(e), L"symlinkname2"); - archive_entry_copy_symlink_w(e, NULL); - assertEqualWString(archive_entry_symlink_w(e), NULL); - assertEqualString(archive_entry_symlink(e), NULL); - assertEqualString(archive_entry_symlink_utf8(e), NULL); - archive_entry_copy_symlink_w(e, L"wsymlink"); - assertEqualWString(archive_entry_symlink_w(e), L"wsymlink"); - assertEqualString(archive_entry_symlink_utf8(e), "wsymlink"); - assertEqualString(archive_entry_symlink(e), "wsymlink"); - archive_entry_copy_symlink(e, NULL); - assertEqualWString(archive_entry_symlink_w(e), NULL); - assertEqualString(archive_entry_symlink(e), NULL); - assertEqualString(archive_entry_symlink_utf8(e), NULL); - archive_entry_set_symlink_utf8(e, "symlinkname"); - assertEqualWString(archive_entry_symlink_w(e), L"symlinkname"); - assertEqualString(archive_entry_symlink(e), "symlinkname"); - assertEqualString(archive_entry_symlink_utf8(e), "symlinkname"); - archive_entry_update_symlink_utf8(e, "symlinkname2"); - assertEqualWString(archive_entry_symlink_w(e), L"symlinkname2"); - assertEqualString(archive_entry_symlink(e), "symlinkname2"); - assertEqualString(archive_entry_symlink_utf8(e), "symlinkname2"); - - /* uid */ - archive_entry_set_uid(e, 83); - assertEqualInt(archive_entry_uid(e), 83); - - /* uname */ - archive_entry_set_uname(e, "user"); - assertEqualString(archive_entry_uname(e), "user"); - assertEqualString(archive_entry_uname_utf8(e), "user"); - assertEqualWString(archive_entry_uname_w(e), L"user"); - wcscpy(wbuff, L"wuser"); - archive_entry_copy_uname_w(e, wbuff); - assertEqualWString(archive_entry_uname_w(e), L"wuser"); - memset(wbuff, 0, sizeof(wbuff)); - assertEqualWString(archive_entry_uname_w(e), L"wuser"); - assertEqualString(archive_entry_uname_utf8(e), "wuser"); - assertEqualString(archive_entry_uname(e), "wuser"); - archive_entry_set_uname_utf8(e, "user"); - assertEqualString(archive_entry_uname_utf8(e), "user"); - assertEqualWString(archive_entry_uname_w(e), L"user"); - assertEqualString(archive_entry_uname(e), "user"); - archive_entry_set_uname_utf8(e, "user"); - assertEqualWString(archive_entry_uname_w(e), L"user"); - assertEqualString(archive_entry_uname(e), "user"); - assertEqualString(archive_entry_uname_utf8(e), "user"); - archive_entry_update_uname_utf8(e, "user2"); - assertEqualWString(archive_entry_uname_w(e), L"user2"); - assertEqualString(archive_entry_uname(e), "user2"); - assertEqualString(archive_entry_uname_utf8(e), "user2"); - - /* Test fflags interface. */ - archive_entry_set_fflags(e, 0x55, 0xAA); - archive_entry_fflags(e, &set, &clear); - failure("Testing set/get of fflags data."); - assertEqualInt(set, 0x55); - failure("Testing set/get of fflags data."); - assertEqualInt(clear, 0xAA); -#ifdef __FreeBSD__ - /* Converting fflags bitmap to string is currently system-dependent. */ - /* TODO: Make this system-independent. */ - assertEqualString(archive_entry_fflags_text(e), - "uappnd,nouchg,nodump,noopaque,uunlnk,nosystem"); -#endif - -#if defined(__FreeBSD__) || defined(__APPLE__) - /* Test archive_entry_copy_fflags_text_w() */ - archive_entry_copy_fflags_text_w(e, L" ,nouappnd, nouchg, dump,hidden"); - archive_entry_fflags(e, &set, &clear); - assertEqualInt(UF_HIDDEN, set); - assertEqualInt(UF_NODUMP | UF_IMMUTABLE | UF_APPEND, clear); - /* Test archive_entry_copy_fflags_text() */ - archive_entry_copy_fflags_text(e, " ,nouappnd, nouchg, dump,hidden"); - archive_entry_fflags(e, &set, &clear); - assertEqualInt(UF_HIDDEN, set); - assertEqualInt(UF_NODUMP | UF_IMMUTABLE | UF_APPEND, clear); -#elif defined(_WIN32) && !defined(CYGWIN) - archive_entry_copy_fflags_text_w(e, L"rdonly,hidden,nosystem"); - archive_entry_fflags(e, &set, &clear); - assertEqualInt(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN, set); - assertEqualInt(FILE_ATTRIBUTE_SYSTEM, clear); - archive_entry_copy_fflags_text(e, "rdonly,hidden,nosystem"); - archive_entry_fflags(e, &set, &clear); - assertEqualInt(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN, set); - assertEqualInt(FILE_ATTRIBUTE_SYSTEM, clear); -#elif defined FS_IOC_GETFLAGS /* Linux */ - archive_entry_copy_fflags_text_w(e, L"sappnd,schg,dump,noundel"); - archive_entry_fflags(e, &set, &clear); - assertEqualInt(FS_APPEND_FL | FS_IMMUTABLE_FL, set); - assertEqualInt(FS_NODUMP_FL | FS_UNRM_FL, clear); - archive_entry_copy_fflags_text(e, "sappnd,schg,dump,noundel"); - archive_entry_fflags(e, &set, &clear); - assertEqualInt(FS_APPEND_FL | FS_IMMUTABLE_FL, set); - assertEqualInt(FS_NODUMP_FL | FS_UNRM_FL, clear); -#endif - - /* See test_acl_basic.c for tests of ACL set/get consistency. */ - - /* Test xattrs set/get consistency. */ - archive_entry_xattr_add_entry(e, "xattr1", "xattrvalue1", 12); - assertEqualInt(1, archive_entry_xattr_reset(e)); - assertEqualInt(0, archive_entry_xattr_next(e, &xname, &xval, &xsize)); - assertEqualString(xname, "xattr1"); - assertEqualString(xval, "xattrvalue1"); - assertEqualInt((int)xsize, 12); - assertEqualInt(1, archive_entry_xattr_count(e)); - assertEqualInt(ARCHIVE_WARN, - archive_entry_xattr_next(e, &xname, &xval, &xsize)); - assertEqualString(xname, NULL); - assertEqualString(xval, NULL); - assertEqualInt((int)xsize, 0); - archive_entry_xattr_clear(e); - assertEqualInt(0, archive_entry_xattr_reset(e)); - assertEqualInt(ARCHIVE_WARN, - archive_entry_xattr_next(e, &xname, &xval, &xsize)); - assertEqualString(xname, NULL); - assertEqualString(xval, NULL); - assertEqualInt((int)xsize, 0); - archive_entry_xattr_add_entry(e, "xattr1", "xattrvalue1", 12); - assertEqualInt(1, archive_entry_xattr_reset(e)); - archive_entry_xattr_add_entry(e, "xattr2", "xattrvalue2", 12); - assertEqualInt(2, archive_entry_xattr_reset(e)); - assertEqualInt(0, archive_entry_xattr_next(e, &xname, &xval, &xsize)); - assertEqualInt(0, archive_entry_xattr_next(e, &xname, &xval, &xsize)); - assertEqualInt(ARCHIVE_WARN, - archive_entry_xattr_next(e, &xname, &xval, &xsize)); - assertEqualString(xname, NULL); - assertEqualString(xval, NULL); - assertEqualInt((int)xsize, 0); - - - /* - * Test clone() implementation. - */ - - /* Set values in 'e' */ - archive_entry_clear(e); - archive_entry_set_atime(e, 13579, 24680); - archive_entry_set_birthtime(e, 13779, 24990); - archive_entry_set_ctime(e, 13580, 24681); - archive_entry_set_dev(e, 235); - archive_entry_set_fflags(e, 0x55, 0xAA); - archive_entry_set_gid(e, 204); - archive_entry_set_gname(e, "group"); - archive_entry_set_hardlink(e, "hardlinkname"); - archive_entry_set_ino(e, 8593); - archive_entry_set_mode(e, 0123456); - archive_entry_set_mtime(e, 13581, 24682); - archive_entry_set_nlink(e, 736); - archive_entry_set_pathname(e, "path"); - archive_entry_set_rdev(e, 532); - archive_entry_set_size(e, 987654321); - archive_entry_copy_sourcepath(e, "source"); - archive_entry_set_symlink(e, "symlinkname"); - archive_entry_set_uid(e, 83); - archive_entry_set_uname(e, "user"); - /* Add an ACL entry. */ - archive_entry_acl_add_entry(e, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - ARCHIVE_ENTRY_ACL_READ, ARCHIVE_ENTRY_ACL_USER, 77, "user77"); - /* Add an extended attribute. */ - archive_entry_xattr_add_entry(e, "xattr1", "xattrvalue", 11); - - /* Make a clone. */ - e2 = archive_entry_clone(e); - - /* Clone should have same contents. */ - assertEqualInt(archive_entry_atime(e2), 13579); - assertEqualInt(archive_entry_atime_nsec(e2), 24680); - assertEqualInt(archive_entry_birthtime(e2), 13779); - assertEqualInt(archive_entry_birthtime_nsec(e2), 24990); - assertEqualInt(archive_entry_ctime(e2), 13580); - assertEqualInt(archive_entry_ctime_nsec(e2), 24681); - assertEqualInt(archive_entry_dev(e2), 235); - archive_entry_fflags(e, &set, &clear); - assertEqualInt(clear, 0xAA); - assertEqualInt(set, 0x55); - assertEqualInt(archive_entry_gid(e2), 204); - assertEqualString(archive_entry_gname(e2), "group"); - assertEqualString(archive_entry_hardlink(e2), "hardlinkname"); - assertEqualInt(archive_entry_ino(e2), 8593); - assertEqualInt(archive_entry_mode(e2), 0123456); - assertEqualInt(archive_entry_mtime(e2), 13581); - assertEqualInt(archive_entry_mtime_nsec(e2), 24682); - assertEqualInt(archive_entry_nlink(e2), 736); - assertEqualString(archive_entry_pathname(e2), "path"); - assertEqualInt(archive_entry_rdev(e2), 532); - assertEqualInt(archive_entry_size(e2), 987654321); - assertEqualString(archive_entry_sourcepath(e2), "source"); - assertEqualString(archive_entry_symlink(e2), "symlinkname"); - assertEqualInt(archive_entry_uid(e2), 83); - assertEqualString(archive_entry_uname(e2), "user"); - - /* Verify ACL was copied. */ - assertEqualInt(4, archive_entry_acl_reset(e2, - ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); - /* First three are standard permission bits. */ - assertEqualInt(0, archive_entry_acl_next(e2, - ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - &type, &permset, &tag, &qual, &name)); - assertEqualInt(type, ARCHIVE_ENTRY_ACL_TYPE_ACCESS); - assertEqualInt(permset, 4); - assertEqualInt(tag, ARCHIVE_ENTRY_ACL_USER_OBJ); - assertEqualInt(qual, -1); - assertEqualString(name, NULL); - assertEqualInt(0, archive_entry_acl_next(e2, - ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - &type, &permset, &tag, &qual, &name)); - assertEqualInt(type, ARCHIVE_ENTRY_ACL_TYPE_ACCESS); - assertEqualInt(permset, 5); - assertEqualInt(tag, ARCHIVE_ENTRY_ACL_GROUP_OBJ); - assertEqualInt(qual, -1); - assertEqualString(name, NULL); - assertEqualInt(0, archive_entry_acl_next(e2, - ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - &type, &permset, &tag, &qual, &name)); - assertEqualInt(type, ARCHIVE_ENTRY_ACL_TYPE_ACCESS); - assertEqualInt(permset, 6); - assertEqualInt(tag, ARCHIVE_ENTRY_ACL_OTHER); - assertEqualInt(qual, -1); - assertEqualString(name, NULL); - /* Fourth is custom one. */ - assertEqualInt(0, archive_entry_acl_next(e2, - ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - &type, &permset, &tag, &qual, &name)); - assertEqualInt(type, ARCHIVE_ENTRY_ACL_TYPE_ACCESS); - assertEqualInt(permset, ARCHIVE_ENTRY_ACL_READ); - assertEqualInt(tag, ARCHIVE_ENTRY_ACL_USER); - assertEqualInt(qual, 77); - assertEqualString(name, "user77"); - - /* Verify xattr was copied. */ - assertEqualInt(1, archive_entry_xattr_reset(e2)); - assertEqualInt(0, archive_entry_xattr_next(e2, &xname, &xval, &xsize)); - assertEqualString(xname, "xattr1"); - assertEqualString(xval, "xattrvalue"); - assertEqualInt((int)xsize, 11); - assertEqualInt(ARCHIVE_WARN, - archive_entry_xattr_next(e2, &xname, &xval, &xsize)); - assertEqualString(xname, NULL); - assertEqualString(xval, NULL); - assertEqualInt((int)xsize, 0); - - /* Change the original */ - archive_entry_set_atime(e, 13580, 24690); - archive_entry_set_birthtime(e, 13980, 24999); - archive_entry_set_ctime(e, 13590, 24691); - archive_entry_set_dev(e, 245); - archive_entry_set_fflags(e, 0x85, 0xDA); - archive_entry_set_filetype(e, AE_IFLNK); - archive_entry_set_gid(e, 214); - archive_entry_set_gname(e, "grouper"); - archive_entry_set_hardlink(e, "hardlinkpath"); - archive_entry_set_ino(e, 8763); - archive_entry_set_mode(e, 0123654); - archive_entry_set_mtime(e, 18351, 28642); - archive_entry_set_nlink(e, 73); - archive_entry_set_pathname(e, "pathest"); - archive_entry_set_rdev(e, 132); - archive_entry_set_size(e, 987456321); - archive_entry_copy_sourcepath(e, "source2"); - archive_entry_set_symlink(e, "symlinkpath"); - archive_entry_set_uid(e, 93); - archive_entry_set_uname(e, "username"); - archive_entry_acl_clear(e); - archive_entry_xattr_clear(e); - - /* Clone should still have same contents. */ - assertEqualInt(archive_entry_atime(e2), 13579); - assertEqualInt(archive_entry_atime_nsec(e2), 24680); - assertEqualInt(archive_entry_birthtime(e2), 13779); - assertEqualInt(archive_entry_birthtime_nsec(e2), 24990); - assertEqualInt(archive_entry_ctime(e2), 13580); - assertEqualInt(archive_entry_ctime_nsec(e2), 24681); - assertEqualInt(archive_entry_dev(e2), 235); - archive_entry_fflags(e2, &set, &clear); - assertEqualInt(clear, 0xAA); - assertEqualInt(set, 0x55); - assertEqualInt(archive_entry_gid(e2), 204); - assertEqualString(archive_entry_gname(e2), "group"); - assertEqualString(archive_entry_hardlink(e2), "hardlinkname"); - assertEqualInt(archive_entry_ino(e2), 8593); - assertEqualInt(archive_entry_mode(e2), 0123456); - assertEqualInt(archive_entry_mtime(e2), 13581); - assertEqualInt(archive_entry_mtime_nsec(e2), 24682); - assertEqualInt(archive_entry_nlink(e2), 736); - assertEqualString(archive_entry_pathname(e2), "path"); - assertEqualInt(archive_entry_rdev(e2), 532); - assertEqualInt(archive_entry_size(e2), 987654321); - assertEqualString(archive_entry_sourcepath(e2), "source"); - assertEqualString(archive_entry_symlink(e2), "symlinkname"); - assertEqualInt(archive_entry_uid(e2), 83); - assertEqualString(archive_entry_uname(e2), "user"); - - /* Verify ACL was unchanged. */ - assertEqualInt(4, archive_entry_acl_reset(e2, - ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); - /* First three are standard permission bits. */ - assertEqualInt(0, archive_entry_acl_next(e2, - ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - &type, &permset, &tag, &qual, &name)); - assertEqualInt(type, ARCHIVE_ENTRY_ACL_TYPE_ACCESS); - assertEqualInt(permset, 4); - assertEqualInt(tag, ARCHIVE_ENTRY_ACL_USER_OBJ); - assertEqualInt(qual, -1); - assertEqualString(name, NULL); - assertEqualInt(0, archive_entry_acl_next(e2, - ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - &type, &permset, &tag, &qual, &name)); - assertEqualInt(type, ARCHIVE_ENTRY_ACL_TYPE_ACCESS); - assertEqualInt(permset, 5); - assertEqualInt(tag, ARCHIVE_ENTRY_ACL_GROUP_OBJ); - assertEqualInt(qual, -1); - assertEqualString(name, NULL); - assertEqualInt(0, archive_entry_acl_next(e2, - ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - &type, &permset, &tag, &qual, &name)); - assertEqualInt(type, ARCHIVE_ENTRY_ACL_TYPE_ACCESS); - assertEqualInt(permset, 6); - assertEqualInt(tag, ARCHIVE_ENTRY_ACL_OTHER); - assertEqualInt(qual, -1); - assertEqualString(name, NULL); - /* Fourth is custom one. */ - assertEqualInt(0, archive_entry_acl_next(e2, - ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - &type, &permset, &tag, &qual, &name)); - assertEqualInt(type, ARCHIVE_ENTRY_ACL_TYPE_ACCESS); - assertEqualInt(permset, ARCHIVE_ENTRY_ACL_READ); - assertEqualInt(tag, ARCHIVE_ENTRY_ACL_USER); - assertEqualInt(qual, 77); - assertEqualString(name, "user77"); - assertEqualInt(1, archive_entry_acl_next(e2, - ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - &type, &permset, &tag, &qual, &name)); - assertEqualInt(type, 0); - assertEqualInt(permset, 0); - assertEqualInt(tag, 0); - assertEqualInt(qual, -1); - assertEqualString(name, NULL); - - /* Verify xattr was unchanged. */ - assertEqualInt(1, archive_entry_xattr_reset(e2)); - - /* Release clone. */ - archive_entry_free(e2); - - /* - * Test clear() implementation. - */ - archive_entry_clear(e); - assertEqualInt(archive_entry_atime(e), 0); - assertEqualInt(archive_entry_atime_nsec(e), 0); - assertEqualInt(archive_entry_birthtime(e), 0); - assertEqualInt(archive_entry_birthtime_nsec(e), 0); - assertEqualInt(archive_entry_ctime(e), 0); - assertEqualInt(archive_entry_ctime_nsec(e), 0); - assertEqualInt(archive_entry_dev(e), 0); - archive_entry_fflags(e, &set, &clear); - assertEqualInt(clear, 0); - assertEqualInt(set, 0); - assertEqualInt(archive_entry_filetype(e), 0); - assertEqualInt(archive_entry_gid(e), 0); - assertEqualString(archive_entry_gname(e), NULL); - assertEqualString(archive_entry_hardlink(e), NULL); - assertEqualInt(archive_entry_ino(e), 0); - assertEqualInt(archive_entry_mode(e), 0); - assertEqualInt(archive_entry_mtime(e), 0); - assertEqualInt(archive_entry_mtime_nsec(e), 0); - assertEqualInt(archive_entry_nlink(e), 0); - assertEqualString(archive_entry_pathname(e), NULL); - assertEqualInt(archive_entry_rdev(e), 0); - assertEqualInt(archive_entry_size(e), 0); - assertEqualString(archive_entry_symlink(e), NULL); - assertEqualInt(archive_entry_uid(e), 0); - assertEqualString(archive_entry_uname(e), NULL); - /* ACLs should be cleared. */ - assertEqualInt(archive_entry_acl_count(e, ARCHIVE_ENTRY_ACL_TYPE_ACCESS), 0); - assertEqualInt(archive_entry_acl_count(e, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT), 0); - /* Extended attributes should be cleared. */ - assertEqualInt(archive_entry_xattr_count(e), 0); - - /* - * Test archive_entry_copy_stat(). - */ - memset(&st, 0, sizeof(st)); - /* Set all of the standard 'struct stat' fields. */ - st.st_atime = 456789; - st.st_ctime = 345678; - st.st_dev = 123; - st.st_gid = 34; - st.st_ino = 234; - st.st_mode = 077777; - st.st_mtime = 234567; - st.st_nlink = 345; - st.st_size = 123456789; - st.st_uid = 23; -#ifdef __FreeBSD__ - /* On FreeBSD, high-res timestamp data should come through. */ - st.st_atimespec.tv_nsec = 6543210; - st.st_ctimespec.tv_nsec = 5432109; - st.st_mtimespec.tv_nsec = 3210987; - st.st_birthtimespec.tv_nsec = 7459386; -#endif - /* Copy them into the entry. */ - archive_entry_copy_stat(e, &st); - /* Read each one back separately and compare. */ - assertEqualInt(archive_entry_atime(e), 456789); - assertEqualInt(archive_entry_ctime(e), 345678); - assertEqualInt(archive_entry_dev(e), 123); - assertEqualInt(archive_entry_gid(e), 34); - assertEqualInt(archive_entry_ino(e), 234); - assertEqualInt(archive_entry_mode(e), 077777); - assertEqualInt(archive_entry_mtime(e), 234567); - assertEqualInt(archive_entry_nlink(e), 345); - assertEqualInt(archive_entry_size(e), 123456789); - assertEqualInt(archive_entry_uid(e), 23); -#if __FreeBSD__ - /* On FreeBSD, high-res timestamp data should come through. */ - assertEqualInt(archive_entry_atime_nsec(e), 6543210); - assertEqualInt(archive_entry_ctime_nsec(e), 5432109); - assertEqualInt(archive_entry_mtime_nsec(e), 3210987); - assertEqualInt(archive_entry_birthtime_nsec(e), 7459386); -#endif - - /* - * Test archive_entry_stat(). - */ - /* First, clear out any existing stat data. */ - memset(&st, 0, sizeof(st)); - archive_entry_copy_stat(e, &st); - /* Set a bunch of fields individually. */ - archive_entry_set_atime(e, 456789, 321); - archive_entry_set_ctime(e, 345678, 432); - archive_entry_set_dev(e, 123); - archive_entry_set_gid(e, 34); - archive_entry_set_ino(e, 234); - archive_entry_set_mode(e, 012345); - archive_entry_set_mode(e, 012345); - archive_entry_set_mtime(e, 234567, 543); - archive_entry_set_nlink(e, 345); - archive_entry_set_size(e, 123456789); - archive_entry_set_uid(e, 23); - /* Retrieve a stat structure. */ - assert((pst = archive_entry_stat(e)) != NULL); - if (pst == NULL) - return; - /* Check that the values match. */ - assertEqualInt(pst->st_atime, 456789); - assertEqualInt(pst->st_ctime, 345678); - assertEqualInt(pst->st_dev, 123); - assertEqualInt(pst->st_gid, 34); - assertEqualInt(pst->st_ino, 234); - assertEqualInt(pst->st_mode, 012345); - assertEqualInt(pst->st_mtime, 234567); - assertEqualInt(pst->st_nlink, 345); - assertEqualInt(pst->st_size, 123456789); - assertEqualInt(pst->st_uid, 23); -#ifdef __FreeBSD__ - /* On FreeBSD, high-res timestamp data should come through. */ - assertEqualInt(pst->st_atimespec.tv_nsec, 321); - assertEqualInt(pst->st_ctimespec.tv_nsec, 432); - assertEqualInt(pst->st_mtimespec.tv_nsec, 543); -#endif - - /* Changing any one value should update struct stat. */ - archive_entry_set_atime(e, 456788, 0); - assert((pst = archive_entry_stat(e)) != NULL); - if (pst == NULL) - return; - assertEqualInt(pst->st_atime, 456788); - archive_entry_set_ctime(e, 345677, 431); - assert((pst = archive_entry_stat(e)) != NULL); - if (pst == NULL) - return; - assertEqualInt(pst->st_ctime, 345677); - archive_entry_set_dev(e, 122); - assert((pst = archive_entry_stat(e)) != NULL); - if (pst == NULL) - return; - assertEqualInt(pst->st_dev, 122); - archive_entry_set_gid(e, 33); - assert((pst = archive_entry_stat(e)) != NULL); - if (pst == NULL) - return; - assertEqualInt(pst->st_gid, 33); - archive_entry_set_ino(e, 233); - assert((pst = archive_entry_stat(e)) != NULL); - if (pst == NULL) - return; - assertEqualInt(pst->st_ino, 233); - archive_entry_set_mode(e, 012344); - assert((pst = archive_entry_stat(e)) != NULL); - if (pst == NULL) - return; - assertEqualInt(pst->st_mode, 012344); - archive_entry_set_mtime(e, 234566, 542); - assert((pst = archive_entry_stat(e)) != NULL); - if (pst == NULL) - return; - assertEqualInt(pst->st_mtime, 234566); - archive_entry_set_nlink(e, 344); - assert((pst = archive_entry_stat(e)) != NULL); - if (pst == NULL) - return; - assertEqualInt(pst->st_nlink, 344); - archive_entry_set_size(e, 123456788); - assert((pst = archive_entry_stat(e)) != NULL); - if (pst == NULL) - return; - assertEqualInt(pst->st_size, 123456788); - archive_entry_set_uid(e, 22); - assert((pst = archive_entry_stat(e)) != NULL); - if (pst == NULL) - return; - assertEqualInt(pst->st_uid, 22); - /* We don't need to check high-res fields here. */ - - /* - * Test dev/major/minor interfaces. Setting 'dev' or 'rdev' - * should change the corresponding major/minor values, and - * vice versa. - * - * The test here is system-specific because it assumes that - * makedev(), major(), and minor() are defined in sys/stat.h. - * I'm not too worried about it, though, because the code is - * simple. If it works on FreeBSD, it's unlikely to be broken - * anywhere else. Note: The functionality is present on every - * platform even if these tests only run some places; - * libarchive's more extensive configuration logic should find - * the necessary definitions on every platform. - */ -#if __FreeBSD__ - archive_entry_set_dev(e, 0x12345678); - assertEqualInt(archive_entry_devmajor(e), major(0x12345678)); - assertEqualInt(archive_entry_devminor(e), minor(0x12345678)); - assertEqualInt(archive_entry_dev(e), 0x12345678); - archive_entry_set_devmajor(e, 0xfe); - archive_entry_set_devminor(e, 0xdcba98); - assertEqualInt(archive_entry_devmajor(e), 0xfe); - assertEqualInt(archive_entry_devminor(e), 0xdcba98); - assertEqualInt(archive_entry_dev(e), makedev(0xfe, 0xdcba98)); - archive_entry_set_rdev(e, 0x12345678); - assertEqualInt(archive_entry_rdevmajor(e), major(0x12345678)); - assertEqualInt(archive_entry_rdevminor(e), minor(0x12345678)); - assertEqualInt(archive_entry_rdev(e), 0x12345678); - archive_entry_set_rdevmajor(e, 0xfe); - archive_entry_set_rdevminor(e, 0xdcba98); - assertEqualInt(archive_entry_rdevmajor(e), 0xfe); - assertEqualInt(archive_entry_rdevminor(e), 0xdcba98); - assertEqualInt(archive_entry_rdev(e), makedev(0xfe, 0xdcba98)); -#endif - - /* - * Exercise the character-conversion logic, if we can. - */ - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("Can't exercise charset-conversion logic without" - " a suitable locale."); - } else { - /* A filename that cannot be converted to wide characters. */ - archive_entry_copy_pathname(e, "abc\314\214mno\374xyz"); - failure("Converting invalid chars to Unicode should fail."); - assert(NULL == archive_entry_pathname_w(e)); - /* - failure("Converting invalid chars to UTF-8 should fail."); - assert(NULL == archive_entry_pathname_utf8(e)); - */ - - /* A group name that cannot be converted. */ - archive_entry_copy_gname(e, "abc\314\214mno\374xyz"); - failure("Converting invalid chars to Unicode should fail."); - assert(NULL == archive_entry_gname_w(e)); - - /* A user name that cannot be converted. */ - archive_entry_copy_uname(e, "abc\314\214mno\374xyz"); - failure("Converting invalid chars to Unicode should fail."); - assert(NULL == archive_entry_uname_w(e)); - - /* A hardlink target that cannot be converted. */ - archive_entry_copy_hardlink(e, "abc\314\214mno\374xyz"); - failure("Converting invalid chars to Unicode should fail."); - assert(NULL == archive_entry_hardlink_w(e)); - - /* A symlink target that cannot be converted. */ - archive_entry_copy_symlink(e, "abc\314\214mno\374xyz"); - failure("Converting invalid chars to Unicode should fail."); - assert(NULL == archive_entry_symlink_w(e)); - } - - l = 0x12345678L; - wc = (wchar_t)l; /* Wide character too big for UTF-8. */ - if (NULL == setlocale(LC_ALL, "C") || (long)wc != l) { - skipping("Testing charset conversion failure requires 32-bit wchar_t and support for \"C\" locale."); - } else { - /* - * Build the string L"xxx\U12345678yyy\u5678zzz" without - * using wcscpy or C99 \u#### syntax. - */ - name = "xxxAyyyBzzz"; - for (i = 0; i < (int)strlen(name); ++i) - wbuff[i] = name[i]; - wbuff[3] = (wchar_t)0x12345678; - wbuff[7] = (wchar_t)0x5678; - /* A Unicode filename that cannot be converted to UTF-8. */ - archive_entry_copy_pathname_w(e, wbuff); - failure("Converting wide characters from Unicode should fail."); - assertEqualString(NULL, archive_entry_pathname(e)); - } - - /* Release the experimental entry. */ - archive_entry_free(e); -} diff --git a/thirdparty/libarchive/libarchive/test/test_entry_strmode.c b/thirdparty/libarchive/libarchive/test/test_entry_strmode.c deleted file mode 100644 index ba183db02..000000000 --- a/thirdparty/libarchive/libarchive/test/test_entry_strmode.c +++ /dev/null @@ -1,71 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_entry_strmode.c 201247 2009-12-30 05:59:21Z kientzle $"); - -DEFINE_TEST(test_entry_strmode) -{ - struct archive_entry *entry; - - assert((entry = archive_entry_new()) != NULL); - - archive_entry_set_mode(entry, AE_IFREG | 0642); - assertEqualString(archive_entry_strmode(entry), "-rw-r---w- "); - - /* Regular file + hardlink still shows as regular file. */ - archive_entry_set_mode(entry, AE_IFREG | 0644); - archive_entry_set_hardlink(entry, "link"); - assertEqualString(archive_entry_strmode(entry), "-rw-r--r-- "); - - archive_entry_set_mode(entry, 0640); - archive_entry_set_hardlink(entry, "link"); - assertEqualString(archive_entry_strmode(entry), "hrw-r----- "); - archive_entry_set_hardlink(entry, NULL); - - archive_entry_set_mode(entry, AE_IFDIR | 0777); - assertEqualString(archive_entry_strmode(entry), "drwxrwxrwx "); - - archive_entry_set_mode(entry, AE_IFBLK | 03642); - assertEqualString(archive_entry_strmode(entry), "brw-r-S-wT "); - - archive_entry_set_mode(entry, AE_IFCHR | 05777); - assertEqualString(archive_entry_strmode(entry), "crwsrwxrwt "); - - archive_entry_set_mode(entry, AE_IFSOCK | 0222); - assertEqualString(archive_entry_strmode(entry), "s-w--w--w- "); - - archive_entry_set_mode(entry, AE_IFIFO | 0444); - assertEqualString(archive_entry_strmode(entry), "pr--r--r-- "); - - archive_entry_set_mode(entry, AE_IFLNK | 04000); - assertEqualString(archive_entry_strmode(entry), "l--S------ "); - - archive_entry_acl_add_entry(entry, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, - 0007, ARCHIVE_ENTRY_ACL_GROUP, 78, "group78"); - assertEqualString(archive_entry_strmode(entry), "l--S------+"); - - /* Release the experimental entry. */ - archive_entry_free(entry); -} diff --git a/thirdparty/libarchive/libarchive/test/test_extattr_freebsd.c b/thirdparty/libarchive/libarchive/test/test_extattr_freebsd.c deleted file mode 100644 index 7cb30b560..000000000 --- a/thirdparty/libarchive/libarchive/test/test_extattr_freebsd.c +++ /dev/null @@ -1,153 +0,0 @@ -/*- - * Copyright (c) 2003-2009 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_extattr_freebsd.c 201247 2009-12-30 05:59:21Z kientzle $"); - -#if defined(__FreeBSD__) && __FreeBSD__ > 4 -#include -#endif - -/* - * Verify extended attribute restore-to-disk. This test is FreeBSD-specific. - */ - -DEFINE_TEST(test_extattr_freebsd) -{ -#if !defined(__FreeBSD__) - skipping("FreeBSD-specific extattr restore test"); -#elif __FreeBSD__ < 5 - skipping("extattr restore supported only on FreeBSD 5.0 and later"); -#else - char buff[64]; - const char *xname; - const void *xval; - size_t xsize; - struct stat st; - struct archive *a; - struct archive_entry *ae; - int n, fd; - - /* - * First, do a quick manual set/read of an extended attribute - * to verify that the local filesystem does support it. If it - * doesn't, we'll simply skip the remaining tests. - */ - /* Create a test file and try to set an ACL on it. */ - fd = open("pretest", O_RDWR | O_CREAT, 0777); - failure("Could not create test file?!"); - if (!assert(fd >= 0)) - return; - - errno = 0; - n = extattr_set_fd(fd, EXTATTR_NAMESPACE_USER, "testattr", "1234", 4); - if (n != 4 && errno == EOPNOTSUPP) { - close(fd); - skipping("extattr tests require that extattr support be enabled on the filesystem"); - return; - } - failure("extattr_set_fd(): errno=%d (%s)", errno, strerror(errno)); - assertEqualInt(4, n); - close(fd); - - /* Create a write-to-disk object. */ - assert(NULL != (a = archive_write_disk_new())); - archive_write_disk_set_options(a, - ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_XATTR); - - /* Populate an archive entry with an extended attribute. */ - ae = archive_entry_new(); - assert(ae != NULL); - archive_entry_set_pathname(ae, "test0"); - archive_entry_set_mtime(ae, 123456, 7890); - archive_entry_set_size(ae, 0); - archive_entry_set_mode(ae, 0755); - archive_entry_xattr_add_entry(ae, "user.foo", "12345", 5); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_finish_entry(a)); - archive_entry_free(ae); - - /* Another entry; similar but with mode = 0. */ - ae = archive_entry_new(); - assert(ae != NULL); - archive_entry_set_pathname(ae, "test1"); - archive_entry_set_mtime(ae, 12345678, 7890); - archive_entry_set_size(ae, 0); - archive_entry_set_mode(ae, 0); - archive_entry_xattr_add_entry(ae, "user.bar", "123456", 6); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Close the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - - /* Verify the data on disk. */ - assertEqualInt(0, stat("test0", &st)); - assertEqualInt(st.st_mtime, 123456); - assertEqualInt(st.st_mode & 0777, 0755); - /* Verify extattr */ - n = extattr_get_file("test0", EXTATTR_NAMESPACE_USER, - "foo", buff, sizeof(buff)); - if (assertEqualInt(n, 5)) { - buff[n] = '\0'; - assertEqualString(buff, "12345"); - } - - /* Verify the data on disk. */ - assertEqualInt(0, stat("test1", &st)); - assertEqualInt(st.st_mtime, 12345678); - assertEqualInt(st.st_mode & 0777, 0); - /* - * If we are not root, we have to make test1 user readable - * or extattr_get_file() will fail - */ - if (geteuid() != 0) { - chmod("test1", S_IRUSR); - } - /* Verify extattr */ - n = extattr_get_file("test1", EXTATTR_NAMESPACE_USER, - "bar", buff, sizeof(buff)); - if (assertEqualInt(n, 6)) { - buff[n] = '\0'; - assertEqualString(buff, "123456"); - } - - /* Use libarchive APIs to read the file back into an entry and - * verify that the extattr was read correctly. */ - assert((a = archive_read_disk_new()) != NULL); - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_pathname(ae, "test0"); - assertEqualInt(ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - assertEqualInt(1, archive_entry_xattr_reset(ae)); - assertEqualInt(ARCHIVE_OK, - archive_entry_xattr_next(ae, &xname, &xval, &xsize)); - assertEqualString(xname, "user.foo"); - assertEqualInt(xsize, 5); - assertEqualMem(xval, "12345", xsize); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - archive_entry_free(ae); -#endif -} diff --git a/thirdparty/libarchive/libarchive/test/test_filter_count.c b/thirdparty/libarchive/libarchive/test/test_filter_count.c deleted file mode 100644 index 4885ab89a..000000000 --- a/thirdparty/libarchive/libarchive/test/test_filter_count.c +++ /dev/null @@ -1,80 +0,0 @@ -/*- - * Copyright (c) 2003-2009 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_file_nonexistent.c 189473 2009-03-07 02:09:21Z kientzle $"); - -static void read_test(const char *name); -static void write_test(void); - -static void -read_test(const char *name) -{ - struct archive* a = archive_read_new(); - int r; - - r = archive_read_support_filter_bzip2(a); - if((ARCHIVE_WARN == r && !canBzip2()) || ARCHIVE_WARN > r) { - skipping("bzip2 unsupported"); - return; - } - - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - - extract_reference_file(name); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 2)); - /* bzip2 and none */ - assertEqualInt(2, archive_filter_count(a)); - - archive_read_free(a); -} - -static void -write_test(void) -{ - char buff[4096]; - struct archive* a = archive_write_new(); - int r; - - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_bytes_per_block(a, 10)); - - r = archive_write_add_filter_bzip2(a); - if((ARCHIVE_WARN == r && !canBzip2()) || ARCHIVE_WARN > r) { - skipping("bzip2 unsupported"); - return; - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, 4096, 0)); - /* bzip2 and none */ - assertEqualInt(2, archive_filter_count(a)); - archive_write_free(a); -} - -DEFINE_TEST(test_filter_count) -{ - read_test("test_compat_bzip2_1.tbz"); - write_test(); -} - - diff --git a/thirdparty/libarchive/libarchive/test/test_fuzz.c b/thirdparty/libarchive/libarchive/test/test_fuzz.c deleted file mode 100644 index 8af4c2f29..000000000 --- a/thirdparty/libarchive/libarchive/test/test_fuzz.c +++ /dev/null @@ -1,644 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_fuzz.c 201247 2009-12-30 05:59:21Z kientzle $"); - -/* - * This was inspired by an ISO fuzz tester written by Michal Zalewski - * and posted to the "vulnwatch" mailing list on March 17, 2005: - * http://seclists.org/vulnwatch/2005/q1/0088.html - * - * This test simply reads each archive image into memory, pokes - * random values into it and runs it through libarchive. It tries - * to damage about 1% of each file and repeats the exercise 100 times - * with each file. - * - * Unlike most other tests, this test does not verify libarchive's - * responses other than to ensure that libarchive doesn't crash. - * - * Due to the deliberately random nature of this test, it may be hard - * to reproduce failures. Because this test deliberately attempts to - * induce crashes, there's little that can be done in the way of - * post-failure diagnostics. - */ - -/* Because this works for any archive, we can just re-use the archives - * developed for other tests. */ -struct files { - int uncompress; /* If 1, decompress the file before fuzzing. */ - const char **names; -}; - -static void -test_fuzz(const struct files *filesets) -{ - const void *blk; - size_t blk_size; - int64_t blk_offset; - int n; - const char *skip_fuzz_tests; - - skip_fuzz_tests = getenv("SKIP_TEST_FUZZ"); - if (skip_fuzz_tests != NULL) { - skipping("Skipping fuzz tests due to SKIP_TEST_FUZZ " - "environment variable"); - return; - } - - for (n = 0; filesets[n].names != NULL; ++n) { - const size_t buffsize = 30000000; - struct archive_entry *ae; - struct archive *a; - char *rawimage = NULL, *image = NULL, *tmp = NULL; - size_t size = 0, oldsize = 0; - int i, q; - - extract_reference_files(filesets[n].names); - if (filesets[n].uncompress) { - int r; - /* Use format_raw to decompress the data. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_raw(a)); - r = archive_read_open_filenames(a, filesets[n].names, 16384); - if (r != ARCHIVE_OK) { - archive_read_free(a); - if (filesets[n].names[0] == NULL || filesets[n].names[1] == NULL) { - skipping("Cannot uncompress fileset"); - } else { - skipping("Cannot uncompress %s", filesets[n].names[0]); - } - continue; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_next_header(a, &ae)); - rawimage = malloc(buffsize); - size = archive_read_data(a, rawimage, buffsize); - assertEqualIntA(a, ARCHIVE_EOF, - archive_read_next_header(a, &ae)); - assertEqualInt(ARCHIVE_OK, - archive_read_free(a)); - assert(size > 0); - if (filesets[n].names[0] == NULL || filesets[n].names[1] == NULL) { - failure("Internal buffer is not big enough for " - "uncompressed test files"); - } else { - failure("Internal buffer is not big enough for " - "uncompressed test file: %s", filesets[n].names[0]); - } - if (!assert(size < buffsize)) { - free(rawimage); - rawimage = NULL; - continue; - } - } else { - for (i = 0; filesets[n].names[i] != NULL; ++i) - { - char *newraw; - tmp = slurpfile(&size, "%s", - filesets[n].names[i]); - newraw = realloc(rawimage, oldsize + size); - if (!assert(newraw != NULL)) - { - free(tmp); - size = 0; - break; - } - rawimage = newraw; - memcpy(rawimage + oldsize, tmp, size); - oldsize += size; - size = oldsize; - free(tmp); - } - } - if (size == 0) { - free(rawimage); - rawimage = NULL; - continue; - } - image = malloc(size); - assert(image != NULL); - if (image == NULL) { - free(rawimage); - rawimage = NULL; - return; - } - - assert(rawimage != NULL); - - srand((unsigned)time(NULL)); - - for (i = 0; i < 1000; ++i) { - FILE *f; - int j, numbytes, trycnt; - - /* Fuzz < 1% of the bytes in the archive. */ - memcpy(image, rawimage, size); - q = (int)size / 100; - if (q < 4) - q = 4; - numbytes = (int)(rand() % q); - for (j = 0; j < numbytes; ++j) - image[rand() % size] = (char)rand(); - - /* Save the messed-up image to a file. - * If we crash, that file will be useful. */ - for (trycnt = 0; trycnt < 3; trycnt++) { - f = fopen("after.test.failure.send.this.file." - "to.libarchive.maintainers.with.system.details", "wb"); - if (f != NULL) - break; -#if defined(_WIN32) && !defined(__CYGWIN__) - /* - * Sometimes previous close operation does not completely - * end at this time. So we should take a wait while - * the operation running. - */ - Sleep(100); -#endif - } - assert(f != NULL); - assertEqualInt((size_t)size, fwrite(image, 1, (size_t)size, f)); - fclose(f); - - // Try to read all headers and bodies. - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_all(a)); - - if (0 == archive_read_open_memory(a, image, size)) { - while(0 == archive_read_next_header(a, &ae)) { - while (0 == archive_read_data_block(a, - &blk, &blk_size, &blk_offset)) - continue; - } - archive_read_close(a); - } - archive_read_free(a); - - // Just list headers, skip bodies. - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_all(a)); - - if (0 == archive_read_open_memory(a, image, size)) { - while(0 == archive_read_next_header(a, &ae)) { - } - archive_read_close(a); - } - archive_read_free(a); - } - free(image); - free(rawimage); - } -} - -DEFINE_TEST(test_fuzz_ar) -{ - static const char *fileset1[] = { - "test_read_format_ar.ar", - NULL - }; - static const struct files filesets[] = { - {0, fileset1}, - {1, NULL} - }; - test_fuzz(filesets); -} - -DEFINE_TEST(test_fuzz_cab) -{ - static const char *fileset1[] = { - "test_fuzz.cab", - NULL - }; - static const struct files filesets[] = { - {0, fileset1}, - {1, NULL} - }; - test_fuzz(filesets); -} - -DEFINE_TEST(test_fuzz_cpio) -{ - static const char *fileset1[] = { - "test_read_format_cpio_bin_be.cpio", - NULL - }; - static const char *fileset2[] = { - "test_read_format_cpio_bin_le.cpio", - NULL - }; - static const char *fileset3[] = { - /* Test RPM unwrapper */ - "test_read_format_cpio_svr4_gzip_rpm.rpm", - NULL - }; - static const struct files filesets[] = { - {0, fileset1}, - {0, fileset2}, - {0, fileset3}, - {1, NULL} - }; - test_fuzz(filesets); -} - -DEFINE_TEST(test_fuzz_iso9660) -{ - static const char *fileset1[] = { - "test_fuzz_1.iso.Z", - NULL - }; - static const struct files filesets[] = { - {0, fileset1}, /* Exercise compress decompressor. */ - {1, fileset1}, - {1, NULL} - }; - test_fuzz(filesets); -} - -DEFINE_TEST(test_fuzz_lzh) -{ - static const char *fileset1[] = { - "test_fuzz.lzh", - NULL - }; - static const struct files filesets[] = { - {0, fileset1}, - {1, NULL} - }; - test_fuzz(filesets); -} - -DEFINE_TEST(test_fuzz_mtree) -{ - static const char *fileset1[] = { - "test_read_format_mtree.mtree", - NULL - }; - static const struct files filesets[] = { - {0, fileset1}, - {1, NULL} - }; - test_fuzz(filesets); -} - -DEFINE_TEST(test_fuzz_rar) -{ - static const char *fileset1[] = { - /* Uncompressed RAR test */ - "test_read_format_rar.rar", - NULL - }; - static const char *fileset2[] = { - /* RAR file with binary data */ - "test_read_format_rar_binary_data.rar", - NULL - }; - static const char *fileset3[] = { - /* Best Compressed RAR test */ - "test_read_format_rar_compress_best.rar", - NULL - }; - static const char *fileset4[] = { - /* Normal Compressed RAR test */ - "test_read_format_rar_compress_normal.rar", - NULL - }; - static const char *fileset5[] = { - /* Normal Compressed Multi LZSS blocks RAR test */ - "test_read_format_rar_multi_lzss_blocks.rar", - NULL - }; - static const char *fileset6[] = { - /* RAR with no EOF header */ - "test_read_format_rar_noeof.rar", - NULL - }; - static const char *fileset7[] = { - /* Best Compressed RAR file with both PPMd and LZSS blocks */ - "test_read_format_rar_ppmd_lzss_conversion.rar", - NULL - }; - static const char *fileset8[] = { - /* RAR with subblocks */ - "test_read_format_rar_subblock.rar", - NULL - }; - static const char *fileset9[] = { - /* RAR with Unicode filenames */ - "test_read_format_rar_unicode.rar", - NULL - }; - static const char *fileset10[] = { - "test_read_format_rar_multivolume.part0001.rar", - "test_read_format_rar_multivolume.part0002.rar", - "test_read_format_rar_multivolume.part0003.rar", - "test_read_format_rar_multivolume.part0004.rar", - NULL - }; - static const struct files filesets[] = { - {0, fileset1}, - {0, fileset2}, - {0, fileset3}, - {0, fileset4}, - {0, fileset5}, - {0, fileset6}, - {0, fileset7}, - {0, fileset8}, - {0, fileset9}, - {0, fileset10}, - {1, NULL} - }; - test_fuzz(filesets); -} - -DEFINE_TEST(test_fuzz_tar) -{ - static const char *fileset1[] = { - "test_compat_bzip2_1.tbz", - NULL - }; - static const char *fileset2[] = { - "test_compat_gtar_1.tar", - NULL - }; - static const char *fileset3[] = { - "test_compat_gzip_1.tgz", - NULL - }; - static const char *fileset4[] = { - "test_compat_gzip_2.tgz", - NULL - }; - static const char *fileset5[] = { - "test_compat_tar_hardlink_1.tar", - NULL - }; - static const char *fileset6[] = { - "test_compat_xz_1.txz", - NULL - }; - static const char *fileset7[] = { - "test_read_format_gtar_sparse_1_17_posix10_modified.tar", - NULL - }; - static const char *fileset8[] = { - "test_read_format_tar_empty_filename.tar", - NULL - }; -#if HAVE_LIBLZO2 && HAVE_LZO_LZO1X_H && HAVE_LZO_LZOCONF_H - static const char *fileset9[] = { - "test_compat_lzop_1.tar.lzo", - NULL - }; -#endif -#if HAVE_ZSTD_H && HAVE_LIBZSTD - static const char *fileset10[] = { - "test_compat_zstd_1.tar.zst", - NULL - }; -#endif - static const char *fileset11[] = { - "test_compat_tar_directory_1.tar", - NULL - }; - static const struct files filesets[] = { - {0, fileset1}, /* Exercise bzip2 decompressor. */ - {1, fileset1}, - {0, fileset2}, - {0, fileset3}, /* Exercise gzip decompressor. */ - {0, fileset4}, /* Exercise gzip decompressor. */ - {0, fileset5}, - {0, fileset6}, /* Exercise xz decompressor. */ - {0, fileset7}, - {0, fileset8}, -#if HAVE_LIBLZO2 && HAVE_LZO_LZO1X_H && HAVE_LZO_LZOCONF_H - {0, fileset9}, /* Exercise lzo decompressor. */ -#endif -#if HAVE_ZSTD_H && HAVE_LIBZSTD - {0, fileset10}, /* Exercise zstd decompressor. */ -#endif - {0, fileset11}, - {1, NULL} - }; - test_fuzz(filesets); -} - -DEFINE_TEST(test_fuzz_zip) -{ - static const char *fileset1[] = { - "test_compat_zip_1.zip", - NULL - }; - static const char *fileset2[] = { - "test_compat_zip_2.zip", - NULL - }; - static const char *fileset3[] = { - "test_compat_zip_3.zip", - NULL - }; - static const char *fileset4[] = { - "test_compat_zip_4.zip", - NULL - }; - static const char *fileset5[] = { - "test_compat_zip_5.zip", - NULL - }; - static const char *fileset6[] = { - "test_compat_zip_6.zip", - NULL - }; - static const char *fileset7[] = { - "test_read_format_zip.zip", - NULL - }; - static const char *fileset8[] = { - "test_read_format_zip_comment_stored_1.zip", - NULL - }; - static const char *fileset9[] = { - "test_read_format_zip_comment_stored_2.zip", - NULL - }; - static const char *fileset10[] = { - "test_read_format_zip_encryption_data.zip", - NULL - }; - static const char *fileset11[] = { - "test_read_format_zip_encryption_header.zip", - NULL - }; - static const char *fileset12[] = { - "test_read_format_zip_encryption_partially.zip", - NULL - }; - static const char *fileset13[] = { - "test_read_format_zip_filename_cp866.zip", - NULL - }; - static const char *fileset14[] = { - "test_read_format_zip_filename_cp932.zip", - NULL - }; - static const char *fileset15[] = { - "test_read_format_zip_filename_koi8r.zip", - NULL - }; - static const char *fileset16[] = { - "test_read_format_zip_filename_utf8_jp.zip", - NULL - }; - static const char *fileset17[] = { - "test_read_format_zip_filename_utf8_ru.zip", - NULL - }; - static const char *fileset18[] = { - "test_read_format_zip_filename_utf8_ru2.zip", - NULL - }; - static const char *fileset19[] = { - "test_read_format_zip_length_at_end.zip", - NULL - }; - static const char *fileset20[] = { - "test_read_format_zip_mac_metadata.zip", - NULL - }; - static const char *fileset21[] = { - "test_read_format_zip_malformed1.zip", - NULL - }; - static const char *fileset22[] = { - "test_read_format_zip_msdos.zip", - NULL - }; - static const char *fileset23[] = { - "test_read_format_zip_nested.zip", - NULL - }; - static const char *fileset24[] = { - "test_read_format_zip_nofiletype.zip", - NULL - }; - static const char *fileset25[] = { - "test_read_format_zip_padded1.zip", - NULL - }; - static const char *fileset26[] = { - "test_read_format_zip_padded2.zip", - NULL - }; - static const char *fileset27[] = { - "test_read_format_zip_padded3.zip", - NULL - }; - static const char *fileset28[] = { - "test_read_format_zip_symlink.zip", - NULL - }; - static const char *fileset29[] = { - "test_read_format_zip_traditional_encryption_data.zip", - NULL - }; - static const char *fileset30[] = { - "test_read_format_zip_ux.zip", - NULL - }; - static const char *fileset31[] = { - "test_read_format_zip_winzip_aes128.zip", - NULL - }; - static const char *fileset32[] = { - "test_read_format_zip_winzip_aes256.zip", - NULL - }; - static const char *fileset33[] = { - "test_read_format_zip_winzip_aes256_large.zip", - NULL - }; - static const char *fileset34[] = { - "test_read_format_zip_winzip_aes256_stored.zip", - NULL - }; - static const char *fileset35[] = { - "test_read_format_zip_zip64a.zip", - NULL - }; - static const char *fileset36[] = { - "test_read_format_zip_zip64b.zip", - NULL - }; - - static const struct files filesets[] = { - {0, fileset1}, - {0, fileset2}, - {0, fileset3}, - {0, fileset4}, - {0, fileset5}, - {0, fileset6}, - {0, fileset7}, - {0, fileset8}, - {0, fileset9}, - {0, fileset10}, - {0, fileset11}, - {0, fileset12}, - {0, fileset13}, - {0, fileset14}, - {0, fileset15}, - {0, fileset16}, - {0, fileset17}, - {0, fileset18}, - {0, fileset19}, - {0, fileset20}, - {0, fileset21}, - {0, fileset22}, - {0, fileset23}, - {0, fileset24}, - {0, fileset25}, - {0, fileset26}, - {0, fileset27}, - {0, fileset28}, - {0, fileset29}, - {0, fileset30}, - {0, fileset31}, - {0, fileset32}, - {0, fileset33}, - {0, fileset34}, - {0, fileset35}, - {0, fileset36}, - {1, NULL} - }; - test_fuzz(filesets); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_fuzz.cab.uu b/thirdparty/libarchive/libarchive/test/test_fuzz.cab.uu deleted file mode 100644 index 4cfa4fb7c..000000000 --- a/thirdparty/libarchive/libarchive/test/test_fuzz.cab.uu +++ /dev/null @@ -1,49 +0,0 @@ -begin 644 test_fuzz.cab -M35-#1@`````1"````````"P``````````P$!``0```#X!P``A0````$``Q)K -M````````````G3U:L2``9FEL90#I!```:P``````G3TYL2``24Y35$%,3``` -M!```5`4`````G3U+L2``TJZ47W#V]K5QO-?O,*UMM1=7Z&6N(3I*B -M7Y$H"`"`C`!8T0``@@U#40&N.,IB!B,NC;`!@@1K6"S,%QZ(`(Q4^GA+7Z-Q -M>MPC#M6QMBF^#3"A)"!4#R#__T'[``````0`0$,)0S72^J;^LO[^\?\!@9<$ -M3[(/D"7DB6`%V`4Y!7D8OWK.ES^?WH/(,RQ?XK':#V<`%<.93$<2E23'(WP` -M)7`H\YE-10B('($`-H!!``R4/"3$.5!'J!3;1,@\@?1-`B@=HWZ"B`@^`"&( -M)-)S"#S&P[G2A;V@RRF$;&!`!,=HO&+@Z``H;,8AR%(.J9@/FDJ,#3,(^8?O -M>V4K7/+3XX=@"`!!VLD$Z)_'X%!H!&7IY1-0-VF)VPF='R4F#;,7L6BBQ`=R -M"_6:*GU/CI!$AA]@>9A\`EC&YR(S[1'W7Z!!OQSUC)IK20TT0=OR*6P-DC-" -M*Y7'BNFER]K*4`A,(9Q/!$\P5$\L[FO=TP8LPI\^AAD27\QHZD!IZ$2GL:^8 -MTO4<`"4Y.AE5,,C:.I;G8^&.*)I,A:M!3_=6;[RE5OS*R"?6TA0$-X3`60K/BHM/S;3F.<`#-9Z*046 -M*3`5Z1N)V-I'^O -M9O^Q$U<2F5]8ZS?2FK<94,VRT\2DOU2>GSZ"#9)KMW"^Z2BAU#YG(9=I'VG- -MQ*?V/(8N2/''>I8_?P6EYO1+]4_J(>5`(2$+W54>A!@`=W^"E;L'QT:8\-[/ -M(=#@"OL=_:MZ)N?K@^G.M"A>Y`.H5W*7?GO/X7V1_ -MV$'"#XLT\[2U]\__SY+Q#S_0FISOX&/;B-/T1?A(^O\:C;Z%TF'_](NPV!NW -M*[OS`O0Y2A>W#P$%/.6R96?&F;K@>\QVUK0=",0ET6_GY#85<;V^5_GCRY"48"Q:-[8- -M(5N^IVFN*Q]P[@Y.=_*_H"O_QN]+]4969 -M5=(\E.H;+8[+(AI*1^Q2M=+:J"5Q;8@+\K-;ZKM3S\^\!%"?M\SB;K^GFR<5 -M#*_+K(N;6O,EL^SZ=-5+Q/%K[)O8-V"%U'5>0L_R2/"A6[K._LN6*NG52SV2 -MQ&&>CA9[:JC%@I'!WUHB!AM7SH`=[7NO2QPL]--D81+0'_'J6O>EREVW;"7: -M],(<)3]RSBDD?0BEKR-`&$'\5I*<[/._6JQ1`("H*6-SYWNRRU'=CD^JQ3TM81*T2.A*"+ -M5'LQPWV.2<5=(R+X$=`^^S3=FHHS'2IG9JD.KGKM3+#FZE[UE9P87Y8WB(Z& -M?$#1[81?PAQWW:&9Y?,1JK$LLRXRM-.V(*D]U\JYX3#W'7FW4L5S]"7TN/8[ -M4Q&/5P!ZQ,QA=H1\IFOHRWNVYD15C*-L+T-9]C>6'7RFLH:&BO?ECPY_!;Q` -MU@KWHCS,^-^ -MZ#/LCR\O?](>$O]>\_+L8N`+G2PUM]*;GS>6\:%A1\=*--Q/+C*+,3D7&W\]#5RY>Y"-74FV1N1G:JRS+9$9 -MFB\V'B5R4SKVHFZ-KM\#>(-2J&^.,S6*K0WV2SW\8%PJEUN_!\MKPRDBFJG, -MN(_IL1/].QYO;D;`TV/9FMU-]?9+"WJJ[FN_>H-K#M%1P7SA:F3;T3S%?E:+ -M57(WFA^/KLK0\_=W>14EO`.P[*7Z29_5TSV^PT.+'\JJ0\PLN)MF69W:)\2- -M+5O#DLX9OMZ[S0YF#TK!1:6.6[3+7G);+S%)5>!OVFIVU@PZY\G()FA*J):) -MUKWV:;/X(O7(&,94M+<#A?Y&(X7VE576O"ZQ6R!-&3>Z7&K;GPA9\V``` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_fuzz.lzh.uu b/thirdparty/libarchive/libarchive/test/test_fuzz.lzh.uu deleted file mode 100644 index 781ebbbb6..000000000 --- a/thirdparty/libarchive/libarchive/test/test_fuzz.lzh.uu +++ /dev/null @@ -1,152 +0,0 @@ -begin 644 test_fuzz.lzh -M)L`M;&AD+0```````````$@B[!``!&1ID#Z0,GO2UL:#4M(@```#P`````2"+L(``%9FEL93&D -MYU4`@5$!`*2!Z0/I`P`80FYIQ>/Z`=-:'>9%#"P%J!\CH0"/GE$,.W6FMSD% -M*_4G02UL:#4M(@```$X`````2"+L(``%9FEL93+5%54`@5$!`+:!Z0/I`P`8 -M0FYIQV/Z`=.:'.9%#"P%J-\+H0"/'E$,.W6FMSD%*_T9?RUL:&0M&@`````` -M````2"+L(`$```!5!P`"9&ER_P4`4.A!!P!1Z0/I`P<`5(%1`0```!F!+6QH -M9"T;``````````!((NP@`0```%4(``)D:7(R_P4`4.U!!P!1Z0/I`P<`5(%1 -M`0```!YQ+6QH9"TG``````````%((^P@`05F:6QE,0``510``F1I6UL:6YK,GPN+O\%`%#MH0<`4>D# -MZ0,'`%0"HP(````>!BUL:#4M-0```#P`````2"+L(`$%9FEL93&DYU4%`%"D -M@0<`4>D#Z0,'`%2!40$`````&$)N:<7C^@'36AWF10PL!:@?(Z$`CYY1##MU -MIK40P[=::W.04K -M_34`+6QH9"T``````````(%1`0`@`@``504```7>`P`!!P`"9&ER_P4`4.A! -M!P!1Z0/I`P``-@`M;&AD+0``````````@5$!`"`"``!5!0``")D#``$(``)D -M:7(R_P4`4.U!!P!1Z0/I`P``1P`M;&AD+0```````````J,"`"`"``!5!0`` -MM*D(``%F:6QE,10``F1I6UL:6YK,GPN+O\%`%#MH0<`4>D#Z0,``#,`+6QH-2TB````/````(%1`0`@ -M`J3G504``/T!"``!9FEL93$%`%"D@0<`4>D#Z0,````80FYIQ>/Z`=-:'>9% -M#"P%J!\CH0"/GE$,.W6FMSD%*_4S`"UL:#4M(@```$X```"!40$`(`+5%54% -M```OQ@@``69I;&4R!0!0MH$'`%'I`^D#````&$)N:<=C^@'3FASF10PL!:C? -M"Z$`CQY1##MUIK@_0`9;+`0@`````+J\' -M``````0`+6QH9"T``````````(%1`0`@`P``37T````)````1J0#```%```` -M`0H````"9&ER,O\'````0!``&0```/_M00`````````````A&OY,1!K^3!T` -M``!!2H%NNP&6RP&`UD``J+*=`0!Z#]`!ELL!"`````!]%P<`````!``M;&@U -M+20````\````@5$!`"`#I.=-<0````D```!&I`,```H````!9FEL93$9```` -M_Z2!`````````````,<4_DPC&OY,'0```$$T0J**_I7+`8#60`"HLIT!_G*D -MO`&6RP$(``````KQ!P``````&4)MD:BT=H!Z:T.IZ9#S:`ZH%CJ$`A]OC1DU -M4VION(3=>H`$`"UL:#4M)````$X```"!40$`(`/5%4UQ````"0```$:D`P`` -M"@````%F:6QE,AD```#_I($`````````````(1K^3",:_DP=````0?Y%<[L! -MELL!@-9``*BRG0%8U::\`9;+`0@`````0=X'```````90FV1J.QV@'IS0XGI -MD/-H#JC&&H0"'F^-&353:F^XA-U^@#4`+6QH9"T``````````(%1`0`@`@`` -M504```7>`P`!!P`"9&ER_P4`4.A!!P!1Z0/I`P``-@`M;&AD+0`````````` -M@5$!`"`"``!5!0``")D#``$(``)D:7(R_P4`4.U!!P!1Z0/I`P``1P`M;&AD -M+0```````````J,"`"`"``!5!0``M*D(``%F:6QE,10``F1I6UL:6YK,GPN+O\%`%#MH0<`4>D#Z0,` -M`#,`+6QH,"T\````/````(%1`0`@`J3G504``+DI"``!9FEL93$%`%"D@0<` -M4>D#Z0,``"`@("`@("`@("`@("`@("`@("`@("`@("`@9FEL92`Q(&-O;G1E -M;G1S"FAE;&QO"FAE;&QO"FAE;&QO"C,`+6QH,"U.````3@```(%1`0`@`M45 -M504``+T9"``!9FEL93(%`%"V@0<`4>D#Z0,``"`@("`@("`@("`@("`@("`@ -M("`@("`@("`@9FEL92`R(&-O;G1E;G1S"FAE;&QO"FAE;&QO"FAE;&QO"FAE -M;&QO"FAE;&QO"FAE;&QO"C4`+6QH-2UW`@``Z00``&-,V4L@`H6/504``#-5 -M"@`!24Y35$%,3`4`4*2!!P!1Z0/I`P```FUK=XVV['"Z\`>$(6[`2-EZ5P&P -M^!J*0MPV*IM]&^L37/)[SD(6GCE`4$+,RA -M<%QVYXC%'H1Q`I@_B\H/L@(+W3`0@5CY6X%Q%WW+@7<`8(F7=77U]%5YG?`; -M3N&I:_6YWA$,3F@?:)>FZ!:WRP0:TH8%&:/A#VMNUUD -M[D?+:#XK%3NMR(PSF4;V"^\X0/E3JMRQ46+7\I]S@7ZJNTX[ROSD+=\7\.O# -MI:W._S>P-B(W4`=N*!<4AM0Y$,P.0&OJER*:CF[S6/=2*T4J -M8HB@[:HC'_0*&[=@,,G+98$J+TE>OL/*B^SJ]0B]?)C"QW6ESMD62-#L*]0YO*`ZHY784:YX:>BM^:'>,:IX.=Y*@R(+B)*BX24P/1>F- -M3ODP9D/YS5^9M>8OQ5I-[<^F!_.C?H\HT:!I/ZJ3)U)Z,OC8+[-;X -MMPT`HQXE(XTV!J`/FOL'T?3:#:L@[2#Y$F`?BFKE-DN]]H>'CIJ-:^/JCO\T -M.4`Z,BR&AN^@;&H.P/W[;;[KCY1@;[MRE6MWEA0[SS@BW-=BZ;/992/*144" -ME)9-=H3.#8,!KW4;K#^:HP[15TP>C!ZQL--2)IGK);'D<;J"O7.2A_4X'"IW -MB(_W\=@I^.U+$T\Q/F2:*5OSDVD#Z0,X?"UL:&0M```````````!2"/L$``69&ER,EQS -M>6UL:6YK,7PN+EQF:6QE,0``50`"HP(`[:'I`^D#.'XM;&AD+0`````````` -M`4@C[!``%F1I] -M+6QH-2TB````/`````!((NP@``5F:6QE,:3G50"!40$`I('I`^D#`!A";FG% -MX_H!TUH=YD4,+`6H'R.A`(^>40P[=::W.04K]2=!+6QH-2TB````3@````!( -M(NP@``5F:6QE,M4550"!40$`MH'I`^D#`!A";FG'8_H!TYH40P[=::W.04K_0`9?RUL:&0M&@``````````2"+L(`$```!5!P`"9&ER -M_P4`4.A!!P!1Z0/I`P<`5(%1`0```!F!+6QH9"T;``````````!((NP@`0`` -M`%4(``)D:7(R_P4`4.U!!P!1Z0/I`P<`5(%1`0```!YQ+6QH9"TG```````` -M``%((^P@`05F:6QE,0``510``F1I6UL:6YK,GPN+O\%`%#MH0<`4>D#Z0,'`%0"HP(````>!BUL:#4M -M-0```#P`````2"+L(`$%9FEL93&DYU4%`%"D@0<`4>D#Z0,'`%2!40$````` -M&$)N:<7C^@'36AWF10PL!:@?(Z$`CYY1##MUIK40P[=::W.04K_0`U`"UL:&0M``````````"! -M40$`(`(``%4%```%W@,``0<``F1ID#Z0,``#8`+6QH9"T` -M`````````(%1`0`@`@``504```B9`P`!"``"9&ER,O\%`%#M00<`4>D#Z0,` -M`$<`+6QH9"T```````````*C`@`@`@``504``+2I"``!9FEL93$4``)D:7(R -M_W-Y;6QI;FLQ?"XN_P4`4.VA!P!1Z0/I`P``1P`M;&AD+0```````````J," -M`"`"``!5!0``A^T(``%F:6QE,A0``F1I40P[=::W.04K_0`$ -M`"UL:&0M``````````"!40$`(`,``$U\````"0```$:D`P``!0````$)```` -M`F1IG-#B>F0\V@.J,8:A`(>;XT9-5-J -M;[B$W7Z``#4`+6QH9"T``````````(%1`0`@`@``504```7>`P`!!P`"9&ER -M_P4`4.A!!P!1Z0/I`P``-@`M;&AD+0``````````@5$!`"`"``!5!0``")D# -M``$(``)D:7(R_P4`4.U!!P!1Z0/I`P``1P`M;&AD+0```````````J,"`"`" -M``!5!0``M*D(``%F:6QE,10``F1I6UL:6YK,GPN+O\%`%#MH0<`4>D#Z0,``#,`+6QH,"T\````/``` -M`(%1`0`@`J3G504``+DI"``!9FEL93$%`%"D@0<`4>D#Z0,``"`@("`@("`@ -M("`@("`@("`@("`@("`@("`@9FEL92`Q(&-O;G1E;G1S"FAE;&QO"FAE;&QO -M"FAE;&QO"C,`+6QH,"U.````3@```(%1`0`@`M45504``+T9"``!9FEL93(% -M`%"V@0<`4>D#Z0,``"`@("`@("`@("`@("`@("`@("`@("`@("`@9FEL92`R -M(&-O;G1E;G1S"FAE;&QO"FAE;&QO"FAE;&QO"FAE;&QO"FAE;&QO"FAE;&QO -M"@`U`"UL:&0M``````````"!40$`(`(``%4%```%W@,``0<``F1ID#Z0,``#8`+6QH9"T``````````(%1`0`@`@``504```B9`P`!"``" -M9&ER,O\%`%#M00<`4>D#Z0,``$<`+6QH9"T```````````*C`@`@`@``504` -M`+2I"``!9FEL93$4``)D:7(R_W-Y;6QI;FLQ?"XN_P4`4.VA!P!1Z0/I`P`` -M1P`M;&AD+0```````````J,"`"`"``!5!0``A^T(``%F:6QE,A0``F1ID#Z0,````80FYIQV/Z`=.:'.9%#"P% -MJ-\+D(!'CRB&';K36YR"E?Z``#4`+6QH9"T``````````(%1`0`@`@``504` -M``7>`P`!!P`"9&ER_P4`4.A!!P!1Z0/I`P``-@`M;&AD+0``````````@5$! -M`"`"``!5!0``")D#``$(``)D:7(R_P4`4.U!!P!1Z0/I`P``1P`M;&AD+0`` -M`````````J,"`"`"``!5!0``M*D(``%F:6QE,10``F1I6UL:6YK,GPN+O\%`%#MH0<`4>D#Z0,``#,` -M+6QH-RTC````/````(%1`0`@`J3G504``!R)"``!9FEL93$%`%"D@0<`4>D# -MZ0,````80FYIQ>/Z`=-:'>9%#"P%J!\CD(!'SRB&';K36YR"E?J`,P`M;&@W -M+2,```!.````@5$!`"`"U155!0``SDX(``%F:6QE,@4`4+:!!P!1Z0/I`P`` -M`!A";FG'8_H!TYH/*(8=NM-;G(*5_H``-0`M;&@U+7<" -M``#I!```8TS92R`"A8]5!0``,U4*``%)3E-404Q,!0!0I($'`%'I`^D#```" -M;6MWC;;L<+KP!X0A;L!(V7I7`;#X&HI"W#8JFWT;ZQ-<\ESDLQ#>-O+FY91= -MO@?+_S`"5M)[O.0A:>.4!00LS*%P7';GB,4>A'$"F#^+R@^R`@O=,!"!6/E; -M@7$7?$0Q.:!]HEZ;H%P$)\YH.,]H< -MSS">!YK?+!!K2A@49H^$/:V[763N1\MH/BL5.ZW(C#.91O8+[SA`^5.JW+%1 -M8M?RGW.!?JJ[3CO*_.0MWQ?PZ\.EK<[_-[`V(C=0!VYS0\2_0M7UO5XH%Q2& -MU#D0S`Y`:^J7(IJ.;O-8]U(K12IBB*#MJB,?]`H;MV`PR5#!U11D+Z"_/*YZ,+'=:7.V19(T.PKU#F\H#JCE=A1KGAI -MZ*WYH=XQJG@YWDJ!R&E3>IWFDBLSH&=H+AD]3FI98==M/;;@-O#MU2?_ZT'9 -MV>Z&KV9B?6C-AC$X[O^PPZ739;23V`H2@29(T9[(@N(DJ+A)3`]%Z8U.^3!F0_G-7YFUYB_%6DWMSZ8'\Z-^CRC1 -MH&D_JI,G4GHR^-@OLUOARV,U\QZW#0"C'B4CC38&H`^:^P?1]-H-JR#M(/D2 -M8!^*:N4V2[WVAX>.FHUKX^J._S0Y0#HR+(:&[Z!L:@[`_?MMONN/E&!ONW*5 -M:W>6%#O/."+LEL>1QNH*](C_?QV"GX[4L33S$^9)HI6_.39R>_YC5` -!```` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_fuzz_1.iso.Z.uu b/thirdparty/libarchive/libarchive/test/test_fuzz_1.iso.Z.uu deleted file mode 100644 index 07a3e934d..000000000 --- a/thirdparty/libarchive/libarchive/test/test_fuzz_1.iso.Z.uu +++ /dev/null @@ -1,495 +0,0 @@ -$FreeBSD: head/lib/libarchive/test/test_fuzz_1.iso.Z.uu 201247 2009-12-30 05:59:21Z kientzle $ - -begin 644 test_fuzz_1.iso.Z -M'YV0``(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR -MI,F3*%.J7,FRIO8,.*'4NVK-FS:-.J7//JW/'D"-+GDRYLN7+F#-KWLRY -ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ -MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ -MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$;(44890DQ!!`@01BCA -MA!1***`43S11X88<1GA0%`(,)$`4'QT(0``F'H@``@"(PJ)`"(A"04(6#"0" -M`!P4E..+`;'(Q@(6),!``^"$>&)`*`+0X9),-NGDDU!&*>645%9IY9589JGE -MEEQ>V<0224SQA!%3@!#F$R#D8(,-,+R`!)D@&)$$$T5,D<445!2AH1!5S$E$ -M$5*`8`((%Q8QQ!-2/"A@"U*\0(05BDI11!!4(`H""D.D`$(,.>0P`PA%N)#% -M$U4X<0010=!Y:::;=GH#"$JX`,6D4HCIQ`NQ3C$$$G,RD82I708K;+`R$(A# -M##'(4&P.R<8P`X'@%`O#L,L<,Y`&"#VP#``,`7`"!A=L(.`SPV -M$P"4G'`69%/1=\8,'UR%V`#PO7#)%CML`L,3+VQQR1-C;/'"$E/<0L5S4VP% -MQ9E/#D`074-=^M2G,QTNLN.6>VZVJU=+[K70>FO[MN`:R[JUYF(+3KKV!B_\ -M\,07;_SQR",K`QD.-`Z!A(B#`%B'0`800A3Z\(_\A4#DAM%<""0&[YR%0&3PSE8(!)D8/85` -MM(K14`BD!N_AM%*".0&[WR$0'#PSD0(I&T8'81`K(K1/@AD!^^\@T!X -M\,XX"*0'[UR#0'SP3H(%Y)<8I5M`I(I1P`6$=!A-6$`.AE&-!61B&#V"0!:& -M4=(%I&08A>V_WHG9@$@7HX`-B-TPF@*!C`VCYA"($MZ)U8"$#:/>$`C?,(H- -M@6@,H](0B!/>R0R!8`RCQA`(%-X)#(&0"*.Z$(C%,$H+@20,HZX0B.`PB@J! -M'`ZCHA#(YS#*"8&D$J.6$(A0,0H)@0`.HXH0B!;>20B!;.&=?A`(%]Z)!X&4 -M$J,,!(!/,.>2`A.&=*PZ(&-XIN("$$J/[#8A.,6JW@!`, -MHP<+2)`Q2MN`G.&=;PL(&MXIMX!T$J-L#8A-,7H.@>@6HUP-2(\Q^@V!M.&= -MV1"(&]XY#8%D$J/-$(A,,7H,@=@6H\$0B,`PN@N!S.&=M1`('=[Y"H%4$J.I -M$(A+,3H*@<@6HYT02(TQ>@F!Y.&=D1"('MZY"(%$$J.%$(A*,?H'@;@6HZ<. -M2(PQ^NB`U!JC=PX((-[YY8`T$J-'#HA),?KB@*@6HX<+2(LQBK&`Q!JC8PN( -M(=XYL8`D$J.X#8A(,0K:@)@6HX@-2(HQ"M>`M!JCZ!`((][YN(`4$J/@$(A' -M,:H-@8@6H]002(DQZ@R!I!JCR!"()-XI#($$$J.\$(A&,6H+@7@6H[`02(@Q -MJ@J!E!JCI!`()M[I"8'T$:,C#TA%,;KP@&@6H_,.2( -M@$@6HPL+2(4QRMN`9!JCI`U(QS'*V(#$$:-T#4A"K3O!NMO][GC/>WBDAZ,C -M^3T@&0P`#@7R0<%_\_`CS-E/3]3"%\9PA@.IH0`&'Q`=#@#QF/\[`(9(`-(5 -M42!)[#P3!^)$T1?H\P&9HNFM.!`LFGZ+`^FBZ;\XD#":?HP#*:/ISSB0-)I^ -MC0-IH^G?.)`XFGZ.`ZFCZ>\XD#R:?H\#Z:/I_SB00)I^D`,II.D/.9!$FGZ1 -M`VFDZ1\YD$B:?I(#J:3I+SF03)I^DP/II.D_.9!0FGZ4`RFEZ4\YD%2:?I4# -M02*F)TL#$3:FATL#43*FUTL#\4NF%TP#T3:F9TP#@4RFITP#L3FF]TP#$4VF -M-TT#44T%0'D`H$T&@'F(IWDW<@`8)1#GE``M&!#LI``Q"$\`L``U6$\,4(/Y -MU``UV$\.4(,!]0`U6%`04(,)%0$UV%`24(,1-0$U6%$44(,:50$UZ%$64(,B -M=0$U:%(84(,JE0$UZ%(:4(,RM0$U:%,<4(,ZU0$UZ%,>4(-"]0$UV#@UR#90(U*%8G4(-FA0(U2%4J4(-NM0(U*%=0,U*%HX4(.FE0,UJ%HZ4(.NM0,U*%L\4(.VU0,UJ%L^4(,$\P,U2#=` -M4(,G5H,)(P0UJ#%#4(/2A2J:1SJ3HGFP900UB%E'4(.`A00U6%Y)4(/II00U -MB%5+4(/QQ00U6%]-4(/YY00UV%]/4(,!!@4U6&!14(,))@4UV&!34(,11@4U -M6&%54(,99@4UV&%74(,AA@4U6&)94(,II@4UV&);4(,QQ@4U6&-=4(,"XP4U -MV&-?4(-!!@8U.&1A4(,K)@8U*#AC4(/[108U:#=E4(,'8P8U2%MG4(-O@P8U -M*#=I4(-LI08UV&9K4(-+4(/QQ@@U^#B-4(/YY@@UV&^/4(,!!PDU -M6'"14(,))PDUV'"34(,11PDU6'&54(,99PDUV'&74(,AAPDU6'*94(,CIPDU -MN'";4(/SQ@DUN&V=4(/#Y@DUN&J?4(.3!@HUN&>A4(-C)@HUN&2C4(,S1@HU -M^#FE4(,#9@HUN%ZG4(,+@PHUR%NI4(.DI0HUR%BK4(-TQ0ITIW<8FJ$:NJ$< -MRAL'4C,7!``A`@LH,SK#=@LEBEQ&I*(LNJ(NVJ(P^J(R&J,T.J,V6J,X>J,Z -M&@0A$@LF8B1!,&RX8"(\M*-&FJ-(>J1*FJ1,NJ0K&B*R8"*?%Z0`D`LF^J0`,`LFPDVC$R*T8"(OPJ,`4`LFPC)E"@"V8"+N]*;O($_' -M%2+P8$]W"@#QH$][*@_^M*?S(%![2@\&M:?UH%![:@\.M:?W(%%[B@\6M:?Y -ML%%[J@\?M:?[,%)[R@\GM:?]L%)[Z@\OM:?_,%-[ZG<6I*9)`@`\]:8"8"(K -M]*8#8"(=]*8$$#1[6@`F,D1O:@`F(DYJ>@`FHE9JB@`FTEYJF@`F$F=JJ@`F -M4F]JN@`F$DUOR@`F(E9OV@`F4EYOZ@`FDF9J^@`FTFYJ"@$F$G=J&@$FPDQJ -M*@$FXE5O.@$F$EYJ2@$F4F9J6@$FDFYJ:@$FTG9J>@$F@DQOB@$FHE5OF@$F -MTEUJJ@$F$F9JN@$F4FYJR@$FDG9JV@$F,DQJZ@$F8E5O^@$FHEUJ"@(FTF5J -M&@(F$FYJ*@(F4G9J.@(F\DMO2@(F(E5O6@(F8EUJ:@(FDF5J>@(FTFUJB@(F -M$G9JF@(FHDMJJ@(FXE1JN@(F(EUOR@(F4F5JV@(FDFUJZ@(FTG5J^@(F0DMJ -M"@,FHE1JZB^$\Z8R8")1IJ8S8"+5IJ8T8")9IZ8U8"*MI*8V8")&I:8W8"+* -MI:8X8")-IJ8Y8"+1IJ8Z8")5IZ8[8"*I]*8\8")"]:8]8"+&I:8^8"))IJ8_ -M8"+-IJ9`8")1IZ9!8"*E]*9"8"(^]:9#8"+"I:9$8")%IJ9%8"+)IJ9&8")- -MIZ9'8"*A]*9(8"(Z]:9)8"*^I:9*8")!]J9+8"+%IJ9,8"))IZ9-8"*=]*9. -M8"(V]:9/8"*Z]:908"(]]J918"+!IJ928")%IZ938"*9]*948"(R]:958"*V -M]:8@&#![>@4FTFMJB@4F$G1JF@4F4DEOJ@4FXE)ON@4F(EMOR@4F4F-OV@4F -MDFMJZ@4FTG-J^@4F$DEO"@8FHE)O&@8FXEIO*@8F$F-O.@8F4FMO"GD`D'-J -M6@8FTDAO:@8F8E)O>@8FHEIOB@8FTF)OF@8F$FMOJ@8F4G-JN@8FDDAOR@8F -M(E)OV@8F8EIOZ@8FDF)O^@8FTFIO"@@@@FTFEOB@@F$G)OF@@F4D=OJ@@F -MTE!ON@@F(EEOR@@F4F%OV@@FDFEOZ@@FTG%O^@@F$D=O"@DFDE!O&@DFXEAO -M*@DF$F%O.@DF4FEO2@DFDG%O6@DFTD9O:@DF4E!O>@DFHEAOB@DFTF!OF@DF -M$FEOJ@DF4G%ON@DFDD9OR@DF$E!OV@DF8EAOZ@DFDF!O^@DFTFAO"@HF$G%O -M&@HF4D9O*@HFTD]O.@HF(EAO2@HF4F!O6@HFDFAO:@HFTG!O>@HF$D9OB@HF -MDD]OF@HFXE=OJ@HF$F!ON@HF4FAOR@HFDG!OV@HFTD5OZ@HF4D]O^@HFHE=& -MU*%F?=9HG=;LP7$K=>%?=@WRMD^DW:?[1-J`^D^D/:@#1=J&>E"DG:@+1=J,^E"D_:@3 -M1=J2>E%\#0"5RE&DC:D@-=R;2E*D[:DH-=RARE*D3:HP-=RG2E.=;2(XI=@' -MPE/9'2)`I=@\1%2*741(I=C7Q%2*S4U0I=CD1%79S2)8E=TLPU79[4Y@I=CS -M1%:*?4]HI=C[5%[9_4]LE=T#!5?9?5!TE=T+A5>*_5!\I=@3!5C9/2.$I=@< -MA5C972.,E=TD!5F*#3.4I=@LA5G9+3.*+3B#IMB'H3.L'\] -M(_\!C0````4@`32`"%`!%H0&^``!0`0\"!30`G9`#0@#B<00U!D`((,0A`R" -M,^H?S\!_%P1%!($:&``2@1-H`L!J=-S``'``!T("[($0T`$.A!\X`2M@`+B` -M19`(/D$UF`$!@*3Z(`3A@S3!%[@&9>")H$,HZ)M002O8!`2:X06P4,%[()9<@6S$I>L`VHE8$P`L3@#D$'KC`,!L$S.`1K81IT?[@P%^K" -MQG`%W5@W*83`,!@*PQ&R!;N@0/B"!2$"]D`R6!!F(1I<@[9P#>[":4@-JZ$U -MO(8X(HX$3$@AOD(OK#X180!,!&9(8$X1TBQ)VX!D7B@9@T3H0@.)&46`>C -MH.E!+"Z1(L;$T#C0T02NZ2,:V'2L+'LDR.9(^/HD621/+)(9/@BT>-:5(_L\3^* -M2+@(`*A8]VF2%Q)@K,C\:!ZKY)"\DC(R2Q[)$)&Z$)79C3OY&.VDE!X).Q(YJTCTRL/3C)T_$^K&//E)* -MDDD.22C/I*%DBXA22]9(+EF_VD^C#`#O!U)&R049)!LD1_R0$+(P6I'):ITC@>QLK5?Y(E#-@OS))2OL([>2FQI*;$E5FQE00@:VDY -MH&2LG)2E,E@^2SQ)+%5E5J0E!HPXF1EUT4)"Q#T8*=$FQUR70K-=2L.E23@+I^$\G)DAR-Q- -M@7`C\B:*I)K[T&^>S+E9,PVFFI2'FZ<@0$T8(37UY@RLFANR7D+,CADX/V;/ -M0()J,R!0%<=Y"04/WQR5H?-J:L2L63DG)HA$G+@S=^K.W=D8@DSJ!`"K,VK> -MQA,A#B-G['R86)-@UDZ5>3L59T%HG,)S;)X,?6@#C^??I)D`P&9>SEO88]K+ -M0,`JK#,<1D1>Q0?/)9U$GK-3>69/RZDO;R'O?)_P,W[*S[D09+SG5?F4Q;-Z -MRLKK23G7I^V$C0#`=ZI#_$D]`P`_1)>R,SB23JTI.-M@CXDS`X&KA$^R.3Y! -M(>S,0))6$(Z@^*2"F:!O6L\BVC:/:,\8`G$S`.S,L=)$^Z@?_:.`M",$F3T: -M$*+)#P4:)U1RVE`SFD/;H,#PF@``;%9"Z2E&>=79/)Z_HZT&@E@YI,2S@@K1'SDH1^<579Y;T#0[2@F!(P>C4K*0&5)&646#:2$]GC_%6`Z&\H%(I^#K-9RM- -MGA$3EC;0TWE+NZDW_::!-,A`4X$@38VIYR2>B72.+E)FVDF%*0#0I0'AE)K3 -MQXE,4>@U39_9U'\R3P#:8]+,0&`KT]1U!E$Y2D9=*?;DI+<3G"K4A0 -M\:<"`:#.T]:93@LJ-EV@VC2+YAMQ6A#**><!=2>`LME6E*;J1;M,7%G(-`5EEI-A^@]M:('E7VV4VYZ4[NJ5_VJZR_( -M1-6YPE.3J3IEJD#5I`I5E%H05NI$#8=)59D:U!NJ56]G&EVC!\&-4E`XZE)' -M*EHMG3(U`^)1;.4R[PI8/:R(-;%FCR!36`/"Y@BH%=6G_E4L&EA/YR,M")+4 -M&W9.>HI4S2;:S*1L,ZTZ57#P20/`6`T(=*7'R*N!X%6HZD"]H))UKC+2K:I% -M%:MMO:VX-3\$F=6Z5\JJ4FV6LI6=-D\`T%B)*P$5J5DQX&0B` -MQ;62S[Z:7&FG/HVE:C*W:M?MREWM0Y!YKG_%M\K5B_I*K^LV7:N\-2"TUK=* -M-N/J60VN396V-M>X41#DAG2UH-9TJ<)7T2I?NZM__:\`UCP$F3(S$.PK>X6< -M/=6O[M?EJE8W*@``KP$ANA[8>CI>\2E&-:\:%0FFFX&`6.[K*I64"I:\9M7_ -MR34#K(D]L2BV.@29#7M8Q.M[%;%TE<3*T@%;7X]K+PVQ%K:\(E1^"BX*`F/Q -ML-15O\+8V9I04ZR1/;)(EC@$F;8S$'[LA$6GR%7(YM@1NT^YYHHM"!WVR8;4 -M&UM=-VE=!:!W=2`$`#9*$/0J$.55<12VXEBL&F.K[(PF<[K:?]M(D3`%#:R>)B+>J4;;/8]5MN43T+`/BL -MEBV;7%;*LEDBRV.[RT#`+)!NYUJK*6N5*69FKL/VVX#;<&H8@8VTW -MR[%=L]PVHU;6M5IL`P*N?;9^5ELF6_YZ.WM,N1D(H"7;LM)MVVB_K*\5MP`W -MX`I<^@D`[NUG.;>9]L)NVNQ*;@L"MH6WL7;72EMERV/3SD`@+?H6Q"9<'>MO -M.>W`_;@@-^22A2!C<4<+PN6W7E;&,MR"6Q#R+<1-L!N7RJ9:(PD`PJP&(;,# -MP5I$KM$]NDA7*009HAL0VD:?C;@_=^+26T$; -M23&KH0V;F[5U%E!%2T49;HS(&@A6)>-66*G+8$=KTGV[ -M<#?NZH0@L*MJ):_K?;VPMR0$&=,[6RZOZ)RW;;>_4MZ"D'@_[]K-O*.7YO:8 -M<#,0<$OJ1;:,=^HZWMC+?)NO\XT(08;XWA;;FT"!+^NEN;.W(*!>W[MXV6ZW -M;;!(L.P,!-YR?-'MZIVY>O7YJM_URWX'0I`1O[N%^E91ZXM^;V'T+0C&E_NJ -MWJ];?]$H`%"C8A;G"@2=FTKY*J9%N9I6\WY+.*LP!4(#;K\0.`(?W2#S@`'` -M+WFZ,!&WZ)<(_),@/A -M8$!A,CR$,^P5?L-P&-P&&30L$-0P$(ZWMS?YYM[AFOZ,2$"%MDF8_IIA`-!M -M!L+$6,.AMPWOW3C,B!NQIPTRA5@@'.([#'7SL!+6N]YV#A<$.VQ41?"6'<.) -M&`5?WR/88\+.0%@8B-@2"V(W[(A;L2M&L4'&%$^7+0Q3]S``A<0%81)WXC`Z -M@D&Q*B[#&=;F(@D!+&[9<"`1J_XFE,C6]JD)'& -M@P,#!]Y`#(P7L0?FAE@7I,):2_I9U>$JWKNE518'A(718YS*0``8J;CZ=F-O -M6XWKL3U>J$'&'0L$>$R)?;$\5L29>'`0A)+QA_'P/V;&@]AJ#03I$H_G[SP& -MO_!L+882<8?-Q0>#'N_B8]F*-3(-[K2SM,55F(-B- -MALR%E:_'G<@P.2;7TB"3D@7"2L[(H/<7`V3P6Y$+`D8.R>?T$Y/D*"QS!W&V -M&0AC@R77XN_K=F6R4W[*?33('&7S0HM_JBVVLG6C(-QDH,Q9A7)./L@;>`KK -M4`#0=0;">E'*5IDI]U>HS);;L@<-,F59O53ER;J$>3+B(`A)&0EOY+`\BF^A -M,#X1Q'BS@I`"_`F3\;Y=QGRY&=_1/`HO!4)C=LN0.3)?PR#SF`%`V-#&7]DA -M[V2W^XV_)@C6K.)XZY9C@J!).3(ZSJ-Q.2"LEQZC5`8"WT#+=!D30V3)3)MK -MS:8YS+0-`8L)DWU^6F;)N;LW.>AD'& -M.-N7W8Q[>_,M3AP%X34'9Z)<@S-LCXDR`V&_).?JO)S7\G,^S^A9_049\*Q? -MJ+,>MLY863H'!.2\G1&S%.[+8[G:#`2,,9[?*[/H3@Q#^*L,Q`&3'].T!PX_0[H#]N_/&;SJC'>N0;8YZ9H":U1X:RX-#`=.D?K:/\09&YT0"`1 -MF/GW/F3.7'4)[6>^NJ'9LV)2],-@A"PK#231I`;^DY3:?I0Y!1 -M+@/A38?I[GNEW6Z7+@A@FBMK78.LF54T^.TQ3<90XL^6>H#5='=>Q'4Z4DMJ -M]Q!D$K6$$=%Q^CKC:0>#IC-S2[[*)QD`1)N!<#C@])B6TY,Z5:OJ\!!D1K6% -MP=2G^CI;ZIK9J<6TH7:[/:;J#(3/8:IOM7E>U<`Z6&N'(*.K-0RL]M7#U54' -MA%*-HL'R?5;,6I1%!V8"3$T+T$P[(`QMJAV;%?01E-8N -M>J8>8\.L<;GSV1Z"91L!X09TV-BUT#P*5Q[.'MMO\VY._>XU3$%`7/OZ<+]L,ETX`8` -M@YMM*V?9#+&%RT"@&YF["V=7STV[:_=B"#*NV\>8;%H(,_Q8(_MM]"V?9K6K5=T%HW_5[AE9B9XVSP2_< -M-@C46J"BV6L=H>$WZ+M(?F%TK -M;I',N)`=P$T[$B[A3"#(^7"``<05NMWDW -MYDSA*WQ[^^?\S6-]RT`@&$&QR.%^0)[K`).<1..@-A -MS"CR#,W('[DI/^4V(QE!WL)+MUW]OW@5@[]HPKS! -M&[4EO]MI$,ZR2H$PS%&Y,3_F(B'(%',`T$E8^/NNX_U572?NK"N\27#C7IOH -M>D:6UE4N9I!@^!H(-F64BV4DBLS+N3G?"$'FFPN$<.[**?@E)]/+O)E+<0P] -MSD]J^1H(ND6NO]-7SHWC -MKU5&NW-@/E/_N46_Z!0AR#CT`4S0R;=!%^@!(9_/@+O*`+7P!0=`;"GDGI%]NE"_6A#L=[NIZ9 -MZ4+R+O(4" -M@,`>$/1Z8G?AH3K'*!J(/EU]^2O'Z@!TLJOV[<#]D0>9W>YH,#LIU^RN'8!MKY6B7M`Z.VX/:Z#65P>@.,V.9_;'/RT._=;"6<7 -MI:6Q[O!]@`<9]QX0*DEL+^.S_19*\R,]PX,R6W?K?1&NH_9'FT>S>T"8-#T& -M@@T$ES+=[7A\?_"V.\@H>$VSW??YZ9SO!<&^A_(KN0`%`KAD(IZ;&IW8U.!TV:[3WS9YO[GFG:NB=],^T;6\,\96 -M?-+5B/D]'[.#3)X/")'DOO]R.V]9T;IGEN'4W'Y; -M@\(&@DKY\B^9SVMZ5&_YO%[F^>>`("%#037@NF'^*9_ -M]1H[R*AZ6P/J`[*G#PB7/LOG][$,PP9"C&GUFQO6"WN,'61ZO4#X]5*>>!/V -ME3OK`P*KU_6G?BS3L(%0:X`]S1WVV%Y@!YEI+Q"J?;+'WYG=G1I[75/J!_VN -M+_)R32`,&VNOH;.]NP?602;="YM:;Y>YO:\I]^J=RD?K-S^,XWQMW:O6FLY/ -M>4+O`?-HFQ0(!__=*_P<'602/@!H)((^WQ/\?+/?$7V27O2+EDDK]D>?1^7] -M#4."0&P@F!1V7\H7OLD/T`RO((S\;U^UE[U!=_@0']J;=5(,`(C80%`M)+^B -MG_R=KZ6#C,T7"#B?Y;?MX^Y.0[Y`6/D1G,*R<="^V)'80&@Q.9^?\_RIS_`! -M@-,7"%!?Z*_N<%_E?[ZSP?=U_MR?5"8V$&)-U.>J5#_M;^@@0_8%@MG7^MR; -MZZ_5JR]MP/[`%_M/%0#4G(&P;<[^OU?[@#\]!YF]+Q#Z/MR?XG+?P;9]:V/W -ME7WBM_(`&,[K^D2RMA%_;($$L-A!$BM]?Z:`_]\/D($/[!8+M/_STW,*OU=&? -M2)9[FC;WT;[(<[&!8%INO^Y__I(YR"Q_@=#\@3])Q\J]7]PT?G"?^?,^&!L( -M*<;Y0__QSY:#S/<7".'?^COZ!3W]S0L8'0:L0_^;__,3G(S'^! -M4/_5O^O'G.>?NO'^#7WNA:.N6O_W36G.EU_VEP>]0`&!/-&CP''#`0>A0)X`@Z!$EB0\0/J&Q'@ -M<*4"LH`R'TVWT]$Q`X%H(002@53@&Q9D0('^1A)XG1V!`4$0V`0F=3L='C,0 -ME!A38!5H!N9@0888*'!H@5@9%A@02(%?H,NWT_$Q`T&J40:>@7A@^Q5DT($& -M!QOHA:F!`0$9&`?&?P!`RS$0+!QW8!ZH"#I?088AJ'#X@2L7'Q@0V(&#X`4( -M^>5R4AWEQ\MU@`(?YE<`PEDWDL.Q"(Z"D5>0$0H&!(%$"WCW@8!:5,4W`WIB -M-2#K=P.N?RH8MN((!@0+1X^!R`P$&D4B2`K^@B!7D+$+2AR0H$%W"@(`J6`E -M6``B08S,0.!9^(+`8#3X=@49S:#%40PN:,-@0-`+*H/"WWP%R0P$(08T*`V. -M@R)7D/$-:AS7(.94#08$SR`WJ.+U&)3,0%!JB(/D8#TH<`49\:#'D0Z><>=@ -M0!`.NH.#6,HQ$(P<]*`]:!#*80"`0"AR[(.:73X8$,R#`&$PQN\!9O[>2C?G -M77[81Y5()L=!Z!$&6T$&1Q@0]!&JH"?8#79-5I?%1P.*9K(@\(0#AEUY -ME$(8$(P%.Z!0F64&&4B@0,(5!86Z'E?F$*H=1B/@AA0``*C,0=!A-X5,H%L)B -M76%!`!96A>(=5B85NAQ:8?#W#@(`K,Q`$&J$A6-A7?A?!1EQH4`P%Z*%'-[* -MY14*!&=ATC>2>6H9X4G88\`R`T')01?:A8RA=A5D((8"@6+(%\)X*U=>:'.T -MA2^AJI4!YEP;(,_E`:Z"+^`:!&=-2`(!:=@8GH:X59!A&@(`>41)6!BJ>*Z@ -M6D?#Q8(9WPU'"Z9!I15DJ',@0;C,0!!1+(:H87`(3@49O:%`\!M.AOJ>@[4: -MMH81X2+68_`R`X%E`1P*A]2A315D0(<"@72('$Y\6U1Q*'1@AK?A6`;,#`09 -MQG18'9Z'^%B+4!"4A]LAWN=@88=&!WCX_Z%ZQ,Q`T&F8A^AA?MA-!1GUH4!P -M'[:'K*"#-1X*!.RA8.B5V6I68:B&S`P$(0=^J!\^B+-4D+$@"@0-(H`8&KI3 -M_:'3(1\*A3379CB`=88QFC*&_%V((>"`)!"8B!!BBFA+!1DH(@!01[B&\)\E -M&!N"9BNADE8;-GKSH2>51TV(4@<2!,T,!`V%@Z@B#HF\4Y#Q(PH$0:*%Z`1B -M3BWBB]@<,F$``#4S$$@60B*1:"6^95%B04`E*HE@(.9T)&H=&V*"N-AA,P-! -MA5$E7HEH(OP49)")`H&9R"7*@9B3E"@0;(D&(EM'&,:(RV"/P*;^/BMB06!FU@G`F(+77*(!($S`T''X2<"BI1BX11D0(H" -M@:1H*%J"@F)!4"@NBO<;GG@2>HC%F"9(U7&"&*&HJ-+!6?"10-`J5HJP8I'X -M'A4$<02,2`">A#-BNP8+LH0W8NO'(=:"`0"FJ'8@0>C,0)!03(JQ8K(85@$` -MQ:)`<"QNBLM@D/$JSHK&WYUX*[Z%[,Q`X%@@B\IBM[@+!1G9HD"P+4*+)V&0 -MT2S*'6%B6ABJP3,#083!+7J+\&+[$V2PBP*!NT@NJGC@8D$P+H**G)Q)^!;2 -M,P-!I?$NQHL$8UH39`",`H'`>"_Z>```O1@0V(O\(G/G+PYBC9!`D'$,C`5C -MQLBA!!D58T!P,2Z,(1O"&!`HC!'C\2?QN8>78'DW^9UWE5]5)R*>C`$BG,4= -M"00SH\9H,]YF`$#-F#,RA(Y4##C-77RK7Z\X"^:(&5!IU3$"`!E'CP'0#`0% -M!<9X,SZ-UD.0L30*!$TCR!CJZ8QM1+6((*J+BQU!,Q`H%DXCU"@V0A!!AMF8.6)REF-`@#DJ -MCDN?F*@93H0MVLHHY[6,J.++&#IVB<%<'H4<"03#8^IH/$X004;Q"`"D$;8B -MW(@K^HRHW^<(X#E%`AYER/%A*ZQC0%!Q]!@8S4`04)R.QV/XN!X$&=VC0/`] -MOHYDFO+(/#Z)A1Q',Q`8%N"C^"@_,$V2'BCM,:B&CY^8Z@H>AXYP4`M)%`$$2ND$2D;@4`#)%'9`?9"D*/*N&N -M:"-V71K?KX@;YE$N9$`04<:='1D0&!'\I%L'HF8]_$T`T&B,4@6DICD)#E?`34#0<-Q26:2K*1Q$&2@D@*!*OE)8DZ< -M9$#@29*2(Z(/>3J1BH+9&[5#SG$PHRD)9WE&`@$QV4H>DZP:`&!,*I-*),7' -M1+Z":QVO"$7:AD1CSU!:P9(!0 -M!]4,!`&&/$E/'I2S09`Q4`H$!:4^Z4[=DP%!/OE/_HYP(JI'U0P$A89!B5!N -ME*Y!D'%1"@09I4-9Y2V4`4%#.5'VD'YDD8?5#`0)AT;)4;Z4J4&0L5(*!"VE -M2+E6?90!04AY4DZ,$F'DU^_ICO_>165!P%<*EJKB(!9H$`2!!F*I6&Z6 -MD4&0<5D.!)DE9`D`-)8"P6-)6>:-;%K!01`4')HE9^E:,@9!AFHY$+"6HN5G -M*1"$EJ>E\ZCB\9(9G&?8"0Z6-5H>)1>U'J]E<5D;!!G#I4!`%_65N6)_UY71 -MAM,DCBA%ZHC8BFPI$!0E=IF\VR'8)52*7!<%RF5L>A7&C -M74$0V!7=Y7?I7OH%089Z.1"PEZ*E=CD0<)?L(\267Q`$^45[^5[^EWE!D+%? -M#@3]I6@I7PH$].5YN17&C7T&0=!G^)<`9H1)%P09#>9`\&"*E@.F0%!@*IAN -MX2`6$*6&.F&]!D/%A#@0AIFA980H$%R:'F1G>D#XE10A46H2\(]VV -M.*J1>%L>M14-!#LFB>EC:@9!1H^9>D"5S67JEVC9@"YA>%@TYE$GID`07$$0R!54II5I9H8%08:8 -M.1"0F:)EEBD0;)DNII)Y4M47!$%]46:>F7@F5Q!DT)D#@9TI6JJ9`@&;&6=6 -MDWE?GD$0Y!EW9IZI:%X%08:A.1`@FJ(EGRD0^)F#YG19Y/4;!$&_D6@NFIRF -M5!!D8)H#@:8I6CJ:`@&D66EBE6Y>C)D[9H(LXR9H8]:08*9HF$<%1:1'IVEK -M%@9!!JTI$`Q%S.4S*1OZ=]*D54E-6IK69!X%:@H$_4:/<4X0!.?$IGEK/IL] -M09"Q;`X$S:9HJ6L&!+SFJ6E#TGQN!4'@5CB;T&:X210$&=WF0/!MBI;3I@OR -M9>*8J%Y\01#$%^"FN"EO_@1!AKLY$,";HF6Y*1"HF7@*1`,GF4G7`D`M!D$09O1 -M>#Z>H&=&MWD6!)ZG:"EY"@249^89(")! -MJJ71SE-2T7L:7PV!4$&'#00R$%.)SWD5N9`4V=` -M$!`1FUJ4I*)#$`0ZQ#2%!PU#C)H?Q'U^G^!G^%D('4(!@#I0$)B?!L'1>#0> -MGW=E+[1!B)_P9_QI0MR8CB+[:7]F!T'&]3D09)^BI?))>*R;CJ*D<@(-!-J$ -M]@E^OD[>I_RI@"Z@\"?YR0X4!`]H^ED0K)_WYU+I?OY"#&@&"@RA33AGU:GS -M5:`@:-)9@IA`\E<'JG,Z6/JG0,!_YIX!I=$9@KZ@KL&-`*(,!#<#$":#V@P$ -M%%9!HHA9'Z.!>$.HARB*F+4^&H@'#V5CA$HV2*B3`H,NH7+!C5"G$`1U"F1U -M(\0I8I;KN"AB%7D*09"G3%,_*!/JA4H0-T(6.A!LH39H:5,01*'/%E;1IQ`$ -M?0H76M9\H7!H`W$CK*$#01M:AHJA`@$9>H4"`(`*00"HN*%]6!PJB#8/-T(? -M.A#\H64H'2H0V*%[Z*!"$`PJ@.@@*HE2#S>"(SH00*)EJ"$J$""B>ZBA0A`8 -M*I'H)"J*X@LW@B@L*HS:!S>"+SH0`*-EJ"TJ$."B>^BC0A`\*L'H,"J- -MQ@@X*H^>!S>".SH0P*-EJ#DJ$*"C>RBF0A!@*O'H/"J0B@VBH0A"$*B'I2"J33@E0*I4F -M!S>"4SH00*5EJ%$J$""E>ZCF@:9H65WH5"J6/@?BQ`CD`@F.56E!@)7NH:T* -M(A65CJ5P*7!P([2EZ)04&J+X'7\85A&KB%DAPEL:E_ZEN\&-L)=J$'UI&4J7 -M)@EYJ0\T`O$0?BE@ZIC:!C="K2)F,:9EZ&"*)!2F>^A(I$$4$8WI8^J9Q@8W -M@F:*&YE0D>EBFH,"`+R*F'5-=*:?:6O*&MP(J:D&L9J6H:*IHW2:9D$:!#?! -MFKJFO.EI<"/@IDB";EJ&QJ9(PFRZAQ(K8A8YL9OVILRI:+""C$#*:1D*G)X( -MPND>BJR(62S"=0>,T`F6G92ARJD%$IWLHLR)FL0S:*7>JGF(&-X)Y -MJD&@IV7H=:I!@*=[*+0B9KD3Z>EZJI].!C>"?:I!X*=EJ'N*),"G>RBU(F;- -M$_GI?JJ@.@8W@H&J02"H9:A_BB0`J'LHMB)FW1,)ZH*JH28&-X*%JD%@J&6H -M@XHD0*A[J"BD0>P3&>J&JJ(2!C>"B8HDH*AEJ(>*)("H>RBX(F;]$RGJBJJC -M_@4W@HVJ0>"H9:B+>B+`J'LHN2)F#10YZHZJI.H%-X*1JD$@J66HCXHD`*E[ -M*+HB9AT42>J2JJ76!3>"E:I!8*EEJ).*)$"I>RB[(F8M%%GJEJJFP@4W@IFJ -M0:"I9:B7BB2`J7LHO")F/11IZIJJIZX%-X*=JD'@J66HFXHDP*E[*+TB9DT4 -M>>J>JJB:!3>"H:I!(*IEJ)^*)`"J>RB^(F;-"(GJHJJIA@4W@J6J06"J9:BC -MBB1`JGLHOR)F<129ZJ:JJG(%-X*IJD&@JF6HIXHD@*I[*,`B9M4(J>JJJJM> -M!3>"K:I!X*IEJ*N*),"J>RC!(F:1%+GJKJJL2@4W@K&J02"K9:BOBB0`JWLH -MPB)FP0S)ZK*JK38%-X*UJD%@JV6HLXHD0*M[*,,B9K$4V>JVJJXB!3>"N:I! -MH*MEJ+>*)("K>RC$(F;)#.GJNJJO#@4W@KVJ0>"K9:B[BB3`JWLHQ2)FT13Y -MZKZJL/H$-X+!JD$@K&6HOXHD`*Q[*,8B9D6=GJ.[%I8NK!RK5W`C6*P:!,9J -M#]&``$##.@)!K'LHQR)F\10):\?JLM8$-X+*JD&PK&4HR(HDB*R,D<^)58`L -M8M8*T;*^K$`K3'`C\*P:A,]:ALJL2`+-NH>2+&)6!_&S!JU0ZTIP(S"M&H33 -M6H82K4B"T;J'HBQBEL/PM$:M8*M)<"-PK1J$UUJ&4JU(@M6ZA[(L8M;FE+%Z -M8AMKV"JW)@4W`MNJ0;BM(RLL6+(J"2.0V;J'PBQB%O3D@[ZA&O."FQB%32+F!4\#:Z!J.&JN3*LP-,(=+DRKK/AWIJX -M(@F+:]X:36(5.(N8!4-AKIMKZQH4W`BIJP:QNH*N_MW>6KEJ$)^KZ:JSPA.\CVL:R*`LIILW#`"9;*,+%*%5;PM8I:3%\LB";FL+XLB8!5WBYCE;`VSQ.PD>R-$ -MLQK$-)O*'K,:1#+KS.ZQ>XN8]6Y1L]4L('LCA+,:Q#B;RF*S2((V^\UB%7^+ -MF/5PD;/EK!M[(\2S&L0\F\JBLTB".OO.%EPCD,M%S]:S7.R-,+B(60)M*HO/ -M(@GZ[#][N(A9&-<62]`2LS?"0ZM!1+3;ZT&K022T_^SB(F;]70/M1'O#W@@> -MK08!TJ:R%BV2@-'JL5C%XR)F>5XAK4A+PMX(+JT&`=.FLB4MDG#2_K.3BYC5 -M>\6T,NT#>R/TM!K$3YO*UK1(PDW[SUXN8M;V!=0&M?CKC<#4:A!.;2I+U"() -M1NT_N[F(6?G74PO5DJ\WPE:K072UJ>Q4BR14M?_LYR)FD5\2[5<;R`(Y(Q!; -MN[V*M4@"6?O/CBYBUA'FU;JUU>N-@-=J$'IM*JO6:A!R+4O[A8U`/]A>R]<" -MKS?"Z2)F);:I[%^+)`2V_^SJ(F8]86WM8MO%0A4C$&:[O3JV&@1D^\^^+F(6 -M)W;&-K":[4AK,(Q`IJTSN[=:MAJ$9VO8SBYBEBYVVHJPJ:T->R/0MAJ$;>O: -MW@BDK0;1V@JQ&^SM(F:A8IEM;JO:&K<:!'*[O?*V2()O2]RV5UC%[B)F$63) -MK7([T_8-(Q!VN[TRMTB"B.0MQJ$>?O;,0%N9?7O?ZK8#KIA5X+ZW -M^BV2P-\&N(VLV#`"Y66*[8$+MMX(RXN81>&FLL>+@GN:/B]BUEF6W5JX8"U9 -M-@*)N-MKAJM!;+C_[/0B9@%G%2Z)&[3>""ZN!@'CIK(@K@:!XAJVUXN8I9W% -MN#+NRWHC]+@:Q(^;RM:X2,*-^\]N+V(6?0;D!KD=ZXW`Y&H03FXJ2^0B"4;N -M/_N]B%D/VI,+Y2ZL-\*6JT%TN:GLE(LD5+G_[/@B9IUH7NZ7NZ_>"&JN!L'F -MIK)B+I)`YOZSYXN89:&-N&YNZWHCY+D:Q)Z[O<:Y2,*<^\^N+V(6D,;G]KF: -MZXV`Z&H0BN[V"N@B"8*N8?N^B%F!FH'+Z`:O-\*EJT%DNN_MHXLD1+J&[?PB -M9NEI;>ZFJZW>"*:N!H'JIK*>+I(`ZD*XKFSV-`()#E^KJKNDW@CWBYB%ZY:A -MK2Z2\.K^L_N+F,6LI;JZ[JYZ(Q2[&L2QF\KVNAK$K[N'_B](`J^VZ":[%RX` -M0.V>"-;N]LKL(@G.[C\KP(A9#!NRB^VJJC?"N*M!E+NI[+8;`'2[AJT!(V:5 -M;.;NN:NIW@CRK@9![Z:RZBZ2P.[^LPJ,F,6SU;OVKJ)Z(P2\&L3`F\KFNTC" -MOOO/.C!BUM1&\!:\>NJ-`/%J$!)O*HOP(@D*[S\KP8A9:]O$2_&JJ3?"QZM! -MA+RI[,6+)&2\_ZP%(V9M;=?NR!OE8FTC$,R[O9J\2`+*^\]J,&)6ZB;RRKR[ -M+NHV`OF\J:S+JT'8O(:M!R-F`6^:+M`+M=X(2J\&P?2^MSRO!D'T_K,BC)BE -MO?V\3J^.>B-DO1K$UIO*1KU(PM1+Z_ZR)HR81;\UO5VOD`L`I+T:Q-K[WH*] -M2(+8^\^J,&(6!,?VMKTS+]ZK0>B][RWZ@1(V:UL`8!`I>A -M%C"2@`'_LUJ,F-742<`B\%]Z([3`&L0+G,J6P$C"";R'>C%BUD\7\\;`!B]/ -M-P+YP-LK#8PDV,#_K!@C9B%V,#`0/);>"$JP!L$$I[(\L`9!!!NV9HR8Y=DU -MP4[P5'HC9,$:Q!:+)/>"(:P!H$( -MI[)^,.-QFMHQ8I9TIP(61I>(HP)3Z0W -MPBBL093"J>PFC"1TPH:M'R-FN7BF\"D\D-X(LK`&00NGLJHPDL`*_[."C)@E -MY-7"MO`\>B,$PQK$,)S*YL)(PB[\SQHR8A:61PP7P^/HC0`-:Q#2<"J+#",) -MRO`_J\B(65'>-$P-3Z,WPC>L083#J>PUC"1DP_^L(R-F>7F7\#B\H-X([K`& -M`0]OK^8PDH`._[.2C)@5Z,7#\O!^>B/TPQK$/[R]UL-(PCULV%HR8E:N)PX' -MQ+/HC<`0:Q`.<2I+$",)!K%AJ\F(6<_>0PP1CZ(WPD:L073$J>Q$C"14Q/^L -M)R-F(7L>\4<\B=X(*K$&P1*GLB(QDD`2_[.BC)CE[;7$+O$@>B/DQ!K$3IS* -MQL1(PDS\SYHR8M:Z!Q#WQ-CO#3,"*<7;*U",)`C%_ZPJ(V;%?#PQ4PR'W@A6 -ML0:!%:>R2+$&`14;MJZ,F(7T[;U:\3P,`)3%&L19_-YVQ4C"5_S/RC)B5M"7 -M%:?%3.B-0!=K$'9Q*LL6(PEN<>6+5=@R8E;6=Q?CQ3#HC4`8:Q"&<2J[%R,) -M??$_J\N(66_?88P8AZ`WPF2L053&J>QBC"0TQO^L+R-F&7Z6\65<@=X(HK$& -M01JGLIHQDL`9_[/"C)A5_"W%IC$%W"6-0+/Q]IH:(PFK\3]KS(A9OU]I7!NS -MGS?";ZQ!!,>I;&RL0>3&AJTR(V95?\+Q<&Q\W@C.L08!':>RQC&2@!S_L\Z, -MF)7^1QY(W3'&L1WG,I6QTC"=?S/2C-B5O\''H?'H.>-P!YK$.YQ*DL> -M(PGF\3]KS8A9"2!M#!\_P0#`?JQ!],?;ZWR,)-3'_ZPV(V8Q@>_Q?^QWW@@* -ML@;!(*>R`C*20"`;MMZ,F.4%-L@.-@")K$"IR*@LB(PDB\C]KSHA9@N"*S"(CG3?"C:Q!Y,BI[(N,),3( -M_ZPZ(V91@CKRCAQSW@A&L@:!)*>R/C*2`"3_L^Z,F(4(^L=*\B)<"(Y`5_+V -MVB0C"4_R/RO/B%G)8)*<)5N<-\*8K$&4R:ELE:Q!=,F&K3TC9FV#9O*93'#> -M"'*R!D$GI[)J,I+`)O^S^HR8U0[6R7:RO'DC!,H:Q*"_,_Z,V+6 -M/T@H%\KAYHT`*6L0DG(JBR@C"8KR/RO0B%D0X:1,*3^;-\*GK$&$RJGLI8PD -M9,K_K$$C9A&$6/*H;`PGA",0K+R]FLI(`JK\SRHT8A9)&"O+RM4PB30"^RO+(&02P;MA*-F$45-LO.LJ)Y -M(V3+&L2VG,I&RTC"M/S/6C1B5F"(%G?+0NF-@"YK$.KR>PLN(PGB\C^KT8A9 -M>R&WS"Z?F3?"O:Q!Y,NI[+N,),3+@C$`X-&(69*AOKPO6YDWPL&L023,J:R_ -MC"0`S/^L2"-F,8<*\\+\8]X(%K,&@3&GL@XSD@`Q_[,FC9AU'&;,&C.)>2.4 -MS!K$R9S*=LQ(PL?\SZHT8I9VB#*GS!+FC4`S:Q`VR=C.2@#?_LT*-F$4G&LV",SD< -M)8Y`C_-[6S@C"8?S/VO4B%F*(N0<.0^C-\+FK$%TSN]MXZQ!5,X%LU(C9GV* -MGO/G'!$#`*JS!L$ZO[>B,Y)`.A?,3HV8I2D&SJZS8GDCY,X:Q.Z".:S!H$^O[?>,Y(`/O^S7HV8!3&FS^JS -M('HCU,\:Q/W\WK;/2,+[7#"+-6(6R8@_Y\];,0!`0&L0!O1[RS\C"?YSY8M` -MZ[Y(XPC4@Z:R,ZA`4(/NH3Z*F)4U+L\3M/UY(W30&L0'O;WNH&_-:1JEB%EM -MXP$=0C?/`,`*K4&TT.\M"8TDF-"&K9@B9B6.+O0+_8+>"#JT!L%#O[]M%JU!A-$%\Q,Z$*"AVC,; -M/4_>"$&H!C&$8M`XZ!^680PI8A;_>,86H4EH(GV$+M(QBAXM-MX(A+0&84B_ -MMWTTDO!'?[,9AI4B9D&0AS0C[4DKTJ`T;NM(%XPW@B:M07#2[VTDC21,TA+T -M*/V8`@KM0`"@`%`!P@P`E`1``5\`I\`L4`I(0!$``F`(0\`2\$LG`43`$>!+ -M_PIY@A2P*P0!IH(O#05@")7"H<`$@`#/]!-@!1#3=4+W4`5``5``HD`%Q`F6 -M0C<]!20!6$"<,"?XTG8"GJ`G=`]Z`C--!20!0\`4`#=-"E.`+WTH.`$.R1#P -M31,!8<(00$U7`4*`KS`%]-*!@A%@*N5*_]1`=5`M5`_51'51;50? -MU4AU4JU4+]5,=5/M5#_54'54+55/U51U56U57]58=5:M56_57'57[55_U6!U -M6"U6C]5D=5EM5I_5:'5:K5:OU6QU6^U6O]5P=5PM5\_5='5=;5??U7AU7JU7 -M[]5\=5_M5__5@'5@+5@/UH1U86U8']:(=6*M6"_6C'5C[5@_UI!U9"U93]:4 -M=65M65_6F'5FK5EOUIQU9^U9?]:@=6@M6H_6I'5I;5J?UJAU:JU:K]:L=6OM -M6K_6L'5L+5O/UK1U;6U;W]:X=6ZM6^_6O'5O[5O_UL!U<"U<#]?$=7%M7!_7 -MR'5RK5POU\QU<^U6U>G]?H=7JM7J_7['5[[5Z_U_!U?"U?S]?T=7UM7]_7^'5^K5_O -MU_QU?^U?_]<`=H`M8`_8!':!;6`?V`AV@JU@+]@,=H/M8#_8$':$+6%/V!1V -MA6UA7]@8=H:M86_8'':'[6%_V"!VB"UBC]@D=HEM8I_8*':*K6*OV"QVB^UB -4O]@P=HPM8\_8-':-;6/?V#BVW0$` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_gnutar_filename_encoding.c b/thirdparty/libarchive/libarchive/test/test_gnutar_filename_encoding.c deleted file mode 100644 index 3ec4f6129..000000000 --- a/thirdparty/libarchive/libarchive/test/test_gnutar_filename_encoding.c +++ /dev/null @@ -1,393 +0,0 @@ -/*- - * Copyright (c) 2011 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -#include - -DEFINE_TEST(test_gnutar_filename_encoding_UTF8_CP866) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("en_US.UTF-8 locale not available on this system."); - return; - } - - /* - * Verify that UTF-8 filenames are correctly translated into CP866 - * and stored with hdrcharset=CP866 option. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_gnutar(a)); - if (archive_write_set_options(a, "hdrcharset=CP866") != ARCHIVE_OK) { - skipping("This system cannot convert character-set" - " from UTF-8 to CP866."); - archive_write_free(a); - return; - } - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set a UTF-8 filename. */ - archive_entry_set_pathname(entry, "\xD0\xBF\xD1\x80\xD0\xB8"); - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Above three characters in UTF-8 should translate to the following - * three characters in CP866. */ - assertEqualMem(buff, "\xAF\xE0\xA8", 3); -} - -DEFINE_TEST(test_gnutar_filename_encoding_KOI8R_UTF8) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) { - skipping("KOI8-R locale not available on this system."); - return; - } - - /* - * Verify that KOI8-R filenames are correctly translated into UTF-8 - * and stored with hdrcharset=UTF-8 option. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_gnutar(a)); - if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) { - skipping("This system cannot convert character-set" - " from KOI8-R to UTF-8."); - archive_write_free(a); - return; - } - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set a KOI8-R filename. */ - archive_entry_set_pathname(entry, "\xD0\xD2\xC9"); - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Above three characters in KOI8-R should translate to the following - * three characters (two bytes each) in UTF-8. */ - assertEqualMem(buff, "\xD0\xBF\xD1\x80\xD0\xB8", 6); -} - -DEFINE_TEST(test_gnutar_filename_encoding_KOI8R_CP866) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) { - skipping("KOI8-R locale not available on this system."); - return; - } - - /* - * Verify that KOI8-R filenames are correctly translated into CP866 - * and stored with hdrcharset=CP866 option. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_gnutar(a)); - if (archive_write_set_options(a, "hdrcharset=CP866") != ARCHIVE_OK) { - skipping("This system cannot convert character-set" - " from KOI8-R to CP866."); - archive_write_free(a); - return; - } - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set a KOI8-R filename. */ - archive_entry_set_pathname(entry, "\xD0\xD2\xC9"); - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Above three characters in KOI8-R should translate to the following - * three characters in CP866. */ - assertEqualMem(buff, "\xAF\xE0\xA8", 3); -} - -DEFINE_TEST(test_gnutar_filename_encoding_CP1251_UTF8) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "Russian_Russia") && - NULL == setlocale(LC_ALL, "ru_RU.CP1251")) { - skipping("KOI8-R locale not available on this system."); - return; - } - - /* - * Verify that CP1251 filenames are correctly translated into UTF-8 - * and stored with hdrcharset=UTF-8 option. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_gnutar(a)); - if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) { - skipping("This system cannot convert character-set" - " from KOI8-R to UTF-8."); - archive_write_free(a); - return; - } - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set a KOI8-R filename. */ - archive_entry_set_pathname(entry, "\xEF\xF0\xE8"); - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Above three characters in CP1251 should translate to the following - * three characters (two bytes each) in UTF-8. */ - assertEqualMem(buff, "\xD0\xBF\xD1\x80\xD0\xB8", 6); -} - -/* - * Do not translate CP1251 into CP866 if non Windows platform. - */ -DEFINE_TEST(test_gnutar_filename_encoding_ru_RU_CP1251) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "ru_RU.CP1251")) { - skipping("KOI8-R locale not available on this system."); - return; - } - - /* - * Verify that CP1251 filenames are not translated into any - * other character-set, in particular, CP866. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_gnutar(a)); - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set a KOI8-R filename. */ - archive_entry_set_pathname(entry, "\xEF\xF0\xE8"); - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Above three characters in CP1251 should not translate to - * any other character-set. */ - assertEqualMem(buff, "\xEF\xF0\xE8", 3); -} - -/* - * Other archiver applications on Windows translate CP1251 filenames - * into CP866 filenames and store it in the gnutar file. - * Test above behavior works well. - */ -DEFINE_TEST(test_gnutar_filename_encoding_Russian_Russia) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "Russian_Russia")) { - skipping("Russian_Russia locale not available on this system."); - return; - } - - /* - * Verify that Russian_Russia(CP1251) filenames are correctly translated - * to CP866. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_gnutar(a)); - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set a CP1251 filename. */ - archive_entry_set_pathname(entry, "\xEF\xF0\xE8"); - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Above three characters in CP1251 should translate to the following - * three characters in CP866. */ - assertEqualMem(buff, "\xAF\xE0\xA8", 3); -} - -DEFINE_TEST(test_gnutar_filename_encoding_EUCJP_UTF8) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "ja_JP.eucJP")) { - skipping("eucJP locale not available on this system."); - return; - } - - /* - * Verify that EUC-JP filenames are correctly translated to UTF-8. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_gnutar(a)); - if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) { - skipping("This system cannot convert character-set" - " from eucJP to UTF-8."); - archive_write_free(a); - return; - } - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set an EUC-JP filename. */ - archive_entry_set_pathname(entry, "\xC9\xBD.txt"); - /* Check the Unicode version. */ - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Check UTF-8 version. */ - assertEqualMem(buff, "\xE8\xA1\xA8.txt", 7); -} - -DEFINE_TEST(test_gnutar_filename_encoding_EUCJP_CP932) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "ja_JP.eucJP")) { - skipping("eucJP locale not available on this system."); - return; - } - - /* - * Verify that EUC-JP filenames are correctly translated to CP932. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_gnutar(a)); - if (archive_write_set_options(a, "hdrcharset=CP932") != ARCHIVE_OK) { - skipping("This system cannot convert character-set" - " from eucJP to CP932."); - archive_write_free(a); - return; - } - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set an EUC-JP filename. */ - archive_entry_set_pathname(entry, "\xC9\xBD.txt"); - /* Check the Unicode version. */ - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Check CP932 version. */ - assertEqualMem(buff, "\x95\x5C.txt", 6); -} - -DEFINE_TEST(test_gnutar_filename_encoding_CP932_UTF8) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "Japanese_Japan") && - NULL == setlocale(LC_ALL, "ja_JP.SJIS")) { - skipping("CP932/SJIS locale not available on this system."); - return; - } - - /* - * Verify that CP932/SJIS filenames are correctly translated to UTF-8. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_gnutar(a)); - if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) { - skipping("This system cannot convert character-set" - " from CP932/SJIS to UTF-8."); - archive_write_free(a); - return; - } - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set an CP932/SJIS filename. */ - archive_entry_set_pathname(entry, "\x95\x5C.txt"); - /* Check the Unicode version. */ - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Check UTF-8 version. */ - assertEqualMem(buff, "\xE8\xA1\xA8.txt", 7); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_link_resolver.c b/thirdparty/libarchive/libarchive/test/test_link_resolver.c deleted file mode 100644 index 8332c4f98..000000000 --- a/thirdparty/libarchive/libarchive/test/test_link_resolver.c +++ /dev/null @@ -1,205 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/lib/libarchive/test/test_link_resolver.c,v 1.2 2008/06/15 04:31:43 kientzle Exp $"); - -static void test_linkify_tar(void) -{ - struct archive_entry *entry, *e2; - struct archive_entry_linkresolver *resolver; - - /* Initialize the resolver. */ - assert(NULL != (resolver = archive_entry_linkresolver_new())); - archive_entry_linkresolver_set_strategy(resolver, - ARCHIVE_FORMAT_TAR_USTAR); - - /* Create an entry with only 1 link and try to linkify it. */ - assert(NULL != (entry = archive_entry_new())); - archive_entry_set_pathname(entry, "test1"); - archive_entry_set_ino(entry, 1); - archive_entry_set_dev(entry, 2); - archive_entry_set_nlink(entry, 1); - archive_entry_set_size(entry, 10); - archive_entry_linkify(resolver, &entry, &e2); - - /* Shouldn't have been changed. */ - assert(e2 == NULL); - assertEqualInt(10, archive_entry_size(entry)); - assertEqualString("test1", archive_entry_pathname(entry)); - - /* Now, try again with an entry that has 2 links. */ - archive_entry_set_pathname(entry, "test2"); - archive_entry_set_nlink(entry, 2); - archive_entry_set_ino(entry, 2); - archive_entry_linkify(resolver, &entry, &e2); - /* Shouldn't be altered, since it wasn't seen before. */ - assert(e2 == NULL); - assertEqualString("test2", archive_entry_pathname(entry)); - assertEqualString(NULL, archive_entry_hardlink(entry)); - assertEqualInt(10, archive_entry_size(entry)); - - /* Match again and make sure it does get altered. */ - archive_entry_linkify(resolver, &entry, &e2); - assert(e2 == NULL); - assertEqualString("test2", archive_entry_pathname(entry)); - assertEqualString("test2", archive_entry_hardlink(entry)); - assertEqualInt(0, archive_entry_size(entry)); - - - /* Dirs should never be matched as hardlinks, regardless. */ - archive_entry_set_pathname(entry, "test3"); - archive_entry_set_nlink(entry, 2); - archive_entry_set_filetype(entry, AE_IFDIR); - archive_entry_set_ino(entry, 3); - archive_entry_set_hardlink(entry, NULL); - archive_entry_linkify(resolver, &entry, &e2); - /* Shouldn't be altered, since it wasn't seen before. */ - assert(e2 == NULL); - assertEqualString("test3", archive_entry_pathname(entry)); - assertEqualString(NULL, archive_entry_hardlink(entry)); - - /* Dir, so it shouldn't get matched. */ - archive_entry_linkify(resolver, &entry, &e2); - assert(e2 == NULL); - assertEqualString("test3", archive_entry_pathname(entry)); - assertEqualString(NULL, archive_entry_hardlink(entry)); - - archive_entry_free(entry); - archive_entry_linkresolver_free(resolver); -} - -static void test_linkify_old_cpio(void) -{ - struct archive_entry *entry, *e2; - struct archive_entry_linkresolver *resolver; - - /* Initialize the resolver. */ - assert(NULL != (resolver = archive_entry_linkresolver_new())); - archive_entry_linkresolver_set_strategy(resolver, - ARCHIVE_FORMAT_CPIO_POSIX); - - /* Create an entry with 2 link and try to linkify it. */ - assert(NULL != (entry = archive_entry_new())); - archive_entry_set_pathname(entry, "test1"); - archive_entry_set_ino(entry, 1); - archive_entry_set_dev(entry, 2); - archive_entry_set_nlink(entry, 2); - archive_entry_set_size(entry, 10); - archive_entry_linkify(resolver, &entry, &e2); - - /* Shouldn't have been changed. */ - assert(e2 == NULL); - assertEqualInt(10, archive_entry_size(entry)); - assertEqualString("test1", archive_entry_pathname(entry)); - - /* Still shouldn't be matched. */ - archive_entry_linkify(resolver, &entry, &e2); - assert(e2 == NULL); - assertEqualString("test1", archive_entry_pathname(entry)); - assertEqualString(NULL, archive_entry_hardlink(entry)); - assertEqualInt(10, archive_entry_size(entry)); - - archive_entry_free(entry); - archive_entry_linkresolver_free(resolver); -} - -static void test_linkify_new_cpio(void) -{ - struct archive_entry *entry, *e2; - struct archive_entry_linkresolver *resolver; - - /* Initialize the resolver. */ - assert(NULL != (resolver = archive_entry_linkresolver_new())); - archive_entry_linkresolver_set_strategy(resolver, - ARCHIVE_FORMAT_CPIO_SVR4_NOCRC); - - /* Create an entry with only 1 link and try to linkify it. */ - assert(NULL != (entry = archive_entry_new())); - archive_entry_set_pathname(entry, "test1"); - archive_entry_set_ino(entry, 1); - archive_entry_set_dev(entry, 2); - archive_entry_set_nlink(entry, 1); - archive_entry_set_size(entry, 10); - archive_entry_linkify(resolver, &entry, &e2); - - /* Shouldn't have been changed. */ - assert(e2 == NULL); - assertEqualInt(10, archive_entry_size(entry)); - assertEqualString("test1", archive_entry_pathname(entry)); - - /* Now, try again with an entry that has 3 links. */ - archive_entry_set_pathname(entry, "test2"); - archive_entry_set_nlink(entry, 3); - archive_entry_set_ino(entry, 2); - archive_entry_linkify(resolver, &entry, &e2); - - /* First time, it just gets swallowed. */ - assert(entry == NULL); - assert(e2 == NULL); - - /* Match again. */ - assert(NULL != (entry = archive_entry_new())); - archive_entry_set_pathname(entry, "test3"); - archive_entry_set_ino(entry, 2); - archive_entry_set_dev(entry, 2); - archive_entry_set_nlink(entry, 2); - archive_entry_set_size(entry, 10); - archive_entry_linkify(resolver, &entry, &e2); - - /* Should get back "test2" and nothing else. */ - assertEqualString("test2", archive_entry_pathname(entry)); - assertEqualInt(0, archive_entry_size(entry)); - archive_entry_free(entry); - assert(NULL == e2); - archive_entry_free(e2); /* This should be a no-op. */ - - /* Match a third time. */ - assert(NULL != (entry = archive_entry_new())); - archive_entry_set_pathname(entry, "test4"); - archive_entry_set_ino(entry, 2); - archive_entry_set_dev(entry, 2); - archive_entry_set_nlink(entry, 3); - archive_entry_set_size(entry, 10); - archive_entry_linkify(resolver, &entry, &e2); - - /* Should get back "test3". */ - assertEqualString("test3", archive_entry_pathname(entry)); - assertEqualInt(0, archive_entry_size(entry)); - - /* Since "test4" was the last link, should get it back also. */ - assertEqualString("test4", archive_entry_pathname(e2)); - assertEqualInt(10, archive_entry_size(e2)); - - archive_entry_free(entry); - archive_entry_free(e2); - archive_entry_linkresolver_free(resolver); -} - -DEFINE_TEST(test_link_resolver) -{ - test_linkify_tar(); - test_linkify_old_cpio(); - test_linkify_new_cpio(); -} diff --git a/thirdparty/libarchive/libarchive/test/test_open_failure.c b/thirdparty/libarchive/libarchive/test/test_open_failure.c deleted file mode 100644 index 5316a872b..000000000 --- a/thirdparty/libarchive/libarchive/test/test_open_failure.c +++ /dev/null @@ -1,218 +0,0 @@ -/*- - * Copyright (c) 2003-2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -#define MAGIC 123456789 -struct my_data { - int magic; - int read_return; - int read_called; - int write_return; - int write_called; - int open_return; - int open_called; - int close_return; - int close_called; -}; - -static ssize_t -my_read(struct archive *a, void *_private, const void **buff) -{ - struct my_data *private = (struct my_data *)_private; - (void)a; /* UNUSED */ - (void)buff; /* UNUSED */ - assertEqualInt(MAGIC, private->magic); - ++private->read_called; - return (private->read_return); -} - -static ssize_t -my_write(struct archive *a, void *_private, const void *buff, size_t s) -{ - struct my_data *private = (struct my_data *)_private; - (void)a; /* UNUSED */ - (void)buff; /* UNUSED */ - (void)s; /* UNUSED */ - assertEqualInt(MAGIC, private->magic); - ++private->write_called; - return (private->write_return); -} - -static int -my_open(struct archive *a, void *_private) -{ - struct my_data *private = (struct my_data *)_private; - (void)a; /* UNUSED */ - assertEqualInt(MAGIC, private->magic); - ++private->open_called; - return (private->open_return); -} - -static int -my_close(struct archive *a, void *_private) -{ - struct my_data *private = (struct my_data *)_private; - (void)a; /* UNUSED */ - assertEqualInt(MAGIC, private->magic); - ++private->close_called; - return (private->close_return); -} - - -DEFINE_TEST(test_open_failure) -{ - struct archive *a; - struct my_data private; - - memset(&private, 0, sizeof(private)); - private.magic = MAGIC; - private.open_return = ARCHIVE_FATAL; - a = archive_read_new(); - assert(a != NULL); - assertEqualInt(ARCHIVE_FATAL, - archive_read_open(a, &private, my_open, my_read, my_close)); - assertEqualInt(1, private.open_called); - assertEqualInt(0, private.read_called); - assertEqualInt(1, private.close_called); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - assertEqualInt(1, private.open_called); - assertEqualInt(0, private.read_called); - assertEqualInt(1, private.close_called); - - memset(&private, 0, sizeof(private)); - private.magic = MAGIC; - private.open_return = ARCHIVE_FAILED; - a = archive_read_new(); - assert(a != NULL); - assertEqualInt(ARCHIVE_FAILED, - archive_read_open(a, &private, my_open, my_read, my_close)); - assertEqualInt(1, private.open_called); - assertEqualInt(0, private.read_called); - assertEqualInt(1, private.close_called); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - assertEqualInt(1, private.open_called); - assertEqualInt(0, private.read_called); - assertEqualInt(1, private.close_called); - - memset(&private, 0, sizeof(private)); - private.magic = MAGIC; - private.open_return = ARCHIVE_WARN; - a = archive_read_new(); - assert(a != NULL); - assertEqualInt(ARCHIVE_WARN, - archive_read_open(a, &private, my_open, my_read, my_close)); - assertEqualInt(1, private.open_called); - assertEqualInt(0, private.read_called); - assertEqualInt(1, private.close_called); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - assertEqualInt(1, private.open_called); - assertEqualInt(0, private.read_called); - assertEqualInt(1, private.close_called); - - memset(&private, 0, sizeof(private)); - private.magic = MAGIC; - private.open_return = ARCHIVE_OK; - private.read_return = ARCHIVE_FATAL; - a = archive_read_new(); - assert(a != NULL); - assertEqualInt(ARCHIVE_OK, - archive_read_support_filter_compress(a)); - assertEqualInt(ARCHIVE_OK, archive_read_support_format_tar(a)); - assertEqualInt(ARCHIVE_FATAL, - archive_read_open(a, &private, my_open, my_read, my_close)); - assertEqualInt(1, private.open_called); - assertEqualInt(1, private.read_called); - assertEqualInt(1, private.close_called); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - assertEqualInt(1, private.open_called); - assertEqualInt(1, private.read_called); - assertEqualInt(1, private.close_called); - - memset(&private, 0, sizeof(private)); - private.magic = MAGIC; - private.open_return = ARCHIVE_FATAL; - a = archive_write_new(); - assert(a != NULL); - assertEqualInt(ARCHIVE_FATAL, - archive_write_open(a, &private, my_open, my_write, my_close)); - assertEqualInt(1, private.open_called); - assertEqualInt(0, private.write_called); - assertEqualInt(0, private.close_called); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - assertEqualInt(1, private.open_called); - assertEqualInt(0, private.write_called); - assertEqualInt(0, private.close_called); - - memset(&private, 0, sizeof(private)); - private.magic = MAGIC; - private.open_return = ARCHIVE_FATAL; - a = archive_write_new(); - assert(a != NULL); - archive_write_add_filter_compress(a); - archive_write_set_format_ustar(a); - assertEqualInt(ARCHIVE_FATAL, - archive_write_open(a, &private, my_open, my_write, my_close)); - assertEqualInt(1, private.open_called); - assertEqualInt(0, private.write_called); - assertEqualInt(0, private.close_called); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - assertEqualInt(1, private.open_called); - assertEqualInt(0, private.write_called); - assertEqualInt(0, private.close_called); - - memset(&private, 0, sizeof(private)); - private.magic = MAGIC; - private.open_return = ARCHIVE_FATAL; - a = archive_write_new(); - assert(a != NULL); - archive_write_set_format_zip(a); - assertEqualInt(ARCHIVE_FATAL, - archive_write_open(a, &private, my_open, my_write, my_close)); - assertEqualInt(1, private.open_called); - assertEqualInt(0, private.write_called); - assertEqualInt(0, private.close_called); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - assertEqualInt(1, private.open_called); - assertEqualInt(0, private.write_called); - assertEqualInt(0, private.close_called); - - memset(&private, 0, sizeof(private)); - private.magic = MAGIC; - private.open_return = ARCHIVE_FATAL; - a = archive_write_new(); - assert(a != NULL); - archive_write_add_filter_gzip(a); - assertEqualInt(ARCHIVE_FATAL, - archive_write_open(a, &private, my_open, my_write, my_close)); - assertEqualInt(1, private.open_called); - assertEqualInt(0, private.write_called); - assertEqualInt(0, private.close_called); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - assertEqualInt(1, private.open_called); - assertEqualInt(0, private.write_called); - assertEqualInt(0, private.close_called); - -} diff --git a/thirdparty/libarchive/libarchive/test/test_open_fd.c b/thirdparty/libarchive/libarchive/test/test_open_fd.c deleted file mode 100644 index 7da8b5ebc..000000000 --- a/thirdparty/libarchive/libarchive/test/test_open_fd.c +++ /dev/null @@ -1,134 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_open_fd.c 201247 2009-12-30 05:59:21Z kientzle $"); - -#if defined(_WIN32) && !defined(__CYGWIN__) -#define open _open -#if !defined(__BORLANDC__) -#ifdef lseek -#undef lseek -#endif -#define lseek _lseek -#endif -#define close _close -#endif - -DEFINE_TEST(test_open_fd) -{ - char buff[64]; - struct archive_entry *ae; - struct archive *a; - int fd; - const char *skip_open_fd_err_test; - -#if defined(__BORLANDC__) - fd = open("test.tar", O_RDWR | O_CREAT | O_BINARY); -#else - fd = open("test.tar", O_RDWR | O_CREAT | O_BINARY, 0777); -#endif - assert(fd >= 0); - if (fd < 0) - return; - - /* Write an archive through this fd. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_fd(a, fd)); - - /* - * Write a file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 0); - archive_entry_copy_pathname(ae, "file"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 8); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9)); - - /* - * Write a second file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file2"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 819200); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Now, read the data back. - */ - assert(lseek(fd, 0, SEEK_SET) == 0); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_fd(a, fd, 512)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file", archive_entry_pathname(ae)); - assert((S_IFREG | 0755) == archive_entry_mode(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff, 10)); - assertEqualMem(buff, "12345678", 8); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("file2", archive_entry_pathname(ae)); - assert((S_IFREG | 0755) == archive_entry_mode(ae)); - assertEqualInt(819200, archive_entry_size(ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a)); - - /* Verify the end of the archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - close(fd); - - skip_open_fd_err_test = getenv("SKIP_OPEN_FD_ERR_TEST"); - if(skip_open_fd_err_test == NULL) { - /* - * Verify some of the error handling. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - /* FD 100 shouldn't be open. */ - assertEqualIntA(a, ARCHIVE_FATAL, - archive_read_open_fd(a, 100, 512)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - } -} diff --git a/thirdparty/libarchive/libarchive/test/test_open_file.c b/thirdparty/libarchive/libarchive/test/test_open_file.c deleted file mode 100644 index bee4b3b48..000000000 --- a/thirdparty/libarchive/libarchive/test/test_open_file.c +++ /dev/null @@ -1,108 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_open_file.c 201247 2009-12-30 05:59:21Z kientzle $"); - -DEFINE_TEST(test_open_file) -{ - char buff[64]; - struct archive_entry *ae; - struct archive *a; - FILE *f; - - f = fopen("test.tar", "wb"); - assert(f != NULL); - if (f == NULL) - return; - - /* Write an archive through this FILE *. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_FILE(a, f)); - - /* - * Write a file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 0); - archive_entry_copy_pathname(ae, "file"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 8); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9)); - - /* - * Write a second file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file2"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 819200); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - fclose(f); - - /* - * Now, read the data back. - */ - f = fopen("test.tar", "rb"); - assert(f != NULL); - if (f == NULL) - return; - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_FILE(a, f)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file", archive_entry_pathname(ae)); - assert((S_IFREG | 0755) == archive_entry_mode(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff, 10)); - assertEqualMem(buff, "12345678", 8); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("file2", archive_entry_pathname(ae)); - assert((S_IFREG | 0755) == archive_entry_mode(ae)); - assertEqualInt(819200, archive_entry_size(ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a)); - - /* Verify the end of the archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - fclose(f); -} diff --git a/thirdparty/libarchive/libarchive/test/test_open_filename.c b/thirdparty/libarchive/libarchive/test/test_open_filename.c deleted file mode 100644 index 91afce244..000000000 --- a/thirdparty/libarchive/libarchive/test/test_open_filename.c +++ /dev/null @@ -1,200 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_open_filename.c 191183 2009-04-17 01:06:31Z kientzle $"); - -static void -test_open_filename_mbs(void) -{ - char buff[64]; - struct archive_entry *ae; - struct archive *a; - - /* Write an archive through this FILE *. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_filename(a, "test.tar")); - - /* - * Write a file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 0); - archive_entry_copy_pathname(ae, "file"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 8); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9)); - - /* - * Write a second file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file2"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 819200); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Now, read the data back. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, "test.tar", 512)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file", archive_entry_pathname(ae)); - assert((S_IFREG | 0755) == archive_entry_mode(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff, 10)); - assertEqualMem(buff, "12345678", 8); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("file2", archive_entry_pathname(ae)); - assert((S_IFREG | 0755) == archive_entry_mode(ae)); - assertEqualInt(819200, archive_entry_size(ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a)); - - /* Verify the end of the archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Verify some of the error handling. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_FATAL, - archive_read_open_filename(a, "nonexistent.tar", 512)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - -} - -static void -test_open_filename_wcs(void) -{ - char buff[64]; - struct archive_entry *ae; - struct archive *a; - - /* Write an archive through this FILE *. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_filename_w(a, L"test.tar")); - - /* - * Write a file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 0); - archive_entry_copy_pathname_w(ae, L"file"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 8); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9)); - - /* - * Write a second file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname_w(ae, L"file2"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 819200); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Now, read the data back. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename_w(a, L"test.tar", 512)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualWString(L"file", archive_entry_pathname_w(ae)); - assert((S_IFREG | 0755) == archive_entry_mode(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff, 10)); - assertEqualMem(buff, "12345678", 8); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualWString(L"file2", archive_entry_pathname_w(ae)); - assert((S_IFREG | 0755) == archive_entry_mode(ae)); - assertEqualInt(819200, archive_entry_size(ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a)); - - /* Verify the end of the archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Verify some of the error handling. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_FATAL, - archive_read_open_filename_w(a, L"nonexistent.tar", 512)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - -} - -DEFINE_TEST(test_open_filename) -{ - test_open_filename_mbs(); - test_open_filename_wcs(); -} diff --git a/thirdparty/libarchive/libarchive/test/test_pax_filename_encoding.c b/thirdparty/libarchive/libarchive/test/test_pax_filename_encoding.c deleted file mode 100644 index 2fb7f452d..000000000 --- a/thirdparty/libarchive/libarchive/test/test_pax_filename_encoding.c +++ /dev/null @@ -1,589 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_pax_filename_encoding.c 201247 2009-12-30 05:59:21Z kientzle $"); - -#include - -/* - * Pax interchange is supposed to encode filenames into - * UTF-8. Of course, that's not always possible. This - * test is intended to verify that filenames always get - * stored and restored correctly, regardless of the encodings. - */ - -/* - * Read a manually-created archive that has filenames that are - * stored in binary instead of UTF-8 and verify that we get - * the right filename returned and that we get a warning only - * if the header isn't marked as binary. - */ -static void -test_pax_filename_encoding_1(void) -{ - static const char testname[] = "test_pax_filename_encoding.tar"; - /* - * \314\214 is a valid 2-byte UTF-8 sequence. - * \374 is invalid in UTF-8. - */ - char filename[] = "abc\314\214mno\374xyz"; - struct archive *a; - struct archive_entry *entry; - - /* - * Read an archive that has non-UTF8 pax filenames in it. - */ - extract_reference_file(testname); - a = archive_read_new(); - assertEqualInt(ARCHIVE_OK, archive_read_support_format_tar(a)); - assertEqualInt(ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualInt(ARCHIVE_OK, - archive_read_open_filename(a, testname, 10240)); - /* - * First entry in this test archive has an invalid UTF-8 sequence - * in it, but the header is not marked as hdrcharset=BINARY, so that - * requires a warning. - */ - failure("Invalid UTF8 in a pax archive pathname should cause a warning"); - assertEqualInt(ARCHIVE_WARN, archive_read_next_header(a, &entry)); - assertEqualString(filename, archive_entry_pathname(entry)); - /* - * Second entry is identical except that it does have - * hdrcharset=BINARY, so no warning should be generated. - */ - failure("A pathname with hdrcharset=BINARY can have invalid UTF8\n" - " characters in it without generating a warning"); - assertEqualInt(ARCHIVE_OK, archive_read_next_header(a, &entry)); - assertEqualString(filename, archive_entry_pathname(entry)); - archive_read_free(a); -} - -/* - * Set the locale and write a pathname containing invalid characters. - * This should work; the underlying implementation should automatically - * fall back to storing the pathname in binary. - */ -static void -test_pax_filename_encoding_2(void) -{ - char filename[] = "abc\314\214mno\374xyz"; - struct archive *a; - struct archive_entry *entry; - char buff[65536]; - char longname[] = "abc\314\214mno\374xyz" - "/abc\314\214mno\374xyz/abcdefghijklmnopqrstuvwxyz" - "/abc\314\214mno\374xyz/abcdefghijklmnopqrstuvwxyz" - "/abc\314\214mno\374xyz/abcdefghijklmnopqrstuvwxyz" - "/abc\314\214mno\374xyz/abcdefghijklmnopqrstuvwxyz" - "/abc\314\214mno\374xyz/abcdefghijklmnopqrstuvwxyz" - "/abc\314\214mno\374xyz/abcdefghijklmnopqrstuvwxyz" - ; - size_t used; - - /* - * We need a starting locale which has invalid sequences. - * en_US.UTF-8 seems to be commonly supported. - */ - /* If it doesn't exist, just warn and return. */ - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("invalid encoding tests require a suitable locale;" - " en_US.UTF-8 not available on this system"); - return; - } - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, 0, archive_write_set_format_pax(a)); - assertEqualIntA(a, 0, archive_write_add_filter_none(a)); - assertEqualIntA(a, 0, archive_write_set_bytes_per_block(a, 0)); - assertEqualInt(0, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - assert((entry = archive_entry_new()) != NULL); - /* Set pathname, gname, uname, hardlink to nonconvertible values. */ - archive_entry_copy_pathname(entry, filename); - archive_entry_copy_gname(entry, filename); - archive_entry_copy_uname(entry, filename); - archive_entry_copy_hardlink(entry, filename); - archive_entry_set_filetype(entry, AE_IFREG); - failure("This should generate a warning for nonconvertible names."); - assertEqualInt(ARCHIVE_WARN, archive_write_header(a, entry)); - archive_entry_free(entry); - - assert((entry = archive_entry_new()) != NULL); - /* Set path, gname, uname, and symlink to nonconvertible values. */ - archive_entry_copy_pathname(entry, filename); - archive_entry_copy_gname(entry, filename); - archive_entry_copy_uname(entry, filename); - archive_entry_copy_symlink(entry, filename); - archive_entry_set_filetype(entry, AE_IFLNK); - failure("This should generate a warning for nonconvertible names."); - assertEqualInt(ARCHIVE_WARN, archive_write_header(a, entry)); - archive_entry_free(entry); - - assert((entry = archive_entry_new()) != NULL); - /* Set pathname to a very long nonconvertible value. */ - archive_entry_copy_pathname(entry, longname); - archive_entry_set_filetype(entry, AE_IFREG); - failure("This should generate a warning for nonconvertible names."); - assertEqualInt(ARCHIVE_WARN, archive_write_header(a, entry)); - archive_entry_free(entry); - - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Now read the entries back. - */ - - assert((a = archive_read_new()) != NULL); - assertEqualInt(0, archive_read_support_format_tar(a)); - assertEqualInt(0, archive_read_open_memory(a, buff, used)); - - assertEqualInt(0, archive_read_next_header(a, &entry)); - assertEqualString(filename, archive_entry_pathname(entry)); - assertEqualString(filename, archive_entry_gname(entry)); - assertEqualString(filename, archive_entry_uname(entry)); - assertEqualString(filename, archive_entry_hardlink(entry)); - - assertEqualInt(0, archive_read_next_header(a, &entry)); - assertEqualString(filename, archive_entry_pathname(entry)); - assertEqualString(filename, archive_entry_gname(entry)); - assertEqualString(filename, archive_entry_uname(entry)); - assertEqualString(filename, archive_entry_symlink(entry)); - - assertEqualInt(0, archive_read_next_header(a, &entry)); - assertEqualString(longname, archive_entry_pathname(entry)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -#if 0 /* Disable this until Tim check out it. */ - -/* - * Create an entry starting from a wide-character Unicode pathname, - * read it back into "C" locale, which doesn't support the name. - * TODO: Figure out the "right" behavior here. - */ -static void -test_pax_filename_encoding_3(void) -{ - wchar_t badname[] = L"xxxAyyyBzzz"; - const char badname_utf8[] = "xxx\xE1\x88\xB4yyy\xE5\x99\xB8zzz"; - struct archive *a; - struct archive_entry *entry; - char buff[65536]; - size_t used; - - badname[3] = 0x1234; - badname[7] = 0x5678; - - /* If it doesn't exist, just warn and return. */ - if (NULL == setlocale(LC_ALL, "C")) { - skipping("Can't set \"C\" locale, so can't exercise " - "certain character-conversion failures"); - return; - } - - /* If wctomb is broken, warn and return. */ - if (wctomb(buff, 0x1234) > 0) { - skipping("Cannot test conversion failures because \"C\" " - "locale on this system has no invalid characters."); - return; - } - - /* If wctomb is broken, warn and return. */ - if (wctomb(buff, 0x1234) > 0) { - skipping("Cannot test conversion failures because \"C\" " - "locale on this system has no invalid characters."); - return; - } - - /* Skip test if archive_entry_update_pathname_utf8() is broken. */ - /* In particular, this is currently broken on Win32 because - * setlocale() does not set the default encoding for CP_ACP. */ - entry = archive_entry_new(); - if (archive_entry_update_pathname_utf8(entry, badname_utf8)) { - archive_entry_free(entry); - skipping("Cannot test conversion failures."); - return; - } - archive_entry_free(entry); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, 0, archive_write_set_format_pax(a)); - assertEqualIntA(a, 0, archive_write_add_filter_none(a)); - assertEqualIntA(a, 0, archive_write_set_bytes_per_block(a, 0)); - assertEqualInt(0, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - assert((entry = archive_entry_new()) != NULL); - /* Set pathname to non-convertible wide value. */ - archive_entry_copy_pathname_w(entry, badname); - archive_entry_set_filetype(entry, AE_IFREG); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - - assert((entry = archive_entry_new()) != NULL); - archive_entry_copy_pathname_w(entry, L"abc"); - /* Set gname to non-convertible wide value. */ - archive_entry_copy_gname_w(entry, badname); - archive_entry_set_filetype(entry, AE_IFREG); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - - assert((entry = archive_entry_new()) != NULL); - archive_entry_copy_pathname_w(entry, L"abc"); - /* Set uname to non-convertible wide value. */ - archive_entry_copy_uname_w(entry, badname); - archive_entry_set_filetype(entry, AE_IFREG); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - - assert((entry = archive_entry_new()) != NULL); - archive_entry_copy_pathname_w(entry, L"abc"); - /* Set hardlink to non-convertible wide value. */ - archive_entry_copy_hardlink_w(entry, badname); - archive_entry_set_filetype(entry, AE_IFREG); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - - assert((entry = archive_entry_new()) != NULL); - archive_entry_copy_pathname_w(entry, L"abc"); - /* Set symlink to non-convertible wide value. */ - archive_entry_copy_symlink_w(entry, badname); - archive_entry_set_filetype(entry, AE_IFLNK); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Now read the entries back. - */ - - assert((a = archive_read_new()) != NULL); - assertEqualInt(0, archive_read_support_format_tar(a)); - assertEqualInt(0, archive_read_open_memory(a, buff, used)); - - failure("A non-convertible pathname should cause a warning."); - assertEqualInt(ARCHIVE_WARN, archive_read_next_header(a, &entry)); - assertEqualWString(badname, archive_entry_pathname_w(entry)); - failure("If native locale can't convert, we should get UTF-8 back."); - assertEqualString(badname_utf8, archive_entry_pathname(entry)); - - failure("A non-convertible gname should cause a warning."); - assertEqualInt(ARCHIVE_WARN, archive_read_next_header(a, &entry)); - assertEqualWString(badname, archive_entry_gname_w(entry)); - failure("If native locale can't convert, we should get UTF-8 back."); - assertEqualString(badname_utf8, archive_entry_gname(entry)); - - failure("A non-convertible uname should cause a warning."); - assertEqualInt(ARCHIVE_WARN, archive_read_next_header(a, &entry)); - assertEqualWString(badname, archive_entry_uname_w(entry)); - failure("If native locale can't convert, we should get UTF-8 back."); - assertEqualString(badname_utf8, archive_entry_uname(entry)); - - failure("A non-convertible hardlink should cause a warning."); - assertEqualInt(ARCHIVE_WARN, archive_read_next_header(a, &entry)); - assertEqualWString(badname, archive_entry_hardlink_w(entry)); - failure("If native locale can't convert, we should get UTF-8 back."); - assertEqualString(badname_utf8, archive_entry_hardlink(entry)); - - failure("A non-convertible symlink should cause a warning."); - assertEqualInt(ARCHIVE_WARN, archive_read_next_header(a, &entry)); - assertEqualWString(badname, archive_entry_symlink_w(entry)); - assertEqualWString(NULL, archive_entry_hardlink_w(entry)); - failure("If native locale can't convert, we should get UTF-8 back."); - assertEqualString(badname_utf8, archive_entry_symlink(entry)); - - assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &entry)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} -#else -static void -test_pax_filename_encoding_3(void) -{ -} -#endif - -/* - * Verify that KOI8-R filenames are correctly translated to Unicode and UTF-8. - */ -DEFINE_TEST(test_pax_filename_encoding_KOI8R) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) { - skipping("KOI8-R locale not available on this system."); - return; - } - - /* Check if the platform completely supports the string conversion. */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_pax(a)); - if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) { - skipping("This system cannot convert character-set" - " from KOI8-R to UTF-8."); - archive_write_free(a); - return; - } - archive_write_free(a); - - /* Re-create a write archive object since filenames should be written - * in UTF-8 by default. */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_pax(a)); - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - archive_entry_set_pathname(entry, "\xD0\xD2\xC9"); - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Above three characters in KOI8-R should translate to the following - * three characters (two bytes each) in UTF-8. */ - assertEqualMem(buff + 512, "15 path=\xD0\xBF\xD1\x80\xD0\xB8\x0A", 15); -} - -/* - * Verify that CP1251 filenames are correctly translated to Unicode and UTF-8. - */ -DEFINE_TEST(test_pax_filename_encoding_CP1251) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "Russian_Russia") && - NULL == setlocale(LC_ALL, "ru_RU.CP1251")) { - skipping("KOI8-R locale not available on this system."); - return; - } - - /* Check if the platform completely supports the string conversion. */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_pax(a)); - if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) { - skipping("This system cannot convert character-set" - " from KOI8-R to UTF-8."); - archive_write_free(a); - return; - } - archive_write_free(a); - - /* Re-create a write archive object since filenames should be written - * in UTF-8 by default. */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_pax(a)); - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - archive_entry_set_pathname(entry, "\xef\xf0\xe8"); - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Above three characters in KOI8-R should translate to the following - * three characters (two bytes each) in UTF-8. */ - assertEqualMem(buff + 512, "15 path=\xD0\xBF\xD1\x80\xD0\xB8\x0A", 15); -} - -/* - * Verify that EUC-JP filenames are correctly translated to Unicode and UTF-8. - */ -DEFINE_TEST(test_pax_filename_encoding_EUCJP) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "ja_JP.eucJP")) { - skipping("eucJP locale not available on this system."); - return; - } - - /* Check if the platform completely supports the string conversion. */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_pax(a)); - if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) { - skipping("This system cannot convert character-set" - " from eucJP to UTF-8."); - archive_write_free(a); - return; - } - archive_write_free(a); - - /* Re-create a write archive object since filenames should be written - * in UTF-8 by default. */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_pax(a)); - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - archive_entry_set_pathname(entry, "\xC9\xBD.txt"); - /* Check the Unicode version. */ - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Check UTF-8 version. */ - assertEqualMem(buff + 512, "16 path=\xE8\xA1\xA8.txt\x0A", 16); - -} - -/* - * Verify that CP932/SJIS filenames are correctly translated to Unicode and UTF-8. - */ -DEFINE_TEST(test_pax_filename_encoding_CP932) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "Japanese_Japan") && - NULL == setlocale(LC_ALL, "ja_JP.SJIS")) { - skipping("eucJP locale not available on this system."); - return; - } - - /* Check if the platform completely supports the string conversion. */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_pax(a)); - if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) { - skipping("This system cannot convert character-set" - " from CP932/SJIS to UTF-8."); - archive_write_free(a); - return; - } - archive_write_free(a); - - /* Re-create a write archive object since filenames should be written - * in UTF-8 by default. */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_pax(a)); - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - archive_entry_set_pathname(entry, "\x95\x5C.txt"); - /* Check the Unicode version. */ - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Check UTF-8 version. */ - assertEqualMem(buff + 512, "16 path=\xE8\xA1\xA8.txt\x0A", 16); - -} - -/* - * Verify that KOI8-R filenames are not translated to Unicode and UTF-8 - * when using hdrcharset=BINARY option. - */ -DEFINE_TEST(test_pax_filename_encoding_KOI8R_BINARY) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) { - skipping("KOI8-R locale not available on this system."); - return; - } - - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_pax(a)); - /* BINARY mode should be accepted. */ - assertEqualInt(ARCHIVE_OK, - archive_write_set_options(a, "hdrcharset=BINARY")); - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - archive_entry_set_pathname(entry, "\xD0\xD2\xC9"); - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* "hdrcharset=BINARY" pax attribute should be written. */ - assertEqualMem(buff + 512, "21 hdrcharset=BINARY\x0A", 21); - /* Above three characters in KOI8-R should not translate to any - * character-set. */ - assertEqualMem(buff + 512+21, "12 path=\xD0\xD2\xC9\x0A", 12); -} - -/* - * Pax format writer only accepts both BINARY and UTF-8. - * If other character-set name is specified, you will get ARCHIVE_FAILED. - */ -DEFINE_TEST(test_pax_filename_encoding_KOI8R_CP1251) -{ - struct archive *a; - - if (NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) { - skipping("KOI8-R locale not available on this system."); - return; - } - - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_pax(a)); - /* pax format writer only accepts both BINARY and UTF-8. */ - assertEqualInt(ARCHIVE_FAILED, - archive_write_set_options(a, "hdrcharset=CP1251")); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); -} - - -DEFINE_TEST(test_pax_filename_encoding) -{ - test_pax_filename_encoding_1(); - test_pax_filename_encoding_2(); - test_pax_filename_encoding_3(); -} diff --git a/thirdparty/libarchive/libarchive/test/test_pax_filename_encoding.tar.uu b/thirdparty/libarchive/libarchive/test/test_pax_filename_encoding.tar.uu deleted file mode 100644 index 47db18915..000000000 --- a/thirdparty/libarchive/libarchive/test/test_pax_filename_encoding.tar.uu +++ /dev/null @@ -1,118 +0,0 @@ -$FreeBSD: head/lib/libarchive/test/test_pax_filename_encoding.tar.uu 191183 2009-04-17 01:06:31Z kientzle $ -begin 644 test_pax_filename_encoding.tar -M4&%X2&5A9&5R+V%B8\R,;6YO6'AY>@`````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````#`P,#8T-"``,#`Q-S4P(``P,#$W-3`@`#`P,#`P,#`P,38V -M(#$P-S8V-C`W,#,V(#`Q-3,P-@`@>``````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````!U@HR,"!C=&EM -M93TQ,C`U-3,X-C@U"C(P(&%T:6UE/3$R,#4U,S@V,C8*,3<@4T-(24Q9+F1E -M=CTX.`HR,B!30TA)3%DN:6YO/30S,34T-#D*,3@@4T-(24Q9+FYL:6YK/3$* -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````````````````````````````&%B8\R,;6YO6'AY -M>@`````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````P -M,#`V-#0@`#`P,3'EZ -M```````````````````````````````````````````````````````````` -M````````````````````````````````````````````,#`P-C0T(``P,#$W -M-3`@`#`P,3'EZ"C(P(&-T:6UE -M/3$R,#4U-#$W,S4*,C`@871I;64],3(P-34S.#8R-@HQ-R!30TA)3%DN9&5V -M/3@X"C(R(%-#2$E,62YI;F\]-#,Q-3$R-@HQ."!30TA)3%DN;FQI;FL],0H` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M````````````````86)CS(QM;F_\>'EZ```````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````````````#`P,#8T-"``,#`Q-S4P(``P,#$W-3`@ -M`#`P,#`P,#`P,#`U(#$P-S8V-C`W,#,V(#`Q,S4W,0`@,``````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````````````````````!U -M``````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````!UR!M87)G:6XM8F]T=&]M.B`P+C`X -M:6X@?0H)"4@Q('L@;6%R9VEN+6)O='1O;3H@,"XP.&EN('T*"0E(,2YW97-T -M97)N('L@9F]N="UF86UI;'DZ("),:6)E2!C;VUP;&5X('!I -M96-E(&]F('-O9G1W87)E('1H870@6EN9R!N97<@<&]R=',@86YD(&9O2!S:6=N:69I8V%N="!C -M:&%N9V4@=&\@;&EB87)C:&EV92P@:6YC;'5D:6YG(&UO&5S -M+`IS:&]U;&0@8F4@86-C;VUP86YI960@8GD@;F5W('1E'!L86EN2!O9B!T:&%T(&-O;7!O;F5N="X@5&AE -M6]U -M(&YE960@=&\@9VEV92!T:&5M('1W;R!P:65C97,@;V8*:6YF;W)M871I;VXZ -M(`H\+U`^"CQ53#X*"3Q,23X\4"!35%E,13TB;6%R9VEN+6)O='1O;3H@,&EN -M(CY4:&4@9G5L;"!P871H('1O('1H92!D:7)E8W1O&5C=71A8FQE('!R;V=R86T@8F5I;F<@ -M=&5S=&5D("AN;W0*"6%P<&QI8V%B;&4@=&\@;&EB87)C:&EV95]T97-T('-I -M;F-E(&QI8F%R8VAI=F4@:7,@8V]M<&EL960@:6YT;R!T:&4*"71E'1E;G-I;VXN(%1H92!T97-T('!R;V=R86US(&QO;VL@:6X@82!F97<* -M3L@=&AE>2!N965D('1H92!F=6QL('!A=&@@=&\@ -M=&AE(&%P<')O<')I871E(&5X96-U=&%B;&4N"D%L=&AO=6=H(&)S9'1A2!I;G1E;F1E -M9"!F;W(*=&5S=&EN9R!B2!T;R!V97)I9GD@=&AA="!T:&4@=&5S=`IP2X@"CPO4#X*/%`^5VAE;B!R=6XL('1H -M92!T97-T('!R;V=R86US(&]U='!U="!A('!R;V=R97-S(&UE&5R8VES:6YG.B!B0HF;F)S<#L@=&5S=%]C;W!Y+F,Z,32YC.C$W,3H@ -M1F%I;&5D(#(V-"!T:6UE2!F;W(@9G5R=&AE -M&5R8VES960N(`H)/"]0/@H)/$Q)/CQ0/D)A&%M -M<&QE+`IM86YY(&]F('1H92!L:6)AFEP/"]45#XL"G=H:6-H('9E&%M<&QE -M(&%B;W9E*0IG96YE2!P2!S:6UP;&EF:65S(&1I86=N -M;W-I;F<*9F%I;'5R97,N(`H\+U`^"CQ(,2!#3$%34STB=V5S=&4`9GL/0!0` --+CO?G@`````````````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_rar_multivolume_multiple_files.part2.rar.uu b/thirdparty/libarchive/libarchive/test/test_rar_multivolume_multiple_files.part2.rar.uu deleted file mode 100644 index 012399a5c..000000000 --- a/thirdparty/libarchive/libarchive/test/test_rar_multivolume_multiple_files.part2.rar.uu +++ /dev/null @@ -1,163 +0,0 @@ -begin 644 test_rar_multivolume_multiple_files.part2.rar -M4F%R(1H'`!EZ2!E87-Y('1O"F%D9"!N97<@=&5S=',N*2`*/"]0/@H\ -M4#Y4:&4@=&5S="!H87)N97-S(&1E=&5R;6EN97,@=VAI8V@@=&5S=',@=&\@ -M&-E<'0@9F]R('-T9&EN+"!S=&1O=70L(&%N9"!S -M=&1E2!D:7)E8W1O2!D -M:7)E8W1O2!A2!I0H)=VAE;B!T:&4@=&5S="!S=&%R=',N(`H)/"]0/@H)/$Q)/CQ0(%-4 -M64Q%/2)M87)G:6XM8F]T=&]M.B`P:6XB/D%N>2!F:6QE2X@5&AE('1E2!D -M96)U9V=E2!D:69F97)E;G0@<&QA -M=&9O2!W'@H*2!F=6YC=&EO;G,@=&AA="!Y;W4@8V%N -M('5S92X@5&AE3PO5%0^+"`\5%0@0TQ!4U,](G=E2!T97-T6]U(&-A;B!R96-O=F5R('1H -M92!R969E2!O9B!C:&%R86-T97)S+B!4:&ES('=A2X@270GF5D -M(&9O6]U('1H:6YK"@EY;W4G=F4@9F]U;F0@82!B=6&EN9R!T:&4@8G5G+B`*"3PO4#X*"3Q,23X\ -M4"!35%E,13TB;6%R9VEN+6)O='1O;3H@,&EN(CY$3R!R=6X@86QL(&]F('1H -M92!T97-T0H)97AE6]U('-E92!A('1E6]U(&AA=F4@<75E2!R96%D(&$@<')E+6)U:6QT"FEN<'5T(&9I;&4@86YD('9E2!T:&4@2!S=')A:6=H=&9O0IA;F0@=&AE;B!O<&5N('1H92!M96UO71E&%C="!D871A(&-O;G1A:6YS('9A;'5E2!V97)I9GEI -M;F<@9FEL97,@;VX@9&ES:RX@5&\@;6%K92!T:&ES(&5A0IA -M=F%I;&%B;&4N(`H\+U`^"CQ(,B!#3$%34STB=V5S=&5R;B(^/$$@3D%-13TB -M1G5Z>E]T97-T97(B/CPO03Y&=7IZ('1E0IU2!D86UA9V5D+B`H4F5M96UB97(@=&AA="!L -M:6)AB!T97-T97(@:6YS=&5A9"!G96YE2UD86UA -M9V5D(&9I;&4L('-A=F5S('1H870@9FEL92!T;R!D:7-K+"!T:&5N(')U;G,@ -M=&AE(&9I;&4*=&AR;W5G:"!L:6)A2!T;R!PB!T97-T97(@:&%S('!R -M;W9E;B!Q=6ET92!U0IL87)G92!E;G1R -M:65S+"!U<"!T;R`Q('1E71E+B!/9B!C;W5R71E"F5N=')Y('1O(&%N('5N8V]M<')EFEP -M,@IC;VUP65R('1H870@:6UP;&5M96YT2!L87)G92!E;G1R:65S('1HF5R;RUC;W!Y+B!7:&5N('EO=2!G:79E(&ET(&$@;&%R9V4* -M8FQO8VL@=&\@=W)I=&4@=&\@86X@96YT2P@:70@=VEL;"!P87-S -M('!O:6YT97)S('-T&-E<'0@:6X@=&AO2!D -M971E8W0@=VAE;B!A(&)L;V-K(&)E:6YG('=R:71T96X@;W5T(&)Y"G1H92!A -M2!B;V1Y -M+"!A;F0@F5S('=H:6-H('1R861E(&]F9@IP;W)T86)I;&ET>2!V -M97)S=7,@'0O:'1M;#L@8VAA"DB/@H)/$U%5$$@3D%-13TB0U)%051%1"(@ -M0T].5$5.5#TB,C`Q,3`V,C8[,C(R,S4Q,#`B/@H)/$U%5$$@3D%-13TB0TA! -M3D=%1"(@0T].5$5.5#TB,C`Q,3`V,C8[,C(R-30U,#`B/@H)/%-464Q%(%19 -M4$4](G1E>'0O8W-S(CX*"3PA+2T*"0E`<&%G92![(&UAR!F;VYT -M+69A;6EL>3H@(D)I='-TR!F -M;VYT+69A;6EL>3H@(D9R965386YS(B!]"@D)4%)%+F-J:R![(&9O;G0M9F%M -M:6QY.B`B0FETR!M87)G:6XM8F]T=&]M.B`P+C`X:6X@?0H)"4@R+F-T;"![(&9O;G0M9F%M -M:6QY.B`B1G)E95-A;G,B('T*"0E45"YC:FL@>R!F;VYT+69A;6EL>3H@(D)I -M='-T"!P:65C92!O9B!S;V9T=V%R92!T -M:&%T(')U;G,@;VX*82!N=6UB97(@;V8@9&EF9F5R96YT('!L871F;W)M2X@"CPO4#X*/%`^06YY('-I9VYI9FEC86YT(&-H86YG92!T;R!L:6)A -M2!N97<@=&5S=',@;W(@8VAA;F=E&ES=&EN -M9R!T97-T0H):&]L9&EN9R!T:&4@)G%U;W0[6]U)VQL(&YE960@=&\@ -M2!T:&4*/%14($-,05-3/2)W97-T97)N(CXM2!S:&]U;&0@8F4@=7-A8FQE(&9O -M2!T:&%T('=I;&P@8F4@=7-E -M9`H)9F]R('-C2!F&5C=71A8FQE(&)E:6YG(&5X97)C:7-E -M9"X@"@D\+U`^"@D\3$D^/%`^0F%S:6,@=F5R2(^/"]!/D)A2!T:&%T(&EL;&5G86P@&-E2!W -M:71H('9A'1?:&5A9&5R*&$L("9A;7`[864I*3L*)FYB5]P871H;F%M92AA92DI.SPO -M4%)%/CQ0/@I4:&4@/%14($-,05-3/2)W97-T97)N(CYA2!D969A=6QT+`IT:&5Y(')E<&]R="!T:&4@9F%I;'5R92!A;F0@2!O9@IS<&5C:69I8R!T97-T2!E87-Y -M('1O"F%D9"!N97<@=&5S=',N*2`*/"]0/@H\4#Y4:&4@=&5S="!H87)N97-S -M(&1E=&5R;6EN97,@=VAI8V@@=&5S=',@=&\@&-E -M<'0@9F]R('-T9&EN+"!S=&1O=70L(&%N9"!S=&1E2!D:7)E8W1P6GL/0!0` --_]75M@,````````````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_rar_multivolume_multiple_files.part5.rar.uu b/thirdparty/libarchive/libarchive/test/test_rar_multivolume_multiple_files.part5.rar.uu deleted file mode 100644 index d5ff36ac6..000000000 --- a/thirdparty/libarchive/libarchive/test/test_rar_multivolume_multiple_files.part5.rar.uu +++ /dev/null @@ -1,163 +0,0 @@ -begin 644 test_rar_multivolume_multiple_files.part5.rar -M4F%R(1H'`!EZ2X@*$EF(#Q45"!#3$%34STB=V5S=&5R;B(^+6L\ -M+U14/@H):7,@6]U+B`*"3PO4#X*"3Q, -M23X\4#Y4:&4@8W5R6]U(&-A;B!U6UL:6YK/"]45#XL"@D\5%0@0TQ!4U,](G=E3PO5%0^+`H)/%14($-, -M05-3/2)W97-T97)N(CYA&%M<&QE+"!I9B!Y;W4@;F5E9"!A -M(')E9F5R96YC92!T87(@87)C:&EV92!T;R!U2X@"CPO4#X*/%`^3&]O:R!A="`\5%0@0TQ!4U,](G=E&%M<&QE(&]F('1H:7,@=7-A9V4N(`H\+U`^"CQ0/D$@9F5W(&]F -M('1H92!O;&1E'!E6]U)W9E(&9O=6YD(&$@8G5G+"!W92!R96-O;6UE;F0@=W)I=&EN9R!T -M:&4@=&5S="!F:7)S="P@;6%K92!S=7)E"@ET:&4@=&5S="!F86EL6]U2!O -M;B`\5%0@0TQ!4U,](G=E2!A9&1I;F<@:G5S="!A(&-O=7!L92!O9B!A&ES=&EN9R!T97-T(&EN&%M<&QEQ,``(].```#8Z8%7O-C(4`4 -M,!D`I($``$QI8F%R8VAI=F5!9&1I;F=497-T+FAT;6S`S/-C(4"[3#5!2!S -M=')A:6=H=&9O0IA;F0@=&AE;B!O<&5N('1H92!M96UO71E&%C="!D -M871A(&-O;G1A:6YS('9A;'5E2!V97)I9GEI;F<@9FEL97,@;VX@9&ES -M:RX@5&\@;6%K92!T:&ES(&5A0IA=F%I;&%B;&4N(`H\+U`^ -M"CQ(,B!#3$%34STB=V5S=&5R;B(^/$$@3D%-13TB1G5Z>E]T97-T97(B/CPO -M03Y&=7IZ('1E0IU -M2!D86UA9V5D+B`H4F5M96UB97(@=&AA="!L:6)AB!T97-T97(@:6YS -M=&5A9"!G96YE2UD86UA9V5D(&9I;&4L('-A=F5S -M('1H870@9FEL92!T;R!D:7-K+"!T:&5N(')U;G,@=&AE(&9I;&4*=&AR;W5G -M:"!L:6)A2!T;R!PB!T97-T97(@:&%S('!R;W9E;B!Q=6ET92!U0IL87)G92!E;G1R:65S+"!U<"!T;R`Q('1E -M71E+B!/9B!C;W5R71E"F5N=')Y -M('1O(&%N('5N8V]M<')EFEP,@IC;VUP65R -M('1H870@:6UP;&5M96YT2!L87)G92!E;G1R:65S('1H2!H86YD;&5S(&%L;"!O9B!T:&4@8F]U;F1AF5R;RUC -M;W!Y+B!7:&5N('EO=2!G:79E(&ET(&$@;&%R9V4*8FQO8VL@=&\@=W)I=&4@ -M=&\@86X@96YT2P@:70@=VEL;"!P87-S('!O:6YT97)S('-T&-E<'0@:6X@ -M=&AO2!D971E8W0@=VAE;B!A(&)L -M;V-K(&)E:6YG('=R:71T96X@;W5T(&)Y"G1H92!A2!B;V1Y+"!A;F0@F5S -M('=H:6-H('1R861E(&]F9@IP;W)T86)I;&ET>2!V97)S=7,@PY`%`!.[9:E -)!0`````````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_rar_multivolume_single_file.part1.rar.uu b/thirdparty/libarchive/libarchive/test/test_rar_multivolume_single_file.part1.rar.uu deleted file mode 100644 index 22b5c8dfa..000000000 --- a/thirdparty/libarchive/libarchive/test/test_rar_multivolume_single_file.part1.rar.uu +++ /dev/null @@ -1,159 +0,0 @@ -begin 644 - -M4F%R(1H'`%INR!M87)G:6XZ(#`N-SEI;B!]"@D)4"![(&UAR!M87)G:6XM8F]T=&]M.B`P+C`X:6X@?0H)"4@Q+G=ER!F;VYT+69A;6EL>3H@(DQI8F5R871I;VX@4V5R:68B+"!S97)I9B!] -M"@D)2#$N8VIK('L@9F]N="UF86UI;'DZ(")":71S=')E86T@5F5R82!386YS -M(B!]"@D)2#$N8W1L('L@9F]N="UF86UI;'DZ(")&R!F;VYT+69A;6EL>3H@(D)I='-TR!F;VYT+69A;6EL>3H@(D9R965386YS(B!]"@D)5%0N8VIK('L@ -M9F]N="UF86UI;'DZ(")":71S=')E86T@5F5R82!386YS(BP@;6]N;W-P86-E -M('T*"2TM/@H)/"]35%E,13X*/"](14%$/@H\0D]$62!,04Y'/2)E;BU54R(@ -M1$E2/2),5%(B/@H\2#$@0TQ!4U,](G=E2X@"CPO4#X*/%`^06YY('-I9VYI9FEC86YT(&-H -M86YG92!T;R!L:6)A2!N97<@=&5S=',@;W(@8VAA;F=E -M&ES=&EN9R!T97-T0H):&]L9&EN9R!T:&4@ -M)G%U;W0[6]U -M)VQL(&YE960@=&\@2!T:&4*/%14($-,05-3/2)W97-T97)N(CXM -M2!S:&]U;&0@ -M8F4@=7-A8FQE(&9O2!F&5C=71A8FQE(&)E -M:6YG(&5X97)C:7-E9"X@"@D\+U`^"@D\3$D^/%`^0F%S:6,@=F5R2(^/"]!/D)A2!T:&%T(&EL;&5G86P@&-E2!W:71H('9A'1R -M86-T7W)E9F5R96YC95]F:6QE*&YA;64I.PHF;F)S<#L@)FYB'1?:&5A9&5R*&$L("9A;7`[864I*3L* -M)FYB5]P871H -M;F%M92AA92DI.SPO4%)%/CQ0/@I4:&4@/%14($-,05-3/2)W97-T97)N(CYA -M2!D969A=6QT+`IT:&5Y(')E<&]R="!T:&4@9F%I;'5R -M92!A;F0@EGL/0!0`O*TOS@`````````````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_rar_multivolume_single_file.part2.rar.uu b/thirdparty/libarchive/libarchive/test/test_rar_multivolume_single_file.part2.rar.uu deleted file mode 100644 index e00e06cb2..000000000 --- a/thirdparty/libarchive/libarchive/test/test_rar_multivolume_single_file.part2.rar.uu +++ /dev/null @@ -1,159 +0,0 @@ -begin 644 - -M4F%R(1H'`!EZ2!P2!S:6UP;&EF:65S(&1I86=N;W-I;F<*9F%I -M;'5R97,N(`H\+U`^"CQ(,2!#3$%34STB=V5S=&5R;B(^/$$@3D%-13TB3&EF -M95]C>6-L95]O9E]A7W1E"UL:6ME('!L871F;W)M -M2!T;PIA9&0@;F5W('1E2X@*$EF(#Q45"!#3$%34STB=V5S=&5R;B(^+6L\ -M+U14/@H):7,@6]U+B`*"3PO4#X*"3Q, -M23X\4#Y4:&4@8W5R6]U(&-A;B!U6UL:6YK/"]45#XL"@D\5%0@0TQ!4U,](G=E3PO5%0^+`H)/%14($-, -M05-3/2)W97-T97)N(CYA&%M<&QE+"!I9B!Y;W4@;F5E9"!A -M(')E9F5R96YC92!T87(@87)C:&EV92!T;R!U2X@"CPO4#X*/%`^3&]O:R!A="`\5%0@0TQ!4U,](G=E&%M<&QE(&]F('1H:7,@=7-A9V4N(`H\+U`^"CQ0/D$@9F5W(&]F -M('1H92!O;&1E'!E6]U)W9E(&9O=6YD(&$@8G5G+"!W92!R96-O;6UE;F0@=W)I=&EN9R!T -M:&4@=&5S="!F:7)S="P@;6%K92!S=7)E"@ET:&4@=&5S="!F86EL6]U2!R=6X*"6%L;"!O9B!T:&4@=&5S=',N(`H)/"]0/@H)/$Q)/CQ0(%-4 -M64Q%/2)M87)G:6XM8F]T=&]M.B`P:6XB/D1/3B=4(')E;'D@;VX@/%14($-, -M05-3/2)W97-T97)N(CY(059%7SPO5%0^"@EM86-R;W,@9G)O;2!C;VYF:60H)97AE -M6]U('-E92!A -M('1E6]U(&AA=F4@<75E2!R96%D(&$@<')E+6)U:6QT"FEN -M<'5T(&9I;&4@86YD('9E2!T:&4@2!S=')A:6=H=&9O0IA;F0@=&AE -M;B!O<&5N('1H92!M96UO71E&%C="!D871A(&-O;G1A:6YS -M('9A;'5E2!V97)I9GEI;F<@9FEL97,@;VX@9&ES:RX@5&\@;6%K92!T -M:&ES(&5A0IA=F%I;&%B;&4N(`H\+U`^"CQ(,B!#3$%34STB -M=V5S=&5R;B(^/$$@3D%-13TB1G5Z>E]T97-T97(B/CPO03Y&=7IZ('1E0IU2!D86UA9V5D -M+B`H4F5M96UB97(@=&AA="!L:6)AB!T97-T97(@:6YS=&5A9"!G96YE2UD86UA9V5D(&9I;&4L('-A=F5S('1H870@9FEL92!T -M;R!D:7-K+"!T:&5N(')U;G,@=&AE(&9I;&4*=&AR;W5G:"!L:6)A2!T;R!PB!T97-T97(@:&%S('!R;W9E;B!Q=6ET92!U0IL87)G92!E;G1R:65S+"!U<"!T;R`Q('1E71E+B!/9B!C -M;W5R71E"F5N=')Y('1O(&%N('5N8V]M -M<')EFEP,@IC;VUP65R('1H870@:6UP;&5M -M96YT2!L87)G -M92!E;G1R:65S('1H2!H86YD -M;&5S(&%L;"!O9B!T:&4@8F]U;F1AF5R;RUC;W!Y+B!7:&5N('EO -M=2!G:79E(&ET(&$@;&%R9V4*8FQO8VL@=&\@=W)I=&4@=&\@86X@96YT2P@:70@=VEL;"!P87-S('!O:6YT97)S('-T&-E<'0@:6X@=&AO2!D971E8W0@=VAE;B!A(&)L;V-K(&)E:6YG('=R -M:71T96X@;W5T(&)Y"G1H92!A2!B;V1Y+"!A;F0@F5S('=H:6-H('1R861E -M(&]F9@IP;W)T86)I;&ET>2!V97)S=7,@5>PY`%`"G$@X2`@`````````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_rar_multivolume_uncompressed_files.part01.rar.uu b/thirdparty/libarchive/libarchive/test/test_rar_multivolume_uncompressed_files.part01.rar.uu deleted file mode 100644 index 876b7e9ac..000000000 --- a/thirdparty/libarchive/libarchive/test/test_rar_multivolume_uncompressed_files.part01.rar.uu +++ /dev/null @@ -1,299 +0,0 @@ -begin 644 - -M4F%R(1H'`%INR!M87)G:6XZ(#`N-SEI;B!]"@D)4"![(&UAR!M87)G:6XM8F]T=&]M.B`P+C`X:6X@?0H) -M"4@Q+G=ER!F;VYT+69A;6EL>3H@(DQI8F5R871I;VX@4V5R:68B -M+"!S97)I9B!]"@D)2#$N8VIK('L@9F]N="UF86UI;'DZ(")":71S=')E86T@ -M5F5R82!386YS(B!]"@D)2#$N8W1L('L@9F]N="UF86UI;'DZ(")&R!F;VYT+69A;6EL>3H@(D)I='-TR!F;VYT+69A;6EL>3H@(D9R965386YS(B!]"@D) -M5%0N8VIK('L@9F]N="UF86UI;'DZ(")":71S=')E86T@5F5R82!386YS(BP@ -M;6]N;W-P86-E('T*"2TM/@H)/"]35%E,13X*/"](14%$/@H\0D]$62!,04Y' -M/2)E;BU54R(@1$E2/2),5%(B/@H\2#$@0TQ!4U,](G=E2X@"CPO4#X*/%`^06YY('-I9VYI -M9FEC86YT(&-H86YG92!T;R!L:6)A2!N97<@=&5S=',@ -M;W(@8VAA;F=E&ES=&EN9R!T97-T0H):&]L -M9&EN9R!T:&4@)G%U;W0[6]U)VQL(&YE960@=&\@2!T:&4*/%14($-,05-3/2)W -M97-T97)N(CXM2!S:&]U;&0@8F4@=7-A8FQE(&9O2!T:&%T('=I;&P@8F4@=7-E9`H)9F]R('-C2!F&5C -M=71A8FQE(&)E:6YG(&5X97)C:7-E9"X@"@D\+U`^"@D\3$D^/%`^0F%S:6,@ -M=F5R2(^/"]!/D)A2!T:&%T(&EL;&5G86P@&-E2!W:71H('9A'1R86-T7W)E9F5R96YC95]F:6QE*&YA;64I.PHF;F)S<#L@)FYB -M'1?:&5A9&5R*&$L("9A -M;7`[864I*3L*)FYB5]P871H;F%M92AA92DI.SPO4%)%/CQ0/@I4:&4@/%14($-,05-3/2)W -M97-T97)N(CYA2!D969A=6QT+`IT:&5Y(')E<&]R="!T -M:&4@9F%I;'5R92!A;F0@2!O9@IS<&5C:69I -M8R!T97-T2!E87-Y('1O"F%D9"!N97<@=&5S=',N*2`*/"]0 -M/@H\4#Y4:&4@=&5S="!H87)N97-S(&1E=&5R;6EN97,@=VAI8V@@=&5S=',@ -M=&\@&-E<'0@9F]R('-T9&EN+"!S=&1O=70L(&%N -M9"!S=&1E2!D:7)E8W1O2!D:7)E8W1O2!A2!I -M0H)=VAE;B!T:&4@=&5S="!S=&%R=',N(`H)/"]0/@H)/$Q)/CQ0 -M(%-464Q%/2)M87)G:6XM8F]T=&]M.B`P:6XB/D%N>2!F:6QE2X@5&AE('1E -M2!D96)U9V=E2!D:69F97)E;G0@ -M<&QA=&9O2!W2!T;R!U'@H*2!F=6YC=&EO;G,@=&AA="!Y;W4@ -M8V%N('5S92X@5&AEF4\+U14/BP@/%14($-,05-3/2)W -M97-T97)N(CYA3PO5%0^+"`\5%0@0TQ!4U,](G=E2!T97-T6]U(&-A;B!R96-O=F5R -M('1H92!R969E2!O9B!C:&%R86-T97)S+B!4:&ES('=A2X@270G6]U)W9E(&9O=6YD(&$@8G5G+"!W92!R96-O;6UE;F0@=W)I -M=&EN9R!T:&4@=&5S="!F:7)S="P@;6%K92!S=7)E"@ET:&4@=&5S="!F86EL -M6]U -M2!O;B`\5%0@0TQ!4U,](G=E2!A9&1I;F<@:G5S="!A(&-O=7!L92!O9B!A&ES=&EN9R!T97-T(&EN&%M<&QE -M'1R86-T7W)E9F5R -M96YC95]F:6QE*"D\+U14/@IT;R!D96-O9&4@82!U=65N8V]D960@:6YP=70@ -M9FEL92P@=&AE;B!O<&5N('1H870@9FEL92!W:71H(&QI8F%R8VAI=F4*86YD -M('9E2!T:&4@0IF965D(&%R8VAI=F4@96YT -M2!A9V%I;B!T;R!R96%D -M('1H92!D871A(&)A8VL@86YD('9E2!T:&%T"FET(&ES('1H92!S86UE -M+B`*/"]0/@H\2#(@0TQ!4U,](G=E2!T:&%T('1H92!A2X*5&AE2!T6EN9R!F:6QE2!T:6UE2!T;PIA=F]I9"!UGH@=&5S=&5R/"](,CX*/%`^5&AE(&9U>GH@=&5S=&5R(&ES(&]N -M92!O9B!T:&4@9F5W('1E2!A -M8F]R=',@=&AE(&5N=&ER92!PGH@9F%I;'5R -M92!C875S97,@82!CFEP(&]R(&)Z:7`R"F-O;7!R97-S:6]N -M('=O;B=T(&AE;'`[(&%L=&AO=6=H('-M86QL97(L('1H92!O=71P=70@:7,@ -MF5R;R!B>71E0IE9F9E8W1I=F4L(&-O;7!R97-S:6YG(&$@F5N(&5N=')I97,@9&]W;B!T;PIJ=7-T(&$@ -M9F5W(&MI;&]B>71E2!T:&%T(&QI8F%R8VAI=F4@ -M8V]R0IC87-EF5R;R!B;&]C:W,@8V%N('1A:V4*<75I=&4@82!W:&EL92P@ -MF%T:6]N.@I,:6)A29Q=6]T.R!Z97)O -M+6-O<'DN(%=H96X@>6]U(&=I=F4@:70@82!L87)G90IB;&]C:R!T;R!W2!B;V1Y+"!I="!W:6QL('!A2!L87)G92!F:6QE('-I>F5S("AT87(@9FEL97,*2D@86YD(&EN=&5G97(@;W9E2D@:6X@82!T97-T('1H870@R!M87)G:6XZ -M(#`N-SEI;B!]"@D)4"![(&UAR!M87)G:6XM8F]T=&]M.B`P+C`X:6X@?0H)"4@Q+G=ER!F;VYT -M+69A;6EL>3H@(DQI8F5R871I;VX@4V5R:68B+"!S97)I9B!]"@D)2#$N8VIK -M('L@9F]N="UF86UI;'DZ(")":71S=')E86T@5F5R82!386YS(B!]"@D)2#$N -M8W1L('L@9F]N="UF86UI;'DZ(")&R!F -M;VYT+69A;6EL>3H@(D)I='-TR!F -M;VYT+69A;6EL>3H@(D9R965386YS(B!]"@D)5%0N8VIK('L@9F]N="UF86UI -M;'DZ(")":71S=')E86T@5F5R82!386YS(BP@;6]N;W-P86-E('T*"2TM/@H) -M/"]35%E,13X*/"](14%$/@H\0D]$62!,04Y'/2)E;BU54R(@1$E2/2),5%(B -M/@H\2#$@0TQ!4U,](G=E2X@"CPO4#X*/%`^06YY('-I9VYI9FEC86YT(&-H86YG92!T;R!L -M:6)A2!N97<@=&5S=',@;W(@8VAA;F=E&ES -M=&EN9R!T97-T0H):&]L9&EN9R!T:&4@)G%U;W0[6]U)VQL(&YE960@ -M=&\@2!T:&4*/%14($-,05-3/2)W97-T97)N(CXM2!S:&]U;&0@8F4@=7-A8FQE -M(&9O2!T:&%T('=I;&P@8F4@ -M=7-E9`H)9F]R('-C2!F&5C=71A8FQE(&)E:6YG(&5X97)C -M:7-E9"X@"@D\+U`^"@D\3$D^/%`^0F%S:6,@=F5R2(^/"]!/D)A2!T:&%T(&EL;&5G86P@&-E2!W:71H('9A'1?:&5A9&5R*&$L("9A;7`[864I*3L*)FYB5]P871H;F%M92AA92DI -M.SPO4%)%/CQ0/@I4:&4@/%14($-,05-3/2)W97-T97)N(CYA2!D969A=6QT+`IT:&5Y(')E<&]R="!T:&4@9F%I;'5R92!A;F0@2!O9@IS<&5C:69I8R!T97-T2!E -M87-Y('1O"F%D9"!N97<@=&5S=',N*2`*/"]0/@H\4#Y4:&4@=&5S="!H87)N -M97-S(&1E=&5R;6EN97,@=VAI8V@@=&5S=',@=&\@&-E<'0@9F]R('-T9&EN+"!S=&1O=70L(&%N9"!S=&1E2!D:7)E8W1O2!D:7)E8W1O2!A2!I0H)=VAE;B!T:&4@ -M=&5S="!S=&%R=',N(`H)/"]0/@H)/$Q)/CQ0(%-464Q%/2)M87)G:6XM8F]T -M=&]M.B`P:6XB/D%N>2!F:6QE2X@5&AE('1E2!D96)U9V=E2!D:69F97)E;G0@<&QA=&9O2!W2!T;R!U'@H*2!F=6YC=&EO;G,@=&AA="!Y;W4@8V%N('5S92X@5&AEF4\+U14/BP@/%14($-,05-3/2)W97-T97)N(CYA3PO5%0^+"`\5%0@0TQ! -M4U,](G=E2!T -M97-T6]U(&-A;B!R96-O=F5R('1H92!R969E2!O9B!C:&%R -M86-T97)S+B!4:&ES('=A2X@270G -M2!L -M:6YE+B`*"3PO4#X*"3Q,23X\4"!35%E,13TB;6%R9VEN+6)O='1O;3H@,&EN -M(CY$3R!U2!I;G-T96%D(&]F('!L -M86EN"@EAF5D(&9O6]U('1H:6YK -M"@EY;W4G=F4@9F]U;F0@82!B=6&EN9R!T:&4@8G5G+B`*"3PO4#X*"3Q,23X\4"!35%E,13TB;6%R9VEN -M+6)O='1O;3H@,&EN(CY$3R!R=6X@86QL(&]F('1H92!T97-T2!T -M;R!S970@86X@04-,(&]N(&$@9FEL92!A;F0*"7)E860@:70@8F%C:R!T;R!D -M971E&ES=&EN9R!T97-T&%M<&QE2!J=7-T('9E2!T:&%T(&QI8F%R8VAI=F4@8V%N"G)E -M860@=VAA="!I="!W2!U2!I;G1E2!A;F0@=&AE;B!I;G-P96-T"G1H92!A8W1U86P@8GET97,@ -M=&\@=F5R:69Y('1H870@=&AE(&%R8VAI=F4@=V%S(&-R96%T960@8V]R2!S:6YC92!T:&4@97AA8W0@9&%T82!C -M;VYT86EN2!C;VYT7-T96T@8V%L -M;',@9F]R(&5A8V@@<&QA=&9OGI?=&5S=&5R(CX\+T$^1G5Z -M>B!T97-T97(\+T@R/@H\4#Y4:&4@9G5Z>B!T97-T97(@:7,@;VYE(&]F('1H -M92!F97<@=&5S=',@=&AA="!D;V5S(&YO="!A9V=R97-S:79E;'D*=7-E(&%S -M2!A;F0@8W)A2!F965D:6YG"FET(&EN<'5T('1H870@:7,@B!F86EL=7)E(&-A=7-E -MGH@=&5S=&5R(&EN7-IGH@=&5S=&5R(&AA2P@=&AE(&YE960@=&\@=W)I=&4@=&AE(&1A=&$@=&\@9&ES:R!B969O&5R8VES92!B;W5N9&%R>2!C -M87-E2!T;R!A -M;B!U;F-O;7!R97-S960@87)C:&EV92!O;B!D:7-K(&]R(&UE;6]R>2!I2!S;6%L;"!H96%D97)S(&%N9"!S=&]R -M92!A(&-O=6YT(&]F(&5A8V@@8V]N=&EG=6]U2!W2X@ -M5VAE;B!Y;W4@9VEV92!I="!A(&QA2!D871A('1O(&-O2!B -M=6EL9"!B;&]C:W,N(%1H92!L87)G92!T87(@=&5S=&5R('1A:V5S"F%D=F%N -M=&%G92!O9B!T:&ES('1O('%U:6-K;'D@9&5T96-T('=H96X@82!B;&]C:R!B -E96EN9R!WG0AD%<`W`(``(].```#8Z8%7KM,-4$4 -M,"T`I($``'1E0IT:&4@87)C:&EV92!W0IT -M:&4@=&5S="!A2P@86YD('-I;6EL87)L>2!W:&5N -M(')E861I;F<@=&AE(&%R8VAI=F4*8F%C:RX@"CPO4#X*/%`^5&%K96X@=&]G -M971H97(L('1H97-E('1R:6-K7,@=&\@70BD$0`83```(].```# -MC+J$FKM,-4$4,!H`I($``$QI8F%R8VAI=F5!9&1I;F=497-T,BYH=&ULP,P) -M7SM",E\[0CPA1$]#5%E012!(5$U,(%!50DQ)0R`B+2\O5S-#+R]$5$0@2%1- -M3"`T+C`@5')A;G-I=&EO;F%L+R]%3B(^"CQ(5$U,/@H\2$5!1#X*"3Q-151! -M($A45%`M15%5258](D-/3E1%3E0M5%E012(@0T].5$5.5#TB=&5X="]H=&UL -M.R!C:&%RR!M87)G:6XM8F]T -M=&]M.B`P+C`X:6X@?0H)"4@Q('L@;6%R9VEN+6)O='1O;3H@,"XP.&EN('T* -M"0E(,2YW97-T97)N('L@9F]N="UF86UI;'DZ("),:6)E2!C -M;VUP;&5X('!I96-E(&]F('-O9G1W87)E('1H870@6EN9R!N97<@<&]R=',@ -M86YD(&9O&5S+`IS:&]U;&0@8F4@86-C;VUP86YI960@8GD@;F5W('1E'!L86EN2!O9B!T:&%T(&-O;7!O -M;F5N="X@5&AE6]U(&YE960@=&\@9VEV92!T:&5M('1W;R!P:65C97,@;V8*:6YF -M;W)M871I;VXZ(`H\+U`^"CQ53#X*"3Q,23X\4"!35%E,13TB;6%R9VEN+6)O -M='1O;3H@,&EN(CY4:&4@9G5L;"!P871H('1O('1H92!D:7)E8W1O&5C=71A8FQE('!R;V=R -M86T@8F5I;F<@=&5S=&5D("AN;W0*"6%P<&QI8V%B;&4@=&\@;&EB87)C:&EV -M95]T97-T('-I;F-E(&QI8F%R8VAI=F4@:7,@8V]M<&EL960@:6YT;R!T:&4* -M"71E'1E;G-I;VXN(%1H92!T97-T('!R;V=R86US(&QO;VL@ -M:6X@82!F97<*3L@=&AE>2!N965D('1H92!F=6QL -M('!A=&@@=&\@=&AE(&%P<')O<')I871E(&5X96-U=&%B;&4N"D%L=&AO=6=H -M(&)S9'1A2!I;G1E;F1E9"!F;W(*=&5S=&EN9R!B2!T;R!V97)I9GD@=&AA="!T:&4@=&5S=`IP2X@"CPO4#X*/%`^5VAE -M;B!R=6XL('1H92!T97-T('!R;V=R86US(&]U='!U="!A('!R;V=R97-S(&UE -M&5R8VES:6YG.B!B0HF;F)S<#L@=&5S=%]C -M;W!Y+F,Z,32YC.C$W,3H@1F%I;&5D(#(V-"!T:6UE2!F -M;W(@9G5R=&AE&5R8VES960N(`H)/"]0/@H)/$Q)/CQ0/D)A&%M<&QE+`IM86YY(&]F('1H92!L:6)AFEP/"]45#XL"G=H:6-H('9E -M2!R97!O&%M<&QE(&%B;W9E*0IG96YE2!P2!S:6UP;&EF -M:65S(&1I86=N;W-I;F<*9F%I;'5R97,N(`H\+U`^"CQ(,2!#3$%34STB=V5S -M=&5R;B(^/$$@3D%-13TB3&EF95]C>6-L95]O9E]A7W1E"UL:6ME('!L871F;W)M2!T;PIA9&0@;F5W('1E2X@*$EF(#Q45"!# -M3$%34STB=V5S=&5R;B(^+6L\+U14/@H):7,@6]U+B`*"3PO4#X*"3Q,23X\4#Y4:&4@8W5R6]U -M(&-A;B!U6UL:6YK/"]45#XL"@D\5%0@0TQ! -M4U,](G=E3PO5%0^+`H)/%14($-,05-3/2)W97-T97)N(CYA&%M -M<&QE+"!I9B!Y;W4@;F5E9"!A(')E9F5R96YC92!T87(@87)C:&EV92!T;R!U -M'1R86-T7W)E9F5R96YC95]F -M:6QE*"D\+U14/B!F=6YC=&EO;B!W:6QL"G5U9&5C;V1E('1H92!R97%U97-T -M960@9FEL92!A;F0@<'5T('1H92!R97-U;'0@:6X@=&AE(&-U2!O9B!C:&%R -M86-T97)S+B!4:&ES('=A2X@270G -M2!L -M:6YE+B`*"3PO4#X*"3Q,23X\4"!35%E,13TB;6%R9VEN+6)O='1O;3H@,&EN -M(CY$3R!U2!I;G-T96%D(&]F('!L -M86EN"@EAF5D(&9O6]U('1H:6YK -M"@EY;W4G=F4@9F]U;F0@82!B=6&EN9R!T:&4@8G5G+B`*"3PO4#X*"3Q,23X\4"!35%E,13TB;6%R9VEN -M+6)O='1O;3H@,&EN(CY$3R!R=6X@86QL(&]F('1H92!T97-T2!T -M;R!S970@86X@04-,(&]N(&$@9FEL92!A;F0*"7)E860@:70@8F%C:R!T;R!D -M971E&ES=&EN9R!T97-T&%M<&QE2!J=7-T('9E2!T:&%T(&QI8F%R8VAI=F4@8V%N"G)E -M860@=VAA="!I="!W2!U2!I;G1E2!A;F0@=&AE;B!I;G-P96-T"G1H92!A8W1U86P@8GET97,@ -M=&\@=F5R:69Y('1H870@=&AE(&%R8VAI=F4@=V%S(&-R96%T960@8V]R2!S:6YC92!T:&4@97AA8W0@9&%T82!C -M;VYT86EN2!C;VYT7-T96T@8V%L -M;',@9F]R(&5A8V@@<&QA=&9OGI?=&5S=&5R(CX\+T$^1G5Z -M>B!T97-T97(\+T@R/@H\4#Y4:&4@9G5Z>B!T97-T97(@:7,@;VYE(&]F('1H -M92!F97<@=&5S=',@=&AA="!D;V5S(&YO="!A9V=R97-S:79E;'D*=7-E(&%S -M2!A;F0@8W)A2!F965D:6YG"FET(&EN<'5T('1H870@:7,@B!F86EL=7)E(&-A=7-E -MGH@=&5S=&5R(&EN7-IGH@=&5S=&5R(&AA2P@=&AE(&YE960@=&\@=W)I=&4@=&AE(&1A=&$@=&\@9&ES:R!B969O&5R8VES92!B;W5N9&%R>2!C -M87-E2!T;R!A -M;B!U;F-O;7!R97-S960@87)C:&EV92!O;B!D:7-K(&]R(&UE;6]R>2!I2!S;6%L;"!H96%D97)S(&%N9"!S=&]R -M92!A(&-O=6YT(&]F(&5A8V@@8V]N=&EG=6]U2!W2X@ -M5VAE;B!Y;W4@9VEV92!I="!A(&QA2!D871A('1O(&-O2!B -M=6EL9"!B;&]C:W,N(%1H92!L87)G92!T87(@=&5S=&5R('1A:V5S"F%D=F%N -M=&%G92!O9B!T:&ES('1O('%U:6-K;'D@9&5T96-T('=H96X@82!B;&]C:R!B -M96EN9R!W0IT:&4@87)C:&EV92!W0IT -M:&4@=&5S="!A2P@86YD('-I;6EL87)L>2!W:&5N -M(')E861I;F<@=&AE(&%R8VAI=F4*8F%C:RX@"CPO4#X*/%`^5&%K96X@=&]G -M971H97(L('1H97-E('1R:6-K7,@=&\@'0O:'1M;#L@8VAA"DB/@H)/$U%5$$@3D%-13TB0U)%051%1"(@0T].5$5.5#TB,C`Q -M,3`V,C8[,C(R,S4Q,#`B/@H)/$U%5$$@3D%-13TB0TA!3D=%1"(@0T].5$5. -M5#TB,C`Q,3`V,C8[,C(R-30U,#`B/@H)/%-464Q%(%194$4](G1E>'0O8W-S -M(CX*"3PA+2T*"0E`<&%G92![(&UAR!F;VYT+69A;6EL>3H@(D)I -M='-TR!F;VYT+69A;6EL>3H@ -M(D9R965386YS(B!]"@D)4%)%+F-J:R![(&9O;G0M9F%M:6QY.B`B0FETR!M87)G:6XM8F]T -M=&]M.B`P+C`X:6X@?0H)"4@R+F-T;"![(&9O;G0M9F%M:6QY.B`B1G)E95-A -M;G,B('T*"0E45"YC:FL@>R!F;VYT+69A;6EL>3H@(D)I='-T"!P:65C92!O9B!S;V9T=V%R92!T:&%T(')U;G,@;VX* -M82!N=6UB97(@;V8@9&EF9F5R96YT('!L871F;W)M'1E;F0@=&AE;2X@"CPO4#X*/$@Q($-,05-3 -M/2)W97-T97)N(CX\02!.04U%/2)"=6EL9&EN9U]A;F1?4G5N;FEN9U]T:&5? -M5&5S=%]0&5R8VES97,@=&AE(&9U;F-T:6]N86QI='D@;V8@=&AA -M="!C;VUP;VYE;G0N(%1H97-E"G1E2!T:&%T('1H92!R97-T(&]F('1H90IL:6)A2!A2X@"CPO4#X* -M/%`^5&AE(&)S9'1A&5C=71A8FQE+@I! -M;'1H;W5G:"!B3H@"CPO4#X*/%!212!#3$%34STB=V5S=&5R;B(^)FYB2YC.C$W,3H@07-S97)T:6]N(&9A:6QE9#H@26YT6]U"F-A;B!S964L -M('1H97)E('=AF5R;R!T -M:&%T('=A'!E8W1E9"X@"CPO4#X*/$@Q($-,05-3/2)W97-T97)N(CX\ -M02!.04U%/2)"87-I8U]T97-T7W1E3PO2#$^"CQ0/D5A8V@@=&5S="!P2!P97)F;W)M:6YG('-O;64@2!O9B!T:&4@;&EB87)C:&EV92!T -M97-TFEP*0HF;F)S<#L@>PHF -E;F)S<#L@)FYB2!C97)T86EN(&-O;F1I=&EO;G,N($EF('1H92!A -M&%M<&QE+"!I9B!T:&4@;F%M92!O9B!T -M:&4@9FER&ET(&]N(&9A:6QUF5R;R`H=&AE($,@;F]T:6]N(&]F("9Q=6]T -M.V9A;'-E)G%U;W0[*2X*4V5C;VYD+"!T:&5S92!M86-R;W,@:6YC;'5D92!V -M87)I86YT6-L -M92!O9@IA('1E0IA;F0@87,@82!L86)E;"!T:&%T(&-A;B!B -M92!U2X@ -M"@D\+U`^"@D\3$D^/%`@4U193$4](FUA2!D:7)E8W1O2!A2!O<&5N -M(&9I;&4@9&5S8W)I<'1O2!W:6QL(&)E(')E;6]V960@9F]R('EO -M=2X@"@D\+U`^"@D\3$D^/%`^5&AE(&-U2X@"@D\+U`^"@D\3$D^/%`@4U193$4](FUAPHC:68@7U]03$%41D]230HF;F)S<#L@)FYB"@I(&9U;F-T:6]N2!I;F-O;7!L971E(&QI'1&:6QE0V]N -M=&5N=',\+U14/B`*"3PO4#X*/"]53#X*/$@Q($-,05-3/2)W97-T97)N(CX\ -M02!.04U%/2)2969E6]U(&YE960@82!R969E'1R86-T7W)E9F5R96YC95]F:6QE*"9Q=6]T.W1E"UE;F-O9&5D -M(&%R'1R86-T7W)E9F5R96YC95]F:6QE*"D\ -M+U14/B!W87,@861D960@86YD(&ES"FYO="!R96-O;6UE;F1E9"!F;W(@;F5W -M(&-O9&4N(`H\+U`^"CQ(,2!#3$%34STB=V5S=&5R;B(^/$$@3D%-13TB1&]S -M7V%N9%]$;VYT6]U0H)8VAA;F=I;F<@ -M82!P:65C92!O9B!C;V1E(&%N9"!M86ME('-U6]U2!R=6X*"6%L;"!O9B!T:&4@=&5S -M=',N(`H)/"]0/@H)/$Q)/CQ0(%-464Q%/2)M87)G:6XM8F]T=&]M.B`P:6XB -M/D1/3B=4(')E;'D@;VX@/%14($-,05-3/2)W97-T97)N(CY(059%7SPO5%0^ -M"@EM86-R;W,@9G)O;2!C;VYF:60H)97AE6]U('-E92!A('1E6]U(&AA=F4@<75E2!R96%D(&$@<')E+6)U:6QT"FEN<'5T(&9I;&4@86YD('9E2!T:&4@ -M2!S=')A:6=H=&9O0IA;F0@=&AE;B!O<&5N('1H92!M96UO&%C="!D871A(&-O;G1A:6YS('9A;'5E2!V97)I9GEI;F<@9FEL -M97,@;VX@9&ES:RX@5&\@;6%K92!T:&ES(&5A0IA=F%I;&%B -M;&4N(`H\+U`^"CQ(,B!#3$%34STB=V5S=&5R;B(^/$$@3D%-13TB1G5Z>E]T -M97-T97(B/CPO03Y&=7IZ('1E0IUB!T -M97-T97(@:6YS=&5A9"!G96YE2UD86UA9V5D(&9I -M;&4L('-A=F5S('1H870@9FEL92!T;R!D:7-K+"!T:&5N(')U;G,@=&AE(&9I -M;&4*=&AR;W5G:"!L:6)A2!T;R!PB!T97-T97(@:&%S('!R;W9E;B!Q -M=6ET92!U0IL87)G92!E;G1R:65S+"!U -M<"!T;R`Q('1E71E+B!/9B!C;W5R71E"F5N=')Y('1O(&%N('5N8V]M<')EFEP,@IC;VUP -M65R('1H -M870@:6UP;&5M96YT2!L87)G92!E;G1R:65S('1H2!H86YD;&5S(&%L;"!O9B!T:&4@8F]U;F1AF5R;RUC;W!Y -M+B!7:&5N('EO=2!G:79E(&ET(&$@;&%R9V4*8FQO8VL@=&\@=W)I=&4@=&\@ -M86X@96YT2P@:70@=VEL;"!P87-S('!O:6YT97)S('-T&-E<'0@:6X@=&AO -M2!D971E8W0@=VAE;B!A(&)L;V-K -M(&)E:6YG('=R:71T96X@;W5T(&)Y"G1H92!A2!B;V1Y+"!A;F0@F5S('=H -M:6-H('1R861E(&]F9@IP;W)T86)I;&ET>2!V97)S=7,@R!M87)G:6XZ(#`N-SEI -M;B!]"@D)4"![(&UAR!M87)G -M:6XM8F]T=&]M.B`P+C`X:6X@?0H)"4@Q+G=ER!F;VYT+69A;6EL -M>3H@(DQI8F5R871I;VX@4V5R:68B+"!S97)I9B!]"@D)2#$N8VIK('L@9F]N -M="UF86UI;'DZ(")":71S=')E86T@5F5R82!386YS(B!]"@D)2#$N8W1L('L@ -M9F]N="UF86UI;'DZ(")&R!F;VYT+69A -M;6EL>3H@(D)I='-TR!F;VYT+69A -M;6EL>3H@(D9R965386YS(B!]"@D)5%0N8VIK('L@9F]N="UF86UI;'DZ(")" -M:71S=')E86T@5F5R82!386YS(BP@;6]N;W-P86-E('T*"2TM/@H)/"]35%E, -M13X*/"](14%$/@H\0D]$62!,04Y'/2)E;BU54R(@1$E2/2),5%(B/@H\2#$@ -M0TQ!4U,](G=E2X@"CPO4#X*/%`^06YY('-I9VYI9FEC86YT(&-H86YG92!T;R!L:6)A2!N97<@=&5S=',@;W(@8VAA;F=E&ES=&EN9R!T -M97-T0H):&]L9&EN9R!T:&4@)G%U;W0[6]U)VQL(&YE960@=&\@2!T:&4*/%14($-,05-3/2)W97-T97)N(CXM2!S:&]U;&0@8F4@=7-A8FQE(&9O2!T:&%T('=I;&P@8F4@=7-E9`H) -M9F]R('-C2!F&5C=71A8FQE(&)E:6YG(&5X97)C:7-E9"X@ -M"@D\+U`^"@D\3$D^/%`^0F%S:6,@=F5R2(^ -M/"]!/D)A2!T:&%T(&EL;&5G86P@&-E2!W:71H -M('9A'1R86-T7W)E9F5R96YC95]F -M:6QE*&YA;64I.PHF;F)S<#L@)FYB'1?:&5A9&5R*&$L("9A;7`[864I*3L*)FYB5]P871H;F%M92AA92DI.SPO4%)% -M/CQ0/@I4:&4@/%14($-,05-3/2)W97-T97)N(CYA2!D -M969A=6QT+`IT:&5Y(')E<&]R="!T:&4@9F%I;'5R92!A;F0@2!O9@IS<&5C:69I8R!T97-T2!E87-Y('1O -M"F%D9"!N97<@=&5S=',N*2`*/"]0/@H\4#Y4:&4@=&5S="!H87)N97-S(&1E -M=&5R;6EN97,@=VAI8V@@=&5S=',@=&\@&-E<'0@ -M9F]R('-T9&EN+"!S=&1O=70L(&%N9"!S=&1E2!D:7)E8W1O2!D:7)E8W1O2!A2!I0H)=VAE;B!T:&4@=&5S="!S -M=&%R=',N(`H)/"]0/@H)/$Q)/CQ0(%-464Q%/2)M87)G:6XM8F]T=&]M.B`P -M:6XB/D%N>2!F:6QE2X@5&AE('1E2!D96)U9V=E2!D:69F97)E;G0@<&QA=&9O2!W2!T;R!U'@H -M*2!F=6YC=&EO;G,@=&AA="!Y;W4@8V%N('5S92X@5&AEF4\+U14/BP@/%14($-,05-3/2)W97-T97)N(CYA3PO5%0^+"`\5%0@0TQ!4U,](G=E -E'1&:6QE0V]N=&5N=',\+U14/B`*"3PO4#X*/"]5 -M3#X*/$@Q($-,05-3/2)W97-T97)N(CX\02!.04U%/2)2969E6]U(&YE960@82!R969E'1R86-T7W)E9F5R96YC95]F -M:6QE*"9Q=6]T.W1E"UE;F-O9&5D(&%R'1R86-T7W)E9F5R96YC95]F:6QE*"D\+U14/B!W87,@861D960@86YD(&ES -M"FYO="!R96-O;6UE;F1E9"!F;W(@;F5W(&-O9&4N(`H\+U`^"CQ(,2!#3$%3 -M4STB=V5S=&5R;B(^/$$@3D%-13TB1&]S7V%N9%]$;VYT6]U6]U2!R=6X*"6%L;"!O9B!T:&4@=&5S=',N(`H)/"]0/@H)/$Q)/CQ0(%-4 -M64Q%/2)M87)G:6XM8F]T=&]M.B`P:6XB/D1/3B=4(')E;'D@;VX@/%14($-, -M05-3/2)W97-T97)N(CY(059%7SPO5%0^"@EM86-R;W,@9G)O;2!C;VYF:60H)97AE -M6]U('-E92!A -M('1E6]U(&AA=F4@<75E2!R96%D(&$@<')E+6)U:6QT"FEN -M<'5T(&9I;&4@86YD('9E2!T:&4@2!S=')A:6=H=&9O0IA;F0@=&AE -M;B!O<&5N('1H92!M96UO71E&%C="!D871A(&-O;G1A:6YS -M('9A;'5E2!V97)I9GEI;F<@9FEL97,@;VX@9&ES:RX@5&\@;6%K92!T -M:&ES(&5A0IA=F%I;&%B;&4N(`H\+U`^"CQ(,B!#3$%34STB -M=V5S=&5R;B(^/$$@3D%-13TB1G5Z>E]T97-T97(B/CPO03Y&=7IZ('1E0IU2!D86UA9V5D -M+B`H4F5M96UB97(@=&AA="!L:6)AB!T97-T97(@:6YS=&5A9"!G96YE2UD86UA9V5D(&9I;&4L('-A=F5S('1H870@9FEL92!T -M;R!D:7-K+"!T:&5N(')U;G,@=&AE(&9I;&4*=&AR;W5G:"!L:6)A2!T;R!PB!T97-T97(@:&%S('!R;W9E;B!Q=6ET92!U0IL87)G92!E;G1R:65S+"!U<"!T;R`Q('1E71E+B!/9B!C -M;W5R71E"F5N=')Y('1O(&%N('5N8V]M -M<')EFEP,@IC;VUP65R('1H870@:6UP;&5M -M96YT2!L87)G -M92!E;G1R:65S('1H2!H86YD -M;&5S(&%L;"!O9B!T:&4@8F]U;F1AF5R;RUC;W!Y+B!7:&5N('EO -M=2!G:79E(&ET(&$@;&%R9V4*8FQO8VL@=&\@=W)I=&4@=&\@86X@96YT2P@:70@=VEL;"!P87-S('!O:6YT97)S('-T&-E<'0@:6X@=&AO2!D971E8W0@=VAE;B!A(&)L;V-K(&)E:6YG('=R -M:71T96X@;W5T(&)Y"G1H92!A2!B;V1Y+"!A;F0@F5S('=H:6-H('1R861E -M(&]F9@IP;W)T86)I;&ET>2!V97)S=7,@'0O:'1M;#L@8VAA"DB/@H)/$U% -M5$$@3D%-13TB0U)%051%1"(@0T].5$5.5#TB,C`Q,3`V,C8[,C(R,S4Q,#`B -M/@H)/$U%5$$@3D%-13TB0TA!3D=%1"(@0T].5$5.5#TB,C`Q,3`V,C8[,C(R -M-30U,#`B/@H)/%-464Q%(%194$4](G1E>'0O8W-S(CX*"3PA+2T*"0E`<&%G -M92![(&UAR!F;VYT+69A;6EL>3H@(D)I='-TR!F;VYT+69A;6EL>3H@(D9R965386YS(B!]"@D) -M4%)%+F-J:R![(&9O;G0M9F%M:6QY.B`B0FETR!M87)G:6XM8F]T=&]M.B`P+C`X:6X@?0H) -M"4@R+F-T;"![(&9O;G0M9F%M:6QY.B`B1G)E95-A;G,B('T*"0E45"YC:FL@ -M>R!F;VYT+69A;6EL>3H@(D)I='-T"!P -M:65C92!O9B!S;V9T=V%R92!T:&%T(')U;G,@;VX*82!N=6UB97(@;V8@9&EF -M9F5R96YT('!L871F;W)M&ES -M=&EN9R!F=6YC=&EO;F%L:71Y+B`*/"]0/@H\4#Y!;GD@'1E;F0@=&AE;2X@"CPO4#X*/$@Q($-,05-3/2)W97-T97)N(CX\02!. -M04U%/2)"=6EL9&EN9U]A;F1?4G5N;FEN9U]T:&5?5&5S=%]0&5R -M8VES97,@=&AE(&9U;F-T:6]N86QI='D@;V8@=&AA="!C;VUP;VYE;G0N(%1H -M97-E"G1E2!T:&%T('1H92!R97-T(&]F('1H90IL:6)A2!A2X@"CPO4#X*/%`^5&AE(&)S9'1A&5C=71A8FQE+@I!;'1H;W5G:"!B3H@"CPO4#X*/%!212!# -M3$%34STB=V5S=&5R;B(^)FYB2YC.C$W -M,3H@07-S97)T:6]N(&9A:6QE9#H@26YT6]U"F-A;B!S964L('1H97)E('=AF5R;R!T:&%T('=A'!E8W1E -E9"X@"CPO4#X*/$@Q($-,05.HQWL/0!0`.^^E?`<````````````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_rar_multivolume_uncompressed_files.part09.rar.uu b/thirdparty/libarchive/libarchive/test/test_rar_multivolume_uncompressed_files.part09.rar.uu deleted file mode 100644 index bdcdc999c..000000000 --- a/thirdparty/libarchive/libarchive/test/test_rar_multivolume_uncompressed_files.part09.rar.uu +++ /dev/null @@ -1,299 +0,0 @@ -begin 644 - -M4F%R(1H'`!EZ2(^/"]! -M/D)A2!T:&%T(&EL;&5G86P@&-E2!W:71H('9A -M'1R86-T7W)E9F5R96YC95]F:6QE -M*&YA;64I.PHF;F)S<#L@)FYB'1?:&5A9&5R*&$L("9A;7`[864I*3L*)FYB5]P871H;F%M92AA92DI.SPO4%)%/CQ0 -M/@I4:&4@/%14($-,05-3/2)W97-T97)N(CYA2!D969A -M=6QT+`IT:&5Y(')E<&]R="!T:&4@9F%I;'5R92!A;F0@2!O9@IS<&5C:69I8R!T97-T2!E87-Y('1O"F%D -M9"!N97<@=&5S=',N*2`*/"]0/@H\4#Y4:&4@=&5S="!H87)N97-S(&1E=&5R -M;6EN97,@=VAI8V@@=&5S=',@=&\@&-E<'0@9F]R -M('-T9&EN+"!S=&1O=70L(&%N9"!S=&1E2!D:7)E8W1O2!D:7)E8W1O2!A2!I0H)=VAE;B!T:&4@=&5S="!S=&%R -M=',N(`H)/"]0/@H)/$Q)/CQ0(%-464Q%/2)M87)G:6XM8F]T=&]M.B`P:6XB -M/D%N>2!F:6QE2X@5&AE('1E2!D96)U9V=E2!D:69F97)E;G0@<&QA=&9O2!W2!T;R!U'@H*2!F -M=6YC=&EO;G,@=&AA="!Y;W4@8V%N('5S92X@5&AEF4\ -M+U14/BP@/%14($-,05-3/2)W97-T97)N(CYA3PO5%0^+"`\5%0@0TQ!4U,](G=E2!T97-T6]U(&-A;B!R96-O=F5R('1H92!R969E2!O9B!C:&%R86-T97)S+B!4 -M:&ES('=A2X@270G2!L:6YE+B`*"3PO -M4#X*"3Q,23X\4"!35%E,13TB;6%R9VEN+6)O='1O;3H@,&EN(CY$3R!U2!I;G-T96%D(&]F('!L86EN"@EAF5D(&9O6]U('1H:6YK"@EY;W4G=F4@ -M9F]U;F0@82!B=6&EN9R!T -M:&4@8G5G+B`*"3PO4#X*"3Q,23X\4"!35%E,13TB;6%R9VEN+6)O='1O;3H@ -M,&EN(CY$3R!R=6X@86QL(&]F('1H92!T97-T&%M<&QE+"!T:&4@04-,('1E2!T;R!S970@86X@ -M04-,(&]N(&$@9FEL92!A;F0*"7)E860@:70@8F%C:R!T;R!D971E&ES -M=&EN9R!T97-T&ES=&EN9R!T97-T&%M<&QE2!J=7-T('9E2!T:&%T(&QI8F%R8VAI=F4@8V%N"G)E860@=VAA="!I -M="!W2!U2!I;G1E -M2!A;F0@=&AE;B!I;G-P96-T"G1H92!A8W1U86P@8GET97,@=&\@=F5R:69Y -M('1H870@=&AE(&%R8VAI=F4@=V%S(&-R96%T960@8V]R2!S:6YC92!T:&4@97AA8W0@9&%T82!C;VYT86EN2!C;VYT7-T96T@8V%L;',@9F]R(&5A -M8V@@<&QA=&9OGI?=&5S=&5R(CX\+T$^1G5Z>B!T97-T97(\ -M+T@R/@H\4#Y4:&4@9G5Z>B!T97-T97(@:7,@;VYE(&]F('1H92!F97<@=&5S -M=',@=&AA="!D;V5S(&YO="!A9V=R97-S:79E;'D*=7-E(&%S2!A;F0@8W)A2!F965D:6YG"FET(&EN<'5T('1H870@:7,@B!F86EL=7)E(&-A=7-E7-IGH@=&5S=&5R(&AA2P@=&AE(&YE -M960@=&\@=W)I=&4@=&AE(&1A=&$@=&\@9&ES:R!B969OFEP(&]R(&)Z:7`R"F-O -M;7!R97-S:6]N('=O;B=T(&AE;'`[(&%L=&AO=6=H('-M86QL97(L('1H92!O -M=71P=70@:7,@F5R;R!B -M>71E0IE9F9E8W1I=F4L(&-O;7!R97-S:6YG -M(&$@F5N(&5N=')I97,@9&]W;B!T -M;PIJ=7-T(&$@9F5W(&MI;&]B>71E2!T:&%T(&QI -M8F%R8VAI=F4@8V]R0IC87-EF%T:6]N.@I,:6)A29Q -M=6]T.R!Z97)O+6-O<'DN(%=H96X@>6]U(&=I=F4@:70@82!L87)G90IB;&]C -M:R!T;R!W2!B;V1Y+"!I="!W:6QL('!A2!L87)G92!F:6QE('-I>F5S("AT87(@ -M9FEL97,*2D@86YD(&EN=&5G97(@ -M;W9E2D@:6X@82!T97-T('1H -M870@6UL:6YK-<#,;5\[0G%?.T)T97-T6UL:6YK@`A-7SM"35\[0G1E6UL:6YK,\`(6U\[0EM?.T)T97-T9&ER+W1EPY`%`"RV@*;"0`` -&```````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_data_large.c b/thirdparty/libarchive/libarchive/test/test_read_data_large.c deleted file mode 100644 index a86bcc08f..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_data_large.c +++ /dev/null @@ -1,111 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_data_large.c 201247 2009-12-30 05:59:21Z kientzle $"); - -/* - * Test read/write of a 10M block of data in a single operation. - * Uses an in-memory archive with a single 10M entry. Exercises - * archive_read_data() to ensure it can handle large blocks like - * this and also exercises archive_read_data_into_fd() (which - * had a bug relating to this, fixed in Nov 2006). - */ - -#if defined(_WIN32) && !defined(__CYGWIN__) -#define open _open -#define close _close -#endif - -static char buff1[11000000]; -static char buff2[10000000]; -static char buff3[10000000]; - -DEFINE_TEST(test_read_data_large) -{ - struct archive_entry *ae; - struct archive *a; - char tmpfilename[] = "largefile"; - int tmpfilefd; - FILE *f; - size_t used; - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertA(0 == archive_write_set_format_ustar(a)); - assertA(0 == archive_write_add_filter_none(a)); - assertA(0 == archive_write_open_memory(a, buff1, sizeof(buff1), &used)); - - /* - * Write a file (with random contents) to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file"); - archive_entry_set_mode(ae, S_IFREG | 0755); - fill_with_pseudorandom_data(buff2, sizeof(buff2)); - archive_entry_set_size(ae, sizeof(buff2)); - assertA(0 == archive_write_header(a, ae)); - archive_entry_free(ae); - assertA((int)sizeof(buff2) == archive_write_data(a, buff2, sizeof(buff2))); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Check that archive_read_data can handle 10*10^6 at a pop. */ - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_open_memory(a, buff1, sizeof(buff1))); - assertA(0 == archive_read_next_header(a, &ae)); - failure("Wrote 10MB, but didn't read the same amount"); - assertEqualIntA(a, sizeof(buff2),archive_read_data(a, buff3, sizeof(buff3))); - failure("Read expected 10MB, but data read didn't match what was written"); - assertEqualMem(buff2, buff3, sizeof(buff3)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* Check archive_read_data_into_fd */ - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_open_memory(a, buff1, sizeof(buff1))); - assertA(0 == archive_read_next_header(a, &ae)); -#if defined(__BORLANDC__) - tmpfilefd = open(tmpfilename, O_WRONLY | O_CREAT | O_BINARY); -#else - tmpfilefd = open(tmpfilename, O_WRONLY | O_CREAT | O_BINARY, 0777); -#endif - assert(tmpfilefd != 0); - assertEqualIntA(a, 0, archive_read_data_into_fd(a, tmpfilefd)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - close(tmpfilefd); - - f = fopen(tmpfilename, "rb"); - assert(f != NULL); - assertEqualInt(sizeof(buff3), fread(buff3, 1, sizeof(buff3), f)); - fclose(f); - assertEqualMem(buff2, buff3, sizeof(buff3)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_disk.c b/thirdparty/libarchive/libarchive/test/test_read_disk.c deleted file mode 100644 index 43d7d86ba..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_disk.c +++ /dev/null @@ -1,175 +0,0 @@ -/*- - * Copyright (c) 2003-2009 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_disk.c 201247 2009-12-30 05:59:21Z kientzle $"); - -static void -gname_cleanup(void *d) -{ - int *mp = d; - assertEqualInt(*mp, 0x13579); - *mp = 0x2468; -} - -static const char * -gname_lookup(void *d, int64_t g) -{ - int *mp = d; - assertEqualInt(*mp, 0x13579); - if (g == 1) - return ("FOOGROUP"); - return ("NOTFOOGROUP"); -} - -static void -uname_cleanup(void *d) -{ - int *mp = d; - assertEqualInt(*mp, 0x1234); - *mp = 0x2345; -} - -static const char * -uname_lookup(void *d, int64_t u) -{ - int *mp = d; - assertEqualInt(*mp, 0x1234); - if (u == 1) - return ("FOO"); - return ("NOTFOO"); -} - -#if !defined(__CYGWIN__) && !defined(__HAIKU__) -/* We test GID lookup by looking up the name of group number zero and - * checking it against the following list. If your system uses a - * different conventional name for group number zero, please extend - * this array and send us a patch. As always, please keep this list - * sorted alphabetically. - */ -static const char *zero_groups[] = { - "root", /* Linux */ - "wheel" /* BSD */ -}; -#endif - -DEFINE_TEST(test_read_disk) -{ - struct archive *a; - int gmagic = 0x13579, umagic = 0x1234; -#if !defined(__CYGWIN__) && !defined(__HAIKU__) - const char *p; - size_t i; -#endif - - assert((a = archive_read_disk_new()) != NULL); - - /* Default uname/gname lookups always return NULL. */ - assert(archive_read_disk_gname(a, 0) == NULL); - assert(archive_read_disk_uname(a, 0) == NULL); - - /* Register some weird lookup functions. */ - assertEqualInt(ARCHIVE_OK, archive_read_disk_set_gname_lookup(a, - &gmagic, &gname_lookup, &gname_cleanup)); - /* Verify that our new function got called. */ - assertEqualString(archive_read_disk_gname(a, 0), "NOTFOOGROUP"); - assertEqualString(archive_read_disk_gname(a, 1), "FOOGROUP"); - - /* De-register. */ - assertEqualInt(ARCHIVE_OK, - archive_read_disk_set_gname_lookup(a, NULL, NULL, NULL)); - /* Ensure our cleanup function got called. */ - assertEqualInt(gmagic, 0x2468); - - /* Same thing with uname lookup.... */ - assertEqualInt(ARCHIVE_OK, archive_read_disk_set_uname_lookup(a, - &umagic, &uname_lookup, &uname_cleanup)); - assertEqualString(archive_read_disk_uname(a, 0), "NOTFOO"); - assertEqualString(archive_read_disk_uname(a, 1), "FOO"); - assertEqualInt(ARCHIVE_OK, - archive_read_disk_set_uname_lookup(a, NULL, NULL, NULL)); - assertEqualInt(umagic, 0x2345); - - /* Try the standard lookup functions. */ - if (archive_read_disk_set_standard_lookup(a) != ARCHIVE_OK) { - skipping("standard uname/gname lookup"); - } else { -#if defined(__CYGWIN__) || defined(__HAIKU__) - /* Some platforms don't have predictable names for - * uid=0, so we skip this part of the test. */ - skipping("standard uname/gname lookup"); -#else - /* XXX Someday, we may need to generalize this the - * same way we generalized the group name check below. - * That's needed only if we encounter a system where - * uid 0 is not "root". XXX */ - assertEqualString(archive_read_disk_uname(a, 0), "root"); - - /* Get the group name for group 0 and see if it makes sense. */ - p = archive_read_disk_gname(a, 0); - assert(p != NULL); - if (p != NULL) { - i = 0; - while (i < sizeof(zero_groups)/sizeof(zero_groups[0])) { - if (strcmp(zero_groups[i], p) == 0) - break; - ++i; - } - if (i == sizeof(zero_groups)/sizeof(zero_groups[0])) { - /* If you get a failure here, either - * archive_read_disk_gname() isn't working or - * your system uses a different name for group - * number zero. If the latter, please add a - * new entry to the zero_groups[] array above. - */ - failure("group 0 didn't have any of the expected names"); - assertEqualString(p, zero_groups[0]); - } - } -#endif - } - - /* Deregister again and verify the default lookups again. */ - assertEqualInt(ARCHIVE_OK, - archive_read_disk_set_gname_lookup(a, NULL, NULL, NULL)); - assertEqualInt(ARCHIVE_OK, - archive_read_disk_set_uname_lookup(a, NULL, NULL, NULL)); - assert(archive_read_disk_gname(a, 0) == NULL); - assert(archive_read_disk_uname(a, 0) == NULL); - - /* Re-register our custom handlers. */ - gmagic = 0x13579; - umagic = 0x1234; - assertEqualInt(ARCHIVE_OK, archive_read_disk_set_gname_lookup(a, - &gmagic, &gname_lookup, &gname_cleanup)); - assertEqualInt(ARCHIVE_OK, archive_read_disk_set_uname_lookup(a, - &umagic, &uname_lookup, &uname_cleanup)); - - /* Destroy the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* Verify our cleanup functions got called. */ - assertEqualInt(gmagic, 0x2468); - assertEqualInt(umagic, 0x2345); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_disk_directory_traversals.c b/thirdparty/libarchive/libarchive/test/test_read_disk_directory_traversals.c deleted file mode 100644 index ad99acfef..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_disk_directory_traversals.c +++ /dev/null @@ -1,1876 +0,0 @@ -/*- - * Copyright (c) 2010-2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -#include -#if defined(_WIN32) && !defined(__CYGWIN__) -# if !defined(__BORLANDC__) -# define getcwd _getcwd -# endif -#endif - -/* - * Test if the current filesystem is mounted with noatime option. - */ -static int -atimeIsUpdated(void) -{ - const char *fn = "fs_noatime"; - struct stat st; -#if defined(_WIN32) && !defined(CYGWIN) - char *buff = NULL; - char *ptr; - int r; - - r = systemf("fsutil behavior query disableLastAccess > query_atime"); - if (r == 0) { - buff = slurpfile(NULL, "query_atime"); - if (buff != NULL) { - ptr = buff; - while(*ptr != '\0' && !isdigit(*ptr)) { - ptr++; - } - if (*ptr == '0') { - free(buff); - return(1); - } else if (*ptr == '1' || *ptr == '2') { - free(buff); - return(0); - } - free(buff); - } - } -#endif - if (!assertMakeFile(fn, 0666, "a")) - return (0); - if (!assertUtimes(fn, 1, 0, 1, 0)) - return (0); - /* Test the file contents in order to update its atime. */ - if (!assertTextFileContents("a", fn)) - return (0); - if (stat(fn, &st) != 0) - return (0); - /* Is atime updated? */ - if (st.st_atime > 1) - return (1); - return (0); -} - -static void -test_basic(void) -{ - struct archive *a; - struct archive_entry *ae; - const void *p; - char *initial_cwd, *cwd; - size_t size; - int64_t offset; - int file_count; -#if defined(_WIN32) && !defined(__CYGWIN__) - wchar_t *wcwd, *wp, *fullpath; -#endif - - assertMakeDir("dir1", 0755); - assertMakeFile("dir1/file1", 0644, "0123456789"); - assertMakeFile("dir1/file2", 0644, "hello world"); - assertMakeDir("dir1/sub1", 0755); - assertMakeFile("dir1/sub1/file1", 0644, "0123456789"); - assertMakeDir("dir1/sub2", 0755); - assertMakeFile("dir1/sub2/file1", 0644, "0123456789"); - assertMakeFile("dir1/sub2/file2", 0644, "0123456789"); - assertMakeDir("dir1/sub2/sub1", 0755); - assertMakeDir("dir1/sub2/sub2", 0755); - assertMakeDir("dir1/sub2/sub3", 0755); - assertMakeFile("dir1/sub2/sub3/file", 0644, "xyz"); - file_count = 12; - - assert((ae = archive_entry_new()) != NULL); - assert((a = archive_read_disk_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "dir1")); - - while (file_count--) { - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); - if (strcmp(archive_entry_pathname(ae), "dir1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - assertEqualInt(1, archive_read_disk_can_descend(a)); - } else if (strcmp(archive_entry_pathname(ae), - "dir1/file1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 10); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 10); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "0123456789", 10); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 10); - assertEqualInt(0, archive_read_disk_can_descend(a)); - } else if (strcmp(archive_entry_pathname(ae), - "dir1/file2") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 11); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 11); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "hello world", 11); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 11); - assertEqualInt(0, archive_read_disk_can_descend(a)); - } else if (strcmp(archive_entry_pathname(ae), - "dir1/sub1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - assertEqualInt(1, archive_read_disk_can_descend(a)); - } else if (strcmp(archive_entry_pathname(ae), - "dir1/sub1/file1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 10); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 10); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "0123456789", 10); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 10); - assertEqualInt(0, archive_read_disk_can_descend(a)); - } else if (strcmp(archive_entry_pathname(ae), - "dir1/sub2") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - assertEqualInt(1, archive_read_disk_can_descend(a)); - } else if (strcmp(archive_entry_pathname(ae), - "dir1/sub2/file1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 10); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 10); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "0123456789", 10); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 10); - assertEqualInt(0, archive_read_disk_can_descend(a)); - } else if (strcmp(archive_entry_pathname(ae), - "dir1/sub2/file2") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 10); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 10); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "0123456789", 10); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 10); - assertEqualInt(0, archive_read_disk_can_descend(a)); - } else if (strcmp(archive_entry_pathname(ae), - "dir1/sub2/sub1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - assertEqualInt(1, archive_read_disk_can_descend(a)); - } else if (strcmp(archive_entry_pathname(ae), - "dir1/sub2/sub2") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - assertEqualInt(1, archive_read_disk_can_descend(a)); - } else if (strcmp(archive_entry_pathname(ae), - "dir1/sub2/sub3") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - assertEqualInt(1, archive_read_disk_can_descend(a)); - } else if (strcmp(archive_entry_pathname(ae), - "dir1/sub2/sub3/file") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 3); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 3); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "xyz", 3); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 3); - assertEqualInt(0, archive_read_disk_can_descend(a)); - } - if (archive_entry_filetype(ae) == AE_IFDIR) { - /* Descend into the current object */ - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_descend(a)); - } - } - /* There is no entry. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); - - /* Close the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - - /* - * Test that call archive_read_disk_open_w, wchar_t version. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open_w(a, L"dir1")); - - file_count = 12; - while (file_count--) { - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); - if (wcscmp(archive_entry_pathname_w(ae), L"dir1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - assertEqualInt(1, archive_read_disk_can_descend(a)); - } else if (wcscmp(archive_entry_pathname_w(ae), - L"dir1/file1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 10); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 10); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "0123456789", 10); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 10); - assertEqualInt(0, archive_read_disk_can_descend(a)); - } else if (wcscmp(archive_entry_pathname_w(ae), - L"dir1/file2") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 11); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 11); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "hello world", 11); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 11); - assertEqualInt(0, archive_read_disk_can_descend(a)); - } else if (wcscmp(archive_entry_pathname_w(ae), - L"dir1/sub1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - assertEqualInt(1, archive_read_disk_can_descend(a)); - } else if (wcscmp(archive_entry_pathname_w(ae), - L"dir1/sub1/file1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 10); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 10); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "0123456789", 10); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 10); - assertEqualInt(0, archive_read_disk_can_descend(a)); - } else if (wcscmp(archive_entry_pathname_w(ae), - L"dir1/sub2") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - assertEqualInt(1, archive_read_disk_can_descend(a)); - } else if (wcscmp(archive_entry_pathname_w(ae), - L"dir1/sub2/file1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 10); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 10); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "0123456789", 10); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 10); - assertEqualInt(0, archive_read_disk_can_descend(a)); - } else if (wcscmp(archive_entry_pathname_w(ae), - L"dir1/sub2/file2") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 10); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 10); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "0123456789", 10); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 10); - assertEqualInt(0, archive_read_disk_can_descend(a)); - } else if (wcscmp(archive_entry_pathname_w(ae), - L"dir1/sub2/sub1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - assertEqualInt(1, archive_read_disk_can_descend(a)); - } else if (wcscmp(archive_entry_pathname_w(ae), - L"dir1/sub2/sub2") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - assertEqualInt(1, archive_read_disk_can_descend(a)); - } else if (wcscmp(archive_entry_pathname_w(ae), - L"dir1/sub2/sub3") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - assertEqualInt(1, archive_read_disk_can_descend(a)); - } else if (wcscmp(archive_entry_pathname_w(ae), - L"dir1/sub2/sub3/file") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 3); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 3); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "xyz", 3); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 3); - assertEqualInt(0, archive_read_disk_can_descend(a)); - } - if (archive_entry_filetype(ae) == AE_IFDIR) { - /* Descend into the current object */ - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_descend(a)); - } - } - /* There is no entry. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); - - /* Close the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - - /* - * Test that call archive_read_disk_open with a regular file. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "dir1/file1")); - - /* dir1/file1 */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); - assertEqualInt(0, archive_read_disk_can_descend(a)); - assertEqualString(archive_entry_pathname(ae), "dir1/file1"); - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 10); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 10); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "0123456789", 10); - - /* There is no entry. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); - - /* Close the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - - -#if defined(_WIN32) && !defined(__CYGWIN__) - /* - * Test for wildcard '*' or '?' - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "dir1/*1")); - - /* dir1/file1 */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); - assertEqualInt(0, archive_read_disk_can_descend(a)); - assertEqualString(archive_entry_pathname(ae), "dir1/file1"); - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 10); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 10); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "0123456789", 10); - - /* dir1/sub1 */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); - assertEqualInt(1, archive_read_disk_can_descend(a)); - assertEqualString(archive_entry_pathname(ae), "dir1/sub1"); - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - - /* Descend into the current object */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); - - /* dir1/sub1/file1 */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); - assertEqualInt(0, archive_read_disk_can_descend(a)); - assertEqualString(archive_entry_pathname(ae), "dir1/sub1/file1"); - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 10); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 10); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "0123456789", 10); - - /* There is no entry. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); - - /* Close the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - - /* - * Test for a full-path beginning with "//?/" - */ - wcwd = _wgetcwd(NULL, 0); - fullpath = malloc(sizeof(wchar_t) * (wcslen(wcwd) + 32)); - wcscpy(fullpath, L"//?/"); - wcscat(fullpath, wcwd); - wcscat(fullpath, L"/dir1/file1"); - free(wcwd); - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open_w(a, fullpath)); - while ((wcwd = wcschr(fullpath, L'\\')) != NULL) - *wcwd = L'/'; - - /* dir1/file1 */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); - assertEqualInt(0, archive_read_disk_can_descend(a)); - assertEqualWString(archive_entry_pathname_w(ae), fullpath); - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 10); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 10); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "0123456789", 10); - - /* There is no entry. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); - - /* Close the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - free(fullpath); - - /* - * Test for wild card '*' or '?' with "//?/" prefix. - */ - wcwd = _wgetcwd(NULL, 0); - fullpath = malloc(sizeof(wchar_t) * (wcslen(wcwd) + 32)); - wcscpy(fullpath, L"//?/"); - wcscat(fullpath, wcwd); - wcscat(fullpath, L"/dir1/*1"); - free(wcwd); - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open_w(a, fullpath)); - while ((wcwd = wcschr(fullpath, L'\\')) != NULL) - *wcwd = L'/'; - - /* dir1/file1 */ - wp = wcsrchr(fullpath, L'/'); - wcscpy(wp+1, L"file1"); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); - assertEqualInt(0, archive_read_disk_can_descend(a)); - assertEqualWString(archive_entry_pathname_w(ae), fullpath); - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 10); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 10); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "0123456789", 10); - - /* dir1/sub1 */ - wcscpy(wp+1, L"sub1"); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); - assertEqualInt(1, archive_read_disk_can_descend(a)); - assertEqualWString(archive_entry_pathname_w(ae), fullpath); - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - - /* Descend into the current object */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); - - /* dir1/sub1/file1 */ - wcscpy(wp+1, L"sub1/file1"); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); - assertEqualInt(0, archive_read_disk_can_descend(a)); - assertEqualWString(archive_entry_pathname_w(ae), fullpath); - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 10); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 10); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "0123456789", 10); - - /* There is no entry. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); - - /* Close the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - free(fullpath); - -#endif - - /* - * We should be on the initial directory where we performed - * archive_read_disk_new() after we perform archive_read_free() - * even if we broke off the directory traversals. - */ - - /* Save current working directory. */ -#if defined(PATH_MAX) && !defined(__GLIBC__) - initial_cwd = getcwd(NULL, PATH_MAX);/* Solaris getcwd needs the size. */ -#else - initial_cwd = getcwd(NULL, 0); -#endif - - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "dir1")); - - /* Step in a deep directory. */ - file_count = 12; - while (file_count--) { - assertEqualIntA(a, ARCHIVE_OK, - archive_read_next_header2(a, ae)); - if (strcmp(archive_entry_pathname(ae), - "dir1/sub1/file1") == 0) - /* - * We are on an another directory at this time. - */ - break; - if (archive_entry_filetype(ae) == AE_IFDIR) { - /* Descend into the current object */ - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_descend(a)); - } - } - /* Destroy the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* We should be on the initial working directory. */ - failure( - "Current working directory does not return to the initial" - "directory"); -#if defined(PATH_MAX) && !defined(__GLIBC__) - cwd = getcwd(NULL, PATH_MAX);/* Solaris getcwd needs the size. */ -#else - cwd = getcwd(NULL, 0); -#endif - assertEqualString(initial_cwd, cwd); - free(initial_cwd); - free(cwd); - - archive_entry_free(ae); -} - -static void -test_symlink_hybrid(void) -{ - struct archive *a; - struct archive_entry *ae; - const void *p; - size_t size; - int64_t offset; - int file_count; - - if (!canSymlink()) { - skipping("Can't test symlinks on this filesystem"); - return; - } - - /* - * Create a sample archive. - */ - assertMakeDir("h", 0755); - assertChdir("h"); - assertMakeDir("d1", 0755); - assertMakeSymlink("ld1", "d1", 1); - assertMakeFile("d1/file1", 0644, "d1/file1"); - assertMakeFile("d1/file2", 0644, "d1/file2"); - assertMakeSymlink("d1/link1", "file1", 0); - assertMakeSymlink("d1/linkX", "fileX", 0); - assertMakeSymlink("link2", "d1/file2", 0); - assertMakeSymlink("linkY", "d1/fileY", 0); - assertChdir(".."); - - assert((ae = archive_entry_new()) != NULL); - assert((a = archive_read_disk_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_set_symlink_hybrid(a)); - - /* - * Specified file is a symbolic link file. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "h/ld1")); - file_count = 5; - - while (file_count--) { - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); - if (strcmp(archive_entry_pathname(ae), "h/ld1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - } else if (strcmp(archive_entry_pathname(ae), - "h/ld1/file1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 8); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 8); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "d1/file1", 8); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 8); - } else if (strcmp(archive_entry_pathname(ae), - "h/ld1/file2") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 8); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 8); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "d1/file2", 8); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 8); - } else if (strcmp(archive_entry_pathname(ae), - "h/ld1/link1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); - } else if (strcmp(archive_entry_pathname(ae), - "h/ld1/linkX") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); - } - if (archive_entry_filetype(ae) == AE_IFDIR) { - /* Descend into the current object */ - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_descend(a)); - } - } - /* There is no entry. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); - /* Close the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - - /* - * Specified file is a directory and it has symbolic files. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "h")); - file_count = 9; - - while (file_count--) { - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); - if (strcmp(archive_entry_pathname(ae), "h") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - } else if (strcmp(archive_entry_pathname(ae), "h/d1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - } else if (strcmp(archive_entry_pathname(ae), - "h/d1/file1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 8); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 8); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "d1/file1", 8); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 8); - } else if (strcmp(archive_entry_pathname(ae), - "h/d1/file2") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 8); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 8); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "d1/file2", 8); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 8); - } else if (strcmp(archive_entry_pathname(ae), "h/ld1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); - } else if (strcmp(archive_entry_pathname(ae), - "h/d1/link1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); - } else if (strcmp(archive_entry_pathname(ae), - "h/d1/linkX") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); - } else if (strcmp(archive_entry_pathname(ae), - "h/link2") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); - } else if (strcmp(archive_entry_pathname(ae), - "h/linkY") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); - } - if (archive_entry_filetype(ae) == AE_IFDIR) { - /* Descend into the current object */ - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_descend(a)); - } - } - /* There is no entry. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); - /* Close the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - /* Destroy the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - archive_entry_free(ae); -} - -static void -test_symlink_logical(void) -{ - struct archive *a; - struct archive_entry *ae; - const void *p; - size_t size; - int64_t offset; - int file_count; - - if (!canSymlink()) { - skipping("Can't test symlinks on this filesystem"); - return; - } - - /* - * Create a sample archive. - */ - assertMakeDir("l", 0755); - assertChdir("l"); - assertMakeDir("d1", 0755); - assertMakeSymlink("ld1", "d1", 1); - assertMakeFile("d1/file1", 0644, "d1/file1"); - assertMakeFile("d1/file2", 0644, "d1/file2"); - assertMakeSymlink("d1/link1", "file1", 0); - assertMakeSymlink("d1/linkX", "fileX", 0); - assertMakeSymlink("link2", "d1/file2", 0); - assertMakeSymlink("linkY", "d1/fileY", 0); - assertChdir(".."); - - /* Note: this test uses archive_read_next_header() - instead of archive_read_next_header2() */ - assert((a = archive_read_disk_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_set_symlink_logical(a)); - - /* - * Specified file is a symbolic link file. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "l/ld1")); - file_count = 5; - - while (file_count--) { - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - if (strcmp(archive_entry_pathname(ae), "l/ld1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - } else if (strcmp(archive_entry_pathname(ae), - "l/ld1/file1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 8); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 8); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "d1/file1", 8); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 8); - } else if (strcmp(archive_entry_pathname(ae), - "l/ld1/file2") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 8); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 8); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "d1/file2", 8); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 8); - } else if (strcmp(archive_entry_pathname(ae), - "l/ld1/link1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 8); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 8); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "d1/file1", 8); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 8); - } else if (strcmp(archive_entry_pathname(ae), - "l/ld1/linkX") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); - } - if (archive_entry_filetype(ae) == AE_IFDIR) { - /* Descend into the current object */ - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_descend(a)); - } - } - /* There is no entry. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - /* Close the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - - /* - * Specified file is a directory and it has symbolic files. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "l")); - file_count = 13; - - while (file_count--) { - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - if (strcmp(archive_entry_pathname(ae), "l") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - } else if (strcmp(archive_entry_pathname(ae), "l/d1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - } else if (strcmp(archive_entry_pathname(ae), - "l/d1/file1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 8); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 8); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "d1/file1", 8); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 8); - } else if (strcmp(archive_entry_pathname(ae), - "l/d1/file2") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 8); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 8); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "d1/file2", 8); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 8); - } else if (strcmp(archive_entry_pathname(ae), - "l/d1/link1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 8); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 8); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "d1/file1", 8); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 8); - } else if (strcmp(archive_entry_pathname(ae), - "l/d1/linkX") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); - } else if (strcmp(archive_entry_pathname(ae), "l/ld1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - } else if (strcmp(archive_entry_pathname(ae), - "l/ld1/file1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 8); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 8); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "d1/file1", 8); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 8); - } else if (strcmp(archive_entry_pathname(ae), - "l/ld1/file2") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 8); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 8); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "d1/file2", 8); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 8); - } else if (strcmp(archive_entry_pathname(ae), - "l/ld1/link1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 8); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 8); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "d1/file1", 8); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 8); - } else if (strcmp(archive_entry_pathname(ae), - "l/ld1/linkX") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); - } else if (strcmp(archive_entry_pathname(ae), - "l/link2") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 8); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 8); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "d1/file2", 8); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 8); - } else if (strcmp(archive_entry_pathname(ae), - "l/linkY") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); - } - if (archive_entry_filetype(ae) == AE_IFDIR) { - /* Descend into the current object */ - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_descend(a)); - } - } - /* There is no entry. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - /* Close the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - /* Destroy the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -static void -test_symlink_logical_loop(void) -{ - struct archive *a; - struct archive_entry *ae; - const void *p; - size_t size; - int64_t offset; - int file_count; - - if (!canSymlink()) { - skipping("Can't test symlinks on this filesystem"); - return; - } - - /* - * Create a sample archive. - */ - assertMakeDir("l2", 0755); - assertChdir("l2"); - assertMakeDir("d1", 0755); - assertMakeDir("d1/d2", 0755); - assertMakeDir("d1/d2/d3", 0755); - assertMakeDir("d2", 0755); - assertMakeFile("d2/file1", 0644, "d2/file1"); - assertMakeSymlink("d1/d2/ld1", "../../d1", 1); - assertMakeSymlink("d1/d2/ld2", "../../d2", 1); - assertChdir(".."); - - assert((ae = archive_entry_new()) != NULL); - assert((a = archive_read_disk_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_set_symlink_logical(a)); - - /* - * Specified file is a symbolic link file. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "l2/d1")); - file_count = 6; - - while (file_count--) { - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); - if (strcmp(archive_entry_pathname(ae), "l2/d1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - } else if (strcmp(archive_entry_pathname(ae), "l2/d1/d2") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - } else if (strcmp(archive_entry_pathname(ae), "l2/d1/d2/d3") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - } else if (strcmp(archive_entry_pathname(ae), "l2/d1/d2/ld1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); - } else if (strcmp(archive_entry_pathname(ae), "l2/d1/d2/ld2") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - } else if (strcmp(archive_entry_pathname(ae), - "l2/d1/d2/ld2/file1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 8); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 8); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "d2/file1", 8); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 8); - } - if (archive_entry_filetype(ae) == AE_IFDIR) { - /* Descend into the current object */ - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_descend(a)); - } - } - /* There is no entry. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); - /* Destroy the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - archive_entry_free(ae); -} - -static void -test_restore_atime(void) -{ - struct archive *a; - struct archive_entry *ae; - const void *p; - size_t size; - int64_t offset; - int file_count; - const char *skip_test_restore_atime; - - skip_test_restore_atime = getenv("SKIP_TEST_RESTORE_ATIME"); - if (skip_test_restore_atime != NULL) { - skipping("Skipping restore atime tests due to " - "SKIP_TEST_RESTORE_ATIME environment variable"); - return; - } - if (!atimeIsUpdated()) { - skipping("Can't test restoring atime on this filesystem"); - return; - } - - assertMakeDir("at", 0755); - assertMakeFile("at/f1", 0644, "0123456789"); - assertMakeFile("at/f2", 0644, "hello world"); - assertMakeFile("at/fe", 0644, NULL); - assertUtimes("at/f1", 886600, 0, 886600, 0); - assertUtimes("at/f2", 886611, 0, 886611, 0); - assertUtimes("at/fe", 886611, 0, 886611, 0); - assertUtimes("at", 886622, 0, 886622, 0); - file_count = 4; - - assert((ae = archive_entry_new()) != NULL); - assert((a = archive_read_disk_new()) != NULL); - - /* - * Test1: Traversals without archive_read_disk_set_atime_restored(). - */ - failure("Directory traversals should work as well"); - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "at")); - while (file_count--) { - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); - if (strcmp(archive_entry_pathname(ae), "at") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - } else if (strcmp(archive_entry_pathname(ae), "at/f1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 10); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 10); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "0123456789", 10); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 10); - } else if (strcmp(archive_entry_pathname(ae), "at/f2") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 11); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 11); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "hello world", 11); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 11); - } else if (strcmp(archive_entry_pathname(ae), "at/fe") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 0); - } - if (archive_entry_filetype(ae) == AE_IFDIR) { - /* Descend into the current object */ - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_descend(a)); - } - } - /* There is no entry. */ - failure("There must be no entry"); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); - - /* On FreeBSD (and likely other systems), atime on - dirs does not change when it is read. */ - /* failure("Atime should be restored"); */ - /* assertFileAtimeRecent("at"); */ - failure("Atime should be restored"); - assertFileAtimeRecent("at/f1"); - failure("Atime should be restored"); - assertFileAtimeRecent("at/f2"); - failure("The atime of a empty file should not be changed"); - assertFileAtime("at/fe", 886611, 0); - - /* Close the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - - /* - * Test2: Traversals with archive_read_disk_set_atime_restored(). - */ - assertUtimes("at/f1", 886600, 0, 886600, 0); - assertUtimes("at/f2", 886611, 0, 886611, 0); - assertUtimes("at/fe", 886611, 0, 886611, 0); - assertUtimes("at", 886622, 0, 886622, 0); - file_count = 4; - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_atime_restored(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "at")); - - failure("Directory traversals should work as well"); - while (file_count--) { - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); - if (strcmp(archive_entry_pathname(ae), "at") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - } else if (strcmp(archive_entry_pathname(ae), "at/f1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 10); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 10); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "0123456789", 10); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 10); - } else if (strcmp(archive_entry_pathname(ae), "at/f2") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 11); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 11); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "hello world", 11); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 11); - } else if (strcmp(archive_entry_pathname(ae), "at/fe") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 0); - } - if (archive_entry_filetype(ae) == AE_IFDIR) { - /* Descend into the current object */ - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_descend(a)); - } - } - /* There is no entry. */ - failure("There must be no entry"); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); - - failure("Atime should be restored"); - assertFileAtime("at", 886622, 0); - failure("Atime should be restored"); - assertFileAtime("at/f1", 886600, 0); - failure("Atime should be restored"); - assertFileAtime("at/f2", 886611, 0); - failure("The atime of a empty file should not be changed"); - assertFileAtime("at/fe", 886611, 0); - - /* Close the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - - /* - * Test3: Traversals with archive_read_disk_set_atime_restored() but - * no data read as a listing. - */ - assertUtimes("at/f1", 886600, 0, 886600, 0); - assertUtimes("at/f2", 886611, 0, 886611, 0); - assertUtimes("at/fe", 886611, 0, 886611, 0); - assertUtimes("at", 886622, 0, 886622, 0); - file_count = 4; - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_atime_restored(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "at")); - - failure("Directory traversals should work as well"); - while (file_count--) { - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); - if (strcmp(archive_entry_pathname(ae), "at") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - } else if (strcmp(archive_entry_pathname(ae), "at/f1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 10); - } else if (strcmp(archive_entry_pathname(ae), "at/f2") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 11); - } else if (strcmp(archive_entry_pathname(ae), "at/fe") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 0); - } - if (archive_entry_filetype(ae) == AE_IFDIR) { - /* Descend into the current object */ - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_descend(a)); - } - } - /* There is no entry. */ - failure("There must be no entry"); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); - - failure("Atime should be restored"); - assertFileAtime("at", 886622, 0); - failure("Atime should be restored"); - assertFileAtime("at/f1", 886600, 0); - failure("Atime should be restored"); - assertFileAtime("at/f2", 886611, 0); - failure("The atime of a empty file should not be changed"); - assertFileAtime("at/fe", 886611, 0); - - if (!canNodump()) { - /* Destroy the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - archive_entry_free(ae); - skipping("Can't test atime with nodump on this filesystem"); - return; - } - - /* Close the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - - /* - * Test4: Traversals with ARCHIVE_READDISK_RESTORE_ATIME and - * ARCHIVE_READDISK_HONOR_NODUMP - */ - assertSetNodump("at/f1"); - assertSetNodump("at/f2"); - assertUtimes("at/f1", 886600, 0, 886600, 0); - assertUtimes("at/f2", 886611, 0, 886611, 0); - assertUtimes("at/fe", 886611, 0, 886611, 0); - assertUtimes("at", 886622, 0, 886622, 0); - file_count = 2; - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_behavior(a, - ARCHIVE_READDISK_RESTORE_ATIME | ARCHIVE_READDISK_HONOR_NODUMP)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "at")); - - failure("Directory traversals should work as well"); - while (file_count--) { - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); - if (strcmp(archive_entry_pathname(ae), "at") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - } else if (strcmp(archive_entry_pathname(ae), "at/fe") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 0); - } - if (archive_entry_filetype(ae) == AE_IFDIR) { - /* Descend into the current object */ - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_descend(a)); - } - } - /* There is no entry. */ - failure("There must be no entry"); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); - - failure("Atime should be restored"); - assertFileAtime("at", 886622, 0); - failure("Atime should be restored"); - assertFileAtime("at/f1", 886600, 0); - failure("Atime should be restored"); - assertFileAtime("at/f2", 886611, 0); - failure("The atime of a empty file should not be changed"); - assertFileAtime("at/fe", 886611, 0); - - /* Destroy the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - archive_entry_free(ae); -} - -static int -metadata_filter(struct archive *a, void *data, struct archive_entry *ae) -{ - (void)data; /* UNUSED */ - - failure("CTime should be set"); - assertEqualInt(8, archive_entry_ctime_is_set(ae)); - failure("MTime should be set"); - assertEqualInt(16, archive_entry_mtime_is_set(ae)); - - if (archive_entry_mtime(ae) < 886611) - return (0); - if (archive_read_disk_can_descend(a)) { - /* Descend into the current object */ - failure("archive_read_disk_can_descend should work" - " in metadata filter"); - assertEqualIntA(a, 1, archive_read_disk_can_descend(a)); - failure("archive_read_disk_descend should work" - " in metadata filter"); - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); - } - return (1); -} - -static void -test_callbacks(void) -{ - struct archive *a; - struct archive *m; - struct archive_entry *ae; - const void *p; - size_t size; - int64_t offset; - int file_count; - - assertMakeDir("cb", 0755); - assertMakeFile("cb/f1", 0644, "0123456789"); - assertMakeFile("cb/f2", 0644, "hello world"); - assertMakeFile("cb/fe", 0644, NULL); - assertUtimes("cb/f1", 886600, 0, 886600, 0); - assertUtimes("cb/f2", 886611, 0, 886611, 0); - assertUtimes("cb/fe", 886611, 0, 886611, 0); - assertUtimes("cb", 886622, 0, 886622, 0); - - assert((ae = archive_entry_new()) != NULL); - assert((a = archive_read_disk_new()) != NULL); - if (a == NULL) { - archive_entry_free(ae); - return; - } - assert((m = archive_match_new()) != NULL); - if (m == NULL) { - archive_entry_free(ae); - archive_read_free(a); - archive_match_free(m); - return; - } - - /* - * Test1: Traversals with a name filter. - */ - file_count = 3; - assertEqualIntA(m, ARCHIVE_OK, - archive_match_exclude_pattern(m, "cb/f2")); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_set_matching(a, m, NULL, NULL)); - failure("Directory traversals should work as well"); - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "cb")); - while (file_count--) { - archive_entry_clear(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); - failure("File 'cb/f2' should be exclueded"); - assert(strcmp(archive_entry_pathname(ae), "cb/f2") != 0); - if (strcmp(archive_entry_pathname(ae), "cb") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - } else if (strcmp(archive_entry_pathname(ae), "cb/f1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 10); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 10); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "0123456789", 10); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 10); - } else if (strcmp(archive_entry_pathname(ae), "cb/fe") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 0); - } - if (archive_read_disk_can_descend(a)) { - /* Descend into the current object */ - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_descend(a)); - } - } - /* There is no entry. */ - failure("There should be no entry"); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); - - /* Close the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - - /* Reset name filter */ - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_set_matching(a, NULL, NULL, NULL)); - - /* - * Test2: Traversals with a metadata filter. - */ - assertUtimes("cb/f1", 886600, 0, 886600, 0); - assertUtimes("cb/f2", 886611, 0, 886611, 0); - assertUtimes("cb/fe", 886611, 0, 886611, 0); - assertUtimes("cb", 886622, 0, 886622, 0); - file_count = 3; - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_set_metadata_filter_callback(a, metadata_filter, - NULL)); - failure("Directory traversals should work as well"); - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "cb")); - - while (file_count--) { - archive_entry_clear(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); - failure("File 'cb/f1' should be excluded"); - assert(strcmp(archive_entry_pathname(ae), "cb/f1") != 0); - if (strcmp(archive_entry_pathname(ae), "cb") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - } else if (strcmp(archive_entry_pathname(ae), "cb/f2") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 11); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 11); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "hello world", 11); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 11); - } else if (strcmp(archive_entry_pathname(ae), "cb/fe") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 0); - } - } - /* There is no entry. */ - failure("There should be no entry"); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); - - /* Destroy the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - assertEqualInt(ARCHIVE_OK, archive_match_free(m)); - archive_entry_free(ae); -} - -static void -test_nodump(void) -{ - struct archive *a; - struct archive_entry *ae; - const void *p; - size_t size; - int64_t offset; - int file_count; - - if (!canNodump()) { - skipping("Can't test nodump on this filesystem"); - return; - } - - assertMakeDir("nd", 0755); - assertMakeFile("nd/f1", 0644, "0123456789"); - assertMakeFile("nd/f2", 0644, "hello world"); - assertMakeFile("nd/fe", 0644, NULL); - assertSetNodump("nd/f2"); - assertUtimes("nd/f1", 886600, 0, 886600, 0); - assertUtimes("nd/f2", 886611, 0, 886611, 0); - assertUtimes("nd/fe", 886611, 0, 886611, 0); - assertUtimes("nd", 886622, 0, 886622, 0); - - assert((ae = archive_entry_new()) != NULL); - assert((a = archive_read_disk_new()) != NULL); - - /* - * Test1: Traversals without ARCHIVE_READDISK_HONOR_NODUMP - */ - failure("Directory traversals should work as well"); - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "nd")); - - file_count = 4; - while (file_count--) { - archive_entry_clear(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); - if (strcmp(archive_entry_pathname(ae), "nd") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - } else if (strcmp(archive_entry_pathname(ae), "nd/f1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 10); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 10); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "0123456789", 10); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 10); - } else if (strcmp(archive_entry_pathname(ae), "nd/f2") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 11); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 11); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "hello world", 11); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 11); - } else if (strcmp(archive_entry_pathname(ae), "nd/fe") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 0); - } - if (archive_read_disk_can_descend(a)) { - /* Descend into the current object */ - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_descend(a)); - } - } - /* There is no entry. */ - failure("There should be no entry"); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); - - /* Close the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - - /* - * Test2: Traversals with ARCHIVE_READDISK_HONOR_NODUMP - */ - assertUtimes("nd/f1", 886600, 0, 886600, 0); - assertUtimes("nd/f2", 886611, 0, 886611, 0); - assertUtimes("nd/fe", 886611, 0, 886611, 0); - assertUtimes("nd", 886622, 0, 886622, 0); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_behavior(a, - ARCHIVE_READDISK_RESTORE_ATIME | ARCHIVE_READDISK_HONOR_NODUMP)); - failure("Directory traversals should work as well"); - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "nd")); - - file_count = 3; - while (file_count--) { - archive_entry_clear(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); - failure("File 'nd/f2' should be exclueded"); - assert(strcmp(archive_entry_pathname(ae), "nd/f2") != 0); - if (strcmp(archive_entry_pathname(ae), "nd") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - } else if (strcmp(archive_entry_pathname(ae), "nd/f1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 10); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 10); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "0123456789", 10); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 10); - } else if (strcmp(archive_entry_pathname(ae), "nd/fe") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 0); - } - if (archive_read_disk_can_descend(a)) { - /* Descend into the current object */ - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_descend(a)); - } - } - /* There is no entry. */ - failure("There should be no entry"); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); - - failure("Atime should be restored"); - assertFileAtime("nd/f2", 886611, 0); - - /* Destroy the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - archive_entry_free(ae); -} - -static void -test_parent(void) -{ - struct archive *a; - struct archive_entry *ae; - const void *p; - size_t size; - int64_t offset; - int file_count; - int match_count; - int r; -#if defined(O_PATH) || defined(O_SEARCH) || \ - (defined(__FreeBSD__) && defined(O_EXEC)) - const char *ignore_traversals_test4; - - ignore_traversals_test4 = getenv("IGNORE_TRAVERSALS_TEST4"); -#endif - - assertMakeDir("lock", 0311); - assertMakeDir("lock/dir1", 0755); - assertMakeFile("lock/dir1/f1", 0644, "0123456789"); - assertMakeDir("lock/lock2", 0311); - assertMakeDir("lock/lock2/dir1", 0755); - assertMakeFile("lock/lock2/dir1/f1", 0644, "0123456789"); - - assert((ae = archive_entry_new()) != NULL); - assert((a = archive_read_disk_new()) != NULL); - - /* - * Test1: Traverse lock/dir1 as . - */ - assertChdir("lock/dir1"); - - failure("Directory traversals should work as well"); - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, ".")); - - file_count = 2; - match_count = 0; - while (file_count--) { - archive_entry_clear(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); - if (strcmp(archive_entry_pathname(ae), ".") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - ++match_count; - } else if (strcmp(archive_entry_pathname(ae), "./f1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 10); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 10); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "0123456789", 10); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 10); - ++match_count; - } - if (archive_read_disk_can_descend(a)) { - /* Descend into the current object */ - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_descend(a)); - } - } - failure("Did not match expected filenames"); - assertEqualInt(match_count, 2); - /* - * There is no entry. This will however fail if the directory traverse - * tries to ascend past the initial directory, since it lacks permission - * to do so. - */ - failure("There should be no entry and no error"); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); - - /* Close the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - - assertChdir("../.."); - - /* - * Test2: Traverse lock/dir1 directly - */ - failure("Directory traversals should work as well"); - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "lock/dir1")); - - file_count = 2; - match_count = 0; - while (file_count--) { - archive_entry_clear(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); - if (strcmp(archive_entry_pathname(ae), "lock/dir1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - ++match_count; - } else if (strcmp(archive_entry_pathname(ae), "lock/dir1/f1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 10); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 10); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "0123456789", 10); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 10); - ++match_count; - } - if (archive_read_disk_can_descend(a)) { - /* Descend into the current object */ - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_descend(a)); - } - } - failure("Did not match expected filenames"); - assertEqualInt(match_count, 2); - /* - * There is no entry. This will however fail if the directory traverse - * tries to ascend past the initial directory, since it lacks permission - * to do so. - */ - failure("There should be no entry and no error"); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); - - /* Close the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - - /* - * Test3: Traverse lock/dir1/. - */ - failure("Directory traversals should work as well"); - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "lock/dir1/.")); - - file_count = 2; - match_count = 0; - while (file_count--) { - archive_entry_clear(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); - if (strcmp(archive_entry_pathname(ae), "lock/dir1/.") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - ++match_count; - } else if (strcmp(archive_entry_pathname(ae), "lock/dir1/./f1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_size(ae), 10); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 10); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "0123456789", 10); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 10); - ++match_count; - } - if (archive_read_disk_can_descend(a)) { - /* Descend into the current object */ - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_descend(a)); - } - } - failure("Did not match expected filenames"); - assertEqualInt(match_count, 2); - /* - * There is no entry. This will however fail if the directory traverse - * tries to ascend past the initial directory, since it lacks permission - * to do so. - */ - failure("There should be no entry and no error"); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); - - /* Close the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - - /* - * Test4: Traverse lock/lock2/dir1 from inside lock. - * - * This test is expected to fail on platforms with no O_EXEC or - * equivalent (e.g. O_PATH on Linux or O_SEARCH on SunOS), because - * the current traversal code can't handle the case where it can't - * obtain an open fd for the initial current directory. We need to - * check that condition here, because if O_EXEC _does_ exist, we don't - * want to overlook any failure. - */ - assertChdir("lock"); - - failure("Directory traversals should work as well"); - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "lock2/dir1")); - - archive_entry_clear(ae); - r = archive_read_next_header2(a, ae); - if (r == ARCHIVE_FAILED) { -#if defined(O_PATH) || defined(O_SEARCH) || \ - (defined(__FreeBSD__) && defined(O_EXEC)) - if (ignore_traversals_test4 == NULL) - assertEqualIntA(a, ARCHIVE_OK, r); -#endif - /* Close the disk object. */ - archive_read_close(a); - } else { - file_count = 2; - match_count = 0; - while (file_count--) { - if (file_count == 0) - assertEqualIntA(a, ARCHIVE_OK, - archive_read_next_header2(a, ae)); - if (strcmp(archive_entry_pathname(ae), - "lock2/dir1") == 0) { - assertEqualInt(archive_entry_filetype(ae), - AE_IFDIR); - ++match_count; - } else if (strcmp(archive_entry_pathname(ae), - "lock2/dir1/f1") == 0) { - assertEqualInt(archive_entry_filetype(ae), - AE_IFREG); - assertEqualInt(archive_entry_size(ae), 10); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &p, &size, - &offset)); - assertEqualInt((int)size, 10); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "0123456789", 10); - assertEqualInt(ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, - &offset)); - assertEqualInt((int)size, 0); - assertEqualInt((int)offset, 10); - ++match_count; - } - if (archive_read_disk_can_descend(a)) { - /* Descend into the current object */ - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_descend(a)); - } - } - failure("Did not match expected filenames"); - assertEqualInt(match_count, 2); - /* - * There is no entry. This will however fail if the directory - * traverse tries to ascend past the initial directory, since - * it lacks permission to do so. - */ - failure("There should be no entry and no error"); - assertEqualIntA(a, ARCHIVE_EOF, - archive_read_next_header2(a, ae)); - - /* Close the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - } - - assertChdir(".."); - assertChmod("lock", 0755); - assertChmod("lock/lock2", 0755); - - /* Destroy the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - archive_entry_free(ae); -} - -DEFINE_TEST(test_read_disk_directory_traversals) -{ - /* Basic test. */ - test_basic(); - /* Test hybrid mode; follow symlink initially, then not. */ - test_symlink_hybrid(); - /* Test logical mode; follow all symlinks. */ - test_symlink_logical(); - /* Test logical mode; prevent loop in symlinks. */ - test_symlink_logical_loop(); - /* Test to restore atime. */ - test_restore_atime(); - /* Test callbacks. */ - test_callbacks(); - /* Test nodump. */ - test_nodump(); - /* Test parent overshoot. */ - test_parent(); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_disk_entry_from_file.c b/thirdparty/libarchive/libarchive/test/test_read_disk_entry_from_file.c deleted file mode 100644 index 7a41034ac..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_disk_entry_from_file.c +++ /dev/null @@ -1,80 +0,0 @@ -/*- - * Copyright (c) 2003-2009 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_disk_entry_from_file.c 201247 2009-12-30 05:59:21Z kientzle $"); - -static const char * -gname_lookup(void *d, int64_t g) -{ - (void)d; /* UNUSED */ - (void)g; /* UNUSED */ - return ("FOOGROUP"); -} - -static const char * -uname_lookup(void *d, int64_t u) -{ - (void)d; /* UNUSED */ - (void)u; /* UNUSED */ - return ("FOO"); -} - -DEFINE_TEST(test_read_disk_entry_from_file) -{ - struct archive *a; - struct archive_entry *entry; - FILE *f; - - assert((a = archive_read_disk_new()) != NULL); - - assertEqualInt(ARCHIVE_OK, archive_read_disk_set_uname_lookup(a, - NULL, &uname_lookup, NULL)); - assertEqualInt(ARCHIVE_OK, archive_read_disk_set_gname_lookup(a, - NULL, &gname_lookup, NULL)); - assertEqualString(archive_read_disk_uname(a, 0), "FOO"); - assertEqualString(archive_read_disk_gname(a, 0), "FOOGROUP"); - - /* Create a file on disk. */ - f = fopen("foo", "wb"); - assert(f != NULL); - assertEqualInt(4, fwrite("1234", 1, 4, f)); - fclose(f); - - /* Use archive_read_disk_entry_from_file to get information about it. */ - entry = archive_entry_new(); - assert(entry != NULL); - archive_entry_copy_pathname(entry, "foo"); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, entry, -1, NULL)); - - /* Verify the information we got back. */ - assertEqualString(archive_entry_uname(entry), "FOO"); - assertEqualString(archive_entry_gname(entry), "FOOGROUP"); - assertEqualInt(archive_entry_size(entry), 4); - - /* Destroy the archive. */ - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_extract.c b/thirdparty/libarchive/libarchive/test/test_read_extract.c deleted file mode 100644 index da0f2265a..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_extract.c +++ /dev/null @@ -1,167 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_extract.c 201247 2009-12-30 05:59:21Z kientzle $"); - -#define BUFF_SIZE 1000000 -#define FILE_BUFF_SIZE 100000 - -DEFINE_TEST(test_read_extract) -{ - struct archive_entry *ae; - struct archive *a; - size_t used; - int i, numEntries = 0; - char *buff, *file_buff; - - buff = malloc(BUFF_SIZE); - file_buff = malloc(FILE_BUFF_SIZE); - - /* Force the umask to something predictable. */ - assertUmask(022); - - /* Create a new archive in memory containing various types of entries. */ - assert((a = archive_write_new()) != NULL); - assertA(0 == archive_write_set_format_ustar(a)); - assertA(0 == archive_write_add_filter_none(a)); - assertA(0 == archive_write_open_memory(a, buff, BUFF_SIZE, &used)); - /* A directory to be restored with EXTRACT_PERM. */ - ++numEntries; - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "dir_0775"); - archive_entry_set_mode(ae, S_IFDIR | 0775); - assertA(0 == archive_write_header(a, ae)); - archive_entry_free(ae); - /* A regular file. */ - ++numEntries; - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file"); - archive_entry_set_mode(ae, S_IFREG | 0755); - fill_with_pseudorandom_data(file_buff, FILE_BUFF_SIZE); - archive_entry_set_size(ae, FILE_BUFF_SIZE); - assertA(0 == archive_write_header(a, ae)); - assertA(FILE_BUFF_SIZE == archive_write_data(a, file_buff, FILE_BUFF_SIZE)); - archive_entry_free(ae); - /* A directory that should obey umask when restored. */ - ++numEntries; - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "dir"); - archive_entry_set_mode(ae, S_IFDIR | 0777); - assertA(0 == archive_write_header(a, ae)); - archive_entry_free(ae); - /* A file in the directory. */ - ++numEntries; - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "dir/file"); - archive_entry_set_mode(ae, S_IFREG | 0700); - assertA(0 == archive_write_header(a, ae)); - archive_entry_free(ae); - /* A file in a dir that is not already in the archive. */ - ++numEntries; - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "dir2/file"); - archive_entry_set_mode(ae, S_IFREG | 0000); - assertA(0 == archive_write_header(a, ae)); - archive_entry_free(ae); - /* A dir with a trailing /. */ - ++numEntries; - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "dir3/."); - archive_entry_set_mode(ae, S_IFDIR | 0710); - assertA(0 == archive_write_header(a, ae)); - archive_entry_free(ae); - /* Multiple dirs with a single entry. */ - ++numEntries; - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "dir4/a/../b/../c/"); - archive_entry_set_mode(ae, S_IFDIR | 0711); - assertA(0 == archive_write_header(a, ae)); - archive_entry_free(ae); - /* A symlink. */ - if (canSymlink()) { - ++numEntries; - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "symlink"); - archive_entry_set_mode(ae, AE_IFLNK | 0755); - archive_entry_set_symlink(ae, "file"); - assertA(0 == archive_write_header(a, ae)); - archive_entry_free(ae); - } - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Extract the entries to disk. */ - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_open_memory(a, buff, BUFF_SIZE)); - /* Restore first entry with _EXTRACT_PERM. */ - failure("Error reading first entry"); - assertA(0 == archive_read_next_header(a, &ae)); - assertA(0 == archive_read_extract(a, ae, ARCHIVE_EXTRACT_PERM)); - /* Rest of entries get restored with no flags. */ - for (i = 1; i < numEntries; i++) { - failure("Error reading entry %d", i); - assertA(0 == archive_read_next_header(a, &ae)); - failure("Failed to extract entry %d: %s", i, - archive_entry_pathname(ae)); - assertA(0 == archive_read_extract(a, ae, 0)); - } - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* Test the entries on disk. */ - /* This first entry was extracted with ARCHIVE_EXTRACT_PERM, - * so the permissions should have been restored exactly, - * including resetting the gid bit on those platforms - * where gid is inherited by subdirs. */ - failure("This was 0775 in archive, and should be 0775 on disk"); - assertIsDir("dir_0775", 0775); - /* Everything else was extracted without ARCHIVE_EXTRACT_PERM, - * so there may be some sloppiness about gid bits on directories. */ - assertIsReg("file", 0755); - assertFileSize("file", FILE_BUFF_SIZE); - assertFileContents(file_buff, FILE_BUFF_SIZE, "file"); - /* If EXTRACT_PERM wasn't used, be careful to ignore sgid bit - * when checking dir modes, as some systems inherit sgid bit - * from the parent dir. */ - failure("This was 0777 in archive, but umask should make it 0755"); - assertIsDir("dir", 0755); - assertIsReg("dir/file", 0700); - assertIsDir("dir2", 0755); - assertIsReg("dir2/file", 0000); - assertIsDir("dir3", 0710); - assertIsDir("dir4", 0755); - assertIsDir("dir4/a", 0755); - assertIsDir("dir4/b", 0755); - assertIsDir("dir4/c", 0711); - if (canSymlink()) - assertIsSymlink("symlink", "file", 0); - - free(buff); - free(file_buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_file_nonexistent.c b/thirdparty/libarchive/libarchive/test/test_read_file_nonexistent.c deleted file mode 100644 index acb72a1e3..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_file_nonexistent.c +++ /dev/null @@ -1,37 +0,0 @@ -/*- - * Copyright (c) 2003-2009 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_file_nonexistent.c 189473 2009-03-07 02:09:21Z kientzle $"); - -DEFINE_TEST(test_read_file_nonexistent) -{ - struct archive* a = archive_read_new(); - assertEqualInt(ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualInt(ARCHIVE_FATAL, - archive_read_open_filename(a, "notexistent.tar", 512)); - archive_read_free(a); -} - - diff --git a/thirdparty/libarchive/libarchive/test/test_read_filter_compress.c b/thirdparty/libarchive/libarchive/test/test_read_filter_compress.c deleted file mode 100644 index 03a1d5fbe..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_filter_compress.c +++ /dev/null @@ -1,80 +0,0 @@ -/*- - * Copyright (c) 2003-2008 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -DEFINE_TEST(test_read_filter_compress_truncated) -{ - const char data[] = {0x1f, 0x9d}; - struct archive *a; - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_compress(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_FATAL, - archive_read_open_memory(a, data, sizeof(data))); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - -DEFINE_TEST(test_read_filter_compress_empty2) -{ - const char data[] = {0x1f, 0x9d, 0x10}; - struct archive *a; - struct archive_entry *ae; - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_compress(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, data, sizeof(data))); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify that the format detection worked. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS); - assertEqualString(archive_filter_name(a, 0), "compress (.Z)"); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_EMPTY); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - -DEFINE_TEST(test_read_filter_compress_invalid) -{ - const char data[] = {0x1f, 0x9d, 0x11}; - struct archive *a; - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_compress(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_FATAL, - archive_read_open_memory(a, data, sizeof(data))); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_filter_grzip.c b/thirdparty/libarchive/libarchive/test/test_read_filter_grzip.c deleted file mode 100644 index 43bd5bca2..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_filter_grzip.c +++ /dev/null @@ -1,67 +0,0 @@ -/*- - * Copyright (c) 2003-2008 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -DEFINE_TEST(test_read_filter_grzip) -{ - const char *name = "test_read_filter_grzip.tar.grz"; - /* grzip tracks directories as files, ensure that we list everything */ - const char *n[] = { - "f1", "f2", "f3", "d1/f1", "d1/f2", "d1/f3", NULL }; - struct archive_entry *ae; - struct archive *a; - int i; - - if (!canGrzip()) { - skipping("grzip command-line program not found"); - return; - } - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_WARN, archive_read_support_filter_grzip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - extract_reference_file(name); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, name, 200)); - - /* Read entries, match up names with list above. */ - for (i = 0; n[i] != NULL; ++i) { - failure("Could not read file %d (%s) from %s", i, n[i], name); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_next_header(a, &ae)); - assertEqualString(n[i], archive_entry_pathname(ae)); - } - - /* Verify the end-of-archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify that the format detection worked. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_GRZIP); - assertEqualString(archive_filter_name(a, 0), "grzip"); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_filter_grzip.tar.grz.uu b/thirdparty/libarchive/libarchive/test/test_read_filter_grzip.tar.grz.uu deleted file mode 100644 index 3f55b9347..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_filter_grzip.tar.grz.uu +++ /dev/null @@ -1,8 +0,0 @@ -begin 644 test_read_filter_grzip.tar.grz -M1U)::7!)20`"!#HI`!P``*P,```L`0``\````)D```#Y.$+F+B8PQP#^C=PP -MI/#7H?$H,(_!0<=O!,4![T/;;'S,=B0_3(R1=9"=YKA%RKR-\,+PJIO2]!I*2V31X]P[DN$GOEND]NJE=5AP+]64N7$3):G02EKP>+AD`!IH`HQ(` -M```R#$'@#E`G"/SW..;YC%X%73G3%U_;&GA#Y7N&P\[%?V!^'>:#?(>JQW** -M1]!%JV?=U`TD.@:H85S[7D\VH/]%6JQ>/;HI.E&)I2N1_M4BU:942T`-IN<9%AZFZVY]'A)5%EY;Y0S/4MGN]Y -D9.U/9Y/!R!PQ$O_\1>]J_8\^I0",9(YV]K_!A:WK9='*J7,1 -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_filter_lzop.c b/thirdparty/libarchive/libarchive/test/test_read_filter_lzop.c deleted file mode 100644 index acce6a4c2..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_filter_lzop.c +++ /dev/null @@ -1,77 +0,0 @@ -/*- - * Copyright (c) 2003-2008 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -DEFINE_TEST(test_read_filter_lzop) -{ - const char *reference = "test_read_filter_lzop.tar.lzo"; - /* lrzip tracks directories as files, ensure that we list everything */ - const char *n[] = { - "d1/", "d1/f2", "d1/f3", "d1/f1", "f1", "f2", "f3", NULL }; - struct archive_entry *ae; - struct archive *a; - int i, r; - - extract_reference_file(reference); - assert((a = archive_read_new()) != NULL); - r = archive_read_support_filter_lzop(a); - if (r != ARCHIVE_OK) { - if (!canLzop()) { - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - skipping("lzop compression is not supported " - "on this platform"); - return; - } else if (r != ARCHIVE_WARN) { - assertEqualIntA(a, ARCHIVE_OK, r); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, reference, 10240)); - - /* Read entries, match up names with list above. */ - for (i = 0; n[i] != NULL; ++i) { - failure("Could not read file %d (%s) from %s", - i, n[i], reference); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_next_header(a, &ae)); - assertEqualString(n[i], archive_entry_pathname(ae)); - } - - /* Verify the end-of-archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify that the format detection worked. */ - assertEqualInt(archive_filter_count(a), 2); - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_LZOP); - assertEqualString(archive_filter_name(a, 0), "lzop"); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_filter_lzop.tar.lzo.uu b/thirdparty/libarchive/libarchive/test/test_read_filter_lzop.tar.lzo.uu deleted file mode 100644 index d5fcc3026..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_filter_lzop.tar.lzo.uu +++ /dev/null @@ -1,11 +0,0 @@ -begin 664 test_read_filter_lzop.tar.lzo -MB4Q:3P`-"AH*$#`@8`E``04#```!``"!M%!PQ.T`````&71E`V0Q+P```"`]```+,#`P -M-S@'A`L@%/T',"``1OT'9B`_\P<````@#?T'-W__-C8V(`!'_`<@ -M/_`?(!?]!S<@`$?\!R`_\!\@%OT'-R``1_P7@/0@````RA````$````````` -3````````````````$0`````````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_filter_lzop_multiple_parts.c b/thirdparty/libarchive/libarchive/test/test_read_filter_lzop_multiple_parts.c deleted file mode 100644 index 82eaf3539..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_filter_lzop_multiple_parts.c +++ /dev/null @@ -1,76 +0,0 @@ -/*- - * Copyright (c) 2003-2008 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -DEFINE_TEST(test_read_filter_lzop_multiple_parts) -{ - const char *reference = "test_read_filter_lzop_multiple_parts.tar.lzo"; - struct archive_entry *ae; - struct archive *a; - int r; - - extract_reference_file(reference); - assert((a = archive_read_new()) != NULL); - r = archive_read_support_filter_lzop(a); - if (r != ARCHIVE_OK) { - if (!canLzop()) { - skipping("lzop compression is not supported " - "on this platform"); - } else if (r == ARCHIVE_WARN) { - skipping("lzop multiple parts decoding is not " - "supported via external program"); - - } else - assertEqualIntA(a, ARCHIVE_OK, r); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, reference, 10240)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("file1", archive_entry_pathname(ae)); - assertEqualInt(19, archive_entry_size(ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("file2", archive_entry_pathname(ae)); - assertEqualInt(262144, archive_entry_size(ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("file3", archive_entry_pathname(ae)); - assertEqualInt(19, archive_entry_size(ae)); - - /* Verify the end-of-archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify that the format detection worked. */ - assertEqualInt(archive_filter_count(a), 2); - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_LZOP); - assertEqualString(archive_filter_name(a, 0), "lzop"); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_filter_lzop_multiple_parts.tar.lzo.uu b/thirdparty/libarchive/libarchive/test/test_read_filter_lzop_multiple_parts.tar.lzo.uu deleted file mode 100644 index 4f8fcbf06..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_filter_lzop_multiple_parts.tar.lzo.uu +++ /dev/null @@ -1,89 +0,0 @@ -begin 664 test_read_filter_lzop_multiple_parts.tar.lzo -MB4Q:3P`-"AH*$#`@8`E``04#```!``"!M%"`KW@`````"W1E?S4W(`!&_`\@/N@'(``````` -M`````````````````````````````````````)!X`0X````````````````` -M`````!$```````")3%I/``T*&@H0,"!@"4`!!0,```$``(&T4("O>``````+ -M=&5S=%]L>F]P86)^0`CR```H`````$DH```!`@``````(``````````````` -M`````````````````````````````````````.X0```!```````````````` -M`````````!$```````")3%I/``T*&@H0,"!@"4`!!0,```$``(&T4("O>``` -M```+=&5S=%]L>F]P86-^00CS```H`````$DH```!`@``````(``````````` -M`````````````````````````````````````````.X0```!```````````` -M`````````````!$```````")3%I/``T*&@H0,"!@"4`!!0,```$``(&T4("O -M>``````+=&5S=%]L>F]P861^0@CT```H`````$DH```!`@``````(``````` -M`````````````````````````````````````````````.X0```!```````` -M`````````````````!$```````")3%I/``T*&@H0,"!@"4`!!0,```$``(&T -M4("O>``````+=&5S=%]L>F]P865^0PCU```H`````$DH```!`@``````(``` -M`````````````````````````````````````````````````.X0```!```` -M`````````````````````!$```````")3%I/``T*&@H0,"!@"4`!!0,```$` -M`(&T4("O>``````+=&5S=%]L>F]P869^1`CV```H`````$DH```!`@`````` -M(````````````````````````````````````````````````````.X0```! -M`````````````````````````!$```````")3%I/``T*&@H0,"!@"4`!!0,` -M``$``(&T4("O>``````+=&5S=%]L>F]P86=^10CW```H`````$DH```!`@`` -M````(````````````````````````````````````````````````````.X0 -M```!`````````````````````````!$```````")3%I/``T*&@H0,"!@"4`! -M!0,```$``(&T4("O>``````+=&5S=%]L>F]P86A^1@CX```H`````$DH```! -M`@``````(``````````````````````````````````````````````````` -M`.X0```!`````````````````````````!$```````")3%I/``T*&@H0,"!@ -M"4`!!0,```$``(&T4("O>``````+=&5S=%]L>F]P86E^1PCY```H`````$DH -M```!`@``````(``````````````````````````````````````````````` -M`````.X0```!`````````````````````````!$```````")3%I/``T*&@H0 -M,"!@"4`!!0,```$``(&T4("O>``````+=&5S=%]L>F]P86I^2`CZ```H```` -M`$DH```!`@``````(``````````````````````````````````````````` -M`````````.X0```!`````````````````````````!$```````")3%I/``T* -M&@H0,"!@"4`!!0,```$``(&T4("O>``````+=&5S=%]L>F]P86M^20C[```H -M`````$DH```!`@``````(``````````````````````````````````````` -M`````````````.X0```!`````````````````````````!$```````")3%I/ -M``T*&@H0,"!@"4`!!0,```$``(&T4("O>``````+=&5S=%]L>F]P86Q^2@C\ -M```H`````$DH```!`@``````(``````````````````````````````````` -M`````````````````.X0```!`````````````````````````!$```````") -M3%I/``T*&@H0,"!@"4`!!0,```$``(&T4("O>``````+=&5S=%]L>F]P86U^ -M2PC]```H`````$DH```!`@``````(``````````````````````````````` -M`````````````````````.X0```!`````````````````````````!$````` -M``")3%I/``T*&@H0,"!@"4`!!0,```$``(&T4("O>``````+=&5S=%]L>F]P -M86Y^3`C^```H`````$DH```!`@``````(``````````````````````````` -M`````````````````````````.X0```!`````````````````````````!$` -M``````")3%I/``T*&@H0,"!@"4`!!0,```$``(&T4("O>``````+=&5S=%]L -M>F]P86]^30C_```H`````$DH```!`@``````(``````````````````````` -M`````````````````````````````.X0```!```````````````````````` -M`!$```````")3%I/``T*&@H0,"!@"4`!!0,```$``(&T4("O>``````+=&5S -M=%]L>F]P87!^3@D````H`````$DH```!`@``````(``````````````````` -M`````````````````````````````````.X0```!```````````````````` -M`````!$```````")3%I/``T*&@H0,"!@"4`!!0,```$``(&T4("O>``````+ -M=&5S=%]L>F]P87%^3PD!```H`````$DH```!`@``````(``````````````` -M`````````````````````````````````````.X0```!```````````````` -M`````````!$```````")3%I/``T*&@H0,"!@"4`!!0,```$``(&T4("O>``` -M```+=&5S=%]L>F]P87)^4`D"```H`````$DH```!`@``````(``````````` -M`````````````````````````````````````````.X0```!```````````` -M`````````````!$```````")3%I/``T*&@H0,"!@"4`!!0,```$``(&T4("O -M>``````+=&5S=%]L>F]P87-^40D#```H`````$DH```!`@``````(``````` -M`````````````````````````````````````````````.X0```!```````` -M`````````````````!$```````")3%I/``T*&@H0,"!@"4`!!0,```$``(&T -M4("O>``````+=&5S=%]L>F]P871^4@D$```H`````$DH```!`@``````(``` -M`````````````````````````````````````````````````.X0```!```` -M`````````````````````!$```````")3%I/``T*&@H0,"!@"4`!!0,```$` -M`(&T4("O>``````+=&5S=%]L>F]P875^4PD%```H`````$DH```!`@`````` -M(````````````````````````````````````````````````````.X0```! -M`````````````````````````!$```````")3%I/``T*&@H0,"!@"4`!!0,` -M``$``(&T4("O>``````+=&5S=%]L>F]P879^5`D&```H`````$DH```!`@`` -M````(````````````````````````````````````````````````````.X0 -M```!`````````````````````````!$```````")3%I/``T*&@H0,"!@"4`! -M!0,```$``(&T4("O>``````+=&5S=%]L>F]P87=^50D'```H`````$DH```! -M`@``````(``````````````````````````````````````````````````` -M`.X0```!`````````````````````````!$```````")3%I/``T*&@H0,"!@ -M"4`!!0,```$``(&T4("O>``````+=&5S=%]L>F]P87A^5@D(```H`````$DH -M```!`@``````(``````````````````````````````````````````````` -M`````.X0```!`````````````````````````!$```````")3%I/``T*&@H0 -M,"!@"4`!!0,```$``(&T4("O>``````+=&5S=%]L>F]P87E^5PD)```H```` -M`$DH```!`@``````(``````````````````````````````````````````` -M`````````.X0```!`````````````````````````!$```````")3%I/``T* -M&@H0,"!@"4`!!0,```$``(&T4("O>``````+=&5S=%]L>F]P87I^6`D*```F -M`````+OSXAG6`@``````(``````````````````````````````````````` -M]Q```F9I;&4S(#[\=PLP,#`V-C0@`#`P,3/1A2\n" -"IHU\"0%9=*G4JUJM6K6+-JWO8,.*'4NVK-FS:-.J7\n" -"Received: from libarchive (localhost [127.0.0.1])\n" -" by libarchive (8.14.2/8.14.2) with ESMTP id m5233UT1006448\n" -" for ; Mon, 2 Jun 2008 03:03:31 GMT\n" -" (envelope-from uudecode@libarchive)\n" -"Received: (from uudecode@localhost)\n" -" by libarchive (8.14.2/8.14.2/Submit) id m5233U3e006406\n" -" for uudecode; Mon, 2 Jun 2008 03:03:30 GMT\n" -" (envelope-from root)\n" -"Date: Mon, 2 Jun 2008 03:03:30 GMT\n" -"From: Libarchive Test \n" -"Message-Id: <200806020303.m5233U3e006406@libarchive>\n" -"To: uudecode@libarchive\n" -"Subject: Libarchive uudecode test\n" -"\n" -"* Redistribution and use in source and binary forms, with or without\n" -"* modification, are permitted provided that the following conditions\n" -"* are met:\n" -"\n" -"01234567890abcdeghijklmnopqrstuvwxyz\n" -"01234567890ABCEFGHIJKLMNOPQRSTUVWXYZ\n" -"\n" -}; - -static void -test_read_uu_sub(const char *uudata, size_t uusize, int no_nl) -{ - struct archive_entry *ae; - struct archive *a; - char *buff; - char extradata_no_nl[sizeof(extradata)]; - const char *extradata_ptr; - int extra; - size_t size; - - if (no_nl) { - /* Remove '\n' from extra data to make a very long line. */ - char *p; - memcpy(extradata_no_nl, extradata, sizeof(extradata)); - extradata_ptr = extradata_no_nl; - for (p = extradata_no_nl; - *p && (p = strchr(p, '\n')) != NULL; p++) - *p = ' ';/* Replace '\n' with ' ' a space character. */ - } else - extradata_ptr = extradata; - - assert(NULL != (buff = malloc(uusize + 1024 * 1024))); - if (buff == NULL) - return; - for (extra = 0; extra <= 64; extra = extra==0?1:extra*2) { - char *p = buff; - - size = extra * 1024; - /* Add extra text size of which is from 1K bytes to - * 64Kbytes before uuencoded data. */ - while (size) { - if (size > sizeof(extradata)-1) { - memcpy(p, extradata_ptr, sizeof(extradata)-1); - p += sizeof(extradata)-1; - size -= sizeof(extradata)-1; - } else { - memcpy(p, extradata_ptr, size-1); - p += size-1; - *p++ = '\n';/* the last of extra text must have - * '\n' character. */ - break; - } - } - memcpy(p, uudata, uusize); - size = extra * 1024 + uusize; - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - read_open_memory(a, buff, size, 2)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_next_header(a, &ae)); - failure("archive_filter_name(a, 0)=\"%s\"" - "extra %d, NL %d", - archive_filter_name(a, 0), extra, !no_nl); - assertEqualInt(archive_filter_code(a, 0), - ARCHIVE_FILTER_COMPRESS); - failure("archive_format_name(a)=\"%s\"" - "extra %d, NL %d", - archive_format_name(a), extra, !no_nl); - assertEqualInt(archive_format(a), - ARCHIVE_FORMAT_TAR_USTAR); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - } - - /* UUdecode bidder shouldn't scan too much data; make sure it - * fails if we put 512k of data before the start. */ - size = 512 * 1024; - for (extra = 0; (size_t)extra < size; ++extra) - buff[extra + 1024] = buff[extra]; - buff[size - 1] = '\n'; - memcpy(buff + size, uudata, uusize); - size += uusize; - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_FATAL, - read_open_memory(a, buff, size, 2)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - free(buff); -} - -DEFINE_TEST(test_read_filter_uudecode) -{ - /* Read the traditional uuencoded data. */ - test_read_uu_sub(archive, sizeof(archive)-1, 0); - /* Read the traditional uuencoded data with very long line extra - * data in front of it. */ - test_read_uu_sub(archive, sizeof(archive)-1, 1); -} - -DEFINE_TEST(test_read_filter_uudecode_base64) -{ - /* Read the Base64 uuencoded data. */ - test_read_uu_sub(archive64, sizeof(archive64)-1, 0); - /* Read the Base64 uuencoded data with very long line extra data - * in front of it. */ - test_read_uu_sub(archive64, sizeof(archive64)-1, 1); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_filter_uudecode_base64_raw.uu b/thirdparty/libarchive/libarchive/test/test_read_filter_uudecode_base64_raw.uu deleted file mode 100644 index b4ddfb0a2..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_filter_uudecode_base64_raw.uu +++ /dev/null @@ -1,11 +0,0 @@ -begin-base64 600 LICENSE2.txt -VEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIOKAnEFTIElT4oCdLCBXSVRIT1VUIFdBUlJBTlRZIE9G -IEFOWSBLSU5ELCBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQg -VE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJ -Q1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUg -QVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFN -QUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNU -LCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElP -TiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBT -T0ZUV0FSRS4K -==== diff --git a/thirdparty/libarchive/libarchive/test/test_read_filter_uudecode_raw.c b/thirdparty/libarchive/libarchive/test/test_read_filter_uudecode_raw.c deleted file mode 100644 index 6f02dc5de..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_filter_uudecode_raw.c +++ /dev/null @@ -1,67 +0,0 @@ -/*- - * Copyright (c) 2023 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -DEFINE_TEST(test_read_filter_uudecode_raw) -{ - struct archive_entry *ae; - struct archive *a; - - const char *name = "test_read_filter_uudecode_raw.uu"; - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_raw(a)); - copy_reference_file(name); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 670)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("LICENSE.txt", archive_entry_pathname(ae)); - assertEqualInt((AE_IFREG | 0755), archive_entry_mode(ae)); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_filter_uudecode_base64_raw) -{ - struct archive_entry *ae; - struct archive *a; - - const char *name = "test_read_filter_uudecode_base64_raw.uu"; - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_raw(a)); - copy_reference_file(name); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 670)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("LICENSE2.txt", archive_entry_pathname(ae)); - assertEqualInt((AE_IFREG | 0600), archive_entry_mode(ae)); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_filter_uudecode_raw.uu b/thirdparty/libarchive/libarchive/test/test_read_filter_uudecode_raw.uu deleted file mode 100644 index 8a5f8b5a6..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_filter_uudecode_raw.uu +++ /dev/null @@ -1,14 +0,0 @@ -begin 755 LICENSE.txt -M5$A%(%-/1E1705)%($E3(%!23U9)1$5$(.*`G$%3($E3XH"=+"!7251(3U54 -M(%=!4E)!3E19($]&($%.62!+24Y$+"!%6%!215-3($]2($E-4$Q)140L($E. -M0TQ51$E.1R!"550@3D]4($Q)34E4140@5$\@5$A%(%=!4E)!3E1)15,@3T8@ -M34520TA!3E1!0DE,2519+"!&251.15-3($9/4B!!(%!!4E1)0U5,05(@4%52 -M4$]312!!3D0@3D].24Y&4DE.1T5-14Y4+B!)3B!.3R!%5D5.5"!32$%,3"!4 -M2$4@05542$]24R!/4B!#3U!94DE'2%0@2$],1$524R!"12!,24%"3$4@1D]2 -M($%.62!#3$%)32P@1$%-04=%4R!/4B!/5$A%4B!,24%"24Q)5%DL(%=(151( -M15(@24X@04X@04-424].($]&($-/3E1204-4+"!43U)4($]2($]42$525TE3 -M12P@05))4TE.1R!&4D]-+"!/550@3T8@3U(@24X@0T].3D5#5$E/3B!7251( -M(%1(12!33T945T%212!/4B!42$4@55-%($]2($]42$52($1%04Q)3D=3($E. -/(%1(12!33T945T%212X* -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip.c b/thirdparty/libarchive/libarchive/test/test_read_format_7zip.c deleted file mode 100644 index 1249963ec..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip.c +++ /dev/null @@ -1,1260 +0,0 @@ -/*- - * Copyright (c) 2011 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD"); - -#if defined(_WIN32) && !defined(__CYGWIN__) -#define close _close -#define open _open -#endif - -#define __LIBARCHIVE_BUILD -#include - -/* - * Extract a non-encoded file. - * The header of the 7z archive files is not encoded. - */ -static void -test_copy(int use_open_fd) -{ - const char *refname = "test_read_format_7zip_copy.7z"; - struct archive_entry *ae; - struct archive *a; - char buff[128]; - int fd = -1; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (use_open_fd) { - fd = open(refname, O_RDONLY | O_BINARY); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_fd(a, fd, 10240)); - } else { - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - } - - /* Verify regular file1. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("file1", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(60, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assert(archive_read_has_encrypted_entries(a) > ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualInt(60, archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, " ", 4); - - assertEqualInt(1, archive_file_count(a)); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - if (fd != -1) - close(fd); -} - -/* - * An archive file has no entry. - */ -static void -test_empty_archive(void) -{ - const char *refname = "test_read_format_7zip_empty_archive.7z"; - struct archive_entry *ae; - struct archive *a; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - assertEqualInt(0, archive_file_count(a)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* - * An archive file has one empty file. It means there is no content - * in the archive file except for a header. - */ -static void -test_empty_file(void) -{ - const char *refname = "test_read_format_7zip_empty_file.7z"; - struct archive_entry *ae; - struct archive *a; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular empty. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("empty", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - assertEqualInt(1, archive_file_count(a)); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* - * Extract an encoded file. - * The header of the 7z archive files is not encoded. - */ -static void -test_plain_header(const char *refname) -{ - struct archive_entry *ae; - struct archive *a; - char buff[128]; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file1. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("file1", archive_entry_pathname(ae)); - assertEqualInt(1322058763, archive_entry_mtime(ae)); - assertEqualInt(2844, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualInt(sizeof(buff), archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, "The libarchive distribution ", 28); - - assertEqualInt(1, archive_file_count(a)); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* - * Extract multi files. - * The header of the 7z archive files is encoded with LZMA. - */ -static void -test_extract_all_files(const char *refname) -{ - struct archive_entry *ae; - struct archive *a; - char buff[128]; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file1. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("dir1/file1", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(13, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualInt(13, archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, "aaaaaaaaaaaa\n", 13); - - /* Verify regular file2. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("file2", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(26, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualInt(26, archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\n", 26); - - /* Verify regular file3. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("file3", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(39, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualInt(39, archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\n", 39); - - /* Verify regular file4. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("file4", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(52, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualInt(52, archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, - "aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\ndddddddddddd\n", 52); - - /* Verify directory dir1. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFDIR | 0755), archive_entry_mode(ae)); - assertEqualString("dir1/", archive_entry_pathname(ae)); - assertEqualInt(2764801, archive_entry_mtime(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - assertEqualInt(5, archive_file_count(a)); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* - * Extract multi files. - * Like test_extract_all_files, but with zstandard compression. - */ -static void -test_extract_all_files_zstd(const char *refname) -{ - struct archive_entry *ae; - struct archive *a; - char buff[128]; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify directory dir1. Note that this comes before the dir1/file1 entry in recent versions of 7-Zip. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFDIR | 0755), archive_entry_mode(ae)); - assertEqualString("dir1/", archive_entry_pathname(ae)); - assertEqualInt(2764801, archive_entry_mtime(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Verify regular file1. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("dir1/file1", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(13, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualInt(13, archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, "aaaaaaaaaaaa\n", 13); - - /* Verify regular file2. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("file2", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(26, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualInt(26, archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\n", 26); - - /* Verify regular file3. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("file3", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(39, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualInt(39, archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\n", 39); - - /* Verify regular file4. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("file4", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(52, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualInt(52, archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, - "aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\ndddddddddddd\n", 52); - - assertEqualInt(5, archive_file_count(a)); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* - * Extract file from an archives using ZSTD compression with and without BCJ. - */ -static void -test_extract_file_zstd_bcj_nobjc(const char *refname) -{ - struct archive_entry *ae; - struct archive *a; - char buff[4096]; - uint32_t computed_crc = 0; - uint32_t expected_crc = 0xbd66eebc; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file: hw. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0775), archive_entry_mode(ae)); - assertEqualString("hw", archive_entry_pathname(ae)); - assertEqualInt(1685913368, archive_entry_mtime(ae)); - assertEqualInt(15952, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - for (;;) { - la_ssize_t bytes_read = archive_read_data(a, buff, sizeof(buff)); - assert(bytes_read >= 0); - if (bytes_read == 0) break; - computed_crc = crc32(computed_crc, buff, bytes_read); - } - assertEqualInt(computed_crc, expected_crc); - - assertEqualInt(1, archive_file_count(a)); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* - * Extract last file. - * The header of the 7z archive files is encoded with LZMA. - */ -static void -test_extract_last_file(const char *refname) -{ - struct archive_entry *ae; - struct archive *a; - char buff[128]; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file1. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("dir1/file1", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(13, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Verify regular file2. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("file2", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(26, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Verify regular file3. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("file3", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(39, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Verify regular file4. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("file4", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(52, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualInt(52, archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, - "aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\ndddddddddddd\n", 52); - - /* Verify directory dir1. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFDIR | 0755), archive_entry_mode(ae)); - assertEqualString("dir1/", archive_entry_pathname(ae)); - assertEqualInt(2764801, archive_entry_mtime(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - assertEqualInt(5, archive_file_count(a)); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* - * Extract a mixed archive file which has both LZMA and LZMA2 encoded files. - * LZMA: file1, file2, file3, file4 - * LZMA2: zfile1, zfile2, zfile3, zfile4 - */ -static void -test_extract_all_files2(const char *refname) -{ - struct archive_entry *ae; - struct archive *a; - char buff[128]; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file1. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("dir1/file1", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(13, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualInt(13, archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, "aaaaaaaaaaaa\n", 13); - - /* Verify regular file2. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("file2", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(26, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualInt(26, archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\n", 26); - - /* Verify regular file3. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("file3", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(39, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualInt(39, archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\n", 39); - - /* Verify regular file4. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("file4", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(52, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualInt(52, archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, - "aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\ndddddddddddd\n", 52); - - /* Verify regular zfile1. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("dir1/zfile1", archive_entry_pathname(ae)); - assertEqualInt(5184001, archive_entry_mtime(ae)); - assertEqualInt(13, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualInt(13, archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, "aaaaaaaaaaaa\n", 13); - - /* Verify regular zfile2. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("zfile2", archive_entry_pathname(ae)); - assertEqualInt(5184001, archive_entry_mtime(ae)); - assertEqualInt(26, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualInt(26, archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\n", 26); - - /* Verify regular zfile3. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("zfile3", archive_entry_pathname(ae)); - assertEqualInt(5184001, archive_entry_mtime(ae)); - assertEqualInt(39, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualInt(39, archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\n", 39); - - /* Verify regular zfile4. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("zfile4", archive_entry_pathname(ae)); - assertEqualInt(5184001, archive_entry_mtime(ae)); - assertEqualInt(52, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualInt(52, archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, - "aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\ndddddddddddd\n", 52); - - /* Verify directory dir1. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFDIR | 0755), archive_entry_mode(ae)); - assertEqualString("dir1/", archive_entry_pathname(ae)); - assertEqualInt(2764801, archive_entry_mtime(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - assertEqualInt(9, archive_file_count(a)); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* - * Extract a file compressed with DELTA + LZMA[12]. - */ -static void -test_delta_lzma(const char *refname) -{ - struct archive_entry *ae; - struct archive *a; - size_t remaining; - ssize_t bytes; - char buff[1024]; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file1. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("file1", archive_entry_pathname(ae)); - assertEqualInt(172802, archive_entry_mtime(ae)); - assertEqualInt(27627, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - remaining = (size_t)archive_entry_size(ae); - while (remaining) { - if (remaining < sizeof(buff)) - assertEqualInt(remaining, - bytes = archive_read_data(a, buff, sizeof(buff))); - else - assertEqualInt(sizeof(buff), - bytes = archive_read_data(a, buff, sizeof(buff))); - if (bytes > 0) - remaining -= bytes; - else - break; - } - assertEqualInt(0, remaining); - - assertEqualInt(1, archive_file_count(a)); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* - * Extract a file compressed with BCJ + LZMA2. - */ -static void -test_bcj(const char *refname) -{ - struct archive_entry *ae; - struct archive *a; - size_t remaining; - ssize_t bytes; - char buff[1024]; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular x86exe. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0444), archive_entry_mode(ae) & ~0111); - assertEqualString("x86exe", archive_entry_pathname(ae)); - assertEqualInt(172802, archive_entry_mtime(ae)); - assertEqualInt(27328, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - remaining = (size_t)archive_entry_size(ae); - while (remaining) { - if (remaining < sizeof(buff)) - assertEqualInt(remaining, - bytes = archive_read_data(a, buff, sizeof(buff))); - else - assertEqualInt(sizeof(buff), - bytes = archive_read_data(a, buff, sizeof(buff))); - if (bytes > 0) - remaining -= bytes; - else - break; - } - assertEqualInt(0, remaining); - - assertEqualInt(1, archive_file_count(a)); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* - * Extract a file compressed with PPMd. - */ -static void -test_ppmd(void) -{ - const char *refname = "test_read_format_7zip_ppmd.7z"; - struct archive_entry *ae; - struct archive *a; - size_t remaining; - ssize_t bytes; - char buff[1024]; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file1. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("ppmd_test.txt", archive_entry_pathname(ae)); - assertEqualInt(1322464589, archive_entry_mtime(ae)); - assertEqualInt(102400, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - remaining = (size_t)archive_entry_size(ae); - while (remaining) { - if (remaining < sizeof(buff)) - assertEqualInt(remaining, - bytes = archive_read_data(a, buff, sizeof(buff))); - else - assertEqualInt(sizeof(buff), - bytes = archive_read_data(a, buff, sizeof(buff))); - if (bytes > 0) - remaining -= bytes; - else - break; - } - assertEqualInt(0, remaining); - - assertEqualInt(1, archive_file_count(a)); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -static void -test_symname(void) -{ - const char *refname = "test_read_format_7zip_symbolic_name.7z"; - struct archive_entry *ae; - struct archive *a; - char buff[128]; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file1. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("file1", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(32, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualInt(32, archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, "hellohellohello\nhellohellohello\n", 32); - - /* Verify symbolic-link symlinkfile. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFLNK | 0755), archive_entry_mode(ae)); - assertEqualString("symlinkfile", archive_entry_pathname(ae)); - assertEqualString("file1", archive_entry_symlink(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - assertEqualInt(2, archive_file_count(a)); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - -DEFINE_TEST(test_read_format_7zip) -{ - struct archive *a; - - assert((a = archive_read_new()) != NULL); - - /* Extracting with liblzma */ - if (ARCHIVE_OK != archive_read_support_filter_xz(a)) { - skipping("7zip:lzma decoding is not supported on this " - "platform"); - } else { - test_symname(); - test_extract_all_files("test_read_format_7zip_copy_2.7z"); - test_extract_last_file("test_read_format_7zip_copy_2.7z"); - test_extract_all_files2("test_read_format_7zip_lzma1_lzma2.7z"); - test_bcj("test_read_format_7zip_bcj2_copy_lzma.7z"); - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_7zip_bzip2) -{ - struct archive *a; - - assert((a = archive_read_new()) != NULL); - - /* Extracting with libbzip2 */ - if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) { - skipping("7zip:bzip2 decoding is not supported on this platform"); - } else { - test_plain_header("test_read_format_7zip_bzip2.7z"); - test_bcj("test_read_format_7zip_bcj_bzip2.7z"); - test_bcj("test_read_format_7zip_bcj2_bzip2.7z"); - } - - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_7zip_from_fd) -{ - test_copy(1);/* read a 7zip file from a file descriptor. */ -} - -DEFINE_TEST(test_read_format_7zip_copy) -{ - test_copy(0); - test_bcj("test_read_format_7zip_bcj_copy.7z"); - test_bcj("test_read_format_7zip_bcj2_copy_1.7z"); - test_bcj("test_read_format_7zip_bcj2_copy_2.7z"); -} - -DEFINE_TEST(test_read_format_7zip_deflate) -{ - struct archive *a; - - assert((a = archive_read_new()) != NULL); - - /* Extracting with libz */ - if (ARCHIVE_OK != archive_read_support_filter_gzip(a)) { - skipping( - "7zip:deflate decoding is not supported on this platform"); - } else { - test_plain_header("test_read_format_7zip_deflate.7z"); - test_bcj("test_read_format_7zip_bcj_deflate.7z"); - test_bcj("test_read_format_7zip_bcj2_deflate.7z"); - } - - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_7zip_zstd) -{ - struct archive *a; - - assert((a = archive_read_new()) != NULL); - - /* Extracting with libzstd */ - if (ARCHIVE_OK != archive_read_support_filter_zstd(a)) { - skipping( - "7zip:zstd decoding is not supported on this platform"); - } else { - test_extract_all_files_zstd("test_read_format_7zip_zstd.7z"); - } - - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_7zip_zstd_solid) -{ - struct archive *a; - - assert((a = archive_read_new()) != NULL); - - /* Extracting with libzstd */ - if (ARCHIVE_OK != archive_read_support_filter_zstd(a)) { - skipping( - "7zip:zstd decoding is not supported on this platform"); - } else { - test_extract_all_files_zstd("test_read_format_7zip_solid_zstd.7z"); - } - - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_7zip_zstd_bcj) -{ - struct archive *a; - - assert((a = archive_read_new()) != NULL); - - /* Extracting with libzstd */ - if (ARCHIVE_OK != archive_read_support_filter_zstd(a)) { - skipping( - "7zip:zstd decoding is not supported on this platform"); - } else { - test_extract_file_zstd_bcj_nobjc("test_read_format_7zip_zstd_bcj.7z"); - } - - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_7zip_zstd_nobcj) -{ - struct archive *a; - - assert((a = archive_read_new()) != NULL); - - /* Extracting with libzstd */ - if (ARCHIVE_OK != archive_read_support_filter_zstd(a)) { - skipping( - "7zip:zstd decoding is not supported on this platform"); - } else { - test_extract_file_zstd_bcj_nobjc("test_read_format_7zip_zstd_nobcj.7z"); - } - - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_7zip_empty) -{ - test_empty_archive(); - test_empty_file(); -} - -DEFINE_TEST(test_read_format_7zip_lzma1) -{ - struct archive *a; - - assert((a = archive_read_new()) != NULL); - - /* Extracting with liblzma */ - if (ARCHIVE_OK != archive_read_support_filter_xz(a)) { - skipping("7zip:lzma decoding is not supported on this " - "platform"); - } else { - test_plain_header("test_read_format_7zip_lzma1.7z"); - test_extract_all_files("test_read_format_7zip_lzma1_2.7z"); - test_extract_last_file("test_read_format_7zip_lzma1_2.7z"); - test_bcj("test_read_format_7zip_bcj_lzma1.7z"); - test_bcj("test_read_format_7zip_bcj2_lzma1_1.7z"); - test_bcj("test_read_format_7zip_bcj2_lzma1_2.7z"); - test_delta_lzma("test_read_format_7zip_delta_lzma1.7z"); - test_delta_lzma("test_read_format_7zip_delta4_lzma1.7z"); - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_7zip_lzma2) -{ - struct archive *a; - - assert((a = archive_read_new()) != NULL); - - /* Extracting with liblzma */ - if (ARCHIVE_OK != archive_read_support_filter_xz(a)) { - skipping("7zip:lzma decoding is not supported on this " - "platform"); - } else { - test_plain_header("test_read_format_7zip_lzma2.7z"); - test_bcj("test_read_format_7zip_bcj_lzma2.7z"); - test_bcj("test_read_format_7zip_bcj2_lzma2_1.7z"); - test_bcj("test_read_format_7zip_bcj2_lzma2_2.7z"); - test_delta_lzma("test_read_format_7zip_delta_lzma2.7z"); - test_delta_lzma("test_read_format_7zip_delta4_lzma2.7z"); - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -static void -test_arm_filter(const char *refname) -{ - struct archive *a; - struct archive_entry *ae; - char buff[7804]; - uint32_t computed_crc = 0; - uint32_t expected_crc = 0x355ec4e1; - - assert((a = archive_read_new()) != NULL); - - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0755), archive_entry_mode(ae)); - assertEqualString("hw-gnueabihf", archive_entry_pathname(ae)); - assertEqualInt(sizeof(buff), archive_entry_size(ae)); - assertEqualInt(sizeof(buff), archive_read_data(a, buff, sizeof(buff))); - computed_crc = crc32(computed_crc, buff, sizeof(buff)); - assertEqualInt(computed_crc, expected_crc); - - assertEqualInt(1, archive_file_count(a)); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_7zip_zstd_arm) -{ - struct archive *a; - - assert((a = archive_read_new()) != NULL); - - if (ARCHIVE_OK != archive_read_support_filter_zstd(a)) { - skipping( - "7zip:zstd decoding is not supported on this platform"); - } else { - test_arm_filter("test_read_format_7zip_zstd_arm.7z"); - } - - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_7zip_lzma2_arm) -{ - struct archive *a; - - assert((a = archive_read_new()) != NULL); - - if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) { - skipping( - "7zip:lzma decoding is not supported on this platform"); - } else { - test_arm_filter("test_read_format_7zip_lzma2_arm.7z"); - } - - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_7zip_ppmd) -{ - test_ppmd(); -} - -static void -test_arm64_filter(const char *refname) -{ - struct archive *a; - struct archive_entry *ae; - char buff[70368]; - uint32_t computed_crc = 0; - uint32_t expected_crc = 0xde97d594; - - assert((a = archive_read_new()) != NULL); - - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0775), archive_entry_mode(ae)); - assertEqualString("hw-arm64", archive_entry_pathname(ae)); - assertEqualInt(sizeof(buff), archive_entry_size(ae)); - assertEqualInt(sizeof(buff), archive_read_data(a, buff, sizeof(buff))); - computed_crc = crc32(computed_crc, buff, sizeof(buff)); - assertEqualInt(computed_crc, expected_crc); - - assertEqualInt(1, archive_file_count(a)); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_7zip_lzma2_arm64) -{ -#ifdef HAVE_LZMA_FILTER_ARM64 - struct archive *a; - - assert((a = archive_read_new()) != NULL); - - if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) { - skipping( - "7zip:lzma decoding is not supported on this platform"); - } else { - test_arm64_filter("test_read_format_7zip_lzma2_arm64.7z"); - } - - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -#else - skipping("This version of liblzma does not support LZMA_FILTER_ARM64"); -#endif -} - -DEFINE_TEST(test_read_format_7zip_deflate_arm64) -{ - struct archive *a; - - assert((a = archive_read_new()) != NULL); - - if (ARCHIVE_OK != archive_read_support_filter_gzip(a)) { - skipping( - "7zip:deflate decoding is not supported on this platform"); - } else { - test_arm64_filter("test_read_format_7zip_deflate_arm64.7z"); - } - - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_7zip_win_attrib) -{ - struct archive *a; - - assert((a = archive_read_new()) != NULL); - - if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) { - skipping( - "7zip:lzma decoding is not supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - - // This archive has four files and four directories: - // * hidden directory - // * readonly directory - // * regular directory - // * system directory - // * regular "archive" file - // * hidden file - // * readonly file - // * system file - const char *refname = "test_read_format_7zip_win_attrib.7z"; - extract_reference_file(refname); - - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - struct archive_entry *ae; - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("hidden_dir/", archive_entry_pathname(ae)); - assertEqualInt((AE_IFDIR | 0755), archive_entry_mode(ae)); - assertEqualString("hidden", archive_entry_fflags_text(ae)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("readonly_dir/", archive_entry_pathname(ae)); - assertEqualInt((AE_IFDIR | 0555), archive_entry_mode(ae)); - assertEqualString("rdonly", archive_entry_fflags_text(ae)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("regular_dir/", archive_entry_pathname(ae)); - assertEqualInt((AE_IFDIR | 0755), archive_entry_mode(ae)); - assertEqualString(NULL, archive_entry_fflags_text(ae)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("system_dir/", archive_entry_pathname(ae)); - assertEqualInt((AE_IFDIR | 0755), archive_entry_mode(ae)); - assertEqualString("system", archive_entry_fflags_text(ae)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("archive_file.txt", archive_entry_pathname(ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString(NULL, archive_entry_fflags_text(ae)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("hidden_file.txt", archive_entry_pathname(ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("hidden", archive_entry_fflags_text(ae)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("readonly_file.txt", archive_entry_pathname(ae)); - assertEqualInt((AE_IFREG | 0444), archive_entry_mode(ae)); - assertEqualString("rdonly", archive_entry_fflags_text(ae)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("system_file.txt", archive_entry_pathname(ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("system", archive_entry_fflags_text(ae)); - - - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj2_bzip2.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj2_bzip2.7z.uu deleted file mode 100644 index 274668fdf..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj2_bzip2.7z.uu +++ /dev/null @@ -1,319 +0,0 @@ -begin 644 test_read_format_7zip_bcj2_bzip2.7z -M-WJ\KR<<``,YXL&G`S<```````!>`````````$C?FIA"6F@Y,4%9)E-9C&3\ -MZP`=+'___________________________________________?_@)[]WN.@Y -MN[WWGA!"^MXV3U\]][O5\7FH?=.[UZ1!97.O<[>5=O;>*5N]KS+:A6>5[=[2 -MUTM;ELU16C6NV5@[9M>>6&-O<]NNG4S&[9ZQZ#>'J];=O;IC6EZ<[WN*7N]E -MEBW``T)`$3!&)E-H!,GJ,F`T!-HC)HPF)E,-!II-H1IZ!I&U4_4V%/*>)M*> -MGD*F]4;U&TI_H2>J'B1^E/TH]3]*/4_2/2C]%,GJ>F#5,@TTS2>H]3:ALHVI -MY3#0A-``1D$R;$C3:B93TE/P1ZI'E/TGJFV(4T?E/0-2?I(T]1M1^E'ZHVD/ -MQ4>FIH?JFCU&@#0T#0,U#3TRCU#U-I`#U`/2#U`'J8`````TT($$T$TFU,DT -MU/-1ZD]#3:DTV31Z$GI/2>H]3U-!H]3!J:&C$'HAD-#0-`#(T:!D!H&C0-`` -M]0``'I`&@`>4:`#0`)-*)":30$8F5/:IZ;4F]*>4_5/RGJ1ZGJ'I#)Z-1H]( -MV2/U0/*>H&@TT::/:H::;4](T/2#U!H/4:-`&@```!H9-`T`:``P```!34J` -M``-`,@>2``T```#(8`````````````````````````````D20C0":`3`)IZF -MFF29B)J>T",U4]J3T]32?JGZIZ'JGM#*1^J?JC\A-IIIJ1X$FU/4T?JAZ>J# -MU'M4T`T]3U/2>IZAH-/34-`-!D`#1Z(>DT/4&@:!A\XT_D?G;6M7LI5'/D_4 -M5!:+!L^"-EG&JTI?Y_`@OP*3XUF9P/L_=C'##4R`K*4N_E1B"`X528(`/PN` -M@R0XU*JI0#Z-Y')-CTZL1%CY)PX*E&,$6UI40B2D;I3$Y*DO2\FOB_$Y2*SX="VT,"D,9_WM -M-'M[6YU>^F`]VSZSUF/J#W4%B:B7N#?2E\,R(7K:8GD0E`$"$LR``!O4#'LS -M25_1^UY.=Z7]'K=ZX'-S>9Y%NWX]TXLCZ5[>OA9DSPI]HRGB-"%0NR) -MU0T`O6]%BM8?-5%6^9>%D&3UZ0L8&V_-LV&/19<`40*KMT!$)9O"6:QN+RM@ -MPR2W79W2PJ2!F9+6T-I8AN*]1`:A8.8?;O.UX<;=_L47Z._RLORW:W6#*?\K -M@X7X>/Y7F^A`_C\#PMI[;ZN7F.5&?;N+OG`;S -M+II-`+?<,(9\&#N>1JVL1NQ(;35U-1*E"@*05-!T=&BD5*$D`XB)[/DAQ6B' -MA@S](\SG;K5^QYJ[0$C,%>VTG&)*PU=#"@QU)Q>8C(8B>?8!_QL(EYM"E)U& -MW -M8US'PE8L55W,J8P&T+&:`]&MGT:^B^]FQQP:F?T4C6-4FC8:#1#4A&`LP#,C -M!B`8#`8`(!@(`$```:I'9*NUU6LM+"@T*RWKML&==V0E3J@[]4QV=P]:FI\K -MK;@S$-M9JVD<3-V*]QQ8Y.ALY`!M7#2ZYH`&Q(4S/>-*&!^X&HH%R/!@U6C5 -M:0BJ-+;-%ASWM.Z[FAR^N\&<[B7.>7U5,7E;"3?,.PZ5DF6"CQJ&G$L,,QBS -MWG2S+)HXMHGTJ*>0P-'QJ3F)X7FA=B?'?CV3LD/&(;8]FDZAGB.5"O,.2TD7[/MVC-S(.U:U -M?*@/=-<9F>UR6&V>VMPCRVLWVD!V?)YDLL:W3W;J]S"2Q,?G2`*!@V)ML$-I -MLQ6E2S/:U&EC-(R?+@6`Q%N:"MRH*_+@K4$=A7@+K2V;6[HVGLYEHN&N4S,: -MRVN7B]U)=E:UY`)?):2/&??L!>/V4>2^ZL<[T.;9[NIGOES=Y+QFEX31U9X2 -M2Z#)-YD(8`!JJJI`/,]*SI,/)^9L`/`O0[+Q^V:)NVZIU]RS$)TM6<@YM0U- -M25@L,.,65,,@M2UA`\.A)B1D('-2$XC('P#(!X&_>$Q.2@92L]_5`4WD^*&L -MB]Y6BRF=NTO_C1@!":!B,AKN&!A$YQI'+8+\HXO'^S7HBV<2>RZY^Q]VV;4@ -MVA0*4M*"9'6QGKE[AZS/YT2C:?QY=C3[:>CT+-1JY@P"PVM!B7_([[9Z'452 -M=%+::RJA<=BVKO18*&Q&Z#7.O -MT)C[7:8J=R)4\J%FFC;'K'ZJ7ZXWHK',?BL!.Q)')$()#5"D"G&XM[>UU@7F -MY\LS")6>94M4!@N\PL!O;DE)I[V%?)BV[$&XXT(),0BADGMDJ"(QAT[.`(:( -M&688%MH*U)UC)$ZRPRPRR'`2#O!Y7`'138,`VL`.$T`CD,4PUY95A'LNY^DE -M/4^X(DA*VP%7:5N71D0Q)8+0D$TX0JX=10>__&[._&Y@]#Y!`@_]FSPLK+QY -M1CSY/I/;\)\SI%0F&H!RR[!?_I]4EZWSP!,!#-P$,41Y0F(:BW@R-RKDL454 -M/@>G05AJ?KH`.23HJ"#Y=84,/16+ -MUU<"8>`/63>L&6?)H_S;;JG?)]^]J7X0%?(ZZ%Z"<>OB&;"CG?'"+O"C?2I0 -M(%['O../Z'B(%5$;6GF8Q14C'H,5W'G*N"[FBX=Q#X\,H7]V#3J*HN=+9>'I -M$<."(H*1*A)`L9>G@BK,A"Y?]-25DGW357*Q0)V0Q/]<3>M?>LI&2`9,!G8# -M$000$NL55]A]_]S_VUYJ^"]]C$#LQL*V(L"("L,@!?&`*([8QE7R$1V>?"1, -MPXK7`9_CI=&2K*N-&MVE=!\.ARBA]7S-3;VD@V#!>(\QB[AHS\B`T6>[XYLJSZ9$ -MZO,.*UA/>N226=,IW:3T7D,AU3-"U3F0&+%?`=7YSB$TVH&["/!O]7-[E]I[ -M[_KY"^Q]KK%@@ABRJ*BZT=>?Z/]],:=U=>2TN6B*Q9C!C#4J5*N"("&OV9HE -M5B1/,E6E]M(#'J`!`D']7'[2Y>^-\?X=@NJ2YD5>#EB^!VPA*]>>VVVW+H)V -M+2L/2E*4O65-C'ZZ4I2,DC7=E=2]U====>FR[ZWS52E*4I<)8;;?4O&()!() -M%%%55551555555554DDDDE:ZZZ[+)WKZZ>W);IK;;;;;TDJPD6"H8<,T4@I% -M@<7%IP,8+LU*.X5MK3A-(3`$SK&!@-Z -M"HE%6JF,JD!,56KEFS9LT&'1::UK:W*+80(\<:BG0+5*C%(%&$-.W/++SG6! -M08I[5:YR5*-CC:;UZ]>IO7CO-:UM@?QZ!I^G0@.M(P.`0(@-((R`4J`@`(0& -M#=ILEW5%^41O=*R#IWRUJWJZKIMIT.[E)$`[5\H=Y?SV27^=2P%-[;>'S,8) -M#SXA-W\3R)YS\*RS\A@B(A4?W;:S6A[GF](7B!V[Z$AO)@4 -M.`]^^8XIJZS6"#(H`LD-2?]Z60Q4@1.Q#320C@X&IV`(_HG"U-"T6JJ:.DU" -M:3UI.0E\%HU[<`4M5&`3H:#SV@2+!2U""<#?05?OI59O*`ZUR5*!,)V)!M&0 -MT!PVA0\ZPG,9"90\ZD_Y5$3KF'3)-B=.ZTX:<&#)#?P0PIF%)5$#[>ETS6`N -M^+7/%;VB0+&3J[+H@Z@Q<0*@;MJSRR25]!:[=;C'46%8"P@+P&!+$W&<]PX8 -M%&'P_[/5]GGQ/H+=1X7.?BV!N,./BF&3#(3C(&(HT'>UUI=]I;K[K(,]##1> -MXYWB=+>7!61B:]++O[ZQN]XOF$&NH6.XQ:*!.3,>X0*)=CY(7DMENL\@LHZ" -M=`0.J)>1]]^*D<8\08I`-6PIR')MXG1WLNP%/2*E(/1I`EI+TCY8XZB"&@0@ -M:F`8U([$PM_)QMC`("U]EZPUEB:TA:PQ3U++0-EOMCT7MD.;U&*28VHV<%"` -MZD,?E5LC!!IHYNIE5#^``SO[-M0#&W0(?BB*BQ0=7OEW>\>&E3?8"8(QWUJ)+R -M$0V:U."!JX&'79,+<8PG#>0X:\3=LX&RU-J"U@9?/,QPD/&L2O#W-KI_]>):>'XL7>_L. -M?F!^3P*<0$HN_7\T+TU"IMMU5/^DRKMV_"?LZ\33(#0/U/%0#1F`@PG;B]%S -M;%B#)/3,8&3=;<=%T5>7Z6^,_0A:/U'D?-?-@GR=X0*NW -M:<>#SCL6UZ!Z#=V/:J\J\U^7+)KWB\9T#ZA]C4ZDJJPGC6H8C#:S&##"@27` -M?*HM9F>GQ]CE;ZVJJMM!Q&$G0&\G?\#R<9)=I5CVNK`/>YU0>'-P2[\S/R<.`@,>[JJ`R6D@ -MH(-'3'<\OB*;I,A0EMS;D[QJVK7)TQQD]!,SARF637'\7#N``IMQQ=@S6%R( -M4ET%\1UV&JTV!\>5'UV6BOX8'IZ_G^^`UT5)'\0&[RM^1D!&3&0G3Y._X@`5 -M'J)OU>9YC-V_U;-[CS$'VMG59;7(`60`"Z\?3#*;OLB*YH::BKPYBK6XMF-* -MH*,^X].7+M6J[5)P/2-%EN3:^/A=2I4\$J)DC0$!WC0;YI18*9A -M2FY+D2TI=,RT)4C#`"@::5#3-+:F&"L01*R$F4M*JPH1O"-B"03W& -M>/:]4`,&J$(BX2O)\5#")C?71\M4.VTJYTGT%*<89:6<6LC!C(\Z&QO]QJ%T -M,C:>[8O*65R_>-+YW/EVFM8,/:%?T?A18E"]$QB!YF8'JGL8!DC!H`'R2P`L -MI1X:Y*)DP8/14]V#!9K7/:Q(SI6LJXH0NQ::7;BP0(1E`4(O3([JK -MM-SD<^KN==<_"^('7[S"+F_.[E"P3`QMK8C@624+RA36F0W!`>*(HL%D!2)Y -M1A1T)!!0K,.X$>=]7#T'TS`GH@WS0AQXO_?V7.?`_R^X'7QEHM"P%M-_? -MBJ6ZK2-'5)11,8X&Y8VD9AF9@!(S)/<5*X\7(O9-Q%A%>OP0.,6N0W2UJ9!) -M)2:ONK\0Z9%2`$D$4O?[Z*(S\4OUIO9>8LO4_$Y#T2R%CN]=HWYXS3)T4U3P -M<<77(8)F?:C$*(IPS7Q&%61L``Z!VC:''=\<-!J['9XWD"!P2\B,@7%*!"## -MI?\*E4_XD]>,N.*VZOIZ]3=H]Q!(='@52_8Y53L/R?Z]CRT^Q]B++B8.^L^# -M.C3ZURGNUXWM;+"]=$\@.LRCH.-I)\%M2,F/?-2NN$5Y[^[#6MY<#GX.`>%3[ -MP>#!8P$"8)8?6A8(DVA@>!2$'L4!K$7MM;5JN.W[FW^*Z;C;"BX0BT](!Z0& -M+W;J&[WT;WFN!WUYW?Z'"XFYID<#VAHFZ^G.8(LK>X6]JZ=0R*CQ-89=!#K`_ -MOS"AL]?J=)@QR#D@TU)KLY9]@L9;!(,3:T$T -M"_E:;3?3S*]K-PRTA(O6<&IS\<1J"?7<.S.&\!&110!,V8RZ9DL?Z-RHA]F> -M0E?#YUVL!^ZN/SSD*FI9P\E/#\F!R9)(:0:63*_*4?0"*?;^L\ -MTJ=RU]@X^KCOHIJ39H>]\[*`)EL7?ZV$=;#@.. -M&R$<_&SK9P>]0([)53>*K,%03`X(JUS:<+0,>-JUHU2!4"I5&AOK#Q>%@ -MI#KV"Y]&8$IXNJ3V;=QMA>P%&5P"62MT=&CZI[G4U=6$@;3>-ZE>V'-X>])> -M9_<91AH_8G)2L&.L@O5ER/CUECGG/T7QL20FJ)TS-'UAR^'HH.>#@`#'7:"F -M=.6'I[T5?MA^UV2JP5)!^-Q1@(GJP#H4?7[5+-E@VE&DT5ZB,C,+(J%:R -MZ!EE44(_,N2K1CR_UD!05Z+&5=LP94^L,1E"VBC'#K*7#A8P6H&JEZY3&FH% -MS-AI.[`H&VU.'2$_NOO&<'/14P,);GS0`EZI`3.Z(#0@!51"[$H-,E`"A(GM -M50A,@`SB7Q6%@AZ8"*@0K?X1!D:S&*I3ZQ'(")JLKDVT*$7PF,+^FFA9O+C/ -M=!KYET+=):(X3PGO@]0&DL%0A%ACX>[MT;EB=37T0PN**V,EX#(SG"IV78+Y -M.U:2K:-DS)GE(%0;4:SI)*P-:!7GK.8S"=5Y$32W<+`0+BF$%W4'#6"V[XO. -M0;I:=G0`-G:HU@NC$,<`3(3Z@YHV@%/N#'C#2;6LQA$0NG=6^E(TWD>0@;RH -MX/>U1@X7!JB\$8"7:*M33_/BM#SF#!36C9&HHMFW36TBH!U8IGTA?P"2L2@)2JX:S$,5$$:PH4E+!1Q9+.6 -MT#-+%:4('?(NH#C'`_-A1S"@,,1B*@D&<-4&B,*(3FQ-=F=F"6AQS`QX*:R! -MNH`)>2'ESU7L,8AQ(+S0!GFOK82!M,PWCZ_=36MUC(C!CL-@:EN6**5*LN50 -MH$G4ZBJF.RP81>O`5E,W9+%@SJIWZ`R2N!=OL!!8+$+&D)C6'6/B!T:T"'89 -M/@T,>_#]4)E>H=]0]E%[**HQGAD-G%`%WA8S.H!!,0DL-9DU\`/U!8U0T+1+ -MALQHC%GH%+`8`%A3CI!R$5!+\AM`&2$5`/-:!^RCMU^&E]$SR!=GJ5?VT?6T -M!5CZS'76D[Q8MNLU)6"I3*/MV[P5E^VF82^(+`B!H"%<;P(B2QI=ZKG?]RR& -M6H*D2P]&4MNU@8+5E1;\O8K+,SP<;"FW!R-?64M][T.[?]&T1OHZ6^2 -MA(]W;6(B>(,W79(QQ-N?N8Y(\3TRHF.;QQ"5V-Q2P0=,EB,$R'$,<-+[CP``OL=W&P -M!648U4'@&'^3>4C2B'>')^B,=8!02@)L'//:YM"?2$.1#4`V&C]B2W`M788Y -M%FVO50%0FZV4S_GF0IR#L9T_37B_,=VITXX;,?6$=G*CKF-"8J -MFO91TV`[0:;8,0BN'/1S.M+0*U?B<"^FK4#K]_SET^RL%+TM*Z(6IHL^]M3' -MI,W]A(9T)[E!8,S_31!5Z@3\0#CWAF@*"'L453^4V4C@B;U'SK -M2+YE/>_JB0BVD`^N3!/?N?>-S+;2RZG(X3H(VK,">\&U+WUR)W#G"E2_$W." -MT:"=CH&0,AK%FG$9K!8#-7<4W9%,3&EZ-25@?8.^[:U13[MT.O!OV>+CV*.-Z1D3\ -M.PB_J7I')8N7)RFO`6W;P4=5J152$\3S?(SB9<# -M2KU3$GA%,6-RE4P\]+BX;@;Z=\Q)-0R*)7MK:(\)O0U/B*-B&^?.M(3PT:1L -MQ2=W9"A4@J64KJ?]:S'""8%0*+;:FJ$0XV;Q#`P+$*(AD4+=!T^;QTG"3UM3N[`83QCJ'6J/-Z -MG6RC@"?O5APV/,XFL:-X%9*&92-@U90PZ8L*E8;_8%H.AF<$*""#TG%20V#V -M1AXU+#]O8[(]-MJ8["D0[\I56^\L%ZM$WI1'4HS&WDN<%*%A_6@B\T(YLP4X40Q==TJFS?U]GR)8NZ(9 -M[UY1@5[W$UZKX=Y!OGM$'@KYW10DT9D6KR/*5(,B&\?>'Y]?J8!B/F320HN? -MA+YYBM/2D((GELG.=F['LXU]6I -M"%,`D,UH-^F!`7-3GVX38MW%[^1GO8[VS4_L2%Z\?G4#2),`R,C&S&`^)0(" -M:^A&#K<+%1'42,BE,93>TN9R96LMC,9Z:>_&\MOB`W'2)O0R^!D@(2`'E6G; -MHG1[%'\U:ZM&F]V:E\$7N%`&%?PMC`KD4&UPJ>:74@4?=I$ARF'3:;2;GSK? -MH[]*`R&?EM59;Y6VG'N*_P"[3'K1![FXH37[,]EKM\SDT<#5>H>O]TF -M9GC48ABYD0%&ICU(RX(P@-5ZW+SMB:?FM_Q3KB!/MN`OJB#U^5C@#D&X7*J*)\!X0L-O0?;@+,WD*=$]X3JT5MA.*J(NEN.;>4CQHS; -M+C`5MUH/>OOIFB-CB/J(72T.>0?2ZW"(AXAZ'.?])P8/1TXFQNG@D54V*(![2_FKG8[ -MG^=(C8B>G9SQ(*,:N93;;!8>\5]+TX#Q;@0=JOHH#JEU?V>I]S_)D^Y5^EZ] -M/_]_M_AVK;'BP`(::B=$_/FE>RI99CQSR?F87YP$I-$LAMGWH"(D6OMD[4UR -M[^/EF9NJ+EF+;;;;;;;;;;;;;;;9))))))))))))))).7>FFFFFFFFFFFFFF -MFFT\2"67V$TTRM.]?Q&>`@$S6#A"BA.V9*KSXW\5N$+MP#K\-Z'P7<<:<;M< -M_VZQ4XP%OAA+#B"$2'B((=`#G[^+ -M#>$>O8EGUSN@P_@^WUN^OP0%@`DT"-@6/*L@N>R0/;O2>GTO?])E?$J'2H'7 -MZJEIIZOH:&_;\";;;:;=PZ6H4]^#Q_VN@Y^"<3K00\//Y;Y7UGQ4!01,Y#TE -MQQO/G6LUVJC-AM(0>ZU7Y)C+]Y9EMLR"@;=2G>Z=-N1K!T."8TS;^S1S8REP -ML>>:.#)X[7:$]6L6]?90P.].S(D.0MGAL@9CWD4"F,S^RZL+BH_I[\QM'X@* -MN0=';>!U%H<*:-1D78/ZX%"0`'5-Z.(!QP&NQFVO\-O\7WNAV<-R9F81`:U; -MB;_YL?V[&^^/G43CG]6BR[^>^/Y_=Y[YX!]_6;'+L:KC[S'K1#IS>$=!/N4" -M%4F0H6!D>(#;^]'886<(@NHG6R'^)VY[_($N+J>/,KAZ0+@`$"[/J/HM]UYT -M!!@&1F9F#!F5Q$U;*OJ_LN$%1=C3=/FT[(PV(ER_1>>C>*!0_/S*`,M2Y(@( -MAV\'9XQH,S-NV%;C^L1%"$.<^G/H+^JX($`/;N:,;B2L@Q2L!<^LM:=ZD=E) -M!X;J(`/EQT&OVK$Z"\TFQ`.7]M`0*9(6JP^$P4\QB,E--?S(U;=1GB`C;\P. -MG[_Q9SS@K`7"_K,-;FQ',8QK&O1N/?>P1SO.(/O^E7X%J`K-A989?DA\J4G# -M-+BU!21&G^HE(A$==%+,^+XV[PM)H['C-48BQU-!30+IV1OE`_L8.\,+IG,R -ML\R"6&M-H7&K(FL7SNE'QQWVYS:]AY?0Q#RXAPWGU"BOF[ -M3O09*:49$@I:JIT*&FVY'2 -MU5S_U<]#O]>K2ZQQ0PBC$$^9]6S1ISUF-_)<.JF,,[#EFY>+(.EEE4IL$!9: -M?$D*1"9Q`<@85>G[%>"0:`7.\#!'S8)!)!1`B[7GI$>P0.%,I0C\]D_&U-`< -MZOZ)((>KJ2?4<'CCM7<"PT\CR,>+N412&*8@6&['M(P60['PH*,K19Q3;J^H -MZ]GK:"R6F"U]7!D@TI38(41D_1)R(A`,V4J9@]"KU3YN$Y>FP$0V#,+]'<=W -MS$"!22I]QN;HE>R&,GG>*A@D(`C($(Y2Q[M]VL$OL(0+',$]HSNE&JY=M/IW -M*[=9K1FX5K-Q?N$S!*B`&CAR$:8`0GE#+`+;!D`=&N%;!20H0@-AN];?#89O -MJK!PO&\'U<&'M#P`]0ZHZ,)C"&+!S$:RFRH?UY=&<3]7Y*%D'E#W&\\PLXOA -MHE'*2E9A8BAPH,,Q#7$56RB7A_JB=K:-5NCR?0+"&J/434,X-#[6:%ZV6(SX -M]8W..(D&3=+>,.5-=;H\'\H/J.*3IWC"X^[\GX+%;/>#7VQ`6ID"BIZ*D$<, -M\7\?RQ5ZXZ$V5`T*355F]PIC:%7@7`U-&1R@&'SJHB`WSZXXC;7L*S"CP'', -M?@(H^6X@/724C874GR\DG5-FF9V`>@HE_"%4"@J"2\>,,,PWL-.=K@P:C[5S -MYG&E?J\/[O%]3K^;9[756&/W-YK/.[>SMO`U_;\_[CBUUUUUUUUUUUUU\2RR -MRRRRRRRRRRRRRRRRSPL_F9U=F?X7*'=GU>UX0(Z,/1,P'ZH`@P0Q#C1(\W'C -MT2S"RR[+-3XDJOL];;6=K+ER[;4_4X6!V?]]?Q?AK)T`-+-J0/"2:J&@8Q@,Y=WWZTS`-F)P^3UN_5 -M5NSF.)-N&HU[O`ZI*=O<=:QQY;K6P//Q<+=CGNSIG3)1!&<\ISPT-$45#6O! -MB),9RLGRI0D;C=F^9113AUZKCB,]ET30VC&F#BQKH89!VXQHQG.>9QEU,.)X -MH\T3'`I== -M=F"\NW<*],PR!>W@+),$K#7I!DX,AC"!`69@`MY373\_Q`KG,O;4D;%[)I"Q -M+M[=!=E:[78-52DV8$?@.9-TG/W^#4PT'R7`+$1UVI41JOBM=%PCOH48# -MN](HY1Q*J89ZI9JX'W)A&QJBI&6JP+LJ!2J8E2D,Z,X7N8U$QIC#%8-9H/CK -M5(&=C87@1@H4H\S-:*RA;C%Q%<8,9 -M:#$19A,MN7!C.,+;9MJXG[=EY(YQCS.G6!`Q$FQ=!@HTO84$BC@P2A99>\Y: -M%1&Q.R+$1*D4$Z8I/2(@&DS$-)=U0(J0BH8`@ZF]W=NDRZ4WFGAM6-)DBR%8 -M61DMI?'\7&-XPPPH$0`O`7>2:E2Q>7CF\-O&@_L\;_1C:N"VIB%$:3F:%Y6- -M!+\/=;VQ.JSI1JKHQAH"32[AD%Z4C4$M*)ZA/1(710#Q)+=-34PZ724!+"/` -MW`&C$;(>P2UH?S8'3"WP=U[;31$B,`0SD`P&!N8H0Q:@AHSJHELD%$.&H5=[ -MB+R8H((G^CT/I@Y.;``T)Y$[`QP.+/4KI4:7V$9-O7I\PH9212D8`,SD/@:& -MI"&"G>6&/5^LW$'E!V#3BR09'+T38%-4I4K^");GL>+YO@M/D1H!(E5`[]-TQN/=7/U^>8W3W623;&4<$"N -MQ-6<)#M&H,G%!9<20:Q$?!!JXK>DK1JM"I]5!:_*J0^I*3=3,W1/_AQ=D%6 -M]O;RS%O;VK%=??O?`@LK.Z`TC(:#`($##(7KVY)"[5A.RLSD->$PAMBX+^;T -MP`LNPT(/F]">;SZC!EDZ.W=3#8\%/*.1'+)8A.(DD[EDAXU)#ZA#1DAY]Z3O -MD@'6)-C52;$@8C(&M?E>WQK.ZZ<^=S)-B'(9PQ8#&?+L(4E85@L4BLPU3%*" -M=?^5@P'_XWE+QZ&)$!BFO2F$J&!,+Y.PRX8QF6*4+1#%,1)'&'!(5JB1B8/= -M62%5(R,RAG&,"N,3`B3%**.*%%#Q@,@]M%\7>T89S1,.3A=5C0```$2@``!'(```4 -M&```$.@``!*X```1R```$-@``!*H```4&```$V@``!)(```3N```$J@``!08 -M```2J```%!@``!*H```4&```$K@``!*H```4&```$X@``!.(```3V```$R@` -M`!)X```98```$N@``#?````0&```$G@``!E@```1V```$N@``!)H```1>``` -M$B@``!(H```WP```$!@``!#(```32```$X@``!.(```3J```$Y@``!"(```1 -M2```$@@``$FP```0B```$#@``!"(```3F```$(@``!+(```2V```$M@``!"( -M```RT```)@```"8````36```$S@``!"(```3"```$\@``!18```46```%%@` -M`!18```46```$#@``!18```2.```$C@``!(X```Q\```$M@``!0(```0F``` -M$&@``!08```2*```$B@``!"X```2.```$+@``!(X```2.```-#```#0P```T -M,```-#```#0P```T,```-#```#0P```T,```-#```#0P```1N```$6@``!#X -M```0>```$$@``!+X```3V```$,@``!-(```0R```$T@``!#(```32```$T@` -M`!-(```32```$,@``!#(```0R```$,@``!-(```U$```-\```#A@```WP``` -M,?```%;````2B```$H@``#N````0R```$T@``#N````0R```$T@``!#(```3 -M2```$H@``!&8```2N```$H@``!08```[@```$,@``!#(```32```$T@``!(8 -M```2J```$:@``!0X```1.```$_@``!*(```0J```$H@``#9@```WP```,?`` -M`!*(```2J```$H@``#9@```U$```$H@``!*(``!6P```$H@``!*(```0R``` -M.&```!*H```42```$H@``#?````2J```$H@``#9@```V8```$J@``!*H```2 -M:```$7@``!`H```32```$_@``!*X```2:```$K@``!&H```2:```$K@``!/8 -M```3&```$U@``!)8```06```$0@``!)8```3V```$E@``!!8```0R```$T@` -M`!)8```1"```$,@``!#(```1"```$T@``!-(```0R```$T@``!/8```26``` -M$%@``!#(```32```$0@``!)8```2B```$0@``!#(```32```$]@``!)8```0 -M6```$,@``!#(```0R```$,@``!#(```32```$T@``!-(```32```%!@``!-( -M```1"```$E@``!'H```1"```$,@``!#(```32```$T@``!/8```5,```#_@` -M``_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^``` -M#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/ -M^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X -M```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@` -M``_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^``` -M#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/ -M^```#_@``!'X```5D```$?@``!9````1^```%M```!'X```78```$?@``!?P -M```1^```$?@``!B@```A1```(5L``"#]```=7@``'6H``!YQ```>4```'5`` -M`!U0```>B@``'S$``!^B```EJ0``'LT``![-```?!0``&H$``"$;```CMP`` -M)?0``!JD```=5P``&J0``!JD```<````'/$``!S^```<_@``)>```"7@```< -M5P``'%<``"2R```@R0``''```!QP```@/P``'^D``!XR```=N0``'C(``!FR -M```EJ0``)<<``"6]```DU```)1H``!HQ```=ZP``(#4``"2-```C00``(Y@` -M`")U```A\@``(:,``"B"```G=P``*`@``"=H```GP```)X```"A&```GV``` -M*"P``"A9```F@```)H```":2```H;@``)H```":````F@```)Q```"<0```F -M<@``)H```"9R```F^0``)H```":^```F^0``*8L``#$P```OOP``+#H``#"! -M```K[0``+`<``#`3```P5```,#P``"_H```P8P``*QP``"L2```K'```*?\` -M`"HF```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P`` -M*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I -M8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC -M```I8P``*6,``"EC```IVP``*=L``"G;```KHP``,6T``"NM```K0@``,4P` -M`"NM```KP```*ZT``"NM```KP```,Z```VF```-I@``#:8```V@0``-I@``#:8```VF```-I@` -M`%$0``!+(```3H```#ES```Y)@``.?D``#I*```[4@``.:@``#HJ```YQ``` -M.+(``#KB```ZP@``.OX``#IF```[-@``.J(``#L:```Y%0``.9<``#GH```Y -M8@``.-H``#R(```[LP``.ZH``$`\``!`*@``/^L``#_K```_N@``/X0``#]R -M```_A```/X0``#YT```^K0``/DT``#XT```^-```/+```#UP``!!5```09(` -M`$"@``!!$```11P``$4<``!$]P``1J@``$95``!#5```0U0``$-4``!(>P`` -M1_4``$@U``!)!@``21H``$CC``!(Q0``1C```$8(``!%<```17```$>P``!% -MWP``1^4``$?3``!%]```1O```$<```!&T```2,X``$(```!)I0``0?4``$>` -M``!$4P``1((``$2"``!#M```0Z<``$(N``!"(```1/<``$2U``!(1P``2(X` -M`$3)``!%N```1$8``$1U``!$=0``0L$``$-4``!#`P``1S```$-4``!"@``` -M1,D``$-,``!$]P``0U0``$-4``!#`P``0P,``$@U``!(-0``0U0``$K]``!- -MI0``3.0``$UO``!-1```3*,``$R!``!-\0``3=\``$MH``!,`0``3`H``$U5 -M``!-_@``2V@``$W%``!.'```2V@``$O)``!,T@``3CH``$Y4``!.<@``31,` -M`$QP``!,70``3,@``$S2``!-"0``31,``$V>``!-E```39X``%"%``!0:0`` -M4`(``$_4``!.R```4+,``%"A``!.R```3S<``$]```!0P```4-\``$[(``!/ -MR0``3[8``%!6``!030``4%8``%44``!2L@``56D``%3?``!4WP``5-\``%5& -M``!60```5B@``%44``!5=@``45@``%4T``!3J```5(```%/A``!48```5!`` -M`%2@``!40```5,```%*'``!2T```4OX``%,V``!3;@``4Y8``%,@``!3*0`` -M4N<``%+Q``!36```4V$``%.-``!3E@``5:```%+$``!2E```5KH``%()``!2 -M$@``4;T``%%8``!4^0``5F0``%9^``!6G```4H<``%*'``!2;@``5>P``%7B -M``!5[```5A,``%8<``!7H@``5\```%<&``!7!@``5T```%=``'__[(*_<*GB -MTO8J#[&TS@MGB4R]0=<':N.(W\G9G;.:/7*.,11&`00&``0)JKB$;(>X)P`' -M"P$``@,$`@(4`P,!&P0!`0```@,$#,"<7L#`:@`("@$]?9*5```%`1$/`'@` -B.``V`&4`>`!E````%`H!```M0RMQLYT!%08!`"$````````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj2_copy_1.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj2_copy_1.7z.uu deleted file mode 100644 index ad8cc4dee..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj2_copy_1.7z.uu +++ /dev/null @@ -1,614 +0,0 @@ -begin 644 test_read_format_7zip_bcj2_copy_1.7z -M-WJ\KR<<``.C9M/"YVH```````!=`````````"._PGQ_14Q&`0$!"0`````` -M`````@`#``$```!PE`0(-````+!F````````-``@``<`*``:`!D`!@```#0` -M```T@`0(-(`$".````#@````!0````0````#````%`$``!2!!`@4@00(%0`` -M`!4````$`````0````$``````````(`$"`"`!`@T70``-%T```4`````$``` -M`0````!@````X`0(`.`$")@"``!,!```!@`````0```"````B&```(C@!`B( -MX`0(V````-@````&````!`````0````L`0``+($$""R!!`@8````&`````0` -M```$````4.5T9!A=```8W00(&-T$"!P````<````!`````0````O;&EB97AE -M8R]L9"UE;&8N@(``!(```"]`@```````,\!```2 -M````?`(```````#.````$@```(8"````````0P```!(```!:`0```````&<& -M```2````>`$````````J````$@```&X"````````/@```!(````:`P``F.($ -M"``````0`/'_80$```````!5````$@```#,```!TX00(`````!$`\?\M`P`` -M3.0$"``````0`/'_BP(```````!B`P``$@```"L!``#4X@0(!````!$`%P`/ -M`0```````)L(```2````Y`$``-CB!`@$````$0`7`%,!`````````````!(` -M``"%`0```````!H````2````A`(````````K````$@```+0"````````*0`` -M`!(````4`0`````````````2````Y0(```````"+````$@```*$````````` -M8````!(```!)```````````````@````&P$```````!]````$@```$(!```` -M`````````!(```"!`````````!0!```2`````&QI8G5T:6PN7!E`'-T'0`@<` -M``(`.P,```````"@X@0(!18``,#B!`@%)0``Q.($"`4K``#(X@0(!34``,SB -M!`@%/```T.($"`4^``#4X@0(!4L``-CB!`@%30``@.$$"`E\M#G! -M<]N-=@#KJXVT)@````"-O"<`````58GEBU4,BT4(B54(B44,7>F-="8`C;PG -M`````%6)Y8/L"(D<)(ET)`2+=0B+70R+5DR+2TR+0B@Y02A^$+@!````BQPD -MBW0D!(GL7<-\#XM"+#E!+'_FD(UT)@!]![C_____Z]V+0U")10R+1E")10B+ -M'"2+="0$B>Q=Z8VV`````(V_`````%6)Y8M5#(M%"(E5"(E%#%WIC70F`(V\ -M)P````!5B>6#[`B)'"2)="0$BW4(BUT,BU9,BTM,BT)0.4%0?A"X`0```(L< -M)(MT)`2)[%W#?`^+0E0Y051_YI"-="8`?0>X_____^O=BT-0B44,BT90B44( -MBQPDBW0D!(GL7>F-M@````"-OP````!5B>6+50R+10B)50B)10Q=Z8UT)@"- -MO"<`````58GE@^P(B1PDB70D!(MU"(M=#(M63(M+3(M"&#E!&'X0N`$```"+ -M'"2+="0$B>Q=PWP/BT(<.4$F-="8` -MC;PG`````%6)Y8/L"(D<)(ET)`2+=0B+70R+5DR+2TR+0B`Y02!^$+@!```` -MBQPDBW0D!(GL7<-\#XM")#E!)'_FD(UT)@!]![C_____Z]V+0U")10R+1E") -M10B+'"2+="0$B>Q=Z8VV`````(V_`````%6)Y8M5#(M%"(E5"(E%#%WIC70F -M`(V\)P````!5B>6+10B+50R+0%")10R+0E")10A=Z9"-="8`58GEBT4,BT!0 -MB44,BT4(BT!0B44(7>F0D)"0D%6)Y8/L"(D<)(ET)`2+10B+30R+`(M00(/Z -M!W1SBQF+2T"#^0=T:8/Z"G1,@_D*=$%E/O_ -M_P````"%P'4-H43D!`B%P`^$QX5`^___`0```,<$)-S8!`CHQX6(^___```` -M`,>%C/O__P````#'A:#[__\`````QX6<^___`````,>%F/O__P````"%P(G# -MQX6H^___`````,>%K/O__P````#'A;#[__\`````QX6T^___`````,>%I/O_ -M_P````!T"8`X``^%B[T4^___A?\/A(N%$/O__XN]%/O__\>%+/O__P````#' -MA3#[__\`````@^`"QX4\^___`````,>%3/O__P````")A0S[___I@_@*#X2+ -MM1C[__^%]@^$BT=0@#@N#X2+1RP[A:S[__]V!HF%K/O__XL5).0$"(72=0J+ -M->SC!`B%]G0=B40D!(M'4(D$).@[A:S[__]V!HF%K/O__XN=0/O__X7;#X2+ -M5TR)T(M(/(N%M/O__XF5*/O__XM2.(G&P?X?.?%\#'\$.<)V!HF5M/O__XN5 -M*/O__XM"!#N%L/O__W8&B86P^___BXTH^___#[=!"CN%J/O__W8&B86H^___ -MBXTH^___BU$T.Y6,^___BT$P?!9_"#N%B/O__W8,B86(^___B96,^___BX4H -M^___BPU$Y`0(BT`X`84L^___AZ+5>PS%:#B!`@/A8'$+`4``%M>7UW#C70F`(L- -M\.($"(7)#X7'1PP!````QT<0`````.F#Z`$/A8L=[.($"(7;#X7KU(N5*/O_ -M_\=$)`0`````BT(,B00DZ(N-*/O__\=$)`0`````B85$^___BT$0B00DZ(F% -M2/O__^F#O3#[__\.#X>+E2C[__^+0A0PY#T``0``H3SD!`@9R8/A^8/!#X7` -MB8TP^___#X2+E4S[__^-1#,2B4,(B00DB50D!.B+C4S[__^)#"3HZ8N-*/O_ -M_XM!1(D$).B%P(F%3/O__P^$@#@`=2*)!"3HQP0D^M@$".B%P(F%3/O__P^$ -MBX5,^___B00DZ#N%H/O__XF%-/O__P^&B86@^___Z8V5D/O__XD4).B#P`$/ -MA(M'/(7`#X6+1U"-M;G[___'1"0(]-@$",=$)`0!!```B30DB40D#.B+A0S[ -M__^%P'1SBX60^___B30DB40D!.B#P`%T%+/O_ -M_P````#'A3S[__\`````QX4P^___`````*%$Y`0(A/&`3`/MD(!B$$! -M@\$"QD$!``^V0@*#P@&$P'7;@'G_.@^$C86D^___BY4<^___B40D*(V%K/O_ -M_XE$)"2-A8C[__^)1"0@C86@^___B40D'(V%G/O__XE$)!B-A9C[__^)1"04 -MC86H^___B40D$(V%M/O__XE$)`R-A;#[__^)1"0(QT0D!)39!`B)%"3HQP48 -MY`0(`0```(/X"`^&B[6P^___,<"%]G0@N0$```"X"@```/?A@^X!B<%U\L>% -ML/O__P````"-0/^+O;3[__^)A;#[__\QP(7_?C6)_KD!````,=MKTPJX"@`` -M`(F5!/O___?AB=.)P0.=!/O__X/N`77AQX6T^___`````(U`_XNUJ/O__XF% -MM/O__S'`A?9T(+D!````N`H```#WX8/N`8G!=?+'A:C[__\`````C4#_BXV, -M^___BY6(^___B86H^___@_D`B94@^___B8TD^___#XZ+C2#[__^^`0```#'_ -MBYTD^___:\<*B84$^___N`H```#WYHG7B<8#O03[__^#P?^#T_^)V@G*==J) -M\(GZ@\#_QX6(^___`````(/2_\>%C/O__P````"+C1S[__^)A8C[__^)E8S[ -M__^)#"3HZ8N-+/O__XU=NHN%M/O__\=$)`@/O__XN%J/O__XE$)`SHB1PDZ(F%?/O__Z'\ -MXP0(A%@/O__P4```"+A3#[__\[A8#[__]V!HF%@/O__XN%F/O__XF% -MA/O__^F+1U")1"0(BT<$BT`%M/O__P````#'A:C[__\`````QX68 -M^___`````,>%G/O__P````#'A:#[__\`````QX6(^___`````,>%C/O__P`` -M``#'A:S[__\`````@ST%I/O__P`````9P/?0(048Y`0(Z<=$)`3I -MV`0(QP0D`0```.AFQP$P`.F+E1S[__^)T8/!`F;'`C`ZQD("`.G'1"0$_-@$ -M",<$)`$```#HZ(VT)@````!5B>575E.#[!R#/?SB!`@!B47LB4WH&<`EP)@$ -M"(E$)`B)3"0$B10DZ(7`B<B)PC'`Z*'L -MX@0(A<`/A8LU!.,$"(7V#X3'1?``````C;0F`````(D\).B%P(G##X2+0T"# -M^`(/A(GV#X^#Z`%UU8M+/(7)=`R+0U"`."X/A*$DXP0(A<`/A*'`X@0(A<`/ -MA8L5S.($"(M""(/H`87`B4((#XB+`L8`"H/``8D"BT,B)PHG&B=CHH03C!`B%P`^%A?8/A(E<)`3'1"0(!``` -M`(D\).B)/"3HA<")PP^%Z(L`A<`/A8/$'%M>7UW#D(/X!'0)@_@'#X6+0R") -M!"3HB40D"(M#',<$)/#8!`B)1"0$Z,<%(.,$"`$```#ID(M#4,<$)"W9!`B) -M1"0$Z.F#?>P!#XZ+0QR)!"3HQP0D2MD$".C'!23C!`@!````Z8L=".0$"(7; -M#X7V1>@(QT7P``$```^%Z:',X@0(QP0D"@```(E$)`3HZ8L5\.($"(72#X3I -MB50D!,<$)`H```#HZ<=$)`1,V00(QP0D`0```.C'1"0$)-D$",<$)`$```#H -MC78`C;PG`````(U,)`2#Y/#_575E-1@>PX!@``BQFAH.($"(E%[#'` -MC87L_?__BWD$B87D^?__QT0D!,S;!`C'!"0`````Z,<$)`$```#HA<`/A,<% -M#.`$"%````#'!"15V00(Z(7`=`F`.``/A8V%W/G__XE$)`C'1"0$:'0(0,<$ -M)`$```#H@\`!=!0/MX7>^?__9H7`=`@/M\"C#.`$",<%#.0$"`$```"^$``` -M`,=$)`C(V00(B7PD!(D<).B#^/]T/X/H,8/X1W8PZ.O8QP4,XP0(`0```,<$ -M)%79!`CHASY__^)!"3H@^@!#X2+%1SD!`B%TG1&QP48Y`0(`0```,=$)`1@L@0( -MQP0D`@```.C'1"0$8+($",<$)`,```#HQP0DB=D$".B)!"3HH4#D!`B%P'5! -MH43D!`B%P'4XH?CC!`B%P'4OH13C!`B%P'4FH1CC!`B%P'4=H3#D!`B%P'44 -MBQTA%.,$"(7`#X6A&.,$"(7`#X3'!>3B!`B0E00( -MH0SC!`B%P'2?QP7@X@0(L+P$"(N%S/G__X7`=*R+ACY___'1"0$$.0$"(D$ -M).B+%1#D!`B)T,'X'\'H%P'0P?@)HQ#D!`CIQP0D9MD$".B%P`^%Z8/.(,<% -M\.($"`$```#IQP4,Y`0(`````,<%).0$"`$```#'!>SC!`@`````Z:'$X@0( -MH_3C!`CIQP4,XP0(`````,<%1.0$"`````#'!33D!`@`````Z<<%&.,$"`$` -M``#'!13C!`@`````Z<<%!.,$"`$```#I@^;\@\X0QP7XX@0(`0```.F#YN^# -MS@+'!?CB!`@`````Z<<%].($"`$```#I@\X!QP7XX@0(`````.G'1"0(`0`` -M`,=$)`3,VP0(QP0D7=D$".CIQP4PY`0(`0```,<%%.0$"`````#IQP4,XP0( -M`0```,<%1.0$"`````#'!1#C!`@`````Z<<%-.0$"`$```#'!43D!`@````` -MQP4,XP0(`````.G'!0SD!`@`````QP4DY`0(`````,<%[.,$"`````#IQP4$ -MY`0(`0```,<%Z.,$"`````#'!3CD!`@`````Z<<%%.,$"`$```#'!1CC!`@` -M````Z<<%^.,$"`$```#IQP4(XP0(`0```.G'!0SD!`@!````QP4DY`0(```` -M`,<%[.,$"`````#IQP44Y`0(`0```,<%,.0$"`$```#IQP4\Y`0(`0```.G' -M!0#C!`@!````Z<<%$.,$"`$```#'!0SC!`@`````QP5$Y`0(`````.G'!43D -M!`@!````QP4,XP0(`````,<%$.,$"`````#IQP7\XP0(`````,<%Z.($"`$` -M``#IQP5`Y`0(`0```.G'!?SC!`@!````Z<<%_.($"`$```#IQP7LX@0(`0`` -M`,<%!.,$"`````#IQP7HXP0(`0```,<%!.0$"`````#'!3CD!`@`````Z<<% -M#.0$"`````#'!23D!`@`````QP7LXP0(`0```.G'!0CD!`@!````Z<<%'.,$ -M"`$```#IQP4XY`0(`0```,<%!.0$"`````#'!>CC!`@`````Z<<%(.0$"`$` -M``#IZ(7`#X6A].($"(7`#X7'!?#B!`@!````Z8L=&.,$"(7;#X6+#03D!`B% -MR0^$QP7DX@0(8)<$".FA&.,$"(7`#X6A!.0$"(7`#X3'!>3B!`C0EP0(Z:$0 -MXP0(A3B!`B@F`0(Z<<%X.($ -M"$"]!`CIC9WD^?__B5PD!,<$)'K9!`CHB5PD!,<$)'W9!`BC\.,$".B)7"0$ -MQP0D@-D$"*,LY`0(Z(E<)`3'!"2#V00(HTCD!`CHB5PD!,<$)(;9!`BC*.0$ -M".B%P*,`Y`0(#X2A\.,$"(7`#X2+'2SD!`B%VP^$BPT`Y`0(A3B!`BPE@0(Z8L5..0$"(72=1BAZ.,$"(7`=#S'!>3B!`A`E@0(Z<<%Y.($ -M"-"6!`CIQP7DX@0(0)<$".G'!>3B!`A@F`0(Z<<%Y.($"/"7!`CIB5PD!,<$ -M).W8!`CHHP#D!`CID)"0D)"0D)"0D)!5B>6#[!B%P'0]H0#D!`C'1"0(H+($ -M",=$)`0!````B00DZ+B@L@0(B40D"*%(Y`0(QT0D!`$```")!"3HR<.A`.0$ -M",=$)`@`N`0(QT0D!`$```")!"3HN`"X!`CKP9"-="8`58GE4X/L%(M="(G8 -MZ(D<),=$)`0`````Z.B)7"0$B00DZ(/$%%M=PY"-M"8`````58GE@^PHBT4( -MQT0D"`$```#'!"0!````B$7_C47_B40D!.@QP,G#D(UT)@!5B>575E.#["R+ -M10B%P`^$BT4(,?^)!"3HBQ5@W`0(9L=%V@``QT7<`````(E5X(E%U.L\C70F -M``^^PH/H,&:#?=H`B0,/A&;'1=H!`(/&`8/#!(/^`G5%@\`:.,$"`````"-!#\Y1=1W.8M5X`^V`HA%\@^V0@&(1?.-!'\Q -M]HT'03#[["B40D -M!,<$)#37UW#QT4(S-L$".E5B>564XG#C31`@^P0 -MBQ2U:.,$"(72#X6+!+5@XP0(@_C_=#B)1"0(H?#C!`C'1"0$`````(D$).B% -MP'0;QT0D"`"X!`C'1"0$`0```(D$).B-=@"-!%N+!(5DXP0(@_C_=#6)1"0( -MH2SD!`C'1"0$`````(D$).B%P'08QT0D"`"X!`C'1"0$`0```(D$).B#Q!!; -M7EW#D(UT)@"A*.0$",=$)`@`N`0(QT0D!`$```")!"3HZ8VT)@````"-O"<` -M````#[?`B<)5@>(`\```B>6#[`B!^@!````/A'Y1@?H`H```#X2!^@#```!T -M8H'Z`&````^$,=*H271?]L0(#X7VQ`0/A+@(````C70F`.BZ`0```.LXC70F -M`('Z`!```'18@?H`(```B?9UO;@&````Z+H!````R8G0P[@"````Z+H!```` -MR8G0P[@!````Z+H!````R8G0P[@%````Z+H!````R8G0PXGVN`,```#HN@$` -M``#)B=##J`)T./;$`G01N`D```#HN@$```#KI[@*````Z+H!````ZY:X!``` -M`.BZ`0```.N%,<#HN@$```#IN`<```#HN@$```"0Z8UT)@"-O"<`````58GE -M4X/L=(E%F*&@X@0(B47X,<"A+.`$"(7`#XBA1.,$"(7`=':+'?3C!`B%VP^$ -MC468B00DZ(E<)`B-7:C'1"0$4````(D<)(E$)`SHHSC!`B%R70)B44(7>F+%0SD!`B% -MTG0)B44(7>F)10A=Z9!5B>6#[`BAP.($"(M-"(7`=2"+%!^@`0```/A('Z`$```(UT)@!T/JA)=,:AP.($ -M"(7`#X6+%6#[#B)7?2)PXE]_(G/B77XBW!,H4#D!`C'1>P`````A<`/A:'X -MXP0(A+0U")!"3HBTWLC1P(H1SD!`B%P'4W -MBSTPY`0(A?]T"P^W1@CH`<.)V(MU^(M=](M]_(GL7<.+0U")!"3HBU7LC1P0 -MZ\F%_W3%,<#HZ[RA$.0$"(/H`8E%X(G"BT8XP?H?`47@H1#D!`B)5>2+5CP1 -M5>2+3>2)PL'Z'XE4)`R+5>")3"0$B40D"(D4).B)?"0$QP0D>-L$"(E$)`B) -M5"0,Z`%%[.F+1@2)5"0$QP0D7<.)5"0$QP0D"@```.CKHXUV`%6)Y5=64X/L -M/(M%"(,]&.0$"`$9TH/B!XE%T(M`"(/"`3L%'.`$"(E5Z`^/BUW0QT7<```` -M`(L3A=)T)(L-0.,$"(M"#(/P`0M"$'0,BT72)5=B+3P!````BUW0H4#C!`B+4R"+2Q"+7=B+!)CHBQ4TY`0(A=(/A(/#`8M-W(E= -MV#E-V`^-BU7H`<:-'!8C7=0Y^W]>C70F`(L--.0$"(7)=`R+1P/C8L5 -MP.($"(72=5"+#B-'!8C7=0Y^WZFBTW,.4WL=&*#1>P!`WWPZ8GV@ST8Y`0( -M`8G>BQ7,X@0(&<"#X.F#P"")5"0$B00DZ.NX.T$8?`B`^@J-=@!UH(E,)`2) -MWHD4).CKFXM5X`%5V(M-W#E-V`^,H<#B!`B%P'4UBQ7,X@0(BT((@^@!A<") -M0@AX.8L"Q@`*@\`!B0*#1>0!BUW@.5WD#X6#Q#Q;7E]=PZ',X@0(QP0D"@`` -M`(E$)`3HZ]&)5"0$QP0D"@```.CKOXL]1.0$"(7_=0B%R0^$BTW0BQT0Y`0( -MBU$$QP0D?ML$"(/J`8T,&C'2B7UWIP>`" -MB40D!*%`XP0(B00DZ(7`B<)T%HM-T(D50.,$"(M!"*,575E.#[`R+=0B+'H7;#X0Q_^L7UW#H575E.!['P(``"+10B+%:#B!`B)5?`QTHLPB86D -M]___A?8/A(M&/(7`#X7'A:CW__\`````D(M&#(/P`0M&$`^$BQU`Y`0(BWY, -MA=L/A8L-^.,$"(7)#X6-3(`\```@?H` -M(```#X2!^@!@```/A('Z`.````^$BP`[!2C@!`@/A(M&/(7`#X6+1E"-G%(U-S(N5I/?__XM#!(E$)!R+0AR)1"08 -MBP.)1"04BT(LB40D$`^W1PJ)1"0,BT(DB4PD!,<$)(S;!`B)1"0(Z*$\Y`0( -MA<`/A:$(Y`0(A<`/A0^W1P@E`/```#T`(```#X0]`&````^$BXVD]___BT

    ")5"00B40D#,=$)`BFVP0(QT0D!!````")'"3HBX6L]___B5PD -M",<$)+O;!`B)1"0$Z*$$Y`0(A<`/A(M'&.BA'.0$"(7`#X0/MT<(Z(F%J/?_ -M_^F+0PR+C:3W__^)1"0(BT$8QP0DH-L$"(E$)`3HZ8UV`(M#"(N5I/?__XE$ -M)`B+0A3'!"2@VP0(B40D!.CIBPT0Y`0(C4'_BRL````BWT,C95P____BW4(H:#B!`B)1?`QP,=$)`B`````QT0D!``` -M``")%"3HA?_'A6#___\`````=%^-E7#___^-A6S___^)5"0,B7PD"(ET)`2) -M!"3HA<")PW0Y@_O_=&V#^_X/A(N5;/___X'Z_P```'=*H=#B!`B+1)`TJ0`` -M!`!T*8.%8/___P$!WH7_=:&+5?`S%:#B!`B+A6#___]U9H'$K````%M>7UW# -MBX5@____C028B85@____Z\V)%"3HZ[6)]HV%AT.($"(M$F#2I```$``^$,?:%_W\WZV:-="8`BQ7,X@0(BX5< -M____#[8,!HM""(/H`87`B4((#XB+`H@(@\`!B0*#Q@$Y]W0KH<#B!`B%P'3& -MHAT.($"(M$F#2)PH'B````X`^$B=#!Z!X!O5S___\!A6#____I.T(8 -M#[;9?`F`^PH/A8E4)`2)'"3HZ8L5P.($"(72#X6+%RL````BT4(BQ6@X@0(B57P,=+'1"0(@``` -M`,=$)`0`````B85<____C85P____B00DZ,>%8/___P````"+E5S___^-A7#_ -M__^)1"0,C85L____QT0D"`8```")!"2)5"0$Z(7`B<8/A(/^_@^$@_[_#X0Q -MVX7V?S/K78L5S.($"(N%7/___P^V#`.+0@B#Z`&%P(E""`^(BP*("(/``8D" -M@\,!.=YT+(L]P.($"(7_=,6AS.($"(N57/___XE$)`0/M@03@\,!B00DZ#G> -M==2+G6S___\!M5S___^!^_\```!W<*'0X@0(BT28-*D```0`#X0QP(7;="B! -M^_\````/AZ'0X@0(BT28-(G"@>(```#@#X2)T,'H'@&%8/___^D[0A@/MOE\ -M"HGX/`H/A8E4)`2)/"3HZ8D<).B0ZXZ-A7#____'1"0(@````,=$)`0````` -MB00DZ*'`X@0(A<`/A8L5S.($"(N%7/___P^V"(M""(/H`87`B4((#XB+`H@( -M@\`!B0*#A5S___\!@X5@____`>F+E5S____'!"3TV`0(B50D!.@!A6#___^+ -M5?`S%:#B!`B+A6#___]U:X'$K````%M>7UW#)0``!`"#^`$9P(/(`>F)'"3H -MZ:',X@0(BY5<____B40D!`^V`HD$).CI.T(8#[;9?`F`^PH/A8E4)`2)'"3H -MZ>B-=@"-O"<`````58GE5U93@>RL````BT4(BQ6@X@0(B57P,=+'1"0(@``` -M`,=$)`0`````B858____C85P____B00DZ,>%8/___P````"+E5C___^-A7#_ -M__^)1"0,C85L____QT0D"`8```")!"2)5"0$Z(7`B85<____#X2+A5S___^# -MP`*#^`$/AHN=;/___X'[_P````^'H=#B!`B+1)@TJ0``!``/A(/[(@^$@_M< -M#X2+O5S___^%_WYO,=OK-8L5S.($"(N%6/___P^V#`.+0@B#Z`&%P(E""`^( -MBP*("(/``8D"@\,!.YU<____=#"+-<#B!`B%]G3!H@>`85@____@[U<_____@^$@[U<_____P^$BY5< -M____`958____Z8.]7/____\/A;\!````,?;ID(UT)@"+%#P#")!"3HH<#B!`B%P`^$C;0F`````*',X@0(B40D!(G8@^`'@\`PB00D -MZ.F)]CM"&'P)@/D*#X6)5"0$B0PDZ.F0.T(8#XV)5"0$QP0D7````.CIB?8[ -M0AA\"8#Y"@^%B50D!(D,).CID#M"&'P)@/D*#X6)5"0$B0PDZ.F+#>SC!`B% -MR700A=MX#('[_P````^.B[U<____A?\/CX.]7/____X/A8M5\#,5H.($"(N% -M8/___P^%@<2L````6UY?7<.+A5C___^)!"3HB575H/L,(M5 -M#(M%"(MU$(M]%(E5W(M-W(E%V,=%T`````")\,=%U`````")^H7)QT7D```` -M``^(A?\/B(G7B<:+5=B)P8M%W(7_B57PB47L=10YQG9!B="+5>SW]HG!,<#K -M$XUV`#M]['9/,2)1=2+1="+5=2%R70']]B#T@#W -MVH/$,%Y?7<.%]G4+N`$````QTO?VB<&+1>R)^O?QB<:+1?#W\8G!B?#KO`^] -MQX/P'XE%Z'5$.7WL=P4Y=?!RG+D!````,<#KGO==V(-5W`#W7=R%_\=%Y/__ -M__\/B9"-="8`B?")^O?8@](`]]KW5>3IN"````")\BM%Z(G!T^H/MDWHB47T -MB?B)UXM5[-/@"<>+1?#3Y@^V3?33Z`^V3>C3X@^V3?0)T(M5[(E%S-/J]_>) -M5&-X9'AB>&5G961A8F%G86-A9`````!,4T-/3$]24R!S:&]U;&0@=7-E -M(&-H87)A8W1ED`0(KI`$"+Z0!`C.D`0(WI`$".Z0!`C^D`0(#I$$"!Z1!`@ND00( -M/I$$"$Z1!`A>D00(;I$$"'Z1!`B.D00(GI$$"*Z1!`B^D00(SI$$"-Z1!`CN -MD00(_I$$"`Z2!`@>D@0(+I($"#Z2!`A.D@0(7I($"&Z2!`A^D@0(CI($")Z2 -M!`BND@0(OI($",Z2!`C>D@0([I($"/Z2!`@.DP0('I,$""Z3!`@^DP0(3I,$ -M"%Z3!`ANDP0(?I,$"(Z3!`B>DP0(KI,$"+Z3!`C.DP0(WI,$".Z3!`C^DP0( -M#I0$"!Z4!`@NE`0(/I0$"$Z4!`A>E`0(````````````)$9R965"4T0Z('-R -M8R]L:6(O8W-U+VDS.#8M96QF+V-R=#%?'`@)```)$9R965"4T0Z('-R8R]L:6(O8W-U -M+V-O;6UO;B]C'`@ -M)`!'0T,Z("A'3E4I(#0N,BXR(#(P,#6YS>6T`+F1Y;G-T<@`N9VYU+G9E6X`+G)E;"YP;'0`+FEN:70`+G1E>'0`+F9I;FD`+G)O9&%T -M80`N96A?9G)A;65?:&1R`"YD871A`"YE:%]F`(` -M``0`````````!`````0````G````"P````(```"\@P0(O`,``)`%```%```` -M`0````0````0````+P````,````"````3(D$"$P)``!$`P`````````````! -M`````````#<```#___]O`@```)",!`B0#```L@````0``````````@````(` -M``!$````_O__;P(```!$C00(1`T``#`````%`````0````0`````````4P`` -M``D````"````=(T$"'0-``!`````!``````````$````"````%P````)```` -M`@```+2-!`BT#0``,`(```0````+````!`````@```!E`````0````8```#D -MCP0(Y`\``!$```````````````0`````````8`````$````&````^(\$"/@/ -M``!P!``````````````$````!````&L````!````!@```'"4!`AP%```#$0` -M````````````$`````````!Q`````0````8```!\V`0(?%@```P````````` -M``````0`````````=P````$````"````B-@$"(A8``".!``````````````$ -M`````````'\````!`````@```!C=!`@870``'```````````````!``````` -M``"-`````0````,`````X`0(`&```#````````````````0`````````DP`` -M``$````"````,.`$"#!@``!8```````````````$`````````)T````&```` -M`P```(C@!`B(8```V`````4`````````!`````@```"F`````0````,```!@ -MX00(8&$```@```````````````0`````````K0````$````#````:.$$"&AA -M```(```````````````$`````````+0````!`````P```'#A!`AP80``!``` -M````````````!`````````"Y`````0````,```!TX00(=&$``"0!```````` -M``````0````$````O@````@````#````H.($"*!B``"L`0`````````````@ -M`````````,,````!``````````````"@8@``00,``````````````0`````` -M```!`````P``````````````X64``,P```````````````$````````````5 -M8```6%```!20```3Z```$^@```_D```HH```$U@``!&(```0B```2?```!*H -M```2J```%!@``!08```3:```%"@``!0H```4*```$[@``!%X```2*```$[@` -M`!*8```16```%"@``!.X```0"```$[@``!#8```4&```$1@``!*H```3>``` -M$2@``!'(```4&```$.@``!*X```1R```$-@``!*H```4&```$V@``!)(```3 -MN```$J@``!08```2J```%!@``!*H```4&```$K@``!*H```4&```$X@``!.( -M```3V```$R@``!)X```98```$N@``#?````0&```$G@``!E@```1V```$N@` -M`!)H```1>```$B@``!(H```WP```$!@``!#(```32```$X@``!.(```3J``` -M$Y@``!"(```12```$@@``$FP```0B```$#@``!"(```3F```$(@``!+(```2 -MV```$M@``!"(```RT```)@```"8````36```$S@``!"(```3"```$\@``!18 -M```46```%%@``!18```46```$#@``!18```2.```$C@``!(X```Q\```$M@` -M`!0(```0F```$&@``!08```2*```$B@``!"X```2.```$+@``!(X```2.``` -M-#```#0P```T,```-#```#0P```T,```-#```#0P```T,```-#```#0P```1 -MN```$6@``!#X```0>```$$@``!+X```3V```$,@``!-(```0R```$T@``!#( -M```32```$T@``!-(```32```$,@``!#(```0R```$,@``!-(```U$```-\`` -M`#A@```WP```,?```%;````2B```$H@``#N````0R```$T@``#N````0R``` -M$T@``!#(```32```$H@``!&8```2N```$H@``!08```[@```$,@``!#(```3 -M2```$T@``!(8```2J```$:@``!0X```1.```$_@``!*(```0J```$H@``#9@ -M```WP```,?```!*(```2J```$H@``#9@```U$```$H@``!*(``!6P```$H@` -M`!*(```0R```.&```!*H```42```$H@``#?````2J```$H@``#9@```V8``` -M$J@``!*H```2:```$7@``!`H```32```$_@``!*X```2:```$K@``!&H```2 -M:```$K@``!/8```3&```$U@``!)8```06```$0@``!)8```3V```$E@``!!8 -M```0R```$T@``!)8```1"```$,@``!#(```1"```$T@``!-(```0R```$T@` -M`!/8```26```$%@``!#(```32```$0@``!)8```2B```$0@``!#(```32``` -M$]@``!)8```06```$,@``!#(```0R```$,@``!#(```32```$T@``!-(```3 -M2```%!@``!-(```1"```$E@``!'H```1"```$,@``!#(```32```$T@``!/8 -M```5,```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@` -M``_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^``` -M#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/ -M^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X -M```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@` -M``_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^``` -M#_@```_X```/^```#_@``!'X```5D```$?@``!9````1^```%M```!'X```7 -M8```$?@``!?P```1^```$?@``!B@```A1```(5L``"#]```=7@``'6H``!YQ -M```>4```'5```!U0```>B@``'S$``!^B```EJ0``'LT``![-```?!0``&H$` -M`"$;```CMP``)?0``!JD```=5P``&J0``!JD```<````'/$``!S^```<_@`` -M)>```"7@```<5P``'%<``"2R```@R0``''```!QP```@/P``'^D``!XR```= -MN0``'C(``!FR```EJ0``)<<``"6]```DU```)1H``!HQ```=ZP``(#4``"2- -M```C00``(Y@``")U```A\@``(:,``"B"```G=P``*`@``"=H```GP```)X`` -M`"A&```GV```*"P``"A9```F@```)H```":2```H;@``)H```":````F@``` -M)Q```"<0```F<@``)H```"9R```F^0``)H```":^```F^0``*8L``#$P```O -MOP``+#H``#"!```K[0``+`<``#`3```P5```,#P``"_H```P8P``*QP``"L2 -M```K'```*?\``"HF```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,` -M`"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P`` -M*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I -M8P``*6,``"EC```I8P``*6,``"EC```IVP``*=L``"G;```KHP``,6T``"NM -M```K0@``,4P``"NM```KP```*ZT``"NM```KP```,Z```VF```-I@``#:8```V@0``-I@``#:8 -M```VF```-I@``%$0``!+(```3H```#ES```Y)@``.?D``#I*```[4@``.:@` -M`#HJ```YQ```.+(``#KB```ZP@``.OX``#IF```[-@``.J(``#L:```Y%0`` -M.9<``#GH```Y8@``.-H``#R(```[LP``.ZH``$`\``!`*@``/^L``#_K```_ -MN@``/X0``#]R```_A```/X0``#YT```^K0``/DT``#XT```^-```/+```#UP -M``!!5```09(``$"@``!!$```11P``$4<``!$]P``1J@``$95``!#5```0U0` -M`$-4``!(>P``1_4``$@U``!)!@``21H``$CC``!(Q0``1C```$8(``!%<``` -M17```$>P``!%WP``1^4``$?3``!%]```1O```$<```!&T```2,X``$(```!) -MI0``0?4``$>```!$4P``1((``$2"``!#M```0Z<``$(N``!"(```1/<``$2U -M``!(1P``2(X``$3)``!%N```1$8``$1U``!$=0``0L$``$-4``!#`P``1S`` -M`$-4``!"@```1,D``$-,``!$]P``0U0``$-4``!#`P``0P,``$@U``!(-0`` -M0U0``$K]``!-I0``3.0``$UO``!-1```3*,``$R!``!-\0``3=\``$MH``!, -M`0``3`H``$U5``!-_@``2V@``$W%``!.'```2V@``$O)``!,T@``3CH``$Y4 -M``!.<@``31,``$QP``!,70``3,@``$S2``!-"0``31,``$V>``!-E```39X` -M`%"%``!0:0``4`(``$_4``!.R```4+,``%"A``!.R```3S<``$]```!0P``` -M4-\``$[(``!/R0``3[8``%!6``!030``4%8``%44``!2L@``56D``%3?``!4 -MWP``5-\``%5&``!60```5B@``%44``!5=@``45@``%4T``!3J```5(```%/A -M``!48```5!```%2@``!40```5,```%*'``!2T```4OX``%,V``!3;@``4Y8` -M`%,@``!3*0``4N<``%+Q``!36```4V$``%.-``!3E@``5:```%+$``!2E``` -M5KH``%()``!2$@``4;T``%%8``!4^0``5F0``%9^``!6G```4H<``%*'``!2 -M;@``5>P``%7B``!5[```5A,``%8<``!7H@``5\```%<&``!7!@``5T```%=` -M`'__[(*_<*GBTO8J#[&TS@MGB4R]0=<':N.(W\G9G;.:/7*.,11&`00&``0) -MP)Q>A&R'N"<`!PL!``(!`!0#`P$;!`$!```"`P0,P)Q>P,!J``@*`3U]DI4` -J``4!$0\`>``X`#8`90!X`&4````4"@$``"U#*W&SG0$5!@$`(0`````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj2_copy_2.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj2_copy_2.7z.uu deleted file mode 100644 index b3d860e3c..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj2_copy_2.7z.uu +++ /dev/null @@ -1,615 +0,0 @@ -begin 644 test_read_format_7zip_bcj2_copy_2.7z -M-WJ\KR<<``-Y\RJ#YVH```````!K`````````/R]6^=_14Q&`0$!"0`````` -M`````@`#``$```!PE`0(-````+!F````````-``@``<`*``:`!D`!@```#0` -M```T@`0(-(`$".````#@````!0````0````#````%`$``!2!!`@4@00(%0`` -M`!4````$`````0````$``````````(`$"`"`!`@T70``-%T```4`````$``` -M`0````!@````X`0(`.`$")@"``!,!```!@`````0```"````B&```(C@!`B( -MX`0(V````-@````&````!`````0````L`0``+($$""R!!`@8````&`````0` -M```$````4.5T9!A=```8W00(&-T$"!P````<````!`````0````O;&EB97AE -M8R]L9"UE;&8N@(``!(```"]`@```````,\!```2 -M````?`(```````#.````$@```(8"````````0P```!(```!:`0```````&<& -M```2````>`$````````J````$@```&X"````````/@```!(````:`P``F.($ -M"``````0`/'_80$```````!5````$@```#,```!TX00(`````!$`\?\M`P`` -M3.0$"``````0`/'_BP(```````!B`P``$@```"L!``#4X@0(!````!$`%P`/ -M`0```````)L(```2````Y`$``-CB!`@$````$0`7`%,!`````````````!(` -M``"%`0```````!H````2````A`(````````K````$@```+0"````````*0`` -M`!(````4`0`````````````2````Y0(```````"+````$@```*$````````` -M8````!(```!)```````````````@````&P$```````!]````$@```$(!```` -M`````````!(```"!`````````!0!```2`````&QI8G5T:6PN7!E`'-T'0`@<` -M``(`.P,```````"@X@0(!18``,#B!`@%)0``Q.($"`4K``#(X@0(!34``,SB -M!`@%/```T.($"`4^``#4X@0(!4L``-CB!`@%30``@.$$"`E\M#G! -M<]N-=@#KJXVT)@````"-O"<`````58GEBU4,BT4(B54(B44,7>F-="8`C;PG -M`````%6)Y8/L"(D<)(ET)`2+=0B+70R+5DR+2TR+0B@Y02A^$+@!````BQPD -MBW0D!(GL7<-\#XM"+#E!+'_FD(UT)@!]![C_____Z]V+0U")10R+1E")10B+ -M'"2+="0$B>Q=Z8VV`````(V_`````%6)Y8M5#(M%"(E5"(E%#%WIC70F`(V\ -M)P````!5B>6#[`B)'"2)="0$BW4(BUT,BU9,BTM,BT)0.4%0?A"X`0```(L< -M)(MT)`2)[%W#?`^+0E0Y051_YI"-="8`?0>X_____^O=BT-0B44,BT90B44( -MBQPDBW0D!(GL7>F-M@````"-OP````!5B>6+50R+10B)50B)10Q=Z8UT)@"- -MO"<`````58GE@^P(B1PDB70D!(MU"(M=#(M63(M+3(M"&#E!&'X0N`$```"+ -M'"2+="0$B>Q=PWP/BT(<.4$F-="8` -MC;PG`````%6)Y8/L"(D<)(ET)`2+=0B+70R+5DR+2TR+0B`Y02!^$+@!```` -MBQPDBW0D!(GL7<-\#XM")#E!)'_FD(UT)@!]![C_____Z]V+0U")10R+1E") -M10B+'"2+="0$B>Q=Z8VV`````(V_`````%6)Y8M5#(M%"(E5"(E%#%WIC70F -M`(V\)P````!5B>6+10B+50R+0%")10R+0E")10A=Z9"-="8`58GEBT4,BT!0 -MB44,BT4(BT!0B44(7>F0D)"0D%6)Y8/L"(D<)(ET)`2+10B+30R+`(M00(/Z -M!W1SBQF+2T"#^0=T:8/Z"G1,@_D*=$%E/O_ -M_P````"%P'4-H43D!`B%P`^$QX5`^___`0```,<$)-S8!`CHQX6(^___```` -M`,>%C/O__P````#'A:#[__\`````QX6<^___`````,>%F/O__P````"%P(G# -MQX6H^___`````,>%K/O__P````#'A;#[__\`````QX6T^___`````,>%I/O_ -M_P````!T"8`X``^%B[T4^___A?\/A(N%$/O__XN]%/O__\>%+/O__P````#' -MA3#[__\`````@^`"QX4\^___`````,>%3/O__P````")A0S[___I@_@*#X2+ -MM1C[__^%]@^$BT=0@#@N#X2+1RP[A:S[__]V!HF%K/O__XL5).0$"(72=0J+ -M->SC!`B%]G0=B40D!(M'4(D$).@[A:S[__]V!HF%K/O__XN=0/O__X7;#X2+ -M5TR)T(M(/(N%M/O__XF5*/O__XM2.(G&P?X?.?%\#'\$.<)V!HF5M/O__XN5 -M*/O__XM"!#N%L/O__W8&B86P^___BXTH^___#[=!"CN%J/O__W8&B86H^___ -MBXTH^___BU$T.Y6,^___BT$P?!9_"#N%B/O__W8,B86(^___B96,^___BX4H -M^___BPU$Y`0(BT`X`84L^___AZ+5>PS%:#B!`@/A8'$+`4``%M>7UW#C70F`(L- -M\.($"(7)#X7'1PP!````QT<0`````.F#Z`$/A8L=[.($"(7;#X7KU(N5*/O_ -M_\=$)`0`````BT(,B00DZ(N-*/O__\=$)`0`````B85$^___BT$0B00DZ(F% -M2/O__^F#O3#[__\.#X>+E2C[__^+0A0PY#T``0``H3SD!`@9R8/A^8/!#X7` -MB8TP^___#X2+E4S[__^-1#,2B4,(B00DB50D!.B+C4S[__^)#"3HZ8N-*/O_ -M_XM!1(D$).B%P(F%3/O__P^$@#@`=2*)!"3HQP0D^M@$".B%P(F%3/O__P^$ -MBX5,^___B00DZ#N%H/O__XF%-/O__P^&B86@^___Z8V5D/O__XD4).B#P`$/ -MA(M'/(7`#X6+1U"-M;G[___'1"0(]-@$",=$)`0!!```B30DB40D#.B+A0S[ -M__^%P'1SBX60^___B30DB40D!.B#P`%T%+/O_ -M_P````#'A3S[__\`````QX4P^___`````*%$Y`0(A/&`3`/MD(!B$$! -M@\$"QD$!``^V0@*#P@&$P'7;@'G_.@^$C86D^___BY4<^___B40D*(V%K/O_ -M_XE$)"2-A8C[__^)1"0@C86@^___B40D'(V%G/O__XE$)!B-A9C[__^)1"04 -MC86H^___B40D$(V%M/O__XE$)`R-A;#[__^)1"0(QT0D!)39!`B)%"3HQP48 -MY`0(`0```(/X"`^&B[6P^___,<"%]G0@N0$```"X"@```/?A@^X!B<%U\L>% -ML/O__P````"-0/^+O;3[__^)A;#[__\QP(7_?C6)_KD!````,=MKTPJX"@`` -M`(F5!/O___?AB=.)P0.=!/O__X/N`77AQX6T^___`````(U`_XNUJ/O__XF% -MM/O__S'`A?9T(+D!````N`H```#WX8/N`8G!=?+'A:C[__\`````C4#_BXV, -M^___BY6(^___B86H^___@_D`B94@^___B8TD^___#XZ+C2#[__^^`0```#'_ -MBYTD^___:\<*B84$^___N`H```#WYHG7B<8#O03[__^#P?^#T_^)V@G*==J) -M\(GZ@\#_QX6(^___`````(/2_\>%C/O__P````"+C1S[__^)A8C[__^)E8S[ -M__^)#"3HZ8N-+/O__XU=NHN%M/O__\=$)`@/O__XN%J/O__XE$)`SHB1PDZ(F%?/O__Z'\ -MXP0(A%@/O__P4```"+A3#[__\[A8#[__]V!HF%@/O__XN%F/O__XF% -MA/O__^F+1U")1"0(BT<$BT`%M/O__P````#'A:C[__\`````QX68 -M^___`````,>%G/O__P````#'A:#[__\`````QX6(^___`````,>%C/O__P`` -M``#'A:S[__\`````@ST%I/O__P`````9P/?0(048Y`0(Z<=$)`3I -MV`0(QP0D`0```.AFQP$P`.F+E1S[__^)T8/!`F;'`C`ZQD("`.G'1"0$_-@$ -M",<$)`$```#HZ(VT)@````!5B>575E.#[!R#/?SB!`@!B47LB4WH&<`EP)@$ -M"(E$)`B)3"0$B10DZ(7`B<B)PC'`Z*'L -MX@0(A<`/A8LU!.,$"(7V#X3'1?``````C;0F`````(D\).B%P(G##X2+0T"# -M^`(/A(GV#X^#Z`%UU8M+/(7)=`R+0U"`."X/A*$DXP0(A<`/A*'`X@0(A<`/ -MA8L5S.($"(M""(/H`87`B4((#XB+`L8`"H/``8D"BT,B)PHG&B=CHH03C!`B%P`^%A?8/A(E<)`3'1"0(!``` -M`(D\).B)/"3HA<")PP^%Z(L`A<`/A8/$'%M>7UW#D(/X!'0)@_@'#X6+0R") -M!"3HB40D"(M#',<$)/#8!`B)1"0$Z,<%(.,$"`$```#ID(M#4,<$)"W9!`B) -M1"0$Z.F#?>P!#XZ+0QR)!"3HQP0D2MD$".C'!23C!`@!````Z8L=".0$"(7; -M#X7V1>@(QT7P``$```^%Z:',X@0(QP0D"@```(E$)`3HZ8L5\.($"(72#X3I -MB50D!,<$)`H```#HZ<=$)`1,V00(QP0D`0```.C'1"0$)-D$",<$)`$```#H -MC78`C;PG`````(U,)`2#Y/#_575E-1@>PX!@``BQFAH.($"(E%[#'` -MC87L_?__BWD$B87D^?__QT0D!,S;!`C'!"0`````Z,<$)`$```#HA<`/A,<% -M#.`$"%````#'!"15V00(Z(7`=`F`.``/A8V%W/G__XE$)`C'1"0$:'0(0,<$ -M)`$```#H@\`!=!0/MX7>^?__9H7`=`@/M\"C#.`$",<%#.0$"`$```"^$``` -M`,=$)`C(V00(B7PD!(D<).B#^/]T/X/H,8/X1W8PZ.O8QP4,XP0(`0```,<$ -M)%79!`CHASY__^)!"3H@^@!#X2+%1SD!`B%TG1&QP48Y`0(`0```,=$)`1@L@0( -MQP0D`@```.C'1"0$8+($",<$)`,```#HQP0DB=D$".B)!"3HH4#D!`B%P'5! -MH43D!`B%P'4XH?CC!`B%P'4OH13C!`B%P'4FH1CC!`B%P'4=H3#D!`B%P'44 -MBQTA%.,$"(7`#X6A&.,$"(7`#X3'!>3B!`B0E00( -MH0SC!`B%P'2?QP7@X@0(L+P$"(N%S/G__X7`=*R+ACY___'1"0$$.0$"(D$ -M).B+%1#D!`B)T,'X'\'H%P'0P?@)HQ#D!`CIQP0D9MD$".B%P`^%Z8/.(,<% -M\.($"`$```#IQP4,Y`0(`````,<%).0$"`$```#'!>SC!`@`````Z:'$X@0( -MH_3C!`CIQP4,XP0(`````,<%1.0$"`````#'!33D!`@`````Z<<%&.,$"`$` -M``#'!13C!`@`````Z<<%!.,$"`$```#I@^;\@\X0QP7XX@0(`0```.F#YN^# -MS@+'!?CB!`@`````Z<<%].($"`$```#I@\X!QP7XX@0(`````.G'1"0(`0`` -M`,=$)`3,VP0(QP0D7=D$".CIQP4PY`0(`0```,<%%.0$"`````#IQP4,XP0( -M`0```,<%1.0$"`````#'!1#C!`@`````Z<<%-.0$"`$```#'!43D!`@````` -MQP4,XP0(`````.G'!0SD!`@`````QP4DY`0(`````,<%[.,$"`````#IQP4$ -MY`0(`0```,<%Z.,$"`````#'!3CD!`@`````Z<<%%.,$"`$```#'!1CC!`@` -M````Z<<%^.,$"`$```#IQP4(XP0(`0```.G'!0SD!`@!````QP4DY`0(```` -M`,<%[.,$"`````#IQP44Y`0(`0```,<%,.0$"`$```#IQP4\Y`0(`0```.G' -M!0#C!`@!````Z<<%$.,$"`$```#'!0SC!`@`````QP5$Y`0(`````.G'!43D -M!`@!````QP4,XP0(`````,<%$.,$"`````#IQP7\XP0(`````,<%Z.($"`$` -M``#IQP5`Y`0(`0```.G'!?SC!`@!````Z<<%_.($"`$```#IQP7LX@0(`0`` -M`,<%!.,$"`````#IQP7HXP0(`0```,<%!.0$"`````#'!3CD!`@`````Z<<% -M#.0$"`````#'!23D!`@`````QP7LXP0(`0```.G'!0CD!`@!````Z<<%'.,$ -M"`$```#IQP4XY`0(`0```,<%!.0$"`````#'!>CC!`@`````Z<<%(.0$"`$` -M``#IZ(7`#X6A].($"(7`#X7'!?#B!`@!````Z8L=&.,$"(7;#X6+#03D!`B% -MR0^$QP7DX@0(8)<$".FA&.,$"(7`#X6A!.0$"(7`#X3'!>3B!`C0EP0(Z:$0 -MXP0(A3B!`B@F`0(Z<<%X.($ -M"$"]!`CIC9WD^?__B5PD!,<$)'K9!`CHB5PD!,<$)'W9!`BC\.,$".B)7"0$ -MQP0D@-D$"*,LY`0(Z(E<)`3'!"2#V00(HTCD!`CHB5PD!,<$)(;9!`BC*.0$ -M".B%P*,`Y`0(#X2A\.,$"(7`#X2+'2SD!`B%VP^$BPT`Y`0(A3B!`BPE@0(Z8L5..0$"(72=1BAZ.,$"(7`=#S'!>3B!`A`E@0(Z<<%Y.($ -M"-"6!`CIQP7DX@0(0)<$".G'!>3B!`A@F`0(Z<<%Y.($"/"7!`CIB5PD!,<$ -M).W8!`CHHP#D!`CID)"0D)"0D)"0D)!5B>6#[!B%P'0]H0#D!`C'1"0(H+($ -M",=$)`0!````B00DZ+B@L@0(B40D"*%(Y`0(QT0D!`$```")!"3HR<.A`.0$ -M",=$)`@`N`0(QT0D!`$```")!"3HN`"X!`CKP9"-="8`58GE4X/L%(M="(G8 -MZ(D<),=$)`0`````Z.B)7"0$B00DZ(/$%%M=PY"-M"8`````58GE@^PHBT4( -MQT0D"`$```#'!"0!````B$7_C47_B40D!.@QP,G#D(UT)@!5B>575E.#["R+ -M10B%P`^$BT4(,?^)!"3HBQ5@W`0(9L=%V@``QT7<`````(E5X(E%U.L\C70F -M``^^PH/H,&:#?=H`B0,/A&;'1=H!`(/&`8/#!(/^`G5%@\`:.,$"`````"-!#\Y1=1W.8M5X`^V`HA%\@^V0@&(1?.-!'\Q -M]HT'03#[["B40D -M!,<$)#37UW#QT4(S-L$".E5B>564XG#C31`@^P0 -MBQ2U:.,$"(72#X6+!+5@XP0(@_C_=#B)1"0(H?#C!`C'1"0$`````(D$).B% -MP'0;QT0D"`"X!`C'1"0$`0```(D$).B-=@"-!%N+!(5DXP0(@_C_=#6)1"0( -MH2SD!`C'1"0$`````(D$).B%P'08QT0D"`"X!`C'1"0$`0```(D$).B#Q!!; -M7EW#D(UT)@"A*.0$",=$)`@`N`0(QT0D!`$```")!"3HZ8VT)@````"-O"<` -M````#[?`B<)5@>(`\```B>6#[`B!^@!````/A'Y1@?H`H```#X2!^@#```!T -M8H'Z`&````^$,=*H271?]L0(#X7VQ`0/A+@(````C70F`.BZ`0```.LXC70F -M`('Z`!```'18@?H`(```B?9UO;@&````Z+H!````R8G0P[@"````Z+H!```` -MR8G0P[@!````Z+H!````R8G0P[@%````Z+H!````R8G0PXGVN`,```#HN@$` -M``#)B=##J`)T./;$`G01N`D```#HN@$```#KI[@*````Z+H!````ZY:X!``` -M`.BZ`0```.N%,<#HN@$```#IN`<```#HN@$```"0Z8UT)@"-O"<`````58GE -M4X/L=(E%F*&@X@0(B47X,<"A+.`$"(7`#XBA1.,$"(7`=':+'?3C!`B%VP^$ -MC468B00DZ(E<)`B-7:C'1"0$4````(D<)(E$)`SHHSC!`B%R70)B44(7>F+%0SD!`B% -MTG0)B44(7>F)10A=Z9!5B>6#[`BAP.($"(M-"(7`=2"+%!^@`0```/A('Z`$```(UT)@!T/JA)=,:AP.($ -M"(7`#X6+%6#[#B)7?2)PXE]_(G/B77XBW!,H4#D!`C'1>P`````A<`/A:'X -MXP0(A+0U")!"3HBTWLC1P(H1SD!`B%P'4W -MBSTPY`0(A?]T"P^W1@CH`<.)V(MU^(M=](M]_(GL7<.+0U")!"3HBU7LC1P0 -MZ\F%_W3%,<#HZ[RA$.0$"(/H`8E%X(G"BT8XP?H?`47@H1#D!`B)5>2+5CP1 -M5>2+3>2)PL'Z'XE4)`R+5>")3"0$B40D"(D4).B)?"0$QP0D>-L$"(E$)`B) -M5"0,Z`%%[.F+1@2)5"0$QP0D7<.)5"0$QP0D"@```.CKHXUV`%6)Y5=64X/L -M/(M%"(,]&.0$"`$9TH/B!XE%T(M`"(/"`3L%'.`$"(E5Z`^/BUW0QT7<```` -M`(L3A=)T)(L-0.,$"(M"#(/P`0M"$'0,BT72)5=B+3P!````BUW0H4#C!`B+4R"+2Q"+7=B+!)CHBQ4TY`0(A=(/A(/#`8M-W(E= -MV#E-V`^-BU7H`<:-'!8C7=0Y^W]>C70F`(L--.0$"(7)=`R+1P/C8L5 -MP.($"(72=5"+#B-'!8C7=0Y^WZFBTW,.4WL=&*#1>P!`WWPZ8GV@ST8Y`0( -M`8G>BQ7,X@0(&<"#X.F#P"")5"0$B00DZ.NX.T$8?`B`^@J-=@!UH(E,)`2) -MWHD4).CKFXM5X`%5V(M-W#E-V`^,H<#B!`B%P'4UBQ7,X@0(BT((@^@!A<") -M0@AX.8L"Q@`*@\`!B0*#1>0!BUW@.5WD#X6#Q#Q;7E]=PZ',X@0(QP0D"@`` -M`(E$)`3HZ]&)5"0$QP0D"@```.CKOXL]1.0$"(7_=0B%R0^$BTW0BQT0Y`0( -MBU$$QP0D?ML$"(/J`8T,&C'2B7UWIP>`" -MB40D!*%`XP0(B00DZ(7`B<)T%HM-T(D50.,$"(M!"*,575E.#[`R+=0B+'H7;#X0Q_^L7UW#H575E.!['P(``"+10B+%:#B!`B)5?`QTHLPB86D -M]___A?8/A(M&/(7`#X7'A:CW__\`````D(M&#(/P`0M&$`^$BQU`Y`0(BWY, -MA=L/A8L-^.,$"(7)#X6-3(`\```@?H` -M(```#X2!^@!@```/A('Z`.````^$BP`[!2C@!`@/A(M&/(7`#X6+1E"-G%(U-S(N5I/?__XM#!(E$)!R+0AR)1"08 -MBP.)1"04BT(LB40D$`^W1PJ)1"0,BT(DB4PD!,<$)(S;!`B)1"0(Z*$\Y`0( -MA<`/A:$(Y`0(A<`/A0^W1P@E`/```#T`(```#X0]`&````^$BXVD]___BT

    ")5"00B40D#,=$)`BFVP0(QT0D!!````")'"3HBX6L]___B5PD -M",<$)+O;!`B)1"0$Z*$$Y`0(A<`/A(M'&.BA'.0$"(7`#X0/MT<(Z(F%J/?_ -M_^F+0PR+C:3W__^)1"0(BT$8QP0DH-L$"(E$)`3HZ8UV`(M#"(N5I/?__XE$ -M)`B+0A3'!"2@VP0(B40D!.CIBPT0Y`0(C4'_BRL````BWT,C95P____BW4(H:#B!`B)1?`QP,=$)`B`````QT0D!``` -M``")%"3HA?_'A6#___\`````=%^-E7#___^-A6S___^)5"0,B7PD"(ET)`2) -M!"3HA<")PW0Y@_O_=&V#^_X/A(N5;/___X'Z_P```'=*H=#B!`B+1)`TJ0`` -M!`!T*8.%8/___P$!WH7_=:&+5?`S%:#B!`B+A6#___]U9H'$K````%M>7UW# -MBX5@____C028B85@____Z\V)%"3HZ[6)]HV%AT.($"(M$F#2I```$``^$,?:%_W\WZV:-="8`BQ7,X@0(BX5< -M____#[8,!HM""(/H`87`B4((#XB+`H@(@\`!B0*#Q@$Y]W0KH<#B!`B%P'3& -MHAT.($"(M$F#2)PH'B````X`^$B=#!Z!X!O5S___\!A6#____I.T(8 -M#[;9?`F`^PH/A8E4)`2)'"3HZ8L5P.($"(72#X6+%RL````BT4(BQ6@X@0(B57P,=+'1"0(@``` -M`,=$)`0`````B85<____C85P____B00DZ,>%8/___P````"+E5S___^-A7#_ -M__^)1"0,C85L____QT0D"`8```")!"2)5"0$Z(7`B<8/A(/^_@^$@_[_#X0Q -MVX7V?S/K78L5S.($"(N%7/___P^V#`.+0@B#Z`&%P(E""`^(BP*("(/``8D" -M@\,!.=YT+(L]P.($"(7_=,6AS.($"(N57/___XE$)`0/M@03@\,!B00DZ#G> -M==2+G6S___\!M5S___^!^_\```!W<*'0X@0(BT28-*D```0`#X0QP(7;="B! -M^_\````/AZ'0X@0(BT28-(G"@>(```#@#X2)T,'H'@&%8/___^D[0A@/MOE\ -M"HGX/`H/A8E4)`2)/"3HZ8D<).B0ZXZ-A7#____'1"0(@````,=$)`0````` -MB00DZ*'`X@0(A<`/A8L5S.($"(N%7/___P^V"(M""(/H`87`B4((#XB+`H@( -M@\`!B0*#A5S___\!@X5@____`>F+E5S____'!"3TV`0(B50D!.@!A6#___^+ -M5?`S%:#B!`B+A6#___]U:X'$K````%M>7UW#)0``!`"#^`$9P(/(`>F)'"3H -MZ:',X@0(BY5<____B40D!`^V`HD$).CI.T(8#[;9?`F`^PH/A8E4)`2)'"3H -MZ>B-=@"-O"<`````58GE5U93@>RL````BT4(BQ6@X@0(B57P,=+'1"0(@``` -M`,=$)`0`````B858____C85P____B00DZ,>%8/___P````"+E5C___^-A7#_ -M__^)1"0,C85L____QT0D"`8```")!"2)5"0$Z(7`B85<____#X2+A5S___^# -MP`*#^`$/AHN=;/___X'[_P````^'H=#B!`B+1)@TJ0``!``/A(/[(@^$@_M< -M#X2+O5S___^%_WYO,=OK-8L5S.($"(N%6/___P^V#`.+0@B#Z`&%P(E""`^( -MBP*("(/``8D"@\,!.YU<____=#"+-<#B!`B%]G3!H@>`85@____@[U<_____@^$@[U<_____P^$BY5< -M____`958____Z8.]7/____\/A;\!````,?;ID(UT)@"+%#P#")!"3HH<#B!`B%P`^$C;0F`````*',X@0(B40D!(G8@^`'@\`PB00D -MZ.F)]CM"&'P)@/D*#X6)5"0$B0PDZ.F0.T(8#XV)5"0$QP0D7````.CIB?8[ -M0AA\"8#Y"@^%B50D!(D,).CID#M"&'P)@/D*#X6)5"0$B0PDZ.F+#>SC!`B% -MR700A=MX#('[_P````^.B[U<____A?\/CX.]7/____X/A8M5\#,5H.($"(N% -M8/___P^%@<2L````6UY?7<.+A5C___^)!"3HB575H/L,(M5 -M#(M%"(MU$(M]%(E5W(M-W(E%V,=%T`````")\,=%U`````")^H7)QT7D```` -M``^(A?\/B(G7B<:+5=B)P8M%W(7_B57PB47L=10YQG9!B="+5>SW]HG!,<#K -M$XUV`#M]['9/,2)1=2+1="+5=2%R70']]B#T@#W -MVH/$,%Y?7<.%]G4+N`$````QTO?VB<&+1>R)^O?QB<:+1?#W\8G!B?#KO`^] -MQX/P'XE%Z'5$.7WL=P4Y=?!RG+D!````,<#KGO==V(-5W`#W7=R%_\=%Y/__ -M__\/B9"-="8`B?")^O?8@](`]]KW5>3IN"````")\BM%Z(G!T^H/MDWHB47T -MB?B)UXM5[-/@"<>+1?#3Y@^V3?33Z`^V3>C3X@^V3?0)T(M5[(E%S-/J]_>) -M5&-X9'AB>&5G961A8F%G86-A9`````!,4T-/3$]24R!S:&]U;&0@=7-E -M(&-H87)A8W1ED`0(KI`$"+Z0!`C.D`0(WI`$".Z0!`C^D`0(#I$$"!Z1!`@ND00( -M/I$$"$Z1!`A>D00(;I$$"'Z1!`B.D00(GI$$"*Z1!`B^D00(SI$$"-Z1!`CN -MD00(_I$$"`Z2!`@>D@0(+I($"#Z2!`A.D@0(7I($"&Z2!`A^D@0(CI($")Z2 -M!`BND@0(OI($",Z2!`C>D@0([I($"/Z2!`@.DP0('I,$""Z3!`@^DP0(3I,$ -M"%Z3!`ANDP0(?I,$"(Z3!`B>DP0(KI,$"+Z3!`C.DP0(WI,$".Z3!`C^DP0( -M#I0$"!Z4!`@NE`0(/I0$"$Z4!`A>E`0(````````````)$9R965"4T0Z('-R -M8R]L:6(O8W-U+VDS.#8M96QF+V-R=#%?'`@)```)$9R965"4T0Z('-R8R]L:6(O8W-U -M+V-O;6UO;B]C'`@ -M)`!'0T,Z("A'3E4I(#0N,BXR(#(P,#6YS>6T`+F1Y;G-T<@`N9VYU+G9E6X`+G)E;"YP;'0`+FEN:70`+G1E>'0`+F9I;FD`+G)O9&%T -M80`N96A?9G)A;65?:&1R`"YD871A`"YE:%]F`(` -M``0`````````!`````0````G````"P````(```"\@P0(O`,``)`%```%```` -M`0````0````0````+P````,````"````3(D$"$P)``!$`P`````````````! -M`````````#<```#___]O`@```)",!`B0#```L@````0``````````@````(` -M``!$````_O__;P(```!$C00(1`T``#`````%`````0````0`````````4P`` -M``D````"````=(T$"'0-``!`````!``````````$````"````%P````)```` -M`@```+2-!`BT#0``,`(```0````+````!`````@```!E`````0````8```#D -MCP0(Y`\``!$```````````````0`````````8`````$````&````^(\$"/@/ -M``!P!``````````````$````!````&L````!````!@```'"4!`AP%```#$0` -M````````````$`````````!Q`````0````8```!\V`0(?%@```P````````` -M``````0`````````=P````$````"````B-@$"(A8``".!``````````````$ -M`````````'\````!`````@```!C=!`@870``'```````````````!``````` -M``"-`````0````,`````X`0(`&```#````````````````0`````````DP`` -M``$````"````,.`$"#!@``!8```````````````$`````````)T````&```` -M`P```(C@!`B(8```V`````4`````````!`````@```"F`````0````,```!@ -MX00(8&$```@```````````````0`````````K0````$````#````:.$$"&AA -M```(```````````````$`````````+0````!`````P```'#A!`AP80``!``` -M````````````!`````````"Y`````0````,```!TX00(=&$``"0!```````` -M``````0````$````O@````@````#````H.($"*!B``"L`0`````````````@ -M`````````,,````!``````````````"@8@``00,``````````````0`````` -M```!`````P``````````````X64``,P```````````````$````````````5 -M8```6%```!20```3Z```$^@```_D```HH```$U@``!&(```0B```2?```!*H -M```2J```%!@``!08```3:```%"@``!0H```4*```$[@``!%X```2*```$[@` -M`!*8```16```%"@``!.X```0"```$[@``!#8```4&```$1@``!*H```3>``` -M$2@``!'(```4&```$.@``!*X```1R```$-@``!*H```4&```$V@``!)(```3 -MN```$J@``!08```2J```%!@``!*H```4&```$K@``!*H```4&```$X@``!.( -M```3V```$R@``!)X```98```$N@``#?````0&```$G@``!E@```1V```$N@` -M`!)H```1>```$B@``!(H```WP```$!@``!#(```32```$X@``!.(```3J``` -M$Y@``!"(```12```$@@``$FP```0B```$#@``!"(```3F```$(@``!+(```2 -MV```$M@``!"(```RT```)@```"8````36```$S@``!"(```3"```$\@``!18 -M```46```%%@``!18```46```$#@``!18```2.```$C@``!(X```Q\```$M@` -M`!0(```0F```$&@``!08```2*```$B@``!"X```2.```$+@``!(X```2.``` -M-#```#0P```T,```-#```#0P```T,```-#```#0P```T,```-#```#0P```1 -MN```$6@``!#X```0>```$$@``!+X```3V```$,@``!-(```0R```$T@``!#( -M```32```$T@``!-(```32```$,@``!#(```0R```$,@``!-(```U$```-\`` -M`#A@```WP```,?```%;````2B```$H@``#N````0R```$T@``#N````0R``` -M$T@``!#(```32```$H@``!&8```2N```$H@``!08```[@```$,@``!#(```3 -M2```$T@``!(8```2J```$:@``!0X```1.```$_@``!*(```0J```$H@``#9@ -M```WP```,?```!*(```2J```$H@``#9@```U$```$H@``!*(``!6P```$H@` -M`!*(```0R```.&```!*H```42```$H@``#?````2J```$H@``#9@```V8``` -M$J@``!*H```2:```$7@``!`H```32```$_@``!*X```2:```$K@``!&H```2 -M:```$K@``!/8```3&```$U@``!)8```06```$0@``!)8```3V```$E@``!!8 -M```0R```$T@``!)8```1"```$,@``!#(```1"```$T@``!-(```0R```$T@` -M`!/8```26```$%@``!#(```32```$0@``!)8```2B```$0@``!#(```32``` -M$]@``!)8```06```$,@``!#(```0R```$,@``!#(```32```$T@``!-(```3 -M2```%!@``!-(```1"```$E@``!'H```1"```$,@``!#(```32```$T@``!/8 -M```5,```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@` -M``_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^``` -M#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/ -M^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X -M```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@` -M``_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^``` -M#_@```_X```/^```#_@``!'X```5D```$?@``!9````1^```%M```!'X```7 -M8```$?@``!?P```1^```$?@``!B@```A1```(5L``"#]```=7@``'6H``!YQ -M```>4```'5```!U0```>B@``'S$``!^B```EJ0``'LT``![-```?!0``&H$` -M`"$;```CMP``)?0``!JD```=5P``&J0``!JD```<````'/$``!S^```<_@`` -M)>```"7@```<5P``'%<``"2R```@R0``''```!QP```@/P``'^D``!XR```= -MN0``'C(``!FR```EJ0``)<<``"6]```DU```)1H``!HQ```=ZP``(#4``"2- -M```C00``(Y@``")U```A\@``(:,``"B"```G=P``*`@``"=H```GP```)X`` -M`"A&```GV```*"P``"A9```F@```)H```":2```H;@``)H```":````F@``` -M)Q```"<0```F<@``)H```"9R```F^0``)H```":^```F^0``*8L``#$P```O -MOP``+#H``#"!```K[0``+`<``#`3```P5```,#P``"_H```P8P``*QP``"L2 -M```K'```*?\``"HF```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,` -M`"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P`` -M*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I -M8P``*6,``"EC```I8P``*6,``"EC```IVP``*=L``"G;```KHP``,6T``"NM -M```K0@``,4P``"NM```KP```*ZT``"NM```KP```,Z```VF```-I@``#:8```V@0``-I@``#:8 -M```VF```-I@``%$0``!+(```3H```#ES```Y)@``.?D``#I*```[4@``.:@` -M`#HJ```YQ```.+(``#KB```ZP@``.OX``#IF```[-@``.J(``#L:```Y%0`` -M.9<``#GH```Y8@``.-H``#R(```[LP``.ZH``$`\``!`*@``/^L``#_K```_ -MN@``/X0``#]R```_A```/X0``#YT```^K0``/DT``#XT```^-```/+```#UP -M``!!5```09(``$"@``!!$```11P``$4<``!$]P``1J@``$95``!#5```0U0` -M`$-4``!(>P``1_4``$@U``!)!@``21H``$CC``!(Q0``1C```$8(``!%<``` -M17```$>P``!%WP``1^4``$?3``!%]```1O```$<```!&T```2,X``$(```!) -MI0``0?4``$>```!$4P``1((``$2"``!#M```0Z<``$(N``!"(```1/<``$2U -M``!(1P``2(X``$3)``!%N```1$8``$1U``!$=0``0L$``$-4``!#`P``1S`` -M`$-4``!"@```1,D``$-,``!$]P``0U0``$-4``!#`P``0P,``$@U``!(-0`` -M0U0``$K]``!-I0``3.0``$UO``!-1```3*,``$R!``!-\0``3=\``$MH``!, -M`0``3`H``$U5``!-_@``2V@``$W%``!.'```2V@``$O)``!,T@``3CH``$Y4 -M``!.<@``31,``$QP``!,70``3,@``$S2``!-"0``31,``$V>``!-E```39X` -M`%"%``!0:0``4`(``$_4``!.R```4+,``%"A``!.R```3S<``$]```!0P``` -M4-\``$[(``!/R0``3[8``%!6``!030``4%8``%44``!2L@``56D``%3?``!4 -MWP``5-\``%5&``!60```5B@``%44``!5=@``45@``%4T``!3J```5(```%/A -M``!48```5!```%2@``!40```5,```%*'``!2T```4OX``%,V``!3;@``4Y8` -M`%,@``!3*0``4N<``%+Q``!36```4V$``%.-``!3E@``5:```%+$``!2E``` -M5KH``%()``!2$@``4;T``%%8``!4^0``5F0``%9^``!6G```4H<``%*'``!2 -M;@``5>P``%7B``!5[```5A,``%8<``!7H@``5\```%<&``!7!@``5T```%=` -M`'__[(*_<*GBTO8J#[&TS@MGB4R]0=<':N.(W\G9G;.:/7*.,11&`00&``0) -MP)Q>A&R'N"<`!PL!``0!``$``0`4`P,!&P0!`0`"`0,"``0%!@S`G%[`G%[` -MG%[`P&H`"`H!/7V2E0``!0$1#P!X`#@`-@!E`'@`90```!0*`0``+4,K<;.= -+`14&`0`A```````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj2_copy_lzma.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj2_copy_lzma.7z.uu deleted file mode 100644 index ff1ce4a55..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj2_copy_lzma.7z.uu +++ /dev/null @@ -1,568 +0,0 @@ -begin 644 test_read_format_7zip_bcj2_copy_lzma.7z -M-WJ\KR<<``-+E]7GI6(```````!Y`````````%QS)"Q_14Q&`0$!"0`````` -M`````@`#``$```!PE`0(-````+!F````````-``@``<`*``:`!D`!@```#0` -M```T@`0(-(`$".````#@````!0````0````#````%`$``!2!!`@4@00(%0`` -M`!4````$`````0````$``````````(`$"`"`!`@T70``-%T```4`````$``` -M`0````!@````X`0(`.`$")@"``!,!```!@`````0```"````B&```(C@!`B( -MX`0(V````-@````&````!`````0````L`0``+($$""R!!`@8````&`````0` -M```$````4.5T9!A=```8W00(&-T$"!P````<````!`````0````O;&EB97AE -M8R]L9"UE;&8N@(``!(```"]`@```````,\!```2 -M````?`(```````#.````$@```(8"````````0P```!(```!:`0```````&<& -M```2````>`$````````J````$@```&X"````````/@```!(````:`P``F.($ -M"``````0`/'_80$```````!5````$@```#,```!TX00(`````!$`\?\M`P`` -M3.0$"``````0`/'_BP(```````!B`P``$@```"L!``#4X@0(!````!$`%P`/ -M`0```````)L(```2````Y`$``-CB!`@$````$0`7`%,!`````````````!(` -M``"%`0```````!H````2````A`(````````K````$@```+0"````````*0`` -M`!(````4`0`````````````2````Y0(```````"+````$@```*$````````` -M8````!(```!)```````````````@````&P$```````!]````$@```$(!```` -M`````````!(```"!`````````!0!```2`````&QI8G5T:6PN7!E`'-T'0`@<` -M``(`.P,```````"@X@0(!18``,#B!`@%)0``Q.($"`4K``#(X@0(!34``,SB -M!`@%/```T.($"`4^``#4X@0(!4L``-CB!`@%30``@.$$"`E\M#G! -M<]N-=@#KJXVT)@````"-O"<`````58GEBU4,BT4(B54(B44,7>F-="8`C;PG -M`````%6)Y8/L"(D<)(ET)`2+=0B+70R+5DR+2TR+0B@Y02A^$+@!````BQPD -MBW0D!(GL7<-\#XM"+#E!+'_FD(UT)@!]![C_____Z]V+0U")10R+1E")10B+ -M'"2+="0$B>Q=Z8VV`````(V_`````%6)Y8M5#(M%"(E5"(E%#%WIC70F`(V\ -M)P````!5B>6#[`B)'"2)="0$BW4(BUT,BU9,BTM,BT)0.4%0?A"X`0```(L< -M)(MT)`2)[%W#?`^+0E0Y051_YI"-="8`?0>X_____^O=BT-0B44,BT90B44( -MBQPDBW0D!(GL7>F-M@````"-OP````!5B>6+50R+10B)50B)10Q=Z8UT)@"- -MO"<`````58GE@^P(B1PDB70D!(MU"(M=#(M63(M+3(M"&#E!&'X0N`$```"+ -M'"2+="0$B>Q=PWP/BT(<.4$F-="8` -MC;PG`````%6)Y8/L"(D<)(ET)`2+=0B+70R+5DR+2TR+0B`Y02!^$+@!```` -MBQPDBW0D!(GL7<-\#XM")#E!)'_FD(UT)@!]![C_____Z]V+0U")10R+1E") -M10B+'"2+="0$B>Q=Z8VV`````(V_`````%6)Y8M5#(M%"(E5"(E%#%WIC70F -M`(V\)P````!5B>6+10B+50R+0%")10R+0E")10A=Z9"-="8`58GEBT4,BT!0 -MB44,BT4(BT!0B44(7>F0D)"0D%6)Y8/L"(D<)(ET)`2+10B+30R+`(M00(/Z -M!W1SBQF+2T"#^0=T:8/Z"G1,@_D*=$%E/O_ -M_P````"%P'4-H43D!`B%P`^$QX5`^___`0```,<$)-S8!`CHQX6(^___```` -M`,>%C/O__P````#'A:#[__\`````QX6<^___`````,>%F/O__P````"%P(G# -MQX6H^___`````,>%K/O__P````#'A;#[__\`````QX6T^___`````,>%I/O_ -M_P````!T"8`X``^%B[T4^___A?\/A(N%$/O__XN]%/O__\>%+/O__P````#' -MA3#[__\`````@^`"QX4\^___`````,>%3/O__P````")A0S[___I@_@*#X2+ -MM1C[__^%]@^$BT=0@#@N#X2+1RP[A:S[__]V!HF%K/O__XL5).0$"(72=0J+ -M->SC!`B%]G0=B40D!(M'4(D$).@[A:S[__]V!HF%K/O__XN=0/O__X7;#X2+ -M5TR)T(M(/(N%M/O__XF5*/O__XM2.(G&P?X?.?%\#'\$.<)V!HF5M/O__XN5 -M*/O__XM"!#N%L/O__W8&B86P^___BXTH^___#[=!"CN%J/O__W8&B86H^___ -MBXTH^___BU$T.Y6,^___BT$P?!9_"#N%B/O__W8,B86(^___B96,^___BX4H -M^___BPU$Y`0(BT`X`84L^___AZ+5>PS%:#B!`@/A8'$+`4``%M>7UW#C70F`(L- -M\.($"(7)#X7'1PP!````QT<0`````.F#Z`$/A8L=[.($"(7;#X7KU(N5*/O_ -M_\=$)`0`````BT(,B00DZ(N-*/O__\=$)`0`````B85$^___BT$0B00DZ(F% -M2/O__^F#O3#[__\.#X>+E2C[__^+0A0PY#T``0``H3SD!`@9R8/A^8/!#X7` -MB8TP^___#X2+E4S[__^-1#,2B4,(B00DB50D!.B+C4S[__^)#"3HZ8N-*/O_ -M_XM!1(D$).B%P(F%3/O__P^$@#@`=2*)!"3HQP0D^M@$".B%P(F%3/O__P^$ -MBX5,^___B00DZ#N%H/O__XF%-/O__P^&B86@^___Z8V5D/O__XD4).B#P`$/ -MA(M'/(7`#X6+1U"-M;G[___'1"0(]-@$",=$)`0!!```B30DB40D#.B+A0S[ -M__^%P'1SBX60^___B30DB40D!.B#P`%T%+/O_ -M_P````#'A3S[__\`````QX4P^___`````*%$Y`0(A/&`3`/MD(!B$$! -M@\$"QD$!``^V0@*#P@&$P'7;@'G_.@^$C86D^___BY4<^___B40D*(V%K/O_ -M_XE$)"2-A8C[__^)1"0@C86@^___B40D'(V%G/O__XE$)!B-A9C[__^)1"04 -MC86H^___B40D$(V%M/O__XE$)`R-A;#[__^)1"0(QT0D!)39!`B)%"3HQP48 -MY`0(`0```(/X"`^&B[6P^___,<"%]G0@N0$```"X"@```/?A@^X!B<%U\L>% -ML/O__P````"-0/^+O;3[__^)A;#[__\QP(7_?C6)_KD!````,=MKTPJX"@`` -M`(F5!/O___?AB=.)P0.=!/O__X/N`77AQX6T^___`````(U`_XNUJ/O__XF% -MM/O__S'`A?9T(+D!````N`H```#WX8/N`8G!=?+'A:C[__\`````C4#_BXV, -M^___BY6(^___B86H^___@_D`B94@^___B8TD^___#XZ+C2#[__^^`0```#'_ -MBYTD^___:\<*B84$^___N`H```#WYHG7B<8#O03[__^#P?^#T_^)V@G*==J) -M\(GZ@\#_QX6(^___`````(/2_\>%C/O__P````"+C1S[__^)A8C[__^)E8S[ -M__^)#"3HZ8N-+/O__XU=NHN%M/O__\=$)`@/O__XN%J/O__XE$)`SHB1PDZ(F%?/O__Z'\ -MXP0(A%@/O__P4```"+A3#[__\[A8#[__]V!HF%@/O__XN%F/O__XF% -MA/O__^F+1U")1"0(BT<$BT`%M/O__P````#'A:C[__\`````QX68 -M^___`````,>%G/O__P````#'A:#[__\`````QX6(^___`````,>%C/O__P`` -M``#'A:S[__\`````@ST%I/O__P`````9P/?0(048Y`0(Z<=$)`3I -MV`0(QP0D`0```.AFQP$P`.F+E1S[__^)T8/!`F;'`C`ZQD("`.G'1"0$_-@$ -M",<$)`$```#HZ(VT)@````!5B>575E.#[!R#/?SB!`@!B47LB4WH&<`EP)@$ -M"(E$)`B)3"0$B10DZ(7`B<B)PC'`Z*'L -MX@0(A<`/A8LU!.,$"(7V#X3'1?``````C;0F`````(D\).B%P(G##X2+0T"# -M^`(/A(GV#X^#Z`%UU8M+/(7)=`R+0U"`."X/A*$DXP0(A<`/A*'`X@0(A<`/ -MA8L5S.($"(M""(/H`87`B4((#XB+`L8`"H/``8D"BT,B)PHG&B=CHH03C!`B%P`^%A?8/A(E<)`3'1"0(!``` -M`(D\).B)/"3HA<")PP^%Z(L`A<`/A8/$'%M>7UW#D(/X!'0)@_@'#X6+0R") -M!"3HB40D"(M#',<$)/#8!`B)1"0$Z,<%(.,$"`$```#ID(M#4,<$)"W9!`B) -M1"0$Z.F#?>P!#XZ+0QR)!"3HQP0D2MD$".C'!23C!`@!````Z8L=".0$"(7; -M#X7V1>@(QT7P``$```^%Z:',X@0(QP0D"@```(E$)`3HZ8L5\.($"(72#X3I -MB50D!,<$)`H```#HZ<=$)`1,V00(QP0D`0```.C'1"0$)-D$",<$)`$```#H -MC78`C;PG`````(U,)`2#Y/#_575E-1@>PX!@``BQFAH.($"(E%[#'` -MC87L_?__BWD$B87D^?__QT0D!,S;!`C'!"0`````Z,<$)`$```#HA<`/A,<% -M#.`$"%````#'!"15V00(Z(7`=`F`.``/A8V%W/G__XE$)`C'1"0$:'0(0,<$ -M)`$```#H@\`!=!0/MX7>^?__9H7`=`@/M\"C#.`$",<%#.0$"`$```"^$``` -M`,=$)`C(V00(B7PD!(D<).B#^/]T/X/H,8/X1W8PZ.O8QP4,XP0(`0```,<$ -M)%79!`CHASY__^)!"3H@^@!#X2+%1SD!`B%TG1&QP48Y`0(`0```,=$)`1@L@0( -MQP0D`@```.C'1"0$8+($",<$)`,```#HQP0DB=D$".B)!"3HH4#D!`B%P'5! -MH43D!`B%P'4XH?CC!`B%P'4OH13C!`B%P'4FH1CC!`B%P'4=H3#D!`B%P'44 -MBQTA%.,$"(7`#X6A&.,$"(7`#X3'!>3B!`B0E00( -MH0SC!`B%P'2?QP7@X@0(L+P$"(N%S/G__X7`=*R+ACY___'1"0$$.0$"(D$ -M).B+%1#D!`B)T,'X'\'H%P'0P?@)HQ#D!`CIQP0D9MD$".B%P`^%Z8/.(,<% -M\.($"`$```#IQP4,Y`0(`````,<%).0$"`$```#'!>SC!`@`````Z:'$X@0( -MH_3C!`CIQP4,XP0(`````,<%1.0$"`````#'!33D!`@`````Z<<%&.,$"`$` -M``#'!13C!`@`````Z<<%!.,$"`$```#I@^;\@\X0QP7XX@0(`0```.F#YN^# -MS@+'!?CB!`@`````Z<<%].($"`$```#I@\X!QP7XX@0(`````.G'1"0(`0`` -M`,=$)`3,VP0(QP0D7=D$".CIQP4PY`0(`0```,<%%.0$"`````#IQP4,XP0( -M`0```,<%1.0$"`````#'!1#C!`@`````Z<<%-.0$"`$```#'!43D!`@````` -MQP4,XP0(`````.G'!0SD!`@`````QP4DY`0(`````,<%[.,$"`````#IQP4$ -MY`0(`0```,<%Z.,$"`````#'!3CD!`@`````Z<<%%.,$"`$```#'!1CC!`@` -M````Z<<%^.,$"`$```#IQP4(XP0(`0```.G'!0SD!`@!````QP4DY`0(```` -M`,<%[.,$"`````#IQP44Y`0(`0```,<%,.0$"`$```#IQP4\Y`0(`0```.G' -M!0#C!`@!````Z<<%$.,$"`$```#'!0SC!`@`````QP5$Y`0(`````.G'!43D -M!`@!````QP4,XP0(`````,<%$.,$"`````#IQP7\XP0(`````,<%Z.($"`$` -M``#IQP5`Y`0(`0```.G'!?SC!`@!````Z<<%_.($"`$```#IQP7LX@0(`0`` -M`,<%!.,$"`````#IQP7HXP0(`0```,<%!.0$"`````#'!3CD!`@`````Z<<% -M#.0$"`````#'!23D!`@`````QP7LXP0(`0```.G'!0CD!`@!````Z<<%'.,$ -M"`$```#IQP4XY`0(`0```,<%!.0$"`````#'!>CC!`@`````Z<<%(.0$"`$` -M``#IZ(7`#X6A].($"(7`#X7'!?#B!`@!````Z8L=&.,$"(7;#X6+#03D!`B% -MR0^$QP7DX@0(8)<$".FA&.,$"(7`#X6A!.0$"(7`#X3'!>3B!`C0EP0(Z:$0 -MXP0(A3B!`B@F`0(Z<<%X.($ -M"$"]!`CIC9WD^?__B5PD!,<$)'K9!`CHB5PD!,<$)'W9!`BC\.,$".B)7"0$ -MQP0D@-D$"*,LY`0(Z(E<)`3'!"2#V00(HTCD!`CHB5PD!,<$)(;9!`BC*.0$ -M".B%P*,`Y`0(#X2A\.,$"(7`#X2+'2SD!`B%VP^$BPT`Y`0(A3B!`BPE@0(Z8L5..0$"(72=1BAZ.,$"(7`=#S'!>3B!`A`E@0(Z<<%Y.($ -M"-"6!`CIQP7DX@0(0)<$".G'!>3B!`A@F`0(Z<<%Y.($"/"7!`CIB5PD!,<$ -M).W8!`CHHP#D!`CID)"0D)"0D)"0D)!5B>6#[!B%P'0]H0#D!`C'1"0(H+($ -M",=$)`0!````B00DZ+B@L@0(B40D"*%(Y`0(QT0D!`$```")!"3HR<.A`.0$ -M",=$)`@`N`0(QT0D!`$```")!"3HN`"X!`CKP9"-="8`58GE4X/L%(M="(G8 -MZ(D<),=$)`0`````Z.B)7"0$B00DZ(/$%%M=PY"-M"8`````58GE@^PHBT4( -MQT0D"`$```#'!"0!````B$7_C47_B40D!.@QP,G#D(UT)@!5B>575E.#["R+ -M10B%P`^$BT4(,?^)!"3HBQ5@W`0(9L=%V@``QT7<`````(E5X(E%U.L\C70F -M``^^PH/H,&:#?=H`B0,/A&;'1=H!`(/&`8/#!(/^`G5%@\`:.,$"`````"-!#\Y1=1W.8M5X`^V`HA%\@^V0@&(1?.-!'\Q -M]HT'03#[["B40D -M!,<$)#37UW#QT4(S-L$".E5B>564XG#C31`@^P0 -MBQ2U:.,$"(72#X6+!+5@XP0(@_C_=#B)1"0(H?#C!`C'1"0$`````(D$).B% -MP'0;QT0D"`"X!`C'1"0$`0```(D$).B-=@"-!%N+!(5DXP0(@_C_=#6)1"0( -MH2SD!`C'1"0$`````(D$).B%P'08QT0D"`"X!`C'1"0$`0```(D$).B#Q!!; -M7EW#D(UT)@"A*.0$",=$)`@`N`0(QT0D!`$```")!"3HZ8VT)@````"-O"<` -M````#[?`B<)5@>(`\```B>6#[`B!^@!````/A'Y1@?H`H```#X2!^@#```!T -M8H'Z`&````^$,=*H271?]L0(#X7VQ`0/A+@(````C70F`.BZ`0```.LXC70F -M`('Z`!```'18@?H`(```B?9UO;@&````Z+H!````R8G0P[@"````Z+H!```` -MR8G0P[@!````Z+H!````R8G0P[@%````Z+H!````R8G0PXGVN`,```#HN@$` -M``#)B=##J`)T./;$`G01N`D```#HN@$```#KI[@*````Z+H!````ZY:X!``` -M`.BZ`0```.N%,<#HN@$```#IN`<```#HN@$```"0Z8UT)@"-O"<`````58GE -M4X/L=(E%F*&@X@0(B47X,<"A+.`$"(7`#XBA1.,$"(7`=':+'?3C!`B%VP^$ -MC468B00DZ(E<)`B-7:C'1"0$4````(D<)(E$)`SHHSC!`B%R70)B44(7>F+%0SD!`B% -MTG0)B44(7>F)10A=Z9!5B>6#[`BAP.($"(M-"(7`=2"+%!^@`0```/A('Z`$```(UT)@!T/JA)=,:AP.($ -M"(7`#X6+%6#[#B)7?2)PXE]_(G/B77XBW!,H4#D!`C'1>P`````A<`/A:'X -MXP0(A+0U")!"3HBTWLC1P(H1SD!`B%P'4W -MBSTPY`0(A?]T"P^W1@CH`<.)V(MU^(M=](M]_(GL7<.+0U")!"3HBU7LC1P0 -MZ\F%_W3%,<#HZ[RA$.0$"(/H`8E%X(G"BT8XP?H?`47@H1#D!`B)5>2+5CP1 -M5>2+3>2)PL'Z'XE4)`R+5>")3"0$B40D"(D4).B)?"0$QP0D>-L$"(E$)`B) -M5"0,Z`%%[.F+1@2)5"0$QP0D7<.)5"0$QP0D"@```.CKHXUV`%6)Y5=64X/L -M/(M%"(,]&.0$"`$9TH/B!XE%T(M`"(/"`3L%'.`$"(E5Z`^/BUW0QT7<```` -M`(L3A=)T)(L-0.,$"(M"#(/P`0M"$'0,BT72)5=B+3P!````BUW0H4#C!`B+4R"+2Q"+7=B+!)CHBQ4TY`0(A=(/A(/#`8M-W(E= -MV#E-V`^-BU7H`<:-'!8C7=0Y^W]>C70F`(L--.0$"(7)=`R+1P/C8L5 -MP.($"(72=5"+#B-'!8C7=0Y^WZFBTW,.4WL=&*#1>P!`WWPZ8GV@ST8Y`0( -M`8G>BQ7,X@0(&<"#X.F#P"")5"0$B00DZ.NX.T$8?`B`^@J-=@!UH(E,)`2) -MWHD4).CKFXM5X`%5V(M-W#E-V`^,H<#B!`B%P'4UBQ7,X@0(BT((@^@!A<") -M0@AX.8L"Q@`*@\`!B0*#1>0!BUW@.5WD#X6#Q#Q;7E]=PZ',X@0(QP0D"@`` -M`(E$)`3HZ]&)5"0$QP0D"@```.CKOXL]1.0$"(7_=0B%R0^$BTW0BQT0Y`0( -MBU$$QP0D?ML$"(/J`8T,&C'2B7UWIP>`" -MB40D!*%`XP0(B00DZ(7`B<)T%HM-T(D50.,$"(M!"*,575E.#[`R+=0B+'H7;#X0Q_^L7UW#H575E.!['P(``"+10B+%:#B!`B)5?`QTHLPB86D -M]___A?8/A(M&/(7`#X7'A:CW__\`````D(M&#(/P`0M&$`^$BQU`Y`0(BWY, -MA=L/A8L-^.,$"(7)#X6-3(`\```@?H` -M(```#X2!^@!@```/A('Z`.````^$BP`[!2C@!`@/A(M&/(7`#X6+1E"-G%(U-S(N5I/?__XM#!(E$)!R+0AR)1"08 -MBP.)1"04BT(LB40D$`^W1PJ)1"0,BT(DB4PD!,<$)(S;!`B)1"0(Z*$\Y`0( -MA<`/A:$(Y`0(A<`/A0^W1P@E`/```#T`(```#X0]`&````^$BXVD]___BT

    ")5"00B40D#,=$)`BFVP0(QT0D!!````")'"3HBX6L]___B5PD -M",<$)+O;!`B)1"0$Z*$$Y`0(A<`/A(M'&.BA'.0$"(7`#X0/MT<(Z(F%J/?_ -M_^F+0PR+C:3W__^)1"0(BT$8QP0DH-L$"(E$)`3HZ8UV`(M#"(N5I/?__XE$ -M)`B+0A3'!"2@VP0(B40D!.CIBPT0Y`0(C4'_BRL````BWT,C95P____BW4(H:#B!`B)1?`QP,=$)`B`````QT0D!``` -M``")%"3HA?_'A6#___\`````=%^-E7#___^-A6S___^)5"0,B7PD"(ET)`2) -M!"3HA<")PW0Y@_O_=&V#^_X/A(N5;/___X'Z_P```'=*H=#B!`B+1)`TJ0`` -M!`!T*8.%8/___P$!WH7_=:&+5?`S%:#B!`B+A6#___]U9H'$K````%M>7UW# -MBX5@____C028B85@____Z\V)%"3HZ[6)]HV%AT.($"(M$F#2I```$``^$,?:%_W\WZV:-="8`BQ7,X@0(BX5< -M____#[8,!HM""(/H`87`B4((#XB+`H@(@\`!B0*#Q@$Y]W0KH<#B!`B%P'3& -MHAT.($"(M$F#2)PH'B````X`^$B=#!Z!X!O5S___\!A6#____I.T(8 -M#[;9?`F`^PH/A8E4)`2)'"3HZ8L5P.($"(72#X6+%RL````BT4(BQ6@X@0(B57P,=+'1"0(@``` -M`,=$)`0`````B85<____C85P____B00DZ,>%8/___P````"+E5S___^-A7#_ -M__^)1"0,C85L____QT0D"`8```")!"2)5"0$Z(7`B<8/A(/^_@^$@_[_#X0Q -MVX7V?S/K78L5S.($"(N%7/___P^V#`.+0@B#Z`&%P(E""`^(BP*("(/``8D" -M@\,!.=YT+(L]P.($"(7_=,6AS.($"(N57/___XE$)`0/M@03@\,!B00DZ#G> -M==2+G6S___\!M5S___^!^_\```!W<*'0X@0(BT28-*D```0`#X0QP(7;="B! -M^_\````/AZ'0X@0(BT28-(G"@>(```#@#X2)T,'H'@&%8/___^D[0A@/MOE\ -M"HGX/`H/A8E4)`2)/"3HZ8D<).B0ZXZ-A7#____'1"0(@````,=$)`0````` -MB00DZ*'`X@0(A<`/A8L5S.($"(N%7/___P^V"(M""(/H`87`B4((#XB+`H@( -M@\`!B0*#A5S___\!@X5@____`>F+E5S____'!"3TV`0(B50D!.@!A6#___^+ -M5?`S%:#B!`B+A6#___]U:X'$K````%M>7UW#)0``!`"#^`$9P(/(`>F)'"3H -MZ:',X@0(BY5<____B40D!`^V`HD$).CI.T(8#[;9?`F`^PH/A8E4)`2)'"3H -MZ>B-=@"-O"<`````58GE5U93@>RL````BT4(BQ6@X@0(B57P,=+'1"0(@``` -M`,=$)`0`````B858____C85P____B00DZ,>%8/___P````"+E5C___^-A7#_ -M__^)1"0,C85L____QT0D"`8```")!"2)5"0$Z(7`B85<____#X2+A5S___^# -MP`*#^`$/AHN=;/___X'[_P````^'H=#B!`B+1)@TJ0``!``/A(/[(@^$@_M< -M#X2+O5S___^%_WYO,=OK-8L5S.($"(N%6/___P^V#`.+0@B#Z`&%P(E""`^( -MBP*("(/``8D"@\,!.YU<____=#"+-<#B!`B%]G3!H@>`85@____@[U<_____@^$@[U<_____P^$BY5< -M____`958____Z8.]7/____\/A;\!````,?;ID(UT)@"+%#P#")!"3HH<#B!`B%P`^$C;0F`````*',X@0(B40D!(G8@^`'@\`PB00D -MZ.F)]CM"&'P)@/D*#X6)5"0$B0PDZ.F0.T(8#XV)5"0$QP0D7````.CIB?8[ -M0AA\"8#Y"@^%B50D!(D,).CID#M"&'P)@/D*#X6)5"0$B0PDZ.F+#>SC!`B% -MR700A=MX#('[_P````^.B[U<____A?\/CX.]7/____X/A8M5\#,5H.($"(N% -M8/___P^%@<2L````6UY?7<.+A5C___^)!"3HB575H/L,(M5 -M#(M%"(MU$(M]%(E5W(M-W(E%V,=%T`````")\,=%U`````")^H7)QT7D```` -M``^(A?\/B(G7B<:+5=B)P8M%W(7_B57PB47L=10YQG9!B="+5>SW]HG!,<#K -M$XUV`#M]['9/,2)1=2+1="+5=2%R70']]B#T@#W -MVH/$,%Y?7<.%]G4+N`$````QTO?VB<&+1>R)^O?QB<:+1?#W\8G!B?#KO`^] -MQX/P'XE%Z'5$.7WL=P4Y=?!RG+D!````,<#KGO==V(-5W`#W7=R%_\=%Y/__ -M__\/B9"-="8`B?")^O?8@](`]]KW5>3IN"````")\BM%Z(G!T^H/MDWHB47T -MB?B)UXM5[-/@"<>+1?#3Y@^V3?33Z`^V3>C3X@^V3?0)T(M5[(E%S-/J]_>) -M5&-X9'AB>&5G961A8F%G86-A9`````!,4T-/3$]24R!S:&]U;&0@=7-E -M(&-H87)A8W1ED`0(KI`$"+Z0!`C.D`0(WI`$".Z0!`C^D`0(#I$$"!Z1!`@ND00( -M/I$$"$Z1!`A>D00(;I$$"'Z1!`B.D00(GI$$"*Z1!`B^D00(SI$$"-Z1!`CN -MD00(_I$$"`Z2!`@>D@0(+I($"#Z2!`A.D@0(7I($"&Z2!`A^D@0(CI($")Z2 -M!`BND@0(OI($",Z2!`C>D@0([I($"/Z2!`@.DP0('I,$""Z3!`@^DP0(3I,$ -M"%Z3!`ANDP0(?I,$"(Z3!`B>DP0(KI,$"+Z3!`C.DP0(WI,$".Z3!`C^DP0( -M#I0$"!Z4!`@NE`0(/I0$"$Z4!`A>E`0(````````````)$9R965"4T0Z('-R -M8R]L:6(O8W-U+VDS.#8M96QF+V-R=#%?'`@)```)$9R965"4T0Z('-R8R]L:6(O8W-U -M+V-O;6UO;B]C'`@ -M)`!'0T,Z("A'3E4I(#0N,BXR(#(P,#6YS>6T`+F1Y;G-T<@`N9VYU+G9E6X`+G)E;"YP;'0`+FEN:70`+G1E>'0`+F9I;FD`+G)O9&%T -M80`N96A?9G)A;65?:&1R`"YD871A`"YE:%]F`(` -M``0`````````!`````0````G````"P````(```"\@P0(O`,``)`%```%```` -M`0````0````0````+P````,````"````3(D$"$P)``!$`P`````````````! -M`````````#<```#___]O`@```)",!`B0#```L@````0``````````@````(` -M``!$````_O__;P(```!$C00(1`T``#`````%`````0````0`````````4P`` -M``D````"````=(T$"'0-``!`````!``````````$````"````%P````)```` -M`@```+2-!`BT#0``,`(```0````+````!`````@```!E`````0````8```#D -MCP0(Y`\``!$```````````````0`````````8`````$````&````^(\$"/@/ -M``!P!``````````````$````!````&L````!````!@```'"4!`AP%```#$0` -M````````````$`````````!Q`````0````8```!\V`0(?%@```P````````` -M``````0`````````=P````$````"````B-@$"(A8``".!``````````````$ -M`````````'\````!`````@```!C=!`@870``'```````````````!``````` -M``"-`````0````,`````X`0(`&```#````````````````0`````````DP`` -M``$````"````,.`$"#!@``!8```````````````$`````````)T````&```` -M`P```(C@!`B(8```V`````4`````````!`````@```"F`````0````,```!@ -MX00(8&$```@```````````````0`````````K0````$````#````:.$$"&AA -M```(```````````````$`````````+0````!`````P```'#A!`AP80``!``` -M````````````!`````````"Y`````0````,```!TX00(=&$``"0!```````` -M``````0````$````O@````@````#````H.($"*!B``"L`0`````````````@ -M`````````,,````!``````````````"@8@``00,``````````````0`````` -M```!`````P``````````````X64``,P```````````````$``````````'__ -M[(*_<*GBTO8J#[&TS@MGB4R]0=<':N.(W\G9G;.:/7*.,11&``!@4S^M8<&. -MP63`)`;+,KS2"?Z;A7RA_=0$&\'"AAXY)C^XW9C3((:>FU,#`MX3R^HAEXQ` -MW/V/);AC03P4*HO-^D@)`C6HHPG!%`$%U86]?<,`<*I^42Y[@7]MBJ?,QX3M -M3/:EZ9/S)=617P5Y5PZIU*:8JM;V!QV(A,(RF!F:C2+OF&6]C`#8M3!B-GH, -M)PY1-;%69(1/24\>8N]NI*`*RQTX*!#U)B' -MXKW5%V6Y*;=1\]!=G:91]&D7!#43@0-P7``RF#3BJBB%M%,.7\)4T&U&X/C8 -M(4LW\ASM]>54Z@W1_9`Y0CEW_N9NJZWW4]4HZ+``;=&4+41:XH6=V/B0#[WJ -M(5^F^T'@XPE].>(76"[6@J7/$,#_3Q.^?,D1G90(-7#9N@JW\W:I<_X```!@ -M/'"(&^G]6XWUER>23R-9*V(/<4/R5B3&S -M"7\S:FU`^C#>_:,*%#(5*,IB!S*]O_15LX>H!Q!D_\VM,"PZ>:N6=BRN-=V= -M;8TR>_16]XO)!,A.D@6P8A?CZ_F5]Y=LR5(L0_`-GEX7GC8W3"%D_*N+DI*? -M<<`9203"1\B,5J$NKBQHD#];WLNRL5=_I/F(56'DZS_[30XJJ6`%1N59KHI, -M34]#8GP&HK\5L?&1B\W3[53)J.$==T?J@L".%=K\:(+=23HOAFY\)[RYNK6G -MM_%6\6J+[6K>Q@(&1V3,R4CM@RS(*,9ND0\DP`%]N-8Z\$_!I=>$FD -M6-@V*1+[X_4)1^T`S7A=L5?A?\;7>+&9J?QRU9T<$I,GGM99UXHTC#[. -M<1Z:'3+=7"C\.5#<_IX&%MCL$FP4:Z>CD,7_>K)W5]^R>!3._10]``$$!@`$ -M"<"<7B>!;H)T``<+`0`$(P,!`05L```!`",#`0$%;````0`!`!0#`P$;!`$% -M``0!`P("!@$`#(>XA&S`G%[`P&H`"`H!/7V2E0``!0$1#P!X`#@`-@!E`'@` -:90```!0*`0``+4,K<;.=`14&`0`A```````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj2_deflate.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj2_deflate.7z.uu deleted file mode 100644 index 2780eca3c..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj2_deflate.7z.uu +++ /dev/null @@ -1,313 +0,0 @@ -begin 644 test_read_format_7zip_bcj2_deflate.7z -M-WJ\KR<<``/O&9Y`````````#X7"C3M7`MX5$<5OIML8`F; -M;FQ##3;859.*+81=")(GYK4\-*$42(N6-&R2#8F$)&;O0JKAY64UU]O%J*#X -M0(GX0$5%I1BUQ020%$6,@!H+8H"HNR9JJGPDT,KZGYFYNYMLD/KV\W/;DW-F -MYLR9,V?.S)R9>[E;'26+#`;#%$G\8J18R0#*JFE-?/=M57Y/N;DRW4].FB#XL:G:Y"E<62ST+ -MS5(1TF\%Y`/*6%O\EP=8)>A<0#9@!=4%O%+D%P`6`(H!RT3>;,"]@.G"IJ6` -MQP!+1/FK`>F`UP.6ZK848_(H8#5@ILB+!TR1QOX2``L!;P2L!)@!5C%&!\A>P#>3':+D%$H<`F@2-`/`^9++_]G^"MEL1'T7;?AF23P5('OFX!G -MQKCTW?1'C/>K0KG3)@->2WX]01L/`&R`UXW+3P5D"CH' -M,"^B['[`&P`/BG26\*VW`,C9'"+_38#%$?5,`L^:0(\/"X/N%_V,%48\)M+= -MHCQ#I$_&\/0\D3X@TD4B_1;!OT2DOQ(SUHZ[1;I#I(V"OP'X;C%N;32'F1U? -M")XRC*W_2GV>Q/'T!I$^'\O3'QXGOU"DWR;2\X6\!T4Z1O3W8R(=)_AWB?2G -M!?]LD?[YN/[WB?9_)])_!.R[8C1927]HVSG.C_X4,Y;_,R+]&]'_DZ%YP=/- -MHCQ.I*TB_?.I/'TFTCYB?@^\G]OO;LSDFEP%U7PO(>%>4N43Y(\OOU\D3IJ)#_:U'^=6FL -M?=TB?4V,9RWJGXB0GQ,SUA_7B72^2%\7_;E7I$UB?+-%_X^)\BQ1_H-QX_$: -M\.]!>WS;>"'X(WW-%?6GQ8JTX/\0X+D(_9[4UY])O/R6:*]%\']]9P?\C -MT9]6D3XCZK]GW'Q^FZB_3O2G9=S\:8@9ZR^O&F<_I^`OHW(Q;^3+X?D]&_PE -M`V%^3(LK4\'=Y+Q7YXGZB_65]_QLG;+N@D87\)<8-'KJNG@"%3 -MJBA^Z[*"TJ5%4JUG@[.A[IVNB@;/ADI7LU11UU`G2Q4U0%+%XI*'"PM**AY> -MM&BE8U7%JH+"$D>%5/'FC14K7.OJW+*KN:C>Z7:[W"2[HQSEE? -MT=`DULKJFK75ZSS.)NK):;)1FF#LZJB!B$2I9OJJID(D-"C -M83T$SFA$;*IOEQDU55-U35PVF^OK&*JG.[93E)Z7&)MG9 -MO(XIT=CD:@B)J*FK=XU1J<995R_5U-0[U[GE1O2+<38UNYJ?`WKZAIJ&JGMNH9JJ0)B&M;M<)&^WB4?\9`%)426Q4VB!X8R-K4MTP -MCY[+\WFMV\GD\NAOU']AJ?@Q#I6M>?SWM9GOG$P1[-Q8GG<(:>+.H?U&Q!1Q -M]_*]-BZ-[XEQ#_&])VX^WQ/B0KYEQ;^%K8UPICDU8B;B` -M,!9],^$'87/"L[`N$\:FG$PX'3$_X3E8VPG#U5()V['/$L9F-HMP!F)YPF]$ -M7$)X`6)XPIDXPQ'.1GQ".`=G-L)YB(\)OPE['^%\G),(%^#L1[@0YS'"V(37 -M$"[&?D,8`7XUX<6(BPB_&=L'X1*S>E#1*_E]&&B:SG=2703IY\ANH73741OX_0)HMLX_1S1[9P^ -M3?0>3O<2O8_3YXD^P.D^H@]Q^B+1G9SN)[J+TP-$/\=I/]&]G!XBNH_3PT3W -M<_H:T7Y.CQ(]S.F7B![EM'2%[&]@M)%H$Z=-1"=RVDQT,J<3B;9R.HGHF9Q. -M)MK&Z12B,SEM)3J?TZE$+^'T3**7P^GE1._C]"JB#W!Z-=&'.+V&Z$Y.KR6ZB]/5 -M1#_'Z5JB>SE=3W0?IYN([N>T3+2?TRU$#W.ZE>A13F]C]H_A_L_LS^DV9G]. -M/\7LS^EV9G].[V+V)UH2/_OORM1?*0/#/H=)&3(N#WJ,*_RGV_D/)8\]NA*S -M4?.8M?)$[W5?ZS>,:AX=X;;,UV*]7?*<_72^LAQ)W'%6?IW291B,!PV,9-*V -MFW,\+[!R/<\SU$G':]3+T!PFU9CJ[S&FT@'$[U=;4TWJFE2CFI'JIP+_8&][ -MZ$<:#IFVY5V$]I)L'DQ1NHS[39`4/-M!2$OTGO4,GHRC;M$4EVNH,;8E-6URB+<_0\FU9 -MYS8G=0;QTU)2-?!JI/50^?$M"33VTJ#?=X2=[[HW_2'KW);[M47+58=96XR_ -MIK$U`JV'L[K=%WP;I<$O^0X_0)5\S[R>$'31RLQDGC(3*I<'?/(#>AGOE]!3 -M\YBT0Y)0'J`U>)@J(*5^4T6^,_E18:M8D;7F^&H]1/ -MN5`)&(Y2A^1,KKE:;J8.)0R`,]RMX&7DC^OH1LE^71V.L)18@[8/S8J#'&_R -MB\%@!\)1='W(WM61/P!J=Q(R55\B_O9X=^$OG^Z>A([B`5H`+#MZO/G()MVP -M`ERD]:;'VR88>[Q/A:A](>H3(6I/2*!ZO,=[()1_,$0="E&'0]1G!"5/V98I -M6;S:LZ2C-VC9H7E)3Z29MK-"%6R"4OIC>KRYH>P21E'/S:`"RF@\1#R=3,*N -M@UJ\?%MF.N%9.4RAC9-4AK5IJ=3ULYYX#,]5&AYYAEJ<:D0%6ES',>_-)WD7 -M(.>Q$K576Y*KL9ZHNV=2Z8I,]63WK?NS7F@U;S5F'4.MW8N]64PX9AHUEE6.5%7L:90(.G -MY6<:F)&\IZ#=-.DJ=0H4:]OG.>LK_Z56:.XI3C6-8%2!C?2H`'L(.FOVBS8+ -M$J,84CB#^G0Q-;MW"6N6:&Z=/41Y,X7Z>UAOEU!>$I5^@JCC*&%41^X`!'LS -M0FYB\7:8D&4_&^F,<(&G,YD9B-%PR5=L3S;T4FOD5]0C:MV7GZC&(E-=E6J$ -M]IFAAGW%TU^A%ADIG^J$C&Q*DQ"@Y='ECV5'GK26$%.(M9A@(NJ4G*_MIE:5 -M8P8ECPH-T[M&>E]S3&/Z^9+N]:VZYVYUI9DWVME0_.FT?IA\6X_04O*XT]4E!^G/FH) -MP\B&GWG':A]0_`;T=09;Y2Y8O(/GN?>1+U$Y_$\?DG"FZBWFGL<,Y%W"YNZS -M-,?OLKQ7GSE)MH$\"J/9@$T_I5R^H71;X`X^XB.7*&$C/^]NM<@4=@K*5,VI -M_H#NW<7"B[PEK!K6&\]K16AU$P,24:0!ZRZ^C]DW@_+?H[)4P+>[7?@X@C5: -M5'+)Z!A:W]/?XGTS71.3R&",F&5>,QL?[!1>$L#SC21$=ON8+U$:A;QQ5O"H -MGF3N%JJ_*Z3?9X@Z!MT8%8@2[?%!,>YZ1BT_!9TU_5QX7[1HCT\WALIR`J%. -MH4(BDY!,W;OWY]'="T2NTKE1ZS5S0K;9C%XE@JR<+/PU8.]2\BA;LNS&(.13 -MRZ26KUB*T0"]N>#*(5'S.IMCN% -M]W^FSWN04ZD^;QNGK#[O/DZE^+R?X%2RS[N'4TD^[P%A.Q_;*)B9[%_8CZ[?T8N*[\WJ-V>/X;W4E\^ -M]D@FVBMJ!+?,5V^Q.O8+Z\_%LXKJ;B,*1RZKY]3NV+U$0Y#G,FW$83%/,UV1 -M]5<;/A!1P_<4LP^S!2M0;J`I*XLR4FF\=FH^2AUEVF#_I,SU/?&JEU3@DG^M -M_DP]&?LLTZD[J)P+JL]/^;[G>758O:ET!=R(%@ -MJG<8"4W$!6VB\]9(=5:E)D9VG8]FA7K>\'QN? -MYR?:6W*]IR"JB$>:':EBE>OHTF5..TU1?:$)[)!1:+*T:3$GI7BLT6J,5I0B -MMJ(W8\S\FF,83;&Q9;JI)]4^?X?Q*I=$>M$5``VQ46@5TLSKUU@8I9Q(85MV -MNS)JE*?P.*0H%(>@O<@X)!QV!-K1`Q3-#OF6LGG(8-DY3L%P-!'09I@&^(Y_ -MW>$WD;V0C36]@[H+?IKE7)(V;?@*CTL#M$>+,C\;U9*?AT>5TJD1:=]&_=SF -MPS#B"B;XCI?XB#^R?2AS$F;.]/!1Q^<=^C/FP)-&U3MP@P<:IR\P61+)TF6R -MTTZ<&7Z-G`&XZKWN?08,RPQPT1 -M3O@-=#9(80<>>5%XQZ$NKOTZLU$,B8A(QPJ;J22.A'3D\VV\0-_/,\5^[IG3 -MD<2)!SJ2.3&CP\9YDK09K-4+GGCEC$G,)2UAE,61GONU:<7\$#9-3$"/6:\9 -MJYPQ=*3PI7+2]C/;>"`A9I8?S'P<$Y%%JL,7B?>"7*4E,&U.T;Q+%J>A#O-5 -M&B8Z7%L_S,0[0\(T+QFU)X[BY:YN5KA*?>';B1B*3F;7P<=8_]BQ)5G,;2ZK -M?3=&RLI]R`AB7&C[\F&[*&6M/W/`5,2FY,Y*9,5/U88X; -MNLKS`AWT8&K_-22)\ZK.61RJDR$H%"=?U:LG70UE&O79K_SZ)>5,8D_(&HKH4*BV/V2.S'#;2:&VD\-U1J^&K&W22;$*W+ZA)%$L.LDS<\.D%):4 -M*,B)ABC`R'!QM#U>"F7ZPUZ13W7T\C`99A@2)"P2%N6_&LH<"!OGCJ;5;1-N -M,T7/I?K1,OWA)JUZ)3^;<=?$[(AP<6U&,IOK='XWLO.[/B'7?@1^S28IJTN% -MX=G:RPH3^72=S:?KMB[D\>)M>T+D/B(Y0_ZS('U[!V@:KV$[USO)4P6]&?3^ -MX:OAC&V4,6L@G*%0QI*(C/=0QLP!-GGW2\!8`8;U<]$,JLJNF1*D4,=2=(/0 -MDA#V,FP6U)],OEPN[?#SCCW,NW#HPRC4IF7RY359+\WEI?E4*JP2)O,_$B+7 -MAHTQ3+E"^=_1`9%I'1C_;"`9TO,ZJ(AF][ZOBV.BB+4Z*8,VU8XE`V-+3AT/ -M59(ZQU6BC,%N_6X645Z25FY2^RB*U0,Y/[,KV^1.)#V.H$?L,4RGF;BHU=<: -ML4NV.8(^1Y!%)?:N4\=)=BB&G`5V&@8@>Y"OOVLO&DTU/8[G4=]QD<6!9?VJ -MX_Q@+M6S'#VF^&TURN;G)376LH/X#))RTJ`<-RJW8CP.I<>@."Z:%4=_C!*< -M2G(O]FRK%9[N,[XIRW%^4Y96UF\Y$M/F^",[DCK^Y#-NM5_WI7C77J6'0JO2 -M_^@K[,V=O%'S%7XJ=_*F5-:F4XT=_)!6AG+C.UG-XG=2U<'CXA:\\+M@?8BQ -M%JBQO-G0_#.F#EV@M=9RY/LY"?1ZPF9S1R^0]E1;!DRJW&B1[T%5,A%X,RY2 -MS!<;Q"^@G)C%`LL>AXE6[0#L]NA*];@O(U\92M22GJ[ENZU7,SY-VE/*]M^A2X)V17_]IM2/MT1;GD$U#ZB@+MP35T)O);2]K,'ELH5UT^8 -M$/>>,%IV=-)X4IO^;[,G7)E$@SD1E58#6R'YNN?93H2K@N64VGN\,V9LTC`V -M&3>44/[@YSOCPXD/=QK#":^]BU.!SLFAW/:( -MYR)B?LFJ8X\(J$?Q[&!6/UN7VCJ*^>JQ49MQ[2I?H'R./;`F33Z3K_P`&7AY -MQ*TQ.P'PA-&O'P>L^G%`+0_X -MWLVH[LTI7$Z)+J?L`E5(8)E/4.8I9-92IK^=/R9@3X;XPX*$(19=RE/8LR%M -MFIFML"+)_NC/5KMH4I72XFR-.@&VO%:+:3.Q`^`I>]=Q;B]S:FA=RBE,;IVT -M[49\N^<<'9CHCF/P#)>+^);?62>*F^U\^)E,4M1CW(]UQ[6\E[Q0N'`^]U%Y -M(9SWY)V.I@\RS9A/BC52F\:JG+UME3F156C*B';[@;UW:B\MLO*=F/,CF77G -MFJ,[U\L4DO?R6FS90,RM868V-!8?#8IHU3].DP=#FD3SYR,G(G_S3I'?RO*C -M^?-NDY\V0;MIHMWQ^?FWR6^]37[>7]'_P8AVP^MH:+_-5,NOJ*7]G_%V*>$IS7.QUD;["$I6H)^5=)6:9.8:)L1N2@ -M)FTG71T7M16T_EUA(ZJ5]GJ[M$?,LDDKL*+8<`Q'>KXL3H50K2B192IL^`R: -MPZ\\'XPM\X_T(71ZS3&U;!BW7%@Y^U'8E=5K>;_:BX$8V3RLE5U4':=%ZK1R -MTZ"5]2I]00RC%L,"LWS^O,73CXNPG3V./K9K.`98%V9D\(N&25K9@%K6IY6> -MQCJ^4]L\;+\.#R2?A6H=K(ZK%+`N6X02N]J);W997V -M67Q:F=]PTI=R[^O*SV>]N/4)_OR+L9XBPYS.<@R!2:R*GN5:`@9*M[A68"*C -M!Y1C5C[N!::6E9I!O=262,8T0+8N>S<>Z9W -M*?T!I>XG\=O#C<&0#=?TB=>$IX42>^=%> -MF!7V0L4Q8-#*^[/*!V@[SF417I37#?YXC*=]5\LK9C/3P\XH\`=M1B(YQB/$ -MLP6S`V\Z^,ROLI]5GQOYD[@#+.O%^QBBA4!W?PQEL_$0#WJ.R?="D#J-LF#! -M_>2G@5!,4-ZKEIL>MQ*3#.%8<#"%Q[UT6T5-]\3X^=22(Z:66"N4=]&$ -M&,'HQ/B,DPV].>PFL'F6;JO&"?<+>U"W5FB&&K!F\3O9H/R`7GMAM*4K(BQ] -MPARVKCTXQKX?CS*YSDV&#S'[`V/&X:,1YY?M0ZT(1.G5%/;T%K/,?E:SX>'@ -MB'@38A&;/+C5'^$7\>W:(F:=18ET\F3S>DL)/U6/BALT7^EI%H@RKV./7AO=ZB))RXF;"IJ$6\:Z.;^\/HAZ/AJ)%$ANNY-M-K/N1 -MH`?7XE^:40VVCR71=:J$N1]G%?]HB3/1].Z@+%X=?&1#<6/O\YX8H2M=?AW+ -M5&(YM*10CO9$$CJJ[29+:46T#:3@'2B@9"T6?Y/P@AA0(JP03_KBO22UA`W" -M4_HV$'JAH,,D"#!/].:!YF.-++9ICV5H2V>JOD.43'B)V1N:[OTNTOQXFSR9 -M=SS)RG'BZ8C]B`Q"1P06@&M[20KT^0YQK*&0VZCKDZD3?OV.8?%,/]M@Q=#0 -MN.J[\2NTO>0HX"G?'C>#/U]`G)1YM7Z -M)7*\QA[_8A+-X[:YXT(BQFDNR1[\,%N7]W*C)FF/SU2/V7Z]_6:0?&7OP1%Z -M=&\YF#2F7$N@?OH*@NH/6!P2NSCSGL=RNU^\ -M'[Y%@VC6WV>@X8X4DTBA25C,8F.D#E8>G(1UB'X6P]=*U@_L-0B&O&?Y'-T] -MX1Q-XG/4YZ52W][OCW`>"66AFY=1/)\_N2..RF@1_B'=+_A\2/*'LS`_!B%R -M!+X^;@3X^W>L"U[R9>KSN&Y:_8P'U'*Z)PA`8_9FPJ*)WDR@=KC&T&_,^N+M -M2.WG(TD2?#[B^2MRS.(-!QP#^\4#+#QE(Z%D+J8H8^[BFIH[Z-]UL&N&DXZ? -M/C3V81KG^AC6)X_\MZ.J4P=?[-8:,5M6?5%WJ70@S,]S@WM-PP.(I_MJ@>.>O@E?R>>N#?+3IE6)Z -MM5)_WTO.4EX,RAN4%V_1:S[$Q6?UIC?SRZKB]HPOT+^NEM^@,*D&PR5$(QU: -MV3!_>4ECN9Z:[2<.2F+)X5D^XQZ5$8,_9#'3T^B6EW2ABSM68%3^8!C?`19W -M?5C;S20D?5MEQ*`J7F:.LLOX?3A*G'<-ZO-V2738,MKN<`E9GUN(ZM/UD5@3 -MQ,-L)1BD/V2AOQ'3DDL3HXYD`JW3A -M#I7@=JP24T+4G.(%[_6M\P;+QWEA -M[&V\\+@AZY(\2\LC>]/A/MH-[P$/<\-+GO/<#0U/KPE-A4U-XZ?"RW32"/>\ -MT1JOCN;J_IDK7*-]<"?O^T0+12@\&MM-T\2]'.N,`=X]L50S(W)MQJ]LZR/\ -M:`*OB3(5>YWN-C,.&^K?LX:MOJUOK'YYOL$-LX,;2.F*01IHK^*\GMZ_:8%C -M9E"8J[WN^S]N.L\_KG-JN@$AX$@*@@Y]05JC+TA"O"BA++T'2I'E-W0O-U.,&5H3A6*WY8O."UW[)WHO -MM)B%#^S47=#R?GV\O7]MN>?>R1Z;]`Q^BTW%%["Z#(=6EPRQN@1NO[8H3(8A -M8#EZ7(1T7T6<)@ZZ=]PYQ[B29S6_M*+W9K5'3):C?3AK><^JCQ"SH2V9>,4P -MQXS=F+B/1RPT;-X<+3+PZZFHP0]$6S[G$5QAL8Z7Z(L0_W\8WAQY`'!9RS/]BC# -M]ZL.OZZWEB.EN&&^IHZJ/T,/SO5/Z4&+YWZ-[&OG_%1X[@K1 -M4ZA_N#@]]]N1$;7LM-HS\NLLH)/-]^64G<:3J1OVK@`JL@K],,AO?0\'D=6N -M__BS/V/'VLO\J>O=]@O!7DU90\E!(W(\P\H)(Y[3@1*CV5E6]W- -M5?1QK3E5;L^H^4]G9/Z",2K')U7;.K2FYL?M): -MY?3@2QM6I[7JR2I\1"$[_`$%M%I6NFRE5%2R%.3#*T)$Q:*'5Q0YI%6.%:52 -MP2*IH%"B;S54XXL14)9QT+>VK&C8FHV_U?@KZ/"?.OKS=E$D_L(K"@J+BK,7 -M+5ZRM&3YBI6KRAY[F[.RJKIF76W=^OH-#8U-[VAVRYY-+=*1YRR!S-N`^@#E"_LC!L76O -MB/0YX&\##GT5EQI?Y7E;&.;0&**C827JE:#\#8!$P6<`K@+^XU>,IJM?X7G? -M!_X\T0`/H`90"G@0@1?X* -M/7.%R`GQ<>I!#!C^8@@EN5%VUM,(QDNSD.>VICWHL:;-?M!M%7\E0O@[KWJ6 -MU=:29LMLX33^0`1*XNO)H1G$2];9"ZV2JZ6FI:JENJ6RQ;4.G]2H=*YS5L$G -M\=-=S.JN;?3`N>"^UJI:9[.S"M^0@2//KK76-;AE>+"UL<9JFYUEG>EVN:QR -MKT4GMY6`LIHFXP2F#IJ^P6-/3T\OCI35K7OO:R4Y3I;DF -MOB&A>8H\=:-TYY6C0:P<;WS9*P>^UW%?;$Y2+/_FV^IO!H,VT`?PTE9)K/3_ -MW_]__S,_>@A`N/XR?W\]N9^GTP%!_&(8#O^21#W#.U=(AE:3X3ZST=AFX-^S -M3`%8#P>#TXFAZ"YCH31%0 -M+K`*,$O\^W8)P*U]_!%-,;[727)+5",[`3ZC&$WQE!_+O_.8")@6\8U(^3*_ -MS+3A#^G_"L`K`8=]1A/1,O#=P/F`>P!D@%O!8&,Q\H/`I,LP\`MP%T?1'U`.F`A8!G@"4`# -M8`M@)^"3@*\`C@+.`"X!?@^X!;CK0Z@/2`MHST^VV?XVF$[6,_T7#F6_436Z;8YL[9VZFU9Z1;Y[]G]PH?:A/M)EA_V]QA;^5/]U=BP..[*R4 -MTF%"%SZGE][0*+O2"PJ7SI:=ZZ3T6J>[5DJO?K+!_>0&AND\E+ZNP9.^$6%A -M76/#F$0%RM`*\7&BJ5XFR77XRS[^EEZ#!(H:V>?FD9@V_KO" -M8KV?S/C$MZ#97A;^&05^#2".^,3^4PR^EIAPN5'`ZT7;,6)?>@8;4'LL-#^&FV_ -MM1%\H^`;!5\3%8ZSW_H0'_^^>!,V;'-QF"]1X'?H?"(N:%T-O@G:W13A!VW@ -M:P/?3F,TW]80G_CF-V9.R@3R?(*/#17V<>J8;0*^#T7(LX'/!K[5$_#M%7V( -M%7%!&_CZ:-S&CY6U3LJ/EO?E"+Y:\-7>AN]P!%\3^)J<5!;-]RW& -M%XZC9/"E&J+'[2CI*?CHNG)?);X5&,%G%?@XDQ?^$5_!>+\/M1G^78:CG9Y@ -M_OX%```58```6%```!20```3Z```$^@```_D```HH```$U@``!&(```0B``` -M2?```!*H```2J```%!@``!08```3:```%"@``!0H```4*```$[@``!%X```2 -M*```$[@``!*8```16```%"@``!.X```0"```$[@``!#8```4&```$1@``!*H -M```3>```$2@``!'(```4&```$.@``!*X```1R```$-@``!*H```4&```$V@` -M`!)(```3N```$J@``!08```2J```%!@``!*H```4&```$K@``!*H```4&``` -M$X@``!.(```3V```$R@``!)X```98```$N@``#?````0&```$G@``!E@```1 -MV```$N@``!)H```1>```$B@``!(H```WP```$!@``!#(```32```$X@``!.( -M```3J```$Y@``!"(```12```$@@``$FP```0B```$#@``!"(```3F```$(@` -M`!+(```2V```$M@``!"(```RT```)@```"8````36```$S@``!"(```3"``` -M$\@``!18```46```%%@``!18```46```$#@``!18```2.```$C@``!(X```Q -M\```$M@``!0(```0F```$&@``!08```2*```$B@``!"X```2.```$+@``!(X -M```2.```-#```#0P```T,```-#```#0P```T,```-#```#0P```T,```-#`` -M`#0P```1N```$6@``!#X```0>```$$@``!+X```3V```$,@``!-(```0R``` -M$T@``!#(```32```$T@``!-(```32```$,@``!#(```0R```$,@``!-(```U -M$```-\```#A@```WP```,?```%;````2B```$H@``#N````0R```$T@``#N` -M```0R```$T@``!#(```32```$H@``!&8```2N```$H@``!08```[@```$,@` -M`!#(```32```$T@``!(8```2J```$:@``!0X```1.```$_@``!*(```0J``` -M$H@``#9@```WP```,?```!*(```2J```$H@``#9@```U$```$H@``!*(``!6 -MP```$H@``!*(```0R```.&```!*H```42```$H@``#?````2J```$H@``#9@ -M```V8```$J@``!*H```2:```$7@``!`H```32```$_@``!*X```2:```$K@` -M`!&H```2:```$K@``!/8```3&```$U@``!)8```06```$0@``!)8```3V``` -M$E@``!!8```0R```$T@``!)8```1"```$,@``!#(```1"```$T@``!-(```0 -MR```$T@``!/8```26```$%@``!#(```32```$0@``!)8```2B```$0@``!#( -M```32```$]@``!)8```06```$,@``!#(```0R```$,@``!#(```32```$T@` -M`!-(```32```%!@``!-(```1"```$E@``!'H```1"```$,@``!#(```32``` -M$T@``!/8```5,```#_@```_X```/^```#_@```_X```/^```#_@```_X```/ -M^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X -M```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@` -M``_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^``` -M#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/ -M^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X -M```/^```#_@```_X```/^```#_@``!'X```5D```$?@``!9````1^```%M`` -M`!'X```78```$?@``!?P```1^```$?@``!B@```A1```(5L``"#]```=7@`` -M'6H``!YQ```>4```'5```!U0```>B@``'S$``!^B```EJ0``'LT``![-```? -M!0``&H$``"$;```CMP``)?0``!JD```=5P``&J0``!JD```<````'/$``!S^ -M```<_@``)>```"7@```<5P``'%<``"2R```@R0``''```!QP```@/P``'^D` -M`!XR```=N0``'C(``!FR```EJ0``)<<``"6]```DU```)1H``!HQ```=ZP`` -M(#4``"2-```C00``(Y@``")U```A\@``(:,``"B"```G=P``*`@``"=H```G -MP```)X```"A&```GV```*"P``"A9```F@```)H```":2```H;@``)H```":` -M```F@```)Q```"<0```F<@``)H```"9R```F^0``)H```":^```F^0``*8L` -M`#$P```OOP``+#H``#"!```K[0``+`<``#`3```P5```,#P``"_H```P8P`` -M*QP``"L2```K'```*?\``"HF```I8P``*6,``"EC```I8P``*6,``"EC```I -M8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC -M```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,` -M`"EC```I8P``*6,``"EC```I8P``*6,``"EC```IVP``*=L``"G;```KHP`` -M,6T``"NM```K0@``,4P``"NM```KP```*ZT``"NM```KP```,Z```VF```-I@``#:8```V@0`` -M-I@``#:8```VF```-I@``%$0``!+(```3H```#ES```Y)@``.?D``#I*```[ -M4@``.:@``#HJ```YQ```.+(``#KB```ZP@``.OX``#IF```[-@``.J(``#L: -M```Y%0``.9<``#GH```Y8@``.-H``#R(```[LP``.ZH``$`\``!`*@``/^L` -M`#_K```_N@``/X0``#]R```_A```/X0``#YT```^K0``/DT``#XT```^-``` -M/+```#UP``!!5```09(``$"@``!!$```11P``$4<``!$]P``1J@``$95``!# -M5```0U0``$-4``!(>P``1_4``$@U``!)!@``21H``$CC``!(Q0``1C```$8( -M``!%<```17```$>P``!%WP``1^4``$?3``!%]```1O```$<```!&T```2,X` -M`$(```!)I0``0?4``$>```!$4P``1((``$2"``!#M```0Z<``$(N``!"(``` -M1/<``$2U``!(1P``2(X``$3)``!%N```1$8``$1U``!$=0``0L$``$-4``!# -M`P``1S```$-4``!"@```1,D``$-,``!$]P``0U0``$-4``!#`P``0P,``$@U -M``!(-0``0U0``$K]``!-I0``3.0``$UO``!-1```3*,``$R!``!-\0``3=\` -M`$MH``!,`0``3`H``$U5``!-_@``2V@``$W%``!.'```2V@``$O)``!,T@`` -M3CH``$Y4``!.<@``31,``$QP``!,70``3,@``$S2``!-"0``31,``$V>``!- -ME```39X``%"%``!0:0``4`(``$_4``!.R```4+,``%"A``!.R```3S<``$]` -M``!0P```4-\``$[(``!/R0``3[8``%!6``!030``4%8``%44``!2L@``56D` -M`%3?``!4WP``5-\``%5&``!60```5B@``%44``!5=@``45@``%4T``!3J``` -M5(```%/A``!48```5!```%2@``!40```5,```%*'``!2T```4OX``%,V``!3 -M;@``4Y8``%,@``!3*0``4N<``%+Q``!36```4V$``%.-``!3E@``5:```%+$ -M``!2E```5KH``%()``!2$@``4;T``%%8``!4^0``5F0``%9^``!6G```4H<` -M`%*'``!2;@``5>P``%7B``!5[```5A,``%8<``!7H@``5\```%<&``!7!@`` -M5T```%=``'__[(*_<*GBTO8J#[&TS@MGB4R]0=<':N.(W\G9G;.:/7*.,11& -M`00&``0)J8R$;(>X)P`'"P$``@,$`0@4`P,!&P0!`0```@,$#,"<7L#`:@`( -M"@$]?9*5```%`1$/`'@`.``V`&4`>`!E````%`H!```M0RMQLYT!%08!`"$` -$```````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj2_lzma1_1.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj2_lzma1_1.7z.uu deleted file mode 100644 index 11c2133f5..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj2_lzma1_1.7z.uu +++ /dev/null @@ -1,287 +0,0 @@ -begin 644 test_read_format_7zip_bcj2_lzma1_1.7z -M-WJ\KR<<``.395S=/#$```````!D`````````(2-+0,`/Y%%A&@[WP)!,(6+ -M]:YDCG/TF9,6Y4@I6&:W,\L.GXAK)SG^7$ASM;Y]KP;]Q:,S]93R>,&)>5<, -M&FZE"`#6^N9W.O9$'UE^T-50DI_AD]BN$0G/D?)@D^5S4+=>0I338+60+5WO -M?S\=&H#(CWK#P8A*.F39U-N85;*`7:QH4MPY]Z"R4@0-G[PN0P/I&4U*T@DV -M'"`CQ@7=GL@J7_2-A[.]&`<]D>$^(9=0(?Z*\Z.%M#RG1BD;5#6(4_PL?`47 -M!00BJ=5&HZ7@@B$C!NO::D+1C%8P).\)*UDX0P@<+::RMJNW=<@+:$ZER\IE^S3<>=HCZTG -MM[:O[2?'(:Q@840D]\]5Y73NXY[]$A&S9_<=T[^)S9E-I@,/"Z%N3%P8EQ8N -M.<>T1U:G?9*=LX1R,65>5\LCE.PG__FU`+L]UUEKFS13]3C4N`J/2*#MK;D6 -MR_YC0[KZK#6ZDVED3OA(WO_#+'G.!7!DNT&:A<:N8%2S1T,0<.CXWI?5110E -M(]/(V5U26WQEEBY"+^%%%QQ*$$LVGS;&M##OO=PE)#7IOV]4!T0>MCVFR7A^ -M)`*]D,D*8(TTY<\22+QK022#]K1P8Q>ZDOE"5%*XR1S_RD)#8:OFV8PM<:&: -MXO9&=U7J?O95W3V[0_>S$IA67];6D(/WJJ:Q>6%"L4.3$3?0E!!$%?%!2/7& -MXB4BNO1`#[FYN$MKM,TL^'./,4GY)NO_;YJ7P -M.<8Z"R!*LK]S`B1=P4X(^JK3]7X8N(%H?=H&K>KB'G7(0C'R=1Z0Z`IBTR?O -M>DKYV:WR$Q0MRO.CI2E[0;'KUGX`,?^8H_"$EOK=81Z5Z4VZQ'O;;O;-'3N/ -MM(@343API(#U5#X1=PK%4)/F?[I"DE\39HS<'P)7H49\16$$ES92A@%4O+Y4 -MAD=?Q`Q6L[^+YH+AJ-Z!]8./"Y'^Q"*$TJ#,%/ESOJCC)X:D@0R_?J)%YC&F -M):9`]N(:_,O,>0]$-QL,-?ZE@EH7Z=TEA\M7949(]"*65FN\?-CF(U?7P0?R&\DOWV5DVFK[.JXEP>WU1IL?6K&/CWJ(7%PM9 -MZI:B)8)Q$N-53QL+1O[;'7O/7/O^;3JY[WU7(!DWS`YXM'QL?+>("XZ7)FJ3 -M#T4640CH[0Q8U319C-]L^2259=A(C)[[!/*9P+!6MXIH$N)1*Z:&QIZ7]E*8 -M%(B.D'_@P=8!H(?*X?N@HB+MAKFN3F][.%W':*1!5I4=/"TFY>,\=4<$EI/) -M\S[27U*=0/;8!0P4W/=5+RC"*W]L[Z>GIXO;=$L;^CKMC. -MFK$GA0?W<=3^K@8Y^D_FAZ!W7WZ#.6HO6/_:M&X<5E:R -MAU)=J;SF.%&+0R;V*[FQB?;-D6E*-E9A9B[,4F',0KL8S]AZ3/3,AZ!6('R] -M)>:,3R!'4,\HCK1#'3_?PE4$NKGPX,R?.IK6$:/[E%8278\-K\&D4\:14"/( -MJ(V,!$2BJH@D@[TOT`^<-9#'>!Y!%G[3Q4L[4EU[56_:"*>E#X'=E='@D%RN4=E!\F6P+B>NF-E.')J;D/S -M>](@#H.CZB,"S;X1F.)O-8.%W0+\OBW-QVYBLHRW$*]^CP(Y/U\G<3B;CDT0 -M]"EG+*#EDEZI35$5+9S&_^!_A78^X7/<2I.4Y;"H60LCL"Q.5U=,LHK4"6W:HZFZ?(LI+*? -M1?]2$%"5;V^Y]A>V$A;XY*$P"@WF:#I'$>>Z@'G8"9##/BP&7S4PR+!4&:25 -M@0#?WAT5NTR6,RW,0XNFDRGJJ'"[!B#`M[^0! -MB$_UO("?`8';,_EYIF/`YS,HY7,OO1Y`A$BAQXI(K,:Z?[$DK[LF1JP-RIXI -M[\KEKZST5NF-26U91M2>F]R-?H6.97>%;M$0B&E;\FPR!_8150K#<]3V($5- -M6SHJ[/"&TYD;ST3!R#@B92\![8+L/;^9;:^+(C'(Z[&A,_Y7P=$6SKYQ6J=0 -M*0/@I?K_Y@L:A'XR_=%D=4UM5^8.7CZKI3H%Z.&F'T_0IXB6 -M2\2+(R4=NDDVG8N]A(]M&ZH6-!N;N%IEGNP%1\$646$4*?JTOC-1%3H/UB]S -M-NON.J5*JN\71XV9L`?IV0DNQY87`Q/JQERXF.B<<1R$A7$ -M??LEM.:+%*JG+/SM23OHC_X[]'*WW.H;R658END(V=8SJK]K^DVX!XR.GLR_ -MFS_7>CF[]F7&4V3E<#!^5`/B!C955]_-N(F0[!^%U)G(DX,Y-SWE%.TJ1,KN7K_JS^OH?.6U\4@Z>K5-0[1GY` -M57LW:6>GO'!>FU^^MH"`=0.VICBJW_"`.AN^14_AL&:(BY,W -M+\E%!4$G^;3$!WW_)J>_-%0KHJUB`ADT\]#`$ -MW3*]RC&JDCHP0&BAT2\;Q#N>&MUFH8&I[^72X/_V&S]J0[4:!R+L=FR<(I>K -M3G<79].'1C5M'U>E=@A:6<8C&M4)IEIC='07>AK,.RT4,[9^6M!/QSSK`/9& -MI/X#T`#T0[ZY:H-6_F*QC:."_0I<'O:3-EJ910,KJ[^>E@H2O$OKG>0HH/;\ -M>`:*1^*-<'X_;P-,1-C>?E?<23A=YI-VJFS]NL;H`D?>=%N\ZC)L4V5TO-RL -M,S:O8KM?0')<[`-@&.`>$;')_TT/3IZX02G6'789"M6-5^4_;N;L$B053#PY8*6KD%Q\#"G99 -M*RY0Z]!B"5/58PTJAH.UI_> -M?7]0O.%'W&>\4J*)FOS]X!HZC^6GLFA%'@VA%5#''Q\V@K:?WJ>\L3D"9G\% -M![+R^KAFA7Y:!61'?B`@^9'[)U]1R,&85*!E\A5CGU:'E%0\O$LHS2\"B(18 -M$R)+4?8NA^8`SJ]-5YD)A:3U7\GMJ,K(\79#AA8J#X81K0]V6#WSKG7W7G1] -MWTS59JPM\?#9`DSGO[3FCJ1U>0F[XY,5-D!`)ERPIK8YNZ<1#3T^S:+C8/16@5 -M=L/='P>_ER`"1V@R?`1@:Q1[!6=R<"SM.1N==H%HFO'0C;.%HC""AY8(+BC0 -M_^(<;#3G4^ZS(=R32LH'F5REZ:9J?G-L9X46GT)QPNQD%CIER2^OB@<;/$ -M_%R:QR)8XMOG._E1^&KX=&ZLC"B'D1YVJ;&*&^[OM/-`LW*+@$^IEI1*2HUN -MJQ$;!@T3%"-OC(Y!&.N$]^G=1CAVWG>^;4K_CU%0O?[>H$C:%&Z#9RH1=WZI -M-'G2?PM[0DM@VUD@'#-X[!I3X\F&Q$/-C9._6,;]T=KCX)Y#+K,"OJP?9GAK-^S5RJ)0LK;Y3A54> -M@BNYR?&'45;186QEIU)WBT\DW7B?FWL.W>MQ@X.Z>"2*RFEB$JP=]&M4<+V> -M]D82H%QX6X:9COZU1JD]$X=;-3)%D'S;\?5L1[^;7F11T)=3:EQ;3M#([X>4 -M>&:!^+/A#!=)N+/]DT'U'1FKJPXL=@G^!$A6=H049Y(?^4G-.Y.4J(BY#1.4 -M:$>D@T;H$PNN>VP6G9',Q;\'M$']7TDC -M/%-"4)#^/D2F%I!-LN&EJCEVS]-O:`+MVO0,`YI(KBH\>4I`AQT>X'U5 -MT('3V/#GB:4M'08,UE]/U:&?L]AOUO6U$NF:J\#BSS8'[5F"/95"R)[@B@^( -M_]/+<%9),KA*@T80#.%W^/LT\['V\G=-6-_`,Q8=,W"*9.8P@^@YN))H,NOY -M4W@9@ZTU-J@XV.(D=_XT[[">*B,8"9RT/@M,K3(/J\Q8T(/_QSJFC-[EWGPV -MDLJ=P'\G6VL2'<>CKJGX$)05&0H?$N4,=*`+_5?7W7@?[KBY*@$<'%7QWH>& -M1A6<5`$UD3B8;S@,[1!$--9<5)=Y\0MU&;I860&<'[2K:C35?'HKD.YL1#(/ -M_N\WBKS'7LT6Z`7I&6JZ*4`0E,!)N,,`S\L-7)?K&;9;I81V+/*(=<[ZW;%I*D+@@"IEC63J81?NT^^A/!B?OJZ1?6IFN` -ML,JZ`]?W8FW'LNFBO+EJ^%>$*E64)G.V]D?]7FHW3G24:D)`BB6.R)PC>@T/ -MMH1)Y2]ED,YCW&6Y1#H.N`M\NW&B(K4/GEXYR4]/3E5/JM&7(TBV9#Y73UIJ -M"74MB'_A_60"U=9$<:=?E_:EQ#$Q['-B%F4Z'\V\^B?(>UWEK:?:N9:&]7VN -MQT"K/+E7./L_%?*NNYFS?WBHYFQ.MTF7[U%<(M&(>,>E4FK[GJC2,B8B)J[W -M]@R5F;=);`Y+[*PK'#H@PRD3RVKND8UI9/\:#<>R2`H<]#GY@H6D,GKG_+@O -MSOG[5;B=T6?,IKNB/)37_L8`3N" -MCV04E30(C[`_,C1ZM\8:&B^^KOU5L$`AL/B4[FM$"'X(X,3>V,:21%"T%K_= -M",4-.[%]PW[1EW0*.N;E=7M&MR14C4SFP,;2RTAT93N<6`4Y'.]' -M<0Y*G?\Y)K'Y,`E[^!:SZ7;[J%F(,BDT)O\.4%"^OY7BYH=[M`;APMZLWJTV -M#PLN&E9SS*W%+IK"\`](5W89"?A2QZE;+:.;UU0V*!4@-OK9WM:")2G$X-G+ -MYDLV!!0N[S-``]+V<'+4F9,3Z/IJL[?+K6%^$LW7+/+T28:LZHN_^^%)%O;V -M`!$@U\W)O\%V1=N1KA?>#2.+$,J5I\X]`L7D@B_\LHJJS%\C@&6O,)W^$1^X6SH@Q;4\*F6*L<]"^U7,:ECU%;Y;Z^AY9QD+86BL72A*#)L828G*3ZFID -MP:@S,=0>12UD`2LN_77?>SHB3H+5:(J['1-,?=,CL]S+Q5:`=U%\;L;^S03- -M*=G[8HV`*E5O4<@A)[3-2Q(!23U#1&MG_9B/`IT9E&\^J3SLK[ALL*HQ:F5T -MP7H>R>=_SQ.6[2K^^;]C@3A9ZQQ_1''XFFAE@R1]$R:,;WYJ9><8)B@P,H`Y -MP>:6RAX5-?]\Q,TY;A\*B58&9FYM_ -M/5(=II"YZBL!Q07-BQ7''E@?+M9(1A(^7K2(_K_0^1!%-R"BG9%\WX$S&BQI -M447_A:E]3`MY8L3$15/PLL,,V.D"<#!TS&&,2D>/W15B5L`*5Q,VXX3>OU:E -M8M.QP!MX`_DR^G^>>F$ZJ%`#44].FM;>9R>],DI:A+5J4M-\([Y<'B$8HT6O -M,3L7$@>Z6V23)DXL30&7P!MD^*E2C%HN;RG0#P:#?^H$9WSH\QV.A&\N_#PE -ME#(*4>VY3*]&JS-JQA;>ZVX*@>\RR'>XPOO[Q/-B89$#95Q>^-#UX";H%=R0+:J`P\Q,.US(!JB`7Q6EO8AC@:1'HJ!DV -M\R$FV#MK0'W.*XGF@LVCAF0BY*_CQ@8Y\>9KAXX$<*60D=9]I1`^V8!;IZJ1 -M5\1HK%V;2.$5*(11I^PR9$L!=LS0.>V5)8=N$`J3X-?:&W$02^%;ED7R]>'E -M3G:C,5I"=R(S#>;VFF!T:8H>:N\A;$3`DZ\[QS*(TM['0KDC+"PJ]?;?LX)" -M]RT?;(0ICY;HY/XV4C]LL^9+6<:]Z"]2>V*7*82U#8X5`WI%\]/_FJ,J?[^& -MP&,U*C?*1!%W!JGEO"EL]HQ.G#\ -MB1&H%Y:ZLO@L^0TH9"#?80.54)Y:)NR;2G_;/?66G880!=2O?"(Q4&^TZ-&J#+RNDBC<$HYE6M7ZQ_RKG/H;+MJN"J[SNK[H*>V^OFI@^GJPQ-0 -MVZM-/PMMC7(C$7W6IC.D$NV'S'^R`["3]:2:)ZU4E"-\FO-GFK)T=U[O7*>/ -M9&F(F&)=3D`5J'B5WE"G9-D4=I".:5-V_I83LAB7+V]2#']4.#T9J_O9UD?, -M@ONJR/4A`Z1)* -MJT?P_B,SW4S,;XG4><,28D@FJ%N66*K&<1&R%E2*"5&O%[>U20*LM"@$-WS: -M2G[W3L-3;Q\IXG#N&GXAEB$ENVP+`]QWWI;FUFNFZZMC6)[@AGZ44AJ:/[!* -MHCE?QE',)MJ!0O-N+!,F(5=0#\][W5:O6)6"NV+K,DJB-KHRE-1BZW_Q%TW3 -M9.+UJ4-UB-P&!,GZ(V(D1/4E+I%R,=[OZ,5[[W<#:.F;)&.'6P:7R82KS$=Q -MBQCV_D+<&B.1F?NVQFNA5#-UD;VRE3:Q1>20U5U0CSDH\6+IE8D'&T3`X)V@ -M/G-NDUCKD15JBL@DX]8XM(;XEX%\JU/O^977K]H4$CKJ>N^/F2\6:7IE-D5$ -MWV?@R"XQRK#!F8CDKD*84=P7]!/+$U5\!D$&:$8--5F@!+QO\_,N:@8QAP.> -METO'5=*$*7^!B&C,<7].Z7>;D?+A>ZPQA$BF,<9^/\/\"#:/9@867V="7`M' -M6;4Y4..L9^9#-Y:ECQJ:UVJ/TY+=N0`1"$82TGD$2O.%/9:-NX,_KLBYXFR2 -M!AY-\F>4\X-2,6^GP57R?T%!]JEGA@IIM:8G)._0!'Z,Z>(1CO2$#CN-&!D: -MW=^$#VYAHWK`*97^NZ";B18_)$&0$,P54J^T+]Q:1&X7ZOX -M+.6-SGM=)-;O6X(WW`6.EI%")'=N?^/'91?K1`N.!">2.%4RLKR*&UX;S+1" -M\PVI,2L&5X(&ED%7HG&)//_$)+O\_F-OH4'FF:+SUT?L&PK(K;I+IX@W6B1![(%W -M2A>[GK>WE,34L\P7KQ07_QANUF7(ULOVASH42%#LT^!]CHL3D>"Y2"[DF(`S -MT3/='[0!8%[XDG/ZI,T^X0JXA:IRH]*>X= -M]"Z=V.LJ1;]78D8*DD+[!]%)2%CX=G^<@_9MIOC`_8_AA"(TPBH7XN-*:]1V -MF<`QGL87I#TH.+%QJH][(T5NE40+NI"CP%<5NGZ*?;628\O/:4R@[<2)3O+! -ME*I9ERFSXK:\&N3(-+9_O0N69;#7VU7U@Q`-&42_6O5T1J$F<,A?,GW92OO, -MR+V^>0`2"XIT4CEF[<)^AZ#).1%MS4B!:!E">OT'X'.*<&SJ.R6@F$EC%54$ -MF36,5'`;Q([%_M"\#G\WH/$M%L/F%^=YUND)Q:J^IPPSS^3E(&QT*75E^,)M -MW#[_;$`)>3].RC7!."?J^0/2,S8(0"SL\QO:(OR!!1J)MDM9@OPYW\& -M:H*^6B-X6!C,L!Q9/1*]F.8FNJR,&2.]!B/EQYT6*[RF0`_('NY8DC493"!# -M[_8)N+5KG.`')R.``AW^93-2"9?),:`E"?N1N`B0[C21TZC#T5*WJR8AH)]; -MCBEV41)9?5[&7(^LTPRIU^A@,;Y8/-9H9.2.@0+OP`IH+*&A0J*'`U/X%3\7GN+,C);X*IE -M)FD27"H8M*O/VT^J5%(-F/9L;)FJ(1H&U=##?58FI(N4ZC=C:+NQS]1O*D"E -ML:C9%MF>5$M#%YO&2@%&TII1N1M234_2CF`9!;?P>,9WKE^4+%9J=DNM$OTA -M04QHA.U=\2^:]X$!!L^($1>51^JVZE]J'!*H;BZ>.GE&O!4,=T"@!>>/L&\$J@`%=`;*N=ESG(OAG7MIF`(Q2^:_W`JH\IU@DQ^KHZKRM*;HOB5OB0Q\-[\U")X@PWIU!I_C:[4\X.U -M]"!MK&&R.7\,>(*6ZE,\2^TE?2,GJ9WYAJXU6L"5VFX-5R%>L])(PI"$[J1@`2L@#TC@E[0B8H"MQK -MOIUWTIUB'E7.Q$`MKQ&*OT*V$27$CIJK;*CEO?=6PWJBD2\!B5'N72(D?>$I4!I[06.KT!)Y:^8B3E$A\6]GVKQ5H$- -MX\,#5;HA*G]>TQ[58K!(*%N"S0Q<(&=ILTVS_6!K>@77J#T8].5$(8%8V[M^S#"]#LO@=SO4$ -MDMK!M3083U<&)`DI+4^*.W/A(J-!(:R5#N3+"^LUGH!(/T7O3#T?A;=!AR>F -M&AFC3:2S/"'3'!G>V80+^\>:'A<^;H#1)E[^&?=WN*C4>E\8)[61*2L^><<;#R8A]"'5ND6O&_<'@C -MD"CWV]FE_[1);\69),/-(+,LJ.0LU?\H]XL8_:7H($?.0)&_"HQG,3&]EBG5 -MG2W%^1-%OU&WDS@Y6?$`^;B)C`I]!83*J#II"K<]X1'6YT,(JU!HG35]1X*S -M-5,5QA;;UJ!D1=0%3I?PF::/OZ<#L;R=$U\QS1.H.=Y+AEC.K)V!E])AA-S. -MDA!KDN^QV]F62-./+*.UTH:114D"$V$DWD#/0ME2$7S:X(*:2#N,#_QI>28\ -MKDT-3,MQ%:]@6H -M*]GUT45V.6$YM+*Y,`Q=QC(+E`H"&\85Q"3.&FB6$+IQ=$_^HA`N$;=SIDL-@1?3\>O!E;O\[$YU^(*"D@ALTGYRJRF<*+]`@[O!L.,Y9)3XPOHE[D2K5$LD',W4Q>/%F\+/'"2U/W5(E= -M=I9FG8(OQJ,M*1GQ%+%`3@WP-A,.*:T(>!\C6X+H6[?]`JJ2%]6QX&(A=:Q\ -MUJIM+))_2U.!1"!5[<8U5AZH-@VYF$C.Q2VV^AM!11S(=G;M#;*N85A^C%4I*V9?@T_ZA@8&3#]%">19T>(+BE_$:EBI7YB!'N< -M33*E_Y(CHT6.,H8#WG[0W6:79>/K<1M9FB6'B_X9\I";A;Q,[1^.O9_=(<*C -M@3']U97@UWA/Y=W4=$_FR\SB61"7M3!)+>;]&ZW+0#4*85?-$^YUVT?:7N?Q -M0_AF%#BW'`L\FJ:18?4X!NR._`[7GE?61$.FY\..[%QZ2^'F&W]Z(+7X(0;R?[J'5 -MN2]KY%$HDA^S"*VK;TQ,Z$8K3A-:)>@'K`'FO%ZX*KRLKG+P3:,,.V"@QC!S -M^DN*76M228@B^B&U20&!KB-8<&L;ZL]W4H#38W]M7^72 -M.W"!1W,5VV%8LV>:KDE:%9F)*ML^_&]6-_O?)H;R!Z%6NLWK$H/0KXUT!!I( -M.GD=DD,'GWUVF>1DX9:%G"1^#<[VJE5@!B@P"5:X1(?!J2A+`6"B```58``` -M6%```!20```3Z```$^@```_D```HH```$U@``!&(```0B```2?```!*H```2 -MJ```%!@``!08```3:```%"@``!0H```4*```$[@``!%X```2*```$[@``!*8 -M```16```%"@``!.X```0"```$[@``!#8```4&```$1@``!*H```3>```$2@` -M`!'(```4&```$.@``!*X```1R```$-@``!*H```4&```$V@``!)(```3N``` -M$J@``!08```2J```%!@``!*H```4&```$K@``!*H```4&```$X@``!.(```3 -MV```$R@``!)X```98```$N@``#?````0&```$G@``!E@```1V```$N@``!)H -M```1>```$B@``!(H```WP```$!@``!#(```32```$X@``!.(```3J```$Y@` -M`!"(```12```$@@``$FP```0B```$#@``!"(```3F```$(@``!+(```2V``` -M$M@``!"(```RT```)@```"8````36```$S@``!"(```3"```$\@``!18```4 -M6```%%@``!18```46```$#@``!18```2.```$C@``!(X```Q\```$M@``!0( -M```0F```$&@``!08```2*```$B@``!"X```2.```$+@``!(X```2.```-#`` -M`#0P```T,```-#```#0P```T,```-#```#0P```T,```-#```#0P```1N``` -M$6@``!#X```0>```$$@``!+X```3V```$,@``!-(```0R```$T@``!#(```3 -M2```$T@``!-(```32```$,@``!#(```0R```$,@``!-(```U$```-\```#A@ -M```WP```,?```%;````2B```$H@``#N````0R```$T@``#N````0R```$T@` -M`!#(```32```$H@``!&8```2N```$H@``!08```[@```$,@``!#(```32``` -M$T@``!(8```2J```$:@``!0X```1.```$_@``!*(```0J```$H@``#9@```W -MP```,?```!*(```2J```$H@``#9@```U$```$H@``!*(``!6P```$H@``!*( -M```0R```.&```!*H```42```$H@``#?````2J```$H@``#9@```V8```$J@` -M`!*H```2:```$7@``!`H```32```$_@``!*X```2:```$K@``!&H```2:``` -M$K@``!/8```3&```$U@``!)8```06```$0@``!)8```3V```$E@``!!8```0 -MR```$T@``!)8```1"```$,@``!#(```1"```$T@``!-(```0R```$T@``!/8 -M```26```$%@``!#(```32```$0@``!)8```2B```$0@``!#(```32```$]@` -M`!)8```06```$,@``!#(```0R```$,@``!#(```32```$T@``!-(```32``` -M%!@``!-(```1"```$E@``!'H```1"```$,@``!#(```32```$T@``!/8```5 -M,```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X -M```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@` -M``_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^``` -M#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/ -M^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X -M```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@` -M``_X```/^```#_@``!'X```5D```$?@``!9````1^```%M```!'X```78``` -M$?@``!?P```1^```$?@``!B@```A1```(5L``"#]```=7@``'6H``!YQ```> -M4```'5```!U0```>B@``'S$``!^B```EJ0``'LT``![-```?!0``&H$``"$; -M```CMP``)?0``!JD```=5P``&J0``!JD```<````'/$``!S^```<_@``)>`` -M`"7@```<5P``'%<``"2R```@R0``''```!QP```@/P``'^D``!XR```=N0`` -M'C(``!FR```EJ0``)<<``"6]```DU```)1H``!HQ```=ZP``(#4``"2-```C -M00``(Y@``")U```A\@``(:,``"B"```G=P``*`@``"=H```GP```)X```"A& -M```GV```*"P``"A9```F@```)H```":2```H;@``)H```":````F@```)Q`` -M`"<0```F<@``)H```"9R```F^0``)H```":^```F^0``*8L``#$P```OOP`` -M+#H``#"!```K[0``+`<``#`3```P5```,#P``"_H```P8P``*QP``"L2```K -M'```*?\``"HF```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC -M```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,` -M`"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P`` -M*6,``"EC```I8P``*6,``"EC```IVP``*=L``"G;```KHP``,6T``"NM```K -M0@``,4P``"NM```KP```*ZT``"NM```KP```,Z```VF```-I@``#:8```V@0``-I@``#:8```V -MF```-I@``%$0``!+(```3H```#ES```Y)@``.?D``#I*```[4@``.:@``#HJ -M```YQ```.+(``#KB```ZP@``.OX``#IF```[-@``.J(``#L:```Y%0``.9<` -M`#GH```Y8@``.-H``#R(```[LP``.ZH``$`\``!`*@``/^L``#_K```_N@`` -M/X0``#]R```_A```/X0``#YT```^K0``/DT``#XT```^-```/+```#UP``!! -M5```09(``$"@``!!$```11P``$4<``!$]P``1J@``$95``!#5```0U0``$-4 -M``!(>P``1_4``$@U``!)!@``21H``$CC``!(Q0``1C```$8(``!%<```17`` -M`$>P``!%WP``1^4``$?3``!%]```1O```$<```!&T```2,X``$(```!)I0`` -M0?4``$>```!$4P``1((``$2"``!#M```0Z<``$(N``!"(```1/<``$2U``!( -M1P``2(X``$3)``!%N```1$8``$1U``!$=0``0L$``$-4``!#`P``1S```$-4 -M``!"@```1,D``$-,``!$]P``0U0``$-4``!#`P``0P,``$@U``!(-0``0U0` -M`$K]``!-I0``3.0``$UO``!-1```3*,``$R!``!-\0``3=\``$MH``!,`0`` -M3`H``$U5``!-_@``2V@``$W%``!.'```2V@``$O)``!,T@``3CH``$Y4``!. -M<@``31,``$QP``!,70``3,@``$S2``!-"0``31,``$V>``!-E```39X``%"% -M``!0:0``4`(``$_4``!.R```4+,``%"A``!.R```3S<``$]```!0P```4-\` -M`$[(``!/R0``3[8``%!6``!030``4%8``%44``!2L@``56D``%3?``!4WP`` -M5-\``%5&``!60```5B@``%44``!5=@``45@``%4T``!3J```5(```%/A``!4 -M8```5!```%2@``!40```5,```%*'``!2T```4OX``%,V``!3;@``4Y8``%,@ -M``!3*0``4N<``%+Q``!36```4V$``%.-``!3E@``5:```%+$``!2E```5KH` -M`%()``!2$@``4;T``%%8``!4^0``5F0``%9^``!6G```4H<``%*'``!2;@`` -M5>P``%7B``!5[```5A,``%8<``!7H@``5\```%<&``!7!@``5T```%=``'__ -M[(*_<*GBTO8J#[&TS@MGB4R]0=<':N.(W\G9G;.:/7*.,11&`00&``0)I/&$ -M;(>X)P`'"P$``B,#`0$%70```0`4`P,!&P0!`0```@,$#,"<7L#`:@`("@$] -M?9*5```%`1$/`'@`.``V`&4`>`!E````%`H!```M0RMQLYT!%08!`"$````` -!```` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj2_lzma1_2.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj2_lzma1_2.7z.uu deleted file mode 100644 index a8316cf59..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj2_lzma1_2.7z.uu +++ /dev/null @@ -1,240 +0,0 @@ -begin 644 test_read_format_7zip_bcj2_lzma1_2.7z -M-WJ\KR<<``-^VG`E^B@```````"``````````+K(8KX`/Y%%A&@[WP)!,(6+ -M]:YDCG/TF9,6Y4@I6&:W,\L.GXAK)SG^7$ASM;Y]KP;]Q:,S]93R>,&)>5<, -M&FZE"`#6^N9W.O9$'UE^T-50DI_AD]BN$0G/D?)@D^5S4+=>0I338+60+5WO -M?S\=&H#(CWK#P8A*.F39U-N85;*`7:QH4MPY]Z"R4@0-G[PN0P/I&4U*T@DV -M'"`CQ@7=GL@J7_2-A[.]&`<]D>$^(9=0(?Z*\Z.%M#RG1BD;5#6(4_PL?`47 -M!00BJ=5&HZ7@@B$C!NO::D+1C%8P).\)*UDX0P@<+::RMJNW=<@+:$ZER\IE^S3<>=HCZTG -MM[:O[2?'(:Q@840D]\]5Y73NXY[]$A&S9_<=T[^)S9E-I@,/"Z%N3%P8EQ8N -M.<>T1U:G?9*=LX1R,65>5\LCE.PG__FU`+L]UUEKFS13]3C4N`J/2*#MK;D6 -MR_YC0[KZK#6ZDVED3OA(WO_#+'G.!7!DNT&:A<:N8%2S1T,0<.CXWI?5110E -M(]/(V5U26WQEEBY"+^%%%QQ*$$LVGS;&M##OO=PE)#7IOV]4!T0>MCVFR7A^ -M)`*]D,D*8(TTY<\22+QK022#]K1P8Q>ZDOE"5%*XR1S_RD)#8:OFV8PM<:&: -MXO9&=U7J?O95W3V[0_>S$IA67];6D(/WJJ:Q>6%"L4.3$3?0E!!$%?%!2/7& -MXB4BNO1`#[FYN$MKM,TL^'./,4GY)NO_;YJ7P -M.<8Z"R!*LK]S`B1=P4X(^JK3]7X8N(%H?=H&K>KB'G7(0C'R=1Z0Z`IBTR?O -M>DKYV:WR$Q0MRO.CI2E[0;'KUGX`,?^8H_"$EOK=81Z5Z4VZQ'O;;O;-'3N/ -MM(@343API(#U5#X1=PK%4)/F?[I"DE\39HS<'P)7H49\16$$ES92A@%4O+Y4 -MAD=?Q`Q6L[^+YH+AJ-Z!]8./"Y'^Q"*$TJ#,%/ESOJCC)X:D@0R_?J)%YC&F -M):9`]N(:_,O,>0]$-QL,-?ZE@EH7Z=TEA\M7949(]"*65FN\?-CF(U?7P0?R&\DOWV5DVFK[.JXEP>WU1IL?6K&/CWJ(7%PM9 -MZI:B)8)Q$N-53QL+1O[;'7O/7/O^;3JY[WU7(!DWS`YXM'QL?+>("XZ7)FJ3 -M#T4640CH[0Q8U319C-]L^2259=A(C)[[!/*9P+!6MXIH$N)1*Z:&QIZ7]E*8 -M%(B.D'_@P=8!H(?*X?N@HB+MAKFN3F][.%W':*1!5I4=/"TFY>,\=4<$EI/) -M\S[27U*=0/;8!0P4W/=5+RC"*W]L[Z>GIXO;=$L;^CKMC. -MFK$GA0?W<=3^K@8Y^D_FAZ!W7WZ#.6HO6/_:M&X<5E:R -MAU)=J;SF.%&+0R;V*[FQB?;-D6E*-E9A9B[,4F',0KL8S]AZ3/3,AZ!6('R] -M)>:,3R!'4,\HCK1#'3_?PE4$NKGPX,R?.IK6$:/[E%8278\-K\&D4\:14"/( -MJ(V,!$2BJH@D@[TOT`^<-9#'>!Y!%G[3Q4L[4EU[56_:"*>E#X'=E='@D%RN4=E!\F6P+B>NF-E.')J;D/S -M>](@#H.CZB,"S;X1F.)O-8.%W0+\OBW-QVYBLHRW$*]^CP(Y/U\G<3B;CDT0 -M]"EG+*#EDEZI35$5+9S&_^!_A78^X7/<2I.4Y;"H60LCL"Q.5U=,LHK4"6W:HZFZ?(LI+*? -M1?]2$%"5;V^Y]A>V$A;XY*$P"@WF:#I'$>>Z@'G8"9##/BP&7S4PR+!4&:25 -M@0#?WAT5NTR6,RW,0XNFDRGJJ'"[!B#`M[^0! -MB$_UO("?`8';,_EYIF/`YS,HY7,OO1Y`A$BAQXI(K,:Z?[$DK[LF1JP-RIXI -M[\KEKZST5NF-26U91M2>F]R-?H6.97>%;M$0B&E;\FPR!_8150K#<]3V($5- -M6SHJ[/"&TYD;ST3!R#@B92\![8+L/;^9;:^+(C'(Z[&A,_Y7P=$6SKYQ6J=0 -M*0/@I?K_Y@L:A'XR_=%D=4UM5^8.7CZKI3H%Z.&F'T_0IXB6 -M2\2+(R4=NDDVG8N]A(]M&ZH6-!N;N%IEGNP%1\$646$4*?JTOC-1%3H/UB]S -M-NON.J5*JN\71XV9L`?IV0DNQY87`Q/JQERXF.B<<1R$A7$ -M??LEM.:+%*JG+/SM23OHC_X[]'*WW.H;R658END(V=8SJK]K^DVX!XR.GLR_ -MFS_7>CF[]F7&4V3E<#!^5`/B!C955]_-N(F0[!^%U)G(DX,Y-SWE%.TJ1,KN7K_JS^OH?.6U\4@Z>K5-0[1GY` -M57LW:6>GO'!>FU^^MH"`=0.VICBJW_"`.AN^14_AL&:(BY,W -M+\E%!4$G^;3$!WW_)J>_-%0KHJUB`ADT\]#`$ -MW3*]RC&JDCHP0&BAT2\;Q#N>&MUFH8&I[^72X/_V&S]J0[4:!R+L=FR<(I>K -M3G<79].'1C5M'U>E=@A:6<8C&M4)IEIC='07>AK,.RT4,[9^6M!/QSSK`/9& -MI/X#T`#T0[ZY:H-6_F*QC:."_0I<'O:3-EJ910,KJ[^>E@H2O$OKG>0HH/;\ -M>`:*1^*-<'X_;P-,1-C>?E?<23A=YI-VJFS]NL;H`D?>=%N\ZC)L4V5TO-RL -M,S:O8KM?0')<[`-@&.`>$;')_TT/3IZX02G6'789"M6-5^4_;N;L$B053#PY8*6KD%Q\#"G99 -M*RY0Z]!B"5/58PTJAH.UI_> -M?7]0O.%'W&>\4J*)FOS]X!HZC^6GLFA%'@VA%5#''Q\V@K:?WJ>\L3D"9G\% -M![+R^KAFA7Y:!61'?B`@^9'[)U]1R,&85*!E\A5CGU:'E%0\O$LHS2\"B(18 -M$R)+4?8NA^8`SJ]-5YD)A:3U7\GMJ,K(\79#AA8J#X81K0]V6#WSKG7W7G1] -MWTS59JPM\?#9`DSGO[3FCJ1U>0F[XY,5-D!`)ERPIK8YNZ<1#3T^S:+C8/16@5 -M=L/='P>_ER`"1V@R?`1@:Q1[!6=R<"SM.1N==H%HFO'0C;.%HC""AY8(+BC0 -M_^(<;#3G4^ZS(=R32LH'F5REZ:9J?G-L9X46GT)QPNQD%CIER2^OB@<;/$ -M_%R:QR)8XMOG._E1^&KX=&ZLC"B'D1YVJ;&*&^[OM/-`LW*+@$^IEI1*2HUN -MJQ$;!@T3%"-OC(Y!&.N$]^G=1CAVWG>^;4K_CU%0O?[>H$C:%&Z#9RH1=WZI -M-'G2?PM[0DM@VUD@'#-X[!I3X\F&Q$/-C9._6,;]T=KCX)Y#+K,"OJP?9GAK-^S5RJ)0LK;Y3A54> -M@BNYR?&'45;186QEIU)WBT\DW7B?FWL.W>MQ@X.Z>"2*RFEB$JP=]&M4<+V> -M]D82H%QX6X:9COZU1JD]$X=;-3)%D'S;\?5L1[^;7F11T)=3:EQ;3M#([X>4 -M>&:!^+/A#!=)N+/]DT'U'1FKJPXL=@G^!$A6=H049Y(?^4G-.Y.4J(BY#1.4 -M:$>D@T;H$PNN>VP6G9',Q;\'M$']7TDC -M/%-"4)#^/D2F%I!-LN&EJCEVS]-O:`+MVO0,`YI(KBH\>4I`AQT>X'U5 -MT('3V/#GB:4M'08,UE]/U:&?L]AOUO6U$NF:J\#BSS8'[5F"/95"R)[@B@^( -M_]/+<%9),KA*@T80#.%W^/LT\['V\G=-6-_`,Q8=,W"*9.8P@^@YN))H,NOY -M4W@9@ZTU-J@XV.(D=_XT[[">*B,8"9RT/@M,K3(/J\Q8T(/_QSJFC-[EWGPV -MDLJ=P'\G6VL2'<>CKJGX$)05&0H?$N4,=*`+_5?7W7@?[KBY*@$<'%7QWH>& -M1A6<5`$UD3B8;S@,[1!$--9<5)=Y\0MU&;I860&<'[2K:C35?'HKD.YL1#(/ -M_N\WBKS'7LT6Z`7I&6JZ*4`0E,!)N,,`S\L-7)?K&;9;I81V+/*(=<[ZW;%I*D+@@"IEC63J81?NT^^A/!B?OJZ1?6IFN` -ML,JZ`]?W8FW'LNFBO+EJ^%>$*E64)G.V]D?]7FHW3G24:D)`BB6.R)PC>@T/ -MMH1)Y2]ED,YCW&6Y1#H.N`M\NW&B(K4/GEXYR4]/3E5/JM&7(TBV9#Y73UIJ -M"74MB'_A_60"U=9$<:=?E_:EQ#$Q['-B%F4Z'\V\^B?(>UWEK:?:N9:&]7VN -MQT"K/+E7./L_%?*NNYFS?WBHYFQ.MTF7[U%<(M&(>,>E4FK[GJC2,B8B)J[W -M]@R5F;=);`Y+[*PK'#H@PRD3RVKND8UI9/\:#<>R2`H<]#GY@H6D,GKG_+@O -MSOG[5;B=T6?,IKNB/)37_L8`3N" -MCV04E30(C[`_,C1ZM\8:&B^^KOU5L$`AL/B4[FM$"'X(X,3>V,:21%"T%K_= -M",4-.[%]PW[1EW0*.N;E=7M&MR14C4SFP,;2RTAT93N<6`4Y'.]' -M<0Y*G?\Y)K'Y,`E[^!:SZ7;[J%F(,BDT)O\.4%"^OY7BYH=[M`;APMZLWJTV -M#PLN&E9SS*W%+IK"\`](5W89"?A2QZE;+:.;UU0V*!4@-OK9WM:")2G$X-G+ -MYDLV!!0N[S-``]+V<'+4F9,3Z/IJL[?+K6%^$LW7+/+T28:LZHN_^^%)%O;V -M`!$@U\W)O\%V1=N1KA?>#2.+$,J5I\X]`L7D@B_\LHJJS%\C@&6O,)W^$1^X6SH@Q;4\*F6*L<]"^U7,:ECU%;Y;Z^AY9QD+86BL72A*#)L828G*3ZFID -MP:@S,=0>12UD`2LN_77?>SHB3H+5:(J['1-,?=,CL]S+Q5:`=U%\;L;^S03- -M*=G[8HV`*E5O4<@A)[3-2Q(!23U#1&MG_9B/`IT9E&\^J3SLK[ALL*HQ:F5T -MP7H>R>=_SQ.6[2K^^;]C@3A9ZQQ_1''XFFAE@R1]$R:,;WYJ9><8)B@P,H`Y -MP>:6RAX5-?]\Q,TY;A\*B58&9FYM_ -M/5(=II"YZBL!Q07-BQ7''E@?+M9(1A(^7K2(_K_0^1!%-R"BG9%\WX$S&BQI -M447_A:E]3`MY8L3$15/PLL,,V.D"<#!TS&&,2D>/W15B5L`*5Q,VXX3>OU:E -M8M.QP!MX`_DR^G^>>F$ZJ%`#44].FM;>9R>],DI:A+5J4M-\([Y<'B$8HT6O -M,3L7$@>Z6V23)DXL30&7P!MD^*E2C%HN;RG0#P:#?^H$9WSH\QV.A&\N_#PE -ME#(*4>VY3*]&JS-JQA;>ZVX*@>\RR'>XPOO[Q/-B89$#95Q>^-#UX";H%=R0+:J`P\Q,.US(!JB`7Q6EO8AC@:1'HJ!DV -M\R$FV#MK0'W.*XGF@LVCAF0BY*_CQ@8Y\>9KAXX$<*60D=9]I1`^V8!;IZJ1 -M5\1HK%V;2.$5*(11I^PR9$L!=LS0.>V5)8=N$`J3X-?:&W$02^%;ED7R]>'E -M3G:C,5I"=R(S#>;VFF!T:8H>:N\A;$3`DZ\[QS*(TM['0KDC+"PJ]?;?LX)" -M]RT?;(0ICY;HY/XV4C]LL^9+6<:]Z"]2>V*7*82U#8X5`WI%\]/_FJ,J?[^& -MP&,U*C?*1!%W!JGEO"EL]HQ.G#\ -MB1&H%Y:ZLO@L^0TH9"#?80.54)Y:)NR;2G_;/?66G880!=2O?"(Q4&^TZ-&J#+RNDBC<$HYE6M7ZQ_RKG/H;+MJN"J[SNK[H*>V^OFI@^GJPQ-0 -MVZM-/PMMC7(C$7W6IC.D$NV'S'^R`["3]:2:)ZU4E"-\FO-GFK)T=U[O7*>/ -M9&F(F&)=3D`5J'B5WE"G9-D4=I".:5-V_I83LAB7+V]2#']4.#T9J_O9UD?, -M@ONJR/4A`Z1)* -MJT?P_B,SW4S,;XG4><,28D@FJ%N66*K&<1&R%E2*"5&O%[>U20*LM"@$-WS: -M2G[W3L-3;Q\IXG#N&GXAEB$ENVP+`]QWWI;FUFNFZZMC6)[@AGZ44AJ:/[!* -MHCE?QE',)MJ!0O-N+!,F(5=0#\][W5:O6)6"NV+K,DJB-KHRE-1BZW_Q%TW3 -M9.+UJ4-UB-P&!,GZ(V(D1/4E+I%R,=[OZ,5[[W<#:.F;)&.'6P:7R82KS$=Q -MBQCV_D+<&B.1F?NVQFNA5#-UD;VRE3:Q1>20U5U0CSDH\6+IE8D'&T3`X)V@ -M/G-NDUCKD15JBL@DX]8XM(;XEX%\JU/O^977K]H4$CKJ>N^/F2\6:7IE-D5$ -MWV?@R"XQRK#!F8CDKD*84=P7]!/+$U5\!D$&:$8--5F@!+QO\_,N:@8QAP.> -METO'5=*$*7^!B&C,<7].Z7>;D?+A>ZPQA$BF,<9^/\/\"#:/9@867V="7`M' -M6;4Y4..L9^9#-Y:ECQJ:UVJ/TY+=N0`1"$82TGD$2O.%/9:-NX,_KLBYXFR2 -M!AY-\F>4\X-2,6^GP57R?T%!]JEGA@IIM:8G)._0!'Z,Z>(1CO2$#CN-&!D: -MW=^$#VYAHWK`*97^NZ";B18_)$&0$,P54J^T+]Q:1&X7ZOX -M+.6-SGM=)-;O6X(WW`6.EI%")'=N?^/'91?K1`N.!">2.%4RLKR*&UX;S+1" -M\PVI,2L&5X(&ED%7HG&)//_$)+O\_F-OH4'FF:+SUT?L&PK(K;I+IX@W6B1![(%W -M2A>[GK>WE,34L\P7KQ07_QANUF7(ULOVASH42%#LT^!]CHL3D>"Y2"[DF(`S -MT3/='[0!8%[XDG/ZI,T^X0JXA:IRH]*>X= -M]"Z=V.LJ1;]78D8*DD+[!]%)2%CX=G^<@_9MIOC`_8_AA"(TPBH7XN-*:]1V -MF<`QGL87I#TH.+%QJH][(T5NE40+NI"CP%<5NGZ*?;628\O/:4R@[<2)3O+! -ME*I9ERFSXK:\&N3(-+9_O0N69;#7VU7U@Q`-&42_6O5T1J$F<,A?,GW92OO, -MR+V^>0`2"XIT4CEF[<)^AZ#).1%MS4B!:!E">OT'X'.*<&SJ.R6@F$EC%54$ -MF36,5'`;Q([%_M"\#G\WH/$M%L/F%^=YUND)Q:J^IPPSS^3E(&QT*75E^,)M -MW#[_;$`)>3].RC7!."?J^0/2,S8(0"SL\QO:(OR!!1J)MDM9@OPYW\& -M:H*^6B-X6!C,L!Q9/1*]F.8FNJR,&2.]!B/EQYT6*[RF0`_('NY8DC493"!# -M[_8)N+5KG.`')R.``AW^93-2"9?),:`E"?N1N`B0[C21TZC#T5*WJR8AH)]; -MCBEV41)9?5[&7(^LTPRIU^A@,;Y8/-9H9.2.@0+OP`IH+*&A0J*'`U/X%3\7GN+,C);X*IE -M)FD27"H8M*O/VT^J5%(-F/9L;)FJ(1H&U=##?58FI(N4ZC=C:+NQS]1O*D"E -ML:C9%MF>5$M#%YO&2@%&TII1N1M234_2CF`9!;?P>,9WKE^4+%9J=DNM$OTA -M04QHA.U=\2^:]X$!!L^($1>51^JVZE]J'!*H;BZ>.GE&O!4,=T"@!>>/L&\$J@`%=`;*N=ESG(OAG7MIF`(Q2^:_W`JH\IU@DQ^KHZKRM*;HOB5OB0Q\-[\U")X@PWIU!I_C:[4\X.U -M]"!MK&&R.7\,>(*6ZE,\2^TE?2,GJ9WYAJXU6L"5VFX-5R%>L])(PI"$[J1@`2L@#TC@E[0B8H"MQK -MOIUWTIUB'E7.Q$`MKQ&*OT*V$27$CIJK;*CEO?=6PWJBD2\!B5'N72(D?>$I4!I[06.KT!)Y:^8B3E$A\6]GVKQ5H$- -MX\,#5;HA*G]>TQ[58K!(*%N"S0Q<(&=ILTVS_6!K>@77J#T8].5$(8%8V[M^S#"]#LO@=SO4$ -MDMK!M3083U<&)`DI+4^*.W/A(J-!(:R5#N3+"^LUGH!(/T7O3#T?A;=!AR>F -M&AFC3:2S/"'3'!G>V80+^\>:'A<^;H#1)E[^&?=WN*C4>E\8)[61*2L^><<;#R8A]"'5ND6O&_<'@C -MD"CWV]FE_[1);\69),/-(+,LJ.0LU?\H]XL8_:7H($?.0)&_"HQG,3&]EBG5 -MG2W%^1-%OU&WDS@Y6?$`^;B)C`I]!83*J#II"K<]X1'6YT,(JU!HG35]1X*S -M-5,5QA;;UJ!D1=0%3I?PF::/OZ<#L;R=$U\QS1.H.=Y+AEC.K)V!E])AA-S. -MDA!KDN^QV]F62-./+*.UTH:114D"$V$DWD#/0ME2$7S:X(*:2#N,#_QI>28\ -MKDT-3,MQ%:]@6H -M*]GUT45V.6$YM+*Y,`Q=QC(+E`H"&\85Q"3.&FB6$+IQ=$_^HA`N$;=SIDL-@1?3\>O!E;O\[$YU^(*"D@ALTGYRJRF<*+]`@[O!L.,Y9)3XPOHE[D2K5$LD',W4Q>/%F\+/'"2U/W5(E= -M=I9FG8(OQJ,M*1GQ%+%`3@WP-A,.*:T(>!\C6X+H6[?]`JJ2%]6QX&(A=:Q\ -MUJIM+))_2U.!1"!5[<8U5AZH-@VYF$C.Q2VV^AM!11S(=G;M#;*N85A^C%4I*V9?@T_ZA@8&3#]%">19T>(+BE_$:EBI7YB!'N< -M33*E_Y(CHT6.,H8#WG[0W6:79>/K<1M9FB6'B_X9\I";A;Q,[1^.O9_=(<*C -M@3']U97@UWA/Y=W4=$_FR\SB61"7M3!)+>;]&ZW+0#4*85?-$^YUVT?:7N?Q -M0_AF%#BW'`L\FJ:18?4X!NR._`[7GE?61$.FY\..[%QZ2^'F&W]Z(+7X(0;R?[J'5 -MN2]KY%$HDA^S"*VK;TQ,Z$8K3A-:)>@'K`'FO%ZX*KRLKG+P3:,,.V"@QC!S -M^DN*76M228@B^B&U20&!KB-8<&L;ZL]W4H#38W]M7^72 -M.W"!1W,5VV%8LV>:KDE:%9F)*ML^_&]6-_O?)H;R!Z%6NLWK$H/0KXUT!!I( -M.GD=DD,'GWUVF>1DX9:%G"1^#<[VJE5@!B@P"5:X1(?!J2A+`6"B`'__[(*_ -M<*GBTO8J#[&TS@MGB4R]0=<':N.(W\G9G;.:/7*.,11&``!@4S^M8<&.P63` -M)`;+,KS2"?Z;A7RA_=0$&\'"AAXY)C^XW9C3((:>FU,#`MX3R^HAEXQ`W/V/ -M);AC03P4*HO-^D@)`C6HHPG!%`$%U86]?<,`<*I^42Y[@7]MBJ?,QX3M3/:E -MZ9/S)=617P5Y5PZIU*:8JM;V!QV(A,(RF!F:C2+OF&6]C`#8M3!B-GH,)PY1 -M-;%69(1/24\>8N]NI*`*RQTX*!#U)B'XKW5 -M%V6Y*;=1\]!=G:91]&D7!#43@0-P7``RF#3BJBB%M%,.7\)4T&U&X/C8(4LW -M\ASM]>54Z@W1_9`Y0CEW_N9NJZWW4]4HZ+``;=&4+41:XH6=V/B0#[WJ(5^F -M^T'@XPE].>(76"[6@J7/$,#_3Q.^?,D1G90(-7#9N@JW\W:I<_X```!@/'"( -M&^G]6XWUER>23R-9*V(/<4/R5B3&S"7\S -M:FU`^C#>_:,*%#(5*,IB!S*]O_15LX>H!Q!D_\VM,"PZ>:N6=BRN-=V=;8TR -M>_16]XO)!,A.D@6P8A?CZ_F5]Y=LR5(L0_`-GEX7GC8W3"%D_*N+DI*?<<`9 -M203"1\B,5J$NKBQHD#];WLNRL5=_I/F(56'DZS_[30XJJ6`%1N59KHI,34]# -M8GP&HK\5L?&1B\W3[53)J.$==T?J@L".%=K\:(+=23HOAFY\)[RYNK6GM_%6 -M\6J+[6K>Q@(&1V3,R4CM@RS(*,9ND0\DP`%]N-8Z\$_!I=>$FD6-@V -M*1+[X_4)1^T`S7A=L5?A?\;7>+&9J?QRU9T<$I,GGM99UXHTC#[.<1Z: -M'3+=7"C\.5#<_IX&%MCL$FP4:Z>CD,7_>K)W5]^R>!3._10]``$$!@`$":3Q -M)X%N@G0`!PL!``0C`P$!!6P```$`(P,!`05L```!`",#`0$%70```0`4`P,! -M&P0!!0`$`0,"`@8!``R'N(1LP)Q>P,!J``@*`3U]DI4```4!$0\`>``X`#8` ->90!X`&4````4"@$``"U#*W&SG0$5!@$`(0`````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj2_lzma2_1.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj2_lzma2_1.7z.uu deleted file mode 100644 index a9a19b905..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj2_lzma2_1.7z.uu +++ /dev/null @@ -1,287 +0,0 @@ -begin 644 test_read_format_7zip_bcj2_lzma2_1.7z -M-WJ\KR<<``.73?8V0S$```````!>`````````#]5#Z3@7ILD\%T`/Y%%A&@[ -MWP)!,(6+]:YDCG/TF9,6Y4@I6&:W,\L.GXAK)SG^7$ASM;Y]KP;]Q:,S]93R -M>,&)>5<,&FZE"`#6^N9W.O9$'UE^T-50DI_AD]BN$0G/D?)@D^5S4+=>0I33 -M8+60+5WO?S\=&H#(CWK#P8A*.F39U-N85;*`7:QH4MPY]Z"R4@0-G[PN0P/I -M&4U*T@DV'"`CQ@7=GL@J7_2-A[.]&`<]D>$^(9=0(?Z*\Z.%M#RG1BD;5#6( -M4_PL?`47!00BJ=5&HZ7@@B$C!NO::D+1C%8P).\)*UDX0P@<+::RMJNW=<@+:$ZER\IE^S3 -M<>=HCZTGM[:O[2?'(:Q@840D]\]5Y73NXY[]$A&S9_<=T[^)S9E-I@,/"Z%N -M3%P8EQ8N.<>T1U:G?9*=LX1R,65>5\LCE.PG__FU`+L]UUEKFS13]3C4N`J/ -M2*#MK;D6R_YC0[KZK#6ZDVED3OA(WO_#+'G.!7!DNT&:A<:N8%2S1T,0<.CX -MWI?5110E(]/(V5U26WQEEBY"+^%%%QQ*$$LVGS;&M##OO=PE)#7IOV]4!T0> -MMCVFR7A^)`*]D,D*8(TTY<\22+QK022#]K1P8Q>ZDOE"5%*XR1S_RD)#8:OF -MV8PM<:&:XO9&=U7J?O95W3V[0_>S$IA67];6D(/WJJ:Q>6%"L4.3$3?0E!!$ -M%?%!2/7&XB4BNO1`#[FYN$MKM,TL^'./,4GY) -MNO_;YJ7P.<8Z"R!*LK]S`B1=P4X(^JK3]7X8N(%H?=H&K>KB'G7(0C'R=1Z0 -MZ`IBTR?O>DKYV:WR$Q0MRO.CI2E[0;'KUGX`,?^8H_"$EOK=81Z5Z4VZQ'O; -M;O;-'3N/M(@343API(#U5#X1=PK%4)/F?[I"DE\39HS<'P)7H49\16$$ES92 -MA@%4O+Y4AD=?Q`Q6L[^+YH+AJ-Z!]8./"Y'^Q"*$TJ#,%/ESOJCC)X:D@0R_ -M?J)%YC&F):9`]N(:_,O,>0]$-QL,-?ZE@EH7Z=TEA\M7949(]"*65FN\?-CF(U?7P0?R&\DOWV5DVFK[.JXEP>WU1IL?6K&/C -MWJ(7%PM9ZI:B)8)Q$N-53QL+1O[;'7O/7/O^;3JY[WU7(!DWS`YXM'QL?+>( -M"XZ7)FJ3#T4640CH[0Q8U319C-]L^2259=A(C)[[!/*9P+!6MXIH$N)1*Z:& -MQIZ7]E*8%(B.D'_@P=8!H(?*X?N@HB+MAKFN3F][.%W':*1!5I4=/"TFY>,\ -M=4<$EI/)\S[27U*=0/;8!0P4W/=5+RC"*W]L[Z>GIXO;=$L;^CKMC.FK$GA0?W<=3^K@8Y^D_FAZ!W7WZ#.6HO6/_: -MM&X<5E:RAU)=J;SF.%&+0R;V*[FQB?;-D6E*-E9A9B[,4F',0KL8S]AZ3/3, -MAZ!6('R])>:,3R!'4,\HCK1#'3_?PE4$NKGPX,R?.IK6$:/[E%8278\-K\&D -M4\:14"/(J(V,!$2BJH@D@[TOT`^<-9#'>!Y!%G[3Q4L[4EU[56_:"*>E#X'= -ME='@D%RN4=E!\F6P+B>NF-E -M.')J;D/S>](@#H.CZB,"S;X1F.)O-8.%W0+\OBW-QVYBLHRW$*]^CP(Y/U\G -M<3B;CDT0]"EG+*#EDEZI35$5+9S&_^!_A78^X7/<2I.4Y;"H60LCL"Q.5U=,LHK4"6W:HZF -MZ?(LI+*?1?]2$%"5;V^Y]A>V$A;XY*$P"@WF:#I'$>>Z@'G8"9##/BP&7S4P -MR+!4&:25@0#?WAT5NTR6,RW,0XNFDRGJJ'"[! -MB#`M[^0!B$_UO("?`8';,_EYIF/`YS,HY7,OO1Y`A$BAQXI(K,:Z?[$DK[LF -M1JP-RIXI[\KEKZST5NF-26U91M2>F]R-?H6.97>%;M$0B&E;\FPR!_8150K# -M<]3V($5-6SHJ[/"&TYD;ST3!R#@B92\![8+L/;^9;:^+(C'(Z[&A,_Y7P=$6 -MSKYQ6J=0*0/@I?K_Y@L:A'XR_=%D=4UM5^8.7CZKI3H%Z.&F'T_0IXB62\2+(R4=NDDVG8N]A(]M&ZH6-!N;N%IEGNP%1\$646$4*?JTOC-1 -M%3H/UB]S-NON.J5*JN\71XV9L`?IV0DNQY87`Q/JQERXF.B -M<<1R$A7$??LEM.:+%*JG+/SM23OHC_X[]'*WW.H;R658END(V=8SJK]K^DVX -M!XR.GLR_FS_7>CF[]F7&4V3E<#!^5`/B!C955]_-N(F0[!^%U)G(DX,Y-SWE%.TJ1,KN7K_JS^OH?.6U\4@Z>K -M5-0[1GY`57LW:6>GO'!>FU^^MH"`=0.VICBJW_"`.AN^14_A -ML&:(BY,W+\E%!4$G^;3$!WW_)J>_-%0KHJUB`ADT\]#`$W3*]RC&JDCHP0&BAT2\;Q#N>&MUFH8&I[^72X/_V&S]J0[4:!R+L -M=FR<(I>K3G<79].'1C5M'U>E=@A:6<8C&M4)IEIC='07>AK,.RT4,[9^6M!/ -MQSSK`/9&I/X#T`#T0[ZY:H-6_F*QC:."_0I<'O:3-EJ910,KJ[^>E@H2O$OK -MG>0HH/;\>`:*1^*-<'X_;P-,1-C>?E?<23A=YI-VJFS]NL;H`D?>=%N\ZC)L -M4V5TO-RL,S:O8KM?0')<[`-@&.`>$;')_TT/3IZX02G6'789"M6-5^4_;N;L -M$B053#PY8*6KD -M%Q\#"G99*RY0Z]!B"5/58PT -MJAH.UI_>?7]0O.%'W&>\4J*)FOS]X!HZC^6GLFA%'@VA%5#''Q\V@K:?WJ>\ -ML3D"9G\%![+R^KAFA7Y:!61'?B`@^9'[)U]1R,&85*!E\A5CGU:'E%0\O$LH -MS2\"B(18$R)+4?8NA^8`SJ]-5YD)A:3U7\GMJ,K(\79#AA8J#X81K0]V6#WS -MKG7W7G1]WTS59JPM\?#9`DSGO[3FCJ1U>0F[XY,5-D!`)ERPIK8YNZ<1#3T^S: -M+C8/16@5=L/='P>_ER`"1V@R?`1@:Q1[!6=R<"SM.1N==H%HFO'0C;.%HC"" -MAY8(+BC0_^(<;#3G4^ZS(=R32LH'F5REZ:9J?G-L9X46GT)QPNQD%CIER2 -M^OB@<;/$_%R:QR)8XMOG._E1^&KX=&ZLC"B'D1YVJ;&*&^[OM/-`LW*+@$^I -MEI1*2HUNJQ$;!@T3%"-OC(Y!&.N$]^G=1CAVWG>^;4K_CU%0O?[>H$C:%&Z# -M9RH1=WZI-'G2?PM[0DM@VUD@'#-X[!I3X\F&Q$/-C9._6,;]T=KCX)Y#+K,"OJP?9GAK-^S5RJ)0L -MK;Y3A54>@BNYR?&'45;186QEIU)WBT\DW7B?FWL.W>MQ@X.Z>"2*RFEB$JP= -M]&M4<+V>]D82H%QX6X:9COZU1JD]$X=;-3)%D'S;\?5L1[^;7F11T)=3:EQ; -M3M#([X>4>&:!^+/A#!=)N+/]DT'U'1FKJPXL=@G^!$A6=H049Y(?^4G-.Y.4 -MJ(BY#1.4:$>D@T;H$PNN>VP6G9',Q;\'M$']7TDC/%-"4)#^/D2F%I!-LN&EJCEVS]-O:`+MVO0,`YI(KBH\>4I` -MAQT>X'U5T('3V/#GB:4M'08,UE]/U:&?L]AOUO6U$NF:J\#BSS8'[5F"/95" -MR)[@B@^(_]/+<%9),KA*@T80#.%W^/LT\['V\G=-6-_`,Q8=,W"*9.8P@^@Y -MN))H,NOY4W@9@ZTU-J@XV.(D=_XT[[">*B,8"9RT/@M,K3(/J\Q8T(/_QSJF -MC-[EWGPVDLJ=P'\G6VL2'<>CKJGX$)05&0H?$N4,=*`+_5?7W7@?[KBY*@$< -M'%7QWH>&1A6<5`$UD3B8;S@,[1!$--9<5)=Y\0MU&;I860&<'[2K:C35?'HK -MD.YL1#(/_N\WBKS'7LT6Z`7I&6JZ*4`0E,!)N,,`S\L-7)?K&;9;I81V+/*(=<[ZW;%I*D+@@"IEC63J81?NT^^A/!B?OJ -MZ1?6IFN`L,JZ`]?W8FW'LNFBO+EJ^%>$*E64)G.V]D?]7FHW3G24:D)`BB6. -MR)PC>@T/MH1)Y2]ED,YCW&6Y1#H.N`M\NW&B(K4/GEXYR4]/3E5/JM&7(TBV -M9#Y73UIJ"74MB'_A_60"U=9$<:=?E_:EQ#$Q['-B%F4Z'\V\^B?(>UWEK:?: -MN9:&]7VNQT"K/+E7./L_%?*NNYFS?WBHYFQ.MTF7[U%<(M&(>,>E4FK[GJC2 -M,B8B)J[W]@R5F;=);`Y+[*PK'#H@PRD3RVKND8UI9/\:#<>R2`H<]#GY@H6D -M,GKG_+@OSOG[5;B=T6?,IKNB/)37_L8`3N"CV04E30(C[`_,C1ZM\8:&B^^KOU5L$`AL/B4[FM$"'X(X,3>V,:2 -M1%"T%K_=",4-.[%]PW[1EW0*.N;E=7M&MR14C4SFP,;2RTAT93N< -M6`4Y'.]'<0Y*G?\Y)K'Y,`E[^!:SZ7;[J%F(,BDT)O\.4%"^OY7BYH=[M`;A -MPMZLWJTV#PLN&E9SS*W%+IK"\`](5W89"?A2QZE;+:.;UU0V*!4@-OK9WM:" -M)2G$X-G+YDLV!!0N[S-``]+V<'+4F9,3Z/IJL[?+K6%^$LW7+/+T28:LZHN_ -M^^%)%O;V`!$@U\W)O\%V1=N1KA?>#2.+$,J5I\X]`L7D@B_\LHJJS%\C@&6O,)W^$1^X6SH@Q;4\*F6*L<]"^U7,:ECU%;Y;Z^AY9QD+86BL72A*#)L82 -M8G*3ZFIDP:@S,=0>12UD`2LN_77?>SHB3H+5:(J['1-,?=,CL]S+Q5:`=U%\ -M;L;^S03-*=G[8HV`*E5O4<@A)[3-2Q(!23U#1&MG_9B/`IT9E&\^J3SLK[AL -ML*HQ:F5TP7H>R>=_SQ.6[2K^^;]C@3A9ZQQ_1''XFFAE@R1]$R:,;WYJ9><8 -M)B@P,H`YP>:6RAX5-?]\Q,TY;A\*B -M58&9FYM_/5(=II"YZBL!Q07-BQ7''E@?+M9(1A(^7K2(_K_0^1!%-R"BG9%\ -MWX$S&BQI447_A:E]3`MY8L3$15/PLL,,V.D"<#!TS&&,2D>/W15B5L`*5Q,V -MXX3>OU:E8M.QP!MX`_DR^G^>>F$ZJ%`#44].FM;>9R>],DI:A+5J4M-\([Y< -M'B$8HT6O,3L7$@>Z6V23)DXL30&7P!MD^*E2C%HN;RG0#P:#?^H$9WSH\QV. -MA&\N_#PEE#(*4>VY3*]&JS-JQA;>ZVX*@>\RR'>XPOO[Q/-B89$#95Q>^-#U -MX";H%=R0+:J`P\Q,.US(!JB`7Q6EO8AC@ -M:1'HJ!DV\R$FV#MK0'W.*XGF@LVCAF0BY*_CQ@8Y\>9KAXX$<*60D=9]I1`^ -MV8!;IZJ15\1HK%V;2.$5*(11I^PR9$L!=LS0.>V5)8=N$`J3X-?:&W$02^%; -MED7R]>'E3G:C,5I"=R(S#>;VFF!T:8H>:N\A;$3`DZ\[QS*(TM['0KDC+"PJ -M]?;?LX)"]RT?;(0ICY;HY/XV4C]LL^9+6<:]Z"]2>V*7*82U#8X5`WI%\]/_ -MFJ,J?[^&P&,U*C?*1!%W!JGEO"E -ML]HQ.G#\B1&H%Y:ZLO@L^0TH9"#?80.54)Y:)NR;2G_;/?66G880!=2O?"(Q4&^TZ-&J#+RNDBC<$HYE6M7ZQ_RKG/H;+MJN"J[SNK[H*>V^OFI -M@^GJPQ-0VZM-/PMMC7(C$7W6IC.D$NV'S'^R`["3]:2:)ZU4E"-\FO-GFK)T -M=U[O7*>/9&F(F&)=3D`5J'B5WE"G9-D4=I".:5-V_I83LAB7+V]2#']4.#T9 -MJ_O9UD?,@ONJR/4A`Z1)*JT?P_B,SW4S,;XG4><,28D@FJ%N66*K&<1&R%E2*"5&O%[>U20*L -MM"@$-WS:2G[W3L-3;Q\IXG#N&GXAEB$ENVP+`]QWWI;FUFNFZZMC6)[@AGZ4 -M4AJ:/[!*HCE?QE',)MJ!0O-N+!,F(5=0#\][W5:O6)6"NV+K,DJB-KHRE-1B -MZW_Q%TW39.+UJ4-UB-P&!,GZ(V(D1/4E+I%R,=[OZ,5[[W<#:.F;)&.'6P:7 -MR82KS$=QBQCV_D+<&B.1F?NVQFNA5#-UD;VRE3:Q1>20U5U0CSDH\6+IE8D' -M&T3`X)V@/G-NDUCKD15JBL@DX]8XM(;XEX%\JU/O^977K]H4$CKJ>N^/F2\6 -M:7IE-D5$WV?@R"XQRK#!F8CDKD*84=P7]!/+$U5\!D$&:$8--5F@!+QO\_,N -M:@8QAP.>ETO'5=*$*7^!B&C,<7].Z7>;D?+A>ZPQA$BF,<9^/\/\"#:/9@86 -M7V="7`M'6;4Y4..L9^9#-Y:ECQJ:UVJ/TY+=N0`1"$82TGD$2O.%/9:-NX,_ -MKLBYXFR2!AY-\F>4\X-2,6^GP57R?T%!]JEGA@IIM:8G)._0!'Z,Z>(1CO2$ -M#CN-&!D:W=^$#VYAHWK`*97^NZ";B18_)$&0$,P54J^T+]Q -M:1&X7ZOX+.6-SGM=)-;O6X(WW`6.EI%")'=N?^/'91?K1`N.!">2.%4RLKR* -M&UX;S+1"\PVI,2L&5X(&ED%7HG&)//_$)+O\_F-OH4'FF:+SUT?L&PK(K;I+IX@W -M6B1![(%W2A>[GK>WE,34L\P7KQ07_QANUF7(ULOVASH42%#LT^!]CHL3D>"Y -M2"[DF(`ST3/='[0!8%[XDG/ZI,T^X0JXA: -MIRH]*>X=]"Z=V.LJ1;]78D8*DD+[!]%)2%CX=G^<@_9MIOC`_8_AA"(TPBH7 -MXN-*:]1VF<`QGL87I#TH.+%QJH][(T5NE40+NI"CP%<5NGZ*?;628\O/:4R@ -M[<2)3O+!E*I9ERFSXK:\&N3(-+9_O0N69;#7VU7U@Q`-&42_6O5T1J$F<,A? -M,GW92OO,R+V^>0`2"XIT4CEF[<)^AZ#).1%MS4B!:!E">OT'X'.*<&SJ.R6@ -MF$EC%54$F36,5'`;Q([%_M"\#G\WH/$M%L/F%^=YUND)Q:J^IPPSS^3E(&QT -M*75E^,)MW#[_;$`)>3].RC7!."?J^0/2,S8(0"SL\QO:(OR!!1J)MDM -M9@OPYW\&:H*^6B-X6!C,L!Q9/1*]F.8FNJR,&2.]!B/EQYT6*[RF0`_('NY8 -MDC493"!#[_8)N+5KG.`')R.``AW^93-2"9?),:`E"?N1N`B0[C21TZC#T5*W -MJR8AH)];CBEV41)9?5[&7(^LTPRIU^A@,;Y8/-9H9.2.@0+OP`IH+*&A0J*< -MEN]^="*Y&E05'`U/X%3\7GN+ -M,C);X*IE)FD27"H8M*O/VT^J5%(-F/9L;)FJ(1H&U=##?58FI(N4ZC=C:+NQ -MS]1O*D"EL:C9%MF>5$M#%YO&2@%&TII1N1M234_2CF`9!;?P>,9WKE^4+%9J -M=DNM$OTA04QHA.U=\2^:]X$!!L^($1>51^JVZE]J'!*H;BZ>.GE&O!4,=T"@!>>/L&\$J@`%=`;*N=ESG -M(OAG7MIF`(Q2^:_W`JH\IU@DQ^KHZKRM*;HOB5OB0Q\-[\U")X@PWIU!I_ -MC:[4\X.U]"!MK&&R.7\,>(*6ZE,\2^TE?2,GJ9WYAJXU6L"5VFX-5R%>L])( -MPI"$[J1@`2L@#TC@E[ -M0B8H"MQKOIUWTIUB'E7.Q$`MKQ&*OT*V$27$CIJK;*CEO?=6PWJBD2\!B5'N -M72(D?>$I4!I[06.KT!)Y:^8B3E$A\6] -MGVKQ5H$-X\,#5;HA*G]>TQ[58K!(*%N"S0Q<(&=ILTVS_6!K>@77J#T8].5$ -M(8%8V[M^S#"]# -MLO@=SO4$DMK!M3083U<&)`DI+4^*.W/A(J-!(:R5#N3+"^LUGH!(/T7O3#T? -MA;=!AR>F&AFC3:2S/"'3'!G>V80+^\>:'A<^;H#1)E[^&?=WN*C4>E\8)[61*2L^><<;#R8A]"'5ND -M6O&_<'@CD"CWV]FE_[1);\69),/-(+,LJ.0LU?\H]XL8_:7H($?.0)&_"HQG -M,3&]EBG5G2W%^1-%OU&WDS@Y6?$`^;B)C`I]!83*J#II"K<]X1'6YT,(JU!H -MG35]1X*S-5,5QA;;UJ!D1=0%3I?PF::/OZ<#L;R=$U\QS1.H.=Y+AEC.K)V! -ME])AA-S.DA!KDN^QV]F62-./+*.UTH:114D"$V$DWD#/0ME2$7S:X(*:2#N, -M#_QI>28\KDT-3,MQ%:]@6H*]GUT45V.6$YM+*Y,`Q=QC(+E`H"&\85Q"3.&FB6$+IQ=$_^HA`N -M$;=SIDL-@1?3\>O!E;O\[$YU^(*"D@ALTGYRJRF<*+]`@[O!L.,Y9)3XPOHE[D2K5$LD',W4Q>/%F\+/'" -M2U/W5(E==I9FG8(OQJ,M*1GQ%+%`3@WP-A,.*:T(>!\C6X+H6[?]`JJ2%]6Q -MX&(A=:Q\UJIM+))_2U.!1"!5[<8U5AZH-@VYF$C.Q2VV^AM!11S(=G;M#;*N85A^C%4I*V9?@T_ZA@8&3#]%">19T>(+BE_$:EB -MI7YB!'N<33*E_Y(CHT6.,H8#WG[0W6:79>/K<1M9FB6'B_X9\I";A;Q,[1^. -MO9_=(<*C@3']U97@UWA/Y=W4=$_FR\SB61"7M3!)+>;]&ZW+0#4*85?-$^YU -MVT?:7N?Q0_AF%#BW'`L\FJ:18?4X!NR._`[7GE?61$.FY\..[%QZ2^'F&W]Z -M(+7X( -M0;R?[J'5N2]KY%$HDA^S"*VK;TQ,Z$8K3A-:)>@'K`'FO%ZX*KRLKG+P3:,, -M.V"@QC!S^DN*76M228@B^B&U20&!KB-8<&L;ZL]W4H#3 -M8W]M7^72.W"!1W,5VV%8LV>:KDE:%9F)*ML^_&]6-_O?)H;R!Z%6NLWK$H/0 -MKXUT!!I(.GD=DD,'GWUVF>1DX9:%G"1^#<[VJE5@!B@P"5:X1(?!J2A+`6"B -M````%6```%A0```4D```$^@``!/H```/Y```**```!-8```1B```$(@``$GP -M```2J```$J@``!08```4&```$V@``!0H```4*```%"@``!.X```1>```$B@` -M`!.X```2F```$5@``!0H```3N```$`@``!.X```0V```%!@``!$8```2J``` -M$W@``!$H```1R```%!@``!#H```2N```$<@``!#8```2J```%!@``!-H```2 -M2```$[@``!*H```4&```$J@``!08```2J```%!@``!*X```2J```%!@``!.( -M```3B```$]@``!,H```2>```&6```!+H```WP```$!@``!)X```98```$=@` -M`!+H```2:```$7@``!(H```2*```-\```!`8```0R```$T@``!.(```3B``` -M$Z@``!.8```0B```$4@``!((``!)L```$(@``!`X```0B```$Y@``!"(```2 -MR```$M@``!+8```0B```,M```"8````F````$U@``!,X```0B```$P@``!/( -M```46```%%@``!18```46```%%@``!`X```46```$C@``!(X```2.```,?`` -M`!+8```4"```$)@``!!H```4&```$B@``!(H```0N```$C@``!"X```2.``` -M$C@``#0P```T,```-#```#0P```T,```-#```#0P```T,```-#```#0P```T -M,```$;@``!%H```0^```$'@``!!(```2^```$]@``!#(```32```$,@``!-( -M```0R```$T@``!-(```32```$T@``!#(```0R```$,@``!#(```32```-1`` -M`#?````X8```-\```#'P``!6P```$H@``!*(```[@```$,@``!-(```[@``` -M$,@``!-(```0R```$T@``!*(```1F```$K@``!*(```4&```.X```!#(```0 -MR```$T@``!-(```2&```$J@``!&H```4.```$3@``!/X```2B```$*@``!*( -M```V8```-\```#'P```2B```$J@``!*(```V8```-1```!*(```2B```5L`` -M`!*(```2B```$,@``#A@```2J```%$@``!*(```WP```$J@``!*(```V8``` -M-F```!*H```2J```$F@``!%X```0*```$T@``!/X```2N```$F@``!*X```1 -MJ```$F@``!*X```3V```$Q@``!-8```26```$%@``!$(```26```$]@``!)8 -M```06```$,@``!-(```26```$0@``!#(```0R```$0@``!-(```32```$,@` -M`!-(```3V```$E@``!!8```0R```$T@``!$(```26```$H@``!$(```0R``` -M$T@``!/8```26```$%@``!#(```0R```$,@``!#(```0R```$T@``!-(```3 -M2```$T@``!08```32```$0@``!)8```1Z```$0@``!#(```0R```$T@``!-( -M```3V```%3````_X```/^```#_@```_X```/^```#_@```_X```/^```#_@` -M``_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^``` -M#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/ -M^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X -M```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^```#_@` -M``_X```/^```#_@```_X```/^```#_@```_X```/^```#_@```_X```/^``` -M#_@```_X```/^```#_@```_X```1^```%9```!'X```60```$?@``!;0```1 -M^```%V```!'X```7\```$?@``!'X```8H```(40``"%;```@_0``'5X``!UJ -M```><0``'E```!U0```=4```'HH``!\Q```?H@``):D``![-```>S0``'P4` -M`!J!```A&P``([<``"7T```:I```'5<``!JD```:I```'````!SQ```<_@`` -M'/X``"7@```EX```'%<``!Q7```DL@``(,D``!QP```<<```(#\``!_I```> -M,@``';D``!XR```9L@``):D``"7'```EO0``)-0``"4:```:,0``'>L``"`U -M```DC0``(T$``".8```B=0``(?(``"&C```H@@``)W<``"@(```G:```)\`` -M`">````H1@``)]@``"@L```H60``)H```":````FD@``*&X``":````F@``` -M)H```"<0```G$```)G(``":````F<@``)OD``":````FO@``)OD``"F+```Q -M,```+[\``"PZ```P@0``*^T``"P'```P$P``,%0``#`\```OZ```,&,``"L< -M```K$@``*QP``"G_```J)@``*6,``"EC```I8P``*6,``"EC```I8P``*6,` -M`"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P`` -M*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I8P``*6,``"EC```I -M8P``*6,``"EC```I8P``*6,``"EC```I8P``*=L``"G;```IVP``*Z,``#%M -M```KK0``*T(``#%,```KK0``*\```"NM```KK0``*\```#'+```J)@``*B8` -M`"HF```J,```*5X``"NM```KK0``*ZT``"NM```KK0``*ZT``##X```T)``` -M,]$``#0<```S*0``,R,``#,I```RY```-.```#1,```U\P``-;@``#7+```V -M0```-AX``#6T```UM```-T4``#<@```WN@``-I@``#:8```VF```-H$``#:8 -M```VF```-I@``#:8``!1$```2R```$Z````Y``!0A0``4&D``%`"``!/U```3L@``%"S``!0H0``3L@``$\W``!/0``` -M4,```%#?``!.R```3\D``$^V``!05@``4$T``%!6``!5%```4K(``%5I``!4 -MWP``5-\``%3?``!51@``5D```%8H``!5%```578``%%8``!5-```4Z@``%2` -M``!3X0``5&```%00``!4H```5$```%3```!2AP``4M```%+^``!3-@``4VX` -M`%.6``!3(```4RD``%+G``!2\0``4U@``%-A``!3C0``4Y8``%6@``!2Q``` -M4I0``%:Z``!2"0``4A(``%&]``!16```5/D``%9D``!6?@``5IP``%*'``!2 -MAP``4FX``%7L``!5X@``5>P``%83``!6'```5Z(``%?```!7!@``5P8``%=` -M``!70`!__^R"OW"IXM+V*@^QM,X+9XE,O4'7!VKCB-_)V9VSFCURCC$41@$$ -M!@`$":3XA&R'N"<`!PL!``(A(0$(%`,#`1L$`0$```(#!`S`G%[`P&H`"`H! -M/7V2E0``!0$1#P!X`#@`-@!E`'@`90```!0*`0``+4,K<;.=`14&`0`A```` -"```` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj2_lzma2_2.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj2_lzma2_2.7z.uu deleted file mode 100644 index 8a31482b9..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj2_lzma2_2.7z.uu +++ /dev/null @@ -1,240 +0,0 @@ -begin 644 test_read_format_7zip_bcj2_lzma2_2.7z -M-WJ\KR<<``-OBM(#`2D```````!Z`````````']'IDO@7ILD\%T`/Y%%A&@[ -MWP)!,(6+]:YDCG/TF9,6Y4@I6&:W,\L.GXAK)SG^7$ASM;Y]KP;]Q:,S]93R -M>,&)>5<,&FZE"`#6^N9W.O9$'UE^T-50DI_AD]BN$0G/D?)@D^5S4+=>0I33 -M8+60+5WO?S\=&H#(CWK#P8A*.F39U-N85;*`7:QH4MPY]Z"R4@0-G[PN0P/I -M&4U*T@DV'"`CQ@7=GL@J7_2-A[.]&`<]D>$^(9=0(?Z*\Z.%M#RG1BD;5#6( -M4_PL?`47!00BJ=5&HZ7@@B$C!NO::D+1C%8P).\)*UDX0P@<+::RMJNW=<@+:$ZER\IE^S3 -M<>=HCZTGM[:O[2?'(:Q@840D]\]5Y73NXY[]$A&S9_<=T[^)S9E-I@,/"Z%N -M3%P8EQ8N.<>T1U:G?9*=LX1R,65>5\LCE.PG__FU`+L]UUEKFS13]3C4N`J/ -M2*#MK;D6R_YC0[KZK#6ZDVED3OA(WO_#+'G.!7!DNT&:A<:N8%2S1T,0<.CX -MWI?5110E(]/(V5U26WQEEBY"+^%%%QQ*$$LVGS;&M##OO=PE)#7IOV]4!T0> -MMCVFR7A^)`*]D,D*8(TTY<\22+QK022#]K1P8Q>ZDOE"5%*XR1S_RD)#8:OF -MV8PM<:&:XO9&=U7J?O95W3V[0_>S$IA67];6D(/WJJ:Q>6%"L4.3$3?0E!!$ -M%?%!2/7&XB4BNO1`#[FYN$MKM,TL^'./,4GY) -MNO_;YJ7P.<8Z"R!*LK]S`B1=P4X(^JK3]7X8N(%H?=H&K>KB'G7(0C'R=1Z0 -MZ`IBTR?O>DKYV:WR$Q0MRO.CI2E[0;'KUGX`,?^8H_"$EOK=81Z5Z4VZQ'O; -M;O;-'3N/M(@343API(#U5#X1=PK%4)/F?[I"DE\39HS<'P)7H49\16$$ES92 -MA@%4O+Y4AD=?Q`Q6L[^+YH+AJ-Z!]8./"Y'^Q"*$TJ#,%/ESOJCC)X:D@0R_ -M?J)%YC&F):9`]N(:_,O,>0]$-QL,-?ZE@EH7Z=TEA\M7949(]"*65FN\?-CF(U?7P0?R&\DOWV5DVFK[.JXEP>WU1IL?6K&/C -MWJ(7%PM9ZI:B)8)Q$N-53QL+1O[;'7O/7/O^;3JY[WU7(!DWS`YXM'QL?+>( -M"XZ7)FJ3#T4640CH[0Q8U319C-]L^2259=A(C)[[!/*9P+!6MXIH$N)1*Z:& -MQIZ7]E*8%(B.D'_@P=8!H(?*X?N@HB+MAKFN3F][.%W':*1!5I4=/"TFY>,\ -M=4<$EI/)\S[27U*=0/;8!0P4W/=5+RC"*W]L[Z>GIXO;=$L;^CKMC.FK$GA0?W<=3^K@8Y^D_FAZ!W7WZ#.6HO6/_: -MM&X<5E:RAU)=J;SF.%&+0R;V*[FQB?;-D6E*-E9A9B[,4F',0KL8S]AZ3/3, -MAZ!6('R])>:,3R!'4,\HCK1#'3_?PE4$NKGPX,R?.IK6$:/[E%8278\-K\&D -M4\:14"/(J(V,!$2BJH@D@[TOT`^<-9#'>!Y!%G[3Q4L[4EU[56_:"*>E#X'= -ME='@D%RN4=E!\F6P+B>NF-E -M.')J;D/S>](@#H.CZB,"S;X1F.)O-8.%W0+\OBW-QVYBLHRW$*]^CP(Y/U\G -M<3B;CDT0]"EG+*#EDEZI35$5+9S&_^!_A78^X7/<2I.4Y;"H60LCL"Q.5U=,LHK4"6W:HZF -MZ?(LI+*?1?]2$%"5;V^Y]A>V$A;XY*$P"@WF:#I'$>>Z@'G8"9##/BP&7S4P -MR+!4&:25@0#?WAT5NTR6,RW,0XNFDRGJJ'"[! -MB#`M[^0!B$_UO("?`8';,_EYIF/`YS,HY7,OO1Y`A$BAQXI(K,:Z?[$DK[LF -M1JP-RIXI[\KEKZST5NF-26U91M2>F]R-?H6.97>%;M$0B&E;\FPR!_8150K# -M<]3V($5-6SHJ[/"&TYD;ST3!R#@B92\![8+L/;^9;:^+(C'(Z[&A,_Y7P=$6 -MSKYQ6J=0*0/@I?K_Y@L:A'XR_=%D=4UM5^8.7CZKI3H%Z.&F'T_0IXB62\2+(R4=NDDVG8N]A(]M&ZH6-!N;N%IEGNP%1\$646$4*?JTOC-1 -M%3H/UB]S-NON.J5*JN\71XV9L`?IV0DNQY87`Q/JQERXF.B -M<<1R$A7$??LEM.:+%*JG+/SM23OHC_X[]'*WW.H;R658END(V=8SJK]K^DVX -M!XR.GLR_FS_7>CF[]F7&4V3E<#!^5`/B!C955]_-N(F0[!^%U)G(DX,Y-SWE%.TJ1,KN7K_JS^OH?.6U\4@Z>K -M5-0[1GY`57LW:6>GO'!>FU^^MH"`=0.VICBJW_"`.AN^14_A -ML&:(BY,W+\E%!4$G^;3$!WW_)J>_-%0KHJUB`ADT\]#`$W3*]RC&JDCHP0&BAT2\;Q#N>&MUFH8&I[^72X/_V&S]J0[4:!R+L -M=FR<(I>K3G<79].'1C5M'U>E=@A:6<8C&M4)IEIC='07>AK,.RT4,[9^6M!/ -MQSSK`/9&I/X#T`#T0[ZY:H-6_F*QC:."_0I<'O:3-EJ910,KJ[^>E@H2O$OK -MG>0HH/;\>`:*1^*-<'X_;P-,1-C>?E?<23A=YI-VJFS]NL;H`D?>=%N\ZC)L -M4V5TO-RL,S:O8KM?0')<[`-@&.`>$;')_TT/3IZX02G6'789"M6-5^4_;N;L -M$B053#PY8*6KD -M%Q\#"G99*RY0Z]!B"5/58PT -MJAH.UI_>?7]0O.%'W&>\4J*)FOS]X!HZC^6GLFA%'@VA%5#''Q\V@K:?WJ>\ -ML3D"9G\%![+R^KAFA7Y:!61'?B`@^9'[)U]1R,&85*!E\A5CGU:'E%0\O$LH -MS2\"B(18$R)+4?8NA^8`SJ]-5YD)A:3U7\GMJ,K(\79#AA8J#X81K0]V6#WS -MKG7W7G1]WTS59JPM\?#9`DSGO[3FCJ1U>0F[XY,5-D!`)ERPIK8YNZ<1#3T^S: -M+C8/16@5=L/='P>_ER`"1V@R?`1@:Q1[!6=R<"SM.1N==H%HFO'0C;.%HC"" -MAY8(+BC0_^(<;#3G4^ZS(=R32LH'F5REZ:9J?G-L9X46GT)QPNQD%CIER2 -M^OB@<;/$_%R:QR)8XMOG._E1^&KX=&ZLC"B'D1YVJ;&*&^[OM/-`LW*+@$^I -MEI1*2HUNJQ$;!@T3%"-OC(Y!&.N$]^G=1CAVWG>^;4K_CU%0O?[>H$C:%&Z# -M9RH1=WZI-'G2?PM[0DM@VUD@'#-X[!I3X\F&Q$/-C9._6,;]T=KCX)Y#+K,"OJP?9GAK-^S5RJ)0L -MK;Y3A54>@BNYR?&'45;186QEIU)WBT\DW7B?FWL.W>MQ@X.Z>"2*RFEB$JP= -M]&M4<+V>]D82H%QX6X:9COZU1JD]$X=;-3)%D'S;\?5L1[^;7F11T)=3:EQ; -M3M#([X>4>&:!^+/A#!=)N+/]DT'U'1FKJPXL=@G^!$A6=H049Y(?^4G-.Y.4 -MJ(BY#1.4:$>D@T;H$PNN>VP6G9',Q;\'M$']7TDC/%-"4)#^/D2F%I!-LN&EJCEVS]-O:`+MVO0,`YI(KBH\>4I` -MAQT>X'U5T('3V/#GB:4M'08,UE]/U:&?L]AOUO6U$NF:J\#BSS8'[5F"/95" -MR)[@B@^(_]/+<%9),KA*@T80#.%W^/LT\['V\G=-6-_`,Q8=,W"*9.8P@^@Y -MN))H,NOY4W@9@ZTU-J@XV.(D=_XT[[">*B,8"9RT/@M,K3(/J\Q8T(/_QSJF -MC-[EWGPVDLJ=P'\G6VL2'<>CKJGX$)05&0H?$N4,=*`+_5?7W7@?[KBY*@$< -M'%7QWH>&1A6<5`$UD3B8;S@,[1!$--9<5)=Y\0MU&;I860&<'[2K:C35?'HK -MD.YL1#(/_N\WBKS'7LT6Z`7I&6JZ*4`0E,!)N,,`S\L-7)?K&;9;I81V+/*(=<[ZW;%I*D+@@"IEC63J81?NT^^A/!B?OJ -MZ1?6IFN`L,JZ`]?W8FW'LNFBO+EJ^%>$*E64)G.V]D?]7FHW3G24:D)`BB6. -MR)PC>@T/MH1)Y2]ED,YCW&6Y1#H.N`M\NW&B(K4/GEXYR4]/3E5/JM&7(TBV -M9#Y73UIJ"74MB'_A_60"U=9$<:=?E_:EQ#$Q['-B%F4Z'\V\^B?(>UWEK:?: -MN9:&]7VNQT"K/+E7./L_%?*NNYFS?WBHYFQ.MTF7[U%<(M&(>,>E4FK[GJC2 -M,B8B)J[W]@R5F;=);`Y+[*PK'#H@PRD3RVKND8UI9/\:#<>R2`H<]#GY@H6D -M,GKG_+@OSOG[5;B=T6?,IKNB/)37_L8`3N"CV04E30(C[`_,C1ZM\8:&B^^KOU5L$`AL/B4[FM$"'X(X,3>V,:2 -M1%"T%K_=",4-.[%]PW[1EW0*.N;E=7M&MR14C4SFP,;2RTAT93N< -M6`4Y'.]'<0Y*G?\Y)K'Y,`E[^!:SZ7;[J%F(,BDT)O\.4%"^OY7BYH=[M`;A -MPMZLWJTV#PLN&E9SS*W%+IK"\`](5W89"?A2QZE;+:.;UU0V*!4@-OK9WM:" -M)2G$X-G+YDLV!!0N[S-``]+V<'+4F9,3Z/IJL[?+K6%^$LW7+/+T28:LZHN_ -M^^%)%O;V`!$@U\W)O\%V1=N1KA?>#2.+$,J5I\X]`L7D@B_\LHJJS%\C@&6O,)W^$1^X6SH@Q;4\*F6*L<]"^U7,:ECU%;Y;Z^AY9QD+86BL72A*#)L82 -M8G*3ZFIDP:@S,=0>12UD`2LN_77?>SHB3H+5:(J['1-,?=,CL]S+Q5:`=U%\ -M;L;^S03-*=G[8HV`*E5O4<@A)[3-2Q(!23U#1&MG_9B/`IT9E&\^J3SLK[AL -ML*HQ:F5TP7H>R>=_SQ.6[2K^^;]C@3A9ZQQ_1''XFFAE@R1]$R:,;WYJ9><8 -M)B@P,H`YP>:6RAX5-?]\Q,TY;A\*B -M58&9FYM_/5(=II"YZBL!Q07-BQ7''E@?+M9(1A(^7K2(_K_0^1!%-R"BG9%\ -MWX$S&BQI447_A:E]3`MY8L3$15/PLL,,V.D"<#!TS&&,2D>/W15B5L`*5Q,V -MXX3>OU:E8M.QP!MX`_DR^G^>>F$ZJ%`#44].FM;>9R>],DI:A+5J4M-\([Y< -M'B$8HT6O,3L7$@>Z6V23)DXL30&7P!MD^*E2C%HN;RG0#P:#?^H$9WSH\QV. -MA&\N_#PEE#(*4>VY3*]&JS-JQA;>ZVX*@>\RR'>XPOO[Q/-B89$#95Q>^-#U -MX";H%=R0+:J`P\Q,.US(!JB`7Q6EO8AC@ -M:1'HJ!DV\R$FV#MK0'W.*XGF@LVCAF0BY*_CQ@8Y\>9KAXX$<*60D=9]I1`^ -MV8!;IZJ15\1HK%V;2.$5*(11I^PR9$L!=LS0.>V5)8=N$`J3X-?:&W$02^%; -MED7R]>'E3G:C,5I"=R(S#>;VFF!T:8H>:N\A;$3`DZ\[QS*(TM['0KDC+"PJ -M]?;?LX)"]RT?;(0ICY;HY/XV4C]LL^9+6<:]Z"]2>V*7*82U#8X5`WI%\]/_ -MFJ,J?[^&P&,U*C?*1!%W!JGEO"E -ML]HQ.G#\B1&H%Y:ZLO@L^0TH9"#?80.54)Y:)NR;2G_;/?66G880!=2O?"(Q4&^TZ-&J#+RNDBC<$HYE6M7ZQ_RKG/H;+MJN"J[SNK[H*>V^OFI -M@^GJPQ-0VZM-/PMMC7(C$7W6IC.D$NV'S'^R`["3]:2:)ZU4E"-\FO-GFK)T -M=U[O7*>/9&F(F&)=3D`5J'B5WE"G9-D4=I".:5-V_I83LAB7+V]2#']4.#T9 -MJ_O9UD?,@ONJR/4A`Z1)*JT?P_B,SW4S,;XG4><,28D@FJ%N66*K&<1&R%E2*"5&O%[>U20*L -MM"@$-WS:2G[W3L-3;Q\IXG#N&GXAEB$ENVP+`]QWWI;FUFNFZZMC6)[@AGZ4 -M4AJ:/[!*HCE?QE',)MJ!0O-N+!,F(5=0#\][W5:O6)6"NV+K,DJB-KHRE-1B -MZW_Q%TW39.+UJ4-UB-P&!,GZ(V(D1/4E+I%R,=[OZ,5[[W<#:.F;)&.'6P:7 -MR82KS$=QBQCV_D+<&B.1F?NVQFNA5#-UD;VRE3:Q1>20U5U0CSDH\6+IE8D' -M&T3`X)V@/G-NDUCKD15JBL@DX]8XM(;XEX%\JU/O^977K]H4$CKJ>N^/F2\6 -M:7IE-D5$WV?@R"XQRK#!F8CDKD*84=P7]!/+$U5\!D$&:$8--5F@!+QO\_,N -M:@8QAP.>ETO'5=*$*7^!B&C,<7].Z7>;D?+A>ZPQA$BF,<9^/\/\"#:/9@86 -M7V="7`M'6;4Y4..L9^9#-Y:ECQJ:UVJ/TY+=N0`1"$82TGD$2O.%/9:-NX,_ -MKLBYXFR2!AY-\F>4\X-2,6^GP57R?T%!]JEGA@IIM:8G)._0!'Z,Z>(1CO2$ -M#CN-&!D:W=^$#VYAHWK`*97^NZ";B18_)$&0$,P54J^T+]Q -M:1&X7ZOX+.6-SGM=)-;O6X(WW`6.EI%")'=N?^/'91?K1`N.!">2.%4RLKR* -M&UX;S+1"\PVI,2L&5X(&ED%7HG&)//_$)+O\_F-OH4'FF:+SUT?L&PK(K;I+IX@W -M6B1![(%W2A>[GK>WE,34L\P7KQ07_QANUF7(ULOVASH42%#LT^!]CHL3D>"Y -M2"[DF(`ST3/='[0!8%[XDG/ZI,T^X0JXA: -MIRH]*>X=]"Z=V.LJ1;]78D8*DD+[!]%)2%CX=G^<@_9MIOC`_8_AA"(TPBH7 -MXN-*:]1VF<`QGL87I#TH.+%QJH][(T5NE40+NI"CP%<5NGZ*?;628\O/:4R@ -M[<2)3O+!E*I9ERFSXK:\&N3(-+9_O0N69;#7VU7U@Q`-&42_6O5T1J$F<,A? -M,GW92OO,R+V^>0`2"XIT4CEF[<)^AZ#).1%MS4B!:!E">OT'X'.*<&SJ.R6@ -MF$EC%54$F36,5'`;Q([%_M"\#G\WH/$M%L/F%^=YUND)Q:J^IPPSS^3E(&QT -M*75E^,)MW#[_;$`)>3].RC7!."?J^0/2,S8(0"SL\QO:(OR!!1J)MDM -M9@OPYW\&:H*^6B-X6!C,L!Q9/1*]F.8FNJR,&2.]!B/EQYT6*[RF0`_('NY8 -MDC493"!#[_8)N+5KG.`')R.``AW^93-2"9?),:`E"?N1N`B0[C21TZC#T5*W -MJR8AH)];CBEV41)9?5[&7(^LTPRIU^A@,;Y8/-9H9.2.@0+OP`IH+*&A0J*< -MEN]^="*Y&E05'`U/X%3\7GN+ -M,C);X*IE)FD27"H8M*O/VT^J5%(-F/9L;)FJ(1H&U=##?58FI(N4ZC=C:+NQ -MS]1O*D"EL:C9%MF>5$M#%YO&2@%&TII1N1M234_2CF`9!;?P>,9WKE^4+%9J -M=DNM$OTA04QHA.U=\2^:]X$!!L^($1>51^JVZE]J'!*H;BZ>.GE&O!4,=T"@!>>/L&\$J@`%=`;*N=ESG -M(OAG7MIF`(Q2^:_W`JH\IU@DQ^KHZKRM*;HOB5OB0Q\-[\U")X@PWIU!I_ -MC:[4\X.U]"!MK&&R.7\,>(*6ZE,\2^TE?2,GJ9WYAJXU6L"5VFX-5R%>L])( -MPI"$[J1@`2L@#TC@E[ -M0B8H"MQKOIUWTIUB'E7.Q$`MKQ&*OT*V$27$CIJK;*CEO?=6PWJBD2\!B5'N -M72(D?>$I4!I[06.KT!)Y:^8B3E$A\6] -MGVKQ5H$-X\,#5;HA*G]>TQ[58K!(*%N"S0Q<(&=ILTVS_6!K>@77J#T8].5$ -M(8%8V[M^S#"]# -MLO@=SO4$DMK!M3083U<&)`DI+4^*.W/A(J-!(:R5#N3+"^LUGH!(/T7O3#T? -MA;=!AR>F&AFC3:2S/"'3'!G>V80+^\>:'A<^;H#1)E[^&?=WN*C4>E\8)[61*2L^><<;#R8A]"'5ND -M6O&_<'@CD"CWV]FE_[1);\69),/-(+,LJ.0LU?\H]XL8_:7H($?.0)&_"HQG -M,3&]EBG5G2W%^1-%OU&WDS@Y6?$`^;B)C`I]!83*J#II"K<]X1'6YT,(JU!H -MG35]1X*S-5,5QA;;UJ!D1=0%3I?PF::/OZ<#L;R=$U\QS1.H.=Y+AEC.K)V! -ME])AA-S.DA!KDN^QV]F62-./+*.UTH:114D"$V$DWD#/0ME2$7S:X(*:2#N, -M#_QI>28\KDT-3,MQ%:]@6H*]GUT45V.6$YM+*Y,`Q=QC(+E`H"&\85Q"3.&FB6$+IQ=$_^HA`N -M$;=SIDL-@1?3\>O!E;O\[$YU^(*"D@ALTGYRJRF<*+]`@[O!L.,Y9)3XPOHE[D2K5$LD',W4Q>/%F\+/'" -M2U/W5(E==I9FG8(OQJ,M*1GQ%+%`3@WP-A,.*:T(>!\C6X+H6[?]`JJ2%]6Q -MX&(A=:Q\UJIM+))_2U.!1"!5[<8U5AZH-@VYF$C.Q2VV^AM!11S(=G;M#;*N85A^C%4I*V9?@T_ZA@8&3#]%">19T>(+BE_$:EB -MI7YB!'N<33*E_Y(CHT6.,H8#WG[0W6:79>/K<1M9FB6'B_X9\I";A;Q,[1^. -MO9_=(<*C@3']U97@UWA/Y=W4=$_FR\SB61"7M3!)+>;]&ZW+0#4*85?-$^YU -MVT?:7N?Q0_AF%#BW'`L\FJ:18?4X!NR._`[7GE?61$.FY\..[%QZ2^'F&W]Z -M(+7X( -M0;R?[J'5N2]KY%$HDA^S"*VK;TQ,Z$8K3A-:)>@'K`'FO%ZX*KRLKG+P3:,, -M.V"@QC!S^DN*76M228@B^B&U20&!KB-8<&L;ZL]W4H#3 -M8W]M7^72.W"!1W,5VV%8LV>:KDE:%9F)*ML^_&]6-_O?)H;R!Z%6NLWK$H/0 -MKXUT!!I(.GD=DD,'GWUVF>1DX9:%G"1^#<[VJE5@!B@P"5:X1(?!J2A+`6"B -M``!__^R"OW"IXM+V*@^QM,X+9XE,O4'7!VKCB-_)V9VSFCURCC$41@``8%,_ -MK6'!CL%DP"0&RS*\T@G^FX5\H?W4!!O!PH8>.28_N-V8TR"&GIM3`P+>$\OJ -M(9>,0-S]CR6X8T$\%"J+S?I("0(UJ*,)P10!!=6%O7W#`'"J?E$N>X%_;8JG -MS,>$[4SVI>F3\R75D5\%>5<.J=2FF*K6]@<=B(3",I@9FHTB[YAEO8P`V+4P -M8C9Z#"<.436Q5F2$3TE/'F+O;J7)#ZL;Y@JYC6[]@E%9`SU*4E_91_/UGTP] -M6`Q.3?S`A/:;-2["5G]4PJ-M0.OP,X:S5W+`V(SK[)K`V2XCN('B@"LL=."@ -M0]28A^*]U1=EN2FW4?/079VF4?1I%P0U$X$#<%P`,I@TXJHHA;13#E_"5-!M -M1N#XV"%+-_(<[?7E5.H-T?V0.4(Y=_[F;JNM]U/5*.BP`&W1E"U$6N*%G=CX -MD`^]ZB%?IOM!X.,)?3GB%U@NUH*ESQ#`_T\3OGS)$9V4"#5PV;H*M_-VJ7/^ -M````8#QPB!OI_5N-]9+R[;;6`MP,RS%^5G3#E1 -M#$3`EZ4@PLLD)TUJ]29W2HQ36\-=H27+^)ZQZMGD\C62MB#W%#\E8DQG..#C -M/9M:G'U=IF::L0KY"PNDIM2JTYWYG`?P2=]<56=5Y3W^#(;]L#L&FLK\H>*2 -M^^U'LPE_,VIM0/HPWOVC"A0R%2C*8@+R03(3I(%L&(7X^OYE?>7;,E2+$/P#9Y>%YXV-TPA9/RK -MBY*2GW'`&4D$PD?(C%:A+JXL:)`_6][+LK%7?Z3YB%5AY.L_^TT.*JE@!4;E -M6:Z*3$U/0V)\!J*_%;'QD8O-T^U4R:CA'7='ZH+`CA7:_&B"W4DZ+X9N?">\ -MN;JUI[?Q5O%JG+V<$1J=N3`-1YK/E*FVQ_;`40;LJZ^7S?[/^OQN!VA>-KS= -MJ5#%T:U^#O**)TU\#7Y`\\%GB^UJWL8"!D=DS,E([8,LR"C&;I$/),`!?;C7 -M+MR6QLHPXQCR!P^O81:5^\8(Z6!:R)8)SB/GF.O!/P7)U*,]G44C?,,M0*7J -M77A)I%C8-BD2^^',N$$L'OU"7,W2$S59[!ED>..B2/FI$&+_G(%M6=OH96B= -M*36WZ;/MFF=9_1$5'Q33GD?M`,UX7;%7X7_&UWBQF:G\* -M-(P^SG$>FATRW5PH_#E0W/Z>!A;8[!)L%&NGHY#%_WJR=U??LG@4SOT4/0`! -M!`8`!`FD^">!;H)T``<+`0`$(P,!`05L```!`",#`0$%;````0`A(0$(%`,# -M`1L$`04`!`$#`@(&`0`,A[B$;,"<7L#`:@`("@$]?9*5```%`1$/`'@`.``V -?`&4`>`!E````%`H!```M0RMQLYT!%08!`"$````````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj_bzip2.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj_bzip2.7z.uu deleted file mode 100644 index 7bff5c0d5..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj_bzip2.7z.uu +++ /dev/null @@ -1,281 +0,0 @@ -begin 644 test_read_format_7zip_bcj_bzip2.7z -M-WJ\KR<<``,N`-_N2#````````!3`````````$X%(H!"6F@Y,4%9)E-97.&0 -MG@`A^G_____________________________________________@++]WN.@" -M5;2VN>I2<\E)ZWC9'+[>1Z>LW93YCGH\J@9IX>[ESG%ULGC*K5V-K;4$LZ>G -M*]8D=N='30&D-:7%;>[=PEZVF;W=>]X]WI;F[W>ZVGH7MV'I+VWO>F&^[KR> -ML^ZJ6<]IO3[WT@]?<-"0"`0R::`"8%/3```#49,F1IH!E/1-H1A3R9&&C0J> -MT8F":9H4RGL@!E3RGE-L0I^D;1E/2GY3::&IZ!3VE/4],3T4V3*>IIZC]%&@ -M:$3(&@$T`1M")O2*>1HJ?IM*;(R-J2?E1O5-ZIYI3U/-4VFIY3]4]J:F3]4: -M;U$>4]J0'J-&@```/2`>IIY(-J'J:>4:9/2&@&FAZ@-`!IZ@!@TT$(*9&(:) -MB)M3R%/1J;U-I39!B!H3!-`>ID&@>H:/*9/2::>H,(&FC`AZC0```#(``&U# -M0!H:#0&@````$FE$2":&53PTGHIZGFU4\F3-"GZ"&*-J>D/*:#31[5/34>TH -M!H](!ZC0T`VH`>HT>HT&(`&FGJ#30:&@]0`:`>H-```:!H`#&5-`-!D``T/] -M5&`````:``:````````!H````````````````````2)$F@)D#0!&C1HQ,4P( -M9-&)B94_*/1/48I^BCS5/$]34\*>D]ZIJ?J:CQJ/4VJ-DU'J>29/*/(:C(VH -M]0\4;4:;4;4])Y)ZC0:!IIH;U(/4:-&AIZCU#1_\;'^SSLZO8M)4OYVHY%(M -M@P;/0&R\QZM9+_+Y4&`!6/Z;DW`[7MI2OQJI@6%*KO\*F((#A5)A`!V[@(,O -M3D177L@'QCR>C-IY]6(BQ\)PX*E&,$6UHB(1).MSQB4JY7O&=Y-RF;;?^KGF -MK*[T514?;G4^'.>[@7#\?JET#XP$,6^T]F=V]9#;FTQP<"V?,";,64W66TC: -M646^[=\'N&_K\QH;@]+&L0H^[RN3JE[\R(9-M,YN(U0!`A9F0``-X@8]N"E7 -MP/*WOB^GS.?T(HW6^_`[VW;Y=\<.1QGSEB[E3=VC7LK=(T(50]K:@.%D4*HT -M`N!JV*AA\U1TSYEV6G,GCP"M@8?TX3#'*9<`4"*FM4!$+,W9+-=IL]M@,,DM -MY#.E6%(/I,D,R7M8]M8A%K%$!IM)U=V?>X]R9LG,"?:8M$= -M(S/9]>J7VJKFWIMJL[T")M:;(K,QK"MJD3>L:]D;NX\DQ_SVZ"ZF-T^RE#5J -MH*G+RD'=]ZSC/D&^8WD*^D$&[W[>^QG67/!;1W0NCUN_8W^_L=K8N$0$IP,9 -MY>/N@!APF[5718"H"X4&)M=066.T=9!@=F&1%FG.Z6V7(_/-_ARW_T=CK*'7 -M@NPH!#'111P1W4%481@F0!+92#>"MM@J39O:8:?/3]';:=]4$RT`X^,B-)KZ -M_@7>G]FHYDQW'I-=:ZZ.B="E^F<^WK^]/]+Y=U.@=D['UUY<>F84OD3`]GWD -M(=$[0P0=-5('XU**^>59+\(_^=-+L-;7@0>1>SX' -M+@-;KG)Y4JJ7:LN3[3")GHD-]AV_U%DFQ@HZT-.@L,,QBSATLR -MR:.+:)]2G"Y9JDK-/46L!5Y+\6DK.%#N$/9YAO^@Y/N*B7N6*Q=@*K6-V<-G -M3/([W5$D*E\EBT7,=K=XHB[?T5J`#SFZ>M*"#=QIC9\Y"++&!5F!'$=\8*:, -MKZ>0J5#YE#Q&0.E3U;#E];3F,\Q][?KD/5,[].R9RD.D>U@(0F#*4W:4>V0I -MR`E5%GZY:+8.U"=1$,F0=!;*W4TX^*)";.VWE3/Q!Y#CE"B/=-2L*UV+VN%] -M,6:\6N*AKNJ":E"D%U1U+UEX(AV#D)K:O.L!ZC&5`.3*5W0J`D:W;<3J]&\I -ME`:6S`AF*8D!`(%0,79DV_:+#:R'VEZ.-BFZ52&\9/B?N&2XKYCYFH7@R&P9 -MG&]?J-G?%!U7J3)2N;$CRU0*,UW7*1%;>< -M9C7[PI5$3/IF#[_$VU%(X@TD'Q#IPP]ZJ"LC$R-IK^PZ#9JK;G3U9[XUQGLL#>S9.IEO.Q<2!ASL0:T@3+6A;UT9A!=< -M&&B=#$E1Q[?CE848 -MBB&^T4571ZNW!E"HHQ!VC>3R:5S,B#!FXDVWE.V^E\OLZ:5\IKJZZ7$>3G?`!JJJ -MI"8R6=2ZN#+=K!YK)C'-T.[ZF%KV+-S(1P-H`$-"!I"S7P]CVU^J&8$14#HF -MHRRPGTNN<@YM0U:DK!88<8LJ89!:EK"!V:$F)&0@>98$ZA"&\R`.4F9GT^6MT/:5):H.B%L9!1D],@V8]1ENR2V_9.:4,L/3_Q+UAJ]U^?Y2F!2T*LVFM1J7+$^W[BSFO.Z?E8(=O;/!BJP.0UAR -M$F^^^,ZQBP'.A$A@EF"+-,$"6<'%[WT,V&;E4*U5^=FS+%P38\@/=4(8O/"* -M$L&UUE1L?=LV_-WJ6N(WP:Z%]N8YVR\JACE43(6K/(V30?N9OCS@=8S#[YX$ -M^Y))7"*4U1I$IC<'(Y&LL"IN?).\1*SSRN84!@LUK19![EW&(DP38@W+!7J: -M2-)D@=AWUDF&!)JP@?]I"L""BPBD%D4G/I#C*D`T0A,L##)(6V@K6+,8DM=! -M`(FQ(FP2ML0VA6@]Y"2.&U2,`*[$"-ZTD"ZYBF-?)*L(X_'Z>5%/G$2$K;2$ -MK#`2MR@6`T$-+LFDA$V@H!JP#NR0=7HY.-!FL0Z7EA``1#\_AT=1\_V>KJM' -M:^M.?_4?;;["^;59HSCKS[N=;Q=7QV=J<\8+.&"'1IS][G?*N25!/U2`)H#W -M_48#@,EZ)``=64(I$'KLK@4"1-L)9%CT<#?>!\K\7J?7J$OR7Y$^C_-U'H(\ -M2,HS4(F83+$'[LZU7\U8@>5,]'%A,T%5=^2:-[YK0[0QJ[(0Z=Z`VDXAUI]T -M3V%SK9[8QG!U.ZP^WE:+@^'1P=7A]!,C`=^R"*@=PX:M]&>.<8 -MM_)BANJE!`O@_0=0>C"1`KLAR*?O7!`A,9S:I>*=R4)X<"3]1=:-$=%$!OAN -M,L'@5O=N,%-F>=IM_5_1.8[C]C,^5]5[\GK>S>]+XO_ -M/=K94ILRG#+$,@B($R.P5D[_MI32?X?G9:5F^RWIP/'>)6>Q]#OL7?&O\AQN -M-Z4?P,,2,IH;><6!$!;&0`S9@"G-Z8X6;0B&9JD(AE#O6>Y)Z[MO%Q-R;HP[ -MOD[L#^C5Q=`].T!!2*X`#K*,+KD'UX@?GL(>SOY.J[/<7[?-,@N95M;BL^MR -M/D_?4N_7_3Q_S;\Y;,.LVO?6%UN/Q_9<_G^,S<^')D0$Z8!>,=$8+F#5H0JN -MR0"M,6ER;.P_'(H6T8<=J3-GG"4+&;.8Q?T=U,-)J@B&S:D`9&9&9TE+Q.MZ -M\$$SJ_HY5[Q)>,YENV`()`CB)]477G51?N[M,?_#L%@BLQ95%5V([,]#Z33& -MG@79DM+EHBL68I<%J5*M+1M%GD9N-JX-,R;F/-D!K*0`@2#ZW:=CZ7`_K**;R\FYSG5P!^-((@N"""""2.%5P?#@@@@8TF12U;ZY8H -MHHHKMWM[>WQC9P;V]]9G744444455555%555555555556[N[N[O$ -MXFUQ>/?);U]UUSG.=(TH:#$8A%%#Y(8,P1F0%:D02J4$>$\,."C8I3"P`%G"*JC/A$Q2/OD8,/A`%A\RF(S'*4"(?$#`)US<`>QY2$A<9@B(AV7&SM>LX" -M_0S?*D:*0H/0T>6QG_[Y>_Y7H?H]+\_;['#O_N9`:;!%UAR)0E0T$Y)P#:_T -MB&Q8D%WY%;KJ@`0U8K^:T50>,_?[:Q]?R//\R[W%8[MKLQH*W:_B8_I@?<;N -MD[V_\(W/TKGU:5AZ$1C.$#!M#9O1E9!5!2'&:D%).!G7>?^T]9/$@;Z:"AS[]V_8]&=3L[;:!!D4`6)%+/.J0D2JP(H8AII(1TN%TR1 -MOV@^G0%[/68&13S#9MQA\^RQD?=,."3R&'-X]`W&;$`H0T'S6@2+16:A!0!Q -M(*OG2JS]R!YE[*L@2&B2!V;`J2'-8`?M))UR0F4/D$GEE1$YC#GDFUS]#8G` -M\>#)#BP0PIF%)5$#[:ETS6`O$+7/0-D[]"6,G4671!U#%Q`J!NVK/%22OK;7 -MAQMM8Q@)\#!&74F(,:[K\X9V2&.UQURS -MP%[50)U!E,J@42['7CN*V6PE$%C)()@!`ZN%B8EOD@"H&^/3#4$`U%%*0X60 -MA^7L[>P%+/*V\'IZ\C=='N[-J*(;]A%MZ[-8M(CZ+VSVME?KY65")%(95N**[GR)5BYSO)*@=` -M`744(;;`==SZ)I.K8%#772*B_3/I+]\\,&-#*5H%U!/^!\)I+3W7GNZOY;/P -M1#)"*@)!Y6=9>SC+Z_RY6?(IE^YT7(E4W74%],*H^5IPO1AJ,./%TSL1F9:] -M0%#T5NE(YUP"SVZ`J9%VU@-"8`?@<.,&#$O-+"!C,C*9(L,/3R;6V%+IG11D].4$[0F;I9FAH&EI:):G -M:%&AI0C.O4+3]'..LGN6@VK!M%5B122"4"`D"HBH66"Y?NU7;PC`!4:#)42> -M^Q(QVL90*,+F1D9*J82&DYF:C"I*'$!L88,?8]7M&>.;-4\XKJ$EV:B:A2UP -MF0>I!7*JWVUM1;03QE=,B0R"\=!U7/-OB?0.'UFNA'Y5)"2"=A@+`K`-#'<5 -M08C;1X%.?L.J0*EIZ]AP.,-0:_2-NK2L_!7,DF7'\8^JJH50J$!\4<1GBJ:* -M$>7DY/IP)YA`0D3*G,`P(B`B*\.XTK.=R,&QGS!X5%-WL(G"C$XFPNT`.9HV@:H?>$? -M#P>Y/8AU_)S#$L=;2,7@E2\G04AFJ'5@4/LS%Z&Q^I7S -MMP<9FV!8*$P%H:][S,UV\?Y8;I"^TV0]46OW->TK:/2A#:VM(F[0S-/W\7;4 -M8\)`6VP`'!Y5:?PL3W\E>\UYA0I`AT<@X[>.F0`[7` -M"Z\EDAN&\UM)!S'T>.KPYK%KD7#&24%&;OW!<7%LUWF3KLTMH/W'D%0F%,8T -M7@L:S*,MZQRDX`DM&5IKV$A&";7D.O(!X;`[EDMW]QL,9\%QA,MTS+0E2,,` -M*!II4-,TMK#`L04J!6$)G+*`N1(IEU&1"8IA1(B"P/&<)H4V,;2W#$5D97A1 -M(0M:SD#X7=;OVK[0&3E%BH*@!E]D20I;"(0QJ\6:?;6\^9-A,HJ"M-P+*,1* -M,K);Q'>XMIET"H*$TN9A&*8T.4(5"9-B,3V\8UX7A@6K_0.]<"*%D1$&7BX* -M!01!&6>V8Q,&F,&%84_IIA5PP0L-DF$,`V;`/@I'6V_/YGPXK<645Q)9O5Y4 -MG[U(ERCCHA_",5&`4ZP0'P?]4#XM[QM3,S!6+RBHE6T^(1BU&QM[ -MFKA8:^#V4(`X7P@,I8.X*_=3JUYD-\\41BI,D,HB]CDH`^V -M[@.GC5QKI=5^)Z77RLH1@Q..-!E\Y339?1Z[\+O=OV6"_L42B;IAWWO2]^?A4&HJ.`+D<,"(%L-G7BQ3"U/;V0W/9IHCT>(2O!PH0]@0'TXP#LEH"U;%&%'H( -M(-"V.]7CR["S!2GB=DB"-7$&0A=C"<\=GZ^H'%&4_/**V]7NU#D,HR=&FF4. -M/B)=0:>;U`&V8VD99EY8!(RY/9V+@_[\GW1X.7GZS#1;1>7F]`YQ;)#BEIR4 -M"B?(?6<1!ZBY>F'M"*^`$H$T'UF'=FF,_$+RZOLN^6+A=C*-Q+06>RST\_/4 -M-:L:\-JH92%(5<+6"][]DFFYN'[O!`03;R7(:2SF<'@P\<$N/MD?`!VS[3,4 -M0Z$\9^R$(-?J=W?!#GGZ`E:(-_&$"R9.T(+G*.O\914+RHZ@FBOQ0,S_@R,M -M647,GF>9#N8_`Q8MA*C+9]RBJEXG6T2O>1.&'$JS -ME]];2P+2D8\$`)K(8`LZDA:$$XM9'5M8T]OEZ*.8COO3FG"I[=.SD4+\G7C< -M%8SRZ!#,OF-.4%D5^LY:?0#T:I(,F^51!]C4D&.['7PWV'Y&@(.OXZ04]T+_ -ME-;:^V-]HH^'?0]CE@(A88GZ^%>"C@:AX"PF,Z0[0S6@$E+*+J/,/&FFIV.\ -MSH]WH(,J@J!5*'@;3B:$>LPQP>6V--WE!"@A -MWFZ+;._0!QZ!]"(`C`(HG]R%'@DVA@HO\;D_7GV$S -MP\#XKO,%MA8P2$7[V0#V0&5V[I+'BIQWU*#Q8VGY=!=_VY/^.MU#_!H>3QMW -M<''6^VDDY$&2("K$20&$C"+$8V-#2$QC:4BM2!=O[V0C$L&&_>W4HV_C<[N- -MNB!1P.@EM\9\"OD=;@7F$AX3`A@Q-&'"(:7>9F%G;,`9F/72HBLJJ[,C392! -MRD!B%4/B.(I`$.F@E)AN@@BO+!U-RA;H>DU0<#G^1B4!F,1L*>&!X -MP&XU1/*]M5"V+!"$N?JP4@6"S+N@&@ZJC<\3#>^211"9%@)QJDH:2ANCAL#` -MSR07=E=30S&:'+%(W8S$GK\<%Y$4YV=0MF8PBHYOEKK$(CB0,4B!OF39YUKJ+^@U+2RMMO[MT'9Z4/`:(!@RSX1<\65 -M`&L&7("A,C.KCF,@&XC0;OIA'1`LJ-FZ="[]:S>8:V3!$'3T0*%Q#H:D#,&9 -MF%*`IELZ(9P$'.';Y,-:\RE33>IN$;9LE\T+7H?+S`"A9SNU<%=-AP' -M(.XG)DU`U`4\OQS'1#4L6UP60CEX^IUUPWV\0SY,0NWB)2(16#XQ8VLL=0H;^55*!ZV7L;`\GBT-KZ!02=;4H&9;AQE9W>K"[#V`9"7 -MMB5;31@"8*M&X:Q3JY^JXJ$0!F1GC]LZ<#K=OV8G7Y?^HRB^0_A>$Y9QCS$% -MY9]2$>XSLYWDPBV6,U.?,S2%896('1=<'$`'GWZ2G?.:/+R'6>Z'4Y_!GJQ8 -M2+%NF3"(\P'@2?1Z&%1L*#0DXG%C*!!51J,@&(P)`32EL8#$A,80]W.J%,BO -M@J`#!$R/+3'1T01<BIEZ0PA.",&!3!`PLW32TV#1Z>RD":$2A-\ -M[I[8AJ#26"J0BP2[V[N5,L1-&M"IY161DNZ9&!Y^/6;A%*UFM`DQ!/&IFRPPG`#$0`OF`\! -M29AZ'(8;F6644%0^#GA(>/F?G+"9/@\/<%R3"`+WI0A%6ZY2I8C%*&B6(JPA -M`*A`R]>KS(V5J*+;===`Q`-I-80\"%D]`:BC,@9E%,-:H50$&1!`AF48@8LE -MG/H`RSNT%&!\^B[P&^<4,^!&8$!B%A6LNC0$V$Q<#(+QA=;&A&'%OYTYY4JP -MU(MIJ,X`7N94#A>JOUX90[$@K:`-%%U;Q(&WJ!R#Y?$36OZQD1@QVVP,>?4< -MZ9+NIJ*%(CE^Q^P6_J8T$@NC7UP!&2S.42.&A\>Q(`:D6`#!?R$`M%JIF,+Q -M<4BL64&C8ISRE8*D?X%>5:4P7Z=95J1@U(R;@T+;IC8`%WBUF=0""9!)WK#- -ML4`/UY8UQKL03UF%I"_HH&<"``X:5$$K1DA<>Z9@#-M&2!5.8'P5IK\>W(K5 -M/6]M8ZWL8X7QT)XEZ:]Q+GJ8N=O8[F='[<>(J.J-ND-#(F -M?;B2IP5;\GKO6IQ73DN&3O>S<"L[.)8ZW./D86S'DWKNY9Z:N/09D)>TAS.M -MUC/75X?8Y'1S%R%'RVTI23=W%AQ0$'MU^60IQAF\G'HU+R9MY_NLT&AGJ-9>UL7<^Q\; -M1"H3C7A?HB/#A3B>+PX.)RJIW.+RGA`P[TKR#:AJNXD`I8&0#(KS`L64[D`, -M<"[I/Q6F+`6"I:N:J;UQ8>A-%3SB6-D(E/2X=[`:6/-S%618_":0"H>T]M3F -M%]0`$',I"Y#ZSDTJY:=MZ]]*1@#&>/R8'N).J6F'L93:O7_ZK&- -M=+J4!M#C0^PZQ'R99OSM*&9["5 -M4>@&B+@&DV]W7`2+BS^9M07FBQB=,#K--J7"DML!=^5NOZ^3 -M[56L#AW^/R%P,!P^OZA=;M6D+9@0+A(@8ZL.L8."3ZI5&/UH -MN]T`Y*H9Q2NP[AAOS<0U62ZA\[IGYUQT^YJP<5/M?U;YR^$R$G&(`@I.MB1[ -M=LAKY6VV$\WCI=F<]]0[FVLZNUP-!9R3<3'H\XT*4YSIE!#A(;0HN> -M_4.ZZ1-J#KRC#=7JPY0!'R_9>9T1L,22;?PK9*;HB&6_\IT1V%K"$+G(TN6# -M"<63I]7J&UM6SQ[M;_N_89UG676GLJJCI[A&G.- -M#4Z;?X4SJL/"T3R)`HD;I@@ETUJ"Z7&)17"W>FU[H/*96E-PE-ZK)UV\-$MJ=CC<8XWQ85*P;3+%D)-5:BJ.B-I=MYM.NZ!C>P$*763;W2\@L!2L+*G#D -M#(:Q=!86Z,@+(66,@."8*YCLUUEE'SS'?F0>N@2&8=7"7*D(_[T7%C&)O/>TL\TAA(;/]+J]?S?.V[MO0W&-?CMOONXO`] -MGK&:H/^(./Z0%KY$WUN#KWXB#P!X%IT$3V/+1F#&M0T3]NH<$3\)D%XBP#25 -M).%R4*$]GGK?Z%:B)G'S#I?U_'G@3$_]\4W4XJNE@=WI_;OS[C7YX%?)I*]Y25BOU,0$T-=U"X(N`,5Y!C-([HK_93>($^W -M0`U4(?G<\P,>:?0I:V`I1"07V)12`K5>$A`IF=/PC_TA>I51B$V(HO -M)Z_.6;A1C/7.,;;CX#U^AM\SH6"[EI`P8Q40'B1IUXB[F89: -M,V`-D!86LU\%QBFB-C$?RHW"=N>B&6L*B.`[QI`4(TH449MO"B+)\QK8!V:D -MQ8IJ9.L^O(NWKQS-TWTM/@P'('1%.!@4=;PT@C$FP]9]GO[.4'59ES&[B);) -M)*$5U]OD^'ZKHLQ][%S%I$@/L\WDYGNIR.'!\R]689=2,*J5"`\S0O&JS5?S-N27!WSWK -MCC[,>>>>>>>>>>>>>>?N:;E%%%% -M%%%%%%%%%%%&FC>,<3?W_PN#@X,>4[?H.2N[`O3>5/+"BA/>&2J\R-^P;A`C -MB@#EFK7VYS"I1($^D,LQ[K,^]8J0JS_M]1JL(/:P$9>/);!(,F8721;ER=XT -M"KWF//M!<%C.^5D+)J!")#OD$.<7@)/;>KPS$;$?@-6Y^.=T&H,?XO4^%?6@ -M*`"1`1L"RVRK,QGC#PQR^#\'I+#!ID+'-(*=TA8^9RS&:CV"#,_2J;^W8J]W -M?I#/QG@<.8[UXK&9)HS'C%C.11TK93]74\J`@+N5_+7U'UW$R4!!GKUX#@;@ -MY@Y[$4T:O<2@61=(BM":CC==.2RTDB#Q'*AM%SU!UIBTI6Q4)7C!!F/>10)] -MO/:R-1:T//^%M[GH&>CTCE[?)&DW%!`6>8;\)B(]D#49%Y)\,!X0`'B&ILWP -M5L@.Z`;4/)[Z8\ZT_'V>_\^_=08,`@,RMLM5_71=2OR?V;R2!";>1*5Z]]BC -MW-ZS_WU^KW\8]`Z68P-S`J.ZU.AJA"AU-&IZ1S4B[FD38E!H$2&\W8-M<=H6 -MS:4E8B"!,NEM$'WCR)WN\W@IR&HY?W5VH6P6FD*JTC6V8$OSOU;Z>/'Q-4$! -MQ6VQMC:AY',,IN\9@@J(@\#=42AF9P$20X614HY>1U@$U^'>S09:M*`2]P%R -M(6#O'>HQBHS,X=P*X+HR(H@ATYD\2K@%YU_2%!0![FG_"`NW]6)5JEZ#%<"? -MWM[M+W$UU0=ZD@L]W%1`!Z\?=VR%\W6"OF4H*S2;$`Y_4JA`II"VS#TV"HF8 -M[)3G=FC:WM+.\!&Q]L')^1RJ#XX5P+AS<&Q?P&Y[*([%C&M1G13YG%1B=KY) -M(^)R==:W=>Y(++86V&J_##[$I.&TL(HMX#P2I]&B>01 -M"HL$6>HKMU#19MW`K83F,-B$_C=>9E\'C.]+@>!H>U27I+:565#\,L]P7-3W:%J -MCX79*+WX@UA)D"D`T(P9=(BQA8BB1T;$,1%Q);=:1S]Y(C^43L]`Y5TNMY)9 -M@94X_?CJ7D18X4_5VPM*>4@&D3-MR[B)!UE+=KX@A[GR>%X?\1BAQ%=7*,+C -MG_TL^K)Z.Q9B$!814(%$3TU()0-RFU_A#_)BO.<-I0-"Q]36=QFGSW#*P`5= -M"]G".N`69-_DGB\B@.`S`NZ')/XY&P@PZU1\LD'/6$#UDU(XS%JISDTI71:. -MM+0.NJ3&P!N#8->2,W,'-D57.=Y<2#??RDLR>3#J6=:_;.EC+SQBLHA:MV;( -MGS]:GADM1K538#```````````+/]999999999999999999^+G]'.KGG]7T1Z -MP]W9V/6ERC)6N)1730JFJI#8AR4A)R,G)S:S"RR[+-+JJNLL,[:V-G:6EI:W -M>XV66Y/VX&U]_%I:7,5L6GJ:G(QZ#$V2V]]SCD>[Q>$EW-*$-<].JJI)&-JV@'.G#\%_G" -M0]I\/D;A<*?<'!>H:%MP[2E2E,/#W:KU]Y(\LK&BE3UB5Q)2:ZT-8:Y@JML[ -M)R=)$DL,D4.ZUK(&2AQHB`S1N[)PS9.IYYM#>,['\=\E)W//,Q5#B>Q%R6*7 -M3T9QR<[/U5/M!!T+`6G@:7!OGY(6CL:F:]'AVHJ"2OJ.?#7(,BF^J6\B@:.H -M@I,U@LB:@GGC<)FFX3=0WC0AI<&$BJD9%$<5&!4U"2Y6>'89^LF++*L%I-HY -MR_)@"+.8+UHDZI-A52"0C@X-4Z?H/Z^)-14W$8JQ;TF)=LW)B0KM6QB"B$$( -M02CFH0%8)J2!H3WH)1J3FAPX0UR)8'Y1FBAB/*[5P@>31C9P=EC"'$3?5GZW)ICU'9=MM:12=9/C -M;T$`PR>`R#6RD8)G"6?*I5*E,BB)!8C75\_/SSQ/$D'1$62MH&:8O:6MOW6` -MNI+[&#QB?J^E;W6$E$4!&/&Z4K\,=AHY-%X5*)A#1G%E6]2+LF/",/KLA>\= -M%$Z&GQ?FM\-I-@`?#5?HTL%#7P^\>35T7UFEUA&3]V[: -M<&AJ0AT&^\7&C8CQ4]!F(/%#N#2"R0:C:NH]`NF;FK9\:,\!04T13YZPC-V'2J; -M@L1O0TXE-?5R_3\B&J.:D&4=Q0`_,%1H4MC'7?5$J&$&])$/70RW).K,$7BZ@="'EO[[G -M!E$??QFSUDW?71DWWC>BO>X]/`<$JCI,J(?H2)-?Z3+O,_;MG9VIRLN]0/+( -MWS<%5$X'15]53GA=AA@\O,UB7C(/)\]>2SQNUZ_7U/`Q5Z]-R[>7)5T]6NFS -M1>BU?@8M'LU[&5\*IRH-$4ZI?*HSVW[+>%/_=T_!"N;S>3Z;Z7=]/\SV -M_X4/1%4N[2'V#MNJ*_,X%%79$@CQ+/DX()"0Q,*0F_8%EP_&K68A,%(V#I/M<@0C!,D7W3&+Y^^"PSFCA/&T.>Y6=1S'X=PW9W6/IS4L2!#0OO -MY\3^=]4Z#Z'ON:W&@/#!OGP,QT/`JOPI[+F\+H:J/[-W&D^'&N7J*"WDD'2< -MWR?%84?_B[DBG"A(+G#(3P`!!`8``0FP2``'"P$``@,$`@($`P,!`P$`#,#` -M:L#`:@`("@$]?9*5```%`1$/`'@`.``V`&4`>`!E````%`H!```M0RMQLYT! -*%08!`"$````````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj_copy.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj_copy.7z.uu deleted file mode 100644 index 3883ab74b..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj_copy.7z.uu +++ /dev/null @@ -1,613 +0,0 @@ -begin 644 test_read_format_7zip_bcj_copy.7z -M-WJ\KR<<``/3^:6)P&H```````!2`````````&3-#_Q_14Q&`0$!"0`````` -M`````@`#``$```!PE`0(-````+!F````````-``@``<`*``:`!D`!@```#0` -M```T@`0(-(`$".````#@````!0````0````#````%`$``!2!!`@4@00(%0`` -M`!4````$`````0````$``````````(`$"`"`!`@T70``-%T```4`````$``` -M`0````!@````X`0(`.`$")@"``!,!```!@`````0```"````B&```(C@!`B( -MX`0(V````-@````&````!`````0````L`0``+($$""R!!`@8````&`````0` -M```$````4.5T9!A=```8W00(&-T$"!P````<````!`````0````O;&EB97AE -M8R]L9"UE;&8N@(``!(```"]`@```````,\!```2 -M````?`(```````#.````$@```(8"````````0P```!(```!:`0```````&<& -M```2````>`$````````J````$@```&X"````````/@```!(````:`P``F.($ -M"``````0`/'_80$```````!5````$@```#,```!TX00(`````!$`\?\M`P`` -M3.0$"``````0`/'_BP(```````!B`P``$@```"L!``#4X@0(!````!$`%P`/ -M`0```````)L(```2````Y`$``-CB!`@$````$0`7`%,!`````````````!(` -M``"%`0```````!H````2````A`(````````K````$@```+0"````````*0`` -M`!(````4`0`````````````2````Y0(```````"+````$@```*$````````` -M8````!(```!)```````````````@````&P$```````!]````$@```$(!```` -M`````````!(```"!`````````!0!```2`````&QI8G5T:6PN7!E`'-T'0`@<` -M``(`.P,```````"@X@0(!18``,#B!`@%)0``Q.($"`4K``#(X@0(!34``,SB -M!`@%/```T.($"`4^``#4X@0(!4L``-CB!`@%30``@.$$"`.$$"/\E?.$$"`````#_)8#A -M!`AH`````.GX#P``_R6$X00(:`@```#I^`\``/\EB.$$"&@0````Z?@/``#_ -M)8SA!`AH&````.GX#P``_R60X00(:"````#I^`\``/\EE.$$"&@H````Z?@/ -M``#_)9CA!`AH,````.GX#P``_R6````.GX#P``_R7`X00(:(````#I^`\``/\E -MQ.$$"&B(````Z?@/``#_)#A!`AHP````.GX#P``_R7DX00(:,@` -M``#I^`\``/\EZ.$$"&C0````Z?@/``#_)>SA!`AHV````.GX#P``_R7PX00( -M:.````#I^`\``/\E].$$"&CH````Z?@/``#_)?CA!`AH\````.GX#P``_R7\ -MX00(:/@```#I^`\``/\E`.($"&@``0``Z?@/``#_)03B!`AH"`$``.GX#P`` -M_R4(X@0(:!`!``#I^`\``/\E#.($"&@8`0``Z?@/``#_)1#B!`AH(`$``.GX -M#P``_R44X@0(:"@!``#I^`\``/\E&.($"&@P`0``Z?@/``#_)1SB!`AH.`$` -M`.GX#P``_R4@X@0(:$`!``#I^`\``/\E).($"&A(`0``Z?@/``#_)2CB!`AH -M4`$``.GX#P``_R4LX@0(:%@!``#I^`\``/\E,.($"&A@`0``Z?@/``#_)33B -M!`AH:`$``.GX#P``_R4XX@0(:'`!``#I^`\``/\E/.($"&AX`0``Z?@/``#_ -M)4#B!`AH@`$``.GX#P``_R5$X@0(:(@!``#I^`\``/\E2.($"&B0`0``Z?@/ -M``#_)4SB!`AHF`$``.GX#P``_R50X@0(:*`!``#I^`\``/\E5.($"&BH`0`` -MZ?@/``#_)5CB!`AHL`$``.GX#P``_R5.($"&CP`0``Z?@/``#_)7SB!`AH^`$``.GX#P``_R6`X@0(:``"``#I^`\` -M`/\EA.($"&@(`@``Z?@/``#_)8CB!`AH$`(``.GX#P``_R6,X@0(:!@"``#I -M^`\``/\ED.($"&@@`@``Z?@/``#_)93B!`AH*`(``.GX#P`````````````Q -M[56)Y8/D\(U%"(/L!%#_=012Z)`4``#,D)"0D)"0D%6)Y5=64X/L#(MU#(M= -M$(7VC7RS!(D]Y.,$"'XUBP.%P'0OHP#@!`@/MA"$TG0C@\`!ZPH/MA"#P`&$ -MTG04@/HO=?&C`.`$"`^V$(/``832=>RXB.`$"(7`=#2+10B)!"3HZ!,``,<$ -M)'S8!`CHZ!,``.CD#P``B7PD"(E<)`2)-"3HH"@``(D$).A8$P``Z(@1``#K -MT)"0D)"0D)"0D)!5B>6#[`B`/=SB!`@`=`SK'(/`!*,(X`0(_]*A".`$"(L0 -MA=)UZ\8%W.($"`')PY!5B>6#[`BA<.$$"(7`=!*X`````(7`=`G'!"1PX00( -M_]#)PY"0D)"0D)"0D)"0D)!5B>6#[`R)'"2)="0$B7PD"(MU#(M]"(M&3(M8 -M-(M(,(M'3(M0-(M`,#G3?12X_____XL<)(MT)`2+?"0(B>Q=PWX-N`$```#K -MZ&O,`````#G!=^\YTWX?BT90B44,BT=0B44(BQPDBW0D!(M\)`B)[%WI^!$` -M`'RT.<%SVXUV`.NKC;0F`````(V\)P````!5B>6+50R+10B)50B)10Q=Z9`5 -M``"-="8`C;PG`````%6)Y8/L"(D<)(ET)`2+=0B+70R+5DR+2TR+0B@Y02A^ -M$+@!````BQPDBW0D!(GL7<-\#XM"+#E!+'_FD(UT)@!]![C_____Z]V+0U") -M10R+1E")10B+'"2+="0$B>Q=Z?@1``"-M@````"-OP````!5B>6+50R+10B) -M50B)10Q=Z4`6``"-="8`C;PG`````%6)Y8/L"(D<)(ET)`2+=0B+70R+5DR+ -M2TR+0E`Y05!^$+@!````BQPDBW0D!(GL7<-\#XM"5#E!5'_FD(UT)@!]![C_ -M____Z]V+0U")10R+1E")10B+'"2+="0$B>Q=Z?@1``"-M@````"-OP````!5 -MB>6+50R+10B)50B)10Q=Z=`6``"-="8`C;PG`````%6)Y8/L"(D<)(ET)`2+ -M=0B+70R+5DR+2TR+0A@Y01A^$+@!````BQPDBW0D!(GL7<-\#XM"'#E!''_F -MD(UT)@!]![C_____Z]V+0U")10R+1E")10B+'"2+="0$B>Q=Z?@1``"-M@`` -M``"-OP````!5B>6+50R+10B)50B)10Q=Z6`7``"-="8`C;PG`````%6)Y8/L -M"(D<)(ET)`2+=0B+70R+5DR+2TR+0B`Y02!^$+@!````BQPDBW0D!(GL7<-\ -M#XM")#E!)'_FD(UT)@!]![C_____Z]V+0U")10R+1E")10B+'"2+="0$B>Q= -MZ?@1``"-M@````"-OP````!5B>6+50R+10B)50B)10Q=Z?`7``"-="8`C;PG -M`````%6)Y8M%"(M5#(M`4(E%#(M"4(E%"%WI^!$``)"-="8`58GEBT4,BT!0 -MB44,BT4(BT!0B44(7>GX$0``D)"0D)!5B>6#[`B)'"2)="0$BT4(BTT,BP"+ -M4$"#^@=TSB!`B% -M]G4:@^H!O@$```!T0H/I%]?_____=#B-M@````")70R)10B+#>3B!`B+'"2+ -M="0$B>Q=_^&)70R)10B+'"2+="0$B>Q=Z:`8``"-=@`Q]HGPBQPDBW0D!(GL -M7<.058GE5U93@>PL!0``B848^___H:#B!`B)1>PQP*%`Y`0(B944^___B8T0 -M^___QX64^___`````(7`=0VA1.0$"(7`#X2%B/O__P````#'A8S[__\`````QX6@^___`````,>%G/O__P`` -M``#'A9C[__\`````A<")P\>%J/O__P````#'A:S[__\`````QX6P^___```` -M`,>%M/O__P````#'A:3[__\`````=`F`.``/A2H'``"+O13[__^%_P^$O@8` -M`(N%$/O__XN]%/O__\>%+/O__P````#'A3#[__\`````@^`"QX4\^___```` -M`,>%3/O__P````")A0S[___I7AT``(/X"@^$X`(``(NU&/O__X7V#X39`P`` -MBT=0@#@N#X2L`P``BT%E/O__P````"%P`^%,@,``(NU./O__XN--/O__P'>C40Q&`'0B00D -MZ&@3``"%P(G##X03"0``BY5$^___C4`0B0.)!"2)5"0$Z"@4``"+C3C[__^+ -ME4C[__^-1!D1B4,$B50D!(D$).@H%```BXTH^___#[=!""4`\```/0`@```/ -MA.!$``(E$)`B+1U#'!"3PV`0(B40D!.@H$@``QT<,`0```,=' -M$`````"+?PC'!2#C!`@!````A?]ULXN5//O__X72#X1B`P``BX44^___BY4\ -M^___B858^___BX6L^___B95@^___B85D^___BX5`^___A<`/A#B!`BA1.0$",<%).,$"`$```"%P'0EB[T4^___A?]T&XN=%/O_ -M_XUV`(M#%(D$).BX$P``BUL(A=MU[HM5[#,5H.($"`^%LP<``('$+`4``%M> -M7UW#C70F`(L-\.($"(7)#X5&_/__QT<,`0```,='$`````#I5QT``(/H`0^% -M*OS__XL=[.($"(7;#X4<_/__Z]2+E2C[___'1"0$`````(M"#(D$).B8$@`` -MBXTH^___QT0D!`````")A43[__^+01")!"3H6!$``(F%2/O__^D`'```@[TP -M^___#@^'%_[__XN5*/O__XM"%##D/0`!``"A/.0$"!G)@^'Y@\$/A<")C3#[ -M__\/A/G]__^+E4S[__^-1#,2B4,(B00DB50D!.@H%```BXU,^___B0PDZ+@3 -M``#I_AP``(N-*/O__XM!1(D$).@($```A<")A4S[__\/A)`&``"`.`!U(HD$ -M).BX$P``QP0D^M@$".C8$```A<")A4S[__\/A&D&``"+A4S[__^)!"3H&!0` -M`#N%H/O__XF%-/O__P^&P/S__XF%H/O__^E7'```C960^___B10DZ!@1``"# -MP`$/A/D$``"+1SR%P`^%!0$``(M'4(VUN?O__\=$)`CTV`0(QT0D!`$$``") -M-"2)1"0,Z*@2``"+A0S[__^%P'1SBX60^___B30DB40D!.AX$P``@\`!='.- -MA93[__^)1"0$BX60^___B00DZ"@1``"#P`%T5HN%D/O__XD$).C($0``BX64 -M^___AD?``#'A2S[__\`````QX4\^___`````,>%,/O__P`` -M``"A1.0$"(7`=0VA^.,$"(7`#X0!_?__BX48^___A<`/A7K\___I,AX``#'` -M@SWXXP0(``^5P(F%0/O__^FR&0``B00DZ!@4``"-1``"B00DZ&@3``"%P(F% -M'/O__P^$+`0```^V`SPZ#X0_!```BXT<^___B`&+C1S[__^+A1S[__^#P0'& -M0`$`#[9#`83`=#V)VNL4B`&#P0'&00$`#[9"`H/"`83`="6`.CIUYSPZ=>/& -M`3`/MD(!B$$!@\$"QD$!``^V0@*#P@&$P'7;@'G_.@^$RP,``(V%I/O__XN5 -M'/O__XE$)"B-A:S[__^)1"0DC86(^___B40D((V%H/O__XE$)!R-A9S[__^) -M1"08C868^___B40D%(V%J/O__XE$)!"-A;3[__^)1"0,C86P^___B40D",=$ -M)`24V00(B10DZ$@2``#'!1CD!`@!````@_@(#X9?`@``B[6P^___,<"%]G0@ -MN0$```"X"@```/?A@^X!B<%U\L>%L/O__P````"-0/^+O;3[__^)A;#[__\Q -MP(7_?C6)_KD!````,=MKTPJX"@```(F5!/O___?AB=.)P0.=!/O__X/N`77A -MQX6T^___`````(U`_XNUJ/O__XF%M/O__S'`A?9T(+D!````N`H```#WX8/N -M`8G!=?+'A:C[__\`````C4#_BXV,^___BY6(^___B86H^___@_D`B94@^___ -MB8TD^___#X[9`0``BXT@^___O@$````Q_XN=)/O__VO'"HF%!/O__[@*```` -M]^:)UXG&`[T$^___@\'_@]/_B=H)RG7:B?")^H/`_\>%B/O__P````"#TO_' -MA8S[__\`````BXT<^___B86(^___B96,^___B0PDZ+@3``#I,1H``(N-+/O_ -M_XU=NHN%M/O__\=$)`@%@/O__P4```"+A3#[__\[A8#[__]V!HF% -M@/O__XN%F/O__XF%A/O__^GK'0``BT=0B40D"(M'!(M`',<$)`C9!`B)1"0$ -MZ+@2``#I-2```/\DA?#9!`B+E8S[__^+A8C[___'1"0((-D$",=$)`08```` -MB50D$(E$)`R)'"3HJ!(``(D<).@8%```B86`^___Z8TD``!\"H/Z`)`/AQO^ -M__\QP#'2Z9@C``#'A;#[__\`````QX6T^___`````,>%J/O__P````#'A9C[ -M__\`````QX6<^___`````,>%H/O__P````#'A8C[__\`````QX6,^___```` -M`,>%K/O__P````"#/1SD!`@!QX6D^___`````!G`]]`A!1CD!`CI=2(``,=$ -M)`3IV`0(QP0D`0```.B($P``9LR)3>@9P"7`F`0(B40D"(E,)`2)%"3H*!,``(7`B<7UW#D(/X!'0)@_@'#X7R_O__BT,@B00DZ'@1``") -M1"0(BT,P!#XXN____BT,575E-1@>PX!@``BQFAH.($"(E%[#'`C87L_?__BWD$B87D^?__QT0D -M!,S;!`C'!"0`````Z*@3``#'!"0!````Z)@3``"%P`^$D0```,<%#.`$"%`` -M``#'!"15V00(Z(@0``"%P'0)@#@`#X43"```C87<^?__B40D",=$)`1H=`A` -MQP0D`0```.A($0``@\`!=!0/MX7>^?__9H7`=`@/M\"C#.`$",<%#.0$"`$` -M``"^$````,=$)`C(V00(B7PD!(D<).@($@``@_C_=#^#Z#&#^$=V,.BP20`` -MZ]C'!0SC!`@!````QP0D5=D$".B($```ASY__^)!"3HR!(``(/H`0^$6P8``(L5'.0$"(72=$;'!1CD!`@!````QT0D -M!&"R!`C'!"0"````Z-@2``#'1"0$8+($",<$)`,```#HV!(``,<$)(G9!`CH -MB!```(D$).C0,@``H4#D!`B%P'5!H43D!`B%P'4XH?CC!`B%P'4OH13C!`B% -MP'4FH1CC!`B%P'4=H3#D!`B%P'44BQT3B -M!`@@E@0(A#B!`C`P00(AA%.,$"(7`#X52!```H1CC!`B%P`^$P`0``,<% -MY.($")"5!`BA#.,$"(7`=)_'!>#B!`BPO`0(BX7,^?__ACY___'1"0$$.0$"(D$).@X$P``BQ40Y`0(B=#!^!_!Z!SC!`@`````Z6,I -M``"AQ.($"*/TXP0(Z6,I``#'!0SC!`@`````QP5$Y`0(`````,<%-.0$"``` -M``#I8RD``,<%&.,$"`$```#'!13C!`@`````Z6,I``#'!03C!`@!````Z6,I -M``"#YOR#SA#'!?CB!`@!````Z6,I``"#YN^#S@+'!?CB!`@`````Z6,I``#' -M!?3B!`@!````Z6,I``"#S@''!?CB!`@`````Z6,I``#'1"0(`0```,=$)`3, -MVP0(QP0D7=D$".@($P``Z6,I``#'!3#D!`@!````QP44Y`0(`````.EC*0`` -MQP4,XP0(`0```,<%1.0$"`````#'!1#C!`@`````Z6,I``#'!33D!`@!```` -MQP5$Y`0(`````,<%#.,$"`````#I8RD``,<%#.0$"`````#'!23D!`@````` -MQP7LXP0(`````.EC*0``QP4$Y`0(`0```,<%Z,0R"`````#'!3CD!`@````` -MZ6,I``#'!13C!`@!````QP48XP0(`````.EC*0``QP7XXP0(`0```.EC*0`` -MQP4(XP0(`0```.EC*0``QP4,Y`0(`0```,<%).0$"`````#'!>SC!`@````` -MZ6,I``#'!13D!`@!````QP4PY`0(`0```.EC*0``QP4\Y`0(`0```.EC*0`` -MQP4`XP0(`0```.EC*0``QP40XP0(`0```,<%#.,$"`````#'!43D!`@````` -MZ6,I``#'!43D!`@!````QP4,XP0(`````,<%$.,$"`````#I8RD``,<%_.,$ -M"`````#'!>CB!`@!````Z6,I``#'!4#D!`@!````Z6,I``#'!?SC!`@!```` -MZ6,I``#'!?SB!`@!````Z6,I``#'!>SB!`@!````QP4$XP0(`````.EC*0`` -MQP7HXP0(`0```,<%!.0$"`````#'!3CD!`@`````Z6,I``#'!0SD!`@````` -MQP4DY`0(`````,<%[.,$"`$```#I8RD``,<%".0$"`$```#I8RD``,<%'.,$ -M"`$```#I8RD``,<%..0$"`$```#'!03D!`@`````QP7HBS0(`````.EC*0`` -MQP4@Y`0(`0```.EC*0``Z,@3``"%P`^%#_K__Z'TX@0(A<`/A0+Z___'!?#B -M!`@!````Z=LI``"+'1CC!`B%VP^%K?O__XL-!.0$"(7)#X1I`0``QP7DX@0( -M8)<$".FM*P``H1CC!`B%P`^%(OO__Z$$Y`0(A<`/A!\!``#'!>3B!`C0EP0( -MZ:TK``"A$.,$"(7`="W'!>#B!`B`P`0(Z<`K``#'!>3B!`B`F`0(Z:TK``#' -M!>3B!`B@F`0(Z:TK``#'!>#B!`A`O00(Z<`K``"-G>3Y__^)7"0$QP0D>MD$ -M".A8%```B5PD!,<$)'W9!`BC\.,$".A8%```B5PD!,<$)(#9!`BC+.0$".A8 -M%```B5PD!,<$)(/9!`BC2.0$".A8%```B5PD!,<$)(;9!`BC*.0$".A8%``` -MA<"C`.0$"`^$TP```*'PXP0(A<`/A"'Y__^+'2SD!`B%VP^$$_G__XL-`.0$ -M"(7)#X0%^?__QP43B!`A`E@0(Z:TK``#'!>3B!`C0E@0(Z:TK``#' -M!>3B!`A`EP0(Z:TK``#'!>3B!`A@F`0(Z:TK``#'!>3B!`CPEP0(Z:TK``") -M7"0$QP0D[=@$".A8%```HP#D!`CI^#```)"0D)"0D)"0D)"058GE@^P8A6#["B+10C'1"0( -M`0```,<$)`$```"(1?^-1?^)1"0$Z&@0```QP,G#D(UT)@!5B>575E.#["R+ -M10B%P`^$0`$``(M%"#'_B00DZ!@4``"+%6#`/ -MM@*(1?(/MD(!B$7SC01_,?:-'(5@XP0(#[94+O*-0M`\!W:+C4*?/`=W)`^^ -MPH/H88D#ZY.+50@/M@1ZB$7R#[9$>@&(1?/KPXVV`````(U"OSP'=RL/OL*# -MZ$&)`XM%W,>`:.,$"`$```#I*3,``,<$).S;!`CH*!(``.DC,P``#[;*.PW( -MX@0(?0RAT.($"(N,B#0$``"#^7AT$P^^PHE$)`3'!"0TW`0(Z"@2``#'`___ -M___I*3,``(/$+%M>7UW#QT4(S-L$".GD,@``58GE5E.)PXTT0(/L$(L4M6CC -M!`B%T@^%E````(L$M6#C!`B#^/]T.(E$)`BA\.,$",=$)`0`````B00DZ+@0 -M``"%P'0;QT0D"`"X!`C'1"0$`0```(D$).@X$@``C78`C01;BP2%9.,$"(/X -M_W0UB40D"*$LY`0(QT0D!`````")!"3HN!```(7`=!C'1"0(`+@$",=$)`0! -M````B00DZ#@2``"#Q!!;7EW#D(UT)@"A*.0$",=$)`@`N`0(QT0D!`$```") -M!"3H.!(``.E,-```C;0F`````(V\)P`````/M\")PE6!X@#P``")Y8/L"('Z -M`$````^$Q@```'Y1@?H`H```#X1]````@?H`P```=&*!^@!@```/A'P````Q -MTJA)=%_VQ`@/A>(```#VQ`0/A+<```"X"````(UT)@#H,#0``+H!````ZSB- -M="8`@?H`$```=%B!^@`@``")]G6]N`8```#H,#0``+H!````R8G0P[@"```` -MZ#`T``"Z`0```,F)T,.X`0```.@P-```N@$```#)B=##N`4```#H,#0``+H! -M````R8G0PXGVN`,```#H,#0``+H!````R8G0PZ@"=#CVQ`)T$;@)````Z#`T -M``"Z`0```.NGN`H```#H,#0``+H!````ZY:X!````.@P-```N@$```#KA3'` -MZ#`T``"Z`0```.FT-0``N`<```#H,#0``+H!````D.FT-0``C70F`(V\)P`` -M``!5B>53@^QTB468H:#B!`B)1?@QP*$LX`0(A<`/B,0```"A1.,$"(7`=':+ -M'?3C!`B%VP^$B````(U%F(D$).BX$0``B5PD"(U=J,=$)`10````B1PDB40D -M#.AH$0``H?___Y"A(.0$"(7`=#NA+.`$"+LTVP0(A<`/A5W___^[0-L$ -M".F8-@``QP0D.0```.CX$@``@#AD#Y3`#[;`HRS@!`CI@38``(M-F(L51.,$ -M"(V!`/'O`#G0?B:-@@#Q[P`YP7TVP0(AC^__^[:-L$".F8-@``Z-@3``"0BQ4DY`0( -M58GEBT4(A=)U"HL-[.,$"(7)=`F)10A=Z1!1``"+%0SD!`B%TG0)B44(7>D@ -M2P``B44(7>F`3@``D%6)Y8/L"*'`X@0(BTT(A"*+`H@(@\`!B0+),<##H````H?CC!`B%P'5RH1SD!`B%P'1)#[=&".@0-0``B<>+0U")!"3HP#<` -M`(M-[(T<"*$Q=PXM#4(D$).C`-P``BU7LC1P0Z\F%_W3%,<#H\#$``.N\H1#D!`B# -MZ`&)1>")PHM&.,'Z'P%%X*$0Y`0(B57DBU8\$57DBTWDB<+!^A^)5"0,BU7@ -MB4PD!(E$)`B)%"3HP%8``(E\)`3'!"1XVP0(B40D"(E4)`SHB!(```%%[.FS -M.P``BT8$B50D!,<$)'+;!`B)1"0(Z(@2``")1>SIJCL``(GVC;PG`````%6) -MY593@^P0BW4(BQZ%VW4FZV&+%*A0.0$"(M-T(7`BU$,=`B+02"#P`$!PHL-^.,$ -M"(7)=`N+7="+0Q"#P`$!PH,],.0$"`&+1>B#VO\#5>CWV(E%U"'"B57PBT7P -MBQ4,X`0(`<`YT`^/+0(``(G0P?H?]WWPBU7"+`H7`#X3"`0``BT`\A<`/A;"%]@^.>P$``,=%V`````#' -M1>0`````BQTTY`0(A=MU!HM5Y(E5V(M-S(7)#XX<`0``BWWP,?;'1>P!```` -MBUW0H4#C!`B+4R"+2Q"+7=B+!)CH@#L``(L5-.0$"(72#X37````@\,!BTW< -MB5W8.4W8#XW7````BU7H`<:-'!8C7=0Y^W]>C70F`(L--.0$"(7)=`R+1P/C:X```"+%<#B!`B%TG50BPW,X@0(@ST8Y`0(`8M!"!G2@^+I@\(@@^@! -MA<")00AX4XL!B=Z($(/``8D!BU7HC1P6(UW4.?M^IHM-S#E-['1B@T7L`0-] -M\.ET/@``B?:#/1CD!`@!B=Z+%`!5=B+3=PY3=@/C"G_ -M__^AP.($"(7`=36+%`Y7>0/A9/^__^#Q#Q;7E]=PZ',X@0(QP0D"@```(E$)`3HR!```.O1B50D -M!,<$)`H```#H2!,``.N_BSU$Y`0(A?]U"(7)#X0W_O__BTW0BQT0Y`0(BU$$ -MQP0D?ML$"(/J`8T,&C'2BFP/```P>`"B40D!*%`XP0(B00DZ)@1``"%P(G"=!:+3=")%4#C!`B+00BC -M'.`$".EP/0``QP0D`````.BX$@``BUW0B5T(Z[!5B>575E.#[`R+=0B+'H7; -M#X2^````,?_K'(VV`````,<$)(G;!`B#QP+HB!(``(M;"(7;='2+0PR#\`$+ -M0Q!T[HM#4(D$).@8%```@WL(`1G2]]*#X@*-!`+0PB%P`^%=O___X7_=":AP.($"(7`=3Z+%7UW#H7UW#B50D!#'_QP0D"@`` -M`.A($P``Z1!!``")5"0$QP0D"@```.A($P``ZYF0C70F`%6)Y5=64X'L?`@` -M`(M%"(L5H.($"(E5\#'2BS")A:3W__^%]@^$,@,``(M&/(7`#X4G`P``QX6H -M]___`````)"+1@R#\`$+1A`/A.@"``"+'4#D!`B+?DR%VP^%B`0``(L-^.,$ -M"(7)#X4G!```C4W,B4PD!`^W1PB)!"3H&!(``(M&3`^W4`B!X@#P``"!^@`@ -M```/A/H```"!^@!@```/A.X```"!^@#@```/A.(```"+`#L%*.`$"`^$^P4` -M`(M&/(7`#X5J!0``BT90C9W+^___QT0D"/38!`C'1"0$`00``(D<)(E$)`SH -MJ!(``(M&3(L`.P4HX`0(#X1T!0``C97+^___HRC@!`C'!23@!`@`````QT0D -M!$````")%"3HJ!$``(/X``^.%P8``,<%(.`$"`0```#'!23@!`@!````H2#@ -M!`B-E04``(D<).CX$P``BUX4C4W,BY6D]___ -MBT,$B40D'(M"'(E$)!B+`XE$)!2+0BR)1"00#[='"HE$)`R+0B2)3"0$QP0D -MC-L$"(E$)`CHB!(``*$\Y`0(A<`/A8D"``"A".0$"(7`#X54`@``#[='""4` -M\```/0`@```/A*@!```]`&````^$G0$``(N-I/?__XM',(M7-(M)*(F-L/?_ -M_XL-_.,$"(7)#X2Z`P``C9V_]___B1PDQT0D&`<```#'1"04(````,=$)!#, -MVP0(B40D"(E4)`S'1"0$!0```.BH$```B5PD"(N=L/?__\<$)+O;!`B)7"0$ -MZ(@2``"A!.0$"(7`#X6,`0``H3CD!`B%P`^%A0,``*'HXP0(A<`/A&8#``"+ -M1RCH8#8``*$7UW#H43D!`B% -MP'4*BSWXXP0(A?]T,XN-I/?__XL=$.0$"(M1!,<$)'[;!`B#Z@&-#!HQTHG( -M]_.)1"0$Z(@2``"+E:3W__^+,H7V#X6+_/__ZY:-="8`BYVD]___BT<4BULH -MB<(PYH'Z_P```(F=K/?__P^&[@$```^VQ(U=X(E4)!")1"0,QT0D"*;;!`C' -M1"0$$````(D<).BH$@``BX6L]___B5PD",<$)+O;!`B)1"0$Z(@2``"A!.0$ -M"(7`#X1T_O__BT<8Z&`V``"A'.0$"(7`#X2._O__#[='".@0-0``B86H]___ -MZ8)$``"+0PR+C:3W__^)1"0(BT$8QP0DH-L$"(E$)`3HB!(``.FT0P``C78` -MBT,(BY6D]___B40D"(M"%,<$)*#;!`B)1"0$Z(@2``#IIT,``(L-$.0$"(U! -M_XG+B<+!^A\#1S@35SS!^Q^)3"0(B5PD#(D$)(E4)`3HP%8``(E4)`R+E:3W -M__^)1"0(BT(0QP0D>-L$"(E$)`3HB!(``.DN0@``BT<$BXVD]___B40D"(M! -M(,<$)'+;!`B)1"0$Z(@2``#I($(``(UV`*',X@0(QP0D"@```(E$)`3HR!`` -M`.GW1```C;8`````#[='".A@.```Z;5$``")]HM6/(72#X4\`0``BT90C97+ -M^___QT0D"/38!`C'1"0$`00``(D4)(E$)`SHJ!(``(V%R_O__XV=RO?__\=$ -M)`@`!```B5PD!(D$).A(%```@_C_#X0U`0``QH0%RO?__P#'!"3-VP0(Z(@2 -M``"-C6# -M[!BAU.($",=$)`A*````QT0D!`$```#'!"1DW`0(B40D#.@8$P``QP0D`0`` -M`.A8$P``B?:-O"<`````58GE5U93@>RL````BWT,C95P____BW4(H:#B!`B) -M1?`QP,=$)`B`````QT0D!`````")%"3H6!(``(7_QX5@____`````'1?C95P -M____C85L____B50D#(E\)`B)="0$B00DZ%@0``"%P(G#=#F#^_]T;8/[_@^$ -MD0```(N5;/___X'Z_P```'=*H=#B!`B+1)`TJ0``!`!T*8.%8/___P$!WH7_ -M=:&+5?`S%:#B!`B+A6#___]U9H'$K````%M>7UW#BX5@____C028B85@____ -MZ\V)%"3H"!$``.NUB?:-A7#___^#Q@&#A6#___\$@^\!QT0D"(````#'1"0$ -M`````(D$).A8$@``ZY:+E6#___^-%+J)E6#____KB>C8$P``C;8`````C;PG -M`````%6)Y5=64X'LK````(M%"(L5H.($"(E5\#'2QT0D"(````#'1"0$```` -M`(F%7/___XV%=`0``H=#B -M!`B+1)@TB<*!X@```.`/A'0!``")T,'H'@&]7/___P&%8/___^EH2P``.T(8 -M#[;9?`F`^PH/A6____^)5"0$B1PDZ$@3``#I"DP``(L5P.($"(72#X6D```` -MBQ7,X@0(BT((@^@!A<")0@@/B#8!``"+`L8`/X/``8D"`;U<____@X5@____ -M`>EH2P``BQW`X@0(A=L/A=,```"+%7UW#H="R+/<#B!`B%_W3%H@>`85@____Z7UW#)0``!`"#^`$9P(/(`>G)3P``B1PDZ`@1``#I -MMD\``*',X@0(BY5<____B40D!`^V`HD$).C($```Z590```[0A@/MME\"8#[ -M"@^%7?___XE4)`2)'"3H2!,``.E64```Z-@3``"-=@"-O"<`````58GE5U93 -M@>RL````BT4(BQ6@X@0(B57P,=+'1"0(@````,=$)`0`````B858____C85P -M____B00DZ%@2``#'A6#___\`````BY58____C85P____B40D#(V%;/___\=$ -M)`@&````B00DB50D!.A8$```A<")A5S___\/A(0#``"+A5S___^#P`*#^`$/ -MAA`!``"+G6S___^!^_\````/A[4#``"AT.($"(M$F#2I```$``^$%P,``(/[ -M(@^$#@,``(/[7`^$!0,``(N]7/___X7_?F\QV^LUBQ7,X@0(BX58____#[8, -M`XM""(/H`87`B4((#X@]`P``BP*("(/``8D"@\,!.YU<____=#"+-<#B!`B% -M]G3!H@>`85@____@[U<_____@^$@`(``(.]7/____\/A-4"``"+E5S___\!E5C_ -M___I6%$``(.]7/____\/A74"``"_`0```#'VZ:A3``"0C70F`(L5S.($"(M" -M"(/H`87`B4((#XB9`0``BP+&`%R#P`&)`J'`X@0(A<`/A>,```"+%-2#"+0@B#Z`&%P(E""`^(,P$` -M`(L"B`B#P`&)`H/&`8.%8/___P0Y_@^-W_[__Z'`X@0(BY58____A<`/MAP6 -M#X01____H#P#")!"3HR!```*'`X@0(A<`/A#7___^-M"8````` -MH#P#")!"3HR!```.F64P``B?8[0AA\"8#Y"@^%LO[_ -M_XE4)`2)#"3H2!,``.DI4P``D#M"&`^-7O[__XE4)`3'!"1<````Z$@3``#I -M\5(``(GV.T(8?`F`^0H/A:K^__^)5"0$B0PDZ$@3``#I85,``)`[0AA\"8#Y -M"@^%O_[__XE4)`2)#"3H2!,``.F64P``BPWLXP0(A`R!^_\````/ -MCJ<```"+O5S___^%_P^/O?W__X.]7/____X/A8#]__^+5?`S%:#B!`B+A6#_ -M__\/A9$!``"!Q*P```!;7E]=PXN%6/___XD$).@8%```B0`````#XBD````A?\/B+H```")UXG&BU78B<&+ -M1=R%_XE5\(E%['44.<9V08G0BU7L]_:)P3'`ZQ.-=@`[?>QV3S'),<"-M"8` -M````B4W0BTWDB474BT70BU74A7UW#A?9U"[@!```` -M,=+W]HG!BT7LB?KW\8G&BT7P]_&)P8GPZ[P/O<>#\!^)1>AU1#E]['<%.77P -M3_____#XE+____D(UT)@")\(GZ -M]]B#T@#WVO=5Y.D&5P``N"````")\BM%Z(G!T^H/MDWHB47TB?B)UXM5[-/@ -M"<>+1?#3Y@^V3?33Z`^V3>C3X@^V3?0)T(M5[(E%S-/J]_>)553@^P$H6#A!`B#^/]T$C';_]"+@USA!`B#ZP2#^/]U\(/$!%M= -MPY"0D(/L#.@P%0``@\0,PR1&&-X9'AB>&5G961A8F%G86-A9`````!,4T-/3$]24R!S:&]U;&0@ -M=7-E(&-H87)A8W1ED`0(KI`$"+Z0!`C.D`0(WI`$".Z0!`C^D`0(#I$$"!Z1!`@N -MD00(/I$$"$Z1!`A>D00(;I$$"'Z1!`B.D00(GI$$"*Z1!`B^D00(SI$$"-Z1 -M!`CND00(_I$$"`Z2!`@>D@0(+I($"#Z2!`A.D@0(7I($"&Z2!`A^D@0(CI($ -M")Z2!`BND@0(OI($",Z2!`C>D@0([I($"/Z2!`@.DP0('I,$""Z3!`@^DP0( -M3I,$"%Z3!`ANDP0(?I,$"(Z3!`B>DP0(KI,$"+Z3!`C.DP0(WI,$".Z3!`C^ -MDP0(#I0$"!Z4!`@NE`0(/I0$"$Z4!`A>E`0(````````````)$9R965"4T0Z -M('-R8R]L:6(O8W-U+VDS.#8M96QF+V-R=#%?'`@)```)$9R965"4T0Z('-R8R]L:6(O -M8W-U+V-O;6UO;B]C'`@)`!'0T,Z("A'3E4I(#0N,BXR(#(P,#6YS>6T`+F1Y;G-T<@`N9VYU+G9E6X`+G)E;"YP;'0`+FEN:70`+G1E>'0`+F9I;FD`+G)O -M9&%T80`N96A?9G)A;65?:&1R`"YD871A`"YE:%]F`(```0`````````!`````0````G````"P````(```"\@P0(O`,``)`%```% -M`````0````0````0````+P````,````"````3(D$"$P)``!$`P`````````` -M```!`````````#<```#___]O`@```)",!`B0#```L@````0``````````@`` -M``(```!$````_O__;P(```!$C00(1`T``#`````%`````0````0````````` -M4P````D````"````=(T$"'0-``!`````!``````````$````"````%P````) -M`````@```+2-!`BT#0``,`(```0````+````!`````@```!E`````0````8` -M``#DCP0(Y`\``!$```````````````0`````````8`````$````&````^(\$ -M"/@/``!P!``````````````$````!````&L````!````!@```'"4!`AP%``` -M#$0`````````````$`````````!Q`````0````8```!\V`0(?%@```P````` -M``````````0`````````=P````$````"````B-@$"(A8``".!``````````` -M```$`````````'\````!`````@```!C=!`@870``'```````````````!``` -M``````"-`````0````,`````X`0(`&```#````````````````0````````` -MDP````$````"````,.`$"#!@``!8```````````````$`````````)T````& -M`````P```(C@!`B(8```V`````4`````````!`````@```"F`````0````,` -M``!@X00(8&$```@```````````````0`````````K0````$````#````:.$$ -M"&AA```(```````````````$`````````+0````!`````P```'#A!`AP80`` -M!```````````````!`````````"Y`````0````,```!TX00(=&$``"0!```` -M``````````0````$````O@````@````#````H.($"*!B``"L`0`````````` -M```@`````````,,````!``````````````"@8@``00,``````````````0`` -M```````!`````P``````````````X64``,P```````````````$````````` -M`00&``$)P,!J``<+`0`"`0`$`P,!`P$`#,#`:L#`:@`("@$]?9*5```%`1$/ -E`'@`.``V`&4`>`!E````%`H!```M0RMQLYT!%08!`"$````````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj_deflate.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj_deflate.7z.uu deleted file mode 100644 index 8c2ad8e6e..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj_deflate.7z.uu +++ /dev/null @@ -1,275 +0,0 @@ -begin 644 test_read_format_7zip_bcj_deflate.7z -M-WJ\KR<<``-7%?>]QH>=Q4N-!@,8R3Q,4IQD@%IW6Z3.1WIX0I>GB[9I='2 -M5.DMTB1I%.$$3:`!]"!/$`\P`>(`20;`#I.98"+PB:+.P$!\T)8@O1B\BGE[ -MR2;JUQ-3U`/V&B6I$(U'B7HCDI;U`-01=`,'L'J3@.D&`/HF2`:>'%&W[#=R -M>7(QRGZ%.D`*RE(BZF=65VUP-[K+9E:7SW!75Z0UU*8YJ6MSQ!@6UKO=>2L* -MI,X%%BD?^+L!.8`BUA?_S`>L%/ELP#S`T'0IYF058`U@JBA+`(R1HC^)@`6`^P`K`!:`7.2)M!"0+_(/`>9(;_YC>(.ZN(C\;;>@&272L2*] -M,P;-Y&'X>/H2\_V6<"FWJ0D1^!2`%3".FYPT&G`7V76,/NX&.`#O&%:>"L@0 -M^2S`[(BZMP'N`4P3>*:PK00XTFAT`-BG'%"B<<% -M?DS4IPO\E)'CLP5^4.#Y`G]0T"\6^->-T7K<(_`V@9L$?0W2\6+>6F@-,SV^ -M&CICB&Y_A[9.XCF^6>#/QW'\R6'\\P3^'H'/$?RF"=PHQOLI@<<+^MT"_YR@ -MGR'P%X:-OUOT_P>!_PFP_[+);"?Y(6W[,#OZLS&:_O,"_YT8_ZGPNN!XO:B/ -M%[A=X"^,Y?BY2/V(]=W[$:Z_\5C)Q8)^NN#_':2]5TQFDY!OK&@_7[3_O>"U -M0.#]HOTD@8\3^-N-''\`:<=EG=\J4>\6]7W$OT>KMTE'!?_?BOIO2='Z;1#X -M:V(^*]'^9`3_+&.T/6X4>([`KXKQW"YPLYC?>6+\QT5]IJC_\;#Y>#OH]Z(_ -MOFV\&OJIYG-%^XEQ`A?T'P>P;H"WMU>E7P -MVR#F_UZT?SYB/%;![]-F7M\+O#NB?L6P]>`3^%L$WBSXWROP(P*_1^!)P]K_ -M1M2K`F\3=>LYKN^E8C^\4[3?IOF?8?QVB'R2T+^$N,$C5U53P)`AE12\>VGN -MD@?RI4K/YM*:JO>[2VH\FS>XZZ62JIHJ62JI0"*5+"I\*"^WL.2AA0M7N%:6 -MK,S-*W252"7OVE*RW+VQJD%VU^=7ES8TN!N(=TV9IQY9SE[>6"O72G*=1VY` -MWBV[:V26-LCU1%M&5'.EDI+-&TH:-I145VU&GZ@KJWL,A0UR>:U'KI,>+:VO -M:92J:LOD:JK<7%ONIM1=7U];+S74U-57U<@54FE9=4E50XE<7[6EJK2ZI*9. -MJI`;2AK<,N-46K:II*QR4\E&3VE]N<0DV2)M+BTKJ4"(1'A=53EC@2SDJ-D$ -M!EP$=%-'E.$:J=Y=6LXRFS?4R[6/EE%S3U4YB*JK:\NDJH9267Y,JJV32^LW -M,B%JZ]PU81855=7N*)$J2JNJI8J*ZM*-#7(MQL4HZ^K==:7U;D9=4EVZP5TM -M0>*J^MH:J4(,>%-5=;54750=C#UE:0,-],H.I6JB5"N0H>;W9M)]^B5FU*)7-U`PWYT@P=S -M);L;JV3JL9ISKH"%E#%=$3_JH8)QJ7BTODIVT\2$)VI#`ZP4'&JK)$^#NQ[E -MM9M+N/K+2N3:$K!F-E3MKF%#JZR7-M;7>NHXX4804F<-K+.RRJKJ<@R2F9A4 -MXBXOE4LAY(:&!IJ?>AE%4.-"A-`ESC2GEG'0+C[B/P-`&E$3-P(W"-JXR);4 -M5J?12GDY;W4KGIP??8_X3^>*#Z-0F,_CGV].??]HBF!GQ?&RP\").HOV&Q%3 -MQ-_.]]KX*7Q/C+^7[SWQ<_B>$)_-?7_\`NXSXQ_DOC%^"8Y-\+FC#?!_E$*$ -M%DK!>R>E<)ZME&)/VDWI*/AP2B'!4Y2:T3^E8Q"O4#H6^Q"E.`0EXR$WI!,A-:1+DIG0BY*;T#LA-:3+DIA1!QR5* -MX;Q[*+T3_IY2!.(!2BA[B$TKF(X2G-P!F.TGF(3RC-PIF-TOF(CRF]'WL?I3DX)U&:B[,?I7DX -MCU&*37@MI078;RA%@%].Z2+$192^"]L'I84X>U.Z%'LKI0]AGZ9T&?9W2A_& -M_%.Z'/-/Z0K,/Z4K,?^4KL+\4[H:\T\I#H/>?DM@_43H>1DA)RTGH,+0G$9H -M,S1E*[XEPJ>05552-CAD);R9<+..MQ!NT_&=A"?K>"OA=AW?3?A4'=]+N$/' -MGR(\0\?W$YZCXY\G?+&.'R1\F8X?(GR-CA\F?+V.'R&\4L?;":_3\>\3WJCC -M'80WZ?A)PEMT_#3AK3I^EO"].MY%^'X=?Y[P@SK>3?AA';]$>+N.]Q#>H>.] -MA)_6\0#A73K>3WBWC@\0WJ/CKQ$>T/$AP@=T_`;A0SHN7:;Y-X1Q$^%F'3<3 -M;M-Q"^').FXCW*[C281/U?%DPATZGD)XAH[;"<_1\53"%^OX5,*7Z?ATPM?H -MN(/P]3J>3GBECF<07J?CV80WZG@.X4TZ7D!XBXXO)KQ5QPL)WZOCRPC?K^,K -M"3^HXVL(/ZSC:PEOU_'UA'?H>#GAIW6\DO`N':\FO%O'ZPCOT7&9\(".-Q(^ -MH.-;"1_2\28V_T9]_;/YU_$6-O\ZOI/-OXZWLOG7\=UL_@4>_CC_4*3\QML[ -MX'>9O?VF92&/:7F@E?:.5OY![>I5*^"Q5(]%+;;YKOJW?MNDS*=C[O8Y:IRO -M0YYY@,Z@UF=LS>?E=W@[#'T)R",%FM1T?:;G55:OE7GZVUN`HEVZZC(KIM1` -M`#M6IRF5#FHL'^B%>,K65+.R-M6DI*<&]L-I$>$:JFS!?M?7U1K^D/3]YJ;Y -MES`Z2;;TI7@[3`?,Z"%TOHT2U>8[[^D[%4_UAC,G!'U;WV);4'L)' -M34E50:O2"/J+3VQ/A$U!YL"FL^QL?.S1/V9>V/XV=>$RQ651%^';'-TB.(0A -M;CV2>:SAHG^+U/=5_Y&[J:'_^^^D!/*H119279$9#(J#K1-1)]^MU?/Q"7E5 -MCUDMMJBK"M4'"]6\J9FY4[?;F#2B1Y)OJU7-FYZ9._WQW[82FVVCV2#Z?J7F -M,P$71@BH">=_A@GT@YCRY-S^9N59EIF[++8\*S-S5_ZKY.EZT_(D9^8FQY8G -M)3,WY5\ES_H[WJP\]LQ<>VQY4C-S4_]5\@R,D`>51)+#^.41/\Z&^N/UHI(( -MXOV]X2B-6\[S!N_X)0U0SN"C4(HM-,#$7E#JPPR]+,KU -M@>]'*(3UX[RJ#$1H3_BS'?W3X\'+E_QZ*-1&X;_BZG=VM.7T(K:\)P%3>(6F4)ZL%*2:T(@<]P`N%),4^1$.C.ITL\:_/O#)1=3]E+R#*!29K1I-E$,V%GY!QU -M#TGD/6[PSB<"PZ2.P:ZW'U>9_/ZDV_TK)XQ75EC(R)0DWANOH[[;(;M2DL3\ -ME9=9NT%]W.P+R4O413G>H=%6WQU_A=B+[$3<.`[$F!S8*E;R`*8(&(:'>>E< -M9&$+?!&[2`"+SG@[S(#*?"'/M]4]Q)J,8D,<=4]KCIH^RL&?J?E)VA#51\R^ -MBYY7U*+^V1/)AUE]WX8_V'&27-LCZTJ*3]#XU<0!5,&.?0MOA$+1(PJNIO4> -M,,"1H$Z=S+SO1:LO!5C?\]S*R5Z)%G9._>X5-JU7*+X";N$L1!M'!60.07JB -MYWV._,YMUB?NN*FOW"1'[WQ)F_A)9[PO7_,>L\+4_$1K;;[V5R(M9!8U>[R2 -M;XXV.*I0+%P!P9LI^@HKH/[--F:UOD+&JA4.$7[2F,4SP=7+5W5%D5X -MCLROB45O,`WS#,SE8I8;5!\Q9'489N,$QE1N\#-[IC).P%;5.%ZY2B\Z/8Z9 -M?IC7[JAQ?)ZPX]8/3:0Q,"Q8AS%$=QFP,:X>/P3G2\&DYJ1`6>87Q&IHA\"Q -MN_3X(Y6JL-+@_79-"7P$-L8QF=1Q^PNQU1$,XJ(IYZU^7Z:3C\5MQAXJC(B[S'#J1P#J/(-S1WR?.7%OJ06`Q7F4F&> -MT7N"[5[VOA.;O?MY_G4OR^IW@NV>_;RW-)?M]!H6<_VT%)J7[?89YCVMX- -MK9/%+B:O%I_5PS*,<^?]%C$ -MGX/8@G7A$RU"V^0U=V%JVETASN>L%`$T=%94"Y[NT(Z2&<]WQ(B^(T>P@'#)%> -MR/D6JB;+]1=_%S&,6/@IPM*322/^M6)>L._S/3^%&V,4I8@+?)4T4.&#JEG^ -M\RQ?Q_)/L;S,\H<%V[_/LY'1'XQ%K_BV4N1P@ZTJ>4VGKPEH/`V:K;TLX"S\ -M8*DJ0I)F6E9]V$#>T&D$Y\`5A%)]`RA419S5(A1DCQ1Q9:HMEGIXGT%_*H[$ -M"=[K4JOUB3MODL4XSP?WON-68?)!/'ZN/ICM.X-N\OG)H(7V]%3A -MF1,)Z1!]KF01]%DZL>69T12\\\S6EO=2L?&4E("]1S&J^2DD?,=V+C8F)132CD*[V%AB)]4%B"E:R,R+Y,83?>X8:/R30-5 -MH)*XL3!XD`9T,H6%3*W>(9,\AL6(?Z*8)3\J1H2,PV-$/20,-D&!K=`&2&:\ -M$"81%=YM_0;KKC3T?(N!ZI%?T/9.B#;9W,NCL;60XZHK8*9Y0K75]VX4!.O! -MLXU4"A[DU5AOIVUH?>UNTO;`97Y>F4[$1U%$,92@#2R>P.BXV12^$&F-O"QU -M6)E_BW8_X(?YX;HP]+X;W%(?WM&?0?'3)/T8[??UT[[\F$GQ]5[C@>+9BXR? -M1/P.@I_&>R_R9"X?E4@!%MS7+>,GZJ(7V(F::L59=X*9MLI+U_1-K5(VYVB, -M%HO`*,GZK.\ET%2@G=GZ;,<] -M9VA+X=O-J!WGZ"%/^'(E0$C@,D?^PNS"ABJCQ-8$M;DHEZF)25?XJ>;7)M)& -MLCB=CX]'8\L5FG*Z(+(_R;HK#3-_D:A]-"F=\73FZCC&"%8JKW[7AJEL9_-! -M[P_VK1;CMOJ6HPW&SAET`.&\6_=@QBU\#)_EW`Y_WV3FW%%V2&5VH+SJ3WJ" -M%S+&;>0NM-OL<"![%_R"-FC?6"!^7T`L'1H\L[<)-%"&=1T;>MNQP!T&I&,. -M4$DPY5XVKQ7:O!*;;_X5*__N:;":<_;.^('+PKF4W<.6&GLMB'D=S7SB^RED -MUDC:Z"'X@==0I+6XHK4H"+=-%SE!DGQ%8Y5T):K"="6B<^]O;WC/V3KCARY' -M%?[1>\Y(A5$-7XNB.6<83E"0RJHU%Z.M,/.$,`=';UBF2&'%VAXV'ILN-A_> -MF)U&FT+"EZ+>#T!+[ZK->QHE\3*]H()&()7KR' -M?%GR%;Z_?XU=.Q)[NFVL,F@.9OTGL/:^=J_N?'QW491N$J[L;6'"KC"AC;NC -M&=P=-76@O.->C:QI+Y&%T?T:RHESGA/$_GV]UT0094I]/ZVF-8C#!;X-^(&! -M*]&%350XO3>ZT$N%BX<5?H@*IVJ%OHX#$O+6Y@OD\@>$*WS[-;J*(G9T/3R! -ML$1)*">>.>X43>$..#>^%>NK06S*P77DPS+X=O-`6X`KYB$^],-/BJ&K$S/X -M%I6L461SBAQ.$=9P-)KSB2AT?;1B!WAM>-!_Z!;C9:,-#N&5B^'/%Y/1\_PV -MJB:/MO];XHI$$L/#IMV.0A;^MRWN'5E[YD2XL=0>HS$5]AW3GM_@=)&D%IL1 -M0P\XV4F+'1ZT\"!@%O/%KOML%!HG/8+`6.SO3-ZI>+##?6\XE&MQA?RN$(M" -M*VUT!7/F!/47/L],1Q.:7GJA`%EG^(Y*G;C^DLEEZD8XBE]@9I*A'<3W? -METWMK4>/>P.."N^V%R4ESMK\=503K4'RGC)X3YB\-XT>E[?3X'5=LGA=/49O -M:*RU^7F)^KC4V50I'(;?='^FZ_E',]6B'NLSQA;7G]BUC.O/?M/CSJO^%-_Z -M*_2`>F7:G_QY7=FCMZC^O,]FCWXTE?5=JL3U?5PM0KWI_:QEP?NI:=\)\50M -M[P<@O9>1YBIQHEMAH/?,9OKIQ];$3P+OF$V73#_*2J17R[99VKJ0J#M;TDU0 -M\[5&>0+8D`K1)OV2:-,9%\*'L?*>G,X.*9TN,^UVP=Y9;#Y6K5!.^--SO/TV -M->GI2AX)^7:3#DQ/T\@HMLT@VV%K+/*DV,XCT3MC&PX/^TV/J"9?N6`SA[&9 -MWAN337)L-B2W[9%UQ=P>VJ:^@:$&"_&V5_3S;L3PRO&B'9?I`0)[M+CCNI1# -MSPY.H7+[P\#V$[8-&/(=>#2V`2E[NK"5KH#.'WQ`+KEZ$I?CEX%>/6FR-C^+ -M3#O9!)=N/((L/(HO@1 -M1-&0.!C8ZBJ*5 -M%>K/=\7ZEQ777G%@&\)SS^D]S/>VG&2!./>$6]3)KUWA3KB%=.7:RZ9Z'',. -M9G_Q09J\91%/LBK'B1,I+S`%AFSZ$=6N'5$;V9E^:'8\?V+1R<[>,AR,F';M -ME+@8=)H$!PJN$.UC6`>M;;3=TNF)"?V]](M\:RQ&W?=R:%'LO8\QR20F0^/I -M`4"Y=7>']9F.`]0@N.,^ND38JTXDGOX=TJM_E#*[MM_M_R#+'=N6POD6"K[Q -MQ+=(XZLFLLIU%_G9(W`3E96\4MSBM/)'H>PI.7\@FMC/3BKR&/:3P+ -MVW5$D1UODK),$UXQU-Y/Z2#'L(0V+_N(FY/&NU1CBYE=FIQQ=IS@.K=PG9\6 -MOC"W3P1S4[]/>=X_QQ?N+/V6SBR5P.;%XF;LIQOM:TA?5K -M6H-/[.3+RT8E*PPLG\/-2EZ`!78J?-7S1.RKGD8CO^J9QJ1F:X7O#R!&4^:Q -MOB+%;#I1W!+-C&Q*2YUD^1B7JP=YGXRI"LOQB=ARK!?,ID0R"S?:'KO13R7> -M*">RD6;8,R/O7H8S=,=F^%W!<'Y,*9)B-6K<3`VVZ@W8%%O]EV&"XF9GIG:S -M,TS":=$2ZFVGAL)M<[2V>OVV7:)NJUZGMYVOMYT?J_X3NEQ3;B'7%%VN$74Y -M;U"W]0WJYM]JK(__-2S/M&'R1.\W;'UD*,6O*2>4;3>4GRJ>(;6ND-V/=+KZ -MM2?G+R'5;DCJVU*X2WK`^NQ"<\`V!R)TXAI0N^13E_3[4\R"R#-7G>^@7$@> -MR\C79^!]]1-*MXI^BE]3T27>4HEL7836MKXS:/!#9P>+V/J^WX9#/YF&XNI1 -MCJL+,XY=?YO!U<-*E:)>=57V.'POZ56.HP*CMB#NH6MC=GVKZHO#.1J\NO15707?W -ME8XTWB+]FI<]M);GJ_D6[X!A;+Y-?D5=:L/P5]D#35GA.V/Y>S'N-K4GWB=$ -M/#'\1K/O@']+.-[,AO_USF=W8Y/.>R^/5EQ=:HX9#]^RXE-Z2$T!ZT?.DE.:L-Q7'UQ5S\63-5\&ROTLNDVJ*Z`]\507%%@L!NA[=N/*T4#N-G&3M"# -MRH[,+NM'9A@QT"Y,V."V`;7HDN(Z*["SWNL&M:C+VQW"=*M&"J*/DXO(8<^; -MGZ6LIP>7W[L^P"[S\08R);UL2)/3^07=*+6H5RGJ5I>`O\9]^QZ\)[-9=![3 -MP,/.MG/!`C:E3K:1<3U,M-NQ\O`FG-_R%N=YY?3@GXD;6X7!]`6D_"Z\PR=Z -M#1[.QM\3]QB)A,TE.[V-8T\\CLNW@[$RD8JA\0-D_\&Z^7JLU3Z>V8!2;.X[ -M''[?5RQHO%;&GJ3VI=!YA]\>DUB=1B8)7\YRY'+.7Z8=[;P?H,4WB!DV^DVC -M#5U9[(:_?KJFW]H8>^,NMCT6.FYLND;2DK -M?FH/W<.\'A^6ZKTLN\R_[\D,Y'AZ/8::'*`"W+J)OS:GEK2G -MTZH[.(X>MTC677>,8M=GX@^8.;&!-E8JXFQ`S^8C(TE[(GF5O3AU`_'' -M-QGC^)[\!1*9U9"+?`P8U0[1M?FZ)"A*W4/:5_-I&TS!.[U(DM4X?"?A!6@D -M-F@Q@<:%]VN50C:Y._6M+^)%-86]3R>0E4#0,.H-MX/Z&V[[V!L)K.-%#G5U -MNOK`5,5_F-#$&WP>F[\;1Y=N/T`9OXI)'LT5EF3GJ>ULQ!Y-BF3'RH,V?A!3 -M]Q$WR/H]HEHK'(1V2^C;:0"2(1!?')"`N&>K8"]R3@VLOP^%*8*BGL1=&`X^ -MM,AFG+J/#!0K?;2(0=1$1R\WPZPH!?!#PUQCQ-/?Z[&#X)?CHI[^;J'GT;Z; -M]!Y:\<#LR?QTN-M$[[/14F(K47LXE:"RUWO@`&9SW;XIIRGF?Q;UH](;;D^R -M_6H?GYPD]9&IRG'';W=<#Y&=[CN$4NN'7C'0?_8L -M!`>?+J#]',$K'0:SN2'Z]\3T/TFZ__'[B,*_[T>#G$XRZ;>7BY/8@UUK,_TP -MQ:GF>**A#>PG$)0)Z?=3D6+AUAX\0U(5]V#"(V?[6S%F.]CN$N_#L^'[:`V2 -MWD:H:F$!J'I9)BZ?Z\Y/;=Z`KR7B[3O'(EJD8,.BO1]?!YLF3*!X2T)[!T(XY97\ -M^7L''ZFEC?X>EKV=:!-*/.7ZQ;W!POSAFR2;>*9$OJ_`.8=OR6E^^1M#*]%N -MVPQ^WRPD\&;<+M\IQE,8@UP;O^\8'A"$]RQ3%INQ\(ZS?1+?;8Q1NPU3E]7_ -M':Q#K2]K\U>!"9T7C.A/7/5$WM\S%9""WR4V.W$S7GZ)JRB0'/'2PYH)^ODI -M'"\$?&8Q>W<@+.#V#8)MI+80]?0NRQX.VU]2/P]0`DU))FK -M0]P2V1]0R7P=K+'QW5/.]+X>DC=[7[_)W[A0]Q`U]WB/OHM?1A>TIG^9?OE& -MOL?+N!L,+R%";5.+!OA+QBHK]53L.'E($FZ9%_E->Q66Z?L)26BFO]-Z&L/T -MD5QT6<\J3=X_&D8,R,0'U/>DNH=Q2OJNPC)]"A2M.8H1^AH>7XU@ZUL+'KQ_ -MK0NA,39VO99FB&N.>-!UK^8/U]BTEZS&&&$:])[H_0;*0(/'R$7M8QI\/<1N -MR9I1(K2XEVO1VOQ3BIZO^D*/S^VKP/K7=D(FF_49RZBH/9'$#]_M06>9@_*] -MVHGX%/.D)#8W2CR/N!TDVB$G<]#S) -M6[;[V3AX#\*:6!?JY`[QIOF%V`PF1#&`:3,&3%#!YU:+@O%74KC],7][YD'] -M%OK^J$WH/(TEL4.\'O]<;%$ZI$A11._#5H/51W]&&+$B8OUVMX1M8)U[$X_LT2TFQL:WD[4LC6F -M7/U/KJ]3UF:%EM5-+*MREL%">XV]4^R[^OCLON)AJR8N:HKV1:V:$X;,E^3I -MZGR:5[HT&[EL)H`FO&Q>\CS/EXWAZ;7AI?QHW?!E/&/$PAH5>V']2A(+2RRI -MTTO%DKJV-4$9RL::>EA;4]EB3>4\I%M!:]\NKK-;.$D]K/XX"J/5$FVX'XO4 -M2O3B@5#:!(FMC>3AUW^,8KBWWQ1AV]$6?"9"]N`S0$:HVZBI.KAJV3#O4ASE -M700%=_E;_AE_O^8-[7'-F[='KM#F9CJBL+RWPX@A6S]D&^'SGXX;Z?/O0)GW -M];NLS;>QS%J\N$"'XJ+LULN$Q7)LPKY'"%/(SXV:W1A8U\$U#^NU -M/@]J?V!@^UWPX`H>[\9RJ9\4WGTM&U[8H*^$#5KI[@B,PA,[_V)'5,,<@ZX6 -MO=V+4>WBO#VCA[=;'+/=^8AV,1K-CFRDQR^9-ZW^7]^D.\+P!(#9,RD(&L;)&057:*+T=#C%O.N%T$/*P)TRN#2X6^1PB/W+W,/IHXN"3 -M*\C-8P%B]5W#ZOL61A'Y;#!X#\T9VRO6B2HQ$%[]ZO+H]E\9WKZ4VNOU/XBJ -M%P*$'X?:?!<;+<(F=WU)TI>']2//_56W/U\3D!';[4<-4=LM7T7:K:/2V?<= -MYF9>A<<=((_[S1M"DG0AR?CE$5[K.=CP&_M<+^-O8-9N/7I"'`F^06]H!,9I -M%U/9(-$CHT_&CB:>DF*8OF<-OQ2GORM2'S9;CW;C_L)W7D&V1:$&AI9DHA$PC#?87B4CAD=#PV==J'\8U.BGT -MO411&.&X4U9IAR+FK[W]#OY'YJK'IFY+4HHNT8,#5W>GJXOI=:#3]3S+7/>= -M$8\JK"V?9W]6R9^.TE_HJ$7=RC$\??&%X.[QW,F3E'EJ2Z[2A2=B@U>58\Z. -MO@G8)K*V]6]YR(DGU]K?+RSIHB=?KN=5%RB?AZ6-'NSVGI<&7_2>=)"QX,_+ -MQ[8S+W6>V*CX^XKK@Z^B.]<`DF/*0-_WK<]U>@?>IK@"GH+,;?V/QF=Z!NJ? -M8G^>A$X_,UC<[2VZ)`T60S((SWR?\B"^F;^COR(2'0X6]09'K<9S1O;RPY_N -M=0648Q=^;WT&?\+@>DT94GZ)D5SH&=.)GB_\%L6O70A0Y87+E!]#X\1#H`N_ -M'QQ4BLXJG8._S41RJO[.K**S>'/@FK,CF`/F:,P:]4`YO_<_%!+%K=J'O^]A -M:EO_,G^#9[SS8JA+]:XEM,^$$L^`]Z0)[U^`EGZ7R#&1_R11JOA!W7GVAOHR -M^@'>F64-GIE5LS/NHY_@G5E6+U>EK9B^Q>Y,FYLV:U::TS[+XY[C/OLE=TX#?N:NTNQKK[*E2X8J2_(<*5S]0L'+Q"NTGY*8TS+-/ -M:9"F>*094;\,MR0WW\Y^#,Y>45L/BIE$5.V1IKS7$_ZA.=:XO*K>72;7UC]F -M+ROUX-?X[*7VLL?*\$-K\_0?64.O14N6KI#R"Q]`]J'EX4S)PH>6Y[NDE:[E -M2Z3T@UEY14;*ZLV56^NJ:U[7WV#['FT49KY!9,Y$Y`/ -M6`)8#2@%;`(\#E``&[]F,C=_^9^'58=,9C?@$X"60[QL*7C.`-P)L$3P'SP4 -MW?:RP"\@_2[@\#=PD?@-7K:=I1QJP_F1L`+M"E%_#\`FZ`Q(RY#^Z>LF\Y6O -M\[(?(?T2Y0$>0`5@"6`:X$Z`!?!GR-HEY/T:T@\#IKCM4S;8IZRT3WFW1!FW -MR(ORY5KA6-&QK=&_&S>QM* -M-Y:6P2;QT4S,WE!9ZX%QP7SM996E]:5E^)U)&/*,2GM538,,"[;75M@=,S+M -M4QO<;KM[@'_-RA?4MI -MO22=OPC=-J#9/'MU@_V1&3#3OVNDSF(0%M!"W%PJ(T^_U&A/2TLK3I#6KKWK -MKM&EY@V6BH2:Q/HQ\M@MTM_W'#7"<]SWICT'#B9WQF4EQ?'?A5[S;"CD0/X@ -M;OL*XZ3_?_[_^9_YT,,^2JM?YG\+E]S#\31`"!\C2_5/DFAG>/]RR;#5;+C3 -M8C*U&/AOWJ<`[$="H4E$D'^;*<]G3(P7Y1F`E5=#H2PSYB7&NSYD -M>B).\(N`8I$J`(O$?P,[$>G6;O[HM@"_Z4]\"Q43.TU_WVLR)U!Y'/\M>!M@ -M8L3OR,LO\TMX![Y(_G&`.P!'_"8SY66DXY'F`"8`2`$X3-06H#R$E&090-JZ -M$[KY!S^DLW`J/BT].I_;6DWFMP+2``L`2P'K`#6`[8!=@,\`O@XX"C@'>`GP -M"N`FX+:/HCT@#;``L!2P#E`#V`[8!?@,X.N`HX!S@)<`KP!N`F[[&-H#T@`+ -M`$L!ZP`U@.V`78#/`+X..`HX!W@)\`K@)N"VCZ,](`VP`+`4L`Y0`]@.V`7X -M#.#K@*.`A'MWEC0(!^],FY66#O_N -M=,YT.&]#K^F[*YVEV*O?43T7"S]P_310F^H -MJIE9W3"S;'.=D-.9D>9T_'LDC=4S_A<=9]RGJ=PQTS%KYJP,NS-]GB-]WBR' -M_;W_TA[9+S.+3N=F@,ULO=-TNW/.O%ESY\UV_HL[I1_S%GVF._];3.$?I4]K -MJ,0!1R[=(*5!A6[\Y'9:3:WL3LO->V"&7+I12JLL;:B4TLH?JVEX;#-+Z3R4 -MMK'&D[8%86%5;4T44H(Z]$)T/%-7+1/G*GRS'XA.JP""JEKVD\]I[DK\/#1^ -M)[NDLAPMH\M8;Z6;J\JD-#I2-0#GR7O+2():,-O0`)06)_V^^3_P&2OV$*,D -M_AT:(!.'_]LCPM^/9G3BWXMA>YG^,8GT[8!XHA/[3P'H&HUZO4G`.T7?1K$O -M?1\;4&L\;VL0-#;`3+$W&<4^5CB&]J^1\LWE>T -MQ?)^R)?(_TT2O5_^60$80VW$OBCJ2JEN)-UW&)T>1\F@2S6,G+>C)*>@HZO3_1OP>^(1=':1GF#\]`_1Y0ZW -M^W"?^N=E&-K9&.OW;P$$!@`!":\V``<+`0`"`P0!"`0#`P$#`0`,P,!JP,!J -M``@*`3U]DI4```4!$0\`>``X`#8`90!X`&4````4"@$``"U#*W&SG0$5!@$` -&(0`````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj_lzma1.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj_lzma1.7z.uu deleted file mode 100644 index fd6b4e067..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj_lzma1.7z.uu +++ /dev/null @@ -1,245 +0,0 @@ -begin 644 test_read_format_7zip_bcj_lzma1.7z -M-WJ\KR<<``,I&RS\_RD```````!9`````````#FU5W,`/Y%%A&@[WP)!,(6+ -M]:YDCG/TF9,6Y4@I6&:W,\L.GXAK)SG^7$ASM;Y]KP;]Q:,S]93R>,&)>5<, -M&FZE"`#6^N9W.O9$'UE^T-50DI_AD]BN$0G/D?)@D^5S4+=>0I338+60+5WO -M?S\=&H#(CWK#P8A*.F39U-N85;*`7:QH4MPY]Z"R4@0-G[PN0P/I&4U*T@DV -M'"`CQ@7=GL@J7_2-A[.]&`<]D>$^(9=0(?Z*\Z.%M#RG1BD;5#6(4_PL?`47 -M!00BJ=5&HZ7@@B$C!NO::D+1C%8P).\)*UDX0P@<+::RMJNW=<@+:$ZER\IE^S3<>=HCZTG -MM[:O[2?'(:Q@840D]\]5Y73NXY[]$A&S9_<=T[^)S9E-I@,/"Z%N3%P8EQ8N -M.<>T1U:G?9*=LX1R,65>5\LCE.PG__FU`+L]UUEKFS13]3C4N`J/2*#MK;D6 -MR_YC0[KZK#6ZDVED3OA(WO_#+'G.!7!DNT&:A<:N8%2S1T,0<.CXWI?5110E -M(]/(V5U26WQEEBY"+^%%%QQ*$$LVGS;&M##OO=PE)#7IOV]4!T0>MCVFR7A^ -M)`*]D,D*8(TTY<\22+QK022#]K1P8Q>ZDOE"5%*XR1S_RD)#8:OFV8PM<:&: -MXO9&=U7J?O95W3V[0_>S$IA67];6D(/WJJ:Q>6%"L4.3$3?0E!!$%?%!2/7& -MXB4BNO1`#[FYN$MKM,TL^'./,4GY)NO_;YJ7P -M.<8Z"R!*LK]S`B1=P4X(^JK3]7X8N(%H?=H&K>KB'G7(0C'R=1Z0Z`IBTR?O -M>DKYV:WR$Q0MRO.CI2E[0;'KUGX`,?^8H_"$EOK=81Z5Z4VZQ'O;;O;-'3N/ -MM(@343API(#U5#X1=PK%4)/F?[I"DE\39HS<'P)7H49\16$$ES92A@%4O+Y4 -MAD=?Q`Q6L[^+YH+AJ-Z!]8./"Y'^Q"*$TJ#,%/ESOJCC)X:D@0R_?J)%YC&F -M):9`]N(:_,O,>0]$-QL,-?ZE@EH7Z=TEA\M7949(]"*65FN\?-CF(U?7P0?R&\DOWV5DVFK[.JXEP>WU1IL?6K&/CWJ(7%PM9 -MZI:B)8)Q$N-53QL+1O[;'7O/7/O^;3JY[WU7(!DWS`YXM'QL?+>("XZ7)FJ3 -M#T4640CH[0Q8U319C-]L^2259=A(C)[[!/*9P+!6MXIH$N)1*Z:&QIZ7]E*8 -M%(B.D'_@P=8!H(?*X?N@HB+MAKFN3F][.%W':*1!5I4=/"TFY>,\=4<$EI/) -M\S[27U*=0/;8!0P4W/=5+RC"*W]L[Z>GIXO;=$L;^CKMC. -MFK$GA0?W<=3^K@8Y^D_FAZ!W7WZ#.6HO6/_:M&X<5E:R -MAU)=J;SF.%&+0R;V*[FQB?;-D6E*-E9A9B[,4F',0KL8S]AZ3/3,AZ!6('R] -M)>:,3R!'4,\HCK1#'3_?PE4$NKGPX,R?.IK6$:/[E%8278\-K\&D4\:14"/( -MJ(V,!$2BJH@D@[TOT`^<-9#'>!Y!%G[3Q4L[4EU[56_:"*>E#X'=E='@D%RN4=E!\F6P+B>NF-E.')J;D/S -M>](@#H.CZB,"S;X1F.)O-8.%W0+\OBW-QVYBLHRW$*]^CP(Y/U\G<3B;CDT0 -M]"EG+*#EDEZI35$5+9SLPO#7YC4(/'^E+!1? -M^*3VBP3&G9$9CU2`[V+^+*?N^CKX/5VXN]BITG#,SZN85C91X7OQC*NK9_X/ -MLBT1D8WVS!OCD4C7_3>4N>6Y[.58AS6TD<_W-2HXTD?5O2$`?JW4#>E1DA(` -MHQ=#I"0OK1YBL'?/Y$@>3"0_Y+,WS'D:N2A4EH3`]F2 -MVFSKLME)Z,E9_,4[!'G+XCO\^^`Z\^_ -M!QY_7[O&*@MP8&R9/?%Q"XE@16@O\T+PU]?>]+QO%2RW(E -M^$A@,C_K8V6Q,(\<*T?3=QQ4D)]CL-8JTO%EV64)I,+2`_,\J._L2^N5B1N7 -MPJ])*IU6?/,23U8+;W*OE:A@V<`;](1`&8U>JD6(DW,D!F]^H:VF;L,-_%X> -M,)O/C?JM)C=5^AL,$UQR5IE^&Z1LE"T4OCT2A?W*V(0FZ=[^9O=[0L[DD:O6 -MTE:IM]=YK:4\#5<6Y>]VU@73]UZ689)7!_EKHD0T^P))9P%J]^#P><2"YV.% -M>U#Q<%/(S*4JZ+.0NU!_ZK^5M7!QAIZX:/Z32G6WM(_6?(8E9)/OGY..D_/. -M%.`#A_`A'J3"O.005L(]?6EP;FQH7HX1HF -MCAR1ZQM^6(:4S7GX!F9"T=U-C/O+M%,($IH< -MF+1P]=.-IA$C!(-S+&9]!:S%,;25N3YB'YX+%D?E-2=`D%!!Z27@>!`2&G1F -M-=33R'N8/38:0'UK8R-M.OE^?B@GK<]_L?9*.CSS19I'B[TRS5DPH]XZ*@=4 -M'N0J@P[$RZJX07]PA()D$BJ>JM2B14.HY/8P)=2E8[1@\';&"H3/)K\^2;9W -MJMT1I_^!-`'/V15^*=!%]QH43#I-"Y#'9@90N#0PDZ7ZG*X -M0/K*DSL[`\0HY64M4W(^[Q"I"\HMJ\:D/N7K3 -MYEO^MPZJPEH2V,*E=IMWQ8"E;5T[__9''NQO$.S;KOSY&Y?/G:5J#A\^T)?$ -M'+?-WQ$Z`'JWI3Y6^9:>JX)Q";!98%$S/HR**LS"4XW8"A%>9BDORAIC[W%M -MCJ#K];":3B4`,5HG,6OW`)L)@!N][4&Q\=V,!V`H=CUN$8->`C$7%9!.USIY -M%$TS2]-DLCFIJ/U,M32BDU!R@0)&:<1L7G:H>H#$GO#/7J>FABW=>4K(-;FM -M(PYL[]WV;8O,LY8:J2@V$53&XU`0`2]F/"[->8L@I4%MFH#ZVLDC/@T#HOKO -MQ3B_.`*!AW+0>7---V)6VLC%/Q8P(?K*&G7;RPF!6=-6/1=4MNA]7W<>H%2) -M6-5]EI]E8CK>-9?A/04EG"9L'E# -M\;IO)#E1-^C!(ZO0H&NE^W@N(3UFG?:I:3P,"#DQ41-K1@*#QE7;]W+$_3L5 -M:1$\.("#"CK--V!Q34.3GJ5-9SKJQRW^4W6SU*"-9<7U8=SX2)+KW'LG]DD> -M@FUA#W_-)WK%\.&\#-_?W.YZ6Y]/1;Q\5),6=LX8F\5?.%]X6<71?;:-^U4` -MM)T(J'EN".ZP>>ZX>;'B_*JQ3QJN?0<,D.5:AB.FA[E5-=-"@O4!(F^R\05T -M8`E-4F!NS5LV(VL-(M#[6!("]1#8;-@LE^V\4*!U:SXZ5@'PPWSI0M.I+($7 -MSJ._H<]-!AJ7>BW$J_#44W$;-7S9L/8*SBN=U[)6I$)(U6E&\8D6B7@5F\D) -M&:U?,]>Z'[6^8E&1Q91HLMEX-7SQM&/P4;ZH/\AF3]9;CL1[ZXSLI/3,Q,VT -MB6BM;E*X,404UJ]\M,L`_R!NT+M``JB>+=-*+;8++B:CLZTF%IME1)&SI`2A -M_;*=>Z[VZ)([-+/O<-8[!@QP"`(J#I3+6R9KMD;<`B&;;Z,TJ,(47QZEP5>B -MF,0.XPN@FLPW0,#7KZ"_`.7^R-JS#H@@6\3N_S-OWF=^J+!Z-'?M5*ZIA=F_ -M>\[088#:U,JEEAE6PM[PX2+CQS13SL/9X%LXF%Z@UB$T'(ZU?^`SO5Z7\0,%I[8@6GD8'03Z> -M:YJ:R>N%?0Y$_O[6LZ?BNRCA=37A,R/,$<>LH35**HTHR$&\Z]1&[TRX0#S1 -MFB"EU2??5S'ZP=^@VVD@,%Z/3C?/R&5PT(J.4;GTKD;]].XMT8G\F\QQ7:-/ -M`*V+!74(GVTBGJN/LYO[@/`Q8@X9N5DZ^;S[9'("+9I\$R&('_CI04"%BKKU -M$8;RDI/->GO2X-)JR/LL`;#\F[X/ILE)[S,7$=OI49NK*YZK_H[C;(U!AU0$ -M6+3;W"1A!/DY/X7G0J@FVI[_Z2[R?2-YS#=2.A9`\[";'@_BJ_8@ZS3*LW]: -M,0(83P2BHK#=<\)9>-J3&3V.R0MAB;Q=6Y_ON<`S-@Y6*H3UDD7B;-Q2?F:D -M--15N@/$^-]81!-&0-4@?-_7ZOP[4228AV`5VGVSOM'']2\Y?`%?^?![ -MKCTI]H[V7VAS[QX2;5XE["D^I\5[O0AN[!#6.P7H@4W:85X`7W8[ -M7=.^#]'OH0JBCP58C':P-3BIP4#OB?%4K2A;:$E8$C/CN!#!6DB.'ZX&HE5SIQ'V_<&HTDT=.P'>G[9U&,^;,3X:OO_!-[;UQ8*Y/G -MD2]*"H-R3*+B!%(L:9&<`5]0]6`KR/<2ATPN8A]/"#O*.O@;QDQ=:+&<.$@KK)K/PKZ90:#3X^\!S)474V8(Q/S0I%"A^O_ -M6M"EW9EC=(ET]FT[3E=A=OA=@T"KA@8@1@%D[B.60ONF^,$KDWGXGJ3UH-]X -MI=BWT5P*"`/+V$U.1B3$5GB_KM>W%?5S(3F=VO^R-%4K2!/M1[FX7D36Y&Y` -MU-N>@6D:>QJPZTL^/R10SZFD2NF`G*P[3]R(9JFF@KL(4&?!#`/H[O]9-9"L -M3:^?RYBI:*V1)-^@C./??0=5*_(QA_CD1M28HUI#&QI]ZEJUT/KD>I"*2]L! -M?Z4+V/`23D=D.(I+9OSG4D='N_ZD''(6034^793JDG'SP7R:CL_ZBH%@,>25 -MJ5=7-H5])9HT8(:!J;FP?90%OR_EX.&[K87] -MAY:`OJI"ICPI)&/6=._AI"AYHM8V/,87`C'O!0'$7OS -M@##S9B&,,KHM9@::[=#9;TVMYW(QO0T\@SMFFAN!=W/U?VPY41)+4CY[?_!< -MNW,W#U,GY_CN5XY>IV",=Y.8)[W]U8Y;3IBC/^N#/`M#(5#P%Q9L#[.ML0%' -M98I%"`G*I&"M`$`7.D,=)!=4]`>H8M9 -M(4I0A#O\]'3(PJ46Q)-;/K-/`5JN",&%"+Y,<-MWE#2-(%V&#>H\\.RHP.]S0-I#Y>E@%6*7Q6FY#*Q&JJ]UW@4WA+,%QE3PPE$8$AS?0O7E<./2QA"5TV%"1% -M(A'0&.[WUV%$,*3.B*:N"8VF*#AU5\Y^8P3WP#7MPTG)VPP#CY9/>N6R9>0] -M).7-KI?S&LC-D.R0!>&^ECY%Y:#?W#HK,#H:3NE5X;M(Q$^U;\%%EBMP@/MI -MS:[EF^7_SUQJ,Z1VF*;),:QLT]CG4C1\)#W\C'4SBJIEUX-)C!Y\6P -M(ZR)/5`:/6_"!UQPQD"^8):+>OG1JHV,3AV%-NN^6R<&LYDJNT3G3 -M\+,?-^B#/?U[/)WSW;&$JD0^I>"MST3DTA4,92>9$3W*HE3E=<`T^@J]\"\I_1@$8P?LYX2=&>TK(H[IDX%#;# -M/052%71UXW$ZM=B7/C./*XPJN8ZV1+&IG$`.V/A"1SL]X@]BN6$Z\L81365T -MRE8"[=YV)6H9BJD@6Y'F`5@R(N6WU+?]VP^US7$WD/&2?ZB:"W=0;ZN0D^>\ -M7`!WCK\DV`DLQ2Q/].IURR&!;Y6)0XVIZ[_3K%QH@_/$Y=U[T`A"[/A:#NNE -MY(59/4G6UVR]J1UV\>)UAD#/V*:1%61;[\F>802&'<-ICN^PP2FHR>6NZNWNAH27%QM4#+H'N] -M+1^%CG`[:[9>S=%M1$$KOK_]JL0+]6+-:]9>AY=+2U\NR4`C3@E,#WWFW1DV -MA*E'.T5\,EV+<:]-A=X!:+G!`F!(9I#4'T^GFR]6D^Q%CR)L`B!0O)0(OF>\ -M3#U@%O^#US4`_Q_@A8*Z1)7%(ZQ%J?6M-$8'\NG=)!4C`MPGVB3&2E[9$38( -M/3@US1,"70*H&87;S[!UC;\*'*>3B(?@G;I3FAPQHWIU-1Z0<22D_[R=_8I- -M;V5*Y;(S,-]<%<6I`?>M!6@.'?)8-U\$.QK9/5Z)QT[JDIIW?/5RJ9([\+W2 -MZ_3!GE7JO@]RBM/C]\_O?J.*]M2KMQB-5/.3<1`\H\RQ2O(7,09O0?X-9*[Q -M"B#HGK\B5.FYNX:5QE+7C!.:C]9,$[KPXR#I6LR2ID1EJR/,)OW%AE7[+>'N -MI%$H907$J5)49IXH#DNA! -MD--=$KY]0&N]Z'<,+_>A(YZ?YK'4`@,^:N?-3@A)

    ;`2,&](DA-\+6/.WM!X0,.T8[F'-?PAX# -M0L?`J#M!ALYFK*I_(_P^(Q^*W4MC((OYFP@Q7RI'W1*IR/8R(\7-A%IZ-S@\ -MXSB/G*3=?/Z5S;*RL7+@:#=0M/.;(5EFT4!R"M6A)YM3U(/+>OG_0)M[[CD' -MKM;*8UGWC!D5I7GPX"@?!$[RK_+AR7;=O/-/^T]&OE?RM_N%..M^T95Q0#0\ -MLX%LA(05LDBT2UJ5(0UFL[6_Z_F!KAW@2!A^I25>BAF8XNXG -M1V?8;M,'%TZRVV\0*!!4NFVG!A*@'_(WU'=8.7<%)XI3^8.N4#3-LW<(^ -M*PNNKKY&I/3Y69"B2=V.W0$BTD>3S$C1F]!T0QNDP8:;Q&S7*`?G+GU7=_HND#LS58$JQMGR`RT81!J8@XZ_.D1)<0IUO8.'@9I!6#.B. -M@\2WO'G4NP,5N?JT?0W.,UZ70[3%(UJ`O7%!5$22^4F[&9A=NZ6TBP+L9@9" -M"H[/I;A2*\Q1P/1T$NC@$PKB]0_9N<:]Y_5YF=&M@6/R>6/2MHA];6.[EQ*D -MK'7!P6?8PN@_(N5PRW4M[A=*#X?C&5;-3"82;2VM]46--D'^+$N0F$A"2OC'&8LCB[,0TY=SP11Y57AOOV^%I^QJK?+.UP8 -M6?:'9U*'*1*QYX?:[&[+X.[@RD*A6BUDW09G'33JZQ`BDN_F>DUYP9I,OPM5 -M(RBT/&BIEIJ4=,;#2^`:VZ#-,]NR[!KXDKC;3:7X8P"4(L15=&/WYL#*W>/V -MG'18))_@*80Z!3QR?DN05D#)$320O#Y)4\.0PME&.N1IZ2Z[0.6,!.E_O&L$ -MG!\UWULP8^IW_W*.O^UK'OW(!GTU@G!2HXZ0YR8\"5X4"9VB,\N_ -MOW&P,^];7*Y8BC#P&JV0`/>4<&2-$=^4F(\\3:!!$GN9 -M\NG!"),B+35?.J0@)Y*##"4/2%SV7__/,;8;Z8*ZER_S`T"%S]_1Y)V+]!Y_ -MYNOOV%+(QZ$;\V7^GU3T'%X7^G1LFW(5`")S?)"ZY"VV:08!;)=@B(-+SEYB -M>#7ZHN301+UFJMH#DYKTH[>)I9&`C=>KV_/B#7D:0-N\#.;BQ_"`/(V!RGSI -MR[40/"&/U'JB=^Z5#$^R7Y]0M$,C@IUI.^P9"M/E.!0:<+PB^_"HD[GI;X@0 -M!52M![84"KTU*3'MZ+]@[691I>:X,(S1@ -ML>4$U%7Q27("H2^J2/)`M#8JV-8RYP!>[=8*0']+B3"R`]S\$&'I[0&>VGJ/ -M/Z#RNQ[F8X:I?;P$W]IRSJK$>+\C);]&ZC\H)O`Z0%$147&IK..R.I$_2$F' -MO4Z&,&YMVP"L"NN@2A[A4@,<++T))G&/^,->Z=^M%4\?_XMNBLX)8[M[OCQ@ -M=T-BJ@TLP)[ -M;CV!F&@YN@:/VR=*&U%T#0?T&(IO2FJ\[Z4/$U_V.-/CWO:U%S$^H^'*,TT? -M@<.0:LH+MP*>KD;02H58$)9VW7P-"KF-1GE3;R>\O-OT,^*G\*"IZP2X**1: -MT0,F#J_QAF3-NEOTO8S'(<(O@7*?,K;)3:_.K")@Y[&;IR,@;[^!U%*\GK\E -M2C.G=3..B8KJC10CDI@>4&73_CW0]^&VUKU1[`&`HZ@FVZ;ND%:@.,-9#Y7< -M-.#4)^^EZV=?7$354;O:D0/>?3'&47!!571?:./5N/XE>@F.?7-[6!=B*`M=`Z$8%(-8-MW:$_2WB@12SV,!$P%(&!H8H]UNM>=5G_>GMN$W^Z"FG -M<0K1N@P[_@-TO/DJ\A%7@G4OM^Q$H?[WG%C:ELB$M2UE.U1TB-<2`$MI``@*- -M5,#;]1%S1$241WG.SBJ`BR#5(6DTF==42ZA2[68+0#VN]'1?9M,"GM\^H?YH -MC%GH&!'GZO1K+PXY$#[L'=6"?)X;W`*9`Y@,]D;/:Q!0=N5<#[GTIVWEJEC8 -M\[!OMKUNS,/N1"OO+W"";$9\Z;+12Y,R8K-!+T&2"WU>G:_7T06IGB@@_7DW -M!>A]`\3>"Q_TV&9=`==*MAY?RR@5EWM<:)>2FTKEV -ML3[GSW>S3=>[2EP!F?F5].N/*_(2^GWP`26*S=3`%0F`.WP5V0YD/1K:U"HC -M3ZII\^%@FE@I2)LKKWMW-YR+EB\H%MFF$Z3TL6= -M+K;Z>EJ=G'VZZXPR,<`K^]F89P%*8%S6#J`U836CGIU[P(?7^!3\ND`<4K(\ -M]:.KX3O\!W!IOYK"K0U9,D=!270*T)?GU?,L>)1T_C#3D:*Y!ZOJCF=HX[(" -M/=Q('%YX.:V!PQ;U2F-"BH2P6$G%6_(8MGO:)Q,+8HOM:<#%;JI -M:XVG-%^\G70`LFB5>24!<]N?^%?.W>?&FEGA+BVC%.6/"P'=<%K^(8BM723" -MY!&*Z)<>^ZY-6S?QB"43$Y)C'A@^B?`L!/@D0=H2\$*ALMV(&' -MFV6)=PC[[8>!84`9(:STD8TW:;/N"4IM]U'9FFL>I^J:4Z\H[#?Z^6N%/DU9 -M(7[NY"SF+V?$N@_G'(RLM'2%V423A3XFY/&WRNZN\;$068UBMF)8N:(UC]IVTWBM^BL*VR8D4QJW4$QD_U[52VC -M"%QYQ4[-K9V43U]?W:O=!2%]HR]6LK.PJW?1)P*GUO!"(`("4TT2J>0ATND -M>DE7.D9-SW.K1*E7"&6:.`L]6\VIH4\*X7^3`:8]QC*\!5D0!^J_ISZG0#N\ -MGQQ,IU?*50;I4)#T\'?YR@V1BQ=60^[1O,2+1H#8"=C#Y3LW7N@MW!SP*%J8 -M_@P5B)OD.V5P7.RZ%WV\H@]9%1V_`F"B&OJR[^HYP--,N?N;GQURPIU6.FOO\.I1(?[.E30]7RR-;7I!WDFM?A&%6/]XI^F-Y0WM[M'EK#-D&S`21RI -MQ7'A!P"94]4RS6L)AL,(7HDW4MV6`WI8::90W2_'8W3!]BN<$S/K.C41\9X'YTAYYA1FV;&*)%(TH:U6;@.Z -M<8OS'A4H`]7>7I!K&Y9ZHA)^,MAL^ -MH9N'U(G(ZWF-;_XY*SYGB,.Y>U$YY+Q(RAD1V7>6.^[".?8P/1(CWBCE?Y(> -MY,GU*$9P=9_V/$Z=-?VD3'O#F,=`8L-;(QJ&YM9O\J>)E(DC[J\"@;>0*'84 -MX\F2Z?,:(*3,Q'XET;J]O9N2A43DK -MBK`!N"+>+B2YC?G8OJ&,B19LT2$JA6T7*;$CKV,`:`4O$!RQ*%J\BKE9+1TN -M^:'"LO%,25X$Y]T.A\29P<3%IL!7&7$!3B!EPWTQJ8.WV,[9)FOF&9B."!^E -M;KJ*DR_G9F*(VN'K[\;%#\:RW60'%5-5;W@OFSL";N--CN[0J-M;O/@/0GS>MFP;N( -MTX785X)P#R%J$SN#YTE5K6CNQ8<84!T(/']&.P,<=I3^O86VP?ZA=Z<@\!L>]8]_/.DR4B!9X/&L&=]N1B5D_196!UGJ\]4%>:I_ -MJ@)>@LN+S]!-?QHT+]D5E_>#D:UYK6.WR(/>([$:3)<4.%I*-@A/IGNY:RS* -M3S2EDLW_2[LV2;LYCM&3\?.=84'RA -MUR=WVX:;A"2DFQ!E8S-I^1<$R`HZWV3?-G]8:Y#,.>A@=`^A;Q?C.V(S=_;( -M,[?6(:F[[");ZA>\H47?VSVG!PA;)3(/MIYZ>'#K`;$8/=OK*W7]Y)+=I-O& -MNZ\B+.&*/D=Z"$T:D^3DO%T1$$``(#(NTHB8(1)H( -MX;#B\$T[$X37,SL]?XDR'KO62?\%3>ST&[ME+XJ(\Y?T?PS9CZ5&,@$E'GCZ -M>3;7RUCFF[GPTS:A;AH>/&+EL;?#K#A^NGCWA>/$M").DS@4PZ3\;T96 -M@VW+?A-+_Q*=HL,2<+\R1G3.#(RC`Z&L]^227?>G]"A%\F]3B5WPD:I12I&V -M<,(N6,.',^$%^X;]L%NZ9H'Z!KU!@+E#R[K1(?M]><;/FQAPLS?>N=XKTYEL -MN-PIY&*VB$-%G-%6-XZNICMSXD6&,EV(J@@.-R`I`XR2`G^,^T,0G++HSITP.5B/&132Q\O0/2LH#C:;Y=.'<;S8>X:KKEX%(3( -M25#P.\@!K]%$*O$UII=CHST9VI[VNC=DB1Y^[X31T*GTG -MV/_Z9@%CORE;KG^;=;SZVXUT#:,W$=9:TO$H%I^!34,9%O3F&AET@#7+XV?Y -M)9$Q7;A@Z'%#;$CF]%6R28_.XCPCJGL@B+^[T@$$!@`!":G_``<+`0`"(P,! -M`05=```!``0#`P$#`0`,P,!JP,!J``@*`3U]DI4```4!$0\`>``X`#8`90!X -;`&4````4"@$``"U#*W&SG0$5!@$`(8!M@0`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj_lzma2.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj_lzma2.7z.uu deleted file mode 100644 index a61aa7033..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bcj_lzma2.7z.uu +++ /dev/null @@ -1,245 +0,0 @@ -begin 644 test_read_format_7zip_bcj_lzma2.7z -M-WJ\KR<<``.X#6P&!BH```````!3`````````-AGR._@:K\I_ET`/Y%%A&@[ -MWP)!,(6+]:YDCG/TF9,6Y4@I6&:W,\L.GXAK)SG^7$ASM;Y]KP;]Q:,S]93R -M>,&)>5<,&FZE"`#6^N9W.O9$'UE^T-50DI_AD]BN$0G/D?)@D^5S4+=>0I33 -M8+60+5WO?S\=&H#(CWK#P8A*.F39U-N85;*`7:QH4MPY]Z"R4@0-G[PN0P/I -M&4U*T@DV'"`CQ@7=GL@J7_2-A[.]&`<]D>$^(9=0(?Z*\Z.%M#RG1BD;5#6( -M4_PL?`47!00BJ=5&HZ7@@B$C!NO::D+1C%8P).\)*UDX0P@<+::RMJNW=<@+:$ZER\IE^S3 -M<>=HCZTGM[:O[2?'(:Q@840D]\]5Y73NXY[]$A&S9_<=T[^)S9E-I@,/"Z%N -M3%P8EQ8N.<>T1U:G?9*=LX1R,65>5\LCE.PG__FU`+L]UUEKFS13]3C4N`J/ -M2*#MK;D6R_YC0[KZK#6ZDVED3OA(WO_#+'G.!7!DNT&:A<:N8%2S1T,0<.CX -MWI?5110E(]/(V5U26WQEEBY"+^%%%QQ*$$LVGS;&M##OO=PE)#7IOV]4!T0> -MMCVFR7A^)`*]D,D*8(TTY<\22+QK022#]K1P8Q>ZDOE"5%*XR1S_RD)#8:OF -MV8PM<:&:XO9&=U7J?O95W3V[0_>S$IA67];6D(/WJJ:Q>6%"L4.3$3?0E!!$ -M%?%!2/7&XB4BNO1`#[FYN$MKM,TL^'./,4GY) -MNO_;YJ7P.<8Z"R!*LK]S`B1=P4X(^JK3]7X8N(%H?=H&K>KB'G7(0C'R=1Z0 -MZ`IBTR?O>DKYV:WR$Q0MRO.CI2E[0;'KUGX`,?^8H_"$EOK=81Z5Z4VZQ'O; -M;O;-'3N/M(@343API(#U5#X1=PK%4)/F?[I"DE\39HS<'P)7H49\16$$ES92 -MA@%4O+Y4AD=?Q`Q6L[^+YH+AJ-Z!]8./"Y'^Q"*$TJ#,%/ESOJCC)X:D@0R_ -M?J)%YC&F):9`]N(:_,O,>0]$-QL,-?ZE@EH7Z=TEA\M7949(]"*65FN\?-CF(U?7P0?R&\DOWV5DVFK[.JXEP>WU1IL?6K&/C -MWJ(7%PM9ZI:B)8)Q$N-53QL+1O[;'7O/7/O^;3JY[WU7(!DWS`YXM'QL?+>( -M"XZ7)FJ3#T4640CH[0Q8U319C-]L^2259=A(C)[[!/*9P+!6MXIH$N)1*Z:& -MQIZ7]E*8%(B.D'_@P=8!H(?*X?N@HB+MAKFN3F][.%W':*1!5I4=/"TFY>,\ -M=4<$EI/)\S[27U*=0/;8!0P4W/=5+RC"*W]L[Z>GIXO;=$L;^CKMC.FK$GA0?W<=3^K@8Y^D_FAZ!W7WZ#.6HO6/_: -MM&X<5E:RAU)=J;SF.%&+0R;V*[FQB?;-D6E*-E9A9B[,4F',0KL8S]AZ3/3, -MAZ!6('R])>:,3R!'4,\HCK1#'3_?PE4$NKGPX,R?.IK6$:/[E%8278\-K\&D -M4\:14"/(J(V,!$2BJH@D@[TOT`^<-9#'>!Y!%G[3Q4L[4EU[56_:"*>E#X'= -ME='@D%RN4=E!\F6P+B>NF-E -M.')J;D/S>](@#H.CZB,"S;X1F.)O-8.%W0+\OBW-QVYBLHRW$*]^CP(Y/U\G -M<3B;CDT0]"EG+*#EDEZI35$5+9SLPO#7YC4( -M/'^E+!1?^*3VBP3&G9$9CU2`[V+^+*?N^CKX/5VXN]BITG#,SZN85C91X7OQ -MC*NK9_X/LBT1D8WVS!OCD4C7_3>4N>6Y[.58AS6TD<_W-2HXTD?5O2$`?JW4 -M#>E1DA(`HQ=#I"0OK1YBL'?/Y$@>3"0_Y+,WS'D:N2A -M4EH3`]F2VFSKLME)Z,E9_,4[!'G+XCO -M\^^`Z\^_!QY_7[O&*@MP8&R9/?%Q"XE@16@O\T+PU]?>]+ -MQO%2RW(E^$A@,C_K8V6Q,(\<*T?3=QQ4D)]CL-8JTO%EV64)I,+2`_,\J._L -M2^N5B1N7PJ])*IU6?/,23U8+;W*OE:A@V<`;](1`&8U>JD6(DW,D!F]^H:VF -M;L,-_%X>,)O/C?JM)C=5^AL,$UQR5IE^&Z1LE"T4OCT2A?W*V(0FZ=[^9O=[ -M0L[DD:O6TE:IM]=YK:4\#5<6Y>]VU@73]UZ689)7!_EKHD0T^P))9P%J]^#P -M><2"YV.%>U#Q<%/(S*4JZ+.0NU!_ZK^5M7!QAIZX:/Z32G6WM(_6?(8E9)/O -MGY..D_/.%.`#A_`A'J3"O.005L(]?6EP;F -MQH7HX1HFCAR1ZQM^6(:4S7GX!F9"T=U-C/O+ -MM%,($IH!`2&G1F-=33R'N8/38:0'UK8R-M.OE^?B@GK<]_L?9*.CSS19I'B[TRS5DP -MH]XZ*@=4'N0J@P[$RZJX07]PA()D$BJ>JM2B14.HY/8P)=2E8[1@\';&"H3/ -M)K\^2;9WJMT1I_^!-`'/V15^*=!%]QH43#I-"Y#'9@90N#0 -MPDZ7ZG*X0/K*DSL[`\0HY64M4W(^[Q"I"\HMJ\:D/N7K3YEO^MPZJPEH2V,*E=IMWQ8"E;5T[__9''NQO$.S;KOSY&Y?/G:5J -M#A\^T)?$'+?-WQ$Z`'JWI3Y6^9:>JX)Q";!98%$S/HR**LS"4XW8"A%>9BDO -MRAIC[W%MCJ#K];":3B4`,5HG,6OW`)L)@!N][4&Q\=V,!V`H=CUN$8->`C$7 -M%9!.USIY%$TS2]-DLCFIJ/U,M32BDU!R@0)&:<1L7G:H>H#$GO#/7J>FABW= -M>4K(-;FM(PYL[]WV;8O,LY8:J2@V$53&XU`0`2]F/"[->8L@I4%MFH#ZVLDC -M/@T#HOKOQ3B_.`*!AW+0>7---V)6VLC%/Q8P(?K*&G7;RPF!6=-6/1=4MNA] -M7W<>H%2)6-5]EI]E8CK>-9?A/04EG"9L'E#\;IO)#E1-^C!(ZO0H&NE^W@N(3UFG?:I:3P,"#DQ41-K1@*#QE7; -M]W+$_3L5:1$\.("#"CK--V!Q34.3GJ5-9SKJQRW^4W6SU*"-9<7U8=SX2)+K -MW'LG]DD>@FUA#W_-)WK%\.&\#-_?W.YZ6Y]/1;Q\5),6=LX8F\5?.%]X6<71 -M?;:-^U4`M)T(J'EN".ZP>>ZX>;'B_*JQ3QJN?0<,D.5:AB.FA[E5-=-"@O4! -M(F^R\05T8`E-4F!NS5LV(VL-(M#[6!("]1#8;-@LE^V\4*!U:SXZ5@'PPWSI -M0M.I+($7SJ._H<]-!AJ7>BW$J_#44W$;-7S9L/8*SBN=U[)6I$)(U6E&\8D6 -MB7@5F\D)&:U?,]>Z'[6^8E&1Q91HLMEX-7SQM&/P4;ZH/\AF3]9;CL1[ZXSL -MI/3,Q,VTB6BM;E*X,404UJ]\M,L`_R!NT+M``JB>+=-*+;8++B:CLZTF%IME -M1)&SI`2A_;*=>Z[VZ)([-+/O<-8[!@QP"`(J#I3+6R9KMD;<`B&;;Z,TJ,(4 -M7QZEP5>BF,0.XPN@FLPW0,#7KZ"_`.7^R-JS#H@@6\3N_S-OWF=^J+!Z-'?M -M5*ZIA=F_>\[088#:U,JEEAE6PM[PX2+CQS13SL/9X%LXF%Z@UB$T'(ZU?^`SO5Z7\0,%I[8@6 -MGD8'03Z>:YJ:R>N%?0Y$_O[6LZ?BNRCA=37A,R/,$<>LH35**HTHR$&\Z]1& -M[TRX0#S1FB"EU2??5S'ZP=^@VVD@,%Z/3C?/R&5PT(J.4;GTKD;]].XMT8G\ -MF\QQ7:-/`*V+!74(GVTBGJN/LYO[@/`Q8@X9N5DZ^;S[9'("+9I\$R&('_CI -M04"%BKKU$8;RDI/->GO2X-)JR/LL`;#\F[X/ILE)[S,7$=OI49NK*YZK_H[C -M;(U!AU0$6+3;W"1A!/DY/X7G0J@FVI[_Z2[R?2-YS#=2.A9`\[";'@_BJ_8@ -MZS3*LW]:,0(83P2BHK#=<\)9>-J3&3V.R0MAB;Q=6Y_ON<`S-@Y6*H3UDD7B -M;-Q2?F:D--15N@/$^-]81!-&0-4@?-_7ZOP[4228AV`5VGVSOM'']2\Y -M?`%?^?![KCTI]H[V7VAS[QX2;5XE["D^I\5[O0AN[!#6.P7H@4W: -M85X`7W8[7=.^#]'OH0JBCP58C':P-3BIP4#OB?%4K2A;:$E8$C/CN!#!6DB.'ZX&HE5SIQ'V_<&HTDT=.P'>G[9U&,^;,3X:OO_!-[ -M;UQ8*Y/GD2]*"H-R3*+B!%(L:9&<`5]0]6`KR/<2ATPN8A]/"#O*.O@;QDQ=:+&<.$@KK)K/PKZ90:#3X^\!S)474V8(Q/S -M0I%"A^O_6M"EW9EC=(ET]FT[3E=A=OA=@T"KA@8@1@%D[B.60ONF^,$KDWGX -MGJ3UH-]XI=BWT5P*"`/+V$U.1B3$5GB_KM>W%?5S(3F=VO^R-%4K2!/M1[FX -M7D36Y&Y`U-N>@6D:>QJPZTL^/R10SZFD2NF`G*P[3]R(9JFF@KL(4&?!#`/H -M[O]9-9"L3:^?RYBI:*V1)-^@C./??0=5*_(QA_CD1M28HUI#&QI]ZEJUT/KD -M>I"*2]L!?Z4+V/`23D=D.(I+9OSG4D='N_ZD''(6034^793JDG'SP7R:CL_Z -MBH%@,>25J5=7-H5])9HT8(:!J;FP?90%OR_E -MX.&[K87]AY:`OJI"ICPI)&/6=._AI"AYHM8V/,87`C' -MO!0'$7OS@##S9B&,,KHM9@::[=#9;TVMYW(QO0T\@SMFFAN!=W/U?VPY41)+ -M4CY[?_!IV",=Y.8)[W]U8Y;3IBC/^N#/`M#(5#P%Q9L -M#[.ML0%'98I%"`G*I&"M`$`7.D,=)!=4]`>H8M9(4I0A#O\]'3(PJ46Q)-;/K-/`5JN",&%"+Y,<-MWE#2-(%V&#>H\\.RHP. -M]S0-I#Y>E@%6*7Q6FY#*Q&JJ]UW@4WA+,%QE3PPE$8$AS?0O7E<./2QA -M"5TV%"1%(A'0&.[WUV%$,*3.B*:N"8VF*#AU5\Y^8P3WP#7MPTG)VPP#CY9/ -M>N6R9>0]).7-KI?S&LC-D.R0!>&^ECY%Y:#?W#HK,#H:3NE5X;M(Q$^U;\%% -MEBMP@/MIS:[EF^7_SUQJ,Z1VF*;),:QLT]CG4C1\)#W\C'4SBJIEUX -M-)C!Y\6P(ZR)/5`:/6_"!UQPQD"^8):+>OG1JHV,3AV%-NN^6R<&L -MYDJNT3G3\+,?-^B#/?U[/)WSW;&$JD0^I>"MST3DTA4,92>9$3W*HE3E=<`T^@J]\"\I_1@$8P?LYX2=&>TK(H -M[IDX%#;#/052%71UXW$ZM=B7/C./*XPJN8ZV1+&IG$`.V/A"1SL]X@]BN6$Z -M\L81365TRE8"[=YV)6H9BJD@6Y'F`5@R(N6WU+?]VP^US7$WD/&2?ZB:"W=0 -M;ZN0D^>\7`!WCK\DV`DLQ2Q/].IURR&!;Y6)0XVIZ[_3K%QH@_/$Y=U[T`A" -M[/A:#NNEY(59/4G6UVR]J1UV\>)UAD#/V*:1%61;[\F>802&'<-ICN^PP2FH -MR>6NZNWNAH27%QM4#+H'N]+1^%CG`[:[9>S=%M1$$KOK_]JL0+]6+-:]9>AY=+2U\NR4`C3@E, -M#WWFW1DVA*E'.T5\,EV+<:]-A=X!:+G!`F!(9I#4'T^GFR]6D^Q%CR)L`B!0 -MO)0(OF>\3#U@%O^#US4`_Q_@A8*Z1)7%(ZQ%J?6M-$8'\NG=)!4C`MPGVB3& -M2E[9$38(/3@US1,"70*H&87;S[!UC;\*'*>3B(?@G;I3FAPQHWIU-1Z0<22D -M_[R=_8I-;V5*Y;(S,-]<%<6I`?>M!6@.'?)8-U\$.QK9/5Z)QT[JDIIW?/5R -MJ9([\+W2Z_3!GE7JO@]RBM/C]\_O?J.*]M2KMQB-5/.3<1`\H\RQ2O(7,09O -M0?X-9*[Q"B#HGK\B5.FYNX:5QE+7C!.:C]9,$[KPXR#I6LR2ID1EJR/,)OW% -MAE7[+>'NI%$H907$J5)49 -MIXH#DNA!D--=$KY]0&N]Z'<,+_>A(YZ?YK'4`@,^:N?-3@A)

    ;`2,&](DA-\+6/.WM!X0,.T8[ -MF'-?PAX#0L?`J#M!ALYFK*I_(_P^(Q^*W4MC((OYFP@Q7RI'W1*IR/8R(\7- -MA%IZ-S@\XSB/G*3=?/Z5S;*RL7+@:#=0M/.;(5EFT4!R"M6A)YM3U(/+>OG_ -M0)M[[CD'KM;*8UGWC!D5I7GPX"@?!$[RK_+AR7;=O/-/^T]&OE?RM_N%..M^ -MT95Q0#0\LX%LA(05LDBT2UJ5(0UFL[6_Z_F!KAW@2!A^I25> -MBAF8XNXG1V?8;M,'%TZRVV\0*!!4NFVG!A*@'_(WU'=8.7<%)XI3^8.N4 -M#3-LW<(^*PNNKKY&I/3Y69"B2=V.W0$BTD>3S$C1F]!T0QNDP8:;Q&S7*`?G -M+GU7=_HND#LS58$JQMGR`RT81!J8@XZ_.D1)<0IUO8.'@ -M9I!6#.B.@\2WO'G4NP,5N?JT?0W.,UZ70[3%(UJ`O7%!5$22^4F[&9A=NZ6T -MBP+L9@9""H[/I;A2*\Q1P/1T$NC@$PKB]0_9N<:]Y_5YF=&M@6/R>6/2MHA] -M;6.[EQ*DK'7!P6?8PN@_(N5PRW4M[A=*#X?C&5;-3"82;2VM]46--D'^+$N0F$A"2OC'&8LCB[,0TY=SP11Y57AOOV^%I^Q -MJK?+.UP86?:'9U*'*1*QYX?:[&[+X.[@RD*A6BUDW09G'33JZQ`BDN_F>DUY -MP9I,OPM5(RBT/&BIEIJ4=,;#2^`:VZ#-,]NR[!KXDKC;3:7X8P"4(L15=&/W -MYL#*W>/VG'18))_@*80Z!3QR?DN05D#)$320O#Y)4\.0PME&.N1IZ2Z[0.6, -M!.E_O&L$G!\UWULP8^IW_W*.O^UK'OW(!GTU@G!2HXZ0YR8\"5X4 -M"9VB,\N_OW&P,^];7*Y8BC#P&JV0`/>4<&2-$=^4F(\\ -M3:!!$GN9\NG!"),B+35?.J0@)Y*##"4/2%SV7__/,;8;Z8*ZER_S`T"%S]_1 -MY)V+]!Y_YNOOV%+(QZ$;\V7^GU3T'%X7^G1LFW(5`")S?)"ZY"VV:08!;)=@ -MB(-+SEYB>#7ZHN301+UFJMH#DYKTH[>)I9&`C=>KV_/B#7D:0-N\#.;BQ_"` -M/(V!RGSIR[40/"&/U'JB=^Z5#$^R7Y]0M$,C@IUI.^P9"M/E.!0:<+PB^_"H -MD[GI;X@0!52M![84"KTU*3'MZ+]@[691I>:X,(S1@L>4$U%7Q27("H2^J2/)`M#8JV-8RYP!>[=8*0']+B3"R`]S\$&'I -M[0&>VGJ//Z#RNQ[F8X:I?;P$W]IRSJK$>+\C);]&ZC\H)O`Z0%$147&IK..R -M.I$_2$F'O4Z&,&YMVP"L"NN@2A[A4@,<++T))G&/^,->Z=^M%4\?_XMNBLX) -M8[M[OCQ@=T-BJ@TLP)[;CV!F&@YN@:/VR=*&U%T#0?T&(IO2FJ\[Z4/$U_V.-/CWO:U%S$^ -MH^'*,TT?@<.0:LH+MP*>KD;02H58$)9VW7P-"KF-1GE3;R>\O-OT,^*G\*"I -MZP2X**1:T0,F#J_QAF3-NEOTO8S'(<(O@7*?,K;)3:_.K")@Y[&;IR,@;[^! -MU%*\GK\E2C.G=3..B8KJC10CDI@>4&73_CW0]^&VUKU1[`&`HZ@FVZ;ND%:@ -M.,-9#Y7<-.#4)^^EZV=?7$354;O:D0/>?3'&47!!571? -M:./5N/XE>@F.?7-[6!=B*`M=`Z$8%(-8-MW:$_2WB@12SV,!$P%(&!H8H]UNM>=5G_>GM -MN$W^Z"FG<0K1N@P[_@-TO/DJ\A%7@G4OM^Q$H?[WG%C:ELB$M2UE.U1TB-<2` -M$MI``@*-5,#;]1%S1$241WG.SBJ`BR#5(6DTF==42ZA2[68+0#VN]'1?9M," -MGM\^H?YHC%GH&!'GZO1K+PXY$#[L'=6"?)X;W`*9`Y@,]D;/:Q!0=N5<#[GT -MIVWEJEC8\[!OMKUNS,/N1"OO+W"";$9\Z;+12Y,R8K-!+T&2"WU>G:_7T06I -MGB@@_7DW!>A]`\3>"Q_TV&9=`==*MAY?RR@5EWM<: -M)>2FTKEVL3[GSW>S3=>[2EP!F?F5].N/*_(2^GWP`26*S=3`%0F`.WP5V0YD -M/1K:U"HC3ZII\^%@FE@I2)LKKWMW-YR+EB\H%MF -MF$Z3TL6=+K;Z>EJ=G'VZZXPR,<`K^]F89P%*8%S6#J`U836CGIU[P(?7^!3\ -MND`<4K(\]:.KX3O\!W!IOYK"K0U9,D=!270*T)?GU?,L>)1T_C#3D:*Y!ZOJ -MCF=HX[("/=Q('%YX.:V!PQ;U2F-"BH2P6$G%6_(8MGO:)Q,+8HO -MM:<#%;JI:XVG-%^\G70`LFB5>24!<]N?^%?.W>?&FEGA+BVC%.6/"P'=<%K^ -M(8BM723"Y!&*Z)<>^ZY-6S?QB"43$Y)C'A@^B?`L!/@D0=H2\$ -M*ALMV(&'FV6)=PC[[8>!84`9(:STD8TW:;/N"4IM]U'9FFL>I^J:4Z\H[#?Z -M^6N%/DU9(7[NY"SF+V?$N@_G'(RLM'2%V423A3XFY/&WRNZN\;$068UBMF)< -MFD;<":E*@8N:(UC]IVTWBM^BL*VR8D4QJW4$QD_U[52VC"%QYQ4[-K9V43U]?W:O=!2%]HR]6LK.PJW?1)P*GUO!"(`("4TT -M2J>0ATND>DE7.D9-SW.K1*E7"&6:.`L]6\VIH4\*X7^3`:8]QC*\!5D0!^J_ -MISZG0#N\GQQ,IU?*50;I4)#T\'?YR@V1BQ=60^[1O,2+1H#8"=C#Y3LW7N@M -MW!SP*%J8_@P5B)OD.V5P7.RZ%WV\H@]9%1V_`F"B&OJR[^HYP--,N?N;GQUR -MPIU6.FOO\.I1(?[.E30]7RR-;7I!WDFM?A&%6/]XI^F-Y0WM[M'EK#- -MD&S`21RIQ7'A!P"94]4RS6L)AL,(7HDW4MV6`WI8::90W2_'8W3!]BN<$S/K.C41\9X'YTAYYA1FV;&*)%(T -MH:U6;@.Z<8OS'A4H`]7>7I!K&Y9ZH -MA)^,MAL^H9N'U(G(ZWF-;_XY*SYGB,.Y>U$YY+Q(RAD1V7>6.^[".?8P/1(C -MWBCE?Y(>Y,GU*$9P=9_V/$Z=-?VD3'O#F,=`8L-;(QJ&YM9O\J>)E(DC[J\" -M@;>0*'84X\F2Z?,:(*3,Q'XET;J]O -M9N2A43DKBK`!N"+>+B2YC?G8OJ&,B19LT2$JA6T7*;$CKV,`:`4O$!RQ*%J\ -MBKE9+1TN^:'"LO%,25X$Y]T.A\29P<3%IL!7&7$!3B!EPWTQJ8.WV,[9)FOF -M&9B."!^E;KJ*DR_G9F*(VN'K[\;%#\:RW60'%5-5;W@OFSL";N--CN[0J-M;O/@/0G -MS>MFP;N(TX785X)P#R%J$SN#YTE5K6CNQ8<84!T(/']&.P,<=I3^O86VP?ZA -M=Z<@\!L>]8]_/.DR4B!9X/&L&=]N1B5D_196!UGJ -M\]4%>:I_J@)>@LN+S]!-?QHT+]D5E_>#D:UYK6.WR(/>([$:3)<4.%I*-@A/ -MIGNY:RS*3S2EDLW_2[LV2;LYCM&3\ -M?.=84'RAUR=WVX:;A"2DFQ!E8S-I^1<$R`HZWV3?-G]8:Y#,.>A@=`^A;Q?C -M.V(S=_;(,[?6(:F[[");ZA>\H47?VSVG!PA;)3(/MIYZ>'#K`;$8/=OK*W7] -MY)+=I-O&NZ\B+.&*/D=Z"$T:D^3DO%T1$$``(#(NTHB8(1)H(X;#B\$T[$X37,SL]?XDR'KO62?\%3>ST&[ME+XJ(\Y?T?PS9CZ5& -M,@$E'GCZ>3;7RUCFF[GPTS:A;AH>/&+EL;?#K#A^NGCWA>/$M").DS@4 -MPZ3\;T96@VW+?A-+_Q*=HL,2<+\R1G3.#(RC`Z&L]^227?>G]"A%\F]3B5WP -MD:I12I&V<,(N6,.',^$%^X;]L%NZ9H'Z!KU!@+E#R[K1(?M]><;/FQAPLS?> -MN=XKTYELN-PIY&*VB$-%G-%6-XZNICMSXD6&,EV(J@@.-R`I`XR2`G^,^T,0G++HSITP.5B/&132Q\O0/2LH#C:;Y=.'<;S8>X: -MKKEX%(3(25#P.\@!K]%$*O$UII=CHST9VI[VNC=DB1Y^[ -MX31T*GTGV/_Z9@%CORE;KG^;=;SZVXUT#:,W$=9:TO$H%I^!34,9%O3F&AET -M@#7+XV?Y)9$Q7;A@Z'%#;$CF]%6R28_.XCPCJGL@B+^[T@`!!`8``0FJ!@`' -M"P$``B$A`0@$`P,!`P$`#,#`:L#`:@`("@$]?9*5```%`1$/`'@`.``V`&4` -<>`!E````%`H!```M0RMQLYT!%08!`"&`;8$````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bzip2.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bzip2.7z.uu deleted file mode 100644 index 07d231ef1..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_bzip2.7z.uu +++ /dev/null @@ -1,37 +0,0 @@ -begin 644 test_read_format_7zip_bzip2.7z -M-WJ\KR<<``.O"&:?B`4```````!&`````````%\J8&Q"6F@Y,4%9)E-9W9C" -M^0`",E^``!!`]_H]/^__X/__W_!0!>&V6UMJ7NU;KNQ4EW6ZT)32$R9`3*3T -MFIM-,*>H/)J:/)/4!ZGJ`"43""FC23]2&@-`&@``!ZFT`)3))E,AJF:GM*/4 -M'HFQ(#0`!H`!P``,`````````)$@C4TT94S94TT;4-``````4/DD[A^'IM)O -M4?;TRQ^=[=^`4PYH41W1A=WR^]==U?7AJZT?W^$+2+C,Y+0@8D][(7^]64YE]_LI/:HISLZ?Y64ZGYC@P -MS*=_?2LN-UY*JV%5P0;L##"6UP:G==&QL\DDAK:=U6@2DV*#;7U,M*%L[[XG -MED];.U`1615GK$ZU;&)0DY.CIX3F4>.3Z=,88NYAOA`BGC+*-U\EMPS.A2K. -MEGU+H86+IM8H0T:(D98'LKYE*3>>"SC9UCCY,<8BN&W=; -M@J9@5.CB/?6G/Q73=1SS;,-N0XZCUB'NH?O;1=NLIUMX^,BWPF> -M)[2>L'[WKK9_:/=]JY3JCFGX'>H7>?:5AV&%5UB1\I^]NJI76^C0HZY!(XT; -M+Q/HJ22Y6GFO$2JJJH4&@ND.36VTQGP,W[C-QR/;LY#@J&9OG=Z>E9/?PPM% -MY6C"U%C@82X'(C=;T40TA%@UT65V&A:0,$%,%E$W5Y,:.EQ)5Y!9R%Z$?H.5 -M-V>CCZB?'#'8^93`*&+HSY..MS.;&:PL[0R==&-#V,E-L*0J9W`\E6I57)DH -M-ECDI8S*">01&1AIQY5B5-%GHU12>*;9%=022."#&9&+:D\;HNT')3 -M><"$.%[1,";-,`U*&V5L(8\MA:Q"3>H'$J'V4O8WH;D=)4QSG(8Z"$JUG93TP'1Y(T_F5=HH87RNA2B>,\-#E\K`W$M$C-F8P(9.8@EQD(A]&_(&SKWPETM(:8VG -M.$V)@?(G(S>\1ER":3^\P@4L]2S#_;.%]PBW$?5:%TUZ8&M(%6$F%[CJWB&) -M>'ZF_-`B.ILR9Z.Z,@[I1F8I.ASC<[L9L6CBM\LT@O*$&<"#A/@0D8X2FI0MI>6 -M3M-W2RD4-Q%U0:-[!&`R&MSG,,:2BKDDD[1U( -M-B9%;RND4Q&Z_/<&)=.:(5!$FD#4X82S4(D"&3&WV;7\*G*M1-39@QS_\7FPNRIS`$5!@$`(("D@0`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_copy.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_copy.7z.uu deleted file mode 100644 index 2429834c2..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_copy.7z.uu +++ /dev/null @@ -1,7 +0,0 @@ -begin 644 test_read_format_7zip_none.7z -M-WJ\KR<<``-!QGV(/`````````!"`````````(/;BV,@("`@("`@("`@("`@ -M("`@("`@("`@("`@(&9I;&4@,2!C;VYT96YTN;;\I7YC.>1BQN+EC0JP:,/8'I^CO'+,+O1BT_V!J25R+>!(6$RN.N7/`:E<835()Z+\30 -M7HIV[7[>>JA7V-Q4B,BA%R4UM#?HQF-[B9DE>M/_1#ICKKVX_%8F!1KJ*HFC -M3WIYZ-+^$,6\V``````7!H""`0EZ``<+`0`!(P,!`05=`!````R`R`H!@8KI -#-P`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_deflate.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_deflate.7z.uu deleted file mode 100644 index bf4f051cf..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_deflate.7z.uu +++ /dev/null @@ -1,36 +0,0 @@ -begin 644 test_read_format_7zip_deflate.7z -M-WJ\KR<<``/.MOKA/@4```````!&`````````#5T;:VU54MSTS`0OOM7[`W* -MA/`:#CR&&==1&PU)'&P'Z*DHMMH(;,MCRRGAU_.M[31-&08X<&CCR+O[/797 -M23::>VZ#` -ME.(^H0L4&_FA'A:9OI;TAUBKI -MQN0YU1!KKG9D'#(3+F+SW-YP5=-XIG2ZS*#563A3%*HV/_2Q,1VOMADXW)?< -MO/'X5*4.)P<)#>)N*:-!-1V;3EB$5FWW`^X=&H]#]5M/=5C\Z]FW@ -M=H`"Y<;N\2!\F$9;\W.E:N;`&/3B<9JK%KU:!13I:_;IP.M-WT@FIK)[5@^0 -M*-*#7J%VIITR>?,:AW=VX\GP>8GB]6Z<_N8M8UPV;579VEVBIM/U96J+JM9- -M\]NDF]HX?=GH/V<4KM9Z_))/G:J?%,KA''U/_\+,87"J=HW50'<+9%?FNN612&M3N68T3(YJOYO1O-N8%@PDH_`FH\2-R72^HRT*,.)AD6%-T6#;EGT_TXU. -MO_VR-QAW=!%U#I<%5150$;*S+8934K_#/!/= -M[I3ZIC>5J6<:D2R+"P\4=;]IG04;6V%0M[KVG"DXEM=EOT/K+YU>S.I?W?=SWP8/Z`@4MJA6GUP^;DG>?#CBZF80MUO=494B-]_/M1 -M9AUE4PZV=2=K4X(JFUHTH\&'NONTK?,*FYDKDW;"1]W45NBY<;C&>$[09SRP -M'_AW=]A3BRGHW/*0!"WNM?=L3,>,^*H]ZF#1-@X"G!I60ZWM]LZ%AA$:[K01 -M7UO]?Y*\,<=W/B<]L?4PIX7"^AG-Z+K65;TK`(.03&5,<7B6?/(C07A> -M1N%'.1$3.KV@9"K(7R73,'H8G]"7+WZ,B`3)^7(F -MD84RD;](I(A')!?!;#61B_,1G:X26H0)S>1<)@A+PE%7_=E'B0Q6,S^BY2I:AK$@YC^1<3#SY5Q,QIY<`)'$ -M1[%(*)[ZL]D].:<";/S3F>"2+`?9D0@2YCT\H48`+T!D-J)X*0*)!Z@6\R60 -M+T:$Q"!:_?N:6>7@U4DYDP.@N/5:9S(9)4(.@_# -M24<_-T```4!$0T`9@!I`&P`90`Q````%`H!`(#WIL+LJ2.2T-J0XF&*!R-C_.Z=<^_9 -MV1\-3^RE>M;>QXU.A7.TUWJB)`<[&KZ8T]<]&O#7!73=1:O.CH8O%NQ0C7^[)' -MUEN-U>

    HU&)4Q[IZH<^Z^V_Z?J?JI.[UJY8?;3]2E -MG^V0&G.LDQ:JD1\IK:%&/MG#^(D]S&_TD&_K/H]^`'NSK2H6D]N^/=::C6>R -ML=WQ9(MDMK?%8SN2+?%4O_K#7#6EZ]NC$+9GV^L<]Z[ -M@,[[^Z_T>$/R\N?J_!-/OH\G/RYDOB@=N'^M9*K\>4.=*AUX>/6!&7M9D%Q!;M/@9]'B -MH"-+\J'`N)?66*?9YU[*N4N5?KOI-_IZ7=*/["TVO\D_8:E[MQC -M5.[96&D?377]O1DN=HY7^4^RK@X9JWY$BZ:<"TH[*.L\*LW.?X\6P[(=/I3+ -M(V3=[AIE`YV0'X^\(;%>XE*EOCR0Q_Q>:NJ_1HMQJ2F8QG4EU[;JNHZO5^II -MPZ]#SY?U/WRL_M>RDP]E?*?41GY%BTUV;<"MK=S#>_8]_-9/%8?*'-LBX05A -M0\VSUUB(%G-28U\C&"[F9.V7I854;M.VB%KPK5^X6#KPZ*IW_6_D\SAS=HQ3 -M=]_+O-8V5]O&YMNE5DEMM:;Z#)WG9^A]NRN12J5#^]*95+,R1IF+YNOOJG._ -MR^4-$K]*;)8XNEPN6]\96R2V2[PA\::U_R0^]KR'QOY-*M@VUAC5?YR=&REM -MAY&9[?B+"^IO-[$[+>.6M?2FZU73LP=#YXP8R<#*Q_ -M]_;Y0*?.6M-W&>.\O[(+E)GKK5[]X.5``````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````#PIQUK"7$B"*(ULY_$__\O$M2#"@F; -M]2^"&_^"/S0*(MI,,K.;T62R3"::50\>!/6@B'A8!$'0@X('3^)1;QX4/`I> -M5-23@H(?5#36))79Z4EE=P_B:=[2>>G75=7=-36]F0D1(D2($"%"A`@1(D2( -M$"%"C`I[(U`'L4+=./%XXH<==9Y`_3-D/X?Z5W[7/>=1/TH\EWB0QN<'QK_^ -MJ19KXRK4T$'ZG;8Z=S;FI_&QU+]*/(YX-O$,D-'66%]5J;%*_0KQ=/_V$;.( -M>SID_6R[O.Y'Q&,"\R\`V>Y7M;X_A:0_U-]+\:K>>!V?J+^.QG]0OQW^+YYW -MC(YOXG4=#ND(L(C2E=BV:=.ZV)(#F;+EE&/)Y?'NKN[E7=W)E?%DN:9U+T4U -MT95(QAHCL25&I=^PS8)A.5I^:>QP02LYAAVST7OEVK5KXWW+>U?TZ/PEY6'P-G67TL -MUC&GCX.'K#X>GK/Z!.CIY/2)>`YP^B2XPNJ3X3:K3X%7K#[5.U=D?1H,LOIT -MN,GJ,_#^Y_29^*DR^BR8S.JS(0BE=F]^KH($.A>8.AGO^OCT&.DS`4%Y;HXS -M!;Y$&)W)\QQ^/5Y\QQ^?YE=]^G3)7JX33V>N>YR?UXOSI$6<"X$X*T98_Y7` -M^C=@4QD]1?HC-I\SZ?P90IKL(;">8]@47STH_CA,'9YP;1C]!L7?RUU'IL[O -M8E-(Y^HA&F7B,'7[9-CZG`2#$3[/Z0A?A[GHZ*Y7P_Y"P/X9-H5T&7RI-M]WIUO$.>_JS#JOM=C7+=2GJ,WWQ?T6^7GLVOO. -MG_;&[X86]J]:K/.2:^\[]U:0_JZ%_<<6>?Y!<1IUNX3T/[2OH/U8E<_#8M7- -M,_/_<7_6=I*)(BS600@M8PI'ZX/%%4#91#FKY?/BI*$=%[V6JUFH(96<Z$[1+@FMC`&+A?Z\X1AZHHNW -M$+VF90K-MK4!@;^![`'HM;6"(?1RH3"`+KZ>0$M',LV=Q-4(L75?:M<6L67W -M9B%`;#ZT.[5KQR:4M^T^(+9LI]'MF_>!V+9SS\;43K%GZ];]6](BG=JX5$IFSF];BIDY3:N"/NUE5M+*>5 -M>G@U4_=H?,?`6L',XJQ%C%6/@7F"!%:L^V,<_@7F85-\I]8: -MU6,:EZ&`C$78(C[_M"KSXJ;_.3)6!?PKJLRQ$?PW8_N&SVP-_T%5YOFD=WC/ -M03)VTS.MZCWWROR)]$YL;3[_V<0'25>]YVB9KXZ0OZ/8JK[UKVN7>7I@_6J` -MCV/[X_/?VRYSEV_]"K/_4Y33AO_9=ID?^>=G]G^._#=ZS_$R5WS^,QC_R[2N -M3N^]A\RS1[C^%QO^+9ZC^T'&9)!Q+>#?TRGS>@4D](",ZP'_,Q&9IX^P_IN! -M^^]*Q&/9OT7]W@GXWX[(O'Z$^1\$_%]%9+[7>GZO/B9B:Y/?2R'S]M$`/\4V -M:N]'B.G^5:C^/3^Y#E[3_GWOK8@;]3/\_.]E?U\F%9IG -M^/Q](*W-6Y=*K'#VJ,KX3%H7>)#\-=9?9A6:42&+GNC0>\44<_^.\=8NXV&T -M[K],'7[]4UKXOQE;M_P)P_O_!0$$!@`!"8HE``<+`0`"`P0!"`$*`0`,P>`2 -MP>`2``@*`935E]X```4!&0(``!$3`&@`=P`M`&$`<@!M`#8`-````!D`%`H! -3`#)5M-E?M]D!%08!`""`_8$````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_delta4_lzma1.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_delta4_lzma1.7z.uu deleted file mode 100644 index 750769c3e..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_delta4_lzma1.7z.uu +++ /dev/null @@ -1,407 +0,0 @@ -begin 664 test_read_format_7zip_delta4_lzma1.7z -M-WJ\KR<<``2BP`@-648```````!B`````````'T^3LD`)QO*P@;2+(;6`.G? -M97%G65J_4ERCV:^K1%6D4`M822)8PY*%14J=_<,7#6T/3RFH$9!9G6HOBE'E<0M' -M0-5!6&]I9Q(LNP>FO1,4C"0-HJF]E+UO?$`OP,0L]9]-?IRQ"#_84'^\-:$G -MT3JIHJE5;*\M)]-TIEK1=3?[2#(5!+N!_HL=H!H_R)BU+F9HX\D5.\?T=(M` -M=9=W4SJW579?/KS>1Y+'M^%0#4C+X<'3U$3C&%='!5[\EF[@4#2B9^U]FY)? -M`J8B_0+7B.I$N.X)PP3;'V&J*6VY.!&;Q7R,;M8N$$GCE7A'DD("6>XDN+^7 -M'[7.>5XJAT[)1$"IP%"H\ENNG?(IVD$"4B#R#;E,KWX0"(+I)G\I;FDXUW0: -MG\77W)*"$2C1DY7G2A@X<7?HF<0(324$@RQ94+EXCPV;A\!J_=-IO`PB]JI0O;215>3NFC>&L@A8ZVO8G: -M(Z+'4*>R53SX'U!L=#-R5/?1CX"K49RW+6#"?:O9#&F-VU+]XA>-H/+P67D. -MZN0JL3&7/ST/0,:N;-K'@%MH5*U@'\5C)M\[!]I6*3,C]3NA^OCP?_.^L? -M=17`;X\L"SHC@$#^"05.3&=DUY$\848Q-SC.@/%KQ:P`5J3YZ^,Q\-/Y(6LQ -MP?6TCO52!37-BUF`NWYVMM2?O%GP33Q3P%?#">B/A68F2MV1P'FKVPF);5);K1B -M>8HI`'2@,V/:[^SK\W]3Z;KMD.*+:9B<=!"$;J;;UE5*DM)][UB? -M]6V.JGB<\EVIL3WF^NX79\"D2_^:2*;[&U%K7_@JZDKEF1,3>-*2=:I*Z6Q%6C)N$U>TY[(C`P/L=7ANK-S3-TT\L:SL.T*&Y0>E -M.GQ/D;-/0XPRM5SL()'1_^7U(H`O&?G,YY4X%=>F@:@Z-KF"#'$:)WGH[<$, -M.1GS0RT6+#EYTEZ8W(/*D52"P-B('Z;VJ('L\]V;[3YB+264VOM'M9 -M/U7+D0$Z>XTTR0PP685OJ%/<& -MJ2F(<2MA[/"%RY6$59Q4^<^.2E4`K*^\*=EF4`D<\@V"R2>@9+%ND3R*?DVC -MY?U5RIHO)]4_)8R<3XLHQ:ARO&7:7!:VK==FV^WJ;$;UM<&(,B#=E*6P*"V"T5QBA@I -M!4R$!8.UO\`TE@9K9&W_'H:$?K3:4(%MF):*_OVK^A>=63C@11U@T1I"1Q?# -M6CJRJNUTIW9D'7P=!P341-$$(0GVW+S/D5NL-H62CQW"4(";.>F1#VI1`SN^2//BUZ2!*N-S5?\L%+&&+]KQ%-VW#[C)/0LX@$90T;HK*16"?-10DTO0 -M>).+H4UE!^5"8EZY\AI;S5W!&-W_GR_7YP*YD*]*(84G3+C"6?R[@K<$M+8" -M'9V'M]T:$P]LZQ6A3#<)_X2D.=BY9BP7WN:17-HZ=K8E9V9>'#%.R$L/'`U2 -M%RBA6\@>;DV"%M-2Z_VL]=$Z/^)=`$-)$CDP#?3I3M&Q"21C?*R@#L:;1=** -M>6J6M\$JO&[IM%E1\K(KV#CK]1!0:?M>([H%FUMVGTU,`#D*,+%)&$FT""V` -M3=1]S*'&PDK^6@#Z,&X][V6I0Z^[B8*7P?4_5N'E9`)5*.4!K2G`=(U@/RV> -M"C?],9@_Q]#\G67)I_,)+$U?R>51LS+,1<0/C$RW$8A_)U)K0:!3GQA004^( -M:U*X8T!*T_1#W1V4@6DMD&89Q$$,KQ\3F%!52496 -M3-!]GJ5^KWZP[LWX!PPEUI'YM$#^I_KLT9X0#)6@K!PWB_NF@ -MWT8/RU2Z8]AY4K"=0@6$,M"\?8/]ZFR2&1&`_!3U=IC.6Y0BN!TA.6C(>Y)E -MI%0?'CJGYHT2-)@CS.KV"@Y<=3%Z4N%FE7E--^Y651G3+2.IEL@BMU6O&1?8 -MX45]0!(O%9X!M:1>K`YGV^_O%/GM_5>+640WA4F9R0420YS.DVJ\99T+VE?TO``CRDOS!&U(=)T6!7O'S!QZ!/&Z+KD=FN8U)\$M19IA^ -ME8N&#-K%0\KB=RE(0WMKCWNFP/9(//7_,0.J@:`(8F,M63OAJPG&`F/$\U>\ -ME?3``?\,Q!FODDU".=+F\0>6-QN([3HC%L$7E(5*FNR9B/R`O\&8;<:8U"H- -ML?X;3TE6(>O0>/9T)7AX+(SZ6/D?FA(.D-JE)"38_Z9*0\%&R+`7Y%"/I@__ -MWF;"!AYKPC`NQ$A]4AFT!ZXW6G-CK3HE&(*Y:LP^FG8;+QYXJBN"!P9@CWYC -MNX@XHZ>]I0YW[,6RH'.JY%\J&"UI8,UC!6+9BR$8ISK9U>KC)*JZYH[[*XDY9`UXU/1_KC'"'5G'Y"&QDW`4H^?0 -M0ZOI`F$V4_#7+OH<),CK;&JU[^F#;AL<5FW0%]&2.AG#K,3E8:ZIWK+P[/`-['JND8[[^DAI`"ZV>]]YO#83_2-Z63 -M%G!2V?XI;66V?((CDM$I#793L`;V]-/[,8_!%6_S2H=/G`\M6 -MQU;]^=M/BMU/?,EQBMJY>6@=21H3LPE5LF9XL/AB4+8E.WGE6X2T!O\'-(WM -MEO'%E0`NU;*PKPV$PR-M9Y%1`&/MC941*O9L=CM/9_A8#*38Y6[=4E-`I -M(M2?3[;8&3''0#RMMF'CW$_6L@E1\V%9^U]/F&G=&[-!=R-XO]=I0O55K3CBY:66KWS>^MJQ\9$VL_2VBB\1W1^A>=][1UMIL$].A,T,W?A5IA:W@/'.WAF: -M2*K;Y']X8D/,;&X,YW-(C:O>"*@5_EZP#J]'/X,'`OZU=@2/&;O@ZX(!^?H\7>I'OPXHV(.@N6[6&;7[*G'YH*M+W>S84F&^UQP/>!^$/*J6#8P);S!S3ALHDN3_BL+3>:8#XL,V3. -M:69'F<4LN!:2(9RP#:V#A)'<`%`CMNJ[^WMKOCK^K.%J_T`@RA.`LPH:_W`3 -M-#"&2!B6PZ&30#4F:E.)@1&KRIB,&JIR13OQY'R]Y(%?K\"/VL'(M&JII -M'VO>J3U#_:[LB-JQZ9>*2.D]2_@U1`>CDQ"L3M0W(D09XTJ$>+T)\6[8[0.P -MPWSWY$R7A.VC[]3SC&-%I$,#)0V$A_%KF."AMKSX/IG2T%BRNZHN$2`W]O[,:4=$*F=AM(#HRD(`[!&`Y3>]="+V`@C<5[5D6J?GMYQ<" -MDEL"N&A@L)PW_T=K7L6HBC3@-5W`S9W2DU9A5/'LQGM4*9TW[;#=LDKA[Q`H -M(XK*DP6REW[4U@-<@"%&K4^-I5Q]W>)[+33W#8X5-LY0(6)P"*H]IT$=PL2; -MV7]>=7S>WGG?H%DV>=ROMC->C]68@]YF;!!6F53BEQ_L -M`0$I*5WKS*W7G>]2YHHA1A)DI11RZNU3 -M(HXMRO2C5)*;!Z4_Z_S;E66MJ%"%X@KZ)>2,IA:E+O:9F4EHL#'D0U](# -MZ$1=A(5"RQPB"W:DCM$M957$TTX]?;_"W]'#,6[#T%:=BU%45@G>`(0W8HH;2WP.:> -M7X.^L`0,QC6'QB.4'<:H_;?[HH55KK+ZZ(K(;#4BU/6 -MM]A-C0R[-7?A!\A$XV)ZV<;3>(#PWJ'G`A1H^M73&2TBW80SG"6\;_OXLLVX -MYX"RW]>A3W+`BH'-7?H)$L"JS&0PLA@6NZ_KV+$G$NV'N&&+PN)M'G5`7X^S -MMS8K5ANE%#L&\;1RA3@"QV;B\,S=(VM7*6P.8;7>YK]SQZ5)/T5IW\X7J/F) -MNH5RK0RF!YFU;``:"/K48?)96)H:VL/WCSBK@FI: -MEG7O*9+W1\`4#U^CUUD)[A!W)[`::QDFW6+FWM>5AA5A[NZ/@G]K[-;E=Q/+VX04AU1D3SFJ35+AHSQ.:LL*B@;,;S@)LR> -M(C]7B^7VTH$RLX+1JGD;-V!+R,*5G%7QYY`>AG>9RA"1YQOM]^O*Z# -M^.F?[5K(S6HC:U-CI\J@^=LXH<]U0=.?[:QWLN2_*H:.S/\_)XG%V<6-"3:+ -M\(K_EQVPN-IU^YY=#6Q+')ZE(BAR.DE[]QV?,&/$]UVN:H$VV&H!3S]=(Y88 -M^?CP.6IHOHQ&NT/)MOK%$E90.VO&>3\%W`0*6I@[$&"OKU1/Q,"7YI)EYL2Y461?+1& -MM2<\%E#K*'87RWDOF@X<;E4-LEBB$0?(CH5(ULI^S.D9:)O9D\52XM*N7>?_ -M&UEV@C3$3(!N;`>4-CU_ZCX?WFHBV"K[,!:08Q[@@`Z%).)!O>(H__Y12NQO -MV+%>&TZS;9\1Q@D3WF_'37E%S"6@N;K@^&PS;2PQY\,DRW>;X^MK/*[QW(:@ -M-`IW$&7U>3@IG%W\HDOMTO*UU>->\P).[R-8?@JD?K.5T:8`V,N8_^@0 -MC=YQ'VNPS%3#"4\BVSY5-VJ&*D6Q(C1_0B#@<7A?>/-_Y:F^S;O4J8-0->_C -ME`/I>\%4@M:.9?:,@/`*M6]4[_H#":*BPKM&-*.XBF\WHW,P,D71^62[3?"9 -M0>H01XC.;&/,& -MY1^?\5W9A*]LMIDHV:MDE@%?@SG"L)XLS]6;!X8B-#.%83SI.T-!WH_OZ*]6.6"(DJZB8:+4[# -MBI35;.F)C)J#^-Y1G_\/1-2Z%/^WML]Y`U`(!\%AO+R*+ROH'68P#W$]LNW4 -MN$23ZM0$*FWW>5==F.;B1#(4J&&7G;4?$7KD[4_0Y-S;G`<%O5PS_M[2\-]A -M4-EF1&L$-Q)`*YG38`;^"` -MQ$&?&V04*(>I(MSZJU>0BGD$KM,FR7P5Q[#/HCE9-_]AY)VF?;R%-I!%14OB]F^RU,^&Q-2>*XPN!&O""WQHB?EB7MV -M"*:BJ"UO6@U5(I]FX^]WAR+(*+TWZY(07;Z4;JMJ/35+;LRL*`0;'E87GUX1 -MXXBG5K!JQN^86V)%,-@BZR([\L(;]/"@FT*\#TS]UJ9&="`[]&@CSZ!CU9]Y8>(V&PIMKA*-%[A -M.67]I'72](-.H6+$I]S=NVIW&?Y9CMBGC'^U.[=+F9W5IW?X:BY$Q&7VE5VM -M."JPM-ZU!X?$YEQ#SCP3=H.3WDSV'JL[*^ZBU)2:QC=4$)*LG\18N&6#B&.) -MSF`5A9(^F60I>/Y7)YC:\(HQWGPH1@I?8*&>QP5[T*!'9^EMJ`[I9^%_[>G8 -M.$Y1V9$HT_(QKYGJ(Q=,;J0:<]2/0.4D[5M#XB\("W)S?WHS&%5W\Q0*)24B -MW47>9%4PG-92JL+CJHF("1+\P\??,G2>F"LZR360WKT.5XQDK@/Q@U0- -MMH2GF"N[F,E`U%L/3>U.^+SOM)/[Y!#H8(WNN56"1M)7)+9 -MZX^`QY$)VYV&C4A@5$MV6)N5QO5N[,XFLTN5(_Z/W.V2(MCY_4U9 -MIU'0<=YJOE&61^+4(+]"K%=,748Y;3;C(SRFD*LA,`Y\6%4DL!^'FUY8A-L1 -M'A)`Z#TQ@VO28XW:]>[$--59(S74PX(BG7CH3N:@MK<*!Y5*.77(A@:>[^FTV$+8V(Z[4+?PC-,N^K%$@->=:5KJ:(4\,*H6:W#Q87-,*CL\45D1I -MZ-BH)<:H'4=BMW(;TV+LNXVB`&U-JGZ)9"1_1ZC#T-+E@,QT][:&5UOYS^Q__\X[:=U5C&&: -MYL?V6CRK"/?%X=\K&]FRL\WD*$I@M8W=LTVS@EHN"BH,`&/65-=R2M6F,'&H -M&C=6_(_'8,6H5_55K>K#]2Q$82F7NP1[ULZOQH/Y$K[I-5A!=P?E1?;("/:_ -M=K^,`P316_*N15(@$('MM6YT^>[-&<\01RX!A_]AW?NVY%T;Q:,O8&"A&$\0 -M)C`VM8:WDF"6>H8JHDE&JL1!D]Y:50%*>`?_Y759$N'X8%38HE4P:<'N_DL. -M:E<2\AHV_WNS-O?Z=IZ].=Q$&Y4H.UK^.08H_V6/@LPF2'G2XMK#U]$I7NE[ -M2-ALYI2\T$TRJKUG1(BOH/"JEWN\O4AF3O)O0&J#796>G&/`5Z$/%]8Z(0.' -MS6T2$U5H=9/6>/9UR>'3NX\7\T:9F>I`2[!9>1:[PU"U(]\9DL8I[,YI]IMA -MN,8K3-\IIPCNL;*93)O"Z+*>_K%9]KYKY1O*,IF0@#V6E_:]3+1`>0IHIAVI!\T@MGNU7BK43RFW^X>!9-'$VON:PR,#VU]^!"O6V)V%*\OX -M80:!WXNCD!!SGY!E[,C)SK::L-;*TB7S'WNS62B1&)[PC>U.Z;EA"H16D<#Z -M1"C/>M8$_ZR*#;#\>*DO))@"]4Q;K?[W>?2\#B)9&YH&&1#*4)FXIV_7-.FV -M-EF]2(:P=SUY3G]8)6KO"J'#(.7L'W"^#SYQN!I`DCF4>4-!'`C/*/`%23(Y -M3O=L^=4*9VE-#4"46RX(!\_7L8'%,;'G".''P\#FK=7C#D>*[,3I?%LS=8H6 -MD>]BOWEC@)*B=YI)M;#!]<(!6"SM(`HS*7>1R(,]:S -MIXBX8:"N7'.PR2<.)P=%[(/N6R(C:!=!&D.O4LCN[ -M$0U4^%:/8&>*MF/8G>+`]+D0%1W=LR&O#\BPED>!L%)0@)9C][;4@>XSM\9. -M:)@-;`P;C2R[(9V``#!;2B#!((RQ_=Z6A8FC13AC)KPFS,2C#KC@0,,!=4?R -MNT"$]8]=HQTZL(EN1[58BJV!V[57>%W%7X>JOLBE`M$2#H$]D*^XG5$W&.Z" -M,UMY\(ZZ?PZ2Q8I97T1HY31%^T?DEJD<3B#IQ[R'N(RF;7Y5?FA:X>SN -M(7R,Y(H;,A)1F"=-US`;XC%_I3B;D?T7FD;8![YAU#I-;%CXW7JK^PX\LV7F -MA2=25.UV$OSP6%60;NVVTJ4.A4_NXC%ZG -M@OV7P!"@KL+@[/0U@YU0RLHH(\`D2/S8NE73/1759@?VG-[#^5K)-V( -MKC6BB"B-J9LJ?F(BIO&UP^-/FN6/E+:U3+;`=]/`ZK5#%!T+@O#UKQQ$3>V` -M#?N3<3,8.])L;@N:L%8V -M%G.KOPN7][!"[<'*KR+>`%0ZO_69&2QU.UUBS4>G2\R`)1#0[B9[]O"E4N)/X -M/RH)DT><1X-KU`4F93].H>N,X2VLZ]+;::6/Q72]V6FY42.I'7X@@09-A],I -M3!,:C#/^]1Z>LS"7-]A3=Z.>]>)V>F1T\KH9=\5.07;*4JCJA"%Z`\C>PA3V -MS>5?9UUE[S7/+R7B>K_&UGZ!Y7%0@A(T?$I=:6GZDM:)'2;2-S9/LO8OQ31K -M(M^>-'.XA.G'!TF$BW7LCL,IF@6.0JR#Y.\(P;V!X74=#QH1T0%T%C&SCI$* -M^'_2-=-9JNC"#ZJ",4\]LE*,%0[5'OKA9P\,%&QZ%F -MX`35=#VBJ>BXGVQA2XH#.SYX`),GM0SI9](2TZX1LH!+S*$BXB()*)C5L;LD -MEB6YHX1"HN4=2%H*$Y:LNC^=5-M>#$I5YA)@WM].QN[0];"PJ&F#?,.BVJRM -M27FN=O8,P?\`P=*M!EM!DGG[H_UZ8<,B>%`A%P!,O[/%@[8_5"DYRX51)=.` -M\PHFMJ90"*@XI.^8F,9'T%FYMW\E%H5.4L`XRO\.=X.+42F7Z?%=UH.#\WWG -MJ#_"]0F<4,V6G#T<7-ZA*MP+`CZ:N`KRI$N5NP1N%\2=SNAY40I2%KO\6QHG -MQF4KH'C;5@VCGO(394SKUP$USQF?(B`3ZU:FP9BR)&K,KC1`$X./> -MF-TOJ2C,?Y!9K!B:J`Z''=?RG,I%\TB)I;KUTT-A66=SHB=B`D57L*\B9X:Y -M]7CA-Z&[`7"=9Y`<"1V08NK?,;CS*5A#>0SOT29]?W+:$2WP(IR`6#;7(U"U -M5?H&ZQM#?;Q$RJ0!JKC2I#K3/(!P6;2EU!O,1:,2B%@4-;YL>TXPH0)@I7`P+BM<:Z -MD'A$\_+O7XXGNHD20)0N--U#>LA+8IBW&@FWGG%SU[A%"$$L2560DF&G&SS- -M9'V/_$0KPRN_X[QMJ^@2SK,YT4RYG,Y[19OVYO,1[RM8HV4X+<>8GD%0#9>. -M\[9%/ZMK<@#&:I79^69,&>(IMYR7E>\;$&:&@S;'?%=7X3)7J$BT>)0U_TYQ -M9ZE9!;>)S@$)V(2M7+YD#U6:R9XKNH58$`Y0[?!,!E_%;P$@9M[J4!2V;?7J9KR@DK_5&0Z4D%.>R% -MZ):(=I#:@8@P47-WUYI]GC3)=ZHM-RGW3DV4RF-N:;/ZC;F,`%XF:J3$DR^- -MUO.%(6\"F@9D]+N>"M+.`UPM7OEQ]FL -M=+*8#`?/-V6:^@Y%SEG(<..;Y;(H^$H,G%&\,DFEB?*"!6]@VYG!GOOC!NCP -M3GP'Y[:+1P$N#*F?6(UV)A?.XYS62=)&BQR:)TO^'6L6:O?TNGOHF>AE>VW3 -MQ+^7)L[9\V>8!"AT@0/(5?/]9""`>7U]FAMD(3>IHQ -MFM)CGJ,V"3X.3!Y`BWH9:/`L%%IV03`3"CB*>Q[@>,M.GO%(M,16IR[4N-H7 -M0_F1S`[>>ZR>0L8I041N/:1`ON -M)P)JZ15?2%&?).C&0JD<30`?_:NO=WD!HX_O;?[SFKQE1X-)C%\Z\("^ -M.SP??@UG)[9(>E$''Z.VX4CG=W5`"XDM.(ZO43K*UNWT/9:2?8AT(),]T]8S -M(D-VQM8A9O)O0Z%6U-FQA`CSH)+QSN1O#H]&B%7JS5]TDHP%/><[;6B -MV#FVW&`*ZQGAFSV!#"#H/B=8Q&%J\"SR8@&8R;`P1+6\A(\8QC/%$/.?1ITG^19+V--7 -M7A8J0;PBPT,)1REB/^984W3T;E'-EF6/QO\N<>WJ-M6\MK//H)=__J-E`'17 -M:M=Y]>J5K`:?=";=62H6^%BEO%*IF.JF`/4N_R7<1IW&[@#EJYZ"_S\W<^%B -MDRHSI!"+1=?<+J0,I-+A,Q?:K.?FGHOT-M#2;F\(-L_L:"48C+`"W#!ZU&0J -M^B)6X;P)5=7&#^E5`-:Y>[.UFGM#3X+KP1-W>^F,Q:;@T:YOV?Y]J4CIVM2L -MO(/=LOCHY@R&HP3IP9LR))TK:`OW/A=H4-HSPI."(I`[)R&CI6[4)!1J3"3F -ML;%]WD8X8O^[L1T$1#(2V;+(X&L$\F\8:>>KQ8:IB#.F).O(1L3JB^MW&%F`99/EXP1-^>*@"NT3'^,,:C>*E=#?-$'-P+W*?DFGG+RV(V7Y1DD%^13&2K\[( -MW6&D;*IGQGN@/@75IQI3B\.R$[WG%`][8JZONR"G!MD>;DO`M#S7.#F+2*EP -M\)D<(Z)5E6_\NXRI#.8FPSMY[SR1 -M_Q!M@A"1["=3C!MC$\I=D&4_,LZ6.VB#9(R-0:RC7N#H)8`X;.R(OOI>%0(- -MA^G"&8WSYE=:$LH&KI0R8\A\(245F%S>,>*@!\DIFN2D8>UUFRG,DY/3B"QY -M%R^8%]#BE*SP\LA-J#*BHOP^KL!#4'S@7K:BXOM6>]K(\:Q-Y#9M&:0''!W1 -M2).:.8;W=B;:*A7[8UE/I^#OS#!+K-%75./$>*Z/-R$5FY_2"9%Q%+IGF-,8 -M.*!/U+B49C6!7B9CFH3^#$0IUM\_EL[I;^:[K^$7E\.0B/0U::D"<)>I!H=4 -MT#D:R$E]*;2(U2?8>I2IO<-9=&##O32K$-T=0#`6I@L3"W*;&YZ21.V`TE." -M&42I%D-,[&UY!L>A:]Z)MW,9(#X)6@3*40H\EU5C!:"1]KT_2Q+9W9)HD):2 -M==I=*F'KQUX_VQB00Z2)COJ$;..3>7=7="`"^CY+(%/>)=4@"<1L;*;0`D_2 -M[PS93J2SI=MS)=:M=P`7"*CE@##"6 -MJZ&B:%LTQI65O^3"$0@KN6.+'+98S#SRV?B;N/Z3833[SOG(O]W?(!3SSB'C -MU7R"-#6+C'Z^/>6D/4Z"<\%G;E:.+1#F/4R.=BU3_1&FE**#EX6'J4E?-)\- -M"O*X52TK19<%1A'L$4O:<"H"D;RD[`>S3ARV(4)/F%J;! -M\I$,R!+>M8+'/K3SSZD/"3Y(01+;E1L,G1YU-?,T^"4:!!^$PKA7T[ENIM$P -M]888.#/ZFXZ9Q8&&BNJ]O68EJ^6D12?)S1HDFSH:C$\'LW"DB%7QB;=I$X'F -M,#-2AV!Y:FS]=QDPR51@_7=7,H,P_X6AR#'*VQC$3@?/;KZ@$RT%+>)?!"1K -M5XH^VQ&9SQE^1NL[GQ -MWX4^.,=&6A()!6RP1%Q+U"K)'U8C:BC`Q1"_NKW_Y#R@='88JUY7_"F##Z&5 -M94Q?2'(A"$PQ%%\;_\2:3:ZFA6%?8PY97Y9N;2`+BG@0;>B[[`;7MH$T7XB_ -M>M]K821YHVV6#)5`2CQW.EK4:LPGE.!4J:W#X13RQOA7"NY$)-%M]\R'VH1< -M3GYYF"S2`%941%][8L@\,,VZT\+0#:?FNF'-ZV*->]#M3PN2>M'7ZA!2V*`& -M`J@;^%INM4.S]N+M@TXT9[]P6]Y!3-4\VC^MM)E]GMP)'D+1&R\FAS'C2S,P -M3/SNG2`;)J9(`HJ&#XJ^(T81,J2[H4Y"!($_@$X4!+E0`(:7F_'=A4Z5YLF( -M3L%Q.UKWM%E$$YD<=JZVX2:3`6F2@M(O"&T_"/!5&'-E3=++;:#0D1=?U*_Q -M?]5%7@%IJ3R=)`0TDKU"D=SG"[K1'M5R/710FDWP[',9W$JLL)-,?LK4;\Y2B/&2"XF?9MK[48':8.M^0Y/H-Q(H>00X.;">\'%$"@;DL.)[:*R5]V!W*N4")7 -M**KA;-."B]"3`R4)5TMDL$Z=BUGN^'/UJ.,&N-T:(E$'X"HFS'.(F7U%N@]2 -MRP4&YHX`8\^M)$$[#?U,&WK68/#!.[]+Y`+;Q@DXORL?,"^]*I;[I]YDMX&Z -M2%/6I]O,]R>\&JA^Y%Z@WFL]TMS/VX]*VJQ)FQ>(N&'@$WW7VHC5/ZK,QL3A -M`D[`7@WAN34HL2U:U?I[&O$1^,(-]$6(!E56K&>](Y%IYD:-'L!:.^A][3AY -MBX+Y;0A`W-)")Z^PM!W4(3&M\1K!42/KVXK?&`_#>$(+)N";"DQ;S9A\0%+N -M4LP93U4+7)B];I)0,SR"9^BU"H9H!%F='-GP(=5>U:7@D>ITZG&0SPI9"@:$ -M(;D.M$PIWS]._CP#+!L<&!@K/&QW\>'&\DAZ14_EV"FT0RL9U!;G`.&G$5'Q -M*H<;>XEOE+M?```ZPK@`B.JJ]H]EB+!K>0-;.2-,>[(V1T0-'NIXE'OD%]TZ+>2:"TE?K1#Y:&=@0@ -M0<8"CL@H)5G*2_8GG&B6UN[&]?B)]O_D>2%)UIU_';T.!GV+=4(NH1YJ"5.R -MK6VT]E)]M%&H*,9-H1^S&J)ZD?P@P_=:/BF7`2V0BZ^GV?O#8^F58L:)OPXS -MT#X'.''TMY!JTO-(C6YUWA68@2VX6@+UQB[3#QIZ -MGZO?T9/<_!I,F[MV(=L+3R-@,63-I,1XX>?[N9!BR0=O-Z@&0TW&B7[VM'Q< -MDS,^-V\NCX:D!F;?7Z\6?`J@3-S'Q)>HU"10U;L^^;0'X!N*BLI[`%X^/X;D -M![C/25?/J8J1$PW6D[UJ[C0LV6<(QV*(L-LPG/!,_^\C1J7YYOE_O'>9,LI! -M!@YK6$%OD\O,>HRNU=KFN(7#2U8WTF_PS^*%C+O>-*NN0P0$'%>QQHA]Q;)B -MF*J!C4?H,CAB><5PO"E>@FT0@+VEJY?F.^GD8P28:?QJ`8*GZQ.I9P"V"APO -M/_7RBZ\VNE=ZW.@J4;21,]B$=33[D21X`-]08D;V+'[I4K<.0QLX,D@"9<(- -M^Z#1#-&\.)4[6DX]^@=-;'NT`1.^N@N*LGW&9E>DYBAX4N4\6\T_T'ITL6^= -M83<]PJP560@+SXZ\S++[:V@R[C9G;K"E.R5BUC@BX#X$1,R5]L'*HLO2+(:+ -M8:=@06<]YQA"U&>&7%ML#I?*Y3(SO$1!B`3_+P!X\9GO4B$M"(S=;F;_UU9T*`FOU>O)\/_$4"M@C1K7K^)_4CBMCK0M3B].-[>G0) -MZZVJ/=4.8Z>?(248O?);T8WJAMTCN0[%PTWU[.-CUO'5>4$T75'Q)O5".',A -MGT!WALW&R8DV>TY,J6^NQ?*=BLL^?G,#U3'U;#1NN,RZ7'HC@#5?(D:X!;Y` -M\&6!WI[+ODO46HR("Z.4'3LK^KO&$ZFS,WE?,DYJ>#DK4';BH'!]D&?X]\YC -ML>[%;DF;E$"#%"@M8LQ#H2]K.E2K^Z"ZG8YC$\IN88<0E>>;``"ZH1*XN8)D -MX*'L[KI)>'W6L__0P*T(I_4693<;@A%\-#A6\H*XGJ#/2T46JOAK+^YGH`;F -MI=\"5S -M0"FO5T"UX#J-Y#.SW'\YOS/@H6I('!`YJXDZT&`K$"A7USET[I3/+RU#9]ZL -M6,(TT&9!TY,]1FG=_^:X987GD_2DY[[GWK19QP.39)F7:#P9`&=(.K5Y`CC" -MDWW/9"P%48&0'VD8$%HTHNVG.Q%O]/.<^_)P0J\C(.IAY/;-!]6(=#/O'C2\ -MIBR:31K8@[[QY<;Q\1=A5[QSR"8B2-A/F1)3G$?91>KY_[94@'N33WWK%.M$ -MPR-G$YCMD;W7S[?]<2V4^=NS!V0SG8%&!T-^5&QL]BLV49Q+21RT7-<@&M;& -M;B^Y$&YDVO301F&2C2_?`7=#ZFGY'TDZO;AF9_\9)65?9]V#>`NK:&'^?!"I -M\/W08`7$K?_^S=FA3-2_H.^K1.%[X%VBHIMRS924QBI5M29].U@D[CR>\LY9 -MFCH"/RB?/8KRL7>1K?D;!CK -M2JFRV+?#2"/_X5W]-J('=:Y=YXT>)V*&&^\]E$Z*?W"N+H1_S+2)"H3&@;4/ -M*](.UZR,;LITE-#=%EIO@6%T%VR9)*LCQV=&T_7S%_;%%L_JSSM4YW'=$C^' -M(]#AS$97_A3&IZ"$+':9E%^'7]1?^:'!@U7[Z5$IXAPZFLR^ZC+=0H+(Z&M[ -M4WH0O\;*[V%&.:C-W.1Q;].Z>PWGQM/Y!=`?/+!#[B]:3839+81=@GM//`3BP$']S^^2NH^K"Q[AZT"AK36LR\;WPW."@%Y_F -MT3>FH?8UMQCKAO]LV%%IK2:_C@.;@6"LT_IV2K!2EYX(!K]6027B#J#P4C+; -M[;>%TLKN3']+5?HCUK'Z5Q4DO!61L0H>D4'1^9&M'Q?E"MSHE/-4,=8MJ/$2 -M(C&0OV6H`*50KKOLVM-XB_5>-]==):(Z'$ZF3%COR%=S,7Z7/&9K=3/7>R`( -M#I$$ZF_YC]W%\%J#$%R"/`5#0-V_6S-^C5EV9*;%L)G::QU\GY]D(H@5AC3Y -M4R*.IX/!N"R99ZFT?@3$7D@>P]]=,\#"WTH$EB,Y[H0_0\Z_H<7[Q/<%($H8 -M\RZ3@,Q[!SKSV4]QXCB*3GIZR;M>OZT,YGZ$@?QT<;CSYT4*!!)F9F3-^\!Z -M(EFOXEYT&%J8U<%T"HNK'$9AQ=D)Q90RC4!OJ]-1.Q0EGQ1QY<,QX\A;J2XL -M@(@5#\!`)/)88#'LT$IT?\F8*%_&@1W^N&(PSJ$+<)M[`F@NVC91DB7)+;3' -MZ'K4Q=ZQWU8YRVC_VR;'EA@%8U]=#2G)W(2XE0`AU(\%/OC9H5"/;&7KXE\W -M?.8XVL<-,[,I\)HD=MS=Y2THV(3)!9-(E+.NU.DWMSN]L_/#NVH+?XJSH_0A -M@8%X-`4)9ZL`J_A78C'DF;G"VB"?P$O&ZQ=Q.0%'6P`N\GOZC0*)=4L'JVO; -M[-8=?M`X>;>X'ZO42T*L'SVG26!RP%RFHTXITO7+J8%U_U;6]2K#?8BB;JS; -MT:%^:II9#9NP`&"(M*-G;17!KI]F28/&7+TLGK"6?\4=@T/>TPH$5F(FPD"]OW-9JX@E$!`V0L1:-'V3Y% -M/-P1(CGA/<#AS@)>J+:>E?K,$S=\WS+#W^KIDQ>>YXE80`\NTRO%0%F?DL@O9.'[8HK&NW. -MJ-U"#/7M=^=+H1@.R48J4L&BPI,+7UJ/X%"W]K[%K2*`&5_9387H7!P'SL(O -M@+]D4VV'`$]+\!"'M.FT!@5XVZ(]!$$]4,/;Z90?;94YG%5D(0"PSRIDG(]_ -M!404$.3*!<^K"A^IN?(-?#M2F-U,5_W`(B9E+MTAY%-5CRLQ^(.H*0PW/1R=]4)?8MVX(N1 -MT0'<,8)MN9_Y3_&G!V,YHH$!<_:>=;HA^AYX`KLQ^097HXMTQC-ZPC>!P*W$ -M"G$]P0K%2R!NI6;K??%9@$A?&>7-:<-W1TB;V0]U=$6HT@5@V]EAI(F#:W=T:HH#2G44M_AZS.IHW4E -MQ]?O%PPW9S&1?%5F@JHU@AX5T8$A(L:RP]A41DR`@<;V++D!O'G21X],J*MM -M?8JF).WJU!H'X5:L\?JAF(=`^2:$DW6V=+84UTU>%5_\@:3KH\02U!LM^M3% -M:)_4/GM"^_=M?]=>!K^L\R_<^VU!FDS]Y*,PF>NB"IR@!NVP'3@A*7VA%VA0 -M/XX(;+U[82(4]!.:]?2\SA,3BYL]I5DO5*NB3(N$E=C;.A$O+9(-8HD\<)ZTJP!O#0\LV*%!3*)Z>\KUXQR -M5/VO#I"EAZ6[2^=M@3B4W[`"-+^69K#M*/UN)=P;*$PRK;8); -M*&-+!7WXR4ZW;\2?2X?0M?@77]Y9IGT#LIQ0SCI>G=3($J -M%#M3&-6[J"N'BA1/T*=AW1N\8IXP)ZZ>"CJ;$KZU3-FDZ\:ZZ4^7`\$#-38V!_53T>Y<#VN7TL4!-#1#OSMC -M9Z#15ND>K9:PI@(KN=/GBSH4%S`&]2+3_8^#E\$3OBQWH'MWU6T;\Q=EP@_# -MH>O6BB#6M^"MN3!^=RE]MRZ"VEWQ'$D>@++.[("^\LQ,T*SX`6?\!+7*`*7? -M)]B=1!^YI&86T*6-0.GM[.*7M(>QE[HO'8,%S)947!AAL$+3%*]9Q.>TZLE#68 -M2XK1;PK=54+\A4J[L'=#`@2$XV'.6)DCM7*!+-I=LEGZO'+O3"B5@&=#-MP? -MIXE5:9*Q%S$#0+3OYZ#:GU,#ZA'*H6H"9S#%8='*\L%2)=QG?AB+[Q\CFIQ^ -M&^GX_?+E=EIL_=UM"@F58*?A*`YO`X?O4<#+Z!R`Z#,HD_<@3.W:]T"4_$>3 -M@[.U&%JEV-%KZ(L<-X?*5AEO2#F&@"YXX!=T)Q+HO2*T*,[<[O9VLTVTKD9R -ML:4S"ER16"LL+0(MC&_*DSQ?MZ1.G)2LAFM";J;(RE1>!<$-=GR&6]JN;T/D -M:'#_JP004=/^\0WT`J8T?(V05T_<["1R9KGA1WP@YBF85J;6R"9R^0=;3T6/ -M0L/M7[8S7Y4/B%[:L_-`$'G(#9E<^DS_,HE14SH&;%`F!<8(%[%W$9],MG>' -M-%6S!I<*40F<$$*85-P6Q!9B]&"VU^R&K$LLQF_&\Q^H-?=05=-H&25;A<5@ -MFKGV5>BK_JOD]'8DYH1C&>8?S(X4,.AK7*(0B86_\`T'&'=D62W;(.=92\<^ -MQPNGQ<$QDL>PVLPJ0"Q!71D)]MM!JV?"!,GOMMI+]ZK=85$Z"4V<<8'RT<2, -MX%W@\GJRS/B4_W4XS-8N%.J#$,6LT2)V>X?I3H?*K*83&3J=-<@A7%N'6#QG -M[*XC&=@%O=^!AJZTE$>VCH5%B$,%,,YS!UB3K\:[__U_/?W_L^9=+$0[]%34 -M$%2A`I$X_W$51X*$Y]?)/CQX'%U'2W`E#Z&.'5)\N^35,U"1;LY%E*C6[(NX -MNI%F&E9B(R19Y]:6\_A/!(>;^%9]LF./CM)1G`TT"Y=]=(8/X5N.70L*B$*; -M.8/6-;0\5)V^)[P(ON -MAA0'%ZWQG,!H&+GT"UYVTWI#G'6J:H`LK]COP.Q-+1Q)9N8]8YYYD^I+K;^R -MU`7(;"V/W//3P5I:!AX'0>XL:H`*B*>:.^LA0W'"I5YI;T+Q6+1(%+[VJ+)9 -MN^7\BFZ^U"$2)%5*7BK9-VI2N06O@'1 -M\')`*S#DBK>)L],YQ!G$#2#?*#E+K]?(?@;JW1@]6N1XNW&USE=O`IRR$#%_S(^ -MLQ.?0ZVF@+88#8L>CE[7&[I;2\I2=%DR+MR$-:4QV#A94_)A&,+FQ=UN6_>P -M989E%2:S:SVHZ2#*#`+*,X*NAX>"NF4YS9;V$<#)'L\R_8;51*F1>3X`,L8S -MM]]V4(%%6D1WU\7>+)7*/+EOW@S!/D57QR9#R3M:&N6SJB!B.5%AY20`P\UP -M12;DPNX'ER`G4E,87<\@D(.0#:7.%-H+V'&"M[!JAM&<:4P,F[,3*)CK>5KUU^MZCY>>NH`H'[3A'K]=&Z6 -M!?G>SAB]^W8W0HK)%-\4LG?10`A,G0;XZ]1S'[-7(T^>16]B0LC!;`3D.DEN+^"6'X[=A2O5D5;IU-M,KP^N783S%ZE\C,*\X;@P5X:QV^;T1Y#)%* -MLC@7GEE.\,]*4<[3!;`7GH#8/E]72:C]TCTEL:;387`2P+CB-^H*J!1^[C@4 -M%!55-B[<$[F!I*EX]=<5W0W=NP9ICH*JN4V6O1ZA4Z=4H_&GR`PS1]7GE:AO -M]?39:FOK'Q%GNE)%^FH>-98O$#/U?2`B@GD.G&L4_7`B`41A..V_D!!G3_8^ -M>G^$CBM*_#@W@>@0\#W#5\X1\&C*R#&=EZ(HU`90ZB6^9I*4Z'FH_\,L_5*= -M!$IL#Q7A3S!IYO!P]T5%9EMB7DM:A_78]9YN_[]+RZFJ4V>J@0SA#[NP-D#1 -M:C"-(%KC&'R>WHUS>%I2?_`H,_NJQ.C'4QLJS'XVE\)HT#0_.?[$2%/[!=K2 -MHK47V@L3JAGSL0&6M_HO>!KX61&'6#G;RZ? -M!%%NBHU2-_V7X.*[9ZK;\N0N=9M\=$>EL7#]NHAD\7*FJKU.^E:()]6(2ZR! -M3PPIS`"1YC$SY8Z/])K`#883#9&Z8:`W63_'WC1\^#.6!H\='78>HD(7]:M% -M]K(`0J,F>L/0N2LE$+;>/(89ZDD\U6W+CA<+.S'I_G+-S,*@N,HYR3:4#@,@ -M`MG2V"[EA$K`^P:O`^(.:(.B'FK@-M[`S"I$9W/**,=?C>5;I/!L0OST&X.D -M(&ZI*&\4M8D5B3-S,33)*R>/*X4I<8!V0>6YW'57OY? -M@S$?1(MILODT@KL2K2^^_L(;43,(W==PA>",I\?COZUI5C^UB6&B,[(<^_$+ -MYKU8,9";R/_2@+9D#WQ=@^0G*EM'TC-58)&V8JBD=]VJUMURJQH2=RE]&2WB -MN^;BIA!)ROUGE4Q"T3`@"TK6XT8E,^W0'N<*(4;R -ME=TAXS8SQMYES6>SPIVB!EOVR0I36T/D1_]WL5W#5N<`=^C(QRWIE?N@3?TG -M_Y8__>U%Z?BL^N9Z;F\<Y53SON2&L61A<]!T_4?%:EC9&GU84U/1A-[?4#[-9J%Y -MPD30#+9`6#_G+]%`";]Y\D6(OWXAZ)]]K%`D[B*+H]V2=^]M&[:Y_^L?94I= -M=M2U@)%LT]N%GV]=\A3GBB-K>A2PTBJE%<,<4XPGA)C(/1+S1*(E3&P -MA@6$5)V",Q[0E6;-*E0=*A6T5U.KY^_C66Y'44^BP35>=31^5S>,T3;IH^"$4%^3OM/P796=[G_HXE!"5@1+V#?H6"# -M[49)5#Z-6K_XMB;K;,MGSN_&I4"VT%%A9#$J&FMN>8)_\(G6@-]ERD58.OQ" -M_PZ@>Y'+TPY0Y2T3%TMN/,V\.16J8&X"5;AMM)85SNS$6Q[_8+2A9^V[>0T4 -MZNHACJ&`])R!9R7BFS=:[OL:HPQ@V'KC?/.[0-)\/2GV<5=TTD@X$``!!`8` -M`0G`648`!PL!``(C`P$!!5T`@```(0,!`P$`#,#K:\#K:P`("@$6V^8W```% -M`1D)````````````$0T`9@!I`&P`90`Q````%`H!```M0RMQLYT!%08!`""` -$I($````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_delta4_lzma2.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_delta4_lzma2.7z.uu deleted file mode 100644 index 951da15ec..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_delta4_lzma2.7z.uu +++ /dev/null @@ -1,407 +0,0 @@ -begin 664 test_read_format_7zip_delta4_lzma2.7z -M-WJ\KR<<``1,P\W78$8```````!B`````````-6%26G@:^I&6%T`)QO*P@;2 -M+(;6`.G?97%G65J_4ERCV:^K1%6D4`M822)8PY*%14J=_<,7#6T/3RFH$9!9G6HOBE'E<0M'0-5!6&]I9Q(LNP>FO1,4C"0-HJF]E+UO?$`OP,0L]9]-?IRQ"#_8 -M4'^\-:$GT3JIHJE5;*\M)]-TIEK1=3?[2#(5!+N!_HL=H!H_R)BU+F9HX\D5 -M.\?T=(M`=9=W4SJW579?/KS>1Y+'M^%0#4C+X<'3U$3C&%='!5[\EF[@4#2B -M9^U]FY)?`J8B_0+7B.I$N.X)PP3;'V&J*6VY.!&;Q7R,;M8N$$GCE7A'DD(" -M6>XDN+^7'[7.>5XJAT[)1$"IP%"H\ENNG?(IVD$"4B#R#;E,KWX0"(+I)G\I -M;FDXUW0:G\77W)*"$2C1DY7G2A@X<7?HF<0(324$@RQ94+EXCPV;A\!J_=-I -MO`PB]JI0O;215>3NFC>&L@ -MA8ZVO8G:(Z+'4*>R53SX'U!L=#-R5/?1CX"K49RW+6#"?:O9#&F-VU+]XA>- -MH/+P67D.ZN0JL3&7/ST/0,:N;-K'@%MH5*U@'\5C)M\[!]I6*3,C]3NA^O -MCP?_.^L?=17`;X\L"SHC@$#^"05.3&=DUY$\848Q-SC.@/%KQ:P`5J3YZ^,Q -M\-/Y(6LQP?6TCO52!37-BUF`NWYVMM2?O%GP33Q3P%?#">B/A68F2MV1P'FKVPF -M);5);K1B>8HI`'2@,V/:[^SK\W]3Z;KMD.*+:9B<=!"$;J;;UE5* -MDM)][UB?]6V.JGB<\EVIL3WF^NX79\"D2_^:2*;[&U%K7_@JZDKEF1,3>-*< -M/L@/V:2=:I*Z6Q%6C)N$U>TY[(C`P/L=7ANK-S3-TT\L:SL -M.T*&Y0>E.GQ/D;-/0XPRM5SL()'1_^7U(H`O&?G,YY4X%=>F@:@Z-KF"#'$: -M)WGH[<$,.1GS0RT6+#EYTEZ8W(/*D52"P-B('Z;VJ('L\]V;[3YB+2 -M64VOM'M9/U7+D0$Z>XTTR0PP6 -M85OJ%/<&J2F(<2MA[/"%RY6$59Q4^<^.2E4`K*^\*=EF4`D<\@V"R2>@9+%N -MD3R*?DVCY?U5RIHO)]4_)8R<3XLHQ< -MU*%_PKX_M,LTP$2ITA\+->:ARO&7:7!:VK==FV^WJ;$;UM<&(,B#=E*6P*"V -M"T5QBA@I!4R$!8.UO\`TE@9K9&W_'H:$?K3:4(%MF):*_OVK^A>=63C@11U@ -MT1I"1Q?#6CJRJNUTIW9D'7P=!P341-$$(0GVW+S/D5NL-H62CQW"4(";.>F1 -M#VI1`SN^2//BUZ2!*N-S5?\L%+&&+]KQ%-VW#[C)/0LX@$90T;HK*16" -M?-10DTO0>).+H4UE!^5"8EZY\AI;S5W!&-W_GR_7YP*YD*]*(84G3+C"6?R[ -M@K<$M+8"'9V'M]T:$P]LZQ6A3#<)_X2D.=BY9BP7WN:17-HZ=K8E9V9>'#%. -MR$L/'`U2%RBA6\@>;DV"%M-2Z_VL]=$Z/^)=`$-)$CDP#?3I3M&Q"21C?*R@ -M#L:;1=**>6J6M\$JO&[IM%E1\K(KV#CK]1!0:?M>([H%FUMVGTU,`#D*,+%) -M&$FT""V`3=1]S*'&PDK^6@#Z,&X][V6I0Z^[B8*7P?4_5N'E9`)5*.4!K2G` -M=(U@/RV>"C?],9@_Q]#\G67)I_,)+$U?R>51LS+,1<0/C$RW$8A_)U)K0:!3 -MGQA004^(:U*X8T!*T_1#W1V4@6DMD&89Q$$,KQ\3 -MF%!524963-!]GJ5^KWZP[LWX!PPEUI'YM$#^I_KLT9X0#)6@K!PWB_NF@WT8/RU2Z8]AY4K"=0@6$,M"\?8/]ZFR2&1&`_!3U=IC.6Y0BN!TA -M.6C(>Y)EI%0?'CJGYHT2-)@CS.KV"@Y<=3%Z4N%FE7E--^Y651G3+2.IEL@B -MMU6O&1?8X45]0!(O%9X!M:1>K`YGV^_O%/GM_5>+640WA4F9R0420YS.DVJ\99T+VE?TO``CRDOS!&U(=)T6!7O'S!QZ!/&Z+KD=FN8U) -M\$M19IA^E8N&#-K%0\KB=RE(0WMKCWNFP/9(//7_,0.J@:`(8F,M63OAJPG& -M`F/$\U>\E?3``?\,Q!FODDU".=+F\0>6-QN([3HC%L$7E(5*FNR9B/R`O\&8 -M;<:8U"H-L?X;3TE6(>O0>/9T)7AX+(SZ6/D?FA(.D-JE)"38_Z9*0\%&R+`7 -MY%"/I@__WF;"!AYKPC`NQ$A]4AFT!ZXW6G-CK3HE&(*Y:LP^FG8;+QYXJBN" -M!P9@CWYCNX@XHZ>]I0YW[,6RH'.JY%\J&"UI8,UC!6+9BR$8ISK9U>KC)*JZ -MYH[[*XDY9`UXU/1_KC'"'5G'Y"&Q -MDW`4H^?00ZOI`F$V4_#7+OH<),CK;&JU[^F#;AL<5FW0%]&2.AG#K,3E8:ZI -MWK+P[/`-['JND8[[^DAI`"ZV>]]YO# -M83_2-Z63%G!2V?XI;66V?((CDM$I#793L`;V]-/[,8_!%6_S2H=/G`\M6QU;]^=M/BMU/?,EQBMJY>6@=21H3LPE5LF9XL/AB4+8E.WGE6X2T -M!O\'-(WMEO'%E0`NU;*PKPV$PR-M9Y%1`&/MC941*O9L=CM/9_A8#*38Y -M6[=4E-`I(M2?3[;8&3''0#RMMF'CW$_6L@E1\V%9^U]/F&G=&[-!=R-XO]=I -M0O55K3CBY:66KWS>^MJQ\9$VL_2VBB\1W1^A>=][1UMIL$].A,T,W?A5IA:W -M@/'.WAF:2*K;Y']X8D/,;&X,YW-(C:O>"*@5_EZP#J]'/X,'`OZU=@2/&;O@ -MZX(!^?H\7>I'OPXHV(.@N6 -M[6&;7[


    *G'YH*M+W>S84F&^UQP/>!^$/*J6#8P);S!S3ALHDN3_BL+3>: -M8#XL,V3.:69'F<4LN!:2(9RP#:V#A)'<`%`CMNJ[^WMKOCK^K.%J_T`@RA.` -MLPH:_W`3-#"&2!B6PZ&30#4F:E.)@1&KRIB,&JIR13OQY'R]Y(%?K\"/V -ML'(M&JII'VO>J3U#_:[LB-JQZ9>*2.D]2_@U1`>CDQ"L3M0W(D09XTJ$>+T) -M\6[8[0.PPWSWY$R7A.VC[]3SC&-%I$,#)0V$A_%KF."AMKSX/IG2T%BRNZHN -M$2`W]O[,:4=$*F=AM(#HRD(`[!&`Y3>]="+V`@C<5[5D6 -MJ?GMYQ<"DEL"N&A@L)PW_T=K7L6HBC3@-5W`S9W2DU9A5/'LQGM4*9TW[;#= -MLDKA[Q`H(XK*DP6REW[4U@-<@"%&K4^-I5Q]W>)[+33W#8X5-LY0(6)P"*H] -MIT$=PL2;V7]>=7S>WGG?H%DV>=ROMC->C]68@]YF;!!6 -MF53BEQ_L`0$I*5WKS*W7G>]2YHHA1A)D -MI11RZNU3(HXMRO2C5)*;!Z4_Z_S;E66MJ%"%X@KZ)>2,IA:E+O:9F4EHL -M#'D0U](#Z$1=A(5"RQPB"W:DCM$M957$TTX]?;_"W]'#,6[#T%:=BU%45@G>`(0W8H -MH;2WP.:>7X.^L`0,QC6'QB.4'<:H_;?[HH55KK+ZZ(K(;#4BU/6M]A-C0R[-7?A!\A$XV)ZV<;3>(#PWJ'G`A1H^M73&2TBW80SG"6\ -M;_OXLLVXYX"RW]>A3W+`BH'-7?H)$L"JS&0PLA@6NZ_KV+$G$NV'N&&+PN)M -M'G5`7X^SMS8K5ANE%#L&\;1RA3@"QV;B\,S=(VM7*6P.8;7>YK]SQZ5)/T5I -MW\X7J/F)NH5RK0RF!YFU;``:"/K48?)96)H:VL/W -MCSBK@FI:EG7O*9+W1\`4#U^CUUD)[A!W)[`::QDFW6+FWM>5AA5A[NZ/@G]K[-;E=Q/+VX04AU1D3SFJ35+AHSQ.:LL*B@; -M,;S@)LR>(C]7B^7VTH$RLX+1JGD;-V!+R,*5G%7QYY`>AG>9RA"1YQ -MOM]^O*Z#^.F?[5K(S6HC:U-CI\J@^=LXH<]U0=.?[:QWLN2_*H:.S/\_)XG% -MV<6-"3:+\(K_EQVPN-IU^YY=#6Q+')ZE(BAR.DE[]QV?,&/$]UVN:H$VV&H! -M3S]=(Y88^?CP.6IHOHQ&NT/)MOK%$E90.VO&>3\%W`0*6I@[$&"OKU1/Q,"7YI)EYL2 -MY461?+1&M2<\%E#K*'87RWDOF@X<;E4-LEBB$0?(CH5(ULI^S.D9:)O9D\52 -MXM*N7>?_&UEV@C3$3(!N;`>4-CU_ZCX?WFHBV"K[,!:08Q[@@`Z%).)!O>(H -M__Y12NQOV+%>&TZS;9\1Q@D3WF_'37E%S"6@N;K@^&PS;2PQY\,DRW>;X^MK -M/*[QW(:@-`IW$&7U>3@IG%W\HDOMTO*UU>->\P).[R-8?@JD?K.5T:8` -MV,N8_^@0C=YQ'VNPS%3#"4\BVSY5-VJ&*D6Q(C1_0B#@<7A?>/-_Y:F^S;O4 -MJ8-0->_CE`/I>\%4@M:.9?:,@/`*M6]4[_H#":*BPKM&-*.XBF\WHW,P,D71 -M^62[3?"90>H01 -MXC.;&/,&Y1^?\5W9A*]LMIDHV:MDE@%?@SG"L)XLS]6;!X8B-#.%83SI.T-!WH_OZ*]6.6"(DJ -MZB8:+4[#BI35;.F)C)J#^-Y1G_\/1-2Z%/^WML]Y`U`(!\%AO+R*+ROH'68P -M#W$]LNW4N$23ZM0$*FWW>5==F.;B1#(4J&&7G;4?$7KD[4_0Y-S;G`<%O5PS -M_M[2\-]A4-EF1&L$-Q)`*Y -MG38`;^"`Q$&?&V04*(>I(MSZJU>0BGD$KM,FR7P5Q[#/HCE9-_]AY)VF?;R%-I!%14OB]F^RU, -M^&Q-2>*XPN!&O""WQ -MHB?EB7MV"*:BJ"UO6@U5(I]FX^]WAR+(*+TWZY(07;Z4;JMJ/35+;LRL*`0; -M'E87GUX1XXBG5K!JQN^86V)%,-@BZR([\L(;]/"@FT*\#TS]UJ9&="`[]&@CSZ!CU9]Y8>(V&PI -MMKA*-%[A.67]I'72](-.H6+$I]S=NVIW&?Y9CMBGC'^U.[=+F9W5IW?X:BY$ -MQ&7VE5VM."JPM-ZU!X?$YEQ#SCP3=H.3WDSV'JL[*^ZBU)2:QC=4$)*LG\18 -MN&6#B&.)SF`5A9(^F60I>/Y7)YC:\(HQWGPH1@I?8*&>QP5[T*!'9^EMJ`[I -M9^%_[>G8.$Y1V9$HT_(QKYGJ(Q=,;J0:<]2/0.4D[5M#XB\("W)S?WHS&%5W -M\Q0*)24BW47>9%4PG-92JL+CJHF("1+\P\??,G2>F"LZR360WKT.5XQD -MK@/Q@U0-MH2GF"N[F,E`U%L/3>U.^+SOM)/[Y!#H8(WNN56 -M"1M)7)+9ZX^`QY$)VYV&C4A@5$MV6)N5QO5N[,XFLTN5(_Z/W.V2 -M(MCY_4U9IU'0<=YJOE&61^+4(+]"K%=,748Y;3;C(SRFD*LA,`Y\6%4DL!^' -MFUY8A-L1'A)`Z#TQ@VO28XW:]>[$--59(S74PX(BG7CH3N:@MK<*!Y5*.77( -MA@:>[^FTV$+8V(Z[4+?PC-,N^K%$@->=:5KJ:(4\,*H6:W#Q87-,* -MCL\45D1IZ-BH)<:H'4=BMW(;TV+LNXVB`&U-JGZ)9"1_1 -MZC#T-+E@,QT][:&5UOYS^Q__\X[ -M:=U5C&&:YL?V6CRK"/?%X=\K&]FRL\WD*$I@M8W=LTVS@EHN"BH,`&/65-=R -M2M6F,'&H&C=6_(_'8,6H5_55K>K#]2Q$82F7NP1[ULZOQH/Y$K[I-5A!=P?E -M1?;("/:_=K^,`P316_*N15(@$('MM6YT^>[-&<\01RX!A_]AW?NVY%T;Q:,O -M8&"A&$\0)C`VM8:WDF"6>H8JHDE&JL1!D]Y:50%*>`?_Y759$N'X8%38HE4P -M:<'N_DL.:E<2\AHV_WNS-O?Z=IZ].=Q$&Y4H.UK^.08H_V6/@LPF2'G2XMK# -MU]$I7NE[2-ALYI2\T$TRJKUG1(BOH/"JEWN\O4AF3O)O0&J#796>G&/`5Z$/ -M%]8Z(0.'S6T2$U5H=9/6>/9UR>'3NX\7\T:9F>I`2[!9>1:[PU"U(]\9DL8I -M[,YI]IMAN,8K3-\IIPCNL;*93)O"Z+*>_K%9]KYKY1O*,IF0@#V6E_:]3 -M+1`>0IHIAVI!\T@MGNU7BK43RFW^X>!9-'$VON:PR,#VU]^!"O6 -MV)V%*\OX80:!WXNCD!!SGY!E[,C)SK::L-;*TB7S'WNS62B1&)[PC>U.Z;EA -M"H16D<#Z1"C/>M8$_ZR*#;#\>*DO))@"]4Q;K?[W>?2\#B)9&YH&&1#*4)FX -MIV_7-.FV-EF]2(:P=SUY3G]8)6KO"J'#(.7L'W"^#SYQN!I`DCF4>4-!'`C/ -M*/`%23(Y3O=L^=4*9VE-#4"46RX(!\_7L8'%,;'G".''P\#FK=7C#D>*[,3I -M?%LS=8H6D>]BOWEC@)*B=YI)M;#!]<(!6"SM(`HS*7 -M>1R(,]:SIXBX8:"N7'.PR2<.)P=%[(/N6R(C:!=!& -MD.O4LCN[$0U4^%:/8&>*MF/8G>+`]+D0%1W=LR&O#\BPED>!L%)0@)9C][;4 -M@>XSM\9.:)@-;`P;C2R[(9V``#!;2B#!((RQ_=Z6A8FC13AC)KPFS,2C#KC@ -M0,,!=4?RNT"$]8]=HQTZL(EN1[58BJV!V[57>%W%7X>JOLBE`M$2#H$]D*^X -MG5$W&.Z",UMY\(ZZ?PZ2Q8I97T1HY31%^T?DEJD<3B#IQ[R'N(RF;7Y5 -M?FA:X>SN(7R,Y(H;,A)1F"=-US`;XC%_I3B;D?T7FD;8![YAU#I-;%CXW7JK -M^PX\LV7FA2=25.UV$OSP6%60;NVVTJ4.A -M4_NXC%ZG@OV7P!"@KL+@[/0U@YU0RLHH(\`D2/S8NE73/1759@?VG-[ -M#^5K)-V(KC6BB"B-J9LJ?F(BIO&UP^-/FN6/E+:U3+;`=]/`ZK5#%!T+@O#U -MKQQ$3>V`#?N3<3,8.])L;@N:L%8V%G.KOPN7][!"[<'*KR+>`%0ZO_69&2QU.UUBS4>G2\R`)1#0[B9[] -MO"E4N)/X/RH)DT><1X-KU`4F93].H>N,X2VLZ]+;::6/Q72]V6FY42.I'7X@ -M@09-A],I3!,:C#/^]1Z>LS"7-]A3=Z.>]>)V>F1T\KH9=\5.07;*4JCJA"%Z -M`\C>PA3VS>5?9UUE[S7/+R7B>K_&UGZ!Y7%0@A(T?$I=:6GZDM:)'2;2-S9/ -MLO8OQ31K(M^>-'.XA.G'!TF$BW7LCL,IF@6.0JR#Y.\(P;V!X74=#QH1T0%T -M%C&SCI$*^'_2-=-9JNC"#ZJ",4\]LE*,%0[5'OKA9P -M\,%&QZ%FX`35=#VBJ>BXGVQA2XH#.SYX`),GM0SI9](2TZX1LH!+S*$BXB() -M*)C5L;LDEB6YHX1"HN4=2%H*$Y:LNC^=5-M>#$I5YA)@WM].QN[0];"PJ&F# -M?,.BVJRM27FN=O8,P?\`P=*M!EM!DGG[H_UZ8<,B>%`A%P!,O[/%@[8_5"DY -MRX51)=.`\PHFMJ90"*@XI.^8F,9'T%FYMW\E%H5.4L`XRO\.=X.+42F7Z?%= -MUH.#\WWGJ#_"]0F<4,V6G#T<7-ZA*MP+`CZ:N`KRI$N5NP1N%\2=SNAY40I2 -M%KO\6QHGQF4KH'C;5@VCGO(394SKUP$USQF?(B`3ZU:FP9BR)&K,K -MC1`$X./>F-TOJ2C,?Y!9K!B:J`Z''=?RG,I%\TB)I;KUTT-A66=SHB=B`D57 -ML*\B9X:Y]7CA-Z&[`7"=9Y`<"1V08NK?,;CS*5A#>0SOT29]?W+:$2WP(IR` -M6#;7(U"U5?H&ZQM#?;Q$RJ0!JKC2I#K3/(!P6;2EU!O,1:,2B%@4-;YL>TXPH0)@I7 -M`P+BM<:ZD'A$\_+O7XXGNHD20)0N--U#>LA+8IBW&@FWGG%SU[A%"$$L2560 -MDF&G&SS-9'V/_$0KPRN_X[QMJ^@2SK,YT4RYG,Y[19OVYO,1[RM8HV4X+<>8 -MGD%0#9>.\[9%/ZMK<@#&:I79^69,&>(IMYR7E>\;$&:&@S;'?%=7X3)7J$BT -M>)0U_TYQ9ZE9!;>)S@$)V(2M7+YD#U6:R9XKNH58$`Y0[?!,!E_%;P$@9M[J4!2V;?7J9KR@DK_5&0 -MZ4D%.>R%Z):(=I#:@8@P47-WUYI]GC3)=ZHM-RGW3DV4RF-N:;/ZC;F,`%XF -M:J3$DR^-UO.%(6\"F@9D]+N>"M+.`UP -MM7OEQ]FL=+*8#`?/-V6:^@Y%SEG(<..;Y;(H^$H,G%&\,DFEB?*"!6]@VYG! -MGOOC!NCP3GP'Y[:+1P$N#*F?6(UV)A?.XYS62=)&BQR:)TO^'6L6:O?TNGOH -MF>AE>VW3Q+^7)L[9\V>8!"AT@0/(5?/]9""`>7U]FA -MMD(3>IHQFM)CGJ,V"3X.3!Y`BWH9:/`L%%IV03`3"CB*>Q[@>,M.GO%(M,16 -MIR[4N-H70_F1S`[>>ZR>0L8I04 -M1N/:1`ON)P)JZ15?2%&?).C&0JD<30`?_:NO=WD!HX_O;?[SFKQE1X-)C%\Z\("^.SP??@UG)[9(>E$''Z.VX4CG=W5`"XDM.(ZO43K*UNWT/9:2?8AT -M(),]T]8S(D-VQM8A9O)O0Z%6U-FQA`CSH)+QSN1O#H]&B%7JS5]TDHP%/><[ -M;6BV#FVW&`*ZQGAFSV!#"#H/B=8Q&%J\"SR8@&8R;`P1+6\A(\8QC/%$/.?1ITG -M^19+V--77A8J0;PBPT,)1REB/^984W3T;E'-EF6/QO\N<>WJ-M6\MK//H)=_ -M_J-E`'17:M=Y]>J5K`:?=";=62H6^%BEO%*IF.JF`/4N_R7<1IW&[@#EJYZ" -M_S\W<^%BDRHSI!"+1=?<+J0,I-+A,Q?:K.?FGHOT-M#2;F\(-L_L:"48C+`" -MW#!ZU&0J^B)6X;P)5=7&#^E5`-:Y>[.UFGM#3X+KP1-W>^F,Q:;@T:YOV?Y] -MJ4CIVM2LO(/=LOCHY@R&HP3IP9LR))TK:`OW/A=H4-HSPI."(I`[)R&CI6[4 -M)!1J3"3FL;%]WD8X8O^[L1T$1#(2V;+(X&L$\F\8:>>KQ8:IB#.F).O(1L3J -MB^MW&%F`99/EXP1-^>*@"NT3'^,,:C>*E=#?-$'-P+W*?DFGG+RV(V7Y1DD%^ -M13&2K\[(W6&D;*IGQGN@/@75IQI3B\.R$[WG%`][8JZONR"G!MD>;DO`M#S7 -M.#F+2*EP\)D<(Z)5E6_\NXRI#.8F -MPSMY[SR1_Q!M@A"1["=3C!MC$\I=D&4_,LZ6.VB#9(R-0:RC7N#H)8`X;.R( -MOOI>%0(-A^G"&8WSYE=:$LH&KI0R8\A\(245F%S>,>*@!\DIFN2D8>UUFRG, -MDY/3B"QY%R^8%]#BE*SP\LA-J#*BHOP^KL!#4'S@7K:BXOM6>]K(\:Q-Y#9M -M&:0''!W12).:.8;W=B;:*A7[8UE/I^#OS#!+K-%75./$>*Z/-R$5FY_2"9%Q -M%+IGF-,8.*!/U+B49C6!7B9CFH3^#$0IUM\_EL[I;^:[K^$7E\.0B/0U::D" -M<)>I!H=4T#D:R$E]*;2(U2?8>I2IO<-9=&##O32K$-T=0#`6I@L3"W*;&YZ2 -M1.V`TE."&42I%D-,[&UY!L>A:]Z)MW,9(#X)6@3*40H\EU5C!:"1]KT_2Q+9 -MW9)HD):2==I=*F'KQUX_VQB00Z2)COJ$;..3>7=7="`"^CY+(%/>)=4@"<1L -M;*;0`D_2[PS93J2SI=MS)=:M=P`7" -M*CE@##"6JZ&B:%LTQI65O^3"$0@KN6.+'+98S#SRV?B;N/Z3833[SOG(O]W? -M(!3SSB'CU7R"-#6+C'Z^/>6D/4Z"<\%G;E:.+1#F/4R.=BU3_1&FE**#EX6' -MJ4E?-)\-"O*X52TK19<%1A'L$4O:<"H"D;RD[`>S3ARV(4)/F%J;!\I$,R!+>M8+'/K3SSZD/"3Y(01+;E1L,G1YU-?,T^"4:!!^$PKA7 -MT[ENIM$P]888.#/ZFXZ9Q8&&BNJ]O68EJ^6D12?)S1HDFSH:C$\'LW"DB%7Q -MB;=I$X'F,#-2AV!Y:FS]=QDPR51@_7=7,H,P_X6AR#'*VQC$3@?/;KZ@$RT% -M+>)?!"1K5XH^VQ&9SQ -ME^1NL[GQWX4^.,=&6A()!6RP1%Q+U"K)'U8C:BC`Q1"_NKW_Y#R@='88JUY7 -M_"F##Z&594Q?2'(A"$PQ%%\;_\2:3:ZFA6%?8PY97Y9N;2`+BG@0;>B[[`;7 -MMH$T7XB_>M]K821YHVV6#)5`2CQW.EK4:LPGE.!4J:W#X13RQOA7"NY$)-%M -M]\R'VH1<3GYYF"S2`%941%][8L@\,,VZT\+0#:?FNF'-ZV*->]#M3PN2>M'7 -MZA!2V*`&`J@;^%INM4.S]N+M@TXT9[]P6]Y!3-4\VC^MM)E]GMP)'D+1&R\F -MAS'C2S,P3/SNG2`;)J9(`HJ&#XJ^(T81,J2[H4Y"!($_@$X4!+E0`(:7F_'= -MA4Z5YLF(3L%Q.UKWM%E$$YD<=JZVX2:3`6F2@M(O"&T_"/!5&'-E3=++;:#0 -MD1=?U*_Q?]5%7@%IJ3R=)`0TDKU"D=SG"[K1'M5R/710FDWP[',9W$JLL)-, -M?LK4;\Y2B/&2"XF?9MK[48':8.M^0Y/H-Q(H>00X.;">\'%$"@;DL.)[:*R5]V -M!W*N4")7**KA;-."B]"3`R4)5TMDL$Z=BUGN^'/UJ.,&N-T:(E$'X"HFS'.( -MF7U%N@]2RP4&YHX`8\^M)$$[#?U,&WK68/#!.[]+Y`+;Q@DXORL?,"^]*I;[ -MI]YDMX&Z2%/6I]O,]R>\&JA^Y%Z@WFL]TMS/VX]*VJQ)FQ>(N&'@$WW7VHC5 -M/ZK,QL3A`D[`7@WAN34HL2U:U?I[&O$1^,(-]$6(!E56K&>](Y%IYD:-'L!: -M.^A][3AYBX+Y;0A`W-)")Z^PM!W4(3&M\1K!42/KVXK?&`_#>$(+)N";"DQ; -MS9A\0%+N4LP93U4+7)B];I)0,SR"9^BU"H9H!%F='-GP(=5>U:7@D>ITZG&0 -MSPI9"@:$(;D.M$PIWS]._CP#+!L<&!@K/&QW\>'&\DAZ14_EV"FT0RL9U!;G -M`.&G$5'Q*H<;>XEOE+M?```ZPK@`B.JJ]H]EB+!K>0-;.2-,>[(V1T0-'NIXE'OD%]TZ+>2:"TE?K1 -M#Y:&=@0@0<8"CL@H)5G*2_8GG&B6UN[&]?B)]O_D>2%)UIU_';T.!GV+=4(N -MH1YJ"5.RK6VT]E)]M%&H*,9-H1^S&J)ZD?P@P_=:/BF7`2V0BZ^GV?O#8^F5 -M8L:)OPXST#X'.''TMY!JTO-(C6YUWA68@2VX6@+U -MQB[3#QIZGZO?T9/<_!I,F[MV(=L+3R-@,63-I,1XX>?[N9!BR0=O-Z@&0TW& -MB7[VM'QHU"10U;L^^;0'X!N*BLI[ -M`%X^/X;D![C/25?/J8J1$PW6D[UJ[C0LV6<(QV*(L-LPG/!,_^\C1J7YYOE_ -MO'>9,LI!!@YK6$%OD\O,>HRNU=KFN(7#2U8WTF_PS^*%C+O>-*NN0P0$'%>Q -MQHA]Q;)BF*J!C4?H,CAB><5PO"E>@FT0@+VEJY?F.^GD8P28:?QJ`8*GZQ.I -M9P"V"APO/_7RBZ\VNE=ZW.@J4;21,]B$=33[D21X`-]08D;V+'[I4K<.0QLX -M,D@"9<(-^Z#1#-&\.)4[6DX]^@=-;'NT`1.^N@N*LGW&9E>DYBAX4N4\6\T_ -MT'ITL6^=83<]PJP560@+SXZ\S++[:V@R[C9G;K"E.R5BUC@BX#X$1,R5]L'* -MHLO2+(:+8:=@06<]YQA"U&>&7%ML#I?*Y3(SO$1!B`3_+P!X\9GO4B$M"(S= -M;F;_UU9T*`FOU>O)\/_$4"M@C1K7K^)_4CBMCK0M3B -M].-[>G0)ZZVJ/=4.8Z>?(248O?);T8WJAMTCN0[%PTWU[.-CUO'5>4$T75'Q -M)O5".',AGT!WALW&R8DV>TY,J6^NQ?*=BLL^?G,#U3'U;#1NN,RZ7'HC@#5? -M(D:X!;Y`\&6!WI[+ODO46HR("Z.4'3LK^KO&$ZFS,WE?,DYJ>#DK4';BH'!] -MD&?X]\YCL>[%;DF;E$"#%"@M8LQ#H2]K.E2K^Z"ZG8YC$\IN88<0E>>;``"Z -MH1*XN8)DX*'L[KI)>'W6L__0P*T(I_4693<;@A%\-#A6\H*XGJ#/2T46JOAK -M+^YGH`;FI=\"5S0"FO5T"UX#J-Y#.SW'\YOS/@H6I('!`YJXDZT&`K$"A7USET[I3/ -M+RU#9]ZL6,(TT&9!TY,]1FG=_^:X987GD_2DY[[GWK19QP.39)F7:#P9`&=( -M.K5Y`CC"DWW/9"P%48&0'VD8$%HTHNVG.Q%O]/.<^_)P0J\C(.IAY/;-!]6( -M=#/O'C2\IBR:31K8@[[QY<;Q\1=A5[QSR"8B2-A/F1)3G$?91>KY_[94@'N3 -M3WWK%.M$PR-G$YCMD;W7S[?]<2V4^=NS!V0SG8%&!T-^5&QL]BLV49Q+21RT -M7-<@&M;&;B^Y$&YDVO301F&2C2_?`7=#ZFGY'TDZO;AF9_\9)65?9]V#>`NK -M:&'^?!"I\/W08`7$K?_^S=FA3-2_H.^K1.%[X%VBHIMRS924QBI5M29].U@D -M[CR>\LY9FCH"/RB?/8KRL7>1K?D;!CK2JFRV+?#2"/_X5W]-J('=:Y=YXT>)V*&&^\]E$Z*?W"N+H1_S+2) -M"H3&@;4/*](.UZR,;LITE-#=%EIO@6%T%VR9)*LCQV=&T_7S%_;%%L_JSSM4 -MYW'=$C^'(]#AS$97_A3&IZ"$+':9E%^'7]1?^:'!@U7[Z5$IXAPZFLR^ZC+= -M0H+(Z&M[4WH0O\;*[V%&.:C-W.1Q;].Z>PWGQM/Y!=`?/+!#[B]:3839+81= -M@GM//`3BP$']S^^2NH^K"Q[AZT"AK36LR\;WP -MW."@%Y_FT3>FH?8UMQCKAO]LV%%IK2:_C@.;@6"LT_IV2K!2EYX(!K]6027B -M#J#P4C+;[;>%TLKN3']+5?HCUK'Z5Q4DO!61L0H>D4'1^9&M'Q?E"MSHE/-4 -M,=8MJ/$2(C&0OV6H`*50KKOLVM-XB_5>-]==):(Z'$ZF3%COR%=S,7Z7/&9K -M=3/7>R`(#I$$ZF_YC]W%\%J#$%R"/`5#0-V_6S-^C5EV9*;%L)G::QU\GY]D -M(H@5AC3Y4R*.IX/!N"R99ZFT?@3$7D@>P]]=,\#"WTH$EB,Y[H0_0\Z_H<7[ -MQ/<%($H8\RZ3@,Q[!SKSV4]QXCB*3GIZR;M>OZT,YGZ$@?QT<;CSYT4*!!)F -M9F3-^\!Z(EFOXEYT&%J8U<%T"HNK'$9AQ=D)Q90RC4!OJ]-1.Q0EGQ1QY<,Q -MX\A;J2XL@(@5#\!`)/)88#'LT$IT?\F8*%_&@1W^N&(PSJ$+<)M[`F@NVC91 -MDB7)+;3'Z'K4Q=ZQWU8YRVC_VR;'EA@%8U]=#2G)W(2XE0`AU(\%/OC9H5"/ -M;&7KXE\W?.8XVL<-,[,I\)HD=MS=Y2THV(3)!9-(E+.NU.DWMSN]L_/#NVH+ -M?XJSH_0A@8%X-`4)9ZL`J_A78C'DF;G"VB"?P$O&ZQ=Q.0%'6P`N\GOZC0*) -M=4L'JVO;[-8=?M`X>;>X'ZO42T*L'SVG26!RP%RFHTXITO7+J8%U_U;6]2K# -M?8BB;JS;T:%^:II9#9NP`&"(M*-G;17!KI]F28/&7+TLGK"6?\4=@T/>TPH$5F(FPD"]OW-9JX@E$!`V0L -M1:-'V3Y%/-P1(CGA/<#AS@)>J+:>E?K,$S=\WS+#W^KIDQ>>YXE80`\NTRO%0%F?DL@O9.' -M[8HK&NW.J-U"#/7M=^=+H1@.R48J4L&BPI,+7UJ/X%"W]K[%K2*`&5_9387H -M7!P'SL(O@+]D4VV'`$]+\!"'M.FT!@5XVZ(]!$$]4,/;Z90?;94YG%5D(0"P -MSRIDG(]_!404$.3*!<^K"A^IN?(-?#M2F-U,5_W`(B9E+MTAY%-5CRLQ^(.H*0PW/1R=]4) -M?8MVX(N1T0'<,8)MN9_Y3_&G!V,YHH$!<_:>=;HA^AYX`KLQ^097HXMTQC-Z -MPC>!P*W$"G$]P0K%2R!NI6;K??%9@$A?&>7-:<-W1TB;V0]U=$6HT@5@V -M]EAI(F#:W=T:HH#2G44M_A -MZS.IHW4EQ]?O%PPW9S&1?%5F@JHU@AX5T8$A(L:RP]A41DR`@<;V++D!O'G2 -M1X],J*MM?8JF).WJU!H'X5:L\?JAF(=`^2:$DW6V=+84UTU>%5_\@:3KH\02 -MU!LM^M3%:)_4/GM"^_=M?]=>!K^L\R_<^VU!FDS]Y*,PF>NB"IR@!NVP'3@A -M*7VA%VA0/XX(;+U[82(4]!.:]?2\SA,3BYL]I5DO5*NB3(N$E=C;.A$O+9(-8HD\<)ZTJP!O#0\LV*%!3*) -MZ>\KUXQR5/VO#I"EAZ6[2^=M@3B4W[`"-+^69K#M*/UN)=P;* -M$PRK;8);*&-+!7WXR4ZW;\2?2X?0M?@77]Y9IGT#LIQ0SC -MI>G=3($J%#M3&-6[J"N'BA1/T*=AW1N\8IXP)ZZ>"CJ;$KZU3-FDZ\:ZZ4^7`\$#-38V!_53T>Y<#VN7TL4! -M-#1#OSMC9Z#15ND>K9:PI@(KN=/GBSH4%S`&]2+3_8^#E\$3OBQWH'MWU6T; -M\Q=EP@_#H>O6BB#6M^"MN3!^=RE]MRZ"VEWQ'$D>@++.[("^\LQ,T*SX`6?\ -M!+7*`*7?)]B=1!^YI&86T*6-0.GM[.*7M(>QE[HO'8,%S)947!AAL$+3%*]9 -MQ.>TZLE#682XK1;PK=54+\A4J[L'=#`@2$XV'.6)DCM7*!+-I=LEGZO'+O3"B5 -M@&=#-MP?IXE5:9*Q%S$#0+3OYZ#:GU,#ZA'*H6H"9S#%8='*\L%2)=QG?AB+ -M[Q\CFIQ^&^GX_?+E=EIL_=UM"@F58*?A*`YO`X?O4<#+Z!R`Z#,HD_<@3.W: -M]T"4_$>3@[.U&%JEV-%KZ(L<-X?*5AEO2#F&@"YXX!=T)Q+HO2*T*,[<[O9V -MLTVTKD9RL:4S"ER16"LL+0(MC&_*DSQ?MZ1.G)2LAFM";J;(RE1>!<$-=GR& -M6]JN;T/D:'#_JP004=/^\0WT`J8T?(V05T_<["1R9KGA1WP@YBF85J;6R"9R -M^0=;3T6/0L/M7[8S7Y4/B%[:L_-`$'G(#9E<^DS_,HE14SH&;%`F!<8(%[%W -M$9],MG>'-%6S!I<*40F<$$*85-P6Q!9B]&"VU^R&K$LLQF_&\Q^H-?=05=-H -M&25;A<5@FKGV5>BK_JOD]'8DYH1C&>8?S(X4,.AK7*(0B86_\`T'&'=D62W; -M(.=92\<^QPNGQ<$QDL>PVLPJ0"Q!71D)]MM!JV?"!,GOMMI+]ZK=85$Z"4V< -M<8'RT<2,X%W@\GJRS/B4_W4XS-8N%.J#$,6LT2)V>X?I3H?*K*83&3J=-<@A -M7%N'6#QG[*XC&=@%O=^!AJZTE$>VCH5%B$,%,,YS!UB3K\:[__U_/?W_L^9= -M+$0[]%34$%2A`I$X_W$51X*$Y]?)/CQX'%U'2W`E#Z&.'5)\N^35,U"1;LY% -ME*C6[(NXNI%F&E9B(R19Y]:6\_A/!(>;^%9]LF./CM)1G`TT"Y=]=(8/X5N. -M70L*B$*;.8/6-;0\5) -MV^)[P(ONAA0'%ZWQG,!H&+GT"UYVTWI#G'6J:H`LK]COP.Q-+1Q)9N8]8YYY -MD^I+K;^RU`7(;"V/W//3P5I:!AX'0>XL:H`*B*>:.^LA0W'"I5YI;T+Q6+1( -M%+[VJ+)9N^7\BFZ^U"$2)%5*7BK9-VI -M2N06O@'1\')`*S#DBK>)L],YQ!G$#2#?*#E+K]?(?@;JW1@]6N1XNW&USE=O -M`IR -MR$#%_S(^LQ.?0ZVF@+88#8L>CE[7&[I;2\I2=%DR+MR$-:4QV#A94_)A&,+F -MQ=UN6_>P989E%2:S:SVHZ2#*#`+*,X*NAX>"NF4YS9;V$<#)'L\R_8;51*F1 -M>3X`,L8SM]]V4(%%6D1WU\7>+)7*/+EOW@S!/D57QR9#R3M:&N6SJB!B.5%A -MY20`P\UP12;DPNX'ER`G4E,87<\@D(.0#:7.%-H+V'&"M[!JAM&<:4P,F[,3*)CK>5KUU^MZCY>>NH`H'[3 -MA'K]=&Z6!?G>SAB]^W8W0HK)%-\4LG?10`A,G0;XZ]1S'[-7(T^>16]B0LC! -M;`3D.D -ME;'FEC90`JK::$Y[8`U(2T6H@BUF`)8-PPZ`/`4+NB -M,Q5;.$^QD+O=>N+^"6'X[=A2O5D5;IU-M,KP^N783S%ZE\C,*\X;@P5X:QV^ -M;T1Y#)%*LC@7GEE.\,]*4<[3!;`7GH#8/E]72:C]TCTEL:;387`2P+CB-^H* -MJ!1^[C@4%!55-B[<$[F!I*EX]=<5W0W=NP9ICH*JN4V6O1ZA4Z=4H_&GR`PS -M1]7GE:AO]?39:FOK'Q%GNE)%^FH>-98O$#/U?2`B@GD.G&L4_7`B`41A..V_ -MD!!G3_8^>G^$CBM*_#@W@>@0\#W#5\X1\&C*R#&=EZ(HU`90ZB6^9I*4Z'FH -M_\,L_5*=!$IL#Q7A3S!IYO!P]T5%9EMB7DM:A_78]9YN_[]+RZFJ4V>J@0SA -M#[NP-D#1:C"-(%KC&'R>WHUS>%I2?_`H,_NJQ.C'4QLJS'XVE\)HT#0_.?[$ -M2%/[!=K2HK47V@L3JAGSL0&6M_HO>!KX61&'6#G;RZ?!%%NBHU2-_V7X.*[9ZK;\N0N=9M\=$>EL7#]NHAD\7*FJKU.^E:( -M)]6(2ZR!3PPIS`"1YC$SY8Z/])K`#883#9&Z8:`W63_'WC1\^#.6!H\='78> -MHD(7]:M%]K(`0J,F>L/0N2LE$+;>/(89ZDD\U6W+CA<+.S'I_G+-S,*@N,HY -MR3:4#@,@`MG2V"[EA$K`^P:O`^(.:(.B'FK@-M[`S"I$9W/**,=?C>5;I/!L -M0OST&X.D(&ZI*&\4M8D5B3-S,33)*R>/*X4I<8!V0>6YW'57OY?@S$?1(MILODT@KL2K2^^_L(;43,(W==PA>",I\?COZUI5C^UB6&B -M,[(<^_$+YKU8,9";R/_2@+9D#WQ=@^0G*EM'TC-58)&V8JBD=]VJUMURJQH2 -M=RE]&2WBN^;BIA!)ROUGE4Q"T3`@"TK6XT8E,^W0 -M'N<*(4;RE=TAXS8SQMYES6>SPIVB!EOVR0I36T/D1_]WL5W#5N<`=^C(QRWI -ME?N@3?TG_Y8__>U%Z?BL^N9Z;F\<Y53SON2&L61A<]!T_4?%:EC9&GU84U/1A-[? -M4#[-9J%YPD30#+9`6#_G+]%`";]Y\D6(OWXAZ)]]K%`D[B*+H]V2=^]M&[:Y -M_^L?94I==M2U@)%LT]N%GV]=\A3GBB-K>A2PTBJE%<,<4XPGA)C(/1+ -MS1*(E3&PA@6$5)V",Q[0E6;-*E0=*A6T5U.KY^_C66Y'44^BP35>=31^5S>,T3;IH^"$4%^3OM/P796=[G_HXE!"5@1 -M+V#?H6"#[49)5#Z-6K_XMB;K;,MGSN_&I4"VT%%A9#$J&FMN>8)_\(G6@-]E -MRD58.OQ"_PZ@>Y'+TPY0Y2T3%TMN/,V\.16J8&X"5;AMM)85SNS$6Q[_8+2A -M9^V[>0T4ZNHACJ&`])R!9R7BFS=:[OL:HPQ@V'KC?/.[0-)\/2GV<5=TTD@X -M$````00&``$)P&!&``<+`0`"(2$!!B$#`0,!``S`ZVO`ZVL`"`H!%MOF-P`` -M!0$9#P```````````````````!$-`&8`:0!L`&4`,0```!0*`0``+4,K<;.= -+`14&`0`@@*2!```` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_delta_lzma1.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_delta_lzma1.7z.uu deleted file mode 100644 index d1e40f6e3..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_delta_lzma1.7z.uu +++ /dev/null @@ -1,280 +0,0 @@ -begin 644 test_read_format_7zip_delta_lzma1.7z -M-WJ\KR<<``/D94YN,C````````!6`````````$-]]%D`)P@\ZLN'Y_OA"<$. -M>]Z/8&Q;PX#$!$?ZQ?PR&S?06__\,PN2SWN6PB<',Z:`2?+W5NIZQP1?:,X- -M*G`\OL';&5F`W80F)['CE68*4/!?&M>Q_R#$Q;@`Q@F5(I[U[F/8COQ0BL\Z -MA6GS"(1>NNT7UW[=_>9;7AG*PCEPPQEG^3!\L_BGG$>(P!]1=3USVU32.):[0H>JF(9*O[N7&AHVJBS -M+_&-5L$(`LTXLA>O"]0KI-^&2EL>6`T68&4T4AV?J'CYW/4JT7.9.]2-G]B` -M'$Z\$3P'1!].A&N'IZW.+$-/U@QTY0DOB0"/L0"BO_7;OC9A1#M3DKY_.!]1 -M@3UR451\>I/;:`.VS3SJ_MO_/E3`@#\&]@Y4][!$,U$05+X.O4U<%Z5*<`_P -M\X1L?(("JO0$4+7GCN/AC5<9]03!N8NSHL=P`_H>=M-A>$-:*G]-VZ>[H'XZ -M*?@%RJ8@E?SWB^`3Q3W[5__+&^[9`2E.A0WT,QG2>)P$BOJT=@0*>."DT!.: -MNO#(K.M&!)"@[;<'(._$-_+HDP67X)2/Z@UMT`^&8/(YGP%A%XL'FS85[J*&VTE7SDZ+@]K<#2Q]BR^!: -M$0&$?Z71(7DJ,*];&?AJ,8>3!`!J'4O*I=CQA:$X1-_@(=NAG>4N`#LXE:52 -MOI"G\%QQ[MUPDA3A5"".^SSO/RAV[IF3*EC2`$*^)I?I?:Q$X'PJ$[O&[H1S -MET$1SXX\SSK&LAYG4QWR51.W["K]U5Q+C!C2(3/]/K2$*[*UU%\M7;$%2K<+--6SY8!=SBR^I6 -M#[I2UTLHL]J*Y,UD8UL!AMC!SG(/X6[*S3G_DP3'.R2%0%_L@ -M-\X(DBY',.J?&`)$+Y"EH%HR_5Q6-!;S)O"4WEJK:_O>*XL9?1ZO1LSTLU=* -M2\`I_R0L;]GSS4X75G>R%$?VWSE8O,U>P-VV#!H7-.4P]1C.NZ>GXP`,X5.N -M.%?[DGZ2XC$*1_V#]G(_RCD#M^-8%?(D83N#1SY-3)(EFYT^H<&HCX60=X$# -M#3LE/JGBC/:$DQ@ZY!+:5GYP:9\-H)9&E%P(<7ORV2P*\^NJFD6@\YX:SQ_K -M_?E2=;*.EQ]Z.4HKBRP<+*N3>-ZR#UW,R?>/C;A'K^/WA=(X`XCDYXD( -MI`H%!NUJ5A/J^8Q[,PH3(F*9!498.OS4%&Q[)(!=%B(<4;MT0.+>_9OZ;PI0 -M/7G@A%0>MN)310Q1^^-KXW!@913&8Z!;=.:6'0GMLNJ0^@DYO/Q3QLQ]]9RM -MX>2?<>)66*R$?+F$S_C#69"K9\P):$TB -MYMG*S2@AR2;12;=1YGI\<+5(>F#R9'VE[_NA\#RQL9Y"K%,AL$+34Y:I9P/G -M%%M;X+0K#Y>T]K5FN=\,2?RQ^$Q77](@_'6HOQ3HY%CVIUD_OR(IO1>>(9_UJ4DSL!D=]V'^ -M*+UYF\S&``SA(AO589;-MK#V>AC)I=/#=B49L!+,MAJ(#KV;>82#S>=@@.8% -M`^C.[R$H2`F1-@5'@3BW: -M772[UL#!!3DRS^&#&$9-ADFJ@R%S*?T&#%HB"HMQ9(%RRH]&QCTT3'#:?!B0 -M7`!&`CR`T?-ZT-JOK07K,;!D:L*L47U5[-='$_"\]12X(]Q>0Z0$P553`?YZQA.U,'_!NT:K3KZHKN/!+MT2>HRWQ@X%1H@_ -M[.:Q[!S?0=GU+>RQU]Z;VYP87DO)3R.&(F`K"6]*JC3QB*;=Z]6B)M'9N%`* -M&@D6+AZ-B%KC2FR(D6,(X+,=94.(6T7R-Y\3;`3+G5@[A8BS'N>Z(\+6:IAF'=6(/B&5`P>P/ -M-."-*9K820*=E>S#.6EON]"QL,K@:O4K(V=U9V*MF?U:2=OVU!CG-@]1H95\ -MMRNM=X/#2TBEP\7'*D7IRCFMJ3TN\;UES!;;"8?=Y'BA>.A?6$ZW3'9<,@0, -M3-B(K'*F7E)/QUUX"#`]^\"H,OD*C'0@;AYZ=!K;_+"4@$MT_7$/(]UGE5&+ -M@CWVE11WZ)6UETE,BJME(D`T#SAT_7&(B/9D)W>N60ERCMI^Y>'HP/S\Y*C6 -M+3"&90U<5:FW:7YPWB/WTL+\`/=38B>"V(DFG#:V'NFK`WM03Z]\.K8 -MSXZS+W!'W7P@@@=AS^DH[]Y65 -MR6I-C7,%B;-$BB(Z\0(9V;,W%C4L-US:PMM[C[/;\+QC.+&PT1H@6AQGSX2! -MKPB5,/21QJ"9;SP2$*OM5)&L.D2)!;O6J?L]K``#(F^F\1]7XLX=66`SU>W0 -M>IY:WK.UY;)\UFMV3L%G/3:S;1J&4L7I#2)^":\8S`-U+OG)6*@ -MA6DM,XBJ>1F0HT=E@#K5CT`,C,&&O]X"97"W4Z;B_0R;I-X$VFI_\%\!8F],IUUJR/4*XD*CE#E:1#$V!I!GZ*6-K=W -M:X;?]7+(3BC8'CR<-CK2_CS:N&2$OW#7++#94=YH>78TYTI+&N*&9&(!E;(@,4WA>5Y^^TKMRON#') -MN70FKU(AD%EOY,,*ENSMLD)3=**-F@@8ZW&7*?O^+]<*;N>Q_,'^TI4"YJZU -M':R5E$A_R+G-IO]4^U41ARZM;8][Z$OA<-!S[A`5`IL<&1'M4^*#2-X&L$P5 -M=D[N+M9L4^!3S2-`%@"V;-[(&)S/1Z1.5)`(R*6S[#UE_ISL@]6''(DO -M7:ETF;UD^7+,;+?%14BJ5DA,(37%:H=3^M4B&P'O^J/Q]'6Z4^>7:4N'[&BN -ML?*1R#,X2P$BSI3$G*=(9='']16_)+@B)F%7L#GOU_0O-D)A_N4L#HXX?+M> -MDJM\^V=?ZL;4^9J@-6<_0S'.AU&ZT6RE/Z%Q>3?<%[R_0JAW[<=FSX-U&B$` -MFKU@I7O<$-QW)SSXQQ4G4[`?$\3R"7'\#]+'D:H^\U-%@MLL*O,R3,%O -MS>P&'=_R;'$&B^N^9\P;+67ZF;JW!XQ4;(9SO[E?-`$J+%^%G1%PWJ+()C0K -M4U&=P(D#^-16""L81BR;?0MSFXM;O@ET.0'@&S+/J(#U$/=9FN!&,`;UDWDO-`/"NRLAA[RD&LO*U$2'D>`O65#+7$!#XQD.2^N&%7O(Y?2*XX: -M#-B*1D>U_USYJLJ*;98ORW0AK]':_E+5T=NDIKO3MP0!A)0DC3YR-Z).T@.E -M`U]L+U76`C894>4N"]@%4WU:0AS\G#RW!MX\?T%\S$K,DIHTP8@:K`*X2;`- -M7E`B?7.@W+Y%AV&KPCR9L%9U!,"0>GRBA.X@U3GI[=A\?D -MF/&E@CB3!3!=\0ARGD_MPR&&*@DI;E.S"L7M+]$>O/,B\\6E*A;C*Q3SF@,/ -MIEV;SU9="P)31] -MOM;"7LB+2*:K-SV>K$WC+\IE`8I]`81U\R2ML.T`L*%,Y]JI.SL.YOTZ_S!) -M%60%EQL%V3GT$MT[5PA6T0M(7>6T`)5K1:O-`EJO)@)<4CG[J;0`2E.+1%,/ -M[8=M\I8-+^S<:H84WJTQ.F^R';X[=^:]'_QD[,W@NC%R=#XPG_'-R#E*7J6O -M!""049K6@5[`6_MHF$R"-K:,K>;CK@3KT&XE5;QU62HL>*[\?/24#1@5:+8E -MB,#1F-L):1JFY.Z;8&\-D%$F5>DZ&8[!"Q<[+CQH*U(UUX-5G$MK7N:63Y!32\EM.;C^-:5 -M%Z8WV$?E?O2PBNSR_N[5%;IW?AL+'M3M`X7@_?`_R6G*__"0:@J:B/VK?K"J -M4I912,:+!K(6:ZE`K$$)`>8>Z<<9VGCQN\3*QIH_KU)P$7,VIH=LCJ55-N5Y -MK.DW($-*L^CGL=-8DU"E$^^E"N[=S9%*&%]I1[)6K3]C\')R"6;B6W%_1-,+ -M.]\D"\[H#%F#Y$0T"$Q\YM=1"<7=Q7E=7++JM>_'IF%?CU[?P=33.#_?U.:6 -M32_T[CK:@6\;/D?!UW]V/D_Q,]A6.3ZC$-\@R!&=/MX:1(="+K[TU0H^V37W5XXR;4JKT@#"76N@P0,]\;$L)BX3*3QBK -MXOP$7J\6*[$!>F=+9<)Y+PN)C=49&/&H$8E7/V/_J6O4?@)!DZ& -M*$,23=I]VY08XC)Y@DH;"BFX;XT4G@HYSYJ'? -ME3@`-T*%BL5A+3:Y#A/>=%M@&^1!;;HT:Z"XJ&C'#*D^X7!=LV%4VV=D?B// -M>3JDTGTN0+FM#&L4'TE1U743(RFT/&7=,#$?5?5"*6J/7]25?4>U[;8&/I[Z -M;M"*%U"R[;3HKIPBB[]G@CYT,F<$X85.FC\J,DOT.\/_?>8(%HJCW/CTA_^. -M9EP7KNW)2<3#'R'.Q<\QX*@JI>LD;/_.-X?55P2>WO_TP0C3P@AYT?AEW'5, -M8SH+/[@F(X`I>:VUHH-@;,T?.LS3W%M*>J-B>WAY[]!"2O,.3QK_88V_-)0N -M=H6,LCQ#]FJ!<&M<6(4B6J?:NW'(K@/#^O9(I7D\L5@QQM8VM8I5==&#HFA* -M,*=".PHO$L`@F)W4C5.+-J$@)L3UU3/ZO2^S$+0KTX:-2;PG[3Y1(;6462]( -M-`H;2%K^>"1``(JAO6EKN>5*W5:B_(>)=60]SG]L#@\H@V3@WJ+%]*S4:/[&N6&=DX:<%;;4O7K_UWIF -M-9,X?NA@_E+G&3[N6B:)&^@BN%#MT#UF=3 -MQ#<5?UYVZ:A$O%#+(D[?W*>`8TL,>`,G6?OUV#R*V83#FE8SWU&!I,=73_9_ -M6^OD&5Y/D"H<6;Z7Q9[(#Q&Y2@\YH8#Y'Z+K:B+,4TO1^(JM+QM('M4X2O=/ -M5Z!$[<;SIYT:CSTK7[<\_9T'M/:HLHP`#$ILHW9FML'GJG8%R!A.O<5$ -MQ%G9!K\1U7&ZA?0&GPG7S5YX.0PD;^(=V/<&Z6ZJAWR5A1DUV@T'QQI6-/F, -MG1!0",MJ@A4@;I8D=O\,>@#\B>'8X&T0$)8;3+0K] -M=>G@K4:()T38G$_(A16)CG2U9'0H_O(1O1EIU-<$E:S22MY1`MH&%FLMWE0G -M$B0[QBLL$T_C3""DWAIW`V"C30&K2Q8=-;/FN5X;"7?;-]\7KCX0[0IW0%!T -M(E#UTN%4;1$Q$G4=XKOH:C+%7$0#*TO9I*'EC0SOZ_3VR[N8S#F_"J\A!6]B -MG>"TP`^7,JKA6K>D:[5:1(OZN5"EAML%U$V?$)D1U$:-SRFT\Q0*$G[\;A6' -ML9Z\76EC'T@W,,CEEE##.@!NOE%Q^-Y00=37MC!=(J;"M(FU#5,%-5'1=DN. -M?90=HS_6.G!*^LB>+::+K%LCO'S-U?Q>YB7)6((& -MBMCGGW)ZJY].)LYJ1B5%@9Q(`V -M>I0<-MJPI,W-8_<"/J\"E^M6Y[=F4CE]CC@U:7%+S*,@?'X -MP7C?=C]S77H47<`;$-+AB2'?5SII!&#'!0-3:`)#9.+`\ZAH>VY;.X'N!\*M -M*9G5FQU3S]:P@]-`OME.K`N,,2^.Y;TTGVK]#\%X1+F`Z^*.G#0['7+5BR:G -M4LJ#"&Y&T`W6:82SA[C0.)`W*:N'Y*@9D`.?G8/`%Q9#31VG7SCG@+7L&4+C -M<@?'@MRBJGK7_TH;@F,9)G1D`XC)P'J9@N7H??+GVV:M3E`G"?V@>%71:O5* -MX;'7IIMSJKH\N$^.18QUA$H5<8WZZ:,NZM6(^:#F*15I[J5%NIM -M>$,DF7E!B,MX0C:E-F^M$GLB(RP#[]Y.R^9Y>1US#=4@]*&Y3%F>:]1C(?]'#4O")9CM2?%>02'.)_HJ -MR\OMKZH#5^S0[.185IWTBPD6KV3W-O"=5_O)4LE=9RW98[@RTRMEDR5Y7C-A -M%;R1LE.%#YU16M!O\4TY!S#N<@_*$I(1&6,XGIDUU>ZW%LU,F;<`Y2TY:,1( -M!2;]WV=*NQ81O//B'!H<=]H1];IJ13/ -MZ_LD<3IT@4V;^/0R5R`L`>!-Q`[8E*@U$#T2H97`M\N]^Q705Y)3YH=[=4C` -M@:C-,E@Q+8.XV9OS`^,H&DKQOTMW8LB61D3)Y\&7;ME9\>5#/_?:X!%T -MA6I4ZU5\=2>(&H\;L0CY*)`>A-]84HU]\42D+8(I=)GPV-&55@%U\8-(#$HK -M6[;,I:!ZG'L"TFL*(VA],B]Y6LR2 -MRSQ;GQ"2H.NPZ8[YL6Z>FVC9T:;^/0I\:#:]>VS&Z3^$9[ZHXVAZ:AYS+W*/ -M)!<^L"H!,<:C")1:VME$JBGG]L59CZEW[C$9'MSRQ@BD'BCL.*,7=+*8$K/W -M^#':];GD-[YJ;;0UL\D+W+Z+-C0$[=M6S.Q7/.\KR\[60([1L(0*PQS\\7Y9 -M4(?#O)X;S)S44M\#69LR"LQ&*[HGATFI4V8%X6H#8<(2&\6$E5"!QOE]LV[M -ML&GJE2R@):=\U@*CY^9F"Z[:6]SGQ&5.T"+*DR5JP5\W[0[#4>9"75+,2TSZ -M>R:XE-B1QD4Z4A#L)X -MM34\;DDCWY`"`;Q0@_"^;=LL(F0[YE0H+']L=/&HQ7XXQDTZY?"DDV`6-0J7 -M#878D'C*^``8"B(E,+(:FX.EU.]C&H<(M44S9TS>:0@OP,FFY_U"CNGE3M2^ -M,2_L]^LR@S*[=1$A5FXJC5>(G@4B=!"Q3[:5$>!<[0(1&XUNPHM061.DG.#( -M-0MZ['KBN@G)%XL#L`S_O<,A-?[(>2A/$YAFRL.S\TDF';WP2J$8-PXFZ_@3 -MZU-:WQQ[TD*0847@^')SZ.8E63.PL]@("!,7A0K:CG5?S$OI:_F'X5O$_:@5 -M:B\3=G6ZG&AES$6PK`.MP,STG/J!_O9CEBB#&O/R0PA64 -ME+Y+]OK`!'$OXMOF+B$&*XVLP2/CW*>D<.1W\U?FTWRA(C^,`@MF1/_B'VN. -M-%WLVJU[EA"E;1(6H@ -M3*)"`[36&@[?IB-&?I5ZB.'D!6V_ODT?WKNJYY(%O:GDE&>+I<`>ZY6$-VJ4"A6>-A87.:TSL1R;U7V+*>Y#B6$S0RNZK0]3G<2D1Q8D923C.IJTG. -M8"1_+Y!%\$J@!G3;^P6SJ4A*OHZI"5AOA_QG&LVB0VH;4EC*TU_EV;@1,E_* -M#!MTD^7[B8;P*"^+K#G?!UDZDI49QL+\,")7-ET$-/`,6C8+!^I2:)DC8\+! -MW]/64DJ!3W.NG:4>>U:B>](T^4@NU4N(]MP)3%&K,6D=R<)&P[`A^]VV!F6\ -MT^P@5:@NNJF%]ICXND]T`*POO7<:S85Z>7*_I_+(N;VN:$Y."U*7Q%MIG!2_ -MU0<:9,G!YG-DFSTT`&0J -M!\7!!:20-*-0?F$P=L3)'7IO\)SFM3X=%?!__R]ET -MALQ@!*Q0([\V2>(I='370+W;>YW$KV[Z^DGC*`H@S5\G"V0U_Z"@-Z-5:-MU -MIHM)]]3U3@#Q,Q+_CYZ]T\@"INZ;KX?9JE\WA:0_DZ%MWB*N=OQ!,A)*YIC& -M2XQ(/]>NE^<%>NY# -M)BA].AF]S:[:L9W'_1N$$^[2EPGQJ3G`"X^R52LXR -MM!!"9#E2+AM(*D=N,>!"A=.Q57^Z&P`6H'0]R&-B410DS8`BV.:WF])S>NO& -MWZ9]J)69UT6+XZ6_3%+_ORUKJ#C80_`F-(G:(MN*(:H#H/$;3:R&EAG/M[JP -MYFQ([TA9R.3'.1?PSKQKERD<*%24DBJ<53[E5U@D!8"Y`KRY:I`>ANI%B_>5 -M/]C\D6K,;RYX)IF51K*"57#8CS#J5I,6D!-IZ87S<(':=1/%\EH_W"T(B#.6 -M_PX)C@(D?+#Z&A#OOF"!%Q=BPN`B>S]JI0I/@SYSUXPN/A -M+Z.EVEKRE!G+E["AW`%V4]8I/J6Y-$J@5AM+SOY`^KKHY9-;#!(P7K0HM5"^ -M!T13A%X-1LJ%+\G1FLP;#Z9+*/P$F51YI=?]@O'#\&0ZC,]=HX=+N+L@3=,U -MEX]S%$"*KI3324[R7<7?1X<66:2)NE=_>T\OOJ$G3L2-U*TN]`=I!`9#\7G@ -M=S"U$JD4W#C]V^A!^^$AF]I_''@S\52C(006+;YEKX42BSKPU<7\E,];'CPJ!*7&?,)J%K%WWLI!2M6,RU1#VAGJ]J#:^G<`&@/2*D0,%[Q2@X%?YA:^ -M$&P(CXNA9Q-8BGR&BEY@2)D5=/5'8EJF/ -MN7I3E8!>!Q%*5T(S.1$NMD7L5=]=\N4I)V)'W5^+#SI#;NGX-8?`W23W>P#! -M38U$:\Y4K<38[`WU_?!NSQL)OP80;:E6WJ'$&ZTPB%64L,1^`4AK*!B66B]. -M*R:X3J)?YPU'-',Z]TC%)27C6.E:[==+^5GE#\B,C'?93H?HSY_OY4N47LKT -MQ?6A-47HE>4OD%450&B`+6+$`]<[.A9#F>?),P3@/8M%S7$WH&\4;3\;FT/> -M!!E(J__9P?+7S[WL#$.=1A.931E8*:"#[%5=2Q'X=W*O9JD0)TF3S.(;OX&S -MA;LYB!!;<>/V%%Y[?71\,<'P-A,0(FY.E+/PTE@EJ_MT:A/YO\<@^]]A'!M7 -MQAG4W_+,48ZS:@:XL%!H-&&!@]X7*N9BU9^1ZM@4%PA=0+801N,(RNC+A2.- -MZ$K,2NN80#26H("4[7-,DY-/WG[),^G9)3R?L`U8,4V%PF!&\* -MU5AD9/X(.(LSZFJ5,1';1?,70G6L'E(**;*FZZ,Q,^,GR>C3:)AISAENP$.^ -M3F\^F8MT)B(+"W+%U>DZAF=#)<(-#CR3SV>J&-4F"YW<)0HDQSR!^"J(T\]M -M(G-T`U!;U6J>P1;YX`F6K^KL,HD&48,_+5*X/W,M_12A1:OCP&!,>US&I7(V -M"?9$/D0AI<4C#D#G&9N39K6<%-9BN!?MNF7ER^05`,]J -M_^Y#V.R)TW-%&Q>A^'UQF0S]'U(=VMGY?*F_VB]AR*!5*5-UL`>5`(\1%UUI -M!M8(D%1C8[KC_WXX:#^,TRN"W(A'1]UAUG:./MC?4]BN-7J'5'%*S"&\Q]#O/]Q(R;&6+T!1K -M=_N`.18AF-[<.9F(8'^[>@;(:@KJ%">P7_OIC)(QH%'0QPA&8HG -MB(:/H,6[?5:,+C^C5$JQ`;BF\)J9A^VW%/W5YG5R.]H5_/"+`,44$56V>'PE -M0I7;BKO6N/!@\?TRF[9M4&01^#'>6@VK=AWCTNO;=8F*U-^<9A[8ZZ5?L(\; -M[:9QT^:P5:X-;6,F-YJ]Z=((0C(M2*,F4V;_%`+E?N,I56]7`DA%S5MR];Y5 -M^S84E?MKPXP!5.5A:M2GE8L@+P>2JAJV6XUOSKT=)Z&MO(U0D,V9IGD@>E,- -MLCYZB1RS#W -M]4+!XN]$&NC+8:TCKMD@H/P6YS@S!7R)/Z-7B?G,\C\])9E).3;]:.*R[KBF -M$T??^@]CQ']B,_U(`<0BM>S/UY)+UMQP[>VN!\83`P^?G>2,304F)Y600:,7 -M@ZNG+3$$*`.83-NP[%5<&.D,/R"`7&4GL[\XE)"+:>V%J+-EW*>UQJ6FY!P@ -MF>[N"QQ$XDUD*-K&*Y&KDG516QKKF/_I\]^E7+T;6U#\H%JFO\@5I-[Y$IU_ -M&[<.2@R6K`"*^PL?5^SUZ*8I'+`PJ@J06!WW#"C26D.6[K_M0P@QN#X8?V== -M@GI$8)NDQ2U?C4FQ%B>K](U$;>`#E8VV='OG,]TK"ZGBU$A'X86A+T;IMYE` -M7:U[V\*0ZD@$N>Q^G]IIVV)(W1UHUQ%D%*\`E,?+XRR9%ECFXS5_7<\T%_\Y -MG5PO[#'OVH*\:ZF?2VB@TLN\(X[]W7!F@#=4^=>!HY4%$P=`V*QV-!N-#@^+ -MMVOUM,5K`8#13E7*R$Q)ZLL/`K;WH[U6PH6E]PI.OQQP;5Z4NCSL+,4+Y3KY?ZJOU_NF -M5.?8;CYK6:7-CV(=8RXL:86)LACKZ@/S5N8!*4/(Y03K:,8\/D'V*(S<95WM0 -MQOYX_HTQL1N5*+`Q6>'(PRD=2P^`E`P)J;8,SP%0!W#H#BQC!F`04ZG:U;L% -M*\C)(;!PVF/(+Z-]J4ZW#2^^48>.BR+AB-7"LORBGOWY5`H[BA$N)W3Y_R'( -M=**C^G91I%XJT=,_GA<>JD+3:(#LFGJB*LW\5&CLB:>.#F8E%#6%)]:1X]0] -M!Q>C[GS26W)#J-E?W@Y,W:76#:M3O+FEV4\)OVL1C2ZI4[>$`'*__O;+ADT* -MSS>RI1G]1Q7`VTP(4UE!K'#)BSO^6KM4EP(#0^9AL)H#"T2>C/^UG:@V,$8(P(TD;8UDH\I6X%##=P$YP>=1F?/_FCF5MR3$09%F7KE_S_._VR@RMIN6PY'OQ;_S-F\;%Z!1*FS706[ -M`K^VYM[A&%VSP?$YECDV4C7C"1/PW7^$QE08@5=2IXY\)\/DBOI7X%-*O*PF -M\VIEOS.DAF5'PZ@`:/VEH#(C4IS;`./"23BL0!(IH`'V^@X_9-359J@[T]DC -MH!8.(H=OT(K'&.@&0OM7`;NO(_SB/[WUFT`?:*1`Z:?'[(O\QU*CYG&.^IIE -MO3AT`LXBX.GRVW.+-GC$&T-)&J/TYB%<7:8$V,DBJ0ORC2$`D2_2#[9GB.99 -M1P)9L:"XMY09G0SWX)!"4=BHQMQJ+1O!H.:Z1$1VU?5O).[A#""/!6H4OV3T -M%-EZZXN>YX!S\MJ]2+:3<;^ZL"@T-'%''*\9T.I!S28U50QV_?"JK[-B$E;O(ZV8[]K7E#CAW -MT'@3)`[]"JF2#DPYOD9B8MTK)0G),(W>J;@-IM)X*C.1;:_S>L+.8?M;?J78 -M[-L1R]6R2+%^2@KD^7W'ZA\5UB05TXU@B3CBJ( -M7!\/AQ5H\"_\SA -M=:F;M`=D%61]2_7LS#":2[P7TS^$H&GU$*R:!=#4ZPB1CA^<5BR#4PNF1%!5 -M'Z;/4>,#S:M_C@;_YT.(0W6)LD0O$&.Y1-;G;T\F5"G1@00RT$=Q2=`X[9Y^ -M820^U%%$.#V32Q:..ZE4O;;B!/5)UDZI6]P*>N]@^4]+A?JV3& -MIWD_]]F0RO)'#!#]:(<7^A:'S$?@5A%FN;@:-(I\P/%%5$;2]=[LX/-G -MCV^6$A\Y=NI'-?'3$*=#FO1G,P6#%Q^>.W@RR-J\O#MS`YIHR/?H:4L*Q65T -M5D%MZBZ]X1`\)@_P#Q)N[PW0KDL1OY?#&$([VH2-^&E)&4H;KNS)7$!(OI"- -M>O84#:X+5*N`1V&G;ZQSMCAZ/RM*W$,'(=7^)772Q.\%Y^*L]Z/8&Q;PX#$!$?ZQ?PR&S?06__\,PN2SWN6PB<',Z:`2?+W5NIZ -MQP1?:,X-*G`\OL';&5F`W80F)['CE68*4/!?&M>Q_R#$Q;@`Q@F5(I[U[F/8 -MCOQ0BL\ZA6GS"(1>NNT7UW[=_>9;7AG*PCEPPQEG^3!\L_BGG$>(P!]1=3U -MSVU32.):[0H>JF(9*O[N -M7&AHVJBS+_&-5L$(`LTXLA>O"]0KI-^&2EL>6`T68&4T4AV?J'CYW/4JT7.9 -M.]2-G]B`'$Z\$3P'1!].A&N'IZW.+$-/U@QTY0DOB0"/L0"BO_7;OC9A1#M3 -MDKY_.!]1@3UR451\>I/;:`.VS3SJ_MO_/E3`@#\&]@Y4][!$,U$05+X.O4U< -M%Z5*<`_P\X1L?(("JO0$4+7GCN/AC5<9]03!N8NSHL=P`_H>=M-A>$-:*G]- -MVZ>[H'XZ*?@%RJ8@E?SWB^`3Q3W[5__+&^[9`2E.A0WT,QG2>)P$BOJT=@0* -M>."DT!.:NO#(K.M&!)"@[;<'(._$-_+HDP67X)2/Z@UMT`^&8/(YGP%A%XL'FS85[J*&VTE7SDZ+@]K<# -M2Q]BR^!:$0&$?Z71(7DJ,*];&?AJ,8>3!`!J'4O*I=CQA:$X1-_@(=NAG>4N -M`#LXE:52OI"G\%QQ[MUPDA3A5"".^SSO/RAV[IF3*EC2`$*^)I?I?:Q$X'PJ -M$[O&[H1SET$1SXX\SSK&LAYG4QWR51.W["K]U5Q+C!C2(3/]/K2$*[*UU%\M7;$%2K<+--6SY8 -M!=SBR^I6#[I2UTLHL]J*Y,UD8UL!AMC -M!SG(/X6[*S3G_DP3'. -MR2%0%_L@-\X(DBY',.J?&`)$+Y"EH%HR_5Q6-!;S)O"4WEJK:_O>*XL9?1ZO -M1LSTLU=*2\`I_R0L;]GSS4X75G>R%$?VWSE8O,U>P-VV#!H7-.4P]1C.NZ>G -MXP`,X5.N.%?[DGZ2XC$*1_V#]G(_RCD#M^-8%?(D83N#1SY-3)(EFYT^H<&H -MCX60=X$##3LE/JGBC/:$DQ@ZY!+:5GYP:9\-H)9&E%P(<7ORV2P*\^NJFD6@ -M\YX:SQ_K_?E2=;*.EQ]Z.4HKBRP<+*N3>-ZR#UW,R?>/C;A'K^/WA=(X`XCDYXD(I`H%!NUJ5A/J^8Q[,PH3(F*9!498.OS4%&Q[)(!=%B(<4;MT0.+> -M_9OZ;PI0/7G@A%0>MN)310Q1^^-KXW!@913&8Z!;=.:6'0GMLNJ0^@DYO/Q3 -MQLQ]]9RMX>2?<>)66*R$?+F$S_C#69"K -M9\P):$TBYMG*S2@AR2;12;=1YGI\<+5(>F#R9'VE[_NA\#RQL9Y"K%,AL$+3 -M4Y:I9P/G%%M;X+0K#Y>T]K5FN=\,2?RQ^$Q77](@_'6HOQ3HY%CVIUD_OR(IO1>>(9_UJ4DS -ML!D=]V'^*+UYF\S&``SA(AO589;-MK#V>AC)I=/#=B49L!+,MAJ(#KV;>82# -MS>=@@.8%`^C.[R$H2`F1- -M@5'@3BW:772[UL#!!3DRS^&#&$9-ADFJ@R%S*?T&#%HB"HMQ9(%RRH]&QCTT -M3'#:?!B07`!&`CR`T?-ZT-JOK07K,;!D:L*L47U5[-='$_"\]12X(]Q>0Z0< -MR!0]$;@AW;DC'-S)FN9,@BU!RG26IWA;(4UK3$,0R):9:)[H!'P^P0;,&.`4 -MJ'\M11\ET?&^&P_1BU":9)5*1$U1!@UP^[&<[V'_(#F@V&KCC6K6"$P553`?YZQA.U,'_!NT:K3KZHKN/!+MT2>HRW -MQ@X%1H@_[.:Q[!S?0=GU+>RQU]Z;VYP87DO)3R.&(F`K"6]*JC3QB*;=Z]6B -M)M'9N%`*&@D6+AZ-B%KC2FR(D6,(X+,=94.(6T7R-Y\3;`3+G5@[A8BS'N>Z -M(\+6:IAF'=6(/ -MB&5`P>P/-."-*9K820*=E>S#.6EON]"QL,K@:O4K(V=U9V*MF?U:2=OVU!CG -M-@]1H95\MRNM=X/#2TBEP\7'*D7IRCFMJ3TN\;UES!;;"8?=Y'BA>.A?6$ZW -M3'9<,@0,3-B(K'*F7E)/QUUX"#`]^\"H,OD*C'0@;AYZ=!K;_+"4@$MT_7$/ -M(]UGE5&+@CWVE11WZ)6UETE,BJME(D`T#SAT_7&(B/9D)W>N60ERCMI^Y>'H -MP/S\Y*C6+3"&90U<5:FW:7YPWB/WTL+\`/=38B>"V(DFG#:V'NFK`WM -M03Z]\.K8SXZS+W!'W7P@@@=AS^DH[]Y65R6I-C7,%B;-$BB(Z\0(9V;,W%C4L-US:PMM[C[/;\+QC.+&PT1H@ -M6AQGSX2!KPB5,/21QJ"9;SP2$*OM5)&L.D2)!;O6J?L]K``#(F^F\1]7XLX= -M66`SU>W0>IY:WK.UY;)\UFMV3L%G/3:S;1J&4L7I#2)^":\8S`-U+OG)6*@A6DM,XBJ>1F0HT=E@#K5CT`,C,&&O]X"97"W4Z;B_0R;I-X$VFI_ -M\%\!8F],IUUJR/4*XD*CE#E:1#$V!I! -MGZ*6-K=W:X;?]7+(3BC8'CR<-CK2_CS:N&2$OW#7++#94=YH>78TYTI+&N*&9&(!E;(@,4WA>5Y^ -M^T -MKMRON#')N70FKU(AD%EOY,,*ENSMLD)3=**-F@@8ZW&7*?O^+]<*;N>Q_,'^ -MTI4"YJZU':R5E$A_R+G-IO]4^U41ARZM;8][Z$OA<-!S[A`5`IL<&1'M4^*# -M2-X&L$P5=D[N+M9L4^!3S2-`%@"V;-[(&)S/1Z1.5)`(R*6S[#UE_ISL@]6' -M'(DO7:ETF;UD^7+,;+?%14BJ5DA,(37%:H=3^M4B&P'O^J/Q]'6Z4^>7 -M:4N'[&BNL?*1R#,X2P$BSI3$G*=(9='']16_)+@B)F%7L#GOU_0O-D)A_N4L -M#HXX?+M>DJM\^V=?ZL;4^9J@-6<_0S'.AU&ZT6RE/Z%Q>3?<%[R_0JAW[<=F -MSX-U&B$`FKU@I7O<$-QW)SSXQQ4G4[`?$\3R"7'\#]+'D:H^\U-%@MLL -M*O,R3,%OS>P&'=_R;'$&B^N^9\P;+67ZF;JW!XQ4;(9SO[E?-`$J+%^%G1%P -MWJ+()C0K4U&=P(D#^-16""L81BR;?0MSFXM;O@ET.0'@&S+/J(#U$/=9FN!& -M,`;UDWDO-`/"NRLAA[RD&LO*U$2'D>`O65#+7$!#XQD.2^N&%7O -M(Y?2*XX:#-B*1D>U_USYJLJ*;98ORW0AK]':_E+5T=NDIKO3MP0!A)0DC3YR -M-Z).T@.E`U]L+U76`C894>4N"]@%4WU:0AS\G#RW!MX\?T%\S$K,DIHTP8@: -MK`*X2;`-7E`B?7.@W+Y%AV&KPCR9L%9U!,"0>GRBA.X@U3 -MGI[=A\?DF/&E@CB3!3!=\0ARGD_MPR&&*@DI;E.S"L7M+]$>O/,B\\6E*A;C -M*Q3SF@,/IEV;SU9="P)31]OM;"7LB+2*:K-SV>K$WC+\IE`8I]`81U\R2ML.T`L*%,Y]JI.SL. -MYOTZ_S!)%60%EQL%V3GT$MT[5PA6T0M(7>6T`)5K1:O-`EJO)@)<4CG[J;0` -M2E.+1%,/[8=M\I8-+^S<:H84WJTQ.F^R';X[=^:]'_QD[,W@NC%R=#XPG_'- -MR#E*7J6O!""049K6@5[`6_MHF$R"-K:,K>;CK@3KT&XE5;QU62HL>*[\?/24 -M#1@5:+8EB,#1F-L):1JFY.Z;8&\-D%$F5>DZ&8[!"Q<[+CQH*U(UUX-5G$MK7N:63Y!32\E -MM.;C^-:5%Z8WV$?E?O2PBNSR_N[5%;IW?AL+'M3M`X7@_?`_R6G*__"0:@J: -MB/VK?K"J4I912,:+!K(6:ZE`K$$)`>8>Z<<9VGCQN\3*QIH_KU)P$7,VIH=L -MCJ55-N5YK.DW($-*L^CGL=-8DU"E$^^E"N[=S9%*&%]I1[)6K3]C\')R"6;B -M6W%_1-,+.]\D"\[H#%F#Y$0T"$Q\YM=1"<7=Q7E=7++JM>_'IF%?CU[?P=33 -M.#_?U.:632_T[CK:@6\;/D?!UW]V/D_Q,]A6.3ZC$-\@R!&=/MX:1(="+K[T -MU0H^V37W5XXR;4JKT@#"76N@P0,]\;$L)BX3*3QBKXOP$7J\6*[$!>F=+9<)Y+PN)C=49&/&H$8E7/V/_J6O -M4?@)!DZ&*$,23=I]VY08XC)Y@DH;"BFX;XT4G -M@HYSYJ'?E3@`-T*%BL5A+3:Y#A/>=%M@&^1!;;HT:Z"XJ&C'#*D^X7!=LV%4 -MVV=D?B//>3JDTGTN0+FM#&L4'TE1U743(RFT/&7=,#$?5?5"*6J/7]25?4>U -M[;8&/I[Z;M"*%U"R[;3HKIPBB[]G@CYT,F<$X85.FC\J,DOT.\/_?>8(%HJC -MW/CTA_^.9EP7KNW)2<3#'R'.Q<\QX*@JI>LD;/_.-X?55P2>WO_TP0C3P@AY -MT?AEW'5,8SH+/[@F(X`I>:VUHH-@;,T?.LS3W%M*>J-B>WAY[]!"2O,.3QK_ -M88V_-)0N=H6,LCQ#]FJ!<&M<6(4B6J?:NW'(K@/#^O9(I7D\L5@QQM8VM8I5 -M==&#HFA*,*=".PHO$L`@F)W4C5.+-J$@)L3UU3/ZO2^S$+0KTX:-2;PG[3Y1 -M(;6462](-`H;2%K^>"1``(JAO6EKN>5*W5:B_(>)=60]SG]L#@\H@V3@W -MJ+%]*S4:/[&N6&=DX:<%;;4 -MO7K_UWIF-9,X?NA@_E+G&3[N6B:)&^@BN% -M#MT#UF=3Q#<5?UYVZ:A$O%#+(D[?W*>`8TL,>`,G6?OUV#R*V83#FE8SWU&! -MI,=73_9_6^OD&5Y/D"H<6;Z7Q9[(#Q&Y2@\YH8#Y'Z+K:B+,4TO1^(JM+QM( -M'M4X2O=/5Z!$[<;SIYT:CSTK7[<\_9T'M/:HLHP`#$ILHW9FML'GJG8% -MR!A.O<5$Q%G9!K\1U7&ZA?0&GPG7S5YX.0PD;^(=V/<&Z6ZJAWR5A1DUV@T' -MQQI6-/F,G1!0",MJ@A4@;I8D=O\,>@#\B>'8X&T0$ -M)8;3+0K]=>G@K4:()T38G$_(A16)CG2U9'0H_O(1O1EIU-<$E:S22MY1`MH& -M%FLMWE0G$B0[QBLL$T_C3""DWAIW`V"C30&K2Q8=-;/FN5X;"7?;-]\7KCX0 -M[0IW0%!T(E#UTN%4;1$Q$G4=XKOH:C+%7$0#*TO9I*'EC0SOZ_3VR[N8S#F_ -M"J\A!6]BG>"TP`^7,JKA6K>D:[5:1(OZN5"EAML%U$V?$)D1U$:-SRFT\Q0* -M$G[\;A6'L9Z\76EC'T@W,,CEEE##.@!NOE%Q^-Y00=37MC!=(J;"M(FU#5,% -M-5'1=DN.?90=HS_6.G!*^LB>+::+K%LCO'S-U?Q> -MYB7)6((&BMCGGW)ZJY].)LYJ1B -M5%@9Q(`V>I0<-MJPI,W-8_<"/J\"E^M6Y[=F4CE]CC@U:7% -M+S*,@?'XP7C?=C]S77H47<`;$-+AB2'?5SII!&#'!0-3:`)#9.+`\ZAH>VY; -M.X'N!\*M*9G5FQU3S]:P@]-`OME.K`N,,2^.Y;TTGVK]#\%X1+F`Z^*.G#0[ -M'7+5BR:G4LJ#"&Y&T`W6:82SA[C0.)`W*:N'Y*@9D`.?G8/`%Q9#31VG7SCG -M@+7L&4+C<@?'@MRBJGK7_TH;@F,9)G1D`XC)P'J9@N7H??+GVV:M3E`G"?V@ -M>%71:O5*X;'7IIMSJKH\N$^.18QUA$H5<8WZZ:,NZM6(^:#F*15 -MI[J5%NIM>$,DF7E!B,MX0C:E-F^M$GLB(RP#[]Y.R^9Y>1US#=4@]*&Y3%F>:]1C(?]'#4O")9CM2?%> -M02'.)_HJR\OMKZH#5^S0[.185IWTBPD6KV3W-O"=5_O)4LE=9RW98[@RTRME -MDR5Y7C-A%;R1LE.%#YU16M!O\4TY!S#N<@_*$I(1&6,XGIDUU>ZW%LU,F;<` -MY2TY:,1(!2;]WV=*NQ81O//B'!H<=]H -M1];IJ13/Z_LD<3IT@4V;^/0R5R`L`>!-Q`[8E*@U$#T2H97`M\N]^Q705Y)3 -MYH=[=4C`@:C-,E@Q+8.XV9OS`^,H&DKQOTMW8LB61D3)Y\&7;ME9\>5#/_?: -MX!%TA6I4ZU5\=2>(&H\;L0CY*)`>A-]84HU]\42D+8(I=)GPV-&55@%U -M\8-(#$HK6[;,I:!ZG'L"TFL*(VA] -M,B]Y6LR2RSQ;GQ"2H.NPZ8[YL6Z>FVC9T:;^/0I\:#:]>VS&Z3^$9[ZHXVAZ -M:AYS+W*/)!<^L"H!,<:C")1:VME$JBGG]L59CZEW[C$9'MSRQ@BD'BCL.*,7 -M=+*8$K/W^#':];GD-[YJ;;0UL\D+W+Z+-C0$[=M6S.Q7/.\KR\[60([1L(0* -MPQS\\7Y94(?#O)X;S)S44M\#69LR"LQ&*[HGATFI4V8%X6H#8<(2&\6$E5"! -MQOE]LV[ML&GJE2R@):=\U@*CY^9F"Z[:6]SGQ&5.T"+*DR5JP5\W[0[#4>9" -M75+,2TSZ>R:XE-B1QD4Z4A#L)XM34\;DDCWY`"`;Q0@_"^;=LL(F0[YE0H+']L=/&HQ7XXQDTZY?"D -MDV`6-0J7#878D'C*^``8"B(E,+(:FX.EU.]C&H<(M44S9TS>:0@OP,FFY_U" -MCNGE3M2^,2_L]^LR@S*[=1$A5FXJC5>(G@4B=!"Q3[:5$>!<[0(1&XUNPHM0 -M61.DG.#(-0MZ['KBN@G)%XL#L`S_O<,A-?[(>2A/$YAFRL.S\TDF';WP2J$8 -M-PXFZ_@3ZU-:WQQ[TD*0847@^')SZ.8E63.PL]@("!,7A0K:CG5?S$OI:_F' -MX5O$_:@5:B\3=G6ZG&AES$6PK`.MP,STG/J!_O9CEBB#& -MO/R0PA64E+Y+]OK`!'$OXMOF+B$&*XVLP2/CW*>D<.1W\U?FTWRA(C^,`@MF -M1/_B'VN.-%WLVJU[EA"E;1(6H@3*)"`[36&@[?IB-&?I5ZB.'D!6V_ODT?WKNJYY(%O:GDE&>+I<`> -MZY6$-VJ4"A6>-A87.:TSL1R;U7V+*>Y#B6$S0RNZK0]3G<2D1Q8D92 -M3C.IJTG.8"1_+Y!%\$J@!G3;^P6SJ4A*OHZI"5AOA_QG&LVB0VH;4EC*TU_E -MV;@1,E_*#!MTD^7[B8;P*"^+K#G?!UDZDI49QL+\,")7-ET$-/`,6C8+!^I2 -M:)DC8\+!W]/64DJ!3W.NG:4>>U:B>](T^4@NU4N(]MP)3%&K,6D=R<)&P[`A -M^]VV!F6\T^P@5:@NNJF%]ICXND]T`*POO7<:S85Z>7*_I_+(N;VN:$Y."U*7 -MQ%MIG!2_U0<:9,G!YG-DFSTT`&0J!\7!!:20-*-0?F$P=L3)'7IO\)SFM3X=% -M?!__R]ETALQ@!*Q0([\V2>(I='370+W;>YW$KV[Z^DGC*`H@S5\G"V0U_Z"@ -M-Z-5:-MUIHM)]]3U3@#Q,Q+_CYZ]T\@"INZ;KX?9JE\WA:0_DZ%MWB*N=OQ! -M,A)*YIC&2XQ(/]>NE^<%>NY#)BA].AF]S:[:L9W'_1N$$^[2EPGQJ3G`" -MX^R52LXRM!!"9#E2+AM(*D=N,>!"A=.Q57^Z&P`6H'0]R&-B410DS8`BV.:W -MF])S>NO&WZ9]J)69UT6+XZ6_3%+_ORUKJ#C80_`F-(G:(MN*(:H#H/$;3:R& -MEAG/M[JPYFQ([TA9R.3'.1?PSKQKERD<*%24DBJ<53[E5U@D!8"Y`KRY:I`> -MANI%B_>5/]C\D6K,;RYX)IF51K*"57#8CS#J5I,6D!-IZ87S<(':=1/%\EH_ -MW"T(B#.6_PX)C@(D?+#Z&A#OOF"!%Q=BPN`B>S]JI0I/@S -MYSUXPN/A+Z.EVEKRE!G+E["AW`%V4]8I/J6Y-$J@5AM+SOY`^KKHY9-;#!(P -M7K0HM5"^!T13A%X-1LJ%+\G1FLP;#Z9+*/P$F51YI=?]@O'#\&0ZC,]=HX=+ -MN+L@3=,UEX]S%$"*KI3324[R7<7?1X<66:2)NE=_>T\OOJ$G3L2-U*TN]`=I -M!`9#\7G@=S"U$JD4W#C]V^A!^^$AF]I_''@S\52C(006+;YEKX42BSKPU<7\E,];'CPJ!*7&?, -M)J%K%WWLI!2M6,RU1#VAGJ]J#:^G<`&@/2*D0,%[Q2 -M@X%?YA:^$&P(CXNA9Q-8BGR&BEY@2)D5= -M/5'8EJF/N7I3E8!>!Q%*5T(S.1$NMD7L5=]=\N4I)V)'W5^+#SI#;NGX-8?` -MW23W>P#!38U$:\Y4K<38[`WU_?!NSQL)OP80;:E6WJ'$&ZTPB%64L,1^`4AK -M*!B66B].*R:X3J)?YPU'-',Z]TC%)27C6.E:[==+^5GE#\B,C'?93H?HSY_O -MY4N47LKTQ?6A-47HE>4OD%450&B`+6+$`]<[.A9#F>?),P3@/8M%S7$WH&\4 -M;3\;FT/>!!E(J__9P?+7S[WL#$.=1A.931E8*:"#[%5=2Q'X=W*O9JD0)TF3 -MS.(;OX&SA;LYB!!;<>/V%%Y[?71\,<'P-A,0(FY.E+/PTE@EJ_MT:A/YO\<@ -M^]]A'!M7QAG4W_+,48ZS:@:XL%!H-&&!@]X7*N9BU9^1ZM@4%PA=0+801N,( -MRNC+A2.-Z$K,2NN80#26H("4[7-,DY-/WG[),^G9)3R?L`U8,4 -MV%PF!&\*U5AD9/X(.(LSZFJ5,1';1?,70G6L'E(**;*FZZ,Q,^,GR>C3:)AI -MSAENP$.^3F\^F8MT)B(+"W+%U>DZAF=#)<(-#CR3SV>J&-4F"YW<)0HDQSR! -M^"J(T\]M(G-T`U!;U6J>P1;YX`F6K^KL,HD&48,_+5*X/W,M_12A1:OCP&!, -M>US&I7(V"?9$/D0AI<4C#D#G&9N39K6<%-9BN!?MNF7E -MR^05`,]J_^Y#V.R)TW-%&Q>A^'UQF0S]'U(=VMGY?*F_VB]AR*!5*5-UL`>5 -M`(\1%UUI!M8(D%1C8[KC_WXX:#^,TRN"W(A'1]UAUG:./MC?4]BN-7J'5'%*S"&\Q]#O/]Q(R -M;&6+T!1K=_N`.18AF-[<.9F(8'^[>@;(:@KJ%">P7_OIC)(QH%'0QPA&8HGB(:/H,6[?5:,+C^C5$JQ`;BF\)J9A^VW%/W5YG5R.]H5_/"+`,44 -M$56V>'PE0I7;BKO6N/!@\?TRF[9M4&01^#'>6@VK=AWCTNO;=8F*U-^<9A[8 -MZZ5?L(\;[:9QT^:P5:X-;6,F-YJ]Z=((0C(M2*,F4V;_%`+E?N,I56]7`DA% -MS5MR];Y5^S84E?MKPXP!5.5A:M2GE8L@+P>2JAJV6XUOSKT=)Z&MO(U0D,V9 -MIGD@>E,-LC -MYZB1RS#W]4+!XN]$&NC+8:TCKMD@H/P6YS@S!7R)/Z-7B?G,\C\])9E).3;] -M:.*R[KBF$T??^@]CQ']B,_U(`<0BM>S/UY)+UMQP[>VN!\83`P^?G>2,304F -M)Y600:,7@ZNG+3$$*`.83-NP[%5<&.D,/R"`7&4GL[\XE)"+:>V%J+-EW*>U -MQJ6FY!P@F>[N"QQ$XDUD*-K&*Y&KDG516QKKF/_I\]^E7+T;6U#\H%JFO\@5 -MI-[Y$IU_&[<.2@R6K`"*^PL?5^SUZ*8I'+`PJ@J06!WW#"C26D.6[K_M0P@Q -MN#X8?V==@GI$8)NDQ2U?C4FQ%B>K](U$;>`#E8VV='OG,]TK"ZGBU$A'X86A -M+T;IMYE`7:U[V\*0ZD@$N>Q^G]IIVV)(W1UHUQ%D%*\`E,?+XRR9%ECFXS5_ -M7<\T%_\YG5PO[#'OVH*\:ZF?2VB@TLN\(X[]W7!F@#=4^=>!HY4%$P=`V*QV -M-!N-#@^+MVOUM,5K`8#13E7*R$Q)ZLL/`K;WH[U6PH6E]PI.OQQP;5Z4NCSL+,4+Y3KY -M?ZJOU_NF5.?8;CYK6:7-CV(=8RXL:86)LACKZ@/S5N8!*4/(Y03K:,8\/D'V* -M(S<95WM0QOYX_HTQL1N5*+`Q6>'(PRD=2P^`E`P)J;8,SP%0!W#H#BQC!F`0 -M4ZG:U;L%*\C)(;!PVF/(+Z-]J4ZW#2^^48>.BR+AB-7"LORBGOWY5`H[BA$N -M)W3Y_R'(=**C^G91I%XJT=,_GA<>JD+3:(#LFGJB*LW\5&CLB:>.#F8E%#6% -M)]:1X]0]!Q>C[GS26W)#J-E?W@Y,W:76#:M3O+FEV4\)OVL1C2ZI4[>$`'*_ -M_O;+ADT*SS>RI1G]1Q7`VTP(4UE!K'#)BSO^6KM4EP(#0^9AL)H#"T2>C/^U -MG:@V,$8(P(TD;8UDH\I6X%##=P$YP>=1F?/_FCF5MR3$09%F -M7KE_S_._VR@RMIN6PY'OQ;_S-F\;%Z!1*FS706[`K^VYM[A&%VSP?$YECDV4C7C"1/PW7^$QE08@5=2IXY\)\/DBOI7 -MX%-*O*PF\VIEOS.DAF5'PZ@`:/VEH#(C4IS;`./"23BL0!(IH`'V^@X_9-35 -M9J@[T]DCH!8.(H=OT(K'&.@&0OM7`;NO(_SB/[WUFT`?:*1`Z:?'[(O\QU*C -MYG&.^IIEO3AT`LXBX.GRVW.+-GC$&T-)&J/TYB%<7:8$V,DBJ0ORC2$`D2_2 -M#[9GB.991P)9L:"XMY09G0SWX)!"4=BHQMQJ+1O!H.:Z1$1VU?5O).[A#""/ -M!6H4OV3T%-EZZXN>YX!S\MJ]2+:3<;^ZL"@T-'%''*\9T.I!S28U50QV_?"J -MK[-B$E;O(ZV8[ -M]K7E#CAWT'@3)`[]"JF2#DPYOD9B8MTK)0G),(W>J;@-IM)X*C.1;:_S>L+. -M8?M;?J78[-L1R]6R2+%^2@KD^7W'ZA\5UB05TXU@B3CBJ(7!\/AQ5H\"_\SA=:F;M`=D%61]2_7LS#":2[P7TS^$H&GU$*R:!=#4ZPB1CA^<5BR# -M4PNF1%!5'Z;/4>,#S:M_C@;_YT.(0W6)LD0O$&.Y1-;G;T\F5"G1@00RT$=Q -M2=`X[9Y^820^U%%$.#V32Q:..ZE4O;;B!/5)UDZI6]P*>N]@^4 -M]+A?JV3&IWD_]]F0RO)'#!#]:(<7^A:'S$?@5A%FN;@:-(I\P/%%5$;2 -M]=[LX/-GCV^6$A\Y=NI'-?'3$*=#FO1G,P6#%Q^>.W@RR-J\O#MS`YIHR/?H -M:4L*Q65T5D%MZBZ]X1`\)@_P#Q)N[PW0KDL1OY?#&$([VH2-^&E)&4H;KNS) -M7$!(OI"->O84#:X+5*N`1V&G;ZQSMCAZ/RM*W$,'(=7^)772Q.\%Y^*L`!T````%`H!``"&-JAYL,X! -*%08!`""`M($````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_encryption_data.c b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_encryption_data.c deleted file mode 100644 index adedbc531..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_encryption_data.c +++ /dev/null @@ -1,70 +0,0 @@ -/*- - * Copyright (c) 2013 Konrad Kleine - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD"); - -DEFINE_TEST(test_read_format_7zip_encryption_data) -{ - /* This file is password protected (encrypted) with AES-256. The headers - are NOT encrypted. Password is "12345678". */ - const char *refname = "test_read_format_7zip_encryption.7z"; - struct archive_entry *ae; - struct archive *a; - char buff[128]; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - assertEqualIntA(a, ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW, archive_read_has_encrypted_entries(a)); - - /* Verify encrypted file "bar.txt". */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0664), archive_entry_mode(ae)); - assertEqualString("bar.txt", archive_entry_pathname(ae)); - assertEqualInt(1379073980, archive_entry_mtime(ae)); - assertEqualInt(4, archive_entry_size(ae)); - assertEqualInt(1, archive_entry_is_data_encrypted(ae)); - assertEqualInt(0, archive_entry_is_metadata_encrypted(ae)); - assertEqualIntA(a, 1, archive_read_has_encrypted_entries(a)); - assertEqualInt(ARCHIVE_FATAL, archive_read_data(a, buff, sizeof(buff))); - - assertEqualInt(1, archive_file_count(a)); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_encryption_header.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_encryption_header.7z.uu deleted file mode 100644 index cdabd247e..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_encryption_header.7z.uu +++ /dev/null @@ -1,8 +0,0 @@ -begin 664 test_read_format_7zip_encryption_header.7z -M-WJ\KR<<``-1(7)]@``````````F`````````!I:QVF.6KJ?=[:U9:-!,8A0 -MB6O0&LG!?DD:R_'07!.!NV;/LY)*FIFWXUI[)=TPG&";5C%*%S+LERGW+.D%XK*'>5.FQ>74JN]"%`5%TTQ[@L^# -MZVV`LJT"61@``($S!ZXQF+DAMZ?L<`,6_>V19<3;V2;&..`F/OY`DLGI -MB?L"X_1-'%<>!(3'6&[GTF&K$I`20KWW0T2OU80/'3WLJ@2\\?YH6A7J\T[" -M5JH6Y6_..SN-L'T>$^";VM@^(Y(^]N\E588GW68QK>M[C@$[AM@/<+RH]Q!& -J"GI1?FZ````7!A@!"8"$``<+`0`!(P,!`05=`!````R`N@H!F[7,7``` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_encryption_partially.c b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_encryption_partially.c deleted file mode 100644 index 68290aa64..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_encryption_partially.c +++ /dev/null @@ -1,82 +0,0 @@ -/*- - * Copyright (c) 2013 Konrad Kleine - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD"); - -DEFINE_TEST(test_read_format_7zip_encryption_partially) -{ - /* This file is password protected (encrypted) with AES-256. The headers - are NOT encrypted. Password is "12345678". It contains one encrypted - and one unencrypted file. */ - const char *refname = "test_read_format_7zip_encryption_partially.7z"; - struct archive_entry *ae; - struct archive *a; - char buff[128]; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - assertEqualIntA(a, ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW, archive_read_has_encrypted_entries(a)); - - /* Verify regular unencrypted file1. */ - if (archive_read_next_header(a, &ae) == ARCHIVE_OK) { - assertEqualInt((AE_IFREG | 0664), archive_entry_mode(ae)); - assertEqualString("bar_unencrypted.txt", archive_entry_pathname(ae)); - assertEqualInt(1379079541, archive_entry_mtime(ae)); - assertEqualInt(4, archive_entry_size(ae)); - assertEqualInt(0, archive_entry_is_data_encrypted(ae)); - assertEqualInt(0, archive_entry_is_metadata_encrypted(ae)); - assertEqualIntA(a, 0, archive_read_has_encrypted_entries(a)); - assertEqualInt(4, archive_read_data(a, buff, sizeof(buff))); - - /* Verify regular encrypted file2. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0664), archive_entry_mode(ae)); - assertEqualString("bar_encrypted.txt", archive_entry_pathname(ae)); - assertEqualInt(1379079565, archive_entry_mtime(ae)); - assertEqualInt(4, archive_entry_size(ae)); - assertEqualInt(1, archive_entry_is_data_encrypted(ae)); - assertEqualInt(0, archive_entry_is_metadata_encrypted(ae)); - assertEqualIntA(a, 1, archive_read_has_encrypted_entries(a)); - assertEqualInt(ARCHIVE_FATAL, archive_read_data(a, buff, sizeof(buff))); - - assertEqualInt(2, archive_file_count(a)); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae)); - } - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_lzma1.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_lzma1.7z.uu deleted file mode 100644 index 1ffb08f71..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_lzma1.7z.uu +++ /dev/null @@ -1,37 +0,0 @@ -begin 644 test_read_format_7zip_lzma1.7z -M-WJ\KR<<``,/HZGJ9P4```````!,`````````%+Y%"(`*AH(H@+[^>`@;QG5 -M&B5-,5-_QRM0L>#MM0W$-S'BJH_8IY"*#4L;0'F!$MLGK8$6R7(_0JIF4F188LW.NQMITP8HMUWF\XR7X"-6 -M&\D7'8\P-Y0ID%$5:_E*6FTAD,UZ*C8?&[QBA -MQ(`^4DD*>=?33B/"4^$0QU4+CRBV<#Q%I'ES]CDV4..(`?$2ZB3)Y9=*8YWP -MKD55I7'(RB6:N.K<<#K;4`K?8S5S74$=%X:A@F!?`%"G+4V*7>T.:+#D%NX- -MO"&K@R&0W=5=#NWE4]:?]-1"<@XD,`PD^@*?QWL.PCMHD':HB^7%580>+:B: -MO-PW#(>)-?"@^,U>D1Y=!9F0\6.0SH[GLR.<#T"+F'3+T``?$Z)4;/6X\AS`:@KC>Q'$IU70=EY/" -MI070FD?O5Z0^K4N`T=F%GBW`6JH+RR8H+@R/JYB?/IC01HJV+DQI**WD\"]) -MFE)I[P]9(OI08OF3`L#+:(H)F&6Q[Y+0GKAC:L!I6*NP(+ALQC@TQ[ALSYJ] -M1B`"6XJH3U%?E3+DA&F$]B0PH*]BYZ%_(8.P1]C1PODZCT1OR.:UM>7>W);S -M5IG800B9F[_=KY9L->M0JZ'C$?"&8X]Q+FU)*)I]F=ZH:2:[\.>OAP1IS -MS/%E3R69K`@/-\N#`"&QKEICZ;24_0BUA0CAEC&AHVWNM5/^CN&0 -MI;+M\"W1W@6-<,_&_OFGHG!&G+9(RA+9>OS697XLAU-((X>LQ^ZVT@F40:88 -MKTV4E(**WG*)U$-F%DT:#XT"I%>D3H<&/>)9Z8C%7 -MQ^#L9(.[[6#NB@B3J2('BE5;T*DM[/[UM+[O:MO6H_/>I=T]Q.)Y``#%>W!N -MA0,"RXLKB"M\7A$C!/;J+>F.U)D&3*>[=BTFB#4""R:)G=90L/;3[OZ\\5C%]"RAMQM_U,38(.3V- -MY[%HZO,JYWMJ="AK?7_"$8PI_US?N!%-+/2&VP13 -MKI2,&K,>[J2_X%LN:)1"&*"R(U[4$O._I5^`W -M0Y9^ZD6\Z7$!@B4T77'F -M$\[ZG7\FM@"?`-[S"MF4PY^:C$H!!`8``0F%9P`'"P$``2,#`0$%70```0`, -MBQP`"`H!Y1S\W0``!0$1#0!F`&D`;`!E`#$````4"@$`@/>FPNRIS`$5!@$` -&(("D@0`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_lzma1_2.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_lzma1_2.7z.uu deleted file mode 100644 index 70b03bd3b..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_lzma1_2.7z.uu +++ /dev/null @@ -1,8 +0,0 @@ -begin 644 test_read_format_7zip_lzma1_2.7z -M-WJ\KR<<``-GH*;IF@`````````B`````````--W(LL`,.P]5,<,713`O:V< -M)`.JE)L$6^G@````@3,'K@_/;NZ,!\A#@(.!6_^L@!U0&A2&3>R/[PWL=[H6 -MI6B>-7,"LEFSPJXL&_5`VI+39=)!5AVU_MRZJ-'/$T<4 -M$.`BV?:<->IQ$-K,-DX=!*T>*)Q&M+J="/NB=:8'E1X3/?KZT!XEN'99V!2D -HL??E````%P87`0F`@P`'"P$``2,#`0$%70`0```,@,@*`<_EW0D````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_lzma1_lzma2.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_lzma1_lzma2.7z.uu deleted file mode 100644 index 4de527e4b..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_lzma1_lzma2.7z.uu +++ /dev/null @@ -1,10 +0,0 @@ -begin 644 test_read_format_7zip_lzma1_lzma2.7z -M-WJ\KR<<``.;^9[-V0`````````B``````````(\.`H`,.P]5,<,713`O:V< -M)`.JE)L$6^G@`.``@0`670`P[#U4QPQ=%,"]K9PD`ZJ4FP1;Z>``````@3,' -MKC&9Q;Z1",.ZTR=H7?D(*P-]#*^T-I.U$V\S<> -MW,KQ]&30$$K2G.A@ZB\TJ2%=E9LVPJES']:2`CL-F<22BZ>*M00K1&/TM`@;QG5&B5-,5-_QRM0L>#MM0W$-S'BJH_8IY"*#4L;0'F!$MLGK8$6R7(_0JIF4F188LW.NQMITP8HMUWF -M\XR7X"-6&\D7'8\P-Y0ID%$5:_E*6FTAD,UZ* -MC8?&[QBAQ(`^4DD*>=?33B/"4^$0QU4+CRBV<#Q%I'ES]CDV4..(`?$2ZB3) -MY9=*8YWPKD55I7'(RB6:N.K<<#K;4`K?8S5S74$=%X:A@F!?`%"G+4V*7>T. -M:+#D%NX-O"&K@R&0W=5=#NWE4]:?]-1"<@XD,`PD^@*?QWL.PCMHD':HB^7% -M580>+:B:O-PW#(>)-?"@^,U>D1Y=!9F0\6.0SH[GLR.<#T"+F'3+T``?$Z)4;/6X\AS`:@KC>Q'$I -MU70=EY/"I070FD?O5Z0^K4N`T=F%GBW`6JH+RR8H+@R/JYB?/IC01HJV+DQI -M**WD\"])FE)I[P]9(OI08OF3`L#+:(H)F&6Q[Y+0GKAC:L!I6*NP(+ALQC@T -MQ[ALSYJ]1B`"6XJH3U%?E3+DA&F$]B0PH*]BYZ%_(8.P1]C1PODZCT1OR.:U -MM>7>W);S5IG800B9F[_=KY9L->M0JZ'C$?"&8X]Q+FU)*)I]F=ZH:2:[\ -M.>OAP1ISS/%E3R69K`@/-\N#`"&QKEICZ;24_0BUA0CAEC&AHVWN -MM5/^CN&0I;+M\"W1W@6-<,_&_OFGHG!&G+9(RA+9>OS697XLAU-((X>LQ^ZV -MT@F40:88KTV4E(**WG*)U$-F%DT:#XT"I%>D3H<&/ -M>)9Z8C%7Q^#L9(.[[6#NB@B3J2('BE5;T*DM[/[UM+[O:MO6H_/>I=T]Q.)Y -M``#%>W!NA0,"RXLKB"M\7A$C!/;J+>F.U)D&3*>[=BTFB#4""R:)G=90L/;3 -M[OZ\\5C%]"RAMQM_U -M,38(.3V-Y[%HZO,JYWMJ="AK?7_"$8PI_US?N!%-+/2&VP13 -MKI2,&K,>[J2_X%LN:)1"&*"R(U[4$ -MO._I5^`W0Y9^ZD6\Z7$! -M@B4T77'F$\[ZG7\FM@"?`-[S"MF4PY^:C$H``00&``$)A6X`!PL!``$A(0$( -M#(L<``@*`>4<_-T```4!$0T`9@!I`&P`90`Q````%`H!`(#WIL+LJNX6*J`]\W5 -MV'E1<]9A1&J5D`#J!0K[IET\(=96D87RO?!\YQ>LH!0''871$*/B-@-70EJ0 -M`;\!OE9CF-^[@!DI0LA7Z5P`#.!8`&65OAKG.CZ"F_H1?0DF"U1TA(*8JEQ>/>U8FBB]^E)QG>MQ_LLWD%-YVI_%$>)09X;WO&$[MP([#E"AI4U,3VSH@/S*]#&EGP37GQ_#W*+P:2"&0(O=$S'+O'75NH+-'ZI&2 -M9W^I\?.Y`$T4YPC[ETIN9KTL\>"^-]*+([,!RK2%12BUU!TRF!5:8B?]<3K' -M1/*E5"22231Q(@S6P/`GO*EAHOGEC)B5=%X;>B*\-D*4#KGX(2,,P4)Q\PQ< -M?L=SG>R/AC>SH1S1_FUK7"#5\]0&QR9`];@`YS*UH9Q@P^S977+E@_P`0KHZO?1>:7[4.RMGB]SF\_BQFC89B)!U68-_]72 -MY'BDKM\E;]&4Z%FR?TOR2'H[7X@Y6`M+Q@![*&M9W!0F#^@UO(8TK]U#-8<-I\2$7 -M#?WC\89&95YI\\`DXII"-P@0IQJ:L4]:O*=@V!W58(_#7%9L4BR8-<$P`4S# -MJX#Y/>DIDB#/.0DY67H@K60XS/*(46/U*%P?G\R_U#/(0%OF -M6B#:U+X9)8*I`.^U(`PKV^7%B=?Z%GP^8CQV8V#'_1?L2KB>;6>!N.8LI>3_ -M%)-N+<;/(+J(QI_U+9C&*VDR9)8X/!5R+N8W6N84NN@'S9P>KC -MN]XGR&MK!GNV=Y(MV+YS=QEYQ-,':9VRQ^N -MPC!ALZ:]"J8\:9T.Y28?K^B>@@5(:I]M>EFH%-#Z>BRBL(L)]_J#F -MT7U4C[62SWU-_0&#JECK.K2F9Z/5_U\6"K2[$'8K*N!+?`(T`:3BN$=LA)7? -MS`:MK/59JR@1*#FE_'[X+C68SP*%RH -MGV(2K8@W&^<"%O>`1]-6ODEC`^X__^'#-E9'<`F-W+^-/#*=00[^ER5/Z%<; -M<5>252LEY6L`C9Q:-4^3!XGD]CGO,-XDLT -M.;'"/12=:`C.Z+3G1-&=R-!O#5,V.W'"C9:N4?==ODY8#*:V;QL.N$ZR'R30 -M>U5QC/A0M`TOK9EX6PZ03U*3E;4527?8OP\+9NXTSDP.-ML`U\:36)X[JXOZ],_M[4ZD"D0T.7 -M3C*M=YOXBE!`I5-VO'3:YUR-42G):6"01XCG5%O]H17JJJQM8A<<,3RS8CI- -MT7FK7"\1P9GO?#3O07):>\L_RHRH?]3Z#W42TX43Z=2HC/8M!H]),JTZ-@/"U#%4-Q#G9EP-$Y^]=$>X70[D -MCP*^+R.X5U[;%+0P8JWW)`P#'VE[%=I>G;TGBX!_**[`)D9.JV9DAAYM[`"# -M0]"E%F5%X?]_%@,>,Y*W"%H.!H6KV`7H>4&=7BX&?6K$"V@"*\#2BVIL.FH9 -M_YP"D5UNL[$1$U$GLQROKS__F*#'PH`%ZC5^,0\)'D&S:;?)8`WEYT,8"? -M1]-Z'S1^IEL/*WJ-LQ\;?%QQ8/*JUY93:52Y,XHJNY<;Q.GRQ`&ZY5)H9'2< -MVT<0P98-*4HW2:\I<\W>0HW2E[B9D8LYS:````$$!@`!"8>X``<+`0`"(2$! -M`@0#`P4!`0`,GGR>?``("@'AQ%XU```%`1D!`!$;`&@`=P`M`&<`;@!U`&4` -D80!B`&D`:`!F````&0`4"@$```-.&5"B^),$C`%""HM.8#>=`#! -MHGG`);CBW],\(2H/P+,[60V#BSUD@SPX?+]7UE`-G%X8-3UI(38JH=H'>(C4 -M.BHYW!+WO_VP/@H5V?EN8ESQEC<5V/WV[($3WNDOW%0OV?,5D(VX$W,9F]X6 -M$@+,!DJ9MCLG?+981]+>4RH&\+O6N:Z[J\UUAP1\;YX=FQG04]%"*WE/:)&N -M7]/;*`CB"$1/1LN;6/@^--#D_P_@^=I7&LU`$C*&]O)XY16O/YBAT\L2Q!M6 -MZ,^,_"DV_%G"4[;]`8E`Y>_4'B-G'SBG0\P#T504(#V)73,/E2#B3I7=S".' -MT?4S]U]05SC_GJUAE*!NK%8\&=\',!%JIL5J>;6'O[D[_5JVE7>4\(D]JBL8$[^!T?<88]&GF&D!J76?C\!TV:R8*BQ,2%*"NX6^-J!7;)H[ -M,VL2_VSHEIU&_VR#)=O81/7B?&1://2C9_O[-3*X(-,H(QI$N8$/CSMR0_PU -MF+&[-\:YPQ-V_/\D'K<+P1?:NF3DC@(W0X+$X,HG8*-0_+3@`07IT`9`RZO> -M=4MI;EB=PHN\-U*#KN5B^JX'^8EFYG-3'H?CITKDVRN+'.(ABHXGW.51@<$J -MTX]Z-:0Y]$8M))->TGEHM">WLYXA/P.=F-)"H)_M7B5FK,I=7R&:5F=A^H:\ -M"U3HG2Y>^C\3P&?0,F/>+S1<<,$W5!DW#+5:DT!&H>R]*HYAL;3=`9 -MG-6=ZO*O/-T<0GY[;.-GK`F4@EZ(HL.JR%:.V(7[VY:.`?"47U/P;N",R)G" -M%MX4UG$88O@.`;_;(1W&"==@<5,SMBD.R7>ITI@G5OR14O5NB?*E!["2KU6: -MH+P#/KA.)R4]DLK9W^<7&2RL#EF40DU1*VS`"A%7D5^"M`OB.0W5*_<#5K7* -MR'D05`R:?G3Q$`L;B5>KD\B"A%!FAV9F[BA2=I^AWD%J7`WFL7T,T%?%VI^; -M]0`QABMO4"3N3&-",I^)1E`Z61GN*(E7I&+P'2/Z$W,Q4^P3@1\Z01D"VYZ! -MZ]*!@]@/<"ZSHHN2'Z66_/Q1';U/W@:5/JY).$#*$JYEYOXW:DD&\7,"\NUZ -M*R7JO?D$*$NX)#AFK5F&$ZS`,HKM4&XRP,+WL+W:X2X98SA`L."UXPSOZY<".O^LP->K,4?Z-"*L#Z[P#"4,UW54G>W0KX/!21G-DW010]NZ54" -MT?"[+_BDNGN7B2'-)K$-,Q;L3<*/`/+A_EM-CG,CZT>TOP.1(>#99CO&/97= -MB[##0N[?U\)&U'1(]0CFGJ2>AXP_3RLI*,:V)B$I-<88"C66?>!/I0-YKR[, -M,(`W)51UA>T26X/6.,4;@!NGC*;0VLT(3KS2Z>(RX'MC'$C+I1BBR!)!)C1* -M!AZ7_:5Q_RI!L!3"6M0;8&NO0V2HYVA,"18X1IW+/I9?$B,06BS=Z#B<$J,U -M-GI\,NTS)(%MEW#FI%Q,1ZU30VDFO38M=_@*<2-HT`H>8VF^;V6!0,8*T'5/ -MS(?V9HD%DO;K^EOY8MB'_7J6P=+7MGT:AAH>E977IC9\\<$?0X0CKH-,^Y5$ -MPG(L?(8VYY=8"QMC)#MW)JL9?(`E$Q-65D_!\FG\A]NOX"3KECRR&I/I,-_L -MY&!L^F*E(.H&^C3[CL?KK2\S60UD3W[E,,NZ1Y^*&S@5U6J#BIL,-/Q?VP9< -M,5*R?(?<6J69T=K\E=)Y6T0$(RM!_S!38A6'S"CCI=F<`'?6/*5KS2L7ON'B -M:!)QKWUW%-N6`)K7@<="%O@E[$=W9+1;A, -M+'*KT@O#)$%J/;W$T,J!'NA?2G7F7GK88KT1(K\Q52<<(!S6;SKP4H#K%(SYK0`B,Y-/&7\3]CZ/'( -M0@61%II0K.Q,&R`2$K'#I8'B(J0'\20($ONEJ2AXW;-'V3AP;9ME^L7JBW46 -M!+9%;M7.G(>CLF;A8*'@X"+832%9%WXO^K*>?/(]*..3\@`!!`8``0F(```%`1D"```1$P!H`'<`+0!A -C`'(`;0`V`#0````9`!0*`0`R5;397[?9`14&`0`@@/V!```` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_malformed.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_malformed.7z.uu deleted file mode 100644 index 179f633f9..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_malformed.7z.uu +++ /dev/null @@ -1,5 +0,0 @@ -begin 644 test_read_format_7zip_malformed.7z -M-WJ\KR<<,#"@P/<&!P````````!(`````````&:^$Y7ZI7Y%&2NU]#ACBW?#O?,F:0#Q9-3ZZL%V%&9)")/O0#;Y`ERR*'#+W -M']$)-E\['NQ`D+7V<4:'4&A)RGS'C>O$2723_A19>9;,$\2C0JSF4UU1"T(U_'3]MZO4WCT/KJ!WNF7\9M> -M2GXEEV9?@RB[9!KSM8!+'_BZX-=+ZQ1=P9AK2U;$U,*>;OX -M0@8/5\`&O3SX0XVTNXGBYWV3][>(89;V#5^B(ACH].`\.-`]#JV -MHNC>TVUX7KVNCA.$;7;W.='`FN@O/(`Y]AZI0RE\93@;9W+HV5&%]I;G>GYM -MI16P"$LPQ&GJL'4'2!:_9C9;<>&"`IM1Q`FND+]]7G4"<0;=..Z_B#^JL(X -M2K!SX%3;4[HJF:50YAG;(F)YR\%_Z=P9PR]DD].*[V5GCWK+\0"PW9=6;PI< -M/"P0T.4O-3K1JV[F=R;7WK]AX:?IS^*O)8`8M^1OM^"SPN97L#JY27PRN?'7 -M+I?=AF\-5G?_6`!]P/J8GJPX'D8.%?:+BW?;LQQ&0TR=//LV*B#.`D*=/,$M -M+M7`:BR$9OJ(R>W5(G]52E%MT9EO:`P.5O%)]I?41B3FK-7XP=/H%%3>^E80 -MT?LM@9V`^ANS95,LQ*9V()?@7I+0.^E]41$[("M"KF,FCZ;0G"J&FSTP'L8G -MNE8*QAE^PQ/!DZ`J?4&PU:(Q!B<,:8B>\$EC8V:$?SS@W-,QILBTWA:#1TF0K(\L*,>S -M+OS8S*UWK;Q]5`+,A8T1MG5(S&EP]C3,T*3KBOL+_4B6502_0D;R5ZW&6M=] -M[-/6Z^@?ZV**CE08_T(K$LJ-:&^3_^AU,8HKMJ;FUD+;MO\MA[K94?PH\QFZ -MVXDVU;ZL^QXG=8TV&.(^VX7:(FM_$AN[UVG$@^FF5,/\J:U[=SQ?P`]F]VO4 -MLDRP[_BGA"H#QT!6QKVMG<@UWAB"GT<_\E^K0[)J7YIK#J4!H0])7GU,XPYZ3_=BO4/HO,@/H53SID -M5?H$8$_JYJU<[WO_`([=&L##U@@&TSG]TO&PL1-KZC`Z-3/23")$^!&'A8M^ -M$;)#(-PGSS20[90Y0-2/=W+14Z2K[0>`L$==*1#1)I$J-O(;S%"9W4>N0.L1 -MG:FOM4(SY*&HUF)'U^^0=JKX4`9U:#("A_ZTG85E"A\JA$!4&F9I%A8.S5:*[T+`TJC8U.4][SP-6"DX/&8)42:!6A>)>2\%O -M;K5>3\@H=I@JO9J=SQ_ELQX"=6+3191GS[K2$-,M=`$(R!O)G]U&GKPTY9-H -M\M-BUW4G0;.GV2LB\85M;0,$`73VZD5N9F5Y5TA&TTG-H4)!K._H0SL^R7)?E$@ -MMT3WC0WZ8>%+K-/&F$`0X>8J&FXK4S=#:<\@;*_&P"$I+*^X"H"D5K-OWH,& -MRD%P6`GJ2M!]_<%EUB`,ZCY=#W8$FA(D'ZZ>:79YF)FY12ZJ5_`[8;6DH6+GW'+!Y,DE'/:@ -MR45)C`>>/6O3+9.GWKN1K$;HH+*;XJY-S60TGB;[Q5O652H+2_8@[+,`]`W0UDAT^NDY9DCXF\]*?MV>KY0^( -M1.)H'^I9R/DH:WZ>'Q.'DY/IV\/BV<)AX,!@?'P -MOGPQ,EPCA9>^Q(:L1`81]IXY.E#ZC)@K/3RJFFY.&I&STW.B4!&HS$U";4($ -MM]05YW/AYKDSNKUGNX^/?M)<$&FA=Z.YS-7H;PKL`,8X,<7\:O@CK(:9HB9<3/QJ?:3;[YA"D0G`HI1^='!@:)+Z)H6%5U+>%?@V:/:TG=O:RZK\-DO2 -MO\"SNRHQ$9?O#E@F)?X(R&@WX+[U!TN7RS,,W*_.\2ZV7UJU*(_;-T<^?*;D -ME$0:8G[&U!^US'W"SZF;&+E6UW8)^5(_<+!_[W1?5W2X)@2>(AO*&)J$XQI6 -M\%]WJ2*.9$M0))3G!\6:P9>5=Q6T09C@-OE:H!8(+S8G.,'-#N77=8$Q4.6@ -M\I0>B728L0]O^0JWF3XI'=4:9VY3*2Z[Z=4;3=[$QSBEZG6GV@QLH-V1,:@0 -M5L/`VG+1RZYA&?>@Z4!=T/Q/B&G@M`PG\M5#?!%X8:JMV%3ZU2,Z6^,GU#!0 -M:X+)+MM[SDL]R\U!S%SA(ZG*EU<)_/OGA-&^6:<^7%-#R,\L5_F+H0UB!_V]T+NC*%X_BR_X_R,EV>K&.F@@8HC%F\ZK[?+*UC"!, -M3HEW+2^'4B#B@,-#^[$U]X\$RB??28MPX6M.D_1+@!XK*C&241F6>"]](:7%$J-59U&IAX.*F&1N\P`5!&T`D(V$8TJ1(+CJWJW:98B* -M%N2<7<`YY_?7=#^,DZBE%S$.=-L0DKTK+T+KV>YC5C">Q=_]U<'K,3((%JQ] -M6K8.C\2&%$:-X-[H;WK>"%EKNFJO5/B!4\7KAI]'^2U.C((O,J&$>%9U/)3: -M7=`G_3BY[&F4W67V&3R5:?141*6"^>ULO9J`HW>GCN -M;)`ZF-^-+Y#;4R^,#8IG@MNCW[WA[KKKJ7Z.S3WK)J;>Y4X/$OMA6&249PSE -M^"M;RXH0B_\_)ZV"[8)]T(1M&MX.6IB2BJ%%#00"',25?S9>3$@(0W!V@ZA& -M(U$6<+YK#]AD3L -M=J.090H:E5RZF`7M3OZN)T%T\*T\MY"OZ_B'[&1.=R.@LQPZ>-(P/T['BO&C -M3>(:C,4:2UNFZ&2M]P)IOLJBX;C#)PY5G*=JPAXXVZCCOKL6*<0QZPUK\0O_ -M_\%0,@`NW>`(!9CQT6QWM9%_,K(5H]K"DLRUW56EY-+M7K`ECGQ/E&0P7!&V -M)&PZD11#0OB)^7,=@PZ'")M`D%F'8Y8^LY3<+8)/=PY="BQL[W:U&9&]HP$3 -M<+<^=.M]@J:K&8I?EDQYF;"SC/Q#T -M;(\]9H"Z.E%Q.6LUCT$8$B6^L1O1.P.X/#C!-R_BQ:+[C:+&.^T:FN'F[-/10^_VKQ^ -M2V!9RX9'T@U_+`5@4AYNP%$:,^?"84J\6$'IT<[E7PHPZB*3@8&MJ\E(:AUO -MILUW\77FA!2GGT!A9QAP5*S?1>0/2Y[5>,$2E+Y?W=5[NGFTF#28[=0RAF:$ -MH+3.]HYS!!ZMS,M7BKNDQ0%UWYR7`IS"(Z@`)X;HU)VR,"[Q1B&IYPYY'FI!WPTX1KC9\F/@`.\4AZ\.J -MIJB5X[OAXTR)%2:866ENQIG+="3MFC9S?7H1;)$>1"AX=MUY+AJ=ZV2Y6X/O -MH(1W@_X93V#':UY88;]^RO&-0-MNPB_F+C;+L7R:7:Y^"-M.'`Y;N0(10J`I -MZ,A`AD&#@S!5[ZHL$)P!*4,N/;$, -MIQ4@7Q6`H`8W=EIG#=QJ-Q^34O=@Y*%7BS -M!1AR7N:EC=J1(B#G4FX7.IUP"-E6T\X:*@R1K`W'=?,6KYC*'E -M.IDQ>6LVPZ/B+(#%M]/85)2/X26+#7ZCO:P8\EG-$1MK4_Y$G8/0IRVTER6+ -M;S(((YITJ1G#`$=4QRGZ`#Q3#6J9T)WOIBR`^\B7V>-V0Q=@5Q7USCI>E/J& -M-Y&IRT*%>$BL233JUBR[.B,J_)O]459@@2XP.)D`M)_D\6F]!YCEA]D^RI?0 -M<^L^?"1$;WW>\D,MO+H2ZK3WC&O<+BCWXNG/2/-`R<`>MO1-HP5?,4.V&&;E -MKE4B('N!YFR_IC:#)W$4AFE+\)WSJZUN_/;0(6`C0T\.O9Q2-Y'H`,0F/3SM -M@XUA1H.!\HP:JK^-Q:P`NM*53:KPP^!7A[DDSN":ZO=&Z'X\4[C):T`TL*+@ -M6#RD3[9.T"-B//%BO6EAV=DW^CRB"6+AIYW+TS=/+I;74V*$MQ;WC`G(/Y7W -MTS94=V\N[31FJZPE]S$4S;^(?*I]5S9,R%<60(^DJN!"]VD^!-$?Z=TD/2LUA*]* -M9H2O\_'4&-"`II"M!ERA'!Z]*$"K>\*(ARO@B?5 -MHMQ/)H+8>_"*MM@%WB7E0ND>PP(NL4^)2W3W<&=VN#VQ2\JHCFSYVP_F," -M+81Q60"2:9ONC?@T?%3V_N!6/SE[-XA)9BSH#`MFW+I-H$R]C12K>@+$V!)& -M_MPZV\9#N8:::EZ_Z1F";.7(8^8F%=2?[N71\Y6*@H+J(:G?J3NBO -MWOG?TV+H:Z9?DVX^![.*`V3 -MD?#+J.$<%?&,ZY'[@+8IO\-FL;\-!`_(F6+RFKG2B'PB-W -M.V#0KCHO[4/E0.E)XF/7AG9F0LH0(#!5/N3:4G[)=-:*7?*M*=06)R3UIJ<* -MPE,M%TFHW8\T>KJK'.R!HVY([)*CA94(@FL]^!B";$<\'DL86J<4&>V%ZS2D -M^\HZ_)I.GU;GN+/1ZXCARQ'KOE&QT+>V -M.>Q\!JEH8>G\/F(*4J2-GM?YB"U*]QPG3GJQN)R=Y,Q;J'O9-2$!!]N*H0*]@#H1-M]=:GO)A&'DVPQ4EO:P!S#A -M$3Y@\N"22\L4BHTQ#%SV1*'82BRBI`ZPV&'2ND7%BR_03SPLK!LZL*2AV6UT -MR7XV:E.(J"2['_CQ$0WG"/%F7+4DO4YPERJ!L*`?7'3&DI=`:4]X)P2Y!5N19V@W1@RI+:?DA$[SZ$XU180.AP%J4DI25";F-9?M].(-_G=*@<0V1 -M.BZUN.N4ZR:26"=<4LV125$XYQD)[YH*K\.>QF>)^!2C5MKE\JRV^.&B;)MK -MK$C'$9Q_-GPH)OKUM&D.J!0;9AC>Q[HFF_,DH,8CD4H][4;QZ_US//J<%W3Y -M[?@#@8G(.M<_ZG_&INAV`5"U@,")`,QZ\`!D#G*0M\NEIW9%)Z\'/LQ=9RAJ -ML)DXC+G.4"$WO<@A_)=YT]^MF^<\XB/$''DI\/JBL%9JMXCI@F\1\Z]ZG@LS -MB/2E,6"(8LYA#+S!+]R_9!!KTKT6D\KM;\_6_G`>Y5A,&AX*,6+#2 -M8=E?W0W?L4.W/W8``N;-Q>+^A0>D_178*1K[_*);FB_[2L-LO015#FZ[T-\# -MW_>5$\_74TF"\._*4KYY'^5)6+^%;&H>X"-I3![@`BFC)MP@8P&9(]'90_R8 -MK\R?>3EI*N0V)48'1)`[Q;*M^B%//-IX;>DM%_E"MB,\L;O2'#2,DZDM:$$4 -M7^W_()&D5+@>H0O""/^UC,IE46^8""5EU`2?5;UOG+363+.E;6G'#]A*OG61 -MP:$B2[.G:4.QH)BHW]('32(N+6!L-A,>&S^+X,]AC<,YN5M[WY1O_(.3/C^M -M_B0$87M:'COA"AIH!"6F7^`[&X41>313D.W_)"0&#!^Q./U_)R[*"@LFF.NF -MI#`($"-E;+\,EN^]P>L3#B`'WP3]1(@R -M6ER+JS&TWD#(\=WRE_5A)(=I.(<%71X'J6T_P51X937/`1]V;8T^PTI#T]S2 -M"+,OM[,0:KK,CS+Y%61W^5/,CL3#65X&NHX4SDPKG/F0NDKOK@0MJ7JG9!+E -M-Q7_@NYQX0O9/JX3"$D+.QU.$W4^&"]XY7$B0VT)2)3[C&@F:#S5]9:>D#&^ -M0KK775&&30U"RZNV]=9VHPHDQ&R[SC#\0+:@'69V#3MK"RX*E]/*@Y?E%C8/ -MO(`TF=1?2T([+H+%END]W+ZGX:MJ(FNTKLEB.?,G)SV?EU@9#SEGLMYK4`^&M\I)[!"K&&BQ4# -MI>RRF#&&$&:B[2&V$)T/"13]K[S[(=6M(\(IC2/$"WL)#SCHZHYU_`.W*K%> -M=KUGCX<1P^;7]?VZLL/8UK)R_M%?-]%CNF:BU-?G<;M?D+VN=,:?*RPR6`LD -M00X"Q=2Q.H1HM`**BRU_.>D'7ZRK*%*OW:/\)9K\,``JEK.,@AJ[SS+=/F`# -MU0MF.G#VRVOR_K$T%0DCS`1[/:H$X!_`&W/B1._K+-3`V:%7&&QZ`@7[EP$) -M1W%6<_KO.-`OE3\93:R2Q8H;`I^W=F@PQY_N@Z,]#3E+G=/:,0U;3ZYH!L]IQ1+ACK[5&F)5OD\V6.7O6Y.+3>/(I#J^ -MW82,N>24#>"R^'CR?/TP/'M#+&OAAA#O^6ZBZW;_8-04,E<4C9BL)/LS>JF1 -MAXA)`#^D&A,)8-JQ.K0()@5XV_9C0;Z2K1RT`.:PY/DMBM.?./O.%ARB;4Q$(";3(< -M*'#]FG?/11A&9WK;\&L,OZ>`ZN=!)E:8N)9:DGICN\FO;6`P\Y?@Y7E)97VW -M8-V="CWTR=M$X,IT7_O:\_I/#8Q>%6@%]#*6O=@^CQ8]\">+`I?_XLHXY8.;2H6X\W_]Q:@Z_[-&7 -MN)8:KT,Q^1XL-[X@`:91T`+3)V>0]`-GK3(8(3[".L)LUK!9U3[EOYFX,"=5 -MU2N[-?:4%M^WD_(2Q;[O&G'D=)@U0WJ!8O7,ISNMH6_4W;74(\D(EMJ(2Z2? -MKG"?M]JFR]*V&[!NAT]]/@84P%2R6KZQU39A=K'\8(#G#]VA##^,Y*T?(%E^ -M$ZAO:-E[CX`@Y_*[M\HD8_#"5QJY'GX8)H\H+OJ`U:(X)HRN*?)V7]YZN`JE -M?B/"=_APG@NXPU']%29T8)XVJ=U+0M3//`56K@_?U(8ATY0$(#%27]'JR)W^ -M10M=)W>PFM&@:0%Z%<<:''[="W2YR[=A>91]\'8E\#L_9`^#@JO\-.2%*$7F -MR-GIPED#8E""_`1K/=5;8Z?;.?0[UJ.G[+J6=`1E'YD72KS5M -M/O77V_O/E&(L?K!W/%%*N="4MC+M8>B<`WS)LOLN*&5!0J+2*PV(.SP@2+M7 -M8>LL8'#VBFY!?2DT'D(;0?]8SX@271HQB@`A`$'ZBHU+&L&[C1XM#AT9RJ13 -M"0!_ON:H\4YQ>^7TBQ9(]X:#F?80TTB=O3_W>C\9X4=E@%U6Q&^94'J@4Q:1C6*>O.F=Z/'M=HG0!_.S]$DO()[7"9A*D+M7>>9FM-V@3G4T-2 -MRY1:ZCU<.]^/U@(!BG49OL_V&@4I&S#8M%TF+?2R*]')065)K%A.[_7)K+<0 -M`?$ZY=4+B6U]*0Z$D:ATPIBR[,5H3;I7Z#5YAXR9&E*MR>DSI[1%\WS]N"LS+W?:5P"=U5/*,LSVJ -M;)8C"[5)-^36`=2MA\W[L9G'6ON9U#W)_+AU9E\=Z69.\5JC7-QISP(./D$( -MJ+MH`5+U)^,])Z]92SFI:(6@MU17,`K30$V<8>*'8N,@XI/599 -M12JJT9:&W"\60UZ9.2`J;(V]"409D%531E=A"DJ4^H=%*)8N\6@;/.;CYF=1 -MMHBVQ0,2M.\;$._4)72,K17B!:=2<)HOC#/8ZG"G9?KH?M^\%Y8>'$]LZ$") -MG54$P"D)4X4K/OT,"ID5'\CMGW4^9N@V,),;L75.TVR?OS8)-\A6<=(JI0R# -ML:WTK>.1T-<,BSR+]5CWNI%3+1GJ;G0.'H\R8)4;_F/N+AJ+(_$NQI?B#"8F -M!WEMDH.WM3MD<^.Z82;7FL<%.B:XPZV):]PO6?(Y7)DV$'&&()N(U4ZUGX=E -MRJ&/-+K7\\(?UXZB1^2-_O=`77U'H:)@3Z3;8@F?*_7H3I9T"&P*/>A"%8B! -MAD#`53B*OW4^\1+I$RF3V!Q`.^2]Z"H8Q1F#-44CRN3IZO== -MA`Q]F"6Q((#H7V^6Y5#@AQ=D7D6[W]LQ -M(K:P.IZK:P4:SUGP^TP>5!7>*?X:/A8J4?9+SO.P79>LX)5W.GE!S"\1ZS2J -MU'$,XZ3E2R#@_^X8E.E-_$EM4.>3$5:3P -MS/>@A%K,_XH:DA8D^;["<7GL/X!A=,0M>"PE'41++V?8:4MV'=ZJ>RBLQWJV -M2^,-?N$V>1II'ZE-U"^O+0#NP-1W0$,@C?NR%/T -MR@DA=EJ&";[3A%>CWM:P4\&PN*U/M6\?:GE%09*3:$Q#S=W>.6TZ7VZK+^5C -M%5RG*B9^'D,D)5\DK&]"%^B>V(N4R$1]SV76;.AU4K;G450JS>"UBI4EKH1L:S5\ -M^,!G;60:&\'O,C51<1)4V,06GE3U/8;0V7T`>\5N[N7UGX$XREJ"NWH3UC`V -M%)GF$O@_097?T^4FT@REC09*7W-T-2BV9DW+WD^V_%C*O&!L[3(,T<*(,CWT -MH3-`3152[H8;@*.R:W%%UP%$].\:2#5`N#1NCSJ8/1T`17M\1V(3,#0TU:A+ -M,<>JR\_2KW12B;.-XSK$BKCGC``F9(O;M$JL`WEEHJJ9_$<@ -M%BUO[>[X/-45/*\'J@/:Q>[TXZ9U^?[WO/&T\SLLS4634>9J&DFW,C$T`W\5 -M*6J"W%)D?+3OU5+QA/KFY3MVQ5\1`8/?!X[>%:3M:)0#)]P.[GN]R8P5AI4# -MF07/@R/"='NQ%8EZ;Q?^HM4+LZNI:R2^8@\A&!G -MQ%CB?!-?M'4^J5V/P? -MMU<$MB[*VB/T3>>[L^O5U/%B^"=\/D:AP\`N@HHUY)Y_HI'#Z1^!`>(-YU6% -M?_]961-](1[TW$1;,U_"<;C->,J>P\;9/Q -M&0'TJ(['HC,(':B#!?EXMF#`'8F9`^,_792<[Z-0%^<[+V8R\5J?E7X$G$&[ -M=6\")WT3#O#]\;CA-J$Y+Y96(\EQ,[Y+F?"6NLA_JI:L<]'?*9$2>NF9@JM* -M(.9BKON1U5)>*#B,*S$6_>4M7JXAH"*1?_O-9)-(F7[]=1-+,?32T7X?2J#S -MO=/W2Q6HE"4^(//X.O?]4^/@BF6V4KH23"Q&W)77#[80[P&V@+5L6Q;5(=:J -M!R('TLUU0)E>\K=6#=[5"\ -MTB*Z%,8CX*91/:YBH`EHRFLYM$#?)7#Y4$-!&I?`"%&_^LYV4!G(=&P\E']0 -M(IX*?@@!4"A]9\(R+2XD8'\Z]& -MB4[&P:KQ[S<@#D/A!%X[Y;.LCOS)A6/!'Z+!^K7..?/?"W\4?E`]ZIV>2KW, -M(K$BH$`3ZIVD_"$+\<54Q26(`=;XH0!3Z;:S=[J8WN(>G*]NR0M#?%GM8Z15 -MND(="&^?@7D!6+%G+&@P<2\<9FG!Q$-=,8JNJLU[W\:`)T:3BW0N[-8M9,BG -MUW3D#E4F^R72`=T#>;MMPO!S0$SY,Z?T\1?+ZSE/ZK/F'4%=T.1"*'QTMN.% -MOPQ8CL%)?L::N$C=VFTB%^PJM:0U -MCS@"\\)!_,H):(W"QLN;,91S8MQL+?;XRI$.,D8RVN`_EF$FSNFBIA*Z3.33 -M.R0/]13X``$$!@`!":@H``<+`0`!(P,$`04&`````0S!`)``"`H!]R-)#P`` -M!0$1'0!P`'``;0!D`%\`=`!E`',`=``N`'0`>`!T````%`H!`+%6SZ6=K.+BINH?CHRX,::[Q5P*!X\DH````%P8V -?`0F`B``'"P$``2,#`0$%70`0```,@-H*`9/CZP`````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_symbolic_name.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_symbolic_name.7z.uu deleted file mode 100644 index 2dd8ca191..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_symbolic_name.7z.uu +++ /dev/null @@ -1,8 +0,0 @@ -begin 644 test_read_format_7zip_symbolic_name.7z -M-WJ\KR<<``/+SQ7U?``````````@`````````%VOQ/0`-!E)[HZ&\R=N#\\G\(P'R$.`@X%;_ZR`'5`:`Y&`K7JS*U;!.)J3]3@J -M?#'*:Z""L7Y*%Z9?L#^PQL3)[(BVML.S!-[#M+-]`$!`!IA7-T96T```"!,P>N#\_\\&P/Z^J%U\S6&7C"[<$<2GL2\B,** -MW`0[F2;R)EO2:N)4RB6G.3+R6%97BQ]K"X),-'`E&./R#`2A\R&D1#U8FUC& -MANR65$7S:?$CR7DS8<)L'MR%.5Y)T-;62DU\S8W?$4=U2972R-0]5J81R3E/ -M\K&`%O\H:/`E4``7!A\!"8#:``<+`0`!(P,!`05=`!````R!C@H!`M-R5@`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_zstd.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_zstd.7z.uu deleted file mode 100644 index acd49c421..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_zstd.7z.uu +++ /dev/null @@ -1,12 +0,0 @@ -begin 664 test_read_format_7zip_zstd.7z -M-WJ\KR<<``2QPP_C,`$````````C``````````+H!E8R#*L]U;J=* -M@K`Q6]^1F4MZF33TE2LJK8X@%5MY%P.#1*EM98=_,9"?K'$*_A0YVC)]1ML= -MK-5-,X82B;/_L`I&FQ!5HP#H````%P:`J`$)@(@`!PL!``$C`P$!!5T`$``` -+#(#Z"@%\$`,4```` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_zstd_arm.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_zstd_arm.7z.uu deleted file mode 100644 index 770e99b3c..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_zstd_arm.7z.uu +++ /dev/null @@ -1,61 +0,0 @@ -begin 644 test_read_format_7zip_zstd_arm.7z -M-WJ\KR<<``0IIN38A`D```````!R``````````1RSP4HM2_]`$@!``!0*DT8 -M!````&\)```HM2_]8'P=+4L`REV0%$E@''(._[5GFW&YEVY]?G/)^,\9+2"B -M(\1H-(@DHJ*L)A?\C,G6FR3?/D.:6QDP<&`QFLOCXM`%J_](<>7+QU&E6E:N -M9=5-A,@4*0%(`38!`-3GD[<=6PPVGVGC_)87GYQ_BZ,9+G<6(:EL+AFM]/OESN[+)245575._@ -M^RPCV7?'7IB-7R_..I.8;"%/NJ_\?\/_!_P<: -M^G3XSS-DOP`414SD%5U,'70-F?MS1VK_/VO^C&^I_1SA*^_=)^^5T\.;Z -M_W0/7Z?^[E_7Q03P`7[I>3]\I]RK_U^TYO^=_E7>+WWZ>^_CU12)L[N?\MU#>?H_X-28WKB?Y#2_H5D[#04WF9R/8>-46ZIY]4H -M_[E-HI8CI(5G.6PHP["KW.$%T24@`CT?H"YM4.#W#_7_$LP0H8J@_5G9\>QI -M=PPFO9L77'W,=3WH_D`?:4S&I@D;2#5JL=/]U?I!=OW1=F+M]/KEY>S4[+:QQ[<3#6#>,P -MS":???N<_*[T7VSG+Y+E_%NEE]<%?4YB^.=!@="D_R`W:7)EGJC+VO<>:,/( -M\K[_V5!^"/W92(#84!'B?5"@#>*'Y&'/_Q;Q1/_;[`_]<+/84PFV[WO2M)[4 -M2L^_FUK-[[<=1DVMEU-2?3DI7H!^/\D=^=X'_6[Q0?]$0Q)M_T)1>VH1],7_ -M:W`1HJNG_IVY`DR(,_?O^G7K_0[6:5[\H)=H)`=>"@'Z4 -M/Q^33T_=]2CA&;)S@F?<`77FZ')IJEE:`V4.V`!0HUVT@RG1%MK`':0"J3LH -M;^^*.CNZ+Q*?D\+1^+8/_W\ID\V-J^^W(_,#XTKIH4:O2Q$CO2S"#\-CA -M&,ZPD*+'A="2":C_L9T"_Q\,^!YD:/"1%93KNHT#)91V>Q/YSKVS/7:72SFY -M/DTCU^_RU_K)=\G&8JW27=_9ODYWQ=HJKB_/Z_K=Z?9U_0XS87=>?^:Q_-*S -M"V+N2S$Z%FO75]*LDE@556Q?8@N_3>3:C+]6M\OQ^LS9[?&KG#N]/I+M2S%Z -M_9?"XGK^W[ITD\=OVVFN5=7&K)++=,MY&[O/=K9U:1H)Q:>NHHI+L?/,\I=I;=WNPLREG'QGD^7T+/>6PRQ2AK\"@C2H$C.5*65$1$1$ -M)$F2-`9""D@*96%02N8^$J#D.`MT#".12:(@2)# -M4:BMMH#O(,3N\SNY98ID=!W0;%:X'+'JB96]?7)D)*]C(/`75J#"!K*H?_US -MA4W\/A]*S]-7_2]IAM/+/`B("R[9CK@UI^F_L_F\S3TLEF]4;-9K"D.FI-BN -MV;3B7IH,H:X*!VQF'5DKMS(QWD"?M;I7HLYJC5@4O84-JXI4]\ANPCC,Z6V! -MH1<1&1[VBD<[;N__]';,59N\AQ^&]#"-.ERLW77^#-%@[(V?&%>E1@EGMLCHLB@IEGBO -MR^7F7VZ4^<_*:H]3M2!41<$&Q+=RB)TZU2K(ZASM'+S$FSC)$0QJJE7#\<..?\ -M5<-K!(&!>!\SDU,3G@>GQG!HY@,:VA83.3UV:[8,/#IFAAR>4[SNQD@#X(ZP -MSB1KCH5,N!*?N?=.*K&"L:.#>WPGFRQ?G!MXSQ%MC#G3I!&A'&2-D>2,A/-E -MECT8^7<1UPS%/*;,`34&^-#OCIS.QE_GW3XHG\@9&@Y?L((/T]` -M)T;C<[`:OL9XFC,(CGNQ:L7!)HW!FUD*LUE../[1_FDQ56O"(#?<^P\D9Y8S -M\B>"887TP=S,B&&5FXH0#40E'^VT-J)ZZC$8F8IXY#3.]BBD/Y!W$_ZW_PF! -M]O@GGFKZK7B;%/:O*>@EBKE4E'Z,8L,CF729$*JA:H"9A4<-W536[#+GLD*, -MA1`PA]/73?\?687^X]/J)UG5TW%7:20ZKXIC[MVDJ)')G',2BOU+XJ+MC.)< -M.2`Z'M=W?='`QE[.OF=_/FV="Y,I[]N:M1/U6>W;\;-N"M*]+K&L1B*%65/ZC8$_36I;+/=_@$ -M3FB?WK+IOVATX0C;5Y*=[>\S4F1(V)J!O??36$$TKF(S2@FLJ\FLP*@EGBB:2%'/9-Z8 -M8Q,_6=Z>;B0PSV4-O0H-CLX!^O0EGI6A1BSB-+@-^M_[_W@_H7<<>.R8P"(# -M;W9GXI=Q",^;'>9$=#]CA-$DQL\_IE\_^00T'^]Z\9A?)Y\``@*`>'$7C4```4!&0H` -M````````````$1L`:`!W`"T`9P!N`'4`90!A`&(`:0!H`&8````9`!0*`0`` -166S@9)S9`14&`0`@@.V!```` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_zstd_bcj.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_zstd_bcj.7z.uu deleted file mode 100644 index 2a75db897..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_zstd_bcj.7z.uu +++ /dev/null @@ -1,56 +0,0 @@ -begin 664 test_read_format_7zip_zstd_bcj.7z -M-WJ\KR<<``0N5BP@P@@```````!B`````````(*-K]$HM2_]`$@!``!0*DT8 -M!````*T(```HM2_]8%`]'44`ZE%D$DIPW'$.RP,C]5>);DM31:I?D,QMZ#'[ -MX]O[KCOFX)J*\$44=%&TV"+)8#QPV28QFR]0!V-3JH9UII:164M``!FT!`!L -MXELXL[8O4Q,!'@$2`5/J6F?&6/][6'!>ZPF&:U6C8%?F9DH.#=>\Y71GN:,M -M^ZA,>'Z0J2/,U:!!Y(?S^B3?P==^[[?]YK&,Q.+\7;C(4KFQ#"L]4*LEI'SCU\6R?O,=IH;BR_, -M^=,]F?4+_I]'MWL=@)3B4LF]J`%84^*+!@]ERRM(EKDF0@0*\*,A13M[J_;, -M*JBF":I,JT3`(:"1UI!6,G[AH1;N$0&++]Q;5RDTUW:S#KB?&TWF[K] -MTO%\G]%M-\G(:E8U$$&Q(;$WDZ;I?H%#_\%^!#:>[<]:V>W_LQ-_Y?Q`(@"A`L^!S]UHDBP&X#+X<) -MS4GK>LP.H+]9:E#78]`VV'FC.[!1K?U2*3:2NB93]/].==UT^O\>==W,\/]? -M==V44-=-'0;;@?WP+*-()<@P[!['GHC]HU%G3KK6_QP>N.7:3':M;%ATH6"X -M5K.NM0IE?OG9C8W8_ZH67)-_%.SL'Q6>_:M>@EZKKIMUJ5R"7&M5A.0'M[;4 -M9V?&P.&\UIV>1F5MLE<;FI+U2(R2M=FUI@DE%2V)P>4ZMO6SVU+C=&8,(,YK -MY>EH%F;<4AEF?GO3?%`"2[7)S_F;T@5U>S"M7+I6DE0Z2*&^9T( -MJG_I9W?UWQ,25(-=_:/IEZ/P9_??RQ%4__=P%-5CYQ*N-=P)*8F#4Q-_J:5U -M'?(JJ";.7XGXA`058FD):LB'3TA23)R_445Q[&_\["64C9^%I)EM.SW%L.LT49QN)R:^3(SM^H7ETE.]UGXV.Q -MG;]%EO.7U5^?C5.OJ[*+Z*C1$-(A?J%;#=`G\MY'Q2V%>VHZ_YM'O9).+?@] -M&[B#>O9PXX#A62$P9N#(I\W?">*#9\:C*[Y`E1!]GR=28((]^C4"J>WK;[__ -M:S)_$_HE*_R&?+\TV>-DL>I!>D%)J`P3US430XU<+-S -M),83X)<`RFY;.%N87*>=0>!SX'OZ_PMXW8W.*B=`J28#S1D*U77O4Y3UMK+_ -MO\$[$]BLC/9N@+Y/YWVH[O3MW+GVQ&Q`R,C:,)F[_R=SFIU!UC7+1_G_FTY: -M8Y)D#["R,A(5%88*A3Y0-$W3'+='>?"2_FWPSMRM12UGXO>_YX^R,O;,`86% -MR76-YO\_I%]?Q!O0\0A\!KO'+A(I&]6GZ:+ZQA?)QLIV;H]'5WUY5M7O6FY7 -MW^C2,I:J?H>S6-B=U9]Y++_T[)Z8.U))Q\I6_2/-'H>(24CM.]3";[*H[+.; -M)<]9:C+&4MTNQ^IGS6Z/W^/<:?6+;$L+^>0INN&\C!Q)+"(-?'D)(%2ZL3O]\]"#?E1$+0VXIS="D"#8T@4)AH;OS0QK*@.S(L,50<_CA -MSLQF9'9?XSB;;-U94YD.FO]*997K@$8#<$+3;FE`!=:DQF+2IM`^P_V)X+H8 -M>CA6D83\V2'4'&8019V9GJ;4N^GH!]DY[/[G+;OB1_1;1C*]PB'S([P%1P=2 -MVZWP^0AVC4J*P$8O6>4N-N<4YQ@52=LB99,=Q-92\YTM6_:!O(CLS*.3].4# -M"=G'`&WN&'Q@PN!^%WP*@ -M>Q#R';%'W>W,J`@NVM/IYT(1Z9WO[L0DR.YFB5_M%B-Q;^"AA"&\S5O?^]2G -M5:0N[G64]G+ZWR@D&V)Q@^LXPO*B9G9F,9'#!BQ>,6;6FU$N?3 -M`.Q/U+S_$GPHT*;\)<@Y@CF:$OL@/;(&MBC.]2FU)]]1H%"W*G?%/.,%R -M%[H<>8MCK*V1.J%.C=7'N/;E*:U^2SX@)@'SYZ\;36III>#+-E0=MARSYX'R -M\WH,G%TT4TXJ7V:1?#Q/HER'4TFC.'Y%Y0D*MH2(6\B5YU*21O#?4OS=K,#> -MM?@F6*^:37;#*>NV\;VYS9R567I^EN(RXY3MF[\:?IS1%VRW7Z[:^VI'LY=_ZBTR<)4IT7]IYY]1OK&'@.&E"VR@9%YH&S'Q,#9CF] -MG8&_K//(.AY#/&&R\L5Y9G9*M">BYP#J+4'9&3=D:QBW=45`IG&!W"1D^=K7 -M3-\)$&`N%0_$JV$!\![TG-`=:",BG5.9A)"?V=NSXPVO21_O-QG<+$FCO"K< -M+7,ER$BPT:CS!0`Z0BV^S#)QZ3PK0-/_L#+OU^QUO<'=-9BN6Y:-5!LY:B;N -MZREX8;-G[,XTOK;@Y$4Z[)9[!"MHPI^1M7KK1KL45B0C''SO8H,4XUG<1RU\ -MG/6=<8^3]'MPL\V\;ITR,#$MU@E[S7%[`00&``$)B,(`!PL!``(D!/<1`04! -M!0,```0#`P$#`0`,OE"^4``("@&\[F:]```%`1D*`````````````!$'`&@` -@=P```!D$`````!0*`0``'';'*9?9`14&`0`@@/V!```` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_zstd_nobcj.7z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_7zip_zstd_nobcj.7z.uu deleted file mode 100644 index c6fed0beb..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_7zip_zstd_nobcj.7z.uu +++ /dev/null @@ -1,56 +0,0 @@ -begin 664 test_read_format_7zip_zstd_nobcj.7z -M-WJ\KR<<``0`N.\QQ0@```````!2`````````#TEXKPHM2_]`$@!``!0*DT8 -M!````+`(```HM2_]8%`]-44`*E)P$DIPW'$.R^E\_]^S[,>DG"("L:I:;)%D,!ZX;).8S1>H@[$I[8=UII:164M``!FT!`!L -MLB.<6?N3%!4!'@$2`4JZ6"F]QIDPV'_>%=P7BW[I8M4HT)&YD9)#@VO>T')( -M6DXDLR#Z0.9.,$=CQA`?#OR3?`=?^_-\VY];GI%8>_\;%UNJ5YYCX1,5_?(: -MQGKIU]U/5,3]112,U@GKA"U4(CHU_>]?%'#,>[\,M\C-Z9;7VUB$ -MX[V_YLFL7_#_N]H]V0'(*.^4G(L:@#4EO&CP8+:TNUZ$?T.]HBVDK*<$SDQKRB7Q&.>2PKE>9]N=98W(:M@B]-TWPM'=H;6Q(O]U]F!6[+-I!?+9H57 -M^J6+/?-BJWKO6EZ`=&0CSO\U"XY)[]U%Z[W[H/VO78!?;`X_\UJW`+O8J@C) -M!W)IZ2AGPL#AOE@>GC:%97*R-C1)6*0P2=BF%YLVI&2T)`*7+!D7D$Y+Q^%, -M&#_<%]O#T5B@<4LE<,G^"R#=>E7FGS?5\P2X9)WXF+XA55232Q>[Q8LE,<6+ -M",9W0JC_$I#NZI\71*B'7?7>MW@Y!H%T_SP<0OV?=\.HDZ$!3DE*')R:]DLM -ML>QP5T$U[?U"XE,25(BE):CA'CXE23'M_<95Z\AA&=Y[OQ*)3+K[1;;TU2MI -M+K];V=)TN^'>ZK[\C;.0L_&WDNVNZ9F[.VZ+XD7R_<;VZ2O*:T\;' -M:OF&B^W>/Z\^3ANG/H?*221';<;0#A$LY6J0/G'W/REN:NQ3V_D_=]0+=VK` -M]SE_IY#/.3QQONRJ$"`S8.35YO,`Z?$],CY5\5_@SV#Z/T^DP$S#/OT:`=4& -M]K<___N8OPWYDA5\1#V?FN1RLECU0+T@%#;UTN!TFEU-._L:5`$.$\5%W>12 -M`S<\2&,]`7X)P.S&A;.)S3W-#(*?`^_#_U_`Y]SD6.4$"&LQ4IWA4/]CE/4V -ML_^WL4,3V*R.SK-!^KV=[Z4Y:._,H2QOS/:CK*P-DZG[_S'H&0J$9;$\E/^_ -M[:BU)4C.`5961:*BQ-)@L$>:JJJ*X_;ICIW2?XT=FKNQJ.5,_/DPZL/,K$5S -M06)B<^]G_O^#"@9&O`4=C[]G<'+Y12)GX_IU75S?""-;6>G2[O'XKC_3Z_I\ -MZ^7K&]]ZQEK7YW%6&[_T^O269[BFWQ,T1RIK6>FN?ZS;(Q%1*?TL^N4R?*1YO7ZQY4AEO?X+GZCJNKCWN_*[WWWKY)9A -ME]>;`]&5V^.>:W>WO/V6M^Z[@WOHI)1$M:F&4TQ,'':"4:CB>C%")2(21)(D -MQ1RR"R@01$'(&+EY$D!C+-E5AA&"G!$1$1DI*"HJ*%3:#M)%"5G$G\"8%:>G[^>!M\V$XK!3)(B?F)-CZ=K`("^=H&,T+K]/R8B -M['>&V!;.[RZK*AXHW/(1&>W$L([TS6UB*(17-)#`^=N<-Y!+LP+,;VWOM.:V -MG"H>@K<%',>.&QD-=+)!XH+%'R\&]".3\%"A*"Q49ZE[Z/-`S&!3[$CTBVC3R]ZNOP";Z'2 -MH2O_5Y`ZL)EB)470T:OT>2R/20[R[(Y,@NY,>;K5;&0GE`P\E#.%]WG4O -M&5+K/5T3')<)O"I,1MVZ"]]^(&Q5B">>RVD\[W$PP\;7(AE#%.%E-HDY"IIT -MR+8L[$1_("Y?)9Q7F&M -MK64ED6D`V29*P=.*;'(U%I_))$V/)_?,$=;YBZAX0W2M@PFKU%9S3_T.T:#< -MW/V$HY:ZT^6Q"C":"ARLJ?J@S!>.02=/K6Z%TS_J/3*YY=UH8DNK;;"^H=ZX -M?#9L*(R;]X<0VT7;[:2U;!;IBO(DRB.[\UAYLS,UO/S@RN?PVG?_*AAX1GE0+O-\:J] -M7,:5^[ASH4F3NG>,TSNX9AQPQ>"V$LT4["&]0W=&EFLO#1^W/A*04USP-0!9 -MOO8][Q\"!,VAXT'A8CF`N?FP)O*.V0A/YEIF(B0G]^KN-F5KPD;:J[TX$J21 -MW@+<%;CB-NJY,<;P!8#[&A:9S.V+U9\ADL)_&*EW<[O -ML2P=S_XO.NY4@\-FS$OP8EX>6=[`00&``$)B,4`!PL!``$D!/<1 -M`04!!0,```R^4``("@&\[F:]```%`1D#````$0<`:`!W````&00`````%`H! -3```<=L7ET='1S test_read_format_cab_1.cab.uu - uuencode test_read_format_cab_2.cab test_read_format_cab_2.cab > test_read_format_cab_2.cab.uu - uuencode test_read_format_cab_3.cab test_read_format_cab_3.cab > test_read_format_cab_3.cab.uu - -#!/bin/sh -# -# How to make test data. -# -# Temporary directory. -base=/tmp/cab -# Owner id -owner=1001 -# Group id -group=1001 -# -# Make contents of a cabinet file. -# -rm -rf ${base} -mkdir ${base} -mkdir ${base}/dir1 -mkdir ${base}/dir2 -# -touch ${base}/empty -cat > ${base}/dir1/file1 << END - file 1 contents -hello -hello -hello -END -# -cat > ${base}/dir2/file2 << END - file 2 contents -hello -hello -hello -hello -hello -hello -END -# -dd if=/dev/zero of=${base}/zero bs=1 count=33000 > /dev/null 2>&1 -# -cab1=test_read_format_cab_1.cab -cab2=test_read_format_cab_2.cab -cab3=test_read_format_cab_3.cab -# -# -cat > ${base}/mkcab1 << END -.Set Compress=OFF -.Set DiskDirectory1=. -.Set InfDate=1980-01-02 -.Set InfTime=00:00:00 -.Set CabinetName1=${cab1} -empty -.Set DestinationDir=dir1 -dir1/file1 -.Set DestinationDir=dir2 -dir2/file2 -END -# -cat > ${base}/mkcab2 << END -.Set CompressionType=MSZIP -.Set DiskDirectory1=. -.Set InfDate=1980-01-02 -.Set InfTime=00:00:00 -.Set CabinetName1=${cab2} -empty -zero -.Set DestinationDir=dir1 -dir1/file1 -.Set DestinationDir=dir2 -dir2/file2 -END -# -cat > ${base}/mkcab3 << END -.Set CompressionType=LZX -.Set DiskDirectory1=. -.Set InfDate=1980-01-02 -.Set InfTime=00:00:00 -.Set CabinetName1=${cab3} -empty -zero -.Set DestinationDir=dir1 -dir1/file1 -.Set DestinationDir=dir2 -dir2/file2 -END -# -cat > ${base}/mkcab4 << END -.Set CompressionType=MSZIP -.Set DiskDirectory1=. -.Set CabinetName1=test.cab -${cab1} -${cab2} -${cab3} -END -# -cat > ${base}/cab.bat << END -makecab.exe /F mkcab1 -makecab.exe /F mkcab2 -makecab.exe /F mkcab3 -makecab.exe /F mkcab4 -del setup.inf setup.rpt -del empty zero dir1\file1 dir2\file2 mkcab1 mkcab2 mkcab3 mkcab4 -del ${cab1} ${cab2} ${cab3} -rmdir dir1 dir2 -END -# -f=cab.zip -(cd ${base}; zip -q -c $f empty zero dir1/file1 dir2/file2 mkcab1 mkcab2 mkcab3 mkcab4 cab.bat) -# -exit 1 -*/ - -static const char file1[] = { -" file 1 contents\n" -"hello\n" -"hello\n" -"hello\n" -}; -#define file1_size (sizeof(file1)-1) -static const char file2[] = { -" file 2 contents\n" -"hello\n" -"hello\n" -"hello\n" -"hello\n" -"hello\n" -"hello\n" -}; -#define file2_size (sizeof(file2)-1) - -enum comp_type { - STORE = 0, - MSZIP, - LZX -}; -static void -verify(const char *refname, enum comp_type comp) -{ - struct archive_entry *ae; - struct archive *a; - char buff[128]; - char zero[128]; - size_t s; - - memset(zero, 0, sizeof(zero)); - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular empty. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae)); - assertEqualString("empty", archive_entry_pathname(ae)); - assertEqualInt(0, archive_entry_uid(ae)); - assertEqualInt(0, archive_entry_gid(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - if (comp != STORE) { - /* Verify regular zero. - * Maximum CFDATA size is 32768, so we need over 32768 bytes - * file to check if we properly handle multiple CFDATA. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae)); - assertEqualString("zero", archive_entry_pathname(ae)); - assertEqualInt(0, archive_entry_uid(ae)); - assertEqualInt(0, archive_entry_gid(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualInt(33000, archive_entry_size(ae)); - for (s = 0; s + sizeof(buff) < 33000; s+= sizeof(buff)) { - ssize_t rsize = archive_read_data(a, buff, sizeof(buff)); - if (comp == MSZIP && rsize == ARCHIVE_FATAL && archive_zlib_version() == NULL) { - skipping("Skipping CAB format(MSZIP) check: %s", - archive_error_string(a)); - goto finish; - } - assertEqualInt(sizeof(buff), rsize); - assertEqualMem(buff, zero, sizeof(buff)); - } - assertEqualInt(33000 - s, archive_read_data(a, buff, 33000 - s)); - assertEqualMem(buff, zero, 33000 - s); - } - - /* Verify regular file1. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae)); - assertEqualString("dir1/file1", archive_entry_pathname(ae)); - assertEqualInt(0, archive_entry_uid(ae)); - assertEqualInt(0, archive_entry_gid(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualInt(file1_size, archive_entry_size(ae)); - assertEqualInt(file1_size, archive_read_data(a, buff, file1_size)); - assertEqualMem(buff, file1, file1_size); - - /* Verify regular file2. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae)); - assertEqualString("dir2/file2", archive_entry_pathname(ae)); - assertEqualInt(0, archive_entry_uid(ae)); - assertEqualInt(0, archive_entry_gid(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualInt(file2_size, archive_entry_size(ae)); - assertEqualInt(file2_size, archive_read_data(a, buff, file2_size)); - assertEqualMem(buff, file2, file2_size); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - if (comp != STORE) { - assertEqualInt(4, archive_file_count(a)); - } else { - assertEqualInt(3, archive_file_count(a)); - } - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_CAB, archive_format(a)); - - /* Close the archive. */ -finish: - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* - * Skip beginning files and Read the last file. - */ -static void -verify2(const char *refname, enum comp_type comp) -{ - struct archive_entry *ae; - struct archive *a; - char buff[128]; - char zero[128]; - - if (comp == MSZIP && archive_zlib_version() == NULL) { - skipping("Skipping CAB format(MSZIP) check for %s", - refname); - return; - } - memset(zero, 0, sizeof(zero)); - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular empty. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - if (comp != STORE) { - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - } - /* Verify regular file1. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Verify regular file2. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae)); - assertEqualString("dir2/file2", archive_entry_pathname(ae)); - assertEqualInt(0, archive_entry_uid(ae)); - assertEqualInt(0, archive_entry_gid(ae)); - assertEqualInt(file2_size, archive_entry_size(ae)); - assertEqualInt(file2_size, archive_read_data(a, buff, file2_size)); - assertEqualMem(buff, file2, file2_size); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - if (comp != STORE) { - assertEqualInt(4, archive_file_count(a)); - } else { - assertEqualInt(3, archive_file_count(a)); - } - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_CAB, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* - * Skip all file like 'bsdtar tvf foo.cab'. - */ -static void -verify3(const char *refname, enum comp_type comp) -{ - struct archive_entry *ae; - struct archive *a; - char zero[128]; - - memset(zero, 0, sizeof(zero)); - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular empty. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - if (comp != STORE) { - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - } - /* Verify regular file1. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Verify regular file2. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - if (comp != STORE) { - assertEqualInt(4, archive_file_count(a)); - } else { - assertEqualInt(3, archive_file_count(a)); - } - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_CAB, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_cab) -{ - /* Verify Cabinet file in no compression. */ - verify("test_read_format_cab_1.cab", STORE); - verify2("test_read_format_cab_1.cab", STORE); - verify3("test_read_format_cab_1.cab", STORE); - /* Verify Cabinet file in MSZIP. */ - verify("test_read_format_cab_2.cab", MSZIP); - verify2("test_read_format_cab_2.cab", MSZIP); - verify3("test_read_format_cab_2.cab", MSZIP); - /* Verify Cabinet file in LZX. */ - verify("test_read_format_cab_3.cab", LZX); - verify2("test_read_format_cab_3.cab", LZX); - verify3("test_read_format_cab_3.cab", LZX); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_cab_1.cab.uu b/thirdparty/libarchive/libarchive/test/test_read_format_cab_1.cab.uu deleted file mode 100644 index bc6ab41ee..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_cab_1.cab.uu +++ /dev/null @@ -1,9 +0,0 @@ -begin 644 test_read_format_cab_1.cab -M35-#1@`````*`0```````"P``````````P$!``,```!K"0``>`````$````` -M````````````D3U&I2``96UP='D`/````````````)$]1J4@`&1I - -static void -test_read_format_cab_filename_CP932_eucJP(const char *refname) -{ - struct archive *a; - struct archive_entry *ae; - - /* - * Read CAB filename in ja_JP.eucJP with "hdrcharset=CP932" option. - */ - if (NULL == setlocale(LC_ALL, "ja_JP.eucJP")) { - skipping("ja_JP.eucJP locale not available on this system."); - return; - } - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP932")) { - skipping("This system cannot convert character-set" - " from CP932 to eucJP."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString( - "\xc9\xbd\xa4\xc0\xa4\xe8\x2f\xb4\xc1\xbb\xfa\x2e\x74\x78\x74", - archive_entry_pathname(ae)); - assertEqualInt(5, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString( - "\xc9\xbd\xa4\xc0\xa4\xe8\x2f\xb0\xec\xcd\xf7\xc9\xbd\x2e\x74\x78\x74", - archive_entry_pathname(ae)); - assertEqualInt(5, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_CAB, archive_format(a)); - - /* Close the archive. */ -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -static void -test_read_format_cab_filename_CP932_UTF8(const char *refname) -{ - struct archive *a; - struct archive_entry *ae; - - /* - * Read CAB filename in en_US.UTF-8 with "hdrcharset=CP932" option. - */ - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("en_US.UTF-8 locale not available on this system."); - return; - } - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP932")) { - skipping("This system cannot convert character-set" - " from CP932 to UTF-8."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); -#if defined(__APPLE__) - /* Compare NFD string. */ - assertEqualUTF8String( - "\xe8\xa1\xa8\xe3\x81\x9f\xe3\x82\x99\xe3\x82\x88\x2f" - "\xe6\xbc\xa2\xe5\xad\x97\x2e\x74\x78\x74", - archive_entry_pathname(ae)); - assertEqualInt(5, archive_entry_size(ae)); -#else - /* Compare NFC string. */ - assertEqualUTF8String( - "\xe8\xa1\xa8\xe3\x81\xa0\xe3\x82\x88\x2f" - "\xe6\xbc\xa2\xe5\xad\x97\x2e\x74\x78\x74", - archive_entry_pathname(ae)); - assertEqualInt(5, archive_entry_size(ae)); -#endif - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); -#if defined(__APPLE__) - /* Compare NFD string. */ - assertEqualUTF8String( - "\xe8\xa1\xa8\xe3\x81\x9f\xe3\x82\x99\xe3\x82\x88\x2f" - "\xe4\xb8\x80\xe8\xa6\xa7\xe8\xa1\xa8\x2e\x74\x78\x74", - archive_entry_pathname(ae)); -#else - /* Compare NFC string. */ - assertEqualUTF8String( - "\xe8\xa1\xa8\xe3\x81\xa0\xe3\x82\x88\x2f" - "\xe4\xb8\x80\xe8\xa6\xa7\xe8\xa1\xa8\x2e\x74\x78\x74", - archive_entry_pathname(ae)); -#endif - assertEqualInt(5, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_CAB, archive_format(a)); - - /* Close the archive. */ -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_cab_filename) -{ - const char *refname = "test_read_format_cab_filename_cp932.cab"; - - extract_reference_file(refname); - test_read_format_cab_filename_CP932_eucJP(refname); - test_read_format_cab_filename_CP932_UTF8(refname); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_cab_filename_cp932.cab.uu b/thirdparty/libarchive/libarchive/test/test_read_format_cab_filename_cp932.cab.uu deleted file mode 100644 index 0d51f10c4..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_cab_filename_cp932.cab.uu +++ /dev/null @@ -1,7 +0,0 @@ -begin 644 test_read_format_cab_cp932.cab -M35-#1@````"4`````````"P``````````P$!``(````(_@``;@````$``Q(% -M````````````=#ZO5"``E5R"OH+F7(J_CIHN='AT``4````%``````!T/KM4 -M(`"57(*^@N9 file1 -echo "0123456789abcdef" > file2 -# make afio use a large ASCII header -sudo chown 65536 file2 -find . -name "file[12]" | afio -o sample -od -c sample | sed -E -e "s/^0[0-9]+//;s/^ //;s/( +)([^ ]{1,2})/'\2',/g;s/'\\0'/0/g;/^[*]/d" > test_read_format_cpio_afio.sample.txt -rm -f file1 file2 sample -exit1 -*/ - -static unsigned char archive[] = { -'0','7','0','7','0','7','0','0','0','1','4','3','1','2','5','3', -'2','1','1','0','0','6','4','4','0','0','1','7','5','1','0','0', -'1','7','5','1','0','0','0','0','0','1','0','0','0','0','0','0', -'1','1','3','3','2','2','4','5','0','2','0','0','0','0','0','0', -'6','0','0','0','0','0','0','0','0','0','2','1','f','i','l','e', -'1',0,'0','1','2','3','4','5','6','7','8','9','a','b','c','d', -'e','f','\n','0','7','0','7','2','7','0','0','0','0','0','0','6', -'3','0','0','0','0','0','0','0','0','0','0','0','D','A','A','E', -'6','m','1','0','0','6','4','4','0','0','0','1','0','0','0','0', -'0','0','0','0','0','3','E','9','0','0','0','0','0','0','0','1', -'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0', -'4','B','6','9','4','A','1','0','n','0','0','0','6','0','0','0', -'0','0','0','0','0','s','0','0','0','0','0','0','0','0','0','0', -'0','0','0','0','1','1',':','f','i','l','e','2',0,'0','1','2', -'3','4','5','6','7','8','9','a','b','c','d','e','f','\n','0','7', -'0','7','0','7','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','1','0','0','0','0','0','0','0','0', -'0','0','0','0','0','0','0','0','0','0','0','0','0','1','3','0', -'0','0','0','0','0','1','1','2','7','3','T','R','A','I','L','E', -'R','!','!','!',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, -}; - -/* - * XXX This must be removed when we use int64_t for uid. - */ -static int -uid_size(void) -{ - return (sizeof(uid_t)); -} - -DEFINE_TEST(test_read_format_cpio_afio) -{ - unsigned char *p; - size_t size; - struct archive_entry *ae; - struct archive *a; - - /* The default block size of afio is 5120. we simulate it */ - size = (sizeof(archive) + 5120 -1 / 5120) * 5120; - assert((p = malloc(size)) != NULL); - if (p == NULL) - return; - memset(p, 0, size); - memcpy(p, archive, sizeof(archive)); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, p, size)); - /* - * First entry is odc format. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(17, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertA(archive_filter_code(a, 0) == ARCHIVE_FILTER_NONE); - assertA(archive_format(a) == ARCHIVE_FORMAT_CPIO_POSIX); - /* - * Second entry is afio large ASCII format. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(17, archive_entry_size(ae)); - if (uid_size() > 4) - assertEqualInt(65536, archive_entry_uid(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertA(archive_filter_code(a, 0) == ARCHIVE_FILTER_NONE); - assertA(archive_format(a) == ARCHIVE_FORMAT_CPIO_AFIO_LARGE); - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - free(p); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin.c b/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin.c deleted file mode 100644 index 7b0fad268..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin.c +++ /dev/null @@ -1,63 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/lib/libarchive/test/test_read_format_cpio_bin.c,v 1.2 2008/09/01 05:38:33 kientzle Exp $"); - -static unsigned char archive[] = { -199,'q',21,4,177,'y',237,'A',232,3,232,3,2,0,0,0,'p','C',244,'M',2,0,0,0, -0,0,'.',0,199,'q',0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,11,0,0,0,0,0,'T','R', -'A','I','L','E','R','!','!','!',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,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,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,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,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,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,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,0,0,0,0,0,0,0}; - -DEFINE_TEST(test_read_format_cpio_bin) -{ - struct archive_entry *ae; - struct archive *a; - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, 0, archive_read_support_filter_all(a)); - assertEqualIntA(a, 0, archive_read_support_format_all(a)); - assertEqualIntA(a, 0, archive_read_open_memory(a, archive, sizeof(archive))); - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_file_count(a)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_BIN_LE, archive_format(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_Z.c b/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_Z.c deleted file mode 100644 index 6afe69113..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_Z.c +++ /dev/null @@ -1,60 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_cpio_bin_Z.c 189464 2009-03-07 00:25:33Z kientzle $"); - -static unsigned char archive[] = { -31,157,144,199,226,'T',' ',16,'+','O',187,' ',232,6,'$',20,0,160,'!',156, -'!',244,154,'0','l',216,208,5,128,128,20,'3','R',12,160,177,225,2,141,'T', -164,4,'I',194,164,136,148,16,'(',';',170,'\\',201,178,165,203,151,'0','c', -202,156,'I',179,166,205,155,'8','s',234,220,201,179,167,207,159,'@',127,2}; - -DEFINE_TEST(test_read_format_cpio_bin_Z) -{ - struct archive_entry *ae; - struct archive *a; - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, archive, sizeof(archive))); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_file_count(a)); - failure("archive_filter_name(a, 0)=\"%s\"", - archive_filter_name(a, 0)); - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS); - assertEqualString(archive_filter_name(a, 0), "compress (.Z)"); - failure("archive_format_name(a)=\"%s\"", - archive_format_name(a)); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_BIN_LE); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_be.c b/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_be.c deleted file mode 100644 index 164396dab..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_be.c +++ /dev/null @@ -1,57 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_cpio_bin_be.c 191592 2009-04-27 19:30:09Z kientzle $"); - -DEFINE_TEST(test_read_format_cpio_bin_be) -{ - struct archive_entry *ae; - struct archive *a; - const char *reference = "test_read_format_cpio_bin_be.cpio"; - - extract_reference_file(reference); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, reference, 10)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "file1111222233334444"); - assertEqualInt(archive_entry_size(ae), 5); - assertEqualInt(archive_entry_mtime(ae), 1240664175); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); - assertEqualInt(archive_entry_uid(ae), 1000); - assertEqualInt(archive_entry_gid(ae), 0); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_NONE); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_BIN_BE); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_be.cpio.uu b/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_be.cpio.uu deleted file mode 100644 index f29b07138..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_be.cpio.uu +++ /dev/null @@ -1,8 +0,0 @@ -$FreeBSD: head/lib/libarchive/test/test_read_format_cpio_bin_be.cpio.uu 191592 2009-04-27 19:30:09Z kientzle $ -begin 644 test_read_format_cpio_bin_be.cpio -M<<<`"#P\@:0#Z`````$``$GS"&\`%0````5F:6QE,3$Q,3(R,C(S,S,S-#0T -M-```86)C9&4`<<<```````````````$`````````"P````!44D%)3$52(2$A -M```````````````````````````````````````````````````````````` -3```````````````````````````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_bz2.c b/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_bz2.c deleted file mode 100644 index 7497bc41a..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_bz2.c +++ /dev/null @@ -1,60 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_cpio_bin_bz2.c 201247 2009-12-30 05:59:21Z kientzle $"); - -static unsigned char archive[] = { -'B','Z','h','9','1','A','Y','&','S','Y',134,'J',208,'4',0,0,30,246,141,253, -8,2,0,' ',1,'*','&',20,0,'`',' ',' ',2,0,128,0,'B',4,8,' ',0,'T','P',0,'4', -0,13,6,137,168,245,27,'Q',160,'a',25,169,5,'I',187,'(',10,'d','E',177,177, -142,218,232,'r',130,'4','D',247,'<','Z',190,'U',237,236,'d',227,31,' ','z', -192,'E','_',23,'r','E','8','P',144,134,'J',208,'4'}; - -DEFINE_TEST(test_read_format_cpio_bin_bz2) -{ - struct archive_entry *ae; - struct archive *a; - int r; - - assert((a = archive_read_new()) != NULL); - r = archive_read_support_filter_bzip2(a); - if (r != ARCHIVE_OK) { - skipping("bzip2 support unavailable"); - archive_read_close(a); - return; - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, archive, sizeof(archive))); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assert(archive_filter_code(a, 0) == ARCHIVE_FILTER_BZIP2); - assert(archive_format(a) == ARCHIVE_FORMAT_CPIO_BIN_LE); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_gz.c b/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_gz.c deleted file mode 100644 index 3cc8f15ea..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_gz.c +++ /dev/null @@ -1,63 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_cpio_bin_gz.c 191183 2009-04-17 01:06:31Z kientzle $"); - -static unsigned char archive[] = { -31,139,8,0,244,'M','p','C',0,3,';','^','(',202,178,177,242,173,227,11,230, -23,204,'L',12,12,12,5,206,'_','|','A','4',3,131,30,195,241,'B',6,'8','`', -132,210,220,'`','2','$',200,209,211,199,'5','H','Q','Q',145,'a',20,12,'i', -0,0,170,199,228,195,0,2,0,0}; - -DEFINE_TEST(test_read_format_cpio_bin_gz) -{ - struct archive_entry *ae; - struct archive *a; - int r; - - assert((a = archive_read_new()) != NULL); - assertEqualInt(ARCHIVE_OK, archive_read_support_filter_all(a)); - r = archive_read_support_filter_gzip(a); - if (r == ARCHIVE_WARN) { - skipping("gzip reading not fully supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - failure("archive_read_support_filter_gzip"); - assertEqualInt(ARCHIVE_OK, r); - assertEqualInt(ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualInt(ARCHIVE_OK, - archive_read_open_memory(a, archive, sizeof(archive))); - assertEqualInt(ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(archive_filter_code(a, 0), - ARCHIVE_FILTER_GZIP); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_BIN_LE); - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_le.c b/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_le.c deleted file mode 100644 index 2d0484c52..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_le.c +++ /dev/null @@ -1,57 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_read_format_cpio_bin_le) -{ - struct archive_entry *ae; - struct archive *a; - const char *reference = "test_read_format_cpio_bin_le.cpio"; - - extract_reference_file(reference); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, reference, 10)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "file1111222233334444"); - assertEqualInt(archive_entry_size(ae), 5); - assertEqualInt(archive_entry_mtime(ae), 1240664175); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); - assertEqualInt(archive_entry_uid(ae), 1000); - assertEqualInt(archive_entry_gid(ae), 0); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_NONE); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_BIN_LE); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_le.cpio.uu b/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_le.cpio.uu deleted file mode 100644 index f7fef98ed..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_le.cpio.uu +++ /dev/null @@ -1,7 +0,0 @@ -begin 644 test_read_format_cpio_bin_le.cpio -MQW$(`#P\I('H`P```0```/-);P@5````!0!F:6QE,3$Q,3(R,C(S,S,S-#0T -M-```86)C9&4`QW$``````````````0`````````+``````!44D%)3$52(2$A -M```````````````````````````````````````````````````````````` -3```````````````````````````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_lzip.c b/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_lzip.c deleted file mode 100644 index d9acf095e..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_lzip.c +++ /dev/null @@ -1,63 +0,0 @@ -/*- - * Copyright (c) 2010 Michihiro NAKAJIMA - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -static unsigned char archive[] = { - 76, 90, 73, 80, 1, 12, 0, 99,156, 62,160, 67,124,230, 93,220, -235,118, 29, 75, 27,226,158, 67,149,151, 96, 22, 54,198,209, 63, -104,209,148,249,238, 71,187,201,243,162, 1, 42, 47, 43,178, 35, - 90, 6,156,208, 74,107, 91,229,126, 5, 85,255,136,255, 64, 0, -170,199,228,195, 0, 2, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, - 0, 0, 0, 0 -}; - -DEFINE_TEST(test_read_format_cpio_bin_lzip) -{ - struct archive_entry *ae; - struct archive *a; - int r; - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - r = archive_read_support_filter_lzip(a); - if (r == ARCHIVE_WARN) { - skipping("lzip reading not fully supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, archive, sizeof(archive))); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_LZIP); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_BIN_LE); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_lzma.c b/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_lzma.c deleted file mode 100644 index 9a8a23ceb..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_lzma.c +++ /dev/null @@ -1,62 +0,0 @@ -/*- - * Copyright (c) 2009 Michihiro NAKAJIMA - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_cpio_bin_lzma.c 201247 2009-12-30 05:59:21Z kientzle $"); - -static unsigned char archive[] = { - 93, 0, 0,128, 0,255,255,255,255,255,255,255,255, 0, 99,156, - 62,160, 67,124,230, 93,220,235,118, 29, 75, 27,226,158, 67,149, -151, 96, 22, 54,198,209, 63,104,209,148,249,238, 71,187,201,243, -162, 1, 42, 47, 43,178, 35, 90, 6,156,208, 74,107, 91,229,126, - 5, 85,255,136,255, 64, 0 -}; - -DEFINE_TEST(test_read_format_cpio_bin_lzma) -{ - struct archive_entry *ae; - struct archive *a; - int r; - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - r = archive_read_support_filter_lzma(a); - if (r == ARCHIVE_WARN) { - skipping("lzma reading not fully supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, archive, sizeof(archive))); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_LZMA); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_BIN_LE); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_xz.c b/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_xz.c deleted file mode 100644 index b19c4fae6..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_bin_xz.c +++ /dev/null @@ -1,72 +0,0 @@ -/*- - * Copyright (c) 2009 Michihiro NAKAJIMA - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_cpio_bin_xz.c 191183 2009-04-17 01:06:31Z kientzle $"); - -static unsigned char archive[] = { - 0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00, 0x00, 0x04, - 0xe6, 0xd6, 0xb4, 0x46, 0x02, 0x00, 0x21, 0x01, - 0x16, 0x00, 0x00, 0x00, 0x74, 0x2f, 0xe5, 0xa3, - 0xe0, 0x01, 0xff, 0x00, 0x33, 0x5d, 0x00, 0x63, - 0x9c, 0x3e, 0xa0, 0x43, 0x7c, 0xe6, 0x5d, 0xdc, - 0xeb, 0x76, 0x1d, 0x4b, 0x1b, 0xe2, 0x9e, 0x43, - 0x95, 0x97, 0x60, 0x16, 0x36, 0xc6, 0xd1, 0x3f, - 0x68, 0xd1, 0x94, 0xf9, 0xee, 0x47, 0xbb, 0xc9, - 0xf3, 0xa2, 0x01, 0x2a, 0x2f, 0x2b, 0xb2, 0x23, - 0x5a, 0x06, 0x9c, 0xd0, 0x4a, 0x6b, 0x5b, 0x14, - 0xb4, 0x00, 0x00, 0x00, 0x91, 0x62, 0x1e, 0x15, - 0x04, 0x46, 0x6b, 0x4d, 0x00, 0x01, 0x4f, 0x80, - 0x04, 0x00, 0x00, 0x00, 0xa1, 0x4b, 0xdf, 0x03, - 0xb1, 0xc4, 0x67, 0xfb, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x59, 0x5a -}; - -DEFINE_TEST(test_read_format_cpio_bin_xz) -{ - struct archive_entry *ae; - struct archive *a; - int r; - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - r = archive_read_support_filter_xz(a); - if (r == ARCHIVE_WARN) { - skipping("xz reading not fully supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, archive, sizeof(archive))); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_XZ); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_BIN_LE); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_filename.c b/thirdparty/libarchive/libarchive/test/test_read_format_cpio_filename.c deleted file mode 100644 index cf4f5ac26..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_filename.c +++ /dev/null @@ -1,860 +0,0 @@ -/*- - * Copyright (c) 2011 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD"); - -#include - -DEFINE_TEST(test_read_format_cpio_filename_eucJP_UTF8) -{ - const char *refname = "test_read_format_cpio_filename_eucjp.cpio"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read eucJP filename in en_US.UTF-8 with "hdrcharset=eucJP" option. - */ - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("en_US.UTF-8 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=eucJP")) { - skipping("This system cannot convert character-set" - " from eucJP to UTF-8."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xe6\xbc\xa2\xe5\xad\x97.txt", - archive_entry_pathname(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xe8\xa1\xa8.txt", archive_entry_pathname(ae)); - assertEqualInt(4, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_cpio_filename_UTF8_eucJP) -{ - const char *refname = "test_read_format_cpio_filename_utf8_jp.cpio"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read UTF-8 filename in ja_JP.eucJP with "hdrcharset=UTF-8" option. - */ - if (NULL == setlocale(LC_ALL, "ja_JP.eucJP")) { - skipping("ja_JP.eucJP locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=UTF-8")) { - skipping("This system cannot convert character-set" - " from UTF-8 to eucJP."); - goto cleanup; - } - - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualString("\xb4\xc1\xbb\xfa.txt", archive_entry_pathname(ae)); - assertEqualInt(8, archive_entry_size(ae)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualString("\xc9\xbd.txt", archive_entry_pathname(ae)); - assertEqualInt(4, archive_entry_size(ae)); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_cpio_filename_UTF8_UTF8_jp) -{ - const char *refname = "test_read_format_cpio_filename_utf8_jp.cpio"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read UTF-8 filename in en_US.UTF-8 without "hdrcharset=UTF-8" option. - */ - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("en_US.UTF-8 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualString("\xe6\xbc\xa2\xe5\xad\x97.txt", - archive_entry_pathname(ae)); - assertEqualInt(8, archive_entry_size(ae)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualString("\xe8\xa1\xa8.txt", archive_entry_pathname(ae)); - assertEqualInt(4, archive_entry_size(ae)); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_cpio_filename_CP866_KOI8R) -{ - const char *refname = "test_read_format_cpio_filename_cp866.cpio"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read CP866 filename in ru_RU.KOI8-R with "hdrcharset=CP866" option. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia.20866") && - NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) { - skipping("ru_RU.KOI8-R locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) { - skipping("This system cannot convert character-set" - " from CP866 to KOI8-R."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xf0\xf2\xe9\xf7\xe5\xf4", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\xd2\xc9\xd7\xc5\xd4", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_cpio_filename_CP866_UTF8) -{ - const char *refname = "test_read_format_cpio_filename_cp866.cpio"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read CP866 filename in en_US.UTF-8 with "hdrcharset=CP866" option. - */ - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("en_US.UTF-8 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) { - skipping("This system cannot convert character-set" - " from CP866 to UTF-8."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_cpio_filename_KOI8R_CP866) -{ - const char *refname = "test_read_format_cpio_filename_koi8r.cpio"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read KOI8-R filename in ru_RU.CP866 with "hdrcharset=KOI8-R" option. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia.866") && - NULL == setlocale(LC_ALL, "ru_RU.CP866")) { - skipping("ru_RU.CP866 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) { - skipping("This system cannot convert character-set" - " from KOI8-R to CP866."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\x8f\x90\x88\x82\x85\x92", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xaf\xe0\xa8\xa2\xa5\xe2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_cpio_filename_KOI8R_UTF8) -{ - const char *refname = "test_read_format_cpio_filename_koi8r.cpio"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read KOI8-R filename in en_US.UTF-8 with "hdrcharset=KOI8-R" option. - */ - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("en_US.UTF-8 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) { - skipping("This system cannot convert character-set" - " from KOI8-R to UTF-8."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_cpio_filename_UTF8_KOI8R) -{ - const char *refname = "test_read_format_cpio_filename_utf8_ru.cpio"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read UTF-8 filename in ru_RU.KOI8-R with "hdrcharset=UTF-8" option. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia.20866") && - NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) { - skipping("ru_RU.KOI8-R locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=UTF-8")) { - skipping("This system cannot convert character-set" - " from UTF-8 to KOI8-R."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xf0\xf2\xe9\xf7\xe5\xf4", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\xd2\xc9\xd7\xc5\xd4", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_cpio_filename_UTF8_CP866) -{ - const char *refname = "test_read_format_cpio_filename_utf8_ru.cpio"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read UTF-8 filename in ru_RU.CP866 with "hdrcharset=UTF-8" option. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia.866") && - NULL == setlocale(LC_ALL, "ru_RU.CP866")) { - skipping("ru_RU.CP866 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=UTF-8")) { - skipping("This system cannot convert character-set" - " from UTF-8 to CP866."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\x8f\x90\x88\x82\x85\x92", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xaf\xe0\xa8\xa2\xa5\xe2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_cpio_filename_UTF8_UTF8_ru) -{ - const char *refname = "test_read_format_cpio_filename_utf8_ru.cpio"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read UTF-8 filename in en_US.UTF-8 without "hdrcharset=UTF-8" option. - */ - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("en_US.UTF-8 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_cpio_filename_eucJP_CP932) -{ - const char *refname = "test_read_format_cpio_filename_eucjp.cpio"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read eucJP filename in CP932/SJIS with "hdrcharset=eucJP" option. - */ - if (NULL == setlocale(LC_ALL, "Japanese_Japan") && - NULL == setlocale(LC_ALL, "ja_JP.SJIS")) { - skipping("CP932 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=eucJP")) { - skipping("This system cannot convert character-set" - " from eucJP."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\x8a\xbf\x8e\x9a.txt", archive_entry_pathname(ae)); - assertEqualInt(8, archive_entry_size(ae)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\x95\x5c.txt", archive_entry_pathname(ae)); - assertEqualInt(4, archive_entry_size(ae)); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_cpio_filename_UTF8_CP932) -{ - const char *refname = "test_read_format_cpio_filename_utf8_jp.cpio"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read UTF-8 filename in CP932/SJIS with "hdrcharset=UTF-8" option. - */ - if (NULL == setlocale(LC_ALL, "Japanese_Japan") && - NULL == setlocale(LC_ALL, "ja_JP.SJIS")) { - skipping("CP932 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=UTF-8")) { - skipping("This system cannot convert character-set" - " from UTF-8 to CP932."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualString("\x8a\xbf\x8e\x9a.txt", archive_entry_pathname(ae)); - assertEqualInt(8, archive_entry_size(ae)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualString("\x95\x5c.txt", archive_entry_pathname(ae)); - assertEqualInt(4, archive_entry_size(ae)); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_cpio_filename_CP866_CP1251) -{ - const char *refname = "test_read_format_cpio_filename_cp866.cpio"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read CP866 filename in CP1251 with "hdrcharset=CP866" option. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia") && - NULL == setlocale(LC_ALL, "ru_RU.CP1251")) { - skipping("CP1251 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) { - skipping("This system cannot convert character-set" - " from CP866 to CP1251."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* - * This test only for Windows platform because other archiver - * applications on Windows translate CP1251 filenames into CP866 - * filenames and store it in the cpio file and so we should read - * it by default on Windows. - */ -DEFINE_TEST(test_read_format_cpio_filename_CP866_CP1251_win) -{ - const char *refname = "test_read_format_cpio_filename_cp866.cpio"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read CP866 filename in CP1251 without "hdrcharset=CP866" option. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia")) { - skipping("Russian_Russia locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_cpio_filename_KOI8R_CP1251) -{ - const char *refname = "test_read_format_cpio_filename_koi8r.cpio"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read KOI8-R filename in CP1251 with "hdrcharset=KOI8-R" option. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia") && - NULL == setlocale(LC_ALL, "ru_RU.CP1251")) { - skipping("CP1251 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) { - skipping("This system cannot convert character-set" - " from KOI8-R to CP1251."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_cpio_filename_UTF8_CP1251) -{ - const char *refname = "test_read_format_cpio_filename_utf8_ru.cpio"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read KOI8-R filename in CP1251 with "hdrcharset=KOI8-R" option. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia") && - NULL == setlocale(LC_ALL, "ru_RU.CP1251")) { - skipping("CP1251 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=UTF-8")) { - skipping("This system cannot convert character-set" - " from UTF-8 to CP1251."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_CPIO_POSIX, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_filename_cp866.cpio.uu b/thirdparty/libarchive/libarchive/test/test_read_format_cpio_filename_cp866.cpio.uu deleted file mode 100644 index 5f0658504..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_filename_cp866.cpio.uu +++ /dev/null @@ -1,15 +0,0 @@ -begin 644 test_read_format_cpio_cp866.cpio -M,# ${TMPRPM}/BUILD/file1 -echo "hello" > ${TMPRPM}/BUILD/file2 -echo "hello" > ${TMPRPM}/BUILD/file3 -cat > ${TMPRPM}/SPECS/${NAME}.spec < ${F}.uu - -rm -rf ${TMPRPM} -exit 1 -*/ - -DEFINE_TEST(test_read_format_cpio_svr4_bzip2_rpm) -{ - struct archive_entry *ae; - struct archive *a; - const char *name = "test_read_format_cpio_svr4_bzip2_rpm.rpm"; - int r; - - assert((a = archive_read_new()) != NULL); - r = archive_read_support_filter_bzip2(a); - if (r == ARCHIVE_WARN) { - skipping("bzip2 reading not fully supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - assertEqualIntA(a, ARCHIVE_OK, r); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_rpm(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - extract_reference_file(name); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 2)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("./etc/file1", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("./etc/file2", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("./etc/file3", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Verify the end-of-archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify that the format detection worked. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_BZIP2); - assertEqualString(archive_filter_name(a, 0), "bzip2"); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_SVR4_NOCRC); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.rpm.uu b/thirdparty/libarchive/libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.rpm.uu deleted file mode 100644 index 884ca9487..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.rpm.uu +++ /dev/null @@ -1,47 +0,0 @@ -begin 644 test_read_format_cpio_svr4_bzip2_rpm.rpm -M[:ONVP,``````7)P;7-A;7!L92TQ+C`N,"TQ```````````````````````` -M```````````````````````````````````````````!``4````````````` -M````````CJWH`0`````````%````5````#X````'````1````!````$-```` -M!@`````````!```#Z`````0````L`````0```^P````'````,````!````/O -M````!````$`````!,F4X-3)F-39E,#,W83EE.61A9C`````$```1F````!@```GX````!```$;``` -M``8```*``````0``!'0````$```"E`````,```1U````!````J`````#```$ -M=@````@```*L`````P``!'<````$```"Q`````,```1X````!````M`````# -M0P!R<&US86UP;&4`,2XP+C``,0!386UP;&4@9&%T82!O9B!24$T@9FEL=&5R -M(&]F(&QI8F%R8VAI=F4`4V%M<&QE(&1A=&$N`````$L)MWQC=64M9&5S:W1O -M<``````20E-$`%5NFEP,@`Y`&YO87)C:"UR<&TM;&EN=7@````````````````````````` -M`0````$````!`$%30TE)('1E>'0`9&ER96-T;W)Y```````````````````` -M````````````````````/P````?___SP````$$)::#DQ05DF4UFX89DX``!= -M?X!,$`@`*`'_X"(D%``[9(0`(`"2B/50T#0#0`](9!%(C1,0&GJ`R`M@PQRG -M ${TMPRPM}/BUILD/file1 -echo "hello" > ${TMPRPM}/BUILD/file2 -echo "hello" > ${TMPRPM}/BUILD/file3 -cat > ${TMPRPM}/SPECS/${NAME}.spec < ${F}.uu - -rm -rf ${TMPRPM} -exit 1 -*/ - -DEFINE_TEST(test_read_format_cpio_svr4_gzip_rpm) -{ - struct archive_entry *ae; - struct archive *a; - const char *name = "test_read_format_cpio_svr4_gzip_rpm.rpm"; - int r; - - assert((a = archive_read_new()) != NULL); - r = archive_read_support_filter_gzip(a); - if (r == ARCHIVE_WARN) { - skipping("gzip reading not fully supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - assertEqualIntA(a, ARCHIVE_OK, r); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_rpm(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - extract_reference_file(name); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 2)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("./etc/file1", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("./etc/file2", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("./etc/file3", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Verify the end-of-archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify that the format detection worked. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_GZIP); - assertEqualString(archive_filter_name(a, 0), "gzip"); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_SVR4_NOCRC); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_svr4_gzip_rpm.rpm.uu b/thirdparty/libarchive/libarchive/test/test_read_format_cpio_svr4_gzip_rpm.rpm.uu deleted file mode 100644 index 54d305b77..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_svr4_gzip_rpm.rpm.uu +++ /dev/null @@ -1,46 +0,0 @@ -begin 644 test_read_format_cpio_svr4_gzip_rpm.rpm -M[:ONVP,``````7)P;7-A;7!L92TQ+C`N,"TQ```````````````````````` -M```````````````````````````````````````````!``4````````````` -M````````CJWH`0`````````%````5````#X````'````1````!````$-```` -M!@`````````!```#Z`````0````L`````0```^P````'````,````!````/O -M````!````$`````!9&9E8V,W,#4T,C@X,V1D-&8P-6%E.#4Y,S6QO861&:6QE -MFEP`#D`;F]A``````````````` -M```````!`````0````$`05-#24D@=&5X=`!D:7)E8W1O@$!@"1O'?9"`(````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_svr4c_Z.c b/thirdparty/libarchive/libarchive/test/test_read_format_cpio_svr4c_Z.c deleted file mode 100644 index 29aa2c634..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_cpio_svr4c_Z.c +++ /dev/null @@ -1,60 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_cpio_svr4c_Z.c 189381 2009-03-05 00:31:48Z kientzle $"); - -static unsigned char archive[] = { -31,157,144,'0','n',4,132,'!',3,6,140,26,'8','n',228,16,19,195,160,'A',26, -'1',202,144,'q','h','p','F',25,28,20,'a','X',196,152,145,' ',141,25,2,'k', -192,160,'A',163,163,201,135,29,'c',136,'<',201,'2','c','A',147,'.',0,12,20, -248,178,165,205,155,20,27,226,220,201,243,166,152,147,'T',164,4,'I',194,164, -136,148,16,'H',1,'(',']',202,180,169,211,167,'P',163,'J',157,'J',181,170, -213,171,'X',179,'j',221,202,181,171,215,175,'L',1}; - -DEFINE_TEST(test_read_format_cpio_svr4c_Z) -{ - struct archive_entry *ae; - struct archive *a; -/* printf("Archive address: start=%X, end=%X\n", archive, archive+sizeof(archive)); */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, archive, sizeof(archive))); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - failure("archive_filter_name(a, 0)=\"%s\"", - archive_filter_name(a, 0)); - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS); - failure("archive_format_name(a)=\"%s\"", archive_format_name(a)); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_SVR4_CRC); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_empty.c b/thirdparty/libarchive/libarchive/test/test_read_format_empty.c deleted file mode 100644 index 2556503ac..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_empty.c +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_empty.c 189308 2009-03-03 17:02:51Z kientzle $"); - -static unsigned char archive[] = { 0 }; - -DEFINE_TEST(test_read_format_empty) -{ - struct archive_entry *ae; - struct archive *a; - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_open_memory(a, archive, 0)); - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - assertA(archive_filter_code(a, 0) == ARCHIVE_FILTER_NONE); - assertA(archive_format(a) == ARCHIVE_FORMAT_EMPTY); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_gtar_filename.c b/thirdparty/libarchive/libarchive/test/test_read_format_gtar_filename.c deleted file mode 100644 index f81796b78..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_gtar_filename.c +++ /dev/null @@ -1,501 +0,0 @@ -/*- - * Copyright (c) 2011 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD"); - -#include - -DEFINE_TEST(test_read_format_gtar_filename_eucJP_UTF8) -{ - const char *refname = "test_read_format_gtar_filename_eucjp.tar.Z"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read eucJP filename in en_US.UTF-8 with "hdrcharset=eucJP" option. - */ - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("en_US.UTF-8 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=eucJP")) { - skipping("This system cannot convert character-set" - " from eucJP to UTF-8."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xe6\xbc\xa2\xe5\xad\x97.txt", - archive_entry_pathname(ae)); - assertEqualInt(8, archive_entry_size(ae)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xe8\xa1\xa8.txt", archive_entry_pathname(ae)); - assertEqualInt(4, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_TAR_GNUTAR, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_gtar_filename_CP866_KOI8R) -{ - const char *refname = "test_read_format_gtar_filename_cp866.tar.Z"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read CP866 filename in ru_RU.KOI8-R with "hdrcharset=CP866" option. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia.20866") && - NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) { - skipping("ru_RU.KOI8-R locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) { - skipping("This system cannot convert character-set" - " from CP866 to KOI8-R."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xf0\xf2\xe9\xf7\xe5\xf4", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\xd2\xc9\xd7\xc5\xd4", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_TAR_GNUTAR, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_gtar_filename_CP866_UTF8) -{ - const char *refname = "test_read_format_gtar_filename_cp866.tar.Z"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read CP866 filename in en_US.UTF-8 with "hdrcharset=CP866" option. - */ - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("en_US.UTF-8 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) { - skipping("This system cannot convert character-set" - " from CP866 to UTF-8."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_TAR_GNUTAR, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_gtar_filename_KOI8R_CP866) -{ - const char *refname = "test_read_format_gtar_filename_koi8r.tar.Z"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read KOI8-R filename in ru_RU.CP866 with "hdrcharset=KOI8-R" option. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia.866") && - NULL == setlocale(LC_ALL, "ru_RU.CP866")) { - skipping("ru_RU.CP866 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) { - skipping("This system cannot convert character-set" - " from KOI8-R to CP866."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xaf\xe0\xa8\xa2\xa5\xe2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\x8f\x90\x88\x82\x85\x92", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_TAR_GNUTAR, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_gtar_filename_KOI8R_UTF8) -{ - const char *refname = "test_read_format_gtar_filename_koi8r.tar.Z"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read KOI8-R filename in en_US.UTF-8 with "hdrcharset=KOI8-R" option. - */ - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("en_US.UTF-8 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) { - skipping("This system cannot convert character-set" - " from KOI8-R to UTF-8."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_TAR_GNUTAR, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_gtar_filename_eucJP_CP932) -{ - const char *refname = "test_read_format_gtar_filename_eucjp.tar.Z"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read eucJP filename in CP932/SJIS with "hdrcharset=eucJP" option. - */ - if (NULL == setlocale(LC_ALL, "Japanese_Japan") && - NULL == setlocale(LC_ALL, "ja_JP.SJIS")) { - skipping("CP932 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=eucJP")) { - skipping("This system cannot convert character-set" - " from eucJP."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\x8a\xbf\x8e\x9a.txt", archive_entry_pathname(ae)); - assertEqualInt(8, archive_entry_size(ae)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\x95\x5c.txt", archive_entry_pathname(ae)); - assertEqualInt(4, archive_entry_size(ae)); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_TAR_GNUTAR, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_gtar_filename_CP866_CP1251) -{ - const char *refname = "test_read_format_gtar_filename_cp866.tar.Z"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read CP866 filename in CP1251 with "hdrcharset=CP866" option. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia") && - NULL == setlocale(LC_ALL, "ru_RU.CP1251")) { - skipping("CP1251 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) { - skipping("This system cannot convert character-set" - " from CP866 to CP1251."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_TAR_GNUTAR, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* - * This test only for Windows platform because other archiver - * applications on Windows translate CP1251 filenames into CP866 - * filenames and store it in the gtar file and so we should read - * it by default on Windows. - */ -DEFINE_TEST(test_read_format_gtar_filename_CP866_CP1251_win) -{ - const char *refname = "test_read_format_gtar_filename_cp866.tar.Z"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read CP866 filename in CP1251 without "hdrcharset=CP866" option. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia")) { - skipping("Russian_Russia locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_TAR_GNUTAR, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_gtar_filename_KOI8R_CP1251) -{ - const char *refname = "test_read_format_gtar_filename_koi8r.tar.Z"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read KOI8-R filename in CP1251 with "hdrcharset=KOI8-R" option. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia") && - NULL == setlocale(LC_ALL, "ru_RU.CP1251")) { - skipping("CP1251 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) { - skipping("This system cannot convert character-set" - " from KOI8-R to CP1251."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_TAR_GNUTAR, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_gtar_filename_cp866.tar.Z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_gtar_filename_cp866.tar.Z.uu deleted file mode 100644 index a6fd80c24..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_gtar_filename_cp866.tar.Z.uu +++ /dev/null @@ -1,10 +0,0 @@ -begin 644 test_read_format_gtar_cp866.tar.Z -M'YV0CR`A$E1($H"#"!,J7,BPH<.'$"-*1`BC(HP;-6H`L!@#8XR-%3O6^&BQ -MI$4;`&+$J$'CQ@P9*V&0C`'#Q@T9`$#`F,BSI\^?0`'4F4,GC!P0(`",J5,F -MJ,.E39U*G4JUJM6K6'G"DY?N7CEZ6<.*'4NVK-FS:-.J7JG/$RY\Z[D!L.+7HT*=2LER-KWLS9 -MY]:N7SN+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ -MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ -1O?OW\./+GT^_OOW[^//KKPX` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_gtar_filename_eucjp.tar.Z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_gtar_filename_eucjp.tar.Z.uu deleted file mode 100644 index 87fa582f6..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_gtar_filename_eucjp.tar.Z.uu +++ /dev/null @@ -1,10 +0,0 @@ -begin 644 test_read_format_gtar_eucjp.tar.Z -M'YV0M(+MTN>"#AXZ`!(J7,BPH<.'$"-*G$@1`(R+,&S0H&'Q8HP;-6)TA/$Q -MY$B,&&/``!`C1HV0-63(B+F29`P:)D&LK,BSI\^?0.O,H1-&#@@0`,;4*0,T -MHE*F3:-*G4JUJM6K4Q7]O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ -MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ -1O?OW\./+GT^_OOW[^//K+PT` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_gtar_filename_koi8r.tar.Z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_gtar_filename_koi8r.tar.Z.uu deleted file mode 100644 index bf4ce0170..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_gtar_filename_koi8r.tar.Z.uu +++ /dev/null @@ -1,10 +0,0 @@ -begin 644 test_read_format_gtar_koi8r.tar.Z -M'YV0T*0ENU:,&H"#"!,J7,BPH<.'$"-*1`BC(HP;-6H`L!@#8XR-%3O6^&BQ -MI$4;`&+$J$'CQ@P9%6>@A*&RAHP;`$#`F,BSI\^?0`'4F4,GC!P0(`",J5,F -MJ,.E39U*G4JUJM6K6'G"DY?N7CEZ6<.*'4NVK-FS:-.J7O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ -MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ -+O?OW\./+GT^__G,` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_gtar_gz.c b/thirdparty/libarchive/libarchive/test/test_read_format_gtar_gz.c deleted file mode 100644 index 2541f9926..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_gtar_gz.c +++ /dev/null @@ -1,63 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_gtar_gz.c 191183 2009-04-17 01:06:31Z kientzle $"); - -static unsigned char archive[] = { -31,139,8,0,'+','e',217,'D',0,3,211,211,'g',160,'9','0',0,2,'s','S','S',16, -'m','h','n','j',128,'L',195,0,131,161,129,177,177,137,129,137,185,185,161, -'!',131,129,161,129,153,161,'9',131,130,')',237,157,198,192,'P','Z','\\', -146,'X',164,160,192,'P',146,153,139,'W',29,'!','y',152,'G','`',244,'(',24, -5,163,'`',20,12,'r',0,0,226,234,'6',162,0,6,0,0}; - -DEFINE_TEST(test_read_format_gtar_gz) -{ - struct archive_entry *ae; - struct archive *a; - int r; - - assert((a = archive_read_new()) != NULL); - assertEqualInt(ARCHIVE_OK, archive_read_support_filter_all(a)); - r = archive_read_support_filter_gzip(a); - if (r == ARCHIVE_WARN) { - skipping("gzip reading not fully supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - assertEqualInt(ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualInt(ARCHIVE_OK, - archive_read_open_memory(a, archive, sizeof(archive))); - assertEqualInt(ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_file_count(a)); - assertEqualInt(archive_filter_code(a, 0), - ARCHIVE_FILTER_GZIP); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_GNUTAR); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_gtar_lzma.c b/thirdparty/libarchive/libarchive/test/test_read_format_gtar_lzma.c deleted file mode 100644 index 280a089fd..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_gtar_lzma.c +++ /dev/null @@ -1,76 +0,0 @@ -/*- - * Copyright (c) 2008 Miklos Vajna - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_gtar_lzma.c 191183 2009-04-17 01:06:31Z kientzle $"); - -static unsigned char archive[] = { -0x5d, 0x0, 0x0, 0x80, 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, -0x17, 0xb, 0xbc, 0x1c, 0x7d, 0x1, 0x95, 0xc0, 0x1d, 0x4a, 0x46, 0x9c, -0x1c, 0xc5, 0x8, 0x82, 0x10, 0xed, 0x84, 0xf6, 0xea, 0x7a, 0xfe, 0x63, -0x5a, 0x34, 0x5e, 0xf7, 0xc, 0x60, 0xd6, 0x8b, 0xc1, 0x47, 0xaf, 0x11, -0x6f, 0x18, 0x94, 0x81, 0x74, 0x8a, 0xf8, 0x47, 0xcc, 0xdd, 0xc0, 0xd9, -0x40, 0xa, 0xc3, 0xac, 0x43, 0x47, 0xb5, 0xac, 0x2b, 0x31, 0xd3, 0x6, -0xa4, 0x2c, 0x44, 0x80, 0x24, 0x4b, 0xfe, 0x43, 0x22, 0x4e, 0x14, 0x30, -0x7a, 0xef, 0x99, 0x6e, 0xf, 0x8b, 0xc1, 0x79, 0x93, 0x88, 0x54, 0x73, -0x59, 0x3f, 0xc, 0xfb, 0xee, 0x9c, 0x83, 0x49, 0x93, 0x33, 0xad, 0x44, -0xbe, 0x0}; - -DEFINE_TEST(test_read_format_gtar_lzma) -{ - int r; - - struct archive_entry *ae; - struct archive *a; - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - r = archive_read_support_filter_lzma(a); - if (r == ARCHIVE_WARN) { - skipping("lzma reading not fully supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - - assertEqualIntA(a, ARCHIVE_OK, r); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_all(a)); - r = archive_read_open_memory2(a, archive, sizeof(archive), 3); - if (r != ARCHIVE_OK) { - skipping("Skipping LZMA compression check: %s", - archive_error_string(a)); - goto finish; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_next_header(a, &ae)); - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_LZMA); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_GNUTAR); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); -finish: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_gtar_sparse.c b/thirdparty/libarchive/libarchive/test/test_read_format_gtar_sparse.c deleted file mode 100644 index 6d15a4745..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_gtar_sparse.c +++ /dev/null @@ -1,309 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_gtar_sparse.c 189308 2009-03-03 17:02:51Z kientzle $"); - - -struct contents { - int64_t o; - size_t s; - const char *d; -}; - -struct contents archive_contents_sparse[] = { - { 1000000, 1, "a" }, - { 2000000, 1, "a" }, - { 3145728, 0, NULL } -}; - -struct contents archive_contents_sparse2[] = { - { 1000000, 1, "a" }, - { 2000000, 1, "a" }, - { 3000000, 1, "a" }, - { 4000000, 1, "a" }, - { 5000000, 1, "a" }, - { 6000000, 1, "a" }, - { 7000000, 1, "a" }, - { 8000000, 1, "a" }, - { 9000000, 1, "a" }, - { 10000000, 1, "a" }, - { 11000000, 1, "a" }, - { 12000000, 1, "a" }, - { 13000000, 1, "a" }, - { 14000000, 1, "a" }, - { 15000000, 1, "a" }, - { 16000000, 1, "a" }, - { 17000000, 1, "a" }, - { 18000000, 1, "a" }, - { 19000000, 1, "a" }, - { 20000000, 1, "a" }, - { 21000000, 1, "a" }, - { 22000000, 1, "a" }, - { 23000000, 1, "a" }, - { 24000000, 1, "a" }, - { 25000000, 1, "a" }, - { 26000000, 1, "a" }, - { 27000000, 1, "a" }, - { 28000000, 1, "a" }, - { 29000000, 1, "a" }, - { 30000000, 1, "a" }, - { 31000000, 1, "a" }, - { 32000000, 1, "a" }, - { 33000000, 1, "a" }, - { 34000000, 1, "a" }, - { 35000000, 1, "a" }, - { 36000000, 1, "a" }, - { 37000000, 1, "a" }, - { 38000000, 1, "a" }, - { 39000000, 1, "a" }, - { 40000000, 1, "a" }, - { 41000000, 1, "a" }, - { 42000000, 1, "a" }, - { 43000000, 1, "a" }, - { 44000000, 1, "a" }, - { 45000000, 1, "a" }, - { 46000000, 1, "a" }, - { 47000000, 1, "a" }, - { 48000000, 1, "a" }, - { 49000000, 1, "a" }, - { 50000000, 1, "a" }, - { 51000000, 1, "a" }, - { 52000000, 1, "a" }, - { 53000000, 1, "a" }, - { 54000000, 1, "a" }, - { 55000000, 1, "a" }, - { 56000000, 1, "a" }, - { 57000000, 1, "a" }, - { 58000000, 1, "a" }, - { 59000000, 1, "a" }, - { 60000000, 1, "a" }, - { 61000000, 1, "a" }, - { 62000000, 1, "a" }, - { 63000000, 1, "a" }, - { 64000000, 1, "a" }, - { 65000000, 1, "a" }, - { 66000000, 1, "a" }, - { 67000000, 1, "a" }, - { 68000000, 1, "a" }, - { 69000000, 1, "a" }, - { 70000000, 1, "a" }, - { 71000000, 1, "a" }, - { 72000000, 1, "a" }, - { 73000000, 1, "a" }, - { 74000000, 1, "a" }, - { 75000000, 1, "a" }, - { 76000000, 1, "a" }, - { 77000000, 1, "a" }, - { 78000000, 1, "a" }, - { 79000000, 1, "a" }, - { 80000000, 1, "a" }, - { 81000000, 1, "a" }, - { 82000000, 1, "a" }, - { 83000000, 1, "a" }, - { 84000000, 1, "a" }, - { 85000000, 1, "a" }, - { 86000000, 1, "a" }, - { 87000000, 1, "a" }, - { 88000000, 1, "a" }, - { 89000000, 1, "a" }, - { 90000000, 1, "a" }, - { 91000000, 1, "a" }, - { 92000000, 1, "a" }, - { 93000000, 1, "a" }, - { 94000000, 1, "a" }, - { 95000000, 1, "a" }, - { 96000000, 1, "a" }, - { 97000000, 1, "a" }, - { 98000000, 1, "a" }, - { 99000000, 1, "a" }, - { 99000001, 0, NULL } -}; - -struct contents archive_contents_nonsparse[] = { - { 0, 1, "a" }, - { 1, 0, NULL } -}; - -/* - * Describe an archive with three entries: - * - * File 1: named "sparse" - * * a length of 3145728 bytes (3MiB) - * * a single 'a' byte at offset 1000000 - * * a single 'a' byte at offset 2000000 - * File 2: named "sparse2" - * * a single 'a' byte at offset 1,000,000, 2,000,000, ..., 99,000,000 - * * length of 99,000,001 - * File 3: named 'non-sparse' - * * length of 1 byte - * * contains a single byte 'a' - */ - -struct archive_contents { - const char *filename; - struct contents *contents; -} files[] = { - { "sparse", archive_contents_sparse }, - { "sparse2", archive_contents_sparse2 }, - { "non-sparse", archive_contents_nonsparse }, - { NULL, NULL } -}; - -static void -verify_archive_file(const char *name, struct archive_contents *ac) -{ - struct archive_entry *ae; - int err; - /* data, size, offset of next expected block. */ - struct contents expect; - /* data, size, offset of block read from archive. */ - struct contents actual; - const void *p; - struct archive *a; - - extract_reference_file(name); - - assert((a = archive_read_new()) != NULL); - assert(0 == archive_read_support_filter_all(a)); - assert(0 == archive_read_support_format_tar(a)); - failure("Can't open %s", name); - assert(0 == archive_read_open_filename(a, name, 3)); - - while (ac->filename != NULL) { - struct contents *cts = ac->contents; - - if (!assertEqualIntA(a, 0, archive_read_next_header(a, &ae))) { - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - failure("Name mismatch in archive %s", name); - assertEqualString(ac->filename, archive_entry_pathname(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - expect = *cts++; - while (0 == (err = archive_read_data_block(a, - &p, &actual.s, &actual.o))) { - actual.d = p; - while (actual.s > 0) { - char c = *actual.d; - if(actual.o < expect.o) { - /* - * Any byte before the expected - * data must be NULL. - */ - failure("%s: pad at offset %jd " - "should be zero", name, - (intmax_t)actual.o); - assertEqualInt(c, 0); - } else if (actual.o == expect.o) { - /* - * Data at matching offsets must match. - */ - assertEqualInt(c, *expect.d); - expect.d++; - expect.o++; - expect.s--; - /* End of expected? step to next expected. */ - if (expect.s <= 0) - expect = *cts++; - } else { - /* - * We found data beyond that expected. - */ - failure("%s: Unexpected trailing data", - name); - assert(actual.o <= expect.o); - archive_read_free(a); - return; - } - actual.d++; - actual.o++; - actual.s--; - } - } - failure("%s: should be end of entry", name); - assertEqualIntA(a, err, ARCHIVE_EOF); - failure("%s: Size returned at EOF must be zero", name); - assertEqualInt((int)actual.s, 0); - failure("%s: Offset of final empty chunk must be same as file size", name); - assertEqualInt(actual.o, expect.o); - /* Step to next file description. */ - ++ac; - } - - err = archive_read_next_header(a, &ae); - assertEqualIntA(a, ARCHIVE_EOF, err); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - -DEFINE_TEST(test_read_format_gtar_sparse) -{ - /* Two archives that use the "GNU tar sparse format". */ - verify_archive_file("test_read_format_gtar_sparse_1_13.tar", files); - verify_archive_file("test_read_format_gtar_sparse_1_17.tar", files); - - /* - * libarchive < 1.9 doesn't support the newer --posix sparse formats - * from GNU tar 1.15 and later. - */ - - /* - * An archive created by GNU tar 1.17 using --posix --sparse-format=0.1 - */ - verify_archive_file( - "test_read_format_gtar_sparse_1_17_posix00.tar", - files); - /* - * An archive created by GNU tar 1.17 using --posix --sparse-format=0.1 - */ - verify_archive_file( - "test_read_format_gtar_sparse_1_17_posix01.tar", - files); - /* - * An archive created by GNU tar 1.17 using --posix --sparse-format=1.0 - */ - verify_archive_file( - "test_read_format_gtar_sparse_1_17_posix10.tar", - files); - /* - * The last test archive here is a little odd. First, it's - * uncompressed, because that exercises some of the block - * reassembly code a little harder. Second, it includes some - * leading comments prior to the sparse block description. - * GNU tar doesn't do this, but I think it should, so I want - * to ensure that libarchive correctly ignores such comments. - * Dump the file, looking for "#!gnu-sparse-format" starting - * at byte 0x600. - */ - verify_archive_file( - "test_read_format_gtar_sparse_1_17_posix10_modified.tar", - files); -} - - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_gtar_sparse_1_13.tar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_gtar_sparse_1_13.tar.uu deleted file mode 100644 index 86a59ffa4..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_gtar_sparse_1_13.tar.uu +++ /dev/null @@ -1,1370 +0,0 @@ -$FreeBSD: head/lib/libarchive/test/test_read_format_gtar_sparse_1_13.tar.uu 191183 2009-04-17 01:06:31Z kientzle $ -begin 644 test_read_format_gtar_sparse_1_13.tar -M``````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````!UF4],S$T-371E71E71E71E$AE861E``````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````!UF4],S$T-3$AE861E``````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````!U``````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````````````````````!U -MF4].3DP,#`P,#$*,C`@ -M871I;64],3$Y.#(Y,S8P,PHR,"!C=&EM93TQ,3DX,CDS-C`Q"@`````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`"XO1TY54W!A``````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````!U``````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````!U``````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````````````````````!U -MF4].3DP,#`P,#$*,C`@ -M871I;64],3$Y.#(Y,S8P,PHR,"!C=&EM93TQ,3DX,CDS-C`Q"@`````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`"XO1TY54W!A``````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````!UBD:;,V!@T8-6)NE&'#10T<-#;>R(%CAEV28_3R9?LW\(P8-F[`<#%C -M)@T<->#6>`PBC.2^E07;J#'#Q>J-F5DJ<`GBB),J+N;`<3JGC(LV8=2\D<-V -M]DO;N'7S]MTFC9OA/6#,CE'[=N[=$V -M9]RY=212"9YD1EOO*&`DE!&*>645%9IY9589JGE -MEEQVZ>678(8IYIADEFGFF6BFJ>::;+;IYIMPQBGGG'36:>>=>.:IYYY\]NGG -MGX`&*NB@A!9JJ)YB](D@1PZ>U&B#*468484RT11###7<8!8(&-)4PX=^DN@4 -B5%*E6.J*746JTHN'2LFDDZW&*NNLM-9JZZVXYJKKKKR&!0`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_iso.iso.Z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_iso.iso.Z.uu deleted file mode 100644 index 989c11251..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_iso.iso.Z.uu +++ /dev/null @@ -1,26 +0,0 @@ -$FreeBSD: head/lib/libarchive/test/test_read_format_iso.iso.Z.uu 201247 2009-12-30 05:59:21Z kientzle $ - -begin 644 test_read_format_iso.iso.Z -M'YV0``(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR -MI,F3*%.J7,FRIO8,.*'4NVK-FS:-.J7//JW/'D"-+GDRYLN7+F#-KWLRY -ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ -MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ -MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$;(44890DQ!!`@01BCA -MA!1***`43S11X88<1G@0#`6!Z-&!``1`XH$((`"``@4I,$%"%0PD`@`7%%2C -MB@*IF,8"!UR``0O@"!#0B0=V:.212":IY)),-NGDDU!&*>645%9IY952-K%$ -M$E,\8<04('#Y!`@YV&`##"\@\24(1B3!1!%39#$%%45H*$05;A)1A!0@F`#" -MA44,\804#PK8@A0O$&%%H5(4$005@X*`PA`I@!!##CG,`$(1+F3Q1!5.'$%$ -M$&]*2JFEF-X`@A(N0.&H%%TZ\0*K4PR!A)M,)!$JEKSVRJL,!-800PPPW"## -M##+04,,-!((#+`S"$FLLLLHR"P,X!&:K[;8$`O!LM,4>F^RRS1;IZ[GHIJON -MNNRVZ^Z[\,8K+Y/_U;O8/P(2:*"]_/;K[[\`!UR=EDF`T,0;;H#@Q!MV0*CJ -ML3HDJ\.R('RK0!MKI#''&V;,4;$+,+B@:0MO@$!'&7/0T8*"89#QA1EOR-%& -M&'2XH'')80BL\\X\]^SSSV<=6..00!=M]-%()ZWTTDPW[?334$?=&XD!U4BU -MU%AGK?767'?M]==@ARWVV%K/./1`-PZD(X\^`BEDB4,>:+:-`.`8T-H]_A@D -MT26:2/;?@`N^>:<=^[Y -MYZ"'+OKHI)=N^NFHIZ[ZZJRW[OKKL,O_/+,-^_\\]!'+_WTU%=O_?789Z_]]MQW[_WWX(BGK_[Z[+?O_OOPQR___/37;__]^.>O__[\]^___P`,H``'2,`"&O"`]`,` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_iso_2.iso.Z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_iso_2.iso.Z.uu deleted file mode 100644 index 688ec36af..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_iso_2.iso.Z.uu +++ /dev/null @@ -1,35 +0,0 @@ -begin 644 test_read_format_iso_2.iso.Z -M'YV0``(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR -MI,F3*%.J7,FRIO8,.*'4NVK-FS:-.J7//JW/'D"-+GDRYLN7+F#-KWLRY -ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ -MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ -MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$Z408<04Q`!PH,01BCA -MA!16:.&%$!Z404$;>G0@``%\>"`""`#@04$>2)#0!`.)```%!<%8HD`EEF+C -MC:4($)"(!V+HXX]`!BGDD$06:>212":IY)),-NGDDU!&*>645%9II8\R%!@# -M##C$0(,,,6Q)PPP$DI-EF%QZ"::89,)`#H%PQBDGG&=NV>67:(Y9YH?_]>GG -MGX7](R"!!@)JZ*&()JKHHL<="...`AU80:0`!`$B`!=0.@2CG';JZ:>@A@H8 -MGR]>:FI`DP9@*:F9!BCJJ[#&*NNLM#[EXJ,#R3A0C3C:J*.I(0)P:XP`S!@0 -MK[W^RF,`+DY*T*3&%@O`&P@X4($"!I"C[(ZJNI@I09E&6R*UUBJP@+:0@NAJ -MK>RVZ^Z[\$;7;$'0[CIMM==FNZVZPI9*D*XT`M"KK^F&&(`)`%A0D`4&%&0` -MN?F20RF(!`CAP@XQQ*OQQAQW['%S:)3!!AMO*/#QR2BGK/+*G7I;4+CV0FPN -MNL`>..R_T@8\<(X%AX@P!@5AT#!!#^,[\\0!$$#$Q1FS[/334$M]MILM^WVVW#'+??<=-=M]]UXYZWW -MWGSW[???@`N^>:<=^[Y -MYZ"'+OKHI)=N^NFHIZ[ZZJRW[OKKL,O_/+,-^_\\]!'+_WTU%=O_?789Z_]]MQW[_WWX(BGK_[Z[+?O_OOPQR___/37;__]^.>O__[\]^___P`,H``'2,`"&O"`"$R@ -M`A?(P`8Z\($0C*`$)TC!"EKP@AC,H`8WR,$.>O"#(`RA"$=(PA*:\(0H3*$* -M5\C"%KKPA3",H0QG2,,:VO"&.,RA#G?(PQ[Z\(=`#*(0ATC$(AKQB$A,HA*7 -MR,0F.O&)4(RB%*=(Q2I:\8I8S*(6M\C%+GKQBV`,HQC'2,8RFO&,:$RC&M?( -MQC:Z\8UPC*,O.;X`RG.,=)SG*:\YSH3*^,RG/O?)SW[Z\Y\`#:A`!TK0@AKTH`A-J$(7RM"&.O2A -M$(VH1"=*T8I:]*(8S:A&-\K1CGKTHR`-J4A'2M*2FO2D*$VI2E?*TI:Z]*4P -MC:E,9TK3FMKTICC-J4YWRM.>^O2G0`VJ4(=*U*(:]:A(3:I2E\K4ICKUJ5"- -MJE2G2M6J6O6J6,VJ5K?*U:YZ]:M@#:M8QTK6LIKUK&A-JUK7RM:VNO6M<`TG -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_iso_Z.c b/thirdparty/libarchive/libarchive/test/test_read_format_iso_Z.c deleted file mode 100644 index 6492706c3..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_iso_Z.c +++ /dev/null @@ -1,103 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_iso_gz.c 201247 2009-12-30 05:59:21Z kientzle $"); - -static void -test1(void) -{ - struct archive_entry *ae; - struct archive *a; - const char *name = "test_read_format_iso.iso.Z"; - - extract_reference_file(name); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, name, 512)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_file_count(a)); - assertEqualInt(archive_filter_code(a, 0), - ARCHIVE_FILTER_COMPRESS); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -static void -test2(void) -{ - struct archive_entry *ae; - struct archive *a; - const char *name = "test_read_format_iso_2.iso.Z"; - - extract_reference_file(name); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, name, 512)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_next_header(a, &ae)); - assertEqualString(".", archive_entry_pathname(ae)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_next_header(a, &ae)); - assertEqualString("A", archive_entry_pathname(ae)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_next_header(a, &ae)); - assertEqualString("A/B", archive_entry_pathname(ae)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_next_header(a, &ae)); - assertEqualString("C", archive_entry_pathname(ae)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_next_header(a, &ae)); - assertEqualString("C/D", archive_entry_pathname(ae)); - assertEqualIntA(a, ARCHIVE_EOF, - archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_file_count(a)); - assertEqualInt(archive_filter_code(a, 0), - ARCHIVE_FILTER_COMPRESS); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_iso_Z) -{ - test1(); - test2(); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_iso_joliet.iso.Z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_iso_joliet.iso.Z.uu deleted file mode 100644 index 4642fece1..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_iso_joliet.iso.Z.uu +++ /dev/null @@ -1,66 +0,0 @@ -$FreeBSD: head/lib/libarchive/test/test_read_format_iso_joliet.iso.Z.uu 201247 2009-12-30 05:59:21Z kientzle $ - -begin 644 test_read_format_iso_joliet.iso.Z -M'YV0``(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR -MI,F3*%.J7,FRIO8,.*'4NVK-FS:-.J7//JW/'D"-+GDRYLN7+F#-KWLRY -ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ -MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ -MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$PDX4056(#@X(,01BBA -MA`)*\403$V:HX8,'X5*0AQX="$``(AZ(``(`6%"0!10DI*)`(@#`04$SHB@0 -MBD8$(,"!`1`@0$`E'KCAD$06:>212":IY)),-NGDDU!&*>645#YY1!%.)#'% -M$TDT$<25(&CY!`@YV&`##"\@8<04(!B1!!-%3)'%%%04@>$04A01!!5/2`$" -M"D.D`$(,.>0P`PA%N)#%$U4X<0010<#Y9Z"#%GI#"S(0:`,(2K@`A9Y2;.G$ -M"YU.,002;R;HZ*2"9@J##9@2>`,(%2Z1!!4@U!D$AE7VZJN3KN8`0Z8TR!!# -M#3+,0`.!!`0[+`S%'IOLLC`00."UV&9+(`#.$FLLLLHR*^2OY)9K[KGHIJON -MNNRVZ^Z[2?XG[V(""$B@@0$Q`4`2`#@!0!4`8`$`"`,73/#!!B=,\!``$`&` -M%``\`4`3"E>,\,4=?EC""T5P%"20`)P(``8%84`R0AH,%*,'!;%L8T`XZLBC -MCR"/*"+&.%NL<\X\[^QSST#_+'301`]M=-%('ZUTTDPO[7334#\M-<9'`-"Q -MO_Q.$?&^$P,0!`!5=TQPUEL3G`,`-J`-``P`?`$`$@`8`8#6!,O-K[X=:YW% -MW`!08777"S_\]]=^2PPQP2@`P'`*!<<`P-EGSU!PQRX`L+?$`/M;M<-?XSVU -MT9\7';K0W4+[[;3,EAXMN-1:J^WKVZI^>KC5C@OO[;CGKOONO/?N^^]'SBO\ -M8?_86Z"(PR>O_/+,-^_\\]!'+_WTU%=O?50'SE@S``,`T(%`!Q*1!,37EV_^ -M^>BGK_[Z[+?O_OOPQT\8\C*.&%#W`GT?@/CDR^___P`,H``'2,`"&O"`"$Q@ -M>P[$LNT9```?`%]`R`"`-`!`#@K,H`8WR,$.>O"#(`RA"$=(PJ'0CV4B>J!` -M(G@@"EH0@R6,H0QG2,,:VO"&.,RA#G<('D34CR`U&DC,=C0BFMG/9G.#P@$" -MX(MW/$P*!0A`(*"`!1($H!U?$T@0VH&_@0R`?D#Z$4$$0`4C:"``#L@1$7ND -MQIFU00`$J``-1$"`(12!`P$@&$'T6)!V]-$,/QQ($&\4-YD548Q!"H`4H"A% -M*EH1BP/98A<%\L6"Z*@@9#0C&MM81$[VZ(UQG",!```'[Q7D>R\+62'7:,02 -M#8!_BXQB(IS0!`2T,`UR<.05LQB0+8IQ($0DR"7'6,8SIM&0;$0F`4`I1SH" -M@`\`"$%!0J#"@1@@1Y6$HP1'M``D!$$*1%#5$ERP@QC$,@"S;$(##H2&,,B! -M#&Q(@QO6H$M2!&(@@2#%+P42S($,$YC%W&0`LDD`;!X(CLP4I26B.L_^"+H$<5EG<6O=`"0N@@2)8"J'^%F*/M"%%^060PE"S8)`E*#;#``$`(`& -M`(0AO11D0P4!X`8`K`$`7ECO0-I+D/=*-+X\`(!^W\!?`)P!`"T`@!H`P&#] -M6K`,`*`#A&6[7_UB.,+]O6\;`(#ARFD8PWC(,(V2NTOD*EOY -MREB67A&DT(X`*(`*A]AM$J#P!4+E(`9[0D(10&"A(2R!S4D@`I@45"J9"$(4P!"G`*PA36[&^F0406&&C56C" -MFI5M*FE#@4^S=G2I3YWJ9]/:2YR^:.6RS.YVN_O=2D%#&=A@4@7`^][XSK>^ -M]\WO?OO[WP`/N,`'3O""&_S@"$^XPA?.\(8[_.$0C[C$)T[QBEO\XAC/N,8W -MSO&.>_SC(`^YR$=.\I*;_.0H3[G*5\[REKO\Y3"/NI8S[K6M\[U -MKGO]ZV`/N]C'3O:RF_WL:$^[VM?.]K:[_>UPC[O^ -M^_WO@`^\X`=/^,(;_O"(3[SB%\_XQCO^\9"/O.0G3_G*6_[RF,^\YC?/^I7S_K6N_[UL(^][&=/^]K;_O:XS[WN=\_[WOO^ -M]\`/OO"'3_SB&__XR$^^\I?/_.8[__G0C[[TIT_]ZEO_^MC/OO:WS_WN>__[ -MX`^_^,=/_O*;__SH3[_ZU\_^]KO__?"/O_SG3__ZV__^^,^__O?/__[[__\` -M&(`".(`$6(`&>(`(F(`*N(`,V(`.^(`0&($2.($46($6>($8F($:N($ -M^($@&((B.((D6((F>((HF((JN((LV((N^((P&(,R.(,T6(,V>(,XF(,ZN(,\ -MV(,^^(-`&(1".(1$6(1&>(1(F(1*N(1,V(1.^(10&(52.(546(56>(58F(5: -MN(5^(5@&(9B.(9D6(9F>(9HF(9JN(9LV(9N^(9P&(=R.(=T6(=V>(=X -MF(=ZN(=\V(=^^(>`&(B".(B$6(B&>(B(F(B*N(B,V(B.^(B0&(F2.(F46(F6 -M>(F8F(F:N(F^(F@&(JB.(JD6(JF>(JHF(JJN(JLV(JN^(JP&(NR.(NT -M6(NV>(NXF(NZN(N\V(N^^(O`&(S".(S$6(S&>(S(F(S*N(S,V(S.^(S0&(W2 -M.(W46(W6>(W8F(W:N(W^(W@&([B.([D6([F>([HF([JN([LV([N^([P -(&(_R.(_T:!4` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_iso_joliet_by_nero.iso.Z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_iso_joliet_by_nero.iso.Z.uu deleted file mode 100644 index 8a5a26332..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_iso_joliet_by_nero.iso.Z.uu +++ /dev/null @@ -1,64 +0,0 @@ -begin 600 test_read_format_iso_joliet_by_nero.iso.Z -M'YV0``(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR -MI,F3*%.J7,FRIO8,.*'4NVK-FS:-.J7//JW/'D"-+GDRYLN7+F#-KWLRY -ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ -MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ -MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```"`DJ.""##;HX()??/'@ -MA!0J>!`6`@PD`!8?'0A``!X>B``"`%A0D`45)&2B0"(`,$%!+Y(H$(EN&-`! -M!0,@F.&'`8&(8(5`!BGDD$06:>212":IY)),-NGDDU!&J:`314CQ!`A"5"&% -M$TDX<00(5C8AY9ADEFGFF5#*4""!-LB0@YHPS$`@@2"H&0.;;L(IYYP@S.GG -MGWX"`.B@<_+XWZ&()FJ8``(2:&!`("`H::243FIII9@&5`8L7N@C4*:@7FHI -M0AAJB$4)+Q3!48@A`C`B`!H4I$$&"<7*(@`7%)2KC`'1:"...O;8HX>A%BNJ -ML<@>JVRRS"[K;+.50OKLM-!2:VVUV%XKJK39=JNMM^!^ZVQ`3@!0!@!R`/"& -MI$(`4`>Z`+@!0!KQ`G"&I%(`\`0`38@;[K_^CAMPM0-;6W"S=N+Y)H%[TIDP -M#&TN'*>??1(ZJ*`6`VJHHAQW['%=_S1:H(WX$N;TP`T0(=&'C5CF>N^>:<=^[Y -M0R2[:.CD`A4=P.6?IZ[ZZJRW7G*+N1*TJ]@^OWTS[+JNW6O;P)K-:@`J`(!! -M0<,C+3/930/](8ETF`O`'``T[_KTU%=O_?6,M3@\0<73OG3R?A^(N^RZ)UV[ -M[T';,'?==[N:]]Y]GUUT\^="W[P+T0.`1_X[`(`X]@`,H``'2$"N'"AV&R/1 -M]@Q%O^?EKX`0C*`$)TC!RX0N5QY"VO`.U$#[5?"#(`RA"$=(%SJ480YT,$,: -MV'`N$KKPA3",H0QG2,,:VO"&.,RA#G?(PQ[Z\(=`#*(0ATC$(AKQB$A,HA*7 -MR,0F.O&)4(RB%*=(Q2I:\8I8S*(6M\C%+GKQBV`,HQC'2,8RFO&,:$RC&M?( -MQC:Z\8UPC*,O.;X`RG.,=)SG*:\YSH3*^,RG/O?)SW[Z\Y\`#:A`!TK0@AKTH`A-J$(7RM"&.O2A -M$(VH1"=*T8I:]*(8S:A&-\K1CGKTHR`-J4A'2M*2FO2D*$VI2E?*TI:Z]*4P -MC:E,9TK3FMKTICC-J4YWRM.>^O2G0`VJ4(=*U*(:]:A(3:I2E\K4ICKUJ5"- -MJE2G2M6J6O6J6,VJ5K?*U:YZ]:M@#:M8QTK6LIKUK&A-JUK7RM:VNO6M<(VK -M7.=*U[K:]:YXS:M>]\K7OOKUKX`-K&`'2]C"&O:PB$VL8A?+V,8Z]K&0C:QD -M)TO9REKVLIC-K&8WR]G.>O:SH`VM:$=+VM*:]K2H3:UJ5\O:UKKVM;"-K6QG -M2]O:VO:VN,VM;G?+V][Z]K?`#:YPATOYT(VN=*=+ -MW>I:][K8S:YVM\O=[GKWN^`-KWC'2][RFO>\Z$VO>M?+WO:Z][WPC:]\YTO? -M^MKWOOC-KW[WR]_^^O>_``ZP@`=,X`(;^,`(3K""%\S@!COXP1".L(0G3.$* -M6_C"&,ZPAC?,X0Y[^,,@#K&(1TSB$IOXQ"A.L8I7S.(6N_C%,(ZQC&=,XQK; -M^,8XSK&.=\SC'OOXQT`.LI"'3.0B&_G(2$ZRDI?,Y"8[^_G+8`ZSF,=,YC*;^,ZSGO?,YS[[^<^`#K2@!TWH0AOZT(A.M*(7S>A&._K1D(ZTI"=-Z4I;^M*8 -MSK2F-\WI3GOZTZ`.M:A'3>I2F_K4J$ZUJE?-ZE:[^M6PCK6L9TWK6MOZUKC. -MM:YWS>M>^_K7P`ZVL(=-[&(;^]C(3K:RE\WL9CO[V=".MK2G3>UJ6_O:V,ZV -MMK?-[6Y[^]O@#K>XQTWNYVN_O=\(ZWO.=-[WK;^][XSK>^ -M]\WO?OO[WP`/N,`'3O""&_S@"$^XPA?.\(8[_.$0C[C$)T[QBEO\XAC/N,8W -MSO&.>_SC(`^YR$=.\I*;_.0H3[G*5\[REKO\Y3"/NI8S[K6M\[U -MKGO]ZV`/N]C'3O:RF_WL:$^[VM?.]K:[_>UPC[O^ -M^_WO@`^\X`=/^,(;_O"(3[SB%\_XQCO^\9"/O.0G3_G*6_[RF,^\YC?/^I7S_K6N_[UL(^][&=/^]K;_O:XS[WN=\_[WOO^ -M]\`/OO"'3_SB&__XR$^^\I?/_.8[__G0C[[TIT_]ZEO_^MC/OO:WS_WN>__[ -MX`^_^,=/_O*;__SH3[_ZU\_^]KO__?"/O_SG3__ZV__^^,^__O?/__[[__\` -M&(`".(`$6(`&>(`(F(`*N(`,V(`.^(`0&($2.($46($6>($8F($:N($ -M^($@&((B.((D6((F>((HF((JN((LV((N^((P&(,R.(,T6(,V>(,XF(,ZN(,\ -MV(,^^(-`&(1".(1$6(1&>(1(F(1*N(1,V(1.^(10&(52.(546(56>(58F(5: -MN(5^(5@&(9B.(9D6(9F>(9HF(9JN(9LV(9N^(9P&(=R.(=T6(=V>(=X -MF(=ZN(=\V(=^^(>`&(B".(B$6(B&>(B(F(B*N(B,V(B.^(B0&(F2.(F46(F6 -M>(F8F(F:N(F^(F@&(JB.(JD6(JF>(JHF(JJN(JLV(JN^(JP&(NR.(NT -M6(NV>(NXF(NZN(N\V(N^^(O`&(S".(S$6(S&>(S(F(S*N(S,V(S.^(S0&(W2 -M.(W46(W6>(W8F(W:N(W^(W@&([B.([D6([F>([HF([JN([LV([N^([P -F&(_R.(_T6(_V>(_XF(_ZN(_\V(_^^(\`&9`".9`$69`&>9`(V6X` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_iso_joliet_long.iso.Z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_iso_joliet_long.iso.Z.uu deleted file mode 100644 index 030dd3cb2..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_iso_joliet_long.iso.Z.uu +++ /dev/null @@ -1,71 +0,0 @@ -$FreeBSD: head/lib/libarchive/test/test_read_format_iso_joliet_long.iso.Z.uu 201247 2009-12-30 05:59:21Z kientzle $ - -begin 644 test_read_format_iso_joliet_long.iso.Z -M'YV0``(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR -MI,F3*%.J7,FRIO8,.*'4NVK-FS:-.J7//JW/'D"-+GDRYLN7+F#-KWLRY -ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ -MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ -MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$;(44890DQ!!`@01BCA -MA!1***`43S11X88<1GA0+@6!Z-&!``1`XH$((`"`!@5I0$%"%@PD`@`<%%2C -MB@*I:$0``B10(@D"!'3B@1T6:>212":IY)),-NGDDU!&*>645%9I991-+)'$ -M%$\8,04(6SX!0@XVV`##"TAX"8(123!1Q!193$%%$1H*446;1!0A!0@F@'!A -M$4,\(<6#`K8@Q0M$6$&H%$4$086@(*`P1`H@Q)!##C.`4(0+63Q1A1-'$!&$ -MFY%.6NFE-X"@A`M0-"H%ETZ\L.H40R#1)A-)@'KEKKSN*@.!.<1`(`XPX!!# -M##7D0"`)O\(0[+#%'IOLL@16:^VU!`+0[+/%1HNLLC"00&2OY)9K[KGHIJON -MNNRVZ^Z[2_XG[V(""$B@@0$9`8`<`)31+P!"`#`%`$0``(+!"!^L<,((#T$P -M`%(`\`0`33"\\,46(VR0B`/E4L(+17`TI)``I`@`.`6!@T%"+`HTXP<%P8QC -M0#KRZ&,`0))<(HD8]YRQST#_+'301`]M=-%('ZUTTDPO[7334#\M==143VUU -MU557O`0`20@L,8)>']SUP!,?G`,`-J`-``P`?`$`$F`/?+"^73,!0,@#9^$U -M%7=3C'#`57`-@-T%AQSQP28T_'#$(3L\<<0%'^QPP2U`W/;#5CPLN>4A!W&U -MU)\W';K3VPK;K;'?+ELZM*A/&RZVL%>K+;"F$]LZN.(:#._NO/?N^^_`!R_\ -M\$K.:_QA_]A;((G'-^_\\]!'+WUQ628!`A5HU`'"$V/0`2$.(!2KP[$Z)`O" -MM@K(X$*!Z\<0A@V9MJ`$""VH\08;:91!1PMLO.'&&?2K0QK(4"GZG6&`YP.! -M"Q;X@C3,X0W3BZ`$)TC!"EK0*;B8P8%JI+.2`<`#`CE0#&0P`QK4P`8WP,$% -M5\C"%KKPA3",H0QG2,,:VO"&CF$>C4I$LX&`,``C+.$)4XC#(AKQB$A,HA*7 -MR,0F.O&)4+S/@6#606=HC(<`B(&V`#`#`-```#50VPT`H,*SL4V+,N"B%\$H -M1C("P(Q9W&(7OQC&M(VQC&N+8QKGR$8[NA&.:%0C'=N(QS/*<8UU!,`=WYC' -M0/(QD8L$Y"$'Z<="ZE&0?53D'QLYR4Q&,H]D`$`:]A7%4IKRE*A,I2I7R%[4@SE"D,WLJ3,3!4`*`1UH00^:T($PU*$$@6A!>%20BMHHHQOM -MZ$Y!*E($D-2D5;TJ`'#QP8*`<&8>].C-M=\RK$M/)UKG@MD%[]*MB^TK6P@/WK7A&[6#*D00XJ96D' -M"C)9@^B+(/K2!0!F1!`1&*`@!A#KCT(HI`78-:TNV$$,UAJ`MKXUKH8-[&D/ -M.UO9#I:VM[5M;!5+V-KR%K>[+6QD`U#9@73@L@,Q`G(%HB]";+8@G@6M:'%& -MVA(M``E!&!2NG+"$U*XVJ*YMP('0$`8YD`%_;EC#4`-`BD`,)!"DF*A`!!#1 -M$LDW(`+@K(R@RM'IDL"_)[5J2=M)X`*+<[U%76@[[@L`^BZ5P0(`(4$\P%^I -M?O2_4\4J2DFPWO:^-[Y-K2]3"9)?Z%;8OP#.ZH`-S.(6N_C%\JJIA'V(TQ[Z -M]YXC8RU!#8I0A0:$H1`6,81G+!`*:[2_&0[P594\X)I:5"#RS.F->VHB'2/8 -MQP`XZD.%W-0G!P2C1[;P6)FL80&3`,9H3K.:UYR9E\6LQF'-,(Z%="`W$T1F -M\]3IA>>\LP#`X[F=_2Q!0IOAZ@;`BMNL)C2I.4QM1O.8S!2F-(.I3$A/4]*6 -MIC0VNWE-;EHST8V.=*6S*6H`_/E@!#D86.DY5CX?NM.*=C2C)PWK4%]ZU)P& -M-:UUG>E:[_K1I+[UIC\-;$Y_DY1IU*_+!#T00E_8T!```!H`$`92AI(-H@1` -M3=?`YFY[^]M!"("YFI,4:A4$4!T<"AAZ5*"8 -M``*,/\$*#7\3"*90!2A`05!46!.D3CZ%)&!A36TZ.)SD1*>1TZGB5$C"$*8` -M!3<%80H'#Y03J!"$(:2<"%L:0L>K(`1<3<'@>S("I'@.J"2P:0B.2L(3G#!R -M3TU\4Q`"^L69[G2H@RE/0[=Z$O0$)JYC/`E-R&X60&"%)S"A"DTX>)YH]6\H -M/"KJD!(ZT8W>=JE+(>XYW[H+[,WXQCO^\4%!0QG8T#\%0/[RF,^\YC?/^I7S_K6N_[UL(^][&=/^]K;_O:XS[WN=\_[WOO^ -M]\`/OO"'3_SB&__XR$^^\I?/_.8[__G0C[[TIT_]ZEO_^MC/OO:WS_WN>__[ -MX`^_^,=/_O*;__SH3[_ZU\_^]KO__?"/O_SG3__ZV__^^,^__O?/__[[__\` -M&(`".(`$6(`&>(`(F(`*N(`,V(`.^(`0&($2.($46($6>($8F($:N($ -M^($@&((B.((D6((F>((HF((JN((LV((N^((P&(,R.(,T6(,V>(,XF(,ZN(,\ -MV(,^^(-`&(1".(1$6(1&>(1(F(1*N(1,V(1.^(10&(52.(546(56>(58F(5: -MN(5^(5@&(9B.(9D6(9F>(9HF(9JN(9LV(9N^(9P&(=R.(=T6(=V>(=X -MF(=ZN(=\V(=^^(>`&(B".(B$6(B&>(B(F(B*N(B,V(B.^(B0&(F2.(F46(F6 -M>(F8F(F:N(F^(F@&(JB.(JD6(JF>(JHF(JJN(JLV(JN^(JP&(NR.(NT -M6(NV>(NXF(NZN(N\V(N^^(O`&(S".(S$6(S&>(S(F(S*N(S,V(S.^(S0&(W2 -M.(W46(W6>(W8F(W:N(W^(W@&([B.([D6([F>([HF([JN([LV([N^([P -M&(_R.(_T6(_V>(_XF(_ZN(_\V(_^^(\`&9`".9`$69`&>9`(F9`*N9`,V9`. -M^9`0&9$2.9$469$6>9$8F9$:N9$^9$@&9(B.9(D69(F>9(HF9(JN9(L -MV9(N^9(P&9,R.9,T69,V>9,XF9,ZN9,\V9,^^9-`&91".91$691&>91(F91* -MN91,V91.^910&952.9546956>958F95:N95^95@&99B.99D699F>99H -MF99JN99LV99N^99P&9=R.9=T69=V>9=XF9=ZN9=\V9=^^9>`&9B".9B$69B& -4>9B(F9B*N9B,V9B.^9B0&9F2J90` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_iso_joliet_rockridge.iso.Z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_iso_joliet_rockridge.iso.Z.uu deleted file mode 100644 index 9f1dd09c7..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_iso_joliet_rockridge.iso.Z.uu +++ /dev/null @@ -1,68 +0,0 @@ -$FreeBSD: head/lib/libarchive/test/test_read_format_iso_joliet_rockridge.iso.Z.uu 201247 2009-12-30 05:59:21Z kientzle $ - -begin 644 test_read_format_iso_joliet_rockridge.iso.Z -M'YV0``(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR -MI,F3*%.J7,FRIO8,.*'4NVK-FS:-.J7//JW/'D"-+GDRYLN7+F#-KWLRY -ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ -MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ -MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$;(44890DQ!!`@01BCA -MA!1***`43S11X88<1G@0+@6!Z-&!``1`XH$((`"`!0590$%"+`HD`@`<%%2C -MB@*I:$0``B10(@D"!'3B@1T6:>212":IY)),-NGDDU!&*>645%9I991-+)'$ -M%$\8,04(6SX!0@XVV`##"TAX"8(123!1Q!193$%%$1H*446;1!0A!0@F@'!A -M$4,\(<6#`K8@Q0M$6$&H%$4$086@(*`P1`H@Q)!##C.`4(0+63Q1A1-'$!&$ -MFY%.6NFE-X"@A`M0-"H%ETZ\L.H40R#1)A-)@'KEKKSN*@.!.<1`(`XQU""# -M##340"`)O\(0[+#%'IOLL@16:^VU!`+0[+,P$&LLLLK"0`*1O99K[KGHIJON -MNNRVZ^Z[\"[YW[R+"2`@@08&9`0`<@!0AK\`"`'`%``0`0`(!R>,\,(*)SQ$ -MP0!(`<`3`#31,,,87YRP02(.A$L)+Q3!T9!"`I`B`!@4A$'*"&DPT(P>%!0S -MC@'IR*./`0!927BQP$ -MUE.#[K3H3V\K;+?1@KNLZ=!^.ZVXV,9>K;;`GNZMM.&.>W"\O/?N^^_`!R_\ -M\,0K2>_QA_US;X$D(N_\\]!'+_WTQ669!`A4H%$'"$^,00>$.%1:@P['ZI`L -M"-LJ((,+!;(?0Q@V9-J"$B"T4$<:9%1:_QGXHP^""P!\01KF\`;J&?"`"$R@ -M`A>X%5QHX$`UVAD`!@"`#@CD0$1(@L08R,$.>O"#(`RA"$=(PA*:\(0HE$SS -M:%2B@%!0(!8,0`8WF,(:VO"&.,RA#G?(PQ[Z\(=`U,^!8B9!`P#@`Q<,"!D` -MD`9^!?&)4(RB%*=(Q2I:\8I8S*(6H;+"F)'(B`)!XH&6V,1^;?&,:$RC&M?( -MQC:Z\8UPC"-[(,%"@MQH(#;KT8^"U$*>#0P*!PB`+]X1,2D4(`"!@`(66!"` -M=GQ.($%HQPL',H`5"HF/`Q%`!`?"`2H8X8$.V)$><]8&!2#@`19H`0E*>!``!!&$%H6I!VW=$,=.6DR/"+H9GO1)4(H29ZLT)2I5R*A@02Q(LUY>,YA]#,``9EC,0R;" -M"4U`P!C3(`=D-O*1`8DD)@4B`$N6:)\!$8`%"=*!:@8@E,#,V3E)J4U7`H`0 -M``A!04(`QH$88*'?%.8"D!"$0>'*"4MPP0YBT,X`O+,)#3@0&L(@!S*P(0UN -M6(,]21&(@02"%``%0#^AF5,!2)0@(3`H0D=)`HQVTY6>B.A$*RJ0BR8TH^ET -M`!.>`*HO*.$)3'#!G+`PTD*Z$YXC.!`;WN"&,[1`#6]X:1GHT`(SI($-96B! -M&\+0AC*X@`YEP`,=W`K7F=94(#?MJ3^C21"?3E2HJ0U6)"@#`XQ^0C2P\ -M#H+1))9(`7!JPD=#VM62-@*>##C0'/+0AI?&U)[M",5`0M&.P0ZVIX^-+&3A -M,04FE(!$'AAK6<^:UC2LM:UOC>M2A.[,$PN48_*S<5^4Y>;%,@=<_1+ -MHG972";Z+FKQ"0!F%N29!"%L)N,;D$Y^\J"*C2YTO5G=!COXP1!N#8!YHP06:VW:?>EV6N]S$+[/-L;*=+66?6F,'`&`. -M`,@#`,A\92`#0,@1#K2@!TWHHPJ"`%74TCUGHP`J6\#*@EL&H*C -MDD!58WO*UIN"T+AU[6YXRQM,>3(WOI.@)S`Y`=BB;D)'LP`"*V"U"DU0=9YH -M)6HH/&K>D"KWN=/M<'I+0>+I8S[K6M\[U -MKGO]ZV`/N]C'3O:RF_WL:$^[VM?.]K:[_>UPC[O^ -M^_WO@`^\X`=/^,(;_O"(3[SB%\_XQCO^\9"/O.0G3_G*6_[RF,^\YC?/^I7S_K6N_[UL(^][&=/^]K;_O:XS[WN=\_[WOO^ -M]\`/OO"'3_SB&__XR$^^\I?/_.8[__G0C[[TIT_]ZEO_^MC/OO:WS_WN>__[ -MX`^_^,=/_O*;__SH3[_ZU\_^]KO__?"/O_SG3__ZV__^^,^__O?/__[[__\` -M&(`".(`$6(`&>(`(F(`*N(`,V(`.^(`0&($2.($46($6>($8F($:N($ -M^($@&((B.((D6((F>((HF((JN((LV((N^((P&(,R.(,T6(,V>(,XF(,ZN(,\ -MV(,^^(-`&(1".(1$6(1&>(1(F(1*N(1,V(1.^(10&(52.(546(56>(58F(5: -MN(5^(5@&(9B.(9D6(9F>(9HF(9JN(9LV(9N^(9P&(=R.(=T6(=V>(=X -MF(=ZN(=\V(=^^(>`&(B".(B$6(B&>(B(F(B*N(B,V(B.^(B0&(F2.(F46(F6 -M>(F8F(F:N(F^(F@&(JB.(JD6(JF>(JHF(JJN(JLV(JN^(JP&(NR.(NT -M6(NV>(NXF(NZN(N\V(N^^(O`&(S".(S$6(S&>(S(F(S*N(S,V(S.^(S0&(W2 -M.(W46(W6>(W8F(W:N(W^(W@&([B.([D6([F>([HF([JN([LV([N^([P -M&(_R.(_T6(_V>(_XF(_ZN(_\V(_^^(\`&9`".9`$69`&>9`(F9`*N9`,V9`. -M^9`0&9$2.9$469$6>9$8F9$:N9$^9$@&9(B.9(D69(F>9(HF9(JN9(L -.V9(N^9(P&9,R.9,T^8(` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_iso_multi_extent.c b/thirdparty/libarchive/libarchive/test/test_read_format_iso_multi_extent.c deleted file mode 100644 index dafbfd38d..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_iso_multi_extent.c +++ /dev/null @@ -1,96 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2009 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_iso_multi_extent.c 201247 2009-12-30 05:59:21Z kientzle $"); - -DEFINE_TEST(test_read_format_iso_multi_extent) -{ - const char *refname = "test_read_format_iso_multi_extent.iso.Z"; - struct archive_entry *ae; - struct archive *a; - const void *p; - size_t size; - int64_t offset; - int i; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualInt(0, archive_read_support_filter_all(a)); - assertEqualInt(0, archive_read_support_format_all(a)); - assertEqualInt(ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Retrieve each of the 2 files on the ISO image and - * verify that each one is what we expect. */ - for (i = 0; i < 2; ++i) { - assertEqualInt(0, archive_read_next_header(a, &ae)); - - if (strcmp(".", archive_entry_pathname(ae)) == 0) { - /* '.' root directory. */ - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(2, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualIntA(a, ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - } else if (strcmp("file", archive_entry_pathname(ae)) == 0) { - /* A regular file. */ - assertEqualString("file", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(262280, archive_entry_size(ae)); - assertEqualInt(0, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt(0, offset); - assertEqualMem(p, "head--head--head", 16); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(1, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - } else { - failure("Saw a file that shouldn't have been there"); - assertEqualString(archive_entry_pathname(ae), ""); - } - } - - /* End of archive. */ - assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE); - - /* Close the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_iso_multi_extent.iso.Z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_iso_multi_extent.iso.Z.uu deleted file mode 100644 index 79100f077..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_iso_multi_extent.iso.Z.uu +++ /dev/null @@ -1,67 +0,0 @@ -$FreeBSD: head/lib/libarchive/test/test_read_format_iso_multi_extent.iso.Z.uu 201247 2009-12-30 05:59:21Z kientzle $ - -begin 644 test_read_format_iso_multi_extent.iso.Z -M'YV0``(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR -MI,F3*%.J7,FRIO8,.*'4NVK-FS:-.J7//JW/'D"-+GDRYLN7+F#-KWLRY -ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ -MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ -MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$;(44890DQ!!`@01BCA -MA!1***`43S11X88<1GB0#0<*%(`-'X48@(D`((````H4I``%"5DPD`@`<%"0 -MC2L*M*(1`0B0```!D"!`0"8>V.&12":IY)),-NGDDU!&*>645%9IY9583LE$ -M$D($(<402"1A11$@)#'%$R#D8(,-,(!@1!),%#%%%E-0482&5TB1A)U29.GG -MGX`&*FB2,A"80PP%WD!@#&PJ"@,)A<)P:**+-DH@"01FJNFF!`(0Z:0Q.,HH -M#(Z28.2@J*:JZJJLMNKJJ[#&*FN5_]6ZF``"+AJB$0#(`4`9OP(@!`!3`$`$ -M`"`@JVRRS"ZK[!#&`B`%`$\`T(2SS6:+K;(&@3C0B"6\4`1'11*9XHHM$J0` -M!@EI,",`'104;XX![=CCCT$."221(6KK[[;_!@SPP`(73/#!!B>,\,(*-\SP -MPPY'#/'$$E=,\<466\P$`$D("T`0T@(`+1(<`V`%`.,FVW&QU2:;`P`DD@B# -MLKQVO/&XQ69!+`!4H&RMLE>$W''/XTZ;,<9('ZUMT@\SK?"GB(9:*:F70DUI -M@98^RNG6F7IJ:-2B9FTJLK.6;?;9:*>M]MILIVWKVX?]DVN!(<)M]]UXYZWW -MWL4EX801:$X1!AT@/#$&X:&"0*`.C.I`*@B?*L!&&F*$(<<8:*1A1QF0NW"# -M"SD0&`8(:O_/+,-^_\\]"#5G>-^T9O_?789Z_]]MQW[_WWX(>O]X'Q#B_^ -M^>BGK_[Z[+?O_OOPQR__5]/'._W\^.>O__[\]^___P`,H`#S`PGJ$01'`[&7 -MCX`DI.&=B%A0.$``?/$.:4FA``$(!!2PP((`M`%D`@E"&_0U$`'<#T@D%(@` -MA#<0#E#!"!H(@`-XM,`@T1!?)&B#`B(```@<@`1#*`('`N"!@A31(.TH2#O< -M8,`6IBB!"+H7`_55I`!(X8(9W&`'/S@0$:8P("8L2(\*LL(;O3"&,Y2B#=68 -MPQWV\(<`X`,`/E`0.N+#1/B(8@U)``@''N!-<7+!#F)P10PFP@E-2,"!S)"& -MU&DQ2($82"#&1I`'5O*+`!``'0GR@3/*\(8,!&60=,A#'Y)`CEXH2"KO2*0\ -MBI*/?@1D$01)2"P>,I&+;&09'DF"2`IDDB>TY+> -M$@"=*$@G$`&!@4``$:\4$9'^"*=9#K*0`;BE(@'`2$=R$)*2I.2W@DG,:!*D -M$\E\)3/=:,H!VO.>^'P+C,(0GL`$KV+("DD@@IQ`,(4J0`$*3Y`" -M%=P45Z\^80I)P(*;NLE6.ME)0U.XTU:ID(0A3`$*<0I"8$$P5B=0(0A#F"L1 -MS#0$KU9!"%N:@E/[!+@^';8(0TC"FX;`U"0\P0EL?4(5OC1+"`663%"X;&8W -M6R:U.E:T2?!IF5#[U20TP4M9`($5R%J%)I!)K5,8@E'#RMFZ-O:QD=UM9W]+ -MV-.Z@*?8S:YVM]L7-)0A#&1H00N\"U[QDC>\X_TN>L]K7O6&X;WPC:]\YTO? -M^7+WOOC-KW[WR]_^^O>_``ZP@`=,X`(;^,`(3K""%\S@!COXP1".L(0G3.$* -M6_C"&,ZPAC?,X0Y[^,,@#K&(1TSB$IOXQ"A.L8I7S.(6N_C%,(ZQC&=,XQK; -M^,8XSK&.=\SC'OOXQT`.LI"'3.0B&_G(2$ZRDI?,Y"8[^_G+8`ZSF,=,YC*;^,ZSGO?,YS[[^<^`#K2@!TWH0AOZT(A.M*(7S>A&._K1D(ZTI"=-Z4I;^M*8 -MSK2F-\WI3GOZTZ`.M:A'3>I2F_K4J$ZUJE?-ZE:[^M6PCK6L9TWK6MOZUKC. -MM:YWS>M>^_K7P`ZVL(=-[&(;^]C(3K:RE\WL9CO[V=".MK2G3>UJ6_O:V,ZV -MMK?-[6Y[^]O@#K>XQTWNYVN_O=\(ZWO.=-[WK;^][XSK>^ -M]\WO?OO[WP`/N,`'3O""&_S@"$^XPA?.\(8[_.$0C[C$)T[QBEO\XAC/N,8W -MSO&.>_SC(`^YR$=.\I*;_.0H3[G*5\[REKO\Y3"/NI8S[K6M\[U -MKGO]ZV`/N]C'3O:RF_WL:$^[VM?.]K:[_>UPC[O^ -M^_WO@`^\X`=/^,(;_O"(3[SB%\_XQCO^\9"/O.0G3_G*6_[RF,^\YC?/^I7S_K6N_[UL(^][&=/^]K;_O:XS[WN=\_[WOO^ -M]\`/?FOJ2_SBTY<.86BD>)&O_!8PGPW+3S[TG2_]Z#=2^-C/OO:WS_WN>__[ -MX`^_^,=/_O*;__SH3[_ZU\_^]KO__?"/O_SG3__ZV__^^,^__O?/__[[__\` -M&(`".(`$6(`&>(`(F(`*N(`,V(`.^(`0&($2.($46($6>($8F($:N($ -M^($@&((B.((D6((F>((HF((JN((LV((N^((P&(,R.(,T6(,V>(,XF(,ZN(,\ -MV(,^^(-`&(1".(1$6(1&>(1(F(1*N(1,V(1.^(10&(52.(546(56>(58F(5: -MN(5^(5@&(9B.(9D6(9F>(9HF(9JN(9LV(9N^(9P&(=R.(=T6(=V>(=X -MF(=ZN(=\V(=^^(>`&(B".(B$6(B&>(B(F(B*N(B,V(B.^(B0&(F2.(F46(F6 -M>(F8F(F:N(F^(F@&(JB.(JD6(JF>(JHF(JJN(JLV(JN^(JP&(NR.(NT -M6(NV>(NXF(NZN(N\V(N^^(O`&(S".(S$6(S&>(S(F(S*N(S,V(S.^(S0&(W2 -M.(W46(W6>(W8F(W:N(W^(W@&([B.([D6([F>([HF([JN([LV([N^([P -M&(_R.(_T6(_V>(_XF(_ZN(_\V(_^^(\`&9`".9`$69`&>9`(F9`*N9`,V9`. -0^9`0&9$2.9$469$6>9%O"``` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_iso_rockridge.iso.Z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_iso_rockridge.iso.Z.uu deleted file mode 100644 index 5f06cb3ab..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_iso_rockridge.iso.Z.uu +++ /dev/null @@ -1,206 +0,0 @@ -$FreeBSD: head/lib/libarchive/test/test_read_format_iso_rockridge.iso.Z.uu 201247 2009-12-30 05:59:21Z kientzle $ - -begin 644 test_read_format_iso_rockridge.iso.Z -M'YV0``(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR -MI,F3*%.J7,FRIO8,.*'4NVK-FS:-.J7//JW/'D"-+GDRYLN7+F#-KWLRY -ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ -MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ -MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$;(44890DQ!!`@01BCA -MA!1***`43S11X88<1GA0#Q@,A$$/'QT(0``F'H@``@!84)`%$R14P4`B`'!! -M03>R*!"+1@0@0`(GDB!`0"D>V.&12":IY)),-NGDDU!&*>645%9IY9583MG$ -M$DE,\8014X#0Y1,@Y&"##3"\@`28(!B1!!-%3)'%%%04H:$05;Q)1!%2@&`" -M"!<6,<034CPH8`M2O$"$%89*44005!`*`@I#I`!"##GD,`,(1;B0Q1-5.'$$ -M$4'`.6FEEV9Z`PA*N`#%HU)XZ<0+K4XQ!!)O,I&$J%GVZFNO,A"8`PPYR'`# -MIC'4,$.P,)#`[+#%'IM#LLL22`*!V&:K+8$`/$NLL<@JRRP)1OYJ[KGHIJON -MNNRVZ^Z[\,;;Y'_T+O:/@`0:6.^^_/;K[[\`5[=E$B!,48<;!9-B(TX`J!C0#SZ"&0`0NY\XH%30'%` -M`+Z\`X`44A000"!08$%N.T$,%$0[5P\TP-0"^5B0`%08H4$`#O3X8Y!M)+#! -M!`^`0$+GGX=.PA!%2)1*((N."$&QX` -MXHHS7M#C!4E.$.668Z[YW*-[#KKHI$]/`@!P^%Q0B&^[C:#<0>Z>X@!;_QY` -M(DXT@<"!9*0A1^&')R[0XKL/)`#D1-8O$/.79PX^W<_CG/1,!P`Z`$`#!=$` -M%<+`BX#P(@R5^]_U[!:``[@)3B[800S,A[XF).!`9D@#&\H`OP"0(A`#"00I -M]!>0^R6/A0#@G_,D&$"Z5<]T?#A@`A?80``\,(*YFR#O3K0`)`2A4+IRPA(R -MN,'`G2]]#3@0&L(@!S*P(0UN6$,)3YC"%4X.?R>"H0S]%\0:1J]THC,$`$ZA -M,ZJ=XB!FC!R1%""G)B1QB1K\FQ,;D3X&'&@.>6C#%;-8PG:$8B"A:`<84?3" -MR4V!"0LP$0%".,+*]:]'`P"2`$B`24V>T7IK8^-`+O!&@]Q0='(D8AWO*`,F -MFH^/38@B```I2"RN00:%/*1`$KG(18KQD7[T'@`&0(X3B'P,YR#7,()>(5&3R?.E()CA` -M10$AIC$)``!D.D"9^!R@Z!CQS%%*DR#*3&4`MID%.W:3!N`4'"QE20Z#G,8AZS>??4YS*I)U)']%,@I(2C!`5*4(,JL08) -M#`&8'3:KAU7MFY.O= -M`F"^X,6O>(WC65D-"U(S)I:``(3JM`$V^[)5JZ%0J3Z*ZGWQG>^&?:O%#I\W@.[ -MP+0XSK&.=QPS-)2!#6QX@P)X3.0B&_G(2$ZRDI?,Y"8[^_G+8`ZSF,=,YC*;^,ZSGO?,YS[[^<^`#K2@!TWH0AOZT(A.M*(7S>A&._K1D(ZTI"=-Z4I;^M*8 -MSK2F-\WI3GOZTZ`.M:A'3>I2F_K4J$ZUJE?-ZE:[^M6PCK6L9TWK6MOZUKC. -MM:YWS>M>^_K7P`ZVL(=-[&(;^]C(3K:RE\WL9CO[V=".MK2G3>UJ6_O:V,ZV -MMK?-[6Y[^]O@#K>XQTWNYVN_O=\(ZWO.=-[WK;^][XSK>^ -M]\WO?OO[WP`/N,`'3O""&_S@"$^XPA?.\(8[_.$0C[C$)T[QBEO\XAC/N,8W -MSO&.>_SC(`^YR$=.\I*;_.0H3[G*5\[REKO\Y3"/NI8S[K6M\[U -MKGO]ZV`/N]C'3O:RF_WL:$^[VM?.]K:[_>UPC[O^ -M^_WO@`^\X`=/^,(;_O"(3[SB%\_XQCO^\9"/O.0G3_G*6_[RF,^\YC?/^I7S_K6N_[UL(^][&=/^]K;_O:XS[WN=\_[WOO^ -M]\`/OO"'3_SB&__XR$^^\I?/_.8[__G0C[[TIT_]ZEO_^MC/OO:WS_WN>__[ -MX`^_^,=/_O*;__SH3[_ZU\_^]KO__?"/O_SG3__ZV__^^,^__O?/__[[__\` -M&(`".(`$6(`&>(`(F(`*N(`,V(`.^(`0&($2.($46($6>($8F($:N($ -M^($@&((B.((D6((F>((HF((JN((LV((N^((P&(,R.(,T6(,V>(,XF(,ZN(,\ -MV(,^^(-`&(1".(1$6(1&>(1(F(1*N(1,V(1.^(10&(52.(546(56>(58F(5: -MN(5^(5@&(9B.(9D6(9F>(9HF(9JN(9LV(9N^(9P&(=R.(=T6(=V>(=X -MF(=ZN(=\V(=^^(>`&(B".(B$6(B&>(B(F(B*N(B,V(B.^(B0&(F2.(F46(F6 -M>(F8F(F:N(F^(F@&(JB.(JD6(JF>(JHF(JJN(JLV(JN^(JP&(NR.(NT -M6(NV>(NXF(NZN(N\V(N^^(O`&(S".(S$6(S&>(S(F(S*N(S,V(S.^(S0&(W2 -M.(W46(W6>(W8F(W:N(W^(W@&([B.([D6([F>([HF([JN([LV([N^([P -M&(_R.(_T6(_V>(_XF(_ZN(_\V(_^^(\`&9`".9`$69`&>9`(F9`*N9`,V9`. -M^9`0&9$2.9$469$6>9$8F9$:N9$^9$@&9(B.9(D69(F>9(HF9(JN9(L -MV9(N^9(P&9,R.9,T69,V>9,XF9,ZN9,\V9,^^9-`&91".91$691&>91(F91* -MN91,V91.^910&952.9546956>958F95:N95^95@&99B.99D699F>99H -MF99JN99LV99N^99P&9=R.9=T69=V>9=XF9=ZN9=\V9=^^9>`&9B".9B$69B& -M>9B(F9B*N9B,V9B.^9B0&9F2.9F469F6>9F8F9F:N9F^9F@&9JB.9JD -M69JF>9JHF9JJN9JLV9JN^9JP&9NR.9NT69NV>9NXF9NZN9N\V9N^^9O`&9S" -M.9S$69S&>9S(F9S*N9S,V9S.^9S0&9W2.9W469W6>9W8F9W:N9W^9W@ -M&9[B.9[D69[F>9[HF9[JN9[LV9[N^9[P&9_R.9_T69_V>9_XF9_ZN9_\V9_^ -M^9\`&J`".J`$6J`&>J`(FJ`*NJ`,VJ`.^J`0&J$2.J$46J$6>J$8FJ$:NJ$< -MVJ$>^J$@&J(B.J(D6J(F>J(HFJ(JNJ(LVJ(N^J(P&J,R.J,T6J,V>J,XFJ,Z -MNJ,\VJ,^^J-`&J1".J1$6J1&>J1(FJ1*NJ1,VJ1.^J10&J52.J546J56>J58 -MFJ5:NJ5^J5@&J9B.J9D6J9F>J9HFJ9JNJ9LVJ9N^J9P&J=R.J=T6J=V -M>J=XFJ=ZNJ=\VJ=^^J>`&JB".JB$6JB&>JB(FJB*NJB,VJB.^JB0&JF2.JF4 -M6JF6>JF8FJF:NJF^JF@&JJB.JJD6JJF>JJHFJJJNJJLVJJN^JJP&JNR -M.JNT6JNV>JNXFJNZNJN\VJN^^JO`&JS".JS$6JS&>JS(FJS*NJS,VJS.^JS0 -M&JW2.JW46JW6>JW8FJW:NJW^JW@&J[B.J[D6J[F>J[HFJ[JNJ[LVJ[N -M^J[P&J_R.J_T6J_V>J_XFJ_ZNJ_\VJ_^^J\`&[`".[`$6[`&>[`(F[`*N[`, -MV[`.^[`0&[$2.[$46[$6>[$8F[$:N[$^[$@&[(B.[(D6[(F>[(HF[(J -MN[(LV[(N^[(P&[,R.[,T6[,V>[,XF[,ZN[,\V[,^^[-`&[1".[1$6[1&>[1( -MF[1*N[1,V[1.^[10&[52.[546[56>[58F[5:N[5^[5@&[9B.[9D6[9F -M>[9HF[9JN[9LV[9N^[9P&[=R.[=T6[=V>[=XF[=ZN[=\V[=^^[>`&[B".[B$ -M6[B&>[B(F[B*N[B,V[B.^[B0&[F2.[F46[F6>[F8F[F:N[F^[F@&[JB -M.[JD6[JF>[JHF[JJN[JLV[JN^[JP&[NR.[NT6[NV>[NXF[NZN[N\V[N^^[O` -M&[S".[S$6[S&>[S(F[S*N[S,V[S.^[S0&[W2.[W46[W6>[W8F[W:N[W -M^[W@&[[B.[[D6[[F>[[HF[[JN[[LV[[N^[[P&[_R.[_T6[_V>[_XF[_ZN[_\ -MV[_^^[\`',`"/,`$7,`&?,`(G,`*O,`,W,`._,`0',$2/,$47,$6?,$8G,$: -MO,$_,$@',(B/,(D7,(F?,(HG,(JO,(LW,(N_,(P',,R/,,T7,,V?,,X -MG,,ZO,,\W,,^_,-`',1"/,1$7,1&?,1(G,1*O,1,W,1._,10',52/,547,56 -M?,58G,5:O,5_,5@',9B/,9D7,9F?,9HG,9JO,9LW,9N_,9P',=R/,=T -M7,=V?,=XG,=ZO,=\W,=^_,>`',B"/,B$7,B&?,B(G,B*O,B,W,B._,B0',F2 -M/,F47,F6?,F8G,F:O,F_,F@',JB/,JD7,JF?,JHG,JJO,JLW,JN_,JP -M',NR/,NT7,NV?,NXG,NZO,N\W,N^_,O`',S"/,S$7,S&?,S(G,S*O,S,W,S. -M_,S0',W2/,W47,W6?,W8G,W:O,W_,W@',[B/,[D7,[F?,[HG,[JO,[L -MW,[N_,[P',_R/,_T7,_V?,_XG,_ZO,_\W,_^_,\`'=`"/=`$7=`&?=`(G=`* -MO=`,W=`._=`0'=$2/=$47=$6?=$8G=$:O=$_=$@'=(B/=(D7=(F?=(H -MG=(JO=(LW=(N_=(P'=,R/=,T7=,V?=,XG=,ZO=,\W=,^_=-`'=1"/=1$7=1& -M?=1(G=1*O=1,W=1._=10'=52/=547=56?=58G=5:O=5_=5@'=9B/=9D -M7=9F?=9HG=9JO=9LW=9N_=9P'==R/==T7==V?==XG==ZO==\W==^_=>`'=B" -M/=B$7=B&?=B(G=B*O=B,W=B._=B0'=F2/=F47=F6?=F8G=F:O=F_=F@ -M'=JB/=JD7=JF?=JHG=JJO=JLW=JN_=JP'=NR/=NT7=NV?=NXG=NZO=N\W=N^ -M_=O`'=S"/=S$7=S&?=S(G=S*O=S,W=S._=S0'=W2/=W47=W6?=W8G=W:O=W< -MW=W>_=W@'=[B/=[D7=[F?=[HG=[JO=[LW=[N_=[P'=_R/=_T7=_V?=_XG=_Z -MO=_\W=_^_=\`'N`"/N`$7N`&?N`(GN`*ON`,WN`._N`0'N$2/N$47N$6?N$8 -MGN$:ON$_N$@'N(B/N(D7N(F?N(HGN(JON(LWN(N_N(P'N,R/N,T7N,V -M?N,XGN,ZON,\WN,^_N-`'N1"/N1$7N1&?N1(GN1*ON1,WN1._N10'N52/N54 -M7N56?N58GN5:ON5_N5@'N9B/N9D7N9F?N9HGN9JON9LWN9N_N9P'N=R -M/N=T7N=V?N=XGN=ZON=\WN=^_N>`'NB"/NB$7NB&?NB(GNB*ONB,WNB._NB0 -M'NF2/NF47NF6?NF8GNF:ONF_NF@'NJB/NJD7NJF?NJHGNJJONJLWNJN -M_NJP'NNR/NNT7NNV?NNXGNNZONN\WNN^_NO`'NS"/NS$7NS&?NS(GNS*ONS, -MWNS._NS0'NW2/NW47NW6?NW8GNW:ONW_NW@'N[B/N[D7N[F?N[HGN[J -MON[LWN[N_N[P'N_R/N_T7N_V?N_XGN_ZON_\WN_^_N\`'_`"/_`$7_`&?_`( -MG_`*O_`,W_`.__`0'_$2/_$47_$6?_$8G_$:O_$__$@'_(B/_(D7_(F -M?_(HG_(JO_(LW_(N__(P'_,R/_,T7_,V?_,XG_,ZO_,\W_,^__-`'_1"/_1$ -M7_1&?_1(G_1*O_1,W_1.__10'_52/_547_56?_58G_5:O_5__5@'_9B -M/_9D7_9F?_9HG_9JO_9LW_9N__9P'_=R/_=T7_=V?_=XG_=ZO_=\W_=^__>` -M'_B"/_B$7_B&?_B(G_B*O_B,W_B.__B0'_F2/_F47_F6?_F8G_F:O_F -M__F@'_JB/_JD7_JF?_JHG_JJO_JLW_JN__JP'_NR/_NT7_NV?_NXG_NZO_N\ -MW_N^__O`'_S"/_S$7_S&?_S(G_S*O_S,W_S.__S0'_W2/_W47_W6?_W8G_W: -MO_W__W@'_[B/_[D7_[F?_[HG_[JO_[LW_[N__[P'__R/__T7__V?__X -MG__ZO__\W__^__\`,``*P`%(``N@`3R`"#`!*L`%R``;H`-\@!`P`DK`"4@! -M*Z`%O(`8,`-JP`W(`3N@!_R`(#`$BL`12`)+H`D\@2@P!:K`%<@"6Z`+?($P -M,`;*P!E(`VN@#;R!.#`'ZL`=R`-[H`_\@4`P"`K!(4@$BZ`1/()(,`DJP27( -M!)N@$WR"4#`*2L$I2`6KH!6\@E@P"VK!+<@%NZ`7_()@,`R*P3%(!LN@&3R# -M:#`-JL$UR`;;H!M\@W`P#LK!.4@'ZZ`=O(-X,`_JP3W(!_N@'_R#@#`0"L)! -M2`@+H2$\A(@P$2K"1<@(&Z$C?(20,!)*PDE("2NA);R$F#`3:L)-R`D[H2?\ -MA*`P%(K"44@*2Z$I/(6H,!6JPE7("ENA*WR%L#`6RL)92`MKH2V\A;@P%^K" -M7<@+>Z$O_(7`,!@*PV%(#(NA,3R&R#`9*L-ER`R;H3-\AM`P&DK#:4@-JZ$U -MO(;8,!MJPVW(#;NA-_R&X#`3R/Z#$]JL?U -MR![;HWM\C_`Q/LK'^4@?ZZ-]O(_X,3_JQ_W('_NC?_R/`#)`"L@!22`+I($\ -MD`@R02K(!Z2/ -M_)%`,D@*R2%))(NDD3R22#))*LDER22;I)-\DE`R2DK)*4DEJZ25O))8,DMJ -MR2W));NDE_R28#),BLDQ22;+I)D\DV@R3:K)-#)/ZLD]R2?[I)_\DX`R4`K*04DH"Z6A/)2(,E$JRD7)*!NEHWR4D#)2 -M2LI)22DKI:6\E)@R4VK*3RLMY22_KI;V\E_@R7^K+?Z?O_)W`,W@* -MS^%)/(NG\3R>R#-Y*L_ER3R;I_-\GM`S>DK/Z4D]JZ?UO)[8,WMJS^W)/;NG -M]_R>X#-\BL_Q23[+I_D\G^@S?:K/]4I/ZZD]O:?X-)_JTWW*3_NI/_VG`#6@"M2!2E`+JD$]J`@UH2K4AZI/_:E`-:@*U:%*5(NJ -M43VJ2#6I*M6ERE2;JE-]JE`UJDK5J4I5JZI5O:I8-:MJU:W*5;NJ5_VJ8#6L -MBM6Q2E;+JED]JV@UK:K5M#6OZM6]RE?[ -MJE_]JX`UL`K6P4I8"ZMA/:R(-;$JUL7*6!NK8WVLD#6R2M;)2EDKJV6]K)@U -MLVK6SRZMY/:_H-;VJU_7* -M7MNK>WVO\#6^RM?Y2E_KJWV]K_@UO^K7_ZVO_;7`-M@*VV%+;(NML3VVR#;9 -M*MMERVR;K;-]MM`VVDK;:4MMJZVUO;;8-MMJVVW+;;NMM_VVX#;`NOX3V\B#?Q*M[% -MRW@;K^-]O)`W\DK>R4MY*Z_EO;R8-_-JWLW+>3NOY_V\H#?TBM[12WI+K^D] -MO:@W]:K>UVNO[;V]N#?WZM[=RWM[K^_]O<`W^`K? -MX4M\BZ_Q/;[(-_DJW^7+?)NO\WV^T#?Z2M_I2WVKK_6]OM@W^VK?[[`/_L%`.`@+X2%,A(NP$3["2#@)*^$ES(2; -ML!-^PE`X"DOA*4R%J[`5OL)8.`MKX2W,A;NP%_["8#@,B^$Q3(;+L!D^PV@X -M#:OA-#@/Z^$]S(?[L!_^PX`X$`OB04R( -M"[$A/L2(.!$KXD7,B!NQ(W[$D#@22^))3(DKL26^Q)@X$VOB3/($.*'$FR -MI,F3*%.J7,FRIO8,.*'4NVK-FS:-.J7//JW/'D"-+GDRYLN7+F#-KWLRY -ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ -MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ -MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$;(44890DQ!!`@01BCA -MA!1***`43S11X88<1GC0+06!Z-&!``1`XH$((`"`!059,$%"%0PD`@`7%%2C -MB@*I:$0``B10(@D"!'3B@1T6:>212":IY)),-NGDDU!&*>645%9I991-+)'$ -M%$\8,04(6SX!0@XVV`##"TAX"8(123!1Q!193$%%$1H*446;1!0A!0@F@'!A -M$4,\(<6#`K8@Q0M$6$&H%$4$086@(*`P1`H@Q)!##C.`4(0+63Q1A1-'$!&$ -MFY%.6NFE-X"@A`M0-"H%ETZ\L.H40R#1)A-)@'KEKKSN*@.!.<10H`PQR%## -MKV;"0,*O,`0[;+''PI`L"016:^VU!`+`K+/%0HLL@200V>NXY)9K[KGHIJON -MNNRVZ^Z2_\6[V#\"$FB@O/CFJ^^^_/9;799)@-#$&VZ`\,08=%0J@\(Z'*N# -MM"!LJX`,+A18<0QAV)"IH2"T4$<:9%3:\1D@1PR""RB_D,8<;_CK\LLPQRSS -MS&G=0L^!-0HIT```9"#0@40D(07-1!=M]-%()ZWTTDPW[?334+]&8D`UDLBS -M0#X'$/3047?M]==@ARWVV&27;?;9:"<-"8TV`H!C0#KRZ&,`0.I,&VP3=.%#EQSHAT0^3IKJL!'X2\"!YI"'-L3`CH@+Q4!"T0X_ -MFJ@@/"J(`"(Y24G"8PI,$(.)`K`%*_KREV'`(@3I41!Z=*$@77CD.VHI2;\9 -MY)+KTV06FD"Q^=4/E$T0)0!(V089H+(=JA0(*UWI2D`"0`#+9.8[<*E+$_42 -MF/"4HC`)@L/(!<\+!?'"(]W!S'^XPY)IQ*0TFS`#3PH.F]KDY@R^&!``40E*0(QD$"0@IRP -M-*<`P$>0#1B2>KTC@2*UISK\+0"E_U,I2P7B4I@2)):4NR!!.G!31>Z4D:8# -M`/X4`-3^";6E+X5H3&4)1()\H*EI?&KJ3(?+(9"(!QJ5(5@'X",!+'*L;]T> -M`'!)!!+U(*UJU=PA`\#6<\95=3PEJYM(Y`.\YG5Z.^JK6P/[UZB2]+&0C:QD -M$W*[00ZDC+M#8TY_)Z0#U8]X=SQ>0!@GTXA2SK)8`VM.&*B1A"'ES4Q"FP-U` -M.8$*01B"?X-&*_E600BXFL)V]V0$2.4-4$E@TQ`+ISB).@)3"]N;Q*:$`0I9`$$5G@"$ZK0!.[FB592J.ZC2`PI"V-8 -MPT`NL12([&`7NZ"Y8`ZSF,>L'S24@0UL>$.E:C`#!9#YS7".LYSG3.,[S>\R,9C7'X%ANUK.@!TWH0AOZT(A.M*(7S6BO\#G-:XY!H!M-Z4I;^M*8 -MSK2F-\WI3GOZTZ`.M:A'3>I2F_K4J$ZUJE?-ZE:[^M6PCK6L9TWK6MOZUKC. -MM:YWS>M>^_K7P`ZVL(=-[&(;^]C(3K:RE\WL9CO[V=".MK2G3>UJ6_O:V,ZV -MMK?-[6Y[^]O@#K>XQTWNYVN_O=\(ZWO.=-[WK;^][XSK>^ -M]\WO?OO[WP`/N,`'3O""&_S@"$^XPA?.\(8[_.$0C[C$)T[QBEO\XAC/N,8W -MSO&.>_SC(`^YR$=.\I*;_.0H3[G*5\[REKO\Y3"/NI8S[K6M\[U -MKGO]ZV`/N]C'3O:RF_WL:$^[VM?.]K:[_>UPC[O^ -M^_WO@`^\X`=/^,(;_O"(3[SB%\_XQCO^\9"/O.0G3_G*6_[RF,^\YC?/^I7S_K6N_[UL(^][&=/^]K;_O:XS[WN=\_[WOO^ -M]\`/OO"'3_SB&__XR$^^\I?/_.8[__G0C[[TIT_]ZEO_^MC/OO:WS_WN>__[ -MX`^_^,=/_O*;__SH3[_ZU\_^]KO__?"/O_SG3__ZV__^^,^__O?/__[[__\` -M&(`".(`$6(`&>(`(F(`*N(`,V(`.^(`0&($2.($46($6>($8F($:N($ -M^($@&((B.((D6((F>((HF((JN((LV((N^((P&(,R.(,T6(,V>(,XF(,ZN(,\ -MV(,^^(-`&(1".(1$6(1&>(1(F(1*N(1,V(1.^(10&(52.(546(56>(58F(5: -MN(5^(5@&(9B.(9D6(9F>(9HF(9JN(9LV(9N^(9P&(=R.(=T6(=V>(=X -MF(=ZN(=\V(=^^(>`&(B".(B$6(B&>(B(F(B*N(B,V(B.^(B0&(F2.(F46(F6 -(>(F8F(F:^!,` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_iso_rockridge_new.iso.Z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_iso_rockridge_new.iso.Z.uu deleted file mode 100644 index 3ef253b5b..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_iso_rockridge_new.iso.Z.uu +++ /dev/null @@ -1,208 +0,0 @@ -$FreeBSD: head/lib/libarchive/test/test_read_format_iso_rockridge_new.iso.Z.uu 201247 2009-12-30 05:59:21Z kientzle $ - -begin 644 test_read_format_iso_rockridge_new.iso.Z -M'YV0``(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR -MI,F3*%.J7,FRIO8,.*'4NVK-FS:-.J7//JW/'D"-+GDRYLN7+F#-KWLRY -ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ -MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ -MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$;(44890DQ!!`@01BCA -MA!1***`43S11X88<1GA0#Q@,A$$/'QT(0``F'H@``@!84)`%$R14P4`B`'!! -M03>R*!"+1@0@0`(GDB!`0"D>V.&12":IY)),-NGDDU!&*>645%9IY9583MG$ -M$DE,\8014X#0Y1,@Y&"##3"\@`28(!B1!!-%3)'%%%04H:$05;Q)1!%2@&`" -M"!<6,<034CPH8`M2O$"$%89*44005!`*`@I#I`!"##GD,`,(1;B0Q1-5.'$$ -M$4'`.6FEEV9Z`PA*N`#%HU)XZ<0+K4XQ!!)O,I&$J%GVZFNO,A"8`PPYR'"# -M##/$,,.R!)(0++'$&HNLLLS"0`*!V&:K+8$`/#MLL<M]MI,0V(CC@#H&!"//@(9@)`^GWC@ -M%%`<$(`O[P`@A10%!!`(%%BP$$`[00P41#M:#S2`U0+Y6)``/0]T`15&:!"` -M`SW^&&0;"6QP00,AD$"ZZ:B3,$01'`2004&S&]1.0>VX\39!.0Y$M^AW#WDB -MD2@.7OCAB2_>N$"/1_XSY40*/Q#F.'+N.>AUCU[ZZ:FOSCT)`.`1=$$ARATW -M@MD'GW<``WAM?`").-$$`@>2D88B1:`A"`42E=.6`()34@X^,FO`0="0QCD0`8VI,$-:X"A#&EH -MP\L%<(?3\^%`@'@](C+0@T9,G2,``(]_^/&/\#B('2M')`7(J0E8U&()!=?% -M1LB/`0>:0Q[:8$8TPK`=H1A(*-KQQC?>4`!]_*,?X3$%)BS`1`1@H0L1B+T! -M`$D`=W0E#E6WO=9)`@#O$*4?`V<0(X(@BBE:P"$3B;$2OL^130`C`"1)R3.N -M00:7S*1`-ME)'7XRE[I\1RD=H**`#(`.;8!#0%B91UH^T)S?HP0`W*'+?[CC -M(*3#@`,*<`)@$DF864#DKI8P@RT>\XN1G&0EUS"#:&J2DSKTY.78J4MWE!(" -MW03`-\-)`(&0LY;=PR@Z6V<)`+2CG;?K92U_2<@I#G.?-/!G(P&Z3($ZDP8& -MG29""8(B:U[NH[IL1RDE<*"*#JFB$@6G.`%PT7.6LYP=94<[V2%(#Y8T`/C4 -M9Q9KH-+"(5.9S!QH#6(:$&HFU*8\5*HNV5'*"!SHAJEL81E8V2-9PK*MK]PH -M!#NZCG:N`YX)D"<][6G2?";2!E4-P%4#VDPTVH"K`/`J317*P[KJA$ -MAPI4H@;1`4?5:#G9AA[=&7!KY]L1^J`HO"(Q\GB77%Y`'O=)QD[OLP'!`%OQ -MJ%F-`D!WF1-([T1KQ](2+P#O0Y[^5`N`YA5DHVA$^<5``5#@%<*20!"E_`5`YB`"DD%`$$&!K"$M";!"(>5$YWL9#`[ -MU9<*21@"W^`4A"F<=U!.H$(0AH!@HMFJOU40@JZF8-X^&4%2?!-4$MPT!$@E -MX0E.,!BHYMLI"'GXOBE><8O%M*<0SS@)?!)3CO&;A"98,0L@L,(3F%"%)IQW -M3[;R+A0BY6))@5C$)%;RBZ7@9`SCV`763;.:U\SFFZ&A#&Q@PQL4T.8ZV_G. -M>,ZSGO?,YS[[^<^`#K2@!TWH0AOZT(A.M*(7S>A&._K1D(ZTI"=-Z4I;^M*8 -MSK2F-\WI3GOZTZ`.M:A'3>I2F_K4J$ZUJE?-ZE:[^M6PCK6L9TWK6MOZUKC. -MM:YWS>M>^_K7P`ZVL(=-[&(;^]C(3K:RE\WL9CO[V=".MK2G3>UJ6_O:V,ZV -MMK?-[6Y[^]O@#K>XQTWNYVN_O=\(ZWO.=-[WK;^][XSK>^ -M]\WO?OO[WP`/N,`'3O""&_S@"$^XPA?.\(8[_.$0C[C$)T[QBEO\XAC/N,8W -MSO&.>_SC(`^YR$=.\I*;_.0H3[G*5\[REKO\Y3"/NI8S[K6M\[U -MKGO]ZV`/N]C'3O:RF_WL:$^[VM?.]K:[_>UPC[O^ -M^_WO@`^\X`=/^,(;_O"(3[SB%\_XQCO^\9"/O.0G3_G*6_[RF,^\YC?/^I7S_K6N_[UL(^][&=/^]K;_O:XS[WN=\_[WOO^ -M]\`/OO"'3_SB&__XR$^^\I?/_.8[__G0C[[TIT_]ZEO_^MC/OO:WS_WN>__[ -MX`^_^,=/_O*;__SH3[_ZU\_^]KO__?"/O_SG3__ZV__^^,^__O?/__[[__\` -M&(`".(`$6(`&>(`(F(`*N(`,V(`.^(`0&($2.($46($6>($8F($:N($ -M^($@&((B.((D6((F>((HF((JN((LV((N^((P&(,R.(,T6(,V>(,XF(,ZN(,\ -MV(,^^(-`&(1".(1$6(1&>(1(F(1*N(1,V(1.^(10&(52.(546(56>(58F(5: -MN(5^(5@&(9B.(9D6(9F>(9HF(9JN(9LV(9N^(9P&(=R.(=T6(=V>(=X -MF(=ZN(=\V(=^^(>`&(B".(B$6(B&>(B(F(B*N(B,V(B.^(B0&(F2.(F46(F6 -M>(F8F(F:N(F^(F@&(JB.(JD6(JF>(JHF(JJN(JLV(JN^(JP&(NR.(NT -M6(NV>(NXF(NZN(N\V(N^^(O`&(S".(S$6(S&>(S(F(S*N(S,V(S.^(S0&(W2 -M.(W46(W6>(W8F(W:N(W^(W@&([B.([D6([F>([HF([JN([LV([N^([P -M&(_R.(_T6(_V>(_XF(_ZN(_\V(_^^(\`&9`".9`$69`&>9`(F9`*N9`,V9`. -M^9`0&9$2.9$469$6>9$8F9$:N9$^9$@&9(B.9(D69(F>9(HF9(JN9(L -MV9(N^9(P&9,R.9,T69,V>9,XF9,ZN9,\V9,^^9-`&91".91$691&>91(F91* -MN91,V91.^910&952.9546956>958F95:N95^95@&99B.99D699F>99H -MF99JN99LV99N^99P&9=R.9=T69=V>9=XF9=ZN9=\V9=^^9>`&9B".9B$69B& -M>9B(F9B*N9B,V9B.^9B0&9F2.9F469F6>9F8F9F:N9F^9F@&9JB.9JD -M69JF>9JHF9JJN9JLV9JN^9JP&9NR.9NT69NV>9NXF9NZN9N\V9N^^9O`&9S" -M.9S$69S&>9S(F9S*N9S,V9S.^9S0&9W2.9W469W6>9W8F9W:N9W^9W@ -M&9[B.9[D69[F>9[HF9[JN9[LV9[N^9[P&9_R.9_T69_V>9_XF9_ZN9_\V9_^ -M^9\`&J`".J`$6J`&>J`(FJ`*NJ`,VJ`.^J`0&J$2.J$46J$6>J$8FJ$:NJ$< -MVJ$>^J$@&J(B.J(D6J(F>J(HFJ(JNJ(LVJ(N^J(P&J,R.J,T6J,V>J,XFJ,Z -MNJ,\VJ,^^J-`&J1".J1$6J1&>J1(FJ1*NJ1,VJ1.^J10&J52.J546J56>J58 -MFJ5:NJ5^J5@&J9B.J9D6J9F>J9HFJ9JNJ9LVJ9N^J9P&J=R.J=T6J=V -M>J=XFJ=ZNJ=\VJ=^^J>`&JB".JB$6JB&>JB(FJB*NJB,VJB.^JB0&JF2.JF4 -M6JF6>JF8FJF:NJF^JF@&JJB.JJD6JJF>JJHFJJJNJJLVJJN^JJP&JNR -M.JNT6JNV>JNXFJNZNJN\VJN^^JO`&JS".JS$6JS&>JS(FJS*NJS,VJS.^JS0 -M&JW2.JW46JW6>JW8FJW:NJW^JW@&J[B.J[D6J[F>J[HFJ[JNJ[LVJ[N -M^J[P&J_R.J_T6J_V>J_XFJ_ZNJ_\VJ_^^J\`&[`".[`$6[`&>[`(F[`*N[`, -MV[`.^[`0&[$2.[$46[$6>[$8F[$:N[$^[$@&[(B.[(D6[(F>[(HF[(J -MN[(LV[(N^[(P&[,R.[,T6[,V>[,XF[,ZN[,\V[,^^[-`&[1".[1$6[1&>[1( -MF[1*N[1,V[1.^[10&[52.[546[56>[58F[5:N[5^[5@&[9B.[9D6[9F -M>[9HF[9JN[9LV[9N^[9P&[=R.[=T6[=V>[=XF[=ZN[=\V[=^^[>`&[B".[B$ -M6[B&>[B(F[B*N[B,V[B.^[B0&[F2.[F46[F6>[F8F[F:N[F^[F@&[JB -M.[JD6[JF>[JHF[JJN[JLV[JN^[JP&[NR.[NT6[NV>[NXF[NZN[N\V[N^^[O` -M&[S".[S$6[S&>[S(F[S*N[S,V[S.^[S0&[W2.[W46[W6>[W8F[W:N[W -M^[W@&[[B.[[D6[[F>[[HF[[JN[[LV[[N^[[P&[_R.[_T6[_V>[_XF[_ZN[_\ -MV[_^^[\`',`"/,`$7,`&?,`(G,`*O,`,W,`._,`0',$2/,$47,$6?,$8G,$: -MO,$_,$@',(B/,(D7,(F?,(HG,(JO,(LW,(N_,(P',,R/,,T7,,V?,,X -MG,,ZO,,\W,,^_,-`',1"/,1$7,1&?,1(G,1*O,1,W,1._,10',52/,547,56 -M?,58G,5:O,5_,5@',9B/,9D7,9F?,9HG,9JO,9LW,9N_,9P',=R/,=T -M7,=V?,=XG,=ZO,=\W,=^_,>`',B"/,B$7,B&?,B(G,B*O,B,W,B._,B0',F2 -M/,F47,F6?,F8G,F:O,F_,F@',JB/,JD7,JF?,JHG,JJO,JLW,JN_,JP -M',NR/,NT7,NV?,NXG,NZO,N\W,N^_,O`',S"/,S$7,S&?,S(G,S*O,S,W,S. -M_,S0',W2/,W47,W6?,W8G,W:O,W_,W@',[B/,[D7,[F?,[HG,[JO,[L -MW,[N_,[P',_R/,_T7,_V?,_XG,_ZO,_\W,_^_,\`'=`"/=`$7=`&?=`(G=`* -MO=`,W=`._=`0'=$2/=$47=$6?=$8G=$:O=$_=$@'=(B/=(D7=(F?=(H -MG=(JO=(LW=(N_=(P'=,R/=,T7=,V?=,XG=,ZO=,\W=,^_=-`'=1"/=1$7=1& -M?=1(G=1*O=1,W=1._=10'=52/=547=56?=58G=5:O=5_=5@'=9B/=9D -M7=9F?=9HG=9JO=9LW=9N_=9P'==R/==T7==V?==XG==ZO==\W==^_=>`'=B" -M/=B$7=B&?=B(G=B*O=B,W=B._=B0'=F2/=F47=F6?=F8G=F:O=F_=F@ -M'=JB/=JD7=JF?=JHG=JJO=JLW=JN_=JP'=NR/=NT7=NV?=NXG=NZO=N\W=N^ -M_=O`'=S"/=S$7=S&?=S(G=S*O=S,W=S._=S0'=W2/=W47=W6?=W8G=W:O=W< -MW=W>_=W@'=[B/=[D7=[F?=[HG=[JO=[LW=[N_=[P'=_R/=_T7=_V?=_XG=_Z -MO=_\W=_^_=\`'N`"/N`$7N`&?N`(GN`*ON`,WN`._N`0'N$2/N$47N$6?N$8 -MGN$:ON$_N$@'N(B/N(D7N(F?N(HGN(JON(LWN(N_N(P'N,R/N,T7N,V -M?N,XGN,ZON,\WN,^_N-`'N1"/N1$7N1&?N1(GN1*ON1,WN1._N10'N52/N54 -M7N56?N58GN5:ON5_N5@'N9B/N9D7N9F?N9HGN9JON9LWN9N_N9P'N=R -M/N=T7N=V?N=XGN=ZON=\WN=^_N>`'NB"/NB$7NB&?NB(GNB*ONB,WNB._NB0 -M'NF2/NF47NF6?NF8GNF:ONF_NF@'NJB/NJD7NJF?NJHGNJJONJLWNJN -M_NJP'NNR/NNT7NNV?NNXGNNZONN\WNN^_NO`'NS"/NS$7NS&?NS(GNS*ONS, -MWNS._NS0'NW2/NW47NW6?NW8GNW:ONW_NW@'N[B/N[D7N[F?N[HGN[J -MON[LWN[N_N[P'N_R/N_T7N_V?N_XGN_ZON_\WN_^_N\`'_`"/_`$7_`&?_`( -MG_`*O_`,W_`.__`0'_$2/_$47_$6?_$8G_$:O_$__$@'_(B/_(D7_(F -M?_(HG_(JO_(LW_(N__(P'_,R/_,T7_,V?_,XG_,ZO_,\W_,^__-`'_1"/_1$ -M7_1&?_1(G_1*O_1,W_1.__10'_52/_547_56?_58G_5:O_5__5@'_9B -M/_9D7_9F?_9HG_9JO_9LW_9N__9P'_=R/_=T7_=V?_=XG_=ZO_=\W_=^__>` -M'_B"/_B$7_B&?_B(G_B*O_B,W_B.__B0'_F2/_F47_F6?_F8G_F:O_F -M__F@'_JB/_JD7_JF?_JHG_JJO_JLW_JN__JP'_NR/_NT7_NV?_NXG_NZO_N\ -MW_N^__O`'_S"/_S$7_S&?_S(G_S*O_S,W_S.__S0'_W2/_W47_W6?_W8G_W: -MO_W__W@'_[B/_[D7_[F?_[HG_[JO_[LW_[N__[P'__R/__T7__V?__X -MG__ZO__\W__^__\`,``*P`%(``N@`3R`"#`!*L`%R``;H`-\@!`P`DK`"4@! -M*Z`%O(`8,`-JP`W(`3N@!_R`(#`$BL`12`)+H`D\@2@P!:K`%<@"6Z`+?($P -M,`;*P!E(`VN@#;R!.#`'ZL`=R`-[H`_\@4`P"`K!(4@$BZ`1/()(,`DJP27( -M!)N@$WR"4#`*2L$I2`6KH!6\@E@P"VK!+<@%NZ`7_()@,`R*P3%(!LN@&3R# -M:#`-JL$UR`;;H!M\@W`P#LK!.4@'ZZ`=O(-X,`_JP3W(!_N@'_R#@#`0"L)! -M2`@+H2$\A(@P$2K"1<@(&Z$C?(20,!)*PDE("2NA);R$F#`3:L)-R`D[H2?\ -MA*`P%(K"44@*2Z$I/(6H,!6JPE7("ENA*WR%L#`6RL)92`MKH2V\A;@P%^K" -M7<@+>Z$O_(7`,!@*PV%(#(NA,3R&R#`9*L-ER`R;H3-\AM`P&DK#:4@-JZ$U -MO(;8,!MJPVW(#;NA-_R&X#`3R/Z#$]JL?U -MR![;HWM\C_`Q/LK'^4@?ZZ-]O(_X,3_JQ_W('_NC?_R/`#)`"L@!22`+I($\ -MD`@R02K(!Z2/ -M_)%`,D@*R2%))(NDD3R22#))*LDER22;I)-\DE`R2DK)*4DEJZ25O))8,DMJ -MR2W));NDE_R28#),BLDQ22;+I)D\DV@R3:K)-#)/ZLD]R2?[I)_\DX`R4`K*04DH"Z6A/)2(,E$JRD7)*!NEHWR4D#)2 -M2LI)22DKI:6\E)@R4VK*3RLMY22_KI;V\E_@R7^K+?Z?O_)W`,W@* -MS^%)/(NG\3R>R#-Y*L_ER3R;I_-\GM`S>DK/Z4D]JZ?UO)[8,WMJS^W)/;NG -M]_R>X#-\BL_Q23[+I_D\G^@S?:K/]4I/ZZD]O:?X-)_JTWW*3_NI/_VG`#6@"M2!2E`+JD$]J`@UH2K4AZI/_:E`-:@*U:%*5(NJ -M43VJ2#6I*M6ERE2;JE-]JE`UJDK5J4I5JZI5O:I8-:MJU:W*5;NJ5_VJ8#6L -MBM6Q2E;+JED]JV@UK:K5M#6OZM6]RE?[ -MJE_]JX`UL`K6P4I8"ZMA/:R(-;$JUL7*6!NK8WVLD#6R2M;)2EDKJV6]K)@U -MLVK6SRZMY/:_H-;VJU_7* -M7MNK>WVO\#6^RM?Y2E_KJWV]K_@UO^K7_ZVO_;7`-M@*VV%+;(NML3VVR#;9 -M*MMERVR;K;-]MM`VVDK;:4MMJZVUO;;8-MMJVVW+;;NMM_VVX#;`NOX3V\B#?Q*M[% -MRW@;K^-]O)`W\DK>R4MY*Z_EO;R8-_-JWLW+>3NOY_V\H#?TBM[12WI+K^D] -MO:@W]:K>UVNO[;V]N#?WZM[=RWM[K^_]O<`W^`K? -MX4M\BZ_Q/;[(-_DJW^7+?)NO\WV^T#?Z2M_I2WVKK_6]OM@W^VK?[[`/_L%`.`@+X2%,A(NP$3["2#@)*^$ES(2; -ML!-^PE`X"DOA*4R%J[`5OL)8.`MKX2W,A;NP%_["8#@,B^$Q3(;+L!D^PV@X -M#:OA-#@/Z^$]S(?[L!_^PX`X$`OB04R( -M"[$A/L2(.!$KXD7,B!NQ(W[$D#@22^))3(DKL26^Q)@X$VOB3/($.*'$FR -MI,F3*%.J7,FRIO8,.*'4NVK-FS:-.J7//JW/'D"-+GDRYLN7+F#-KWLRY -ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ -MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ -MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$;(44890DQ!!`@01BCA -MA!1***`43S11X88<1G@0-2\,]`(U'QT(0``F'H@``@!04A`E$R14P4`B`'!! -M03>R*!"+1@0@0`(GDB!`0"D>V.&12":IY)),-NGDDU!&*>645%9IY9583MG$ -M$DE,\8014X#0Y1,@Y&"##3"\@`28(!B1!!-%3)'%%%04H:$05;Q)1!%2@&`" -M"!<6,<034CPH8`M2O$"$%89*44005!`*`@I#I`!"##GD,`,(1;B0Q1-5.'$$ -M$4'`.6FEEV9Z`PA*N`#%HU)XZ<0+K4XQ!!)O,I&$J%GVZFNO,A"80PP%RA`# -M#C/0(`,-!)(0+`S#%GMLLLLV2^"UV&9+(`#/1AN#L<@JRRP,)!CYZ[GHIJON -MNNRVZ^Z[\,8K;Y/_U;O8/P(2:*"]_/;K[[\`!US=EDF`T,0;;H#PQ!AT7"K# -MI3CHD*P.RX+0K0(RN%"@QC&$8<.FB(+00AUID'&IR&>4;#$(+K3\0AISO"'P -MS#37;//-.*>5BR8'WDBD0`0`P(%`!Q*1A!0QL(@!T0!((<4733QA11%$!-V! -M0$,:+84,06<@T```:(U#T!X`'?;1,P2M@4`%G"U%#D%_()`!;M/0]@8"'>`V -ML0`$#<*.;M<0=`@"*>"V#4'7&-`";M^0\^.01R[YY)17;OGEF&>N^>8PF1C0 -MC28&+=#0`6B=]$!+!^`TU%)3+7I`5PN@-=<#>3V`V*\#4#8!6J<]T-H%:`WW -M0'(;H+7=`^%]@.DP]#W0WPAH+?A`A"N@->(T`K"`UHYS[OWWX(BG;QDD-N((@(X!\>@CD`$(^?.)!TX!Q0$!^/).TU(H0``"`04LL"``[0C" -M0(+0#K`19`">(]J0""(`GPWD`E0P@@8"X(`>_2A(;5```R0@`@R0((0C+"$) -MAE`$#@1@!`6!H4':49!VN*%]!,G10.3WP?I-L$BJ"^``"WC`!"ZP@06!8$%\ -M5)`*XBB#&^S@_$`H0A*:$(56)`$`]""T@@P-?N]#T!1]>+\`\.YH,0"@`!/A -MA"8DX$!D2(,<8D!$!"I0(`QTX$"42!`F4G!H!.$`%#GH0?J1H)!43*$)^0`` -M+1*$!%0(`R\"PHLP9'",CCP1D0[@)CBY8`8(^,QG.D?C`AC81I[6+ -M:2\Q.<\BK%2?6,VJ5K?ZFAM"52`Z!:A'!XJB@B;5I'ED*$N?6I`,2+6'\*3I -M.[`!OX -MREC.LI;+`V]<2V]/+H,KQEM\'KW*D3?6I?$ -M*>V;DXFKT<^QV<4TI>O5"'*U.(MYO4"5P69).5\9C#BM9Q9N$P<]D`[XM\59 -MW+*F-\WI3D/EAI062*'#'"2]/KBD9LXNFK$6:MC].8O,[6(@GQL_,E>-Y'<`8M*8E$GY;#0!+SSN1L'8M%^5&$+DI&]T_/9ZSBRQ'&D@;X-5F./&T -M/>Q,A_OC(`^YR#MR0XT+Q.'G]JDLU7UG2*M:TA0T>4`^\&IYNEEW!3&WOB$N -MRWY?G->GI2"\=5?S*RH<`'\C"/123E:@UF#B\ZW!S]L==%LF_7DW1\[U -MKGO]ZP.YX=4%LO2=JYR@N5[W=3&^:I>./2`@*'I<,UWR@J#<["&N\]1?[NZ8 -MVUWN<^4BX0A"N(>?W8S7@[IGY6B#O9L8YK88$4 -MGNECUGN9V!O_G:DTSJ,E^5WVEL^[=)6N_5Q/[ARB3U>+D)6 -M(#4R?-.YI_C/WL#QU&X[<7\?$!%0?O<>U[STIT]]V-Z0^0`(/NC3/?M_`UW@ -M3<2^\W4_=YO;&P"H1__K>7AH7(M>UVO_/BV;F'[5DU_#6A0F//[!__[#XR`> -MM6.(=S1"Q5>9P&B+)P=(-7KQ1W7@1T'[UW_\!P_/5WXF-`2-%0#<=5/5UX$> -M^(&:PR?M$``*0`6'$$1)``5?@"G#`BE(4`0@@"%#L`0QF`1$<`0PN"MU(@6W -M$@2B`H-0@"&1,BA,``)!*#4V&"<@,`55``500"A4T":2\H13D`18T"9O`H-R -M0B=VLH1VXH-4D`1#H#]P$@13`(.#X@14$`1#$(5&8RM&6`5"H"M3\()]8@22 -MHC^"D@1N,@20D@1/X`1+""H\V"D0V(@4I&"EW*"EIN(9M.(EX*`67&(:!Z`(@.(NT -M6(NVF!%H4`9LP`9O8#BW^(O`&(S".(S$6(S&>(S(F(S*N(S,V(S.^(S0&(W2 -M.(W46(W6>(W8F(W:N(W^(W@&([B.([D6([F>([HF([JN([LV([N^([P -M&(_R.(_T6(_V>(_XF(_ZN(_\V(_^^(\`&9`".9`$69`&>9`(F9`*N9`,V9`. -M^9`0&9$2.9$469$6>9$8F9$:N9$^9$@&9(B.9(D69(F>9(HF9(JN9(L -MV9(N^9(P&9,R.9,T69,V>9,XF9,ZN9,\V9,^^9-`&91".91$691&>91(F91* -MN91,V91.^910&952.9546956>958F95:N95^95@&99B.99D699F>99H -MF99JN99LV99N^99P&9=R.9=T69=V>9=XF9=ZN9=\V9=^^9>`&9B".9B$69B& -M>9B(F9B*N9B,V9B.^9B0&9F2.9F469F6>9F8F9F:N9F^9F@&9JB.9JD -M69JF>9JHF9JJN9JLV9JN^9JP&9NR.9NT69NV>9NXF9NZN9N\V9N^^9O`&9S" -M.9S$69S&>9S(F9S*N9S,V9S.^9S0&9W2.9W469W6>9W8F9W:N9W^9W@ -M&9[B.9[D69[F>9[HF9[JN9[LV9[N^9[P&9_R.9_T69_V>9_XF9_ZN9_\V9_^ -M^9\`&J`".J`$6J`&>J`(FJ`*NJ`,VJ`.^J`0&J$2.J$46J$6>J$8FJ$:NJ$< -MVJ$>^J$@&J(B.J(D6J(F>J(HFJ(JNJ(LVJ(N^J(P&J,R.J,T6J,V>J,XFJ,Z -MNJ,\VJ,^^J-`&J1".J1$6J1&>J1(FJ1*NJ1,VJ1.^J10&J52.J546J56>J58 -MFJ5:NJ5^J5@&J9B.J9D6J9F>J9HFJ9JNJ9LVJ9N^J9P&J=R.J=T6J=V -M>J=XFJ=ZNJ=\VJ=^^J>`&JB".JB$6JB&>JB(FJB*NJB,VJB.^JB0&JF2.JF4 -M6JF6>JF8FJF:NJF^JF@&JJB.JJD6JJF>JJHFJJJNJJLVJJN^JJP&JNR -M.JNT6JNV>JNXFJNZNJN\VJN^^JO`&JS".JS$6JS&>JS(FJS*NJS,VJS.^JS0 -M&JW2.JW46JW6>JW8FJW:NJW^JW@&J[B.J[D6J[F>J[HFJ[JNJ[LVJ[N -M^J[P&J_R.J_T6J_V>J_XFJ_ZNJ_\VJ_^^J\`&[`".[`$6[`&>[`(F[`*N[`, -MV[`.^[`0&[$2.[$46[$6>[$8F[$:N[$^[$@&[(B.[(D6[(F>[(HF[(J -MN[(LV[(N^[(P&[,R.[,T6[,V>[,XF[,ZN[,\V[,^^[-`&[1".[1$6[1&>[1( -MF[1*N[1,V[1.^[10&[52.[546[56>[58F[5:N[5^[5@&[9B.[9D6[9F -M>[9HF[9JN[9LV[9N^[9P&[=R.[=T6[=V>[=XF[=ZN[=\V[=^^[>`&[B".[B$ -M6[B&>[B(F[B*N[B,V[B.^[B0&[F2.[F46[F6>[F8F[F:N[F^[F@&[JB -M.[JD6[JF>[JHF[JJN[JLV[JN^[JP&[NR.[NT6[NV>[NXF[NZN[N\V[N^^[O` -M&[S".[S$6[S&>[S(F[S*N[S,V[S.^[S0&[W2.[W46[W6>[W8F[W:N[W -M^[W@&[[B.[[D6[[F>[[HF[[JN[[LV[[N^[[P&[_R.[_T6[_V>[_XF[_ZN[_\ -MV[_^^[\`',`"/,`$7,`&?,`(G,`*O,`,W,`._,`0',$2/,$47,$6?,$8G,$: -MO,$_,$@',(B/,(D7,(F?,(HG,(JO,(LW,(N_,(P',,R/,,T7,,V?,,X -MG,,ZO,,\W,,^_,-`',1"/,1$7,1&?,1(G,1*O,1,W,1._,10',52/,547,56 -M?,58G,5:O,5_,5@',9B/,9D7,9F?,9HG,9JO,9LW,9N_,9P',=R/,=T -M7,=V?,=XG,=ZO,=\W,=^_,>`',B"/,B$7,B&?,B(G,B*O,B,W,B._,B0',F2 -M/,F47,F6?,F8G,F:O,F_,F@',JB/,JD7,JF?,JHG,JJO,JLW,JN_,JP -M',NR/,NT7,NV?,NXG,NZO,N\W,N^_,O`',S"/,S$7,S&?,S(G,S*O,S,W,S. -M_,S0',W2/,W47,W6?,W8G,W:O,W_,W@',[B/,[D7,[F?,[HG,[JO,[L -MW,[N_,[P',_R/,_T7,_V?,_XG,_ZO,_\W,_^_,\`'=`"/=`$7=`&?=`(G=`* -MO=`,W=`._=`0'=$2/=$47=$6?=$8G=$:O=$_=$@'=(B/=(D7=(F?=(H -MG=(JO=(LW=(N_=(P'=,R/=,T7=,V?=,XG=,ZO=,\W=,^_=-`'=1"/=1$7=1& -M?=1(G=1*O=1,W=1._=10'=52/=547=56?=58G=5:O=5_=5@'=9B/=9D -M7=9F?=9HG=9JO=9LW=9N_=9P'==R/==T7==V?==XG==ZO==\W==^_=>`'=B" -M/=B$7=B&?=B(G=B*O=B,W=B._=B0'=F2/=F47=F6?=F8G=F:O=F_=F@ -M'=JB/=JD7=JF?=JHG=JJO=JLW=JN_=JP'=NR/=NT7=NV?=NXG=NZO=N\W=N^ -M_=O`'=S"/=S$7=S&?=S(G=S*O=S,W=S._=S0'=W2/=W47=W6?=W8G=W:O=W< -MW=W>_=W@'=[B/=[D7=[F?=[HG=[JO=[LW=[N_=[P'=_R/=_T7=_V?=_XG=_Z -MO=_\W=_^_=\`'N`"/N`$7N`&?N`(GN`*ON`,WN`._N`0'N$2/N$47N$6?N$8 -MGN$:ON$_N$@'N(B/N(D7N(F?N(HGN(JON(LWN(N_N(P'N,R/N,T7N,V -M?N,XGN,ZON,\WN,^_N-`'N1"/N1$7N1&?N1(GN1*ON1,WN1._N10'N52/N54 -M7N56?N58GN5:ON5_N5@'N9B/N9D7N9F?N9HGN9JON9LWN9N_N9P'N=R -M/N=T7N=V?N=XGN=ZON=\WN=^_N>`'NB"/NB$7NB&?NB(GNB*ONB,WNB._NB0 -M'NF2/NF47NF6?NF8GNF:ONF_NF@'NJB/NJD7NJF?NJHGNJJONJLWNJN -M_NJP'NNR/NNT7NNV?NNXGNNZONN\WNN^_NO`'NS"/NS$7NS&?NS(GNS*ONS, -MWNS._NS0'NW2/NW47NW6?NW8GNW:ONW_NW@'N[B/N[D7N[F?N[HGN[J -MON[LWN[N_N[P'N_R/N_T7N_V?N_XGN_ZON_\WN_^_N\`'_`"/_`$7_`&?_`( -MG_`*O_`,W_`.__`0'_$2/_$47_$6?_$8G_$:O_$__$@'_(B/_(D7_(F -M?_(HG_(JO_(LW_(N__(P'_,R/_,T7_,V?_,XG_,ZO_,\W_,^__-`'_1"/_1$ -M7_1&?_1(G_1*O_1,W_1.__10'_52/_547_56?_58G_5:O_5__5@'_9B -M/_9D7_9F?_9HG_9JO_9LW_9N__9P'_=R/_=T7_=V?_=XG_=ZO_=\W_=^__>` -M'_B"/_B$7_B&?_B(G_B*O_B,W_B.__B0'_F2/_F47_F6?_F8G_F:O_F -M__F@'_JB/_JD7_JF?_JHG_JJO_JLW_JN__JP'_NR/_NT7_NV?_NXG_NZO_N\ -MW_N^__O`'_S"/_S$7_S&?_S(G_S*O_S,W_S.__S0'_W2/_W47_W6?_W8G_W: -MO_W__W@'_[B/_[D7_[F?_[HG_[JO_[LW_[N__[P'__R/__T7__V?__X -MG__ZO__\W__^__\`,``*P`%(``N@`3R`"#`!*L`%R``;H`-\@!`P`DK`"4@! -M*Z`%O(`8,`-JP`W(`3N@!_R`(#`$BL`12`)+H`D\@2@P!:K`%<@"6Z`+?($P -M,`;*P!E(`VN@#;R!.#`'ZL`=R`-[H`_\@4`P"`K!(4@$BZ`1/()(,`DJP27( -M!)N@$WR"4#`*2L$I2`6KH!6\@E@P"VK!+<@%NZ`7_()@,`R*P3%(!LN@&3R# -M:#`-JL$UR`;;H!M\@W`P#LK!.4@'ZZ`=O(-X,`_JP3W(!_N@'_R#@#`0"L)! -M2`@+H2$\A(@P$2K"1<@(&Z$C?(20,!)*PDE("2NA);R$F#`3:L)-R`D[H2?\ -MA*`P%(K"44@*2Z$I/(6H,!6JPE7("ENA*WR%L#`6RL)92`MKH2V\A;@P%^K" -M7<@+>Z$O_(7`,!@*PV%(#(NA,3R&R#`9*L-ER`R;H3-\AM`P&DK#:4@-JZ$U -MO(;8,!MJPVW(#;NA-_R&X#`3R/Z#$]JL?U -MR![;HWM\C_`Q/LK'^4@?ZZ-]O(_X,3_JQ_W('_NC?_R/`#)`"L@!22`+I($\ -MD`@R02K(!Z2/ -M_)%`,D@*R2%))(NDD3R22#))*LDER22;I)-\DE`R2DK)*4DEJZ25O))8,DMJ -MR2W));NDE_R28#),BLDQ22;+I)D\DV@R3:K)-#)/ZLD]R2?[I)_\DX`R4`K*04DH"Z6A/)2(,E$JRD7)*!NEHWR4D#)2 -M2LI)22DKI:6\E)@R4VK*3RLMY22_KI;V\E_@R7^K+?Z?O_)W`,W@* -MS^%)/(NG\3R>R#-Y*L_ER3R;I_-\GM`S>DK/Z4D]JZ?UO)[8,WMJS^W)/;NG -M]_R>X#-\BL_Q23[+I_D\G^@S?:K/]4I/ZZD]O:?X-)_JTWW*3_NI/_VG`#6@"M2!2E`+JD$]J`@UH2K4AZI/_:E`-:@*U:%*5(NJ -M43VJ2#6I*M6ERE2;JE-]JE`UJDK5J4I5JZI5O:I8-:MJU:W*5;NJ5_VJ8#6L -MBM6Q2E;+JED]JV@UK:K5M#6OZM6]RE?[ -MJE_]JX`UL`K6P4I8"ZMA/:R(-;$JUL7*6!NK8WVLD#6R2M;)2EDKJV6]K)@U -MLVK6SRZMY/:_H-;VJU_7* -M7MNK>WVO\#6^RM?Y2E_KJWV]K_@UO^K7_ZVO_;7`-M@*VV%+;(NML3VVR#;9 -M*MMERVR;K;-]MM`VVDK;:4MMJZVUO;;8-MMJVVW+;;NMM_VVX#;`NOX3V\B#?Q*M[% -MRW@;K^-]O)`W\DK>R4MY*Z_EO;R8-_-JWLW+>3NOY_V\H#?TBM[12WI+K^D] -MO:@W]:K>UVNO[;V]N#?WZM[=RWM[K^_]O<`W^`K? -MX4M\BZ_Q/;[(-_DJW^7+?)NO\WV^T#?Z2M_I2WVKK_6]OM@W^VK?[[`/_L%`.`@+X2%,A(NP$3["2#@)*^$ES(2; -ML!-^PE`X"DOA*4R%J[`5OL)8.`MKX2W,A;NP%_["8#@,B^$Q3(;+L!D^PV@X -M#:OA-#@/Z^$]S(?[L!_^PX`X$`OB04R( -M"[$A/L2(.!$KXD7,B!NQ(W[$D#@22^))3(DKL26^Q)@X$VOB3R^-Y -M3(_KL3V^Q_@X'^OC?[-O_LW`.3@+Y^%,G(NS<3[.R#DY*^?ES)R;LW-^SM`Y -M.DOGZ4R=J[-UOL[8.3MKY^W,G;NS=_[.X#D\B^?Q3)[+LWD^S^@Y/:OG] -MV[-[?L_P.3[+Y_E,G^NS?;[/^#D_Z^?]S)_[LW_^SP`Z0`OH`4V@"[2!/M`( -M.D$KZ`7-H!NT@W[0$#I"2^@)3:$KM(6^T!@Z0VOH#4VOZ[6]OM?X.E_KZWW-K_NUO_[7`#M@ -M"^R!3;`+ML$^V`@[82OLA[;/_ME`.V@+[:%-M(NVT3[:2#MI*^VES;2;MM-^VE`[:DOMJ4VU -MJ[;5OMI8.VMK[:W-M;NVU_[:8#MLB^VQ3;;+MMD^VV@[;:OMM#MOZ^V]S;?[MM_^VX`[<`ONP4VX"[?A/MR(.W$K[L7- -MN!NWXW[2OOYV#M[:^_MS;V[M_?^ -MWN`[?(OO\4V^R[?Y/M_H.WVK[_7-OMNW^W[?\#M^R^_Y3;_KM_V^W_@[?^OO -M_[DO_^7`/)@+\V%.S(NY,3_FR#R9*_-ESLR;N3-_YM`\FDOS:4[-J[DUO^;8 -M/)MK\VW.S;NY-__FX#R3_OZ#V]J_?USM[; -MNWM_[_`]OLOW^4[?Z[M]O^_X/;_K]_W.W_N[?__O`#[`"_@!3^`+O($_\`@^ -MP2OX!<_@&[R#?_`0/L)+^`E/X2N\A;_P&#[#:_@-S^$[O(?_\"`^Q(OX$4_B -M2[R)/_$H/L6K^!7/XEN\BW_Q,#[&R_@93^-KO(V_\3@^Q^OX'<_C>[R/__%` -M/L@+^2%/Y(N\D3_R2#[)*_DES^2;O)-_\E`^RDOY*4_EJ[R5O_)8/LMK^2W/ -MY;N\E__R8#[,B_DQ3^;+O)D_\V@^S:OY-<_FV[R;?_-P/L[+^3E/Y^N\G;_S -M>#[/Z_D]S^?[O)__\X`^T`OZ04_H"[VA/_2(/M$K^D7/Z!N]HW_TD#[22_I) -M3^DKO:6_])@^TVOZ3<_I.[VG__2@/M2+^E%/ZDN]J3_UJ#[5J_I5S^I;O:M_ -M];`^ULOZ64_K:[VMO_6X/M?K^EW/ZWN]K__UP#[8"_MA3^R+O;$_]L@^V2O[ -M9<_LF[VS?_;0/MI+^VE/[:N]M;_VV#[;:_MMS^V[O;?_]N`^W(O[<4_NR[VY -M/_?H/MVK^W7/[MN]NW_W\#[>R_MY3^_KO;V_]_@^W^O[?<_O^[V___<`/^`+ -M_(%/\`N^P3_X"#_A*_R%S_`;OL-_^!`_XDO\B4_Q*[[%O_@8/^-K_(W/\3N^ -MQ__X(#_DB_R13_)+OLD_^2@_Y:O\E<_R6[[+?_DP/^;+_)E/\VN^S;_Y.#_G -MZ_R=S_-[OL__^4`_Z`O]H4_TB[[1/_I(/^DK_:7/])N^TW_Z4#_J2_VI3_6K -MOM6_^E@_ZVO]K<_UN[[7__I@/^R+_;%/]LN^V3_[:#_MJ_VUS_;;OMM_^W`_ -M[LO]N4_WZ[[=O_MX/^_K_;W/]_N^W__[@#_P"_[!3_@+O^$__(@_\2O^Q<_X -M&[_C?_R0/_)+_LE/^2N_Y;_\F#_S:_[-S_D[O^?__*`_](O^T4_Z2[_I/_VH -M/_6K_M7/^EN_ZW_]L#_VR_[93_MKO^V__;@_]^O^W<_[>[_O__W`/_@+_^%/ -M_(N_\3_^R#_Y*__ES_R;O_-__M`_^DO_Z4_]J[_UO_[8/_MK_^W/_;N_]__^ -MX#_\B__Q3_[+O_D__^@__:O_]<_^V[_[?__P/_[+__E/_^N__;__^#__Z__] -MS__[O____P!@`"@`#H`$8`%H`!Z`"&`"J``N@`Q@`^@`/H`08`0H`4Z`%&`% -M:`%>@!A@!J@!;H`<8`?H`7Z`(&`(*`*.@"1@"6@"GH`H8`JH`JZ`+&`+Z`*^ -M@#!@#"@#SH`T8`UH`]Z`.&`.J`/N@#Q@#^@#_H!`8!`H!`Z!1&`1:`0>@4A@ -M$J@$+H%,8!/H!#Z!4&`4*`5.@51@%6@%7H%88!:H!6Z!7&`7Z`5^@6!@&"@& -MCH%D8!EH!IZ!:&`:J`:N@6Q@&^@&OH%P8!PH!\Z!=&`=:`?>@7A@'J@'[H%\ -M8!_H!_Z!@&`@*`@.@H1@(6@('H*(8"*H""Z"C&`CZ`@^@I!@)"@)3H*48"5H -M"5Z"F&`FJ`EN@IQ@)^@)?H*@8"@H"HZ"I&`I:`J>@JA@*J@*KH*L8"OH"KZ" -ML&`L*`O.@K1@+6@+WH*X8"ZH"^Z"O&`OZ`O^@L!@,"@,#H/$8#%H#!Z#R&`R -MJ`PN@\Q@,^@,/H/08#0H#4Z#U&`U:`U>@]A@-J@-;H/<8#?H#7Z#X&`X*`Z. -M@^1@.6@.GH/H8#JH#JZ#[&`[Z`Z^@_!@/"@/SH/T8#UH#]Z#^&`^J`_N@_Q@ -M/^@/_H,`84`H$`Z$!&%!:!`>A`AA0J@0+H0,84/H$#Z$$&%$*!%.A!1A16@1 -M7H0884:H$6Z$'&%'Z!%^A"!A2"@2CH0D84EH$IZ$*&%*J!*NA"QA2^@2OH0P -M84PH$\Z$-&%-:!/>A#AA3J@3[H0\84_H$_Z$0&%0*!0.A41A46@4'H5(85*H -M%"Z%3&%3Z!0^A5!A5"@53H54855H%5Z%6&%6J!5NA5QA5^@5?H5@85@H%HZ% -M9&%9:!:>A6AA6J@6KH5L85OH%KZ%<&%<*!?.A71A76@7WH5X85ZH%^Z%?&%? -MZ!?^A8!A8"@8#H:$86%H&!Z&B&%BJ!@NAHQA8^@8/H:0860H&4Z&E&%E:!E> -MAIAA9J@9;H:<86?H&7Z&H&%H*!J.AJ1A:6@:GH:H86JH&JZ&K&%KZ!J^AK!A -M;"@;SH:T86UH&]Z&N&%NJ!ONAKQA;^@;_H;`87`H'`Z'Q&%Q:!P>A\AA"@>CH?D -M87EH'IZ'Z&%ZJ!ZNA^QA>^@>OH?P87PH'\Z']&%]:!_>A_AA?J@?[H?\87_H -M'_Z'`&*`*"`.B`1B@6@@'H@(8H*H("Z(#&*#Z"`^B!!BA"@A3H@48H5H(5Z( -M&&*&J"%NB!QBA^@A?H@@8H@H(HZ()&*):"*>B"ABBJ@BKH@L8HOH(KZ(,&*, -M*"/.B#1BC6@CWH@X8HZH(^Z(/&*/Z"/^B$!BD"@D#HE$8I%H)!Z)2&*2J"0N -MB4QBD^@D/HE08I0H)4Z)5&*5:"5>B5ABEJ@E;HE<8I?H)7Z)8&*8*":.B61B -MF6@FGHEH8IJH)JZ);&*;Z":^B7!BG"@GSHET8IUH)]Z)>&*>J"?NB7QBG^@G -M_HF`8J`H*`Z*A&*A:"@>BHABHJ@H+HJ,8J/H*#Z*D&*D*"E.BI1BI6@I7HJ8 -M8J:H*6Z*G&*GZ"E^BJ!BJ"@JCHJD8JEH*IZ*J&*JJ"JNBJQBJ^@JOHJP8JPH -M*\Z*M&*M:"O>BKABKJ@K[HJ\8J_H*_Z*P&*P*"P.B\1BL6@L'HO(8K*H+"Z+ -MS&*SZ"P^B]!BM"@M3HO48K5H+5Z+V&*VJ"UNB]QBM^@M?HO@8K@H+HZ+Y&*Y -M:"Z>B^ABNJ@NKHOL8KOH+KZ+\&*\*"_.B_1BO6@OWHOX8KZH+^Z+_&*_Z"_^ -'BP!CP+@7`0`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_iso_xorriso.c b/thirdparty/libarchive/libarchive/test/test_read_format_iso_xorriso.c deleted file mode 100644 index ce71a560a..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_iso_xorriso.c +++ /dev/null @@ -1,216 +0,0 @@ -/*- - * Copyright (c) 2011 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - - -/* -Execute the following command to rebuild the data for this program: - tail -n +32 test_read_format_iso_xorriso.c | /bin/sh -# -rm -rf /tmp/iso -mkdir /tmp/iso -mkdir /tmp/iso/dir -mkdir /tmp/iso/dir2 -echo "hello" >/tmp/iso/file -ln /tmp/iso/file /tmp/iso/hardlink -(cd /tmp/iso; ln -s file symlink) -TZ=utc touch -afm -t 197001020000.01 /tmp/iso/empty -echo "hello2" >/tmp/iso/dir/file2 -echo "hello3" >/tmp/iso/dir/file3 -echo "hello4" >/tmp/iso/dir2/file4 - -TZ=utc touch -afhm -t 197001020000.01 /tmp/iso/dir/file2 /tmp/iso/dir/file3 -TZ=utc touch -afhm -t 197001020000.01 /tmp/iso/dir2/file4 -TZ=utc touch -afhm -t 197001020000.01 /tmp/iso /tmp/iso/file /tmp/iso/dir -TZ=utc touch -afhm -t 197001020000.01 /tmp/iso/dir2 -TZ=utc touch -afhm -t 197001030000.02 /tmp/iso/symlink -F=test_read_format_iso_xorriso.iso -xorriso -outdev - -map /tmp/iso / > $F -compress $F -uuencode $F.Z $F.Z > $F.Z.uu -rm $F.Z -exit 1 - */ - -/* - * A test for the iso images made by xorriso which versions are - * from 0.6.5 to 1.0.1. - * The xorriso set 0 to the location of empty files(include symlink - * files) that caused our iso reader could not read following directory - * entries at all. - * - */ - -DEFINE_TEST(test_read_format_iso_xorriso) -{ - const char *refname = "test_read_format_iso_xorriso.iso.Z"; - struct archive_entry *ae; - struct archive *a; - const void *p; - size_t size; - int64_t offset; - int i; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualInt(0, archive_read_support_filter_all(a)); - assertEqualInt(0, archive_read_support_format_all(a)); - assertEqualInt(ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Retrieve each of the 10 files on the ISO image and - * verify that each one is what we expect. */ - for (i = 0; i < 10; ++i) { - assertEqualInt(0, archive_read_next_header(a, &ae)); - - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - if (strcmp(".", archive_entry_pathname(ae)) == 0) { - /* '.' root directory. */ - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - /* Now, we read timestamp recorded by RRIP "TF". */ - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - /* Now, we read links recorded by RRIP "PX". */ - assertEqualInt(4, archive_entry_nlink(ae)); - assertEqualIntA(a, ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - } else if (strcmp("./dir", archive_entry_pathname(ae)) == 0) { - /* A directory. */ - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(2, archive_entry_nlink(ae)); - } else if (strcmp("./dir2", archive_entry_pathname(ae)) == 0) { - /* A directory. */ - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(2, archive_entry_nlink(ae)); - } else if (strcmp("./file", - archive_entry_pathname(ae)) == 0) { - /* A regular file. */ - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(0, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt(0, offset); - assertEqualMem(p, "hello\n", 6); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(2, archive_entry_nlink(ae)); - } else if (strcmp("./hardlink", - archive_entry_pathname(ae)) == 0) { - /* A hardlink to the regular file. */ - /* Note: If "hardlink" gets returned before "file", - * then "hardlink" will get returned as a regular file - * and "file" will get returned as the hardlink. - * This test should tolerate that, since it's a - * perfectly permissible thing for libarchive to do. */ - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualString("./file", archive_entry_hardlink(ae)); - assertEqualInt(0, archive_entry_size_is_set(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(2, archive_entry_stat(ae)->st_nlink); - } else if (strcmp("./symlink", - archive_entry_pathname(ae)) == 0) { - /* A symlink to the regular file. */ - assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); - assertEqualString("file", archive_entry_symlink(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(172802, archive_entry_mtime(ae)); - assertEqualInt(172802, archive_entry_atime(ae)); - assertEqualInt(1, archive_entry_stat(ae)->st_nlink); - } else if (strcmp("./empty", - archive_entry_pathname(ae)) == 0) { - /* A empty file. */ - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(1, archive_entry_nlink(ae)); - } else if (strcmp("./dir/file2", - archive_entry_pathname(ae)) == 0) { - /* A regular file. */ - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(7, archive_entry_size(ae)); - assertEqualInt(0, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt(0, offset); - assertEqualMem(p, "hello2\n", 7); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(1, archive_entry_nlink(ae)); - } else if (strcmp("./dir/file3", - archive_entry_pathname(ae)) == 0) { - /* A regular file. */ - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(7, archive_entry_size(ae)); - assertEqualInt(0, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt(0, offset); - assertEqualMem(p, "hello3\n", 7); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(1, archive_entry_nlink(ae)); - } else if (strcmp("./dir2/file4", - archive_entry_pathname(ae)) == 0) { - /* A regular file. */ - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(7, archive_entry_size(ae)); - assertEqualInt(0, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt(0, offset); - assertEqualMem(p, "hello4\n", 7); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(1, archive_entry_nlink(ae)); - } else { - failure("Saw a file that shouldn't have been there"); - assertEqualString(archive_entry_pathname(ae), ""); - } - } - - /* End of archive. */ - assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE); - - /* Close the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_iso_xorriso.iso.Z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_iso_xorriso.iso.Z.uu deleted file mode 100644 index b69a94501..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_iso_xorriso.iso.Z.uu +++ /dev/null @@ -1,61 +0,0 @@ -begin 644 test_read_format_iso_xorriso.iso.Z -M'YV0``(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR -MI,F3*%.J7,FRIO8,.*'4NVK-FS:-.J7//JW/'D"-+GDRYLN7+F#-KWLRY -ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ -MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ -MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```"`DJ.""##;HX())3/%$ -M$DT$<401#V;HX$$\%-2A1P<"$$"(!R*````B%"2"#0G=,%"*,A04XXD"G?B& -M``DP(``%``@0$(D'1CAAA1=J:.212":IY)),-NGDDU!&*2636#PAA11"M@"# -M"S2X``,(,A"8@Y;L\,(,-^SP -MPQ!'+/'$%%=L\<489ZSQQAQW[/''((L\\X\]^SSST`'+?301!=M]-%()ZWTTDPW[?334$M]MIL"Q;@@`4>&*F0%%J(H90'<5"0 -MWB#^2"(`)J*H(HL(N2@0C#("/I"-..K(HX^OBABDA'47.>GEF&>N^>:-5GEE -MEEMV^66G8\)0YIDPI'GKH'L^46B=H>/9YIM"]GEHF*R_?FBBG/?N^^_`!_]H -MJI>N2BJG:GY::?&LEIH\1,2/VFKR(;9M?;.UPHWK]=QW[WVL'UC1`0J(?)HX -MC0$QGN../?[H-P!30'%``+Z\`P`46)`00#M!#!1$.]432`#2,8"!#"`=!Z&" -M$300``<8(0"0.]`#(PB`&ZV/1TYH0@$@.(0B<"``,RA("`W2CH*TPPSF(\B, -M%E?!QK&/@I(+`/[TQS__`;`@`RR@0`Z8P`4V<(+N`^*K+.@X`&1P@P0`@!H` -M0(."-!%]BB/B"]TGH@$0(0E2F.'^^B>0_P7P1P0T(`(-HD`&.A""043C$%V( -MP28@X$!D2(,0&(H!8!H2'9/3A&2F8RTUF,)(`,$,:V%`&`.#! -MF,A4)D&8R49._F@!2`B"%(C@)B)4*7WT" -M$T#@UB=8(0E$*,(40#"%*D`!"E:B`@B,8"6Z/F$*2<#"8*6)H9%.`:U-X.LG -M@W#6)`PA?M,,PA0P-(0GG#4(0Q#L%:):O3YA3!UV0H,UB"`JG3>UJ08#7(E0VFDTEKA/HBJ4*22$+(+""7*O0 -M!`SEE;18"F5A"A&"PB82Y(DLW"0?#R1( -M+@;$BSB$J4P72M-;EK.>1T0C"F.D0L752)=[!.F(ZFO#5QY2EHFT)3EO"5$D -M`J"2F1Q(#@Y0D`-\-'(!0$`TIRF#:J8TE0(-2"L=K%^%#H2AN?SO+C/HRW2N -MLPPRJ*0."J(##A/$P_5TIHA$S-@9F#B@V60Q0F/J8H'`V+\4!G`O#X34,HQP -MO5C.\GY0:$>"X#&^]9SOB0=Y7Y<*L,41;NBK9%S$`/MHP.<#\R[G*T-4DAD` -M^#4DFL.I2"@_5,H6KN0."K(#'P\$R+L4\WQ?W=\)_ -MGO&4;X"YVN_O=\(ZWO.=-[WK;^][XSK>^ -M]\WO?OO[WP`/N,`'3O""&_S@"$^XPA?.\(8[_.$0C[C$)T[QBEO\XAC/N,8W -MSO&.>_SC(`^YR$=.\I*;_.0H3[G*5\[REKO\Y3"/NI8S[K6M\[U -MKGO]ZV`/N]C'3O:RF_WL:$^[VM?.]K:[_>UPC[O^ -M^_WO@`^\X`=/^,(;_O"(3[SB%\_XQCO^\9"/O.0G3_G*6_[RF,^\YC?/^I7S_K6N_[UL(^][&=/^]K;_O:XS[WN=\_[WOO^ -M]\`/OO"'3_SB&__XR$^^\I?/_.8[__G0C[[TIT_]ZEO_^MC/OO:WS_WN>__[ -MX`^_^,=/_O*;__SH3[_ZU\_^]KO__?"/O_SG3__ZV__^^,^__O?/__[[__\` -M&(`".(`$6(`&>(`(F(`*N(`,V(`.^(`0&($2.($46($6>($8F($:N($ -M^($@&((B.((D6((F>((HF((JN((LV((N^((P&(,R.(,T6(,V>(,XF(,ZN(,\ -MV(,^^(-`&(1".(1$6(1&>(1(F(1*N(1,V(1.^(10&(52.(546(56>(58F(5: -MN(5^(5@&(9B.(9D6(9F>(9HF(9JN(9LV(9N^(9P&(=R.(=T6(=V>(=X -MF(=ZN(=\V(=^^(>`&(B".(B$6(B&>(B(F(B*N(B,V(B.^(B0&(F2.(F46(F6 -3>(F8F(F:N(F^(F@&(HZ`0`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_iso_zisofs.iso.Z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_iso_zisofs.iso.Z.uu deleted file mode 100644 index ef54ca6c7..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_iso_zisofs.iso.Z.uu +++ /dev/null @@ -1,63 +0,0 @@ -$FreeBSD: head/lib/libarchive/test/test_read_format_iso_zisofs.iso.Z.uu 201247 2009-12-30 05:59:21Z kientzle $ - -begin 644 test_read_format_iso_zisofs.iso.Z -M'YV0``(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR -MI,F3*%.J7,FRIO8,.*'4NVK-FS:-.J7//JW/'D"-+GDRYLN7+F#-KWLRY -ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ -MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ -MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$;(44890DQ!!`@01BCA -MA!1***`43S11X88<1GA0+`6!Z-&!``1`XH$((`"`!059,$%"%0PD`@`7%%2C -MB@*I:$0``B10(@D"!'3B@1T6:>212":IY)),-NGDDU!&*>645%9I991-+)'$ -M%$\8,04(6SX!0@XVV`##"TAX"8(123!1Q!193$%%$1H*446;1!0A!0@F@'!A -M$4,\(<6#`K8@Q0M$6$&H%$4$086@(*`P1`H@Q)!##C.`4(0+63Q1A1-'$!&$ -MFY%.6NFE-X"@A`M0-"H%ETZ\L.H40R#1)A-)@'KEKKSN*@.!.<`0K`PRQ$!# -M#300"`,)OPKK++'&(JLL"NXY)9K[KGHIJON -MNNRVZ^Z2_\6[V#\"$FB@O/CFJ^^^_/9;799)@'!%&62`,$49<$`H`PC%ZG"L -MPS`P#*P";:R1QAQOF#$'PRX4"(*A']>11L$Q?'S&R`Q_K`<(+K3\@AX7O^'O -MS#37;//-.)=U8(U""C0``!@(="`124B1\]%()ZWTTDPW[?334$M]MI,(T*CC0#@&)".//H8`)`]EWC@ -M%%`<$(`O[P`@A10%!!`(%%B$VTX0`P71CM8##6"UT$$2)``51F@0@`,[]OAC -M&PD(4$$+*)``NNBDDS!$$1P$D$%!KQO43D'MF/$V03<.1+?G=U<^9`"#%WYX -MX@$LWOCC!4E>$(\%79[YYIW;;7KHHY=^>O4D```'T`4%+7?<"-;]H^]"#N!U -M\`$DXD03"!Q(1AIR(*XXXP(Y7OE``DPNY/T".:\YY^*[6_0^1[W4`8`0`-!` -M031@`P,,Q``V&.#=A":D`[#)32[800S0I[XF).!`9D@#&\H@OP"0(A`#"00I -M^!>0_"V/A0#P'_0"2`()3@]UI=."$2`0`#CH@0`/H$(8>!$07H2!"HQ(X`(; -M^,`(TI"")5H`$H(P*%PY80D9W"#ATK>^!AP(#6&0`QG8D`8WK*&$)TSA"ING -MOQ+!4(8`Y-T-L7>]U.F0ASX$HA")"``C4L$0`-A`001I$!M",0`*@%,3K(A% -M#0INBXU8'P,.-(<\M(&,9BPA,$(QD%``HXTF>F'SIL"$!9"(`"$<(>;^MZ,! -M^$@`-0R`*V,XQ]2YC9`#P25!ZEBZ0RY`D8R401;1%\DF>!$`E;QD&=<@`TUR -M4B">!"4HWTC*28(/``.@0QO@L,K-\;*6UBM@Z101R$$>Y'0%^%GV\A:`7V9A -MD;E:P@R&"%HA4`^+TK&A-JUK7:A$]M0.15#B$ -M5I,`A2]8*@C``IO@$J"6P:@J.2\`0G&,Q3B-T4A&;+ -M6-\"5[A@RI-MD9L$/8')N8U-0A.HF`406.$)3*A"$_B:)UI)@:Z/&BZD:GO; -MW'Z7N%(8;VN;ZP*V^O>_``[PS&Y`CBE8(AG;L,8!]JC2!P0$'P4("!,!,.$* -M.Y#"%[:PA#/,X0U[&,,?UC"(1RSB$G>8Q"9 -MRE>VQG+7]8RF,I2F_K4J$ZUJE?-ZE:[^M6PCK6L9TWK6MOZUKC. -MM:YWS>M>^_K7P`ZVL(=-[&(;^]C(3K:RE\WL9CO[V=".MK2G3>UJ6_O:V,ZV -MMK?-[6Y[^]O@#K>XQTWNYVN_O=\(ZWO.=-[WK;^][XSK>^ -M]\WO?OO[WP`/N,`'3O""&_S@"$^XPA?.\(8[_.$0C[C$)T[QBEO\XAC/N,8W -MSO&.>_SC(`^YR$=.\I*;_.0H3[G*5\[REKO\Y3"/NI8S[K6M\[U -MKGO]ZV`/N]C'3O:RF_WL:$^[VM?.]K:[_>UPC[O^ -M^_WO@`^\X`=/^,(;_O"(3[SB%\_XQCO^\9"/O.0G3_G*6_[RF,^\YC?/^I7S_K6N_[UL(^][&=/^]K;_O:XS[WN=\_[WOO^ -M]\`/OO"'3_SB&__XR$^^\I?/_.8[__G0C[[TIT_]ZEO_^MC/OO:WS_WN>__[ -MX`^_^,=/_O*;__SH3[_ZU\_^]KO__?"/O_SG3__ZV__^^,^__O?/__[[__\` -M&(`".(`$6(`&>(`(F(`*N(`,V(`.^(`0&($2.($46($6>($8F($:N($ -M^($@&((B.((D6((F>((HF((JN((LV((N^((P&(,R.(,T6(,V>(,XF(,ZN(,\ -MV(,^^(-`&(1".(1$6(1&>(1(F(1*N(1,V(1.^(10&(52.(546(56>(58F(5: -MN(5^(5@&(9B.(9D6(9F>(9HF(9JN(9LV(9N^(9P&(=R.(=T6(=V>(=X -MF(=ZN(=\V(=^^(>`&(B".(B$6(B&>(B(F(B*N(B,V(B.^(B0&(F2.(F46(F6 -@>(F8F(F:N(F^(F@&(JB.(JD6(JF>(JHF(JJN'`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_isojoliet_bz2.c b/thirdparty/libarchive/libarchive/test/test_read_format_isojoliet_bz2.c deleted file mode 100644 index eb33c0b4f..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_isojoliet_bz2.c +++ /dev/null @@ -1,141 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * All rights reserved. - * - * Based on libarchive/test/test_read_format_isorr_bz2.c with - * bugs introduced by Andreas Henriksson for - * testing ISO9660 image with Joliet extension. - * - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_isojoliet_bz2.c 201247 2009-12-30 05:59:21Z kientzle $"); - -/* -Execute the following to rebuild the data for this program: - tail -n +35 test_read_format_isojoliet_bz2.c | /bin/sh - -rm -rf /tmp/iso -mkdir /tmp/iso -mkdir /tmp/iso/dir -echo "hello" >/tmp/iso/long-joliet-file-name.textfile -ln /tmp/iso/long-joliet-file-name.textfile /tmp/iso/hardlink -(cd /tmp/iso; ln -s long-joliet-file-name.textfile symlink) -if [ "$(uname -s)" = "Linux" ]; then # gnu coreutils touch doesn't have -h -TZ=utc touch -afm -t 197001020000.01 /tmp/iso /tmp/iso/long-joliet-file-name.textfile /tmp/iso/dir -TZ=utc touch -afm -t 197001030000.02 /tmp/iso/symlink -else -TZ=utc touch -afhm -t 197001020000.01 /tmp/iso /tmp/iso/long-joliet-file-name.textfile /tmp/iso/dir -TZ=utc touch -afhm -t 197001030000.02 /tmp/iso/symlink -fi -F=test_read_format_iso_joliet.iso.Z -mkhybrid -J -uid 1 -gid 2 /tmp/iso | compress > $F -uuencode $F $F > $F.uu -exit 1 - */ - -DEFINE_TEST(test_read_format_isojoliet_bz2) -{ - const char *refname = "test_read_format_iso_joliet.iso.Z"; - struct archive_entry *ae; - struct archive *a; - const void *p; - size_t size; - int64_t offset; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualInt(0, archive_read_support_filter_all(a)); - assertEqualInt(0, archive_read_support_format_all(a)); - assertEqualInt(ARCHIVE_OK, - archive_read_set_option(a, "iso9660", "rockridge", NULL)); - assertEqualInt(ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* First entry is '.' root directory. */ - assertEqualInt(0, archive_read_next_header(a, &ae)); - assertEqualString(".", archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(86401, archive_entry_ctime(ae)); - assertEqualInt(3, archive_entry_stat(ae)->st_nlink); - assertEqualInt(0, archive_entry_uid(ae)); - assertEqualIntA(a, ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* A directory. */ - assertEqualInt(0, archive_read_next_header(a, &ae)); - assertEqualString("dir", archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* A regular file with two names ("hardlink" gets returned - * first, so it's not marked as a hardlink). */ - assertEqualInt(0, archive_read_next_header(a, &ae)); - assertEqualString("hardlink", - archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assert(archive_entry_hardlink(ae) == NULL); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(0, archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt(6, (int)size); - assertEqualInt(0, offset); - assertEqualMem(p, "hello\n", 6); - - /* Second name for the same regular file (this happens to be - * returned second, so does get marked as a hardlink). */ - assertEqualInt(0, archive_read_next_header(a, &ae)); - assertEqualString("long-joliet-file-name.textfile", - archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualString("hardlink", - archive_entry_hardlink(ae)); - assert(!archive_entry_size_is_set(ae)); - - /* A symlink to the regular file. */ - assertEqualInt(0, archive_read_next_header(a, &ae)); - assertEqualString("symlink", archive_entry_pathname(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(172802, archive_entry_mtime(ae)); - assertEqualInt(172802, archive_entry_atime(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* End of archive. */ - assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS); - - /* Close the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_isojoliet_long.c b/thirdparty/libarchive/libarchive/test/test_read_format_isojoliet_long.c deleted file mode 100644 index 4283c399f..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_isojoliet_long.c +++ /dev/null @@ -1,149 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2009 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_isojoliet_long.c 201247 2009-12-30 05:59:21Z kientzle $"); - -/* -Execute the following to rebuild the data for this program: - tail -n +35 test_read_format_isojoliet_long.c | /bin/sh - -rm -rf /tmp/iso -mkdir /tmp/iso -num=0 -file=""; -while [ $num -lt 100 ] -do - num=$((num+10)) - file="${file}1234567890" -done -dir="${file}dir" -mkdir /tmp/iso/${dir} -file="${file}123" -echo "hello" > /tmp/iso/${file} -ln /tmp/iso/${file} /tmp/iso/hardlink -if [ "$(uname -s)" = "Linux" ]; then # gnu coreutils touch doesn't have -h -TZ=utc touch -afm -t 197001020000.01 /tmp/iso /tmp/iso/${file} /tmp/iso/${dir} -else -TZ=utc touch -afhm -t 197001020000.01 /tmp/iso /tmp/iso/${file} /tmp/iso/${dir} -fi -F=test_read_format_iso_joliet_long.iso.Z -mkhybrid -J -joliet-long -uid 1 -gid 2 /tmp/iso | compress > $F -uuencode $F $F > $F.uu -rm -rf /tmp/iso -exit 1 - */ - -DEFINE_TEST(test_read_format_isojoliet_long) -{ - const char *refname = "test_read_format_iso_joliet_long.iso.Z"; - char pathname[104]; - struct archive_entry *ae; - struct archive *a; - const void *p; - size_t size; - int64_t offset; - int i; - - for (i = 0; i < 100; i++) - pathname[i] = '0' + ((i+1) % 10); - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualInt(0, archive_read_support_filter_all(a)); - assertEqualInt(0, archive_read_support_format_all(a)); - assertEqualInt(ARCHIVE_OK, - archive_read_set_options(a, "iso9660:!rockridge")); - assertEqualInt(ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* First entry is '.' root directory. */ - assertEqualInt(0, archive_read_next_header(a, &ae)); - assertEqualString(".", archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(86401, archive_entry_ctime(ae)); - assertEqualInt(3, archive_entry_stat(ae)->st_nlink); - assertEqualInt(0, archive_entry_uid(ae)); - assertEqualIntA(a, ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* A directory. */ - pathname[100] = 'd'; - pathname[101] = 'i'; - pathname[102] = 'r'; - pathname[103] = '\0'; - assertEqualInt(0, archive_read_next_header(a, &ae)); - assertEqualString(pathname, archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* A regular file with two names (pathname gets returned - * first, so it's not marked as a hardlink). */ - pathname[100] = '1'; - pathname[101] = '2'; - pathname[102] = '3'; - pathname[103] = '\0'; - assertEqualInt(0, archive_read_next_header(a, &ae)); - assertEqualString("hardlink", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assert(archive_entry_hardlink(ae) == NULL); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(0, archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt(6, (int)size); - assertEqualInt(0, offset); - assertEqualMem(p, "hello\n", 6); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Second name for the same regular file (this happens to be - * returned second, so does get marked as a hardlink). */ - assertEqualInt(0, archive_read_next_header(a, &ae)); - assertEqualString(pathname, archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualString("hardlink", archive_entry_hardlink(ae)); - assert(!archive_entry_size_is_set(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* End of archive. */ - assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS); - - /* Close the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_isojoliet_rr.c b/thirdparty/libarchive/libarchive/test/test_read_format_isojoliet_rr.c deleted file mode 100644 index 3c19516d6..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_isojoliet_rr.c +++ /dev/null @@ -1,170 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * All rights reserved. - * - * Based on libarchive/test/test_read_format_isorr_bz2.c with - * bugs introduced by Andreas Henriksson for - * testing ISO9660 image with Joliet extension. - * - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_isojoliet_rr.c 201247 2009-12-30 05:59:21Z kientzle $"); - -/* -Execute the following to rebuild the data for this program: - tail -n +35 test_read_format_isojoliet_rr.c | /bin/sh - -rm -rf /tmp/iso -mkdir /tmp/iso -mkdir /tmp/iso/dir -file="long-joliet-file-name.textfile" -echo "hello" >/tmp/iso/$file -ln /tmp/iso/$file /tmp/iso/hardlink -(cd /tmp/iso; ln -s $file symlink) -if [ "$(uname -s)" = "Linux" ]; then # gnu coreutils touch doesn't have -h -TZ=utc touch -afm -t 197001020000.01 /tmp/iso/hardlink /tmp/iso/$file /tmp/iso/dir -TZ=utc touch -afm -t 197001030000.02 /tmp/iso/symlink -TZ=utc touch -afm -t 197001020000.01 /tmp/iso -else -TZ=utc touch -afhm -t 197001020000.01 /tmp/iso/hardlink /tmp/iso/$file /tmp/iso/dir -TZ=utc touch -afhm -t 197001030000.02 /tmp/iso/symlink -TZ=utc touch -afhm -t 197001020000.01 /tmp/iso -fi -F=test_read_format_iso_joliet_rockridge.iso.Z -mkhybrid -J -uid 1 -gid 2 /tmp/iso | compress > $F -uuencode $F $F > $F.uu -exit 1 - */ - -DEFINE_TEST(test_read_format_isojoliet_rr) -{ - const char *refname = "test_read_format_iso_joliet_rockridge.iso.Z"; - struct archive_entry *ae; - struct archive *a; - const void *p; - size_t size; - int64_t offset; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualInt(0, archive_read_support_filter_all(a)); - assertEqualInt(0, archive_read_support_format_all(a)); - assertEqualInt(ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* First entry is '.' root directory. */ - assertEqualInt(0, archive_read_next_header(a, &ae)); - assertEqualString(".", archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(3, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualIntA(a, ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* A directory. */ - assertEqualInt(0, archive_read_next_header(a, &ae)); - assertEqualString("dir", archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(2, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* A regular file with two names ("hardlink" gets returned - * first, so it's not marked as a hardlink). */ - assertEqualInt(0, archive_read_next_header(a, &ae)); - assertEqualString("hardlink", - archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assert(archive_entry_hardlink(ae) == NULL); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(0, archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt(6, (int)size); - assertEqualInt(0, offset); - assertEqualMem(p, "hello\n", 6); - assertEqualInt(86401, archive_entry_mtime(ae)); - /* mkisofs records their access time. */ - /*assertEqualInt(86401, archive_entry_atime(ae));*/ - /* TODO: Actually, libarchive should be able to - * compute nlinks correctly even without RR - * extensions. See comments in libarchive source. */ - assertEqualInt(2, archive_entry_nlink(ae)); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Second name for the same regular file (this happens to be - * returned second, so does get marked as a hardlink). */ - assertEqualInt(0, archive_read_next_header(a, &ae)); - assertEqualString("long-joliet-file-name.textfile", - archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualString("hardlink", - archive_entry_hardlink(ae)); - assert(!archive_entry_size_is_set(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - /* TODO: See above. */ - assertEqualInt(2, archive_entry_nlink(ae)); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* A symlink to the regular file. */ - assertEqualInt(0, archive_read_next_header(a, &ae)); - assertEqualString("symlink", archive_entry_pathname(ae)); - assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); - assertEqualString("long-joliet-file-name.textfile", - archive_entry_symlink(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(172802, archive_entry_mtime(ae)); - assertEqualInt(172802, archive_entry_atime(ae)); - assertEqualInt(1, archive_entry_nlink(ae)); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* End of archive. */ - assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE); - - /* Close the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_isojoliet_versioned.c b/thirdparty/libarchive/libarchive/test/test_read_format_isojoliet_versioned.c deleted file mode 100644 index 011b5e296..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_isojoliet_versioned.c +++ /dev/null @@ -1,87 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * All rights reserved. - * - * Based on libarchive/test/test_read_format_isojoliet_bz2.c with - * bugs introduced by Andreas Henriksson for - * testing ISO9660 image with Joliet extension and versioned files. - * - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_isojoliet_bz2.c 201247 2009-12-30 05:59:21Z kientzle $"); - -/* - * The data for this testcase was provided by Mike Qin - * and created with Nero. - */ - -DEFINE_TEST(test_read_format_isojoliet_versioned) -{ - const char *refname = "test_read_format_iso_joliet_by_nero.iso.Z"; - struct archive_entry *ae; - struct archive *a; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualInt(0, archive_read_support_filter_all(a)); - assertEqualInt(0, archive_read_support_format_all(a)); - assertEqualInt(ARCHIVE_OK, - archive_read_set_option(a, "iso9660", "rockridge", NULL)); - assertEqualInt(ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* First entry is '.' root directory. */ - assertEqualInt(0, archive_read_next_header(a, &ae)); - assertEqualString(".", archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - - /* A directory. */ - assertEqualInt(0, archive_read_next_header(a, &ae)); - assertEqualString("test", archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* A regular file which is called test.txt and has - * ;1 appended to it because apparently Nero always - * appends versions to all files in the joliet extension. - * - * We test to make sure the version has been stripped. - */ - assertEqualInt(0, archive_read_next_header(a, &ae)); - assertEqualString("test/test.txt", - archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* End of archive. */ - assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS); - - /* Close the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_isorr_bz2.c b/thirdparty/libarchive/libarchive/test/test_read_format_isorr_bz2.c deleted file mode 100644 index fb4f4a853..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_isorr_bz2.c +++ /dev/null @@ -1,206 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_isorr_bz2.c 201247 2009-12-30 05:59:21Z kientzle $"); - -/* -PLEASE use old cdrtools; mkisofs version is 2.01. -This version mkisofs made wrong "SL" System Use Entry of RRIP. - -Execute the following command to rebuild the data for this program: - tail -n +34 test_read_format_isorr_bz2.c | /bin/sh - -rm -rf /tmp/iso -mkdir /tmp/iso -mkdir /tmp/iso/dir -echo "hello" >/tmp/iso/file -dd if=/dev/zero count=1 bs=12345678 >>/tmp/iso/file -ln /tmp/iso/file /tmp/iso/hardlink -(cd /tmp/iso; ln -s file symlink) -(cd /tmp/iso; ln -s /tmp/ symlink2) -(cd /tmp/iso; ln -s /tmp/../ symlink3) -(cd /tmp/iso; ln -s .././../tmp/ symlink4) -(cd /tmp/iso; ln -s .///file symlink5) -(cd /tmp/iso; ln -s /tmp//../ symlink6) -TZ=utc touch -afhm -t 197001020000.01 /tmp/iso /tmp/iso/file /tmp/iso/dir -TZ=utc touch -afhm -t 197001030000.02 /tmp/iso/symlink /tmp/iso/symlink5 -F=test_read_format_iso_rockridge.iso.Z -mkhybrid -R -uid 1 -gid 2 /tmp/iso | compress > $F -uuencode $F $F > $F.uu -exit 1 - */ - -DEFINE_TEST(test_read_format_isorr_bz2) -{ - const char *refname = "test_read_format_iso_rockridge.iso.Z"; - struct archive_entry *ae; - struct archive *a; - const void *p; - size_t size; - int64_t offset; - int i; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualInt(0, archive_read_support_filter_all(a)); - assertEqualInt(0, archive_read_support_format_all(a)); - assertEqualInt(ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Retrieve each of the 8 files on the ISO image and - * verify that each one is what we expect. */ - for (i = 0; i < 10; ++i) { - assertEqualInt(0, archive_read_next_header(a, &ae)); - - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - if (strcmp(".", archive_entry_pathname(ae)) == 0) { - /* '.' root directory. */ - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - /* Now, we read timestamp recorded by RRIP "TF". */ - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - /* Now, we read links recorded by RRIP "PX". */ - assertEqualInt(3, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualIntA(a, ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - } else if (strcmp("dir", archive_entry_pathname(ae)) == 0) { - /* A directory. */ - assertEqualString("dir", archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(2, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("file", archive_entry_pathname(ae)) == 0) { - /* A regular file. */ - assertEqualString("file", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(12345684, archive_entry_size(ae)); - assertEqualInt(0, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt(0, offset); - assertEqualMem(p, "hello\n", 6); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(2, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("hardlink", archive_entry_pathname(ae)) == 0) { - /* A hardlink to the regular file. */ - /* Note: If "hardlink" gets returned before "file", - * then "hardlink" will get returned as a regular file - * and "file" will get returned as the hardlink. - * This test should tolerate that, since it's a - * perfectly permissible thing for libarchive to do. */ - assertEqualString("hardlink", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualString("file", archive_entry_hardlink(ae)); - assertEqualInt(0, archive_entry_size_is_set(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(2, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("symlink", archive_entry_pathname(ae)) == 0) { - /* A symlink to the regular file. */ - assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); - assertEqualString("file", archive_entry_symlink(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(172802, archive_entry_mtime(ae)); - assertEqualInt(172802, archive_entry_atime(ae)); - assertEqualInt(1, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("symlink2", archive_entry_pathname(ae)) == 0) { - /* A symlink to /tmp (an absolute path) */ - assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); - assertEqualString("/tmp", archive_entry_symlink(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(1, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("symlink3", archive_entry_pathname(ae)) == 0) { - /* A symlink to /tmp/.. (with a ".." component) */ - assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); - assertEqualString("/tmp/..", archive_entry_symlink(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(1, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("symlink4", archive_entry_pathname(ae)) == 0) { - /* A symlink to a path with ".." and "." components */ - assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); - assertEqualString(".././../tmp", - archive_entry_symlink(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(1, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("symlink5", archive_entry_pathname(ae)) == 0) { - /* A symlink to the regular file with "/" components. */ - assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); - assertEqualString(".///file", archive_entry_symlink(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(172802, archive_entry_mtime(ae)); - assertEqualInt(172802, archive_entry_atime(ae)); - assertEqualInt(1, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("symlink6", archive_entry_pathname(ae)) == 0) { - /* A symlink to /tmp//.. - * (with "/" and ".." components) */ - assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); - assertEqualString("/tmp//..", archive_entry_symlink(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(1, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else { - failure("Saw a file that shouldn't have been there"); - assertEqualString(archive_entry_pathname(ae), ""); - } - } - - /* End of archive. */ - assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE); - - /* Close the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_isorr_ce.c b/thirdparty/libarchive/libarchive/test/test_read_format_isorr_ce.c deleted file mode 100644 index 1e57acb76..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_isorr_ce.c +++ /dev/null @@ -1,226 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2009 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_isorr_ce.c 201247 2009-12-30 05:59:21Z kientzle $"); - -/* -Execute the following command to rebuild the data for this program: - tail -n +32 test_read_format_isorr_ce.c | /bin/sh - -dirname=/tmp/iso -# -rm -rf $dirname -mkdir $dirname -# -num=0 -file="" -while [ $num -lt 150 ] -do - num=$((num+1)) - file="a$file" -done -# -num=0 -while [ $num -lt 3 ] -do - num=$((num+1)) - file="a$file" - echo "hello $((num+150))" > $dirname/$file - dd if=/dev/zero count=1 bs=4080 >> $dirname/$file - (cd $dirname; ln -s $file sym$num) -done -# -mkdir $dirname/dir -# -time1="197001020000.01" -time2="197001030000.02" -TZ=utc touch -afhm -t $time1 $dirname/dir $dirname/aaaa* -TZ=utc touch -afhm -t $time2 $dirname/sym* -TZ=utc touch -afhm -t $time1 $dirname -# -F=test_read_format_iso_rockridge_ce.iso.Z -mkisofs -R -uid 1 -gid 2 $dirname | compress > $F -uuencode $F $F > $F.uu -rm -rf $dirname -exit 1 - */ - -/* - * Test reading SUSP "CE" extension is works fine. - */ - -static void -mkpath(char *p, int len) -{ - int i; - - for (i = 0; i < len; i++) - p[i] = 'a'; - p[len] = '\0'; -} - -DEFINE_TEST(test_read_format_isorr_ce) -{ - const char *refname = "test_read_format_iso_rockridge_ce.iso.Z"; - char path1[160]; - char path2[160]; - char path3[160]; - struct archive_entry *ae; - struct archive *a; - const void *p; - size_t size; - int64_t offset; - int i; - - mkpath(path1, 151); - mkpath(path2, 152); - mkpath(path3, 153); - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualInt(0, archive_read_support_filter_all(a)); - assertEqualInt(0, archive_read_support_format_all(a)); - assertEqualInt(ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Retrieve each of the 8 files on the ISO image and - * verify that each one is what we expect. */ - for (i = 0; i < 8; ++i) { - assertEqualInt(0, archive_read_next_header(a, &ae)); - - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - if (strcmp(".", archive_entry_pathname(ae)) == 0) { - /* '.' root directory. */ - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - /* Now, we read timestamp recorded by RRIP "TF". */ - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - /* Now, we read links recorded by RRIP "PX". */ - assertEqualInt(3, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualIntA(a, ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - } else if (strcmp("dir", archive_entry_pathname(ae)) == 0) { - /* A directory. */ - assertEqualString("dir", archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(2, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp(path1, archive_entry_pathname(ae)) == 0) { - /* A regular file. */ - assertEqualString(path1, archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(4090, archive_entry_size(ae)); - assertEqualInt(0, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt(0, offset); - assertEqualMem(p, "hello 151\n", 10); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(1, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp(path2, archive_entry_pathname(ae)) == 0) { - /* A regular file. */ - assertEqualString(path2, archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(4090, archive_entry_size(ae)); - assertEqualInt(0, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt(0, offset); - assertEqualMem(p, "hello 152\n", 10); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(1, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp(path3, archive_entry_pathname(ae)) == 0) { - /* A regular file. */ - assertEqualString(path3, archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(4090, archive_entry_size(ae)); - assertEqualInt(0, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt(0, offset); - assertEqualMem(p, "hello 153\n", 10); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(1, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("sym1", archive_entry_pathname(ae)) == 0) { - /* A symlink to the regular file. */ - assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); - assertEqualString(path1, archive_entry_symlink(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(172802, archive_entry_mtime(ae)); - assertEqualInt(1, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("sym2", archive_entry_pathname(ae)) == 0) { - /* A symlink to the regular file. */ - assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); - assertEqualString(path2, archive_entry_symlink(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(172802, archive_entry_mtime(ae)); - assertEqualInt(1, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("sym3", archive_entry_pathname(ae)) == 0) { - /* A symlink to the regular file. */ - assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); - assertEqualString(path3, archive_entry_symlink(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(172802, archive_entry_mtime(ae)); - assertEqualInt(1, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else { - failure("Saw a file that shouldn't have been there"); - assertEqualString(archive_entry_pathname(ae), ""); - } - } - - /* End of archive. */ - assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE); - - /* Close the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_isorr_new_bz2.c b/thirdparty/libarchive/libarchive/test/test_read_format_isorr_new_bz2.c deleted file mode 100644 index 4c1b5692e..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_isorr_new_bz2.c +++ /dev/null @@ -1,207 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_isorr_new_bz2.c 201247 2009-12-30 05:59:21Z kientzle $"); - - -/* -PLEASE use latest cdrtools at least mkisofs version is 2.01.01a63 or later. -Old version mkisofs made wrong "SL" System Use Entry of RRIP. - -Execute the following command to rebuild the data for this program: - tail -n +34 test_read_format_isorr_new_bz2.c | /bin/sh - -rm -rf /tmp/iso -mkdir /tmp/iso -mkdir /tmp/iso/dir -echo "hello" >/tmp/iso/file -dd if=/dev/zero count=1 bs=12345678 >>/tmp/iso/file -ln /tmp/iso/file /tmp/iso/hardlink -(cd /tmp/iso; ln -s file symlink) -(cd /tmp/iso; ln -s /tmp/ symlink2) -(cd /tmp/iso; ln -s /tmp/../ symlink3) -(cd /tmp/iso; ln -s .././../tmp/ symlink4) -(cd /tmp/iso; ln -s .///file symlink5) -(cd /tmp/iso; ln -s /tmp//../ symlink6) -TZ=utc touch -afhm -t 197001020000.01 /tmp/iso /tmp/iso/file /tmp/iso/dir -TZ=utc touch -afhm -t 197001030000.02 /tmp/iso/symlink -F=test_read_format_iso_rockridge_new.iso.Z -mkhybrid -R -uid 1 -gid 2 /tmp/iso | compress > $F -uuencode $F $F > $F.uu -exit 1 - */ - -DEFINE_TEST(test_read_format_isorr_new_bz2) -{ - const char *refname = "test_read_format_iso_rockridge_new.iso.Z"; - struct archive_entry *ae; - struct archive *a; - const void *p; - size_t size; - int64_t offset; - int i; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualInt(0, archive_read_support_filter_all(a)); - assertEqualInt(0, archive_read_support_format_all(a)); - assertEqualInt(ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Retrieve each of the 8 files on the ISO image and - * verify that each one is what we expect. */ - for (i = 0; i < 10; ++i) { - assertEqualInt(0, archive_read_next_header(a, &ae)); - - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - if (strcmp(".", archive_entry_pathname(ae)) == 0) { - /* '.' root directory. */ - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - /* Now, we read timestamp recorded by RRIP "TF". */ - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - /* Now, we read links recorded by RRIP "PX". */ - assertEqualInt(3, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualIntA(a, ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - } else if (strcmp("dir", archive_entry_pathname(ae)) == 0) { - /* A directory. */ - assertEqualString("dir", archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(2, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("file", archive_entry_pathname(ae)) == 0) { - /* A regular file. */ - assertEqualString("file", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(12345684, archive_entry_size(ae)); - assertEqualInt(0, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt(0, offset); - assertEqualMem(p, "hello\n", 6); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(2, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("hardlink", archive_entry_pathname(ae)) == 0) { - /* A hardlink to the regular file. */ - /* Note: If "hardlink" gets returned before "file", - * then "hardlink" will get returned as a regular file - * and "file" will get returned as the hardlink. - * This test should tolerate that, since it's a - * perfectly permissible thing for libarchive to do. */ - assertEqualString("hardlink", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualString("file", archive_entry_hardlink(ae)); - assertEqualInt(0, archive_entry_size_is_set(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(2, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("symlink", archive_entry_pathname(ae)) == 0) { - /* A symlink to the regular file. */ - assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); - assertEqualString("file", archive_entry_symlink(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(172802, archive_entry_mtime(ae)); - assertEqualInt(172802, archive_entry_atime(ae)); - assertEqualInt(1, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("symlink2", archive_entry_pathname(ae)) == 0) { - /* A symlink to /tmp/ (an absolute path) */ - assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); - assertEqualString("/tmp/", archive_entry_symlink(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(1, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("symlink3", archive_entry_pathname(ae)) == 0) { - /* A symlink to /tmp/../ (with a ".." component) */ - assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); - assertEqualString("/tmp/../", archive_entry_symlink(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(1, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("symlink4", archive_entry_pathname(ae)) == 0) { - /* A symlink to a path with ".." and "." components */ - assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); - assertEqualString(".././../tmp/", - archive_entry_symlink(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(1, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("symlink5", archive_entry_pathname(ae)) == 0) { - /* A symlink to the regular file with "/" components. */ - assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); - assertEqualString(".///file", archive_entry_symlink(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(172802, archive_entry_mtime(ae)); - assertEqualInt(172802, archive_entry_atime(ae)); - assertEqualInt(1, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("symlink6", archive_entry_pathname(ae)) == 0) { - /* A symlink to /tmp//../ - * (with "/" and ".." components) */ - assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); - assertEqualString("/tmp//../", archive_entry_symlink(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(1, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else { - failure("Saw a file that shouldn't have been there"); - assertEqualString(archive_entry_pathname(ae), ""); - } - } - - /* End of archive. */ - assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE); - - /* Close the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_isorr_rr_moved.c b/thirdparty/libarchive/libarchive/test/test_read_format_isorr_rr_moved.c deleted file mode 100644 index 693caef62..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_isorr_rr_moved.c +++ /dev/null @@ -1,273 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2009 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_isorr_rr_moved.c 201247 2009-12-30 05:59:21Z kientzle $"); - -/* -Execute the following command to rebuild the data for this program: - tail -n +32 test_read_format_isorr_rr_moved.c | /bin/sh - -dirname=/tmp/iso -rm -rf $dirname -mkdir -p $dirname/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dir10 -echo "hello" >$dirname/file -dd if=/dev/zero count=1 bs=12345678 >>$dirname/file -deepfile=$dirname/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dir10/deep -echo "hello" >$deepfile -dd if=/dev/zero count=1 bs=12345678 >>$deepfile -time="197001020000.01" -TZ=utc touch -afhm -t $time $deepfile -TZ=utc touch -afhm -t $time $dirname/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dir10 -TZ=utc touch -afhm -t $time $dirname/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9 -TZ=utc touch -afhm -t $time $dirname/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8 -TZ=utc touch -afhm -t $time $dirname/dir1/dir2/dir3/dir4/dir5/dir6/dir7 -TZ=utc touch -afhm -t $time $dirname/dir1/dir2/dir3/dir4/dir5/dir6 -TZ=utc touch -afhm -t $time $dirname/dir1/dir2/dir3/dir4/dir5 -TZ=utc touch -afhm -t $time $dirname/dir1/dir2/dir3/dir4 -TZ=utc touch -afhm -t $time $dirname/dir1/dir2/dir3 -TZ=utc touch -afhm -t $time $dirname/dir1/dir2 -TZ=utc touch -afhm -t $time $dirname/dir1 -TZ=utc touch -afhm -t $time $dirname/file -TZ=utc touch -afhm -t $time $dirname -F=test_read_format_isorr_rockridge_moved.iso.Z -mkhybrid -R -uid 1 -gid 2 $dirname | compress > $F -uuencode $F $F > $F.uu -exit 1 - */ - -DEFINE_TEST(test_read_format_isorr_rr_moved) -{ - const char *refname = "test_read_format_iso_rockridge_rr_moved.iso.Z"; - struct archive_entry *ae; - struct archive *a; - const void *p; - size_t size; - int64_t offset; - int i; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualInt(0, archive_read_support_filter_all(a)); - assertEqualInt(0, archive_read_support_format_all(a)); - assertEqualInt(ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Retrieve each of the 8 files on the ISO image and - * verify that each one is what we expect. */ - for (i = 0; i < 13; ++i) { - assertEqualInt(0, archive_read_next_header(a, &ae)); - - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - if (strcmp(".", archive_entry_pathname(ae)) == 0) { - /* '.' root directory. */ - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - /* Now, we read timestamp recorded by RRIP "TF". */ - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - /* Now, we read links recorded by RRIP "PX". */ - assertEqualInt(3, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualIntA(a, ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - } else if (strcmp("dir1", archive_entry_pathname(ae)) == 0) { - /* A directory. */ - assertEqualString("dir1", archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("dir1/dir2", - archive_entry_pathname(ae)) == 0) { - /* A directory. */ - assertEqualString("dir1/dir2", - archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("dir1/dir2/dir3", - archive_entry_pathname(ae)) == 0) { - /* A directory. */ - assertEqualString("dir1/dir2/dir3", - archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("dir1/dir2/dir3/dir4", - archive_entry_pathname(ae)) == 0) { - /* A directory. */ - assertEqualString("dir1/dir2/dir3/dir4", - archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("dir1/dir2/dir3/dir4/dir5", - archive_entry_pathname(ae)) == 0) { - /* A directory. */ - assertEqualString("dir1/dir2/dir3/dir4/dir5", - archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("dir1/dir2/dir3/dir4/dir5/dir6", - archive_entry_pathname(ae)) == 0) { - /* A directory. */ - assertEqualString("dir1/dir2/dir3/dir4/dir5/dir6", - archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("dir1/dir2/dir3/dir4/dir5/dir6/dir7", - archive_entry_pathname(ae)) == 0) { - /* A directory. */ - assertEqualString("dir1/dir2/dir3/dir4/dir5/dir6/dir7", - archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("dir1/dir2/dir3/dir4/dir5/dir6/dir7" - "/dir8", - archive_entry_pathname(ae)) == 0) { - /* A directory. */ - assertEqualString("dir1/dir2/dir3/dir4/dir5/dir6/dir7" - "/dir8", - archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("dir1/dir2/dir3/dir4/dir5/dir6/dir7" - "/dir8/dir9", - archive_entry_pathname(ae)) == 0) { - /* A directory. */ - assertEqualString("dir1/dir2/dir3/dir4/dir5/dir6/dir7" - "/dir8/dir9", - archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("dir1/dir2/dir3/dir4/dir5/dir6/dir7" - "/dir8/dir9/dir10", - archive_entry_pathname(ae)) == 0) { - /* A directory. */ - assertEqualString("dir1/dir2/dir3/dir4/dir5/dir6/dir7" - "/dir8/dir9/dir10", - archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(2, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("file", archive_entry_pathname(ae)) == 0) { - /* A regular file. */ - assertEqualString("file", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(12345684, archive_entry_size(ae)); - assertEqualInt(0, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt(0, offset); - assertEqualMem(p, "hello\n", 6); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(1, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("dir1/dir2/dir3/dir4/dir5/dir6/dir7" - "/dir8/dir9/dir10/deep", - archive_entry_pathname(ae)) == 0) { - /* A regular file. */ - assertEqualString("dir1/dir2/dir3/dir4/dir5/dir6/dir7" - "/dir8/dir9/dir10/deep", - archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(12345684, archive_entry_size(ae)); - assertEqualInt(0, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt(0, offset); - assertEqualMem(p, "hello\n", 6); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(1, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else { - failure("Saw a file that shouldn't have been there"); - assertEqualString(archive_entry_pathname(ae), ""); - } - } - - /* End of archive. */ - assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE); - - /* Close the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_isozisofs_bz2.c b/thirdparty/libarchive/libarchive/test/test_read_format_isozisofs_bz2.c deleted file mode 100644 index adf962427..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_isozisofs_bz2.c +++ /dev/null @@ -1,190 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_isozisofs_bz2.c 201247 2009-12-30 05:59:21Z kientzle $"); - -/* -Execute the following command to rebuild the data for this program: - tail -n +32 test_read_format_isozisofs_bz2.c | /bin/sh - -rm -rf /tmp/iso /tmp/ziso -mkdir /tmp/iso -mkdir /tmp/iso/dir -echo "hello" >/tmp/iso/file -dd if=/dev/zero count=1 bs=12345678 >>/tmp/iso/file -ln /tmp/iso/file /tmp/iso/hardlink -(cd /tmp/iso; ln -s file symlink) -(cd /tmp/iso; ln -s /tmp/ symlink2) -(cd /tmp/iso; ln -s /tmp/../ symlink3) -(cd /tmp/iso; ln -s .././../tmp/ symlink4) -TZ=utc touch -afhm -t 197001020000.01 /tmp/iso /tmp/iso/file /tmp/iso/dir -TZ=utc touch -afhm -t 197001030000.02 /tmp/iso/symlink -mkzftree /tmp/iso /tmp/ziso -TZ=utc touch -afhm -t 197001020000.01 /tmp/ziso /tmp/ziso/file /tmp/ziso/dir -TZ=utc touch -afhm -t 197001030000.02 /tmp/ziso/symlink -F=test_read_format_iso_zisofs.iso.Z -mkhybrid -R -uid 1 -gid 2 -z /tmp/ziso | compress > $F -uuencode $F $F > $F.uu -exit 1 - - */ - -DEFINE_TEST(test_read_format_isozisofs_bz2) -{ - const char *refname = "test_read_format_iso_zisofs.iso.Z"; - struct archive_entry *ae; - struct archive *a; - const void *p; - size_t size; - int64_t offset; - int i; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualInt(0, archive_read_support_filter_all(a)); - assertEqualInt(0, archive_read_support_format_all(a)); - assertEqualInt(ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Retrieve each of the 8 files on the ISO image and - * verify that each one is what we expect. */ - for (i = 0; i < 8; ++i) { - assertEqualInt(0, archive_read_next_header(a, &ae)); - - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - if (strcmp(".", archive_entry_pathname(ae)) == 0) { - /* '.' root directory. */ - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - /* Now, we read timestamp recorded by RRIP "TF". */ - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - /* Now, we read links recorded by RRIP "PX". */ - assertEqualInt(3, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualIntA(a, ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - } else if (strcmp("dir", archive_entry_pathname(ae)) == 0) { - /* A directory. */ - assertEqualString("dir", archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(2, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("file", archive_entry_pathname(ae)) == 0) { - int r; - /* A regular file. */ - assertEqualString("file", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(12345684, archive_entry_size(ae)); - r = archive_read_data_block(a, &p, &size, &offset); - if (r == ARCHIVE_FAILED) { - skipping("Can't read body of ZISOFS entry."); - } else { - assertEqualInt(ARCHIVE_OK, r); - assertEqualInt(0, offset); - assertEqualMem(p, "hello\n", 6); - } - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(2, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("hardlink", archive_entry_pathname(ae)) == 0) { - /* A hardlink to the regular file. */ - /* Note: If "hardlink" gets returned before "file", - * then "hardlink" will get returned as a regular file - * and "file" will get returned as the hardlink. - * This test should tolerate that, since it's a - * perfectly permissible thing for libarchive to do. */ - assertEqualString("hardlink", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualString("file", archive_entry_hardlink(ae)); - assertEqualInt(0, archive_entry_size_is_set(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(2, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("symlink", archive_entry_pathname(ae)) == 0) { - /* A symlink to the regular file. */ - assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); - assertEqualString("file", archive_entry_symlink(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(172802, archive_entry_mtime(ae)); - assertEqualInt(172802, archive_entry_atime(ae)); - assertEqualInt(1, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("symlink2", archive_entry_pathname(ae)) == 0) { - /* A symlink to /tmp (an absolute path) */ - assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); - assertEqualString("/tmp", archive_entry_symlink(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(1, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("symlink3", archive_entry_pathname(ae)) == 0) { - /* A symlink to /tmp/.. (with a ".." component) */ - assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); - assertEqualString("/tmp/..", archive_entry_symlink(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(1, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else if (strcmp("symlink4", archive_entry_pathname(ae)) == 0) { - /* A symlink to a path with ".." and "." components */ - assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); - assertEqualString(".././../tmp", - archive_entry_symlink(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(1, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } else { - failure("Saw a file that shouldn't have been there"); - assertEqualString(archive_entry_pathname(ae), ""); - } - } - - /* End of archive. */ - assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE); - - /* Close the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_lha.c b/thirdparty/libarchive/libarchive/test/test_read_format_lha.c deleted file mode 100644 index 6a53976c2..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_lha.c +++ /dev/null @@ -1,294 +0,0 @@ -/*- - * Copyright (c) 2008, 2010 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD"); - -/* -Execute the following command to rebuild the data for this program: - tail -n +32 test_read_format_lha.c | /bin/sh - -#/bin/sh -# -# How to make test data. -# -# Temporary directory. -base=/tmp/lha -# Owner id -owner=1001 -# Group id -group=1001 -# -# Make contents of a lha archive. -# -rm -rf ${base} -mkdir ${base} -mkdir ${base}/dir -cat > ${base}/file1 << END - file 1 contents -hello -hello -hello -END -cat > ${base}/file2 << END - file 2 contents -hello -hello -hello -hello -hello -hello -END -mkdir ${base}/dir2 -# -# Set up a file mode, owner and group. -# -(cd ${base}/dir2; ln -s ../file1 symlink1) -(cd ${base}/dir2; ln -s ../file2 symlink2) -(cd ${base}; chown ${owner}:${group} dir file1 file2) -(cd ${base}; chown -h ${owner}:${group} dir2 dir2/symlink1 dir2/symlink2) -(cd ${base}; chmod 0750 dir) -(cd ${base}; chmod 0755 dir2) -(cd ${base}; chmod 0755 dir2/symlink1 dir2/symlink2) -(cd ${base}; chmod 0644 file1) -(cd ${base}; chmod 0666 file2) -TZ=utc touch -afhm -t 197001030000.02 ${base}/dir2/symlink1 ${base}/dir2/symlink2 -TZ=utc touch -afhm -t 197001020000.01 ${base}/dir ${base}/dir2 -TZ=utc touch -afhm -t 197001020000.01 ${base}/file1 ${base}/file2 -# -# Make several lha archives. -# -# Make a lha archive with header level 0 -lha0=test_read_format_lha_header0.lzh -(cd ${base}; lha c0q ${lha0} dir file1 file2 dir2) -# Make a lha archive with header level 1 -lha1=test_read_format_lha_header1.lzh -(cd ${base}; lha c1q ${lha1} dir file1 file2 dir2) -# Make a lha archive with header level 2 -lha2=test_read_format_lha_header2.lzh -(cd ${base}; lha c2q ${lha2} dir file1 file2 dir2) -# Make a lha archive with -lh6- compression mode -lha3=test_read_format_lha_lh6.lzh -(cd ${base}; lha co6q ${lha3} dir file1 file2 dir2) -# Make a lha archive with -lh7- compression mode -lha4=test_read_format_lha_lh7.lzh -(cd ${base}; lha co7q ${lha4} dir file1 file2 dir2) -# Make a lha archive with -lh0- no compression -lha5=test_read_format_lha_lh0.lzh -(cd ${base}; lha czq ${lha5} dir file1 file2 dir2) -# make a lha archive with junk data -lha6=test_read_format_lha_withjunk.lzh -(cd ${base}; cp ${lha2} ${lha6}; echo "junk data!!!!" >> ${lha6}) -# -uuencode ${base}/${lha0} ${lha0} > ${lha0}.uu -uuencode ${base}/${lha1} ${lha1} > ${lha1}.uu -uuencode ${base}/${lha2} ${lha2} > ${lha2}.uu -uuencode ${base}/${lha3} ${lha3} > ${lha3}.uu -uuencode ${base}/${lha4} ${lha4} > ${lha4}.uu -uuencode ${base}/${lha5} ${lha5} > ${lha5}.uu -uuencode ${base}/${lha6} ${lha5} > ${lha5}.uu -uuencode ${base}/${lha6} ${lha6} > ${lha6}.uu -# -# Finish making test data. -exit 1 -*/ - -static const char file1[] = { -" file 1 contents\n" -"hello\n" -"hello\n" -"hello\n" -}; -#define file1_size (sizeof(file1)-1) -static const char file2[] = { -" file 2 contents\n" -"hello\n" -"hello\n" -"hello\n" -"hello\n" -"hello\n" -"hello\n" -}; -#define file2_size (sizeof(file2)-1) - -static void -verify(const char *refname, int posix) -{ - struct archive_entry *ae; - struct archive *a; - char buff[128]; - const void *pv; - size_t s; - int64_t o; - int uid, gid; - - if (posix) - uid = gid = 1001; - else - uid = gid = 0; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify directory1. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - if (posix) - assertEqualInt((AE_IFDIR | 0750), archive_entry_mode(ae)); - else - assertEqualInt((AE_IFDIR | 0755), archive_entry_mode(ae)); - assertEqualString("dir/", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(uid, archive_entry_uid(ae)); - assertEqualInt(gid, archive_entry_gid(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualIntA(a, ARCHIVE_EOF, - archive_read_data_block(a, &pv, &s, &o)); - assertEqualInt(s, 0); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Verify directory2. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFDIR | 0755), archive_entry_mode(ae)); - assertEqualString("dir2/", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(uid, archive_entry_uid(ae)); - assertEqualInt(gid, archive_entry_gid(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualIntA(a, ARCHIVE_EOF, - archive_read_data_block(a, &pv, &s, &o)); - assertEqualInt(s, 0); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - if (posix) { - /* Verify symbolic link file1. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFLNK | 0755), archive_entry_mode(ae)); - assertEqualString("dir2/symlink1", archive_entry_pathname(ae)); - assertEqualString("../file1", archive_entry_symlink(ae)); - assertEqualInt(172802, archive_entry_mtime(ae)); - assertEqualInt(uid, archive_entry_uid(ae)); - assertEqualInt(gid, archive_entry_gid(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Verify symbolic link file2. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFLNK | 0755), archive_entry_mode(ae)); - assertEqualString("dir2/symlink2", archive_entry_pathname(ae)); - assertEqualString("../file2", archive_entry_symlink(ae)); - assertEqualInt(172802, archive_entry_mtime(ae)); - assertEqualInt(uid, archive_entry_uid(ae)); - assertEqualInt(gid, archive_entry_gid(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - } - - /* Verify regular file1. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("file1", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(uid, archive_entry_uid(ae)); - assertEqualInt(gid, archive_entry_gid(ae)); - assertEqualInt(file1_size, archive_entry_size(ae)); - assertEqualInt(file1_size, archive_read_data(a, buff, file1_size)); - assertEqualMem(buff, file1, file1_size); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Verify regular file2. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - if (posix) - assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae)); - else - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("file2", archive_entry_pathname(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(uid, archive_entry_uid(ae)); - assertEqualInt(gid, archive_entry_gid(ae)); - assertEqualInt(file2_size, archive_entry_size(ae)); - assertEqualInt(file2_size, archive_read_data(a, buff, file2_size)); - assertEqualMem(buff, file2, file2_size); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Verify the number of files read. */ - if (posix) { - assertEqualInt(6, archive_file_count(a)); - } else { - assertEqualInt(4, archive_file_count(a)); - } - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify the number of files read. */ - if (posix) { - assertEqualInt(6, archive_file_count(a)); - } else { - assertEqualInt(4, archive_file_count(a)); - } - - /* Verify encryption status */ - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_LHA, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_lha) -{ - /* Verify Header level 0 */ - verify("test_read_format_lha_header0.lzh", 1); - /* Verify Header level 1 */ - verify("test_read_format_lha_header1.lzh", 1); - /* Verify Header level 2 */ - verify("test_read_format_lha_header2.lzh", 1); - /* Verify Header level 3 - * This test data can be made in Windows only. */ - verify("test_read_format_lha_header3.lzh", 0); - /* Verify compression mode -lh6- */ - verify("test_read_format_lha_lh6.lzh", 1); - /* Verify compression mode -lh7- */ - verify("test_read_format_lha_lh7.lzh", 1); - /* Verify no compression -lh0- */ - verify("test_read_format_lha_lh0.lzh", 1); - /* Verify an lha file with junk data. */ - verify("test_read_format_lha_withjunk.lzh", 1); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_lha_bugfix_0.c b/thirdparty/libarchive/libarchive/test/test_read_format_lha_bugfix_0.c deleted file mode 100644 index 2b4160b32..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_lha_bugfix_0.c +++ /dev/null @@ -1,76 +0,0 @@ -/*- - * Copyright (c) 2014 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD"); - -DEFINE_TEST(test_read_format_lha_bugfix_0) -{ - const char *refname = "test_read_format_lha_bugfix_0.lzh"; - struct archive_entry *ae; - struct archive *a; - const void *pv; - size_t s; - int64_t o; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify directory1. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("f", archive_entry_pathname(ae)); - assertEqualInt(776, archive_entry_size(ae)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_data_block(a, &pv, &s, &o)); - assertEqualInt(s, 776); - assertEqualIntA(a, ARCHIVE_EOF, - archive_read_data_block(a, &pv, &s, &o)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), - ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify the number of files read. */ - assertEqualInt(1, archive_file_count(a)); - - /* Verify encryption status */ - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), - ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_LHA, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_lha_bugfix_0.lzh.uu b/thirdparty/libarchive/libarchive/test/test_read_format_lha_bugfix_0.lzh.uu deleted file mode 100644 index 34f5fb58c..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_lha_bugfix_0.lzh.uu +++ /dev/null @@ -1,19 +0,0 @@ -begin 644 test_read_format_lha_bugfix_0.lzh -M+P`M;&@U+7T"```(`P``$D*U4R`"],%5!0``,;<$``%F!0!0I($'`%$4`/4! -M```#!FS;%+&?H/SZ_`=2K$ -M-,5VE5(EVT9P)2WPS:$ET@K!861T3'*N&!9P1"!)<58 -M77$ZCA;PVAGN>:E@6E`;&<>"ZC!Y63H&,DLG*7"!89A!JAN$L?(RDL_4`*!5 -MFWE%HD>>J)M8]^%^EM_SX;PSL4PVL.5A30:MQ@.E>3">;0[^XNA:([UUF>FV -MLJS"HLP=\5-Y)HP)8800U81@-`7,)<)ZD6)*P7'5$BBE@NYFR%CS>"PRZ6`Z -M8JPQ)&7:HGF$^/FQGF_PQ;'VBN?WET90#=W4S(2%Q9+!.>\`MR,`]Y;GQNU* -MFV]2K+=B$EZ2M6[KKUMXA2,NK[\3?3>^;:NB(+]2)S/?J*C<=Y'\SN?1Z7-T -M."&"A!R%6"V5"ZI&W[UZFT>T$?;.=#MVH9@V=/!#*$).G2G(Y4.Q*[1AVL?6*_:94#("2J<.Q< -M2F+D][."[K,$ -M^*>G*P8XG*=--.O:V?F58URE?C"9Q>FRRHW0RHQTQ\`IS.%ZJ:J2YKXH6C:+ -MHAD@<2N;;[H(/YMP]]_/=25P$K"=;&?2)-\6HA5V6U"%Z`/3MMKL6>%KKCGI -*+1"40KV_/\%````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_lha_filename.c b/thirdparty/libarchive/libarchive/test/test_read_format_lha_filename.c deleted file mode 100644 index 126a8704c..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_lha_filename.c +++ /dev/null @@ -1,221 +0,0 @@ -/*- - * Copyright (c) 2011 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD"); - -#include - -static void -test_read_format_lha_filename_CP932_eucJP(const char *refname) -{ - struct archive *a; - struct archive_entry *ae; - - /* - * Read LHA filename in ja_JP.eucJP. - */ - if (NULL == setlocale(LC_ALL, "ja_JP.eucJP")) { - skipping("ja_JP.eucJP locale not available on this system."); - return; - } - - /* - * Create a read object only for a test that platform support - * a character-set conversion because we can read a character-set - * of filenames from the header of an lha archive file and so we - * want to test that it works well. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP932")) { - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - skipping("This system cannot convert character-set" - " from CP932 to eucJP."); - return; - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xB4\xC1\xBB\xFA\x2E\x74\x78\x74", - archive_entry_pathname(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xC9\xBD\x2E\x74\x78\x74", archive_entry_pathname(ae)); - assertEqualInt(4, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_LHA, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -static void -test_read_format_lha_filename_CP932_UTF8(const char *refname) -{ - struct archive *a; - struct archive_entry *ae; - - /* - * Read LHA filename in en_US.UTF-8. - */ - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("en_US.UTF-8 locale not available on this system."); - return; - } - /* - * Create a read object only for a test that platform support - * a character-set conversion because we can read a character-set - * of filenames from the header of an lha archive file and so we - * want to test that it works well. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP932")) { - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - skipping("This system cannot convert character-set" - " from CP932 to UTF-8."); - return; - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xE6\xBC\xA2\xE5\xAD\x97\x2E\x74\x78\x74", - archive_entry_pathname(ae)); - assertEqualInt(8, archive_entry_size(ae)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xE8\xA1\xA8\x2E\x74\x78\x74", - archive_entry_pathname(ae)); - assertEqualInt(4, archive_entry_size(ae)); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_LHA, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -#if defined(_WIN32) && !defined(__CYGWIN__) -static void -test_read_format_lha_filename_CP932_Windows(const char *refname) -{ - struct archive *a; - struct archive_entry *ae; - - /* - * Read LHA filename in jpn on Windows. - */ - if (NULL == setlocale(LC_ALL, "jpn")) { - skipping("jpn locale not available on this system."); - return; - } - /* - * Create a read object only for a test that platform support - * a character-set conversion because we can read a character-set - * of filenames from the header of an lha archive file and so we - * want to test that it works well. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\x8A\xBF\x8E\x9A\x2E\x74\x78\x74", - archive_entry_pathname(ae)); - assertEqualInt(8, archive_entry_size(ae)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\x95\x5C\x2E\x74\x78\x74", archive_entry_pathname(ae)); - assertEqualInt(4, archive_entry_size(ae)); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_LHA, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} -#else -/* Stub */ -static void -test_read_format_lha_filename_CP932_Windows(const char *refname) -{ - (void)refname; /* UNUSED */ -} -#endif - -DEFINE_TEST(test_read_format_lha_filename) -{ - /* A sample file was created with LHA32.EXE through UNLHA.DLL. */ - const char *refname = "test_read_format_lha_filename_cp932.lzh"; - - extract_reference_file(refname); - - test_read_format_lha_filename_CP932_eucJP(refname); - test_read_format_lha_filename_CP932_UTF8(refname); - test_read_format_lha_filename_CP932_Windows(refname); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_lha_filename_cp932.lzh.uu b/thirdparty/libarchive/libarchive/test/test_read_format_lha_filename_cp932.lzh.uu deleted file mode 100644 index 151701460..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_lha_filename_cp932.lzh.uu +++ /dev/null @@ -1,7 +0,0 @@ -begin 644 test_read_format_lha_cp932.lzh -M30`M;&@P+0@````(````*:2#32`"&4A-!P!&I`,```L``8J_CIHN='AT&P!! -M-'"`))KERP%TJNDQFN7+`72JZ3&:Y'0;`$&:91,VFN7+ ->`:#K$3V:Y - -static void -test_read_format_lha_filename_UTF16_UTF8(const char *refname) -{ - struct archive *a; - struct archive_entry *ae; - - /* - * Read LHA filename in en_US.UTF-8. - */ - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("en_US.UTF-8 locale not available on this system."); - return; - } - /* - * Create a read object only for a test that platform support - * a character-set conversion because we can read a character-set - * of filenames from the header of an lha archive file and so we - * want to test that it works well. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP932")) { - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - skipping("This system cannot convert character-set" - " from CP932 to UTF-8."); - return; - } - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=UTF-16")) { - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - skipping("This system cannot convert character-set" - " from UTF-16 to UTF-8."); - return; - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Note that usual Japanese filenames are tested in other cases */ -#if defined(__APPLE__) - /* NFD normalization */ - /* U:O:A:u:o:a: */ - #define UMLAUT_DIRNAME "\x55\xcc\x88\x4f\xcc\x88\x41\xcc\x88\x75\xcc\x88\x6f"\ - "\xcc\x88\x61\xcc\x88/" - /* a:o:u:A:O:U:.txt */ - #define UMLAUT_FNAME "\x61\xcc\x88\x6f\xcc\x88\x75\xcc\x88\x41\xcc\x88"\ - "\x4f\xcc\x88\x55\xcc\x88.txt" -#else - /* NFC normalization */ - /* U:O:A:u:o:a: */ - #define UMLAUT_DIRNAME "\xc3\x9c\xc3\x96\xc3\x84\xc3\xbc\xc3\xb6\xc3\xa4/" - /* a:o:u:A:O:U:.txt */ - #define UMLAUT_FNAME "\xc3\xa4\xc3\xb6\xc3\xbc\xc3\x84\xc3\x96\xc3\x9c.txt" -#endif - -/* "Test" in Japanese Katakana */ -#define KATAKANA_FNAME "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.txt" -#define KATAKANA_DIRNAME "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88/" - - /* Verify regular file. U:O:A:u:o:a:/a:o:u:A:O:U:.txt */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(UMLAUT_DIRNAME UMLAUT_FNAME, archive_entry_pathname(ae)); - assertEqualInt(12, archive_entry_size(ae)); - - /* Verify directory. U:O:A:u:o:a:/ */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(UMLAUT_DIRNAME, archive_entry_pathname(ae)); - assertEqualInt(0, archive_entry_size(ae)); - - /* Verify regular file. U:O:A:u:o:a:/("Test" in Japanese).txt */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(UMLAUT_DIRNAME KATAKANA_FNAME, - archive_entry_pathname(ae)); - assertEqualInt(25, archive_entry_size(ae)); - - /* Verify regular file. ("Test" in Japanese)/a:o:u:A:O:U:.txt */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(KATAKANA_DIRNAME UMLAUT_FNAME, - archive_entry_pathname(ae)); - assertEqualInt(12, archive_entry_size(ae)); - - /* Verify directory. ("Test" in Japanese)/ */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(KATAKANA_DIRNAME, archive_entry_pathname(ae)); - assertEqualInt(0, archive_entry_size(ae)); - - /* Verify regular file. a:o:u:A:O:U:.txt */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(UMLAUT_FNAME, archive_entry_pathname(ae)); - assertEqualInt(12, archive_entry_size(ae)); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_LHA, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_lha_filename_UTF16) -{ - /* A sample file was created with Unlha32.dll. */ - const char *refname = "test_read_format_lha_filename_utf16.lzh"; - extract_reference_file(refname); - - test_read_format_lha_filename_UTF16_UTF8(refname); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_lha_filename_utf16.lzh.uu b/thirdparty/libarchive/libarchive/test/test_read_format_lha_filename_utf16.lzh.uu deleted file mode 100644 index ca5da7a64..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_lha_filename_utf16.lzh.uu +++ /dev/null @@ -1,19 +0,0 @@ -begin 644 test_read_format_lha_filename_utf16.lzh -M@0`M;&@P+0P````,````L/5872`"IW%-!P!&I`,```T``5]?7U]?7RYT>'0* -M``)?7U]?7U__%P!$Y`#V`/P`Q`#6`-P`+@!T`'@`=``1`$7<`-8`Q`#\`/8` -MY`#__QL`078S9B"U0$H^DQ_F(+5 -M`2CZ3'^8@M4!!@``GW<'``!J`"UL:#`M&0```!D```!V)L1=(`*CNTT'`$:D -M`P``#0`!@V6#6(-G+G1X=`H``E]?7U]?7_\1`$7<`-8`Q`#\`/8`Y`#__QL` -M00IF#4J@E-4!L"5C?'65U0&P)6-\=975`08``$%^!P``5&5S="!I;B!*87!A -M;F5S92!+871A:V%N87L`+6QH,"T,````#````+#U6%T@`J=Q30<`1J0#```- -M``%?7U]?7U\N='AT"@`"@V6#6(-G_Q<`1.0`]@#\`,0`U@#<`"X`=`!X`'0` -M"P!%QC"Y,,@P__\;`$'D5O!-H)35`?4-F(*15=4!Y%;P3:"4U0$&``"A+0<` -M`,.DP[;#O,.$PY;#G%0`+6QH9"T``````````-3`PET@`@``30<`1J0#```# -M``$*``*#98-8@V?_!0!`$``;`$%%!\Y.H)35`3/_]%&@E-4!,__T4:"4U0$& -M``!>;@<``&8`+6QH,"T,````#````+#U6%T@`J=Q30<`1J0#```-``%?7U]? -M7U\N='AT%P!$Y`#V`/P`Q`#6`-P`+@!T`'@`=``;`$'D5O!-H)35`?4-F(*1 -@5=4!Y%;P3:"4U0$&``"M>`<``,.DP[;#O,.$PY;#G`#D -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_lha_header0.lzh.uu b/thirdparty/libarchive/libarchive/test/test_read_format_lha_header0.lzh.uu deleted file mode 100644 index 8fa8b9248..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_lha_header0.lzh.uu +++ /dev/null @@ -1,11 +0,0 @@ -begin 644 test_read_format_lha_header0.lzh -M)L`M;&AD+0```````````$@B[!``!&1ID#Z0,GO2UL:#4M(@```#P`````2"+L(``%9FEL93&D -MYU4`@5$!`*2!Z0/I`P`80FYIQ>/Z`=-:'>9%#"P%J!\CH0"/GE$,.W6FMSD% -M*_4G02UL:#4M(@```$X`````2"+L(``%9FEL93+5%54`@5$!`+:!Z0/I`P`8 -A0FYIQV/Z`=.:'.9%#"P%J-\+H0"/'E$,.W6FMSD%*_T` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_lha_header1.lzh.uu b/thirdparty/libarchive/libarchive/test/test_read_format_lha_header1.lzh.uu deleted file mode 100644 index 303c9bbb2..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_lha_header1.lzh.uu +++ /dev/null @@ -1,13 +0,0 @@ -begin 644 test_read_format_lha_header1.lzh -M&7\M;&AD+1H``````````$@B["`!````50<``F1ID#Z0,' -M`%2!40$````9@2UL:&0M&P``````````2"+L(`$```!5"``"9&ER,O\%`%#M -M00<`4>D#Z0,'`%2!40$````><2UL:&0M)P`````````!2"/L(`$%9FEL93$` -M`%44``)D:7(R_W-Y;6QI;FLQ?"XN_P4`4.VA!P!1Z0/I`P<`5`*C`@```!YR -M+6QH9"TG``````````%((^P@`05F:6QE,@``510``F1I40P[=::W.04K]1YX+6QH-2TU````3@````!((NP@`05F:6QE -M,M45504`4+:!!P!1Z0/I`P<`5(%1`0`````80FYIQV/Z`=.:'.9%#"P%J-\+ -/H0"/'E$,.W6FMSD%*_T` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_lha_header2.lzh.uu b/thirdparty/libarchive/libarchive/test/test_read_format_lha_header2.lzh.uu deleted file mode 100644 index d5d7591f1..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_lha_header2.lzh.uu +++ /dev/null @@ -1,13 +0,0 @@ -begin 644 test_read_format_lha_header2.lzh -M-0`M;&AD+0``````````@5$!`"`"``!5!0``!=X#``$'``)D:7+_!0!0Z$$' -M`%'I`^D#```V`"UL:&0M``````````"!40$`(`(``%4%```(F0,``0@``F1I -M6UL:6YK,7PN+O\%`%#MH0<`4>D#Z0,``$<` -M+6QH9"T```````````*C`@`@`@``504``(?M"``!9FEL93(4``)D:7(R_W-Y -M;6QI;FLR?"XN_P4`4.VA!P!1Z0/I`P``,P`M;&@U+2(````\````@5$!`"`" -MI.=5!0``_0$(``%F:6QE,04`4*2!!P!1Z0/I`P```!A";FG%X_H!TUH=YD4, -M+`6H'R.A`(^>40P[=::W.04K]3,`+6QH-2TB````3@```(%1`0`@`M45504` -M`"_&"``!9FEL93(%`%"V@0<`4>D#Z0,````80FYIQV/Z`=.:'.9%#"P%J-\+ -/H0"/'E$,.W6FMSD%*_T` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_lha_header3.lzh.uu b/thirdparty/libarchive/libarchive/test/test_read_format_lha_header3.lzh.uu deleted file mode 100644 index e6128264a..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_lha_header3.lzh.uu +++ /dev/null @@ -1,16 +0,0 @@ -begin 644 test_read_format_lha_header3.lzh -M!``M;&AD+0``````````@5$!`"`#``!-?`````D```!&I`,```4````!"0`` -M``)D:7+_!P```$`0`!D```#_[4$`````````````#!7^3$0:_DP=````0@_0`9;+`0@`````+J\'``````0`+6QH9"T````` -M`````(%1`0`@`P``37T````)````1J0#```%`````0H````"9&ER,O\'```` -M0!``&0```/_M00`````````````A&OY,1!K^3!T```!!2H%NNP&6RP&`UD`` -MJ+*=`0!Z#]`!ELL!"`````!]%P<`````!``M;&@U+20````\````@5$!`"`# -MI.=-<0````D```!&I`,```H````!9FEL93$9````_Z2!`````````````,<4 -M_DPC&OY,'0```$$T0J**_I7+`8#60`"HLIT!_G*DO`&6RP$(``````KQ!P`` -M````&4)MD:BT=H!Z:T.IZ9#S:`ZH%CJ$`A]OC1DU4VION(3=>H`$`"UL:#4M -M)````$X```"!40$`(`/5%4UQ````"0```$:D`P``"@````%F:6QE,AD```#_ -MI($`````````````(1K^3",:_DP=````0?Y%<[L!ELL!@-9``*BRG0%8U::\ -M`9;+`0@`````0=X'```````90FV1J.QV@'IS0XGID/-H#JC&&H0"'F^-&353 -(:F^XA-U^@``` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_lha_lh0.lzh.uu b/thirdparty/libarchive/libarchive/test/test_read_format_lha_lh0.lzh.uu deleted file mode 100644 index fff88c7ad..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_lha_lh0.lzh.uu +++ /dev/null @@ -1,13 +0,0 @@ -begin 644 test_read_format_lha_lh0.lzh -M-0`M;&AD+0``````````@5$!`"`"``!5!0``!=X#``$'``)D:7+_!0!0Z$$' -M`%'I`^D#```V`"UL:&0M``````````"!40$`(`(``%4%```(F0,``0@``F1I -M6UL:6YK,7PN+O\%`%#MH0<`4>D#Z0,``$<` -M+6QH9"T```````````*C`@`@`@``504``(?M"``!9FEL93(4``)D:7(R_W-Y -M;6QI;FLR?"XN_P4`4.VA!P!1Z0/I`P``,P`M;&@U+2(````\````@5$!`"`" -MI.=5!0``_0$(``%F:6QE,04`4*2!!P!1Z0/I`P```!A";FG%X_H!TUH=YD4, -M+`6H'R.A`(^>40P[=::W.04K]3,`+6QH-2TB````3@```(%1`0`@`M45504` -M`"_&"``!9FEL93(%`%"V@0<`4>D#Z0,````80FYIQV/Z`=.:'.9%#"P%J-\+ -=H0"/'E$,.W6FMSD%*_T`:G5N:R!D871A(2$A(0H` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_lha_lh6.lzh.uu b/thirdparty/libarchive/libarchive/test/test_read_format_lha_lh6.lzh.uu deleted file mode 100644 index 22ad4ac70..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_lha_lh6.lzh.uu +++ /dev/null @@ -1,13 +0,0 @@ -begin 644 test_read_format_lha_lh6.lzh -M-0`M;&AD+0``````````@5$!`"`"``!5!0``!=X#``$'``)D:7+_!0!0Z$$' -M`%'I`^D#```V`"UL:&0M``````````"!40$`(`(``%4%```(F0,``0@``F1I -M6UL:6YK,7PN+O\%`%#MH0<`4>D#Z0,``$<` -M+6QH9"T```````````*C`@`@`@``504``(?M"``!9FEL93(4``)D:7(R_W-Y -M;6QI;FLR?"XN_P4`4.VA!P!1Z0/I`P``,P`M;&@V+2,````\````@5$!`"`" -MI.=5!0``C24(``%F:6QE,04`4*2!!P!1Z0/I`P```!A";FG%X_H!TUH=YD4, -M+`6H'R.0@$?/*(8=NM-;G(*5^H`S`"UL:#8M(P```$X```"!40$`(`+5%54% -M``!?X@@``69I;&4R!0!0MH$'`%'I`^D#````&$)N:<=C^@'3FASF10PL!:C? -1"Y"`1X\HAAVZTUN<@I7^@``` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_lha_lh7.lzh.uu b/thirdparty/libarchive/libarchive/test/test_read_format_lha_lh7.lzh.uu deleted file mode 100644 index 1eaf55cb1..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_lha_lh7.lzh.uu +++ /dev/null @@ -1,13 +0,0 @@ -begin 644 test_read_format_lha_lh7.lzh -M-0`M;&AD+0``````````@5$!`"`"``!5!0``!=X#``$'``)D:7+_!0!0Z$$' -M`%'I`^D#```V`"UL:&0M``````````"!40$`(`(``%4%```(F0,``0@``F1I -M6UL:6YK,7PN+O\%`%#MH0<`4>D#Z0,``$<` -M+6QH9"T```````````*C`@`@`@``504``(?M"``!9FEL93(4``)D:7(R_W-Y -M;6QI;FLR?"XN_P4`4.VA!P!1Z0/I`P``,P`M;&@W+2,````\````@5$!`"`" -MI.=5!0``'(D(``%F:6QE,04`4*2!!P!1Z0/I`P```!A";FG%X_H!TUH=YD4, -M+`6H'R.0@$?/*(8=NM-;G(*5^H`S`"UL:#6UL:6YK,7PN+O\%`%#MH0<`4>D#Z0,``$<` -M+6QH9"T```````````*C`@`@`@``504``(?M"``!9FEL93(4``)D:7(R_W-Y -M;6QI;FLR?"XN_P4`4.VA!P!1Z0/I`P``,P`M;&@U+2(````\````@5$!`"`" -MI.=5!0``_0$(``%F:6QE,04`4*2!!P!1Z0/I`P```!A";FG%X_H!TUH=YD4, -M+`6H'R.A`(^>40P[=::W.04K]3,`+6QH-2TB````3@```(%1`0`@`M45504` -M`"_&"``!9FEL93(%`%"V@0<`4>D#Z0,````80FYIQV/Z`=.:'.9%#"P%J-\+ -=H0"/'E$,.W6FMSD%*_T`:G5N:R!D871A(2$A(0H` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_mtree.c b/thirdparty/libarchive/libarchive/test/test_read_format_mtree.c deleted file mode 100644 index 40c65868d..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_mtree.c +++ /dev/null @@ -1,846 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2011-2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_mtree.c 201247 2009-12-30 05:59:21Z kientzle $"); - -static void -test_read_format_mtree1(void) -{ - const char reffile[] = "test_read_format_mtree.mtree"; - char buff[16]; - struct archive_entry *ae; - struct archive *a; - FILE *f; - /* Compute max 64-bit signed twos-complement value - * without relying on overflow. This assumes that long long - * is at least 64 bits. */ - static const long long max_int64 = ((((long long)1) << 62) - 1) + (((long long)1) << 62); - time_t min_time; - volatile time_t t; - - extract_reference_file(reffile); - - /* - * An access error occurred on some platform when mtree - * format handling open a directory. It is for through - * the routine which open a directory that we create - * "dir" and "dir2" directories. - */ - assertMakeDir("dir", 0775); - assertMakeDir("dir2", 0775); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "mtree:checkfs")); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, reffile, 11)); - - /* - * Read "file", whose data is available on disk. - */ - f = fopen("file", "wb"); - assert(f != NULL); - assertEqualInt(3, fwrite("hi\n", 1, 3, f)); - fclose(f); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE); - assertEqualString(archive_entry_pathname(ae), "file"); - assertEqualInt(archive_entry_uid(ae), 18); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0123); - assertEqualInt(archive_entry_size(ae), 3); - assertEqualInt(3, archive_read_data(a, buff, 3)); - assertEqualMem(buff, "hi\n", 3); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir"); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir/file with space"); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "file with space"); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2"); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/dir3a"); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/dir3a/indir3a"); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/fullindir2"); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/indir2"); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/dir3b"); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/dir3b/indir3b"); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/dir3b/filename\\with_esc\b\t\fapes"); - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "notindir"); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/emptyfile"); - assertEqualInt(archive_entry_size(ae), 0); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/smallfile"); - assertEqualInt(archive_entry_size(ae), 1); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* TODO: Mtree reader should probably return ARCHIVE_WARN for this. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/toosmallfile"); - assertEqualInt(archive_entry_size(ae), -1); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/bigfile"); - assertEqualInt(archive_entry_size(ae), max_int64); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/toobigfile"); - /* Size in mtree is max_int64 + 1; should return max_int64. */ - assertEqualInt(archive_entry_size(ae), max_int64); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/veryoldfile"); - /* The value in the file is MIN_INT64_T, but time_t may be narrower. */ - /* Verify min_time is the smallest possible time_t. */ - min_time = archive_entry_mtime(ae); - assert(min_time <= 0); - /* Simply asserting min_time - 1 > 0 breaks with some compiler optimizations. */ - t = (time_t)((uintmax_t)min_time - 1); - assert(t > 0); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* toooldfile is 1 sec older, which should overflow and get returned - * with the same value. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/toooldfile"); - assertEqualInt(archive_entry_mtime(ae), min_time); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* md5digest */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/md5file"); - assertEqualMem(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_MD5), - "\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\x09\x98\xec\xf8\x42\x7e", - 16); - - /* rmd160digest */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/rmd160file"); - assertEqualMem(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_RMD160), - "\xda\x39\xa3\xee\x5e\x6b\x4b\x0d\x32\x55\xbf\xef\x95\x60\x18\x90" - "\xaf\xd8\x07\x09", 20); - - /* sha1digest */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/sha1file"); - assertEqualMem(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_SHA1), - "\xda\x39\xa3\xee\x5e\x6b\x4b\x0d\x32\x55\xbf\xef\x95\x60\x18\x90" - "\xaf\xd8\x07\x09", 20); - - /* sha256digest */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/sha256file"); - assertEqualMem(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_SHA256), - "\xe3\xb0\xc4\x42\x98\xfc\x1c\x14\x9a\xfb\xf4\xc8\x99\x6f\xb9\x24" - "\x27\xae\x41\xe4\x64\x9b\x93\x4c\xa4\x95\x99\x1b\x78\x52\xb8\x55", - 32); - - /* sha384digest */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/sha384file"); - assertEqualMem(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_SHA384), - "\x38\xb0\x60\xa7\x51\xac\x96\x38\x4c\xd9\x32\x7e\xb1\xb1\xe3\x6a" - "\x21\xfd\xb7\x11\x14\xbe\x07\x43\x4c\x0c\xc7\xbf\x63\xf6\xe1\xda" - "\x27\x4e\xde\xbf\xe7\x6f\x65\xfb\xd5\x1a\xd2\xf1\x48\x98\xb9\x5b", - 48); - - /* sha512digest */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/sha512file"); - assertEqualMem(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_SHA512), - "\xcf\x83\xe1\x35\x7e\xef\xb8\xbd\xf1\x54\x28\x50\xd6\x6d\x80\x07" - "\xd6\x20\xe4\x05\x0b\x57\x15\xdc\x83\xf4\xa9\x21\xd3\x6c\xe9\xce" - "\x47\xd0\xd1\x3c\x5d\x85\xf2\xb0\xff\x83\x18\xd2\x87\x7e\xec\x2f" - "\x63\xb9\x31\xbd\x47\x41\x7a\x81\xa5\x38\x32\x7a\xf9\x27\xda\x3e", - 64); - - /* md5 digest is too short */ - assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/md5tooshort"); - assertMemoryFilledWith(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_MD5), - 16, 0x00); - - /* md5 digest is too long */ - assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/md5toolong"); - assertMemoryFilledWith(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_MD5), - 16, 0x00); - - /* md5 digest is uppercase hex */ - assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/md5caphex"); - assertMemoryFilledWith(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_MD5), - 16, 0x00); - - /* md5 digest is not hex */ - assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/md5nothex"); - assertMemoryFilledWith(archive_entry_digest(ae, ARCHIVE_ENTRY_DIGEST_MD5), - 16, 0x00); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualInt(30, archive_file_count(a)); - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -static void -test_read_format_mtree2(void) -{ - static char archive[] = - "#mtree\n" - "d type=dir content=.\n"; - struct archive_entry *ae; - struct archive *a; - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "mtree:checkfs")); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, archive, sizeof(archive))); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE); - assertEqualString(archive_entry_pathname(ae), "d"); - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_file_count(a)); - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* - * Reported to libarchive.googlecode.com as Issue 121. - */ -static void -test_read_format_mtree3(void) -{ - static char archive[] = - "#mtree\n" - "a type=file contents=file\n" - "b type=link link=a\n" - "c type=file contents=file\n"; - struct archive_entry *ae; - struct archive *a; - - assertMakeDir("mtree3", 0777); - assertChdir("mtree3"); - assertMakeFile("file", 0644, "file contents"); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "mtree:checkfs")); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, archive, sizeof(archive))); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "a"); - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "b"); - assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "c"); - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualInt(3, archive_file_count(a)); - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - assertChdir(".."); -} - -DEFINE_TEST(test_read_format_mtree) -{ - test_read_format_mtree1(); - test_read_format_mtree2(); - test_read_format_mtree3(); -} - -DEFINE_TEST(test_read_format_mtree_filenames_only) -{ - static char archive[] = - "/set type=file mode=0644\n" - "./a\n" - "./b\n" - "./c\n" - "./d\n" - "./e\n" - "./f mode=0444\n"; - struct archive_entry *ae; - struct archive *a; - - assertMakeFile("file", 0644, "file contents"); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "mtree:checkfs")); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, archive, sizeof(archive))); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "./a"); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "./b"); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "./c"); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "./d"); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "./e"); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "./f"); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0444); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualInt(6, archive_file_count(a)); - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_mtree_nochange) -{ - static char archive[] = - "#mtree\n" - "./a type=file mode=0644 time=123\n" - "./b type=file mode=0644 time=234\n" - "./c type=file mode=0644 time=345\n"; - static char archive2[] = - "#mtree\n" - "./a type=file mode=0644 time=123 nochange\n" - "./b type=file mode=0644 time=234\n" - "./c type=file mode=0644 time=345 nochange\n"; - struct archive_entry *ae; - struct archive *a; - - assertMakeFile("a", 0640, "12345"); - assertMakeFile("b", 0664, "123456"); - assertMakeFile("c", 0755, "1234567"); - - /* - * Test 1. Read a mtree archive without `nochange' keyword. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "mtree:checkfs")); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, archive, sizeof(archive))); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "./a"); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); - assertEqualInt(archive_entry_mtime(ae), 123); - assertEqualInt(archive_entry_size(ae), 5); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "./b"); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); - assertEqualInt(archive_entry_mtime(ae), 234); - assertEqualInt(archive_entry_size(ae), 6); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "./c"); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); - assertEqualInt(archive_entry_mtime(ae), 345); - assertEqualInt(archive_entry_size(ae), 7); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualInt(3, archive_file_count(a)); - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Test 2. Read a mtree archive with `nochange' keyword. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "mtree:checkfs")); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, archive2, sizeof(archive2))); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "./a"); -#if !defined(_WIN32) || defined(__CYGWIN__) - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0640); -#endif - assert(archive_entry_mtime(ae) != 123); - assertEqualInt(archive_entry_size(ae), 5); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "./b"); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); - assertEqualInt(archive_entry_mtime(ae), 234); - assertEqualInt(archive_entry_size(ae), 6); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "./c"); -#if !defined(_WIN32) || defined(__CYGWIN__) - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0755); -#endif - assert(archive_entry_mtime(ae) != 345); - assertEqualInt(archive_entry_size(ae), 7); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualInt(3, archive_file_count(a)); - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_mtree_nomagic_v1_form) -{ - const char reffile[] = "test_read_format_mtree_nomagic.mtree"; - char buff[16]; - struct archive_entry *ae; - struct archive *a; - FILE *f; - - extract_reference_file(reffile); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "mtree:checkfs")); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, reffile, 11)); - - /* - * Read "file", whose data is available on disk. - */ - f = fopen("file", "wb"); - assert(f != NULL); - assertEqualInt(3, fwrite("hi\n", 1, 3, f)); - fclose(f); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE); - assertEqualString(archive_entry_pathname(ae), "file"); - assertEqualInt(archive_entry_uid(ae), 18); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0123); - assertEqualInt(archive_entry_size(ae), 3); - assertEqualInt(3, archive_read_data(a, buff, 3)); - assertEqualMem(buff, "hi\n", 3); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir"); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir/file with space"); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "file with space"); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2"); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/dir3a"); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/dir3a/indir3a"); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/fullindir2"); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/indir2"); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/dir3b"); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "dir2/dir3b/indir3b"); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "notindir"); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualInt(12, archive_file_count(a)); - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* - * Test for a format that NetBSD mtree -C generates. - */ -DEFINE_TEST(test_read_format_mtree_nomagic_v2_form) -{ - const char reffile[] = "test_read_format_mtree_nomagic2.mtree"; - char buff[16]; - struct archive_entry *ae; - struct archive *a; - FILE *f; - - extract_reference_file(reffile); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "mtree:checkfs")); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, reffile, 11)); - - /* - * Read "file", whose data is available on disk. - */ - f = fopen("file", "wb"); - assert(f != NULL); - assertEqualInt(3, fwrite("hi\n", 1, 3, f)); - fclose(f); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE); - assertEqualString(archive_entry_pathname(ae), "./file"); - assertEqualInt(archive_entry_uid(ae), 18); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0123); - assertEqualInt(archive_entry_size(ae), 3); - assertEqualInt(3, archive_read_data(a, buff, 3)); - assertEqualMem(buff, "hi\n", 3); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "./dir"); - assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "./dir/file with space"); - assertEqualInt(archive_entry_uid(ae), 18); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "./file with space"); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "./dir2"); - assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "./dir2/dir3a"); - assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualInt(6, archive_file_count(a)); - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* - * Test for a format that NetBSD mtree -D generates. - */ -DEFINE_TEST(test_read_format_mtree_nomagic_v2_netbsd_form) -{ - const char reffile[] = "test_read_format_mtree_nomagic3.mtree"; - char buff[16]; - struct archive_entry *ae; - struct archive *a; - FILE *f; - - extract_reference_file(reffile); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "mtree:checkfs")); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, reffile, 11)); - - /* - * Read "file", whose data is available on disk. - */ - f = fopen("file", "wb"); - assert(f != NULL); - assertEqualInt(3, fwrite("hi\n", 1, 3, f)); - fclose(f); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE); - assertEqualString(archive_entry_pathname(ae), "./file"); - assertEqualInt(archive_entry_uid(ae), 18); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0123); - assertEqualInt(archive_entry_size(ae), 3); - assertEqualInt(3, archive_read_data(a, buff, 3)); - assertEqualMem(buff, "hi\n", 3); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "./dir"); - assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "./dir/file with space"); - assertEqualInt(archive_entry_uid(ae), 18); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "./file with space"); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "./dir2"); - assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "./dir2/dir3a"); - assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualInt(6, archive_file_count(a)); - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* - * We should get a warning if the contents file doesn't exist. - */ -DEFINE_TEST(test_read_format_mtree_nonexistent_contents_file) -{ - static char archive[] = - "#mtree\n" - "a type=file contents=nonexistent_file\n"; - struct archive_entry *ae; - struct archive *a; - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "mtree:checkfs")); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, archive, sizeof(archive))); - assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); - assert(strlen(archive_error_string(a)) > 0); - assertEqualString(archive_entry_pathname(ae), "a"); - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_file_count(a)); - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* - * Check mtree file with non-printable ascii characters - */ -DEFINE_TEST(test_read_format_mtree_noprint) -{ - const char reffile[] = "test_read_format_mtree_noprint.mtree"; - struct archive_entry *ae; - struct archive *a; - - extract_reference_file(reffile); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, reffile, 11)); - - assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae)); - assertEqualString("Can't parse line 3", archive_error_string(a)); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* - * Check mtree file with tab characters, which are supported but not printable - */ -DEFINE_TEST(test_read_format_mtree_tab) -{ - static char archive[] = - "#mtree\n" - "\ta\ttype=file\n"; - struct archive_entry *ae; - struct archive *a; - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, archive, sizeof(archive))); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "a"); - assertEqualInt(archive_entry_filetype(ae), AE_IFREG); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_file_count(a)); - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_mtree.mtree.uu b/thirdparty/libarchive/libarchive/test/test_read_format_mtree.mtree.uu deleted file mode 100644 index 7bfb252ec..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_mtree.mtree.uu +++ /dev/null @@ -1,40 +0,0 @@ -begin 644 test_read_format_mtree.mtree -M(VUT7!E/61I<@H@9FEL95PP-#!W:71H7#`T,'-P86-E('1Y<&4]9FEL -M92!U:60],3@*("XN"F9I;&5<,#0P=VET:%PP-#!S<&%C92!T>7!E/69I;&4* -M9&ER,B!T>7!E/61I<@H@9&ER,V$@='EP93UD:7(*("!I;F1I7!E/61I<@H@(&EN9&ER,V(@ -M='EP93UF:6QE"B`@9FEL96YA;65<7'=I=&A<"E]E7!E/69I -M;&4@F4]+3$*9&ER,B]B:6=F:6QE('1Y -M<&4]9FEL92!S:7IE/3DR,C,S-S(P,S8X-30W-S4X,#<*9&ER,B]T;V]B:6=F -M:6QE('1Y<&4]9FEL92!S:7IE/3DR,C,S-S(P,S8X-30W-S4X,#@*9&ER,B]V -M97)Y;VQD9FEL92!T>7!E/69I;&4@=&EM93TM.3(R,S,W,C`S-C@U-#7!E/69I;&4@"!T>7!E/69I;&4@ -K;60U9&EG97-T/7$T,60X8V0Y.&8P,&(R,#1E.3@P,#DY.&5C9C@T,C=E"@`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_mtree_crash747.c b/thirdparty/libarchive/libarchive/test/test_read_format_mtree_crash747.c deleted file mode 100644 index 9500bba2c..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_mtree_crash747.c +++ /dev/null @@ -1,49 +0,0 @@ -/*- - * Copyright (c) 2003-2016 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - - -/* - * Reproduce the crash reported in Github Issue #747. - */ -DEFINE_TEST(test_read_format_mtree_crash747) -{ - const char *reffile = "test_read_format_mtree_crash747.mtree.bz2"; - struct archive *a; - - if (archive_bzlib_version() == NULL) { - skipping("This test requires bzlib"); - return; - } - - extract_reference_file(reffile); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_bzip2(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_mtree(a)); - assertEqualIntA(a, ARCHIVE_FATAL, archive_read_open_filename(a, reffile, 10240)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_mtree_crash747.mtree.bz2.uu b/thirdparty/libarchive/libarchive/test/test_read_format_mtree_crash747.mtree.bz2.uu deleted file mode 100644 index 84f38955b..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_mtree_crash747.mtree.bz2.uu +++ /dev/null @@ -1,6 +0,0 @@ -begin 600 test_read_format_mtree_crash747.mtree.bz2 -M0EIH.3%!62936:OH@(@``'/[@,`0`@!``'^```)A@9\`$`@@`'4)049!IIH! -MM021-0,F@&@6````9%>$(K!GIC*XFR0`$```J0+:$XP```!D-F)H[#SE9+2' -4+E"L=ASXUI%R(I"HD'ZA(5?1`Q`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_mtree_nomagic.mtree.uu b/thirdparty/libarchive/libarchive/test/test_read_format_mtree_nomagic.mtree.uu deleted file mode 100644 index be089103d..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_mtree_nomagic.mtree.uu +++ /dev/null @@ -1,11 +0,0 @@ -begin 644 test_read_format_mtree_nomagic.mtree -M9FEL92!T>7!E/69I;&4@=6ED/3$X(&UO9&4],#$R,R!S:7IE/3,*9&ER('1Y -M<&4]9&ER"B!F:6QE7#`T,'=I=&A<,#0P7!E/61I<@H@(&EN9&ER,V$@='EP93UF:6QE"F1I -M7!E/69I;&4@;6]D93TP-S7!E/69I;&4*(&1I7!E/69I -M;&4*("`N+@H@+BX*;F]T:6YD:7(@='EP93UF:6QE"F1IF4],PHN -M+V1I7!E/61I7!E/61I7!E/61I7!E/61I<@ID:7)?P[;%H<2'('1Y<&4]9&ER"@`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_pax_bz2.c b/thirdparty/libarchive/libarchive/test/test_read_format_pax_bz2.c deleted file mode 100644 index 8c5d28ec0..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_pax_bz2.c +++ /dev/null @@ -1,69 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_pax_bz2.c 201247 2009-12-30 05:59:21Z kientzle $"); - -static unsigned char archive[] = { -'B','Z','h','9','1','A','Y','&','S','Y',152,180,30,185,0,0,140,127,176,212, -144,0,' ','@',1,255,226,8,'d','H',' ',238,'/',159,'@',0,16,4,'@',0,8,'0', -0,216,'A',164,167,147,'Q',147,'!',180,'#',0,'L',153,162,'i',181,'?','P',192, -26,'h','h',209,136,200,6,128,13,12,18,132,202,'5','O',209,'5','=',26,'2', -154,7,168,12,2,'d',252,13,254,29,'4',247,181,'l','T','i',130,5,195,1,'2', -'@',146,18,251,245,'c','J',130,224,172,'$','l','4',235,170,186,'c','1',255, -179,'K',188,136,18,208,152,192,149,153,10,'{','|','0','8',166,3,6,9,128,172, -'(',164,220,244,149,6,' ',243,212,'B',25,17,'6',237,13,'I',152,'L',129,209, -'G','J','<',137,'Y',16,'b',21,18,'a','Y','l','t','r',160,128,147,'l','f', -'~',219,206,'=','?','S',233,'3',251,'L','~',17,176,169,'%',23,'_',225,'M', -'C','u','k',218,8,'q',216,'(',22,235,'K',131,136,146,136,147,202,0,158,134, -'F',23,160,184,'s','0','a',246,'*','P',7,2,238,'H',167,10,18,19,22,131,215, -' '}; - -DEFINE_TEST(test_read_format_pax_bz2) -{ - struct archive_entry *ae; - struct archive *a; - int r; - - assert((a = archive_read_new()) != NULL); - r = archive_read_support_filter_bzip2(a); - if (r != ARCHIVE_OK) { - archive_read_close(a); - skipping("Bzip2 unavailable"); - return; - } - assertEqualIntA(a,ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a,ARCHIVE_OK, - archive_read_open_memory(a, archive, sizeof(archive))); - assertEqualIntA(a,ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_file_count(a)); - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_BZIP2); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualIntA(a,ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar.c b/thirdparty/libarchive/libarchive/test/test_read_format_rar.c deleted file mode 100644 index 1425eb9a4..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar.c +++ /dev/null @@ -1,3810 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2011 Andres Mejia - * Copyright (c) 2011-2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -#include - -DEFINE_TEST(test_read_format_rar_set_format) -{ - struct archive *a; - struct archive_entry *ae; - const char reffile[] = "test_read_format_rar.rar"; - - extract_reference_file(reffile); - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_RAR)); - assertA(0 == archive_read_open_filename(a, reffile, 10240)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_rar_basic) -{ - char buff[64]; - const char reffile[] = "test_read_format_rar.rar"; - const char test_txt[] = "test text document\r\n"; - int size = sizeof(test_txt)-1; - struct archive_entry *ae; - struct archive *a; - - extract_reference_file(reffile); - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_open_filename(a, reffile, 10240)); - - /* First header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.txt", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(20, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertA(size == archive_read_data(a, buff, size)); - assertEqualMem(buff, test_txt, size); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Second header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testlink", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(41471, archive_entry_mode(ae)); - assertEqualString("test.txt", archive_entry_symlink(ae)); - assertEqualIntA(a, 0, archive_read_data(a, buff, sizeof(buff))); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Third header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testdir/test.txt", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(20, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertA(size == archive_read_data(a, buff, size)); - assertEqualMem(buff, test_txt, size); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Fourth header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testdir", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(16877, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Fifth header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testemptydir", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(16877, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Test EOF */ - assertA(1 == archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_file_count(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_rar_subblock) -{ - char buff[64]; - const char reffile[] = "test_read_format_rar_subblock.rar"; - const char test_txt[] = "test text document\r\n"; - int size = sizeof(test_txt)-1; - struct archive_entry *ae; - struct archive *a; - - extract_reference_file(reffile); - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_open_filename(a, reffile, 10240)); - - /* First header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.txt", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(20, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertA(size == archive_read_data(a, buff, size)); - assertEqualMem(buff, test_txt, size); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Test EOF */ - assertA(1 == archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_file_count(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_rar_noeof) -{ - char buff[64]; - const char reffile[] = "test_read_format_rar_noeof.rar"; - const char test_txt[] = "test text document\r\n"; - int size = sizeof(test_txt)-1; - struct archive_entry *ae; - struct archive *a; - - extract_reference_file(reffile); - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_open_filename(a, reffile, 10240)); - - /* First header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.txt", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(20, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertA(size == archive_read_data(a, buff, size)); - assertEqualMem(buff, test_txt, size); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Test EOF */ - assertA(1 == archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_file_count(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_rar_unicode_UTF8) -{ - char buff[30]; - const char reffile[] = "test_read_format_rar_unicode.rar"; - const char test_txt[] = "kanji"; - struct archive_entry *ae; - struct archive *a; - - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("en_US.UTF-8 locale not available on this system."); - return; - } - - extract_reference_file(reffile); - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_open_filename(a, reffile, 10240)); - - /* First header. */ - assertA(0 == archive_read_next_header(a, &ae)); -#if defined(__APPLE__) -#define f1name "\xE8\xA1\xA8\xE3\x81\x9F\xE3\x82\x99\xE3\x82\x88/"\ - "\xE6\x96\xB0\xE3\x81\x97\xE3\x81\x84\xE3\x83\x95\xE3\x82\xA9"\ - "\xE3\x83\xAB\xE3\x82\xBF\xE3\x82\x99/\xE6\x96\xB0\xE8\xA6\x8F"\ - "\xE3\x83\x86\xE3\x82\xAD\xE3\x82\xB9\xE3\x83\x88 "\ - "\xE3\x83\x88\xE3\x82\x99\xE3\x82\xAD\xE3\x83\xA5\xE3\x83\xA1"\ - "\xE3\x83\xB3\xE3\x83\x88.txt" /* NFD */ -#else -#define f1name "\xE8\xA1\xA8\xE3\x81\xA0\xE3\x82\x88/"\ - "\xE6\x96\xB0\xE3\x81\x97\xE3\x81\x84\xE3\x83\x95\xE3\x82\xA9"\ - "\xE3\x83\xAB\xE3\x83\x80/\xE6\x96\xB0\xE8\xA6\x8F"\ - "\xE3\x83\x86\xE3\x82\xAD\xE3\x82\xB9\xE3\x83\x88 "\ - "\xE3\x83\x89\xE3\x82\xAD\xE3\x83\xA5\xE3\x83\xA1"\ - "\xE3\x83\xB3\xE3\x83\x88.txt" /* NFC */ -#endif - assertEqualUTF8String(f1name, archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - - /* Second header. */ - assertA(0 == archive_read_next_header(a, &ae)); -#if defined(__APPLE__) -#define f2name "\xE8\xA1\xA8\xE3\x81\x9F\xE3\x82\x99\xE3\x82\x88/"\ - "\xE6\xBC\xA2\xE5\xAD\x97\xE9\x95\xB7\xE3\x81\x84\xE3\x83\x95"\ - "\xE3\x82\xA1\xE3\x82\xA4\xE3\x83\xAB\xE5\x90\x8Dlong-filename-in-"\ - "\xE6\xBC\xA2\xE5\xAD\x97.txt" /* NFD */ -#else -#define f2name "\xE8\xA1\xA8\xE3\x81\xA0\xE3\x82\x88/"\ - "\xE6\xBC\xA2\xE5\xAD\x97\xE9\x95\xB7\xE3\x81\x84\xE3\x83\x95"\ - "\xE3\x82\xA1\xE3\x82\xA4\xE3\x83\xAB\xE5\x90\x8Dlong-filename-in-"\ - "\xE6\xBC\xA2\xE5\xAD\x97.txt" /* NFC */ -#endif - assertEqualUTF8String(f2name, archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertEqualInt(5, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualIntA(a, 5, archive_read_data(a, buff, 5)); - assertEqualMem(buff, test_txt, 5); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Third header. */ - assertA(0 == archive_read_next_header(a, &ae)); -#if defined(__APPLE__) -#define f3name "\xE8\xA1\xA8\xE3\x81\x9F\xE3\x82\x99\xE3\x82\x88/"\ - "\xE6\x96\xB0\xE3\x81\x97\xE3\x81\x84\xE3\x83\x95\xE3\x82"\ - "\xA9\xE3\x83\xAB\xE3\x82\xBF\xE3\x82\x99" /* NFD */ -#else -#define f3name "\xE8\xA1\xA8\xE3\x81\xA0\xE3\x82\x88/"\ - "\xE6\x96\xB0\xE3\x81\x97\xE3\x81\x84\xE3\x83\x95\xE3\x82"\ - "\xA9\xE3\x83\xAB\xE3\x83\x80" /* NFC */ -#endif - assertEqualUTF8String(f3name, archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(16877, archive_entry_mode(ae)); - - /* Fourth header. */ - assertA(0 == archive_read_next_header(a, &ae)); -#if defined(__APPLE__) -#define f4name "\xE8\xA1\xA8\xE3\x81\x9F\xE3\x82\x99\xE3\x82\x88" /* NFD */ -#else -#define f4name "\xE8\xA1\xA8\xE3\x81\xA0\xE3\x82\x88" /* NFC */ -#endif - assertEqualUTF8String(f4name, archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(16877, archive_entry_mode(ae)); - - /* Fifth header, which has a symbolic-link name in multi-byte characters. */ - assertA(0 == archive_read_next_header(a, &ae)); -#if defined(__APPLE__) -#define f5name "\xE8\xA1\xA8\xE3\x81\x9F\xE3\x82\x99\xE3\x82\x88/"\ - "\xE3\x83\x95\xE3\x82\xA1\xE3\x82\xA4\xE3\x83\xAB" /* NFD */ -#else -#define f5name "\xE8\xA1\xA8\xE3\x81\xA0\xE3\x82\x88/"\ - "\xE3\x83\x95\xE3\x82\xA1\xE3\x82\xA4\xE3\x83\xAB" /* NFC */ -#endif - assertEqualUTF8String(f5name, archive_entry_pathname(ae)); - assertEqualUTF8String( - "\xE6\xBC\xA2\xE5\xAD\x97\xE9\x95\xB7\xE3\x81\x84\xE3\x83\x95" - "\xE3\x82\xA1\xE3\x82\xA4\xE3\x83\xAB\xE5\x90\x8Dlong-filename-in-" - "\xE6\xBC\xA2\xE5\xAD\x97.txt", archive_entry_symlink(ae)); - assertA((int)archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(41453, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualIntA(a, 0, archive_read_data(a, buff, sizeof(buff))); - - /* Sixth header */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualUTF8String( - "abcdefghijklmnopqrs\xE3\x83\x86\xE3\x82\xB9\xE3\x83\x88.txt", - archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertEqualInt(16, archive_entry_size(ae)); - assertEqualInt(33204, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualIntA(a, 16, archive_read_data(a, buff, sizeof(buff))); - - /* Test EOF */ - assertA(1 == archive_read_next_header(a, &ae)); - assertEqualInt(6, archive_file_count(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_rar_unicode_CP932) -{ - char buff[30]; - const char reffile[] = "test_read_format_rar_unicode.rar"; - const char test_txt[] = "kanji"; - struct archive_entry *ae; - struct archive *a; - - if (NULL == setlocale(LC_ALL, "Japanese_Japan") && - NULL == setlocale(LC_ALL, "ja_JP.SJIS")) { - skipping("CP932 locale not available on this system."); - return; - } - - extract_reference_file(reffile); - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_support_format_all(a)); - /* Specify the charset of symbolic-link file name. */ - if (ARCHIVE_OK != archive_read_set_options(a, "rar:hdrcharset=UTF-8")) { - skipping("This system cannot convert character-set" - " from UTF-8 to CP932."); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - assertA(0 == archive_read_open_filename(a, reffile, 10240)); - - /* First header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("\x95\x5c\x82\xbe\x82\xe6/\x90\x56\x82\xb5\x82\xa2" - "\x83\x74\x83\x48\x83\x8b\x83\x5f/\x90\x56\x8b\x4b\x83\x65\x83\x4c" - "\x83\x58\x83\x67 \x83\x68\x83\x4c\x83\x85\x83\x81\x83\x93\x83\x67.txt", - archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Second header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("\x95\x5c\x82\xbe\x82\xe6/\x8a\xbf\x8e\x9a" - "\x92\xb7\x82\xa2\x83\x74\x83\x40\x83\x43\x83\x8b\x96\xbc\x6c" - "\x6f\x6e\x67\x2d\x66\x69\x6c\x65\x6e\x61\x6d\x65\x2d\x69\x6e" - "\x2d\x8a\xbf\x8e\x9a.txt", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertEqualInt(5, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertA(5 == archive_read_data(a, buff, 5)); - assertEqualMem(buff, test_txt, 5); - - /* Third header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("\x95\x5c\x82\xbe\x82\xe6/" - "\x90\x56\x82\xb5\x82\xa2\x83\x74\x83\x48\x83\x8b\x83\x5f", - archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(16877, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Fourth header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("\x95\x5c\x82\xbe\x82\xe6", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(16877, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Fifth header, which has a symbolic-link name in multi-byte characters. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("\x95\x5c\x82\xbe\x82\xe6/" - "\x83\x74\x83\x40\x83\x43\x83\x8B", archive_entry_pathname(ae)); - assertEqualString("\x8a\xbf\x8e\x9a" - "\x92\xb7\x82\xa2\x83\x74\x83\x40\x83\x43\x83\x8b\x96\xbc\x6c" - "\x6f\x6e\x67\x2d\x66\x69\x6c\x65\x6e\x61\x6d\x65\x2d\x69\x6e" - "\x2d\x8a\xbf\x8e\x9a.txt", archive_entry_symlink(ae)); - assertA((int)archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(41453, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualIntA(a, 0, archive_read_data(a, buff, sizeof(buff))); - - /* Sixth header */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualUTF8String( - "abcdefghijklmnopqrs\x83\x65\x83\x58\x83\x67.txt", - archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertEqualInt(16, archive_entry_size(ae)); - assertEqualInt(33204, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualIntA(a, 16, archive_read_data(a, buff, sizeof(buff))); - - /* Test EOF */ - assertA(1 == archive_read_next_header(a, &ae)); - assertEqualInt(6, archive_file_count(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_rar_compress_normal) -{ - const char reffile[] = "test_read_format_rar_compress_normal.rar"; - char file1_buff[20111]; - int file1_size = sizeof(file1_buff); - const char file1_test_txt[] = "


    \n" - "

    \n" - "\n" - ""; - char file2_buff[20]; - int file2_size = sizeof(file2_buff); - const char file2_test_txt[] = "test text document\r\n"; - struct archive_entry *ae; - struct archive *a; - - extract_reference_file(reffile); - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_open_filename(a, reffile, 10240)); - - /* First header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("LibarchiveAddingTest.html", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(file1_size, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertA(file1_size == archive_read_data(a, file1_buff, file1_size)); - assertEqualMem(&file1_buff[file1_size - sizeof(file1_test_txt) + 1], - file1_test_txt, sizeof(file1_test_txt) - 1); - - /* Second header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testlink", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(41471, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualString("LibarchiveAddingTest.html", archive_entry_symlink(ae)); - assertEqualIntA(a, 0, archive_read_data(a, file1_buff, 30)); - - /* Third header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testdir/test.txt", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(file2_size, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertA(file2_size == archive_read_data(a, file2_buff, file2_size)); - assertEqualMem(&file2_buff[file2_size + 1 - sizeof(file2_test_txt)], - file2_test_txt, sizeof(file2_test_txt) - 1); - - /* Fourth header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testdir/LibarchiveAddingTest.html", - archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(file1_size, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertA(file1_size == archive_read_data(a, file1_buff, file1_size)); - assertEqualMem(&file1_buff[file1_size - sizeof(file1_test_txt) + 1], - file1_test_txt, sizeof(file1_test_txt) - 1); - - /* Fifth header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testdir", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(16877, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Sixth header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testemptydir", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(16877, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Test EOF */ - assertA(1 == archive_read_next_header(a, &ae)); - assertEqualInt(6, archive_file_count(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* This test is for sufficiently large files that would have been compressed - * using multiple lzss blocks. - */ -DEFINE_TEST(test_read_format_rar_multi_lzss_blocks) -{ - const char reffile[] = "test_read_format_rar_multi_lzss_blocks.rar"; - const char test_txt[] = "-bottom: 0in\">
    \n

    \n\n"; - int size = 20131111, offset = 0; - char buff[64]; - struct archive_entry *ae; - struct archive *a; - - extract_reference_file(reffile); - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_open_filename(a, reffile, 10240)); - - /* First header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("multi_lzss_blocks_test.txt", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(size, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - while (offset + (int)sizeof(buff) < size) - { - assertA(sizeof(buff) == archive_read_data(a, buff, sizeof(buff))); - offset += sizeof(buff); - } - assertA(size - offset == archive_read_data(a, buff, size - offset)); - assertEqualMem(buff, test_txt, size - offset); - - /* Test EOF */ - assertA(1 == archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_file_count(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_rar_compress_best) -{ - const char reffile[] = "test_read_format_rar_compress_best.rar"; - char file1_buff[20111]; - int file1_size = sizeof(file1_buff); - const char file1_test_txt[] = "


    \n" - "

    \n" - "\n" - ""; - char file2_buff[20]; - int file2_size = sizeof(file2_buff); - const char file2_test_txt[] = "test text document\r\n"; - struct archive_entry *ae; - struct archive *a; - - extract_reference_file(reffile); - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_open_filename(a, reffile, 10240)); - - /* First header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("LibarchiveAddingTest.html", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(file1_size, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertA(file1_size == archive_read_data(a, file1_buff, file1_size)); - assertEqualMem(&file1_buff[file1_size - sizeof(file1_test_txt) + 1], - file1_test_txt, sizeof(file1_test_txt) - 1); - - /* Second header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testlink", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(41471, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualString("LibarchiveAddingTest.html", archive_entry_symlink(ae)); - assertEqualIntA(a, 0, archive_read_data(a, file1_buff, 30)); - - /* Third header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testdir/test.txt", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(file2_size, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertA(file2_size == archive_read_data(a, file2_buff, file2_size)); - assertEqualMem(&file2_buff[file2_size + 1 - sizeof(file2_test_txt)], - file2_test_txt, sizeof(file2_test_txt) - 1); - - /* Fourth header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testdir/LibarchiveAddingTest.html", - archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(file1_size, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertA(file1_size == archive_read_data(a, file1_buff, file1_size)); - assertEqualMem(&file1_buff[file1_size - sizeof(file1_test_txt) + 1], - file1_test_txt, sizeof(file1_test_txt) - 1); - - /* Fifth header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testdir", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(16877, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Sixth header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testemptydir", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(16877, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Test EOF */ - assertA(1 == archive_read_next_header(a, &ae)); - assertEqualInt(6, archive_file_count(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* This is a test for RAR files compressed using a technique where compression - * switches back and forth to and from ppmd and lzss decoding. - */ -DEFINE_TEST(test_read_format_rar_ppmd_lzss_conversion) -{ - const char reffile[] = "test_read_format_rar_ppmd_lzss_conversion.rar"; - const char test_txt[] = "gin-bottom: 0in\">
    \n

    \n\n"; - int size = 241647978, offset = 0; - char buff[64]; - struct archive_entry *ae; - struct archive *a; - - extract_reference_file(reffile); - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_open_filename(a, reffile, 10240)); - - /* First header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("ppmd_lzss_conversion_test.txt", - archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(size, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - while (offset + (int)sizeof(buff) < size) - { - assertA(sizeof(buff) == archive_read_data(a, buff, sizeof(buff))); - offset += sizeof(buff); - } - assertA(size - offset == archive_read_data(a, buff, size - offset)); - assertEqualMem(buff, test_txt, size - offset); - - /* Test EOF */ - assertA(1 == archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_file_count(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_rar_binary) -{ - const char reffile[] = "test_read_format_rar_binary_data.rar"; - char *file1_buff = malloc(1048576); - int file1_size = 1048576; - const char file1_test_txt[] = "\x37\xef\xb2\xbe\x33\xf6\xcc\xcb\xee\x2a\x10" - "\x9d\x2e\x01\xe9\xf6\xf9\xe5\xe6\x67\x0c\x2b" - "\xd8\x6b\xa0\x26\x9a\xf7\x93\x87\x42\xf1\x08" - "\x42\xdc\x9b\x76\x91\x20\xa4\x01\xbe\x67\xbd" - "\x08\x74\xde\xec"; - char file2_buff[32618]; - int file2_size = sizeof(file2_buff); - const char file2_test_txt[] = "\x00\xee\x78\x00\x00\x4d\x45\x54\x41\x2d\x49" - "\x4e\x46\x2f\x6d\x61\x6e\x69\x66\x65\x73\x74" - "\x2e\x78\x6d\x6c\x50\x4b\x05\x06\x00\x00\x00" - "\x00\x12\x00\x12\x00\xaa\x04\x00\x00\xaa\x7a" - "\x00\x00\x00\x00"; - struct archive_entry *ae; - struct archive *a; - - extract_reference_file(reffile); - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_open_filename(a, reffile, 10240)); - - /* First header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("random_data.bin", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(file1_size, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertA(file1_size == archive_read_data(a, file1_buff, file1_size)); - assertEqualMem(&file1_buff[file1_size - sizeof(file1_test_txt) + 1], - file1_test_txt, sizeof(file1_test_txt) - 1); - - /* Second header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("LibarchiveAddingTest.odt", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(file2_size, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertA(file2_size == archive_read_data(a, file2_buff, file2_size)); - assertEqualMem(&file2_buff[file2_size + 1 - sizeof(file2_test_txt)], - file2_test_txt, sizeof(file2_test_txt) - 1); - - /* Test EOF */ - assertA(1 == archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_file_count(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - free(file1_buff); -} - -DEFINE_TEST(test_read_format_rar_windows) -{ - char buff[441]; - const char reffile[] = "test_read_format_rar_windows.rar"; - const char test_txt[] = "test text file\r\n"; - int size = sizeof(test_txt)-1; - struct archive_entry *ae; - struct archive *a; - - extract_reference_file(reffile); - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_open_filename(a, reffile, 10240)); - - /* First header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testdir/test.txt", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(16, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertA(size == archive_read_data(a, buff, size)); - assertEqualMem(buff, test_txt, size); - - /* Second header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.txt", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(16, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertA(size == archive_read_data(a, buff, size)); - assertEqualMem(buff, test_txt, size); - - /* Third header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testshortcut.lnk", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(sizeof(buff), archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertA(sizeof(buff) == archive_read_data(a, buff, sizeof(buff))); - - /* Fourth header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testdir", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(16877, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Fifth header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testemptydir", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(16877, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Test EOF */ - assertA(1 == archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_file_count(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_rar_multivolume) -{ - const char *reffiles[] = - { - "test_read_format_rar_multivolume.part0001.rar", - "test_read_format_rar_multivolume.part0002.rar", - "test_read_format_rar_multivolume.part0003.rar", - "test_read_format_rar_multivolume.part0004.rar", - NULL - }; - int file1_size = 241647978, offset = 0; - char buff[64]; - const char file1_test_txt[] = "gin-bottom: 0in\">
    \n

    \n\n" - ""; - char file2_buff[20111]; - int file2_size = sizeof(file2_buff); - const char file2_test_txt[] = "


    \n" - "

    \n" - "\n" - ""; - char file3_buff[20]; - int file3_size = sizeof(file3_buff); - const char file3_test_txt[] = "test text document\r\n"; - struct archive_entry *ae; - struct archive *a; - - extract_reference_files(reffiles); - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_open_filenames(a, reffiles, 10240)); - - /* First header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("ppmd_lzss_conversion_test.txt", - archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(file1_size, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - while (offset + (int)sizeof(buff) < file1_size) - { - assertA(sizeof(buff) == archive_read_data(a, buff, sizeof(buff))); - offset += sizeof(buff); - } - assertA(file1_size - offset == - archive_read_data(a, buff, file1_size - offset)); - assertEqualMem(buff, file1_test_txt, file1_size - offset); - - /* Second header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("LibarchiveAddingTest.html", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(file2_size, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertA(file2_size == archive_read_data(a, file2_buff, file2_size)); - assertEqualMem(&file2_buff[file2_size - sizeof(file2_test_txt) + 1], - file2_test_txt, sizeof(file2_test_txt) - 1); - - /* Third header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testlink", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(41471, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualString("LibarchiveAddingTest.html", archive_entry_symlink(ae)); - assertEqualIntA(a, 0, archive_read_data(a, file2_buff, 30)); - - /* Fourth header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testdir/test.txt", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(file3_size, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertA(file3_size == archive_read_data(a, file3_buff, file3_size)); - assertEqualMem(&file3_buff[file3_size + 1 - sizeof(file3_test_txt)], - file3_test_txt, sizeof(file3_test_txt) - 1); - - /* Fifth header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testdir/LibarchiveAddingTest.html", - archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(file2_size, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertA(file2_size == archive_read_data(a, file2_buff, file2_size)); - assertEqualMem(&file2_buff[file2_size - sizeof(file2_test_txt) + 1], - file2_test_txt, sizeof(file2_test_txt) - 1); - - /* Sixth header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testdir", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(16877, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Seventh header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testemptydir", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(16877, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Test EOF */ - assertA(1 == archive_read_next_header(a, &ae)); - assertEqualInt(7, archive_file_count(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_rar_multivolume_skip) -{ - const char *reffiles[] = - { - "test_read_format_rar_multivolume.part0001.rar", - "test_read_format_rar_multivolume.part0002.rar", - "test_read_format_rar_multivolume.part0003.rar", - "test_read_format_rar_multivolume.part0004.rar", - NULL - }; - int file1_size = 241647978; - int file2_size = 20111; - int file3_size = 20; - struct archive_entry *ae; - struct archive *a; - - extract_reference_files(reffiles); - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_open_filenames(a, reffiles, 10240)); - - /* First header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("ppmd_lzss_conversion_test.txt", - archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(file1_size, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Second header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("LibarchiveAddingTest.html", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(file2_size, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Third header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testlink", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(41471, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualString("LibarchiveAddingTest.html", archive_entry_symlink(ae)); - - /* Fourth header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testdir/test.txt", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(file3_size, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Fifth header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testdir/LibarchiveAddingTest.html", - archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(file2_size, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Sixth header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testdir", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(16877, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Seventh header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testemptydir", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(16877, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Test EOF */ - assertA(1 == archive_read_next_header(a, &ae)); - assertEqualInt(7, archive_file_count(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_rar_sfx) -{ - char buff[441]; - const char reffile[] = "test_read_format_rar_sfx.exe"; - const char test_txt[] = "test text file\r\n"; - int size = sizeof(test_txt)-1; - struct archive_entry *ae; - struct archive *a; - - extract_reference_file(reffile); - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_open_filename(a, reffile, 10240)); - - /* First header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.txt", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(16, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertA(size == archive_read_data(a, buff, size)); - assertEqualMem(buff, test_txt, size); - - /* Second header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testshortcut.lnk", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(sizeof(buff), archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertA(sizeof(buff) == archive_read_data(a, buff, sizeof(buff))); - - /* Third header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testdir/test.txt", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(16, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertA(size == archive_read_data(a, buff, size)); - assertEqualMem(buff, test_txt, size); - - /* Fourth header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testdir", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(16877, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Fifth header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testemptydir", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(16877, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Test EOF */ - assertA(1 == archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_file_count(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_rar_multivolume_stored_file) -{ - const char *reffiles[] = - { - "test_rar_multivolume_single_file.part1.rar", - "test_rar_multivolume_single_file.part2.rar", - "test_rar_multivolume_single_file.part3.rar", - NULL - }; - char file_buff[20111]; - int file_size = sizeof(file_buff); - const char file_test_txt[] = "


    \n" - "

    \n" - "\n" - ""; - struct archive_entry *ae; - struct archive *a; - - extract_reference_files(reffiles); - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_open_filenames(a, reffiles, 10240)); - - /* First header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("LibarchiveAddingTest.html", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(file_size, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertA(file_size == archive_read_data(a, file_buff, file_size)); - assertEqualMem(&file_buff[file_size - sizeof(file_test_txt) + 1], - file_test_txt, sizeof(file_test_txt) - 1); - - /* Test EOF */ - assertA(1 == archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_file_count(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_rar_multivolume_stored_file_skip) -{ - const char *reffiles[] = - { - "test_rar_multivolume_single_file.part1.rar", - "test_rar_multivolume_single_file.part2.rar", - "test_rar_multivolume_single_file.part3.rar", - NULL - }; - int file_size = 20111; - struct archive_entry *ae; - struct archive *a; - - extract_reference_files(reffiles); - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_open_filenames(a, reffiles, 10240)); - - /* First header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("LibarchiveAddingTest.html", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(file_size, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Test EOF */ - assertA(1 == archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_file_count(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_rar_multivolume_seek_data) -{ - const char *reffiles[] = - { - "test_rar_multivolume_single_file.part1.rar", - "test_rar_multivolume_single_file.part2.rar", - "test_rar_multivolume_single_file.part3.rar", - NULL - }; - char buff[64]; - int file_size = 20111; - const char file_test_txt1[] = "d. \n

    \n

    " - "
    \n

    \n\n"; - const char file_test_txt2[] = "\n<"; - const char file_test_txt3[] = "mplify writing such tests,\ntry to use plat" - "form-independent codin"; - const char file_test_txt4[] = "lString in the example above)\ngenerat" - "e detailed log message"; - const char file_test_txt5[] = "SS=\"western\">make check will usually" - " run\n\tall of the tests."; - struct archive_entry *ae; - struct archive *a; - - extract_reference_files(reffiles); - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_open_filenames(a, reffiles, 10240)); - - /* First header. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("LibarchiveAddingTest.html", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualInt(file_size, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Seek to the end minus 64 bytes */ - assertA(file_size - (int)sizeof(buff) == - archive_seek_data(a, file_size - (int)sizeof(buff), SEEK_SET)); - assertA(sizeof(buff) == archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, file_test_txt1, sizeof(file_test_txt1) - 1); - - /* Seek back to the beginning */ - assertA(0 == archive_seek_data(a, 0, SEEK_SET)); - assertA(sizeof(buff) == archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, file_test_txt2, sizeof(file_test_txt2) - 1); - - /* Seek to the middle of the combined data block */ - assertA(10054 == archive_seek_data(a, 10054, SEEK_SET)); - assertA(sizeof(buff) == archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, file_test_txt3, sizeof(file_test_txt3) - 1); - - /* Seek to 32 bytes before the end of the first data sub-block */ - assertA(6860 == archive_seek_data(a, 6860, SEEK_SET)); - assertA(sizeof(buff) == archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, file_test_txt4, sizeof(file_test_txt4) - 1); - - /* Seek to 32 bytes before the end of the second data sub-block */ - assertA(13752 == archive_seek_data(a, 13752, SEEK_SET)); - assertA(sizeof(buff) == archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, file_test_txt5, sizeof(file_test_txt5) - 1); - - /* Use various combinations of SEEK_SET, SEEK_CUR, and SEEK_END */ - assertEqualInt(file_size, archive_seek_data(a, 0, SEEK_END)); - assertEqualInt(0, archive_seek_data(a, 0, SEEK_SET)); - assertEqualInt(0, archive_seek_data(a, 0, SEEK_CUR)); - assertEqualInt(-1, archive_seek_data(a, -10, SEEK_CUR)); - assertEqualInt(10, archive_seek_data(a, 10, SEEK_CUR)); - assertEqualInt(-1, archive_seek_data(a, -20, SEEK_CUR)); - assertEqualInt(10, archive_seek_data(a, 0, SEEK_CUR)); - assertEqualInt(file_size, archive_seek_data(a, 0, SEEK_END)); - assertEqualInt(file_size - 20, archive_seek_data(a, -20, SEEK_END)); - assertEqualInt(file_size + 40, archive_seek_data(a, 40, SEEK_END)); - assertEqualInt(file_size + 40, archive_seek_data(a, 0, SEEK_CUR)); - assertEqualInt(file_size + 40 + 20, archive_seek_data(a, 20, SEEK_CUR)); - assertEqualInt(file_size + 40 + 20 + 20, archive_seek_data(a, 20, SEEK_CUR)); - assertEqualInt(file_size + 20, archive_seek_data(a, 20, SEEK_END)); - assertEqualInt(file_size - 20, archive_seek_data(a, -20, SEEK_END)); - - /* - * Attempt to read from the end of the file. These should return - * 0 for end of file. - */ - assertEqualInt(file_size, archive_seek_data(a, 0, SEEK_END)); - assertA(0 == archive_read_data(a, buff, sizeof(buff))); - assertEqualInt(file_size + 40, archive_seek_data(a, 40, SEEK_CUR)); - assertA(0 == archive_read_data(a, buff, sizeof(buff))); - - /* Seek to the end minus 64 bytes */ - assertA(0 == archive_seek_data(a, 0, SEEK_SET)); - assertA(file_size - (int)sizeof(buff) == - archive_seek_data(a, -(int)sizeof(buff), SEEK_END)); - assertA(sizeof(buff) == archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, file_test_txt1, sizeof(file_test_txt1) - 1); - - /* The file position should be at the end of the file here */ - assertA(file_size == archive_seek_data(a, 0, SEEK_CUR)); - - /* Seek back to the beginning */ - assertA(0 == archive_seek_data(a, -file_size, SEEK_CUR)); - assertA(sizeof(buff) == archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, file_test_txt2, sizeof(file_test_txt2) - 1); - - /* Seek to the middle of the combined data block */ - assertA(10054 == archive_seek_data(a, 10054 - (int)sizeof(buff), SEEK_CUR)); - assertA(sizeof(buff) == archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, file_test_txt3, sizeof(file_test_txt3) - 1); - - /* Seek to 32 bytes before the end of the first data sub-block */ - assertA(6860 == archive_seek_data(a, 6860 - (10054 + (int)sizeof(buff)), - SEEK_CUR)); - assertA(sizeof(buff) == archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, file_test_txt4, sizeof(file_test_txt4) - 1); - - /* Seek to 32 bytes before the end of the second data sub-block */ - assertA(13752 == archive_seek_data(a, 13752 - file_size, SEEK_END)); - assertA(sizeof(buff) == archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, file_test_txt5, sizeof(file_test_txt5) - 1); - - /* Test EOF */ - assertA(1 == archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_file_count(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_rar_multivolume_seek_multiple_files) -{ - const char *reffiles[] = - { - "test_rar_multivolume_multiple_files.part1.rar", - "test_rar_multivolume_multiple_files.part2.rar", - "test_rar_multivolume_multiple_files.part3.rar", - "test_rar_multivolume_multiple_files.part4.rar", - "test_rar_multivolume_multiple_files.part5.rar", - "test_rar_multivolume_multiple_files.part6.rar", - NULL - }; - char buff[64]; - int file_size = 20111; - const char file_test_txt1[] = "d. \n

    \n

    " - "
    \n

    \n\n"; - const char file_test_txt2[] = "\n<"; - const char file_test_txt3[] = "mplify writing such tests,\ntry to use plat" - "form-independent codin"; - const char file_test_txt4[] = "\nfailures. \n

    \n
    \n

    The " - "large tar tester attempts to", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 4576, - archive_seek_data(a, 4576, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "hat was expected. \n

    \n

    \n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 20111 - (int)(sizeof(buff)-1), SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 4576, - archive_seek_data(a, 4576, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "hat was expected. \n

    \n

    Large tar tester

    \n

    The " - "large tar tester attempts to", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, 0, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 20111 - (int)(sizeof(buff)-1), SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, 0, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 17749, - archive_seek_data(a, 17749, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\">Large tar tester

    \n

    The " - "large tar tester attempts to", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 4576, - archive_seek_data(a, 4576, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "hat was expected. \n

    \n

    \n

    Large tar tester

    \n

    The " - "large tar tester attempts to", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 2236, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 17749, - archive_seek_data(a, -2362, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\">Large tar tester

    \n

    The " - "large tar tester attempts to", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 4576, - archive_seek_data(a, -13236, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "hat was expected. \n

    \n

    \n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 19985, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 4576, - archive_seek_data(a, -15535, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "hat was expected. \n

    \n

    Large tar tester

    \n

    The " - "large tar tester attempts to", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -17812, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 19985, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -20111, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 17749, - archive_seek_data(a, 17686, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\">Large tar tester

    \n

    The " - "large tar tester attempts to", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 4576, - archive_seek_data(a, -13236, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "hat was expected. \n

    \n

    \n

    Large tar tester

    \n

    The " - "large tar tester attempts to", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, -((int)sizeof(buff)-1), SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 17749, - archive_seek_data(a, -2362, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\">Large tar tester

    \n

    The " - "large tar tester attempts to", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 4576, - archive_seek_data(a, -15535, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "hat was expected. \n

    \n

    \n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, -((int)sizeof(buff)-1), SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 4576, - archive_seek_data(a, -15535, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "hat was expected. \n

    \n

    Large tar tester

    \n

    The " - "large tar tester attempts to", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -20111, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, -((int)sizeof(buff)-1), SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -20111, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 17749, - archive_seek_data(a, -2362, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\">Large tar tester

    \n

    The " - "large tar tester attempts to", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 4576, - archive_seek_data(a, -15535, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "hat was expected. \n

    \n

    '0@9&]C=6UE;G0- -M"J'(=."0,0````````````,`````8W?:/A0P!P#M00``=&5S=&1I61I -#include - -#define PROLOGUE(reffile) \ - struct archive_entry *ae; \ - struct archive *a; \ - \ - (void) a; /* Make the compiler happy if we won't use this variables */ \ - (void) ae; /* in the test cases. */ \ - \ - extract_reference_file(reffile); \ - assert((a = archive_read_new()) != NULL); \ - assertA(0 == archive_read_support_filter_all(a)); \ - assertA(0 == archive_read_support_format_all(a)); \ - assertA(0 == archive_read_open_filename(a, reffile, 10240)) - -#define PROLOGUE_MULTI(reffile) \ - struct archive_entry *ae; \ - struct archive *a; \ - \ - (void) a; \ - (void) ae; \ - \ - extract_reference_files(reffile); \ - assert((a = archive_read_new()) != NULL); \ - assertA(0 == archive_read_support_filter_all(a)); \ - assertA(0 == archive_read_support_format_all(a)); \ - assertA(0 == archive_read_open_filenames(a, reffile, 10240)) - - -#define EPILOGUE() \ - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); \ - assertEqualInt(ARCHIVE_OK, archive_read_free(a)) - -static -int verify_data(const uint8_t* data_ptr, int magic, int size) { - int i = 0; - - /* This is how the test data inside test files was generated; - * we are re-generating it here and we check if our re-generated - * test data is the same as in the test file. If this test is - * failing it's either because there's a bug in the test case, - * or the unpacked data is corrupted. */ - - for(i = 0; i < size / 4; ++i) { - const int k = i + 1; - const signed int* lptr = (const signed int*) &data_ptr[i * 4]; - signed int val = k * k - 3 * k + (1 + magic); - - if(val < 0) - val = 0; - - /* *lptr is a value inside unpacked test file, val is the - * value that should be in the unpacked test file. */ - - if(archive_le32dec(lptr) != (uint32_t) val) - return 0; - } - - return 1; -} - -static -int extract_one(struct archive* a, struct archive_entry* ae, uint32_t crc) { - la_ssize_t fsize, bytes_read; - uint8_t* buf; - int ret = 1; - uint32_t computed_crc; - - fsize = (la_ssize_t) archive_entry_size(ae); - buf = malloc(fsize); - if(buf == NULL) - return 1; - - bytes_read = archive_read_data(a, buf, fsize); - if(bytes_read != fsize) { - assertEqualInt(bytes_read, fsize); - goto fn_exit; - } - - computed_crc = crc32(0, buf, fsize); - assertEqualInt(computed_crc, crc); - ret = 0; - -fn_exit: - free(buf); - return ret; -} - -DEFINE_TEST(test_read_format_rar5_set_format) -{ - struct archive *a; - struct archive_entry *ae; - const char reffile[] = "test_read_format_rar5_stored.rar"; - - extract_reference_file(reffile); - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_RAR_V5)); - assertA(0 == archive_read_open_filename(a, reffile, 10240)); - assertA(0 == archive_read_next_header(a, &ae)); - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_stored) -{ - const char helloworld_txt[] = "hello libarchive test suite!\n"; - la_ssize_t file_size = sizeof(helloworld_txt) - 1; - char buff[64]; - - PROLOGUE("test_read_format_rar5_stored.rar"); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("helloworld.txt", archive_entry_pathname(ae)); - assertA((int) archive_entry_mtime(ae) > 0); - assertA((int) archive_entry_ctime(ae) == 0); - assertA((int) archive_entry_atime(ae) == 0); - assertEqualInt(file_size, archive_entry_size(ae)); - assertEqualInt(33188, archive_entry_mode(ae)); - assertA(file_size == archive_read_data(a, buff, file_size)); - assertEqualMem(buff, helloworld_txt, file_size); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_compressed) -{ - const int DATA_SIZE = 1200; - uint8_t buff[1200]; - - PROLOGUE("test_read_format_rar5_compressed.rar"); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.bin", archive_entry_pathname(ae)); - assertA((int) archive_entry_mtime(ae) > 0); - assertEqualInt(DATA_SIZE, archive_entry_size(ae)); - assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE)); - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - assertA(1 == verify_data(buff, 0, DATA_SIZE)); - - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_multiple_files) -{ - const int DATA_SIZE = 4096; - uint8_t buff[4096]; - - PROLOGUE("test_read_format_rar5_multiple_files.rar"); - - /* There should be 4 files inside this test file. Check for their - * existence, and also check the contents of those test files. */ - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test1.bin", archive_entry_pathname(ae)); - assertEqualInt(DATA_SIZE, archive_entry_size(ae)); - assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE)); - assertA(1 == verify_data(buff, 1, DATA_SIZE)); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test2.bin", archive_entry_pathname(ae)); - assertEqualInt(DATA_SIZE, archive_entry_size(ae)); - assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE)); - assertA(1 == verify_data(buff, 2, DATA_SIZE)); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test3.bin", archive_entry_pathname(ae)); - assertEqualInt(DATA_SIZE, archive_entry_size(ae)); - assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE)); - assertA(1 == verify_data(buff, 3, DATA_SIZE)); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test4.bin", archive_entry_pathname(ae)); - assertEqualInt(DATA_SIZE, archive_entry_size(ae)); - assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE)); - assertA(1 == verify_data(buff, 4, DATA_SIZE)); - - /* There should be no more files in this archive. */ - - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - EPILOGUE(); -} - -/* This test is really the same as the test above, but it deals with a solid - * archive instead of a regular archive. The test solid archive contains the - * same set of files as regular test archive, but it's size is 2x smaller, - * because solid archives reuse the window buffer from previous compressed - * files, so it's able to compress lots of small files more effectively. */ - -DEFINE_TEST(test_read_format_rar5_multiple_files_solid) -{ - const int DATA_SIZE = 4096; - uint8_t buff[4096]; - - PROLOGUE("test_read_format_rar5_multiple_files_solid.rar"); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test1.bin", archive_entry_pathname(ae)); - assertEqualInt(DATA_SIZE, archive_entry_size(ae)); - assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE)); - assertA(1 == verify_data(buff, 1, DATA_SIZE)); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test2.bin", archive_entry_pathname(ae)); - assertEqualInt(DATA_SIZE, archive_entry_size(ae)); - assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE)); - assertA(1 == verify_data(buff, 2, DATA_SIZE)); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test3.bin", archive_entry_pathname(ae)); - assertEqualInt(DATA_SIZE, archive_entry_size(ae)); - assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE)); - assertA(1 == verify_data(buff, 3, DATA_SIZE)); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test4.bin", archive_entry_pathname(ae)); - assertEqualInt(DATA_SIZE, archive_entry_size(ae)); - assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE)); - assertA(1 == verify_data(buff, 4, DATA_SIZE)); - - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_multiarchive_skip_all) -{ - const char* reffiles[] = { - "test_read_format_rar5_multiarchive.part01.rar", - "test_read_format_rar5_multiarchive.part02.rar", - "test_read_format_rar5_multiarchive.part03.rar", - "test_read_format_rar5_multiarchive.part04.rar", - "test_read_format_rar5_multiarchive.part05.rar", - "test_read_format_rar5_multiarchive.part06.rar", - "test_read_format_rar5_multiarchive.part07.rar", - "test_read_format_rar5_multiarchive.part08.rar", - NULL - }; - - PROLOGUE_MULTI(reffiles); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("home/antek/temp/build/unrar5/libarchive/bin/bsdcat_test", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("home/antek/temp/build/unrar5/libarchive/bin/bsdtar_test", archive_entry_pathname(ae)); - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_multiarchive_skip_all_but_first) -{ - const char* reffiles[] = { - "test_read_format_rar5_multiarchive.part01.rar", - "test_read_format_rar5_multiarchive.part02.rar", - "test_read_format_rar5_multiarchive.part03.rar", - "test_read_format_rar5_multiarchive.part04.rar", - "test_read_format_rar5_multiarchive.part05.rar", - "test_read_format_rar5_multiarchive.part06.rar", - "test_read_format_rar5_multiarchive.part07.rar", - "test_read_format_rar5_multiarchive.part08.rar", - NULL - }; - - PROLOGUE_MULTI(reffiles); - assertA(0 == archive_read_next_header(a, &ae)); - assertA(0 == extract_one(a, ae, 0x35277473)); - assertA(0 == archive_read_next_header(a, &ae)); - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_multiarchive_skip_all_but_second) -{ - const char* reffiles[] = { - "test_read_format_rar5_multiarchive.part01.rar", - "test_read_format_rar5_multiarchive.part02.rar", - "test_read_format_rar5_multiarchive.part03.rar", - "test_read_format_rar5_multiarchive.part04.rar", - "test_read_format_rar5_multiarchive.part05.rar", - "test_read_format_rar5_multiarchive.part06.rar", - "test_read_format_rar5_multiarchive.part07.rar", - "test_read_format_rar5_multiarchive.part08.rar", - NULL - }; - - PROLOGUE_MULTI(reffiles); - assertA(0 == archive_read_next_header(a, &ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertA(0 == extract_one(a, ae, 0xE59665F8)); - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_blake2) -{ - const la_ssize_t proper_size = 814; - uint8_t buf[814]; - - PROLOGUE("test_read_format_rar5_blake2.rar"); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualInt(proper_size, archive_entry_size(ae)); - - /* Should blake2 calculation fail, we'll get a failure return - * value from archive_read_data(). */ - - assertA(proper_size == archive_read_data(a, buf, proper_size)); - - /* To be extra pedantic, let's also check crc32 of the poem. */ - assertEqualInt(crc32(0, buf, proper_size), 0x7E5EC49E); - - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_arm_filter) -{ - /* This test unpacks a file that uses an ARM filter. The DELTA - * and X86 filters are tested implicitly in the "multiarchive_skip" - * test. */ - - const la_ssize_t proper_size = 90808; - uint8_t buf[90808]; - - PROLOGUE("test_read_format_rar5_arm.rar"); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualInt(proper_size, archive_entry_size(ae)); - assertA(proper_size == archive_read_data(a, buf, proper_size)); - - /* Yes, RARv5 unpacker itself should calculate the CRC, but in case - * the DONT_FAIL_ON_CRC_ERROR define option is enabled during compilation, - * let's still fail the test if the unpacked data is wrong. */ - assertEqualInt(crc32(0, buf, proper_size), 0x886F91EB); - - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_stored_skip_all) -{ - const char* fname = "test_read_format_rar5_stored_manyfiles.rar"; - - PROLOGUE(fname); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("make_uue.tcl", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("cebula.txt", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.bin", archive_entry_pathname(ae)); - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_stored_skip_in_part) -{ - const char* fname = "test_read_format_rar5_stored_manyfiles.rar"; - char buf[6]; - - /* Skip first, extract in part rest. */ - - PROLOGUE(fname); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("make_uue.tcl", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("cebula.txt", archive_entry_pathname(ae)); - assertA(6 == archive_read_data(a, buf, 6)); - assertEqualInt(0, memcmp(buf, "Cebula", 6)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.bin", archive_entry_pathname(ae)); - assertA(4 == archive_read_data(a, buf, 4)); - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_stored_skip_all_but_first) -{ - const char* fname = "test_read_format_rar5_stored_manyfiles.rar"; - char buf[405]; - - /* Extract first, skip rest. */ - - PROLOGUE(fname); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("make_uue.tcl", archive_entry_pathname(ae)); - assertA(405 == archive_read_data(a, buf, sizeof(buf))); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("cebula.txt", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.bin", archive_entry_pathname(ae)); - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_stored_skip_all_in_part) -{ - const char* fname = "test_read_format_rar5_stored_manyfiles.rar"; - char buf[4]; - - /* Extract in part all */ - - PROLOGUE(fname); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("make_uue.tcl", archive_entry_pathname(ae)); - assertA(4 == archive_read_data(a, buf, 4)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("cebula.txt", archive_entry_pathname(ae)); - assertA(4 == archive_read_data(a, buf, 4)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.bin", archive_entry_pathname(ae)); - assertA(4 == archive_read_data(a, buf, 4)); - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_multiarchive_solid_extr_all) -{ - const char* reffiles[] = { - "test_read_format_rar5_multiarchive_solid.part01.rar", - "test_read_format_rar5_multiarchive_solid.part02.rar", - "test_read_format_rar5_multiarchive_solid.part03.rar", - "test_read_format_rar5_multiarchive_solid.part04.rar", - NULL - }; - - PROLOGUE_MULTI(reffiles); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("cebula.txt", archive_entry_pathname(ae)); - assertA(0 == extract_one(a, ae, 0x7E5EC49E)); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.bin", archive_entry_pathname(ae)); - assertA(0 == extract_one(a, ae, 0x7cca70cd)); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test1.bin", archive_entry_pathname(ae)); - assertA(0 == extract_one(a, ae, 0x7e13b2c6)); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test2.bin", archive_entry_pathname(ae)); - assertA(0 == extract_one(a, ae, 0xf166afcb)); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test3.bin", archive_entry_pathname(ae)); - assertA(0 == extract_one(a, ae, 0x9fb123d9)); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test4.bin", archive_entry_pathname(ae)); - assertA(0 == extract_one(a, ae, 0x10c43ed4)); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test5.bin", archive_entry_pathname(ae)); - assertA(0 == extract_one(a, ae, 0xb9d155f2)); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test6.bin", archive_entry_pathname(ae)); - assertA(0 == extract_one(a, ae, 0x36a448ff)); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("elf-Linux-ARMv7-ls", archive_entry_pathname(ae)); - assertA(0 == extract_one(a, ae, 0x886F91EB)); - - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip_all) -{ - const char* reffiles[] = { - "test_read_format_rar5_multiarchive_solid.part01.rar", - "test_read_format_rar5_multiarchive_solid.part02.rar", - "test_read_format_rar5_multiarchive_solid.part03.rar", - "test_read_format_rar5_multiarchive_solid.part04.rar", - NULL - }; - - PROLOGUE_MULTI(reffiles); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("cebula.txt", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test1.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test2.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test3.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test4.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test5.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test6.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("elf-Linux-ARMv7-ls", archive_entry_pathname(ae)); - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip_all_but_first) -{ - const char* reffiles[] = { - "test_read_format_rar5_multiarchive_solid.part01.rar", - "test_read_format_rar5_multiarchive_solid.part02.rar", - "test_read_format_rar5_multiarchive_solid.part03.rar", - "test_read_format_rar5_multiarchive_solid.part04.rar", - NULL - }; - - PROLOGUE_MULTI(reffiles); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("cebula.txt", archive_entry_pathname(ae)); - assertA(0 == extract_one(a, ae, 0x7E5EC49E)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test1.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test2.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test3.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test4.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test5.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test6.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("elf-Linux-ARMv7-ls", archive_entry_pathname(ae)); - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - EPILOGUE(); -} - -/* "skip_all_but_scnd" -> am I hitting the test name limit here after - * expansion of "scnd" to "second"? */ - -DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip_all_but_scnd) -{ - const char* reffiles[] = { - "test_read_format_rar5_multiarchive_solid.part01.rar", - "test_read_format_rar5_multiarchive_solid.part02.rar", - "test_read_format_rar5_multiarchive_solid.part03.rar", - "test_read_format_rar5_multiarchive_solid.part04.rar", - NULL - }; - - PROLOGUE_MULTI(reffiles); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("cebula.txt", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.bin", archive_entry_pathname(ae)); - assertA(0 == extract_one(a, ae, 0x7CCA70CD)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test1.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test2.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test3.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test4.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test5.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test6.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("elf-Linux-ARMv7-ls", archive_entry_pathname(ae)); - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip_all_but_third) -{ - const char* reffiles[] = { - "test_read_format_rar5_multiarchive_solid.part01.rar", - "test_read_format_rar5_multiarchive_solid.part02.rar", - "test_read_format_rar5_multiarchive_solid.part03.rar", - "test_read_format_rar5_multiarchive_solid.part04.rar", - NULL - }; - - PROLOGUE_MULTI(reffiles); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("cebula.txt", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test1.bin", archive_entry_pathname(ae)); - assertA(0 == extract_one(a, ae, 0x7E13B2C6)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test2.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test3.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test4.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test5.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test6.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("elf-Linux-ARMv7-ls", archive_entry_pathname(ae)); - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip_all_but_last) -{ - const char* reffiles[] = { - "test_read_format_rar5_multiarchive_solid.part01.rar", - "test_read_format_rar5_multiarchive_solid.part02.rar", - "test_read_format_rar5_multiarchive_solid.part03.rar", - "test_read_format_rar5_multiarchive_solid.part04.rar", - NULL - }; - - PROLOGUE_MULTI(reffiles); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("cebula.txt", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test1.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test2.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test3.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test4.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test5.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test6.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("elf-Linux-ARMv7-ls", archive_entry_pathname(ae)); - assertA(0 == extract_one(a, ae, 0x886F91EB)); - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_solid_skip_all) -{ - const char* reffile = "test_read_format_rar5_solid.rar"; - - /* Skip all */ - - PROLOGUE(reffile); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test1.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test2.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test3.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test4.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test5.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test6.bin", archive_entry_pathname(ae)); - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_solid_skip_all_but_first) -{ - const char* reffile = "test_read_format_rar5_solid.rar"; - - /* Extract first, skip rest */ - - PROLOGUE(reffile); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.bin", archive_entry_pathname(ae)); - assertA(0 == extract_one(a, ae, 0x7CCA70CD)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test1.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test2.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test3.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test4.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test5.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test6.bin", archive_entry_pathname(ae)); - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_solid_skip_all_but_second) -{ - const char* reffile = "test_read_format_rar5_solid.rar"; - - /* Skip first, extract second, skip rest */ - - PROLOGUE(reffile); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test1.bin", archive_entry_pathname(ae)); - assertA(0 == extract_one(a, ae, 0x7E13B2C6)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test2.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test3.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test4.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test5.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test6.bin", archive_entry_pathname(ae)); - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_solid_skip_all_but_last) -{ - const char* reffile = "test_read_format_rar5_solid.rar"; - - /* Skip all but last, extract last */ - - PROLOGUE(reffile); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test1.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test2.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test3.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test4.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test5.bin", archive_entry_pathname(ae)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test6.bin", archive_entry_pathname(ae)); - assertA(0 == extract_one(a, ae, 0x36A448FF)); - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_extract_win32) -{ - PROLOGUE("test_read_format_rar5_win32.rar"); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("testdir", archive_entry_pathname(ae)); - assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755); - assertA(0 == extract_one(a, ae, 0)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.bin", archive_entry_pathname(ae)); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); - assertA(0 == extract_one(a, ae, 0x7CCA70CD)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test1.bin", archive_entry_pathname(ae)); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); - assertA(0 == extract_one(a, ae, 0x7E13B2C6)); - assertA(0 == archive_read_next_header(a, &ae)); - /* Read only file */ - assertEqualString("test2.bin", archive_entry_pathname(ae)); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0444); - assertA(0 == extract_one(a, ae, 0xF166AFCB)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test3.bin", archive_entry_pathname(ae)); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); - assertA(0 == extract_one(a, ae, 0x9FB123D9)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test4.bin", archive_entry_pathname(ae)); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); - assertA(0 == extract_one(a, ae, 0x10C43ED4)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test5.bin", archive_entry_pathname(ae)); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); - assertA(0 == extract_one(a, ae, 0xB9D155F2)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test6.bin", archive_entry_pathname(ae)); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); - assertA(0 == extract_one(a, ae, 0x36A448FF)); - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_block_by_block) -{ - /* This test uses strange buffer sizes intentionally. */ - - struct archive_entry *ae; - struct archive *a; - uint8_t buf[173]; - int bytes_read; - uint32_t computed_crc = 0; - - extract_reference_file("test_read_format_rar5_compressed.rar"); - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_open_filename(a, "test_read_format_rar5_compressed.rar", 130)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.bin", archive_entry_pathname(ae)); - assertEqualInt(1200, archive_entry_size(ae)); - - /* File size is 1200 bytes, we're reading it using a buffer of 173 bytes. - * Libarchive is configured to use a buffer of 130 bytes. */ - - while(1) { - /* archive_read_data should return one of: - * a) 0, if there is no more data to be read, - * b) negative value, if there was an error, - * c) positive value, meaning how many bytes were read. - */ - - bytes_read = archive_read_data(a, buf, sizeof(buf)); - assertA(bytes_read >= 0); - if(bytes_read <= 0) - break; - - computed_crc = crc32(computed_crc, buf, bytes_read); - } - - assertEqualInt(computed_crc, 0x7CCA70CD); - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_owner) -{ - const int DATA_SIZE = 5; - uint8_t buff[5]; - - PROLOGUE("test_read_format_rar5_owner.rar"); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("root.txt", archive_entry_pathname(ae)); - assertEqualString("root", archive_entry_uname(ae)); - assertEqualString("wheel", archive_entry_gname(ae)); - assertA((int) archive_entry_mtime(ae) > 0); - assertEqualInt(DATA_SIZE, archive_entry_size(ae)); - assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE)); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("nobody.txt", archive_entry_pathname(ae)); - assertEqualString("nobody", archive_entry_uname(ae)); - assertEqualString("nogroup", archive_entry_gname(ae)); - assertA((int) archive_entry_mtime(ae) > 0); - assertEqualInt(DATA_SIZE, archive_entry_size(ae)); - assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE)); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("numeric.txt", archive_entry_pathname(ae)); - assertEqualInt(9999, archive_entry_uid(ae)); - assertEqualInt(8888, archive_entry_gid(ae)); - assertA((int) archive_entry_mtime(ae) > 0); - assertEqualInt(DATA_SIZE, archive_entry_size(ae)); - assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE)); - - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_symlink) -{ - const int DATA_SIZE = 5; - uint8_t buff[5]; - - PROLOGUE("test_read_format_rar5_symlink.rar"); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("file.txt", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertA((int) archive_entry_mtime(ae) > 0); - assertEqualInt(DATA_SIZE, archive_entry_size(ae)); - assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE)); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("symlink.txt", archive_entry_pathname(ae)); - assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); - assertEqualString("file.txt", archive_entry_symlink(ae)); - assertEqualInt(AE_SYMLINK_TYPE_FILE, archive_entry_symlink_type(ae)); - assertA(0 == archive_read_data(a, NULL, archive_entry_size(ae))); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("dirlink", archive_entry_pathname(ae)); - assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); - assertEqualString("dir", archive_entry_symlink(ae)); - assertEqualInt(AE_SYMLINK_TYPE_DIRECTORY, archive_entry_symlink_type(ae)); - assertA(0 == archive_read_data(a, NULL, archive_entry_size(ae))); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("dir", archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertA(0 == archive_read_data(a, NULL, archive_entry_size(ae))); - - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_hardlink) -{ - const int DATA_SIZE = 5; - uint8_t buff[5]; - - PROLOGUE("test_read_format_rar5_hardlink.rar"); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("file.txt", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertA((int) archive_entry_mtime(ae) > 0); - assertEqualInt(DATA_SIZE, archive_entry_size(ae)); - assertA(DATA_SIZE == archive_read_data(a, buff, DATA_SIZE)); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("hardlink.txt", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualString("file.txt", archive_entry_hardlink(ae)); - assertA(0 == archive_read_data(a, NULL, archive_entry_size(ae))); - - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_extra_field_version) -{ - PROLOGUE("test_read_format_rar5_extra_field_version.rar"); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("bin/2to3;1", archive_entry_pathname(ae)); - assertA(0 == extract_one(a, ae, 0xF24181B7)); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("bin/2to3", archive_entry_pathname(ae)); - assertA(0 == extract_one(a, ae, 0xF24181B7)); - - assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); - - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_readtables_overflow) -{ - uint8_t buf[16]; - - PROLOGUE("test_read_format_rar5_readtables_overflow.rar"); - - /* This archive is invalid. However, processing it shouldn't cause any - * buffer overflow errors during reading rar5 tables. */ - - (void) archive_read_next_header(a, &ae); - (void) archive_read_data(a, buf, sizeof(buf)); - (void) archive_read_next_header(a, &ae); - - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_leftshift1) -{ - uint8_t buf[16]; - - PROLOGUE("test_read_format_rar5_leftshift1.rar"); - - /* This archive is invalid. However, processing it shouldn't cause any - * errors related to undefined operations when using -fsanitize. */ - - (void) archive_read_next_header(a, &ae); - (void) archive_read_data(a, buf, sizeof(buf)); - (void) archive_read_next_header(a, &ae); - - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_leftshift2) -{ - uint8_t buf[16]; - - PROLOGUE("test_read_format_rar5_leftshift2.rar"); - - /* This archive is invalid. However, processing it shouldn't cause any - * errors related to undefined operations when using -fsanitize. */ - - (void) archive_read_next_header(a, &ae); - (void) archive_read_data(a, buf, sizeof(buf)); - (void) archive_read_next_header(a, &ae); - - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_truncated_huff) -{ - uint8_t buf[16]; - - PROLOGUE("test_read_format_rar5_truncated_huff.rar"); - - /* This archive is invalid. However, processing it shouldn't cause any - * errors related to undefined operations when using -fsanitize. */ - - (void) archive_read_next_header(a, &ae); - (void) archive_read_data(a, buf, sizeof(buf)); - (void) archive_read_next_header(a, &ae); - - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_invalid_dict_reference) -{ - uint8_t buf[16]; - - PROLOGUE("test_read_format_rar5_invalid_dict_reference.rar"); - - /* This test should fail on parsing the header. */ - assertA(archive_read_next_header(a, &ae) != ARCHIVE_OK); - - /* This archive is invalid. However, processing it shouldn't cause any - * errors related to buffer underflow when using -fsanitize. */ - assertA(archive_read_data(a, buf, sizeof(buf)) <= 0); - - /* This test only cares about not returning success here. */ - assertA(ARCHIVE_OK != archive_read_next_header(a, &ae)); - - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_distance_overflow) -{ - uint8_t buf[16]; - - PROLOGUE("test_read_format_rar5_distance_overflow.rar"); - - /* This archive is invalid. However, processing it shouldn't cause any - * errors related to variable overflows when using -fsanitize. */ - - (void) archive_read_next_header(a, &ae); - (void) archive_read_data(a, buf, sizeof(buf)); - (void) archive_read_next_header(a, &ae); - - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_nonempty_dir_stream) -{ - uint8_t buf[16]; - - PROLOGUE("test_read_format_rar5_nonempty_dir_stream.rar"); - - /* This archive is invalid. However, processing it shouldn't cause any - * errors related to buffer overflows when using -fsanitize. */ - - (void) archive_read_next_header(a, &ae); - (void) archive_read_data(a, buf, sizeof(buf)); - (void) archive_read_next_header(a, &ae); - - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_fileattr) -{ - unsigned long set, clear, flag; - - flag = 0; - - PROLOGUE("test_read_format_rar5_fileattr.rar"); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_mode(ae), 0444 | AE_IFREG); - assertEqualString("readonly.txt", archive_entry_pathname(ae)); - assertEqualString("rdonly", archive_entry_fflags_text(ae)); - archive_entry_fflags(ae, &set, &clear); -#if defined(__FreeBSD__) - flag = UF_READONLY; -#elif defined(_WIN32) && !defined(CYGWIN) - flag = FILE_ATTRIBUTE_READONLY; -#endif - assertEqualInt(flag, set & flag); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_mode(ae), 0644 | AE_IFREG); - assertEqualString("hidden.txt", archive_entry_pathname(ae)); - assertEqualString("hidden", archive_entry_fflags_text(ae)); - archive_entry_fflags(ae, &set, &clear); -#if defined(__FreeBSD__) - flag = UF_HIDDEN; -#elif defined(_WIN32) && !defined(CYGWIN) - flag = FILE_ATTRIBUTE_HIDDEN; -#endif - assertEqualInt(flag, set & flag); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_mode(ae), 0644 | AE_IFREG); - assertEqualString("system.txt", archive_entry_pathname(ae)); - assertEqualString("system", archive_entry_fflags_text(ae)); - archive_entry_fflags(ae, &set, &clear); -#if defined(__FreeBSD__) - flag = UF_SYSTEM;; -#elif defined(_WIN32) && !defined(CYGWIN) - flag = FILE_ATTRIBUTE_SYSTEM; -#endif - assertEqualInt(flag, set & flag); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_mode(ae), 0444 | AE_IFREG); - assertEqualString("ro_hidden.txt", archive_entry_pathname(ae)); - assertEqualString("rdonly,hidden", archive_entry_fflags_text(ae)); - archive_entry_fflags(ae, &set, &clear); -#if defined(__FreeBSD__) - flag = UF_READONLY | UF_HIDDEN; -#elif defined(_WIN32) && !defined(CYGWIN) - flag = FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN; -#endif - assertEqualInt(flag, set & flag); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_mode(ae), 0555 | AE_IFDIR); - assertEqualString("dir_readonly", archive_entry_pathname(ae)); - assertEqualString("rdonly", archive_entry_fflags_text(ae)); - archive_entry_fflags(ae, &set, &clear); -#if defined(__FreeBSD__) - flag = UF_READONLY; -#elif defined(_WIN32) && !defined(CYGWIN) - flag = FILE_ATTRIBUTE_READONLY; -#endif - assertEqualInt(flag, set & flag); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_mode(ae), 0755 | AE_IFDIR); - assertEqualString("dir_hidden", archive_entry_pathname(ae)); - assertEqualString("hidden", archive_entry_fflags_text(ae)); - archive_entry_fflags(ae, &set, &clear); -#if defined(__FreeBSD__) - flag = UF_HIDDEN; -#elif defined(_WIN32) && !defined(CYGWIN) - flag = FILE_ATTRIBUTE_HIDDEN; -#endif - assertEqualInt(flag, set & flag); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_mode(ae), 0755 | AE_IFDIR); - assertEqualString("dir_system", archive_entry_pathname(ae)); - assertEqualString("system", archive_entry_fflags_text(ae)); - archive_entry_fflags(ae, &set, &clear); -#if defined(__FreeBSD__) - flag = UF_SYSTEM; -#elif defined(_WIN32) && !defined(CYGWIN) - flag = FILE_ATTRIBUTE_SYSTEM; -#endif - assertEqualInt(flag, set & flag); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_mode(ae), 0555 | AE_IFDIR); - assertEqualString("dir_rohidden", archive_entry_pathname(ae)); - assertEqualString("rdonly,hidden", archive_entry_fflags_text(ae)); - archive_entry_fflags(ae, &set, &clear); -#if defined(__FreeBSD__) - flag = UF_READONLY | UF_HIDDEN; -#elif defined(_WIN32) && !defined(CYGWIN) - flag = FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN; -#endif - assertEqualInt(flag, set & flag); - - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_different_window_size) -{ - char buf[4096]; - PROLOGUE("test_read_format_rar5_different_window_size.rar"); - - /* Return codes of those calls are ignored, because this sample file - * is invalid. However, the unpacker shouldn't produce any SIGSEGV - * errors during processing. */ - - (void) archive_read_next_header(a, &ae); - while(0 < archive_read_data(a, buf, sizeof(buf))) {} - - (void) archive_read_next_header(a, &ae); - while(0 < archive_read_data(a, buf, sizeof(buf))) {} - - (void) archive_read_next_header(a, &ae); - while(0 < archive_read_data(a, buf, sizeof(buf))) {} - - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_window_buf_and_size_desync) -{ - /* oss fuzz 30442 */ - - char buf[4096]; - PROLOGUE("test_read_format_rar5_window_buf_and_size_desync.rar"); - - /* Return codes of those calls are ignored, because this sample file - * is invalid. However, the unpacker shouldn't produce any SIGSEGV - * errors during processing. */ - - (void) archive_read_next_header(a, &ae); - while(0 < archive_read_data(a, buf, 46)) {} - - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_arm_filter_on_window_boundary) -{ - char buf[4096]; - PROLOGUE("test_read_format_rar5_arm_filter_on_window_boundary.rar"); - - /* Return codes of those calls are ignored, because this sample file - * is invalid. However, the unpacker shouldn't produce any SIGSEGV - * errors during processing. */ - - (void) archive_read_next_header(a, &ae); - while(0 < archive_read_data(a, buf, sizeof(buf))) {} - - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_different_solid_window_size) -{ - char buf[4096]; - PROLOGUE("test_read_format_rar5_different_solid_window_size.rar"); - - /* Return codes of those calls are ignored, because this sample file - * is invalid. However, the unpacker shouldn't produce any SIGSEGV - * errors during processing. */ - - (void) archive_read_next_header(a, &ae); - while(0 < archive_read_data(a, buf, sizeof(buf))) {} - - (void) archive_read_next_header(a, &ae); - while(0 < archive_read_data(a, buf, sizeof(buf))) {} - - (void) archive_read_next_header(a, &ae); - while(0 < archive_read_data(a, buf, sizeof(buf))) {} - - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_different_winsize_on_merge) -{ - char buf[4096]; - PROLOGUE("test_read_format_rar5_different_winsize_on_merge.rar"); - - /* Return codes of those calls are ignored, because this sample file - * is invalid. However, the unpacker shouldn't produce any SIGSEGV - * errors during processing. */ - - (void) archive_read_next_header(a, &ae); - while(0 < archive_read_data(a, buf, sizeof(buf))) {} - - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_block_size_is_too_small) -{ - char buf[4096]; - PROLOGUE("test_read_format_rar5_block_size_is_too_small.rar"); - - /* This file is damaged, so those functions should return failure. - * Additionally, SIGSEGV shouldn't be raised during execution - * of those functions. */ - - assertA(archive_read_next_header(a, &ae) != ARCHIVE_OK); - assertA(archive_read_data(a, buf, sizeof(buf)) <= 0); - - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_sfx) -{ - struct archive *a; - struct archive_entry *ae; - int bs = 10240; - char buff[32]; - const char reffile[] = "test_read_format_rar5_sfx.exe"; - const char test_txt[] = "123"; - int size = sizeof(test_txt) - 1; - - extract_reference_file(reffile); - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_open_filename(a, reffile, bs)); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("test.txt.txt", archive_entry_pathname(ae)); - - assertA(size == archive_read_data(a, buff, size)); - assertEqualMem(buff, test_txt, size); - - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_decode_number_out_of_bounds_read) -{ - /* oss fuzz 30448 */ - - char buf[4096]; - PROLOGUE("test_read_format_rar5_decode_number_out_of_bounds_read.rar"); - - /* Return codes of those calls are ignored, because this sample file - * is invalid. However, the unpacker shouldn't produce any SIGSEGV - * errors during processing. */ - - (void) archive_read_next_header(a, &ae); - while(0 < archive_read_data(a, buf, sizeof(buf))) {} - - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_bad_window_size_in_multiarchive_file) -{ - /* oss fuzz 30459 */ - - char buf[4096]; - PROLOGUE("test_read_format_rar5_bad_window_sz_in_mltarc_file.rar"); - - /* This file is damaged, so those functions should return failure. - * Additionally, SIGSEGV shouldn't be raised during execution - * of those functions. */ - - (void) archive_read_next_header(a, &ae); - while(0 < archive_read_data(a, buf, sizeof(buf))) {} - (void) archive_read_next_header(a, &ae); - while(0 < archive_read_data(a, buf, sizeof(buf))) {} - - EPILOGUE(); -} - -DEFINE_TEST(test_read_format_rar5_read_data_block_uninitialized_offset) -{ - const void *buf; - size_t size; - la_int64_t offset; - - PROLOGUE("test_read_format_rar5_compressed.rar"); - assertA(0 == archive_read_next_header(a, &ae)); - - /* A real code may pass a pointer to an uninitialized variable as an offset - * output argument. Here we want to check this situation. But because - * relying on a value of an uninitialized variable in a test is not a good - * idea, let's pretend that 0xdeadbeef is a random value of the - * uninitialized variable. */ - offset = 0xdeadbeef; - assertEqualInt(ARCHIVE_OK, archive_read_data_block(a, &buf, &size, &offset)); - /* The test archive doesn't contain a sparse file. And because of that, here - * we assume that the first returned offset should be 0. */ - assertEqualInt(0, offset); - - EPILOGUE(); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_arm.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar5_arm.rar.uu deleted file mode 100644 index 19a890436..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_arm.rar.uu +++ /dev/null @@ -1,916 +0,0 @@ -begin 644 test_read_format_rar5_arm.rar -M4F%R(1H'`0"[Y3SZ#`$%"``'`0&6P(*``(S!/"8R`@,+SK\"!+C%!>V#`NN1 -M;XB`!0$296QF+4QI;G5X+4%2378W+6QS"@,3JRFO6QUI@`R+6-Q5@&9E5#(C -M9@!0A]YP23)D@&0D%C"*9$%8Q!<.!6645P45%I6X#%14]2"<"*BL0%2E*W($ -M.!`C8<"`G`DMI:E:*RM+:5HVP6"E$:RH-LJEKG`8D1`8J+8M%+O6\SOOS>]P -MP*W@]^^]]^^_O?O\_?@,MV[UO7!YPZUKS7FO-<&'XMF9UO>=[S.MYG777>M> -M;SN;DWL,_O[9(3\'_L`"`"K_L@`J@`(!_V0`90`(?]D`(4`!`/^R`$J`;;_M -M````MPQ/[73X?J'#APM<_SE:E63YR7GJ,$?>*[1@M]#_ -M7-+GLGV_:RC'WX>N[[[+\[E>\YW`M1[YLMZGK.N:2+5"\MTU`V>I+N:G,0(> -MF\_P^8]_7^3Z6%_#H^]TWLO<:W.?J7J`\=4^TCG"WGF8+Z#$Z5:J6T>$P@%Z -MRD]/8W#4%*DL\)WZOFQ/^/=,M!6OGDSSZLOID)N#U=)H^4\G".X?5=/G,Y;Y -M_\F2AN<,\APP@*7'W6D^K$V&%TSD5GYQGN;'_`+=6\NKBROP!S!H8>/]M_6` -MOCPGM>`=W716-+,M"`'Q8;NO>&_ODU/*+TH7P:_1K](OA%^I7ZIN>ZMC/J*I7ZYN/Z]3V'T%J7QRYL/>14Y)?MU^Y7[MA[V7I -M99OWWRGOU_KKYAN+^PQGV5/@K_::MWVL8]7]?[(A[#O^UZKIO`YO1WW`0?F]B'A/S\'W.FYSWZSI:WU:'#W;OZG!Z;< -M&=ZG23OEY_N)GRZ[NM-,O/!TE'29:Q7@K;&9;Z -M>VY6GS?L_MZL",WW_/_G]&ZQ.B\S\T[7]'X.GS/=97.;;H+M;>5T/F:+U:K4 -M^]=^VZKJN7<7OY->]A5/U-;^D!NEZ?U^!I^#/7;S?$$7V>J^ -MG=O5ON.RF'N/@NEAH/^,;([7"?%UGA_-]KR:NZ^7R6_[_Y^Q][4?7I_@T-'U -MOKY3P>HQ70W;[FN_#=M18>%J/*JL]Q;W^J[>7O]U[UUV_TH-ZYGO_E^G8V.P -MTT-]:^=^BN]^Z\MO]Q5'COYWR8T7I1 -M*K8Z^%S%-:1>7_)]W^EWO.N_?YWZ^:O'0?ICZ3,_-NH-VZKW?9>9[ZF<]OSH -M7?^-[U)CKMZ,7X_SZO1O.+\')>W\7M83[_Z;KTMX_)_3O/I6$'[?*_-2\KHJ -M.D]6;%/>6$O\OV[>?O^SS5TRWK^4[_'U?3_4_7['87FSM/Y4'I]=Z;_]6=!6 -M[_O(]7]C&WU]?.^$SQN7]+8.NA[_YM/6=+L'_:X^:VV1KIS'='LA`\KU^:SM -MOI\S7T_Y>/_2_^][FT]ZA->=O>1M.]J7AW=J\-S_/Y:Z:Y^Z=7/# -MKX(*KC7^++`O7"JZL95XX*OQ?=8Q5W,O4ZM559I0U7O%,'5*KS9+:*LK+QNY -M>==2&P[%]>%]QP)<5Y20&+G3+\/6JK6'[N,6Y5I\,(YFB&R\O.Y^4WSQE5RC -M#O9>7YLCMG+@KNIS\N1=%*9V7I:V4XJ3?RDVH)=^*2ZGMY8F_-)5 -MI>7CD-9RX+NV':2R&OTEUDN5;IPIEYW%4OY<=&4Z*7^^2(;#2XK(L-'+G5(I -MJY5Y\E?;67%=2:4/CC8R^[E7?9+EI"6IE]O+D5[(+,RX:_NY.TG4BGQU]C -M+)+"J;!B]F2K!RR"_-R%9=V9>AEQW;J84N5;F2WR7I?9-12_WOG$L7(1=<9> -MW5?R$7W4RX(X/K37N&,NJWZ$*IEIS+Y*7^_#E.#N45.)@ -M]HI9'9.4[%B_>)-1RXIXZ89>^4I?*NOY"\U^E-#+5=FY3F9<%&E.*EZ77DNW -MDJ\69S^636N4N^.(I+3RYM^KD*J_683R7E_))5P)Y5?["&R"8O$F=GY? -M[^^066EPQ9@?2XZD,OCY>=D#2LU7BR;:95^(IH57[LEP4J_UGRJ8N&<)I9+. -M#2XBKJB9UL)5[8_>/E\(C=:7.OWFE`5?K,.F5>'E-M)ODI3DY>UR>0$GC.V[I@Q@C\;E, -ML(8^NK[_&8EN>$^<;EW[OMUB+`'&0RQ^#%,3(B?;4#+=X/ -M_Y#+Y83QG[RR$^L;CLFO?UC`9H9#N\ME/K\;Y!'';23Z]7D&8@TZ$J"^<>T' -M&G?;8['`K-4_@KYC<@"//;XSON[\!<3\XZK8*O*0&3^$GXZ!;(Y')]]E\\#')/]W>.[J -MK6[RKRQ#RGT*?LEE&P)$F?_N01+8_'$I9-PGYJ^[0,?NK\#ONW$D"_?>`/O' -M]OE"/SW60`/ADV1^C+]ME.V7R`#Y[P2F5[?MN[`\1^\JJ95/L$P"@GWE>Y-. -MA4?0+VE/8/ZQH/^+=OE?`9+[6R@/\Y,D>5@?@#T$OH#F$T]@/6-[H);OR9]! -M?(K/@#\`_B%_A3[EFS.33^ -MP-"Z(.,GD.[6!^,ACD*X)OD3]A'[!?P04],H_^.`^._2:?_D7@G>>[[S&9-L -MC\$GT`\]!@DIX*7II"&?O(Y\L9'&$'7<&2,5+501=XW'X]!"(_J$\!%UX -M';X_+&M,?WG?"0R(E-A2$R*)U".LL)8)>VC#*`_V8P)OB6CR!<9/C#V -M,[[(B?CP%N[R8B\:#O(ELCWC)7;-7W+3Y91^.U0WRA#D"FBO(/Z%.0F[[SM6:S[W>0$ADN^[L&\I/^'"]BT>LKC@,R*`B! -M(?I!Z-NX[L$>LCX&4!6!?@V;P*O_WF1Q^-^NB#O'(D_)9>6[+P8X&I^^UE!L -M^(NFZ!9?>.%W0BZ[EF6^@LGS*Y(6;IFR0( -MQ0K)G@(O!!R*C\"T)?=RB\A/Q5CUE$1:6BPF\L>LK+5L2_?==YW^0XR(!G`J -M/2W:B[^S=>@+]W6-/TR@[XUWZ0OZEB^M5W&3)7X*GT;HY8WDJP9Y25*@Y:5O -MAD'LE^07&])L7M``)]FX?2.RB6#UD:OOLME987)47?>=LR?[EH6,R/?,TXQV -M7QN,QN62[K;HOE^`NNZR619=%2][_=MWPD"#\`^1.QLI!W65:)XXZ'C,8W\B -MJ_R=-^SZ6PG38?&7_G8"W4X?JNEZ;&8#G<%QH-_Z$0NF$#`\[S[3J/S7\Z^A -M_],GQQ_?&_X(N3\''^_(N%6G],?Z9\ROX2T]+&3MDSF3RF?HZ(_]IFG6$2TA -M=%Z'%\;K;>=H.?]/BSGMQ/%U'.;;B)#@;5]^+KG\3#?>Y7>T'`G>&[XG$=W# -MSASM#[?);^[\*Z_`]^.9^5S\_SN?EF?C>_!=>%=]_R7MT4;EOY\O[',_OIO6 -MYW]N`W'0>C4>?T?ZNE\WJ/S=7YG6>5B?(Z_\'9?=[3QNUU61T_<:3N_#RF@[ -M_.YC->#X.:S&=[_093P^[TG<:?(ZKM?&[3[O9?@Z_R,3Y76>9U?YNH\WI?U= -M'Y]1Z/0;C`?MYWUJ;]_,^QR_\^6C47_6#EMY?/ZS"Q__J.W/_#_=YHQ[N88` -ML'W\5X[O^ONWCG/7$^KW_+B.YVX^29`^(%I"L9_@OK>IV/6^3]/;T<][WO3WM4GUOQX?983]8!XX%!.\/IO.BWJAMKYO/I>E@[,& -M]`K^"O'OW8&_^3]R(_!G^UI0;QRL?$>6"^O7YSJ?T.OF`O(/\>SS#CB@WP'? -M[U.G_3>9`'IC^L&RI]OB?*FOD!_V]1>PV`_Z#OHDQ$L'Q3@(^`GX`?L!^T"P -M%`/SG?6!)T&X!7ZVH;]NODF@/X"/W/^F"?V^Y0"Y`_P*@#]'Y4!ISX@%`_W1 -M^>">;K\`'Y6\',S*9TXU&0=K`WI@[C1A`Y%TS%Y[P'*G_]O_RS-=\8/A:=)\ -M^69EH?Q3BW_[W]R7/,&L[-R/=_7L%2^*->J7E1L%3'*-BJ=FHL509#\;)B=L -MH>0;][GCOEO=>0_.MG<2_2!YKI%UB?;B/+?]4C4V0L=Z/VXU'N-%&U-OM)%S -M#KU7GUX:^77JU\DO5+XI>$OAEX*].O`7I5WZ]"N^7>+K*R\J;CBJJW5=LO$7 -MM5[1?;KV2^S7L5]@O8+ZE>O7SZ\-?+KU:^27JE\4O"7PR\%>G7@+TJ[]>A7? -M+O%UE[CYU5;JNV7B+VJ]HOMU[)?9KV*^P7L%]2O7KY]>&OEUZM?)+U2^*7A+ -MX9>"O3KP%Z5=^O0KOEWBZR]Q\RJMU7;+Q%[5>T7VZ]DOLU[%?8+V"^I7KU\^ -MO#7RZ]6ODEZI?%+PE\,O!7IUX"]*I*U)U;72)U]*7Z\!1KII;W9W\3A;@>0O -M^"ZATU]^48/HQ'V_UA-_I[7U8RT#2R%H-A%#H_TC=X&ND.(4HQ>!%!]>A,F5 -MK"/_Q-27EE#ZZR3P6%X??F3*AV0#FK$NL?M:KS!9_$CUM0(;R!**DQ?G7\3`Y_/70DX^]/MPN=4 -M_6@(DCHM:O)(4?<][H;QYV-].\;G&Z&8`4`G!":(BM@/N11U4HV(DY&T/F[7 -MLS%[<^]$1;S.X8+&4[+N)0[,]LY3P&'Y9DAU7"C#5F>X:N`,[(+)D[/`6Q<] -MS)DX"C*NUO-0@=3VIWWC="(N$9C\C'>`T+5*J4.5(F_OD#5']'RPG43A<%W* -MB93OZZ-:*1]U<=VPV^#$7\=Z7_)`T83/6L``7B).L"`SPAVRO^AE!(GJ`JJ2 -MU5=(F7P&S,II8`IN]@E!0HOHC_E%<=%)*5_K0:4F;%"&)MMY)+U6HOLDC4,, -M4RUE$9I`>8)@@,S?1+V)H7VR$7>9IHDTKE1DE+H`\1AY"DGOZ[4>4)#?WSQP -M](E->K^FK_W6"ZS^7EK7T0<$^RRVIR6OQ;,O8OE -M%*\H*6=L<7.X?:8J=/\9]Y:=Q:S'_'8TY)]8,$^>Q_]8'APUI/V/^"$/5G]9C^O&IRY6E?\?SM&'___^VFP8(9\@KX)=^O$"AVO8=2N5T; -M0+V*_MR%;6OS\7?N*\0Z&OKI'KJAC]O*?68:7E&L#QB[$+0M7`G8=Z/.6NK! -M<7W:Q;=_H8NW,\LO<@K*!M9'H&+$/5HMYS*=E4:$R\2/1C!9^[*Y91NR(T6` -M'C@+)_.V/6-0HV3.D-AHX8C]>E!L2D -M7827=^D28G"R\V%NA7=CW++PFU/NNEJ(?87<1[2MBUR`^VV)\PDVB;)'2^?; -M^UB',2M4S!FG#M6,.*Z$C5M+(Q5W8/LJ73'F=I'AB -MCS.D6]TX94@PNW9H3`L2Z/W]XXQGVFD=F?;EL9"Z!35BA@R1MB:3L([82="+ -MU\PP/0'6U]28^44,#-1KUS0H0%1QFXE\P5?(-@K\IJVZ.67JU)JA*7`Y]7*W -MYA4S42XP*B5.58:GDN-;2O4]5Q38J2%CR\&7?$!KS3;?3-!@"T@%&=.D6G2( -MFQ-BVIET#&FBI8&>\5&(9AAM,$T3`OAC>\=M&L)LEH%ZF\*E9$W;":\^/YE# -MP@?:"4OAF[.FU;-+9B[0'0S#'G!^9FP[R24[^4MWI;I@=L1'&JR]M\"+`$,*_1Y -M,FR%I2$>.V4)F;-#=HHFL4FRN(-`V4^HY9O^-_/TD.@DG/*`W%\4,[5D;=<\ -MRTIYK!1 -MW!`:%?AA>VI/N8,O]4+K6=()HGZQ,<.SYU4#`!0C_I8SJPS41T^];?&P0=M\ -M>BAJTNEKS3.'WRI8M\G%XM$@<@2H)$DO:_=%+:"V*3VFP'LI4#J4@NU3,,G, -M^(_<7C8$9L2)<+H-_*X4-JQTI+MC?PAU5I9&B;`.09W1:(7)RZ4#./_'OF5# -M4GZKA11OU\6I=KB?W$S^,,ON:0VR'WBS#X%)NE:[$S=VQG7J?,HE%?3>@R9/ -M!8G1?;@9EVW4;+%B'B^57V!]WPQ>*W:C+L,_ -M4B??:\0`XVDI=^FHNXWAX^\.?+"T4MGZ$DUDIAF7X9&PAG+<0_=?NDV&HV"U#DA;.30&S-X!&VY -M\H2$PS#O-?)3[MB*B!5\;TYV>VE`V3;#D#@B+:E)X5G>O,RSE-2?N'):H^\N -M$35L.L]1G/1K3/:*2PC%O%YW\"AV2=:$.LR!M##I2%V_9DA?7KCE*/50*BO@ -M!S(V0KF:%Z-*,2G\$JC::1FC,=M^W["Q#9-^,60>0=7(JH%Z,]4QQ.KI`SPO -M:N$/M_#E%C2>('".I2S9Y7V#AY`SDDL/%F#=1_9$+8:PR?91_RFA@4%,)LZ) -MMK(=PA37P,@C-I%>DB$?G9'":SNS@8#6+5VH!`_8-$%PCPI6/UH`^;"&=#:K -MV'UK"*A.\\7YWE_!)\>N$?\?JCS=0_"B@LS<9\9V\"GUQ6>I%*TJ"!7);YB" -M&2&&RAUN_V\6UI!,L0I-<&'SE^973T)(P]XJ+AC="L`;=TP++2H'CF!CHEV) -M+]@7+5.`(]]M1:40HVI$@96"&]T)!MK%R9DTB[>4MJ""%HK'1B/_'4?Q9^_I -M$VVFU8/YP-XK5+TMZO$Z9D"[J'#3EX%-?(H7X\&&$45C@7#_T,$(N'S^.=K4 -MVS"+.")B_<`&HW?+I'I.TA\S;,-)?B(VL`F+=$O! -M1CE?4"J$"N6R9&=#GX';OC7$*%&QH5@6D9^#G`Y0ZV/ -M]8_<^_]>1SI)NG,,HCJPL7ARG9ZI=;L42AD]^[K_%9^^E9GO%+$:*63WOS+- -M9?&+%M9R8AQ>*SAVKZAG)!YA9`S4C,FF-".MT[+-O2(V)V"+T]P+../'U^;:`8\ -M2;V9J\]&0C;$DTROGIJ3OA\50*7\)'.$-IA=;;F72>H`QF.-".J7\*-M0$\T -M5;'$7LD.*,HW^;D80Y`"1-NV?+^;B -MO7#3)RS3J7MR909B](ZJPMXO2,IA3T",RRCV4?XR2L2PUXD_98D]JU.XBX>B -M%&AKRANQC_*0Y`5JI<66997'"+7G[U_,#S>@_O -MW>)@KU(0EL7`*BSLDFDQ)HPO1;%AADF_"O1DRL:9G%":^3 -M]=$;M:FA['NBNLO]E:;>$NKL`SCM,F7G56[4W.5@R9J72"VAJSFE9:J/-RQ( -MJH_>YSH0H>RS5AJ=\405OMH%H^DOM!:DMDN6(9SU\3<:#L6>!AV`*1FD;CBMKRS)HMDD,T0M`1$W9!4( -M\<%HG:/@!*JMH'D"$:Y%!S],?)WQ./NJ8;HR<_N0M[^`LANT+:)?$1]&6=Q -M$9.G"D'B)6.68=:3MF2*Y\@94](F`*Q62(=X'N8DSSS%NZ_5W*RW:K*K&+*[ -M-DCC#3HA2_!B-G;Z%A))[ZBD.0'K;"J`W>D4:C-X>]NI;M4;:[//J-W?[56N -MA/VVW)XIGH'5-"JGE#4C0\<^0P.B]G,G(,/=,@L,'-F%*4#\9W+(>3HPK!E. -M8C\$V!.&+A]Y^"$GF^?_,(RF*HVSVHF[J'H8KG)LVM<60TB228GGJX>W'J1; -M>J'EQ#7$\,EU^_Y@QZKGXBF7L4W9ZP5GC"KKO`]-+XA<:O2IA^S7EJ,3$2$'31'$+[X\-`XIL,%X/.RO0<,>(+YL -MJ;946[O_KLB@O-1>94-0^C4FI$''&"H%=C?DLJ5DTK9N^*A;X^%K)]@T8Q*W -M=%_G:4K>*C@V*6C>(W-=MXHPF6>-6PFS,PQB2^TZL33<)NQXYKJVHK9'8*;7 -M5"3+"8IK#3C+"XL*:;E_XABSQ5:985\*1M@E.)4&+YSQ;EBH6>`/G.2>S9G! -M75J->V%`MXLAMB]4^F(N;#+TDUC3%VBD=D3C13-"U[/V -M_N@JRC'E\OQ]DI.I3Y=U\*,[:3[PB-'WHE>NQ)]A^5_QJFLPL;)-K&2V)!:<7%\OEJV-L[HU#X;C3(XML^B'W9\JS@&* -M^'-)I=]TIIMJ;D-*`V`)'LZU@[9`[3'XZCSYC[Q*UP0-P:-P3VXZ)6S72W+" -M'JFJAKCC"+B&_N@,,`QEX&ZD=T?O.KGS?T'1RA^UGM!.TJ.//Q#!=A;K>D%&@U/+@5?2Q\3HJ/"OU).K=@1`(?<" -M2$74Q=Z/>@-4@8)[P?ZB+R]ZO7T#N]QF@W?*=3TB6`9H`1FY`90W^P\M1$#R -M[=P"=CYNR<[N?URO5F161-%%1"RA>?;-THV9F;.]GPT381TTG>R4Y#YV7;Y^ -MW]X5E>C,,,<[_/FFA#)*8_]")R]*<%WH2.R%@,D0[)!Y=9/05M> -MZI4R(EW`=7ZDN!B41Q#K@7&8%/1_XI)HRCZR7-,T,BY -MJ-B('J2!'EMF26GT-+WBJ2P.$BV_`&NC=PV6#6;Z*5AH(ST/S@RR5=J(*OO? -MZ)SZ)K@PLJIN[`WE@.AS78#TYAZ7X:RE&"V6P@WC/??(IW=^010RG(4%4KWZ#(P4&U"Z -M7L_=(IF'DI+4'W/+H\?%#GU9&A+@K\IH9% -MR%%J)]`V2DMSF[?L%%I`3P?>Y@, -MW2MS'V*]E)Q)/F2)UAB_B -M"VC[6[VZ&S3^_!\P/'UD2ZR'L[/P(%T2(;,]8:\A?&%/>#/N@,?0$R=0/MQ' -M+_2BWN)C\MQ>><9'XP7L'J"1.$W,+\@'ZI`JH@._];'>0_.U*45FH;S`BA%/ -MNV''R_JSR)$IJ532JSIK^,7.DS<3T'UBDUX@\@I(>`EZ3?(T8:$52#^-VR+/ -ME%#8OF7D@B[,&QG7PH=)4$B+K[G(I$K+!T, -MI[?E-+/V7*(::F$G&N4'H1DX88!AW_-Q$EW84D'^YZX1VZ=*@>YEG[DB$1<& -M0%/RE5K<6^%K)9T!128;&[D678_XAI03004)A@Z,/5:^1,5:]E$C_:AV!$8N -M/.A>74L&_OGHL&OVR^R#[FW/M:OW8$V'51N@#FQZ9E0OB]NH_VO-EME=E7MU -M="2;'V5;MU="U@3JOZL,;=C'%Q]:IQ5^CO7$+.1BB=D=6*R$OT017\I0]U$5& -MA9N1;S3-D$H9=JHO'4\0DF[_\SX[_8K^#'=0?L_^`34?^412L9`/NGEYZ"8> -M\_TAV]Y'[X"LX:]C+CKU93HQ,%FPL:W9GE%.>[W01(%7U,;BU]O?L/VEY"YN8M)Q^?<1"EA_FN\7WB]Y7]A$!B8_F,#UPP -MWU"R'QKT>F20X%ANJ&MA8^&"YV^#6T&&,0V:,.&F!)6]<)-A*'REP-)QR3)* -M";KCKP$%ZBV&.B2*-;(3-RW%LX*,`)K,/M@NR#FY$Z_'W<-A:=33X@8LP?$# -M(8>:\2<0Y$W0#(J=SV;B.W^;!B'BV??YI,Y5P,,:.!7 -MHYMIQB.?C)FS(86B0%;NQ`4<0OJNTCWXPYT;',LFQ$.!@#A#<;6'$+1*!9U5 -MEF@8+;\MQD`7-%V0(KR?S($3&PVNEF,L1-UB:*)L=KNI'ABC$.LNS3\?8\!5 -MBS)N1A>!^%-V.!#TTGH`>(C=F%,FK.&4J4%6P!]OAJ#A-'GZ1 -M6%&AV?2452\9WD8YH"DQU3.N']>+3R&62O9/#/T,=7VCD>)\)>15ZG1H^5T9 -M^Z=JOG`K=@9IG,B7%@V58Y[!+DHX9LF:`?!Q5*=AZA-,B:QN&C3.-$6,Z1*O9D<\9U( -M1Z<)H[?>)(FY.`O&&9/FD(QO^JNH&>2IBTJ,A@!F86EWR3+DQ^)&$W91UK$1 -M?NBZY`6T.T0M$?&1S8EN&3R?&<,Z=#[WRRDD$^+V/3>=.-%B:!W0@7?NW)(M -M8M$Z<:>!KDF_@R/,V)=M^_6*D;(H'%C9AGM/`US-LBSP0,Z+8B^.]=3T,&`2 -MX`V())F[N7K-PCCS/2+C[?G6P]B:+<;\V.&N/YE.&P@31EZ6SJ@'68;H?ACZ -MA"2-AB_I.F\XL:V,GV -M[%RP!:21&;.*-I6(/VCD/(0MFJLA$YG&V+`%&3!*U#9"+I7_[@3]B#V)F;#> -MN:=#[VLP`9B>A%=67:Q+J'E8`YQ<7'A#A%AB6)6;9`3N%T\9X?M9]J$RAC:$ -M[Z\#")@Q>P`/RR"ZS%X6-0,F[_!HDDBISE!!2#'3B]+)>%]+?"%<:%&%EHKD -MG5Y-PQGO9P`#H8JDX"#[TX$P:J),+<>_?6?UK,:Q04LL)>@LB/0E!>E20&+B -MKVLH?+A4%,7D`MS38(64V>$4&H'AIMG6!EZL4(:%4"&+L/`P;3;^7J,A24RL -M,MIP@?-9#'EI]6,S@T"Q`NT9V;XM_#:1G;Y)@>Z$\LTSF2@N,1'UTBG@&L=; -M(^)JLSPA1P67]B)SGV`'7V4G"=!GSP3HKFF^H,.VCD05G(^WHAX.`/=*!]QC -MI=.:(,")DPB1Z6RG)'[.A4O84="7)J*82XG)2I7V$C4[Y1;AQF\[&H4]?'Y< -M*3)+X-]/-;1<]_B>!$*7<,&J2F0S4ZUW.LU%QN`9?W)'P7]W:VCSUS4#[.<0 -M3T^-Q*"]`'LOSR!HPXT)'E5]B6A(!.PET:PW"3B^ -M;)]OK-&9MLD6_4OY.YH599(54RD60=PLT+ZXF+=)/&X4(`!C1H[L6%]6BMK% -M2RI-+,!X4Y'OC9 -MY?]+`!<#KE@,<%7W+C1*GXKXJ"#@JBEF!'2L$G71I/%4*UJGXS%#1X?0JX^Y -MCW!YI+9X%!3L)@$.N&?E/>)+"WFAB<'._NNB<%%L!_J^UDBY!;7YN*C"WM_[ -M#%O_O%[%*<4KQ>8]]7L%S`QZ;+&3$F"%O^HO0H&BC0G\-7A_TMU>Q_S6B>L: -MK%B?^T%&Z`N0GIDJEA;_="RZ:64+?YRW1HAKTQ[7^D,T7-!VK8^DK-.%:[5# -MB,YFP$#+%%O!?2SO^E1K6\M-HI-F&GF;C$+8\SLSGO/-SSC]G6C!#,QIV!^2 -M))A8RSX>GK/:@@E&+C\HR$;'J)0]>X@Z6U%!;I=4M/''\ZII1/JDRI.J0X81 -MM[LS66E813.PZ63=# -MO0#FK-HW2A`[J]C(%SVJG!RH#F"(H`P-;=%T=?'PI"ZSO4M5'TT\7*H'GKC2 -M[[F^20X`V=?Z@%C@CGAB[T,PQP( -M.U"!+$1%&&]:1KN`FP7`B&S8[$'M>+X#QTX<:3?3)9Z,6%'QJ@:7@/>JJ)-E -M"K3$DT>:WPT:`V6O"9?B97L+&P($].%7=G%0\G21AP.&#KA=7"QC:4BG'QL( -MW-%J6E$S_-9G"0EV2#;6R0:ESD9KVT#2YP3WEB#0QDV`@->8#1AE$&+FDW2: -M/`S6T6A?Z&(_Z<"U7!EF*H2J./[E/H,(JLZ)`<)< -MZ++9$7>3V:\.."?=.T[-%63PM`:>^O&Q^$-9>UN[.[K#250`=/T#@"&ZR.#Y -M`HW^A6]`&E#0#8L,[D9\M6IEX&&!V0M9R:BA,6GMXW)K*3HSL&2"Y>5F=G0< -M(QTQ4&2C3,\8'2R$IGGO,"?8F^A([T@N'+9_R`P\/$_1>.$EZBQ+SXO6LK_G4>?8]G -MCFW1+>-T.,@U$)Y-P-)7KS`,Z=(6J]TS.]80!IE(=,[^M-DS3TI#$<#Y!ZWZ -MD(4E:%A0KD5XZ"RPW_FB^Z`3NK+NGLAN*QWV$,;2YL6>I?0/6@Z=#SH6^Q$7 -M-RBHG;YKF]KRDNQ![SDBXP(C^'2:9-7U9ITV3??`%L[_IF-P%"$(^ZV1]$&J -MU.QO:N@;Y!RA@LK/VR1[7-EOV0[8<-:]89N**AL-/(S+_]X5) -M>XR$;G#)W9Z]#',*/6R5P??BKC^8/!3[80^\=9`PW1DYMA[5>9,>]7QB[EAG -M%[I))_LU]^;(N^ETTAXTI!%9)[-VRP>-!5+>`R%.Y<@[&S%R8H69:P8C!@5D -MXC9B(5;H*+58>@UFFG-M?VI3'7IG56K\]$G$/K(4)T -M*O`NR9V)05#4`DT]SJ;#8^/JK3LTWPD0-A^I28WW`,Z^!K(UC,*(JH:S2]8> -M*U:!K;%C57?_0Q9SHRV]7&'/C>PE^BQ0=E0S%F'/C:5.9T29,'6UE#V[R\ND6?N?+_]>./W -MVZM9Z,4Q\_^0@.J;#2V^^NK#L5Z,)`;;GN5&JY*3?;$4GW]Y';,M'F'/^,:; -M]TK(G:,JZZV-\"ZJQYH:[HR3J0M?O$3-D"5:B`RNC&]DV_QX -M:#%W*>8>C:P@GP2/CWK/1IV",XZDS<3-8`,`/JR)8%?+[PHV\/N/R#6`V6`S -MIX6F`J^"UCU?\@:;'4@)F8-I(+R\5('=FO90=+K%]$M(W!,,5#'WDK(>`JSC -M`2-2B'(Y^EE&6PPHTM0RL'\IGH9WEDDYT8_GL#;H+V>75Y)]["_IN.WEF'Z0 -MR;8I^`.&&0L<^5/8)[S=LP:"VV]_:!=1X-5>>M#8:JB,\%CV%G^=B/PGG$#T=Z( -M_KXO$+_D" -M3?]T"/TF:Y.&N*SPGJK\[14"/0'@DU%4F+LH%JWE.HMJW#.,$!I)MZIFF3-J -MT?VI.V9-9FJ[:(Y(-)FSQM;(^27I?.N43P&D@4;=5,GBP(6A%43E0ZC.7LH? -ML\"(VDP^X`BU=;:+;O_4BVM]V\6X/O,C*(=&<=^<+68:HTTAS+)@`64V'O6C -M1'%S&EDR^53A7#_I8PW=`B_@D.$9V93DF?)+)\6QIV::VA;T9%R7(0=&UGRP -M:EYT&ND=7P044L3PXT)[*'3[QM]4[A&0T5W`U4CH`/K=6637QE#1:C@;^W? -M8,GDY!`FE.`YAZ!GJ2S74/&Z:UL-3(G=L;+NRC\H3)M"\!WKIB9%7MF[ZTQND/%LM9G -M;17`?DA3M%9N@O'P0K&KSR:'Z(9MH&E$ZE*N1"%$S2O6>B>T2+/F9P&M(M3# -M"J\$2[%IRV!:*7;60#1$6U#25$]G1G&T0T!V;B2HS5%A'8X;2:Q0&"0 -M23.4<4C^(L:$*_)R#L#7!44H]^?E#=_5C00\OAIJ>F:!LK)F`X_2W9Y3MI2V -MHM\7SL&RP$L'8-62ZC;8?-0LXN]8>1P%!%"O_1WS)M5!P^?^A(Q;#2BRM]LF#"T0+N7=R1^+GIV= -MAQ8(OB)D05]DQ1LDYC@,Y"HV_47P*=XO1[DR>-B78:+3\Q]ULLT,X84QNU!" -MJ62);%EPX#.QY8NW_61KZ:8V)I0BJ3F1MU)1?4-J;-1>+`\^/WJWO#0HS<7" -MFD.&>-E2KM1V35,-^L5=4:$0U`BX:=F3L+^S7QN[.RV`A681L9T+N#IMK5WM -MHI=46[GU(NZ647"P]N9TNR675-NLRM]:&78T->'J333H:4\,VV:MS]53`,65 -MQNVYL.?`PAU?J%3FBC%7H(=9OBL0K"*Y;)!L"6F(#.EF"RO0VK/.2]4#/(-:%E`$N?D#:`C>EDID"8W`,8DNMHI'O\AI"'5=WA\H -MVF;:_@B?BIZ*[<4M"V)A[O\2<^,.?9],9`ZX9]VQ\RYB]$9#('I2+2_CW;'R^U"C!*:=?!KVY -MBX*^%7PR?=8SG-EME=,719O9:N3#_[%_VX$[QMED=<-"3:FK06=FY55Z*]U; -M/#3-<759K@[+5*,6#>(5M,SIP(2"'FY@;4X;0`KK'[;VJ1T>;6][6+:]-9!W -M&Q("66Z"A5O-+P@AD] -M'KI&3K%;..#@*@.@=[@OFV[/)[766T$2_@M,)J;P+(NFV`K69W`9[5\7IA4: -M^%8I$/P]V.3T;&HZ#CQ63BRJ0#;;72*+)6[:!KIB^(\Q&-)[+\U2X"G;M:$, -MTNDQVRT6=6](`%B9V7"P6(5K3D!E\`-D`SB^U*M&X#OD-"(XNC9E,Z$/BH[I -M8D^J^-H,Y]6QH-K4A#H,2H=!0<(GQK\K".W(39O093[V?T"M-VSLE#H(Y?9` -MP'*+(;G7OZ[4#79W]E\(_Y@_C"D]<,>87XE[7X%R^.+K*7TDN))*8M*L'H;T -M:2Z0V^`'*N?UK*-H[YKI@OU?=4B9J6E>C84B_&"UR*$+]L7\5]L#T/Z*5#)' -MU%&7+[5HL@;@],&F_B1B`SOO=+ODF2HBC84,&@X0M5G(SO`"7F1]C&GKB%)> -M`2D!?JP#J/X&/1[O8:6O?'&9Q8,Z8[P -M5[3K'GH>CG+.@DELA3!*C0:Y_E%33M[79R*E.UXA-!?T+)S`!3-'1QT-V1S` -MN``V@&Q]-GJPG4["(]@#/5\$[1MX2:73+NJ;T>;B%_^3[6AZ,[.AQ#&@\8N4 -M:D\;MIB5/!HT'0W9GETZFUB(6/&45'.D6==Z%UCNORV_Q<^T8K!#34,&3MGB -M#',8ZJ\]$-1GEDG.(-]R2H -MTS)(9XH1)="G=R2B[52LK%KOJSQ%*!8(=`ZE<`]6B!F\1I-\=4"8;$RHR0OU$Z^U::0SW&B8A%S`'J8ZDDTUHVB%B(PV@( -M*V=;?A]P3U]9VXG/*6N)NW\O#_2OH5^EEM"S_T6)/]>,;<_XL+& -M-L5\7#8K_[Q#C[97L_]PQ+TLN1AM)6V`1LU2\FE&EMAM*O]C9FAKUC19X8^6 -MG:3LMLY4+/E(]BH%8K3A6++XI7@Y=7XO`WRN[Z--F/"_:KMA*Z82O!Y9CMJE -M=/_0V7+*[82NG_HCJ-\*OQ.OWTGN_[>]U/*[Y/^BB_^I;+B>W*_$P\KMJV>) -M>6JM&=AV+H;(J1%IL/Q3Z8DY`Y'8=5,=VK.XF55,L\"UB?K)X-AVJVL^ISY? -M]D+??5\*IG6?,AP8N;V-J,P>)(_U")/(:PP=R29\OP?W&-R(KU>/%5F7-&3* -M$6!'L/3,0NAN.Q&ZZ..J]'"W.)3.#*C"@,OB1H_HQ=[)[IE)=EDH&Q8=GP`5 -MJ,\9YH5&?ZO42)V(/*= -MU.$B.=KM(M*L(::CT-2$,#>A+SXT<;K&\,/]S!X>-AH]@SY*CH*23%`^@YV1 -MX1,VBJ"!]"\J*_>2.>6[%,](H'00Q$?H@_K4_WA)EBUY7YV-^9@IG3/$U'$' -M5[/%E->%"AB.SQI)@)K,O_1D>F>-=IY%VIG,9S-XF.-/L]W-)J$V,AAX*F#] -M"D]9G[Y-3Y'.C.9!]&+ZRV>%RW7$)4N'K/9,8Q!89K/(&=CX8.>:XPZ*@+A\ -MHG.?'[G\N^!N%>3PZWJEIOX2(>2WIR0CJDO)UWU(Q0.%TLX!; -M1,(R.VYCSGX:X7UL:9!&%YL<=*%%P?TM=MK9QF]L@D;IVG_"=0-["M>BX64M -M0_,4P*@$$[X3.>7QS]@&U(T'PB[C/JV7%;+BV8V4B.!Y8[?7'@Z(:#@[D-I4O;FYX.5>2-6[!6]B0(S[1]6 -M1NWI$#8F/[27$RT8GF!6,G,CR?#W]1&RV'>'20%-CQLR8PZ\KM(^-&8+2/4A -MPH_:*4`=F?>C(M1JS]J:>N(CUY!C90ZIEG?]4EHM";6X!E%K/C]@M6F>EMB= -M#/W+;$3,L,ML+VR4X.4ERIB(4X4D,O;FL;U'F,,N]K>3UWT/5FG.BQ#=L -M%3I\T)\=(%+IXY?C4!DX[=1M82#141/.F/?,W)K%>O#%=%UDE#MYI60H4:N,>;0XTKP:7UET4&J8Z3,XDO"W:5\U'],(O076[^'$<7=-P1GZAE4F;%XA#!C0K#PZ9"'W -MP#2,ETF0EK%8:S%)336KA!&IAQ]+K1QD9]8S(H`'L0)!"-UY5!!I;9634 -MEN_';*&BEMD;4F=HJC5'\`ZUF?1B^3SWU&]WM:"\QN>U_/Z[;6@O.P2;0]%P -MT^"E"I)A)6IA']C(YXQ?/"G<^9Z@;7$;X3+";'G)=# -MJ_:@!7VZ.,$DST1QP]%"1XA-V]#N;1U#.GQ>4DVNUG$R+L-^0GE&%$W)^OM0 -MK>QP2B^O5RG6M@#EPCJ5\/N^Q!X5<4E\476^YI@+I#?L'%Z.RC\Z?9TV0`\- -M-89M8:Y#05,J'37(+853!7OI(.]@25"TZ;9;SR`AB7O=YXU'"J8-%J"?JQ/Q -MJH%AM7=\%(7,B85[FMMAJ;4(XVM[V(O#5`^[,GQ6PSV(3VU&J1I&D#@EF;CJ -MI3<#0#L -M!`^RZUFF&^H0]-L>G,TN?V\F6;IB_'68LLX8?#"E72?A.1?4%0UC.W"F&>SX -M-ROLP/1D:8_=\%ELM`3V)3D,3&+.L'Y:=?\OTU9AKW.,B![$]@JC22=8(6$@,*,$I -MLL(JS^&?P/>`-!MMQJBCL<1TPK:RL8!PI]?9N8'5$B;FS^'9XRW!4O -MH"[WH;\`=P/P*N24B6Q$_UYIL88=ASUA/(9(_)&)Z&&58XFI9$4_B<=-`UYD -MJ1'MJ,&RI[!)7#_UT7T,#7`=TO;=LP.H$YB#A8^#&NL#\D3:&/=W_C6TRYFC -M8F'!(V?8XPT%?<::6\=3-JO\2G)KCL*?G#-W>FCF6>IC?0XBNX)L&#8_P.\':LV45CE_RB]+WG(1O\7%RKU>7\7!_Z0L_QIFO5_C[%7, -M?NSF6H^"KIOJ]"N[7M[NKHWBNG;K[)>P7T2^77QZ -M\)?!KTJ]`NLOP)Y71:JZ;->Q7UB^?7RROIQ\]KN.[X0;A`9:!U3V'OZ<7(VL -M;M&P?(SH!F0*37?W6I?_1$!ES=-_PUG/219Z-UV=<;\4XO4N!R':_0I8DF.1 -M(K\.\Z?<@8?YIV^4CM;<$,BZJR0]XM2>)`POO)8,6?,GY2C96)E_,8'>R7PJ -MF!^51!_,OO?SKY?]"\3S5ZG:+O/U+VBG662C4^>O2^@OHK->VVR]#Z*\)3P% -MYW;J->IVB^[7N%[9=^%(53#L5\>SRMQZC(**/*$"N?J33?XD;V'8[@5;6R/U -M$[.+F8B1/4?>:-H6+T,'%4\-K,.G=.A2A\>I`1>,0[@8<5A]`T=RXG%6'[YE -MOBK;!O-F'3YZ<<9:/6@^T9+M4],-SA`) -M]UA9)R/7S.@HE"XS@&R=#D@PY)RZW91]^SWXN:F6IPA9^1\+/Z.DS`VV^N:9 -MP+1T4-H?G3RC\`"P!*=& -MT/S-^.^"=L_BJEZ`DQW8_GD#IW$I#:*\DPS;/?;#B=N-;X]8S1,BH"<[P=0L -M\#DC3U#^)=4PXS$>8L+!Q[AW\9/R,8O%9>L()CG/"W'N`3I\\-YG<$FFBG4N -M0JN#MN,H-)$'AN<=.4V=A/M=,'R\,1N\!EXLSL+DGQKCP[ROUS.E^"9W?(]SYXJM`-J4T[P>W`S`;/$^HN6 -M"8.W:L!,B4[-PVI?LN97K>*I.SN%LP&JL[&2E-!./DM5UZ*@FG[4W@!(-=_= -M[BEG&=;(( -M0"*?]&EK4/ARI!UNY!HCN]A.N><,VI<_9_)-KV0LM0&[D;L8 -M;!9:6=1BSFDE2QJ=N0(9Y=L[[D1Z?NQFZO-;[JG;$9\PTH7UN72F+P0VO)/< -M-GI8$-#5M"*LOC"/T3"ZBIV]?]!M)'/0*D','*QG4'91#V-2V0B`%"BTX+VI -M`7.1'#\OEF=4DQ=M<_9AT(Z'%)HZ+H7C:!)=NKQ?7.*JK`6J%EU7#.QP!?K. -MQ/F2X4*,.5*>4X3MH9,%M.=13;;R6VNU0L>H-OP;W3RS.KICS#*NTR,).UDLXNY7QRZ'IPI -MR`3!S.20%&UD.+(>.7ZX -M_%G03+]:9N57?JS**7R0R!\`A'!IG1H.UY@TN6DKQ5NUW*[DD:989I=XN;6. -M&&I,OEEYLQ;\\B22&KTX@4)5"1"[+J?XHNLT$RZD<,\\EY?VE(*:^1^)K'3! -MTMSCA0EZR>S=L5+.P82U(PU]8^YNK[E+\K5>>8!%N#VGPZYBO&EH/(P]R1O1 -M6#WF>HT_!Z9XZ)7[GHPZ5(=!62TUA"C&LQ6M.26A,]SR+W8H:2UE[9JQ9^@( -M:_01(\B.G+\41[SZ:UZ9?M4$_$>LCRC1V;YQ`#H,<&3JN/_79I;P6C?(SVQK -M;@H2:='CRK/=]CJ!A8[?@?WSX^$LL/&Y1;%CMU2Q;JO!/5"`T9"`,-.=^YFC -M=E0SPX>(Z;=SLG3!`A=*3GKH_P!B!_"(*%TZX^RQ,@$<>=[J?@H16W$K/X*S -M@..(^],FUP`R(TF29FT.%&?<;_!3NZ2&UH+IMAYU]E8R=+\DNP9!(M;*'BN@ -M.2>Q::I1T>BO,UP!S/Z\81[[]Z:G*`'+Y>25+6K9U+($#,.S[`H.1!;=71GE -M57!R:/,M2LZS@YU9F')7=783SRKULQ-5>19L:MD'V;9!=A%RS:?%:L,,FF+% -M&%H[N&=/M"HSI_^_?0'Q2;$%-M4_?,+["+LDS&G%]S5W-AQICP9DX_[$Q>Q3 -M/SFS^%L@<$SH$F3K_U]]RYHRN+TI27-L>.%!D=H"K:=?"=`@X0Q8,1D"!!!V -MJ\'"J1][U*QQ$DHZQ=\N.[#.!.1';(="HSLU?O,-B9,HP,,.0SJY/V#V'$CZ -MTQ[I\!YU!SL2`I2I7W#.QL3[*W![Q*+BG8)P+&3)HD7)TV2\_*-`(?2JUGD. -M;`374,!!V;1T]Q#AI/?+(@6*3.SC^"AL-D>K^U6`JX3?+6..!`_0%*)VQT,0 -MVMG(!/@N)@ZV/ZRE*`WF$Y9,L/:-%-8D5<&*(>-?=O)3?)MA\VU3-+,V#3JR -M6!685A^)--A3&+37@UK.-(Q'?7)N'1\($ZX_C$]*R2>81P)UA%0T'>,I@H^N -M>UT.-V,PC=&>9C[33;'R\\(>D=.HBQ=\K5MLWDX>-`T=O,S=&?T>>F9ZS -MF^AA1MSP;IKG);GLQT'"<&>]',-3"6]E=)>@+H:"Y$&'N -M*`?O#-==XW[]3<[GHLB/[I=))(?28)IJ<^JRK[L"IRBKWLUPNVS&S`#,? -MNX/-9CTN%@)39I#H-J.C^:6S[`,@C-KV).V -M?"EUQ[Q8=*2<3Q;\P+6`[DT7VTR)Q&=&>IP&$,P'V-#?++3WA16T(MFGQ39L -M?<#.WARVSH_UA!8F*62R!$"T8>&8!C#;1V&R7=D@3%G"RB*O;FDS'D`@TYDS -ML/P`&%(>ZTN<69X$]Z*V!!G3RN"P@X9/-&&\1X6P!Q%G(83"L,`,LV!I6"F> -M6/)2)E'2'9CO10'0>210"$0?*C-.KTPW#V!82<.0<,RM9++Y!SC($?J3(0%6CNPF2$DL#4R!V\8V -M9_>.W+"X8L*<<*9$I5Y/R:;X7U+.2$-LB3OC\!F20CP_P+@_`AG7X#D"CHPS -M(8BA%Y^0@MM%)QZ'49DH)MZ@`99M`[YI;,Y-M,<"/KT9]G6_;Y="5VUF9%C* -M9X^`&:?YJ,.>2^@)#\^.YLA^-:.,NGF_U!7DN;.H -M7@5JF*#P(V)X<:86[16FORH9EIP2\9_0O)'Y)G\JBOS$SPIIA2+Q2G(]GL^% -M7Z!0D]D?L"'=.YUW!F>YY@3/L9WA+?8KN"E"Y`'-8<9CAP#SSK:BWB=RVB)Q -MYT5/\/W/8P<,%Y51\RZ^L7.>=>2.U&3/0S1:ALO%&@UU5):ULVI.>!KJF7B#S?V!RS/:1D33JB6BQ+& -MC;HQ8;*%%/=NLRBG[ZOMIT(2\FQY'=INM>$_)M(5&["`"BM4M?ZS?.S)K;6L -MB*@[2$I`W8FT3;2GM4G<'8LE"3/Z,+NRT\B:)4@8-0Z"WN1*:F0U^CV>-UDLG7J=`U5TF,1EY!4HQL.B7/(>?#A+K8 -MH;_:!MZ%3M;^LTR"];L6DM8YQI-LW$:_!8<0.&S,&Y".*!1QL@A:5'CK]J`. -M?KLMLK8N;1[V*G12&[ZEAVSLA+I?`75VD00P[$GIT>."Y!0+2A`C%B>NH\<( -M3D6:--\^UR.LQCW%!"K9'BC\ZUK%68:=;MLW%FQP^Q,-7@Y-CXJ9;CS% -ME&CI`R'&&YD:"!\;94 -M08M5LU:60SRKSV`+G<,TU,\?\G(FF3C$GK>SN"/M^_\1+L3C3EUES!IDQW)) -ME@@XA@`XV'X$'6QOA9WL#A+KN39G&WYY530GCX:X(T/9G1S.X*?I%B6G\;5*#>+GPJ6\4G7T,U -MKHXDL\-5BA]A>J;1G7E:M,=')*4R'6S@]CBS;@%GB(JAM4OR-C4'AV^-O)?5 -M.!'3LL]AUHZ@A,#AK)BEA1H/7\H\$JE#G/[K#5TCFVG_5##$RCJR/1!48,H9 -MW[D,\PM=%F7N`"B:ZV -M0.SR.-3,N1ZC9ZYI(\OWF..22PFMN48;]%C2^G`=G&7IAN\U^Q..@0DNC)*" -MC[>+O%YU>=70C(0#\HDK=9P,Q$9XSUR8LJXE,0U=&*#/J9O=>O6>',*GW6W@ -MXVMO;7/<>)P:`5#U'<7`R)MUP71^^H&13Q\QD>%OFLEPK^]P[@IPV6\)&[$] -M"J"P%\2U/B(R\>?685JIEF!#<;9AVFY\+C%EHL+,0W(9EPS:;=6K/9,%1`)? -M75K(YA4TJD?>1[A@YKN.VX3>5$SO8?-.DA+[JZ.A/:'G"Y*6RA3 -MRL0+7T7)\+[-]N?UWR19?1F1CY&LA>GLG;:8S&F4A@4@.I";++I2SV -M8YKA>EW#*-#F3LBF$H(JX)LX7%270IG/*2E9=+@WA17Q;3<9254KCKU;)T;8 -M[EID<'ST=MD!SH;]P8.AL>$;H4/V!6$XT7AD@!&G,1P-/U#(,R\E8)]K\K,< -MEU29,=CMR,]3%]WU=%& -M*D'5E,GKHEK&O/0QIQI[([AZ@6^@QGR<5(/2K"]X,@N3LDY(?**;56 -M/K'DHQ1$U.>%PEIREX0T`X>W7,?RX)M+ONYV?"ZC[%CPNI[,>3/V.:X1=4-U -M`%)X\T%%2C(Z8T,/A4H5Q@X4D<6.D%&]*^T-Z>LNYB#-6B.R/>01$,^^430`RT?W -M6)@YF,Z?::+0)H1A)^T9C7YTMR8_OE.RY<=.SZV^'6GG#_<[TU8U^";D6^&(Z@?7/^8O6E)*V#P.Y)VLB6[L?>LGZ2)*F%,]:25) -M>YG.8.DB.H7WF-7&%:DTAC_"RX*7G)%G""U=\:T[@J*8%_05CWO8:%#Z#R4: -M"+E;"2/:=$$%LD^H"!M+V3,X)N3,KB7'PJ*@[_D-2PH=:U]!_D@9 -MTCD01B[.Q(&DS43-!UP4Z6S;F>2FK`]E2BB&@B&F6JK9RPI2'3)3BW9$)K4< -MNAUMH'9^QC.O8=:8'^*YO>M&JE%OHM?,3H>CC[=BH72C2V=)$P1I`!62D(G:_(1#;B89XOW-P$EP8#8''24Q0T!VX'8A=RR>G4O3C]K4M@)PNBO-Q4]V%A/38\<# -M]WR;)L8=)-U_<1,4"J-,-75FWVBB/;FD'/:V)>'9L&]IO8;UDSPP+U*T6+9Y -M,`:F/V[!/BXEX<0+.@#),.I)8&951#(S10!0=[Z%T6)6V[!`XF0D=#`8@:06 -M@&V8,<+&=;:;$`ALZ9C74`H($FN@Z'',Q`@8,!R)@-P9"01&YS'S,?.8ICMZWU77\I55[NJ^W6_=U7WOOV]_5>JVKN_%?BOQ? -MQ0[^#BLLB[D,^R!\F0()UK9IB-0U,K31`G>;[K/3O9^2F?K-58>FE"].,F9N -M"8MYQX,W'X5"#.1=['E-\R$KIVSEEEX_2`,V(PVPH7P3.QFZ!E,GS5*1P,!\ -MI;CU14)RT\PBNYPR9*AL!];QXPQ6V)R5N3+!NJF92G26%HRZJ0I1I)OJ".Z/ -MG*!.>*#9@3Y]3/$+<]K(B7W'(9QYP9E)VG7?E49UAMSVTB*5.+7H7J.B.'JR -MLS%XAM*8L;3ZE%M.!0&&78R80TAYF/OJ8A8ACH(ZR_3")E^)H#($?#-<('H@ -MQ_QYSQH\$0-VS:QDS+1+_3*C*'AG<8L=WNG].]S;2:4`9Y9DB7<).E+Q9BX5+U,@8*A!XCBQ7M:HX -MOZ(;,@%B^`-Q2P3E@I;R"S(IT?_PD*-@J(+0^]J -M)2B5C7:WJ#2=7E4L-E&4L(1&/MBO)XI:X%N&(O"F$Y7^!>7DUVFY%[D2I!C; -MN`9G(<3>2)]H=#A>28M;@"+I/,P701G'X'S\5Q22SYM.FX*6N^N^?&]!-_8M -M=Z+]YQ+M)XOTWWA'#D@4@1.=L`4P%XCJ,;B;6SFG!4)PX)#7OZA1N^GG7-M& -MMDC1Z[!"FIQAI3@T>:;TG&'8DFG&0J3BCWKYT%IC?^H8(;"7=OGA$1`$],7M -MY?W_ZJ=>I$#I[WM#!+4%U%H1H=S<=/;@%GFO! -M'G6EK_[LN-I.KSU+[UDWZSFGS^!EQIOJXAMG$7O>&]I[`VUV86K`Q< -M%%(OKK5POMYB!J/ABW9LL2DRPJ,C-72"_\D#,HS:\,!"C6O-]A'*06E[\6F- -MY>FY:!=J+XKR#AWE+L5\3BYU,0-Y]J1;&XK=,M832^HBNH];QPR6Y/6&>=6, -M#8UB07Z4U*WUI*4PKPQ1+^VG_0P$I?#6QSCFO7O9I7C>*[E]A2G*!$*-@O.L -M_'E4^[FF'6`N"&PC<#:7?(BK#$!SEBR2H,&(K@&M&,Q$EY(A*_KXDVKY$@L) -MSX82OJPU?=\6;5\D)5A*YAJS#;2(&594`/@+4MX3U/NI&)B\J]Q`Q;7`5E.\ -M4S5@K@UD/VM#S6^\5S[KQ"D)@X&U5^*E7O2%HG5_%T=[*#/@OMYBH.N1![@M -M?$GW;I7I,XCV"V6JU]$*^Q9PU*P+?&!K(6MDP'!F[E,!@,AT@!-+`'ON1926 -MW=.G&1.ZUWZ(@Y\G=/?^4+A']Q.8B:N-_$"8L%`@&F,.*&0CWA(\IUUQDB?`Q0EFV@ZA[IRESMSOX\U3\".S&6X9[O-7V#UG!&IL5/,33]J6" -ME4RU"8TG",@-WN6%B#K\]),T]'6<$@&-J1Y<;"+-DBGJC+YCC%ICX+B).%$A -MF[`<)TXV&8G<-@"Q7R:1]>D?>8%OQTDG];*?19A@X^CY$S,19T*NO -MV.:OAGIOM+N470JYO4B`WOK2:TT_K(&`R>7G+(H$HUO*,%*L4MU#22286U6N -M8H3[S%P(;,F++`D5$`G]=[.1UKNHW]P-^_.MC!NSLZ6=(BA+;:Q0,"\.09NZ -MX,<#,Y,B":I:ZZ==)^K>X9X1*#1!*,&28R9MY&!Q$6P1;9G#)ADKUY:S9D3W -MRTNZ>,\X,=:%QF4%I=;QOXNBFR")\9#?U1KM@*39KP>=J:-\,Y57/7*D5LW2#@,-%A'H8^B!1Q[R#%UZ*A>O"Z`;"@'P#@W@ -M282R[2E/#%],R2LVU6"4H;WMXA-I1RKF=^S>[5E3+\ZR<#Z$U@4_UK!QI'%H -MW_>9/'FD]1_M4NJ!CIJ[V[K4'N+-@ZC',BDWT!A?$LX^*8?%J:M`ZO&`J"2_ -M.;]$NG/>`?/5"^S8C0K\1=U^9%]MD88X5]3N^IC+`NI*-\]B^OS1HOHY5R_R -M4%[=]B::)KDP;6*&>RBJB70U8]_0,DL2!(5QQ?JH("GS\U]K("7B,8S.L635 -MZ`DF5\`"=]+3!#OM,-YP6Y>J.F!W]4(J2BSDBC#^)71X;\7+P6Y>;EB$99ER -M*G)^:3S`LV&+A=#.T.=Y'AJJ5_(C&]&M&-*C8PN%MOP9"*5HIX,-)#W/A^T; -MIHL-N>!(G1>U)BUPUZ-CR3I:PZ^!(>J"/7K0(H>E#DP\/H<8RA!9-YUP_T*E -M18:#,V'!$%7#'H'PB"B>PF9D[UB@'$ZAR%K,8'>Q)-&]/)4%6+4O>4 -M,3@6.%WG']HS&+;S$#6QCHSC>>"J.N&EBF2/\;:Q]ZRXA-D*-V"Y5>:0)D -MN(2?W>2)J+5GA6`RFT=]!(IQ>Z3=]EA(2]MMI+_EB3>`YL':F$@`-MIG,'5Y -MEM>Q7NY7NC;\I5`]BO8\@X%T_*XFY=I!9,ICT.%;1E@1^$EGW'$EC3A5U,>% -M'`[@VY*!)IF>8P?U??]YT-$BG*C8@HE[/#> -M(FC3W7R!5;?&4#9(3Q":^U826>;O3M*P[%510YB\^RX:Y\O3=#!A)HV-8T=D -MFODO;AQKHFP;HA;6XHY7#17U?M4,C&)$P=X,6!''$8!EDHTWZ"L:V.]I=C.1 -M$VO'8ZA33#L)^/^T7!4JOL[3\&."?_SWO\0SI@C3N0S^WF3_WF?&]15-`VTW -M/MQ&X3?K:EC>Y]*FU*L4CW>@IE;];NG>$9Y/\D`.=M=J&""-;O^20GE]U+>= -M^[R?\LP\7'88Y-"8"G_07?,&2T0GQQV6:,F42D7@2`SZP;A9QG[7Y[W.)QD1 -M)HR3V/:QMU&D=]$_9[/SGVF*&&_[ZZ_G]D)5;RZG^1>]3Z9K\AHLP^8^OJ(Z -M\ON&?4R(%1=@=?!N38`]/L0&C>*=7=]9$N+8L^\@1/3WL#!6."JS`HPY,X6N -M3(KP:3DYA[S-VT^YEI)U;4R>."&I2#1\?VL/EIZ._0[SNKR;EQ7.*NNBW&75 -M)B*188(:]49UL=*I%'79U?1Z*Z+(OL>T*JCVGF_.DO%6$I@ -M\S3',O,8JL@@WF(>PMQAF$%<),ME"P@,N@UZLH0D6[D\HNZR^%/^B'V:TY$* -M,$<>EV6W.'_D$(#+VA-R]`&\1P_OM[1LID6;C_BW4MG>2CC[K[\"P"N8-SL9?K!:ZW:(I2-*(@!'R\M2WO2\%WME4&4[)%R,O1U -MD<:Y67H^9%LPU&?H=!D,2B5(D*^YJ[PUH_C9?M2%=(UQ)?3O5C!:XGG4HQFO!\[93CR5)L&(Z0'7BMS!'6>7679KY$?G-%.#,B06A1JS.F3$ -ML:+`=1=`7GP)!#W]]4CJ"9"KC@-V)ZM%\*6)#33FFI0QZZG3G62&;[QKM)&; -M".-(W2B_RZH7\Q#C+7>1X48"2GDB*)LX+&-6RW%'*I^]>ZT6U,:O9Y1=\^W8"K5.O,UF"=W/]D@HVR@ -M83X"Z!J58DVQ115B(I6A6<(Q-GV:-L@(],V(UI0DLU1O,1?%-<+S+8M?L]G- -MI1+IKSW^AT>,AB!>M/VB:''8J6"DF(W`XVLEIY/X!YSF_/O0(X-2C*J.]=32 -MFV1KOL&%WA4`^;R+W&6ZYJF?/T7-!,K=^P]D.I-M@+S##,?<.WTM<`3NGATW-9M.4/;P7DXXE.3&_$Q1C@*1,?=*QD7B9/R['UBDJ/OELL:^;IGV9\ANA9F?MP -MQ7%7MMF['`3@PSM+]=.6@/K<00B.K.A[/KG%@A4YFG]SW\CY\#Z8S.&_''"! -MC[FA7A[G`7O_Q-%`WHK.$"=3J4\>U"@#="WB-<0F+DM9TKT8L&UO._^ZZ8PP -M/?^:%$2P^P++R24(Q`T4A)WIN=AL-!PTP;N1#:3%:PV*))Q>"QGR6FNV?7,X -M,>;O[E+<%J)^F%H&Z&Z'2-8&G`;,%Q@R_! -MA`MZ(:`H&%442&)#2L]2%-/B!KZ+O@`8@4,3#9FC*]&=,^^%`E6VS7^F77K*R*=#`3*$CC>01YA],748IDJ&M76AY#7I2PV -MNCY>3PZ5GB6JO&95>3RD'`"P!N/@AE[U<1_(AYWA^T:\X"[LXPX%[/ZS*+-L -M>&:ADDS-A/(]*?>7L_ZB;V*N%*ZX-4Z&&^7&7P!Z,;\IURPD)"@<3G0K@H*: -MD:O=@E#[""Z*:'$@IEES0F@5?0S)QBE\BW%D,,Y"O=OTW8JYN(X0%0#*'B#C -MLGWU]/@:&Z@@9LPT7J;S%8]DW$(8#%2'XUY2I9G@/TTVC6%.YO(0)=R#@VP4 -MQ.,'WPT1*+N>:8Y(0X[*^XM[&&AH)O&IY,\?YL\@&BNP=-%K#D/@`:HZ]\A/ -M:-YN[U-&$3?X`]B#">?,5U$70I_JF`F7::U2G+THT,6*)HY@ -MK:3H8"8[YX&7E8?1`O3%\ZOL0QAT\&1%%!#1"*\\@T_QCX,_\=,7W[G:%Z(Z# -M)0A1]D3&=MHZ-_5TLRMC'7VE/!YQ6:Q;K$WLH5S=Z0,?IY$DRAR@/S_/H8X; -MYB]E%//93ZL%3093.+,&5@QL`+6"'X>=?A'IF+67) -MYG8K79$+FC<4%>D$!^)H-SX?P2HG[R,R&^&I?-X3&'[+['/$<`JETNDP:1R= -M.IAO/B!CV.=$TFA;]'7-X"3?VJ3,5)K&38__`R^@Y@S8G[T#B%?*308C]0+LPXF -MZE\C=A6X5C0W2%UQ;W/_6!2.1K881%6H(#'077'O>^F&XQ9_U!=C%%EB':Z, -M4`<&:%,_;,*#+5AL;S'W(09''_AR$OE&O0Q(Z]:59.].+ -M4&0/<9O+F4MJ+,M'X0E%I-UZIR)"0$4BHT2IU0K@QQ\^2W1+X:A%B4AT$1]2 -MQ[8*5-_M_G\A;X;V[ADM_-0<6C,Z;>1P"1I&\&X[4'@#>:/='M*CIOU&I&E5 -M?TP--'2VB./Q/`.M+!WO44:!;(6?0-V[>E;&L6R?L4ZJM44__ -MYO35E_]`)S_I*]F,W#J^V*CV+1N@PF&^XI1SNR`I-JYMR>XY9\L?!L'4]4*!M>\(O0V$7O -MG;-U/6^M&,=U:,"3#D(L*<&H6?*D[:4^9H%]R=Y%[WV/^RE)LVR\\_Y3#[%[ -MM2__P7NG494I=+H)LR^=BFQ#4G`="598LABGV&+^$TJ?/+/I1/J.#U$P\0>8 -MT=Y9Q?RWH]O!@9!UM&Q:=F9R/VL#PC"`?']B6QH\NU$+\T()6AW')T9(&>:9 -M=0?,&)E-D2WC2//SGGW>&3AQW&X911F[.R36W?HG+7>Y/!=3?VE0X#C<<*Y< -MO+8H["7BE9FEK11PK'"/04OVA0K,M+3N3)X$9JKS=.F+H08Q'">\&(!7#.HY -M=,]\'DPQ="8Y.V&]CO&-Y_0"DBY^RNPP!8F2VQ?0Q7)0\337G8O!$^">)PH\RV1]^.*FD517ZY -M\9E3^2#?Y8C!*8A5Y9&AO8O*(RG>V4HX>F!>"(?XCBD@H0%B3-#%P7(#?X2/ -M.]/F%BQ_YA`&JXT>-!`QUG0Z/X`1!YV<+D#K,MV\/E1^'F_2CU;B"'=1_3Z@ -M!G*ZRGCP[C?AGRWH@EM=]'Y6<#'Z.6JAY[JICP3W](#Y<*/M(\+N&X_[*Q$Y>E\NTL -M02H(3K+6KDA%UG!-CJFZ;ZX'HPG%@;MRW1!K>+'%Z4";R89F7AAIO&KD\OK1HU`A>%CKJ/R\JZ7765,>K -M",RW@0(\!K4#0G]+H)"O=AE\&+$J,0.MRBP7O!=0#0'C^)VG-YY693>;0(IE6]?)$S3`2. -M:.=:3GG]68MTPPW.-/67PPJ]"MYQC%R>8JVHWB@G#%T]MD?#YSS-'.I!%QE% -MODLYC2@$#,F,IX%U7F$#&P4MBIP:U(])T4Q!4.!AG3*L[<;$>9 -M-P]5M"56"XQ&2K4]#HK&$<%[CD().K=4U -MX(353W=@P0TB!G"^*[=:\&PB&?Z/,?TPPF"K&GH5',58JD%RTO,O`*A;J;S0#OZ1.8-3.4O*78-&1%X_* -M`MY1%8Q%#92E;;^)X!U;Q+,$JO&]NGFN?4NPQ:C/^!5Q'0OYLD)3Y3S7.MY@ -M3^>]1A5&CD;J0[,V#P\/+`5'%QAJN1GZBJBQ_&[8>?E -M6K^G!NHZG+D#@=`C-N?L2!Q"KZ8+X[6"^GKS6Y6//#!M-V_%8P1]*XKGR-.6 -M*Q!F%IK&+.H%$ -M+OQ[Q1500WN\Y;`<20GHQX(K82`T9%J#`%"-!)2"VE%@/")_/&"37DZ(3V#; -MBFP/>O;YH70_DRIU'K>F/Z'X&^;\_ROM^$^]=^^^ -M`+R=AKW#A!UZ/N'SCGK\I=B)D0_[B":YZO>?XZ;:"L=BPG[[AX_2<+W/QCP- -M9G?@%G#,7=/UU<`2]6YJW@^:WYN(5N>:W,BW?OX\&)41W(#I/&W8>?@J[HIP].EZN:33#4]%8&(G+7?R,T#E`_4\>M'B`K=`>[?1XKR[4`G+BW- -MWQ=UN8[R1O)1=`#[1D]GW0S\"Y[1$>A4E(L3@2'2,.HD8;%0AN -M-`"Z4)65&M")LO4RT@HRIK!4UPEZ:6>9C>K2Y1>,])MLN;4F.RC;&K:/_T^) -M=/.G^)9D'\FSX,C_.\U^,BA:Z3+SB8;,O`P[SX/A69 -M%Z6"<43]O,%/SXCT%_Q^%D$*-W=%:=%K3R0@UX4&!'NI-*I0MHA8XL#H*66F+,27[LS;W')0:%#3TA,C'LGT>H"^5?8>@FGZ/ -M1EBJ[X<7*)^X@B3#YP1=T)'')Y9DQ?+LF/^%:?PQYU"D!1@_J.Q.WK>AT=9%Z\.D$5+!#2H<%P*LV*T[;I5`K]S_P1HD$I_/-"+61#N@\-!8 -M:;C<2=TT1>H$-!KD];X5VGCUJ8Y/G?"IN<\+OGYH_#!<4-46>61KPNR!!^13 -MRH`')\5@F>BZPFMN_4+I-MSY$/8+FZRX<=5TXK2@&(_.)`^DH75'Y-I.$B_! -M)7JR@U5K\:8Y.&LFY4#\(%P6R:A!_S^$Y%6\*&)0IXY]Z;T`&QKAP*W)-F4# -M9RQ+CU0FYRQ^3AEYN&;27GJ-RR2@/@*7KXTRLX;J>.$LU34@#>1"O6C"BXR2 -MIIZ'2KVAM.Q'*-(Q-V*^CZ9+MA'D87=&?%^)YIS!A?2`(UO(822=.ZG7Q+_S -MOZC?[R<&BW?/"0@TCHS7NG-Q"8K*S%8FYHUIRD/S'!;5YWTU'N'J?[ -MY12*=VWYC;[ZBC/J>(WMRW\>_\[20ICBK-G>K -M>:!1I/1#K"P+F8(JY(T1<8=(\S:GF8=7$H+!`[^L8QG/Q)88E/F44^.KF&8B -M#KG(]A$N%0Y!="5SXZGGW_8:F^?.$*G4F3I`Q%7$J<2W$02V"P7]<-7-NI -MP'.^83]PQB$P3&0Z=U<<2JSZF?;Q*I:J;!-+9$*8)@0ISZ#*`#8`8;E[,L\, -M)+6CUN_T*/U`SYQY\_A_.HBGWY[B^;GW',26F;V[=PWZ:,Y;S>@0U,^-&0ND -MXT=&:6G*O2N*QOPKU(FF5IH#G.N?H+NWLO>A4#NF! -M(?Q_JR)Q]_"`4@1CVK49@(]>C9B*/TL0=$R6?"D0S-Q+J8Z7&<68J&_[/-F# -MW&`!A+V/IJHG(>Y[H`=OLUQ)D,F9,%] -MM?(LH`]XJTJL+RCIJ5\G"8*S+7#[IFRMA2R%1+Q&-X1U`;2OC^8]7R6K3"O# -M=Y;QHV[BCEI4.-XEQ5\28?Q_@7SS5((;8`Y1++/AWBW#@66L#_-X=_E/]+3*[_X<.]\,AM@WRGGJ`J9*D#!1"#PU!JVX7VXMM;C2/`U[D\ -M2F&1OEK%@+D8EWX'@'_&^UD(<"`G%OEV.18?L]!-@4U4TKA[4XIHX\^,V20R -M,BNLOL0V):G>8JPG15LS0'*1F/9.*-3(,TJ<:BW[=V2?0;'!Y8FK]_TE&/-Q -METJ:S$AKTZAR?./Y:YI@/:?P8`1B8OHS$9-J2P_4\%S1P3B;.!)(UK>LWQ+CT#;<:SKJT70:TZ -MF3QKU>DX8N*O9XAU')2_WR74IEUEKO;WV9+UA=$YI%3G-V*;/PP#/PMHU^HC -M'%OOPN6:4OXH`Y\AGYVZU>_LC0C/[D:Q<;7_]8I2+<7KUY&;VA+GG;Q^^A[M -MG7!>\^8]W=ZLWO?1R[/$P+CF;MWAR7#CL7?*YVIE-(YS\BAO2=.=I]2]''A# -M7WM+Z[FOJGS@KP2KT7#;@_F$;X-?A)8T&(4"2@P9 -MR<:\".,Z%'?^_VH([NXHU.7'-CAGJ:6SK*=9M>? -M5&TW1/9CA5%R_V(4)HP`MNZ<:A4/%G;S`OD)5DFJKC;MVRNWKJYF%?M_ -M$KF95^W^I7*.N9!F.+.PH\),VCFI*<^K_SP5S_(&/?^_@6>:^211QE+\1UA; -MQ6_$4\/!8#YCPE3S^>IZ^_WZC8ERRVT\JGI^1]Y_I^'_) -M-4]1?+RS4G.]-%'O#I?!_HS8MD[$/F*+`]4#=*W*.RZX]G"E`;G^J37]A<8?&6'@P%:B>L>+"/GSEB? -MZ7NY,-`^;>[@?2FI&UIW9W*KIE;ITW.ICW,S;"8F>='X&FW8//JJ7UU].?<>C=\U6@Z7;DIU;T:J8FDQ,PO\0$U9? -M=&P[O2-=<*%M9X_@,ZH7O/;\%G= -MWK,/>_H\"68]=P,`XY^_=XDZ<[>0I,4F)=^AXGK -M-[U?"2F!BZ:+1?!)[_@HQ9OJ3(L"G[^\&>"I=G8G^$CJ`MBSEQQH\[<_S)2[ -M$B(J-"&O!!YF]"H9['M(>0,<]O7+_JI&IRMKO -M?X\:F`$6+A:M`;;E\[NUH7$VZV.86.DM3I\-T<4"PTWP4LL*K -M],RKZOU%3D*WAE>8;OMNDT6`:B`],#=J0%G8_$G-S'XW]6/CB!W;VGS?J%KM -M\-AH]O]S@1_#\+()-D0N\CU,N3)4$0FN]I1!5D`X0%O>)UW61W$3N;J/II,R -MJC$M+LRWX#?`ENP+/.B`)FE=)DZ,U`(:RO$?06N)_QX#7B]?DFC[XX"WP&A6%QICE<=`XD -MS'_()2S2OJX93YD6_TJX=3.]>HR:F\IQ[+E2O9*?"5/ZK[\&-->L^K)J.C_ -M?QOAUG'SU?%GS%["X*RDA?+\K5+,G(^'<*F?4QKOAK.^4TMD%@`B926QLJ?7O= -M'5#O9B(*Y'PZ7J+4@LDI`9%(8P]LZBV1.8HLYJM#7NX\S?O>-O(X3<]I4Z9B -M^9,7VEW!@%E\P\NROO*YUS%]43UW_M`F?5!YHZ\R+_8= -M1&0.J".J](0%*GX!O034O"P8#S4'7+OAEYX:[=?LG#)SAU![2SW -MOG,A$_/',<>]`O8+D6;3&\#>?8;7@GE$W.+W%H+B=_IAKXA4&$IC/>;VD?+J -MX*;&6+3OI,-%\[VIQF0 -MJ1M]>U!">C2B.I_11!U!B^N)[HP/ -MXY?S0D&E32)4OKG$K4T\KP13SB'KQVX?]RCRSWM7%Y823`Z-[>O@45!,KAI6 -MV2I0+R\^SWQ3-TV+WZD:-+II,.VHQYYPWF*>6(HWH&/U_J-KYAYGJS2:N$)B -M7JBEZRCQ;V,H\'E/*:*4Z_T)G90I!56?@SGC^:8YXEZ_ASQW.V5!4<2H3F$> -ME5I`B6_ZQD.AL:CD]63*`7$TF!'=.3HG1G2&5Y$!^$,B#2(AH"QZU]N..\9I^]YN#AN>G>9^G4N5T=>F5>F4NUT=8:K#4NUT=9U5G5+M= -M'6<59Q2[71UPRKAE+M='6$JPE+M='6;59M2[71UFE6:4NUT=9E5F5+M='685 -M9A2[71U@JL%2[71U@*L!2[71U?JK]2[71U?*KY2[71P@+Y[(_7^5"NPR5ZMJ -MID18#&M-CLCSV*#L'!,BLY.03/H5#(FYPGT$&*YT[?4@8?&R'QTP+CA00.-R -M*5+8:AM?9@4,B@'-UQ,/`NO#P_G>ES\/YYZW`F1X_:AO^YK+,5?*S^@3<_3, -MQMV#FM!&9C14=%_C$QU][]@,P9:_]=]`?X>\?]2H?^A<7F-ZG@KSV(718EW( -M#7/7D'L&\=V#S.U8J(MY(00[H_BD,_(`/K0^[[\&(_L#IEIFW$$B>N$?S6F&DM -M:;Y,2Y%M(.JX9PT$61N\F>\S8C3],F!;KKRXNKDBZN9$QB^3'F8FYNR -M9W@ACNU)*K@`4DTC1-FB49O2I=;B#AQ1*U%MH$[%SP%K6H&TB?RPVN$#TOOT -MXFZ%\P).8>&HH\03<@B8D7SQJZJ?[L.?>+C-S^:)`N/S08U-'$,W-PIY+?D3 -M$:/=]6&.1TR`8W$,3/2Q)'`&U8?_F`.]ACI#_J<:"M`$'5+H,0,>()$86C$)\S&X-"67+1CF7$9 -MSND'QS@0L03"4_:(Z<-3:M`:\H$Z?MU"34P_FWELATH%LIK2&F<6_,8[#:!%>-BO9!O9O=\Z-K\/&@;A>Y,6"CT-"F`8XH3:\5_"CV^_ZR/,TNZCS -M$;N3W_%'Y\;EG:[9?6\1"DJYE -MT=/B>-X9Y4SKKSZR=[K4(D:S/7($:6@@T;J-V,I!6CB!3PQJTU58CJL]<8>+ -MU@ZP]ENL/C]\*Y*H><(9N!>P@)WL[CH^R,XBC.3T=;F73#9FV.7PXPD-C'X@ -MQSC3$7AQW[6B&X),FC'`L-%NE%L/C"?[\8-K!MZ>.S5*B!4\RL:O[EW$[L>_ -M(2(HBQB<;DSL*5]&'Q(?-^;*LW"M;M,H3J3@`(46XOQYID[!B -M7UT04+I=;83&;D(A-_C-*8B4PRCF+=DZ^T^-1O?VIN&EQPY@7#B.?97F0D%; -MI+7A(C;B61CV+C-V%7'Q_D"*MNV18O]`!*C(A4G%7K9]TG9_[H%V28(C(`S#..K5Y=6K\C -MG6V9I8]V]%NR66+,%*.%8??$YX.1,R0A1V.Z'78=8,"(R%^99;J[ZFJ8+$8T -MB"7*N1S*DS,M7-P5=.:TN,%%1DV -M]&1IT,X48W9)DG1D&PJH\+?`N>&I:BU!=T=LX=EEQUDOOL -M)LZIQ?CVU\2HJN2T==PT!0QYDQ*D',MDHX2LX94B*,TK.&4]@J15$%Z`'[:C -MZ;).]Z*.(SC.`SK%LV44E3MAS^_,!`)5T[FW()6]6YK3MX93\UU?M5(*1+#7 -MHNAD)#WUT!IM_Q7?%FW\?CS$\L'J9C3(2\,><(3-U5XTBZ^CP5!*/L.,-,#,XT -M*ZXY(NDD;11FA^1"0[H$$-X,-%CD-%+2E<$9WC+9A5F%:WA".;&_IX#KW-Y7JZ$HUTN>`2QU_VW-SCEZFR$5-1NI4[F!KN9!75.K$U+4$ZY7 -M(U`'!:[#%1SN(EXWRD[M+51YK8VMWW2^`PC3$A1";![W2]NO/D)2;Z3[BDRE -M@6^D#'=<&U\%23*&EGKLW6(#)*0*CE)3CJ9I?K"`IW)6`1M5KIO;A('0C\KY -MO%`_*V':F(OWCA!C,ID-E4:N57^WJXLN>=OO+`^4Z*0.,BI^9@'Z'Z=[B1>& -M?R_0)D`?IKAXJ%^%TS?W@P^FO]$$3?IH(]LJ^Q3XLV[)TMP8L\SUQUQSWM_S -MJ*13F&]4WSV[7HJ.=B`_O&.,_^IT\OH%S/#WI)+%+/&_81*>M5SU$/]K<22X -M_X%'CJ>*?>N]U1Y)`ZYUV\EZ3^Q__IPH.F`)ZWQ-V$.2<<^\=O$_N4;'UG28 -M_V;NHCAY)"7/JJ/><=OAU%=\+?WYV2=\XPBW\$NO%Z=TYI9VB1=<06EZA1KP -M4[.H!7U;M*^KK&?(Z!\CMG5,TW.-@PQ]-K^1Y9EYGSEA55=315UEMJLP7^V5 -M\#'@?)(>^E_>I4[M6:M3;JSGU/%5F:/EX[F9M3YBLCY&;Z;F:U3ZRL[)3'5G -M:*>>K.B4_"K/>*8GJ*Q8J9]6;)2TW*8=LXT$NWYU3F',]HISZLZ%32JS,'RU -MSF8:FG5G1GKOG,P77QY>&PG7R59TCCY;F<,?#SG@H9:=\>\IU+M=&87\&CI&&#)=\ -M6NW<>*WQSUX[SF`YE^J^2X^6WYC?G-^HWS''FO/)7\SY1C)DI]]XN/A1T'#- -MIZB-H-,2>^,=6FWTO`X`/.`$J/E`I,WDO.%^\WI#+"OLJW;T3X_O$NC+FF=G -MI.>C5277-TYZA^HP5JW'8MUS=@W9M[=OOF[63"(;MO?./!;MV^(WQ6^.W<-^ -M.WY#Q,Q*GIY>&=,]"]0Z_.;^:WBSU/M]4W5UFU)KQW8(E@^/Q>,2[U\JO1RG -M],O=YIN;;)N8L5\L_@^,+AK&]FTOTVM98V0^,B%KL:K*UUEE*I'5K(5P^3SI -M]D,F.[2_E"2@3^#GO:ROU[5!:5NTLP+QMP!R363:S+5$&'&C_4'=K"AO'>_. -MY#NHK6;:^/;**CR3B`=T>8[!KKFLQF
    C$-@``A,!U -M$57HJ#4``(3`=0=35NBI+P``BT<(:CI9@[A<80``!`^WJ/J"``!U&8/]6'44 -M4>A\-0``A,!T"C/`QD0D$`%FB0:#_45T$XM'"(.X7&$```%T!U/_="0@ZPM3 -M_W0D(.CJ.0``4%;H8WP``(M'"("XHV$```!U!E;H"C<```^W!E#H])4``(!\ -M)!``#[?X=#IJ7UMF.5X"=1P/MT8$4.@?-@``A,!T#HU'OV:#^!EW!6HZ6.L1 -M9CD>=1!F.5X"=0IJ7%AFB09FB48"7UY=6UG"$`"X!"%#`.@]8`$`N$R=``#H -M#V$!`%:+\8V-J&+___]V".APCO__@V7\`(V&]@```%"-C:AB___H3QL``(3` -M#X0Y`0``:@&-C:AB___H:93__X3`=1%J`;E0#T0`Z$WJ___I%P$``("];<__ -M_P`/A0H!``!35S/;,_\XG5W/__]T>V@`"```C87,8O__4(V%\.___U#HC'L` -M`#B=8L___^L3`[VH[___$YVL[___@+UBS___``^4P`^VP%!H``@``(V%\.__ -M_U#H\#8``(V-J-___^@VZ___:@"-A:C?__]0C87P[___4.C!(```A,!UL0&^ -MF````!&>G````(V%J&+__XO.4.B/````BT8(:DE:7P^WB/J"``!;@_E4=`5F -M.\IU!\:``6(```&+1@AF.9#Z@@``=!J`N`%B````C8[V````40^4P`^VP%#H -M%9```(V-J&+__^BYF/__C8VH8O__Z+^S__^-3?-14(V%J&+__XO.4.B$```` -MA,!UWHV-J&+__^B_C___BTWT,\!>9(D-`````(OE7<-35HOQBTPD#.C3$P`` -MB49H,]N+1@B)5FR)GN@```")GNP````XF"11``!U#>B8CP``A,!U!(O#ZP,S -MP$"+SHB&]A```(A>7XB>]Q```,:&\0````&(GO0```#H\H<``%Y;P@0`N"0A -M0P#H05X!`+B@40``Z!-?`0!3BUT(,])7B_F)?>"+1P@/MX#Z@@``B47H.54, -M=2HX5U]T'%!2C4<04%/HL?\``(3`=1-J`;E0#T0`Z%[H__\RP.F3````,])6 -MB[/<(0``@_X"#X23````@_X#=1V`O_<0````#X03#```C8?X$```4%/_=PCH -MGO3__X/^!0^%^@L``("[K$4````/A`$,``"+=>@SP%90C4<04%/H/_\``(3` -M=1%J`;E0#T0`Z.SG___IVPL``(L#,\E1_[.D;```BW`0B\[_LZ!L``#_%6`R -M0P"+R__6L`%>BTWT7UMDB0T`````B^5=P@P`B)?W$```.9/<,@``?Q9\"#F3 -MV#(``',,B9/8,@``B9/<,@``.9/D,@``?Q9\"#F3X#(``',,B9/@,@``B9/D -M,@``BT\(.9%@80``=1N+@32C```YA^P```!R#8"_\0`````/A3X+``"^``@` -M`(A5[5:-A52N__]04FH&C47M4(V#@"(``%#H)]7__X7`#Y7`B$7NA,!T#H!] -M[0!U"#/`B(?Q````B\OH0I?__U:-A<3N__]0C8.H(@``4.@++```,\E!@+MS -M,P```(E-Y'13BT<(BX#$<@``.\%T9(!][0!U7H7`#Y3`_L@@1>XSP%"-A<3N -M__]0Z#4U``"+3PB+B<1R``!).\AU$C/)C87$[O__05%0Z!Z*@QDS``"(1U\SP(A' -M8(N+J&P``"N+V#(``(LS4(N#K&P``!N#W#(``%!1BTX0_Q5@,D,`B\O_5A`S -MTHK"BLJ(3?*(3=PX1>YU%HJ3M&P``(A5\HA5W(32#X3>"0``,]*+1PB+=>AJ -M28J(`6(``%B$R70'9COPL`%U`HK"_W7;__S/`4(V%5,[__U"- -MA_@0``!0Z$L<``"$P'0VC8/`,@``4(V-9-[__^CG\___A,!T,H"]8-[__P!T -M$%>-C63>___HL//__X3`=!DSP(A%\^L2BT<(@+A780````^5P/[(($7SC87$ -M[O__B\]04^C)\___A,!U(FH"N5`/1`#HX>3__XO+Z!J4__^`N[1L````#Y3` -MZ0;]__^`NQLS````=!>-A<3N__^+SU!3Z+WX__^$P`^$W````(MW"(V]Q/[_ -M_VI`@<8D4```6?.E9J4/MHL@,P``C478BWW@,])0C8-+,P``B57\4/^S;#,` -M`/?9C8,Q,P``4!O)C8,A,P``(\B-A<3^__]14/^S'#,``(U/$%+H)D```("[ -M&S,````/A),```"`NT$S````#X2&````:@B-1=A0C8-",P``4.C_=`$`@\0, -MA'__XM/ -M"('!)%```.@K8@``@TW\_XV-Q/[__^BI80``Z03____&A_@@```!Z;<'``!J -M!NATX?__:@NY4`]$`.BPX___,\"(1?.#3?S_C8W$_O__Z'%A``"-C9S>___H -MC0L``(N#@#,``,=%_`$```")1=1J4%J%P`^$C0```(/X!0^$A````(I-\XMU -MZ(3)#X3]````9COR#X3K````BT<(@+@!8@````^%VP```#/`B$7OC8?X$``` -M4.CN%@``A,!T-8!][P!U.3/)C8/`,@``45#_L^0R``"-1>__L^`R``!0:``( -M``"-A_@0``!04?]W".A*"```@'WO``^$A````#/`BLB(3?/K?HO+Z`B4__^$ -MP'10@'WS``^$G@```(M%Z&:#^%`/A)$```!J25EF.\$/A(4```!J15EF.\%T -M?8M'"#/)03F(7&$``'1O_X?D````C87$[O__4%.+S^@B\___ZUB*3?.$R70B -MC863I7OK__X3)#X3$!0``BT<(@+@!8@```'00QH?W$````8"X`6(```!U -M28I%\H3`=44SP&I0B$7O6&8[\'1`C8V\!A,!U!O^'Y``` -M`/^'Z````(VS\#(``#/`C8_(````B8>`````B8>$````B8>(````B8>,```` -MBT<(_[#@@@``_S;H)QX``(M'"(V/H````/^PX((``/\VZ!$>``"+@]@R``"- -M=Q"+B]PR``")1S"-A9S>__]0B4\TB\Y3Z%(]``"*5>\SR8I%\HA7.8A'.HE- -MW(E-Y(32#X6=````.(O$;```#X61````B[/D,@``BY/@,@``._%\?G\(@?I` -M0@\`=G2+B]@R``"+@]PR```/I,@*P>$*.\9\6'\$.\IV4C/`._!\(W\(@?H` -MX?4%2*1?(SR8UW$(M7"("ZH&$````/ -ME(6UWO__@'WO`'44A,!U$&I06&8Y1>AT!S/`0(K(ZP,SP$"#?=0`B$WPB$7L -MB$7Q#X0)`0``B[.`,P``@_X$=&>#_@5T8COP=$*#_@)T/8/^`W0XC8?X$``` -M4(U#)%!J1^B]W?__,\F*P8A%\8I-\,9%[`"$R0^$N0```(3`#X2Q````,\!` -MZ:L```"$R0^$A````(V'^!```%!3C4<04%+HX>G__^M@:``(``"-A52^__^+ -MSU"-@X0S``!04^CF\___BDWPA,ET3F:#O52^__\`=$2-A52^__]H``@``%"- -MA_@0``!0@_X$=0K_=PCH&>?__^L2C4,DB\]0C86`P``B$7QA,`/ -MA%K___^*3?#K`XI%\8.[L&P```(/A4S___^$R0^%3/___^D[____,\"(A_<0 -M``#K?H"[&#,```!U=8"[H"(```!U%/^SY#(``/^SX#(``%;HQ0,``.M8#[:# -M<#,``(N/X````%#_LW0S``#HT9T``(N'X````(N+X#(``(N3Y#(``(F(2$P` -M`#/)B9!,3```B(A@3```#[:#<#,``(N/X````%#_LYPB``#H09H``(O+Z.>- -M__^`NQDS````=3`/MI-*,P``C8-+,P``]]J-C\@````;TB/0C8/P,@``4E#H -M!!L``(3`=`:Q`3/`ZP0SP(K(@+MP,P```'4(B(?T````ZR:`NZ`B````=!TY -M@^0R``!\%7\(.8/@,@``=@N$R70'QH?T`````8!]\@"(1?!U7X!][`!T683) -M=54XBQLS``!T*#B+03,``'0(.(O$;```=!B`O_0`````=0^-A<3N__]0C4,D -M4&H$ZPV-A<3N__]0C4,D4&H#Z);;__]J`[E0#T0`QD7P`>C.W?__BD7P@WW4 -M`(I5\701@[N`,P``!'4(A-)T!+$!ZP(SR8!][P`/A4X!``"+=>AF.W70=`IF -M.W7,#X4[`0``@WW4`'09A,EU%8.[@#,```4/A20!``"$T@^$'`$``(3`=!.+ -M1PB`N*!A````#X0(`0``BD7PA,D/A;X```"+5>0SR3O1BTW<=P2%R70?A,!U -M$#F/B````'4(.9>,````=`N-C9S>___HR@T``(M7"(VST#(``(V[P#(``(N" -MV'(``(N*U'(``/?8&\`CQO?94!O)C8/(,@``(\B+@M!R``#WV%$;P(V-G-[_ -M_R/'4.@F#```C8V!3_W`(Z*KI__^+1>"+2`B+@=AR -M``#WV!O`(\90BX'0<@``C8V"P``BWW@BT<(@+BH80`` -M`'4L_[.D(@``C;?X$```5NCU$@``A,!U%E:-0R10:A'H(-K__[E0#T0`Z*;< -M___&A_<0```!@TW\_XV-G-[__^A^!```@'WN`(I%\XI5\G0&_X?L````@']@ -M`'4DA,`/A6'T__\X@[1L``!U#(O+Z%F+___I3?3__X32#X5%]/__,L#I0/3_ -M_[A!(4,`Z)51`0"X/!```.AG4@$`4_]U&/]U%/]U%.B'*P``C8VX[___Z-,# -M``#_=10SVXV-N.___XE=_.BA#```A,!U'/]U$/]U%/]U#&H2Z"WI____=0QJ -M$^@MV?__ZT-H```0`(U-X.A=?___QD7\`>L,BTT(4/]UX.B:#```Z!UU``#_ -M=>2-C;CO____=>#H10D``(7`==J-3>"S`>AI@?__C8VX[___Z(P#``"+3?2* -MPUMDB0T`````B^5=PA0`N%,A0P#HTU`!`(/L%%;H8NK__U"-3>#H[7[___]U -MY(M-"/]UX(-E_`#HRS<``(OPA?9^1%.+71!7BWT,B\:9.]-_!GP&.\=R`HOW -MA?9^$XM-"%;_=>#H@SD``(O&F2OX&]K_=>2+30C_=>#HB3<``(OPA?9_QE]; -MC4W@Z,N`__^+3?1>9(D-`````(OE7<(,`%-55E>+?"0DA?]T`\8'`(MT)!PR -MVU;H4`X``(ML)!CK5X3;=0Q6_L/HJP```(3`=4$SP#+;A>T/E,!0_W0D-/]T -M)#3_="0T_W0D,%;_="0LZ)]_``"%P'0C@_@!=#^#^`9U#VC_````N5`/1`#H -MZ=C__U;H\PT``(3`=:4SVSA<)#0/E<.#PQ&%[70<4U:+S>@A`P``A,!T#[`! -MZS2%_W0#Q@UT"U-6B\WH[0(` -M`.L&5NA'#0``7UY=6\(D`+AH(4,`Z&I/`0"X+%```.@\4`$`4U:+=0B-AH__^#Q!"-A?#O__]0Z)P,``"$P'0+,\!F -MB87P[___ZP=FBX7P[___@\=[@?\0)P``?)QFA<`/A*````"_``@``(V%R,__ -M_U=64.@=:@``5_]U\(V%R,___U#HVR<``(V%\.___U"-AL",L"+3?1?7EMDB0T`````B^5=P@0`@TD$_S/`QP$L -M.$,`9HE!)(A!"(E!#(A!$(F!)!```&:)02&(02")012+P<=!&``!`0#'01P` -M`0``PU6+[&2A`````&K_:($?0P!09(DE`````(-Y!/_'`2PX0P!T&(!Y$`!U -M$H!Y&`!T!^B2`0``ZP7H1````(M-]&2)#0````"+Y5W#S,S,S,S,5HOQZ*C_ -M___V1"0(`70-:"@0``!6Z.M,`0!968O&7L($`,S,S,S,S,S,S,S,S,S,4U:+ -M\;,!@WX$_W0B@'X0`'48@WX,`'42_W8$_Q48,$,`C5C_]]L:V_[#@TX$_X-F -M#`"$VW43.%X:=`Z-1B2Y4`]$`%#H3M7__UZ*PUO#N`00``#H:$T!`%.+G"00 -M$```B\-5T>A6)`&+\5?VPQ!U"H!^(@!U!#/MZP,S[47_M"08$```,\F)7AR$ -MP`^4P4F!X0```("!P0```,")3"04Z%DE```/MP"#^"YT!8/X('41]L,@=0R# -M3@3_,]N+?"00ZQV+?"00,]M34VH"4U57_[0D,!```/\5)#!#`(E&!(-^!/]U -M+V@`"```C40D&%#_M"0@$```Z/$>``"$P'054U-J`E-55XU$)"Q0_Q4D,$,` -MB48$:``(``#_M"0<$```C48DQD88`5")7@R(7A#HCF<``(-^!/]?7ET/EX($X``#E%#'8- -M4/]U"(O.Z*[____K.X-^#`%U#_\5`#!#`(/X;74$,\#K)H-^#`!U&+\`@``` -M.7T,=@[_%0`P0P"#^"%U`U?KP8/(_^L#BT7\7UZ+Y5W""`!145.+V5565XL# -MB5PD$(MP%(O._Q5@,D,`B\O_UHL+B^IJ`FH`:@"+<1"+SHE$)"#_%6`R0P"+ -MR__6BP.++TU]>75M96<-5B^Q15E>+^<9%_P!J`8U-_U&+!XMP#(O. -M_Q5@,D,`B\__UHI%_U]>B^5=PX-Y!/]U`S+`P_]Q!/\5/#!#`(/X`G0(@_@# -M=`,SP,,SP$##S,S,S+A4$```Z-9*`0!3BYPD8!```%57B_F#IR00````@'\B -M`'4)]L,$=00RR>L"L0&+P]'H5B0!#[;P]]X;]H'F````P('&````@/;#`70& -M@L#]].#XP&$R70#@\L",\"-3"0<.$<;#Y7`2"4````(B40D$.A, -MU?__@'\@`'0&@=!^#_?]T&H-,)!#_C40D$(-,)!3_:@!0:@!5_Q44 -M,$,`,\"#_?^(1Q@/E<.)1PR(1Q"#_?]T'&@`"```_[0D:!```(U/)(EO!%'H -M@F0``,9'(0!?78K#6X'$5!```,((`%97,_:+^5;_="04_W0D%.@D````A,!T -M&XO/Z'\#``"+!U965HMP$(O._Q5@,D,`B\__UE]>P@@`456+Z8-]!/]T>%.+ -M7"045XM\)!2%VW\X?`2%_W,RBTPD'(7)="Z#^0%U%HM%`%:+ZP>+S>A$_?__`_@3VC/)ZP2+3"0+^8!_(0!T!S/`Z1H!``"#9"0(`(-D)`P`559J`ETY;Q1U&8L' -MBW`4B\[_%6`R0P"+S__6B40D$(E4)!2^4`]$`%/_="0DB\__="0DZ`G\__^+ -MV(/[_P^%R````(!_&@")KR00```/A+@````Y;Q1T6S/`B$0D$HA$)!&(1"03 -M.4<4=2TY1PQU*(U$)!.+SE"-1"054(U$)!I0C4+^8%_'``!``!T#_9''`)U"?]W!/\53#!# -M`(M,)"PSVT.%R70+BP$+001T!(K3ZP(RTE:+="0TB%0D$X7V=`N+!@M&!(A< -M)!)U!<9$)!(`BVPD.(7M=`B+10`+101U`C+;A-)T"HU$)!10Z#9O``"`?"02 -M`'0,C40D)(O.4.@C;P``7H3;=`R-1"08B\U0Z!)O```/MD0D#XU,)!#WV!O` -M(\&-3"084`^VP_?8&\`CP8U,)"10#[9$)!;WV!O`(\%0_W<$_Q44,$,`7UU; -M@\0!'41@'X:`'1:C48DB\U0Z([/ -M__^#9"0,`(U$)`Q7:@%0:@#_=@3_%50P0P"+^#O[=1O_%0`P0P"%P'01@'X: -M`'0GC48DB\U0Z%7/__^+1"00,\F9`\^+T(O!@](`7UY=6UG#B\.+T^OUB\.+ -MT^ON_W$$_Q50,$,`2/?8&\!`P_]T)`C_="0(Z$+X__^$P'0$L`'K$/]T)`2Y -M4`]$`.C#S?__,L#""`!65XOY:@#_="00BP>+<`2+SO\58#)#`(O/_]9?7H3` -M=`2P`>L0_W0D!+E0#T0`Z'G.__\RP,($`%%14U6+;"08B]F%[74'L`'I!`$` -M`(-[#`%U"VKU_Q5`,$,`B4,$5E>_`$```(-D)!``@WL,`,9$)!0`=#TS]H7M -M=%N+Q2O&.\=R`HO':@"-3"0445"+1"0H`\90_W,$_Q5$,$,`2/?8&L`$`8E$ -M)!1T+`/W._5RR^L@:@"-1"044%7_="0H_W,$_Q5$,$,`2/?8&L#^P(E$)!2$ -MP'5Q@'L:`'1K@WL,`'5E:@"-75M96<((`+@$ -M$```Z#=$`0!6B[0D#!```(7V#X2X````,\!F.08/A*T```!35[,!B40D#(O^ -M58OHT?V!_0`(``!S7P^W!U#HR1@``(3`=#T[_G8YC48$._AU!V:#?@(Z="M5 -MC40D&%90Z-RX`0"#Q`PSP&:)1&P44&H!C40D'%#HC0$``(O8]]L:V_[#BT0D -M$(/'`H/``C/)B40D$&8Y#W65@+PD'!````!==296Z-(;```/MP!0Z%D8``"$ -MP'43,\!0:@%6Z$75N!Q"00``#"$`!5B^RX`!```.CL/P$`4_]U#/]U"/\56#!#`(7`#Y7# -MA-MU+6@`"```C84`\/__4/]U".CN$0``A,!T%?]U#(V%`/#__U#_%5@P0P"% -MP`^5PXK#6XOE7<((`(.)!!```/\SP&:)`8O!QH$`$````<.+@000``"#^/]T -M!U#_%6`P0P##5HMT)`S_="0(QH9$$````.A'%```A,!T!#+`ZT-6_W0D#&K_ -MZ`4!``"#^/]TZU#_%6`P0P#_M@@0``"#ID`0````Z-7\____M@@0``"(A@P0 -M``#HW/S__XB```+`!7L(,`%-65XM\)!"+\>F"````@+X`$````%=6=`]J -M_^BJ````B88$$```ZPO_M@00``#HEP```(/X_W1I_[<($```B9]`$```Z&_\ -M____MP@0``"(APP0``#H=OS__XB'#1```%>(G@`0``#H`!<``(O8:$@X0P!3 -MZ".1`0!9687`=!%H3#A#`%/H$I$!`%E9A#X5M____ -M,L!?7EO""`"P`>OV5F@`"```_W0D#(OQ5NA560``QH8`$````5["!`"X4!(` -M`.@_/@$`4U56B[0D8!(``(U$)`Q7B[PD;!(``(/+_[T`"```4#OS=7#_M"1L -M$@``_Q5D,$,`B_`[\P^%@````%6-A"1D`@``4/^T)'`2``#H'!```(3`=!F- -M1"004(V$)&0"``!0_Q5D,$,`B_`[\W5._Q4`,$,`@_@"=`^#^`-T"H/X$G0% -M,\!`ZP(SP(B'1!```.G0````5O\5:#!#`(7`=12+\_\5`#!#`(/X$@^5P(B' -M1!```#OS#X2I````5?^T)&P2``!7Z'A8``!5C40D0%!7Z#H6``"+3"0L,\`# -M1"0PB8<`$```BT0D$(/1`(F'"!```(M$)!2)AR@0``"+1"08B875N!Q%`2``#"#`"`?"0$`%:+\<9&"`!T'E>_`X```%?H -M;SX!`%=J`%")1@SH8$P!`(/$$%_K!(-F#`"+QE["!`"`>0@`=0G_<0SH3CX! -M`%G#5HOQ@WX,`'0/@'X(`'4)_W8,Z#4^`0!9BT0D"(E&#,9&"`%>P@0`BU$$ -M`U0D!(O"@^('P>@#`0&)403"!`#I`````%.+V597:@B+<("_C3[P^WQU]>6\,SP(E!"(D!B4$,B4$0B\'# -MS,S,S,S,S,S,S,S,5HOQZ*X#``#_="0(B\[H'`$``(O&7L($`%.+7"0(5597 -M:$"J0`!J"&@(`0``B^E35>B6`0``C;5`"```B\[H -M````C;-("0``N8````"-O4@)``#SI8N#2`L``(F%2`L``(N#3`L``(F%3`L` -M`(N#4`L``%^)A5`+``"+Q5Y=6\($`%-65XO9:@B+\U^+SN@4`P``@<8(`0`` -M@^\!=>Z-BT`(``#H_@(``%]>B\-;PU6+[&2A`````&K_:($?0P!09(DE```` -M`%:+\5>+?@R%_W04B\_H#E\``&@X`P``5^@2.@$`65EJ!(U&!%#HDT0``(-^ -M"`!T&;]4"P``5_]V".A_1```5_]V".CH.0$`65F+3?1?9(D-`````%Z+Y5W# -M5E>+?"0,B_$[]W0Q:+````#_M_````#_MO````#HOTL!`(N'``$``(/$#(F& -M``$``(J'!`$``(B&!`$``%^+QE["!`"#.0!T3XM4)`2#.@!T1H,Y`74%@SH! -M=`J#.0)U$(,Z`G4+BT$$.T($#Y3`ZRF#.0-U'H,Z`W49C4($:B!0C4$$4.BA -M5`$`@\0,]]@;P$#K!C+`ZP*P`<($`%>+?"04A?]T+5.+7"0058ML)!!6*^N+ -M3"0DC30K4_\58#)#`(O._U0D*`-<)!R#[P%UXUY=6U_"%`!5B^R#["2-1=Q0 -MZ+@```"#?0P`=`S_=0R-1=Q0Z*ZT____=0B-3=SH0?___XOE7<((`%6+[%%6 -MB_&#?@@`=2!H5`L``.B#.`$`B47\687`=`F+R.@S_O__ZP(SP(E&"(M%"(D& -M@_@!=02#9@0`@_@"=02#3@3_@_@#=0C_=@CH@JS__XM%#(/X"'(#:@A8B480 -M7HOE7<((`(M$)`2)`8/X`70%@_@"=02#800`@_@#=1-J((U!!&@`X$,`4.A) -M2@$`@\0,P@0`58OLBP&![%0+``!6BW4(B0:#.0%U!HM!!(E&!(,Y`G4(BT$$ -M]]")1@2#.0-U'O]Q"(V-K/3__^@0_?__C48$4(V%K/3__U#H8JO__UZ+Y5W" -M!`"XW")#`.CJ-P$`45:+\8,^`G41_W4,_W4(_W8$Z#NQ__^)1@2#/@-U7(-^ -M$`%V,%0!```(F>1!```(F>4!```(F>5!```(F>2!```(F>3!```(F> -MF!```(E>)(F>G!```(B>H!```(B>P1```(B>RA```(F>[!```(F>\!```(F> -M]!```&:)GO@0``"(GOH0``")G@`1``!FB9X$(0``7EO"!``SP&:)012)01AF -MB4$B4$@B4$DB4$HB4$LB4$PB4$TB4$XB4$\PU6+[(L-(.!#`('L%`$` -M`(/Y_W4\C87L_O__QX7L_O__%`$``%#_%6PP0P"+C?S^__^+A?#^__^+E?3^ -M__^)#2#@0P"C8`]$`(D59`]$`.L+H6`/1`"+%60/1`"#^0)U!\'@"`/"ZP6X -M`04``(OE7<.X!"```.C1-@$`BX0D$"```%-5B]C!ZQ]6@.,!#[?PB%PD#(ML -M)`Q7B[PD&"```(7V#X1'`0``5^CQB`$`B40D%%F#_@)T3(/^!'1'@_X#=$)0 -M_[0D("```%>$VW0*Z$"K`0"#Q`SK!>@D:P``AARA@$`65GK -M!>BT3@``7<(,`(!\)`@`=`:+1"0$ZPG_="0$Z$MH``#""`"XCB%#`.C=,@$` -M45:+\8EU\(V.)%```.C2.@``,\")1?R)AG!A``")AG1A``")AGAA``")AGQA -M``"(AH!A``")AK!A``"+SHF&M&$``(F&N&$``(F&O&$``(F&P&$``(F&Q&$` -M`(F&T&$``(F&U&$``(F&V&$``(F&W&$``,9%_`&)AN!A``")AN1A``#HA@`` -M`(M-](O&7F2)#0````"+Y5W#58OL9*$`````:O]H@1]#`%!DB24`````5HOQ -M@SX`=!R`?A``=`Z+1@C!X`-0_S;HCSP``/\VZ%.%`0!9BTWT9(D-`````%Z+ -MY5W#5FCP@@``B_%J`%;HA4(!`(/$#(V.<&$``.B7____C8XD4```7ND*.@`` -M5E=H\((``#/_B_%75NA90@$`@\0,QT8,`````KC___]_B;XP80``QX8T80`` -M`P```(F^*&$``&H"68F^D&$``(F.T'(``(F&\&$``(F&]&$``(F&^&$``(F& -M_&$``(F..&$``.@U6```7XF&X((``%[#5HMT)`A6Z(&$`0!9A6XOE7<(,`+@`$```Z%,Q`0!35HNT)`P0``!7:BY;#[<& -M9H7`=$.+R(U^!`^WP5#H_04``(3`=!QF.5_^=19F.1]U$0^W1P)0Z.0%``"$ -MP'0#C7<$#[='_H/'`HO(9H7`=#[?#4.AB!0``A,!T!8U] -M`NL%9CO>=0R#Q0(/MUT`9H7;==V+M"04$```:EQ;,\D[_G02B_>)M"04$``` -M9CD/#X5M____:BY;768Y'G4/9CE>`G4)9CE.!'4#@\8$@[PD%!````!T*&@` -M"```5HU$)!10Z"A+``#_M"08$```C40D$%#_M"0<$```Z!!+``!?B\9>6X'$ -M`!```,(,`%6+[+@`$```Z/0O`0#HI/C__ST`!@``+?"00A?]T-E:+ -M="0,3U;HT`<``"O&T?@[^'(,5NC"!P``B_@K_M'_5U:+="085NA9I`$`@\0, -M,\!FB01^7E_"#`!3BUPD##/`5XM\)`Q79HD#Z/H"``"$P'08#[<'4&B@.$,` -M_W0D'%/H?(C__X/$$.M75FI<7F8Y-W5-9CEW`G5'C4<$5E#HZ6`!`%E9A7UO"#`!7BWPD"&:#/P!U!(O'ZW]35E?H^(`!`$A9C1Q' -MZP<[WW80@^L"#[<#4.@82```A,!T[`^W`XOSZPH[]W9-@^X"#[<&4.C]1P`` -MA,!U[#OW=CE5:BY=#[<&9CO%="Q0Z.-'``"$P'4)@^X"._=WY^L95^B?!@`` -M55#H*6`!`%E9AB\-;7\($`%6+[(M%#%97BWT4A`F8Y`P^%!0$``(MU$(U'!COP#X;W````5FBL.$,`_W4,Z#I(``!6 -M:+@X0P#_=0SH!$@``%93Z<@```"-A0#P__^[_P<``%!3_Q5P,$,`A<`/A+D` -M```[PP^'L0````^W!E#HQ0$``(3`=#>-1P:+?1`[^`^&E@```%=HK#A#`/]U -M#.C91P``,\!FB84$\/__C84`\/__5U#_=0SHF$<``.M?:``(``"-A0#P__]0 -MZ'/Z__^-A0#P__]0Z/-^`0"#QP0#QXM]$%D[^'9#5VBL.$,`_W4,Z(9'``!7 -MC84`\/__4/]U#.A.1P``9H,^+G41#[=&`E#H,@$``(3`=`.#Q@175O]U#.@M -M1P``L`'K`C+`7UM>B^5=P@P`@WPD!#H/E,#"!`!6BW0D"`^W!E#HX$4```^W -MP(/`OV:#^!EW#&:#?@(Z=04SP$#K`C/`7L($`%:+="0(:EQ89CD&=09F.48" -M=!A6Z+O___^$P'03#[=&!%#HM````(3`=`4SP$#K`C/`7L($`%:+="0(5NB_ -M____A,!U$0^W!E#HC0```(3`=00SP.L#,\!`7L($`%-6BW0D##/;9CD>=!MF -M.5X"=!6-1@1J.E#H?5T!`%E9A_ -M``@``%=64.BW10``5NAV_O__A,!T!V:#?@0`=`U7C84`\/__4.A?^/__5_]U -M#(V%`/#__U#H844``/]U%(V%`/#__U#_=1#H=T4``%]>B^5=PA``45%358ML -M)!0SP%97B_");"04B]T/MP.)1"00#[?`4.@7____A,!U"&:#?"00`'5&C7[_ -MA?]^/VHN6P^W1'T`@_@@=`5F.\-U*68[PW4>#[=$??Y0Z.+^__^$P'45#[=$ -M??YF.\-U!8/_`70&3D^%_W_(BUPD%(M$)!!FB41U`#/`9CD#=`J#PP)&B5PD -M%.N$7UY=6UE9P@0`55:+="0,,^UF.2YT6U.*7"045XO]N8@X0P"$VW4%N9@X -M0P`/MP904>B26P$`65F%P'4*A-MT#F:#/B!S"&I?66:)#NL#:E]9B\>#X/Z# -M^`)^"6:#/CIU`V:)#H/&`H/'`F8Y+G6O7UM>7<((`%-55E>+?"045^BM^?__ -MBUPD&(OP,^V%]G464VA<.$,`5^@;1```5^B/^?__B_#K.F8Y;@)T'FAH.$,` -M5NB[70``A8UN!`^W10!0Z/5!``"$P'1,#[=&!E#HYT$``(3`=#Y6Z*9Z`0!(66HZ6XT$ -M1F;_`&8Y&'5$:C!=:BY:.\=V%F8Y4/YT$&:)*(/`_F;_`&8Y&'3HZR1J85EF -MB0CK'"OWT?XKWH/K`E-H@#A#`%7H!T,``.L%,\!FB0=?7EU;P@P`5E=J._]T -M)!`S_^@D7`$`B_!9687V=!>-1@)0Z%A<``"`?"00`(OX=`4SP&:)!HO'7U[" -M"`!6BW0D"%;H"WH!`%F%P'0&C31&@\;^B\9>P@0`4U:+="0,5U;H[7D!`(OX -M@^\!67@8C1Q^#[<#4.A3_/__A,!U((/K`H/O`7GK9H,^`'0*9H-^`CIU`X/& -M!(O&7UY;P@0`C4,"Z_56BW0D"%;HJ____XU.!#O!/!```@?N`````#X>#!```A=L/A'L$```S_XE\)#R%VW2U@V0D*`"- -M1"1(@V0D)``S]H-D)"``,^V#9"0<`"%T)!1J'%90B70D).B[-`$`(70D/(/$ -M#(E\)"P[?"0X#X.9`0``BT0D%(M4)"2+RBM,)""+?"0#Z`%T)H/H`705@^@!BT0D%'54@_@0 -M?4]`B40D%.M(BT0D%(/X\'P_2.ONBT0D%(/^$'TS1NL*BT0D%(/^\'PG3HET -M)!CK((M$)!2#_1!]%T7K%(M$)!2#_?!\"TWK"(MT)!B+1"04BTPD+`/+_T0D -M,(E,)"P[3"0X#X)O_O__BWPD/$>)?"0\._L/@AC^___IR/W__XM&!(M.%(M^ -M"(E$)""-6/V)3"0PC4']B5PD/(E\)$0]_?\!``^'6@(``#O9#X=2`@``@_\" -M#X=)`@``BP:)1"0LC2P(,\"+U8EL)!@KTXE$)"2)5"04,]L[P0^#NP```(T\ -M`HM$)#R+5"0@*\6+;"0\B40D*`/'.\)R;@^V!P^V3_V+\"OQB40D.`/SB4PD -M-(O&*\-0Z"N8`0")1"1$B\8K1"0\4.@;F`$`*W0D/%:)1"0HZ`V8`0"+3"1, -M@\0,BU0D'#O*?PX[R'\*BTPD,(M4)"#K%(M,)#`[T(M4)""+7"0X?@2+7"0T -MBT0D+"H80`^VVXE$)"R+1"0HB!PO@\<#`\<[P8M$)"@/@F;___^+;"08BT0D -M)(M4)!1`B40D)(/X`P^"+?___XM\)$2#P?[K#HI$+P$`!"\`1"\"@\<#._ER -M[NE__/__BT84BQZ->.N!_^O_`P`/AR\$1XE\)#@/M@.#X!^#Z!!X=8J`<.!#`(3`=&N+?"0L,\D/MM!J$HE,)#2) -M5"1`73/`0-/@A<)T.6H$C448B\Y04^C3````@_@%=1YJ%%5J%%53B\[HP``` -M`"O'B\XE__\/`%!3Z/L```"+5"0\BTPD,$&#Q2F)3"0P@_UD=K&+?"0XBU0D -M+(/#$$*#[P&)5"0LB7PD.`^%:____^FV^___BT84BPZ+=AR-6/R!^_S_`P!W -M7X/Z`@^4P#/_!.B(1"03A=L/A(W[__^*$4%'1H#ZZ'0$.M!U,HL1A=)Y$8T$ -M%H7`>!B-@@````&)`>L.C8(```#_A`("_#!XP@/MD07`H/*_PO#P>`0"\;3Z%DK3"087]/J7B/"6\(,`%6+ -M[(M%$%-6:B"#R_^+\%DK312#X`?3ZXO(TV4,BU4,T^,SR<'N`_?3`W4(B@0. -M(L/!ZP@*PH'+````_\'J"(@$#D&#^01RY%Y;7<(0`%:+\8,^`'4-:`0`!`#H -MR"$!`%F)!E[#BU0D!#/`4U:+="00,]M`BLL[\'8(,@P00#O&L&#[;;:@KHO^+__^L-:@;HMN+__\'K"H/C#XO#7UY;P@0`5HMT)`BZ -M```$`#ORBT0D$"O6.\)R`HO"ABN4P$` -M@\0,7L(,`%6+[%&+10@STHD1B5$(B5$,B%$0B4$4B\&)3?R)402)41R)41B) -M42"+Y5W"!`"+41P[41AS#8U"`8E!'(L!#[8$$,,SP,-6B_%7BWXPU.+V5>+ -M>QR-1P,[0QAS+HL35@^V=!<##[9$%P(/MDP7`<'F"`/&P>`(`\$/M@P7P>`( -M`\&-3P2)2QQ>ZP(SP%];PU97B_'HM?___XO.B_CHK/___S/)B]`#SU^#T@"+ -MP5[#4XO95597BW,8*W,75M96<.+QHO1Z_.+ -M1"0$BU$8.\)S#8L)@#P!`'T*0#O"7 -M__^+SO?9&\DC3"08`4T8ZSB+\`/"B448ZR^+7"08A=MT)U/H\DS__XM]%(M5 -M&`-5`%.+!U*+<`R+SO\58#)#`(O/_]:+\`%U&%^+QEY=6UG"!`"XXB%#`.@? -M&P$`45%35HOQ5XEU\(V.D````.C:W___,_^-CJ0```")??SHRM___XV.N``` -M`,9%_`'HN]___[O`$```QD7\`E/HFAH!`%F)1>S&1?P#AS&1?P$A6V2)#0````"+Y5W#4U:+\;O`$```5XM^0(7_=!"+S^B\E?__ -M4U?H6!H!`%E9BWY$A?]T$(O/Z*65__]35^A!&@$`65F-CK@```#H[=___XV. -MI````.CBW___7XV.D````%Y;Z=3?__^#24C_,]*($8A1#(E1((E1),=!*`$` -M``")44R(45")42R)43")41R)41B)431FB9',````B5%XB5%\B5%PB5%TB5%H -MB5%LB5%@B5%DB5$XB5$\B9&(````B9&,````B9&`````B9&$````PU6+[(!] -M"`!6_W4DB_'_=2#_=1S_=1C_=13_=1#_=0QT$HM.0&H!Z`F6__^(ALP```#K -M$(M.1&H`Z/>5__^(ALT```!>7<(@`(M$)`2%P'0#B4$LBT0D"(7`=`.)03"# -M24C_P@@`BT0D!(E!%(M$)`C&00P!B4$0P@@`58OL@'DH`'14BU$LA=)T35.+ -M70Q6B[&(````B\97B[F,````"\>+10AT#@.!@````!.9A````.L&BWT4BW40 -M5U934/^RY#(``/^RX#(``/]Q?/]Q>.C`20``7UY;7<(0`(/L$%-5BVPD((O9 -M5E>`N\T`````=`.#Y?"+3"0D,\")1"04B_")3"00A>T/A%H!``"+^8`[`(M3 -M+(E4)!QT'_]S!/]S"/]T)"SHDBH!`(MS!(/$##/`B4,$Z<(```"+2R0S_SOY -M?!!_!3MK('8)BWL@B7PD&.L&B_V);"08A?\/A)<```"`>T\`="F`N\T````` -M="`S]COQ?!I_!3MK('83`\>+R(/A\"O(`\^%R7X$B4PD&(L"BW`8B\[_%6`R -M0P"+3"0<_]:$P`^$MP```(M[+/]T)!C_="04BP>+<`R+SO\58#)#`(O/_]:+ -M\(M#.(7`=0F+1"0RL`=1F`N)D0````=!!6_W0D%(V+D````.C4 -MW___BWPD$(M,)!2+QID!0W`14W0#S@/^B4PD%"ONB7PD$"E#(!E3)(![3P!T -M1(M#(`M#)'4\A?9T#3B#S0```'0P]L$/="L/MT-,4&H!4_]T)"CH'+D``(3` -M=`V%[702BT0D%.FQ_O__QD-0`8/(_^M0BT,LA(-6?`"`?BH`=0U74XV.N````.BNWO__Z*`Z``!?7EO""`!1,\")#"2) -M`8E!!(E!"(E!#(A!$(E!%(E!&(E!'(E!((A!)(E!*(E!+(E!,(E!-(A!.(E! -M/(E!0(E!1(E!2(A!3(E!4(E!5(E!6(E!7(A!8(A!9(O!6<-5B^QDH0````!J -M_VB!'T,`4&2))0````!6B_&#/@!T&H!^$`!T#&M&"`Q0_S;HC2```/\VZ%%I -M`0!9BTWT9(D-`````%Z+Y5W#5HOQ5S/_.7XL=B=3B]^+1BC_=`,$Z"=I`0"+ -M1BC_=`,(Z!MI`0!'C5L,65D[?BQRW5N-3E#HLDT``(U./.BJ30``C4XHZ&W_ -M__^-3A3HFDT``%^+SE[ID4T``(M$)`16B_$!1@2+3@0[3@@/AJH```"+1@Q3 -M5;U0#T0`5X7`=!H[R'864&C8-4,`5>A[GO__@\0,B\WHY9[__XM&"(M>!,'H -M`H/`(`-&"#O8=P*+V(O#P>`"@'X0`%!T0NB&:`$`B_A9A?]U!XO-Z+&>__^# -M/@!T0(M&",'@`E#_-E?H$2__^)/E]=B5X(6U["!`"+1"0$5HOQ`48$ -MBTX$.TX(#X:D````BT8,4U6]4`]$`%>%P'0:.\AV%E!HV#5#`%7HMYW__X/$ -M#(O-Z"&>__^+1@B+7@3!Z`*#P"`#1@@[V'<"B]AKPPR`?A``4'0^Z,1G`0"+ -M^%F%_W4'B\WH[YW__X,^`'0\:T8(#%#_-E?H428!`&M&"`R#Q`Q0_S;HQ1X` -M`/\VZ(EG`0!9ZQ;_-NB/9P$`B_A9687_=0>+S>BNG?__B3Y?78E>"%M>P@0` -M58OLBU4,@^P,@#H`4U97B]ET>(M%"%*)1?3H];4!`%F+31")1?B+111J(E^% -MP'0RC5#_C111#[:%P'0.9CE\0?YU -M!S/29HE40?XSTF:)%$%F.3EU`X/!`E'H1Z(!`%%1B_R)1?R-=?2-2RBEI:7H -M0@L``%]>6XOE7<(0`,S,58UL))"+17B![*````"+"(M%?%97:_D,BS"-1=!J -M4/^W6.%#`%#HVRX``(U%T&HZ4.@Z1P$`65F%P'0#Q@``:_8,C44@:E#_MECA -M0P!0Z+,N``"-12!J.E#H$DC65P7 -MPQO`@^#^0%[#S(M$)`2+#90/1`"+$(M$)`B+`&O`#/]T"`1KP@S_=`@$Z)N- -M`0!96SP -M````C840____5O]U#(OQ_W4(:&0Y0P!J4%#H.6O__X/$%(U%L&I04(V%$/__ -M_U#H0T0``/]U%(U%L(O._W404.@,`0``7HOE7<(0`%6-;"2<@>RL````5HOQ -M@WXL`'<',L#II````(-]=`"+16R)15R-10C&10@`B45@=`YJ4(U%N%#_=73H -M[$,``(M%<(/H`'0N@^@!=!"#Z`%U-(U%N%!H8#E#`.L)C46X4&A<.4,`C44( -M:E!0Z%,+``"#Q!#K$&I0:%@Y0P"-10A0Z,XK``!HH-)``&H$_W88C458_W84 -M4.BKA@$`@\04A<`/A&[___]K``S_=7S_L%CA0P#_=7CH\XP!`(/$#+`!7HUE -M9%W"%`!5B^R#[%"-1;!6:E!0_W48B_'_=13_=0CH'/___X3`=!;_=1"-1;"+ -MSO]U#%#H#````(3`#Y7`7HOE7<(4`%6+[(/L#%>+^8-_+`!W!#+`ZSIHD--` -M`&H$_W=4_W=0_W4(Z!F&`0"#Q!2%P'3@5FLP#/]U$`-W*(U]]*6EI?]U_/]U -M#.A?*P``L`%>7XOE7<(,`%;_="0(B_'H&0```(O.Z#H'``"`?F0`7G0(:@'_ -M%3@A1@#"!`"X]R%#`.A)#P$`N/A"``#H&Q`!`%-65VI<6%#_=0B+\8E%P(EU -MQ.CN00$`63/;AC_ -M_U?_=0@SR6:)"(V%).W__U#HH"H``.L.:``(``#_=0A0Z+@J``"-C?S<___H -M,L'__VH$C84D[?__B5W\4(V-_-S__^BUQ/__A,`/A+T#``"+^SD]].5#`'8< -M5XO.Z#<&``!7C4X4Z"X&``!'.SWTY4,`L!BT7P`_B)?>#K!HM%\(M]X(M-V%.#P?`#P8V-_-S__U-0Z+_&__^+1=1` -MB474/0`!```/@MC^__^#__\/A#0"``!3B\>-C?S<__^94E#HD\;__V@"`"`` -MZ%Q@`0"+^(E]Y%F%_P^$"P(``&@``"``5XV-_-S__^@JQ?__B\B*1>N)3>"$ -MP'0'T>F)3>#K.(T$30(```!0Z!U@`0")1=!9A<`/A,X!``"+3>"('#E!45!7 -MZ/$]``!7Z/=?`0"+?=!9BTW@B7WDN```$``[R'<"B\$SR6ID9HD,1XV%M/[_ -M_VCT.$,`4.@!*```:`(``@#HQ%\!`(E%\%F%P'4,5^BQ7P$`6>EM`0``@WW@ -M`(O+B].)3>R(G7S___^+^XE5V`^&X@```,=%S`T```#'1<@*````QT70"0`` -M`(M%Y(7_#X0-`P``#[=4>/YF.U7,=`IF.U7(#X7X`@``:CI99CD,>`^%[P$` -M`(MUY(/(_XE%U,=%L/@X0P#'1;0(.4,`QT6X&#E#`,=%O"0Y0P")7=S_=)VP -MZ`%?`0!0_W2=L(U.`HE%W(T,>5'H8H$!`(/$$&H@6H7`=1:+3=P#SV8Y5$X" -M=PJ+PXUY`8E%U.L#BT740X/[!'*ZBW7$,]N%P`^%L@```&ID:/0X0P"-A;3^ -M__]0Z/P[?>`/@CG___^+1?"+5=A14(V%?/___XO.4%+H./?___]U -MY.B47@$`_W7PZ(Q>`0!963E>+'884XU./.C*`@``4XU.4.C!`@``0SM>+'+H -MBT8H:##30`!J!/]V0*.4#T0`_W8\Z#6#`0!H8--``&H$_W94_W90Z".#`0"# -MQ""-C?S<___HA;W__XM-]%]>6V2)#0````"+Y5W"!`"+1>0/CKD````/MPQX -M9CO*=`9F.TW0=0-'Z^Z-%'B)7=QJ(%B+RV8Y`G8?@_ECS]__^-A1C___]J9%"-A>S]__]0Z,<] -M```#?=R+1=2#^`-U(8V%[/W__V@X.4,`4.BV70$`]]A9&L#^P%F(1F3IS/[_ -M_X/X`;A`.4,`=`6X2#E#`(V-&/___U%0C86T_O__:F10Z`X%``"#Q!#IG_[_ -M_XT$>(E%W`^W`%#H2R0``(3`#X3?````:F3_==R-A23]__]0Z,DE``"-A23] -M__]H4#E#`%#H_'\!`(E%W%E9A<`/A+`````SR6:)"(V%4/[__VID4(V%)/W_ -M_U#H#CT``&IDC86T_O__4(V%&/___U#H(24``&IDC850_O__4(V%&/___U#H -MY20``&HRC848____4(V%?/___U#H]R0``&@0TT``:@3_=@2-A1C_____-E#H -MTG\!`(/$%(7`=`QK``R+@%#A0P")1=B+1=R-C23]__\KP='X0&H@`_B+1>1: -M#[<,>&8[RG0*9CM-T`^%K/W__T?KZHM-[(M%Y`^W%'A'9H72#X2A_?__9CM5 -MP'5.@?D```$`#X.&_?__#[<$>(/H(G0E@^@Z=!R#Z!)T$X/H!'0*2(/H`74T -M:@GK#FH-ZPIJ"NL&:ESK`FHBBT7P6F:)%$A!B4WL1^E$_?__:@U89CO0="1J -M"EAF.]!T'('Y```!``^#*/W__XM%\&:)%$A!B4WLZ1C]__]1_W7PC85\____ -MB\Y0_W78Z%OT__^(G7S___^+RXE=V.O65FH!B_'HPO+__XM6!(L.BT0D"%Z) -M1)'\P@0`5E=J`8OQZ&KS__]K5@0,BSZ-="0,@\?T`_JEI:5?7L(,`%9J`(OQ -M_Q6`,$,`:@5H.#E#`%#_%80P0P"%P'0$QD9D`5[#@'ED`'0>:NS_="0(_Q5` -M(48`#0``0`!0:NS_="0,_Q4\(48`P@0`@>Q`"0``4U565_^T)%@)``"-A"2T -M````B^EH=#E#`&I04(EL)"SH\6'__X/$$(U$)&!J4%"-A"2X````4.CY.@`` -MC40D8%#H05L!`(N\)%@)```SVUF)1"04.1WTY4,`=EN^5.%#`(,^`'9%4/]V -M!(U$)&A0Z,.#`0"#Q`R%P'4L:``$``"-A"14`0``B\U0_W8$Z'WW__^$P'01 -MC80D4`$``%#_-E?_%5`A1@"+1"040X/&##L=].5#`'*JC40D%(O-4(U$)!Q0 -M_[0D8`D``.AF]?__BMB-1"0L4%>(7"0;_Q5$(48`C40D4%!7_Q5((48`BTPD -M-"M,)"R+="0X02MT)#"+P8M4)%A&B^['1"0D9````"ML)%PKPHE$)"B$VP^$ -MG0```("\)%P)````#X7.````#Z]4)!AJ9%N+PIGW^XO8BT0D7`^O1"04`UPD -M*"O+B5PD/)GW?"0D`\6)1"0@B\$K="0@F2O"B]B+QIDKPM'[B_#1_@-T)#`# -M7"0L>0(SVX7V>0(S]FKP5_\50"%&`,'H"O?0@^`"#00"``!0_W0D)/]T)$16 -M4VH`5_\55"%&`(U$)"Q05_\51"%&`(I<)!.`O"1<"0```'4UBTPD'(V$)%`! -M``!H``0``%!H@#E#`/^T)&0)``#HSO3__X3`=`^-A"10`0``4%?_%5PA1@!J -M"/\53"%&`&H%5ROH_Q4T(48`B_B)?"0B`>0$`@\0$+@<&8#T0`4?]T)`SH`P```,($`%6+[%:+ -M=0PSP%!0_W40N>@.1`!FB096_W4(Z%'T__^$P'4J_W405O]U"/\UT`Y$`/\5 -M,"%&`(7`=1/_=1!6_W4(_S74#D0`_Q4P(48`B\9>7<(,`(`]H$]$``!6B_%U -M!>@(````QD8!`8O&7L-5B^R![`0#```SP%,SVT-6B].^&P$``(B4!?S\__^( -ME`7[_?__B(05_/[__T")1?R+PB2`#[;(C002]]D;R2/.,\B+1?PST3O3=L",]*-!!(SP@/`,\(#P#/"`\`ST(O*@?$`8P``P?D( -M,\J(BZ!/1`"(#)W!740`B`R=P%U$`(@,G<-91`"(#)W`640`B`R=PU5$`(@, -MG<)51`"(#)W"440`B`R=P5%$`(3)=!4/ML$/MH0%_/[__P^VA`45_?__ZP(S -MP(@$G<-=1`"(!)W"640`B`2=P55$`(@$G(#,];!X@(SU@/2B\+!^`@/ML@/ -MML(SR(/Q!0^VA`W\_O__C8W[_?__*\B*$>L",M*(DZ!01`"$TG05#[;"#[:$ -M!?S^__\/MH0%9/W__^L",\`/MLJ(!)W";40`B`2=P6E$`(@$GK]___K`C/` -MB`2=P6U$`(@$G40`B`2- -MPW5$`(@$C<)Q1`"$TG02#[:$#?S^__\/MH0%V_W__^L",\"(!)W#;40`B`2= -MPFE$`(@$G<%E1`"(!)W`840`0X@$C<-]1`"(!(W">40`B`2-P75$`(@$C6XOE7<.#["!35HOQN````(`SR0^B5XU\)`R)!S/` -MB5\$0(E/"(E7##/2BTPD#('A____?SO()7P2)3PB)5PR+1"04 -MP>@9)`$STH@&ZP*(%HM$)#B+^BV`````=".#Z$!T$(/H0'4C:B#'1@0.```` -MZQ=J&%_'1@0,````B]KK$&H0QT8$"@```%^+VH7_="-5BVPD.(O#C4PD$(/@ -M`XO3`\C!Z@**!"M#B`21.]]RY3/278M,)#R%R741:A!2C48(4.C<$`$`@\0, -MZPV*!`J(1!8(0H/Z$'SSC40D#(O.4.A)!@``@'PD,`!U!XO.Z(<%``!?7EN# -MQ"#"$`"+5"0,BTPD!%:+="0,BP8S`HD!BT8$,T($B4$$BT8(,T((B4$(BT8, -M,T(,B4$,7L(,`(/L7%57BWPD;(OIB6PD)(7_#X2C!```P>\$@'T``(E\)&QT -M$_]T)'!7_W0D<.B0!```Z8,$``"-10AJ$%")1"0XC40D7%#HBA$!`(/$#(7_ -M#X11!```BU0D:%-6C4((B40D)(M$)'@KT(E4)#2-2`B)3"0HBW4$@\+XB\8# -MRL'@!(/`&(E,)#`#Q5!1C40D5%#H./___XM4)$P/MDPD4P^VPHL@(P>D8#[;`P>L0BPR-P&U$ -M`#,,A@0#[;`,PR%P&E$``^VPL'J"#,,A@(#[;`,U0D&(M=+#-< -M)!2*@*!01`"(1"0]B\+!Z!`/ML"+="0@B50D5(E<)%"*@*!01`"(1"0^B\/! -MZ!B)3"18BH"@4$0`B$0D/P^VPXJ`H%!$`(A$)$"+QL'H"`^VP(J`H%!$`(A$ -M)$&+P<'H$`^VP(J`H%!$`(A$)$*+PL'H&(J`H%!$`(A$)$,/ML+!Z@B*@*!0 -M1`"(1"1$B\/!Z`@/ML#!ZQ"*@*!01`"(1"1%B\;!Z!`/ML#![AB*@*!01`"( -M1"1&B\'!Z!B*@*!01`"(1"1'#[;!BH"@4$0`B$0D2`^VPHM4)#PS51B*@*!0 -M1`"(1"1)#[;#BH"@4$0`B$0D2HJ&H%!$`(A$)$N+="1`BUPD1(M$)$@S120S -M=1PS72"`?0$`B40D('04,U0D7#-T)&`S7"1D,T0D:(E$)""+1"0PBP")1"1< -MBT0D)(M(_(E,)&"+"(E,)&2+2`2#P!")3"1HBTPD*(E$)"2)4?B+5"0@B5$$ -MBU0D-(EQ_(D9@\$0@^\!B4PD*(E\)'0/A<_[__]>6VH0C40D6%#_="0XZ!X- -M`0"#Q`Q?78/$7,(,`%&+T5:+="005XM\)!B-0AB)1"0(#Q!2"(7V=&2+3"00 -MB\&#P1")3"00BTH$#Q`8B\'!X`0#1"0(20\0"&8/[\N%R7X9B\'!X`0#1"0( -M#Q``28U`\&8/.-[(A6<(,`(/L(%57B^DS_T>);"04B7PD"#E]!`^.DP```%.- -M72A6B5PD%(U#`C/VB40D&(U\)""+Z&H$`_Y;#[9%`0^V3?^*E(;`?40`#[9% -M_C*4CL!U1``RE(;`<40`#[9%`(UM!#*4AL!Y1`"(%XU_!(/K`77'BT0D&$:# -M_@1\LHM<)!2-1"0@:A!04^C]"P$`BWPD'(/$#(ML)!Q'@\,0B7PD$(E<)!0[ -M?00/C'C___]>6U]=@\0@PX/L*%-55HOIC40D%%=J(/]T)$"+=02#[@:);"08 -M4(ET)"#HK@L!`(/$##/;,_\STH7V?D4[700/CYD!```[UGTLC6PD&(ULE0"# -M_P1]&XMT)!"-#)^+10!"@\4$1XE$CAB+="04.]9\X(ML)!"#_P1U`T,S_SO6 -M?+L[700/CU0!``"ZH%%$``^V1+05BDPD&#*(H$]$`(A,)!@/MD2T%HJ`H$]$ -M`#!$)!D/MD2T%XJ`H$]$`#!$)!H/MD2T%(J`H$]$`#!$)!N*`C!$)!A"B50D -M%(/^"'0O@_X!#XZD````C4;_C50D'(E$)!`SR8I$"OPP!`I!@_D$?/.#P@2# -M;"00`77GZWZ-3"0L/MD0D -M)(U,)"S'1"00`P```(J`H$]$`#!$)"@/MD0D)8J`H$]$`#!$)"D/MD0D)HJ` -MH$]$`#!$)"H/MD0D)XJ`H$]$`#!$)"MJ!%J*0?PP`4&#Z@%U]8-L)!`!=>LS -MTH7V?C\[701_/3O6?2J-1"08C020B40D$(/_!'T=BP"-#)^)1(T80HM$)!"# -MP`1'B40D$#O6?.&#_P1U`T,S_SO6?,$[702+5"04#XZQ_O__7UY=6X/$*,($ -M`%:+\6BT-4,`QH8!`0```.@9`@``B\9>PU:+\8,^`'0(_S;_%8@P0P`SP(D& -MB48(B48,7L/I;@```%6+[('L``(``(V%`/___U-6OH````!64.AD````BTT( -MC84`_O__5E#H5````(V%`/[__U"-A0#___]0Z.5*`0!9B]B-A0#___]9]]M6 -M&MM0_L/HZ`$``%:-A0#^__]0Z-L!``!>BL-;B^5=P@0`:``!``!1QH$``0`` -M`.B_`0``PX"Y``$```!T)%:+="0(5XM\)!!J`%=6:(````!1Z%4````SP&:) -M1'[^7U[K"8M$)`0SR6:)",((`%:+\8!^!`!U,VB<.4,`Z/\4``")!H7`=!]H -MM#E#`%#_%8PP0P!HR#E#`/\VB48(_Q6,,$,`B48,QD8$`5[#58OLBT4,5HMU -M%%>+^3O&<@*+Q@/`4/]U"/]U$.BC"`$`#[:'`0$``(/$#%#_=1B-!#90_W40 -MZ`8```!?7EW"%`!5B^Q6BS7(@40`A?9U$+G`@40`Z&G___^+-+?"0,,\"+\68Y!W47:``!``!05HB&``$` -M`.A'!@$`@\0,ZR!J`6B`````5E?&A@`!```!Z,!(`0!90(O.4%?HOO[__U]> -MP@0`BT0D!(7`=!&+3"0(A8):,\W!S@(# -MR@/!B40D*(M$)"#_,.AD<@$`BTPD)(M4)"S!P@6!PIEY@EJ)`0/0BT0D)(O. -M,\LC3"0HP4PD*`(SR_]P!`/*`^GH,'(!`(M,)"B+U8-$)"@4P<(%B4$$!9EY -M@EH#T(O.BT0D)#-,)"R#P`4C3"0PP4PD,`(SSHE$)"0#RHT$AP/9_S")1"0\ -MZ.IQ`0"+3"0\B].#Q!3!P@6)`8M,)!PS3"0@`]"+1"0H(\TS3"0<@<:9>8): -M`\K!S0(#\8-\)!0/#X73_O__BU8):`\'!S@*) -M1"08B\C1PHO&,\/!P04C1"00@<&9>8):`\J)5PB+5RPSPS-7%`/!,U<,`\6+ -M;"00B\@S%XE$)!R+QL'-`C/%B6PD$(ML)!@CQ='",\;!P04%F7F"6@/*B5<, -M`\$#P\'-`FH16HE$)!2);"08B50D*(U"!8O8B40D,(U*^XO"@^$/C6H#@^`/ -M@^4/@^,/B6PD+&H/BQ2/,Q2',Q2?,Q2OBT0D%#-$)!R+3"08T<*)%*^+;"0@ -M,\7!P04%H>O9;@/*P -M(\8CSB/N(]Z+="0DB6PD-&H/BQ2.,Q2&,Q2>,Q2NBT0D%#-$)!R+3"08T<*) -M%*Z+;"0@,\4#PL'!!0/'P#P`*#Y@^#X`^+%(J+3"0D,Q2!,Q29,Q2QT<*)%)F+3"00BUPD(,'!!8'! -MUL%BRHO#,T0D'#-$)!0#PL'+`@-$)!@#P8E<)""+7"0DB40D&(M$)"B-2/B# -MP/Z#X`^#X0^+%(LS%(,S%+N+1"0TBTPD&,'!!8'!UL%BRC,4@]'"B12[BWPD -M((O',T0D$#-$)!3!3"00`@/"`T0D'`/!B40D'(M$)"B-2/F#X0](@^`/BQ2+ -M,Q2#B\75N#Q"C"$`"#[$135597BWPD6&HX6XMW&(MO&(/F/XM' -M'`^DZ`/!Y0/&1#X@@$:)1"00._-T2G8<:D!9._%S$RO.C4<@40/&:@!0Z%3] -M``"#Q`PS]H7V=1%J`8U'(%"-1"0<4%?H.??__RO>C4<@4P/&:@!0Z"K]``"+ -M1"0<@\0,4.B!:@$`58E'6.AX:@$`65F)1UR-1R!J`5"-1"0<4%?H_?;__XM, -M)%R+]VH%*_%:BP0.B0&-202#Z@%U\U?H"@```%]>75N#Q$3""`"+1"0$@V`8 -M`(-@'`#'``$C16?'0`2)J\WOQT`(_MRZF,=`#'94,A#'0!#PX=+#P@0`@^Q` -M4XM<)%!65XM\)%"+3QB#X3\!7QB#5QP`C009@_@_=E55:D!>*_&-1R!6_W0D -M7`/!4.C,_0``@\0,C4<@:@%0C40D&%!7Z%?V__^-;C_K'8M$)%B#P,%J``/% -M4(U$)!A05^@[]O__@\9`@\5`.^MRWS/)7>L",_8[WG88BT0D5"O>`\934(U' -M(`/!4.AR_0``@\0,7UY;@\1`P@P`@^Q(4U6+;"145HMT)&!7BTT8:C]?(\\! -M=1B#51P`C00Q.\=V>FI`6RO9C44@4_]T)&0#P5#H+/T``(/$#(U%(&H!4(U$ -M)"!05>BW]?__C4,_.\9S1HM$)&`K^(E\)!2-%`.)5"00:@!2C40D(%!5Z)'U -M__^+5"00C70D&(M$)!2+^FH0@\)`@\-`6?.EBW0D9`/"B50D$#O&L" -M,]L[\W88BT0D8"OS`\-64(U%(`/!4.BL_```@\0,7UY=6X/$2,(,`%%35597 -MBWPD&&HX6XMW((MO((/F/XM')`^DZ`/!Y0/&1#XH@$:)1"00._-T/W8<:D!9 -M._%S$RO.C4[QT`(!;P@0`4XM<)!!6BW0D -M#%>+?B"#YS\!7B"#5B0`A=MT.55J0%TK[SO==P*+ZU7_="06\(,`('L'`$``%-5 -M5E>+O"0P`0``,_:-7RC_,^CT9@$`B42T,(U;!$99@_X0+S3/P]]$C -M3"08B\7!R`8S\(O"(\6+;"0@,\B+1"08`_&)5"08`[-0.D,`B]<#=!PL@\,$ -M`W0D)(E$)"0#[L'*#8O'P<`*,]"+Q\'(`C/0BT0D%(O((T0D$#-,)!`CSS/( -MBT0D$`/1B7PD$(M,)!2)3"0@B40D%(T\,H'[``$```^":/___XE\)!R+O"0P -M`0``BTPD'`$/BTPD$`%/!(O(`4\(BTPD(`%/#(M,)"@!3Q2+3"08`4\8`6\0 -MBTPD)`%/'%]>75N!Q!P!``#"!`!5B^R+30R+10@Y311_#'P%.440#H2R'___]UY(M=X%/_=0CH[````.L#BUT(BWT,5E=3Z`48``"-3>#H+1?_ -M_UN%]G0',\!FB41W_HM-]%]>9(D-`````(OE7<(0`%%6BW0D#%?K`X/&`@^W -M!E#H!`$``(3`=?`/MSYFA?]U!S/`Z8@```!358ML)!PSVXK#:B*(1"076H3` -M=10/M\=0Z-,```"$P'57BD0D$VHB6F8[^G4I9CE6`G48A>UT#XM$)"!(.]AS -M!F:)5%T`0X/&`NL>A,`/E,"(1"03ZQ>%[703BT0D($@[V',&9HE\70!#BD0D -M$X/&`@^W/F:%_W68A>UT!S/`9HE$70!=B\9;7UY9P@P`5E?_="0,Z(PY`0"+ -M?"080%D[^'8"B_B+="005U;_="04_Q4L(48`QD0^_P!?7L(,`(M$)`2#^$%\ -M!8/X6GX(@\"?@_@9=P4SP$#K`C/`P@0`BT0D!(/`T&H)63O(&\!`P@0`@WPD -M!"!T"X-\)`0)=`0SP.L#,\!`P@0`9HM$)`1F@_AI=05J25CK"0^WP%#HN!H` -M`,($`(/L=(M4)'PSR5.+7"1\0556,_:)3"0,5XO^.]9_%'P$.]YS#O?;B^F) -M;"04$];WVNL&B^Z)="04*:PDE````(NL))0````[S7,F5FH*4E/H?.H``(/! -M,(E<)!QFB4Q\((O8BTPD$$=!"\*)3"00==:+;"04A>UT"6HM6&:)1'P@1XN4 -M))````"%_W03C4Q\'F:+`8U)_F:)!')&._=R\3/`9HD$>E]>75N#Q'3"$`!6 -MBW0D"%;H1C@!`%F+3"00.\AV#RO(`\91_W0D$%#H!````%["#`"+3"0,AP@P`BTPD#(7) -M="J+1"0$5H/I`70:BU0D#"O0#[PSR6:)"%[" -M#`!15HOQ,\")="0$B0:)1@2)1@B)1@R(1A#HN````(O&7EG#4U97BWPD$(O9 -MA?]U!;^T-4,`BW,$5^C@-@$`64"+RU#H_!7__XL#5XT$<%#H'5D!`/]#&%E9 -M7UY;P@0`58OL48U%_%#H!P```(M%_(OE7<-6B_&+3A0[3@1R#XM$)`B%P'0# -M@R``,L#K'HL&5XT\2%?HA38!`$`!1A2+1"00687`=`*).+`!7U["!`!5B^Q1 -MC47\4.BW____A,!T$/]U#/]U_/]U".C^_O__L`&+Y5W""`!6B_ A0`Z)$[ -M__^#9A@`@V9<`%[#@V$4`,-5B^R#[!!35HUU\#/)N````(`/HHD&B5X$B4X( -MB58,BW7P:@>!YO___W]8._!R'S/)#Z)7C7WPB0>)7P2)3PB)5PSV1?0@7W0% -M:@58ZU&#_@%R2C/`C77P0#/)#Z*)!HE>!(E."(E6#/=%^```"`!T!&H$Z];W -M1?@``@``=`1J`^O)]T7\````!'0$:@+KO/=%_`````)T!3/`0.L",\!>6XOE -M7<-5B^R#[!!3,]MFQT7T``6-1?B)7?!04U-34U-3:"`"``!J(&H"C47P4/\5 -M&"!&`(O(B4W\AB^5=P@0`N,BS -M``#H?.(``%-55E=H8#M#`#+__Q6`,$,`B_"%]G1D:'0[0P!6_Q6,,$,`BIPD -MW+,``(OXA?]T&`^VR_?9&\F!X;0U0P!1B\__%6`R0P#_UVB(.T,`5O\5C#!# -M`(OPA?9T(3/)A-L/E,%)@>$`^/__@<$`$```48O._Q5@,D,`_]:W`:&`X$,` -M@\W_QT0D%*0[0P"^``@``,=$)!B\.T,`QT0D'-@[0P"`.'C'1"0@\#M#`,=$ -M)"0(/$,`QT0D*"`\0P#'1"0L.#Q#`,=$)#!0/$,`QT0D-&P\0P#'1"0X?#Q# -M`,=$)#R0/$,`QT0D0*@\0P#'1"1$P#Q#`,=$)$C8/$,`QT0D3/`\0P#'1"10 -M!#U#`,=$)%0$)(0```!`/D,`QX0DB````%@^0P#'A"2,````<#Y# -M`,>$))````",/D,`QX0DE````*0^0P#'A"28````O#Y#`,>$))P```#@/D,` -MQX0DH````/@^0P#'A"2D````$#]#`,>$)*@````@/T,`QX0DK````#P_0P#' -MA"2P````5#]#`,>$)+0```!P/T,`QX0DN````(@_0P#'A"2\````I#]#`,>$ -M),````"T/T,`QX0DQ````,P_0P#'A"3(````Y#]#`,>$),P```#X/T,`QX0D -MT````!!`0P#'A"34````*$!#`,>$)-@```!`0$,`QX0DW````%A`0P#'A"3@ -M````<$!#`,>$).0```",0$,`QX0DZ````*A`0P#'A"3L````Q$!#`,>$)/`` -M``#<0$,`QX0D]````/A`0P#'A"3X````$$%#`,>$)/P````P04,`QX0D``$` -M`$1!0P#'A"0$`0``7$%#``^$S````%#H-&T!`(OX687_#X2[````5HV$)!03 -M``!0:@#_%7PP0P`SP%!0:@-0:@%H````@(V$)"@3``!0_Q4D,$,`B_`[]71\ -M:@!J`%=6_Q54,$,`.\=U;&H`C40D%%!H_G\``(V$).0S``!05O\52#!#`(7` -M=$V+1"00T>@SR6@$`0``9HF,1-PS``"-A"0,`0``4(V$).`S``!0ZQN-A"0( -M`0``4.@F_/__:`0!``"-A"0,`0``4%?H9O?__XOXA?]UVE;_%1@P0P"^``@` -M`%:-A"04`P``4&H`_Q5\,$,`5HV$)!0#``!0Z`NW__]0C80DX",``%#HI?G_ -M_S/_,_;H4*?__ST`!@``<@O_=+04Z+O[___K`C/`AL$BWRT%(3_=38S]F@`"```_W2T.(V$ -M)!@#``!0Z.*V__^-A"00`P``4/\57#!#`#O%=0A&@_XU+\6I`7XD&.\=V -M`HD^,^TSVT4Y'G4"B2Z)G@0!```Y/G8"B3Z-AB`#``"(GA0#``!0_Q7(,$,` -M4U=34_\5[#!#`%-555.)AA@#``#_%>@P0P")AAP#```YGA@#``!T!(7`=1MH -MN$)#`+]0#T0`5^A89/__65EJ`HO/Z$AD__]?B9X,`P``B\:)GA`#``")G@@! -M``!>75O"!`!5B^QDH0````!J_VB!'T,`4&2))0````!35E>+\>BY`@``,__& -MAA0#```!5VI`_[88`P``_Q7@,$,`.;X$`0``=AZ-7@3_,^BG````_S/_%1@P -M0P!'C5L$.[X$`0``0P0P"#^/]U)U;_ -M%0`P0P!0:O]H4$)#`+Y0#T0`5N@48___@\00B\YJ`N@#8___7L($`%%35HOQ -M,]LY'G9P55>-?@2-1"004&H`5FB@#$$`:````0!J`/\5P#!#`(OHA>UU)V@H -M0D,`:%`/1`#HQ6+__UE9N5`/1`#H4V3__VH"N5`/1`#HJ&+__XDO_X8$`0`` -MH=B!1`"%P'0)4/\W_Q7$,$,`0X/'!#L>-OB`#``#_=?R+3?C_ -M%6`R0P#_5?A7_Q7,,$,`@ZX(`0```74,_[8<`P``_Q78,$,`5_\5T#!#`(U% -M^(O.4.@S____A,!UOU]>B^5=PU:+\8.^"`$```!T*_^V'`,``/\5W#!#`&H` -M_[8(`0``_[88`P``_Q7@,$,`_[8<`P``Z.']__]>PXM$)`0!`8M$)`@1003" -M"`"#[$A35597B_DSVU-J9/]W!/\WZ#[>``")1"08B50D'.AFH?__/0`&``!S -M$HU$)!!0C40D'%#_%0`Q0P#K:XU$)#A0C40D'%#_%0@Q0P"-1"1(4(U$)#Q0 -M4_\5]#!#`(U$)!!0C40D3%#_%?PP0P"-1"0@4(U$)#Q0_Q7\,$,`BTPD%#/` -M`TPD'"O#&TPD)"M$)"`;RP-$)!`3RP-$)!B)1"00$\N)3"04C40D*%"-1"04 -M4/\5"#%#`(MT)%PSVP^W1"0P0P^W3"0N#[=L)"H/MU0D*(E&#`^W1"0RB480 -M#[=$)#2)1A0/MT0D+(E&'(U!_XD6B6X$B4X(B48@.^MV(FH$NH3@0P!9@_DP -M=Q"+`H/!!`%&((/"!$,[W7+K#[=4)"B#_0)V#5+H/P```(3`=`/_1B!J`&@` -MRIH[_W<$_S?H@-T``%^)1AA>75N#Q$C"!`!J`&ID_W$$_S'H]=P``(M,)`2) -M`8E1!,($`/9$)`0#=2.+1"0$:F296??YA=)U$(M$)`2YD`$``)GW^872=04S -MP$#K`C/`P@0`58OL@^P85HU%Z(OQ4/\5\#!#`(U%^%"-1>A0_Q7\,$,`:@!J -M9/]U_/]U^.AJVP``B0:)5@1>B^5=PU6+[(/L)(M5"(O"@^`?@V7T``/`B47P -MB\+!Z`6#X#^)1>R+PL'H"X/@'XE%Z(O"P>@0@^`?B47DB\+!Z!6#X`_!ZAF) -M1>"!PKP'``"-1=R)5=Q0Z`8```"+Y5W"!`!5B^R#[$A3BUT(5E>+\6:+`V:) -M1=AFBT,$9HE%VF:+0PAFB47>9HM##&:)1>!FBT,09HE%XF:+0Q1FB47D,\!F -MB47F9HE%W(U%\%"-1=A0_Q7\,$,`A<`/A(H```#H]9[__S/_/0`&``!S%HU% -M^%"-1?!0_Q4$,4,`BT7\BTWXZU6-1.N^_S9HA0```.C@SO__4.N`_S9H!`(``.OO_W8$:(0```#KG/]V!&B#```` -MZY+_=@C_=@1HT@```.BPSO__4/\VZ!2?``"#Q!#IK0$``/]V!&IYZ6C_____ -M=@1HW````.E;_____S9HW0```.N;@_@X#X^Z````#X2M````@^@7@_@+#X=R -M`0``_R2%%Q1!`&C>````Z4K___]HX0```.E`____:+0```#H0,[__U#_-NDV -M____:FGK[VIJZ^O_=@1J:.GX_O__:&\$``#KVFAP!```Z]/_=@1H<00``.G= -M_O___W8$:G'IT_[___]V!&C(````Z/3-__]0C84`_O__:``!``!0Z,4L____ -M=@B-A0#^__]0:`Q#0P#_-N@XG@``@\0@Z=$```!J9^EX____@^@Y=$"#Z`%T -M-(/H`70B@^@)=!.#Z`$/A:T```!HA@```.E1____:$,#``#I1_____]V!&@& -M!```Z5'^__]J;^DS____:(P```#I*?___VA6!```Z1____\]@````'5JZ)"\ -M``"#?@0`="3_=@1HR@```.A%S?__4(V%`.K__V@`"@``4.@6+/__@\00ZQQH -M``H``&C)````Z!_-__]0C84`ZO__4.B7[?__:@!HE@```.@&S?__4(V%`.K_ -M_U#_-4R$1`#HW(T``%Z+Y5W#D%X100!($4$`;!%!`'D100"($4$`CQ%!`)81 -M00"@$4$`LA%!`+D100#`$4$`SQ%!`-@100#B$4$`N1-!`+D300"Y$T$`N1-! -M`.P100"Y$T$`#!)!`!8200!.$D$`6!)!`&(200!T$D$`>!)!`'P200"&$D$` -MC1)!`)0200"Y$T$`H1)!`*L200#IO\$``%6+[+@`%@``Z-?1``!35O]U"&B# -M````Z$3,__]0O@`)``"-A0#J__]64.@4*___@\00C84`_/__N5`/1`!H``(` -M`%#H%%K__X3`="96:!Q#0P"-A0#J__]0Z%_L__]6C84`_/__4(V%`.K__U#H -M2^S___\5`#!#`&HU:)8```"+\.C:R___4(V%`.K__U#_-4R$1`#HL(P``(/X -M!%8/E,/_%00P0P!>BL-;B^5=P@@`N``0``#H*M$``%-55HNT)!`0``!7:@)= -MBX8P80``.\5U"#/`0.GV````@+Z(80````^%VP```(/X`0^$T@```(N<)!@0 -M``"-1"00OP`(``!74U#HW>O___^T)"P0``"-1"04_[0D+!```/^T)"P0``#_ -MM"0L$```5U#HS<```(OXA?]T!#O]=193Z`6/__\[_74,QX8P80```0```.M_ -M@_\#=0N)KC!A``#I<____X/_!'5:C40D$%#HSZC__XN\)!P0``"-3"005SO! -MB\%04W4'Z"RI___K!>A7Z___4^B3C?__A,!T-O^T)"P0``#_M"0L$```_[0D -M+!```/^T)"P0``!74U;H]/[__^L2B\?K#O^T)!@0``#H=H[__S/`7UY=6X'$ -M`!```,(<`%6+[/]U)/]U(/]U'/]U&/]U%/]U$/]U#/]U".B.P```7<(@`/]T -M)`S_="0,:@#_="00Z*K```#"#`#IG)@``*!0A$0`PS+`PX!\)`0`_W0D"`^5 -MP(T$A50```!0Z$W!``#""`#IGL$``%-6BW0D$#/`5XM\)!BS`5=6:O__="0< -M9HD&4%#_%10Q0P#WV!K`(L.%_W0',\EFB4Q^_E]>6\(,`%6+[(/L%%97C47L -M,_905HOY_Q4,,4,`@WWL`0^7P(B'``$``%;_%1`Q0P"%P`^5P(@$/D:!_@`! -M``!RZ%]>B^5=PU6+[%8S]CEU$'8HBU4(5XM]#"OZ#[9*`0^V`L'A"`/!9HD$ -M%V:%P'0)1H/"`CMU$'+B7XM%#%Y=P@P`BT0D#%-55HMT)!"-:/]7BWPD&+,! -MZ3`!```/MM!&@?J`````#X+6````B\*#X.`]P````'4BB@Z*P23`/(`/A1(! -M``"#XA\/OL&#X#_!X@8+T$;IJ````(O"@^#P/>````!U.XH.BL$DP#R`#X7D -M````BF8!BL0DP#R`#X75````#[[)@^(/@^$_P>(&"\H/OL3!X0:#X#\+R(/& -M`NM?B\*#X/@]\`````^%IP```(H.BL$DP#R`#X69````BF8!BL0DP#R`#X6* -M````BGX"BL#X3_!X@8+R@^^Q,'A!H/@/PO(#[['P>$& -M@^`_"\B#Q@.+T8/M`7A3@?K__P``=C>#[0%X1H'Z__\0`'8$,MOK+(V"``#_ -M_X'B_P,``,'H"H'J`"0``"T`*```9HD'9HE7`H/'!.L&9HD7@\<"B@:$P`^% -MQO[__^L",MLSP&:)!XK#7UY=6\(,`%-6BW0D$#/`5XM\)!BS`5!05U9J__]T -M)"2(!E!0_Q48,4,`]]@:P"+#A?]T!<9$/O\`7UY;P@P`5HMT)`Q7,_^+SSE, -M)!1V'XM4)`R*`H@$3HI"`8A$3@%F.3IT"D&#P@([3"04P@P`BTPD -M"%-6BW0D%%>+?"003@^W!V:%P`^$[````(/N`0^(XP````^WT(/'`H'Z@``` -M`',%B!%!Z]B!^@`(``!S'(/N`7@7B\*`XC_!Z`:`RH`,P(@!B%$!@\$"Z[2- -M@@`H__\]_P,``'":+PL'H#`S@B`&+PL'H!H#B/R0_@,J`#("(00&( -M40*#P0/I3____X'Z```@``^#0____X/N`P^(.O___XO"P>@2#/"(`8O"P>@, -M)#\,@(A!`8O"P>@&@.(_)#^`RH`,@(A!`HA1`X/!!.D(____7U[&`0!;P@P` -M45-5BVPD$,9$)`L`9H-]`"UU"(/%`L9$)`L!#[=%`#/;:C!:,\EF.\)R-E97 -M9H/X.7/__ -M_P^W1"0$4/\5*"%&`,($`&K__W0D#&K__W0D$&@!$```:``$``#_%:@P0P"# -MZ`+""`!5B^Q65_]U".B0'0$`BW400%D[QG,._W4(Z'\=`0!9C7@!ZP*+_O]U -M#.AO'0$`0%D[QG,,_W4,Z&$=`0!9C7`!5O]U#%?_=0AH`1```&@`!```_Q6H -M,$,`7X/H`EY=P@P`5E>_@````(OQ5VH`5NB7V@``5XV&@````&H`4.B(V@`` -M@\08B\9?7L-1,\")#"2)@8Q*``")@40&``")@4P&``")@4@&``"+P5G#N%+\3/_1XEU\%>-3@3HN8W__S/;B5W\B5XDB5XHB5XLB5XP -MB%XTB5XXB5X\B5Y`B5Y$B%Y(B5Y,B5Y0B5Y4B5Y8B%Y-CHCF``#&1?P&Z%*-__^+10B+ -MSHF>F.8``(F>G.8``(F>H.8``(F>I.8``(B>J.8``(F>K.8``(F>L.8``(F> -MM.8``(F>N.8``(B>O.8``(F>P.8``(F>Q.8``(F>R.8``(F>S.8``(B>T.8` -M`%.)!HF>0$L``(B>1$P``&:)GE!,``"(GE),``")?AR)7A2)7B")7AB)GMCF -M``")GMSF``#H0BP``(M-](O&7UY;9(D-`````(OE7<($`,S,S,S,S,S,S,S, -M45:+\6H`B70D"(U.!.B(C/__@Z;42@```(O&7EG#S,Q6_W0D"(OQZ"0```#' -M!G150P"+QE["!`"#800`B\P@`QT$$.$-#`,`"4/\VZ%;2____-N@:&P$` -M68M-]&2)#0````!>B^5=PU6+[&2A`````&K_:($?0P!09(DE`````%:+\8,^ -M`'0<@'X0`'0.BT8(P>`$4/\VZ`O2____-NC/&@$`68M-]&2)#0````!>B^5= -MP^EK)@``@<&,2@``Z9`J``!6:@"+\>A;$@``BX9`2P``AZ?2*___,S,S,5HOQBX;42@``AZ=.*__]6BW0D"#NQ@````',$BP'K(3/2C8&$````0CLP<@U" -M@\`$@_H@L)BP21*T21?`/&7L($`%6+[/9%"`)DH0````!J_VB!'T,` -M4&2))0````!65XOQ=#%HL!Y!`(U^_/\W:.1*``!6Z(K'``#V10@!=!)I#^1* -M``"#P0115^A#S0``65F+Q^L:Z%/____V10@!=`UHY$H``%;HU\4``%E9B\:+ -M3?1?9(D-`````%Z+Y5W"!`#,S,S,S,S,S,S,S,Q6B_&-1@3'!FA50P!0Z$4! -M`0#V1"0,`5ET"FH,5NB3Q0``65F+QE["!`"+1"0$5HOQ`48$BTX$.TX(#X:J -M````BT8,4U6]4`]$`%>%P'0:.\AV%E!HV#5#`%7H>4[__X/$#(O-Z.-.__^+ -M1@B+7@3!Z`*#P"`#1@@[V'<"B]B+P\'@!(!^$`!0=$+HA!@!`(OX687_=0>+ -MS>BO3O__@SX`=$"+1@C!X`10_S97Z`_7``"+1@B#Q`S!X`10_S;H@<____\V -MZ$48`0!9ZQ;_-NA+&`$`B_A9687_=0>+S>AJ3O__B3Y?78E>"%M>P@0`4XO9 -M,\E6O@`@``!7.7-0+0``,\DYR)>P2).SE%$'<#BT404/]U#/^VE.8``.@GU@``C89DY@``@\0,B\B) -M1=CHW:3___9%"(!T'%/H1:7__XO8B5WPA=MU"E>+SNC[#@``ZPQ+ZP:+GM3F -M``")7?"+AISF``")1=P[V'=&.Y[$Y@``=SYJ.(F>U.8``.B)PP``B]B)7>!9 -MA=MT"(E[-(E[$.L%B]^)?>"+3?`[3=QU>H'Y`"```'8?:CA3Z(W#``!963+` -MBTWT7UY;9(D-`````(OE7<(,`(V.F.8``&H!Z-RM__]J..@OPP``B]")5>A9 -MA=)T"(EZ-(EZ$.L%B]>)?>B+CISF``"+AICF``!7B52(_(V.P.8``(N&G.8` -M`$B)0PSHS+K__^L/BX:8Y@``BP2(B47HB4L,B\>)?>0YAK#F``!V0HV.K.8` -M`(O?BQ&+R"O+BP2"B02*C8ZLY@``BQ&+1>0Y/()U`4.%VW0#B3R"0(E%Y#N& -ML.8``'+0B5WDA=N+7>!U(H&^L.8````@```/AR#___^-CJSF``!J`>@;K?__ -M,\!`ZP.+1>2+CK#F```KR(N&K.8``(DR)0R1T1HO.Z(.&___!Z`F+SFH'B47@Z%V&__^+5>"+ -MSXE-Y(U[%#/`0-/@A<)T#E;H^:+__XM-Y(M5X(D'08/'!(E-Y(/Y!W+=,_^+ -M1=PY1?`/A9(```!6Z-&B__^+\('^```!``^#\/W__X7V#X3H_?__BT7LBP@# -MSCM-$`^'V/W__U:-3<3HE>_^_XE]_(7V="R+3>R+`8/``ST`@```+^8"_J@````!U -M(L:'J@```/_H3@<``(N$G[@```"%P'0+BPB)C)^X````ZVZ-2RZ+PXT,CT"- -M202#^"9T)8,Y`'3R5HNTA[@```!34%:+#HF,A[@```"+S^BK(0``B\9>ZSC^ -MCZH````/MD0[!(N/7`$``&O0#(O!*X=0`0``.\)^%BO**9=4`0``BX=4`0`` -MB8]<`0``ZP(SP%];P@0`45%355:+="0@5XM\)!R)?"04BA:*PH3`#X3<```` -M/`)V9CP##X7,````@WPD(`.+J5A,``!V2FH"6VH$C5@'H"ZW4L#[9* -M`0^V`L'A"`/(B\7!Z`+!X0@KR`^V0O\#R(O!B$K_P>@(P>D0B`*(2@$#U@/N -MC0P3.TPD('+!B\?IK@```(N96$P``(#Z`FH$#Y3!@,'H7HA,)!,Y="0@=DR+ -MUHH'1T-"/.AT!#K!=3>+#XOK@>7___\`A!B-@0````&)!^L. -MC8$```#_A75M96<(,`%97B_F-MXQ*``"+SNB&(0``:@&+SN@A(0`` -M:@*+S^AJ(```7U[#:``!``"-@6P&``#&@6P*```!:@!0Z,C.``"#Q`S#55>+ -M?"04B^F%_W0C4XM<)!16BW0D%"O>C00SB\U0Z'[W__^*`(@&1H/O`77K7EM? -M7<(,`%%3BUPD%%6+;"005XL[*WPD&(E,)`R%[70R5HO'(T0D)%#H1O?___\S -MBTPD%(OPZ#GW__^*#D>("(L#BTPD$$`C1"0DB0.#[0%UT%Y?75M9PA``@>P( -M`0``4XO953/M5HN#4`8``$6`O"08`0```(NS1`8``%>+4`*-?"08=0Z#?@@` -MC7PD'(E$)!AT9(N,)"`!``"%R70%BW8(ZR&+=@AF.2YT%HN#4`8``(M.!(H` -MZP.#P08X`77YZP.-3@(Y40)U'(V$)!@!```[^`^#I@```(D/@\<$@WX(`'7` -MZP.+<0*-1"08._AU!XO&Z8D````/MRZ-0@&*"HE$)!(SP$"(3"009COH=$,[ -ML]Q+``!V9XM&!.L#@\`&.`AU^0^V4`$/MTX"2BO-*\J-+!([Z7<+:\(%.\@; -MP/?8ZPQKP0,ST@/)2`/%]_'^P.L#BD8#B$0D$8/O!(U$)!!0B\[_-U/HD58` -M`(OPA?9T#8U$)!@[^'7@Z7+___\SP%]>75N!Q`@!``#""`!55HOQBXY$!@`` -MBY;<2P``.\IV)(N&Y$L``#O(=QIF@SD!=!HY401V#SE!!'<*5NBP5P``A,!U -M#(/(_UY=PU;H;%8``+T`@```Z9P```"+CG!*``"+EGA*``"-!!$SP3T````! -M$H```C! -MX0@+P<&F<$H```B)AG1*``#KJHN&1`8``/^&7`8``(M("(F.1`8``#N.W$L` -M``^&<____SN.Y$L```^'9____P^W`3N&5`8``'3(5NA16```A,`/A$[___^+ -MEGA*``"+PHN.?$H```^OP0&&<$H``(N&@$H``"O!#Z_"B89X2@``@[Y0!@`` -M``^$+____X.^7`8```"+AE`&``!7#[8X=1F+0`([AMQ+``!V#HF&3`8``(F& -M1`8``.L7B\[H/5(``("^;`H```!U!XO.Z,7\__^+CG!*``"+EGA*``"-!!$S -MP3T````!$H```C!X0@+P<&F<$H```B)AG1*``#KJHO'7^E[_O__45-55HMT)!17B_F+ -MSNB$`0``B]C!Z`4D`8E$)!!T"XO.Z'`!``"+Z.L1@[^,2@```'4$,L#K9XML -M)!#VPT!T#8O.Z$\!``"+3"0+^0^V;#XI#[9$ -M/BH[Z'4&BT0D$.LU4XU&`5#HT/C__XO8A=MT(FO.#(MT)!115E/H9,L``(N$ -MK[@```"#Q`R)!HFTK[@```"+PUM?7EW""`!6BW0D"(V1@````#/`.S)R#4"# -MP@2#^"!R\S/`ZQ.+A(&`````*\8[1"0,<@2+1"0,7L((`%:+\8M.!('YXG\` -M`'X6B\[HZAT``(M.!('Y`(```'P$,\!>PXM&$`^V!`A!B4X$7L.#[`Q35HOQ -M,]M7BX:P````.X:T````=`*(&(U$)`R+^U6)1"08C9:X````B40D%+W__P`` -MZRN+"HL!B0*-1"00B4$(BT0D%(E!!(M$)!2)2`B)3"049HDI#[9$/@1FB4$" -M.1IUT4>#P@2#_R9\\XM4)!2-1"00.]!T2^LL#[=/`@^W0@(#R('Y```!`',H -MBT\(BT<$B4$$BT\$BT<(B4$(9HM'`F8!0@(/MT(":_@,`_IF.2]TQHM2!(U$ -M)!`[T'7GBU0D%%WIB0```(M*"(M"!(E!!(M*!(M""(E!"`^W3P*!^8````!V -M*(V1?____\'J!T)KPH`#R(N&3`$``(D'B;Y,`0``@<<`!@``@^H!=>)1"04Z&<6``"+;"0H,]LS_X7M='!6@_L@@%*_`[ -M="00<^3K1U9J`%#HJ<<``(M,)"0#_HM$)""#Q`R)!)F)O)F`````0SO] -M7UU;@\08P@0`._US\HU,)!SHCN[__V@$MT,`C40D(.L2C4PD'.AZ[O__:`2W -M0P"-1"0@4.@KZ@``S(/L%%.+7"0<5XOYA=MU"KE0#T0`Z"5`__^X```$`#O8 -MA^Q@`` -M@\0,@'PD#P!T0H._V.8```%R.8U+_S/;B4PD$$-6BW=\BY?8Y@``*_.+AT!+ -M``!*(]8CSD.*!`*(!"F+3"04.Y_8Y@``=M>+7"0H7HN'0$L``(7`=`=0Z-`( -M`0!9B:]`2P``C4/_B9_8Y@``B8?A?7L($ -M`%-6,]N+\5+^XF>Q.8``(F>U.8``#F>G.8``'8;BX:8Y@``:CC_ -M-+CHOK0``$=963N^G.8``'+EB9Z6\($`+B>(D,`Z(&T``!145-65XOY -M,]LY7R!U&;X`!$``5N@'MP``5E-0B4<@Z/G$``"#Q!`Y7Q@/A;L```"+=QPS -MR0/VNN1*``"+QHEU\/?B#Y#!]]D+R#/`@\$$#Y+`]]@+P5#HQ+8``%F)1>R) -M7?R%P'0;:+`>00!HT!Q!`%:-6`2),&CD2@``4^@(M0``@TW\_VG&Y$H``(E? -M&%!J`%/HA<0``(/$#(7V=$PSP(E%\(M?&`/8@[O42@```'4L:``,`P#'@]Q* -M````00``Z`H'`0")@]1*``!9A+V3/`:)@```!0B40D'(V#N``` -M`(E<)!A0Z/W#``"+JZP```"#Q`R)JU`!``"+&XO#F8/B!P/",]+!^`-J#%GW -M\3/2:_A4:@PKWXO#]_&-#"LSTD!K\`R+1"04B]@#]8F+7`$``(FP5`$``(FP -ML````(O'7_?W:@1KP`Q:4ED#QHF#M````#/`0(A$`P-`@^H!=?9`B$0+!$&# -MP`*#^0A\\T#K"(A$"P1!@\`#.\]\]$#K"(A$"P1!@\`$@_DF?/-JUS/`C7,J -M7XB#J@```"O[O8`````/MDP#!#/2C00W.\B+1"04#YS"`\*(!D:)1"04@^T! -M==]?7EU;65G#@>R(````C40D"%.+G"28````55:+M"2<````5VI`,_]74(D> -MZ/7"``"+K"2H````@\0,B\^%VW00#[8$*8/@#_]$A!A!.\MR\(T$&XE\)!A0 -MC8:(#```5U#HP,(``(U61(E^!#/`B3J#Q`R+]T"+VHE$)!"+Z`-TK!AJ$%DK -MS8O&T^`#]HE#Q(M$K!0#`T6)0P2-6P2#_1!RW&I`4HU$)&!0Z-?#``"+G"2P -M````@\0,B[0DH````(O7BZPDG````(7;=""*!"HD#W04#[;(BT2,6&:)E$:( -M#```0(E$C%A".]-RX('[*@$``'(<@?LK`0``=@B!^S(!``!U#,>&A`````H` -M``#K"L>&A`````<```"+CH0````SP$"+T-/BB50D%(72=&^-KH@$``!J$%DK -MCH0```"+U]/B@_@0-3@2-#($[$7()0(/!!(/X$'+SB40D$(B$/H@```"# -M^!!S)"L4AFH062O(T^H#5(9$.]-S$F:+A%:(#```9HE%`(M$)!#K!C/)9HE- -M`$>#Q0([?"04)="04B4PD$`/!B40D'#O(#X/'````:@-;BX[&8Y601U)HN&V.8``(M6?(/H -M!#O0W.8` -M`(N60$L``"/=BTY\18H$$X@$"HM&?(N>W.8``$`CPXE&?(/O`77:Z57^__\Y -M&0^%AP$``(M1"(MLEF");"08A=)T$XUZ&(T\OHM'_(D'C7_\@^H!=?.);F`/ -MMT$$B49T#[=Y!(M.?(O9BX;8Y@``*]T%_.___SO8#X,$`0``.\@/@_P```"+ -MAD!+```#V(TL"(T$.8E&?#E\)!AS28/_"')RB\_!Z0.*`X/O"(A%`(I#`8A% -M`8I#`HA%`HI#`XA%`XI#!(A%!(I#!8A%!8I#!HA%!HI#!X/#"(A%!X/%"(/I -M`77#ZRZ#_PAR*8O'P>@#B40D&(OP:@A35>A]OP``@\0,@\,(@\4(@^\(@^X! -M=>:+="04A?\/A&7]__^*`XA%`(/_`0^&5_W__XI#`8A%`8/_`@^&2/W__XI# -M`HA%`H/_`P^&.?W__XI#`XA%`X/_!`^&*OW__XI#!(A%!(/_!0^&&_W__XI# -M!8A%!6H#@_\,_?__BD,&B$4&Z0']__^%_P^$]_S__XNNW.8``(N60$L` -M`"/KBTY\0XH$*H@$"HM&?(NNW.8``$`CQ8E&?(/O`77:Z<;\__^#.0(/A0$! -M``"+?G2%_P^$M?S__XM.?(O9BX;8Y@``BU9@!?SO__\KVCO8#X.@````.\@/ -M@Y@```"+AD!+```#V(TL"(T$.8E&?#O7@#B40D&(OP:@A35>@&O@`` -M@\0,@\,(@\4(@^\(@^X!=>;IA/[__X7_#X3M^___BZ[+?"0HB^F);"08B5\,.%X(=1V+A80```"#Z`@( -MB\YJ"(E$)!CH#P`)! -MB4<,B4\$B\[H7&___\'H"(O.:@B)1"0@Z#5O__\Y7"00=CF+?"00B^N+SN@Y -M;___P>@(B\W3X(/%"(M.!`/8@\$(B\�?!Z`,!!HE.!(/O`775BWPD*(ML -M)!B+5"04B\O!^1"+P\'X"#+(B1\RRS+*@/%:.DPD'`^%,____XL&B4<(C4C_ -MBX6(`````\L[P7P"B\&)A8@```"*PL#H!B0!P.H'B$<0L`&(5Q%?7EU;@\00 -MP@@`4U97B_F-=P2+SNBH;O__BTX$B]`RV_?"`(```'0%L@%!ZPK!Z@ZS`2+3 -M@\$"B\&`\@'!Z`.#X08``(3;=`9?7C+`6\.+SU]>6^GJ```` -M5HMT)`A7B_F`?@@`=1:+AX0```"#Z!`Y!GX)Z(D.``"$P'1=4U:+S^A9```` -MBUPD%(O/5HE#!.A*````N0``0``[R!O)]]$CR(E+"(O.Z`AN___!Z`V+SFH# -MB`/HXVW__X`[`'48B\[H[FW__\'H"XO._L!J!8A##.C&;?__L`%;7U[""`!3 -M5HMT)`R+SE?HQVW__XM6!(OX@\("P>\.B\HSV\'I`X/B!P$.B58$@\;?__P>@(B\W3X(/%"(M.!`/8@\$(B\�?!Z`,!!HE.!(/O`775 -M75]>B\-;P@0`@>RL`0``5HOQ5XN&A````(U^!(/H&3D'?@WH$0T``(3`#X0! -M`P``BT8(B\_WV(/@!U#H(VW__XO/Z#-M__^I`(```'0BC8;$Y```QX97.8``(F>T)@``(F>U)@``*D` -M0```=15HE`$``(V&R.0``%-0Z-ZX``"#Q`QJ`HO/Z+EL__]5B\_HR&S__\'H -M#(O/#[;`:@2)1"04Z)YL__^+1"00@_@/=3>+S^BE;/__P>@,B\]J!`^VZ.A_ -M;/__A>UU!\9$'!0/ZQJ#Q0)-@_L4@#`0>#X0>)3P0/MXQ5B`0``.M@:@]90(E,)!`[P7,T-@\4#:@/K -M#^A8:___B^C![0F#Q0MJ!XO/Z#!K__^%VW1Y38'[E`$``'-?BD0<)XA$'"A# -MA>UUZNL^B\]U$>@B:___B^C![0V#Q0-J`^L/Z!%K__^+Z,'M"8/%"VH'B\_H -MZ6K__TV!^Y0!``!S',9$'"@`0X7M=>V-KE`\``"!^Y0!```/@H?^__^+!\:& -M8>8```$[AH0```!^!#+`ZWMH*P$``(V&H````(O.4(U$)#!0Z)+S__]J/(V& -MC`\``(O.4(V$)%L!``!0Z'KS__]J$8V&>!X``(O.4(V$))BRMP`` -M@\0,L`%=6U]>@<2L`0``PXM$)`B![,P!``"`>!$`58OI=0>P`>F6`@``5HNT -M)-@!``"`?@@`=1J+A80```"#Z!DY!GX-Z%0*``"$P`^$;0(``%@,B\YJ!`^VV.C-:?__@_L/=3>+SNC8:?__P>@,B\YJ!`^VV.BR:?__ -MA=MU!\9$/!@/ZQJ#PP)+@_\4%VW7P3^L$B%P\&$>#_Q1RI(N< -M).@!``"-1"08:A2!P[`[``"+S5-0B5PD(.AB\O__,_^`?@@`=1R+A80```"# -MZ`4Y!GX/B\WHL`D``(3`#X1@`0``B\[H6&G__XO0BX.$````@>+^_P``.U2# -M!',I:A!9*\C3Z@^VC!J(`````TX$B\'!Z`,!!H/A!XE.!`^WA%.(!```ZUMJ -M#UE`B4PD$#O!@#`0:+1"00B4X$:A!9*Q2#*\C3ZHM,@T0#RCL+&\`CP0^WA$.(#``` -M@_@0L)@\,+:@>+SNAB:/__A?]T>TN!_ZX!``!S6XI$/"N(1#PL1X7; -M=>KK/'41Z%9H__^+V,'K#8/#`VH#ZP_H16C__XO8P>L)@\,+:@>+SN@=:/__ -M2X'_K@$``',:QD0\+`!'A=MU[8M<)!2!_ZX!```/@I7^___&A6+F```!@'X( -M`'4.BP8[A80```!^!#+`ZV.+G"3H`0``C40D+&@R`0``4U"+S>C!\/__:D"- -M@^P.``"+S5"-A"1F`0``4.BI\/__:A"-@]@=``"+S5"-A"2F`0``4.B1\/__ -M:BR-B\0L``!1C8PDM@$``%&+S>AY\/__L`%;7UY=@<3,`0``P@P`N+`B0P#H -MXJ(``(/L((O!4U97C7@$B47LB\_H;&?__XM7!(/"",'H"(O*B47H:@=;P>D# -MB_`!#R/3(_.)5P1&._-U(HO/Z$%G__^+3P2+\(/!",'N"(O!`_/!Z`,!!R/+ -MB4\$ZR"#_@AU&XO/Z!IG__^+5P2+\(/"$(O*P>D#`0\CTXE7!(7V=00RP.M] -M5HU-U.B"T/[_,]N)7?R)7?"%]G1-BTWLBX&$````2#D'?!'HD`8``(3`=0B- -M1O\Y1?!R/XO/Z,-F__^+5?"+3=3!Z`B(!!&+3P2#P0B+P8/A!\'H`P$'0HE/ -M!(E5\#O6Q6_W74_W7HZ(7=__^*V(U-U.A2TO[_BL.+3?1?7EMDB0T` -M````B^5=P[C"(D,`Z,>A``"#[!Q35XOYZ(8"``"#R_^)1>P[PW4',L#IE0`` -M`%:+\(/F!T:#_@=U$(O/Z&("```[PW0KC7`'ZR*#_@AU'8O/Z$T"``"+\#OS -M=!2+S^A``@``.\-T"<'F"`/PA?9U!#+`ZTY6C4W8Z(?/_O\SVXE=_(E=\(7V -M=!^+S^@3`@``B]"#^O]T(8M%\(M-V(@4`4")1?`[QG+A5O]UV(O/_W7LZ+G< -M__^*V(U-V.B&T?[_BL->BTWT7UMDB0T`````B^5=PU97B_DS]H,\MP!T#?\T -MM^@[]```@R2W`%E&@_X@<```"+AF@&``"+TXF&9`8` -M`(O+B)YM"@``BX9$!@``BT`$B!0!0HN&1`8``(M`!,9$"`$!BX9$!@``BT`$ -MB5P(`H/!!H'Y``8``'S-C89P"@``B_N)1"00O4A#0P"+V`^W10"-3P*9]_EJ -M"(E$)!B+TUBY`$```"M,)!1FB0J-4A"#Z`%U[(/%`H/#`H']6$-#`'S+BT0D -M$+F`````1P/!B40D$#OY?+"+7"08@\8#C4,":A!KR"A89L=&_P,$9HE._8/& -M!(/H`77N0X/[&7S?7UY=6X/$&,.-3"0``!9B\B)3?`S -MP(E%_(7)=`C_=ASH#,/__XM-](E&%%YDB0T`````B^5=P@0`BT0D"(M4)`Q3 -M5XOY#[9<."D/MDPZ*3O9=0:+1"0,ZU!5BZR/N````(7M=#*+10")A(^X```` -M:\(,5HMT)!105E7H;;```(N,G[@```"#Q`R)#HO%B;2?N````%[K$5%3_W0D -M&(O/Z`H```"+1"0075];P@P`BT0D#%:+\5P@P`BT0D!%-6B_$SVT-7B)YL"@`` -MB89@!@``Z-_\__]J"8V&;@@``&;'AFP(`````FH$4.A%K@``:/4```"-AG<( -M``!J!E#H,JX``(/$&#/`B(0&;`<``$"#^`-\\XO(B]._``$``.L1B(P&;`<` -M`(/J`74$0T&+TT`[QWSK:D"-AFP)``!J`%#H\*T``&C`````C8:L"0``:@A0 -MZ-VM``"#Q!C&AD(&```'7UY;P@0`5HMT)`A7B_G!YA0Y-W4$L`'K1%/H0P`` -M`&H,63/2B\;W\8/``FO8#%/H4O```(F'K````%F%P'4.N5`/1`#H=B;__S+` -MZP^#P/2)-P/#B8=8`0``L`%;7U["!`"#.0!T#_^QK````(,A`.@,\```6<-3 -M,]M6B_$X7"0,=2MHE`$``(V&R.0``(B>8>8``%-0Z#BM``"#Q`S'AL3D```" -M````B9Y6\($`(!\)`0`=0?&@6+F```` -MP@0`5C/25XOY.%0D#'56:A!2C4=@4.CFK```,\!HG$H``%")1W")1W2)1WB- -MAZ````!0Z,FL``"+C]CF```STK@``$``B9>`````@\08B5=\.\AR`HO(BX?< -MY@``(\&)ASQ+``!J%(E74(VWC````(E7"(E7!%)6B9=83```B9=<3```B9>$ -M````B9>(````Z&RL``"##O^#Q`PSP(O/B(=%3```_W0D#.CW_O___W0D#(O/ -MZ#G___]?7L($`%:+\5>+CH0```"+^8M&!"OX>00RP.MU/0!```!^((7_?A"+ -M3A`#P5=04>@TT0``@\0,@V8$`(F^A````.L"B_F+#K@`@```*\=0BT80`\=0 -MZ&Z"__^+T(72?@8!EH0```"`OD5,````BX:$````C4CBB8Z(````=`L%#/[_ -M_XF&B````#/`@_K_#Y7`7U[#5HOQ5XN.A````(OYBU8$*_IY!S+`Z;,```"+ -MAI0````KP@&&C````%,SVX'Z`$```'X@A?]^$8M.$%>-!!%04>B/T```@\0, -MB5X$B;Z$````ZP*+^;@`@```._AT'(L.*\=0BT80`\=0Z,:!__^+V(7;?@8! -MGH0```"`OD5,````BX:$````C4CBB8Z(````=`L%#/[__XF&B````(N.C``` -M`(M&!(F&E````(/Y_W052`/(BX:(````.\%\`HO!B8:(````@_O_6P^5P%]> -MPU-5BVPD#(O95XM\)!0[_700QH-23````7,'QH-13````8"[1$P```!T1BO] -M([OANT___4(O+Z%P% -M```#[HV#1$L``".KW.8``"O^=ZS<[_7,BBX/8Y@``*\50BX-`2P```\50 -MZ"P%``!7_[-`2P``B\OK#(N#0$L``"O]5P/%4.@0!0``7UU;P@@`@^P44U56 -M5XOY,]N+3WR+KX`````KS2./W.8``#F?L.8```^&SP$``(N'K.8``(L$F(E$ -M)!2%P`^$K0$``(!X"`!T"<9`"`#IG@$``(L0BT`$B[?2`0``C2P0(^Z);"0@.]5R+87M="F+M]CF``"-CV3F``"+AT!+ -M```K\E8#PE!J`.BM>O__5?^W0$L``%;K#%"+AT!+```#PE!J`(V/9.8``.B, -M>O__BW0D%(O/@\805NCBWO__BT8@BW8DB40D%(N'K.8``&HXB70D%/\TF.AU -MF```BX>LY@``65F-2P&#))@`B4PD'#N/L.8```^#B0```(ML)!B+AZSF``"+ -M=)@$A?9T;SDN=6N+1"00.48$=6*`?@@`=5Q0_W0D&(V/9.8``&H`Z`EZ__^# -MQA"+SU;H8][__XM&((M<)!R+=B2)1"04BX>LY@``:CB)="04_S28Z/*7``"+ -MAZSF``!968,DF`"-0P&)1"0<.X>PY@``75N#Q!3#BX>LY@``BP28AWPK_8EL)"0CN]SF``"+UXE\)""(3"03B70D,#E+4`^&V0$``(E,)!B+0TP# -M1"08B40D+(`X"`^$@0$``(!X#0!T(XM`!"N#@````".#W.8``#O'#X=D`0`` -MBT0D+(A(#>E8`0``BW@$BT`(B40D%(O'*\4C@]SF```[P@^#.`$``#OO=!Q7 -M58O+Z'7\__^+4WR+[RO7B6PD)".3W.8``#/)BT0D%#O"#XBX/8Y@`` -M*\>`NT1,````B40D*%!T'U>-LT1+``!1B\[H)-C__XM$)"B+S@-$)!Q5:@!0 -MZS^+@T!+```#QU!1Z"FH``"+1"0T`T0D*%7_LT!+``!0Z!2H``"#Q!CK+X"[ -M1$P```"+1"044'0/5U&-BT1+``#HT-?__^L2BX-`2P```\=04>CCIP``@\0, -MBT0D+(O+BWPD%%!7_W0D).@DUO__BTM,BU0D&,8$"@B%P'0)BPM74.BX?O__ -M`;M83```BU-\BW0D,&H`61&+7$P``"O5(Y/75N#Q"3#4U:+\5>+GEQ,``"+EDQ,``"+OEA, -M``"+ADA,```[VG\V?`0[^',PBTPD%"O'B_D;TS/;.]I\"'\$._AV`HO(4?]T -M)!2+#NA'??__`;Y83```$9Y<3```7UY;P@@`@^P0@SWL@D0``%-55HOQ5XET -M)!1U48-D)!@`,_\S[8L#_Q-RN("^4$P` -M``#&AF!,```!=3G_="0DB\[H4/?__XO.Z`3X__^$P`^$?0P``(!\)"0`=`F` -MOF'F````=0^+SNBUZO__A,`/A%X,``"+AMSF``"-7@0A1GR+`SN&B````'X/ -MB\[HP/?__X3`#X0R#```BXZ`````B\$K1GPCAMSF```]!`$``',_.TY\=#J+ -MSNB@^?__BX9<3```.X9,3```#X\##```?!*+AEA,```[ADA,```/A^\+``"` -MOE!,````#X7$"P``@[YQ.0```^%.`,``(O.Z)OS__^%P'44B\[H[NG__X3`#X4Y____Z8L+ -M``"#^/\/A((+``"#^`(/A'D+``"#^`-U"8O.Z,GP___KTX/X!`^%L0$``#+` -M,_^(1"03,]N$P`^%4`L``(O.Z$'S__^#^/]U"+`!B$0D$^L>@_L#=0T/MLB* -M1"03B4PD'.L0#[;`P><(`_B*1"03BTPD'$.#^P1\O(3`#X4,"P``BX;8Y@`` -MC5<"C7D@!?SO__^+3GR+V2O:.]@/@P`!```[R`^#^````(N&0$L```/8C2P( -MC00/B49\.]=S28/_"')RB\_!Z0.*`X/O"(A%`(I#`8A%`8I#`HA%`HI#`XA% -M`XI#!(A%!(I#!8A%!8I#!HA%!HI#!X/#"(A%!X/%"(/I`77#ZRZ#_PAR*8O' -MP>@#B40D&(OP:@A35>B6HP``@\0,@\,(@\4(@^\(@^X!=>:+="04A?\/A/G] -M__^*`XA%`(/_`0^&Z_W__XI#`8A%`8/_`@^&W/W__XI#`HA%`H/_`P^&S?W_ -M_XI#`XA%`X/_!`^&OOW__XI#!(A%!(/_!0^&K_W__XI#!8A%!8/_!@^&H/W_ -M_XI#!HA%!NF5_?__A?\/A(W]__^+CMSF``"+ED!+``"+PR/!BTY\0XH$$(@$ -M"HM&?(N.W.8``$`CP8E&?(/O`778Z5K]__^#^`4/A38!``"+SNB9\?__@_C_ -M#X28"0``BUY\C7@$BX;8Y@``!?SO__^-:_\[Z`^#SP```#O8#X/'````BX9` -M2P``C0PHC108C00?B49\@_\!=D5J"%T[_7(^B]_!ZP.*`2O]B`**00&(0@&* -M00*(0@**00.(0@.*002(0@2*006(0@6*00:(0@:*00<#S8A"!P/5@^L!=<>% -M_P^$N?S__XH!B`*#_P$/AJS\__^*00&(0@&#_P(/AIW\__^*00*(0@*#_P,/ -MAH[\__^*00.(0@.#_P0/AG_\__^*002(0@2#_P4/AG#\__^*006(0@6#_P8/ -MAF'\__^*00:(0@;I5OS__X7_#X1._/__BX[45B@%``#K76H/7T`[QW,7C4@IC0R. -M.Q%R"T"#P02#^`]R\^L"B_B+2P0#SXO!@^$'B4L$P>@#`0,KE+Z@````:A!9 -M*\_3ZHN,ON0````#RCN.H````!O`(\$/MY1&*`T``(U&!('Z``$``',4BXY` -M2P``BT9\B!0!_T9\Z4?[__^!^@\!```/@FH#```/MKJEWT,`#[::P=]#`(/' -M`X7;=">+R.A"4___:A!9*\O3Z(M."`/X`\N-7@2+P<'H`P$#@^$'B4L$ZP.- -M7@2+R^@84___B]"+AA`0``"!XO[_```[E(:0#P``$5A04``#K7FH/6T`[PW,:C8CD`P``C0R. -M.Q%R"T"#P02#^`]R\^L"B]B+3@@#RXO!@^$'B4X(P>@#`48$*Y2>C`\``&H0 -M62O+T^J+C)[0#P```\H[CHP/```;P"/!#[>$1A0<```/M\"+'(7H@D0`#[:H -MZ(-$`$.)7"08A>T/A$8!``"#^`D/AA4!``"#_01V+8U.!.A&4O__:A19*\W3 -MZ(U-_`-."(UN!,'@!`/8B\'!Z`,!10"#X0>)303K`XUN!(N&U)@``(7`?@Q( -MB8;4F```Z;@```"+S>@!4O__B]"+AOP>``"!XO[_```[E(9\'@````!J$%DKS=/JBXRNO!X```/*.XYX'@``&\`CP0^WA$8`*P``#[?` -M@_@0=1+'AM28```/````BX;0F```ZP:)AM"8```#V.LDC4X$Z#91__]J$%DK -MS=/HBTX(`]@#S8O!P>@#`48$@^$'B4X(B5PD&('[`"```'(*1X'[```$`'(! -M1XM&:(E&;(M&9(E&:(M&8(E&9(E>8(M.?(OIBX;8Y@``*^L%_.___XE^=#OH -M#X.C````.\@/@YL```"+AD!+``"-'"B-+`B-!#F)1GPY?"08@#B40D -M&(OP:@A35>BBG0``@\0,@\,(@\4(@^\(@^X!=>;I!_K__X7_#X0$^/__BX[< -MY@``BY9`2P``B\4CP8M.?$6*!!"(!`J+1GR+CMSF``!`(\&)1GR#[P%UV.G1 -M]___@?H``0``=0R+SN@NX?__Z7SX__^!^@$!``!U#(O.Z$;H___I:/C__X'Z -M`@$```^%`P$``(M^=(7_#X22]___BTY\B]F+AMCF``"+5F`%_.___RO:.]@/ -M@Z`````[R`^#F````(N&0$L```/8C2P(C00/B49\.]=S4(/_"`^"3OG__XO/ -MP>D#B@.#[PB(10"*0P&(10&*0P*(10**0P.(10.*0P2(102*0P6(106*0P:( -M10:*0P>#PPB(10>#Q0B#Z0%UP^D'^?__@_\(#X+^^/__B\?!Z`.)1"08B_!J -M"%-5Z&N<``"#Q`R#PPB#Q0B#[PB#[@%UYNG0^/__A?\/A,WV__^+CMSF``"+ -MED!+``"+PR/!BTY\0XH$$(@$"HM&?(N.W.8``$`CP8E&?(/O`778Z9KV__^! -M^@$5NPQ``#K76H/7T`[QW,:C8A:"P`` -MC0R..Q%R"T"#P02#^`]R\^L"B_B+2P0#SXO!@^$'B4L$P>@#`0,KE+YD+0`` -M:A!9*\_3ZHN,OJ@M```#RCN.9"T``!O`(\$/MX1&[#D```^WP`^VN+3@0P`/ -MMIC0X$,`@\<"A=MT)(U.!.C&3?__:A!9*\O3Z(M."`/X`\N+P<'H`P%&!(/A -M!XE."(M.?(O9BX;8Y@``*]T%_.___XE^=#O8#X.B````.\@/@YH```"+AD!+ -M```#V(TL"(T$.8E&?#E\)!AS4(/_"`^"0??__XO/P>D#B@.#[PB(10"*0P&( -M10&*0P*(10**0P.(10.*0P2(102*0P6(106*0P:(10:*0P>#PPB(10>#Q0B# -MZ0%UP^GZ]O__@_\(#X+Q]O__B\?!Z`.)1"08B_!J"%-5Z%Z:``"#Q`R#PPB# -MQ0B#[PB#[@%UYNG#]O__A?\/A,#T__^+CMSF``"+ED!+``"+PR/!BTY\0XH$ -M$(@$"HM&?(N.W.8``$`CP8E&?(/O`778Z8WT__^!^A`!```/@X'T__\/MIHU -MX$,`#[:Z/>!#`$.%_W0CB\CHBDS__VH062O/T^B+3@@#V`//B\'!Z`,!1@2# -MX0>)3@B+1FB)1FR+1F2)1FB+1F")1F2)7F"+5GR+^HN&V.8``"O[!?SO___' -M1G0"````:@)=._AS(SO0GS -M\___BX[*!!"(!`J+1GR+CMSF``!`(\&)1GR# -M[0%UV.G`\___QH9@3````.L5B\_HR,C__X.F7.8```"+SNB+[?__7UY=6X/$ -M$,($`(/L(%-6B_%7B70D$("^4$P```#&AF!,```!=5?_="0PZ)7J__^+SNC8 -MZ___A,`/A#T&``"-OHP```"+SE>-7@13Z(3;__^$P`^$(P8``(V&H````(O. -M4%=3Z!CA__^$P`^$"P8``("^8N8````/A/X%``"-5GQ5B50D'.F["0``C59\ -MBX;+^_P``.Y2&I````',J:A!9*\C3Z@^VC#(H`0```TT$B\'!Z`,!10"#X0>) -M300/MYQ6*`4``.M;:@]?0#O'-2"F-#(X[$7(+0(/!!(/X#W+SZP*+^(M- -M!`//B\�>)303!Z`,!10`KE+Z@````:A!9*\_3ZHN,ON0````#RCN.H``` -M`!O`(\$/MYQ&*`T``('[``$``',Z@+Y$3````'0L"@\\$2XO+T^>#QP*%VW0CB\WH2$G_ -M_VH062O+T^B+300#^`/+B\'!Z`,!10"#X0>)302+S>@E2?__B]"+AA`0``"! -MXO[_```[E(:0#P``T`\```/*.XZ, -M#P``&\`CP0^WA$84'```#[?`@_@$L/B^B#X`'1[8/(`DV+S=/@0(E$ -M)!B+V(E<)!"%[0^$[@```(/]!`^"0`$``'8QC4X$Z.PA``!J)(O862O-T^N- -M3?P#3@B-;@2+P<'C!`-<)!C!Z`,!10"#X0>)303K`XUN!(O-Z!)(__^+T(N& -M_!X``('B_O\``#N4AGP>``!S*FH062O(T^H/MHPR`!\```--!(O!P>@#`44` -M@^$'B4T$#[>$5@`C``#K7FH/74`[Q7,:C8B?!P``C0R..Q%R"T"#P02#^`]R -M\^L"B^B+3@@#S8O!@^$'B4X(P>@#`48$*Y2N>!X``&H062O-T^J+C*Z\'@`` -M`\H[CG@>```;P"/!#[>$1@`K```/M\`#V(E<)!"-;@2!^P`!``!V$T>!^P`@ -M``!V"D>!^P``!`!V`4>+1FB)1FR+1F2)1FB+1F")1F2)7F"`OD1,````B7YT -M=%#_MMSF``"-3GQ14U>-CD1+``#H@<3__^G4^___C4X$Z*X@``!J((O862O- -MT^N+3@@#7"08`\V+P8E<)!#!Z`.-;@0!10"#X0>)303I=/___XN&V.8``(U6 -M?(L*!?SO__^+Z2OK.^@/@P8!```[R`^#_@```(N&0$L``(T<*(TL"(T$.8D" -M.7PD$'-)@_\(W.8``$`CPXD"@^\!==GI_P,``('[``$``'4VC40D((O.4%7H"M?_ -M_X3`=!2-1"0@B\Y0Z.6[__^$P`^%%_K__XO.Z$SI__]=7UY;@\0@P@0`@?L! -M`0``#X67`0``BWYTC59\A?\/A._Y__^`OD1,````=!+_MMSF``"-3GQ1_W9@ -MZ>S]__^+3GR+V8N&V.8``(M68`7\[___*]H[V`^#%P$``#O(#X,/`0``BX9` -M2P```]B-+`B-!#F)1GP[UW-(:@A:._IR;XO/P>D#B@,K^HA%`(I#`8A%`8I# -M`HA%`HI#`XA%`XI#!(A%!(I#!8A%!8I#!HA%!HI#!P/:B$4'`^J#Z0%UQNLN -M@_\(PD`@``4U565XO9 -MZ#'(____M"0X`@``B\OH3.#__XM#'#/2`\!T'S/)BT,8C8GD2@``0L9$".T` -MQD0([P"+0QP#P#O0QB-@Z````!J!5EHG$H``%"-LXP```"#QQCSI8M# -M&(/`,%#H68X``#/`@\0,,_:)1"0H,^V(1"03B6PD&(A$)!*+"[@``$``*\:# -MX/!0BT,@`\90Z$AC__^)1"0LA<`/B#8#```#\(ET)"`/A"H#``"%P`^.7`(` -M`('^``0``'S`Z4\"``"+0QPSR2%,)!2)3"0<`\`/A!0!``"+5"08,^V+>Q@# -M_8E,)"B`O]-*````B1]T"(FWS$H``.L\BT,@C4\$`\)0Z!9`__^+="0@,\F+ -MQHE/""M$)!B)3P2)A\Q*```/A,8```"(C]!*``"(3Q2(3RR+3"0<@WPD+`#& -MA]-*````#Y3`B8_@2@``@'\4`(B'TDH``'4QC4<8QD<4`5"-1P2+RU#H!M#_ -M_X3`='F`?RD`=0F`NV+F````=&J+3"01*```#1QB+5"08`]!!B\:)5"08 -M*\*)3"0<>`:`?R@`=1L]``0``'P4BT,<`\`[R`^"^?[__^L%QD0D$@&+3"04 -M,]*+P?=S'(OXA=)T`4#?"0<`8E!!'4*4HO+Z.H!``#K#E&+2Q1HT')! -M`.CJG___BU0D)`/O`U0D,(E4)"0[;"04````*_`#P59048ET)"SH-*\``(M%((/$#"M%!`%%&(-E -M)`"#92``BT,@@V4$`(E%$(M$)!2%P'0[BT,8:.1*``!54(NPU$H``(NXW$H` -M`.@SBP``BT,8B;#42@``BT,8BW0D+(FXW$H``,:%TTH```"#Q`PS[8EL)!CK -M&H7V>"%^\HM+(%:-!"E04>BWK@``Z]^+;"08@'PD$@`/A*;\__^+@]SF``"+ -MRR%#?.AZX?__:50D*.1*``"-NXP```"+0QAJ!5EHG$H``(UR&(/",`/P`\)0 -MC8.@````\Z50Z*2*``"#Q`Q?7EU;@<0D`@``P@0`@^PL55:+="0XB^F);"08 -M@'XL`'4EC48PQD8L`5"-1AA0C48$4.C(TO__A,!U#,:&T$H```'IR`4``(M& -M)(M.&`/!5XU^!#D'?@S&AM!*```!Z:L%``"+1B"+ELQ*``!(@Z;82@````/! -M@^H0B40D&(E4)!13B]@[PGP"B]J)7"00BP\[RWPS.\@/CW$%``!U#(M&"#M& -M'`^-8P4``#O*?`V`OM)*````#X1+!0``.X[,2@``#XT_!0``BX[<2@``C4'X -M.8;82@``=C"-!`F)AMQ*``!KP`Q0_[;42@``Z`_+``"+V%E9A=MU"KE0#T0` -MZ"L!__^)GM1*``"+AMA*``"+SVO8#`.>U$H``$")7"0HB8;82@``Z!L\__^+ -MT(N&M````('B_O\``#M4AC1S*6H062O(T^H/MHPRN`````-/!(O!P>@#`0># -MX0>)3P0/MXQ6N`0``.M5:@]=0#O%-3C2-#($[$7(+0(/!!(/X#W+SZP*+ -MZ(M/!`/-B\�>)3P3!Z`,!!RM4KC!J$%DKS=/JBTRN=(ML)"`#RCM.,!O` -M(\$/MXQ&N`P``+@``0``.\AS3(.^V$H```%V-8-[]`!U+P^W0_AJ`UIF.\)S -M(T!FB4/X#[?`B$P8_/^.V$H``(M4)!B+1"0L"62/!2X/( -M!(O+T^"-:`*);"04A=MT)HO/Z/4Z__]J$%DKR]/HBT\$`^@#RXEL)!2+P<'H -M`P$'@^$'B4\$B\_HSSK__XO0BX:@#P``@>+^_P``.Y2&(`\``',I:A!9*\C3 -MZ@^VC#*D#P```T\$B\'!Z`,!!X/A!XE/!`^WA%:D$P``ZUUJ#UM`.\-S&HV. -M(`\``(T,@3L1<@M`@\$$@_@/ -M'`\``&H062O+T^J+C)Y@#P```\H[CAP/```;P"/!#[>$1J0;```/M\"#^`1S -M!#/;ZP^+V(/@`='K@\@"2XO+T^!`B40D)(OHA=L/A`@!``"#^P0/@MD```!V -M+(O/Z)T3``!J)(OH62O+T^V+3P2#P?S!Y00#;"0D`\N+P<'H`P$'@^$'B4\$ -MB\_HRCG__XO0BX:,'@``@>+^_P``.Y2&#!X``',I:A!9*\C3Z@^VC#*0'@`` -M`T\$B\'!Z`,!!X/A!XE/!`^WA%:0(@``ZUUJ#UM`.\-S&HV.#!X``(T,@3L1 -M<@M`@\$$@_@/"!X``&H062O+ -MT^J+C)Y,'@```\H[C@@>```;P"/!#[>$1I`J```/M\`#Z.LFB\_HQA(``&H@ -MB^A9*\O3[8M/!`-L)"0#RXO!P>@#`0>#X0>)3P2!_0`!``!V(XM$)!1`B40D -M%(']`"```'820(E$)!2!_0``!`!V!4")1"04BT0D*(M,)!3'``$```!FB4@$ -MB6@(Z6@!```[R'5/C40D+(O-4%?H2LK__P^V1"0L9HE#!(M$)#")0PAJ!%J) -M$XN&V$H``&O(#`..U$H``$")AMA*```/MD0D.&:)002+1"0TB1&)00CI%?W_ -M_X'Y`0$``'4+QP,"````Z0+]__]J`UB)`XV!_O[__XO/B4,(Z$`X__^+T(N& -M>"T``('B_O\``#N4AO@L``!S*6H062O(T^H/MHPR?"T```-/!(O!P>@#`0># -MX0>)3P0/MX16?#$``.M=:@];0#O#)3P3!Z`,!!RN4GO0L``!J$%DKR]/JBXR>."T```/* -M.X[T+```&\`CP0^WA$9\.0``#[?8@_L(78/$+,($ -M`,S,S,S,S,S,S,Q65XM\)`PS]CEW!'8=4XO>BP^-!`N+"5#HS_G__T:-F^1* -M```[=P1RYUM?7L($`(/L*%97BWPD-(OQ@'\L`'4GC4T````@>+^_P``.U2'-',V:A!9*\C3Z@^VC#JX```` -M`TT$B\'!Z`,!10"#X0>-1P2)2`0/MY17N`0``.M>BUPD$.DB____:@];0#O# -M-2`V-#(\[$7(+0(/!!(/X#W+SZP*+V(M-!`/+B\�>)303!Z`,!10`K -M5)\P:A!9*\O3ZHM,GW0#RCM/,!O`(\$/MY1'N`P``(U'!+D``0``.]%S%XM& -M?(N.0$L``(@4`?]&?(U'!.FE_O__@?H&`0``#X(6!```C9KZ_O__@_L(L0B^N#XP/![0*#RP1-B\W3XX/#`H7M="B+R.CQ-/__:A!9*\W3Z(M/"`/8 -M`\V-;P2+P<'H`P%%`(/A!XE-!.L#C6\$B\WHQC3__XO0BX>@#P``@>+^_P`` -M.Y2'(`\``',J:A!9*\C3Z@^VC#JD#P```TT$B\'!Z`,!10"#X0>)300/MX17 -MI!,``.M>:@]=0#O%)3PC!Z`,!1P0KE*\<#P``:A!9*\W3ZHN,KV`/```#RCN/'`\``!O` -M(\$/MX1'I!L```^WT(/Z!',$,\#K#XO"@^(!T>B#R@)(B\C3XHE$)!B-2@&) -M3"0DB^F);"04$`VPD),'H`P$"@^$'B4H$ZP.-5P2+RNBJ,___ -MB]"+AXP>``"!XO[_```[E(<,'@`````#3PB+P<'H -M`P%'!(/A!XE/"`^WA%>0(@``ZVIJ#UE`B4PD&#O!@#`4<$BT0D&(E/"&H062N4 -MAP@>```KR-/JBXR'3!X```/*.X\('@``&\`CP0^WA$>0*@``#[?``^CK+(U/ -M!.B7#```:B"+Z%DK3"08T^V+3P@#3"08`VPD)(O!P>@#`4<$@^$'B4\(B6PD -M'(']``$``'830X']`"```'8*0X']```$`'8!0XM&:(E&;(M&9(E&:(M&8(E& -M9(EN8(M6?(O*BX;8Y@``*\T%_.___XE>=(E,)"0[R`^#*P$``#O0#X,C`0`` -MBX9`2P``C2P(C0P0C00:B4PD)(E&?#E<)!QS28/["')ZB]/!Z@.*10"#ZPB( -M`8I%`8A!`8I%`HA!`HI%`XA!`XI%!(A!!(I%!8A!!8I%!HA!!HI%!X/%"(A! -M!X/!"(/J`77#ZS:#^PAR,8O#P>@#B40D'(OX:@A54>A.?P``BTPD,(/$#(/! -M"(/%"(/K"(E,)"2#[P%UWHM\)#R-1P2%VP^$1/O__XI%`(@!C4<$@_L!#X8S -M^___BD4!B$$!C4<$@_L"#X8A^___BD4"B$$"C4<$@_L##X8/^___BD4#B$$# -MC4<$@_L$#X;]^O__BD4$B$$$C4<$@_L%#X;K^O__BD4%@_L&BUPD$(A!!8U' -M!`^&V?K__XI%!HA!!HU'!.G+^O__BVPD%(U'!(7;#X25^___BZ[=(ML)!2%VP^$$/O__XM&8(M6?(OJ*^B) -M1"0AH?0``BTPD,(/$#(/!"(/%"(/K"(E, -M)"2#[P%UWND5_O__C4<$A=L/A%WY__^+OMSF``"+ED!+```C_8M.?$6*!!>( -M!`J+1GR+OMSF``!`(\>)1GR#ZP%UVND8`@``@<+^_O__C4Y@C0R1BQF)7"0D -M=`V+0?R)`8U)_(/J`77SC6\$B5Y@B\WH@R___XO0BX=X+0``@>+^_P``.Y2' -M^"P``',J:A!9*\C3Z@^VC#I\+0```TT$B\'!Z`,!10"#X0>)300/MX17?#$` -M`.M>:@];0#O#)303!Z`,!10`KE)_T+```:A!9*\O3ZHN,GS@M```#RCN/]"P``!O`(\$/ -MMX1'?#D```^WV(/["',$,^WK$(OK@^,#P>T"@\L$38O-T^.#PP*%[70DC4\$ -MZ+DN__]J$%DKS=/HBT\(`]@#S8O!P>@#`4<$@^$'B4\(BU9\B^J+AMCF```K -M;"0D!?SO__^)7G0[Z`^#K@```#O0#X.F````BX9`2P```^B-#!"-!!J)3"0< -MB49\.5PD)'-0@_L(#X)^_/__B]/!Z@.*10"#ZPB(`8I%`8A!`8I%`HA!`HI% -M`XA!`XI%!(A!!(I%!8A!!8I%!HA!!HI%!X/%"(A!!X/!"(/J`77#Z3?\__^# -M^P@/@B[\__^+P\'H`XE$)"2+^&H(55'H2WL``(M,)"B#Q`R#P0B#Q0B#ZPB) -M3"0<@^\!==[I^/O__XU'!(7;#X1`]___B[[H(9HE$)"B` -M^A]S;8N&1`8``(M8"(7;=&!F.2MT3HM[!(I$)"0X!W0PB^^#QP8X!W7WBD)1"00@_@!=%RH`74@T>B-CHQ* -M``!0_W<$Z*"M__^)1P2%P`^$'O___XM$)!`/MU<"B\B+1"00P>$#.\H;R<'@ -M`D$Y1"04&\!`9B/(BT0D$`/`9@/).T0D%!O`]]AF`\AF`\KK46H!C8Z,2@`` -MZ$.F__^%P`^$S?[__XM/`HD(9HM/!F:)2`2)1P2*2`&`^1YS!P+)B$@!ZP3& -M0`%X#[9``6H#63M,)!0;R??99@..6`8``&8#R`^WP6:)3P*+3"0@08U0!@/( -M#Z]4)!QKP0:)3"08`]([T',@B\'!X`([T!O)03E4)!@;P/?80`/!9H-'`@.) -M1"08ZRMKP0\[T!O):T0D&`Q!.]`;P$`#R&M$)!@).]`;P(/!!$`#R&8!3P*) -M3"08BTPD$(I4)"1KP08#1P2($(M4)!B):`*(4`&-00%FB0>+?P@[OD0&```/ -MA:K^__^)GD0&``")GDP&``#I\?W__U97B_F+3"0,C8F,2@``Z`FE__^+\(7V -M="&+5"04,\!`9HD&BPJ)3@)FBT($9HE&!HM$)!")?@B)<`)?B\9>P@P`4U56 -MBW0D$(O15XN&4`8``(UJ`@^V`(J<,&P)``"(GFX*```/MD4`#[:,,&P)```/ -MMD4!P>`%`\B+0@@ST@^W``^VA#!K"```!?@$``"-/$B+AF0&``#!^!J#X"`# -M^`^VAFT*``#!KGA*```.`_@/ML,#^(N&=$H``"N&<$H``/>V>$H```^W#'X[ -MP7-#B:Y0!@``@'T!@`^2P`!%`8.F?$H````/MP1^B8:`2@``#[<,?HU!(,'H -M!RO(@^F`9HD,?O^&9`8``,:&;0H```'K78F.?$H```^W#'Z-02#!Z`&5`8```$````/MH!80T,`B898!@``#[9- -M`(J&;`H``(B$,6P&``"#IE`&````QH9M"@```%]>75O"!`!358O9,])6BW0D -M$%P2+R(N&=$H``"N&<$H``/?Q -MB8YX2@``BY:$2@``B^@[ZGP',L#IDP````^V3P$[Z7U%C00)B8Z`2@``.\*) -MOE`&``!J!`^7P(B&;0H```^VP`&&9`8``%@#R(A/`68!0P*#^7Q^"%:+R^@> -M`P``@Z9\2@```.M$BX90!@``A# -MQP8#R#O-?NZ)CH!*```/MD75O"!`"+ -MAE`&```/M@"*A#!L"0``B(9N"@``BH9L"@``B8Y\2@``#[8/B(0Q;`8```^W -M`X.F4`8```")AE0&``"-4/^*AFP*``"-?_H/M@^(A#%L!@``@^H!=>B+AH1* -M``")AH!*``#KDH'L%`0``%-55HNT)"0$``"+V5>)7"0<#[<[*[Y4!@``5U;H -MG0$``(M+!(U4)"2#Z0:)1"08B50D%#/MBI9L"@``@\$&#[8!.)0P;`8``'3Q -M#[9!`8M4)!0#Z(M<)!R-A"0D!```B6PD(#O0#X,``0``B0J#P@2)5"04@^\! -M=;P!KH1*```STHN&>$H``/>VA$H``#/2B\B+AG1*```KAG!*``#W\8F.>$H` -M`(N.A$H``(OH.^D/C;8```"+1"0@C50D)(M\)"0[Z'U*#[9/`>L:@\($C80D -M)`0``#O0#X..````BSH/MD<("_@/MD06`@^V5!8$P><("\?!X`@+P8M+!-/@ -M62I+!%_3ZEX+PEO#58OIN0`!``!6#[=%`&8[P71RBW0D$%.+7"005XOX,\`Y -MLU0&```/MHPS:P<```^?P(T4B(M%"#/)#[<`*\<[\`^!A$H```$```"+QEY=P@@`@^P44U6+;"0@ -M5E>+^8NU4`8```^W!XE$)""-6/\[=P1T+(UN^HM%`(L.9HM6!(D&9HM%!&:) -M1@2#[@:)30"-;?IFB54*.W<$==N+;"0HBT<$@$`!!#/`9H-'`@0/MDX!#[=7 -M`BO1.85(UV^D.`/@!T]P^W!P/3*\,SVT-FB0=F.\-U -M78MW!(L.9HM>!(E,)!C!Z0B*P='ZT.@JR(A,)!F#^@%^!HM,)!CKYHM$)""- -M0`'1Z`^VC"BU2@``BX2-1$L``(D&BT0D&(FTC41+``"-3P*)C5`&``")`6:) -M603K-HO"T?@KT`^W!V8!$8M,)"!!T>E`T>@[R'034%'_=P2-C8Q*``#H@<#_ -M_XE'!(M'!(F%4`8``%]>75N#Q!3"!`!358ML)`R+V5>+?"04B;U0!@``@$7^ -M_XL'BW`4B\[_%6`R0P"+S__6B40D)(E4)""%VW03B\_HL!+__P&#@````!&3 -MA````(L'BW`(B\[_%6`R0P"+S__6O@`(``"-1R164(U$)#!0Z"MY__^`O[IL -M````#Y3`#[;`4%:-1"0P4.BI-/__BT0D&,9$)!(`#[:(H6$``/?9&\F#X02) -M3"044>F.````A=MT#H.CB`````"#HXP`````@'PD$@!U3;X`"```C4/__:@%6C80D,!```%#H2#3__XL'C8PD*!```/]T)!3&1"06 -M`5&+<`2+SO\58#)#`(O/_]:$P'5\BT0D&("XB&$````/A80```!H``@``(U$ -M)"Q0Z(&+__^$P'1Q_W0D%(L'C4PD+%&+<`2+SO\58#)#`(O/_]:$P`^$5/__ -M_V:#O"0X(```5(U')%`/E<`/ML!0Z&R-__]J`8O/Z'6/_O^`?"03`(O/=&O_ -M="075N! -MQ!@@``#"$`!6B_$SP&H04(E&&(E&'(U&(%#'!FA#0P#'1@2,0T,`QT8(R$-# -M`,=&#`1$0P#'1A`@1$,`QT84`0```.B":P``@\0,B\9>PU%35HOQ,]MJ#(D> -MB5X$B5X(B5X,B5X0B5X4Z'Y:``")1"0,687`=!+'`&A$0P#'0`0!````B7`( -MZP*+PXE&&(O&B5X)(A>)HE>*%Y;6<-5B^QDH0````!J_VB!'T,` -M4&2))0````!65XOYBT\;_ -M___,S,S,S,R#;"0$".G6____S,S,S,S,@VPD!!#IQO___\S,S,S,S(-L)`0, -MZ;;____,S,S,S,R+3"0$BT$$0(E!!,($`%:+\8-^!`!T#?]V!/\5%"%&`(-F -M!`!>PU>+^8M/#(7)=&"#?Q@`=%I5Z`4/``"+Z(7M=$U3:"Q40P"+S^C>```` -MB]B%VW0Y5HLSC4\44?]W&(M.%%/_%6`R0P#_5A2+`U.+<`B+SO\58#)#`/_6 -MBT4`58MP"(O._Q5@,D,`_]9>6UU?P\S,S,S,S,S,S,S,S,S,N`%``(#""`#, -MS,S,S,S,S(-L)`0$Z>;____,S,S,S,RX`4``@,($`%97:"Q40P"+\>A7```` -MB_B%_W0CBQ?_=A17BW(8B\[_%6`R0P#_UHL'5XMP"(O._Q5@,D,`_]9?7L/, -MS,S,S,S,S,S,S,S,S(-L)`0(Z8;____,S,S,S,R+1"0,@R``,\!`P@P`58OL -M45&+20R%R74$,\#K;%?H_@T``(OXA?]T7X-E^`"-1?Q6BS=0:/Q30P!7BP[_ -M%6`R0P#_%H7`>"R+1?R-3?A1_W4(BS!0BTX0_Q5@,D,`_U80BT7\4(L(BW$( -MB\[_%6`R0P#_UHL'5XMP"(O._Q5@,D,`_]:+1?A>7XOE7<($`,RX`D``@,(( -M`,S,S,S,S,S,BT0D"(,@`#/`0,((`,S,S(M$)`B#8`@`QP`4````QT`$```` -M1#/`P@@`S,S,S,S,BT0D&(,(_[@&``*`PA@`S#/`0,(,`,S,S,S,S,S,S,RX -M`4``@,(0`,S,S,S,S,S,5HMT)`C_=A3_%1@A1@"%P'4#0.L+BT0D#(M.%(D( -M,\!>P@@`S,S,S,S,S,S,S,S,@VPD!`3IQO___\S,S,S,S%6+[(/L$%-6BW4, -M5XM]"(U/_/?9C4<$&\DSVR/(BT40B0Z)&(U%\%#_=Q3_%4@A1@"+312+1?A1 -M_W48B4$(BT7\B1F)602)00S_%0@A1@"+31S'`10```")602+1Q2)00B)60R) -M61"+!E"+"(MQ!(O._Q5@,D,`_]9?7C/`6XOE7<(8`,S,S,S,S,S,S,S,S+@# -M``*`PB0`S,S,S,S,S,R+1"0$BT@(ACO"P``,\#")`"+1"0$ZR!F@_D\=1=F@W@"+W40:@)99H,\2#YT%D&#^11R -M\X/``@^W"&:%R778,L#"!`"P`>OY45&+1"0,4U56BQ`S[5>+^8EL)!2-3"04 -MB6PD$(MR2%%0B\[_%6`R0P#_UHO8A=L/B(T```"+1"04A!J+1"00_W0D(%"+"(MQ%(O._Q5@,D,`_]:+V(M$)!!0BPB+<0B+SO\58#)# -M`/_6BT0D%%"+"(MQ"(O._Q5@,D,`_]:+1"04A=MX!(7`=4\Y;PAT2CEO('5% -M.6\<=$#_=QR+S^@P!@``B_"%]G0P:`0"``!55555:@'_=P3_%50A1@!J!?]W -M"/\5;"%&`%;_=PC_%5PA1@!6Z`VH``!97_?37L'K'UV*PUM96<((`(/L#%.+ -MV8-[$``/A#T!``"#9"0(`%97BWPD'%?HA_[__U>(1"03Z+:G``"-!$4``@`` -M4.C)IP``B_!9687V#X0'`0``56C@1$,`5NCDR0``:/!$0P!6Z%OC``!H>$5# -M`%;H4.,``(/$&(OO:B!89CD'=0F#Q0)F.44`=/=J!FC@1$,`5>B[B?__]]@: -MP`0!B40D&'0#C7T,5U;H%^,``(!\)"``65EU#6B814,`5N@#XP``65F`?"03 -M`'4*5HO+Z'\!``"+\%;H%:<``&OH!EF#Q0E5:D#_%1PQ0P"+^(7_="TSP(U- -M_5!048U/`U%J_U90:.G]``#_%1@Q0P"%P'0+9L<'[[O&1P*_ZP/&!P!6Z.>F -M``!9C40D%%!J`5?_%7PA1@!=AUT/XM-`(U#$%=0:!Q40P"+ -M,8O.58E$)!S_%6`R0P#_UHM-`(OX58MQ"(O._Q5@,D,`_]:%_U]Y"8M$)`R# -M(`#K-X-[$`!T,8O+Z)_Y__^+0Q`SR3E+(%&(2R6+,%%148M.+'0%_W,@ZP5H -MR$1#`%#_%6`R0P#_5BQ=7EM9P@0`S,S,S,S,S,PSP,((`%%158ML)!!75>B0 -MI0``:\@,@<$``@``4>BAI0``B_B)?"0465F%_W4'B\7IX0```%-6:.A%0P!7 -MZ+3'``!7Z%NE``"+V(/$##/`B_5F.44`#X2J````:@U9:@I:#[<&9CO!=5QF -M.58"=59J#5J-3@1F.1%J"HE,)!1:=41F.58&=3Y2C2Q?7V8Y?@9U)FBT14,` -M5>A9QP``BW0D&(/#!%E9:@V-1@2#Q0A9B40D$&8Y"'34BWPD%(/&`HML)!SK -M)3OU=B9J(%EF.\%U'F8Y3OYU&(T$7VA81D,`4.@1QP``65F#PP9J"EKK!6:) -M!%]#@\8",\!J#5EF.08/A5S___\SP%5FB01?Z*VD``!97HO'6U]=65G"!`#, -MS,Q5B^Q6BW40A?9U"K@#0`"`Z;^___,S,S,S,R#;"0$#.G6_O__S,S,S,S,58OL5HMU$(7V -M=0>X`T``@.M-:A!HG%-#`/]U#.A):P``@\0,A7<(, -M`%6+[(/L,%-6BW4(,]M7:`!_``!3B_G'1=`P````QT74*`@``,=%V"":00") -M7=R)7>")=>2)7>C_%00A1@")1>R-1=!0QT7P!@```(E=],=%^(1$0P")7?S_ -M%2`A1@")-U]>6XOE7<($`,S,S%:+="0(@VX4`8M&%'43B\[HM?3__VHP5N@H -M3P``65DSP%["!`#,S,S,S,S,S,S,S(-L)`0$Z<;____,S,S,S,R#;"0$".FV -M____S,S,S,S,@VPD!!#IIO___\S,S,S,S(-L)`0,Z9;____,S,S,S,R+3"0$ -M@VD$`8M!!'4,:@Q1Z,!.``!963/`P@0`@^P055:+="0<5U:+^>CEH0``C01% -M`@```%#H^*$``(OH65F%[0^$E`$``%:+S^B+^/__#[<.B_V(1"0/9H7)#X1X -M`0``4VH@QT0D'`T````SV\=$)"`*````6L=$)!0^````Z8H```!F@_D\#X2) -M````A,!T4V8[3"08=`=F.TPD''45._UT!F8Y5_YT!F:)%X/'`H/&`NM6A,!T -M+&:#^29U)C/`C10P#[<*9H7)=!*#^3MU!8UR`K,!@\`"@_@H#QP*#Q@**1"03,]L/MPYFAP0`=`G_L6A+?12#Z`%T%BV`````=23_-VKK_W4(_Q4\(48`ZQ5JZ_]U"/\50"%&`/]U -M"(O(Z)SW__]7_W40_W4,_W4(_Q4D(48`7UW"$`!5B^R#[!B-1>A35U#_=0B+ -MV?\5A"%&`(U['%=HC%-#`&H%:@"-1>A0_Q5X(48`BP>%P`^$A0```%:+,(U- -M_%%HO%-#`%"+#O\58#)#`/\6A":+ -M1?A0BPB+<2"+SO\58#)#`/_6BT7X4(L(BW$(B\[_%6`R0P#_UEY?6XOE7<($ -M`%:+\8-^(`!U#H!^)0!U"/]V'.A7]?__@'XF`,9&)0%T"HM.#&H!Z`4!``!> -MPU>+^8M7'(72=00SP%_#BP)64HMP!(O._Q5@,D,`_]:+1QQ>7\-5B^Q145>+ -M^8M''(7`#X3&````5HLPC4W\46B\4T,`4(L._Q5@,D,`_Q:%P'@]BT7\:@%0 -MBPB+<1B+SO\58#)#`/_6BT7\:@!0BPB+<0R+SO\58#)#`/_6BT7\4(L(BW$( -MB\[_%6`R0P#_UHM''(U-^%%HW%-#`%"+,(L._Q5@,D,`_Q:%P'@YBT7X4(L( -MBW$8B\[_%6`R0P#_UHM%^%"+"(MQ%(O._Q5@,D,`_]:+1?A0BPB+<0B+SO\5 -M8#)#`/_6BT<<4(L(BW$(B\[_%6`R0P#_UH-G'`!>7XOE7<-5B^Q15XOYBT<< -MA->R!7_W,855-5:OM0_Q5@,D,`_U8L -MBT0D$%?_6UG"!`!5B^Q15HOQC47\B77\ -M@V7\`(-]#`!0_W4(QP9P1D,`=`?H94<``.L%Z%A'``")1@B+1?R)1@2+QEZ+ -MY5W""`#,S%:+\?]V!,<&:$9#`.@M1P``]D0D"`%T&?9$)`@$=0A6Z`U'``#K -M"FH05NAQE```65F+QE["!`#,S,S,S,S,S,Q5B^Q148-E_`"-1?Q6B_%0_W8$ -MZ.!&``"%P'0#B48(:A#HQD8``(O0B57XA=)T%(M."(M%_,<":$9#`(E"!(E* -M".L",]*+PEZ+Y5W#58OL45%3C47\,]M0:&Q30P!J`5-H7%1#`/\5>"%&`(7` -M#X@.`0``BT7\C4WX5E%H3%1#`(LP4(L._Q5@,D,`_Q:%P`^(V````#A="'08 -MBT7X:@+_=1"+"%"+<12+SO\58#)#`/_6BT7\_W4,4(L(BW%0B\[_%6`R0P#_ -MUCE=&'06BT7\_W484(L(BW$BL-;B^5=PAP`:F3H&````(/X?7T/:F3H+0```(/X?7T#,\##,\!` -MPZ$HA$0`A5O\UT`Y$`/\5,#%#`(7`=`U0_Q4@,4,`B_"%]G4',\#I -MMP```%-55S/M:@*);"0<_Q4<,4,`B]B%VP^$E@```%/_%20Q0P"%P`^$@``` -M`%=64.A'5@``@\0,B6PD$(U$)!!055/_%7PA1@"%P'595?]T)!3HL/[__XM, -M)!"+^%&+$8MR"(O._Q5@,D,`_]:%_W0UBT<(B6\(A65G"!`!5B^R`/4P/1```BT44=`4-```8`%#_=1#_=0S_=0C_ -M%?0@1@!=PA``@^QPZ(S^__^$P'46_W0D?/]T)'S_="1\Z)P"``#ID0(``%.+ -M7"1XC40D,%50:AA3_Q5@($8`BT0D/(N,)(`````/K\&9]WPD.(OH.ZPDA``` -M`'P'BZPDA````%<[3"0\=0H[;"1`=00S_^L@C40D##/_4&B$1D,`,\!`4%=H -M;%1#`/\5>"%&`(7`>1!75U=74_\5Z"!&`.D4`@``BT0D#(U,)!!646H"BS!7 -M4U"+3E3_%6`R0P#_5E2%P(M$)!!X'R__A_@<$.``>`#XBD -M````BTPD$(U4)!Q248L!BW`LB\[_%6`R0P#_UHM$)!QJ`U7_M"20````BS#_ -M="0@4(M.(/\58#)#`/]6((N$)(@```#_="0HBTPD((EL)#P/K^B)1"0XP>`" -MB7PD,(E\)#2+,<'E`E50C40D.%!1BTX<_Q5@,D,`_U8B^5=P@0`_W0D!/\5.#%#`/?8 -M&\#WV,($`%6+[(/L'%97:)Q&0P"+\>B&7?__,_^)!E?_%8`A1@"-1?3'1?0( -M````4,=%^/\'``#_%30@1@!7C47DQT7D`0```%"-1?R)?>A0B7WLB7WPZ.L^ -M``!H,(1$`/\5B"!&`%^+QEZ+Y5W#58OL9*$`````:O]H@1]#`%!DB24````` -MH3"$1`!65XOYBQ!0BW((B\[_%6`R0P#_UO]W!.BE/@``_Q5T(48`BTWT7V2) -M#0````!>B^5=PU:+\8V.G*0``.A^;_[_C8X\I```Z'-O_O^-CMRC``#H:&_^ -M_XV.?*,``.A=;_[_C8X\0`0``='&#[P%U -M$@^WQ8/H`71-@^@!=#V#Z&5T!#/`ZVJAL`Q&`&H`_S#H:A?__U"AL`Q&`/\P -M:(X```#H>SG__U!6Z+AI_O^$P'0\H;`,1@#_,.LJ:@!6_Q6X($8`ZRBAL`Q& -M`/]P!/\P:F96_Q5H(48`:@'KX/\SB1VP#$8`:F96_Q50(48`,\!`7UY=6\(0 -M`(M$)`2+R%,SVV8Y&'0[5E=J7%\/MQ!F.]=U'@^W<`)F._=U"&:).8/`!.L3 -M@_YN=0AJ"EJ#P`3K`X/``F:)$8/!`F8Y&'7,7UXSP&:)`5O"!`!5B^RX)!`` -M`.A//@``9H,]:I1$```/A($```!6:@;_-?CE0P"^:I1$`%;HAA;__U#HW7+_ -M_X7`=6)H:(1$`.B<_?__:``(``!6C87<[___4.@(6?__C87<[___4.A.D``` -M,\EJ'E%FB8Q%WN___XU%X%#HI4T``(/$$,=%Y`,```!J%%AFB47PC87<[___ -MB47HC47@4/\5="!&`%Z+Y5W#BT0D!#/)AA<)0``_P5[``0``'4Q:F2- -MA=3^__]0:@]3_Q5L,4,`9HN%U/[__V:CJ.Q%`#/`9J.J[$4`QP40YD,`J.Q% -M`&HRC46<4/]U#/]U".C85O__BWT0,\"+=1165V@`YD,`9HD'C46<4&H`4_\5 -M>#%#`#/`9HE$=_Y?7EN+Y5W"$`"#[`Q355:+="0<5X7V#X34````#[<&9H7` -M#X3(````BUPD)#/M:B(S_XET)!PRR<=$)!@L````15H[;"0H#X."````9CO" -M=5IJ(HU6`EAF.0)U)83)=18[="08=1`/MT8$9CM$)!1T$&:%P'0+:B*+\EIF -MB11[ZSR*P8A$)!.$R70$,LGK%6HB6%!2Z#-N``!9A<"*1"0760^5P6HB6CK! -M=10/MP9F.T0D%'4$A,ET'6:)!'M'18/&`@^W!F:%P`^%=/___S/`9HD$>^L6 -M,\!FB01[@\8"#[<.4>B65?__A,!U\(O&ZPN+1"0D,\EFB0@SP%]>75N#Q`S" -M#`"X^2)#`.CW.@``4;@4?0``Z,@[``!35E___W0/C8W<@O__Z*]K_O\RP.MRB5W< -MB5W@B5WDB5WHB%WLC47+=>"-/#:-1P)0 -MZ,:-``!9B\B+11")"(7)=02+\^L3,\!79HD$#_]UW%'H4TP``(/$#(M%%(DP -MC4W,3^__]U".@)*```N%"K00##Z\;_=0CH^2<``+@8JT$` -MPU6+[+@,(```Z,,Z``"`/7"D1```#X24````:``(``"-A?3?__]0_W4(Z+(4 -M``"-1?A0:@%J`&CL4D,`:`$``(#_%2@@1@"%P'5DC47\QT7\`!```%"-A?3O -M__]0C47T4&H`C87TW___4/]U^/\5)"!&`(7`=2^+1?RY_P<``-'HB47\.\%R -M`HO!_W4,,\EFB8Q%].___XV%].___U#_=0CH+%7___]U^/\5!"!&`(OE7<(( -M`,S,S,S,S,S,S,S,S%6+[('L``$``%.+71!6BW4,5XM]"&H`:@!H;$]#`/]U -M%%-65^C"9O[_A,!U;8'N$`$``'19@^X!=0T/M\.#Z`%T%(/H`70$,\#K4FH` -M5_\5N"!&`.M$OH````"-A0#___]64&IF5_\5:"%&`(V%`/___[EX:D4`4.CK -M0O__5HV%`/___U#H*4/__VH!Z[__=11J9U?_%5`A1@`SP$!?7EN+Y5W"$`"X -M!"```.A@.0``BXPD%"```%,SVU:%R70"B!F+E"0@(```A=)T`H@:B[0D$"`` -M`(7V#X2T````#[<&9H7`#X2H````58NL)!@@``!7B[PD("```(E<)!`/M\"# -MQ@*#^#UU$X7_=!F%VW45AL#@\8",\!FB44`A?]T -M+V:)!X7;="AH`!```(U$)!A04_\58#%#`/^T)"P@``"-1"084%?HBU/__S/` -M9HD#7XO&7>L",\!>6X'$!"```,(8`%6+[%%14XU%^%#_%8@@1@"-1?Q0,\!0 -M4/]U#%#_%7P@1@"+V/?;&MN`PP%T+E;_=0C_=?S_%9`@1@#_=?Q(]]@:P(U8 -M`8M%^%"+"(MQ%(O._Q5@,D,`_]9>ZPB+10@SR6:)"(K#6XOE7<((`+@$(``` -MZ/PW``!35597:```"`#H88H``(OP687V=0JY4`]$`.B)P/[_BYPD&"```#/` -M,^UFB0:+_>MN9CDN=0AF@WPD%'MT86:#?"04?71[C40D%%#H_XD```/'63W[ -M_P,`=V>-1"044%;HO\4``%;HY(D``(OX@\0,A?]T%(U'_XT$1F:#."!U"(/H -M`H/O`77R@'PD$P!U$(T$?F@<0T,`4.@%K```65EH`!```(U$)!=0556-1"0D -M4/\SZ-O]__^)`X7`#X5P____7XO&7EU;@<0$(```P@0`58OL@^P10_Q6@($8`7HOE78```"![A`!``!T*H/N -M`74-#[?#@^@!=!F#Z`%T!S/`Z<@```!55_\5N"!&`.FX````:@'K\%?H*2`` -M`*%TQ40`AC___\UE.Q%`.@XB```_S60[$4`Z"V(``!963/`0%]> -M75O"$`!5B^R#[!A35VIE_S70#D0`_Q70($8`B_B%_P^4PX3;=`EJ9>C7[___ -MB_B%_W0/C47H4&H85_\58"!&`.L.QT7L70```,=%\"X!``#HK>[__X3`=#]6 -MA-MT%FIFZ)_O__^+\(7V=`E7_Q5,($8`B_[_=?#HQN[__U#_=>SHG.[__U!7 -MZ+GP__]7B_#_%4P@1@"+_EZ+QU];B^5=PX`]4(1$``!U2HM$)`A7,_]F.3AT -M/5;_%0`P0P"+\(U$)!105_]T)!B_L.Q%`&@`$```5^@2CO[_5VB(3T,`Z"WW -M__^#Q!R%]G0'5O\5!#!#`%Y?P\S,S,RX#B-#`.C:,P``N*@<`0#HK#0``%.+ -M71!6BW4,5XM]"&H`:@!H2%!#`/]U%%-65^AG8?[_A,!T"#/`0.FB"0``@>X0 -M`0``#X2@!@``@^X!=1(/M\.#Z`%T:8/H`70W@^AE=`*PXA%\NL#BD7RB@UQI$0`A,EU;832='W_ -M%40Q0P!0:)A00P"-A8SN__]64.@AB_[_@\00C8UDSO__Z#KC_O^#9?P`C86, -M[O__:A%0C8UDSO__Z"KD_O^(1?.$P'4._Q4`,$,`@_@%=0.(7?*#3?S_C8UD -MSO__Z#CC_O^*#7&D1`"`??,`#X4U`@``A,D/E<#^R")%\H3`#Y1%\X3`#X2X -M`0``5HV%C.[__U!J`/\5?#!#`&B`````C86,_O__N7+$1`!0Z`\Y__]H3H24$``(/$#.L&BT7LB47DC46H4/\5 -MA"!&`(OPC86,_O__:(````!0Z*0Y__]H#$,``(V%3./^_U#HDSG__X7V=#AH -M$"<``/]UX/\5K"!&`(-EZ`"+=>2`/@!U%&ID_Q6<,$,`BT7H0(E%Z(/X9'SG -MBT7@HZ3L10#K!HMUY(A=\X-][`!T$%;_%4PQ0P#_=>S_%1@P0P"`??,`#X2" -M^___:)H```#H`"K__U"-A8S>__]0:!!10P"-A62I__]H``H``%#HQ8C^_X/$ -M%+E0#T0`4^CBN/[_:C!HE@```.C(*?__4(V%9*G__U!7Z*/J____!5R$1`#I -M)_O__VH`:F=7B1U4A$0`Z-E;_O]J`&IF5^C/6_[_:.8```#HBRG__U!35_\5 -M4"%&`%-J:5?HLUO^_VBT-4,`:F57_Q50(48`:F57_Q5D(48`B_"%]G08:O!6 -M_Q5`(48`#8````!0:O!6_Q4\(48`:@7_-3B$1`!7Z`\)``!J`O\U.(1$`%?H -M`0D``&B0W$4`5X@=M`Q&`.@='```:@;_-3B$1`#&!;0,1@``5^C;"```@#U0 -MA$0``'4@@SU____-83<10#HW7X``%DY'6RD1`!T -M45?_%<@@1@`Y'6RD1`!T0H`]<:1$``!U.6H#_S4XA$0`5^B5!@``@SV0[$4` -M`'0B:@!H8*]!`&H`:'Q00P#_-=0.1`#_%;0@1@"%P`^$X/C__U/_-3B$1`!7 -MZ%T&``"`/6.$1```#X6C````@SV$W$4```^%E@```(,];*1$```/A8D````S -MP+ZJ````9HF%9&G__X'^J@```'4)@#V8[$4``'0_@?ZK````=0F`/9CL10`` -M=2YH`"```&B44$,`C85D:?__4.AT1O__:``@``!6Z`PF__]0C85D:?__4.A< -M1O__1H'^L````'ZGBPU`A$0`C85D:?__:@!J`%#_=>S_-=0.1`#HH]W__XMU -MZ(,];*1$``)U"6H`5O\58"%&`(`]:)1$``!T%&H`:F=7Z,M7_O]J`&IF5^C! -M5_[_H6RD1`"%P'0D@#U0A$0``'4;:@!3:!$!``!7.\-U"/\5`"%&`.L&_Q6H -M($8`@#U2A$0``'03:)````#H927__U!35_\54"%&`(O#BTWT7UY;9(D-```` -M`(OE7<(0`,S,S,S,S,S,S,S,N%`:``#HMBH``%.+G"1@&@``55:+M"1D&@`` -M,^U7B[PD9!H``%55:!A/0P#_M"1\&@``4U97Z&!7_O^$P'0(,\!`Z5`#``"! -M[A`!``!T;H/N`0^%/0,``&H"#[?#7BO&="*#Z&IT4H/H`71(@^@!=#^#Z`%T -M$8/H`70Q@^@!#X41`P``:@9>555H<0$``&IF5_\5P"!&`(7`=`=0_Q78($8` -M5E?_%;@@1@#KDVH#Z]9J!.O2,_9&Z\Z+]>O*:FQ7_Q5D(48`4/\5Q"!&`+X` -M"```C80D8`H``%;_M"1T&@``4.C:1/__5HV$)&0*``!04.CY`O__C80D8`H` -M`%!J95?_%5`A1@!H``$``&BT`@``C80DM`<``%!5C80D<`H``%#_%8`@1@!5 -M_[0DL`<``&AP`0``:F97_Q7`($8`C80D7`$``%"-A"1D"@``4/\59#!#`(O8 -M@_O_#X0V`@``C40D$%"-A"1T`0``4/\5`#%#`(U$)!A0C40D%%#_%0@Q0P!J -M,HU$)#1058U$)"10:@)>5F@`!```_Q5P,4,`:C*-A"28````4%6-1"0D4%5H -M``0``/\5=#%#`(U$)#!0C80DF````%!HF0```.AK(___4&A,3T,`C80DO`,` -M`&@``@``4.@V@O[_@\08C80DK`,``%!J:E?_%5`A1@!3_Q5@,$,`]H0D7`$` -M`!!U9&HRC80D_````#/)`XPD@`$``%"+A"2``0``$\504>@KZ___:)@```#H -M`2/__U"-A"3\````NP`"``!0:&!/0P"-A"2X`P``4U#HPX'^_X/$%(V$)*P# -M``!0:FA7_Q50(48`ZP6[``(``%7_M"2P!P``:'`!``!J9U?_%<`@1@"+#62$ -M1`"-1"0H4.B@4/__C40D$%"-1"0L4/\5`#%#`(U$)!A0C40D%%#_%0@Q0P!J -M,HU$)#1058U$)"105KX`!```5O\5<#%#`&HRC80DF````%!5C40D)%!55O\5 -M=#%#`(U$)#!0C80DF````%!HF0```.@V(O__4&A,3T,`C80DO`,``%-0Z`6! -M_O^#Q!B-A"2L`P``4&IK5_\54"%&`/:$)%P!```0BPV,W$4`BQ6(W$4`=`:+ -MP@O!=$MJ,HV$)/P```!045+H`>K__VB8````Z-@/[_@\04C80DK`,``%!J:5?_%5`A1@`SP%]>75N!Q%`: -M``#"$`"X`"```.@2)P``5E=H`!```(U$)`PS]E#_M"04(```Z'L___^+^(7_ -M#X3S````5;T`"```1H/^`0^$R````&:#?"0,+W0,9H-\)`PM#X6T````#[=$ -M)`Y0Z$1;__^#Z$0/A)````"#Z`%T:H/H"W14@^@##X6-````#[=$)!!0Z!U; -M__^#Z`!T*(/H,70C@^@!=!*#Z!YU;E6-1"064&ARM$0`ZUS'!6RD1``"```` -MZPK'!6RD1``!````Q@5Z:T4``>M"C40D$+ERQ$0`4.BA+___ZS$/MT0D$%#H -MP5K__X/X3'4A9H-\)!(`=1G&!7&D1``!ZQ!5C40D%%!H0+``"_``@``(V%L(+__U=0Z+;>__]7C86H(O__4(V% -M^,K__U"-A;""__]0Z.SY_O^-C:AR___H'.7^_XV%J"+__S/;4(V-J'+__XE= -M_.@_YO[_C8VPHO__Z(.O_O_I.@$``%.-A;"B__]0_Q58,$,`.)V\LO__#X2@ -M````5XV%^.[__U"-A;""__]0Z![U_O]7C87X[O__4.@A\O[_C86P@O__4.BA -M=@``B_!9@_X$3^_X3`#X6K -M_O__@TW\_XV-J'+__^BGX_[_Z1P*``"%VP^%%`H``*&$W$4`A<`/E,.$VW42 -M:+1%0P!0Z#.Q``"AA-Q%`%E9BGWSA/]T"(VU^,K__^L0C44,4.CFZO__B_"A -MA-Q%`(3;=0E0Z"YU``!9B_A6Z"5U```#QXT$10H```!0_S6$W$4`Z#MU``"# -MQ`R%P'07HX3<10"$VW0%,\EFB0A64.C)L```65F$_P^%APD``%;H_W0``%GI -M>PD``(7;#X5S"0``C87XRO__4/]U"/\57"%&`.E>"0``A=L/A58)``!F.3UR -MI$0`#X5)"0``,\"-O?C*__]J(F:)A?CN__]89CF%^,K__W4&C;WZRO__5^B% -M=```O@`(``!9.\8/@Q0)```/MP=J7%F#^"YU)V8Y3P)U(8/'!#/;9CD?#X3U -M"```5E>-A?CN__]0Z/@\___I^````&8[P0^$WP```&:%P'0+9H-_`CH/A,\` -M``"-1>0SVU!J`5-H(%)#`&@"``"`_Q4H($8`A3_%20@1@#_=>3_%00@1@"+1>RY_P<``-'H.\%R -M`HO!,\EFB8Q%^.[__V8YG?CN__]T+(V%^.[__U#HLG,``%EJ7%EF.8Q%]N[_ -M_W025FB44D,`C87X[O__4.@8//__5^B,!P``QP5LI$0``@```.D/!P``#[>%^,K_ -M_S/)*\%T+8/H,'07@^@!=".#Z`$/A>\&``#&!5.$1``!ZP:(#5.$1`"(#6"$ -M1`#IU08``(@-4X1$`,8%8(1$``'IPP8```^WA?C*__]0Z*:@``!9@_A&="*# -M^%5T$3/`HF&$1`"B8H1$`.F:!@``Q@5BA$0``>F.!@``Q@5AA$0``>F"!@`` -M,__&!9CL10`!1XV=^,K__V:#O?C*__\\#X6>````C87ZRO__:CY0Z%!1``!9 -M687`#X2&````C4@"B4WL,\EFB0B-A?C^__]J9%"-A?K*__]0Z&/B__^+V(7; -M=%UF@[WX_O__`'13:)A20P"-A?C^__]0Z*]3___WV&BD4D,`&\`C^(V%^/[_ -M_U#HF%/__X7`=0-J`U]HK%)#`(V%^/[__U#H@%/__X7`=0-J!E]J9(V%^/[_ -M_U!3ZYB+7>R#?1`%=16#_@D/A;<%``!J`5=3_W4(Z&H)``"#?1`$#X6A!0`` -M@_Xh!0``:@!74_]U".A+"0``Z8<%``#&!9GL10`!9CF]^,K__P^$LD:``"``"-A?K*__\#P5"-A?CJ__]0Z'XX__\SP&:)A'7X -MRO__9H.]^.K__P!U,&@`$```C86H0O[_4(V%^,K__U#H4CC__V@``@``C86H -M8O[_4(V%^.K__U#H.CC__XV%^,K__U#H?][__S/`9HF%^-K__XV%^.K__VHD -M4(V%^,K__U#_=0CH<=C__X/X!@^$\P,``&H!_W4(,\#&!5"$1``!9J-JE$0` -M_Q6X($8`@_L'#X70`P``@SULI$0``'4*QP5LI$0``@```,8%:)1$``'IL0,` -M`(/[`W4I9CF]^,K__W02C87XRO__4.ANJ@``6:.4[$4`C44,4.B2Y/__HY#L -M10#&!7MK10`!Z7<#``"#^P8/A6X#```SP&:)A?BR__\/MX6H0O[_4.A(G0`` -MO@`(``!95H/X4'0S@_A4C87XLO__=!1H@LM%`%#H1S?__\=%[!````#K+&B" -MJT4`4.@S-___QT7L!P```.L8:(*[10"-A?BR__]0Z!DW___'1>P"````,\!F -MB86H8O__9HF%^,+__XV%J&+^_U90C86PDO__4.CN-O__:B);9CF=L)+__W5/ -MOP`(``"-A:IB_O]74(V%L)+__U#HR3;__XV%LI+__U-0Z*5-``!9687`#X3U -M````,\EFB0B#P`)H``0``%"-A?C"__]0Z)@V___IU@```(V%L)+__U#HR=C^ -M_X3`#X6]````B]^-M;"2__]F.9VPDO__#X2H````:B!9#[<&9CO!=`AJ+UIF -M.\)U>8OX,\!FB0:-A;"2__]0Z(;8_O^$P'1:C86PDO__4.B*V/[_4.C2V/[_ -MA,!U1&HO6(O>9COX=1AFB87XPO__C48":/\#``!0C87ZPO__ZQ=J(%B#Q@)F -M.09T^&@`!```5HV%^,+__U#HZS7__V:).^L#9HD^:B!9,_^#Q@)F.3X/A6O_ -M__^_``@``(7;=`PSP&:)`^L%OP`(``!F@[VHXO[_`'045XV%J&+__U"-A:CB -M_O]0Z)?H_O]7C86H0O__4(V%L)+__U#H@^C^_V:#O?BR__\`=0__=>R-A?BR -M__]0Z/_A__]7C87XLO__4.@KZ/[_9H.]J(+^_P!T(5>-A:B"_O]0C87XLO__ -M4.@?-?__5XV%^++__U#H`.C^_U>-A?BR__]0C86H,O__4.@F-?__9H.]J,+^ -M_P"-A:C"_O]U!HV%J&+^_U=0Z&'R_O]0C87XLO__4.C4-/__C87XLO__4.A" -MZO[_A%J&+___?841O`(\(/ -MMY6H4O__]]I0C86HHO[_&])0(];HEMO__U!2C87XLO__4(V%J$+__U!3Z$C1 -M__]F.9VH,O__="-3C86H,O__4&H%:``0``#_%7@@1@#K#(/[!W4'Q@5PI$0` -M`6@`$```C47K4(U%\U"-A?C*__]0C86H`O__4/]U#.B#W___BUT0B44,A<`/ -MA8CS__]?7EN+3?1DB0T`````B^5=P@P`D#/!00`$PT$`I<-!`,+#00#0Q4$` -M$<9!`)[&00##QT$`;\E!`)[&00"IR4$`%,U!`%W&00"9QT$`4XM<)`A5:B!3 -MZ&]*``!9687`=&9J(EUF.2MU"U/HKO#^_V8Y*'135E=3Z+=J``"+^#/):@): -MC4<#]^(/D,'WV0O(4>@.&@``B_!3C4X"4>CEC```@\009HEL?@(SP&:)+F:) -M1'X$_W0D&%93Z",S__]6Z.@9``!97UY=B\-;P@@`@^Q<4U565^C:X/__:FC_ -M-5B$1`#_%60A1@"]L0```#/;B_"-?1$X'6.$1`!U-(L-0(1$`.C7O?__:@56 -M_Q5L(48`:O]355;_%0`A1@!HM#5#`%-75O\5`"%&`,8%8X1$``&X`.'U!5!0 -M55;_%0`A1@"-1"00QT0D$%P```!04V@Z!```5O\5`"%&`#/)B%PD*8I<)'!! -MB4PD%(3;=!^+1"08)?___[_'1"0DH`````O!QT0D%`$``$")1"08C40D$%!1 -M:$0$``!6_Q4`(48`_W0D=&H`5U;_%0`A1@"X`.'U!5!055;_%0`A1@"$VW0C -MBT0D&(/@_@T```!`B40D&(U$)!!0:@%H1`0``%;_%0`A1@!H'$-#`&H`5U;_ -M%0`A1@!?7EU;@\1\0`0``=#F#[P%U#0^WQ8/H`704@^@!=`0S -MP.M%:@!6_Q6X($8`ZS=H``@``/\UK.Q%`&IH5O\5:"%&`&H!Z]]3:F96B1VL -M[$4`_Q50(48`_S6L[$4`:FA6_Q50(48`,\!`7UY=6\(0`+ERQ$0`Z10>__^X -M&!```.@X%@``Z'W/__^$P`^$T0```%565VH%_[0D+!```/\5-"%&`(OP,_^+ -M[H7V#X2N````4X'_``(```^-H````&@`"```C40D+%!6_Q7L($8`:`A/0P"- -M1"0L4.AR2O__A#X1+`@`` -M5NB`9P``63WV!P``#X,Y`@``5VH\7U>-1"044U#HT20``(J,)&@0``"#Q`R) -M?"00QT0D%,`!``"$R70(QT0D%,`%```/MQ:-?@)5:B)=9CO5=`*+_HE\)"2+ -MPV:%TG0VB];'1"00(````&8Y*@^$B0$``(M4)!!F.11$`0``9H-\1@(O -M#X2(`0``0(T41F8Y&G74BT0D*%V%P'0%9CD8=16$R7419CD=6X'$0!```,(0`(,E5(1$``!J`?]T)`C&!5&$1``!Q@52A$0``?\5;"%& -M`&H`:@+_="0,Z$<__O^#/3R$1```=0F`/6.$1```=`F#/5R$1```=1-J`&H! -M:!$!``#_="00_Q4`(48`P@0`N#@C0P#HF!$``%&X`"$``.AI$@``4U97B67P -M:)!/0P!H,5$`(O.Z,Z'_O^#9?P`C8WPWO__:@)8HU`X10"C3#A%`*-(.$4` -MH&&$1`"BSR9%`*!BA$0`5L8%#"=%``'&!0\G10`!HM`F10#H/ZG^_XV-\-[_ -M_\9%_`'HIZK^_XV-\-[__^BXJ?[_BTWT7UYDB0T`````6XOE7<((`+Y0#T0` -MB\[H9YK^_VH(B\[H*9O^__]U".BZ_O__N)_400##Z\C_=0CHJO[__[AIU$$` -MPU6+[+@($```Z'01``"`/7"D1```='EF@SURI$0``'1O5F@`"```C87X[___ -M4&ARI$0`Z%KK__^-1?@S]E"-1?Q05F@&``(`5E96:.Q20P!H`0``@/\5$"!& -M`(7`=3#_=0CH;F,``%F-!$4"````4/]U"(V%^.___VH!5E#_=?S_%2`@1@#_ -M=?S_%00@1@!>B^5=P@0`58OLN``@``#HWQ```%;_=0AH7%!#`/\57#%#`&@` -M$```C84`X/__4/]U".@_*?__B_"%]G0B#[<.4>L'@\8"#[<&4.A`*O__A,!U -M\%9H;%!#`/\57#%#`%Z+Y5W"!`!5B^R#[!Q7:@K_=0C_%>0P0P"_`@$``#O' -M=496,_965E96C47D4/\5I"!&`(7`="%65E:-1>10_Q7@($8`C47D4/\5O"!& -M`(U%Y%#_%:`@1@!J"O]U"/\5Y#!#`#O'=+Y>7XOE7<($`%6+[%%1BT4(B47X -MBT4,B47\C47X4&C`ID$`_S58A$0`:)1/0P#_-=`.1`#_%;0@1@!(]]@;P$"+ -MY5W""`!5B^R`/6"$1```BT40HXC<10"+112CC-Q%`(M%&*-DA$0`=`0SP.MC -M@#U3A$0``'0%,\!`ZU535E>_<+M!`+L83T,`ZR/_=0AH4,]!`/\U3(1$`&@X -M3T,`_S70#D0`_Q6T($8`AF6````@WT(`HLU6(1$`'4-5O\5L"!&`/?8&\`C -M\%-H``@``(V%`/#__U#_=1#_=0SHG.#^_XV%`/#__U!H(*Q!`%9H;$]#`/\U -MU`Y$`/\5M"!&`(M=%(7`=!-J0%F^>&I%`(O[\Z4SP$!FI>L5:+0U0P"+R^C: -M%___Q@50A$0``3+`@+L``0```'0.:D!9B_._@)*___:``(``!H:(1$`.A4Q___C4PD'.@-S?__ -MN>"!1`#H"#[__[\$<0``,]M74VB`:T4`Z!H=``"#Q`S_%5@Q0P"+\(7V='Y6 -MZ"GF__\X'7&D1`!T:E5HK$]#`%.^'P`/`%;_%50Q0P"+Z(7M=$=74U-65?\5 -M2#%#`(O8A=MT+5=3:(!K10#H)QX``(/$#,8#`6B":T4`Z`O\__]J0%F^@MM% -M`+]RQ$0`\Z5FI5/_%4PQ0P`SVU7_%1@P0P!=ZP96Z.'[__]H``@``+^0W$4` -M5U/_%7PP0P!7:.!/0P#_%5PQ0P"-1"0,4/\50#%#``^W1"0:4`^W1"0<4`^W -M1"0>4`^W1"0@4`^W1"0B4`^W1"0B4`^W1"0D4&CP3T,`C80DG````&HR4.C% -M9?[_@\0HC40D?%!H-%!#`/\57#%#`%/_%8`P0P"+\&ID5HDUU`Y$`(DUT`Y$ -M`/\5U"!&`*-TQ40`Z'C6__]7N>@.1`"C?&M%`.C'^_[_C4PD4.A7L/__C4PD -M).A.L/__4VAPL4$`4XU$)%RC0(1$`(U$)#!H2%!#`%:C1(1$`/\5M"!&`(U, -M)"2)'42$1`")'4"$1`#HTK#__XU,)%#HR;#__Z&@[$4`AQ%``"+-5`/1`!T(H`]FNQ%``"A_.5#`'0.BS6<[$4`A6X'$U````,(0`+AL(48`Z0````!14E!H -MQ+U#`.B\!@``6EG_X+AD(48`Z>7___^X8"%&`.G;____N%PA1@#IT?___[A8 -M(48`Z7___^X6"!&`.G;____N$P@1@#IT?___[A0($8` -MZ7___^X#"!&`.G;____N``@1@#I -MT?___[@4($8`Z7___^XC"!& -M`.G;____N'0@1@#IT?___[B$($8`Z"%&`.GE -M____N(0A1@#IV____[B`(48`Z='___^X="%&`.G'____]P5@54,``!```'0F -MZ)X```"AX`Q&`$"CX`Q&`(/X`74,:.0,1@!J!.C4`0``Z7<"``##H=`,1@!3 -M,]M#.\-U!#+`6\.%P'0$BL-;PU9HC%1#`/\5@#!#`(OPA?9U!(OSZRIHJ%1# -M`%;_%8PP0P"%P'3L:,!40P!6H]0,1@#_%8PP0P"%P'37H]@,1@"+SKK0#$8` -M,\#P#[$*AR+3?PSS>C$#@``B^5=PXO_58OL@^Q`C47D:AQ0 -M_W4(_Q6@,4,`A-1``0`"%]G4$ -M,\#K/0^W@10`0`"-D1@`0``/MXD&`$```]!7B[X,`$``,_:%R707.WH,<@J+ -M0@@#0@P[^'(01H/"*#OQ7<((`(M%"(M*"(D(BT4,BTHDB0B+0@P% -M``!``.O@B_]5B^Q145:-1?A0C47\4.AH____B_"%]G4+BT4,QP`$````ZT.# -M/>@,1@``=2'W1?@```"`QP7H#$8``0```'4%:AE9S2G_=?Q6Z+O^____=0S_ -M=0C_=?Q6_Q6<,4,`AZPK' -M!=P,1@``````BTW\,\WHW0P``(OE7<.+_U6+[(/L.*%HYD,`,\6)1?Q35E?H -M\_S__XM-"+\``$``QT70)````(E-U(M!!(M9"`/'BU$,`]^+<1`#UP/WB5WX -MBWD4@<<``$``B47")?>2)?>B) -M?>R)??!U)(U%T(E%^.C\_O__C47X4&H!5VA7`&W`_Q64,4,`,\#IUP$``(M% -M#(L[*\+!^`*)1B%VW02C470B\M0:@+_%6`R0P#_TXOPA?8/A94` -M``"+10@SVSE8%'0M.5@<="B+1SR!/#A010``=1R+3_W7D5_\5C#!#`(OPA?9U3O\5`#!#`(LUW%1#`(E%\(7V -M=!:-1="+SE!J!/\58#)#`/_6B_"%]G4EC470B47TZ%;]__^-1?10:@%3:'\` -M;<#_%90Q0P#HSOK__XMU[(M%#(DPBQW85$,`A=MT&H-E\`"-1=!0:@6+RXE] -MZ(EU[/\58#)#`/_3Z`[]__^+QHM-_%]>,\U;Z%H*``"+Y5W""`"XF"!&`.D` -M````45)0:(2^0P#H9/W__UI9_^"X-"!&`.D`````45)0:*2^0P#H2?W__UI9 -M_^#_)5@R0P#_)50R0P#_)5`R0P#_)4PR0P#_)4@R0P#_)40R0P#_)4`R0P#_ -M)3PR0P#_)3@R0P!5B^SK'_]U".A^CP``687`=1*#?0C_=0?H3PH``.L%Z"L* -M``#_=0CH95,``%F%P'347<-5B^S_=0CH2PH``%E=P\QJ_U!DH0````!0BT0D -M#&2))0````");"0,C6PD#%#RP\S,S,S,S,S,S,S,S%=64S/_BT0D%`O`?11' -MBU0D$/?8]]J#V`")1"04B50D$(M$)!P+P'T41XM4)!CWV/?:@]@`B40D'(E4 -M)!@+P'48BTPD&(M$)!0STO?QB]B+1"00]_&+T^M!B]B+3"08BU0D%(M$)!#1 -MZ]'9T>K1V`O;=?3W\8OP]V0D'(O(BT0D&/?F`]%R#CM4)!1W"'('.T0D$'8! -M3C/2B\9/=0?WVO?8@]H`6UY?PA``S,S,S,S,48U,)`0KR!O`]]`CR(O$)0#P -M__\[R/)R"XO!692+`(D$)/+#+0`0``"%`.OG:A!H@+A#`.A'"0``,]N)7>"( -M7>>)7?P[71!T&HM-%.@?"0``BTT(_U44BT4,`44(0XE=X.OAL`&(1>?'1?S^ -M____Z`X```#H30D``,(4`(M=X(I%YX3`=0__=1A3_W4,_W4(Z'L```##:@QH -MH+A#`.C>"```QD7G`(M=#(O#BWT0#Z_'BW4(`_")=0B#9?P`B\=/B7T0A?'1?S^____Z!0```#HU0@``,(0 -M`(M]$(M=#(MU"(I%YX3`=0O_=1174U;H`0```,-J&&C`N$,`Z&0(```S]HEU -M_(M]"(EUY#MU$'1"*WT,B7T(BTT4Z#8(``"+S_]5%$;KXHM%[(E%X(M%X(L` -MB477<($`%6+[%WI%OW__^F:!P``58OL -MBT4(5HM(/`/(#[=!%(U1&`/0#[=!!FOP*`/R.]9T&8M-##M*#'(*BT((`T(, -M.\AR#(/"*#O6=>HSP%Y=PXO"Z_GH7PD``(7`=0,RP,-DH1@```!6OO@,1@"+ -M4`3K!#O0=!`SP(O*\`^Q#H7`=?`RP%[#L`%>PU6+[(-]"`!U!\8%%`U&``'H -M?`<``.@B.@``A,!U!#+`7OIL`%=PU6+[(/L -M#%:+=0B%]G0%@_X!=7SHW@@``(7`="J%]G4F:/P,1@#H7YD``%F%P'0$,L#K -M5V@(#48`Z$R9``#WV%D:P/[`ZT2A:.9#`(UU]%>#X!^__`Q&`&H@62O(@\C_ -MT\@S!6CF0P")1?2)1?B)1?REI:6_"`U&`(E%](E%^(UU](E%_+`!I:6E7UZ+ -MY5W#:@7H;`@``,QJ"&C@N$,`Z%H&``"#9?P`N$U:``!F.04``$``=5VA/`!` -M`(&X``!``%!%``!U3+D+`0``9CF(&`!``'4^BT4(N0``0``KP5!1Z&G^__]9 -M687`=">#>"0`?"''1?S^____L`'K'XM%[(L`,\F!.`4``,`/E,&+P<.+9>C' -M1?S^____,L#H(P8``,-5B^SHS0<``(7`=`^`?0@`=0DSP+GX#$8`AP%=PU6+ -M[(`]%`U&``!T!H!]#`!U$O]U".C.F0``_W4(Z,PX``!96;`!7<-5B^RA:.9# -M`(O(,P7\#$8`@^$?_W4(T\B#^/]U!^C.EP``ZPMH_`Q&`.@RF```6??861O` -M]]`C10A=PU6+[/]U".BZ____]]A9&\#WV$A=P\S,S,S,S,R`^4!S%8#Y(',& -M#Z7"T^##B]`SP(#A']/BPS/`,]+#S(M$)`B+3"00"\B+3"0,=0F+1"0$]^'" -M$`!3]^&+V(M$)`CW9"04`]B+1"0(]^$#TUO"$`#,S,S,S,S,S,S,S,Q75E4S -M_S/MBT0D%`O`?15'18M4)!#WV/?:@]@`B40D%(E4)!"+1"0<"\!]%$>+5"08 -M]]CWVH/8`(E$)!R)5"08"\!U*(M,)!B+1"04,]+W\8O8BT0D$/?QB_"+P_=D -M)!B+R(O&]V0D&`/1ZT>+V(M,)!B+5"04BT0D$-'KT=G1ZM'8"]MU]/?QB_#W -M9"0@P -M10``Z"M%``#HY08``.C1!@``4.@=F0``6>BUE0``A,!T!>A.D0``Z+<&```S -MP,-J!^AB!```S,S,S,S,S,S,S,S,S.C1!@``,\##S,S,S,S,S,SHC@4``.B& -M!@``4.@ZF0``6<-J%&@`N4,`Z"("``!J`>CE^O__683`=0=J!^@4!```,MN( -M7>>#9?P`Z);Z__^(1=RA]`Q&`#/)03O!=-R%P'5)B0WT#$8`:+0R0P!HF#)# -M`.B6EP``65F%P'01QT7\_O___[C_````Z?8```!HE#)#`&AD,D,`Z!27``!9 -M6<<%]`Q&``(```#K!8K9B%WG_W7A7^___65G'1?S^____B\;K/8M-[(L!BP")1>!1 -M4.BWA@``65G#BV7HZ(R)``"$P'4(_W7@Z%N*``"`?><`=07H,HH``,=%_/[_ -M__^+1>#H#0$``,/,S,S,S,SH9`0``.F(_O__.PUHYD,`\G4"\L/RZ>@%``#, -MS,S,S%6+[%;_=0B+\>@"+O__QP:`54,`B\9>7<($`(-A!`"+P8-A"`#'002( -M54,`QP&`54,`P\S,S,S,S,S,S,S,S,R-003'`6A50P!0Z(@Q``!9PU6+[(/L -M#(U-].B9+?__:`2W0P"-1?10Z$LI``#,58OL@^P,C4WTZ)____]H'+E#`(U% -M]%#H+BD``,SI_D@``/\E8#)#`,S,S,S,S,S,S,QH4"%"`&3_-0````"+1"00 -MB6PD$(UL)!`KX%-65Z%HYD,`,47\,\50B67H_W7XBT7\QT7\_O___XE%^(U% -M\&2C`````/+#BTWP9(D-`````%E?7UY;B^5=4?+#58OL@R48#48``(/L*%,S -MVT,)'7#F0P!J"NA#*@$`A<`/A&T!``"#9?``,\"##7#F0P`",\E65XD=&`U& -M`(U]V%,/HHOS6XD'B7<$B4\(B5<,BT78BTWDB47X@?%I;F5)BT7@-6YT96P+ -MR(M%W&H!-4=E;G4+R%AJ`%E3#Z*+\UN)!XEW!(E/"(E7#'5#BT78)?`__P\] -MP`8!`'0C/6`&`@!T'#UP!@(`=!4]4`8#`'0./6`&`P!T!SUP!@,`=1&+/1P- -M1@"#SP&)/1P-1@#K!HL]'`U&`(-]^`>+1>2)1>B+1>")1?R)1>Q\,FH'6#/) -M4P^BB_-;C5W8B0.)PD`P``4U9J%^BE*`$`APS3?PSR#O/=0>Y -M3^9`N^L0A6\/,S,S,S,S,S,S,4U:^-+%#`+LTL4,` -M._-S&%>+/H7_=`F+S^CB^O___]>#Q@0[\W+J7UY;PU6+[&H`_Q6T,4,`_W4( -M_Q6P,4,`:`D$`,#_%0PP0P!0_Q7,,4,`7<-5B^R!["0#``!J%^AI)0$`A+?"0$AL3#[HE<.9#``%S/F8/;L!F#W#``(/Y('(<\P]_ -M!_,/?T<0@\<@@^D@@_D@<^SWP1\```!T8HU\.>#S#W\'\P]_1Q"+1"0$B_K# -M]\$#````=`Z(!T>#Z0'WP0,```!U\O?!!````'0(B0>#QP2#Z03WP?C___]T -M((VD)`````"-FP````")!XE'!(/'"(/I"/?!^/___W7MBT0D!(OZP\S,S,S, -MS%=6BW0D$(M,)!2+?"0,B\&+T0/&._YV"#OX#X*4`@``@_D@#X+2!```@?F` -M````-?P0/NN<# -M$(/I,&8/;T8@9@]O;C"-=C"#^3!F#V_39@\Z#]D,9@]_'V8/;^!F#SH/P@QF -M#W]'$&8/;\UF#SH/[`QF#W]O((U_,'VWC78,Z:\```!F#V].^(UV^(U)`&8/ -M;UX0@^DP9@]O1B!F#V]N,(UV,(/Y,&8/;]-F#SH/V0AF#W\?9@]OX&8/.@_" -M"&8/?T<09@]OS68/.@_L"&8/?V\@C7\P?;>-=@CK5F8/;T[\C7;\B_]F#V]> -M$(/I,&8/;T8@9@]O;C"-=C"#^3!F#V_39@\Z#]D$9@]_'V8/;^!F#SH/P@1F -M#W]'$&8/;\UF#SH/[`1F#W]O((U_,'VWC78$@_D0?!/S#V\.@^D0C7809@]_ -M#XU_$.OH#[KA`G,-BP:#Z02-=@2)!XU_!`^ZX0-S$?,/?@Z#Z0B-=@AF#]8/ -MC7\(BP2-M/E!`/_@]\<#````=!.*!H@'28/&`8/'`??'`P```'7MB]&#^2`/ -M@JX"``#!Z0+SI8/B`_\DE;3Y00#_)(W$^4$`D,3Y00#,^4$`V/E!`.SY00"+ -M1"0,7E_#D(H&B`>+1"0,7E_#D(H&B`>*1@&(1P&+1"0,7E_#C4D`B@:(!XI& -M`8A'`8I&`HA'`HM$)`Q>7\.0C30QC3PY@_D@#X)1`0``#[HE<.9#``$/@I0` -M``#WQP,```!T%(O7@^(#*\J*1O^(1_].3X/J`77S@_D@#X(>`0``B]'!Z0*# -MX@.#[@2#[P3]\Z7\_R258/I!`)!P^D$`>/I!`(CZ00"<^D$`BT0D#%Y?PY"* -M1@.(1P.+1"0,7E_#C4D`BD8#B$<#BD8"B$<"BT0D#%Y?PY"*1@.(1P.*1@*( -M1P**1@&(1P&+1"0,7E_#]\#___]UW??!_/___W05@^\$@^X$BP:)!X/I!/?!_/___W7KA#Z0%U\8M$)`Q>7\/K`\S,S(O&@^`/A<`/A>,```"+T8/A?\'J -M!W1FC:0D`````(O_9@]O!F8/;TX09@]O5B!F#V]>,&8/?P=F#W]/$&8/?U<@ -M9@]_7S!F#V]F0&8/;VY09@]O=F!F#V]^<&8/?V=`9@]_;U!F#W]W8&8/?W]P -MC;:`````C;^`````2G6CAH%A=)T(8V;`````/,/;P;S#V].$/,/ -M?P?S#W]/$(UV((U_($IUY8/A'W0PB\'!Z0)T#XL6B1>#QP2#Q@2#Z0%U\8O( -M@^$#=!.*!H@'1D=)=?>-I"0`````C4D`BT0D#%Y?PXVD)`````"+_[H0```` -M*]`KRE&+PHO(@^$#=`F*%H@71D=)=??!Z`)T#8L6B1>-=@2-?P1(=?-9Z>G^ -M__]5B^R#[!BA:.9#`(U-Z(-EZ``SP8M-"(E%\(M%#(E%](M%%$#'1>P`_T$` -MB4WXB47\9*$`````B47HC47H9*,`````_W484?]U$.@])P``B\B+1>ADHP`` -M``"+P8OE7<-5B^R#[#A3@7T((P$``'42N-/]00"+30R)`3/`0.FV````@V7( -M`,=%S,7_00"A:.9#`(U-R#/!B470BT48B474BT4,B478BT4P`B67DB6WH9*$`````B47(C47(9*,`````QT7X`0```(M% -M"(E%\(M%$(E%].BJ)0``BT`(B47\BTW\_Q5@,D,`C47P4(M%"/\P_U7\65F# -M9?@`@WWL`'079(L=`````(L#BUW(B0-DB1T`````ZPF+1+?0B+3PR+T8M?$(E-_(7V>#9KP12#P`@#PX/Y_W1) -MBWT0@^@423EX_(M]"'T*BWT0.SB+?0A^!8/Y_W4'BU7\3HE-_(7V>=*+111! -MB0B+11B)$#M7#'<0.\IW#&O!%%]>`\-;B^5=P^B[=@``S%6+[%%3BT4,@\`, -MB47\9(L=`````(L#9*,`````BT4(BUT,BVW\BV/\_^!;B^5=P@@`58OL45%3 -M5E=DBS4`````B77XQT7\U?Y!`&H`_W4,_W7\_W4(_Q70,4,`BT4,BT`$@^#] -MBTT,B4$$9(L]`````(M=^(D[9(D=`````%]>6XOE7<((`%6+[%;\BW4,BTX( -M,\[HZ.___VH`5O]V%/]V#&H`_W40_W80_W4(Z)$Q``"#Q"!>7<-5B^R+30Q6 -MBW4(B0[H&B0``(M()(E.!.@/)```B7`DB\9>7<-5B^Q6Z/XC``"+=0@[<"1U -M$.CQ(P``C4@DBT8$B0%>7#^R`/@J$$``"+!CL"#X2`````#[;X#[8"*_AT%C/)A?\/ -MG\&-#$W_____A0<```^V?@D/MD() -M*_AT%C/)A?\/G\&-#$W_____A@& -M```/MGX-#[9"#2OX=!8SR87_#Y_!C0Q-_____X7)#X7&!@``#[9^#@^V0@XK -M^'06,\F%_P^?P8T,3?____^%R0^%I`8```^V3@\/MD(/*\AT$C/`A8-``"+1N,[0N-T=0^V^`^V0N,K^'02,\F% -M_P^?P8T,3?____^%R773#[9^Y`^V0N0K^'02,\F%_P^?P8T,3?____^%R76U -M#[9^Y0^V0N4K^'02,\F%_P^?P8T,3?____^%R767#[9.Y@^V0N8KR'02,\"% -MR0^?P(T,1?_____K`C/)A?7__P^V?N\/MD+O*_AT%C/)A?\/G\&-#$W_____AF,````BU4(BW4,#[8*#[8&*\AT$C/`A6UW#B_^D"4(`P`U"``420@`[ -M%D(`(0E"`"D-0@!N$4(`I!5"`(H(0@"1#$(`UA!"``T50@#R!T(`^@M"`#\0 -M0@!U%$(`6P="`&,+0@"H#T(`WA-"`,0&0@#,"D(`$0]"`$<30@`M!D(`-0I" -M`'H.0@"P$D(`E@5"`*X)0@#C#4(`&!)"`%.+W%%1@^3P@\0$58MK!(EL)`2+ -M[(M+"(/L((,]&`U&``%FBU,,?$8/M\)F#V[`\@]PP`!F#W#0`(O!)?\/```] -M\`\``'<\#Q`!9@_OR68/=LD#[+"X/I!%&+`8MP((O.BW@8Z)[6____UHE=^(E]_(7_=`SV -M!PAT!\=%]`!`F0&-1?10_W7P_W7D_W7@_Q64,4,`7UY;B^5=P@@`S,S,S,S, -MS,S,S(,]&`U&``%R7P^V1"0(B]#!X`@+T&8/;MKR#W#;``\6VXM4)`2Y#P`` -M`(/(_R/*T^`KT?,/;PIF#^_29@]TT68/=,MF#^O19@_7RB/(=0B#R/^#PA#K -MW`^\P0/"9@]^VC/).A`/1<'#,\"*1"0(4XO8P>`(BU0D"/?"`P```'05B@J# -MP@$ZRW19A,ET4??"`P```'7K"]A7B\/!XQ!6"]B+"K___OY^B\&+]S/+`_`# -M^8/Q_X/P_S//,\:#P@2!X0`!`8%U(24``0&!=-,E``$!`74(@>8```"`=<1> -M7ULSP,.-0O];PXM"_#K#=#:$P'3J.N-T)X3D=.+!Z!`ZPW05A,!TUSKC=`:$ -MY'3/ZY%>7XU"_UO#C4+^7E];PXU"_5Y?6\.-0OQ>7UO#58OL5C/V@ST8#48` -M`GTMBTT(B]%FBP&#P0)FA7,!```/NB4< -M#48``7,)\Z2+1"0,7E_#B\-=@SI -MKP```&8/;T[XC7;XC4D`9@]O7A"#Z3!F#V]&(&8/;VXPC78P@_DP9@]OTV8/ -M.@_9"&8/?Q]F#V_@9@\Z#\((9@]_1Q!F#V_-9@\Z#^P(9@]_;R"-?S!]MXUV -M".M69@]O3OR-=OR+_V8/;UX0@^DP9@]O1B!F#V]N,(UV,(/Y,&8/;]-F#SH/ -MV01F#W\?9@]OX&8/.@_"!&8/?T<09@]OS68/.@_L!&8/?V\@C7\P?;>-=@2# -M^1!\$_,/;PZ#Z1"-=A!F#W\/C7\0Z^@/NN$"V+T8/Y(`^"K@(``,'I`O.E@^(#_R25=!U"`/\DC80=0@"0 -MA!U"`(P=0@"8'4(`K!U"`(M$)`Q>7\.0B@:(!XM$)`Q>7\.0B@:(!XI&`8A' -M`8M$)`Q>7\.-20"*!H@'BD8!B$#X@,KRHI&_XA'_TY/@^H! -M=?.#^2`/@AX!``"+T<'I`H/B`X/N!(/O!/WSI?S_))4@'D(`D#`>0@`X'D(` -M2!Y"`%P>0@"+1"0,7E_#D(I&`XA'`XM$)`Q>7\.-20"*1@.(1P.*1@*(1P*+ -M1"0,7E_#D(I&`XA'`XI&`HA'`HI&`8A'`8M$)`Q>7\/WQP\```!T#TE.3XH& -MB`?WQP\```!U\8'Y@````')H@>Z`````@>^`````\P]O!O,/;TX0\P]O5B#S -M#V]>,/,/;V9`\P]O;E#S#V]V8/,/;WYP\P]_!_,/?T\0\P]_5R#S#W]?,/,/ -M?V=`\P]_;U#S#W]W8/,/?W]P@>F`````]\&`____=9"#^2!R(X/N((/O(/,/ -M;P;S#V].$/,/?P?S#W]/$(/I(/?!X/___W7=]\'\____=!6#[P2#[@2+!HD' -M@^D$]\'\____=>N%R70/@^\!@^X!B@:(!X/I`77QBT0D#%Y?P^L#S,S,B\:# -MX`^%P`^%XP```(O1@^%_P>H'=&:-I"0`````B_]F#V\&9@]O3A!F#V]6(&8/ -M;UXP9@]_!V8/?T\09@]_5R!F#W]?,&8/;V9`9@]O;E!F#V]V8&8/;WYP9@]_ -M9T!F#W]O4&8/?W=@9@]_?W"-MH````"-OX````!*=:.%R71?B]'!Z@6%TG0A -MC9L`````\P]O!O,/;TX0\P]_!_,/?T\0C78@C7\@2G7E@^$?=#"+P<'I`G0/ -MBQ:)%X/'!(/&!(/I`77QB\B#X0-T$XH&B`=&1TEU]XVD)`````"-20"+1"0, -M7E_#C:0D`````(O_NA`````KT"O*48O"B\B#X0-T"8H6B!=&1TEU]\'H`G0- -MBQ:)%XUV!(U_!$AU\UGIZ?[__U6+[%>+?0B`?P0`=$B+#X7)=$*-40&*`4&$ -MP'7Y*\I35HU9`5/H]1<``(OP687V=!G_-U-6Z.9F``"+10R+SH/$##/VB0C& -M0`0!5NC*%P``65Y;ZPN+30R+!XD!QD$$`%]=PU6+[%:+=0B`?@0`=`C_-NBC -M%P``68,F`,9&!`!>7+?0R+!H/X_G0-BTX$ -M`\\S##CHR\W__XM&"(M.#`//,PPX7UY=Z;C-___,S,S,S,S,S,S,S,S,S%6+ -M[(/L'%-6BW4,5\9%_P#'1?0!````BUX(C480,QUHYD,`4%.)1>R)7?CHD/__ -M_XM]$%?HQQ```(M%"(/$#/9`!&8/A;H```")1>2-1>2)?>B+?@R)1OR#__X/ -MA,D```"-1P*-!$>+3(,$C02#BQB)1?"%R71EC580Z(\1``"Q`8A-_X7`>&9^ -M58M%"($X8W-MX'4W@SW(54,``'0N:,A50P#HV/@``(/$!(7`=!J+-3KV!O`@\@!7,_96Z!!D``!97E?_%00P -M0P!?B\-;PVA`(T(`Z&$1``"C@.9#`%F#^/]U`S+`PVA4$$8`4.CV$0``65F% -MP'4'Z`4```#KY;`!PZ&`YD,`@_C_=`Y0Z&(1``"##8#F0P#_6;`!P\S,S,S, -MS%6+[(/L!%-1BT4,@\`,B47\BT4(5?]U$(M-$(MM_.C)$P``5E?_T%]>B]U= -MBTT058OK@?D``0``=06Y`@```%'HIQ,``%U96\G"#`#,S,S,:@AHR+E#`.@$ -MR___BT4(AX$X8W-MX'5S@W@0`W5M@7@4(`63&702@7@4(063&70)@7@4 -M(@63&752BT@#9?P`4O]P&.C/"```QT7\_O___^LN,\`X -M10P/E<##BV7HZ")0``#V`1!T&(M`&(L(AC2]_[_QP;054,`B\9>7<($`(-A -M!`"+P8-A"`#'003854,`QP'054,`P\S,S,S,S,S,S,S,S,Q5B^Q6B_&-1@3' -M!FA50P!0Z%+[___V10@!670*:@Q6Z*&___]968O&7EW"!`!J.&B`N4,`Z/?) -M__^+11B)1>2#9<0`BUT,BT/\B474BWT(_W<8C46X4.A6V?__65F)1=#H=_W_ -M_XM`$(E%S.AL_?__BT`4B47(Z&']__^)>!#H6?W__XM-$(E(%(-E_``SP$") -M1<")1?S_=2#_=1S_=1C_=113Z)S6__^#Q!2)1>2#9?P`Z9````#_=>SHWP$` -M`%G#BV7HZ!/]__^#8"``BU44BUT,@7H$@````'\&#[Y#".L#BT,(B47@BWH0 -M,\F)3=@Y2@QV.FO9%(E=W#M$.P2+70Q^(HM=W#M$.PB+70Q_%FO!%(M$.`1` -MB47@BTH(BP3!B47@ZPE!B4W8.TH,2#?<0`=2F%VW0E_W<8Z%38__]9 -MA+?0QT$O]U(/]U'%?_=0CH,P8``(/$$(-]+`#_=0AU`U?K`_]U+.C5 -MUO__5HMU)/\V_W48_W445^@,"```BT8$0&@``0``_W4HB4<(BT4<_W`,_W48 -M_W405_]U".BA_?__@\0L7H7`=`=74.A>UO__7UW#58OLBT4(BP"!.&-S;>!U -M-H-X$`-U,(%X%"`%DQET$H%X%"$%DQET"8%X%"(%DQEU%8-X'`!U#^@"^___ -M,\E!B4@@B\%=PS/`7<-5B^R#[$13BUT,5E>+?1C&1=@`QD7_`(%_!(````!_ -M!@^^0PCK`XM#"(E%^(/X_P^,[@(``#M'!`^-Y0(``(MU"($^8W-MX`^%GP(` -M`(-^$`,/A!U*X-^$`-U)8%^%"`%DQET$H%^%"$%DQET"8%^%"(% -MDQEU"H-^'``/A$("``#H#OK__X-X'`!T0>@#^O__BT`!6 -M@V`<`.AZ`P``65F$P'4>_W7@Z`@$``!9A,`/A`,"``#I`P(``(M-$(E-].L& -MBTWTBT7X@3YCR+6?R%VXE=Y(M=#`^.E@```(M&'(M-[(M`#(L0@\`$B470BT7D -MB57,BWW0B7WPBWT8B57A.!P``@\0,A2)3>R%P'XNBU7,Z[/_==B+1?#_=23& -M1?\!_W4@_W7(_S#_=>Q7_W44_W7T4U;HY/S__X/$+(M5Z(M-X(M%^$*#P12) -M5>B)3>`[5=0/@B;___^`?1P`=`IJ`5;HM/G__UE9@'W_``^%@0```(L')?__ -M_Q\](063&7)S@W\<`'4,]D<@!'1G@WT@`'5A]D<@!'5M_W<<5NC$`0``65F$ -MP'5,Z"KX___H)?C__^@@^/__B7`0Z!CX__^#?20`BTWT5HE(%'5?4^M?BTT0 -M@W\,`'8<@'T<`'4H_W4D_W4@4%?_=1114U;H6@```(/$(.C>]___@W@<`'4' -M7UY;B^5=P^BC20``:@%6Z`CY__]968U-O.BY^?__:%RZ0P"-1;Q0Z!CM____ -M=23H\]+__VK_5_]U%%/H,`0``(/$$/]W'.B:^___S%6+[%%15XM]"($_`P`` -M@`^$^P```%-6Z'#W__^+71B#>`@`=$5J`/\5U#%#`(OPZ%CW__\Y<`AT,8$_ -M34]#X'0I@3]20T/@="'_=23_=2!3_W44_W40_W4,5^CUT/__@\0PP`#X2A````C47\4(U%^%#_=1S_=2!3Z*G1__^+3?B#Q!2+5?P[RG-Y -MC7`,BT4<.T;T?&,[1OA_7HL&BWX$P>`$BWP'](7_=!.+5@2+7`+TBU7\@'L( -M`(M=&'4XBWX$@\?P`\>+?0CV`$!U*&H!_W4DC4[T_W4@46H`4%/_=13_=1#_ -M=0Q7Z-SZ__^+5?R#Q"R+3?B+11Q!@\84B4WX.\IRC5Y;7XOE7%]@^$@@```(L^,]N%_WYQBT4(B].)7?R+0!R+0`R+"(/` -M!(E-\(E%Z(O(BT7PB4WTB47XA+?0@S]CDW?B6+WHM'!&AD[D,` -MBT0#!(/`!%#H4?7__UE9A2% -MP'03B\CHN\#___]5Y(O(ZQ#H0D8``(M%"/;!"'04BT@8A@3A-3T/@=!:!.&-S;>!U(>B(\___@V`8`.E610``Z'KS__^#>!@`?@CH -M;_/___](&#/`7<-J$&A8N4,`Z+"___^+11"!>`2`````BT4(?P8/OG`(ZP.+ -M<`B)=>3H///___]`&(-E_``[=11T7(/^_WY2BTT0.W$$?4J+00B+%/")5>#' -M1?P!````@WSP!`!T)XM%"(E0"&@#`0``4(M!"/]T\`3HZ//__^L-_W7LZ#W_ -M__]9PXMEZ(-E_`"+=>")=>3KI.BK1```QT7\_O___^@4````.W44=>J+10B) -M<`CH4K___\.+=>3HK_+__X-X&`!^".BD\O___T@8PU6+[%-65_]U$.B&`0`` -M6>B,\O__BTT8,_:+50B[____'[\B!9,9.7`@=2*!.F-S;>!T&H$Z)@``@'02 -MBP$CPSO'<@KV02`!#X6G````]D($9G0E.7$$#X28````.74<#X6/````:O]1 -M_W44_W4,Z,7^__^#Q!#K?#EQ#'4:BP$CPSTA!9,9<@4Y<1QU"CO'!U.8-Z$`-R,SEZ%'8NBT(7<.+ZHOQB\%J`>C#!```,\`SVS/),](S___F58OL4U97:@!2:*(S -M0@!1Z-#F``!?7EM=PU6+;"0(4E'_="04Z*G^__^#Q`Q=P@@`5E>_@!!&`#/V -M:@!HH`\``%?H?@(``(/$#(7`=!7_!9@01@"#QAB#QQB#_AARV[`!ZP?H!0`` -M`#+`7U[#5HLUF!!&`(7V="!KQAA7C;AH$$8`5_\5U#!#`/\-F!!&`(/O&(/N -M`77K7[`!7L-5B^RA:.9#`(/@'VH@62O(BT4(T\@S!6CF0P!=PU6+[(M%"#/) -M4U97C1R%K!!&`#/`\`^Q"XL5:.9#`(//_XO*B_*#X1\S\-/.._=T:87V=`2+ -MQNMCBW40.W44=!K_-NA9````687`=2^#Q@0[=11U[(L5:.9#`#/`AM5BQR=Z%5#`%9H``@``&H`4_\5[#%#`(OPA?9U)_\5`#!# -M`(/X5W4-5E93_Q7L,4,`B_#K`C/VA?9U"8/(_X<',\#K$8O&AP>%P'0'5O\5 -MB#!#`(O&7E];7<-5B^Q6:(Q60P!HA%9#`&B,5D,`:@3HQ?[__XOP@\00A?9T -M#_]U"(O.Z`RZ____UEY=PUY=_R7<,4,`58OL5FB@5D,`:)A60P!HH%9#`&H% -MZ(O^__^#Q!"+\/]U"(7V=`N+SNC2N?___];K!O\5Z#%#`%Y=PU6+[%9HL%9# -M`&BH5D,`:+!60P!J!NA1_O__@\00B_#_=0B%]G0+B\[HF+G____6ZP;_%>`Q -M0P!>7<-5B^Q6:,160P!HO%9#`&C$5D,`:@?H%_[__X/$$(OP_W4,_W4(A?9T -M"XO.Z%NY____UNL&_Q7D,4,`7EW#58OL5FC85D,`:-!60P!HV%9#`&H(Z-K] -M__^+\(/$$(7V=!3_=1"+SO]U#/]U".@;N?___];K#/]U#/]U"/\5V#%#`%Y= -MPZ%HYD,`NM`01@!6@^`?,_9J(%DKR+BL$$8`T\XSR3,U:.9#`#O0&]*#XO># -MP@E!B3"-0`0[RG7V7L-5B^R`?0@`=2=6OIP01@"#/@!T$(,^_W0(_S;_%8@P -M0P"#)@"#Q@2!_JP01@!UX%Y=PZ%HYD,`@^`?:B!9*\@SP-/(,P5HYD,`H]`0 -M1@##S,S,S,S,S,S,S,S,S,S,58OL4U9756H`:@!H2#="`/]U".@JXP``75]> -M6XOE7<.+3"0$]T$$!@```+@!````=#*+1"04BTC\,\CHBK?__U6+:!"+4"A2 -MBU`D4N@4````@\0(78M$)`B+5"00B0*X`P```,-35E>+1"0055!J_FA0-T(` -M9/\U`````*%HYD,`,\10C40D!&2C`````(M$)"B+6`B+<`R#_O]T.H-\)"S_ -M=`8[="0L=BV--':+#+.)3"0,B4@,@WRS!`!U%V@!`0``BT2S".A)````BT2S -M".A?````Z[>+3"0$9(D-`````(/$&%]>6\,SP&2+#0````"!>010-T(`=1"+ -M40R+4@PY40AU!;@!````PU-1NY#F0P#K"U-1NY#F0P"+3"0,B4L(B4,$B6L, -M55%06%E=65O"!`#_T,-6Z._J__^+<`2%]G0)B\[H);?____6Z+$\``#,B_]5 -MB^R+10AFBPB#P`)FAEM4```B_]5B^R+50Q6BW4(5P^W.@^W#BO/=14K\F:%_W0.@\("#[06#R/]=PS/`A#`[ -M\W8LZV*+A8S[__^#R`!T4X7;=!N%]GD',\!FB0?K$(N%F/O__SO#=%`SR6:) -M#$>-C>3[___HY00``("]B/O__P!T#8N-?/O__X.A4`,``/U?B\9>BTW\,\U; -MZ)&R__^+Y5W#A=MU!8/._^O#BX68^___.\-ULVK^7C/`9HE$7_[KK8.Y!`0` -M``!U!K@``@``PXN!``0``-'HPXO_58OL48/(_S/25HMU"/?V5X/@_HOY@_@" -MB^5=P@0`B_]5B^R+111(@^@!="Z#Z`%T)8/H"70@@WT4 -M#70>BD40/&-T"#QS=`0RR>L"L0$SP(3)#Y3`7<.P`5W#,L!=PXO_58OLBT44 -M2(/H`70]@^@!=#2#Z`ET+X-]%`UT*8M%"#/)@^`$L@$+P74"BM%F@WT08W0' -M9H-]$'-U`K$!,\`ZT0^4P%W#L`%=PS+`7<.+_U:+\5>+O@0$``#HPO[__X7_ -M=00#QNL"`\=?7L.+_U6+[%-6B_%7C4Y`B[D$!```A?]U`HOYZ)?^__^+70A( -M`_B)?C2+3BB%R7\$A=MT,#/2B\/W=0Q)@,(PB4XHB]B`^CE^$8!]$``/E,#^ -MR"3@!&$L.@+0BT8TB!#_3C3KQ8M&-"OXB7XX0%^)1C1>6UW"#`"+_U6+[%%1 -M4U:+\5>-3D"+N00$``"%_W4"B_GH(/[__XM5#$B+70@#^(E^-(M.*(7)?P:+ -MPPO"=#IJ`/]U$(U!_U)3B48HZ&G=``"`P3")7?R+V(#Y.7X1@'T4``^4P/[( -M).`$82PZ`LB+1C2("/].-.NYBT8T*_B)?CA`7XE&-%Y;B^5=PA``B_]5B^Q6 -M,_8Y=1!^'%>+?12+30A7_W4,Z$D8``"#/_]T!D8[=1!\Z5]>7<.+_U6+[%8S -M]CEU$'XA4V8/OET,5XM]%(M-"%=3Z%L8``"#/_]T!D8[=1!\ZU];7EW#B_]5 -MB^Q1,\")3?R)`8E!!(E!"(E!#(E!$(E!%(E!&(E!'(E!((E!)(E!*&:)03") -M03B(03R)@4`$``")@40$``"+P8OE7<.+_U6+[%$STHE-_#/`B1%FB4$RB\&) -M402)40B)40R)41")412)41B)41R)42")422)42B(43")43B(43R)D4`$``") -MD40$``"+Y5W#B_]5B^Q6B_'H8/___XM%"(L`B89(!```BT4,B0:+11")1@2+ -M11B)1@B+112)1A"+11R)1A2+QEY=PA@`B_]5B^Q6B_'H:____XM%"(L`B89( -M!```BT4,B0:+11")1@2+11B)1@B+112)1A"+11R)1A2+QEY=PA@`B_]5B^Q6 -M_W42P`` -MB48,B\9>7<(8`(O_58OL5XOYBTT(QD<,`(7)=`J+`8E'!(M!!.L6H6P21@"% -MP'42H1#H0P")1P2A%.A#`(E'".M$5NC140``C5<$B0=2C7<(BTA,B0J+2$A0 -MB0[H#5,``%;_-^@R4P``BP^#Q!"+@5`#``!>J`)U#8/(`HF!4`,``,9'#`&+ -MQU]=P@0`B_]6B_'_M@0$``#HQ48``(.F!`0```!97L.+_U6+[%:+\?\VZ*Q& -M``"+50B#)@!9BP*)!HO&@R(`7EW"!`"+_U6+[(M%#(M-"%.+`(N`B````(L` -MBACK!3K#=`=!B@&$P'7UB@%!A,!T*.L)/&5T"SQ%=`=!B@&$P'7QB]%)@#DP -M=/HX&74!28H"04*(`83`=?9;7<.+_U6+[(I-"(U!X#Q:=P\/OL$/MH@X7D,` -M@^$/ZP(SR8M%#`^VA,A87D,`P>@$7<((`(O_58OLBTT(C4'@9H/X6G)1A"P`>L",L"#/P!U!H7;=`*)'U]>6XOE7<($`(O_5HOQ -MC8Y(!```Z-43``"$P'4%@\C_7L-3,]LY7A`/A;L```#H%DD``,<`%@```.CJ -M1P``@\C_Z;D```")7CB)7ASIA0```/]&$#E>&`^,C````/]V'`^V1C&+SE#H -M(?[__XE&'(/X"'2Z@_@'=\7_)(4V1$(`B\[H.`(``.M%@TXH_XE>)(A>,(E> -M((E>+(A>/.LXB\[HH`$``.LGB\[HMPH``.L>B5XHZR&+SNCG`@``ZQ"+SN@O -M`P``ZP>+SN@+!@``A,`/A&C___^+1A"*`(A&,83`#X5K_____T80_X90!``` -M@[Y0!````@^%2O___XM&&%M>PXU)`+%#0@"Z0T(`ST-"`-A#0@#A0T(`YD-" -M`.]#0@#X0T(`B_]6B_&-CD@$``#HN1(``(3`=06#R/]>PU,SVSE>$`^%P``` -M`.CZ1P``QP`6````Z,Y&``"#R/_IO@```(E>.(E>'.F&````@T80`CE>&`^, -MD````/]V'`^W1C*+SE#H-OW__XE&'(/X"'2Y@_@'=\3_)(5614(`B\[H.@$` -M`.M%@TXH_XE>)(A>,(E>((E>+(A>/.LXB\[HP````.LGB\[HQ0D``.L>B5XH -MZR&+SNCR`0``ZQ"+SNA[`P``ZP>+SN@=!P``A,`/A&?___^+1A`/MP!FB48R -M9H7`#X5G____@T80`O^&4`0``(.^4`0```(/A47___^+1AA;7L.+_\Y$0@#7 -M1$(`[$1"`/5$0@#^1$(``T5"``Q%0@`514(`#[Y!,8/H('0M@^@#="*#Z`AT -M%TB#Z`%T"X/H`W4<@TD@".L6@TD@!.L0@TD@`>L*@TD@(.L$@TD@`K`!PP^W -M03*#Z"!T+8/H`W0B@^@(=!=(@^@!=`N#Z`-U'(-)(`CK%H-)(`3K$(-)(`'K -M"H-)("#K!(-)(`*P`PXU&&%`/MD8QC8Y(!```4.CF$```L`%>PXU1&,9!/`%2#[=1,H'!2`0` -M`%+H#!$``+`!PXO_5HOQ5[\`@```BT8(BDXQQD8\``^VT8L`BP!FA3Q0=#B- -M1AA048V.2`0``.B5$```BTX0B@&(1C&-00&`?C$`B480=13HO$4``,<`%@`` -M`.B01```,L#K`K`!7U["!`"`>3$J=`J-02A0Z)W[___#@T$4!(M!%(M`_(E! -M*(7`>02#22C_L`'#9H-Y,BIT"HU!*%#HT/O__\.#010$BT$4BT#\B4$HA2P`=>L```"+01"` -M.&AU$$#'02P!````B4$0Z=,```#'02P"````Z<<```#'02P-````Z;L```#' -M02P(````Z:\```"+41"*`CPS=1B`>@$R=1*-0@+'02P*````B4$0Z8X````\ -M-G45@'H!-'4/C4("QT$L"P```(E!$.MU/&1T%#QI=!`\;W0,/'5T"#QX=`0\ -M6'5=QT$L"0```.M4QT$L!0```.M+@_AL="J#^'1T'(/X=W0.@_AZ=3?'02P& -M````ZR['02P,````ZR7'02P'````ZQR+01"`.&QU#4#'02P$````B4$0ZP?' -M02P#````L`'##[=!,H/X1G4:BP&#X`B#R``/A6(!``#'01P'````Z8@#``"# -M^$YU)HL!:@A:(\*#R``/A4$!``")41SHK$,``,<`%@```.B`0@``,L##@WDL -M`'7G@_AJ#X_-````#X2^````@_A)=%.#^$QT0H/X5'0Q:FA:.\(/A?P```"+ -M01!F.1!U$H/``L=!+`$```")01#IX@```,=!+`(```#IU@```,=!+`T```#I -MR@```,=!+`@```#IO@```(M1$`^W`H/X,W499H-Z`C)U$HU"!,=!+`H```") -M01#IF@```(/X-G469H-Z`C1U#XU"!,=!+`L```")01#K?X/X9'09@_AI=!2# -M^&]T#X/X=70*@_AX=`6#^%AU8<=!+`D```#K6,=!+`4```#K3VIL6CO"="J# -M^'1T'(/X=W0.@_AZ=3G'02P&````ZS#'02P,````ZR?'02P'````ZQZ+01!F -M.1!U#X/``L=!+`0```")01#K!\=!+`,```"P`<.+_U6+[%%35HOQ,]M#,\D/ -MOD8Q@_AD?VP/A),```"#^%A_/G0W@_A!#X23````@_A#=#Z#^$1^'8/X1P^. -M@````(/X4W4/B\[HH0L``(3`#X6?````,L#IS0$``%-J$.M7@^A:=!6#Z`=T -M5DB#Z`%UY%&+SNA8"```Z]*+SNB]!```Z\F#^'!_370_@_AG?C&#^&ET'(/X -M;G0.@_AO=;:+SN@1"P``ZZ6+SNB4"@``ZYR#3B`046H*B\[H.@D``.N,B\[H -M/04``.N#B\[H!0L``.EW____@^AS#X1G____2(/H`730@^@##X5G____4>EI -M____@'XP`'0'BL/I*`$``(M6(#/`5V:)1?R+^(A%_HO"P>@$A,-T)XO"P>@& -MA,-T!L9%_"WK%H33=`;&1?PKZPR+PM'HA,-T!L9%_""+^XI.,8#Y>'0%@/E8 -M=0F+PL'H!83#=0(RVX#Y870)@/E!=`0RP.L"L`&$VW4$A,!T)\9$/?PP@/E8 -M=`F`^4%T!#+`ZP*P`83`#Y3`_L@DX`1XB$0]_8/'`HM>)"M>."O?]L(,=1:- -M1AA04XV&2`0``&H@4.@3\___@\00_W8,C4884%>-1?R-CD@$``!0Z!@-``"+ -M3B"-?AB+P<'H`Z@!=!O!Z0+VP0%U$U=3C89(!```:C!0Z-+R__^#Q!!J`(O. -MZ+,+``"#/P!\'8M&(,'H`J@!=!-74XV&2`0``&H@4.BG\O__@\00L`%?7EN+ -MY5W#B_]5B^R#[`RA:.9#`#/%B47\4U:+\3/;:D%::E@/MT8R68/X9']K#X22 -M````.\%_/G0V.\(/A)0```"#^$-T/X/X1'X=@_A'#XZ!````@_A3=0^+SNC8 -M"0``A,`/A:`````RP.GD`0``:@%J$.M7@^A:=!6#Z`=T5DB#Z`%UXU.+SNBK -M!@``Z]&+SNCC`@``Z\B#^'!_370_@_AG?C&#^&ET'(/X;G0.@_AO=;6+SNC4 -M"```ZZ2+SNA7"```ZYN#3B`04VH*B\[H_08``.N+B\[H6@0``.N"B\[HR`@` -M`.EV____@^AS#X1F____2(/H`730@^@##X5F____4^EI____.%XP#X5``0`` -MBU8@,\E7B\*)7?3!Z`1!9HE=^&H@7X3!="B+PL'H!H3!=`EJ+5AFB47TZQ2$ -MT70$:BOK\8O"T>B$P70&9HE]](O9#[=.,H/Y>'0(:EA89CO(=0V+PL'H!:@! -M=`2T`>L",N2#^6%T#&I!7V8[SW0$,L#K`K`!:C!?A.1U!(3`=#!J6%AFB7Q= -M]&8[R'0,:D%89CO(=`0RP.L"L`&$P`^4P/[().`$>&:89HE$7?:#PP*+?B0K -M?C@K^_;"#'46C4884%>-AD@$``!J(%#H[/#__X/$$/]V#(U&&%!3C47TC8Y( -M!```4.A8"P``BTX@C5X8B\'!Z`.H`70;P>D"]L$!=1-35XV&2`0``&HP4.BK -M\/__@\00:@"+SN@'"@``@SL`?!V+1B#!Z`*H`7034U>-AD@$``!J(%#H@/#_ -M_X/$$%^P`8M-_%XSS5OH:*#__XOE7<.`>3$J=`J-0210Z-OS___#@T$4!(M! -M%(M`_(E!)(7`>0>#22`$]UDDL`'#9H-Y,BIT"HU!)%#H"_3__\.#010$BT$4 -MBT#\B4$DA#1A0$BT84BWC\A?]T-HM? -M!(7;="__=BP/MD8Q4/]V!/\VZ+/M__^#Q!")7C2$P`^W!W0+T>B)1CC&1CP! -MZQ>)1CCK#L=&-+1>0P#'1C@&````QD8\`%]>L`%;PXO_4U:+\5>#1A0$BT84 -MBWC\A?]T-HM?!(7;="__=BP/MT8R4/]V!/\VZ)#M__^#Q!")7C2$P`^W!W0+ -MT>B)1CC&1CP!ZQ>)1CCK#L=&-+1>0P#'1C@&````QD8\`%]>L`%;PXO_58OL -M45%6B_%7@TX@$(M&*(7`>1V*1C$\870-/$%T"<=&*`8```#K'<=&*`T```#K -M%'42BD8Q/&=T!#Q'=0?'1B@!````BT8HC7Y`4[M=`0``B\\#PU#H..S__X3` -M=0R+S^@5[/__*\.)1BB+AP0$``"%P'4"B\>#9?@`@V7\`(E&-(-&%`B+3A2+ -M0?B)1?B+0?R+SXE%_.C?Z___BY\$!```B\B%VW4"B]__=@@/OD8Q_W8$_S;_ -M=BA048O/Z.;L__]0B\_HL>O__U"-1?A34.A)3```BT8@@\0HP>@%6Z@!=!.# -M?B@`=0W_=@C_=C3H'_'__UE9BD8Q/&=T!#Q'=1>+1B#!Z`6H`74-_W8(_W8T -MZ$#P__]968M&-(`X+74(@TX@0$")1C2+5C2*`CQI=`P\270(/&YT!#Q.=03& -M1C%SC7H!B@I"A,EU^2O7L`%?B58X7HOE7<.+_U6+[%%15E>+\6IG66I'@TX@ -M$(M&*%J%P'D@#[=&,H/X870.@_A!=`G'1B@&````ZR#'1B@-````ZQ=U%0^W -M1C)F.\%T!68[PG4'QT8H`0```(M&*(U^0%.[70$``(O/`\-0Z-+J__^$P'4, -MB\_HK^K__RO#B48HBX<$!```A>K__XN?!`0``(O(A=MU`HO?_W8(#[Y&,O]V!/\V_W8H -M4%&+S^B`Z___4(O/Z$OJ__]0C47X4U#HXTH``(M&((/$*,'H!5NH`703@WXH -M`'4-_W8(_W8TZ+GO__]960^W1C)J9UEF.\%T"&I'668[P747BT8@P>@%J`%U -M#?]V"/]V-.C1[O__65F+1C2`."UU"(-.($!`B48TBU8TB@(\:70,/$ET"#QN -M=`0\3G4':G-89HE&,HUZ`8H*0H3)=?DKU[`!7XE6.%Z+Y5W#B_]6B_%7_W8L -M#[9&,5#_=@3_-N@WZO__@\00C7Y`A,!T.8-&%`2+1A13BY\$!```#[=`_(7; -M=0*+WU"+S^AOZ?__4(U&.%-0Z/([``"#Q!!;AP@0` -MB_]5B^Q14U:+\5?&1CP!@T84!(M&%/]V+`^W6/P/MT8R4/]V!/\VZ-/I__^# -MQ!"-?D"$P'4RBX\$!```B%W\B$7]A17&1C`!ZP^+AP0$``"%P'4"B\=FB1B+AP0$``"%P'0"B_B)?C2P -M`5_'1C@!````7EN+Y5W"!`"+_U6+[%-6B_'_=BSHV?K__UF+V(O+@^D!='B# -MZ0%T5DF#Z0%T,X/I!'07Z$@$J`&+1A2+2/B+4/SK6(M&((-&%`3!Z`2H`8M&%'0%BT#\ZS^+2/PSTNL[ -MBT8@@T84!,'H!*@!BT84=`8/OT#\ZR$/MT#\ZQN+1B"#1A0$P>@$J`&+1A1T -M!@^^0/SK!`^V0/R9B\A7BWX@B\?!Z`2H`707A=)_$WP$A@'J`%T&H-^ -M.`!T"(M&-(`X,'0,_TXTBTXTQ@$P_T8XL`%>6UW""`"+_U:+\5>#1A0$BT84 -MBWC\Z()*``"%P'44Z`\W``#'`!8```#HXS4``#+`ZT3_=BSH:_G__UF#Z`%T -M*X/H`70=2(/H`700@^@$=)5P3K%8M&&(D'ZPYFBT889HD'ZP6* -M1AB(!\9&,`&P`5]>PXM1((O"P>@%J`%T"8'*@````(E1(&H`:@CH)/[__\-J -M`6H0QT$H"````,=!+`H```#H#/[__\.+_U-6B_%7@T84!(M&%(M^*(M8_(E> -M-(/__W4%O____W__=BP/MD8Q4/]V!/\VZ/_F__^#Q!"$P'0:A=MU!\=&-+Q> -M0P!7_W8TQD8\`>@=$@``ZQ2%VW4'QT8TM%Y#`%?_=C3HX!```%E97XE&.+`! -M7EO#B_]35HOQ5X-&%`2+1A2+?BB+6/R)7C2#__]U!;____]__W8L#[=&,E#_ -M=@3_-NC,YO__@\00A,!T'(7;=0?'1C2\7D,`5_]V-,9&/`'HJA$``%E9ZQ6% -MVW4'QT8TM%Y#`&H`5XO.Z`D```!?B48XL`%>6\.+_U6+[%97B_DS]HM7-#EU -M"'XE4XH"A,!T'0^VR+L`@```BT<(BP"+`&:%'$AT`4)"1CMU"'S=6U^+QEY= -MP@@`@SD`=1/H434``,<`%@```.@E-```,L##L`'#B_]5B^R+T8L*BT$(.T$$ -MBT4,=12`>0P`=`3_`.L#@PC_BP**0`SK%O\`BP+_0`B+`HL(BD4(B`&+`O\` -ML`%=P@@`B_]5B^R+T8L*BT$(.T$$BT4,=12`>0P`=`3_`.L#@PC_BP**0`SK -M&?\`BP+_0`B+`HL(9HM%"&:)`8L"@P`"L`%=P@@`B_]5B^R#[!"A:.9#`#/% -MB47\4U:+\5>`?CP`=%V+1CB%P'Y6BWXT,]N%P'1E#[<'C7\"@V7P`%!J!HU% -M]%"-1?!0Z!(W``"#Q!"%P'4F.47P="'_=@R-1AA0_W7PC47T4(V.2`0``.C& -M````0SM>.'6[ZQZ#3AC_ZQC_=@R-1AA0_W8XC8Y(!```_W8TZ*````"+3?RP -M`5]>,\U;Z)B6__^+Y5W"!`"+_U6+[%%14U:+\5>`?CP`=5:+1CB%P'Y/BUXT -M,_^%P'1>,\!FB47\BT8(4(L`_W`$C47\4U#H0C0``(/$$(E%^(7`?AV-3AA1 -M_W7\C8Y(!```Z+W^__\#7?A'.WXX=<+K'H-.&/_K&/]V#(U&&%#_=CB-CD@$ -M``#_=C3HG@```%]>L`%;B^5=P@0`B_]5B^Q14597BWT4B\&)1?B+#X,G`(L` -MB4W\BW`$.7`(=1B`>`P`=`J+31"+10P!`>M*BT40@PC_ZT4K<`A3BUT,._-R -M`HOS5O]U"/\PZ`J>__^+3?B#Q`R+`0$PBP$!<`B+`8!X#`"+11!T!`$8ZPL[ -M\W0%@PC_ZP(!,%N+3?R#/P!U!H7)=`*)#U]>B^5=PA``B_]5B^Q145.+712+ -MP5>)1?B+"X,C`(L0B4W\BWH$.7H(=1B`>@P`=`J+31"+10P!`>M1BT40@PC_ -MZTPK>@B+10P[^'("B_A6C30_5O]U"/\RZ'2=__^+3?B#Q`R+`0$PBP%>`7@( -MBP&`>`P`BT40=`>+30P!".L,.WT,=`6#"/_K`@$XBTW\@SL`=0:%R70"B0M? -M6XOE7<(0`(O_58OL_W4@_W4<_W48_W44_W40_W4,_W4(Z$S?__^#Q!Q=PXO_ -M58OL_W4@_W4<_W48_W44_W40_W4,_W4(Z*3@__^#Q!Q=P\S,S,S,S,S,B_]5 -MB^R#[!"-1?A0_Q7P,4,`A7<.+_U6+[(M-$%>+?0B%R70MBU4,*]GSJQ/)9O.KBT4(7UW#B_]5B^R+10@SR5-6 -M5V8Y"'0LBW4,#[<^B\YFA?]T%0^W&(O79CO3=!>#P0(/MQ%FA=)U\(/``C/) -M9CD(==HSP%]>6UW#B_]5B^R+10B9,\(KPEW#B_]5B^Q14:%HYD,`,\6)1?R+ -M10Q7BWT0A1&+10R+WBO:A?^+??AU#$_K"8M]^(T$%HE% -M##O#=J\S]HO&7EN+3?PSS5_H@I+__XOE7<.%_W3GBTT84/]U"/\58#)#`/]5 -M&(OP]]Y9&_;WUB-U#%GKRLR+_U6+[%&A:.9#`#/%B47\BTT(4XM=##O9=FR+ -M11!65XT4`8ORB_D[\W>7UZ+3?PSS5OHR)'__XOE7M>7UW#S,S,S,S,S(O_58OL@>P<`0``H6CF0P`SQ8E%_(M-"(M5#(F- -M_/[__U:+=12)M0#___]7BWT0B;T$____A@AD?__B^5=PX7_=-R%]G38QX7X_O__`````(/Z`@^"$@,` -M`$H/K]=3`]&)E0C___^+PC/2*\'W]XU8`8/["'<65E?_M0C___]1Z'W^__^# -MQ!#IMP(``-'K#Z_?`]E348O.B9WP_O___Q5@,D,`_]:#Q`B%P'X05U/_M?S^ -M___HZ/[__X/$#/^U"/___XO._[7\_O___Q5@,D,`_]:#Q`B%P'X55_^U"/__ -M__^U_/[__^BV_O__@\0,_[4(____B\Y3_Q5@,D,`_]:#Q`B%P'X05_^U"/__ -M_U/HCO[__X/$#(N%"/___XOXB[7\_O__BY4$____B87L_O__D#O>=C<#\HFU -M]/[__SOS+ -MSO\58#)#`/_6@\0(AC^__^) -MO>3^__\[]W0SB]Z+UXNUZ/[__RO?B@*-4@&*3!/_B$03_XA*_X/N`77KB[7T -M_O__BYWP_O__BY4$____BX4(____.]\/A?K^__^+WHF=\/[__^GM_O__`_H[ -MWW,RC:0D`````"OZ._MV)8N-`/___U-7_Q5@,D,`_Y4`____BY4$____@\0( -MA+SO\58#)#`/_6BY4$____@\0( -MA+O03____I*_W__XNU`/___^L&B[T$____BX7X_O__@^@!B87X_O__>!:+ -MC(4,____BU2%A(F-_/[__^GV_/__6XM-_%\SS5[HY(W__XOE76\/,S,S,S,S, -MS(M,)`Q7A#ZP%U[8M$)!!;7E_#]\<#````=!:(!X/'`8/I`0^$F````/?' -M`P```'7JB]G!Z0)U=(@'@\]\(``/\`=`SWP@```/]U -MQ(D7ZQB!XO__``")%^L.@>+_````B1?K!#/2B1>#QP0SP(/I`70,,\")!X/' -M!(/I`77V@^,##X5W____BT0D$%M>7\.+_U6+[(M5"(O"5KX`_P``B\HCQL'A -M$`/!B\K!Z0@CSL'@"`/!P>H8`\)>7<.+_U6+[(/L'(U-Y%/_=1#H$=W__XM= -M"('[``$``'-+C47H4%/H:P(``%E9A,!T)(!]\`"+1>B+@)@````/M@P8=`J+ -M1>2#H%`#``#]B\'I\@```(!]\`!T"HM-Y(.A4`,``/V+P^G;````,\!FB47\ -MB$7^BT7H@W@$`7XNB\.-3>C!^`B)1?11#[;`4.A+/@``65F%P'03BT7TB$7\ -M,\!J`HA=_8A%_EGK%NA**```,\G'`"H````SP(A=_$&(1?UFB47XC57XB$7Z -MBT7H:@'_<`AJ`U)1C4W\4?]U#/^PJ````(U%Z%#H&$$``(/$)(7`=1@X1?`/ -MA&?___^+1>2#H%`#``#]Z5C___^#^`%U%H!]\``/MD7X="N+3>2#H5`#``#] -MZQ\/ME7X#[9%^<'B"`O0@'WP`'0*BTWD@Z%0`P``_8O"6XOE7<.+_U6+[(/L -M'(U-Y%/_=1#HQ]O__XM="('[``$``'-+C47H4%/H/@$``%E9A,!T)(!]\`"+ -M1>B+@)0````/M@P8=`J+1>2#H%`#``#]B\'I\@```(!]\`!T"HM-Y(.A4`,` -M`/V+P^G;````,\!FB47\B$7^BT7H@W@$`7XNB\.-3>C!^`B)1?11#[;`4.@! -M/0``65F%P'03BT7TB$7\,\!J`HA=_8A%_EGK%N@`)P``,\G'`"H````SP(A= -M_$&(1?UFB47XC57XB$7ZBT7H:@'_<`AJ`U)1C4W\4?]U#/^PJ````(U%Z%#H -MSC\``(/$)(7`=1@X1?`/A&?___^+1>2#H%`#``#]Z5C___^#^`%U%H!]\``/ -MMD7X="N+3>2#H5`#``#]ZQ\/ME7X#[9%^<'B"`O0@'WP`'0*BTWD@Z%0`P`` -M_8O"6XOE7<.+_U6+[/]U#&H"_W4(Z%(```"#Q`SWV!O`]]A=PXO_58OL_W4, -M:@'_=0CH-0```(/$#/?8&\#WV%W#B_]5B^R+11"%P'0-BP"+"(M%"`^W!$'K -M#.C*.P``BTT(#[<$2"-%#%W#B_]5B^R+31"%R706BP&#>`0!?@Y1_W4,_W4( -MZ/T[``#K#%'_=0S_=0CHJ/___X/$#%W#B_]5B^S_=0QH``$``/]U".@*_O__ -M@\0,7<.+_U6+[/]U#&@``@``_W4(Z*;\__^#Q`Q=PXO_58OLH6P21@"%P'00 -M:@#_=0CHM/___UE9B\CK#HM-"(U!OX/X&7<#@\$@B\%=PXO_58OLH6P21@"% -MP'00:@#_=0CHGO___UE9B\CK#HM-"(U!GX/X&7<#@\'@B\%=PXO_58OLH1@- -M1@!65X/X!7Q\BW4(B]:#XA]J(%@KPO?:&](CT(M%##O"#X!\K^,7T5\D#^>L/Q?5T -M`<7]U\"%P'4'@\$@.\]U[8M%#`/&ZP:`.0!T!4$[R'7V*\[%^'?IE````(/X -M`7QUBW4(B]:#X@]J$%@KPO?:&](CT(M%##O"#X`\K^`/YZQ(/*`%F#W3!9@_7P(7` -M=0>#P1`[SW7JBT4,`\;K!H`Y`'0%03O(=?8KSNL:BU4(B\J+10P#PCO0=`J` -M.0!T!4$[R'7V*\I?B\%>7<.+_U6+[%&A&`U&`(M-"%97@_@%#XR\````]L$! -M=">+10R+T8T$03O(#X1]`0``,_]F.3H/A'(!``"#P@([T'7PZ68!``"+\8/F -M'VH@6"O&]]X;]B/PBT4,T>X[QG,"B_"-%'$S_XE5_(O1.TW\=`UF.3IT"(/" -M`CM5_'7S*]'1^CO6#X4G`0``C111B\@KSHO!@^`?*\C%]%?)C0Q*ZP_%]74" -MQ?W7P(7`=0>#PB`[T77MBT4(BTT,C0Q(ZPAF.3IT!X/"`CO1=?0KT-'ZQ?AW -MZ=H```"#^`$/C+,```#VP0%T)XM%#(O1C01!.\@/A+@````S_V8Y.@^$K0`` -M`(/"`CO0=?#IH0```(OQ@^8/:A!8*\;WWAOV(_"+10S1[CO&#P@([T77T*]#K'(M%#(O1C01!.\AT#C/_9CDZ=`>#P@([T'7T*]'1^E^+ -MPEZ+Y5W#B_]5B^R+10BH!'0$L`%=PZ@!=!N#X`)T"8%]#````(!WZH7`=0F! -M?0S___]_=]TRP%W#B_]5B^R+10B+31"+50R)$(E(!(7)=`*)$5W#B_]5B^R# -M["B-30Q35^BA[/__A,!T(8M]%(7_=#"#_P)\!8/_)'XFZ.(A``#'`!8```#H -MMB```#/;BU40A=)T!8M-#(D*7XO#6XOE7<-6_W4(C4W8Z.'5__^+10PS]HEU -M](E%Z.L#BT4,BAA`B44,C47<4`^VPVH(4(A=_.B,^___@\0,A1HA=_(EU#.L#BW4,A?]T!8/_ -M$'5XBL,L,#P)=P@/OL.#P-#K(XK#+&$\&7<(#[[#@\"IZQ.*PRQ!/!EW"`^^ -MPX/`R>L#@\C_AL3BL,L03P9=P@/ -MOLN#P1HA=_(EU#.N8_W7\C4T,B57XZ%('``"+7?CVPPAU"HM%Z#/; -MB44,ZT&+=?164^C;_?__65F$P'0HZ"P@``#'`"(```#VPP%U!8/._^L:]L," -M=`>[````@.L0N____W_K"?;#`G0"]]Z+WH!]Y`!>#X0@_O__BT78@Z!0`P`` -M_>D1_O__B_]5B^R#[!R-30Q35^AYZO__A,!T(XM%%&H"7X7`="\[QWP%@_@D -M?B;HN!\``,<`%@```.B,'@``,]N+51"%TG0%BTT,B0I?B\-;B^5=PU;_=0B- -M3>3HM]/__XM%##/VB77XB47TZP.+10P/MS`#QVH(5HE%#.CA.```65F%P'7G -M,]LX71@/E<-F@_XM=00+W^L&9H/^*W4.BWT,#[`7``#K,[@0&```9COPX&O\``&8[\',*#[?&+1#_``#K`X/(_X/X_W4P -M:D%89CO&=PAJ6EAF._!V"8U&GV8[1?QW%(U&GV8[1?P/M\9W`X/H((/`R>L# -M@\C_A#QP*)?0R#^'AT'H/X6'09A#QP*)?0R#R/\STO=U%(O( -M:C!89COP#X)5`@``:CI89COP`7``#K,[@0&```9COPX&O\` -M`&8[\',*#[?&+1#_``#K`X/(_X/X_W4P:D%89CO&=PAJ6EAF._!V"8U&GV8[ -M1?QW%(U&GV8[1?P/M\9W`X/H((/`R>L#@\C_@_C_=#$[111S+(MU^(/+"#OQ -M<@MU!#O"=@6#RP3K"0^O=10#\(EU^`^W-X/'`HE]#.DY_?__5HU-#.B2```` -M]L,(=0J+1?0SVXE%#.M!BW7X5E/H]O;__UE9A,!T*.A'&0``QP`B````]L,! -M=06#SO_K&O;#`G0'NP```(#K$+O___]_ZPGVPP)T`O?>B]Z`??``7@^$9?G_ -M_XM%Y(.@4`,``/WI5OG__XO_58OL_PF*10B+"83`=!0X`700Z.@8``#'`!8` -M``#HO!<``%W"!`"+_U6+[(,!_F:+10B+"6:%P'059CD!=!#HO!@``,<`%@`` -M`.B0%P``7<($`(O_58OL46H!:@I148O$:@#_=0A0Z&OV__^#Q`QJ`.A\]O__ -M@\04B^5=PXO_58OL@WT(`'4$,\!=PXM-"%O__B^5=PVH,:)BZ0P#HPWK__X-EY`!J`.@),@``68-E_`"+ -M-6CF0P"+SH/A'S,U(!%&`-/.B77DQT7\_O___^@+````B\;HT'K__\.+=>1J -M`.@@,@``6<-J#&BXND,`Z&&G``#H<1T``(MP#(7V=!Z#9?P`B\[_%6`R0P#_ -MUNL',\!`PXMEZ,=%_/[____H&!,``,R+_U6+[%%1H6CF0P`SQ8E%_%;HLQT` -M`(OPA?8/A$,!``"+%HO*4S/;5XV"D````#O0=`Z+?0@Y.70)@\$,.\AU]8O+ -MA".L0_W$$B5D(B\__ -M%6`R0P#_UXM%^%F)1@2#R/]?6XM-_#/-7N@<>/__B^5=PXO_58OL,\"!?0AC -MCH-_W_ -M_XMU$&H"Z$LO``!9P^C@( -MJ`%U$/]U"/\5##!#`%#_%B3#HIQ$``(O&Z?0```!35^C@ -M.P``:`0!``"^,!%&`#/_5E?_%?@Q0P"+'>`61@")->@61@"%VW0%@#L`=0*+ -MWHU%](E]_%"-1?R)??105U=3Z+$```!J`?]U]/]U_.@9`@``B_"#Q""%]G4, -MZ%X2``!J#%^)..LQC47T4(U%_%"+1?R-!(905E/H>0```(/$%(-]"`%U%HM% -M_$BCU!9&`(O&B_>CV!9&`(O?ZTJ-1?B)??A05NA.-@``B]A9687;=`6+1?CK -M)HM5^(O/B\(Y.G0(C4`$03DX=?B+QXD-U!9&`(E%^(O?B178%D8`4.A@#0`` -M68E]^%;H5@T``%E?B\-;7HOE7<.+_U6+[%&+1113BUT85HMU"%>#(P"+?1#' -M``$```"+10R%P'0(B3B#P`2)10PRR8A-_X`^(G4-A,FP(@^4P4:(3?_K-?\# -MA?]T!8H&B`='B@9&B$7^#[[`4.@;/@``687`=`S_`X7_=`6*!H@'1T:*1?Z$ -MP'09BDW_A,EUM3P@=`0\"76MA?]T!\9'_P#K`4[&1?\`@#X`#X3"````B@8\ -M('0$/`EU`T;K\X`^``^$K````(M-#(7)=`B).8/!!(E-#(M%%/\`,])",\#K -M`D9`@#Y<=/F`/B)U,:@!=1Z*3?^$R70/C4X!@#DB=02+\>L+BDW_,]*$R0^4 -M1?_1Z.L+2(7_=`3&!UQ'_P.%P'7QB@:$P'0[@'W_`'4(/"!T,3P)="V%TG0C -MA?]T`X@'1P^^!E#H0CT``%F%P'0,1O\#A?]T!8H&B`='_P-&Z7?___^%_W0$ -MQ@<`1_\#Z37___^+30Q?7EN%R70#@R$`BT44_P"+Y5W#B_]5B^Q6BW4(@?[_ -M__\_<@0SP.L]5X//_XM-##/2B\?W=1`[R',-#Z]-$,'F`BO^._EW!#/`ZQF- -M!#%J`5#H7PP``&H`B_#HBPL``(/$#(O&7UY=PXO_58OL7>D'_?__@STX$D8` -M`'0#,\##5E?H!CD``.@!/0``B_"%]G4%@\__ZRI6Z#````!9A+_NL,4.@S -M"@``C7\$BP=9A- -M?@3K$8M-"%;_%6`R0P#_50A9@\8$._=UZXM-_%\SS5[HX'#__XOE7<($`(O_ -M58OLBT4(BP`[!4021@!T!U#H>?___UE=P\S,S,S,B_]5B^R+10B+`#L%0!)& -M`'0'4.A9____65W#:"!^0@"Y.!)&`.AV____:$!^0@"Y/!)&`.AG_____S5$ -M$D8`Z"W_____-4`21@#H(O___UE9P^GP_?__:@QH`+M#`.@-3'1?S^____Z`T```"+QN@@3'1?S^____Z`T```"+QNC/A3BP"+&(7;=0B#R/_IZ0```(L5:.9#`%97BSN+\HM;!(/F'S/Z -MB77LB\XSVM//T\N%_P^$O@```(/__P^$M0```(E]](E=\&H@62O.,\#3R#/" -M@^L$.]]R8#D#=/6+,XM-[#/RT\Z+SHD#_Q5@,D,`_]:+1>B+%6CF0P"+\H/F -M'XEU[(L`BP"+"(M`!#/*B4WX,\*+SM--^-/(BTWX.TWT=0MJ(%D[1?!TH(M- -M^(E-](OYB47PB]CKCH/__W0-5^A[!P``BQ5HYD,`68O",]*#X!]J(%DKR-/* -MBTWH,Q5HYD,`BP&+`(D0BP&+`(E0!(L!BP")4`A?,\!>BTW\,\U;Z#9N__^+ -MY5W#B_]5B^R#[`R+P8E%^%:+`(LPA?9U"(/(_^D>`0``H6CF0P"+R%.+'H/A -M'U>+?@0SV(MV"#/X,_#3S]/.T\L[_@^%M````"OSN``"``#!_@([\'<"B\:- -M/#"%_W4#:B!?._YR'6H$5U/H[C@``&H`B47\Z+\&``"+3?R#Q!"%R74H:@2- -M?@174^C..```:@")1?SHGP8``(M-_(/$$(7)=0B#R/_ID0```(T$L8O9B47\ -MC32YH6CF0P"+??R#X!]J(%DKR#/`T\B+SS,%:.9#`(E%](O&*\>#P`/!Z`([ -M]QO2]](CT(E5_'00BU7T,\!`B1&-200[1?QU]8M%^(M`!/\PZ+K]__]3B0?H -M4K+__XM=^(L+BPF)`8U'!%#H0++__XL+5HL)B4$$Z#.R__^+"X/$$(L)B4$( -M,\!?6UZ+Y5W#B_]5B^S_=0AH2!)&`.A>````65E=PXO_58OL48U%"(E%_(U% -M_%!J`N@#_?__65F+Y5W#B_]5B^Q6BW4(A?9U!8/(_^LHBP8[1@AU'Z%HYD,` -M@^`?:B!9*\@SP-/(,P5HYD,`B0:)1@2)1@@SP%Y=PXO_58OL45&-10B)1?B- -M10R)1?R-1?A0:@+HROS__UE9B^5=P\S,S&A8YT,`N9`21@#H40$``+`!P\S, -MS,S,S,S,S,S,S,S,:$@21@#HZ%5J -M__^+Y5W#B_]5B^S_=0CHT_K__UFC9!)&`%W#B_]35NC9,```BS7@%D8`A?9U -M!;YH$D8`,MN*!CP@?PB$P'0JA-MT(#PB=06$VP^4PP^^P%#H,S0``%F%P'0! -M1D;KUSP@?P=&B@:$P'7UB\9>6\.+_U6+[%%1H6CF0P`SQ8E%_(M%#%-6BW4( -M*\:#P`-7,__!Z`(Y=0P;V_?3(]AT'(L&B47XA2+3?Q?7C/-6^B1:?__B^5=PXO_58OL4:%HYD,`,\6)1?Q6BW4(5^L7 -MBSZ%_W0.B\__%6`R0P#_UX7`=0J#Q@0[=0QUY#/`BTW\7S/-7NA,:?__B^5= -MPXO_58OLBT4(/0!```!T(ST`@```=!P]```!`'05Z*8&``#'`!8```#H>@4` -M`&H66%W#N0`71@"'`3/`7<,SP+EL$D8`0(#X?WK`X/)`HF.4`,``.L'@PV@[4,`_UY=PZ%P$D8`PXO_58OL -MBT4(A7<.+_U6+[(-]"`!U!#/`7<.+30B-40&*`4&$P'7Y*\I35XU9`5/H -M++'__XOX687_=01?6UW#_W4(4U?H&````(/$#(7`=02+Q^OG,\!04%!04.C& -M`P``S(O_58OLBU4(5H72=!&+30R%R70*BW40A?9U%\8"`.BS!```:A9>B3#H -MB`,``(O&7EW#5XOZ*_**!#Z(!T>$P'0%@^D!=?%?AP61@#_%0`R0P"%P'485NA6!```B_#_ -M%0`P0P!0Z,\#``!9B09>7<.+_U6+[%:+=0B#_N!W,(7V=1=&ZQ3H8O[__X7` -M="!6Z$'L__]9AC_`P``QP`,```` -M,\!>7P6 -M1@#_%00R0P"%P'39ZPWH7P,``,<`#````#/`7EW#B_]5B^Q7BWT(A?]U"_]U -M#.C]_O__6>LD5HMU#(7V=0E7Z++^__]9ZQ"#_N!V)>@A`P``QP`,````,\!> -M7UW#Z$K]__^%P'3F5N@IZ___687`=-M65VH`_S7L%D8`_Q4(,D,`A:?__66I0C87@_/__ -M:@!0Z"QL__]HS`(``(V%,/W__VH`4.@9;/__C87@_/__@\08B878_/__C84P -M_?__B87<_/__B87@_?__B8W<_?__B978_?__B9W4_?__B;70_?__B;W,_?__ -M9HR5^/W__V:,C>S]__]FC)W(_?__9HR%Q/W__V:,I<#]__]FC*V\_?__G(^% -M\/W__XM%!(F%Z/W__XU%!(F%]/W__\>%,/W__P$``0"+0/R)A>3]__^+10R) -MA>#\__^+11")A>3\__^+102)A>S\____%:PQ0P!J`(OX_Q6T,4,`C878_/__ -M4/\5L#%#`(7`=1.%_W4/@WT(_W0)_W4(Z)=H__]9BTW\,\U?Z#1D__^+Y5W# -MB_]5B^S_=0BY>!)&`.@D^?__7<.+_U6+[%&A:.9#`#/%B47\5NA%"```A -MZ-%C__^+Y5W#_W48BS5HYD,`B\[_=10S-7@21@"#X1__=1#3SO]U#/]U"(7V -M=;[H$0```,PSP%!04%!0Z'G___^#Q!3#:A?H_(X``(7`=`5J!5G-*59J`;X7 -M!`#`5FH"Z`;^__^#Q`Q6_Q4,,$,`4/\5S#%#`%[#B_]5B^R#[!#_=0R-3?#H -M][3__XU%]%!J!/]U".B\VO__@\0,@'W\`'0*BTWP@Z%0`P``_8OE7<.+_U6+ -M[*%L$D8`A7HM% -M"(7`=`.#"/]6@?____]_=A'H0_[__VH67HDPZ!C]___K4_]U&(U-[.A8LO__ -MBT7P,_8YL*@```!U76:+112Y_P```&8[P78VA=MT#X7_=`M75E/H=V?__X/$ -M#.CY_?__:BI>B3"`??@`=`J+3>R#H5`#``#]B\9>7UN+Y5W#A=MT!H7_=%^( -M`XM%"(7`=-;'``$```#KSHU-_(EU_%%65U-J`8U-%%%6_W`(_Q48,4,`B\B% -MR700.77\=9^+10B%P'2BB0CKGO\5`#!#`(/X>G6)A=MT#X7_=`M75E/H[6;_ -M_X/$#.AO_?__:B)>B3#H1/S__^EL____B_]5B^QJ`/]U%/]U$/]U#/]U".C' -M_O__@\047<-J"&B`NT,`Z&U@__^+10C_,.BT%P``68-E_`"+30R+002+`/\P -MBP'_,.@%`P``65G'1?S^____Z`@```#H?F#__\(,`(M%$/\PZ,P7``!9PVH( -M:*"[0P#H'6#__XM%"/\PZ&07``!9@V7\`(M%#(L`BP"+2$B%R708@\C_\`_! -M`74/@?D@ZT,`=`=1Z#?X__]9QT7\_O___^@(````Z!U@___"#`"+11#_,.AK -M%P``6<-J"&C`NT,`Z+Q?__^+10C_,.@#%P``68-E_`!J`(M%#(L`_S#H60(` -M`%E9QT7\_O___^@(````Z-)?___"#`"+11#_,.@@%P``6<-J"&A@NT,`Z'%? -M__^+10C_,.BX%@``68-E_`"+10R+`(L`BT!(\/\`QT7\_O___^@(````Z(I? -M___"#`"+11#_,.C8%@``6<.+_U6+[(/L#(M%"(U-_XE%^(E%](U%^%#_=0R- -M1?10Z.C^__^+Y5W#B_]5B^R#[`R+10B-3?^)1?B)1?2-1?A0_W4,C47T4.AP -M_O__B^5=PXO_58OL@^P,BT4(C4W_B47XB47TC47X4/]U#(U%]%#H^?[__XOE -M7<.+_U6+[(/L#(M%"(U-_XE%^(E%](U%^%#_=0R-1?10Z!S___^+Y5W#B_]5 -MB^Q148M%"#/)06I#B4@8BT4(QP#07D,`BT4(B8A0`P``BT4(6<=`2"#K0P"+ -M10AFB4ALBT4(9HF(<@$``(M%"(.@3`,```"-10B)1?R-1?Q0:@7H??___XU% -M"(E%^(U%#(E%_(U%^%!J!.@6____@\00B^5=P\S,S,S,S,S,S,S,S(O_58OL -M@WT(`'02_W4(Z`X```#_=0CH0_;__UE97<($`(O_58OL48M%"(L(@?G07D,` -M=`I1Z"3V__^+10A9_W`\Z!CV__^+10C_<##H#?;__XM%"/]P-.@"]O__BT4( -M_W`XZ/?U__^+10C_<"CH[/7__XM%"/]P+.CA]?__BT4(_W!`Z-;U__^+10C_ -M<$3HR_7__XM%"/^P8`,``.B]]?__C44(B47\C47\4&H%Z"G^__^-10B)1?R- -M1?Q0:@3H:/[__X/$-(OE7<.+_U6+[%:+=0B#?DP`="C_=DSHW30``(M&3%D[ -M!9`21@!T%#U8YT,`=`V#>`P`=0=0Z/(R``!9BT4,B49,7H7`=`=0Z&,R``!9 -M7<.+_U97_Q4`,$,`B_"AK.9#`(/X_W0,4.A:%@``B_B%_W5):&0#``!J`>CF -M]?__B_A9687_=0E0Z`WU__]9ZSA7_S6LYD,`Z($6``"%P'4#5^OE:)`21@!7 -MZ`G^__]J`.CE]/__@\0,A?]T#%;_%00P0P"+QU]>PU;_%00P0P#H3O7__\R+ -M_U-65_\5`#!#`(OP,]NAK.9#`(/X_W0,4.C3%0``B_B%_W51:&0#``!J`>A? -M]?__B_A9687_=0E3Z(;T__]9ZRM7_S6LYD,`Z/H5``"%P'4#5^OE:)`21@!7 -MZ(+]__]3Z%_T__^#Q`R%_W4)5O\5!#!#`.L)5O\5!#!#`(O?7UZ+PUO#S,QH -MH)%"`.BU%```HZSF0P"#^/]U`S+`P^A=____A+30BAH.U#`(6!4`,``'4'Z*TS``")!EY=PXO_58OL5HMU#(L&.P5`[4,` -M=!>+30BAH.U#`(6!4`,``'4'Z%\A``")!EY=PXO_58OLBT4(N?\'``!35C/2 -MBQB+<`2+QL'H%"/!5SO!=4,[TG4_B_Z+PX'G__\/``O'=0-`ZS"+SHO"@>$` -M``"`"\&X```(`'0-.]IU"3OX=05J!%CK$"/P"]9T!&H"Z_-J`^OO,\!?7EM= -MPXO_58OLBT4(,]*+2`2+PH'A````@`O!=`%"BL)=PXO_58OL@^PP4U97BWT< -M,]N%_WD"B_N+=0R-3=#_=2B('NB2J___C4<+.440=Q3H6??__VHB7XDXZ"[V -M___IJ`(``(M5"(L"BTH$B47@B\'!Z!0E_P<``#W_!P``=5([VW5.4_]U)%-7 -M_W48_W44_W405E+HBP(``(OX@\0DA?]T!X@>Z6("``!J95;H$```"`B\,+P70$Q@8M1HM* -M!#/;.%T@:C`/E,/'1?3_`P``2S/`@^/@@>$``/!_@\,G"\&)7>18=1^(!D:+ -M0@2+"B7__P\`"\AU!2%-].L-QT7T_@,``.L$Q@8Q1HO.1HE-Z(7_=07&`0#K -M#XM%U(N`B````(L`B@"(`8M"!"7__P\`B47P=PF#.@`/AL4```"#9?P`N0`` -M#P!J,%B)1?B)3?"%_WY3BP*+4@0C1?PCT8M-^('B__\/``^_R>A/4?__:C!9 -M9@/!#[?`@_@Y=@(#PXM-\(M5"(@&1HM%_`^LR`2)1?R+1?C!Z02#Z`1/B4WP -MB47X9H7`>:EFA@-4___!#")5>2(!D9J -M,%@"R#/_B`[&1@$`@'W<`'0*BTW0@Z%0`P``_8O'7UY;B^5=PXO_58OL@^P, -MC47T5HMU'%?_=1C_=12-?@%0BT4(5_]P!/\PZ$4[``"#R?^#Q!@Y31!T%XM- -M$#/`@WWT+0^4P"O(,\"%]@^?P"O(C47T4%>+?0Q1,\F#??0M#Y3!,\"%]@^? -MP`//`\%0Z&PU``"#Q!"%P'0%Q@<`ZQS_=2B-1?1J`%#_=23_=2!6_W405^@) -M````@\0@7UZ+Y5W#B_]5B^R#[!!65XM]$(7_?@2+Q^L",\"#P`DY10QW%^C* -M\___:B)>B3#HG_+__XO&7UZ+Y5W#4_]U)(U-\.C8I___BE4@BUT(A-)T)8M- -M'#/`A?\/G\!0,\"#.2T/E,`#PU#_=0Q3Z`0$``"*52"#Q!"+11R+\X,X+74& -MQ@,MC7,!A?]^%8I&`8@&1HM%](N`B````(L`B@"(!C/`A-(/E,`#QP/P@\C_ -M.44,=`>+PRO&`T4,:+AA0P!05NA8[O__@\0,6X7`=7:-3@(X111T`\8&18M5 -M'(M""(`X,'0OBU($@^H!>0;WVL9&`2UJ9%\[UWP(B\*9]_\`1@)J"E\[UWP( -MB\*9]_\`1@,`5@2#?1@"=12`.3!U#VH#C4$!4%'H8('__X/$#(!]_`!T"HM% -M\(.@4`,``/TSP.GR_O__,\!04%!04.B3\?__S(O_58OL@^P,,\!65_]U&(U] -M]/]U%*NKJXU%](M]'%"+10A7_W`$_S#H6CD``(/)_X/$&#E-$'0.BTT0,\"# -M??0M#Y3`*\B+=0R-1?10BT7X`\=0,\"#??0M40^4P`/&4.B.,P``@\00AB^5=PXO_58OL@^P0C4WP -M4U97_W46XOE7<.+ -M_U6+[(/L2*%HYD,`,\6)1?R+512+31!3BET,#[;#@\`$.]!S%6H,Q@$`6(M- -M_#/-6^C`4O__B^5=PX3;=`C&`2U!2L8!`+AX84,`QT72484,`B474@^,"B478B47HB47X -MBT4(5KZ`84,`QT7LH&%#`%>-/(7\____B77,C00?B770B77@B77PQT7TK&%# -M`(MTA;R-1@&)1;B*!D:$P'7Y*W6X._(;P$<#QP/#_W2%O%)1Z,/J__^#Q`Q? -M7H7`#X1!____,\!04%!04.AO[O__S(O_58OLBU44A=)T)E:+=1"+SE>->0&* -M`4&$P'7Y*\^-00%0C0065E#HZ'W__X/$#%]>7<.+_U6+[%%15E>+?0R%_W46 -MZ#;O__]J%EZ),.@+[O__B\;I'@$``%.+71"%VW0,@WT4`'0&@WT8`'<6Z`SO -M__]J%EZ),.CA[?__B\;I\P```(MU'(/^0703@_Y%=`Z#_D9T"<9%_`"#_D=U -M!,9%_`&+122#X`B#R`!U,O]U".BS]O__B47X687`="+_=?Q35_]U".@*]___ -M60^VP%#_=?CH,/[__X/$%.F7````BT4D@^`0@\@`=`1J`^L":@)8@_YA?RAT -M"H/N070%@^X$ZQ__=2Q0_W7\_W4@_W48_W444U?_=0CHUO;__^M5@^YE_W4L -M=#:#[@%T&5#_=?S_=2#_=1C_=1135_]U".C]_/__ZR__=2#_=1C_=1135_]U -M".B$^___@\0+QJ-\$D8`:@10Z`+J__]J`*.`$D8`Z"OI__^# -MQ`R#/8`21@``=2MJ!%:)-7P21@#HW.G__VH`HX`21@#H!>G__X/$#(,]@!)& -M``!U!8/(_U[#5S/_OK#F0P!J`&B@#P``C48@4.BX"@``H8`21@"+U\'Z!HDT -MN(O'@^`_:\@PBP25F!)&`(M$"!B#^/]T"8/X_G0$AP\S,S,S,S,S,B_]6Z,](``#H?4<``#/VH8`21@#_-`;H -MG$D``*&`$D8`68L$!H/`(%#_%=0P0P"#Q@2#_@QUV/\U@!)&`.A,Z/__@R6` -M$D8``%E>PXO_58OLBT4(@\`@4/\5S#!#`%W#B_]5B^R+10B#P"!0_Q70,$,` -M7<.+#6CF0P`SP(/)`3D-A!)&``^4P,.+_U6+[(/L2(U%N%#_%;@Q0P!F@WWJ -M``^$E0```(M%[(7`#X2*````4U:+,(U8!(T$,XE%_+@`(```._!\`HOP5NA9 -M'P``H9@41@!9._!^`HOP5S/_A?9T5HM%_(L(@_G_=$"#^?YT.XH3]L(!=#3V -MP@AU"U'_%3PP0P"%P'0AB\>+SX/@/\'Y!FO0,(M%_`,4C9@21@"+`(E"&(H# -MB$(HBT7\1X/`!$.)1?P[_G6M7UY;B^5=PXO_4U97,_^+QXO/@^`_P?D&:_`P -M`S2-F!)&`(-^&/]T#(-^&/YT!H!.*(#K>XO'QD8H@8/H`'00@^@!=`=J](/H -M`>L&:O7K`FKV6%#_%4`P0P"+V(/[_W0-A=MT"5/_%3PP0P#K`C/`A#_P,/A57___]?7EO#S,S,S,S,S,S,S,QJ#&C@NT,` -MZ#1.__]J!^A^!0``63/;B%WGB5W\4^@&'@``687`=0_H7?[__^@.____LP&( -M7>?'1?S^____Z`L```"*P^@]3O__PXI=YVH'Z(T%``!9P\S,S,S,S,S,S,R+ -M_U8S]HN&F!)&`(7`=`Y0Z'X=``"#II@21@``68/&!('^``(``'+=L`%>PXO_ -M58OLBT4(,\F)"(M%"(E(!(M%"(E("(M%"(-($/^+10B)2!2+10B)2!B+10B) -M2!R+10B#P`R'"%W#B_]5B^Q1Z'/P__^+2$R)3?R-3?Q14.BX\?__BT7\65F+ -M`(OE7<.+_U6+[(/L$/]U#(U-\.@VGO__BT7T#[9-"(L`#[<$2"4`@```@'W\ -M`'0*BTWP@Z%0`P``_8OE7<.+_U6+[(/L)*%HYD,`,\6)1?Q3_W40BUT(C4W@ -MZ.^=__^-0P$]``$``'<+BT7DBP`/MP18ZWJ+PXU-Y,'X"(E%W%$/ML!0Z'S_ -M__]9687`=!.+1=R(1?`SP&H"B%WQB$7R6>L+,\"(7?`SR8A%\4&)1?1FB47X -MBT7D:@'_<`B-1?1048U%\%"-1>1J`5#HT"```(/$'(7`=1,X1>QT"HM%X(.@ -M4`,``/TSP.L7#[=%]"-%#(!][`!T"HM-X(.A4`,``/V+3?PSS5OHEDO__XOE -M7<.+_U6+[%%1H6CF0P`SQ8E%_%-6BW485X7V?A16_W44Z#!&``!9.\99C7`! -M?`*+\(M])(7_=0N+10B+`(MX"(E])#/`.44H:@!J`%;_=10/E<"-!,4!```` -M4%?_%10Q0P")1?B%P`^$C0$``(T4`(U*"#O1&\"%P712C4H(.]$;P"/!C4H( -M/0`$``!W'3O1&\`CP>@!>0``B]R%VP^$3`$``,<#S,P``.L=.]$;P"/!4.@; -MY/__B]A9A=L/A"T!``#'`]W=``"#PPCK`C/;A=L/A!@!``#_=?A35O]U%&H! -M5_\5%#%#`(7`#X3_````BWWX,\!04%!04%=3_W40_W4,Z,\%``"+\(7V#X3> -M````]T40``0``'0XBT4@A<`/A,P````[\`^/P@```#/)45%14/]U'%=3_W40 -M_W4,Z),%``"+\(7V#X6D````Z9T```"-%#:-2@@[T1O`A<%T2HU*"#O1&\`C -MP8U*"#T`!```=QD[T1O`(\'H''@``(O\A?]T9,<'S,P``.L9.]$;P"/!4.@Z -MX___B_A9A?]T2<<'W=T``(/'".L",_^%_W0X:@!J`&H`5E?_=?A3_W40_W4, -MZ`\%``"%P'0=,\!04#E%('4Z4%!65U#_=23_%1@Q0P"+\(7V=2Y7Z'P```!9 -M,_93Z',```!9B\:-9>Q?7EN+3?PSS>B*2?__B^5=P_]U(/]U'.O`5^A.```` -M6>O2B_]5B^R#[!#_=0B-3?#H#IO___]U*(U%]/]U)/]U(/]U'/]U&/]U%/]U -M$/]U#%#HK_W__X/$)(!]_`!T"HM-\(.A4`,``/V+Y5W#B_]5B^R+10B%P'02 -M@^@(@3C=W0``=0=0Z!'B__]97<.+_U6+[%%19HM%"+G__P``9CO!=00SP.M" -MN0`!``!F.\%S#@^WR*$7<-7B_HK\@^W!#YFB0>- -M?P)FA-N(@41@!7_Q74,$,`_PW8%48` -M@^\8@^X!=>M?L`%>PXO_58OL:T4(&`6@%$8`4/\5T#!#`%W#B_]5B^R+10A3 -M5E>-'(4P%D8`BP.+%6CF0P"#S_^+RHOR@^$?,_#3SCOW=&F%]G0$B\;K8XMU -M$#MU%'0:_S;H60```%F%P'4O@\8$.W44=>R+%6CF0P`SP(7`="G_=0Q0_Q6, -M,$,`B_"%]G035NA/C/__68<#Z[F+%6CF0P#KV8L5:.9#`(O":B"#X!]9*\C3 -MSS/ZASLSP%]>6UW#B_]5B^R+10A7C3R%X!5&`(L/AM7 -M4XLPQ0P"+\(7V=2?_%0`P0P"#^%=U#5964_\5 -M[#%#`(OPZP(S]H7V=0F#R/^'!S/`ZQ&+QH<'AZ"M&__^+Y5W"!`"+_U6+ -M[%&A:.9#`#/%B47\5FA`@Q0P"+3?PSS5[HU47__XOE7<($`(O_58OL4:%H -MYD,`,\6)1?Q6:$AS0P!H0'-#`&BP5D,`:@7H%O[__X/$$(OP_W4(A?9T#(O. -M_Q5@,D,`_];K!O\5X#%#`(M-_#/-7NA_1?__B^5=P@0`B_]5B^Q1H6CF0P`S -MQ8E%_%9H4'-#`&A(Z"9%__^+Y5W""`"+_U6+[%&A:.9#`#/% -MB47\5FATZ#Q$__^+Y5W")`"+_U6+ -M[%&A:.9#`#/%B47\5FB4L,:@)8N;`61@"'`3+`7HM-_#/-Z#%#__^+Y5W#S,S,B_]5B^R` -M?0@`=2=6ON`51@"#/@!T$(,^_W0(_S;_%8@P0P"#)@"#Q@2!_C`61@!UX%ZP -M`5W#S,S,S,S,S,S,S(O_58OLBT4,.T4(=@6#R/]=PQO`]]A=PXO_58OLBT4, -M@^P@5H7`=1;H/>#__VH67HDPZ!+?__^+QNE8`0``BW4(,\E35XD(B_F+V8E] -MX(E=Y(E-Z#D.=%:-1?QFQT7\*C]0_S:(3?[H!#\``%E9A@".]^)5?0;]O?6(_!T,(O7 -MB]F+"HU!`8E%_(H!083`=?DK3?Q#BT7X`]F#P@1`B47X.\9UW8M5](E=_(M= -MY&H!_W7\4N@*S___B_"#Q`R%]G4%@\__ZV>+1?2-!(:)1?"+T(E5]#O[=$Z+ -MQBO'B47LBP^-00&)1?B*`4&$P'7Y*TWXC4$!4/\WB47XBT7P*\(#1?Q04N@# -M/@``@\00A#H,`(``(O'7UM>B^5=PS/`4%!04%#HLMW__\R+_U6+[%&+30B-40&* -M`4&$P'7Y*\J#R/]7BWT002O'B4W\.\AV!6H,6.M94U:-7P$#V6H!4^C7VO__ -MB_!9687_=!)7_W4,4U;H;#T``(/$$(7`=37_=?PKWXT$/O]U"%-0Z%,]``"# -MQ!"%P'4)M;C^___K&8H! -M/"]T%SQ<=!,\.G0/45/H-#T``%E9B\@[RW7CBA&`^CIU%XU#`3O(=!!6,_]7 -M5U/H"____X/$$.MZ,_^`^B]T#H#Z7'0)@/HZ=`2+Q^L#,\!`#[;`*\M!]]AH -M0`$``!O`(\&)A;3^__^-A;S^__]74.@"1___@\0,C86\_O__5U=74%=3_Q44 -M,D,`B_"+A;C^__^#_O]U+5!75U/HG_[__X/$$(OX@_[_=`=6_Q5@,$,`B\>+ -M3?Q?7C/-6^C!/___B^5=PXM(!"L(P?D"B8VP_O__@+WH_O__+G48BHWI_O__ -MA,ET*8#Y+G4)@+WJ_O__`'0;4/^UM/[__XV%Z/[__U-0Z#C^__^#Q!"%P'65 -MC86\_O__4%;_%1@R0P"%P(N%N/[__W6LBQ"+0`2+C;#^__\KPL'X`CO(#X1G -M____:!"L0@`KP6H$4(T$BE#HMJW__X/$$.E,____B_]65XOYBS?K"_\VZ!O8 -M__]9@\8$.W<$=?#_-^@+V/__65]>PXO_58OL5E>+\>@G````B_B%_W0-_W4( -MZ.O7__]9B\?K#HM.!(M%"(D!@T8$!#/`7UY=P@0`B_]6B_%7BWX(.7X$=`0S -MP.MR@SX`=2MJ!&H$Z'W8__]J`(D&Z*G7__^+!H/$#(7`=05J#%CK38E&!(/` -M$(E&".O,*S[!_P*!_____W]WXU-J!(TPB#Q`R)NQP"``"Y`0$``(U[#*NKJ[\@ZT,`*_N* -M!#>(!D:#Z0%U]8V+&0$``+H``0``B@0YB`%!@^H!=?5?7EM=PXO_58OL@>P@ -M!P``H6CF0P`SQ8E%_%-6BW4(C87H^/__5U#_=@3_%0PQ0P`SV[\``0``A<`/ -MA/````"+PXB$!?S^__]`.\=R](J%[OC__XV-[OC__\:%_/[__R#K'P^V40$/ -MML#K#3O'$3?SX__^H`70.@$P.&1"*A`W\_?__ZQ"H`G05@$P.&2"*A`W\_/__B(0. -M&0$``.L'B)P.&0$``$$[SW+!ZUEJGXV6&0$``(O+6"O"B87@^/__`]$#PHF% -MY/C__X/`((/X&7<*@$P.&1"-02#K$X.]Y/C__QEW#HT$#H!(&2"-0>"(`NL" -MB!J+A>#X__^-EAD!``!!.\]RNHM-_%]>,\U;Z&ATU___QP`6````B_-7Z.K2__]97XO&7EN+Y5W#@'T,`'4%Z,;0 -M__^+1?R+0$CP#\$82W45BT7\@7A((.M#`'0)_W!(Z+32__]9QPB`^___ -M@'T,`%E9=(6A0.U#`*,4Z$,`Z7;____,S,S,S,S,S(`]T!9&``!U$FH!:OWH -MY?[__UE9Q@70%D8``;`!PVH,:`"\0P#HYCG__S/VB77DZ.'<__^+^(L-H.U# -M`(6/4`,``'01.7=,=`R+=TB%]G5HZ)'2__]J!>@%\?__68EU_(MW2(EUY#LU -M0.U#`'0PA?9T&(/(__`/P09U#X'^(.M#`'0'5NC5T?__6:%`[4,`B4=(BS5` -M[4,`B77D\/\&QT7\_O___^@%````ZZ"+=>1J!>C[\/__6<.+QNB7.?__PXO_ -M58OL@^P@H6CF0P`SQ8E%_%-6_W4(BW4,Z*S[__^+V%F%VW4.5N@2_/__63/` -MZ:T!``!7,_^+SXO'B4WD.9@HZ$,`#X3J````08/`,(E-Y#WP````A04_\5 -M##%#`(7`#X2$````:`$!``"-1AA74.CL/O__B5X$@\0,,]N)OAP"``!#.5WH -M=E&`?>X`C47N="&*2`&$R70:#[;1#[8(ZP:`3`X9!$$[RG;V@\`"@#@`==^- -M1AJY_@```(`("$"#Z0%U]_]V!.B2^O__@\0$B88<`@``B5X(ZP.)?@@SP(U^ -M#*NKJ^F^````.3W,%D8`=`M6Z!?[___IL0```(/(_^FL````:`$!``"-1AA7 -M4.A-/O__@\0,:T7D,(E%X(V`..A#`(E%Y(`X`(O(=#6*00&$P'0K#[81#[;` -MZQ>!^@`!``!S$XJ'(.A#``A$%AE"#[9!`3O0=N6#P0*`.0!USHM%Y$>#P`B) -M1>2#_P1RN%.)7@3'1@@!````Z-_Y__^#Q`2)AAP"``"+1>"-3@QJ!HV0+.A# -M`%]FBP*-4@)FB0&-20*#[P%U[U;HQOK__UDSP%^+3?Q>,\U;Z*TV__^+Y5W# -MB_]5B^Q6BW44A?9U!#/`ZVV+10B%P'43Z`S4__]J%EZ),.CATO__B\;K4U>+ -M?1"%_W04.74,<@]65U#HOS[__X/$##/`ZS;_=0QJ`%#H33W__X/$#(7_=0GH -MR]/__VH6ZPPY=0QS$^B]T___:B)>B3#HDM+__XO&ZP-J%EA?7EW#B_]5B^R# -M[!!6_W4(C4WPZ,"'__\/MG4,BT7XBDT4A$PP&74;,](Y51!T#HM%](L`#[<$ -M<"-%$.L"B\*%P'0#,])"@'W\`%YT"HM-\(.A4`,``/V+PHOE7<.+_U6+[&H$ -M:@#_=0AJ`.B4____@\007+V%L"B]^%]G0' -M5O\5+#)#`%]>B\-;B^5=PXO_58OL7>D`````B_]5B^Q6BW4,A?9T&VK@,])8 -M]_8[11!S#^@NTO__QP`,````,\#K0E.+70A7A=MT"U/H&C(``%F+^.L",_\/ -MKW405E/HK\[__XO865F%VW05._YS$2OWC00[5FH`4.A?.___@\0,7XO#6UY= -MP\S,S,S,_Q60,4,`A<"C[!9&``^5P,/,S,S,S,S,S,S,S,S,S,R#)>P61@`` -ML`'#B_]5B^Q1H6CF0P`SQ8E%_%>+?0@[?0QU!+`!ZU=6B_=3BQZ%VW0.B\O_ -M%6`R0P#_TX3`=`B#Q@@[=0QUY#MU#'4$L`'K+#OW=":#QOR#?OP`=!.+'H7; -M=`UJ`(O+_Q5@,D,`_]-9@^X(C48$.\=UW3+`6UZ+3?PSS5_HL3/__XOE7<.+ -M_U6+[%&A:.9#`#/%B47\5HMU##EU"'0C@\;\5XL^A?]T#6H`B\__%6`R0P#_ -MUUF#[@B-1@0[10AUXE^+3?RP`3/-7NAD,___B^5=PVH,:&"\0P#H"C3__X-E -MY`"+10C_,.A-Z___68-E_`"+-6CF0P"+SH/A'S,U^!9&`-/.B77DQT7\_O__ -M_^@-````B\;H%#3__\(,`(MUY(M-$/\QZ%_K__]9PXO_58OL@^P,BT4(C4W_ -MB47XB47TC47X4/]U#(U%]%#H@O___XOE7<.+_U6+[(M%"$B#Z`%T+8/H!'03 -M@^@)=!R#Z`9T$(/H`70$,\!=P[CX%D8`7<.X]!9&`%W#N/P61@!=P[CP%D8` -M7<.+_U6+[&L-8%]#``R+10P#R#O!=`^+50@Y4`1T"8/`##O!=?0SP%W#B_]5 -MB^Q1C47_4&H#Z%W___]968OE7<.+_U6+[/]U"+GP%D8`Z%''____=0BY]!9& -M`.A$Q____W4(N?@61@#H-\?___]U"+G\%D8`Z"K'__]=P^C8U?__@\`(PVHL -M:$"\0P#HLU\``#/;B5W4(5W,L0&(3>.+=0AJ"%\[]W\8=#6-1O^#Z`%T(DB# -MZ`%T)TB#Z`%U3.L4@_X+=!J#_@]T"H/^%'X[@_X6?S96Z.;^__^#Q`3K1>CY -MU?__B]B)7=2%VW4(@\C_Z9(!``#_,U;H!?___UE9,\F%P`^5P87)=1+H#\__ -M_\<`%@```.CCS?__Z]&#P`@RR8A-XXE%V(-ET`"$R70+:@/H;^G__UF*3>.# -M9=P`QD7B`(-E_`"+1=B$R704BQ5HYD,`B\J#X1\S$-/*BDWCZP*+$(O"B47< -M,]*#^`$/E,*)5*$T@^%B@```(7`=1.$R70(:@/H:.G__UEJ`^@YN___ -M._=T"H/^"W0%@_X$=2.+0P2)1="#8P0`._=U.^C&_O__BP")1+3=S_%6`R0P#_5=Q9ZRMJ"%^+=0B+7=2*1>*)1,` -M=`AJ`^BCZ/__6<-6BTW<_Q5@,D,`_U7<63OW=`J#_@MT!8/^!'45BT70B4,$ -M._=U"^C:T___BTW,B4@(,\#H`5X``,.+_U6+[%%14U=J,&I`Z,[)__^+^#/; -MB7WX65F%_W4$B_OK2(V'``P``#OX=#Y6C7<@B_A3:*`/``"-1N!0Z*_J__^# -M3OC_B1Z-=C")7M2-1N#'1M@```H*QD;<"H!FW?B(7MX[QW7,BWWX7E/HI,C_ -M_UF+QU];B^5=PXO_58OL5HMU"(7V="53C9X`#```5XO^._-T#E?_%=0P0P"# -MQS`[^W7R5NALR/__65];7EW#:A1H@+Q#`.@,,/__@7T(`"```!O`]]AU%^C$ -MS/__:@E>B3#HF1J!^@MY___68EU_(O^H9@41@") -M?>`Y10A\'SDTO9@21@!U,>CT_O__B02]F!)&`(7`=11J#%Z)=>3'1?S^____ -MZ!4```#KK*&8%$8`@\!`HY@41@!'Z[N+=>1J!^@CY___6<.+_U6+[(M%"(O( -M@^`_P?D&:\`P`P2-F!)&`%#_%%]GAG.S68%$8`L#4&KV_Q6,,4,`BP2]F!)&`(-,`QC_,\#K%NB) -MR___QP`)````Z&O+__^#(`"#R/]?7EM=PXO_58OLBTT(@_G^=17H3LO__X,@ -M`.A9R___QP`)````ZT.%R7@G.PV8%$8`D".\8;V_?3(]ET$/\VZ/C$__]'C78$ -M63O[=?!?7EM=PXO_58OL5HMU"(7V#X30````:@=6Z*O___^-1AQJ!U#HH/__ -M_XU&.&H,4.B5____C49H:@Q0Z(K___^-AI@```!J`E#H?/____^VH````.B7 -MQ/___[:D````Z(S$____MJ@```#H@<3__XV&M````&H'4.A-____C8;0```` -M:@=0Z#____^#Q$2-ANP```!J#%#H+O___XV&'`$``&H,4.@@____C89,`0`` -M:@)0Z!+_____ME0!``#H+<3___^V6`$``.@BQ/___[9<`0``Z!?$____MF`! -M``#H#,3__X/$*%Y=PXO_58OL@^P8H6CF0P`SQ8E%_%-65_]U"(U-Z.B.?/__ -MBTT%]G0T4U=6Z#0Q__^#Q`S_=?A6_W44_W40:@'_ -M=1S_%10Q0P"%P'00_W484%;_=0S_%0PR0P"+^%;HXN#__UF`??0`=`J+1>B# -MH%`#``#]B\>-9=Q?7EN+3?PSS>CI*?__B^5=PXO_58OLBT4(\/]`#(M(?(7) -M=`/P_P&+B(0```"%R70#\/\!BXB`````A@7GX&.A#`'0)BQ&%TG0#\/\"@WGT`'0*BU'\A=)T`_#_`H/!$(/N -M`776_["<````Z$X!``!97EW#B_]5B^Q14U:+=0A7BX:(````A@S@`=5F+AH0```"%P'08@S@`=1-0Z"["____MH@```#HEOO_ -M_UE9BX:`````A7<.+_U6+[(M-"(7)=!:! -M^2!E0P!T#H/(__`/P8&P````2%W#N/___W]=PXO_58OLBT4(A+=TR%]G5#:@3H[][__UF#9?P`_S60$D8`C4=,4.@P -M````65F+\(EUY,=%_/[____H#````(7V=1'H1,#__XMUY&H$Z`7?__]9PXO& -MZ*$G___#B_]5B^Q6BW4,5X7V=#R+10B%P'0UBS@[_G4$B\;K+5:),.B8_/__ -M687_=.]7Z-;^__^#?PP`677B@?]8YT,`=-I7Z/7\__]9Z]$SP%]>7<.+_U6+ -M[(M-"#/`]L$0=`6X@````%-65[\``@``]L$(=`(+Q_;!!'0%#0`$``#VP0)T -M!0T`"```]L$!=`4-`!```+X``0``]\$```@`=`(+QHO1NP`#```CTW0?.]9T -M%CO7=`L[TW43#0!@``#K#`T`0```ZP4-`"```+H````#7R/*7EN!^0````%T -M&('Y`````G0+.\IU$0T`@```7<.#R$!=PPU`@```7<.+_U6+[(/L#-U]_-OB -M@ST8#48``0^,@P```&:+1?PSR8O15[\```@`J#]T*:@!=`-J$%JH!'0#@\H( -MJ`AT`X/*!*@0=`.#R@*H('0#@\H!J`)T`@O7#ZY=^(M%^(/@P(E%]`^N5?2+ -M1?BH/W0IJ`%T`VH06:@$=`.#R0BH"'0#@\D$J!!T`X/)`J@@=`.#R0&H`G0" -M"\\+RHO!7^L]9HM-_#/`]L$_=#+VP0%T`VH06/;!!'0#@\@(]L$(=`.#R`3V -MP1!T`X/(`O;!('0#@\@!]L$"=`4-```(`(OE7<.+_U6+[(/L$)O9??AFBT7X -M,\FH`70#:A!9J`1T`X/)"*@(=`.#R02H$'0#@\D"J"!T`X/)`:@"=`:!R0`` -M"`!35@^W\+L`#```B]97OP`"```CTW0F@?H`!```=!B!^@`(``!T##O3=1*! -MR0`#``#K"@O/ZP:!R0`!``"!Y@`#``!T##OW=0Z!R0```0#K!H')```"`+H` -M$```9H7"=`:!R0``!`"+?0R+]XM%"/?6(_$CQPOP._$/A*8```!6Z#\"``!9 -M9HE%_-EM_)O9??QFBT7\,_:H`70#:A!>J`1T`X/."*@(=`.#S@2H$'0#@\X" -MJ"!T`X/.`:@"=`:!S@``"``/M]"+RB/+="J!^0`$``!T'('Y``@``'0,.\MU -M%H'.``,``.L.@0-J$%FI``(``'0#@\D(J0`$``!T`X/)!*D`"```=`.#R0*% -MPG0#@\D!J0`!``!T!H')```(`(O0NP!@```CTW0J@?H`(```=!R!^@!```!T -M##O3=1:!R0`#``#K#H')``(``.L&@L.@ALOO__:B+KS(MU%(7V=+Y3C5H! -MB\-7BWX(Q@(PA+?0R+ -M#X7)=0I?,\`STEN+Y5W#5HUP_XU!_XEU](7`#X4M`0``BT\$B4W8@_D!=2^+ -MC]__]0:,P!``!1Z#/I__^#Q!"+QC/27E];B^5= -MPX7V=4F+C]__]J`%"->P3'A>3]__\`````:,P!``!7QP,`````Z/?H -M__\STHO&]W78@\00,\D[RHD7&\E>]]DSTE^)"UN+Y5W#,__'1?@`````QT7\ -M`````(E]\(/^_W1$BT7T1D")1>2--+.-9"0`:@!1,\`+!E=0Z%),``")5<"- -M=OPSTHE=\(OY`]"+3?B#T0")5?B#;>0!B4W\BTW8=% -MY/W__P````!0C7,$QP,`````:,P!``!6Z%7H__^+1?"#Q!"+5?PSR3O(B3Z) -M0PB+1?@;R??97D%?B0M;B^5=PSO&=T>+UHU(`2O0B4W(B\X[\GPRB\%&*\*- -M-+.-/(>#QP2+!SL&=0U)@^\$@^X$.\I][^L1BW4,B\$KPHM$A@0[1(L$+1<@#1>2+3<2+1(/XT^@+\(M%_(EU[&H` -M_W7,4%+H@DH``(E=V#/VB]B)==B+PHE=_(E%Z(OYB5V\B47`AQJ`/]UX(E-_.BD&/__.]9R*7<%.T7\=B*+1>B# -MP_^)7;R#T/\#?B#5=@`B47`=0J#__]VO^L#BT7HB5W\AR)3?2+`(E%V(M%P/=EV(O(BT6\ -M]V78`]$#^(L#B\\3\HO^,_8[P7,%@\0#PXM-M(OXBT7X@]8`@VWP!$J+70B#Z01(B7VXB57DB4VT -MB47XA=(/B>[]___K`C/_BU7T0HO".P-S'(U(`8T,B^L&C9L`````QP$````` -MC4D$0#L#QD"0``H6CF0P`SQ8E%_%.+71B-C6SX__]65XM]%(F]@/C__XF=A/C__^CS -M^O__BW4,,\"+SH'A````@`O!L"UU`@3S#[[`B\Z)!X'A``#P?S/`B5\("\&+ -M?0AU(HO.B\>!X?__#P`+P744BX6`^/__:+1]0P"#8`0`Z=,2``"-10A0Z'C` -M__]9AD4B\$E_P<``(/(`'4&L@$S]NL),M*^```0`#/`BYV8 -M^/__@>?__P\``]@3_C/`A-(/E<"!X?\'``!`C;',^___`_")M;3X___H,1H` -M`%%1W1PDZ#<;``!96>B`2```B864^/__/?___W]T!ST```"`=0@SP(F%E/C_ -M_XF=,/[__S/;A?^)O33^__\/E<-#B9TL_O__A?8/B.T#``"#I9#Z__\`:@)> -MQX64^O__```0`(FUC/K__SO>#X4``@``,\F+A`V0^O__.X0-,/[__P^%Z@$` -M`(/!!(/Y"'7DBX6T^/__,]*#P`*+\(/@'VH@62O(B86D^/__,\#![@5`B;6P -M^/__B8V0^/__Z!`5__^#I9SX__\`2`^]SXF%J/C___?0B86,^/__=`-!ZP(S -MR6H@6"O!C58".86D^/__B96L^/__#Y?`@_ISB(6[^/__#Y?!@_IS=0B$P'0$ -ML`'K`C+`A,D/A>\```"$P`^%YP```&IR63O1<@B+T8F-K/C__XO*B8V@^/__ -M@_K_#X26````B_*-A3#^__^+E;#X__\K\HT$L(F%M/C__SO*)A(TP_O__28N%M/C__TZ#Z`2)C:#X__^)A;3X__^# -M^?]T"(N=+/[__^N/BY6L^/__B[6P^/__A?9T#(O.C;TP_O__,\#SJX"]N_C_ -M_P"[S`$``'0+C4(!B84L_O__ZS.)E2S^___K*S/`N\P!``!0B86,^O__B84L -M_O__C860^O__4(V%,/[__U-0Z(#A__^#Q!"#I93Z__\`,\EJ!%A!B860^O__ -MB8V,^O__B8U<_/__4(V%D/K__U"-A6#\__]34.A)X?__@\00Z5P$``"+A;3X -M__\STD"+^(/@'VH@62O(B86P^/__,\#![P5`B;VT^/__B8V0^/__Z#`3__^+ -MC)TL_O__2(.EG/C__P`/OL",\EJ(%@KP8T4 -M.SF%L/C__XF5H/C__P^7P(/Z0```!J+C9#X___3Z(N-I/C__POX -MBX6L^/__@^D$B8VD^/__B;R%,/[__TA.B86L^/__@_C_=`B+G2S^___KE8N5 -MH/C__XN]M/C__VH"7H7_=`R+SS/`C;TP_O__\ZN`O;OX__\`N\P!``!T"XU" -M`8F%+/[__^LSB94L_O__ZRLSP+O,`0``4(F%C/K__XF%+/[__XV%D/K__U"- -MA3#^__]34.B`"P>H> -M,]"+A:SX__].B1"#Z`2)A:SX__^#_O]T"(N=+/[__^NM,\`XA;OX__\/E<`# -MP2N-M/C__XOYB84L_O__P>\%C860^O__B_>)C:CX___!Y@)6:@!0Z`T<__^+ -MC:CX__\SP$"#X1_3X(F$-9#Z__^-1P'I0`$``(N$G2S^__^#I9SX__\`#[W` -M=`6-2`'K`C/):B!8*\&#^`$/DL"#^W.(A;OX__\/E\&#^W-U"(3`=`2P`>L" -M,L"$R0^%FP```(3`#X63````:G)9.]ES`HO+@_G_=&F-O3#^__^+\8T\CXF] -MK/C__SOSHN]D/K__X7_=1,SP(F%O/C__XF%7/S_ -M_^F?`@``@_\!#X2N`@``@[U<_/__``^$H0(``(N%7/S__S/)B86H^/__,_:+ -MQ_>DM6#\__\#P8F$M6#\__^#T@!&B\H[M:CX__]UX.FL````B8R%8/S___^% -M7/S__^E:`@``@[U<_/__`0^'O@```(N]8/S__XO!P>`"4(V%D/K__XF-7/S_ -M_U"-A6#\__]34.B.V___@\00A?]U&C/`B86,^O__B85<_/__4(V%D/K__^GU -M`0``@_\!#X3]`0``@[U<_/__``^$\`$``(N%7/S__S/)B86H^/__,_:+Q_>D -MM6#\__\#P8F$M6#\__^#T@!&B\H[M:CX__]UX(7)#X2X`0``BX5<_/__@_AS -M#X(]____,\")A8SZ__^)A5S\__]0C860^O__Z>P!```[C5S\__^-O9#Z__\/ -MDL"$P`^%@P```(V]8/S__XV5D/K__XF5L/C__X3`=0:+C5S\__^)C:SX__^$ -MP'0,BX5<_/__B86@^/__,](S]HF5O/C__X7)#X01`0``C87`^/__*_B)O7SX -M__^-!+>+A`7`^/__B86H^/__A````(82UP/C__XU6`8F5O/C_ -M_^G)````C95@_/__ZX$SP#/_B\Z)A;3X__\YA:#X__\/A)0```"#^7-T5SO* -M=1>#I(W`^/__`$`#QHF%O/C__XN%M/C__XN5L/C__XL$@O>EJ/C__P/'@](` -M`82-P/C__XN%M/C__X/2`$!!B86T^/__B_J+E;SX__\[A:#X__]UI(7_=#2# -M^7,/A+0````[RG41@Z2-P/C__P"-00&)A;SX__^+QS/_`82-P/C__XN5O/C_ -M_Q/_0>O(@_ES#X2`````B[U\^/__BXVL^/__1COQ#X7]_O__B\*)E5S\___! -MX`)0C87`^/__4(V%8/S__U-0Z&K9__^#Q!"P`83`=&R+A9#X__\KA:3X__^) -MA9#X__\/A97\__^+C9SX__^%R0^$$P4``(L\C8Q]0P"%_W5=,\")A9SV__^) -MA5S\__]0ZSHSP(F%G/;__XF%7/S__U"-A:#V__]0C85@_/__4U#H_-C__X/$ -M$#+`ZY"#I9SV__\`@Z5<_/__`&H`C86@]O__4(V%8/S__^FA!```@_\!#X2B -M!```BX5<_/__B86<^/__A<`/A(X$```S]C/)B\?WI(U@_/__`\:)A(U@_/__ -M@](`08OR.XV<^/__=>"%]@^$8@0``(N%7/S__X/XDM3#^__\#P8F$M3#^__^#T@!&B\H[M9SX__]UX.E2____.XTL_O__C;V0 -M^O__#Y+`A,`/A8,```"-O3#^__^-E9#Z__^)E9#X__^$P'4&BXTL_O__B8VP -M^/__A,!T#(N%+/[__XF%H/C__S/2,_:)E;SX__^%R0^$$0$``(V%P/C__ROX -MB;U\^/__C02WBX0%P/C__XF%G/C__X7`=24[\@^%W@```"&$M<#X__^-5@&) -ME;SX___IR0```(V5,/[__^N!,\`S_XO.B86D^/__.86@^/__#X24````@_ES -M=%<[RG47@Z2-P/C__P!``\:)A;SX__^+A:3X__^+E9#X__^+!(+WI9SX__\# -MQX/2``&$C<#X__^+A:3X__^#T@!`08F%I/C__XOZBY6\^/__.X6@^/__=:2% -M_W0T@_ES#X0*`0``.\IU$8.DC<#X__\`C4$!B86\^/__B\`"4(V%P/C__U"-A3#^__]34.@NU?__@\00L`&$P`^$P0```(N%K/C_ -M_RN%M/C__XF%K/C__P^%NOS__XN-J/C__X7)#X33````BP2-C'U#`(F%G/C_ -M_X7`#X28````@_@!#X2U````BXTL_O__A"%_W1_BX4L_O__@_ASG_ -M_UE9:@I:.\(/A9$```#_A93X__^-=P&+A5S\___&!S&)M;3X__^%P`^$BP`` -M`#/_B_`SR8N$C6#\___WXFH*`\>)A(U@_/__@](`08OZ6CO.=>&+M;3X__^% -M_W1) -MM;3X__^+A93X__^+C8#X__^)002+C8CX__^%P'@*@?G___]_=P(#R(M%'$@[ -MP7("B\$#A83X__^)A8CX__\[\`^$TP```(N%+/[__X7`#X3%````,_^+\#/) -MBX2-,/[__[H`RIH[]^(#QXF$C3#^__^#T@!!B_H[SG7?B[6T^/__A?]T0(N% -M+/[__X/X@1 -M"/__B^5=PS/`4%!04%#H<*3__\QJ$&C`O$,`Z*H(__^#9>0`:@CH\+___UF# -M9?P`:@->B77@.S5\$D8`=%BA@!)&`(L$L(7`=$F+0`S!Z`VH`706H8`21@#_ -M-+#H3!,``%F#^/]T`_]%Y*&`$D8`BP2P@\`@4/\5U#!#`*&`$D8`_S2PZ(^@ -M__]9H8`21@"#)+``1NN=QT7\_O___^@)````BT7DZ&8(___#:@CHN;___UG# -MB_]5B^R+30A6C7$,BP8D`SP"=`0SP.M+BP:HP'3VBT$$5XLY*_B)`8-A"`"% -M_WXP5U!1Z*>V__]94.BT#@``@\0,._AT"VH06/`)!H/(_^L1BP;!Z`*H`70& -M:OU8\"$&,\!?7EW#B_]5B^Q6BW4(A?9U"5;H/0```%GK+E;H?O___UF%P'0% -M@\C_ZQZ+1@S!Z`NH`7025NA#MO__4.B7$P``65F%P'7?,\!>7<-J`>@"```` -M6<-J'&C@O$,`Z%0'__^#9>0`@V7<`&H(Z):^__]9@V7\`(LU@!)&`*%\$D8` -MC02&B474BUT(B77@._!T=(L^B7W8A?]T5E?H(K?__UG'1?P!````BT<,P>@- -MJ`%T,H/[`7415^A)____68/X_W0A_T7DZQR%VW48BT<,T>BH`70/5^@K____ -M68/X_W4#"47<@V7\`.@.````BT74@\8$ZY6+70B+=>#_==CHT[;__UG#QT7\ -M_O___^@4````@_L!BT7D=`.+1=SHVP;__\.+70AJ".@KOO__6<.+_U6+[%:+ -M=0A7C7X,BP?!Z`VH`70DBP?!Z`:H`70;_W8$Z*^>__]9N+_^___P(00```!S"8L$Q=A]0P!=PS/`7<.+_U6+ -M[%&+512+30A6A=)U#87)=0TY30QU(3/`ZRZ%R709BT4,AOI -MBW40A?9U&<8!`.AZH?__:A9>B3#H3Z#__XO&7HOE7<-3*_&+V%>+^8/Z_W41 -MB@0^B`='A,!T)8/K`77QZQZ*!#Z(!T>$P'0*@^L!=`6#Z@%U[(72BU44=0/& -M!P!?A=M;=8>#^O]U#8M%#&I0QD0!_P!8ZZ?&`0#H#:'__VHBZY&+_U6+[%WI -M1/___\S,S,Q5B^Q6,\!04%!04%!04(M5#(U)`(H""L!T"8/"`0^K!"3K\8MU -M"(O_B@8*P'0,@\8!#Z,$)'/QC4;_@\0@7LG#B_]5B^QJ`/]U#/]U".@%```` -M@\0,7<.+_U6+[(/L$(-]"`!U%.B0H/__QP`6````Z&2?__\SP.MG5HMU#(7V -M=1+H=*#__\<`%@```.A(G___ZP4Y=0AR!#/`ZT/_=1"-3?#H?U3__XM5^(-Z -M"`!T'(U._TDY30AW"@^V`?9$$!D$=?"+QBO!@^`!*_!.@'W\`'0*BTWP@Z%0 -M`P``_8O&7HOE7CKG___QP`6````Z+^>__^#R/]=P_]U"&H`_S7L%D8`_Q6(,4,`7<-J -M"&@(O4,`Z/("__^#/1@-1@`!?%N+10BH0'1*@SVP[4,``'1!@V7\``^N50CK -M+HM%[(L`@3@%``#`=`N!.!T``,!T`S/`PS/`0,.+9>B#);#M0P``@V4(OP^N -M50C'1?S^____ZPJ#X+^)10@/KE4(Z,\"___#B_]5B^Q1W7W\V^(/OT7\B^5= -MPXO_58OL45&;V7W\BTT,BT4(]]%F(TW\(T4,9@O(9HE-^-EM^`^_1?R+Y5W# -MB_]5B^R+30B#[`SVP0%T"MLM2)Y#`-M=_)OVP0AT$)O?X-LM2)Y#`-U=])N; -MW^#VP1!T"MLM5)Y#`-U=])OVP01T"=GNV>C>\=W8F_;!('0&V>O=7?2;B^5= -MPXO_58OL49O=??P/OT7\B^5=PXO_58OL5N@Z$P``BW4(B0;HB^5=PXO_58OL45 ?@`C47X -M@V7\`%#H@O___UF%P'0%,\!`ZRF+30B+5?B+1?R)002-1?B)$8/*'U")5?CH -M>/___UF%P'79Z,[:__\SP(OE7EI%``` -MD(,])!=&``!T,H/L"`^N7"0$BT0D!"6`?P``/8`?``!U#]D\)&:+!"1F@^!_ -M9H/X?XUD)`AU!>D5%```@^P,W10DZ"(;``#H#0```(/$#,.-5"0$Z,T:``!2 -MF]D\)'1,BT0D#&:!/"1_`G0&V2UHH$,`J0``\']T7JD```"`=4'9[-G)V?&# -M/0P71@``#X7L&@``C0U@GD,`NAL```#IZ1H``*D```"`=1?KU*G__P\`=1V# -M?"0(`'46)0```(!TQ=W8VRT@H$,`N`$```#K(N@X&@``ZQNI__\/`'7%@WPD -M"`!UOMW8VRW*GT,`N`(```"#/0P71@``#X6`&@``C0U@GD,`NAL```#H>1L` -M`%K#@STD%T8```^$OAT``(/L"`^N7"0$BT0D!"6`?P``/8`?``!U#]D\)&:+ -M!"1F@^!_9H/X?XUD)`@/A8T=``#K`/,/?D0D!&8/*!6`GD,`9@\HR&8/*/AF -M#W/0-&8/?L!F#U0%H)Y#`&8/^M!F#]/*J0`(``!T3#W_"P``?'UF#_/*/3(, -M``!_"V8/UDPD!-U$)`3#9@\N_WLDNNP#``"#[!")5"0,B]2#PA2)5"0(B50D -M!(D4).CY&@``@\00W40D!,/S#WY$)`1F#_/*9@\HV&8/PL$&/?\#``!\)3TR -M!```?[!F#U0%<)Y#`/(/6,AF#]9,)`3=1"0$P]T%L)Y#`,-F#\(=D)Y#``9F -M#U0=<)Y#`&8/UEPD!-U$)`3#B_]5B^R#[#BA:.9#`#/%B47\BT4,B\B#X#_! -M^093:]@P5HL$C9@21@!7BWT0B7W0B4W4BT08&(E%V(M%%`/'B47<_Q6$,4,` -MBW4(BTWB+1=2(;>6+%(68 -M$D8`BDP:+?;!!'09BD0:+H#A^XA%](U%]&H"B&WUB$P:+5#K.NB;L/__#[8/ -MN@"```!FA11(="0[?=P/@\$```!J`HU%Z%=0Z""<__^#Q`R#^/\/A-(```!' -MZQAJ`5>-1>A0Z`6<__^#Q`R#^/\/A+<````SR8U%[%%1:@50:@&-1>A'4%'_ -M=Q0_W78_Q5$,$,`A4*=2QJ#5AJ`&:)1>2-1>!0:@&-1>10_W78 -M_Q5$,$,`A+#)68$D8` -MB$09+HL$E9@21@"`3!@M!/]&!.L(_Q4`,$,`B0:+3?R+QE]>,\U;Z$[\_O^+ -MY5W#B_]5B^Q14U:+=0@SP%>+?0R)!HE&!(E&"(M%$`/'B47\._AS/P^W'U/H -MAAL``%EF.\-U*(-&!`*#^PIU%6H-6U/H;AL``%EF.\-U$/]&!/]&"(/'`CM] -M_'++ZPC_%0`P0P")!E^+QEY;B^5=PXO_58OL45:+=0A6Z#GV__]9A-A?SK__]04?\51#!#`(7`=!^+A?3K__\!1@0[ -MQW(:BX7XZ___BXWPZ___.]ARE^L(_Q4`,$,`B0:+3?R+QE]>,\U;Z(SZ_O^+ -MY5W#B_]5B^RX$!0``.BO\?[_H6CF0P`SQ8E%_(M-#(O!P?@&@^$_:\DP4XM= -M$(L$A9@21@!6BW4(5XM,"!B+110#PXF-\.O__S/2B87XZ___B1:)5@2)5@CK -M=8V]_.O__SO8#QP)FB0>-1?J#QP([ -M^(N%^.O__W+1C87\Z___*_B-A?3K__]J`%"#Y_Z-A?SK__]74%'_%40P0P"% -MP'0?BX7TZ___`48$.\=R&HN%^.O__XN-\.O__SO8^?[_B^5=PXO_58OLN!@4``#HP?#^_Z%HYD,`,\6)1?R+30R+ -MP<'X!H/A/VO),%-6BP2%F!)&`#/;BW4(5XM$"!B+31"+^8F%[.O__XM%%`/! -MB1Z)7@2)A?3K__^)7@@[R`^#N@```(NU].O__XV%4/G__SO^AE -ME?__QP`)````Z$>5__^#(`#K%/]U$/]U#%;H1P```(/$#(OXB7WDQT7\_O__ -M_^@*````B\?K*8MU"(M]Y%;H_LC__UG#Z`N5__^#(`#H%I7__\<`"0```.CJ -MD___@\C_Z'_X_O_#B_]5B^R#[#"A:.9#`#/%B47\BTT0B4WX5HMU"%>+?0R) -M?="%R74',\#IS@$``(7_=1_HN)3__R$XZ,24___'`!8```#HF)/__X/(_^FK -M`0``4XO&B][!^P:#X#]KT#")7>2+!)V8$D8`B474B57HBEP0*8#[`G0%@/L! -M=2B+P??0J`%U'>AEE/__@R``Z'"4___'`!8```#H1)/__^E1`0``BT74]D00 -M*"!T#VH":@!J`%;HT@$``(/$$%;HY/K__UF$P'0YA-MT(O[+@/L!#X?N```` -M_W7XC47L5U#H5OK__X/$#(OPZ9P```#_=?B-1>Q75E#HB_C__X/$$.OFBT7D -MBPR%F!)&`(M%Z/9$`2B`=$8/OL.#Z`!T+H/H`709@^@!#X6:````_W7XC47L -M5U90Z,/[___KP?]U^(U%[%=64.BA_/__Z['_=?B-1>Q75E#HQ/K__^NABT0! -M&#/)48E-[(E-\(E-](U-\%'_=?A74/\51#!#`(7`=0G_%0`P0P")1>R-=>R- -M?=BEI:6+1=R%P'5CBT78AO7^_XOE7<.+_U6+ -M[%%15HMU"%=6Z'''__^#S_]9.\=U$>C7DO__QP`)````B\>+U^M-_W44C4WX -M4?]U$/]U#%#_%7PQ0P"%P'4/_Q4`,$,`4.AQDO__6>O3BT7XBU7\(\([QW3' -MBT7XB\Z#YC_!^09K]C"+#(V8$D8`@&0Q*/U?7HOE7<.+_U6+[/]U%/]U$/]U -M#/]U".AL____@\007<.+_U6+[%:+=0B%]G45Z$N2___'`!8```#H'Y'__X/( -M_^M1BT8,5X//_\'H#:@!=#E6Z$?M__]6B_CHS>[__U;H&*3__U#H]`(``(/$ -M$(7`>06#S__K$X-^'`!T#?]V'.A]C?__@V8<`%E6Z'"G__]9B\=?7EW#:A!H -M2+U#`.@1]?[_BW4(B77@,\"%]@^5P(7`=17HQ9'__\<`%@```.B9D/__@\C_ -MZSN+1@S!Z`Q6J`%T".@GI___6>OH@V7D`.C;I/__68-E_`!6Z#'___]9B_") -M=>3'1?S^____Z`L```"+QNCQ]/[_PXMUY/]UX.B_I/__6<-J#&AHO4,`Z)'T -M_O\S]HEUY(M%"/\PZ`+%__]9B77\BT4,BP"+.(O7P?H&B\>#X#]KR#"+!)68 -M$D8`]D0(*`%T(5?HK<7__UE0_Q5,,$,`AC\D/__B_#_%0`P0P")!N@` -MD?__QP`)````@\[_B77DQT7\_O___^@-````B\;H7?3^_\(,`(MUY(M-$/\Q -MZ*K$__]9PXO_58OL@^P,BT4(C4W_B47XB47TC47X4/]U#(U%]%#H1/___XOE -M7<.+_U6+[%%6BW4(@_[^=0WHDY#__\<`"0```.M+A?9X-SLUF!1&`',OB\:+ -MUH/@/\'Z!FO(,(L$E9@21@#V1`@H`704C44(B47\C47\4%;HA?___UE9ZQ/H -M2Y#__\<`"0```.@?C___@\C_7HOE70`BT4(_S#H93'1?S^____Z`T```"+QNC5\O[_P@P`BW7DBT40_S#H(L/__UG#B_]5B^R# -M[`R+10B-3?^)1?B)1?2-1?A0_W4,C47T4.A:____B^5=PXO_58OL45:+=0B# -M_OYU%>CXCO__@R``Z`./___'``D```#K4X7V>#<[-9@41@!S+XO&B]:#X#_! -M^@9KR#"+!)68$D8`]D0(*`%T%(U%"(E%_(U%_%!6Z'W___]96>L;Z*B.__^# -M(`#HLX[__\<`"0```.B'C?__@\C_7HOE7<.+_U6+[%97BWT(5^@=P___68/X -M_W4$,_;K3J&8$D8`@_\!=0GV@(@````!=0N#_P)U'/9`6`%T%FH"Z.["__]J -M`8OPZ.7"__]963O&=,A7Z-G"__]94/\5&#!#`(7`=;;_%0`P0P"+\%?H+L+_ -M_UF+SX/G/\'Y!FO7,(L,C9@21@#&1!$H`(7V=`Q6Z-J-__]9@\C_ZP(SP%]> -M7<.+_U6+[(M5"#/)]\*`?@``=&>$TGD#:A!95[\``@``A==T`X/)"/?"``0` -M`'0#@\D$]\(`"```=`.#R0+WP@`0``!T`X/)`5:^`&```(O"(\8[QEYU"(') -M``,``.L:]\(`0```=`B!R0`!``#K"O?"`"```'0""\]?B\%=PXO_58OLBU4( -M,\GWPCT,``!T7?;"`70#:A!9]L($=`.#R0CVP@AT`X/)!/;"$'0#@\D"]L(@ -M=`.#R0%6O@`,``"+PB/&.\9>=0B!R0`#``#K'O?"``@``'0(@]\(``@``=`B!R0`$``#K#O?"``$``'0&@=0.#R1"X`0`!`"/0.]!U`X/)((O! -M7<.+_U6+[%%1,\`A1?AFB47\V7W\@ST8#48``7P$#ZY=^`^W1?Q64.BO_?__ -M_W7XB_#H*/W__UD+QEDE'P,``%Z+Y5W#B_]5B^Q143/`,\EFB47\B4WXW7W\ -M@ST8#48``7P$#ZY=^`^W5?R+P?;"/70R]L(!=`6X$``0`/;"!'0%#0@`"`#V -MP@AT!0T$``0`]L(0=`4-`@`"`/;"('0%#0$``0"+5?CVPCUT-O;"`70%N1`` -M`!#VP@1T!H')"```"/;""'0&@ -M6XOE7<.+_U6+[(/L(%-65S/_B7W@B7WDB7WHB7WLB7WPB7WTB7WXV77@NQ\` -M'Q]3Z`3^____=0B+\/?6(W7DZ/7]__]9"_!9B77DV67@@ST8#48``7PGB7W\ -M#ZY=_%/H=/W___]U"(OP]]8C=?SH9?W__UD+\%F)=?P/KE7\7UY;B^5=P\S, -MS,S,S,S,S,S,S&H*Z%47``"C)!=&`#/`P\Q5B^R#[`B#Y/#='"3S#WX$).@( -M````R<-F#Q)$)`2Z`````&8/*.AF#Q3`9@]SU31F#\7-`&8/*`W`GD,`9@\H -M%=">0P!F#R@=,)]#`&8/*"7@GD,`9@\H-?">0P!F#U3!9@]6PV8/6.!F#\7$ -M`"7P!P``9@\HH/"D0P!F#RBXX*!#`&8/5/!F#US&9@]9]&8/7/+R#UC^9@]9 -MQ&8/*.!F#UC&@>'_#P``@^D!@?G]!P``#X>^````@>G^`P```\KR#RKQ9@\4 -M]L'A"@/!N1````"Z`````(/X``]$T68/*`V`GT,`9@\HV&8/*!60GT,`9@]9 -MR&8/6=MF#UC*9@\H%:"?0P#R#UG;9@\H+0"?0P!F#UGU9@\HJA"?0P!F#U3E -M9@]8_F8/6/QF#UG(\@]9V&8/6,IF#R@5L)]#`&8/6=!F#RCW9@\5]F8/6L-QH5P_____C+MV>K>R>@K`0``V>C> -MP?:%8?___P%T!-GHWO'VPD!U`MG]"NUT`MG@Z;("``#H1@$```O`=!0R[8/X -M`G0"]M79R=GAZZ_IM0(``.E+`P``W=C=V-LMP)]#`,:%W9R=GD -MF]V]8/___YOVA6'___]!==+9\W9R0K)=:[9\2;W;U@ -M____F_:%8?___P%U#]W8VRW`GT,`"NUT`MG@P\:%GT,`WMF;W;U@____ -MF_:%8?___T%UE=G`V?S9Y)O=O6#___^;BI5A____V=`VX`0```,.X```` -M`.OXN`(```#K\5:#['2+]%:#[`C='"2#[`C='"2;W78(Z(('``"#Q!3=9@C= -M!H/$=%Z%P'0%Z=`!``##S,S,S,S,S,S,@'H.!7419HN=7/___X#/`H#G_K,_ -MZP1FNS\39HF=7O___]FM7O___[M.H$,`V>6)E6S___^;W;U@____QH5P____ -M`)N*C6'____0X=#YT,&*P20/UP^^P('A!`0``(O:`]B#PQ#_(X!Z#@5U$6:+ -MG5S___^`SP*`Y_ZS/^L$9KL_$V:)G5[____9K5[___^[3J!#`-GEB95L____ -MF]V]8/___\:%*X-#AT/G0P8K!)`_7T.30Y`K$#[[`@>$$!```B]H#V(/#$/\CZ,X` -M``#9R=W8P^C$````Z_;=V-W8V>[#W=C=V-GNA.UT`MG@P]W8W=C9Z,/;O6+_ -M___;K6+____VA6G___]`=`C&A7#___\`P\:%(``P``@\I_9HE4)`;9;"0&PZD```@` -M=`:X`````,/9H/@ -M('05F]_@9H/@('0,N`@```#HV0```%K#V2PD6L.#[`C=%"2+1"0$@\0()0`` -M\'_K%(/L"-T4)(M$)`2#Q`@E``#P?W0]/0``\']T7V:+!"1F/7\"="IF@^`@ -M=2&;W^!F@^`@=!BX"````(/Z'70'Z'L```!:P^A=````6L/9+"1:P]T%C*!# -M`-G)V?W=V=G`V>'<'7R@0P";W^">N`0```!SQ]P-G*!#`.N_W06$H$,`VW`V4H$,`ZY;,S,S,58OL@\3@B47@ -MBT48B47PBT4#=7?B)3>2+11"+312)1>B)3>R-10B- -M3>!045+HO@0``(/$#-U%^&:!?0A_`G0#V6T(R<.+_U6+[(/L)*%HYD,`,\6) -M1?R#/1`71@``5E=T$/\U(!=&`/\5,#)#`(OXZP6_8(1"`(M%%(/X&@^/(0$` -M``^$#P$``(/X#@^/IP````^$C@```&H"62O!='B#Z`%T:H/H!716@^@!#X6; -M`0``QT7@J*!#`(M%"(O/BW40QT7<`0```-T`BT4,W5WDW0"-1=S=7>S=!E#= -M7?3_%6`R0P#_UUF%P`^%60$``.@X@/__QP`A````Z4D!``")3=S'1>"HH$,` -MZ00!``#'1>"DH$,`ZZ*)3=S'1>"DH$,`Z>P```#'1=P#````QT7@L*!#`.G9 -M````@^@/=%&#Z`ET0X/H`0^%`0$``,=%X+2@0P"+10B+SXMU$,=%W`0```#= -M`(M%#-U=Y-T`C47"PH$,`Z[O9Z(M%$-T8Z:D```"#Z!MT6X/H`71*@^@5=#F#Z`ET*(/H`W07 -M+:L#``!T"8/H`0^%@````(M%"-T`Z\;'1>"XH$,`Z=G^___'1>#`H$,`Z#(H$,`Z<'^___'1>"TH$,`Z;7^___'1=P"````QT7@M*!#`(M%"(O/ -MBW40W0"+10S=7>3=`(U%W-U=[-T&4-U=]/\58#)#`/_7687`=0OHZG[__\<` -M(@```-U%]-T>BTW\7S/-7NA3X?[_B^5=PXO_58OL45%35K[__P``5F@_&P`` -MZ'??___=10B+V%E9#[=-#KCP?P``(\A14=T<)&8[R'4WZ$0+``!(65F#^`)W -M#E93Z$??___=10A96>MCW44(W070H$,`4X/L$-C!W5PD"-T<)&H,:@CK/^@M -M`P``W57XW44(@\0(W>'?X/;$1'H25MW94]W8Z`+?___=1?A96>L>]L,@=>E3 -M@^P0V'?X%E9W=GVQ$1Z*]P-`*E#`%%1W57XW1PDZ%8"``#=1?C:Z=_@ -M65GVQ$1Z!6H"6.L),\!`ZP3=V#/`B^5=PXO_58OLW44(N0``\'_9X;@``/#_ -M.4T4=3N#?1``=779Z-C1W^#VQ`5Z#]W9W=C=!9"J0P#IZ0```-C1W^#=V?;$ -M08M%&`^%V@```-W8V>[IT0```#E%%'4[@WT0`'4UV>C8T=_@]L0%>@O=V=W8 -MV>[IK0```-C1W^#=V?;$08M%&`^%G@```-W8W060JD,`Z9$```#=V#E-#'4N -M@WT(``^%@@```-GNW440V-'?X/;$00^$<____]C9W^#VQ`6+11A[8MW8V>CK -M7#E%#'59@WT(`'53W44045'='"3HM?[__]GNW44065G8T8O(W^#VQ$%U$]W9 -MW=C=!9"J0P"#^0%U(-G@ZQS8V=_@]L0%>@^#^0%U#MW8W06@JD,`ZP3=V-GH -MBT48W1@SP%W#B_]3B]Q148/D\(/$!%6+:P2);"0$B^R![(@```"A:.9#`#/% -MB47\BT,05HMS#%+ -M2PB#^1!T$(/Y%G0+@_D==`:#9<#^ZQ*+1<#=1A"#X..#R`/=7;")1<"-1AA0 -MC48(4%%7C85\____4(U%@%#H0@,``(/$&(N-?/___VC__P``4>@HW/__@SX( -M65ET%.@2<___A,!T"U;H-W/__UF%P'4(_S;H(`8``%F+3?Q?,\U>Z+C=_O^+ -MY5V+XUO#B_]5B^Q14=U%"-G\W5WXW47XB^5=PXO_58OLBT4(J"!T!&H%ZQ>H -M"'0%,\!`7<.H!'0$:@+K!J@!=`5J`UA=PP^VP(/@`@/`7<.+_U.+W%%1@^3P -M@\0$58MK!(EL)`2+[('LB````*%HYD,`,\6)1?Q6BW,@C4,85U90_W,(Z)4` -M``"#Q`R%P'4F@V7`_E"-0QA0C4,04/]S#(U#(/]S"%"-18!0Z'$"``"+[<&=_@]L0%>RS= -M!9BJ0P#K,HM-#-GNW!G?X/;$!7H>W068JD,`ZQZ+30S9[MP9W^#VQ`5Z"-T% -MD*I#`.L(W060JD,`V>#=&8/F_NG4````]L,"#X3+````]D40$`^$P0```%[:Z=_@]L1$#XN1````W0&-1?Q045'='"3HG`0``(M% -M_(/$#`4`^O__B47\W57PV>X]SOO__WT',__>R4?K6=[9,]+?X/;$074!0HM% -M]KD#_/__@^`/@\@09HE%]HM%_#O!?2LKR(M%\/9%\`%T!87_=0%'T>CV1?0! -MB47P=`@-````@(E%\-%M](/I`77:W47PA=)T`MG@BT4,W1CK`S/_1X7_7W0( -M:A#H3=G__UF#YOWVPQ!T$?9%$"!T"VH@Z#?9__]9@^;O,\"%]EX/E,!;B^5= -MPXO_58OL:@#_=1S_=1C_=13_=1#_=0S_=0CH!0```(/$'%W#B_]5B^R+10@S -MR5,SVT.)2`2+10A7OPT``,")2`B+10B)2`R+31#VP1!T"XM%"+^/``#`"5@$ -M]L$"=`R+10B_DP``P(-(!`+VP0%T#(M%"+^1``#`@T@$!/;!!'0,BT4(OXX` -M`,"#2`0(]L$(=`R+10B_D```P(-(!!"+30A6BW4,BP;!X`3WT#-!"(/@$#%! -M"(M-"(L&`\#WT#-!"(/@"#%!"(M-"(L&T>CWT#-!"(/@!#%!"(M-"(L&P>@# -M]]`S00B#X`(Q00B+!HM-",'H!??0,T$((\,Q00CH?]C__XO0]L(!=`>+30B# -M20P0]L($=`>+10B#2`P(]L((=`>+10B#2`P$]L(0=`>+10B#2`P"]L(@=`:+ -M10@)6`R+!KD`#```(\%T-3T`!```="(]``@``'0,.\%U*8M%"(,(`^LABTT( -MBP&#X/Z#R`*)`>L2BTT(BP&#X/T+P^OPBT4(@R#\BP:Y``,``"/!="`]``(` -M`'0,.\%U(HM%"(,@X^L:BTT(BP&#X.>#R`3K"XM-"(L!@^#K@\@(B0&+10B+ -M313!X04S"('AX/\!`#$(BT4("5@@@WT@`'0LBT4(@V`@X8M%&-D`BT4(V5@0 -MBT4("5A@BT4(BUT<@V!@X8M%"-D#V5A0ZSJ+30B+02"#X..#R`*)02"+11C= -M`(M%"-U8$(M%"`E88(M-"(M='(M!8(/@XX/(`HE!8(M%"-T#W5A0Z*#6__^- -M10A0:@%J`%?_%90Q0P"+30CV00@0=`.#)O[V00@(=`.#)OOV00@$=`.#)O?V -M00@"=`.#)N_V00@!=`.#)M^+`;K_\___@^`#@^@`=#6#Z`%T(H/H`70-@^@! -M=2B!#@`,``#K((L&)?_[__\-``@``(D&ZQ"+!B7_]___#0`$``#K[B$6BP'! -MZ`*#X`>#Z`!T&8/H`70)@^@!=1HA%NL6BP8CP@T``@``ZPF+!B/"#0`#``") -M!H-](`!>=`?905#9&^L%W4%0W1M?6UW#B_]5B^R+10B#^`%T%8/`_H/X`7<8 -MZ`MU___'`"(```!=P^C^=/__QP`A````7<.+_U6+[(M5#(/L(#/)B\$Y%,68 -MJ4,`=`A`@_@=?/'K!XL,Q9RI0P")3>2%R715BT40B47HBT44B47LBT48B47P -MBT4<5HMU"(E%](M%(&C__P``_W4HB47XBT4DB77@B47\Z%'5__^-1>!0Z&UL -M__^#Q`R%P'4'5NA5____6=U%^%[K&VC__P``_W4HZ"?5____=0CH.?___]U% -M((/$#(OE7<.+_U6+[-U%"-GNW>'?X%?VQ$1Z"=W9,__IKP```%9FBW4.#[?& -MJ?!_``!U?(M-#(M5"/?!__\/`'4$A=)T:M[9OP/\___?X/;$074%,\!`ZP(S -MP/9%#A!U'P/)B4T,A=)Y!H/)`8E-#`/23_9%#A!TZ&:+=0Z)50BY[_\``&8C -M\6:)=0Z%P'0,N`"```!F"_!FB74.W44(:@!14=T<).@Q````@\0,ZR-J`%'= -MV%'='"3H'@````^W_H/$#,'O!('G_P<``('O_@,``%Z+11").%]=PXO_58OL -M45&+31`/MT4.W44()0^```#=7?B-B?X#``#!X00+R&:)3?[=1?B+Y5W#B_]5 -MB^R!?0P``/!_BT4(=0>%P'450%W#@7T,``#P_W4)A$`@```9H7`=1[W10S__P\`=0:#?0@`=`_WV1O)@^&0C8&` -M````7"-04!=P_?9&\F!X0C___^-@0`! -M``!=P\S_):@Q0P#_)=`Q0P#,S,S,S,S,S%6+[(M%"#/24U97BT@\`\@/MT$4 -M#[=9!H/`&`/!A=MT&XM]#(MP##O^<@F+2`@#SCOY<@I"@\`H.]-RZ#/`7UY; -M76XOE7<.+1>R+`#/)@3@%``#`#Y3!B\'#BV7HQT7\_O__ -M_S/`BTWP9(D-`````%E?7EN+Y5W#S,S,S,S,58OLBT4(N4U:``!F.0AT!#/` -M7<.+2#P#R#/`@3E010``=0RZ"P$``&8Y41@/E,!=PU!D_S4`````C40D#"MD -M)`Q35E>)*(OHH6CF0P`SQ5")9?#_=?S'1?S_____C47T9*,`````\L/,S,S, -MS,S,S%:+1"04"\!U*(M,)!"+1"0,,]+W\8O8BT0D"/?QB_"+P_=D)!"+R(O& -M]V0D$`/1ZT>+R(M<)!"+5"0,BT0D"-'IT=O1ZM'8"\EU]/?SB_#W9"04B\B+ -M1"00]^8#T7(..U0D#'<(<@\[1"0(=@E.*T0D$!M4)!0SVRM$)`@;5"0,]]KW -MV(/:`(O*B].+V8O(B\9>PA``S,S,S,S,S,S,S,QH4"%"`&3_-0````"+1"00 -MB6PD$(UL)!`KX%-65Z%HYD,`,47\,\6)1>10B67H_W7XBT7\QT7\_O___XE% -M^(U%\&2C`````/+#BTWD,\WRZ`;2_O_RZ?S2_O_,S,S,S,Q1C4PD""O(@^$/ -M`\$;R0O!6>D:R?[_48U,)`@KR(/A!P/!&\D+P5GI!,G^_\S,S,R#/1@-1@`` -M=#=5B^R#[`B#Y/C='"3R#RP$),G#@ST8#48``'0;@^P$V3PD6&:#X']F@_A_ -M=-.-I"0`````C4D`58OL@^P@@^3PV<#95"08WWPD$-]L)!"+5"08BT0D$(7` -M=#S>Z872>1[9'"2+#"2!\0```("!P?___W^#T`"+5"04@](`ZRS9'"2+#"2! -MP?___W^#V`"+5"04@]H`ZQ2+5"04]\+___]_=;C97"08V5PD&,G#S,S,S,S, -MS,S,S,Q5B^Q7@ST8#48``0^"_0```(M]"'=W#[95#(O"P>(("]!F#V[:\@]P -MVP`/%MNY#P```"//@\C_T^`K^3/2\P]O#V8/[])F#W319@]TRV8/U\HCR'48 -M9@_7R2/(#[W!`\>%R0]%T(/(_X/'$.O04V8/U]DCV-'A,\`KP2/(22/+6P^] -MP0/'AMF#V["@\<09@\Z8T?P0(U,#_`/0L%U[5_)P[CP____(\=F#^_`9@]T -M`+D/````(\^Z_____]/B9@_7^"/Z=11F#^_`9@]T0!"#P!!F#]?XA?]T[`^\ -MUP/"Z[V+?0@SP(/)__*N@\$!]]F#[P&*10S]\JZ#QP$X!W0$,\#K`HO'_%_) -MPXM-\.G!>/W_BTWP@<$H$```Z65!_?^+3?"!P>@@``#I@ZO]_XM-\('!@"(` -M`.E@]_S_BTWP@<'010``Z5+W_/]H\((``/]U[.C1Q?[_65G#N(BQ0P#IX^#^ -M_[@XL4,`Z=G@_O^-3#I4O;\_[@0LD,`Z:/@_O^-323IZ__\_[@\LD,`Z9'@_O^-33#IV?_\ -M_[AHLD,`Z7_@_O^-C109___I__W]_[B4LD,`Z6K@_O^+3?#I69/]_XM-\('! -M'*,``.G$._W_BTWP@<%\HP``Z;8[_?^+3?"!P=RC``#IJ#O]_XM-\('!/*0` -M`.F:._W_BTWP@<&SH -M6<3^_UE9P[A4M$,`Z6O?_O^-C:AB___I3_7\_[CLLT,`Z5;?_O^-C<3^___I -M=LS]_XV-G-[__^G,=OW_N(BT0P#I-M_^_XV-N.___^FW=OW_C4W@Z8'T_/^X -M(+1#`.D9W_[_C4W@Z6_T_/^XM+1#`.D'W_[_C8W(W___Z8AV_?^XX+1#`.GR -MWO[_BTWP@<$D4```Z0_,_?^+3?"!P7!A``#I@I']_[@4M4,`Z_O^+3?"! -MP9````#I6(G]_XM-\('!I````.E*B?W_BTWP@<&X````Z3R)_?]HP!```/]U -M[.AVP_[_65G#:,`0``#_=>SH9L/^_UE9P[@XM4,`Z7C>_O^-C?S<___I^77] -M_[B,M4,`Z6/>_O^+3?"#P03IE(?]_XM-\(/!).FK\_S_BTWP@\$XZ:#S_/^+ -M3?"#P4SI9_O]_XM-\('!1$L``.FD^_W_BTWP@<'8F```Z9O[_?^+3?"!P63F -M``#I4)W]_[A@MD,`Z0/>_O^-3<3I6?/\_[@\MD,`Z?'=_O\SVXM%\+GD2@`` -M]^$/D,/WVPO8,\"#PP0/DL#WV`O#4/]U[.CZR?[_65G#N+BU0P#IO-W^_XU- -MU.D2\_S_N.2U0P#IJMW^_XU-V.D`\_S_N!"V0P#IF-W^_V@X`P``_W7PZ&S" -M_O]96<.XQ+9#`.E^W?[_C8W<@O__Z6+S_/^-3=SI$//\_[@`N$,`Z6'=_O^- -MC63.___IXG3]_[@LN$,`Z4S=_O^-C:AR___I@X/]_[A8N$,`Z3?=_O^-C?#> -M___IZ5K]_[B(MT,`Z2+=_O^+5"0(C4(,BTKL,\CHI\O^_[@8ND,`Z0?=_O_, -MS,RYZ`Y$`.GSJ_W_S,S,S,S,N<"!1`#I^M0#`(S4`P"HU`,`OM0#`-34`P#> -MU`,`ZM0#`/;4`P`$U0,`%M4#`";5`P`ZU0,`2M4#`%S5`P!HU0,`>M4#`)35 -M`P`2U@,``````*#2`P".T@,`<-(#`%#2`P`RT@,`'M(#``S2`P``T@,`]-$# -M``````!0,D(``````'#M00``$$``$!!``"`00`!`$$``4!!``&`00`"P$$`` -MT!!``'`00`"0$$````````````"P[$$`8.U!`'!:0@"@GD(`<.Q"`!`#0P`` -M``````````"&0@"P&4,`<)]"```````````````````0````$!`````@$``` -M`$`0````4!````!@$````'`0````D!````"P$````-`0````T!8```#`'0`` -M`+`_````D&`````080```$"8````<)@```!0FP```)"=````T)X```#@GP`` -M`$"J````T-$```!PT@```*#2````$-,````PTP```````D-,```"@#`$` -M`-`<`0``\!P!```@'0$``+`>`0``D!\!``#0<@$``/"&`0``T(L!``#@BP$` -M`/"+`0```(P!```0C`$``"",`0``P(P!``#0C`$``.",`0``,(T!``!`C0$` -M`-"-`0``X(T!``#PC0$``!".`0``((X!```PC@$``$".`0``<(X!``"`C@$` -M`!"/`0``((\!``#@D@$```"4`0``\)0!````E0$``!"5`0``()4!```PE0$` -M``"6`0``,)8!``!`E@$``%"6`0``8)8!``!PE@$``&"8`0``<)@!``#`F0$` -M`-"9`0``X)D!``#PF0$```":`0``$)H!```@F@$``+"=`0``\)T!``#`I@$` -M`""L`0``8*\!``!PL0$``'"[`0``4,\!``#0YP$``+#L`0``8.T!``!P[0$` -M`/#N`0``$.\!``!0[P$``!#S`0```/0!``"@]`$``%`A`@`!0","``"@)`(` -M`$`E`@``@"4"``!0,@(``/`R`@``4#<"``!P6@(``"!^`@``0'X"``"@@@(` -M`,""`@``X(("``#P@@(```"#`@``0(,"``!0@P(``&"$`@```(8"``"@D0(` -M`,"3`@``\),"``"@G@(``'"?`@``<*$"``#0H0(``,"F`@``(*<"```@JP(` -M`-"K`@``$*P"``"@M0(``%"Y`@``H+H"``#`N@(``'#L`@``$`,#``"P&0,` -M`&`C`P``<",#``"`(P,``)`C`P``H",#``"P(P,``````````````````"H` -M````````T!9``%";0`!PF$``D)U``-">0`#@GT``P!U```````!-`&$`>`!I -M`&T`=0!M`"``80!L`&P`;P!W`&4`9``@`&$`<@!R`&$`>0`@`',`:0!Z`&4` -M(``H`"4`=0`I`"``:0!S`"``90!X`&,`90!E`&0`90!D````0P!-`%0```!2 -M`%(``````&@`)0!U````:`!C`"4`=0``````>``E`'4```!X`&,`)0!U```` -M```````````````````[`"4`=0```````````0(#!`4&!P@)"@L,#0X/#@H$ -M"`D/#08!#``""P<%`PL(#``%`@\-"@X#!@!;9^8):H6N9[MR\VX\.O5/I2X`7```````4P!E`%,`90!C`'4` -M<@!I`'0`>0!0`'(`:0!V`&D`;`!E`&<`90```%,`90!2`&4`0````!#`'(`>0!P`'0` -M4`!R`&\`=`!E`&,`=`!-`&4`;0!O`'(`>0`@`&8`80!I`&P`90!D````0P!R -M`'D`<`!T`%4`;@!P`'(`;P!T`&4`8P!T`$T`90!M`&\`<@!Y`"``9@!A`&D` -M;`!E`&0`````````F"^*0I%$-W'/^\"UI=NUZ5O"5CGQ$?%9I((_DM5>'*N8 -MJ@?8`5N#$KZ%,23#?0Q5=%V^!1XR(0(`L>,^O^^D.ML4*3WH_F^\GAQQ@`` -M``!X;&ES='!O5<`````4V5T1&5F875L=$1L;$1I0!P`'0`8@!A`',` -M90`N`&0`;`!L````;`!P`&L`+@!D`&P`;````'4`0!P`'0`,P`R`"X`9`!L`&P```!M`',`80!S`&X`,0`N`&0`;`!L``````!C -M`'(`>0!P`'0`=0!I`"X`9`!L`&P```!W`&D`;@!T`'(`=0!S`'0`+@!D`&P` -M;```````0!L`&4`/@```#P`+P!S`'0`>0!L`&4` -M/@```````````#P`0![`&8`;P!N`'0`+0!F -M`&$`;0!I`&P`>0`Z`"(`00!R`&D`80!L`"(`.P!F`&\`;@!T`"T``!M`&$`<`!P`&D`;@!G`&8`:0!L`&4`+@!T`&T`<````````!P`&$`<@``````3`!)`$,`10!.`%,`10!$`$P`1P``````(``` -M`%\`7P!T`&T`<`!?`'(`80!R`%\`&-L=7-I=F4`4F5L96%S95-25TQO8VM% -M>&-L=7-I=F4```````````!32$Q705!)+F1L;```````0T]-0U1,,S(N9&QL -M`````!2K0P#0YT$`7``````````````````````````````````````````` -M````````````````````````````````````:.9#`)"L0P`E````8#)#```` -M``#4,D,`D``````U`1!`!```` -M```````````#````(`63&0``````````H"1"`$"L0P"`)4(`\(9!`&)A9"!E -M>&-E<'1I;VX```#X54,`#%9#`$A60P!@.T,`80!D`'8`80!P`&D`,P`R```` -M```\`'``:0`M`&T`0!N`&,`:``M`&P`,0`M`#(`+0`P```````!`````P```$9L0P!?7V)A/0``8'9F=&%B;&4G````8'9B=&%B;&4G```` -M8'9C86QL)P!@='EP96]F)P````!@;&]C86P@2!C;VYS -M=')U8W1O'AX>`@'"`<`!P`( -M"`@```@'"``'"``'`"AN=6QL*0``*`!N`'4`;`!L`"D````````````%``#` -M"P`````````=``#`!`````````"6``#`!`````````"-``#`"`````````". -M``#`"`````````"/``#`"`````````"0``#`"`````````"1``#`"``````` -M``"2``#`"`````````"3``#`"`````````"T`@#`"`````````"U`@#`"``` -M```````,`````P````D```!M`',`8P!O`'(`90!E`"X`9`!L`&P```!#;W)% -M>&ET4')O8V5S0``5'5E0!7961N97-D87D` -M``!4:'5R0````!&0````!! -M=6=U0````!D9&1D+"!-34U-(&1D+"!Y>7EY -M`$A(.FUM.G-S`````%,`=0!N````30!O`&X```!4`'4`90```%<`90!D```` -M5`!H`'4```!&`'(`:0```%,`80!T````4P!U`&X`9`!A`'D``````$T`;P!N -M`&0`80!Y``````!4`'4`90!S`&0`80!Y````5P!E`&0`;@!E`',`9`!A`'D` -M``!4`&@`=0!R`',`9`!A`'D``````$8`<@!I`&0`80!Y``````!3`&$`=`!U -M`'(`9`!A`'D``````$H`80!N````1@!E`&(```!-`&$`<@```$$`<`!R```` -M30!A`'D```!*`'4`;@```$H`=0!L````00!U`&<```!3`&4`<````$\`8P!T -M````3@!O`'8```!$`&4`8P```$H`80!N`'4`80!R`'D```!&`&4`8@!R`'4` -M80!R`'D``````$T`80!R`&,`:````$$`<`!R`&D`;````$H`=0!N`&4````` -M`$H`=0!L`'D``````$$`=0!G`'4`0``````9`!D`&0`9``L`"``30!-`$T`30`@`&0`9``L`"``>0!Y`'D`>0`` -M`$@`2``Z`&T`;0`Z`',`&1# -M`(AD0P"<9$,`L&1#`+AD0P#`9$,`U&1#`/QD0P`094,`````````(``@`"`` -M(``@`"``(``@`"``*``H`"@`*``H`"``(``@`"``(``@`"``(``@`"``(``@ -M`"``(``@`"``(``@`$@`$``0`!``$``0`!``$``0`!``$``0`!``$``0`!`` -MA`"$`(0`A`"$`(0`A`"$`(0`A``0`!``$``0`!``$``0`($!@0&!`8$!@0&! -M`0$!`0$!`0$!`0$!`0$!`0$!`0$!`0$!`0$!`0$!`0$!`0$!`0$!`0$0`!`` -M$``0`!``$`""`8(!@@&"`8(!@@$"`0(!`@$"`0(!`@$"`0(!`@$"`0(!`@$" -M`0(!`@$"`0(!`@$"`0(!$``0`!``$``@`"``(``@`"``(``H`"``(``@`"`` -M(``@`"``(``@`"``(``@`"``(``@`"``(``@`"``(``@`"``(``@`"``(``( -M`!``$``0`!``$``0`!``$``0`!(!$``0`#``$``0`!``$``4`!0`$``2`1`` -M$``0`!0`$@$0`!``$``0`!```0$!`0$!`0$!`0$!`0$!`0$!`0$!`0$!`0$! -M`0$!`0$!`0$!`0$!`0$!`0$!`1```0$!`0$!`0$!`0$!`0$"`0(!`@$"`0(! -M`@$"`0(!`@$"`0(!`@$"`0(!`@$"`0(!`@$"`0(!`@$"`0(!`@$0``(!`@$" -M`0(!`@$"`0(!`@$!`0`````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M````(``@`"``(``@`"``(``@`"``*``H`"@`*``H`"``(``@`"``(``@`"`` -M(``@`"``(``@`"``(``@`"``(``@`$@`$``0`!``$``0`!``$``0`!``$``0 -M`!``$``0`!``A`"$`(0`A`"$`(0`A`"$`(0`A``0`!``$``0`!``$``0`($` -M@0"!`($`@0"!``$``0`!``$``0`!``$``0`!``$``0`!``$``0`!``$``0`! -M``$``0`0`!``$``0`!``$`""`((`@@""`((`@@`"``(``@`"``(``@`"``(` -M`@`"``(``@`"``(``@`"``(``@`"``(`$``0`!``$``@```````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````"`@8*#A(6&AXB)BHN,C8Z/D)&2DY25EI>8 -MF9J;G)V>GZ"AHJ.DI::GJ*FJJZRMKJ^PL;*SM+6VM[BYNKN\O;Z_P,'"P\3% -MQL?(R+CY.7FY^CIZNOL[>[O\/'R -M\_3U]O?X^?K[_/W^_P`!`@,$!08'"`D*"PP-#@\0$1(3%!46%Q@9&AL<'1X? -M("$B(R0E)B7I;7%U>7V!A8F-D969G:&EJ:VQM;F]P<7)S='5V=WAY -M>GM\?7Y_@(&"@X2%AH>(B8J+C(V.CY"1DI.4E9:7F)F:FYR=GI^@H:*CI*6F -MIZBIJJNLK:ZOL+&RL[2UMK>XN;J[O+V^O\#!PL/$Q<;'R,G*R\S-SL_0T=+3 -MU-76U]C9VMOKK[.WN[_#Q\O/T]?;W^/GZ^_S]_O^` -M@8*#A(6&AXB)BHN,C8Z/D)&2DY25EI>8F9J;G)V>GZ"AHJ.DI::GJ*FJJZRM -MKJ^PL;*SM+6VM[BYNKN\O;Z_P,'"P\3%QL?(R+CY.7FY^CIZNOL[>[O\/'R\_3U]O?X^?K[_/W^_P`!`@,$!08' -M"`D*"PP-#@\0$1(3%!46%Q@9&AL<'1X?("$B(R0E)B7V!! -M0D-$149'2$E*2TQ-3D]045)35%565UA96GM\?7Y_@(&"@X2%AH>(B8J+C(V. -MCY"1DI.4E9:7F)F:FYR=GI^@H:*CI*6FIZBIJJNLK:ZOL+&RL[2UMK>XN;J[ -MO+V^O\#!PL/$Q<;'R,G*R\S-SL_0T=+3U-76U]C9VMOKK[.WN[_#Q\O/T]?;W^/GZ^_S]_O_@;D,`*&]#``Q60P!H;T,`H&]#`.AO -M0P!(<$,`E'!#`$A60P#0<$,`$'%#`$QQ0P"(<4,`V'%#`#!R0P"(@!A`'0`:0!O`&X`+0!L`#$`+0`R -M`"T`,0```#P`<`!I`"T`;0!S`"T`=P!I`&X`+0!C`&\`<@!E`"T`;`!O`&,` -M80!L`&D`>@!A`'0`:0!O`&X`+0!O`&(`0!S`&D`;@!F`&\`+0!L`#$`+0`R`"T`,0``````/`!P`&D`+0!M`',` -M+0!W`&D`;@`M`&,`;P!R`&4`+0!W`&D`;@!R`'0`+0!L`#$`+0`Q`"T`,``` -M````/`!P`&D`+0!M`',`+0!W`&D`;@`M`&,`;P!R`&4`+0!X`',`=`!A`'0` -M90`M`&P`,@`M`#$`+0`P````80!P`&D`+0!M`',`+0!W`&D`;@`M`'(`=`!C -M`&\`<@!E`"T`;@!T`'4``!T`"T`;0!S`"T`=P!I`&X`+0!N`'0`=0!S`&4`<@`M`&0`:0!A -M`&P`;P!G`&(`;P!X`"T`;``Q`"T`,0`M`#```````&4`>`!T`"T`;0!S`"T` -M=P!I`&X`+0!N`'0`=0!S`&4`<@`M`'<`:0!N`&0`;P!W`',`=`!A`'0`:0!O -M`&X`+0!L`#$`+0`Q`"T`,```````=0!S`&4`<@`S`#(```````(````2```` -M`@```!(````"````$@````(````2``````````X```!'971#=7)R96YT4&%C -M:V%G94ED``@````2````!````!(```!,0TUA<%-TQVL%````````0.KM=$;0G"R?#`````!A];FK -MOZ1DCJ]6J9]'!C:R -M2UW@7]R`"JK^\$#9CJC0@!IK(V,``&0X3#*6QU>#U4)*Y&$BJ=D]$#R]6V%/;FDJ>Q@^=71E"F[S5MFEBX[HMM]^F6L -M4]YWFZ(@L%/YO\:K)91+3>,$`($MP_OTT")24"@/M_/R$U<3%$+)3W`L!T&XP`7?"P -M=<;;J12YV>+?<@]E3$LH=Q;@]FW"D4-1S\F5)U6KXM8GYJBX<6:#Z*/#TS3^E+AF@<=:\AT1I?0%N -M^1"=5AIY=:2/``#ALKD\=8B"DQ8_S6LZM(G>AYX(1D5-:`RFV_V1DR3?$^QH -M,"=$M)GN08&VP\H"6/%1:-FB)79]C7%.`0``9/OF@UKR#ZU7E!&U@`!FM2D@ -MS]+%UWUM/Z4<3;?-WG"=VCU!%K=.RM!QF!/DUY`Z0$_B/ZOY;W=-)N:O"@,` -M```0,56K"=)8#*;+)F%6AX,<:L'TAW5VZ$0LST>@09X%",D^!KJ@Z,C/YU7` -M^N&R1`'OL'X@)',EZ8L2FF5OQXI',3'JM+5V';'-M$,5=J3D)W'FJC+2R48=O`-"8BH -M]W00'SK\$4CEK8YC61#GRY?H:=5Y3@.4Y`$```````"AZ=1< -M;&]]Y)OGV3OYH6]B=U$TB\;H62O>6-X\SUC_1B(5?%>H677G)E-G=Q=CM^;K -M7PK]XVDYZ#,UH`6HA[DQ]D,/'R';0UK8EO4;JZ(9/V@$````9/Y]OB\$R4NP -M[?7AVDZACW/;">2<[D]G#9\5J=:UM?8.ECASD<))Z\R7*U^5/S@/]K.1(!0W -M>-'?0M'!WB(^%5??KXI?Y?5WB\KGHUM2+P,]3^=""@`````0W?12"45=X4*T -MKBXTLZ-OH\T_;GHHM/=WP4O0R-)GX/BHKF<[R:VS5LAL"YV=E0#!2%L]BKY* -M]#;94DWHVW'%(1SY"8%%2FK8JM=\3.$(G*6;=0"(/.07``````!`DM00\02^ -M!0IKU'\.9?K)14P*TP+#@.A.SS^*+K\B'=80YZXI.0]<\+R -M1GR88G2/#R$9VZZVHRZR%%"JC:LYZD(TEI>IW]\!_M/STH`">:`W`````9N< -M4/&MW,H&J)M1^/(#Q*+A4J`Z(Q#7J7.%1+K9$L\#&(=P -MFSK<4NA2LN5.^Q<'+Z9-ON'7JPI/[6*,>^RYSB%`9M0`@Q6AYG7CS/(I+X2! -M`````.07=V3[]=-Q/7:@Z2\4?69,]#,N\;CSC@T/$VF43'.H#R9@0!,!/`J( -M<)\[9=2Q&'#8JK8VH?>ZC.X86CP -ME+V:S!-JU<&-+0$`````$!/H-GK&GBD6]`H_2?//IJ5WHR.^I();HLPOO+K^K'8R(4PN,LT3/K21_G`VV5R[A9<40OT:S$;X -MW3CFTH<':1?1`AK^\;4^KJNYPV_N"!R^`@``````0*K"0('9=_@L/=?A<9@O -MY]4)8U%RW1FHKT9:*M;.W`(J_MU&SHTD$R>MTB.W&;L$Q"O,!K?*Z[%'W$L) -MG8Q@%;#CJA8+S1"'@2+%.6__A/\_P4/>6-G_3;59G90X;EB!@`` -M`&&P9QH*`=+`X070.W,2VS\NGZ/BG;)AXMQC*KP$)I2;U7!AEB7CPKEU"Q0A -M+!T?8&H3N*([THES??%@W]?*QBO?:08WA[@D[0:39NMN21EOVXV3=8)T7C:: -M;L4QMY`VQ4(HR(YYKB3>#@````!D0<&:B-69+$/9&N>`HBX]]FL]>4F"0ZGG -M>4KF_2*:<-;@[\_*!=>DC;UL`&3CL]Q.I6X(J*&>18]TR%2._%?&=,S4P[A" -M;F/95\Q;M37I_A-L85'$&MNZE;6=3O&A4.?YW'%_8PG2(``````!") -MO5X\5C=WXSBCRSU/GM*!+)[WI'3'^<.7YQQJ..1?K)R+\P?Z[(C5K,%:/L[, -MKX5P/Q^=TVTMZ`P8?1=OE&E>X2R.9$@YH941X`\T6#P7M)3V2">]5R9\+MJ+ -M=:"0@#L3MMLMD$C/;7X$Y"294````````@(```,%```$"0`!!`T``042``$& -M&``"!AX``@(5#`!$```"`A4,`$@```(B%0P`3````D(5#`!0```"8A4,` -M%0```*"%0P`6````J(5#`!@```"PA4,`&0```+B%0P`:````P(5#`!L```#( -MA4,`'````-"%0P`=````V(5#`!X```#@A4,`'P```.B%0P`@````\(5#`"$` -M``#XA4,`(@```.AS0P`C`````(9#`"0````(AD,`)0```!"&0P`F````&(9# -M`"<````@AD,`*0```"B&0P`J````,(9#`"L````XAD,`+````$"&0P`M```` -M2(9#`"\```!0AD,`-@```%B&0P`W````8(9#`#@```!HAD,`.0```'"&0P`^ -M````>(9#`#\```"`AD,`0````(B&0P!!````D(9#`$,```"8AD,`1````*"& -M0P!&````J(9#`$<```"PAD,`20```+B&0P!*````P(9#`$L```#(AD,`3@`` -M`-"&0P!/````V(9#`%````#@AD,`5@```.B&0P!7````\(9#`%H```#XAD,` -M90````"'0P!_````M#5#``$$```(AT,``@0``!2'0P`#!```((=#``0$``#< -M(I#`($$``"$BD,``0@``)"* -M0P`$"```Q'-#``<(``"0``````80!Z``````!E`'4``````&T`:P``````80!F``````!K -M`&$``````&8`;P``````:`!I``````!M`',``````&L`:P``````:P!Y```` -M``!S`'<``````'4`>@``````=`!T``````!P`&$``````&<`=0``````=`!A -M``````!T`&4``````&L`;@``````;0!R``````!S`&$``````&T`;@`````` -M9P!L``````!K`&\`:P```',`>0!R````9`!I`'8```!A`'(`+0!3`$$```!B -M`&<`+0!"`$<```!C`&$`+0!%`%,```!C`',`+0!#`%H```!D`&$`+0!$`$L` -M``!D`&4`+0!$`$4```!E`&P`+0!'`%(```!F`&D`+0!&`$D```!F`'(`+0!& -M`%(```!H`&4`+0!)`$P```!H`'4`+0!(`%4```!I`',`+0!)`%,```!I`'0` -M+0!)`%0```!N`&P`+0!.`$P```!N`&(`+0!.`$\```!P`&P`+0!0`$P```!P -M`'0`+0!"`%(```!R`&\`+0!2`$\```!R`'4`+0!2`%4```!H`'(`+0!(`%(` -M``!S`&L`+0!3`$L```!S`'$`+0!!`$P```!S`'8`+0!3`$4```!T`&@`+0!4 -M`$@```!T`'(`+0!4`%(```!U`'(`+0!0`$L```!I`&0`+0!)`$0```!U`&L` -M+0!5`$$```!B`&4`+0!"`%D```!S`&P`+0!3`$D```!E`'0`+0!%`$4```!L -M`'8`+0!,`%8```!L`'0`+0!,`%0```!F`&$`+0!)`%(```!V`&D`+0!6`$X` -M``!H`'D`+0!!`$T```!A`'H`+0!!`%H`+0!,`&$`=`!N``````!E`'4`+0!% -M`%,```!M`&L`+0!-`$L```!T`&X`+0!:`$$```!X`&@`+0!:`$$```!Z`'4` -M+0!:`$$```!A`&8`+0!:`$$```!K`&$`+0!'`$4```!F`&\`+0!&`$\```!H -M`&D`+0!)`$X```!M`'0`+0!-`%0```!S`&4`+0!.`$\```!M`',`+0!-`%D` -M``!K`&L`+0!+`%H```!K`'D`+0!+`$<```!S`'<`+0!+`$4```!U`'H`+0!5 -M`%H`+0!,`&$`=`!N``````!T`'0`+0!2`%4```!B`&X`+0!)`$X```!P`&$` -M+0!)`$X```!G`'4`+0!)`$X```!T`&$`+0!)`$X```!T`&4`+0!)`$X```!K -M`&X`+0!)`$X```!M`&P`+0!)`$X```!M`'(`+0!)`$X```!S`&$`+0!)`$X` -M``!M`&X`+0!-`$X```!C`'D`+0!'`$(```!G`&P`+0!%`%,```!K`&\`:P`M -M`$D`3@``````@`M`$(`3P``````;@!S`"T`6@!!````;0!I`"T`3@!:````80!R`"T`20!1 -M````9`!E`"T`0P!(````90!N`"T`1P!"````90!S`"T`30!8````9@!R`"T` -M0@!%````:0!T`"T`0P!(````;@!L`"T`0@!%````;@!N`"T`3@!/````<`!T -M`"T`4`!4````0!R`&P` -M`````',`90`M`$8`20```'$`=0!Z`"T`4`!%``````!A`'(`+0!,`%D```!Z -M`&@`+0!3`$<```!D`&4`+0!,`%4```!E`&X`+0!#`$$```!E`',`+0!'`%0` -M``!F`'(`+0!#`$@```!H`'(`+0!"`$$```!S`&T`:@`M`$X`3P``````80!R -M`"T`1`!:````>@!H`"T`30!/````9`!E`"T`3`!)````90!N`"T`3@!:```` -M90!S`"T`0P!2````9@!R`"T`3`!5````8@!S`"T`0@!!`"T`3`!A`'0`;@`` -M````````0)E#`-D```!,F4,` -MQ@```!"&0P`C````6)E#`&4```!(AD,`*@```&290P!L````*(9#`"8```!P -MF4,`:````%"%0P`*````?)E#`$P```!HAD,`+@```(B90P!S````6(5#``L` -M``"4F4,`E````*"90P"E````K)E#`*X```"XF4,`30```,290P"V````T)E# -M`+P```#HAD,`/@```-R90P"(````L(9#`#<```#HF4,`?P```&"%0P`,```` -M])E#`$X```!PAD,`+P````":0P!T````P(5#`!@````,FD,`KP```!B:0P!: -M````:(5#``T````DFD,`3P```#B&0P`H````,)I#`&H```#XA4,`'P```#R: -M0P!A````<(5#``X```!(FD,`4````'B%0P`/````5)I#`)4```!@FD,`40`` -M`("%0P`0````;)I#`%(```!@AD,`+0```'B:0P!R````@(9#`#$```"$FD,` -M>````,B&0P`Z````D)I#`((```"(A4,`$0```/"&0P`_````G)I#`(D```"L -MFD,`4P```(B&0P`R````N)I#`'D````@AD,`)0```,2:0P!G````&(9#`"0` -M``#0FD,`9@```-R:0P".````4(9#`"L```#HFD,`;0```/2:0P"#````X(9# -M`#T`````FT,`A@```-"&0P`[````#)M#`(0```!XAD,`,````!B;0P"=```` -M))M#`'<````PFT,`=0```#R;0P!5````D(5#`!(```!(FT,`E@```%2;0P!4 -M````8)M#`)<```"8A4,`$P```&R;0P"-````J(9#`#8```!XFT,`?@```*"% -M0P`4````A)M#`%8```"HA4,`%0```)";0P!7````G)M#`)@```"HFT,`C``` -M`+B;0P"?````R)M#`*@```"PA4,`%@```-B;0P!8````N(5#`!<```#DFT,` -M60```-B&0P`\````\)M#`(4```#\FT,`IP````B<0P!V````%)Q#`)P```#( -MA4,`&0```""<0P!;````"(9#`"(````LG$,`9````#B<0P"^````2)Q#`,,` -M``!8G$,`L````&B<0P"X````>)Q#`,L```"(G$,`QP```-"%0P`:````F)Q# -M`%P```#LCD,`XP```*2<0P#"````O)Q#`+T```#4G$,`I@```.R<0P"9```` -MV(5#`!L````$G4,`F@```!"=0P!=````D(9#`#,````@```/B&0P!` -M````*)U#`(H```"XAD,`.````#B=0P"`````P(9#`#D```!$G4,`@0```."% -M0P`<````4)U#`%X```!````C)U#`&````"8AD,` -M-````)B=0P">````L)U#`'L````PAD,`)P```,B=0P!I````U)U#`&\```#@ -MG4,``P```/"=0P#B`````)Y#`)`````,GD,`H0```!B>0P"R````))Y#`*H` -M```PGD,`1@```#R>0P!P````80!F`"T`>@!A````80!R`"T`80!E````80!R -M`"T`8@!H````80!R`"T`9`!Z````80!R`"T`90!G````80!R`"T`:0!Q```` -M80!R`"T`:@!O````80!R`"T`:P!W````80!R`"T`;`!B````80!R`"T`;`!Y -M````80!R`"T`;0!A````80!R`"T`;P!M````80!R`"T`<0!A````80!R`"T` -M0!E````80!Z -M`"T`80!Z`"T`8P!Y`'(`;```````80!Z`"T`80!Z`"T`;`!A`'0`;@`````` -M8@!E`"T`8@!Y````8@!G`"T`8@!G````8@!N`"T`:0!N````8@!S`"T`8@!A -M`"T`;`!A`'0`;@``````8P!A`"T`90!S````8P!S`"T`8P!Z````8P!Y`"T` -M9P!B````9`!A`"T`9`!K````9`!E`"T`80!T````9`!E`"T`8P!H````9`!E -M`"T`9`!E````9`!E`"T`;`!I````9`!E`"T`;`!U````9`!I`'8`+0!M`'8` -M`````&4`;``M`&<`<@```&4`;@`M`&$`=0```&4`;@`M`&(`>@```&4`;@`M -M`&,`80```&4`;@`M`&,`8@```&4`;@`M`&<`8@```&4`;@`M`&D`90```&4` -M;@`M`&H`;0```&4`;@`M`&X`>@```&4`;@`M`'``:````&4`;@`M`'0`=``` -M`&4`;@`M`'4`````&4`0```&4`0```&4`0`M`&$`;0```&D` -M9``M`&D`9````&D`@```&L`;@`M`&D` -M;@```&L`;P!K`"T`:0!N``````!K`&\`+0!K`'(```!K`'D`+0!K`&<```!L -M`'0`+0!L`'0```!L`'8`+0!L`'8```!M`&D`+0!N`'H```!M`&L`+0!M`&L` -M``!M`&P`+0!I`&X```!M`&X`+0!M`&X```!M`'(`+0!I`&X```!M`',`+0!B -M`&X```!M`',`+0!M`'D```!M`'0`+0!M`'0```!N`&(`+0!N`&\```!N`&P` -M+0!B`&4```!N`&P`+0!N`&P```!N`&X`+0!N`&\```!N`',`+0!Z`&$```!P -M`&$`+0!I`&X```!P`&P`+0!P`&P```!P`'0`+0!B`'(```!P`'0`+0!P`'0` -M``!Q`'4`>@`M`&(`;P``````<0!U`'H`+0!E`&,``````'$`=0!Z`"T`<`!E -M``````!R`&\`+0!R`&\```!R`'4`+0!R`'4```!S`&$`+0!I`&X```!S`&4` -M+0!F`&D```!S`&4`+0!N`&\```!S`&4`+0!S`&4```!S`&L`+0!S`&L```!S -M`&P`+0!S`&D```!S`&T`80`M`&X`;P``````0``````=`!A -M`"T`:0!N````=`!E`"T`:0!N````=`!H`"T`=`!H````=`!N`"T`>@!A```` -M=`!R`"T`=`!R````=`!T`"T`<@!U````=0!K`"T`=0!A````=0!R`"T`<`!K -M````=0!Z`"T`=0!Z`"T`8P!Y`'(`;```````=0!Z`"T`=0!Z`"T`;`!A`'0` -M;@``````=@!I`"T`=@!N````>`!H`"T`>@!A````>@!H`"T`8P!H`',````` -M`'H`:``M`&,`:`!T``````!Z`&@`+0!C`&X```!Z`&@`+0!H`&L```!Z`&@` -M+0!M`&\```!Z`&@`+0!S`&<```!Z`&@`+0!T`'<```!Z`'4`+0!Z`&$````` -M````````@!!$```!````````@``P``!L;V\?/0``````````_____________________P`` -M````````````````\#\```````#P/P`````````````````````````````P -M0P```````#!#````````\/\```````#P?P$``````/!_`0``````\'_YSI?& -M%(DU0#V!*60)DPC`580U:H#))<#2-9;<`FK\/_>9&'Z?JQ9`-;%WW/)Z\K\( -M02Z_;'I:/P```````````````````(#_?P````````"`___YA69QL0U` -M````````__\-0/'`````````````!%`#! -M!4,`R@A#`,\(0P#Q!D,``````````````````,#__S7":"&BV@_)_S\UPF@A -MHMH/R?X_````````\#\````````(0`@$"`@(!`@(``0,"``$#`@````````` -M`/`_?P(UPF@AHMH/R3Y`________[W\````````0`````````)C````````` -MF$````````#P?P``````````;&]G`&QO9S$P````97AP`'!O=P!A+/P4P^_X):S@]`("6WJYPE#\= -MX9$,>/PY/0``/HXNVIH_&G!NGM$;-3T`P%GWV*V@/Z$```E1*AL]``!CQO?Z -MHS\_]8'Q8C8(/0#`[UD>%Z<_VU3//QJ]%CT``,<"D#ZJ/X;3T,A7TB$]`$## -M+3,RK3\?1-GXVWH;/0"@UG`1*+`_=E"O*(OS&ST`8/'L'YRQ/]154QX_X#X] -M`,!E_1L5LS^59XP$@.(W/0!@Q8`GD[0_\Z5BS:S$+ST`@.E>BI8XJ/0`@/,6;;<`_1?KA[HV!,CT``-ZL -M/@W!/Z[P@\M%BAX]`-!T%3^XP3_4_Y/Q&0L!/0#03P7^4<(_P'#_>@(@)#T`P-)''^G)/R`D\FP.,S4]`$`#BZ1NRC]_6RNYK.LS/0#P -M4L6W`,L_"(C_S(]`$`NNN,&S#]\O57-%\ -M(WL@/0!@?E(]%LX_Y),N\FF=,3T`H`+<+)K./X?Q@9#UZR`]`)"4=E@?SS\` -MD!?JZZ\'/0!PVQ^`F<\_:);R]WUS(CT`T`E%6PK0/W\E4R-;:Q\]`.C[-X!( -MT#_&$KFYDVH;/0"H(58QA]`_KO._?=IA,CT`N&H=<<;0/S+!,(U*Z34]`*C2 -MS=G_T#^`G?'V#C46/0!XPKXO0-$_B[HB0B`\,3T`D&D9EWK1/YE<+2%Y\B$] -M`%BL,'JUT3]^A/]B/L\]/0"X.A7;\-$_WPX,(RY8)ST`2$)/#B;2/_D?I"@0 -M?A4]`'@1IF)BTC\2&0PN&K`2/0#80\!QF-(_>3>>K&DY*ST`@`MVP=72/[\( -M#[[>ZCH]`#"[I[,,TS\RV+89F9(X/0!XGU`31-,_6+,2'S'O'ST``````,#; -M/P``````P-L_``````!1VS\``````%';/P````#PZ-H_`````/#HVC\````` -MX(#:/P````#@@-H_`````,`?VC\`````P!_:/P````"@OMD_`````*"^V3\` -M````@%W9/P````"`7=D_`````%`#V3\`````4`/9/P`````@J=@_`````""I -MV#\`````X%78/P````#@5=@_`````"C_US\`````*/_7/P````!@K]<_```` -M`&"OUS\`````F%_7/P````"87]<_`````-`/US\`````T`_7/P````"`P]8_ -M`````(##UC\`````J'K6/P````"H>M8_`````-`QUC\`````T#'6/P````!P -M[-4_`````'#LU3\`````$*?5/P`````0I]4_`````"AEU3\`````*&75/P`` -M``!`(]4_`````$`CU3\`````T.34/P````#0Y-0_`````&"FU#\`````8*;4 -M/P````!H:]0_`````&AKU#\`````^"S4/P````#X+-0_`````'CUTS\````` -M>/73/P````"`NM,_`````("ZTS\``````(/3/P``````@],_`````/A.TS\` -M````^$[3/P````!X%],_`````'@7TS\`````<./2/P````!PX](_`````."R -MTC\`````X++2/P````#8?M(_`````-A^TC\`````2$[2/P````!(3M(_```` -M`+@=TC\`````N!W2/P````"@\-$_`````*#PT3\`````B,/1/P````"(P]$_ -M`````'"6T3\`````<);1/P````!8:=$_`````%AIT3\`````N#_1/P````"X -M/]$_`````*`2T3\`````H!+1/P``````Z=`_``````#IT#\`````V,+0/P`` -M``#8PM`_`````#B9T#\`````.)G0/P`````0<]`_`````!!ST#\`````<$G0 -M/P````!P2=`_`````,`FT#\`````P";0/P````"8`-`_`````)@`T#\````` -MX+3//P````#@M,\_`````(!OSS\`````@&_//P`````@*L\_`````"`JSS\` -M````P.3./P````#`Y,X_`````&"?SC\`````8)_./P``````6LX_``````!: -MSC\`````D!O./P````"0&\X_`````##6S3\`````,-;-/P````#`E\T_```` -M`,"7S3\`````4%G-/P````!066X`7VQO9V(```!? -M;F5X=&%F=&5R````````%````+"@0P`=````M*!#`!H```"DH$,`&P```*B@ -M0P`?````@*I#`!,```"(JD,`(0````BI0P`.````N*!#``T```#`H$,`#P`` -M`!"I0P`0````&*E#``4```#(H$,`'@```""I0P`2````)*E#`"`````HJ4,` -M#````"RI0P`+````-*E#`!4````\J4,`'````$2I0P`9````3*E#`!$```!4 -MJ4,`&````%RI0P`6````9*E#`!<```!LJ4,`(@```'2I0P`C````>*E#`"0` -M``!\J4,`)0```("I0P`F````B*E#`'-I;F@`````8V]S:`````````````#P -M?________^]_`````````(!#`$\`3@!/`%4`5``D```````````````````` -M_RG#8``````"````40```"2M`P`DE0,``````/\IPV``````#````!0```!X -MK0,`>)4#``````#_*<-@``````T```"<`P``C*T#`(R5`P`````````````` -M```@[D,`**M#`````````````0```#BK0P!`JT,``````"#N0P`````````` -M`/____\`````0````"BK0P````````````````#H[4,`<*M#```````````` -M`0```("K0P"(JT,``````.CM0P```````````/____\`````0````'"K0P`` -M```````````````$[D,`N*M#`````````````@```,BK0P#4JT,`B*M#```` -M```$[D,``0````````#_____`````$````"XJT,`````````````````..Y# -M``2L0P````````````,````4K$,`)*Q#`-2K0P"(JT,``````#CN0P`"```` -M`````/____\`````0`````2L0P````````````````!@[D,`5*Q#```````` -M`````@```&2L0P!PK$,`B*M#``````!@[D,``0````````#_____`````$`` -M``!4K$,```````#_`0#%_P$`4"$"`/`R`@!0-P(`=Q\#`($?`P"3'P,`I1\# -M`+(@,`L"(#`,(B`P#< -M(@,`^2(#``XC`P`C(P,`.",#`$(C`P!24T135G1."$!&@$&S-:[+8A2E&@$` -M``!$.EQ0')A'0D;6X`````)Q\#`#8$```N -M=&5X="1X`%TC`P!=````+G1E>'0D>60``````#`#`&`"```N:61A=&$D-0`` -M``!@,@,`!````"XP,&-F9P``9#(#``0````N0U)4)%A#00````!H,@,`!``` -M`"Y#4E0D6$-!00```&PR`P`H````+D-25"180U4`````E#(#``0````N0U)4 -M)%A#6@````"8,@,`!````"Y#4E0D6$E!`````)PR`P`$````+D-25"1824%! -M````H#(#``0````N0U)4)%A)04,```"D,@,`$````"Y#4E0D6$E#`````+0R -M`P`$````+D-25"1825H`````N#(#``0````N0U)4)%A000````"\,@,`"``` -M`"Y#4E0D6%!8`````,0R`P`$````+D-25"184%A!````R#(#``0````N0U)4 -M)%A06@````#,,@,`!````"Y#4E0D6%1!`````-`R`P`$````+D-25"185%H` -M````U#(#`-P"```N8V9G=6%R9`````"P-0,`9'4``"YR9&%T80``%*L#`'P! -M```N&1A=&$````DK0,`!`0` -M`"YR9&%T821Z>GID8F<````HL0,`!````"YR=&,D24%!`````"RQ`P`$```` -M+G)T8R1)6EH`````,+$#``0````N+1#```````````` -M`````````````````0```/____]+(4,`(@63&0$```"LM$,````````````` -M```````````````!````_____UTA0P`B!9,9`0```-BT0P`````````````` -M``````````````$```#_____X]"``````#^____ -M`````-C___\`````_O___P````#00@``````_O___P````#4____`````/[___\`````NJ%"```` -M``#^____`````-3___\`````_O___P````!,MD(``````/[___\`````V/__ -M_P````#^____`````/6P0@``````Y/___P````"T____`````/[___\````` -MDKY"``````#^____`````-3___\`````_O___P````#ENT(``````/[___\` -M````S/___P````#^____`````"3`0@``````_O___P````#4____`````/[_ -M__\`````0LA"``````#^____`````-#___\`````_O___P````"1YT(````` -M`/[___\`````Q/___P````#^____`````!SI0@```````````._H0@#^____ -M`````-C___\`````_O___^'L0@#][$(``````/[___\`````S/___P````#^ -M____`````$GW0@``````_O___P````#0____`````/[___\`````!OM"```` -M``#^____`````-3___\`````_O___P````"<^T(``````/[___\`````U/__ -M_P````#^____`````"3]0@``````_O___P````#8____`````/[___]9&T,` -M;!M#``$````@4P,`N`P&`*`@!@"$OP,`H,8#`````````````0```#!3`P"\ -M#`8`3"`&`#"_`P!TQP,````````````!````0%,#`,`,!@`\(`8`(+\#`)S' -M`P````````````$```!04P,`Q`P&```@!@#DO@,`K,<#`````````````0`` -M`&!3`P#(#`8`="`&`%B_`P#@QP,````````````!````@%,#`,P,!@!T(08` -M6,`#``3(`P````````````$```#@5`,`[`P&`)@@!@!\OP,`',@#```````` -M`````0```/!4`P#P#`8`-"`&`!B_`P`DR`,````````````````````````` -M`````````````````````````````+K$`P`DQ0,`CL0#`*+$`P`RQ0,`SL0# -M`.;$`P`"Q0,`:,4#`%3%`P!$Q0,`#,4#``````"(Q@,``````&+$`P!VQ`,` -M3L0#``````#NPP,`_L,#``[$`P#BPP,`+,0#`$#$`P#,PP,`LL,#`![$`P`` -M````ML4#``3&`P#NQ0,`W,4#`,K%`P!ZQ0,`H,4#`(C%`P``````=L8#```` -M``"FP@,`NL(#`,K"`P#:P@,`[L(#``##`P`2PP,`DL(#`###`P!&PP,`4L,# -M`&C#`P!VPP,`A,,#`)##`P">PP,`A,(#`';"`P!JP@,`6L(#`$K"`P`\P@,` -M,,(#`"C"`P`8P@,`"L(#`/[!`P#LP0,`W,$#`,S!`P#`P0,`KL$#`)K!`P"( -MP0,`>L$#`&C!`P!:P0,`3L$#`#3!`P`BP0,`$,$#``#!`P#PP`,`W,`#`,K` -M`P"ZP`,`KL`#`)S``P",P`,`?L`#`![#`P!PP`,``````&3&`P`NQ@,`%L8# -M`%3&`P!"Q@,`````````4VAO=U=I;F1O=P````!'971$;&=)=&5M`````$5N -M86)L95=I;F1O=P````!39717:6YD;W=497AT5P````!'971087)E;G0```!3 -M9717:6YD;W=0;W,`````4V5T1&QG271E;51E>'17````1V5T4WES=&5M365T -M%<`````0W)E871E5VEN9&]W17A7````27-7:6YD;W<` -M````1&5S=')O>5=I;F1O=P```%5P9&%T95=I;F1O=P````!-87!7:6YD;W=0 -M;VEN=',```!#;W!Y4F5C=`````!,;V%D0W5RM0#`(S4`P"H -MU`,`OM0#`-34`P#>U`,`ZM0#`/;4`P`$U0,`%M4#`";5`P`ZU0,`2M4#`%S5 -M`P!HU0,`>M4#`)35`P`2U@,``````*#2`P".T@,`<-(#`%#2`P`RT@,`'M(# -M``S2`P``T@,`]-$#```````"`D=E=$QA&5C=71I;VY3=&%T90"R!%-L965P`#\#3&]A9$QI8G)A5<`9`!#;VUP87)E4W1R:6YG5P``$`!!;&QO -M8T-O;G-O;&4``%\!1G)E94-O;G-O;&4`%P!!='1A8VA#;VYS;VQE`"0%5W)I -M=&5#;VYS;VQE5P!&`D=E=%!R;V-E4UAE-P96-I9FEC3&]C86Q4:6UE5&]3>7-T96U4:6UE -M`+T$4WES=&5M5&EM951O1FEL951I;64``"0!1FEL951I;654;TQO8V%L1FEL -M951I;64`1@-,;V-A;$9I;&54:6UE5&]&:6QE5&EM90`E`49I;&54:6UE5&]3 -M>7-T96U4:6UE``!R`4=E=$-026YF;P#^`DES1$)#4TQE861">71E``!G`TUU -M;'1I0GET951O5VED94-H87(`$057:61E0VAA71E`+,"1VQO -M8F%L06QL;V,`5`-,;V-K4F5S;W5R8V4``+X"1VQO8F%L3&]C:P``Q0)';&]B -M86Q5;FQO8VL``+H"1VQO8F%L1G)E90``00-,;V%D4F5S;W5R8V4``+$$4VEZ -M96]F4F5S;W5R8V4``$T$4V5T0W5R5<``-\!1V5T17AI -M=$-O9&500-/<&5N1FEL94UA<'!I;F=7``"'`4=E=$-O;6UA;F1, -M:6YE5P!7!%-E=$5N=FER;VYM96YT5F%R:6%B;&57`!T!17AP86YD16YV:7)O -M;FUE;G13=')I;F=S5P"%`D=E=%1E;7!0871H5P``8`--;W9E1FEL945X5P`& -M`D=E=$QO8V%L94EN9F]7``"7`D=E=%1I;65&;W)M8717``#(`4=E=$1A=&5& -M;W)M8717```S`D=E=$YU;6)E&-E<'1I;VX``',"1V5T4WES -M=&5M26YF;P#O!%9I0``/0-, -M;V%D3&EB45X00``!`-)&-E<'1I;VY&:6QT97(` -M`*4$4V5T56YH86YD;&5D17AC97!T:6]N1FEL=&5R`&,"1V5T4W1A%<``*@#475E0`7`D=E=$UO9'5L94AA;F1L945X5P``$P)'971-;V1U -M;&5&:6QE3F%M94$``&@!1V5T04-0``#/`DAE87!&F4``)H!1V5T0V]NM`0```#D```!^Y=<\`@```'@````_B6DW`P`` -M`!T```!]!P8.!@```)4```#(72P````'P```!\````> -M````'P```!X````?``````$"`P0%!@<("@P.$!08'"`H,#A`4&!P@*#`X``` -M`````````0$!`0("`@(#`P,#!`0$!`4%!04`````!`````(````"`````@`` -M``(````"`````@````(````"`````@````(````"`````@````(````"```` -M`@````X`````````#``````$"!`@0(#``@(#!`4&!@8`````X$ZV*&0```"X -M1D,`/6;WPF4```#,1D,`"$D8YF8```#@1D,`I+G"7F<```#P1D,`D@:5CF@` -M````1T,`,61B6&D````81T,`,7X*&6H````L1T,`"98Z?FX```!$1T,`6,VT -M3F\```!<1T,`OS>5`'````!L1T,`0GT137$```"$1T,`V#`>?'(```"81T,` -M6`8D8G@```"L1T,`+WM/9'D```#`1T,`Z2]#97H```#41T,`R(GOK'L```#H -M1T,`C*;B7'P```#\1T,`>["%#8,````82$,`2D2H:(0````L2$,`L.22_(4` -M```\2$,`@ZZ"PH8```!02$,`@JSNC8P```!D2$,`[C:ZO8T```!X2$,`\,-U -M/XX```",2$,`+$`GL8\```"D2$,`$8>6*)````"\2$,`I+I*9I8```#(2$,` -M2[@9^)<```#42$,`'VK/2Y@```#D2$,`8KBO#YD```#P2$,`C6I:H)H````$ -M24,`DHDBRJ`````424,`#39P>Z$````H24,`OF#T.Z(````X24,`@&J\3JH` -M``!(24,`#NP:4*L```!824,`X+E!OZP```!H24,`IJ?26:T```!X24,`(:)! -MY:X```"(24,`[LV#$*\```"824,`_KG@M;````"H24,`8G`61+0```"X24,` -MS*+":;D```#(24,`)O-)Z+H```#<24,`)IYV*[X```#T24,`K"1@@+\````( -M2D,`ZS6Q[,,````@2D,`>IU=O<@````T2D,`7:^1R\D```!(2D,`&B^NILH` -M``!<2D,`2)#K5](```!T2D,`F8#4WMP```"$2D,`P[TON=T```"<2D,`0'CZ -MN-X```"T2D,`AXS7&N$```#(2D,`.)0-[.8```#82D,`7GR0H.<```#D2D,` -MA4"07?````#T2D,``S&LEO$````(2T,`,=)X-``````82T,`!"[:CP`````H -M2T,`.!&.A64````\2T,`BJ[`W6<```!82T,`_2+C9&L```!P2T,`WU-^!P$` -M``"02T,`2OU`X`(```"@2T,`Y'*V0(````T34,`#6\H=64```!(34,`&UFW+F<```!D34,`(HM= -MPP````!\34,`K,_@-P````"034,`]02GQ&4```"H34,`^`;N"@$```#(34,` -MG!IF=P(```#<34,`-0>8/P````#T34,`[O.U-@`````(3D,`ZLG8!0$````< -M3D,`X4BS]0(````P3D,`6`>%=`````!(3D,`B^(%%#`(110P"844,`J%%#`+Q10P#0 -M44,`Y%%#`/110P#_____````````````````=9@``+$9OT1.YD"[``````$` -M```!``````````````#_____````````````````(`63&0`````````````` -M``(````,````"````/____\````````````````!(``````````````````` -M``````````````````````````````````````````````````````(@```! -M```````````````````````````````````````````````````````````` -M`````````B````(````````````````````````````````````````````` -M``````"0:4,``0`````````!```````````````!```````````````````` -M```````````8Z$,`````````````````&.A#`````````````````!CH0P`` -M```````````````8Z$,`````````````````&.A#```````````````````` -M````````4.U#````````````$&Q#`)!M0P`@94,````````````````````` -M````````````6.=#`"#K0P!#````BF9#``$"!`@`````I`,``&"">8(A```` -M`````*;?````````H:4```````"!G^#\`````$!^@/P`````J`,``,&CVJ,@ -M``````````````````````````````"!_@```````$#^````````M0,``,&C -MVJ,@``````````````````````````````"!_@```````$'^````````M@,` -M`,^BY*(:`.6BZ*);``````````````````````"!_@```````$!^H?X````` -M404``%':7MH@`%_::MHR``````````````````````"!T]C>X/D``#%^@?X` -M```````````````````````````````````````````````````````````` -M````````````````````````````````$!`0$!`0$!`0$!`0$!`0$!`0$!`0 -M$!`0$!`````````@("`@("`@("`@("`@("`@("`@("`@("`@(``````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````!A8F-D969G:&EJ:VQM;F]P<7)S='5V=WAY>@`` -M`````$%"0T1%1D=(24I+3$U.3U!14E-455976%E:```````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````````````````````!`0$!`0$!`0$!`0$!`0$!`0 -M$!`0$!`0$!`0````````("`@("`@("`@("`@("`@("`@("`@("`@("`````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````!A8F-D969G:&EJ:VQM;F]P<7)S='5V=WAY>@`````` -M`$%"0T1%1D=(24I+3$U.3U!14E-455976%E:```````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````@ZT,`+@```"X````` -M````1.U#``071@`$%T8`!!=&``071@`$%T8`!!=&``071@`$%T8`!!=&`']_ -M?W]_?W]_2.U#``@71@`(%T8`"!=&``@71@`(%T8`"!=&``@71@#^____```` -M`````````````0```````````````````/[___\````````````````$54,` -M`````"X_05&-E<'1I;VY`5]N97=?;&5N9W1H0'-T -M9$!````$54,``````"X_059B861?97AC97!T:6]N0'-T9$!````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````";>00!8WD$`$MY!`!S>00!BWD$`,-Y!`#K>00!$ -MWD$`@-Y!`';>00!LWD$`3MY!``````#!Y$$``````.W=00#WW4$`TMU!```` -M``"6W4$`H-U!`*K=00",W4$`OMU!`,C=00""W4$`9]U!`+3=00``````N=Y! -M`.'>00#7WD$`S=Y!`,/>00"*WD$`K]Y!`*7>00``````IN1!``````#'W$$` -MT=Q!`-O<00#EW$$`[]Q!`/G<00`#W4$`O=Q!`!?=00`AW4$`*]U!`#7=00`_ -MW4$`2=U!`%/=00!=W4$`L]Q!`*G<00"?W$$`E=Q!`(O<00"!W$$`=]Q!`&W< -M00!CW$$`6=Q!`$_<00!%W$$`.]Q!`#'<00`GW$$`'=Q!`!/<00`)W$$`_]M! -M`/7;00#KVT$`X=M!`-?;00#-VT$`P]M!`+G;00"OVT$`I=M!`)O;00"1VT$` -MA]M!`'W;00!SVT$`:=M!``W=00!.VT$``````"3?00`&WT$`Z]Y!`!K?00`0 -MWT$````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`0`%`+`%`(!```"``P```&```(`%````J```@`8```#H``"`#@```$@!`(`8 -M````8`$`@````````````````````@!E````>`$`@&8```"0`0"````````` -M```````````'``$```"H`0"``@```,`!`(`#````V`$`@`0```#P`0"`!0`` -M``@"`(`&````(`(`@`<````X`@"`````````````````!@```"P&`(!0`@"` -M_`4`@&@"`(`6!@"`@`(`@.@%`("8`@"`R@4`@+`"`("X!0"`R`(`@``````` -M````````````"@`'````X`(`@`@```#X`@"`"0```!`#`(`*````*`,`@`L` -M``!``P"`#````%@#`(`-````<`,`@`X```"(`P"`#P```*`#`(`0````N`,` -M@````````````````````0!D````T`,`@````````````````````0`!```` -MZ`,`@````````````````````0`)!`````0``````````````````````0`) -M!```$`0``````````````````````0`)!```(`0````````````````````` -M`0`)!```,`0``````````````````````0`)!```0`0````````````````` -M`````0`)!```4`0``````````````````````0`)!```8`0````````````` -M`````````0`)!```<`0``````````````````````0`)!```@`0````````` -M`````````````0`)!```D`0``````````````````````0`)!```H`0````` -M`````````````````0`)!```L`0``````````````````````0`)!```P`0` -M`````````````````````0`)!```T`0``````````````````````0`)!``` -MX`0``````````````````````0`)!```\`0``````````````````````0`) -M!`````4``````````````````````0`)!```$`4````````````````````` -M`0`)!```(`4``````````````````````0`)!```,`4````````````````` -M`````0`)!```0`4``````````````````````0`)!```4`4````````````` -M`````````0`)!```8`4``````````````````````0`)!```<`4````````` -M`````````````0`)!```@`4``````````````````````0`)!```D`4````` -M`````````````````0`)!```H`4``%`V!@!%"P````````````"8008`J14` -M````````````2%<&`&@%`````````````+!.4BZ&.MA#/(B+",,!J&3 -M#KH8?+(Q_E\Z[$D@^Z2#O+"+,/@A6SX(9`M=).R#O7A&LZN97>]T^]"[P\QV -M=4]U969W958D>1OHJ?HJXLN(+R(S"6X=\9R>!#RJ!N/"N#`NC`OCPK@P+HP+ -MX\*X!([+F.?T9'MA/V)<;.#"9%(UV5[8CQ@7QL4'7,3QB?[L\^233Y<_]6>? -MB^.3UJU'>/JP^/"CM?=NY;?OI+__P_)G?OO.VGNWB@\_HM.SMJQ'='I6OO^! -M^N++E1N_^N++WON_H=.S5OA1=O=C<73<$EX01\?9W8]7CXLX.FZ#I3QC->;? -MR107^<]_M7`U,7\J4]ZEL[,6XB+N/^`\H&J,1AS758WQ>-6XC,,$UJV]_&_0 -M_^_/?W;OU[^T/'_UBY.?_F0L98OUE[GC_H]_-$I3^_H(XJ/#PX6 -M=T=IZO#'BYSS:=89&)=VX^*2=]VJTR[_-=M+>''=V.%3$;`C5=>G&1;F%UZG -M&1>.7YA?.'YIZ[\.5<=D7)AWF7.7EOG1>.3N -MM_'Q8U]Q45]]Y>JG1Z/HZZ\=XS(>-Y]S1W[[=_G=.\G?/K4[TT_^7/[V`_F? -M?\\UU;'))(C0'?/C^;G^Q]_3/_W1[DS^^A=Y[YYC?E%,O=6XB!!?BXQQ$0"B -M>10SBG4+83G/,N/X90R@FZ/[>'NGA;B8/Q4!@`G%G/?*1S<.6P7*HQN'Y[W2 -M!BX2@;"QR3UX[:;YZ1C -M>[J4V6H]TO')&V\>O?/N_9NOG[[TRNEWO[?4^=(K#W[X^M$[[YZ\\:854"[E -M`8H`C6VX*!X^_^*W+[_Z[?=_L-3Y\JMG+[QX7A1N\B/%>\PK=08.?*MUJ2`# -M7PM^A``1FTRE_L(44ZUC:K:72GL1"!(9%*BH!VAVIHSI60[65Z8$?K)S7>.1:&O6H^ -MSAJX*`+$[ME+G;;JF-B/.%>JCTM$)HU#09\'WS&3J1VV=0Z7FD,@1,1^U'57 -M6@073=W)"1;!A;`[O4,+4D8BF%]FY`0"V8^ZR[Y-<>FZ+E51L+JAO((-O+M+B)$`OFEQF!#-M+Q9`4=AN>P;L%;3(&N`0=R%#S8@*&'/N: -M<40B&9=*/3S8'AGC-250DS&6;.,P"_O&]A(H^]J(S5+)_%(9^P:H/%AZGU0$ -MAXL5PWO25M5Q_:62?<,J%=CCA50ROU0-@2'U^UHMQ0>T8%M=7Q4%L]'-=MP1 -M"LO8QB64=,EVJP\B))+Y)5A7X>+K_:$^AJU]'CVO8M*-1N&OR\=:52"+N*V>X2%]; -MH0D`MC4Z?/9,>IH?C27"@;L#7Y27'40TH<@MA1*\LMDEA'V'&U*D^A+FU"-<F-6A+N.:":/ -MO.27B[$=NR'@1+3V5&BJ"9X3`@9L[<)4ESK*"-S(-X"PDB;:/$N1AK;&FRKUIA&U5Q6O05AA-@K#<1D;?\\O1@!MRQ -M?B(OMBYC:O*&VS'%UKTIDZW:P=0$%T(8I`Y,)H^\[VO.)6XJ"GAA:A[%[L6H -M$"W7WEJ3,5'CMR#$01*LR1B]6!'A?K#DG`1 -MMB*:;$GZP_*RCT3@?F+C^-:EK-FTS"AR7=.Z^25MB01)7N8!\U*GE&)S1^A% -MX?C1$S]`&&9DBHP6KH]J6D&JJ@C[YN?2.C:9U:@^180[AF*PX\Q@96U*FS&M -M&09[$Y,)@W>O["/%IA%1@1!CE)D^0ICT"$Y4=/60+[)@4Y!"B4 -M3WK=`I%]A+LF<7#JI&;0BO;0C9@V3"K_/15"_%(Y=U.1-Q8]M8!8AK,>/4,4 -M_WGBG`P*?TW$X#MJ7FMV\><2=Q/ -MF]XJ:4^:H9;MXX`Q0*EHLUGVE$6VSCYKZ;[WK:2I5%XJ6[BT=&OW049I@Y5; -M"RMWM+9WTSL"#+)&S<$]!1BH'UTDS,-<+&PTDLSS[+:?JZ$(!KE8^"GSR+"< -MXL')E8F`@VS!S8.(A@3LQXF>18.<.Y9@L'/!FY-.US5N+KI+>4T'%=?-FIL) -M;2QT3H2DQCN0/3L9=R>A'ZU -M`1_6TH!#NW^]U+A[;9-:+*[MM2((R6#&`&,H%>ZFUYTH5RJ8N[J'9B]/XW[: -MF:]C$4*I0HY?9NM8M#._;IG.$_2"Q64"S?9\:&:',R'C`@`;FK;G.%0TLZ(2 -M."X`L!'/M9I"59YV$#XN$ZN9R358+8]W`I=K:%B+Z?L4NX++!)K=6="4SZHS -M'<(%`-8T[54>"$O/UB>[A0L`E)KV*G<4IA)B<>E^DNZ-GJ+]RBZ^4E]X4X#Y -M4:UR6U0E90F\:)'NHKU<2%D5T&311.OL+BX`D$H<%%,=P^L:$#N-"P`D`H>% -MN"+@"8)242?IY%N)):9U'7[>5I_HC#0EPNHC`N%]Z#PT(D$AF7Z:`7 -M!SGE$3(N4]DUXD$N2H6,2\78S03C,L.G&`+&A7&Q@`L'O#/J:@Q#*_?;,[\P -M+HP+X\*X\&!<&!?&A7%A7!@7QH5Q85P8%\:EF[BP.->I_0'L1XP+X\*X,"Z, -M"^/"N#`N/!@7QF7!\7_UL1ZD2@_N/P````!)14Y$KD)@@@```(E03D<-"AH* -M````#4E(1%(```"Z```"7`@"````P>XI$`````1G04U!``"QCPO\804````@ -M8TA230``>B8``("$``#Z````@.@``'4P``#J8```.I@``!=PG+I1/`````EP -M2%ES```+$@``"Q(!TMU^_`````9B2T=$````````^4.[?P``%0U)1$%4>-KM -MW=ES',=]P/%=$,3!2Q`@D9(HBA1O4A2MPTZ8V;SG-[..+H-`SV)G -MNGOF6_5]U,.B^Z.>GNG992JU6"12C2$@N!!<""X$%X(+$4-`<"&X$%P(+@07 -M(H:`X$)P(;@07`@N1`P!P87@0@9P*1"IQA`07`@N!!>""\&%B"$@N%!(7!8* -M1*HQ!`07@@O!A>!"<"%B"`@N!!>""UG%9;Y`I!I#0'`AN!!<""X$%R*&@.!" -M<"&XD%5""\&%X$)P(6((""X$%]+/9;9@8'4CGS:__HL#?SO_ -M^%\.MGZGL^W/;\6^UN]VM_Q@5/YD^^0U<-J_IC?](^J*R64T_^158\"'V_?V'F-@ZV?G"Q5]:AC]ARZ)RKV3$W;7V -M3]#\^B_1H)(,E`%<9@IZDP=34%!)!DK[9.GG(L]MH:"2#!1<"@EYQE^#7NN` -M2P$'ZL$%+G"!"US@`A?ADM<;"()PT3Q9<(%+("[3>;V!(``7W9-E-Y>6[V<: -MKOXVG5O1/XX*R>>43RN?&2X:N+3\()/.+EL!Y2MHLLORR>$2-1?Y/]4Z*Y7D -MD\,E:B[I[(JE7-*Y5;A$S<52*SOYJ^$"%[C`!2YP@4LJ-9776_5<='_RZ/]J -M_9\<+G"!"US@`A>XP`4N<($+7.`"%[@$X3*9UUOU7'1_\NC_:OV?'"YP@0M< -MX`(7N,`%+G"!"US@`A>X!.$RD==;]5QT?_+H_VK]GQPN<($+7.`"%[C`!2YP -M@0MXP`4N<($+7.`"%[@$ -MX9+;T%OU7'1_\NC_:OV?'"YP@0M<0N(B!P%P@8LJE[DB7."BS.6N`Q>X*'/Y -MUS)D"7."BS&6QE,INZ*IZ+OH^LZZ_6O\G][A\Y,(%+FI<9.\B -MR?<9X0(752[S1;C`19G+/1_B]+N<@GCPL7>5O*$BXMWQ]-#R[9M[0,+LDGCPN7 -M>ZXM7#PQ?Y61_U-MN2K)YY1/*Y_9XNW:U[E\[#_>'=V(K)UP25I1SLOF;<)% -M'N_"!2ZJ7.3Q+ES@HLKEH[)WE8(+7)2X?.P_WH4+7#;A\E%YDQ8=N,!%FMW.G&@U&L=IG*1)@NIS$8$/?Z]`2BH)`,5S8QLU2.YR'%C))_@P-_, -M04$E&2B#NM?]&-B42U37(ZGIGW[%)F:3'>X__M(4*]MSN>NF1M8CJ^'M -MW[9^EZO2%]>@QC=_'>7X;]\V7"K7HP@_4%WG[[V=;\*7F4OM,@@R%&994>(R -M6XS^8\E(-?_#OQ_XZSGOF>]K'0EYQB]_K/S)\H?OZOAOXZ"HD1&MST7 -M*9MGI$B9RTR1D2)E+G>X'E&%R_VR4F/YU/`Z)3U5+M-%!HN4N=QV&"Q2YG+? -M_WH`XP47KD<4`A>N1Q2`RWW_ZP$,&5P"7(^&UBFYI>Z5`W3;9='#!Q,(%R" -M78\81+BHEBLPB$GB7*E)DUR/X*+>HLMHPB5(HWD& -M%"[*39=2?6L4YVK)1:Y'\N"/,86+:O*#S8PI7%2;Y7H$ET`--8E@H7.1`@)&%BVH+KK=P,;AP44T.!!A;RYP;7?(`1G;7##I<5!O.,^AP46ZRQ*##)4A];'CAHMX8&UZX -MJ#?CI+K8\,)%/3EQ[%PE^]+#9:+$T-O)19Z%:*EWG=&'BW*C!48?+LIY&UXF -M`"[J#;+AA8MZ\AU')@`N`9)7OCM6R9HT<\D4F`.X*#?M>$LIL$: -M+C..YF3#RS3`)4!L>.$2H%$VO'!1K[+A;2?C,X++C+_A93+@HIJ\TL!DP"5` -M\DH#\P&7`!M>YL-T+M..0;'AA4N`AO),"5R4JVQX;ZV0H9G%9=K?\#(K<%%M -MK,BLP"5(\J4U)@8NJLFO-#`Q<%%MD@TO7`+5O\'<&,EERC&Q'!M>N`1*?I;L -MY@J9E;EF!O+,&5R4 -MDSOJ&TP;7-23.VJF#2ZJR1TUTP:7`,G7')DYN*C&'35<@E3R[JBOKU#4>4-O -M8_+6]_5EBKKF2<=*+I4S:N8OXDXONM[0VYA\CYKYB[@_N_^_S9472JPK6_(V -M7TQAQ%Q.+UB[P/2L,X51<_GV_;*M"\QHD2F,FHMTRMX%1EZ"818CYB(+3).E -M"XP\LGM_F2*JPL7N!48>V3&1$7/Y]KURTX2="XP\LF,BH^)2_KQ3\W8N,#G_ -MCIJYC)C+G]XK-\L"DRO95]\&BYG+5U@Y)$=TQD]%VG_I)T+C+QE]]XRA=BF7,XOVKG`C!2940U=;RJ%JG[%Q@;JXRKQJXO%A98+*V)5^,95ZC -MYR(=E`4F:Z$8.1-@:J/G\O+M?5.N=[&!4;.!)C=Z+E(QV9=^[B,^H_LF.#HN7SK;KG1Q@6FBP6FUOW) -MW;)*)^]Z.->98#Y=S\Q8N,,,%YE@/%^EQ[^>02Y8E -MWQ-@FK5PN;A83EO'10X=KRU3;0K$17IZRL(%1@X=KRU1#0K*Y97;Y?JL;5SD -MT)&9K@V7.^6@'9MQ[5M@Y-"1R=YYW[I3#MHW[Y2;<[9QZ6.!T<1%.C-GVP(S -M*H>.+#":N$@M$[;M>7LWF&]M7%Y<<-/6+3!RZ,B4:^$B>3?5HR6;ZF&!T<=% -M;JIW9ZWB4CETO+I$5;83+M)QN:FV:X'I7F?6M7&1F^I].188N"CWPKQM"TPG -M"TRU?=-?(7;8P4FK]KSR5>IK+##5<;E=WGDO+9;KQZQ:8.2U*>9>%Q?IV+15 -M"\QPD;G7R>75V^6]=MU4M[/`Z.,BG9NS:L\KKTW)WW^%@E1#+M)!.4C*E*SI -MUAH"='+YPY[7%BXL,'JY2,_+2R6`ZOUG%[%I@/5E.7EVB;0N5R<<'=95[ZZA@:]7"3OZ-&:!68% -M$)JYO+)8WI_U7S$QOWX6&-U<)/\Q3-$.,==98+;L%7\!"+O#\AB&!08NBLEC -MF.:Q$@L,7%0[*[^V:LT"\Y`V+S(NTJ$)QYX%!ARZN;RT4&X<+5FSP+Q#?U24 -M7*33,ZXU"PPXM'.1GAQW[%A@P+$)EX5RQ'UCWFW(V'!)NKZ*#_U"XPA7*0G,&2PF(0O,*9QD4O27N^'XUA@X*+6^5FW;MCL!>;MAPG- -M0"[2B$D9N8=U?@8FAM8^9M8GKS_@4>+N;UXJS;9.!]]?LK<#&T,]-NG6E<^O+> -MLRRXF-D1`P\'Y.NQ,>9RT;\[M;=6.1P8*!J4_,!'C!<8V[E.1OXDQ2_%!K@8WE-98S8Q"&#D6L)O+C)N$+LSXS^ZTMG4OE6``N5G0X9\`FYOU5N%A36T:W&.]8`"[V;'OW#NG> -MQ'RPEGKS@7TED(MT=LK9K??979]_+``7:[:]$[JWO;?6X6)3S\J1=5]!9W(L -M`!>+>B*C54SGAF5<+OA;OR2W3Y[V:A0C+_.^^9DUP>7N-C54V/ZMKWR&Q]PL:QIMV5$WR;F -MYTLV<)EVZ?/.3[M[AC2)Z=B`BWV=JYP/:!%S91DN]G5J0M.-4E?>>Q3VQF?F -M!HY-.Y9STEH6F/=6X&)ESVBY4:J\:P<7&VO3F';W1W^CU.N_ -M"@,72V^4FN3[`[V%2)-_HZ&N6MM9Q4P\7VGHKLUKIR4PT7VVL=B>I&25[_AHOMR:WU@:&H -MQ,CKWW"Q/3FUWC,0"1=Y_1LN,4A.K1N\WYT+OZO+<(E#?W@8$S:7;O_U;[C$ -MH)/CSJ[>\,7(01)3,F5"[RE4;R$EQBU>D)IZ$O-#&=_LM3/_XT -MBIC+:#HU[M3WAB;FO56XQ*WCNRI71/(;0]+UQB -MUW-C(B:D/>\R7&+8,_*&KZ5[7B9/2X?D#=_N?.T+>\_+S.GJB>%PQ+SU$"[Q -M[/&A$,3<6H=+/),C@L<&0Q!S91DNL16S?Z!08RZ=_KL-__)I[6/"3!"SM^9B -MY-T&N,2ULQ/.GOY:BY'W>>$2U\Y,.$U]A=KO>>$2U^3@NK&V8F3/"Y<8)P?7 -M#;T%<_>\S)!IR7?;=M=0S/55N,1=3,ZI[RF8N.=E;LSL>*ZTJZ=&7-HW:K;G -M96*,[?ELJ:Y68JZMP"7^'1TKU=6$2^6?[=LYEW/^4T4R-A&3KHD8^:TRN"2A -MYVHEYIVE'7.9<,C\CHS60DRG_UME<$E"SU;$=.VL'1X],@V)$_/60[@DI60SS`"[)V_E6+2;08Q@&.D[W2NDJ'\.L -MP`4QRG4J/X9AB&/683DEJ$+,C76X)/4DLCHQEY?A@ACU2Y+_-@Q<$*/:]36X -M)/L=O-J>##"FB/FCDP&X)+CG1DMU@4\&/MD\1C,)>=]7"OJ")ER2W+&QTJ[* -M;S*H5#D9^.=/OA[CF)R>'RO5JXN1[\ENPF71T/!M$C)P,P"7AGH -M<;GIGPS`)>&=S)8:%,7(SY7!A4[E2HV*8MYX`!=R3N=*3?*K9MMRN?&E2Q*C -MEG`Q>U3$7%Z&"WF=&7?V]6TGIL/_EY+@0M+9<>=`_W9BY&ML<*'/Q;0,;"=& -M?DWHK/^?$DEM\J_E;'U)8HSHRQT" -M"Q%<""X$%X(+P87@0@07@@O!A>!"<"&X$,&%X$)P(;@07`@N1'`AN!!<""X$ -M%X(+$5P(+@07@@O!A6++)5LB4@PN!!>""\&%X$)P(8(+P87@0G`AN!!""\&%""X4H/\#9IGG&MFY;-<`````245.1*Y" -M8((`````````*````!`````@`````0`(`````````0``$@L``!(+`````0`` -M``$````````D-)L`)S6:`"DZF@`W)\H`.BG2`#LIU@`\*MH`/BO>`"U!FP`S -M2K<`,TNX`#)-N@`S3KL`,U&_`#-3OP`Z5;D`,UC%`#9ESP`\;LT`-F;0`#9F -MT0`U:M0`-FO4`#5OV``U;]H`,W3>`#1RW``T=]\`-7C?`#]UV0`S=^$`,WCA -M`#=XX``W>N``-WSD`#E^Y0!)-;H`5#S@`%8]Y0!90.L`0';;`%ERS`!I3,<` -M>5?F`'M9Z0!!D"H`2K$P`$NT,0!;ICL`4[,J`%:Y*P!7O"P`4KTV`&F]1`!9 -MP"T`7<4P`%;2-P!:W#H`6]\[`%SB.P!=Y3L`:\%%`&C%1``VG=8`(X;S`#J` -MYP`Z@.@`.H'J`#N!Z@`[@NH`/(/K`#Z%[0`_ANX`(;+-`#[C]0`Z\ND`2('; -M`$**\@!$CO4`4H7A`%>1Z`!^I-@`:Z/N`&ND[@!BI/X`8Z;_`%[NZ@#$738` -MX5XJ`.MB+`#O8RT`ZW0^`/1E+@#X92X`\'<_`/EX/P#-?DT`@U_P`.2'-P#K -MBSD`[XXZ`/20.P#XDSP`ZY!8`/"36@#YD58`JXGC`+./[0"VD?``N)/S`+F4 -M]0"DQ^0`L]_\`+3Q_P"[\?\`O?/_`,GU_P`````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````!/3DE(1D0!441&1TE.3P``244C -M(!H;`DT;&A\C0TD``$(=&1<5$@,3$A06&!PD```B$0\-"PH)$`H+#`X1(0!P -M*5565E965E965E9651YP4E!S='1T='1T='1T='-04BI4#X$`'Q"%`!$\NP`B$(P`)Q66`"L6J``N&+4`,!JN`"XA -MA0`['\<`/B'0`"%=E0`K1J,`.5*J`!)[`$AGOP!M6*H`2VO!`$MKQP!.>]<` -M6WC*`%%\U@!N1MX`3@!HGE$`;;-2`$O% -M%@!3RQ8`7\8H`%OA&@!MS%(``%2*XP!=C^(` -M59#I`%R0Y`!>_@!9E_$`7IST`%N>^P!K'U`%CN_P!0\O\`A#8M`(HW -M+P"7/#0`G$,Y`*=%/`"+7%D`E6->`*U21P"V2T(`NU%&`+I:3`"D:64`N7%K -M`,%/10##6DT`Q5Y1`,YH60#49%<`UFQ<`,A[?_4` -MTX%X`(Z)O0"-A6YO;V]N;V]N -M;FYK:P```````&MK;V]O;V]W=7=N=RAY=V]O;W=O;VYN;FYK````````;FYN -M;6UM;75U=75U*'AU=6UU=75U=6YN;FX```````!N;75J=75J:FEI:6DR>&EJ -M:6IJ:FIJ:FUN;@```````&UJ:6EH:&AH:69F9C)T9F9F:&AF:&9G:6QM```` -M````;&=H9&-C8G)R8F)B,G)B8F)D("XP/I,``````````$Q$/T5)44D-%!E\ -M?H60C84&"A\A+C`^F@``````````3$`/$$%*10X6%1<:@(N+B0<%"!\D,#Z: -M``````````!,6E=<7%Y<#A0F6%E=>WJ%!QTI5UM>>IH``````````%)*1DI0 -M4U!#&!I\?X6.C(8C(Q\B+#Z1FP``````````54].3U165$V!@8*'B)2/B)65 -MEI:7FYRB```````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````/_______________^````?@```'X```!^````?@ -M```'X```!^````?@```'`````(````&````!@````<````/````#X```!^`` -M``?P```/\```#_````_P```/\```#_````_P```/\```#_````_P```/____ -M____________*````#````!@`````0`(````````"0``$@L``!(+`````0`` -M``$````````0/@4`#0=8`!4+9P`9#7D`(!!T`!)%!@`65`8`&5X'`!IC!P`E -M7@H`)V<*`"QT#``M?0P`,GD.`#A[*`!0%A(`8QP7`&P?&0!G+"4`="TF`'9)H` -M,TZH`#=JBP`:2]\`#T[W`!17_P`68_\`*W#0`#1OV0!-+J\`0!_X`$LER@!' -M(]<`1"'K`$HE^0!7*_``5RWZ`&TVY@!C-/\`>CW\`$UCJ@!*:K8`4VRT`%=U -MN0!A?KP`3G/"`$Y^V0!3;,@`47;$`%5YQ@!6>\@`6G[+`%1]TP!M9M``=&O< -M`'5H[``N@@P`,XP.`#B'#@`TE`X`.Y,/`#F=#P`[EA$`.:4/`#NH$``_M1`` -M0)X1`$2E$0!'JA8`2+@3`%*]%@!@ET\`:[!1`$C#$P!4R!<`4=(9`&#'*P!Q -MT%(`.X>T`!JPVP`:I_\`+I#9`"*YV@`LKOP`',WZ`![D_P`KR,`7)/G -M`%:?_P!<` -M:YWJ`&2>\0!QF^(`;Z+N`&>B]`!CIO\`:Z3T`&FF^P!KJ?T`=:3K`'BF[0!Y -MJ>\`:ST`'BN^0!^NOH`1MS_`%G;_P!,Y/\`:50"C96$`MVUH`,9.1`#&6$L` -MRUY0`-5?40#*958`U&56`-AG5P#*>7$`AD+_`(QO_P"9?O\`B:W7`)*]W@") -ML>T`B+KX`)K`WP"KRN8`I^7_`*[P_P"QY_\`L_'_`+OR_P#![?\`P_3_`,CU -M_P`````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````#(S,S,S,S,S,S,S,S,S,S,S,RQY,S,S,S,S,S,S -M,S,S,S,S,S,S`````````````'M\?'Q\?'Q\?'Q\?'Q\BWQ\>RR_?'R+?'Q\ -M?'Q\?'Q\?'Q\?'M[`````````````'Q\?(N+BXN+BXN+BXN+BXN+BRR_BXN+ -MBXN+BXN+BXN+BXM\?'Q\`````````````'R+BXN.CHZ.CHZ.CHZ.CHZ.C2R_ -MCHZ.BXZ.C8Z.CHZ.BXZ+BWQ\`````````````(N+CHZ.E)24E(Z4CI24E)24 -ME$"_EI24E)24E)24E)24E)2.CHN+`````````````(N.CI26E)26E):6E):6 -ME):4ED&_E9:4EI:4EI24E)26E)24E(Z+`````````````(V4E)26EI:6OY65 -MEI65E9:5E4&_E965E965E965EI65EI:4E(Z.`````````````(V.DY.5E965 -MD9&1D9&1D9&1D4*^D9&1D9&1D9&1D;Z5E963DXR-`````````````(V,DY*1 -MD)"0D)"0CX^/CXB/CT*^CX^/CX^/CX^/D)"1D(^2DHR*`````````````(J, -MCX:&B(B(@8&!@8&!@8&!B$*(@8&!A(&!@8&!@8B(B(B&B8J*```````````` -M`(J'A7>`=75U=75U=75U=75U=4*`=75U=75U=75U?7]_?W=_A8>*``````#! -MO(*"@GJ%@75U=75U1W5U1W5U1TAU=4!]275(24E)24E)2DI*2G5*>H1Z@H*" -MO,$`O7Y^?GIZ>$EU=4AU=4=`1T='0D1`1T!(1T=`0D1$1T1$1T=(2$E)=WEZ -M?GY^O```O7Y]?7IX=WQ\BWQ\?'Q\BWR+BWQ\BWR+?(N+BWQ\BXN+BXN+BXN+ -M=WAY?7U^P```O8-#0GEV@WLZ88'QL; -M&B$F*#@Y/3X```````````````!=6E-/#5)78&!<4P@2%J2?HJ:QM[>VL[$7 -M'R(;&B4F*3D[/3X```````````````!A60L*"@L,4U13#`D2$Q45G*&FL;*M -MI;$8`P0#`P4>(RHZ.@I::RM[>XM:XD-BHA(28U.3L]N;D```````````````!?7U]>7U]D -M9&1D7UZGJ*^OK["XN+BXN*]-34U,3$U.3KJZOKL````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``#_______\``/_______P``________``#_______\``/_______P``____ -M____``#X`````!\``/@`````'P``^``````?``#X`````!\``/@`````'P`` -M^``````?``#X`````!\``/@`````'P``^``````?``#X`````!\``/@````` -M'P````````````"```````$``(```````0``@``````!``#```````,``,`` -M`````P``X``````'``#@``````<``/``````#P``\``````/``#P``````\` -M`/@`````'P``_``````_``#\`````#\``/P`````/P``_``````_``#\```` -M`#\``/P`````/P``_``````_``#\`````#\``/P`````/P``_``````_``#\ -M`````#\``/P`````/P``_``````_``#\`````#\``/P`````/P``________ -M``#_______\``/_______P``________```H````$````"`````!`"`````` -M```$```2"P``$@L````````````````````````````````````````````` -M```````````````````````````````````````````````````````````$ -M!1P"`0`$*@```$````!`````0````$````!`````0````$````!`````0``` -M`$`!``0J`P4<`@``````````1([U_T**\O\_AN[_/H7M_SN"ZO\Z@>K_)#2; -M_U>1Z/\Z@>K_.X+J_SR#Z_\_AN[_0HKR_T2.]?\``````````#^&[O\[@>K_ -M-WSD_S-XX?\S=-[_-'+<_R'_N_'__[WS__^]\___O?/__[WS -M__^]\___O?/__[WS__^]\___O?/__[WS__^[\?__4H7A_WZDV/]9*O_P=S__\)-:_^2'-_\W)\K_5CWE_WM9Z?^KB>/_```` -M!@````,````$````"%K<.O]*L3#_:;U$_U:Y*__K8BS_ZW0^_^N06/_KBSG_ -M.BG2_U0\X/]Y5^;_LX_M_P````@````$`````P````9;WSO_09`J_UNF._]7 -MO"S_[V,M_\1=-O_-?DW_[XXZ_SLIUO])-;K_:4S'_[:1\/\````&`````P`` -M``(````$7.([_R&RS?\Z\NG_6<`M__1E+O\VG=;_7N[J__20._\\*MK_(X;S -M_S[C]?^XD_/_````!`````(````!`````EWE.]U2O3;W:,5$\EW%,-;X92[> -M^7@_]_F15O+XDSS6/BO>WEE`Z_>#7_#RN93UU0````(````!```````````` -M```````````````````````````````````````````````````````````` -M`````````````/__``"``0``@`$``(`!``"``0``@`$````````````````` -M`````````````````````````````````/__```H````(````$`````!`"`` -M```````0```2"P``$@L````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````(//P<"##0M`@PT,P(--RD"#3>_?]8G_W_69_]_UN@_?];H/W_6Z']_UNA_?]; -MH?W_6Z']_UNA_?\N2:7_?+3]_UNA_?];H?W_6Z']_UNA_?];H?W_6Z#]_UN@ -M_?]9G_W_6)_]_U>>_?]7G___59[__P`````````````````````````````` -M`%>>_?]9GOW_6Z#\_UR?_/]=H/K_7:#Z_UV@^O]>H/K_7J#Z_UZ@^O]>H/K_ -M7J#Z_S5/J/]\L?K_7J#Z_UZ@^O]>H/K_7J#Z_UZ@^O]=H/K_7:#Z_UV@^O]< -MG_S_6Y[\_UF>_?]7GOW_````````````````````````````````6Y[\_UN? -M^O]=GOG_7I[X_UZ>]O]?G?7_7Y[U_V"=]?]@G?7_8)WU_V"=]?]@G?7_/%6K -M_WNM]?]@G?7_8)WU_V"=]?]@G?7_8)WU_U^>]?]?G?7_7I[V_UV>^/]=GOG_ -M6Y_Z_UF>_/\```````````````````````````````!E^S_7I?L_UZ7[/]"6J[_=J7L_UZ7 -M[/]>E^S_7I?L_UZ7[/]?F>S_7YCN_U^9[O]>F.__7IGQ_UZ;]/]K_]MFN+_78_B_UV/XO]= -MC^+_78_B_UV0XO]=D.+_6Y#D_UJ1Y?]:D^G_6I7L_UJ8[_];FO7_```````` -M````````````````````````69?Q_UF3Z_]7C./_6(K>_UF'VO]9A-?_6H37 -M_UJ#UO]9@M;_68+5_UF"U?]9@M7_1&&P_V.+U?]9@M7_68+5_UF"U?]9@M;_ -M6H/6_UF#UO]8@]?_6879_UB'W?]6BN+_5Y#I_UB5[_\````````````````` -M``````````````!5D>K_58OC_TUNRO],;,;_3&O#_TMKPO]+;,'_2VS`_TML -MP/]+;,#_2VS`_TMLP/]"8;#_5'+#_TMLP/]+;,#_2VS`_TMLP/]+;,#_2VS! -M_TMKP?]+:L/_2VO%_TMMR?]4B.'_5)#I_P```````````````*K)YLI]GM'_ -M<9/,_U&+Y?]0?]?_26C$_TAGO_]'9[W_1F>\_T5HN_]%:+K_16>Z_T5GNO]$ -M9[K_1&>Z_SY@L/]*;+S_1&>Z_T1GNO]$9[K_16>Z_T5GNO]%9[O_16>\_T9F -MO/](9K[_26?#_T]\UO]0B.+_<9/,_WV>T?^JR>;)GL3A7XJMUO]IB,/_4(7? -M_U)ZT_]CIO__8Z;__V.F__]CIO__8Z;__V.F__]CIO__8Z;__V.F__]CIO__ -M8Z;__V.F__]CIO__8Z;__V.F__]CIO__8Z;__V.F__]CIO__8Z;__V.F__]C -MIO__47?1_T^#W?]IB,/_BJW6_Y[$X5^3O-X)C;;;ZV.`O?]/@-O_7XO>_\CU -M___(]?__R/7__\CU___(]?__R/7__\CU___(]?__R/7__\CU___(]?__R/7_ -M_\CU___(]?__R/7__\CU___(]?__R/7__\CU___(]?__R/7__\CU__]>BM[_ -M37[8_V.`O?^-MMOKE<#>"0````!^I-B+9X;"_TQ[U_]\L/#_P_3__\/T___# -M]/__P_3__\/T___#]/__P_3__\/T___#]/__P_3__\/T___#]/__P_3__\/T -M___#]/__P_3__\/T___#]/__P_3__\/T___#]/__P_3__WRP\/],>=;_9X;" -M_WZDV(H``````````&Z/TR)IB,W]3WS7_Z?@_O^]\___O?/__[WS__^]\___ -MO?/__[WS__^]\___O?/__[WS__^]\___O?/__[WS__^]\___O?/__[WS__^] -M\___O?/__[WS__^]\___O?/__[WS__^]\___I^#^_U!\U_]IB,W];H_3(@`` -M`````````````%][SK5=CN/_MO'__[?R__^W\O__M_+__[?R__^W\O__M_+_ -M_[?R__^W\O__M_+__[?R__^W\O__M_+__[?R__^W\O__M_+__[?R__^W\O__ -MM_+__[?R__^W\O__M_+__[?R__^V\?__78WC_U][SK0````````````````` -M```!4FK(2W6P\O^R\?__LO'__[+Q__^R\?__LO'__[+Q__^R\?__LO'__[+Q -M__^R\?__LO'__[+Q__^R\?__LO'__[+Q__^R\?__LO'__[+Q__^R\?__LO'_ -M_[+Q__^R\?__LO'__[+Q__]UL/+_4FK(2P````$```````````````$9(4,& -MO.C^_\KU___*]?__RO7__\KU___*]?__RO7__\KU___*]?__RO7__\KU___* -M]?__RO7__\KU___*]?__RO7__\KU___*]?__RO7__\KU___*]?__RO7__\KU -M___*]?__RO7__[WI_O\9(4,&`````0```````````````@````<````--7T. -M_S![#/\J;`S_+H$,_S:=#O]%M1+_,8L-_Q1+!?\_$0__52(<_V\M)O^(-B__ -MJ44[_[]:3O^E44/_?C_Y!TX/\````/ -M````"`````,```````````````,````'````#DBJ$_\XCP[_*W,,_R^$#/\X -MH`[_1[T3_S>>$/\980?_4A@4_V$F(?]S+B?_C#@O_ZQ&/?_'75'_NEM-_Z%& -M//\."%C_&@UL_QX/@?\I%:'_/"#(_U@NYO]P2.+_E'?F_P````X````'```` -M`P```````````````@````4````)2Z\4_SJ4#O\M=PS_,8D,_SJF#_]*Q13_ -M.J81_QIF!_]6&17_9"@B_W^W_````"0````4````"```````` -M```````!`````P````5-M13_/9D/_RY\#?\SC@W_/*T0_T_-%/\]K1'_'&L( -M_UL;%O]I*B/_?#(J_Y<\-/^[3$+_V&99_\UD5/^T34/_#PE?_QT.=?\B$(S_ -M+1>N_T`BV?]?,??_>$WS_YY_]?\````%`````P````$````````````````` -M```!`````4ZZ%?\^GA#_,($-_S63#?\^LA#_4]05_S^V$O\=<`C_7AL7_VXK -M)_^"-2S_G#XV_\%/1?_B:UO_U6A9_[M11/\0"63_'@]Z_R(1D?\N&+7_0R3@ -M_V,S_O]]3OK_HH+[_P````$````!```````````````````````````````` -M4;X5_S>"#?\I9@S_+6X*_S:%#/]'K!3_.)00_QUT"/]A'!C_523__$7D__P5)(_Q`):/\;#5O_'@]K_R@5D?\\'\W_6"S[_W-) -M\?^EA?__``````````````````````````````````````````!3P1;_(\'4 -M_QS#[/\@\O__(?___S7___\J\___'WD(_V$<&/\A797_(X#,_RNZ]_\PX/__ -M4/+__U+=__^\4D?_$`EH_Q$\N_\27-S_&J?V_R'5__\\_/__6.[__Z:&_?\` -M`````````````````````````````````````````%_&*/]-KQO_.I(3_SRE -M$/]&P!3_6^$:_TS#&_\PAAO_;BTJ_W8U,/^#-R[_F$`V_[E01O_6;U__SFQ= -M_[9:4?\Q*G[_+B&%_R<9DO\P&J[_2"?8_VP^]?^(8/7_KI;Z_P`````````` -M````````````````````````````````=<%4MF^T4]9HGE'N:[)0_7#+5/UY -MY53N;3K>)65>VC5];UI5C7NZD:67]O7%L_=.!>.[(>W/6M'!JMXZ+ -MO;:-A[W6BH3![H^&TOV:C>G]JY?][KBH_=;,P/^W```````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````````````````/__________X```#^````?@```' -MX```!^````?@```'X```!^````?@```'````````````````@````8````'` -M```#@````8````&````!@````8````&````!@````<````/P```/\```#_`` -M``_P```/________________*````#````!@`````0`@````````)```$@L` -M`!(+```````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````!&%P!`A=<"@(770D" -M%UX#`A=>`P(77@,"%UX#`A=>`P(77@,"%UX#`A=>`P(77@,"%UX#`A=>`P(7 -M7@,"%UX#`A=>`P(77@,"%UX#`A=>`P(77@,"%UX#`A=>`P(77@,"%UX#`A=> -M`P(77@,"%UX#`A=>`P(77@,"%UX#`A=>`P(77@,"%UX#`A=>`P(77@,"%UT) -M`A=<"@$87`$````````````````````````````````````````````````` -M`````P?__]9H/__6J#__UNA -M__]__\` -M````````````````````````````````````````````````````6:#__URB -M__]>H___8*3__V*E__]CIO__8Z;__V2F__]DIO__9*;__V2F__]DIO__9*;_ -M_V2F__]DIO__9*;__V2F__]DIO__-E*I_X2X__]DIO__9*;__V2F__]DIO__ -M9*;__V2F__]DIO__9*;__V2F__]DIO__9*;__V.F__]CIO__8J7__V"D__]> -MH___7*+__UF@__\````````````````````````````````````````````` -M````````7J/__V&E__]EI___9J?^_VBH_O]IJ?[_:ZG^_VNJ_O]KJO[_:JC^ -M_VJH_O]JJ/[_:JC^_VJH_O]JJ/[_:JC^_VJH_O]JJ/[_/EJN_XBY_O]JJ/[_ -M:JC^_VJH_O]JJ/[_:JC^_VJH_O]JJ/[_:JC^_VJH_O]JJ/[_:ZK^_VNI_O]I -MJ?[_:*C^_V:G_O]EI___8:7__UZC__\````````````````````````````` -M````````````````````````8J3]_V:G_O]KJ?[_;:K^_V^L_/]RK/S_*[Z_W>N^O]WKOG_=Z[Y_W>M^?]WK?G_=ZWY_W>M^?]WK?G_ -M=ZWY_W>M^?]WK?G_3FRU_X^Z^?]WK?G_=ZWY_W>M^?]WK?G_=ZWY_W>M^?]W -MK?G_=ZWY_W>N^?]WKOG_=Z[Z_WBN^O]VKOK_=:S[_W*L^_]NJOS_:Z?\_V6F -M_O\`````````````````````````````````````````````````````:*;\ -M_VVI^_]RJ_K_=:WY_WBM^/]YKOC_>J[W_WJN]O]ZK?;_>JWV_WFM]/]YK?3_ -M>:WT_WFK]/]YJ_3_>:OT_WFK]/]YJ_3_5'&X_XZX]/]YJ_3_>:OT_WFK]/]Y -MJ_3_>:OT_WFM]/]YK?3_>:WT_WFM]/]ZK?;_>JWV_WJM]_]YK??_>*WX_W6L -M^?]RJOK_;:G[_VBF_/\````````````````````````````````````````` -M````````````:J;[_V^I^/]SJO?_=JOU_WFK]/]ZJ_3_>ZSS_WNK\O]ZJO#_ -M>:GP_WFI\/]YJ>__>:GO_WFI[_]YJ>__>:GO_WFI[_]YJ>__5G2[_XRT[_]Y -MJ>__>:GO_WFI[_]YJ>__>:GO_WFI[_]YJ>__>:GO_WFI\/]ZJO#_>JKR_WJK -M\?]YJ_+_>*KS_W:J]?]SJ?;_;ZCX_VFF^?\````````````````````````` -M````````````````````````````:*7X_VZG]O]RJ/3_=:CR_W>H\/]YJ.[_ -M>:?M_WBF[/]WI>O_=Z3K_W:DZO]VH^K_=J/J_W6CZO]UH^K_=:/J_W6CZO]U -MH^K_5G:\_X:MZO]UH^K_=:/J_W6CZO]UH^K_=:/J_W:CZO]VH^K_=J/J_W:D -MZO]WI>O_>*7L_WBF[?]WI^W_=J?O_W2G\?]RI_/_;:;U_VBC]_\````````` -M````````````````````````````````````````````9Z+T_VRB\O]PI.__ -M;IWH_V^#_;I??_VZ6W_]MEM[_;9;>_VV5WO]M -ME=[_;97>_VV5WO]ME=[_57:\_WN?W_]ME=[_;97>_VV5WO]ME=[_;97>_VV5 -MWO]MEM[_;9;>_VZ7W_]OE^#_<)K@_W":XO]PF^/_;IOE_VV;Z/]OHN[_:J+Q -M_V>A]/\````````````````````````````````````````````````````` -M9)[R_VF?[_]KG>K_8(74_V*&T_]BA]+_8X;1_V&&T/]@A<__7X3._UZ#SO]> -M@\W_7H/-_UZ#S?]>@\W_7H/-_UZ#S?]>@\W_472Z_VR-T/]>@\W_7H/-_UZ# -MS?]>@\W_7H/-_UZ#S?]>@\W_7H/-_U^$SO]@A<[_88;/_V*&T?]AAM+_8(73 -M_U^$T_]IG.C_:)WL_V.>\/\``````````````````````````*O*YLM^G]+_ -M\C_5GO(_U9[R/]6>\C_3&^Y_V&# -MRO]6>\C_5GO(_U9[R/]6>\C_5GO(_U9[R/]6>\C_5WS(_U=\R?]8?LC_57K&_U-XQ?]0=L3_3W7#_T]TPO].<\+_3G/"_TYSPO].<\+_3G/"_TYS -MPO].<\+_1FJV_U=YQ/].<\+_3G/"_TYSPO].<\+_3G/"_TYSPO].<\+_3G3" -M_T]TP_]0=<3_4G?%_U1YQO]5>&V_]EDN+_R?7__\GU___)]?__R?7__\GU___)]?__R?7__\GU -M___)]?__R?7__\GU___)]?__R?7__\GU___)]?__R?7__\GU___)]?__R?7_ -M_\GU___)]?__R?7__\GU___)]?__R?7__\GU___)]?__R?7__\GU___)]?__ -MR?7__\GU__]DD>'_5H3:_U*'W_]A?KS_87Z\_W>;R_^2O=Z+``````````") -ML=LC@JG5_5MVMO];=K;_487?_U-\T_^'N_7_Q?3__\7T___%]/__Q?3__\7T -M___%]/__Q?3__\7T___%]/__Q?3__\7T___%]/__Q?3__\7T___%]/__Q?3_ -M_\7T___%]/__Q?3__\7T___%]/__Q?3__\7T___%]/__Q?3__\7T___%]/__ -MQ?3__\7T___%]/__Q?3__\7T__^'N_3_47K2_U"#W/];=K;_6W:V_X.IUOV) -ML=LB````````````````?J38M6!]N_]4;;#_4(+<_U9_U?^QY___P?3__\'T -M___!]/__P?3__\'T___!]/__P?3__\'T___!]/__P?3__\'T___!]/__P?3_ -M_\'T___!]/__P?3__\'T___!]/__P?3__\'T___!]/__P?3__\'T___!]/__ -MP?3__\'T___!]/__P?3__\'T___!]/__P?3__\'T__^QY___5GW4_TY_VO]4 -M;;#_8'V[_WZDV+4`````````````````````=);52FB(R/]-9*K_3G_:_V*2 -MX_^]\___O?/__[WS__^]\___O?/__[WS__^]\___O?/__[WS__^]\___O?/_ -M_[WS__^]\___O?/__[WS__^]\___O?/__[WS__^]\___O?/__[WS__^]\___ -MO?/__[WS__^]\___O?/__[WS__^]\___O?/__[WS__^]\___O?/__[WS__^] -M\___89'C_TY]V/]-9*K_:(C(_W26U4H`````````````````````_Z?E__^U\O__M?+__[7R__^U\O__M?+_ -M_[7R__^U\O__M?+__[7R__^U\O__M?+__[7R__^U\O__M?+__[7R__^U\O__ -MM?+__[7R__^U\O__M?+__[7R__^U\O__M?+__[7R__^U\O__M?+__[7R__^U -M\O__M?+__[7R__^U\O__M?+__[7R__^U\O__I^7__U2$W?]2:[G_8'[/=``` -M`````````````````````````````%MTS116;\CV8I?I_['Q__^Q\?__L?'_ -M_['Q__^Q\?__L?'__['Q__^Q\?__L?'__['Q__^Q\?__L?'__['Q__^Q\?__ -ML?'__['Q__^Q\?__L?'__['Q__^Q\?__L?'__['Q__^Q\?__L?'__['Q__^Q -M\?__L?'__['Q__^Q\?__L?'__['Q__^Q\?__L?'__['Q__^Q\?__L?'__V*7 -MZ?]6;\CV6G3-%`````````````````````````````````````%0:,>@?KWW -M_Z[P__^N\/__KO#__Z[P__^N\/__KO#__Z[P__^N\/__KO#__Z[P__^N\/__ -MKO#__Z[P__^N\/__KO#__Z[P__^N\/__KO#__Z[P__^N\/__KO#__Z[P__^N -M\/__KO#__Z[P__^N\/__KO#__Z[P__^N\/__KO#__Z[P__^N\/__KO#__Z[P -M__^N\/__KO#__WZ]]_]0:,>@`````0`````````````````````````````` -M``````)$5[8ZP>W__\CU___(]?__R/7__\CU___(]?__R/7__\CU___(]?__ -MR/7__\CU___(]?__R/7__\CU___(]?__R/7__\CU___(]?__R/7__\CU___( -M]?__R/7__\CU___(]?__R/7__\CU___(]?__R/7__\CU___(]?__R/7__\CU -M___(]?__R/7__\CU___(]?__R/7__\'M__]$5[8Z`````@`````````````` -M``````````````````````,````*````%#5[#O\L;0O_)F4*_R1>"O\D9PG_ -M*WP+_S&-#?\WG0__-Y`._S-]#O\D8`K_$#X%_T84$/]3(QW_9BLE_W0M)O^& -M,2G_F3LR_ZA`./^N3D/_HDY!_X]'//^#/37_>S,J_PT'5O\7#&;_&0UW_Q0* -M??\5"X;_'0V:_R,2J/\L%K+_,1BP_S0:JO\]'Z;_3R>F_P```!0````*```` -M`P````````````````````````````````````0````,````%CJ%#_\VA`W_ -M+7<,_R9E"_\E:@G_*WP+_S"-#?\XH0__/)L/_SJ0$/\J<`S_$4`%_TD5$?]@ -M*"+_=S(K_WTQ*?^),BK_FCHR_ZA!.?^T4$7_KU1%_Z921?^91SW_@C8L_PT' -M6?\;#G;_'0Z+_Q8+B/\6#(K_'0V;_R,2J/\N%K?_-AJ__SX>R/]+)C$_\YC0[_+WH-_RAJ"_\G;@G_+8(+_S.4#?\[J!#_/J$0_SR5$/\L -M=@S_%$D&_U48%/]F*R3_>C0L_X(S*_^/-2S_H3TT_[!$._^[5$C_ME=)_ZM5 -M2/^A2T#_E3TR_Q`):/\=#GW_'@^/_Q<+C?\7#)#_'PZB_R42L/\O%[__.!O& -M_S\?S?].*-?_:33=_P```!4````+````!``````````````````````````` -M``````````,````(````$$JJ%/\]E0__,H$-_RIQ#/\I=0K_+XD,_S6<#O\^ -MLA#_0JL1_T"?$O\O?PW_%5`&_UL9%?]M+B;_@CPO_,9`-_SBD#_]"NA'_1K42_T2J$_\SB`[_%U<&_V,<%_]V,BG_C#LS_Y,Y -M,?^@.S'_LD0Z_\-,0O_17E#_S6)2_\-A4O^Y5TK_K4<\_Q(*>?\A$9'_)!&C -M_QH,G_\:#J'_(@^S_RD4P_\T&M7_/Q[?_T@CZ/]8+/#_Q%/\UCP__&%P'_V@> -M&/]\-"S_D3XU_Y@[,?^E/3/_MT8\_\A.1/_78%+_U&95_\ME5?_#6TW_MDM` -M_Q,+@/\C$9G_)!*K_QP-IO\;#J?_(Q"Y_RH5R/\V&]S_02#H_TLD\_]<+OG_ -M=SOY_P````0````"`````0`````````````````````````````````````` -M```!`````5*[%O]$I1'_.)$/_R]]#?\M?@O_,Y4-_SJI#_]$P1+_2;X3_TFT -M%/\WDP__&5X'_VL?&?]_-BS_E#\V_YH\,_^F/3+_N$8\_\E.1/_97U'_UV=6 -M_\]G5__'74__O$U!_Q0+A?\D$I__)1.O_QP-K?\;#JK_(Q"[_RH5S?\W&^#_ -M0B#L_TTE^/]?,/[_>SW^_P````$````!```````````````````````````` -M`````````````````````````%*]%O]$IA'_.),/_R]_#?\M@`O_,Y4-_SJJ -M$/]%PA+_2;\3_TFV%/\WE0__&5\'_VP?&?^!-BS_ED`V_YH],_^G/3/_N48\ -M_\I/1/_:8%'_V&A6_]%G5__*7E#_O4Y"_Q0+BO\D$J'_)A.R_QP-L/\<#JO_ -M)!&^_RL5T/\W'.+_0R'O_TXF^_]@,/__?#W__P`````````````````````` -M`````````````````````````````````````````%.^%O]$IQ'_.9,/_R^` -M#?\M@0O_,Y8._SJK$/]%PA+_2L`3_TJV%/\WE@__&5\'_VP?&?^!-BS_ED`V -M_YL]-/^G/C/_N4<\_\M/1?_:8E+_V6A6_])G5__+7E#_ODY"_Q4+B/\E$J/_ -M)A.T_QP.L?\<#ZW_)!'`_RL6TO\X'.3_1"'Q_T\F__]A,?__?3[__P`````` -M`````````````````````````````````````````````````````````%._ -M%O\[C0[_,'0-_REA"O\F7@G_*VD+_S%W#?\\D`__/9C3_ -M_RC@_/\>V/[_&F`'_VT>&O\>9)K_)7O!_R2&W?\FI?__+\G__S/;__\SV___ -M.M'__S_,__\]R?__P$]#_Q4+C?\02^C_$E'__PY)__\/5___%(#__Q6C__\9 -MH/__'ZK__R?%__\RYO__@D#__P`````````````````````````````````` -M`````````````````````````````%7!%O\SRL#_*,'*_R+#U_\CT>G_*.W_ -M_ROZ__\O]/__-NW[_SKG[_\MU\[_&F('_V\?&O\W:HO_.X>T_S>9U?\YL?7_ -M0=G__T?H__]0X?__6=O__V?3_O]JQ/'_P$]$_Q8,D_\:2]__&&'__Q5=__\3 -M9?__&Z[__Q[*__\FM?__+L/__SO0__]+WO__B$+__P`````````````````` -M`````````````````````````````````````````````%C%%_])LA/_/9X/ -M_S.)#O\PC`W_-Z$/_S^X$?]+SQ/_4,H5_T_!%O\[GQ#_&V8'_V\@&O^%."__ -MF$,X_YT^-/^I/S;_NTD]_\Q51__=9U?_VFM:_])K6__,8%+_O$Y!_Q8,E?\H -M%;#_*A;"_Q\/O/\?$+__*1/2_S$8Y/]`'_C_3";__U4K__]J-?__B$/__P`` -M```````````````````````````````````````````````````````````` -M`&G+-/]9NBC_2JD>_SJ3%?\VEA'_/*D0_T2^%/]1TAG_5<\;_U;#(O]*IB3_ -M.'LH_X([./^+13[_ED@__YI`-_^C03;_M$D]_\552?_395?_TFU;_\UN7O_% -M9UO_NUY5_T$WM/\_+[[_-B7#_R86N/\D%;W_*1/._S,:X?]$)??_4RW__V$[ -M__]\3?__FF+__P`````````````````````````````````````````````` -M`````````````````'&^5(APMU*P:ZM1RV:>3^9EHT_N:;5/_6S)4?USVE+N -M=-52YF_&4\MEJE&P68].B)-95XB985VPH&5ARZ!E8.:J9F+NMFQF_<-S;/W0 -M>G+NS7USYL9Y<-KMO6NT9$E6W_?;$2_6YZ -M>GJ>P"!@A!@9S!(&M,:\UB"D&1!H>&B8:3'#C#RV+(-8,C(@$$NL91F!M#`& -M/@A+!DE+1H`LF8>!!=CR8%C`#`QBF.[J[NJNKJ[J[JJZCWR?S/OS.'1`1$1$1$1$1$1$1$1$1$1$1$1$1 -M$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1 -M$1$1$1$1$1$1$1$1$1%Q&I#3SL`J#5&Y_X -MOM/`/44`#__Z>QI&6#E)TF*%I!L,FMO./LYM]3'?2C^K=X4=O_XU_DQVG?/<] -M]MY&<_.^MS6W+K^UL7GI38V-"X\U6MN/-UJ;C]I&ZPECS!:B@$,U1]6!.L0T -M$&EA[`9B-A'30J3ICZ6!,0W$-#&VA9@FB,$8,!;$^"I`:ON`R^BF`Y[O[W.S -MM\_'>[M\K+OW[$?[>\]\]*5/_I?'*M_NQAL;EN1MQC3>:DC>9,0\!N9Q1!Y5 -MY(D,MC(@11FHHK77E2!8#`T$BV`%&AA,G0`\"83]Q*?BV+_P<)R`V"[P/+B; -MJ'X;7]AOM_>=NTN -MKMO']8;H,/5ID**##(89FN60.31SX%Q5$R*3"<`:Q-J#VR1!DD`&82L-GRCV -MFTU,JX%L-/WYU.WSZO`WW4O]G],7.C]_^V_^[)W#RG?_XW_[P:TK;_J:"_=_ -M^CNWKCSVAP]E3QT=-`A\GE>"KPYRA^8.5'TM&)""`(Q424"L`6/`6M\=L,9_ -M_.4VG#?6:PN]?Y'^Z\_?O?L>_>ZE> -MOOL?_Z=/7'KX<[[W\B.O^X:-BXV6L7O`+M!%70^7#WQR*>J&J$N]P*LODZI# -M50'U`E\(O22U;0)B,:;XFR]'=:T)QP6!>!7`GT\\003-P22;&+N!L5O8I`E` -MOTWWSO7\G[_RW&]^WW.___:1\KW0?,T3VV;[>XW=_(8.2>LVRBZ.@7IA]P+O -M2%$R')DJ>4U5*UK_0MBM%()/3?@-"1($WH3SAB0(O@UBK^%^H;:\8(@GA23\ -MMH5A4Q(N2Q/L%MA+8"]W,1O_*_GN]\M+_^0EUA!K20"?IC_UK8/N*S_2?_'Z -M9OK2*^1WVKA./[3N10I"G^?@=@ZGS17WVP50A]:?S'4"$!J!&""H(]I -M`B8002"`D>/B^H(HQ*![&7HW13LY#'/(M2V)^?#NW_NEGP)X^(V_^O[[7O.I -M/WSQ`=U,FG=`]G!Y&^=ZJ$LAJ/=>X'/02N4_0`"J->$.@E^0@&D`IB*`D>M, -MM9U``'X;FGX\B8J`,0DN[Y$.]LD&.Z2#NZ3]W79__\*W/?61#_\TP.\V'_M` -MTUSXQZG9V.R(81!4^@&.3!T.)4-Q*$[#%M_Z%Q2@:&CY*0D@830UPKF*`"H2 -ML($$?.YEA`!&":$Z+R(TMK:X<.DB5RY>YLJ%!V#S$;AEVMSN?D">_ZZ?.6W9 -MF!=K1P!OT9_YNO[^K7_=?>HIAC=>QK5[,$S10MBSS.]/(P#G6W^<^GVGA1Y9 -MM?@2A-\6&H$I2H#M] -M3=[R\%]J_H?ON7#ET8?_U:6'AS2W.@A=E#0(MA?X0O#5C0H_@0`J$CA(`(QI -M`$(E_,9XM;?4!"81`.,$4$#)TGUZN\\P[-TD&[;)TQYY-B`;[-'?OZE)Z])7 -M_?#5CUQR=NM?MLPVB30)%@LT"'G1TF:"@?N_$. -MN?9W?O&T960>)*>=@7F1]WK__>#9ZZ0OW48[`Z_2._6"[!0MWYJ&5#_FX#$< -MW$K][U+]ANJWJHJH?YX4USJM?NNJAZDZ].4!>C>#+.33*9KF,,Q`09V3X4>> -M^[Y-VTULXSK&:A`X-_),+.NOD_!*RH(6I5%%I+A.#ORJ+ORRV42%LDY5'4.7\7)O -MG\[-J[SV4S]3N'7Q>[C&6A&`.?DM5HM\O_UGL]TVVD^]D&GM-8\(!%.^A+'] -M\=_73^FDZ\?.C=^X))IJJ[LI#%Q)4B5!!"+PADA!>^GGJK[T5I$=;!*,D.6M -M:X+/Z&>J]6N.0OU>8X+NCP\6H:R3LG[J)`-9VB,;[(?C0A.I$10$S21_VRW< -M6P>(;Y&#!E%QLE;EJ9=MRNN8]$K'SXW7U?1:TMJ_VC6)[^J51*1:EL^_"TUT`*W\1$\]#:P?`12MYC1=#\:^VB.^BB7S -M@F8UK:(N[/5\UY40LI$\E\(_4HS5D=E1,J4NHU`;"A*HM(OQ,FC9WY_ER0N3 -MY^-"#G8+1CZ\&B,Z57#K1P!K9P,X@&GZWV&-9)',V#E#S2!8VP]^(MC09S;U -M^VA-'J=_LH5I8&J^I_UTQ"XQP_4S00Y-"DAI')A"-J%/[57^@QFN_M<)YT^6 -M\Z(7+T&+F)0FO<9)I3_\8:/ZCY:#A&/%U9&=M<(:$D!M(*CH2^?.M[19V,^U -M&N8N_4^OW*48L_-:H036(6>$-6.15O`!JGE=Y<3G.N6IH,JC+T\JF"CG!ZA^L -M__7CNN6_U!NT$D+_"K0V_@\-A42@@4^):A@=@$0-5AQ&O?.0")[1&:6I\)6@ -M*L&P*.5?BBZ.*0VC8Y_EFF']""!W,,B@DT$_>/@-<^_TDX=Q\=)7S*'BP#BP -MQ3:4.L$/\UF@$;Z81)"&^&,;A@(!40,A22[@BF/QR0&Y0N[)1I3*QZ"OT'5H -M)T?W<^CG:.J\&_(PAS2O/!)500?>T2?K@@IY/L#EP;O/N6#["((^3AY:M%&C -M[50YY!>\_;PG7SA7'Q84SWI^=%W*83]_;U\<5S*+SV^>#\C3OA_R2[MD:1N7 -M]>J%!2H*]*5QVY**DZLC#LY[0RP[G"2L]!!2W,S"B'_1H( -MS6!8+/:+H;YB2-`[_GCG'A.\_PHK1`[!R<@+=![L%+D&/P35TGXK*E@U6#4D -M:DG(2$@P(UX*ZX.U(X"\W25_I8-[N>=;>!Q8A9:$L7C0)(S7)\ZGAO--0R,< -M$RSR6G@"ELT;%!^&$R_D0NG,X\?XPYAXX2A?.T:W3E&]1C;L,^R!L8U2H(7@H6>3*K\UC&@G8>2\&-T66SC[ -M&$RH(U.XR-=\_*5P\L$&,@A;+*H^H5*SA#ORM$EF!"%'W0"3-U!,T$9R7#8D -M3_NX;(@ZQUV4"V0\H"G;V%*@&\'1)GA,^"D-HB-"7Y"`*[HIP?NO3%)X]@DJ -MIFJ]@]9C@@^`Q83K"Q((I*-*!N3B'9$R,61BR#'D8LG*=M^30Z8YXC*L&^(T -M!5V_*0)K1P":IDC+(E>:B/6J.>(YW/.X(.)0J;'Q`+0;'("RT#7(=@O@GY"4+#"YP97>OKE -MB$FP-N?BQ4[I"-3I;9>38RIOP#H1&"IQ+";/2)@3L('834RRA7$#5%.L>J$B40J#9`$)];?0:,1<.DP -M%S:1RRU$&ZCFB)/0YR_L`1I4\I`RY8K+>3,#WN(&/.Y2'M&,U[1R[KNH7+H@ -M7+HB7+I?N/*@12Y;N&1AJS`*&*I>84;1"]X="+M#87\H[*>&.T/A1M=RJV^X -MOI_PR9T63_;=WF@L<;E._=Q9_$BAFTQ;&+)41R.7()K1/W5XG#X-4R1)!6H+9 -M-/"JH;-EZ&]!>$,B#J$R]B4F -MY8O>_(=\\>-_Q.=<>H;7\HHOWWZM?$-!]@63&;*N8>^VH?.\G:E\QL+%1LK% -MYAY<$KB";_334+Z.(V_[\GW\N8?XG:=?S^\^_^G\R2M/D!==#RDZ+QK*Y=-& -M:*U+PZ)2JM6EO[]5'O^"/H]_3I^'GQAR:2,]6+Y$Z(C0ZQGL*P;;,=@;LY4/ -M"[8AV"U\^%Q-8^\#3O@1__ZC_$Y[JHOW_../VB?9OE>Y#Y]@;_XT&_QYL9K -M^/GGOHY*$=8#8V[%]-UI;D"FI;S]'^_PT*4![>N.6R\[KIYJ^8;T'NJ0?OZK -M-%ZZR5L^^CEL4`U'CNH7:S>U9@T)`#BLHK]B<)?/?:[#\Z\Z!EUE,)SPTUI' -M3T:^$ZFEVO&!9TYZ_L$;BPC#%'8Z<'?/(?T.K^GUPD"GYT*&] -ME'E1C*=WAWJFRY=F*7G6F[M\!3J#LUV^3IZSDPV.7;ZSAGN#`)B1BV5\=T:5 -M3:9=-ZEU&3\\ZK<++.B9*M\2%.(S5;Z:'>/09YQMK"D!K%CUFNK.-M&9?Z)K -M["GE?.7E&\5TH=`9SIS]\LU>WK.*]22`"9-_9JIZ'=_5R?>;>+*:^37=*5\/ -MWG-!_OMR8.^D@@$:VU'G5S -M?&U?)MRG[C>.O\^1LY5+R/331Y;CC)5O$7)RELMW#V"M"6#21(S]OI)N5\>9 -M@]VNTNXKW53II>55&*DV31)F2PM.C9U>+^GI/GIE$\4 -M\L/*ERMYKI#4\SS?O/]V'[*B?+K\\C5;XOVQ9BQ?EN-=SP^\O_7$6A/`)%QM -M;O*COY;2<(Y7]Y7=@=(UEH$1AF(8&B&U0F8ES.\17"+!/U[(K>`2XX?B@X.. -M*6($2IB`(L4'9,J99@9(P-XCK1.5[_K@M?S8 -MKSJL2WFUK>SU#0.WR="UR+1)3I.,)GGP)U#CPUJ+%8PQJ&GZXR*NH=C@=N!] -MYJW)L28OA\&LR3&2XSWB^^#Z:-;#93VR89=LL`LN0X!.S]#C!XM:VTNXH,#:1^GH7D@N1^=J,IYP(8?(Q6\3/^$*RI(@6;\`X-4D;Z -MEN#0HXF&N5W*T#@&QM$GIZN.CLO9U30XF,.@"V]/6]"[%>6$\"D&JC -MM6.`E^[;YJ<_ZPUPH\/^HX:>$:_"B7J*I]J6L^F"WWX9%KSTY0_..#9,]BF" -M@@9A*2<)B2D%R#OU2YA!"/0&PK$-;.;GMHH.7T,&+9#8EXR)-T\"Y:JAS'K'8WFUQ___W$-=UP%;? -ML)UZ+T$_DZ]PQO6O9F0-@&(^`-`,"X34PX,7\P42PDS`,"D(*.:-EL[>F8;) -M0*&QV&OE[#8SC#1XV%Q@PZRGV$S"O5.2&NX\>A&]V$(S[YN.:(@.'*;3%JD, -M"QX$WU1;/Q,VC`O7PH'[4."UT.!E"/!ZQ.#JO`Z4O.O(=C/T[A#3"3$*!K-/ -M'!GO_O=:GTYN'L>ZG.T0L;>("W`P-H".3>XI0H(G?@4M,:-_'U\?8#PD>#$) -M*)",RP?DZ>M(!W>1WFU,M@^N/T(`\^*ASB:;VB3%88V4LS'&@X5648$9(8&D -M3G%%5.`P$[!8#*182:@@R6)6=Y@^Y;?61WY68TG%,D@,MMEDR]X[8K.>)3G* -M^*M`T_J^6AZ$7FNMOPG&G6+&H-&126YE$V/"->(#B(BI?E_?JG&^I::(%.P0 -ME3!I!_]L*T@K\7$+#@C_]#9R8F`L!6,W4,FKV7:U>(,C\3X+3<"))S"$(K9! -MN6^*X]#BF[`MNCY%=*""*(LL2Q485"3!-C91'>)<_]BOM9AVU1*OSN?4PX'[ -M_PO=ICXWL4AEJ(=B7\&*8M'P>A6CSH<[+VE%#@S]:3$#,SP[04A,@IDF_&MJ -M!EA#`E`_;:P65$/3##(?%,2O_N/7!B@7`E'_&2$^^2G$ZO>MAB`@4';HK:"^ -MLU_U&"@"5(S%OG,&<:$%Q@`YU1IS!@:$@"`..@[MNQ`$Q*]2Y`DJE`LH@FVH -MYK@\]P$UQI;ZJJ\+X%Q](1!*Z:\;P$6TFO**UKY8!Z`V#P%% -M)"R>0EZ%3@A_T[Q/GG5#ZOE@(/D0EVO\9;6@(#XR -MD/.1@4)4H$KP_78D(IN?GUU -M?<&IJ2VP`J(&HSE6QR&>8!V^" -MH!OU6H`0F@@OU&(-:C6L`ZDCJP*5*P+7@X18XT-TF[H=P`3AES)"D.0F!!() -M^F28GJS#''HYVL[#^H0Y.AR+"I2ZH++?)L\,:=]/&_9Q]4/WI8SU#V63H_5V -MD6JQ#@G$);YU+@*"B)&0_*P_+^#4!%L.1`8JQ[W+.?M%9")'GF?D:=^'!D_W -MR8>[@0@*0ACX,N1^<9,VRH[FO.I2]D7*4&#%/QDA0B_TA;`7D83+B$!`0RH[ -M@,5'^Y%2L+WQ+ZSZ%TC"E!&"?-=*L'0%D=_=PM\/J.BC2,N@&82%/%]3QHK7/*=H-$4(@$.-; -MWH%"+I4QKIQ`0J5?EOLZ,I6TC(=A9=0NT`S;H$Z+&A^)J(@85,:?$\0%;475 -MAP0;9B&.X2?)!GMD`XMM;`&",8T0GFQLN%"IA:=6H(C%Y\JN"."[+L8A1H,V -M$!8(@5(K0GR]B>0A%4L#!_.;U&+S2".8X@@V@T)-RD!3($==BC#P=.&RH,GD -MO(QR27.&.#9):$GI5.O?5*FVU*/TCP[]NR)DEP@9542@8-:LX@.&;5YN:VL' -M0AD0)`0NQX8(1*4F(`8G%B>6/`3^\.V]#90!N3KZFH'S"[2N&]:.`"0QF$M- -M3-[TJGRAV@> -M.&RUE7S<4&AK^[Z+H2U!-O'33XO^I5.D6"`DJ4(4B[F";=Q'TMQ`:RU]*0*E -MH:]:#[!8#@PT+`)4>;Y57??)]H3PV&I;4_,EV#H$WV7R!.`"@80+-4&UB;H- -MU&VA.L"Z#'5%9*`L+$0J;`(7Q7)9$BX7$8'*Q4X4)]6:@.7Z@(RM"RB5UE-_ -M;540M#'"&#GV05)]RV_*.055I*%J=:%BW6`C%BL6E1#T8R3YZ$`-64^GVK4C -M`'OI`G+?)J)]'Q7'%7U]W^`K&JS[05@=7M@G]M$FN=<5ZK",-K@'W#_EX'[A -M^%(.!?KN0*F!E`N,*E@+B:*)0D-#1""#F->2-!^GL7$_MI'4A#P$/`U=`2D- -M?.'YY5"AH%*T:46#.J+C5]DN0W_72R+5<&C1':K8H-PONDAE=\((8J6,`J36 -M8I(&J@VL:_IEQL7Z)<'$<%$LVU@OM%+T^4>%O+:>%T5IZ]V=*L?5*YHTO:<> -M?4#&?B=(60TZ=I4692P['55L1E.,J$B"D81$FB"-)7SQR\7:T98TFWZY[:2( -MS2=AV&[6"0'EG68\-R,**9]VOY&OM):,!&TA"),\C#&;&)O4ENT.$76HD=(A -MTU:/S&?9Q$_Y\]P&+2G_+X-]%'WO$,"E*$.3:OS>2C6V/Q[C?RQ'1Q?I6/F> -MHVP2]J4B#D/-$2ETE]8-:T<`U(Q<(YA[!:"S9K8M,MB`>CCN$^#($IZT"HZ1 -MQ<-^HG/_XMC9F#^O,WU>ZS<6N'X$L&H<6TC&6EB=LK_JS,LA?YN_A%.>N9P" -MKI*R#[0OIY*+Y6.-"6!1;'N"^\B4?:`V/E<=S_+(0^\Y;_;DD/M,O[G.=MGH -MPLHCOYNE>S5?X6:Z>H:+=,;?3.?K:5VO]6O]8:T)8`[,*@"SF@5F^9;G;2@. -M^1!GN=7\:^TRS0QP3%FM^^H=7LQI>94C?CF-&Y?5)D]O]>\=$K@W"."P+T". -M\Z,3/&]919PT)W[VPAZO?#/?KM[V+]9V<=`H>$CQ3QUG,U>'X=X@`$ZSZF7R -MP^LC@\LHU")D_:C,3?G[LLV3XZW[41$4UH<@SA[6F`"6](KKDUWF>4S]2Y7J -M1B<6E@FC&Y,TSFG9E$545>&<-WYG&3L^SDU/B$5:WZMAS''-8[I)<%)NU@EK -M3``GQ1'CZ)-]A&:[Y0E4Z%44]41/GOL;/U[95B9*,V5/#__3&JL;YY@`6.Q7 -M-H,U^5`L\2-:C3`51D`]].]G+N?'>D3UHS67_W4D@!-6]R']]47CQ -M=\0#9['"SYN%HZS<.M%4-WGVP?2APCD\_HZ!X_RV/A'YZ+NL)Q6L(0$4.(:] -M>1%?T*01H5$IF9+=^03Y^!D\YK5'$>.D'\SPR.,-^1W,U.*I;>X:6O`/S@;6 -MF``BEHVCQN5GO_:L8HY<3R/Y]2QXB4@`LWKE+>L9)69O0DZNR,QF%3S2(W#, -MT?`P)Y_E8[J_GL[XF\/L_N.SI4=O<;1^-1T/2*FG8_/>1H77#O$\"X6]GD@Q5AVOS;&:X[SKV7 -M^+.C400O82&R<7J:13T/4\JXQEA#`CC]#V$NZ%%_/,(K;AFNS%/U_/EPU)M8 -MM=7^9-"Y3L]>"V<;:T@`XSC*^E[;GS8[;\+AU'-'XA`+^Z28!2=9:'*10^YE -M?J9D[<`]CWY(:3>3B7^9](>EDLJAA9WRU\E5L(R*/QW<`P2P("R,R"=8QP]S -M6C^S."JS:U68!93WWBLQG%<".&[+/MN\W$..YPU;MK+"S?;S6;*_@/*MKZ"M -M7\[O?0*8U,T^KOOG48XQ(S-O=&0SX>"X&5D`9`::.&I"PR'1AHXDBOGMYR<9 -M:)O7Z6C6.YX%P^1)<6\3P*'O5.:X]A2SN>*[C-SQQ+=<='2`TZJ)>Q?W``$< -M]W7/Z`Y[;!P6CFLA=S[67^?'`H8)9HW#M:CG+A+KW\@?BGN``(Z!E7Q;,X7P -MF8HCA?R,R,?$(HZ82R;U!V:;>'`FBJBSG5Q7GEAO`I@_QO3BGW74.']]B9IC -M%..P7RUJE/*PZV:[?(9"'AMSU,[29O",&H#/!#$M".M-`,=]$XMTR3URJNPI -ME7'!.):[PE(7)CC5('#W#-:;`.!L?T,+N/_Z$,BQ5*13+L#1HJRS7[J66'\" -M6&9(YA/?LF8(G+<)7?)R-T?.YSG6=(3QFQ\JSVGXF<4:T@`ZU;],WH0KGLQ -MU[)PZ]EJ+Q)K2`"+PG'6D3KF-3,];X$?XSQ%.[V`Q,Q/,]=5%7`LXO`B -MGWL//&M&'YFE/'?]0W&<#=Q#!'#,SV'AY#W#T1BU4<4;:%%/O(I<66 -M*Z(RY_GC%>V@:GA&?1:/A97I+K_TC5\F7_X3W^].N\`1$6<5O_S^_\%^Q4__ -MRDIE9'4:@,@7K;)@$1%K!Y&O6/4CD]653=Y'>GW5Y8N(6!N(R(>`_W.5SUR) -M!O#+[_G*2QCYVE46+")B[6#D*W_Y/5_Y^E4^_)7WOJ.YJFD\]QR#-&.8.,?(7?O7]7_W6DTG?;%BN!B#F+P$/=0<#`B+"[ -M.X`;+RZ[3!$1ZX4;+]+KYTC0E!40(]_X:Q]\Y]+[RTLC@%_[T+M>@\B7YT[I -M#5-$!$1I?^+9X#I]!E2OF&(Z[:30?>H:J@X1'W^HW1^`R`5$OOED4G@TED8` -M8N0]8L3N]P8@@HC0VK#N!VZ_2V>E@C)<1$=\-$".(D0\M -M^_%+(8!?__#7"B+O0X1V;U`6;&/3L+N3HB^^P*DS;TPQG8&D+UYGD"G&FE). -MTLS1'V8@\F=^_<-?^\4GE=)&H(86\J)"$$+,(@Q'SRQ0!Z")1&`-_ZUNP/JI3+6 -MTMJTW'FE"R_?6F:Y(B+./EZ^17NOC[468\R(K'3[0W)5Q,@[?^.__?I/6586 -M%CX,^!M_^Z]=!K[&J=+M#Q`CY=^,M;0V++L[&?KB=>31QY95KHB(,P]]\3J# -M%)J;%C$Z(BL`[6Z?*Y>VF\"3P#]81AX6K@&(D;\F1K8ZO8$?SI#*N&&LH;5A -M486=/[T&6_H%&DV#"1I`759$A/U.'T00(]_ZF]_^[J7X -M["R^"V#,^S"&=K=_H$#&6&PCH=FRW+W3AY=O+J-,$1%G'[=>8F\OI=%*0E]? -M#LA+[AR]P1",>0)CWK&,;"R457[K.[_ILX'/&Z89PV'FQ_YK,,9@C*6Y8=G; -MSW#/7\,\]MKE57)$Q!F%>^%Y!BEL&A-&`,P!>0'8[_39WMX$[QGX"XO.QV(U -M`"/OQ0CM3CF..99,V0T`X>[3UR%-.75U+*:85IG2E-UG;XRJ_Q/E1>@/AF2Y -M`R-?^EM_]YO?O!`YK6%A!/!_?]=?+R?^=":H_[X+X`F@N9%@$\/=NRG<,-U]D=R^GN9'XUM]4&L"DM-_I(49$C"Q\;L#""$#$?+6(>:C7'Z*JDPMC -MO!W`6$NS96EWL2%H`19$N'OU!@SZI_Y28HII)6G09_?: -M31I-BS%VJ@&PGE25;F\`1N['R->%5VDT@_'/ -MABZ`0.D&?`C:^UT>>.@*^"'!)Q>1I1-K`&+DB\7(FP:#U$_\F3*<,=+/*?T! -M?$7A3KL'QFQBS+><6'8Y(0'\]@]^\+*(?(TJ]*:,_8\7H.X38!-; -MJD-W7K@-^WNG_I)BBFDI:7^/G9=VL-:0A&_>SP`L/`!G:#Q%Z.QWB_T/_O8/ -M?E!.(K]P4@W`F'=CS&:OVP..9C`)_9Q""S#&VP&,,=S=U]@-B+AW<>,:NUWQ -MQK_"^:?L`G"D$;!(698S\/,#/@UCWG[2;)W(""C&Q_SO[/<.'<*H?@!"*+`Q -MP2$HP=B4_B"G]]33;'[ZGUW5*XF(6!GZ5Z\RR.#RQ<0[PY7>?^"U!&:3(:"] -MUV7#SP_X(/"K)\G7L36`W_FA#W^V&/G/LC0C#4$_C^X"%,)?.05Y`K"^&W!S -M%W;O<.KJ6DPQ+3+MWF'GY7;0>,_\T(A\QA_`NJ3E%04\X-L*$;8+FSK_#B?8Z1J21D*2 -MC,[])XP``#/+$7A;`&(2Q'SKL6688Q+`[_[(WPH3?Z#7[AXY?%&D$98SM?A]U.G$>\_0?@Q1$8)Q7BS:2S&&7C4D,>,(`$'=&9T#.[3Z77GD) -M'CZ1@3,BXG3QRDO\4,>:]8@S=_<[<*DLH)F47H*8!%(9`8PUW.XJ^\,S*WE-$Q#*@ -M+SSCU7_C_5W$V)%Y,1XU(^"<\B0B]/:[_K?&?//O_\1W7I@WCW,1@!CY$C'R -MQF%_@,ORN5664-Q*]2FZ`L$M.&EX)PGGA-VGKH)SG+H:%U-,QTG.L7?U69P* -M-O'3W^O3?ZG9Q6KR-;],J=)K]Q`C5\3(N^>19YBW"V#,DP"]W;IOM^R^![P;\Y#R_G5D#^.@_^Z[+(O(N565P5."/P[H`4OX7SM?"A(48 -MZ<88=CN*>^'IU;VPB(@%PKUPE;U>Y>U:COT7L_]*;:'"<61*1,@&*6E_B(C\ -MN8_^L^_Z@GGR.;,&($:^`=CL[W8]X^]0P/ -M?&X&C<8*7UU$Q`F1INQ>O88BH\-_IC;\)\'Z=T(C8('>;IO6]@9X+>`CL_YN -M=AM`6/&GO]LY5E^E/M&A,G^$OE`Q.]`:&F%VH+&6.SLIW+S&J??G8HIIGG3S -M&CO[#F,M23+N_FM*+7A_Y -M;#'RY[-A2CH84IN_.%\:QX%`(99&LPJ6N-M1\FN?G+4L$1%G`OFU3[+7E\J_ -MI9CY%R;_3&WICRM7X7ZA<=X0(^^=-:^S:0`B3R)"?[=]['[*@4(7GH%":1PI -MAP/#V@&(X<[5YV$XX-19/::89DG#`3O/74>D9M>RA?#7EO\JQ:&2BY/(EHC0 -MV]DO".';_O!GOG[-/_#FL"U`4N^P"U-V"FQ:; -MV+)+<'LW@QO1-3AB37#C&>[N*V(+C79L^`^9J@&<1+;$"'F6,^SV$6/>*,9\ -M^2S9/=((*$;^"O#`8+>#.G?BX;\#]Y?"#YIRS8!&*V$X-(BQ['53TF?_E,;K -M_\RR7UU$Q(F1/?<4[8'0:%F2IC=JBS&UX3_`K_-SX+>+D*W>W7TV+FV#-P;^ -MXE'7'ZTFA`4_^[OS>_X=V@6`2ONI.0098V@VBVZ`9\[;SUZ'?H=35^]BBNFP -MU.]PY]H-K_Z;2OTOEOXJ+YV"D\J7B#!L]\BS'(R\X^/_^S]XW9'B?=@?__AG -M?^"U(O)E+G,,CSGV/YD`QOH]C!H#"\-)$3KI]EX&+SYSZN\WII@.32\^P]VV -MEB[M=0<@:ET`IG4!%D``(D+_[CXB8D3D`QR!(S0`\QXPIK_3KKGM+L8&`%"H -M0;Y>*@W`)EY]*DB@W7,,KO[)&7C#,<4T/0VO_@G=@2#!B-UH)J5MJ^K_PV3Q -MY\3R50X)[K1!!3!/_O'/_L/FH1(^[0__Z=_^H(C(^T2$P<[^0IAI*D:&`ZNE -MP\3:8$&UO'KM)>CL$A%Q)M'9YK87P5^/_$QK^L>-%:0#J'`,_6_=A -M$?G:P[(]W0@H\A>!-Z2=GI_XLV#C7^TYH2Z$\7D!X]V`UUQ_&C[]SR_[549$ -MS(\7GN9.F^##8FFV&B.Q_PX.@S/B!0@L5,;Z=_?8N'(1O#'P9Z9=-Y4`1,S[ -M``KU?UD0_S!O%S4@+M@!FM7T8&,LG?Z0WD<_PN:?_,[2\A(1<5STAX[>$)H; -MMOI^#ZC_>D#HZUBDG&6]`?D@)=EH?>&?_/S_^-F?\5>^XX\F73>Q"_")7_A' -M5T3D7>J48?OXKK^'V@`.J#_4/`)-V8\>P/37OF%`U`W@UL#O?:X7!9ZO_!`^\9&,*$-1OT -M[:`TJKQPJ\?5:[NDPP'9<(C+,IS+<4Y!%>7@!(N((U"\@UAGDR'%QEOO"I=U -MFR0DC09)LT5S8X/FYB:MS6;I_%,:_VIK_P&'U_."Y6RPU^;"(P\AQGS3)W[A -M?_H[;_G+_]W^^#43"4!$G@3H[^XO3?;':]G7D92NP3+F%ERE:EDQ-0911<05 -M@56I=B(.0T&6R^S>W3/P_=010W4AX+Z;:H.MRE9A[FO1?ZLZ/IQE%_XJ5!GL -MM=F\[_(%X)N!_WG\D@,$\*?_QP^_%7A;/AB0#P8K^4!$@F]4,1P8'"F21N+= -M@H,=8)0(K%\=114#J#I4!20V93,A5)-(Z`7&>CL$U;=9"GKHIAY(84*;E$M_ -M!GT:6YN?^"9TD@U+V"C@>F%RDY\49H -MG@-@BV`K@1`B)J#H`M0,U$FC47Z/-DE"PU0;_AM9_JNXR5%=@.7(VV!GE\;6 -M%O@AP>D$(!(F_K3;L(2)/[/4LXYK`*T&UB:X),DS0:OJ57K5R'LQSG'*JN(H#(`$L-UJ0$$J9>Z\$\C@B7*W&!OC\T'[F\"3P(_ -M4)PO">#I7_S1)X`O=6E&VCW.HA\+JNW2(U!0:[%.:6XTR=(L"+IG4F,,N;6X -MI$X`E74[XG`,0A>@N;4-@*;]T\[2F44Y!%@&L/5=TJ21>`)H>DV@N=$,FL#\ -MZC\L=T1FL+O+U@,/@/#^IW_Q1W_PS5_Y-W,8T0#,>P`SV%NQ\:^JY5`)86L, -MHMY(U=IL,NBG%8$:\2\A\Z3@G&_]2R,@1QM"\HP_V]%8W]%Z4>K6LM*AO?RJM56AM-;#(H*\E8@[4)>9*'+H$K -M;0!1[F>#Z?H6O[7M%Y-Q]K1S='91[P)X^Y0MOT%3&@(;WA'(VI$Y`'Z`>\;G -M+%GN!KL[-"]>!#\D6!$`(E\"O"'K=G%9MOR<'%X-)1.*`8/_,EL;+0;]JA_F -M;(XMA-\%+\!2^B,-'`7;]+-$2P*0:`2_Z![Q3\YRL=I3.,:IY*J:$6L2N"8;`9U/]2 -M2P!&S?Y'R]4J9&^XO\?6@P^!F&]YYE=^\KL3D3#QI[V_LDP<61%0KAI4Y*G1 -M$FS#XG)!C8+:8/0KA#\*_CP0ZWM_29+;G1/4M0!J=@%#JQ7_OGH%)-!53UI<.*_[6;#48]K.:RV_= -MZ!<)8!Z(]7,`;!($/YEOG=CSB5%[0+%-&C:T_M5EHL>89KDB^1ON[="Z=`7@ -M@\D;OO3)E878T9_[]KFDM*CD8J)0L]4@'?H)0)5R%8?\CH-B$I!)O)%531P& -MF`GEN'ZUZQ?_E+%+YO\N/_>#_VCE3?`:T'XUAZK9M'0+S:#V]]/77-8/!;D: -MXXG`F=F7B8RH0:#12LJNP;KYH*P!`5`.CQ@K)`U#GDVKX36J^=-&.=0:-($5 -MNWZO'R;7CP@T$EN?-,`Z?8?K00`U7+JR>=I9N#?PM-](!!`1<8X1"2`BXAPC$D!$Q#E& -M)("(B'.,2``1$><8D0`B(LXQ(@%$1)QC1`*(B#C'B`00$7&.$0D@(N(<(Q)` -M1,0Y1B2`B(ASC$@`$1'G&)$`(B+.,2(!1$2<8T0"B(@XQX@$$!%QCA$)("+B -M'",20$3$.48D@(B((!!`1<8X1 -M"2`BXAPC$D!$Q#E&)("(B'.,4R(`!:5*]?.C)VKG(Y:#:74><3Q,^W[UX*%. -MNWYU2%;[.)U^K`HR]C?%GU/AM"OJ7H-JJ$\M3YQVENXA:*C/L3H=J6,]\)/3 -MP(H)@%K%E%]>)?SC?ROD7N9_3,01T%K]CVPC3HSB.]:Q5/^;/V`J6:P(JR6` -M>JM3KQBI;>L$4&H`IU(W]S1TY(,D:@`+A8XU9F."/D(,IYO3U7RNI@'4]T=E0$^)@$]!`R@JQ?BMB!=\ -M%5]!@!=^AV_^"_T_]@,6B9(`H@:P8(RI^EI\[Z[:9_SXO'0!1H1?QYAQ7,"% -M2`#+0T4`8]N($^(P`G"C&H'6_WX>".!`H:42?"!+[9JH!"P4F@6!+P0_:@"+@=9V -M#AC_"N'/)V@!YT(#&&_]F=#ZRVCK#X!$`E@P7)[YG:@!+!9U[[X#(P%U+2`_ -MJ`6<`DZ!`/+1D3Y'$/PZ`801`*D9`2,!+!0N"P10"+[+3CM+]P;&-0#&[5[C -M).!3-2R[6IP"`=3Z_0>$/PP+BJ%J]>,HP#+@TC$"R*,&L!C4/5R+K9M"`OFH -M/>`4L'H"*(4_N/^6@F]JPN\J]3^.`"P%>:D!%-OTM+-T;T$/ZP9H31L.=H%3 -MZH*ME@")OJM:_KOI+;/V7!9<&@2\U@-@%6!PF^`(MDX!:Q>`T#Q_8!BJ&]&U3]RP4*1IW$48"G0"0?3N@(C9'`> -M-(#2[73,T6>2X(^,`$0L&@>&`:,-8`FHC03`X41P/C2`HI!!X%6JB#\C7G]U -M]]](`LM`20`ZYA$8L2",1;LJSI7"/WY\+@A`:U.`&=4`%,J6O]B/6!JB(]"J -M4`^]-DD3\,=Z/@A@RAQ_+;H`3!;^R`4+AXY/!HIS`18'G7*B)($)T9BM#M])902LC@,>;5JI(*#7!K_?UR^,ZXFS`9:"<#5CT/4^I#WKO8E+0SPE> -M@E#:`E1)'F^:W")Z;9BOY*M?2=OZF9M6.CD&($S$)N!;5@K(BQ@DG`6$,1)VSI6`D!/-B`U`D.7*XXIPQS!*=D#NTY,%H- -M`TQU_XDL$+$.T.GGRPDP!E5!F#Z\1#`XY4GM6LG09"Y*6#2*YR72HY#/=.>RYSW6M2S -M5W7?6^ZDUZXZ: -M.Q`''`,B(NYIU,8#42V7QO*-HEFA&*SL25_W2#7'K_;L*/@1YQDC1%`_]Z]O -MK:93NU+!^_I'#CPO"GY$1*VKL"K!+W!J`CB!#"(BSB56+?01$1$1$1$1$1$1 -M$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1 -M$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$1$:>(_Q]#*AH3%39B$0````!) -M14Y$KD)@@@````````````$`!P`0$````0`(`&@%```!`"`@```!``@`J`@` -M``(`,#````$`"`"H#@```P`0$````0`@`&@$```$`"`@```!`"``J!````4` -M,#````$`(`"H)0``!@```````0`@`'$]```'`,`(RI``````"P`;`"\`6P'@ -M``````!7`&D`;@!2`$$`4@`@`',`90!L`&8`+0!E`'@`=`!R`&$`8P!T`&D` -M;@!G`"``80!R`&,`:`!I`'8`90````@`30!3`"``4P!H`&4`;`!L`"``1`!L -M`&<`(``R````#@@`4``````&``D`/0"Z`&P`__^"``````````"``E`````` -M2P"2``@!"`!E`/__@@`F`$0`90!S`'0`:0!N`&$`=`!I`&\`;@`@`&8`;P!L -M`&0`90!R``````!"`"%0`````$L`G`#$`!@`9@#__X4````````````!4``` -M```6`9L`/``.`&<`__^``$(`<@!O`"8`=P!S`&4`+@`N`"X`````````1`BA -M4`````!+``D`"`&#`&@`4@!I`&,`:`!%`&0`:0!T`#(`,`!7```````````` -M$```0`````!+`*4`"@$!`&D`__^"`````````````E``````2P"L`,0`"`!K -M`/__@@!)`&X`0!O`'4`(`!L`&D`:P!E`"``=`!O`"``<@!E`'``;`!A`&,`90`@ -M`'0`:`!E`"``90!X`&D``%T``````%(`90!N`&$`;0!E -M````"`!-`%,`(`!3`&@`90!L`&P`(`!$`&P`9P`@`#(```"``(%0``````8` -M,0"1``P`:`#__X$``````````0`!4``````6`$H`,@`.``$`__^``$\`2P`` -M``````````%0`````%,`2@`R``X``@#__X``0P!A`&X`8P!E`&P````````` -M```"4``````&``L`D0`(`&4`__^"`%(`90!N`&$`;0!E`"``9@!I`&P`90`` -M````@`B!4``````&`!8`D0`,`&8`__^!`````````````E``````!@`F`)$` -M"`!G`/__@@!T`&\`````````!P``4``````#``(`F0!#`/____^````````` -M`,`(R)``````!0`F`"X`MP!#``````!%`&X`=`!E`'(`(`!P`&$````````$P`:0!C`&4`;@!S`&4````( -M`$T`4P`@`%,`:`!E`&P`;``@`$0`;`!G`"``,@``````#@@`4``````&``D` -M/0"Z`&8`__^"`````````$0(`5``````2P`)``@!N@!E`/__@0`````````0 -M``!0````````R0!=`0$`_____X(``````````0`!4`````#3`,\`/``.``$` -M__^``$$`8P!C`&4`<`!T`````````````5``````%@'/`#P`#@`"`/__@`!$ -M`&4`8P!L`&D`;@!E````````````P`#(D``````'`#L`2P#"`(L``````$X` -M90!X`'0`(`!V`&\`;`!U`&T`90`@`&D`0`@`&$`9P!A`&D`;@`@`&\`<@`@`'``<@!E`',``!T`'(`80!C`'0` -M:0!O`&X``````````0`!4``````J`'<`,@`.``$`__^``$\`2P`````````` -M``%0`````&8`=P`R``X``@#__X``0P!A`&X`8P!E`&P`````````/#]X;6P@ -M=F5R7!E/2)W -M:6XS,B(O/@T*/&1E&UL;G,](G5R;CIS8VAE;6%S+6UI8W)O -M51O:V5N/2(V-3DU8C8T,30T8V-F,61F(@T*("`@("`@;&%N9W5A9V4](BHB -M+SX-"B`@/"]D97!E;F1E;G1!3X-"CPO9&5P96YD96YC>3X-"CQC -M;VUP871I8FEL:71Y('AM;&YS/2)UV4R,#$Q-#4W+3$U-#8M-#-C-2UA-69E+3`P.&1E964S9#-F,'TB+SX-"B`@ -M("`\(2TM5&AE($E$(&)E;&]W(&EN9&EC871E&UL;G,Z87-M=C,](G5R;CIS8VAE;6%S+6UI8W)O -M3X-"@T*`````````````````!D`4P!E`&P` -M90!C`'0`(`!D`&4``!T`'(`80!C`'0`:0!N`&<`(``E`',`"P!3`&L`:0!P`'``:0!N`&<` -M(``E`',`&0!5`&X`90!X`'``90!C`'0`90!D`"``90!N`&0`(`!O`&8`(`!A -M`'(`8P!H`&D`=@!E`!\`5`!H`&4`(`!F`&D`;`!E`"``(@`E`',`(@`@`&@` -M90!A`&0`90!R`"``:0!S`"``8P!O`'(`<@!U`'``=``7`$,`;P!R`'(`=0!P -M`'0`(`!H`&4`80!D`&4`<@`@`&D``$T`80!I`&X` -M(`!A`'(`8P!H`&D`=@!E`"``:`!E`&$`9`!E`'(`(`!I`',`(`!C`&\`<@!R -M`'4`<`!T`````````"4`5`!H`&4`(`!A`'(`8P!H`&D`=@!E`"``8P!O`&T` -M;0!E`&X`=``@`&@`90!A`&0`90!R`"``:0!S`"``8P!O`'(`<@!U`'``=``> -M`%0`:`!E`"``80!R`&,`:`!I`'8`90`@`&,`;P!M`&T`90!N`'0`(`!I`',` -M(`!C`&\`<@!R`'4`<`!T`````````!$`3@!O`'0`(`!E`&X`;P!U`&<`:``@ -M`&T`90!M`&\`<@!Y`!0`50!N`&L`;@!O`'<`;@`@`&T`90!T`&@`;P!D`"`` -M:0!N`"``)0!S``X`0P!A`&X`;@!O`'0`(`!O`'``90!N`"``)0!S```````` -M```````0`$,`80!N`&X`;P!T`"``8P!R`&4`80!T`&4`(``E`',`%P!#`&$` -M;@!N`&\`=``@`&,`<@!E`&$`=`!E`"``9@!O`&P`9`!E`'(`(``E`',`2`!# -M`&@`90!C`&L`0!P`'0`90!D`"``9@!I`&P`90`@`"4`0`@`&$`;@!D`"``<@!E`'0` -M<@!Y`"``=`!H`&4`(`!I`&X``!T`'(`80!C -M`'0`:0!O`&X`+@`\`"\`;`!I`#X`/`!B`'(`/@`\`&(`<@`^`#8`/`!L`&D` -M/@!5`',`90`@`#P`8@`^`$(`<@!O`'<``!I`',`=``L`"``:0!T`"``=P!I`&P` -M;``@`&(`90```#(`8P!R`&4`80!T`&4`9``@`&$`=0!T`&\`;0!A`'0`:0!C -M`&$`;`!L`'D`(`!B`&4`9@!O`'(`90`@`&4`>`!T`'(`80!C`'0`:0!O`&X` -M+@`\`"\`;`!I`#X`/``O`'4`;``^`````````!8`5`!H`&4`(`!A`'(`8P!H -M`&D`=@!E`"``:0!S`"``8P!O`'(`<@!U`'``=````````````!T`10!X`'0` -M<@!A`&,`=`!I`&X`9P`@`&8`:0!L`&4``!C`&4`90!D`"``)0!D`"``8P!H`&$`<@!A`&,`=`!E -M`'(`0!P`'0` -M:0!O`&X`(`!M`&4`=`!H`&\`9``@`&D`;@`@`"4`0`@`&X`90!E`&0`(`!T`&\`(`!R`'4`;@`@`'0`:`!I -M`',`(`!S`&4`;`!F`"T`90!X`'0`<@!A`&,`=`!I`&X`9P`@`&$`<@!C`&@` -M:0!V`&4`(`!A`',`(`!A`&0`;0!I`&X`:0!S`'0`<@!A`'0`;P!R```````` -M````!0!0`&$`=0!S`&4`"`!#`&\`;@!T`&D`;@!U`&4````````````````` -M```````````0`%,`90!C`'4`<@!I`'0`>0`@`'<`80!R`&X`:0!N`&<`2P!0 -M`&P`90!A`',`90`@`'(`90!M`&\`=@!E`"``)0!S`"``9@!R`&\`;0`@`&8` -M;P!L`&0`90!R`"``)0!S`"X`(`!)`'0`(`!I`',`(`!U`&X`C)[,W$TLS4!-A8Y2SK#.O`Z'CV4-YLWM3=8.)DZ6#M*/',^?SZS:#-I(VF#:C-JHVPS;N-@8W"S>9-\0WW#?[-RXXB3B=.5@\>3RP/-4\ -MW#S\/!$]&STJ/8\]SSX```"````H````$S`M,#@P5#+V,JLS#C5D-0HW4S?% -M-^LW>#G0.@$\]ST`D```9````-\Q4S.V,W@T<37A-0HV*3:M-C0W=#>^-_PW -M#CB-.*\X2#E].=0Y`#H8.DHZ:3J:.K`R#C,S,V$SFC/&,R,T5C1S-$8UBC4+-A(V339^-K0VZC:, -M-YTW'3A3.%\XASB3.&(Z"CLL//T\83WJ/@P_)#\I/R\_-C\\/P```+```#0` -M``#-,6XR'#-:-(\T738%-Z\XZSCY.!LY3#F?.=TZ0#MQ/'H\Y#S_/`X]*#T@ -M/@#````@````>C1@-F@V?C:_.10Z+#HM/5,](#_4/^,_`-```)````"8,*

    :01STH)UC8''Q"QLSJV%YRP -M=8HME&P1:CD4DS^$9F$>R^RFJ,'8W7\"<.ENTM:]H,.C1\':!!PID8"II1RC -M3.+4;HH(.H#I'W`(K6CA5M6CU[TBUVH;F'T*M+"G%BGOR6"U#I)-@TY@GXXS -M37:7=/5Y,J'85Q&QM'$LFZZ8'TNNJ-7.8C/*]1O81X#@# -M>F>U>#W49_JZ!$RN>6G5D0>DN,W_N70?'0T2?^%9":&,XL_302>:'PDU9SF[ -MK:2-43F1J1S5&+9-EQZ'>%;IV]"^K_58]8`[JX/W`]S2B>\!4.']J,5-\'[H -M,>5E)4_;O`5!8M1-P$KG++A%T,GT3/(?->Q;TN?387XJ9O)%2.`1,R=/.@:E -M'?#F'`S`/=R^&'DH/5;AVZ""F*W%FITL7X3SP&`BBUM>`I)X2#E<_Y%8%.\\ -M748!$YVS!K]'K5.)J1UX`A,+=]GJT'*P&Z:MOZ%6CL_0(Q!]0(6$V,Y)_P4S.J7& -M-!.^<9I84!PDL@AB[F%YU>GKHE5_Z5Z:C!;G-!T?_AP$2NB8VC+N3-^+]L7- -M[Y?A.*1*`K^C7-DTK5>Z/"#S38(Y,,2Q_A%1J`22)UPO"WY%_$[N?"8>=HE$Y$N(\]*W_ -M0MQ;Q2(1<^;UJR)YC'[R6JQ5^`>(PKH(/9#AQBFZ>`8)]]JS<89MX3+X9Q[! -MW5DN91\>5-(?]2-H<)ZK.[T5M!(=B]U4LV'6\MI,AS&5SZRLVRSRH6V-?BOO98 -M0$J`U$YY7(M(8/)J']^&VP=5(_93RIK*EZB_X]8H\QZW:OIH/ -M8TT-N$R;FC:];8S1ZR,I/BZE$_'A!#RF"OR4S*>6/(ND!I63A_=V[#:E5E7V -M#SMM"E%-S&,\FO)J#B*5)[)A$<+I5U@3)=.C+PR?;/0P$*S,C16:[XN635`& -M-N0J9"RR&'W6;NQ2^I)]Q^T72%Y[L.KH+\/[4>T1SD:+"W4D"3.J@J;TAV(L -M4$IF.N;9@VLZXNJ8*G.MKD=7"KT?<3BG<34:@$32)^201M_KDI;%Q;KP4CA!L- -MY$T-_M+3LR7(ZEQ":,SK$C&(8+;GT!DY+9/IKYL_(TD1R(+*8V9]^! -M-[W92(1U"TKBO-VM!!])4K8E"4B,.(?"YOA7S2']#[&8BJ4,F?OOHA\3Z"9_ -MO4J5RH[4';B=?J*V5>2GX#S6T@T;\SVLY'&>Y?$8J50'2A>^TR'.L"`T2#@A -M$?1'>,KRJSP:[^S[0G4R)78/+J[5QT(H-DI5N94(62'RPD0AP837V'_(+`M! -M_(4:SG2BS=1C"&A<,'^]Z8C5C(:6UI"B4M/'#*VLVV)-NNREH+=3J&B5DO8& -MC$CH`IY(8OAOG[=/JUU\V[#=G<,5A@,V(D(.\\4'.H[;!`R[92-5-XRN3N#\ -MOD0JY;G@N:*$]O-,9G]>[0]UNXHPE^PP:XT.`?Q5]2>]X$KF,PFVFTGLN43( -M;30/BD<]D\$5E:[1O.P!K2>E:T4ZC95=\?FQ4=DH$O02@L& -M"^1033,<0*@WNNKA.LU@:HR;)1G64/R:'A#]5$?0L_^74J:#2\(O.\0K>`HK -M^D>J1`&1'J<)3$$?RA8P.Q4<&ZB$HR/"@M2_I_8=ZC[KS7 -MYKNS.7.$V0RC)5="J//2-7X`+$1A>G5BGFII0-H8<-WCY?59/V>QLEPO\[RA -MN:<\I).+_$ZN/\;D^):C+80E(+*3\*K[NB1]4:@91F@MFQ -MLZNH?J2N.!7:/_!!E/*1!Z`WHNR#=1\9S'?+'@8L5#U&=P'J[-%K@@106'W, -M:TF!ZJ^NA5LJY>UV_#GXVWX.28.P.HLL5(U3DJ=.+MXI+#0245ED:,3YY<7AQ]= -M!R@^_0UXEZN^(-MB,$I@*_S51QSJ"HKZC+T=8Q^:[$,;Z9V*%,O&?E5D -MJG&NXW/HU27F:L90U1&N2'N[RCX5[(:%9F%_]N_0Y:!/WBVE@?CKK"7E(HY9 -M+21N'$-.32<09T6";S7YB3;J8T:`M!2728&CT(Q8 -MJOFR+R13L,EI%"JB?&:-VJ%P,#OI]DVS4P=5!6LWH;Z$H8Q>64`CG -MC%T(`1R#+"Y,;]76`)RGQ$SP+[.NP.'FV?]6-Z,RE7(I-VO9Y\0L]D^)>^K3 -M@`:&I88@Q67$8=!;S#T&4Q')T\D^+VH>++_J*F5H1U,I33K'J<^'ZX:GAK&1 -M^1)2T7MO]:2X-TZ`QS32@4\Z".%QB/UX`X578A@"T'Z5-^I6D54:24P-TH&C -M^U@FC7&_*%&["S$PQ/_@I7J;X#2YV/CE5U.G:VKJ&U1A;/@AO=0/"]MF,=RY -M)TD,UB[G+EO$Z&A*I'\[35H."G]U(TL]Y%-6?,8#>-M\F$0:L>C$`N\\@T:K -MKZ;^>;77=#RH]C+=O8]5ZH]L:IZEZ5X_I:#'84#'-Y@ -MPVOM@?)$BQ[>'.WZ@Q4-W_WJ([P:``TP0M]J->;V\G2ZQIS'6M8%4BOK^?H( -MU;__0K0TD7I\EK+,$7#O:>W_/=.ROU;X":Z]&9J!DYKY,Z(%?M\*#9I`+_R0 -M-96HI2NI6B8YZKLG@2JYB.BE+L9L2:2A6QF%W1-R@?PZN:%43F=V7O1 -M9N@KYW"/!4U-#R0F<=JGS6B;UI$\W&+BKJ`0&O,_(M->_E,[-VA_Y8SZ:22X -M3#CF_:\1-M=AHHU>+1@1L072$S?.J\Q^4('WB:]C/<11FA=9XL\_E>%` -M5\O%.*P`*]G?<"Z9AN=^/:!X;ZH\APBG7T+/HQEVXAP`=5*UY:"-2LQ7L59# -M-5+7JIZ8U1_=U!I9O:G(@/UQ%Y+)A/WC`-H2O2F-1*"<,8;?\8>U#O2G6:V!=GJ]@HT="\VC@=(.D'9"2ZB41N!E^9ZN8O"N] -M109>X>(CL.%U+MK[S_%6FS\U2UN_FB=06TFX4.J444A"R^LAR-9Q$3C30=*>Y_>V1GDT'A%6 -M1!#:-\GBDPCP"L6^^H,(R]M3!..(,>1%1W9&;N6C(QY(]!^I"D,',[8>XH6L -M=FNXL/^V>&S>1R2`T8%?K'DDJ,?]]D6)SAIK+VSM9]0W8=X];3[TA[!4D?NB -M+N]I02+&5"C35,1*QUDZPL+-#%CG7,`(;%>!I);,^94$NDGPH"R<&R\-E\K' -MDP?KKI:)*C7*9!-T=0.4+"9]X=SRCBUKM(W#M9)A2A35]D9GY8PK(N%ZU<6< -MF6??N'?FK,CG0'R?$(3^+SY?V,B+,T;'(>I-N&BFZY8"]L/O=-=>GLY`96`6 -MM%CW@2Q:L"'N:N@G5>26..@(A>:U*8/0[4\6!$HAT'\D^`0&<#!"]9<6HEDK -MKVO6"B<`-9UZ!3K]@VV*%B.H4-EY>W:H!Z.V^FM!(55$&2PV^;?7.`)N,^!G."Y<([S -MW9#DQ@V0G*C&.3>JN,R-!,W!0+?CX0C.C1$7*7@XIB%^N,=/9SR0#I[.-8"V -MPD:9W8H3@Z^?5%3'"$)/ZN6J,:09;]D8"*E\[0^Y#US:2AZ?4B:GB5`<,)!+ -M@78P!ZHU33-1;-X2.B/\*:VG7WX38P'N%9]&).]9^?/#5M22*\S\M!&&TZJ3?-=A*M%Z`^V3 -M>0IV[*?#?44SH'U'B,NLT#S"?@?VS.>&ZJ>1P,.L#L2.DQM_N4*Y0-G`&][Y -MB1Y6(=#E,.+HRO*39Q+8[]2O.;9VKBPWM\?R@_DP9^@MG2(&RK-QT=-0-Z!O -MR7I?ZIARG4:$B%+V";,O3P5(;_^TDY[]9F:Q -M,]$4=IPSCJY!>[$F*M:PM^VZ1'-51,%4%;_8N97.5OX5KXVP]$HQ0J4.NA2V -MJ>F1ON_.`,=:[%RZUG-&9,=$,OK`*2W+E"[Y(A^##QW[_;8G1*<*EV0)^MJM -M,J>"!TE[1[F&#_)3,P'JQJSQQ7QX*'L8O=5CU\@3$'THA8)SOAVS+/:M$>I( -M$KZL>%%!/*@BQPM2BMA)1T"FX7\]*-#1.D'%#5W1$V0-0.T5?.QJ)G%NR4;7 -MM1U@V,S$F"NTU!8@P'EZ;ED[)"!6";9GJG5JO+M*C(=.D''23`\!!"`8HT-\ -M1\CL`673V]9Q\HZ4SBS.;(0.A_>8?LM(T7)`CQ`Y>\(7-*>D7.),9YDRT87[ -M[LABS,:%8NP)'3T28HUP)_Z"JR]DRIV`ZN(UWX4/"'D0)<=LW&U?]FH.[6A" -MBKAF)EHYR]&[_)M@=918(\2>UZ;CPFFCZ.!]7JP=&9J,3:9H<`OEB&KSI?"2C+E2Y!R[RI$YB(`F>X1 -MJ0&;64F6`W'7&N?H(:$]89+U,H;P??X[!--J_!U@*&.1HG@DD<>:85X72./? -M'N/`0V3,H#^K3OD.C%Q9>GC_`I$*?JLWI+MYN_ -M%*:<^\J\PV^:!!(W&-"MC\B+P6>*UPA:#H(_$)E?%VABBW1V?"H;.2)3B`$` -M8=._!NA5R.T%G_+0-ZE2JNT#KR[3H)(3=C[T;K/ -M>N;4LWX)C:[()`8B\9,KS9P["IL,L*BDN^IV%1$)S,(W;W;%8QZDUC9.!?JT -ME(ECVUT6);0/]4=Q_Z!F8C*'@]68J!-(TE>+V\0XGE)W`RI.*.&IN.6?4%[N -M9MC5,J@,'RK+MP8)(:Q95P0""-]ODS,(/_^KW&^D"'TGZ_4D]=Z,G*P(%,>?ECDC&?VX3(->BV+AR](!)1"_KA2X4,JSC[FQIZ9GGQ'UY,C_SVY -MFP]9NEL@2>+Z$5_$["1#L+>3EBYLI,O<]ECIFVQ^(IAW-9+?,M*(6G1)>E[M -MVZE.V%T>DQ+JB?CNCKL<0'"(*/`),2A-Q-5X!N;M,:7P,7_6XRF -M?Q-&<-'K<96*;SL?W)"9VMJJ%WR,"06L1Q\@F'$\!!0^G)V?N5SWG/Z1I\-5 -MZ.Y'0P5L`(S.4$4!"Z(+<*Y2*"0EE3!71HU5;4&T^0((T42DI$"WCVY#`B>N -MZ0OJ!HO(FK6@+2`0:A:]_E=J'!EUB`(E[.LO0UMQ*K'JN=ZF1+`1O]"RC?;B -M[/U9L*8>]1KWR5=2#0/X<-O1":Q$ITZ>J6%4"WB&WV9055H_,]*N.1^YZ]Z( -MTP!$C.<(5H)\9\[7F40@TYK4]#M99L\3M]'E$ALCG8X_YC?(T8%."R/\J\WC -MJH`-P:3?YG&4%*"4]K3F)QPU[`&E%'4T%/I]-432'"1?E8CZ>(660L5(-X\O -MS4C-VDD)?EO!L%+9HJW.00AE7Z$/Y[/I91H'R'/;B7F*B$99/C^[ZK=(#2X?N2 -M`EC7ZA9\S@JIGI32ZWEC9C`QC3MU('P'\]J_>(`54Z'BT9AS -MI^;4`/X0K1O*)$2^6XMGZ/XAB7DA/8C)$8^K\6 -MYO3R'I[`8'76RT'ZW:XQ$+WE6,XA80O).X?#DF3[4R8_*8(@1K8)[V%5+H^E`"EB(/(M=>3B -ML>X(/-CP9'7[KVBY_RQ!U_8I?'QA/6 -MUNWZ7,]K9:K>QCXMB_UMI&;5EWYFK1R&< -MM44C:1DO6@FA(U-WV/Y>X];Z"=YXA_ -M63^$/'6#Y)":++D_-N07_4?OA\N*%>(KH&;-78VP@\JBN-/6#43NEL&AO7S% -M_WH`Z;\1]LEM<(T&K+J7"ZZXKI4(RG.*0H%\,/ABXEVDQ+ -M8TQ.YB0^Z$ON:7->`==F>3VIV=5-N)=R[R2&6$/H^K@W`5%@<'@N,4+F$KUQ -MY+.7/!G'UHI)AT(&(0IW[<>!V?19O@8*>NOU^L23YQ&CB3Z4`XR"0O"%MR`) -M?&0>]QN<,AIBZE;1B>DP18RRR2QX)7/-WCZNNAQ._[@S0UC_/AZ=BP@'J2:; -M,OYL]Q^4A<2OLU37&$'9P\AR>.:X2.,P`&H@6A+]J)70B<,R&:5;V?$?>!Q_ -M2U`!A.W;"#B8')BP'A#DE%7?41LMT-N\JZ:50C+6*+JE`_("YJHFE?^^F'-> -MRJ":>^+@3"7<>MB?#%J='L9^8YBX?A"^BDK\_,C -MG06\%8#V!/^.7[)I5(G??39U/JD`M/72G\!H'`+XY@>=,S6C[DBIB5SX/TOC -M!)%]9.:-@HNH(]?'4_)TO_*25)-RRR@P+`FZ<91!`Q)?8)7(+!/%V.K3\N!/ -MFY1HW6."*7->,$98>N?$J)7UZ98+8^GNXG)\9,:RHP"5KJ>R8:$02/L3F:M$ -M?JZ/.`_$\MR^$OEN7.M1@^?#S:9WS-'U5:/#&+.7[?V*FT+&S4MOT&G<)KT7 -M^H(KKDW.;$,[CK7?\6=.E/<.'OT@MX+`%J4#!2'J_^3U].IV$1DUA)C2YX'Y -M6@S_%^2K!98O=NT,4CV:'2Z.R>].D.:5)8?NXP=(7ZLB#"!$ONTKR6YX.PBO<\SLK\R9%C`.=FCSVAC-VJ(T5TL7_4($3^FUIC>Q/[. -MEH#%MLMXKO83!(?Q#A2:R&H-'AM'Y00NSPX1E2.Z&BZ=!@Y`HA3$W[-3XHO8 -M=.J#!"=$TEC^!]W6OCT\A*C5[-X+L]PGG49O[ -M&XR=\X\W)WRGOL18Y5R)(*D*SQA#,SA">NNL\JHB6\D=6IFX>V%5-5G5S*6U -M&ZI(9]FZWU^"#^!V>,EAC)3!6BIQ>1[$%@[`1'(<*@?R^H\W:U7C)1K>@H:^ -M3B>VWW,<@JV)#)^-Z&-30,3P)VY$#.&['_@?O -M>?$?+-E?2`QR:VZ15#4[QY#PI`O"KGD'IX5N9>(/D84VI3%7#+-<`$/=D!00 -MJ>W0P=9G[!&MI>P^(!J@8K$PJYO<-Y!YURV^^0:\I)-`/J9C;R%D7;5=_X"2 -M0`^KH]ZWQOELY&8?.\=#3B1G^LPS6.3XF3(M -M_\&\!,LF.8],/^JTR\HY:UT_;0,0DP9\EHV*U4*6$;P&;E>(1*+-&B'=M3W3 -M:)SCTWOH1FW;-5A:(\R*")&Y[6R4T'*_;]:S(`L>-69L2,07$L)GQ#8;0,IR -M)J^R"ZW474!5=FD*J5\MQM,#9XM3CS-0Q[W?=_W=E3."PX@C,\IEUL@:2)&1PRX`P;/Y8VAB`P]DT1(\(T/NC:' -M2^IOIDO@/-\,U\Y!>EO7,Y>=(ESW8VY1MM_APZZ5S22!@`*.TV8D"3^$*8Z] -M5=T/IWS`0CMZ>M,_WL;6D"\"MR.Z/N+`?A2L](MQC& -M:D^(IO(2"]`.#["_[H3N/^K82J6SW'L;./=WR#G8ZGUGB<\I2-],1S#DM^7* -M`4@'$\3#>^`#-R(45(3<5[.%]D,K"LN=QP"J^&QY_:Z3^>>A#KK!'GJ)+R'V -M$;AN9,2'#DB6T)JS&2]KJLY$:JUB40`](0J_]V!XV^@!2USO-U[>=#H-95LQ""_\LK#;5V -M:P8-+^64E(LNNZ*8VZ19;Y,@\R0UXPT\8`?NBX9'W&<98O%!LYR!@IVQ5ZI, -M$3^&]GR_\@D?]:WL13>%>&NO5]B8M?&EN<_7ZXTK -M%I83Z>RW0*RAK,*2)8$KY>G8,1D=\XJ^MS+[U"&"$0&`^!R;"FMY`[6N>M:? -M#J?E&=G%#]35SBDQ"2!_W$O'?!/#TJNJ8PZ25O5=E1-YHW):H,[X,'KUR;(? -MA3!U0T3R>]SVV:#_Q['0FO?>25:%I`!@=_ -MBO<^!KR%PDM5@IV!-`I3)7_9/^D$CIH#/WV9Q?%#IE&#HCWUH,N]W2G6K^'A>5!(#ZN%6/U?]C&BS2E%:)9@ -M.?M5TR.NS%;9F*CL'CJ?;C2WVX77LQFHNCA1\E]1`XK:RY_LP,/DVE;#XL40 -M8--A"ZON(\G"6RX48C;BK0'P3J2J?B0J>=N%H'IQ^2FL;7L?%8ED-@,'"!*@ -M?H?YUW%E&6&:+`@FD1PDNLL)'#7*9)_\W4'M$+YKMA69@-GAC$6Q=%C$O?%P:PM5/B>N -MGEOQ!C@#*+/V-&='CT>.X(=-U(WC:)2YVIEX_P+-(LZ;`*RK[`3^R6J;31#8B!<(P>/#FE7W9*^?!>+DQ1L&&2A'R[K9C50+&:,MOM>5 -M<$DM\`VPV*MU>@OD6H'2^\%B6X##E^YY:$@YL4F?%6<]?Y#_D4%&I -ME)`#_/WS&#BLS^F`)D?1`04*;%20E%!WM4NJ8#/C\W7K91D]9#EHOTE85SU) -M\F^9RWS5C^(UV/.4[>Z(\1-+>F>#9RQZ_JW@)EQ -M!#:2:(UW&M?WU`EU..O?&RY2A(0S1>2.S&0?)F`5;X+A?GO_PR2X1E;1>NPX -M!?7?92I!9>(Z)A\.8+;6-G!_OJK^#L^TQ1Y'C1KDGY -MM7AW#L:PGL'SC.9D:MF,X:)7OK*\BW>L5OZN4P\)A#/E],R^`'O?Q+7B2K>7[F_^L.U/*"/DL4;X_GU3T#IR?LKZZ7.AO<.@3Z*!2?I6-#S=3RRY,3MS -MI)?004Q-Z64[=3=-LPQ`J6.Y/,ZF$9SV4'7^KNLS%5NE$TVEIJQ/K73U_R+1 -M)5J3NC9<9RT>8*9W^KX:7=SAD/;_Q]?7CJCG>(>#EY$:SFCV$#MS?>B6/PKJ -MW!*[..PZ*)!L($,:[$'W/1[R4KMO>_DL,<%0IN(ZA^'3H?__KER*'>GBHADY -M^7J]ZHWQ58M4")0U>!/BF-%%MSSC>P(2(*BA:31!DW,_AY$]##_U([!<.//6INWL(U.1Y9(8(;]W"_<+J9_ -M0!\RQ<^%!->%2+M2J_,IU?"WUSW*[5`;-L%?LE4RL2SD!YJ(V-&)$%),L\%B -M-9F>"^&)@3WA%L5F<2!*]YXDB7DWK7@5=2"PU9"#,$_6A8D01$-B;)G_K:<@ -M"\(S&2VT>S1(YW/>,V5T@G\QPJ*CY`<,^R\.]T>6`P,`(@(Y'KX,K`-BHA``L7OFV.P481D&XB"T7> -MN2`FT%$^H<=UV[`3$LVI)6.,$+&T-O/^\X:\74"0U>.T&M,]E@_]YM*HEG_^ -M",_&8EF?,`F11I'RHRM?>5'D6=Z36`\/21?`=G,1HAH:=9E#W93$15PJ<5<& -M(I@7H&Q0JP2F+O/4D^DD"-YP2>3/:2#=U>4GW,TB-98EW%CR<$`:N2X\A^KD@N`*ZG.AE7[P7G\X[ -MK5]^C_;E$#0FE_\)'%%O^ISI_UM_9Y;K^1\0+SMITE5).P0,+R)U((Y(J]/> -MO:V4[DWHV<>P7W2A%/('7`\,U))N1MLC"@XW"M=Y0`H@>DYLO-Y*E3-9.(1* -M[=2$FS>KF@US#C&8`Z#SO7/;R&RR$VX*:_(Y;PA8*V>?$/>0!44HG2[<489B -M"_^:@\31\F,NP;RD#?&%GRBSN..?`&'\(AX$7_4&-NII4[`F? -M,;34Y*UL&P\5"F94T\$-*09?FFA[?%M3T0JDN7<#Z*U+>A-7_]%0F&8Y8P0, -M-`:K$9_T7<^N,*LO2WCP(P[H.JL_[WX($.,9DWW?U0Z$)"/2'UC(+X.$`):> -M8]:C;MVY(S)D:];D^>CPS^)-6]Q"+]E>0H724KKO(Z*N5C/87OE9-Z;?7L`6 -M5AYL7U05>9N*+1'/1*0F#J>STX&#Z47D5.DX&0ZGG$]XPFH%?\B -M.74:8\+GE5?QK_&"B-4SVW[Q/;],;](.1>ZA%XD+WN8!R2K;CSD<.($Z+9") -MQ1JAB-%YH9_QR4=.5-A`Y`";X^%\,8&Q5 -MPA7!CVWQD."8 -MK)0[IQ-B+HZ*R:8(9XP!EI6U`M]A7UU)U`)C2[Q?E8KU\%_$$H*G/2W8N5L( -M[PY@O^#4N.>UX-3"X2`#2?T$?XM>AF]")N@%G!+S#@'#_?(^8U/L'N=;;K!7 -MKXDU"Y-;ERD,W!S+=[95I'Q>*$[&=8WLKC`.&IW?/A+*G-4'(IDT@,)5:;)_ -MX/(I+_%AVC")[JZ3)OV'\:.``[)Q9/R@;C(I>`\^AZI@G([M:OF5)"WUQJ;- -MAYW:-TWR;6$DX'$#G6+'9WUIF+)CX>N:):1K!J?B4P'7R:TQ1PZS&&"2'2T) -M[$/?&R`!,`1,\\:IR5GESFK19?P;K-"),?Y#[VCCO-L?L.\XF,EV^$Y:IBQG -MX::GE\':1Y.\DY)2@R;HD2,ONRC/Z+*1$?`W=V`\3Q(=\YT.T(I,\*/J/D;+ -M>1Z-X5."N@Q1&,Z.=!R_CNE==H);%S"#F-S3)IY\M6C&\\,0!OG^?IRN:%`] -M;MH_46]I^A51O#"#GZC@JTR8V@`E/7$)%K14QD'+)KK?UQAVC,!47%8]VER- -M@W"7M+G#N`S*I`/3Z/JG@(XR1I=#LI(^*CM.OA_OROZGKG\[_-0_:/3?IDEY -MQ?,E\^5`''2Q-XT0U"9L^WB7!N<3Q$7_$#=?&U`CNC/^J+(JI13Z+I(8P`<@ -M3]+,?=%MSU6QB3\=9A:1"DO4VJ,E0TEKWVVO4V=?WW6_%-CW>WL:,"?(XGQQ -M!=]:'<80TEW$57$15,;-<-EVX)`_1MJR(CTCW/T"3BGZ,VL/DULR51*5`$FM -ME6+Z'F:6KW379$[UR=3`BLM=4&>:%'*P:DVYF,3@]:INO@C*YG2X=>XIFZ72 -M)7DUD-2+`9S1]X%+W80/J;R7\H344)'%.!Y1/(U70T[H@^!II7&$IZNB(90% -M9&%M;FL)!.D]%G0+NH]*)F3L*30&'>"541'QO/!H^4X79W*=E*"].L`L/`M@ -MHZ3^7MRM3FJ%NF:IM<$K.BC35-JA.ZW!+$+H6X@Y[*\SZ@L&_0'1&25@V]W@ -M)K/A"-$D((/TLXQ)5`^>=I3RAW=)0]ZHNYU:E:*ZS7Y'R$(`U^2T=X($=[== -M%_15V=]&?$1RM44.GLT0+CRG#J!A\"6$@16M%XX^8U"S]`8XC,#B!W%C+N^6 -MEM8GK9,E(WLTG7IC"5-361EIQ#>(^B$3.67[\P2M*#8%V,UIA5EIP=J,DR=0 -MG/L51X0S/!)8-M44<&LM#]N,M:-$/-@)-""OF<,_+G0)B.:6`FX=-/$R;,+- -M@/TQWCRHC!V4EV>JO+M:HBD&N]V4G;T5%B%,X4XL(1BRT"?9M#$4ZB/V_-0T -M7RV33569!!H>!BT2()J^G]()#7`CRO@G<`F0O/G0(1F/$=VQ-%$:N4N@* -M;,2;)ZTHA=:J(VN\P0$2;?YN4<[NS>T[LEA94<6_.>ZAS0@E3#V(1U -MIS9ZD3ML>95^(ZYUHGE&DJB,:"QUN.,6@PUEU...W%L7(JV5N9H`<[('ZU+G -M,GMR(5VFH3B1`,PM(;JXGM>DYILO$UH*+19XL;2[()NQT)=M6NUZQ^>)Y\,R -MD?IQZK[1)#J&+\W"Q3E4B/+UJ=EKZ.?*\(\[J*"1[:;U= -M2,K*68M`/29\(3*87;1FC17TYT#(M^"]EGL">3)+@)@6U\AM=MO##H%BS"Z4 -M\*O5EE%D^9;P9I)4=ZKHHB,3O\ULQQ$FX*>-1$`.)#J:@^YB/]&^D11-#"S,Q;U3_ENI"A0,MNFSKID-RT$75'.:H58,DZ14V#PGG%+$N@HE:FI`1 -M_<08R00]@]>@;*?XX;E%E$?CQMN\"Z%;!K,K^KA:^P-:J&::19Y/L;R4A*?_ -MV5'LX+^2'024D>68-2&D=K`X3_"+B,FPPGC!,9>_:>5_8,_T3):"V=89=EU( -MZ8_H?S&;HLE[:[G^T`WB?PU87)K.&SC?&'(=*?#MQSA0&O*GGQTU,#(3*9(\ -MS-:^KV"KB4`_)YM&%;U)@-FH3!6]FX6\FC]7+M`[NTU@X_,_@F[^%^Y(4HL0 -M=!V/?H#Z%#PQ'J5C+WW0?*SA!%A7T#[J&55L-+]*-F1#L%ZY`&WAB@Q]5LH7 -MXEDE?73_*SFC@AE"I6_.CPGSS<;DJAS#J_69P&8Q80/X/@!CR-5"#E!19YU3 -MW6!^%&ZO^$Z%JF:%O'&4V)(T;(E-(2%G.%VFY6P,>?6FSY\Z+ABZ;>P<.DH$X)U\=.O"YV?0?$ -M?PF?V6STGP\KAXM`5*@WZ%^5V9=BJE*&&/^I:P9LY7LG-&A16\)XGN;N"@PW -M=0*^H*50M867P*JO_1?U)]4X(I#PA3<9,MNB=_-5]AB]P;F`4?!T9T3US04% -M:V*7L2)C88#/E/ON"0FYX7G][>/).W2(0P\LVM-?#W\2MBF.>65,P@_U]^KP -M1B!#C\D7';-+E@STR?$*F^)>"4\Y/83$>X+E9(%"I:W&=O9:SG\]X/!@V*KU -M+]*@DS6I5KYU2Z.GV#.KX`4H(%W/J%62=2`43H=3=FA=HHIDS=)$!GTAZXZ> -M[?4"THYKUQ=3)VAIN8?+'W+F%>NKWB6NJT5 -M*=4>UHGYDKN[*P`T77$ULC2M.GUKWK/Y/UC%GKBC.#\#`&QI&R2/3X8)]/LH -M]BUX+9CZN,XD-[X"?T&49=*$_OLW*(S/OF:*BD`H]F0W59?)WF0UAD:F9+@` -M'(8&G;;TV(KSS-L-MQ>L,"FPSJ$9T&0]GUKG''Y4I%%^LE.R=Y=\G:^1:ASO -M/GL4X)GP0]$LCZ,G4!8F=`(*-]5$DL-25YB$FED,OD#US= -MASF/$&9O#J\?AB/@_4?U3"X$#Q?!G/,0+NV@)ALKYMXX,+[6MYCP:JBT[@C, -M(GC2_QY?D=Q!5=_2#U$<'4:WO^.L*]&:(?O:1+T<&2+-;>R2ZL6^1FH?TZ+L -MM$)ZSHQ7>15[X#6JM.3`!9/[A.L]2`3Z]1:15"4,C7!L>BL9#89L]X'VIF>Y -MIESG1O6\XZ\+A/,<'DFMB,M2SV\!`%(H\;)5O8+1T^.-+R+[^(#]QTP,!@(! -M#F?TH!RWW,69.9A)R@C@!RX#7OKM()L=@0VC'*Z4N57;7/?HV4WX/4AN\R9DB3]SV9N!O_7&FYP/D&OO) -M1^SRM7#S/$=B/[=H!:I[J5_HZ8@Z.!J;B`=$("S:LBH&^4M:YR7`_O5PI8D -M_=<$-[R+,PJ3/^T)N^3!2W:TQ^^LOP2"Q2Q/`TZ/^:%@<:*ZXU%$ -M2Z']4NY00`&!T*]$)5RX!J=2SA%SME!L.4BMP5G>#HFZ3MDZAMYU7#;E08*Q -M!PIRSR0-I14Y,G3[EG?V>($1ZT,-420'`*F^9IPI!:M'P!EN]:)TAVX-T(,& -M-ZT&X'U(4EN/M4`0DD:1V01K&?:!/9UO$VP>43E9[H[^O,4@J"4FOV+^!&RV -MD75`S3%RMD$M=3KA?HRB&XRB]/\(8H8$E?Z9+LMN@^ZT6E^.*1T4&2,D)HCC -M7'04)E`"N$QAL5:V"]9[V4T#0(C2PS&D([69@>'$O>+D"8WDX(/V84Z!_T+A -MJ%6X'GY1@=^K16FHGJSAF+R2^T$T59?3@TBIP.\_,,["450^/3%+NCL;DFZF -MC+#=44T03;V\7W7'&Q_C"N^L8P0>+F@5.$E@P!P5:=\=H*4*Q-_:Q*?)ORBV -M>(_R5BO_BS2"&M9*Q*/>!2JEF1NWEN_Z;6Z1X!:EP4&UF!CF53*Z&=9[XR2O -M'PW7LN?TT2+/BN@=G/1)%3>OXCBU`&9 -M,ZT;NK.!'4DKF];$&&I3*HEJ]8DG>N%^G? -MX!"7(0+UD(5$=G("NUDIBVLRL-);CTCK7FKOG5#>*1JHK#^`(;_892\9,H;O -MC.4B2-]9YA7G1DB`;T+\3>8(KX6A*-B1A-N+]$H!XCQ7G*O%1OM^!.B$WSMW -M+S5"(93)GS?^5>J(CQIGDU+"8N,19Y9`)*]C-G8'6FFM/M:EL4L.KI8^3 -M+I`#T,(5^.U(>=-YC7\MU?!>7,*CSO05SVIEQQ1T.5]?XH;.T;Z3.T?OPO#( -MV:"CX02:4NG2O=^<9(*C81.RN$9I!VHCV[*P4S -MD/4@[=5LX]\E(*_?%K/%R"TL'M:2>@G`2\GQ>!'_.P]`?LTJ]&-#Q9\.-7,Q -MEDZ2;!?HHSBV.SQPH\'2D^7H8*"$:#CP_1^2;MYU7N+N29$>)@P/C:G9Q]A] -M!X`S2"B5#WXXXI8E2`]G$V&2'@S_IND;1/]":8A62/YUANX%96\,\@R:FKQ* -M;[!+D_QV$>\,;^0?P[P@.\%`B[&;X>QXU91<4^VTL_ -M\T*U%C',JM3L:OPX&$0JS.O;9PYS-QJ@#$#3ZJK(OVH`@YG16M1@G]'"#U)=;BX82,!L?*I'T[L\1LCLBY^ZFS5>J?QL*_"W,+M1C_A -MN2WAM]S-I<=)K^@#^FF8``$0N%RAOS(\:XF/RB'C([M)%K*S0/[+W`(6?B(T -MBZIL&NFL';M9TUU/C%-J(K&"1IW3A<1M3T40J55/6<+^A9?RP=\19/A$8T,1 -M[S[YH"2+=N*4.M5$8)(0UZ59=[`R>"0L`3_*&3>0R^5WNH"%7(JPPH%&<0S; -MO/-Z$98%_?*5G`'0N8U-`3G]$@10$?L$0W_;=Q8P^XD:)XB2,X&\*>=,AI'1 -M`K-8A7&%9*$U.<,$!S&U0['LI=.M^:"X%9)\A16N0[H>5B.PFB3\2XW&063` -M]/YX/^G]QEC01VQ_0*&8_G)P-9Q7+[SPC,A2N8$O!=UK2LNZ8'!?^`RNB^9* -MZKI.9E0=TOG=U&C2E;2N31U^<1C8T6@4SB`P^+_)C4@0&DIPK@)1H7(6:!)G -MO]3+R5?]RCMGHY06:3U-JAB@I"!!<2FJ1"-5*](3K,=@+77L` -M?-=7UH3;*!4%?1(J8^KE`%YY(!MI#GO:XP4]U=]7!3-T)_0Q^T<'I:JI&.E>`)G5?/5JMB,ZG6@=@`X'ZELT!3+X62E=U/VGI_FI'_4-W -MKNAH7\ZD`KSE=L%>X.'BOZ1*?J2D\A"`[*].I$W+O;#^,*FOFP#A'7!A$!AQ -M,(%?="@M9/]?]E?$`4;OYU:BF`^X=Z^^`M3MJ\CGD,>.Q;8]53"M?DU+"V]7 -MJB"UHCR_8C=;GI'..W*$`UUA-(#>WLCT\D"V]QE7\:S:2K1V[C=&0UVC^PS+ -M4A@4\NO%O0*MT&W!^-^\'DWU)R9(%N(*IE>C"WX9&AM?3(-,VCMA`+LEM\#E -M08#A.`L&V<.Q4+ON4[CWX-W1T@@^92I?@<&DF2*FO5.%U$I4YO8'?BS.RD%HO$%;G-+QENP'B7T">$ -MZE1A'R+)%'`Q9T]?4=2_XM36B>:MB+S&!V7U/S:?7KSWO2>=',(Z8/[%]46) -MZ=.*5F)$_[H?^[-:V;_G\E4HZ$]4%(T(5EZPJT -M>Z*F_L+/12LP1ZDW.%E9^2Q#!8`&N -M5U;E/8D^RDSK*UE6KJ-L\Y9.'#6EYU&&U;\+B*\=L+:BOI.=$?LL%C>I;[7- -M16*GBAKD5PV_0`<)Z+\(,% -M];UA#%`4MW]57!+D[,GMU:Z^%_-2/#+;`!-ZQQS#U[3$YT-5H2.BN*A5KE<6/WIR#I[7D\RC7CM580TZ/? -MH(,/F)RI@AW1QV/;R1:+^QMXJ()?8E%0]8$9,2JR<7 -M1?;PY%[*P(G%>^D`<]IQHUH29ZSDJ).S84`E.#/4LZ@,+>H4F)#R7&B538/Z -MUV4G!78:J9(%4=CS%_FVK?\%`3C8[.E9WH -M6-!;:$)2,TI-L][E,PGFDR#.Q4HOA\%IV$PB[%,]<+M>E,W"X0FON$(,)I9R -M*+65Y3^.7R`^3O_)^$CX[JSFQ((6[F4)$)42X/L>["*COH`XO:_RY,I@BA -M5#160R&3&2\WP9!\)2'_HGB*61"B3X^OGXMHEWX84'Y!D<^`P -M:?`51_2^0G8;WB2\M5:AX:]QF(Y^>%)0+"PLZM\]9.#B0`-:9EYPS4SW4L?* -M3M85-<6&]L3BZO)AF4Y_KIR\3^LG\2.ZXW/)5%Y+.RJF;,6#XN3B!L;5D'8I -MH5N%.'L*V]Z]%M3RY_[`+`ETO=ZEP5)?O*3G3JK%`:W\[O=AJ;:O\(K$TT.B -M+$=+`%RJ?E%H,F#2\4F'4(H/LK#\@``9G?IXT^\/$D%?+[#4%71,=`E< -M`;+P",%]V"+24H3Y1#$M6:!WYH5B-0?+DLB^I+M7R_9R+.I5?X5OG3XF97EZ -M9I#&+6)3R-OJ^/KGT+]X_K5)W=>&L,':7=+ME^GN?RP_D=+".34#\B*T$L`_ -MW(O,-40*EQ"-DV5`(^#N2TW`8&??\EU.:$=^#=6].W>B$MMCGXSE"7G&!PVRHT0L,6#=SGR>L(@P5\`G*:@WLIMA`"$0>"'2R,<%:.PN_ -ME""0TFH?+1LNS11"5H_U&F"H>8V=(;!YZIT@-\@U[T+BG&'_PA32)&G<0&BW=)YQ&^QOZ\>'Y\ZQ0"$,8'>BQ+0. -M9$@TV?IC$_WO&]9XJ(>1+&2Q83J@X-USE.I(27_G06;NYPE:N%` -M*+&DB<7"*H\TVBC&KI+J1.0M[&<*/#[3$Q:')[!*3P0,PMC0//S[ROB -M`6(8/F4SS=O[%$O5ORFC3MBJ6H/JY@4C\:'XABQ03J0F`=7[>06TT[)E/;'? -M[>65[1'CSD[(P\=1DE2>5OPKBZ_V&GY,06RJ?JJJ<%TVBCWCXS!.C*H-6UXD -M.L*X`1N#K7:WP!%VG(@L!:<_!+GC`XY(@Y1H:O)X>W?+]Y4+;Y)FC@Z@,.";M^AS<5XICSL6IHPWPXK>$ -M#G\'S#4KOK`CJMT`%B!8UEWOYD`]V!E][&DS-%#0E$;<9R$2_X0_R%@W3:WI:\%2J_1E-`M0"(%9!$MBK^.76&&T`<:+**>42#>?/ -MQCS(0ZZNG^04B4DUCL9XIE)K^,U2*ZL9J`AV'%FW<"+UXKNF\*ZG8RI;/5YTL21\D`5`#; -M(>A)@\9_'#N;63:*[R*<0((9>K-;C[]&2#Z/:]; -M137G[];P.9[,(@A?@V]B:Y\NU'_"_-,9[!N.(7[YNC+#*O"%(QQ*^U"2N1@! -M>#V69_3,AO5G`DW)O/HCL.8BO]IM''Z]93H19%U%`C+[8XI9P2A@"2HA-;#Z&.2S7ED2!FL<5@:&>O_E7O0-]\$!>0A25$=:.JNZ -M&F"X.Y5Q[^7_A0DT<1HCIJ(D5C(2&9N?I)&XWH+MGM#!0!%*;U//)N!F:Q(L -MG#SS]PK:*$^):^0[C`#+BZZ$O@/F5%@O8)7ULSG)M$UT9W'"QB&*!!F"M]X] -M?K;]ZEZL9`7G5GS9C'%8N00=JUT%=ZT++Q4:@,GIPT`+HGPEYA%.\T:^@2F)%_9(^U -M+KY%5DM%(*XJ"H;>IJ&`'4LW675;`C2<\(,:)B!%#8>0W^`0E0I&^M:IE.BT -MN8@>XO1?YWGFJJ*W!KS',_Z!'C]%CFCXI2TE=2$^3[1%P-)9#7@0I$(0/8@5 -M`AZK7DY5X4(HP$_O(?AV_Q.).'5IHW#-&@72$B*C>YN^ZE8D/OZD4T -M&#Z2^;#H,2_B]"!?;,&7>XLZ!UF]^B$J^=EVUF!$02XDK4>U[0OKM[6K@)"= -M4A]EN2B5>C7MLQ2_,QAJA\3LV@3-=2UD)+IJG:]P*&PE^[-Y5)M!:10Y>N,&L8'4>NVB(:BFU62B\SD$RU4"90XB"$ -M-W?'46-#T/5_WEA-=Z>G5Q.0^%PQ[P"!2#7QG8F_MND$X`FB\@GR"N.5?Z35 -M$[OB\H^O0HGQQ%V7/J%*X15K@!LQ9XX(DCW`$51+`7TF&IMR2FJ4^/#+_H?* -MZH`R2AP)LO250/7I34HLP3I$T)U13U@5 -MN^%!]ATOU;60QI+,UN<:6>?NR3%P>I06L/'JF9=]4!/;C_"^/2GP.AKY:!?6 -M!CIMC1;L&T9N9_;LQYJ*P*7@%?_LL3;'9_Q*D@YL2KC$6],R:+MV?RE[\@)Z -M]3)`I<<&ZX:28I<^PS4;)3,8QZ.ETQ2KN$Z7&9"Y)H5NA9RCTO\6=><':"UO -M%>,X:7W8P9Q'[D@:PQA.=7W\DBT1OFU4AY-"E`$H/S92H95PY]NFEO9.1>,OP4)19O(R -M"/K?I"0K\RP-CO_)V2&Y9I?\4$`H%([$8;.9R&"$0`QGP0`P(K^DM\L)\0*, -M:X^V>Y?Z=C=EY8'F7%5A:+^^1/PHD7DC\:-6+4PW_VT#M^]%T,C8#UP.9N0@ -M*EJZ9Y)J0.BX+[:O#`7B3#NM,\9N6A&&>XEX9KE("[7L+=S5/!^_@PZ!+QQ* -MMBN?LJVL^*?O/SL,M#C+W^LE.P5=4(*R: -M?"Z(A2&JK^YIV7'F07^@BY=Q00CNW_)MP43>NBD\Q1R4W-"!0_\\QL80_R58 -M=4_U=U^Q9U0(J+<7Y%O=DY$P\F-X6H3:JV!W153]P5`T$B.%O!@.4G2"W`+[-\I3J,B5*.]H>(8[+6M1FUT8.9T;6X2UZ32 -M8O\UT`R@PI,6D))&>OOG`$/@W`6<#/070;N3V -M]I]=>DO*0V:@I)]W8-IH`?XD9PU> -MK6?U3K(_D-QTRD7JG)](S-@.O-T<6%J.'+A!*P`:3(R"T"B9%0.:$`&YHF#, -M(])C1L=4^_BU\#D.]^?HI^/95^Z[OITR#RQ8^\,10Q/,<-L32-A&/+2&G?12 -MV5G8F\?()V7(Y^92,PRD\2!.5'/T#"2GK",$%+@"E$%A=U)&7_JL-]8T^C_[ -MA?W]6N2$Y823>7-I,]X&##\PX^>-2C/6PNSQ:CS^PA<83:4CB*S@O$&O+/`M -MV@%*O5Y[.!L5L0<0/,;B-:<(3,'>10BW#]VJ6&C)9)WCI17>=L[_KZJFP(;7 -MHV`!>V*W!07Q2U`-=ZH8_.+IZ_H@)`W3%.'VLSN+BDM1,.",=EQBZ;65'6*@ -MH&#B-',:Y`S53NJHU+EC:8E[&)GATMQS#++)B,7<[XQLZ#"?03!Q^C"0Z@K9 -M]8F.!4DDX9;X"*-PXLOU>MK:K6ER7Z;%F$H<]>1D6;Z*,:2V;3X;51XO7^,5 -MSJB`M[DTC.]I,`96N5L:F+1]/DX1-#7TDL#3?Y>2/2W5A`O+?V;+4B^PXO8) -M%T*VDI('_LFU#\R`S=U'291J\QT`N<:QR2Z.7M^J,^3*2SG>U^V.J@?5`:3P -M;Q<,XBNHC09D+=$<"WJ)&J`-?^202*YMPQK8T6-J3#PZW'X; -MC.=S`4^\EE!L0TC32CNJ+<@X=9D)ZWZC/B]%A[?X\6_IPHQBHB8@4?PHB!3M -ME]<59K+_]$C0U]5!3`U0O^GD5@B@E]^&E"+4D9)FE^!V-_,S2KY/O!B_>OFL -MMQFGTS;O!1K'J$EB#P;F(UY^$"T\8B$-L6?O*XE\G_#J4QVT3BP+T`NLYM78 -M<_JDX0P-$"QP/)Q]?._.E27)-?8D^2`7K(W-QYUR()?G+(N>K4_&*ROZC0<*#GSMU#8).#?+=J2/@4C/[I50A::; -M2=;$E*8KX`[0Q.Z:6KJ2'9CHUI1=7Y(^*_M1%2U*DU_/Z/J)\47>5W3=I$X& -MSC&"X'3)M3DC&5K9AFP,1P``SX\[RI&S3[G'R1/;&NQ'&U(WS8=%K1/- -MD_2!`YN--$:5UPA4R2#OMJ-[_;BSCZ5JET993RXL_@$DUE8O\9V918 -M5X8=48EA9.6$JGIOBMCCN2;UX;"AMECD/.()0SKGG[N_R=+`J.[)8&T@#`$? -MA?G]O=#TMBZP)?R0OO+^]D@&B2Y8\=J]4]\I-+I:J9M%ZDA'R,AZNCH -MF%=LN4WDT1ZVFX""$7]+@_!=*]8D#$0H!!NOLRJ^?+,O+*0NM&P7;/9H96:2 -M''6I>`8@#7$#?40OUQ%*RIG^YKQUF7)YRT*.#42C"Z%_563D^1P1% -MOQ^E2-.NS9!]MT,8YPJDS0'+BGNP7*I]=W1!SRO\6)%A`F$97^7,&B$ -M,>$1G&JZ)@ZBODQUF!QIB6(*%V,BO"D$7EOMYR&VPW-$_MXPLTS_*AK;.(8: -M$'P`'ZWG?[B[7Y5')L6&H[#`?Q'2W$W:A74S#@:`MI"0D;`U`-Y&SDVW74>? -M2=($6"=7P(?(@@]49R`_8!N58>S*&EHLR$B$R?XIP!/ -M!ND>J:EAJ/T.R"5*U@%Y6`H::'_R1<&S,J!3RJS11ZO)7PT+<_3GCPHHQ#R8 -MU5[X.G,HP&1(C+9PL>DDL\8A=B83IML9&&3K:%8F2NQT%P -M);_1&FR.$YHACR&I1*'@)*B4Q4>^RXVS_LJ5\>)&H#[2XK>D!3L#9\-[%A/I -M*>V.;Y?:=UI2SVK^$_7;XR@[$LZ#4$_7"F@=6)<[43*4$PY<6`B#5JO&90QE]9N63+YK2#8E/OR%W*P+`BI%1G#?GW&2EZ%0>A6OFE/P7 -MQ?=;:;:'X`C\H2TPM#S%G_\G8X8,X9K1(VON)V9)@#-UHS1<>EU&`N0S-PB3 -M`H%/DCYV;ZKP=E,JY)'%%_`)'1_['=Y#1\>$P9P4K2^Q6?LIWBTL**&@RN?_ -M_P.MY$AA>D(W"1:U%.&S^TGF?;:SCQ*7+,A[]SH&.$6M2;_4W -M83Q0JQ[#Z:*/_F$EN(7#>K#5"3).5( -MX_,=@E[LP[LAPNPK"]F`JOZ$``QYXR&J4GQDJKQ0"663L= -M3'V2,TW\`]*JQ<%S-:9(1DS7BP8Y2TX%T4`TI.`X -M#R4M&_RLUN1+][&]9GVQ.[?V+LM(0Q.6-2W.F"C4#UXC<#RX_)JA8L:^-946 -M)&84U(X'7D!*5"^`&')*+DW2PN6F$0(+641A&B*8-/%\#3JZ76)&M;X_CP.Q -M[#'-MM+8Q/NYEC139_*[X6.D2WC`M+T#2TX/@3D0D?335;F-S>.TCD5I;E]C.C -M*0A7!970A>5('5<9]YMDMD][638L$==QK_GK,<.$WQT8"AU2O3:H1F"Z#O'0 -MVFU&(S>Z93"*X2VO54J`CY5BU)R*ZOZU@./#S5O%+;*8['&)*'?#*/GL)_*# -M@#^$KG'7GI?:5B`*NHNEG[RL9OB>^V:[(BU\9:?U\:DQXQV)@A;N`*AFK%63 -MH8@G/]MV\LON-%;V^LT.?((.UT/.5INGOU[YO2(8)HF#XS?2>R5%D'`L5I9! -MD/]A77A_SK>;+$WN[Z/)4"M8XZ0DNZ;@]0G=[!KT<;$QK9 -MC-!6CTG^.MW,]`ZO_[=CCGI)FR\*PF/K%:[9<4TR/->RF-MPJ7K90@_A#>:+ -MO6S/K&NY?L]N/1,RZPE6JTP(9NO6:YBGY1HE*%9VEOK_>VU[/W[$]H6J#NO, -MD&-Q'$?;5KQR_1-##F'=3IVI,C+2R@J=H) -M(B^Y^C^P[G#+LY"?L7T)!>SZ<4=9$NF[BW#"V-?=[N8(;6626TXXSM)KS_#? -MM4MZB3<*]RUA@.X_DR"5WKWX=3(]*UV8G"CA+=.1LG&1+3/1!]F(0F-&F?]V -MWN&(/]X\H`,);_=`AFV[S<,?P$N^.\Q/X>(#8;J#$U#N7=.)78A.1EEK1)N! -M]5%T:T_4I-*3-G+,5W!I!OU1:WUW+*FY38"63$X?0/99!K_I14.21F98K!:V -MHN(NP[,V?T4$-*!907X4B76ZX1EV5?H*%0.@JF.(SH*UTN7V5[7[,5F>V!AO -MX87M7<"JOQM64_=>@.-]!_@U].R/U4TYLN1L-,+#P'&4_JLW4RFT-'4JLK1# -M*6G.DJH($@;,I"22"1?A0=JP0Z2ESG(7J;7/PB^H/,WM#RWS'CQIQSY._8TE -MOTF=,R]*\D9=J*!3JVTJ/9("*F^8E+\L6JNL5OJEJ4RW'%/X>[&:A(%&L/_% -M*/-*(_%'#,QW.`8TB#L$^Q:(X$?4,=;86[*#A6AHDS;%9RKK=`R.@)VN9./Y -M3+E02UMY@;7[63C#P2+;BH3#OJ<:WOU`2-PX9?'0VIBOG#]<02WB).< -M6XX6G!MOVNV^[0;[/QSF/\(9OB^QJX5VCUJ^2(4<"1QQW6LJEM5XJ)2/-F25 -M.9.S,>__JSX^\&M$T(>VD:&=@[MMB.3\;?D!S36Q<;H5;EQZJ3[Y?UQF+!RHU. -MYJ*?P*6HY7=VV6"HW3)RJM00O==\OQTND&\O?FI\_2-BI7Y1GB9`#P*5?G_P -M.:R/1/VT>ZI9AA@0K/;I%?%T3GEOPL=.WE,E#NJ`+S0$F;,99I=,\WQO^FIL -M8A)$:MN/AF]%04_T?[BYF!@]YMI?I%MAJ4<'\P,AE7DW75-:F*/0^+AF&N7D=B8_ -ML\629Q9WOW_-B5SMSY3ESTHR9C2&`ZHP;%B1] -MI.)P:P\US?6T!MAV.E3NJ*:=42GRGG;=\4HR&SR*EKPVH[7PW+51%CD=3/^P -M'P!W/SJ+FU1U+.;.':Y_D=*9L3,5X9;B0=)0GML^NC\-N] -MEJT563]Z8"?JOR4P?Q;4\SVLS>8Y6)V!LTV(MVZ;.'"%#8960 -M(K?XV(7XFL_['FQ6&3H'72O\",_QI<>!5%TLFK+=B6:KOZ=GPYL*XR6>X9@G -M\%=1[G1TJ\8 -MI'O(`%WL5S.0-GV$$IVP09\Y&!9$H:773)>;ZBQ>_]CS*SZEJ!76QZ*JBO`=%6CW/'_MJ -M`C2F>EN[GV4WZ:_E9;11:N=ZSS>,;()&W7#HZ(&$)U?.!EB&E4#"CS]%,)JX -M3&H.2Y8\M7[P@_\+R+!5>8(@EYT4XS`<=YE">5%S68+\Y=$J(*[72O22C3SN -M!/.P$V)U[IK),\F/S'5IF=3M+\JJ*!%KA-F*UB3+!9N#&,*&7:`8&G2EI==S0EHWDJB7L4;#(6N;!RR&/UJA_:R) -M)\?L\B^/S`Q)4D&.^'BC[!CD-XYWK@I/QQIBY"=V-"]=];`I@/C(<"+PBB)1 -MR'/.,_CZ`*RQ%)5Z=[0NRIX2`CK@==/#X2X#]_SD(VWFIXNP=TP=HVD.>W63 -M-W]37PL0G1?&D.?#D#J'`N1XJMJEG*?GAVC1:Q"T86H6.QMA.)\PV9@`P\[? -M\8$G#10I5,Z4@"9G6>3+169\+"%:573@_W!B5Q;RQ/]-\T/'W*/P>XD*IGE< -MH%!X_>*AOI#RJCE]S6D-[4^NYL-=,Q,*J\0KS.8)E;5X3Q7"U#9^O3H_B49> -M-((@>.C7A:3];>;/U3-LKD8`]$]@:>=PR+>(1%KFQ9Y,/N[!QI5E"GG>AP/Q3A(Y)6/$BO:-WPF/+9$-#&L-`\_OLSSAM*M(E+.`H],I+C(5AMP:5(X -M-T?6B:6YBU2)M*QF)G",`\L.BX'AGL3_0HO]=XKT8B.<^WWG;F,[\#A#E;6^ -MGV^7E;.R=!:YPKF$Y\+#,A%,0O@HKB4I,Q62P>5P_`H%.O9X6"UMLT>DTX/8 -M,C:"J;:Y>"']2_+R[LWATGKWRPL-U&M/9XI!2:^3_ZH9W^M(KF;'%1QJ>;8( -M$4A5P;>OP/@I32=($=[AMR@Z;`#;@H%VKO[<#.J;W&62$6WY[U[57^D&M3!\ -MTI_=9\:"ZIK_3MWL4K,)=/*95_TZ^A0[W>[>9O!&2$-/*UGME(R9460B.JPY -M*4<6.[(NDK^#_QW\P':(Y=::-ZY?.`FHLI!M)/=RO3,A,=33OO9IB?NE(.1J -MLVE6.Z+_D$M3VJ-5Q&9?`E9 -M3\,"VYJ.'L:/O:S?@TH"(Z47],42K..91SR;OIE^D^J/-$>%Z&=6*D<#)YWX -MP)C3Z&`9R%;=EE89JF/B+LOFI@2_F8TT'?N -M-]DX'AB')5TF/Y%1M7G0OY"\64/,:AZJ]9QN.3'#-[/DU?6U2HCWJ\K,SCB. -M)W:7-)9HP[S?M$U1$FMN29`:^Z&S8-699F]CW))_O6T2(3^9H$L%7(MJ]<8, -M5H_(!]UXTY%@&P`HFA!Z>?`3GO\"$7";YV_^(T*@_8Y=S%AC`\4#O>J$,"%7 -M]!@U.M*U)S=+UE/V$N?DKI0[,NE'WZ#,,'!T0CKI`,$H[6?R+>:&"_`YJ<2M -M5:;A::\;T_,^&IME+G>72"0(Y?5C:L\>MPB!TI^2:@`8Y2+Q0R<5EDRC^TF3 -M5\)L$K98Q$!J)=X`=@^+OML@A0,J].X?5IERNC9J%`.;I@%!';U?>JN!`'': -M9+*]8M>!HYD':TW3W;RD?;,@09I>Q#S'-Y]]))9@R-775BC5&_>+I+9LU7U_ -MY`D_G?H&-8Z%`05O"VRTW:E6]DD',XT/EP3&*/G]$#[_O<@30[U7.UY#>.B= -M*E5UR:!*F[H\5Y*.A[>V:Y'# -M%\)]T=.+):6H6AI-_TK2A*-K;'\[CT+.B^4\(\;^K>58H)F&MDDKK%CGO?ZG -M8E1J@T8B9@2BZ"NZ_-&#.WN'N?_AW(Q")<)P7>;%CUK^ -M"EJ;9?S'"O1+#D)6FDX./*Q2Y-M=FL,6#JE7/M@$N4=M@=2(BU;8_Q1@5WX^ -M+Y3DT95LCEZXR=HWX>PT]TWA;(V7;7-2 -MR=K<'OW3.@F&"UO8P.CP=-*?A4I49QR,+Y)\A:)7*V':>\1%47Y$NX5\(2[T -MV$LBX.\"`%"=?5M`=Z2_5Y3I9B!>JNLO]7G8Y>-&L@5MJ)9H-S:K8&V1T[() -M<&E_]&LX#*$56Q8$!K!$"P>IL/.+",=8@,)?NF@:1!H&7'T41J,XQ98E@BXI$:3GL\"D+H*H!BZ1@T%FV -MLU]%\5+=@2QTZ5/*-!RIZ<8,)3:67\$L'D.&J#[R*A\Q6!B0H@10'&:H42IC -M>?8.D!U3F/;]D\9TV\AW9.`&B(0U8IP/D9*+9?KG?@@SY"@$,3AC -MKQ+(9G$VA4Y>D*#-?19DY51*6LO"+3;G>`_I`NMX?SC4W%U>)?QZSW/K=8'V -M\WHN@=CO$4^2N#TH7VR7@G9R:4/F!PK\XJ!N2#8P>MH)%_:*&`OR]`"&U9/< -M5X*T\7)_&$/GY4XPQ!(#'#,'&5YH6CI9(H[-6L?+,`K*AW -MJ!Y$]'%P,WAP7*D/8?>RO='CEH$M'_MK-H9"[^3O<4X'R%/9* -M&.W'*(@'S3E<"%1D8I5^N)^:I%2MB]^B%'*W.FLOLRM]S3/6Z.+1GU] -M*3D7$ZQS6O2N(QQB,XLK?D\-7\FC]N4S@4#!4;:<'::Y;/P5X<9T^V><9ABYQ.LL -M&D._.AA>$87^4OG5J4D.362Q?LNMZ34^*QGD;ZG_O7D.&L&9RUVG0MV`)0(U -M0[1SE,M62HW5.H6BN_9]3P$:K3#O_&#+\1F\@,6MW3I(*D$RMZ9GA"#WD#'C -MOM9>VB"#KYWZ^/9@87Y"1T4)&1PD3J"IDC=E,A0IQJP1/+"?+L][':902AVP -M4IR`R=G;O_\[!R7'7I=;;IM[5YC),@[:K%Y;0'TEF>LG]9M$>F=ZJ>'% -MO-CO"L7`$]`#D'EO+N<;XI.`PM!HZU;:>NN@*D8!SY"C@J;#"G95,T(9J236 -MWQ5E+;3G'!!G/P:E<='X$!64V2X>L7'D1T5N1:\4Z!V -MP+@NC8K\??%MK0J?=^0;5%VAUC3;@H(2P8[&B/H0.;N5SL&^;%:I%4"GC#K` -MX!7OX(J(-5KARU(%LO>NQ("*CK)^V166@$D\(80762A;K7U3JUBXS\V)]T;0SNWW43RX\BB0GR(0^MT\?HQ=$(Z125>8WAJ$3:2E]^0%: -MRHHL*_(C:L67,)BE@$NW&0^NQ[=`_S1+FO\QQ.$K#YV#@6Y:!U!+V9_G8/NL -M49<$WV*ITB?>^CO#![HC9ULZ$B5O/,]/.P:E@++O>3;N7!X=(I&XS@L.B=+: -MU`.">9B4&_O-6@I)RF[+U7I\#P0)4*&FKDS3)Q2+Q-$/92">D)8P@`0\[V+I'O>UH]:D&V3+-T6W\ZXV?8\7#VTIOX*UE3DG9TBDV9I4,RQ/<:A[MFY.`>, -M=[8NHI7'".TOT6#G$F(40C^(MBOZ!WDP!$U/DXT^IT(S0J1'JL4T%'E;CPFD -MS6FQ72/.@!]VH\5KR: -M9\-U=ZSN.UZ7#43.8CZ_LR*9+R:*3N'7_0QS33J27O$1LQU9GRE0:7FZT^G8[9A -M?<*#".Y7DG6Y/@+<"YY/UH_%K,K\*B;H)0H0G-_NV*>,<*MI2VL1T;+\> -M$CV"#\Z1S=;V$:ELFPC1*D3JI-@]UZ5J9F_&QK99L\_5@,PBHMJS&%FZT^YV -M=RVEL0.#CJ'<&HV/^+8$.I,.Q36;(JY.B-7PMJ&T^12?":$_>A]/EB"@',.J -M#3P9\J"$C_>$Q2G:5^YK@:KM?:&;N&&=D%T`_B@IPGF;79N/SO\NKW0P.->6 -M46V1[OQ:Z2JC)4&-/SQP_8IJK+"PX -M*WP(J2)O*+5(P88LD%8(C+#?/S0"NCOJC^K@'+OZ)%,K9F.1=/FG#2H6G*D' -MK;(6-M2H@`X!+5CPIKU8KV,:LAP.STZ8(L60-0+31Z'>7HIP2A85_=*MWJ`+ -M04U&/U53N87%!/2 -MI74:RR1*^N>)*)C4GRY[!,$E)0\@58Q!&=F4[H4'-'BGX<4!ZZT]I\=;#;\XIN: -M9*@IG@49F-XU\,=9;3W!0OW/PO7%J`7U1?L;2L39@>4.Q?M`(GKL*B.\DW.& -MVD+TLU>(RL+44(?I?DT,T0J,J#OK@R'T;P0*W,QT)%ST`CMD%+84CJNZ*FYV -MA!L3`5'G;N@P9]23]P7(B-_-ON1 -M3LZP3`59I0AY''-8/\E*0(S?NQY_,,\GXB^2./&FQ0-ER7'-_6\#J>PF069YRS -M=[SU1(*R"_UZ^PB"Z%$`INO(B3+W7+'>=_X##F0L`G-DL[&+(@90#(R%05U+ -M2LJ#GP[@A"#>#?LD#[U0C_IG6_@IWY`H[&Y:HQO!@$>^(TUH*5F#@C$JJ>/. -MG.V=-4'@9)-+(!4!W.?_TP,J5A7:JI@VFZ'YHK%K0%@?# -M?M[<1ECNL?5CS`3?8;8V75.!W1TN\X_C\=KC*OZ].091,0ZYS4?^C($614"M$(7;. -M^Q=GNT!38(+_PUC\:%BV0/9$JJKUHK@UO5(*TH=".-DPE[04"^3E]3`3WZ_] -MEQ+$]O\TI>SOA]N)U6LP$`HH@&=X*6,\I1^#+R-GC -M9#`Z@#?=;?4D6B:LBC.\)9H0B.+,!2T0YB<&*S[*L*!#)@IZJ3!5`-+F2TO3 -M@MHH0,(URCDI3RH=W0W*4D\M^FP/EL(N": -M5*30@T@E*X.M/-H(MZB_IQ2CCZD#7FNQ$D?$@IX=40!F?3`L0S0I%$I[:&!U -MZBNI2._K1FN"N>DS#OZ"=DT$@N\#JMCJ1Y^BS1N;\J6\'3#]2)^P?P1S7;4H -M')K$U,3\Y:1)_3M%*)_!7A`,*:C8BSQJGDA92@=%UCG`O`;)*07MT3%.W)9R -M_BV'YU95TK/1P).)0WA^L_L2,]D5]!C$L8E,"UZN9"V7>E2Y$9A'$)LIA>3= -M3KQ=FI8"RG<_JP2J1?LTH*H.>E0&4>NQ&]=@SKT0S:%BM\XQ"5KW4S0&"6^` -MI\]20%I(\4BSI963I@]@P2'SLV2K-=T-><:K.S>0]*X(X#4QSTD62TW%1.D:"!!K74L%T -MDT\U!0.'&$PG0*BJ93.[9QB*6A%?"BT`E$EH4A:M>1>JLN.OA`1$D!GD4X,_ -MSQ4)6O_,Y;\W'TQUQ5C+,)K\O;L#&PLKO+@6KS_(4B5Q<5;MV&,&>,%Z\`

    AA3\-O8:=T2N9J!9)IG\&GW/,1R0R3]RSF]O*P1J2 -M5>`LM^`E.?<1I)_:`M\YIIU,N[M]!9]K#-,RHH<3BS-CCB-X53LO<-LO$1=+ -M7'$8MWO;>S97S&M28,E80,XY-"ZKJ[OGYY3_6E_-D&SM\4_[Q%`S%KXN,19; -MC1GW0,M:YW./[%<-_#,#%A;$!5/8LLF/<=_U0ZOWR!+HU!!')V+&ZULOJ76> -M+P)>Q:@&O$*`CAYYJE"-<)GHTZAF[AYBSE76.(>P?]AHO65<@B5OKWP%YLX:?6+!<[<'ZHU -M;7=1V0W7.EQS%>.@CC^91,NI<#H[X,R18,OVE,V'CIB*_@PGWZ'I1"?BV_H7 -MD"CJ_IJ,&1.1'/):+*(F]/:=$BV?S'*1/,-)I*J:J&9VW>\($/@4,;J!@3#" -M8MZ?D.[+!.1D+<-%U4&X=6Y";C/G3ZM!TP:"8X0[*;Q!A6RHC/(%T7N!#USJ -M@@C(U>78J7Z,GS^.LYFS60)J7S@#]%TAHG152@7>6E5K>*49+U'`7,\+8"-5 -M/5TQ[AM(4I$OAY^_3/GRXH,;4W50O@'G7-P=[_[*YI6IJ\YCD -MIN3;G67@@X[>\`DWQ01L8I#OV!-#6M4@\NZ+/8A.NV3\X!="9^)NKL/@NO<- -M.S>9F,WP1FM^/Y`9X0^"@SZO4N3F;1L7(/HX.K/>7O_'E^F/-;4O!RX>:1[W -MSC5#0V+_#(F&)5PD&8^YUI.BR;+)9"7M,]6.Z9H.UC4JFIQ8%HG>ZA<<8TMB -MU:S9U-4"Y,LH_I]5=&\L'>GO73A[*+,.)R0PPU/VMXDP(9RM$6?VIF\6NTHT -M)$0NO`K?6PUHU2/Q%/7,V8D'IM%(2;""S%#\,QXR_LWD.T.O!8,#&!X4A-\& -M2S[Y\*H0QOSO7<)0*RC'DM@U)#:,-8W8^NANJ6"FR9#))'NG$AZ)T5;$?^;8 -M#EO_-.\R53LJ"'5,0=FTP_,\+D"/W%O78JZBR?'3.J6-]=,&2'0GJX$8':)< -M,3;ZE*+CXH@/K/;P"]Z\6QI]VRIL/<`J.G,J@VA6&0?_LV"-IZ7]E9LH]>^* -MK2B=>_/CZ*LV%#CVX)"-\QD#/2-?G+E,YG0W3Z[+69BF>Q5M.!3J)3AR7]F3GT'+[)2U3Y9&H[<$8GW)*%#^0O93 -M'8&]ZNV:O"KHK8A\MZ`+)V<7`SWNW!&G@$H=UF3SF0U:[77.HD<]"N\!HO$: -MC%KF^]CL"15),+(?J.H&XBL$.=GULG2G#B+.0H50"KGYW%4%G+`T+=A5?5T7\'./?K)O:>Y;"O!8E!U-GC`0Q5$&K*E(KK,8F% -M?K>$TB[<79R<4K@CE^%:@/?9(RTZ[&Z9\@2GU41J]Q/?D=A.CY<^%%(PW+X- -MNYFACT*_L1A[/6=I^1_D_HZ['M!1&D^%:5;9(E`O*Y`M4Q))6WJ -M&+";3XW1"LNSM-Q(L\^2$N5,NRH"R:Z)9?D!G!A+0^U,[#K!8=*9WTST<7SX -M<`^KOJ#K]#K -M%`\;;925KT'..N/*[XV7?>!.*_P)H\3=#`#Q#T9XQC="9RQZBA -ML+?VUCY_WSK&EC]H4D3=2][.OSN9/##*"LR/[+:J$V/WG'"<^4RMB28EH1H6 -M>Q>`)9^8_^F%5X%ZBC^(TOY2BGACP!^O\!1'>GLM[?($6,)T(]BC5?@6<:\@'OQ]-9<=,(8V8QXT5E@BV:LMTN]W5\-2::> -M1FW*074>UEZJISX>AV*SW.&HUO9F10FG_;4W&#M;=Q89<_D2:.D^X"'N30,1 -M)5+_Z19S=H;:4CRK,4`&^"KX<(CX[6`&;3Y,#;%00@;R@C,0OT*&W6<[F-)M -M;4P[F)]I!YC4A@9"+)4>H>`[ -M";60ICQ-J3$EBS@"5;U!WA/:P3V.92-5VA@3=])RL&]]>2F*T@(K?"`'_K`6 -MO5B+V3%0.4PU6\""B4K8=<>0E_2YR<%"WD)\G31>RE`0`X@;L/Z]%TQ(*AA$ -M0.@E<7Q8M/=II!JPQR*"[D,OJC"W;T9:BK0_=6]M30]6CB;V"9Z)2[(KU6J& -MT`6'L&;N)EI4RC9+S4YUE@R'IE/>"N;"C.XTUX8RR+/6OA69<#S!LM!R+Y(- -M_(FE*,B#>DS'(*.77/>P>GF_TC8(V2JX13)0,N`9[GQ]B[N8KM")UZ96,$4< -MJ[,"K;*7*+6ZLO@?/\BF?@G7OC*[W15PE!96K/31 -MAE*!G.4[8--0F`Z<2)H)A&5J4+#5]-YJ%ZAW*#)K6>B+,>`5P^@_8&T\F"?U -M^>U98:4]7XA_R/[=PNU0QBP-B8WC>L3&5=(/KJ\F0=&:,CS/=H!VY('BD7!?5(;53/3Q6/. -M:,RLN#\J7D:\\BQB<+]W;4B@7G__)YT3ERMD$.^;V4<0&S.'::RCR>N,I%-7 -MCYNWJYUG(K$^V/@VUU\>+?C'2W*H$Q(471&\JL&.`V$I?=#F*D++DGEL= -MFG2@OYU,JG-)5<1ND;D8`&'/C9I\*1@QIWL))U*N -M2H.7RI=GUJ&Z\(,J5G7=7U?V!6NB,%G>C\:]C4AB;2-OA:+QDU6:@!47#D?X -M0R%DZ53BL-SZ2!0=8D'W$<%(`73I!8T+8\P5(QA>C@HOM` -M=[99!KQNY5+T`FNJ;T-*U83MU/E$3)*Q>\Z8=B`@]AAZ/V]=X]^WH:GYL<8@ -M(DSU,A;DCL83H@5]%T'UESO=.:@N!-29K?@BPNS61#"/EEY?PC(92LZG^U@. -MG09U8RPAZG0WA^;-4DSG&=*9X9E1@JWSS#=YM -M`&I:U7&J](CETVD'MA)I;)D<";1!B.-[#<=7-='0=L6("NP*,)LF@O9%`L\1 -MBB@+7^3CQ^'D4/:60A_;.B"ABF(;2Q@G'\>$`5(#8)0-3EO^V\SB*J$8MT.I -M^\V0:ZJ`LK7)/9"\^&28HYXH`C[F:&246OE8M>%_YH[[0\8FEI6(S%)I^^') -M!-*>L`./.X*4CP0J:N*"XDK,HM?R=YA2=(LJ.P3O:M)8MZC`0G0;[,2=>(]] -M@RH;"[9@XU5P)'P@M><-5$J_BD\8(19NAXW2X)*@JKQ+9KZ%'K@[+ -MKC.\TA:)A$_VQ!,U5D5O>@1Q01O8L[TQ4V#8<`VFEX5_]#J6)1:#'F7>0L?R -MP8R0N9./F_RZA[W8:IQJ(M`AB=WBRK[ZGU$I*E$`!9'%Y\KG6,?HX#O1HX\. -M&>=UGW2:!AR#H5"]]0\Q?)-;F+,$-A'7+\>_4!_;M#O5-,I>7$/$8390@P0U -MI>WRY62$ZCL?S%!1%;;`T&(I,@XJOG&$:Y8=J^05(<8B@8UP39VUA\OY2C/1 -M/!0`F>2T"CIIVWWGF_Y3Q)--;+(:B/O4SDJ6N1'DY7^S -ML-4:3'7+2&O<"25IG&-KV9%F9(QNQ*Y#!.K":Z=@C^+:H=&8SS00PRRI+%&6,I)8I_U`FG"L'`" -MPM]0G.JI&7\`-G<.XF0:&;TGHEB'=_&#*0I7O^'MY(H`QW[(78_\GL)['M63 -M*8/D9\SCDONR3)S>.'/C[`Y/;8ZH1-S\-?2"(7AO.(L\4RL\_\]FB#RD"I/T+,)@%3K9$/#G1W?7%PI`K?-.U!>P#)MR'U=1>7['$R1`V$ -M>FNO&#.BU9LQFJ4])3Q?^M2MY//9<$2/;FN(?>5SSN%H><-VN%.E7JPU1:Z? -M>O77P8MWE!A43G)3UQYX.8T*2;VHPYG&8/[8->1_P0&2MQASBE(^(1.(+7>4 -M_R@R66).00HN:(LT^(\5^!_/!17,,NA0XQ%M]02(&[D'V;I8QG6>FHCY)GB5 -MGI+TB4$4?XP\"<(VG(@L*1$[7)<-[-."\@=D?+-DNLVHBYI^(]\C6TE;3<4& -M4JA;"6\SA+6HF>$D,T\M55;_ZJT#ZR8WF3GOAH(6=T/ZK7N.?(%C!3BA#9-% -MSMENQB;:\_T=),MWZ`2U&3A;R"HIQ#5DSMBL%87O:14V'$O"^ZBLQ%*0\&X. -MF^8Z4,3L.R<(@\V3':4RO.Q\\KM/`F%O9*G07.,-?,8@[V&#H4,-_3,<'O$E -MU^,O$SJ;U(U\@[(+D,-T+JPC&!V#/[JIBY7S172T>D5[5ZVLYKU/7K/@&A## -MS>A&4DM>[!^![C+/*D]1W](*QV51&80Z*Q+4"^94?J&PH!?*1@B%21W^7FF< -M)ZB=QP/)**KK5Q4HVI[_YCVWB(ODB4+]^L -M-]W(7U*\O26N7->$*].# -M?&T()YD(G#9D=R_8-4C=@#HFBO16BV+T**)&Q1>9=H0)+GPNMX\+YDD8&`4? -M5S[>"0T\57BBDYN<0+?<45M1V(T]/V-*APL9[E_ZX1$E6;!^H8+-<''?YA%R -M=5-<+2?)@N%#@R96D2,7-UZI6-"X@T>#17EF$*B)XL%KE:%A"BBRT;*TP3PC -M.YTR',T]9VP[8S$#Q?+-J]M+5\^0=C<[*/N`I1'T:V8;1 -M#3B)63;3S5!#3%U6$55B/:WR^T!6=87P:'"#*IG-90)0@ -MB[_3@8`>_"?`D=R.<(\S&-)<<`RUWW$*2?L4/AT$KE'KI"7`!\6B?$L".50J -M)GWDJ'9AOX5K>=I=JIMC5M7\VIY)3G3^&;;F_T5DJ!3G?^?K.!YQ5D:^IN95 -M/UP;&BH!A3?&EF8*$+D8&D@HFE@I73D)HO$=)3Q;![[;?AV1**Y'^W8/H@R& -M^L1U/7$I7(7)4?_YQX8G&,0.X5J6>C)TA!-E/YNU[(-%C2`?W)?+]+VXQHQ% -M!^L:E0X"*V3RG*01>C=OG6Y;ED?G?(KQB2TNFC,NN+ZS?!VHOMX05],F30$X -M,NIK&\U73+V@X'[]00C57*6X+M9H4!A_$^3:>]"M*2V=6%9H[>M[21,`N&@( -ML";DS4790T:E2:Z@;H<;R80[4R;Z8:4#(VJ3KH$VC%U0,DSLMU=GC%&5;1FL63[TK'-1;4V^P;)?(X -M0P28/(;/>SX?:C.+:/9V5?[-Y(5^XW.E_D2%'[#+#-H* -M0!>Z2*!B6;HC_1<\PG4BS9-L'U/PGF:=3G_'%5<)^=I"KHY/S+\1O7*`R[RU\L4R>4GQIN%3H5>S<8QG[F+%=HI>5W_GO]A"=,D%Q] -M$RD<02:^CY?(_I95QTO>@%]T1AR!GHS>AVP7<^'X+]R!Z?)MQ -M5OY1=EGN2V480Y(020>].68SFL]?1^O+?+:]4.L^@"GC1>Q(\9$B3$RK*S9` -MK#%R%A(#G?%PA*O#O))`1$/M#52?T0=#JBDF&C,N0=`%][A\T&_@S"W/LX3+ -M7&:.[T632'J9:VI#*9KB=QLO#UEZH82^?U?"8]A\/V22#S37A-6NB[Y/8W]% -M#M0N,+DDBE.-@YF>G(7NB3`.")@%%Z2MA_BAJ7ZU=1+1IU$P(#=4HM6--G_Y -MPE;E?%;WK%K19[8CA[,WU%65#=12_NF%SDNQ6.YQ;J'N,58#YZ?!I.<`=&AD -MEA -MEL:,2VY&-R@!=?&67.2_:0DAFX?.\6+)(>"N!2Q%JM/?(LMW3%,X9?'B9#^_VCL -M^PRA4ER=].ONU]S*,W$SP2FM^0TGR`;_+!&6.GB76HB_'.Q8X)GF5)I`-AP0 -M'B-T'H=/C#65@K6.R=SF7/@\6X`?F@B$,G>]S!(B4;`Q+ -MH?$@D+3LVWG_=P*9!.>2'*MTH\G"-RB&@'>2$<7+L0NC`F5,,35 -M6(Z-<6!3*N"[NH,>:&K6<_VGP+M5(P\:&B-[#04"4OB(-NK6,5?,[+6_A@.` -MHV(GAQ_'LY1M20V<54'UQ"Y7<'%`CC@ZLC_L+PP;-[IR=R*W\`9!9`%2EA4% -MY014'?_A`4RSY.J@X"?WN-FN2?:C#Y(#Q_Z?Z!9K?:GE7S)3DG# -M1.,:'I53*A._<<>9*-E/]\>1"^M@_<[FCQS:%?0?PQZ4J160]=B3,TJ<13WL -M2FO7J3*'"+%238EKD^P?W?0H:1;66,A(3&=TZ-]4X;^>(E([(=HY3*`)E#YSIC@WT5X-%\!NG"H[7#X:6%.'C -M=9#N6C%1(U+75L`F1VXD2P`[J7MMZ2<-XE9OB:(>OWKQFE7DYG' -MGIOND.,;MD"IN^1ZQJK9YOPZ,)!9.FJ)(MLR>==$B+US=SHD,"=.W2M5QK5. -M`D->Z9^'$EV$;N^9/O7.^[OQ79';SWSZ^:CF(:D;=;^(VIT+0!. -MM7:%_]^J]E$')%70"=#W;Q'9A -MF&VISR6=JF?0B1-6[?T0B+!ZJZR`Y@%PFE!BS[32EA7"PMF>="?F[V<=L$16 -M0UDHSN#JRP@'`+16;>Z)!0O8L(2/?!G2Q[YUP,.A01)W*DA&EZSE6Y73W5%8 -MQ":=<8@Q5]RF!@8;<2A4^=XP[NHM^7D&TP\M7.E>VE[PUG=[W^&2EZ&WL`V#Y4CH&?\/O^68 -MF\3&\AY+CM>IL$VFGM3^*V!"L6CR&50%1'4U6WJFK-5M5?G$R.E8`3;8&8KF -M:3^'PH6T%4BXO\=+R7\&1;>H_RZ@)4HK<1O]Y;;J1H4&>FB&M%*[_"@]L:N? -M!EB(>T\T-8;FN15*F[EH9I#*4O0$,:TV^94(13HU?)LYXWB8!&2_*S!#KF`G9B -MP^M?4G["!U=*HZ%>7::#>U4&/>M$X[4WBH^ZPN0C-\VYM&3:U-AUIE,LE4BGM.AXLKLK8UYR`0%VI;P -M/V7<(OSV'7D?+/QH//I?')4UTYX"U17-4A&K$4K$I7[\%0=7R4\;87B!^UJK -M+:,T()1=5?XR%UE'0\YB/6ERSO*QQ<&8.,R,EL(;4K+@I*JY="NP:*;GJ1^L -MEW]E41:)=1*SU[AE;9T1W_+/#D_V5M]\TRS:=*V=/.+W!=7E,@O+>FB>KHM* -M+$0[X#SW15I#?@2]"YT^Y;5\%?+4M#K,1X5Z!([N<4^YF1]&C"]._ENAA3T= -MM_'AN16^D<\D[_XGGJ??#V2(D*Q5=9E"0BACMJ\[Q((B9%=)6FE^0 -M+R@R((C.'@A<:\.7'6Y'_,VL%$)2DEA.Y#@?LM*3T3S2H_SXS<4#YJF;4!$U -M/08"U&XFC^+%+Z?\1`>T<`LI>X0AG5FBNX%1EUYR%$3WJ[8[X3*%SUJWE'S1 -M'%WB%#]YW368=4)<;&+#1_VE-&R\'4QH1`2'YB_!MV@3XG:9B63)@4@]=Y-E -M$%7;\'%AI7YZW0IUH6@1]YFWN*\@DZ:B39*EU$\Y7OY;-<"X(1V><<(0(Z;S -M7%BV=^Z_'`Q"-XV?YKJ78N;N9TNF+?89:96=&;'F,.=GZ?4=7[`3CHV_(G=3 -M/+Z=B($^3`UOC:LU,P:,E)@G -MK/(L8Q(,HA('J0E4TOP>Q>6"_L0KPJ*0JF9!CF#?1R9.RQOC7Y%.CAH*Y=1. -M+F]ABI!%ZU7;"@D2AJ2A1*%^>5QCXZ1#ND+X$JSX](CST2.1$AG(UZ6')C%< -M[);?9JD26GX4`=C1GM61*=:M3ZD.)]`T4`%I>VLF=A>^9SH.L:CZ26F??_Z` -M1-5]E!$!%1@:,WQF4KY5Z[A-2+NC3$^N\)I;#.!-[G/*%+Q#`]#S9U&C=KK, -M*L&$SJ:DG0$?Q+?4FF`XU)H$*3SV8YSL\^3DID,`REFJ9GV0#,FJ]P]=ZT7%Z5J?UEQPU.,&8$K_@"79HT'\_N4EXL:PP$OQKJ(F%KB-VL^J0R]> -M,\R[+OW1F^(!:4J"ON&;;TO_)2_`.64@]#Q4+`"9]C\CO[XDB9^:IL1IQ/ZN -M)3CQZTOR<;R'N=8YW3:'KD[G:\;+;1-&/80+G2GW',-?>3SY&W.?.K%(,4T[ -MB'7RF*NC+5)M31Q,75[+'\0=YZIMT.`DV.EIQO.=T0:O*"/O)8/:O?/O7X"S::A*]&XQT/69.7US:?]9;.[WVU#Y)H'JBL7 -M71+!8'DZ&?I%8H4NDBRRZV6];^:NKX^&N>'94TXB*NGMGRYL.\2-QJC24[?K -MQQRCU$^[P"1P"8]KX%\F\?(.ZW8:SDVP*#.]0+:Z@S*]`P>JI!!,C8J^^'=? -M)[FVB6IQL4F3I28$K6FL8C%_<(5A&F-Q1^MLF>GA7HW-K7);0!;XK=2G'VGH -MP!3PGR7=G05V,!C(_G%XHNU/`N:J6`-N.2U`.\HRK3!3LX:!E$MKKW^[7-DG_FQ6?^>='1>_B -M,-A6.M!0:PRL/%4??47XE%TU%Y$2JW'K*N-[#[+^V-G[JMQQL^S%=!)#3(AJ -MA"=/>!QO>9ET['/%LT),OR/I'%IS96_G7&L81&2&BEM]]/_I\EKM>AGCY86E?NL!3HRA(B` -MT=I#P]!X!DL58<:"N6MY\FMZ%*2$(`38;CBAKG0-63XB!.+1P"DWH:$AUTI3WJ&V0QYG&Q:G>Y49"C/`YM5\)UUN\-/4%"LGU+B1]68QDU!O1@? -M'"WR4=ISQC%<@>OO\&YNMV2S,YUO32K3PGOZG>VJ+MF]23$!P:3I_RCB$T:K -M@$VFWAU%'380[,E)6^\,[U(6$/?B3?;>YWA9^`B):&XTP5RH;I^'STDCVW<[ -M@#@7B0M-+1#@2<;^=XF']F/O%2$$[%[@'LO!<]U7LSAW7*W6',&".\ED)/GK -MF)JA+S),/A"ISXD3DIN/CU!Z/((0+/QFZ#-+949(C.RIFXY-#]8+M8")7`8_ -M?+`7<]B%E4C\_++-A##O[;6=/!GZ311(3+:Y?S^S_[_LLN]IJTCP))FE?]![ -M`1>V+0M1$AF@9T1["5B*_1$+L:33<1+E[>2`(=MV)Q$[_V7,#Z'5Q$`;GY@_5?M.I[1O46&_']!/(\VPK/FW7:;<%92 -MF!XH`3/]#P7RM)F(%`IW2UBC4=OY/(>O\]9SCNZ$G/HY\YG4!HGWM;NU@!'& -M?&@UUH**6RI/WF`[.3?\CPZ1/M< -M]#B3#_MOFR/6U_Q6:YTP4RM&@>W<`1KJD%EN[#>(Q&%DW@\20U83.R';Q."QR[^PA"+W+*4WB40"NK=Q*N)U.&;6CEV'$0 -M+64C\R[!F\?UU$!3W;X'USFE;.(:Q=3=.36"OMZM_"9/&=H1!RGA,M-@V]9@ -M'!F+'R[1WEHQX7%[`._7(6CP.AP'P"\[\]R^=A2PPV#"1O!DY?3#0\[EG]IJ -MUKU.8)H'!!H[4Q7=!.:?T\I%J#B&5,2-H5B.+9C9S[J,N5+>3D):[Q>L'4-B -MJSH?"?S#H1:[LF:U).E+H$!ZY3TT*\B:>01?J] -M!M:2?T2=380YE@DC`3I!W(DE4TX+2O7.F^^R?%"%Z&TS(J":/V*TQ/MT.3@W -M/S_]D%5Q:Y'KQ>3&`:MP$(Q>*([10 -M5P=;H^+3-;AOT\\$_%I0N1I\UAFJ^8`NPQ&NL)XC]6YJ70ZR6/`_UHF82:0!.]B;^\O -M->38!'WTO?"XRCEV,/)/5(O.]]XS"%6.$B,;H!')"W -M2]+#9-@E^^LX<1D#F@O)C[.S__T/_#EJO_WC98^-WV$0XVU^'=Y=U,DWYR37 -M$\=.A'3K/8*>X^1$TR^4]/%`/:40<"<#\JH*`5&\7-$B=::B6_G[&?,`)&6> -MR*ZZ/F>_65XO3$T]4J+J[H8\76AG -MBVOSWK4?_QX0,5-*_@^(9@%WNEIR%4#'.)AQ0PR/&/BL>'ZL6+'FHLC?(<$K -M91(^Y8ZVW_YA`-O]\AQ!(0)D.X,"G:"$G*@03,Z=KZ3+^>5$,0P,,TS`VL`- -M['I#9;@+!C?XWF?PPJ4'6""$$E%T5/@%:FN4FHX?B%!V8W%D4)O*T)_6$N,Z -M_X[NPT;G1:%T%QZ\-+;59W^TGH-<212XEL@A(10$7)6@:8N+WB$ZF#0,^7*[ -ML^W4:`4'IPJY-[2.=;Z#2$6@9,)G=63'0A\FXC>B/VDQ^YVPU`0PGC"&X[)W -M]N`8MP/T&P4!SL8]WSU=*_5/\S:<-8\4V,08.%A<2@Z:)HZ!F) -MX5S5"^YNNO6CTOQ>Y`TW1>_X`TO04`IDYD]GYTK\T.Q8B_#5ROD0'GZT\MTY -M>`;"G^G5_1B_6X2*#]>`B'7K, -MI?`7G4I(398$U?T3.AX_R`LB';4`3EZ_#FW_'#`7_21RON9%HS]NU<7.!VJ3 -MC*_V^8A_9I3GL@#L9U@AG007F56@4HPN6=N\AKW!E1;>2OIU2JLU.$].C/HN -MD[YXG;78<>!UD/XSO"4SU>(1[2(',/E2+W$49+>5W@5L*"Z0EG5$B,]K$DVF -MH";5)?#38)4^5+Y$+"B:Q)TF(M\'_Y-AB:QE[NI7:U^.`LC=?H@RA.@$P2\G8M".D2X29Q]>_Q\KHR-&C@467OL;-T;E)P>8_4RT>1WM<\P" -M+$:;$&8U[0_,\_88*]`4_@'D8G+TR)0!X/*`D25LYS473N[6I]Z25NTH;T:. -M7IE[67S#%V_"68(-$_`X73PEA9KDB8@A_2SY=DL*`_(OW0%Y`"WX -MXEP9]T9\Q.F>,J#P4%BS)^TT&1I8_4;=)BQ'0P.>GV"L3C5YB.(17R9.ZE;32B -M2P3L)5\(F'FH)!!D6P/G_0VQ[,>O455OG1-3@J8>!]_G:EW+T.R16/B3"D%X -M,8`+KF!KGA8K*=^LEXDW:'&G@?W<3B -MWO@7K%T24H%$F43;'-[:7DQ)B[$PK[S=)F1/7N/,^[>':'T'D&8UM":)?%)] -M:E#GA58UX8JMYN*%G;'PW1UI,N)TE/`$REF43?@X.,1WP)[LM]L@ -M,7?]0!''O,UQC@0[.+HJ&ZZJ\^X8("5X6`S_!CGB1MY^&9M7^MDDHYHLOP&V -MIR(9_(76OYA)58(JR_5A5%4+A1=&L?)N_D(@3D>NM\]@MA[N]9P_OC*+A(,^ -M<*_^>MD#N<>2R?*921%.@5CR#[/J"N+S9>28>X3N'4/U0_.D#%(UFM`3'9P% -M""E9AOE*@JCHW@_?6AL=.OGVPE1DN+337`K2U_\SNESHN?K9PZP**9\-Y5-/ -M:RI5V.E,XUSU%:3I]1Q0#3`]D?^QGG!(Y'B060I/7.,\KP($_(LQ"5+`>33[$`Q/?0G[-5KYIB[OY/9MYJQ=1FU?:/_D$ -MB84")]EK]S>@V6@FEA$!>DFPHG`PA1"69,E^CHP&:XQ2LMJX;,^$S%O*8H%M -M`32F,LZZ,6411>3MMH`?Q_ZL;U72WX$7A]8G$)_]X:O1*8'Y+)<.65U+1B,4 -MUH(;P(6:DEH-[_U2*;3GW&\P3R'%D_6&[&-F'Y^ERFD<%VZO)UTKO?>?\P,H -M)XE&2Y/:J=PL/W(8ZM\!MWB=$7#W2`J`M=$'!4ZNHT$JH;<_N=D]]APF:W(I -M@1FNSWV4XW-9M7/_U',SWBIY.;C9&VDPJH;'&]B64+H:'8@85Q8YI9S1*53K -M>;'X06P)8N,@CJJG/5]/E2+,Q4@PF2WTZ/7%XST\$DT2'$#KJMDLU4HYF^*+ -MN"M.YHY=A%/*CCF@\NW'@9O2DN22`FJ]`T\C`PQ6&C0-JJ(Y+PWX[CN,...C -MMIRFQ`L44!YN5_Q`MNB;ZG<38T.[%YUAY -MN&@'EH/6EU#/2$---G#2=K3AF=?!-F_VB*I(1\]=O!9L@YE_"_C+&ZQ*9`,\ -MC9F"Y+"D)UU%W4#)]\S2O@N!NO1R-7S'?FF%P$%UA-2V_% -MK_&'AEP1R=.5^!I&%7Q'#Z8M)C#T3K=@!6]-E,WL\UDN^`5DU5AX9K5.PM!)/#K>: -MR#"8)V[T6TU$%<:\5$LN36!C(G708V[,O:#K.&S*XX/4I)&#Y5/V&EBY&X_. -MIX">8+&U:2C"KSHKS9+4NG-M9F*D"^*T#BEZH94Z?*JH>\?#PYOJ3G(SS74= -M6?9\/D)N:"%,H,79*PR!I^SZ]W40RBJB6Q)*YP`,.)U8',B81Z>94TP6T_'& -M/N,.G&.\NF:6O,VY*C6S>?_2,`-/'(#AJ"K+_8:K[MQK(@[@2ZOA0VU#MTY3L+[5.<5T_:)]2P-Z!U\?J[%4`%PM0.V8G(` -M&[LCI.8%&X&A5).-!.DU5/;U0QN"K5'4^C*$8(\PI&*C]&$)"XI5/^&_ER=> -M>Y!L=_#56Q46<0&':E[.A"C\Z=FRW3R%)@!.1T?LS3\8;9.Y>\-?_(--MV"< -M^]GK(%,QAW*%XV-`\RE':%P/$L,O8)V27"-`,CXB"/W8*CI: -M?3-B_C$V]RUM&3@''B<[\<4T`2E(WR1[-$%CX=,(O!X)-!;6`<+;&.!X8FS/ -MAW3+_T5!D/&>[TEF31L/F\^#I1C^7VO -M$AC6_&\_5%7W"OW`A=4%NA>2AB&0QM_@*'GT+FZ`[*C=CJ):J],\LAU\&,&C -MWA%&S7'96H;A_6-:;"..*5D(N)+D4-N3V]ZK9=SQU189U,P/XG5 -M$3RB@CJ?.GY(^<^'1)7PSN@+2G>@AO`H]*3ES%Z``D;P#2;V^0[=6_=F0RKT -M'AN>I.'*C(-)`FM:[8X&0>!_;XGK#;X)6:@]G[:`Y5%FF7,Q]J8QX@'5]TW_ -M/(Q6+TC,:ZZ.-MS*3DB)IROY]E]QUYJ#.2R.=A)M<8""[`XDFI/:$&[+R(H, -MOW\*706NHI)(X9175Y5E&CDGWRY05L7JX"90KH*/)8Q%?B.=:QT_=MIF/ELM -M6\]7.I";#^@'+*RX_OOKD%0QP,&9"RN)&AE,$\>N&\E18[HU;Y2O9QIXA9KW -MHH_6.KXZ@EQ)RN>^[!S7QI!C8$8'K7K&^(J$&P+4_^7D\]F27\\4">!6+YEY -M:E:(NB!(%Y/MT[K(B./]-KS2H*;]6%8IYD>40(.?:H*D[S\),:+V!DD/<0,BA>*[_4^/I`!<[C8<^X.FB3Y=07]!2SFHH:ETP)XT -M-68`.XFC>-@PXY$U55`60E9"N<)%\\N!M$O\N2DNV(9P"A#7SD`9P(M+U:!-TE3A]O?>_J#H!W,7 -M*B7_))6,CRM.202G7MPA@?2+E:[I%B8P9F?JS=W_]F/JF4+%+"ZN;3S^WAUZ -MO6L7",=L5-,6-+TK&3<(M=YM8VVE\I"NU"K!@M<.QZV3/$_%;X+ZN^TLM>\M -M/>ZMH1?&HC>YV<,Q-1T2H2')?LC%RY;E,_G^".ZOS4U2D2L9Y/Q`1?50/AI' -M_C8,!,DI?HRYUUM>3RD$.?O?3"KK6Y/TESMYNBX&>D;F2TR.+(HD)S:SI1I3 -M"$H'/:2"-8S+[9&8KW##JO[)ZX,_%D2GBE?@-HB`H#%J#T6[$W9MEWR1C(5K -M$'!"*>5[(7\1"EX'0J:"QV/\2VY'M!W9KVGA0^XKL:I-MU2\T)/O2UVM-N`+-,C2=%]]'SI:7#N*PPA$5K,--N -MZI@>,(SS*';PJOU2?FD2@_SN -MC>8C!G^1AI*E.BX?UQ$-6\_<=@"YL!&+X8QS"N2ID^I?U`U<#RC328P@/0`$ -MJ/NMH`C\6'JU=93:;DMD'3YZB"55,4&T5IP=:6R@8G?=YI?QO@E`9Q_3Y/NJ -M_*JY^K`W(%+!KQA`I*$&6@X%/DX#$RS]UA5/L@.#O.AE -M2DH3$0VNVK,F@B!`PQJI0$R0F;R=X -M9$N\\HEM6:S+]A#U"GV-`<(X>W%)N>U`T#B+MJ%,6;(ZWFD(]`G_^]/*AH4= -MY/V2-.32&1]X9W:DD>$R8GEJI4I_TSX+J@>+H'UBY]M:Y<]MDL9IT%1>:B_L -M4J6"-,A/DB6[H^8XY$O1:[7SYC7K[\E*U**(_=*:2W*)":&5H(%I2*6X;O"=631GVIW%W -M*&0MP8,$R;\BR1%&H#`^DW=X7,K(#A"0-,.:DW\)Y!);\=F@HO.QN,T'U'K/ -M`Y4:_NR3%(,^D,OH$1!F+ -M9'[09E9(9X-?'F-<'8[;6=4)S8(@)-Z/U](!#$/D9257"FZ^@D]985Z8L3BG -M6BM_['`=&IRBUJ`$(>HP6SHA0,2QRNVVVT\YTF(U*]T-]Y\+&?_6>/857)W: -M[1CUWLR,X4-+EJSL-3'QL?+`C9&9UGL!T$A__8>1N0N=P(LI?W(-ZU[C3XU? -M051?VKD@[0T3Q[8S=[#ZL6H1N%$-B-:P]8JPVH56M6B;YPIRW`ZP29K>C2=' -MZZ-:CXF?V*F\@CIHYC^YS\61$_P`5NY7:U:$-C-1A15_M@HX7-+;E/E!E4N& -MB@KA'GP2'/W\*#).4,`51(G(#ZJ'LASLQ?S4"WK,@_[P,Q^\:R#N&GHJ=:WG -M]'Z\6ZJ<6DYN/M>#H((1U6'+B*G'1SS2=GH/C,0`D%M3QUF%-#ZM/<,ND!4- -MUVU;:TIC]G?R8%$I"!I\M8KN!&_Y5UE#N2@Y@):^*>RF&G3MOGQ9\5RJ$[K9 -MH?SHVA'CR^?A?LWW>-^\6JG$$D"WI[%LPHD?\`` -M+[6/'G,JI(F;:ZJLO(K:)5L5+S65?;*+63K@T+C#S*7/:E-&NM(27G!-Y20V -MB5./_]^!GV<:2<(86V+D4%?E,N/]/G!DV,X(CB3HV\C!*2_B_&1H;_TY[=:\\6U2<$?]?I9KH7H,G,8UBJ' -M^91MN^GD%`(NL;0M#[)44OE0$]37X0`/%%"\J>02R\I;+(>"IUY:H" -M**PO^((T-+Z'?98@IB:WOHN6Z>7-B;MA+5OS/C0&>>I(MR9DG&`B+ -MYPUOP>FN-YQM+AW(%1,`2H'4TY9:YJK$81,MN1\_,VO*6:9?IVJ8$4M/;_?Q:O1(__C'Q>;?UCA9(T%_E!-+ -M]0_NUOW0[8.,E@W;IK7U:O,J=[R3'10%I+Z[#=8,^!L<[FIE9:.LK1!)_F2" -M!?//GO?(SA"&US?]4HX_>PT;7I>HQ[I -MYJ`_[RP$3?6QJZ(%\.;`:M%UOQ70UV^[M]3_S<8B.3[U\K!`O%C.@#<9W -M-HTYB@^250X8KH<\",=(1D;Y[2Y@Y"&F[67'`Y,!*,L.H"^\"JK#;Y&6DB>X -MN7L.T?E8$445%\#GRB$C2Z[`_<$1!R@+#=G,!P0+$M<);0T>;>6H=7%F]8P7 -M<8L&+%?#` -M-$Z"V((3$@@4@F+L]@H'TT='Q';=C5> -MI@(^K3A^@4Y0(\.]AB@B^DEL]YX_'.'&T:6FX#LQ#WY8:5DI`*60!+XD8I%- -MC`8-X^KZ_XU*9\Y;WLVGLFB>7+7$3M(D];1@MS1EY_JAL55EW;75:35H`/`H -M^$M<6IH&PY^"XHLQ`G&2+([4*X@C&/E@BUQE5\LL%9&?2"M$P"H=C2@R! -MH,LQ&P"["UJ$:`1++SX^FJO(S5_P0_*"]$DW=,`AD(//"@P!:GN9,PB5:$)* -MT,5*OA]?;B)D:@:[2,@S=S02L_ZVLEI(P\QF;_:/"?WR`&&@<9SL]^.20URC -M(GL21!],M-Z/$G#OX/'2KTO]!]#$-Z27U*30O9,RS):B!+ -MU#OLN*C2#,/.HW9\FZ*27HV:GW)4T"JPYBR:S+COC$/37U0>\[502\>'L`TZ -M1L6IU,;_'PS.SB;N]!5LS@_8KHXT/?GG^G(?S3OUE>?@V"01K>2XDA'9#':)M:Y -M&`/`=KW\P!K^LT$0!&VF>$C>L,XJTEY5PJ0-`V?VWN\_>ZWH+*F`4%>QL["4 -M4X>YA1K6)_E#1?'1AGZBE+(<;B'C#.46?PYV/A"(PQF22LZ7B,RVXDM*OQ7S -MI3>?VJP`BYP?0Z\G6,\,+&B;GY;F`RZ>M^VBX^MYXOK.09B*V&[!W&P%!*L- -M$5RH;5D&$TKG4:O&XA=FR&=VFU8?U&*JU>#L&A?QQC4*XNW*E$62OKY/*T%E+O:_<%<%WWVW1@#^S9Y@-J8JX#=EX6M=Q+'J+MG$30B4 -MZ+-/3K])T9;`F`N8H3UT)MY8<:!%;`NF?8W4C2#@/01O"OM3@#AW:,)D@YA0 -M6E3UXUWOGD>B6;[]S='^X$)9VEK!_3.'>,S_Y`%Y7O9P+P3ON)/3X[M!0'P2 -ME#M$+3(DBM[(9.:;A`?9#++F;PK9IST`#3/$!>FN@+ZXUM&/Q5/V1*'RY?R; -MHS6O/KJ8O?VU3\U%I"\*B`Q2YL0*AM -M5AFXZC(P%7T:K#JHKUO!J4T]:[R_L]\TS:Q"YF/YN+);B,0.N6B`NQ<3?3JY -M"?<+$'$:+`,J_;K*R(/@"WB_\N,?.%E$@$,@O(7N"TA.T[!N899R*VG^JRSF -M6(5-N\3#=%='^OV] -M#YTDIC_R#JU4O69L4B;=:+GK0"OQ8 -ME$@E<8&P4Q41S-DC\"2\?XBYZZ%@7Z2B$Z^'OC3!TB<&9+Y2,$JAG6;DFK0[ -M$]?0>1[1\!"^;*$UP12A8K2V##V"13Z!HQBC66?*P)AZX>[38]V6$PFJ7]+E -M@(WT1?%ZQ3JYS2&BQ1_T3LNW?V\+2<*.5 -MBEM_Q(,(%0[A5#BJ;$:\<6&,WBG:C.[AD4]5Z9/(NIK*,^754WX]O23TM?@JBUS89K`,9X_NV^[==]?NG_7XMU(U3&'8BXP!!>Q1FZ'VJ-*%!S)RTFM-@2>A8RKXZP@B90%O#S$L1TJ-15^,OH^/ -M8LJJ@!V'@:_;/9F.C&0#2W"^P*!HET%!GB`LG`:<_388U/P#.E0ADU4DQUX& -MH3EX8DWLK=]^$%)&`K`A4I;!R+K($LS39[T@H>DD$PS\U(0S8L'$<#[L%EU. -MQS@E+H/,T&?XCFLVL[WD&"&FL"=#!+V`W!EW,*]-]5>Z1+107BOZS+15"41\ -M:>)D^IR4RI/!1.:L8)5;;*LD^XN"-=%3"@L<_?.1EG2IT"4T8?Y9Z#X2N#9A -M*#OG=A`G@^W@7A^Y"XS/-L6W%2IBTZN\\%2Q -M[Q3][#^U9QK,49\JB7Q(2[M^2\JG% -MK;(/^MC,.MGWU!AE#6LBFQE,I_K]7:Q`FN?&Y!IIZ2LBV.?#6LPG[F!QBRGB -M+]EHW%9'V+YHZ@QB4E,BT?2T[5(S(+[)5(B+JD;HALSH8UCL5Y]V+PT<3?VW -MB.\4BWHIFCR`TQ\<)>G1XS$;R7KN$' -MZK^W*^.3GU@"2/Y]["!`$,0VL])QO[1*!EHYW;" -MY?3PU#1*9FW7:Q]6+.D#S(YI7!'=ZKR?1Q:B`;L5W#ZATI[YMYUJTB:9]I>( -M8MESX!9/:S1.I!EM-0;H$8-DX"K%3^_Z?S'_" -M`WP6B&T'&]`B7M\B/)[EQL:`&$<$_`"C!OD@5SH8(9)B"58,1TT<:\(ES-L<&(LP?7J/%,Z5+`B*S]ZS4#5K&#A`>SBR#V*L64_1M1M -M)2^ILX^\OU'V;_3TT*3@XL#4?JN?Q.%8@@I`RE38E'V)]SJ;&J2D^@N?NQ@T -MGY$?*_H'Q<@CC7AI[W3\CM6<;!-6[,D$6NZU&]@5OMG$YZ)3S_\/X/DKE!0T -MB&52&?S+JLCI#$P"2(V;3Q+;]2Z_@C8/]9Z9VF%5_I>K(RRFL0>K>Z7QG.BO -MQE!UQ2.!\+N"MV.+6T5VIS_+9H_M1S3'7KPPNP[&$L`)*FG(`]^S/^@"-(+U -M+8@6/:0GFQZN*3&JM"3I.A9XM,+5:[\4?RX*7"BN2U5EM"6F;G?4A;J2+UWT -M/8A<=>L82/*G)[CL>Y%E6M9LG$>WZPI]%#@$58BV.L<=DS;-9<7!W02PT2UR -MH1SP74CW(/*7Y?-CD(0WNJV(^(\7,A!^'N]M>A]>`X8\M]:D8?HQ47@YI-&Q_DA.`.S4QU?>0 -M/>]/FV6SH?G2LRO/-;-LGG'H2B@79(@LP)CH\0\@=+*EH$\6P3)@.VD=+B(Y -M)G`;E:VRRB$K48W!=^?.7QF#G&T\HIFP&&>XI>+->%HAGDCM3]P$S;K;\WD@7]Y -M2E*?09/-PD_\?]13?O%,3]S8GHF$]9RWW+WQYT+*JEAO2U#(`?9`C1ISQ?+L -M3Z45/.5"(OB&1,0_7E&E5O;F$MW+@O]#OA0>&&L3A^`Y>C]9U^<+@R;WT&G/ -M^5Y`82:%B"K#Q3.ZS=G)3L\1+V4CL&P+#LT(/OS[YLBM?)5.X;:`?\FL$X\^ -ML;YZ0F;(X>-:?SN%MI`P1*_?;(3Z8253X,V249BIWVPH=M&A>K\B=8/5*^3Q -MG_!,=;)WL*2@$JJ*4(EN_V2DO/HAUK>!X4>W#G5*33OSL`!V7Y>P8HLEK4E> -MYVF0GN_J=H0WFD>\[_8^(T:`;S84=6PV*4@K_JD47==)H$EXC9+K)SYOV$S: -M[EP!6^O(6W[173@RWM!K&[%JJ;@U`(X:1G71B -MP33_Q_O&K0N\GSI66^)U25:4X=QP\[PAXX=3#MWOH`X&)/4-$*D*3YO:;,6; -MCDIK01.\@BE#U[%QC2LR!LL`=%>6RPGCW65)16#6>?8QKDKKU4)YTA(>J?<3 -M6RDG#>`ID=074IL4"+U,726T%_+CD+$RDQX;FV0E#;9J9JPHH0Y+;=$2FUQS -M6(HBH`S6<^&SKHR?2LQ;[S08[`9('O@D5)=G9!'D0\&_J;X'.%D]THK4T1RB -MX4AT[%*7V%`-O`1EGW+2W"#5_`._]\OC/J@.8LX,/(")++GIQ@>UR/%MR@[: -M['B8""@'/#SL@25937=#WQ@<>1AJ<;<#(.:8W8&%:JT+ARSSH^]+O3EL1]*= -M9HZ>7<2OFTV:Q5L`7UW='J)GK<7'F"2V&0C/$`3<((\0D3U_Q#%%IA!N#8]B -MPZC34<\B=\05H8R[Q?*N2>4LSO1R5[53:DPG!?JR#//S146/.L'`:7O=B,M#O1YJ>7#Q*L* -MKK]<%U_K[N.J#J@`FO[6DD?=%`_F/30SX3L57:\$L>*12J\_C -M.KP0!]4=)RIB46=,QZ@Y8=B=D[A]I#R]F?\G3"R4-`>*OPK"&=$\SG/[]A/C -MNRB6NXQ[T1?8N'=J2]9,+Z3KO\4;OY^W%H.F5-=H2+.)64_]7/V@[LA&PM`[[.`^K:?6S(I7 -M:_6PF)YXKO[AF!'*MJA4#P.K:SCO;O%,70NTVF9;*"+_Z!N)LOA)PQ]#OB:Q -MISF,N169`6BZF%$7#SF!#]Z5C=*K1G]<8)6$&1:%O0%/1\EZ$F$`JV$2]&4> -M8P`JM#L_XIT-@O'H*&3P,TRA=&2U36@Y]_$OJ=ZB;EI5B$ -MX;&T7],\8"7FF3O!OO7DZZG@BCQ=%UY*)9%(K@)02PNL%T(4P@X'!N%`&E3W -M^<1AFQP;,1Y2SC;GHZO7912Z?LL>#S6>>VQ4QB(Z]D)KA?2L1OW>OP!OV``< -M0T[13[I+;[G&7*P-G),`?08?48MN5^0+B9W$_`18F%?3`Q.KJB@8M9<%T8S' -M7Y5LPU9Y=`PBPN_GC?F*MJNN$D;JN,@?`VQ<%UVU -MB)4Z1KE>-!&JZ;N+(1I#'X1RP4Q:P"Z;T3U>T;&9,YVT4?=^`:\9O!IDV6L% -M+5]QR8+%L8?=ASKB&L8,XEXLVL-./UL5-X$6BC".QRE)ARE",%,1PXL"Z=&O -M[D[AW5\P">BS2U`'6H,*IL^\C-U?(SP%Q&%D3-E5U*!S7?K*I0`QYKD)X`/P -M>B(1&UA.[0K#,-L:7/UC?:TO0*SN3F`\RJ>JPPN7\@AOM>LCRBJG$JF[HTL/ -M%KRB9S3W)(0L_I^YYH%L^T=V*P$E^FHC8:<&ZB"DR`&!+EKV.NU(P%&;'`ZE -MZ^$TU`F@VP:%G(((X6%63:D393FZ]>,"'^G_Y=<]5=[+N`'96G).C'K),W[# -M&??!H8`,J*1J,T'.=P]JJS;BK`V,<_,PX(0;Z=K?#;;1>,/`8::AZ>C3HDZ` -MD*.E+(]2G'+01C=45KB\P\>D.BQ0-E(Z:6ABV=*&M;=1DBP'6V(G`&7-D%P+ -M$QY&@VW*(,GOE:Y&JR[##(B>W5C38KW^%@EN@B2`!NFU -M5U2)\-V5BN3R#.<#B:6>Q\;F>9RJ!NI')IOH_U;+4GRK/46L6Y6Z$D])?!_? -M=,.RXB(:H(8'7F'(;;*D%R,./KXE+8>Y1H562(0C%0",'NW\(OE)7-BS^H`" -MGXBGV?'`^%$1-2C@C\D/15$%(H=V[U>S8XQ(8V8HEHB\K+B45N@U>M1UDER1 -M>UZ=%BQ(XH2@<"132#;J&:MR6."P5\K4^&M>XL.44*HI;F5NI39=;B[8LH`E -M/%95>;#NY6"&>2W34;2BJ]N2*G#F?Z)LQ:9`A%X?!/K2V<2`"%S`G_HIBE\D -M"L&C%A_G]\0"I()SRY8)U1P`)Q.4'IMO&)QO6186!(X90MJC+1D!L896;(=N -MA"_A40%J^FK5_S,^_T@Q=6`5+8$5=7U=4Q$+UY(+7RT!Y**U>V;1`LHF<*!\ -MD@:",&FU9Y(Q#@R*_]N)+_?.0F,5K(T<-^&5\YY_BS.]/#=X[_/6:%K>D0_Z -ME=B:8XWK`;KK?4K&I):%JQV=$FP;7+;Q(EH>!^O@]U"X@U/(=MWWNJI!/S:# -M-*@\W9PR(S!J*F:PLJSH:SI*OA=S$(79AF63OY;NA>2VWKF4&6$!L_KK7H/@?,^4R+\R:"N\B[U#Q7WA?PU1K0*4\Q:IR;0>K-)J6*]-XEW+#Q&W^Q8.2RYZ74W>'H0JA -M",59=7GS,@VWD!K+T=],G##FU.Z_U]0:]3MOB6./^QR5(P;\YV+>)D%>35K6 -M+\WBW=HO!VGM`G,^5]K8MM7D39_.H"2B^>;]Z`E=S-/)0ET#^#Q5DJZ&_(Q? -MZT8SO\Z`0WRYJP4`-;`.(T+5BC%$9W#J(T/J.?\^V5.2HO$/:P19%\$+)7$#J..(="ZM* -M3]F0&"P\3MR/JI;7O:%SB3]GC\UGHDO`E?8):,R5N[1;Y,S1[?_,[R3TT:33 -M+$O8LD6*DF6.^SBO&N1.]>GLE[!.ANV&86)[4?.O%F&(R%KKPLS/JD@L/>B( -MFIF@_I9,B1W,L29!GZ:#U._OQYTA]!D?HHNR\`BP5,,71I9&&>2_9>0[,\XY -MI&03Y^IZQN%D?:PA\Z*B>`XMA%'=:R?F+0U]=5EI%+G^OM)!!P\_LEON0TG0 -M@J@XQ2Y(-F(1=[P,;\]RUGSV<8J5V.?`NQF5]+Q,9#H.9)@P;M44IQXT4QU1 -MG;;&)_&LW!=;;6]F*;3)Z8;PO,BSCEVW_G[`*:LKJV+K -M&(CT+NOZCQH)_%!UNW*+[,K)&LP7X3U\4HEFLCJ0/WXG]7P5Z6++3A>TL1-E -MD\,(CJ8FSUK$N0B$R;[*<.8I'*_1GQ2'*+*E++J&@QC,EBGVI -M8#!NK0S1P@PEQYQ6SFFS;\F\B.>]&TI -M5H2*K(CXQ7TCAMPG#%]EXU=WP->T?[&VMJTUJ,TUN*JE!N=&=-SQS+D?::5\ -M6@4=<2U`HA[V;DV\_ZOHR]EB^5"`O!+?M;(K8BICL*Q#P1#25D_K*Q+&"1+% -MK9NM>L[;<::OX4A_"S>?&=7[T56G[V&*'?EG[%3/^YRA3,P@OI^`*KQE22=M -MJ0'4P$;#[<==GOIUK+0.#)1GS3/N9C -M]VH^7'Q@I?9J3M`3_H3WQ"FQ[B-O5'=4PH*-)&;X."[BLB.S'ZK3(0!=ZV<0 -MWA5ZO5Y#?CZGDS,BH3-J2C$EVHYVKGAM:@G)F_E#.Q4X2AA_T]+@W9,6+`ROVV3,!&5*HHYN`L9CK#=')[>JZ)WK7T5?_)E$R*JEKPSJJN -M^G7_A(BSW7B/1UVLSK7XWXLT%Y]0&-5WDF@.X$BO?K,0NVV.AZBO\(6`VBM[ -MHY,80#RC&@SKS:(&3,8W9.LB6`/8$_.[,J87G0 -M&/%A,KM#\3UFW-8M_,1:/MTT1[++RGN*J2D5-XGI!XE^6#MIU!`F*F(@U989 -MDU'I2]2VN@I4AO+B?'+C"D=.20]^IBP2RC5@(B$"WA/X[+J[7_FEPTZ<$D!] -M'%*=[AG/A^BF]2H&;\"=8`HB#R:X,-[2":!1A;-D;(HYY,3?7NFM4//*Q*C/ -M?Y4N-$(:L,#H](R]1[YI@[11^C`F6!>LSIQ+=P_P-\F;"";,ID.T`WVJ"3>6 -MR)]JRW_)B_!2!M-IZ@\(:!+_K;<&Z5S]^@/W$(.[OI-32:=1[SE:9_V"CQ@( -MV:'$+GY$/>_%^R_"#0?L]1'[6C+#&R:\&SA*7]K,$.K3`AW^_JG-EVODAEQK -MK/.C'#8NL+@N&KTL/AT392/)73;.G -M0QME>_'-:OX+&((*OSPQNUR*'KW,LG8QTR5LX0WU#Q7KD&WP=;AB^1X@GFZ: -M2EL&3"2P$2I<@IS>W,YS^9]D^1I[XDEOYQ@+#ZYNTJCKK.#7>Y[8G@=Q,:1[ -MY%8:7`'S-ML":4CA3Z[.#O2-^GYM?E$:1=% -M88S3GE9-8&*:.^R`D[^OL,8(I43)(#OC._U!4@#5 -M81S,JQA[JNU_L@=DYMRBF9#V0DK^,VZ7MP&3("MP(E.Z5)8D<"K%D8^]PO'S -M:$*L15%7T(D7*"U'*O"V5<#?+E)#-J)G7^]0%X/!%]#E0D6)&_/.IQSTBDD' -M3XQW1ZAML9$FF:J\FGFZZ5>/"^2?(#)Q@_>;P#_T!LZLDE`)'#H56F2I)7GR -MO'CAGGQO@5[%AB_@)WW`S3P]!E]N5B;P:TA-1].K -M+^.J97,PK0F8=MY/;SBS9%&CFHLKHG_I#D@:0B\M]6"7Z*.&WX:F -M9O+U%8,#GG%Y+&U%]0;!?>EUZ?-B'0\$&@9W%F-\8^X#4'6@MG:HOV2,SGZ9 -M+53#:-E-7G/`8HQ1NV^XL1_(2;OY5VQ0`U')Y/]?"#6GF3N)LRKB1F\^/\T@ -M`,GXOYF_U_(3$>+=72"L36.7K(U]2.\%$ZX.M[.WTY#`Y@GP.4``?E>P0W]B -MW_@JNNKBSA@+LC>OY_I*,?TI_=*;+Y'QAE*4=#@Y>*_^RM -M9?$\Q9)L@N&B8T,OTY,O>1S2`^51@J]F]KT!7KL;D-DK<)/"9>3VC_CML4P5 -MJ=32"UN2>JTQI5]5]WO,I#W1>S,S[!0\J`M<\+(GT#%_S('"&9R21<:O/Y? -M.H"LMJDPMFXES]!L"4H:F=XASQ/WSUWAF@(`8#6T;<36&X`U+T3M-"2/XJQC -M)Y!2Y1*U'J'LPD$3&0U[7^,,CO=_[@BT;WT^,]/H"%EC$99' -M0;.T8:V`)]/=?%DY\-)\HW-WR@\SU]3J1LW_3+5.>]C$Z$WY1[W9B)Y7G))?[X["`!5-UU30:'Q:IZK;2A,\?7 -M>KK([J:[J+W>_:U=[+3V?VIZZ%,U>+5NL\_50._N*3"['E:M^E`-4Q.A#$KQ]%N`;*O\H9ZBK@;J_L$N4X?B"!E_'*NZ286-A$ -M4F_KNWD_DL^PR&306$%^\#1\87 -M00K6>[QM*_^(_U@+G9`(?G=B->!G&/:N`2=[57K56G7A^Y7]X(E?Y/^K[?0: -MT.D>)">Q8HTNGI7K49M:]6LL3,SB^)3+5ZJ%[P@AL;7I5@ZMT"H\O5.*?H!U -M,P55W>?)R2_QKB[7W5.W<0>'^LD?B__D2,S3W1%5$/^4?QH]EK336!G(Z+&+ -MB[DA0633.)(!1K=MNY*+C4[5E.^1"P3+5GPR'+P^^[;<>#(TSN_]^RU^DZ.6 -M5W1L9=T`[`7$`_=4&Q#VB,>X&Z[\+S]SE-X03'&37-_P;"P5#+9+;'7;"HF0 -MVY*>:]G4D3O4O@I>*B_AF"H976RGTS#GGU^EU.1\[\V!"CK=3JTOM=W"H`)K -M(*QK+(.EL_AX*16@E92FJ+*=RC-(MX7U;4B'V-8JMUX/7AYZM-K)("\\^^OZ!B_U7KO,$8&W3&O_O]_KT"(YO0EQ -M$($>Y>N\98L&^WW774/&=\`DMJJO-&O4UTN6YDE/Z'5V#D/H"PH4K9))O'F: -M*H-KM:F"J.%3(GV1\5`![ZNUE-;;0I5!.#2G1Z)B2G$OMQ<=>8>52"/9:SW' -M<(LPP&)5+T*=DQPU4LN%(0.@(4K9-^$R]-X462#14/OJ'V,3\W^R,08KMX#5 -MJ4_?-XJ+;R()&+L-2BR.J'K/$!.`I'W31)1F[CPX01D?7E9ZHB9,K(5Z)?=X -MN)8R2,'"+0_*)>'"Z976F]5#:TI0A:%192SRSCB?[^QE>C^\*N%W9D?A5F1M -M5-XG2;>G%398R0G2M(^B`OQ7?34H^\C_E?M=HWS+]L/G-XL^_-"YR>&/TE;" -MF@->P%59&U,]"[X0]I9G5I-`3&3%/^PC%KWKM!\.,P)*W3`F\.>'D43L*HN>:2+L[YQ^ND -M8%L=`VL?>@SAN>`L*!S^8"`$IX`<25O_$_1<>]NBYK^Q[72DI)NFUIT,#P*[ -MZX+&;_N/5V=8]`2I-OQ\/\U"?2\&?='4L6>LC";H#$1PAZ"@>&88L('Y$1X" -M'ITJSD"C';XLF?)J,Y*"W(VB"T#T`1S2"9L\G0RA-,SZ)JT'31^F:WPX8C)` -MSYTI>ICW^8KEJMZF*#TLZY^7^[PNN)'HP]=F.W4)R?FWN@87UA.W%^Y;^E=D -M$$KO6>9KKL'90V9'Z+F[]MZGS=%$JMP0(F1X;WEJC4U``EM@`3]TMU])C0HA`*#XKQA -MFU?5?YIFML7)Z>U!],>-_W^;8[O"BS+NEU35BM`O=-`:"I95L=SCI_]]2ESN -MO3L'I?K^^+ATD9/R!\Q):WM0.1(D)@>\G9WP`*Y9U97 -M9+W$[@Z(WU!2D>"(?X#G-"KNG9YY9LG5&<[[/6DG$7X2XU:X!:U92V#%VQ.= -MO3\U92/>N409_%&FD7B^#=M(87.992!DW@/1DKIK(:F<;OQM=S)/FAK^+NR' -MM4]"+`8:F`$GZZVL:*P!.!F>Y%%P,S]DN)+X"(/MEF-,`0R[TSDR<)_`('84 -M+?*.")D-ER_KH+X(*7E0T@)?M.;'-A"#^+]"JU(_7LR!8J2'RX;=X`_0M.WZ -M<%DS3](;Q$9GSI"U+^2?:_05\/J-\0H1X$?0='$2TJC+Q]P,V0)D39-NQ'EG -MT.*A+IK+:1?,Q39=X>`DI]G1[.T0@K9<6"OMR^)_M\!EO&AZV$4%+<;F4V$P -M;.Z>86]G_49>G4MZ@[IPWQ\"),H.9![\$H!/7K]OCU^J$`[LF$O^"GV&!_B- -MEE+W_NJM%HP-I5,D]W!)?T-]6'&:KJ<#C8@M0HX_ZX3WIY"G:M5/P(I05,38B5Z@(K"`%A -MT,1PK&*JYBZN`:\\L@M-^$YS$&_7#E)T*$I*/RS8&%@]6>.66,'D9../HA/2`SN'-PP+9 -MOF*K]ROJF&'W/I6A[P319E<_0"A!7._I+TAY)N0N->_A=R@W[=VQ8G$W*9/W -MC-ET<.:!KP('B^TF6L@VMUR>/P/II_%+]'4&7JL;PL)MP,E1^_M*^.#I5C02 -M,=/>VE,=@#C$PY<$!,MX.A][#UYUXWF$/>D%^>M87E#'#N:A#1'^,#=0L:/A8(-P/>=H -M1SQJ?B,4._U`$IH7(@SW$8,,'C:G3'`H/<3#T+L2NP:HDARTI=&(O&)L8RH? -M%O=H\*L506>5IC1#4]!#*6:V,6E#N-F'=7+AGTSRH6P\]:5OD=NIB'>;WN4M3V -M=GOB4VIN"BBXVKI$8$,7R:QB\M83ZVHVUH*S"X4VRZ9K0'/F=ZG_959,)ET1 -M2WO`;MC!T':0KM2LK//P;^#:X.?-4%%4.5<[.0:$+ITC#0K'`"./2U'9_T'X -M9QNZ#Y`R?DD2@ICA:J*'CQGGX=GLF:>X3-.2JO;HJ_I[#IJ&#-/GDO>20B:9 -M&RJ.-@J94F=O^NFY&,9R2WRP3T]Y8[9H:ZG#,O!\&K;OMJ$G7)[NPDW%Y$Z$ -ME,QLR?3DBJ=Q-D"[R@=$%>V8<3%T115_,Z+[0L";NE?RTDK$&/:P+NG!H;10,J#_W1=LLJ>_R.%308%*Y9'(JAY=.FPT?24H`F>L&4<8W40%>/X -MBA'2?KW"$OJZ)KYO6F=98UR^=1=J/DXR;."YZXLN.)5>,("9 -MI*.X9.AGNMFJ$;PF,8KS&JE0J>1L4R$'?)C&YZ'`?]\ZYDH'AJHR=T12Y8QM -MA:VX@/8J\H.Z%_:].T^ -MUB0#"6ZS%$4X`F`"Y]^%TI-]IXS/O5#SRQ1[[TZO]C_(Y&32J?J0R;,K,4FH#CP&BS#RK -MPS")*G878,1H;HGB3V>O!38I.6J08'PBO]45GPVS!N4Z'O!8K6HI[RZMVQ^\ -MI\>3@DG/^>$6'GBUV"B;B&-DCJL&=PIV7DRE5#E;:H-PS/.:(EN'#7!IGFIN -MS5P*&X:.ZE>>.+E<*,PA`E*[A(I![>P%-8(/YC30ZQ_VEB-)M3T931'M-'K5 -M54WT;2=BM&02]U-OJS9I:U?&/09K8HS'PI[0E:2C5+_]&AGG3$Q+B#D1$Z%: -MGN[G]X*=OSF-82?6\/L5E:-J,IMV97GE2[5L*R1)@%E.6B%5@IX''.H^S1;W -MO+62(B>[TBQ$&>F1GN82Q_*`;_?+_RUQO.?XB6<7).8$813Y\B50V7J''0EJ -MDH\+AWH+P.';$4!QHT#0$WE=1\\XO+(C82BBB!MP0#K -M6@:YA(1RF(BA#1R-PFK;+U?8704-G/^?EXRF._B(&UCC*/_WW0+DT -MEUI*?JC4NR3H&LGR_AZXD6+C\S_YW4`\-<4;M+2.+CP4\3)1/]'`,'?$ZCN\ -MO3;M?.KXUV?K -M#A7T)?5I9-^ZJ-JGI4$56^RRC[?W_M%F("<.@XF5YMR35B^GSR%3M)5NDZ:# -MZ3LB&>MX365)>X8-5I$^9&Q%AC3\Z<1%M;#$-BURON7(J1#+9[*0QC7J>&;Y -M(`K-/!_.PM_GG(_O]D2^_P=U#W41]^?L/%<'\?_&P;V;W'WGXMD$.5L[>A03 -M_^!AGZ/Q?*7$W+$YB&ED-\%41J.]4@A`3*N-?=+@?W)@R@\$Z->,VZN9!SQC -M#$+=C?A#"4K@J(L:5E'4.U;AYUFDR/SR;8MD\,N?Q>+Y/<.8/0Y`6ZSLEKVN -MSUVWA9P!A&\4ZCFY!.%*\X:/*L:P&1]M2>O`6##RHFY'7YIKG,\7X/A`N_]\ -M;K054:/]N>C+:+Z2=VTK95'F]"N7H!A0;'>SLP[^49$LRZ"+$+A)?5^HJ#UD -M1"'*?Z_,H'K(\<(4GT!6YM?+O%M[RHGEYVME,0`7"8SDFA9V!X+&X3-56,6^ -MVW0`-WBN2]3_/#20+]!#WM\MFZKNLJIX@@((F.HW)K3S\?12H#SM#[=N&$D# -MAV)FT#>`R.OUZ(U\'6RKZ)<"Q"="0_L,[U7*%]<=#F$*P$/,04GM)<+0^5#1 -M/-V]@NTBYR,)).J1G%9!5;RLG(P"`,;N.%U%L\&R1^AK=,?Q5S8_<+7@Q`K!D,]B"'RPJQ -M54P,6=@+<8E!40XK5P9'K$;JGJH&M2]Y640#C?A-&&EQMTR)$3';1X::]4J^ -MRM`["I6&\D@6NL%R?F(Z*1Y%MT2R54.O*ZL_<=XWH(X,.UB]PA5WP&8DCV/T -M6:Y.4((+S*).`S@H1$-!JT_(&QF?GY::$-&I5X#%ZWNA7CM-)#1LQ7<:K6IE -M.VB>]AT!;]XK$`I8[)#N:"*09M0!)\X)!"J,.\%JTZ@N1+74 -MJA1D*73$^CX^E%2@A>R^GK#!QIX`&Y=8^6G&+CB/>K46O4\&/SB2O'!Z-2?I -M96082?13XR^7;01ZH9#QYJB130V"+40.CB%D:U-2/ -ML3#[M443U!6I#\_`7'0BP#[^]\C=<&A43A1H5>$*+FW6>^,-X`3(`NA!QY/RT#C'%%3SQ -M5BU83F#$HH%<":$!`*L*Q]RTVE"]"1Z7Q0N9@I15:&+/;OOWB?WCW@]!4!FQ -MT09@Q.Z'8Q!I?0LA:E'MJ8,6BMSNPGPKRDM0=,:N&&$ -M":#4RO+AWV""34O!*'Q5]^Q*9\V;Y[&&H`KR_?SD&!IOQX?7I5N*G]WA)]9I -MG9Y].22.9Z$2*R@>H`Y9IT"A_'_Y-\#SZ]6>!V_2&.03WIVE.3U>25DT:^(P -M?A8[X./@ZT#FN`H%@B[[OD;$971RQ%KL-JNT^(5)#P1J_"#."._%&HK:6FO8 -M$FFTZ$H%R@IKAO;3[N\;[&P%L(O;N=ONGC]XX4/4.1"4\@=)/F,VQLN.H4G2NS"%GH5U[2]#^C -MZFN&&!.&&>MNC9$)DI\`IZS7X\;&_JZCC"-'AN@%>");8*K-732MS2OD'MHJ -M6@T9N&.$$+]C<:>A0'Y4A@-7\\#G=3^P_-9>T3VFM'A6.GS!,!.QS1_:AU[, -M!YVWP9LH%8&>M.UW0MNN(&B,*K -M&ZYE3A4]G0\%BCD2BJ!H27"FV..+=69U<=#.0&A>88PM3>G#_-E=-0-%K<3$ -MM4^'&6BO*ZJ!XR(5U,Y&TQW5HX+QQ6;AJ7L]_#W8SA_J"G=[E^V@*H!O.@5M -MQ@;0[(F!/(_/Z7A)YWR.Z48UKPD$G&" -MY^(-MT(%<,A<3T)-?YRX[(?O%J/$2R:9 -M5"GD-S?*V%?A"QG8`$>#K;9`N;2R*[`K=GPMKM42.6C\4&>]UK(JO*9S41.K -MSCNKH+?^T$0HR):9U,W<6+^0ET)(26901NO\ED`B>MW-HMM>'SK='HU=A[C[ -MXUU1-_791,D4Q<%2=1_GA!)29+Z!>6@>J`X1J+8)(@O$Q1`^=K_QEM`*-CZNND150S%>]K_1(VVM+$U<*(P=:&YR2&:[:`D#"F -M'&4G,)N!,%[R<\5!C"_0[FZPQD^RRE3OEI!J\.6KRBG-Q[IF%8O_(V7;DL_> -MGO`M($GOV9(6`T@NJ:BAG82M*,<`^ -M33-[_#(DS^M%*/&"*K/RT*PI9[/KOL7;`G$#JJPO13E*K13J=-87_Q,R:3\N -MIV3J$$=S4Q1:F!L7*HKBX/%.0&,:,,B^#`T3YIK[>*`#K0?)`Y^P.X@SXY)B -M7BU,FTSP>+_;Q(RB$7/>!`[AR8JAB[.[^0`'.%!@BA34S'R#W%I%W"MC,'S- -MO4Q#\&HQ)34J`A'.6NYAAZ4>P$`!5[3\FI0M7,!@1SC0H'>\,8Z/=BN6>MM!SHS%:*5K@4*]2X4K.E`ZXXD!<"(A"W)#\BU]&E)>MK8"P -MY"D2[9^3X[[[^^<6E10NG(0@HW[&+%"4R8?C46]SIY;FUV8TQOAP[?(OL+*7 -M;7_\TBH7(:I!!)T63@4`$U9@``")EGJ;K[?FP>Y!RKKO-:^!:GJ%":>&.%-N -M,(%?-.S81MG@*>H>/NAPEZ_>U)2/)4XU"NG+EHR]NRLWW-ABLK`PYMWF`.RN -M!AO?4H4K/VC:0-$Z!XM+4KOB[URYD<:0BK(S/Z$^T$HT/<$6MTB=1:LL,&F& -M.<\:+ZN6<)(-;85$M_!V`JAH%>RNM<2Z[9U%XQ35C4BQ3=^IR4)?TS*'&E!T2562]H -MS^SE3.[!BW*-?$DVD<$4P)$A>L;7W@*1A'"TO@=:#MOK?-^MU4,+:V -M$@H.\@=D"D`*_(SO%HG:@("0C6?/!36SA/7H5TDI@@EP`3TOI^ -M%EXHG"-M@$ID[6./&)MBT'$N0;PUH9@(KF -M2Z:9;$/+S#:Z8-BQH.CR?$C(A;H>>:>%TQBB56TQ`1#D?RA/8'<)2/D5;#/P -M64SKS3/MB'RHX -M:'-JF9<)8L6DFC357IL?QZJ35,^H^`Y88/-*&V9SPT84R3F'$F'P''M'S<4[ -M5LS*,:6JH\,/JA5O-X)V6XH=(=N,`>7>&W:#PZDEZ0^#!D%B^L=`M>`FMSW^ -MIU89$UIV19Z.&YNZ9SF\6M9>PZ^4&K8.*`(*KH?Z='O7*4Y+YYK;2&?+R]$+ -MFDBIET0+CL;.#7^5XJ4`ZZA#ZV->59X-6B)MK->10H7U>^`'J+>T;O-@70]: -M3'-,P1,++?&6PH):OC89#YXT"KD'M$6IY8O4M&!K@ZWOAZ1,\2B"^Q.SL,8 -MJM,48O815$.$VU_"ZEAI0-MI*R0OCVQ@:D"C7VS^_1)#8(P1IP+'Z?#/)M2D -M3J+3^C#ZDM=TINW-C[":HD3$A,P:]P]_CS@EV-B]2U\(08OY%6G:$H6SX*=."Y4O#8O)4%96-L%DK5^%MK,]%\*S@;-2DL7\(J68 -M5?2#`E16)CU7\D+@F'8Z]:#RX`3;3FF9@*P^SF4LM-]B -M2I]IFQ-XTNR@DN(S^Y\_FGO`!07B9HQ@D)R+\[52J] -MF#8W,U/I+]_],&.)4/Y9=IPV_T-@2B`]+OAG!E)U/!'./N]=,4:)YX)6+PR^ -M2TN]?4V9XY_M\=&\B(+T5V^WEP#4L]SJT+P(Q#66>E$4WC'@4>'#\-ZED3L3 -M/[&#SI]=)3A?=)%EZL<#.CA;RZ5Y,LGD$!I:0SZVE,4^[3XN?\O^TCVHDMRAX.1M&0CPN4W8HEM]]@!=P[@.<*^(X.TQ1')(]ER^,L#JW -MESS0VD/2)!;%R"PE1KAC9`K%]`.4XI\1BD]2$#)=!*NVL]]U\>3>^BPQ[;NB -MLNUKQ1V!]<7@O'9P`<])014H!BT[Y'=G/UM35GW/&U?%%"!9[`U1O&(#[3G< -M(9+1!EX-QJ0%?B:3F^!K7%2T_EY?__A__5-WFOTS,T=:I2_XF0>P';2*,W5QG`\'M$@)P(OK=&+Y6 -M?9,XQM6@\A-YQ+P+B?$;'P3M&L'RO(>/3%)`(>1+]A/T]Q`Q6`^2KN%'MM_' -MM&QJ]P!R0/L\D3)T\H\9&SPCQT);GPVI.@;&^E%R"9T#*/OKE0@'9H!;/'G/ -M\F'*UY=L*3"?H?13^J;I'$2 -M*D@V553I%50;3:?O!;DB#8UA@M1.Z_ADT8J]+23ZPD2`,*X6[G#@P%`%>UDZ -M8E=R_TEB>!*T7AIZ^@$9#BZ/7I75()URUO=J9:#0[+A)4;('0BQ9RAG[4@XW -M"?9"YQ89<.D-EB_BP=?8$N#Z84@&E%G5"[LQ*Z1?OS4B>N48?7S:5N-!9%/F -M\=P^/JHKPR\AN*3-,3'1J('N\`6=N+:*X+=28!FB[(6X\PQ]O.+8\WW=NDX- -M94XB4_T:'5A/P=1O?GXH'QNEHL(E5YRP=H8UJ`8"3G6XP'G,-]<'<#836K>* -M#D7J`3*/;!9S]K150>8>2IM8P7"@<;U]MOY4)/C_73445.EFGOQ(P?3S`5PO(A-"X -MHP/:EE2M2:E)&?*>]!A29.]XC;X_DUZEJ8Y\^F+$9Q[QS;=-&&KP(F/-UQZ0 -MOL'(M!"6[051[;6V70]JKS&95!Y?&UGZ!V+3OH#' -MBLR&/A$Z%%Z;CGV.-WJD'_H*WS`\0DZ(8JM=7;+_402<'X^1KF.IUXB]AQ0? -M/,>YI(@CQVV30#AF*^Q/NQ2+.?U[%]=J$R0'*A -M?AI]TN_TH;>OK=Y3O.+UI.??[2TX&/[UA+IZZ]2*\^&,-"W/+O@LT=,XNHSR -M&Q`:[`:V*4>C!]K5)AU3P_0'CRUPYB`)0"0]`+11EC=]^)PU;UX)8>E\9_R: -M33@.0]DO$&<'Z^)Q)*P,9"_`"+Z:]>&KM(S:$`(CYRFQZRG_CWG4Y^Y'KVA= -MJ]2"`807;-#4SLV_TLK:(X_"[9U(:I'3Z]+9_S1KKYUG9G7/$$FX:=`^"+<< -MJ8-`I`9%JBI\(N<1@1#QT9RK5$H%HRW@NO@.9Z9X]&E+_@[%YKV5-M7#ASO#^]^[0\^O#.X0EVQ+PP-I7@/?').4A -M=YV,YNU92'F$N52!,XQ8W6[!_M)NXK;%,GU -M0MCI.S2\=4[*^-&5=%4@SD+1B#9MI??7.ZT(1^V,2;T9[\D*O;&E+@E';6HB -MP\4$#HR(7ZRX^@FT@EC\6'J=U. -MV+I/T(+L!WI)UB*;*7%.O#N,QE1L44^:X:/[W2C$?_)B-%ZKVWRH4X^^B8)# -MD94*\S2%$K\3N:2T9E=:'/XBGNV>S>I2_IXMY`M]&6%,3ZD_HFOVW5@D((2$ -M_Q1>,:AJ]B?N+1?*`JFC2/H9:@\.E>7./V90D3!DR0FO7XS\:_Q1`36&S3&T -MCE3IG=(@F2E/-^0B?AI5<#9*ISN6\V',-:JEW002BJDXVL%48N&JT13U) -M?6`M*?1[1>E::W,'D`@?3S)&L>WR4Z9!/#7]UE)"K_0;!Q6_35A^*%CD7?U] -MP^]&3Y:+4FK8Y@G&C61I\;=#7M!$Y#(KB9KTU:HF@>OU_>$-TCR;_\7S(3$/%0[EUX.Y?=$+B5?+/\/\5F54*%0$]3634,A-.;L -MIEU/:HRT(37_ZM6<5`37HL^13*#I?U%$/#:O::9>"%#.,_-"T`0[AT'=?^4R -M5D_VA@CZ$@#]\?Q1Y8&C)PUZ$8]&B?^^O*&4A?M`?BX-.OT2B-Y^E@$+LWCC -M'R7CQ,5G@6T>=MYU,23X[TO/\A=&C#-U+T6]_,'9)0Y'5+`O-7\W<"PU@4Y< -M)HZT\Z%$%&X8;C7LCDB8US,)*:#A[GF6J'.XE(J0'3`\8(S(%3'DRP>ZLI3Q -MJ)S#K@4%1&WY]^K`_OI\Q%#T_^;B#;[O$P:2$H3+7FV0392B7FI)9S?, -M:,JA+_KM;H.C>7?F=K(!$SI89.\MCB@'Z208@_PWH+%R:6Z:QL]!IBP?0D`% -M+B]]2?\;`%MU[8=5/3Y2L,]^BSH6\I;65S/QCF]:?X;`QL(&DB:WWAXMJ6V6 -MC)&M;:%BQ3OS_5BD7BM_R)O(?0VUA.($+_PXF4G -M:-QZ.7/H,-?VOX!VD%87W;P:,,2(4KZ[B`4+TN"4'FQ=&'#HI'/&CK?$]-^. -M8DO(?--91TE2<)Q(V,J,6*D8F1VT0ZK-[._.RRC*M[FR3I29\'2.XRY4&,D) -MI>J\3(`;IS6-17_V:[,%&K1`IFR:+,*>T/4$.S]\YKE5/X?956>7]M"@551+ -M;$A@IACJ*0N!XRO/\MOHE*)ID+VM2ZW*#AW836*;?>-![X,-!OP45SPF5G5L#X$(U)A6'0/=^C8:WIO73FQEW%0L`&JB\^.;'5^Z -MO017AZ]/CS4[:`M,#/KWG:[:.@7BR_1=NV`7\D8V-1RDJCV^WQ=Z/$76./%)-D5707Z:#!:4JY:*?"+7;+(J:VY -M>[KY3:D=C5$6#?@!MV_QFK)F`+[W/Y?K5`>&A6X#:8T$![,V!B$0@\#LC$N7 -M>*FHDX_VQH!8Q -MFDV0L?R@OGT$$M1YIG*70NU]7A2TLI_'_[16-2C@83^L<U2W\Q7W6J'L(47!*PR[QR(<>T.1A@9QS7Y_B^KG?2G3H(F2>!JJNG^1^HJ909O -M_P`.H$"OQ:EBA)*KG#PR*(2J!5Q&"H>3_O$/$9G5L(W-#+BH2AHYS#S"#`T@ -M^K'_U,&1??3(`U@0L&>7DZ%CH",%_ -MXO5_ZC5=\+2?&LAL9AHF$-\2^79=E<*)C.4X -MF='/]S\/$LPU;I``@H0)`GRFI_XSQ[ -M23*XB%G1#M3V./,(_^]5=K%X)TU])V)6^\MF$JY[X1:#<"2#`9%>F):\/<=6 -M>!,6M^CS(!I0#J7A'_;GZ).:RUVTT6YLI*;2G=Y9M.V?NVZ.RZ.-K -MY2NL_3-VAC;UP56\1B&R$N(%5,K+_-:"86(%+:,U(,5ETQ8>N!F(Q9^D,BCP -MN6&7I'\<9NQ@B1'HMW.PW%\OJ_C`.AP>^4J<=WWXM'`D6)VNKBV;4%$GM\R- -M"KT4(2K2T'"FE_;(]C0NEYP^'S>TD@KITX=`%AX>8N6[0-=Q,XP-L2%$-R0; -MG+.L+POP!AX8&2X8LP@>VRG1D9)12B^`AA%IQ)IUXF(26O-MH=V-5KM:M2!D -M'SQTA)&\]I4N81UCQ#T!LJZ.&S4#S-"%93WP8;/5Q&?)3$;N -MM)EC=W69_DT9$*7%(0'3XGC=PR]M('ZXL*G\(Z"+W=[0,^]89QK_[0(F_UX: -M[4N>H8;HH9QA(SU`KXV5+1B(EYPC\IR^N8G.$*A*,MA6*R(UL'"B=0M@1BIH -M3$UXT81??M:<:YH(P_MR5?H=A)*2U6H.X<1"S--2;&+G&&2F'*\X0J25(IUF -MHI+HQ1$+3V-@N%O%*/7N1&2P0%1S6UZOA\(RZ-[*:(O#L*4%\)EPUDKQMR#+ -M]C*F$]%%J=?H_"'#V;!,9OV8+EF3,5EJY<&IA%L4CI7:KO<-;\) -M_AH:\D<5CR'.>V0QYD=AV/P_.\CC#8015SKF#/Q.3#\/E3JQYW!@$3._YA&T -M0T_2HDSPL/Z9#(OVCR(1+S3K,X6^G]WXAL5)2'V#401N;W*:,Q3(2T=F#?+^ -M/MPG5@AH]1^M?/%GBY]--[T)7F\RDAV*TXW%+[_!%0C#3C^]J4N,U/C>LFJ3 -M]9N%06K4E&W3 -M;1K&:76IJ@'VM"B&.>Z;76QQ!N;%%"_^A^),QZ\`P-HQYO!:W&W>D=L&^2=W -MCR(K"4B[GYIJ(Z`&N3T;[YFY.!QHCB?.O;*-GV,BBR#P!*>5)JO4(8GYCG-" -M!5>LBY`5AZE!?Q^CP&15/U]1Q[J:S-6WFRE* -M+UCMRG+1L_7?T2C@`S)SN17KE]*@53B8\366*[5,7SD$ZYG01;^5AQK]Z)B" -MF;>C5K*],L5B'*'9K9.09?*3E6-78,O^_Y,DG$MT4NJO%Y\2<&=:QTPU<+,+ -MJXV,UZ!Z==F?&JPYVA5T&D]%4Q=H,G9(>*H;I8(,U`8@]F]#[;7^;$%Q6.A'1&Z4MTV6&!M`_%C+PL/F$%L3]@KGI'T -M\EYIG,J%>':14CHZJG[=V*N"4_A)YZZ^9$%[0^(^@&U5E<#7[/&0\KM1NKBY -M:YI`@-=VF:9D%0$Y_$>H'/Q_4;`"I0L'*ZSW9/I=.S;3B0A"+/J*[0C:,N`[ -MGDA1JUW:)#U#_I8/%4P0[;75Q<%(+#'`&WLS(NW^;S.18ZX'/UW$HTXL3VEHG0 -M-MG`)B>5+5^P*ET*/0A`Q"1?:1Z]*I'_3^WFN$5]GO"DC(TKCR!JPHBV);;: -M5NM./C8*ZI=?$-X@PN`-*P3%$F?)U#E\9]T#A35>H_IE!9XHEEJ+?49W,U`W -MCHS<-M>5R._D-SV57"#)CL9$9F`#;MDTP7]5+&Q>DU$57OZ0:M&1MM_K8Z^N#G=?[J(^?M6U2P:\! -MKN0KE.4R'=QM8*)12J?LJ=R/M`+J1,K+;.IK$3Z6V;)#I>;AM\/K\TI(K(S^ -MX0AUZBXW&)-P4N==1`@`OC>D^@#XXE:2I[I//0R5U'7CV`%3L>3.;0>>\O;< -MB]L.J/UQ9J8(NO@?*#1$U($;",%.8;;V98]EP#T6FBBIEXL$BR@ENK[N1_-^ -M;22,6*S3MYR:Q0_?2A5HR]1->P*($X)`>`=YY_Q#E.Z*VH.CVIS7W\O%=6C2 -MWY%Q+XCX";J;VF_U!G/[2*SV;:[8'1++NW1MV.TMX!U?G"3]>H^4?M+K=%V5 -M.0/[I-.!_-=++Q8VY,A.JOHQ(2K687EZ -M//=AFE%BR2\A'"C(!.R7),H!:+$E!?UXMZH)[*AW,Z":BBM:;S#]YP5>&+/N -M790+)BP.HA(8G`*M%_Y+@&3(\_'9TC\KWXM,#\V4>W3VI=X&!93VSF!1SN&; -M>?C_]#M^R=%?7WJ6AML5S$F$JSI:[PRVMTK(_ZSSOKP),Q@X%H")45.(B!JE -MN,>2L=@S+?,5Y%D/B9EL%Q+X:,X=XHO9QAF8#G)4?MPH(\2!V!RXFBHA&6C< -M^5F`C25*AC]DIJ_LJTX0KF_GL[@3$)JPA7^78;'"H*Q:(H-%0):8<,'AA74YV#M>L&YX44P885/AYLTA4K7L@>1PQ5&<#\ZZ@OM'"0HL: -M=GZA,,Y'T@7],N:PD-&$P!V&EI2JM^^[7!M"S4F>52K\RHT*>HT]U.%N'4$` -M5;:`7@H;_:UXZ45# -M&.WJ.008V$$:/?"+_-P`MZ5^;GQ^]$%%(KYZ/VI;N1FWV%EW58A**D("_A#3 -MK9<&?&DO3ZP.`M.62R;)[*^0P]5#;M#$U/.B$\Y&.O#*4SR+<2 -M^>R"C;&>!LU7\5>_9MY0%MG+4\]6+0[Z"F&.7"(85(@0NF'9N87'V[=O_9&' -M%2Z5W+%--KS5H;(_"2Y9\@WTC,P'R0`3'LSE#7W*(%,7LV,>-+QD8F.W!*!2#WQ6/;M02/;&![@LF7E]'2G?>.NNZ2@+XK'G$XQ-(F[SW/Z#+S'=, -M"5L=:VR=MV1\5%UE8EKW_D>B%3O^_Q3LG:WJFT&]0&)_X.BI7-)_,7J -M4(E^QJMU)5^\WXJI0D`X4I19EFZMM+46@223 -MM5I=74[K2;&8KVQ -MMOU%2(H15MME;GZ^5X9B%35%^ENA9IN9_Q[@\:V^G2XGFAKDK?--6JL)4NWE -M8.^TU,?US.=Y7;KAIU%#6L*JH57J1@#0M`4E=[_;5:38O]`$?9,MY,8@CSR1MHPAZ?!\$< -M2T;]3V01K,<';+[#"YAZ]Z'.Z@P`VU4=0U<%]K'(P!,',AZ:9X%M=/?`?*(8 -M36TOA>\VT<]S[^OBR'5@-F4LMWABLMQXS.I\"A\3N/B8NY2J%@G)!XKD]U1P -MK*HK5M7GMF-V/)LR^!&8U9<"MM>=)NQB[RP'P9]N00FG\44MO9$LVEZ)77Y8 -MDGRK0EETG;.WKKWIB2#2%GC>.Y:#2(3DM=&W[DXH!3,MH'^)N%[%X4*_X,6FWBR@HXPH#0,EM7D8>OP`=#C`,*S43G)3@*^/X7$1. -MV@A('N/IUN)QI31D.B1)S>`PUZ-&WFTT,D&R\Z$#9:#E<^DH]4?^SXF`9+G- -MN8/-S=BN\L`S,J`$F*Y\`G5,-+#;_5ZT$A2EG?/4]I\-=U;Z?%#A6/LS!%N& -M38=WF+J?P)]@6&`KBW*ZMKJ_@FEDR],TB%TD]D%[.M'WE3GEB^JP#M%+>4CG -M2>QMZ.212%&6HUDZ0+(KE0Z^KL0=RV`1<&<>&WKI+`#ZFBA*DF/)`Q$@)M?* -M9):[8KP?FD%CC#M_BL:20IG(['6?H7;?"9$$MI\M+TCY%VR`.I`UC">IE4BI -M04S&9C;(K28Y\/92F,MU7>_A_+>SEB73?YBVXVPC9QYTL^R!BL"?>, -M!KVUQ"P8["O3Z8LC^*6?H(`^&=$`%!R]REH'Q`N#A1<^:*1 -M$@4HMEFS!0!0L,N@D7#]*Z\6C,\;II=@%#,\V2I+'4!13C_X>*^YDF0PJO\G -M>-\O7>A_@[AYLUTE";7O`ZL06L:1U?"ZHIK`2F.G<'R-">%`1;M_38ZB/3=3 -MY:4OF176J1I$ED#]"Z=%ZP*&WU&!:&@-PZR19 -M(^'F!#!7,ACJ6T/BH>U13KA',F6S]C.9G]`.:*X5#-X$6UY>KA0OD@J@RO:P -M+5K>T-7_M:,[4PVU7*-29F0^ZS!/VZ@QA&(NT0QX6)LJJYMS/0:^_Q(1,^FC -M'K%Z`_BAP2(K6I4D6C6NV!$U,6+78"?X'%>]3\NCTFWO)K6^1ZEII^=\""&- -M"8W6P]Q5NH#;"C!.=:JO8XCOW:P+HVR?R<88)M6(E0[XP5B>#21SY,70_$#H -M6F9I;JWQ"9;'7O8==GF^$[^7EH261"QW%C%O0]TQ"ZZ3WECF>PT%NJH17DP" -MD7/7-K(,EH3Y035VIKW*A&4E:=+ED/=%"KB!4]/X[;Z%-D6@P-YW[[E[S[#6 -MP^:<[VQQ!Y[J#?]9L+VJ^C%G%\U=:"8?EORRKK\,GI_E0YJXPK>7875[8VXJ -M./:N+2$\H=4,>QA264AOJ>+A*[[^C..2BT\D5H[U\,`ZF^_MY%L)SVVW8-%^ -MWEF"@6[I:]DV+MV?;;QM[OPGSPK/8$$U`.%1!F\BQ$&U`Z%4WS1$E\@51/T7 -MQ0V+0L]I=Y`7)*5"XU#IC8E"M.'$6%B@8+['$>)31;>QY6N#!U;?<7C1ZT(" -M"(\#SQ<%TWL!QEX3DI#!5E!]4$/()E[4WJ/C84<11(9]-;,=_W/5QP7K.3>; -MR"6?N0(\#UO!O.I^0%8.H-5T>T".==EU8)OXTM1S=BQNI"6(U1!4K>39++?& -MB>T_'?J`NQ=(E2M5R$<;X'^UT^@.8XU:\Y.D!@.Z394ON;=:\9X6_2?* -M(V_PUYSR1%"CG7]Q"I.RW#M7H.'^(*OAOV1,0["Q2>CP+[.16M^FK3[]1"'16 -M'1WB'3C*V('(+E>]RAFFS">XH(709>$M<#"[OT#NQVG'^8=^\@3AC*#YA0DO -M?X$YV%%@/$;D6J=AI:;,'\&!I=L!^PDGTI;4O)_P/->&]4N2&*8Z*TAO?<@% -MJ$S-3ZIIP\#!,"J'^EU.C/4+91;1FX/BU:O@LK277 -MY8+/<;HJ*M09&?S%ZC.NH/UGLH>P+-F@6_6]B0-PN=]Q&""%P[>WPP_QI^:/ -M*23"0/KIM;8<=@\SN`,##CZ4!CG8\56%R!]2:E1TYI=F[(#((%B3P>+N\Z)0 -M-R2.UVQG:;[>=GV@"!`#SB*T#D_-(Z';X/=]QNYBO4P+DJBU@S5X81_A@Z8`_ -M8KAJT]2#%#E\\?^BT2X0?O*V#B+P^7U?+TP)\Y-_I\F,^+#6A;PHD@[7I%.T -M+GW$#ZOW3$`Y:GS+E4H*&6NATBP#:++YEL -M,^)3AT@I(I*80EPZ=^39AWR9T6#'B)I#O[9(M(W/"$1A>^*QOTY=_K'TG,0K -MF^\JP65FS[-G-5AX9,N -MZ,3GN'?DC8P0J@+5E*,Z;%\LD'C9<@&+26RL:O6B=?-PD62#`_G(;#462^MI -M2X<'3Y)W8AF>;4CUG`#PEZB)Y*P!.Y\9LUU>V!!8PRH:^-].^:\_$W/H9OF5\KYC#.:>L]E1^FK! -M*.H(.]0#&(/B^&1MHB_C6;A?X^!:Q)8=SD';*AW#, -MK^?&W9&HF`;5/Q7&V$VL^]1Z-'Y0X-%AU_%&AXX\]SZMA@\1PL+U*?%E0_2\ -MP*W!+E]=!;GJ,8=(E@&C(@I.\9#-6T<3^&.*UJ=[[,1\"UIIP^Z/]3;7#2?6 -M5%;GWM[9$X::F>7]U.()@4'2NS5/$]-VN82?T<=!(TBN+RYT_`=$B47JXK_7 -M0I#R9AFP&GI6S4M:/"D@5$-BEB9"QB,H-I_)(I@I7_C[@-+,FL\! -M<^9!%Q+__U$U^&8U14=<8"C/^4Z_\:JP:D))]IJJOEPTD/X -M5OV3^;I?]T,9,4/:-AB69V3X[S\%:G62ZMO70'M^CEJ.1C0O>0_L!%8VQ#`? -M>L\`K5_P@'0ADP^5T^7FQ:[[7^($P&1D1BJ$P3=G2> -M+0+/]V$0@ZG!CA5CC6N5?U)>1'T'.=R.H"]0)>2(\`^!(`[7^2W2*76"T2>Q..=-)Q<'Q&%=XE*SWC8J:96/'AK2WQJ6@( -M2&K'B$^LI!/K2Q_/<\[.B*^/Q%W'[+2BA,.[_Y\Q-&M#^)"[/`' -MJ.==\MWHQMW&90`.('1F[2"M\;+>&N$<2'^278+(FW-IVX%V7;(!:6DAGN%` -MWU0#2&9.T:8:1#,T9<\U"&U%BQ\G&9EOWP?WC:EW-VP!"/Z]$O9&;UID7>\ -MK$Z9!!QW"UY?R8%A8E+U5])GBY"N)*TW(GPD2=I*8B7_1Q-"B66;:9@QJ+-@ -MC7GQ%>GYA>U/C:-,WYVP_B5YMK/67/TA.4["D+]C1N5%C-`_&5N0KO9R98NH -MFI-<=6ADT`;69R^5J9:7ZLLA^.:E&%1)P4@%]@;-]F-UM&V:MKP$;T&6.W_] -MI)?W0A4N/BU!)HRC3TX0'*+?M32)/_H_"8Q8(DBQ=4,OYW;72@1$1;,=:7/; -MNV20B0_$685TH!F\5T20+!9$880N:@W(#(_`.VS1CW`!5GG2LN3U6]^.FS7;\/$E2A^AKS^Y.V8"$X(:K&LZ97B) -M:\*$OJI3\.XKZ-B[Z*ZI!PF'%6;]>$)`/C+N- -MGI\@$^VS;NC0(3Y]K(0)X(1C%T2?`8MRN++NE#.!@DD]^5C#'^%^%J)9RH"= -M/PIBI"+GB^2;Q`K5#(BG7#!CS&!WYB8>(D1W^<(W@G[2I8.V"/MJ7(V7!87A -M+2-]9CH)?4&/A0JM;AH^]*75$HH[S)(77DU3]BD)RXK_EY:VMJ]!PW4VGW$_ -MQ@D1U(/3W^[-\$>$;Y1QV2334\FTQ`<-J)886V(SHDN94BN%)J@6D$R?DC>[ -M@GH4CR!,S?\\682+2A$;[M0`R^X7I&:GGSL)?:G]IV;5'?6 -M_K:-\,L"3`^-4N5Z^)?/5R[`Z^648=9Z'>??`'FQ -M"Q&'?<*EY/<\=PB>'"KK=%ZRRU;^.ICQ``Y9!6S?U?`V2DT#FAY:=HRE>448 -MAA=C]W?Z\[]'$0PS@1OQ\YL%=<$8H&%`%HY4YC\!U/?-Y:XY(\KJ)TZU;7J9 -MSWM_7TBVB!UH?RB&Z=TUH)@,'*-^GA>CT1;&WP7C:JX(RDOZ@0I0@@$_H%5[V`L]K"27X@N%1OPJ]_HP+FEQ`?I;#13%O=U4LP,X>-3O]L,]LHC1]4F@+ -M5@G/[C@]_+^BQ*$)YPW=?%99E^M-&[6*HBDS0D*I0J8S"?AIJ'E/+\%//E:A -M7@`$MGHFNJN%^5_2[]-HB_1++T-^46A-F),Z+[RV'5X/)9$H.2[)0^ZSI7O" -M?Q>GVVAY_G;90=40#&%^ME>#`Z5H"!/*Z` -M'DUDA@S<"9WZ!6'J`!AC:_ZZ>8[/'G3EBGQ0,E>/98$/[U&MXL&]-I$E9CXU -MR_OX"XLAS8"/S;@^5(:+F\ZBW2LV;H+',D$4L4Y6)'(NRV5S6\H`;+*DN*]" -M`K!`5]71*_I`_#4&0VMHX.W$"DIF6M[]:-U'+4C;]2/"6T@;$,W7[&V4/+RP -MY-!:%U:I%#W7V&B&+1`S!D),H_`,.Y0%H/&0/O7JE_%YTNOX4B2SZUA6XL>! -M?^%O\+L\PP4_IS4^*=F7\0I1FV]IEUY?X/(5)]84X4)^6S%\-5\*%"E]N)2Y -M(&G_.W#[=C%[BS=VD_59_P1JVSO0H$G?V'&UN->"8]?#@+.6JQM1AC9"PGF* -M37D1<`;C?C!G(-^?.UV3[4&K)G;45/MQ+`]X7MR8<[W$8V2WP1>S\J2RD,1: -M>C8OG*`Z`.U>UX%]IJ&;(?5;**H=938:UHTG`NVY+C+GX!^ -M?JCW`H4\W677S9L$G*%OUT(*YN7`@QE7>L#W^Y^JXQIG*M>T>$:4AD2`$3$6 -M^R';`1.X?!,14D*@X2\;D1=S`NGV[O1+5$>I'0]PU?A)0-3N#9;`\DUCD0?: -M60.PNV".!<6D)"&XZPV%9?Q`1@3+'CF!9CO/!$\L5DF*_X[/+=`D-H4][!<.FGO]7^@17QB`F;G>`OD?/@MQG`H'?>- -M0T\/RL3+H#F&4_KIUD:1-E25PM-5-"#D3H];H99OVIY5TL(,$O9"UWQ`7$$K,T[Q(Y;+);9:(;2G\D^D=GDT? -MP58,FZ%"&3-W7K#_W0A:;MRZ^&]JDD*++]>GHN1/A^$"GYZ+LVWBRY2-0G^_ -M`G0SOV`4;4OPMX4,B_)G+8B--*RB/--\[\\:@%^_QTQSKK,5O&K_;[V$4,O* -MFI1;Q4=#,GO6BU0*%1%!DE(J-K5KC._Z),??PL(KE6("`F9`O`C:VJ=JMWW="'XF\9M+BE@$!21U@!# -M@Y,U&KE/[-8P"[P6@K90NSY?1&ZU?Z9X(,HW:?$\RPR`4EK)Y*`"_55%2IQ= -M=2RX.6AXKJ62K#FB"]UJPA"^2F&/+B)#%5FNY[<8"10""DF3@1(?&Z?>*5!7 -MZL@#9GUI-7H(>5AFT/K55W2BJ![?JVQA0)C$X(CP'>.P\*P[\]FC-C#!;@I+ -M2F_!Z/C(-"=]6_!?2N>JOFSSQB`449<,1GVLV]>*CO2%(GQL*`A$&ZOM)0MY -MU-L"T12WDHO]4*YF%+-HX4AB-IN#(X -M-\G8:%!^-)9R?HP>W"I@SN!!0RQ$Y4RU.:#9+^;]2R8<2 -M"2FV7Z1J\$SS]ZQO@E\%_F-#Q@\)CV?2G9'4%YAJ=/\\BZ3V=6"-7DVM9J+V -MW.`CUY?U580V@N')55R)_Z9>N^R2#KR*+HK'.R\2XQBM;0^"IN@#.WP0Q!EH -MUPOR[(T#WJ4)JX*+#@(C>:+_V6+S%(6^<+[LV?XN2A.LFHW<'$*?2JT -M-_DS,LBC$.N6'B-_Q;O@*_\GR11:FB6T&H6.MJPB@8V/ZNJWK1_V -MU659N4R&C0>?!7QZA7D$CS.Y.)_?0?ESRHS_A&A&2I&Z9D9ZW\M,^P:6M3B' -M1\+0L'Z+2S$%^/8WA&M84LF`93F9>6?Y:]B>P3%IQ(DV(2\XHW%YOVL11"2G -MV^[7`;;0]?\YX.*XE4/[^GE/9!R/*EAZQ>UZX;',T&3$Z^T\? -ML=-GE_NP@',QT\*%^9"?C.SJKBM\VRP$21]V"A82-`ON&;/,:DBPOQB=`S)H -MBG[OMX^"\NLHQK+,,/>DQQMK$7#K&H0GDO=-J#E\0C?T,27C&4%IHA-*P:]L -MDV00D+IC9&>RWD5NR\?K_L'=W$-X)[[0[C.'AXMM-?;*8P[H([%"AV@0RJ_5 -ML*"!(NUXP8`T=,.2H=<@-CC7@OW.`!KD^(TQ@]%(EM%3UFS@6'QV!.-:T?,8 -M&J2^=7?(5A@X3;Y;Q -MB)92]*?X$/CB<@[@)$3)=E=3."E6O+^GBL>;&,`N-.[Q-].TC67<>3?!:]^U2V"?TA8;OW?S^!Q"X -MJ\HJ*3^_G+JO1;CTW3L8D.ZIF7V'^39HFPF2M4\O?9/?(RI5DD__S23J#,YW -MHI9LH7\2JZ;U%V;C#&D=[@+ZS5>IQ*]]7/76 -MJBZM,F8PYXXPBX1B/5&+&YFHD*=*9`W3);]@\[8[QV)DX`A2KXW)6O79X["' -MRG7K?/(U#E#V+:H#>==0/S[4'X`;8YV1 -M6?6VNZU'@/WEL"I200\5/.(@?I-ZKMRL?N;)8&21QO[+?_(<[Y$"N"G`51.$ -M]^PBJB&`"RT@6)I/+$%1>)ZM?91IPXYGR>H'&;>Y,JI81+EEDLD->" -MO=LL?.4A(&CO='O]6IZ'],=C1JUPD5<,QC*:!+#';Y8T[R]XPV<3&?VCS@M6 -MX:#O)[0ZY3%J![MG6&D_@`.@A\;(?[HU(8I]L2KOV'M>;G=-0>G$KC`#L:C[ -MUL4EI,"_IHUHJY>T_5\(\41AQ0Q.YGWN,GK#DTNZ7`)_/78UWYU>!3;;7CPQV5\0V+[J -M:GP[SC79RHA,K)$D&UZESO*]B5I'F@(+86<-^:+8J_OGMH/_FQ(?;=MUOZ?N -M_"9EU($XWYFP[UB"*JUG0)(8+1DRT`[/KS:\Y2XO6K,PV$SVLJ^*7G5]4#D0 -MJJ(M5IB#W*%)%G[UG8&9%$E(IJGAS8%H0`:H)T\+N11S<'"DEG$5]E`)=`GV*;.W$DW5%.454F5Q1V0]@99`R4A=)B8T^W22, -MJZ]F?>TK'1OH'%INRD1Q_UMR9+P%ODXZOV:]-\'B%QQ4F'#9^.7-*:T5M2^H -M0T-.3)]##7BCF_(S#7JU+>,NZ.K3V -MQ?.V^OZO$`S4#J>?;SKI!_PN&!2R&)``XL@ZCT`$=Q:)2TO7%9=H^!D$G]L$ -M$9K@(Z(_&O,*)/"XZK9RQHT3C\98_&'W-8#FVSGM;(:`'^^&BPN^V3#>@@_Y -MP(O99#B(J\K:GT[3))=`<;[[X5NEE>;S?)*=JGZ.9!)]\6?,V--3[Z,P1,:K -MR1N?9K]GG,VL;TDND5+K=2@(^RDQ/_MQD"6O?*\.6J9J:%)S/NEX+7[L\=T/ -MU/Y+-FJ63?[SP5+Q#IW.GZY.=$,#[XW3&BO4,YC"[:5.#RH*JWB=[[RS2YFW -MK+;"?D.G3VS&AX5J85ER1-]Y4/H(%J-_TV6CI918]WSN=/8>W'>]B]NOM4C# -MS[G'+#D6_CZC6"G"7O<.I(M8!;^TV>&BKG4'ZEX0;;TBSGA!YN!G]ZGS*P!2 -M?OOMCHK"^I/Y4HV'7&S[@Z"V[8,,_$3!T&0&-M$I38VJ$K(GEAT?EVO[KS=3 -M=IU(2!T!]A_Q(8M`JA]N>-0TL++[I(:3'>%*:;FO]MX9K]EVS`R[XQD6>D[@ -MY+[UGT3&ETC`Y2C%&(G'1MW[E25+OP9CG<=S;I\OYKM.\_YX$@!I]E48XRU) -MT&G./M*H]D7Y%4=))I3YX2?0P)6+C1VGB%L9IFI.SVDV$.011JF&J1K&+]BK -MSF_>FA=:U3+Y+[X>Q[[_[E;6&2ZD2'J917S$MX\!S*71<4O\(IRI+RU/V@'J -MH8#,<)41],2]/KWP!P\MK_6/CI;`D:WA8ULB1>^K(5321]J -M`5=9NQ_5+)496KE0!?(=+G:$*<"`HXPTIK*SGN_W9I@Q37O$1U;5^R3IFTV7 -MXLGN`I'.167-'[R'J,>_)(U.[,7(VUV=2-6>B+=CIR&R0)$AU:\ -M77L$ZW'I*B(V(PN7G5.E.HO]3=N`U/N<-02.T3^.#7$A4CM_(H?T7UM)XT`/ -MR"IBC4&O<<3(.BR35=[XQ16>S@0I@U(;B++>&3S5-Q`+P\&M7)[UT@#338T? -MD'%A#PYX:76$]FVZ$+,+ -MRQ11[+9NW@/D#[;!PX9BAU"LI9V%%[)X&Z;O]?\BB`Q+C+">$CY -MP/&;_CZR^;3:$2-1_D$/]4;>8;SE:>/7.QC7C6^U3JVAW@F8:G4@](5;PN?ZTM/$E(6A7;!Q/R@#JE)B*U*!HBC4=2 -M9B(DGN>O2)72Q]GS%10W70XCBT%#@TZW&O-'Z?":;1\D*+&3T^% -M1M:)##7/LD%=9AX%QA#!+;B7.#]U:(H*(1?"02"`[>[_O=(J@-65PV6<)<9! -M4GYSQ=8P4`;932P&M^J^YE=MY*&&<^&]S?L<\LJ1)G@G@VC?1Z]&[,C#:#`J -MGO50H%Y2*GT'OG&5)2Y-AB7Z=0.:IVI!I^M]!6L#EW--WS_$D30BBFZ'\A;6 -M`KWGP!+AGXJ)E"D#),5,T+VBF'J1,?J>T.Z#G[)'PE2RBQ@.ODI(PM-Q4M,0 -M,""@T/Z,^GF:UIQ6%O^&&>3U+"U@_I0NYEU,?MI5CI2^O>E -MUBA8#+'-GM==KR'NBV&I<\B)_VNT^TIWP>GVQ`/A;K5U2#XB+#N@!)9S_N8: -MY@+;DE6@Y746H40?J[/1QA@#PH!+=H45.TR4PUQ%B"1-1$>+4HZN.G@-AUAO -M$R3Q:2D[+XGS4EA<'253I->CEDKI&^^!-9MQL]P44C?JXB@!JD(;O.&IM*"EU/09;F5K* -MYZ*L9T`ESZIF.8H:"*INPQB;==^[CYT'F5A"V>\*E6\\Y$!?@AC7DP00\*ZJ -M$2'/,GXX@S^=IIY@FB/I%+@[Z$9J*4<4N/1H>_W*0.H/=6Z52M@SB5;00>GR5@0]B!(=+Z\UGD)%6F^`QX.;H0`>T-SS]IFS -MSJHR/0$N@_[WK!>#9E)8E*E?].>9T">M2=^M"(IONF9C8^#8*RSH=;CG1J7= -MH).=0_.F2*.FONWVT4M9'B7CYBK0Q5"K%Y)]%A!`_'%\+L_ZM*,E53E$\57? -M^;]:KT!-2NG:IOZ,`:=I3B%$MY%VECH]QZ0SG`;_SQH-+3>:!H&7".@FN4R4 -MJD7$;3>..6U$>.C3L2UR.-Y,3B+W)AMPAHLRWXZ>Y+=-F\$X2,(G^KC"#D:& -M9CM0X03'=HT*`_8`S[A)'FME4XXO -M__I!Q89#><_W-MH>\'TCUSQX0TM#984?Z\WE%%>KK,YAA\;QXL)R"C* -M!RB9`)=\]W4S:@RLTY:/@)Y*NCU*Y4PH^M!+TVGD"4C"AA,,KSM!]FFO7.]E -MX=Q)_2*.78)7,MWLKG8L&]4PV'$XO>)7_A3+++O6[\*S9RT?[G:2GCZ^.Y67 -MP813B-_-ZI0DG*)K5U#N3?K<]GL`X?>`_1J#";"K"I>0OB%QHUFS5`4=N@FO; -M7]X<=?IVA=0-W><#^I -M)7D\97BK)+3<[UZN$-;Q4OU_*CZ-&ZA_F0AE5$1B7B>=,J/CN-C5&O*;_""P -MC1VHI/URT4[:.?-VS_GY$)3$LRGA):F(RX)'=B5) -MGR9M<4BB'@\\(![3Z,4CWW'=ITD)W3DYF -M]5"(VHV96KNAV2,QRJ9WR[2A/E$?;5\]<`&I[-;PZC[@2/F[79-E/?#==+CW[' -MY+(<^T"17S^U!@W&PI)W<_+3C&6*E(AY;G5RZS"D%>9^**Q=XRA5)W4<8ZF0 -M"Y4\.D@H^0/MPY,-G]%/1U>J8=J=@,?%GW(X4!X:CP0/O3F$-Z(.P8FRV%>4 -M&"6(-EP84)`OG^?^7D"HEA2QHG>]>DI%(,&.IV&0&:&M:0-5=V%H'0US_B'\ -MHK9E,NH^U8,>C+;7X@R2?NI9Y!MCZ-)&U"PKDODD+^XNIWBIEDA2?G" -MGX53[QW>"&JS0%OM/[>"3Y)`//>*9($$`QO<"#/_DW,_17[FIN]5,`4_0#MH -M=`6AM>#`Z>6/MO -M[;X%H3K)'[<)KKL_])WSV6:H&2R[T9Q.AO<<9GI5B92\*]9Y?A.JW_U_TH.V -MJXP0V^C:&3'6?UY?>'+8@+A'<&&U4!FHU^Z+'T6?K!6ZB`+(^9!0XXJ"I@`U -M7I4];58#S=L?0C?T^W]^R"/`R#618(,L[NG3*F)E!YU?B^Q33ALR*C\P!^Z# -M^$:B%KIJ"R+W]AFJ2@]AE_TXBR_4H6)X;;J]:);ADE^TA]=LVD@V;,SXF!/3 -M"(;U*`[T-.!IG7\U<46\L-2ZSVOB\8MRTL[U:+#+Q3>`L".[#!&L0%.HE:TA -MTM"9^ALL)DF([*M=36J;$)]Y9@+;N3(7,LMU=-\"&LE`T$@B)OZOW?H<2P&G'<98F(=ET7/F7X="G`W]5#:&,Y`[0;\@46 -M9C!_C![PZ39*CL`B8!N!;:AB=K0BH:O+LL8MO'H6G&47K7F\YT%_!"J`"O+8 -M*6Q?>8W4&&/&9_1VI!*IK!P0]CM\AU,@]1N<50,%,_/F*L:*EMQ@'YFBGQ*R -MK-KS-H_5F&(,4X^,KG'>BF;#U=NBS%\P#ALM>B-+K?I1]K#YS2*2H1E%\A-3 -MM^BJT2E]E4T>*K'F99&(=VFQU/QT3TX[8"Q&QB:=?F?;:BH5UPPG>`Z;J;Y8 -MD,WKMXAK#."&V_6ZF/R6Z2)RRA:.F@@SR.CU7X]#.L0H7A.M-)0N$-?/BMFQ -MJM=0YRP,PFGGAX\4:99V,+U@G7GD`9\:TFQFF#F@!2,#$(H^,2V5%KU-%Z.\ -M7C8<4#[B:!6?X"?-9_E::]/^X&%R/RO5F,."[BF>YR'H5W624]'R+B,2_`42 -M#_$SCT@J`SE,5N:I9%&A/RCFR][JOKTD=A"P>ZL82QG],3SYUYNL>O''Q+D* -M^J<3C`DQ*VM1)9?_S(W"0Q-A\8W;TK84:1=C(FF<-6<0[\,;/I5Y^NYDE^L] -M,YWCDF*,T5ODV+]F4']Y[^%>&?JD'W5P1T(-W-BW0ASXIT?FQWQAMEK'/&)6 -M1Y5="F)7XKL1`/$&0VX3G5^//M"&-;8"S2)X(U(8=5ES$6N9#5POE7\>OIX! -MT=#2O:_ZTQ%G!N]&O=N5&*5]=\'9I)!\[?-\J^&+>GV`)9@`Q>/-WD6VI+I< -M9<0XVN0QFB7`61!6W#^U?A:V3KC:)M3)L\\_(?9<7I4]_L/NF3^AWUK6F>8` -M#NN"JO62G#>$*\YFA4(5J/-?S3D.22>PWL_BUHKVL?.*Z[*3P$NHI']C?O2? -M$?.1"ACL_Y>?51<[Q">2PYG(0._;@H5[V*=[FQIL!>)LW3 -MY"FW>*K=O=6[`;Y&M"EOSX(7D^'B!]4+)";T*]MT"7@BI<<]U)#PKHNI/!XY -M4%1Y`X'6$[,(N'NQC6OQPVAVJ"1MV:8 -MJ['QSOJU7#^!'E>D$9S;#'X_44-DAGN^76]N4HUA];=B/Q@=X#R9 -M%2@0C8]\;T2.1__=G6*FU3Q?2P[#/I&6-^3B.;5$D5P?PKI9;VKVY&-]D`)4 -M$EQ7.OE7XJ802*;Z7T*VW^K_,:`HT.5&78MF5O(2AICOU&)2FB4@H%UJ"B*C -M`](TB*.]<`$YJLRHJIZ#I*(D -M[M5)6!&CG14"PB!@I/@#,V\$'OB]ZRO0#E1,^$WV;^`47I"W+PAV`)U+QCP. -M&E7"HBBO?L8L&T!W=G\.00,JT*8G9LR@LJ@P"%UMJ'?"Q0(W09E+KQB6(B_\?29-3@)E9FHSD0Q[6.7 -MQQ@_:(JJY0E!U5MIM4_]1>^[@&34F@:;9XI#'VD-(ZA;2]D&'!U5.3)^I8+# -M87(1DZJRG4TH&\)2[LYP@?^@K$)N"RO82[KK?C@:OF(P>B];)L;7.)XK90"5VBKNXGFEE^*5Q;#HRZ3P1:R;3S;-G -M/'0`31**.E<\:6(P'EA&45*0:UYP`+]?2`Y-!3[^U".N712A*&YO[I3RBG=2 -M954),``?]D"+Q$\>WN6B_0;LZ=6&@!$VS7/S3-T#$DV.WC+"V)G(%%[RQLKV -M_F1ML\&E>1I7O,SH+$2WD!33XUD^WRRTAVUC23S/://(MI[ENY -M\-I3NA^049"GHFAE[&22@(D49_4_QDB?3V1*A*4'S\6=^/0YEYF:85C%%%=" -M,CH@GJ<40QK"65#7)6( -M5OB@)=PAW'!'YRWZXR&WC$OLQ:X>%O9\8J-X=_20F*D6:GX)R8>[X<(UW(X4 -MA5,_)X790Z>/Y>9_H@?]T9W<=PJ=+XNS!4S!V2R-DZ@2:CT47%":,[&"+LR' -M(<[W>02?M@E")T#0Q'/,B7T8HC4$PS22B@M]OQ`LJ$+$*"(%2D&[O>6^NU[UPZ_Q6+H%9+T7< -M4L$1B!0`5W:F]R4!4<38B`C%>N%L90<7S/0!'YF^=?$(<5-32^-7/*-A?99J -MSV:_#._+]=8;ACR67%F3>@!XDB;&WJ.$%$9/Z!P"6[,S:2R/I<$W:WW`IC0J -M_0_I0[$>M%DEQ*E(91'?;\-J=D!F][=R.'.5=H%^<)836]$3A-Q3>B(/0NR2J -ML1-<"%1T!6/UP<)F(GS8+FJ<9\&=-E[HM4B94I`X8[NH0W*)P>24)[J**>7! -M-3.[M"9&J=-@M!.2DJ2WH1<=>06FV%VD`[ZVJU>!X -MU+V0M9:]]W'>;W(['<76W-R[\,X0M4/OEUO2ZXST"`(4`&`/_9#O[N9AIBHF -M2\.`ZM$B9ZV,,P%N6I6'<'BR75*6N/B$GK3$BF?G^6,A?E)-%Z3]^^$IRA^S -M@>B/C_Y-S1>J=)0Z4GF;BIEB7B*UHB%2X$$B09_8^_1%+-7O8*?8' -M^W^,M^%*]:X["]ZJ@,^?%CI\:"BZI7BIUPHO*X#U`=;.4NUU91)C-K3UL=TTFC04GXMF54]R(;JV\JZI['CFEQ;(E:*SB]*Y3=TT"!;4GH# -MB2;OYDM1XG*N&>1-0*EX!<0R3%"(7#+@Z3L#73S;`Y.B@LIZ_C`S$7!O%21& -M[[L*7#!HKZ9$91_966SG+SS-CQ,XE<"JRBAK_V<[B0@;+RF"8:US,RSY."4V -MHTEQ3:W6#8)8JE13E.S)NT'#F]`8@GMPLJK&>OCUPY?)D8J];-&6;YY=\O_W -M($)X&8)D^P)*484L13P/#])U/\P(>37I8UWT-(=MR\"%EPYB84=<#.Q;`8R+ -M2NH'B/NV^][E3%H\^XW6`+;AK@,8ZBH%&SJ\VZA.W^K#NY%5\IV37)6ZW:S! -M2@?YQ<*!7E8#B9SF`^3$*`-R%^GF3EG>OZC4,^'FYFJ5N157+XB+N3/T#+PO -MMR!-I;L=>M7N]N9`F7;$Q-`OF_X3C]$0[ENTV^'"`S7OV(W-]GEGP0^$:Q,; -M(?C<I1_`\47+I]C;_+Z5*Q+`N3B/%TS2Y$S(H^>( -M-)ZH+OV9QLCE5*E4LK_A\7\MB(G'O9"ZIGQ9F7:^"!B,%U1)^!_9P`..2BM] -M"&?2VTHFT[[\J1_`*C4N!T3O'+V<[KR<=?FR[<(HX17ZG):O5GYQ31.WN.A? -M.R`_>AKE18@.!'A?([RJ;_V^N7W>[!J%T/80HW1V!.+X6_.4M%6;J&1Y>_OX -MK`7Y;*V&*AC1['5*C![<\LMV_U'4@FW)^AD_QOG7/'1)(UQ$2(#/?TENS"W1 -MO8LA[+V\)*UQ)WP?FY24'@RM0]1PKE=2,$1QRC=%/&=VN+D:L88R/&4[02Y) -MJV]V*TG5L&N3MT8=7<=1BFBG9SI3%$`//$3:CC$S-\^ZP:PH$?PGN#C+S:IN -M\YNO840Q6T,91%M4+^=:@[&@]FV\MWL8D[KK85R:):+YO%&>'U9G'"^8BPC6 -M']C_#`)V<#"KVGW^Z[8I!KY2RM[S6NI0-/`?PPNLX#8&`,'M7:FH--WSP5R0 -MLD?2@@>N3-]0+(0F7DF6*IJ`+A+\.4<<:+/+UA90\YU>3B-^.'D8(M(NR>,)"+Q?RKYO(TVYJNW)+@H;&&FV$V?\# -MK/AB6\*1(D@?,+EL$T4PV[QWX.,?+J.E6DU0Y_9]3*9M&T2J:U^LAN'F\0C& -MWG$H5PAR9E8YIH2Z0J@1FS([))C\(E%FHPZ/JX*$7RHHEK -MV"UKW=/4M<-Q?]=S\LH\I/.ZICD",ITO./%9ZHQ&#^O.,WG+7ZA -M[L.#YO9^:P$QW)J>\&4)E-7"H=V:'=LQ1,]NY.R5M]QT/FH^6KXM+[JQ>3=_ -M6EU4V"'[$+RZF\9CO0+_GD3I`PU(CZL2C`OD>+Z3`HAOPHP(_J+F3U??H;MC -M,1Y,']/'SK'+#(:`O&)W94O:./&*U8Y>9(/, -MTBVR%#G?XQIX7!A`_ZX3`(AFBYBQYXA?[":&#$U&!$8;R5`GAPFC1,%@P5Z) -M$(,-79'AE/*X;4SH3B-;#TZ9(C5^ON^UJZ/C-%4LR?*"]$>_$,G(']#S$=/@ -MC)SH4)M2?'3+\J?8H0!VAE.KFC[(=@L4J?N)T8>AQZG)B?0N%?P(F/@"6E7( -M<1NL$+@#J4XJ1F[^HDY3'?'J#\E:[<)\6ED4Y][=5XH!*%I<6LF1B0'H'"K* -M=E'*TR_P)K(_Y?`N.GP$O';P"^;-7K1]C225JUI&$]ZJ\"+W-#$48\T%$?K( -M1G,LA&)#Q4-7MC"-#(DZ*M2;7.7@?FPF20C]D;9XEX`SS#2EK?R.8B1]TFW< -M_)5<[?B65LC+(QHFOD1V<2JU[P9]@_-;"];N3F9N"J&`;CP)7XUI9?5G';?R -MTF@:6W0#.<+(DTN0`[TV`3+G@X>X7?D^'"1P6#K?X95Z?/+L2<0>,XA2G`V' -MK5DZE8\$V1E<-Z("V!1D>+EV?G!L0A34U5.X8YP.SWU0V)S;6A6SYX0"$9%9 -M>`^<:B$'S+RO+PQX*,KOF<,L1NG^LV]>=3P0032JN/YG`PRGV[]TV`^Q3X]% -M0>NY@'JU1A\-0$]!KQ5-]E+7@9KT^1P.A\E_/U'#$7+-8,*XCIQ)SV_5\Z<= -M9>0D._W!(_-L=YIE#$,44DV?.T`VPG@O.'>XEDD6(:,09?]&6,?D8RQW5%U1 -M8%UB-8\KS*<12W-BUKGZ8H"55I*"XJ0.`&6*:_TGD -M=AP8A5'GTS+W_C;!9(8]CHI+$%RKD^2]\K0@%S.@^+C!`-;,(O4W:=Q7C5HH -M;""[<>>K8_S',!?!G*B/6SZO+S!5'D!4K"L+.AM`]'VS^C-PO3!KN&"FG-^% -M'Y45W?SWZ/KS=J(\*9-RS+N!17?(/.,_XHUGC[,LWP/5+4[8A@LSNIX;R4>^ -M2[!YTNXUH(L3_NP-YT+BW]IMMIQ]D;24JA"7R]?=*5^;*\UN2O&TTZ+RP`+4 -MU',L2`YX^-\KU)3MWC,<5"F6Q#^R4C+Z(X(`3%V<9XSS9P'8II_]FH@SNYB]M -M?[F(300!X00+3`3RRJGU?-=\,Z+Q"]6P`DSMBXW""ICP]3-UY5,L2]OGJ&:H -M]HQU*X/@C48'U@Z)U.ADF`8QYI.KYQITDSY9G>(9[@6\_=$R8EN^'(PS=5A2 -ML2,O!<(D$J'&[2&8T6`)3-OJA4GS$8LM+D*>\!+BCW`(D>DE>JCCI+Q".X_2 -M]P8Q4RK<,_?ENF-@MY)G$E>S&B_&?1LYZW(97NV&!E>$\\,"0@KCXU7!A;=? -M;9>&Y^"G-J_3ABK?6&ZF(Y=RRDP]G\WJ38=[L3!/9-B7NXK\F-#_PT%`TOQI.TWD[([, -M@#AP)7;!?_`A_C*2Z1F6$5?4,)R>3GM8_UV?)8"S?,_3*F1[; -MKS1WK3ZQ,*&1P7RK]FR%%L&_<9CFMUFZ<)EK)>U26>SMNR-B?Z;T#U4K)`(V -M,#JV^JG*/S75W?8SA%SIJ7ET8U-U$XINU..FXYO4NKQ!I[$Y/3RDJSD2%C?G -MPD.8=R43GO%UC6>R0&'U##@D2]ZXH33IFUQQSPN_Z"MBWV3?>UGGH.^4GB:F -MU5G@HQ9,(59+$VNR/C">.:W]P)9,+"!?+O`E"5R-)4[''+E[VX*1\3LO$Q51 -M73Y'+&_>E$Q=2'G/EG]]\'^1IZY_#_8%O>Y8_X&`J@CF%5_KC#Y=+ZSJOE*. -MAA%IE2!Y'`*`ZT*B==VD#N#,!4[/(PJ`5-?:!5,3$I'EF!DRG+Z52`XIO$'( -M1[3E0H4$1KLL_7TX$&C?3[ZU-&2K&R^&4C,)O&$``8<%`,_.[!]J\B9`[W&780;EKI#]H@^"`M$R6F!J$SKE%$H\\=;'#)PERL3K] -MGSB88R0D6X_X2APU3OD@'$N#`,+\]5&+(,\M4IVR7"P7>&DCMHDPU];'EIF% -M%,.'$@$NKT5Z-LB,&&9S\1FHZ4&$G+V6!UO%!E+3()=!H9-H`'(YB6KZ*52@ -M4A]'(I5*46\XV5FHJETJC.&LQ54/">C`.Q/'T8P#;#W[E@;^>[[FPB-;KD= -M-`<$@*,K*&G.BU>N%;K^/;M1?:RF`8TQ)'M8U@N`NM&2O -M/4'PF30$][A;O(<#W1K/U4OVEN4[6\SL4/9.2E)HW$<_&YT;#L7ZG=9ZK5$POH=>O*C1B\H!(VXW$#V"QXI>AU'RHDS0C?B% -M*0KVSU"+]JFQ'#ZE+>=D@P3G1CY.T06DM -MTRLPMCQ7_$DR,60[&+PT.3)K_JFRQUJ(.9KIHI>9Q?YRS$)]$]^0D"LKRLDD3K=1 -M2"U2*Z0[+NQ1:X&:R`P72A7:HB-C3PHPM12`B?$>\>ALJFO2D[]5C>Z&!0>< -M$V8!`I).QY]ML]T4]>XN(R?>IX2CH8YV;]NQH@,O4T?V-NQY)BR3%6^/%(6, -MGV"J("G.VYH`?QRV?W_R50#16_]QX/[I\D^4UMYJ5\)Z;G.@]'7E&E2(:LJ* -M7=CT3:3-YY8E%%S+ZG+5?-"(EWXG/]`21IIR="H`%9A&^WUDNT)H$QGKM&:H -M-@BEZ\6G%JJ0K#ZU67(JAMGT]%EWC=P;5&H./[*(W6].+';XH_.^@%9[K;Y< -MJ6:R=2$@F%*B,1_+0*C(:%WL='DODHN*'!$?M?<6<2@UD>/DNBW*LQPR%..@ -MUGU2!+EXUSB+KU8M?(W5R0P0N?S5=T6O"-C#]N-T5TN.[!)!;S>='U>4=YN< -M1J826#5DXB"BG(S';W\@BP% -MB\>+_4B<1>),*^#/H1Q5N4E<0JZ[TET6_B`SEL(7T4`RH]L$3+(:V6XX/GX@ -ME`'2C0Q?(0GKSB,"D]0X1*X"FJ_6_D^Q-UD$"N>H!+R0R\+R,4ZNYQSNV&L$ -MB0H$ZY9"-H-@:*W!@.5LX2PC%^%.32;-4&6'YKH>S4PMQ&LZG)0:4Y:2FC$. -M5E>W(0BHXLK6-AK34?!OV'CASH/J+M*_W)T!@^SKPIX1J[82_+7#YSN:U\:3 -M9PIXFHO;,LG8K"^8`L2#L[#.&ZWM!>0+$9M\/&U2A)Z`P&,OX1?!UYQT\:8< -MEXW[!U[>#%GB:ADF5W-B\^([BFKLN2J(,J[B?U8O1@"]@AIY1"GA:GU-594R -M>$S(![1@RV;$*B!/'%#N?3V/P+;(8/O/?HB$4#YX1//+,Q7U5E0>;(31!*VL -M[B5'I[MQLN0654#EP@($Z-:RAH$&0D1542B>+?0Y0%;YD,B5M^&00F6.9FA, -M(GPN@C-.S8=:ST@W5N6OYRXJ!`80U2N -MT%.`OFC!S+TM)\&Y*(M5J-;/>U(%>5V-U/0HP3Y<19V88/I*LQNQ<7=+I'0/ -M4K?$\UYJ8YS-'INY52EE51?65\I!%P5Y%/C)ZO@4XNBT>-ZIQC_$(^M:)H;3G,L7GG9O_0"A.M0:*1O>]>/H^/^'K'5W)KFWLT\P\C__(!(D^$0 -MP1$-^)JY-8/&$*L@OI6[SS--A9`4K.IF`1 -M7LBR\PP[GR2=8UR03:@,#=0/7WRM^H7HPU'QVMQL"JI8=-<0KQ-2PLTSS)/* -M@@(C:D98IP<,+Z^+)L%"H]A`&A-1?H5OZYCJANV`8@):P1_N47.-?'L!VS&U -M4WW43V[Q*UAZW3,"XY(FHQ[AK+55Q>(9)*@+4PK@J>NELLJO'7O#G=#5MN%U -M-L59<>0-0)@7P.142.D3M_DQLV/HZL=HCB^&K4C53?I!I==`:=PPK'>?=-?@ -M1;BWQ0%2]J'Y_@5QQLH.]OR?&,GGVOYU22L)=^:H1,N115% -M8(#&,<,@J_$?%.7=<@C09K".]3>VT:,?B!-XY!<8HAG2::"#`5H.B$QA6F?^$4WSNI'B0ZX,\7/[W^[5IX=R,N2P04""4BJBVHL)%YT`IPHVSLCA;SEI!4]K\@97>'V-"*D)4RW<)14M1<"5LG2,'_?VB&N; -MT>=J$LWF(1(1O2$9ADNM"U<9J&#XQWVPC.R7$2X;TC-?CCU$O*J3,B6SKQVS -MQB!1N91_6FI4YL<'O0:6\_#XM(((\8?@N20_".L0Y@S11+]\>GUQ[CB&?$Z! -M:,^8NZ`)X0Q]U#=DOW-APQ:K:^K]\_U^=8B,\@F;4V1^`_<8'3UR7Y/H3KBH7. -M#_8(XZFI]O>[:]8(CAH'.^GA=JJIF%B6%YS`Q<<5<-*2T29T);J)CYPHA^6@ -M18\ERJ4W^W3^U,"AXZJ5PI]1!=`B,XI^6#Y6(1@B=9B`4E$XZE%[@[3;1+G; -M5%2,_QE]MI@*0COT/1"0=0M.$)[_FOZ\O!EXP@AIP9OG`T4;&1JT0 -M5OEA+WS5,:7[,[8'98'US@`6B4@CI!M=##GW:=D)8N2P(Z/<0Q[]_K.-/&]H -M4R`'.]*\EHM)@4$?BXQ;FGWNX0:+),,^NM^DO?@'YE&R\D`3\"\_QCO\\Q*`?;^O!\>>&$D#$R%:951`]P__"U?1^0HV>-3<5I^1.@Q>OU#JK -M^GIZFHS>*[5`CCV4J'8=N/G.ZXAW-?XU@R@0.1,5R:!E>W2]B&PJ],.'98C! -M/8KFTX($\[.4;MB,`.-36W'@->21#FJ!>I3D!5\\/RKGS^F;8W7S2$?>15%A -MB)\`'!VU%)LT@YG1`(:?Z^2G;"'D=@D(R+3D9>$*0Z,;390/A[FK+_RAW\5;UB!!EU)_)AW85OAV!-0ZD4-7WV^<%F&N8YRW;N0P -MP1#YL.LNR$O6IP^]$53'1$7%_N*CA#U42.V90%=*F`G'1N7O!`NFQ$Y$%)F' -M,B:'?DN5*2G2A(IPZ#1E^57[6]MJ6K@*TO^F"2XY2C9H<]V+]+PI186M*;=W -MSE)"ATA%KG)ROZ!!3VWS)7=M3D,+Q#ZKG#"GS*1B&8:(W^WF81$>C.47Z:83*MZ\;6)9AY3UN+P#-5N-G0ED^TJF)]Z7JJVP]92 -M%D6*?F7+([!SUPFH=,WZW$0CLX03#H*E=LN'"MM:I`DSJ2C88U#58E/2](?WJG[RK#TX;1L]B^B8:,,"B -M]%ZHFQHWW^%UL$8/':7FO;Q)H]NA+EI/"DTN-5?0C1'R;PHWF(J0GF\F778$ -MG7YGU!5(!J&W;B*[M"?RDL-"7`!'$SE?1DTQXU);S6VO" -MYG)3=W9J,;%BS&]L9U!OBQ/YRG(Y:&Q6*Y&:V#DW7"/_88VAQK'E`\%QRGM -M3<:/LT\/:CY9A&1+.!=VZ(%JY&;MYZ+>U>1ZB&FVCA0-4JGC%)XQ[&BL%64@ -M9)6!$C5GA/7R!-^JU*\I.J,!/]PM%F;XRH\>2I6.,9F!I8^2:A(1N1%S+ZJM&S"#V[=B30YE9 -M,S%)@:R;.AWB$7V>>L\.9^F7F*30PV]_)98RQ'Y -M6H/.3G*CLG)(1LW8`/_(SSL)ZUE#2VFV`9'<561C986K!S0(R_-,J)ZX-T8I -M.@)(U-Y(.5LZC\39JZ-$\0L7N/,UZ?O11\G,Q81#^<@OZCV+\7W?@>>K=?L?Q<"3L(!+G@@X9UK/+W=!6".S@+TP@ -M:>.#O>J'V$8$[8ROJZ==B5][!XPQDXS -M;!WQ*.V!M`R8QH/N#SBD=:V:,9JI1ZTWI -M)J!5=,#T7<9P9?H'E6JN<:3$0W8?/>2(Q'JVD71J_:TVT5M'A.`/\788M`A\ -M'\=L`G4D&+:W6BAB;P@OY;MZ]-[!URP)(U4"XWRS7?L_2^#B'1D#R3%CD9W6 -MAE2\:(5]&R>/J&.Y@9U5'RQO?VXM1OEB.D\N;X;UH6)8^(H1=7DVX[":R@OW -M+>,`[(1^8].(/.FCQ/?9''-L>JKDF$J-@.&VS1T?6=;GJ_G;!<%W$QT> -M^DF^CV;M%?7O"2Z:`)P<__()#P$R^R&@-`[.$NX#!5&\`<=RC1/PG0E,<\LG -M=+D`&C0TFV/0"`%LW'.'+>PZ*O4;+H0LKW],UZPFP-1082F.^'<7O(2Q(@75 -MZCQ8-HU`A12@<1-W-W82N?5K0^!?3_OP$H!`5V,.*_JU3FEIV5HP$8/*FJ_& -M1GR.5J>"#7BP2IQ[U@XDU`4B7T11=]_3T@[4:00FP_X'ZD?'1YRGF=T* -M3SGL_V`9(!\#(L -MZKZ.BF#YO-@>-J)5`:4N.VB_KKU,*M>$XI0=>R^L#%MBVAPK*.X\GV^DSMJ%G21AB/SJU_!9^2&/EM%H -M'#0QA)9^MSF%8:^EANEHK.LKL/3Q1L8<1&JMV27\,.$9/19&E1/KECI4#/GQ -M][PQQ,Z'KG`@TEQ@L3VF((OFD^3]8;^M]=3[V0XGXI`%M9!\(*)?/`0$Z(2Q -M0L)K@2T+HH%,!/`31+,6S[W%XZ^$`!;(#:TMU1_>9D'&^_#5`%FU&P08SV2% -M@!:P\YQU4=2==B=BXXC41LRFSPD?FZY4,&2\B73G(1']PE^27+]I9WM(#-44 -MAS\I_N8&BCR1\[@^TF*8'2V.A07G'&<>K)%+`3A:G@Q<."B1PKA/EUOI]"`% -M,\^(RW35,!ZK:90$8^BX2=R&J=JF=4KCO^)^(3.5T,L!X8KVRE4HQIHY#XJC -MA*(DQ%`'ODSU&+Q/,0-%7K6FXS?*-=6AF:U>!QXH]1OW4VI9:6IOVQ]%2 -MY9^[89YD82[.5M&_-R=SAW4V,5V9#]F_(&;J-TZFKI?(*YMSWT2WL:=:;>1( -MQ\"[A"('@S)QBE<5K!2M:7&!6#C-4>QN)E>688F^M[;56^?=)'IC&9Y@C3PL -M$\!==,#ADS);M;P/Y7FMN8!5OSOW4\=\?B'K@9+%#>\[SH.3D#`-/3RQV@9&Z)L.VH,B?Q;&\95#";:6Z -M_K0#P'4U>BWE1M>U]I`4:<#KRK\*VF6Z,P9^&:0;\_ZOQD"JLT"DS-@(\!LFV]RTUB\9Y?IRA+]RMX0\AI:?AYT\ -MB3H$?-JL<_"3%]"H?H6K/_8@!>/Z-LK:0CK\HQ!.*#TF8(L>Z+:%4R3_KL0> -MYF[]*K:VMOYFA^0]0R[E?4[!RYV/*2PWK+K`Y"^P;TM=2[X!:T;^AV<+T"3T -MC`],"+V?$/Z,\)T8_%MM5T;=8)Y7`<"/PO&NGLH6(TBVQ.V55SO9FKU7L4AY -M=>#0=ATQCT-C>VB`^FJY@?"BD'@.UDD:C#:J!9PX*(^@-@Q8I:^S7!22JA=< -M3/7=0Q+4M`";"X&PUJMX$Y34L,.]\_YS6>8WI>!)@3T")\;$K#/[O*/_)M"I -M*'?RRG\410;X)<_$"VW:+W4ALO0_43GC3==!?+Y2`BV?S$4H]+H607/O@G<* -MW/3MZ>^]S_F*WQ#XB>'9HD.R9=UF)TRI+PAV.>:*HO"T>BLN^*P["?-HO*^F -MD0LR_>C'B0IA:[$:QL3&=D9I1JED&?$NV1E*A<>`BMV3D(7$!_S$OPE[@*4G -ME:21!\:[]G`38'29*?:H\NE]*:T%&7@4BUS7R;_V83;=R'UNYGAI*:*33]]9 -M=7=F!`@#NODW3D-.R!E@R(:EUMUA'\6X?S*!LN0E;)7N(AR[?.-S,(-)6VD: -M=T\UZ&<>V[T9C491LV#1IJ@>UI84+L(I2H/FE6%D?B;6\=\&C3$&%&4(S2"6 -MOARJPJ+XSHZTBB?U6$$NQ)"'8Q]8>NQ'XO'DD-1CZ/`[)Q!@6+OUI-`SH_9_ -M^6*9:[Y"V1U(32S>8B[4J#-9DZ52X49!W?*0.^K,:_Q^LYV+SG,KHNF2O -M;OL4N>\_3+%5V:YH/QL0\&^E/'E^&NOJ6LJE[W4-URT.VH>5S$EP,=;`D8(_ -MESSR%Q0/57!T0UC,&_*E[96*]N8V -MAO-_T#"AVSIBN\LX[XQM'F;QRO"+F4-$8G@ZAO&CUC>9ZH<06XD81M`6&N$# -ML]KF)+.GVW:4'K@&]8],B?)O^T,.0R$I]O79+:)OLN@&CQ^9+)8Q`R"U[G]_#>RP14<]&YQ`!MA^2:$>PW!79GX7H] -M?].,]0V5'Z8[^-]-FS_G38(YQ`*PF[":,(K_F\^Q]N:]!4DN.O.FAY9,,9/? -M*Y'E_-+OL='`Y/+1#IUI^B*C#,W^.R],E^N/LY2__;CH/RQS-T8/(H^@(_((A_=/R9H>?$&;YY)NC,,%\NLE2BXL>UNQ'3N -MCF;;I\U3UVG#D5`&PX]F7@')C.R@O=?YS5-G:?>/^09',/^*32?\&(CU^.T4 -M*,>.8[PO6M -M16^[H4RNFG#JZUT24:_-FE_5!1B4LKHG"F:=2(R&SDPVB(V&* -MJ)/O;/B5C!/GU(**T+13`3ED.9M95C%0`I;+0%)M:T3D&X""R6A[*V\S++BQ -MVB%\$//!$`J93-(I$W9A,YHKO2G%#R5YY`1(_4QSNKZZX<898>;`JC078&_7NVC:'783.3 -M.0K?\7=-1BO$M,F?0%,]!+X8HA$\C2,B30C[C3]8K;'UCIC2C+.JY*;TICT3 -MQNN*X4LKBR:#/1YK.D6^*599"\_8"W4`+^9+K?2!TS>_AE:3T>S(K^TFZ^_Y -M:TDJ4;MDLO)"Y/SBJ%`,S0_?0@4P^>GZ6XMTW9G[GYPZOO;SS-50J4IU%+8& -MA(&2[IS\@F%@=B*B?5/@UO@["O<-JP&(?=HZ-2OO:F++W);7=B"H1PQWG9UF -M,3A@X>-TP;0=^0@#9^K>I9`79W,]V:&WTH4@2V2/%CC;?3VW(:7^B=(O -MS,:(#FN%=0[S+C\)`D8D[CA[.&2*B;$(??7C;CFKR -MCW5K+_JH9NM>YR;PKAZC.?%32N$S*7 -MIVT-;J_PPA?2W!V&^Y2#BNHC-XJA+6]",+*,&6QH&3[H\:/SR.A5)(.FGGUY -M;B>YGY&FP3C)?!CJ^(B.`P\+"E#JBM6O$/XI9X^G"(_'_T?+!Z#'H)1C+XB85AC"=>]Z'O#]+=IM`SI]"!.C -M:(?%A*%XLGCWI/8WD$[#<8(GH!F -M'R=)MIG["1!_A&AL=81M\>(4Z]=[B(=!CC69O<5Q['^$,G&U[:*0H/X#< -M1=,S?J-LK<;=ICQHC1!S02ME2L%:YC`,S[E@91ML*>OZ"4V3\((/0GEQ!P_X9$]J`5F`!8( -MRDFE&@>F7818B5:9&S2>/*R^YP(FK*+6+F3U`Z5A#W#8&$8_.4+X#I)5Z>FN -MX![P.?X[9%>=(R -M,U"NE*PIW#@W@J`$9D)EQ-XA^4IH`0)RKC4"UG*QXV,[7D+!LH*5"5ENGSR2 -M+_YF10NA3<(>&")XO.VKVKIO=N&FARP3EUGM[?>(+I@J#^OY11^(YFNSNG<$ -MMUGC312)WA&:V'A6E.?OTUTEC=,#N6[5JU7U)U\+*I3D0.F!N':%IC -M(;HJ-"-T`.@8;[,BE'"Y/4C>OQ%>##RASK"9(G"'?XTL9N+3PP]/*7YM!WF1 -MSE&(.A-"!V!L1B_61K;A#YI=UEU91!06`&DF./QV0M2QBFN3[#G$%-?N9C^M8;Y=U -MA?'V#V8I>&9:\%<\QV-CSNPN^MJ(A'IZ:.Z9]&-@;@K5+%GTU]>0I0-E4@H. -MPZ,@AWS20F+#`]'8Z.E:>9Y.LSN+N;JQD3WO(%8YS4M% -MRVPOV@(>-;^E\2O\FP1\?2`\O&?1;EPJ]H&=*RA*7<7SSSN,;=N-)+L^_2XA -M0[^R'N1+//%Y"#FJR6P'&/L5#A+\V72SQ,>LT$I<&5@=D:0775M;YU??H9/D -MH(@WCRE?)"1ZDB%+%E.DQ6>R2E8#J@6KOR![C9HQ,J'Y8^'Z6OK^9%D9H'#T1;O>2O-RK['?.>>R'LT&?2"U#EM/(KR"J,=,O -M4NCXO`"PLM)S$C#^?#'>F.3*J`\LX'Y`.9=2G\Q.`4C`/PP7;JHPXMZ3,KD; -MP%Y"0/QK]?S-4,AB]4RR!!0&6;O*0*TJ.+,V'Z4 -MO2)HKH;4=0IV:=-O!^--&&A7[T7IDMUF/=(IEQZ#?\M.Y!3NX_W(/N7Q*-._ -ML]#B\'F9$P1@_!`/`O)H@.U!UA"3)NAM8L0IPB'N::GJACDVFFY((B3@BSL_ -MG*V9%&4GAK\N:Z9]257I?5WQ65#MD+P3J<5K')TN7WW"OD'T91K`'D>-9#-' -MO75&UW>V.6:&>/0` -M20PB*FD@5HL#)ZJS#[5N0]N[!+IJLAL[?(,#R2F`^-2]DG/JH33S.`5W;<+YCO+57\:VIJ<5!X6>N;'QNG:3W^2/(*`5B7SZ -MC.5AO5T,2D^^)C+-+'F;@'PJ]6(4-(X[$`>W%043HX,/I4^W]Z9(XU",S;ET -M&`3LT(5B$"SM*8ZQ[>-W&WBQ'MI.$&W:(BVFD!-`,)DQ/K#DYF?^O(>;)D'B -M0CG,Q\-_$,`W]U1GB9]`/J;UI:`MQ\:_G:/;;5PHLV;!@OI_-T26G_Z&=&0G -M6.4J99L^5"9G6TK)KF.%8/%#WBAD5KPUEW$K99+XY)D%(^_CY'R6_S0#SDJ: -MX:(:$/^NU' -M,S\<5D%G8G0Z#2"T"?PSQ77P:J0#;[)\Y0OVAV(*203=1]W$9Q^HIRA$IG,2 -M&]%[_D42!&KAJP1J7'GSMVJZ@,'^F[8V:HM"^'B%N4=N.7D>I^C<.DZ?%+_W -MSF>!E`%1)R)."%$![P?7]F+G@X$%[=.3B,`2;&H'I,DZ=8]Y?DMKNF?EO4^L -MIWVD!(GH!G"M6!:6O$?ITUL3,5XEPJQDT2&$X[G3*>9(CUI@&FWU4`8%M[M" -M[/-YNY/\_+>>5_:L0RQ!?M#KVD",%L)=X[X(ZK]%&X8,"C)U"%#4[H&&-3%< -M^'[J$#%QDSZ#!MQDQL0M]DT:VS'9PZ-/PDL3;$D%JC0G9^T_^3H)#4N6EG3$U."E -MR`->-=4._[]0K,:R;/<76#8@M_RAB*"+FT7+@B2S&G>C!U]2M)E02F0'"]!\`'HH6-,47P!4XYY.NKLG$-L7!=GI6.!'<&&3;_JP81JW -M=$\1^6(:WD5=B\HJXA(7WIG#-]!4J_1N;9Z7,3B]*SA6!]SG^PBC*7R2X@E5 -M]X]W*UUAQ'/4/)_,D+Y'_%U&_PY(,AY%D[K\\J2:A4V$E)S88@3'I!8/KZ2C -MEUR6`/D`$$1BIIC3G%"[G]![Y3+SG*$6DI8Q)QA!BF!3?A$73A((.90P?"A] -MHNM$U:E!3ZM3\K`?JX>BAF9'K<+U9=V?/DM"_@G<6FD#/*FK1;25SMKV[D(+ -M-S$&$0'76BS#]GZ8XXG#[8F8TZX;G2?.<0K47-:K[.W^CW>ZHI[1$#J]XPM? -MG(W_0\D=DC$P&4:7D*/"%5SL;T'L/^"BG@B-_:1`8\L>+BQ](:%=IY;/S>63 -M&1!@>H@=3#!B!<83PSTL'!\?N;J;R3AN+M,M9LHD'D8OH/3L(SHJWT+<=_DC -M`=`,53"NE"4!@B(O9?1,877$J9^]VP`?:Y+^QEG"JJ=N2[$@C*-\M7TKK?@@ -M=!5R@'M^.$@P;#1X@OI8]#8O0FFF`A^AE'89J_9$Y77Y4/[ZQZM[3L0C!#&8 -MF`?FQ!V.UX$46M:"1/+42IY9`L@7$3R&D'7?[?HFI@3G1W,[\,2X23B)0!-\ -M3OLISZ71OLV;GSEPM6NI1!'5R1,+3Q#:<_KDH<2"$?,_M\%:FU0/(LI6)#HI\)BJH,"W0_[TCBLMZ:^<5>ZDR9PX'/7.*;Y -M^G1G"R-H49[5Y#-[%^B#O_FJW.[>D.T5XD#M*1\;Q.^R7.*PV!5?07I-&4(O -MGLW3Y0FIQ2R78320Q0M7B#O(R-+SN\@YSL<^4I'.66M[)#X*2H7RO]!^K@.Q -M]Z@K/W3X((Q'Q!L=8B8WQ'5H9\V0P4N7J).M.<_A^6Y1^R`Z'F!9^3(G#'UC -MZD/+MX1N`0%SFYM\N+XIP?PA*,3`J&Z7GN\NS0!,%Q'_D@!WQ:>[H3-UTLJ6 -MA*[EMFU_U18*MMAEAUZAE-_:U`2EPSFB((8GH%8:!O`Y1>CM'`W@+JO1TE!_ -M44+ZE<[@PVVCOIO.QG\G'!B)^X^I@WFHN@PUXWPOT?LD/G/%`#A!=*ODB_4E -M%]4=AUFD>J#K^52A^JL8"L*NC.(JJBM+1D?LO$NRZF#1[X$CP="Y;DZ*RT6A -M*Q2GZ.(XD$#YQZ"4DB)W/]I#2C;8DV=_*+;Y3;S*7M#7@.X:59R3AQ17J2D9 -M1./V$S@D[<^<*!M@8!2)N\S202E>1L2.?M*(4DW\I11HB5316[V(?D&A@#2% -M7.O>[//B1VN=I5%)L]+UKFPJ.]O:E@SG;A@F=K9`N\G=6+.Z[*J]_;EP:$?L -M[3N3"V[;0PR'.LHR=QE-M!$_G&5B=E_ -MJ?"L+SJ)XG&!"T!@2$'H5ZH@8LB/7AWJLKM,TH5!@E=0DB7(/):QE!^,$L[/ -M?U]:YJRV(&I/H=&F#.55X8U9>RZH:KCH9\O;WJ%WML8V7E?T!OY+P]EA4%#F -M'I(#'D:Q7P/D4I.F59MS`!*+@>OFBZC,S::;; -M4E8Q-22+$22XSMVY2V."I!4$SX[.R#IR\9IWU0'(.2R3"3:X+%T=7`H>ST)? -M`L*3@9(%X)F6M,I01/I1.SPOZ83P/"A@;.('.QFD75R/I0#&@^,Q! -M=S)H<*[<_8T'+8S#2$.'%S^\AH"8`96'(&7![(%P`D\.7I>?$".#+HA[PV!+:+.(DU`J.E/9HYJ1TZ0X8L$U24U -M`UTY$$3/MO(V7?X22X`]B<,6-W"HP]X[/"/[XH&%K_ -MF@@(N;`WI-1QB[@1@?]-E?YO&337'E@;OI=20XI-6+U7LE17`7'!7'R -MEYF*P=0,VC?D4.Y?U`:@,\1C*O*[3,_T6QGMBSJ]B:P>=\MN9-T..SX -M*6FR,R?MYT7I/`%Y^SLC1Z+Z1XX\A@D -MX]8NBER-H[Q8OWLBUCYI@&@?FBH32: -M=)`09MR?J*BX/:?C@YX[D^P#[^F55VKEQ-P3*Y350ZQ -M&A,INKG7U#M]0LK7MRC'#L[#HW]7#'7%E'YO$*8'%+?/?`9E)J!39\EW/EIA -M#FLR1?OJK*)*1GCW4IEE5%13>7YR4V%3'L;I7+4W'95;X=;X[6=[LCQX40B6 -M=2M)YO7O"(!1_RTV$;K4?8P8*#HJBM*K+&W!M[X2_#]D>Q=)C2T3J2\&BZHT -M5YS3$ES6-;,J=RNM^_10?T,W#H_JQL/A2LLQBS]1+74$?%C%O#W'&C@>A=_X -M."AQ)35 -M3?5LT(Z<,=M*L;C_Y(EQ_I#P0R8@/6,7^O!_`S86=]P>?A)Z?BR7 -MV"&&[39?X+3W.W$,RYK0Z]YI4SN8\#1,-!=1R?3WP)/:U/D,/9O!)`]EK2%: -M8#`>T-C>P<_]&&J$^TJC>"6/EOR/G#UY&/'$H*5*4R5&E!I@^O0)ZW(8 -M.!(J7;>%2;!5R9]K(REXY$U3>+7(3Q\'QX',2]R&7Z\8?PJ8S@]^SAXEA[#B -MT,Y6K[`_N]IL,6L;R__-&[8$-F`SM3E03AOS0P2&_@'I;ST:"2MT\C;+*M3A -M:NG.9%%R5!=DR+`5FT5<@MG8&]3ZT<_G7-3W[_:Z$-*HAR!8PJ2U&KR\24@I -M_!?(P"4V6-C'*Y^IG^%6L]S+"LZ,=;A!Q"1KM?T,BIMP#\7O%QEHTYWUP3Q! -M'&*_Q^5?VD#Y_M4A\HF$X!C(+WJT1J@;[%70K(?4K^R01-A3^I`L!2`,053)G0V4DS<$:PMK+Y9:=6TZUK%7'#J53:] -M(@V'E4H@'Y>SZ!96N&:7KOVVF0YFVMYAN?46)`1Z8U]53$H"CD%'Y/%3Q7&; -M((XF3R+W6CC]G=_!X/FSSP(\@/5*.NF1Y^E-H\$KCVVCW#%Z!LNO/?=_P<-+ -M"%`Z0&^66MB2J#MO#I7^V,MUG/?IX\1QX1*TY;N^A_(%@(0\&V]Z,WKPND^# -M4&_J6PGA?!U7_%F'+RST"EV\\`AZB7O\+"D`4.HK*BX]L:0CWZ0L\>BSP82; -MFJ#-JDD!M%;)[WB&C:#+6,'0@-&6+JC`W=Z^SO`GNBC&%+Y)[YMLL!@=>?CG -M0B,$@[@<1N25D[)(9D4FX6,@<,:A`GEK1X-LOM*5_&HSJ-G^+WE/E9>>_A+M -MMF#F5&B$N;Z9L#,+[8S:MC5!L0H[A&*'6G`3&W&LL?SMET43TT3AUR>,K.SV -M')NORP:D3^D.>G3H"8@?%G*^ -MIX_C+PV.OV:@>M>@AR,X6(EQ-(1?$:GQ[K`./_H\+*^^T\'^]'N9A=O-]<5:X/1V'*0@*?].8 -M\'[Z?@XNY*@?Z)WO\)7P^^VD1R;9,X82XW*`=3T&-/$)`$W'!*H+*%;IN``B -M6=+R:B,.F)0MQ6)K+ZF&,?O+-@,:&@MR0'#FVF!)C1B-69+/")DUN\HJ>1TQ -MXP#LJL0?*EVJ$'V5@A9#[3KDY<#Z4WOL/X+<3]+1@$N`.HKM_]BSX&%#SH;X -M"P:[<-E*)A4(E'FB]8J^1Z;TO-MEPV6G47"VZ[;_+UF-B9HH9`)*PL6OFPX\ -M__Q#M53YY/6*X#A[^R'@9_>YUK_R+E=6[&MI`RA[]J;+OCM>"+&@JMB?5-#_ -M%YKI'`$HM^&V+H5]]8^=V%XL.8S?H?LGOSKGHT1#WDP_THXWZB>JH"L'94O, -MNE@.'M7M#5ZLJR@SI5$9$"?,[:]*G&0F;O,"N7EMY(H-X/4_JM.!8\$\8"3^ -MATX-)(%Z=UI3$RVW=4!N-3*$BSPW.O]+6E]`<-8KQ8M?U2\X)[N[H$V0(8EH -M)WNZ5'GB]P'I-*O[43A@A%3,?+@6L*&Q)-@(*.WXE#?]5&#=:I?H^[C9P^SV -M5.CBWB:5/M&Q@\C"-/--$2=U+W:%Q0=^H+_V0BCD2$)`RQ6'(>7-Q'K8E>S(#SY+/1=-ROX8.>.R)/%/N&B2 -MRINGUY"2,F$@:&!>>#X%H@&;)Y>M4*2:'O-JU$EFY!HY6#C="X@":,>&/UN> -M'NFM(]>Z3\-UEJBY65RGAI#BCMFI;.QJ.7MCFD9<;ZBM',J%Q<7'-VF(^+): -MUCL1F"3UP=*YAB4WLK:_1MD,<$G3@DKPL79'Y+S_)T@GE;>U].$EZF#+XM-; -MY]>36QEYI=%+KEH_!3UG4`].RKATQP`F+PBQ$^+L),YG1-++WU@+YZK(2$5" -MFEXN0ZHX:/BKBG6CY&Y336P<.3\6WF.*62'(XGJ;-W5[H*Q8Q2$]_+,IBN>/ -MB*`CH5HSI4.16N?6AR0'`:>1LUJ,P:N,[A4R)$I4MC8UC>OK0"C3P#9N?Z^D -MD9T[+!@W1"";*KY\(5"&L.+J$D.FS@<0TG`H#]P8NTZ0F:N__9N69<[,M@'Q2#2%*[G.D -M?F\*A3<*WM9/;`5'@,ZNZ*&F1/3S;J+/C72@3U'H%9>EJI!$U:/2&1G-H%)O -M;PMD4>D,G#6G#8A;/`],FUTRJF12R+\I=E2U0@/L]G>I(9`.40F>[MT(WH]< -M\/-?[3S1#SX]L!4H]1)A1\G_EUD&(GGW-/D-,V^"Z5-D%6`]LN%ZT:#31:!] -M8J(VKX740T_UFUHW:K^0%LU;18EPC2:\P>%.-"O8M0S+YM%(Q!8<(TX4<.H] -M=;^=\6_B)S!.ICHY\5P,=/?*FI%EDR=B;%,NC(1Z"^.+MQ8: -MWK_O_$AUD'^B^''M_L/J6M>B(@GDR\10K=L -M^!O=,H]E^&O_>JQC/M];:1*A*(P+-Y+%%\F4N!*N8DH'R)/<-Z4)2)T(]Y+. -MB2(M4,+"C-$*_403`%OVD4CK']<3`\ -M-5O.6HLKE:(/3`JNB'FM-+>66:C$F&%+R1BG*F=Y2KSX0OG+^\6DPA9K7TD.`F1>,U&`I+ADD/\,V#8_L -ML:%=A,JD4)/2#4^#@DZ0$2$6;*]43*3/97FZ?5S$ -MX=1ZQ]9KVJ&()64YZ#.\B.@A=1M[&N8_]2C#II7BCAB5;U)OW!AAWVMVA'IS -MP_-7\;(S15*YR9#^:WIE8O1LO]10JW#OKL -M+G%+MDIIU5V`)MZ1U;JD77V_(J28B]&IV-1PF^O2V7O;`5CM*2&T]:&.RQS< -MA_(W#.^(]2KE@HVP1&!J;.CRZ8U"RP'7+,,&8>W]J;[EQLU7`1A^H+>+'$[L -MA\?M_QT8+7^2>C;.;XS@5399YO[._=LS:^V`87F0C7*#*I)$,1&VG@;H9?&R -M$&%#SMLKW6]:$_@CS/V>[D;?UQ1E['`#JP#*)C1L,'O[.%-;+=6C5FIU[N\^ -M6TN1J*>_*)+P4:8AKW+E+Z0DZ.X0(.K,;XZ^UMAX>=-G2#AD7?=3,@H>V9PX -M35F,"RQA'"3]4/5F2O%,6YFAA_I?:.0>91>IX)/R`>'/ROM*[0G*^;F-)]>I -M$GWRV+ER(W37L2Z@-7 -MXAH[=Y[&A/L^R,UX46CF[!NO3$)#1X9SA1L)&*ZF4[F^*Q?[V17NU0I7UF,% -MY:/"D<\^*`Y)I++=KE0N58#81\%0C3'N)_L^HD`>@)(`(+O'_JA%E"("<\@T -M\^$/?7A]+^(1,CKO0'CXDKV[<%\)R#'5"@')^8MQR(SG"`4]`R%-,'4<=YN? -MBQ0(E7S@$2$^\MAL\_B6X*>9,KD14B3FG_CJB0#R?TIK`CVQ&5G&:[T -M#A/1D_8Y^O6N`QW>.+OAV<$R=,U+%>M:@\J0UUX[W/QX4_$0OF7AL+Y7-CUZ*LY -M'0$=*GA/]80M&SE@YLW6TG]-DS2'F"Q[D"K<8=?X2$T,HVGJ"E.65$EH`3N) -MA?M(:6`>#!WX8;^`^TH#5D!8YDX'HAF/"L9DRR107F40PJ0=!@@*0;,_=!H# -MIGR.Y51O@C]M8HLF)^H@DB)>O4H6(H6UZ/,2AUCQD8593-IK -M&.::K$?:ADY(7/J,E9DA938:36T_&S^=E]KCF4THQ&R$336M>.O.X/D7V?LZ -M$_+VFCI;=D((0:^-OK=ODJV\]>.1KJ=`9SI38T'-7'[80THXL)%E^A_1OD7( -M8NR^DY"]YQOS6TQ7!SX#G%0V@XB+,H-1HS*U`MX07DGXG;&_R"TXL<^KZS-7 -M7;FF5FWEKPN4"@56%*5Y,4C/]4/QVRA\B.X^[@-%E/E.,Q_""'5W_DH[TNI- -M>(".TEU(+\,4P0$^*1JS'A5*P-8DA\OY*+*J-25ZWO8Q$R6MH%?9C3!FV!AV -MGW56IZNJ;?K#0$^+3Q)!Y%^:(G[-_,E[."("]J<3!"C[/Y,`,@?, -M.`X)B?WX7J"E0__2S$9/'+RJ'XD!W*9L(R,W\V$EI -M,/J_G$:I1U%UC2GH$>"N$.K6`I#_U98>O(3=P3BKB>BHRC@5-DA+W94[7)O' -MQE6OD[A6/Z.4?+QN*L$4^MN0^4()I-!DJSTNI@W5PXWR)A:X7EO>GT+$NU.7 -M2W4'!$^'AP7@.,"S-T^J@B'>!_S4Z>ZK'&R>AYD`5*U*W'_>$NB%_AY-Q:.D -MA&"_FF$Z%IT?PPD(T*#W:$?P'!2('Q:U#P38,DM!]789?_\FE]O*W>V?KSD< -M,%CJ%K.E&!#2-GG3?W*M/H@@_T`%LP'>J#MF7@<%:BT5^MSVG[TPC@1T381@ -M(X%+UAB`@,8%6G:``'EY?2^1J()B]R%A\3IQ=V:+:D+A,BZ:&HSH/W#O2Q'M -M&3#>,B%1F'[:N\![']0/S],]X?2@P+`C3-W]794/K>P-6*F5]"(,XG4.0I!0 -M,86'V#_G7<0*3_$(6?4Y@()NF^73K&IIBH!J(^"N'+:T%U8S=SNARBVJ@(?; -MP1ZCI_<8\]L04:.,:MHAV3,460/#$N2K331^J"\`Y9OWM0--YNC;=\&?7(1Y -M'QQ!0`]6^"F`%0U@[V%^\0TXFNHT\3-M$29Q,,49+X!O!N!WQ"Y@;`?B<>!^ -M[`J+4R)G/D[WWXE%"DAI-LN5G;BO%W*@J&8_+**YKX*F90K&Q51^4K)Z[`67 -M#JNUC1'L<1@GPQ<_$&R7X$6?#"8@]X@5B)EP0/>H]1]6FX-XTHBVZU&)JS@J -M"Z>B0'"'Z#5[_]&?93CI1ZZ`2H&_Z30,P"7E -MM+>9,P[6VD\8HQXSDH-\^X'8^284P69_M:\@G1@\A#VX+>_Z%XYSHY5QC>JUWJ15.[.7Q713<^R9IR6ZJU)CWUNKL`@:B -M$+LY'XJG41(BW;P89&"Q5-N]#O^1=(A]H+VNG4LL"LB>DQNN,W1=`_0I\35! -MVI6FU_J(D2+/*!+3OI1-H:5U,2(!!"3SH.X2VX4L\,OGH*K&D^B*OI<[6Q.J -M.*=50EK@-Q=B![.YG9`7U9EGH`@S.P\J_1DAD$0SO<_J2O^O0[\&;Y+-_15R -M1[SO)9$K]GA3]X^YTQC"?R3B&59;^7&[ZOGN=S-XJ!OA_@42,`P7S<6PFC*< -M$%\#:+U!,PHF7'0G$[N?1XKJU!69*EP"%E\-[A%A(!N\>HA;+.6Y6^3`YI=+ -M);LWB);_W,YM!S.[00YH':G5`.=-+Q#[A7R1W*E7*):KYYKBFM[SZ^9_1A35T?111O.B-MG&$1OQHP5V0<5 -MA5G*6^E_?:)FI!4MHY[U#,Z;OI)Q<_N-O'<"H;ED(NU?U>-_Y/EOT)M$>3$( -MS<&Y,@FO_^A(S/W4%`T,L!%`HO^CSB$\(1_^13A$YB\7=C8&'FC,\<,R*9E) -MV[^6^:LJ6A(;R"U/1D%X4_NBG\'$^1NH[8*L+:$#*3(9%!34Y_*3%\!:/4;T -M.\5K3"!ZZM90B&LD"+P@$)K)(3R'NW0P$Y^<'D4:06,A*41R"AX3I"?-_@,6 -MP2L[YZ;YB2I(,0!QR1K=8$V0R$""D#.H`VUN&[AI"ED5!N'+)'M-9O%E^18 -M](8AW8^P57'I- -MPF=GZ"V34OK@DWAQJO6.&3"^FFJX>R2&E0T-=4W*-S\L1,J`"("H\Z3J0MIH -M:DLPJ."?UNP'F>D.IT[F?S_.J=A']'E>S/I"2_-J9QX,U -M64-'K+=K8!`/H(":LN,*S_)@*M:LT1VED._@\8H3OP\'UNEE1^+`P6YC<3C\ -MC+W%8^LG^WI$8F/=%Z525=$'3ADL.5JX_U)B#4=;!1`S$4%]0`_9U!1'/*S] -M)ZX,XSWH^.'.4PO^SO.U[Z%(_D?_YF!6X[N4Y6)B6]I^W< -M'J4YEWIX_[K0PP/]NFML"/<4>QC=D5P;,Z+!A-/E^5M[MAA-6'T;8IOVHF:! -M=./_UKOUO@W/?ON`$9T_MP6?-,:&_&=%/!#:`]7L@G7",FJ73TS@(KJ4!/S: -M/!CF6&&F)1W8QU8V#$*K)CCAX856=\8+RS/T&1PB=YK7Q0I-8M1$AC(!OL@, -MDFEWVR6X;->NFGHEN#?TRE"PY1'R4X*`@AM5,SE?_UIA.&.$EX -MPBQ7L:QZ#2:JGB\]CI!5)CIG0:7;E5FG7D'SVI?#/'L_6?IQ=/?)%G7`=ZQIT!HT?P?_K(RJ..9/AJ[@""U5U-?__;#8B3 -MY,_?+PFCH#IRLM$>#"IC<\M5!R2`MM:($35]Z4N@BU`O&K15ZXZ8=`=F*6E! -M9`UZ=U82P.T^8 -MH`EVWTD3'$RF>]9>?2DIRBE>'S;4`HE@4 -MW!%.0SZEVW(%<'@>`1IVQ^42IFI*LJ#>32`II^K5(^#,'.E;9'L>[%C<<'E# -M!17:9D4[T\,S4;/OQ4)]0BU-H4`T/J>8W"4CNLG!O2HIHF>8'B)[(3P,&9H) -M:U,7_/1K>]C402#V3DBXN1>?:!+8!6YD_8X6Q@CF#,#/TO:M8=VB`7:A9]YS -M31U`<%)/<[P''QDU&(\E!9=[B,ZG@QC=!Y:N;RZP)'PWNZZVU8J];[)&>RQX -MZ7PDQ`H'`-GKUQJ\H!5Z,8WFQN`...O&SS]M&`FIW;?.G[FV,EKUV(UHN8.I -M+0O=Z'*/$IO,Q)'H(XW;*"L6B[]JL]'`C -MC46]OT..NG2N9S8NG,FEYIZ!XD=_D.5RFQC*LX]]]!]HY'@R@D&T%E:IA,VX<&_,3J`TJ3F#Z -MP28(W^`7OV2L-7B);JID0^G\B0RC3"9]3.*MH)+FG<24N5(@(:U*0[(NU"7W -M"+B-H*\%UL^P$9.Y*':0?]$:JYT1)*BTJ2@*_"?+S/K[V[[S1!V,,(,4F?*F -M55G-L_A1?AR(4:`:#:'Q8$I1D]S=EK/]D_C$ARD%L')/D>#X^NH8_%)VE*+' -M9<],\NOGVVV3?R\WI^CB>H@VTN+\P=.FHM*O,?C%2,L)D=/3+P(VS/2G*%(E -M<$*:2.TE%R_'P!`9FCE!=1YJML[DN)#*90+:+5QO53_>'\4SM-U#"QX^M/PN1`+>D)U$)H)]2E -M+0J!?QTGA3_.):71]#'47CEK?YEC9MHHS2<\RG&?\D0U2Z7J*]B5EP:X.)-7 -M%'L#-AJZ:Y0MQ:N)8)Y`Y5DHN1+ERQ$`> -MDO/_65?`Z*E6_F`X0XY1+(ZD1"!.'877]UL^/(53;:F+`GOD/UIWF$(S>6+[ -M5%8H=7MDU^B>#5:6$:SSWJ8^1&2#(F-Y?4FVO[;%#7674J8`>;[$)G7>C`M7 -M@NH'Q^([*^AF6!WAO\]"TE>JZTC,G,@I:YDS>`PCO9--'C@529>&G55II[^W -MT$MLUCU`T>8?+(/]_,00QP)YF%OA[^9P/H%U""EGNA@\QUADW%&?B\([SJI> -MI71VDGZ.DW*X>7!"21V?+'Z(E*<_"IX15XN:$5F^0.9`]]A"O5P(Q5]I1I20 -M08-N,1"G?I%[V-W%"]^]]:7XT0JL6FSB&V7[TWH(+DN_HK4^)^PM[;%A8-VK -MQ&SPTP^D`C@O-VUN8FN0V'4_A5-;.`:V5/P?O.'5/6)"V1T!T^FP,>%$]-"U(V]!*"1.1$N%^]*D"*_"G*F_QCH+;!);^+BQW -M$ADX,7ZR^MM@\_@.SOO7Q)J0YZ=IIWI#"48F$`?>ZWB8Y -ME1`]D&&[B=#:H$>@ZHW6FOP_'PE#[PQDH -MV">BD!+^I>LD[H.U$_BG0$>.)K_'&=Z\N=ED*%:_^O&?#(4U=(:6`/5JA)!Y -MV"'Q/E;4U*;D%!F2FS/)B.I'I*ZE'L#+6[G>0)^F"@?D^>O0HQ-#3HW!,.UH -MT.[`UR:V(54UV7/0YD)[8L=O6*4LW63*OX4K,7[1RGQNWE;1Q]']9SG_`G(O -M-T>U#5*U-]Z)&YZ$E]/2EE*51]!GKN&_Y:#8_H28KIALW\$BQJA'TF=;;-[D -MY-_.3=Y?'A2"2//C]"2X6^98E/_BAR=N(0UND`<@9>LTJW`ZMP -M>\6:=L`@&P,Y@[I(^CGK8'B8D$:?*-KG&_XHQ,WC.C.-6$SU6-B6LVF$""/I -MA;.MR]?NVP39,C9AW79?WVJ$0E!9Z&?3'Y(KF`-IKK^C -M:D:HDN3?*K*59]XF1`3JT/T0FV#/-:^!G%5N=\G72-9:#S*-P:Y>$0+39U/9 -M-!U3DMKC9S,?'(&-=:LW<8;&?ML;Z!O&\^'E7TX\E7%&7(:>T/FQS8IG19DGUGHUS4(`I7>0JBR2MH^Q/Z:X -M*WJO5W!43Y0P3CI2Z%1H7\YM##30/VI,'YMQRLG$]1[1>'HJY'!'-2<(IP_IY4VX?4BT](9:)IU.T_O[YC(TJEERRZWHY+=P"PPT%W^C)Q,F7C -M9T,4<8R/?FF>!Z\9`+ME_L'(?[;M6PXK993,5WMB`]J&8C7:-D\8)`0 -M0JHXBV`C+_6'J,_?6/B@?-.QD8CS_4?-NM_QO?:.2@M\,?-QF6G+ -M.^C?4PPGX[N4F7`/K-(XW_^VU]W\U4G;\5ZU?-!8V!_3O7&]'RVS/M'?/.RO -MEX[$C5HTBX-^VMSPUI)0OW@%+$26$9'`2):<^KAWHD!*5FR"TL0X+=19B%"K -M$=?2J0=<2,=B7#T>AXS%-_ZFS/G!N?R?N;&!NI[LEEPS/](IZUL%(CD,S3YR -MAZ9V4R76!&E*E1K)7@?RC1FC1]`^?C)"E5[ -M\/FQ\_&ZL&;+ZXAWIPHA.XWF%A&GD0WM1O(&H/>G1#I"_/OD+@V#&VNP.DRZ -ME#K2)KKU6"!7(G9^X\R8%=8WU]76AN'M-#/M;@^HJ"2P -M&GP[.ER5"F$?V_9Q0VY(FOI=[IJE`Z.0CT`REM\W2_4-OC57UL_OJ^*CO2-V -MHS1GXOUA"WJLAG5M/I,\ZU/N"&M%E"E7X9##"-<*^*B=%]=]XJ\=X5@((0.> -M+0@+^$DL?J3^@9?NL9VWF]Q>&"\%,QS)]J9>EE9D(7 -MV'_I.6SM05K$F'/SMOT8VJJ9"!V/PW8KF?`C/M6P=` -M`Z1R;1C$_+CLH$6E86,8:GMV$>2X))FV4S -M2Q1,DHN"M)VU7P1)S*?A`CEKQ4N@JW9D2H2`.6J;/ACEO=8#^Z&+J>4>CZW-X?W;9ZTO,LU(-./"%.]?PY- -MA[LY,$W7GWO"7(9E^^\I8_,,W`JOJN7Y"@E7TD(KQP@@`YHP]3YOP:&^>('[ -MPNW6GD+A0%1L4\RYBX>Z+^0ZO?"M`&-C"CM/\0SPH_`.,RDTF+RQ)Z;AD_-\ -M"0@`!7_IZF/)?31SEG#34YH[5X:%\'FDT^Z_7F0'!"#FXF6#7H$JU]Q0 -M'P97/^K1@DJ#9"+S?JAK[HG_+Q-V;7OD*(+/YB?&H;M(OT]_2I6Q["QMLOD5 -M*L^,^)9=G'0/:>C@L(VVT#ZMS>#JV4"B^?NL$Z&$)"&:_,!HY<&S8<^#\OCZ -M'C_#5N":Y2H_J&BGM.VE5I.F2G,,PD"\9M1V:X_5+1BI3V_R!&%`H4&2F6&K -MJ04P>7K*[2(^&G9'=Z?&O\$6.F@==?GTM5P<1\,WE2X99-H\#!5?5R;5,&N[ -M%W)^LON.S*J60Q:`;%^RWNBQDLV59(.*AZ[:OK$BH);+0[B%-A+Y?.P&=]/T -MY79O$@"MM39V+4D_6)-L%%M4#;%R9RVZ.7@AC"/-?YDS`P@YCK7?#(6P#D= -M6`3!V8'G;VN+.7%AS:_IHA2+1S3`(1[;_?GVUG!_:#\,OBXD^6WR?<0MJ(TT -M9>N**ZG2'B#?P%E2P5V8D32EZV^(7(QT':0*H>&<6GWT:S^V*\C22R:VC4+! -M)O1*ITX3I3<+_MTL93'976PNV_!`]<-G*-YFCK_UD('Z,[-TX+PP?IVGU@D> -MS7H56`":WO&&^JB6V0:FIK_=N*!3_=.P$/1H.UQHEMAFW^&SPE^.I/`3ED\* -MB\V&]=R7_!QQH>+WZ4Q*UJ^B8S,9,47C!IO@H&$HX>Q[U$EUNINL2TUS)8K> -MB%DD?@;*;!GA'EZ\"+8`9I6#W?\#.=O'&&K*$*>^YQ_;/A76'F;$T@`MC@$: -MI-%U:((PG?R_`'=\_]V,.H!P78WQ_[8F=:L#99"S6Z33]V0``!B=GW?PON<, -M!VQI1'BIY9,99IBX#8^4<)=_/7F+'O*HK?/G#S1815Y^P1OI&T#1QY`?,*R@ -ME8O?U)F)D0I)*[H4M].9W$WZ@#G)(4(-8FHIMF_I]/P@!*GHM'?(2G\0X -M',9#9TW53VZ7\D;>?6!2AOKOBRO*G@J%HLT//%*_++A#5307X+^3I$UJ,*Y1 -MI^DYEI!2%'%/)[V_#?$MO?:AI%24)N5QO_#5MW^7".OHP;8OG%\='Z/!M$;E'U=3)+=;B9>HLD\!17PE8CFP)\+$34N47V; -MGPH-HA(S/GCO%#_V7V\2+:Z0A!-'+++ZD[;3YM3&3?C?,12#AO&*4\9)APUW -MNU^=S4.\VC-FNQSO7Y+-WIS$A)\T&UN+;KF/JQ`'670V%F\:I2,S=CO20+5L -M>M]&"[0H!E''N,T[?%JCPDIH#RXD+HI54AI"O()N\5Z<`-)67-A]!J17[VCF -M\LEC^Z)]M(C4`$R9W-M[/U!P!['1Y*)7X5MBRNL_0BH'V+7>D1;PLNFEFJ?0 -M;A=B8H5P9MV8:X$>%W;+DX%X/[YRIHJ&ZV'.9H)T"CYY%,Y](Z('"U">(*!" -M:5">#4=QJ9;J"$G(<;RV9S2UW*2UGF!8_748GU:=5,:=XS2.,':SS.I.K1*V -MV%V!F,'D2*[<%%=6'AP[7("5^=2LQ<:&_K1<%MN;((Q>: -M^NLHD2,QW=V4*FRX%AN$>1?'Y@S0>;VF?82YP?GI5*@IDO-5)<*R\25?IW"O -M*B>>KJ\53O,@F+0B*:O8*CN-P`BXP:K<4#4D=*0.'XYN&;&!8L1I6>`.QL/S -M/Y`-C\)>VBP\"!GN(6?R\!9C`/_I(`_Y"+VW$=1V[^&^(Z@HJ4]XFM^TB2(K -M1LBZ;_`RC^[J37B4N_E+T4/ZF?;%+X%!6-,H6I@1S>GF)['=]R4+UX,W%9^N -MK=?_P<0^C)@_YBMZI::RIG&Z^>+!M(@(Q7ECU?`!Z1R/+7W+?7;V8U=G_=A/#4[Z -MJH`GV(!H5-,9:QMYUK3N+BCS1N6)S6CP__[2=LG^(.H;.SW=P5%]78X_I@TT -MFD`&YGQ&HF]=LAG40(,HB=;/@&-FNO-]W$+MF_^QI"D0"<9F+*OH'#*71&-> -M-&#DX)VAV3`,XYO#IB-JP=\$?]]&6*8>0`=R78.RZ-WJ_?G%4`1+5[@&&/#> -M@X[+++(PUB1C=#9E%_>$->98+M_%+M5@M+WGC=4).BJ/U8)&F6S'L3)-@O0Q -M^T\,_/&-BX=[VMP11V)5+W1.N2]9"@L,OHDKR<2%PX,=QL1OO5/^?M(WC^=8 -M$*K\/2W?*U\_AB9)\/QS9,KU0-16?WLSC6:HA8^=#;9J4U?F50 -MOUELI%(S\>&!$1")/4(X45FH6*.*\XSZ;9Y3'U\A1%6NYWKD9^WG?ZHQ1^Y^ -MD?C!R-X`9YM*QVT'0]#VVAD\:V9X)\Z=(#^5OX][G8@BT<>K-8G[=W#LPA`D -M=Z#R:EN+G<`=_$\01B;90HEQCL-NWNR@-KPU9K;42)#2,D[4WAW9Y`.*#VG;8E2]K^H&-\.IT$P/PTHW^3`DZ/J6/, -MZYE,/,"$5*WSRGM>P74A2+DRCM:;7!U1K3_I4RVT')*(O7%F[88;YG@+?DP* -M9A(MKO)P!JR$^:0_5IR>YM*@^?`<'G@5C"QHS,ZSW='.Z481\9N/Z&JB/+34 -M8]+._K[B[);#B=2H?T;4$#B_$SR:.Q/R6Q*44R-YP -M4KD@XZ<'V>,V_]=\;_=F0DOMYCN5V](KQ/C9C<3Q2E)1R\T?A7HWD>DXMJ4; -M?].;35SOIQ,8T:U@P;CSJR21 -M`<\Z??9]@1E%.L#TVUR%32TM,*Y80C.WP>]Q62&(X<;D6XJ"XX!WX5F=MU6B -M%!'KR--WZ!0$KPNNU2X4E`^,K)5ZABG%<&G[=:GWW@E((:R?`\S+0J@C-G0A -M#4![R+TEBC4H<6`9EMOH&6E*`D03G:74_5AO$5L/H&0:V -MU8)E#N;2D6+9H$N3A''E,0>=I%&M^<`$KZ@.AGP"7Y`30Z1T;63]$Q7MI:-. -M`X,AE1WM1DR[=QD?]2!$U#%,1.?U+G4%G#(&V1W4BRT_2C,!2#$RA3[.!]!H -MK)OVTO>!*MQ05*QYSVQ+N\V2#.BW$:I@GH'M3BH),65%;GU[]VUU -M,I?LSCFSO^(15O<_;*2!J,+\]Z9:+U$\,>-$%]4;.3':H\I/AIRE(!0]Z.I: -M%=8LZB%K&1"T\_E4VYPLK+DT;+J:**^,!LCFT6Y1\/H!+,%H&T/I?Y`^4;)D -M*7-`+C?.;7>>!KLT,9!G@^3]/0"`,[CP1BT%TTGAA]?QSRV/(#KBS.S4/L5> -M4EDB,0#%R/HGKTG0@7_QO#_12@U&*`*?[[)"R%[_"D6$,G@-H*#D(&.C@'GY\,;+W;'&T&51)D0DV$<]5-'^:QHP8,W:6;Q06[KE`"'*5 -M%Y!`*9;W-N'YBL_I/M363E*03A>>3?O6[,?_;]BB'S[7Y:^Q<0(MC -MI,=$R];GNTBX!@!4Z!9,`W'DO$2A"0C5(!V;T<(H51ACKV&,DG`4FY#NW=0G -M78P"#%*BAF][AV$?P%)I\<#2A`[&=I@./3!6(]=#T,CI*)=/"<.?5&L4*BH; -MQRN(7GM@=0F#JG?FH/]:*8RI^E^U0V_UH5:2U]%%#,4RA.LH]MSQ?RJTF961 -M^PP?XIS/CO+05,8Y!A$/^I6L)9/?3`J;YRH0%X5%Q?TPL%?71.`=<<[B[_K5 -M>0C6.M7,>W.#@!2@[`NBFE+G#&`2=MKZ=*Z*9J_3^F5AR]11!"6G1$Z0/ON/ -M\R=@G-O>7@`U*,_A`BGBK[SFL$'>D3(0QJ[^S#Z&%3VR(@(O:W_6&XV*QG-Y -M%+6M[;S6$2T@U#J@Z -MT=K8Z1$K>KDQ+XF_]^/U@=#Z\I7GD<=#.2KH8&#[83;,UMZ.J;CRG&0$F&4X -MRJ@]6G@W:,GJJKHC=:BHFXE[0>A_YM'?%S&:RUV36A_@#9 -MZ:-U5;KL<0I"\KY2H'B6)%==A6\8O)C]FJ -MKZ.S'WIEZQEX7U\6O\W=A=8R2I8&=]@M0+G6.9."9SSG>7G2QW&I-IQ&E=J1&OU!'L>0?^+/^`;T;\B6 -MT?`U[)`/C1FG\QF(T4&;4R=C;\U7SC+![&.+D+L8NHFN:\E7/4=AIGG"KX,1 -MQ:3L)[*\T`_+4RPG.QN_ZM#0<)')/VE.9#]#=6:J>GZV/G#=``O)F!K!\#7I -MB:(9Z,4_,UC]`:AB]2I+-72-?_O(.)><`E0J2TUA:V&-;<(R0L\,5@T59#B"H[;G/,Q;#JP>=-WYL(`6FPJ;*(A.H=`W0#X -M&,/M,O%`;6UEAA=3+Z![(W$#>*N6//9+F$M4?R@^*E?B=I7H,>!=CZW:CZXJ -MD:)3=8N:Y_D#!&DQ&HBJ(B/-[F-TDIW[]RG7)'&25@NR?#5#6;GS65?SZJ5` -MJV@)&(OT7_X>,`_\C^JUO6I*!0AV7]PW0&PY>BR3GFQV27TC*")[TF`NLE_, -MP$OG\70>[R2[KVS_65.C_LA440$:4&*_R*BV-J!:0!J-:_AG?'O!8 -MD_"WUVHR1BSWD6,`#!91Z2M%@)/RX.I@R*C22L^R']U"N:"2DS21C5(@&UT(2*N>!_'-#5)Y41%VJBM7((41^=[H\.V1D' -M;NB8_0T5=PC8O^6+')B_,P=SS;BSF^#!_AV>LV.2IC5NR`\#NC\2%R6:QN09A2[+CY$W64D^WP0T4**_M8)18>+.8# -M!WBB/I9+I<*3%RRB6H.DUER`]PKUSI%;=J)0`AE+J`4XMKT6BF2SXG76FD>F -M.^`TDZXS,Z_B>;5YG9L3H+93&X??.G&UNUY8`AAIVV_5O,2A+XN.LI_+Y#V7 -M^%.[@$+_P^;5O6@ZG:"/:2RKIG>(AM/08H`1[#KOO>C'3(([W4OHVL(:.YHDM\;W<;8%P7O)+; -M*0-=>72GC"#F"5I@3K_=U5Z3@F&1$Y)J:7TJ^J%<#P(^[I=Z'-^MZNZM([E@W5T(Y)KH4.0W[P%MR1>LQ.DI$S(_$J7-D>00<:S/0IF>^\"P"-GOXZ[&B^[5]P!,0BT$H49OTS9?_67K -MR=VY&N1AI1126!EM(FX^*FLFFF%RR#8+]1HWZMPN`X4@`]K7=XH(?NCOWEVY -M97M+HV]3U=\X>?W[`HH?[^VY+XJAZ.IBT2@E:+`5J16B*S]UD0A8>"_*[W<( -MA!*RIF2P(GC_X6B[!4/.K>>'8$/P8N>+R253$=X#H??C6%F:.CO;A`C]DKB! -MW\1PJ*6CGW6AGG`PP"8^0I2?'T;=>'76HQ>=!@D9 -M-H1_7F*[.DFF>^N[WT$&NY_-PD=M(A14M1(,`:_MQN4'LB-A:I*^>4(;Z6VR -MJDU_?W!/*;/*[;!56$:Z9()[&,2GW8;\D2N'<"7<`S,62Y9XLU>:%](DH$E% -M2BG+JL%2=_?"2]C#Y*.WJ32:E;@XMN'`3)#3XDW=,='B'UA[^?6H67"*#:/= -M'G'4H01RED-O,AII_%W9U87"W+@%B\&%H-$CTR:F,FV0('/[`BI(;IR=%M]N -M)!V#*,WLIQ)<5`WK'BII=`YIKN3#.!2#C@J/ZVGMEP=N4/0#@H-7(WMX,DR- -M:=8Z^*W2``'I+M?2`\TL[!.=#F[DA`:;GGQ -M!BQY41<`:XH#G%B5K$X&7T7=I8NL7P7A^,\(M<>@)'DH;:H=*^E92+9J)A_& -M;)MBM$B+AZ-75K&D%WQYR1SUR20307*J1U_RYM97GSHA7%.B-XKZML>.-S\M -M^):B#6G`PH%2UUTWN%]-.R+?._@X<(9Y3&KT:-C^9H3SWYF`(*N%_,7F.'^? -M4!RC(\_S;\/Z"-]_X]TT:8&;G\IP"2S\0+VGTL@M26XOE5=,G9I6[H6ZA0'A -MJ!LI)!C:$>`@D0=/F9/+BW_$NE/NFE7W73K`%>.;`K2_*]H]/?"2#-,*("/J -M:K%(V%OSM("'C]?EY938ZTYK2"%58RZCP>-O\"[@MU##9`W>BR+5['*+3/2, -M_+J82`'\/WXZKYD9^]RUT;TF\=WZG/HN*M;RE#O8J1?=7F4G/K`^4,D6/&72 -MN4_8*`]DB\T'U*69Z6!;+WLT14DHT<:"XC368>7'8'@R@]/TC9S.6MH(AI,W -MX1#CIT=Z+CH\HNAM0YQU+H%'$TF6R:T)6+J#$C@P0_WA,N57C`#OS9*12=`* -M&*$2`T2FQ9Y_V_T1[SS4`4..@0A)ZH]/-,HP@W"9\C+YX8+RZ=\Q@@NJD`E$ -M[FX^7'X1$07+$H__U;X;=.NNK9\H'O!%VQJ^K+:1DG?P4WGCCN%[:$YSSHL< -MM4PYBY;13T+GQI@/*EP?UPPE7SV#U$BF#YE`,8C_BUU34N^+9A#ZBZ5Q,`85 -M\"((.NNX7/YO8CKV=K<^9!/:L`'1?@E,8MWB[;LR7(EF6/RE5\FALLO9>:]% -M8+VM,`EY-==LUJJ@.1SIP:.!W%')C7)^7N&J-I/.SQXD;S*\C5].'JZ0%`DS -MQ)8@YPR;-,SJ%TJBSH@@U,`77/:Z=R%LG2P+KW7I:!U=73F#$Z9I`NGDQ`#, -MTN;"'"UN\"?Y[$11#XC\_Q$YX?"R_+^CH(S6RFU?,;_A4(W'BPYD(J%D2G`)UY>)+Y3TNM#G0/L!_Q])X4+]RX-">5B -M[AQ;EVMA/F<-I5UR\CO:0VIWD7SR)OB$@A`\[3R<@T;UX5H:X"M[3S&R:P#: -M]NO+!XO^N/'VFLJYP\#N';7^J\KN@;PW0U.*D\A:!^89NFVD+Q,O8DZO)2?% -M'T3O@1"@YB4H@3CLJ(1BX+OD(/*.Y^*-M>\@(B*<"^[W+R)'U[T"L]N]D`8= -M$JR3-MF;:=-M@W#O@BF6S&TUP%<47%A6W\0B,.A*/CE+^QE=^K&W]:"6]\-I -M:%31//:;[3=NN`5I>IOQ531V!%"6GW'7,5Q/EJM@EVLO_[8,.5"$]W&=\ -M_7I<0@==ZH)P\>WUN\-261Y_1EN,Q/(-?F\='5(Y=!$/=BO&7/Q -MYM<3_$"G"M3E]=??FK%UJ+!(H,<)?D$`GVB8"%I#`XLV2;YXGFU$;"Q9\,W^ -MC!LT<:QT8G.-*EQ<\=)V[TO)D4_T$T0T7CG<=<[A[=6@&MPOPF,"=IT6^59@ -M?5<$;3<5D_?_7>Z4P,=`:2U+JJ4+ZXLM>?GX+0J/%BNJQROG]2YG6&8@;<,( -M%3A0)\E)T"!GEOZ?M?NT>&%\X(2^X]'8JT&,*Q)_E*?3ZS*Y@HIKGF*T_Y>. -M;#.!L53ELE>,"]V]\0S-2(+,H,0'9M[>.X5<+T>&4XB&%7Q5>=9%)A"V)N>1 -M_;DX3Q68@L/MTO5(ONE0.VDO>LF,IX+['G* !LHS+XF?R?9.QDO!0D1D'8 -MC2HP3V*'&#O/@P?B!&>53QEU=3TO3/!]WQ7]Z\*GFHYGE>6YSNKTW'BC7@2L -M=:UC5PKQ_2.%=RE5(=20;3)W]K[KM?CS"%<=3Q>I@IS6%*,U*3+\.9D5L#$: -MNGZ*`@O/0QB?)DI$89Y!UR?Q/0WA0%O)(%M!X5QUW6F&P(V[V1< -MFD#!$0_(A[ZJ<\\?5?K\2Y)$M;U'4=,N;L[9Y(C$8V!I1%$IRKTU@IE$_MZ/0I/=*RR)`0N6?PAD$K7]3T\C`HPJ&TX]5O0.+WE0` -M:K-U0";W#)O"^9SQIA0MN\#Y0N6*$R,M)5OAO9CI@QB8-<[AD,WS2>.>KMYQ -MM:D^.UFT]H"'H*3EZ;R.34D42Z&62&V%A*BV['B[E\7UU6Q>BX&)<(.D!C]>@L>24I>=YQ;620]^;,@%,G=C^?90 -MV*MK,.U]R+C/G9X:`]07?MKMUJ"#]8$E>[`%; -MUT$K(G%*)AC%-:Y.NL\@>:HJ=.9HX(/&AOR@.H:^F'VNOQVUUO0"]N^R:_2FL];[P\TZ512J\@VDH -MY,\G0.WB??,#PYL>BB_Y'8]$,(ZQ%0<$B'-DN0V[OC\H>T?7;ZA@[4BMN&&' -M_;ZKIAA]6/`[_3,Z(N:U'%`(OE'TL8 -M]4WT*27LB0M=L=H4(/HC<.62J6&X#<'^7EP^K_-+U\%/5\]9'>J%=JL.I"8O -M+02940TA=IR",[S=C;4TISKI8!E#Q5K*-&<9,@,=O()-K6N22,1[?CDQ_I.A -M]9\?++!\\R2A>*8D0G')4_AF'` -M$F^O6C6JI0G0=R+IJ_,LTWD\C''(&"3DP5RK"D%(JJ$YJ%\@^SOD_8]0XA69 -M`5]/C4&4XQ[PUYHHX\5S%9&IWE/5E]JA=E+!&,Q#I'\DBW_@KV':Y3"A\O"R -M$G);E]64HJ6A&/8V\#0/#_5*?_4>HIK$`=\UBWT_`%.#%?,389J3RAX8)%,F,EK4H-)=C=+0L&:BY0DI&NY@.`L_D^O -M>N3R0\)P>+U$T[2^YZ>!O[R:J,YIB8)JC]#!GB[IL^#-+CD%_&QIUKK#T\AW -M6:W)*-Y)FY"DUY\9IF]'@'7FRR([TMROK,HG>5#=((Y;XYZ5!?I3K/=/(MUW -M4FOFA?OE5M1VW7U<9QGH)6-@^D);3 -ML@WFH!>\BGO!II@E_N)'T:M[;D9I.$C9WUU4$+)#MWK4TE40G=5"$,(%R1(( -MD8_N[,#ELQ?0HR?>_:9WU58:)K6.BA8(#CRZW]%@5+=MO,*"5J?^<.TDP1NEJ^DL=4'6$*_'X4*&B#V=+ -MTS7)NGY1'VC$Z-0H8AAO`$MPY,Z_0<-E6)2!/6`7L3_,*@2 -MWCO%BNQ';VQS2W)XRO0=[]R>0#<%&0(5CH'6'XF.ON+L73E)L2X,//OT5K88 -MV+?HB@@#?)54<-K/E8#]W+*ZTG<5!A:2SL\\,"\"KS=-!(3O?^^V4=AOVO$Z -M:OE9FHI5O;5S.P^^QKG,U9[/+!B(CCA"#[-/!X&]%[+/D.G$J(M2L>:[O4I# -MRTN\(#6]'P(R_'!.'B%AT^"J!VI=TXH7OAN'GW_0!*F#!AO+&KA8\N[#'GU2 -M,I$=+V`:A+A7,5[)-PSE])B=7+N_#C!COB93Z[7%J?C:`@TS6.LE5_@/#OMEB>'F3=5^)`JP=1&T@_:]AJI:*UMKE:=R69_^):B(NQT -MS-"1P&F5UF&+M.0?$N/+&X:Z(=)&P/I2E1C]^#E* -M`S7!`Y.U"QB\<,N3#HQ0',(F#A&"_/-U1>"&ZAM7>!C5T8VHE;K"\\_&3:^L -M(ZBG1\I-'G+S?T$2`_(8QR_E8/4&T3;MVOVLT5,ZGEP]ICEE14UD^?WG#EGE -M\ED303@LEW2>OG=Q+HQ@7V3$V4,;<:GA-T[QB=@5CV].&6TWJZ5$+8G;?S7) -M`H:B/AC`PC>;3P,YU;%Q.%4$1V^DP-+E7`9:0M6W52`!Y%A4AC=&(#<0)-O9 -MT&?AB<3J@'_(=\42L]H^=,1P>-5.S6AYRW-`M=)R_2)#CQ[N!L-YD]SIV!_C -MK1S&.NO=[QEE+(:[CDMZXE^?!@XFN/H4`%&O@U'<]P2;7S^=,S,2`;R*&?*@ -MC.@8<8#>)UKQ#=2!\TA2^MN"0$]Q.N%0\U#Y6%36FIRGC;#^ -MMU;AW*IN+,G+*SZO*+CS)<:C]-X5T=5BE#VRDK.P\Y#KY_<'4G_FPT)49S$Z -M0]YY=0GI(5VB5[X'U4EV=)-A?DG80Q^@=DUL30JXN5F>^9+.I,EN"8#$2U>O -M8T$+-KY`*ZDTL?%9>EWO&7H89E.*(M2.\GC;(YS_%5LO<3`6=PD3D_KNEWKU_^C!6^;)20!9:4%0Y> -M%LK9TU#@-:R*NMO?65L/`CT=9P,2GY(U]^Z%Y6?;G-Q8AKL5BBEN61!S"0-B -MU2HWH6_@/UMR<9/DL.\1#)/,2F4%:`2E/"EZ6TE+*D@RW -M7A)G[YT[@3CUX;FUW/IR$E9[E>8U->D(\SU/T-:K8X4D.HT&[J9/QZ$X-T*1 -MBHT(=A`C0#LQ(;$,4S5>H>0,\2-',/KG>TME,543W<$!+:@^XB7'MY%T@G*' -M;4;HF>[=:T,:P<-_.!^0_;A,0&-LC5213K/QG''T-#YT4.'=JCK/[T)_V`1O -M#7>I\^1P+^IA657^ZBDA$42\`44GX*>HB,/]+*(.!G`(-;7K.+/<+^V?,-`.>C8.B] -M_!&\#9QEV4(]I1)`<2P[G!"`&[]N'I4MPO"-%CU]L\IOF_"@'I$13?J3OC0K -M"A*:276]TV8F5F+S4+TUQM,"-.UEY^`KLMLG[S'# -M!_EQ^"5MR;$6+@K+WS@52^+]%W>)C"G1R;S.OGFL.K>VU+D3IW@WG4=8ZZ!' -MF\F3;U/O/!JJW1.+XW/QS@.(2?]1]W3U*T%1ZEK(U*[GQ.BTZ^8RQ4$]7&PW -MAEOQ@+MHIP\'L$3M!-EK-C5HJJGM\@ZP3#CDJO.N&WA('O.FSTU.A;,J%Z$& -M>_]\[UYG_AEOEU*?EN';ZD-P2]#YK*U0UZ8X/V%:/-,2)K[_92E49/Z2'F@N^31I(\7<5@6PE-'8)50_F=XOI@%"'/D70VY1V+6"YZ'S -M.WL&U175B%6\\@Y#T2>NX\#-C$Z(M=U4%5$2=%L99N@Z?XMZAH-@=\%@8'K3 -M]]T4:?<,]X,)^RG8KBKEFT\"W!D9!L9[E.=:0Z%4G\%R;+$W?`_5FR*3II^@ -MP\:(;U!C;/1EA6E5JARM[8D9MW`H;PWW`0'C5L8W7:QY@!C0TI(3J*%1][7I -MY!9<_!WW+FQ<7J!)4]B!\O%<(?HRP0*#EAG4\X%\Y1:U6_*/69XS[SCU5XA' -MI(2+H:5-.V2?B*0AI+OA\J`^C8M)Z,1B/+=`$WQ0M6M.5?*.<;Y/_XJL;0CS -M/(Y_OK6W$J-TKXP1Z5JK6E?9F\$KB^IWA(UIL1\"K5@`JE*_=[?>M0D;VU?@ -MYGBN\?9LY)2A=:7`>P4R+/ -M%94:@6O64>[&6A&"7W'RO6PTZ1$VL,;EM2#LH\+N2'D^&/-[C!%5K>5B?0$1 -M[O"O9BGKB6[(7/D37Q/313_H%, -M@H55Y?&0[K>\7K!D77!'V"T,L5]V -M`(W$.HE/6B._G85]-`R6S/YIN;<$U5A%N@*?[<9NU%,]KE"UJ'$P490,R.>H -MD%$@[;ULWRXJ+>,'%[ZUX.J7G'^3+G-@_(C$7!OM/-3NA0PGNSN;<^SICV6` -M>@P81M_='4U6DVF.4RXEUV0;P\NT_7L_Y-KJ'GD^R-[TL:(/=B&4.U-\(F7$ -M'<_*,<;YUO<.B!B[CSO#'94OO+<9?\L\N4QZCXG5K.HVZ0'0K[#"[%.T7I2@ -M<0=T60TC(-2'^D5F_\P&G/GC`/$\T&K3S[R:+8P2A6I?4%K\=9"(CE*.8/CK -M.'%]_OLE\<7=?2+F$1A`S&51K7,&;3#(EJ7=*:H7DHL?E%-^@6Z)6PEZ^:2M -M%`F.CV9C/4/_&FK'5:%H&K9`#Y50F'.=+&(>S6)A4(+HT)A#-=ZW&Z*(D64W -MT8HH!]A6M;;.L&VEE+Q(>CH>V_QHW?`.PM[`[!,M34>K4*_@:PLD6<]V;5$B -M(!T23?ZJH^]OBKU<-RB8*NT53!9$].&D7+0E0KBH,1,L[FB),'ENOT;@3'Z; -MY!/FTW8:ZB:G9F"34*`VL2MH9O-[=-S/M&)1^3W,MH@Z8:O]]%,0"ZQ]EB76 -MG.Q"FBBI$C_RA4/?[8"%3A=K+>LB$H0#B4]CUG<2D>N_UQ*D#?Y)6'J'A -MX@ODJ&U)H8>J7R-$@A1834E=*;8;F;@J>SG\?W]MI@C\V>/@J",9P7S_0YT= -MI(<[1$DMM)#9'I-$QN=US5LV./M6@[%"K1,C\"4'!Q?[0-']*R3(@;8BRC$6 -M)";J\$&/^,ZY^?1?@?MKA@SY]>9N0XGY>=S;5J,WC/>7*,-I.-'D-G^*]<1[ -M]1-MEUK@BH,&#$3VD7C#2]1$2RE=,>2,:=)5%ZMC)0C1C*K?HYK696WO,^?Y -M#;'B7TT"U*;TLH:5"KQ>$RFEFJHJP$POFW;Q&[\^)+^F5,U;L\I+3.+@_TJ3 -MUL<^M+!I%18R=\=9;9D&I0X'E:5H6V9**F\:M:+N?6;Y4IH$%9A;_L"3W]HQ -M"'4R'=3Z9CD-6PP0IN\6_C5S!O=("L19LW07RZ1H0ZY"\@A0>E@78=5%7A8# -M.)W(-`W:M89L%'>`HSH'OM+K\'1@@(@8T^<6)*\+W)@I5K-ITMN,@,JPQR>2 -MZXBI<`E%W('/4`3AVBW@WA#Z*Z4[\4-+0:OYPT3]0T/Y>SJ*#;[=K]ZLXQ0' -M%`J5>E^?*@@H-[#FE[P;#C(@@Q.B[U!A;R3TE+__%1^+`\45-)^QQ(;YBR`$ -M>^[CU$R&8=!GNO53Z/I/J>.-0&#_+W]Q`<%EUWHHRH52:_9O+-_&S)7H96:( -M21(-TBH_;\3MB)"C(VIHP?ONX/^J9;J+X*[Z>;V=8?5=--\=F6WU4\1#`G(4 -MSZ6P+S_96!B-2VPGQ87M*E5]H,IQ2F%G@/^'<1QR"5N*Z31RQYE4>!%H#S:T -M#Q[ILB^#1IY5C7KA#NU":T>2CCDZMGX(O[\P8`=6,%IC+^$I0BDW@NRLAB:O -MJSC%B(B0Z$)'(:-2`Q]W$\Q\(\1O+[..<'ZM@,XH\?&(B1"#LSW(8B1RJ!8U -M.V@KGV8$N1UH!2[]0%TPX?93B?$TGH^XT>471-BJ -M:DD)P3,//=UJ;3;"[,=_[@`[OS&^L0`AU..N#O-Z)Q*UM%R//Y67>[AI\@&\ -M_@$#?JIZGPUZDF<'R6PF2$W1;RR3@I#E!:]0;7O,6030"TG?K+Q`K:Z#(I$9 -M(>_XIH2R"6$4W<](V(:RMBCEGP^/IAL$YU^Y'>T*28"N@+!W)JAK/#C&U[[S -MAS*J-+%>"\Z\5)@RZT]6/%SE0X0%7=5;H.+F/FJ5*4PGW=W/8P@B2KI`%R[# -M+]_9R99;].Z<#$P?\JYY!`%$RE(;DKS)ZNV:L[7_[=_G@):-=3@_L%Q60I!9 -MR!GJHAY7E*L,E>[>*] -MG%'G?BJK>#X@'66,_38.E\/-<&1&I]RV[VC;V752I$AGY->MH[O_]$D1"]E1 -M`14-50;_TC!I7/G"XD`#D:U$F?*+P_/4T(-$LV!P]KR[.A2!1`CNS"ZJ/Z+/ -M.P>U9QSY,#:(O\P<%$.&,AI>XT3HBJ0!=`(X;\5U<1:J#H[Q^&F23=71,=4V -MWQ?_Y.JK+S*B&J@9TZR3779"6LEWV=-TW)V[SK..&3`H3SDQM`B,-41L"4.< -M&`VYL$_9HZQ`_"QSFV00$6HC$RG?%78PNP@[Q,B8C?^K',G']D.8:\QEZ@:, -M_Y"S@K8#]#W\Z@&Z1[J0C8'>L=>)..T&-NY&4#%S'N?:0N$9W6C@.1.E:K.P -M$-2]^$BO"2_C@6$2\R4B@X5.J8*)A6ZPY"Y,]_C?A20CE&[=QA#B"9>52@RF -M3B';ZO79KIA\06$9T1CUE]L,K&8^$PQ.I""R1#51O%3'9.;Z0&>)Y_.:P@(] -M2DD1*N0_Y7&>N0U3OZN%ND)MGXFMCC.04KM;0=+_RO*L(=/QX`_-J6&;;CJ1 -M'4-R]=;J#BG\)Y`F$0IH$>G=9K?8B4V[_E>6D9++*;A>/@OUNX;[P3'$:IIH -M>1!:@PD*?`9;0##BX/$M\IC04PC\(E!QU4J";*0K)'8(&0^'HD$<;T(+>'#[ -ME=J;IUKQ[0/5Q9Y&R@N3^TRJ4NK6FP!"J,\5Q4?^IYHL[[%V2;ZK:O>IOE$N -M,,S(")4M?"TNL2>KAXBI?=,30*- -M[)3DSM=0D1.#`PW\,$IO,VIV=ET:9!AL4>@=FJ\)WE@5[E$UD]OJ_YJ?5$_P -ME`O)3>3-M$]^9_49%^UN::,_JW`UFBR73;L:R.QF9T^8DJ`81)YX1-Q&8!IQ -MLCLP;07,^/WW<:4-0V0<4U=R(#HNM;Y2J[3[V(,`I(S%/6,\K-XF6/A]ES9HJT7!C;_34^ZHRBR$(!O./4/+E -MF0&D<$W/#*.F!$GK'_*N9Y-`:Y;K7L][@=A!?%S(RM1MQIY -M@+^G*$9"\!M)NZ^,2P_MV!A28)E12G*"%Y -M,G#!-]^HR*1TC"7<<@@$DN70<[7)$!AN7!O57,TXN1<()M9]91X)C]Y&$ -M=V"GN`P-LRJBEY?\L%P7+XG)@#=UVR?F$E;P,X<#W;;VF^A///3:C$%+M%]D -MRN!_I:_QCN5U\(B58X(]GVQ=/Z$"E* -MLF0+[QL%\76PK.1Q`M`2_"GZHW3EEDQ?]`7\/LSZN7N\#RN%Z3=X74M(D*A*NOK=:,,; -MTT4(`3WF[1V;4-QYM=7!T=J%I&*ZU[*U/4D%O_\I]RH -M`4X.;1`.\#-]VCIME`\BI)K0'+/ZE`8@7VSRS>ZHS5T2LQA30_WKD38XD_6RQ@6$KAF0:KM%!F4>Q -M[4)&V9NUV.'X(:'K^3/9'7S9TB2Y9;:'B2_/)+O]'(N5_=6VQ\*+DG=SG$:? -M'ST5YXQ-:/`L"-A;."LB#('=T95$/= -MHF9_V/:T,1!O&'2]JX436G`T1.+H0__C[YERTNM;H(N,J<[NTF?17W^H8SL) -M]M09Y6FVV(5?5*J\DE8_2FN%$FQ>6_V6\D"I??&&'])!3,']L>EL4YF>[GXV -M7>CI'SGIWJ^L^J?<;TUZE"I;CK(L\7]3&2JVF^OBVY-HBDRDM!`21JN>V)A6RV8$LW) -M[O=*;U/OJ^N]R'1B>;#ELM!95X<">RQI?_-MG$B,3AJ4X(^R6Q%K.D]ZW52S -M$][=^DVXW/N=;3ZWJ>H@5IPRN>T%&BEAS`*SHH= -M8X87@NV(B-[+R;]U;+8>.^KZ$.]T4;]JM.;ZE\J\/NHPS/G%+1R`%I#C&35& -MGH;2#_]*.VI?/S01PW$7A63.Q37['_B4W/"-N4/!4&J9E)6Y/*SEYVQOH6P< -MX8Z+?TM`*.G1QD6RY?"VBE(\YK2@#+RMQK_O"D'YW7`%`)6L!UUIW\449',<]VU(:2/Z'*_L.#P[OKPL[2X -MG?*I?/3T$(N:G\`*8E-3D++OKGJZ3ZJ-M%9O[:;)4^^X.*`OP.4N`G)NW,A3_C=B&@T#.F^F8Q1_WO+*1W8. -M"S(BC%''^<[I-X&2NZO*C'T?>8QZN48U;&5RR:V$A5/XYAC*@5%6%'E7$T2L -M2=6"JLL"KOO#X-_^&M#-IJSW4][_0?7;`*=4)@N2#B37G('Z3*D;I'(]E>K7 -M&TAD`-P%^K^-Z\IUU)72]>0QL1WA%2$51^KII4\' -MF38=TM%5O^9;&:Y;Z:WQ<4,&I%_.!C?E2&;'\#6:HU+XB5&]=VSFWL4'.UIA -MX*'(ZYZ=&"6"[NG!DL:IM=Y9#@'.8Z'"/[H#I+E>]?!8PYG@D!DSD;UE-:NO -M^\V+.VNE=C]S8CO#D4/0(&X8D'=Q!SFC&*@K;5$(O.J,F+C%(+4Y#[LF>"]Y@3U>F[R_0^NV*3WXBWX-8TBDFN8 -MEQYW[O:6OA$:GD:8RI^N##4)&^"N.PAK1;.9,O'-I#C0QJ*0N_5"FL/W0;V> -MPBBK3;48,AN^`Q94#3YXFC`O?%FU_"O$8]8YZX'$\#8DFQ[3&,PK))I3#C6T\%]V -M]5=.?.A+$U[&:&YZ_3-]C-B<%K&#>)*QJIEW3DL\QO'E:=IO):-7S,A+G:T3 -M-C[2M/.LVS*")O4/F4_[VG9HDJ!U010XUV&1UIOBON:25%H575RD$GFU@JH$ -M>5FKMN8A;@7Q>5<(-KX4>4\*LR/LI2MT&.`,HL._1N[T"XUZB^]G="+2[FJY -M45CV[)+2&_&OJZ@JS\X;!8HFRH/Y>ZFCC_=(WL'DN."?>18C:S>47HL@$#+C -M'DD+GO1)HV9[&68+9HG>#Y.UH/)49!5+Y``R!B(NRN13KT+=')@J.Z!W;EKQ -M(]7_V0LJD[]NJ'SF1254$W(#]63=2X)FW%DK*,JY5.R1X6^4EF&=Q_<&G11Q -M7A0QO+M;FK2QB'+@8!7*JP:T=V__/.3#8=(64)D+D[&@B5DCAQ.XY)1.5HJZ -M/<^I,LRX9(_8SM#"Q8\`Z#9'(]L4>AO_"V)"R0[;*[+=CIA90ZCOU/N5!&@3 -M]^H6)@\$_&BB][@!BIU$3=<24I>`_1:-_TP)F:>.&6+L)]WG6)4T91/RB=W'6;)@JB:2!Z_2D]WYHQ%G -M_5"4I7?V7)!OM&""CYUM%+DG!MI$*O$LPR0:HGEQ;Y08,"BX;.DG5#``$T9L -M?P'P\_N!OLFR3?\J`%DL0:5U3N2CGY#/TJ(O0PT7>TQY9CPXTEMRIL1#2::+ -M@Z!EUHOLKSC.X$.H[J[(%T<+UUP1CI.XUO,/6,I"VD7ZNF.RR]<3JT -MS!.SG$I[T:+@]#-HI'56YPFSI'AI64F$_B3K%8JM>DAD![26!>":YNQ"5;+L -M*O.L8;3I\$4[)(+S$;DK -M`Y[P7Q:28.%`OG#(1/L4\ASQTUO51D_"`%,;[H_M\GJ;SCD:9>3*W+7-3L[V -M_BR;6E@+$:O4U:D"E,%8JA_;WC3:[.5OWG?YWXBI#RR=!=`]-.2-SR16]@_J -M+66:4;,:#97F/3+'!5:';2_V$O8P[3Y0`3]TFD$3ZOG+?]`FC8?,7[4'QM1A -MSQ^CM<;I,D6/J!%*,%YY[&X*N!^"6TG::U053(A.:%4^5])4GLR#-$XSW]-M -M?[FLY.BR9DSMC8PSB,W<)PQ'B"PO3V`HAR`(`![IK7K.T^;+FU^5="-O)/'0 -M`"=LZ^4]8;U/?5"=C"U;V@0!]WVWQ)(L]\"_+>&*`_GX+M -MWY7.S-?$&;_[C'D#A^U\FI]*O0?5CZ#[;\W<:`;M#B`\PL;+M$+['YX$]A!! -M>O8$^CG_=;;W2"=[\E9@#UQ9*7MYWL/LZ<8-R'935!G( -M(]`!T.E)\]L%(J;+K-'F81@>+E!CCY'D[/7%<\+/J`VJDZ`&T%-MG$N0HPJ] -MK7G89A6F&T\P3+4X?XI'#-VZ/QBA('$_V$<#]G``<)PN7M)6*6<;J\N]X<_C -ME/;4_M`F':$DFWB`6(*)[.9?ZFWMGV&"'/FUO&U$<(&OT(=*Y1<5!)/B4Y7D -M7I_(,9/-`K+CD'QB_\"LA"E09U15%0X@%F)UNJMI]_%)+0/)AIHIBXT,]H@5 -MK\FZ`"67]$%8T-H0V!G-`14L"F2__[.GY8?!LT?8X%@GZ=LH"G^2JCO&@^?_ -M[@^*;1G.)2&IEQO8:HM&IN01\.5W+EO3'9+X((K+4KD'6E[-.0T.DY]FP7 -M6,LK1Y<\CR<]1:0ZBNW!D!"'ECXJ[5EZU8 -MT2F0*7;MBD/(_@G.GI;2/5!&J7N?,F`U2U/M9]I-0P#"35K^TD9^+&/WHE`?QH$PV+=__Y3RF)+- -ME`&:`7R/^:;]7LH:ZXY^W@IG8/NMG@@Z,XPIH:J5[CMJ'``"4 -MR9X(U8/O'"ROKE%D:4)`1')*+<>'FX%(X`-AF4X;NKF,3YY\G4QI42FTQ@PW-N0X -MMB?1'4)'!Z2I%/-[)7O!7\5U^B'35-05W3V9TM"Y)"$3!P3Q`2-N]N-W/E:K -M5TL;SVO5F6Q2D5,9\GD.L9/LF6TQKT-UTL,[!JBTW8'NOD+K-,_%UI[X26:< -M_,2#K:>'=&UIZ\XL.-D$] -M`"=8?#ACSX'@F:ZK#5`(,M)1@H&I?EC>(*&U-@"L(A\E+H=)PSY>,X)8L1L! -M37L4AAF:VZCAW&GVO])5&GC!-Q4T*SDY&[C%@J-$>^R,2YOB: -M!&VJX-W[+@S]D+:"I:MG.X"-:_9@%BS7YT*C^#^'TP=-LNZ.==O^:LR?F0WW#Z@6((R!V'P+M+;3%OTRS`%<3[ -M"S-;6%1@ZO.$(0]:"]^H)'HI(@++MP(1:2!MZ2FU^Z*][(F^GE7)A]C4TB4`#+@6UX[<4X4QB`YNT+*L13(N -M-)TTHI#PV0>=V8Y[2)P,SB&*NN=N,%A#9`2VC8MY*F1M4(W5SZ#>S/"".FAM -M0WV4',@0(;_],BK7I`0**A$PYT)[`[7L+/<%T5WAI93<;@L:E50DU(97('9) -MD!]ED!`%\NP++$,/^P::"06'=?@FF0/]!\:K&A[O#>M27@K>9=[_*FBM!0UQO;E,8N9C -M?V\UWZV$0V'H2Y9"A1M:<`-,`D5JQ`1"97.8W.=+OS:7>-S2(%BJ>-^5?[46 -M5G$N>(_+@'UK9];L%_@MWU^H'FV8?86KVS+8FX[G%X%UW$XD/:!/R?)->B=* -M^_)7[PG]QK%6+-_PQ/T`'EF$)&Z60,#4SX;^X'TJC -MN&VMI.O*&MVP)4%9"3%UP*F^R#;Q+T"K9UUG^XB*B7EA!M%!+7FV.2 -M3M$DN5<"#0T%`MLY588+Y7V!.DQ7N"(6+TM,7`%GH5?.EA@=H]^-)=+ -MMCGNZ;1&-^&E-<50HS.Q-?G;PY/C7\E(\4K^??A"=GS -ML*&QLA$`N,KMM;*/U$+0)LAS^0RK<;6H4&BD20HOU@^1?)MFOC0&T1^C& -MD<>1GU$;AZA_G^TA,%M5[5W0Q>44OHZ+C%4#M&%&].Q%N@LZW*B:7$++TQ6WIPJM-Z];.'B65W -M-6T6S.G\XE2]:`L2![J59(*5*(5-!N%3V)B!21,9D.+L8WI]4/O;.HM_@P/*4J-!\ZNX?UUP,\1\$:,H%20RVW)-#!\? -M@+Y'%&>AR5*CWN_3#]5S>1RY4["KSY[,*%6 -MW^!ABEAPJ-_=IHGN:X)ZX!`>L0N-8[OH%((/U![&S_I]#"](M1J*"2C>C<&_ -M0.+^QB!AF[61`*!WBJ`S*\Q3M-HTU$4`HIR^,B>,S1?CVS`-(J,H+1=#O7%) -MMJ45SMV,?)+=42*OEP>8V`\N+;0]_P90(LLQP&5+[B\X1HU]NSC_8W2)P)W] -MN&?:NE( -MR<)KR7`DY*N/.0^/IVV]_TK+ -ME__6M^XPU'^=$U0)6%@2%-7:9HQ+]H>:P#[7LNKP!23,L7?-"K^_\UPS8,-! -M_5"A#]%!M'0!9Y.XG(1;UZ,3QSVEY8A[3C#G(8MYCB7M"R#E!@O"<+3_#Z+) -MK@([UEYD_*9FB1.K64$!L.QH"WL`:HOM>?G9VY336P*?_4'0HOGNGG\_]+8<'VNFK;0ZGLP+\UW5M32YQ?#4T, -M!7T*`N&4:_%+QTKU&:L"$+K!4%L65^P%*O;KW""^P,F-C22QAO?<7YI)GM=, -M!SP4V`Z+FHX1D\MY39T.+#!EWD"S6[M/Z4$;8)E1`T,-@OU@B,['G[MUQ`!4 -MO/[RW*X+S]Q+&8;*:Y_6*V]L[F(=U4P:SN-UC\<9OW:Y)4=>@8^=-*V:1A`S -MG^'R:&"OD0"CXS%XP'HGQW0PXT]EL)>!?_>:Q#:>VMBY.M -M-0%E;I\GOF,^?_UY]=TH)XQ])71G09AAUO8XIQ]8&5_X;9MUV$K72U.FYKJF -M+3*/H1,\LK"CJ!^<#,(3WTS;,E$J5# -M!$C417!MY_[<(U<;B%H'H31V; -M+K<0[,C<"(7P$5E]]<7N]Y#]*7#8/'-0'!:Y>2V_&ZDF71&-SN+05&>(LPAZ -MW&'->O65]O@]+DAU[HW^K*8G4SA^H<=@.R=2E%+5FX@33OZ -M)VF/3"5PUPU-(&+_5P#8#;*S-W?/S[+,G4/0N&OZR51+MBOXD&)V5'R&J,X" -MJB&_EYX6$.9*GGV*_ASIEP%)$,=<#TJA:1\A4QP&W`XX1ANF55K@>.&08<@V -MTWKA^%T22YR]$,*Q`;*;\$+ZG+(5/^2ZW%B)FM-TJ%LQ%;+EJFT=]2.29?O" -MY.@#C)&GMW&3G66UJ<`R9K#::-_2L$++/EZL!W\H+`>5R-'8>+XG@HRR]LS+ -MAC/P$.K*(YY7Z6:DB>YW#&$:O+^Z"A4C2R;OS*\FXG#,WSW]P.*?,E>%0#N]IJ)_4;CL9^159!QC -ME-@.N;39S@'--'D^ME2$M -M'%.'-Z?#Q13M*39*([?L*RN=_^2.8)N=E'*'G^ -MH8W\?HI)S@UHS%LTVNJD;3^E,$UMWSHB40T05]LI?\W!P2;J7$P4SP\S18CO -M7M29H/._1BQ4G)I1N/=2%NE_[)<4L41S -M`]./A*C5_`I('1/S10@6;V&*Z<,>4A8X./X@D51_ZD -ME5N+@'9W*I!JM^Q+_)V^()3;*G\(L+J6.))7$Q:RE`+;\1Q^6),?Z.\C513- -M?38K@R5;G+JFW;73SJ5++C?]>@QM/N"VW002N_:<,>?4PC1JMUK0$5((?%@0 -M)>@",D_"D`MYH1/!+SI!7+)+4D2>'FRJW1,P$'%]"=R?Q1_^M?N!B*#R8%:VZZD:ZB^[-2[_L]]?ST%`.KK6M&'E#V^R@1#H"HIG3)O<<]=V,% -MLT&Z]:F[IQ[X6KXI#] -M,N\%,I09]*28`MP&V9\2I2VM/NBU0O_0]*4A?A_VK#4_WYH=^4V;E)(\NXIT -MB>93Y1?=^65WIIL,8D.<"DN_YG*C5EOWS?DZV1B"*XZ.%V`F'^54N,`EZUN] -MR`DR7LN12@T-R\'?CQ%X+'!1]ZSOE6&R>^% -M=0*V01"8NUQF;HZ_)PV75H9IC3R7\IJPEVO2:;>X#E,`&D0<$!P+<;$L"3P^ -M1\2"6C?]`SL?\2Z2X%;624.WH_,]T;P_LYL.5/#:M"5A2^R*]JT63M&/X=$H -M!/9!&;I_VZ&BZ-/-.JM"RGJ&4<8[;A@)ME%54&,PVH(&_QW^S_'`AUO6_56V -M/J"S3E+GAQA9.H1_\"+EV[%B]$*1F=@ -M=*=Y]HAY5A4*3$JP+79%.FYR9P9<_+OS\0O.*MZ>]@(#(IW?^('(&?=-2AJ- -MA?ST?\JS37?P>H"!ZT8UQ4ET)FK_:,^5DSCMF?N&M'1E,$S"44FLJXN\=9!( -M;-LY,3#(#S<550>$X]:R`*!BW$W3`8(-8?*QFCP#.'&IM95$+\M(= -MDZ>8**XSW%Z6+:?S9'HKN[:B84RX'>U\-)7C-XI_F/`Q1\-QPA/D(>//G21I -M9%1E`II?I,H)5]HO;K9*2+'^9HP'P2>]6\$%?/3'I]9[(U8NC<\TUE0*J:F6=#D",TR;Z9H.6F*+$E4F/3:KB#X:!F*@1V",A6&& -M#80HW^'NEJI]X&O= -MX:>C\)()EUOF@//>>>3O]B"^=D*";6\*KWY.6_D)OV0,)2(A]>]?J1K\\D0" -M/&;TV?\G&*$8,(B'=H@\T7);QQ):H"Q=,?]9M9JO(3P*_?C];R"UO_CJ+]-,=K3&_Q;=O6*5M"$HBH@?>9?S8-&F9.+O%2L<<7^@KM(M)&SB,DS]("S=%NT*'V).%PJ%:8D7BP`D2GJ'HE[Y, -M6QWW2N6HMZ$WJM5$]<^K5WBUV)";R5Q['TM[#AM,!N!:"5$\<"?$,^^,5)J@ -M@AYR/(2O*EN;0P6/@O!@2$4P2?/D;HI/-:WEYL(8#+,CX:[/:JY1LH2R8:Q[ -MR@IC"-"?6-9MH5KO8=&FJ98T"@VS*TMER8FO?6(\-SL'&W*[1Y&+.VF:WQK; -MD7IE7W7,C]8S(LYJ6P9R/0I!E'!@=I'(%6"&LOSA_> -MG;[#C;GTM+HVQ2$>Z%G-\MB4=M[QJW-J\,/SX?+,%ZKFV+=Q#`5[?\9@!/_W -MOB+2(-GNX`)L0T!RR'FP[R&^/6U*V()5"XOT(OKH2[2S/,&_)80 -MKJD;"Q4R\R9PO^Y&14TXZ!!P/'_:B%NQ!:*)*DZX1$GY/_%QJW><#$4"=",. -M>?+UD247F""S2E&GYUW)&*&7\`7RL^/#IYX&$V8T9?X`[N)KM5L0%:XI:5>> -MIR9`;$>"<\,'O-YCD[('HP\;/W7UW&;7_PLPAHZ`?OQ3.<`MQZ%S<\4[/*PS -M@J_9JB(5A?X-W)S)NL")^Q[WB<1-E'-T<1)7LT@;M>YWV-.]7//-DM -M-ZS\?U1TOCIX=F.^(+J!S>H>LCUY]@@ -MQ=I``PY19J6[O03MJ,&S4"+H8///?[Z?J&B8PVL>,LR:K?!F=A7*:B7$!(P,[+S^8Q?4!>(-,3G`C"3KZWU=B+[STHH%!$OS^F<-B]:P\\5A@B\S[3S(@T] -M9CXUQ:7*T)*C_7U;!,X";KU:6CO+%?9$$:EBS/L]$A83H@"%"96'`&E)([Z0 -M3.8T:,X.UZPH+*B7#MZBF-\:1271$K#"HO!L[HX4B]2VP>+YTLE9G#E7I:R^ -MU.QQ<#&.=PA)/ZA!>&P?V+@S`>'-=;T..72='M$E+QCKV(_^G9N-/[_-J,CN -M@&Y?L>V5%`6=H8Y+;_8XVSRL!28CN*B9_<$=$":4'M9LNG?HD7GIQFWKX*`Z -M[I9[K>D-\<47=-7&+`YB4H@$$`6[\V1,%IBYR26TUHX`V20]!$6(\W[V+5HJ -M$LTE]^?'G#>*S#;ID;4$8O+Y%U,F//1+-I$(1=W'*6IBTOXNM>/\X\@!5>][ -M5%1P'GB,B%L;/\4RHSQL0WB`)#-JE"15@+P6""W:D0CAR: -M;[J3M/"QN:?]5/!IE"*\^":[,D]O/EW[N:RLSKV_H4#,&/#JJV>8S%#Q'O6I -M.H,TQ[M]5&G*.EP#UFI:ZL7!F>Z9$=02WC0:>^N(F;W-0_O2 -MN$!T)]L)9SR'YWDN&=>ZOL-@=<=9X6,63@SB9&><$K>[EF\1X4SA,%'[. -M=Q&5@>17*Q]+V-&47"CHT3C*PC04CSZK(%FZ7C+9?X+CU:F*H+T@X'U8X]]G -M>QKL3@B;.5#(.K]\H*SU3#B2S`T@SVX4!I.6QNBM!29MRF+PRQM -MSV!PQ_>BBA%V.)4( -M)TD209KWV>J'8]Z+#8-DR:9'SS")>::6/`EE.)[I6G_<&CN+ -M'%OB(58?6[=Q&BVHN<[F>O6F`/,"%9OL?_O]7]=4D6)W?SUY?MUUL<%Q_#OC&U,Y?NW,ID8L5;V^O2)ADG*A@&I[B3JQ>W!^$\\%+( -M^#'0THEC"V0KZ!Q!4ZS(5:92U,Y>?_^EEV(;Y?:"\4+`<9>$)DN*`UY?PUI6 -MO[-RL):2(_0?M<>2C&-<\[L"\?HW8C0/LK'^Y>(6'._+R7@Y[C'<_JL1,E;6;4UP`EBB[5%*8=@&>J$,2!S,MY!,^Q*>E@DB/ -MFTI,T0]K`09;QN%0T+O\]:(S`EL^(M=;KG1+4(M#K<@CT,0>X9<9$:G(TM>0 -M^+7Z;@?5`KA[C!7]KIF:V%4][%;D,J5'?._YV+LM'0Q-*VJTB#-C82FJIQKL -M'&D'$S;LA_VQF!*-7;L]%RA,G$M8U:B\3;X^F!#6!QOL*O'N26T)MWR%/DN4 -M-*E1SHC_MNM-SW^4KLP$NK[3-W^-@'DI>,)`YQ]_T(!42A0KQ,>U8>0'\94V -M86-C.$$*(KU16XCS?L5'EK0XC;`0!V'&F,>&6-RY+GY]& -MKSLP^:)>7PJ600C6+A%M-\$C_^VKQN7B-RMAME2201JVL$<-$Z^=4TC6^IF+S--X*]^KQW)[U;Q!7=Z#428S3@LFH -M5\(JDHDJ"ICZN\8L5@&`)!$%0"=@):O0 -M*^]!@0O28L.$S5`PHN\[NO)L(>6!!/U((/B; -M$24GJ:Q,#87W<],\I5430)EKU'B]1([MS1RO\_A<0MM5PL1;,1=EG9LK1FJ9 -M.#D6]FWE2]79919H'Q\X@E.ZT:H;M9[P!&F9RY>M3[:.$8V*@Q"VQ"P\@-WR -M_DSS=BM$J!0@U1^O8$4Y0&)`7I?9KV2VE0?Z_JR6#FSS^0J2Z-3L<64_2XI` -M"+.?M"#8W9^WAT-"*]R5UJWHB)P/S"QK6Q]^3G9L7=WBG<=OGF%1I*5W="OA -MC*19S09`#$:I?T,B6ZQ9!%/69;'8BEX=V4:7A9LL5KZF2)E9N7IZ22#[[D!- -M;:?.Z_8Y)8+W83\GIU,78^S[$A2G\UME`K7C(4$X7,"7;X^N1^=*X]MC'(>O -M_P/)0*OGT%TA3M&&G-(VP[L?Y04V^?^S*P8W\(OR-@#:W6]G+.$V8]_]7+VY -MQ#'=8/C<*+U9%\)J<;[;*Z_QYOIK@T1M/2?/`TBF-UD]RTVT%4'7@@_C8JHYV:A^H/ -MVEHYX??&I8,E\;VT,#",3D9YJ-\%;=(:R!FCK#&6#+P1Q53I)*+C?%$]]].V -MVU?=7)YN\NU39)LV\:A2RNLM&NH[E'YX"9G[[ERI6(+*AT5:O/3.DQR[ETVL -MILW0*U^1T:I12U(WC_._F=$)?$VQP%XVT((GE]I/3G7:;#\O]'L>G1D!N,#) -M"/E$"P4M-/2.BG*<]`;&??AT.-*]+4^@UF\FO5098%%R9BR3I=KOP6>C)PI'0Z^WUF1[4MH -M%S$0QT13=1A:#U_BR^TF&:HN4V%3J<7U!,1))=4U(,&<00J2=]+[/3B_M@&7 -M^I7\?9%(55;"-^$R(:"HUO'W\9I]?-)D.9<%5IB7CIX,\%5BK2VZQGK-2C#0 -M)+O%1Y._'YA]`/TS+4P-/9-HC][B8Y:O;L2(C:+!&GU33 -MF_%>9'90$$;3A*8N^@A6]#P\TB)Q'-$Y!AHA?3MTVWZI..5E/I@2$DQ0KS9= -MX.U>PR&9=XWH^8(E3[$&X*D@PU-$?.Y$+MQ&TGLSOKRFTQP/"S8JH,_GW?*3 -M@9=^?^T8]CAMR7-4&^;8@L&A9L!8TB2V6J5\YS5#*:]55)Y1T@&V_?&8F+M" -M-1K3Y[N5EJ//1WOGE9&7\G0E?^_D5F5/H0F"%#5H2\V6$OA%\(MY-AJ -MHC$&R*(C`'OPSN)Q/1ADAA\+$AB2T[!\GSK>Z3'1V"/;Y<6`N^NLY^)9TRQ] -MJY%<#`6'O126)V_Q_9P*M#NRWOA-^"M(EMA)E-!S'VG`>3%NMQL+N6%!G!"" -MQD80S1\0I`ZTK4G@[[;V,0BB0_[T@.KP^'K\%Y_TD>[YD339`(?![TC+59RJK=M@U5'@)DYTIOPV?I;]BD)ZA?@P&FEG_Q,LRF^ -MHHV(@PUFAS"[V)\_FAAPX69^N\7'($UH*GIEG;YK#.\_]V3D6.X]:5CK6@M/ -M"U@1TEBD'P,BC=-V3:L_?]86UN0*_4L:'%"MM/ -MH\]\]]_13F*3?5P2BWW,[3A7T.;>^D0!3RN3WDTSKN43]&[TU+E=(,^R"LP\ -M'8HQX4B?+0F7``;W-=F->/:99*G&[FX367!`Z`!7X*K9)F%N74]>+,M0Q<"$ -MOXL/8L6I@\D`/"9!0EA]:YW1]O-,L*I(7:C6N=MLQ9C9%Q>Q)KK,LJ9*&*_K -MF4-K!R$+S*^:YQ;2%4#QI>\Z-5)N-.9K[ -M7O0`B2>.LZG4=B)X95A+_$%JFQ-\8]0\Z\J**-NN6D=S8OZK0CF@KC@K;Z6^ -M\R'!%[H/2B$2?WA:/J#P_YD@=T^@CY<0W@;CG_I]]#H@L`::.GJ>I>ZE\[.) -M\R.4OZ-VE[P@G`(B%GSK`E M3F45/%!V7\GPNDLH/8?58ISFV.MU!"Z0HP -M2"*@27:DOC5O04E+I0`NIK<[B["M>C0\;L2_--/-)33_SZ81FYF<_9 -MKF:X'2\HF%JZZ7697XIY;\%%61;/2/K!:6:-80V>!F6SZ!TI5>= -M%27!Y4W'L;=,U,G09X8/:JV9)TK`@'YEQR='F=<\FR5<_DT/,6L-OEK>DIP9 -M+.X$M-K=`5C6B"@T;=MG.#V;?/_P.CTZTZ77&YU(0G?12JXS/10SJ!R#%=&N -M$[!4UWTX/H+LS0-;@&_.#9B\$(F*%*XPL[)*]!'8ME_;U-_>W?'Z -M]=#S;OFZ1"""D -ML-^6<2<7M7;XAO<^_10O2%;F0'6\=>=2SHQB-D-A;NHV;PA'>C^I -MRN&Z;")!,0F^!]*EJ]#O!B+1]@(:[&4M8!G!N[>ZK0'#L3\H3">-):^?[89;&_ZV*Z,8#0[702>"=5F+]HC(:'?R]6X7OF -M-%Z0M!A]GXM527;(;9.Q7^G?9>GK7MXXK[MLS![*>*79GN0'^/[??S( -MATAXF4H57";6DZ,)6IC1.4Z,^-[:/[,W(K_6V\Z:B^0VD7=XQI3!:ETNH_JW -M.XZ?C(N-]:0P^]^7@IBW&-#T\"!P)#H>B*#L,&&IG^-]IJ>"^?_7];!N=&X5 -M`?<8,MO313J8AH1(H&WDFX))'QK>LR2*^<&&L;\>Y[&P97M/ACGA)1[Y2@YB -M`]]U:KCU="%]!90TC.X.96 -MS_W*K,3\HDPJ%,]GJLUVE0DCLW2#W/=54K6$BY`0S#L82@/:I -M9(QL7/SZM2TCC0"T-=]\48F$IN..4$[':G)Z[)`S8C%#`].W*AF3H('$-7ZL -M7ZIZQR`75>!<-WR=N)H$HN-A5?$FYG'MC?!\*@XX`ERH$\!BQ%5 -MS`0\9**U7EL-C)0W1$O<^V$GTX^P_$RESX6CPX'H8P -MH^!M*@52F8%$Y\:^*T4`N3O6U9DGT(B!;PC$_`0D'!#"]+"IP0#5,C'T]T[: -M-(;$)SAKX4C9"+EQ=+0'U;S6PO6G6.V&*-OG=A:HP;7C_/LW+P7&D;TIWH`Y -MOK`E<1U5TM&,_;M?K#"IB,";FL3P6WQWS:8.%:Y7U;_=&X:O]T5MB[T]%V(TQ2\U'/="39=8]9L-.7A3;[FZ&`6M;D^YI.3P=G -MT;J^;SDT5V1\FP?;X.0:=2@.(7YM!FNW(O@F9V*HP2L6I#TQS'+$AF+5.O?3[^D5.%<)DR@V<Y`DDW@([^:8`DY_Y2A\[[^]!7U-+/>6CB" -MHC_T6,[&/X-H(3`P^9A:>HD\:%X(4EQQI>(TFNN`U]28>L)<@5>N&SZ&7F>K -MKMRIH/:R1RM-XN/6$PZ60_ZO@\U,X>=7EML7&$<<&)R2G^4KA7OFEA"VUUMV -M,L*M'G-1<.B#]F(];O3-1=E7*3K4^35,,8[29C[5G]]K-N'NB(.B[*JA<1?R -M2#A8B'`D4C`'874C`U.T+,I^3\%^G6"&N4*F3FS-9C#G2.UY(S+TQ`2YPHYY -M)J4W,9*:98R#=6? -ML__(11D]D1&!%1O6&EX;.>&?"X!R&59?XXQ-T\)I-9^'#TB$"\*^@?JD2F?! -M'0Y-TLB\[:6'@\$U`A)((52&(DX^Q`S+T<$?;RJSE$'^?KVI.XL)@W50#-2D -M'NY%5@ZNIH&LFON=U=7@WL9?OO5^BP1)'DG&'7<*7Q(!CC24,18'I;EJ'C1M -M0IH-77^,;6$`QKF-ACK^F(69;EB@+]0\WE%'O3!2:32QEO^]]9R37++3^22L -M37K,YH3NEHP81:64&EM$?3/ET[]_/Q41E"0_EXW52[.[Y7LUA"VP+BR*%,IN -M@.DV&LN+?)L-,PN7RU9D`+FL`#2FVB%;<&1=1SO#*UB:^)!I)_`5]9+=LX3I -MGFIBL#:2VJV])]][F+G&9N6V5RM47(&I1#%4_+Z[H@\@`P0=`=B%3(.X&"8M -MD^(J^T/B^/HYQTGR9I)/PO^0)Z,*VA8'LWJA8@T@T;>Q5Z2S0,`_M&BCM>KQ -M?:D&4Y>(]]?.B0Y,&O+.B!28R!?.[SJ6N^T)^MD:UZ0>K+M)3<`Y1\^<;$=) -M0S551PCN4QAJMMGQ]/O+_5XD`[&<0WNUGK=*YUJ`)./*_]UF.D$U"H62;UUI -M9.-3QTI94^`)?NL>>OC.#GFZ`:-"`A.%<#P&$E7`5*,K5 -MPMKV.>?J_G?I&"X6*?NP\6;DO?I%>909D.4Y'.^$72T`+P0I@E;]_HG39Q[L -M^S1A,T`Z>L.E*M,PQ)6@KX:37>:T$1?LL4(0DH3[7P91G>/=#*A[`9MB2L/M -M^XIU,^3^QFP:P26NK$FO;CWDT=ROHP5WDFGEJ,R6`8(?\AS.M_\1RW4E -M("84ZB]16`D_EC!LQ:V9?S/Z]';7V89LB+>UCQL/:C=%-^:=OJJ1F783!=N' -MSPKP6&337T6Q\X!9KZ5Y,3D#[T$&M7Z]7]J+Q.S5%42L3S@2^C>2QY\7^1R[ -M$'CR!O`V!'"HF88UK\\L5#YNVM0IK"GB\0SZU/@N,8Z]?RC?;;@-L=8B5-EB -M([D$:/%1)*JN(/90/Q@$4LZOZ]G^\W;/4HK%96%VNS?SWW$117E%[#0[*1A0 -M99!>[6J4V-10CBM%%'I4O)ISU+`7M[QC8D.GM)4J?Q9AG.K>`;UIO4_44!Y# -MJ7W>ACD=I<`YX+##DYR)QE_DP'Q7VY"`+7#V`1]/2"0-.CZVSP3X=*9U:0C+6PO/,CPWQ` -M;V4'%^K']<&)IF+&,4M8\_#^$&%K5$7>/PO5IA%,4BQ)`UP8\`AT^_G%Y5HC -MZ#;KD">Y.2X>T=GK&7=L'&5<$P?_4_2*,)A:*(U,LG:_E`O,=TR6<<8$&@$B -M]R!8W4>0&_A!X4Y)GUS6:AVST,QA=NVY\+7S_ISY7X3+7'`&F#X)B+`I1$': -M,AU<"A&A?L_"&UC;-^,[/"N]#NR -M+)Y8)^#K1,!O%KP`OWZ5?ZMH;DF\?+!!L`K@*N[B?MFAPMN5,WU83V]<3\J- -MI:WSF2\OWQV(HKW[&=6$2/F\;"TQZJF<;:/N,A_YJ%@R\X0`]+UC`ISM+>4K -M.F+B2F[B=8^A$+[UX[LE`YR>K6'HL6+G[XBZ9ASDQCA@X?I$;"$ICP6_'2N6#M_PP,=F&*4FFIX9*2>$2#R!,/Z\Y#_4 -MYLW"&U=>``8-\^>ZO/6^V\N^[!'ITO>/*385PLK\1W=P"3A^T-Y)C=-0&C!O -M4R0VP+UR??8N*6E']6_DZK9SS5:SR$2(3!YH#T9IIV#7-%.YC\++Y"#@)/V#!J7<`MJ@F(72#3],!>6)9A)JW&7>4`1 -M+V3M&,W-K$4)(@;0!OV-9=+M;GG.:%I(>=^-XV7"X -M)+M/LRD"3;X5&E)0I_3@[&,BH6%.3#-`\YGW0XES4U(NAXB[I/YHK23-H-N-9RT"8V!T'1 -MUE_7H'^";-%`''UA&,Z4_NQ<;J5%JECE5RKQEZU5LZN7K;C"LO:;.=Y)FIDV -M">)$$67V^OU)&!,;I=W=TEHTP"Z>7\F#1U[9(RL)O]5$=L(N7O"!;EC@*>8' -M5*)%J"/5G,!+A]K[@8+$(K-[[N5*G*IE\Q%1K]T*MVU>^.1K,_#KM3.Z1DL_ -MW\3M!VW'$BW)!S>A@MME&5K(;!8TONHB[=Y7MKK+%FH,\:.`C/L8H^N3RO2_ -M:KH*WO/_$E"=?/C:=8UUX)@3=4GWM=E.V_R9[(OH+9J+E;XU0?\G3\?2K6)- -MY9B$]"" -MI6JU)[B=]9(0[>8MNO;Y*5KO@A7-6!XB5#>$]Q!Y\&\T<(]RI)X$G00:^$*P -M"Y?BP+IV:9:JCA>2*;LQRS>DJ9W\VU@!,W.QV.YU=")Z$ -MLPP-%GT3,+IMTN:4Z[``^0[(U^N]$[0P2,7'/?<2K^,)58J]T04 -MZ0\*K=>M&?B"28Q!-S49,V+_=`QSC`[VRL3A)!9M -MN.E@8=->R:$]7UL@MK(&-+/-&+7J/I9$LVJK$V0%OJ(!_[^\`[WB0@GGGJAB -M@*B*`S#PY^C#:%#"QCEN2MKG3F2Y`\P2CW=SZHZ7B6$O@/_GB@5WY?KB8UK' -M1_A).-@\:J=2%J/M\0Q/)W#VL0V)YE?C&^Z"ZHGZ7F'`[`X7(3+\NR@[N<5U -M)*_7?G@=BXQ]=`9;,)$FJCY/$"'7!\O+D??+-4;*1@!C3G_O-2??9@9WGU)3 -MMI:N&EHPML1`D*"4?K%R1WW -M*2PW:!'H)9Q;VVSS82M6T+JYH%&XQ$L&..,F`WH&XUQ:8PH>TA -M^H.,ZBRN2-6=_Y/+4$B@9B'H#*&WMI=[:C_K+#0AO5\(0X\](_J5H,9W2V'O -MI3@"I:WY+853XAA$/^TCO&^)=+DSD0,-_",7)WM]+]X*YF0URJ -M+U@";`9Z7%2/,1IK\8\>K8"/_TS-(1CFT_,B7B29%.>*/^U\YW?\G-1X'$D@ -M]-#[()A,\#YL-4XNF%GNU`*WU)79.K]5_1)$'?A>-,7&KE_J;0(;@=7\?:&, -M*4M=C.B;$Z$OBO=$" -MB/5Q6:BLO;=/`:EQ<2/])C'Y43$8!&O61EDFN+Z.3#M2<"?4KF+]0PLR+-U: -MGD/3EZ78CRCV:&F*KNQXSF:=U6K$UZ/H@M[MELL^81_F3-:;F%L;OX0Y/2UN -M@_OWFT!SO$A[!W2."ONZ`"&^T&"9_*R:=!L398__XX("6,_UD",.#1J_)?'] -MN61FVL;:D6J^<'&PX-L%AQ+_3.3Y&I'>8U+:=1I36,[@U>_ -MPL$H3$`=7_7<59*#F\3N$3-7/%&#]-F,EGE>\E4Y80H($%A.4J#S^J22]Q,V -MQ0G>@F;*E5K!/SEHLUK%1.&0XI!3#YDBB77K@N1Q@%N9^`7P[+ITAA^![3_Y -MYHDUNW*<)69?K3W'SHNHDK4R5L#:$3(2F7%)FO(KD0(,LI\X_F,?M!K?:!<: -MF[2>:%8Y3/B4I;\THR7F-1C=3R@4"LQ;;^=3^#E`61E"C"];F`D-[POQ86SU -MX<.!)3C8+*WU37'FLZ'_UI!QX'P#VG"NB5[]!FO8 -MI#$FQ42[,=Z1:7\1P"V(H$!-E>:-7B/,14N(/I9=IM,*(#,&F[#LLB+(0WQD -M[`T5'UO_L4I+Y06H[XT[K6(N6Z;L3^/5:?=('N/PQ36A5K4^%$5YDM;*!,)^ -M,/2>UUWF])&1-%\*."%D()/;3CC+77[TCJ!!&WG]WOR2=KKD-;P%Q-!"LYHK -MH..;>U;#WJ1+EG.887VK).1W)A??Y5V'X&;?XA+OY-!2]K0O,P:$4LXJD> -M;G7R>R;7^5K)VCT=V6==ROW7%[9R@$8K>QAV?-#IA7A!OOYR>$Y'O\,ASV;. -M@)2$36S^O[(ER*Z1*H$]=;_V35_CPY>C]Q]!VAF*3^^W_4?G.&(5]!C3!V:' -MAC=L\ZB35O#W11PU6O;B`#V+%G?[;$UUQ9YR0V;1^;SAK<:`2X&=JH_B+,>1 -MLV[2G'8J>!I[U33-QLHO@G?TVM\81N8Z9-"D8GL>M42N-:7Q:*N^!9EA -MD6=^EC%O5I#^O8NF=`BW?CA],%O3B8[E;O"UB_P/8.2I7;.LW\F`$Z#@EDMN -M<$&TI>\1\;3>L>G'H9;:6,>X[&:_1YMF(4Y[?PKM>/N?U",NXP?A[L6\Z;WC#F'HG'5FS0][*_#:-K^JS01(N!A.R3^87C&3Z -M#2*9LM'I]"-\[`[)_X;_&+WZ`:!]B$JN_$VQG.DJO(K&*R`"O7RS3Q)N17U@ -M%_+KBI?!?%0XSUG%*V(Y)H\.JD)]"W"]]I@&("0@#8$!^C=,6I+/D\M^4>64 -MD+Q')CN_C-J@(2X\#O'X9I&F#/J<5[U[2BB@\UAOMT[:V;[$4D0`',A3>(YD -M=N3'D"3H<%NF0OS87:9I!U8IR^Z(3X?HBCXT1'GJ^^+MT3*@%SE0>8DQ0Z5? -MG[?L\+*E2E,RKK<`,?*L>I_9];5I$-8YN2P5OO;O6\WA0;#$;HI'W;*C8"I# -MM`%E6P,X]S).?J`+R6^@=22RJ;5M_J]S6=9-(=UQ2%@S?)IU0R$HU]5%/S\< -M#<4&%4P[36))H<>HN73CEY.=1](/T?BD&F5`,_(:*`O#N+XQC+2KW)?DE!]C -M8S[-_"]M&#R!J'-6.O\@B4Y%!MW*Z<>`JNR(38Z%MI8B&@.6H5Q!!@MND8-) -M#*KXD<)`UJP0ID5>ID#-X*6,K/##N7?'ZA`M0OT%[P2WE=QU3]1V[8`#A7IX -MS/^B3EP9W7:@C>2;1PB=;;NN="%-1\;)IMINO4LZ%O6$9H6\XO"= -ML'^W.,5H(9$#[<.40H>E[(G9D.U"\LZ_1*K[X[JNPJY;H2BZ&AG0+ -MK)"W\J')@C<)?-!*"[Y(#M6OO9?"XINA-H5P00!NAU[?<(9)+((HQT];H -M$MB&K]]$V36E:\*/BH3IG8E64GBZ4!/SIG1?R.#D1*`?(SWR^]#^8+_&.;:[ -M`LJ;'?%+RF<.^*4CRI%APLQ!#Y]*[A8Y.\2_>>G'7Y=LM>;LBR=UMA^`+6V? -M>'@G>@,#N*2,Q\CUU2+IGF?QIZ?\U_J#4!BKPF>;F'T_Y"6&?)3$MJ.>6F%F -MK\;H^T-[&"$=F:5\D-KD9E+U0_U=E"2ZZ(LXWI1ZWLQ2^7`ALGS+[\1+[E[8 -M[9[4&6?.$B+D!#FN=7D>T[*2"%@X.&$\R)D^/=HS2?G(><%0`'J"BW2:_-4' -M&)O:@:4+?%[457V0D&HPN#L_O1#BYI@O>FT=C33P_ZYK,P7U=,?4%!N?V1>X -MU[=P5_.4J@.#)CP@Q5'BO%^+^>N(,:FEF]5N8XFK!8656-N!*H_LBS-CSLBB -M4L*];<=.8RPY/92`X.T7(!.2J]<#GX04ME(8L\ZZL(U:\`&\B1NM^';67G$V%'?6`QO)UZ^'02?S4JHOGH'PD] -M+!`I@+XT"^MM1ST_Q)??M?6)-D0.BI6!#D.7QK4SAT++=(+ND0I^G"=XZ_I6 -M2/VB,0PQYD'^*9/Y$#$&<9)J/8@!6\A6_M_#>'G)ENG`BPU551KT4 -M'W([;W-$?BQ"`@HY\BU;/W=$D==2>^"7[:.PH!.)Q&V6:AUXU]29@]63_"1< -M$[X55X>RLRC(:GPV?-!VH9<:NTT@7NR]ES6&^?9$K9FDNOW -MIZ("6"`GD(J:QCWU-$:,:JO,W?N_>E:L*3I<1[I#S*_8(8AJSK&3)*'$=B6' -M,'[%W*UX3%!K3++1[V:!=A;98YBCJCEHQ+;!V(=^#+KUJJ`6-\]/(BER$AV= -MIE`/^=:8GS^O0XKP"XZ?RA>C"$600VPE*OS`#VF8`,^JP(M`JRG1C?W$,+]? -M"0D"O<*[C%)Y[N*SZ\USC"-/(D6S#]!T)\O!9R6]7DD=!1PU[@X*@##8+G109BW4CE:F5 -MG1CY]A^(12.Y>RW6599@>T;]BO"5]?.5):8;['X=9%G3:1TZKY'-`"U446DN -M/?#G!%&"L(I)ZBK!O["]#.)7\(O?1]=;N=D*_1P$O3?CQ -MU;#[1W>8M*5V(()`X1G)BVCA*:',\GEZEG(@L*D<>U3#:SD[>SC*PV, -MX^XH^\>E'SG!7%CK9%5LNFI_Q!$U`5Z;+[53^J36/RML7<^OPDH(2%(NWW2# -M"@++-QMTI$>ZE`[EB_]W:2BL'UX;I:,)I":T(54Y`I.<+(M9C>?_D2JY&"@J -MM.=*2S.3U91LZFZ:]U8#*`A/ZVIN&>/I>Z=W7PU\7KM\PE5Q(MW5_F#-].SJ -M%1K@"A";6N'KH._(]P+8$V[NP^CBZ1+AKT8+4S:A$C$5C*2&S4G82(=$`F6& -MJ#N;MG<(?8I;\U`+]*:Z=K`H^4)X!(N%>B=+GG0*W"-CV1*6+KDY\$!.;"O- -M+K=G<(C'C(WOMF"^;*LS<+0^H;#=T-$WLYLZS%OP--<9%PC\ON>!%S==XP?L -M[RL"!#?5.FN=448S-?[B!1&]Q#S(18(3J3!Y?PO,M!P1C1I9EE(&W)>/5]"3 -M<$OY,6?YYD$#%/F`>&F7V6J$+P`SL<'IHUR\>&MBQ*=^K*0?<5(7G)B\MDK! -MLW61*U[6EH9-YGZP=$S5\$Z!E)5XZ8!VVGKU$<%4)GV73S_N>T*2+:L?VBX* -M'%(M^IQ)U;]DRX5W\]WAHJ"%(JJ0<=$6B-.GV34Z^`P>YXVP1&H9D.39ADR/ -M9BI@C)F<[OZM!1NS^$R6[2/?.GZ,S0$05Q[*`.5MS#J-'`TS9/S -MV#*G5PB4BA^C:P*LYT6K*NL%:S9#V9H^`XQU2BCE=E/]V6WT_8%GJU4;GN^G -MZP65#DO%>U<"0*1:6_)]4Z1M5@WP>$G<_K:A4:?U_`?$7!@3E3E66=1XVQU\ -MA-F/+98OD;+Q?WV[S9E^Y'D)]%+"NA,BQL>*T1\+YMM;E1L)NS9[;OV=*US[ -M5I#)39YV<$X9Q<*T[R'B"!=^D!;C?'JZ3[1?`E:-:>>K[YA`.!=\%:P_]RXD -MB*,#*O^4-H!?;#=$[2`D94W35W6NLQN+%>[L(W0/2C]SP#)'M$E`F/X1U;FO -M/K6BG'ZK'Q0?=56O^P[2@!RU%ST^>$<0L$]>*@WRQRQ(F=E%DO)=F@2<.+-> -M.8@U@#."!5?S`QSN8$5>\>G'B#Z4?CA_[%[+NNO'H\A$^"K^:F%RZ,LR7"YD -M?>#OTE?HM!A;P[5TCP^V=GA:K-60,`>1"=]M."NT!XIH1"77S-T#+99\>QK@ -MNA%J_Q]N#F'`5R"\8\SF`P*AIMWDW3[]L1`G-ZK^'OA_>>8-32_H8-ZU+V<< -MF$%24&U(MHR(\0,89+/YHR6$\XN2J#XED+\:D=$;UHO4BK$/H;`I&,]"VW[Q -M*K(8AX#KK=3.`B(8]F[&(/JD^2:YJ6F9'!Z.:N7V.R7:$YPT#?^C'.4 -M)?=(T#^GU6JT;QPLV7IG%Y#:E(G2S@Y&A_79W2,2,]809WRK'E)5VX"=%R*B -M>F(__''W-!V.KT^H5=KK:L.HK\O`')71V(G,+7I`OR]AMNO:;@'FI.LGL.CA -M)F7]G0?1V%YVAKD:,7'%S@%XDPL.]?30)ZI\'\=Q.2EAV:YNN=41_!D5A*-T -M<`J9R*I8U$*6E8WJ`A<>)2.SNFS]'G]7-D7U<>*SB)\-NS!!CNN1Z#O%:\WA(=SXZOP8ZQV8 -MA]=SY$HNPC*O60%-:ES0QXC$+<&E86#9=9L$NWN@7M48O7`E]VK:F:KXIEVT -MK=TI/GM!A82Q4FQGD8JEB:#8HJ11TSK#Q)(- -MTHLVO%`,-U\%P,5ZRGWPX[OJIN`/I(9*DXYAR8E[M[42Q@`66*,C]Y\!]'G&M.&&?YHO0>P#QN=,')@F(I&\:Z -M&G-+5462T9W]Z)S9Q5<)Y\"_C#*]HE\#E??<:RJ>6_^D&A`.XV7_`#WY:>$ -M;I#!6DW6\1T*RNA%"'Y;+4L!OYZ%!/=S0.Q>]-F57V!QT4VC2O=.8)[(@UU"WH[/K%(2'`'`0X>'JR9KIU -M4T=+.)P0+:&=U`42H*XMW!25F;RD-+T87*/T3"0-^Y4DIKU!XGZC]J(?*8Q+ -MURC'1P!?DED]PP-1VKU#`+$$$_M&B6.T0@-S"TA9>L8R6*#U"M(J45GW"A+Z -MK?)JGDAW@=*C9?;8P#G_,$Z'2NBPD`'MK40XZ3!:16ANX'YB;JX"&/.`P2`#YR<-,RZ>=@-A:SXU'/V?[^UL9+H*&AH(D -M05/4V?JWPX\\6.2@D^R."GG8Q1Z\/,+DRNL"?I):;18V'N(0*AKH!^.' -MC[%1'[XS'?I+%T8)!B)7A -M)]ZQF.Z4M=ZU,A:95-_=B(J_(RHDK:/UE$URG/=0C<&8>S*Y3;H'I1YTN,]H -MO[+J/2?I`K5EP2OE@D)KKR&0#>[$_4-'%T"Y`52$U7-4:KY^-Z@"G30QPR3P -MU=9.=,K62\Y_"Z)0_A\EO:SL6OAEHSEQLRVOH,LS`IF<:84PB"SR3']D!REA -M0YTG%3:&[34HDY+U!9@!I$(SK_.%!G[-*,\YHRCM<7\9Y.#L8%#',6S72"^= -MZQB\'GZE(!M$$)SVM37K3=ZSRUKD"L9DN;\6SO]AFC5]A'=J,)TI?[U;D39E -MC==F`QFVT,:\(F$D[DV?Y=^RJ1/.HG]D5 -M:I:\W`WS-(SB.`+06T(EK,IYYR-=)U4BF=X'/["3E0@JSZ0Z[3E -MW.D$O,^_`4MB$\3WFPUZ9"V#TX[9[8Q7YU1CW;O&S/V!S+/,?3:R5):[;S'B -M^Q"KB`_W(?VPQ5D9):%+`O*M%AMVJP,X3]?/".&Q;D2D2$^[8P'I2FKV11+\DFFL$5U2Q(KJJAQ")<..A&Z4 -M'X8[913IX5`A842[S+3\\_K)MG&M%TO@UFXT#1!.Z?-AXT"[=VHOX+G.?W;$ -MV/N=T="LE'!I.-.1QNDY6U`8!LA)0D,/MV/GU[-J1TTQY'X6U^-9&&'=L)89[L&(WRM]0/CPH -MP0CH'I,/2G-MJ@QWT:)2'IS['BSUIO$^!"YZ[G:,S^:D>)NM`E.S$F;4SA!E2%Q[R3@KO__R9"(T`8W=>B -M3A$PR7J>:(^<]_,HIA6*<$V33=*18+S3ZJ)80P_-)T/;LJTH@&-Z>V;`S5Q< -MN@1:Z!ZAYXFAO^`!FLT7'/)7C5C?.7K>D!>`6&B7>C1IM&N]+:X([RGZ#?QB -MTA\A#31CULLQHK[L%B//$W,(V;10U2<9#N*4NSM=IB93`[4(\"05M6@B%REA -M)+@_QD5<_AN3_RDDO2U-4"=F&=16T&SPSM3VS9F:/FM& -MSK$5%.U\HR(."E[59JZ_,^::25*F\OPW$$T`'^02HA"^2?\1M=$X>"KE/G.1 -M\ZL&E3`)`AB.5%8_U)YE2A!5LC^@>OD3T40HEPV21/"BZ=G"!@B+S/3N!]QW -M93=.Z;EGO!_?<305[L6`1)==#`6O?^F\02`@M>4_:S\F\Z!4;;P56TS5M**S -MF3]P!DMT4=&T4]FZ0;!D]-.=M5#C*+O:V,0I\1VM$#?>3:=6C>,7N%Y00MB_ -MZK*IC]EM(;=81*^+'XHK9"N&PNR6<=L6LK+^<'/JR+N"UJM#C*3(3C]3W5\\ -M1BOA?)J$%DQJJEK047)8I]^K)@+QU,YVI!G?J>[0&VFJV*XC(^J,2_5!$\+O -M%S.#C-58Y(JLLE'*N,^G_-]9$L"X844*QX"M)3F -M03)\,YGMOM[K;9Q'NG9+(M\@S%[TY.@M#R);ED%J7XQ7(LA#D9SLSUT>Y1;CSK6%Q -M(_S73?&D$&&SW`'9/_L,11OGX_+@0VF$0/6+JD:MO$WXD0EE#.D29MU0+WI41X"JV59L&UY]H1^U%I0;&I%ANJ9.#X1/,^)LR5M^&?4SF4UG"]VSK#0`1U"!\]5B%0_]I -M2.+S@M3+\$&5OPB2URMV@VW_2LP2'_WX^E\^FK^70?LGE<;$1A()=8K/ZGG/ -M*:TE7?Q%6!K]'L.^VTD"\_9G1+20,1O.IH)A/L2SC%A\2T,RO42Q/8!JBNDN -M/]S2SN'?[LQX5:Q9/KN-8U,3+;GK[8@]=3#^Z^N0>FN6[^?A.*&8TFW/H)EU -M!C&'DE1J:)1%F<)[J2;<&1*FE._9R-L2_O0 -M1N2D?5&(KSN5.C`.90"SV1DIH4"#1:LW7W-,]`(RN+_"S*5Q8&`V_WHC]YGZ -M(DXXTR']KW:]ZJVXNKV35FF@KA-,).32#J$+?H'Q7X:G:710S/*I`=IX2*N, -M5[>*_56G1^@<]4(Y!P8N]@"S>6Z(TP_V5&G1)B0Z\\H+E&(T_7>42HDI`VG- -M'#1J%S4TP]7`$A4/.>\G3B\1*OQ^]0L>\84RI<"OH#F)M&?I_ -M8%FM[O@[C7XL!I$#>IH0"K1AO;\J%L)P32U[-#P6 -M]=X3,\OQ-/E8"_WPT-M;<7--]=D`2XW<)BHMHK75+MZHK`E6U-DW=_Z&4;D8 -MZB:4CQI)7ZJ,[IVLX8QJ-ULQ]4\VH1R0L5&'LB0_/C*+A1%#LUVJVQH<-2?O -M$%H23WSQWK:#__2F#%2DJC/(&E=!@PX%CT5$5]81U6M]L],I -M5K>/8-L)$60@=`9>FAP09JVA"14BGE8>)^<<7HT9=%YV8#[ -M,*%T7=B<]P-%W:%EXC()@S7L07@C?5BP8*WVJQLP*9X,&A[N?C_)*H<[L4:A -MNK\]G]G$>RW'?7>0VX?76)@!$O/U/G">FZ-8%;Z5`:Q7&Q3E)T+V7*`I*]DB -M_W&;-5WHX_8Z.>PHD\J3;UF#3`+IG-WT$9P;?26SO*N6OBNU:J+,[MA`J'#S -M^/8^2)NL5&MT)]B;VWOSU'K+JY-MK-J@B,N="6-W\V/LQ+`4Z2;GEB+([P,R -M2``!1VR.C1Z=/Q-@D"PS@J>X35,VU12!FFRT:]G8>H9E]]M5JP5TOUI)8FAT -MS%[?IJ`X9;O%F0>_`FH%(,NVRF&_`/H,\<4/TQKO84]>WX334DWS/#.WFT#; -MGK'@9%I%44R^W[KR#<`""JNBLJ$R8_F#"&(R3\TYX)7,`>@`06$309KUEQG7 -M>"@%LLYF'./RNU$WOD3`P]T3Y67.I;Z=5@"'6FYAMV*/*;MW&-8*/!@]V6PJB6,H53ONA!VS4*'U::J9SU`DZU7B,^+S(41$.P'M> -M[SEH9K?_*WR:RH4+*^<5/8>3_X1?/)NK1GWJ@[8FH;U\OP[6QQ)=SZH'#KC7 -M(=;AI\<&]U,MH@]FB,L:T-@^[.-6PS_$/#IIVQ/,:EG_^AIYSZ+.KHR@]^4T -M"@)WRYBIPTDU@C7&%W=?4LXM90FA;DAA\A'[E'"3`+D^XN^1.Z)CZ-*_$JWK -MT.B9?'8H9E7T_HH[4=Y-W2ZT657=/`RML91&M)=JPMXT3@D^1Y='MD@9=\QR -M5N8JGQ::!<>H_A[16$.OGV?3O9\Y"<N(? -MQ2%7?LX_S7%;#;'UZI2<]6P\0=ZQ-_0`4N3&+__E-=L!V`""\/0+V5)^>Q)3 -MW8"H413"3U87/Z.HP#FYFZ/)PTBW@TY&)J5(GO?4DX=PX+)8A(BM\+0"V%( -M$US?RH]V8/H/W'UX@F0>B?9/9>'3'O$P(M#;TS/'`I@4F0'?Y-BZUZ6-`?VK -M2-?>$J\%;'<_]8GJ"*6HL*IX%'AE!9-X#8:#PT\B^I(:=DE4%AP)=O2'.ZNI -MQYC%-5<9`UZU(ZW76HJ?[!#CXTTK9."DJCT`6%P"4F[DTT]OS&>>V+%X.1QT -MNXX7=-3VX.K/&[S)(I_E1D(6I-5U?>CJHR,5IJVKZ,26:C;=>@WG;#M#?(-? -MH3.TZ^\ETCG4L@N33\9HC"=\%M$/6$Y3S'#>5B-E@G/31103K]'6I**6@UP[ -MHJWA'<94*Z0#"+>DDZVAWPQ>P7O^6Z_,V9//-'[\'B_.4_V]N/Y((F-B4CYF -MAN_YC05=>>I6VC64C:YMQQ)U<0R -MP%>@^(M1$7,PQQ8+`("802SI!"LL$5;MSL`W2Z(3D%SE -MCAC'=B30P?7D$"TP7)-O>#6']5U@LG%*8YRIFUZ*6D;'>UK91?_^=HDD%&Q] -MAU4V?9[AC$<$%)[=A/8C@4_[I6S^;B*`/39BCE3OVE4V-^H?SKS*U#^(VV;Y -MRP<-3^M,T04F`H$O+$\%):HA21F0\0HF]+3Y7>_,3YP -M_/+=U?_2&1N#'SX>'HM#\'"5]/]$C[7^U"^K475*.YJO-M=D%JXI:4+3V:]2 -M?LE(;Z0!?=A,?<\HH>`FRNZ:)ZJ8@)7$.T-)1:(#S8:F56UU'X*Z%EA4:S\- -M,>_KMUM3>7Q/]:%^+-&]"^^4+P2,[E-70?W3"KWW%<_!RJ/"V^8E04:M>5FU -M$H3:V/N?FY;6=?PF"\P#XFKT+0K.45%(`4J@=4F_!:$3/<&>ZCK@Q!%(1>J# -M9I3KGLQO2;2K1RJ;IY?H73C-"'4@(`#_%/CF]8"=BS`),O>Q5IDGKJ*&K_&) -M%]X#VUW:I0\0L]ZNX2"'/I+WDA'9GC:!P-2D0Q".J.L>+>4BY212#QSD1.L! -M*"V(+G$Z]!`+VW]`Q/AZSO$4\.'@PV\$`M/PV.W1^F`M(^+Z0XT::VAE4UF[ -M]IG8",\?>.K)H^8^D$]0168Z1I"J/CBK4F@-^4N#!H\,GO=M1VCWX1$YX0+Q -M=+8)$5='4$6(7'[/KM$Y,Z9H.L*3"#TK-30=;VY9'L"'B_A?M+`$&_%ZK5B2 -MRN9`H"1ZN#9NVX2H)6RE#9]@?],L<$TOGK7T4G/5-J(T6M1>*-G$R55LU0>^ -MN31OAH!_"QRTP)H4.#E2@>&OZZX43G2-)71(WIL-\:223%YJQ>>1PMHLK)J* -MDBM,HI75)#D)48Y#QTS[GF-"=^IJ>%%=9HH.+%5FRJSP3:#*!U'=.B*AH'ML -M9GOK.)S9=B9R,Y0<%TVC*W%49`.#%$O(HM7\<[LSK=!55P.1\FS:W"DR:LJD -M.>J2A($%_`\%-V.Y*?A$9-,3&5L7W!UGS-L)^VP.6'F4+T4&$)(X+E%VVWD@ -MG.I39S\].IL#5;BR05$_K;4B'STBF+4(1N;+-I"WDA!F6;R$B0P257U*EP>T -M\\[:>+PCMUO53&0DAOMKO[25P_ETM?/*/'0`$O/_F$>`BCRHXF7?O.4U[7-# -MT93W/I:8,I.`PG=P[Y]@8#\:U$J^PTB7U9!^1"K -M#*6T\318.!RDM=H)PS94,_W&)U=*(61SXR*26F\E\4S#OR@4/5TBY&M\!;&! -M*612LS`A2SBKPU8>W6WPFJ!`E*^#Y@0O&F_/T`K-BL=`=N1$)V+VHE(@HE%A -M,$O'6*S%\S^CVSL'DOUA5YTRF5-?5\[IU^#ZP3DF7;"5H$5E3L"'^^:9C+:A],C>`?':8Z23%W]F$4WXD1H`&^(5231#9NL9U4KK*##*8)G -MVSP';\I'(-3Z06*>^HRP")RZ@;6G$NL=),IV'9OW!B\;W^]X+!Z)@^^0Q.K_ -M-3"R?MZ7,XOBS^]'H5C;5LU!PF82?6C,Z]"$D7?4G<'H;-N)`MY84LGSE5=% -M<[^D78$>"U=C_GW$\%-#Q_=)F\195$A4+*+W$S!A_.$8STZ%QL^&=FR&]J8_ -MAZ,Y-)3\]A@J(5*2GNV46P7%]B:-QF0#8W(3XDUV:WL#UMD)!#8LY\QN4G1< -MB61D&GO$E(VXR1LGG$7K(KXVA\\#_U'Z2`8#28%FN<']=(FXHA+MCK^5-_2DP(ZGI&.!B6D;#8' -MR[R;5;1($2G?(CI]3=U%KF5BQL:JG,AQZ?!TU-@'^\2'-B^QICIG_E:/#@M5H^P -MS=X:UW%M[JQ_L#"FV@IT0APU:4-_">9+:TX_`6_[Q&LH]-9.XL2"2DRVS-RH -M-5+\%DY$K50YR'K``K_!@NN,(!)H5#L*"/'Z' -MBLKU7(:M:R9PG'H](X)=*[O)NMI06P!Q8R/=`/$T-9!#V5"L -M"Q1+"']S8]2Y#P"=36V>'@V7%/31.!K!3T[=..P/U6DLB.JI!T;Y)^GRL -M_C[)7#=?]L_7O#!7@-QVZSB&Z;L&#`GU3I=CIIK#8#:]_%N?\3'M!CF,BH\# -M<*='B5ETZ=L^]5[LGX4E/%.P,+L\N?0%C@1OY'C/UN;"?;UH%CWYW3`BL*R< -MG86&7JH?*@Q[N-;%NZ*.1)4_]R1-:?QB]-)6%RCX8XV#_L -MU;%.8-W!CJ.S>@Y`Z/;)1"'MS;7:=5#U2W7-WVLA9OPM9BZ*8%;5K4B-?S@J4BM1/9%=NS7`.O6; -M('5BHPC@TYK6R!?\F0Z:&YQMDAI*H+&$TEF6)0(P>-E`]WCDU[Q_@S?4CH5G -M#VQ'RYJD(IAQ2%FN8I"P@;`UM*81!ST7RV"3I5"B/KTOEGF3,SB%IR/L6RP> -M<33P@2-()2D%U]\)UZM(%J,1E22X$#S"1X^LE](QQ\=*[,[@!7G&WQ1PHE.< -MB'_%O\]S0#B*2S%L"D6M#38CK73U]MQR3G$&Z.LZ2JX>=KQS>#SN?\^ -M455@)IQE[[<[&**E--H6M-[Q$`Q+9.*$J]G(JQLV"UB#T4GC2XK%2W\ULY^B -M\6`\"EEJ63+\XR_IQ#$&L5M4X^8`S?N*U/4J*5RO)!!\HX5=0@T$NUK<(S)@ -MSWIC5J*>^:"YQ90P32L8%\??H-KJ0N/P_J+]@:N84/#@'TD25$0076."T42K -M!&"YH5T?E\")K3TK.C#*>EZ -M#C`+R__3D.^$*>Z-8&@5=/4S0-]7\$"C0G,2YH.WRI1%/>S!/\%E8NC\&\3K -M&I;`8WBI<_BR"5R-_Z/MCJ2X*59SM8[DV-Q<=RH0S:UE&)T#H'C!WN)]+8,= -M,4V:M@J@U.JA?B@@"N&D,!LFEJ61=`1@\$8+SN@L!4'*[50OF![21 -M7.5('<5P=,FO'OT"(=/J1=8"U[RA-1>66@UKLSWUN\Q\'^U$MXD-A/E5O&MX -M5S8]FA:FXI6@=3S!"(L>&$''A*FCQ_NB6$+-LMUA:R0U'ZXLI`:DTWY)9A".-;%RH3S2TB3B,Q.\B?IW)L5^3-(>: -MG]7!P-SI.*2W2]G$+KG%M0^<2:0YB;EP:V\YN)*QT%EV)0R!X@T=54QK\A=E -MW>KD-3)KP`>W5GM7;GI!?HDMZZA=OC-;MS4\2]%KB)-JM-.R_<-9['AP%+CG -MX$M^BG9AUYUJD@;+P-+`!9:4D!E].47L-(\>B@%<^;ZT&Q;(]B;S$[ZW>%2X -M786#_V=.]6(E/U"C)M-D4U^8/ZY,,I1[*D@0);&*,##[@EBN]==NDDG3@1/) -MFYC->M`QA2J>:J+Q_0;-7'S2>L0&O_&9M2UU#NO3\D1]>_M.!:)NI46;9XV) -M2SPRIJ1=ZJS'@`SY%VO0QICS/O/Z3)GM?3:2D:WN63D!H(JUM9F*[R\Q_%1 -MB%]L@V9;#Q)XGW8@_+)4BT#ZEE"7$:VL,T]5/HPP+ZTB$V@>'FQW,3N -MNJO*FBSOF:JJ>M>:=AF#_XGPOJ*0&*>TS!G;DXQ$X@!!61='H9*\_G$*63TP -MJ&TO:^'NN/;0X"UJG_8J(8+Q)S/##MR;F"B=L9>A+:MA7FME"^<)/\@G=%'5 -MF'J4'M);S",.Q@H_@N_/_61(-'D;F+.-<.WFB`_E*]\I&=O#>NS/'H3@B<2$ -MO_VT`,$C=E^!>YO.=(R>%>-/FOX\-%-A!>%Y%J:$6Q?J2[RF5R(U%77$!$'W\K`V$(_D;U7^"KL6 -MP5(R8LJNBG`C;N-XCV(7R;;[B:VXLI$:U\;'KV?QNH-Q*\MGTO0LG-\NGOUA -MMY@010A7.YRS0HSV1652GBAT7^VQ'X\2ME1OXKW9AF^)`[9@)$7THOZPQ:@=M\03YC#A,'ZPL -M\$S#>-R6-CKC3N,2UGV;P[W>^@(%*F&!&PC)076FN:VP1G8?P]:R!-E.O6LK -MS$WJ@5A)(KB44_*`F[V:?]!/HNHP+71&.G_>?`,(U6U!;?+[*/F5D+'CF/3=U@K#E4PPG7$A*2]('5W4.>2 -M8Z[O=I>'+SD>+J28>%3&=-4?[#84:9A8*H'P=O)[ZB8GLS%0;^5IG!P&:48+ -M.EMLOF=`9UH-%+7GN2'!EY\I<[M4_7\H>O^K3S`N4[OL[IKK,8!LW:-[V?(L -MKX^;B(^6?3,R:^N('"6<%M:$IUXGW].4`MI3JH4#_Q+V]$0^#A[C?GFDMN3N -M*WH9QJ(B-H.5C&C2&H$3V%&;_T`1&Z8V<0-DA286:J[<2_&+8EXZ'8%>7A"4A9!(>U`P)_<1 -M8FA:(\_?YN`FK"V(-:_`:N>V;&'+O\.P_B9^7'+&E'-54]^M"/[Q,&UTE7GZ -M51XNA<3"B0Y;L-+,%NB4L[\=<.FN7^HPPWZ#=@;9%-97A"QJ!+3T6ZQ%3:P\ -M:)MMA[-23#^QIXM7W]6B/RYD*\<,-P#D;67J#Q,8]UAF'M(>Q10=J5U0Q.;> -M,Y$-IOROK-I\50_62,$C?ZI0T.7IW%$&N(&9V5X/":XUSE\XRE42PMR;*W&]Y?%U//U_QR= -M3F:GMWH>GC-J%<&4J]H!'"J("^\^,!=NEF"NN/\=*(9;;1M&Z>$D]5:4;)O>%;)^( -M=]9SR2_QO?:=F;LY/'-"#C -M;EN%CM_H`>7^">R/:A_93`D53F>C=%`AUO"WII:]G(9MLXK#QVB1I8C6<]CH -M,X_:PO9FZ"O$D:?HPAF"#;4Y-UOXC1[5]5HZ_78X=@9#\0#^#A8I0>$,>QPS -MN5&VAQV2<=KLN/M;#ST''.LWJYF;I3'$E!E4/^66ZLV7Z`EPQK@_WP5C>&,B -M'M)_!3$;]X2A/WI>&M_FC$FU1_"EW-JX*I9^8!OTE7%_"WGIO".Q`-D>N7P\ -M8?QK%77E`UKBF"?>F\3T^FL&I.S;M6XJY'F4[,?&!6>;.I(6RF$I`*%XT\K6?MX]F84?WTH?<[#8=1\-AB+> -M;5<#[S92T;TA043P`:D>R>N=,,DSZ1@MBQ"6Y6'[8=\,(CI_*5&50QUTY7(- -M@[Z5'<=#W!<-%4G\MA)2@MGE,5EMM;Q;`OT@V5BC2??<]..:#,E(V2RK30W!V -MC7YE<##VZ+K7$Q;/G=+ASV'L:-?3+BGUZPS>I92.L47O:!T:%@>:%E#B?F!I -MV`^K@`7_BS-W!H*$$V_(7L,C'YD)IN>_THI+@M)PZODF -M#L3X46&VCK#>&TDT#S&*9#2Z1AT``[!^T&.+,GLZO#S-\*"^LRS(SN.F>HEZ -MJOB.D#%+;HF0E<>8G/HK4L(EHK291?+7I3<#Q$6\K/14P5 -M$XL]<.5'>D%K?M&2PVF06WE?STED<+5P>#C8V'E'U\FG3@"86YBVBBZ-F1F3 -MK!3__5*4F0E(R&!V^X"&O!M&N;^FGY=)^#I=E>H\PO+Q]F2M@/4.!Q9)GDU9 -MGQ7\_PE8-Z1E*&3Z@Z#JLX7VGF8WA]1#AB*2F3:6%>=?A)F[>$8J&F@3>7%[UJ)(;&^5ZRS?^L*]2&@+&7G8 -MRM=.+J/*7)5Y$[%'TPI$[/:/=T5ZZS?0Z,XER/5"R9$\BVB&<3*LK&_5NA\6 -MI0:T--_T+>A%V_7[?Q!XI0WG1_<#:%T)+G03C:'M=QMU^.M3?BI,OC5'(Y@> -M."!2YSEAU#M8MI6W!?C#W5.(JX-%+),.JSL/:R6`<1S6M(_")=/=0D6,<9,` -MYAV#@QKX946ZRST%-R58YL3UO4$_;GK=TEQS#-&"FQ[(D1?I7[89*_BQ)+%M -M=T-DU8(\W<;$:JG/04^V3(E8P7,ZLJ"N8WYXZ&O$X=N2+CR\H"8(SXF0-40-RJN&88=Q3&XY,3<=*&SK',]/E5Y+:B%UTQ2 -MVQ[&X>A0V$+M?I(&B+.-S+H9,FN^.'=?8'*A:)'9VU:9MZ/KWEI'HA9FE-;Z -M)4I<2!].[_>%^?SI*;"D#LB=^?E]/0L-`7EXCE -M@S],FYGCN7S:.FV`B-_,VV:7BOO^0)%G1WE0:!H"&C.9"Q1+DK8D7\D_&7#T -MCFL]WM>](1Y+MRCGK]S-JONQ'+WXD'R9L?ADG4P=?&?KI3%B.Q\QW_+T0>^Q -M-8A6(A[M:,#"A%50DLWLN-WZW-#52P&7)%<1@#))R_BQB$CL'6.+%E*J&*B<.U881_?=YBEU?,\F",2W.--%%5@33Z#51(KI;[*@@^ -MJ'$!#SU04(OZ`=[TDZEMD_=[7RV<8R&=+71:M4<1*^W5K?GWBHPU%HG:` -M<';HO.D?%B+[(]18(3/BGGJ3IE/$\0'#A1_>1FT-NK]"M,%I:\QN^\-2R@9> -M.5*SQ'C"F)MK8A4"QMF5@*^*7V=:4);M>*CN,.-H_$+/[75RF0GX*5Y=K:=LZ=SC*WF>PLW6%HN+FJ>7NTX/%# -MPG3;903"6.:A:+'OYZ?;>W8J` -M-BGPI-%=L,P*O<^S-O[RE\-D[:#09W8A&VA)M[&++'T);2;%K2>5#=-W:VAM',(C]65F\@1"#=(,<%=!N,=)T5`\LLW'.)Y!\W"N<]Z_%.GO1C8.BUH5::0/=F -MZZ8?[G^=8E17*-FB0C//OG-<4J2O\A<1%Z-#1J<;ZJ-^`CS!<@<.38^.>VXA -MSSMWZ#9&IH:3`H`T:3-+/=%NDG/P!O(4G8^\ESCR3@&T*/Z5I?Y0Z.Q!S=3, -MO=[_-LO:03DIG)9K$IMLCB2J)"62`":`6@'03?F.D=\O^B6P_W -MAV*=[]UQ80'/CTV;OZ<4CJ"OZKV/=9EKFFXYY;NR:^MJ_M%LD"OS@"M0RF&- -M<\+X@,BV$#::^ -M(S_/??QV/EK*#]QH:9?":[V86D-N`&M3"QV>]!VV>6=?X:!GVK/>,UG';!,K -MU%E"L<\@CT^)"UEH)T`Y"&8A.UP.ND%"*+W*E/I7NOT_[?;!",$19A-`5,Q( -M'D^H=E;4>W(0HYNA`7XJP^A7SZ7QM-5A?8%U:*>PGC(\M\R0D]4*L6D'%0!= -M^(^[-)U6I<:*'%L,X_&FID/6!AKBJ_*!2W40E=)IJ2'_4("2^LMU`;PD;_70 -M1@L@;S/Z@Y4I`<3%;J?]HSB:BV:HUL;O_"*O0@V,^9C36;!?-!!?3ATG%719 -M+M'NSM4T6NDB'5+XVK+D7!_M04"03ECL7C`3Z9/B'8O,4:OR?/)L0$[Q/M4P -MD_;=/,@VD,N6R"?C[TOS'QR$@0!EW37@HTH6FZ<6&(XTB)M9*A@_2D$FO%""&#\ -MR.QML27OOU8?]P-N)::[_B+,`*.\G8 -M932.1^@7/Y_8A7_26"UAB.2AP3?(YLAB\[SL)2YRKH<;A=TC%&ITT:.Z!]UC -M=`JR"#)^\<&J+#K'V9@QW?8T$-N(YJA;*`08QK?*(#O=U@7-['WA>M@3-L>2 -M.`;4`]5:?CH]DP[HH5/1[O$?._Y55OQLC=RD;TZ"LR5J=$(TS4+K-NK?3+=% -M!+ESX=)U0UUU//0V..P@;WIN6>A\G.RDD,X\LL2@_4D)J?)BTHL.J=/3^2WG2O!? -M\=/#THQY0ZXQ6DD8+[2RHJNL,V;01CO:'XGR\TTO'/8-<8/`5Y# -M\>JDZGP.(1846265##VQ")E!!/`D,;*VO*R)WQ]!HK.!/S]'=:UIB/*7$:ZK -M9TO1+M/1_K1(QML>CD3`/O);FY4C!HX0N92V2^AB1 -M4%0%0C0K#X2!^E:/%!SUQ)N0\R/,O0*#,\%JSU1-<^*5S`40`[F@I'G63>"L -M$K@;HDH,=&K)[V,V69$0YCOTFLV$)%0[1CK9'K9NB/"9J/'M&KPFA`G],=:O -M+5`;G;TEJ=6]E$[ZD&%XCCI7[%8B*3D"LM^5@G2]&:OA.EFHGLN-^SOR6DQ0 -MB$T6@_!PL-`?C=JAJ/Z?-FU1/]A1;'I&'W;W.UH%<[A(PW?"?5].UISG<6]] -ML;ZT[9P'!2"CQ?+E10GM15M:U*XPWA<2$6T -M.]-.Z'-PH/,O\L3CK8!:O*S\HT*WCQ4JW`2GP6PT7N!:+2S9!?" -M>,O-!6W6YZ``C-FBJ(GD8<-)+&]'D"#VU#\4/1$-_FV5L0$-2%U9N3.R>Q(X -M@ARP=;)]JE3Y<6>M`)P9#'YX`.$ID,6(^15;=1.7QN_]2%A&R_3CP5!L[J7O -MHF@6?D>HH^M'6GDSM:1(?]%:]N<)4\.QV5.!M?:A,V934MNJRT)9BFNB/0Y, -M>Y4FH@4(OMC1<),W),,9J>UGNFC.Q-.ECA*AP`P]OH*%CDY8%BOLK]/[.>&\ -M"PZDZ6\#)*'_?EDM&KL4D-%\*LK@@MHA=,-D92]*9PY8ZJBS'4?\A0U7+]G6JW!C:ZKL!4HT)XJ -MHO-Y]P9%[U[M_)VEO949-X%6>OQA>^O0E/:#U"%ST+8^G/&?!TUNCR"S(!H@ -M'ZZW)U*M88PQ?2#*I;T8%+G$UH-`!T$[4`^*E -MO-PC4=-H!X8QHE-5:KZ7A1D?2J%/7K@//XLBK+)?0U[L6Z&U5*](*0<=@F\, -M`(?5V._(R%RSDV4?KP%DM37"PQ"1N#W4E.8)I?);QO#0QTNYL;2D0?7R]R[I -M/HS@3#VXO!F4-#`G3Q$;H*M]3+.9&3[A&XB<(*(RG6RA!3>+^MR/1VGR7MV@ -M,7\&+:'[.!FL:"C@D8,>YH?+07\W#PO%;`LN)9N)@@BVFK -M#[3ZR*G(7<79K@0E=T0SJ-YQ@I`"/K -MFK8'=,@*]L14&)PE5`.^2JY\RQ=9(6G5_?=]Q72B6\IC-A4$-^LR/0DX9WXJ -M=22>G'D%2-R_J-M?7O0D>+10AR`4CC-17H5*4AHEO'7AD-Q9I,L/'HVQ(U;G>R82+X$8OYX1J+%&!BJSUEGA) -M%FPAC=BF3$=U&C,:35A'^@8'5Q&?1/V^KXS:D-HW=F'ZX9`P;DAY^.WJ+=C4.I6Z&B( -M?T!EFQ,CJ+1CY59_6C:-?&X-16YBXI%+WHPYNB6TXU&3&<)]W43928;?AU*5&M`UA%'2 -MY@9;@L9S.SQ&*6`XHC?3LJM#QTY`\>)CV]RB2KQ=DK0>D*(AD*2-G\."&#W' -MV$`$1'M7(EW+>_\-H/FA:XHN$$39*FABW1J::!N%]:$A0_(#B^!2^@\%RD;5=*P2J&<"T6#IJ^@5Y+BA-'2%/WCE?*A9&+Q1R-&,+']\\1 -MO\XYJ0WGS7VD%KFO`_F\^Z02*6C[2R?D7G=Z<1D]4@2XYX2Y@GOVRDO_0ZF@$HZ.U8A?!`/!Z=%EB*0NTZROX,PB],S>? -MV=`K?0!+[ET)RB_T`Q^B$WVXII,84*`<9?5^\V-F+!(46O:.F16RLGFP2G;, -M4STZ^I+>70\(8U5WD!%GTLE!RGL4]E1BD^"\/)PVVC>?T=ZLR'?P8NJ/#P$[ -MXZ;X(XO7B8X\\!?3TX2C!U4='U'/K2+5#K#YY7CQMV,)D,BZ60OX=#LNC81\ -MX]">NIQC&6^'%(#^(#ZBU*0P?Y3EAO'Q^U(FU;1DC`67/\W:-=)0;AKR='%[ -M:W46Z/'VP!EGM\/#C=/H;[6&8$`'(OCJP2=,*EE6][RU+/3A=)\?LZE45MQF -MQEWT1H3*^7Y\"9D^>1KMRO#(,#\3%H[A/"BF0&OK7D[K[-$T6W%V -M4=@]?NGBD\]L3LN[-:(2->A<=K&4357@Z,#T?A9!6?0=#^5&/`\J)M=[#5M% -MIK6*S%JH*-'N0[#CC)B69FE,>I0-@J_PX&($XE4_X+9]39FV;.+S(SES'AUM"E_\YO8FK3\>WLK -M8D_ZYI"'MDT!2^[GILR(;9O(HG(;@\?P0P\">8P%2(^4).J#X:H5<%,&,F?8JP/= -M&)MNX^0YB1;1KZ1'BD2N11UU+2!J<3!6K7KK]Q=01/9P#B6L<@2(5#X66,P= -MZ.#MN1L^2K7IXYIA+X=`S[,K7W'HIB&)_W;[<5:=YY;TKJ_`!]D';#=/A)28 -MY*'C,'!48Y;W'=];W$S:OW(57*\\(2:C;L(9$J63$Y]4PPA;"CLM]4?5,#_/ -M*&P>Z$'9<4+P>-HPT@;=<[QNNSLV)GY'99&UXJ-R:YEQ.=2S8`L1L#@RA!1S -MF,7^@V0$9+961J0ICX3MJZ8G!M-:R4`\N6S%`WS[<)15;1FOQ4[Y^+\))RE1 -M7>K#]UZCO9O>J$3R3T]1YCLZ:!P@SOA)O5WTE -M\X.U_19I`D@UN['S6#98,40XGT/QLA3OC0[V0LVE$-98'SMJ$=J( -M1Y*60Q2.AVZ5YN""S]OM'&'D7@90YEZ5N`E,XQ[`NA*)U_W9RJ)XJ[5&?-;4!&O9$X!1DV3Z!IISR -MO*H5&3Q4Z.REN^62I'*W&GWIC.$ING)T/]][(!FG^QMC[EMMR.7,O32G`?$J -MV'V_V2N6J:@,&2M`:M^1:*%E5C>C,SNX`!9*#=N690VM_0BA)+BY:C%#-OO6 -M63>I5H#^_24.D68HWH3+5,(AC6IQGT;3<)--9+F>_\9/O$BSLUGAX=LD>3E; -M6WYDVK-9G>/Z+^O&U7*+E7QN!1K"Y3)66)W:""G'H0\/IV7I)E"E!S5$J,+: -MW;]RP'?ZPWL4'R(JX@>=,3#A21<2OJ@S_'7;07YK0;W1L'!-C0CP%2`]^DZ% -M:&R7#H)ZE15W2E&>`R!]0W5>,&'NLH`:",&*U.R>4:; -M.P'O2_FQJA-6$T$^.\I"+59'[!Q^B3EE/JY^'=_?YZ/CY:/X2M3;PS`U41Z> -M1\64:W46/$5>"V@_JHM&CPQ8G$X&:`.\(6*_24[II7%Z\(1H&.GIEP!NL&T& -M9=K-3SQJT5(@T5:T:!$<2.R<[)W!O_M/6T]\NCY@JIDK*F&.&\[LY'JS?,7, -M[$W[B'766'H8VIB[(\ZS`IQM'L^+"UTJ/HI9R*DI#%CR'-X'?2>Y=U,+DS.`1.3"R),U*!FTH)Z_!5F4]W*$X;G\'@Q; -MR")L+4YP2_4,J-8,4!*`EAR*R#728_U8H."Q2!RO"\-':@,6WM)U0ORYORI,O>;K),YY_MC?0^' -MI"OTF^H:/>@&8PML#7;WK-N+!!4G5ZXYC:P^[[7`C^NK+T+P&^?T3;>^KRE# -MOZF$M`#2=,?_MLF1?LFWCJN;)+Y)L3G]Q>`^OGAF>0LZ5I-"Z2>DDI5(N:MP'"*E5('K!OU+(PNP/Y_F8D%6@7G-PQ"2-O`GI@CC.&GB^"[^6G\M -M#BU1,+-DOQ6?'X<_]5T&&)4W]?YIL&_S& -M1;Q0DA:CSA;1\RL,;Z.-4<3FY*,A4;>),*3ZH@G9`&')2LXIS%4'E?Q/64W< -MEGYZ0/?87K^XI0X7]R6NCW$>1PDPA622Y<,F&@E8:'3-80J7I3^D6?Y'PKQ" -M%%P;)-A$:=;D61E!1UE,9J'"0ATM$VE..E54W[%Z<]?C;I.T;4(_J/^$F=1G -MP#4"B6*^0>YE1N%C$\=UTJP>-_?9MY\CMP1D$I`%3^-E%H;X#$H0GHF!99A` -MR+Q -MR$$O1*I-O%\NO+_+YX)U-K[RC=%H/7(3Q)DA1J3#8U0-")W]6""A -M&D.*]7;4\?B=6-X!(G+EY&OY;>[Y@KW8BV)CVOV]+6Y1OJ>BUDRX&+34A?@)D8#%CZXO1@WSN'=PJ;<.2JF3E6P<^ -M`QQ)$^8(O,RG#]%@L+@5(ZUB'F]R[B&ML]GKS?IP:$U=HCL>ZE(B1"+"+4!\ -MK,HA*Q>F+2HQR+FNH_\?G+R@>.:3JJ3CC9E1M5\?=4;]@-PZXRU#1FH`V**X -M4YE:_?DH-@<(L4SVT^2G;@N4Z3M4OAE-?NAO?LR^,;17]KCK"][,G,#TN/T3QX -M"%T#!YH1]-=[F@_K<^68!*'$N'AYC08-$N-D7T.@81_V*_<'&Q_Y/WQETJRP -M)>G#`*:07X```GN)ZV\*;U;?9`<[YL3`@=T$ZRPRZ[YC'<,KF-)4D< -M4!ZE8]]W#GH-"_8<_EJ3">)P?6;)?ZPMH03(@F2_VJ_1&&7&QR%,ONH8'H:Z5IM)`/:J_X474ZZ[N<0G=VAWQ4R<+2R#0%6"6[5QV)E"+=ZO^Z' -M]0S.@M\?-%G/(-+:1F-376@^.%$!>/8+,0#WQ--BB5G[+#:RMPAN(O3.;3,G -M9PKBEW-7**J[:?EQ#H`VB9`.^]JBC@MW?(B+\\2Y7)-1UIL:BP6)7Z"TL&(- -MN=M>,$MY_'#PG/F`-/%'/8UQGLIUD),479@A:)OA9^;`[H<3;%#EVE,Y_595 -MU:\P5X%NW>EAH@R8SR](M80K_B:*!AKB39$1$MZ9OS2NDVAU^W2$1(+_BR%D -MY1NE_F"B/]^K6>8;*^K^L,4LZ^2M%HC&:>JQ_A?TLGXA1N=.YQU`HG#.R?9Q -M`74:C"0O%E4ZZY?X7J9/_<6LIV`(:]AY"O`RNVCZQ>R:DU_E6M,)L'N[=P4P -M$/RFY'Q&WZ6U0ZUOEY,)9O3K##M!Z"J5>'27+V3@,^;C: -MZ:HDFKSS"IZI[8X`11[2&\R3=XH+29Y6[TXU0L"PKAD3G=)ISBNX'@`="N_+ -M_>Y9["5>QT=Z/X[.PXN!H"@QFMS!AG@#J0)$,2]K/?R'O:IN3!X8Y&$^7G\2 -M/=U5&C5.R1\D].XVA&*2IF$`K?"Q:&[&.DT*T3ZE]2ZT8HK185E?#'922MH' -M1>\+1I1K7.,,Z::,I4>HMD;`V"H(S23_%[9A%PX]HVG7<` -M?#(=9L4^O?A/8_9']#[:7"HDRL8?BB.'4;"6:U:_5,5XF?XOFN+,_AC@OC;X -M6V3@1_.6TSGR6NFGI4NH3`*)PX6DJ83B>#9JX3?RYXL3_#6ND428#7!*<:&` -M(P[#I"@:2MKN?!!3.3;]#XX;H5"YL3BN"GS>C7RA!5=N_0$$1^_[>F6*"6 -M'?E$L^K;;^$N/1J-5MXLH)[1W/`K-4R&* -MIRK9H&.OUI"R,B(T!5@F0PVNMGB3;HSPD]N1?7$E_7;P`4=OD-B[4\R\W5S8 -MXG9BV7:\YXXIZR=H78ZQ5LQL!?E9JB"6#S=[(E2OKUM(6S:W/?(WL-41GG8W -M>=PV@H2(/,'K[`;Z)AYKCIT,`ONPF7D?Z;V)C@G>R2R_XW0M(^04*)^;=<:9 -M$B]TB<^PH74^1).I!76%^8^2WNKF[[H,;.XI*_^"W!R":#A%X'-(=$M5-3@E -M"#LJ)2_R$P^JEN?QOK<52["WPEBH9.%\>IS89[V=[Z9QCDD36Q3/N_3)A&P8 -M'\]%FV>K7_1U.N:JG"T_T7F"%D:@)W6;S/W?_S](RM%BAE_QD/(FW?`?.VRM -MA\4TU%8,XB1XQF[;H=]1VE3RA7@M2-S$79++\DRDS,CN?UZT0X;IT:FP=!U[ -M`6J_/#I_'RT7G[]$Y=^J962_`@=.C)_>0K=+D-GJ?2?U24]N*02BG&.+.*O^ -MB9$I=V'32#!&XCL)*&QQ6[:W4H_\,^R.Z43K!E.3'\_10`.=ZV9%M*F`7%KU -MOQ18.L&PJ>H,2VCURH&/@?W&>]0R?.]#PP[+,UOL%6-_T\!("8!"1[U@T;;2 -MNT036_W9MR*E78_.M*&BW\0A@8]'T)"G$8PL>%.'GUA^Z,*ZP^?XKD/.=BZ5 -M9Z_ZA:TS7JPGQ2FHJ$0JF0LJ5U#:)`<.K8LAG7!0!%0 -MTS*$E5$M^+A6_Q%QW6B[^T3BN`J1%,5G\=10\O$HS5(^34E/`._$.]_H=?4S -MDUE*=`1E^#^-[V+@`2ZBSLJ3FBGHRCOMB4W)[/HW4;T -M0XK!U[&WC#+M*`^:G/7RA17X853L(I@8>2IEDV4PZQ.RE6:H'3.7K-*\O#W< -MCGQNPC-'7=6,Y.=SX)J!V'KUC42V*<)+I!CZX.,G?94N56P_H!S8#&([2C/C -M_W-LLXM;WRAK^3TP(%;'_AB;CZI_K1]K!;E%4O1[HFKW'+NU]?\)DUG#_=9> -M[.SN<`._M&^$AO_!&[&0R\*HP$T*/?IMB>^I3G=P:JXD3\3T<+#NVQT(FA!K -M\4Z+';V8"@VD]65K2RG\0JT_AR5?!)[^5)_0[\%K("0(SJ=>OM"68C^@6VI? -MV@WP&<7HQX*K-6L`@XMCXBY&T2E@A`(Q6J7L.O5ED[8,4Y;,<1D`WY,5D@!X8(5AV#>PG:F"!]!* -MDRXCPD!4Q&KQJ\K9=*GW;0\++-6(,IJV(F?(KM^=[7>EE>&MP!WA -M5V@:(!(HILQ*JM:8H^?!"(:MEL?_`!=@XNVAK>SJ@H,3"L->RXELB3A$E$!B -M08%?L!35WP)JX2_%I0B"`+4Z?Z;NXD91PABR;4$.2?#IL7TS-TG;Y&=)QU9, -M1.TDZET.50&-Q_@OR$.D)2*<.CBG'D$B3IJ -M&-'_8T%+15&L2=S>!DHNYM0*54BP)W?B,A&[)_*__*530)]9\HP4>#S=BKZC -MI-#VA/-7.]2K7A+:X<:L4F^GZJ&>B;T'!E\T^H: -M#;CMAA%7^"$#-Y3CH()8T),2-WBE%_-@`A#%M&?O"[]1;R1%SWC@">X2%@%4L!'3>W#-^@9D]B@B1=< -M/>SHR3UB_1O&/ENR9NN;9\2:6LY9R&CT6%_0QT2ORP#D+S"Y@NLZJ1$W%&\P -M#^0V6]J):-I-HBVBF$S> -M/DSK]Z=5#_8PVTU0L7E-N?J3[O4$/ZZ@F0G(74!/=`9\(>/YG:Z^NH3XBHD> -M_\2D9Z%B`B"*BMBM0XI[]'3)#4:84I*N#>VKO_(3[GQ;XAD#ND>=R5R=&"*M -M;&.=;]JS)@#!MAO`"\`?O@-?B?*N\U$582IC5DJR3D!$7T-5DER<=DX=6J@T -MBB]FB$;KJT:S@U![UR'^[4WX'E#"*?W;_2!#;A9(TJ'FV.Y61+-C-[!S:9S= -M#>UV)";7ZPF0B+Q?-L.O!<Z1F_CC]C`>B -M4:&I>VO$!(95ZMGSL+]V-/;OZ8')X_K,B=:ZOP)[5QO@UZF97X/`,_7M@EY8 -MZ`ZDA*61Q&^"LW.A(=NBOW%_Y]4PZFK-3=ID291?CF$M4B[47OTNZD -M#J;P-T$;M2ZZ7LY\DDYH?.`N'T[ST_0T3`(D9K)C+1C%T31./X@'"2V6BV.O -M+H#)4_T:OPL`=(AK^4S8="]D,6&549Z78=L5T'1YZ-KW.]_/[B9AEFR7@JUO -M2\'Z.FOUW2R"O%'`TI2Z1HB+!]=8A$;9LQ] -M^R5IJ[WX6]"8G]Z4?8X+`/-Y4E6H,\&+&"?"ED-!S>_PV@R?E/A3P][Q!D`V -M=,"E$3E(FHXI:!VYF)$`]$U$?$#O0N8;;YERL!DL!;9J(R4JO&H1PWAEJ<)% -MM=LOGO-DQIW@O3+`$%5H"*\*O@5(!KE-[0/!$Y2J(MM12T:G=?5R#[J]G&8. -M27I1/+-%Q5_;3?.!F;8ET?F#;I&Y0)G<5)PS@ZGVDZC?CS`_<%?B^"(3Y8"J -M5]A.D3%2GJJ5@HB3:`I\GI757RHUMVNJKU*G\!*DW#J/>-'Y%HZ_/OT2!9O; -ME#>L>0=VF$`,BNZI291Y4V751@);11R_W3:>=*?RKZ534T6!MO!BH7=N916N -M[L&IFY`M<0,+A0J0.^DEP%C/1YO/X[2+65!Y]?7L`<-*@J^\VBTC0JU.`$_?&B[ -M>PRP>/+X+[S)6Y_)]PKYU0+ZR?#(\D)X^6=A,:72U'+-.EU06)_\P\EQY -MA\_41B$.-6U1>?`W,'J45#D4$V>-H,U-H@`H)Z;+DJA.7S>I8[)/TI^.HU.% -M7Q,Q79P&W:T$J/HD9!A35@VFD -MBM6NC_(_?IIY+L1J%\GNC4>XZ\E;@PO2"`&2[$Z2(,[5S -M>(J<%:JAHF:\(,10M5^.\WA,YFFZU']*PPV/HPY1$/Y4U5*8V3WY/"G$+I+#Y93^<4*8?]A7>DX"%HT4) -M?]RS*RL-BXT(L'K,[Y[MW4&^04D].UOY*P+D56AX>5(I=C9NN-7OS5M+VI#= -M7WDVN[U3M-.H?'&LX;U/-O/[HNKLABS/GE')^^; -M)?Z_7=`VZ/))1'[QH"P4TLA"M'BFO@#\5;+F5+;G3&TF0@J[O^/RSDH;Z-\% -M?O1?<-CMZVN4+&!344>,`JN+G.M>&QS/%7#U,B6?M#2T^*DHB$0Z%_=30E9: -M2PKV3O`5:$U>Y;]\&_("#24/^A&ESY%^'3,J$@#\1^Y'ZX#X4(0A\K]W%N*A -M]0U'*H2TY6NZGTJ&^B7V)FM -M<'-E5Q1:V\T9LRS#4+_-EMXY']WO`C*19^N70'^N'9N5()+D3`;WB^Z`>8>Z -M^*>K8+#B;/#ROY`)&%[;V4I>$6[M/;!V'C/..]G.\6V1\($*M,($^J!]E"$H -M2@&Y25Z'JI$5D6.!RMD`T!?X)>I\+'R!X3`D>_IV,.BE: -M9TJS!8NY&>:K?;`FPT]G_T\.`<#200^2V:.-:=HZDQG&)(HH4M#TD$)4JCVY -M`'(U3$I;)TR2;RS*^MZL%;B5[(>,R-'V%:,5.:ZW6OH)?TM6)@I'9>K+$-=( -MND6TT$%M-^2@:&Z&3#*T1%Z`ST5Q^&8RO`0/MD;4'F%."QR49_`<=<2G^89N -M]`^GS4Z;`0`H>,C;\?^27L,W3I.OU"_OV`JID.REK)UJD>:,%)PX;_:QI>7G -M895#B0>)[L1FP:`3H)8/'\7.9!3E`E!E$@J\D/*?K@W@93=Q;HKBO+#3!BSD -M!C>18O=V#<:RL87.2L^8"%5/!/0H)BG4N?JB7E`&2]UW46O#N(F"%_O[[TJG -M+/!XOK4J!!Z6(OH8%T$H:^C*_>1!ZL]J.W$OMM/C0:F$PM/L,>AA8!OY9$"J -MQ[C^5:K>!278O_,5(Q>@-T"B^&&>;I81B.-16MU,S>,]3/(KN;0Y@J@O%7M) -M_U@T[?36_%EN-1EH'J8[@,S]$7]]O:R0#-QR0#'JH?U6/"?,6`*A`[VP5&U\ -MA4DR+Z5B>%02PD64<.$?%7&,3@0LHF$TNG$*_<*T?2H$]=XKSXW$P\(=HM&LY)5:RX[()0UF;3FP%\5-UBAO -M9L]-D7:YPB+1R,VYKRQ@?4CWWJZ25!=H8]WG5>B>6C(6@>PK?955>-W(;W,@ -MY^2\^CN*VWF,F;XEI6-:=,/OO0Z$7-U:?<)N$^6U*.;BEKB9HL%"4L(OG*1L -M137_:.QQ)[:G)D289FR/XPN‰P-9T7MBR^[M>RY&SS/-"J?=S0$%J9TR^ -MN;R;R,0<;\Y3^0>).Z%2\'(&TK"9,NI7L//E=[64JY=S\-[4[`@8;^K"^-M(4O]F7XDO4QX._1+ -MP1M5#Y.OAW+YM;_'CV[MT!]G^"7L<>70LX/^ZD#-4OQ][+-C`A+1FFO&T786 -M6"<&XA-G'3`S45FQ7F,+VJ@.>NPQW72*B(ZK@=9TF(*]VES6LM6IW*^PO'I6 -MJJ,TB(7M/*ZV7X)(%$Q#3R?[CD49T%7I0?!-8MWYBR4D0PH9P":C2O=%D<)] -M_8*_!H%92Q6D\_E5$X.''7%C*$!6)U@EA3FA?^3VGO:*'0%R:=(3#2)-,#\> -M!@'-^L`#WRH3Q?-86$;[+9M?>%J0C^<5=R'_D$I-B`!^1SKKDF)CE%J@L@+% -MY'7`:W*P`JAIFAW@YQSN/9@0W>;A)FAS`3,YSGIO](Z:^83H=&MS+=H(@X%7 -M3%P-%<."QO+:X5D6._[42*`OG$P$7_\'PW"^[-[_I%[O67CTB6VD@2"=T -MH^FR1!Z`7]M'DL5E-CFM8-3G(/*3%BGB\=/:CPWLZ[AEK4?L:<\)%!0*8G*N -M]WQ._BCZ/EVKB3?Y80`3,LQ?3Z=:C$`J&067E`M@]ZNT3JH1*T-.U`N>2P\K -ML4#GRQ5W:AT,M1H>W7L?/@JU&1SG!99"74*[?JR]R`'_]%JO'T-Q";Z_NKT-,\I5;.W -M#FZ@WCHAV+^O?`$?L!$7ZO"^-2>_8N$9][C$*Q\2#W>"$00>%8+ARR]"V4B@ -MEOQ054RB/Y>=EKP\X7_>YDZNY'_0/E`?3&MGU3L!P1[&G*B/<,R_G-&2*[&U$EH@VY"K'L=_5D/,2(<&>,[,/*KAN&S#7LRRO -M-3D^*NE+)%FEM/L?]EM6S#H$M5B_-DR,6<,),LCH:%/$``BW8K\$YPE]IA1%=.F4)Y*V:6V8*> -M&ZJT/+#55]$<\3IP(TJ6,+UAU9%Y6.+C>_-Y:<**.E&.!6.>@4+$05A4/3SD -M':;*CJ:S1S%+'I\C5RZY3"SUFN:RA@3#,SYZ\GL6B_XY5%!_6*/N5-!H:!!B -M^T&LIY0)[*A1])2(=MJ)HULZP,QPL3IS28>KG9_FQ%:6S9[VMS9C#EI)-Z^/ -MM?Q7J=#W3OA,5K+WMR;(;?`D0Q!.+UKQ3[,'`D`8HRMN'-]P4W,KWG#8OO7( -M!FAD(MX7*5QZS)0!9!D46USM3O%W"^[*J6:+C[C4444=7'_G92.`LV#T?6*$ -MI**WO@M#VSG:)#JI7FDE\PQT[EO9)]W63_T=`RB?(($1I>*G-NR(_56P3SMW -MB-9MT3G/V1++`'.J]0F*^G>&X2Z`SDZCZD%W`2%'>^M>"G+99\ICL>[CP2RM -M4O$J.M04RBF^-L$MIY^??WI\0_]ZZQ*$("RTQ]TH7LFV0),J3(`WA]4YL*B% -MJW/R9.6OCB.(Z4B,(HX2HA;,_:G:6VFN0%XV -M)1U8-34H3;1#!"`OYY,_?7_T1!(/-9*[5]3]%\8GC7W -M0FMR?[D!(M;Z,$!'8OU((2YD/=J:%5>1O$OT3Z/?X^NUDXC)$4`KDP%#V^GX -M9Y3'%AI?7\]V&)V%-,E@EGC\K/A=EWR?_C%#2%-]%7Z9NN$^Y_9^X^=\5@5V!/CL2EDK?).1 -MW+682IR!KFVPS+JS!Y/],!'J2BIO*[`)31STX4N2"IFE2(M03K%1B@(.)T'? -M9Z2F9._KY+2SP4YMI4/N1=&&12#BIV]WA[2T`_P#XC"BH*\'5(KUF`Y5>G4* -M%^]J)(C,:NFU-[LB"X[1[3A_O3D$DB4($H`,:O_#1AE;K>K%Q*@C/C)PDG[; -MJSYFU8YF(5#O'^U\>+]F!8<+W^DIL^%/@3`PW*S>';MWR#!O,'#[@\0;ZB1- -M&.&`%L+CB4*\T$LAW`L,@$JD=A>-*\:Y]5![D*?AVAZ>>S$3!TO&>U55\`3O%+'L'K4.%Q%>T####FPEDQ`_>F$F7\SZ,;^^S,N[?\BMTE),LX&"&>@:>9#LI.7W.Z -M5VMB\#`.P$YY32!V+8',MG;QV87!7D,!X&W`C0.PGFR_XPNB/74)S*JWM!1"-Q^UUJ3G6DR:KN/;HB:%X-P8NGAJ>,-("!N+^%_75M6`HA -M822+2(6K\?K>][,9B.<@6 -M`091(-'/"DR#B9/IM5X<^T+S4?62'(%=:-O+LYK%R>FTB^T$E.\;GCXU&M=H -MR88V="W0F(@R,C5')Z_.61_:4T*),O5]&H%%S::$M*JHX=6S)IQ;:I!"KWT% -MN/OXN?SH2#L?]A+JF.%(XVM)$.]-.ED.;%AF-D'4.CB'Y.:MM,CIQ)DF70LT -MO>900G#R>^4[?R5(.4T_-Z[+I`!4AH855']LPHP77E7(L)2.'&B_#0=&:1Z1 -MT>9CY=Z01L+0DRPIK1CTUG;N04VP/+:B%]B&3WZ/ZH/3#) -M,V3(AS.+=':RL@]9EQ%%G&P<'%]"P"U#0'JVKXK42J@'M(%?YO$$!G/Y`3?5 -MR*7+=J32((Z8N9NU8%76+4K#5P$$$")CCK3JR16C%SF($F=M^5]02RF,LA0, -M*BHCN1]!7C8&14:]-\"XPFM8-T=39^-J#TZJ4>2]XRWU0>&$T5#,'%IM\N2T -MS[LJSQ:`?&0'6O9:Z3=> -MB>N($`@_N&SH7-%=4RJVM$6;8O75=RE__4C1F]E0P,T(H1`R(:1&:(+9%KL\ -M_QB.3[3E6O=QC9?UIP*1`/7'17M.`I:>?>/&9%MNND&!8?FYF'@T7WH -M'K&ZWC,-_GXJ);6[U(Z'?43KV,F*>]KA.G9%ZABB302T7+>SHLAYI%7(Q40C -MPV-8FLQ%49'P-E@8HYEK\`*3R=R'.V%X_*:L/:A%`=&=66B.X]9O -MV$.P^G>BU7_96M.HF!WY1FOC\;_8_XI63V4AQT?=XP2.&U\N[T2DM]/OCS*0 -MTYOLQV(@&J8`N;+RK$OI`2$B�GT_C0ED',*UH;[H,(O!^DRO.U3EP4`&G3 -M&3]]P=$+K* -M[.QEZ?1^1EL&*C$*P75*U[F3/]=^=89$'.YU'@G+*5LLRX.8$VY>G0YU0*0G -MOSD-N..GDD&.K<9M'/Z,-5;SA7@K\EX\L?35Z$",21*SS.2>DLNX>\7B/ -M?#KK>W:4@Y\`YR.(5M[W0T[+_@+QO[0L!#H"X_.G#,4JL-`&7[2JK'_ACWM, -MS);D1V@IAA7O!O+1)'I4,5"[+R%S$//9^>T5UX$V(`&KA!#*M(O3!DWI?OG9 -M4*9HPW;#(X*O8R^-T]NU`@;(<+K0XM)2,IK_E4FUWHYS:0B?>PRMXB:.12+3C$64J0!4E@XB1:U?.$?P>)FN8Z`.IW]JFIECB",M"DK$[9'PUDIJ> -MDUL)B\!L\BX#\$L@_"1NB/EN?T#9#0=?"*JL][@Z)>G_]3V/BG.%3Y(_B6.^ -MR/L<\1D)60SA#F>$Z?^Z_LW)X6S(E$AVZ,'P=$N1JQ<5MF//S.3:I."6I,L, -M1-T>KG9&%Y1ZF8<#D\]Q2X4DL'3D@UC4M1ID0!OY<<4Q`\;E&,@QM1\LQXSI -MU1VXA_OQE0WL0"'(8M)L8[GV6`;D'_G2!DS!F5$7RV:52R>@JH5@PMD\RAIN -M02A"1T"H'TE"?]K31VXUBVGJD0_DR2;%9X?@LZXAH087(S=T">Q&KJ$?.[]=%.;*7>#7W@;RU!'+4T'<-.AI&0%BBHT?="--[G -MX4T!`<6.9P*W7R8/Y9+FO-"(Y_S85V3\G,R*>NR\R="[8]"(Q%LJ-"`\;TU!0TD(Z=3=G`)75M'(!,*?M@I5W[U,"OKR<;E!R^ -M&UE0GLJ)M@BGZ2J0;"4W'P;>$C@Y($&5*JM?+E-0ISV2+DA!E;1ADT0MM+\&D -MH+#V1,<8>FX9TF:A,FP1B_K5BY!^N1JY(RB(]NX:A/M#4_0VOH>JW9,O,_C7 -M[]/-('NX=O-C!RHAWF1]20U5E;&R&QR#2Q94Z[1Z+-H*Y4I%W'7.@X,"+1SK -M=]^0A('N!;3F7.0Q7=+"S`F!*_8\\9#]IO`@41!,Q7>[>)TL7DIRA=PX``(K -M#J/P"FLL/(^7YO$=EZ=CQ6\G-^3X_(>'K*^58033ULX7*NJT>2(H7O;H2E(" -M)XABD._"$L]:N[!O`Y+#*NWQ870"(>\[IT'`@X@ -M<3_4YAD&8XI.LI!ZVNK5D%(V1_T"L-^&Q3G?*I1_OE`;&6$XCJ7X*P>?!K?I -MPA(*1U/2(KJREUSK'T&I@(WJ8M48>DO&H:6IQ'^Q"=S(+4:8DACLK(.J.J_B -M%ZPBD+3X!623<[7EL15TI9$/4GAPN.R)/$D!9G\PRI4L^WJ=S@TK/JDMW^EGV%*,&B\LE+B21?# -MYCGS0>@K1*]K9`FL_8+R.Z@QL\*E:(<6'J34GE'_R4H\[G_^NX7YI&V1;P2O -MU-:4W7>$TH.B0/?E)]V3=E>6)*D5$NT1:]1T@';QF]R(0XW.9.>^KZ"U9%/@ -M82'Q?[\K)5Q`U&+:3FX15SQ,`#%(D9U5^[V?4D=]#&(K`R+)DOQ,5&9#(+O# -MC3*0EP80,J\AZ/24PT52`U"9V9N<.]_LLMRVG'<5JQ\1TE*DG6:N.&\#+)F; -M7>LE^]KVNZ-"?,9*7Y((UQ,G"9Z/I!_XW -M36YI+=4#@\@D\R\_WN?<--];9Z@I%_K8*$<0YAOO0UMP^/@O.I?TE[#"40T>B9ST7_2:G2>GK&-J:HE -MK;TUH[-?$8W+Z`5=,T>P$`,8WR"GV&IPU%[IY+,ZQY7Z/NL7B$+=TKNDDSV. -MQ3^EIG^*2G,?"=1_E4;B%(`H_`X6/\<30+NAK -MAA[2U^T#`PJ0_9&5\@2,K(9I_';7@/N`R7Z3/L'\KL1\3_Q[8^S0[&;C;YKL -MK"*)EQ*EGHDC:>="A2'QCC@RAIRO3Y/&$ZP]XJL:C!7V4&M?`*REGVLC9T[= -MI35#%_]3TYNYY*B._+^)-P:ICO1`\E>K%25]@-#)T?`&H9$6._C4EK4?@+]] -M/T2Y?8BC9&+;D+K/(+0=98MM])IP356O#3S\J@R_!SIP;TGY%S2G0?J$.2XM -M0A&[D%1),`?D?JJYX2>L_DF,@")P#,#^<1I>;-*.$M"(60D+E,>2(S)O]LUV -MS]\&=[WUT,"CC"U\Q(Y%)Y9,]%]&KK[(B(T<*56!0.S@IDD\IE`5IQ=KX3Z; -M8']SMTOU5SW'%D)(\Y^=;*[4BJ0D2ZVTO2F=".;W9A?&1@7$2HZJADEN2XK@JM]]$E2-`VW2WJ"4NE0J -M"XNK*#QYP6WO/!;-W:Q@1[DL)0*-K\O<=N#9BEQQ(^9TI1-S"<"X1Y-C`9?E -M#U>]+!TC>V=L^I[D!-TP">A;SH)17710RE+M:B:37,=9=WJX8$&.#+(3TXG_ -M`8S.LDV[X.'-U6VK3XD\N_J?9\2(YY)!`N\2.8$A=,.$ -M)M,HK^#>"4>9THS""".3-M"#SN*>"KSW4D&XP_V."G%'GW$?@]H."7_!W4I7J!.BK^7SAW)W -M9R/9`+,1T[;(M1:;Z81@@6OV5_K>':5*,_ -MVD.74<;K-(C_IW;@);@MHIK3;YP_S*.(9 -MQ^DH14C,L;_2QJW1WN$W^Q&ZL+@*CR('M%X^@YH*&M6"9&TR;GCQ/6@+K#N5UF4V' -ML3-'[6'!7Q_T%WE.="7^?!D6C!=,)(^5JM_R:.VKZ-,.V>8GZA?ZK&_D\_[6 -MZ47MC6D$(%\WY,0)A#3%PA#ZUL3_K61(Q02SP?;V^U"$L8U> -M8*B9@I_H58N:$_@]R.YMM&F: -M/=973J@@+>=G9RX9_DMQH3B=Q!H.'(T(K?`I(IQL``^`RV%#)GEX%MNW?G78 -MAWAN=>FJP"]^%FDRR]41-4#7S;6V(B%DWXK4;:`ECUH]B#IB]$*M.4MYU5OW49O)LWM^H?83L3:'%$^OF -M$N;GJJ[Y6TRA[I)5V#XD1?W_7N6DF7RM`4;F;U['7Z215Q\C.;QSA"9#V:HT -M>L",HL+G[VO!&F7UXBJ1,$KH(*?@4CZ?L39:*KUOBBHAA0Q6@*G4O?,"-.64 -M/?@\7T`>#@E_@,%2R['J):@QU>M?6E',_?:J&:N^C6J=TU#P[^'523IW5?;_XD&HR -M0?E#-CFEYIF)(;:9EY_OS1VNK$5/;K -M`Q1K";L:`45)T.?ZK%^`&EF1E\?<._#GNBX%BK8@590@"O+=E#&5'H/J7O>8 -M$D:NT6S`[25SFP=V2TFZ:XC`2U=VK[RU@LFYRJ=J6\Y\43$8KE?L%`"CJ$1G -MK$Y\Y:'^EW5K@K<1KK+KJ&8L.MY2GF6/P"#Q-5JLN!676[\49%"`3F=IGNIB -M96NIEYKCLML:6^(2.5N8'P.^]3&N3FD1JHP7[HM5;[*5[RSI0(5(YEV]EH75 -M_DC*MN+%S"^&@;VYQN^SOR6;*M[996+\>5(HF?J*S"67L/H%/*HT)RD>/MH/ -MR#M?(6)5O5OQ(RSAAZJ7D?Q#PR<^MUK#UHHU?2#7D)DL7_L]H/5M+)NQ]Z-: -M:4X2&=-I_8[)C+'*]F<1;'L<01+*ZT##XWU^C?-;`6<14^&^A\P?Y$:1&B -MC70F6PI%#1MSVF6QD?;J([0&3B>W-;KO"H&KW;90MY#41?R29R'LDW#FT'S) -MC\S`:MG1E=-PHRFDN-AT25ZU[NDJM>HSLVQ-FA70V(%-V.I`+HP+;]T1%>,7 -M'M;Y7DUW4V@"4.ZE"L0@[?:NZA>W!PPT82;#3^<^X.+;_[R2=;^;/!T/V*[6 -MY9U]:NZWXDYY'Y,KHIEKQ4MX>MT,*U5=%Z/L44[VQ6C9;2%.H-^*(@X*KC!] -MC&?>P]][$P4,*O5-7E!:)=>7-[]5&29X$_/,@W>'>>0,&E%@@T%L>I*CD')?^>TPN -M!WKX^O^D#*A@_N;D`Z/P#%?\4B;$^SDIQCS^X?^*1*F\FQ59]),J6#S9BUOU -M]4HMU^37PS3O3V4A"R`P]RVC"SAZ>WE77,;I#(Y8VK^9:J^/X?`FH(U6`&8. -MX>/"R&APV#6B19SHV(8X/!IS&]OC=L4_7Q3>=MY!0&H(J#E^_&UC9@@KXZN: -MFB\&9A7*0A(JJPD*O(#UYUW8NS#P7%\ZX0M?>G!$4`\+"P0]0NFF%_C.TZFT -M[\"X9Z]6>&TG91?QTV_,%`VA@;LT1\T+)#J.P -M2<]7$3RO,((A#N^(*Y\6.@'9KK&" -M?G0-&^V/#_A<@[J=01(>:,?KFS(=GR!.`X`8@BQA?JEFLI'?\,Y-M>!%>"<( -MF0"Q3@:8ERCB`RMKG`UPR&B\#Y7_P&N3H[>_ -M0@3IM"G->ZLJ=V'DM#^J4A3+@2;VK7S*;H)_`98@TK*!DI4$"E:(,ZE;HHCC -M2K*TK?U`8UUY/U0/Z(<0*U[SBX'7&>]?^%^+,XY)L\\\^8W4T-L4R%BXC"6+ -M(UTN0`QZ203P5LDEDT$L)3_%%O?1H'L^$;L$/`UR[3GCX..$C;)5Z9NO7$;I -M6L86PMV\'X/_93&$@$)3A9@-TDR[M^1$0NK$^Q?*O^/%GI8Z&N5^8PID -M`+E'3L=$6Y8;Y&SE8*EP%L@D.8'#R]4T];9T0U.U\JIN?Y=Y"TS'*!;;4EM2 -M`#`@TZ[(!JE"J%Q'W(-QT80)!?VEDIZC3>QDUT>AR7T?E7T[]BZB'U8L;FS7 -M"&[M-0P+-?M1/N^4=!"O\0OTD]7\["8<''!\X!S6F41'53!FQYRLVWZYLT@I -M:ZYBR>*D>Q7*EG"=EPNY8Q"6;IJ -MN>B*0H]N+H9+L<)RU.(BQ'KVJ(&EXZC+E(<:MZ9[H!`*)1*W$&/NO/_$\(AL -M&\CNEYY.YJ2XN3US>8#YMZLN-`9W"HV?05>J'B!L9(*M:+D/2C[R])@?*_:. -M_/;4W-&^1TOT>Y@WSN835E:'Z!VF[I[2"#UY#$UG>.C'S7BJG.6^@\WUZ;)\ -MT.Y9)A2<99<_NR"NGZ%W^BX+C[DXANDW.J,9+`12&`0/AK,3'"0/O2*^-`;! -MF(>79@#`QWCQ[O':"ZG=(OJP2Y9*KB=>]XYS6MHI?56OIU,1V4$BLZJ=A.5[ -M)(+UDZH*NR:9\T+/3U474JRYE/VB*%G-CEJL9H@)M"?=_6(A>8/#0)DO)>AD -M"_YVI36]`2HI(&&GXZ!8_N42D"SMZ\KI^S]R!?/)?B?ZY!E[BUTQCX+/I'D8 -M7?^%/PEN;WJ"C\"UY-HWT#'8N!?CX,"[UJZ9;KWSCU+!QM^$_(HNA\LPTWT6 -M"'I.8SFU43@.31E=:L+M^MM#91$D(A)*X;TYQG%8VV$V_)>+I'O.X;`A61X[ -MDO[@.F5K^,9*$FY/)%-(PH8,4ZNN:\?!W*HXQ&TMC]_I'3.!_! -MA_E^JB(:L!%?T'+[J-)]?BER=*-]WFVMF@2">! -M=3@Y-[XFM=],"_W^SFCY"]+_'98:%,L<]+,I2=1.?]%!,[2Y-ZLQ-9`FVL(T -MP$%7$V48I\UI.LG:_KCA5;&MZ7?QJZR((@D#'L%*K1%#\(*<0;9U6%B^.= -M;@7X\EK$$IGA;H,+9G=5ZWM^,B.+@._=]^,-E@[G!<_%=6*?"G5.OAGS$S1= -M(YR*&A2_S?EU[1?/?U,B6(*NUF!$EVVU@);]3P=;]OSJ>WP9SU$6BV-V:_1UJ>5XLG/).T/81.[I`/Y*T^^MVB2!S?JQ^FC0\RWEH\)EY7TC#\=5PYG3`MXY^\\BT8N`5:JS@2V$U5QWFNT91Z4L)?560:/C,146M> -M*S^T6=#Y99DM_R!&`_T8-EW7C"^@Y9JQ\4_O.I&J5U,F'+%\H3'U(66=[L#Y -MT!&B7YA*\D[H@:!?(LYB9P'=LB8JH05DU?4QH]6BRKR-:$4,K!1'J`]#S^^_4HAE@!]+'*I,[>+BR^Q2;'A -MLK,H0CKMQ`[//^\_,N\L>3XOBL..,CW* -M358&9&-8MAMUP0+[.#0EW\)/S-]]P1#,X'8&)%32'R:V2%QI,HCC@_>8_(14 -MQI6M$JL4FKZ=*HG#\(N8Z9N,(L?S=A_[,ZE8[:&E..<"3C=&`T7_55ZCA$5Q -MO#G$2G-(MB]HH%D6T[K)_/HY'Z::3Q;?2Q]-B^N#2H]=W3^`33WNP&ZR:8+Z -M3[=.ZY-$V!II0'2-"2Y">JFA4;-;.#I0JY[CIQ4J8.RSI##F!)YCPW#7CFXA -M((F[^(C%OZI-&2"?28U"7)3)XQ54;7\]HCMU2"2!<(G2'V -M!UI#5X?9IA77T8>[BY`>)J>JJX_4"XQ&#.Z%C'O):5GN#1@C[# -M_R](:?\85J!BRB$-*9`93*XCJG!;_Q4.9*M-M[YJ(W*=)94!ZQW97HLB/GCP -M`5%V[`JW,G')N5!.1;%Q0"Q\*':A77P%^Y\=8C=^M^U[VGMWBFC59.2R[?6& -MQJL'%9(EB5<4N%O^!X@KA;)VRH-[,3(N9+5]0OS1.* -MX*47VIO*6Z6-:6E:JP&:.B_6/::QFE-\:5')LWOPY`W%W*^%I"DYZ1/W8RD> -MVC:W*X*B8QP\_!6P)[9G93QH4UL"2;Y%P2GYH07;'UW -MMY?H6P-YSN>>WG^GY&!UM4^,JX=BXQ7&[-=Z:Z?VBJZE.M]6_O-$69%=SK\\ -M>\[/C4+&?,\@8?DAY-M#;!;9OJLG=Q8KD3Y9>]3>]7"S?8PB+DH3( -MDF0+6\3SS"@FGS"+Q/OV0V=Z.DQN$>'>U"L*K''"%K&3HZ/1F-UM6**$\DLV`0B4E?TN%SA^NE -ML=6E$1=K]%*IYQ/W\9Y?XL38:](AYOZ__N(-LL=M?^&%*[_,AK+&C3?Z#$P"3@AJU^%DL0D3/I'X,)$S+C)=4&A=;IM# -M:.=H:C>=P&`(]"M4_PEG&H@XLD\&XFT!8\5]@B6_]%EUFL%E5AS.@+Y.IT(3#D]3"'*+-,G^537&FX^N>Z%Z -M`6(E!ECGH=//L@WANT*"-KEF.(&H2D!6@Y0CUPF,.#EADYM#V;OF7"K%R,\4 -MMA3Z5,,OY#5Z+?%.LQ0CS/ -M1@Y5%AP`)S]/O(A=7#VEC0^YE%!AUO^SQGNE*L2>3!#'[>>\Y/T:/$.+`[]%V$J__[8B;KY8C6#A -M]:V'!>:'_5O$+%>^]+49N/IQ0 -MXRKW-G/>`O3K)009U/24`:/:P^Z2L$T\YUDQ'9$84))_[UF(KA$:`UN87*9& -M^7LF/164DI]RZLTW_QT``M>+T<'16]P7]9T&Q,N?D###+IYH1D^ELF9K`82` -M0B.GILICC3]*!]?$#F<(78"JT8'+^B.[W1=;226E[](R=T"9.#Z8"YM#XR[N -M[A_G%$!=7C+E/*>O.A/$Q2PZ"F'0U]VR(HGA+!Z[M_V5LM3^H?LB40$<:WXU -M/[RQQYB3/8)1:+8[^&O,QKZ@X=/@6T2>IUG!:2[7QU_9+/?9#0@K@?$G=%M/ -M(>0$+B@][].PU!*G18YFH"^C_]L;[TGLW>.1#OME)Q81%?+\#)6HP/OAI?V% -M>8E5Q?]>8WL*/LOA>+0`\]Z!)=:JT/F*`MB30/(Z^'DZ:B\>?N5%8?J#C3+E -M=2%Y;VLC,Y88)6QJGKDK4H4*C>GCU\[D(N2#%1"Q(-BRDG,@LU-$!)+KR>K:@:25SVR@-N -M-R]JUV316RJ@G&N=0PEC3'O.-IP$.N2[[LF1F^2 -MGV-26;!;)$/9Z]7P8FBU\^"',+T]1/Q4LK;3TU-:4=+F^X'EKO6]3&T6`Q#< -MP_BS"C4<+*?I=OC.A(`%.6'N_3?(KB=XSY3,G$(TE9B2>WQ6B=C4=%`9L:(R -M%#[2I=H61M/*6\Q!3`14JZVQ*RQ.HA:S9V'GR/ZJ4.H:(9&T0?GCHMI25[

    % -M'8FN^A,5I`V/B-[1<0D#MV"F)GR0#XGG_*%!8(C;IS2O.5+C'W?\9 -M'-:\J1KKZ'"D\N0)VX,L$2KE%?`VY_W);8.Y46S?`^\&KJ0=Q -MUM'AB;*C/B!T?Q8+--.@?R^57\8D)'CA58VV^3AOT$IQ=>EA=A\S$\.0AC]\KWI)59>`. -MG!7J6EX_W@[8X9#&E(8-S2Q'WH-`^"(VJA:P3EB$NG4FG/8P1EN/)9XF<]4( -M&2/2>%;>CU)HGU3]&@&'?1-+N!%45%U@=$M_(PTCU8405W9@0M=IB7B&JPPF -M6M\&_MLODU7VO!^P>C]C/(]CQ^L"#AG':Z"3S@L"$]MET30/SRC6O,8@K2:U -M?^HUTB+LH!)C=F;;K&5^3`"4G&N0+!_VL_7(\W?5U.;M)]*Z[$"$;;,/+F -MVX1\F7A29Q2+%2B^%C3T:0@6U/\]]!PGVRI6^Z3-PSG$C)#D;(_(#>:4IQ4_ -MUR9[K!KOZ5&S*MQEF]+, -MY,L<[4=+X,YU]06CD3@)@%NE]K%^YV#G&7(@72KF6P_"I\:FXO*D9YE-_!M[ -M4_E?T'@+\TING4!B&`600S*$-L^;>"'X9H>J)VP:'[7["P@#:G+E%!TI7H]I -M4"9,(U,'K+Y1'=J,A,@$=N--L1D\?#>WE8`HUV'`D<^8;I_7'")H):HV7`/X -M^.^8^6693#W_+9DA(1X-)6DM9XEH*VPBL1Y7)R`BO\.,GZ -M.HH$["T>@Z)*VJ6.!OV5[Y/U -MUXC;1QW4CR86HP,;6U1 -M`:_UL--M3]A_G$<5U,NF#>G<3\)Q-M6RSZP*1]S)$ -M*JVICDR=6FTD%\0F[?#3^$2FUS3!$#RO]YH**<**0_0Z -MQZLQ/>%KNT=30/OXQR=]X;`*D%^_HB'YS@H%_>5@QC[+53V(W8:=RO7X-_]7./E"M^=8(W&[7L]S(#N&8+"Z493EDP\)BO9=F>^J_)^T"57Y.L_OO&J -MP3!-MD]61R>JJ+[!68G#=/;-YLOD'[8O[EU$;_J-(8BB2J&-R(MZ4J,5'FLEZYBTY$P>QRHZ?RU9<'>P]-8@D)K3ZTW`:?A$-YDZ++G3&#[0JAM_-AFO!T+L:4B -M@X]V=.WCJ<*;K+_FST6J*SOPD4_%VW)0SD&)]M[U\$_\"L.XQ/ICPL*=TR3[ -MF7?QA*IVG-E5:4VDG3?,Y783(5A")/4'/[G`T9T#IATC].;-?-,A%W%%O/(CG"BH>I -MOD&'G4-3&CK&,^3CEO=^52*SGJ9Z;>SBT3=:0.>>7#-@/\??1!HCGC]26[8\ -M2V;;,0[1RHQT%@C86$TF&H3AFBQ?HE5L+FG=TD.41D?;"FC4B\CB_E -MN:B$J`=VK:$)8J-6>!NUWF'H4OS.D0LWD^[2)/='-+=X%H65#+$"GY`E^"(S -MKV7CA/OSIU1@ZS$^Q:1A?(YBMV][H#IWV.:3?Z'P8PC%?EOJ4[%]8.#>H;R/ -M&^W"_S5#/E?H2R!-9=:VN,$#G4AS -MJ0ZK',=@V&N'(Z`#RUY>ILXIE_4 -MM%J87ZE:RQ?((_OO+9`>[32NCG-*_A^+AJ@T*%+3?2M:4G0?ZZ7<-H!C!54M -MRWH8::Z9R>H!G-TA3L3-/=83BDPL-AQ-\W'4B*9U*:)UME['.$DMN$V?2`X2K\LH59CI6?-G`]HF.$H`.)PN/(E:S@@ -M%IF+L$V>F!T=*O[EJ3.G3&#YJUD?.#M$CT#@-.L;*G\GB+J,*X;B]@^-08GS -M79$T]%VW+R/+X+]$_XK,DB<%S2D%9M9?:,U"C.:B&+7[P)A' -MI\^UQ8NR%6$X3]'XIKS$[W&`IC115*K^*;;NK.`0$>%2+]-G/OI<'6\N)@ED -M$6R26Z*W.K1A?[CP02`_@=DFM9KF>>[^S5M'TRQ#E$D7/Z&9`9V\L\X!>2F, -M863]?QCWROI/47NNK-@HN[.4M,[7VUS:)O[Z$5P;G?=A3K?W6^,K'`%CN[UM -M.FR6MTC3&JV-<%QA^G&!#YF9\-[%,&`9V"5OB([(YKP^X472X!0\)N\Y>699 -MMLG3#8+#;01=J*76'3H"H`;M@LW=+Y7*370S/#H._S7Y(%4SND$M>/JN+BB_ -M\Y+&BNI7KPW7>5[?8@DYQE!1,$?4S)WT-RU;P74:_X3#K62KQ:`87B#0QR7T -M8T@00O/O;]O,T!SMNK?PSN25:U^#W=RNQ4Q-)_H=*0[+EEO("KLND'LVA^R8 -M\(U?!2J7'TB3",EQ:8AZR1WMT>9^!$HTZHU7=>)27LW.5SZ:L[$ -MVUC(:8J]2B%3)2@-*]:%>/3XX'".`=)?;(X@H:S'?'O\=AYDEGXA5E3A_=<$M`F -M3$3'E=E8\8*ZVTS8.<`C54\GHJ(0$GO=?MBW?`\_O;QI')Y$T6J*"=!52\:= -M7E*ZT*8;U]G3_H#:7(<@V41?5?;AF#&FHQ5L;:NLZDN=2HG^4R;%4(%H.O;7I?S.E:^)5-3!B'A4X:VA -MQ12WPJ0@QD(5@04K53M8!"FW+-]Q"T/*/SZ\U>D51'/]T:8&*J!L4/ZROK[B -M7"(56U4+3XK/3'?NIKSOOWX/=J/]]6M0A,/S=W:SE_%(+_(+%**;Z01YPF=J -MD`76USS26*4H`WD"V5A^VG??,80&^G%FC)7%?.XJ5G$Z2\JILS4Z05_W'_IX -M&,[WZWONSZ]AC4-KS->S>G:X`M?$X[^(1KMF>Y_HFQ]?6=D=LOLN$X"ZXL^_ -MB-!@+K-J!".7O'(+FGCB/'?=)5,MT,QS:X&"?J`G3.UT@=)XS$:VN+GO$Y6+ -MPE,38P9)DH+8H8*4+WDE)N=+Y24%5&"C^6,^,U%(Z*#63R5Q%EZ+D&,0B[/T -MO>L3_@Y)E!03PC,/14Z6.SUV?GH9Z,]@REKMJ5K[P@K$NG0,X%4XS;28@,Q? -M]%.=>IA[#*P-(1TL4?.4\*PQ(2+3%2Q!&3+2+.AC<=QD/D9I -M27M+*;$))SFW00;SO_5GD8:SR$-_R*]9LMN^O&M@WK8_G_T<*8NNJD$PO/C[ -M<"(V3SPBR_L(5.J7^#LN\&Q+%BH@LV`*:1K*%4&ME_\^:%*!R=QM[U9)).JR -M(?B7W6$&NR!K7P(B/POIL(.IZ6SI:< -M69GGJ$@2&),T2B%8PR:160!T>>=%FA";J:>9CDOO>=AO!:>3Y'\D\M9<`@$HV3>OF[IEZ5LA%QW-!LQ;)M!BVWQ7,YKH)MF_4?'DCVOT)D?)+]JGG -M3#FF;L6RH!]S_Q4W7???8UN@F"<2P[@7S(Y7[FC[Q3UBY#KT7H*-@=#^[(+Y -MJXV$"7P)0L2LE2"4VLV[,3"S)J_M,(^?5>0\S=9]OBEN>2Y@RU!S._I;HXSK -M.^BN4"OY^FXF2J(L?5Q6[,1]&CF]FL$9_\JZJGR:6OQGPUR[ -MM8_L?9._@)4,`IKI:L4XAN`LN<8;\_GUDN58X8;&X$3;X.+H/8T`3738Q6,G -M0Z]E)(YY:D+K$A'*E8`4MF/IH^3Y]\_,AV[)Y(!4*:8."H&#L\8N:>1$:?GN -ML`UY%)<+W5S%7&911NC@_HSZUV6B*5$ZT2S>Q=.SEUC/Q1!$/V9P>X.Z%^HY -M,?GI>26_3&>VS(?M)Q_T8Y>`*X6D($TEBRP+GBJ\#R^69:S?>=4UK3O2_,=$ -M2RA$E:[&THS+/VBIN'$/#$T\5[(1#ZS44X4@[.@N1+20;'3[UI*G5*(TQ]@, -M-YKW^:.(I>HJD,^=7@>>(F8`PY?(7>$8Y`*&V?)3'"EJ5X[A*%_JSLZ\X:"" -MUC&7,PR*<-5BQ/Q6\)D[3`T+;SHGG\D+J(1J+D:NATD,_]IW-4E^G?'9.'AI -M(#=)`T8?1'\GR.*NOM8_74@EUZ!^1!N.'<+!8-60Z#9X]*]2.9C3;?L&"T[0 -MM"C<=UH?!E=D/.J14Z6KRD.?Z)(W[DI6F,YJ+/*Z.*DC\I1S8!_Q4EJ,59Y_ -M&#D-36QPPC4"'P'4RV3%WO6HBO$!)Y\56_Z2,\TS8'SZ'TQ^C'W4\7"B*4-3 -M.B&O!U%!3KAX9-F!6W)^6A=_L(JE&`$'IFP)6V9)K%N7W(?FCQ\:3\??5PR%"%;T9$J,R3#^8"EUGO -MZXK67N)+Z>24D@C&///4M^L%N%>SYK%W1!KKA?HY'QV2+OR;RGAPXW#E)[K& -M1>H^``BC\=T;!DA%2="8BW0?F??I@5<;1L9?L;V[*G:TQT2M0"&0/GI_UK_N68:-@[,XPW -MU>5.(:=(P&[%#1\+MA1^L*2BHH'=`4F'O$FXN6.\M`2*C&?X!-L*X(5\NZ\E -MRG\O=B!HR/LX/G.5]G[*CDIXR2SL`0Z:^H$DYJ:MG)\E!2`T.?F%]RZ[KWF, -M$/RSH.OQ#3HXK,,-<.]SA5\2(ZO+K+M92CIYUM0`*@'>^%VM@"`+V%I0.)R4 -M<]HUZBL[E5A25.&?VJ(Q2=8$EW4'FS9Q&"0(D_;!P'_`40/0-NPZAH'&&(0[ -MF`:"/BB^)N>]I)*I$TH!A%8(,S6T>U:-<+)8C!?`*V%S`(!?,C_][U#2YM[D -MM5S@FZ/B45S>=G<"%Q*E%N2AK,TV2M,$6Q)UC_"3V65='9N!LA7'9>/LL:L; -M5N=.PX*M4A+%I!^@B%31(7*01@!_/C#]W6KI%/3_E4M\4<3S..I?]K`\[AQG -MP<&TK$BO:`C.IF:)G2IYU=,.J.5U?OY@*29H(6_;2U^N::3JM:Y@&N)2;/"? -M//E>I6A.YUH"]+UW1H$1D[V\ICJVO?.T= -M*OW8;)+`TW`9&Y)3;@]F.P9RO.).3.O[^/G[Q:66YYBSQ@O[9 -M*Q$V7&`P)1^X`9I%^V@\9J@ET_B=KEJ];"?=?4RY/;ZEP"'#V0>Z`P?=V]`I -M6$VW8B'1$)>)@1_*_[;::\$1R:%-PWI#TK-:"+`0'X]8)#'_;5RW5]1Z5=M, -M=>9'.SW[N@7?''>"QOPRE62_=T1]5TVY2O/:FA*E),.\,A%*.N7X;OX?IVM5 -ML@88V6E_+IW===WZ%P7[3WSM6O=?1X2DHF>K92PXWLOC&34),IZD0"S: -MN2\$0*J%/:I6,-K@+N_T=NT_CS=&R6V@50C(4D"J-1N$6QS+Z*-&!O_CF"(7 -MM;#S*3@`-KH@T2\SAJ5CIJ:$Y+UT0S;2-5>2`K."78-JC#E-;>I=WF:`#Y##]YGL0$8K!\.#`;O.)Q!=\/M(C>PA/R9D/F[Y##>8I>./@3=HU;X^WNY_KS2/2R>`IEC -M3JU"]S4B:T5_9^UQ5)!'PGT2#8?+>T0M)ZFS[`9KVH:-1D8,/+>S?[8=U;(_ -MG3U9\?"4F[2*YC6]N'.L74BIT@1=YTT4JQ/6K8RN.,MN11@,&[6E'NZ7T$9F -M5JE82O_Y#T1C7`_6!$?&_?P:1%[('8Y2O@7BE<_CZ[,<-2IEM>*B7)W:R2UC -MZO$VMFU\%C2V6S0JMW;4@=!_:Y5I:1E/2L#[,@GEUZKWZ_K=S[:_D@K0NZIX -M<"#'8(&$!1APRRZJ-]@,Y1="N=5N/H[TG!?C3)QA&I!<4R&0*>!M'%$S[:[< -M8W.<`Z;/5W1OG+5@Q(_VSO-&.%,9CL/Q8V-K^G\6_@LJ^SEP\>!MIB%BJ[);*4(#/NU@KLDA5G6OZ_#6MWNKJQ,\RJ/I -M$SH8'7%,E7)Q_\-J9.%HZ:[EN8)<,E5T`52N%K"8L)W=1(F4Z'7Q25 -M>U]@L):$;=*5$R$;]3P!ZPJOAV&;=78UG+PD;;!;VO@BYTF.QS^Y+T=\:OGY\,^G>B=XZ+=#):)MK&>Y_F&00&EG">Y_^H< -MW8P5SE,UNX&^'5V'V'V-%DF\%4N/CK(YZI"^QN6HVZ@D!S*]?;P\X6V^^?;9 -M^+^YK-SX((*\,(]_EBO))W*ZV_[(2T7SLF)Q[BL:N-:`C;`H[)>./ULT]6-, -M?_W#S;K%MGX/7"-;_4YP@9>GG:_R!Y98PU9]?O2)*P,MIU38ZM&ZLS7GPK]7 -MQTN5T=67.)?)_DDT.CCQ5Y"CQ1A"!C=C.TU(K[#+UXJ89"F@`Q`EA#<(`VQQ -MU*TPQ!JM><7B$Q<# -MLW\J\J`),<=%A8)]YC%J?7+VBT_(F5G!XX1BBUHF>'_@RNI%^ZQ%9WL@YO]- -M3ZV+O)(/SD3AA7?6R=KF!R>WLTS1H35>;`+(`J/:F>.D)@H\ -M:N-M"@%^8QO>MB?P%(JC%:3S&,9+'FK[+H+\OA_"LFC#RE&_A@9I9$%G.\P% -MI+U:N\9H4HWM@,D>[5)J`J'+P"LYUR>0NG!WEZ)S/!+D6PKA(]WDS-D/W2\/ -MOXB$]8FA-^B`YQVI8D3>.AVR7?$7)FGB<,B?/!1I>O-3:DM]'OA^OP8BG!-! -M]V$_6,YEY#G1"&3U3%#*EN;?H4$8]VL.]M[J&'BEN;:JHR)WHPY43"RBBV79QHVUL -MS//N($-8L+MZ!!DML=T.N`>-^ISM0L4H".HH_P-],3`D -M0[K^6<>>/ZWG'!1O-CU(MONIAA,QW%**NIV<;0#20/7N/R1Y0N(ORB4JEVYM -MBGB1U!Z!NF8I.<3^[(S16.)(55Z5HY_27_&\G/K5`S^,>Q]D,*4_,^#)^3TZ -M0SN1?/,J'K%OS`#+<32H7AW^[VY-:V[[+#!5S]26T!IFUI\L?G0_6#U(//U[ -MPVX.$WE/`W5.VVP4M;EBM3SB5+4'88#4#8ZQB[?]5";^A(#TI@I6H1;;;@'3 -M:");HV/QIEA%P%$A:OPU[,2/4B9[HE[..MJA-N!:&%(V`NUI4:"JR1CU'J:, -MP2P?TC,MSO)=,ZN!:=.:&9H\'CDZQMX#'C9:8%1G5M/D=.:D:L7OXU`3\%J; -M8U"+S.K+`XVLVF(&1F@)PULZ7#]]&'SV,?+"#&,CE++9N/D1VIUPK?J\?JCQ -M-5J93)ZK_]!(S/U4%5F0T,#HS@C,:H\'8<_'QJ<'7!:.?IUU,E*6CW!3[J,. -M7])@L>VX@I\^8<-+6;=/Q<[4*'"T#:+*0,57LFN:K)5:@8V*&2?=;CZ?[#(I -MD_31NN[!&J9I_G=#L-Q3`]4PU)N(7U&>+XB`K?VB;AZ%'?J(*U[S_(RZ!@NJ -M\H&P#OSFU$.MH<)5P_M0A$ST$^=1CG)S50>60\6)KKI,);\6QB9D=P4]$Y[B -M&V9VSDG-VI!MK!_`<&>REDU_T**IGG74YO7PI-2X5CE$[3@XH=U'0-`\E$S: -M>(&LM!]FGJZ%$1XAN/7.99T0:('.3]]5V=]Y@!H-L^CJ&=34=[LZ.8^C9NQ/ -M9,S`:N%=GN-(3#N$:N-,$(#+'MGGE2?LDIE`_G*?R^/E7#?^O%`N3^V#5I50 -M-':-UGSN,$3-Z\;)/TQG/+?IM^L;T:QR?D'(. -M)PEO)Y_(P>'J^_$+.%,J1C&_M_M]NT=XZ-/5!YE1;+/"*G']%5#22G>U&'N_ -M6_A)EE!BH$/4+LJ=29&E#=R`H7BU_^^^^%;:?6@S?:=0=`[R)#<#]^.VH6Z7 -MK3L=V>5A;Z4H+P>>R2]":[=\WAK(B@;=<#H2>SD**\?JSQ*#, -M(J^8=IG@=5ZX._A8M=6@FIH_Q%1PEMM!,IH=FQ!03F#2BDSBR#EE/V*#TJ$KVPV0?3%:D""%=HV^`!D+8MTN=&+@2I7=*RV&Z+\RH',$5K4HN2TTY2,'U0O4+_6HY$\H -M;J4C*4,CIS8,%7ZXP+KZ^:!+9"ZLQRW(E0]"W&\/3FK&N+Q]1-A -MERN)V,@![R$*S[J!5]5-1TB-AEQG\*JP=?HU@$<+&1E_/J\HK)4;-0RT_&8, -MY="'M7)UWK)0\'7G_UGN&@4U@W`(\XO`R#A:,!S+-$?(J"(612ML2L->N=0! -M9L3@N>LC1,NT_EAQI_@KNY&TR8F4R6%M''JJA#@TD>1,Z1-I%5QP:@$-*3.Z -M*_PGQN8")]]8&V=@D&G21[LJ[VC]-4P9_S2?\V:^B@P8LCRD9'EXG_RY6)GM -MR6/N44PX_Y3%5^GI*.J5O`,=4O^#E-;YN9"[?(BF6[T8&7^$-A$;6=KSDER\ -M[%3C69BYHQ:1ZL.&M*4A(+:9%'S=KHL6[#OC2.W^CR3/EYF"I$OK-2"2F(`^ -M&`!#Q+-V^?ZO<+Q.<,V'G(,_$$S1QW8YJZ_R\^/RC8287,1,PK6J/%`X',TT;.5G<04`AE+JV&['@`4 -MPNZ;F()LYP;5'9;E0(4BZN^#:V)VA5Y9FV?/]\/+V2Y>N+N=IB-WB4L+U_&_ -MUO:33?V+KBZDFA<"KZ_-!4HG@RF*%K#Y;`L2L@>2]GSB1[I`"P4N<#UWCM*T -M&P:U-0<;0)(`87``^%YC?3#Z#58C::\EQ;HQV^DJF7FX.]W+\*;T^M=>D/@! -M82[")4>"BV.!570@UL>8@4V%,@[L#($'K/?1D>870G*/7?"Z-NBKLTU//T\O -MX5$D9-#4D\6B"E%5HN;,+_36A)H61I05`5&&'HNXSXEY^T:RV%V?,DAR4"+@ -M?AL>+/_DW1]N-,$#< -MN'(46_IZ-PDB6DF8RVV7(^F8* -MW]K,-39NG6X(B765Y!$5,VL-*$I::%A\61NK.:DV/BU1V4"Y_W8US5H,#)>"UZ3-QI=;$)W0$90AF5YSB`\T9%* -M(O_\!/]V-\7D)$F6&O$M.FZX?\4\GNS)YBU$D8H4?[G(T-W-DWB@NKP)#KP+ -M9(J,$MI9M"PWZR_QWWACMAKIJ->!TI::0K>__T"([DD[TGKRZ"U-Y,K2=2_D -MNZ[Q.:EOBE8^L<9;_`;LA-JXS7.`E<+CP.?LR*_U_O?.3)8,A_I-W3'T/@_` -M:B2XU3RE0J9>O4OHE:;)A2I2/;1Q:`ZM[V2$RTUEOJH+4P_(C.[_=_%MZ]`3&** -M@A32GQOTNT/%?7.8PN2FZV?D6XIPLQBS:30/HR_Y>%_O?<9"&-1"&S^@1G]7 -MJ`R5/6S2ZDV-"8\ZO\%\F\N+\=GA:9TOEU]0NF;9"T:TSCEC?4Q'2YG8:,O& -M0X%+KX&<8IV.=)LMV@GNQZ=MR&=N>&`=3$T98SS=,/3E#;L5$>7O\K9PIYFJ -M\V2J3%J3W;5P!)24D,Q")>KCG_02@8OL]7_KUYY;VY4".#5&9C]--`&P-P1C -M477%)2,-JWS,&L? -MDZ<6*W73'M)-);V:=Q<1;A$793]Y.O>0+C7,4JM3VES@_>9BNXRZH]M0"66- -M-KOB,F\8.A;H21*L=O<D>;W2JG3[4D=^(=-E'"E^QEH -M5,)K`.E-(W$03R0[3N,=*PN\?UI'2S;I-\?J?3?I4)C(@.*R\Y9CZ_`!BB)I5:7EX(6F)95:=^W'=%J3^R/>VMR+L7 -MF*5\<:^M`]VBOH#)-XVQ)-J+.,VV/DH\QP^QBXG0W`?5JW"):+X:O4CNA>55 -MUCQ+`WU?$@HP"7F&X>ZFD@)[$_^P%AK6QJ]$FLT9*"A;U>3I-R]5GPIH!2F4 -ME9XLX)H9%U:OZ/0=8+!&&-W^9(4:@K":XD".N5>X7NVQ$".=DEZIRM^"V$;=?U'J\.3ZFQ1,SDAD#N`H='\H`$JC?P_JM;:K(Z0/AU4/ -M8Q.\G10-N$SS')MS#J#7RU3!D?(B\Z_;$Y]V@Y6?TL5E4BCH3298KO_7,8VJ -M@)\>0.RP2M@S\O^F[05`-G#U.!1!"=2NKNF^8Z]E63LBN?[5S?V#'G'QGN9! -MU7\>A($\>-.._9W(#]#3Q**+['7A.IET3ZZ2!OCD9;2GY7Q=*0P9![.<1`#X -M"HIQ`VIKNNC-G&PQ;D&]1Z*Q![2 -MJ-)]&P_6E184;17U1TV(5RZPDJ]PXK6CA%/>!38&JG`I"_BF5*\$01PK%++, -MU(2J70QPP(NMTZU;UR/=&28\X*F8YM@F<5FP7"$6_@0>,Q_Z$]E4]5M,ZCFX -M:@(D,*W*9C)9DZGXU7X,5<^[[B%S@MHE)]1^[S1[OG+2.])Q"0!/CA -M*4>2X;E<;U;F>[2YK,'K7.SXWEV,>GW?UJ-;O$:$WT,;3"*SY\@2W5S0=>6Z0W7<9=J^6QPT-BU@J/Z,+-%WV>+E9DS6-W -MQ^H<=M\,QPM5]V1J]F&(9&WT^RNFHJ8(#TXX?\S1F767W,QYG`S5QYZ3?%_N -M]%/=SHI&LO?TJ,VC)+.]DOELB58])4?[5^9_\A$OR$+Z(.P4SYTN -M;P'"XLU.3=-\_LYV%O?_N;_K8C1<_]K!*>;:TOS]=A6!]1VRZF8L1)NHGIW' -MZZWE(7/&`>G-K?,DM#:IZAJKAA3N&?0N;2:OBH1$..W4I)Q\U?!S<0-<(ZW,"8RYLN,OP6J(G?E*HNWJO2RT -M@KW:YZI\:`8TWQ<`TQ#%ZD531BRC"*:F#H<]/\!'8\#V=&LD%UHDY+9<;:P:B`R, -M4S_>(:J)$,&\NAE>09RERR4D/AT+8P>LFT9)H_=FN.+J.CWFDHZ;GF+D*:,I -M>V!4,'_$*=_R6=%#HAVIK\>IC:,M/?":T/W)D1A[5C`9@`[QE'OXFHXZ6$0O -M9`,<3$//2@<=WJ/%]-MQ^.5DC2L?"B)"FBBV:4US8+GV.5?K]FTR/%1G])7P -MF3(?6+P4E2`.0:G49)<$#S#.!!,>2&+\>N:UV^)>4LG]/] -MJ&"'\^YW2-0P+VF3"EM_W#HA^)<_@A3$@#H(G%IU*B@Z)$)7;)NY1MJZO`DY -M=HZDY0[]0T^0U0D"='9;B%LHW6O*_19)A5#M5:/*VA4(KN5K<]UGS:7\]*'[ -MI2Y7$Z43'J\PRP\ZTM!:^D@LQP>!_7W$?\]VRN)&+9Z,,E<@7IRO&9>6E.ZK -MT#3A?8!.!V&=YI9E_%OSUU-N,8RR?3SB@%I(1A8KQ3P5M(-Y%_":^Z/J_,&\ -M`>7AV^K"[?`PM.&.!5Z")*F[$88[2=546'N1OW'&0[G\[WKP*4&4`L\;.`-2:_]75V;:Y_&,^HX?/R4N:5O:(>8M5NV0,!RN"7IDXLR(9-O0-P?L"SWQW;:Q(?^#(V4_CCU -M'-GEM%-5+PD*HN]ZWS8!^HOP6:$C<[2/0L*)??Y^3%TX8`-W56!BL2&DKL@) -M;!KVT][9?MIGZ<3$-DWM4TL1HTJ6`LQHQ[9B14$5NC`+6@:PWNII<9+5=07^ -M=*L!S>]&;,KM/<-25-O'>S.<*`WI!.5$V88K:F^"72Z0R&;-PI%W@%6("16YG'&6-_/I^U\A\XN56=\T4UE5+ -M)CMJ)TODVT+O61@B%VBF^S'\[M5A5[-/N30A6%7K0<4*U/L,O>?YH2LU0N?@ -M`7S7=9NLK(LD-[&?3JLM.JB_/'-8YW^@I>8>]-@["LGILWHCT0_R<5SGM43( -MRJ*EOZ[H:!J_Z%RV(\L/"/7*$\][HQWR':E?@KL@KD]D2YPROU35Z?U0AFI@ -M.QL,XHFEU*"#KL#6P6)OC@4@)A2&IW9L=$V12NLJNOLSR;MXLUB&0?@,Q<%* -M:5R#.9>8+RY,I"O%IZ90S\K%WXLFEX\ILIP(OJLPPH#H/V3#/3W?$FT&C'UOEW@3!Q#(*N -M[C]HH7G_Q9/X>K6!5KT66`I(ZI -MAI+,OFHCSZY4-A[7RX93[22LAI&NZ"W\2*$H0ZMKH^UE++8`+W<0&`!S($/W -M<7KS;'TU_T9N]YPLD++WQUECXX*QEQ6R9O;,+ -MG>_)),.?BZJ_R^U0ZE&]FNVM0Q',@F]TDAN5K%1FA/'.U?&E'BQ?YNB*X=,+ -M2MD5R:8W2PL>6.Y:X5@FP3DX`[5%G%B$^D9`770+IY\!%3]R#E%/KAF4#E.O -M;4.28E_Y^.^A?5(@\SS'*?H!Q3MF5#C7-\=[%\W(:XUBR^JWA33BH+D?)K8_ -M75^]4VNLL"J83`RIC(YA87?WBDSR_]PMY*0RM1`B56,$^!HHY$/1)OH,J.EM)?F5O&%J.3,'XS8YJI+6PLOV:=0@@VV2@43)L\10*) -M+)/B3;_7^^/XU/.V,U'19FB@S&\4C9PB,GXZD21J;@I(`\C`Q2C=4\L[\J!` -MET2T_OT5SLY(NTE];#R5<@L+V716AD0JF,LS@!K?\F(YDI=#+Q:@3-?-CU2V -M[Z^1U(X(W/5)75P$5B9OL=4Z\$8%`>[?%?&6;>TR'#ZU)EQ+&J3U+ -MR,D`+WURJ2T$(=`PQ+?4BQTM?#FH]O68!?-B4?")=S7+0W(H5I9OD^V("D!A -M?*WRR:3J[;;T&@/K@OG&:DUHCSX'-IO4,:L),+8;7QD.L$D^A0-*9A!)@NJK" -M,^,%"(F1UKF.+/?A`'.&=]P+^8M/W3*NQ#P@C2/Q8L)D"+"Q_+`;YE$M9GBS -MCX.,'T?L=5#-$L5LY4=A8?0"]Q-MLB_AZVMYVN0Z)8LO/BL`?-."%?MC,MM> -M,UWI;`J`2'WLO+)\'#/G\LS@>`>+,E.*:NRJG;B$T0_F=6!<[5HEM>P4RI+G -M-!@W&#RA@7.]O&HS!TK\U8;,8;2,'B9M@1^VV.LJ!!YT\P:K)>-"R!8Y>J18 -M[0Q_XD%0RN1-AS:CI4T>`['Q\1P6Q3BU#=O_]>A)H$=L`%&&^QJY82G,\H6N -MRK/E>^W9YCWG+Z'E%,4,MS%2-::OL;=Z[U7\57<+N>..0D"5=211T>V$D]NX -MEVS-6X3"2O%J1A]LFL1^A+EH1C'2M+-9)'_CF>]R`&/8TC''4;IVUZ( -M5[V[2*&Y1[N0#AF0!98QOA+@4CU)[G'LN\!C('+_&2P95,JZ,O$Q;W*]&]F` -M3+V3DO!USP*M(N -M>AH0'9NU!>I33S6YFRK-TY=(XX<=3HL9B!:BVX,CDF1;X<5%X!$XYB(JOE[& -M"UNZ(H0G)O5AX[3Q<1GYC%N`@Y(_.FNL=+99G4///0++],A_,5'42^]G'QP3 -M6L;`N:TTD=G]K.C?K,9-MO7@81(GOT,?+-8>FPO;!FHSZAT"WW*_WH`/H6M3M;]RVTGMFQ0R6Z$0*\Q_MI??XDHR -MEX(]?/"$(P;JA?SXXC0.$5FL9HKZ5#S,-9(,O -MG?5,58C,$(8>/>TPK6.`_6=@0OW6H:>O^MCL_Q$QJ"8%F+H(4-7PW%-3;/%` -M@'6YKSE_AG)-DM/58$0WM3@Q4WR(G%!]6"X,[\-&0[#].+,V8ZJ9>U"IL>>+ -MMCGB=K-P9VJ7O0]X$#=?UG9A;%#%]4"9EV>,U=I<(R@QG3LXO.@%C*N_-0ME -MJL'?/*7AA#82']REJ_+@+R?'/>M/.B/%*P&#%A"0SFJ0=P0)\#^V8R3W7[H" -ML!)UY>W9R5)/BX@AIH..'QA>GX3=>C)/W=IAIYNZ?A9AFXD2O!^Q5_D&/0!B -M&879KD!609^=1'S=V*7Q$KL#7R;F\]^)Z_)E>B'F@1P'(3<%"R:_.S^!3'J$ -M$R$>HK+Z'J'C#8L%Q*\CZE^SY.6!,'EXG+E^;0>53A@8Z[^]P''1&Q;,P+^6 -MM0*HROYQZPA-Y8O;]9X4HQ2]"((?1'Q%T=U6B7[H)]$ -MD2PP*US'QJXB:*;!;6T!$QD\( -M^5\]!1=@TJ]3RLZAA_=FM+Z1,400'53.4[Q#'A)`0P_D=>" -M2!\T0__!#VH#;A?)F'QH2=^!]_[=9J),HFH6\<'2KZ&@4N7J,R%9NH,RC9(? -M8L$51<0,@M$CP&?O75^R8?=JC"^*<3%#PG0ZWJ+WE@D2%Z(V.PK)Q!),9__S -M6E[>#E]L+.-1`,=%"YT65.N -MX%_N%V1W52^4H%;:6;?Y]I6L:F<-XYX?`?)](>&9(8:J?,P\NLFQ-Z'` -M,ML.:_39MGN@L\1]HX!T%W4YS7)J-`7KY!;F)U;#H[C9L%%)4([33_J?%ZP< -M?T\ZO'7P53EYYIE#*LWW!$)KEAZS+@.I1Z,DM%J`76/BFJLN_2UW`-T]PAI@ -M[JI<<7CN&B!8D/GECRWY0ZS&_/)4E^C'O"G\9;6PG(L&[5,J8H#NY991O887&NP=NHN`!= -M!=OE7OX;6QD,$&O^M`J3V3`VE!60J<;X0K-?`%XC#SCU*EH*FZKK9!PWYZ=< -M-`Z;W"](WPZQ3M^Z_MOOTP^'.--K:RQ;-Y'#ILY@[!Q;:9EG]YS^WX*#+2P8 -M:*0VN]>!1_6C7/^3Z;4%>0!"89F*[5Q(I5X1P(.I317OY37L"@*6&$"3CHE< -M!C._12_`<\LCG+_^F4'SFF'6U\FY%2/N@%^ZZI[(;GL(^+VX&JO\D.DNP'DY -M]R5F,,&$7B59.77!5' -MOXKL`)7(8ON43XN#TIF80-DB-0*L1?6YL$=9%)7>+.%M\@65 -M#;J#7$_]^+3/A:M8+P1_IA$[H$5XY:U5K*WE.APAW\NV>.30(8;-JB'1LYNM -MQ_>6J4.]]@N=$T;0UWG+0>E9J`#NV\-MY_C<3^5#&E/"@+&'ON^,]_I_W_9M -MT,8::D1?KM]\-&=I^%3S^W[Q;"M+SX`&4Z`;GV2U:+PW_L1I,>@'DC$,%4.; -MB"@'(C]OJ$>QZW$A%1PHNN1PK>SE5,*/3XN?JT'$J6:%D$@H4.\92_020LQ& -M^KE,^465S9-!^QA/:]423X7QK.16>/O8T=LB).RO%Q8L`0MH>F8?QYLJSX6S -MS&E@@SF?)*Q82_R,>)6%&IN)F$0B;Y&^@$SLK"#ST;JJ&53<`XS -MO4$#\3FCJ+09L0LE/Q,)%WY4. -MB)G6PUQ99`AQ!=LJ$.MZV]6NW)FYA$C93I!M##Z<0,P.?;S5_SC@'OI+8B\[ -MVT$;0RBB%<0&__:8`Z[%8-"R%SBUF3%[U"0A[&HIK2F(`$0YRU,IN`MG,$5$ -M36WU^N60X9MH^K#-1A_N#V1%_EH(WC[65;-BA!!&(L.\9A"CZZ[(?+-?KF\?XU\&,#S(M;#?&2QF72 -MQ:#R2Q:"6)*J&5J8-885H11#^J4"2V_>Z+*"/^N"VQ5J*?`*K)%>;UW/PRA" -MF)AXDMUXD$GY:!W2;#>-5&IH34ZV>71\3A?`>I0LQ5&.UA:9:O?J4#T=U!UR -M!%T(`=(P\>3(*!.EO;7DL$_`@4E1T$AJZ0C/M[Y;9C2,Y -M$5#("S\FK2R)&WA2SD-'?B%\(D0L"W-IC,8=I3';!8)G*I,[RBBY$D=<&6DJ -MZF,#>^@=NMV5<$X56">4I-27F(3`42NT.E[R?!/AH_,Y\@7]+_?JLC+>) -M:J]&-:D_'H(]D/YJ:]W1YP\OA/'3"PC2E`G&5FGE&EI#R]ZYZ-'N[W55)D9Y -M=_N$>,/V*E,C@68U>`%]\/ZJ*9A9ES5@8XVV.2AI.%R!Q@C"1\5 -MDQ?#OQ/M&_(#<)JW6[#DE2`Y]+E@M`WRWPQD!'"OP-<5H\ -MPOZ%^E1KJLIPAGZ]+X];4$>"U@,-QW=^;49N^@WL^AEY)@Z/FG.ED[_YD&^Y;W4HQQB)D*G([S\M=R=B+1`('5'M2>7.IK -MASGF$[;PUDXF8P788$-Q9?,M>4 -MY4^D".K5)?:;1@%#Y*!SB+G@-;2?(OE;B;:/2?;C6"'D.VR'ZPRLY2$(1-^2 -M_\?<,P*G4M681JF&4JLGWFVTXEF<7P\5V_Y;Y@"`B0A+I>C`(P[A6GV8T*<` -MJ+T>J3^8Y8&+:%WXX+U#%N+_5M-)+%4NE6E=ADH__$:X34Z4ER7BNY8EIM:V -MK]?N!225>.NHF?^6.&_RA?""B\F^:JCW70UB/%>?AM0I#<]@4I3UR(2\MI#' -M!S9?ZM?;A[V%ED>O@HP_RG\Q+X):A#%/.S^TM]8S7'LC>0"GB;9"*\-F9P5#"8GGG+]VJ`DD>6-A?\;`J -MPF5A@5*21/H%H<-/DX*+Y3K53M()QI-7]:KP9`A76GA$*P\6`9:GX"3OP0RF -M[0>A/O^PX6$UTCS[VT\[L:Y27"5BQ;P7#_^9@,'\*NQ\"\HZ*;)@B5RS`7`? -MVY>YG(8[Q4QA8#X2*1<$/=;U_WW<[R=D69XC!9(K,[JQ!C8SON2C;]\3]/2C -MDA6HWA+P[M()I(GNW][T$9Z$Z"1\[E>>J%B5_:"69WTZ:T9WQ!LG?V9&OP\/ -MS6:0YJ4`BH`BYQ&0"(X!SN[9+M748`FNE+Z51C&'-&#S!!!UBT"[#HK)C2VC -MB@E4PV9)L?;K.KS3X5P1-ZRZ#6IZ34RH+H.K].A@[.!-I&K\?&QQD-@*-AGN -MH>?-.CVW\/Q=T/KDOW&`*@3NX8(2$+_27]Y(-:^Z%LPGR!W1'GW$%U6*8)UR -M.Z:?G>'AU)4C9:^.KB[]\?\V*V/L"<0]X3.^1A, -MD4T!]-(O=D5>[D(=);/`CI8TAP>+43B:2L/BH_;<'M:K.9K$&O'3BS,\SUC- -MB6^!'#,J7@;<^QA.IJ`?2)$-25OB35)VC4J$/CH\6/`G!F,KD*TI#P*WT/#^ -MO_JHLX'A04UT6^;&,^A%?/AG$&Z^.@6R7_D?TI=2R1CTXICD4<#-K;W'F4S7 -MG&^)>:!:HFJI%9DYEXP52+!<_F30V40*4U#5WJ>X-^C2T008;ER`O+,)T3`\G55B`JMD!1F_;3X\ME%U3,`=$&+GSF -MLF*5U$^$+,$G*-U/!5-=3`A1;]H,$EFPH%$-]$*IZ*].B&:WEPF@!6YWB@LB:K?<6 -M6Y^.00HP[C8[`PKFY;&A\BY6C05T9*+8M1#LN47DFP43%LB1$<\Z_SD5FXF= -MSO-I-&%1^670F[+#5VFS1L&)W#>B?WM@1\%Z;4OVU@O$S'->1$%^L63%[O=V -M@_GNZR-.&/=HH>P;JF+`AGX1)Y77V0IO[M&S`M2`"*(\U%0#_3"EC8(FR"4U -M!FH_*3>PSRC2(P:E>4=CR(;MI_+(/\`U\']J\#4YKJA(JW17;Y!,3XYO>PP? -M`-[0;YE`E?6MM[+U0IYV>!,;^-(1P_H`UM!#./E;X'#J\"DGOCL*NCI?+`IQ -M0ZK7_H3)H#E\;CL"$<&C7?"D2//F*8GRR[))M10HO:,!S#W*_N6[Z1"@0Y%& -M\5N7;NNB2JU/3>/7F3073=+3A'P"!--?AZN)_?5RYG1>@OC[\P<85I>R1?*X -MF/IK;JBM+=)8`&#'HQ$&+Z)@X-P2K;`N]@;M020U6O"YJ]NU$&M5X-C[0_?QBW#S -MJ6)@K6_]V-HE^!:,19,?""@011-J?_I)6R&RY][4_'M+O=9-%H/E%2!;@Y]R -MK0W4T_;E4&68N[UV9SCSX-JV)=3+6-)RT5Q+P&&;2[I\@"2IVVY`!*]L:0V, -M_J2XA_>,W,ASN*Z*NK7EKD9T9VEL"V$)N^H0]2^C"/YQ>R6M6$!$",9,"J2TH`KX)=Q8!>?K7/9M8",J<[H -MQJ([O]P%6Q,KB#$9`A=W;MV(->V`Y(0N2),1CH(CES#0KATM-QR+O>=&M*%N -M$.@3?D$[PHWC@59Z%[%`#3HP"%P\@_3P]C@:L-;[WW:\ABY_L<,`!" -MU1S[8FYQ*=-S_IN,^<">'LIXU4_DKDE.6?^+>$DES=9>+9K6HZ3^B6>)6NKN -MZX#%P$0S]GL<,UPXTHYR8)6ZTF(PN&D$T"!]IRV5JYEI,&>])&K"IX#,9`K2#@):1I[.K$[(;CM#LZ77>% -M)6U@[1B5CH?(4$TGR:D[,91_Q+RILUNB65QY+"/=&PR)Z(?I!9F7LWQ>':6- -M>Z@Q='I%!"P[@Y/ -M"+_4]0:%G;O=WHR[*ZW6D72(]4(E_[5K8$(T!"KQB4]E9X;\"\\5$I:]'X)N66P7PD -MD4KO2&UJU,@3]X$^K%D;.Y+$.-])$<.TA!W,)DU8>$:B?YZ[4:N+Z10YA%M# -MDRP8@`.H3'P(M'5O^6X`1;8P2J/?9Q4^4J?4&C_D^57A@&N"+AE748X`R/Z! -M;"(XT5"I0&1GNE5OL(YF* -M\[+3&&85-&DE/#Q\O\"CI'Y)`;P4@!EQ%O*VI4.CXL3UO+9R!H9'UYD%ICU.4'N%GYTQ_J" -M(P[1+[^HUX8-9GZ,2H/>4#'5':%6]2)D>MR`@JG$"SIP$/!ZUC>]-)UL/'KD -M&>K.9>!>^NHP-T`IO"A*>)"!(DF%MKA=YU9[K1':=3-46?.M7*(-+^>R7^]& -M]'HJY'7\+M[%0\TJ"\]P\4A @%Y5S\$*])(SG<8"J.1_2DB.?]HESXHFOP:]V$/XRDZN[* -M<2KO'+)>B`O8B6MD,"66+'N`_T3*OXH$."D=*-3AR,$^Q3KP7'%>&#AB?/#0 -MJ:W2:[QX(5[8>EG4BV>_31%I[ -M]6?=@;-WTR_0L&L7\KKCB;J":0?!=]M@51[#MC09JZ`IR@C_V%K[!I':@VQT -M[_Z_R;2UU47,QB98NR0L!HB<1['H%U/YT73[WY/"]A5WVYJ?X>GO35"9[6YD -MYXDVU1)EU=BL"Y%UY(&P'J1ZDRQA!JV`I^!Z<)VM5XOL?/H;_?"%IG)4V`L] -M-JT$QTDY-U[.]R#DY`Y+-JM5_E?4HA`*FJT>Z:/I//OE;LW\0\UK[%L+T[&+,= -M%JF65!YC&U]RJWK-_\7U8SH:]HO*N`RKF2CM98%;'_M]&XNN-:)K*?Y!2[(5 -MJNRN]5_,1.9F5#'$/?]DA04"#P6YN\"ODY9KI[^2+;VEN/VW5MW$W@)+\NJ- -M-'\(-CTBTO.Q1JA9M5+?#9&.PS[3ANK*_0W=P$MC%$^` -M'.T(RI^V=`(#G3PJ^S+4RJ(TP,'P[3!UU[4P33SR#&7G08>'*#[`^'$86D@Q -M*6?TRZ`)@9F4"%//AO=Q7A5.MNRJ^"=1.+R=#N2=CJ9H7^Q23*:Z)(/N%>/$ -M=>O1_/@(OP*`=G'['9=R0%F.^ZYQ9[+/V4E:$5/:/#7J;LPRS.3ICII7"-$+ -M^>AAO)3['_!^.,Y$V3[@93G4E9.I;\MIRSXL\%)=&G^`7>Q>;PCDMK;?\(JY -M73Z_$GL$H\V!Y8:8P9!'?9C.@]U748U$=QSO=C!BU/SG-0Y*%ZX;CD3B* -M$#-&,65=W<>AM_"DH%D`>NDX2.O(W[:7Q]#.DQ,&5M*RE-6UY"8;+O,T%(\V -MQLA`Y_BNT=!^BR#O:+1'X\T?,E*0*RWO#`]LS8(MU<,#Y?N:N*77$LR);:@> -MI'N6)Q_[J:/.N.>VN"ET3FHH_E$4]3-$1_!B/`7/%HT=Q@L-L+.TE]ZTAE'# -M50A@P"#$+#3F[*6P#J4P`(A5=KYZ]NI"?FZVNP0FFEH/K4U<\M660'<,P]@! -MJ?%J,:?^4<"1>V7#%TNB(=H?S1B`(#`"5J*AK)$[`YHM=6RI&?O7<.LO\VL5 -MJ$@@FX756F2R!A2HJPQ)Y[3"-0P>*4/V3L6UILM]7OR>/N#*8M.:9KVC@Z6J -M"9<@LS:=V(_X&#(XISW,W@#.B85&0K`0PSJ6<-O -M.*V74C7I[2%99/8TN6TK71;NO\[WD&_1+C56&BT)>MH-9;:_XA*X$GJ6]J9A -M-O$X>Z$511-B78VI'$E=-(67S8_(3T;P+25/.N0!<,:6%-97D+B\I=6=_?UF -M8K*/.3%=OX*&E$ERK(2ANXL$5_V>N[MPJ>C[RUZY!WM:AVY7#C^U?.@M/IN3 -MC?H2[30FM$\5T)7L8*)PQ/$2;9Q*(OL)M2'$H-3.F`*UZHP^/>87;$$XP&34 -M_5U)9J"#Y?KV:(5!=AY%FZI:5S4*&$5?RD&Z9Q08KY#U$>%YE*LO-8A-YL%2 -M&KZQ["<:,;?J(U85L7T6N6Y:VJ"U;GWWB1]TGWH.Z=;6Z6,(KH<\$PC8TFS# -M%XLM6$ZQ]_&SP>%_4-QH+33=)1LY6()WXX':T,4M'*NXI]'-S(A009HDB5NH -M$UO(K,S&8-Q_5-3R"84@TB;U=X\*?R9*7\S3>B%0BW[#YF7Z6& -M*7/D1**S),QF[XD'C&XT$ZPB>>WIV=4I24O\/M_?/SX1^[MM1T)PN=\"+P7$OM#.KE+D#LI>$2\ZT!/P7CK76,#<-*C)@HKM^-;P -M9%'I?"T/6:R0ZHE%59[I49; -M3N8CQ>N9-=6RH:\@O238(Q=K01LT,IF"KT=H^`K!9$&QIP]7F!+6#]IUN"O# -M0C5"0`A??+@!YAKGRP7&SF9>01I_HJ4&3- -MF)(5&Z43"B"[?W,!KV_<%FM42,/'[Z?$-`XXHX.ALTBOWB@:ZII,9TL2JNDJ%> -MMIYH.#V_"R_3B48T?MT$LGF3@`;!S]D>G>5FLNV@)BC>8HS!]TPAK!:)=&73 -M`HR1*WJ_KOS&%<*!,/7,&**.L@&UG)`UTMW$QY[N6'3XZA07'7`NJ38$\OO_ -MM3LJ3(QNX>?\`9LH\T19'CFN5=J)YF"R;%I'VX0$(]4]N>LA);TGVJ'ZJ?\& -ML<)D5">A$RP8(#MVL&93GS<[$JO7[_BQ*,BLJL(A%F$=`U.V:?TJP$N7,9>S -MU/V3%9[8I";!\H$L)XQQ7M3\+!3T>>*Z(?U:?])/TZ\5US&.`Z*[G>SXI(F+ -M-&Y]/([O`F=GFJI(LD,,A!Q7YV="5F1I0U&\)+1--D-D*8I6I9I*5G-+&HG4 -M"U'F_WWU),'<4WI1FG7IF_12H+U2[[2QJDLR*[EX-R&*[M`+W[E-/I8XLT7U -M5;>Z*\3`;PWJK\%7-L,8^+7GCP=_;Z+\,R;#+A[\+ -M#I[EDD-V;89),24+05$5.W5%;0A8D&BZP<@!@UE1E:+IU,4AC]PEEHA__GV1*TU!2!M9X#\8NC&4LP0>VS\30/JF -M.R#$/R32E/!I67:NBEPM$(8VJ1J*T=L&]B"PBC:6D0Q[1".`I"P.R/<80JY9 -MFI([3FNB*_O7"U-Y?E8SUPLQ3&_3SV`M&5U`!7^LW7TMW*`;A%ACRGXRZ6C; -M6P\,3A-36$&.OBA]ZSF#.!#-R$S9WS+*>^^N5_9TXV>I65B.UCF8GO>2#;^;+,]EU_$F!0NDED$3%*7XU,;'VV:\\GH]$;]90"3\H]-43'VOM,, -MA&+*0AJM70-T_I'J6H\M-W+?5,$XRD)I?$1D=9AZHPIQ4J=<>C";&- -M`.B[:'3Z*B/P6,2FVD,Z-C>X``.F\`K.1[/Y\;B_>7;K[&)*`QXQPIW?-3S:T.J,4^>"AUI`3[$JX'FWY)7$9$>91BG['.D2Y-V%J6:O`RVM4QP]""'K?O!)C7E<^@^;4 -M1$7G),YDF3N'U]-G'5?3G$F9YE/6E -M?*M'@6NOFH+1*`DZ)Z]64%@5S#2F]8)$]/7G]DYXJ06\>[YS?'J -M$?:PL?Y63>$59($8A]:(OWTKNB1']$H:A$5XXN@@@$,NJ/EZW;`H]ZILI&0S -MG11ZS'>>W*9\5PHA9;=4P@0:Y?4J>CDJ+O^U(T'4\)CQ>.5-F#BBH;(U.4#J1(;U!0MAWKZTF"B=^M"9*@ -ME?16NFN"06;08(?J9.,C<-R#*+2A>]*;687=\VY6MG8&H6!091C]8/\0_#Z[ -M`%1$';>JY%7HD>X4#SG#&BXK5`5]L=:FS7^A!@/V&VNST+61,:X."O,M=2>H -MMQORH/)(T`OW0&HAG^2ES-5;:QB4IV$W,%_A)E&*LZQ_4'1*FC)G[WCU`SP- -M.Q4=\&;?!3)L./UE`<\8006#I='"1\B<"]4.P`*G[P+^&CYK>G#/%[D#D^#X -MT7A%>TOVH`!KO?\;!BHHW<7>Q]JL4HO)-;U!'@]K$;U[Y-CLV04T`M,+Y'=' -MXU%*.>]'FJ:Q0=.]3;V,7)S1\K,H;B0D -MAA'@U?D6N'^CI3D@>)1![)`;2"=_!?`J3<`@1SZ[#H--/(CQ:FT%5DA/M;.X -MW2CDB6.V$);X$"XKI+9N\UB[A3H^$7*1#?7#+8ZSNNM>O76],OE';F8;QCMI -ML=P%7\Q3G2WN9U?GD:4RD!9C:PO0RJMLQ;Q#8\<^M(EU/DDK!V7IJ]Y=F\TJ -MQ)U6?#Y7N^N/U9IUFRYH4SHI#!(_NKZV0N_+@H(.X.<*&/GGD#TW\XK?/DC3 -M&BCS8@Y51>5-Q#CXQ`NAA,UU268<"'\W7_ME\X?H0#NCS?!PJNW[%DKFT@=D -MF0E.?)SGR"S*"O)\MG=H3Y8&!;1B95[O]IU[&"<@&ZU)?5N;G_KVCM_9A-V0EA>^ -M)]SK-:N56YZ:\.O^&0=S'S:^<3FFI2$^ -MN=-T+1T*W>A4W0)^)O1[JH'>/<8AR`G!6=Y,C#Y(^)Q9"GW`HQK!M^-^%\:U -M8?FR`L@YI:E*[JJ$KFZ$-,MSVUZAB2\VH+;D[.S:P97/[Q;.6`")D#U`F$VF -M4+WD*BW$>K\PDFRVQ-"KT5/HI9T\\1HD5W=0\A]`AJB2U#8=X]!^='.76L0# -MO1WO-,^CZC,=%6I6O!PC#%^!XADWC7$C*DQ7G#NH:#]=`JSXN9/_]$C4_=0, -M#0RA$7_7B*07*0]X(&2MI8R_BX,G%@8>_-I>><-'&OS[=W#3T1AOL`37'&=K -MS!-N9:5;*/"-`_$Y6*,!>,+'RL"(^]A`8'DU=_A`G^O4*_+6%_HJE*7,!OY. -M63/2Y;59:,8?_0$*-R)PM2CFRPRUV"40G#GT+@U3.20XP^!-AS`$\A$")/X/ -M8Q#$R=4%]/!X#IW48-[69U>?]\A&\D6HLXG_+\<0'L2>A;#6\H(HR-$%_&-` -M=S>>05`P*?1CHDGB\P;CQBQ`)%\5!`"MD>]9:7@RHJG(B$3F(EY&NK>Y[O8=J"35-C@/R:RU^U>1RY$R)=\M1* -M"BEN2I$3(Z$\C;:5OY0%K<94(D!6N(-=Q/E4V5D.X"W9799RK9R*3*DI'^/U?CX[+P=E9] -MK*UV4RY@YBU[%S&N>474_OYKVSIK7HH,3R;*0P>0!X:!_)BM)#:W10>.G)`I -MS=S$+H!4#OGFAC`T1SL>DLMY%A-1&$)XWQKV -MH('G+@ITFU6*A+4-+V)8,>FB1O^SQW^2B_'O+<*T3_]]$[(E8B44&K,DNEH&5E -M9@3>!6'!MM,&^@>-V&S.;)7TE19EJN8<"Y.V`\+5`D3+VO6:9D/?446'ZK]@ -M5-IS-?M7TAB^*A8!"MBSGL98SO"!2"#-BN!PYE;`_S1>+W;)RQYXC=P7]9?G -M-36!M4U5-[L<1`Z?TZ9D[>>)S-!*;C]NXTI\ZKK'/!"",:NBD1T,B'PPGP=W -M=ZY2RUDYQP)%:F^1I!VAPIPN?+M?9)/E`?L'6AHD`-H!UUWFVR7:'"UZA9&U -MXUZIK`7J2^(1XO-1:W7'*51/L0NF";HE7?EN.=I*MA1'P\+QC]:D3T@*6SL5;IY8XS?,"JF-5%VX`T-)3?S_CCYFWL]"1U^.BYK. -MJTY=]V!,6RX -ME'=91X!TJ6E'U-XWT/1B:B!JY0JT17'',74,L*N<_'16164X97(4W7K92]C8 -MJR]ENRV5WJ80CSDB$?)F*/P7'XL*TYG/XT,T/A)<\;Z^P1_YD;:7`CQ*=9&P -M=L3\LK)I<&WF/H2-]%!@)%O<_#-J_Q;%LYGE>SSF#.QUFJFO/F`/RCHTP.$O -M_BI29^2&I=/2YO*73PL*5'YT/-?IM:P -M>E05"WF>0"&`X\X?_XR[[20TJDY5>HWBN>&K+$ -MK4B@C`?]A7+U_W6RGE)4GE^UL&:]H6[Q<&$I2*-C^22"0OA]U6TM7 -MG1!JT6Q)R(71E.:D\Y=!])@Q\JUDH:*P#O`)B**_HHH"+?&NLW<,M!5U*N.< -MC22>[ND[!DLPC+6VH>M*&9;5I\?4J)9)05VW-ZT:#V%6`OU#9^%>!+@_[OMZ<%'_UC]>I+K8V-_7-$4MIZ+P)_:P"'5!*=IUW603Z> -MO3._OD;N1W -MK(`Z:ZZCU1Z*KRTOJ%L[HO-= -MZ$IJPG(Y7O.9V,V@B4B0B&CX1NA.*I@@=UF@60B?E&W,HIF/*ZMM,M9P+ -MEDIZSU_8J9$>]A?CXE)*4Q/A1B-_YX$,+%F0*N)">FDT`XKD[UW3EB+9\.Q` -ML:?A`=/+WS'_LH64T&W\*5FV:DMWU6,5KB+U);>W2I%%2WCS[&`H(* -MZHA^=OX+ILIY0"R)<.%/44IU#>IX+(Y(!=Q<-CM=;3%=JK0V -M@>I0TN*$M01[:P7.`>8AY/6OTD@>[Z3,?FM<:3\(#1/"L?X5+]LIA7UF//_@ -M=N-,SMB?]8AO`I1N7)=HY45?-^^L2ND?SUQ]6!>&Y,-V@[L8=[ -M-.2,BTS)KH=BY;C`$$PV$M#SZ]6:I\GS*^[M:C-S/ATB7W@[:A3RVOBLJEK\ -MI3[UJ[)#@Y#]2WY$N8S3:I!.(,(KNWX\/B._A+!"U@0FD!(9U:[FLMK_\TI_ -MW,3,R71T5%IF-?9Q1D8O)4,\TOU_NIL7Z_#?^T<0N6K")]76NFJCF7L+#:ZV -M`FMWEZ6''KA6-TS7>\>R[%W59D0HFZ.VQXK.IF%RL"7A\2`]8P.<9;_:8S0K -M3ZVJ0/47C_>Y9?6H:UE_#=9'*?:HG4ZW3_5A.9UI3:=/5RH4T7/$<.%WUHCX -M/V7X%TB=F+_V2I&IHL3`;']3D@&;U[IZ06J- -M0VTT=QVXHL53QL)QWVG"3_`F%8V()KIR$W):.0*8HGTB'?X5]Z@"7W])^E>Y -M#)Z[>!M#_^88A;21L#3RS.^E@1I-JRC%`H6A*Q(.N-T>SQQJ@[G#EX(_7JO& -MF)]+>=0Q(4H[472KY<;\,'$/GSV3=?*[IL4^]NF5/98RL*U3<'I=W1DAL6OW -M"*3KC*7",TD?#P53$/SE57!J0L),!=V!M`P^XURVN[ME4"J.X9&8MH>A*$T@Y_1+%`+L`38=J8P:CJ1$ -M;6L)D^[UR^N8[F7SG5!^-F&DCZWO4)9%.G`L(6SDRU%G$?,;39:9'='W.<[SZ#&H2R_.JG4/\ -M<[X]K6OS^A"^_8'?/G=A/!@FWR12!=X!Q#'VC=V8Q#!H'FDKWUJ%7A_Y -M#=5!167F"G#W*_]%=@(-PM88UHV@OU'GP@!,;<@C,[N!%-)A/67"L#V3!G2' -M@SE?:#2:;^=%2Z#!K1Z$7O"9K`VD$'Y'1_I3.D!*--JQB5_&E?O1-&ZX1EQM8?7S -MGR=B4?,FY9TB327GU0E_3_E2&A0=3#T'MW -MMQ!28D;9D>LP^TY,5*O\XFSZ0DK*YS?F^D=@ULL6PXZ]ZDK;=?1GOG33SS\2 -M1Y_^>`I`THBUF;EY@T/:5`7('$03U34X,RE/W.8SS;7R.AMF!@90M*XA>:7] -M)77:,@T],IHRO#?O`.3OX54E^;4C[Q;AQPM/-_,BD+;'QJ+C)NZVR'5/\KL_ -M9TRSJ.<>1\T@:$M(BYW1.T$597W^$S<7K=FD>L#%7%1P[3^3S)+4.-%H: -M67Z)SK"X/[ZJK3Y'%/_CD46;G1#XNT4`[,[5GD#\]&3UD\4\]_YE^.&8CM2` -M!N.QVO5G4FJ/8%N=;-`RG2K*SE7'KRYO-1*AA>8@VX;JI(EPXZ.^T_F9J[*^ -M=:#XO\H?+30@Q5(5)$[`4-R;C.;%_2&3<$$L^+1[_UV'.LN:&J5\\4OF.8$= -MS>$P1?$-=BCA1BC[_BP-QKE-U%"@*O;NE*)@$?B8E^"M67YG,&3_9N,>0!33 -M.NCX15C3T6G24,1?VY5RSH5JV'''&1DI83'Y:P[RDH:HCZ/I.VF7!F#V\:DY -M!0L'157:SU"*T6F.6V""^>P,\)X;8@UBO$*]_@A*LGJ%@N=+6>`E4$*>-!DN -M<)2L55=H*,XN\I7$Z9CIXO$<@;)3HE(89%-+$O\LW/%K?%;F*%#XI:MA_QZ_ -M$K5C.W(>H+.^XZCUA#%B9^J^8Z4=F=&/$#ZLE]8>4X\?479N%WMLUX73N_S/ -M]]"4>!(M99"U)0GG>#/M'I^9ID/"%%2$Y.PA_#R#7[1(]*-PP,O!!W[3E_M9 -ML#/>AL4*!,XEZXCFAX]E]02S)U(FHNY?_DM?5.VIW#M1^&40BQBKEPY?%VB; -MDE"^&5&2JER?BR@9U,_>C;4K8!9#C&=H*U2B9I/[Y6&'^*N+ -M2T3H-+$5GUSQE(&="$CJXV,F=6KKY$FP1R8\HQT8!%^BTYA"NY+N-3V_`P"1 -M?IR)ZE25:I<@![%QE.$2IO7!ZT.AD..\5C&CU>,C@!9TE;J$TH^X%T:)K6E- -M3:?.@>SIWLP"VN_R->97:DY$S#AX-D%MN-PG*%49=#B![*'+'GHJ -M=!B/-4"8CIBD?T#N:K#VU6DR*"E/9T@1#[5U2_F!]@*ZEJP=>K#4:&^+F2C` -M*E+8PX6SFPH4/DV -MD$UTCM"L,P:Z.LXSHO[T1A9Z-L8'*;-4H3 -MC,.(,GD -M'W<0H/!*!TEQCZ9;0M`/").,!+H$`;K>02&#TC5"Z8=BQMU%'`8SZI6*W=XL -MZO#FUU:-?P@D=%M:SBLK8:'\EF=Y@4UJ4D8MB>1FLR:!F2X^KTU>M2CVS+MF -M)L55;,$"?JV<5PZ[@"5M#\$6'\,ZB9QH]=$)$?U34MDF?\L_+V9FT3D-CSZK -M*!'J+=/""JYAU.N05;/EIRO:IU7"@&*]LG,3?LJ37<\V&]G1L%/!\F":1%S- -M9U5&4=J.F)>G5FJ+(_]E!15+T.9P`?3VKX=PS,Q4ZNRN$)3A?!K'+Z$ -M-UJO97,_3L!2&48)+LK6TJK4F`#9=F01M@E4X-@W`PG%#WK.=B7&$?2/$H,[ -MX2RRHD`.9Z^;NITF'<_VC!BE&8?GX[`R=OY;/A:8_[K"NIIC5)ZVDY%UZL9, -M9"(OD&5B+R@_5IV,'0,T1@IWQ3NS5O!5##1:^#B>?:JBA2DM=1X!EPW[%_&[&<:#]3ILQI,XH+_?^OI -M>G5IZT-Q^G``KP="5!(9B4U=-O41C@#_'_V)A40EZK7R&(&&T]'6)8<'U1&YX6.0*\7KDH -M%H&5.4A6ZA3,@$16'=^^XX[;P;9]Z0"..-KA+J>@Q5-(K3`&T*]T,5WCO\A5 -M<\N=)J<.6`NLPDNZ0P+\9<`8(+#F-E$AZ`IZ.\E6%5:^5X0X=7SUA!8LR(ZH@'Z>* -ML1H[&9"1B-6,!C)H]D\H0$=M=LI?Q+JL?1CLO4@P(L#WN1V"]PN*A5T -MHP^1PMR@VOM29$.V\!XV:30,7)0%ADM).1S,P=;"R<+(M9.W3PYXRYZ(4+(7 -MR+XU/J#TL!O?>_[5!M>43Z*^PBGN8'.`&Z1C(!"6Z6<7:[W.4P#KN7>)Z(CR'0A>0ZF0#5&NET,@[S#H,`UA -ML)XAW9KJS59!K?K-SFKT7N?V%`"G(),T,T3I/:V'D:AEDEV+^/H^%648AI3^ -M187U:8,4.J>01%KP[Z;##)*&B[$SI+\S+APUF9"G&>A$)>'C"VB&:?]' -M-,UJYRY4-^1?Y_CN'X"(I.4RF%$UK#K&9C0Q3-MBC3VN9HK(7:4Z;2O@N5Y2 -M]L([S1D],!T3\^[(BN*WDM[MS8%&D"I"I7BD_@QKUNW9U!*^A<%!N6+\5_U* -M(.*+27T03>6W[F-5_"&_6,(CE+SN9)WP140RJ:LNQ1KD6:)O6![/#(QO7_P] -M;[_=->M:521./7#W#%0U=?C84:Y?*X%+HA"7F*]B;KN0N#!_913*`^_>C>JZ -MG''L::P?WT50PW;8Y'QCDN0Q,O4$KQ=\6F1B=5\Y9QE.A-CW<;! -M=4+]?/IS:]GP&'$@Z,JT-GT,O`+T%)*YI@HF.:?_HID.`29G9-`D.F,O$?K. -M9?L4R`7I()KR&FA/Q5-B5+OR:QS>?-\DVP>K>7F2ZH$6R10XE>O]NC=S2:FM9 -M]M)7_HGG+HJVQ)!GQGY9^F23.WG,R^(H[GZH4$;_35A=/BXYRM!R_M8TIY`, -M!*6W:@:V6^WG;C79(RN37F0/0#B!'AU.QW">,6MAGS;@;2=FOXP5^K&4MW2; -M]OX0J+"D#N<@IKW<^U6A,1>,:=L`S?)&9>H^/\:-"_3>"Q\=J$GA'#WG4\6$([`QXY+8=A!2;MZL0L_^(V(B;'A4"'QMC8P0Z!+S@ -M.2G!D$@+@K*I0(_8A'HW60Y*8:/\D_`Z*^WAZIKHE^7AD7J-R%/+WJ0Z,5!X -MVI[)8,$!(,R*O6,O-6$[5^Z^S$,C&'LY"-CS)?P02+[;-Z<)0>&[>++$1)0+ -M_^T_C[O`9@["&(@YJ?#U.J#9\`MITTJ?AQ%=QIG_8I)3)VD+$!J()\PL@"?W -MJJ3`AH3:6OTF='FN3M86`L".X22`\9/YD5!3=#MO\F#6<=M>DLZ"/:; -M@NG7DVPX+=-ZR)'2`0'[7(=.,F&.2>`(FDAK-Q_M![+YZ"HFH4^MH4_BV^<< -MCI21; -ME,8AR']/J386;0%VA()900YT04%'X'D:3_ZG+(6KE#X4HSQP5*(#$=#PN(R2 -M,&E`M#8%P]ASO^WR6Z+EN#X3?MDDJ'(R1V!P/.2OFSBC9RX3#`T8Z_R.8/[S -MA8\6](C_]J_@G&=E_UD3)V)W+]<$B-O4#^-\@U664G/_KV`%0[02?B8EMYC7 -M54&OH%=PMZHVE1PF7YD[X5;Q>^G3E;'>(3_#&@(16C3CTAD&DV-X.R$=Q9@< -M,"/I*6]T5-1F%E.I(V].@K%?M9HZ?\%_GP-$3B2J6&>D"VS]-"-O%@0Z>HUO -MH`PQ74:/__0\SUL7)V>D:IC44(*6M^TEAI83]7%2B -M1D#>3@X]M19P1QWGTB.F0*EH*C==IK[U4"E@@76F6(PMOJRC^<'5.`(!:HSE -MB,]6J[#YP9I$OV7._4/:L/U(4"V@<'7!M$X)BE,XXGA=J2)>I28ELG?A_?Q -M#8.Y^.>;TI)$,M$9)$C2U8^M!?-N7WKJ6>J-4P5#)UD11/$%X0:.7UE'[MEX -MB'"CK*.Y.S[%_LC+F1P[53%"J29!-S,/H"QE/C/=A9((YD*-;#C5BSN[6]A(M"T)JFH,YT*UEC6=C9P=AD)[I-!RZ3<<6?2!?1\ -M.[2TO.IZ:X]-.>P,VAG(;`Q7+X7UIW*,.L+F+%%[X7\NUGF^&$2BV84ZVBS' -M<&XOT,AZ0-2%T7%:7YXZ'Y\^I(%YT&0X0:D])ZMO(GV]48=Z8@FI>7+\F9,9 -M"_UF3E0B)O$XCPASDF$LU!V38R#B@$H@A:I$SG -M!"E44SU];C6J3D8_-.2(Q/0.@B@=E3!YEV-;%?+(9?*S*9-4HR5FHE.\FW5E -M>#S0;LE&?G\^'LK.]EZ?^\84,((8'EJKD;\FH1:&_@S:17+O*I\Z&\J?MT;3 -M#\V5+#%NVP`[N4+VO"[XOHFQZ]6(KH3[_&=**\0TM*3P1QF!+"?(TT*C%5-T -MW?F0!LCXF1B7)/GG3!7U^7J7"W+OPFV#^Q4/YE,X!E:2``OQ]!!/(*(QX=U/ -M4&.[@8O6R):6XUU81Y*!H[RU.0%'%=B,^-*?K/B627J(B/VU#?S*-UHA5E$A")F9;\,:QY9!0_$P>F<7&>_( -MAA/R`>4$(ODK?3\6AS@^D_,0C%:M-^[^7KU""_18'W=TZ>RX -M!#NJEUOBD=VRJ.B6;8#TNVB7'CH#S3DC5`8Q*Y\3<.)*YP!Q-,(LEBNA:`58 -MN>_&YO[.IK!N\"Z[E%Y6CJ-$M"Z)YV;2W.Z!L_0]HH[M!57?[MJ"W&Z#3=3W -MJ-Y27+.098O)\DM6X8#F[[[YF,#U"(%B>JL&5C.\OC_C"T`M*J*..89#IN,/ -MY/>%Y>^2&KR/AW..`F1(P=P^(BEOW5P55AO*T(%;+1LSMR=<1G@'7TG;VIY/ -M,0=II[`#"-?2T#_9CQ8HH;@,\+'#[81*;XCYYE+STN+E2Y6[")MZ+1BUS,S&9MTN&9(X2?ROY6_<[?^JWN7%^Y0I?;Q+08\[ -M=08BF.P?P\1^JV_LO>#T,Q'+_\5=(V&)M8P(`'9;JL;JAQ]DT$+7;B%W+'>J -M[*,HB5D3]M.NEW)T#+*[-`K>?",[_[U_)[@__2\#Y6-,/"#<2#3P/>$=[;@DN(TS>9@8HT96'%*J^YVN[]`/-9 -M&A_]57)^Q2;:Q^2*+$2'H^4D-+U^2D;8/.5O9&+E+)**G`-]LG+E2,GL2TF_ -M3,RP"]UX;7.OP'X?U;YR2`SI0I[\,1Z^J]<;$6XF#Z^3Y)+BL!PEQ]F3\3BU -MD:7DCO'T]V`8CI1TMC\11=/3<$N:2K<8/TZL3W%X>CGZO++T,)WW""]0"[3K -M(3*JWAP;0-"@@S>3IGZR*7F:TJE0]W]D`65LDM4;/A[&SQ850\PO`7^8(_K( -M$J47Q!<>#D]G!B@?XJ>LX`9G&LBT%>19N1=PGX48HVE2ISN@\$3(#G915!UL -M:8&4;IR``M1`[N"^U]+AQ>M21)T>(:P!?FWK@1I'-'-4//C`V&\I6H8`1/GJ*(,; -MM^F<0IWS$!0J1HJNX,XK/$1&2F@Q]'U3^(I/*.RI.,JBBE""73T&X&5"J-*V -M#P,\;H^3S^G2=G(J&3KZ-@`:.E5>8&-4W06VWDO73ISL:F<+PP;?@'9O,K6A -M?3!Y"]"8M8*8%4.M$,=]U6-PO"VV]Z/3S_ZC$9:>'9EMC&;Y%N`1(A65K=/# -MW.IGBHN7JG=.^Z7B3QMY94RV65_L#L3N,WNH65CJ>15:6YLW;8M2M;O7R8PP -M&^`%SD-E@$XRE02E8F3IGU_):[>9SI2<_YL3B7N5"HI$\T9=Q\4/E?6M*[`# -M^*>[Z7%?);INS:Y4^&S%T&MD8351_FK+:BF:5GO$O;I)XTF(%)\1WJMW:TV4 -MCV(#]OB?_LH%%)5B^&"(/YR`"E4)-8^62G<0AU0)EQCJ1#0;U;PXY09U`*91 -MDR]P-,?#;O9%8`5P#:&&YD+GE)`QH:XGK'0[TN<BA&[1?_ -MHQ#?]-JGM++2U67-C0W.X)42U+,)G0`05J@/8'^/G1#^9B -M)Q!#6;J[T.Z.MR^&H1R@/+C`'$\!+IA`E_2#MG;-:)%MF#/$"PRY$="[]X?? -M!&7_95#@Q!!3VIZB]UR=`-0^^-\^^=U4=`2G^(._J_X9)C! -MY#"M:=RI\*\R591-F&T8O(]N<`%"`FQ-=*/$N2AB=7:_I.*++Y(0>MU;>"\5 -M&>(`UT\:'CU=RB\.G<8$9N7!! -M42'31QU,J]$TD60*4%YIE5Z_X*: -M)3PMO/I/.-P[K!_$_:8(AK?AE%L__6JGN]B+'S3FNE^L??TPB+CZ4!+`KXJL -MVZAWOL+[M?T,_Q+??OS\)$Q>0ICF8MN[=21X,UB2(*DV-.]EU7'Y5N"OF=[J -MGLO$P9Z>"P%G!=,TQ.SY12LI&B4I-\'(_54\NA_XVF1<5%FP"K13-3[7K@@2 -M(UZD:S09M\Q`;8XX/F -M^@@EE.E]8M=;CH@0Y%7E\>RXAFP0`%BL*!Q,!GR(?>_/1/7.RIZQ^_K^VLZ`P%407VRX#/NR`+>HQ8Z]T -M76"H^`49M@K,_"32GGPXR&\+:CS1[/8&@>+M^]*ZI"^*@-T(/-/L#F,YBSPJ -M2E8W_?W_!T1,1U8;5.8U`V,3QF4:]SL_ACX,^D7F9&2U;7>7C>#JA+:B[C6- -M"MEH_$.K^=)D^X91&G-\K^L[?)&?\C -M/?#"+%&>OVXJN9980VE?(VC$\\.:Z9YE.2B@+H$2.TX(T9K\-^O""U>=F)9B -MGJWF_>B$X^U#R``MFOI$9U57C4+F>B2)=*Y;NTH@)K,/NL;ILRDRS8J'^U,# -MA?`Y;Y-U/T_=(+,<147BRN/M:;6%2/KI^\&WBM8,E8MN0.Y\@QK?7K1 -M1<1R.$=+(?U>$!\$Y@6,@`!\U\M(F#\S>Z;:]#CZ4K6^ZO%Z`XH/PJ4[XA!# -M+JY!M@,N8E(!IOXE1M:-+F<'JN"/"A9("8NT]>:;D785;R2W@A/(=)SDF5<^ -M5ABND.]/+\^*!1P"W>=?Y=)W(%6`;3>[N5/L!SU@W0EF="/%9J=XGPM3F(D8_F$ -M)U-CQ)M\.=%'9)RVK03S_KWS,\,,A7*L:-JF/<^3N>=V'.P;'\S2\L?T$,<< -MA5"=M:9(3$WZ3WLW_P/2HKR"[QSBYMS7Q__S$&OWVV6W&QMAFE@ -MEO]]D_2K9Y^0YY!1[N<_UZ&B;L:3[PI387@N$H9S(8;I^;F:@`G#G38:42@> -MWL>G[#UAY]Z`U"_7$`[)MF%^]_`'!B)@RE)W:2*#)/$QM.WVR1WW*E6 -M?KADM1*#T;-?:%[LPQ.`-:\LK\&W,VB'&/.+/ -M/JYDHH<-I)>#_!;#QB\2;LAK".S/.A;X8J=9DXDFEE5LR2H_K[+RHDU<7VK_ -MVW[G.TY&X'07#H]#''^CT](AO7[7P=%[U-T0968_YBKGWT3]F4KG?-"NL@'Y8#UX/.S75Q.L` -M/ESZ*47?);G(V<\`(\1(L>D7@BV9M<$>)ICM$/L@Q/&N%XIK\S^PL"\\_&M4 -M$--,]X&)$#-D$1O#8OL41$C]""U/87.9[/?;DU`H3#WLA*^L7,SO.`0Y2T]K -M8((.8-%?V5Y([AG60X(RT=2E&/`$`GT$,1-%+=S9(35$H\O6<@R@ZJ\4Q^," -M.E%H(#.WJOZGE`NR^)!<&RJ>OG'T`,PM^C3%>(6IBX5QRNK)#\W868:CI4#] -M!2AR';4P[=0P/&&:!:`J/5FA)YH\S#,KUZ,IQP*=/41)*'?MW^EESZ$VI1V%TFXOJ\=2Z%G;=&-KIIBS;45($3TY8(.F!%7W9(**7AD#K4 -M"+./?\VT)$YQ".^3LF\?(:#F.B-\8CBKL6]9%H4_"QF -M0Y+"1R:K!CA`HP4%_"HU$:ENK`E?8M8"J3AZ,UE9;T"5(T7*3[L+'>B0X2C0 -MU<^NG*9E]'R/54XR\20GEBOH(?OERI03C^+C^L+T^[LP"3=C#F1*\07V&64( -M//)8$[,GK5)4J[<99+\LB#X\*-UP"3U4V"C58&U1SWFWAWK$.$'((Y -M'.V2ER[/@VQ\[-00W-'@/62(3#<(XL%A:4ID*S*WECXFQV?;95N/\00A.)&7AF#%Y:&]B!S"J10]N?\3&V1 -M\9T0O3D+N-@NM,><@JLS]N@(+Q$ZM=N8*Y>Y9A0@F$[R?M!O@_%QBP;TFKB? -MRO]8N%92$.%7//7ABQ9^&SM@]R*M*GD[?VX7X/=*V*XIMHQX_&+(V^O0D[_D -MH/H%36$5B"`D!-;*P];8$@GZ0L8S2.W&NFV%E*2JNMKK<;&@]O2BN8J5"-AP -M,KGTZ?1'7&#',"?RE';7$3"A6<6/$?KR,1P`'8_&E3S7`;6"S'F/"P#/#?V! -M0`A/GIRI3):B];FO\)*)$HXYJMUW;(VY\)8?_*SX2:+]-#K3Z$Z>D(^PD4E- -MD>M:(363:7M?9''$,TDBR5:75)Z*+JPN?=%*17W9]D!3A8A);,'$USCYM@?.M`H -M/[8@=FH[9I!)`WK')@=JCV`:0:A/(;E;7^'B7+D]&Z%"2T,_01Z6^B!^SZ1# -M6-EWRRBU$4-Y;^9@`V?=S#86\*9]>[(#>`"Y8LUN"=S:W"<34!17/--^3L(# -M$#O:>RAAIJ*>%Y -M>NEUJQQW_H@:N5LX<;\X&'+AT'6!GD!79=/KG]HD[S,QGU"R-4Z,X&H/#5-IHW!YT/F6PG;^E?C1 -M7#-?V5(KE_,0YCT,*5I9>WO[:,@7MZL6&%[O)V/:ENCAZ+"8_0)<#31CVD^8 -MTA)0J?(=3F@$3/PC$>$AT1VM%4^2)B`,=$+Y]I^:%(BR&75*=18(LYLZHP0E -M1AA"HU5#H7?LY:G_+%UVS@W<5)!?/S2.L`$3_-"L/86 -MMMW>TAG),-SW"3/%%*)=4.!<;%."<%N76RAO`PA$2C!XK\5QJ?P?::*<<5@_TE;O@YXV^FPFT9!6[%$B%9W*^%+B4.$PP&KM6*P"+'$1 -MA8/#1;YW7>\SJKRDB'IGK^:1:2SB7$JIJ-.<4KJ2B+M\9!\PVXE](+CYJ[SV -MXGRK,S4R29C"@;T7Y6=>7$;""[W"+*TH8P;%F.R,PY7%L^/E[(@;'N[>F>FA -M)O_@RF[S3N"L_?%M.QHFBUO!24Z@+(Q;+YTM`W+5;D()[)RZS=7!-9*9PX\XPK(QW:CR.0IYAY(+<5&I -MY439''^/+@DQ;)/OJ+=%U[#3FB_-'6@XTE-&A7=_!_\B!T!)\7XAR;`>8$RH -M)F'KMQT3VE>5LG5U6+0N3.:"5WVZ2,&/Q-_*)HL#.8[J??>E``+?Q^\QOPTT -M0]Q!3D7UVROT<0WO-$`L/V($JE7U18@,:DMQXY)E1SZ#A)RN6-65HS-V+Q&>52_W3MU*"\#ISK -ME*6DWOOS<-9)PLNF1R6&<_RP5%UAI%3]EA]K,;E1'`T"!-.18^UJW&4N@HU(U_ETKB68TP3FXWY0H,#OYYV;Z3!1H%3 -M]`U?OD"E,4)?G*1=3M_"QA4JG6J9/SG>D;HHCUUV?'%+5[T@J**0=8[5>([+ -MGLM)+M!!90$4>0SD7#6(,6A12QUR-N]R6'W)B,MOBFQME(-15?SQO;7'#P5= -M_OUW/'#6/QFM0A3@TC!Z^9^#R.#&;UX:1/K,07^)K%@\\CLNXVHF,!_D>I`W -M5]\<"_+392WJ8G39[*!,%8B9JBC,&_0_ZUO+_NMQ=Q5SE+'7JQIEC`L'8D'! -M."-*B$@&FYH6<4,9-B7)5X?Y1(L-Q7A<.=0^=5Z&B-YFELZ[<-NY/W4(+I21(,I![]]\]1*T`P#NP -M#3A7JV!I-K;63Z8Y1I"W7(::]`YG)J4-(0V<#RRRHU&R)38F-W*-'P=^&BBT4D,?\95G7)U.F&CGL1?(+?MME8P6.HW -M0K;V,"!PDI+,2IP>):\X]^T.B0@G#5[N*Q>[FK\UF(E^$[T5V#KQ()H-,B+- -MD+')ET,O+>4FV7OFVPPT7;!EA"/Z^*[//`L''+".\.!4\[4C51!=T%7^)M9/ -MHGUN\0*]_/GPB=`*&4),OC]#WJ-J9,T@C);"!][+?"B?D7*>S(2EE/0CNIVV -M5(;<+EDKX%./@%U%C%!=F?[1.,05\J4&]11Y7FZ8WL@\[`$R8(V"%;5_=,#SOMXG"B3B8+[0Y4;;TQ>._ZI(9CLGAF[%T0[J@ -M8"YPB/D;L28UR481:'G01'PDC&MX:X_FE3!N)QC@85R?])?0/UDV/*8Z&85' -MD1M=N*3#:='-^0>999+_L6J]`5']+_%WVGS[D;RL+5$5J9RW\C058^V5N9$5 -M;=9F5*';K]"GGM=OF[,^JL;/G\#*YLJ@L'PR(`?E$4=YAQ%.$6=_)ETG -MG64QF';27[Y1QC!W3:$\1#5@8^PE:)1S9%=!GU>.QUO!%QN2-@@R1*[?2X=: -MGG>H'S\"N)+UN=I+48KW;?RDTKG:S4KK+&&$L\Y"-E9^3=@0MV0KP&'^&+_C -M5]VA!%"D,<6X&)21^ADA/%17RH3UY3#:J]!"KN<<_4OCZ%?$,MOH'5(O^*I' -M"5O,)0?_O-S7EA8\HS,Z_U+)G5/AZAR%`;1/.E8].!/T5F,J*NQEBC*-]!0'W?#91A(OFV=C?(5C7'NP_])>AMN@P1:1?;I(LUV$* -MD*2HO"+9:*\7\XRP/7^URIFX^?;_Z[>.^&<*PK^Z[9)I9BI!18@'X#/&VAX_ -MA.,-Y$9[,IRYH.V@X*%%W[X8&-,<3)X.A#X6EEY0:1(?Z\9'=Z."8ADJE@YR -MNL)!/>:-\_K8!3Z!8:*KV@8X2^KDU'P%T#>\90TW]EI0X7QZF2Z6_AFKCIY` -MT:F]V1X'O78ZQSURE^2#WV4?#D_SXYRF*S`!J?\L59XF*ZL":H=++?82#` -M!(45,3:@=P`&>#;3^>]&UXE`![Y16/3T:4JG)A[.<=M0`9S"C8+/ -M=>2A(\CD#X:^S08@G;*338X3`X6TK:+M0H#IGR/$S>P8KNZQMAE:0@:RZ5`A -MJ9,)1FZW\URYNKYL8A;H+K@=^MA%RU.;.[1['?S[7V]F?OH9YF(212;DP@DP -M^'0EV)]+2]P>[%\:K"$_MBZA"!6`XOFI:K.W#5)2)+YSZTDP6`E3DB[%&KHN -MJI7J'2;=:(;B9/(&W9?&FB,NI+;EVQV%6A'D@=)(%`'7Q/M*/IT->E(,3_BN -M.Z66FFV-U$,RA35X']C'\W)V.59:\ZMN0%A$44?X"2R>?:&`7DJ=HGQ6,Y49 -M%?-83KV-B869V2<_1"@!RE$'4^V$`N?IC4^Y%>.='J:/_4*&9"I -M]TL$*X1N"U\O*_Q3+0E)#28A(9W0ARX$\8#MF&:%V3N/>::GUV-/PI'=[Q5# -M?9%^IA].$=2'JY;86$FER[X=C%)I\&'U5K^FMQI1=)B91!WE#45"@ID-'ZZ8 -M=9Z_(,\B0Y*(M8U"@V[:U,?)G`D_\>O^03#\I>4T6M2F='1&084YSSDZ#^!6 -M!K.#(W#L[C>**DISG26UA<+3#1VM>GFF(8,L4]`_Y*5LYA.>)KT6R`[]T=.1 -M;>%X-RAB,OI"Z=O/!2%<#$Q@BZ2=7-BZ:<3@/;(K.G*"3Z:&^-*WJNB8%!WG8X@1.(_N>S5=.J#$"0H\>[WR@--,&]RAX-J+AOIJ-4"K -MN3[2$.H@[-$A``VQ+7S)'AYJBGDT]]`;"U:71FIBO%$R`!2YDX5:JR%OEDI$B=0" -M@'P(DW;XGAWEO@9NB&O[P,G_(?+VK63HOV=MTO18$=_ZVT[\`!N6^%YE]82P -M-[JAB%BY^0L^`]E>,>`^YXX^550C-R^%L`^\$BO=T?A@Y?2A<:$%O1H(2\:) -MJ<;G,IO]W+X<.)\$O>X^]SV5E%7<08L][%$/4I$D4WPLR;I%+CCVZ-$;G]+W -MQ,"'V>C&CA_SLG:FP%RY0T..0;IU[MS$!9;+'*9^G*%*TKULH"8[*6DUVY0GO.KD<]JT; -M!NP@7\^M1T*-^$MS2@!3.]73$)CDM>3C@XPP/<;0KA`CHUM+#4M-LIA`$!*9 -M61_F!_E!,@`8>A[!/S:>'7:!HN!NY0M1RJKD_O/Y&",(?T7VB!ZT/P7O(&G" -MW;H!W^\KT`89\GW_++$/+7CI!,LRN$EUD#Q_9\0X/.3]+&W6/C-+D)IGO,6% -M6MF3#,(X\7M/_F4LD,+YSG]"WQ!571FOX5\1&LZD>Q4/#Q_""Y=CAY&R#G*+ -M1V&IKH`)/N@18FQ[IH<2GULWDQEE=[O0LP9/8TYBMNJ1``?ST7H>(N,M+B/F -MZ&_)520'22:8*[K-<:HG,/IE$'06L8/-Q:"#Q\\&7SZB]1$`:A[(DS9A5"#' -M_6NQQG@<]<8-(8]<0F',.2R^_N)3V::WN#7E%^G13\Y.-_QPK6<,)S?BK:%M -MXZ0O:]7=2?T[N85"+*ORZ-M"?;,>1/1.+%A("T>$;CP.1M=@!F`O<]Y/5B9O -M$R$?8;LD4)4)&#]FZ/KCK&L[CO4H&3I^Q\]7EK8N+[='QR?"=A!4Q^PTIS<3 -MJLTT62P"W\!8]YK_'EOHT$5MKJN3#/&9]/MFG%I79&2RF_]\6DW9W$JK6(;: -MZIU*V[=HTSKM47"0D25.)]&KX66P:^IL+)Y=Q#X[N.A?(/QUD"J*.5PNXL[%R7WA:*]1^IX[64G2;!"A18OHS(=U:]QRC2!2HT(@`MR,:F(G]EOTEB*M)4&YNTG4QQ.%%//#%=J -M-5GO%#/M8,-ZXNPJAYD;%XBLN*E8KXV)_0(98SL$6"8C4 -M5;YU`;;I-"P@>\PDF@`44T/S[V,P*>D$C$?%3B<6%(H!R7Z@>"AAK7*BKI9Z -M7,\Z>6H5E?:]I=LAM(7<'$/U)XGZ531X7Y>(+T,'#Z8+9BL]K;33CQ98JU5# -M)!-_4+J6LQ&6VXH'___020S/V0$540_UH]J/Y\UJU@`<>FB#NJ2U0A.&RGH; -MMX(?$[US.D9TB$(/M[6R<*56\XID`&3W9Q+AO5P>3 -MXR_%X:[TK<#DP3I[O5:#)ZS3+M:F^*4.NJ-WNMF3Z6T(59BX]4Y#.J%W"$(=DQ,?R_EDGN$/_!"I-@>?(J!5+A -MP)CL48$R!GL-V#R0Z&K!*GNK_(74WYC%46YQ0&X+`"+#+N5B3H+7B6Q2>M4> -M&>I;-$7S??)1(GZY6OZQL_KL9*PCMFJ`U')FK#7X#/%$76[J`DA4U8-6>LC?ZOO`TSJ$DFDQ(TAU^T0;AD+@SDD&95PQY7%YY60]^J5PCN2 -MJ;3+1F7;.9`59MN[:Q3KN;Q*M^T]ZLI9YW'8\;6M3NF6B8^S73ZW*%4?<6,L -MW:PWQ?U7AVA'\L]P8^$"XZY*COQ'J:YPGT0;YY:!B*"0YAQ'XX*4ED]>35EX -M[0U#1\5^CLFEI(NWQ@&?S2B$L\3W7Z(4*CC'C';_ZVS%'OHN`"HEN2';VPVL -M`9RHKT+K.Z.*]JV,XIHFV3TF)BDAD.REC0]RKS^GX+KR@\[ -M%:[KQ,X1\X^\C]3'_JMZ2:\H]3$C@1J;9P5R,RE=6CK:HO`:I;]I)JH=PGFM!B@(\7H%$FFT+U&9'AWFPQ,CB(CQ.TRIH09"$9W8-S-C0"X--A3NWP2/+0B -M:^6^"5X/?!,]G(2&X`:+CZ'.(@&(SM=BX_A@,&`?`?\M\R\G7:V(N_V`F9D< -ML1>08]A^IG"'>"_=,1;J!KV2*QD_]EB\B5F*`!FC8Z75SB#!<52D6=O+YH'L -M3"H5D()T>FF@(A4K0PT458@=B$LEN@G#`2`*:.@M`G&PSYEJ*\!88'PB]7ZV -M%IJ868LC2.0(RS>6CH@6NK(V3?\#1[IXHZ@[[TV[LK:V,K$G[X%`?UH9*HP@ -M04+@[@VB8>@/L&E)=?H7B'.&-L:*`72,T@2%6']->)35_`F\AAM^(AP!BXH-9S;.Z&H* -M'>_/EN"I?*VVS+^&H73M-8M+@M&&EV-.)UF_`#>&U=$%R5)RJP*K1:$$YMK- -MM^\!%M\=]5E8I5'!X0Z9],N&##/O/)E*38^K=R5.X8KHFL2-8)88W[VX7N7Z -M\%][%RZY==!W?4&02*CM$X=/,CL3"R>2I`>C$8[^%5AD>$8$^A1#Y+,3AYLN -M3SU3.3/@_=<.8^Y-+_!43.!8LZES0<0]0SGA9Z;C/\D)")509%I"!Y#WT'3" -M&5=225B6&=(XWHPG\-"-?=P,WB=!:3)35A]\G[/`&Q9(>QWL&R=Y8"J0G+L; -M41FP!5Z/.![BU[$N'`O3I1`X9`U6]Z,6P.0QLUZZ(^8I0![9GQU90T*(DTM` -MBXH$I,4P)EP92A'#%_$H,@SIRSMF`G`-OF(Y91YZGV8XXWH5-"J!Z$9C-;5X -M2A@:FF7-*>P_A]Y%#MEDG20]C'.AS -M\J:3^Y>_EG=]7`*[Z)*#-GXV`%;%7609J(+8;V=-,UG?K;S*A^*BENWK3TYQ -MT=*RC19Z6!KJ3*(9<[J44[Y*G!#]0,3>N\I/GB/(1$V285XZ[)`C`/Z:(:F\4@S7IY]9`L) -M>+B)6>O2@\%\V.VWU^EO-Y6OLCZ4NVK@V8@YYS=C5>1L^([\HP5F=3^2L/?1`)%:)JO]<8[;HT]Q+*!L%0*KGM:'V6;SFBWR8IIYGCIO3_$%8 -M5K\"4Q1>]MZ1)KT!1"OO(3K1%J=/Q-C06%,?Q-/YUS$'+)/)_#-"A9_;5:#7 -MOV940JP$9^3,X+2D/#1QJS]_#P.K!$AE?%75,-=%?R5J!][[0=\;`Q5-MD=' -MD.`%5[AT(ON$F'JI>`-J8CINB.06(,+?6C2(F,B+N!J^X9Z)0;[%FKV^S3Q\ -MU7%^Z4P9_+6L\L'G/"3*$#$F"/:QT"9&%&?%?U]NK$.7J3_IUUL>9C*])47_ -M>`T5G`"C4DZ_69`0PRK_0)M0R]%36$XMV:SG[\\VU2A.0Y*R),1E6'K'_E"% -MZE[:^6<>GX/LQSA8)3!6V/MC1.:N_G<*37H$J&)61448P*@.L?]0[>/H811$ -M=:14[H/`8-9F*"\.1?S)H0D;U>`KL1#T$_Z2L&$LZC?G\Y$#R@Z??EL,M=_I -M-+F5A+R;IV`W2A8+V2$=R']"T7J9.21*OXKE7>UXST55*R*47*5!B],8DQ!*8!K2%K>%.HJ/H^*@318R),_^* -MGMW?PQK_J>-I<\4#WTUBS1=:,R\*<14140(UVBWR."(ZIKC=91KE,"[RO+>L -MV_(!1'.1"W?\SXVM"5A<=+WL!:THG"AU#"_+"6NV:1#V\^X3+ZF-74XWT49WD:L*T?$703$J -M9W@+^<7I-H7^%0./B4Q:FMS`YI./G5F(<#S:M^S0/$!M59AF6IVGC[GHP0@/ -MQ$9^JTAKN:")Q'2!5@<`9L9F.=I3.N(X[LU^=2^?B:03L\#2(X@9DCAO]%X4 -MF$;&-?I-J-Q6D5??]?):[?U_H=;HPI[?.1C0L4DB+BW'I=(\@Y&!HW,H&KY[ -M0-K5K#[&F9XQW;M[[,O?[O+DVER1MNGGHMX2[CM$2+%1#T%/8^=-;@DU@&#U -M]D2?*D+?,6EE<0.GMG-1VJS4)F::] -M@W$Q_+Y&(4&)57F3(04#^'+?$>6<-8&5G%H1<#+5T;Y1*BMKEG^;0FC:N[TZ -M0H.`B@$BF`6=I?F\6(W#[&WYRW4KE_E$2-$WR#DJ71-$/))/S-T3!%%D1A=? -M!X&M0!>B%8Q.'0Q5R.^CPC`CW%PF!=QCM_^@>'J[W-)P],2[^2F]NK^Z-N)' -M:4ZVA-H3-/6Y#K'[;A5:!RC%'3EY:,:,,]$UTAH(L&A[T_@([1$.#IXS>P^& -M!C1$&^W]?QC4@?L3^:?XHF8[3=F-S`V.NII<,J=L@)/G>HP*F,"[Y:M_H@^Q -M;8;O&DBQTM2DCK59HPSJ_I&`"?*YE=^W%\H07@`BIG7VY,;9]:1N:=[ILT6C -M61D.E866$C`NAI,61C@9IO&P-(XH[;8$X]>N(K\+0-$*@8;$\^CI1/_!NU+, -MZZ3B4+/5B7PP4^L\8(.],6@XTV`Q@';BY@2%'8"FB_?/ -MAIR)):L-DL0[Q#3ORN+.(T!,L\Z0)94XEH&AH=I*E;X?TIGF#[@A%"VB)I/M -MY#():Y<8XW`X>^QH!B=A#5.B%8FY!F55@PZY`G>D7.,>3HFD]M0?ZN"2)%L9 -M[4S:=Y[^,#.TB'DPK^:ZZL,Y!:!.R(87-TFID5ZQM<9&H6$K@F?ER7Q7"1!] -M'8!SX_JE&ROTSQ">+-:CE!O)"HV"?OPP3FX;^%E7,KOK:S(*M555.(DFG.F) -MFC8?C`LI[R"5*6^-^^-'?V$_BA5?\`P1-:%W]GJSV3<.CQ83$,0!!=U3CX=K -M.;2,D537P\X@B/8?M?,,J:_@P7FT;@L^UTTM_#9U,^WYUA)VOX?5!GO4[.2P -M>C)>B67SDJ\,HE]3%H&$9%U6F$M\,SU5%3=J'*H8_@%8X7VUHSIJS(2#F"+. -M'$T=Y)Z*G2V7'ARBWD!#92\3O=_T9I"?THNG:C8*>LZ3:K1,#RZKIJ1M5(HM`K39,+,&289@TZ;X(KIFE9L_5 -M^P5Y(:]'89[U)SWWKM07,@%^UB)2+V'6SRSO4O_)1.>V5,!E"-&@>'^UVPX$ -M=U;)PP.V-%IN;CSG6:]JZK.5[,C)5RUQ%X$O2@Z1@2@($&NH!81"3$KTUJR7 -MRUIJC]."[10P\6^-SF8A2]1^AKK$N],,$?+Y%Q;@)X?)*"?!/K:PIOS;(W&P -M^E?VG`00;7=K[LVQHT70?#U]0`+%SEP[?(KW[Z^\W`DQ(J7!WT!XL&8O*49= -MZV#"V0840CJWQT+W:J@^";,UP^@R^>\`,A6?<4ZWUHP-(-CO)#VNNB-3&\\DT``F@ -MC&`]T#,*N@XI?7K)!`_Y@#U3'G)IO(MXJV'BXM\TAP?_A*-I<"(0_9^^^6[O -MVN;F2!=&1"Q(F!K(%C))\:#EIZFUQ1:'5CD-)!D'K@X]?O!5P8]JR-:Q$N*[ -MJM?Q(ZO/1&Y#(H`SFOT[HCZ>3A.74167ZS*/F&"@>7U19C\%R=A9WRHRA$$; -M^UEE3X3FKDPI)O+DGLW;52S!/(%A?U03BC4HGA8#@XL2%RB=NZS.E(#2-*S\ -MN1UIV=%4\83+;UP-C8DY"#T2@3X.(\)%S\VJT)F(BTRTFRTD-'_3A8/6/X:7 -MN0C%$8@RZP0*$LZEEKB$A)F_RU3V`@%4Z]CN5'32(HLRMU@%A,S.3[ZMJ*/Y -M/`J13R-770\95U6G+MRE:83?LV?14/_&^4)TV"76JI]NL=^44A[36=OF_X(E"YL(A@_,4U0\9O@#[ -M2,(O9C!-%QCI*2D^]+Y?LSF5UK`:N*O1(2Y3U\I[OH#:B<5TOX51=N][]]H" -M^J46*;M]]GI@LAWR`K1#QI*.,%ZBW4K=KK4M47[`\O$[?VE!]/2@^&-Y9V&+ -M6%Q@J!W%10(H@1$U/6V+$S]="N$D5ZZW-Y"OR:=[WO1;CX;W$6LV2)]))(>RT]L.EG`Z$;GK&NCA^A!@'" -M2HTB#('QGL;^9E>O!#AATFM:]U*C.`M;C$M1^8<'%Z^)M-ZW,JZ(G+4_))]X99MWE4AYM$+OKHE$HM:#^#:$-O$?Y-I -M8-`E9Q0>YE/;IJK?0];('$UVM\(H\Y[G9:W42MU`P.3`6TU[Q"8J(,Y)E(Y* -MB(>-B`LE'U<\RTS`-%81G>[$7(),[6RV+%9M]"2T??TH_;CWI3M%(K,32Q*;E1OY,=9>0:5>/[(PCXFU`+)]XN.P(.@(6Z1 -MQ$:TFE#;9D$>4SJ9>B=YOR9\BU`X,5($ACI5KZ5ZNRX7YH;=.W@JH%NT[_<" -MGC<7V$NU=\1\;X=W*6`;&=*OELI6HNENA$,KY7D2A='W+DV!.=>%]/U$B7,0 -M7O.-,_WOD`S2,`_B'CU`::/5/1J]6BE6H\9>PU(YAE>I8/2].6AL#JQQB=:( -MQVCQV1IVB_Z3O6G_?.@G&7J]/EBU1$J.$T>5?MNX\H,*%;KK=JP;:Y6=G2N= -M^B$@7V1Y8W],MW8O-W<_"XC[>O8LYW1B-^P\'PTYS8@)1-;OTZ=)5;[&K@EP -MOT$0E_+8>S%G)22DO(C3=>1U:%A\BN6VWQZ.X(SK2K>^N2**I*12>>?C3OI$-@)IKOJ#`?YHTUL#T\$_?$4G>OC7#MPN^' -M8S'0`=1:ZB@!:?_[L/&01V4;;Z)]89.9(K8CWJY=/B!/U;+%`PZ5:*Z0V7YA -ME4#0ABUL*OL.Y?M9A%!-`X&M<8GQ`;&2JH"26MB^$5]5(67@2U,L7'`C*19X -M'3GY*+P5C`@>YKH]$Z/O&EHBM>/MY*5I^#.M;^\G=]*O5,ZT5*2-ZXFMXYYZ -M[#=J)(4QE9$]E&4P73MDZXJ32,J`SZS`?K=4_KD?+:HN^CG<&D] -MF%PP(@L`_.M(!L5Y%7_*I+X2%U33?"IF)I!BQAZA>B,0265TMEF?&,F(\O_B -M!)ZHA8KV7VT:Y@4=-_O24+PPQ;.=8?U=*J-5(VF'%R1IE=`_TM`6BIFFBU&K -MR[_K0N2,023[3`Y0.KIR49VI&;6'5?@RG?7AHYG9PK[V9^]6HX"(10`0JQG_ -M0I8@/X#C50*L6V9$;"INV*5:W]`W5[JAL"N860TOA%EX"YP"?T(FOU^&_[SW -M#.+7N25O:.*AK&;"S28=2""`K5]@9"I<<.:)>S$Y`6R6((&=!T&+QTTJSI7O -MI\H]I367$!PF15:C[EX=[+@NB?66"`F,H"5P['&[Z*GP;V5QD\1,JALL/\Z0 -MX.2P]4Y,9(_]S9.7;L41\P_F/RY;W3@=O?IH"DMBD^C;'!A1S.'J/;E""V=P -M,40`5/A-$$)IF9E/SC(GP/E<Z0F&G+D=M7W:F(=V1D$Y:7*(Z`,'5J#593&\M -MX<@[#[`KLO"SSQ3'IZIC_A$&=('VN_D5C+E&:?E\3ECIAS"[40`&89VU'W(: -MD>H8M%JC1G%M-DYI[__`SCXE)NGQ(GJ`APRYZ))D#,LO9KC>K-$`F2E%`04% -M?QI@=*?6?8&Z%`=`2!A2X8+[[^;=BY*C/"AF5PUK- -M;Y8"^&G]%<.0<[]/WXY+4"WRNUJ63G6*G>0N=*F("(X.#6\*'$_W^XJ./=D2 -MH?QIE@,DT^0)[1U?O#=<'L',JN)U/4(U"\C/G*^^=!W(:V&BWF< -M+"X:_0D+); -M,@K",:N,]T7OG)805[R#EPWBQEBM0II(2M%R#`'&]64'+3FO_=\Y5G0'=_F` -MVK47"R_Q`+V:+8?MQ+8$_@*_JD&^O^7X*;;^S8K?PA9HPW_<%"=:-60[J+FJ -MO*=N2HOW9YBZ7T"?F.9'>"]=7PYY&9LI@H-*%9=6W7KZVKUG:-/ZB;.D_6L)WDBU;)@D/M1DL2K5\[Q_G%#>/TC>/<4"_NN/MV-WZ -MB74J/%0?L3AWSAW5"6L2EV:?U!Y@;TI;IC+>7)&;8JAWIP*'<00,+P__LJ!D -M^]VP*0IQ[]H+EIL]8;EF#UROM.X#!7C/@!!B=0#`G`$KDZ3(I*,6EH7:O[WW -M89F[4TX_0R;0)"_3IM[",UQ9RK'CHP?!V(Z#%4I"6S)5"K?Z[(6O4#)13/J% -ME#4B:3S(Z)3-Q"MV-[+T`5``@[7>]51_Z^%P99)34LFEWW4&`HP111VQ2,*A -MGCK-.EED`ZP6R&U'HL[[:+#%SO#*^&K1.2XU,]\DL&%DT01_*A8\N@4]WH`7 -M*NDY=AH\TWCZ1M?Q976%`9EASK`O_4MWDBH^6:<&$3JM#:3B -M1OMYH33U$-8#4A>DW)@<11ZB4$Y*\*,_'AE\_IYN4BE%2XL1@1=K`X7?Y6"'E'RU71^FAAE -M@5IAQ7<>;D=C_Q\E"L`([SKF'#J`D0$J($B;)Y'"X3YG[LWI3??B(4G.IB'# -M"-0P83ESCAD+I*42OZ'LUM>>((_M[6$@W<>S-N*"K*HP**5\%.]+#&W>V_J+ -MU=RCOMJHR-%Z;,^J91=PMQPF?TA'73DA\&,$SMRP'QYXBJ=`OPF__2PM#0SD -MR^ZX[`#8U]_Q9MLX[C"^AHI4'?NT^(\J1AZF3[]9H,ESIN1>?I=@I2!P9 -MLK81J$`1O7US!:8[8!8ZT8F,"&(;&YVGLH#81)$\:4<*%M_X\I^ -MPO']L/)585./IJD_S5H(PQU]`-T;Y>L*D.$7<#?^_A%*I']XG[(1>)V-;4,GLF,"^UE#Y>JA'S0B!;6>16+\C:_]4*)W4N&Q -MHW9GI*S[Z(1D7F?Z/WU@K*+$DL;07-S2,D7PKC>X$(XQ"CP\M!3/KSLJ,T+G -M"9.!-7OD[376(9LV%"^S+'P,P1\S>[/K#]:#E&4)O^#CT@[T=U\0%3=IY)V$ -MKOGK+:+,:47;ZBS^"Y&FD6X*`VM;+0&\P=!'M[5R2YW_EU46#J3C<)-E`]AE -M5Y#H1<7`S^R9_^Q#D]B#Q\B0G&H=&FPDLTSC[;U(KV#6A-!Y>CT""M#7/']7 -MR?F%1"%GZ\.K*$(.W(QDR3+RJ:\A9UT'+";CW0]QI%?4_N:D\1G%OCYB-A\> -M';1\?4!Q!!4I.[2-];'@^LVYIBE%VI4^*98?XCG@I>LVOQI"X:*:4[=?*;0J -M$1^P04[^>?[(F?:]X7ZS`FE=&3_9;]__ -M7?EEWF/%E"W"BSEE2XR&[,#2"R?$A)-H.,@E17<(0)]!O8B -MNFKU:PD;M$MT<]RJ)4\:!]]K7:Q`H&R?D9V"O+)[E^ -MVP[L%&I3^5O]7Y)_B8EXDEK9O./ERX^]_`&Y.049[*"TH3"K;_/4\Y0?JH/: -M3JX\OS-G9PNA&#$T]TLMS;1Q!78W0U$/=L^>_';DP5LU(K)7O$2['N))F_9. -M^\5+DV?(8YSW8UHI`A="#V,P_XRS85W6BG<4BP,C#7/*7S7'4VX`HWAZBOR`\=U#=_$ -M:MHDX*%.;D(H"LUL_OG[(CY -MMK./LNW@/BW>DMY\2!M^HT2[434&VLQX]I%#2'D0;APZ.)I76T>JGHNO[V6I -M9^PZM$O*^%IWRA/IY>`0TGJ(X".`0YIJ35N>UV,?3V#@F+?K&1H]^7W0D&/X -M(P03O2GKHN$*N,L!0]'T3"Z6WHHK$<'2%?-?`WP/!EUC(81O8)ZRDJ=_(KE: -M@($*#;T\Z7,_CUN#Q@:<$+;BI5_71*9>@?(!J?=O2R(C#8M4*-#=6Q?EG@7Q -M(K]98J@*-J+)@+LDL^U?(!8PI9;A`W;8!\IB]FVD'5"47,.L_A5FVFI!RD8G -M=E!+#:FOIXB=TH&7:17#_^`_74W@:F"S&AOD\U?AH"]*`"91$`\*-Y:QN'2( -M>15G0S4T*)=R307_+#?/[OXC$JE#3Z?Y9MJOL`?S!8&BA9E[Z^'$4K90,9QX=3D%STDJ[@VYQ4QQ&,OL87'>3<"(J%?O;Q[)1O-,P':=FHG"S)UCZ6+I!/EYAYAL5(G3U&, -M#GG%1]UW]%1?^&[6:/XMCND&(5]JQK=&"DI(_!G9OOTFTBR,_N=:Q7A"3J). -M3/:&^POJ=9P?-O9:5:V:>5>PAHNY\26-C5P0=48C -M7>4V=Q?KU'Y7P"2!WUD6" -MF-`#]O=I\?Y!T%#.03..LC<_J]FE!2LMPB5?BBNC^P,)KQX\`VJ>70IJ'UF+ -M-Q`?(F^M9I$CB#NW]B8K`O$-Q!.:8!A)T<(84#K8BZQ%J'J.C+VL%>9[7B/; -M-GR@(M2;=QZ5#]\I$)`ZKH[^0+6)Y6,LI08Q(NAIC!J! -M0PQ2Q!,NH\N,Q4E'W8]COHE94NG[LTB6.L-`CD="09 -MA`]AAY&.V_W$H'^!U]\8:Y"EIOZ'GY/[@K:0])SD9N)&Z;@NR4S;F$$R3C(N -M8<,G`[5Q^8J#T&K^,&T_X8TRI#81_9\CT6M^)`E$@5T$HM+?F'Q^-I570P2G -MJT]C!4K9C%XMX485?XN*EE"C5ADMY#CF^Y"[X6/=XY.!%V3C>*2N%&5C$.\K -M4UCAV47(?:SDC9JT=,#&0`3HHBG5]M;\6'NDB*2S94M?#\@)J)R=.TZF((:1 -M;'!/8$I=;..:3"0J;(*7+>M".Z)\,Q!1FST`*K+?,[4L<5I0BX5'U1>R6TC_[Z67 -MM$-,@^T%J]D\8^77#TVK.ETDV"L96)8)?'SZ:?WOPO,FQI&5@O`RXPV'/N#^ -M@!B_I./$H1HVX,)-6>SDX-$1Q]/5P=?>PA7NI*Y_A%)KJM&%9T'^*<+6,1-K -MR,6>68<6Z.;M@@]8*5LW(6MBLW-VMD' -ME&I&2B#/&06G,V]9>6=J%Q7Z3!YQ\DE:EFS>U3TV'CLB)0HK+&9AM9E5Y -MBLA13U?1OI(%E@WL.]C\\CEAZ@OW2X%"2JUST($^F;N17WF.DOS[Z3YY`GJ$?[_WX(/V(4O -MZ^#X+++A@2`SK318[9>(EN*GV*:0`O#MS`C>;Z+55!R25ML?ZS"3.I-FEM?\ -M@F',VZ'8S68V[UA_C)>2L`7\0+GM@K-\LBAE@YXHR$".,I>L"WK8'A(A?SHV -M-'J0/T(1T\9.8HJFDH2=,A(,PFYS?V#SY0AKY^D4;!OM5]$'O8",&\>;$+,Y -M<>T]J@@XBSV<="!HY+'$A0[N&I=^FXKM(3_J!-24SVEVI7LR%]3)A%+VGL!] -M(52`=6XPB@SX>PG6PBQ^FH;(Y3/.PYLNC3%DN -MV=]'+PLWY,A9`"$\U[;^N@U&5GBMMQ,U-.L1Z@7:"AJPWI6>HRYS:N3V3.IM -M;%&+#'N55,5GO,YY?X"VHNJ(P]X_#C($"IACY]"M%FL0W:L"[I2&$E&:9('F -M0EQ!12!B?U,]/8"32_9D1:CBA5$"H?+XY=PWZ0?#$M?L6"W3!-53#I7/8">V -MJ8^I$\OG`/.CL?E8V]9J9Y*,LAC6OVI0=XI"0SC!-7=HWONH-'TLG'!"_6Q+ -M\\4$,G`04(S\KQ(#:4E4I(-5[O7S_>38SDC3'R$3N/@;XK1J3EF@4MSF7-N1 -M-J@B^72/"YQ&H.97U2]AAB#8JLB^/&2Y"O^1?6KI1FI.,=#/K:S,#U=VI%?M -M^V2<8RUUM?-"Q!6/N8,.6J+K_)V7:0]^Q:N<]1,YBM'^(\B]H4-F=R.XFG?89/ -M)9]M6H\;[NFPYKDB^BY5^Q. -M((O%U_GG`\2N?AZ]9-(=GM!E(OLV_$6#TCN8._,>"HE`W"%W>..-19&`@2YL -M:QX582'(R*_1G7<>LSC[/Z.R1<=QT[?(X9QJ(E!D4,Y6K/,]OB>7 -M'B.I.JT8)!PN-2Z!;C<"4OB*NUFG)^P\U[JL`*'H[._5$K3%:".M"S%F5"M#ZCC0TICQW,,R$\%C/NMEX%N6:9J2 -M5<58V:U4.G*OG5FJ^Q`O"U6!^<,O\U`TWGE?NDZJW7;=[.P6YUD<]7.O]8)EG6, -M[-"TF5]RR&==",_JJ*=L@S;\Z>`7BC;C-;)L4V:@K\43[Y_A0H=VSF?U -M7X&?2+7KKIK3HV]B:5&G:]#C9%PT*0,!=N8W0"9YU;F0_%O@^Q\E<`(W_K\K -M<-:ZD<#@U#JVK:.S685C2+E!+^SN^1+XQP6T+,8I`*\-2-!7]!@`=P0ZWIU^ -M](R'B,'01?R!BN-Q.*02ODD@?ZZ7Y*\I>'J!T/#]39-KIA@H"WC^7M!M_B:' -M8S:B667OZN(WK6'=(X9BAUAU\,6;^@RLF9,&W[3U_5"6]MVSWBE'*?YH:@TR -M:@PPV%E3Q][E4[O1R;@A*C4:>QMT,GG2E%*XW'&(^2V)O>>ZQ1EPN;93P@J6 -M7K3Y*QNI^6(M7]C_E<.PJ=D&&HVE(5=G38&XWKV_P-!(C>!YV2H#;]42#!'= -M@$$4;`(5*\ZOO[=!&C,T)`4Q^S#=33)D"R?O3,SM=+9*@H.7$UM5?D1(IU(* -MMQBOF,]P-LS,&TDZ,Z`#27=&4=IP9:Z``^A"ARVUQE[G(7-XG=H -M\R3&%R#OZ#U> -ME7`P=*OME9"U;XG>O]"F>KUL'6B3./[_-C)&D;0`C`41>0QB1_-YC4EYQ?/Q -MN\JV@+,<*``J]).BI`@"'#LH3%RGWOU@HU19Q%V'7[$U'X4$XJQU.320=AJS@.Z6?E\X@ZZUX9`9]6 -M65$_7ZX?R_94M%V\^%V)8JQ8)(OAN$T\Q_8\[Q.E`YNY/$NG=FS0"A:BL$"\ -MYWSO;X[SU(-RM_L;1C1Y06`+4]ZL2V`=D?]$GOA%U#'$Q#S91"X_CV[;G__#-ZM -M(?:KAQ02#2WYA(ZY/ZO1+IV8)MH)^_OF<0/OFAZR!SDLY:9,"J49CX!QA -M#_'I3(W`@T6Y3:*L[5A_7F!.!J"`5GWW*_1LI@.*9(TDF_(*;J._.@1W> -MIM7=I691?#&'"=JKQI=AAYM\YB5AX!FOW!?M:AG9[YW03D%61`AF?N_NW#F( -MN(`_)'Q6B1K/CB29]N-,*?YFTJ8,RSLI)V<""J;S2:A! -M"]3>'W8R:(@0<'*0@T&+(0?D\>+$L$7-.]4Y5(J,]N[1HI.%R/Z_D:2_;V@$ -M2P,2T?VZ8-3R$R_8X!$WYVI^SA@+P2+-NUB"_RM5:?C:CFJBCZ`WF!%[1?(A -M8%TQ4NU_2:"D=X#=8V"]7R%MD$Q:7I3U1Z)*^%5(V3NV1HQQF3?W(^@-FS'3 -ME'K0;8/9.8N,J3INXE/Y]1HYAOAGLDU@>-*:MJYZR&0292IE07$LKLR9+UHT -M:22B\4/%)>,WK`M#F)/E:5S8$PP8@Q9N=:N5@*OT442?TY#$6GWK`R=59.Q3 -MF%YI4HFHBQRN!(??&^.&ZT[1I49'D66"CU(YN'"!YKX_C4\)_+)<.%3)W/TA -MI-T+/TSQ[E(MS=42/VJ+#EA4`VN-04^^EJA/V[[\7!RS4]2<$I'&3[`#'5K(+IP0[!4%];<7 -M4@`VA:@P*+5CI'(BQV";AL*4!1[J5JL]0"Y?P;?;<15WP2XGP%.?W7@\T!4R -M@4"K?`&(O`]PL.`]VP7_IVAN$08FF&W"R7S,@5LVD"F6(#A!0EV9ZD-:CR-; -M_6=T;`=E(EF9K/G_T%//*=PX48VP(3K/TKL7!CS3)&@S36]:KUP-JD1.`QGE -MZWL9<3K&5%\U9FP@4XV/)WR2H;QN26Q:=U0T?XE9C,U8_UF$M`6SCOY]^VY. -MYB)UZH;!2)=R<`TH.X-K6YJ=NA9/%^`$)]+)Y#MM,QV*3T%5D=-V+[O) -MK@*=6NSAB2F/L&8ZP:P.<(IG6Q&TW>[KS(@1,^I(&<5N>,WGYMR>WP&#^GI& -MSZD"?3^OG'DK^T^0A584G>^Q;RDIHOR*P*?:?R\44$NMB9E@J]Y.BT7\V"@2 -M]<8;SE]3"$!1?1^5;,TAZG0R7HD/F,U>BXS$R'SM%N&[OU`"@,U39R^I;K32 -M%>4TV\&<``>@RPN!VDS;V -M>K_[?N>4FN8.DS?3WK8)OEF'KETCQ1=\9@O_GJ&@GR5+:).OAK+"5`Q^=&.M -M"J_%L@:6SS:\@GN&W]T`+R^7!.QBD4D58\8A!71*,:16:]K^@$M%I4WP8R_; -MMW!1:F;[,\1)(-MCZN!YKKGNN_3Q)=?4X>-ZXSJ]UD\7P0WN)%,*4(ZE;"[[ -MPA.)5IBWQ";V2#*X2^AO3W2GKH'=YU$$NAP.QP&WY6W^`6>8MVP#3L];T6F\ -M7/T4)KR5L.TINCES":G/^#$VB+<[N9FI"=-Q0A6AMX$#6;F06I+ZH`*7&)CU -ML2V*0[%A]IBKUM85@;G;2.6=\0N=#DW,\-ZZC.G7L`,O&61F[`!A9->)ZY9R -M@T_-/"O=ELL=C_-L)5B#H30Q<_433V61V>BR+[/X]%R>YSCI"PC8EBFD<4]; -MZR#B?*PPQKTD*B[2SKTA?+7^U^@T+]':MKOW_2)1<%*7WAF><4JV@8,.0PK_ -MX=J!E]5KW<-P_3/>$:P?79DQC02VJ.!S^A+@KIY77BB(,(JPEPP`[]*0*FI^T]:)9R^W^$13:N(,B8,("R&E)NU0R@+09;C_R -M>+%?@4$G%1!WTW<%JG&==$E.@CPBQ>+==H"[*W:0*/0NU:5?>X!CAE!Q@LOP -M7IV0OC%TFF`EI.R:=#ET!ND[^Z[28AY6,"WNH[V7UYVM!'^X\SNZQ:M_H+)] -MENLBE9L_1O4!G6Y6G;A,'"Q#7O0TC4TVPCQ1#9<)JO7%6WJ&0#5Q4[I%8:QA -MK:GAF'#0SUP+,(;W9E0]>V%*@?%JA`L82P_$U@W0ZF*UE6'&(8_U.`Z.E10: -M.C'.NTX^OL^ZE,]9'X&%N3(VXA*F%4./L#*2TJJUO"GG6CYU[*1J+\&$A8;& -MQXQ?2Y)+1FY40]`@;/FLLF.GD[KX!CKTG*@B@F>]?UCBZ2+8'R&T>K->^:';#?J"),<_:";@^.N?]$!SJT4&.)EZ>.1$*ER#J@%)-5\L -MS^NG>OFBEQVE\<,TFL;<3/PDQ0-(_%1__`M]#.6P\>W\=FLL0;QCM>M;>H.V -MJ1U\LC=D_<'4&?XC4/!H&XY;%TDZ;>(F;7/\6[B.HT+7[^N%SJ!/DAYF1]21 -MY%/2X=JI@B,OYI1EE7J05F0^ED"D+EQF-@95VT5C_XN2G8D3N3-R\KN1=:+P -M+SG%QM1WHN&KC&JU(/C*`X+)(58.A&W"P/ -MJ3"!2`II]-)HPY\Q:;Y5F1XV$A79/A3#SL^)[#)8,S^&'$80W6'"MYU4)#A*I\S2/;\J[]`7.46=/QJO69,3[`*D-7K+2_[U)< -M:]M9S7KDARLT/((6N37[,YK1Z90*BEWBOCJ89[7.%8K?$2Z37%: -ME(H_QHB:/7U-E.">?+!7>RAR&,@PW,P`/]AZL]R*:9T2B0&2?FUT=V%QQ6=& -MJJE)Y@!W&``;,@U[TR!O#Y<7F0.H?NT75E"6/J[>5J^#5SM]URSW/U%9+'52M,B9_E -M5W*/Z+!-5_/3T$GGN=S76?).``FRQZU -M9+>9KW)'QQ3C1(CR/P2CAE;VX&W!?RF8=0$ -MYZJ(L!HSI;R#G=R.KR!ZT]!-\#<%/G+E_J?48L\R')@@*PYI%@FHU$7WQDZ0 -MD,>&=P3WI1C"62!\1M3HRPW(NMQ> -MJE]]M=-VY+S,S(!4+&9+\6`@AX+7'VTX\PP%@\F4G41M1OP/*%=;K,:IGQZY -MN],ZNV'OTVV6U\'0WKK#O -MQY$*S,"ID8HG5K%W-."?/8!H%)[/X*=L;Y"K -M3_"XB97(QYDO5K4=<@Q`0SO0S$KWW>1GR/8J))LTPZQ:E;H904YX*]Q54DQ4 -M>/%?DW/E8@R)W?7NIDJO\R:OZLU$'X\?[JE9-2 -M[#X!+7/?83H-N(*%;M>*'HK??3?*#8W-;Q1DEK9"D!8/.JUN+A%\7*OXD.&6 -MEJ??DXH8N&A#5Q4O)/F0@"@0)<#>E#M*L0R#5<>__PZM&4[@!CNGERNY--GE -M9&]`PD.\9B%^[_2.(9;]P.`0C=&6?\3[>!5&C<%2^T2S9U"1^1%?[/*1%0O9 -MO]UVT.Z^Z800_@![O#N(R7VE(ML7;U6/0^8`OTM2*'KD(0*U+JC-G*/VQ[.^ -M&G/4DZ)8N:/K];TXM;#$4\%QOIVPF9PT3GH)7@=C<&_E_8;,3*K<6MSV:U5]QJ!9 -M>9]=_3NI&P10=)8SQY_-`G7`S+RN"#\R]^S`^P"O3HV[IQ]%-_X -MK'.O%GT/A;PGT'G\1);#"5G642[#T)KBO(OYI?2;:@ -M17@(:4CX?>$GJCJ5S?Z!U./O9REKM""*G\5:H;OE&+C4<5572P:GIVRT2.#6 -M]N]P=,2")B3^U$_7WQIH.2`4K7;EQ?QSP`^9-&7N$"62@?+ZC4@:/H'F/;C8 -M=;Z_DE`6M!*2\CG",_QQ.5![]VTQF(`66%LDV#GEPBBO4E7A#"8=J/\*Z>V( -MBGJ,MFJ1)7P1O)P5#".Q:"V58X!6O\[>M9(;92JOBCF?=.I%XH3$6I=02R)6 -M.#Q5:IR@2:BNLAE\R%5RE]3?"TW^8_:9`S-NB5-O&D.)[_PG_=PI,A;TL4A- -M-Z;G/0[NQO#5$&\HC@*&.YVWD(+*G6#E`G")5F@)U;#1*#"2*ULHTR*`TALPJ,@=NVWQ&L,7G -MY]9Y-BK&8D:&QBMJ`==A&2!ID*]]>&K<_^A:KCP96(O9TB2Q(/*,^U!D(0$:+BT]G%&BSN2R# -M%PF/R)LWM:4M\PST%F6A#F).92%^OC8T+ -M,GR*%U@R9J?^3__H2)53V-4!%0QFF6DR;?\M@:FBG]>C0"N0[*KPZ3;7R)R` -M[X5S>-8/5`NS*`B/_C,D8,VB"N=W&!Z45/6HJ_+V8\FHR;B&Q.==8&D:M+]1 -M^9>'2XDW,)W"9::<:X%9$(XA=:0#7%QG&L2>NNFIGKWR,@N^AS6J5M:+=]9= -MG>D!$/:19ZY2/"?GY87BLD`:C<_HE.Q0?+1(JL86:,559?AZ/KPW3??F;P0Z -M`3)@6Z5'^WDV&<"SHQF3;#\EHMV'$0JT.W@C:.CJ*J446<6GK5V=1^4>.+3^ -MSZ5_S!BF=+YX"W<186L9O!DW@TQ``^B!U[K0C\;Q1Y:`K@/1D\QJ:?QI3*V. -M!0,Z6"&[;E3S.GDBA;*O)@_/@`;D9\*8(.%5R*ZU0`[;4K+8C\`)XB(,:M]%4XP`W_4=\@M0I.]E"X7>_:/SJB2FO%!&=9IUTZ')$;J8[0T_3()UT8/,V'?+%VRA]QJI8^= -M`:]C,$7_UF^6\MD<]$:1Z[ZVX`+;C,)%A#V>7+3!C=DT=-7>1F\3=^S"+J73 -M`\P/]$=C_@R!&I3B@S7WGD:VLR8/9&?I2M$D\KI\52"@@IK)\,"N)BYAM`=P -MAUVA43Y5E8,UC)G,95YV37?Q:Z!CAH@J3MDHSM;@5BI.@6&/$L&I?FYL]8^R -M`A5+OR365T$<)243A%IYD9<>?]\37AMA2?2$?,H#@.4&^8_YO<$W%`[=E&T( -MFP:/@F_*^R[+@6&T&%+MHNEB3W!#_W,UF7-=H`!/OHIYXC5!A!"(,G`U`0%D -MGE6L_CDV;>,*HWZRANCE?W[ZOJZFCS"ZZQN()%R%LUBQK$P!U>F24\DXK-Z! -MT!,JNN6SJ?L8_BR+9%\A.C:3*))2*]R!O'J).^M]J[PH@V+EO)X0S*Y8T7=O -MT%)W%PWQ2OW$:7WR;Y,A&^]#`;T[WR:>*W>B2.C^SRMTP`HTU@*'0GN4RK^^ -M_;N40E8$&<&\'2GO%KB8-ZPG\>>)JF)Q?1YUD>L43N\.Z6Z-86J[4['-SA#C -M?HT.Z]#LU]B1"\Q8!_`1J!*]\!199LXW2,`IZ(_SE!$NU\Q+_X)8#U#)M(YS -MA3NDN.G__CNVVZJMVNQL/J^'/7RO=:9AM^6IM#0,J-_Y.;RO(YX[N&WRCV-6 -MZY<\$8:,%FB`P7M95M/Y1'PI):P&9W,5JKF.(2QU3SLNYX<<[+ZFP>,>_YAO -M&`J9));U+Q@>_-4`G=$68X>G(;IYXWD)86+.*W;`CW/7SKKI/54"8=ZT -MRX$^/Z<.'"BC5M]HKXPD+G(ZY6K>39C>^KFNSASOZV>GT9I>S-KRK8B6&8)_ -MV4_*MLG21XWSZPJX62[ILV'NFD;(-F(.]P419?+?P&@*W3U?O";QO:3ZS`#Z -M\`C%$<\KCMEU7X\TLE%S/[N;$\#[Q'.*9DK?Q\O3?<2N,FP>9^W).SM]^&O;I^C<&'!:32_P4RB#`/#K=;%6E]K%I'3B560!]GMI9B -MR-YOO^W\%JMM&X^I!JLCW^H< -M98+=U"&O_705JY+7P09+[J61C*\PJR-0A'H]PHDB`7 -M*2[,*H)FT[!+=6#J%^J8<2AQCM#80SKHHQ)$'PY[:X'EK.<9[&]=)G_-PS@1 -M@.;W3EU.*)U9F]HK5B&;:[UKND1.FF([3>K:`5CF$-$<4 -M.[-ZZ$9-EQJ4=2KLD0_VYQ6(5DM>M7&M+RT\1J-CS5=%7A*?P`2=A6C*D[14 -MYD%OB5@`P/>5RD]9BKON]`,71?CV.MP?&JR4J:#.C?),FW"J#H6#>>KKOL$U -M^X*^`>EO)-1IA(_-R&#*:B_%(N4/N*(6DLA`_6@,I(E5F*9ZHG]0) -MB`\90'/6QE\K7\*79Z`TM;5\K5N%AJ.R;W -M40*-V\<)R172&T=KT"*VTO0.C1:S^?\Z"_6\'-K4",>+[ZM(?]!:R[U]O63* -MR/='G>*@`S),-@A)*_/=E![KWCE1(OCS;6/"`FWI^*2/'H3J7E-'CQ)2)QS^#3G6X?467A22%.5<&S]^AD[UL+ -M$CBT>FH;47:@X(,,U,L'UB763%'^+@7TH2;3ZDJW!4*=^O=S/-Q&L9TC>H;R -MYX]W"?D7`TB%FN)VCU+`16\7?;H?B/^`0V3]2\0MW_1D\"6334#T_D&D:(LZ -MR=3MXS=';!4')/3[B$?Q,%H5RQ=MT[^WJE-)N>QTG[JA?_/,JKZ?^@*V)3K8 -MY+YUD'9&=_%4H"&Q&E=S-.,,<1B5JJ9-KN0:[>$.&8U.L&]I:0B9"4[YK>-@ -M\9"J8GF0NM'<"KQM&0/ZN;(GM"X8=:\['(D'Z%G_U5QO][MZSP8[6M_ZELG>Q -MP93>$^A1-(&WM1<=[PZI^YOIA_$3OXF+#G-,Q -M?"6N1#<,2-X!:\L^*J4H"N4TL35-!$J!E)>5TKKG?^6/RE"IA3Z9W!60`T?1 -M^1VB=.I66%I@*S7'YQK(OFKYB_E/6W<1S`*%K^FN#D*X3D,I?\^GT_^[=XX\ -MAPX^[G-/\N:=P' -MYR>X&MO`0E,?\NKC(T)I.D1!];*Y%YY6_8#-`XII_4.:I$W^Z)@YS%[#;[I[ -ME'K/$_G`SQ69`50..AZK\0E3=O%0>='YH./M$D):7I8F6ZP.P]^[:M5+-4@^ -MIR?8.,G\+/RDM1:RA\BX=@\KT:*=>`%1VBZ'@6>!I9_IA;7$A[1^A210C9MP -M>1.''$WS7R62&`^,LYLE`6D/^5+-.%ZCXE1D/3U&4D4*0LXEP)1U*^QAA+?6 -MWC?XU;7\TQST+FQ.XL!4IJ<&1GUS/C-&'DL$2C<45,673.7A;ER4IF`L>>K9 -M*J\FW8(S;_KCE],X51H2O="/=]RL*@X=]Q3'&G%8!C1OIZI#NLY<-1V*IHC_ -MY.)`$_%\W;F?N-Q[L&\ZU?X00NS4Q3EX.IIC8@%][:/8_JZGEKF%*N):BFMI?<``<@CZ**91>2QT50Y_`R -MEN4G`+W.5\J4[^#),DX]W?H+QZHPJP#%Q(L^M/O;^"MKWN`D?W.; -M8\J$,#0DP&M6C+AX/@LD)32\(G -M7^)&SDJ"6E0G]M5V**1+9Q`4E!VL-@^928$?O]BV\?+^E#<@"./A6X+'+9"N -M>8CWE/)Y+U_R"K0N,;;=Z5K/5#YC$?J97]:NUL\W7I+@=X]$I&0D+Z& -M#[U1'.#B^0,SPA3?A3AY4*CM@DFX\B`^)O@I*9G`XXE(90[6GDT%+70O0+GMV8B5V+UR/Z5"P<)S(L3G)'F_[VV34R?YS7A(V"3 -MOWH[LF!@=_/*.L?\",7Y)8+;K-*7<#@)-ZK/"OT@*@EL'=1E"F/*+BQ=-:W^ -M3S+^(IQWW&0Q*K3`\DOJVCW9?GEX#9\IYIAYSYPFLNQ3PI,2B1*5VNPE&M[^ -MZ:!B92KP15K4+A2G&Q-!!ZNLW.MG1A]!Q^'%'=C`&7/A -M")-[,=Z0;;RU<03VE1RE#L"8CW4T*E0$V1ZKLB;N-6H`##?SF0+I21S(M-05 -M170*.R#7(`)IW.QR::Z!ZJ.NRL$_;X,_(DJZV=S=;B=L>*]VQ3T-%SLG)+O; -MP%]_4Y`WW$3PJDU!7`M[X2^1;]H"`1G+$8Q<6"@3H('6'2AR.JO@,0S:YA,` -M=*^7X#GPN@3AH0/43=7,[668IL_D]8N[(I@YD!*"A$!1S2:CRI[R*7#OZ8#+ -M#LS'B=.9%5&P(.RK_US83C*RJH!<>+QW*PM_F*GM?[^5M2>\X[AW% -M*((G(A1S2P=6$]T,&V*>#\]@$!E>>/Q$MKC]=/1\T<27*]L9)1+-_9:&GM1A -M5*>+;,#6WP(+[-/KV8]*`[TSH[^XU-1>OF -MY_@ADF.-$E+@TF'`(&.6DK"554?AXRT)KL^7:\2X<8D]QTD]J246'IH9X#[VZ1:))I#U9)WO#?K^M[&,5P(Q`?)@FQ!MQ/1L$R4E5BK1MOK5[!84?C3^?/ -M]+M,,\2B(#N9_"L#L*U\H!I?N%T_2G`.7AS'D\L8U!1'JTVB.5:E#>X44%9K -M7S%Y8.8T#F#(N@\PZDC6&\U'@G_3E[Y@?R;W9$9`_\,J(@_D-01>@!O;`3[J+R,`36[N+2W^],KM#/R4<)2.O6T/HB?W<9"/P -M@C`Z$0:8\,`4R$KK-DY;KN&-:PNL+I\)!EQ#4*2DW.%VS!T>^@Q3`VF-9^Q# -M9:D=8TNB$:FH_W<&.DR!1E_4YNP&GH5"(N-'+OCPQSWVQB4QKA>18Y(]F%XV -M;8#B7W2]#V@)-23%:C2I:?V$A;`.I:X0^Z2G&^M4K-AB".+=F1,M45-9`6-J -M/FN("WK\#(TK*NJEL6BB/2"+Z$A7(G)[YN]PQ_>??8'SB<$<7K7Q4/Z=+X#> -MT?F.@L@7B4[S*CD1P^RB]O^YL[`ZJDDXZOH;"8-FH4,UZKV[3TO9''.1,+53 -M\).N5=NBH;\)QXBGJGY!"S%5>026U^&DHFT9PZ$XUIY\S -M7<1$8YWG68Y>UDR(MA=]R/RWY\F_#R=5A"82G.$U!OM0_A]:E8&=CW&:#+FJY'BNR2L4Z^FD`H>DD_I]3:L6[G0R -M6P;U/L2EHW]3X`5SK4><20!F.;8PYIN;!H;R+,9_E>H8\PWPP3%([>5/97X/T`_NH94P";=#->G%4"L35HJ]21!WDSE#!.=?I -MYIH^[\@!/R'Z9XE`*+$6:6\,TRL/0$]^P0:JV]:;ER+R_!(NQYZ_18.0$WNK -MM_1;WQGM0,3]W0G&^]$C6BU'^<+H1>-;BSP/G$PGZV[;NWT0QW<(LLKN?Q/0;E+"&HWO,V_QIBM1Z1DYBS<& -MP0`MODJH,N7R#77LK6(&.>_'1'3/RL<_-P#P)7E8 -M`1!Z_!2'6UP8Y$;'%V`&^"RMKYADENK[WNQ++NXJD3"&$.M;SL']IF=.!5-0 -M5A+9]A(:*H'0YM`(&>?-@6HEJ(91:%I"(#D6!B(D#W+]-`)AO#4]][0^M.HQ -M[!'M!%P5"ISNA>P<&B1?,'MTITC@`X.`$1:^V]Z\>R8]O6KCJ"LS.+:>EJ.& -M[$TE\7;-=L6H2=H/\-);A!I`@$_NWX`O!MIE>W[4>.@+N-%$3$/7L$9J@++6 -M[BFO6YX>"#9=:^X$TW3O$:8FY]5-YZG^%\*/\>HU#:G`UB&INR5) -M"5G/MQJ838)O"+)F52"SLO_>$0^)@=8(9.V;(!"AVB90T&TD5!:3`?G,%$_2 -MIW`CO1GZ+4E++^A%4+TMXP+U%_+F<%,@/O1O6LK>AN!ET4;S3W;&B3!1]9SB -M\$MO*W*N6#VY%MX#RA\`>0%4?W&GD(NA''V:4LN.)[5=7I6MCSY225`G48&3 -MV.DSR=JR'^393\Y1EM%\W*P*(V5AO[G!5JOA:_1:1=X3:E_=#S@A]%US@/`- -ML(45*334-K1LCZOU5RN.1,9[T\XH1M\,N3P8-)9`^:I[X"^UNQO6V/5*'2:MQ7UA?_&1YHZ7_T-R*-[+=FX\CI%DLX5A(63]!6,Z3/*$MY -M2YQNBVT*CB\8V&_8QRS*K#D?IC$C';L_[,6-O++FZ>1E4^,!7OTK"\@,P(=]&E'#0TW`3KH?* -M919J&'JY`JYR5!PN5.57O+9A:#FJ>OHY""5;#_UYCRZLL]+;JS=3J]L0)V^?L7!*V][2O9EXBIX%$8)N!75''IVXG]^RE/)_S`F -MM7^3V."9N9X+Q8/LRWT-E48J)1H\P`F++YX_/:SM=KRCE8J;4-\[??D6'R-3 -MF;83,`C%]FI(2$Z=W9Z/?#7:9^>$?1CC@Q-6A$H-GL?I$7>;22$+^4N7:&M< -M[LM(C[WBH>-)Q!N2Y,4^+/[6HMD>/$EJ4V)R!,6#+WIR\"VR9JL()+0\!*8X;@F&C&;OO_O-'.`%)\'$XT9<'\;0:A]G+NXJ93U -M&URJ)@DF6RSX5&:XRVQCZK'@XM1D-/TG.&+YUPXZ3]` -M@9SSC+S,Z\,1?FE+UMF.QA[%O_>B-4MUE2UH*9.4`82GJN\K&1&CNYR%9AQD -MX6YFPW-+=BY`;^L)W`9?!LEL.O@^#ZQ:"$%TZ;>%-[;BA)&UO7!B&G'U4KL_ -MVRY[$`%WF!!8."IHZL^\#U3B^80:251<>6BO-NI&V5'@X(8$XP=J@66$)2CO -MMN2YDJ):2D]9_?\X\GK:_#?ZF$X]L_:?T&ZBNEB`I'XK]C(Y.P)(_C^=4[]+ZL,__] -MU4DM+'N<=2,2[@',JN35M!SC-`3>@F303VO"*%\&H)H=ZX1)ZAR(!C&8`0FO -MCX[>B>;'42V\]5)/VLF[$4 -M)`_FN)7KI%BG8,=^?ZJD[G&N14/,CNXH(2I/.K0_[B#L6`@G@]5+#;`!P?LW -MAD\6-F(*,*D[&K4^/[R20>!("DVY)G%WI,FF[F(]H"7A1)-'%*JA6\]U[DO` -MM*.$"I5,)EOR&CLE6.S;*801`:CTQ9=IFX;X]CH[CK0W4G7.\EYW)C]6>G?> -M)P;^#I&K[OSZYQ)%C3Y+S5I).XE_>"3C,YBO,R=AMIWB/!C-*K3WAX*+LM_4 -M,RAG7^&=?HJ.';7MXPMJ4TM'OE:H1B3JA@POFOT__@M3W33SO5(@9(/ -MV-([>?I;!6C6][2QTFPP?E_/==:)1S,A.P\9H)E3J<4.[5=-!'L??49$;"XE -MF(Q'1=[!N\_A.:(J$'X'MKK1[=!:Q;.M6&32`IHXE%WC1 -MO5C"8*!,_]&ZA#^60(E;,@*U*"T>CV_3?L&M2K<;F4Q@'3*^I;2FB4&^:AC\ -MSW7&:[UM\_=A3XA/`GC1O+B2C@.73L\:B7FEV3>TBCS'JW:T9XI^TO#B_V8G -M^F'\E=RD/$7.9:+ETB5G7L,&52O=7:V)XPU.I!5/X]A7Y%MQ9+'D'7JZ$L4O -M7Y?BTP"5(/7%K'+6NQT@O&%`WYLN;4IE^DF]Y^.AR[O,0:5`@G'N"`;H+#C4 -M@.(UQOQQ9FF^*%Q,:?72]ZT]]"4?(7NYG9T8O^]Y;,2`/]8_T_V+T5K=.FDS -MOH;+(*6W#7GD<+#IBI#R!/M-\+S*>"0^9EZ9J0&2F1/)-W3-<)$\J6&2DK;T -M[GI"QJ4.F47@#.L+$]DJJK=WCN!_#I8"_^5,\#F:K8X8^_7UF"&7"*A:KZ&! -MXAE+4FFH%$E_>%`"M!SQF[.!$V]AB3?R4==4U=/1\D$JV44_?9`3QPF"D;EW -M/UL.A`0#%AH(B@QEAB=QBC>O_4<7TW7*FFQE%ZT@5SI^,^@D/S*`,ETC%)5( -M*N&%Z;-.+>.%\:4BPK+A.<'XDI^L!A+KMX^JTO3P_2Z>YEP@4HJ]'CKI1P1- -MZ:O,*IO$G=Y;NMGUV**] -MV^B:W"?E\GI'_^8B^$?%$Q9I,6IK404W$\X)'7%^6;:;UGE&2T/K;/?XZ`J1U.SL;7NJ@"<#JV2, -M**S_L$SR\E#O9(J!F!15\-6,OIH_K:F*=2*09*2#&^QK!8]\,_BB@_S5VS-_ -MFVU>FQ"950\W!40'GAC2Y(5*NJH`L>K;I5'8C[OXZIU%STQM``")T5(,Z'7, -M-#C1]R4FSDVPN>8/Y\'LK(Z<63P4DY)]B"ZAB4!)T]90/90VQ>B@*%(<;!YV -M5.)-"RMI8X@@`RN9=-D&EA!#X@&2R6560<>?MHIE'.1XX2D4`[>QT_I`*`\P09]Z;[5R^_,;" -M'8U5)@T;MB%F77&4-`MMQP&=^!!IHZR>KDFRK[5)5GZX<%PHQ]FIC<($JGBDD5?K4`39YZ^S2,EUJ?_\L&&R#CEJBCTE#Y1S3VU)C1A6G"ISFC[SA&!SH6=9 -MJ0;EJXAVZ9OR1M"5@DA,*O;-N`C8@?%LLA\P`^1[X#&`?5=*91M#@+VS5T% -M1.L^B^1-LC=0GHW>0ICW;[YCOYIHT"NM^:P)*6G\XRQ<_M=S6Q4'M;TI\!:7 -MEV5RIN`/ZI3B)5N)2A67`Q<@!*D5N6H%^.N$6G?8S_Y8I)^DD`?8,6GV)CT.J7JHR\J;4\> -M+-6K/H>OJ5"44IKKN:I['RJT'$/W>J4V(%B*WMW):<)O[R<8=^AR:@@75-HN -M)`7C`7&/2A7ZB#__VR3@H.7'?S95)-EHB&;K.EFB2E"R[A)`['#KID)QQR8` -MCOXOI@:XH![,Q:G/;N"SDA>;_Y?$9\=[U*%%YR,88MI`E>-XE)JOFK*L`OK>C-TD`_DXDU:O&:QI6KSBTG#[Z^;140"JABO)= -M5NI%[?)NK,CR0!EA#.\ZSGP33QZ*J/XUR"$N9X&*%Q-QN(^9IF1"3-0NE%F` -M(?&S*L>Y,6CSI;EO;F4/:V2;]#G+.&`HF=-;0=(>F+>.Z6SK99GB[FS^"<\H -MLJ17[VD\*'V3"!DQ#=65("W2R+2#GM16BY]V^2Z\I_+7SJF?4@5OA1ZV)LZQ -M46HB;X,W]/%Y\#&],?S[U"2WNG:NN:-XL:)JSW:/'-=8%#H -ML)KQF3M0.(=`YSXO"2Z^8G9;B#,>=OQ>2!BG;);.^SWWI!MPC&G1'A?4DIS! -M-[,%&`2YOND%!9$%6G242]I)(M<@(E#`3EAM0*)&YLOGP@IJ&[&39'D%AZN[ -ME_K_"Z(YX1M_86Y"6(?:XDRS0*9*]U,YD@8Q-4W\,QG@!P;%4PZ5T;8WGOZT -MG6GD#I$("&I8X[9!OI#-NSE?V4H[IQRWB`7*`JCL1J%'P"@KW,?1,+=449?N -M9`T*W&3R!@L.E_*(6OXC-%6Y7LMO)-+JJ%!=;F#@U[F$T5#74L8!0H(A.[Y) -MB7$^]O+4K>?\)OE%0/^PEA8T+LZ].EW]JWK493UZ:0LHZI!S3G;I/J2 -ME)PT_FB3=Z<#>6AQG^-A'/;+@EAQ?]Q4?VJ&--)Y#^#_^HJ,2*0S--#MLCJ! -M$C(5OE>0HR5NBJ<.(Z)\+E?L90%9-5210[1MYF+C"B9@2]GEI8!:;*+EML0&L:` -MYU\>;*$0@=>J0016:`<_&:>">C'=#N4@W]_?EY9V#PDMQP@+M7J&?GY`LZ,V -MV/VNK.*KWW2#D1",!;&BTZMJLEDJWD[EP!4=^3F[Z8*E5<(FL*IR -M]M"[QA\<]>,*QPE`=!NLE).\'$D[W`M"]S4O;2S`W_2YX1JG^I%0PMVO8>CZ -MWHK]@5^R$C`D2&)1Q'/_=4YW)',+V=G8;S@+BN'"IZBSCBY2^@;)@]1+_271 -MAZ+'6"ID2#C`9!+.0)UEG'X@UGB]S(6LW`]T -MZ75,2AN='@#ENF]J,.!%>':M(O*\<\^ILA>J(VB).-/%P:`W\YMOAGI)<@=6 -M!)T`Q-#S*OA2#:N:=98!^>S]\"11OT&<(EW_ -MN&NV)*<#KU>9`*QXCBX3Q>I&KNK(,H;D8B59>3^S#ZO57K[:7ZTY>U3;(/>8 -MCD$+00/V-3X.MD;3)]#2E\"=WG\9ZT9`%`?5KVR3*S(^(5*7!Q55(K3&?IPO -MVH7W*F-VC'DZ=TR2GG)!!&;QA?X1W?E[0AYVH4@4`8]<(J6(GNXN`L!0G"?S -MKS7MP^M]^-P9!WXMMP87L%>LNR;2%1S -M1YGU+]GO(D/9:'XWQ"3S>9<'N'!<4\;0N'YPHH`2.D=R#-<)[KMZZ6IATCBK -M&_YG73/[*9$^G9Y;8KC!()YL6K75JV>9.7JJ!]B4#4:_R`HQI@MS58>TC;A\ -MOBN6C5(?Y>#1M:BRE2F_Y*B/[,;,2H\4+(O,B<,;MTP&^[+!33Q%_8I!SI&2 -M-"'=FYC[OBS@R])**8+-%\M"1R8FX$.&W^_JVD+7%Y"+#\,CIV$I9.R[;Q8O -M>MJ5Z%I8FADV`M(":]_5@W9OK,8;Q9G<\_$"4?+YY*@ -M3O7L(THMP=\CMYC"`2+Y_P+7\*:O-\0ID/?/8LAN(YQN\DM0%6M]$FW-PU^P -MKZ'0*DF;9EB+`S]H6MZVQ>>B,I.%^-PL8M>LB1T+)@#LAS5(XN -MNMEY:IA.^@9S$UW\UE&6:8;"[@CD5!$;P0A8_X3B$C("\/._<;Z -MSKS!W647#_PS8J.@<$3ZF+O'XBG[?7/X+N_KN,1R5:O'56C#M*4#C&"41PH0 -M"HT1,NW7ILA-:=`'SQ#FF!7SWNA(%Q/;8&N[47U':N?)#J4;6\],D7S[+@;F -M]DM(HT/VPP[%/`VC`%3_6'GZ/XEJ*[@B)(M%LB'\X+#MYO1?=Y8?:(\7JY89 -M^AA!-U[VJ(+)DEZL@)-NNO7\D4)ISD%`EI@/6'T?ATN8*)*]`8SB@RI[R^CC+%)=((>`QST?RG!6M4:-47H'':FD15?:[H\W\!1;V47.1YN]#2G,N).@8X?624QNG*2N[IHL@.XS77,H? -MSVD0QY1N7GI[:'59G;J%9;.[1-04UZC95B9^EK9G%ON"*_E\+4N`LX%`=A-R -M&E!0X7_N`:_$$+3&8+B&_M*"N;N^E7,PH-`AF[,RK+$%1^C3`/CW(9.A'5?O -M@?51>%7(D9D^"YBI&[S:#'`)P[6JMM\^+H[<#0A(HA+\\S7A8$EKKT65.D$6 -MZ(&AW];9.*PD'I.QQ^GO0.&W3&#%?'FB>Q'F-^`T8S9H3A]$=8G_8+/[%&.Y -M;/:[T^_^KF0;V:?A>AZS:/X*@9NP"5RW9)!J8$>#9?<[==BBT$GU -MJ^P"HO`2.^23VU-_9G*704`#)&_75.$'RI8IH[G6L>>#*>W]V_B'FX`GNS[2@^J+0+KW)OGLE$GQO\$PLJ3KFT!ISQ*Z-^`;)RX -M1X_QT$J7R-`Y$`(2CK&B4#74TX'Q;101C*LK_N5S%D -MQ9M631/?!XO4SZRW-/Y3H.9RBN`%LIW<8BIZT07?84$,]2PCAL+VKR,=-6O& -M;NYHG2]D.=,FXE";4[B)K%'\3V]$0:WM?RU.-O$CE-'O)`5*>'(VFP"H6'@8 -M*<]"#Q`)?NL[)-QTEKZ(Z?ZI!&`.$E@T%6LA$M76%0R$&;BZZ;\`65EJTMIK -MC8>TR1P#D)^AZ!:S=YIA!.6V].SV2`^AZ[(-0"3A61X,4(U]AR+WU!#;*`J; -M9$0A?T_B,7+AL;J\+C<+RDR]-I^5(;DP<4O`.)O"4!W^7.)GHS5IT^IZ)L?! -M1#&53FMA,I'_QT/&<8SD$.)G3/B>CI\B/'A*H6]AL#29#P>ZEO:##E6"DT+/ -M"*MYA4HUHE6+EK8D[K,Q$*!><*[P3Q&4I^=2M979%5/)JKQ"=`XK3B.O=8;G!X"G1`+J+GG/\,S[3P/ED90Y?-IP(^S"5'9T=$<\(K\ -M_T.)6LW>_`-\@+ZU]<%FW,AYGZ`,OI&9?45N:-;EPG^QYQD7TIE2QY@"8)F: -M2F(B$%]/PVB0MR7G6<)MWW.IBE-(?M_:Y(GTWG>UXE!323\1`>(E@91/>VE#Y.Q_40)X?$O`/I'Z -M9T9N8=/('*OK8-`"=(BW?J`1%A-7TR%D'1S,UC*L>;\OVIR1H:)'DNB53^_9 -ML2E+F/HGMOU1S[&_^AY9^#,SE;B\?0@F.X68U)YK!#U.UT]D(^A?RIOD7A^@ -M:S/B2?CRK5X+%S/$QMM\4O05T&]WH;8@\4>L5LJ2XLK]N0%0LP+0#O/Q4P$2 -M"826BL.XU;F7L"FJ%.&SKH;TQ*X`AN)I_U'65=20/]%6,D!:CYEJM$V:@("H -M(%'YOHG!!=L_UB1DD![S_R`DXF)_/MH92_)"[3\6)6ORHQ%O"AF;ZEL'S9*^ -M9"P'6$#(DQQR=XJU9CVW&OY\6K\5&Y1&^C[LZ9)!Q8=ZK[AE%R*X+[^2F(62 -M6]W8?G8C[HY(SYTQ[XI+ITC5XA'+;G<,S,'4<.)X&[N/I66K -M;M&-\T'2J0WA?X^7DUMW_U^RFPK)EUU(G?!2OW-)>YP$QJVYKMS.%9C[&H4J -M/V"E"-*?RZZ;E'2OUQ(8F8:/*@^Y:.[I-EWT)@QK95ZV-4#&[)7E@U2@PXTV -M]U1=OM'*YY?\G'4'L#!52$.*!Q\="I:__C*2ME!6<5;NGQ3-+4VFUG8GR`T) -M8+KVJ^R)9QNKI\4A0#*Q0!1GFP3H]1["HRAWZT6(SG<%L_M&=2]/5X-31.%=@$CTNL-SVXDD?O*5@*@1(L&-CI?0BEMS>'XS)H8?T"1#:. -MZE:(R2(18W_4@#@O`[^0CDJ7DDP6U4)<<^7S%98 -MQ1[>U2+Y($&$=BI&LO!3TWO%QFW8,.SUJF+BD)M0QSUA<]/8"6PO3EF7.@Y= -MC7MF=CTH`4RCCBK""U_$)IG\JOF.?19#Z0X*,H=K="CHS4 -M4:DX7BXV4!CV9AFL&37I9WV^BY\YGS!K<2IQ.E@$5[I,"#.\AQW1@(267PDOR?D[YD -MW+S^]#9]0WZ]SS*3:"V`"Y>"LCN=W3:Q5B^UK^WIAAP/]_IO41PU&NN1MH*R -M?-,]X02SA@.,[*4G#PCX`ZJNC-0>QA(03YC^]((/PXZ"C$UU25!"_5V)?U8 -M_6^*96]N@-UF-M?-(SG<)O-Y,*S`TJ#O'HQGEVR%@-9F1*@4UPI&4[D7PB_K -M+Z0L\;,L>^ZMVN+V^$43K\IQ!KG052V_,Q]Z.!DD%G$E#-C&PN3JX#JC\0IW -MQB^\\_.7N6M=#'EJI[F\C+$56;[NAR>I\6[#`@3^[LWL^[ZZ>,M-P0;4/#>^ -MM&W5,"II7//=&Z-:GH -MYIF5XB,;=VL8.2;-(V6#/%L^]W\/("YJ@6AO(1U/VX*RC=08KTLH'3:$_4'\ -MMD1'7M1E\[,U*]YBV@LPAWDP9M(OQ3+M'H2O4^&TQW]2=Q`Z[K0/D/UW*"F^ -M1!/Q2)>!>ZR.[6ILP'B_37/BB)SZ-AZAE%_O!W5L.GUC%TP,Y*0RL&:I<(C' -M&P!'K"PHD[9@!Y,A!TE5'M3PB=QS+_#R\Y6(W.)Q0^W9BT3[QK>?$8/&KI6@ -MT];TMJP<.&>X$^RR:_A*F=`V5>1G#+5:;=`/V!*:7S>+],^1J#GDNSFR$AQ; -MX)R:!J=.-C>>7*[./[HZRXJHNM4$&BCZ)"PB_=.$;J_%J<(N%"U5FMS=_CYZ -M?QQ@6&1^>M"O3Q,3DLF`2`WYX/2T%7Z82*+1RI3M2J(Q)657O!VB>F'CK7W. -M&/4_6F97O5^.,"QUA?C3.*P/.17(KB0$"LLHV"K0V^5J@$'2AM8V5WG`!]V/ -M*#("$MOW*#63EH#60)T$P:1L8'."+,-ZV_270^8Y40^$S)%]G0C'XRIN)8C9&1CQ-G-A`:WKA?G/["A"2W\8I@PUW`>FTR3< -MRR,4^S&Q]7^JJZKOC#N@RQ"G-J9UF5XQ5K';76#EA3HMEX"<*.7,:2+.?]!Q -M%4HLZN)G)Q:#L1O8("C#&5W.@Q6/H&L5M"-7E6'3+C*P`VL*N-8NXCEZ-MKO -M&='U%QP)(]@J)W/!^V(-LXM!F2ZY("\UKU3FX#RLRM.5^K,E\#,Q:V8HM;:O -MM4^;#PE7MVIYHF*?7*(T-XLC6OPL44\W72Q5AK8'D9Z$P'-R?UM,RR[B\2>5 -MEY;RG+?_P[&>8,,\Y8@*,%?YP#C`J3^C[P2@)X&TG2LSSNA_.:A.]>N,&*): -MN.BLGR_H\\<-*@UPP&P_'.HMS9Z]P#CCD-E!V-9;!(ZM1\'ZP>Y638KX*&U8 -M+-K_BKA[O9*L-CP7N(N`9(-)(OP@0.(>.D4$:E:``AFBHU\3W1=O_\UB%Q!: -M-*20`3;O;-'.8Q#+.0/.^-9FU\)NV>O!H08L4[9 -MS`WP(P,&&8/D_MG$QZ*@').!1D(F>)T3SCVP4X^U-?^C7L)'T#KC=?0SVUFOJ -M>-&ETX$'X/^YR^\Q'@$EMD\A;2*+1I+VHAZ$$'P?U7_/G\C?5W`U'\DVUF+GK/^>IJ&[4X_6A -MX4U!M),E8$DF(%L<9?PPXD$2+ZD#Z>RG-=B%9>%,_IB).C-N9N7FW#RCDGFF -MYAZ/?:CIGT%J'T*EOGTH'5C'B0<+O -M-WAF,M]_RE&,11]\(6OUOP@9,C2#*OY"[1)P2#ZBM)8YGC-SVUC*F/7/[,`E -MH2)*Q*KL[$7C*AW,?E-H&:E_FR4[:*671T@Z1]PNS8*2?1CI(),?937:N8B3 -M8C]\FHUHTJ%W6.QQ1F&&C--!`%@]9)RZP-N%*A?I6WR$H(T\-@W8L&MKJ$!Q! -MH!9(.NT-AK:7L,%`DYOX4@KIW:T2C!*S+&(ZI@BY=793AF&6#9"&E<-<="S, -MI]!X@OOFBGS$B>K+'YGW)T87-A2`J"`IHX=I%^&*T8IRMUK@\@H,7-H#([U> -MO__4?#O%L7A=19W(::&^3\Q4LXVI4D+#)).AX",[4$?'%*SYNG2>IIXD_4?J -M*58_]/82YPB4N^7%6?)B`_`'#;UW^[?RMUAVF@;61/I);7-UWVH.Z97*5S<$ -M1TW\2PRQIY?:08*'B>(2-N.WWKF -M0$MN1[L`D;,0S_$.NAN3$'DU[R@KLQI^UU]W&*4(=HW^DNYXFGTD2`G?D\LF -M"3\:+%:VO6$;K!)`>_BGCV(5I87-3,CH9+M8/:AZZOYIMZ2P/@7$3D9WY%_. -M`75Z]:09QM@+DP"U3?A=X@GB!Y'MFVL`I`C&H4.AX,_T`[-.G(\9_$-7E5MB -M-68Y8RF'7_?+NUI.]Z"WUILET7J6H/CM%QS_'2-!5-#=4<));M;8+P1F^NCJ -MP-HD>DI*B"!W_<50PM-1N:8EK]:G?"@)L&B:#N$3/IGNY2E2%Q -M2V(+G2.I+D>W8#1@<_:`AZR4_99#I02W6?M0D05=4NTZ!;[N -M2(B4UHA;]C-/>Y@2STUN\L=226:OZ/'&^>S/@4,6HXOKK.MY+)2F<07A1Z2_ -M$A+9-BG[(476*PD#X1BO;%T$&:]XC;,%6B4E8&7CE.$-OB5IA)9;H62;5IR8 -M:PEKKH.3WH`2CJ"^0;H[2$$N\(_ -M+F0&7J.MO'!'[YTK=1H:EX\8/<:\LI'N)P9K^"1F=>'3HQ="K+ZEB'"$DI/L -MKE':'TS&L$!!TF5_Z3%E<&BFE;_\UP*5K[SE]]?B&Y'_?'(ODS#7V+>1]E_! -M*O7W-GF<.%L3FZ+)WF!/J?2G-[9MQ?XJW;#C7[1\W90-FDCTU#/\L>-0U-V& -MK`(Z5*GKY(]FWLG>E`43URB\0BZ[\4DQC1J+W`5D)X9ZC=D\4>S*R>]E;A(G -M3W^S`%E3LW5&AH6X6'KI"DO3EPKN?>MBDH@=V;HH`10?)%L./*T9/:\&F4A$ -M9FYF2F0M70,+/[JEWX'V+-'Q`LRQ9PBA`[V-_989HV9WR[Z]V,J=`S`8)?V( -M.OWMYM_^\NZM;XZJKM)OO85C0DKW!KX37:F811_L2YH983(,.CO>F=O(\4Q! -MNG3)H_X+4[""=O4C!NZM'5B09:4D -M*62T%T\.`A`A?-_1I.=(_4_R*H2651?C*4Y0\XD[4&*%#KNBESJYQE05_(3= -M@.>!UJQ+#>G/0=D\X_MZ26K>02?49$>138'(SC5G?Y-]PF$M+&[\&4U(OF`UOGPZ7P?B5=0TA_C\09D -MM3]^KF,U1>K]P(88>XPYC<+4?C">4KDP@;;7QFJ+,S^J^@$\V"A8&L=1!V_1 -MC>O^[L,`F1(C,JC)<1>%)_=R(U@G:&'6GH&-EG'^[1P.Q=LO]@WW?^4?*@KB -M^+-@Y*K7#S1R,?3'9"?+6!RNR^NV61T@J[X5H/](:8WFRN!_CX"#]_^@$C`_9#1`1$-NHU`C;J+X2%`"/0,&!6+R]U'PR/C8)>/YRB;N;`9 -MO,^ICN3H:222\S5I=L>(E*X4K`)+)37&DUH#JZ.\,PD)(HJF"T?[=>00OH$# -MD1(ZS@5&G*F-3?G(BXM_UH(4XB'Q?2K.,.T\H`K0JV1-%7OAN'WQ^3\P(BDC -M5M.]\8!TT(>D$NA"L9D`QUU-O&"] -M)RV01)6M4Q`>'X^A4YJ1?I]P\9:^=Y[$"S_@,-(T-79HML. -M2=KE>Q]\.!2=8I[7Q)(I&0$B0E_)[T8'"0]+OHKZD)TD^I7@DQ< -M9!(2?LT\PE2TB:NBJ45,*8J]8TMA2D0Y_.D7'S*:8LQ=V=J8HVW_94B%C^T> -M/C#>]2]#(XQ;PP[QLBII:%*/#9_I^A57[Y6!:3\Y/U,:F -MK`JMW'[G)N(CH(#IP/(Q__P\8O:NORA<;_0,(@D^MY[L,:/;!=/*]95/Q!NC -M;RLU+$&1?^**8F7`P>$N*,5#"-:B4`6TO6ND8Y/.@'AM7QMGKI7Y>`2R4=&> -M!%U;(H\B4)!>(HND\%J:M;VE7T`L+5'X?0+@HZB#-H%5Z6<`OTWLX_ZI@$QM -MFI?&AOC&&"7M/\=@MWQ0RC-]^%9=0NO,D4)=XJ5FJ*+=3BY$AF?EG]D1U>41 -M*I,Q!LPW6*"/7X2%TT3L"ZFM/M;3\&4L;;3H`6?%J3$?M^7O'&(> -M+ZC5HB!YV&5_4UQ>1D0(3"YJ"-NJT'G\8#-PHD6O-Q<^/I5'V0!25;C`00EK -M9`!J"%9:=J:MV=" -MIO2\!<.2Y;(1DCO/"#&;^5KO'6%:]2:M3X#F"OW@2!0U4I9L?*V:9F?R:6W(E'/%X1-,76S50Y]DL?5-5A08O]LA8L/P5'Y=MV'06<#WBVF"M1S95!N!@/ -MY7S8N9@JZ72G0YX8DM,3;F$G]0V?HEI;]U8\&1!@94#U<`@Z**!>16@[H;(850@6GF7@8[KD8YMT@:7_2:7N/.C#R -MAI'VY>G$T1>G2ZL1PBJPUTDU0$;HK+M!T;5:P&+E.(H]Y&96S9'KE#D`EB.7 -M)M)GM,?',2\D[*^DEET#:93/.\FYA%FLG,+(824@/P0W*Y?LF8_P[RU<)5^* -M7@R@:=.?_;4]5\.I\=.6L.)(US>![Q8EYS4F3&W9'1N$[SR1X6!=_I@2AF3: -M$+Y-A1X$?^B4$)DH:^,DY1.:UA$\.MZ-92\4KH3U7O?HW^I?V598 -MW\-9%/Z])XDV''L;C1M1TMA`(QBPQ,U.&OO@]$[K&&#.836QE2P,QBN\\+AA -M%'YW+4!0[[!/[9@0.VZ+=-`EV]6F2 -M:I3HKR8/\_X8%Z=Z)8GC-\13()1<]>.!>W)3:88LQREF[7AU``$)U(D;C3;. -M*)4!^W;SB,-/JFGYD&GO9^@I6.VEPXI&5;`.J/RW4)=E;(UUK4!6@__D"#DY -MB^-F8J:(B5/`I@DQHQER6+8%_^+/7CN@!RS8/N3D;1(AIFA&#)QL72"/H?6& -M;9D%I[6%ND\7,W[8;74'PFD"+SO"/=U,\*[%63BBIF6S&IB)FAN*_@QX]-+'%=)ZQ86&+W&G?UW`TL]3_O*L+UK5/R+ -M4L>O3]>%*XJ7S*ND*<#];HU"!RDR.K-1'_/[%YJSQAV[W:UDIT!N04-4=MDP -M`9@^GGNYX9JOE:?`7`%71`BF>R4\FP&*%]L7R`/M^"B?+E#'K"LW5V80(EGY -MK($FU[,?\'*QBV;J3BGK%T,1;B"PS^GN>J?T.K".R$R(7?H/`-RQ+?YR!8N6 -M)BV#!FZEI4^?>6Z.Q;@/@&,(6*G+X%9/7F'$/'%2RX"Z:40(V16@=@Y[V5A] -M0AI4JC4@YRXN@8E`:0N&SB==(^_E\W?":K&&I",WE_]6[HAU*[A9T -MN364"8(A+?4LM05[`RTYS0J2"/Z)WWORWI$6D"LX"U4`!(=TFE3$6?$*165Y -M,:*#S\74T38"G[,>>]NT4F%?V?L@[VFCO7W6PL1)")8=<-!7L%`JW1C^E:[9 -M"#R50HO8TJX)FV0`I@[_*9];9P&N8E"K^#$]_LZR0(2PPYW#?T\VEO( -M.F5EUK._"WFW<1#E)WGEOIT:'95'?UKQN)1R&H.B[2EM.B8;U-T!A`RA-7I[ -M&0S='3]WO,I?%@$?YF>*@-1$=]J(W\22BLVP9:;W7&[*PFF'!D_).HV0:R_P -MVTR-+RP$E26C`ZN=B"FX"0!D;1!RM:G:53!FKEO]%Z.W=!A^EL!23EUU;V(C -MV.?*^AHB/Q[UU -MAZWIK.76)I3.5($CN.U_;FA()6I@D^,KHT6C#"J]]E]")ANMA&EHHLPYMHEE -MY=W22E1*Z"KJ]@@+_+?#1\67P_=VCBW-9&FK&4LX#+`,]BL("%8F>UQA?_I8 -M%E;UV0RI".#LC2[`A;!9IDC@0,OGN>AR2:LW#S/6W8-UH3X],U*=88'`X@V; -MNXXLLNQGN\4V_#&VN'/>@T2(QQ.SN\>4'("M:Y=.33KKA1$%S-OT8]AZVD#X -MN^^UC7X3K#(V)".K8S3R(_I!NFE!YWA&D$8T\%_7\LF@@&B9D/4]CJ+'/BAG -M\UH/YY@[%2E7;RJX\NM38PN!8\D%^03)\!J&0Z"6?\U36X\S460*R:5 -MNIW+BX?@.K8/?DQ./^U\>/M\@*L/NM[W]24J@%@PPZ`M\_W=-YY+%:TE0?D$ -M+JI<,L4Z*$PYXZ8?CE^&_"7`YX!7\6)/S=S$71*#N4U,X306E#<,MAA&_L,# -M*`TH1*T]RH$9S+(IFY5/@XT(F9TC-NHK@FA?(:P6`-A[U+]<*]L'R.D34N^? -MZ$D4`],SPY6)9`4ZY/#9$0N-1;()^TYWD(89M@*AJL,"XH8@&R1;D/+%_OX; -MCA6U%E[#0@@,1_PEC:T@RA9TB6J$EZ#.6:8@(+YK$JI+V_.7?\=\!2IJ='CL -M-(8R[9DDL'3,6B$[4X%OH,H5.97B@IM0*$M0S1(']=28 -M[Q7"T$."[ -M.RZIQK62@:Y?],/])0`ZDGXN@_\[ZH]]^N&,'$3,&0/9Q)B"P,_6%)(.;@*' -M%'_T=;&BCX2_0G(TB1+UWD.!S4587QBH;!*OJFX*(0F!5N^FQN#"M@@Z@/J' -M>]B>D!2ZUYVMEDV`\*X8FQBJE:7)%9K98E,HPY/( -MQ$XRTM*$`P'+$)VH225K"S.-MS)\+GP%1S9L3=[*B1U(95+NX?M2^I!Q?MJT -MJ>01):%V*YN]OY%!R?R<@LA;]>&,'EA7G&2*UV)I,)',7-4#`A+B78DO\7]P -M*BJ..6/-$_L8L(=6B$=\P`-H:IZQWT,`Y9BT>!EP.6'VT%H9EFPGJH)!HLA. -M80D9S$0W_E-$?[KY1KJUC&+68ON:*X&`ZD7!"[Y2BC9:E%=L29^LMOC)1AM@ -MI>2:;53+^#\,$4UL,@>R5`5J17?WT`)RLO1L)3BPGC(<64B3]Q0H9.$],[,\Z:SW6Q:7Y!<9.:&72#)&/M=]8);*C8F`QJCSW*-` -M^`U6:N$>TU7:S^,>=_8/L(,UNS&K$^^8+$$W#"'@+[&?%H3IFKK_VI+JYITG -MF#8+@KMXUNMS5:4NJ`/C63P2=,-B?)2)D\Z3+>>PSIAMBD89_;2@@K3@9#L( -MQ5#:H?WJ79!K4Y2_3270]E[CCY9/C:Z=3K_/F2'=4>5%UDHDZL8:S&O;_Y9V -M8YR!+$S@H37@E1NG5>4]-%%B"?.5RY"'DNG@.0K1#GD0L.UXA;6(4J]A]<)I -M)8MED-$V+LK`)]19FZ:&')<\=@KL4[\#98:DB!`+G#-DXI -M,6=<9,5+Q0X70\+;Z)=28$&[H7)`0=$Q+SCL4-Y``Z`44*N&JR4Q%Z -M@U:QHN6;+^CE4LJ1BBBJC/NN/4[RE4_5@;M]D5U)DP>E'Z_+2U*N97F]05]Z -MZ(R`I]?M!P_]M-1<4#"%S10<:C@0.H)D@O'N!JXYRB(D)V5,4S0%%`.1:V1% -M']BT>":R`5N^A=9]-?!EZ6,2L=9<8JJ$)U;_NH#Z0C:=_2W"/!+RD69+1/7T -MCAK=L9"R';_F/^*+Y!"U19'G$\0<_<#7@?5V -M?@#EFK*DT=^",,A7%KJ\\"F/$+>.O_[($)AL./MJ98;=5+$G@GXZ"!A*,Z9, -M_8N`ZHF=ZDYN50==4]^H3=!;^"3&>FS(,6O=HCJ)8T7PO65^["3 -M/%\+RF8\=`086A./'_MCB$`--#=(0"/U/+<<_(5"3*Z5_U.=E)K,KCS>0`>\ -M'W3YPX/`Z>#C$+1<$M8V7.?N-&7*%EXEJ:P&A[1I2C+CL!8+=-Q^D8R/2IFH -MRBHV8G_LPJ,'\NNV+S$S^FO#I]J&=^@XWDZQ=&7"8$.-(K6S6HEYSSDF8*FG:QE(I(/!_ -MUT("SP.JG.K@T3NZ9T4,^VY-D_P\PY=J!Z*2X_CMBCO2-`[*_"`W7^%L8X>Q -M4^(`<+&]UG('WO2&:6R!WEJG"QCC!/]@ZM^=Z`X+33=B.J'N]"QGL.#-(W*3 -MU>;BV>ZAOVU!Z]L\&W+ZF7!3^/X.V_^(<_LRL'JO+F;Y#W*FC42'F,(281MC -M9CQJ?0-ZN.;G,)%Y]0)E]X=?AKJ^<'X'MXG-2\QAB8>Y1S?W@`AGK`"7C:U!Z0;,$S?G%'X9UQ#9O3:$2F7CW -M#ED<&N'$.#P>?CAV.&R;%M#[+.*(*-"4N_^K@TRP.HE71.L -M+(>C7(*&*QE[=^:$J$BG$::TIOVC-,T^\9<;]/F^J;ZLL'5.0(]!:0"USG>K -M&`9HP&OT"O]_J>HH;"%C.%QA3G@4((XAY;S,W^LVL`()_DL2=A?D/*ZIW_^U -M:3SW(4^/=H;5F2BKB?MA=LM[A%1SMBB"`#=#;/JL!Q-XE/_;]KXFXPI#:O\- -MK?F@'+[3*CW_T04"LS;)"M74I*MD>_(A`=V7M?=?OOB+W]8W'QU@BQO33<<& -M9JG/T4?A<.4$['NPX[SI-9*>96K;AI/A'%^>/ADIE*S7`@K0D!TVLGH*76]& -M;Y`Y9TI`F(]"GD:IQ+L.S:$;6#:62=1'B`INJ!1,QSR==IA[6N59B1]>!!M9 -M/M@1)U(@&X7;*.'T88M:4BP?;L^B"GN-)#(5D!@>-Y&`PK9-'@K;HQ*A6R5] -M7419=-(?S3,Z>-W.GDBOIZFJ-8[AALHH8N*O' -MC>VO[QW3=(,"E?`FZI_5&:REO36R3;$GG47,#A=$,;H9&8!(@&C&_2OYB<&\EQP`J4Y2J,F+ -M;Z2^(`=V7.RS7F^!7_\ -MES&7C2J\TCJFGPA+/=K);6BETO[_;@#)UMN(C\<'TX,+(`K1BYKX#/C: -MLD3F7'!O>>S^.WB%![)9M3*K129T -MA#K<$["ND>IK`-':A;EZ/'T:-(_4.)!#4)7K.P629GS%NE_8D#>(-"::Z;M^ -M3R1%-2TX=UBV0[F2-;QKIMU!MJ*]BA23"-M(6&8Y%WAQWT4KQY:1"#X7IOVV -M8\^]W!;&U=3M.^G4,/5TU<],L,T_L\DQ[CQ]%XH%B=KN@Z"6R<]?U;7D':^& -MO0QHK_Q37650VFB3G=7<69\'$\G]=R_E;ZIBB;V49_B&$P),@QH6EA5SAT&? -M]R+H,\0M^+?J\2M55NKA>PKU;48!#A`Z2]"^0XU._R+`V;<7-I#.0B*ZYDBD -MT4<[J/R^+%^,JJ7C/`5SBRRN9$"FQN;G/9G`K!'E>_#=)O;?4\6H-#H[R)@M -MD986_YLAZJ0=E$?;KL/"M#:_A84!DCK"N9+,+[]Y&S*H8M!$3=QW`V..\#AD -M/17T7^B!?YO2T'*]H>QL4M2/R@,5M4E^WC/-J+`_`8*OX6-^E_NE7U@#1]TI -M\^54\_+OB&%6LU5VYW@7O>+Q>3!*BEZ'IJ&ER0IZ:+]/RY\=BQ\\ -M_IH/##_(9U0B&\8H%:7JP>/A9"]G@*&N;.=0,#7G,;*K((^Y[!KZ4L402KG^ -MKG,4%,5BO#_UZ9+>B&EH_:_]%Q`S3BVQO(]KL6E+@8MW*^P_!ECN]UQ;/TJ! -MUO"F;K0BNZ)/>DIWL)#\QPY\0WH:F!B:&"VYI,0"1X7(PW56CDV:>/M -M/[W!ZM#I>0K%SAR:*(9"]]T9CC+@`]\+2"4SL-FS<'>F0=.CL&2$O^6-=Y]# -M4HYE]!NP&?YH&H^V2N4\&8J'Q67+`YE@>Q4S#/<'%7YD@UGF`]Y3MW=E,A0& -M1$$+]`8_=^"BE82<\K["()DKDVG'R.I;IR!N6.FLHMI>1MH>%E;1HSBNWAG5 -MO$5:*3@'X2T=[;L\8MGTEHO$H6-LZDRW[8PS-$H^6*Q_M(A!ZQH",0'F+6J# -M=0?W$`>W7@\CE=S`GIQRPN(LK`%&QR74=+3?B1JO/,VOW-WLK39NT`7\O<_/ -M552P20&"`,:#\><%@8'\XOC/U;=^QW7+O_2'YOM!(UEHB3(GG:+^ -M6##3/[)ADFB&#H%E7A<):;X_A*UX'UP[LH>Z/)(:Q?.'X^&&6&DS8SQJ6@ZE -M7Q3:9?"IT8O[@0XRT9)W@YJ+J"VAPC1')"C*RJV7TLN=WR%L:%W^YLTG)#[S#K?,)`?KF6O,5.#6>OA`)8E\" -M.@-24,D&Z\V&RL)!.HBD%VPAII`=_>WBMS3BQ,&:?.DOG&_9YN/@*\*27MQ- -M;-_1E(4%.=J=K_2?@#3Y'-L6*08QTR2@J^=GDAV44?E%6`WL02<0)G>Q/7@[BKCZ?Y>?6XCB8X6C3!E)5L] -M*T7Z/6HN0[:M1%_[A\.G@%GS@ -M+IK8Y<1*%;2G=$:Q+.OL]>I9!%S;*L[,8I*F.!O&TCZ5,?9UW3-(C:".LJ;D -M5$WE`Y'+_^@MR>)*486EIJ(+I2@9XX?<;]R4^;\2`[)RDBUU$`D*';$^,^;- -M<$VYZ?BNC7TZK@384-5I2>[`,]@T.LU;[(3<2';`X_B*A:)YYQDG9PD*MEPY -M.*I3*EI;A$9O:I<2>F`NH."B#K!IJTQY,1 -MNG)IN&*%FMH>'+HMZ-V@+UO4P-@)IJ5TAJ'@/T`%88(]\:`2`-<\8&"J5*DA -MD^ZR_YX4,*-V)&@`QF%E0K3=OVZR$#3!&7LZNH3;BJ>=]'8R_^(5WC\A83F? -M?K****06>A"\8GP`\VP#2<$_1;J&3VX9[-M=Q`A3.<#]($P.QP(U%KT=,KX: -M`F?:;8HD`=T#=AY\@RU%B$GCASN.S`:^R+"1Q;O,"H_0_2_&:8S^4U37;C2='B0%`BT])(LR80$K?C;DX!N^"F-T0H?\`=9$0-FI#)OYEF,WURGI&82 -M?]";+\KR!KAC].0A@@-@;+(`VI9P2:$[D?`$?6K9#< -M60TS1,QI*B)3$["$QWG&P\X_54Y8F:1I5CB)@**#6Q@T?]^%$FI*:SWO\+Y) -M:CI$VOR8[SB/@@^&Q\R6BNHM[="C)S(S0K1D=FDSC&28_CYI]S,P?6KCU[*6 -M@9`QO88>B"^`GPU:Y9J3#P.VM%=8'CJ5$6VBZ^L&?&;I@Q(=)*":D3Q_KWT8 -M24U8"7U=A\B:36D]:P8@SZ.@FQ2%!?[_-",26R\7XW3>;7A\VF#PXO*IB+\* -M$/_KHW55&EFT3)6UK:MH(%XH<#BSG2B-A*9NI`/GKPL--H;?N#,>'L1LOB@0 -MP^\LKG&3C3TAJF4KQ_&>?SC_2O>T0?QMY+ZW*A4'27":+/UCT-DY`7*3@.V] -M"#RZ-DL;JYH0^328&^\$9C7".=,@ZQIN;8+F9'F.N"@['K!A!:>+X`[./QX8 -M].MSA[.`#Y^Y3R8('`T2;_\+WBC,IP5AONLAQ"0$&D79I^6TC^#G-&"FP@IW -MSY&@2(B885_\W^&I\!%?U^FG>-1=+>;"*&AA:K'&H6JIXXW#Q(\-.!$19':O -MJ.R(@E!#FD._LO`V?!TYC5L3UL_>Q:74Y8=0Z[/'2PSPF&UBC0TGO8^V -ML:B"Q>E_4WDV0B6'^^O78=[+-U1;JI^>T8UPUX5D9^CTK6C">[9-\'KUSLOY -M_=X-0BQ8<])'(G%(X:RRMNW8&.I+?ETWIWU>'$G76&7A#EGQ'1`AL'.+ORLN -M+#=KXHQ$,OP4IQJ+.OQX6<(380I&-Q8=[G^"*D_J8F^0;C="NYID\V(W'$B* -MZ.%BZ>8DJTE$*8VN00P*N`_JY*+`Z]#E!=B'O(`W-H'J4<^\SO@-(R#T&7),4//(BL.VHS/->!Z!$;W-&^A%1Q@C]4.3V2]GG#(-^"G`>`:GZ@%I6O -M9:X_[!DODOQC4KE=RCB_Z+)K):'(D[>>>L,#>7!'$Y#C9/P2E\\+^O_CYQ+X -M;]4V:J3,>IW)=L;*[-VR)'S]/>OQS#<@2=S[0T6WE"7H=C__;?&&-L2@87JZ -M_?.X=+$F"B7[%;$,6*%NED_3'8+6K?MIY-V/;'YRC4=@(*('PZ4GRQ[NM,<% -M5!(DL[)8P^QQF^_-%,NX`C!D@5$#+.Q?PO7;?$XDZ[8O6K5Q6Z("?(I8$_Y2 -MGY/SIS33MH`?5O2Z:#*3Y5(?;0\@LT@MSIXW2C,+_)B`$P^9.].#NT26GQR! -MK-B'T%-J%1@S)Y:9IA]ONCJ+7WM>`F7\M6R3Z*&?^S+A;V>-Z'0L7+I"T\(& -M_DIF?(]0[8M_"():0/>#I,OFXJR_Q?8+O:-9(C\+%=4,5K"E-XLGGI+U]03T -MEZ4%(?'1;37#X;!]Q28CCT(QJ!DA^X+XE/_@I!,I/X`0X7NVXYE4Q=12X7O3 -MPD&3RH&GP%KCE](+PU0/70CD%>1B78BZBIYQG47._]D`L^"P&O#?;IL1>^KMEGI+;^G(^FW27*R -MD9^?4I@7<'@#>Q71[U/O1\^ZY[C@4/5H;^70W1=*KL%:0[?S(9CLFP)8VRIS -M4?K6&N@-D!9$@@_# -M:@$SMC=?<\JZ458+LPO7%-GNN\N6'W`R-A/,.Z!%*6+X3([<]S)74CMZOX3I -MIFRF`TH;,XEI1.R`&!@%R>3R3_?G/-26!A@=)5^R*:I<@@[%C\^DO?PQ^Q -M((4R!-.QL(B]$P:QW(.US/UMVLG":GB$R,.`V`IZ)+@236(3:K-AAZ.<#<_W -M]?BK>;GM@_)N"$G*EY4S]7%H2_/94CPT]LF2)>ZT;?HZFM;8]FF+$QM/K.\K -MO+ZSP>+F"5I+YPO&RB&C"SG+*'32.@V<.F3)X0$GZG946<")%N91N3D8BNH( -M:&O]7JY4IIS=2X:B49A-[=5%O:'PX*YD_W0L:L-D -MQV$OGQ](*1>]L?ASL6KJ#T]B2@:-F.#D<(2XC.F5<&CK" -M*''GA0K7@A:Q"O(:JB)*`8CYT4OJRX)JT=%2"D'RB0XPH\ -M\>6EOJGZAKNF6Q!7-IK7PS7USTL#4W@92OE=:A;ZD;MC*A/GN,L^X8;D&LRB -MYW7NWIYK8_6K1*F]D]^0QC/8S<,P/65M -MZ6NI-^K?5%5\@(W#CGS/J329?!^GS/B68_.2JHO:Y,-4*@9XGN8VSU4S%C*> -M<#L]D;5*!Q^CIN7=KQOR_ZN4QT+JKB%LY!Q!]4Z9%8H:!GC-@2S`K>H%7ZEA -MI%2I=ZF$T6AWI;T[6IEA;RRI@67-5N-6>G9>&`JS:W[S<&MUO*[$"5Y^'?ND -MREJZ$9JWKR(RAL+C=/*[6W`)6RZ302(@Y/X#@7;`\2C+%)9%-VP4* -M`A4]F9]Q`G9L`;>(A/%[:14@'4=5=^J9=J<>@^B>F24UA/A"R&;?'H0T![09 -M[3Z:4XJR<3$\^//O&]P;_]+P]5I21TJY-_D>:E5%XDN%6\42I,DI##X6V`D, -MR&Y%KK24B2\E?(32X]+M88W%XPE70-1>3&FD"O%"X$A=W[?RH[!U)L>*'%9> -M6\W*7PZGN/OF`P.W[BD99SJXV5Z!>DT2Z''+A?5C^?%Z>4Q0B$(`Q;HE(TX* -M_A/%H^;BPA9^EV@XD>J2DI>1^YOFWL,X+PW#C\T:]DN?/[U\"@IL=B.OL*IK -MY"&)1P?)-0XA:#,N#BC!,:,I0)_V%(9UA_7#@^K9^P?#@EE7I[>')D(UMV'' -MNJC<8X9]["X+,#(L(W[BF:B35'2XX/Y79"C:+ONYW"E3B>Z7XGJHK_A=,):F -MFTI5?]$Q*87>-,6:&D2W(%2M8]2N'_&@"H,21&%==@+;G&[U+-PJ_+!E3Y[L -M[B@KQ+7PL'12G--#^.W"9PQBWMA&?=KF!!_-(LBL[4AC/FNKYV0)NP-6G6B& -MRLU<7'33MQ#AL=+1CF-;]5GD)\]]'2S9-3*N@CJ]Q>J"6#()GGI)/,E&^J&-.4)X+#/VLF#,-;JW%6(51/OC>1A3DK_0!P`D@<&/3 -MTYXDQ-(POMOJ!6\@$V;!V*'VW6AH3W`HN``6*9L6++_^A*%FZ%DXX9=#B#'4 -M>PD"Y!A13%J>-`$1.LT8.*+XG2?@3"+=G,!.BS0R:-E -M-];55./]V)#4AZ*9@(!]?^B(*Y!N!F*VK;E/A/TQ>'U[\,M!-NVA^&2D+.M< -MD.#]@&LGT'&`X -M1$LNBFBB15$XL`RZE>V;/85#N1Y9W5N=Z-"Q7H0/;3T/$Q!0ZTR0"'=83,B.BAQ@)2\FYC!=_>?RF]Y((VR_Y4#1WS -M*JZ_H)JON5ZSO;,S27FBN2K/49VKS('HOH!*FQM0=V":,N%[3R3X101_.>V:-AM6A$ -M++5WGIS0>/Q^65$II["F?#<_*DZSZAG5_#C5VG:]/B;E6Q77NT=-[0X_(Y@,+_)4CNF(*#]-AR3!;E8=QC)NH7(@Z1#TE -MM["(2HSZBX@>5+55ZHH?`F,R/^VC1#B\<:^C&=CM:CKP)>PJO\=Y"1ZS72JT -M#C2Z!COG%'K[V'LL>'#AIL:#EU0 -MW`ZQ'2GSGLI_TMV-^9OM>@JL+,Z].1[/&7-47#1[YZFVZ^%/-SC&7%@?/UX_ -M7$N;K0\G.NE"V`E.;KM(2+74<;4=PL[<9,$7*`\/'Y;/LG;RR79.N!C^_TRE -MEF+WJJTA,ZK;AU#=3S-#VF>SH*@^I0G*BV`2HVP#!>%RT%,@ITV[K3T?*1_. -MB^@KZCV:>W>,8XAHSH9>"F)/]L;2,\:#`83 -MK)'9:?*FS<-*V_/]S-IO&BW6H/=0DA:7T``*W?'&]29Y,;(O?]9IRH'J[*4> -M%RH5Y,\)HG.Y@?ZR@E5[7G9SS'ECWPC;_7U]]ZYCD,U=S%DR041@/F;#W^=, -ME[1P^U]GR!B_E&TOP$$4A<;X9XR\D8O>%U0\N3-MP;\;=-V#$QB^G]=H7IB -MV_R2X]&<#A[/`E$/5C""'6CY#A:*=`;3%9-TD)(DJA@E7P>0U##;]/$W,&?S*`[8M)TJ8I#6K!IZC?3A=!BV.%*S[=1?^T[5]?Q1:?8_F[]*58<^ -M]3_"`8F[D6F7M*_[,D0>Y#M3GZ!]"8?#X&HE`"/S^>HSJ&1`(.A51A=R7%(L -MG,;:-Y57V[\7D>3&BZP6)'/CX:]93#+'>L91>YL#QOEFXYAH68"^27(8A+LN+7H-AD8%-A^=I%1M]]\7YS[HY*GIKS1:O2@^M"P-O`K<]+&3W0RT@;C -MTP0\Q?4J<6JHEW"`3^OB4[(*P-<_ZKL^]T>,M!+2.YG'FV\@*Q/^BB@U,AF] -M"CG/Z?WJ==^` -M]07N\2^V[\\AQ\8ADDDQ5ORYL=I$TV>OVO8J39S_P1H4PK+"UC]8J+F8IQ>1 -MZP\OS7$=/+VXS%T_$\5/"KHF__254R0$Z:K_7?7#N:A3_)3CQ/GYB!N=PQ4C -M9$L'W/P*>@;YAF"K"X*`.Y54]"\Z,+*9N_0ZV@O/>B/T@Y22]R\[*Z6)/4I0 -M-A%:N+Z;?=5Q'Q;.'\]'8M -M#`N92=*4WU('Q,'/PR:3OXQ$)PJ@%YVWC^B=^["Q=V@LJ;\J8/+.]DTS)1Z0 -MOZA`"-\.?^8&#?*_3H]L6(W")R<[:D -M0T>Y_R^'NB19X?ILO,`_EEI?/"[5Q30S>*EG\LLVZ>;LF0W&L$B-]N@--=1V -MSJ+$O3`""9]@1[RGB3)[L4,_/QNOJ0_:1N\NZ!93]'=PEL\+4@\!:',9I%=L -M('&7O2T$.S#$A]A-181D=W?^(QS(.:K=D/58!B1)-^PO,TB"4HB52Q@=Y.L[ -M9FBO-#L_JJQIW.AB2AE5%SBUGJI#Y)=F9L"0+?R[194#XM`3F2H5DU+[ERJI -MQ=/?+,X8K'":PB%'FRTV8[N-S,T,.TV@A_>J-F43J7"`C`$-+-_P,O;"ZV+K -MWF>0%%^C470U]MC4KZBN-0C(Y-WR`'^D@'`])1<#YON0TK6MQ+#3/S3+08&O -M!7&&++/2+Q"'LKD8Q(WY!RO:8M-_EE9(+8Y8NK59]@QOU[U)7AP^?H1X>,D% -M,DEZF3`M;8`S1-.V=CZ#MNUV+I[T\$)[_WDZV%<_L<-MF`Z2:C4YEM(I!08< -M9R']&F*<$[]?^Z-CY--]N%(DDLY>W]EN&=9Y["F`Z.[\&,I5I(W#:+/0.YPH -MV1=JL=IF@*C+!A#9$)PN0=#:HMZ':/290GSTQULD611 -MX,MLH8&)[LPYSQV#W+^Z=!]7Y=(YCL -M88N.KN@GA/Q&+EL@I/$;TT./Z/AM5"U(6M(4D:CKXWV[IQ([XDGC44&D? -MAAU+==*9A6?\;KC478&SL0\6R^NM*Q1"NKI7A6V]Z%T*FP2A=,!\&:EYT11D -M%",<_P0#'S.-TS_7L^X-M3!V18DI"GA]Z:6&`8KZ?2697P:%%G@I>/;1&S<%D;I88%.H&'AC,4?9A&%JT`ZFQVD).ED:\0_M%LW+7Q?%L$-!E!O1`<%<$ZM^(/MC-4/\' -M5MDUZCCDMTLS_&0*4F(4K8_#AW8#;%=I1$_)JC:]-Y?X<;@YZB,7TU4C(A'K -MT`;T+SJ8_I'@BHO[R/R3/@98M%Z'`C)M8,=@LY1NC.7T(H^S>V3KW.Q77:1L -M6L@C'NF3$9-@VV\GPG44GWQ`:A^FW;P8-_?SE>M3$`B/O\B6!S'[KO2=>Z?Z -M:ZO$Q1&RG;9TQ#LBR!O5_4H`(?S>5SIS69Q13M/VW'-;$5)<:Y`1=D`BY>>/ -M!Q-^BQ+SMK9V*JUHA-2.LH.*7OO&C/F7JUAIEDZAA[>ABO"3#>PB$D"79F2> -M9MTV12PK'2(VLA2,].82ENM470+$`(5:HF+BI`J$EV6YZ;=VXY,C4#8$MQG' -MQ]\635$\:U8-`B]328DGZ5R>\SY;82\\98V/@A -MDDXB9S?\1Z%'T>\UA;:E*_\I]$%Y=',"T[532ZGHF=[@WR/CVX* -M5D1L72$;[5EC2-2/QTR":U9%J%='@HCI/_=XV(GM[;VYPAT[9-KR#XC!W<72 -M3G*A=V0?J&[!^K!X,K6NE:G;,&HM=Z`Y_VF?(I7U@VQNBPPU"[4R`_XSO/^6$W0 -M0%WHLU8RAIWAV4O<#%V!HP&"=^K&,TW&6.Z,2(FF!D$R"P]_37(3DV%[ -MQDD/U%5K`^-=&KW*Q/=&4JQI1-++(AR< -M(%X4_OAA&VR#PNQ1"V3%RZ[,6@`Y_?73)(J@)IXH5LSEZC*@!K-F]_#5R#&8 -MV("^AE-&G*HT[+)Z@@?0[V$,]'S\BV_Y?YI'^5F<[YPZ/DKRU]NP90O$BH@ZD%U,6X^\)F"=XWKVY4) -MEJILL25\>("'/#W3>"]@M5A^_QI-.6JY>ZCS&Q0&&3A#!Z3F->>E#[AEG:,G;G'5K6$B(G4S8(RO+,8= -M\_Z'.*TM&-P[7XB=)>=_1?-1=R%K71K:MW]WGP2<1 -MM5U`O6;;">>&8WC8:-$5+X!8HZ"+MT[Q])2MT?W/GKYI.H_H[&PXGT(7F[?0 -M_?J[A?SMOM5`[NWO'=;[#+';U` -M3/)I@5HN_]/7CQJ"!Q&,KK,^(I -M]T5PEL^!HE-@%E"AW<8%IO\,Z0!&Q;-T!^%CT#`3F#B%;90O9T*O^$?-GX3_ -M\MB2T1X9%PW`B"*C=N93&,QWZW*>;'O&>6K@OD?52?]T08@$LF)7.NP$J!9S -M%^,]\$=%G7>J&I%Y!W%/,L6/PA(0.B947R$0WK$.U-?,K$Z#4T?[6B9^ -M?OH?[6-;/`>BP@"V(B0VN/DRK(-LDN9`YX;YQ5]@F`RS9[[`]2NBF8&Z+?_9 -M5(DKK2)U6#'9ZVW9MY%YT?&T2"^NZR_D?=_7OMGVC#DV))M -M82I`B1[(A5&^#DDZLH@H=8M -M&,JME($;8J*7S)O>ZHFV*=&54GQ\U9<0HHPRZF,J*G+^0+/]S=_B'\Y[->2> -MGO@60M]&J`Q0LNQ5FR,?#C'H1@;6)TJ1M3T[8",1D_;NAJDZ%SP1MY9\.A^@ -M2T)2WBWM.[/)F$KKWMR8#NKSQ8$,6P%S3A,/-5[NXQ;`_&+^J',2U*WBZABA -M.F3^I_-?SDP$0%-Q"#'<234=IHCF2L$K@N[RVI93>?IO2SIFJ"+B"%II!#FH -M/P\>\ES<+!F]]^&F/YCA];I0OM204S;'^0 -MTH:5L\`4Z!6;@@C+DHJ2Q!,^DG]7:KM!_R]!,7S(ZGSC)%^^`/(^0)ZO,&VL -M64'IDD,C4PLQLZMKM(/F/?A(4_3)"^*P2;2[Q-:2UY-57!#.U'QM*&Q*UZ[& -M*U0_:EY5A:[KFN!ELA@$%"("!ZGU*&[G+4D%ZYXKLN@Z1[Q)%L\`!4SIA-*(YNI<4.27P5!2G/>WY6^+2> -M5T5^3(M4$8IS#-"4"4C(W;MHC2U\[T):NB*C-V;'D8D45NKY<\EF+H=M4W^B -M3H(^4X(E%IZUK=79)U<-3'],N!]+$QS=;`CF0G0O"=<("W^ABEYT@SGP.W>& -MJ+[A9GZ*B7+HPEW6NZ7+PQ\A>LW>.H.=W3H.69'W'83:EXT^ON^;V-OGV\O- -M?>(C.K`>N\TY&3SRAHU._MK28ED::1#%!@U?\;E_#@3MC-Z-\G'9(W4]4?IO -M(;S7[BQVA_?QYNFB#DB89QP8]H-$[MA?[EVF`UV)#R.39$OMO@QB:_/C?F=/ -MKB.K1[W^G%,LJI@%$=?*F%7@ -M(=4UURY/Q(5C&7>+@75GBV?LXA#K`=[*9@PE?KMA-!Z[>*!TDG[$LI3T#0NO -MKS-N7I3*;F+L1F%>EV!J3&SR(VP#4LURR0X4BR)$GHAD'VAT82=`O2F)+^T] -MFWBRO@CQ-GCB]!*Y2T7#4I\>6\TKRO5663N:^=DPLCJ0P$-P)??R<_%=9L:" -M*Q:]VTY;GV52)35F5_@:85EK*^=Z=^#DR=DALZ86Q"IB8C+`FMK_!#O>]X%2 -M&=FB`%T10Z^)NUR2Z2!SRL16N$_$%3M!N-; -M]\8)H30MIM8>'BN*8VW`SW(/=+=H3R-!*=GV6UJYGD/)"J41.CI*'2TKK0XU -M$GB^>ZT8BBI=_J]::K/$=LC.:C7XJ@74+QEK7X1`/1]5OKOBC$Y3.Z"2//KR -MXL_(<7DS0R/J36@SCZAMLO/"H"=ZN^`E'8ZO#M;(1J97$`4^C0;Z+WM_'2IY -MUH'(N#*2DP_#RP -M$QY$KB;84?*_.'O?]`;L&JRND_+0KXJZMEV>@(^9W.K"*PA -MD:ABFR0'>L2UI:5>9HT$1#,R#XR;JG+US& -MO2$7])%!E$>"JR>66:_*TUF-(;=RRU5`N7JVWOMW1<5+\2K;8H3L]9]?&=F+*[^I#Q;[3.G^MTR*`&"7WMGJW2^_;%* -M5*S^H%.>$Z:EAV4=Y^^W>$C*5M>C'Y0!Z/'<LH -M0L)IQJMQS0.$IS8Y$QZ\(O_P#X$LCGDYF,54B_9H+@QKU^8+F`&DRD9ZG:#+ -MT=W&P'D=%K.&GGTRT:Y-5;):O9NEKMNM0TEER].*9!180/9;$P\1,C(4*63@6Z:5*HQ0);Z.0`!Z(3*5;)M4`U)/%!OO]<+>9QH>1,+O0``J:XWQQP#("M3#K3R%9Z:/;C/%''F.L1:I#Z[JAFU\& -M.V5"4MC1(5,EI[**^]&]74*91HBY%^YL:C[)\ND(#,*`Z.MO9H\I\CPMN,!: -MV>^SL%1_IRYWMD+`YB)2C:CT;D%7KZ>B);"[.H>VQ(,=\)R+4,<,B-_D/MO' -M/]_7L0TBCSB)%R<[,LAV7)[M4C4?1R5M/4^)V\3+R@D:*SU2[*0B?O4?CU_K -MECQ_X6`S+VOURRVN_4LDH(`484R:L0($C6`/[&\Q]TAYS_6/U\A$C^[V;=-R -M$(A7,=QG$X/G?DT>K2P\J891>>H9L,>Y`08/OX"WWLVRHIK6O.ZB[QUG-AN) -MAQ#G%/:Y#5-SRP<1/*07V+C8XY_\_Y":T,([S]'I'R2=V8]YNPP(#DN4X2`L -MPWB=_V%Y-=Y3.\O?^U,8M_YA],+O03]QB5,U;:4TKS4YA0(%9RJ8&7_^@$C` -M_=$,$-#L2.)H[*J)1JT%#TKCV>7&\8Z6Z0\>Y]#'&9C/+(0%SPL]?TSJ+G.) -MX45C:TZL9+OP/L:'HB7?G"8Z]4)\&4:X,6[BE+?O8Z&$2N*0AQ:S$4L.]$K3 -M%D(%'LY>"BBHIL`J(1EA5RZ>?ZB=9GW.JAX^7PEGJ-]8I$LIV2GSUFA;I.2F -M6'/2W6TC.LG'W!9^]=#9*J8M.M+>97//Z)'H=0]:A?'L?T[M:>.B?E>7W!&9 -M&T*DBG+AAP_ZNK"GE*E,2J<]+>\(HQVT6+H[Q*:N+H>ISLS0&OL`7(^W9H>R -M02G6(\MRA6GL^C_O.ME^\;K=_\#_9=J-4[.[)B@T/_S3C>ZS(NR.UL4EAL\- -M(F%D(Y2-"V\;`HV^8M*;(].I-17@[Y=$YV1S(V5SBZW="/HB=G]7-?.>H6A6 -M##G8-%R*O!;@\=;KI;D:J(B83%$W6K89I$HU"H;76E'JM,*KO^%?.K -M4@4?_*X;;+86O9UXS_^RN1%]J$:S'N`4P`\'4MGS4^:IM&Z9@QNC57.(PB#N -M36-?W[`0#I)J0_K$F\0M$:U(A<:[?"9'Q5U%(LYL)#Q-'^^9,MPF7-$V`WP% -M^!&H/<5O<)$)(>_4ZQ99V-MHE0. -MQL:NF:+?A`"I$&8^YII[YF$XM>Z!]%R101M?-V5J^$712H/)B&;?@;&R*=@I -M_()'FF7D27YKNSE"_^Z/WC(/,+N_Z_3=2M)_+&ON7=EAG+\;BBOVEUJL.9/9 -M!G!,4P*O\8@>&G?CY_;O#&U/30UQ:H/7(EFT:^-'?E0@N]>:,L/!I8Q20,)8?7MOR0YGEL`NQ&RR7$5.6[\`YR0^RT'8%2_#P!VKJ+G%M9GA=\Z-?CM>,>88U*$5;<(P#;PZZ?D& -MED%[&';F09YE:+CV^3?[K^;(6&@98+?3M.X2FZMBGZ_\,+PEJ_H/,E63X-?U -M3C[&]_K%-;FB,N4%+($\E@6<$(=0L41NU6N*H<"17FWG`_7IY6>$,=L"^A`F -M\;!YW^&0!]>G0":"&45$PYJ!VQU[@D2/!A1B#F*6$0;GC1X/]S"&(ZEQ6U-2 -MYN5=%$\#.FHD.X**.(8W=;G\3GY$F/WL=2T'P.E>AS?&'QW.)`QV@P4 -MOL[O#T/6^_B3R\'%UTK1"^*R%5"2Y`6I2*SAW'#2?#WG?8?I4C*D&_2.*ZL: -M/%\8-+=,9Q`26,:S4JZ0H-ONGQS[CSKY6&2%UE+^HDJ\4%B*A_>6&T:T#!J? -MMBO3)ZU3GI85:X?/*U`=3E%/BQ.V#IJ(O#U:"X&FXDIJ4)^P1K\:%-"=?5UP -MK-@^\`0GF;?%J`LQ]>$>EE:A-!T<*MSORIM[OM:BJF*&M.2>KXE]84V'*!"Y -MK2<>P#-7+Y$-Z>F/``CVVEF+<5+Z[U#C:2+VO%Y8CK3W>AK%7+D'&XYBBC)[ -M0&>QZJ:$\POJE*H=`"29RED%=`K'G99WSN7#YTI%/(SP:_B3''5%0*(Y8V:> -MX^<'QO1IF/5>Q131)%`60GSZY%>N_'6_9_>*R%_1R44>35J3"$/W4`R0N;"" -M,HU,//<`DG\O=R1G-9&@MT`-,CL!Y@]X[J"&%5/G#3)T%OE75(*::QH:\ -M0_\&(Z0K8K7"Y%+X6BPGAG(^1E!@C]]D>6+N>:[E3>000J_OO#E$$5P=_,$S&^J\C9M%8UKZ%(:S^BKC"WS\ -M8NO<5#IKO*]]EQWVM^LR1>#8WC,5W#\L!(T65^[B&[&\\*Q"C!K*'"B@\]#. -M&J!W\OG7_E[VC#U>O'&%%1!1A]=V'0H`U^$C/!@+!(%+IK%\*XJ6.\XH',_] -M57MAQV9B*(1#&![9C$AK&EF)P+EZ=BLLO)?ZVP<,7A0W(+<\\UQ,3I&)[TO) -M/Q4#+8\HP3K,:YW3BQRN3&DO%'WL2O'QF<:6V`5=\<\=YN>!==-VX_@?\)_" -M*P]?-7%#N]1WB%1.U/?_^[]\^,72F]6H??P<71R!.(>V7"A8PRXY6#JBE+43 -M)75&6DP%,$.=A6LN5)#B3DA!'Q.(5\W!05^QF?#+FJQ_AKB/L"&::FPV[0JM -MN@SE@L?YQ']9G=8>\8MA'`8:*W86$HM.E&<0D'$CS;^97];S76JT)Q66_[VN -MRSO]/%+SM6\5?(#DO!W^FX78H-5E`]V@R7R_ -MW,`A7ID'[^%SX(RO>$5`_]YHZ:!(08BL30&.G%G=G(G8H4K4;[*3_6W5R$#1 -M!/G\P[RXHP>0M+=XORT">]NHC9:E*M#5:^MF\QH'=0`;W<"$(+$IZK4;,`HA -M45DQWC*P15;!!>R>8;RWPIDV__4'_#3[+4L$I#HP6#VK7WS;[CBV(('92)K& -M9II'Y.D-[)F:0$"8>A84ZLG&`Y(,U1YG9?9ECU?282#C7F'+E=_FVU/GC1G@ -M]^!A;V)+9MP,/J/.>/]_7V,[-GS6HB=S-?M8@QCIA("#R7Y&B"SZ4S=!$)F, -MFWA<=?`W?Z:RHV&K)';("0![W,F5"$RNON%3-"9K9S.3D6I.>2H77 -M6NWN/P7JTJ`-8P)Y4*JP@7C)['E+AB[!EIP3N6E?1.82:NWZ_+PI8=(=@.@] -MH2+]$&`0+=[F%2^#2+R)$2>1860T4TP2:_(V79V6 -MUK?98):\V]K`Q]N!S+:!9?0F$M%*6/'24LHMD\&,P^:F`N.;?(N5<]'KFIG^ -M0MHG\;RX:#M*&;W2-V6GH0?%KC-RWS@1[S5%8#J8U6!`X5!/A5%FN!SUZ"6< -MZC(X>SCB2*-CX/<4ARC39*+%TN1@_A`4M4$66WIT2BP]]'A=&3(AX6\V2WN, -M\&^LY@RJ>]8/"2_(81R@D(!][HO0^4=)5[K^\J0Q\%??LNE1B@P-:%H31=0> -MKD&L&UNZZ@W:07)@)B(L'`SLL:SU'$V?1G.=NIO.\!\;AVJ[%2T`Y\/);&",Q`(.F4G8E'XYXUMH#[F& -M6*A>@*01("ZC,F&HC]TJY^YS=:H8L -ME&L/OSL[9IM'I\^FO\=-G3G^N*901[.EW_T;V7G)Q+U<@Z&-FLY$ -MT&K;`A/2=_Z66,.4K$!A*^:*Z&SKQA^@FX3,=PQ]GKZ/$=Z5-<0TW8T-N@$; -MN"[N9-GU7$`Y*R!SF38OULLJIB9W.*ZDR>BEL,I"Q1L14.*-PAQ,VH;>@Z)0 -MS>\XJF(WL=1:>?>#R-XQ67@.A)+)$A<%?$L?O_DMM[B,%X:$>F3_UR'-$P*G -M>-UHC8MYCWB;_/V(*07S8\E;,`6FN8$,5D[_D(^==`16+N4\2R'\5R0`M*S< -M2;E.CS-V]9O%M?7CWMM'?C@[F@)P=H -M'G>YB89;!&>+#HTZ]\#AYUTN\^&S#O:M7K@]JJXW=-#@\G9G47::2[BBVB"! -MO>7.->T&8'UGXND=31;,+QJ'6[HG=:*FJ8:=?IC -M\W8VB&9\3S1I.H6E4)81*^.8(3(*9,PV"??IXB1?C-0/%'&',,X`$SD(54ZU -M-,097G?.:=1OSO_$;]@8J%"0JB+,^L??GATK['Q+/W4"Z@!\VPSY#1C.*=[) -MGI-UE,[CMS7'_@,,X^1IR$4T6?'J8I=5P/VSV-;>L$-NHC7:"]]*A -M*'H4>4]`_E0>%!Q/W6!%@7C:8T2NA[+TE!FN+A,U&,'@7?!:\NXPS=M(?:]$ -M@,)8O=>_Y$XGB2*\!$*Q<=&QBZ#_\@XW\0)R>2W'[G+3'IP(X+""99)`>Y!# -M6G'@%^G8DQ5874EA*0.W79N92VE>L@(2X7MQ]E5>5J;NP[1?&J-PS@=IKT*) -MI4WZX,TG`$UKHE90=6A!-9;!^$,OS:-4HJ7OEK7OA#=/ZUJ5./.'0RJ!+BLXO0DWLD#'S_VLSTM?P+^'@WF/' -M?J,B^_*F!?$K*><2`;EM`^X\]"WRK[`;&0$<>.PL):H/KF^!;Y"%[]8)Z^XM -M;*QC^@%&(+[?D@&ZK.^.[)^Q?S#\]\YT9]4):N6H`UFQ;D.U!8SIB`87BX8: -M5XO-(2NCQL\7%E!9%*A^Z8*B1NQ@F_GO=#Z"_IU`'/?>=WD)H/ZH@[P`M:/9 -MR7CQK8/H!%UVR#$_C;J,&S7D8KJ2S8;\NMV3Y0-PZ89;3>.:H/F&/&@Q0_"X -M8_V*R<+#V))6$%!NTG8#[']=_HXF5A;]#ELU=!!9UBI0UH'!3J&2& -M?I;NJZ&`/>GZE,:"+?O\\CNQ96T&='`$]I:)2W&'7^^6,/B&$Y`G>MO>I-[\ -MNNPXEBPTKN/*7?K=A5+H&FW7?3^"!7:HHR3GX;0S5_4`YH.,DO"#5,&]2^!V -M$VP@7DGNR8WXO-155.9+H4,E"^\W3'``:1AJ?D+)JD7QWE+WY7N,+C&TK\M(^4[\]?+W)K'1>\)TNSW' -M63;1'`Y/)9VI^M$!-G^;,%FS))J`TE,T4,CA,S,P0H8UFI+:7N;Z)CH/?'/B -MX[%,XADT#:#I]0[B\],$2G!7A)&4=59P=1*ZZ -M([BVF.D4*ESV+O2.[%DZ.XL^UB!;QO]TBXPX+AJ@W4X3DTARF_MUWR^:8COH -M*3GRQ3GPAIZ:;NM!#BP0!V2#"7%`L^R$X\3"%+:7M1 -MDY_`ZM(RH6%>JB-7>RYJ1PT.,06D:UG5O;P/L.99J_<8JT8\J3LZSTIVLX$I -M]ZS%R`&N"CJH=3]CK]!Q45G-P:L#9/,X>BQL;R*<2&B^;BUG990Q`(ED.5?M -MV\8NWQCD;9?M'[?"-)9G*N]/D(5]39IZVC,JEQ>KR2!*:VLK_Q;M-9XEG8*] -M7V7D$PU4V8>AN^I79*&H%ENAQ)'LV).'('&--O6Y*B-68#961L\=TH=K'=\9 -M)_WFBY'-,PGG-^O/)>10E15,[@^XWPEV/8'T>D9O%GK:.C7H5"*3*ZW/Z5HN -M;,)N)VT=_UTPO1GU.CKR"=-)--L#+M.\F5IA9N2R:L;KZ^$8W1Y1*5Y5N6[PA>C36^TK-/D?V_#=H)I%O)\MK;G^"#3C599XAT-.?(\;:_ -MV^E7F:?+4K!7L1R>@\&JT]20Z(4O%.[03L+?`OM&6>E^C[^N]T;U`00#/8?^ -M-7M3DR^\`0SEV-K>Z$J&3ZC^7?,K@-3XX!@:2^@0T(B]YZJON;,TJR2>1Y"P -M4*'0JE'.P`X*.V&E'$I3!T>3UA(Z50P/0I]WH;!"D:F/]1;^Y!JSJ>TSKF#` -M*:S0/`,6CY\98FM/FT*@F/B]]-TZ'9$>7,,V5"UU&?)D,P<\M`8(Y?M-;A7; -M_)O?X.[[=^1>I<"0K-9/Z-<'<0,3EAP7?%)Z[H(PFNM`J5]:Y/.D!S$]#R-\ -M8+P]\7=X)S>P:[/5&%\U?5R'H_HKN1791'C+L3]!<23B`%^M8YH*#(MR5-,1ZP(1CCIU<6O]41!=#NK6TH?WFJ%+9$`2\J1 -MH><4B1)K2&6;#(["N5!K`?_93T6)OZ`(6\%@:M?=[:_[/'_E`D=/1QS+T\H? -M/YQT4P,[K$&I&9%I><#X,-HG -M+2;41/]/B!GJ?<']@4S@WR(&>HYIB^CNQGR(I;]3 -MIMKW#3;VO%_!5K-?=`9'@^9`JZ'#73SOE-#]B)#Y_3"(J$:&\R&KWVTC*S_= -M*KN#]H5BV*]`Z>N=2N98-(-+G'[E6\X@X2?VC22!'<$2N8"X\J+*/[3*?P.\^`(F7J*=!2:D#/,/_1\BB1H0[E)4 -M#^0?O("G7T8Z7?RH@`_PQ`^*?5!%4NV,QB;R14MDSWRD6B"Y:J -M@(/<$A8_B`]Z2UB")]H.C=.+/@8D*1TEVXO`43B?5R$X#RZ$Q=TP@S5"JV$G -M,Y,U!.,Y?PKFZ$2C.$YU<8VJ;'IO9-DUF'UI96.#:*/^.KF>%Q'97!=G`&TI -MQHE4T(3X'6/![,LOO2M'$;4\)^[M+_$UZV$*CK5^-A=-P/X+[A6;PWB&^H]> -M7:>2(V%:9?*#2DO=?J80%$#F=."D&YMZZY8!;GO,1(GS,(06VDL$Z@J7O=OG -M#N:Q5N4/`C9A+5PG9KQ']PS["&Y.-;PH/!,_H$&P@M9D")F(;:ZFA.O8A,1D,[&^??KEDD\I+680EVON&[3 -M9=-)3(S9M4),/AK<+!2H>#*;%1CS4.#'1#6&M6M&8-,[BUP6?+6U6QV;>Q-] -MG'Q20-@LX8]RI9'QA4TXIT#?9^%!\)/MVC\\!#X\N.N%7>5O]E;F'3YXT\ID -M_=@^@*1,H:E)=>,M[8UV=&J./L`@+7O3V;9_HUIFK@(/WWP+Y=*H53`CR3!% -M2E"=2!.2WM954@:9UI:+M->'9$T#67P"<)G&%:2;9#G\`>W1]VS`JJE>V:#N -M,!58!P.4IPL*D1*P$23<5HO.\V%NF(J3M`.(]'EV]J=]-P;="2;-JG7>?SYY -MP$@)FC`9(?\Q4`N8,1VV$$44P,)+WIMAHDW?$H+OU+KKOG;<9Q2]6G$%J2J,FQ -M#1EKR`P&B.,^;' -M-<-^S&,V_,:QO&9=%=7N\ND77FG6D>6?'D+`TR/-R -M.)-U77WNKJZ+&JN_P+E-UU[X*&N=IT[XGB`(&&R;%DW"+7'^F@*5&TC-C8G? -M(!;(?V^^X(CSR%:!6M(4UH!3;E\%.#T(G`=S:/G&&AT'>FPM4[@*$^2%Y"*; -M;4`_S-B8S384`JW@&*"0VC++LEMAC&9QF*"_BYNG&B-#T,#UJZ@&;LUG>NM_ -MSF'&I1*?8V:O,MX0V:A6EV<0-/KI.LO:^H4TKIT?86S>@8N<&>-";VFYL6ER -M#T1)(OV7N)A)*O`@F<&L.WC=95C".+.@52@89-O@)XU-ZLAC:1'`.)TT>X<6 -M^W;,R.C@?1;#?T@GV4T -MF@]%2GH%X0=8+_66U3].STY8K,$,^*=D+[^>46>H.-FAE6X^/=1W8&-1H>&! -M1!3O0H@9.%VPI`Y'0"#>P*+U(K]L\3;,:=T]D)N8,G'P`Z_<61]_NC;=CZ,4 -MK)`G*$46TOE>0N=&0:EP7RCQ267T"[F$72H\`N)^[8RF:($[++J&S[BVNDJ? -M#OZCB7@H[K+-.(2.0EP#\;D7!0']SG*(GD_#J$5XUUV(#,I$KF1RC^;.[4?, -M#Q2;391,.).HJ.7E^V"X,9WZ%*A;BG-/N=!(6G>-JO^O"'Z`1`2 -M(V.LZ(*0)6U&=-"3B-/P<5E'$`QIAZO*C(,H'O$:+M%4,`0E9,]A?/(6[$T/ -M);$&>D!%A7Q>"D&(TJ0B%]E:^1WEMW6\B3F#1[BL1^^72"3,(U0V*RZX@,-H -MWA%#H^L['O[($U/>;13O8(R^@"NRTYA-D][AYP)!3Y3)C;DO"Q^'IC!;^,:=G/Z'IS` -M"^/>5LNTVLH"C047:G\DU@9>=0M43KASE@OZHLYAZ>F@%AGD$+5.)K]AZ-%$PH[/:?:(F -MR`J>C'BT/H&=-_IQ)7YIA%K+P0)6Q$=>;^^9BV*XWT_G3A;[QS_QVD1,'/3M -M4SV3*!@%#*9%C55K]YX1W,8?FC)8S707^H!=P.(2E=([V#$I3T44'UXQV%4A -M6'J^,XO"^2-6&V8RV"Y5[F2_)FSU-VD=Q-%BE5=JU1(;KCQDMX+]P!1[(G$N`S4W6_9PF]M,W#/?EX[_X`/.WNOB#R$]YX(46$ -M*+\"EVELH1T+:SKJ-[6BD7;?W1$&*;!7X*W#UY#3ZO$CX>29'%=T7]0_8'"G -M8=DN^KMSB8)2^!QK<,)TM'U?Z63T`NJKWBFTE`+L8>0#,X&LH7%*9ZX7FPM] -MQ##OW,Z_@!59$/-OQ7L.+$;3'+]0AR&A]_EQ\<%1[?O%RP8B_14%JUO$!5?$ -M$H%:*N#L2F';;IQZIP(9Q&1E!>%,.PG6D>,$*3#?PN92+!6V.)%KH7A8<".7 -M$K)&.B#*V+^3V.3`UD&??[COBG,I,"_!HTECH&OR+Z=44X4/&&VO,U,CN'?] -M?*VF+3[8MU8$;D2.BS'OPL8(:W`AUR+>7@GRGP`Q2JXW&PG;V0LK`:X>"JGW -M>XO96\;J98T&NJ2_:1(D!SNJ)V\\;Y^:8J.LI:CNS4S/`4OQWOS1I=]B`#)-O`R@.[/!W_=%2[S#*Y4"3;[`E^+=3;",S>>T9[90-VO\@D8'2BEZ6_G%:5>'B*SY-QVF;J;9ST*8M82%P&:V-=\9" -M@IV@1GQJY9K>$G>470/*?.!.R^OVLZ(_L=X`JB507H)]\[O&+V5A)]#JARZ? -MBM9!43FF7V$%XWH0:+YO4T1SE_+!`GC>_\N))/@SXDZP("LL4U<0(&IH4&S, -M]3*E"6AM+DD0.3;F*(9]6,=S%FG59=S,RYR@=%-8S/D+C!ZRI`7;>BM^88^_ -MC73,.6Z7+]8=D(ZDS10]?1[`!,*?U8%MX&ZKR:;9,!P/>1@;U@'AW:IO/(R/ -M&=:(/6(L]4WW1CS9*&6:'O%)2__K#8M`FP(9_9KD,%`^AK'F0JEBY'U(#1.. -MO9K;6SS)'6ES`E92W_C:MU,J;0&]6LYT@!M%F(A.OS'`)D%?J**AN)/5#DD<*/C16/-G@4^6$F7R%83889MBB! -MT.GN3;77,05S>DH94:+(]M(O3J_5RK*#/T.#ZJ.)Z?QX8_[^8ZT*.UW@M4TO -M+Y`&G"[]9Y+&[+;I(LZGU_',[G\F6"TZU;.OD./GQK*S)^T6KIA6C.J_F<+2 -M1>.\6JE!/L!)(C]N`H84^M37F2N(.1@?<'@183?I):#ZX.9C'"H];C\$(5",1$09?_OB<]GE_/U?',)3VAKVF#P7)K39. -MZ::X^>LMQ!#1DJ`7M*`U<+#.0UO\-CMFEL,\]!>[(+"KQ\H-5`8J:=Q?_^;> -M&ZRGT<.5RD940"*-ZI`]U5;Z3%C)0Z[DA'FTM/G3KK.8RTH#1$01ED_%O)&$ -MS8TP7RH2F5;F2%:K$:FF?QH45@^[B-&2+T55)=0**NL):!`Z%FNQ*AX+AV=H -M^GTVZ7.@6J(!QD6'D]U!02#D]W[+U0OR5=%Y^(*-@*_IXQ"^2DHKUP."U$D)@<[*<6_DNK5CYP; -MBR_;YM$ZK_1FPQTHL\J%YD09O4+'ZV[-\]&$\7AV^A6V7"+ANJ/XMI_=VKL?TO&U[K)+2)WPC\; -MU@'Z6*%A(7!*+J:C&VRJ:-'"%5(-E1(95HGNU5,A@GNV':D^HKXU6ZU?+)!* -M4OU9X'<9$J6;J?4>?$WZ/B#3C>XKU"CW8VBK;#<9MGIF^5!\<#X^J%KO@*16 -MFTONT/7F(Q5R=!`H'E";E\B&8B4QT%U<2*S.KSW9JCWW:J9T31;_E6[ZS8)7 -M@P'AX,W(%:W7Z%*!=Y)&[,I^N`$C4`@J@KOIB -M1,O4B%J0D9HO.)2^M.@9\9TC[L\5(G%.3>69"`1([MV)VA']W--7^W;^I'L/ -M='H4)*W9)9W>Z-%E+0>()/)4-C`2,CQ3(]5/X3+L)8]]0UK!><..VT3"S7+( -MY,"CQ/NT"./A2CWQ@CHX+L,#0/?/)?'P3;\@`?LWO@+,R+>@'-06W(VN4:[& -M9P,>QR-LI5E/VK]M0?$./P!(#.+-4\KEQ?! -MN(LL^\Z!^\1_C'A`/6:9JXIR17_J8Q;T>8W_`A''PB>FC>F5%BZ/I&))41GP -M0DG0K[A$9I<;*867*"MY6I==TH?$FC=^X!N9Q(9]A/,]W.S>L3%DEO2YRZ%@ -M7DNXP@1`(1O\R#&@E$L_VIZ`I=!`)%Q!KSGO?UN\-YN8/@@%3V^QG159,F9' -M54:@05CI.$>L5./"_L>?(<:NPX0CCJ,HR1H51,*ZI2W6\"+>VE^I!5PC:A,! -M](]*?MF?9)>,H;^/3*B.@7;]Q\4ZQ3S=I6UD?:TE*&9L'I) -M84KU*0L=ST/D2]A.)Q`<]R^N5.JFZQNLAO`:@IGC?''MWDS\A\)U)FDK;1[, -ME0]JVL1F.0\@T?:!YL&CMA9'I?;T5+NZA^/!KN*.\7 -MGFP')=E9WC)# -M<,*C%_N'Z=L]H72VJ/Q%&=`&8//7CB%`I=/[W= -MLU"'S@>KP^6$.'H1T09)4#PQ=9>XSZWV@E'IEF?Q4+B%U[UYG*A_7[-B7#_# -MY%?EH!!#3+`!0?SP\95004=6K?T>*S8N!97Q&U&N$.\O[6_*M4=UQE-=^U7$@::+UQ/KA/ZISID&,:[%W4ZE).>L7AS4P((R<,L -MK:\&C1QE+XX[)BW&@E>T;'2<;*K06#XM$M7S/72Y:RXJ4!][FVY,<8YW3W&- -MR"IO)/@+%0`;?M8-S#>$7_%(%/P'=T3^L:5V$;3O&YA`UG715VK;@VK5G^'' -M>>?@-^(J9F#F>)VQF%0+9!#R7T.#2G=0_JK`2WY]2O[?7+$DA1J<.BRF"D%M -MDX/!%(/D`I>TR5U^$PN<=0,H.?&\I(%N%W^_[;#$ZN+.P3/9[[`G<%8.$1$J -M%Q@EW7TC%5?5!=CDA8N/#)B=,SEO)YQ4`?W`^5@!\-#<&3!.\14`-MBU)O;" -M`T5K!)9R%7V52(!#WD+=G@ZQ7'>>:)!!S>3][*$_/056BAFSBR*/$V=?$'+? -M<#02;N\J)<*IXR9V4=HBZX/;+#+*Z%K]W^L:GLT.CE@0:D%S_O5MOB -MX*03\@38SK!.9,+A`ZP"(@+C -MFTP?$V[3\QOH0-@K=<^K0']"B_\BRD.=:[`8FDX3:!RZ%Y!&Z@(T&W\*>(;B -MEC3M8B=5H,1UX,D(Q?F1Z"B0^N=(^NR-.5F"?JCMCB)$$+9?1_F"2LNB$AA$ -MY[3.=*?K.LP4]JJT+LP\TT3B)K=49@=Z(?*WS/,7^Y@+#:38@$6#1MH%<6H0 -MXG3X=3[*/=AP),18(4'*T -M6G(X&6H`4MV=C9_(*S\,^8:?@)&8:ZBP37BQIX_+F19VTO?#RP#L:9!A()ZM -MXN$IUPPC+O_BW;K=IU(\.89B"KA/B>BGTG@Q<7,D>[W.N0^^/'BE+E^U6V1Q -MU"/QV]B%S9B1]DGEN_AM)TL[PHJ!L2(D34LKO/QH*H3P%C2F7 -M9-T#S5QM3L"J_SP`@E-/W+3"J!WN8YNO@;(_8VM0&!5,7PGSWWVX8N9VL48 -MUB"XY4<&LJX3\U-:RGS&6#J;Z/=)15%6HTS;8Q8#K6LLMUC#8ZAO`[R0%I(H -MXL?,/_4AB^S!EH1RR9.FZ#HR855W;UI#"9]TF&MR+[$K5:`G\Q%9S>=+][5RMCO0,'M)Z4VSTRA-.']J6;M.JAO&U'$2"\]'-:$#%$6KQ>^3,:KXPJC%B;:7?/9-^@.<^(W9 -M>X7A;@78^0201JOFTQW!'F-"D^]I)'IO2,*.!5[Y1"K@P.?BI"4-.JXNG3!\ -MP15SCAC80M[J(^%(?*HNM"N\$.[=USL_$'$>VS1TWT0VR<N+*2-8Z)@&`D=?N,CL*FQ>70[JE2;P)0#:`^HZ\^E/KX6^91<(1`6\1 -M-2B#=OUI,$9'CBI3]KII,;Q2?SD_',2M2X],6#YHW`J9S(2%GX6JT6Z'.0Z7 -M55N^(`^=LWR,&^IFAN<+08B0=52O -M^>F5<2AGVH2VZPNZ,!:KF%_`EB)JHAP%O+?TGWSIP\?>=U-L3A)%>(=T5V,% -M0B?.*T"K^+24B*ZQABHWDHS:F"8)."7I:STYP;(:68 -M&63D[6("*_1L--EQ7:9_?9!9`QBS2'B&YX@FO<$1\DIE.WY[L>S,8WSR&<0\ -M2PRY)J`&)Y5V:VTC%AXOE&>)\]94EM1SP#2_9Y)G?Y8A5N,DN.U^0BV<,:HCABV-N=!+(!8"U/+3Q -MW",3HJB/6,7]ATK"I:^D;M;7W_^LHG:C%J=C93Y4)1JMMWXO#0T`.YW,!0'] -M'CZ6BO*Y3@B@#`4E9NDB'"']JDR;%#,447Q\$S$H/8UB@=5\N]@62N/`(=M6*B -M4Y3K^P>D+JTO8-=(G:A!\Q>'P^!N%:F5ART1KWJ83A/)?1?TUXU)+.I?&C(5 -MR1>0,[.#9&$%[4#X66)`T(7HK&G7!A88JK:O[?4X$*L(7)%A_C%SVG-&U&98 -M+;-`O^^K[6%6]MIRHN8T1QO+0"L&^NE8J_R[55[S5J!D'-VT@",IW6.RE -M[^0&[)J,WRHP0?2X,!DDT>EH_!^FX"V^IEF)EBMSHK"C.%\A/P?4`^%IVAT2 -MVV*J8#K9-MY$P[6-2XU7F#4MQ!6@2+7X\K_3"\\0 -M>K)'_..E8,%.N)5)2,O4!FIQJ*KD__IH/12.!BZ@ZBDE4*'4>(0M"S -M4+VX)7UK]V!7T8:_$M"Z48>;TGAKP"2F$F-MGRL3YO->K^\5UF9_I3] -M#?QE[*2H_E"$%JV:!V6,[<:JU?KERN/%&W*->0R>F;<:S0_4LA6+()MBY;<' -M8P^FFRJD)=:ZC=Z[&:QL(N5[-:0C/S'&Z]4FUJO^`-<0(#ZL -M=1;^)@!:]LDMOBVWHUKWN?0]X#M,T`;((`,.G/Q)J&<5\%MM>'M((Q0[6?M"TS6>"1>7QXMFF!6[F4Y? -M[<%B_0?W,"F9G\@DMRL%?>L\3&_FO]]F$1XZ7+=>,TO3RB69P^I9I^HP%9W_ -M2"*@_<>)XT[$F3;VF%''\CJ?4=9$6[(A>[Q^C[[@X[3,3.%96,D;L9G))-O_.I/<%0?P@<6K8N1JD?4QF9RL@ZB^QB\Z/V<*94'F219.,@.5V>S -M=?*DH&C<]J4OY/XX$ZUR:"#8*0SNNCOL:J`#XM@EG:*(?_[MW -MN*2HE]\^\)PWXRF']CBXHI\5J"V$JAD2(P!?:4:59HG1'`4*$[U.Q'"-TP@6 -MS^3]\;SS+S\57V4Q[G=%00:\^TCGVZFJ`@?'[O*Y[AFU_N[&,H(83WDM(\09]"+1'0%J:\!7Z;PUPF; -MQU^5P23U38EYWV$]$PF8/O_R2*P'(Y,R\&+.!V%CK*E,^W[JF17D5;%8*)0: -MP>F,`J_,A]=`6=S/(&IQASZ4#X\5+%Y>A^U27!Z%%*V;DF5TF6K'2!PL58PL=+?+;Q)N^PZ`\7:M5 -MZ8HX&Y40!YR-I0MOFF&F5XV-KHX2.H8V$N!O#-H%TUTB>$G]5F*FI=ZCR"6S -MGF='*V>G=2PHDR82.K$VF#1%<][^M@TK6P`/Y^)%SGLY<9I_$VQ7B-&XNV\F>7)Q2(NVNITK*,."Q;YIR>Y=!\]!K -MGG^0<)>IK%3X@;$03$+T:CX"+QF5(S7P -MG:`W!OO`B-+=PMGMIU:&+W-&06-HSI(OA\3:!*,?RVCP;4&MJG(02*SY9%(= -MB\O0E-SF?@ZCS-\(T[3G(<6%*%[D2EMBE)R3!*6KAND8MN>:JQ"%HCBML`]Z -MZ/KDC[P"`"BBG9!WPRKW?#Z3Y,_G11DM=(Y`C`C-&PH4N]FJ#(`6+0EEY/0I -M`N_#>3RZ?ULF)S#I6A81-8F]4NP+ZS=I$RTW"W[4&K:Q -MSB-1Z:2OUB`\URL!-)XB@@PJ!B8YC6710J[F89*TM>'O[(MGGH?NZA`EGQP= -M;3]R7\#-F`#BM`HB9$N>@0?G,'P/DTL2<7@FXK>FT9V2&JMC^PU4 -M1ETD;5TC-28OP$6F00%3'`XBBO$B31$`(&P!2Q)/ZV!?:.[)C#1D(FALW,&8 -MQ"+T=PD'7^3<%!C?A9R"C1'P`IQ+BE02@T)V^^P9@V002J.`;I>!MF^8#2@R -M30W'*AJ!L2! -MPRS/0U*HC9.Q(V'147:P$)DDW'22,PDY308BKL=U8&@/MNQ^\B+?4.>$L.11 -MW3T3.KLJ/6X7>[^`MF*!FN7,M-AP+[RP<(&>U&+@ND@0$/!CWB501OYF9*D. -M$*\PP`LRWIL@CO'R]!/K.HH,')*6;B?0\U3\*8_E(1JR,1-+'4G<>.=N>FM5 -M]9B8S_0$4DA4$C_MB00JD;2XX3A%#7%M?DP\HL@^MYXRH$4;<;BJR^(V;.M!-;$Y0J`QP`"<2Z3#' -MZ>G(H7$M^-?.+INL$3:'ZON$$B!)-%)L]4)EAPH3)>1]8,?YH![8_,/3ECVG -M61$][ONNZI7\G@57DZ2^N/2+&5)Y#"*M^PMGP"M[WC2K6P`&5,O(Y$VY$FN_ -M3DK1D?T;=*"<#@V_^%,V$!O?Q`T-54]-SPCJ(`=#;;QY.D3Z&],P(L_?^GG. -M2^QZBCW63A!2^).>L['[M=H_/G[ILOIQ%O-8ZO/'R;P\6!?/R\T -M95@$5Q8H`D5]F.[K64A+&UZ7WVJ^P$)OJD/'&W^&!"/6,!+$(2W7CZU-%IDG -M[%U^)..)6MT=E)]YP%7+?E1/9I,1I-GW4CJXX>8X0V8[P?S_+YF]*X\`MN]N -M4P.L)(V"RP$&DV1VS0K(?/-(N6Z*X!TN6"QO&1IX8`(:^C[ -M)$GKH9'-:]"$SHRKP0/+N8O%'Q#@46HQ/"Q0;DG@MA+[(.!*`\#D%2XG?S7G -ML4+^)F:)XY@,F'@3%FOUZ0@TYMT8]3U3<*BC7,H^CE$#VP*^_AX^$&:L+K:2 -M'.]-UZG5]9Z?"6X^I0=.M%7R$8&N$O0UB1MQ'\&&;J4U')JO:5(1KS#[_X1C -M*2AAI"$//7J2\7Q;7+GT8"038?^WR`6]B(%VA]-3@?H-+_O/B)P"@"X>/E#; -M3L%TBHV9AF:R\.EII24BRI<_(S>U5$DYHY&@#TBU[6R@;&P(F%<+X/'_[:3E -M.G?15:VQ5X!#%`K;Z7Y$4\V+-,S>*CV2[W`_>>\R" -M^@E00`@D,'BY$1I_O-@5E`@QCW;X%);NR7<[.R6*(!9%FS^Z&PI8"J5RQ'B6 -M^O+UB9]9LQCP1CF3LG)VMF=FQ,3%;&'U'VH^<40$,2W_"S*>F?CYD3__\0YE -MY(67`0@INZ@=RFE>?]M?D'41I\0,J9J9Q5"]^@2V^7\U?:2-VKN\4[ES\S6P -M4#Z68(N\+B?AZL4'8L-3]>MP!(Z%\4?&I+N9G,84B^R!>P\-]+5$">'#.FMT -M*'#F%6[^HR$E4]('=>AQ52P#QQI0/U@'H8U1C"1*`ANV8]Q!N*-#8G-P9J0. -MJ/\H2Z]TOP"6+3D8O%IF%Y6I:G,\%Y-R,HU!9XB5-03:PG8?)#$)7`5M>>@9 -M+NDXU4`Q@]0V//28)UWJI2EC+KW']2G9+:)>'2=FA31>-;6"/B@2>LP8"R]9 -M]0E3%$VRZI!YW0`DL#DQXY,77J^T[Q2&10L:ZUVAQ$AG*YDJYU-.YKJ4',OU -M30&#_T:3\^G&K/_A_&VY,DOQP>&]4AT#&I!Q2+1I-$Z3$SA?N/M.16PS/CWK -MI(%GI,`/-[!D$U3B'$U,!;<8..S,,*T/U$XI^&`W/L)QRI-6+_E4GYFQC5I6 -M21'#?WN^0"=Q`(,I2GW^SJ-"=+(`/:4O9 -M5"(Q(`>M,`.;OOWZE0962KFTS,;YTM7.EZXJ5R)?0T%\A!FS5E)!-&`;$=Z& -M)0>'2T"*@XV31:A8[6&T$?JM&0^Q86&*\LN5Z32:7LB -MD<9@@%[&_)UK0Z&27AA9XC;Y6%,?]XH'9$T//\EM&JDPF--KU%OU:1_!3.*Y -M6FK+QWGHO>H'OT9-3GS4Y6D4(@HSQ=;GIJCOR(+S?-.[M0V[2!T85,^4M8-8 -MSO8:2;T;(FK600M$!\I"X>1>SPRJ+7,G0BN235)?3[P0S&N/R+&+]+,?#>AF -M'IM,C6>=8K'E*OW(TAUQ4X+38O94W\YH?JRQPM$)M2`*R4^#CX)S;430W'-Y -M3@X_ZQJD*0ZUS2^#*S?4!T&(DTW2TRQ4NDE#-K\TG;,8.+^K__1(S/V5`141 -M#':/E&?\.&OR3L`Y#-,LXPZ0%,D*G%&X23,=Q$W2$J#=H$=YF)*I?S=$67;_ -M_](,C$'_O:6IR"T'%Y.+2EK18]X?Q(I? -M127,,L4W+:LY3\AF=$%?MLKQ.:5!8AXE<4)TY!%HH[Y\O\=7F833+$V4Q64G -M+3-/O=]<:IN-Q^&I@M4(M]8L1\55$%@&J+K?4Z4O%I35R\T_MQ6K7S[G]/]!QG87KBHR6"U-&NBQ58C1I]6Z>_!*S/KD -M-J[:T2<:_9GG&A)N>>O&##,FJS`]$-@IS8/3;L:F+D>MNCM28AK.DYH^SY%E -M!R:9P))/Q``WAR=EA51AZ?C++P1`;`.P')L6`6]^ZDDC'^24W6J)O\S\+#=[/&T?81)X%C9=O&@,C_F;;B&\.<J#J_-/;MN/E-8E228\^S_?@F$.[`,`SL$_QF-L"H7=[!+$Q]"*%&9% -M\W]W4.[%H*&43+3]EP/G>I#X?7,S''FQ4R%W$;0GE^K&("VV\7 -M&%?9&C(%$XX]"="M^KPO$N%TFLTII@5^00P(25D%0VU -MA_+Q]$V\2W//3^*JAYDF4L>!L_ -MH?MY^-V]?X=KJ:>S.3M/*DT?T#[6C,`)+JPJ&.*QM8R5XBLB*%NA&Q:,6O`TGJEC`"Y24% -MU!1?YW%(IBA54R)XSM^%Z,R/]-Y558N7&X(P(WH='YZE-VK,JVE7?*G5UK:% -MGE$\"H(W3J+I=O$=Z],%$T+<"LL;U69(5M1;M)TB1,E&&\%7J)#TXY[9=Y.8 -M25I\J[X;0I6;B"DBX!UAMIQ.ZY#9RAQN]BB'"IPZ+Y)R\$,*7M0KW(=:Q:Y9 -M@8C19L39["@MHN#^8WAT2$>&JA6JA)J2VLINNH0$$C(OOJ@?$O0^M/$Q7_\" -M!OJP`9;S9?/VX.$X+TEW>[NJR?N9(`?*BI*FU-4_-^NW61LCE<4M"T*/+1`S -M.02/Q;7CI+7/[F1U7Y?!&4'M)&-SD](>G%^T`>!(Z+0JI4%N:^8(R,$NR9,N -MEBR*O-FQH2`4OHWR=P&X37ZT\J8OPD';LW,B?-,W';@+EX'-9XVXD]S-ZXJ, -MNYQ`HA9NBZ$$?91R#+&XD^?A.F&75"BU9W8%[>HIK.#<&JR] -M$#_R:W\U?\T5,FCFHM>RSL$*@2%-K_"0G1BA,PC/.E@%TQBRBF.JP';2#ZC*P'\(72_FLOE\L2OKX<7T@/SP^(U]&:'UP%7@DGOUW -MP*YY=*)O283\JQP@_5T8``,D?NYT7-K\R2"//[K1KRTIVEV@DXSH"&@$7/#[ -M[OBZ>;HOW$4YOU10SW7"047;O8C3%SJ!MON38GC8=A?QDS;5\!`NO"6'=L*\ -M554[6MZ7)W$1*G:KGD4;R4P'15WWCK\=DR)N;J&TBU.:YJE(`A=_GUHO=>4, -M0XPPOZ&3[!M1T&?C`$#1C&;3V/]AWEY+`1%YXL7=L'7!,2%8B_&8*@I*5CS/[A27'.2T[N&Y7LLQ4&9"J1Q0RF]?!TU,=SA#K75*8S*:04.@3T1APV6I -M61R8`!S'50C5M?^T=#T=*&)ON&CJ"'^<&W$`59M`LCY4^E05QHI])S;NWL0# -MZ+%ICX#FEB8F/Y!$2OCQ3OQ=II74!5AJR]F61G*=]O9\3!?B\"2JU[E:_9IQ -MKC&"9>;_`G'CAA(_,=?Z7;%)']]MG.N3%UN[\3*7*"$MGD&68RVXMD^FV_G, -MN/ZKF^!<);M[)#;'\`O:[R$\D5%O-30PJB)O`QMINYKU&Z\ -MTZI&!4W(3`XKJP/S=3'HXD9CL/6@!(SR,MCO:']O=A@90RX)75GA5,J:34Y= -M,XF4*F1P-?2_1B,4._D5B/:)P6\12NX+*_C$>>MV09`\BPF0ZEF/@B&:E-4W0\4[:`"/XP,NE=7O*95R.5ULP,:J[SY.&S2W8YFGQLYM7=;/NC]C"A`R[85=:%*!WL28"]U&4J%;,9HF1?.RMC'R!> -MAY9Y>%95CEJVN93J:_YQ1UO>+8?+*"D-CAVVD*HAUZWA4]N[*!G-+!<.KOM: -M>SYO/08USI_#G0ML1E7P&)5I$W<9(L%%\7M0SYJ!@NES,*R]AJ%QVOE8(W"E -MS?8EP6[=QW8XITZ.*:XY0"3=D?D54SS^@*-%IZY8LHVQ?] -M(`C9(7G+I4/,RV8Y[@$PX-,5?2N2MX=_>,;`)!/#Q!!>OG@/+DH_Q)52^R!1 -MZ82D9-23:!`G7JFG%"+`\ZD^G/$JG+V74WT?&$0/+T'(#X3B^W5;3D]"LKI2 -M!&_D>#,\C0#0TH4V)X6^K\9BHYNPJ,7S-K#2V2`%Z"CNW;D%/?IHEKD*TB`` -M?R8M)L(:^2','FF='Y=KIEQAI&9(>&U]B7'_Z`_(QP3`:VINVT@Q,MQ8^W5C -M2RL(PTK'VT3(2RQ=6#0^'6B1#<2UC?L:?HC?DA -M50[9@FYML2)EP1J>G0&SN&)*?[]K2Z+6J+R?:6(X?6:UH0GOJ;$PV!SV45C7 -M7'[B5?^='191H@HG"NCO2ZK4T"+@8X]*C$DI0U[)W2$FOH$Q`P1M.0,T;M-( -M';B[RN#BU@H;"":.5JD#^F08:C1!2;0%_F)QXUHSY0#(+`G10(,4]O`(WO03_MQ-RT`B3S -MN%GE[9=L,=.:SD(-[VY(ZSX$ -M`)-^<>711RXT$/``RU*_46JX5-W\DM8.E,]ER^X6]IY0Y?9TN9"+P@_LN^%, -M0///G.Z\_R=B+(-,.S-+,:,].^)\#J,Q;49< -MWD;>$&F2TWHLPJK8P;Z#;1L#:`93F`V4A86`+&_Z8+`3L#7PS6;U:JM$5_U, -M0:%Q&"IQIA.Q^]*Q,,SHPA!L\3%[#92DW+:W9&*X?C\_GAMK@V4"$\:.\(2] -M>XAN/AF"_`)SM4YS,0Q<_<7"JZQR'57!(-P$$OLR6LW?2T/;@E>#>J0S<#8, -M'!JJK$NS14+,<%= -MM3@[WZA6-P,O3$C?X=.>CPD6?1TKYA(>L([4%]MVU>BW1(N$=5-!,S#H@3,T -M"(CID*I[P0XDST\V&:P[6>^B]+VO4&>;$O5C2P6-4SUEB]/E7^9@786%]=!/ -M+YG!UNY_X>4`YJ>AEWO0+U=2N1O7D'^?P,"\J0^S(R9TG?:J\6(`A4<)S'WS -M1O[$B4HBX'#27=W955Q#9)!C+7G@J)`)1FW'B<^8TS'HU5<+OA=<>;7%?=DF@8;!]FOO)Z'_U()& -MV7F#U<0@XVUH`>H6P?2!K#*@7D"#!N0(LWRLKKJ`3E$MP67*5GNC*GOJ3M#_ -M@#)03X'#1J,[DQ,X6_N!P:4NZUS)<>7S&:K%T$P$UQ@C6J>=/!R*0ZDI\^+S -M\#C)6[5D%($*=*J*!<3@GNS6XYZ<^J=-O&6RTU.3C-AT1:1,R$-).J$DZA78 -M32UT?1P[;RP-8.%K34'MA1N=NM$-T-59P%\O6V>^5'^,;UFY"T -MO*B"`#N2!)`#QA@VGXVK2/^@Z"+K\`\IIP-*C&#O'7[_>V@&LLD)Y9IMF*$AI2V(S2RY,NRC-G[EU>7[P7VT)V^^I -MB;-'M-EQ3O$DU:Q#9)6U^CR"$1!%>!A3ZT0DP/DCU12L*1&G*`S_RT'^N/2+ -M4;(26';7V-KW>T?EHYARTD,.<:U>4;K@BY\W-1VF72.N$]IWI0LK*XWTM;T(3'?O. -M`:CS<@<0C=6SDN&(I''W2==2YV0")>Y.P.W43L,I<:4]8_K[7H/=0-!P_!=H -M3T69LC2#NA1:`__CS8OH*^7(KG((S`5.#98JZ_-&!1TA])X1GAS3T]TB`)I/^YVV&WH@A;$8;_D^Q/A)VKP'.#N=ZB%XER7 -M-;]ZP,G]8YR88&>V%8&/QSWJ'%.S?3+0&JU`PXP?S!R^";%VN?&2I6#1D3'5 -MWRT^KN,C[R=)>*HEM^2;&WV3:!$2D*!W1YB`2KN.E4;+A7CMQ!\&)DOZ -MD3`PVE9I\1[>F.[>DR^N*^YQ8C3P_)MT0E8%SKFTM_O;EPPK%>'XI`T.32Z@ -M56OV?UZ>^0/OX>\QM'BV\+2K;*/6J9!$644\9K-1KH0_F/]1?F,_99FZ!B%: -M)73CRO[A7'P<^4;9B&5@%R$6J]._/U2BD\4*D/QI^&]A$X9S,M00/ULY0"8< -MAMLI__SS?I<^O#,^]1E.EH3L^9/QSBGR$>KFN%%G5"QQXGM>\\(S6-OQ/G>7 -MQ&2]@7["C`=U(".7&,M6X_`4(%PLB/G6U_RYU!ZK_C]M89-&9.FWV@`6&`6\B",YQJR -M<#0SKFS60NL$A%T60R'\?(ZNU&MK8@O35TD9$3O5J`A(B!M^8NQ;9+. -MM:<$54<]J?8>N[B-FY-.-_V85419>"Q$LS/[$GX&:+=LK4E](5OYJ6+$96W0 -MJ%>==AXV2)Z<3RO2/^B&A.`).VT@!_%[`'O&!T,4^3K8?Z*IF""NA,__M"VC -MR'E#]KV:FS._X\`)XB'80$S=P:;^HA7"$O@O/\&^Y`VLEI)+,R9\T56AK[4A -MR/C9J`88BA9Q%:OY/9N=X9&*/SY;8CQ2B<5'>"5]^??YMK2TCF446X*:^XG. -MSM?='8`-;G73L,Q`*[\CL"@X3=P@-%_\[;1\O8#.R&+.RW=@2-^HZ[1(6]ZV -MAN%:Y#D#H-KJ[FBS*+'N`_0TSM1>&?/+,V-Y/BQ7G_,9X75QPS).JP1'1U\" -M[K=')9[/Y;YC@(81X&1A_,%+;WZC1J.60[+^."VIC$KA'3.I\95L#%L38_41 -M%=_V&5%.O9*0FB(D,A[9^Z?N<2#>"!)_/,L\;OIUBZ-T*YC_0IC&N,K7,"U: -M#R+)HS3-`/Y_5^!)UH=*?):'FVQ>`Y!T)122MR;VDWMV:,1_@)&;HB><9KQ/ -MI..]U$H_X.Q2?T#S#I;-0-B#=G]IJ&P6_,(\(]U";99G/$C)EX_N%:"6FG]/ -M>)HQ34*9]<%FC"5RH4],KB)*W^!_R`7E]S,BVDI1:W2<`5W721IC^ABT^+EP -MP(1?IWR)M?.(/?'6+EZ:=8)O]9$'\5BDYPPWA5=HU$U_'(G#C__K)SXM%H*) -MPUX%Q>I>#,P"MNXO4GO1.3;V!FU5K'O7L'`RM,_+Y!_B'*1,7\@!DA"D&,;M -M`OD=H9_,.LP\;3;)[#L9B'2S(B716MN8 -MYFPNPFFO7UL_UODEK9;>EFC)_FE;Y8V<%#7H8>+13]BEM@=:'ORE>ZD&--V[ -MXV4Z6!\?1>16/1JMT8K2I"@'03%A+BA5$/F&B?/?I_861,K.2!4Q1WUY&!S; -MLR4L?I54"(:H8QV:Z*56W[1]X?BC&9YE#`4.9+S$R[:08\T,[2%C4B![W+(S -MF+5JU[CW.TV_`Y`E6'KKG=I[QI'V.*P%Y4AZ]<^E1BAM_SQ71P`Y*6814V+I -M1Y2UJW*ZEOF',J\%O\$H?/P^)[K2+RJ1?VJ/AY//MT]/611^&@+H:WIWX5(. -M]J83U5"EV`TR0))`<"B@/FW`9(`<0]*84\Y=_]Z;`V'71;G:]0'?^8KJCB/' -M"6D+5"P7&?+)A[\+:BF=QBB:_XFYYZ01:MQK_%2XLTY<"\PV9I768ZW/P@T< -M*L)Z<<0\=KETF=HYK7J@].\%Q6$JVT"0M42+BIZY'`&_T<-";*WI%%G4ZLX% -M<).S3WEF5BR:+.?\-08C7DV&CEHIJVY!;D*.U*`F>?KE&%'.%XW3.L^Z*>7? -M,8$(OUOB1CA`K]`R^V1>O'@(I419W[.S6>X)XOP<;VWS(H3QD?'S)>I:(>#!9ZN*!@1,IQ#BZUGX,^$9W;!4,HU$ -M)5)XYHAS?GQ/8^6U-%#GB8L@L#E[$M?Z5E/R75YM8E84.CIR&ZP?ZX;VN&9Z -M)"J0QCSG0J7X173!N*V_[';H+IBS;8:\3VV8:2MP<3H_3NP;6W`(Z+2[R)DO -MF/K"//T(Y0G -MB2B4C_D(OE=F"=2H1Q6;K*FZ&:\.!N96/;"KMC]2"9^J%V[.RT!NE&T)4_)YM.A:5=.288#-;9`0JA -MRKT$4UTDOFXB2OIWW\*1LY(!<@82`E`A.IB:04K3^`[#HIQTY>U`'CWT;@PD -M@L5J?,8XYZ(;.!-*]>B2BBP_=3:82HA*5U3VX@AZ@(%AO[JUL!4+VK)EYN5H'#R,0YL:\IBQ>&\@;8V>4=^*7(P^1]Y0.+WY\\(?$4O -M1)]">QLH"??UUEK)==P&"VQ5#"RGZNL_.8=Y*R&YP)RHR9[Y&P\-:S:/CMC6 -MC)'B7#R2/FK4NEZ\GR3<38-@\*EUH4XI>;CRGT!$O8&AFYHY&A7J2'.M39)U -MF_:M5^_H`!TD]SYR;I]-03_0ET.9N`M(?3]]@CVHTND[F -M+LANAZ`>.@NM,!T4?R&FV5<+'<3"-3XX,OJER,.S,(?N[.)F7AAKT[E&H?Y9 -MI95:"E;*\9[@`FXMZ?3YD=&=$MS#T%)4D1UA.VA"':\OOA76,Y.:SDS*EMI: -M82S#RW3),=5A7QROK&&_#YN3YZ9SV;@WO7N([XRO61 -M[[5[V'G=ZIVQ;72E48.>M.'LK`@'`"9LOT%0=8,QW8)..0?Z2" -MA:PA7S/>#P*,RW^G5JH;<')HO?9.?,`?*.:Q;US38ZUAD:3VI"$_3`_RQ8'X -M%F:S$B.8WTAR6/X>7W[41%Q<8D1J/8G[T`*"HW]"Y6D'3Z[V9/]5%WJVRD[J -MH,8,P/D\/C2W/5O?_7F0&H3.$3X/'$B/GU8&??8!)K(JZ)](5@UNFA*"]->Z -M\Q-I_W(OGL:`7UG])WG;AV]>B7HZ#-Y6H58'1>HM.$,%>KHS;G&"TS:MT_:[ -M+(E8:;1%`X#6"Z3];WM_AJ4$_[)ETJ?*/KKONEB;0-/&;X -M?A,U5Q%[%I-GI<%8V=H(0;II(]>.4"V(/ZA+]2>Y-"/#TG92K#KZ(FK.AY,@ -M&P#E5Y2T'[`XT1G&9JJ3.1#DNN>_$T7D$TT[+81O'/4D>5EU5JTAPB.'%^^; -M\54-KMO-!KP-MU813\F)W:1"\[=4EF-C=SVLS`&$;FVUF(A]A2J%IWH>\ZX90A`X'V4S%`'\ -M._*3-AL17!GGUEK@4MCL:<_LSX)M;D;WC.CQXI*2SM"UQLGY-FS=&<5UU0#? -M!-U[GE+1?KY(/<-KG+G@`L\019BM!A:MDH@!77SU0Q*S-&%WM2'.VUK[)R,^ -MTUMN$0;*L=:Q"+O0S4'DPOF?Y>*&DYT((6WVBM3F_%27+N&ZB7:0>-`3;3\O -MC#E%"^$+MS@(3T]NC`TNC#],I+$_=YG_EMRDTX)8##X`U(6`*E8A\'#-ED1=5SX7%C" -M]R])QILMLAYV52:,FJT_OA<_C26IW(\%QKG*9&_30:HVOS(NW28T]K\@#[(= -M>#\S@"3N&V'^2.3*?=]#92?'\Z"#VC>/T:DX*3QN:I;1^_$-]T8](I#F3^[9 -M8[V`]0Z*Q][*$#8&?PJB/`AW18FV)?6U\FZC#[O?:CGGZOX?`<8HBHUY"4"B5R)F;^#X6] -MP)=2LO%85N88M&"%MGLL -M8N["($EZ!1@H9>6=US;]8'T&M>0+6,`Q,D/1#!H@Z3F -MNU)XX)AE39,>#=P=,6E$OI5VC4C'QR:GLM:@XO[V$@4, -M"[^;IL6SXC#RA3Y2I$.S*C+KR'#;%KFB`Z.2;);/G["01;T39$E`_"#PHE^. -M8?-@U,_:[K0EHO"M-P]O%^SAFWWT#?YL&^F-2$2%@<5?Z&NQ*J0#>2.D6%VI3D)0\^P&NA78Q05C-ILC_[5PJCZW%X -MDN5>:67<:@Q,LZFXQ54SGH&,CF3#$CFQ%UIQM^3J]$[L2W5NY];SK%=]`H/> -M(>+B;XK">Y>>:C!E1K66FHD6+!215CD@;C"@NX+XG&UCVV[AF:T)82%"+6^VDZ!TA!AYP*9B;XP/"-GAQ1=L=,G3_0['9IFN-Q*^?SC+_!E\T6(&@XC% -M>!/O;\*%YE#J6,(6Z71#PIV7.R>&@$U9J -M4R(%W(N/YKO_-$7ZI"G:&:/2X/TF7T7:-+,I9[0&?P'.:$([L$<:-6^W(NC= -MF[+)KFUT8D.)".E#([]0IY;SF]GBXJ*G",3@2 -M_O"`MM%_FK'&R9OA@LTH()2D3CUC^#IBG)01_QB!/B0 -M`@I=G,D3;_K+"5G*G-5J_,QQP?Q_=HO]_=;;`,5<@,.-(,]]\),.9*/F#5>1=!^&AFO7)Q5@T_ZCC%!,(X^K+:0Y -M!`U9S/>Q;R`@?]TN^T@S7K8I0!@Y6<"+X':",NAC?1\/$G^43Z0>TNF@3X!8 -MPAY="T//G?]C,7?D/?\CH4+2S+)+'.\=1@&0$A?JR@K9)BH4X`7`XY`'<,HQ.$UV[)HHDJ546EF2!/>KO8 -MV5H(L6:M3U+^2K+H`_*JRU5*_1]T,29A/(ZOA>J=DT4^-)M9#&L22\]AB8%3 -M&--=>Z)-&=2L3S7''2U+S.]U&&,%9&_-$!=DC2O,?9;(\C]X!$5)[1+3A![% -MJ::QB<#C()CU>CV6Y,$LG$B<>R!:8TGKC@44A78FVF8[1<-A\9'FH)CXX!7_CAM -MT_LR4(]B`;8S3:Z3,`F>GLA(!<1BDYB6V$?N0BU%&7[]K.?52B<1@3X5AR0V -M6\<5.I<S2*SFKPLR)QP@L2J4F`#.AY^0:\!^TC0(&?S0J -M7$&@J>!X-&9,C9J83(COY_MEM4K^:)UQA9CL';?,*P/1`-=4/N2?M -M%:?87WI?@:#1:_UBMDPS1V,F)Z-!"']I(V^Z:/V"O6HJ:4+S3 -MW.N&'=AJV()GMUFUIX0).DE">OZN>%/$A2B.G>H\O1XC%:K;1\7N*@GJ_`"\ -M3.RZ`1M^(D/0@@0!KGH,CB2FLB>:EZ-LZA`V.-*.K;C<#^ -MQK@ALGO2;+)*F1)S?[`10)XDG1?*@7Q=!X/[AJUF&F[J+1;L6UZM#^,I'3G9 -M_4,-"[[F4$T1=E5FP?Y"L7_FU&!B<&EL[:H/JMTSN!B#:)K*GI$E>'I[<=R$ -M!U;6%Q=NU,'MG*5*BBG<,=H.4NYU1W4LPH0MRXT)X?MOSM%6D?CL!@Q5$L/2 -M+A;4>J/L>-J_#^!S/*"E0UZK%U644I6*R2HV,^U0AGF/V2[+QI/K:<5.2!\: -MGW!"_"V;C5>8;0SMXLV/$$ZP+K;O&299F("DJ<%CSBB98I@Y5(Y2TO55<]`@ -MLH7I2O+V.Q(1MZ+R$3P32+000[I22":GWSE_/WZPU.0((OJ&2Z:D$(A08L%(?G`3)M^4#_\[QONQP5YV<$:$O'0FYOI1&9$$DV(&6K;_ML -M@P6[[E#/_PN3%KVT.8[-]-Q11JBFYP_*1EN5&,$4@C<$]Q?PG$^6S'+9"K!8\:V9&TDN3K^*&A6C=] -M:W)O]NSE[1S>?EJ@7VPXP*RFSE_D/G]1>VIC_1![]HVUEMK5I6F5PNFAI[7= -MHL+_L^ZG`.K4-4,#6>#H4+GU>W/F=3$_.)3R8*YZE_\!PW$$1+''10V,H>@O -MPE`L4M#CMV)O.$,>!%]XCH@WJP:&MQF1C-RYD[%I[I`#$X',VE+-UV#?(G2D -MX=`'FU6R@I&+9Q)&-*SC+A4Z&CZ0\A4$Z_$HR#F1%"-,?4+06 -MWKVB'34S`&49_XEUA]XHLD>53"VZ\Y^N!-6"4D`840O;8+;P0]HYP1"HE+W< -M#!=_EF:R6Y4SY\K9Y@G7FS>W)3%48KP.1>J94_E5VC`BI!%F@.Z:20N> -M(#SCV]S;6S*4I8JZA;"/'1R4[2AU!*%;U_0K.SS;"R!K:1M<5J+??N,2`4QN -M*L=L*(VY!-[[>EF@5K.1KMO4^F9+@# -M]$0'$KM)6>#4C4FJ`4;^\V;`K]\X."!@U0XB80`B:5T3'DWA`*<&J70U02^Q -M)V4^"'([(5;WP<)MG'4+Z(:]'"P$"8O -M=#5^M]M04SMA-_$;M>926PDP99RYO/__"-\>S.8%/T,$Q^2G12&P>6+N+XA$ -MIDW[^"I)AA*Q<#.+OD6A!A#!(C#4Y[PPAB9/A,O-\1$"W.^J5C[F1%*74=-. -M(3SK]1R(UA`<_^?GHV)CKX72U<.`]&W5?SES%B.Z0$O)1.P)-.CI!2!F -M_P-QJ&!P'!VQW'S@,GH.RZU8'ZUCC^AG8WI7.SX(K18EY(%^'`&;T*ACSQC_ -MLG*U=""GL\SDG;:"F==;,3_ML"_6"QF-#60-;,AA9GM4TN<_P.SV)+O3+725 -M'NX39,%/T_9C]WT'IC<-3*P`Y:S_G&S<_;JWE^46!F;/"IT$E2[$VU;9AY=. -M4^L`!XT7LI)5$X"W^&"#OB))(?)5#!'N2/QNTTEHQ;CSN.`8$:%25G6&G*KVS*JP\ZBS79^Z8;]V\A@#A\OU'Y,G%`PA-?A_%$1*]<:[63O6U6(0TF2NH+M2)7(%10,VIX8F60)E$OZO%N9;A+ -MUPW?NNRV91"0?.-B_G1EVS+4O$>V2^\."O -M!>LJ%6AKS_I#5)U]YV5C&XX,)/'`D4X!8A'!*[=*PM,FLAK;&?AMW;>]L_,* -M!5)G&.2$P+M^VKK#<89-Q69]"W07=T`>7G$#+WY--A1W>U^QK*]*LF`,-*H[ -M(UG@8KO)\SB3EJ$D -M@CB\V\NDI?R+MA4&`FEN0AIY!F_H9U)F/[\`FQ$NA1HHV8`C"$E+_E=PJ5B( -M,RM0&)<)*[[-6(^#3X)"4'0<59?#=@#JGB[.5K/+/VS66%=:^BWDZB-HWW1T54>(?I$]IHU5RV8-O)L7349H6IVENF -M!YV:Y._K1?-M2&]"X2NQM;X0^2%+_.JZ:M@B`I4C74$;7;G\T:G,+B5V$S?N -M!5F2\N-G@CD6C,2KY,)\PCXQ,4O`VW6#T#)FR5/_"B@X@AWEQ(X!$1OM,6DR -MQ/I'T<].Y\<95<#Q?`R:=-0%";^917*R+T2[HV>R;TL3!XBRE)F34_^X8!&I -MRB_-YZJF#2+%+UA.ZR0O^J3973/6M-VT2R-4_U')D$71QF&@EC8M+D#DM;#! -MZJVL>:[8\"I-`&=P1'OG8I=>-VGXADX[WN330D!X%'*[^`9N2!]I$ -M1L0[369ZMJZE##[0Z*E&F)3Q8D%,,F=C^^Q(/ZU@])I*2 -M4P4EW^3_G;C@$61XZ)R&-(T'T!TX22)DB:R((B\S>G4<>KE6Z-_C*W<%:,%U_*!B:1(8%)% -M=O<;F1/+J4K2+;5#2G+3_6+S/>.JU*!O^2>Y=#GD9,/KE*SHCO3UZ6XQ2IIF -M.+6?KOI8.KN'YC64+L_<.G'WC&T3SB%]ZI:*;\*HOALO;ED*4&TIIX]6\#7] -MC38[&DR0%F`G)AV<+P;*^W)ZVK!V(J=_25*6KZMF8"U'G<:#^3J=615SHH[. -M#;AWX"3%S%NZ^2PKS3QER4`-5)A9JM0.9Y^79>N"#6SM'CM%OTN;,$W -M=']NY38Q9"@)W&_T&=TM[L>GK-M6#DA-4?^&@TM6>D]7Q13"KLG$"EWOA;*+#8W( -M3WV,U&4(COI%=4#BLT&2(!9=H.,V`^N]I?*3-U5;!&:!#OF.Z,?QFJGEQ.!! -MGBQSX^^:3J].\&03SB%5L],8->='RJ_##&HQ_Z4ZA1YGD[<<`K;J;_!\=X>> -ML'O7WH%W#V%XG6;N2=>Q%JPT`,C/`\D3.2:UWZ!\([*7Y9D[;:%P#AII8#5L -MY`-G&'6F5Q"[5#^_&5\2`/PL[BU#I?G@+)YP^4-K:/M\/?AY,?8L:DZHR,V> -M`!2_1L-`J@E_#W`897-*@8:)C:%@E3PV$QDION(;ILCJ[T9W&BB5MH])6F8. -M19;9*E!_Z[5)8597I612'I"WO&.HOHY.E?P1H+7W -MBCC0F:OLSK@A1!+%#MD8$`)QENK3Z8"WT%!271$^=B),$JT=.W(H#N*?(9LF -M3<+Z"ADF`DOJ[31I?YK0='OUKW^8@3_* -MN.8M/)OWRC"@NEW!':EX*%$!F!5GX+\'U"4H&)&$L"K9*/].E4'=?7_]<_GE -M!4V,,)!7X4)Z[SW'!/XHOPK`;S1E./?D/C3\A-<"L=O@"E\I:>D`#5Z.NU-; -M6]FZB..-&>WP9P?M('.\()NP<#9Z#7B\H(.MQP2Q$),0`0]A_\RF=]*[G'2I#H,Z4F--&K8:MQ0P' -MHG\LOMGN:1LW(2!G)?Y%O*7J-KU9_)EE&HBC9M\V#'EH@I$V01+*]8&;M>;= -M@3?Y<(BF.6'UV1(7)OG[!RKN,`3O=6!^/E0(_RF(C(XK?)[+",AZV%HGPDL( -M0O*._T*W*M*KX@/F._18__H:U(=,3E9$^`7I!_O+W\K?4,.J?KC*%B"."-85 -M_!UFH4@6>>S)O_M5K,->>!%5G12_$KO/3&W//>O`A?5YU`,@0JI\:8RCK*L. -M'ZK0^%25!$#7:L"AN#.YB<:.%\>!I&B8@2&XC"/U;$)6( -M]PUI97[.:J8*%CX>I_L@T@YD*_I#%T-K3R#/&#R_L^E.M)6#1L%@L\,4\6JE -M!*M9:9%T"92VRQN;AJ -M6VZQXHPO#YO/QH]87L"X5(W^C9$HZ_OA>"_`_8H+]?GV+!MXX(C"L#;0TVF(9W/! -MS-L;0$(9V,(9%5'%9]G\@FB07O!PBL366W_CJ6*\Q##Y(]9X/^`"34(J78#2 -M.G89YC94\F@/M0%-Z*Q"2VYFA$/(LK11Z@C/C`E#,)TI9)#]!Q:^T++3^W&[ -M6BB$I-\,5`$4JMI$3)4QA)Y'?N[U*;?S,4'%R@M:CCRK3T@+,!4B)>O]+7;X -M!M.R^W>0+,I*0J!N$69$]]P:SUAQFT/#S4BHA>Z+PIU*<[[FI-[_#W>JU-WE -MN%GA9_@3V$UA\."G6!J#ATJP"['"NU>4KK29C--$^&C4IW#K%54_Z8.X9;]H*8-8T2S -MX-XEVH0H0-O=T\O4GZQ?TVX?!!D@R.R5)C+M[Q\8!P?(TJC="H?->>J8#CP6 -MYF0<(L*ASHL!XZA'G@7LFU_ZWP?'"'X'J_IBU>G^D-^_7<#6(;A5+O`1/[V= -M%E1Z9]XC9D3&_U&FCUE:-`W?#ZQ35@RHYP7_"(*N`0$Q@I;(H'Q+6\!KOC`F^.K6PYX).S#D93'-F!E:"TA5EE]6G5 -MD%1#25`N^169'W^T%&2?*L(^%N;$V?P?$4"WT'<,5H`A\>+DD\H.I>OX^H=( -M.JLI679-L$``1Z"#5(I7@/B9]N@AF%;0>-HVE$GW;`UJ>5!1IK>7H7H?F;':,$LJO#$&7BZ=!UK>%:D&Z[9QA;Q"`/W(YXFW]S'=GW$#J -MNJ2--O+DGW*K>ME^6E!%-;) -M-9M'M76*"&Q"/I,,.X``&F+C6MGH=[NK48=X;/PL(S>4?%\A]G8Y637C*UM8 -M1#C8.@31S=Y,5O5P4X$7!1TO]/WGJ=N-UF0,XF0%Y_N%'P?*$5VYD5]L[D[" -M$TCZCQ#JA=O9D:LZ1KOX_1T%EU^3Y,7$ZO[":T:S6]):8J`:BO?\FE`)8KXD -MOKUV?77IB*X8P@F+.B=5+.8S.$*`?BR\81$DV1$7C^YA!&:=`IM-:4ND17@I -M(J"'@)AUAVJLPHG^.CVE6NS,Q#V3X,'>:1B#*;\D,6AJ;O;=2 -M3!I0&&]YHD)CF>Y$N[["+T-#'1,K1@@`M44$1Z_L6`%Q49QKEQ-H.K_7Z-K3 -M9FV)XNGNV?A?7SYRPHTY2R/"=+//,;$Y](:0TK1>9J:0*E+L7*<[0K#:18_F -M<:J0U4:8E9YW?*.M)Z'!$VW`\MH'CX�:Q>C"#OQ:=2GK5C$"P$WG43]"0! -M%6!:W(Y.-P6S`:5SX6=^6$\$K2;UR'V;"PVIZ<]%GW>]60PHC!J4K9E@B+$ANKQ3(B\47:[QV]F+37S0W,AI-5@CKKT]K -MFQ!1)-"NDLF%_3V\^D?W_SS"K"&`0`/_5]$@@M&.@`[B[]RCRWL/M-?Z!_FU -MT#(ZC6("2_XHV9,U60'[`:$H[NOAO:"*_X&O$9@&E3216,'Q3E>I8LEY[)&9 -M`AI:P>/4Q`@/.X`Q*_I)=[.A9'G`DR[UN[FD.0M9TC&?XG%=B=AW -MQ!3(`*\W;Z$H&'36^?F_L8.WJH/(%+J:BO?GIG7"Z&G&M!"2=(MZ4$'''+`7 -MRU,VU\X9D=9ZUBUBY/\O1,6/[R;&;!>++U/]"@94[P[YH.+:I[B&,T6#QLU9 -M>X1>6:D%S;/']9X\N^I;)SE!!VJR>,-XT10^Q3?MZXII*DX;B93I\U);O.,( -M/)PA>12!SCERZ2N.O8K3XX\&@0VO#1J^H94F="4FDK4`E>?#,S*)SYT6\X_^ -M^RP\%0%<##&QJ_@L8%0S)5,6M@8\\'8]TZ\6%N5.K->$8$:P44MS%D@?U0,W -MQ133XQOZ[`"M:U6LSY^1@2N`T93U)00'*V.C%_$@``1_!H"=/2S)4)?@WZSP -MDX"`P7,^G&\X"+W6VL/V5RS9M3NGCS/W@**44#8!:E?4S-I2^0@(,%$Y=;-/ -M][/#J*=(FF'"$UHD-6LIM5,?H:V#\Q6P6)V"M[V`#VY8@RZG[']8\H.#Q%O( -M6TS* -M;RZAJ6Q($3A5"`TD0RWK[*Q\)34=V!DL0 -M%71R1HF!VA@X0%3V]S*T'#**TY]]B<+T+@L"'P5H\K#+6\C&]2JXWCHK[0">) -M/]@%B?:`$D!&:L-0A)?;C)R!I+H8;.U5-\C=[XL[S'G1'!B>G,WQX3!X1@]X -MW_R^H#O7,3F'*0ZZ)4]23IRUJ/E[0,`%H?C-@^S&>4UQBKB:!=)\B!N_=_]` -M+F-_#<=!@[=X53T"TIFROWC -M6NZH;\($O]^,C0B(>=8'MZNZ -M^(K+L<2.S"AY=SR\Z878+U@]TK>Z$GW&JU#-9DN=2GC:!QUF6%$K5#(I/\8M -MP],Y=SX[7VVA]TU*<*]8PB.BP_'<\<3D;JU(S>4/NPWO@DVET491$T -M'9'6E)[0H]\ED[C<0)*8W#G=D51M]*+'^ZMGZK_-^UX]1W_^D$T_D!IE'R;: -M,?Z9P262>C0/^-O/(6=\"J!&XW$7$!J28Y^F(BX-/8J.[JT[(F_$U3./*1/W -MJL46VHM0J$U#YZX8OX)S"EZ-\IQDD_,"M-A:'(82;D8>T#XLX-]!BQ]2`/K_Y>\MT(=&DU019*AA2__B/C%[;CE)PYLQVPO"(*\09#9_A2%T?5 -M['3X;_L#$@VXQYWZKT0XY4HA&@^D#>&N^]1.?X) -MH(_F(G)P617=QFW/]8>#"Z.NY78U(=W% -M1R4J+AIL!X[ME@6'0E0=FY=ZWTN&81`QO`/E3@?!"#8;/4-Y_5>(F^X/("HF -M?R2B_@8\@NUA=ETR$^,*L+)O_BP9&#$IB5&`F+Y/0K=3\F6#;4Y/NO>IC%0N -M:[WIPJ$].4-AA\$Y9-QFJ["ZO-)\(;0&:[9I$,A(<_,HEAA5+'+1"-9(_Y?! -M2=[SZ8.YBW)O-Y*S2290K -M1#%(>=:+D`K=SOD7[ENAKS/V)3E9&8&=58EH`>:9]JHOQ*7\JYROK3-0@$YP -MK1,5K]CKMZX!,,6/@OQ]R<@01_0#/A].T(\"DRW7Q`+%D28K0*TA*TZ=^J(+ -M"@@S06.BRCR]+WB6C*\OWX0:8,T"&74N__^@2-D3U93,$1#("F$$8W0",A32 -MW<;D9.24)+[707PZ_[]0[)!:$N'U#

    )^2H2"@M?6ZH&L!<(N\"XE%<1XX -MJ1NS#S?WAORF#U695CI9!1:;[]@`O6!AU%9^WY.7L:`H"YH1CFB)J&3#D.Z+ -M([!F%4&*<,!80X6PSGN74PR*,<7]MM6GT3ZWNI/1>>_&)99 -M3T,'K/?L/)*L080A["H\Q;GXS/]PGC#N1V\"G&2":NS5LT+B9;H:\=)W)V;R8/,$^E_[T;81!)U1#OJ@D>O`Q9B7[< -M"XA7[.HD"&5_C+PD093;\R*B0'3,Y:3],-:RHK;BJ.+C=2G.>!FL(S/73 -M_[/6+1/YER_'`O:Q?YQ2W'YI3O,[$1T>NYA2.H]QZ,O=0?#_M&1/GDF/^',] -M8NE\"W;]KW/LU,01<$N$JOQ5U(]F7\QIPP/1TE-M]]1O>%=`!QM>X9 -M?%M>$1J.UKZ4P"(A3ST-S7BTYG4?\%%-IDJD`>SS<6TTA8[):6I5#$62(_(+ -M4_$%E8/P(9C.9#*C6$71D=)KPXB?^],-:I[IA)4NV4$(D%2W],>'<+]F"1)L>`"Q[YH=X":P)K:KF=9W=UW!Y`RYD7$;0 -M&QUL$A<._!RE$6>QX@&MDWXVY`K;E'Y+JJ9ZD?3U&:1QAJHRTFP4E -M99*.N8ZR9DGJ?V>"D$:OG!=:"3>W8<))9XZYP,EYE"9G,RP;BVN`[F\\.S=X -M1MHEP/C\.9RT5TW2FTYKQOY;H&_;!?LVT10H06MCD&X,:JOFH$Z`M`@?P\S5 -MU7!8O``0<^\GM6?46R&_&73$MQ`0`LZ%H"-_'#.<]UN+T7OV)CXV^Q&/*G"T -MN@TOG,W6GBL:[K[*%;[?TK5+X,H*&:"S""$7>!TECXL>E9K#"H?]<8B[4EGS -M>9W1Z&SR[Q?LAE5F'N8_--^",OGR;8_KQF,V0EMA,4$J(Y/)W5,Q)!_9"IQ) -M]#OV$C.J('>PUYD6-42_1!W,_\)\(48&5]=4HER.6MQ>4U92X.'BA^1-PB%= -MNT?CD-HJXOA5%%2`VP[C>HVF:4E1;(M59_Q#X3/L60772W]69S`.2[0BDA9L$ON]W;Z>+L>5#K[D?V -MM:L.Z!Y*GEXA@I%G18^CNA:I=K8#TR0<,^1^D;N#HDJHV0YED!:PXK\,I%7!N@I01#6_JO!2 -MR9$5G+^%7<,#MNCM4HIFS%?';)&7U&$Q,1>`S]Z^A/13CE4-,/5\/=7:G$7? -MMH[7:+,.TDU^8KP)<\WS,>7@9'IM`3FR,FXCZ^8WSPR59KQ6\IKZJM!ML*WZ -MV_H;.34+]H9&XEDE3?^Z*_BAY$'%6+(_'!%-K3(+J$C$2\39=090\ANE`3C2 -M"P$=%,N8U9,Q@CWRVC!&QCP<[`]%P*BES!^32S:<$1#J[^H?SH>*7[W0?^RH -M6?8EMQ[[ET-#D=BG3^^EM"27;3H@:,WT$L;XGG?0UD1W.#&?*7_/V5DC+O<- -MVRT1))NJ*O1\M]LN;&E.J*;64W.#7PPDWZP(77%&`-B@2:>!8B#*]A-DCL<* -MO`&H/!NJ\E'A!3!32='O4#B:4P@JEOD1AYTD!EL\",?!/)8]EDX]=IBW3Z^3 -M*-Z#.N1KG%.1)G".C=6]X'`]].UHJG=<'IH7E25 -MDDJUJ&.Y(TKILIF)9M84;K8\]8_^,!V5J8_Q"1M1]8V(>LGJSI'S[[G\2,_3 -M,:S;.^CRB`2:88-WS_%0'BKT@$>[ID]ZM)S_7<$[F!JN8T\(2RK."PT&NY`^^JY,/@"9C=)^"A7C_V")>=@! -M*+P*T!C8$0O:P__=?5T% -M**OLVFD/Y'*<;45,54K-U#EQ<-Z&J69FNY2(2V".98VKO16>0*IUE1:K'_$> -MIE/4<+HB=]8'#DA$F'I8_R->'<8H0!6FEJ;)T2TTDEU^[K4+T(<%B,*TB`XU -M)\!%BK`V9Y?;)XWE#:Q^3PT/SYR)(K1RJ^3O\GHZ2>N'/LM_&-U1E%&>L)DN9Z()+X3[2T[$HN`<0"B,[^E3FDX6'#:^J3:&LG/'W -MSSR"13@SK9!.]%KFPJD\N&A56[RN6O-NIO93U@>TREAIS6DW$8#4,`WX86CM -MA7[XE9_%$6Q8#R2!,(\5W!2;*4_6I9V[=B3)2P&C,[R#WX.2-N#$-A#DPTAY -MTXL2%"J$2AV+)@FA?!BBNN&)!I?ZBD7=S`$7Q":A_8]I#OLXG@I9FZ8GCHN! -M@O=2#ES'2V2I\GJ+P]#&\YS^0/E5U3-.XJ16<<*_P+#OSOW.9'`JM(`Q%8'O]#@-B\ -M.MXQ=R#152%>>"WZJBC%]S#"%0X -MP$^(61^^23%'=.&R(!FWR*\T.2N/',/Q"]Q-++_4\7>S,BKUK6S%,*K9:=12 -M%G52HM54^^<5S`L$7&/U4S;]UPU_*X-E7,E:Q3OM4NA[0D_5'M$:)1HA#Q%VUR9HH0/VR,=\Q`8MP1J@;CCDCZZ:4 -M*0F[+_E,.9-83QFKEK!EN#2AJZ94'@WL]*V9/V<8B?VFG\FJC>.Z$&XPO?B'KSA4:`5$F[/SVD%;-:R$(E!ZU^=**F@ZQ&G=W$)?T/WX5'6QQ[ -ME;_R6/IC9<3ZC_QG#;W*4"ON:]ZCT>(871T&4Q)B&F]<$.:K21$";:;V$&8& -M),`:%"TC!BSPI%J@QV![9['JS+8@80BIYV#'^5QG\Z)\D7Z)I_H$,P$.7!/; -M35_H[AB/O2OPX;-I47V:'@A#EZDIFQ*N/0<0*9SM?X=JIN)[$!/($>'4\.F$ -MB4-J2@M>WUC(R/X'0T:K\NBOIMRR9$`CP]Z>TN(>IO!C6-?V/E<;=&K_>(L- -M_Y348ZOT$6AAWZI]ITWC[P^HF\,FO%AI?8(9UT5^@!I!29"(W8&[VFUX8I`3GHJ/E[\Q.9=:R -ML,YTPGPAPF*WX'U?.*C>(T('#D]#/_(G-9KTX:+ZI2;>787*JUYJR_N( -MF4P6@,BY).E=BZ=-;LXN/,<\'B&R$V,W'#U@?C,Q[=2^[#F[M_^5 -MSKZ2E;I.#N]!'*ZIG-_MU?<*0E#WMR/?/,9\:A_];*1._R%0^]H>;KTP&MO< -M*MSR(940/K*>Y7?U!*M'DKXY66+0Y5%,F_G6]4GOJ[(OK[/\"@PB5?#J -M5DD):@OU(P@5R`^_9RWV;N$ZJ]^%5? -ME/('G3X3WA>]14.?:1)X7_@:CE$,:F5,:!43^"W"*14WSKI,(AC2T5V,+DQU -M6::';-!<9?#-4]H#N[G$S?I.0,*?WL7J:UC)`5'#R%^'K^X\YIPD@.T&2)02 -MB27"EXI+,L@Q]1D\0S?V?J<:0B;!<<65_57M1!)J.M),(Q0<>THE"V;O:>(3 -M\R9&T,)6#,CJ.F2WVM`Y?TP/8B2B'?T[&46\_:AT'Q2*?QOH66'^U -M%LZ/R"&PW$^"114;CU^D_^2HSL:`E_*0,!#Q%273#N,9I8_NFQC%K;G@E(8$(T$Z -M(P-<.U2#Z:"U^W'`L-!D^BFTS,HHRMKGJ"Q1]:3R#+G1/5QE(34V*\TP)<]+ -M]J!?7ANDT>"";RNTW&,_&E-D&M"(.L?2JN6RR2(VHIOWD-R=-5^,`[88;TF* -M4X40G)$P`)37RP!B2%06UZU5J974>WI-=V7@8]?8A=1G_]4XK8A -M5WC9__B_`Q`'7,DY:Z>_%^`?#6[()UI!0 -M+"A3()@:@8ML'VU!5^)4F]/ZO][N&"SM1L#6@1,KVL:X"R]41_E12OS7>13# -M%K.:Q,%"^:-9&=EEI`4#/>4Q/U>S:AC(M$27EE#H)U7YQ`DZ:637)AU^EEX) -M@GW^#W!OXZM!PVN#S&/5T97NU3*B:?'&AV$]2%=\=I2OL:_/:G\9E\UB&[/. -M=TDNGMVDE9ZI[/DWK7RL8B_4B&J2-[Y?KWIF-0V?`8$%QNM!^&WCT+R).LY, -M3\]*,1RH*57I78IZ^(IIT`2XBANTXS21AJ=:*68RB_!PN`+*B8\NF -M1&E"0:XOC0?"]TTAPR`R$ME&FWEES_O4F6H>_*6OC36'UC.YXQL`'.JX<]6S -MRH7H-T*24XCR'ITH[8W1CIPZ_[]!..O8LZ#KHC#GU%UC+0^QCZ[KZYQG`,4P -M>TW#7Z_\G&+ITHV/=6N>2"O7X6W8U$N7`5U>3-L5Q3'LT$F9[X#5_1UNE7=7 -MT(=KD59EV*X/&PZU$B_XL5ZT$:VN>&+G2PO*;J3%_6O/ -M3!)&G*<*Q.,1I7-DLNJ"3C7?H?`6ZE)]D/G2O!^Y3Q2L/0-+$U]@)CL`U)0( -MS.D,2@(4)W&&0#,.3N9'56O6"H3I@R`<9O)V?]GT5K-^713U;KP%B[[_`OKT[?UZ43^]RI$YM[WHM"$%^-43"[)@T\6,.L -MV;"VC$95G(II#]H8[4FPZ=K^"G!`\K">QJ'G$3VA0%(YV>I2%#5E[,[COSV> -M6^G5W56%#7*<.]`@LKC:DL_67`D?#R`B,*'RCOFUV* -M_%Z$45KNJD*._5*-N.O(?P.FUK4/YFQ[>1OR@\HO:49_N"19?1$UQ(RNX`78 -M;5,A]$YEMO"/Z6&@)XU4A,4U&*M\P,AR5B4)6:T?_#.)269>AIC/-'ZJNV_C -M=CV'R.:IN.H`&GH8LM;^@D)*RW8(8J](.2Q/T=-]JK=W=-=_#%-)X6]:00R( -M^Q_2CW?H!,HR<*8/."GS0CUP:N%NU1`ECJU'L1DU<711[Q;'1/\Z@)C=O`$' -M'N?3U&!)E-W![M?^":4LE1R_5K6U51I3QYE#(ZOV-KH^3MPT7J!$49 -MWP\N%4DRI"8]5R!MWB=U`?NPDV;ZB[CVOL@E*YD-#3&;&U-B#B:)#/*]BGIV -M+JG2YYDS3/+!PUJL.40*OR"BWQN*O8=WL/?-XPFS;=RA88^U&,([.@# -M^NDD-YC#_>'=Y`"?^+MGMM'*L++B>BNO(B1G"XNT,7JDSJ/IHX.6(V')I4^6 -MAZPIC"A3(9],IQF!;HHX.#N?\UJ3XH69K=H'PJ"$Z\5\ADTN(<:3`G$X@HE? -MC<>N?M09[CVZ7.1]%E)MOQ;V.SW/HI7IGK+N>2$/7-P6V=0V[\YO5ZBWF4Q. -M,,K1]Q?DYL!1%V'.GD30EH-F1]K+>_-_8YLSJBMZ&HI'*IV44\U.41IQ`+;, -MH_>C>SI@S_`G[%$PM?RYW?_,;&E(( -M>H"5-Z&-SZ@;LDDFZL\D&M?EZ23EB?25LKVPX<'JNX,)?ZO2QBK0+5)3W`@O -M/TG=6S?OD"/DS5B5)KD[E[(?B=J+\9R2@47N8V%A8;D"V$`U?QT[![;P -MPT0B,QO:W0N;+N7,HEI7-[1"M)Q=1`+T/P^"Q0))?;P#3C;X'=4+.NRS%^D& -ME4I*[@D:_*"O&&_U:^#<";+TJCOP#M=M'%&">.L7;+Q6$JL-QQ^`%!\9C(;6 -M+Z;D"@(&'76FT;TZZ77G+\R-AB]HH(]MN:N1L$Z',YS14`41XNXY:4AVQ3R/ERJ,T_;,WM=ROQ -MMF_E6?U+J8&4]^B#2*)1X(^FD)J.#UK@&I`#EH;(!H&JHRRNG>_&:E>C;>0M -M4W2X73]CBDY\W&S1;%YG,QQC904\.Q=&*1XLLRJ)M"+D!R(#=1XXP$$*B6XM=_NIGU0A[M-*6O9[YD:5=]G;U0._V213HFX+DQ%PL/MS>S-3;H%1>,DX)O-@A$<"+V14)"F`0)!*\WYH-) -MN,(;&&",KE!,RHY=OL"QK2_&W8Z0[*I<9R?"'Q.M,3X$3540O -M#U*N"**%(>W<3F*V$I,#GZ=A9/J4LYL#E_7OJ"SQC(M;>O7'H&N*T'_Y[P)G -MM;YC7^?)5AV7/TV:#)D[U&*">!)=58\$.@-7&V)5GT,C+*->+EG=H.QZS%,[ -M^S%UR-_9CP-H]6F-Z91^T/>8D\-.F<;LO]2HG5A!_M29FY.SM/^+KP*"R%BI -M?3?8#MV&)+56,Z30N"AQUCLV8>PX]B1>F*_DIVJ0 -M+6*6?.#HZ<)EI\]F17U>HB%'!>WT=!!4*SYV)D`6TQQ=P89>S$_8=R(K6-W< -MN45Z3SHP\ORC*R"`QE3R@?&C#3%Z`/-9A:U`45^_F@`6YF>`%AV4?J._WZT3 -M&N3CH9/CY%@4B6+H -M.#N@F19H+#]\R%M-S"E5A1CG_D\L.5>ZLV"ZWYWT3>SX1_3L03`),S,_N-\? -M;-+(KTNR@E:+%Q@6I=F7:-)`R_/N^OF&3.'R/M-+QZJC"=B46=&U^1C1V -M/@*Z[#WF!F1_/QPR\-L/UVJG<4R!#&@C;J;17F./_,!JE:7X;;%87X.[^C)U>W#'IX8+UBOC#^*?1K"YVB:#F3"S9F&L=&;-Y%E(/^"8#DFB1K\O+,MC_/5?B+(M;9]!JWW_7M!!OC^ -MP;RPX\MY:`5J#A<(1]"27@7YDBA]GYGI^\%:M;)-_:`"WCD/;8D.`V;4O47)#[5:+*OP/+W4)+OW5TK^6$IIRFPEM)G\5*/\_5DSSYX%C]H@.7SUPSH]0_5UNED7:DLA_:UX7<+Q5 -M>4-:W^$U7\U-V40WK8201MSHE]@-]"@A/!\[RB5Q39!2;]3@GQVVQ+N+E1 -M!H@!.Q(CE+3%@ZBY@"RZPR -M/`I'(W@:MO"&OV/J>SA8%W#IMT1F3_;]"0\$PZT^,?SO8Q?+Z!QMZXJT)7=9%U4LXMTK$6O@:.(KC1CM -M1V$67W28J80_;GPT11XB?L&^6Q'([>U/A=#%&3=LJQ34:\?Y:!`0>3Z3VAF4 -M0#;,M/#,5W\P2]YJ+^'$!QX?#J\=1.]S"0X*C^G=PAF5[EK9^G\:U;Z@]+0D -MQ&@N"TZT.A$=T&F+4(MO*>.5AX?!IO)N%1K4RK&D1X1>:79ELOHSIZ>LA&=4 -M+`\5"FA:SQ]XHQ^N8*BN^H6!3\-^4?A65%=?-B56L.E+Q.^7PK!7/7'&484E -MIB417<&.J:S\N56GV>0KH9-PM7"8:A7,BJ`M2^3D-_M+#!U#+9::<[:!V0G3 -M=*'#8H<0\%T"T\\"A7H=?UR&KVBH?4MDYA1HO955-F.,8?J5MD5O9^*X[N98 -MMTZDW`I8&QZ\X;M$/'L<=^@*\.MP]"R`>RPB*&R-OP5[66]'"8"LQ;'`WKI- -M/AMNJ1&V)-T.&`(L$?3M8NJ/E6Z"C.C0$M\L*4(7)YWRE'$-#??6S[B[?ZU* -M*!35>::K71?HWL%V:Z[XC=5:BK94FBQQI'+X,P^2ZND9HP*T*P[,',<2QMLR -MA>)DY@5;#W8'$!I:=9S&`D=79&?YGMZ]OW.##8&*'QL@<%J$HVX#T"4JTU*O -M:%YIW2&R_+&V^(\R:0_6GE.?:H/!!4S]T?B[C]W>!4%PKDHC+VV+^A#2`# -MFWXRLK+LT3.,#/ZN3='Q#@!P4!&>^"A]]A^Q,DOWB`D1]^;S:A(._P-9'MSP -MK&!1\:ZSO'?$R\RZJ!:9\L,-<8PX/$$)5!+M:GHTG_S82$M[]GKQC?I(!EJ4 -M[G7\JO"7M%#?-.:\/:\"'J"V8'9,?QEP9&=K4#S.XMZ:D'#CGN(&'CF5T`9$ -MLX35#&*G9-^@H#Z^4\G0B+$#[#D;/9:B*UCI*3%U!,4$>ZG\9?/0MR=QUXJH -MZ5T-^?+^=S]5#'#`2ISOQ)"RNB1S(C#=;T#30`E/+S=]+OW`.S$KVT\K41&Q -MTBQ.C$V>8*Z^#$DY%3YYI/S!D&?-JR"K74/CR2F([%OUAN=XVG\MV^@4@#`H -M&_A%&:V#F!<+5FW&'*[F-\/8+D(PG:XZ6!OW*C018I];-6>7ZU>JS0-(?ZK? -MHFF?/G,G]`RS4K=.Z@N:==NAO.5I3'+,J@FOL^OI,ER_!)L -M)EEJ[T>&,&W"GGB-$^YT_C>,6D+MRAJK9\Q=6B.M)EM?9&'8(W[&K'P=)O:P -M<@7,"T=CF-CLDFQ=>24;]NQF(0#H[3KH(D_HV2Z'#RH^W032@[\Z1F6[L\EH -MHPHEC@5#4?;1ODE-#Z/'0"BJ5>/AJM3*N+!(@3.2.:IP56-)&I&.1:4O5#@?G$\029$#$;0(Q^P.W7=!>QBA<@\H$FATV="SULC+^G]E$E-1B]91JC -M6]=HV5[A0EU8ELEYP2T.=<,:_=.@W_&62RU[U[\&]?E(A<'6!4`)IZ8"4H(K -M67LF,"2)UM!.4Y([$?G]7CQ)W4,1AY5B#N0&!?PP/QRP(B``05054GCZQO[H -M(40>51.&8^!Q@2RF/Y8!?`J/]A)^V*IS'-%,,%ZWLI2XZ\:"EZ>X9FN\:V\/ -M(3/(Q60:G!`K(C&!3XX"Z8ZFVM'X6&9)Y6_IP`&G-&W%/E@(:$F8M^GFWQ\* -M0I<,+2[CUAE=D47K1>$]%GK!L%JQ'\!=T*@2/&=15Y^(:W\V9M"/U@IKWQN3F3%;0T -M4OFDCG<.S'@"OVM\2[P3<3*:"X$4,5+(ZZ@7*"@;!-\#P]2I(0.ZF,)@W)KV -M2KUY4C*F!B"'4MRREF:S/-IK"J2ORE>5.1P>'H0'1F-]#WOD$?(W]AC<[A!-CX -M7`\=!$I=3H0C7!9$NI%!PRPU)&*SCH+Z'T@>I.L'P -MD[;3S*S49ZHCEQN@CV\WAF%UU&))&AFOFF,%C^7UT_(&[P#RCPW7\5)SNQ5R -M6"@&)%7P>>`*RH/D79/E*34GCO^@F#YALZ%5XI1MGMID#!\W?Y]>]I?TB@&Y -MH%YF5OD/5+PKC[^V%J>M5Y74D7#IY@1V[&-^[9#T8!AHK3%]YCO4==#"]IYJ+9]T7,Z-('\+X -MWPGL3,+7?=^N-K,50UZVP[90G7-)G>X0NUY#7CN)3[_& -MV(DS2QBG"!:;3X\\9C]:AZJ5>B=_7O%41-7K^2I'B((&%MS`)C"Z%XOV^,9Z -M4`\(088*Z%@][N6HPG?_LX`)J-'[67FP#>@?L`%#*E99QF>6\KTOL75N.>@T -MTUHD`3SDL'6=H9$C#GR0A+J7VQA?5'].X.N5D9^1G8"S!T#DA`M`&XWLD>79 -M2:3VKB39[]\GZQX;\69J"-XRD-.@+'6!(@D7\?5F>UQHDF*6M[T8BZKS=^B8(JJ!4PG%1% -M,\LQ@`-\W)NW8:[LQ_V"LF8O+8S\6:::)#LJ.NS#E[>`=-WK1144`#6+KN#2S7.=F((E$6L^9QM^GO.TW$>*@4?!0.&KD*B"Y&DN(T?(LL:[M;]]%6 -M5YP1#'O:E-OOBL6\8>;A/3<3CGD8!W_0C0VVN8]D'6I4&Y[\CIS+8CE@W*>) -M(\M(*A9=9'W!$/',:3)&OX9DF='Q.+#=WWS%>(O`&78#^B#K8`_GKR,R$5AO^F-==.2C3Z$:,&& -MQ,_GIQ$*>XO8>;A7Z-/HJ.*!^6V$[*O9!LWZVH(,OBZH#><.O?Z8KSR7.MH\ -M)O\(J%D)'*11*KVH:JZMM"YG]WLDKEXN5U1STGVMXZ__Z#/E+/K.%.J-C2W< -M;,U:X&P80GH1]]8?9\:EMWZ7+J=ZBY=U[N9`O$Q@EP4-&G[B`SPWM2A[)<7_YLDNMQ^'4SGOZ/FOAYS]U.IWN/X)N8^_!D% -M"I%-#@?9:F'7U8RNU8@+&!?$H,)Q"N\:Y%]GFX0I(Z<0R`!5^$6^#7 -M<59V#"'?.08?7(7!T\A_-U(IZ>K=-JW]M61!,A1!UQ;8(M+`@M3P59N5ZE:AQRBRK:O.BKY1#J3F&H8U(0D -M'NH?V?(A*C:3*GAOR*G;7@7*4*JCCVA:_/[#Z[+'>VK$M7A&V;W,A70B_^UJ -M`1#'?HPCCQ5X0K?V0F+FO;\G@N+%%BJP7IKTF_ZDP7GZ:ZB==R21C%XJ$14E -M[QUMIIK%Q?SC?:JE<2++I.=?ADR`?,&%R9M`1-BOE-W36+/.7N\094Z$206@ -M;403H"1UT329]XH//>ED#'2DW6<@R3;O#'NQTCQZ(THIS"6HQES\!4FW,=9&=PC+:M#N=1_5%&NZ1Z/H2`#931% -M@.EG$ERG_;+0CC<)"$5[`8ID-!-K/2,]3S5_:Y0Y,2,84BSB,[ELVCU*,_/Q1F#U-J$U4WB>W%Y1O)(E84JDIW,PS>`8 -M("JH;UC*`R<"2Z!RPRYJHBO"WP#EVJ^DY!JTBSA[LU0(C>FR"-FY%L,738?' -M5WWX;65P()F,K>N:&ADVICL&L$A&63UG"&JP>-!?CC]+J80,C#GP5OK>6.%6 -MW?+J7K>E_$Q8'`C%$E>)C]5KUK -M?R^5(U/?Y6I]O*>)YPV0E36'W`23HQ -MXDZW09\;(G,QW`]I`+T#6_!?*97X?@BKE#7R5-J)\'.I]F@SME*=FV[*CG/+ -M+?-/R91$51FA80Z2HUHE+D+C$X//2U=$`7RQW\.0+HR2[L.`0/T[U.29J]') -M_D.G[MDK.Q=:\7?#+S1V547?K(1E"&0E8^\ZH`'\?DX<['@N.ASVVPL[+#=' -MGZEM@"38N$!!2HL(C.C;KG49YQM92O,CV3,20(D[[0,["D97 -M.Q.-LES2W'])LJH&!R](167EF!'AZ/(7S3\;Y -M[1`QA*3'5(YK&3JO62_(<"KZ-\P(1.*\::Y7-/JXG/C@Y?]#N6D?HK!'7 -M3[5J2":%XO(=%5/H1@@U_6'J&()0I;:'7JGSU`@=A:W+K0@3CP#+$WAR<@SG -MRR/2]E=%NM]4F0CIYPT,7[Z\]O$D;,ZBH7Z-:'B -M(/YL"QFY_53=0>JM\;.??*7-S3QE9>OX/FNU -MY\*QG3+YWM<`9?3_W3[H\B>U.'G(A6G0UOU% -M"T1-3WYUN#;>,8U*]&4ARA;^ -M@H_P?!0RXMJPLZ'`UMEDK,F\KB?(@[]*,$WL5A228S=9/:%S8G?Q.<2!O3,A;L*3FKVGZQ$J-"YLPX$M2# -MD'FD:OR1,9PT,0VT*ZGB>"0^TS8VH.^8*J!D__?6*3$?))$&!($UK!0R\6#I -M9U\V:9UIIV.R$4XV3S'/9&?C;9>2BOOL9,H>,QVTA:/P<(=NW[*]DC)F\,<+ -M8C8ZI@GTB^RW:LZV"[-=].\@":5A22`9?QQ/:*=$R!.:.+?V[V><`LI&TV;. -MS\_S(NY)2A1>6A(G'H1*#N#&(MUHXQU9SP/<^=0,^F))O[]-\\5?'PGUXC85 -M4QW@GZH;V'V"P)C%'L;D-5$I)%&;TZ[7B)(P[>'Q=6&%N3R`Q#_8_/;X;$4N -MFV#C(X'>X*@6->&F8C9]>NU&MD3O_3]_STU+BKE&^K^H:U=,M^Q.AYOV6FAI -ME^YE^%&'O%TTQ=A\J0I=6MS.S\0:4CT33;>PR]J]H,7/Z&T-1Z.2'XQ^DYEG -M-\YH]K*@C"8+GB+;Y(0T(EO%_7'L8EE&S-PZ&51TBG$CV?9J%+!5OW+[!?;K -M.&?'!IW_]E8#``;Y<0G#XEN$M:E]&45OJG-312&*HQQ(+A`L&,B%8Z5#3F.W -M"F].),.]&V`2*@$C7`C!HSTCRGY\'O]U9^VC'<%2QE+G$N^#%E7PU6ZF/75E -M7*GZN-1M;$4BI\DQF+2$ZU5D!U5GY#M1K]Y:+NA06XS*EFH`*E.DK&`Z[;9& -M@)J7?GOON*'HP_(6SBU68!AR3''=&X:A59GM1X7Y]_078.`@>')CYZ]XX,NM -M=-C)XGT+0T;B2A=D5O2[^Z'B2-G'-*I8:0SU#RNP][Z"+@K<":]]F>3V0W!` -M%="78,H?G9X239#3>?LL958GM*!.D)]K)HLH6[N/BQ%D^+:7#%:_SWPZ7P,C -MKY=HO<3M;T("@\/"X8X[+Z.*B;3ROIDEKEWN:)<$AS@K['H+D5TIM*$P$3', -M$CVM-15M*:K<^)X<4.7P4ZA#`"CT#,!61X?R#^#V2B' -MQKO"%TOI]T)#91RS,LN1]976!1W[J+3340:HP-GQJH!A7+UVX4K1FF2@IJ14 -M^2C8\5M:Z..UWX].YW>+DL97.HM#[PHWCE5O/1[SJ>9[6G_4&>J -MCB,\]T0_PL'F/A=A_"XC\5/]2I0`X.E#0&S[N;%P,1X+/]`2^?6*OZ6X:!Q( -MM'(8G-GL+_Y05KEXXD:37%C_B+`,N`>M._V!$8P#T_"L:LS^9*L&OC%GCWXN -MRR36:$H%/S40%KS1\LE'[H1F@E/&MZO$WJ!*FY?CBBB=8B*9249TP%8FI4:X -M[`)"L$0!4M4A$\=SO%QIZ47SB5PZ[4]JNK6$]YV`3-NJ<[HJH6YM@H*1JV+5[?BR")@V$8_*HZ$[M1(\R+]NK=*')B&4NK8RR%PSEPN@?K?[M'S-R] -MR?V,8ZP[UB6"!D&G-'GI4G^7\>#+R@V$N<#0PD/\^,0:>)T/YKPF -M"[D/@E[;?--E+0.FHK=,B9`SJP$O70&D1_)%:$F4$X^Z_1^,2%K3/M1.?^P\ -MO32-;PH77*$3F%7$G"9&&%+->@4UR)Q\4[8PH2Z&&G89]<`']DT&XA_I0 -M[!/%5H`COWMH;=8?/*OPENOQDOW['"T3UW9,-!M5)@!%4ZH#!`)"^X]9Z!,$ -MP4FT.N;+_ZU!3Q<]9]X<\@B(3O19C"=0\\):U-_#Y6/@GAV3!)$D -ML8FB@:WY/ET+/-&=7QJ6^*7H\[=2#EXW_O")9S^1!^"UNV'.) -M2F<-(H)4@M;)@NGYP?&1RR:MVH;[3`.;P_!!N_$^4RD'.-[5KEQV2"++U%:[ -MM^)+M>76.+&0=>4K:I*+1OK/1H2NZ<0;YEADH>]Q#KPD_6KM2]_J>$2R00(> -M,X2G9MN3T]7A4E35UK26?VL9L8(WR<0 -MNR32\1QX6!U(;L+\:.&(I@/=*H;OZV15H<\_6483MSQ6]A^]D>OYDMXBM0Y= -M,!:F+A9;GD2#G$PY2QH?,B)H"OF;D3=0ELZ8\;@+B-!L0>^`T97!/6YTLG"8 -M^(0E-/&"$\7BCX,SX-%_NCXE%Q8,$A(Z@TQNH-HIL(I$MUD.%G6)JLB&TY\^ -M@6JN`I9Q$R6Q/@JVA&F&F2=08#I:8U=-+$MU[.Z)>@#RA2\Y/ZGT,\4DD-63 -M?1S)3IFL3Y"-X_G(MNO;*5DQ@:R49 -M_-O\D:*)O$S?98'OC##5W.XT4K:A&1@E^,JXNVZTYKHSN2`DN'U)E$-F@T=& -M471+J#E@5!04`$9G):8'SSP:,(L:+XNS?S`TS!B+WR3YY8RXLMF=RW)^,;F! -M%)L4L%BS8,]TX#],=V.\ZBFYFQ.0$RBYO4>&Q]WV`MHE59],3TUT=[T -MM^9OD)D5/)^E5HC_S9CNR"N9X*T=LR/PK][?NI#(V:WF>QBU570<-L2[/U#9 -M;2_,N]Y7=J-O[6D2@O@J[O#YE8Q_0_,>H8@[>S=NO_=89 -MQ:.NZ6[A@=8C5N3["`!AX+F.8]H,-IL\6W#RVFZ89/T69P1KU<]^YXIIM6E? -M?>4R2K+"QCFMN7VH).ON@=9Z=O<.T^U1PZU#;7OR72MA;L6-8(UW/62IU-:. -MD&LHFYF2QN?H%E*SD_VHR^KE`=]K^ABCBPU@8"2;VMN_RD%B$#G^H:8:U\ -M`2#6PBII/JZ`]S2"GFJ=`T`R&T*^W]..$@[D,OA!\T9Q&FE^5OYD/6A<%?L: -M3$>YT^YRO+2%UNFK?J*GB1UV -M(#WXLDP3U30E3W88`.!(+>,2[!/2L"!4NA"=E5K]Y#X^J -M>!FBBFHO\WQ@*1#H\_/^'U5NM"'F8D7>=EI=N$8ORN?UR -M)`S3/G()1G>8Y%0!H^P"N=E-X@N6G*1]=FE.O;,[W5F<7O-"55ACXK52FJ3I -MR@?B72`BT*UV$E:2#7F(\O"/`6[Y;//2U;!A%KP@[?:^4'/7@/&T2$2Y=%DR -M?K*V%5=:K:QD!5V?!'L+#Q[>=!^3)O9O0"W/D3`^3_<6;]>AMI2HWU[I,4@#WU!!OUZ;UH7M-(N*1$E[]%A=3TIB#[7#*I])[+'AK/W=Q!IL!EZ7U]2.2VZ -MTX$_``R:?",L']:N%I$,?XP.AH*IJ8VY4>TF,QR=35T+79N#A%6C6?.CNTSB -MU'OF.T'SFK-@Y+@P1T&Q\(-X$-!D\#%Z+P)F.'S:>>=.8Q,_8GXV%Y],:*2G -M@`9I1L)6?>7..$XEY>75M%M.L4-/CZL4R_7$,XRLT[A&A;),5G.9>_"M2&A0 -MD)L?`$50R4Z76A]Y/?59YJ4@V=X`)P#P21T^$YMVLFK_][0T"]YR+_C[ -M3:R9:U%3F@(GYQ[!>&^+ND1/(^8>K,B*9D=L#E('?E%J(RO!% -M%&/T<2/EL4=R'H+>C26#(821+8U%A2U#-VD^*R1!K;-35-C4MZMGO/2G+V=P -MZHAZWC[Y3!)@]12^FJIVP^0:A/;_`/=7U4GYOA$&!YQ)*EBC>LA0X+VXCM+?$W)\N)E*]8G-TGC4:%\7=/`$4[(F=0 -M6P-,"H\9#XL^6';TI_,;+$HJHD-H7^T[*V8%C9`79/GN!K@.+W2"]HPY^XV' -M?2#W3])(6LO;'7=^8AUJ==LEPYV)U?,V/Y(&^^\KR]7-8=_GI)7^HT!\M#$M -MI`9^@OZOBHQ]=EE0+FK#-"=C771_<"#MN`2+Q["WZB+Q:DQ^TX]P\..>%6-` -M52/*$$$F_`/S/MEYB/CG9JL+2O6#9#TLQ"[R>+_8"`^KY%(H(R/"2'U/:S1H -M![DS`K'EVNX(K\6M29!(I/EFTB"J5Z^X0ES>1M!>K:B/(X=$)X.:N9MX -MB9M*L0YS%'%NXQ:*#AXWEJ4A#D&9D(/S,??F)&CQJR5Z5,BLY^IQWH3-(!'_\DB/W54`#1"_Z,2ATKTU_&*KR*:<.,X>GYKS -MBD(4_J.92U".P,[N"QQ5@D242?DHD+C6R"8W:9F=JM!)3B>[$<`=N31+"W5. -MOMR9FB1)[/*(4$NX63T+RGQRJ_UJ[[8KY(<03@EAT`ZM!T48Y^P_4(,U.P$; -M)RSA7>C42*%@M>]DZ@^SXF6OLB.YU=E]R`ULWIMW:4,KZ0`_Z)^:_R'%SFC) -M#Q.RIL[6F?MS?"YFY;,@99T:F:.1]_X8#]&G3!#Q9_"A8M#!XJ3S#3<-^?_M -M&E>V-04RKF"?<6%$49DV1\?"SS"FB8X848%9)K>:4OJ$ZYO]?#:F4==>")%N -M^06U@SNO))SW[4*I(+_1VW -M3LY8N@BTJ3_]S@RH'?.6@GAE)W$3G`?2CP!"4E3[:2LR8>,RQA;KYAI*_7N1 -MO7JX2#1B366C7#(TUWM/ZP@F\"3\)J^.1,&T"\/87;^^FT1>U)IXM5Q1_D@. -M-#"T'HK#^VZ':-K58G5C<9$Z28>%]C"H3F]+YC@\EUZ;*8HB_'@4>O->'LVX -MGZORWVBKJS8G`0]&R]OF5[X8B^6J^[U$-E;4]P]"9@IT[]7I0V$34D1-RWG` -M'<\61[.35K?]]]'$OXOC -M^*[7L$<]&I42EE7`C[^"(A4+ZDKKT<'CIGIL>#%TP.0D3;QP#+=I@3ZVVP:R -MZ_YS9B-RN6]V:9*9[3.M9`5:+V-5-(>,87Q['7\]1";]PA5UB:S\*DMK;*`?8/M)51&\CAT'6#ZV#F=KI/_)(WG[ -M'*90XCQ^E[-@->E2\S3M,#C3:4!W_7.Z]'B#$.51`2RK##^"8K3`_^07&MUC -MI!T@T;?]O$2*]FRN3/)2MVZT1*//_"],^$0S*.O^IU_[=['.UH#)'!Q?P"2@ -MRW`.-3[W/O`$I>02A*WZ*G_>B#0*'YRV>8A-W6?4DCRG&MYPO_HZ[1VKEVP% -M;*@&E*_>5M`YHH,0]93`>A/%7G+D.K1D[]^(SSB`[P>*$);_NUK]O`_#K#K) -M\5N&@7K#)R_PO+(=SJ$(N'E##98N<@/1_&1P,>J?TU.4;M -M$0WH5ZBQ6AZMG*#&>H%U6@H2RU/^3MZ2.)GY/EQRFU+*M)-MOZX8&$W3=;3V -MA$C[!\GHKWAWI:Y/@RE#<30+M)STQGO%:T;#3KRF/.U_!;34T>DPRI*U\2Q: -M5>G/"(0:S7VR;/?LROHW&#KT/(4#^X^`'/=YY$.2B8MY'&("$Q]L4[IQ^XR$ -M8=B[;B;FR5Q1O;J>7KB21)M+$27UW2=XR$6"5CS5G`]:3L,+-VD.B9N98%H% -M>?F(T=KCXVM!%93]FT;RBWITF?:O-I+47QI;:&U& -M=V9R"8]E,B?*IN1)-")*0.2^1;WAMF7G?&:9R]O[N)CTK.#,]]4(UT\R2\HX3S"',^K\2MI1AW\"=>9@71JF -MFFC`@DXBL>`WS*PP:9[`3&4NBQ':++5O^J8\S;4FPQH5,>_T"0+U.SP*#%2M -MA)D@<'&[C.APN\F"V2I21WMPBF9.GIE\>'K;^`$4"GO%89&J)[YECDFI76!0 -M7F^!J)OQIE;)ADB=G?S`'7KG?JTO2+AW7>.^140RIA'?<8@3XC&?!KP\?T-# -M%Y;:[SN$--W[55CJ>X])Q3.^M2QTHVP#PU-P;C.62XF4$>9K'Z5<):(,MG0[ -MB"^8\,*/)<[GK$TC1-4&7==O2SAY1Z`C:N!B:R%'?0:Z!$3D7^?264#G)4#J -M4AWE)3/<&*K>0JDH!)=&#?CN#--QU]$B`JJ;+G7LJQO1,![ZOH@]H7J(X)][ -M.&_=*`V+D<_N'LJ -MO!@_:I.@"A=;[/\_L&<_.R`-EI((6UDKF:%8Q9C!?G93/TX(\,'`9T6Z9&[QJW,\Y*>EK -M^O'8&-Q7L"N0!4^YOVT61>1WN=D$<,S7&XL9!LN_UC\==+[3I^W1K,9H9(R]?H\89PHTS' -M6!J)-[1RUJ*)96A:['8\-3(DZM[!Y2B&I8VN/Z.%SJYH3O&6HK)?.OU+8][, -MQ_=;O2YHS:@=G:22)/*"^:&716Y+/1VU<@#-KX(J^A"Q?Q5[S3AQ0&50 -M4CC34R\O3`J1R!GK4E81RETZ8V<[C0= -MSW1:M[(AE%RBXY827KK:>C8^@X(;%O!O?LZI)29NP^S/BK\65*F,8.;>X38) -M@G?6T6:M$U>Q0;[MC5.(W]\`IE3!.=&D!SF129!'8&DK,J1IBG("0GVP-M2F -M_P4N90U#MH3PVG9%6>XWWDPEQYKI*#9()6U&B'HMO(Q5)M\./05< -M#[!U?ES-EN^L2S:+])/]6R`?^';&]LLAGAD'%% -M,MAP-BZ31&_Q)(3*A98^)O&6GJFF`AO9,9X\3;H'^?Y*.F6C:JM#[5>,B`]9 -MWR5.'5A8UV"C.G0F`C`J'ITDM_,LW`-`G=%74<.2N%-H!D2-.(TKW+YC>\H? -ME&I+R2#_K#Z4$I\C02JC_S+D\&3:2(3#$F]XKN;>$[&TM7HXZM+8P-3P+G_? -M0Y7\A>0^\V,]-0BT'-M1U.PD*&)FBH%?DMB6_%-8/:\;L."9`F#&*GPT^RB< -M_#BL/RT2\R*:!X/?",P*V<%`9];A:T<2Y\E%]S@`H>!Y;,_]?B<2`X?,_G;[ -M`/F30OOCH1W/)F#4U`TP%+E/(:!0@ -M0517)K-O`4T&UK=U_G!31JGAJ76H%3?<$-\ITG>V:-%6\^H-HQU@@X#R>J$O^9:&71=(N7A#/RK#T$EMA:^Z -M:Q6)-Y=?FO`F.A09!&DHM;,(DW`2]GIF\>1(<%[_U<7R=AX+K6"TZ -MLZ^C',#ME./$LZ8:S>(&WK%60=I%)3=#[KS1ONN'1>IL+FR1ZGX0(S0X/.8* -M:1S^[9>]Z&6@?Z:7FFH<]'AGHHTO]5T=Q%F`"OC9*A]+-F_G@:5`K?JV -M^*INTGSW-FO]+0;%7T7FI3;.E*/"'?W^RANO?\`Y"%P<>E1Y/0&8'[F9<&S, -MEN_?[KUM$'B3D)BBRX`J:;H,3U'.D\-BJ<[3%Z.Z>VEJI`B!;:8)*B%6/$R0$]'K^X@L_#=,__6%F5CNIQ7+L3U\-JTZ?W_5]1T=8Y.2#M9*2Y-"?&($?N-0>M4IK'PS:;51 -MG=6`F3XM14?FFE!5M`;7SJ5=L&`Y8@WL,,-U>]+D5N%L\WHHGJ+2`_;)S,4' -M0=WG.8TOZ"T)5VSH)XU>*"_R'GA;2I2X*V?A70G0C%JG9^/<3O_+\8A[#J_" -MJ]M4ZP$0$V&]8<)3R_CSHMG\%?:OHK0,%Q.52)*L+Y/P"L-U&U2A6`+J)0A:/4T;X,R;AZ_6/?`\RKL%VOU,J%XT].(?D> -MW9V2(O7SL[0T*_''1W0H4-+?;_4WKPZ*;2I]21*41,9,`EF7N),K,V?4T9E_ -M4%PF-_F66D7I--#5D)O5P=P<[F*2J,K"OHS_\4B&QB9S.-M%)MC(NP2X1RWBK[H+H@ -M_=^)U5C"OA(3.*$U*7<2U*XR/^,/"K^LAM\+F[6VK<1Q[W`.5:__AXQ\X&^C -ME8>K"T-^EPQ>EW@%AIS#!FQ*>H$H0W\I=Z#WY:2&^R+AE*\+K`;]&-G@(,K# -MB073*N=0/:%'4]3BL(-G*IY:L/6W^B(]F:)RICA&BZB.!#\YY6,KO5N?/XJR -MJ2PDEB158\@3P^Y`M&)%1=N>L*,R1PY%5B3.+X)N'+Z0$U`QA&)R[]R0#YYLXF%5C_CNGF!Q'3>5)/#HS&EC6@JH?0FE5P/7]O`>CL7Z[ -MYP<_'D2+ZH0C077&TV4/K".CZ#G!P2S[5U_Q@\Y:R3$^CI?R&(!N/9Y62+"R -M,K*Q]DK`3<`5LXB<4+JE,$E#I["E.FK5.B+T)++="5\$H1"*`PNL`G>_?M`+ -M`#+B)`+AAZ$M,@66Z'RM'I);?0>$4G)7#3OGU`6L=3;<26:"\B%:"B583:Z@ -M#[L=@7OKQ-9H0/6V-A+?0_ON<,G2^LX)U& -M$&7D7K+2:9AIXG%"!=[_RQ:7OD#K*Y44RC<01#[]P>4INWN3OCHN9+-"ZI!5 -M)9!6%]D()H'6>'TGP/#J'K9COIU!"[.>5A-$29H,Z"]&1>GEOA4TLQQ,%,7D -MET(@$]E?8*0NJN`'<1QJ'XM1OJ=3/R?(\AA!B*F*2<.PU,_MIF65MXY9!'7M -M7RDOP);_F49LC56[8"UL9^>9%UO45R1^75K=6S25O?&E,MM@MV$4R7M$X^H[ -M3SH`D[:H>\)[QO^1_I1M@A@1&K[#H&H`VY`/ -M)O\PXWGFMK4ZM@/YL#>;]?AF$+HCYJF+OC)AH@(C]R?4`<_!/9XAH`^7, -M&36%7?RT%X([<9ER_H[_QWJ\81\VFK@GJY&#K:Q7*?BRG)B4['=+3E[D<;-;O_@W$&%8#(KVNWSJMA>&(;P!2XDFY/0Y -M:QWNX*$[#3R)W<(ZPFEH9)NT]98(-Z-C33][J'K63!OZKY&"@D36>I3T9/UZ -M>'3[!GAI?AI2_0#3T@3*L1`3E&H3Q:#3O=:.)Q:H8)TP/8AC$\7[>$ -M=`65&XD`!3J0Y(&.[IF)3ZU;Y2+C+@/@H&O)YAQ -M5HY3HFHN'>Y.IG99MPG+.9-M-V&''YA!]S67HO/QHN15F<.@\PF2^K\@'W3N -MR!31K1*I(_,U&N@]C)8;$B^M6U[9H(94SQ$::$-,O.(?H,_@"[W^DJ#F$,DU -M/>F*ZYA&L6WI8`K?@V2J3&KL+!YRP5A=:E'@*I.S=T:G4DSL5\;>QRT&G@J4 -MC9JCA(EP[7]>=]U_25O.D2@T[Q$4U#`R7 -M=66C[!HFX/+-&=W?0"I#T/EAGW/-SU@CX3FATR1R6%?$P>Y+V.O=`C(R!WEQ -M_X12[=4*Q"0*7K(A4;B>5:*)G%-[KNV&GM"\24QE[]BY4G3I -MH_^C;CF>_R";HW)_H;D` -M0F./0"GY>=#0HX.9R7188S6T876@/;[DT['<9[NETH)*&NE=\U49?7NBD$[& -M#Y$+@O497*I[[(T^ISO0`B9@:,OV4("CZ[2Z24WB'.;GXKZBDF<[/T;)>A27 -M,-#951[-5-NE[O0S3IK+H]&K!]$N'AN'-@Y8R2:R`9XU+A$H"(.W:SYF5DS1 -M:K@L(<3*=#$#L@VV%%F\HM*(CH=28A&^H`@0-]EZ<#'S/O"S^IQK\S+$"[X! -M--YJ;KRS4C;,06:))-7/33?_,5$FZ.?OE&BH@B@G.%\.)V -MELVT9%`?+!OQ!PT3R4P:!,P=R::!Y1I3&J7>V#F#XHHM6+I86U'45:D<`YU& -MV'7OY?6L6&9)[1)<6TZ?T1IF!X!^P@K0,;&M?Y$NP\YG/M@#(I&='VT^L#GR -M?)DNO&KL.:)T&#:&MHJD#2R4D:FTP>EW'9(7SPJ9\+X%56K!1H%%A]V[/AEG -M2U=F5#IMQE(2**GQ.3Q+\,"U*Z]<+1(EUKOXZNP1)B7_;6V^]\*@NXA1OW<% -M5*F=G-B:@B)^Y24$\7RI8*5\&'HG+`%"SO#B\HY]RP[CL2'#\H4 -M_?&U%!1YNIZ^ZHWKP]H"+65.>AAC3917KK=8?1YBS'G\&>JW>/YWQ>ZU1PR, -MT\/]2/#$D]QUX"1]\NAKV9IU/-6@^-X%4O!]Z=C]J@HQEI0*L:4N\^==TZC*F[5-K^- -M01F(8G?`5EK$[HN8<%'G!7-#6T"S_;]%-T-%BE%(.V-BX"C>K)1V=;=R:4;) -M!7R6=54[7V[$;KHVLFETL%8:KR`%O9<(:EYBX0JY<7R^,-TZ-QP.O^_\^^F3 -M/,9,HG$B+QYLO2XUFBFFKI56W=2,'!=[LE`GN(,JZ>+A!+8+%SZLN4.0!@_V -M1&[,Z/4FB5S?I0'O3I)D(GNE"+!;T0?7XSA]W*S&L8P&,#\$9TM%;[\CO:QB -M5:0J1:#K&;?+^[01VF[K]"TT0H%0OIV;NYO,QZTQN)O;^B_WJYV#C1N:3*U; -MM><(T^G1Z:#.Q`V:'\QK -MO-:>FV?G -MBT&<6>6QQ@E;-X-B[WVIJBLF_C:&Z)PFC'I=>N[NRTM8VVD-FP9'_5ZH3,*% -MZC58A&FS])K>DMS@HX_=D599?>6[_V@,?BSC'\OSTNB]I\L,GM6.L!\`;`VD -MX]-O6'I'F')AA34D3@5_OIJ,"1-&_E3!(]RZ;D52YWTM)Q!;\Z3@W#CR6@+? -MQJJN_##P[JG(`%]\Q>HGD2:#L%UQ._]7C+IQKD=+"3ER`!=G_=A#3P_AY]GU -M@!^(OW"0#S/KVHE!)-7)=_>$85DC)/99C^EYCLS^06+S[W-7P+TDT(E!\6]* -MK#N.\KD>/H5M>FD3=LH;=O:.EGOP,VC?TS-%KZL;Z&XI5P@5Y',-%D -M2!N;ADM9[7Y8FW9!7,-F[O!#DVWRM]572)M*/?_:OCMQQC#+F\8>4N,%3P\N -M-Z$\V.9D&Z6;T7.S@/%WVI6%[Z&LXS+PB'<;">GIVRHD_2OW@/GE^7J&!*@L -MPF7%;PKUH'JUM`(',6756<#SEHA<4EK)_.#6 -M[7HBM!.<6"&((7(]IV;04K(NGU\'B1M;3LMBPMBI;69^E5>IC)-300/WL8-_ -M4![AKYL<(8+:92[*G2R@0$5B"K%XMM.+4:6M,0.U=9!=AF'](#NU-)J&=JO.P0O+6X3 -MQ`FGS@5L6_>C(O&%80:9QO9\^K/;*WKH3 -M24`SVA3O>9B,^"7S?OK&:#NR8=T2(S$`\-^"FG$U;?UB$*=<\=%0R'2LYO#Z -M3"\)B4"%_1DPNZB\,CP7=YN=/)?Q5*4KD>@>^)W&+"A?M6K+U^_KPD',5V.# -MY2<^"!8,RBG3%G'Y9:1,5/45*ZV44FZ(/.9U$M.,PA%#(L<1P -M`8WO-*&]Z.6T%3"CW;7!;60C+[5).1*&:2PX\T!R@%'UE=+=@):XO8M[8EFP -M0,\EVRIO23S)]DL>SZ/=D>-SAK(UJI/V'$9`FU/5'-/R'__XG2'W[D^"AIRA -MKM`")D4V/?J!:-[K?8X6G.G)*?H`""YF*E)*F<5:^H6"HQ_.N''O3SR;EUBM -MCJ7P`=[DGW*IQWW.!*X8:D4DAE!2HAU: -M$,J)GY2)*]M+7\2E,.&_ASO!?,2+/)3W6%#=_[\34;H?6T*N2L#)0@_:#H+1 -M`]`N:.(,OR-_O&6*^P\"YR?TO*B&;]=+O^EA\-VV(88RJ -MY[.N?A=UFFH6/<0H\UC7L6EZ^TCB494.U2SKR+-/8=#X:YO%0$'G:@8SY%PQ -MK4'LX;&K(8P!%J>/3F=C3S,T2GC',4.9%:*UW8VB-S)76(V43CQN/.0RJE9G -MCB&4Q<.,V?VXBFX%4OB:TD(IY[WNF=8-+&:@/GZ7]^5AAGLF8=/#4YP%VSF^ -M>8X!LZ%FZ+#A(ZIK,( -M),:$GQI_GCG?9/;UH+@E3P@02$6BSLPG!\0?>]Q6\&\9Q%Z?3,^KY5F/9X5D%7T%H^T='X"I%TH8'(3C_DZ^ -M6BO6;9C'9R6;#'\71;2A4-]DG2X=]0]]@ZAC%>".S\T5??X$4=26AL[KZ^<] -MO*8CA&JHO7:N#9M*+(J4TI)+SZ-^QY&7@BX]JZ%]6MN!6JV]MKE_2_;=ZZR7 -M71=Q9^_&E'U0V"64,IFKL)P[,-GANV%3;P+256P1QISV0[#Z'7SEZ`3M@X@I -M*&C&/0$-I&P/OO(D7VY*%V!^]B28;BZ606I:WJJ@M8^3TA@)HN,[`OBPBPEF -ML@J>G?W[B4Z2>G[JB(4O#G@[ZA!%O@#$$W4_22-?2&"6!'.#:%_P)1E2-#V$ -M#L^.2?R)1Y&\ADKOYM1<-I;&19A"2^JR9:AJRO@_DK*19D6M,G@Q9H2V`=LV -MFOM':G1P29W%LM=MG`T*J'0;GNUY],!,^[_GV"\3:IR8R7B+;MGN^RQALQF5 -M>9B\)^T+N7OIBG9%WC[OCVDF8J>^>8(8F:,ER+]'SRM?"%*[8HDV\.4DH<4B -MP"[A1\L210B-+O34.;;SR?[^^( -M$+="K;?$$JKL8EU5EJZ*:YT1&,LW%L.EL'CD`[HRLS/3A54%\.]6HTCEV;(7 -M/`K_QG`:/:PC)X"_=T -M#>`[`%.5E2<"8C4AO4]G=GO=%=&T,:?D5V"RL.G0T?8,/8.7MS!M+4C^/0W/ -MFY[C>[:I4:+`2IOE\J?R?IB/F'\S7`+DQ]N]D-Q:\^'L6-+/@)I#S\GL$:XQ -M,1W]F#2X*%>$)`R:GK_,$-9;V`IPUOZM#)^"VKU!1^0[+X3;,`R+?K(2.\PV -M&-`L#TX(*#@S*$7:4_!8[ZMRM9*"\:Q;#>-:N3BT[->9]]^@$3\[?W9E(1K" -MH35HP--(9,R)9T/&T$YE^)H*-%>3;9NMFP)0Q`2'ZUE;/XMY2F++;Y<1\9JY -M7Y-;,<#]?NK#[0),-X;"/Y#!2:2L]8-ZNK:%K1A;5A?/S663BP;D!^YSVWQ5 -M?D6*RC02QDH=!X?*(/P4@B9;G)@V6D-AA;>,2U=K9/*QQ:F;OA%C5Q= -MU>,I)$V&(W<"@)F4U!->1%P4<05/GG.QM>'K;OU@&W`4',IAJCJ["UE1)JBG -M0Z#+4J`@+L]S@8+WJG]!8PT(&L1>&3I4M`5;3*ZUG=TY\R19K<]MM,Y"7]"R -MXM.VFO&I>G)!2?:6LG.C"\WXET25Y[;F&0OHC+&`VM`=:%"BW+1QI=.GDKM0 -MT1WC)H/=6BPHJ2CFS3LF8@\O1PTI[30LYXQ+UO^Y/54).7T;2`U\:W06$';B -MV"0KGXP2T"KYA -M\4C/'C19(PB!)7-H_&2`MH851Q\=%Y=E6]'T!=@?N#=A;=[O50!_RY[ -MO=R56NOY%O65<)1+)J6),8C52K57G!<#HM:^Z">9[3,N,C#/]W0"/7V+/SBE -M>KGREAS![A6M!(::#Y]]%=%:L<[7CM8[:+M^JCOIK]:EL#4>*+9F4-BL/!0` -M$<%OI:O.G+N)T(;AU(\@90IM(F`654!JM;U)_-T\6Y.MS$=YD15T-YI-8$-R -MS]H0G='.H[O$\RJX_13M:=/SXFM"&K5`W<5,?-L_LEU.MM+]L9M??F16*-MH -M;@G@-]T5CWC-#^F'`0&PN%[H.O/DHWD_7*H,MPZ_'"5(]C;HKF"5F<@PYVW+ -MTN6A1,Z.()AO.8O$F`Q>[[FG8@AK]D/#/>%J\W-8^YB?`DY2!#OTTM"OH+N/ -M*1$_&2J!80MXFL?;.Y94@*8\*O4]4`PK97@/+X]I?JTX\^$^KZ=Z>.:/&,73 -M2TUH;1E'N[=S73MBF+.1M'=5`T^S2)%L,_#7^X/L&PGL83^,IIKSBN3`Z1AW -M@\@=WY``6#80@-:JT^/VJZZ#VU[?<\+ZY3K<^75.L-&!P2AUB'G()K""?!V? -M(SDUTT@L#S*N?)65JJ>2H^C&NR'&&U)6/-;0Y=UF#'V/Y@3KP?H6K4`(G-FOH,A"?Z?'G(Y'LF4]-/=Z&#PD5R/,-L41/ -MA;4QQ07>8I4_H(M:@E,3 -M*CG]R3FYASF\$^[LIV-[I7YUE8$!QHPY5&Q<"3'D_T+UCAM>97,$=)?]=0N) -M'AZ*G9";7Z;ZRJU,DC"YAXKFOE)!88$FZA4W,G,V"_FH[U7PPX"M!SWBCVU1M+33DF4^G]X\B, -M'M(S[>FFB@HA2!>(O5P=2C]6I)FMKNKX;R)AKU$("46DT_OZ>.1NS2K[43_; -M@F?7'4#IP2[^6R`LO9=67ZNE>@QYC^U@WVHS$1HSQ`9:%T?(O169I`?;OVE# -MLIZN00@/]^C9=XB:0.:W2BL-=F+5:L&W7SD\#9#=W,*6+X5*+O6,OS\&"HL[ -MZU'$\54``>Z]&U^M`:QY_TW= -MQ.=7A[1>-/ZF@R(+71!O*]/S];+!L_LMYPJX`B2+8!SNB71K24X+8/U&ME;T -M)8K]$LB?M#$/Z_V^_RB\X;9$]OB=SHEI*]6`944(*D\F@[[=A$=A7"(=4ZM'9*B-9"6*QU9+IR#0D6)?KU-(6F'9EY#4:)X]P*- -M!Q#PLK&LX,*B2D1D(+H13>WG:0EYEBP;\,[,,#$^8?`X)D/IAD>O[V_!Q\3& -M93>`$]P9F9Y&AR:.KXA'AZ$=(,I?[69'TY`XV_[J=&3AJ>V#]T6U(@Y@3P8] -MN^W\;)*[=[OFH.G\]W` -MZV#`$7[EZ;7)HN*F)6NZ1(SC'HT=&&*Q=5R"9O:TP@9EXHL6.>*P#ZG>DVR< -M,\2^.=O^:F2Y1Q*2K\VSRS17R;31X>-XI#D0`%=H/S[BH]<$!F/_/P=YH!?, -M$M::^@7=)Z0P<-FDWI]L(E(UHJL)F*I_ZL@?1U;Q[K9C?]PDI!*W,3K`PM)Q -M5CF/)E0K3+KU':54,B=UU#CU;/5G7';GGOVL\RNO_WCR^%RV0&O14B$RI1/+H@@@:0"N;WX&R:)T0(-;<_#LAW`;DM-,%3,T0O3XM*RF_ -M5;YE`5S-*-6[1\HPEL/MQNM'B8SF4XU$ZL['(J3!V<50!N/.$TLJWTN\3T91 -M_'PM5KZZ`CO\7#PDLR"A'$64X^ZSU3-!"^2CI'`-(@P!Y:0^1!RJ/Q0PJ6-< -M,V6?UXBBU1=R_@SJF@0*%Y&IS=V_\/O(.]EDN=PP<.JK6+*,4&9ERCW$ -ML/FT[^Y6SX`!*,CNZ:W:!!U7]L%FA1^4]"LV*ZZLV_B'_B\7(='WGJ(TR6Q. -MK18[?]`EAC^%D>@^.T9-WXJAVJ*/J,;X(7B'8+Z.#08S&QJYNJ1,$2P]AFLI -M,%F0#6((2$GVU0K1N)V=PS"\J@0"ORY^9,UF@C"7);:2HZG&3GQ^5E0T@S54 -M)W+JN9"^`#7%%F?.UC;$]1 -M)>-3$M<+-WN7:I(\,7%4H^#B7ZG"OD6F7YB[]@3B?,MQH-4'M'YIS[W(<$*B -MS"8E'(29.=SZY;X4`9`P'`X;-R:M+LD=,J2Y$-AO6CL&WEH31&\GLVY;?0O6 -M?"U"^BPAT4F)5^3255@TN?#`R?]WBT29'_VFN4QK[-,.IQCT^@&$'K7N+H3^ -M4AE:],<339^5"X*6-B)?/J&VJ@`BZ$)LI:(S8I\]@15-"M\`36?:2<$=R"`'&8O=&=2F84!#$DE_G -MQKTJ@XD7D)JN3"X2)ROW];HSPI#E!4$P0FH`$UIT?'-G3E%NY8_M%!BP2-1)(?.7Q?#CR[. -M-<6E%R:V-A[7%+A`BQ2/PGL$%#__)57&;IP,>2K57Q-NS(N3@9B-`$40#*^R -M7<4.J?^`BB)[I%E7?>&CZF$W.-0>\XF>-AG3U37FMV4 -M*[_9<`#[*>V%_OY[%_ML$Y/.%"`.8)-&NS5]V<7,PRK_]-,T9:T1L%G>D/'W#J1)9,4 -MP#IB03#"EDYR5V(IXE)^,0)57.#WV$&V1+%!=P7L/A.WWNPT/S\2>FUXB\P# -M@..5GL^U.R0-XB2LWZ%H!^!;P.6.[-J$PZ[#11N$<%&Z#3G8PN[H[:II$6)L -M63\A%MG[`=M:TW4M22MM,5R$P3:EC6TU'W:$Y?7*X5"8V\#4?:6V9:Y,?]9" -MJP,26<7#",.N;G%E3YHT`SUUJA$1/T^X3N0E.."3B'L+&EM6L&*Z7.E4NQH) -MT"D!YI\FQA1=*G3E'X>%GPJA@;5?EKFB_'7>B&H*B[,L8CP<6`G7^*J,J6N) -M&JO%//R`OPAR'D'JE$N\6N!!'O/I2Z)*3EB;H12)=:IX2L@^'6&OR/O"2WZLSO,C7[Q:J.>S^&@U6<_%DR6Q]RT&-.NP:WE -MJ*Q`5V>50[NF-UI8G;JL]/=#\ZFDE\?00I+J%0A$MRF6_+1Q";GB?D!`$B53?@A?F2GJ[+: -MEX6@X$),6QN8`W`K$NT1.1X/6VD.ZLUWJ^57[#8KLDPYY#LU=UJ`.B5^ZK@T -M,I:PBH6YTO`02/MKVP;::( -M?MG)!AU!:7U=D?R6];D:<#@FRLR@PB4CZI1LE6+_WVGH3YW -MWBO.@[I^8O^ZP*)=83`V#!)]6X-B5FW]6@I]U5O"H]M`@8:](Y]:,T/X!?N' -M!,`7\%-G>-88OL)I91A.5.M$C0WKN1\_%W<1.=P&K"@S@ -M-9AA>J"PW>WJ3O1@N91;\X*1>@USG7Z7CE]AT@37U\^A/=^L@U)VSD54)9J' -M*LOSDBH#5N_&-6:IL]P;V$G);I.+Q!H\Z2_Y,9&@)S3?M8*`D@O6%)PH71#> -M8C#:<7N_V\(L#8>>M;JDQ]+2906;+F9ZK6X?'^6$4O0X;+?QWQ]*$] -MBXM$YLI!QGVTL8+=+6TO+6!F0,:O0@4CI@TD(;__[TC/?XA&OFOL<50D@5H` -M$#L)R]F+Q8,UA*!(':>JT!]PN+! -MD!(+MD3$97I!,)JSWL?H<'CRKCKP;TPF4?3 -MDD`3MS0R%>"G%R:QL>T^27&R?L:I'Y9'QX%Y0]J_QZH+ID<=5YX#@U.XC<&+ -M(!Z"^SP%-ZUT-JXCG=E#%A4XBDH%IBJ=A^;]KL^C*$LW*)YD_TG.#"IG -M0WD3!+MJ(3VYH4_:>.]W3[J2V+0SF%7TIJA;2_EQ]TRC+MJ1H_UN-QG7V1+C227!VTJKD?E+>]?^P.TF!Y"+KNE -MBW1.:)(O&;XVD`**W_.Z;*!V%,WD0?WB1W5YYGRK;S<[/N#G9Q'S##?A,C2H -M+***?2CO&%8M-?`,1#!,:RQE"I8=>CJI0X>S"SOK(4_,[78KUSO9W-*ISC&7 -M*,[W_7LO`CY7WKLA_7V]&\T%Q/&FGP-]R@EM,?B<3_OT1;T^_Y>LV$S9&*IO -M(M^(`Z+$;5=#+6WGB]DI.(EP]8X^`QT`NJ4COX`BE@;_,$GG_2?OGE*4>U\@ -M7/2_@W)L%I+2U"_X;:LF\8=0S_P$B"^%/KG[P`S-PA(&Z\X^U)'76`O"^$M9 -M0XN)X?E1)/]8=VWV`1^V,%K$2_6="";32$]53`_\;V@!:_/:.\Y0$\>0=![P -M!7M81+R3('@PKZAJN0MV;-:2N>NE"C5)^5HS'.6VBU715F/#;Z8/2-Y2%^EV -M_28%D$@]W*VQ675(=9O6.$-"!R*R;_PTI5;UZJB$D;MQQ>$`"/2=]UP,R(VV -M!'1$[W[03!\I[86DT\VOT/.-!8V(&`$-9>8/)0Z#G<_)?O%RVRXD=,[MXQ0GJ,L6."2P&4_A0+$0F=B8IH*)VKKRQ*]AR<62"? -MK\J%"TSA%R923Z(AF>B\-JKHG_6$ETF.SM,-*L:7)?)L\*:U>U#=0$=^5[%\ -M2+O'MEU42(%.S(A6D"QA='EU7!V`T@!Y6UYALWJ))AP9)M[$GM7*G6B)H*C\ -MNJU`"OV;TH-6FMEZ*2Y_('1B2+T,E4[&DK\^L/($M775?P7H`-^[/V1Q/QY!8Z:K_WO5[BP.)F!TI@!HOJ>C^1+Q:8HX8 -MEIV!-B]_U!_X:_G&/V:)V-@5=^(]4R2H._?P3972I!-;C&414$ -M_QPY=*OG==Z*LC%!DN^B&D'5F4@;3^L60[]1Z6A^K78PIK03T!-]H*UP)TL. -MG*,L#%-M&V=S+_7QV^KP6WR,$[\5?,N40E"IP+IE1:+SP&S7B;LN!O)WU+CN -MI&,6)`R&'NP!0P%`YVAMS(#9_-YB0J5!GE/VC3Y$PZ>KGJ1HE;S,AQI"[B[)H-U -MPW)A"!E-;QK5L*ZE`[H?^(7Q:,[J_A@%,G9MX:D$F$"1IA;$$30),N$M`#T! -ML:9Z'CP&,.U\$/.3[$[?>KA"TFO)%]';_J&5^[$N7TX_^Y3?KOY>!$Z6UR,' -M"W*:K0?^A@9`)_S2LTV>XQEJ?SK[C%E+[=97GS!;:Z&=\W?#Y5_2\YQ).Z/Y -MW:ZD7((YY)F(_%`EF*IFI3,Q?.)CFKYCKH7.:S+I`;3R#U$QG_9P,$8826`J -M(%0::`;UL/MS:>0G!42CW+P,(GX0MV[@TY9(URN/TGWBL!2/IQ##&RYO13C -M3*W+V#/B5:R7B%]'1:2Z[+\]HHN?*1KO10P:'67IN`ZRNHX,AX4/>Q\_K9WN -MD1+.#\45Z.D1L\19US`'BE_U!-:9_IYW%,""W:HEUO*LJ@H -M>WE<-.8TA3$MRNP3$Z:JC`QQ]0K?XY@-#C6)YBHC\(PZZZ,IZ'O#L5Z&7AH7 -MQ:DL)!/GKWB=]N=JJF'2SC:)@X&IVK+JPEJ*3T;XK[L0ON*X&V -M1(4%2Q?6"@C5?DLWUYY5@3_!)Y5Y>UV([V%0/$BD%.P#3&UF*8GF0BW@K_S/ -M:KC%A.T[L:77(F31U=APP)Y;%R7MLM91@X=*T$!G."-8./1P=XFC`@I"Q -MT[;?%!PF2.?S_1(@=HD+:63YM[\7R&?LI..,V6*-6.BKOM8^+D'T+F#Z>T;` -M8`(_=I@"SC_$R4'_1?M*G,9;6S!>.O,G*OL$KH]D@@9:9W9@TW+F/J\($PNY -M$R2.J>>S9]&Z#$=W%AI_C<)R>]7P@`(7\3BWM\@!F:610V-!3Q9\0OCE1MP0 -M%GV='38S()&6$J\0RE0R*-$:Q%PV9+N:W?8TPB+M,)3[TMC*JI,U?>ES;-Q0 -M!SV:H80:^>O\Z,V59\%\]\*D=T,@/-W>CUY<&" -M607Y6)R#0*\I/QYYJ_8G#NNQVI7=!034DG^<]`$_V=Q!"K![D+C:5);% -M9:5T9*`Z'TSN[HJ?Y:J9]V/^AL&.9%<+`W\#Q``?ZJZMNEQ"@GR`B@W*3/HN -M*`P"VS'9Z(4CWQ_`'O!_`I/@L,4/V0>[$\G?$Q&.JM-!I[G1U-PE#?(9JQ`_.0C@�C#/_/8\W(]"$(8 -M"WLAE;L@E$$3M2Q"'E*/>D,5(YA;N9PKPXV!"W]JJ@Q#Z?"$D=#)JM`3BJ(W -M=JNR5^6HA5S+20685"@:_E<`:$2:+FP5N!"+&57E,=%1(+,.. -MK<;/G7'BG'*N78?2SMLS$1,XZA_@*;Y3(-B&B3D$_N'X5SR>`/9=Z[.Z7;_Z -M4H>:3DKF#&7QL]]WY9/Z,/S2H!FMR:671P/>W`WG><1Y`NBT9D738@B'.WO+ -MQE7K<@3Y;KRJ4M/XSWK;(;,^>3ZNU"L^N86EEF_!';_*1DL16"K.59M2%=*' -M3%#P>Z;HB.)%>5S.SX)U1I!!2,+<1!^?][J1Y;!I1!03@=R0H.`;^Y"X7;F.WB"9?4#!9=ZH+,), -MWJ9"2L8OW-?U7R11#"S[91<)#4O7UR[G@",-I;)4]<&]%#0*4B7`#!M:SI9MYK\Q;S%J*2)M[*A2'9);D1+4IW:']B5:\A\?)Z`3_[Y;/8J7QC6\J;6MKPM=YK^O -MUCN"15[U>GFGE?7$#0B4WBO6%_X/Q6!)@4KM+UX!;H97;UG_F@-3YI);&K#0 -MCXH`9W%N>3+-Q+?V0F41\81E;29T/4>\^+"0K4_:#;B"H!IC\S3`EBI"D)6G -MM^GU9CM>@I8OQ^MBB*?_4#(R=Z'%`%T$[C%NX.:,9U+OJ4]UIHP*)'E2D'&R -MFTK/H>9A\)PQA(/-!MNM0/(-H)S*7!)G?*=_:+UM*[SIS:RJ.D%(6#!S4W(5 -MA!VM,770D%',](LTWF]DD,+6T,?[=Q!>2#W./,J9Q!_>H=-:@H(&%0G61B3' -M8!C@Q*I>[E*AT;45*H%[3DC6-J;J>^AT:G-,]!%PG8M'2?H"DTZ\\AJR@BG*`-+D%:=#2>P!Q!02$/[=TZA"L*6=_Q#6`#"6F5FXSK5\C -M1G%+%*>FU46L%>]KX"V:.>*OZ)J:OG.1DW\U)&UN).4_BZ8 -MT<2?I=$^B1IOA8/B976!/`>0">$WVG_MP,26@"<9:<0#:WKC<*TNZ]4:3-DG;F489Z'LQD.,:*-372>82KS.[:WA\>J720: -MU%EAI%38P#FLKUTFG+,M;VBK(*!`IP_HQB7]#8?410`P=;*' -MA(4%D=-HL@NI=[[8LB(,S]S6_X$CZA/=I_[[.?;4;;--4-\/OX7ES5RK43TQ -M[.GX<@M:7',?&G+ABYE*K'0/G#_I$O2;E/<*:OX7404U=8)7+4*@_PPU&7$7 -M!LX6W'I17H%>ZJWWW/F.^WD;YKPZ -MUDN0^'WZ7`XT1SD`%'D"TD;=>VE<#Q"B99'F6<)@P)/2_!?-TL#K^CKBF -M^-'!-(2:)2>C6BR<+_-/%WLPA$(_!_#-#/%;-BS:ZH8'6@VC9J;O7:X^W,GD9GW -M%E::%:\8VHK7%_5S?0WZA;2:HQN6P[\FK>YE(-.5N-BN*GBH1\V(&ZY\G@BF -MX@/L<1=\I#"`F"+&B[$O+/Q=(B-4)>>P'1N.-E)1W=;\=9RF_..?L$GRG@M+ -MKW5,JT'-/7##BM/SJYEXI$K<5V..;NIQ.S3,67+I$+Y5%\=XE7W)%,=9G7F2 -M.,D6R6Q$M#TL!H6+?W6/+2Z3'[+H5:=Q4?%RHC'A,IW'K'QC*CT>#LO3F[Y;V7!WL5DT#(AX]K5Q<1 -MQ\'E7!_$3N#;^YR`:5>OAN'5KY`;T"@[I8AFT -M3N4G^&+%\H2J<5'9>)G2Q4F!K*>Q!E7%/?T^+FRE:;"/L_@4H9[,PV&M8M[O5['M]BD9V+_:7 -MTJ*@_FUA+?-T#M_IB&]E^^'1#(*FZ?)\G4=`UX`JB^N+V-'$@4K(HVM/#1_K -M%O!8:N)L"$<0U:J7(.%D^=XPDSNC'%J<+=<5+./WJUD-M3OL2ZR\4FR9BQ4( -MN^/2K>(^9:%!]7EUC3W8N&.5$@MA8QYZ!":S%VJMQR9)O_'Y^S8H`TCI3[N/PXQ&V[DATLWB&&A<57G!# -M,_%X:?$VU.E"I"'M?!YB+4L+1O=5$@Q>)Q>U10\BCQ/G3P^3D:T#E@1?'U6. -M@Y'(=&FA*T@QH[]>^%RM$6`X0SY+<`;SV<2YPA,I=R<4V"!^?,C%_:3)>^CDR+4!K4+D&'D!/L1XA++6]JF<]NAGLYPV=7Z"=+M^G\P\)!FE"="E;B%"$HA[_CU4.T?]H+_=@.-X#XN/* -MPTW_3Z+`5O;2:5QZ.7#9_Q;E:I(U>IL>R5^6@9Y%2IMI%?5Y!QSCQSC?R$)3[Y.9HKDBIG=]PHU'1.TVQ,0="5FK('S9^_PJ&!* -MK\#>2QG35$$<:VG6>6]4*G=_@\JTP4PDW[@#@>8EP?![%%([J,!WZ/Y*'9D1 -MK8^^AO%LP&L*I0T$"B*7MEM3)VFP[*!%@NX/XX)!H-HK?N4*Q?TX_SK(7];` -MZOR[(?C`,7<=3_<.SF\Y_HF$5EO\IAEDJI@VI=6,UYPR7_X454Q^-IW=U^!.# -M$C2=*R\97G6'1/TK!7FF?ZS/*:.XE1Q0;:>D%JXU==[$F0=0T)&!*EP1<^ST-JLX3@-BU`BW2,7^'+8P\7UK.UIR/Q -M0O/D_:IBH'G_07Y$<']4Z3LJ3B]^O5RD?".U6L$?O1K?7Q^=T"I>O#/I&AO6 -MN"YO/[[5!WK:(1Q3$*^O&?$D"EZ1,!DV!S]/WUB$J,0EKSLT_[>CK&([U,RB -MV$V;4=$,[H5VA"N?'DT78]IL7%WGIFBSMR+403/Q@G?0AG2LD8W2M8C!0`'P -M$19X#JU[K.LGT0Z;,?7R9;_@M+(-7AW+59_>-`M7^.&G3SZU%9#YZTG^$*/# -M4AOV)OSZ!7;3?=JDVIAG)Z.DW'ZE=="`)SXJ8YM -M$%')_:]@$>"ZBT41`S:HA_TO+&=O);ON@5U*\SYJ@9E22UEY''MU5EB.ZWU'_PB>3^M*Z2ID`=!B+X2BSRY;\M"`6PC9OJRD3=>_V#%39RF[A=B=^4-; -MZUH#M`BZMA1<:/W5=3LD6)8V4]&\K\'CS3`WN#4;Q:<.$-*`7.RXSH_D(,E? -M(4'367REB7+.C>S[H;EB?R10X4W;T)'-XRCRO_M>O8$4#'E*/=P@>]&:B?=" -M'MSD"\C.PYY&S::=*S;$YGS8Y`#<82 -M:V=2,4]U1C[4IGZ'8IW%L3J;ZJ(P+#,;5P'`N%[3:I:$D[ZN[Z_C>*/BFS)#/AXHC9O<5I^UMRQ$[&H\+Z -M7,1`7HG%\CT6Z'0@%X;C"0.7=&!"3,9,$U>_BF&2DAA`LF+X3#,/(QUZHAG\ -M:`S=881@"/[3^'IG$#6#SJ0E9H&8J\(S>PQ$M")*)Y'DK$0^I$.@GVOAV'1_ -M6$-4WMZA&G-:@YRG)5[[X&O5K_T$#??C9-X<_X\*".8M'B)^CVSXY'Z39P\- -MQ0.1-,[NNG&!6@L#K:D88#$'!CBAG1G^H#UEX!`\+1:['K-=,F,5)4\PXP9? -M8TAB_OR/,*B%+G<*/\^\?U4R:LJ:.!\;<\B@.&PEW!^Q.>7N+R+38V?)[Q#V -M)XX[4/$H3,0C:X='S?!I>R1RP:\HV`UV6`^\L/)YE0IO?^^/X#=2_QNL^_+"ELX)0V\JP<*1X9XIHD_<*WX]?41* -M4<:2O7Q/8:)DR/!RY\Q4>W_!N'WNTM^`9\/KM#UN))NG._-O$SL9#56+(G^@ -M/)$<'I_E*W0Q:M<:%;J(G0@NSON49.5=9SHY;MT0N8*.#'ZJ4#J:7[CM\`): -M^V!1?X)0OK/=I3>;F$&6&%!6+/P2"%@J+,FQ)GZ$H6:0Q8GN-[2\OKLAUMQ] -MA>Q(F4W@U$YX']H"]UHGB#M$ONN01"FISVQ[$8T`G]L*TY9@(H1H]1('-.Z[ -M++-GOVC_*19K(K0&U99BQDRNLR)0VR@IC)7:Z3V"N[(XC>GA-.7\,3+K;U6W -MN=>5QCHNJ"+E8:O1:@'KBR_`\'6?+M8,]'LU4&G_F%7KMZM.-RD81NX\(HM\ -MA&*O3&&18Z5>H2;Y9Y(&-XJ#2!$Z4\ -M?[P@)(<"N)(Q]\D -M@E$9#4DR7WV!*G5/C'\+4$].LC56/'@";N%L%?GMYW$.'>UK*1;.>Y,(M[2L -M:''/L$H/?>I.P==A/I>`<$D_HTQG1^W/3)JES(X7P%6R_9*@V@4UV=!^RU4[ -M>E15]B:E)4;)[%R6/)!FH#/_L,!OI`:@2XGPU#,VKAZTEBI_;:/+J;N<' -MDR9:D(HZ*/'5L\_3BDWZWB\48&8J4!HP0W90K]]PN?(;@1$M(+/XUU$N"?9G -MDZ7*U]?LS>4>-);I=MX`.F`[(0?D`TBFX(:"0*Y,<#^:8NA=K*&H`B2BMMRA -MC+R1,9UFUV4N+9LL+.>,U*@B.,[S8U`C_WH"<&`P4-\GV0.B_IEVDP4#F"+E -M"9%:P7PS(EK@0[,A)3L;LFV,Y$HZ>;;"'",%M&C=`/Z1M?G";?AJ;2)DTF3P -MT?)ST#AM"#XM5MA.C3,@3RR=RS)!.^ -M#3V#7X&(M@D/VR,V__V"]C++^N???N7.SC5IN-\63=@$?NOEFZVQJ8*-&5N:-QG)/E!,MUT*=$C]>@36CB+_HH?:RJ!6)S4%J2P"?>\+/RM^@.5WF2=SX4 -M`8O>/N<)\PH\!Q/O]`%,:2D>A,;C6V0O)G'!$.\N$5GL`\_U&6+B+(/:FN\, -M`F,OD]%6`UCC(0!C_(@$%0J)\IOF.]U%_"-`:MV0C>7NEN:WE3%?[^J8+8OVV!@[O?ZL)O>>!?4RR)#7M=R(G5ST_T#!H*7S@6(H7YOY`W=70*+I[DFM:9R,-%HIQ -MSG=C36@$C02D1,Q^UI -M@'P8U_[_*JQ?(`&%TLBP<9T=T]U[!,K!?Y$QM,D^K6RJWQ9/&4@%@LK3X=+Y -M*),_-,/JXH>Y.WB#=H1D:$Y42M<^!T;`]*HKN5JF2N;4,*H6PRX\(RZR0/39 -M).CI1G\S-$,OKZ8U`F#QVS&ZY?][4A0JI)0_Q-*%G%JXK7_RA*X2_G-F21IQ -M5BS]2NQWYGNWEEC+>^/.!EO^H#ET%`=QO$5!UK>J'%5JUCG5LV^FHRO:;.`V -MX&<#^)*(GSQ622N=YO3;&R36$,_33O]Q_GXTU4#(L8T_367[G>:WVWNV'[H- -MDS>5:BKPE]8&1K5FV,FU&Y@&,'N_!53*KDDXBBE>`U/J%,UUJ]OE]-R*=Y>W -M^ISW308S6*-6,=0R)]@!HAE%ZKM=]@\L16C2>1SQ'83['G/`[Q^][+U)/0`H -MUU:`M6?W1_F9*4S&8]T^B5(AY#,W-#S@/V0;4=$#3OU8R(F7RTJM2L# -M8Z_E9:>9,Y[$)<(B.X&O_69!1QJDE0YAGL2X`HF.XH6^D,= -MP8_=WN[>79PB!=E;(H7W]11S(N,MV5S2!UK/]HO\,Y`[+*5) -M/4U[HE&N([G4Q'II#N^_JQ?_%E"S-B6#*+8+H%)09FN_8[,)CP\$^KHBD;%,Z;#59P[QI:ZBX%%8-76 -MJ<_-XJ(>^N/HH[$<%C]$Y5>9NR]DQ$\W$6RHD -MYY]&K.-J*-I,3U0!RV*]2A1_?ASA<-BIB'S(V9>:&PW5B!:R[SN(YM[:IO>, -MRW2-E4!7=6\0CS&8N9::&UXVA7C5-B1%L^_M8C:J&P$F(.B5EOD-*9@`WT_AQW[B^0_^)@G6FNWP>Z[G1*+&4#5?(O8VR-,$%RH -MO%R>+5PE-@M_-()!Z;W'\D,6J75K39KO3'2C'3_%CQZ%>_[)$,-\[BO: -MRZ^F*T@!NM:`JV*T6S@Q.B/0FN+C/[UJ]=3*AEEY)%$(?(#0-\)T* -M\WY`L5&:5&R?T".J(%T^[PO,[F<< -MV@\NU4K(.A&7KJZ$LD6(%*+$^`6)W74I(F].D.JP1W]YHWY,*.Q)]FS^=-MI9((]U-^'N;GA=JB\@93@6H5\;;" -MANJ-)+T(T3JAXA1>44-`G(;%(5+T/PTH!C\+NFL:=SJXX>FQY-_C`L@,/95- -M,$.CH%Q*]JBT7M"5R!B_._?Y@IK]TD^?7+KA)R([GG`-V@]#8V-M#X47Y_@X -M)QM%4JLMYGU6))?^J/5;+2MMTVRA,G&/TH]=*4!;'IFQ)^-19%VC*8_%2`&A -MJW(Y/.Z>E1^W/HM_2)"SV5%NLLU=HS&9>+K-.H1`E;>[$H6YQCGIZG@*X0 -M]5"F/_%:Z"RF34:KR`*]U0LJ3%-U0L0RER366WM<*"X?1)D&8.0AQ3Z`N?[O -M.70J(Z\8G(U)WAXI3'V])ENZ!J;"S:+=_=[U%P3O]M8LC&2Q051MYA)T`*TV -M[RX&\>RF8ZLZ9;>`=JSO3K/N/5/O..Y2LT42PNOL?-(<`;'$*V/=DN1_6N1\ -MJ^JY@K`]'>WP&#C58SZ&J:R\@O18O+8O.6)->L7LKFTL21OB??-!`723E`U+8)9R%)+L4+`<%CEAJD@CQP[5X,FH<\8K2("#7 -M@GE/"Q(:SUQA:[5#%XOG(%$GB00)85@R+:@Q,\IJX6\D`ZI-G\#SC'47*C98Q18W4V#B=4M, -MPR$9MT3Y5Z"-S+U!=<>^@[\D0OA4K&GFPA7-BK-58EC$QS84!^NE;)_@$FFT -MN=Z3KO8>-Q@$0IR$J3;$;B;$!1_JA5$,2TOXDOABQ\SAS3RKV<"LOM4:LW@:\@\' -M`M0[+]>62G=VE`L]=^1.+HDN8C -M-V%3F/6=.\@5D"%6GM#L%JYFH5Q@5U&?"F0H)HRT?5165B][6$73FZ+'C`=Z -M5M#]XUX-*:>UI25^<5/2"_*^0X7F"B@#'DDF0-D``7:[/0CV\D\;<)?(<0-H6+)%LU-71UCW2UU:;&@U5ZQ@+3M -MK-N58?!*=Q!_]"I>QTIR.1C1I$K%T,.U!N@"H=#':!#P1+BHEQU@G6W9'XA> -M\QCZ3X_5>$PX,6K#5V?-/PN3EHQ4%EN6&$O[:V+M/KJ+':BZSQABW*HEFV&Q -MG*(B/&-[KXL+'<^EF87I[-4/]U&,/K]QMVDCK^](A)`E0^C*D0^2#!3PX)W1 -M-!N[/^5^3NBU`Q1$^B8IM51DE#V:SK`9_D+!XBZ\OW?P9T/7Y8$[;;=*UWZ\ -M`7R?RR[FWCF'I'QDF02O_RSR=S4D)E01H",MD5:EYY:*&JR)%V9:(1MX%#*?;0]* -M8*J'16-.]#;'.9"TA*L/Y%DBC:.B^<29)=@B7)G?.SSH;P+B)38'!8U -MAU:'/=:AEBD$.`RL9'0A+&2NSER^(3#&;"3*!6J.&ND'EZS`*3RO']GO:*`9 -ML4G,=L?G[W2G.EA@,.7C&K"F^SX'$E"E9-$N&S3""?`>/*3)?LCU8&<273^G -M:+_&"/"]<>)=8K`T^I<>`(W6B6T51RM,>D@R:!_%OP+<$&ZFZ->(%*S-2NU_ -M-"%S4.>6TS&-CDL6JX4M'ZO41VS\C'_W57[2FAHNLV`5"HOY./)=LYS,6\Q\ -MX5\6G=@.AH1%2-P2QH&+TPO(5:;K^7PI+PEW-.[%PX;93<]A1]A^$/SE;S&7^4A)3[(B$%)-@HNQ -M`PK+E3PPH[*P4*SE^]K0G59EJ(O<2W`$>EQ02!$&75)O;GK)/V!SGP*]%J\(C6>AVNNBVPJ9]^ -MJ0IS,S?:&R_"8M1OY*AK]Z+C:,9V'04W6I<`'#8,-KBB!JR82,N2TOJ -M-M]-8KW*Y`Z@RV):>FNZN7H=8S>YT?J>JE2X\/Z(VZ2+CE=YMKR^:L5Y\5CZ -MW6#1&3YV`-$WBL3YKXO,UZPS(JQ]T`6H8$0VDF0!@*511F?9JB:<6_0;3J_$ -MU)E"SNU`JQ31[E-`"ZLQ;$I4UJ,"E+5C8AWG?M=SFH$$/I/JN%@__;[ -MLMT/<[G$]M,6<819P]!K:)F(O#!DQH=6YKD%F#'=EGLXK0'8X(L/%,E0\5;@ -MK`.#X>.:_Z#>?F6RV`+!2H1=_TKOC7)Y5#6Y,2)="!+`4>6;K^4N+Q,T?8S4#A -MU,'928F%45;5]IO;3`!MBN_>BRLT'T,DK75.YY`DV=X4].[%("?F7$T! -M`PGY;C&I?I`W(6EI_G)!!/,*Q6K::ZL#2_Q6TSO?:/5PGSDXQQ^3.=6L+.SB -M=VL0Z7HH4I.@(ENV1&6EZ([\5#]OI.O'FN@V,??#J3^D!5T\L1P-0`>UIMJD -M3,HRW]`C''AZS)R`^\0Q9\"'R!%*C:4!3OF@`0EHW*B;+CGZ-=->#A/X/B** -MQ$`2DNO[-J/M8.P=?\\E&;#`.,[5E>S#.<]TL9/D?!/IK0VO#'G3[=S1Z+P63(!L&DGY8RF)BY/#&RLR*-,D]\0$O-[:YR -MU>>XU,67>$2@&/N#6A67HZB5)U&IPM:1_(HY#2H7D0M&F:.'\"M4SZD6@-R* -ME-D^EM'TG$3D$K.G34BJR9&`ISEZ\9`;Y#(9%IR8F3@O]\_D]JF`@15)XBQ= -M59FX*^?NB``F>Z?8*XZ"*4#<:(>MA]NB(*,R[7'3ABJ1&`BQ&ACP]'%JR_ -MB1UTKX%T.>BVJM,C8],.+,.>\3RQ6+W1R.9IGO&FEP@Q%RTX+#-%*TYD -MR$E@_HJF=$!FA&F7!>A_$L2*QE;(W"6W'P -M)%P]6_7ZR8O&(I2X""5H%EA@ZR?_E[O08$6A`!O6[ZQ1(_(2;82-1Y`<D"KW*,T;\>X]T2`A:N5`#7'O^G[IB9);3L%:3_R#2U#RD!<-8P\$M1V@G5\D;6BT2/C0KT[2+K'!2FH]FM4"',61^"<25^0PT%`X1Z -M3$K?%P[@R\_R)\H6OG]#-2AIZ -MHS':J'5MNA%8,$3+;9W0I=#^RC+5$)62[L)%W__N]:'U*&(NXLE^71-K7XK% -MLI?O$P<$;Z:V_V([_E3:;I';KZA=H9+:[E_^^8&VQTN'+Q(+<>ZCQBE8GS?K -M[.9YSO]%?RIY\#C0[(//#0\F<3#K3-.6(RJ)06$8BA(PZ(YDHL?0(7&>,WG0 -M6E]+OHI$B1]?5O/*/)<^7A_0N1S\^Q*:R1[D.2!30L`PX+M`$\!->.\Y;..JL -M.@6F?5\V^@H%@CN[T!6V0.R8S_->+_8YGN]/0QFH_ZSK09KTN7]&T3[MIY)1 -MT9_\Q)>KUU8]3IQ>;#VJHGW"#I?@LQDED1^L)%N&GW)P,X>J#`)S,IZH1;&# -MUD6X1?@AW3U^X'O+`"6XPH"H!S>RB\[*;1^0T86`1B/$HUA1QJ"^L-P',L>D -MK<`"NH1A("/(5PK7RN"2;VY]!4Y^^>@N`C6;I9JNBOQ^9N+*:?-J(U7,+^ -M(#7:+"/O]7*484"T?X:T%T-P34K%NAFB%?4>>AUNN).$:&"K\9_GV\:P.X.# -ME!PNO%B_/R8)&C2DB"ZVBRY]J\9Z'Y?9ST"+4GV&[LA%`"G6$4*A!'?NMYJS -MA9U9B\TH.P;GUWFPF"Q.C0\2ZHQ-*&_UCE.F0A-"ID'/A:CGGX"!T\%T@UWQWHS!$A8&9<"J8R>SLC -M`0X$X3E;/R)@H^@>Y!H&C-]SV^*WX>0CN/N/VON\P\3G_#2:F1&12OS6Q3\G -ML2S>4#*M85KT__QI`:`V7/8R8;?K^F.]Y:ES3!;F6#N_NUN#ECD(A<0%AB!H -MQ/&6.L -M01>&R2*#1`*\F>UU'&0G!_<0XD<92):9+C&0W&=$^P/1.3WY&]^#^QKEQLG` -MZW'5:Y&GHX5.^6:09-_#76_"$\.JAO';ZI8O.9\E6BL@2U
    Z=Q1^:<^CUFG2QO))GH8)QVE5/%'^K<1B:O/%0AOTULC) -MYEB\9M)+X[$0OZV!^+BZ]0*99XXE4?,B9K0\1+"S)0]P2C8(C5SGFJ-Z"F%$ -MX:>U4$ -M^!U]C;VL"DT!];1#<=63D9._[6KET#W-\7.>\Y0`A,3IZ^:0R^5VFI!RC*:Z -M_D\@$QR=CKZ$Y2SM_IV)*+LJ+W"@(T?0-@#5&)XB<_MX#WC'S_;>IN^F62%^ -M5`2Y,P4=0@F4LAEU,:'>"\]AQM<$Z?/*Y.L``PG574769?&8/"9_CW!_=".J] -MN_'AH@JMI".M#1^>%3J51D`:1VUCO*B?:/1,_^Y/R&-#Q=K9&#KU+LGFO2)N -M2&[-RH7R&X@3B%--%'_=+UKMC@(<"MM21"TVU:LZS[])!/&5QZSSI8?%*&0$ -M)*#?_3@^H_PLHA,+XRH'6=5XW_8L,$HB0-HAXP,#G>59H5E7%G@,EXTB/I'5 -MM+P+L:,<[E(5#^/'$%;W43;^_&&'DOOO">9048+86PC@S!:$`DKK));8&\K$ -M56IL0W>ZV'LY.-`7S5^EV(([.!)DO5NOX,9=0^3WA)3KW6D,KB[E)N?X%$I0 -M0CY`WU$<;_T;TJUZ;"E]_++S1PF0L_J?$U9H7BC3CQ>$&,+*!=J7A=;G&^0,)698:C`_>PNA("/C -MZ>`M7+%CX0^%!=V.V9U^UGY6^JZYOJY,W79>1 -MK5X;9T>UM>9>5O4)(*&QG),.6WT2YVLO9KTVQF*O+44/?JBGOOK?B^>(L/$P -MCM:02#_";PA^"3Z[^BGIE7R@.P>,(2M8#[E7G/.V_K;$L<12ZW61]>1")H#& -M"KMBW?MV+\@-;;FF1R6QTLZ_6(*_QS;`3;N8@"5JCQLQ/5[[+!>/7PLM8+@= -M125*.LH=_<`U0%R`8D)LPCCS&F5CZ=>J1.+2J3_0IANGNRW76TJ,CO%7)O#? -M#,=GW-':%,3*L(&$BDL@W@WM=*65VP54R\B!W5`G0UN@F;BV&]UR&0QR20V@ -MG*[>SWSS>JJP[M]C@GAQ%^3/)[6Q336)?1:#(3_Y;!JU%,=:]88B*XKX'.NG -M@OS)[J^#:LD7EUEO63OW=A%^@TLW@8;M^7*;-+<$T/\)K,FGRT;7=,]M#^9` -M>2_NS=?BLP=EDBY;/YYQE/?^RFM$B!=/\E".'PV5?S=)W* -M@K?(#@:LMH?3&!4.`QQI9VAE7B]&'*V6`9EEX?(U-AQJWB,%.^6%;!EUNO[. -MQ7YN&9/7&X,$P_(6%K_)XPYYA&*6F/=.*D3KG2,`1!E=EECOR^A=3E5>SP0] -MLE)`R)G4E)QZ!FK;Q-@%C%/_A=@X1EDSAG"0PV*@:%*8(UR^IGD5 -MO:6F\#>=3O&H[[[D*3%"H[[2"F%=*GSOBI*J.@(>AS3A8D:M5_6^VK-5. -M(1>!]Z(+2)A#A?&2#>``MBLU%5WFX>C3*7BQ.]7"#.P]E_`"!@`/`=)Q7P#D -M",.ZZ<>\Y^WR9D'\ -M;#SK:HI=%A\T.#7;R?E=P?F?ZT0-NG#+9*6'%I--FK"M>C?.4?AK8[3W\X), -MBBV\UX?VH^J'UW;S1OZ/IP?>OV54[#"GLZU0QF;@I^V"]9P7G+!Q$UWL,GOU -M%BO)#/U"NER@HD/L).G@::@>MU-@\GG%ME^!$>8M0UQ8[Z/ZXRG9*L]3!RSW -MX#?.XWYR38GIWUT028O_73AYU$E#&Y+O/\WA^:,O?^UV(I;@H*2!JU:X\-K[ -MJ6ZRSE9Z.3N\L7`/,B7C0IU=1+AM8NY=(@BZ["5`((.XHW;7I:<$9V[]T@HQ3&SYKCKXY8/ -M0/(=C-G5/$Q##7QU=*DNUD6&088E&#[7+&2>X5)FDMKL]JF@>EF[)T?.@3G>Q6T#_6MSF5F/N%,N1UPK9C^3N]M:K -M,MX$UDK4#"0;/O@CCXG+MYM%X#9G_O&53-\4Q8/>R%VAJ#SC"XUAP14XD)2@ -M*0PX+P.U9#D^_UF*;%&:B3MYDKR5TH+&;DXB`Q[2YU2 -MQ$+B59<=,]:XLKB#B'O<2S.,`)&(6H"DUHD22**"LKW&H!1A^]/Z$;)0O<2# -MA6*F?U',JBHX&WW#"(CR2W@`QW-0@!5B_&;VI3'3OU1:S?AZ[T4&SD]7WJ.B -MA22H\F^#*C-FX!/Y9VXC#=J,&Q$`1+Y2"IG^9-/?F2X_H5X,K8J6UWL(GB'( -MA$B+-67Z2._+YT/FBI!ZETLE_CB8Y]2M^[<+I)<_W39'RXU(MN[FKZQ2%P&L -M&%-L2PNIU60EQ=8JB)N`':XJ%-G3*)E@-HUI:CT1#XKO: -MEU:KCRV)F9VFJ4T]%2@7^S#DP3(*\EWK8UB7(_>0-JL\YO/$6M#$B4.F/UA^ -M.TYI;][@>,KL'C&&ZO'B%@@"C_Q:[EQ6-=";P#$:.F'>O%#:1DQDBZJ>Y4G[ -MUU(^:(\D5_>9&FB@PAQZ[QTQ)EF__*8T.UPPERZ8F19\DR"&J2\3(^\=<*_6 -M8'-_E`GXC2+2J;$47$X:0M=%F$ZK1.>Z4>0#AP<:!HQ%MZ(]\D9BP*Q,RD6" -M^%A>H-B_H06`XY@*:AU9N8,%C(-2(!]WC6*&<-:W3\4QKY)[2Q2`7\L5ODQ5 -M&X/;O[]B#R-W!_5+`4'[LXV6NT2NU9@C;>IE]P5OGTA;%K5FG,IGL;HD>S@+ -M5@JQ]:XGT0\R^C$*$#&A&_"Y"T>2_E)KCE4*.@*O5DB0!RP/@1S/S`F\^)`T -MG0(K7%:D*0T^L!1,RQ/[CH>D/P($B^-G7&264Y_"2`H4[!Q9Q_TF679'A!5. -M+"X\CI/ATV;`QDC<>%/M6""H`&BH"GCUWL__/D*-!.'O"52@_I:WE=>Z' -M>'$%[XC_RG`>4-;F[M82@EC1W=U&XTU]YDN/_ND(HT_&>?GEYZWM, -MY_^H)BF[/O-<]:_@MONK/&;?[(C&42J]]H][RRPO.3/$=8Z:9\,Z".\$]K@1 -MMV/I/B&T[7AL*W1#YIR2AD'="F_HH -MYIF3I@?E_P,>[6":U*).:Y3)/34-#\M>,MC*.`X&=&JE85RZPH[(`!5\Q!)1 -M-D@LC[K8T(X#2MG_%#H69AFMM$E1&3?NF.K5->53\$4Z_^:S@X;G1I=5X9Y+ -M`84M&U?5!/?`C,81>D!%[#!]G[3Q/%6,P9\GK![-AYGRG#='/7*3)PM`"16^ -M8Y]*40W]K7ZP-B34I6"2TK^R2R`;SY*)NF;![P"FK6P=&3D$-WR]$^?>9?VX -ML4PP75)N8-2-WX(UZCDE]1]_&%1R#ZT4N'8[,D -M==AD+(<31>\%J`/&M#B@]YOL']`CE\$VUH4):[ZT322L+37!X1DAW'8.`-/I -M*NSOWN:/K^9H(T3]F$6\D

    /N:B[YC(B\@P. -M2O@NP_F*$]JU#<2@@.S90)E'@EK,\:22=BB,ZMQ37FF8QOJM-G&R_#*W9W!E -M?H1F-+3<5FI\^WHBXR.=BE]\?9&Z;'KWQ)<+I[/YO8UE0-,7`T$P/]"`+$\7:G*33K$$ -MC`KO$ZO=D8-I&7C6]`FUAI-H*\1FPTIX8/2'O$:1RF8;JR02G-8S=E*Y.JJOM^B?Q&:?EISBU@X$:!ZTIG*.K4K?5 -M@=_4+\7-'RMW/9Y`CULQO;/_66_3%2CEJ1.D%LWJA?B?HC/G70!F$H"$82*8 -MR>EV$;.'I)O84\L1_:@A8E=Z!1+DF(Q4$;R[!+.9PB]@8-].)C>EUM4234H> -M]V1$N0F:]5TM[8^6AFY/\&:O56F/:1+_I5AXSUW:WPY:N,-EQ>#L9)*0(3\Q -MHZ@DJMGAOW?*QS?E;3[\Q;"GHS@:+T -M%)9P2PA-2^"_CHPZ0\9MLA"-R5Q!CLY9OW$^,V\G!A%2MH*3]?[PR-?`$-(I -M="?%0!MPY8`^#D%_&W_#SJ1Z_NU,*]J'>0Q<0R6`EQN'(#JG,A/()@-AW1N? -MJ#&@&9%4WGD)5)4?AEH`21J^JCR17X,R,:%\8Y_WU\I9E='VDA#9CISD4$J@A0($I/S2?J)5J%< -M"`B8TI]OF[FT./9'70?)%EW;+KO]2_;"C4R+QQLT<%Y -M(S*!D$1W&N-H-[FB?HCA\LFMD2`Q(0 -M&7=85)7>31 -M"&LJ8J:Y9;]!S5.5!Y%R?ZI"EC%5Z0Z']-\\RJ&@)F\'I4'Y8B5U0+EA[0** -MU(\*PPE'-YCJJEDCO9DTRL1&7D[C])GK_54+EE;:B)(U'.9NCGM.0T.8/2SP -MN0!'R`,C\#^E"7C^@V;!NA3J>_>$O -MWZ)U5M5>Y@5RS>VFP>=]#_MZ+42[;TTI%CK-KI2CU$F=&16DW9G%WW@]7[[3 -M+=]H+YQ#`.%XK3H,TK*LIQ443!EVL080?:_LW"1CA^:N']+DS'S=[DFHR+)] -MGF0^8?8QI2&?H2W'`3()*I9\T"M^QF,;W@+/IUQ6;IN]N_SQ`FZ>[3^1#:-? -M=`S>/1"U;->D1+#8`OKUX^1^"4QV%[ -MOHGME`XIH+UL3PT4KHT0-EP0NGT=HG@BD;-I7"/V>O)%TW#5-ZH\=\EHN8W^ -MI2[C2**:N8;R9,[CU$,4X_MUY2]V[R75PXU,J5BQTM21;#L<[;E=5DA(@LQU -M^AXC"+X";^OG=,S8K#MQ^MI-+JT0#6!_I:T_O%4(5C"A2>Y)!R[_AGHJ,EFP -M[(-=J*+JO%MO5SU-!R*O4XUA+I4OM@OUZ078!G101R#8E`-F*#2CS7TY^I@V -M3KOHN",%\Q,^:/GH*B]G)PMT7]E-F3@P.0LP-%WKIV_W2CSTM^[9?+_H]OF% -MZH2FHPXA?7(Q[(9:66CWE%Y(!-ZGJ$YI?-.!UV[W5\D!8BB'V24.ME$N4XW14H+,!2"F#L7!@BQ("ZGL?]=BU5A!4-&\?_<.FHI> -M)VH=Z@W1?S#:P7.X]^:J+M-3'<&'MDE?,T'/*]4?. -M*C2M'9-A2GCD.'MFMAT,/8GR()6=FL%U[H)9;_/^_QB -M@&WLE]4HH"`R*:V5\8_S<\_#7/Z+%`'^Z+6R*Y(NQEWRZIBK2*/O -MG3*W_"H;6Y3'TQVME"YIX%?16;I+A)ODUA_<,]-:\-5,UW)RNR.D2-L2JY?J -M&L(2;LW"1_!HZO'5J`%D3R*KH2SZLY&V9\?954H>J%982R8^MKUN/J\>].9^ -M^4B:GOW$][_`:16`^`*T-Q;@RSX]C7G",K)([8(?/XZW*Z8_8HA,5O%2NR%[ -MG(<8++O:_LS)=-1\6;UYS&NA+UVY+JH%&1T>?:N\)3Z]9K1-L$9-2'J\PH?>&`BN-0X2ZEVUC[ -M"_.FB5DR_H$@I#W\/K$EQBL8K$X?)]I,YI)-&TED0W[AOW>ME58&-E;[V1,R+\O82CG%3S&EIHQ`'SNXP_Y(PY3\N2O!6PD)/+ -M9W#]F9J+A>`;>K6OV#*H!,-:W/)6]W43ZJQ0WB[3@`Y'7;==P_8MG;Z*S!%T -MD8B@P=U?N"I$VUW;CYJS`5)AZ?D'=1VMXT=`_'&=WFGI8.S>[5:1=HS"C,=/V`""G45=))+X@C*<(?Z.QZ9>*OE8)3>(`?>)QM(SM&-^L$"3IPT^P -MDGA"4'+R4-[<)`Y$J*-DY.TZ4R-F`X=B,(![9(XQ^C^DFVY=M2I&NN7VOM?0 -MX%&@XKNEO\WU_?28-CKFN0/R7"+"B^%]Y*83QJG1@D+^*+%0M^I7_MWKFL*4 -M*&S?\Q555])Y*C_=MJH1I=F&XG)(.'.=@DD@5,7JBC`M08^LT,QN&Q]X*?B^ -MX;I9C9VCU=.*_F&,Z-.V8ZD-#QKXZ0"`X8IUI:\$U<)D0'U+7\9)R7>_,<%5 -M>Y/]OP;KZ*_'(:5'4"[JUT=&*BP*9G%3]2=[6H#BJ$4MG697>^AN -M<4\'A!@)P@SYEL*"$+$>QL'B#^*8HI?7J_YK_G&1B%;W%$H&@Y:E1P\+`Q]> -M^QU_V-_L5TJ/.H)QCJLL,4[#%`Y@Z/W7#(:HV#-GE;P=7(&YG5BB4(RP*2K, -M398/^^;9'8IJ,.TGBNVU[Y1X&7?2O0R2F7SFZ<\X)*;D0'P(8O/U%"*P6;ZK -M(?[4W6*T#J#\/'UY)O3B,C0&+5,>*H1=S3KHD5H/P943$TAG\`3.?T.H<%<% -M_>8QKWP!?N1\G0#`R65\E;>!_VM"3Y*@Q_T#:/,A%4LM-M_9*CWZ%%VA^_SY -M[VP\1(H/,$FA/0J!"Q($1NFY74U?22!0-/6NM@+^O()1O$\>VF-6E'@"\6J/*//CKSP5L0!';:T2G -M02(":U.*+]`?@ZF0RW"P;SP7,(.7J7Z+$SM%6$,_.4#^#B?_A-^20:P,S.$@ -M_+PS:&OBJ`5[$"*FN_`,9B9[\7L9_M#(\'<\MT57%/4&!P%!.'8;903Y6?D* -M,G)+..*\5?93!M#LIE*,C855B#XX,UU@!1S'EU-,6WUS5$GN&:MG2:%72;57 -MK0$")36BQT__ORPR@9\`!R^ -MK%-,#+7W<2H;:D3U&)#)[?14WR:6_56,G]^,5N;35P]'AUUEAOM230>].^5H -M^?3N==;P/L8J[L`6VA5ICY=P"VC=P298M8>DRJ2HS)3]UP(9`S4YBES -M\CS"%[4@45HM\+`Y+$C>]N$?<@CES(DV*^B'4P_-\R='LC%$"E*X_O(;&H?4 -ME'X(O80*+6E+?CIP6U;EALMVN]@BYZ4BJVHIIOXD)0=1IX\TW-ZP:!01JQC_ -M4=1Q)Z!(I+&4/B60H^MEM$RU,G9T.,"+XY=(U.0L]NK'+'I!0<*X+*9==3]' -MW@#?EG<\D6QWIQ7QH01*@PR.N2@ -M+PLM*/\`7="$\_JNO?HT!R:TE?5'G6`K`S-V/3&Z!$.QIS1&N45\L;M((`U- -MH*E32\%]59.D$*HV,,^J'6Y4A,VTR2C\BCW+0$KV4=C2IL7HK0CZW#7>EHU8 -M9GOC#O?"B(V:G"61<18<^F6Z&SDA#$0*:EF5\62CNX37V:^LM`D/X"5\=A+E -M[$66.+)%.1U>4N.F6U]\Y^?O;9*GRBH?3\^,%8M;IVWE[^DD_"H$98+^9 -M$\A^_5)6TG'\%G\G$DCKMT1]H"951WB7?/T9/=67D#4PHY1)B4YY*T6+4J9\::Q9B2(AK%V?C)S1. -MQF347N7Z-W$TV#&][J$)(4+W530\,C<2-=@.,@>Z[[9V]44ZBM'L[M:#H0KX -M2-#U=_VWV8!CX>/+R@(&'.12-@1N&+N_O5>^@_%M1/T?'>9GFLEXK -MK@__;&P&?'AS,VFY^TI^(JYT-1-;G;RNB'MGL_]*-3/BI\0;CO_10KI/*`-O -M\9,@'P(U@1Q32JR[G\[H@O>\&X4 -M[%-M(%&%M`']$>4C;#]G[WX3T<>PMG28=$[.)U"-0);>@N5K95`MM)O,-V.2 -MAI4F%MU*D^J:)U8,>8HWK%E;9!]H),\D$'ACU`-IJMF; -M>\"O"MPT#KBVDM4+)3;"J/>X@8YR4"LCG5QB#V73#E&,N+U^*Z&UQ?NC649E -M#=IN>?\F++(NZE!IKE`V)I[L/B57J*8NH(=V;((-9Y[3ZG#*KOW1IJS*!M-Q -M"^LM)??N.NM!`^J1_KC%.L-:K?FJNE[T?,&NDFT\W?!J]@V#U9`8&Z7*D2K\ -M9JZVO^_EY(TJ-%;+!7-]RJ:GSCWRI_/[:N3/6KS#^;(I<'=R%'&"YIETGM;9 -MOM^BXY[0^-U5K\1+:HVN,#47C^`89:+S.=ZO -M*7IW8GN#>HWB8S:J-7;0\#+VCH#%,-C8:-9_0=E1LF9O0U-"&EVFE:B.N+6H37RW>&>71.'ZX*1G -M\;!4"1=[RCE):=R&0"W7HB;DQ).25M+QLE/)<'SS=<)$C;D,'A3IK&<C&@T*S"!J?>Q#+FRD)>L5H:WN:Y3:\(O)6WPB)?"#$F##J052!K^2Z@K[ -MT[OE%^=,(34Z5L4/9#5>-&1<'D!!+Y9;Z5N-6*)!<7\5?UU5ARM!^0;5#.6:9\`.R`I4OQ(J`8NC&!Q#]N?E55([;`0OL]5[HN36?,W -MY1GU6-IL_B!8^-2OY+_8!2]F/)@\*9#I8`9;0IA*L(<*]Z(*++=M5Y5Z,V?! -M6O/%=S/J@4003MH\L*'W(C3%,*J/#IJUU][08Z7[EE/&H$&+-B7HRJ28O!V- -M&#P]DB.=ZY^2&!O6,93NQI6/^!37XJC7Y.-=95?__[M=?*2T!XHEY_INL.RY -M<_[V2SA*-?4RT+:YHYCJEWPP,CN+1HS)_KL0O=0DD\FIKXG<@TEBUQ"2@&@& -M@;@EF$0W.$W/!N@-?&8&>RS7>1?*C?MN4OU_RO3+=4(?T@^31XE'=W'H;]JK -MNTU)GK!%CB]Q1&Z=5L-\CD"WL0+A`VKKB+C$T.9H"-]AQ,]D4R&-WI%AP3+F -M'G66F:G$_,L.^;=C)L3M4DN6;:,+@D<$R$P[%(.Q=EJ^P*BO;_>Y3(95+&?AT[%&%3GA(%$SE[RQ[W+(W*7CX@/)126.?*-@V4KC/: -M>X?A:(@1ZX602W!<`SUSCLLU:)MF2&JN[)M_DT`>\`(,4SVI -MU^*%%&?Z!HN(,/HHNB!2J#7`[5WUH%TSS?)+@L.^RBL;B00Q!Y97-E6=(Q<$ -M6]9/`(-11;$O&P'9GY5'KD)%`TDOJD]R5V/&T+G9$DC!J,_45FTY>8-,1SMJ -M[R:U,H2@<0K5G\4B$UX/D;7_ZWW+";YTL\X-_RP[U&=R`+M -M.G`,@28'_O#`^F:8.BDC;2<^P++&](X%R[;47>D3+)ZX^DI,!E^ -M5I4%8K@8NI-4R)F3+G,,]J!Q4,!#`(<:S4!4J(5"_6KW,QM:>Y0LKX>WO*S) -M-O[^*5!+^1LYN0,NI)WXUP!+EU:ZR7M2&0N^N$7#-&V(&?I6-V_2R. -M4M'O0,SNJVFR^TX!/B@;G.R+L7\`O?GPUK`EB[B[2[1G*NN.-3_.*R(,![W& -M'VNJ%$>H9W^:4R.Y8=*9?U#S_CZ30:9D5*7IE2VO/R.?H;-!M;*]_/1H;Q?/ -M`91=!&:X`JFZT/W,):U5#Z/;]#['78;/(194[.C20S%$X#!@H=A/`O-;?"/X -MT,&<;06*+TG4`JD0_7E`C*%>Z^)46PUK$G\LJ%7@M,L@RB*TY%_'6NGJ.Z+R -MED(ABU`^#8*JH.D9/)'G_CQNX.3--O:6NB2F^H(T[]FLUSTEGF/H_C@[>@OT -M9WK2[%UG^(!.M;19HJL!!XMSD+/$Y5N_I1EE;P[()Q4W7\![%*U^!5.6*(]2 -M51TI$WZ-+'S0N1@I\^`-Q"Y008@FC2W6,CD+&A+5OT%$N;=MK.QB8!"&Y:;(O'N=,7W1EE!-4^!Y&D -MIK%!XB1^_'TH1J%<)D+H-'.?_]!(F/X0V14-&I_4T4FF*;_T&GZOE@VHV\EF -M">TX\[+F -MK?15\X?*<3S].*!N-G8WH*GU4MUG[&UQNCQS>VP;N]C3;(7C^I!`;:IU8#,A -M4V6O!"L4+<7!JRZ-F9[')M.2#/'R>J6Z-B5%2M%=SH9:Y< -M;=GL+"_D^Z=AP'Q:X?&!&&J4D=?R90JFP2_Q*AL*V3<+2QA7TEDYRFQ3\@L> -M5W:Y8+'`]THX03-2TG\IW@-%>U`G?WAK@Y3?N]&()4=7X_I.&PM8+]9H$5B9 -MR[LG:0!/9SMB(%Q<^$9J.)B']5%I(&8N4../NNL"LDOW[=5-S`K3R[L1D/FS -MFT,Z1@?4';"91ZQ/TK#LJ>G14D(DXKA'0_VP.`63JDUA#BE(:S6^Q'V$+:[[ -M_#8#Q@.#;FK]:)9V!M-U.0Q,K<0\W:BDXYRIV5T<\/I$MU*4!R,\.`NO2C;T -MYPK!'A'X]/QB9&[J44]HS@N&X3HY0/UBD:K35IKA>?9/VUHD-+C6G[9DV/B+ -M\K28-C1TB4XX*&20=]K_>:#ZDUI-86@(6TK*`-&W^``]!GPS#&DN-=2]A;P; -M>?QX/J4W*:2+><>O:YC#SZ6':$$A+\I%(VE(I3>C$^:`$33'GZ?9O\A`S2JU -M)2K:Q7%:6@,L?!M)OO>[92NG<`]H&^Z`^6ZBL!#IML==_M%(.0,\^C07"X-5 -M;O5.!J[G0O[:(R]WJ5UQ689SZ3!)DN*0Z]JYE^_5BVI%V7XT$*'NN6]0(*FD -M<308]KWIR/*O4Q3*]QS:0KJN24+'2?2-X?"?TTB^;QV4=2!QGW*]4_]-;*;G -M21.`#,D,1&L;D;-4"]SNK`+Q1,HUG==JY_'#4)F!;#HKVET=O(]0URL62C8EOHO`^8(H#TV?I]VETUJH5Q8`@Z*I&`)E^"W@(\6 -M"/@5,=W)!PE\>KBHQP]F;BZ*Y"O(W,)!I9I@'F'\]$4VLKI.;]J^IH.$_NZA -MCFQI)"PL:![*H\\-_1KY4L4]W4GAI(8PE\BE*&5=F`>6-VX-H!":).X"^YU5 -MO`@5NU*XKNED&\`:8?];F,!:%@4;!74YK*M8D(+GYJ)$UY2)_T*HRQ#<6DY2QQP^Z -MU3Y=S53X@$K)TYBNRK"LKE.NO -MOQ_!B0EO;Q1FDN7+=#>Q.'K]Q1,%3W;22_D``_VR&L2@)9N-.((8P8)A7?`? -MXDHM$&:Q_:R._TP@CKZ,G;7N/W(!VAL[6@GMM03DD,:CI=%\@WJH\70LT>ZE -M['$D)OXV>HP-(+DVYQ`?FO:/?[4*`TODSM8AVB"CT*;N/G>\$I;MIN2M5,NK>7\JH&HN"6+3W0%J -M+IOK^O1I2B!^+%@W%T3QYW9DREGN&1FRQ.9(F2-H)DG9XS`OBGE6*/;P@:&. -MW[MT\,F=G$LV".C>SGBB-8V!4>XP5V[S+B!W7W[X5@S3\K0\MZXM?:S>"B/2 -M^')38XUVK>KH2*$+0/+);$=W8VO'/9]?GE)ADV8@2NA@$`3+BWS*+=!C;JUD -MABT]BHI!869=@Z[K]MVZXDF2IW/4"*WP1552XGU))2>96@J6K+7Y,^E/ -MJ4B"N@S?JZ$)K*=`>/B_,7O0$Y:]A\[PBW -M_J,8T4X\EF%<\9CV=RT+&KWH?3"8CP6>4Z7#N9)6L=LI6YFV)*X4^E3&;D/"E3RWO-=)>>$(O+].WZW<$O>\X7?]='`35F/(A] -MV:(L-@%L?(!JS[$'!$S%6E,IQ`Z3JFK`ZSQ&MI.4NN>0W.-=U3(V]D>N59^% -M,B4*VZXI?)$,8X755%"OV!;ZF>HM<.JL#R("Q,4FM_;&J@\,?J7%8I@0!`#5 -MDT>(A+!NB*!\IG!AS,:3*A7;PKY1(]UIR>=7/-<:%"$3?IL09A7ED+IP8L=: -M,UCU`'#Y*T_I?[H:U*B4'Z'>?,Q\"A!_F2<=4U9L/:8X\&==%Y[#KOJ -M8>-V,^%R-\#2BSF'ZE]=6WZ'.CUS6>!8K#V7='0:>9-4YNWY]?HTYY5P26+E:?..=4 -MQ6]FL=I???^JB.4Z0/&CZB6P8B_(<]IZ0);\*PP$CGVGG'S;>O-P__!4N/&,#;_//G`UZN'K2P5T>^:G&P;O#;\1CE.;BS+_:*191YLQIHS -MPAZ"%CNA_Q@!@]\C1U3\A5X)8H=>=7*$8X&5SHVM*ML:,6 -M.TRWU6!)94EG$5?(VRDU;X>/%,EZDES64)TFI>P -MY2D4YNPC*CT;)9O!M=N;0Y;J=9@+[*WT^`PB'[;PU5-D41[N3CJH%,R\U,K[ -MD]+L?!!4HU!^*2C"7AI<6VH6!W.SOV'>VNL\IBV&[PQ;8V[`G-JF]LP3-(58 -M64=F8R"`E?_#5C>#Q!=P2BNRQGEVI1`N0ZR@D;!G.,DMLG#'=F,J((010ZS( -ME?:@>#1_S!W0`MB\Z/R=NOY@;C -M/8`UXE]P5(-7A-\>1/WV1)Z"X^-:J<((*/3J<7CEUH:H9US.\\F:W8LL]/C; -M(=LOZ!Y)><#O!8=PA9&O-8L1X3J$YPNJW20)Y?O_C0?LWF4PCQU)WI4-7A4F -M7;:!&&?UV+=RL':IV:[A`C)>[$C;/L;'%%P-T_FK]]HM8$W[0:>(TXF>DJ5` -M0_/K$\$H>X)T@^!(1F-:O0`)G?".,A"C4X/=G>^/?%,^[J%S1DO#*O7+MU=I -MW%JV>9G>]'-8V_:U08V=,@9S\H/#`=KR(J01:\X34A[".R(!/`DC?EE=@7,> -M&XFU\D0+:^.#H>\P.JU&:];& -M>SZ2P)&>]AWSW4G[/BC",X"!P+,L8)98R\JK:HFM".-,;JD`TYTMI#W)G5\Q -M/YW>HGV78$S\MY%!P!6/2!O[Q<]@U`F,,%E7U;(Q--;#3,$&4TYG*AKU!K[/ -MW8^1CH`T08:>,[\_DB]NN;K'_4/PZ`^[VB)"KPQO;55@Y)B.)KW3EY4D'&,>8?E2WRDB6@-Q9>/RJ6E(#Z'"8RQJ:9]U/\H\#(+46#= -M(KB\WG.,6Q:L5E#\P\1U%Z_/699=;"YN:"V41B=5B1&GO'PSOMF"/W7Q5IZ/ -M%5F*G=O.]EB:]O8>C>^9\!K8_;VZ\$HX\QJ+UEZIKK1] -M>>FT1\@X0,BNL0+0JP-)R;>%T4PY:1SGI)AS_=FVL5UY^@#(7UN:GTW_VO:: -M5M!^":*^/P4)"*AK>&$MK$.@"532YJI$RC_8.<'ICTA"M5Z,+G`-EMZPZJ2> -M85CZXR>/'66F3<9$KUV.#!@S`52"A8OT\*Z_UO:$8$*"1O4Y<[M/4SSI5-CL -M%^77/M6DC9Q#_\5/:XF^GV5M)O4&*06?V3GB#X]SXSSBPEI+R(>0QH*%*ZB- -M!WV0@1F%2-7>729SO*,JN_56*_1F?%/Y@UGK -M]0S=5W!K)Q=2-VBDO2^IMTPJJ_3R]S">?U\ZEXC@=HP'TVRB'#T`JN-F-DFE -MQC+@BZ^TBFT/;8'YSRVR=NRG\ZM(-S.<3XLM7\-TFJ!U3^W@8XC88)7T=9TC -M%S,*/A&#K,9?!&%H'#-FD$H!CU(BW@)C^<(6<`=+'B!$NV.<#T^7P'W$>('6 -M8N'>F5+/^D*0X^@J'-"G_ZM2GW3@@I?&T'>6J^(O\0LE+Q?0D1O=&9MK12LH -MIQ'ISR!AF;11:2=P#.:^5$_6FM1MC?KD,XE1G)P2Z40Q35'9L-0==Y"E^'A"6&KQ, -M#7AEO67?S^K&AEI$/5\38&V5$:F4BZJZ#8O,Z9&2BE)*>9ZS$N', -M!9F@"7:R?GG>%N@DQM<+@U"5\V^3SJ5PN*UH6W'! -MUKR*%P0M=KWI6Q53NIPF"FNL(0MB0`0CD\8ZLX8:$_&"L3:RM.$'64XFZPB? -MM,+(!'?OEF6#)KNDS7=D-<[>4*Q^62/N'%.A7WU$;03-4B=289P]O8?@WW') -M*43T74IP.[!OP&1J]HD71$W6((3S:%S_SL29_.7.WDOZT)P`4ZU#!MWS@^$@;US6NJT\4G4WM*P -MMW[&"DW(@%[W&="02O>D)Y7>P9*GD[=CE002\%NNJ+5%S:5PB8B(=:OB?6GB -M);-^!(RGD?G0'Q2W`7[NWAXLVL`R:09IEH^^&-53L9X''? -MP2"0^QL21E?IQV&1+N5@,&,17&MB)5HK8N1ZK$_#"@POSZM#H>NQ<=50E,Q@C_;M]Q86Y9*FE1KM9L,@ -M?AV>1O-=Y/S6'67NYFOWBW@6.<'5/=LN!DG&HFTMB(975`:X$-8&ZJU1S#`, -M0IGVK$5&RG#,)0GS(-28+FQC!4&*C]+&1.NBG$R7XR;8N9ME+".,OCS,N/8Q -MP9,8<\Z5:1LV4)T(WSO_@)7IZGV5.*2L>R!39"Z!,;\`H=(?Y+*7<;"]Q.&C -MF,2RY35M_\=%_\!]6.!J`5K_)1VU*4[-ERS:.Q5AWO4>%/QK:66IZ;YK"VO]9V&?D-_[[0GCS_I$9^"P1/,+)YI]]#Y=GAIG+`0% -MS:HRNR?`",WBK$+V*F/S4>N7^!%/Y,9IX9%-)5]67-3IKN<(CN[DB>UPQP,IG49T#V1&ZB<;M[:WMQZZ>$5WU$,G#F.;NS -M!MKK4V(*[VTTO*!IW-&?T&&J?PY0<8P\[V\59<,F[3_+4S6J*?1ANIPA-:2$ -M\&!Y:@DBW\.4VU6V5P[]FN%W05VE9WH#;ID3D)#0>2Y4BXB=_"H,1(+=[%I4 -M7FA`0,]X%*0/D/,GOX(8XB$9SR\B$D(N;KR]I_UN8*UVR\D=EP*>X1EVAWT*_T( -MJ-/E/55RZ7]O\Y:'H3].=\:V4=/M@$LJ'HX1F1E![U;MN0W5MMKA+I&?J.AY -M,26'`MR+%%5D:H5QIV*F4%""(8IWM'IENT3(LZ=:1PF+CF\[F#;2A4#*"4%#)!B,Y<5CD@$"*(.;+S(U`(@LX30F:/SC/<212D=HO -M]JBX1W_2O?KIH:-@]DF_JF#UL>-,QV>+)R!!]%98$$FX&\UCC6:%;&PNZ5>F -M7FG5$?$1/;:1\"4Y5TG<*LUO[')T:4QS\4)2!R:U<( -M*M3S3X/JG.'V-!U@'-X&GGZBB7GJ"JUNS4+I!PPS0RO,,9US6+--\E=X2\N_ -MI>V#T;5'O\C"3LP@A1.M-XD%\';D#"__0AG5K^VQM4#+7K)O^K>FLC_KYM5; -M4\9_^+R>YYX8&KZ:[E^%D,\":`*D713OH/.(9Z&B;%"?Y_K^7]U:&_RJ*J(' -MF23N-Y:$U4CA7_W2$&!O6<&C4[`#)>/^K218<.PMC'C;#^:7!Y;/>._]8Q*, -M$"3[-Y722XKU=G:TKKHY_VIV*9-#CDY?PBO!Q-LK#8O_?_A44_0A+*%9A86QR:^Y1-H.Q]JU\ -MJ>L+SACTVW]7#K=%+3,[*>N'A)14$C"@3U3&57P?ZP'VWP,+5/532:>0:I#_ -M.^D^P==(CN&?36([.R6MD-<6GO\&Q/7%O?O]5Q9ET2C-?YW\4JP)$10?.O$^ -M'Y&+R+WA!FE;TI_N0F"U:@Y5[BO'1*B(:,N7Y!PEV)11C-F0>HVMK0-1AD2QK4+1Z^82T4;E5.9>L[&F@0X0D#-\,N -M'3=(9_;N\K,D,QM^5?-ZSA$K#7[*G-HTB0^M]6;\CF*Y+>:WQO2(R*:3)[A= -MB0]AG;?8^A,QYEKH@(U)/X\_>.O,_RSBIB0GZS*[U>RSJT64A5]>$ -MNL=-YIB#4,%UK,O1C,S:_#N;^!/2%7FT"/_5JDD_'0MJ:86 -MV(ETNPIO^>9+/C(W1V'X\G-;>*LPD>Q5$+X-$G!TPTO1]?*J&5^I\S:UY=OV)@ZH3DPUI(=%F3UU&K(@M -MQ8H2QW?V_:,HT2FBZA]1'?&\Z,!QT19*;1A"5),QV*3`D;.[.T*FMO'`[3"0 -MPL7O+HWFX9QJ#Q!]EA[U2^^H$,F!VOR:]SQI)PIX99P"0#Q1*""0LS]`19;$ -MY/:H7G3W\D$EJ*I[!;KSI_21#[YAF,?Q?G9`#1DP5];&IS:>E_`#B@9IF]RC -M`V,9R97DXU=#=^C]7$Q$L`^$K?A;4_'C"M;"$W(DX`QY:?"XO8]YWVMQZ"V\4)$6>,W)Q; -MR6_D62G8`U:\AJ^9;TIA145SBU`FDB(ZY`EY7!)HIVLO#D]?`@W1"/5&@6-T -MU^5\VWAF@)(\UI^1&9[I?*38Q]R(/F7":8F#VQQGVE<`[*A?F8(D`4:':QL' -M?[\07I,Q%+SW*SCEG7KJ+N,2UQ+C)#F;1?$38$]^(]/.>4;KSNB@EL>8Z74? -M#FW?6-Q(0&,8+]O8%^+?(EZHOOP88-KA@!Z!V,!<'D^R5!<=P;.;I?A_GMT< -M-GL3ODUK:W6D6GY^@`2A!N48 -MI>@C.0?#1QEB^GX3\GI-9%J9Y2_7Z?@3WUJ!&=8/P2-V8)U*)D,"JD$\I':/ -M]DW[;:T/%SLC4=5W-H=8E5HNAT:=+#&9#"RA0[@9F_B/J;[F4(F8-!V1W!`' -MO`2Y./]/)DP5\1PVB6#]M)8_4]K/_P%4U+&83K2E<.:A?BS2_.=ED+3-U&3F -M%[[,D2Z[K*:^+RX>@[H;6O22/#UL=.)-J2.$6)XQWF`)'B1+;M7G(;J`\BLM -M_7S47_%9WJ1^UYVC&O.\0N(^W-RTR96E5;LRIAJ0,\(R*!CYP,W*Q$+H5^&1 -MO'BXW^':[NPT?91:9E93?1D`WZU0T*.%*\FK!LPV,J\H$22Z;O54K;`$==5F -M[&'N6KVN.\9CAE9*!2U05%2)82LN%49I'DAK-+8*5HO2^.B>LLMW4WX"/A./ -M52?=T+^ -MK:I`?[-<:TX$8-S,Z-@EVDM$I71R90.&;H%L=`3+2S3L^]RCB5HA19E -M11KDL859IK`_:)P9VZ.IC6T3064!C8I+JL@->^M" -MXPD@\>G"GWQ=!V.D-VK6(@2C&K/3)[T=.B+'\_)WT>_9_7Q=-!2R2W=N3V>A -MMR4A_NX-FBH!<^?$&1]6XM<)VC3@YFJ<)D"(*WWM;9_:^19W&KRI+5>LF$+' -M"7)=9`AUC/,%BC4\)L*,;#?"2&O7IPWT)`Y%T7W^]*J@.F)]V0*HD]&HP>`] -M'C& -M!TAWP&JC-^]MJ*_M[O7RG7_XMYW&Q-0'W@6\8#L3RBKWVZ2KC$C):/,ZKB2C -M_6SHSN[1!U&7[L83""):H?S6%X-I(CBI,:#GU]_+)K4X5^!-U08EDCWSKAIS -M4O,G9#6_E,J(=Z(V4\YBOA;[D9IT>_6O;)08LGFHG=;-C^'!YQ+$LW@[HLL' -M\R`;;>N?F8K2!N$JE:5F7S:GE38Z)<6R1JO4&$WD="?+),`54.6@V\TS6/R2 -M2%^.T?*4^51K-DF'AKGJ+W02M%D`_10=H[;C_4#]U\BDWI>&&NY'T>4&T5K+ -MRR'F65O'TZ$CN.1^3F)LL#L!PP4#FS#-[!_7=XRSZGI.!Z(Y2;^W;HY_="`3 -M.:%R@ITCSWJH7!F21OK;B"H%=8.$!-#8(Y>P`5TAS0T$,\8E`^G=&'71?NFA -ML5W/5(Z$NPA&%P*$(#Z_'6"8X=FH1G_R[.2,/R[XJ\.@'+SB#O1M<6D)EAC& -M49IPROCL6&L4X/-VV8`A`N-9;YR"^&/=/&@XQY-^!CR_@!4B.Y)4J -M3PXT_E'^D'VA8&Z3XE!6CRF=YS*"QBY0TB>CDR@K@1D0UA(5\60&%MRD36+* -M._/C)+9LL!'XO-W(WS1X=(_2*!T1:F#+%+"J;G2;5,.$WMY9JV6B=3;8[EOY -M7(Y<)"/.*'/*3%Y*22CCCYAAQRR,5$!0Y(%"MQQ*A1>TT$.'*7Y_XC"^PDBK -M=%2Q:C(->8+]'UW=/89.BRT2>^-E1G$"VU]BA=NDW4T/_H*=Z*<#H1` -M?"[#.MQ4=S5/MBH0"(FW:(I1^FAC,]L%V1YE+(E0Y!PV;FR'30WJ5OS$]+YK -M[(79\#$O1CV=!/H.">O1;37B7)ZP\J/R0E?VN:I@C\E2[_GO5[#5I,<)@7=U -MSN$/*H#U8)VN32Z)^9L0CK#'K!I)&"ON=3E"E][]#/FZ%H^:CM'P#M`2V\QW -M3@^%Z!5W=1P^L#J*=M1_71W*(1$H4KBHH_.]-T/H6TJJRX28B0\1$`+;!^T[ -MXRQX*@\+R(-[%^Q)FF/"]/)/'73=>CTAU<.WL90M,ZO0@^_UV7%].&>^\0EO -MZT9$*+( -M#[3?'+Q18>Z>G^`HLM\U$:("?")PF?C0( -MRP^.F:L5WY(A482F%Y:M`@ND/-8:"-E^(FB?J2Q81.?BG"9U'=A>9\+/Q(?5$+H,_F]8[; -M1NN#<(3P&7H.M74',FMLK(E1)26T%',@CK8B&!VOG@WB@IFAH(%R_GYQI481 -M%E?75AU]ZD$30KDS\9LEYCS\$/&\2UP&`B"B1RY%+SX7.A1VD4UJ -M]'J!(_#_CO`8_3AM#$EZ)-]7`X`O1I&+YVMSUM -MKYO-S2G\VJT^6;\L/9Q7'A22QC]P96:P)RGK#);^S[N3YSLIP+[F)//KVAB* -M2!0AQX`IG5J/BLX7PHNAWS`-[TQW*#1)Z!/J4^SH-I&!;,W[.P_W+H!M%6Z! -M6<-Z,:S`8H$=]A9U*H7'\45Y -M?5ZZJGO?11:\2"XAAJI=/0U9C!$-"YWE-G=IC*:"ZFJ(IZ,+.BF_7$>KJ>M\ -M7KL@WD(^0^@AIV<4R\:$'C?;C\%C-S@I9"1MOX[A'B>^13;?+^IU\8(@$)60 -M,B+8J-HVE&WCI_LD`%0Z*278DB>3?GED.K!&1-#_W?Z>=/_(WN5D`1Y#7)*Y -M'F*_[2.E6P -MQ\=E5.LB^#]Y!$^+<1#I=6DAP*W[3:@63`[;;7D)(YR!W9H-#6JW8#[SD%"\ -MS&\_H&;66GH7YRW_`#XTIOZ@/M\%VT#TX<\X<$*&:IP,-Y=JLA5.SE>Y-3]4 -M\IP!]@DQ*MZ.3IHE^>(M$,#(]>UL4^1Z/Y@D4:I(IC["VLS-+*TI13)>O3/H -MUDF&[EZ:.Q,Z-U'%3\Y0V4!<(U%L:T1V2#A'?>""X0]*UN`9@Z%N"_"%R3=D -M@R=7QTUI17+A)@G^M^YFPNYO--<>HEUK@OWF># -MYO7BA;?R+$P64\.7T`L-4K\##N_JR@%PJPO=#%3TLO=Z?*)0WT3^VG+I#*%6 -MT3INR'),#!Y(HO!'8L(=VI!_O%4!U2%#NSFM.F0*4+&IH2$-9]/4"?NZ9C0' -M^<3,ZUH`K.K5_W4=7)3$B\:RX"XBA^6$=`G6=?O!4D?'H[B0W0T'=L4=.VP4 -M1:@:?-:9HWYX[6:0'7E!HQA%,>HML&1Z#??C_Y4?JKL1111A1RB#'#+4:N8D -MP,R=)K9O!F3D]R"..BY:9Y(R6'#,*H(ME-NE.U;CR;P;=>]#+2)4]?24+JZ1 -M8*$RWFY&&I[;%$H8AGUCB6$U6K-LD*X[`*^+Y#]K,_M6M<6;:KW1,C@QD6H# -M.'RKW\[1VVE?1U8FE@?#*H^EJ+$!GL19%[R5+]X-X?S)BZH1C2KDYDR]SMF9 -M&==O=OCIL29Y4FBY/?;YA(%N("CEQ#,[Z$-$EI@&+Y>)]IEQ"Y*=%WE,#*^X -M58@D(AH7_N17S<9KA]O>+5+3Q;WYOF\1.QG8JT=:.O-$JS5??:E9P(TC.=6H -MGB&RAOTM?J)J$6,\Q%.SS(N6A,2Q?=`5L8K.C"IM?'05*'=AZ;#&N<8'#'6I -MNF*QF5P'O*LA"#Y"E!*!F9BL:Q>N,U74J4O*KKF./4$0-)[,QEQ41,#D+V*_ -M?#O[[(A>%$E"V#[>_SXB?:A -MOA")4!E')!<.F3GP$O%0!EU[X2?I(PW[?7P^U[ -MRFNY(5K2ZS]HZ>\K[K'K##ZE@24@6\C(TGBBJ8C)*V%'Z9S:#[QWPL"!Q`+]/*2^;FRQ(M*8:&`H^),5)2'D:7P0LC5;I01,!6\VE/6';/P"([WL.%5MU3GAP\DY\;XR>14T'S'9,E-2HIG8ZEVA+ -M"C'@=]DE_O9GN#76P174\Q`DA+>_6=?B>%KZ_0T^OBZ`4&_O+?]TVF?1=QNE -ML2#FE=#*B)3DT?[WS\T/K1_*&V1EN9Z15'N%4Q$Y=V#E?37^:(-87_TD[Y,, -M@>!X_P>IU'YGQ@NQ*FU$T5E5)7YV^X!JN0H7\<\Q*K(RCS_Z71,35URPW\/"<>\P5]5(^^>Q -M2.]E0%7R/MO#;%B(7^>W+"#*MM$]V2+#"+YEVH<)?]QF:49(WC.]:*$=GYW` -M%=BT@LEOM:9*%O'1;O"E2:#*2W2/"W"[XTF!3!,84;[7P;:ROW33KBDPK6QI -M3E(S3`RIGS=/^&!#A.N*4ARZT6A7[>QNW,`"\6(E'3?WT.B67S9I?RGT.7`OVD;ND;_V$,',7=.28>XS1&/EB:`]G1?RI##0G='W*_N/ -M::FD#+;O_G7J/&Q?RLT0\4:O_L?H6W8ML*$F%A3,[&[.20)Y -M>^#*_?8)3)#'E>Q?^8CCKH.Y..8!BFO';U;A2<-"%!_$;T$%6"@;*`[Q;7B= -M0P;#%22!RR5R%DC0?]>7$%J8<9N"J9ELTK_G"M%IVJ!'L`5T!TKF!N0J!!O` -MP=VZ#\:^<8(1V$YP$)U=R@_!HLN[:`OMPOR;AG,P96];OYAPB!8K1+XE: -M->32X%B3JJHLYC"?C[(AX9^T+I&2A+\N*S'!"_OM&:-'H0D_W"U[@_F8JPFN -M;),UE'W]'\<_?FUF2[%5GNWL%65;W78DFU^J_JTZ+IJNF4-KCOSO.M-PF$2( -M_W*+DP5%9NJ$:^"_S$Y5W;-=L\#K.);<.%T)9UP95C]IN=`!50GHV.GGLQ>X7Y\99W`Q_/T8;" -M`%V74,(8OO]'8/7^*GAE\5,S(N;U+:V2W#"?5-J?>*>>6_@8O[:8YP=^IAW$ -MC91YTE3'J<+Y#0>C"ZQ_F'Y3PL6-X7'\BRB4R$5G@AKXF0&H'<0C?JK1@]7= -MQ>M`ZIY5GJ;E#LONIM%63_H2Q3\HX!WLX%:?49,:.8[&$2>-+Y54%HZ#_WI^ -M1R;0<5"F*$POTVO^*=N3@\G@`]\"'!]CG6+C,CMM-Z_.S_*R0O7:E9?9D9:$ -M"1@L82&38/$)>).\F83T2K^-X7U7RFS^U;N8"T#L'083]59,53K2:ESCE6=W -M`,7I8?)]]%`EI4ZG,(UGU?S[[Y%NB$;G+FM%'Q=`(ZW1_P5WU2(2/+XW\R]S -MI-@<9_9NPS@_`J97RD=>`*.\/=JU\/6:%J`ARN;WD/[7N2!]P: -M'`1X)+OV+"\Y=0_E?3Z-@_@J4W#Y3/(R]"MGS#BT2[ZL5`25ZFT*B(K%#4$1 -MGF_>`H8Y;1NYQJRA&6_'!^`A.B#_M0[^:_C[U -M$6"R7K`T;P2<8YY,=',49UD$9G`XC40X_/BT!TJ8?$,WKW@>L6@,0Q^>P!J -MA^5P/U*B$)/$>X4;\I\$#8WM<:2#:X4F&ZCUP-Z(WIR`BVHC9/[V$6VCJ&7K -M]#.%OLV)L=6@LC=(#(5W7(B2]+/)$O:FYZTR)ZVX37]^1-8F\=7`2"X_/3U3 -MM;M&](=Q#.71D,&^AEUM4LFE`>RGG#)6QBD."3J].J<&79J.UOR^(@C`5Z#% -M_&!`Q-F[BT.\/'`,VN!3ZKA)1`XJG#71O/)+MQ+\"` -M,QG>LN)PDF27RE*7ZHNS8RN10I(2F`FLLL4NZV!84XQ_>_Q&P^0/8X09%O8< -M5DAVP<(2X$\QA:J[_:\,_EPH)PF!?L?'+9J%?\*NK";RKD)JK%26,U79=1=$ -M8[ZT6"N80Y-U8=Z>8BZ7X00Z!`ZQ=`M(7#!TS_!/@B8@R6;U-;0Z;=5:L\"> -M:&8E.WXLI@;[[JZ'OHG'J0(OWC/^*7&OOU=#9;67M2"L.!P!C6=4%?72Z7YJ:1UVS,CFR9:E\.G<6_--NZ>#H*18AJ":JU4AA -M.^]%0IC&[MVK.(LI6HA3J-]I9$B)*@IG?7K`KDH:I01V,0300V* -MKA@DR%!GQ5O^UYIT`UU4%',]R#1;#G[\1F2TLAVA"_PG1QW/5V1J("37SGB+ -MI-[\%"]/<_5>%D1C&6:]%(Y`]H)GW?0^4)(3O_Z2[R.S31&%KHB6Q#%3WB4A+^^5\(&U?]1 -MIX@S2_JS9FT"D&HJ+"SX>+T.3)*7(YSJ(%3)DW@73S\6:9RFVJ=NE&LD@=,) -MAVNZ1Q2]P7>?WX4J8`6L5S&:.@.IJ";EV)'3(/7G[A9*L7YG>C6O:=.$/'Y1 -M>57;-E4F,+LE/`/+#U'EHUBKH&==589(-C9-`'*%8CFL\[_!'&'?]B/1#"3NR`G5D6W\0D)&]X<>PM`::[[3[0>@+S9 -M*BKIW>"W=)]"X)XXX&-0'M"[>QIPRC=0]E&]3_,\+)U1# -MA"Q[YKHHE7[1R`ECZ[])PEM[S_=!EJ[W$<)1'#(J!CP7N>/I&W[!]Q5VG,!8U1Q6+_,\:/.Z.*A+AW3!P\!G -M?0-L0VYC!R-[%H#P\3\.]"C7X)]7J*`=5\H-NR-4V\,LF>(ONY/C+#02C-X% -M$;E@1G8.'F]2T:F'G2-Y)T.7CLR)R\?/(F;R]8-!?'XZ(MI)I7J7I,V)KQ7H -M!,"+>@5"&60SY`37\NL=K]*=T$.8WXGS6NW%X\3OW6O]`/=II[B.D"AQN0\^ -M?3>3]QB7?B;FGNMI>IT(MF/CMMMQ5D`$M<@4QR(KH5[GUHS8+#1&5;:R2T]? -MYJ[YO'2:'03;'`U`=/&%^0Q;'W -MGJPG,EI,%1K"6\Z-83$88EQ%X#P9)2/7(NR/^W=#-8ZXIBR#] -M$U_\?KK)@_?:C4YXP#L"R5Z,!'':FSJ^XSMAHR%!H0B]KMI[$X*H^WBSR&PL -MLL"^O@KR>)F/OO36)4RR9*!N618F`VF%"$BJM^N&D8]+FVH?!O(30'_)P*EQ -M4NEOLI"[-:X'S%,@';!<00Z*B<6C -MF6 -M-XWON-8=9DB>!VO10@8:5`]$3Y7%-3-'GZN/GT6&X<58::H;U+"6T!F)4H+] -MAI'=@44Z*)(',V$H8+*EC%$\#IK^$FMUPZ)A/VD3H2()@3T6FZ'N//"BT('S -MOO)/RC%R;V;0M+06':=N#2T\%'L,?Q\"-O[?`DRL#-B!X%*4P:6/_>;V#/^R -MDD^@OU__K?+^OA1!VRG:/NC_:+\72ID;G=,$Y,TO=@U4OVC&;J/SH[6\SXT> -MEJXND0.#F/)[+9AZGQO\6`B.2`3]#AS5N-.NAY].2IEV;*9ER]BMCJ5/ -M:'0MV3ZP:C9I)K.I%#'O^PW3<69E/=^VKV1Y1DZWRV'_B_'I]U6/#,B+ -M+MID#LZ(C_%KD'=H^=]#O"*#>LD!=C0K@PUQ5)R6V$V\:_ST>NH^?RBKK83W -M>2(>:BS))?!<92_0$(^R&^%O'![RVM$(P&QA;H;J(B"V6%1.6>="L6;3YLB\4X%!C7(^.NGQ/B*N_,H=T[,1$*Z2LA! -M!.E%>"U'G74P11W=/?C*BDO'U<;5CH`TE8S[R,OLF@:>YB.Y7NI(2HZ@D)&Z -MEAL%Q#P_Q&A6=B=8I_+HAC>*'AM#R[8UMT4:&ULS!H]KF,(:5DW0]08_=13$ -M&&9)(,1+6R$=_J*%RV2X#]:B703)NJO`[7A7%.,(YHFE&6I=5M%0)'A*YSSF"[XEPHJ&5%V0D67H&;C#]M9 -MJJ,(S!UC34/U"A7XC3LWM14Y4F69SF$!304(!I2AFQQ@FU_J,K&:/RFM(+G;UH[ -M+XZ9VU.N>2@CN''JC<'\U@*_X7%F`%\M[B"GZ5JVJ;X$YPM!&`ROS47=CPXS -M$CP.T\C)/XFX\'J?^:PG.2E_C_6\K03I-Z$(5D=IB?EQFA@Q6H&TD<'I81!7 -M]\8K#TY_[WIC`@S33T=:ZYEHFAL9$:+-6UG'QSET$$_N(B- -M0!=EJ$(@&FE+"^LT?Z^9J'5TD]B#3'$\$(]93_:?C,0NGF9$UU5?CH>]E%Y0 -M)R^X+'9X94MJ'Y(:=/J<\?JPYER%_XGFTYD3PF2'W'E&UOH'E.P0XV]@\P,? -MK^I8):.DZ.%[RC!2M*9!@8'N"ESW)/$3XUCU4:!8OU=XA:PM:LYE.<[U -MZL8YFX!6S"DXSFM[4]9K7@7[GSFJBCR#TR;>MA+57A$Z^(_YX9_BR]_R6WAC#JT_F.*4:'O>-&F1PK('^?K^1XG&%' -M^'X<4^Q.W@@#/":0$R$+PB!Z#"5!D>WK=MDD09._P.INIV_PBJ`<#AB&A3)*,&,1V!>3:5,US:2P+ -MGAP7R3C`0;-NUQ>K#M2!`U:$Y?1)7R7]9$=[U3<0%Y+OE%$Q@!&FU6H#)OT1 -M#:@._W;2(!#AM)\01NQ"?\\N;2N1JML7#;LU*RQ:@N+@_L7FC!G;'S[=/W\, -MM5K5O(XRF^\)'0I!0I%8Q[AQNM"JX%'Q]UH/(OQO*I'_A2=!"H&AD14GNW%6 -MB+QV8`3+BX)*"`0QZ\3^$9RL]-%T:I3`ZM^.>Y:SO%[L#7QTQB*Y2GK'CYX0 -M_+Q4GC39^=>_E]#&F12'2MDC`(V5A_"A!F':S[)QG$*E[\OM&-;E,RZX.3)HWM^7K1`K`/HK4UENX(\ -M\VU>$?$HA==N_&1L_+S!1+:4:_(VDC+,BK+6QF>Q(+:J^4!7WXVS&L9[.(UK -M/P52#D9+^F"6V:O#8-=0-,/X;R:/L3>BRT>Y#':\,!)VPMB#\]1!171'1J(RGO> -MPC'W3RG"E:+I&*&"L:2^"TO$4*XKO1;&#=1*R7%^H7NEE?9@E;;!A.3=>(J= -M<=I%10[JC66R:=5;AG-D4;D2CGJO5]59_+I2V!)7Y.0-^]8.:*X:5/G41,K. -MWVC4H@]6U(&(497XJ5DXVD[K?'%5*$:=`O#>9PTCT')\ -MVPSNGG"GU9_H,+#E82:F(Y^*6?]_!G@P.W#!=II:/TXJ -MC;`9\SK#U:!3R[*@'W^/%6AH)PA+&7B,4OD$K"1SMCS)3F`7D.B1F+`F9C;A -M6?'6Q-%B\4%L,:7XE15PT,AH%7+7#I=.18P:PV+I;:JVA@^H:?@VN$XY-SG1 -M1+66](V#;T=(VW@<(6=F:!RRD`1+DTCM#&ZQ7#N+[IRJ!(ZYR8O4B3NP/$9+`'/\Z/N14!^)FM_"@NEW#(.F>G2:9 -MR=/#C`R7JM-LM$?:9=&&.1T$.DB_-4%E8M$#+B=["\RNQ-$[7%WEW)@/Q9^: -M!C"BM&K,+5/*!UTOOWK`K$_S*T=89PXFVGOL+#3S@:BF%+!:WDG>R1@&YT0[7XH5#H#.A.T?DM;Q9 -M*ET<<8"W0\O*VE_(3]8&]!=/$E9:'F`< -M%YL)M?Y;YF;N^6,V\AX:.,U;W[T\/2++"GG,>YB0#D#L7GOLP(8MXILNDH+G -MXN_,#_/W:8KU[.P+@ZT<,K%O\C62&%([5"J`X9B"ZS[$N>IQE)BX=<%&UC\3 -M`'(14I#ZW6;X$8Z#8QO]GZPZW2FK)9Y0:>IA1=FAFIF7'<%>)R:8A>\0]022 -M_.\E?Z9]Z/V$B)-4]YY[5,"3IQDIJ5@*JPGZ!6FJ;8CI:LDT$7J@EI*GW\:M -M[9VDI9-&_G@AYJ#_JW=Y8!FIV,,T>)0>Z?%QQ./$3S71)9=`/.&HZ -M8?<#T55O-$>`:X369_=?C/-&2[:<>H!VP[6E^>U?$'55"'J37"&*ZLW=V4'_4H/)TE-K -M(KE/CR1Q&?E_6T6MN0C'"7<^H[":2IG[5M6QN^8=:D;6&JO[\^^S*+GJ=3H: -MMC>-4NPL-J0")E*X@PG0#6#U34ZAG27F>L&].,FWQSCO`[Y3,(30&#-!H9^^Y -MX;C>FYZJ:J@V>E8F[LN@*7/DL^9AA#TB]W6X"&58I(%U#]CI6]>9X$=0\?8% -M27*[!O<`'6C>3J=F]J<+#=V<>G(^VO397Z6AUW+AJ,NCLM*@0%^Y`QV^32_) -MKLE#M'4O/!A&K,`DS0UI*$=U)YH#P%NS:4CTEI?IX2!/N^:WJDE7)I$'O41` -M[:\AY,652%@O=7O#*JW3S&@3JG_,W:1YT2P2`"SWRJ:*28KUN$G$9+:\17,5T2Y\P -MB/"7^"%]_SM;Q>B?.N!$=AU5$8V&=2&UZ+\A[O88^]P(>&S.D -MX.,@SU2`FQ[E.DO5=?$C?_^9>>I\_(.QKB;T#?L??TF.HJ1@^0;?6%M"^_I` -ME*+LNDJ*_B)CVX"3>;=CLN>JF)>5\9'TXNSX*@SX"8\$0JI&(.VXHHIF!OWL -M7L!V[8L3Q9X?/#C+KZC#.HWXQ-/H%U;XM4&[`80Z.R2O:HX/]YWZX:B;!*31 -M]@U*HL/#+0QL)-ILY>,JUP"O%J:(XCK=<'MF9-V=F>4,#_3@U24.X;5BND3' -MNF5K2#$;0=EED76[FI9IUF?_MN2AVSI-M%V-&(&J,L/DC8BT>.OVB^(-&X0S -ML.KPB^D0*V13=E_S8(&!<$`.9-E!??E8_SOU#&5*_WH1!6+MV[VYR6G\B47I -M^==LT6#>E.(MM]Q:\C+JB(HH*_/.D!B)[$`7SO_AU;K5CO46DSIO"&`3_!8/ -MHD0$T2K%Z+#`GR8`A_AXQ@P%S.YB`I)@6L)LSM;S39O(B7X1@3&]VU,3G=49 -M:N[L%VW+=%TF5S61!`7.K;E#23(H04?0V:T!(_;-)A+X%I=ZS!#_L/$U?M$< -MYC"B()W'S]$13-_O744C-]2PQEPJ8']T(X"Z9GDAK"`T+N&IHD%"H&+G+D!: -MIJF4J=J&&68`[WGI3N$1^8Z37*3LIFTW80^"]WIIA,XNXWJPQ?U(LXUB.1V9 -M:`VU$06YZ6@"FA!#.=PI14O;7[7.CP=E27R?.I4G#-W*X_"A1SQAGWW7YV*">Y<[=94&::,7$LSKD"^SD8-S.L!A^;<3M&JMUJA[ -M2T#P/I),6T"@&X_O%MR_X4B/!F],J/.;VE;S?9F/^/3H-Y+W1K]AH\0XJ"5F -M?CDZ]GY,MZ=JL(QC9S%UL('S$&D53ABA4C2XL%6Q5D:N>I/+Y-IC+9<\I`>\F2JH4\3M3B*)S7R$M'W2UN# -MAI([#?ST2CD(#@R#XIB5BPMO>>:5`EQI!D4:JPU";T9D>-SH^3)8LOA+_S'F -M0OV67+5U#UFQ\EL(ZQQ.HQUD=&ZD.31D'I4(;9TZ@^!3)QU=506O\7UPNX'; -M1K7T0=I\ROF/TA,._B?AO69E;8;E.V"#8T#0U_[7WZ!$ZEL>IF_U&Z"('%ZF -M@)@-&%JERTZ1Q6:@O93;RD:YBW4U@*6+0Q8/!T1V1+3)8)&?E6+"=Q5$J?`R -M\W61N,8K$WA4MR&01UV!:X`AJ`U)7S0*=-ZYNT4[6FRLM&+!FY5[L\EL;[@H -M1VD]%?\C3Y-9_&WP>C16@C;.#?SK39.AW=M@1XAIISB785*@??+GK`Q -MRF>@IR__`07+D#>#VK28:"T+L'+>7-0WSGC&51_00NMBHN.V^B7:K_&6;@5C -MX(D-,CB9M1!WN5/Y^B$A01PV5`S&?U/]6:/O``44L_9E/_RP%5ACHM;2AKYN -MLB?'IKUSU9G\FE..E!5U$<%1V>B(^281]E$4S^^R]JDV<3B@O(AO*3_H#(BQ -M78C=-=\(+)AZT49'].[JH`^"MW^D6N3?SB7EG'-P]A(U;E,,.-G83%[95[7Q -M'9@B'<8.4JC"NM2$:2OCPYH906"LCS?=MDO1_W/^-?HS9;83%%]@5&(WJ62( -MH);=.OD"%%RIUWQU'(4YSXQ-9&*L0"$R,DYH>04FO,?D166*0(7\F. -MVAP).Z>^`!J5KI#,UHZT.8U.L&&P,XC(@FSEXA9N'#W)N7^<.[.F\Q]\]-3M -M$!'!CN<<_*);/HEZIFB!+)^!RFF]MP$HIFS(C8<863Q#XK@PTLCV^:^PAV.^ -MD_B8MJ<'H)T_/W(&/% -MG1$S=6S&S*]>XC7TA4OVZT!:?VA>@_[T)5__F\4CR?6B;WI^AFNE.5=R,:#M -M(FO@_G(1D>HO2.04BUEE'YBJ;>/UDXP%LX!F)_EC63=D<%0%-AVZM$!(46>D -MRVU#NN'+P\U%CFI/?_#2V`!HFT)V,? -MCF>3$,6$1:EPFD*RE-8,HI8?5_<)I/'-6&EL" -M/AM[*.'H?69)?\+8<8ZB*/C+K_[MVN'KJ"0BU$[N>A6C%A'YU,%CJU3?4-IC -MF%EX7"DK`V>"=-O#S=Z%JAC@&4):R=%7MLZ(<,#BE7Q]P-,)W&VS%.2.Q0_& -M#.L).VGPZOR.UR@_EK^O0]>F+%#KCY?15K,AH*B]L'S6W:#P0"!1CU::/]$E -ME@2(PI@L3?KIQ8T1HCOK'I6G]TV@V[X$NJQ.9KL@D#ZI=$0\K6]P5FE7>JR' -M\_2WIIZ7B-N(X>UN+"(ZA=>`HDA='XZV.+&\!6BPR'!%42)%!)W^12=OY9_. -M',"TGN$"[FDH(FGPH>,J;W0[%$7*]PT=O0R?J"L,+/S18M6<#;6I#!R$H/H. -M1P70C-KB(BH5L<$E/Z2"M.^.3-+\,DE:WJ!*E$QY=6#??I\2B8P:N)3<%%X?]N$Y$R\R*'-"#KH#:&>30D1IFP\>7FQ-'4M(&: -M?9]-\)T"PQ]]_@"CZF/.PC=0C0CJRO[FF:<^R[^4^;WD1=$MF+6]#_%.<&>3 -MZ2EN9V3DY:7H>G*N1K>9]ODSP?@P]CDQ73Y].3D;*9\+RC_1N?[3J.)^H372 -MAZ$4I2&^X!:8Z>*$9D[3(=Q<\T -MKN?/^Y1[4/_!8]D_ZA^K9TR\D@M@TV?1J3T=L0"4Y1U`5\`A?$[R>6Y+ZLFB -MI"N3SZN,&DQ'M]5N^;1I_YYLMN$?E<4%=_0#8E`*S -M19J>,8^3T7G8U"*TGXJL02IN:AA<+!I#[UWGFHAE,/)>2B8U#5$'E(;IBT6K -M[HP14*V^^V4@47W@PF%R[BVQSO-$-,K*+G888T#!K9D=*>)$SB -M4GS&:;J;46[9A1OQ"_2YSB>>CYZG`VL@L5/G2Y*TSS1'RY]NQF[R8`#;YXIL -M^:N1[I0^F_H/[_7?V*5Y/DR:])'Q_$X!F2L!,ZMQI.8+ -M1'M?Z\M;/U9G;,=J%%F4FYEFA&X"`9[*R#,$UKOP' -M39*D>O`[JJ]:`@<)&U)=VDEB[J8E6Y8E.-W\*%!'MF_W=S)?A)RC69_+O,FA -MW`_TY+7/SDZXI*QX>M^#X$]V7]I;;1M@'\2A8DG$,]].RR1I\H=G)W')-6:4 -M2=]78U7-RNV/BA(/FR0G_2+M^HO#^`BJ3'T<;Q;DG/W2?&LU&+O?KB*7U1U: -M7'#N;4BCC>61;4&X\/><-M//UE/Z.^D.,A+9%_NP.>EY\]MS`4].R/ -MP(LJ@D@4C6U&?GB-H[H83%3_V@TTHC*/1GJ^6=\\EO,AE,#=S#NE7D*O_"E6>J'LCV5-0T;E30%?"(X1R3LLX -M1H8V(2X)L'Y74:E\<]%J6#@IM`VNPY*O$UH\XLMCVIO(QZZ0OU9?JM)Y?J-S -M>]!E`H_,K^#>(!A#JJU`,-YPAZ=6@4+)`TSYMX@+%\N=K._NVIXIE\Z>.C%H -M2ET=NB?Q<<@K`?U<)[;]]1AN5+L%%GL\G.'MF2OWQQ=LD^#(?LP1*1U^OH;TYB29X.NF:QY0:VT?>- -M_%HBNTF74N$)^"`(N7\])701K6Z.4H:ZT%.TGMH.@34BA2W8&YW\H>[HOYAU -M_?,K,!\%HF3>Y<9Y5;\@M%8J][?#S<)XB -M1C,WK]^'VB?]>3)OXO"&KUS<]ST?P -M@A6A^64K08-\$^M&UJPSS57J$?5-1*2_:VL%E3F\D"#`%K(.:=H)55U-#WBM -M/Q=1[%+B=A_?T+<^0W/IWUR9O>HM7_]HCZG._@^=5U!*7'9B:KXS^=)8E=$X`JQD#%3S(6ZOR^&.9XMWF -MB`^DVE3I:RU2!BOVDQPJ!CB]6G1WD\W3S2XS2TWJ6P;&$U8'#TC6$GWIW&!C -MLL'W;F0"[JC4:L(>^X5GQY-^,)J1$PBM`I+ZK;'B)FH8H702+%3?>N:=B(45 -MDHRG1*6A/1!S3D19U:S\_<+_!0BT&4#$^WP8#%FT(!\DZP5)VKYE]M&=\1X7 -MK\X1MM2!%#":Z>!O1&$])^YEDK9QA9XF_=JRPE`9NU]EBV,CVX,I#5! -M%>'NEP0E:'KJP/&<<$GM7=K%6IDW%3S$'4<[3'#0L]WF_%AA -MSW&A<*'X&\B;-0.$LAPS8IM(QWFNJ?ANG)8A=Z6L'LJAH?93A,XD[O-(!9<% -MV<^JL1#$T1*W/]%ZU&TZUPQ?OIT`@<0S6+IO!IR$ATQOGHJZ$!4J),/XB#U'8M*^U8^<1(`>O"#I*Z_[/ -M>)?\53X[!,W%)*U?W;-0I6LU,4R1SN8'".U5-5)A/^GL0E,:V+'F4Z$>Q9$K -M`LY-!!B5M71K0LX"6R+L*(A'2PN#V]>$M`%(!P91E(_N7`?FRNA)8&_UV\BC -M!_ZO1&;$S_G#AX_0G]5!MPY6=#!,&R#4]:R![C,Z1ZSQO$/!Q#&_Z/-]Q&PM -MB1+I04*'48&XH3K3Z34R"A\QHG;E+;*%"QL(3P3B&-OA;\DC1=PGPXY6'8'6 -M:\AF[27+0>F*UK-LHTAL@&\Q5\\B1.^FS(R3"Z_P7Z2_B$.46882>P%S>#S` -MZ`]>][5:<3@7Q+_[W)^+L]D,ZORW`U:KG!C;4;K\+HT$1X)5/\X[611M\A[349I4Z[EO*5*O6C@F@A[+)XZM3:;&[;N6!>_S8'E[M -M^\NY'(YGN#0@GG,F2U$3#.3O>A#AY9'?[AW4?A;0-5IH#ZKHM;\(E!SPI/ZT -ME=.[W%BD&@Q1BYDQ6//3XRK+8"!$G3J.4^'NJ.@>\5?U&(8#$UZQ -M?&WURL8F=R]B]][`O5I;GN)TWH/`X,Z&4I8_0:Z\"#UP_:3B3X$O/CUY_2XZ -MOH[Q7H[G-FX\M>F7&FHD0T_>%@+$Q'!#J(@\OJE&:H4?WFF_J_WQX$X?6RDB -M+G%H+:![)<$]CI_VUNZW6I..3FU.?LE*X<75+*N):XW>+( -M582_W6OPPGWHET)"Z&]^SD\,M@!8N65QI*.(,RYA8T?:7XBTBZMIB=D8QUVVB^8^EF][ -M0E=2F<3WIOTR7_:U[$3-RIQ\VRMW(.\T\9()$_QR`#CZ[\4$&GGGB6=W!HDJ -M@R&F7\G]U`HVP0&JJ=ROP"Z:EK!9>5RX[:N?G3S>.*2;!0!X^,:_?%[K0T8" -M^$&"89R4P2+!(MX$R9]!,\R6VT!Z*VB-MO9<==NVKP\EI`BG&0)H#X@8'`@7 -MA$W/N[/QO(^F\9?VX&TI=JR>5:D3[O0T%4W6.GH^Q(@C`+68C_IKXC*OQP;U -MU0GVHEK;IJ*U-41G5_R%[%D@DQES""_ERFRC%R?,ED5]9DV\!#WA==0(II!E -M+ZXD3LIQ:PH"+6NJ@2TI>6V$QT9()&%O\JVD/'E3NFR!IJR@&)C73+KXY]K" -MX/GK3SMX.N=ZBC/#)+#YP08>7CI.S_CDGN^KS3D7)HU@6Z<7/K&`_LKH(25; -MB(@MBZ\-_5&:3)QR/`@M6<%1],&"4"!XNFGVG;PLZ<6KO65,A3Z%<];#N?"U -MVU"*,"24[%F%URVPK68RSE\QGRX"D'OT -MI--ON>?WF[1X%?!^:3=<,_&44I%=K"4`@=H@I^NM@\-AT>?&KC6,>@V\_]AW -MSIQ.QPP[7FS*Z]9B8RE)R1G0M8_@PQ8$NDB$$WE;2"2@#$ZV\"NM'M7%HC,)+S!;G`MQ)V"VO -M!`%99#Z-A\%=,57]ID2A-O)0I+;VY>48094:\.2@>AE]*N2$J._ZZ9'KD\RU\D^F1(/ -M`I.?N*HIF+-)C5!KZ4X>HE+O<2@SHL`C9N2#"_PT;3'X=(72!8-2N:(3N>SR -M,4Q.M]ZS0U>R>.GCJY7B#W\W3!TKJG\-AY)V.;)_TX@Y&&<:*$6T;PRKIU58 -M.[L8W4+X4QS"P=7%8I/+.K:%3A^_9F4W#`?N9?1%J+!+GF.$YUA^9XB'0H](&Y7F,[34`U3OR_R/U;990& -M(6$K$<)X-I'T7IIL,D6%+0AY'T*NZX?;S)#8CN&!F.^O;:KEB>3RX(@JLY!,FH2)]."4H2ZDSG$N+&%M*YK,P^ZTM' -MJ/EA-K(Z_64HW*&&1>5I6.=R@%B!QG:[>`C/74@MO"C+R3_)@!B90N_BJLLBQ-X=$$Z>P#PZHLST1&.! -MGH\%L4D*<1&R/,:6J@Z>=.$JWF04X\WO48,9"@KE"B&!:L47:E% -MSBC)'(:R:I=&^XF\P1VSXSBX`N0A28$6G#9[NL:\'*6_ -MH'Z!MH<"+--/B:&/,RAVMEHSK+!'239>>@DF]SC+[\$A.?4#GD3VE\#_3X"" -M8TJ&XK:>U+H,Z%9^$5G4;=[8]^)-\4,[6O/Q/];EY248]_@^9G;93](Y(&W" -M&HB9Y)+!`2_CPX3_.X-1NET<35XQOH9'5GS-`D08T+6MTFX1ND+]L&]T! -MX&7UWNTM(C3]C/'"RIIDB&D)2%IMB_MS6Q6L:"`ZL([6SZ&34NH`M=!' -M:E/M"[%8KR4>Y)X8NWG;\N_1 -MAN=WG[2DC^X^5\AF-\.,SKE:_+^C'=*"K%=QP?G]4;[Y)`;-`U)\DJI#U':MR(3G=2T(_U_>2:P8VWL".H'?`;]G^)HQ"9 -M2&]-Q)_YU):C^>'EF!DP@1395\?TOZ#^D\C)V^5@:B]07"1M+Y$)I6.9Q%VV -M>,7HH=M$PUFMKTK$^]UFNU'7G#$\F8X][*X0Q,NI7SEG>E"EN='QGCW]QL^X -M<<[F1$$*'\O76M8((4N`LIU`[9?1UT,7R"A9X?A@Y:_?6G$@Y>YQ5+FDC;P;O(3IX7+QAEWD^G;5U\2J>7$=>7[` -MX)>=#Y+`#[%:;!1V8HI=Q`7I;VM966QXUTLFB9X$H>WXTFN<\WCJX[)B=.XN -M1,I)H%Z!I_U.2^!XM/%]\W^?,$"T>37Z'E[")YIH5,F2YH#5&G$\4\TN^@>: -MCJWSKC37'S6>NU$/RBAVX\3AX$-Z9=ZY+%AE#3A[)L:^]2WO.H%V-*K'I:^E;B/K')E -ML45P7,UWH#V6D<=?FML!KC%\)I.RYOLW9K6S=D5W1&ZUF=)GH4KJ/>J@2>,R -M0J]JJ!^V2W4DDPFD=J'=VO3G5F5P#2IK([IFCX6:M=S1*,V;JXY@T7>JL\1= -M7*6AYG8I$^4`\'W8GY>EF:RS5'S_6#75W#`(C#%`^*\Q5BLP`;6#V%E/4]U[ -M2J^S[KGI1&TB);^QQ=\7?_G!#Y)MV"*>_S.:(+;ML.P#G,+47+%+JQ"O%CGJ -MX0KL6/H+,+8@K3$NYS5/'<'_7$9%/Y_W3W>F'P6Z`#8F4OL<]JWAG!$F&X4* -MWZ#V`BL%")4W&?8*D-R_YD57(^V/CU:Z7.'0V,_=KIX8Z)_[ -M;N3KNV9ZCX$3(A["^01>E0=0)3$_>'IAQ(:FT*?CN)JR8_N+KG.]J_WY$YK4 -M=EX:6__)8?_&K,8\:JKTQDWY*QC"Y(DX*=934@.Z1=1:2XM_RNLOZ9?IR\\1 -MSD(%7.8'G'G#ERE0XNAY+![E#S:ZPO4B5YUDZU\TIPTSP=Q"20X]T7?=$OJ^ -MDLV0-LC'RP3!SK\__.$`PXCV?#4F]48IY$4>X5%HIFXJ-I8[M0G)^2JX:YA* -MN@[0S!6,IFMS@:D=L7*AX%S1INU7S'HTDS]0:\:%J=38%H52=%M_D2QAWI[& -M&@SKIL3[-<[43<7LCM7#KF_R?2&5'/$Y=&_;.CQ"RJQ.V,KX&4Q\@LV?2;"Z -M/I]46C6S;WJ+`6BV3<:QCI)7!W]385#\$&52JYP\&.>2HW.`+*H67[WNQ"C"@$_@>FB(@(Y/T3QG.]@.@ -M<614!MV.&"M1>W#>I$D'T""BJ(9MM9BY!XX"`KUDDA_"52:Z&_\'^WE_9O%B -M!UH:9\,;HV-0QR19ITFKZ?C&$W'3;R]D;O%N3Q*P75C0CI.5$Y?%&X*(17SA -MPBZ_ON'E%I_)-D$#*AD/3?D-)*`NV',6KGJ&V7.<70)JTV#25A(^H5ZO>*+3 -M3*:&C>_4(NA)'Y9*GL5O8#UWI9Z7?L7Y8]:.$=^ZB98F!0E\]R?W4T.CF/:Y -MT3WE*OC2Y#]A7,:4"_U^9!S>04"-""MXL_O\[-O9KL3_3/E[WI,A_SOU!.9) -M_<[$IO@96DDPX1]'B$RD5%/3K9&$!%B(WL7$`SG55S'TT863JW6]U;*@ONQJ -M>.A.@Z%;-@X)'LW(6XHH[Z9N*::O<3GNV#RZ$ZF(F5Y?]N3BMS4@_&]D[F^7 -M"_ZG^,C*YA0V:`^G%NHK0)4C\ES$S?^D<;!>I/!N%XX,U8XO0#:%I6"EV*GU -M=P6%7^03/7#,?ZY&XL&1#B)@/?L6+!%CTN9YTGT[@[`7BPZ[98#JMZ?C$'(B -M^V(OKO%+HK@`$7:NAPB>^=7A=H=D^^OKSNRM6H_+RG-"2-DDU#4UY!ISFV>- -M'9'UXO\@K=H0;9R$M2(J5HG#62W*GQIF:@[326?!X\AXR')U?:(;=A'&7QPK -MZ.9.3%VU21.M\.W`>Y,3Y`C&OX8[")@L4^BK?N#!"4:DSV;KGQ1XNF"BHIM% -MHJIY&#_QGO*..6A)]=-*X['QM%H$766^M%S+2ZD$^C-@4H,16/N9XY-E<]J. -M@41%=36:A<(F8Z`KC)L#@AZC^I8L8W<-@5BGD/>&GLX5N`@6&PBQ6HQD><:& -MQH(MWEG-_G4NI^;5U=(KGWY(QW%><#%@J+!YS=F*!%_[SFY)#)I$90YV9(`Y -M%R4BZU=2JP>JW;`L@3*R]N'2K-/L2#-F!:2&(0-%1:_<"5G(59"!=<>#?64+9`/Y9!35+`)!ZR:Q[/?; -M)3.MT[Z[B#$DTHE%:X@@D81%(C`!HLY)&ZA`TA854$7;O_T,80=K8/D&;Y`< -M1FZX>;36_*-B%)I, -MGD-X3L0#_LBJZ#P(F02NBHC>?!B.[*FT:-$)AJ74057X/I2#X:6#NF][CJEX -MRD7H&.5CF>U#8_NO:]8+I)LO,VRJ"RFDDT+;TQG5B>>6=HI"9$FO0U;%..II -MB[&O8&Z+:P$+A[\P$M"UJ137>[)D/W(W&'+"VC>BG&B^QT(6-N?4@F3()Z!Z -M:DL_W(#@.M8\5**,YMA[PCE3//FLB/;K<3:3ONK2.UJNOK0GPJ2)*P*$)/*@ -MXRM!N>%BIH@+

    0H"M=U.^6@D^363V*G:WO@=(U[$/]YO^(GWU!$/^]1T07 -M1HHK6?EII(HG-\LI%K%0D"-A??/CIOU@F$10@DX_NH[$DK1!L".H$.I+9M:, -M$Z7>:\&BV!\GM#$%>M=)Z*!LY)5254/[N!`9WZ\O2H@X=.+FN7\GAX7^)&9? -M(4.:VEWKE7QG^8(E2K8Y.`[P!EC\`1AS-[I[+_\4Q))$3]G:A]K=7S^`Y0F4 -M]J:"A9>W_ICY/*>CR^?_&=?0HMR1'K=I\;W^S21RQ]:*BJ61+`ZWGB81563G -MMLQON(^[(-%YU-9F1TYF.AO%.0*'9$?J;/=-2R***=3U\KGEKS_"C?F)F5*V -M_/R/U&^2"@+D*+ND2U5$`0V)FM>).TV-J>+U#L688$87'J:)0>W,YD6Y1E -M0\)YX(D"6*17(*?S,AT:1Y$'MLF;HR],"J8G$69UKPW\NHEO,'=43D5P4P@S -MI#D;0SD$*HVAC&XK5ZRL@OV"A%+]`-Y'1R:1F7=>ADF0BX!G&W^HF<_X:)(# -M^M9TZX)[<4&%Z'[P!^20Q&G-"8+CUN1:1U!/JM6,X8)('OWQI16LW,(V_9!- -MJ=VL49=%<)Q+-9O^6SDJN/YZO>GBW?P$YI4KK[I.",L)U?-3*`M0OI$)@$Z' -M/HHUIF@'NC,QI9-[CLJF&(D5"/NBOA2V)>F@S/H9>80=;XD!JZ!#V3:X$9QZ -M!/7'C"G=$3M!YPE^Q,(;K+SPQ2I4N9R8O<+T`>#Y/O/CD1K.X-/M:79D'\/W -M:2]0:9-"J`,"",D1?ZR''2&6ZSSJ+62 -MJ7(LP3%4W/D476&\WT03K4+Z86S[DQ3LB7>(G7$40B27<(9'J86:+CZ"\)=4 -MJ97N<$L@5/^-(38,?K2N-?'CT`8S[@(&0*,E"(&LK+Y*=+_6XG"_.NKS$<;F -MQ@LY20CO*?6NZ?Y&X3QV>MOP5U:K]M;4<=F9^7Y@@VD)*].Y>10-`\M&]Y(* -M)U%L/@G&&5-=:44'Q%QX0!OU;Y<84/W'H)QY&`8HG("QA,!I>OQ$GULWS!'+ -M8CY>0X]I[Y]2T"8;Z>8SH7C2;:;GFQTU4H`62$[E2EH,?-1M]@:`49A9.(^\ -M5SJ(R$:YE$\^IX,9\)-V0+V@AZ^M5,.F!*G -MOQZ*-K(IYC_3 -M]Y"=O=ZH`U@)KG('B6;[-=4N!!YOT5ZY;M^9TTM9EE#A3#[^O2EAD3<'RA>7 -MWEGK`"MTZP;*;946GEZ175354E+"!@=*8-0(+A]T7&VJ/HQE!I?/-126G:;Q -M*P#"3I]=HC:N*1K5;82("6/U=0@./ -M')N25Y73:EZ78IL(1G4)04>=%C*0S4HSWTEU=G# -M240D[V[*/YQE?XGD/9Z0GFO5!F-\AP9;T5B,T]$&@M^38%`K'NL-D[W6-1P1 -MA&[Z1"!M:>ZC/$LDLNP](N'8H[O(6=:&G(;E#.*>]IG(E(`)*&V,?Q**4"^( -MI2(Z7.":[G,)TPF:%@_55,>9Z[9-CJT7^ULEMH&\5+H)K1Z#P=H56M*51O]P -MV1];*<;F)Z<8N.YN!!C`9`(T\C/4_BK?)^3<0:BPH2S*EA0%I.9 -MMEKZ2_KZ;TX;':`R),G'M')$0A4N,7?7HF7>;2%-G]+=I"4-:=9OW$M%,RO* -M1X::G1<6$WQY[!#2V^3K;4^A.9BHJZDFF?@$U#+;*$'V;!=0^RSGFR3:0&6@9XC[3T<]&%EOQGQ]JX?@X -ML?L@]<::P./K$$6=]+'CBYE!;CY$^R_G_5`G[JZDO,!.P9S!*E9G:[7PPT`5 -MB3.FC$@?/Y-60CN@D@(G!(FVC@_H>75I2GDWA'I:P@1<]?7TD;:O]4+Z.^^@ -M8%%`:+#FET$27HGL(@LY@"4: -MOZ0XG/-:/GRFU$X==4%)\?>1-,X.A284H1ME[N;(W[CH-Z9,SX!K@9^..#2R -M(E)=X6!R+HK%_`'E'79Q6]W1PW:NQ<(UL=QU2T\$X<2V6>05^P>`4RY8H"9LCRL.3]#1+ -M7YXHZD)W+X?D^M\F$NAO$JHH,S%964EG6\HSZI$5MZ>OID:ZL&*RPQ03\529 -MR-9_;:LR,N-XIRA>XZHM]MI-UTDV3DI1/ROEY-8L2UL#MI-^]'W&A^[VHQ,Q -MK:2"C)4_44/#%BYQE#OY?]_@FWY:WSYA-&_G8")M+SZMK8NLB#MW/GIQ<^$" -M3]C6T_8`ORB`7I/H":\ULO=D:$8U(I+R/G13\S2%7"+Y=]JYF5*>G,8[ -MT+RAE#:!]W=4WP36B&P[68SD9I;$^T!O?;2=Q,.T4M#P/X'_,3B">D^CBM;@ -M:&Q-TA'W(C[@A`78CG8C]`J=5M(&3`P/;@YBQJV>"B26$)K(;[MI6^47T[7[ -MH3AI4S?=W'+O4?,,0NH^(J>JFH?M*G[J?'R+]DI^OI[_X"#1$[HB>:@'I\,% -MP_5+9,BZG6U\.AW:APF]W&N)*Y>:XT[!3!G>7\!%QFN-GK#IX<(B3G0_) -MNUKD#.="L4\1W"G.?"AX)T&=6CFNFO*JGV/OI6Z(88)5W38\3:--IA8D -MG5PP@RB^KXF69`:)_Z7&0XL_?K6MOPB^[I++JNJ>[ZS$#\9#D3[57AF]#S73 -MFS8J]<^9>')GUZ!].*@?)-7S?/Q)N>7\[&_1YFC=5OF*R:^@6\:W7.3UE[ML -M^R0?5>A#H(%-)//EK1\GC^D9?%ZHX]]I()UG;]*W-_TJK++_UM'35*T`*"`6 -MM_6Q$N#XB/^F'$6U9C8$;"5H(9SA8NEO.Y*5F5OW/D_**1=P^$U`V4_M2\;C -MTHPRJ;(A$-P.;EH"-?ATA):9,H)U!*IMC_L_U*D=<\*I50*"T%>-KZ:W_U(A -M<'IL$L]![.M^^V:-Y[/UK.`J,M.-QEVHH$FHN#W-9SI4N>MTV;$F!-82->-S -M)[F-&G`"&CF=1]W"!P^S<0^WQGP,7X=RXOF,6)_!O=58@]Q5]!&2IF!+&/SF -M8!"F$D;3TL4I9%89,'_#PX3S],-^(;@`D\5!2IRD\-N[&LJR/4_/F1BX;X:Q -M,IOYEGN,UTTPIQOEX-:UL8Q&OD7VC<\.ZKM.\IUA-GB48KXG>' -M@3?3LP>OAB5:,GQS=&RP\&%:;41[='54]3DH.0Q`9RYG)_-5&8:)B_D@*-GE -M0KIKTA%.&SAJ4`<)=DABSRTON7J0;]_<+9=Z\PVDTME"V9SQ;.0!N+&!35[F -M,5+M%5R-"<=FK+RK([MT0I?>'6FC1[/+$4UE,,XNEJ"=2S=I6CL`WQF3E_\A -M(?9L(A2+1M_E=SD0%V>0T5,%Z(E86-1>U8#4VO'N+[O[TM2F,/AEJDM`-B4J -M\6O4_V`8"B!YPGMF*,3)F%H:X.54Z+J+HSFO8L*CMQ/`L3-6YM#8KW0EYJYVU`T6N'HIYOP5!B<2HOI-@= -MC^/V.<,Y&C:]8-N^R)RB8'W7MCEDWO,#=26%6X&I6OAV]EXY'_]Y:(LKFI#S -M1N426ZLB,>XA(`D$5.SL1>&349$TA-A0$**!:,?B?)-QJ>):B@^Y]?Y?0#7" -M[-3F"SW;-0=6IF1H8' -M1/Z`T".B"P_[5_^JC(1\0>5^V"A5R5/;SRPN'GV+.TE\'J(CY:Q%47T+4.<+ -M&-F5I/S?5-IY847&41%B,9^]&_*J,B -M;I)GD,9[4_2#?W?OQF-]@1G18+E7\K;59@?[V%X_:^@?0+7DKMYGU&9"4R`] -MA>I-=(53>O#Z4!#+6B?%'%C*C!0T`X&2I&(R;S8R-MZAT/YR7;S,JB`(H,97 -MZ?[:R@NIA`I9]<4KS2,V(9APCRPVHK1VD^VX$5K5\W$+=D2*^B[;AO"E^BMI -M\7$^-2\X$$D=%0-9:&PP#^&XI9BC-7G9\&!;(6P;P:$\!9.@=0_6BFNR8Z;2 -MM_\4FC>B=B!J[")L',]D6%,(YP^`Q-1)XWW78)#*VOR773-']/U&9/\[KYWN -MJK,VJ,@.+9J;J/1K)"KOI7-_?V((H(I/WF8%#L] -ML,#%)-!)`W491@,8?R[;&\]YM.C7Z4TN:%=HHJ%69C6='LVA!\M"2Z)#?"@)O18T%84H(R=2:(KU -M7`_FB:46&H00&2/AU?9`2?>+RS_@E!N6(*.8 -M6C2=?PDJ;7?!(BU+_QB)FT-5T.4(?LC3(3`*P>T"YJV@8_:[9'3 -MK;SF/QC;.*=_F)&NCM7!H@*^4]\'DA-HF1%C$N4FD.=UWB,N!!_2]$(6#]%* -M!K9H0X)^'.ZM/@A,A@-!V9M-X3N[?B4"RYT=2QW8X8O!!B-+!'&)0D=X3F<= -M]9(9$)V>\`^M\7,J1:RWI?-#@(X>,AMV/0VX7 -M;E>7.S.6+?N:-D#XMU&7Q`4=6YZ7E2G[]HZ$$>KIBQI[>`#:LF<'W'[N][N' -MNV2Q+1[[?A-&Y!0*(DU7.&\RA_R5OEIJKNN`N@;;@V\(R^"XTM'(-PU$-7,B -M9PM*W5V`3F3D4D2=V3UG\;9!;#V;+3%3%;Z;ZR/VSI7*E5*1'*HD<`750/I' -MQ"]-"*]H_@-DM2;2>9-H=D$NU4<`FE@V#7O[H\'D27Z3HVLFIK^NA66^=4$85KC$6OI03#`U2E1*UCL*^?U(,S_R%^J5A]H#Z2XO+!QS@(^I30 -MD%D6)^.2VUYH*10P0)E%OWJ)E%@'<-@)O#5RB=U9)/G=UW7T;9ZQ4]4Y_Z7@ -M(6,28IS2JAVF//P5NU1A'?B17_6('T#SX8!;`&[V_;5^`-`\*%GKVMNRF)V` -MFPPKX2\%_MX"T*,=V.)D6)QI92!3]WY5YTGH`E:,[W^))13:S13>,3$V;M.% -MZ0X3Y82!J6VEZ,)2&R>%B(6O#@>&,:=*9KX`5@E.]=[Z9YD,_'7>+#U+'@&$ -M>EO&#]ES`U#.4>Z:LX.N5?=*$4:-)AXQ-=?"4D -M39#EX!7M%M)/Y;G<,BN2`/)#_(_&YHD-9)3M@Z16;Z>&O%Z*E;'`3V$[,#GP -MW?KZA5HKF5DG0=Y\Z@P:]!XSO%@L@7\X[U?)U]3.'N7*AF75/>3?`H#-<+4WF -M04X^0/'U!F\^6#1%7!BC"YAV&5^M#+Y>Q5Q944 -MH8O.9FP\Z!M"JP`A98^1#\0N'UFIG;_SGNM,X]Q-!$_7.G$NA]#0&>0BU2&4 -MOT3X#4=`#&Z@J"1\Q(!>;;C/(S\**&462*`34MB?.^Y2D+/7W/EXC7/,]JR/ -M%[O&E:=Z28=E9:MHV?RLZ"JEAIGV8*2'2FOU-)$A$0@_[*.>IN3=O=@DW/KY -M`?/_^DC0_=5,$-#3B-Y(V86'H*!QIT.EL%_+6#X7E"I@,SB:G9VWAR[UF]>X -M@.)'C&:5NCAR]7_/>4YX0_TKB",.+G\:I*!65Z=F3F%7*F'/;`W"#^+[SDWX -M5,7?:(.R%$)2I4T$5W%GHJ]RSE":^#Y@3>)OHBV4C5&HLO3-H>T"\I2;W?7- -MA?&Z6-X>:AA!;H&:1RAE4!Y8-'JU19*N6?Y98H@O#A9JB&PNG3<YZZ.D_Q\U_`!=R@PM3A/UT0X3`.7G:-IC)7,C-=`A@&L)%;C^[9($M8QLLL -M+!7\.WO4=R0_`[0TNK6KZCLCXR##%M.WEE?Y35` -M73>DF(/I)'6\!D+^OW#=NP88W/A6X,VKQMO)'1.]=:12E&MZ3G#8<"3NV2*5 -M$$7UU^+Z4^*8:>C_>3W=$^8E':_FC>U/8';T\](6U9B#%3L26JC=L?F.`#`U -MQ?:(W:DVU?P>A^F'DKGY?;GNU-PH9/UVA:@*1(+A'L']>`WELB\'["FB3>"S -M#'N#"J@L>W9LEQP*3QC\572"ZQ8BYC9\N5_2]-/=(1CVRU]H<2J@P=88!?9- -M-HS590.M-7^3--E46O#5K`_)D=$FL#S(TOJ"!'0"4Z]UW"3INO:OT:R=GD`[ -MPDYS:YIXDE9+5--J4.HS75V#"NVJQ]0Q[TQ@N1*Z'O8MF_IOQ/A=6TH5&"K] -M(#E<_N8F?WVAY3,FFY?99-[N==OH1@>0AA?Y#W`Y%J8Y@ -M4!W5`&XJ2UA'W?:;HR\.JE54E8%";:[<)536H%5>]IUDOXR;:X,<-B7'PY=% -M`.*%CNC6X994&,^-YN]A)65[`S`!^V!MNAU)878U^DU//?=;6M&Z;@GB,])1 -M74ZK.=2Y(E_5_@3@HG?0ES*W2L_G];'4;^\DB)4J\C5B-;3%"--ZL9%4ZNWC -MEKA%@TCA5>F+D4!BDNUV7`$*OC>4\VP:G9FCV=%B%#9H.0CPI#NG4?_LK6.<+EL=TML'E8,8^;<-TWR^B<1MK3 -M)#(":YL2'BZ*J+,'C<"H?\*^;Q>)V3K4,]!I1N@?U$$:7@K632OCC+@>C'U> -M=`]$O+$^W=:BM!I-7?.T`^Y`5P"331HKM+&^R>5IMD@.6P+?BP>:W-"8U-"U -MU,,79<49X9%-:^*X+8?-W9FGG#?/E3.P2^H70F5)+B[><7CTS@0C!1Z;R:C0 -M;RWG?C+A_T=EG.+'I&QWYB!40?;K,D]B[F-7#I)MM2Q,Q76\!W0N)B=NXK7] -MU_HL&W,8`,1HP8Q#,*[QG:N@K8CLIYX^JQ'A!/%KU%$68!Y2% -M]C9O:V0^O,=MQWO+1G66M7_`K5^%/VHA)[VH"%;-3_3EV]N<)BP:8&^^(?`] -MJ@UOT776@_&*959,10$?N+"DU1>@;]U4U0^Y09.4'L23Q6,RW7Z^4LUI;.4" -M\9"*<`A2M7TH[)L;PB^TE#/>V[DC1Z:6W3T!1XDPP&8L5RN5 -M.V)K>S -M:T-MC1I4=U1MMBFSML1G>CHMT?CGWKB<:-IVX+9D?( -MOPBMXS^QU$FQ\*P="8VBLBLV0DF?UVGRRD7(DTX%G86>(`R\*!TI.M<9`-A> -MT-DB[(JDI$7$>>7IG"RF4=>&KL]QL.BV!IVT -MR^#\1$V$1"K6FUR;^+W`K\>[>534VYR94O%6./`7>5'B77.DH:ZE:"9T8)/3`.)BWOH"* -MG'[+#C:X>+9%&[_:5FU2I4W]&/_OZ7_9BJ$7F%C5F.)W>7*9D=I -MPA0Q$V/6J-/@Y6FIS+$B[CYN605!%H'H'JFBYM'JT>MN;M@)"^]:#\.Z/)?T -M/OKI'#TZ&*^G)]OS20BT9K0A'&R:MGVQ#**]Y&R-COP`,==F-D^+!ZS#B9<3 -MF8C5%/*%&K)K2:4_7KLD>^?(;(YEB*>>4AZ+-'_ZSE@RM,<=F!\CQFUNA7_0 -MXD_7(5R$')U2CH9#A%G+/1@CR=0=))+T[P_M><^D/R;(("9F'Y)8)=.G#H,\ -M%1\])"7-\Z4ZP6K\&NX'9I.O]T*-.JN'PK[S`]V>-5&EY[_J$* -MZRZ?7S"E?"<^(!P*D`W`EEZ -MH-B_(G=PMT'SDG6'O=;(^Y^^HY4<47.82@*Z+\%@5PB=I.`?P#8S`0+ROG\# -MA?C:0!-Y^^%]M82V([$VMHK[9?1R"M@QK,]]^('.T&U6ICFL/=V'VW(2SZDR -M@;(#`-1562O"E;L:?NH3.U9U33'J5X_NP^3FER/4T>F\#V%#&AV]I)GN,:,L -M#G:M),.$X,Z-_5%\;OJN\+2C>HQE]W6+F'%G6S.?/FD!J,U@K'M'IO]_5``L -MUKA'*WN#"@.!#N2'+N>#\U*X/QZJR1>E6P[@KPYP;8'`(Q[5"V'0)@+9)=JN -M#'[#QA//8MC'=YTG\5IF_4.>\&J8F=/JPET1[`TK7#*__[GQ)K_S"DUXEM1M -M>R*1'<<"?WH3ULX[GJW+(Q!#A;GI]#G=0_.W:41]85WP)%";BBF,6@,U9,J! -M>99(P\Q1R[',W\8RK4U,^\"GD'_&0';%*6*MLTWR>Y"(\.03>V_5UM,H?F*2 -MP8\QH?C&%,Z/C7!2O:BE$'["M-BY#).W@8OG1])!5%-#, -M^J?9L;U<:%H88.,,H"*YI]Q?N]0WJ=5U+7XHCG_%6"-JCGD11?#2?0PU,JLP -MMRT4H$D)[#RLBME-$Z*_JVMJD!W>[)JHG!/U"@^MC\`.4ED!^DB8'HWA7L"+<8,S98"-).$%'D(7-QAF10SW$C\*;XP]O&*( -MZ,!QGR64I"/#-7$?L.L%!%F!<,CJP[,W$:!_ZA=HS63;\-OZ/#]!P&2;`8F@ -MKPE@GS\:)5I@@4A;0%A:0%E*B!K.+,BA`QTC#Y]7;A0L3-=LZ8C_;RG;-\*$ -M\#Z?H"I:Y7YPO]4?WRBR!I0U@52Y+_8^LA9%/PU7TR;STQ0;#`$D`'X215;" -M@URW&:@>RZ[U -MH`#Z14V?KX4%WU,^4]N)ZX01U"$G4^[LQ^=P;-US&UT@ED<+V$33M,ZTX)R. -M0VQF/B#F`-TMZZ-[3[M1EWT52A>A*%]#GG[FT!4+58U9OJIQ&=+:;;-B1L;?^)HW>B8C<&AUL22!\"&=2X.X]79)VL`%5&73?J:97&E.$5RHPJI*-@KX5:1SZ9,:CI^M -M*5M.V#ICJ,"0*(Z8K1\^P#")W#\)1Y?/WU;A+*EU/=_QISY'VL<+T.] -M+5+I_QH8#I7SH`4*GQ,)Q*'L'`4,\X3%"8NT^6E"P,WPA&HFZ])_9*4]MZQ& -M3?BWL88I:@I5".>0U!G'4=]S)$%-L5X:-OF24S,P4GLAP83=%8 -M:8<7@WO)77;U\_[S.9I,,E@?HY_=LT;>1Q(($FR6?Q/Q`M\N?HJB2:$J:7(" -M6KHRP$0\/YG]EW6/Q2F%K#?IK*9,!_?H^-`B:J3K8^SV1.CG@)'K,P7$W"@3 -M9X5BP_^4_)/#[];"X+C^&)W3+#J5SF.)'09N<(.C>%M@T+REHX1EE%B>J -MW>ISF<.SM=>)3#!:B$D4!0L*1&PU7&+A&PP5:QJE5AVDH3OZ7U!0[P2J>_?T -M>E2:4'D"27X0XEKV*3^7\#PVU`"02-[NH:G6[7VVYSD37::+NI.?O3/1006P -M;&;,G$+8W60,'D;$YWB6,),.!(Z9D]G-V'CJR9,$!BZ*Z6$BI82:%X_)UR>F -M]O6;<),21)9P,HLG>^HKW<`\G,#C$8Y'Y^#%>L@/K02(,,3Z,AY,E6M%9NF( -M_5I2?KM%P1(FBV@(8\>,&61LKH-`.A=CO<0R?:`T0[6Y*P"1)[0]N;@3^_*Z -MSRS'+&@@"2\U;\.YOCG29PB0-4@>7UN=F;2'/;UHC+EJOL*)TWXU%B^=A6&Z -M4\N1$7%_NF8!E:BJGN*Z[OEJS8E*AE@".49-`.,(=+6XXUB -M[`#8'I[YPU`C]:@JI9B6&"5#&%PV^Q-%QX'AVP+BPE5*0?\+I]"\8#@L0Y6F -M31LR7OME`@QN'S^)O:T(5 -M:G59`RJ+W?C*C?,V[OU -M:B#US;\CB=LA'?;M7E&9$('P94^;`.BTQ;"5.]5$]>@NY"8P+0W_'Z/J$?Q$=Q5[:.Y>Z<-!P+1 -MZ?S;M>KG<;:/W21^F`5,J80R"=C:J")"F'7VN^\X3DP,9&(5$E&`JD:!L:"! -MO8((.7%>/872PC1W+J8Y3/2/;[X<'9[QWE[P1R:XC=!9ZAG`;%B*S"KCL0)O -MMIK9$TL)E0=R)^:T;H_TM2,@+0/R6_6(6ZK1;L/#"Z4+._ADQ[(J&8I5J]O6 -M3#-:,HT1N]N'#/F!K7=+#9'4JU7P`N,%6V:YQ8TC7HGPPDKPI-X/RG:P!FZ+ -MJQ_[`T!3*1-OA13E1&=HND0)HOXQ$\5Y?PCF31:>:F+'E(8TC]$QX"@R9! -M+R7D(I]U-J0^"^99)Y)W<\'&@E)91FZ8\N]P(WB:!N)22O]WIRRKL]W/F&S% -M[T:/2!PCE6KMD2O9$_2MYCAGN+XSDF++-AZZ!^J;2FC2<@B20#-]!9M*M;6'>UQ(G1Q_FC/2\+MRXG:_?XEYK0X2PM;=@+MP2 -M@QX02H%+8=YT#&QJ<#R'@:MI`Y6-V#K'#C*[MA5LH0_\E@AIWOI\=WFT@[8B -M,VTA:B_+V];G],;$O\;UG#WSG#"=X#:Q-[P-;4J.ZCG24A[+OY3E>(R*$T0: -M7FID"6X$2;HQIZ8(UA=]W]V`V]N'$;/23+#R30Y"(#HF>Z,@20,]F=QOMF.@ -M)R5[_)H==*NJ:%?F,19.9:*K6!-QGU12,`N/^(#?*=`/OSF;?Q/:'.\/6>NR -M^3FIQS'?3INED_[4):3AK6O9_)YDXBR<""VB&TWV+,YVZ45>/F-'*4K(&=JD -MM4[A<_F`F7%W*EB#K2%-A^K&F9K(Q2P3)`ZYPK6'->!Q=L5RHZL6#4%S^%_] -M'?H7U'S;[[:?"*(]%*QS-;4TQ<42QI9QT*D/]>?,[=@.+ -M;`>@5Z>_#2.N"A#A`_'JW8`[RXILKW&G/Z1_2":>\Y:NL!8.5U4=U"2V9-"N -MJBX]F:M,SM0[>,/T.]5K8FV7O?4CR]&$'1?/\(@Y/DBTX,4J-D^:8GBEW.)> -M47S99L2%#SFW07V$3N>:4F/W8_E4VH^FVG.>)"CP:"JZTT'C'`S-5AA9%,OA -M_I)$<*.]Z.M+UK.I<7/#]Z%F#O\J,^B3_%X3]J9*ADV!\HT1?GX!$G<%Q4DK -M0.:PIH^-,2<8=#L4UVD;.*I39-O"2V&6X)3`.N1AR]0E]OW'[0/^K.&G/[[T -MTFMTU_^H4A%W8.;M"7QZT"FM1BZ;;TN[,+MBBG08,THF*6L[[VIQ;N/$ON>'I>*=BZ= -M1+#-5Q9KEXPM303Z29#I>173`BTRBE:.N`V:!+?))X;ZAU2/L1#.*2M1]UTJ -MK83E1CH@G38`#K9=I"M@]9MQK>,JA,AI>B,6#$!4]ZJ)#5"%P0:-;07A^;@N -M=Z6Y.6_L1F]ICIQL6U"/PS5]__:II,0JB=[(!6\">8B\':XC<%OP20Q9\@2% -MSNBW]D@O!B$,0&P)S(3,W&E%>*P2MA%;QS]I'E#[?N:_-+3,[_>R'RQX``NJ -MHOG2.%X6)P?;R8&EB[=+7:)75$)?6W^KE`H!-F+$9K3(.P06(F7?CVG]F[\] -M`<2:D223E_R3%VTM*57=_YJJBCXL`1\X+;?^!4%\I[0-?-`@4W=.&4V.[>DH -MDOM6%;]PS4E4:)5-"'N#@UYDKQK#H\#7YB"SR!2S32)OL2`.%J")>5VDHJU4 -MU-*J&2?29/UKPXM26&TP"E9Z:'?5O<21OA.?\-Z"UK_!;8C#,SEWD"'N0T() -M0/D\+(7/QXX&W&0KW1[F7#L1R0"G\2+#@5@_.^&6RSI-C!(V+@3Y8FE3WAY, -M/G;T5P+E+'DJ&;L<&0.#*C`:A'M\Q8>=Q-2YQ1O]KM@J_$V'Q;R!J]'L4#=6 -M@1`2'0,R)'JY5]$O/%CK%)7D"HRH9`8R%ZC,:>L;&"1'P'-VN![U&X8H(<[5 -MFMS!2>QP06U$"2H+52JUK[J#<%K`T_.@%=40<*\DNQ5&/159*M(]0@MBPD?U -M1>RV1C/D4R(MLY&IWL)R=YJ,-"LJ.1A7QN)VQD6M;:?1^E!H*,PE3$A>JE*9 -M$`)TYM@]NV5G2^Y.7H6Z9C-_ZR!I.>MSBAF3MB_]39"ST3/BRU+O&=RQY785 -M";WFMZ4]E@9@(W21;8)`NI -MVN@XOVXPE_/0V$>-3?*J,C)U0()!W_J'O%3!)=URD[I28ST%/0R`UID[A"$+ -M15>F'F:!X0*0F")"=;QVX"K?DGHP,I):'QOR(`'N:T1U6=4-_X$5#?I1.8(<8X1[S#+9C]0SXP>Q6*1C%)IS`^%AL -MVT\IUN,3F%O.IV]>6F`PT7$SOC5;"DV`?N;^0_=N5BP:54C#)A6E\G&DI3Y2 -MHR76^IMXYA^,^X(HQ!9B:9])W1-,U2FOH6#^7;=!-=T,!R$>?AP>4YI/1@6!1K]J* -MLN6(,"QBN:M?@K.F`D.\IP\OV,6+B-`L&>`F:5OKAD5'DF^S!"5I.>?;@X'] -MI7_Z\WG3;62'$QC9\]GEK;*K^53L"6JS=MHJ/;&OQ%YLIUVU>MO0("G$N>OD -MNU+U<8%IK__#>6RU?X07=.+?M/)VTX=6J_=3X`\O#0JPC8;9M2Z#,T`GIQ1U -MBHQ.G,R,M('X6C6YTJWW"@9)9,WL@5D;JJ*/RTA_9V;$D-Z0JCV#]S&Z,'#/ -MK5$+3;3^.NH/:<,Z<=I;L)W;,TRC_(H?F41W0(58/_7GV$(I_,?68OC)VQ<# -M'$XH+ZBOLB\ZFW,IM8EM9>?Y[M8?;;\4_&]9,`U:9QX844U#&D,XQ-QPKPX9 -M^GM2%DDH",E/945M5ED?!BAE!%VF%59)=")5%,"ZS -M!30_@A?O4T*UO6.:S<\20:M]I/*!P9:3.;*MLCD*"G$U6P10ZO*X26)&S__M -M)RCB3MC/1U@?9<@OM$!NEAY'1@V:RN-B`*+5S5.5/G)M6B3"!LF2[@3(Z9,? -M0DZQX#'D+E*NB?B+33\LT36XTS(SFH",;`&L_CJ^ENBU@Z\+@%%8B8\(H\W) -MV&N@=]L>MRH@HX,LB:3F@=.\NU=PT(56)B)]3_'D<,NFX_Q5V%;-X&+=7*>D -ML?.\0FC8I?;]4"#N*1:\/ -M?3BKB>BB5P6^!3OGMM,/E50,032CQX<\9=?XL1/RCC]KFIEY;SIHU4W\__W)+VPT*A!)_GHU_HV$*S?="J\FAMI2YH9/QSN5K>Q!D=Y+6% -M<9-?F^^MU.+:4*DES74&UV$NH5@,O\S6M6%&:V8&Y.93*]`@*7CDEG6.()_/OBOT$,Y>`5IB%"%8ZCO\VF`N:`M -MZX7`4G4KHI[H,P1W"J@2.7'ZM[UY#/*JABCA00=M%MOWZF#:C!:YO@SD%V3I -M#Y^=M(KD_(1GNK%T/U^PHS@]R..6D^Z\/?^=-8&WJ9'%K\?/U6`&Q"$?^:_! -MRN`=0M^97!1\UL`)KUP^XKG&J$@_WC5&(9@P&0==VZJUQGHDM6';?#H;VAOR@E';GA5YA1O>A(:ZHX"V76D(EE!":JI4. -MR'?+6BKM*;Y)Z5F5^[UYO@:WP9<]LTXCJX?&3Y=O`)8L.'A848/9G^._S1`I -MPTIA%NI-'3NP\G][H#:@]]MK7..]#`F3=Y4-4PT=;]D+GC&CV"&F53^!F#C> -M*2->S=A58J_:VL>RN(6[>*NML8LW]B:?*T`2,>T-/Z1%D:1O5.UCY%4-#AV- -ME--1W"$BD5MHCVT<1OG"H:G!S87/;,B(FU),5FEB7 -M+&Z67&A8!RDO9Q5*H"SX(^[7:E/3ZO!$[=73VY13T$_[#`_6Y/4P3-5$<9R\NB]+'T&%X5[_8.?@%-0 -M?YG?F85J#,!S9;9Y2)FB9R!,*1-`#KC=5Z&'S0J/9R$Q'5^VF!+HP!J_[#UEQX<:(G0D_> -M:E+T@1O!T(]SCS/+GS[`DN9?!KS$#]Q"5%ZP7@]8'9(,4A#9])E(,AP,2G:> -MQ_\L@-$-G*=$V'@K'#"=N4'S4UY[DL3V0?]BZ["I';IBVC#E53P1^0WGJES\ -M!W6W&)"P:H5D*;9I(C/<6I^1WQ/>'C11<&H=,V+$",#CPXK+K -MS<&>8T$W2ZO)<@-&`W@>'1=?.,FAJ)FO4S;4XX6WI,M@+8&`Z+I'><\P8\:I -MM%D2R9.!WI`MG>@JJ\L[.LJ[E$Q03LILD"2\._6 -MI`&[?VU>D>-V4R?&0\,"0$`]IZ(H'G-M!A` -MTA,/:JL&]GN90#O#+IZB)'B&`BVH<86V[!P+ISGD=-^8R:`2F9L?B>RV -MULMHK4.2E7C@D3IN3X+U8.`-A,ZY/FK3#\YO!::\`+6;>8LM)P+R[PDMM>QB -M2:/,^*2A!W72D>,FPLTI7.Z#F;W2Y#MZ[,]:T7L[Z8&V+2 -MH<1D\YM&+G/H/%PSZ_"`+7+MMMJ"6K_&:#83UOFT;G9/!L@I.!5M!,L(Q,X9 -MM=]-2%D.AX%\5J(J9/Y+=JT:-97D,\KX"A&$3@BO?K2 -MM8'`QN$%RN!<6%_CJK$:NQ+&6WUK^HR&9CC8PHN3@)$TQ4?D!"G2O*L,% -MR[3"/3"Y\F>HG].#?'.Q9">^I)"'*2?0FA/^-TS)*N'1.#$6=FR,94)]Z"IA -M/)`VKZ&(:41HG2%![2YE*20BJD'P"8%"M8!7C11KBO.+[$+8SK)2+;-&_NQ; -MN[C+/UH9Z+_`-*LGHH359L:CTH30S%9(&:"OFI*+M#Q/=\I0O_62Y**2RQ%E -M@)\C5:><^"ZDC.7\EO&VF[J7M6?E-L)1WUTJV -M("7Y\B/\Y-2.OF(1%S,3;N+EC`_XA!(5;[^N(0ZN([38<[3IA1/C1.W;'H`G -M0P1!R"G#8="D`E(T/I&"GC+Y^T99J^S95N!WJ[7I)9;Q^&88+NI!B,OV8267C>:/YV%/V@G4>C1R&!$GL\C_.@-$2EF?LGO)G"";=+H>"V -M6^73M@@S`@OY<>!C_J1*]\=-F_7+^J86_BA*"L&@IGNIB9454^^V2A'/$4;M -M.&K^01N(+H.:$24X0GVYB'MRFI%MT, -MVQ1S9,S9U+?A\DN>,__![=F!IY.N!SXPSTPG5GG_G:)T3J/9LWZ2MKG0[G8I -M\J)).I/BZPI>'8I^OEG6XX*4S\JN23XWD#G-OB*>BWN!7+.U`[)>T&##AX'4 -M`"PNP;?\\?FQJN#*T-F!3,??"UT(#D7G)7;ZV2,2@^C)NJ`;@2#+I>NOK`AV -MSO8CE\C;I*"4+&T/,>K0X<[,?<\L/Y>@Q-G;=1D-=Q-:!.0B'%%I:+CT`&!+ -M;>$#UFK1-4ZITQN4PQ$(OCG5U7UG!H.,+3ED$#FLZ_0ZZ^6!/H=V(PB3;4)] -M@+'G1[R\)+Q;-,;LA1S^J7M+<(6I>]-[.B''YD7VG9X-/ -M3+'FP5?:'D"(.<)*_`(PEU4((DD>U+$KX&&R52U^5:P^*5@*?Y%Y89VM"<=M -MQNRQ,D%_?H;;_.KV%K>/["\\91HD&%\5Q,;A"E/1)R!QMVRR*ACH<(PP"VF\ -MOYJD-QEN.:QL4B0U.HW7$@P;0:Q`8[`O),3,E[>=472M\=15[IW"L@`'4@8K -ML[];QVV$>]7@(8:EXAB%-ZY=M\FU0G[2>+9.,53V*N:G69U0M@L\NRF]^/$Z -M>45GV7=_Q"OAW#(7JG1"V+4BAH(;,Q'5LQ";T:V?>E?Q5_UIU^.&KR8$@88> -M#Q$J.`]R:*O^2U`3]A/'W"GK&:'_16[AML;ML2X2;W#SLP+`K>U8PD#,_%'^ -MRG>'?48\>:*P+9C]D;A:@$N:@YU$O1PE8+=E?JTF3[NZAK?TWFAB:O%[I)YW -MB?DWAF+FYD8X44E6\YD7,.B45NGH049UETBB:T*QR -M%4%-&&W"=>>N]QBR18A[A)T -MSX;C3@$;T?A^<V8`%P[ -M7SEKGQI#N16,VNC7_TAJV.W%#\A4?N5UTF(IIYZ)X+\!$9ATV-=^*8_0L=%- -M)H',P\9=FC`!"/I][IIM^S;5!:79&90!X_F=:[:ID'X[Q(T_>]X)+MXL'K[G -MX0%7\`'2>_]Y%DYD3T5,,2P!]IA`DKKH;0>R2;Z$<%MH -MSP*U`]!Z5YN%(E4P/L0(7KG72)_5JQ$9R$1''^>0GCQ'6I2-1DCUK^^HY+6] -M;V/?87(23\#^*W,5B-E^D'&2=)Q4K8\[]"D$``VL]X^LJZW6^<"!X\,7ZH%4 -M`K4X_2CK+TMVI)6[_65BOBP!%><:.5BF!A.JG)(&-VS,PI_ZO8/;I29S\M_S -MOF+O,C2MALOARS1)@T?IB-<8/3=LGCW7@@^_, -M>^U"P1GM>RQ<'Q'T5J"&]Y_&$JMPU=:%`F+[9=@\L1`C%==1,@J1$4Q0\6KG -M9$0:_AH!XYEGT+38D)$.,7:*BQ!>WA)O'U#=+K%"TY`8ML#=7;EI*5-J_-G< -MO--WR*OL!Y\#1632T;Y%G$DD791/'&)D;\CN^/!\@ZT+'(Y53IY@I?X+'O]9 -M*I7/!^75IOQW@-S+^@/U:3]2/L.K_5&+06@R4$6#C6:%8:>>0PD?J>?<3'\` -MD[FW:936,!<;F_5OIRH=J\L"T&^_F<>[0TEA+F"R.5:%J6E[AF=7[ -M0OYD?S*N-KD;$*CR(D0AJR]3:*H#;+B)55Y+KG/9@7WS"T4YXLD.X=*OSQR) -M_SEXW[@_G8`5C29-^,UIHKSGNG@#:URXO->X15*"GD,Z"J-,!3YMI=7+8R0Y -M`9@]XV\BS/#RK>S4QE1[G93M2(1=]>X0#-4CLV;^#\:_HV^U]*ZTIO;SL]`9 -MZ%`Z5A="O^33CY7KX1LBQ0]]*VR,:5Z):?\[J.;\97?8WR+TWI\T-A"=#\+D -M'L5G2K01[BYF]@-`4_C]:1G=?37G7]FJCZ/<))H54\4]`]L<[YN^5Z:W73E\ -M_Q2AX2%.%7B@2SU,"JH*<6"/\>D1^UJH3',B0:6O-"CVL2!)#TLKJ1M`A]8& -MQG#4PSAD'%UXX+<3?([W`[11%%^;,]_"V*MU6%]WG(]&K/4R)1'*L8J)Z%96LS0Y[V+?J?PUR,UYC-J2D!^G'EO?5MT$+:XIAX*^T>QNX:2#&:[ED.0!]MC)'V%]$-)/ -M[$?6F>7CV;__9KUN"S0V@!7AH2[T@P[]@UXN66!^T]"*9-9_2KG:7JL4,D(^;B*>^JN5QD -MCYAH%F,U3J34*+B%C'5@^.X@'JKW5U$]\6F&(#P+1V-+M;L08XCT.F`U'RY) -MC1!0^`E^.Z]1Z(7M(-1.5+Q<;?'G[;/84\1%')&Z,U-'\D\SWU7(G4+K?E$X -M?I6/7%VB;V0X^QFT1>$\*_$A3#74W/69D3=>A/7&[I^_BJU.6)/^S_\DWCRM -M[,PX7KDQ2Y?<1>-E:++S=2WD;F=CC:+]!W8R_=59@,I?+/3V;K4-!,3;I`Y. -M3DU9>E@8,DC?HMN@4VA5[(C99;5?:,>U96+F=.<@@O@`=R!>)2[7*.>>NAAO -M_)?'IX'XM@`OO=&K8^7BN!MO4?P$F.-50C;NKSN9FV9JF(B>,.IG!I/ZM+E1&QA/,\7XS]SBOMT3('DTX,DG8/F&@7I&6*I#3"\V.WI-Z*:' -M.4C]RTUQXD1SL^5$&<7A[J)K:E^,MO2=G`(+K.P,^*]A*SRBD+%X"`+WG$,D -MMT[OP#@WCCUX!GH6Z*J'`OE)J4+:))D?:*(=+D$(O@X]WKF+UN:[GFAVSGOU -M.D>H0ZJM=V+FXUOY,,C%E44U@:9=6AKL_4V?ZQ760O6=MX?8:HS34?337?Y$&)HV.]W&$Y9<57XG(13DM:J^?YI%X^%XEB_ -M(O0]3UQ9/%IILM%J>D4\\3EE&EH5J%SRC3 -MUX*GX!$RI(4-ET2[%^'MQA0T#0RS(79+]H]3PIUD.00PU$;&FX8X/215"W)T -M-C)+\!"TEOOZ?U*.!#P/)F;HJ,N<>*+@AY[LG!:)A]PT+7']EI\(48\LAUSE -M0ZN%M___2Y((HV=R1_"BNX\UP?G_:H;I\")M9FU;V&#;S/:_Z`^22;-.P$I# -MBHW[XILA^>:O&O]DOEK^@N`Y>@%@9&->2SG.@F@)](?7!S3R"1 -M);;QI'$R=R>]01V>R;I/FS_)-]AT072K\$A:2RH-VJ451=K5$:.15FEM%UOF!>1ZB8`&>BP1/),I%CXZ@%L`G -MK^K'H<3(%N1$IK"`@O[/V*=@;0\#C2"4"12J@3$Q\!1^%MC.+#662\$5W];A -MC+%X'>@,%HP&;M -M7]*?6!>M;(E[A&[)$JH6/KZ:%>^I27:^X+/3(#FM6-$M*P`Y\V/6D4F_NMVI -M3Q]5;PK(7JCK.`?05.H1YH$DK,SP$ -MFAK%N;Q0\`&6'(_0?F&U9^P2J!G)?HGFJU+7.90?18]56L3&J..@MSTYDJ@6*+44>I[Q20>02U#BY -M8$=D>12[-OQXJ*"'-7H<=`TD:_D5"EHW[EY]`SEG.+/8QPY_F231?#VXGH.J -M%3!V$D95X)?JVJ:=TQY)B -M\^NG2K1D#YJ.E<2]3/S2%\';2TDD>OX+SS@.C]PVG%UD6M7W_?W^TSK\=J(*0P:"_&>D0, -MF=8'/_:I+EHF:=('-O+8\6],H=L:B)C3DL5)&'B9[[4:?R9'6S.2V5Y2M[(5 -MF+KHU?C7TE`)19$>_-/J(;KETL/FWQ\7WDK0F=#SR!0:8$Q1^``%Q7="A&?'D.P -M#5\XG6/S*#X6&'-I`Q4A+JI#V,U5!(I!`KTPDIA5UU&U5\E`(#7'N`=3"!'# -MP-JFL,?+JDB/UW%]AT66-'B\<[!!K$!6HX`C'S?%K"H^JG8*^+NVB3]K(XY- -MX2<6<&4+"C\C^1+*:B0'JLX,E@'6"Y1ZY'HL?PW<&>JTV-UFNL?I<1RTR2%:FI7UYERH&\E=)HJE=I$N+ -M;%YQ-Q=5ST+Y5U'Y,4<6]B"_YB12&5,TK.BJ,3X_8J3CHGBL3&[7WODS=!?@ -MA#V0@`X45T\0N>,?@$P+B%!T*>Z'0>;IEH)'TF?C@(*.K/"#]V -MVA+?%Q]+=XCY -M0#:\/4PIFHP27PJ`O`-7([9_>BKQVYV6X*D4.)E']:Y`EE,X/I&95:(%FUPL`.%P. -M!2";B?R+*HW79807"VRK'%AG6I4.LQM(^#`B0K:8'S@"_A66 -MV*@9BWGCJ$TVAWZ5T(N0N8L^]=],ITMFW-)PA*KT]0"%K=4S_.OABX^\LS1/ -MWYG6LA_$`\^<-%@LQ3E;?[^_M%;6W^`W55_?WW8'\RIV`OH^/S)2CY6N20SN -M$W9`O#220]DY)K%_#SE_I-#?%CV5(^[\M7NJ]&*PM'S\UK2`:?TN=R>Q?/6H -MB42^^4,D;FWFA5&-HU)+E:D35,OM*4VT,EE1H<<++?%< -MG=*>4&:OW$M8CD#8YVZ>`KT3FZ-1/:T(+N&A!1O/#_K@G1/G1IZ"<(@D;4/4 -MR9U=Y#U%M6>65@^0ZK\I^%>#F]_OCEZ+F(MFR/0M-0.? -MP-*]2JJJYAZ2U5;#_U$7GZUW[^,@9CO&=G3IB%84X5E"Z]9E==Q`72%A6?N7 -MYS+73;4)HV*OUB<`#TM5A]S*%LFLZNOD8-C"R:6CO_*P8D8\G]BF=SK[S*N" -ML*0(%3:E>&'MT$S8?_D60-2>T7)Q/WSR[L-@(D8M["P]NK -MMF1<47X$L-`H?"Y;4!8;!9`",&:%\;0PY1G8PK)]&BKTUW&^^46BS:LOZEQZF=*8$G@3L*3OJZ.7N\_OVU<2F]^.NW'G($%K9CM@ -M(!F#%7C`!\T@4GIIS9OY??`\"C6:>,_V#W:23^2*^PTS]`.<'KFK7@=X3-'> -M!J'\[5GUZP>+BHALA_*O-+^,(FEK,ZW".AD6^`KM$*:-_KEJ8Z9P;2N-&1;S -M?OI^O!YZO;4*047,?BL$3G)+SM1`XP'K"!/:"(;9AFC?1=RJYGLVBA"F8C -M;JV\0_U*>3!)4Y\86;HV&K,N8P7CA_'CM)XAI..)Z'!N*@`I33RO,,&! -M#8D8FP@I)]A:[N;PEXU%G)W82+1*:+(18)"^3.+LY,#T>:W`'G0$D.=?)AI- -M#D[B5]VQ-DC3/K#R:KP6L:6*A^11.A'/8,-A%,BA]:[?KRZ;YB^8N@#!7!O@ -MRQ_[4S;?7I(Z9ZKD\.9'D)9*;_T'PL=28PGN033IRM;R5F:#XB(ZY=&(86G7 -MQ[I^ZP3P, -MX2$-#,^Z!R\_1T\BG8G)7.D7@MYNUC -M]>HLVZ?'X](A1[QCX&8+B6,EGV"6>().O+)HHC/`N+*>_9Z,L0QEK".3TL:' -M]JD=&=(90A_,V$JP1N0J1OH]-MPQ%2;%"L0Z2B<*[]')KD]B\KYZ -M_N6-?6$.Q#9->XXO(K](_D0!_D8,!I4P\*PA7&'U#'/RYZ?PHI_^%S=#]`6I -MY=PJ0AF6JWA%'2H^%//#&$IQ"B=!,P%P()T:5>F]+>.G"V@YV; -MU4XN.3%JOT-.6UVB%S_-<(;8Z[)9V"J>"1)(VM?7T]:_5-WCNUE*5L3PX$M. -M.]+6*BWTD<-;\?_@NGUM<9H[ZV2;,YM3_]1J`.MG!I<&8^*Z-]M\\T&..T"T?3]6?Q5+F52OP>4T?;6?Z.F62I#>DEUP]\<%$^P -MW(@71B3A4H<&@]+/Y+2[&:C-A7M9.>O>/I@*J'_,:=ALBV<7\A__*XE%AO:Q -M<2QCH#?6N9X#!U\:TM_Z*%'U\"]$?@X3:8I"V3,*J2T#;<(="JG*O3RK"6&6 -M\7_!J`7M[/MP`/?RZ;'DH%_!:C]V)MBF6]#UI;!X;(Q8Z8,?SU=^VTV5I'D. -M<_N\N:,Q9@'IMJ_XJLRF4:)+>N;8\A7R0P*IDIK&G?TI8L/]=/[[J2(N[CAT -M"K";,GE&3TPYM.6QC^B_]B%,-Z7 -M#N+1!^WI2M+4!I/"[@];#/"WX7Z9N3S^/J9S$(18;_D]3E*HV9G4 -MJ*WC!-EN871V;?T%]A0`F?YC5DAMPCEWW0M[5FW!>1ZX?L=7'@5ZP6$=A9)^H] -MF7%1U6'M('\VKV?M@='EEOKF.6V'Q5_&)&NK\6U5Z\9P`R -MTCNVX_F8BE\8YWB,Z*1A?3/%E2#%:[X^_V^[@]YPV$8%#,-5@`,>NX9K7+*) -M<1JC&)6DQ1Q\%<&U3Y$SR;BHKC0@T_VYED@'.!-Q3E7`L$@E'N'9S"VUT& -M/,%`5F$_5Z(V$:A/W`+I84$&GF(WA1YZ[TM5>JXB@%.=11\51-O060^@JMYEK]]FF92Z3 -M$%0]27)@)YDL:BD*;4$<^/'!,0(8T+S7INVY"]*P4'WSA>>2@WBWN\W:*UJ? -M\C4_J65`>)#AD*YOYHNR[]7U0+VY27-[I5CBRT -M6_EHL*ASK?R'2)BX(E:G1`-3:UP0=O:]P-/T+`T>L-M$--C6\D\MQH#OT,(! -MGP+%T<@GG'(]J=I'>'C)-TAOGT<`.F/1BMM="3:51@0]X/JU3YUL?>$,+]&& -MA65*C;Z868@EGA$"0DO%3K(_,3,MG7W5YU6T(PQ4.(8**;WSUQD_B?;4R+,G -MQ8/>0[%EXRG@4HV&]'11.06$_<*IY7O&*8>A;$W+<9^V[<1!H0WN)#6R@=)/ -M\5:.@@R#`_W*/1T=1K448!?E1@MK&E)W_#X12*2'(S/<1?,IRB>4HH)CZ*78.RO>0D"WKY)V^L(_1T%4B@:J^6P' -M@*\@]`WT0!<*<=J*R4>Q&OG[EZT%]7_1>F+M[66MN4%!`M??'JS@K0V&XQUY -M5_QO)RM0@T'[`FQ,)XO92&2$P$V\7^W>F)-*NT1V7'`-WH1!=I5P`F&$8OK3 -M4>),[G+>&I?)XS,V/HDR0%@%#OF=ON(B?VFZ -M&B$&:-^*2X-S-161JRD5#31Q;_Y)[]'9)D$$2 -MW5IR)?JS:,XK*F"#^K'Q&8*:2#RL`HDXB::(&RKZ9IN$!0K@CR6%`^L]M,FJ -M8K!BTD%K3TWT96H\9JE>,5]5PNQFOZEB3_WA0+J!L_@%0?&+;W;O.]1%TT5Q -M$G9N85X)LP?>1,O.]*^;B`O./-&RA#H->*]Z*G(R+91@6E9W"*2ZZ74()_*F -M[&*,(@JOIS+^>P('@,881(BI5/HY]V+L#^9;,DEGF>.3\:6R6]Z'*%?"B/ -MQ$Q-?OF])\9K2.5\H+%9RN2D -MP))[W#@RT/0`*W().969R9[VI?.]Z>@O/WORVP^1C_6#YG\]B>I0011;-GY0 -M`KJ[*.10RH)3+J(,7QKK+9`U47@:VT1Z::R:Y%^Y[38V)+C&K -M#:&?0!T@=J=1SG%D.K&35N/]POOHO\%BR:P4OZ[^JOL4(,8D?W71")4BGT&\ -M5;IRB-_M@\0S4OYUB`IW!=NR+TKJ$=Y9W@FY94[S#(RQETEMDV9J:#U[+KY. -M!RG(-3N11%K#.>T+'F<]8=RW8TW)"XA-ZA?/O\Z)&/,`&'`_&,G+GRG<.AO: -M[RM9&WL,GS=5BSK^$(-B=KHA(M#OWE)AH;,:0-?PVS^?ODSM$'B3]-(&,@_# -ML+N5]W=S`^GF4$I$`,_OV)64,HF"'F6[>..P73I-EHV8QTT!Q)_7DV-Z$6(_>>L+IL$E#HHTC*@2)2JK#>S?PZO*PY`XPSB$HW&T!L!/I -M7^NA",'$$),A[DM!!?A#9=[(1%.I;=)`=P%7/NG(96T&D^QNN,;H"7W,D2H#$\U*QO*SP4'"I>?H(3<\O[;%"\V1,55+BOE)'U_;! -M[(0X^/[TG*'+4:?U;2Z%>827>M:AYAP?7A]P3S28;GD`;60RQ -M(/[HP"9?H/KDF(20CE:HO42R2*Y>V^=7(RC/74YT/7#O;KRF1`'6AJ,V-R47 -MX*L(?*3!I1K\D)<[]90V(6G.<[88.2>`/L9D'Z@[HDF4795V9_O\TUSS4KG# -MBP#Q$&JK4T)8E]PV$(2G:A,821;8?#/OF0N_M8;+/-+H@K9!34RGEQF.8E[_ -M"UIJ?QH+I&>L/4TZ\Y^5U9)H1\N8+^3_7! -M`^FH*^M^AF/[)J!V72=Y,<8?LH4ACY1^I#&Q5''4.PSM,9?ZL?P]*B'%0-\2 -M$J]/^#ZG66^DO;.#>EQ9P@'S\8`]?O"H--C@"5="?WF'BX!D[A@:+^.I<&^D -M3.A+^PU#N[D5"K?LIDI.55-/`V!D#Z/&7$ZF*6$H\V<"5;[^F:/7/.00"-WF -M\XXY]4TX\6=&3U3!(5*^B=WRJQ#ZB@&25UQ=<,;M;-BXO5$6^1N6>0I*"&GP -M%[*%7\KA#@30R-B)E!Z\XR:C=Q_RV'ZP3/2)6=4$;_Y&(&UP8"BL4'@'ME.,5M,_AE]SGG+`J^5=B+K\I -M2=1XUET5*IUG4`V'$@E,)MV/[`_-RJQ2R$76M$-0\>AD'5#%@._WY`'?Z)"' -MC]?R)67I10$D1:WQR;2E"U5$&*,1(Y1CW\&[W]O$B\) -M22M>)FN(4_3;^/2M]\C"A#.9X?^00"@F]MIP%)\EPA5.=Z]WTT'YAE?OBT=N -M",0E?3=JF`VU*@H+(`5P0CN)VQL-QHK&\"DW<*S._LH)GBP9Y'`;=@'R$L@I -M,@!FH4"8M;>0+)>*Y?+S=@UD#(6;''\)7&,K%E"T-8Y&;[%_*P4-G%-[*TF? -M/(ZJ?)]5P76M/VZ3$%XL3)\VQIH#;#0P4T6\E*!A9,@0T,F(*62Z_;/8KW\Q -M[7.L7>NQ&IV6<9$[MJ3;@"6?;513=U,WVO<#E7@L7@TY2ETX\4"(FS8B5G<] -M.>O(N>!/90A.F02XT=\,43'/_;=YN:V?\FDU3Q0BTPQ'0:>/M861E"VD,CN=Z^< -M(VD/OO+(VQ+%X<^/+C(Z$?[&Q%5RAHB[M,L%IY&LJ^CK*HX5K"CNXYP.YJMO -MSYM<\!1D7P_F;]F080ITR9H^,^SZZL1-H -M-:,3WNYV0./W1KV:#L)-))MMU)ZM7KW83DF=KS=^9;%ES=EC9H744GS;FK/X -M^O$J?R038:/[[(F4OUY]%@^QHF;TW`S\.R-U^O(%&#:O@:^:*3H_(SW!>C9% -M]+'/R@/LQE<(H(?QPL::J"IYP)ZEY?_6Z#YQ+-<;:$CACFD9E&]T9)/R-(F! -MY5J`'E[7L:&9!TK!+8H:/BLT`]HM%#A+Z'S4VTK,'_W"J8H<`A/C)!(5F)IV -M*,KMM\)->UCH3_74K5%2:?C%G3"^"!1)V"M.-<3EM\Z.Q8)W><\*ADG]9I,7 -M6;$0D)A+*XQZ$Y9^E>X630RH4LX6,FX-YTVE!A>,!KOP_?B8Z+?\ZQK'JM"3 -M!1?>QN5B=(/J^1]E4Z\#/3*>!JI=(R1RV90,W-K7T5#(I:9":?"ZE]NH386.I.&$!,VTMZPZ5 -M$/FZ7SZAZJ/V8/)(*>RB%I,A"$6W_+G>J]Y;)%3DQA>1XL3/!!Q#?_N,1FG> -M=J6$<,SCPFZL6R0;,H60]J@=MVL',S?.&K-S%=9@T;@10+NL?^ILESOSR9D1 -M\AEO[?=S;`2O2O[U7V\4IJI-KFT?88(RY[/DV\VQH$7>M(]J'W8 -M#!I]48T!,"GX2AS!BC@E&W)!?HJD0)1AALC'*GN9@4K8UCP,UJ>4Q2NX5;?X+9';/B'D"&ULT@;G=)4II[8UK],+@LZ=:2G9P4UU4R( -M'0*IX]GZV-)?G?'F)"YVO2&6ZSC$6(MAE))0J_I8"8LYW4HV+6ZC3QA_`P7` -M>6J,OH)[B3\>&.*UV;H#65R$;L=8#^(AF\UU)?*[>H+V);M(@'A,J%SH0WBX -MKV?NU'CS-&2[6`>]D)\UAF4[>7-89A!^F_/'Q_6V).B1U1=, -MWK#FBP3'G1/5.9N8P"[2K%EPS3=\6>Q-:)9VN*"U1V$J!.?X1USBWT>[KEJP -M\+B>(0Z%OW_]'=-[$7?+<.B:7/;[TSV!>LG-..N)M=IB._FO8 -M!TV.=H"R")<-;)QR;2?8?1#2QR2H_`%;;"![!ZL$5;`J&#W;Q6.=N;&4I[(? -MJOK?N`G^A]VJDY@ID\6N^\_"UT]C;$__R;'WSYA20)Y!5<.&N:#V^3ODWG>; -M0JI_G;Z:%':QPA8/!E97KG+IA%WEKDQ%U5T0XX".U%)XWNQ]QPK#EI!]0S*8 -M;RU-/4M/P&381HD#%9#O:;69!Z/I+W@M5'6.(GI$*SOX[2E:WJ/L+\'R.>"T -M7%KAC\N76*]0WDOL>7M"F&LJ5^(`D],14+[M87:=:ZH;/SV*K]`6""%V_%=@ -ML3=W*^),`_1=AICAV/.0RK6&ZV`C4H%WT'?-/0XFA@;XH2KRGJ-EEPY1)V@F -M!:4.[V,_-'X0R?0I4WLS&??+^=G+JP$2;^7F-7&@[D;4M8)\=U3+H="JP5&G -MK#3?/0GH\$"?XKRJ>I@!OU/RY(4F*<"F)9,\9(?*8QNIX@K+`8'QEKBO&F7* -M@X-#YWLQR55G$5@&,,WBSK830T*,.#QJ(>D_I!<>+FFV?EB_1D"(#B)6''<& -M,T8,ENI'#\*9Z$XJ*FR[:ELL>MP@-#Y;U=(0G74%']/.HV?99+#S'23-M.WA -M=N"=P&:Y]&_[H!O@M#=VG*O\O'O,;QL08WON@&JZ-NP:%E&_ATNG^FT!+.[J -ML(8)1I0H,P==/T*'(=XTA:#F(N"(F!5J>*2IWWP',T=HA5C`(:`,]F?9@-(`I!WD9FG$9 -M6_V:BCR^M1Z]'-PG@>%!8O,?[UCM!9;%W[E*R[5ET'&P2=(Z.AC>1#G^[G>T -M=Y(I07/!TTUB<*X&,W1\[O?VG_!9UY>K0#394$*6!"07]X -M,?2-FTG8T_B3SK[+&6Z"_?!41GJ^:G1?[A*Q#).TEZ$J?U7@XW194<:T3=G# -M,[PG.E="#`8UD"57=K2,\*$#>%T=HDWQO&*2\I.GQ_SP5KN?E+8.&H`$"2>Y -M@6?Q3-9JNJ[6$F?9N@@8^H -M-[4\V\L2Y1]A&JG/+$\MA;ODV-:`D^E-B3U\L0Q]&[O.(4.P;QJ[XL6UX)_8 -M`K#RJSZ9^)IB4>?>-BQ\X2_*!!]\9^H[V`;`_%['XRA-H9M<2Y[4`.9P?4^/ -MX3`K=F*]Z4()V"@`[!7!OXVO6]Z'.%=.+W-$T+7`[I-I>2P2@V.C.Q8:D,KKW%^\!_9`,YUG-BRS7\>C+/WKBV,8!$YV[H:R1 -MV?TA.0;)`3(T=&HM0&';Q0'BZ7W'#Q)'C"+'I"8<:!>I:S\9D)AE7\XZJXH- -MFEN]9-ZHR&&>^Z,'IHY>Y]R![V('L#RIYO;[/X:8V*ISZ]3=R(QJ*8[(B"=: -MII&1VB%=^(1,3$=Y_K48]MWRM5ZH/`0')[;+F`#R`PH27A&+0YV?K,./!MHX -M.)N*06[BA$:1ICPJZC-P%XJV3`D%CH('/\).VPLQP*(=[/^WWO\J&H&0XY_E -MDOY1D'9J=)1317M$1BZ]WGZ:VN]XHP9L\>)!Q>=!:6\HP5?623,8$H]MT]7< -MCOB>K9P9M35M+<`NB&VSC?MW-ED5="[;#I'V%GNRTY#Q3L0*5:A\]SK?+LMQI0YW:_][B#%2\LH*NJ/+&'_1>XD4G5`A.' -MBUSOC-#7HM,?;RW2M"MLHO]GK"?X8;J*'`+#-N74K%UL?D"S6%+3M;I55OT$ -M'SCA.TM>%8]O6J\QD)]B\^1>;9N^MRAK&&:J*[*VCGA4X[OS]!&^]0DNV6*4R-4:8 -M@X2A1TYD"(D%[>=9#^9_*0M#*R%%F7-^6LSVUD4D1CEKH%Y!XP%,H\E>F58:B&:E-%FSVNA3,-*"/38F^R7 -MYE!,'A,C@MJFVU\W,"QY\L)>8S-N6\^.,SN0@,83=5S64V<&S^FH%;\:*)!+ -M2MQ4C(O8N@N1L$VK;6HB8T^Q*>[=.4J,>%@E3;68?@\;V -M*I1K^167"'#K,TD*3HH^3T3H;7'U0!'UBH?Y"*K2[%BO5"]F5)&ODK9G^*"2';[':-> -M&2SKH+#=93[0711[(0JUN+'7?$,(QM)N`[OR_>4>[A62JRS=`WNO2\9BOJ,_ -MLI^//]_=M^!_GQ^N^S22Z)HRZ[F2!/5O?.-[FX[Y$O -M-:]7TZ-!&+A#K-5-8(F7QES0Q=P-:7&U:'?>5?U/RTAP-;C#B!EM[LLZNT\9:+[7IR5!T>'C#W0]X)W$^2Q`6LHGD$&=#_^;&4& -ME3`BOFR$"A^`MQY)#:R8<,=)X6&`<5*AM(_NY`;92N3^")B-[^>Y4BN,2@(_RQT?!81(NX6 -M?%A&V:);G%&A>PCV2J1MB!WU$:>DBFV`H_\2:[>!1"P8OX"]U*N&:\>$2@'V!N#&! -MM)::[#&Q.YF5X[[;QFK9TF]JJTA(XG$O6/!5/OR-]7G%-D<>E=@[@QW -M*<:)"H.LM_CCHL/,JQ(0>\GWM6(3)GM`#%"@6=0=5!@EI9](@HV5].GN=;[X -M,WM;J0@C#G1-DEH8=3^_DF'E0\!![1YQ>BNU!,]O<9QQ8B%5@0KORPD;$QN` -MD^5%<_=(YM56M^4!1D/3?NL"'E[#ZSXO]2(Q9[(#9UYFGR9U?FZ*YU1:FL!: -M,"9D+D'F'ZI5A.@C6.E%0:HG\`PCS%;%3;F[%77^FY?GY']MV"$(K^)<\_BT -M>I)"8O;)+[F-:J+]27RIZ;_L;3B4V'-S_J0=C6/]>G\R]%89?M.=LUG)=.\, -MP6%MR]RQ8RWXO!-M6Y4$8/,K7)E`NAD\`[#LZL`LM=>^":?1 -M9Q0(:D")Q=Q>@E(M8`A9N[.U_@>S+2JU)DN.=:@$@ENJG"1ZZG-NKURAK"4SU#C9 -M__M&;L>(D)4%O0-%`&+O%M/@[8;&"!!K40<1<%9GT9^^D/M7:A^$N:-H^_A" -M"YJY"KXX,<;"I1V*8)J;K-4LNE,F-VE?LX'(J1 -ML7MI+9-P9>HMZLZ19+(L3KJ^6\*#B(SV;.NF$XH@EZ%(H7!ELH#.U+T@QEY_ -M.#1JAM@B)G>-Q)N.8/*'VGL^,7=^HL,=\X;*#.#?#E[KFSM8B"B/_)ZI*L;[ -M*K##!Q;IT3/POF\8Q*OLH9.QZ!;0(2;]6`89FRF&7,6W11Q2YA$7/34D)I#=%KK -M0$VU^;X21(_/W\?Z/R<#K43L1G2*;-3/<@7K\J_.2\@)4"E=_AV2\+%W"[+" -M`GQI.PY:609M?-=X(EE7^B^*SZT+&CA3^D4>-H3R-\0+"+;/YIJG -M@+`V1PWR(%=8@[S:VL!JN2:RNNYW#:-;BZ@H-62MZDW@J.P@1:LL0[;>=$YK -MI!6T))+<^="R-MAEJ['+'VCD.+CGDA7)544B=^YG42TUM$D2>IJ3M)I414HD -MJ'TIMU^4X5:DRUF"E`I,HPED[:0J,HJW\,[]ZWK$=;$NG7?RU3IO(9`JEP8[VP.A6@>*EV&;:0I -M>86_5XX]T8!:.`^6FZRFFP.6"N43!F6FL+K[L#PY9!77F7)%7`X5#KG`22+DYC.BG_8K=G'% -M1:]0P;L'AM)O]>#96.D/E\<.)@:B/A`$XETP-_QM\58DS0-,.C1`CVS4%N2>CFK7BY@.1L`T0K5L.EY@( -MWA$[+!D/7`TZC#1S#JVQ5+2+PR4J>G"N(-IFM'SK_*&#$EV%??E(AZ^1,?*8 -M93(C!'BS_W()D00_*9`?\COO"ZG`&&W9MPB]ESNB5L*U93=XE$=:(Q_`'IM+ -MV4!V2@O*DE:E[/4[K\F`PADQK->#'7A\815NMWF#?B-TUP*#[CHXP'^'2$>ODTI'$L)_ -MJAH[8$_0%8-B#B:.'%_*7I)?;D,QZ9X4;4%@%IITXM"G6GX!]X8$\%"5(M4@ -M,*^$5AR-@7@N9*+2MR=V("KO%GFH]D0M4X:>!-1;6+_W,7E_.KGFGR6,U=QA -M#&WF1N7"\PK3XJJDJ?4HF>$.3;>Y3C&)-.(@5!#A<0E+`K -M%]^E\M<@$ -M-;TT>#HQ05[;[:DO-Z.`*6'3[]SG3)?VY/,'SHJ]%Z^T;'%3$2RXNMEPNAB) -MDS!WO+?+798J\+5U`Z#)`7[&>`<5H; -M6%306Z)>AKQCO#\.Z^9B,?*LEZV`]])'93JD%VLW:F`QT![EWLPH5;>)/&7> -M26-(L$4YM^NI8G^?,(9+]JVM7V?_>4"OD@,,9:FE`>^7N"?ZZ9#3F@^F__!C -MT+>[,_S[3!O2I)9'F][61DV=,:DC8L>T,"B+XN!Y>CR?UK!M5-HN4\L#^#?B` -M;H@&F]V#AUJHL\5!"CDS$C=4O1*9-O#H0@N$='YD)^5U9->MK=EE6AB:"?PS -MUG`SG*%[]$($L!,::6A0*AFC.]^?S[)LR]([ -MHR6M>E9RUP!C[S[BAM2L>=@Z-M_38\K\%6':S2CE[?CVQ4[YT0$,]*3E1E6I -MZ3$M_--! -M5VRB4`<=7?L!27P9W,DFQFYS&+*[;"D#D,DG?02$9"NJ+F]Z8=:5FCF3-H3K -MI;*HZLP_84?@<(.2'#:*P(6#4D!M/;WV!LI.096Y8V( -MH(4Z8MY2#4_CLF+"O;<5;IFW3FC+]+^4O-)U>4C!SPU!Y3-1=N]68<)^5Q&J -M1&M*9C5O,Q,,X2B(O8V^VFU8S>G-;$E+\:*5JYQ%W!Z-.C9>J+]?<]=TNF?_ -MP4A^WC?_;'&V)-@`T3#UY>9BPISBAU[R]-[VC5V&!5SGJH<1E?V,%W1Y2I`T -M;XG\F=7W1PK)MYIH4YNL3'UM'XB]%JJ@>18)ZK5ZPI4J\4_]-[R7A4B60?X# -MXJ&T5L!W"K3TS]@@ST3\\+`(>P-]@KPZSER6H[SCT*.BCQT0MIXXKH&KB%8@ -MHR'$4=PX[0?7+AZ>(Q5CH>5)XWCO\$!0=\\86DP/H#3J;''[\]371T;YPY24 -M8ZXM0+FQ:7_6O;P<4!_(255QL:-"`QX,/!`:&XD.B@FE\XF.LQ`O#5@LWZJYJ0R -M0-6D^ALW^#D.F6@R#=ZC6W5HPJ=/&G$7D%400T8LLF8 -M7!4+@:Q;M'J*\YZ!#H$*GR6J^IBL')`6)IZ,L4Q)BH4?YA6>_8-WB5-'>?`= -M^^F1;+0'"^\FE22/4&1]3CHW&Z8M/1/B]@+7?()$5:T4N;( -MN+V6^A;$*Q](VIB[Q0$<9=Q$JE?^=0_DMHA9=^"FEX&.HV\TE%&4<$)Y.W#R -MNHT_-O)6ED2/!)'U":HQM&Z0EK;GC%Z6=;#DKPRAX1W;:`"^/\37A7>JNCCF -M3HO.-:O!9&9/=;8KNLQ):F#(U!(R"3#^P_Y]7(_#$\`1E;X+-@Y`[=N@)YR6 -M21?@+I0V?WYQLBM=#_^11%T.IM.W?9A`J#G]X`,:&)&C*>:^'[M`E(-9AVR= -M$`K93Y:3S`[6E%O?G#.>,TE/*&T*U,TOE[V#<\CI73;NG65LA$_UE/5-7(8? -M[Y;1.^$[_:=WU^=QBH0E5%*(SOSFF)G()X]M458$G%:;!^ -M&L:B6V>X89#_,S8JSE6/4C)4[.E8)C%5S/!=L*&(V?MEL_Q*<-`L'2Y/+4<# -MBL*!6^WQ]9-!/NPM?_9YC<2*NI/'*<90V^]>,>7VG%*I#6$:2:@$]3YK_ZAE -MBT#/?&6#'IM>X#_LG(]/^'S/:/.[MJU$=(`^F^73%V8A/FFTK&`B#)P3/$VA -MC7`2.#S46A`Q`8!HD4<&G/H)BI,%4%?7$9W1@'2VE;)%B2H'<^]/>B9":SNG -M823%^>+-TX6K<-.?YZ]9"1U3]EQ9\Q-5,2V`^5.3P;\ZF:(^JS83"7.B["=% -M5RFB9HN%Y49#O/LLX4)5P<.>_,7:8V/-I^]AUV372?W1_7X;:!A.4-68[+?R -M<&??^R,XA&K-6SEIO8?6!?PX^.ET%>,"32]H7>`O;-@E0"O*WX0!D0(>IG`P -M^EK9.&ON8E"+6EM<&,OA*J=2VUV--5SNXHC+!SS954?1'JO<%EV783:ZNM2- -M+]'4R900^ -M1Z#==`D%\0VXZ>K!\_Z1AV5W]L_)%TF`$GBYIP00S9V]7#^'5I9NL_W$28L? -MK)-_=@8_8[3QF;'D.\)2L9L4]]YQM4-#!$,&@Z%$FV$+VV76M_2T]@/#;]&;Q$4EBSREYUQBI(1:%*U#,*7(5E,0(B2+]3U\G -MZMJ[R>Y^-K^`4S2_Y^&[Q-X6@!XHCF>L%#AJ&UD)K)YOIG62SD2O(+Z9_AB] -M6NR.[$13XMX*DDUPVCQH[?U[F.DXZCG:EE9M">U).&9Y[I@QJCH[S:H2-V_# -MAF7A+PM4J2!?SZR?(!&M(TW!;FTJ%5#2&30_I&-;PJS8UAA7\":`2V/A:T`] -M%]R73;^=FZXDAOXF&^L831J1&5C:K--YX7E'3OV"XSC\N(1;_R:EETMTSV,< -MYLF5F4>P!N90CWGD*74==K6813%=@"9O-(1!V&JD;G^C7`.JZ^21:<*62NB> -MV^]PG4D60LZ2[_1ZR80""E5`SZQ04>X^/V,I*]6=&JNE2#QI$Q+RE`16:CCX=!UD)L -MYM3]*.S@"ZA4Y`Y4W+4D]5(I*RQ:U/6,,B`VV#R.9AD";Y)$WFZ9-D,=K=@C -M9>*HP9TNAE05C=:[184QM+1O$FC?W>0Y[PRQ`PSC;$1OZOU282,J"JD."D>5G*?'` -MZ.M8?0$+'>;]M*8KO:*T"/@D(Z!'2MYV??#X/U,O>=@7,DYTL"QXGSU^]JUTP2(6JP -M%/ZXQ3P2D)6\H)5^1V4PYY.U)[E_T>\;M'G#A2W*9&NZ1*YZE+I^7$[*/3PX"AZ9J(A+U[,L -MSUY,R8[UBX8_&RD0R8HC4\[*D$4=+K"\QBXRD42E=G*64#V>!6V&1%:P@UUL -M6OV%9PCS>1MAT&+E!S_@U/@)+@Y;[V(=9F7$&?ZZ!-(7A64NS*CY%-_Q45-J -MPB9/XL>UJ"M1ETQX+:`\LXM!+5L$ABU%EC_*89U9"O_]TJ`N2H4G@.=+Y8BQ -MG9,)[I&<$-MVFNK5Y@*.,*J)C;>%$..=TY+9"WC@52U6M!4S-22B"N?T[030N?B&-N\-=`G`2) -MO*>QE(W>>=7>&"E)N0)EW9%7;:X4^=H#JZ2D7 -MV_'O[4+ZQ[@C0BPFMRC,+;6%=1=\2.>N(ITR)D5Q$70U5"F\G1\#Y51QG\N6 -MGT3U2:,Y`W'T32O"6T,,@&J'-FF.(VK588IQD^IJ-SVB?%*4SA677U+.>6Y,'%QY:N,XE1 -M`:;NV'OX&!T8/WV$'W\W0/-N-+BR=C3;8<7];:TE8D*Y*_%; -M^U<84]FM&"!"%*H&&1?$.X=&F`.&`HZVX!HA,LO(,O%Y,:219K&0=\3D`!)$ -M#>[(6M`X+_AC`H,"0VG4,%-IL&0S.BW@?TQ!9FI!K -M=L*AQF/5_QO4PAJ[R#T9]_>LKTBFM.$N590,'(="EV]@[&]&[C`4_:^TV/-W>B,K>VS0(9>U@"\JK&>`?TR";67@D"JCO8$% -M7%!'JH>_^S*YRTLIDSKU0-BU"OM9K>P6ALBKJ,(T)1\/.9$)V#XAH?:'^"6X -MA4`SX,1XRBG"-BS!3]FW[\^IT`Q(`$9=@)+45,,?(S:6(D$]C"&1R#\1*`@6 -MV)&0S(Z_=4:M993$5]"R,RO3MU!5X1-IC=C[O!30+X\LR -MF`W056QZ3L5*<`"N!E`.1"D54(U5JC*#:`?-A?*S._!@ -M9J`/#:_$7U-X"7($T+3:4=DZ<]+7.F'KDM&VO!N2&S -M@CQ?UIN]?Q&*WI8\3,,KQ^KFNA+3Q<$ZC+I%,\\RB^AQ]FLL>J#=O? -M+N-R8CZM)K:?U]L:>%O*S64FHK#7ZB4!B"W@,-/8(MX8Y.F9O%NM'QFLPZ#-IEJUV$$>W`9-><:> -ME!NJ>'CLQ&.YDA?OZ?C@WA@N)L%?SDO-[ZQ1H@)2IY#(C<>?[-R;"U"%J."I -MUX&&>-Q)(@8L/3>H'D00ZFUW6&%(:'*@<`W"=2'$;VLC!54[9_\FZ9$90(ATO#I;/!T&-Z<5((G1?522D+CCLKV4:5AY9OEVG -ME).FBE2`4RE%-S_V[PG63(OJ]+`Y0WN&^8FFHV-))_M#,]QH0^14BK2PCEMF -M#R9FTZN7/&,3A*(T+?1%1>QC#8\FK7GL#:HG]I2,6``%]+!U*_03*AJC),PK -M.%=Y:PW"[?,GQ'/[!6F"@W<#FT([4<+`TH"DZPJVOP2C@1V$T4[(^+Z<=U>P -MD-,W*/CYD?WWSZMJ^=0CAFXOG+$UD1(&:*OU5#EH6N92:_)]\&\=E/NS"W -MN.O/:;'^R+*B1V\X";7G/J^_YE))7B0^,$/4V8H(6]=G'1'EW#W9\53!&ISW -MG461H#4/N0QG#OY?[L+\`B*H23%`K;YTQY#A5DP&#_W':"APA-V\%F\^K$8P[EU,1ZR0>"D5E9GA>N/-Q:R3'25>.)-C9IQSMJH -MEF*KH_[?AI[($M_Q%!5O$#4P`UU/O:3GSS6T$O1CMO*'@5$>.^FX0SW_3]^Y+< -M[Z%W1H.*[>4R8%1#N^5HLPHV0&1'ANP&/B?K,:X;Z"]K!S',\4=QYG!DJZ(T -M6`UDE\IL'E@LLL>#9RQIDY[RGYR9(L.@[OF+`-]\4:U!\V>X-P06\D66@0MB -M5]'].2@R@]OS6RA7HK7DX+]P+M@EDZPT_PV%>4V$NI=V!$(W+_C+HO`/1>#N -M%*D'M]!50&`5^1`;S@)`&R4T\Y)?;E*\"UN5#0V\,P`G<<2B<)M[HV-N+%!Z -MP8LH@5^J9P]0?;UZCS>1FR;9^9HN6%)$Q_46 -MKJ5?#=<,M+-[&A)(H_&\(>%O-AJJ+@##KVD*,));E8S=H.Z6R07:G9SP89<&:P7N,?#]!D/1V"]Y&*J(O!!=C`AS2JIC85]%3X7&5BQ,;R` -M%([R!X4/F^&Z:@`E@O93\EO>D*WQN9&4@,@MWR+6O'A>.\(-B/F"X#*N3[F) -MNDRGZ0%%H\2]5IU,GVGA"SB;B\@&V3[;DA,IR"Q1&GARMQ@9^@<(L[61;JG6)?;?$HG3&>(Y*Z='$..*Q10%IPJB6./7CK0_$:%2$:W69!U,;^3COT3KXJ6]`FD_1_UCIQ,((_/[5 -M,MA!7:+(-MYMEW6&H-[%Y4L/.3+3I-\+IF&.QJG8XOTI2AJ#2H#C3@3O)W8^ -MV9L[;#73D[NN]E9CL;16@6*VK_*7X!!Q1$&2"-CN17 -M143+.EWRN]`L"R*RP-H4HZ#R9@_6%'Q1\I7T6X6%A'D -M5QS>3J?&]Q8I=P6I[7N]0<\'_C5+=8&D`)PK3O;:G(+S3+I0V&_Y&SG'W_S5 -M%_'-?D>*'F2=%J`X`^8F8ZV"N&D#*(H7+E65L -MO[>1`]TD/";V9>^UTO=],O?38H<"LS-%B=; -M'EIN:T$MVZ1U^WAY=$-^K,!UAFNN`-*MU3@M=B -M]U9+UO&E4.H4I(7M).I@3/G$&%;/[LYH5M&^JYD4>KFO;I7"GMPQ&O3C;+-D -MF&K;/+SYH.L;.YBP)$.3@#SN`"'0ZI^,6+B-'0?=9F$H)-[WLDKIH6)8T&)C -M2,+"8)CS]>!EWYD"EY#\Z_U_93P)(!#Q>7-HX87IJH&*DEL=0Z"$Q/^.['*; -M41RVB(Q2/O:I>2RRZ0H6;/;)&U\9?3=U]J_7)J@ -M=?NDEGQIL"DKD[@6-(L2`E^*]:VCSTG_N?<%;KEN6O$]'PJ=7U5GW=II2P?$ -ME62#C?-8?:-1>59SSQYWI!P^'6%"A@=;FY#NH-C5Y@)9?NV4`#FP;)--7"2@ -M*G`QDR7"D>9I.;-)`L0*>>!H4-.2?ST*0OD@/Q;FB1>X6`0MB-9JTZ$QJ?59 -M*N^J_9=XI4A:V8O^8.:GGN=->AD,C^7P\=HM!FA93X^;D?\^4:D^5P3TRTM4 -M:26A!&W"!)[<\'%1%!AN5ZL`C'YNZ6H)(]M\+`S7@"5BY.3=^XJ]XWP#E:/K -MW0-;5?)`NQA/*C+KJ<+6R*5X>_,5J*^+,D%O^R1+0,H#FKX.15_)\`\:5NV] -M$,IZ@I[.8VYZ\XI"\JG]YDZ3]/8[2PY0Y#>\I?!]GC"E)_ -M-?MD8IBR&G]KJIMD;KBM[G#K;-M2PVJ!&F;*<]8V3Y5,IU60!)Z@:3R4;*3M -M'(TJA*#]"T:F1"8O[-A'R#X9%AC*1_#S[I%38DF/&#I,:)EVM<1'WK[R"4<( -MCCOEU?\VDDJ#8V@%,:E3$&"!#!_A[OA<`76R=%!$W(M<2#AK<,1DG$>9"I9S -ME5TG>[-EHQ$_AI"*P^:`417/ARKDRM_9FDK?K<%@*+8B1G50VY/&SB%OI<&> -MHES)W".*O:$[`MCDZ;I&7 -M(8-D<7[D,3O6>EP>G#N$\+K-`WGT0S6+MFWQJA8?([[:?2UV""G5C2TF^EKX -M?J^DYEC@9A7&PD)?\%[(6@$D0*W(V76A^%OMN^V_PN6RQ1R."V,82VW96W"U -M&Q;PN"NI#'?T')$$E,@-25_/_5,^R$IJ4YRF!THX7ZULR%$PGQ^*@PN77J/H -MF&GH*1%8Y-/Y((Z`;S,"F63W+;>L+%/,E!]2=GN2)?+7%WJ"J.I5>01H8HFI -MKDR_SI@+,55[UXF`?\%:5)$VRV\[D"^E!#=M,LI1%+NPLJ[XO<;2$=;5^5@#Z=/)K -M%=,"8#J.J\O0S,XNVXH#8VZU/1H/!_VY=BFWT&]H\LSF)LR?U<:B;=71LXS -MYF;VO3F4>A\(C0?>(2H+DX0<1[T.G0/B1GJ".3LE[?_\[\%7#>*/*N\"E%?9 -M.O]4HYS]/+[X30`?)OTY!:<"_V1F7<::H.\K_?"ZKC134T?X<>G)%_XT8KG< -M@:U;$]Q[O:X*3=I>;<# -M)LJ@#$(=@7F'KH*G]I%LL8BGJ1Z'54Q0E:S@AN?9N"NY_4VHQ]*-WEVD-(]Z -M']TAI>O/]"B`%/4OAZ`U`AQ0WN`#J^#Y;_\&"%HY%RBTZ/?05S/4HAAJM?BB -MX.GP^>/A@[@4JL!V+7!)&W%1!]'FCWY5M2:"6=Z_6[U0PCM^##*`[X9#XBR[ -M]OJ\Y+A;>YY6$+OV!\_-I-1`?!/5J(S9IUW<1S;O(??(Q>"I2`W4QE5JI>IS -MX&">)'\,&[SN12C^[CE!B]*+IAJ^6;GA^:*.TT>T!F9MM8R1BTZ[^'`!>5Y[ -M=[9;>NK#M?V=%X\]A2)"6W@J")YG!?>0-U#!3"ZC&%R@QRL%UFPB7#V-2+U` -MJ^1=_K.MZ"+;1-MT[?4@J??-3#EX]?W+?-V2LTY`!("$#S -M*&DFK6YB%T_<+F[1!V;3-Q(I+KKHXW -M`Q6UC-L,0+6J%%4__(!(S7X5`,S)&1/\!(@A4@^_XX#(6#H%C3K8J0P_QLC* -M;_H<'?"H(3RW2+A@\8#@@.RALO8H'%2U"9!T&-G7<;VPRC9S9B^@:*S.2(LD -M*+LKATZFW;9JN.`1_X-SCE,"CE6L"N"J!ZC%%QE@!OD``VPM_`MW)2W'/+`M -MR%@W6CO=.JQC7TR$H\.9P?+YWN@.EEAIH`!)2)WP2[I7>QWZCQTN8],?V.>L -MKVH+3.4)W8Y21UHON3SZ;5PE)[]55W;SJL7YMOVS2)X_?#B2]"0F!9#M61+\ -M#Y3TA16FX4B3E7F(UFJ`B(0@2XK/10%9K!KI>0+OR_BW8TY?K7__S>UV@"M? -M#?DB4=_Z=PB^BW,PEYK2]K1BTI]GI@./RY-$&WJ<77'GAI[2&DT_6D.)L^6#4%! -M6PN#(!V24P\%LX==,%;>N8QQ4R86J*V@=AJ343LT96T>E2/GV#)T6U5'$V,9 -M3JN9<2MKLLJD6=)8W-?^;5;S!FTZ;KP[%E&8CX'F_]7C\]BP3/%W!MI).A2% -M:;%:=)`5TFW)F@13WW!&`WH`L&],?O86KX]'#V2C;4@B?F'2)[0*FH4$X0IA6KW%+QH$T$%^"%DR9?U.U]:C'I[W>2@C -M1JW_SW*@E+6@UA;Y7MKL4R2-;1^$PM4AJ5\-56; -M2Z7]?\-^8\6=%@1;A7O!OJ=;7R+C-#5K$^4#PL#OF^2;L]2?XLY4\PED/PZ+ -M=M>WC!OI9@K3JF&&:ST%1_R+R#`W71*OO"_MRM.%R]O"+_<7,F"C%(;E43<= -M-'QEQX,JK/7*971\4.WAVW`C]0@T!T,8Y:%B[ -MC\[QN8(&V4U+.O*-03?I$(5LL[5H/C\EY&S*"WBO=R5W;@$A4\+4%=S8I=P] -M$%R)>.[^JC5V/^_'AU^+`1>!N]U/V<6IL4!.M.6*"^$8`L;?7E9Z.D12SZQ\ -M`73:=)7-"9ZN2!\%EF`)5N-_\=/Z%^?(&@9+(?:[X>5*FD -M2Z/OHN:!-"J'PF_T\'%IQJ.B]_9KP8L]T^&XV1YU<)7&!I@6=,A`T[L9[!HY -MFC:Q`LB[Z,!6=+P7>N4+42GKT'`X^Y!Z9B;MLXVA>^NB#@'G1*%L-FS,B>&H -M*K![>Q"A)"'E7H"X5\](6[]K,Y!=T;BGU<8]]6HQ[I*E%:9=+>TB9H>V`/N6 -M/0K55'F;&"=6K$2IS3#Y+OYC%V*H#MN!>)62BW!M.+^:T@'Z\9==BS>=4G1M -M3SVC-O(*&FDBE=M9.^O1IM6K#,0G,[E"S5H!"%8[!_H+])ZF+>AW4RGW6'C( -M?2':SNSS,\&[#.B8BB@: -MXH:]#A49\Y-XK9V&,%UC3"$W)@;5OBS%_R5D<>*.R&#R'`W0)@8+-,#.@^K7 -M)N%);U!"I*(!)I8,&ST:U/H"P\;N6,%HW68H,9"^DB]-F_3*%^%BYHP8^->/ -MAS9U[),W5`(P0_05+9?3%&D`I%\-\4Y*AI]MU/@'''1,Q_)R^P85799:.C8PL(I!W=(M2%,J,/8WJJS.8@<[ADJ?Q;>]'1%3R4?F) -M+8LNI)5Y$O=-_S39OQ-F4!OZA4G79-]<1EM6G1FF$#&.4[HMO!:'I5+@H!48)\#]4;"%8_L%T/L/3U.2(RS\LC/+ -MJ0;I'3KO+_>M>(@/.PN2WA-F)E._J3(M*:1P$"(_TN,D&`*(;,R)(/2!,)CQ -M6W#2I'&`?4-=YQY1P\UUDRID!ES%]J(1H3X&,=1T;3396C5BA)TT,T?ZI9"]#&GQR00PP"M''`NU3%\ -M1*D*7MXWYL/1*NYHL@"ZK\A=H%-_'M!_?@C-TWR+PE?L-TN161;<$N8?+_<- -M4A$J,U;FC22T,2DOS -M5PR$UMY3^2ZO))5A."6#EB&F2_6Q)(R@+C.W3MLSA<8I1%6*%*"4W0M3AJM? -MHE):.J>%`XM/S-UZK>]&@5ZZ;@#;+!];U,\2#DMZ1@A(S+;&"8PI.R*.<<=NL/O) -M?U!^V_R!\G%NPMCJ0^HI:]WJQ:YDPW!,Y\(U#"@YLXLGJ81[;)G9=8#*#3E/:D>0>!F>R& -M*5YG?,35:J1\\M%UM@+B!EUP;QBPAK2@.@O'*)S/PO=:.]#DMK2AT30J?-LA -M,D;X#/&M5,2)":U^34G4*>R$2G^L^A]DP.'V]E1(5<:"M7PP._@"9E5:S&6( -MG=^M:3^7T_7/3@P`5O";W]>!\#`67)QX\0\&7?11F+-T'F'E<^,_.\#G]62V -M;E.QOT_4U'/)#UL3Z&!V[>[L?.EWQ)J&)&8'(MS=<+=[J="QG:`P`Z7GBZ*D -M[7PD>`@]SH.98--;*-R"?T87A`?"P+7L(P#[[19`>7B\!8`)PNG -MY(M-'_#,,%V9.(+0F6;.^G>WMF -M&)(W(/N'2!FM=5GZ[>,QSKN0M*K`(P6%#/4BCJL]PK;QEUO%M5%PK<"XH=,( -M@AY=^/2;3`%XLQHN?=K5;8;T+(LHRLS)QQ0B_:=HBX9S'RM$M`AG;171?F'K -M>!1I^PX\K,R.*"_7'/$5P@N%`B+M/8PM:'79>_,VQ);K=:)4_OOEU1/)()32 -M?6)$`?:X@AA2.(DD^)-XT*=<4FTKC$/SZ84TN:Y#Q"\=VMD0JAU"\54]:W(/W[!F?3'C`I7YN -M/RI-93&).N!GTGV[J9:WGH<3U_A!=PNNG;K:+C'D4)V(MRY-&\HH!-#C!T`P -MJT2>I`!0*0[HG[87BDYMW^5FMDIZA*>(X_S%JJ3_;3L$,[T;R+0OK#+D^#4[(U5-NBZ2:R!;@3Y&/-A3HF__OY=G+"URY?)"K-PQ$AY]-:3%/$ -M#Y3&7XCK$YD+*ES7`1_8-;HCQCTC\] -M9O;&JMB#/[Z)B!6V-]CR5(CA2]U(?'\R577EUK&=&_ZD19$RT46DFWG2RV*" -M3;M-?#=*[\LD-4PW?8CLU.M$XA1;17.IV&QPX -MDU`2M2T8-1G4Q'9*^(RI]T#E'@^*DN4NP'$X'[\?/>WIJ1]16AK)8-5<>3\_ -M2X\>YLJ9W%Y;@?.REDL&G.%B]0=W<8[5-\DM5',Q:2I:PVO8JJA1B79.;6"* -M8E,7]622PB`X6V4^T^%[*M+I^ -MS!M40C[Q(,'VTZU'*66G?HGQW\JA&QMGI*DK"`KG/)[JQE'<:>Q$`7,/)EFD -MFKR;G^!5I22+K\L?-W$#Q)T\<#UB#CV8\4`_.=0IX=HHGH?V0-'U:`=A6"`N -M?X]L)]3YA(TGV89ESGBIEJFI4CJQ]M?#,J53ADJT:>4A0ECHSY]X6'DZ];-U -M"3A7JJ(_;FQ?!4^R9W0#5P`;]5YJNX=H/4RG%_797ROIQWAPCQU2GBP_E%%Z -MC[SF0&Q2]J!%O5X/>!_@YB8KR-\&JU,I*`B2LN8QDDS;DL;$%! -M0]"Y`ZN*ZNO1)W`XK;YKB)"*BW5I-L9BMI0$:"1=Z+1ZPM"(4FCV%!GJ8P.5 -M^EIT<,%;4_OUNU1,"S#9*T%;3\EGO;H#??5$G2]VB\08C`$*G4A>%HLA$-[' -M(F(IV*7DF)N`R045##\-6UT9UY#X#*2<$/K/_T0OFCW"12QB::>>2R&YN=-Q -M7=@-";[$]X[0Q_WM$9&Z;!,9P!7S2`T)-(E4(%I1[_4==2"4W0+<+Q+"]9K6)E`T)A&&Y'0EH#@?, -M1J;>BV8T]^G\ZR85[!S=I"?E^5M`?`4"O#$-%W>W&A2+$G2_"=WK`_8G!?G7 -M5*%B]G>2)5BA/$R/9.5Z@)B@7XG7;Z5^PMMHJBS<[4$BO\GP!$<+(& -M"&]=A3.@GB>!H"J0\*JNLV[TG4QD(.,!Z8K#UMT\9X#\^B^9S_LA$[@-G"]; -M,+)MQ>I+NKZ`4HF9M83F#7IW.+)FS-F4+(:VG>-]Z%I'`WKO.+>QGC-[O9WL_="3 -M<=0%M$UX`G[EC:3=W6Q`J!XMN5UV -MHE#TS,R_(2I#WQ7+-SW4,7]"]",+)._S?'.^:V@%O`-"I^M*<(@I-\+T]V>Y -M.7R]`IR/^&B4>G@Z=0WX'D8QJGPXQI@*'30J -M)#FCT9MM:DI1)0X#3?NG#U3-L^4LEU'E\1+$MNQ+-Q:-)WX&$XJ,27#L=5>V -M!4B"/YXF\A%H/?/YNT+63^]DP>3%BQ/5/9`8[''#0)=5^G_^*8(HCTGU5O#D -M,,Z]7404GYSB72I=Z#=G"(#KDFS(#-&\G\H5]:BZ4BX@.=R0UV;O]DER0V"F -M#0;#;=YY$3H#Q0*]R3]L@HI6GW1>"$0CDRQ$-K<.HJ;VYGWVS,&5H!>2N_".X<,U$_+HZ=6+SYX.0`D0OM&4KB^0]48LI-`B4/=(V,( -MSLT1U+,_?`XTW3%?C-QG=PQ]"`KJ*%[HB@J#*BY=7G*FZ7*/RM,>P=O7M=2; -M1U_J.M_.H/YJ>V;2,5"9A6FA$A!IPHDE+=/5ZH"`*]S.;6/RP!\+XUN3"-B9 -MJ291?,"B+1&-GZ>O;"KIH_VIOXO'`8=YLV!_7]QT][U32((C'RJ0B++(90*H -M^9A(!XU);*\#2MMG18VX -MM_LXWVCI-FIC,^_=P/YD-BDW>L1,`C#MZHP\YK1BA0P3.W+O6>Z?!3QBNOCV -M>MR>F`'T:T9PM!9@G$*F9T:6+E'OR0$K+2",FNK*`U@J1)E$?JH109&(ITA" -M[GAEX97[(Q!R3Z3[))V6#@T*?04IUM#'3IT4"*83E->2:J!T&&>K`\=ZD:L) -M/\V;&J(4DI06+$/HWN#2A/9028`N'UR,TH/`)1E'9O!\F)>#?'$Q;K5'@Q -M36IW$"Q5U($Y&P490X1?*5 -M/?ZERZ<\Q,]I%`\&I,V)+3T]#AX!KS%]3Q4TC#G\*>ROGG*23>7 -MM39'*AMD9SY!!-WSZ!=E$# -MDE#*N9]#(%6LF-.G]Z0X@KUK\A"-]KJRY?)5]@=>'GW15#`,[)[H\\*P??5\ -M%L!$O"G0SB-:T21OU#UXO3HC*1$S?W*@P]7\/#"!\;E<0`(HEL$H_4853P.* -MZ"!^$@D.[/6Y:;PQ"7*A7)Y].#9J>J[:L%^=K+J?Z:*U:LC+&L]FNYH@Y:FA -M$45_D1&IJQI`!)B)#84D\,4-]9-`+$IUE(@>%D&KGC4KY?H,[3E2@2H?PW4+ -M%N:1]LQA1QF5.4,IX+PG-VAV!PFC@+,][E`"B-39#Y8P1ZDY6&Z;U2 -MP6>=CULQV^\2HD]W%K_M,H&-?:#8##\*N(,I(^Q#92Q$0^4?LQQ;;Q`.*-HO -MOB3AL*5SJYM#9:O5`*,P1:%"P^5??,?0!LGI>P8YD9^`I1(7U+BKP6YTM% -MU-7]>`2*7QA$QYN153?DUJ.JK:.-F$^F-N)T")VYYG>B3<&,*#/C,PRY?V4MV.WG)585@U_F:XR -MM*!"67]%INT(9MAWW%O0N*(RE+38'B[()%W:DNU)`6QSW!H8-'*%5"`HN7VC -M*GTF=(&37),>`_7($7&^2Y-QPR'T^'A08SBYAB>6V"E3 -M>/3ZEB@BJM1^6'-,`B7BZOBQV8U&%6)KXI#-`\@GQ/C5T0PMSJ=*<7K>D)\3 -M-YMV/3`/<\>#C^TZ(8VQ%2_`NE\KA+*QW,M(3?SK?[*BC?;5B8KZ0PAA0*3: -MXZNB)7"0.T:[OPP80[)0)0W1,PY#_(NV]RX)FF];Y(,KN6S>X,$5!/,&/4NO -MOLGM&6^'`Y/'9J,)NN'$`RZVR)[,"(9QU_1M;_.H1OL,\_7O&ZFJJQD5AQ-Q -M4"Q:-V*6&R8K^.C>$?$N\+(TGV4OUC69K++?.QFA#](USLL*YH:EP;25UOHD -MS,V/)6W6YC^5-+S/61B15")>`G4]UL3;Q(\F4O/W1*BG?N_YWFTJNG],BK<( -MG91L7+XQE9"UEM-B,8FI"3G3>K1O%W3@?IDJ$4OBKVT:R!9W0%4R1$";%Y+R -M]A=9/BM0S+!^,B/EP%Y[T@3M.U%/-]RQV1X!KRYVR-EMBK<>HI:Z]\N3309O(D4%Y0;Q"E7H(LHAC#@124MX_YB&VBHJ[?%5-_-]%,0*,&/_=_ -MM?<-6$=#W?!H]TZ@\P75.F:=(486*89.;RQ]9_P?D(FY_32?G+\\I&-E[;%* -M.SI490N\NB1N6<\]#G8'R/Y!J(.8T-!HF^8(DF?IE$M,\0;.Q[H6Y03'QN<$ -M6%01O!V435ET^VLD?9?6B,H6(N@S22P("JR10Q#>5CU-^A!S6)Z81%V`FOHV -M\H\$P;1/AS3UGZ:FHE=XM4&(5=]FVU2,WWGPPZ@[V.268)7'S&^;K(C@N:+] -M#G\N>56]_]?.T-W63];,L0OT-S<8S;U,W7R11)4UV#N5U7OLEXAL]+:(Z,8` -MCTZT&KSJUI1]X3E=P*9"#,\[\%38GV%%@%Y.DRJ0KW'Y25'8FL^OO$XA -M%=JUUN%S@FJZF1D(BR1$J*+I*W$K=(\ZKIA$W";S;5&..W%2V9XQ8FQ>ZAZ* -M8??P=."(GA-!LFJ(VPL$8WL5X,SBVMI*/[R8XO;"5XMSKC#DC4;F>$6=!1*1 -MR(2^&A:C%3WXY%0=_:B[`;H>4AJ'5,6S)`4'H:;9LK`:5?QCE>3_/);1*7O;,!4E)R/),C8N6SXPY[VT/X)Z5<-H -M.`Z=MOLQ19\B+_CIA3K;.$/*[/HM&,1(F#6/)?T_:5,E4D2*HUVB-""VM:;,K;[R+Q@95O5 -MK%K=@6IW`/Q>A''-,-S'0*N/H7\XO=AFE#2\J?^Y%U: -M@YD9_,^CK`M+;>S6(:CE_-"BT5^!/J.@@CI*%'OZQHX,]Q?7;B_CZF&Z=#Z- -M5E"1LHL#-.%^:'EALTCWBT@"*;G878:9S@"[Q\_&:[C!M9&1#0L/.+CX><## -M4D"6I]D`F>D`2WB1S;6UDIW$LV_._)D#P!I^/@U"3#?XV:ZB5>6GM9L6"U>* -MT=!F`.5Q\`%@./1%NU]4`SRW>7?I4H5YBJ@O?1GLK)CH:])"\;@.[30R@1K$ -M%H5L,2DI-@*!J*GT1B':3&;S3X -MWY&.W-/_DM%,NJXP]1@TQ6"NW+N81JQ5G7"?P*`%Y?/YBQ#TF:$SM=TI)@L# -MQ6=:=NH/&)"B2#.7#O^K42B:XI\`+;(7BO(")`.+>,Y`$_=$Q-'ISZ>/`+_' -M-[O5$\WDI2;68M88=J6:BX]=%B[ZYN9?. -M//E!04)K8M"7,\0+BL-'M8J%5YIC<'7(./8X0ML\,#/["5V(.F18N#,1F$WZ -MK5;^:,4[.*03'K(^(3ECGFQR*]8%B@S-3,]0XX&7.)AO'")X>NK_('':AI:F -M@K"HW`2`A$K0@=2AZ!XM+\^[GU%.>J&=2?/?`MB1OR#&/RM&9P:6;16G9S[` -M8^##F@E9^V(/1([RFFRQ9;GA'\?8YLZH;KBFD^!K#$"1A<=& -M7M,VPERE>:='+]4W89H\`A_N%/7-=EB5M(209C,VRX:!C`59/W?;LN;:6F1A -MD*YA)&)A9M\)SG;TV%[G;@-0P_.[9D\+Z>W'2=-$CW7OT9S;\M6$'/O@#+&0 -MZP55+A'R`\=7/TEXXR"6FH2V@38\/*6LM#*[L=%WIK.T*6_F'3[4SNZY!$JW;%I9H+7 -M\+YE;H)K5BG`[41*U1OJT!+@\`^?0=G)-=+GOR%E<&6;'/M&B2?Y!S+':^BP -M"H(W%S5\;OLXVH)X>K%4)_COL#T(44ZZOO6E?XID`GCVQ*AYA;UK,@JXV-;L -ME+T#97\_'?1`'61?7A,G&>KR@?8K_5-^VQ0Z5,%$]WY<"IYV?:2P94970_II -MR6O051'Y*W55A6A?`#A_.7!=M[]L-VDF!$7U1WOD"4`YE2TEU1*AP2-M[QX7 -M6UCXI>@R7O^A\W),XMU*S[`7%,R2?%F.`2Z.P\Q,1?[\F.DF-=.D8PGHHF@@ -MD-M0\-8*W0,/BTB#&7:?^R)/9-SDHK1-H>67CS'>T84E1A:.?0I2=2ZN<&T` -MI<*G*"'D,Q40Y?@QBP,$R(\[P=%RQ_GWQVQ:P-C#3RM#^Z@+/_%UMD!?'"S^ -M&4\@2\&&_GHE8&K2:!YQL,-D*4;2EGG(]A0^I=;Y]O2TE&DW4`75%3T3!`-3 -M5`+;KE2&/SW?7'VO78PM"\Z+>"PZI3!'U/_LFYC@8-#V"W< -MP+1_SZC`T'K/`#?QG3TU`W`.$H"E*3&%3D[^Y>WJX4VJ)4L0R_K%H_SN[]8' -M/7KWZE2)58DN1R"1X<_I[A?^9P3JEX0,[ZRM?:Z*A>)73^,\J:"U[\)46M$+ -M17WEW3-ACF['`V(S.QA#UUV@M\X"`M94O-*"4U=8:4)6<>*96<+4,G"[,4$RHDFQ -ME"Y<(3GX)]"&<^UG*T9T?LN#JP7(+QV95^%H:K>[`I73X5@(XR?C,DKAW< -MN['PK#Y!$OGM-4(&3>W>H[;BI.)>ZHK_IQ/WX;R+U=-=`EW5"IW:6`CR%-.% -M';B/O<\%5%2SO>$AOLH4-3?6TZ_7.!^?EYTBS_G7N`63Q.\>[8HO9>7+`SZ_ -MQMD!;1.][!`?E4P/F4A1OPS:VOH.JO\W4O[3'1U4T+IV.2/OGT&V]+6FNW>H -M-;.&->NZ+>"S<\)QP;[J9'6"Z,]EUR"O1Z[95II*@MY6HWTFX=/_>)Z3CO2_ -M-@_[Z$>>[D@K3O-'[,IX6Z(*DMW+AU(#-?YK_55/7?%4B73T%I-?!2PQ/?YY -M)GVCP(^\VN!SJ;&J7;IE/U-<*1NEOAU#OEV_?4&ZZ]T2EKX7#U+ -M]R#':T.E8Y4A;3TL9E3L4>X14T/*_M['1DGXMG@AB(1'@KL7D+ZP$O\OV!15 -M"F):)5^#L0*UFX^%-M[C"^!5/#_;8[ -MI]M/4]$2T$@\[2I:P/4+6V@T94[P=X"$)=>L\OTDZAK5U=-,:4T_^PA@7\UI -MB[DG]ZA&??67^C(R+GA")&MX1PEQ3?#_&3]HQAEF'-_E<%6P'75B39^G>DQ> -M7V;`-Q%K:9U*<;6:N_HJ$L&YY)-D$?H7.Z^,076G("T8TH@"W4(#4(;D7C&P -MJ)V$>X,*8<;UQ9=DGJ8+')T;E\7''_\[LLEEWPVSSNK/'$VD%Z2<"7\H -MXTXO6)3IZC]Y>P*_+(KMUG$\5/JK8*-;_W8[$\FE7_^+J!)@#%KY^'CPY,*2 -MOZ'Q:V:C8$J];"L!'FG_B/`=578TY.IAX.2T4A%\><0,2>8 -M'9JAKG+MQGBB:GN&3TQN.'@A_@R3HSQ!Q>8VFQWBFT#X$T`.7*9L$LE#W,D3 -M7'5(6QH-L*:[]`+2,E4YOZ&K8]7"!^;IT6L4%N=$Q6ZW$?\!:ZK5`6RSV:5, -M`&&K8`/1UQA2HZ0K9`K`2%LRC0CE!0/S+2B<=^6G!9@/.,0<7XY]<[-G7D%I -ME8_(9_E[7H>$)L4*BK0H*9JD4-K1QA-+KWS%P*G3SI4S"%(U5/GY_M_E'D*FL"C#_)QH^Z;T[H`#Z`&B*'])!3;;1_P*X;A=777:9!(L'`H+X#J3_\F!-.U,5IMLDJY<>.MY&@1B0 -MYGM5IC&ZL*Q[$85`-[&FLC]>+TO"8J%%ZZ -MC#``D+Y3._M0GT;7W#N)B$YSJ!.ZA*6D0V[/;C]ROP7D89,K$8(T=/8]AYR) -M+$F0AN"Y;V!C6=,.G!&VJB*Z[_DK`KUGT>]LJ"Q!G1>!E^]GU2C:'"HIGX=` -M*8/R50+DS6LGH;0A2CD3^`+P@4E@/:>0C6BT)]SP]`-=5ZY&ZX"<978N_D+X -MI-#>XDU.@D>QK&*L"BG$M[M;4U]>C9&J-BJ*I&[N.I!C!DGDQC9)2JJ-UY4' -M..OU,H=OOF:MR.DZ.>62>M<^*KY[$>"4*WE-H7%2<)R)_@WB/.&CFVTOP`[E -MT+7!:QXY/V2".&N\;<#9*H*]#X_8_Z=Y0):X[(<9TT%5RN&:U>]-@&&G4A9: -M5.B&`2)0H_3H/C41SD-M5=_[RID -MJ.!1B(C=>:KET.?B\#QZ-/"#@TA2DX88RD"6.OC9_M$O1;11#+OT4GVS]67P -MORP<#[>*#9'_CYP:5%3^"2"P@>;&,!-]#I&(.U!HG`O>M96_X+[9F;?'BIO= -M3$B(`F5;:[_HO35EM9G[8;D=BF#!2],*R;=V'G<$T/H=>.)^MT_+MG!?Y9R'A-$`*-F7K07I=KP1RS`,\NA1`=T;;^25KMAB`9MG]9#%,/[ZC2>+HSR,&$=` -M,4(%:G%?E$)PYG)ZZVR`P9G5-B<2-2G)ZW)JE7?ALF#HKU_>0)[:KN>61 -M1.3K,:!AK0I(A`XNE2)'7M^R"C\-MTT$*?LH*VOU6^Y%`<2LGFPC[`P'XDH. -M!Z!]Z'RO/"2.G6C:Y=&NM`,Y`)/8%9UP:`8]WTE(SKDX`3WJ'4CU5:#?GI^K -M`45J-/Q@6XG9'-9&LL]5164,KD7M#ONB*\=L*C0QQ\5]>]VI!SJ4\P)=KVVM -M-R/,WU,MB_TR@`22O/#<>0Z`$<@D^A%C@SS4<.4/`F!9K?\$A-@7-4JFP+- -MF_;Q&%(&.<-1E^\V0G9+/L[Z\60$2KH",E;2LT0F10@I.66J#4+8 -M&3OPRZHDP)QJL*($%8D?X_O4=(&`)[]@^6\D?UHA=G_-S5R#T([HN#WT&'NY -M'33)DX6VY=/I@8B>08[_7-$79A/,]=.D9#+VP^<,Z$5O5-B),Q6I:T8*:3.%J_ -MC,N%;>3?_Z2("ZC_KGJ_RZ%1SH[A>&+`9&AG#VO$3U.PYB`187#\_Y*#,_3& -M9)(I>SH\BDLY;B34R('O=7U$CA]B!RN%D3#5=S'4%)+7!1LBS5[Q\_G"':5@ -M6C_CU\,9,<-%8+KN0CJ_W4N2P_#>%C?:Y';(A8_O-",3Q8I8LYD0/6_.`0$D -M^#5$]!P*12]^V[U*`H4U8M_LK*^9^16&S_B)9K6>9G!*ZNNJE#B353K?:%C$ -MKI5A2FHQ1@[\\'"Z!F'*EEP-T1&+N`^!TOIURY3^Y:KMZVZ9]N[:,SNL%-\YCD*.<$ -MQ``#E^P\(]7E\!\PSC(.'$[*N\5W/YJ6#O-WR'*@])4#-JR/ED(Z8&@+%$AKPZ0WR-[YQ[4G8'++.3SG -M6*$1^YVN/BB%F7S8:B&53.&O@W9A=T\`:X@*!39G24.H6;KIQ^1&2S?Z&>=\ -ME;G!+?XU!6[33L6NNN";7-1B%.A(9/:5`/A(@EU==0VTT9L13HKJD$&S$\[D -M0>LFR\JSB2F,7L#HGW1H*34L"OTH"_@FF+S4=Y2,]@UZ*MH_EMB!_DHQ#]G= -MW%(?!=,'EAQI)4".PBB61G'C@YW0R#N7I'@9R),UNMSJ>XZ#AC#'+`"=P]GD -M3CCUR6Z7(<7P12Y5_HP0E1LW..SDZ,@F*WFF3(4M)9&0)C=]8!)-PMC/[)JR -M*($/L>G8\XDQU@VD>WL5][`B40SI%F?>2O]MAQAT:P'ERU6UF$OF_X1^PI&S -M?]R4(^;:^,>%*6]D-UZT:;)2Z6FB5&C_+(B%:+4J@`4$2?X\Z'P=O40':[%> -M7J^L;K=_T/6;%_M:__77=22LU?3%$)R1ZSS4A\00`-/*U@C[H#PX;Q)\YC5^ -M4P,Z(QCTE0FH8SH`!WPI[$IF="VI(4#6@/M!L&0:L3]`<#\,"C -M?7.3[]\6'K.5WEC!P]U0*ZX3Z?1A,NHG04!K]4%:^2OUMDK3JU6#XFG%?$Z3TA.LZP?'H2-E\15H4KB8J -M7UG-+`8UGU46@A0*>*!,Z?C.38&5OW2TJAWY#T-&?5[<_K^];)H_;A7?5W%3 -MY0J/X7$*XB+>JL\3UE0+SZ/( -M/FQ"OF?.QB[L>MA%4NBD'=[YC9N:NZV]HX,2,0_"[ST%`0R%&)C*QJMA0C._SCNZO74J4@O=/=V)I#?7*=!,MO_S7W;\@61+;`)R>BL$959AV@@=J1_I5- -M&C8(Z04S7=JM"M[%]9D6+7Y/2)2S<3O-Y7A<'];^.)24"W;HU83H*!7N%<-%RP.PD. -MO2P#`;B;6W_=;TM`]M2U":PAFYX1642E9(M7:J?DKW1-`!AT3XO9/:E -MC@*9HL2T@&L-84]CH2#"8V1`C&."1I(R5?,B;47C[8[C(V6&T,CS6`AK'.+0 -MBXDR2'JMO&NR:V4%SSJ3U?!/>F5;4*%"_)]%XDUE4S&=I0MO!(KR82/CE;9E -MA;]'P(QJJ3W:=L0O)="IU5]3RC*&B'DB:""T["R1S=,O8TWPR5R69C6:(?#% -MA;D@G@/SLH&YR7C0+"^I[4(/G#<1E&KTJU,^;]^KN%6N/KSF)P*8)^(.!;DI -M-1G(695O<(30:J_H2M-+4/Q,]RCSU`4#9F*:VX6LFE/ZNB-]^Z')6?``[B:Y -MRW3IX:Y2.*=4+'?;&BHK^.6*W!1X`[_7_EGBS+KV7K=?]LX)[#K8G;3)D8G-H^_*GW9]"K'.*X -M_86<^1[T(!3^CR?6H.EI!*4/=61UY'Y&=,2I9QYTQ\@H81MGLWX"B43ZT.!$VT_\!!CC)9#3RSLD"!ODA\I@#!!4&USTPB%]2M#U#RIAX2K'N^4=P -MN?K`P'LU%^C1.FI4R5]H47E`$:1XH;#-%8. -ML>YKE5R@?&NTKQ:*J8+:3M3?:M73':9U;Z<\=#&U(![FP+"'\E_OPU@MEHP$ -M.T'V%]G%F-]NYJ0(ND@U+:"%LW%N#4`24JQ;$8,"."2!([D=)5$W'#X -M7?2D6Y(*[<&,Y.*>$=5D@*O$/[I?]FEW^U+ARWR;!A3]/=%\JHUVB(?XGB`E -M&GP<*Z3+]9X=E[CU;,!D.1G#0#)IL-*MQ04]P5(*0&=J#S_[BZ@QO9]UG/%,5\4TE(D*+>G>O0[X.L)#$Z/#?R,L.524]J#^'H.&5\JLI4PO7/+&35#=%$M>_':K0>81/D -M^2SL2`SE=:OWHSS9;3$,*]'&R@\V-;0J;BEH0Y+M'+S+Y(I7M_J_S20DQ)*C!B^I:K-N9V_N. -M(%1?U/0R(?EXV(^8"JO)%BL!%M,!IP"B[(<1*O_9#O7)S%!'"`PQ;= -MR9T7+(+334@3CFW'RJ%#^37%C9VO+/_^F@4%2JI*3`>+)M_&JW#/R#+4TQ -MZ4&(E(2J!^8_I3?8(.6OS+L5894V_6!1@V^Y3*VL@/_O8=@F#NUMLU'^L1=,ZI\T!=_CP+!"7P@T.FIIN(QSK/+3WCMLEG&''[ -M+$WM(`S`X#;`L@7UO*[R:*;YF-108B/0U2I],+/Z&)$H$R.@K,PR8>3X"!G- -M>)&5O[?/K\O%%S"S'//"E(F-O"N7&Q<5,JW;!%KC7;KJ\X(('ELU4H0Q'R[-9]54+7KRWHQ_,,*S."@^FD= -M[R?YV1*L!0#<\?W?*BE7(MFY[`2:F"C648Q-K.DK@>80W;.(<+`]X`'TJ?(T -MQ)'4,UIIE.M0; -MS6G#KT9:-UKCGKLTQ'%@_$)0=RKU!/OHTJICKEC6K<6:BQ'R"D8PTY\5NRD_[;T1;XL?V/;^*O<[Z%5*`7G -MAS>6YJZPU@_SNC(79T1'*S:PH_#R->%?L$IP4Z=4K=><6*,@"!T_W>E5Q7!: -ME:KI(3,:NU_N[:.>Q>0QA/D-I(.XN@ -M.M(,9DHR+=S[M##R[@L_8A1:*__"8=6;,+`6S:A&#\#H:"&+'3<'[XK:KHR47-1QBRL5"N11[G!==J&S2<9 -M6MQKU`S0W%(0/&7WNTW32:%KWPF[G<[&9]ES,H* -M=;;GT#W.IQ_V<("/+8V&**&J0)HKBQ*)7OEIE7B75#S^5'^)3WCVI=7PIKH7 -M+MFO_J&TCDV=0R\Z0M%J:,-.".'6,;DS)'"A=!Z:9%]@/<2[GU_ZIWQ?$FQ) -M/K]K2AN+K2)GC^/2#RR7HK;9]W.RTUA9] -MK2R!BC&H4A`KL+%=J25GMT+@6%7-:I"UTEO+9`-A-Y;7QY(X(1G+5#!D]9]. -M5QY,")X*]`=UB?73OZ,'%/22VKD%J_P,'.O!9`Q1OPP%#!^,([T2QM/P]D=; -MSW7@Z.@'KF4>\)V!&8/2V/=.)4-N[&YR1C&4]N?W8ZU28H-)X-0Y"J4,;H'= -MO]7PG4VQY@4K#Y"@/9"M=?4]]_3-IB.4QY^$KIX#4L-/DTC>?>#XB:J4OFQ` -MF3.#_=B($^YBF#IVTV*&V-&#Z7SNK-%-':G4Z95QXS'(_E+S]0.8P#%!PXC` -MX/)_%E9+]E(2$CBO?2(R`9J,B)JA1)8)QF0=^9.O(Z9!_V^7OC3157-7*"`>W!SC:6U%X+,#^9C:*8^ -M%CTR!O#*@:FA6HB2H(H\!.W<)_"6F/<*,,/:,W_@$\.QZK0TX-=%)MO:&\+O -M^QRQB_':6(E"J7-!OZ4\^Y/`JFY^Z"Y8S(()4Z?ZE`SYB_.D%R3+NPUE`RL" -M\]VD.-.N[)MI3,Y*:L/UQ'5=(W\:FD_MK)W"0L!.SD*3/>&]#!Z#S@W>>#Q*4.? -M5//GZ9(^$G_#5N>LQQ;0!V?&*0_>\",NX(T_F@#"'<]&>=R2OC,:B_!&TZ(B0Y$%:2!XC2Q -M-LX7=$34!,;\4&PG'P36;-JN%F[E:L9.(M^A1/Q'/()'@>/H&D#S5DA5"F.7 -M$AB],'+))6-J*^B.FB9WTH%>O//8^-,.^81TIL8G\".,3V-A6*==&`Q+(U%) -M^41HS';N#,IF`@4.&NUND/_CZ&M@4+A6=E%&"$<%7,*D($L34VI.6HB".H=U -MV)*<#D>PQ,?GB:V6RBW0FCC*]T)PE275_%!)9UB%$7AF=>#2(`B_DQ[_OWPZ -M$K4Q)8]RA0%K$)28`%PSTDM_`B%UL2C[)BGSAE&*(2ZR>0G72[F'7K$:U<#MG!).6:TJ=">T(+/^%WG4U -MY,_N_G'\/S4P-\F5I;Q>VQ330^S[50%WA3G.6R/:(2`\)9V2/,]?TEU"HVN# -M$8$JAN<5?(ATQT[GO0,.J>7P"+Y`=F+J[P(/CA6T%'VF<^%MF5KVY#<^#-UI -M,=[0F^Z+(LIY&AUBUP?\U=*2L`>U,1[A#6J4W+Y;'^^1='!@5UUFS=13>#5Y -M2/JO&4)7.@6XYD51_40[E^@Y2,Z#K/+P'VS^\3&=J@A6S]0"$GUIK&@UGWJJ -M"D@A52B(DPB%M?)Y%D4]%RN+\'I\2,[YPO+?()47V)$BI_S..VL*'0#9S^8-WD8FJ4]9IEKOWK?"#,/-:P -MFRF)G.SO'N7X/&JL*_#&`H`4R:))UJE,#J*R/O!8#.ZCCC@::9#D$*/2?HT72A'5G/;(-X_-](HP_/@*5 -M1.VP8`FJ80N"Q!6-/6!S=+H5;HE-!J:AW95.2B*HY$"R\CQ958GY41C)$("U -M0#H/D<)TTW&?E'ZQ@3QJE\ZEZ>OT@@?Y[6[,M"('Y8NDXYUZOMVH:+C9Z#<\ -M"&GK"F\>X3@'^.&(UE*RW80=VXN+XU%7>*BU:F)5A-[T/R$2SJ!Z^)LT)4&E -MW<*#@6;E.Y6-DGED%5B9C5;_T.K']-!_(``EB:CL.KSY/RLL-E0'U8#ZZKL6 -M\8"9.9A#1ID]_#/\CCO()#=#IV=6;2<=_RB;"/"@\$A>@B7`;N844]QD11B5 -M/QN=VOJ^:$QWU#B5URE:;-BFL,"*Y&P5*WL]721>`(7>P;0"HQ3;(W5444;C -MF):*V#WCD1=C$7:+4F?/7V(ST-%0@-4#?O#'[,ZNB98S%`.F9(![<":P.)6C -M!9+EN1GZXG'`=/O\\4\I9O@KJ8Y[V*9&$W4HZ6SZ]6I'+"4EXPQ'HFY),73R@(QSVO-`6-A,$O!C -MT9U9LSUFF:&D0LI8CWLE;[):_PD]:Z*Z.*"F#&9R*:&Z78C7Q=MQ[W^4[AB= -M4M()IQ\R'OM@CT;8%"/^KV!^;)0+)Q^9OCXD[5WV/^O)[X0@)G\-<*@0"TN; -M]UAD&D&*]@HYYO!WOQ517#1B4*IY7XX]<_M3N^R,_YM2X4>Y_N'D=`PL@_QY -MIG0R*9`R"'I1K;IF^6R/.^`:0CL5.6\F67@#J%*[A>ISQ.!?<6J34B[8`%0?@;_.@; -M#^9CQ]`%GC_>![,0,H/+I@[\EAZOVZ0M2/QQ'D1HE8\PWSOTH5RZ["X2T=H< -M_NO9HB7^AX:H?9)\F&0UG$'9*^':N,U9G'6LGIY"#1LO_QLB:-@Z?WM/T6$1%U5U#LYCV/^4X6B<-C94*I_A,DIP5"-] -M3[9AU-9"$&VM0401ID\"P;]*B1LT%6?$*021]>O_FQOR5MXXL-Z,>&2Y3U!` -MP+\.]F:HX7DN$;'$ZY4+DC;W,2!&C8S]M,36G/&V'"K\4->I-HRIE7]BP&*6 -M>JY@Q%*P..Q^WT%.J/LV2*BM\\M=\3W*-AT7RMZ9:L3F5^%=K*G0G_K;D,.N -MB[%(]?Z:WJ43WQ.SYO_>]FJ&7U6CB&H*6!1E58M*GKEZ3YY?T%1G"\C$,YM! -M)'?^4!'9B:"#V_SF\?JFTY@/MYC\V@SG#I0N_W/:DM^V"?L-NQV;@@+F+060 -M@[F`J'C3/!WTDP7ID67!';(G4E<'YI-?7T>UFHLC79V/`ZRUO]26N@@?",%X -M1X'QH9R#HQ:<*3OR33.'AU%(;KKGIKD&Z:.Z'B,I&N1<%QU#BH1Z#1L-'"'I -M'.Z?6;B0KJ,*.BT7Q_/H_F\+._,X1'FJ][:;RM`*:FV9_6HJP>+Y%Y3Z,9GS -MTZ9INWDNV3^AZ3M)=SK\7SE]^2Y-FNQT#G+]+W1+#]:I13>4-T%$6M/$7C&H -M?2Q,1#LI%0S2,=EEFW(R+'6U`(IP,A!+\F-XC7DT<*?&>* -MVG_1*AI$@$P$?0GJ"(0)L6!3Y2YB40N6DW%-/-PF'OUL&NCH>ZMW5).=FST7 -M5:C(4YYGWKRL9!#`,$ZF!W+"&II_7K^L1!#\R=95F88Y0>W>G>\;2ET*[B/F -MY,L=%9$D3MHW;VC!_(L:ICU_/H-?D9#8[V,^QCNVGED_4MDN\&ZTWO!!PPF! -M3!\T456<&@NO&E3B8$2ES(./P2O""H(7%7Z(XL<*C97\#PB(/+9`NS!33 -M>OTP="Z\5L/-L+82HH>_J@VX/P$*/"1U))(`X,P2\!F`>^1YRGA*8PZP/E*( -M=K3_\;2%0F)UG$K>)=.V5HAO9D5RL'V]>M^([[.-WTB5GC#&IB5!H;@@?,%[ -M[]%5_A?;[8%2M@`6U#$,TDWP"_)SKDG91!>Z&2W\E!T=]W!$.H[">=P"DR\$ -MQT<`7]HHAV.+U7,<@J#'"[QXSJUD]@!(]==F$)^!GUZ`G,D#J#8BEJ'(*^69-"OSR]_#49JG9A;X]#,#L;>*I4X?=3L"-`CI-P?A3H4Y_(F`\< -MKWY5O%B,<@!=%^QL:5JTB@:K)4J8&Y']":!:^!_!BS%!(`H.W6X6=$E$_5C' -MC0R\+:/BTESO< -MCE]T"3B.WEZ7)81(A@<6=]MQQT/[EO-+4N.U[AI)Z5P#BT?M$RPIW;21%BM\ -M"Z0QP=&ZR3#S*NS6*IT#"7*UNNJ1M:=N_W,J]O>ZF0'P%TV&[W__XQ(9,4?F?1OZL1'%9?,M4P -M0:_&*>3VE0!E@'[USQ)(*3+M4A<^WJW\.P\MG(G<\1"^-:;/6@69`DP$0I=W -MRN87+"F4(NE":=/;]&`9'O%#OQ-6`R3N9@*^$AMQ%FFW)H%B$W(FU?0N`$RYT&_F_.':)1PZF"%6H$OL0Z-:&:`VX#%?:B(4!,@PW` -M$(%&,(Y6:QRQ=?W]477>(<#Q;\SWM[9C1S0=R"-SWULMR@;+OV-39B!F#2IQQ%:[^QG>W*C/LT5 -M/=Z,ZK73H?=('_KRA3M[.M/8TL)6A%%@:S<@82(+%(EF@<"8[O-H.NDU_E]. -MV+/(1(*>\%\]CRQ]!\%9M?(,Q:1EKC_AO24<*@S<[W!4T* -M:(RP@)0N

    )'E!?>+%^3J(\K"Z40/[6<^\9)RV\R,$J.P3W2WR8F?]4Y:&S)N71C> -MC06-R4N3_9?%3OP\#]^8?449X],]^R37QT9::OU\;H7#H"&M"\2F1!0E4RJ- -M/YMV?WF#%(=J],+81>-!!.TLC%^5^,?]6,]+\=,`')B]-LB8)V_,R7@SU_OG -M+W4L0D%:>X:',./VQ<"8]NAWYL,;^:&WDMAQ"*'$CT`1PY[-ZM&#'4LDJ06L -M;#Z%V!A2TL4C`F,^"O72I4M,,6JR7AZ)^<31K7N\J:&2BU=.X`D(T483"ZJ3 -MKOV7FK('7$&Z2VQ$\'&B#X9`69YQ-$?A@])+?R9+05`/E59W1Z9N8Z,CDS -M/5:L-1"R^QY8EH0@Z/:E*^R&2FX7SQIWL6T7DSMMT=@`I7/A[6ZE&^5:UXP4 -MJAC<=W1'JP,08X6%3JB>ND\+O>P^H%"V,\OZ#/&Y!G)&+%7](V.E]0MU_YH-MD@EIBJ,YF>S2 -M?.LEH-R/P'KEV,O?+W179LQ;GT/N[`?KO))NI[/K',C!>8Z(=-!M,O.-/1L_ -MWT!$O(X831S.Z+7"GOLUC4!IB5[&,$R&^6B_M@H1QY%VR6\6.Z3R2]K<"O`W -MAT[MM]_^?/Q218/^)TQ[6UII*_<2:'WUOUF.*`]YU3S2"JEECF -MASA"N-RPYEZ7[\W$9NP\':\HA'2#E.^LRM]E'*,;5"G8L%R"(,2&:?4$Q$YL -MJDJ0J%.A(`:+I0[YV8Q"!P/]_KN*/!V&CM4E*9&)(X\QCA1U1KZD5U9]/+X7 -M]MQ-?X405WX9I[VF`X3NC8L2"@50%O_1&*(&AS88/(#M-T#W3O2Y(-7B05&6@+X"QO -MY"W3B$!/UPN>$&NSE^LK!(7L+Q1"^`PFX(V>K:Z09=&!\C<364;/H_K06"<5 -M)H1F/!-^8'%Q/!I(V%[/VPY"5_=$SM["EHD?RRR4%;\Y%#]C1`S\S>F -MLIKEA.4AW717__R>#I.8?N=&U,;H1:\_.[8(?GH'0WRVE<7&VWT/>'P*=Y23 -MY0K;$G4!(IS-W3FRM4N4MO#M&TY$V.R02VS7?5?PS,5SO+/AWZ'6)5348@_W -M-KJ!9>HRIQP6VF#6A&5=3>:MYY%X1,[1S-\[[Q-` -M@2%7YK>5HF!M(!W(4_TXZ=<;TKD2G5\LA2H7CQR+@]/X8.85&2L-9WW-1K -M8'1$>K!RIHR!WEB3@M2&P)6\'`RU -MD)(02'/\%CKZ#261/V/'"RO3[KZU_B@@>T][G!F:1WPS^CXRX)2[18 -M[%_1.O:$M-O+PXUJ[6B1RVD3*,=OC,$7>-:'T3KZHR@=KM)^3R*6SSYM[9;. -MMA0>Y-Y;>\!)*21RS\&WZZ,WC_6UD$+A%XVUZ22$1Y4HE5>VIQNO49Q!R)+] -M=X:`P^T7X?#YA!';G8O\^L_-I!BI#LM07UKU;S=P<#91,[R1B]JC]P@?]N=5 -M=NJ5_A->K[HUL*@]OW8:4]J(&!$1?_1:2D.O7U&%B+$.1=I*`&$0<_GL%VP# -M_\>('*UIT_)&7O#&3-77+#]0=&;-H5:.]A9R-A1T+?^YG"_$$.?+;-A7L+-\ -M`;'K5-V225;()<#G9.?(6TLZPPGO@$)`G%*+PM47WP\ -M68Q+[GK:9`M#EV-J3-Q>S=VYP8RNQ5-$[?XD#4?[V;G<RBZO40*EXX/V#V5SYDK`D3JJ*L_!CYQHZK\Y'E>[Z)$EN*TIM"(STT,:$KUT_?V'<('`W0'F7*T69H_;K.H4<&0*WR6%!,RE?W>&:LM\4!'0M2H6/5_A> -M1\,04L?8F>V[)3?.2T_A&'1V>N7N,ISXX)_WR-V.P]>D;9/"9E=.9KCLX_=G -MR7(SNKH7#8T3[;@`=Q++V44H`8',9N_S6%]%;O=DH8FY1\"99XZ+0E'06A5? -M1J\T9/*5S1FX&@Y,DV[=5PGF;2J`[(\<.%O_#[B8E8I8VEY+UO)X`13Q#`!G -ME1Y\XEGX@RCV;,1C,[R\2`6_XG!J*M*U+#KVX>GV5#'WK#1E?^Q8P'H*KPJ@ -M%$(K:=60FQL;P@Q]A0[0P\F.T3W;FD)$&!*['Q&!PCGQ4DQO>>;FU-I7GC\P -M9QV*OUS^RF#4N<&).<-78J5,@[A.\:_#&@S9G$"=K/>P6KE.Y0@;:V_`4+[- -MT8'$#9]EE]G;]HAXOAUM)E'MG?1'HMU,S:`H?;*&1=Z__**T8?0<(M[=SB>* -M6(-6HY1M59WT(7%V&Y2AB7K*C\?I^!?(M$#T5XZM4]ZN8/$QE8U]SG"1$2=8 -M"/?DO&OI'[BX6,W1^I;XU>%/_-KAVG?TLL5`E9(YI%#3^%PX"OS5D:]DZ14T -M(;B-M>U:?]6>M)N_,K^J"/HO/,C(?J71RI9=:!/ -MY@3CN."5E -M^:;CANPHVEP#&7T["5<-BM&JQ4W+C;-*!@]0Z;PHK:9"N3C%3[PS(V/ND]", -M^5!DYI)\VG%GA=.>S!'*5HLP/!I1\<,%Y850/G(D8^!;^*H#DO&^DAJ2P'MT -MO@#AHU_SS<9(TK$?RQP":TI3MO5\?W6%Y`S57^'.[SM2'%7LY\*C(_%:K6,Z -M_(G[X\,H!$WG4E29G9L?M'?4&F6.-SKP1>2?8:P/^8?#33,H[8R -MF+6S'>K10.+-0I`;^W$BM]4^ZEUZGT>?\.E4^P`P.'?^@H7O@G3'4IM^&J@( -MCD>)_4-P,U\SOA]9/Z,`R-,I7CUA<;3SQ^\WK>5_&F45/A,4-[_DNF -M6--:^].'E_5\8HBHI2129Y-]QLW02:YK5^M[E@5:S>:-H!,Y5:,B;O>1J-)> -MR\V[!%RWM@![]J9;'F'8GFV";[(;/Z,+NG*I%31L0UY+Y)):>=O,3B"_T.50 -M*J%"%H?CG79R3"^R1ZG.85!8B:+G:A+DHA.IE+8LQ`R^32C77W3EIC+3_U=^ -M2IZ_TM+1,OAYF&Z-#6XZS"@U:DS"3Q*<-:QC"*1*T)UFH3A4U&36^20QXFI: -MJ8!,TX62'`B5(#U%1&CYK)Z1Z#HPK=HW[U6A1-#"]9TL:W?#B*6OG*(2#[#- -M3C<_4V^A[9O="J``AD@)O9#_Z]N.W4J:A5MOJ4YV]1[]?Z_?E,L(/3S`<:9X3@'8>5)!@]^N"FW]8%4(%_K4/(/]M.#`*'@;,$5-ZG__W+096]Z"!8"]*^.,Q6#$)*+,6B?C56Y] -MIFE?-`HT`_R^=,CQAX61L`:0]^6/"&.'86>?"^3M^.C^`_W"&[>U*\,+@QCA -M:C`A>Q@JF/NH;,XA6?U*"M'5E=>U&83'J=/'SYMI`W/TQ!.+@X3OVP^$HDR -MSZ9MD1[];,U0M#(11,&<82IH'3(RR-@OZ1%3SMC\WZCQ8$"V%E_<%I1@M!>Z -M9>V#IX`%I)$3:8,^74\.$92?('[7B$G!WV+8O[EJLB8TH`_6`OO]%2+@.2H: -M;9\$K[3V=S,P^UGDKI,4+].&4==[,9%*6ET[=3(-KGP5&N2Q`$5)WA<6K7*! -MO/9$#GD7G^'8)?FI.RV9)>\&@'@>?$(Y?U+1%8EYVB@":'@)['>F'--C2<=G -M;A@@16F._4NN66'FTL5X.2HRB?)CTQ*:1;*%F`,C"'@]Q\953QS8%LA&P?$;3W@3RH^2*6E7#-.@U[Y3 -MC.Z>G+KS%@E(X=(3JE8ANZ73GD.]&*1[1=$/3DT-3`!LN'9=[>$14.0 -M%5#AP(WS,H]3O&D6XC1)B]]TK%#35V_:_4OQKYG.4,TI&>7F-GCT2WP2)`<) -MHZ5UD=9/R!$>M[CU+BVG7;T1D6WBG_[NJ-LQ'4\\^DZ1S$@\4(.OVND3XVL:%BXJI -MR(*[0G,K.A00K)ZZ!E)[NH^S,!@<>S%8JU[*^4:E/0-]K(>"B^6G%3!5GRXA -M3KM>FR@G80,X'GQGB(]TOG0!)?0-$&+@_$5*W6HTK3V/<0&5QJ`2HN5!G^W7NM -M&"VXRW/,,Z)XQUAH2BV@WCRV#"WZB44W6,!6332$7_P@>MOGR -M3A>MZZZA+`'JA!I.:LG@VAYGZC.ZL:FX_$T'/P?V<&TZ4!K7I#??3J0+5:X_ -M>]Z<_9;QTYO"J$@=$Y#:#JT?F*4E'OE4T(:@F;[.4-W5*-)6Z7*]W;B>^<;# -M:DG`3K.H-9Y\A=N9G^$)<.V`8%VHEZ/O+(J7^(W,#X\NS;B2:E1H -M?"6Y30B8_C-J7IP91D8\2RQ.$S*(>*`[=99-D3B4?DC`?XU0['TMRA3?15JA -M_,64&&KYF/_]$5CQ30)ETXG_G/* -ME\I^C*NY0KR&G8.V3T6\XC'EMNY4I!C%:.F\H(JXS-P@>$LALV3SN -MV*P.ZZ-0/#YB0RE);.E+(2IIWYP1N'>=A@FUHA$;9WU_O)UFQ(H*5!77]SA+ -M*<9HHHC<1G]RI/8L270/@XU;P,G=S'2](&DH$WH92M,[S -M60P5_TYR:A@]V5??`"^AFZQR0-EKMNFQM$BOA4"&I]&"=^E9W2FA_0-,9*69 -MR1#$^P!2#!`D#3_@X*"8AJG=XH.RUGYQ39$" -M_!MR4%JZ'G)0$E8I"74Q%%(JLPWWAQYD^U(6*H)'^MQ7=!:8O'M<7`OD5?L4 -M/9S-YPJ*F(CD?.RXFFKZV.;KG9\&IWYR5W2-6OXQ68,Y30<<4;!OA;#52Q5B0KWE9/TF06I`K0^'19M0\.U(BN19?IO#6'-&6Q -M;WA8NQ`1-!MMMA-9ZUD;E';HLAT0#:XD+V,NPV&+WI(YXFMJLQ2?Y>-"!KIV -M`HYEQ1N:Y1?9"-2%7"");*!J:XU?6FY,*,[ED@3[#?2><46LS^B<5C/$U.GM -M=9-&BNC(L0D8D!]:R`]UL$WMV/B_(LAVA31]T>W.M -M@XH1Z+:+;M]3.;"'_-JGZO<=!_IAWE.Z\;@/%JB`J:S0W?6?X[E;AC0 -M;2GTW`Z%*AXTZ^!&\I24HBGNJ$HV3B5G]R^YS]*OU083]"1Z!+*-\]^#_E+N0Z],Y:]=<0:> -M!4UEY$J.$N:%:-KL3+-WG\(TQ.A4K0@+S1;9_AJ$')<-[+6AU)E*?S7&:=;I*=S."J?W5F2D)_(:\$"R]]?>5 -MI)KD!MN]L-UE+]$@XW_9G'0UOHL?TYZC=D,P2#+CGWQ5(F3($D@%9V-E@I)/ -MY#Z1UT[N*$I^/1^)Q!O7XXZ@?!`V8I5D;Y(W_C*^V`T%*U\)!H?:`2D\Y6+! -MR.&0X@1L1YI2(*J^2VGRUYD^#[CM>`.C5P3)&$!]+/D;0<\7!OK_]FJNY/%G -M-M^3H]L;TJ39XY?J&241*^$/&JWG^=^)JN!;&ULQA@Z66\RN7/=;/*=^`1Z(I=(:O"=;S6= -MYS&YAAV0>?2;1+HUWA/>S.-@9T1Y;#):5+-2O9ZA%_\"+@!<(/`:D\#-*:QF(NQ]-.2$CWGE^ -M]ZBVLB(RC21=U=(\4]SN8ME2XN'A9:8(_'"P06MI8#$&;6B6-AY^USAS=)X' -M.5!C@N'07,`>%E/)=@=`.!EKEEM]*]6,\';*1]]6:]JEH($_(0X6S:69L/,W -M8:DYO<4LJ?I@8*IL]N^J]XS;X&7V"RB&3I."E5%O-,X"L++=[9Q5[LYF8ET4 -M+00*\F=`X3(-(DOS5334R\HMJ5;_:.;FM-I_G.E>ZOA).*U(^33SM`K)ND)[ -MEY#Y]MH.B[(@]W/89K]F]7X2F(8A#(R"54^UB7Y&/Z-+-P^5JDF)H+O!I1N_ -MPQYQUTSFA-`G2%Z$F>U@?TX9`8$UP*_JF=-EIX#-X%JS2V810Z%SU`+==]$. -M+5'KO6R#^@]'(;>)I3+:*1KUSU[EZXLG,2:#BL7OGH_Y#Y>PN\K&%D@7K?,; -M?\#VR->%02?UZ11.:?*Q`G9>.AG3:+>#)N8S['Y'/(:O21[27_:0QFQ4;0?U56%9.S!![BS^>BEAQ3 -MG\H+.BY*\BHO1'XG:F5&\MLN'_'-D2C[/\UR4Z26'_^QE_Z,XI/?&?AWS\)\ -MEB6'H+;J%I`Q&AG8Q&;D.%6R0P^0ZY7<(Z?LYNW1MF! -M](>6M^JB4"J)LPT@>L`ZF]Y,<,%O2?@)Y;WFHI`<4(`]`IX,^FC=9*CFB!DK -MIIL6533M$D4;2W'-...S$CB[GPK265;6=(K1?U@*4D+[0E#5![1=210%JC'- -MZ(ZODFMMNOC&")B:A2&P1>`H_4@2_]H&((=>!#"U^M!():P0L#=2Q')2?R(B -M+(NOA56,-Z,K$X#>GP'+X1["$F54(^X>'=GQ!P51ONAN]\VZI_D5N74=\HKU -MDDKK^=#:1]GHCULPRK]S/"R-WCH<3.$\#&OI0ST8;2A@`9'-I50X)X39P#&L -MZ`SXP]`I-9,HU,'N#PPE"J680>MHWP'6WNI*CR7O&"X%`6[G,^-*RY,9X\=U -MOC1Z;X0I"Z:*(!9X4-?/$O7Z]U`#XW-E,]/:3M:NHK!E1,J96-ZD5Q6_.^\% -MI.%)Z4IR_1$S0T$I(B0=/R2>96W,Y>!7JD="TOX/N-8BNET%F:]O(B'#4'_< -M+'`!Y[F=I5W'`]`AV:!-\4=BN[94&LRKV(;W7O"/E]-!@E$CA.5O\?RQJ;HC -M/GLOT"L]H>Z*]4G5U(>!U32#!',>T#=!N,3W]#C-$)M9M%(F<;Q55!\IKH\> -M:]6J\8J,E,##U4%2['-J=P0,CF4I5F(;041:U]VU/D^QP\&L(QWTI8JES0_. -M[(^]ST0-:EK]I'6$9?T!+VK+LX+6&.GOQ8GETKXU,TK-"4)AJ&1R<*$34,<5 -M%D4>-T148261,#7U^D'M0BE"`8QFC$JX8E'M%RV['3L8E`M"Z7D#1#SUXQCB -M2ETL@`(5+&$NDZ$Y4U8GSU9IX_TQT7;_0QF">!I9@@;9I["3O^MET$+?-*#D -M6D\3Z*H;_^]Y+J -MFEC*$4_!59.PNV3XD$2B!=(Q'M^Y(T9S\X%K.=>F8M/FCCPOQE$#A"_*MG!8 -M+@4N:^0)!R2-4B6ZYUTZFK3099U>U*L7\##2)L[(.;CC1 -M?:/8'FK$-0\.<*AC<;Q+IZ\#GO9>I33*ZX+G'L0MG2BZ&8$#^:J6P^1BLF#<)-66'_;IL/.=GA3)\@B-6@PKP. -M+]GG@9>Q^^2!31%W8*42Q*N.D#-SFV/\M[(?Z"A?0'VR,)9#>L/B`VY,Y-73 -MK3/R/^#D%M3`"SJB7;"-:;SFKVAH=A6>I[V221<,PK67+N<'I)V/$_;>.;5[ -M&TYC,'OK-I)1#PQ+B#%%RA)J/]TQ7!&H;Y9.KMYM;?MA\(B,,=R_2SO`'YW\ -M(X;E0:)W)W`)FM9?5[+ -M:)JI?1R3--OY=!+5N5EX4('KC>D[8TK#1NJ"_[PG&V<7HWWASC.:\QW]]Q#/ -MYC1%:O[Q/N-//[*2ZS+ZWN(:O$+I^`48]=>NR-#+L32NTF"WD!:!SQ."#;'0 -M+\8Q1YGK':2MEY/&MYDI8_FP1A^(@6G2KWN7WD@0R!,TYKU>&%,1-)CR!]Q- -M,NS/]4>T&,6Z!^)Y95D!QUVKB?2\QOWL8]J-)NMLQM#&%W=P*2R<4N^*(8=( -M_3EE]A(IST%C%#^>)G1:;-QO84$@$Y!S(47KI&\^<)F441%SG14-2S:9;WYO -M'I4LT:$HW8;#SSZ?1.C`V$L>&2-FZ2N20X`>I>2YG1IZ") -M)LV40D>FI36M+*7_'`'.!-Y4/M5YGY&V4AOZXNV;MQ%[%1W#D#,@BKJ+#.X[ -MZ7/ZMFM#W0.660YZFU-R"7!4U%`3?DHK%S30?MU9"1]0DG,^2'SEEZ[.SD,6 -MB"L)]_/W#P*-6>I(JM6;2"GSO\'&;S2LCWJ5$(RT_)KJ@_5MZAHD`R*A3 -MD$C,M<@FR:EA_J#X.;]5_8BQP0A?]-OD^$>;83T\1L')EW/=(0T2;IZ!<[HE -M;E/+D)$\7_!:WR-IYF?23.1WL_6/0GU0!]CI=Y/['&I#[PI%8K7D(Q*\*3/<.P<1Z&IF^=5KU.LI/XJPF#KX,1 -M^Z^`@QPO<+3''XV98&H-,HJ:GZ:#>&LW_4WPLIH.@-DK1L-F)U*P<_6.;S^% -MFIU>=O):IS9I!EB_(ZZT*;ZY-@J'L%\Q;.D?T0U7UA^9%\"7)I7X'P'WI%`R -M^D,X,%%ABS!K"*K\2S*,9V^IDD4A3$['+L?:5*6#Q92J*)-[:2F1_W\\/_Y$#KA+=2FP -M"JA6I51.V!R_P9A/'"![*2`D?NW!X=[%'9&?D'O1!^`%W)_L0?;PHLLHC5[. -MF5+FXQ,;B+?1K:N[#"HBJ@&/3=>BJO$,%\WUA?.HF7^B;7G_X<@VHT@'DW(^F$NKC3BN$M_!;S3V5^L28$2YU=+CWHX7?W -MQ,^UE44XUO_S(=_@L]!OCSW4@WQ,TK'Y2156+Q9NULWI]4+>S_IMP=,Z7UFQ -MDYW,.8QJ7V-F/=I#59&V19(1X0U+#C\\$A\CP(E*GJ -MZ%PLUHP<27A6>E`B<5HHF$:I[&&LJGEC4IFM+#,V-CWEVVL!XAZ0PXFX57@B`SN]4`>_SRSN+ICPGR:E*A@Q?Y/9K2"J_L0V,S$-[P -M>Z9#;F'1/DX9$GNB>@RNA][;U%LR*H"6G$ -M$"<_8RTDFC\B3?IE-""K@X24!,D*,TG'L%%YJ#@;2"9^?Y/Z("%4.1+Q/!$M -M^A6,"S!H;U[U?Y'KVU\<9+7H`12R5`]P6,RK>]>O/NA[,9"*HOB\<<6%[YT' -MM$$&NX5-DZLV[E:/E)&*/OV\K.N6#/J,:N%-N<['Q13D]X\?!![PO92>#1M_ -M=%V!ZF[U-U&EP1^L^7HL-&'L!41*J@KPM-;:#`EBZ-@?QN9F3-:>^% -MA+G9$+&O\O=YHDF_E[2%_,]*'>'D68/#+(%:(-7\O)44&YW1E -M)%]UQ).SR2@\9!#?8Q-/SU69741CD;6,AY+BHFH7EVNW5*7+-W(5L1YCF?#@ -M0+>E/:DE94\81S?B'8E5(VXJ2[6L,0^2.6P?8)7>>.SEV@&OFWI5(6PFI%'^ -M3#`0L$H6]4:_OQQ@G]MF,AJE:$E02V*2J_#JK`4^D3E,,KO[B;#H&%)7T;S) -M=_=@[)B4!ALONMY1(Z^,GTHZV9;@?)+A]<4[\=,\D!!QDG=FKAG-KJ83<2(' -M-=R<%1Y<29ZZ;';KXB=9/V,KRB$(?FB!50`V,,2`=1-?5O[_LJ8>"A19-EQI -M$^,1$&>U7VGXF([U31$+].SE46#*FW= -M^8A`#)P]")J#@"&-6!B'^3OK)RIA?U9]4.MU+"\$%3H91]Z\\?1;4QB(@0W0 -M]*3CB'.S6G7K06SL__.J$*IO%5""TXE=@*AN\YS1,,YIGJ(FORW_]O\%X_,# -MS*59:9YBX`W=O"3N!YDWRKZ2U!-HO&DA^>CG@JQ;@_DJTH=0,+C^8OQ#=-+I -M!7NK0V]77'!BDHXM,!4(;WFN'W351#`""%TXA\8IKI\$2^+`WOZRF7G)XCKA -M`9&6S2U:4K0E_9\BVVVA:<1IQQ*>EGKLZ6ZQ&VK9,2*Y^`3AL&`@^0X(VC#5 -MZ-28$^$GWHQ.`9-+7P\XGII#!#V3SR]N->,+^FS-`V**PX7=T=MEOXHE+&,7 -M0;9E-&XMCDS-XJ[Z.(',+Q&79ODU/>3&M&H1_HG[[G-I0YK/2OVG8>G+9'E( -M'KOV;GHT`0HCLYZ\UF`T>_'5'WH3!0+09YV)ROL -M^:%"?.0MH/WD_\)%_VTUK4&MBE"G%)/7"'+*-9)T%!8D]2J9@H_2Y> -M@,YD<1J>5D#A!HN6G^&K&3P\$;Y]1CHJVG>8DNQ=[PRZ,R#U24Z+1?"0.Q9KL!B=@VVH&6D'+Q#BM3,?S-RA7?Y?."WL3LUA2[*7_2.SICO* -MQW_V0)WDH\2`MR7'HSHR:K@D=\U<%1R -MC^N,/$8;,_/.$`$LH?S*K7ONFF#_Q+^TOO:SMMT97)C4<3U2!EJY41W",+L19CT -M;27A_&#*C65+CCL0]$7F<0DBFQ[1];3R2UYKQUJ]V5\WJE')!VOU'I*9O95[ -MH'#'\O0]II^V68Z,X5=JC)D9OX"._:;(X6PO,V&TQAGLH%UA_P8L!L.2%L>& -MIZB/6`(*JG40O0[]!1?J6\QB^#7(X^TS[CO!D3!F$&[R/F,DK#-ZV.9!B -MJJ"%?Y.QBM:RM7\,H'N=^TIIK-E.E_R1-UDFR+=)*V.O:L")2ZB9@(+2GFXX -MKY1E@K84%U+3L0^F?8"]AWQXN6F-VLJTW^'9_H/5ZM?U_C3<_/K4M4X8,-E7 -ME_H.`:$=74N0L[P;^7H1-8L(9V=L[7DQQETE9M]P"HY8=>F2'`SH2#_^R6GG -MT_"'2DK'U-%D"KJ],=%+6&`OHE7W;<\@[9C)QAC4H4ZZN$8LYC'Y%]I-J(-) -M%MLIBZ,)GQF[Y4%794T,"ZZH4M:IRJKX0`6"^-P>9%7D,N%)8[QQ -MD7SGS8+?1/`*[F,!TDI2P->;`"QFX#*HBV$IMGV_$FRP=NWDV.>4?I*ILB^H -M.9%;]D^#UC^X]NDQI=%D5Z[*/U+1!^PUE43B( -M+TK1A9V;)I8E4QOCZBN_"I#`MQ=0L%N[!^@H,G+LDQ#-L43&!K5^`6C1D*YT -MVKO"DL2VM\4J\1U3S=O]*D7Y^_:?P/616,V%_'6EBDEH9_DP@\.I0/X3[.?NFB8/L33(]"?(9E[A-*CZ/\+VV<"R0>`4D5O_OQ6[JW_QGE2-D(7S -M51[KM/;[1_M9;".FID<"%-K[&C3\@*>K4&A4YV^JT;G1H;XH7PQ.EG@Y*CU6 -M(8O?&+X2>^*])7)1?SE>YI[U:@L?"K?.?Z88%!+WE]EF6YQ';X8.2GL(T[@! -MZLZ*V/;<*C\`K-?J#8%'+CRITEQ?^2(?HY@'?+D:]4!F2)&%O_*T)$/L8#3H -ML7?3I.926%=#F+@5F'1B;QY5&W^#HEB0:[`R%0\?E1QIP7068;:C]_Z8OSL4 -M"'O.L'2RT6@PR7(D&[L=X2VZ)DE=9UN3T4C/LREP+S)3F*4=">1X\TVMVT_! -MKN]7G(QU,%NCYR*==VN7JH):1B_SJ8VYC"U7MI5[3ZWS4G[6G0BC=)MT5SLP -M9W8#6M)#>FZI;^R*8)83XWFCO55C>`Q>"@P6"?B?3VZ8=/;QF9@"R5`-._10 -MP7\X,KE*(+!`&BY4ZV`'];&J\F'PQ<6NM(V3K,%HC(^/+PA&;:+L92@1Z3G] -M,!)$!1^(:+WS?,=�O>J*W'`4.9*ZLBQL?B]%=,4.\Y)8HV,[IQPZJDZRX> -MP^`<9L]7JB.I(*60J,&WV;AY:@5!IA>NIG]&I:.618NT9[.;@`T>-Z2A+8<9 -M*2EN5*O)9RMQ^QL^D]#F1+YYD@K2?>./\#CE[^(%(+&P^HH6)@L*DX4O/A^3 -MRZ4$MBL%:^OUU_W#($%9W<95&D^26FH"(3&E/2'&]>^^T-^7>/'DU\X"FW$/ -M9%%`\7-'J)5LT%R'SQ<7]_E2_M8":]R -MF4B!I??NV"GJ?W(R:?VG>1FJ"H?1\#1.QRA+NL'W;II7U/%=;J[V>I0K6J6Q -M,?7GU+8S!3BI*%$&)YMOR3J\[LH\G;J/+1_9HZE##,1YF8:I/;O.R8]UIU8' -M/%[(WWV#)6WM7'K]:PX"G8N3*E1;8+EI>[1)UD+R$B+2[J+U.ZP"9@1XNBJ@ -M04O'(OP8CA>'P@8_R)8PO`J.&[HUM]PC3C0'WUF24--4#];G]OD[-_5XD9V. -MW(2'5^GFVO7V=G(/'MO>+$ZUJ7BSQ%QR:UZM(&@%,(>41BJ:_A$D_AA[L4?F -MSE.KC>CB$>0Z[:O"8DJ8^&7KP-/[O?VF9PYRT%H50+%E.CXP5<5>CG8"7U/[ -M8/10-T`H_09Z7:=!&`1;=?W%C#Q'4,/G^?IT]#&%$]T/9MK6,TB.'R-&5GM7 -M3#FQ5&&F[9YS+X=B -MMTFB@'?7&?ZX^9'XI:2YP,]()XC$4%?P&V9&YBVU>SFPAPL(`(42=CO5!,!$ -MW@9NI=@RNX;HR4E]#`!B,&.VIUK1;^BTCEVS]1)9&C'%%>BTC2PK%78H[Q5K -M&.VY`_K]5U>2X?_.>8W+&PW8J_"K+2#*)MB1 -M&X#A>]!P6X\"F7`#2DL6+`]`PC+CE!"W#[_Z89\*>AA[\=#%GV%:E+K[JO(O -M''N<[;RH0MNR;G?-)!1@%D;2-UTZ<7%,/;X7)&6JR&$Q/-ZA3-+^=I#"9G#; -MQHIW/9,^;B73UU:?RZ:.ALM:L%\AFF\#Z#3<&\R(,\=8KT+'RBJ*&DG">!Z] -MMK3IP([<]NY0V"MK^/*'K=4Q"5J-Y_A%TAH-[Y8]G6(6UY2,;O:MY=$X1SB) -M/_5-*5.5<9RQ1XB$HT1B^)5YR4B-A#0SL.ZF-9"B$XT?TUI!HAQ/V-PTRC*4 -M)EI%.7,40@V`_=4"@)4>];#^:8#$/>A<;\SB2?Q2X-5[=3S!')EX@^=80EJE+`7IJLYKUL[Z')E$ML@/8`' -MLNWD6T*CFZL@&&0=M^9YI%:<.VJ';OJ2GS`OHFK]V@6VJ$BBBC653H>*<;[D -M8?C4*B0WO*P.,]=)V$D7X;:TJW)1(UY$P()!(=:\V%X0(8/9AU*6S>%4H9=D -M2&,6=9VS#!GAH.>,ZYF1A4)8RG]3\TZ<&F>@B-!'=T%(:>HK7ZYKC"WZU,HO -M^5(+A3]@A;ESY9?:#GW4H><\`,**M5WT75QR`;Q'IE$VB@4$O_\@2-$]E4S! -M$0S_ANC!",6FF#/P3*G'[U#%QJ7ZM$M^0)%II`^?G;G9Q)1@GT;D:#ETB>O/]_J3*!<]7U"`Q5!Y`)'G3?/Y]`!R -M:UMNO0LQ'IYMB_.&Q4O`8*[):PB)\A/CTW/KB4J>LT$>^C" -MW$*B-FSF2CA<&XK/9_I`+?6NT]AIU0ITWB"8?[-;@V'0CBI6I11`[?E==`1T -M6>$9C*20!Y1Q]P2-[.MN+;)1@AG\>4\RKQRF&IN/9,@>B2[-F>S64%N,^POB -MJ?%/35J5$!WG4TWI)@\\3\,;5DZ]+`>5;CX;0,P!+\(^[QFLMU0*&4G4`E0X -MC,Z._$"&KX)#*,YYHR136%7,"SX\"]W4EG*@J38`O.-B@JTGV-^)KU8G%M)^ -M[HSP5'3?L4/GN<)5X@M'FFE07'H.6QT3QQG5.)]G8!$K"4'83I -M\*APF2M0H3_&+)_@8'$_/P-$4^&9#'>;MJ993X:;11(RU]LW]N&SFD@T9P3? -M7MHA]:)W*;T>S8Z!76,!&4?C.-]!Y*(/J^';P4Q&XRE$?E)3H4EJ'L/\03LW -M;[4L;PGG;)LOL45?TBWL)#G -MK4<"EX_%.BE>8]DT+C(A`KC$.M)YMTMYV]"Z#)447H&$1HZ`X_`H'%F:7!S9 -M6E^T4(`O..C6PL^L@+Z(L;^3*8Y_$)?XT@WDET0+V:A&:,KJ-@"LU;;U\]6%XQ#H55@R9X:I;(,@DT:(?#*ME)5Y@YAA+PE'9^0?L8AMEMN\-L#']UUE_?=(_WH -MDNS7P-#W9G>_UG40A9H$)M7 -MQU+`CTVSM!H[31TVH64](L,D0I:@WJUK.J$4J1"`A,6LP1<#1-GC/75XXFD5 -M"KK'4UH?47,UU'F(RN\RCC>`GW:8\1&=;!67U2L%M$C\_@:/#R6NL -MYZD4K"SG(NK1!>!FJFJ^*T&9UWP(L(R/7LWEL2Q!F0_SM>5$C:$8"F-;UG"' -M66018CXS^K=7PBHN$!67>GC2P"$T:UH&.EU:5?M"2RA;4J=IV&Q,%OJCU'3Z -MD$%S='$W;.K&,O$'H9^>$MGK(B1OE^/`&'$84A4U2ZZ;[?,A?.RJQT* -M\L&TRE"UWY-H1\QK![TIG/BS -MQ1SQZ.H,>J6S?0#&9`"`^?NK[B23FQYAE>-FICU^#,H;SI -M#34VH__)H`A\53'+!1@`>=*6JSC+!P7O4,:5A$"F/E78MX[J[RLF"0RQ^B5I/O+,PZCO\5],4OS3KZ&`%1+LM=SR -M4-3Y+BHOX2/--CM'U,N/A`:B*`3N/X?>*"/:I7ZZVQ;UR-$"(=RE"^)@[R$: -M9%#6'%(,Z(T^6TN2"=L*/:V*;F\L1!`BJ5G#=L$[$$E,&KVAQC$?5O_R8[Z5 -M?W^@1>(ZKI1A?#K8H,O-`QO/1$DQBY6G^=>E.3BLIW+1'Z"/``94RP/W/2V$ -M/:#;3@\JDAB":P+C@`\^]8WQ]+:&>W64;**$%6TW)N3?M/-/LAO\S*,3WF#K -MS&-V_*VX*F@0Z+^V9N8>7&#<,?H\CLRB?YP[M76P:Q^`'=\T]-@QX.&-E8CM -MPG.!3:2ZCM0D1FF$L=.\;D30_3IZ2[6+$ED^2MG>C1NSZ*A," -MYSD>;>%DH$6M.Q++NLL(`C^!8$C(N0VSQONG?]$VE>Q)UA+^B78K#;8-+^PO -MD@7`Z@/:%I!^!_I1<7L[0%89X(1[*//PN&)>A;G-J/T*[W\A0!IT -MXV/.[;3^CKMKJ2.M"K+$+R\^]=99V> -M&KVS#!Q!!"XWW!+)ZPPXX=XFI^7:.%$!"!PO_T$H$3;:%)LMA]H)5?885USL -MBY[(WMT+P&#/-V>(O&$>#LOLEIWY40Z:ZU5..493TS3J\\9\3-P" -M72&TDXL5>TCWPW+_^"D"T;4!"&`.V+I35607D&3<4D?+/MSI(MY"@Q(=DCMV]K^Z -M>-IMXEE6/*0]:NM]C;!\Z00XQO -MP!TGD/?O?!UK_#*Y%34*WWKUVE7PQG#F2:K=LU:>C[F#37O)2B^U;2Z&7R^& -MC-ZJ;%(RR1Y6NZ!G]4&GO_PZ4NWU;48KX35ZF\.<'8/E<0UKV:(YGQBA/%": -M3*4,UZ"L/!:@QYUG=UT'>')&G?^B;R`2E+;3O#UOTZ^MI(Z.)CIJI$3[1!B0 -M#]MC7'B('4)(U=;9YZ4K"Q66N\3D'BW^YN,"68W4R3O^:\>Q*7[H6_/>6RE1/AY$N3X -MB^6.G-^ZR35;8'/3%,QNW(?V\QVS^8X"A?M'(2(3HB99@CGCNT)OOXML!"ZI -M2UL[]>R[D=DZ'G&A@`^-/WEO5IE"$T]N;I1Y!UTI"@*0"R138`&2T9[QD^U5"1 -MD$]TI*X<2JJ,"%HD+DTPNGI'1.J,W3G:*;X3$\_T@!,#T9!JX7_T>]5Y`$IXA_ -M?+X3!87?Q'=G@Q+`N75WV-&##)1!=@K1>-2[S`S$!V%N?Q*OP;YS;QLE*,%C -M.0B?MYV9N'NXI[B(?YD%SJ@>!"4FM[!!F$9S#+.$LM\#C0N%T2@2('FLW=Q< -MX`HB6L7L/-4*K&(V8%_@6/?_T9V$@>],30H,SP,1"KDJVS0R,9]FOTX:QF;G -M2.Q6;`$?6"EB@N8L,PRWML8(Z%%;(06RSG;RC2+<:;O^X8&'H-7A`8&1#D\L -MXX/%W%]E2XHHL)/HFCX1?Q;V.=,ZN/F4=64)ZJ9^`$@'0#PDQ:T;-HN!.E?" -MA6B<*>U%*MEDLA]\-)<:B;ZO+CI`.$02`T_H^V[$APJM2'F#8%356'8#P>CT -M=+\7%+6 -M&N.E_G?.X$/G/F:XR=`6\9$6`EZ,_CG09(W?Z8=XGP.[^+Z)BIEV6+S^U^.$ -M7,'C_(4QR,>,Q3*Y[;NKFK"#%]3%'N]>MTZ/[:=3I4K<1H394Y^OSMR:53'5 -M?_7&C&V:H\SMQZ?H4@9_-!NCOU;O0FD04:0'?B3$?(:&Y9^JWS&<0OH]$.\? -M[S9XO;6EY^3:ZD*7@;>%<]M?F^>I;AFJ2>^W^>RT36F`KX)FKA3FEN.WM:&C -MP5J@L.T1O<65/((EPZ2(C`][%L9ZC#?TTJ!%5LV@&?,-6)INS\B"=ND^^]&Q -MK]:3:06P\!IV,_K0^A3#]ZCFY -MT$S=@M3&8Q#?$)JA%^`Y+J%SK@LPCY -M?ZFRSBOB1FZ*L(-TG;<\K;_.K@REJ@[$;Z\RHW.,%J[E:HIFGQ*^L/_#8#>5 -M.^LD@/77OK/$-$!PK[BG$_ER%?&0&N!'_<':](^^9DQC9SAF%T`#?,UIF;.>>X2[4&D9H(BIXI`:C0@._K!E -M*+/B&(JHG";.?VZ>E"G(R7]B9>?9B'K3]=YBRZBBYY0RN<5:4*:WFIPC:K`K -M?P=`I382_V_1UD6ONYZ51`NPMU8^/HU7'@A(:#]$2/%0K(@RQK'Y.L3(GBP, -M'!5M-1F+;(A#_^5$)1$,7&/3AK&&@[??0B8J'W&?#/!Q,3:=#@744%RRI[+P -MHW_05?'N+Q,?5-6@-/:C$M;*J).8=]_L.[Q+>P;58IW0!J]"'(W@1*0YW;"Z -MH<>X"L[O*]P4=UE:U.ED<.2)#W)"[&.*9:%XI?R^O+[R5R5 -ME3N`CTK)LVD7>%:/4:E.7MP*E[4>77_'P"2G>+86+JW&A)F/L0\U!774S$1G -M[9TG^P4I@(,+1YAY?6%61S8-3@HF4*#OZLN9DUQ4_(4^RDX;ZN"%-07<7B@M -MMME3=YLSELV2[B()V$BO(AM3%#A+D,)&`HH";20?_M.M<_0O_CT!/>O=+$8F -M`B2Y)V6$C?=?.J0AP.PNPE!O?V'LBTQ.((,&F-E%/1C'JXHYGZSF_(D=`6EM -M&+)'&'@*F,&F&P-Y2&I7%76T^ZC[M]H,UKQ@=@<[CGR>ZKN2N$A;I5W*<15< -M`P='04H,(07,I,VV/@3;AQED/4;A9T`(5.!7/09WV,])4@G6["+).D[H)'"I -MU6D9A(!B9/?*%!?[4SW%5YAQ&N,SM2@O\32JZ]GW+&HII?V)C)`.U)QR\Z^L -M0JOZ4R7-75H3WOG:P7;B.VTL!@5E%NBAO+B\4,"J&=^]IF6Z5$&3&^9KQ@2YGR=A -M/`7LM7PCD3I9B>2]$5^TBQ!9]4Z5ULHKN6-A94^KMP8'/"@=4'*%$C>O2VRT -MX.LO0D3]?\#F'+G4@^+%J2;'&(<&JJ;>/G`-%L%O#V$`B=0:LZ[KDJ78:Z*E -MU;'<,5FF:)^N<\#-RQ5ETNO%#BY]GPVBSN[B\`X=4DW+9B79TH-XY/?VFI&R#$`Q*WM60D^Z[MV]=1#4B7"@S6?,- -MP7[O0+0`>GQJ!!M);!^*<9?"N%.)#(&:!X)CHC_Q%\L -M7,)#$Y92T+,L)PNX6N[.^.V-MKZB'-.@J6RI@`;\J0:XCSTPSW73P,N*2UDT1^O!0N%BXY8LF;LJ8"[L: -M-1+(,U6G!'+4U:,+51P!VTI.ZT+O)N#U'B -M>>L0K`H\CJU3CR\N-7SB4PC6<\7>=A%?W3G?PWMZK)IN0H(+SOX48:9Q^772\:ZC))2;#Q%CX0QIXM;W:6+[ -MAWDBS&X-+OXC',?5Z[2*FPD\?Y=C@SO40 -M!1J]`GRLER\_U$\!^6%H2"LRHI36Q/LMKAQ#A:D$+P$-8&RX.&8_DEMM4/LI -MWO[V>4U):3D;6>5W+`5E0`E`2S#3%RD'XN#PHVU6[E."?/VG4I[&[-A^JJE- -M-)^WVCO_UC*$9;3-5%]M`1T@`?3]J7*;91&M"'6^$2F:J#DX58`1GGFFZZQ- -MW@5_JA]?^]ZPTPH5+EJ9EB=2^U'VC5[[7G0>5HAW&W>7=->X^F:W'PK%S\I# -MUH0#6*2L$J5O$/!Y:NU5GVK9O1!.`-$&`&*DH[PW!\F(V*D70RC<;'=?868O -MW$U;J)8[RMF1E5KW$I?S^W,IEE2_G:G@-44*`MP1KNL:C;[W[YR3*/]O!7\& -M="0&IB7F"H4NC):L1;,Q4C7\,))"_B86.,5MUR9V;Y1$YSF354IW%C,[)K6S]-SKY?^ -M$ZX540E-4KO=Q;E,P\=$=8ICUM,?B8U,,"TA\-`NN<54_]-93.[MHB`PIUA_ -M'K/2XE2OF?F_*"((+34IP=OWXGF3N:-:155-]=PG`F0I*FI[BA0,VFCQ;]FN -M"<^S?,7_9HRTJ!?#-28$KE7[W-,-H[!(RXK5[VD^8DAN9V>TR`)[5YL4WWN) -M@7.D/_GVOEL[X?7Q6!Q(?\4(=-*C>2,BZ=_WNEI1.!%?4,R^$==OQ3;0@,B< -M8_+B,T%4J8]VF^1@`8$B0M5G,^D:,&(0D%KX!G8VDU[Q43CI:%@@1GO0)2K' -MQ/POW@?9HCU)>B2S2+@2%K!Q+UT`)M80X0E]`!`**_I:`?9-)W9^E'L7(^>H -MA-D>CO!#DOM,N)H_"@ES,6B]3E]BHWI -M_04M<;[^1$]J3XV2]+)],2ZY`M>>WNUE;6.`VGPW.8ILA(0Q92JZ;^;%-?:/ -M!TWEX:ND\E/0<8.2'O[D=0B:E?=`%[E -MJE%LEC4_\7B)TZ@$.KJ2FRO_79DIWDA^1D24>G_.[9AZ%7RT?@*E$-A^%PVI -M,9X0\[3L>2)$>(#&4M8D7A``#M!#+"Y<+W1([$N=.=A!;]N=M -M8)@MGGY*2IK.GVE!'%#J^(.OZF"J7[VJ+:]&2>D+9O'J[3YI-*7A9K3;IFCV -M_!V3ZUL$<"D7;$,9#CJOZ,(,.=+EP%/>NV"RGHCJ&$.@H(Z68I`_C"!N`C]1 -M-/FWM5HU'89=$1ZK3&/,!&C2?(&:L#JW@8^)_.;T:!!G+)-(K'D]R*WHNZK/IDB]A2(;5H3" -MPT8'2['D5Q/\D^#,L+)C3,5U5ZP+@>^-&670D-:_DC'MT#=/%>CSZ&.I/4^R -MVWD^Y:_IO8;^H/\)=X"Y%@3GB? -MW'`H]8M'":+ZQF6J6S>LHZ+1F"]?^.;\U0D(F/&=JC_ASWE(RU&J^0W2$,3Q -M)V6&[!UH+WWP5;"`XJE4Y`0CK!P+0:#W%S*+4!6#?=JO>7<-8\4QI -M5E/2DM%260.FM:%+?4'-)@"UV?6!ZW/6/JY^X_0%&/ZI!!+X^HQ3]L$G -MKY.%XK*G[>PHG@)S2_+N&,K`M_F,S8C/B;:BKJVA$1C(288]I51$XT+FT^M2 -M^"M=+3J@M/T.7(<;I*XI!6:`!60)5LT!S#EFVZSWK4#3E -M_K-FCO+9:C4.3V]\>)&%O,GI-]FQ5>?$>1T-`$BX?5-OX$\3O-Y6=F"_2+`! -MS:_5\OV#(R):A%Q842&<_-56$!0`)+N)B9-GL*6?8*Q?)KN]B!>7*^/V@:OH -M65[?OVW1[+>[!?^A'4J'+$9")+4^Z+KQHB&3S^8D0T:;`TR&G\=N.)7I?$Z0 -M?VBNM%&TYMIL2\MX+6=C+?8N&YE!U'P!*KDXZLU,JP0PX*1'T>K -M8",1)%?+"$NN[)WD'Y2Z-$.(L6V'QH>\-ZB&$PO[K>GH'@8]?6HB>6EQT=&> -MV38:3A5N')*%G0&,UP0;<']T&>J*`@ABRA[DRLU:0H2"LJBC4;70`D*/E -MBDC\>^4)5O;C'.$ZR70`#/L7G?X0)S#W4^@?V:^R8G%3 -MP=S8!9R9)QYRBFZ.9J3@B""R/H9*5F+B+#%/UR(`X(/YC#7D#,UT5$Y),ML" -MT#XLK1MB5<#?XG^WUVTN>9#N.TPXR -MG8-0[F?FG\+,70[$:Q[!:4LH96?(SN@==R@J#/+5>*31V$/ENG'W,F)/TZZ9 -MXR;AXW3D%*&_;LNY/OEX#@/:%?/JWJ$#JO^S,\X(N/H>6>93M//0`6KS_0P0+_. -M\R&WX\IL,Y]B`:^!%8-C+J3XHT4#Q=R7,X?%;GU8/+=##TCY^%LT`(?D.0)S -M7[%L3/,B)]R9EA3A>CT9THHRMN_P/\44Z1_0V$M:=@/.J%`,P8%X28Q(=J;9 -M*8;,&]!_4W+Z;P\;;F.L[_QKKYS4I?]`EP\4:0(@ZG`)&?AD-"^+HEMT\[62 -MHJ9#GF<56OM/:;:/W\5V\JW36KS]2VV4+MG-YW)8%/4-)?!=&*-SE>V'VSA" -MW(F9V*ZR8H)O%H.J5:_RP:'C4;V..-9/HKSC5,"EAE9*.=2$1U[U1RP>S)VB,@RF\8`G>7%I6ZWYTDE8I72J_+@S`WFHQ-858Y -M7T0+9USGL^(^KU1%8@(H%>@CX9,/5A`[4G]]6:U=)D;1)OG?"A$E4_Y9=%IR -MM&Z]<\_B6SZS<[=T['=)1_F=4#KX6.F<"S"E<)&+ZG&0:L;@I`*)T`1$Y(10 -MK@FPO]?<^#L4MY9:%5DGF-(I]H\-OSRD&+Z@MVC6<]T)8T,,NZXY`_BY(3R< -M*F52-":=0OK.Z^L,.J3KU@_@1WK!)9J+7>ZW5B%+V(:''=:@M+3;E>4A<`Q: -MU[%+7/P'''M6V/;+>*IG2ANOA3+\$___^R"]SEI[&D%,KZLS;\QE.3'%_I%* -M>H]'.SN+0[O9J&7VZ]V5T];0L6Q:>1F"(H5!55@?-5(LY<;2FN8LYB!$7G'( -MS2R2T\/<6,.?ZCG9D./.MAGXGPQT^*,DWKU=W[A`5MROU;:?MVC\2$&5(VK4 -M)LBI&P:8),[H,R:!B$`-CI+2Y^L\9_;CC4?T2>H<)/&IB6&RUTEW5+P/!3RW -M[^'`,:0Y=@I8R5U;(#O7]-;CFB3P22MDYGGH2P;^"PIJ=9G&FTTBNZ*Q8 -M+NMO_X3ON+;`!?36"F]D,S;N1(2FB>.ZH(#^L__LY(*"K&8F:180)EA^X\*: -MPO'.S[V2_!A,P^V)HB<.JUVBG>)S$5=BM*\P-#1B_B7M7N4BBT(S,_RL&L07 -M'+`KT`O22?*2><#'($OZ)B)?.K@6"X38[[UQ=1FBO\HE0Z"&A)U1VE- -MZ/>IOWAJ"^F#R#DO1QS1LB%(FED(]"&C)N@&05H7),1$61'Q^9;-JV4I7,Y2 -M9/;OG3?:AS\?8V_N]63(:@>O)^.D9E)19HA,F0"Q=K8.@MM2,;MJ(Y;>M/E\ -M$;[[:@,8_YS6';FG",Q'T9O4TCDJ0ZXDAJ;IN.>(:\))M:4.'#[GF>[/YV^2 -M%?(VT+18/#$-`\]IJAHL?(5?G$&Q@/^E[BX9GF@X#*35-71P!%J-_1/ST\@: -ME4F]I4P04$N.C11:@O68$B0R`F;M5G\8VD6Z-2%[55VM`&\U>4B\VU`V3==2 -M>2W(PQ7>2'Z+85\_02T[A!I![K>FT$'!$IK0R8Z&.^<7%7L3^A-W&+0Y'`?C -M"R._FG%8SZ3$[@4[#F2;13M!ZSJY><24=JG> -M>X!D[11P(#P`*Z7:?0"F_"9,,\UO-;S,[+G;/#KA!/P-'+,-D+$%>C$K/7#* -MK#W#\=06=P?+8\>\44KV#7X=?#ND,LPS7MAI9@^9%2N_P/"B:V*$'FT=GI4( -M1&[P0A*9^/+<@/R-D<7V:\I#7$YT"8,,2JIB*EFO$AUQD2S8CKH?=BBNJ4Z. -M\@<"PNNZRH,;;I:1(W(K^C[A@A6N8?P@*K.#2^/ZNSV&Z0F7WD4$9VEOHGAY -M$)3%I\UT8%8HU(,A_P=EKORPI4]W7X_5B-(D4^=#/N\=ZW7U5`D$P9&.H`(4 -M@.9=J$@\A=]O)]X_VR9@:3;S'B7L -MSYF0!O,&HZZ8#Y2&0^/[-]="=.RI=7,RB=U'FNK&0T&Q$-#3O7SI$/\,.?WR -MJN7C0'_UTA!S/GP(R\4HCA+OUCNK'CZA_<'U>%Z"Z:7XUX6X;\)$;RO0\M@_R",_25`G^,*5?])QSF2]$,-VT^S\?JP;#NWT_87* -M(QJO;N`:=$MPUK1$VU**V@MN812._MUWB$1,&C,.$4K/[%8 -M2BOYK0GD\LS,7!_!3=LW8,N^3B^^V>&L)L^NL^0GCXR*?5[$E=8@00D*3NZ5 -M.'T-!C:[O&^>0NNN*ZU?']+J$IHWF;!X=#A'N"('?<+'_J(_!2]JJACAKH*%I -M-ULV-B&VD6E_5]AJ*%BX]`Q=9(+E7&M3^T34H33P"G8$'?JWP^)P%N]K@;X, -M6@`5BAP>F9-@+P)^4XB""_DZ9T5_Y(0.;)B4-G0+AK&0XKV)`*36#P?L88\N -M:MC.$K[BST;:'J83$KY>-;EMH&C3G,S2`:B([?8$8K2C+%JU]IJ)8TFE%S29 -M<>>B.S\9:0WM!_/Q):G4)5;_?(`$95RFVP,&&2E)T"\4D]AU(SUF4J,T41ZS -MAZHX>$+*@E&??`AU^Q524$T.0RBE-KG2&/)W>4L'VJ8Y)+H32:P5PU/BM4=C9O:A -MP>UFU<<(:Q/2"=6.[2A5<(*O6;YE0>A0"K"Q`4C_2R1,A#IUGPHP/;^6^J;7 -M]@S4*IC);#+1.$1G:M=57\WV!V_C'';$4GW\SK0EH0FD$H,%A"/.E4Q?;J)\ -M]#%O^/7TRL1IL^?,I=)7$[5(%8XJLLYMQY'!@A]_/D[FER4CG(!6T8B6:S\" -MUCHT&)Z0NO&@_9G:XOB$+^7/BC]O3SQQ($"(,6*\PA5G,B;^DY)=(%":I>2! -M;^DT%!4$4^CHA'QQ@?]/[>@\IWU41E]N;9]IPP=?*[H""UC-/?"]4+G@YLR9 -M4$3.P.[*!+Z)9DTSP)65U3P)*1\TP8GPXU=-QK'Q8@JA.OQ@N]5EL=4.0;[A-WV!X% -M-3_?)@/IK"JZ;"]/9A-4=Z"-([K*I33/S'$Q_WD*L0R2Z4.-M664[(!VO-[G -M@_4D"WDV6CQK>]47Z-G">76LR(.2'Y?('G`\H*!GNL1@K8?>5C[K% -M?^%Y@8M"\89^3AU*2GRZ)CT$6Y[UY)(K"QZHNY)F -M!$/W,HU/!IF_'Z9N2V1&`\'RM,AA?3_CJY3YYAO_G0-%J)4%LZ8>R^E(_^VV -M'@BDY#8S*L$`P\C#E.@<3VX,!7._-SNF^3=J"K%J<__*;K+'/GL&X3?:W1O6 -MUX2"1@*"+/, -MG[2%OV$9MZE.8-Z\_P(DC9M8K(0_^"H/FP+#W#SF>MK)&0B9Y)+"J#DVG32\ -M>O",A.*MH6YQ-'4WTNBW;L.<2ZT*U5C9):;L8>\.)>B[>GN0R41&1/&B!0N? -M\*JT?'LY`^GD)XM0M.O(+CSV`:0<]&7^<2,KT$G<3^6S_((L&I=-VF(@[2^8 -MT'CMU_#_IO@+I+"4B:6>:3+]T$01HHN@:WC^$5]%, -MQW6>JWTS2/$G,G"#JS2B=4BIQ!"D8)L&'^X_:[L.EY"5`:%<0G.[6JYN8D<] -M_P(;K<_>?(OXD]"#)4`@;E@H!(._&O?*)\CGJ*"MV))]<':S=OB:Y"@',)"$ -MG?1*L`L/`,C=PI=X1^LNL[?OS=1>/51?RWT]VR).B%C`-1_)20VL6N@=O:?R#UNQJ8N.-TLQ[3OUA;`P:[0.F>%0J@!_ -MEAO*PXKWP#T9_D@WOA?'U2Q](9\\FWZOI<&3T29Z;N_P>,6..1XB-1`>'`NQ -MIC\N+G$CHE.0\E7B35W&CMI83_`&\6O2R.6!LJ]%ZGG>MQQJ<)<=@O^<\-ZF -MDKDNZI.^5?\IQJVCRLF>-:U:R@J@N[=_FXR[HU%BG@H#7( -M3WF<-'./A;M!_A)3VPJMQX'Y)Z`CLMP! -M`'H#@/_/^IX8)=Q&?.F=^1EJS=+REAS-X7E(Z^WUW>SN-='%/L09$^C!QKCS^]))X+VF3;IC::OTP\$;YX)%S1RC;@9W`YZXX3 -M,7&Q%T/%L7`-ZU:^41 -M+186(CD:NR;LRX5TB;@W$:Q3ZKK^4)>6F[:V+6+;_(,QHY!+72_188/+F\;: -M`RSA2?@Z-8@DX8BA@2V:8[J]C -M"BXV8G*Z@)*OQU4-L1XH^@*G>W1.J[]^;/)@\XZL84I!H.?G"$2.^#\:U/5. -M/&M=@N_K(ZN-\&L9)DESS[O@0;! -M9GH6W0"TEG$`M[MC!\F^5`\@YRJ'H3%1J$WUBVA03/A+C1:P;A:+%'IVXD[Y -MDS)6KD<'FL!8L4^Z?584L.3B6V_9(J(\`D0TAA)Y=O@M*%-224_&XW*``GF+ -MN)6(BUOZ'.YP;KZX_?7,2J3TV'ZUB6V(IRG)P$B)&RTD1QB+H\VAD4B#9%X7 -MA*BJ%J?!^RE\F5`H75VLY9G=;[V(SSM/H07^=E+QVHC7BQ'D9:_:38U6]VH4 -ME0,.J`+CVMAH[(&GRM@YC2VS36OCY#Q+H14R8\%,>R(`F4:&L+FYHEN[ZWE8 -MO(7VC!"64OC'#\%DME-4:8IC3=+$+JV/94W5UTH)[@D9MTBB1#->^$'?%\C5,'8/`-%J@+QSW[4O\9D5^J>% -MD,X$;1]D4W;K4&8XUCQMJF,I$??#MY7@RT:8?FDSW,.\N3)^5_G1Z_2^1Q>3 -ML>(_ME>O/OS8037B]7;H2!3A"$P@D$H]WMA9:R>82'#='EJVJ?9N`6I\P&#W -MPX]\7&3O4Q]9H'^VKY)M(AVSS&V4XZ/7(H?#6,==KP`"\T.O!_8N''6_S/RG,>;Q$'+M`70TAMAR0Z#9*O;%V`]+,@Y -MPI+HJ$8UG6=^I&=QYSHST=Y,F%^#R8Q+]< -MVL"*&.]NE\B=YO&ORNP3/\M7+@`"K85A>L;X>><`ZC>:8G7_&B0,I81&.BU6K-0`Q/! -M7VJ0PIP"ODS+#5&@'XD)A-7R?-H%#$#0UTBUR%BG0*IWF+'0'LF,Q/(*XILK -M#`\!\53-#Y=BK-?4.=IJ6S2`4*O([QVTJ.><"-7*.H+@Y**;[)RKCR7+WPC* -M/:DUVD6/;**'@7:IW::=^W.-U- -M_3IN@W&#FO(@?T`_,2B=@`4BUW_/=.A?.912ICXWI-+G8BCS"L0!2G:[ -M+4DCV8+8.(G`8T7A@E\6=G[\'Y2E]4&V39*(NQX+H0G&.#]S7M#H:BWEG6[, -M[0(\.F:J/<9(@`;L+TV4(66OVR;U.P3612Z+J-E_F'#!G!2:`=B63!Y]3!]( -M]/]ZQC[Y^#"'5FDDL%!\7X^&=@ZWV/W.@#/GMQ1R_L:/O_80WDQ6K.P,(Q1P -M^]OFW&^KN@:%FMJ_4@P,BY%F>X_#'CM^'CI1KFWXDCTG\*[J.OT(?;NUG2VH -M7!:#RVBE_RS>HDJA`,4Q84%UI9.(7FX-79(VWLY?P+WJ(@*%%K%+/[%O5@!V -M^R#8VMW2=6,K.:-24GC\(RVR$`X^1GCV9?[W!9K]6U#MF_7O"%0S>!*`-5%( -MRK+@I9!+/W&2,)+Z1&+C">M)0"N?QP9)-SU0.K6T`G<.94E.LR_0U:ME)>OO -MYL-YOW53E$Y>Q/9OE9YP/3WD42>G` -MVX>.LFWAK"?\!R\8'*DMIG/2=UUO5!F`I;`[ -MWXB.9\U#>\DV1L(.G.B)KLL9P_N+7>C9*L#'W\=M)%I][H))#\:!R4,QN`T4 -MY27T)OM%_3$W:]0I3JB.4);GW7(IA*GG^V^Z:28?QI'FP,I/S=)M,54&=;-^ -M\T<^[&D"LVO+_)%&53WO.NFE7.`WM\D]F8K$-FI&5J6(&&7CO"%,M^:GVF_< -M`YDH+?6VB=R-=2SB')'OA4[8QU.35^ -M\:UOP6_*OJ&JA4+8.XV=/V&.!T#=B&A4`5]MP89[ES!P$?=:O6DT]PY7NP;E -MN/:51_V"E5%/8_CB$-C2E9V^5,]\?UDK+BQ&6&24KCWMS$FM\V8#9_SA'*/V -MT_!I_2I1U`35BY(X'?=PK!SFG9_%NT]:T79YRU,B&5W`"H4>8NM'-P?Q@CK\=.^<.<&$X"0P=<%9J-BU*&_*? -M.'[$E>+C`XC=E3?@@;AH2)B.?8-V*=S$;I^@)?S.\#/Y6N*MV,[*TT -M/(ZSMF^V=&@C3\XI"@Z`]K/*BG!IPAEQ[HNV9MTW7`KWUN:GF&ID8PH?.+!! -MOM51^E*`UW\,6H_7O:N(UBM411U2?2W(UNOV*#6OSA0K?UL:Y_S]."`?N)'Q -M;^BS`8]S-)7O3$B`Y6/[DV`1VCY*DI`P&)T:F!1018M+FOL3K0K*H`(*H&`" -M]XX&94VP9Y,3EY -M*7*=C[!1RF=!D?UN5V8O/*Q1SMIYD"PR38_%;.8L(0#:A?W'!8<>E^\X61B! -MWD!CBQFOCRJQ(U-]O`*&)QTL:7'>+3$>8]0[Z^C+W.C@#X"HR?Q1P@W-289:V,T`W'U-J*8KSIB"9&Q;:9,\'&0%Q:M)V:*>MZX8)`0H\72V -M>I?:*OA79&A@112DTH;-C7K+LSM)8SC#*T3?Y7\P@PT(R%"@D -M_;@T`]=LAK.(LG6PU%!F]+S(0IG]$-N@BW>2@[PI -M^+TJ)E;<[$)O%WL?T["JZ"P]N7'@U42Y-0%BP4F<%H4VI3GN5=:9W@*VEH`; -M?+P"W<@J?/_%IS#S-[P*,$LQ@'W%E!H&0<_6I\N'6%RA&XVUC:E+ZP]KQA%C -M/Y#?A=H\9T`[CY33#C:#&DZSODG4W:W?V\PF5'O>L0GC#4&.1]H!F>7AJY_& -M4BZZPJ<,+K=<-BW*B`V><)IW$S(&EG)WILL%PI?01Z^'\N(RCX"EN7'+?K^2 -M#<_F:4<)3/"QQI=$YWD=I^Y[ZI"&[ORQ;W]S:M:`XSLC#94!V6WNX")KSQ6G -M6%J84[/U/^#@*^BO^S53UFT*$LT])[# -MC])KZ:8/+`LC^]V&+=Q0@+_M7*Y!EN;/O37$K'EOR!N%IC0?N!(GB$."31^U -MRQKVH]->.Q\O3Q>.0L\U"CNLT.T8+OF/G&)GP`VKYRR+.P?VU[GH2EP+F(G, -MH$LQ8?\M\@%@&FPK!.`CAXU>ZTEO50'@:66V14IXRE=C)Q_5G$74^CCQV<0C -MHB`<4[XRSA7KNNH?E]BC4_HLS2!I_WFW8#S_`OT?@Q'6Z1+V:V!K@?I%>^S: -MQ_%::.%Q!7%IKA`(AO8_?C&L/PY*J4.;-6,-T>S>>:*QM974B#T2\39*3HG? -MV6*6H#B=*ZE].5I@QC,.^X&`Q%J$EMT4H.&G1=OO-QWD*?G:/),OUAO1UNQ. -M?L`?_^D>H\X7!Q4?K<-CC8MKY5RL-3'TH\W]IBUKA0L[^7YVIPH/";=9-DMR -M?;WB-VSXO%;T3G>CK30'N[$Y<\DEK+;.XO^X[+[DM"7-LAD0';>Y_5TI7,Y" -MH''3DM40MLQCF[S!,2#+K2ZQDV -MOI^-J5DA/!5P5RW;&V9.K-#3,`!*=N7.W/C=D*W:>5XK'>19H89BDM@5[^M_ -M$'9JJ;M8$:U%M-]3JLL(V!8=:-Q^(34J3$'1VQ:@5B6'1;6D++7UGKDIKW#L -MR_)1%`V4K:";XO -M[*5X2V!12+Z" -MKC@R>9\XQ?:VS_G7**9SN_;*6"2P2W;A_]:N+3Z2)U6.;+^&?2KD,:MK'A1" -M"\XLXU)9Z'$@@.U?GG8#$PF4;;O^E[(ZBVV<)H@JUSAX[QF=*%D(]/,]P64U -MV'>L?.A+>CQWP1^8(P15JGL=!Y0F(HVEP2V*?[^#+V!+?2QQNAW@RYS%'T9? -MTV/F'"+S^EF8I`-ZOY]EZU*1KIXQU8.3N$!]3*0(%O:!+`@ZY>F3\"^WFR0. -ML85YTI.DP$GS^>&I=DS'HV*`5Y^7LOR!@(9;;1#-$%!5TLEJJTUF\HS#5GA\ -M0U*R]THW$::[^YX*:U4*ZCBPJO(E3>-Q6ICD297ZVC$/X@I3HLE$1Q`41)S$ -M\$"U4US]R'L8%C/-/:%`B1F4OK%]CCQWCP'FE>FS,]=73346?T(ZW(O[EBG4 -MI`OX(LZCL3/,Q&!1Q6HE,FF2@L$Z5ML[%FO,%.64KERF=F`4KHTEWY,Q1P2U -M0UR'"TT([_L;1KS[.\\1FM"J9TQ6/%@UTO=4^ZWC;%HW@8;GE:N+IH.T@S\0 -M85VN?H>,@D=-CI4,TMUR0G-+\&AV0_+7,\8L&4HPSAZ)%L35,_66I%](G"/":!V*H%ORKGG@+SHA)T)RO#@`'!B&ZT2M9=.;D\H8+)WABOC__*,S6IN^S#Q(1@2LV -M&_+^(YD7OO/GD\#4=L<>2=Z2/G(9I9?.6HGMQG""-G5+=MIN"TB_V-K_G)^BB4[=0EO:18"[+[:KC)@#BB+R9S7EF27 -M]&#PP'T1()I*H:S8X#A;Z&;$&D.C9-'P`(9B_Q^5^6["9N6S1(FQ0?<6C][< -MZ-G9N>U0_"DSMU..!H6\2.RR%*_FX*4V)N$.EN=:>%+'$VZ13;HI^D_2CWIZ#X:54C_R\>8G0D']L:$D-/#SUF5)+ -M17O%:R=WGKW`U-)6R">I%)F"99.5TAS2'JI>%<*DW,*(SZ.Q;U.HKR5^O;JW -M@3_@=]2T0"8(6%25NH"WJK@/@O]BUJ:`5&9"G62LXFA6*%\>N%9W&JVF9[(@ -MHEWF:J=TS&J94?FZ09>(%S]Y5>S#6821"&Q7VL;G3Z@DPFC8/[L,G#BFS1U" -MDL'LY[RRR(KS?T1$4VD8IF -M@W%4B1@3WQAN$AI)TSF1XS6AH33QC`>1`0@@*YBY7IL>MW`UC#VZ -M,Y(&'\3Z6R/*P<>8V-AJJHOJWK\VX[P[@@)/_^1(U1?9#,$1#+",_@C`,T/0 -M_A$GR`*U2<9_:'XI75`!P\K-JKH-<-7HV4O\D-VY -M@4&@M/26[#4&S>QE!4:IX'6G01>1?HC>14`"[8#\S]N,L_&$/02B9IUNQ87R -M'U_^+\**;QN(#N6`K'U+,*^R;!:2="^T)0!5>.$]@QS==Z>)-&5A]8U(WZ6G -M:]RK8V#.,WK:#N<^UQ?Z#)$NSPR)DQD1!5>X3Z4QDBW4Z]%8W']:;>(.YB+" -M'D?5^0-0%*.IL&7[_E[WX"$Y(CO>WJ82,]V_;G;:/>EK`'4:. -MLZ[I<#KE=U$J$5BXZT#)T.@?"*9\Z;?C"\6>HGT&VWJ8:'>1.-BD!1[*6^E^ -M7]%T"`A!DY@I%\-&]FYGH:]W,=2$4J94H?[WP -MI`'7R=P$D:0GAOP<1SLPPE'9=J2%BX@<'9NS:^V_+Y%_P`^#L(K1MK5NZ_MI+N)W#S5!G= -MW>H,:P/%P=1"IWJ0#C(M7."Q9CRA$%=]IQZV/E(S^FX*1/X^]1/1.I!L!(0. -M%<7L+^Z.8*_-J%^8QLL;$%W9=(D!*<#N$LPE[-R1#@,C!F*[14>R[(+7A6 -M`FB*=*K'>094V"I[+CDR(O[+*1K0"H^MOONTB`9X38Q1Z.V=<&3]Y#$2-4YN.6E&2K`@NGNV^2Y(YYI!&;%6!J,THDQ8[@\BA -M1EH.$QG$?5.N1K(7^#'XID+T3&@-:/.=%/J..@.$?478^FZ,W##PZU5C=>\- -MDJKZ%\O^-?CA0XS+R4EZD)M6$*OM[*0$2RKL=JIN)L6Q+B47@K(#W*4IZHHD -MQA-W.5,IE8KS(S@U`7)PCA^"R`?HRFPTC-4>@A$PDOP.1&O"?$ESDT.\]Q]X -M(]=5_7TGDA@G2]C:69QLHYJ(?1UC:P+-N=@I(>]3)=`8 -M,_E%ZMOG!_#5;Z!E28F8H;`JLC4,6M\SV-B[X9#DX<.O,,_H#6A4S1(LB6V/ -MQ`1;*1>3=P8A^NP!L\TD+.*@W6WMZ5*FWX[,)V2@7YV!JME"KM')@DR33M&A -M95/.+]%XI8/C!%],-&FI]/Q\_MGW+#:&?\_R);QQ!AD*>% -MP%,,:]'9I/D39-<67MN3;[IUS*6+`?SB8">N+%SZSU%I"HVN2#5@K0OWR[_L -MN].SD.D)+J\4/H#]86+/@"NUD1=8?JI0+.V"]DOMIGUE7]M0"K6%,F2JB'WB -M[[K:JW:QEWRSW,,L([W4UW\@"7C>?A57%#K(#@GXT:%'<@# -M4MAV>`/+E'D*VDKD=Q*XY=,FF2S%H?/^OD6JY-0D.XZ>5GR(+/^T@X4,.8=W -M4\MW5SH0(/]0R0/^*EK!9N'BT-*@KR=S`B^2.1!?]J3"I9Z(?3%&H#-[3\*_ -M.83K$>U3C*%OQZ8Z!ASS -M'/UQRK;4GRT_K^G]^^N*8S&WG,NOU6[IJCG8KRZ2,R4 -M*?MOM+E;\VV*:+FVAWZ=_[>&H%OQ-FFLS[]I=N.8R"NAF%Q*5R,.QV@YQIU1 -M49,U9G@0S',/S6ZF\3ZZO"<7+0FK?!-Z,M$H4O>Y,3CMO<5-IIA@K=6KJZ/,QC#2DOW'7HB#F>VS=] -MONVP0MQ"O5\,F)/(0J(B^>]=3T'[E4E28=Y>P?.3ZD7K6KV!#9=W\!RVP@,Y -MF?%LHQ>9-B`^M1>:*\]@;7(JIT'KH`'CH!9Y%$H9@ZD;-AX:C_Z@P%`)&&9V -M_8==_(T1M^1M18NBR`)^,4R)6A9D-5YP@QN-JVW((V7D"(=U)2I"AI3>[?Y> -MKJ$O\I]4@<38=UNVJ6M03U1S@[V#`Q3W$`17R5Q\A=B8VVA\3I!AXIA/(!TI -MY0YO2,:`993\`N\L1;\VX.0E)Q*T@I]/X`G[R6EVACF#>C":8!/.U0,3CJ3* -M)+]OKJ:_]U&@DJCQ*"IJ@R\;P.6>>.7GAM.3JU(I9!6 -MXFKS2HM.%8R^/#>MN;QC)/#M7.WO2X`4CP/,],2>VTB:.8)";$IC&M&9O:_F -M=2=/_/#'<*(B.8)DEG%B`2FC,\E>XJI::)Q.'H%3CT0?#>F>\=DIH*RO)\?I -ML4\5]%N74Q9!G/1IFRW6 -MQI&(ATMYXA\$_@%76NP3YY>H%"5[W$IJ]-)E7ZT".$`7U%!W!:9^7J58/\)- -M,PHJ98\;NV1@=R95C-TP>@F^?'+GT?_>(9I)XE\*H66F_3*/Y]ES)OMH;7]^ -M]6%*=M/55I;H6(=MM]6&4:*S48$1ZNL!/:C!ZE43Q5!-`N^!#&4:"L>@O\!W -M0/HGCQ<*55`6OMA)*%P,6]C;6[H\[G=AD:C[RE8Y1B,]#3H(*+5X)7\&5*@\ -MA1FR353-126*0'L4AF+C8C__!K+K=(FO'QM"O&MQ_U(,TY@ZK[\X5$X/I4D@ -MH>W1[HEO;2Y.JL;C[2$!->^Q;*(6XBUGCA(`P\K']B*>>'$E$ES=+6^HG;JU -M7;GRSFBGK8X0-\0`[BY7=>\_@G@T,O8S1G3AKA[XX&SB%I -M<)DPJL[`+K"W2R;:OA9#LV=(HR<)@+-3\Q&6D?Q8WF1L>@MQ7M5/$6Y`SX<, -MW#ND]@.!@VDANA:E>5SMYO!L!D;RZ);T&#N<2OMSY92)QL)SRT1I\!V@Z"9^^_$!ST<4?9CLU5457=*EUQ@Q&E3S3GMT:CT -MV4NV_"ELX-UNR4$`=M5SA=%,[7=_T5GDAU(+DK=M.@)Q#\W/8)9'DU(12\\C -MY8Y0-CU)E_Q[4W6U(3G^M%(Y[SHA6GLZ"D*PV.F\,F]LOT,$=3QY7HO5\4,9 -MW5M%#5-2M;'J@RL&5EB@2\%2-)\?E#I35+LR?8V%'2?>!=*_.RUI]_#V"V)5 -MER_X>?EE'/CZQR"K>0L8%FZK=^0"8M5-N4"*3?).&ZASV@->)D:NG$NQKTRZ -MCJGK=SGM?X!T4,-2-1.@HIF;;75!U0Z>?^9`*54;:NH40P"4^0:X!59YTNIL -MS7)6HEF$[/KG:TF+7.9V<]0M%$25HT1NO[]:5#\"TUM)"4/SL#:7718D -MA:'2ZR"KF[%D=];(C_0/&BJQ]D=LY(?RE--[:I^_WD$DD=:`J[>)'@91.EP] -MJ5],*K]]\B"VK"L_G?])U4&R+O&;40(7J8-"`+U8GI.'XI1!(^3VF7['X5J" -MJ$-?M\OG`8:R1GK]^_>T:WGPD:KZ89=H -M8I'IS5':D1M*@N^AZ/W(3PG5IDJ=7Q3B<(VA4\O5OEDY\=:AVVG(T8-Z`EI_ -M>T>5E1@,7?Q9GX&[U(UOLJN5_)QO,EG`1!O+D3$`2;=L"?`%C(P#$8S.'[.PQ'9W'7D7$49(=>,>T]#?J)9L_YU1J:QPERSR0#QTMS/]+)HR -M'-7;C=!SIVV7UX$N!/2C$HN,QR6[_4#5THSF[DIFAX53?SFS*/T'R'@)@@A@ -M>SBI'E)<,.C6\O?OD,PO!][,X(6B=@443$,,A)*7DQ0PVR^]W=3C!*U\MVQ/ -M>^M!J3B@ENU-.$`H![G-*-[([WDQX`:_=60:#*]#U86N'YX4.*-14[^!CUV3H/MLF/8DV4> -M3VI/ASA4)=F^"UJKL`+'@JI[X'47E$BJ!(>7P3V[FX\MPCJLG*G9+0)4@/>P -MMB+JD=*YVY;@?(G:6BS*/[C.35%=,="_PW@MBM#<\09@;L$68$&2^)7S6<'5 -MTL.68;7>;^A8VSD\>,X4LY8IB6D='-Q@O1*N1(MPYH:VELCH[3M*L;J-&TM^ -M;I45-0>,"7R+A2'F&PKG:'QW$=.:;`OX_N45YX$UX[EB*XHL,\=DJVY?("M6 -M3Q^_!["R6`'DXY)2MRC\,>H10PK*T#]YL5 -M@>O@2FN\7A*&0&U]*)U5OH@TZ26@8*G2<8O+"NOW)S^0O1LB@TILN&/Y78U` -M`I-K1D^3L=4<3(M1PU$`KIR2CAF8#@IY@+H2L&@!/KLS/7W\O3D'<)<*>'W4 -M-2&@BFY:W79F84-0Z-,TY;GV;OH@@+F=MX1VZV,4NDD#(75.4Q?=X"+:AB_- -M\[\2GV=0!,BA&/WAPE@H?7/KYRT3%UPX_0C6ZN(XSN@%#?_W -M/@ZXZJ25'8'8BKLN0\$CPQ?M>RUEJY)?YM:*!#9F<675W7[(1"I6OBKL.`8I -MN*26UKN&,J.B:W"?/".8L""S=O/OI$X-[(9@\O^E>`*E5A'F1!5&M+XZ"1&@ -MSCI])9`=2M>&%OENM@NH_$B:8X2"2RZF`,RM=SO6?F,Y0"F]^0V\"Q=;O1^L -MNBG%F&-4QM)R!W89^1-)J]-ZZD',MTRNG.)K_/R4-C15S@UG6M#B<40^S_J1 -M'N]_OH0D'S[1EC4@\H -MTE&A>-BK84M7L=)2OHMWJ%ZG^=A=Q-.,#HEI1M>L!FI"L&$O[Y[/C38B*H;C -MG`&%Q;Z7B41P!'A#.!+S^M(>4/.*,@B -M'.-$EOWBDE&KU%.X!+'*&9AQ.%FN#6*N;1;"4IUDP[Z:FT"9^]65"]*VK&GEH:?::GIE^A7 -M.197L<<=7<0_>FK=ZN>= -M/CGGY%<#]'!?GX48Q;.;%;DNG&-^`#HW!1%?_X&'9U6XM'P%K*8F4?;8&FB+ -M?DC['>MZA2UT/'F6QT,6XU/,%3-S,O'T^LH#5((Y&GK%86?9@\-&3M(>-VSZ -M#/J0&A`/%85=;DD%D$?&2;[XP`H><2+E$=>9P7OI(U[:'_^7X=SH70^OSK&& -M"5F>\F!-)B&!J2G-@Z$;@2,DRXJ&WF4!S(6J'G0U;SNC=_)Z:F`=RB;[R;:1 -MU:Z$@3]]P\]WT\?:X,(;EFQ9`\=Q8TFPI4@OC_E/_P=_`-7>IH<:DOX%59J[ -M/D+[A3I_*V.\`VURZ/\@X%J;3)59"H;/5/6-R>RS#_7BKR=:V`<1>M+4-U/9 -M?JWIO(CDK;+JMHQYK,T_NZ?1)%_*"=/Z%=&*>A$%2A]J9JFLXMO*HEOKON7B -M/%LNUB"]J$P%N+A<=6X(]+7P`JMD;P08L;5MO(-!+LB2V;%\R)UXY8O.ESA3`P=;1@W?L&O6 -M?D=FA\L+S&LD4Z6<@UM?;]Y[="#'_&Q=``.JH55:I'5=G(+BL?Y[4KRFUH;!\OS1PJJ?C123;PA&NI6+]-39 -MRQU:4ADWC*>#^=\-NE,A/+;E!^/$L5U5O(8U1/"WU(/M70#9#RU!1#'=W2"[ -MO#\U%?I:*/%NH.;)TX/'QF4\-@8O?+D8`_@ZD`2V^#&([%7S.:P^2`^72T;@ -M7L+(/EX1<2I]#>#$SF.=^W]$EM_*C)*%-D^208C)>Q2TQ8?_2#B$%,^)R0/` -MW?F''J+!$9K4^DB_%1E$B'3\1I0-&KD2D&N0IT7QT@-M>^55J`5^%#)@>*7( -M@2C3K.CRYLG[,LR!K,[N?C%TQTZ_!:4R)$(OB9SXKME3'KR%1#F!.6E7_9LG -M^.LB\3L*%KFJ$65K=E\NW#_<9U&&SX6G85<7.Y#/?7I^ -M(]JM,G%YT3Y%-$*_QXS'*A65G$JU>";EK?X'`DR%K8'6:^(0LY[IR7G(4 -M;$#C3Z8%!55BIX.`U\(NQJZWCS06LU,ME]$79\V3*?13+G$`G]`E]\W77\MS -M0'%1:P]S@R\JS(.E2WW"N)"CY982ZP_A)0[D:X/,9F%G0C>":_4-Y]U/M1ZN -MI=Q-:\CM/EAW=DZ1D6EL>1RB6_F:]2@Q1.ZI@FJ1`Q<6P!8M<`;O:FMW%X)[7).@G1A`M95@I9`BM/ -M:N(5P06[<'[!W51?GZ^XY45(J#NL;O`LA;^Z%FUA6]IBR8'T+!CB[!QW>P%K -MC&C>@M`V*!G=K@?Z[7['Q`?NYE9"?A6/,,VMT`I#IFI[:>\_7;,9V:?>^3I7 -MX3JT^PC0/M3`&[W8;T&5,RG^'7:TU?:?8U6CWBJ\4U8@!T.5:3U9CN6W32V' -MK0SW-'!U@!MW8#VAOZ+P9,<'A@N@J*'0Q)X?%A)G:E,JR@')0WD,P!P5#@)N#B`)83<3\5-Q9TL8"Y]+BB3]5Z?7Y;2QO`Z5_,7@B9 -MJ8)`$21LZ0N"V$FB*XQ'S#CDIG-*QV)1.FL^E_I/+G`&49QH]DAG8?+DEJ-V -M585V!TM+N;$!R.@M1WU.X^CF2]"&X2(%..V"%%3)ZC6<=5D2A1GQ;L,.2,>" -M5#F($FG,^:%@!?6.5!J/:-(K/M)%C"T$1E^X`.8T%QA+;AEEGP"FV,(_U]V!*N:M_1H,U=$3#-W7E:Y3%_^4?@) -M'MS5O]Q./FW-R3K0DHL@H6NH_1)]:-)9TZXGV0EK -M*IJP,P$CUS":16NR1(?-$CG/OE1'L>E^(G6M_G!F+`5&PV7JCXRN>^@'_RG= -M6UP_.`8_*/WW[C=XU:+O+S#%=57U/1ENY9VF0CN8^X.34LT)NSAPE4>ZP`/% -MGU)Z)IM$9!E=,';GBS-.[!QS'F\'2L/FYC?LFR8 -MUE]CDYZKRTZGOSI?$X#:\I[82 -M99??F>4!.^B@>D;0".DZ)(@<[:#,+\?.&^P16"0%V'Z2$GGUD*^\76&F'I=+ -M@W9`B6AS-03]!R)E+;!CR','%?G'+\+%+UEU5'0!--2%ADH^NEJ1_G_"J,/H -MT()T7LM<4/O_8NX>6(R&`*>[PU:),M2G0"K17"`BEXT?G0POV!]X9$A.M2WH -M5;!-KONJ@Z^!IU>9%0C_JKBFB28NINA/L:'5Q=OER;-M0EG7E%P,LZ36EK8L&22I0 -M>=);\MP.A=ZZ#RYQN)8U2JUD,7R+"+[\I;\H'%\I?]$PZQ#]-!2(,"I[#X4T"3[+'(L0A4"<\E@X@U^,V5F -MVD]]?D<%=:GG3UASE+"076N?ERGVT*)<\1PF/%:_=(8J`033RE/UQGXH+/!L"+P;`S]$U[CDX<9A]TR2DY- -MN.]GM;H0)^?&G0*#Y)R*I#F6V36TNMB`.1-5-/GH+'N]8V6<9K0"UQ]GNM7S -MP,[W)VS'G=`+2AK\CN_\(C -MXC3GYT4%D4\%GT=!.^9^P;3B9#.$2H+XO -M4T&$.#JV,3XE:(M<>`YPH*Z*[64`O%5RG/AB;HA/&RY"HJ/%"G_]R$D.*.6Z -M"A@AB;=BJ.H;L$=A50R_+6Z@_])A.BQ?,88GEZU -M7?T7?I5<(E[=$][!6"BN%/*D8':N6S(2>\R"7X=N<&AD"XPOTEH_ -M$B:;[2':`47@*'F!^=411D5XI:2-XUZ>.SWBXV$]*=X!7DKR*LO(ML_39T7_ -M`0"U$:O^0*J#&_*(K+$*1"#-U[5XM9J6`@531W^."+@E1FP[+_'QBBPR^(^" -MSW?2NL_#+;%_!%';6E]K93HE/UB&+R0D$`J(%(O/)'#VZ&FOCUNC`D] -M`\2SPBH?NK+OE_GIR_ATE^K9/$GFQNM0V.X^5DIF_T-.I$WEO#$F.U*:=@`V -M/_Q=S/:^U0]7)V`3W^!\=?`I`D<"T)TZZ,<3"0">=X/H%Y)/OT1\F`Q6"'V` -MH$$0$.S/["'5>"NI+C9O]8/MCN26HEEJ,/X0[\^EFK'',O]=L!A)T+L,=6KO -M*?N?A:!+6PZ&^?(/B`\[."$&JRHBXO`B6+NG@7!O4_Q?AIJ3K@6>V[-1@H:*!:I7JPJ2H[+U -MR8YL?8*/Z`V[UJ;S3=O%L'@X.-$$AM@(^:K+P<:W?)2=A?Z!_V]&@=_1J::K -MIYF.Z/="S#'7FK,]0IK@[8TGF65$Y:6.X0$>;!*5WA!?7(Z@@GLMH#*O/0A# -M#JQ$QK`"/^H<18SE&@/4XKOP\>UU!YD)0Q.B"ZA1`'+F$(#2]E^U/[<#(H6B -M@]%Z8J^`@HM5'U6T^Y9"9@XIIF+>N!IO!!25"D?$0!>[*[N?/@+3A! -M%;&D:DI*.R`D_S8[PJ+YTD[ZJZ(&(0GS%/'[VQ&)!#CL@1+Q?TYD6I_`-?JS -MXFW7*@"5OAU%ZS7?-&#V'6[0(U1$0>R)_CZ`<+ES9?&Q4HU<@+!W%LJHD)7E -M>DY8NKFQ)C/VG6BWQ@0B\C*P18@H6XB;QI9B,G<1`42@2&#VV(JYBAZ2@V0Y -MN5KWXXO4+789\(/E+C![[U@Q__T&$"`(_G.)6T38L,&D'#VL5`_&QW!@:&U1 -MQCYIYZRFZ#G5[GY.-S[$GF1>VTL_"/$3@%.6/)&;4C`^J+ -MA5]8MS=3C_#?B0NO<5X^S'>C6?)A;7.:_=G&94%!&0]N)@7/KKZ/7&;^X4TT -MP`M`&Z"S^JRG_4JDTRI6`Z5]+&&T.?^2)( -M,$MTC+NP`S#2?;=.2L1R7'A9U6LDRF-!1/]T+3W3S=QE7ESOKFAR"7-(G(8=9AOH-^P_+Y0A,YB:U;__=9W0;+1T -M"20#,(Y"HV+U[Q_94O=%+GZ%37@'L:S+Q!K$#")B_OW2RWSNF'A)M8YK;Q7; -M9J4Z;#?P,L;8#P%N99Y,M*[J4:*]:HNL5Q)A0EP*],!73+4C]X%9VK0-1;3# -M+)>FBHO07J&RH.3C@Q1&J]R-VBU`'#_1W#X^_8UD0::,/15\LT3SE4H'4]X"7Q( -MYSQ0,\H=A3?11R(7%%5NM_">EK6>%0J:`&5O;NZYP'Z[X46W0VPCNH6\)^5ZF!"BWQ7E2PQ<>"$#:"(BR"Y:J?@"*?: -M+X*M#(`WE#[_]7#*Y-X`DBY2GJ'V"EJ0R-_A'[^C8]PL(2J)?90M>&"*\][' -MYNS#J&%98NP73UOAU^C)T=)#$@$U]=":S<&?9V42B<&.`-'_R+=R#ZT@7!`! -MTRN7UW2"F<&%TUD!+S+#:9/!!W48+YB[R;*J\:O6/($F;-_T-H+XD-&7/LN.:J<)^WG2)52F8&-U[8J"#<>Y@NR`-J$'B8 -M^Q8$#?/(6=5A/,+QL$#!3)!3)E),*QG0Q*Q*PYX=L:31\0`ZRWUI^UD(ON5@J%&-@7,LX.D_9+29&%AQ4/F"Y -M8M9HI`RZVQI(5^Q2KD*_0$AA&/Z$CT1YLTX`1'$(6<$.#"KQ,CWV353-V?O3 -M**?=9>PJ"_-="25((E2`&0_U-@_,8*1@K[\C3QK#-=&:]7,=<+XHLQ`8:ELM -M`97$98?5B,_G83$&W(UMQA\Y_3)S"PFBK)_%A!J0'<`PJ%HBRI/"_]6_VAWZ -M"'@]Y.2$$:C`S\3*-'K@)7^E]=\JZUEP/C^7M,?Z34XY^O*H>HE1GZ('L2V4 -M%T#OL!\$_"97B1!`UO_T+M_@9DYX5(IZ.4%6$KWRWDH&(C+1\I9K-@["9YLC -MHN'-@EZ_\7BU8_^?34^1$N$L?.6A]PKYFZ(]^6WO$U:HED/'W>#L.QL_SW?5 -MQ:[D,?6WR>=("9>#;9+!8=9O\VYQ2%&92D.J-8$.,1049-88J7^#:$F2C\I% -MF;GL,/1:%;LX'[:KURH+(D`?,[6"9%P,AE_;6"UN8YM?:Q:LM+/$Z]H/-UD2 -MO5\X"'0.@7[]%83I*V7QH7,B/*;A?(`*0-<+[QM/NHL'&`Q98=T)Z<@9B/-- -MW\I[9-=]#$''A6F^5T5+;Z_)XJ%0I;MMRQD!X!UW-<'2*<[F*\T:=%P:JW@% -M2)Q?-@8;_1^^JW&V$7723:<:)?G_=TO"\/7:XL#HN>HO#^,>-I.Q^EP -M05[+!UG%X.M3$8&VPHNWC5+=!'RH@.@FI5&\ -MZH^J%,R8M[JED$V_M1]?V#%)L(K/"9_$-($JRL!:W_H3)WDO-HD6BX[JTYMH -MIY'1J&ZV22*!OW2^B_4GLK_.X9%:5)#<"7R[PY@01:Z0>\A-_&3) -M6G/62/"W#M"/^TW"V:(GN%ZGG':+F5PI6EA:(,RTHJY7NVOZ<0G9H4+$TIL` -MJUWAT:[7+65''T$SU_S(8:=8$GT.N?HHY5:&F?M7R]G(9)%*1&&*']O1:G-] -M%W5^[:U`RY%?,]D&+W4HS60*+2K6VOE-E_"@6HY"S#@/%?#ND@E^+SN2#7"X -M2ZG?1I.J2\I2))4:$2DW/N=.:4*8[X:[6[`0*F.\+KC"U`?^130<9$I)]CB- -M9G\MJU<5-O='G#C+3H-[&-#MOL(5V1'PO.I[\&AG45^9JOKP]X>\#T`W!D-/55OPU$)7O1NOB+",2M[DF;35%1@%(PA8ZH8Y.% -M.['$7[^&^!"]T^:HAFS=[M@O4_WP%X5E?*4 -MRRK"B5/FN*MBE^3*@9]B@#%FU94(=@E7O#IN5IYN,!6LJ(]-73:4Y%_Z+$GR -MMTLT<<0:F2.C:H^6!3$HZ75V[)I(ATB*U$(K%),$D\R=Q!R7O?;44\TAZ]UA -MUL(>>IY6"&9_$/4=RI!+#AO&*CIYIIW95*U/!A%Y44-5V#!!0G^98/\::$3H -M&>`=Q3Q@^6N!=2`GN?C(5MY9<>6^+]MM*J;S3JD.VZ8M09F4SO?G0X7;#!P# -MK.]W=>0Q$L2/)Z7W(]BBJHT&Q6^7T#N0/Z1`T>-/3G1P;V_`T&:V^`3M\W*4"@]4"Z -M?8?V2^S+]$Q$A#F=^EDLS*P*S!]4$,.\:8ND'9NDHM%F\@5W*=RAU\&YVU,X -M0RTHD+-*HLYNY^F)[HOI^`8@6KW@UR*M>"BW<7[Z'=7VM( -MNBTOL4"U%H.;M76UGU4])(+>\@,@]I'T(C!>!&J5XTFQ@M2IS>WZ7OIQFG<' -M=XH'%-^7AB9C*2=M+K.&;DYR9\M4%`/G@67I86])XGQ:M\N9?A0:$(CBA631 -MJ]73-DD'C$U_$21FOT_7:,X%"K,AY1O;3[8[L)^]$CXU:E1K(VZN?/!4.V'& -M.@G^V:\F[6@H[TXN7K+0IT;.^!73#]$L"G)^-TK<9H?(Z\'N%XCI&TJK\[<8 -M:[%6`Q38[(,G+I84D83B(=MH%Y3@[C``CY7T9O/314(.!MG)H>]H4]B],*2 -M2EJ5;-2C6!9+'1SYU_.GQ?)XE`0K0;'Q8]J#.$*CC@R&]#FODS$VGV0`;2_( -M-LR(TOC8U3M$A%1AP99G*FZG8/6=V;)L8/9\`#Y'H2&QZ37(;9')LLV)_+(Q]0/=>H;DMO*AT -MSG[(/I@G7#D=!#9K=57T7)@V6"9@/?Y3Z>7UO2%UBW_]B:L7DWF.Z)GN7:*H -MXIP!F+RG&Q14LXT+[*I]PJ^!/7;[4'ELZSO.:Z5)9IU^,07,D,3/]%0Q#7B0 -M0%7N&=\HZ,4V4".[/4XHBHHJBHR_5U=?SU0^XU@[=*61R%-:;*)4GN$<[PTH -M1G>PSPFD$)Y2M"3WA7P1((%=1HPG*59$2,Z2!OG)C*47R,N1I:]OEO`Z[!8@ -MK-0(DQ5J%%5[&YC^PKMZ!7%[`U*(3!=J!9N5!P<[)*[8T1&-ZZ]JTY7G-KNU -M;8X+!$@R>.6E&_+R`PO#J'5GLCD&0YPKNR&I"S`X07("]E-B-.T;P#"S -M;IEKY'((>"?;[,RK+O^K.W0X"]R&!5+T0_^[VI]([\[$77\VU1DNLM3S!_`V -M9V`92+3E16=]*1J'_1@8\O6D8!RA-75OZ/6.\Y*Y\[:CG(H.AJ0D=^JM(&MKQ3!W'BN0SS'>I@VRPZ -M&%_G_QP_^IDV4.>C6!$,8620.CHVT -MG3^FJ'\D(@:55VHB`0+\#?K[Q>)(@<4D>?4#A.TP!3B,KSSH:M!ET3Z -M,FR8MVY2]`9J)[`N;4MEZ`K4UVK4&KLTZW.\,[>#;];9ADT"?DS0[9MU();H -ME0+@5\R;+$/!4B@@6[[:_+W1]QQHKS@(KI7'@S96O&+R9_KPE:\017YUWU,L -M[T!\CMQFQIOA1U^'`Q5OZ#[B5;*S?R_,73[5L2171KN;=57DE6^7-V\:(28! -M`J(V#5L1Q<+9/MP&@4_Y[MAC*MEWQ.7K2"\=?_%2H1Y*MVJR2$4373RQ:H8Q -MP"E6L/R\QKK4+?>NVGAG_^+`C!:.`";ZN^7H[3F=X\8%?_".C_)?QZ_EOY,3 -M]O/CKXX)=M7XH_^!OL+Z]KV?8[;"UX`*A=L7<1:+):N"A -M$[^4B9"9318*Y=H`8I#Q`3HAZIFK3`TG7)N7B#`8Q2,4/=[8K&M[!,2V^2`N -MTD1*QMD*L0#)]-Y]Y6K;IA(:OZ]IVH7"6?/8`D,_PH=WDSW=N/#!%^^LU[165V6U5M:3V/U./*86 -MA:UK4Y*\W"OI@VYHYR?O<&`@,%_8@PE9JZR!MB[QQ]AZX4=T14*0BR&LUND^ -MF]'5Q*2!VME=M\,;07/+SQH#D4@OA[]Y?]@(HA*T?2D(/KA&A=XED -M:^1@>^O?-LP3O/!L;T69W"C8`XLFGR2Q9P&^R,7-W8>4"`KY4T`T"9203A<< -M/+,*!-V^-J\Y$+JXX&WU8]2BS@,/`4L3-G,)E!5"Y9;5Z!WRK/%N5H/2'4,,6O^KLST -MBJ8+DK>2:?WG?I)NHR8CM*5XR_:KQY@1@[Z;[DAZ$,_!Q$O<\)#?[!@!AY;] -M-TY;(4(@A\U%J+L]+W_1NPI?$7[R,]"+T*U2U'63*%YX>3]R+@5'W-^W2%V8 -M=ZX!\(D*3=CJL)WA\>4.*A)QUN`-Q9#E.-4HC,/9?H6/XY"LN"4=DEL)`K1X -MCMQ+OT:S0B_4.>AI&@M5)+DV`/*H6^?J(F`5/TA+ZV.G!-[8TPPG!T$V\F:- -M84`7IYSYAIP1W*,?006RZ*4EK_G4-T@A!,'M&:C1;3QWI@HANDZFY@%@-I1A -MB-.#R^-)[TH7AW'LRZA2T%@MS-(L025%4<-=@IB=SL*XR9:(#[=0-#QVK&[@ -M::AQ:$O9,??"#/:P80[0?\``B[[20&19;"+,'-`P*0CEL2(9Z>;LD1W -MFD3&`,1YX<=_:798IEIURPEDK]C&!WL!2AQ6;V>3_V?\'F^[6'\$0-;RYZB_)+#&;%R_A47?6H3YVIS?L'\>7`S&E -M;AB@^*>I@0C7L(%/9B_C2)D`@?S;J%Z`;4F)1/R*7TC-[BPH"^]>NI1V+D49 -M*;>&8HXKMX2LZ4<(6#IYK5=-,Z1^/".-549[S5-J&#.NKS$F%9[AOPC/M@'[ -MLN$_U*?YL;&+-KT -M<:8,QX]III?I$R_C$77*+D:.HX@7E:5X'5*TK?1!4=]^15X"UGO<+Q&73_1& -MN]S>^6]]1@9&3%Z+Q/!+-8?V')<0['B+U@?(S5<,1*C:<5AB*XG_SHDE@]-? -MK1'/H3Q5#/`9F5"'!/U%&"5KA!'AXPP.IT8=BA:S.+FJG\)+0_ -M#\S2%!F'W\?G%PWC(I3V@V95M7*?<*\"81VHV^&PYLS>"&D63KLA3&]IZWJX -MU46!]1Z:V9YMH%+1_Q:1='%(ADX(4!_QIA+*R<"*I2/3QTC\4>SMM/+MAS/. -M\VI$%FR6L(T4C,H;]6R^5X;,#OZ8[R0Q4!,^:Y8=W'-P2LH5P<"T;=9*H8:5 -MQA#RAP<+#C-7MMV_A16VK?V(;66+J$;IJQZ3(95L.9&9C]7[X3\105&1P'J/ -MBF(!HDWSI0PEN$Z'U4+1$=)D\L#:IY>KIC,EQI,!XAK&JZ+^C%A*(O_DA_^Y -M@(Y;%WY4HV+'32+MFMD)GU59[]H^L2SJ(F'YH&SK1LI`=4,VPFT",'?0(T1.JIXM0A3CU<8(^0,] -M,P2TFY2U,%/-'=5"!JCY0>G1MCRXM15Z_V$S3OM18/-2Z128TS9U'S_TGZHK -M^X8R_Q/:4ZHS[X,-T*#Y/_S:89+X*#]ZJ`C&,+A*<%T^U0\6II*]_V#E(`SZ -M\$`PQ"V$ETU0=W$V3>1^TX>P25'U;LGVBO?RK-=0>AR*N+:31#OL>C[,2BP# -M=9+FLC<'ZS7>?N15E/C%]8S3M'!G42*Z_P`RKOPV!736AHI_28-L4Q2T97GP -MLV:,J%DR*23.M=^=?"&"E?@OL8#3]OPZT9-%,LF0%QL6!_8"!;DS=(.`UU7M -M!%=1HL`&Q:G1-N`U5Y1 -MCV@$\B`5]XZ`'5*S,I5768!W1T@6+%E[D",(V)T3A%I;\;@QFG]!/!6Y+:(O -M&B>F<^Q4PJ_1&KG?$$F:6J8F\=,SRR2I.L($/H)Y[&J!=+\_GO^6H;EQ?$P` -M_Q\M<9]X-JJ4J3"F\\D: -M:A,;7G6B1I:`IX#4TQU/DC.)6;$C'L?'+W@?WS^L3CAT_(ZVF,:<27:$3<-/ET=;E>UYM`Z,)1R_23^FJE# -M-?U^!7*FRF]KOY=SPD61U-9SX=.IGX6=%: -M-+*#FX]^P[$.`F&:KJR&?F@@8OC2^Z`FY4V(AOZMY]"(&)*5D14S3&[KX.ON -M.:WOW9^83NBO)&3"[3OIW)"*7%1SVM.!UYT!XGY0KDL1Z@Z;1W!-D'F+5I". -M:V+)`P%R'^J(L*V[SR2\T.3]KDIJ-8GY[G?W3SF")62L8)[2TXTYG[#Q:B2E -M!3M#;MD2`8M7U\YT=#00[IZ$:N9*)+J+KYOH"IK6FZXO4O&A@284TB23^HUY -M469<_4]2@J[&Y(06_($R\&T)Z1PEXU@I#YK'O:EPO@3K$H+E -M8(R<2W+@,3REP0TXPW3%5-UA,;[M^?]6'[!S7'B2`+"F!QBN^(H1&3Z@^($Z -M@M?+?N]0:-#A"/;]+6J"W`<=R%><,3-Q0-S;<.A,(!9+=&?RX+G5\5/1%2VE -M\NG^X/MUU"<'IJ?".?+M\S4N(,O49%]7C$I"0OB))@(A+23]2Z7X2BNR%(;T -M?[P_?>)G`+3[R7-=A?^@`6GEFU5L.4A;GT_7!45GUP4X^Q-SP#(>8UN&V8?: -MC4!93AYTPV!HHP"-W6U5?9:G?HS67O/F65WIB,_!;^6=+(LVHZ1.?4$#US1' -MG-?=C*#D(UOJTIA=!OPTD\[T6D6JMCNJA&)Y4\QYGE8[$)E59*D6S75X!V4Z]P&)C?4_T^L`#P17=K@$[=SFY0B#U8R?L`7PMS"[7I:,@F[J,/&KX< -M.4_)?!,*[BR]3DKW:$EVH[D)L6,#END\CI.!`>CX-B(?3'>,;.PFFGSZC&<^ -MT3\_5BLHN.2"XRTO("GK?Y[OZ>)V4O$"QJ7'G"`Y:A73-#IV;U00Q%R=FM7; -ML7:^[OKL3%#SGH'&@#;S5)+JO%Y:LW)&HL8YV7%&-?#_D5[//_6"S2,HMJZR^3549AOQ,4C0DR'S@2]/G+\\;[NY9%U^0.1 -M9]LE4:!U'Y?R7H6(9)-W',+G*N%:&:>JB+K8=.0Y6+8-KDI;Q%^5YQBBI=24 -M0[!XY(@[HVH70ZX149X"TRA?EW/K5!S//=K;;I7M -M\N\.%7!IILB/8HVQ0['*_M1^L5XM$`!$I[`\`RGMY@UFR$K>H][J&)]A_Q&5 -MQS^G<\-$/S80W:&9R20>S6$W#X7_P-5!EH;`J384G&W8`*`]")ZH@-D_LZRB -M>VR;Q#I+;"YH6\YAIX`K[/8XHR^&DC1501WA_;((P=6MCD;&9)&?I&LNM:/] -MAO%HR.N)@)ZH*8"`(B\F&_(PYEWATMV)&1[OV+'WM:U6E$NH2@=IB+M#V#QU -M)!U^?A.>,D@5P,)89!G'F?[`%XV+T1*W<&CECZ1[+38?9_P9498@EG\$2*%7 -M(Q53J_AW&XY8)ISR/W0PQ`5'^)Z\T0D8:GS)WCN=9\6\R#XKA@R?Q=,_I63%G -M>EN^*?FZ1B:S&9Z`@#ZF?4\E\K/*Y@Z2.@?:J!M_+7MRH'$%>"-(QS(%YJ]6 -MTW-`@ST$ZF=R5`+WL`2YBE[!Q2-9 -MT+Z5F8+_,UC=8F`*8<7%$`F@.0D4!0@UL5`;&F&)NOWZNM"R."058X7Q7N%*?G^@4N-^)B,OSSR=_>Q -M]VS]PSR:VR.TW -ME2DV7-J(;QXX*X(H4_OVA0<)[H=*]7`*.J9`W+E("P\<,H".L@:KGP`=Q"5` -MNRN\TF64)#Q+MVAK;R7`32X%ESFIS49XMSPWNZQ_OG,5 -MP8WIYP3AMUD@2/";UR_<&Y5%?$*+F)!,\2JJ:1#Q\?8H0U03\:/_5$]X5@$' -M0^HFAD#FO:C'(!+$)_$LUQ4J+_7*D]B1;C"]E?R[F\E7*##"5W'15=]\H -MGONV(.S'3EEK]L]IU-&"B,-^F9YY/DG^>-N]9)1`X9WN;Q8X!XV)`W'4X!E* -M'EG-(T*<7*[!:=SI,07?A")[5YF0D."`-A%7GY+]C#;?EMD%DH:OZ183-=?2 -M9ZR9I\GI^21B[RMEFRQ1W*V@EP&#JW>Z\`OA(F>+P\;5;MP/].,2H"+2".YS -MWNN3#?MK-Q1(F^E++HHQM/-Z4B8=5W9=H#`1D!E/YO(B^+1^,H@ZI8@B`C2E -M9ZD`<>=LD[`.+>+5V,0CA8LI)AD60UJQ%D9))O=6P$)4?7BXJM2D,Z84+ZY3 -MU%RJ+W!M0M4NX(1L8^NJ`3**;G+3HI;U?S@8#KGW$>"IERLB&2U)W`*5[^`# -M(,_0;Z2"8>;.]GR:#6,&;@>@=6S[`X+(K?=%@8B^A'NU4PA,<[KH2KW;!%Q,ZM!,@SHUL@@&1.B -MY<(SWPM -MZ/<@8#;4K\1FK3],K/J[1T&J9L_[N0?%HVLP"U6PQ(@YQ\'\E=[RM?W`BVQ7 -MD[S?8)A^D;C$T3@X^B%?`*>_&.`^@$=@V9#G-J"/,Y=%:E]NN=%`!O'`G'\ZY3UD%AEWN_-C9^:GGU?_<2,'_;FYF2O2<+3& -M,'@4HX+5WVA%:#.6W;RE5/`7P8!+=:",]^AU/-O@$?NA*B4!'4P+$UC0XL'K%18`9M\M20D(>N/XJ, -ME_"AG@D;LF-P!Y`@(A4BQ!;FB]D"<_4(Y0.[SY%)^]KIW5`;_5DA!Z257!8)"J+YZV4W]O.T_4PT4B'Q,<_K -MZLFS'??B'0N/D`HSIB73%=\70PZ4%GE;_%)HZ`9ZTF4Y@&NE[.*X,\$*2JQ. -M8RW+?W$@7]7?_N[]S.0`&A;5T#VW53QOWB"#7S;?=_6_6QK -M:Y<^J195)?J1UH97RB,PLQ"3O[XP9!NKF$Q_/'`N`-U5I`%6Y,01%/WW0@87`1 -MO$;/Y//((11%.Q]W67UF&+B-6 -MVJVDY_HRL_JCD))1F!O"4LPALU%I7`^$/;(7LYX!4)-]R*ADL*O2$:SZNTCL -M3>HYYFF-$JY:2V\EXGQ;A09X!#G08F2Q4'G\R+2VZ5+N5=FHU#U+UXBC6E@_-+E(?TL=OWEHI_2XC\?JQUL2.G05)T.BX>J9 -MXFD0#!IAI3Z?`@#?XJ8^&ZT>J7R&@*=\6`DS'L!?OLL"[N9ED-1(._=4/>^@ -M7[68^/S7S,E(KH_<&30G+*>97%*3(H,W@IUYY7O0V$8P`_ZL8ZDV.A380X#M -MP&8E*%M<,6/GGYFQ!AY95880>[MIXFE80D[J'"7F=S%`.FON>L-PQLS_:= -MP9+LH5#MC(WH5\RD38F(AEDX*3CN0_@J:PC^(N(4H_<\'>&OO;>#YA1Z;0D)[TW1J[)=')L^>[9T7?/CY^>- -M:.FP8-;D*!3V+QM;6BC?V6_#=.S83B*C!BVK/F4EI1A_.4-1'I'DX_#FEB![ -MM4"/+7PW7-7MKIH0A,7[O!G/^!YC_@ZF9$OGK"CRTSR+8)M-_8>:A"Y]_IE> -MG*-^LVB6FFFWXT^=:QN*5ELU<4>1LWD&CD/5>8AWL:BY><3O2GR+XOO^?&E&[JQU]&18JQ[O,ZR$#=:]+:-L'+AYVP694.U53>7,OFR -M#2AN>3W>SS:7SJ(:748=_!-/C^!.="6^8OKT,KIHF07'(_;P!/LVR?/Y?YB/ -M4O`;3<2/G98&1RYZNE<+)`X7VE/X,LF&WQGOW`;UDMM(-M$TU=SM/JT%')[! -M;PW8"J2LJ@S]_`DCH,I+:X8HEXRVG>^].QD3:SWK*#C46>5:!BN\EA@EC?RE -MH^)N)DRGX^'YX3KL;DE(S(MS:,5P?`2C[5`'`('`.\]F9YYPD#+-/C/\(G`& -M7"%*[!>/KX#RUOO(\A6W9^HXB*E"X?0$T/!W\1-DU#_Z=LCO?$8*!B@'?,82 -M@SA+H,(9L!;E:1>CFUS#09*^`MO@'GH;@B6N7^KS -M`/5AD,6PT+7O=P`H%/,LCX#`XG,",Q'E3HH"1A(6G[@./=9JU,PVRJ*AJ@P[ -M*#=L0K22I-;BL8/V:[F)U>Y^)@,L6E<%9`2]EJJIG\Y'.D9[,[]AE83+Y:A^ -MA0T+1V8`&O]%-5MPAR-Z`!LC_+7$/1#I+>]6L.K^FHWDZOU+1DOEQS.H(/(; -M/+N68.JR_R\>^(&>>I9XC4#(2A"[ZO.C6K<8>E\N(T;L_+>N&0[U,7>!SO*/ -M(YNT0QW]X'/`R_(=6U8%B1]*1@4R=:Y*]9E387G0E_K9)'-N^#;%<:YR[$5Z -M79@J5YA4V4?Q)HV96H?6TY!P8:G+RCB41^GY?:7>W=Z:IE\`I@CWZC>I/7X< -MYL.:PUUS+J&';.7<(\3ZDC.97MYKU^`[!U;&@@:'E]>LM5`D<-8' -MZ)MJ).-)9HS<38>"GR8JO&[=BK___/+FYN_QTM!C>8J-^@X$HX>\NHJ&JFNM -MLLZZ@[Q)K;D)4.2,]N&H$^>Z61OL?452\-7G$1UG/%XQ"@!PZI0XL(,:I1<4 -MI+-1""NU94=:8?X@)F%<_*]#E[CC+U`H!BP$)A&+V]^D&E.4!:*S,+P";X*1#"ZM'VGW*>H8M!%MF2GN18? -M0B,;QEXT`96E@1=#VA;`;,,2J2*-YHW-O"C(_>?B2&9@,WUIK164@/LHTX9Z -MA_5$NVN3=33V@R[O[;+7O_EXHJ!HM*`V%V#J7BXR\_]"W7CK9O_E(Z%LA*^,ON41T\%W(]FIJDOGG`D\`]08Y7IN],(NICT-S&A;=#)@*KJX -M(NC6=&J2H*&7[U;#TQUY%?7(O)W-M$CAJ8U,H>5)`BL'5'I8\=^Q16S/OK0Q -M-GJCRAR')%N5R`EZ@NR\-+X_LC@1\"PV[#:-+OT>CTK$/B]/*)=DC>,R):1[U3S$:N:FO&? -M"\L,!45/N9V-Q<3TH-N2959\0)R0_[NQ1R!9/FYW$QQRNOHTJV+OR:TCFV+U -M`7N[&$JAS>FNI"`SN(IA^\0V89Q<'M97W:D9X(5RS/`2_1DSSB,@,W]]#,>2 -M#=V&[3YI[XC[T/F&R_]9\NJ':K![7[<7J;/A,SAR/1I@6,L&9&4]HD!E@-?; -M1'MX-GD_Y4AY=G,N'=?JQY!-$P`3..B@E_TR%S\N5SQY"PRPK,B**G(\CW._ -MD^)`$F.+,[8(X)/?YE"U#<]#+S]B5!AP%$X=)D\KO(VK\4$7W.[B+[`Y?4/] -M;/PA''4U`+2#J:MV*Z9SI[@I'"G,?_GH.^C&*=MZ56#L=R"8>@&;Z;FEI!GB -MG.'X`VK;?-@F(L/\;6YLLO3_5A@X>[=M^;,Z0)S/%E,YWVF@@YA.27`T,,-` -M]Z:`STB,6P`_\"B;4(Z066%_((S(DR6DMAJT`KW+J>"Y0N-A6VENSZ>=DPP2 -M@W-KY;_M'V$W';.%-MPD;\DJ>=T(&5KMOA;Y[0F+,#)XV^61'1:>&F!HI#$L -M_(K`1XZN+?:&:$<`3;4[G$4,+'>"`J7T3]!B9(SC=5\[`[:E2VA4]XGB\1G; -MDA^:7J(KD]B*UMW]G^T')W.Z@V$Y#E27:0]J4T6C0(%WW,V[:3_O'05DA&M\ -MF7W[V.+)AZL*O[^-&=9A&E81+@=<*O;KL_SU2H>?@8].-Z5GB?YBR5%0CEJX9V)T$$HYL$*?^S6K19 -M$',D_'2*R!M&0MW37CP"W\9)T'C!>3G;([5K^ZW`R2@@!LB2K7G'@-FF^^#%51>!`!FN!CJIP_K1#O4;7=RS:7WMHX<^@%!&ZA@!Q//E0Q -MD2;G$!_/X1H"%"<-L)N#5`SZN*CAR6RW`5ND;.#V/Y6IS?)@_?C`P\/)W^&P -MTMK-;\`O:%P45W>8;+'U,AW_(TG?5:.<+_MZ4)%I(Y[INFAI/NA*M'R`+9P'"L7[PJVZWGD.85ETO1 -M#<9HA!E)D\_0+*[=;ZQ-U3Q$G<(B5B^O63]#O?),2'&#%RT;8W1305:?Q&UK -M[V1,*_]OD"6^;XVOI-;&I(8(A''>&,Z.B=_&:E+I81?U_7*^@Y[A+B?7A6-+ -M"\VY"_>""(-1!K^GX)L43^]76V>322/!GR9:=Y\?O9V`ZWFXL6 -MH)/G/_/#TJ7ZF.?M58YCE4UON%2I82P9'T#YP.*4UP#$'J,^'M.KIDQSNUET -M@$%O[/4_]?Y3X15J;_FZ`M5L"B?J:$?<];=1:.N#^ -MU2IA@PDO/XJA<]SI?W$DQF=]KZ>JUP[G[>J_O$Q_JVCS/1'E[%[O?#[5SD9' -M0KZ;`$5OW]SS+X_DRH8)UC13\RYH7-UKZ1HVX%*'Y6_O+PHO^-6%+]S6N)[3 -M=M3'N.:6SH830M\#RUJ?_,U+X>#'O2$K5`K'1[79XE>8N9)?Y$(P2)OFIM+0 -M%0+((P7T5#CG`4^\G[+,:*@`">C4\?GORGV -M7(_"6![)JB3->O!G%([B/.+]]8E/YA8L*"O*<.]'O+8!L4[.X=\>PY=XE -MZ(C+V$F!>-_,O00Y\*S1QGOE7(&&$B]T6PN(F74YS3X`DO+Q&9)5$3*@Q3\ -MT4(T#)&J+L&*L/<_O;VC;?LX>UHQSSE^DI!W%_33;.5-YE!6+(U5.M5G;[!R -M`J:?!C5[NN[)Q&Z+/+(4='-_T<->``[T@OZ,S#@[9_-UE<#=C=#[K]:5S=D]>[%5Y.-CUXX"CU+GFA,N!+]O63B4IW'MUT)6TKJ32B -M_V(01EOU$#07UX32-)60:0IT:-9>&7M-`187B?;CY254N3HR(A$)`,)J\=6\ -M^-)0TA(?32--G6=:Z(/1.?2O[0G[9"SD'ARXWW_W07`Y8QG]7_LX1A&,.N; -MZ.KX..[_"[,[!5P)RECE#M3Z!&OT2YU>H!DQNO-332L0P$F?KHD5],74H4V4 -MBQG),`8O>CDBL@UH5/RG[V?Z*P!H]7KO+T.#LYWHC@)$BQU]<6>AZ@Y!L+,^?%M7%$3 -M#TE."T(RFY@+02YV`!G/(:`7!J6EHQ"'U0^5&=0XR_G#,H17=+E85\BX_U#5 -M:8/6#O,F/5]\'^COU@6'$N'-N:W8I6&M_7=FYO_N84K=*YSA1MDUF?Q,:]A`G1I-,R)RA0L!8%54/_Y"4RV+_LZ9%"Q-4D`B -MUE4SQ^*#08SD8@9IGI>+-!"4G3 -M?(=;7X:NF746S+FY_\AR*HXO4*L*WD(&V8/U+)$Y\C822DBBXCYO&L1\-S7I -M$[(THX30)04E6,S(5F17_>.>M)&0?-C&6&T:(3=L)[-;I-,\T:&>O0.E6`@3 -M-6=I'S]?A)8`?T-S`Q5&Y'=C;+/[O;OW+,1/'12Q\#.'Q2#$E*RG@=A/+-4GG-%0'_)6>!+ -M*E>-*=+>3_VN@&;YS5T'+='[_G")^$F#]/2]/4JDIG!?*1`\RYDQ;P=;#U67_2IU\_G="S7U(0CK`S6<@SJI[+G6[YB^=*A_"@C$<0-#;81W!.>?W -M9RJU78D,6`K@G>VV\AOT]\*;AZ[@E^DO3GI]CR\L`*RT1>0:!%HVB%45=3O$ -MPV&D;3Z"QG7X@3S/3]ZN@_1%57"U`9IHN*UZC-+">_G7K/DM&CQL\YUR42D$ -M_6E,#8@&O&3AQ'N/@S6`'\43=M#K>:Z[&%A5X@B\'_EK5$6R_"\J"L&F6GML,RN4/I6$EQ"W^=V7>9 -M"!142"+3V&T#-WQP"*`^E^1?..W>M'4)[5F(.X)]59JP67Y*[I'N>Y:B" -MR['%GF=*]Y]V)I>!(1+?"A49/&V`YJ4L()^KCST!'UMJJ]WP@@YU&QK'CV=; -MKYO0]GEP.K2Y3.!2/!&6/-(&`XNX@.PI_7"71-18PG1]9&]'@;Q$=[<>GO[(/F3J"Y_F1WP*@%6(B+[&%W2JA3'_;> -M5\*;&`Y-F`1Q)=[)G`F<08[9@O`3I2>1#DU^#\&2EMO#7YE_E3$<6@ZM>H&7 -MS[J2Z`-:>#-_X9#L9JID0,:)1>_1,5\FM4Y&S_U?7L66T#EQ;W:N'AWL`GW_ -M&KCU=--ULM^);^.+^' -MB];:T:3L6],]+SS/:/G@F>_EY!0_URMR$_2G&^4_QF+\?(=_C>>4"3R/\,Q/_;17(4ZXXUHJCD^LW9/]T&?9(?F -MH[!>5\>V1P9HXIMROX7->VBEE3T%9;I'F4^G***GQOTKC)O1.K_.R$]R0C87 -M2*HB/G)*&2__!*!TZF>9/\#S.=68K"T6U_U82GF'5'TQP;M8OP*7D"13@'NC -M^W@]LTSG\DO:%`R2XWLOOY">8)05VSLWI'[<:XUZ$EQ<`D[L2<;+%5NY&L#A -MN79Q$1<3,NU`.5&5M3H=;<\+@GO'B.Z`#&?" -M".KB,-SR?UN/(UOGN-.7%2,E9Q\>P>:`W"[0"(NG@/DQ%`CA]RA' -MVS%O&=$V/X/=M]@LL)//SU=)ZX`,9C[LM!J_]%$+&R36 -M&)I:9?IEKMU.2RTLV&*BY<2&#UML@UH2#VSE+Z42?6Y,Z$BDG4^Q5N#TWBU* -M0"]0<$)7*[E$)N$OY-RGH$@&[OI+RGF74;C,$@5?!D8V8FPHUDI3%Q&JM1AY$0&[XG5%QWU%44!Y -M!>\OJ\A-PXJK'9,SK':UVYD^7A:580':#!^BQ.'R`<;7I^BZ]ZF(Q9AO$XWR -MDVG&8+37IV=$A-<-LO61?;DR?QX)W_M@F?LL6?$VWYF'@_LX[7<=U9D.(ZI0 -M#^F,!U+GH)TY"XZ2[1Y/@M4+VA]C>JK0/-1F@$KME&F`TSLL[\P$LHL(L`EV -M_LKN7(W^JPL+GPL@DD/6XUN9$4![.BS-($"^%5;@;E?'_[\IF:2#U4ZY&?QJ -M+YH%@EP;V2IT6Z1/Y&@0-E,'5\-6`^;0M#]BU3PCO9@=21$,1XQP=B944CX; -MMM?3_QNU)"H^6<[.XNVRK3Q[GILV1'NO6X]M&^)9,+3D8.W3+`9`ZRAR*K,E -M?_UZ$3[5.;.WAS]RKTWN!@_X7CO'421.6)D$:2W1IN -M4RLT"5H-LKP:?9\9*":YI7>E)(DT'37XITW"LNRLW-[P+HISADX -ME$GN2;\^$,1C<+L%".(4J*J8XEG$"IG_%1!:!<^+2T7SS5V&7##&$.QU6Q(* -MK]<<\L5T["NXQ06/8@PTO@1:)^\H4,!E+=]HH"9DU$"5-D$XP!!BM=%LI+@"]@YA -MV0RW]@GD2&81LBZN-1AH<=*OXRN -M"R-9U\XT.A7TGEPKR)-L?OJ$R4SWT;MQL:<>$.1[[`)UVP69-BL -MQZ@5*-`JWVB8Z'LR(2G0'*]FAJ&5B,G7K0#:D;8QD^>BZ!M]VRN--V[RHD+Q -MG@'8[*V&J:!2P59TP)%GSM/D0YS<]$[5&YN&\@CSE:DX0(K)W@0&>4@XA$^%H@.XQWV3/R0G]K[7&@N=E%-8V[N1Y?NC,E[B7,IN!ID=-Z/LTBBTFK -MZ/]=#%""BZ@<[WJPO-!RU17(V0'-SL\XB#PXIDPDAKH5_B;A[P%3+6+-5\+^.\: -M^/H%%$"^V"6\LL:8CU[2$CT:F(HK61W;_R\.O-Z`$_SFPU<55TBNWE(P"$T\ -M6I*F/7@00L6JOJ(1A@*0T%!6"GFCO'>BGPX.=XATY"4HVI-T/RII0E`<^;19 -M*VRP]#3Z:;[#SG/L1%;QG8MD0(2ZC!\,&;P]\ -M;Q43+J7K?\:'OY.NC37K/`LP.]/2RVMGKV^8B`#661P'YKI(B*OU,M3-`*&W -MB5$_KEN/T9ET>-QY[\'\I;&!\LIGA2F,=*\]KZ"W!.'S1[RV$,2>IO=J"*6B -M!O!:*HG@39/KBL]ULKTZTX1;`B=*Z13")9NI2&&M[6GB.H+FT(S?*F'!!C&NQ@=W<8F;[!?=?TW,)EL8L;CX+6;BL1G9)P0L0-ZQNWXRC0 -M)IOUCS?7:"N-A0HFIA+2S>:#;6B*5M@*MSO_G%-8U^K\4OI,E_.3Y'O;@7 -MWUC>>G3?P6T(H':(L5W:/6E=4/<;23H:G1$,9,4RO4U%@3YB%M[_= -M/K.W62IXW-BVC=U%R.[B5"8>'A1#BN=.;-W:H-,?@(BJA]:K%&#^&^2:-RLH -M%_R/,1`/BC0PC+B_Z&=%AIS]MC/^^/"B6@&/Z#MBB?I8%XA?.-'W??D/3\:/ -MC.QL%DS`F^E*"!520UK_!AJ8SA7K0#_DZE8PXN9[_#P:M`,S6.>+VVF>Q56Y -M$H).FC9R2/^QLQ57AQE:U@0:?\:>[@=8U`G0?^?UK8[QE@47<1^0]6`S(Z[1 -M"2H^RNU*76@1PT:IG6YD.<&5VGFIM6H8KB?I=#72JU-K=-R.LX;)T%4S%?Q& -MB7>XKI?4OQA!DK?W5<-N2`NZ]7W3OC\R'64RZY7='SX?2F2=`4Y9Z7XE8;-V -M>W`0[_Q67Z9.4Z(T5J_+WO6R7&AV@X<]1`X()'_)J'BMS4G]'SO!22>'0:<, -M+@#27BI+]/RI>[5*$"UQ:D+@G.OUGS#-KB7/=TWX!$!BW68H>-/ZL.T@+)4EXEWC5$'F^_E;L`_:%'S59:GQ:`-B%:_WGNG2 -M,)ZYFM^RAXYS\>V$(HLH5()%7<,"NV^`OW1DW0/\`53+S,$@H/XDTZL=@\?]R[%:9ZO!H%MZ1S')A+`%7V'S0)ME;I]) -MW*+G`X6V>>>M-@1*V@,^WLWE=>6A(VZ-,[\I2E-_3H&)+9BJW\^*9VT+4?8Z7#:1,2LC;1["U`YL -M2A*-KYLR!ZU\+I%;5:[GXF;=&E9 -M5V]*^*1[AR<5A^9(:DP<<@$6'?+T%G!JM(N`@M;X6%:#JN_7`F@\Q*[!6YO^ -M)B`A(F6#;7HB04QT8V8NQGIU.^&=WRV]1K63$]_3%$V5XE[U,GMJ*[FB53(; -M1K?]=G&%#.K&'Q\WK_XT3!5FF[#]*=JED2Z$4BJ\AG`Y(7Q3-^;*B1;=IX?V -M?U/^HU]^-N&'J*W_$_:Q+@B=K(`9(^XK-Z`]@1;'$Q(I*:=^GL=#$4#!/?K94)Y1A<%_P\1C-,S24YX/Y@C-@QI@ -M`EQ*I&8[$=ICJ#D!X7+)FN]Q6Z"R!YA,Z.D/AI!X\BYKBAX1,`Y82=//8E -M1;&Q.\2^V6D71THF.59`N^D[0H]),7*Y)P/ZCXS0$LI'MYLT&!81M\&83:/: -MQU%30:+NF?"0$H#T\LY]49=&PGYV>ETT-,W3ZA/(D0$T8JQX(*D'=7>0")^@ -MQSD]:./7O)O8IVY!'_""1U#`\/7Z_:%+Y&"=.]6(34E+2&VO(D#/]-CJK&[4 -MW).;98U&)+LJM/5PE-%?6_LF[,`>NL&X;?SXQ/::MT.8Z5:#JF$A8@>#SX28 -M%<&L11SFE\V;8*N(5&P\0*!JVT+.JBB3MG/0!]G!X3I)VR^:/1C0O#F[O#IR -M03W(A3=Y.S;A_[+;,;#M/D%4%02:84:#;,#P=]?K@HT.9ZG9G\3+K#!&:',W -MQN:,,T]FJTF6N+$1Y$OB/'8U`ND:8_P?JS)Y(" -M/D1/[HP\3X"O#?PV*YS&S+8*]2N%0\$^NV;Y/;BHL1"55,C[^Q*/%/N^'?J/ -M='4DMM.\&%:I_1PY7M"&+JYI&*"B2!`HL%$&,"?,%T8E;L8>$,^XZ?RL>%=: -MT$$:X+G9BMKN*?=U_P83CYM/2;TT#]SC1*\C8&&,1*=!B1OY;6LDJRY(R_T> -MTQ(R/`.Z<'5.HRINXSU<3TJ+(#O2]7,0P'=,.#>4U610]S$"51@/DKREJ+(+ -M48W8OE<"%%R]E(4H3BVH/=7,*4T7:H"GAS74B626F77:3#`*6D,E*,3S9D`GY78%ABME<1')-X -M.#MB'@=&F!\6$1S204$/[%Q[G3HI)FBD(,@[.!UYKFE]]=XX^NT1.JJS%V]G8@R-Z&/UC$C>3 -MP=*&M2HPBKS1$101S:N44N[:X+&89`.^>KL=EJ"=%./[3'PX0UI[E\5Y;TC:*GJ;QD1W?W>Z(JH[=KIE -M)PSM"=C"^/)-&C\E.;P[N,(L"YP6C1A4]"OMHBM)S*]RHH'5%>CY#1"RM?LA -MJ82HSES@"9)B$W[&'=ZQ27>R -MF"%EC0TSA="FR$;-SG9U>Z,XTTR8*D9,/0E??=CU-B8#>E;BBC2:-IA=,CN/ -M\S'];,R"S>(V\Y0;)-P!^JK@[N>D<-)*BDS47Q'+;T$Z@AKRZX8>203DHAP%ES$[3ZC3: -M=DFEQECJ"6M2#:\2R]6S(;@74:V]AS2<>`Q'\#+ON3U2J30`X8IP]N<0J:!J -M6\D)U[O80.HN,W_"UK(#I#I-."FH0PQ^G/?\R^H:RP%#S=>):8'VHA!>IY^8 -M/SX?L+XQR>S"R#VDF)M/R!^/.X&`(@9BFP*=CM33N%EH\5R:?7'S7\C;?U*7:M6M3J@9=:8BD&S7;H/UU@F`BO737*3@ -M.TQBIP*]&EC\[UCOO9=Z[#[P-<;_G8'RU:)@#1%]#Z+U\?].V8^BV:$;9FFU -M8!DP"O\,.?VI0W%N$OV.>S-[VAI'L&RQL(C,X*:I`Q>\(?ZL[]O]`06E -MHR$.B;)%>_;.2.BK>><%I3G.H9.?@"0K?%NIS>M^JV]1O0I6P_"ZNK!8-6LI<))*&Y@6)+'_XO -M29WQ4^*.04V@ZMM3"&>[S";U?G-V\56`6SW6%V=5Z2(`A@][E`AZU:W'H$#? -M:Q>N[AN_1]H/:$PU[IZ9S7J#(S3N8C)D'(1`GW9)F_W8`;:J@@MM -MT03.?X5KV)4A3^1@\COUXR_/*7'K7B!N -MG(?>W&N&P(0:GE$,K!S5IFJSK*2O3P+O?3;KU9021^+<>!C2ALH!Q=@I&"7. -MZ$\Y:2.FZH04P;M=>STDA?=!]!5@2!'*M(PDI^,-6EM&M+.W4MXXCM`NE@6[ -MK#TYEO%G0':Z4=]IK+[+K`^>W='^)3@(!RBO^59XF-:'#666^R&W,U<\9WI9 -M;P94`#0_T$CR'\'-H_E'EFB\82TMW;.C&O@W>2KFP^\05,4R$L-??2IALF*- -M$TO@,E`QV5)J![.K@VZ-W*)F>.,]EWJ3W,9(GHRUZ:58"2(`%MBF'(YN5DM& -M;O9Q[?>@GF856:ED.ME=<[!B=2->C>!DT!$1B[$CFF$N"L#&/PM2+SEV/%6K -M1:/VP;AD2&ZM-`E);UX14HPJIB(P9CROZX>N?/;1P%)ZTU/N4U&7B9-^D*F5 -MIC#<]-9]C+`WU0:0BTM%%"04L$`"KIX!1!&W--FM:Y:0X%&9\RBZ)YD?A7UQ -M?\C7K[*=P&,@)_\J5'N1M)N:8F?WE^+`0Q)$?VHJ,6PS(4-LD05IX.[J@XEA -M-M.UCH*B)\0*"TGYE$HD4%3VJ!5]J#)=]UT\L9N=6=R__7K"L17TY$8KDG]= -MSF@>T+.3>:3Q=SX%FT(#000&VQ9YVX*R/*Q9X84`)X>I&3_945$@S5B9..T+ -MF=`H'O+6$G;QS2+*HKIXRQ`PO]G!J-+8(09*GMZRL3.`O:_THP8N^]@?2=&0#"ID4--D([ -MM18J`CV,1D+ZM##+N?U-:72FNS">GAW?7NP\4;@W_4^&A1FREC.I;^NA'-TO!G#@("-]6816T@2/(-QR36*302\E4$,3"*!NX:X,X6 -MLY*&`3XP4@3?H+C,J",X[OD+HE<"8O+4R/#._K%I'DL:B-!P`SZL?KR7O:&J[1CLG@[ -MUYE1/UB`?I[2JC'3`6(/'>V^WK&CM8S:>]C.:&Q$HA(J(":J7#0\%;9YM&6' -M&IX)7"=7XZAR%*.%TT4E1^3M!]:Q'Y!'>RL``-;P/Y)B`J8%]U`<+2NM6IL` -MQ51F%6IO.J3?P)'@5?'.<\U[(Z9:#>4"-?89O -MX8@1#:.WK0H,HIL_P`B52A!R+:/2',JT'EW/GM\21+@S>$E0F^@+]+ -M`%=E)S`9ZLU.8V7YE.V1"]UUX.69NYB!OE+U*?0R=MQH%W&^R&"EC-*1[=W$ -MR%2S?D*>YG3R@C`Y5AA>_9=&X@.H,7YI31TYI%#!TBG' -M9'4]70*CYTWJU0;(P9!F*NIY*S@%!;T\@H>< -M4J7ST6:%44KQHUXUQ_9,R9DH1/=5P5)S_M0ER[''ZB4+\B:AKPD(P/%!P7+H>^I);&'P(]1YAM24B[D@8G8YK$>`1F!-2N=^WMO``-6 -MZ9[HU5N&N?YT7=8""S@>'K,?'S('W3G$&)P'?7WTN`TCE<>,(QJ#-S'&.A:I -MQ,HNR'OC-\1N@O?R-)^S)`_?SU!J8-6.\=_7<#$9/ZM1L85;]F`]7!UNP+-Z -M:%VT8#SZ$"]KS-QHT1@Z*]59SS1+9:*Y2BF`4\R'+B%U'OB[G"`6!KK[86VI -M[K)A&G!DV^56P3BM5\738P6H4A,7C[VT#9&.]YK2ND"5O@M5>'*S0/3I<7-R -MB2>&=(I>Y[P(GXHUTF6%[/E-P5IQ2J3B2OJVA-77-0VQ50\^($"XK[:&G6^9 -MT"U8,U.XED88!2:$_>7\5]=+P[O>I$\3N9$R@+JODA^J)/:QPW^?MB:H=+9: -M[\@[)^M.`-C/`%T+I@&B+"H%F[47:/A;T$8)P8]4SQL?K64\87D#"QAP1B'`O[%C^PXTSTL(ZSS`F]NF7D("WG9'5F -M!OZ!`-"AM[]E^7(])0KX&8L?7,=Y8/?T[+S[CA:%_F98MCSQ"A"]I=WTCA-Q65&8"95Z7I,ZU#\_91 -M$F2'&7"C&>(Q9AOFYF*Y>'GDH3!-X5O'!3>)<^]_%K4W7J>[^AN\5#=_:C]M`HE%8(3/`8ML"QN":?!AV`ZF"ZI%K!4%.BTR3D^A!ANU<^IJG -MF8N,P(&&$%QSSDEA8K6/T2K6[#-EWC<%!60FC.FPYCB=A>QSO2`H`0\[`TO^ -M5^W&AE:_$*T+7?:T?-5+Q@14 -M*PR?[2]%B\X5X1OT%G[V_C5:#UWT;5[\M5(V?+=OC&&,-XV<--G8ZISPP%Y6 -M+92;C8HDM%I:Y^U$YD"_T%307/I.G9/.AOYC%*7_`;O_7R1Z=\ZUO%.]&-.M -M49$0O)ZR7<3_(/['M/0B2.HBX?!U>D'*6ZE19I*HBPK -M/)\T9-")]>-V0WRF/'^`_)Q8DPX*-:?),X13R1+-4(()J7TX5.*[;7]@S9`SD>1ZY'D^;<@$/.#'6?Z,L44 -M7J/-4.OQ`Q9!A3M"E%4V0-Q2Z2=8]D@<*=J6@(*SZ[[LB[8^8?>O -MQCR^\N1H)9T92KZ55V?C8*9^K?:4Z0PNBD>UOEVST)>+]CR?:CJDN(O4T9R" -MD+OQ+G*'"`7FN+SF_4;AT>OIW4N<3:=WA:O<+.%E8UV<6TJ5U$>VXCK;!IDG -M-]B%,;9>UV8'^A8@9*?'`JA/(9!ZAE?I(S=)2B?RIG?QDG#)2#'Q.II#9BX; -M5,\JUHC:9/COGV65NY@OE:L1V_FYZX>A`P9`;^U5X;+C(,$\ZZOO^;,(BDR= -M9X%)4K\LE-]%2-K+[9CN%5@[^2;K[3/$9,(*F,**I_%[>I?GNSG7U3")^_A$ -M<**E(4?G62]%4+1`)G55,TM5\&+3*"=EGYY -M@PK3YJG2):S[9><'!=>9)9&IH>8']-?\4\O]9N+:>'M;['A\_4-`,5PW<:LI -MGQQ.K+PM-=*07@'($,ZNQ,^H5M(+;D.7E2Q^,U3M8Y#U&W.7'9]_#@/Q]&7"]<$'RIYK%WI3BR0H(0@"2& -M42AG*4M"O\@]$GM!:&/H*8\R@L:L#Q6JQOM7("=XSWLE%F"CZY%]]3+'WXQE -MNC:T+'<#56&:ZN?C,0_K74?"#/NOO/FCO2]PF,Q!G?[A%0>68V.A"]9UMP=2 -MXWM#29TA"_SCPWCZ#&O(3B67FH,)6L6@`:NY1`)MC0A5R"C;I?\B;-9J[8TO -M.WT_#AJ;&PA>`^?;JX\;KH9<(_?;^/CE!JEX[P^GJ -MC[W44A?\/XU_ -M]AC";G*+CH)C_D%+WY)&E%C9AXA]!L57[^$R[\@SL<:`Y^6RPHY1?6T%E[YT -MQJ`D9AN%PB5?3UFKP\Z7ZMTW)I7X]<],A3]^)I+VV#Y$DGC&9 -M\#T>@R@SS:\'>CX9FPZW::YY83+:27CUHU1T("]1F'"#3:VTDDC(E?5&@.^^ -M@@QK>=60]J45@.6L@RU`1!+E)%Q(.Z*#H4Z&9&0[.N_/9H(KD*`_7#I#-A,VFJZT#5Q?,)&9:,O)O%M-O<_Y8&!I -M_F,]H2 -M[#ZOP3LNP1ZU:_7;`>$_?P;P?4.W9ZG@X\D2_G)O9;H?5I'LN^=P#OW3SISO -MG",0<C+\*0@ -MI8HXJD='Z@]B7GK_&H9@Q*$^5?]64O8N&\D$I5!M%.8UE0/5Q1-1^0:F]6K9 -M),-9\HOARR)F8Q_/4?JW(&J6W!UYO&)UHX@0MCOTYE%XG50T -M$19%BM?D"W+)]Y17Q/\]54E83OEXOD*_;<]*"XG^]$MB\R7N_8.#W&G`>5F+UA -MG=!ND[5@V'24$BB`]^/E=$WU:0H9:0HG..8NY%H/0'/=--3CB,+A4DAC__02(T^4`T1 -M+"2_Z:>&Z.@@'I61SS6#QD`P7Q^E[:9:B"A$A*^Q4'X1&*"T`;<(8]2X;I*F -M:D9>G\L2:H>INTCX\INRSFNA'/K]M,8F@=@0C07KOOW`%EO6X%JH=9N9P5`? -M#73,"M[VJFM;29XS['^_D?7]%AL`B%RSMB:G]W0`)_F#1 -MR/5$EHQWF'6V"3^&RQ5<'(&52:I<[?]9]]B-FOYD>>_+Y#J"=J!EE`&R%XA? -M8589MJS7>[T[<,/A>KNM+WBT;AU]%`"'8!+5*",T-YACH^&/CB8'T:X:I/() -MZ-[UB\C>+I[2G0&YRG!QFA3Y+$AD4$S5B<:`Z`WL&*_K[2\W(BI=K)+V07;K5V/B@Z&J$U`Q:;H5M* -M<6B!;4IBBTO;NGUOOGGH -MN3K"^,KDY@VNXY*_X;_ZE0@XARJ,1^>GA`@N]!.+U%HYO8$PLD1R06XX$\B$ -MQ;S#*^+99EL?@4LP&E+?=4G_GII9N[LIOFZE>*LBJDEQI5^O;9O4;337A<"E -MP'>V45;>8*?\,D`O."^M>%@W\V!+.!.B&1GN)TQ/_ITI#PO#ZKJ3 -MFBEG%IQ"0,!=*M]:UBGOZ)1<+@?D*J5D4O:H+=/?3O[I=ANKDSNQ'?7$+'I+ -M,2KCN)4)M-DW6`'[!HFA5AJR2F:%S9:4Y9QF;4*A/AR:F\<5P;(R^E]K@Q79 -M:K@=5S!_`%N=]10!AA>[%JGTH:UN=V.KM^"LG:N4O\-C2[FT$)]A20";X1'8 -M1@:>A=%#<8XOD^!Z"Z]_O,$S*+'WB$/HO-KH-]VQ@HVRBAUKPOM1:U"F_GU/ -M3`I/W^`9H.FN?KY2XW$<&C/744NO?^ZF9H4?3>2IOQ_S\VVD_6A@BP[P.(.G -MW.4"'4>#*MJHX5HQ(7WE"_+/O[?C4P4*+4ES@".]63OX"SS!R]TXH"]K%>^+ -MNA]R.HKU-*^7%V56+!Y99E"M*RI(MZELV(Q_TJP!6L2U&@UKF2N^>679S67_ -M_0:3D![IN('9`9G\'.SJ'AF7,.&4N-G]H']7B*L1N?:#UP%*5ZR%4)'>.A-3L&\"ZBIF]/4-[:=%_LAN-69V-BFJ" -M3$IW*9))<#P@#'HW7>&CH,6(N!OI8O -MC_GBS*#I.UF^=LH46?H)NG5JF]N6NR#_-J%F%K_S\AC-(E6SG7#?(HWZ,$"`'"$J?6P&!=ED%@,*X9 -MN=1IC!EYM0B,F<-#^R>EZA:=[`]I/VR,1LRREAO7'5*D$50T\&)7@4&$W",0 -M:E?UHQWNK8@//F`E]9?+B@+0)%5;`G,VIJA]"M8^WLEM$O=X/H4^+ZXU/6,- -MQF1%)VWFZA1[AMWX1)_!\CCA:@WHU6[*#54!.!I(J`RP/1"8&NM(.-UWT4)O -M2RT+NP,3F4V(@Q3-_!?7=Y9FHG=`:=3\X`!F&9T6$F@D"K0OYMZ.!$MH'X_$ -MQD!T+""BYYYJ;LP1=:"Z-U'1"];_PAU9[=)^Z0,I;XZFR?:R>;"T,LQZ821N -MXJN$W5%XP-:(D_@#2'4H@4M.FKZ=R*'9-PR39(Q+\6+P4+YB -M#DH>^GI]'80>M[WS`G/6[[!+LT`E?YT[@961@FE_WJYW%"NT;`E"1U#:9[;4J( -MK_VV)!R'=>E^<81J!3'F;OA";UK-E'-IL')@!SB&&!LV_D`?2:IZ4PV+$0AW -M-G64\D_G2'PAP@A'+D75>EA0=8[?/SH%V1^207(0XON=L.6\8S0IREZE!:WH -M\CMSIN8Q4->>50UT#:;.COT2X#+OI4[+0<_3/>9&+?_:JYN'WIKI'IVQ)AJH -MI9```.Y14->\(;VT6U_?R$MGB@W%T$K5 -M`QLO=J.196-J,>G-745FD=GS3P!9Q&>\?!_)V?VHC:CJI[M$4N>E-5 -MJ[?U+B2'>`TN8!41MM8BIF!B_-9V'Q#;E#H63RH3*N8V',`K-13-XKJ2:(VDDZ1]5*':+P`F -M&Y-?'KJT(0?<[[VWNFYGB3(\$+-\WZ`FM_5WQIY1(]O8A02_*A[B(B<68*KJ -MZ.8V\T5#G87K:'N-*F1<_@'6G6ZP$M%TR:)3;Y8"H0_['E777&4Z:M=^+1"%5N2+\=\FM5'];F56%6)>OSUI\X`#$6J/VRBDT83_L,U1K\#6 -M8SY,[12[K8T6\8%B^_7H(CBN^C6?+?+F:#FKO:BABJ?.P#QPK"7.6JR3`3C` -MV=RI4"C.KD-*-9R2C]_'W['8\AW(;G:3Z(C.+DL/=,)*=T;KG$*'XBN77:2G -M\85.),#;?V?C(S&R2954G*40A'28'A`P:5YSZPX$C]>:8;M:V8?HYDW(!(L( -MO6=]%O[RC)&OMOMPC\?,F.GA+K#0G$2!]=*XL%2'?J$KMD\(:_T3D`^F'J/7 -MUKEVQC,>O\'4[,C=QE<^'[9BN<5DO0J7D94TL,12D7((K$WPZ?Y15X0)(Q8X -MUFW/=#F-ETH4`?F\+<'Q@&O/QVMT8H>NE5<_A#J]UP[\'_"9N+[#<8H%BJ/M -MV6Y.(-MJ%&5;UA_,1)`LJNU!]LWSW;DL0(I:VF'DR)Q)G#J>%J(ZV_(M9OAT -M:;_*T!5-R*7G1N:P&*44O5R4?)%.!CLSYM4V'-Z#RF_ZPI*R:Q`>XXY4!A35 -M=/.7_H.!=_/IN6-SGS*$_%9Z4UV -MB(,1P(]`9D6>,4";ZVGPZ1L"3_B65_I-,OD5&YJU5_RK"$_9?8(@*!CU#6VO -MDWL7)#R>4'[@CFUWAC/-JRH7H^&0,--7]WWR@GI@WVI6KB#9_K'+I*LJC$]9 -MG(((8\N%#7S(!I(5UQ`/^`$GMIW\%ECE!3MO_5W,%L?A%^B59TP'SB8TJ3)@ -MCMUB'G2ZPWV;R61>R9R8Y2^!/(=LG)**,1,TN0N)4U#=/<3,-87'.G&P?/:<*&QO0%Q+ -M_5YLHZYC,#5?A9/%H&^FL=^=I.T4$8VG-JI^[5H/W<[%98>)>>J^W#*^"KKW -M^5,$^VN'U/G%A7:*YNE[)?`U/>M\XGCH%CFR4@'M*_RA5Q07)B#B]XFD7$/3 -MCRSRTQO^F?IGPCHEGIN\P4K)E;*=[I)!(T?DEK<\B'G+CJA"-KMBNM3^S-$]3/;`B^+`>`,TM0LF/T6GF)_]5!996K10U7 -M&_BVCY.7]J]\T9>.EH1M$[AO>I94R.AF<^5&LP,V]`@D.6)<\WCM6'[,(8P51$ -M[2?V]^[A`H=P*@6FE"=?)]^.%`(%,0-7N*:M)03]8[XI0<>;RA,#Q-#RQ[3Z -M[8L9AJ8TSDDGD(.@A'4,,!]#9"1Z/-8V8C"P[IF"+%NY6,.WO*E!0T;1[QIF -MS]M8+EV5,13)I;20QN9!<38@6[/!Z(N+?8JEA8O%W[4MK-$&\V;AZU;0 -MRBJ^5PY$`&\7C7"2C64^R(RK%_0$GF>A3-_<=?%SZ*D5#>!ZKAV<2\$"D&!J -MJ&9F)B2JVS/IR_T-A;#]4@Q_CUWE$IK>!:3WH5U<_BE"X?_F/=1D)Y>)L:HG -MX$VPB>X]_*0J/O"R2-[G)\`XTJOK]%"$GNAY#^(H(E`07X.?A&55ZP)?T24# -M@PY4`RJBN"V?0F)ZG`/\3W;9?8<8L7]PD0-#+FH<^6L..*[VCF_;?)V.CI/A -MHZ,F#*[F_=H=$NEL@G[PRR^'*D']`2V!YCQMPR4F20P#J10FS&+J*1NJ7D3G -MR+90L<6)75`H'UE`K\#)-_O$TQ83'.&]H"5$[.K//7]9#H0TBUOEBS53J>X0 -MGBZ)!U5\*'9(U0Q(!/LW_C^T8'9*VKKP=:XN)8H22W=OWL^3EH#9`>`3OI]X -MPD26)//I0JY?>6!ZS$T/**=(EDDZ4H7Z3O -MZ$N$FZLQ5D;V9^+EM%TQ_'U\3`Q;M\62D/(S-1*^@*6F>S\L2WUK#HF3=@^% -MBL/CL]%JW+MMQ@M2/A\PEZ'PQ#^Y0(R[*N*09KW3!9*\@:E5O^?Y0P1BGKJ, -M$VIFYL;#'>6>>*Y2-_;I`QC4HCQR\=#G;U(MDP5I3M6"J7:P8$H5S=^Y -M#;8P/RDER>-WK-8&:X"T>.6%RME($,E5I6M%)=U5A#)`^G^,S6V+HKV"@;S] -M8T6?(!<\,9#/&5'H=6L^N#DP*_GBMO"0_"F4QMX?"V-0[,@BC&6>_85MX"8#'ZN=<1!G71LX@RR11V= -MTM;K_W`1H`=J83*)ZT6^N+;)RPC.M>"F^9:B\XU+`1D6*6WE.89HI?4^SGX` -M::H45Q5SF<51VI=,Q)#)EC%+B?*HY9Q_%*)^^R)KMGA2XT`Q;N$LVC -M#97O#WS_A6\=IY-8;YD4ZX573]Y'.)Q+S)5JK;569G8[_]@(AH*%*D*X^:BC,[EEIQW6^40GV29LR, -M3`7>3!9&N^X$KDY1'<3>99IZ(%^0KJ6>]F'ZI,\8L5C"7Y!5C)"DL'N]% -MNC=)%D,^WW+6:@EC/-J>9;N&;QO$D3KAT2U]^/"[:1#Y,IA!CY+>TK4EYA1T -M`;9F)G_+OR**9%_C]\!=`^Z>Z#TA.[I8)2$*_?>*8:,YXG$_1L,!)\PZ29K. -M=,Q.UE1D`5PW*8$Q;M-Z^=IK8[S?'`_B8!MZ'WB,)I,84);\]=]W:^"W/\/."Z<'2/ -MJ`I&4G/5"@7GX.Y_5#OSCYHU"7$!M;`HZL!.KH17VM-"+LP!%GD@72%&?9XM -M%AF1PXH=],X$>44GK)A1!+M+[P@,>I3M;6QKGKO7;3=IM9[74")$O)ZR31XI -M'X+W3BPTP1'`B[K;>[B'OG(/&W3)+;(*WWB\2PRF3&:=BFR"NF]@I;P'ME@K -MF^+FS=I\-I?`!TR0EI4-U'RBN*=HIQEX^IEF47[E]T3Q6KW'IO^$1L13`[/: -MY(XHQU4,&8E.*8]PDP9(XY/<=A5T?S[_V+G1FX)&E*0E?!98`!2&U)T\.S#/ -MG.@949K7Y);,^PXQ+$J1F%*_]]S"2;3@QU<&/S]U.Y:B]2NPGSYCNAOU_C4V -M&53D\X?Z6PM(62]`765U0/R-CP'RT1`75MP*X;R?(2MI?+^B743*.W^W#T;5 -M'4JN189!''Z#!S_F(CGM\\R@/`0UT=.8Y?+2'H7WJ6T9)D_B6IQG?1L1V -ME<5@]QL!U3[W^$::^=[9$^<(F*B=V!UGT>.80'2ONZM[843T78#6TYW2ZO^7 -M+.5\&93$.4<7RIOD(359H@(7ILT5!,)J[0TW-;_`O1^^B;ND^P3!KT[,?9>K -MF'W+""LL6H%*0CD*JM#TI^WC0F35J'JC]/X+)5_V0Q\0=-GZH!>3%=85>O/NFG-1>^Y5?:1Y)%!PG9YC`..*9D.&MGRS-+-W?RX_ -M'-=5@Y%;I(P#`S4>],>6G5HER+?40(APT_KW9?+L;^>H3"7QU\IQ5RC2\M+C -M>Q]LRU\#,6:[!$[^#+)7:\)VQ3"DQ3]PWSP>]N\^8JKZ]H$"*W)-6Z>V`&"U -MOXRI3G-70N7-$CMY#@M^K4MA`)3).I>6BJGG/\Q%]+XX_1N[EP_,)/E+ZO`3 -MXSKAI;G1QH#7.,_06IWL96MZT^9'D'W&AR_Y_*@9$,P-K"C$J'&%_HULM1"'ECU.W. -M(6BS6"RDVM0*>!AVB9!?CSJPM87F#C'!CW+Y:B,X/+J(\IEDK -MRPO23YV[HLR_>(SY$S5P$;Y#^R`"0"&#?/*@2XVAJR7:0$HM0(4J;\G7OW?U -MG59Q\C=')&5&;FA/>$DD;"KC-_832\C\NQ(N7>SGUB.!<"[$J?1MYDT&>^6T -M.FTV<6K>[6E"8,L83;WR*Z+\%G&*']=$A3>I!+_CW5??NY$%$THYCD$UK5"M -M-N<[U%06(,<[E%R&ZGI5`@90??_AM0A032DF]A8AS(CZ8G[ED5" -MY.TAG&B6.J%^N_CUNU])E\$C]M7>T[A%RA"6)S]<-;<6;1>F>=S-P^+#RE<- -MENRB[-\+*X.M1B6HZZQ3)2,&M\O$P_]"C["V\6C8KTE34;/X"?C!FYK"8,UT/+ -MR(6J#!P#?TSR'SOV:B@;)]6;XK>71RM6`5N='OJL`6OS(,I@HKDCW!0/'#C& -MH,@G%Z<#3>=1C[J"*,B]R?L1;#44'OQ,[Q"_ZQP##N&V;H'6Q7?$/"LZ1=\N -MUV%TBCVMVPNLE2`%1$6J)4@DP17@HF3TY[&)HE)*RPAV0W)%'\29T0)2N0K] -MPWSW_>*.MM&?,G7MN+,%X+3R^G[!./!8?,9JV6.3ZR/9`H'SH#]((I>*D^6QF9+YC"5+HSLI4>5$C -MM_.CPV56[G#I(6Q*6O;9BO*2%:N@S)L37@)M3R".RGL'Q/0;W[J:?[OS&;(Z -MQ,-Y(#RSB5B-BF+.!/Q6)J4KK?Y5:ET@HJ&5[GL[JU^M!N#9-;'\D0[ -M$[D()`CUQSLF#UA@;_<[?:L?B8[F7BKJPI+[%8&TC.8((78JH$&BAK(E/U^?LKJ@, -MNQ9W-9;&C?S"2.`TM.P\7D7&!9)W`?1B^Z8^(V&!78>G/71S?(-M=T;8"IP\ -M,@5?HZ)Z94(Y8<=K?JF4-P:"86O_O=@H+\-B;.Z^8V:/W#DB3P$I;#>X0[O0-E=&]-I"#I.#\CE+?3=,%=3L"1<=PYW3H37UV[7Y&BJDC5U -M&KT1?>:=J&6?+XT0-FWG")A\Y8B#*_7413Y1V>W+Z&K;!D>EZBI6HY5K?+&^ -MP;*Q4?@_N$*#"XDN4QR*6"M%Z]KI[4`Q,%+?TFA/R]I9 -M!/&,6G5ER]140#4*>,'DJ^8$U$S='1%OTE*.S91=J*,?F=.<(F]_P*E06VMC -MNH"0D$N')=7(A`,C5GIGHD`@13O"86T^_E;ICRT*SD))(L_XTGIW`9Q6+=P" -M^YX4?.V?0=P]7G078OMM'_^H]'N"_[SG`-4R'XZ3[Z%JDJ*T()`"R7@EP6JO -M!2['P9)X*.U*1P8ENA:?_>ZIR-S'O[)#S#VLN4Z2!?D4`+&G8*R!X8K\V.4A -M7[3MLTX:.*;T`*E:2=%]&QO#*C_E[/1_F_==*>.YH&NTL:?'LLC4)1'P]>`S -M?2S.1RC[7Q#NM_J%>,*5YH(Z_O^)<)P"9ZK?XB4!9))%"87%>([E]$@7X0AN -MJ,(I*?L\_6F<>13($VS"T,TD,)@Q"7]JO'@U"B(90;OQ":DT6;*-ZDOY"J'$ -M#?.\YP=<@%I&NB$#S[ZA!G2J)YV>U'\RJGW -M@6?:2Q,4I1Z##%X>_@.44:L8=X-T\2/F*Q)RHAV,'I2^6GJF^@%->TFVA:#:&ZA'6FV-DMW/FKOT_>=K;8!.3;LN_YF[ -M7`K(_?P1VIZS.$RL?(DYE`M+/"KS,.\4&/#[K[#&9?TH),@8QZV`1(HF@#V_ -MZ31-19].YA]5B`E\20KCR[MJWCE7S]&=`RZU["K*>&4>?6ENB@C5?;U*O4]* -M*]3)';,,$*2N/H39KF&`;`L5@TJ*#/1XBJJ`A^]QF(D`!].BV^@RD@OV4M%M -MGKX%8:GD!L1OW2^/\)WEJ]W`!?)/DI#3*XS7YJ*"&AOAG,JN]KMZEYHAL7@; -M]\/5$BEY\(+D`0W`ZT%`4&GN#5Y=W*PSM-+:@4K:7EUDQ-#_+R0T@T$$EK2A -M2@@T.A+02%2^D$*X$DT&%2TY#U]>A(C<#B`0Q])E/W63L3P[L.CS.AC8)(Z& -MO%=?SI#((/3>@:T`?E*%7K@H6[">\)%X/P(?RB(F!ADK]OUT`]Y= -MP=U2ZW_,*:ZH;6[JQ,=0N?YU/?E-G35B@T/M(8%\9UJY'A&$T6&?MAQ9),7" -M.Y72&)X*`GQ6^5(Y>"`^0H2J8Z) -M-BA.B-@^G^H?T'YMRI5K=D9=AEP>^<9?WP+8G>J??.XN'B>FN[+VZV@UNJ^[ -MW?:Z"XNV5%)I]SIA`%NDKC._:/+3[N,PY6G,HS&(/T2'/]M!"$\7)==U]O]0 -MM,0A9E[M6'M3HQ"KE;&G\QE\R_$T:('!K#'<,^.[K;^:[Q#?U$V*O[RH!>1T -M=='LC\>/H.\'].=Z[O\L7DN63 -MW<"L8?X9J,%`F56;HGCCE-;M*P2369Z".;A"'E_)V4Z&DT=SUUGJO.5PB/ZM -M-U>O^_<<*P]_5%U(DM%H9*+M":/0I=^UF^*P4=OB?%/15FD*DSRE20;@YP") -MGP+5D^17)5;Q<#1-TU'Q826V!=Q6?WH_RM^$" -MUN*!/#0K)#[J@VELI.8?*UW0-I)I$1E7VN^MKOC%+,8U;%4`V]QR[&@1%2&7 -M&[?)2/$&5--KH3I-:,!?;;G14ZSD8P23T(EHW[I"$5NTE`/I^Q%96PZ0EURZ -MS8.EX.YJZ?KQE&<4)6&%?.17F\D\Y4@FY<"4V\&(IUT!)9,MYOTY -MF[\3=>!D#ERB_[2>K,0EJO(EHZ`^R>=>G;6T^-%Z7@9:N-4WH$==]LA_5IF` -M)IZTZH<]V5&*K2\#*MB8;Q9V`,RT\MMPT8#*"H(TYL[H3DNZ!,B)%37#])B> -MW9SZ4]=U\\\A[!MV6.$C1%L+C-=,]YJH1&2_D@O%N^L[8KRTTI5[M]SK(>!DOR!MZ=%T$`1W59WR(W!BM>> -M2)O:FPP_C/J"!3MA)OJ/'#PCM/*<_*L$A^W06J"H'31Y)5?7MPY>?Y5H5GZ8A5)8AQ=]T9G"E-4B:5Y_!7"P-)#Q/<2S2LZ'J` -MQ_TB:EHY//WKT$]!LQO7\JN/LMRO%9Q%>//(6R6GKLGV`,K=>2C0Y^<5+[7+$-?(J<)0I^#EGH=06 -MK'*+(^"L"(50GE-OD\;"X$H]H:/QK]%6H?R#EHLL9ZC;6@-RU].G"C(#-(^OQN=+0?$72)+?&95'ZAFLJM;@IU\D-YJE -MUY\;N(VICP`V6X.3BV(84O-Y_7*)!OHCO8%5!W`AV2Z7`.F+@'0.>4#57_]! -M0)SR.*IO80)T;8@KEG?WT_U2()#M%*J4Y7YFO8"R?IL*,68S4QQ=HHL=!7\7 -ME"_?1*X9IB_'#"-,S1#/A-[RRQ*$+A0V\0+P1@\V'%8M3EY -M6Z^F(0%_\P$A49V.I>G+O]-[/?C5&-SA$)P!]V/*E0"W)$'=HVYCNEXZ)YAR -M%SOMZI$/R[\WCXEK34EL!P7&80:"W03FP^>(Z"],61$?HZV%V#4IU>-&C?Y? -M(>LA(!W.36EN:=W(K>=?NO(H&^V!"EG\.%9?X<;-C.%2[@%@K3JJ$,6=4+SM -M'6R7;[^6@-(&HU&?8E:IBS-M6RT%`<`21-OJRA^..4=L6?DQH@Q,E80J, -M0[J+D?/7DW646?>37-(#44ER/)\^CN?ZR'"I=IDOLLOF,A%6I^P4C9]@V'>9 -M$WNS,;@!^5]6#^&5PRB./C+OF<5"`+D!AA6WSRJZ$>2:\%K;TBB<-/(5]B$/ -MM<6),DX%"/V\BW8JEG!10?/EG`V5A?3G"J4DH"]M#S624P^WZ>:>;%".2+%L0`N4@(BULA>H+*!O.HU -M%?KQ"&-]LJ]%PGX=(W5')%;=\ -MWJ+VU4.Z1(R0D3J;;<2R>"$B#\GGHF]XU?FE?YW(L;#?=*^^B>175.Z.P6** -M@2-M=UR0&Y.]%,-&)5ZL:OK>47("Q,_"&->PAAFHY?$?-6,NH!8:X/TIV1Q*19`%;EB#75'B!@#WS\Y`2)0Z?_@T(^!E+_74>(MOVET6PRH-B>Q&!?#^FJH0$/RFWN7\T?W`F"_?W-_ -MIM$W^A6>#P?"^_Y;162!Q*@]4MHV]G>MW:/XS``P`J8JIC-5@]'^V6BX0(5. -M0UMK&H^OX^%=U@B'**B:WZK;=-U%=KE(7RJ0+^?MC%Y5;J$V.3%`5O52,#7! -M^//6IV6)E4]V:5BXU][VG_`AC^]#A??@F9JAK4HA"43)@4E4W -M?-KP7_2NG*5;V^:R/R+[^XX"U!HWMG%++C$?=.9DZ2S?9U5ZX$5""8:SDV8A -MHSB]V@>2Y"X@MS:;\'9.`%9;:&;$C:T"A(&`G?BTGZ2R:@6O+>0KM,BL!.YI]C8S771$I6);1H[CYB\&O:L:- -M<#A%C/9KOABLJ8O/F\?P38-?:Y28P4^\)/K8_`92]5DP<%CDBKOCF:\2M'W] -M-+8`FV)U+RL*"[;P2TCNBC-0BH__+XSIKUY>T\2D';)!/\P3'>36&'KU<\9>G'PX43!DH!CEA*"^;B*`/"D28(HEY'O6L6*0.L -MD,7.UC\;#8`F#__Q&#YM4=/:S:#9]T>.^NNEVT2R\TO'[-ZP$;JY=@/M)P^E -ME$?8ID$&M_DYGXX=`L',:Y]FGPWA!(*A1C)H)\63(D`E@_EDA;IE#_Q#L?-^ -M#8@"$&W(_-DI-/4)R`5.UK*[9.A(ZJ^,K-]#GBC_IQ9UE3Y*H;8FV&\OP8[2-CBA/"T+,3,=C]%1>3=V6<>.(Z"<&JY!(&]_#J?8 -MF3\]$2W/3'2KA[5S-%#U\%B/Y.\-G*75IIBBNQ`+3E,*A8O53V:.$OT@[8+\ -M0,-XT7P7=B[;L8J924EO:N9`.LLW,,&-.D!9*$V<9974S]EP2F/@IP(JKU*F -M>T?N#/=KXV6?_M&5J']LAG76T5.F++]6_1B@M[J^WK&"YVG7IA(Q-N'1%H_S -M3VJ>'N!8Y73V"&+8*V>OZ\#H]86?D8^+FG2DOQ[ALWA[X\N0'!^FE -M<3L>E=DDRM"T@U^1-VE0NAZ#IK?NE>0>5>C$SVG!K'TVC1]AN^.O_@W](4^\ -M7N$EL2Q'H./=+K8.<#@AM!H6KQ)%W+2DPI-&:$O9'H5&RM*_W?.IT/)V$MGN -M*X-,)@3IWPR'5* -M%;,B,$8@QVK^CD)8S<.?8MHENVZ]`\G[UEN]LA#-V-G`3*C\`*P`2[^[QU?R -M"G0@*O=CLT_9UPF);Q2J2KE;V*[$L#$>%M^+A,'NI5]:C5?P/RSV_*`:#,-< -MENU]1FOJS5,:QI)8C9U");:MPT>UEH9%@2V!=C[3H;)T3]HZ:I9\VA11[E@R -M7*2(X#;Z7#RQ@EXG&T07302A>%]F']LJH@P5$&Q&?.]Q?E5NV^VLH@11*EEY -M-Y$YI'4J:ZVF./>EBZ`M"\P(H/O6IYRC%KUV@\[4?EC(_D -MQD7S9Z75";QL?]`]W7S?51QA>NI^@3<-9TI#=FL;PSX[F^&*Z^;\#7UI(ATP -MSZUB8ZD8]1CI&:?S0TLV@_M#\_$B4<`4RNOZ;!IG[)N<"X)>7JE?7X&1;OG^ -M,\?M29Y#K32^@S._Z'F9/T1UO.DUA#CJBH)ZE,RCL50K4/2HSSP:$^TQ>M6K -MV'2J@EQ"0X@:JYXE3#=2-M@.:^/5)+?.8WI/EC`.5[#J(WWWX(CHL)FTJWCJ -MSVGOQN)DR!N\DP`7UW$IWLJISMU8(@JH1:G4045 -M>Z]MBRA`>W_M`./90<=6/T0BR%[]^OSL*+;4<%;.<&F(_?E9XCX'./&`RL21 -M?7<[."LSN*".RH?8\\5W(KUH']E_&/=0J%"3B&^,P9*Q[^E-E0"&402AN?;# -MHQ`+>>?"X"E&1(Z'4>;`JFF5UKP6;_8,72Q"X,4BM]Y,2/`+M02_^OZ/2("G -MZ=V55U&&!@+,IU^E.`,R0,Y*O9GL+>1[KPO.R@E(S,$8^0\")+W!W/+("&:& -M553X_!+O6W&MC^=23PK%H]HH%4_JGLI00>MARH69I[!^VFSRTQ1F%X9V&(_Z -M6?(?QZ&/Q;J0%%+"HKENGD.# -M:13**(P^D"&4+4(/6T88N(W>GQUV"X'Y'$?=J/.?&>?NX/PVM("8'",)*.@6 -M/A?NEG&$)<50]:OC-MRXU/AGZA.@,NCW)6OS#72]P4\1"-_@*U3,8>N][FQZ -M_?+,^U$@448&?"RDY;NWQ-.(S;5N)XV];P>3RU%EF/-W'LRK;%-R+*)S?5VX -MWPRI1-ZA6?E@2`1AF!:;(#$"GLJG=CY9>VD0',5WC0(B,7^">^N9JX0!NFG. -M3FL8&O;H:AS"OX7_Z:U"DWB`+\QO?OF33RW)C6JW(^^,-PWS@>ED08OI0"X\ -M,`6)B@:U+:[?Q3[C2Z62:*^^)FR0QS/7P*7SA.3)]S8`YV;'DF%"/YH,[@U[@*'V&>X5Y^OM#^MN>:S -M=O0O2X#6V5[J\4QWT0.:@76#'V!L7P&`=2.:OR+48>BWQ_E\+KZQQ&N)2)7(9+`102Q>?/?+ -M"[Z<\`&I_$Y8Q^]Q]$D>/0C4!YKQ3S$5"P@)T\!A8=:6=:-13$!!9_'G0O(? -MRZ(9)MO*R0*JK8F9]&#$X/N6/FJ;;ZNNDDL4D0%G\]@]?+\!ZEPTPA8V4(8N -MS%1`1O]%B+RS5/L9JK/0-+"M;/;PVM)Q4$1L:@HM(HL'G:TA,K.5Z^^RH(8/ -ML'U"S8NQ%-1G6<]+_?]VX6JE-,[AI*C-(D4@4!@:?=S]L2K\UFW:XBPF,T1B -MQDVVRTI>4*X"=&\A@J4BU,@4:TE') -MSVW1C#91#[7MB1&`6!RE`^!`32@DP'(1V($M'F6L3P1N)KV<82KD,_#4J09^ -MFXG'B:G)7E)5;KM:4&XG:MHLS/<(Y>3A0PA(MQ5+8LE5@)M-/?9/*CHYKT\8 -MO0,3+V?\6S#YNN#^Q%C0PKJHWL55,4&$_ -MGWDL/;O;^.WI7JB&\J=.;`6;G;NL'0Q*O2JYG@M&G^S!ZG^4$3"M!0I0V8<; -M*P>W^T'YTOJSB]+F`B]>4O7TK?QY/Y5.H8$GH!$[/*C@=6AJY!LY4DI_SES3 -MPF,6O/ILM]M#[/,H6G+T*R8IK8GWB>:E%?I\Z[SNV7E#]N>-(5\2$7=_`Y-T -M^!LNB+S9F0Z4]O_YIV+8G*.)@R@ -ME%BS@O0Z+@:`_)9:(QC447S]:,N$1"7XVSBNMZZB/;S7IU=&X7GOE&-.N6X! -MF%(Q12,/@-:_VZQ2TP+D%F]_QE*:W#.L=2I>NX.*E^_S]NW%LV[0EZU\%PZ& -M(=E=BK"<=[/NTU&^.%"["0C1#5:[$=D;UY]%O*IG[;#%)L3`W9,F -M?!\%2GYHA!F1"0-`7.KX@YBP1TG9C*GO#"I+-E/3*CA.^;6%7 -M0(3Y#$/F@N366WL`]+"&_^?XBTL;06ER#OAKB5U6SCH9B50@44SNRR%((NL\75S\W[LCS+9]!+'VHFFP$$XZ4W:)#C8[I)+8!U]8. -M_X2T>G0457EW/>KMV2\`\N4-(U4:@LG],,YX*,3KD=M8H'>[Y)5I=6UWF;/X -M;C[M")?%5G@1_A5!2YQ]IE,0ZQ)F#`1U-'0@4(")&^X)XSB4M[GHU52W,N2) -MZMJZC^B.R$]H&5BZBPHPOK#REO)U80A#EH1E@>VO"3*[E^=)XB&?TDIL3&W$ -M6KZBQ;#;[?`)\GDQ8MNAT.>WDEKU13>%$-.A/'L__P7FQ/3!C77ELBY\`QA( -MU9=HT)X'8OVHT]%%4SXX5Q=A#[.;N,SA\G*_^DO>\"Q]/4`0D[2A-F/UTPY* -M27[/G2B1U0!C?'(6K`\F%0+28AA_(3TGX8BZF0.F-AWP@Q2X\OHS0GOING\VDB=&<"7?PU-M+%>]&VLU[XTP4TBYA:/ -M3:<%TD&1S71A4+&]>X/Y"N$G9C"WX5 -MEJ*'0*_HEUBX]?S_+)J;;!-6Q(%$TW`FYTGZ[OO8GP@UK.QGL4"I,8SRO358;]12 -M*F&ML/AN8([:/FX,KS>FJL'1_=8``;.:4G! -M=)>N_ZG,K\)V[:KQ4A"E#%JJ)RU#]!\Y,T1F+4CL:R^*.L-'#2*+5FG&J5V% -M1&1&)5K`0S8;7-AS_YF+"!]2&'28LNU1]<$^;F)[\VR@OTAC@I';,/%J<-1A38J[E*N> -MV!>EYOQ\*;G%*JZ3;F@^C53QX7X$4!98,"_SKZ? -M<;D#4[/8G/($-Y8J>WRC6`[@/5W=G*UM+C^+A'TKE3*J%P+^^"8KF,*SP(P^ -MS/;]?W9\R.#BD3R`D1UWVV0X@WU1FE1ZY/J6AG]JSR?#[`GY9J+J):-^D&*< -M&:@+[A`>J%2EQ")K='EQ9OB*=DWRZV+2HW:0AZ&KA8H:T+WX!(YM[#"H$PV\ -MYWEYK,EZN'?&P=!&6\64+H4A^F#YLY_6G-/B`JX)PXX]*S8#S -M28($OH+"%@N"-`CZ>/=`J:;@@[1(2*WK7RIWSJK94\:P%J# -MRVAMX^J/]!\PUV6W]JP4Z,98;20-%C>;[>!/B#SVD5SN^(6,.I_N6/:.I04< -M4?_W1_-L^"NB3G5[&(&"KBP"XVZGSUM*>:93=3[?>F[29HAR,86;2AIX!/R' -MG(71$R!VPL8QFWU?A-;)G5#2N7BP17O%)AK]?L&KC(H1((=<7SG -M@LX6HCS[Y?QSG?K3^B]_9-.HA+(0#R@Z^DZ\1>.H'$:%U^.5*Z -ML<+;&YOW8O$M7-DY^F"C&X'!RE1?2D]S<)"+/WJ9(GFLFI,JTAFHA6#*4H/, -M$^4<@7R+/64MZ/+#6GBJY9,M7\?7Q48C]ST&DY0A!WG0@^-(S!:J$<$_L]@I -MD8PSC=QUF(8`'/&<'K(*)7V@)`_M;]`1(N8#K\W: -MB.J[452I<^>=N<#463/D6BWT2.3I>EU+\G:@&R:Q_&TA/F+A>=.]@6@HC'K5 -M([W#X:N.P+DKD'QQX?OM31H@9-6%"')A/%L5D7SUB4)3L!=:P[*"PF7^I)[=86,6+2"K?A4@02I%PV`05UYHZQ/@+ -M/%C838J"_ZM[M3NJ`(9`48=X./[LJUIF4>2;:W'Y$]0:?BT-4B_D -ML`&`5,.]K4#HVD'M#V7@$&WMOW+T^7*J^KI4O-[,H8AJ_('A@=?-F"-3.GY. -MGP3H6C_MHJS9F!5>Z`.*@LPYNY/F0?!61`-%TQDBRA:Z_H]7M'&.N4Y/2.KI -M75\!CRXB-\.XY+,&.W\A==O:HA_@9U5N-QRA>7,E8J0KI(#4*PZ"Z8GYV2_# -MKV#Q:AE2WSR#-.Z=F;J=2@3'+J*.<$`QSXTA@7.UO+/`F$H0`\WA,)5+(V2_ -M],SU4#OYM\/X@:@&\Z$K]W@59I9=&)8-=1BZ2PC'KQSY8\H2RZT8GK'@LK-ZAEREWM;V[??J/(Y4QM:!P-?G+) -M,]07Y]`?@(_.O]'O\S%_5:T6Z@N@7_4?!/IZD8@0V[W29V623># -M;:B&CM!W^W1FY9+N_^R]OYLWO4OL`SKRK=L\DVW@0/_@V%02>?!H:H]'#98@ -M=JX!V9U?CUO"NUU`1$90;:$8A&VUBM;^I7<5=0?@12_GQZ2&PSKNWL`;VKOK=E$,U&)+GN/]_&'UYZ1* -M]3U19=6_GOY+8[N\[5#38.+RP+.6IMM,Y@U!#2@DA&T;SV1^(B]/QKB1UB5B -MND1X>`=7>2/NQ+&(`[1=6;C&#%WI%C9_DC/2A#//5;DEVA!W@A_?'5S!'(=* -MV9O@1? -M!Y/O.>%W(+'LHE5>A5:'[WI_=-^>%;2Q:IC5$YC0@AWJ8!+Q9`'1@2S$N&G' -MIZ]`F]0]?4X^VD/#A[M98"UHH@Z09BWNZN<+W`I5N$LE;[U[`GA8;]U -MEWO+Z1#V#;X1,F')U0T'<$M5'V%>.J"@YM:ZLI#Q@Y"=*C.ZE!FA8GU<3[45 -MXY;E':F\_2`$`.3\+[?;]!@Y"MX%(B*@3=JED0Q@$)=#B`K'JM(E_`C@7"*M -M(QUPW_O:-814ULKKEH8W`5#),T%C[1 -M_M2#D*?>7 -MHFAH.'A6]#C/-1*YE_0'?_%4C0,)XLC%,3_??_G7I:.A)*:'4'Q?=>/3CR@< -M[RP7JAR.OXEOP(H2]IWFJB'D2(XT$WM3O"<"Z@QN=,[CB+`'W?EV7ZZ"R5+GRI4%C8VHJ4EG -MF'+M?38SN-^$&LN^5UXAK?ZE4YZZ.1G4;]T?%<$"T<)30HVYW:?-9N5_Y)CJ -MH7(E[B&T>0;:,!ZG5\9\6"L1/]@/$P'79\/%T`07!"-5QI-UHMV=D6`GAUE= -MJ-.)VT2ES-QT\V@Y.8\<^M[OS9;^1C#,NO2_GU!`':QM5QJC3@Q:O7ZE!6W4 -MW:&(R0@CI+HFX(`&G-)0H=A824$?BL,9B2GG'@*EAU$V&N8C@C_GN/9!U\2F -M=V*5C:EAJX]'TT+2=D!.@,'=FJ.%TEF`%7-!,YJ::]*Q%KWI&RO/$Z0)SZH7 -M6/BG=MVPU.0=WVSKM,_4THRDAW`3+[R0JC'KHD\,-?+/*-@5?&K>W[9QQ]&H5O>GD"GQD^46`6DK(X -M(L<'3+]HAQ3B8C!L(ZL^*NB:POP%A:U"F?J>C`W6.,/A-6Q'#)1G28`K -MPHLYH^*<=EOX7^Q^K5,\IBF4>^T"_D*7`Y"]*#Q$C?1RMA4*=,?;RT0V9$A+%YK._UAGJZ`M[/H&RY--+7/'"UFL/V:KMV6<_$)*8+U^(-@-]8!O+`I8 -M?<&A#Y@X;#2.-"J\F9:5<1-F3+U=1&11N<7?RY1^8VW31L. -M/Q;+\:;8/G.BN6FW=W?F(0(F&(!:%A-/RY]XM;_#AGE$UZ^2+^'74V@CB]-2#"ZR"'LQMWG0J7CG3N/4AV!B)*2R!+&H -MP7^7^!GF%AQGU[_SN1:N%'=#A[D&U+N4=U&J>D^*TUZC3<%(O/JFNE-*8Y -M!A_H+W6OYSUOGKVJFL+]H=*+X`I0P:83!Y$[5L#H`(+[>5!)5P=DOW^OSO -M=$KDSPX;H:D3U?:Q3!CB0'-=Y^=A6ES;4R[.:YY&Q\=^X+NU3;/<*ZMC#745 -M5.5H;10422V.W_M9"T\(A\SK#BA)5HF@;?$$XR$>HP*B09+\\@"F6D])DI6O -MB,7K3B=C:,!I..WS18UX)V9CXEA!;\&`WB/T3RA\;T%Q;!'8/F+VEL'SYO"$OQ\B:* -M,60;2E+BS\;[B@)P-#-AM10-ST7=L&ANUPJ71O3A"/B#G4VE3#NE#NO$D?ZA -M4(?#!M=N%*Q<@ZBMYSUMR:#C8_)U_,T8I2]0:*9-KJ>437CD+J;&)HQ."!/. -M.I"(&3D\6=X+V9CI^EK^:0`%*?6Z?[_A%+#QY-5/#E($$0$+M0RR%I'G<2&(/_)K -MG&PQQ/9.5X\;(8"V'*.&@XC84V>EP%N;5DRW&ZLS#@!M?IH\#K@TJU]SH]5V -MO-_.CX`X@*1[?DQPD14@&GM&P8*^F@5&N%4*&&$+D[66[Q)9\V)YS.7MQ^*T -M$W-@9):D>+@0XB[S[>9!OJ2_TG],'AV76=*F_DFFQP^#]X(*/W7Y1H&XQJ26 -MR$ZM2$:@XE0ZM*4:4VW6@G=_HK4UX43!L -M%+C'/(BM_YJ,!6F%/";]S:9\YX]G"RBG/NFGR,>\,@8C'0D^PE/.?XSE2N\. -M?]R/0JG_TX@"4K#X2&%AA*F%!(;1T&OA?'QIP&RD:HR,A"8K(P>MAR@8YL<_ -M9/)"W0S$ZC^PRB^IPF_^K']AFM.JI%??28R!X;W'\.`IN)R6=W]EY:*XU,): -MM5K#=C3RBW:UGC>P#NW\Q$^:1VE.ZM`/ZC(C7_!*-XWIEQUPMAO<1P+R;UOZ -M:TJ"!#AG;>C#-SJ"K);.:/N3ISZ5JQ#U3KXLWMB77;&9FS0O#P]=9H6X#;]EMG-_!39G$,*HYSP16G>`J(PI/E=QX -M)EPI8A?RPSH$=(>WKOB>&%F?L^6JP`T]H'96=#!*'RA#C@9P`"Y^L6:!-+&_ -M-YZ<]*.4>WN9F-.9)I2;IU1@]D'A?4!(K"/J<'!H]KH!?IQZ>[)Z]KR:5EE^ -M@GI+ZYW$JX:7^A!3M8N&:L:REV.6="U#O_4"FCTHH.:@B*4V95E;$/-!C^1X -M;AN6R355`W/N*O/SM&3XSU;!H=>>.1,D4I"4R7*TRI2CA!$<>8J8'_RX,H5+#`)&QK7F@'B$*+LZ-(P_ -M=XF`&M$SC76#!/0EE#CH$$B@PJA!TUKKB=U`K"D%E>`:U]A$S.3?K=+DLMPQ -M))H0^.S6OC(.QQN40^BAN(QS"T=61`[NL_I1/_814OV?^K0OU%6B'))IIT5= -ME[&KK];N;1+X$2R!N.K(B5A"&\+>)"=[.0%K(=B++OJ4"GHN6^X -M;G>?+>%9U1ZWY?X\S$=TD;+K)=>MK:+:*^J@)LA"N!)(;W4\H?:[WL`U)#7'IGG;BZ9]=T7W90MFO'(;ZNF9TI,CAN>+FR--VP8ZP,Z -M*ER^)^JEV:J2;6,X.[:NFG$(=-NJ&<#3&QQ.=%/DT5S&42!W8MOF#^L;1Q#2 -M%'Y;EJWD/4Z0L-PZ.?'!.)T)M!C;L)&ND42$>32@\.9E-[-K/5K%$27X^!%, -M79KUO*4=/&](;NK'%Z6HQ8/+PGQFH>'%\I-?N[]1^LQ#N%-IX)<!M4W$ZSY&7OCZ7R$O?SR]OA=&["[*`A0MEO[,@= -MI=03KLN0<5A!=5R*#MFL`/SMKYE:YS8`M&.W(QNC)HOU\+`/]M5RX&H]Y2QGV12@L& -MRCQS.2S7U..,@/SB;5`\CB;DET8NE`4PE\HK@$$]0%IJCC[<,'8[07=/@3,Y -M\1LT]F*KNEFS3,$,X-##VD]P4HT&0128JLI"-O_K/NTD@L$R!-&<3"T.^`)M -MV1[MU'@FIA_/OU1/O -MD$7PTF>YX%3K+(?*6\SM/VVV88SZXL%C;G?VTZ-A79!!DH!D2K762]!ETL/T -M^.H#E;*SPN<\4^%EHT#P#5YTJ(/`([55-F"O<-UG@[_%\^$YL<[>(>_@'SDJ##,''?P`8``%]0CU(N2DW[=FK%C^\PZ -M1-J1HX@),D8?`O=Y>].[19>!$C/A+>KR3($]R!VS!C$@\A5X3[-6 -MQ41#*'Y@(<0^I.)X7%BT2+(>CP#Z_3$JEF*0[#53HOCY?/^VL,5D7@P+EC:! -MA$P[\?1SVU<;#$*!`A(3_)!""C":@GOJ6F_'CT]S0.D(,:)*S;*#8,+VC062 -M>SMC-GIK`UV@,WJ"3_>A#B_F(GR?/6CC(WTQW%U93WQ<[T^ROKV*:-BLTX5_ -M^+&@#K"W_N>5*#;GE?2/Z1LX**JELJX?L*(7^:3GE-$NZ.Z[\=TO36A!YD,( -MK_FFX0DQ652"P2A3!%7UTBQX'&EA`<44EI?5K10ZGV!4C;8!SKS -M@WJ^]\/%'9?FV$["VOKQ_:\<$2;=?M8 -M/`>0=;<45[(X,4+$5B;#7Y:MS9#HD9`KM.Y+F_6YJ0V3\[*(R=_?#IG@_;WN -M81:)Y19=DAST,W?5I,Y@/RAH.Z+S(#`@96S7.J9.Y>N9P/CKHA@A6TKO):YC -MD00Y'`Y,MD4!4P#8/MY.]/Z>Y?Y$ORC-@Z5,C5&(G,.^,L"FH-(_(9%-K295 -MPT8^#5MPK/4S>XTJ*W740:Z.KU%Y>Q4<.W -M?MCUGF)N.9RMK:GZJ=IAJ_@72TLC">0L2SQ3=@DSOZH3-/(EDK(RH?:5Y2PB.S7?OE(WY1?E@@EIN,V_Z/475@1UB -MM10L&1<+E''J;(X>![!@P.6^J2;7@G$:OOQ`H5G*B_=6FHK^9)YU(,)YS;QS -M"T`/)82"$;(("`+18FT(DVKQ0M';67['"M(&AF3K%'T!>)A"TH^:Q=*J^>A! -MU%X##TBDBB'P=0"E0D1MZ0VM>/3NK\BY*O-J+??$5,;EDE_#*UG\UM[;X%^C -M>J1R-ZI_4,5E$?RRF\4!2#-#JG'ZWR";$L)0.4DE`F??Y>`+7XVHR[3KC4SG -M'/5SI0,RG$^XG''4#I2W^&H?#"V)0P?/-'`-QJAI5M%P=8Q^DU2%6`J!GEL3V'R9_?=&M'DN`1Z+"J6[UH@V&OZO -MK!S$-Z6P+KU#>[UEG4%23@@4[^9)`E@"NIR-B)K,,N.?O/GN>V2YYI%/*1V# -M>\O)38V&\2NW;?56(_@)0^CM9]-T3CZ#[E#7X_-'=2*FP*(S`9^>I8CV%E-, -MB5TE)L=_$W.\_1"(JA(B@"%/'%\N8!6C_!,2S5*QH`Y#Z,4M6X\V1K(P>;*E-<)2 -ML_AJ`!7-'%`.'DK[ZI7(L2?0UL@^N5-"8K%A`=7..]B2R`9B.D-'^(&(4!PX -MO0U62;A&7`AT<=BWU^.W=MB;X*&^3Y#>W&&+U"4R!CVH^K[2H#II-1!LR,SHWJ.3J>2U\@GGA,B0&_4_%+0\(0 -M]#YH#M<5=A6Q?!U>50H;W(U9<%0,-XN`G&F4OSK5K?,U\6)03%7J"FA)7U_+ -M]8*+-=>/I9#>W"E.J/\=SK`SUK[M2EH -M,X)+H_B[42UUT%/32_\KV$<5@@8O)U[1FA-!P^0KZ`U4`$KNY"KY,K,908_R -M#D"O:A_4N;P;?\DQ[)'K%QHB0J3TM[N+V.V0NXPK^*\[>N@?(H8]ZC1VVM[; -MKU$IOU)+<12[93-+]&'KO/D$2A`-(GLX^CM,&,F=`YLB:8>Y/9&5\DIX$@8Y -MFO+;7!N3,&U'3D3*2^^&V<,2K>H)8A=J -MSB^E;[Y>L5M`(+E)'H8P8R1B"6R9!`&<1#?H>=>?Q8P'/<1<`3&-R9CZY`AJ -M[LE[>J5`I"X7'@KR9!G,(:N9N'VVL4=+/6LI3;,@&Q9"C>T3GG:7<0'HL\@5 -M'3YJ'?#K'EN@>)4::8)R!3TQDFY*^]+1[$W%C1-\(@O)D_V>NLXJ(%K`6O7R -MG:$%4AP)-=++YQ[$=+C!]IA<3V-:Q(I+P][CMGM*R]^RP\D%<1/Y`T-1R,7^ -M@1MJC.I+AG.['_^^@M"2R>O:P?IV1%5)>(2];*]6V!K_TY?O;WW^=F]GY0:0 -M^@Z-+3.`2Q,,B[KI%KS.J)LS8522D=:VQOF")MN+'.EW!_3OW:`&_]B -M)^,6R_(8/$-X14E'6IS0I1ZWNC*B'?9^.-L0ZKDN`<5U2K.CJ=!@N+;/ID$T -M">65=?6%`$2#MZ*EO_ASZR#/&WMUK231`3)CLD5N<%*7?)]NLP`<'@.!;KX14A*XT4PB%XBG%ECY,8@ -M,6,?3N(EF2G+]E4M/J7`CGU;=IQ;P064`@FM62X,+@ -MNT?J%4)P/K<1RQ[`0@?/4^2QO]-.N_I)O``%P/5&6H*%P\&M>A%<&DG>8_CB -M#+E\H_H1*O9Z%:DK4H5?YX0!4^UH"!G987%"TFD'HQ2%-V0YGQ^%4UK]*9I] -M@%F7@^E1EW&*&">RIK/64Z:'V0`KITD5R9+&QA.2NV_T7OOX*PV2?]*PVR`F -M[S*L[TTE\YF? -M+3^MY6V'\;V%GD2AG3Y,/S"Z/-2H(_9RH5*2:05WO]NB/UF.PA"/\&)%Z)1[ -MW'&R@6]AQ30PN+\!NB[6L\2Q@.NS`UV%_VJG^*LX1?=G_?9+SK4CKA9K/$MK -M!?>8*_.V,XBL25;?;;:E*MIG%[F@L#Y>GC^AIHRX!QO&/$;5X`Y.-L&'_>J> -M=/7:3#*C_(7_^498M$N&IBP5BF'/0D.D*%)CAW'B`)IAMX?O-DO$V;TSE>4V -MK/[X^RE-=*-P7^J=1-/O';,34FA?ZWJ2D8`R(^IM#QP,TO#4."(O^?O[_]^D3"6CM5@0!2D*2^_WO7;V8O -M.[Q:-J'OIH5Z&GSQC5P8=?/WF:87R@2.W\VU;37@YZK7)^O5O1(DBR.M?H:[ -M%WLZ-9BDM:&R,+FK*VIRAV2LI(3TP::[,4ZP(MWQ -MVWS&9SZ,KL\::/(*8"O1NW%M*O$03(#+W;=1,<1,NCNE7EGCDL*)K:+TK]@! -M%&BRCG+_`N@+)+=TPUS#D0W0BFR2)].[=3\I*5G58CXPLY!><8S.[^HPRZ%3_"/BK,3^ -M$R_[=R`X4VF-R3*]=.G^MD(A"EY7]!N=.K[X!^#QSAG= -M/7^R[3^FJ"\G9JH_P<1`>&SN[B%6A?&TS81P&I!TH&_JV&P'*6TYMH>`'2>>MTD>FTC:VE78RJ$NW\^N?M?^ -MJ#Q;#\O13DI"R1MO;^@E(5,]_ZN2J)>O!O@[$9T[!&4TP!OS;RH-A(#!"DD& -MQ?'7.KA507K)2UO&$94E%Z^$M7Q?0@(#LA1&_G7=QFBK^#JDSX(9[]?*2\!% -MA\%2J4/[C%?$",B$L3/0]M89J,,'P7T.;J.UNO/F2I_UB+P+HBBTQ7O7QU$E -MC^254X1+&!8W+JH(ZWV)5?)]!UUITRXZ`H[R^VD&2[J$Q3V)P_>MY&#$^[Q1 -M`H965Q<>?LJ*Y-(3-\]1?Q42?Q,89=21\<[I\IVCVIX.7'Q%<&",6>[!*EM+ -M0RE5XYHA5L:HF4C20_W2((J1RY^Z,N9A6[N<86(LA7-9="*=?KSY.-\XF"E] -M`F,K"-:XAQ)>+3'\3]WEF;8>C.E6W7@._9B[Q]A`$L+8[%)S(&VQF1#^`DQV" -MJVFDW<.FA>.RK]N]ZCJO**K[G'6[@Z4W!`A^L[HV!M7W:[WP87R=L -MQ"ZN^Q':(M%[(I7\G@)G+X*3S:/[[%P=F;,G77YV"3@9%36V=)T04\@^6-KC -MNO.D:W>K<7`'"B<'B<:L/B=H$R658B$+9\Y<0"TM -M[H:,V5-2@&\C64,@XM]%%`'`R8AYKY7>.-)R*I-S:5\@ZJ]&C6^^KP]]'Q!O -MZ'6`62D'@'2M80D\YO%.Z41:_^HO6)V%8^L@]5\F@T0I+QF3H>_);+3L^P!, -MA4I>=`;6PL!DU>2]I5"=U4JD`"Y'88]J]50D5O*KB=U<06SJ*&R1R[D -M,W5FO.UR4IGC("/(ARW^$@"QA^14>J!HJZ2N;6$W`*8)M:"O8@,$4^N`J51; -MCU-MFE$S(*8TP;IMJBY_U>DU4,Z*S90)?V7I5%_"NS*&`%\#7P.*U"(V1/D` -M(B-X22W8$3@@OH4'1I9#[Y'%P&TUX.#+=R_Q=+&`Y!X^5FZP1W*@7*_*+<\\ -M#0:]>D3FDG*%8TE(E+-W9MP70_>E+8L]O9KQ6E4OO[*&`8PH6T8]-TM@H;!9 -M#N1WUW=#-KYXLL8W`I^[T$OA'9):4$-K>:HHL)+%P%;*7WO -ML.6Z"L%Y>ZXR1YR:VH/.JKB[*F#>I!:8>+&BE6YN-R@ES%[FF0(RWU[VXW0; -M:R\*9$5"MS[M",8Y;M"OL2!YKWT4*!IGJWLP:%!ZYJO(O1'Q\"F:#$G:9PS; -MK99W&4%R4_6RG"D5W$XHAZ[T&.B<;]9M9CL'=[N592X[-1E#]@A99+8RF5KT7PZEOD%PGLTD& -ME@^O^EQZ*-G'`0!8$^`]L1,JY[LU:K1PLGOP3)).K/J;;!@PUV?FZZUN3]RU -MDCW(E*R@BY[G9C0'8*\FO2(O%?1K_GYES<.S(NIP_4:)K?TPL9^A>QGQY^46 -M9@WX`J6X=1)AP4>_<>>=_#:4GRK1S9V.$$SK%U#FX!T"#F3L%M9MW$0?;W0^H+990O -M?,S/W7%A?X_2C"3(=8'5*_2FOAE=+FG.@A`?\TL]H\0*2%]&;.,3;H.E/NNE -M[=8^#W`E-&D(K8A6T19H/JTN27#A2#`18V]T)6%B?#9T;&)5VCW`DSWH0HQR -M?Q*G?FF,3QZPW]E?)10**5'9YE"-NN_J/U*!R#FXNU'J(:3A:>`ERP9.DJ8K^=^YL*EYQ.HW_MF2]]C/1*O_2SZ&4!@ -MX"H-(3;MZ9M+\,OG)@`@[+,7N*\\8\5>&O^5!A5>02UOW`L(VE$&]#<1C.]R -M3>##8L+>:*3%&3"[&W]S,03>KU%1;;@$$'^I@I\0@?QRWM3?1G+;__#;"^Q9 -M@"0+%`'@*,YVH0($/`U^;<>S<63W[K=JYK6KCO*+*B/EQBB"MZY7ESWS>#9. -M65O8TUS[O/W4@BSY(T/PFUF:''^K"I=2>(5R&I;C/0_?T?Q\O!:QG^<+5:H7 -M$5N<0N$%B]1B6`LFO:7NCN(8@SQ]*FY\[TYSAV'9@?LSG!=NZYS.+YA"42#% -M\F@B%R'-S"W0O\>7I"PI:8G,\VQURS-;([8RP1.:0TQ\]XV$,,C7KJO^SU:= -M$:#Z]9E.PNHA7RQEF"LW)O_57:?-V\?7M+"12@&-V-S -M_V.1")ZY1HU@MRD%&B)QJ/!YDF0Q,UC8GIBQ$GOR2WHNACXN#11`K/.@%`,I -M\&R/4"LLI,_&Q/`,PH%U3)X5QIJ]IAF_U(P@U(#=Q=Z"``=X!(%4U=]1%YGZ -MCND(I%CUV[=4*CT!)3TFO?EH",))O,[\F6&OCV#-9)L:0^ZJ[G%,@$.;4'?W -MT!CC*_470FNHUF[LR+-Q<-=U0>YAN%9KP]$X`CJVC:Y>\V*KIJ4'9Q*.Y9MF -M%F'9&1FMD_+'K#_=:?9/!^E\JKEI016'091I/B:\UJ/;!?EM^:Y#STSUP/B: -M<>6F''GU^?A*FC9$VH,6O\#Q`EYO_*KO++Q(FW5@!'9$F9[S$36`_.^HB'/!1HW -MI(])-):YHT/_G9JML:6V(!&^=;L_\"8W%NEQE.I"V+A1&/[OXC8_)LE@.8!> -MC]D"FQ:^!GBD/XWD,1-M/T(9EOK%LO\:]TB<>)WYE%)I[R'!4.=Y*BJG?*KF -M>H@M(8KP?D%FK\7J&%TB[)$*Z7^LG+HV\>]69UI65'_YN_[8D;[VLU-,5_")>SK$M -M"X4\E**:$:!)K,-_*H+^;+7\D!+._-ECR$DZ%+0@UIDE14H+H"S9C&OF)F81 -MY25X(UZ,A%H4^Y8K$UM0,%J%PK6/CY=%.R">R#"C^7=G+A0$-'YZ7KO+ZHG+ -M!F9'#E^$#.J^CWSYC7J0BNKR@I.G!4^-NJ+VC8F@"Y--=ET. -M3\='M)5%&STT>?2'HI)6"LU.(_\(B*(B>M+,5Z0P;?4^L.TD0P*"?9O3S9KE -M3L[2OTYTWOU>U:FE^?O4-%N?W>P4`RJ0/D(25>?!4+3CR)1?Z"2H-P`UO]VI -M8R959QIJO)N0E6:AVB+NULW-[9N.Q+N"H.M*+['KE-E6=T72JLETB=R$,7Q( -M=OT`8S:>^:EK?*Y^HA%^*$L`O!`!PGT,U32D+#&/&W[:VF7\52HPFR1CB@03Z+-/FYK)!HPS%<#:CLN+GSB -MJ;90<.NT$IWELPWDE[P*NP?W`=19UD5"75JO]Z]&`M&RJA4D"F1>"U3)R_8F<90$!?[J7-/=X:66@#;TF7;T8L^?+C`Z).0125M4\W']" -MU-&7$]L;;BYY4@YP/TU"RB""WMY833!>W_-N=(]Y$TO"M1_>S';;SX+E!NU^ -M:'ID:Y_EO@8)RAV55IE>7*<(]-V41Y38B36@;$5-$4KD+PB^4DEK2EMG85>G -M6$1SVJ;;#`,GO`NN6-LK6CB#T\E\:!]]E[9WLV\.`J8A_BC$^X_==1P;#PGT -M,XJ?`,XIA%=,[7Q&JN7=WTD\AD\#V)PV?U12`XQ<3WHIL<1PS&X%@S%E+^`^ -M&[C>:2=P``Y3#:<(0@@DO!?<+*RXP^%#'.^D?:2YJGN3`M!;E[I+]T''HH9` -MC,VE&"^-R16VNTB&O28H0@)>COE2FD(5PE>=O1@J9[^*:\8M26[CU-)KR]#= -MD&I4HFA2V2^9EHK\GN&'):7;">5>UON"]RNJ+=LSE$.T$]I^A%0 -MKC`,^Z^>X5G:YLZQ*S)0#DTDJV$[4`1]3<(9T03\4&2%YRJ5-/-B=*%';M5[H\*S080&F3RVD?W@&*8-P&SH@QB;WZT,\FA!>GD[;9_%II -M\:$:(\%XRCK1[4(YB&44!E&X;%\Q7H>73F2]TO$#WX@AQF"RM-_)M!6X5%;E -M=HB5M3BP&AO7C\UAG2F$FS@(Y)5O2!$Q.`FC@RDPXT]C1]?]00R$79Z:Z5+P -MR#]A.6'R9=ND<`I-%]JFNZTZEY_T)!<%IS[Q!20Z;9$6\,`=LSA:TF(/U$;. -M/%\+0KFE63D+ASX990DAX0>M692KNH>T\!;I?5$$9&K).)*:($9*4@_'0)K: -MCOS`_@398VQ,$9U?#3\K[(>]6NJ\)'-VO,G_EM2=R\E_R%VT>FHOOY4NUK*K^86HT:5)+ -M)O3AJ46UOBHR(!T\]9"G!1_`<)9,B/^8%-`9E!'6"7 -M>01D$)X8/SC\KF1?%S..,P?V+?4(!',^2KM=U$_;,Y:*NLZYB!OGPX><1XR^ -MW.ZP'@A`0LXR/HK&);\U4_VP)WT`8TE5K;%], -MCJ$H$6^;=04S@I0%2^VID+15^#^R*O6ZD8$K2H(D;Q*EDUNL,E>-8PYZ+"%T -M<$DA6VQ6P=.R-ZX:-';FJ`SZQ:@;(&[07ZX=[MX\T\.Z5965#W+LGE:K6P*] -M"TF]Q!GULM33&612WM>4&+]L$V3DIH'AB.,`!`]!7FSQP]G%I:G^>35W)][5,UM- -MU!1O;(AB;\>9GJ$.ZUEN,MV:)Z#G`X"[PJ$>2,+VD?`\>LQ^)X1T@4JS'@>L -M?&29U]DW]L#1&^H.HZMW#]Y0]LNP4\WC*;?^-^Y898S+*AQ;_6X*TITE1DF+ -M5*@2"F2NJ7MU#=2@]%[IE*J+#$-/ZWT2G[EUP4%2K\!+-_$HK)DS@;V]\,%O -ME[#.4G8>DX=>35-/-1+/^I1A/*(,&H-U=07MHH4=/E]B7;M6>IT*$P0%-Z718>;F(Y-YVEDDSE'E.PJI%)'=3_PDIR%K(_Z -M:W2F^<]#WV"$"B%?_\,_A6%:Z6=DH"X28Z>J=41`=@2XEN+9[+C)*0%;THOI -MTT42X@TN;C69!T\SEM[R/MXEF;F=^!/S]'E%-K.ZI?H*9>8X4('J+>LPD"$YQ%E^[FF$>T,H*?6FB\W1$'"F6F1O7DPOZ482#$&)($O!P\%O1+ZGZXH* -M^G\NE;Q&-NY7"_VQL\E"LV@.!?KU8Q]GC`1,OMI=E?R`*CF_J6KES0P*.ZO) -M?,V.+"&W9ZFOFK*&L[GXUY"CUVU=5E+.8VQ0F;[&H:.;0HFI)8.D71[S%A@% -MT#"OPMOZ-3-0DDI)%L*=NCI14X',8,_%9:E2`S,HY92_$L1KQ3PI+ -M7@RFPUEA_VF1PXBWU>EFT(!5PI>D-Z9 -M(+TB;J3!1H5 -MXT:(*67[DI%*3.KIH2V\_+'L?KE7J)-7IP1U$'<^HHX)6+F""`WV34'9C@S8 -M]JP-!U&^>$<"_=`AUUJB:(5RB"I"9;0/3?0WE'_G0]#PD6M0IA+/J@OGJ\]! -M:W(+-QZ8A<^1!TRHIEE%V)*S/TC8:)Y29-SDY%8Z*'7,R\3#PW$`(YY<^`A? -M7T\GBL'UV!X,7%D\G/S9=<^K:(A6=*"X/B(J8FMQ8UL05AOW=4Q)2VPXA%H* -M2AB?<-S'QL"N\E2H.)M\X_M/V,B#/ZZF1!(A*""*A+G/(:9?QN+SOMR0Q&8" -M7.^8WD;_/N#H!MW'@EK6FKNV<4@SY_.XR/N[.X!\U*TIS9NB?3A5*D2-K[&C -MB28`*.O?2*[F(],VR+!9UTWMRV$>L/#-PLBWUWS,*VK!%QUPM\M>%]J>0JZO;5-LME$8A+8_O24'O3UBGK -M\*+MH3]J`%926(PP-QF2#F-6Y&44Y/6P-$+",9@(_J^^\BV_%;%(_Z4&01A) -MO4\RAC%QL;?`DZ)[G>#/`"S80YZQ$Z"?=']R]G!6SD&_N,'Y?U,GO=B3%W35 -M6V[WN?G4\KL<0UP2LI\FX\I4`JA1=R#WYF=_8\GR>8Y-!KIH3/QJ^G=1#+S; -MN_/8$S!-L2^7TC0!4VRMWS6WS;(8X3HQYJ])/W-Z6+>!`X?3WH\^MZ)M+VZ( -MIU!PO[ZMJ[%PFYBJ8;F$B"CA2?%/M$T8+<_J[K&G\VCK/-^ZD=BB$W9XSJ`C -M3>#A2H85GC_J24'"P8LNTT>GN1]&\O/!>HQ,]MMY&5RDQA$;$8W9\L9GA'RN -MU[\Y[<#@<[`A`?3'.<>S-&Y&&K-;>5Y>9Y6_&:W;5_*U.'\XA8AT6AT5U0$D -MG@=EEIK<7TQ:-K.UQIOB25<'6*M4^GO]D==,'S!4.IS*PR+*'TWW/(I>Q4#: -M7_A$3;E#80PF1;=HA`1;)._%`\%_7*8%Y4I/5`U>N$Z31K\6X5OOU=@ -M)N-W-"0S0^%R:8<[A\#NL]&E;??'J1`Y\426G^3!AGA:Q -M7]T&;W)9>G&VB:N*W_=[26\/^+RL;9AC`60/O;C"2O=[^E,@X',_'(F;)0O8 -M=8_YJ\*]-YL1A(+[#WR3W>$=H>HG`+F"GN&V'28X#*\H/*"T/L@WO3*$:4@I."F'=.$E\JC?1$&3_P)] -M`@#IW<-A$J-#C]Y)OB"+'CA?MZK006+>]Y%EQJ[_7/+`1A.A[+O\*8`17QE_ -MZ&BK5W:_\D4RIU;OYJ@4E"2%D"7E]F3[S3HQ?#*BZ@`8GL->G46W3334.8`- -MH%21S(2+Y;*MB?I#.R8<_1;P"Q'B.SYV<.0@U*/'6>+N(R/IHG#E-[B\W+^V -MZ)R#/[IF,=S>7;SN';W6\)S.=R_HFF_&+Z(':5<:#7K-B=V8N35)SK1!1I>\ -MN02]&$$PNVBEPD^4Z&[D!9WYPN!<&#D)]>+W4:/, -MNT6_$Y<2H9+A+IUZTW9>01:B/\VFZQ5*=SWCQ0U0=]4CMF]O -M#'@#-Y`.21[_1B";S/\*#P.CF2*[I\QR6KM8&?G07UNP=.`AR.E_[1;MT*_? -MVW@2X.&'NX!412O(U3B%LV#?>0*A4L']34/&;AQ.0]/?%/<`W1P*0@YLFJE[ -M>2JA);T:[TAXAC\OW`.[IVZ_*9)C2%V"3JG%T6\ZX8+AV96`!8F&DRBV/FP3 -M<'P8'S&ZV%1/.J(@FHO&^_J^H3H`??IR!73%&]\'O:2-O,)-1;#P7T-M2>D) -M[4?W&,*='B1;R8RX5"@B]V5D(_)PY]A:T!!E\F`*]-,.T^=\ -M1<:W/N@67E!S'&;!Z"A4+#@Z>(61%QV)%D!9?>/KY_.KM[LC[M@54;"G%M-9 -M_PH$7"O/L`J>:?,(ZW[S]#+F>W[:TYR0[4EM$GY\A1I,E)M@`_0($8'@]]A- -MRV]=6G;:Q"4Z_7A(,%Y1)(T1GS>C?IOJYY46"0<^XL3(4'/$A^8!1QN:"Z*WD\:=B2Q8DWP/Q'8G4\_J)'"1 -M\&/J4+2Q+&LUYIM'.&_!9]:_'?B+L#@VKS)[^GI1T\EOBA@B571\8IC2U6!+ -M_7[$0/(5),_)RN`NE`ZI75=`2` -M<`$P`(^H7Z:<$U\PE];\_.<[26'[IH@##Z'=)RSL)A^)TERJ\B)^2*+86!W# -MVH'=<8VUN0?VG7&K_N&[CIZXBWXUW9AB`D%_`T/#\_O]QI[8*4/?'^ZW\!0% -M;OL9V&R%;,)@<7Q#VDE_GZPA_&VT=6W6:JCB;Q$0OC'KS:3PH]N2UJHW^^G0 -M27OPO',GV[L5GGQ?";C%&'N_)^TF,DU3;YN<^Y)`L?W+L(8HO^C`D+I7>.2_ -MUE:E`)3$P`USJ"ZS*1O.C!@-3$P5*:Z1Y.-9'T0)-=7'A[9[YQ]'@&V+I)$D -M'3E:+W/2@)VA"@[815_&Q]`IF;&IRRX>]3[D)E!)*7CF]'-*3$^7=^6FX:45 -ME@VP/G=U/Q1JU@<(AEDR+&54!-*G*IQL+4[B-'TF=ED<5AYC6P^9H/-!L+P. -M/A958QK@8@B(E_46!@VGO`O-(N(%9.=8J!3,DW%:>I9JPP'/?. -M64Y`!V1/V7"PL`)!+9^'6:ZXX0T^Z$"#W#7$*%5O3[4RS'INP43RPL!VTQW5 -M.]5/J`47`P=F*W1$\\@_UN5F@0C&1UX -M&9E)P9VJ6']*CP0-_PUT-2B?/[1H/`GS"O^`!,%=%$JDPVP5YLUJ6_[V`H7[ -MC#BQV)P`Q0B/760&V7$UO_K7XB;>.N-)+]5,#U[XO-K^TL!2<#COUIQ&'BTM -M3L=IAK)XN#S0<51+/0/PK_VRGP^GM20T@,>Q>#M7(C0N/M^M90"_Q7?XAB?O -M@PJ/;[(2-V-RH@ -M1I,E8.T.N^_DK1XF%?IA`OB:R7Y?1+UZ1"0X9L8A_E@O%5?S8*\[/-SA\B6_(0DQ$]R; -MS;)FW%:@(0[,8`JXD95G^^PJ9:Q$Z+&17!0[__V=VE>8E>_,T^&?M\L+*SFE -MQMQ_\S3_S]I0=>"/#1SX,#NFIQ\YRJJ8M8Q@!F=CR,3K*`)UJ<*E#2E84XH. -M)32DA?NW4O99.HTT+'CL5#U;5J@MK#>BU[U[+XT9\/O,KM+U -MWP35B^;%HB?X(]?;XACZ:55<7*WE&\?@:F!;)?;WR+!X)G."L+)J#_+XFI0X -MVN,F9=-TIH%K'763R:SG\MK=[$QIF\A:#D"`P:H*8;>Q+U5HFLOR5;12_)N% -M7'94X)K`A-8<"Y(T_L0)`J/E<%[M;*IGZ6]HV]SLJUH-0*D5*PU7GEXMM;([ -M=0]L2%LW[D;8ZXFH^6,_%+>-'C;/*;2$D1I.M7"PS,Y!%BRT`VR,=4\.5JFX -M?*OO=";5\B@UNU"1>@LS#50WGJ!J=#LZ$D63RBRK^@6D66"^-[SS[BLY;_,4I(I!25'^*5%EY]<Q_LJ9& -M6RPD7_>'Y'O$R-(?\@N<=_9$MQ8'(K%:7!_*,YQ-B,^Z6G;L8#Y4/_]*03WX -M-W+,-6,*1&$L).Q?O[Y8KF[*461TUE_F:&O%1X>,%5GIQ#,D4"V83']*HASV -MK_T_4C%#+146I;JCZ;KTDPDUKBW"6Q6F2/E*$U2[& -M6.Z_+MNUV1(QG&VL*87'1FJ`G4=:2=<19H8SH&P\^>& -M+6>K&+%06Z1)MPADIS#%@0-=!1P'6V^JB>>-#OCH%&PI(E;F$-'B1X?IVFTV -MJ^O_S01@E[,HS/4S;0[S@_9+5:0$6[^\APM%HG9)ZBL$^U85*(V2#7MT]:(D -MB'DM!S`:X_A&(2UAV_Q:/`S]LW&BIJ`2LN!K'.-2'V&:V$:#!ODJUC16>*Q5 -M&IWP:F/O8)"%^@@M*_GEU>#K!KJ)TR<%B2U/! -M'E1!]?LC@7;1<.2'?O2+A<<=N"2,M?4:'CPN6A,#H$#&!]SG._RZ*-#<6OER -M8#V45_TLL4XX?7D!*\F5;K$LK`5<53N!LVR*5#;D7=O%.:]TP),Z[(7\1OO1 -M/=6,(MQ+ULV#.:#PLZS-.&3'37G#T_?R+H'>:_.:*/YP6*`'#[4&*IP@H^E -MP5Z+M>&`IJW[51%+,.75A/,I<$JR(<1.K=X%%QK"<>3)$6I@`34[Z>- -M2;ZQI(,)`8VYWL9Z.#XY]\`9BF+=:!ZS,YB]6K9/BN:^C'<4HYK#V_1E`[R+1Q=,]QZ;X3SF]M<6#P;WF=@2875&9NPQ+2+#5C-=*K^DKS!EAL8 -M1BB3\"7_X]VWW\_(,;IOY:-W"2Z$;\J[4H9G33SMAK&\'4OOR;1L@7JIFN&\H$1;!3\Q!`$%M>7'K$)!HJEX+<*[EA:7ZWTA24?%/\@LQ[UE:D -MH(:4T:!ME\Z2Q6<)7I$5/D\;Z3'+L]U[SX_!^'R%,^ZG'VQ_5QE.)V=:]IWA -M:Z$4\66H(8<&1?Z*UZ=QIGI&$N@8J/,B'UF/]+JB)>VGA-X^CA_1:#.IP3G`'<,WX4^604O,N8KJ`K,YPA;\JA"M\_7)@2:& -M5^*C]0:O:$4&^2"#?LBX]W&3ULOO@-W+X6\M`BWMN`#.C476S'T#4>F<%..H -MK"(X]*J\'!9/'`QIS\Q$K.N5H73N"CNZ*1C2=]$;.%1>"XA$)[KYO80LA -M>WLQ+^&HDG$ZP,DR><>XF#]$:A`F:1>*C`%`V#CL/?9_.^\(T7#;A"6UV465 -M76`Z1!/JR-4,E-LQ<0;NN!3W*SK(0(/CAT'X\YR[&P/G2JXM_8O?;2S&LE$; -M?N=O_]B_?>!JC/1<)>OCX!U=S`OU^K]E&0MHZ7*$V@)\R_ET-0AHDC4TL&7@ -M#S8%5<0N=9\F&IC0,L2&W.UC]M1,'$X6W?7\[R`W`,T"95$[3*<:S2_2HT2U -M<&'_C<4FF5M\UKQ,]B3WO4\_]'8;J>R[D)TZE7"-3(PB1!)!G4!) -MG<[$*9H-1P(=EGF[@?WKI28!`3#%%3I=HAD^\<&NAP9ZWR'Q]-%ZY6RFQ&M.8K -M2A%AZRXO)5#F"N7?F!4.))IF!8X;(@(3>/*C=5J>_GH0%&O_((5D[ML=WWZ2 -M0Z^VL:&0#<.LG3`3\0/0N=M1%_&..%`[`*UV>1*9C2V3AHG$`*T5^UZ1!]G@ -M0DI.C1F5A3OSMBC#!#"%-ZZJ&5U+TG-%%;G).P&&-8RR7.#G,=M)_EYF089? -M)%'KF9AL)NTU&G92)V]QE4!?D-"![GFC2&]M\GWL-<&"S`.["[EP+6DM2O;> -MB6H!#QA;V]>VU-$LRM+-TD.'K2A"R$@&P@:[08"66?2$*M^>:7#RD` -MBE/Z?@]FSP8G3O=W_T7`77H:JH0PT[>H&;P[MMGHBS]#87=,H6W1%X0YNWBO -M,1"TPW,.BO%04)5T^O[SP[>EQ%?MRD;Y;&UYL[>2^-SPPBBSD1S5< -M[CB41O6QFR$K>NJ]MES!Q(^]3&1)QW^OZ,WQ01)M?9Y1H%I`<1CTEM:#R1S, -MD&-X!)BG:'C_::XC,LW;)(.)3W4MV:SHEP(0B3`M@Z3C*%L6(IDMY';?,/`' -M3_O%HLJ$9.J0E\`)0E^NZ;@K83#8.!H)#TXF4[*M^8NBV]5RF1'[PT"?TXFJ -MUN.!;+.[R:>C"F09J&D>6@S,H%#DB?J'ZA"X6Z^R[+?Q/MZ8113)Q#4R@0*/ -M7[G2IH\KDG*)%5DM$?]LPJL]N.)MMO:7L,40)XE^14J7`JKJ7ZJFS8:G"A8' -MX?S&GQTMWU>,O`)O'[N+X+!T$_'5[ERK].U[^<20&".%> -MNJIR<:^IK?D?M,H/0'^_1O>/TWMC26M*D^8,0(9JSCB!-K:^F(PVWJRJ%5,_ -MB7$H%<^3!6#W[$SAJ?\EAE#KFGKY-:BWO&,SZQGG8\;(G;0]#5>O%,)UMA4& -M&80`Q>=47F14$YQ*N&O"JY0(9$4$1-P<5512*-\/ORUIR?:@#1DD=!/\Z(=W -M(\T;XX=-J,6`^@8[N1G@[(-6TD3,966ZBBAKI0#?C?'4XO$;H'<[X-K7^:6\ -M^02KK=,;TTNQ6WUPB!08@SOA_!*D -M&[!QQP`"P.:T7)Z)1;.U[?[=GC<8H7YF4=,EKZ;A69SGOR##%QNN/1%&!4B1 -M!^I]Z-7;6\`#S1:QE!R9]A?(TX_9:`F8^V?Q1<9I+27[#3*JBO8_D(D;!M6, -MHK&D<_U>&.0D>RYH/EK%[KP*G1IHL,GAO&B;#$<$T5^:X@^2;8AK@OP6=6GX -MC/"6U@!E#0..V7`/<ND^A)HW[_R805?S!#QN)12G$JU>06 -MDHL7*G;[]JM1+S;60=0"]EC@C7>3S\X.W(,`.5NZ-R,I-Q\ZT1IV'ANUG$M>,#8OZ`'U:1<`?2Y^SG0!SC)H%'CCL -MTJ,4HQE>\5G6R2J--/PK=3T -MPY_*DC8.'T-:?G.=HPJ5B]4(JP3@'F"12 -MS8O?T1*G'!SWDD1-T""46RDSO@X")V@O4\CK&]H_TV9"&<`UDR3!]A6=>;O/ -MZ:Q1*W-?33Z"H$03O-1(9?+28&*MD';E2;(/XC?GI)5Q360R!TEJ4C##`[O$3$S05`!QZBCJ^R.LP!DME&753("08Q[66`. -M"6?:[+RB7A)N]D;J(T@LA82!+*L],M;SJG1T9;NG`"E&A-19>-L;GD?`&H7E -MK$,@9RKBB>_IY&`=PQH"=5;1ZCT4M>F.SWU0:,>:$66@V=O8HO_U4>!!#:M0 -M;@\`)B$OT9CLV/9E/&I_%;E8\CZF'5T3$LMQO`9'ZU^;$BTPM%@'R9#WJ+T? -MXL:.(C5:SJB!NT.U8"=!J`B9**#QPE3E&>$_;76RY:=O8LAI$3@I\U6;2J]/ -M+.RHF;B6%;MJGNV,4\V6]+\X0YRDUL<)2D&P!!`(AA*H5*]$E=.1PJ,:C6$O -M/`6&>I#\33#!>[.MS`L);*54'?XUA5`K*>OWY?;?C!/+7R( -M6MB;H]\0AC0L)[\M)SGMT*!;CVG%UQSY,@@DDNOY'O\^_E(P=41"9@Q3)P@' -MDX0(`\K*#\F'HO9(CA16*H,)SM-\N=8./:AIRP2)DE^4G418Y@]SM_=GS/PZ -MUQZ*/-;5\=BF%HBQI4@=DZ,/4._0[P?5(4A44SL]385(J,4)*U/I>9SKDUE+ -MZS0P4AF';&.CS;7-'CDO;W5[7KMTJ:9X3/CD,!]E%.8O8WU_X%$#&N]7GW?1 -M@NCGL0%'++?/-G0\[I*,8PS!:]-W5H0$3(S8TSIM--00U6;`--DZ1U/;T-LT -M8#UU-UGJXSP]]*.Q_(G*=E3+IO<<$\'QU61MTK;$-FIT9'?]K7'&[?`F58X/83N@(^4D;^P*R4.U/<-E(^$K246`EWA$&4#\QA;?3;C'!K/'-?R!00,=4Q=EC -MX.=[Z76O_(N1_=BOQ$HV9#H0@^YGS>1W?8>ER-Q67-B"2])S$\_^E`[SD@)) -MI+PUB\*<;7!!>)C[)OB7,.;YQZ%)44/BFOO8>?K]5F<::Z\@F:AK%9V0(B92JFM8.\7&EB[>Q?<-&6V+%_5EN4/ -MV])Y)NXSHK423K-^J]A_-\=T]\WT"'0Y"UD^?P[E,77(&]?$KY -M\37FV(?4KX&N/CZO-121$U/H0@1G?SKH]O28,=\R.-7/O\)26#=)CJ,/XO%0 -M],PBBJ/#OF+2B3@3TXS-7"!1&@!;QG=>>@M761?X8&P";\;+E+P@L*L^@VX$ -M/?[^2G8D].Q)]1"`G_0>2?6TY^&-0&I=)U^.H-P%;7OB)AL^*M8'`$^+[%' -ML?$KC!7]E4R(\I3Y;X\'M#)!V7ZDE6NI$$Z>=!,;E5?P%=)<3>-JX:]P6#YB -M-''XSUA+^5J@>ALD@+5+;@4U"%(<;G]ZZY#3[TS?52>WVLV,"YJJI,4,NJTL -M$9:.'`I#.<9L@#K]B\L,SR"4L'[JY>\2I;!KPZBWI'LY65#(!9_%PGCA5Y2< -M\:,@T/IY3>T$7V\.(5DD"6L''PK5O0#X)")F">/D,VBUY(M(C4)9H7$O8I#Z -M["()N*UYO2(=T"*(S\^J-96ZT3*&9:XK8[^8#-F;\)T[?8Z2RENA_2K+Z8!' -MA;CO/Z6AHOPEHCWSW#A1F?/Z_N8"!VEE5D/I3E&LI[R)/+P@?H9PXKIJ"=&PQ: -M=\[#V7*6T$>$%>9AQ6\EJ(\2FF`H;)Q]6(>;E,T0^'O)8M24?<8@X@;%.Q!` -M*Z-Y0F7+YL6+W20P7YN_5@")5HGTU$NH%*)DW?[O7;_RIY(]+.LEJ4^KLY67 -M!20X`.OAG58A)+^D=#0(G<" -MH_7.K9)S\9W4(D@$OLK)ED)B+*%_U'GIEGE%D9U_T0TUXV)#71;S5->CH^Q] -M`5I/"PW)?L+H'3'Y0:6*=R((7?KUT`AY>#@48#K[H.MUN]G45/1BP72H_8O@HB_R;?^F%0ZQ%!SNZQ:\D@LQ.I -M.\@;;QPW.>U%NH[R_W0$V^9'^<16B+5Z1NB@A+N=9A,([A`DE0FN\[QXN^S9 -M$-?0B8JB@ -M1@:JX.KPL/KXWY1\GW!['C=M()`=Z7FF!^1&(4Y9J.S0`>@*_*G8O3/3<98[ -M[@\`X1X=.W7P8Q.]8L:#,T1.2?SA%9LDP=0!M0*H4'T@AY#YG2`47/N3W4$` -MN+NK42ZU1!&Z`T:&O=*(4JQ%C_$B8M"-K,)5S@0]`;;[>UMT.D7J]3GSR_1? -M5\+)YW=),)WTTF5V3#YTZLW9R3B=9<5+W)5 -MRL_:GQ;ST9LB7*:U:.3M@G'OAV5X7;`GK]78UCS/@?QKBTX$5$4OAH=.%<0N -M'2"E66B6BH^W5G]5N[6";08QOKA^&@C"NCM[[4A&M9"97,",M=!%J.M[#5,L -MSMM!?\2:A4"RK#6PIH4RK+3.BP'$%OD_\%X! -M>4@HC0/E3"*=/^UO%A-!P\MG$..)?.4)YSZ[WBF02R7)DZ@R+=@#O`G.V=FE -M4OT3%1"&K_LQ.0@<(F/+SUIU&B+OGJBV3.,AQVNM -M@SHNIB7KW%^1@J:"J3%'B;#M7E+A$\\I7;4LGX$QXXPL5Z0H=LU-Z^XBTN[E -MU)6B=3[6[CDP49-1095)D6'^QTT[9((@E?"7$A_W[W)&)$,:N,-E- -M9MJ+QG01BNFB:?$^G\E2'Y%CEKKE*#5'!**33S4$8B+;UH#EI.>]D5U02Z3> -M_=O["KL74:PFVD5D@'5"8^I)\!%1+@.4JP4W%NJP^;^T'F#DCC]^]_%K8PH\ -MBB9;.4\,-7*(:H#+P2W#;`L3XM].DJ:_&+`..PD](]:X8M1V?;@`.H[VH!*L -MZW/CW5"F=6DTL]"NWY)],JK/C-?N&U=E/X91T(YT^D[,NIIN6>(S$<8&65^Z -M$MV"N+;CYEC+>+.J$.9(KK&L+8D"AN]Y%@6DQ*:[C,/HZ.Z?FAX6[7B]NL=< -ML^>2P^*YWZ2B6TVA]<-GOF4U%TYL=HL9!Y,5K>XNR)1&=CL#I3_\@+4YC/[^ -MT(ROIA#CWA=MTB'ES1(4^N'=`(B(R/P/,&BR8:Q+?7\#L%%=GTTEWD3-Y/-S -MQ]2\/B2-,@>T6ZR4H!/GDT(EY)@6.VB*''#.HM6`;K`HTB>E-X,?@6/R+N/& -M.5R?Y>&'%+ZAU/>7UJS)%H\YZ)[%J"P/GUJ?S#XIX!9P`SQ)0>L1"\84K+0R -MJ>P@N:L7`3_T[U/A<2NP?U(+')FZI%J!8..&_PIM*57)^CI['2M,KN23ZXR# -MV>QMA]S7#8ZF_X5/`07JS1_PW"?;3M'D-K-.GU2Z%!%,(I?IN?,Y(9F!84<*ILXR -M21YW92JD8X,D!Z#)=WIW'5=)@*-=>D0_S!Z146);SF-F!'V -M#R9$"RT/*;W5@,X+0L=KRL)OVVE@$5W;@^#F/ABE."[W96(]#?)*=%U* -M'!)HPT3^U1PK;CIG[_E-`="7*.3_7G-8`AC<4*#DR>07\"LU62?\Y+^7XW/A -M/1X4&9&Q[D#L9,[=3DUY\,]Y'-R1,?I(*NE2Q_:6K9ZFC'WCR\E_9X>ML6OH -MOY99VOUQ2GVBM]XCL@CB&4-TH.MEPMW13E8L,,OW/IGZ6T/3:B+.Y#,':9`/@6&T9^A2;-(W754)33J1 -MX;&#.F?52$31^+$,6>RG-;`;:Q(!!TX0[WPIR/_HV7"C4$7-,"I&'-I_A00J%*&!/`KHW+AR(('=( -M-5'F8@\BIG)\.V[#9H;2O->7G -M]##&VP2ARZ:L[@\S^GN23/V''+WD0"3M)5*AMA3+DRJ%,^%*E61EVR4P9?64 -MOQ2[RR7$A4O_F"UPY7(.G5(&`7ZG)P/_DHTW4DZY6>'66'5H3C$2P46PBP83 -MG$G\)U=;AK<%O"`5T>#\]DQ_8PU_`)C!CN3AYT6K,RB5.&2M+ZXESW,3!@3" -MS/U%6:7\YPL/Y(FSIBA6XMHVXVVUE&32@5AZ>AM>;8MZ0`FDT7W%[/;H'NZ5 -M]G[\,#3J%;$OL6Z[]X`@ZD\J@E@ND2M6##C68B'CRPO!XHD$0+J\:.7%.0FM -MEKSYQDX]Z!S%;OYTUNAD;/3U`[ZS`]GA)U3&^OB3',!F*HC5L\5OS\\>=@?Q -M8);WTR[#L&A@S9P$@WR`K)O@.H^DX&2C4R>KJU(%ZL]5Z7WD$*%8T@YQ"%>O -MTZ:$J&EDZ&B9N`LN)=GY/@#_-?%NRT&)HJWQP-7^UL3NHZ'X+M$2(W`!_J2A -MS/71'H@[#66<,RSV>CVY[L'T%PG8PY9^_2Z(%\/DZ0Z8A>Z+W*==OV*I2<^= -M"@@&$A0#]I[;K&"**Q+;GT0&I#83A5Z"Z+*HNW'";0G(3$M)\T -M,O0LX4)L-FADIF0GLP;GEJL=/FL:Q/3LJK+WY?DMU\3N]78Z[1_$8#/!FZ7F,Y_K\&Q7]'NQ-<(_ -MP&=@/B\LYTOEP4IWG8S.0\%W4J.:8Z#\UG/W]FO*+8BB6JA -MX^U>1AV.@+28/O,R7N7J!UZ4\*[[LD* -M7HS8,C^`Z7A-5G7U]$R\M$,X#VD)8[ZDL"(Y&O-*7'P90CF!C`A@A&B%2N#O -M(;9MK!L#07_4!347U?1W=1>[U<=#Z0?_*@WU)9C%V0H"48*^@.6B3T4U[^1J -M,!D/[-)#ILWAO80?F*[3D$>8DRZ2"S;MUXN./R!CL'7Z'8B%C"IRRFB*YSBW$6NEQ^8/0WI3<=Z\58-?ZT%8RUCX3(H -M]<=&T&D-&`+(G.&>S\=Z"X9&B\2)>.)`Q1O]L5J@!6=YY&[4(Y*G:5'9)VRRN8.#8_02R%J':2Q;7"7>;AR]WN;/%>V -M;*"`R5RM^FV(_X.J>\RO*?_.5`P#"M#>OF_:7`-PN4[]E(@!M7I[*B&-[0"@ -M8E`D5A?OHV)GG]A?3BCVV\UX0,^0&'U\8)L2_WEFNLOC.R/%RY[(RD?-*5:! -M23E#`!DL(`3&^V7,B?2=Y]^,[>K+I6H%\:'D>S:`AX^ -M+:B#$5B+??A5F.OG0E;$ZZ!J@P+).`K"EA7)D[7XMLN+`,9G/$5;6_?I<_=9 -M\+;KT/_&;A/-*O-6P,GA@J`7XI0/\H*,)P%]M*6S8)7I2-_9\7/S5OT2]0/? -M4_A;^O;92$U94=\U7R"70$NR0K:HPWE7,*]`0;]5T8Z=&/$P4K'09`0%(X.* -MX]MHN9B[!2O9W=^IV5A/;84@%-P\[X@#=IYB4*BA*H);95MQSU:WPR7F'EEP -M1-A??PZNW2Q^P2(-'!-P()2\#];\1N(^.KWZVM`Q/A<-W[D\5\Z*DD2Q03DAP#I7-YHY)]M;/,H9AO^YAB/'#X)?9% -M2DX\VR;:>]DAL"18 -M=O548_2_?IO?(G9Y%V8,_6VBT)I5@!@9T]HJ53(CGL7Y>`>W67=+NY(D('<: -MIS$;QD%1><)^G)V@*`6I3D"9<[EM$^3#MX+BM:(4P;I1#0Z1E1'*EI]RSL5Y -M(Y]NNWLU[>F5O+&V+$U*'K-_YW:MFB(;@/N`Y]YI'G+"^(CVCX#`"2RDD-^[ -M8O"A'Z56N[QJA\YH]8MW\8HEX5H3]##64#IIA,3$PY/V"354I<5W*;Q,!/WY$0*KQIS5_NX.0GM55C,W+$BJA!&# -M7D'OWHVNB=YL7W!-T\6)'BB+*^X^9GE`(PE&&-01LRW0/EF"%_K96*W`8$<$ -MKLS9AE31K*N+-9[JM)6S:'+@*PQ?&<*C)Y,A;5TJDJ,EETWH:?VH";*\&#T)&\X@2N?V]"0:]#KEUSV4FQ\OX=BGL5X.](%0<5XP&>:7-/ -ML1IX^,B0<$PJGH@C\Y9.)XJ!6UFD:_GS%FDH&<83C6S<>)L:3$'3\5+UL_XS -M(ER5/]GZE:ON_*MK6C0\27&C%N[-,!OP>'VD1E0#,9XU=9K@11!U]V.;O?C' -M0:;C@4*H[-+KN;Z@7JP,R\GB3B!Q#L_6_#%3(7-NO)#=43N_%B88AL2>@JE5*K -M7N\,).K_I[P"U3CV=0F9:/T#2*Y1R`(S4-@S0_.5ORT%S",)0&4_Y%(Z0H+Z -M"\Q[?[;Q<@6[H,X?3$3IRF60CR_P'_HH7VM08KM>XWZ[[W:Z -MS`HY>H0&KZG!)'N*O0G24VZX\Z&.ICQL_4+"^&_J9Q\^:'Q<>V1AT*V(N[55 -M>09J/]0J-!Z_NM`/`R5_1H8'NJ=,GU$U\U?BBC:MO<>*3/T8N%7AZ`$<+DS -MN+P`FPO-/FX*\-&H;G -M[B>'R'AQ(@PC=S;O57%%J"(YW-]*BT>?,X5ZL(%`W5._^_F7JE6OET[<^92- -M+^&#_^`/T]X)V/ZJ4O2%=W#R0K5-7-+] -M?(JDN6&.X'`R*3QH=/Y,"8*)::Z<:M%ZAEPL)E8+>)U89Q2O50`8^Z]>V(>= -MKQ/>UYZ)*]W](6SN`,*9O]M60!5.YU]O< -M(10]K]G96TS2S_YN'`:8"=BO-`1$XR5J*]F0S4S[KG1RON)J9Y7&H/Q&0/]T -M@U#'(+F-RLMW:P.9OU?0RGF"J"REC/N];M -MQ3J2./U>BYHYZ..5)BTL;LT7*-8,.UL`]-:B%G4S]'`KJ.FT=O0Q2=95LXD$ -MS?,,HS[L`"?MKB.4XH01!CY/2P-Y.@E./[>?1!)),?:1G5\`MH#?DHP-&.#9CSV58$/\IP433G3$0:E]AJYXJ^H]X&5S*O4,(5D16X2!B.WKL*2K\X- -M8B02-`89M-GT1U9J=/!.KA`M+Q#66M[,-O&.X'[-'>M68Q3`GC_%P$O_"_$% -M\]S^NX+=/J86+3VR9GV34`4Q)6!/TJ*X=Z[QEQL1%A>,&`6!EG,Z6>:=?8,+ -MB[S-Y'5D,725F="!;=8X=V([(5>!W9ZUR($4_`;&-W -M+1,,TUX';,+]==(!*AAX&%]7?UC3/A7N-S*9#!MK)E5&L'#Z2?I=\9SZ)CMK -MP6[0^HP\17;!O\^L+OJ#2).FFM*OGKEHCN`^('XWK98`( -M#`#03IR9_:^5/M@6PMP5<55-0=]!`7GIQ;A+"+XTQDK=EQ7Z8IB1MD>[_H:% -M;NJ?:_07L[KW4E4R-8SGIL%YNQXW1V'C"N'\@"5-6G63^*(S03@,S4TK8_T. -MY\K>=!)XI2WL&H--00!/V%3'3CQK(RJ@`7JATGZ,RQK-Q)8K-]HS;WM9HLT< -M_.&[7/YS'UX3Q=[Y$)GNN\O@#<@<)^N$9S?.`.P1LE[@8]]ZW86&VP71>&ZL -ME8$+M"-`YIA5L7A"M+WABB6J$S9CEQ^G,;H)29BY25[X_(#C6(CKY?)@0A9_ -M6`[<)J#,U(>QW2P%XJ>S>]IL#:>Z/7/0MC_4)";$JB&IZT1F:N_>C?L=DRBQ -M(P.%F9-60<67@S*^9$[)2KCOY9/0V,=1E%S";Z488>,-GN4$!.S?`U.&`!4]AQ)DR>/S-P:Y"+%W_)OJV-70EO'4I[R$1!_E\71 -M7:J_WZ\RMB;P%;M,T9)C"Y1I4OMC&7KZI^..^-Y[%U=;&!$DZF.=)4@DJ,3P -M"F4W?>`MGI.)JX-T4V=\8'F^O;`Q05/-AS&>L5!N\G.K5JC8MJ>(6*,1D@NT -M`UPU."-46Q8.]='_'Q>+:M.%N1"1[`72'Y=DEPD"*("@-:T6^4P_Y6605E#T -M`VA[1C'HCI4[%.=@*WRF.F$#XTUQ>^LH?Q%P$AK&O+0^`T*MJ<\_S%9DORC= -M@#D0B^<9)WO1YL3+0[G.]&YI[:4LD56 -M=N0H`>'W;;^(ZN4W/AE:QY@?!S"0(S_AQC(WA*FD;YIFC\Z.R;,AH3;DNV&< -MO`9_4+7LS2CT.2A[7@P./FG1D$:9A=082C_F^VXC&Q[XF6"@C9TE+5X/EWF[P]L)6,TO[B,@O=KWOI+BA\^.R'\?_%'.A=6) -MC73HZ8&\+)3LI>+E0DUN?8/T>2,ES>51,-[7D,+XJ\SY');KFLPZ5N9[9T.KGIHN%]$$%#;&E?T]W3XB5;DW7E5$XL2T5,/?PR]VT3S -M?'I_;T\4\@V<5I?[R'A[)6S+0J,TI^&%;L`Q&XO8;'RK8[R*;*::8+\/B/]L_6#WN=/-:A#)JMBPP -MZ?O,OA.^-^N&-W?%,EN'K3#$3YM\'8^9_MMRV>D0$]NWESNW,->H>GD)<+3T -ME\9-"L#6N+09Z(A-5Y^XR8GK[R-2Y@EO^FO+M$;T,#\O$*QX-A5)(=-:R/_I -M[DA'UB:EFAZXS[^[,P?G+4QD_%]`OYVD]0+="FV1<4R1W+:B'EQ1>-+E>@72 -M?/I:-&=VW@9T]-SO?T$B5H9QH&CF=@086@5J/F%KN_B_.'00A@"./=>X52+7 -M_%EFR8"E4F)`<50-@Z,#`G!&BPA(^H19TGE540K+$!E$H3"KWOT_I,DTI5":*BXC -MND'>BE7UV1;@W49TK+&>V[,\@UJL@(M"^T -M)[>,%FC\?]0:94N)B?8C/$>5/]"]J5"V'8O?C+.##:\D8UBD0&>WR97$9.#] -M?W-YV.!H/3?]L4FR>32K,#K3A,IZ&59-^,+,T&/ZH'M@3Z5QDTG:H#B1T&A. -MK;L*MIZLZ\\KO-YAD^1A]Z6&PJWFT+V*.^T#R4O%F)N]MUDTI0I&G`] -M#F$77M91KR#8;DBS>QH!(Y5T91Y"0LR,D'59FUA;H9R_4V>.@Q+TBP/5U-&' -M3+VL"*ER$+X3$]BG'1(EB_`^MJU:( -MD^9\FK"'J;R6M3JU2$S/I)B^*=OH$JO&A"U2[\$QF\^/E8<;Y-R2J:D.=-=4 -MOU;0A'\1,)RF=N=8]IY%9*XYW>2]FY0YM,+?/35(G`G8D7Q,=I<5M:*Y-J&] -MT+1Y611=Q%6"%VC!JDUFK87GY9CA8`I*/$H`^I53>>4C.[=RNX(=)N"=60`' -M=W-1/@$CKO8./T:_L+JRA6X]>%<7[VH"@S0W))S\<`\#=YX_96'"?XN$Z9BJ\/';]HEB\!>4Z@R_=BOE/KM1_DGJ>KV/_MR_#ZG1VFKW -MIYFNO1!C&.F`N?D0$`FY\A:.L1X\RIR#B>7?:5F]WL*FSW!Q[-=57\MX,OG4 -M:?K(HH79]1&;!,^-0H"?B'R6O9V"-Y#1>Z9AOH``_2[_&<#1;/?:, -M2GTL,5S4X:UQTN'P`IK[]D+B$>/)>#)N?E7$#>)LVB7<\^P&_C%6&"IF8M_& -M0")V'2BMGB8",1CO%Z:UY5:*X5)5%..!?^$GR)@#8\%RJ -M',4UI?9[:A2E65MGS_O`W/_.X)5G]VP1(9[92SU.):6.%'(*`"6Q_@U,L?'4 -MC9;HOKGOG/DA@R]T5X]*L]+`(+OIG=H.[.2,/-:FL7[%IBTHWHGUO>'U(X'Z -MP_E;P`$QNT?@I/$A0D4+>O:+,?BA"%VG-///'( -MM9)R/P%/=9!G5`RD,^"0Y5BOCDI/V<$'K6C@16:_@";MM\F(IUT+B/!R\<(V -MZR?#/DR'X:QY\4VN-=M+_Z^JYKC".Z9_Q=&YUS256O-TGGE4M%`O-H97_ -M4$7FX@`1T$35@CW7J*+6`E%UHKO1@#W/TP+D#E9LRNMG@))!Y^%M5DK7A;,9 -M#S.4'JF_-O/F$EU>C01<6QMH=P1WI?:OD#Q"``_'J?+-FN725*%C$Z`6]_73 -M\RDEV-W*P"AMB6&:`'>D,I#D4-;.E_YT#085\,I;>QZ4YC:=:)EH2_J$Q2A' -M'8T1S8(A6*R8EC%ZNNN$PG0&4P>69A?`,*S?8UZ-2#4LA#][JW<$Q1)TT`)V[,"\`_J7)%]GD0LT=YTZ -M@163&M#3'?T77P4+A']#.]Y(]0G!2X\@0N0G.SL&&KLE4DRLC()O"(KQ'SKL -MDN=@!V,D\TJOXE8:YKUKY]-^+#-;12CQ4P@9PI-/3=&F%W$,JQO/NZ]7:G(Z -MQ252>,:-]?8?WBMMP/W8+5%"B$%9L*6/T$JR;`!S4M8M01B@K%^^:K7@2-%_ -M^]#0@6Z?ESNOSH[.EP[<\MUG388IL?04[5.3XKJ`.?QO_LJ7N5>"U8[Y2H(CR -MX53&E"KAP^;I/AJQ:5RW^E1-5YQ>'!#2@=N[I"$#^ST!$"(EZ<6. -ML;AF?RU]1';9@``HOU57$[CUNCIJ&"%)FEJ/<,P$>Z`_+BL>0@RW9QL"]1U? -M?W6*!ZI//%Y`IU+LIR!IN-^O?*#(^@.DH]VOS,',J&M`&]K_B>AY$5U-- -M0KB!]-?"AC4`RW*)632ANC5=R:<5^5F,9)Z%/6\1I[I(^D -M/<-)/8!%Z6()H;!>6=/HR("\U+$;R8DKK1!PTB&'RKPJ;.3?ND78`234`ED6 -M<4]-;E'PJW;6#+PML,6PI<3*RO<+QD!MIBFS6)+8& -MY&#OW4)].(._G45!/T*W5EVVLPPB#W$9V>0FJ#Z$F13OFO)#I"JS9P+Z2N%UWLN(*JC,A52V,2PCDV+>W\4TR -ME,T^`V?D97^S+>IU;Y;MS+)ME#S^JIN@%#U]6>W -MJ,V6*)D'.5Q@[<)$H!CY9!J;[TH2,2(SE)90O@HZCA.\*EJI"AYE`F,APB,' -M;@2ZXOEGFWN@J=]!V?`=G3_$!Q25M8;/\];3.6#]Y..%50=<\#WR_#-C(.J2 -M[$A8/8(P'A:W[)7X_85DN?`ID09ZE.@'LHAL9YY6#KR[+ -M7B07A`)Z3Z5IB6Z-P\#+PV/;GP[C]Y=30>1>G0+(H^'M5=@+VYS,P?(?"EC$ -M%E?M*C^*XO_TCE5W`4[I*M#W>12>DUEF)190JJH0T0P$SXA_,,Y=(J`')7T8 -MV;+QE6XSL_G]W";-!02I@/.>!"[^8#`Y((+?KF"WHR/_FVQ1B4[9[!0,!`$__^D[)HQ*)=(3M/_:T_HTH,6(CRMYWM9-6%!-W9+C$]W$2WLMC -MDSAVAS*^=A,?*:CUC:2J][BK&3Q!G,+6-P]OF8O7>Y+B0?Z@'`1N_?B8]-ZU -M>UZY+X>$\YK9W=8RXH?E&>C_G$_T&B_`:7H!GR)[!EP`T]1"ULKP-`MU)Z3G -ME^[5^:T#5PB+T$_,>0K&U'S8[?T#&_<`6HABKAPB>J8?//=-,7T\GH$[S5G- -M>"R<]PQBSEO0"B%%P>6D)MZ;8&4?;%28B#B64B5;0X&E+<@D^W=B,$KN*0%< -MP*,Q>M0,$M=Z7(Z9"IJU[F_5B*',$C^;$#&^ZR -M0H,8&J'#I%6[EM;L\V0K@>_,><6,A"=KK3+YX)0\(,&QL*+D&6;^.[XH,4L" -MQS0%B,&U9P^T24)HT5LI;S`TPJDB'$K#^[NJ@`K`&WT*P=<6XRICB.N;0E"9 -MPZ*E*>Q[W!AJ\JUI__2%26B(I?WF]JU)'K5\%`Y`U)H#EZHI[41_`SL$6["< -M6.B?AM4X($7+OW=33R/V>#GWJGX\\@"+(H!S3*U6CU*/$4M)'L^V+K/%@-=[95U@!,\#:#U-66_%5'_=*@N2Z.?%H,;+R$0#Q9=B% -MTG(>Q6!7VF4\2M:2=0P_4-%.<&M=\*Q53G,84^K!*V[OT!,Z-:K6,>L1]BGX%YQEL`C,-QM4GLSW^5V4UMRXO&41_]ST]GM"L:>$WF-^N+ITL%O& -M\\T)W\67=YI?HHFR+RLW\H^Y9$"-\G?]X.I[F5>-V?42*KE]?FJ?U/`+@'IV -MFG03S$'V(8$'&Y)VAXJ'*35Q.!DDT&H]U<`>4ZCR<:.O0UMT28]L/_!7%3A# -M2M_?QXK/=+AL&:%]KO[]`@=`HVH]G[;-_>DU`$F''`3'G51>PZ-R'N>%,0_+ -M.2F.OLFR)E(_,%RX`3C#PF+\^+$XRAK,QAB]#5ORSXJQ=A>KVG):*06_O95`EP`_C;F,32UE-0%W-/ -M>C)0]HXBA(MCNZ`%0Y%N>]Y@Z&9^SX -MJ.CJO9J?6+@$!G(V(Q9#)Z>Y^5\;KVP?B8M>^EZV"5'X.:%>7^J"C&QH4;WD -M=S>\]>;4U@@8:G*F7:K?_DW/9WPE#$EA)\D;5""X0^O6Q9[]MWHXZ@U.`%J` -M42T;"=8DBRO-R!C:'Z$0M=FVSC+MG-M,7/Q4N;K5GLY5H_ES0R0[&OX8Q!), -M8:C/DR\"JH6VAVZB<*`L"8E2D-,$+SFR[_A9?5R$#V92.>_[9JXDJD)E3A9J -MK`94RK6W:MFZU5+/H<3%#U$",?)'*^US)H6"(*.\`.]84P"VK4J+M\KF&;5. -MHB*2@*C5-?V.T!9,Z*K<$A[SI-Q*-(J,/T&-F*R:`$`%>1SV,^=.SS/H49<7 -M/RF-K0V!3)"N;&L]20-#XE/JB,'$K,;0G`8@9H1`^I=-P+"%O1P1$3]RU'Z. -MS82;.N0UTLV,!*%PU.]QJSP'B+OX^29+_[EJ[A7TL>J#;!;@-,!7QYR)-3Z( -MP3)E/K"5^-F3XXK<7G:H^"K(W?T>B`?1G;PXJCU]&'"4J#:I3KQV`H'1093; -MS9*BW[T\05J__7T$'H$#U6:^"W"9-3C@GX=+_T:,"0M*ZT9=V#HPIB4*P,M) -MD_@N_D4GTY5I$E/[M6?TO$9D1GZXD<600%RY*>4GKMX+<_+;C]3=X7]?,8`/ -M/P(;87_:N'G$-A?EEDX,HLQNQ[`&=?D,4,=&"):=*?VML5+KS.%8B]G)Z,8, -M^_EC6_H?Q0GF'2!E$R<116F!4!U[%HOAQ)KL>UZ,.RM)8S%OK9,P6'%4X,)S -M$A).GLPJQ6;VA#PAC:ZNG1&:QI9XS>W4BH#]NC,;`=F-?YSLN)& -M&=3*OBQ8$;=N0V@C[X;`ZF]^?H$[77O/(?6"?4OL"YI2FFZ;L\TNN@W-^*P_ -M6'B+R<55[=]P)48)$*)U66Q9\7VH/RP/OF;O$KFTAOHI&=YX.M? -MSL'6J%URD:"69JNSR,JV_@EXWB%%4*C&4EOX&W$*(89,[7\A[:LGRY:1-SO? -M+Z.EOL7?QJ=*;+57;'&83QR..)OG8T/2'E5/BH\B-QIM!6W(%UKC8[D]. -M#]/LZ@C40=)!LU(Q\$C$3-JKBU(P\5^6O5%<6.NIK"`T!$T;Y&TQX&4#Q2%` -M>S7?AX@P`'QO.D_S\,^-S:^9`N8IQ(DVR^,C]#EYU,[\2Y)E<9ET>0M%T?W!,JH.8<'3CG;0;&C5QEF+V -M!X-<<&DS":,B7A%!6#K((8"@6XL!(=>FHG1ZP+K6'GRPP%TD=`J!B)+S.GKV -MH&00L/GOX)\%A-Q!L4HSZ.6M1=12W<'A6[QOG^CF1?#P.S-`(@4OAGHPJ -MG:V2XZIYJMQOKU6Z3.5\/M83PW:;8'BWT3L-^05S[464-.%TERZ!MBYVX!%. -MU8ZG@Y='UMQ.OZEZ.M+,KR -MU<6V5OGY:MO9_Y[DUVA('N,^H)!,9QBQL-B<0R"3XIOJ0 -M6/6[E_'#^JBMZ8HK;"YK\-7[;E5[)IC7?>(](IG/FI,10"*"IL+NS]M30PA[ -MH!ACIO1L>((;@N`'G!]-,4KJ]G+1-_4=G2-!B3P"*]M*1T(GM2+,!3]DZR16 -M"2%'0#P]A@:D@5TXB2N[,H#9+]\%0;CTJHQ=@F_>?8>-BRXD>P)Q:G)^9\N5 -MO?*6;-@JJB@S6Q#ONH)IO+5F0,I,L;00M)K=I9NR-?J":F;HX7^9+@C7&VPOP;W0KTXQ;.,H4SLOJX4)WYZRX;[%52"P)&EUWXD*%ENASFR=C -M*'O\,=@ID?@"WU;*8]BHP-RBX!H#4(Q^V\``H?("V3=Z?IZSQ)F(4G4I8^;+ -M5,=PN/[T\,'(F:.%KZ5;EJL_7Z`JYD7L;*D'\"?6Z<]MP^[V($0H0_&&],#C -M:<,]_6P:KGO\O\V`0S,_O#2[DE@'F71HF)0,EWVY4?7%IK9\`93K>%[ -MRA3CG0J-;WP=TJ^Z/<)N=3 -M\!D)%T+V-+SIH"<"/_!HO%#^GW/J?^T[(WAB*$P;KKD%],B[DH+E>%:+NLD4 -MA]37LAM7P!\@QCKN)![*J?"7A(GDK<95X9=K'9[0G?X((>"7Z@R2%WQJ]HM2 -M[L.NM!`IOX?JT,%CN.+NDNJ91/N:%0!O#&RL%>!P_1]6@E,B0:O(+OR,^[)< -M7:0:=3^_9;JI^?HK,XX<^04=2Z3UT?E6T9.CBU2F['/Q9#$^*%G66PKOC?X) -MX6==4(`H&)R;N21X^2.]CABG76_X3B#4QV?=3KN>4N9#BL^"-4]M6<7\P,1I+_ -M^A?0$)S@053CR7?7&N[+F+(CB;'R',49+*=DI,+JX4T)\J6 -M6RZCVAX_M0A+,S;1[WXHY%`O60.KON,AO_V,\6TNJYZ:7YRRX^?KK(?AT)[]VN=CER:]RV^^ -M;3Z0\<&;N;[H]L*^(Y3H1K8QJ$JLD]Y*F$7H#V?. -M5BO79'9LG.IR0!)R1<>E,\GP9U>PW8CO6/YF^?0MV&#AZ`#[T`$&$7YPMSQ= -M'0MPO[>>$U=D$^JE#K.C%J=5;XXQ7638_MNFK[:\H^I;GZI?$DE'OC)L.8[J -M@6G)R68,;4`NX>\W`DK(-%(`#=F01^\1M3.;'>P^(/1$VWZ!R%X,,N*<1^!H -MN:$(>*W/`^B5-K6D/PJA7BU`?K2J.0J7_QS?U:6$@"%AR&27I=F.'6/+%GK6 -M`PV@OZ:I@'T4MW5>]6_*+.FO;HF:KQI9V=@F'& -M=2=XA%K:(GP,NK.+W\>P^!X`],;,(K6+R;$[J^AVXJZ[*:"TR)%2#M4HXA7.BCN;^@IX>/`T% -MV;6(1>][A,I:OTF.GZQAIUUGQ(3$)7?[*3&^6Y1M&W-FCNA<1NY&,6AN*'"\X0`4H>C'`$ZQ-,Y9U",Q-D">//49DL8&K,LOS)GG;92$H?N^ -M6@P[;E=`4)&6?F%B+YIM^AF?YQ`\I7]M&',PJBIW`>I_L(>,6HYI`V&ZA:.2 -MA4#XATD+S(^+T991I\J%2!@Z=HY+-4-0]NI*M04)+V`58_T-LFS,?N>@$)!9 -MG>79!);N-,\&4)>2L^[Y*57!LR>U.6#.=`[*TU]R/L-V.MPN:(W(K3\)F1O2 -M*$-1H4`IF7PR`0V^'X5EC"^&XV;#5,7M@B'92%^7I8?:S:DJ@7XL($AAH]NA -M!UU]LSW-JY3'QXU@AAO8/H=K:3!I*+J2+B?V=-2V&]BLG)G0)>SK3]/$@BJW.-N_WVXZTBP#T_T91YA -M#J-86'DB3D]9@MK//?V5M\.A0E)II?>L\MHY\ZDFL0GUKU4E3N!;'@@&+KU< -M?:,S_8_GTMJ.M/03^+`M'*[>U1^&@Y=:]_\"&R4Y9,ZX0[[=E;+[[%`N-S.:2?J"K -MJA,X"><(F(T^S\G1?2:UAF1CF02Q@A>C(UZR/UR#?>HKLKS>=U7*JIL^J-?F -M?XOH-@O:"/<\=?%Q(B8PG,'`>Q22X&S0 -M`?HSP*IG=8IJ&!#VL,#TD@++V1ZS^@.[N$\(NRL,%WM>K2ZSW^C -M(4\UJMGO9?:@W2)/JV]O'CX-WK;[?1F!C[:1W45`B.KBVYB^]N.8QL/U>D?N -M*X0EYX2$-SG(NY?2RBH1DQ.QZDIL!G/S78(3H?0T;3M*9L5JSY4%&P45$5B@ -MOM?:-%0O0:SD.:8E[SIKRA+\\*\$JUL4/LM$,!S^JLV.RV\^@Q&8`'GB]G/B -MCM\(RD,9$IZP8OFFZ19&AR_=ULTH\W[P7BAUK#P\GV<&+4)C>$DL9Q:SJ-H= -MIL:LT7AJ"Q51LC]+5!?(&3,%^5%\]].1F]0YH.QC#O\SH2YSA7F);R):KF;TKR5R#Q7Q&_9[YN9.GY#/" -MGKV>(!/P\SI=&E7YY233#N7BP34.ZN[+)S$-8R+:[++K,^28\/[=P=B(M[K% -M$#X1LZK7,XNTDSH'L3.<#&+NT:@;&A6+16,PQ -MC>'QQC&6]SA7JFZ#;Y!R)R!%+DV^L_Z9W%NU'(^SQ(=K1RNR";R<+H5LVIMR -M`]"J:%D/4I>,UFBHR%G8"?].FCN0(EL*35R_F$([V=I)#'H:*"M19?W9!8Y$]U]%RYJX -MW?#4A-?QF26/Q"O"^/`DP=1(>LZK/3F1XYHU]9%3I9\K`!#=#>12/#E+6GBL -M5R+Z;)KLBS;)VVQ;#W!#72%="W9L^'`F"(]&,3(^B&S/U8]K]V;>\0H1'[-M -M`?$Q>4N+5+@X16Y`.-)K$7'^ER_<.G"1JZJG&LIE_![<&T<2]Q7,9?3(_[_Z -M1="TM'ZJ)E,]Y>/C/FG&0>Y=,_]36?SB^S876X_`2W<]Z,`9"K^3`HV -M.R]9H@WAIII/@]>*GJ3]PH@*VL:PK:33%>NYI[(D].R':C`W@P)I8!\G2-<, -M5Q0("A0!;*C"ZE;]8.8[[]9D]SL`\4_\H]NA:&1<++T"?\]B"1XFEIU:?7JM -MH-L-(]TC9->7;!N1O^FQ4I6;O5T8M1YO9/"78OUD,AJ24OG.,'>LU -M);_$HW&WVBI==$#WA2]Q+NH(84$NF_F$C#4Q+`.!`/AXE19HRX8H[A*R=F+""LV -MV%$AP$WB7\XCEEAH*V\ZB>)#P*Z4AEYZ79*"4],=:?.]VB7V=#EOAD -M@)>]?68PBG\BK<6JQF_3@!N85"B&WV90M)P!'$D.)9!?M5M -MY%^-F>72G87:.5E#L>3Z=A)#]8;9FQ*G"#YFD(V0K[UEGU,.R&/44/!&V:-6 -MXXPV\EW5/WI87-W-5![.`-$%E=9L)C#()B<3$Q`M&/->A,+HQ-[H/7LO<()0 -M@#@Z]=!HMLN3SZE]"`OZQUKXNBUSSO[RQ0- -M3P;[>%Y&[D1R",*OW1_A](N.#I=1HDO3FHO^;Z##Y)&`?*0/Z0J.?T)3,8&` -M__60,*=@=5(^?6?[G0:O$1W=_AX%'_3W(C>H3KA -M><4&'5RN/*ZP@'S_V3.A&\,6$?GUF3]ZJA%%M$^QFH,B^%%JV.Z0]H'I/T9O -M"%^S1Z]*S%PN?_Z/%?B-Y8B7;`\1!(OH*Y@X,F+'+'\[F+,:3M#$*$$QON%"^M`8,7W4;2TC_I(N, -M57ZQ&OGH3XN=N<^/NSWHG7R9W3X8UB -M9M):T0;7_BZ[4:DPC#`<;^AAI,)!_5U(]N,_"O5#'==>]39>K=%TG9AF>G<@ -MR>J[\N3?QB;F^"XWS-2JRR5D.IF[YR8C\K*^FK( -MNW2L/T9E?P(N`48'3?#>%'C84.0AKP8_'R%/[6_(T_U5ZBM<'5*2%@4"$(WGSX/1Z99*Y.7)CGN_,BO -M]Q7"USWW-7KG8F!/=`KL&T3#5`<%<>PU?>U7_WXU*J:?G-^@P`HEG,(YWWY1 -MHQL50:BL3RZ2*@.5ZZ&ON-S0BPP/KY?E@!Q6<:$"V'MB+0.*JZQ,*Q*Q%=25*,UG6.%#`F+].Z^`D -M.(W0H3N8F&FV5>[TSCT];RB:*V5WV7=B\S2WQZ_>GYZLZU#E-_*JCZ -MIUW'TJSP,A$I`,YEH*B!*.0^U'E#QA6?7`;.#53?.>UY:?]..W` -M.*\%_D>FN!7"H=/A(D@W%ZGWX,T=!G?6"66N<0A[(/;U?<3C/!2T=F+_WF9% -M\/``7ZK&`S"!*A1-$`#`MY=$UOR"K9WIJG]GC4]WL+0^##L.JR4-$N%L?1EX -M51HM'585QQ!,4M^.B>XQA6@#7;YU+>^D\&J")%P>.^N%/! -MR65*C_9%99Q2("3?'89L3G&5C4^ZR!.7,0I&)Q@\V?;;\-O$@4PZ"AD+\AG% -M:)IE+'29`)LU@#K-QH)VAO&:YJS*GQ/*NZ<8)[+Z_H*-AX)^+*[?;`:Q+B%K -MO^IPZAF:(6VL:>N`&;[62YE%\O#0,"Z!8J/0Q\G[^-?'C-S1"OIB?6F*E/EW`%[ET1-`7=."6I -M7(OR[Z'SV(TW?OZE/FG'`N!9YAY;>;=".HRL.4'CHJ%K:A7)%8GI^E44]L -M!#0$NM1S`=NT1LVCZG18<4O1PE4188PXM,KV&%U^<;HYBO=^$=F( -MZ3U7N[)!+=CPD]="2L@X]+8T)!F271%-LR>\8+;%+,-A5!=^ -M&E4S0/W-^DSX)5[__/"DCIV\H\-'5AH*/^VD:$N&T*?(]N'X -MA?KIF'=CL$SO+2$"1GRKWA3RDS4YMN\8YL>MA[C%S"@826PS56X'PT*4QCW$ -M\A(@@J_./T".1",VJD`'MZF=U%)0:!J1E5V>R'PU/(9D(E*8? -MOSU6,#JK](8`:CY;P<*Z.Y`EV_ -M8V2+W1J[O:)Q8UO$SC`9*L5QY#S?"JIM(NH].?Z(J*%D[+T`8![ARU[2X+FH -MR_,_%5?Y4+CR>[?]@AF]VQQ.7;4HV?WH<85DX:[$?#$P\GDP-U-W^F]796 -M[&N["W2LV"=_)NTL4/F&%[+QA\M0F&[VV<0/4'!#>R1ZZRZ7 -M6XI,VM8[PMA%,Z>$I(5I51U^Z):BD1`(1FI[\RW^N_$$&N1%4M"L%TS-]\4FOF -M,D9O@2(6CJE9PG='(DCG;H8[)G>)+_"Q -M%C6<\7;7;9WF?GNX6X>B3GK%=Q/3&TKFFK*HGC)+9+;%;N;-(>]SC1&K'ZWM -M'X$(PC&E%FAWIH=Q<*T)[?<%=MK=(%9**&G-(I*RWY[9SJSU' -M]&FMYVV-`)RBO0X/E)0,;G2RW\$)VR7RQE!#1?P^![;[R"74NC(2X4?+6]S4 -MNEUO5Q+<7#$E^7Y[TEHFC_D8*'[>6Q:H1CQA#L:AC2RRAM!/MS1%,1%V!OBS -M`L3D*VCHXCJ$TC=>L3-:4$])A?)UZ+Q>L%+`_$Q4_!W1!-74J896W1W\A*H6EH!;9SN7,@P7Z)9+B -MW:9S;4=DB.2(HDY#R?UNCFS%7W3H_A)'_O@^938) -M3HFNB^E#+5<23ZUF8$I'/*';K$T,@&$A[7Y`B=R'P1O6[S6]XNGMM`%5!MO` -MLP9W`L07X9J7+E4PL/F1^VQ`M\/"?J%5[,&>$ -M/#&(:8-!Y'+3AB'AOYD*DM+Y*3H)LYZZ<**>O5^>0A=@MF2C7PBD8N@/U.,U -MB#77B^--W6I/+5]W5%_M<$>02DFS;\?1VZTAX)AL",+P$TDBX*_]#_[(GWL# -M#8N7_YT!B/4B)Q`%\>)@*Q4`7Y2&.SBYC<]XAO5_5N>KK1:@'95<9/*D<@8^ -M=9>1W`LYT7BBRX]^7/FQJ_G4@0RE@56+*06;`=BO,63YR$U -MJBY9]$NV:&3D_>N.)FSHTT-7Z+*`&;`^'M;#%(2WFS)BDOU\A:[Q+PU2YZ(Z\:!M9-&) -M?ZH`?CX4I -M\S8K:<+;[`T8SPTR6!KOMQ!5>1?G#P&-+FS)36BBV6HD].*D#9[ZZ'%:(/LV -M3*(9GU4^SJXH;GLBF8A7I+H*.5+V<&K\_B15'>C^#,8,]8PW/<)`?"'!310G -M%IVB)!<(5QP)GVVI&^2.&GC8;#B8.R"6LQE/&]%DR2^ -M9=#@'7=(XBY2&63+/'8<2G>W?Q"T6?7`:(R%R#,3>2#'OBAQ!). -M&OS7+%T4$\%T:R?=`\==?`YD.IN:I)'+?`H?G^(N9J=1(462-+E`'N&*\/.> -MXR(Q_+(WZ!1%N;G:X64JZX@`A51BRFX>#^=K_R07N`F10ZB4W<0_=,!%^YF0 -MSV)4I[VL2GNP`I^&M_JKA%_H)&\5V!MNY]A\X/26-IT\QZ-*TM$2Q2B8GK'] -M)WBF+AQ_@>Z7]#XK0V2GU"Z1ZJ0\Z)E:/ZFV1#1;.)8I2'?'EQ9/3'*YW9B\ -M`/)YDFB[8+38$X\&;[M%HDO*;JT-QCVQ6H'V\L%;)@_EQOH#38`Y"RRS,9>S -M!0*#NY8">9[WK$H0H0Y*B@.W^QRJ0+!;C=/A3V[5? -MF#.T\DD[E0OXARC\L)&1A?*ZL2J-`191MO"M`;,"/121,(\3T'J8]_C$G<66N=E_G?N -M(X.SNM.4%,\IQW'HPG^^[SG"Q]4J,-]2^2+68 -M-)I#)QP2Z>`3OXF"\)-(6AOI>PJMY7Z0$RE0WSR$YR[2=1-5WIPN`H+"C;@& -M9H#V$ADGWH\:C(CW)8B -M*[_A9+$>"M]`MI".JZSE7%VM\W)0F/!6N\\`CFLG7X;6?T`_S._/68WU(P]_ -ML\V$$-S#73*2S7Z[,]DW?P4%M(^EA`8O -MN[$Q@D!71;U:2R!N+">!T/BH*C/;Z5S%Q*G$GTMG).$`NXD6X*?J17$C627L -MGT<^,WJK[.-=MQCD?RNKC3O^=5%;B*QFX$-803@D9QKX0IDPMA7YD/8F,954 -MU.999.X%4ZZ# -MLWMV^]4NDQV8"DL=K@NN2:\6:BAY;3,$04J\WZFJ$H\S)FV+TGHH2?'*MH%) -MI'?F,7USJ;;)*Q]6L]GT(=_P4%Q?^U_!BJJ[%)-;Y\B99O$AH85[IWV-2'#D -M1CH'W-$[F2JP#B*LO](\)T<-?NNO1LD%,XO29KZ -M%ZA=O'0/#]G87ROC=G.+:)ANTVTND\W#/`O/WM_XUEX,/B -MBP-DHD5"'?M"M5JYOFWSSE(NWK"0NU&-HSL7<1B&J_4/.0?$`=R91JH1>>3J -MC8["9B?A;0'(`D(&UJ"?.PV6Z5;S5G)2Q%S[W61A%$=,@P#+#RP9(J^.9J0L -MXNYP>(.N]\VR2?RB?W$G>)A"@R`A3^7X(]:CU;Z_C%13+W0R4M]G>`OFQ -MHK"$M0!;3;]+\&JK55F3"?=C1F'HS+8DAL(JBJ]D+(K#_-3CIOR\MT_LEZ2D -M6-T:-2-F7+<]'6R[,3:+J__`:Y'P.!V3"%GG@DR0=Q:"6#DND8,!@`<%`K]+ -MTO=JU1;7^.5^8_;&_4]'*(IPGOR9^8;/N%?@C<>S^[?)3IV'E,R.>:*/.$?R -M37VIPEG;*VC^\K&7`O?0UP;ATL[_:ZCTQ,MS:L'VP8OSU%57ZV[T21J-?"FN -M.7GH>$A]$HCSM0.]\W[(I+6ZZ/06I,/>-"/J\7(.RKTV*5%W@! -M_>ZXVB2'4C2R#?)\F@`>\;XUW!V[X=,_DK`"!)NUW\4/'/QA4`#5V@7F<&BO -M[':;C"!$`\$FI9Q0>:I'^]OM&5IOF=#F?:1RE[5/-=0/A8)K:J:>!.,19MO0 -M8I*6Y(\8@#.&SY739F6<"ZN/9SC^K)")F1J0SF*V*LZ1@T/N[M[/GP0B&,_) -MO?*`5:OL4GX7T'A66VK`XW?J`,4)[=&;\_&&AZX8XOY/1^MU)YP^`!Q%N.OD -MDM3'.;]M4J#GWM*29(0@9Q3UFKZB\_G+FEH?G,Q4.N@]E=\)_8H -M\6FIP+\$%;Z[5T=-TQN#6B%X%IHA"P?+EAS\*YR!ZB-268^PF>)*L);Y;)_N-AKS^I9`N%Z3W+GGRA$@LO:7%!?CT&@YYS45N0)W6)6264V?$'P -MR=WU$85FK/7=S7&12G#JAD6WGT9JTD-7VI*IDFY2,KGZI]?H_XS.^QGBI-H$ -MKM`!V4]D"VV0\`CJ=Q,9AOI;=$^5;P=RAGL(#NJ9V\@<$B?04$ -M_=2N)5BJ_;. -M'[*4[K#$K@C\!2-CJ0@Y_`2!G>._M1!\=7(Y?/ -M@AI!,.,#)OF1%_NPTU8ZH\5#K*/7K8O@F_Z^F@@>%XG]/$<=N%LG#QK5QSUT -M0J0!$LJ7>]]F;7[DM0YW[-`=4W#N43GG^@%N6M8*W8ZJ&C"BVFC,UO-DQQKP -M)50F9"(YI-0+\3$78QZY0Y?XQ/`^4D4DM5NHH0:UI"?A$YZ7"1\[.;\L76.\ -M)O\70"2X8-"WE2=LJEX"B/))K]M=D0!1Y)WCS6?*=;Z)5 -MER&C[#4T^UO5CQ@/].@+)'9_W1D*0X$5QS(= -MPQ$?^"N$]X1]J+!1OA,L]'7=!YF$X&%R28FY#/0(5B7_'UQF'`XX5$@WV1EI -MXJ+P^$+9_EE=@C<*!1F76X[/\+G@-[\LZH)ZOF*>4=PI>GF)V33]RHEX7K#E -MAUR?-K(UZ_^#VWU7OX;_LNZKF+Y07K1F&>X-=#@?#BT3N[KC"VTG99$F75MW -MTU0U$^V!R*RO2`V=F2K\CLI%O]!!`%B/BRQ\\BW"H.<-I%5`?8?^!@IV1<8B -M3WV6Y6&HMM&V$B:$-.IP828*I4D3#-CV`$Z5^5'#[`3:#R%-B/\BK`=4?DQ^ -M(=6=57N@UW#FDU._7!Z99]2Z8[1HYK-B73=Z$J(R":[I\COHI$$:JQ`,44D+ -M_R[WP4/(6_^HS4<7P,^(&,+'&OIPDC/^#!UC+%H&!:RS:7/L=\/1A0^CAX]@ -M^#V"P4G.D_("P`'QL:13F>,TB_YCAOEW1B& -MT?.2@AY3X`M6Y_;4*!&9Y`J/XD,X)&0#O9/55-V3FFF*RW+)YV[]^/"?C#0R -M6!I1#>:/DD;#9E6]QI:;480Q@8MG?27LFYSV8:;&4?23NM)H-%Z`07HGI,#+ -M=S(JE!?\TJ*?Z3LXLXLL_]/3`G6T7E1`O+X4:K0$>#YCFP4`,OX[7NYK^HUP -MZZPF/IIE+/#8><)A?U2E=3+>E3V5I^7/[&?!T2G-I.6AY1CKK9`8%./"EA+IO-,"/` -M#6(B2J$:4:?T/D'8A98X734,&#FN[H#>;7]S#X/%18PNNM/H8+NLKOQP\G`] -MM8X@!>N"?0F1S551[0[[9X'X4>_,XS^C[5*7F(94Z0HODQSS&562'643VM_% -MWBK[G*]'/H3FVQ#T_Z=:4\[*+ON83WR'_*K'7"-@IX4C,II"#"04M$=O)JQ= -M(G\^?&)\.9OIE^FH,[@1KK5-?N=!H_1X&!S4631,$.J-BVXO]DG\DQP8P6FD -MH0]T3!MM5@\_\,U2R>ZCTZRKF8N)E0VJ&HA-D@Y> -M&DYFX@$3I*QUVR[+4K,6#[OVY/K(-DZW36OFN=\&<)(#DH2#JB9_`<4E(]7< -M-Z6SHRH4BQF>-K@OGM[[U9V.0?QII\:9J&;L)J^DT:DW+KE6KAE=_43Y;"7N -MC(3W4/Z'IUQ3M?=96JL](-CYY'X,N>G"86R&\>KE4Y;.@214B_+3>0%C42S/ -M?H#@CE#'3VDF?NWD8CL1U/KK':!GL2R9Y??(G2[R^A5K2Z -MS7/,B3T`&(;F:SGUE+\-1QU>7T07U^UJ]A1T.XACJ.-W^D!U%,HJ>LJZS;[? -M4"^XP@HN;B9]#C_]YX#;GHLZ-XT&)&R^9:QF@7@QB5@TX-3_W%#\A\C(C64R -M6>W?,S/7N4/2A1Z;C9K_*?85G]`I5RR!=D%+W;L#K)^O\!?X^?C"A]HZMF5F8%F?.W+44%B<(*N -M#9>S4KRCGS:K)-6'FBD$PMCKRKQ&!>\&&*/FD2S[#'ME*81*6Q%3%H1[5H?$ -M%USY-WSYSL@KN72@K;$]!I8E1>,K3T-V4Q^/6`ARIA?P#&*);/-_9H4DV/6$ -MI?K$]YU>3_YZ`C1G`6-E^,W+3:FVQ_\V[VPMUVQG/AJ>`-5Q"'7S5;&U9)SD -MK@?PCG+WSBLQ*'(A:S90GV3U,XA9L]/!G%2IT-CZ'AB/8DYCLTQHNJ.M#)C@ -M%0=BCHRKM6G+C?P]7UBZ58L^H,2[T"]UHKE*&CD!LKK4.DC52E"@JB)4+*Z: -M8Q^;B!EF,K>L/QDU#-\20!H)^>/E,ZTY<$^B<,X*")VN#6?[^UZ5DT_.4G0X -MC2`VS@)&IMB>W=E!`!PK+BY.;M:*S<5>X7>)\;$,NLHDAYV)OL/VE_*?^C:* -MQ)/%C/C"`B;_TC:4G&$>#4TR -M13:0N8XSM(#)?-+7J+,GV57+QZ)5ACA=J_NT:@+#?<"VL?)C2UT/OH7+#1S& -MM;8NL/=D5V?D9_EF"B.Z*::4N`XM8)Y+LR>!;"!H191R@;[$`J[R,]2GY7/@ -MHE:[0X7`!84M]1>7EC1Q77[VS0RL`IXMY!'2SX[-(=X-%#8EW=7EJ\_Q=FOI -M.9KK/8HDR1BTQ**K_"!W[9`BQ<#]^^^)3BY(^UA0^2"G+K@$'!/7/X[O]']H -MXA5>:5,#T>)UK6B,#=[;-<'/SW>;%8ZV/QH#<$NAW0S&`-CDS4BOG470SIAP -MM+UKEZ0?UP-VY5YL?>N_G1[ZCA9KAM<2K!<0M)M_@EDMB0")""NW!T@+J/L^ -M*S>:/P>\W;^^KX,-JE9KD![96B934_=K`Z!LM>W)BI[K:NHNE+$JMA):<(@> -MN!:[]+Y1:L4GS"6:,-\/AIKN,X&T_5'LG3/F6RK7MAR6_8*0(7R7J+.J8 -M6/$/(Y@61'KA-E8]PF-'44#W*=(NLT;$!0-KG,1+8=(`BX+:&=D7*GT4F7!* -M#VC11&%_ADHAK]T"=C!)F[:?=\6.L>6A11#Z9PQ=4Z%2.0_L26_PO1`77$F3&=9$ -MQOI&ZD3R=:]/B(@]/@<\84::"Z-6^+^ZC0,4%=SJ_RQF*-">I5%2E>.FJ)&T.OT>TM,H#)J^V46I@VQTUHHO=-"$GK,0I^ -M[37[85\+*#8A-1VQFF$[J42UDS@TDRYX&)_TJ'@4-#^>@XC-GQJQ%[HV*!'4 -MJ+9=/$3I9(`'G:(;C'3WF=$'I9X%L2G_89SK:$W@MY7<2.&F7XT)@(D..DYG -M]1!3JK"KC]NU]RV7^G;Y3'IWL1.QP/5]T#!U)2/,H]/=5?:&QY!#I9']'7/' -M\?#))?\`434)Z:!E43XX,JDW$[K;^`S:)B^$3+9IA5ZS&6;MG,]C%F8<27#MA&FM?<5$&(' -M"6PR*[VS*B<923W0\UK^(;B1`S?THIS0;Y&G*I_3>1JIMP9-U]6GI_UCSX6K -M%N8I?MJ.%$Y\3N]$#P/\F&Z9"Z`=MCYZ[FP3$A7^'MN@F]/^.&H:$; -M]FS\>L8,L('[34/Z"@6R^L[+2$7$;ZH$]=7 -MG<2D^=&V/^LTDX2`(?/1JH`=O%SUO06B#/M7%KI#NF4 -MVM#WM[5A.>/*,@6C_#@Q2T^B%BX!38@*^8ND9.0ED!^2:V1\1:W -M7/M2)!K5+#7&LY"/K.4;2:^)+A:*KM0?"K'3^Z9!=FDE5H4[__[?=Q'M0E-! -MO5K!MN9$XI&[_ZCCSPO;T-(+\../IV0 -M5NBB8:%3S&@(QL\JLV<"$@-SFON@4$U_:>M:#+V?)' -MQ%147.'`TZ3;KIS^//0FQU$7#EU^Y/]3L8`)S/,]YOT9SS4\G05S/CT%U1$H -MU0"<8IJFM9.FYPU@^ZG7X#0SNJ7&V7"_M]T;U5K_$*,@"6^,'FX7R'IJYGV0 -MM@'C6BH(^7K+&PKYTV>MO6>-+[H"?HL&^$!$JP.K!]NULIRP(MWQ"N.811U! -M`_3,W!#7&V+J=_/AG_%U,CU]I^+^1!Z=8=0@W;,P84$#P7JKG0(/VG&8&0Y= -MTUHK3N[?TW"\61BC#5Y3NQBW8KWGTY>N#?!HRKV'Z -MFN1LRP0'/2&B7UE8E=AAO,;OXH( -M$Y^U9RK(`29K-\#X,.^7A-.AZDP:A='\:Z-%=6KQWG%Q-ZBE6`:O$WO@J3L8 -MZS;==A=BHE84"`HQ]="FL<7V<)&<^C8!H9H;5F52634\&V]CA9@[H?$_+\=E -M21^.X=LAL0#%H$NK=?_EF.#7_VVH^KRK4_<==?B;+Z=RVN]$B;E^)HTN%;IA -MF2%4+S:2K@8Y^]%U\L!ZHNDVL?JUR78`ZVU-S/B)3!M+&N*TZIL5D:9 -M`UZW@S%5IU$*=YYEQDOCE?_6P+U\[1?P_>%^U]N=/TAM#R>133T!KBQLF1"K -MCJO#J;O(=O]M8YRJ7I?Z!GUT2A(W.P!I&.[=YGI;L;LP_A0O\>7PG7(G.>9\0X%/D[9D4GT]AD*^UO>_4JP.22FQN&\E/-!O;4E7/WPP*GH'A[J/)(R)`H(">I;_-J.<.J -M5`?!ZLU"AH4Y;;SP!_FB^]>><9^8B'&*49XWI,XWO2R"8^XO%)N)H,.=Y*;9 -M^@O$?":OZUY3D_VFZ<*+>>CF.MQ!7M`!3G$+#-R@N"1$"NB2#JUMW-[&6IYU -M*O24C]L,O=O6\8=1I20YU1?KA;5`VE4:-W>& -M?AZUNK+1Z2?AH^*((U)8+&K6.(_K'22!S+[4':0`Z!"Y*E9'BY4C*ZBH+"F8 -MW?>)Z];_J`OV8"J:MPE2C;`4$3)0=E0?YKP=LI6[PPJS[]^)/OY7\.]&F,9U -M*0#Z)DDS]$>60#[-C*ST%",N1*$SR&R>=`37/<0]9NVR55,EIUT40#8><*&G -MP]GY[J@-6*C_"&'I?&.UA"O8=1WA,Q^+34I-0)8'8YLPK9\R%[$;D')-V&=5 -MX+(91.RI\1]O'12L>;!-%,NC("2.Y7]%-;SHL3=D063C7<0T_T6W./3_^#+U -M"I)MXH5`PYE-51,B(-91XSTA'Q3I;@*863`%'G+ST9;3AMC8I)9^C\3F*14U -M:.6L'NHFX:>XBX0\HE4:1\$UG&NUZ$*J$!1QYA7>&^` -MDU1VB!B3^`3U+`T7/_0N9B0OI?\SR8++H?QIR(&YPALLN1Q/FO2-ML03.:X0 -MIYT3$G"'&9X0"7H2'11G;/X(KK;:7=?0*$9B9.>G8Q8L];%5WV"4$Q-U%(BM -MNOLU4?.V$5*T<9QW?A3)/@N# -MXH!)R!,V>)ICDF=$N>P[-R)2,/93D_!`%0:W`87X\](`>=+G!O1HDH,WN`YI -MC[9TMA,C6,13:*OELO^_WXSV!8CK$E[AE9.;D6A-J$=JR["[GQG^\G/N9(59 -MJ4VTV=S7I9="WS<\#8UWZSNA@"K>9P)+93[B7CUE7M7X:8"[3D)4G18='G:] -MJX+[F8JDL.O)99B8HH36S0O6<+'ZD0;9QW\$Z6;);XA>>X"`A.=W(,@'#(`@ -MP4YO1%^P;50'6P5 -M9@63N4\11OM5Q]V7S:%6Y; -M=-0L3G3>1\V3%-3X/YJ9N+RCF+85,P%JBD``^`&3NAX1JQ3?HL4<+#QOFMI` -M$.0!<"P6$`393G=%J_RW1!@#$LT]<,WOXAKEUYV(+\Y, -M(30VG*9!4*=:M)C>O4XP(H_S/77(&9_*_H1YAG`NJ<07,%/\4?J&M`I\PM?Z -MSJ*U&\GD]/C3L?UA!T!+&1G1!(OPS=G*M;40)%(E-C@Y/VU%O'S63"1!] -M"=+'/C',J"&\^,],M.X.K!7\GA<*7X=8#59HLZQH-O5'76`2DXC>[LL[2G0M -M5LJL;AR"$^(C@"\HUM`G%5':(5/F;.+=+-_IMLL+GMWS&N5B(,/L5$2?;#34 -M/^NZ8U)=X>=[\'@(=UT)(F3':9G;X]T$'Q3%`K^=\[ZE/;?:DB_0+M[`NJ2<18'"P!*H.F:^&7F%NF_KW"!(UEGQ;>VB=R+/]K\90/WT4;/-HEI5"E:HL%B0A\7B^ -M.[Z20U`=1=3R-2O[F\^*[;?EAK:76#/]`$[J)8Y2NZI:.,$CF<'1W79[TL?S -M#71(76[23/V4VT[A,":.,1_":`S_D-3>11+19[I>DE -MQS<_!WOT\6ZU9$&?9":Q"+D$NC7B8K2(S,)5S3/<>A]T%^7+1X#*BSLJX-QB -M)HR842HTYX+RA7F8%C>V.DW)!.R0F!>9*/UZ%-EPN=NKIRU3=>,0I9>[:&QG -MRF]!]3_8'^&E^2%'FT0OE!17*`Y'&:>W*I),=Z_DKN`)>EM(QW2\X5HTW,C/J)L`HVS"B"6R)]NB>V+50: -ML96=SSXC&JPSU.+1D[DF0<5E?9/.H, -M=;RK4$1A.UV78HF -M5:_E9GBS9!(:$`9V!K!Z7U6:]HO:\.0KCZ0GM3;(/#->W0J<7V^=]U++Q[(, -M;9,'O>]2]U^Y68"9IL>VL.A"C:/C@@PFL/LL=B*\A"8$@2L!+7!VOD3_E)>4 -M?3@]I@ -M#!;=BV&&``:J4\FJ"C3Y_Z_@$AVY[P>@3=SE+) -M>7\+VF\T%%GA&5Y;2DQPAKH;&7-HYHB)^NU*X&(%5"3:;LQ5'.L][2+M^3*F -MGTIL%K:*20-A]KAM\.S\Z[KC(P%N#G/J^)'M"2`?7!%I?XHFG+:-5^H,!F8X -M)]JH0'_$@<,3Z@*O-)*1AQ7COZUIJ)SAKDA!1JV_>"-._@5T[A1A!N@"YSXM9%0S#1Z6R;>2.7-;6D@1R0($ -M=(V]T3C+1Q)('/+]LSOH//D-]3SH838;&[[#(RQLKC[1QB7L-^Y=X,`=<0OQ -MJYA'SV'6[DKV01B*9(]Y9,0?8"2*] -M;<6_!WW($?NM20@A.)TJ&$O`6OT\I#&1GETL?ZX?(/RX26^&O5SQC2?<8-%[ -M4SS&6QBLMQ4=!8VA>4I"V?3A/G$J&G'3(>'1>("#'_V9JXPLG,MQKV9>`'?L -M"`/M#8*9Z+$XFP1+9/.AWM-">4+X0>:C]_KE^(D$LK["C_,&$J,6#A4@1Y^+ -M%R)8JUPS^-IGYC(L8::/!`X77:)RB'N?PO.?&BI5RFXQX\):/?%$TYS4TVPY -M,G?L$&L0X!"T>3O(L&*8L[9LEDF2>S(/17L4 -M<%89&G+N))LL8:DU>Z9TZ8+HAS>G:4!R;\%5BGV/V`'@X5OT,Z3/_*?+KPPH -MK^R_KPMOH!%*.LXZ2VJY>K).:H>DRI6(Z[#)@.+9XLY99O4WWX7@G8X7BO?Q -MSKPA%[4'/CI4?\*Z7K8[*>&:]CAD`WR>R*!^&/URA!AGB -M*2HY!PLIA"4U:'YI:*U']NRZ5[N*N`>'-"78'>S6S6%9%;G2*A/2IHB_?::4 -MKCQRZP8]37:&TS[LM%+RTH@E\FLBWF^^`XON'_B94K'E%V\1IB@'(/$D<;@+ -MXVYO^-`]GN`6:$X,INXFR'RFUFS@UL)A9:)`<7%,0\SQ(^Q%R`8FI]?\V3:! -ME]^1O-OS8!O;XCZM>3+.MI^%&`)5Z[3:."NE[NV<#M[+U7[`0T11_C4"/!S: -MOB(;PJ`"N06F6LVC0R>A(Q -M%)WXH6T`0Y]@;X/N>TCTL7^*V(:-24`Y?R- -M02TS@F(GM^@XR=(HDDO6NGPQA`MC+A@M>&`!$/[A(6>T5[P!!%0?X_RL;[A_ -M6ZU%$+#?O^"0^Q\1>\NM2Z+1C0S;DRS&3#A*P`D','GND9?O'*/KBD>RD=-S -MP4RB3I#O`&"UBQ_4*!`%H;28J,,H_ST"^'Z_1"X7B(*BB -MF%QS+P\*83@-U1DAA.&G^>]N[1/R?=^[#WY-@[G8]T5,`/RBAO+P.J46F834 -M_J:>X\_J=G#I('U"X5PJY_+E^_N7&P$1M8D>^Z=K4",R(7:R['H<,TQK[F^- -MZ.:'6/,1Y/-2?ZYIIY!SE*]]XYV92RJC%)G&=USD6^3R.SM)!4=8[F'$OL&* -M?LK+59S3>=D-7DKG4*/;P$0;!,-JF_\6C5:`6 -M!N^2FW$27F]F90,TC@#E6$""\!V-&9\.$?E='4PY1,S>'Y7L*`(GCKG_Y"SA -M'K@=F`%&\PO,Y,?X6[77X\1@E3KX0'7^F%=&KI18`Y)8TX(%3E($S[76W2]] -M"F;*@(>(#+R"2(T!BDTKZ)?9G5I4(>3Y+W@0LV1E%?V_9?EWOU*FSV7H[I*N -MJIU%0_)9AUY8QD+W7)^K$Q;T1P]-J;B9,BFE_:%N&NGW3_.+$JOX@,L[?!#/ -MXEV4WMFVH%$,(S_&D'O3TJ3P+"N,""`4UTT)WNIY=8M8EY`=VDZV6E%4#;J# -M_)6^11;NVJCB4ZP--:=S#9TH?;,UD&.4H+;K8)PW('`R0V+/2O"J"<$NY>Z1 -M=@DP2M!XWM2$S[E3R6+OB#2!'4ZJ8'T<"+BN$FZ?>:\H6V)EQ*S,;WG26WQ: -M<9O.TZ$F2?>?!2L/$(>VQ9#>>6GLL_5KW:T7YB]US4`)_YQB"JDGYGWFFRI@ -M9-VU$2G.56@+6EG+W>U@)1@[0%@(!ETB)NEL*7T-45LJ@+4DF)AF4N=JS)& -MXF_RIZ=[,%^*#YH-DU?3B>)RQA"D*B9Y"=/5`P=V6I%\H)8IBL6_E%:\F`]1"/ -M>E;('U0&&'`@=CTX9 -M[W[:E1X6ZPW0E2+I4-*8'ER)1P\$6\X?P)WD]2F*R[7'?L%9(/JG31,"2,H, -M)FJ#YU"Q.+A:^1"Z,.D%2>6$YP?&MY])XH*W5=ILL3Q]"^[J$;RGA06OQQ^K -M6*9*9L%XN"5.8Q-ZEQ57FQBSZ87*Q-"-:G3N$^6M,W/.P2#6YX%MY`/B4$A^ -MPS[:?J?O91NE>(BF4]5Y*IKFN%-MJ$'-N`S\!"AG0Y27@#--]VV.W^EM\H!? -M(W[DUF1=B[++=,4H[)SKKA,)LF",AAB5?]0[;A09:@/?J6%&QVLG:7VIB[?# -M2?\T5ZUK<<#[3]29-+I61@)(PT"&5G!>8UEG:I_;[6=`ILNVQ04/=!0D;%5N -MES2Q=>V*?)Q:0COFU80R`.Z7S+"X/UF/O=GSJ:"$C0(>E"5[75#3IO<['"MN -M(K+Q,9CTSP-<9&/J%X -M7U=!Q<7+K#VE0'^84PC&C=-KEFVXZ@J/&"-$]=5":'=LJ"T<&+G,;9'+Q@Y* -M6LJO644#3<$,L#]DHT+3!#&MHV[ -MA;EL,]O2$&J4'CQ7\)EFTI\T?C@&*T$C;84&?0NCT)R4;YJ`HMX0?X23)RI: -MWE-(=L3R&3]-<$G831U*-N*\KO"#?VF!05,"$*W_)`@K8AK]QL^,#/#CT5MN -M^)=SH+-_"*14`G3`O9D;GOVC3/`]9F>2%J<;TQR"H,R7GQC(VU%V.&Q*=K.( -M(@''%7@OO7V/TR[SMY+7G_P(W^*%-S=-TB(0V\M=]%T&Y2TJGLF -M+UT8-1OV4_=/F]C^RNL6(BSVYXZ?VCO:E9I8?.@TAJ$>*L/^A+3&7'P7[H74 -MC.9D)]9S5$"5=8U_&B>0U^\]2[1;H&F@DI#T%65:#M, -M=3^XM6.\:3_?Z^7/Y6J;TPE0[);GU`4OG'C5*(@_:7RF2-;&!27,WW>V=0!Y -M6F1HNAA#B*V^#Z.N50(P)X:"^=;^J28QNTUBWIE$"?"U6!,/6FO")),1\#PW -M=!_2^V-AS(L,<:^%DFY;C4I0#LT!_OZ(">Z!!#IK@OQ2\1?X1NXD_D\\?:_Q -MZ+2*E9-^82NJP.QR!T/5E#S2/L`*U@E$<5*AU>SSAU794Q5=1('T>D8^_,K- -MX@>(2YO$HPD;,[,%SKO9M;K'T2?#LN1QC-[Y45U=4?-=!&^AP.=`(A+P$.K# -M.Z;SB_8E/B>W@UL+@5P7;=:_"@BIF)84,R](!&%Y56GKA1IR]@CM+4J<+VZ" -MVG6D\%>%D(T\O!G#W@$@`/U:.PO.U2"%#^!.NQ:*PGU?$/>FTD/PP[M\33J< -M'$G!;W4HWHIN*-CP&7&6*)I6N97(\18G3"2T9@X&+6PTX7#RWSA3$$B7PA)Z -MI%1<,8N?;Z3$.,_MAC5+CW"8WL8W>E<*BZ"+,9'C+DN_(4W>,H8PW$0FIO]2 -MFB&D$EO=\THOTQ'9H[[1*6Y?!Z@JJ9%QZ>9ZW^$S8DIU!7T:ML#;`C[KQPVM -MMCR7]7B'V0#)IC#/M&.D)_X$;%]Y0!_&8-HN1X(*O8J=.ADA-)%X%:(9TL"= -M6?0"R!(3CZ>:5SUQR!7DRH71$QL&"CS%6^"EAR1KPB\GV60LY"2CJCUU6YQB -MRC.L#_S[3BF^E43D>A^X*`V@D'018Y[CZ9V-`D-%Q;_/&#B*RJ#PWAE6OWK# -MVHLI!MI!.7XC+8!&ZJ;LA(^9^R=_X6CW#\?RLX*:]JYUV4@Z? -M?.U=:0<;[RRP"V0*R*5,R*$SU!T][2*??F0?'-'OYJBL_9>G,;T8`*&9 -MO'X:(9OR-.MW<#T>4S[_+<-IKT8U8^IPIS>KJ$2P]+P^Y/[]:8&Y--K\BMW4 -M!-?GR6A&;?KU;O5<")$*?D0=F@"PCJ=.=]_J,W?8.V.NZUMTCKBOFI3&L]5M -ME.2]4<1R=V#5'[2!>M-"&,=_&$67K,4:K<0#\V'6E'=O?[+N1*&5\H\%XT+) -M;_*F#_]#IT[$W;^:9J%24LW;I:>>4\6X$R0B8U9MG\X[BN-VHG5@S2Y"9EU4 -M6KX:Q(IY62`F`4"3WQ,&R-(3J9)-NLU6?IBB(L0S&&4O__[&KY>RD.!L]?%U6E5I*XX35:/.0;/1R8]>UCWT -M_Z'I!1+:76QW;[/,/KZ[D:S.)NC.02N@A^9\F#Z63[0(]FYQN#HQB`JMU&I< -M'*6!N.)EIC`J-CW!Q4,%MJ\&],L!/(BM4]K$\!?G/&,P@AHIP#5IN_F^JRD, -MB^;)ET:A77NY;Q*09&Q&:RL^W4>Y[%L2*`1-_9TGTJ-6D']CVW9:@5Q>#\?S!8:L3E-F-U$X:&)X\Z>'(&XJPNYF0V.BBK -M"U<\*/K5Z-$ZT2>4V4&3!SA[[O)S9??L&5XP-I6M#2&MU0=7VZ$@MI+;F$(( -MOOH0VZWY5/]'A'9[!AFW7,&9WW8C^@IL<(63X>8D#'KU4*WYUP>3@&I"N7'F -MQT.I*+!22V2)]4?X0(=/$15\,WEO$ZB8]GJ -M$BXI#PNFBK`W@>/[F,CO>$%1&'W5C.[H>TWX[*R[S_FR68_2WA,/-68SRP$8!9$GR.SBW)/'?<,:Z=5 -M)+L_1;NS-L16$?@^W5/9R&$(6:ZGGJ6J`FI7NL''?H0?BK3.8K,3U1SM@Y]T$!H,KJ%R$<#2AF5N-U"`9 -M;DATB,&&!"GHIR>^26T3T=HA257.[ZA -ML$#:F6]Q@%.[/.BJX6:_0`DZ49E/\NMHUV:T]=*F;(#%@2[#'8\"?_7ZH];# -M-7(W`@5-D2V8FCD2P/P+3K5#&T"FZXK$I_C!7`/JER<2RB>7^.6#\'N/24E/ -M-W;7.U*F$3+^'5([RE1EA8^$L-998:5) -MOYX?<'C<>!66BEI5%((=%3P4`__<_A6&&*`,M2?@--4S3I%,U,J,9#T=O[Y> -M;W&:@G$9>#[J)_OA$R+(O3;U4 -MG&^-?-2YBR9K^/65U##[JY03%9#>!'H2/A74G!-$]$=;$>_UXZ9B.$5UIQ$D -M."_`<+H]-]S%Q4-!\\5<36!D6A:2.U"0$>GHI#%-]/70D8IDSCTD@&6<6'[8 -MT6Q?:A^3\;:"C;?T[ -MO);*M(52[A-'#N`V(6R&Q*UR*HVT46+Y>Y5PFJ@+Q_BV*Q?WD=1\[&O\`;5T -M`UJPS&K2R"2X%^F7GK^[XI>3XOT/_>FIS!&#-O?\U05-0\FED;5J!>JM)7LK -M8B?VCI(?AN3Q_B9>25@ -MEVINZT!=2109;C2YBP^H2WJC"(LM,UW<%8!XY5<6#F,]G5V -M+54/P2>R*U`_C))M,EMJ2HGHX1]CE?`0[@A,S8K'G-^_5)O+6FL0ZZI^HMMJ -MK=.7"Z@Z9&%Y&H)_[XI<]R1N6=+:TX;N(]5L"50ZB8^;(&_/3`'+#UL[]M3L -MYD%L8LCDO@US4JC53<,?_5-:1C1O`L0.`C4=#$!LD6:4L>C^PI&#T72 -M;%QLP-<>"2Z@[SL_J%'Y]Y$^H\<;_RAOE%FCX"6TL[*FFML_V6DW"DR/Y=*G -MT*\9JO7+YVJ8>/D#?4$\=#TO5JA:41R1FX##^VE:I073)-5H#?#^HAI9?SAH -M:@%NOHD"%`0CP)R+*O;VDTRK3:T/-C[Z`A2M=33EN<4F#V]R&LGPWSJ8)&]? -M=#VCP(.%@]_0("HS:XL`8Y4A,4U15K?-'?\ -MQX=NX0ES\$'6$L*+>RNG6O/:RI^:;Z3V\=26+MO<@BY(4^.`D\P -M`1+Z9_0RL4B!%C2EH4>@@.Q%0'48S[FAB3G]%:C^TPX$YL,!D#$GT^4].-Z? -MLMO;KQG6BRYBNE<&!&I8!E#M1K&D6O1N\Z2P-F5O]CEUOJEJC)(Q[3#:#J5W -M>'GRL16F4$J>9E`WDPNZ%]EQ35R_=>9O%EDFGB&$J9Y2W]K5:5M[_SN4._WP -MOI.'961B6;>YZO0]+6+6W-R&@V=9KN;T:,T7F^_B$.#P&JKP1\*-TH,:' -M4^RA*])JM9YH'HV.$?R`7.9M/^D3H$T("20I+$!B>Z\&G5.8BT$?72*ZI"4V -M`G*Q87%W7;>=G,:V6++,D^KR8C! -MR=,YY7BI2]]0-ID'6->U?=YMF#G9_K!\!'9+:_X7JBO9I/U)3WI\X2N,&=ND -M2LS.O*=@,YT6HQ2E2JIYM]%3[KVMM``,)[K-[JQN3GE@KR'1,%)VMVNJ>*;W -MD=(?`:0M:K0;#=)G(.*HC"?$5)US])!A/)XG7C86HO_.<>1D#/JCAT/G&7[F -M&53S)6Q8T.=!EM_I*XZ0E4P9+<=_SU^JZY8FH^_#3-<\MIZW3XI\;$Z -M,_A<<#>+L]TI,),_R,W_Q4A.`3'P-RZ,0J=((;T(:9?)HP>;%24&P+2]JXUS -M.(ZL$J'X$169M@4DOZUA-XT[DX>HZ-!'CJE6=`!!3?'IV69+X&E'[`1& -M<0[Z`FJ%J@_8U5N&6QUEF/5HVQ7`K,Y8$N@[G[B+'=!)V5G&?J$5TA3H(NPI)!N1^OG"$#M],_'I^HJ01R(GCTX.2)?>]'Q(1UM`6&=!@QV2H<4;<\ZX$+HF1GO)I^&SX/13GB` -MK%%M_:33*^>KA=*Q;.#MOQK/<)D0!S>ZVDU7BM2R#W@S3JZ24.O1),\DPG5CU*"7FL9=LY.LV<\J?ZN+<"CNR8,,->F,@X -M+L'GR`($X2$4[.2Y$#B?O45F>Q/P;Y!.UUGI4A1\ZX)I/U;'2[L%[7?6/=^, -MR+#^2GLMLZ?TA/81H-6@MDT4@BI\L^W'7-X>#6)&5<_7[>%/EEQQW4;S]M.? -MOM_/;G8WBQ7$]REQR:TN4V/KJR%@8\&I"^<739;LP'D,+JOCB;D^!UI9"F'3FC5] -MF\U&SH[,:PU_*D8839;BO)X6I;*B640;1>D]M&:*$OR#46MOR!_Y"K>V9FC%3Y%)@4?) -M@-21U*#P2-[IYR)A`NE>'?>L]K,3)2J":@W1/8*]BN-I)5RMNW,E9#)`P1,, -MZZ6%&R__[UH@DT![$5XB4^R+]SID34[^!8/=`UAZ8/;C"U8!X]Y(7P.HB^:H -MR/K\O.$R9[/O8,MY8.5M:]`;ASE>`N'`\I%>;A;S7U; -M9;.PY4S1/B^F43>V4>W++U;LD;C%L0*P^&]%H_VL-`&[F"O\)J0.Z@"@+L-G -M*!84*HKOT3L*=,9D38P_NU8QO1%,_(]T6+?ZT3GJ:?1I-ZY19+U%C$W+4AT< -M`Z<,.(_X:X=9.?0&]>O/=96;,XOVORZ\B?:BZR$;&GO9H0@@W.3&%.@)#;JU -MTQ'KO'40?)_B1(<+A7[=(Q'!?W%-!'/!E4Y5-W39+FBT<^]URB&`[&2I[24/ -M/RTKJ;U7J8T@6L6+PF5I+]^TLK%KN@+"D$_34$!5E$%#?ZX*PL`."_OI1`S# -M6^08&A,=*0LB$X[_8==1=G#)!\:UB1'UUF -M_(E526KW%Z3%CSO\*AK/\=K(U$/>1=;,/`&P##7#A*-%62.OYGEL4:/1PIN> -M,2N*$?$#>;%B@U`=!(S.&/QE?%\8[(NXD,\99164'[" -MTR*FG$<2XKLUKHND"G>5\!&!]OQ]S2#?,\?X>C^$6B8&1B@J-?ND80?GUUP! -MHE[HRUS;B,FWC3QUWZ'Y+W!LG%O=H[/:D"4(,Z%&Q0DU0:H6)(1)DR=G>C:@ -M:!(>14HZ,O*ULT@(E>IQ"OGZ)MGI3?*!.6P9[KV+O=U2;:L6$:PS@7AJ]B%& -MM5"34?S/!)*C0? -MAARK&Q(H#6-;=>(E-"@F:4IIE"^X#CI*G56P=@.WX;GZXD\RBH3K]J+B!"DU -M!M@W,$K1T/S"_#/7V@@&9/BI<6T0+-'=N*#95,0G7<;LR6&_+$6(WZ?1J7=S` -M5UGGWB3GO^1*8D8E'P#^H?81PWL>+VZ^R%O.OO5RV*4J<@>3?B64RMV@P86I -M_G1/+^?'HB6U;Y0E3<-;M(LNWO@?#_5Z38%+>&HL=@Y/ZL,^HV[%$DD0E4!N -M-#>:1ZUFB]:Z<].JZV)X1X;B-X71A]_:`!L9PW\(>R3/HA'TI*>AR'O2?_AL/7"@\XO4/COQ$8J47X3U%Q`(U'', -M_H63.`"29#Z7U-]<'#%+.B6M9Z?5$"!%`"PTD=>0\@X,\+!+;$9&5[]_BY<) -M8="0=K%O*'QB*%>U9&M*OB76G&(Q$JXL]D2_MM&K>:LMM;LGLIT8^7;<%^3, -M_[!)W]RN`Q1"-]%7D`^Y)#B2?NWQ%=("0MI4 -M80R8^R@[@(MKG6+S:))KY2M(U:FY^$(`4E';H96D8,SF6W*49:1BFLQ)Y<_5 -M+E&VZ#S0O^A:AZ].@:6CH+.`P;D49CQ:37B@I5M@C-$/@L.T_#%$C5OZ.^K- -MMPG]+L6KMS%O**3FCR(U'=+;2PI;WU$;98^R_`0:1'8;%_6B).T@=E<`%YK% -M8JO>:N0QE64TYOX/[L-E!?/J))7WHJ$*$4@CPAKWW_M1"0H\'#P, -MTZ@5O;,+A6.H[L&G4)<5.0GP-[X9WE5G.[NI@]W5]QH;PG@H3R@'!G&]UN'B -MNMX=^I`@[:_S0A$92@ESLJBT''#8C\4![:\!.H-5Q2_(+;W/A``Y$I.#8/SG'X+'`$#2'7#_OWDVYX$^Q/0&N?@KS`O,I""?KP>C"W&T -M78Q\*.A28@=@(1[`?ZGM@&B1@0F6[7JW!2N2S/8Q]U^EBHBG3>+)?A&^S@A@([!E9TT_`5,@EXITG -MES26=772%(1!K;N38&*A8):C)QWAX=-FH-04L%SUDP4[;L#9SG1B*;;]'=T68#0/IJ5S6S,VT]KB -M67?CYA,0ZG6SM:(,F3SC.UK,S"AJ)E=];Q%D5?\(`]!MY1M?2;WV(V@"Y<.PWY;:"/)(HP]ZK&^ -MN)9M1E_16D,$.70Y6??&^+CCG=96R\FZNG"SGT&A)V>%FB]3JU2&GR'=(31C -M>QT\?IPD&'^'=9]>]F0$=!03-8;!?!<'8)A=8>GI![&!8WT]Z8'W!-S1/W2P@(@-3,#G]^O\2]CXMZ4?`_^96AE:U*BC3 -MEIN!&(Z6L\N=\_+;GQ;!]5N[I?U47P=WF\0W?JVK=1]ZH9W@R?@W@>,"J?X9 -MI4PFXE$DDB$<>1J%P8'1$JWE+5N7LF*#0(EP%P^HV7+2J`H+DE/<8>];P#Q% -M$HULIS2W37KQ_G>L*%'L>`H$0')3B5-)J?S'JG9@#^>)(J])EI#;J1+L?W7W -M>`:/>CB_%51CT=]SGQB\-M>S/^/N2&1"^_J:[)P)AT(4AY(Y/X)4VCWX6W.M -M=!MGN[R7K84.>#2`2T3;MOT=.*>#5-8Y`SP4&\4J$LX!1JY"Y&ZOA3,;@=EU -MEAW4`1],P00<3QR*5R(Z*$E,`](2]:*,PMG-8?^8(FZ]R.+:US:-*26U2X:0 -M)+6@PI"B)!(*J)!Y:I5AJN\IN+9D#<%ZQ -MV=:9,L7[0S*!W,C(VFYPA:L75-%I*I"%8MS$@BNTD5`[%#,SYU4?EHSG6+Z# -MZ[O=#FXZ1S0YJ`G:KZ@`=?^LL[QBC_O@R=WZ9&CB$6Q)/'U,;=AZY@AM2/EK -M=)+V;_29:;NQ>5[A;..IRWCX4T6SGF^JN$^PST$8Y2,%W7I\P\W6B,)]9D)B -M?=/N,.["+S4X,`?I\B('"PH/XV305 -MT$0>+03L*TPYMM$>>M-)SM^!N%F>QLK@T%KPNX?\^*==5%>7:<@1KDO[2CFA1K`DIJW;P0 -MI];'S7L#V//"2@T)#0^:ORM"\YK]6T&O&9K;P1:SNW@2&_[8MAM*M@GVOTM: -M?0.7&)KQK>%1E##!R6$O"+0?!HQ94*W7X?7$W5U;N0RG##0K&@.HQ_&\! -M4LI#B)57K?C.Z8AEAUF4A03B/!YG7>[,MX$@:0XO:\- -M4PUK[;XT@R#)Y=Z*=C`4)SKPUV0+9NZE8_HL>PU;HUT$BGV=E[\06V%ZXAFK -ME$%[@@'D#K5SO]"?0$YO3%,$@X)8TP-EY>>_5 -MOC3TD$AK[UOE56P6+EMP_"_ZR=E5CQJI>Q+W6M\-' -M._KKF2<($0Y!U)SW7%0/PHKJ0Q_MC. -MJ=D\095/?"5'@Y-\QQ\@%N<48=%.GH8TOHU*MI.8-9O>ZN;LPU29J7(@74Z&&DD!G@F'\W0 -M7O]T_!"L^6^M--R`UL4?&[55WN\%#!&EN#)$](?9=)%&E,)X/3+!)Y.P!'0ZNG];U4^?_$D9? -M&:=+L7RV<&=D.@@ALIX)YD'`.+R7/;7$/Q1\IKQ_H72-<#D`0A)N%NF,;\A* -MW^,6F0CVD7*,.YESH^%P_=O9*MW!^7XO3\AG1M?>P'AWQ\IT>!4[N4_5DU!1 -M/^?5+-`R3S@G0_8-<0.>"F*\%2BQ@:5X3[N[,>RT%[UUQ8B'V^TP`$RXH0OZ -M>UO'28=O./Q&U-:VHLN`01+^%_[D(0OE&W/9H=V_S=H,$9Q:&Q!4(A3CXP84 -M,:XO2)1\/?()6SOJA^&215TB#"7<1-@&P7_\"UW."FB#V*Y,]J&6_8;GUK"3< -MK!-Z9,M)G\YXY:6JEOS+1:G]P$."?F@PD:L9K^7Z&J;<>9DF5A;U!V5^KWTE -MZ:O3!J`W^>?D#2Q#4B^#8HZ5`JQO;9%"'Q;6)(+OU)!HJ*\SIZ8]?83F7187:4*.X.:S^^!<&QL]H\L= -MM(&XXX$"WA$O\P8F/&(1/.*=;EJP9.]A>@7OU&G8WI#3(O60S0)"(AF_TX3+ -MD\T[Z-D%(,\ZI$0J220GF4T7RW*O;BJLKB1)-#73[](*1[N9H0"F4Y89ECY# -MJNGM$&\(,--$)JY:EW:=`"_VCR!74/H;9W2J&`!,3G\/;CM:*JGHF&?%-'E1 -M=2;86&OCG6E\2I:?-J/\=$'RZT-4/\6E^8[CD.+,)!M"KZ8H!`9LB$E-B?[< -M-2E5^-*C)1Q-1JJ;'?T51[%L0$_K;W[P!@P3SD_TTWGYCT<:TLIK564ME@H;C6,3XD!'9GP:R -MT;>O*C^R)R8K!T!]-4F"IL?NF+DYHEO;C,A@B_Q`!'KA\\5)D4>AW!FX!+[A -MG':0V^MX.N'J=YD$W07-ZI%D'.YG]F8U8CK&;E\OOSVY6TCZ&8"G7`5,!I*?*HU>6LSU'S4;.C&WZ%8SBY76 -MEAWY&O*I;3!('R]WXZ:41'Y\N;\#)P&I<#]QHBO'AGVT2CHD%]U64G=I]T./ -M5$;QAXV"G7*,^^46582'"+A69/XP1M?D;(0'P"^)](9EV,8M[`X7T!XYEK$M -MGT-:P:OV3:A7<<__BQ"9U1P$EL'CS0%36.MF"_^AA:(%TI]*@4&,+V!AU -MU)^S]GO64^^F&NV6;1A6K3G$F(WE"29^_FI?]%<=,S/2?-;J>K@IU -M!(N*Y:<"'H.Z?G%9K*Z'^,W?$GM6O,K>0UZ0.VR)L -M:VW)-82_QV+#7ZV%,XP=U`MR?6DH1BBN(-O1H;74D@` -M(7RF+;+OC_GJ/_TW\LN__<^PE^7ZD2(X1IWP&I%;#%^4=/VG_G6/@2@#,5N0 -M_[L/__0XC*K2/&G&2T.X\HI93; -MAJR!C?>((RV?Z:RE*VUP=Z,*Z9W2"D5#JL1*>?$U-C/ZWI?C -MN`TIZ&FY0&:>UMV;F["+00(X0]3+QZO6[0+QJJ>[]V>:[#*_L\=%J?&(862<"]ZR0 -M=AYVR!OS]Z&.NVV(B;7H>U#6?N6^H21>MKL\86<>"@]^?Q!(]?^8_FFB:YW! -M$L2]JII@M:O48,(^>J3]`9Y+YZ;U5B5,&WI:-;`V94L92M5XT&#M%\..OG[$(-0(6LK[P]K6('7A% -M%:8*T!.205!G_]MH\`]/4>7#K:YL/K)8[Q^H#I0_Z=5%T2?98/-C9*I(CN3D -MM*=.6D^+]VX2?S$`4M6IZ!FU7"4U.@E&GH[`"98=%`U;EW9"$:=PF!^H?A,+ -MPU^X\/5J4;C(4F6U^8OV^ULK@;62'1XK5U9VI:]+`-8`&>HA!C'B>I[?)T#$ -M>TD.$.E>:&!"NU,).SM],[D6%7@:PR.:4-BB\!":9P[PC`"HBR_L9,UOT%;^ -M.T5";LJ]R)3#H:T#SGT0/^>%/A1`/S0-!EVJ(UK[X3]ZK]3T;@;KGXVNB2Z[WZ^4:Y9L$TJM=D?'HKBZM4<&R4=!N3+9 -M9CXZP1"120#.U*3EC`,_-0!.79&]QKR@Q\.C)QI-M$I'+OR2D@E2`HZ_`/$/ -MQ?U8F=B;/$VVMDZ_H8:7J0H&4;$\?;N5US>FO0._.BZ:! -M5IGGG4&S$>&HX$0$FCI*?MX@&Q=FNI)WGV$)A!K6_II]TL'.:Q`#J)T<"=-> -M83XY5O;>%F/4DZO^Y[ROZESX5^#8 -M%0EV@+.1.#6RK[B&U)F*$KK^+2V8[?=2O)!>^T -M)F&0R>*3<+&G^I>,?!1RYW;?)D56>V80 -MV/&U4YZ_U4B2`-Z]P@1-B6`:HP94B"M3&K*FXRL]75^PC3Z*L@T-'8K4:&R6 -MKBM@76[R,>1NUSE12N*`*0+;:X],4[/G%R;1XL7$]W^&Y9_+3Y01$_B.;F3[ -M/(N4#\)W&8*Q_`)/H9$0U;Y0=PN&"=+3U1^-)_QFN3L3<837F+YJ2 -MROH'XY'[-;U>3];L2>2J7]J.ARG`6">M?\J_U%AJ_GT"R+>\KP%B)CTVO7)N -M].70\XY\#2"6(O[X7P+%D/?:7D.*XSELL"3^UR1_.!0*96"^>G0E%I!GM\8T -M`88T?[VPRU4R76^OS0T"MF=`P!L6>; -MFE):RO?NU.VQC0HD_)2E.\EU8\B=&D+;17.SLFNE515]-4P<1VSR3Z[@XI34 -M0GF(E53X'4V41$TL)7394+&"@%>STK`,7W3R5`>Y`/[&PB-%G:T?9SJ<^5YL -M8*#_VJ"N991L$)5;P]$NS2::;PGFV.?FOX\\*4D1Q3V4^^4R&6S)]GA1[':+ -M3V\[OQ@(!CPNOD#,NR)N2W9=H!@8G^"C0$4*4^)AL%CF8M/3L8U\G<0P -MD&UC,B<;S;^9TKP,SZ0(_Y5GO$[#"4QZI`%8_8D04T[Z\OT479X)9BJ&H*_" -M6>^^3'B#9HCPFI/BZQ7P4N9&74N@K_K],Z,X4T5EIY\S%6=R -ML7`HA':4?"?$=9W\3OM*$$.[%.LERD%&,GH!",(1%MJ*=L&V-5F?UFG=47;* -M0FY&.D_T/Z+CGOI;'#V39+; -M7)H&Z?2_"OF)1\K&O@]IAS'74:QNUGP:^R>N,BUQHZ9FR\'/.2""HDV+/C^B -M!C)KRE#*.S*_[9>NLY"M>1>G!V$\RL?2/\2`ALV"D0S=_J"93`,XOF'K0"W) -M2.2@ZJSR_B0OTS9665(N&7(X\A_#T&+X.7(?F31:E,E#)$!&<\0CA0D;UBCF -MLRFPV1DI?@ED/#P"Z&4L4AR67J/T.MA')(K'^^&R"5D06F*TJ(Y;Q[O9@5NE -M6"+E[ZA@PM+[PW5L^.1%;"'IZGHG(,I92\$9@S?\^FW<+N-))HF&/-Q^5XP' -M+\5:CJ4*8LO0Q9;V%Q5:SY<-^KIOZH[6F0=AQ-4N.4&D-__)( -MU^%-`,S)X1!Z)3*73\`]DR[&FV[70EA\?E46%1[&)0S\N4+8)^%Z1#EN -MFLH9H;)LED,6($2GJW/ED<\Q13_D$W/@\E)%Q#9%7$0MY$'"=<"D)I!**-M( -M6+TXKD_2C>G5?%DQ@_^2M,;&*56!%#K-K)-)]EJFXGH&)HNU;WUL/*S>[Z'4U3U%.?AS=?$$_6O@9N\N[&S@*$137X6'^& -MM3,OK7G>`7]/A;3\3X!W\%_4DGBGLFOM'4H5TQ\_/P1Y4+E[,U$\3 -M8-Y`^@27(K8(0PTU3A&I7F>?/@@@LJ;?)KLR>\N(^(OV/YG>DL6A>:TK2TZ^ -MS*E3:)EC:<&*'/(>U#SEBIGDQ1'3D(]E;VB2V_DW#0B+IVFG!Z\F--JM4>!G -M$P;*$6=>B!R6DZE2"XL$?W3<%L62;XO=TEJ1XI6`K[+3S`;-!^2SH\Q9DUY[=?U[FTWZ'J;3*=H_9?BA3:T?_B*P,*'\?X'\F` -MA<_@Y60'@'*VE;-P>H_%:OMRM0SDX18KA;#-_0-N"C"3\S"(T#X*;/O#O-- -ME?F6)P4#_E<.P!]0^B@JCEL]<@P8N-IY*^Y>:R^L155$0'Q6Q9RI/_%.R[FY -M"$-<55@'2^#AHS#9IK:>P'.P*>L5%`8J3MGWV -MC=1D+=N"SX>*'FFJY4U;(+"P'2NMS0+T*U`V+.<>9)V -M6"1B5TACU-?1EW')H\$=RH;;B9-?F];!8"TGH'UY<\T%_1WZO-RQU:@%A#-( -M]FV8^;'>O\(572^4*M#H\5F^FK)/YJ>JKNF+[;I:4SJ_30&!V#\MVK@'A36/ -MFNL2/8SZ]W`?^8ZID?[H/V".,\!ZCT7TP6WJKHOY/2^"JL_,6R:Q5N -M%`.QKN77-*UK=:;YR+M0*`0*N'>V]8/^;/[`$D'3%JQ%O!0RG[(3JI8H[&>B -MQ+L:[>3F/[NTA*XA_:O_)`0R+8_@0.Y`.BWV#;C<3:YD'Y?/*`]UP2 -M;@,%?H(^]H8%24X)PI\#*M'LKN6;LQ%]2++S5M.F<*(LZ;$HDWFKT/17.1DJ -M!J=$C5U[MSNA1V>;5AM582+)<&.^NPHW]QY+RK9/GFP]^#;L`88:JI>RU7N2U_0Y3 -M^?J/@$N -M;]2CUP_HV:3%^>M2BXM:@;<<(]ZM_6;W0JJA+9&)#S69L*"_NF!8_P/+T\[- -MG%@C:N3&(\`C71\(+#D]J#!GL@N'"E)1;?CQ`WI7CQXL^LZVH@.8JN'`X5?' -M=\0/_[IC9BU/G)68.8O8TXRCZ2J!%X$A)#4O-+W_QXI0"T?"Y`1!#Z+[XLR< -MU%^##\M*817A42S4!F/PK(DM*[JL1M;`96BA]BEG#OYJ6D\SN8L&719\,"RZ -MRU[F4%TT@(ER7^^0&'J(^M"D4Q;6\RK=7?%&3L.Y]5'D_TB4VE0++5MN0_WP%_S@`BX2WGD -MV$16G.B'=XVQ"G+'G('O"CN!I%.#ZCIX=\%'E_>W)8#1]_OX=/Q@ELBH=.M! -MPQ)G6B8L2:+ZP1T?X[/12KF"+G*%Q&L0?.YYI+EJNH13UP:Z;(=+Z7V_2$!! -M%H:Y8DDFECEK4:F!_*UCK\MU4M!BL[-WQ$&4>+%@OKXQNK)48(`.O&CD0"LZ -M2^'K)IXEM^VRRA(U,PV\34#5=_(!>'+KZ4+0?)%\"9[YBCKB_H\:ZGDT -M.>ZB*#ZUN*2(FR"XNY*X!0G8VS0.#@C$DQBC^$C*2X:,\"EWV!VW/N/<3L:1 -M*O;'\?I/"]X0,I:VU"VDTG'7#I?!$$%)5Z$+_\;O*N24-L"H7?S5U[PZWD8' -ML9B7`M$Q^`_P.A!2SLID;6$+[ZN2"4>(BSOG5I-`<`A:SF0IR`6$? -M3NE$3.H@?8N#Z\A7"[G$P8.^71HP1COS!+LR%YZ7DGPYA3D+G5UFZRY0)H+-U:["7ZX4^^@! -M/TSAP63<>,Q;7W^8A.)->C<6`RJET&:6QI%JRR)=2V8KG*]\KLKD$V6DQ7NP -MJRX=\`[[]^K&>ZP0YU9W2"(4],#7JVU9393T,,#%PRH//H.+*8CTO4B,)R'7 -M"D@!&NP,7>J\KY59]J3083XBR22!J@0,M'/L3+A.[HYVK!\X&EVF_H6!-FV5@2V4[HVP+:5;O&>D_*W/DXK%Y#AV -MGN&08Z89D-GSGH(_Q8[G?I#^(6Z,,$4W\BQ=LK[/`T'I3:CURX"[1@?*IQLC -M[QK9B(A-XW+-S"3D=Q8EI;#U/G?]G4?-&2#^8N2`U(\^I&N9P."??$'^ZU+Z -MEUU63.N7-1V&V:L74-`)KY7T]LGZR5C;H$7"!C/D4[8\4!^;GNE0SWIN_`2? -MLV\S$=F;>27RSTW!54KLN42IT\GT0F\(Y03'9-$5YCJ;=FKCN^X(A6H1W!:%H"`;7@-$J&]CE1FH_\EA_6(@5'>L+99Q/2NC,"VTY!Z(Q#1$S-UQ)\ -M8K8G16)R)9$X]#,.2]9X57<WV -M#H]W7G6%,R@=)HU_S:;35T0-Z@`1G`6[YKN.55U#*Y^!/%Q?K<9EA@*&_FLM)1BJ< -MQ@:HU%%@>1)-N!W'^7DM=D'GO;PG5O^,4E_Q0<;31S.?ZE\^#"1.O!.G5"65 -MV_R10[";T]P)J4SV$QAO_>?N*_:O3`R%*A=2J9-N:"),JD>AH$XP05$"LA$%OPSKDFT&YL0G"Q$#L:6$X -MJ(IV<8I3C#NMDU9QR&2?MZ5N!I+]_K3Z0MD*2PKN8[>VS:_>DN.<'KK$%OE&ERTS1L6'!6W -MK&4XA'8):?:"F42'J0K&D9+-"'C*:I5]XK'*F+='M2J`NUVCZW?#Y*."XUZN -MN!"VH77)X_PG#=B,DJ?N^TIQO1%V2JN?+E$!R`MSJ;7C1P/"F?+C;\U -M`[BN4=!5F`TMM+Y0`$)T'=23JT(`4U6$XIQ4SYHRA/O,PY/UA4['_$%AD\_N -M0(U.ZX\7SZ"9CL-:;H_BZ'*`P+%IMOK_?S-.DC<%ZI&7EP8)\4?W&3565R=I"EB[4/ -M#9+G7D,Z.CVR"0B"$ZM9Z&X0`6K0:WTN3[04Y*L:U`?2_>YQ7&Q9)C!C4ZX! -M^4KA76@.E_NIY`<'ZLU>1?+MSKC$XRIN*T[+VC8CA1S[L+F;'V\QG-: -M"D)LJ^'VF(-:!"P=N_-D9F)\O\&>Q?L-+WL^/O6^?[2\*\5+`B`RGATJESAF -MH)`Q7HSE';JOY*3LF+)344\TA9YF!A4GX`C.LXG5A;L$7*4A!0.9D/)X5/PN -MO'8DU`D5`QJQZH")AHPZ_!6J?F=-M&3B#HQ!2)6 -MF'PU9!'_V:0&D4N%YW4T4;'1)90'N1:OJ8'#U_[$`JY$S/"9+LF)%WY)]8V' -M8#0U=Z73:!^TK/'K%V6-:MK[C'B^(O\6U5M!3P`70Y%K&(S'?A9XN;K -M3Q))=98:V%VE:7Y3*_'R\=#A9A$.5NJ+$]!4(!CE'0I\.>F"4J7KFK -M_4Z`:%3"4!ZF8^RU62Y&7C.Y>!$]3Z?42H@"! -MK&BKC#W*]`K_(3-.%$K<+E@GWGO;$F#/U?46_8LIU^ZUV6"OUM04Z9$#Q2ME3)2'.-E,HJ>!0+8+4^=^06B5I#%G4YH/110Z8C?Y[C\@5F/\S< -MBX0G11ER,_=%U[Y(DX(A?S#I_*\IN9-5I`_>?;_PU].7ZC<3IP.5:^2Q3K\LEH4>LG\RH:+H@PT5CAJD?!$S -M9Q=V)L$D@]OF$(P?G2*YC`\RW@@C-]0%K:676LS])-N1K=DNM`U3)FZ*O6`- -M9%2U^QU$G-H]NYE$U@5SJ:,P?A%=HX4%YM9\''9,K`#1_U;0R^(?UE"+?WH3 -M!8H%F=-P>\EEZ18QV>MWJ"EZ]?R/D.>15LS8 -M)+(F%!EWAH^_JA!("@NTC-,B**+]X91JAV!UO\7C[Q`8O&E.6"*GFH.O6(1O -MZ=0D@VWG5I4P=BP?`\\`R\JJ,%(K$^)+GNWN37P,!15;[,>P'#O4\EKJCRD. -M"E*TJF&.ULP]KW!AZ=8G@>Z?"TL5HI6TF[E5W5FTBS\&"#'CVJI`-H?1*X+: -M]D/\S=ECGW"08AA+5/XYL(G3?S(:]*YD?0"(KP3:=U_:@8B;3)N -M'6J":-1]7<>;T)\.[U!R1] -M+>"J9U_HC[@7_S-%L@,K6!U4,SEJXPW1Z$M)_'J6"28YA)#YP%)^'>5`&<5T -MW*KPGCLD/!]FM!&H+CVA<;=3H1$N*<3/!S3=+(2V8&7B,2<_>^"1)?B44X3? -MEE9`Y$A"'*2UL+UU5Z@4J'5W&5SLTS,W&(Z\!6B[/M\][&.P!""4#Q*^64^P -MN@;X0?H^4-!SWP[E-4PP*70W]"%I-T1-("V>*!N;("%4DGI538.#?8$>T=DU -M=E*:/\]4R^\EK@$EC(6@_NCP,20RI=W"C$S2 -MS[R\)9#)",?##"@S4NS!P.>@4!@9Q"_$%,XQ-)&UAP'X4%6V,Q[I -M"P5*4;(`1G$$MRA*A>!<$=^[S+V>,7>T.P-"1J!Z!-3@B$ -M/^ZYY;*TJ#KH*T.R*"&)!J@F*[B`<8@,QWF)7E%QN/*M=75#/3#A2_C,])'2 -MKWWAFGGV;)OIRWQB`FQ5MI(X,IP\N5.=30,=$R@C:E;WFW\0J*(,A;>]PXC' -M?Q$?*G[:AO*3UXH@E`!#EMT$:%VER8'(_Y,;`-:VC&QYX0[7TN@++_I87SBO -MVU%$C54`T7G9[YY+:$%#_"FDVM:]JBC),Y^"7W!?FQ`4B^7@B0"1;.Q4QV[0 -MUD9VJ;:V1?<(O7BT`P,TWNP"^U@WQ70Q/1P_8.ITI<=/5TDQ(@6] -M\`/!WE[MWW<$@0_=.LM]_WW263&,GBD#TO$+A_XV0T2<2I>+*E.;:_\AO_YL -MA%&!NOC[KOS,V,ZP5&S'P1>DNRH#B?C+=-E8J&!4&Y+U%0<\HZ`S$JW[)!-$ -MLX.'N+KS2JA#2%='SG1DAH*;3$TU"T2B-B`V5^>ZTWUQ42F?ZA*@TCL)I?C/ -MHLXXZA.UVP:2V,4;/?V."'4R*LT]4F:3/FRQ@3R^)7:]OU4F$-$QJ3B`G[X3 -M2$*<6%^<^JZ/MTW09Y_ATR$!BTQ?^T[/%1J4G7JH&?WL9`LH?E^^\Y_::%M7 -M*KT#LK?[,%WB\B;T%'$+K1-0@7-2LFK%.YYHPH'.CXOKQ`"L@A%RO,!AANE2 -M;YB'VZQ$SK7])3A$<&S.!LF:74)`]7!JVNT#'54>]);+4^JP=6#0G_^:XL9/ -M3[@^J`=_/?9O?'Z7HV0!L/S@^H1Q9[8/!3XWQ.6!H-H -M[R4NEYA]G+!46@E!&CY)']KXE.*;HT_N`1]@#.%J"O_BUSJ1BD#@*I!!4_G( -MR5!'TXLHLXD]N?H.O6K##S.Y_G;R%F%1C<2`-, -MJU]A:YKM+@#R0:\K"MV^R>EMM@&CKD'J'!K@7,*NG1_!H_TWU8_R?I5R6!5` -M,#)K934)J2U<-T:]U@1Q/[V+@I-$X:@#3*P;H[$OPK;OX@9$*%U29[;??$-@ -M>TCJ%_AC=%N]?VTZ>4`ID#3YF\^LBF'HAG_,Y;=IW9'O -M42<16E#YX_RB>J(@LOX'L>O9&UBSQ_F72=>1)%[XQK(RC1&52`W -M>0\%4_TC(:XL6$ARZJ28:#.E>]BZL'?1EM>CN -MVG2-['X#F$XZI'@-!:= -MV#IV$G)8`-*GC@^)")TI^+?\A%^EXK6FQWQ`7F#_V2_$6`Z&1F&19[G$0&10 -MYV.>K`4%UL1X'V^M'$PP\7+?"O[X'AZP'8Z)W'BF+5XI^!RNRPE5\'T&\K[E -MC<25'.D):!>T9%E4MKL@A^E#DO7$%E+DYU"/GG4++ZJYY?L'NOVSN[O`KBK- -M"7#6C&9:YN*+;S-NPU+-^S`71.?/-H$'/D2(&]*"#MZDK,.T5@N'CK'4D\Z. -MYRX*S1`;.88&T@T$SM_6E37.;H'/OB9D8;-'J:>Z(G&+D&&0OHY0NG*!_3K-KBV#!_$`%NJ]LZJ -M6[36E:&K`S2?[W'&K?5.6X"_.>/80YGYT]"6UOTA(KIY$Y;3$]=?*&2M7?$EPK;3 -M9M*[_*\IB/C%-M923#C_-PZ4N06@'@2?ED:(XUX;FE,B"I96F`;[2HB.&0R. -MQ#R4H,@A&(->33*#RECKZ-F5OD;SN.XV1)[GT#KYK^^/5Q?CYQ>5&NS[9)"C -MKPCH0[F1OVO*3]60Q_/9V>PS3M^8D+"GN9=819/%JA"KCC?)H)B"K"W56P9[ -MF=..`9VZ4*3AF"L5>J'CTVPWCS1S-,TLR[DU:"=?WB!&1@P>+"[ZS,Z/*$C> -M5RF#`[S!@U.?Z2C!P,?(-YTO33_5C.7O/MKZB=$2\<`8D`7-Q0@/?3?!``]* -MVM;CA![67[0"52RV?BXY%/_/[COSOT3>&L9(*V[P4A=<1`]IH@7"ZX3G?3L9$CX)J_K53+E-()4J@7L0O4=M4J6)6YI\H:Y7X4R -M$!+TK!WI4]K&+%6@J$H'$63"#C91:90_&&:K'J;IXJ$$#R4*$T(C%\[=)@D; -MPOII0>EA"""3]^'JTJPI1#!!3@*SC)S,W?A3=_0VN:00#4<$3[6F,X%]ZW?7 -M36T`!SK#O5*A!B0-J_*?C%.9;,.#E^XF']F#@D$2BOSU-<0CZK+D)0;[*-#[LI9 -M:_!6]UGLPUGO*WXR5)6QNSI_WB[1;G5%CTVO)^>_^?4^CGKD2D/X]HQ^<)ZTOQ\NRP -MJN^_%<<]+-G+[610[%P-SS>4<,!CF:'.N^H"/3?2FE<0>[%BR%Z?3L%S^Z"] -MD/C@>IPR$1PIO0M#)BG8#?L4,E_#:>ATB::09[XYK:U[YHOUE&Z>5^M!TX<) -M8D_R*E'_^])`;C%3_O=7U!!IE)__QX;)J>W#Z`BF:6?B)A=?UY2V$!&<$E*7 -M\JN>7$DM[J-1:*40>$9IJJ.#MZP!LK2*\.;2&D??V`WLDDV>IEN%F?^,&()@ -M9;KC`J]87(7P65<"8]UYM_UDDZ2,XR,R5^8/Y,FB*4H1Q''FW@AXM2O4)Z<0"[LNPY?3XIUP*->` -M+F6O,M1BAMR<,70YIW7Y'LH&D16*@%6BNF?TE-9:I-LVQ^-0'(JL0"\XYX!+ -M6OT9R,2E.R,96<`,32.@-?YX!\Y4_T*?N0,Y,WR:MO<9JYD("D"-06!4+A!*SKA6;]0\[,'DL!;.:Q/]HPF:.$' -M*3D]B4:M+>@(+_3`UQJ9'7L5"O%\I,U!P6,6S_#@O-*`3;> -MT#MIW%,B(,;K58)K<-_BK4>=],3GR=U=MC!5&#Y?(FA7UE,X"]$N#C0WRS-Q -MOEN^3M[N]=:J'RVB)3[`RF\6"Q:&$HUK<4B,P.-JFN&++#TB -MDW#FN'Y8QX+_%TO.C9USPN=(G+VX6/#Z4:T2#P6X$JC]4.&@$<_[9VW?Q9?L -MUPT(3TJ?&L.I)KY]6QX=*5NHHWB3^MPKIBJV-`KMQ!S0CW+3Z3I1-!P9J.G* -M(%0ZKRA+`+G^MT,\XPWP@S`6)=GF,/T3(":-'R`XM&P,:4?_P4USQOXKAM/; -MOBG6

    \\`3[L6VCS#X -M"=JE+5/P=K?G'(WXI>>,CGZH$]]$1*ZBI4@'UQ+:$213LT?>D'1N^,A>YC7K -MO*CPQL:L96`LJKDLHZ0#?:7"P%>$Y$LJD`V+HK94!YO%JT>AZHU(1S -MXFY+@N'GAQ6+TJR`#.^?8:\0YA4XSE"-I(04?U>JDS4V[?C\)68F?NTR.+4E -M%;AKUR9B\.``]-=!3J&==2QD4J2"%<%9[5A_C#3&.604RXV+5MX<1HUURT<7 -MCC9GR:CQ_8#=FABQ&PRZRT5R(U(T!WL^>Y#MX7#!C;FT&*NDA]>:5&NEF.%T -M@7:5"_IV'NV<],@`[#VP`_DR#3^<:K%WTRKG"]:92D9IBV&K';KMO5=D_^G* -M("2CB*:SR+\.^;6Z(HH$[[&7E8E*B%\`)!.;G%N2?^[;D?G-Z\JN3,:@*LM7 -MFNQ6JRZ`0=L%"/I]>2866IW=UX$20YV2"6^>$]<&@D8O'HV$"Q6=SC%%,]O9 -M%-5.?5FUX5KI)Q\;GD?PL!]J2[XF1>";(95$QM[$$-U=8W5A+V(^.'$S;X(X -M("F5)O`;#=Y%Z1CLZE)_&1E`253,>YFI=TK=+0O>(;:T<$_$+E,J10N`A_<- -M")%BSOP4>NLJT[S?QK^*RL=WG&^)@OBTL6+KI^\(+V'*[96MV*G6,*I`_-MY$7)PN@#VE?/A!S^"6N'2QDDD5\3/?C0PV]>I -M0052D8UH7^D]V2EY_S2'FE=_[O_-$^TX!=5>MDPDN[]-)F=&VM/:-1J6,(Y2 -M_4O1,O2CW5_'\2'*T)F`['D/1BJ'LXE4L=T4%69&=XR-.HF2V2%ZB(>3<@`^ -MW7=I@;LM__IWK:!-!(/&"%YW%6\2,C8.!B@L:Q5?=JX^PY/>5W$1N%R@GYGK -M6!Z6;%4FIL"S,>?M>X4N#F2#@<-9;-<$>\]7`8;ROZ<._1;Y@.J/2=P__T]/ -M!UKBP9P38(6_*%(,!Y8UM1X%.X`$_\\W''16E"YBG7^..C"18^24$A0;.8S> -MV61Q-^00(@^N"ZTBLC(#397RSRK/>?U+?,/*[#]'@.!\?$::W+<4HT;`5!;# -MS$O_18&ECA6/#F--_&"ECFR9&@*FLJAOZ@P@H-[^X& -M)IV*ER-W)\Q*G![C\"+J.^LAO5AV\;S06F#6D1'_N>MO>#A_*V,@NFBIA@#3 -MN5S%U:LE1;`(VI61W?HQH\+F,WWMF#E78+$US99;I-J80H/%V-))@ZY\I_+^V<#%:JC-Q3+6JZ,1%%'#]-=(3,[5VP%J0:B) -M@!'<\04Z]'0?,S8PS4=.#X^N>_F/13P%+JC/*9%(*C%T)B>PJM!F9URK+93N -M_SIL)K0XGJ'E"9GBP_BO^)Q=?:?'W%<,_0BYHM5%*>MBG^A4)%/]O$ON6)Z< -M5A\D''7[$-)L.FO17AK5Z!6;\)186@+]KCFQL9\2#39&^)+X[C -M;76V7.X$L]ZA/5<^@GQ7>V26R+HHXE+".SSI`ZG`D*N)W/,N8"[\W*MG]_14 -M:-G#'L?O9QXP_SJ[U':O+Z5=N-')-?%@)$8%MYNW:1QQ+[9(0&3;`!$7U,P@ -M)^NQ^-+V:8?Z0344VE-EFB<7EA5NB("//$3UQT-G?U%'(("22X_V'2:/"70@ -MO,'#E[W`(N`1BO]R,Z/C#'EV#M>N -M;8R@)>N_,#J:6199'#1FNB-;AC#ZV?*,ON:'%'^$^2S]3&Y;"$J8-Q!:CZ*! -M6\OHS"GH8D#3:N"0#,M`ZX,T_1)[[G(JY+3W[$0FSYF.CTP\2TS3?415=*:I/M3\'BAKG`5*&Y6R%*E#6]+=8 -M:?.[02=XS5/-H"1P5.%&=7@0[-F$1"!BUSK4#Q7K":S#A;)655M,:&&G3;GL#+H%*Z$2N -M.@K'DI^'5?@C@0;D#?E@+X&:T`FJX\/CMK3+J17;1NWX6?%`AW_@*.>&=[+% -M+IJ=B0&#H2I&T%!A!5;ZU*I1!J[HY;XP[&?;4S8B_0QT[S%$S86U[S5D0)Z+ -M7\&0EG\L?&\G@.*$DF\KMQ(&2T!^:*D_`7S%/U,Z'5:+JV]B(N<`;$'W(FIW.XN/[M!AE]0JV9WOW716TO<4#I8+U[ZUI& -MZOP/297'JX!,5T&:TYG3K*2V.JV0'LGA*'7E\^AUSR.Q&RM>#<`H^,IBKV)@ -M"@H8E-DQV^I+.ZY0/>"=YGFC6G>F<'2,8-Y6HWB<.%2>(VBUJ->XEXK/A^>( -M7;0!1^S"HK!E[A44X37DC6"$SDV2^A\=%8UP6EP`,2B -MR`]Y:+XME8'PU?#UV1 -M_7SL<=OVL!UGL0-^<_6>TD3M@R'B7Q3*^5:7\'B"$$3GI#HZ)WY3'0>=Q^(=N!N&=8X -MD.&A3Z/D7@$U;,`,/Q7D94OWJ@3EJN\B#,']OAXYC8B)$#!@2=[DEJFCRMH. -MWO4,^SZ!]BTE`.9-P[HI\`K?"$^'-K]XK6B@A208$"G-8$(OL4`$[/M9$DGE -M;K*[8+'7HY07M^&?5?T\ZM^B\1'R&_7>@3(>,>4[DB^]2>F;*IG%(<ZYO>/B`F*69\]5V5`F2`BQ3];'JK+T#TZC@?[#8&[#GPB!9D?81 -M%SOU[@[K,)+L9/NW-Y^K#HQFT_S@&! -MK+=882G,:O&0#BXV+ZXDD#F(>98Q4*6"/-,ESQ' -MCM!01R02#J2!9J$\#>>?#'=:OD'.?^^$VO'"\_J-6OP'\^RF156EUO>6B'_^ -MM5$AX>Q63?IOUF:LD(-T0-T4;GG6/ZH1AK[=\6E2_XD7Q)8^\\06VR=`#H"@[Z2FQ;YE2-LRC]_H6- -MA93V%0>3LY_`;0F:]LVY,Z44GG$BHXSO7Z*R]/QT7HF4&I3:F;FWVG)#L;M( -MY2N!$J!$KVT+KAY?9E@@HS>BM^12S^>GWA*I4%A*?-7S=P<9KN.'TXJ#USQU -M/FJXJV"#[MWX5F$3J%?)P)6`5=V$%$Y0';7BSN?. -MX1EHX"M(1M249@[A8`E*IZ:K]NLB`+YWX#&<-4YQRX]\G!5ZQ>$!\W`8GVHIY>> -M*2QDF"[8-!'C?M)`[M+)\="_/^'"__-XX$JM-@5HMC'>+X:0>Z1X;_*PD/E2 -MD6$GK+WW.>"O]M'OK$4F<K*QS:MN),<53 -MK->Z(_ELQ>Q[USG-0$=%@FD3%%MEIB*\!9`%%N'EF8_J[NV.F-"'UPQQ`=I` -MAD5,C8$VM%PT\@WN/D**0^+P"CN;.4T%?4A,7JL/'@;;U^N4(=0D9&+\H)U_H_5\L5^:'>>(;$NY9M_`.._?$?69;2@::AU./% -M*,"D-L#^[*6BSL1YG+4)N5#"A#"$2KZBI,;D5WS@N_TD%>L54FW#,>(S\42$ -MF\M#\^)WOX=;X9?`)N(G:*ZI9:`>SD-#&?81"Y@/T0_QM)F.;#GOH_KBA]#`(X#B!X',AO8VGTF$\<3JO!3GO[C.1*@1B -M?/9N!FOL]HP_I8*[(AOEU$A_>M*N;WZT1$N+58.DI=Y?&H%-$Z(=814:$WXS -MNW7C<1]XV5V1GOIH,:WF9'9)0)M/\#YJ97GQF+D]?AC:AFBG(@D4QD2P$*Q&W=:R(+SJ`]?H]G"WLX:@6F[)H,NX4\BM5 -MK'.'M8ZHC@&'#.6X#R3G-_!QD]=G6WF)Y:XERYNCK^H@-KIQEK7)"HF79Q80 -MN8NHE*4-,D)))22ZA+4#,>A+):8A*.)W!6V0J>4X\1XMB1(QWEI=U@76[O?F -ML-8$.UT+7,/D.*T*P^O9C(>3'.NG@-`$`)Q1,GY"1]#X'Q9#(DVC)"GG)F+C -M$KY.LG*;@M>@`%8BC4'CDO<=T_X=Q+]YQ("4I7V-`7V%,K2GRE)#]33LWI_1 -M&Y.D@?/3GH7J\L[8H[;AD#-3)/:\1#@K::M%)E;\;Y'\J,-A-7H4)G -M]&6@(06M,Y\?C+U,@E#:1)VXU]Z9[-LFI@:UL'\/87C:!:J!Q)QFJO`,-X%% -M!ZW,H=<,;6C>`['Y]+.5J;314+K(=-P[PKRP*EB4Z+C3MO[DBL9+2JX:2QS0 -MZ5%TN:1-UGXZFA9B##C)L*FT`3.0"%E)S8()=$)ZJ"!U6;^MG.X)7*\OZ.^:OJPKI@G<)-%;<@HF5Q!F&N_$A(QDN2G":-E'%!.7R_)LN" -MQ`V[^1.'B'_I32S'K\G6J8>T]6-I:T[A"EMW17.0VKA:R\AT%+K_^7:DI(0/ -M9HC-H^5X$A$%ZKF)?9/PT.2=U7K/1RIOXFCEQFV2"76:DR@9_V,47,OI5QT& -M2H`-T41G]SVW.8T0$!DUW=CGHR`J,76LC*4,PB-5R1P$K -MH-[=$)1]8&3`LG71%G?W08H.0*,_M0)['R>0T==A2>:H5U+&7H^A8%!:!VZ$ -M=2C*)V;]0\GY1"60?GQ`'/"UKEE1-?W,500LZ1^^^-1YX"E)5Z6Z4NJ\OVL5 -M3TFZ!U?T,UI0SY,8AW-SQ?*;!H*.@@@(L^T*#O_&->Y1T?D\ -M>/U#OK]D'R9/\ZE3C^`Z/:2]7L[W2M'-9Z0P>-U_.,BK1[Z2BWIQ\%'-8D1W -MD^=4B`4I.:0`!9#.>K2#-1JL'[1O$PC1_?,FUQ?;3F53<"Q92Z@G)#PDX+]: -MAQ1D^UD>5"(U1?3AZDM^$4^TS8*+M.7_ZZV,,K=/&7D_12"M7DB("$_DT'\# -M^`T!QX$V?I[A5@'M4#]7HM$JW0=8]34UJSG<(TTJ`G8&EIF?C)Y!$,^`D"VI -M=YU_?<<\G>,0;K_"Y2H%UT""BV6>5?9[=14)R5](3TWH'PY+=87!`PXEL$5R -MXF?%S-\^6AO7!J)JER+-Q/9)W'63`=:KMV3H!YYND+$3VN*7I%B&(DX:*5C?_E9_:`!`9AF\)B[XSR*+DP=W!D$.,&0;-M;T\3O2#][_X\ATP -MLLESMM?MK.SEL#:,\]!*%`P8AF/8'_;D+7S4<($9ORJ8#UD88/^_!ZPV8W<7-+!PE[ -MFIBX#WVC5^DT&#/27B@E?`R#%VHU=FGADU)V46UT8#%JN;NY9D0S -MM:Q]VJ>&#Y@ZL_J0-GXD&BLFQLE.UQGS*823J^_LL*Q"'^RXY*^;-ZJ -MJYV6PG=]2$&3Q\C]T$JA#/,^8+B4^VS.\MF2D%)_UJ3/@7BV\CSOWK#^GA0= -M.LB*C#(23$P(6Z*%"9_\@#[LVCYO+!:3PYN[2,J?8T)G@.X$ZJ=)F[*]P,G9 -M@^D`:@K>?&Y^GG"FS"7S$8D -MKB[?Y:N\646@;;PE-#,0G&[\WK\:)3/K'*&O#/>CDD:!7:KFJ1R4*!6-,3H) -MI.4J>7WZ;!F(.#)M4]@Y3F,.XU;V1-]DQ3:[;5%4U\`N7(^N3W[YZ*::.*<3 -MY0ZI\0QGJGW)%VVL4`U(8?VF=9I0R:RH__?4L`GY5,S[A=ND4%8\# -M*-.W/*-\F)Q3OP^H(:.(DG@J#>H`(&+.V(]9K"IV5-!%CX_X/4[AL(P`'C2W -M($G<.9-B54L&>QUIWQ`D[JF-%-UD=<,GI@>,HS+>S2UIBUK29PL:\H[5V!UV -M1!9,Z1C1RE7%3Y68I)+8^=B;KYK)O8/R*[!P9;:3JA+.B;)K31%=TNZ>YLE2E@8DK*B)K$(-&,4:7405MO8\=GNX:7U\J)U=IYZ".\' -MOXTQ%G)C@2$K7SM*1@ATTUNN2(4DBF-=D5397MEM#/$-`BQ?5+K,T'K"UJ)P -M,\$K=C$O_`S;:C[@*Y>I\N76XWP&M43)CG;/^!H&]'0VV! -MZ&$[AI#2%5V"PJ-'1':`/=.3FH)U1OJFN#7(-:'K"YDR]A_UEOM[C6TIO%X2 -M_=Z[J4=DP9(Y)YV?F]Y@=B1(>$&K7BKP:;!-H("UT0GWG1;SG%?(ZRWRJ]"8 -MUYK6/*"=DRV$5HC;(1`YJ0%/Z*_3R*^53$E0.+O\D<4(L6C:(5$N1D6ORG0< -MM@P@]1I8.>BR`@N6(4_XY -M5W?$V"!0T$Y8\)L#HS"2:/;TRNFQ.,48OCF.%X=V'"%?G,03J)H(W\>RZEV] -M7\R\ZEK^,O^726%%FX3U/\8APF#GJTAV\C")G37SC"X(U>ZN27]!S35'YS<^ -MB)QT]B55Z"`"Z)TL%&P%S9TY#VI(@'^&-1"W.@IQ7/^Y;_C(5>0^BFPA#*6@ -M-NXJB!4;GN(;;1KQ!?YJG_IV`40GH=#('??3(2^G`6H[8Y3&)S*1\%>*7BZSEYLP2W]1>9!.8S]A8?V?@H=PY*X1FX<51M&>0&"CW.8 -M3?UW924^2_?`YYAO._-N!Y"XF6#HB28L)55A>#*9YOY*64-!P8'GO"NA&Z>V -M`%K"S@BJ9_LE+##/D4X&(X(CJ9U`@U+O#;]RO#:]D6ZK;G=%:@`$B^,R6,J= -M7^+/)2JI>ZG(<%`\!4XRJ;'#7NL2F1=&&=35"6XH;%-S4Z'E_=;ZU9C=(`L3 -MWUEUO%[Q!1G7Q;1E^,,^C3+8]4:)N9O`I,]L58)0+2QV9AK29\O9;9-ED=\7 -M'\8B/C0*#":NEL95JDX:26HR8#C'<-AN*Q -M&YY"[U>?7KV#\)B703:A+;(]"ER'&BW1'0C/>`;O3FN$1`*I`BB&]POQ-1`S -MIF>"%*!^L-_V35Y+MRQ;K^4P&?OF.2[FD$%@ -M<\0+_4EPFE6I8.!RG?O%9P7,.5`8-'4SR=-B.#&(V#IH84D[_;",>C4:ZB -M!L5[?P-Q$1+`U3D3TZ!E8$\F)QOTE,L;H=;;E]OE4W+@7&$9$-4"2U)&>`'9 -M'"IA&EMASXV0&8OV1Q9]6?8(A,^+<8=X^49ZYW1E$1<11%J\43?51$A&C/0H -M2W.-N<-?7IR`X6ZMF*?F:,2AHJYNH`<>869>Y$X,X%1\A]*JD7[`,N9U2&1# -MQWQ+W.>D]!S;D&KC%H(Z\Z+\K,:6P5A]JB9LYPN^*$;GB$'_PRMTL_'B@M]0 -MFE(DB[4V2U@3CB2K-#@85%1$?Z5F1S-9@U8(/>$(#R3Q&[Z^@W4.J/$E$6B\ -M)<$R5Y:93PB'28"12NGE6GB'WKLF3D;JWN_(-`\K);SHM7Z[:R)@(2.5:M\( -M_\PC?$184MK4^8_[8F.=S7FJZP"QB[PE7OZHV-J6/VB+P'CFBG@A9GU/:+#= -MWX[!:1@RF1)=1.'[>_UB^ORX8>>"KK?+S>_=5JU.'XWWL8G05K&35@L-\7#% -MOOZLA+U_")^8IW>@I+?A_]Q?\' -M^%22T#=/U`:E6)!;8<#X.Z"#A5`_PN*R#M!63$C89(@98QXN/EX,(-1=Y<;Y -M!7>F5)3&B6VM3:"Q&-(36H;^D'7$'VS,)[*..5A\T!Z%K^5M2J'SRI:1[N9A -M'N6ONW;4=@AWHCCG1\QB0^J3DO-B/8/8WY$9]:#4E3[ZWK*I=)`]@QXAZK0?"#G]D -M1"[=C/S+9\^(@NGKJE]`"F6/X"9?&)J)PB+V@Y/=<0NFBJ>&HUTX]31W/218?T2$)>NZ7=9/S10DI=`UQ[8_& -MJGD@\63-H$&O(W$#*;MJ%13-D0_16>?>;3`^RVV@AAG[D]J16$WJVN2CB1.6FQ%Y?)@6L3!6A9MZW\,I#W9FMY -M4._0?"V`-NM*;V+=-7W=L0;(_`L5O.1Y_^&8_4Y]$\B%44M?Z''@UXMJ38?_ -M2B0,^2:3`%%S)]%Y'=-A#;W!O@;$,E5W>JA"/S -M\/N&E]/XRTH,P'?ZE085_R[AA7@W^-^4= -MMM-1Q3CU'V%4'^?9;1?:'*!/I^),;AQZE!?A"A[P8WF?"OB,Z!S"H=\"%W3>A0::'/1=`NO11#<[&>5-MV-LJB3OJWP4[N]\HMJM! -M6_]^I)HLS*6'UQXSL)5'#0L!@G\[7]7!S$:X[%7NDNM_3_X!;+@?M";@*4:5 -MO_$EF)N*3`*)N9G9*J3%B]VP3%2>-CTJ]S*\&J@"4S7T"FTWS#7)<`R]N`.E&7>?;??$P=AV[R6\;0"FV=67QQE&'W_BU'!9L -MP#7'BD$$K$H8S7UPA-"=$C1FO=17=)ZC$B&F/S_5-QHKAZ[_DXE2;_`"2U!` -M`IBJ)*I=BI2\;S?%BI*W2RA@5><=>,+_R1@G\;Z!0@EPAJLBM876[YOKN+X\ -M"W<%C-[F@!>\4!0L$'3ZT^K5_K`BV"M=Z7)+6TB!/=#LTM0=2#JZ7'\?03C! -M1`1/)\3D%V94ZY,N9RZCN -M=J^QJ3O_N;5<2#$))@;/LREU0`WEURZC"E=D<2V!X5/0%F7JRJQ,@=`EL.,4 -M)LA.K0=G6(K<-5Z'$`RSIUMGI_@`IS.K,3JI_=17\(<3IQH3UDU]IP/!]VP[ -MF.*Z?3>``R.F[,,]^>_] -ME;UW"9]<9I&29"]M_,U4]\"QL?HYWG?%K=%NY[IJ@2"27P1?+"!;\AH)))C0 -MUN^%%"'6_9"W^#*3D(N_>0):CT?,6%":TUOT>C@$YWIDTZ]9F9[%$K+XXO0Z -M=RE`,%_05X'AO\VPN%"DP>++#K(3*2LOF+,LTF<,`V`)C-3=ZM'@K6^O&WBO -M8ZT@,`?0#+%A*ZBCHV/"V$L;M!CIE=.'UK13`\Y?AS6B<0NA?]V.NJ\?6_-B -MZ9(TSP/<7_C^H@N<>\QA,M.D,V()***F,PI`9?]Q8[L"IFW1=@R6KB9-7,$B -M@?%NMR)$*X@I#UG#Y5_)DJM,H=YYJQ$1I+*T4V.WY1R;*A0$%QKP/V^UGI#82:S>;H'UX9,3X/S1#1L/1'6-`3D -M+4C0DQ[H(6\`&44^\9KGNB93?2&9N('!K]_/5EJGF%#+@T=(V/8BJ?FOE\6_ -MO?]!!3CKDI<1F=<],(QGSWL;WE&K*6\:9;Q"%[!)HFJ<:1LC#P=[1]]%U(`` -MULHJ?),-P\5W6A"`[";EL$M3%*(*!JRYZ+L5Q#\TXP=[+`45\DI7V"!R&9P4 -M*=]+5IE#2^=$;BF1C[-PAS?'MA'[(45``N5IY=*[D6W2T)"%%%(^O'[9K@:0 -M-Z+W9B%I`BD8#M'PS.C!T*P<`1O&R%":\SS,W-,_QX?R_I,PI&8&K]0+K,W.A+!8MR#KF4!-DY75(346^5K]\2CAEXR=]QPI2(VW -MHFVJ6^+=Z3Y\NN%\7..QB5X<4P6&Y[ZB1)QWH$D]S4/;JW=@D5K!8:;X/5T-I//A!%Z+ZE;:3VVJ -M@_7,?O\&,9Q$`OOU`)5\=Q_-*6DZI`^8OFE;,BL&[B7[AP,8SH]F8S1.(L(= -M]J.2]P:*?IP3!>X(0H5:Q2<1&1:!\$\-]2^E2II]XQ8VG/+XVX&]OX@Q.\E\H8U)/J]6@<'XB -M<4P\\.'5J@]H"'"*SM^IGG#69"K\V68@JH6,BHL2/!LMFH4%ZI[*?<@H:^\\ -MGB6<;UG_O<9..FZ6<[9]&H;>FK$0_IL'9N_`-*MT9\K2P"OJ5!AMP(O"1%*. -M=3:JBB;AV\#"[S3B74#/9N'?V%G0W.*<.-WD9Y9E"/AJ""+J*']84TO*Z:C0 -M9L>?T6 -M,%A(]EX4NO')0V]]&X4VVF)FW,ZY"$[%8-72)O<.B4S/&7ZNC?%`XR3YH!O[ -M%TI>J!B".(+LIU//)E[3#BPVAFO9?ALFI[[#HJ>;DH/HKN,`H-=TY&-^?43, -MU60S\^0LIOI@)E&<61*WHRY(["D7=W_2O&H4^])9O@GYY#>'";*C2,IDO:RZ -M(>8<89SSZ[KE3N%*B$RPCTJ%99GWFY"^CM%'/84KK**6T-!Y[_E`ZW(\'Y[[ -MQ@=0F3\PKWD(&ZFFV,5'ZGFA$$6@KX"'RIF`%U4;?13"G%EC$W*.O%01(5+& -M68L.X&$1W^8*&OM4-S_101E<&:P$*W]J[M0X(Q*]S>U8\687I./BW67/29C( -MI-0VP5!NI8OGQRP"LO76^G9KP;FL&3;3LY_:]4;^9FFD*#1+&G7XVVT5#K22 -M;2SZ899"30$$5QYVNUX+!UUS;'4[?!:7>!XDOPQGX4LJHG=G%Z1$(>74:E[" -M]7736`/WTO@0V*YUK1CF=6-JM%^ST#(#,PB?58E4'5]P+U`3$RSJL$_8A2UG -M#*$,$1(-72:1;0PI$05F^8-E?SAW>>%S4E)V.KN4%F'U`1];C>T$_UGH<451 -MI4N\N--.O>R4M@6\E9+"8O3>B=`%6GAU"6*\EV:.L' -M'U(DBRV:]XYD%^6)!>/3-4/TK,?>O:5^4U]E5X6(X6[GTK_W*M"^;SQLCEF4 -M['AF[MGKSRCUJZ$+G&031199;3Y5Y)\@'"K].^&UMV)?#8N+1B:_/*E\*I>\ -MC4>HA,*N1ZL8.[S/##Q5DI:T/5L?K%'!W\#IQJ9GLBE1TL"X!``'X5GQ*.:)`H(:A^Q`ZXN$@TK4@C"_[2"P:4TK?J[U.&`;C_(XV>:"Y)E)PKX9!/ -MMACFC#.&3$N!U&U9,0QBL9V) -MA9-_"1:0J]8!6/R_@#\Z*9;;&!^O]Y`QD%L:!*F^)1*BZ&1&#*6N,V[4RW;V -M^J*1>B6D.&&GK\=G/2>:6^:`LEU-Q_]^X\M]@K)5"2K_\^I11.8MRYH^ -MA5Y^V@S-0W##69BAO?7^I2PRKK^&%!=6>!'O]GH1:.W%XC5%5T4OE=5AG2W. -M/[44./J10&6!NJ;45'#`69S2CCJX%_8O$A/_(A/=^,=?@4$]ECO@V!II@2.>IB8=&,)FQIO413K=Q&28U;H: -MB$%T`%GG>T[S=GC:"(=(M4JZ#/!9=%,[5<2".L!6G*E=;*'`96\W$]/WEI#`&1T -ME%AO`"W?NXA&]W:C[7A>R=V;H!(P;7JW&I=C"^2:Z7G.A&;D&Z0/A^W^Z,PV -M>+B*)^E=&WQ;Y>Z%_W'B!>S-#3ZV@X1Y:8F[NNY[XU$X7,&X7B$\94$/_:#D -M-825KUI%@QICM`]'7,=3(A=DL'519)9OF'Z#6&\)1,`E(:=8U6Z:6^BYF"Y -M^+5-50I#T!\YX3V+JK4&YGC2*__<+(-%XTX_K,BZ0F;FAL$[:L2(\-P7/,^B -MS#Z<.@6KP@]?_*%A'&43+6YL_'I1-0TAI/O'*[%_L,QG=6Q;W:KRCS!Y'U[1$\HWT:1Q\>2=37[_4 -M4HKUCB"@(O(47F7;2\F=9)%87]$/^F`A/N0@S!OHE*\>'0VC_*4$L4&0,3U? -M`%/MY@MT$>ECB-PV$ZMF#;RVF[2@'MM]DY"7K)\'\;1@V8^C'@?=E2R%RV^O -M54E0FX$XR^*-$(>RT2Z?W$5_N?V)JD,67SR/OLHIZ-*:O9>TZEXE,($51HFJ -MVYOUETN9ZIT*7\*L@Y'LJEGD0E,]NZH10DMUR51T@RKM3_]#CQ9HRL97^+AU?< -MQWBB57"\/)3:R:!1XX@V<-]%Y5_C=/42!:@,@4(K3P1;)Y4[4'9'#YO<3$0A -MU*FEAADFHWAUH)INZ348-O/8/U:TJQ[LA -M!BO"AFU,\/(%BF6VVD)[Q/5;`LZA6U!K3PKIY=/L+#'7^4R=[CVGOC0L(J4: -ME!';3LBO[+PL>CDE"J;(?L!BEO^04R/"CN8_F.'``9QJ56_$^RB)%]F$(<4^ -M.C%AO70!4B21Y9]>THKG7K6;MH5YQ_#S*K,4=\@3'GC:K$W6G0Z+F(PE>K_K -M`0R*"-[49Q)6X&G,J#,""Q=O`/:X#T88$'%ETJI-G*PUY(V2]&.QO;QI.BG> -M&;EB)ZRK0D,V.>E_9X>276V8@$=8ABH0F=GR#=\OT:&^J9H!>&6`ZB0-NO9$ -M_>2#D9\F3[9GI)49#3T7^J=G-7GF/_=BQSQUA!93P&^"NIOJC=.]/MJNR<8AJ!MQ,)Y#$FAKD@SSAK>`-T+ -M:MV]/^N4`0ERH(A,.7_Z:=0)\8H.[9,]>K"UF;^)`*0@7+^/".HH3[00;R"` -M2102RCA8S]KTZMX!+)/G0C2H=[<@3>[)AOQ'C@VAA`E[1N,GTOC[470UMLFA -M=D.S<%>3(3U0YYO+NUU!$SX,&(A^6OCRAUP?>:7;0X9O@\`1JHF#DZ2\BWKI -M`DZPYO=OG>1!B)O^&--B8NRNP+A#CRIAS8@I(UMXJE#3*'W_L.L5)B+ETD,$ -MGU-&,<6@>BD#\\4@-)O]E0ZT(7KW&$0UO4(AUOM-!V-0YXL1=E_\M1ZX3@DR -M+DZ#WZQQ>08.]K';ZXEDJI7X',)$_HS3+P7R[@ALL^ZX^=)X%'"B4G,ZJ+(* -M4E='XY56$HW216N^Y@EZXK.'?`*J>,K"(%AAGOJJ08;LCA63;[M6]DTS:'.^ -M"FVB`\Q%4"`:KB%C5*=;7\XR)G-Q"AFS?#BR;0OX@UF!0^W+J-/LNK/OMJ.% -MS!,()CD4@F>WOG-;6_D1+YD!L'Z!&"*)2]=>OZ!LZ77]R[!S(W"U`0VS]S]B -M(21H(H147%*6(FT8LE&NZY8(2K9%+;AT@U91,AU(FBSE$B -MVVXT+/.X^$XU:U0GW3\BTS-LZ?MEC)FDR?@EW;4]U<@.9C*41@!U*<33SZBP -MAX/C:>IH\-%BP*#"KY<7@'5+@C**`OEM76*Z)=`?N?ET/FY>(\:C0>S:>BHC -MW(SR;0G5"'T[(^ASZ4IY23&1^?_#7U]A5K^JAQ) -MZAH!W/@FW7A.EPJN:W5=B[\_Z5/OE#PLFI?<,I3@IYGMQ0[X.2L`%AC.S(5V -M.R*\%8JXN?[.Z0-4V"@&IL:$Z[A>-"_BLJ00EX,3OWK^CZ%W@?K3RW"%$%I0 -MJW%^L`\"9-4]W06`:6,,,TW<^D*4BF\5-M;;6%\OQO:)SJ)0W`QS7:KN;,$O -MF9'Z,AJP05.\ZKHX\<'>LZ!X^@.+?@[X17KN'D\,X$&C&\9C[[J%J&V/_'^; -M"P^*G/;ES`?,T9_1!EYDL`)3HVM:9:Q&?$POE'5H;-(_26AEETDL/`8\"WK% -M5(;$3,@VDF(XOF8--B4B8QY<-$K'[>V&NA<%(_.]1_`1G1%B]E+%4I+LUXR. -M58Q;A/G3(=#3PJ.N-7YI,^RL]!(T"NCN3.JOOMBI;BT$>+BR-&\U%> -MS,E^?K9WH,_?8N, -M>8N*9(XF,3SLJLJ&E[T4>MFV`4'C*COEZ!?[M2[=5SFJI76?Z!$&2`\&W\6` -MMNDA]OVH<2#WY^G)I_<21W[KYA9$/EV&U'K3U!O`R:`];K0*6;A,O1"`GZ?N -M*?S-/X"-7 -M6>RA1S:0>.JR$B5X^:F6X<4A2?7T3\)&VLA!&NTNJRR2`R2AXZ]YY]MNMTT' -M61@8H4KZFA'M("0IN(?('`E(ZBQS](FNV>YY^60JUL+`7NAKN)J`V8!3]4H' -MJ_AE.%_PL<7^ -MA,(0AQ<@/Y.335K`&V%E"/!APZ -MR28R1;3F,%Y2VP!^D"0-7:,S<-E.LEG57,KDB/J8DJPX5EI8U%@\1(IW(^TH -MPT&Z)>T^(3>'B79JDD"R8LJA`/G`IO7%SC$#`K\4JG746CE:/2Z^FB2/$=X;EK2CA7,V[]]=5C?-RZ)C02N2\8'V6"]P^ -M?"XT6MH!X%U1L;_74TP8Z?=Y?-"?I6GX@F)D*8;_:'HH*EUX#X>TO.1$S!R+ -MAFB3=B.N]PW2L?*+F"=('!;>C@O],Q2,Q,-(-FUG!E]1_&WORI&S)1URMWG- -M%_T)AQG._D_E&1X-!.FYM]R7ZQA"Z)+DL!I2?.E5(A$CVQ0W+0>"%GBC`5A, -MB-`QJ=[^`:5,:!NOKX -MC5L)63'TJN-\=H$@8]Y.#DFIL(/K)\JG8A#VU,NS7X)T4ARFD2D\MF=SB+S( -MI7&0$AC^LUV)H*@]!9I7>C6#!5Y0DAV9)HV>DM)0Y5?V/)[."Z$ZN.B"N^-\ -M[D3CY["C*D?7+X^_MUXP`_.89VQD6)E]_-93_UD2JA9, -M@(FWOGB-T8MET-A#8F,?3:06G9\:R@IL3(+;/-YD8L[OK0MA%^R,E\$!]"/&ZF)>F -M)%-[;S--?ENL=NH[D-`F?CK#$@*&8&GNZ@*OTG2W46[2WYH&>R`&39?:]0]( -MIIDD8?6S&OC:-AA@PS[1#&2*Y56V-63Y;WBKOMKIKGO2'H\T16BYV'O6R14ALWR[RKWR\L]! -M7RW+-7)2#+%?X/,2U1G\7-W0S%8(;\D(7#/?S0N;HSX9OLT_T4P5W&*62EY+ -M8?]#;^:K+]_2>+;*OT&TZ4^)Y_U".(0Q^9E> -M3,9M&,S+.<(F-IX#.Q2C8)S_K9'C'?@TK6I\^?U($T*3"SR -MY'Y[CCI`J]$V"GL(S<73>RRCV"E#EO3B.5`&6W%V8XB9;:OJ]HM)Z*$$?O$T -MV1;MT`F!-H!+HT7YBZT\H=,=GI2K=FW4DS]DWJ1&;F)=J738W2G9*N3)/]]# -M@="MQVR.#425'2UD'=G=/F:A&P`^G'M+7DI8?NG(#5XI5_%>]MO`6--ZD<1Q -M>-R9:G3I*8G]B8`F+#.MDR:J6V<[X!7='>X'GCM_;UU(WZ#4Z)TJLA%H+.TID.',\/0C5FP -M3$T?T&N@/\3UM9:H)`(_Y(_`D.N>`M0\JUC1Z?)WMT*<41[<>M)AM/X0&5Z2 -M>+H\A#G-$9)E>%X06Y70+?^LMAPHF8MC+S:A)_R6\T;2:'VJ\I8T0MDMWIP<.PY/-F[V?B)MT;?_5JLQ>H:#B@U6DATLQN[.-+(7]K)5F4?^[3FEV3>8[,I!%S#%GZOBX844*S -M1B:,ICV0FRG?H/IM4@"/2JHA[Q-]`8!2^ -M2<*R,8!:=@Z22$1QED'=UE)+,'&<"BTD5'^O-]`G.:<#86?:2(.54#Q-,.!Z -M.!B,BZ#EERZ8C[[KKT$JF6K38U31]PE-H^+CU'Y1&3DLMZI2V6/$_U'C:9:/ -M2)%*MU5WJM9U)5TVDVAKQF.&UOF@%P53BO25>I`4TP+;+Z(;(T1`,P@8GJVT+[-[>>A)->\B^"3)I.IUZ]Q`SD]8]*#CE\-'=K -MQ&(-1^0/?T6@_C,^+;B(+MDX9H6_EYT:>&AV@:>BKFB8P9C]#8@??,LYCA>' -M0MH#A=Q&YW=S1EN=ON$(!RE7G3]&PO%8S)9\)RJ.12:D6<`PI7H)=U=76_&H -M_NNJZ:EJ<#R-GZ2D$Q -MG#O\QFZT`GT&GZKXH<2?26"TI3Z/U$93N;$**DB&^<'D\B0]%7H&Y32P45;& -MX,&=DD]\S&+SA'`^KD$[.1%_/>3:NN5G9$Q`:,_%(S\C-S/,>#70%[R`-BX3 -M6K6TXDF0615/%==%$?C!I"Q4#-&9RB,Y19-+W8%V#,\QVO$+ZH93*D*?GL;H -MUP&Z&$<(O*6^S1JW9UX!L:,;Z`!K?2>R5FOGSB -M",\5]S[TP4;E&.E/?+1$((9CW8FKECW46S#<)@CB`J>1T0+H.4?>99[UZ"0= -M0R`@XJ)R?=_*L%!1KN/G*6HF3$N+4+LZM2TZVR<5!;EU.&ZM3$A"#HT+GVL, -MQ$F77R."23#2<_!=1MC:&9%M-E3,>Y8:%=)L59I#SDOP.LV!+$SM,\#LK6\W -M2)T$(2LJR$%#F&O6J&F3WM0HL7.K["`A0A+2TFS'A,!T,NB#XJ=T?_Q/**AD -M74]M0&Z[F]^DBM9_N>'>KY;73_.D-8??O/;L0"`_GFU.E7\&;L+V1*T`#'1+ -M5Q?AXJBHH\P3-:TBMM+VBUKUU#DPSNC9/,\"Z!\ZBJ4E*<@:J5/%[\YJ%C\@ -M:!5TPP7W+^6H98T3^^F]UP$I%1JQXS8W)YH4-#(<;`R933EMI`'[^ME7?5BT -MZ#((IYEO#J\+JLIHB\\A:BZP,7&V&?J'CS"`S -M>A+W3[K?YUX9[D%Y`#MPL-A&-#;)9;:&N[4/!Q./^XDO:+!=0J<>\MB1`;57 -M-">6KE-#AW3;FOXQO8)V4I6W.W_I\W"0;K/:-SK\`:R1O(_&AZ!]=KEB[8"N -M<94C]F;)"VL?\S/99O?.0Y/>)T8[*0HQ]$254GBJT]>T0UT>=IYZ*"/!.=OXCPQP<:4J>S_8H]0XSX4J'I(XO -M@DE(6(4583R9F)1T@Y-S8H_+)ZKFL@X7S5:?W;29QC*R=)U\(;E=CH`!C0X* -M$:&TG3G``_WFC(G_`54N>4,?<`06);86`P;MW0W -M-9FJ&R/N0?4*EN2\8<%<%''#!G=ZE8B)%8LRB+GM?XSQW_-`@&P=H&1C>G,% -M'Z^6LV+HC,*5_1VJBTMM[?3,I/1<_=VE00SLF:5Q$S%P$)P'M^3%MUJ6?>:C -MK.9S,*K+/KEJ^PK>#\)-X+]2[VO]DC(/E,+(X%-;KM@%O2;1D\1_H*P1?.C? -M[QC0?J:X+.Y!/QWG?FJ5L3X(06.F4./A7> -MO2";J4U">LK@Z_.O'G\&/M3HD/#O=[:<:)&F>RYJC%"&D=BBGA@XOMT:RMS; -M_:O%3$]J)\0ON%+S:UV>)`$U'VS_\/S0VHK@\WEA__JMQY)ENI&`4Y -MQ?&G90I_??_ZA$F\]\%]-^3_8LVPK^[;'-W:PL`\+8HI]+@8CN_,HS._^CGL -MM5R137LQ>1%-F)D>A"RX9A^)?RU#*8TPW]FB08>%O@E^;FB,+]DM4H_1XTNE -MJC;@$I05S!MP>*)YY>[V(@'*75U+(A040S$3CP;9C/?SZAJ^<]C[SLZA77H; -M/.[V]HW+^[/43D9H+%6)),+WGIV<0?;EBL)7!>QFCH;2NFIJQKA:QF7Y^Y)$ -MCE.`JD(<7F8$N=Q+AB%\; -M,$;`4,=K*+SM<4_&.*=7E_OK6M:WX9DXT-@+VY86WJ>T'N[+M:`+P09G149X -MNK%E>3:2=;PP.5MI:QSMO='/?0*)@)?"0X]-"Y(%WL>5;1)T4-<$X"MX!SX^ -M[&&W_B,+F0->:DFZV0]QB>?70WTYH=TY;8#!E=W+&J.U#,02P"?YGU%`T&X@ -M7SFH4&*$Y9@4(%436N@F/5&.QRE_<#3.@LW,AD++KC]"1?%&NI\A0\$%SZUI -MB)$'WXQP^]*S75S!RVZXG6O+WL.C_;`R/D]5'-Q.TS^I9R5N`\M^V/2O<,#<\' -M6R4-/`G*G-ZM&YEQ"NVH4"WZ.8V('\,NJ7Y\2.@Y@:SMQ1W@G#6:#9HE1`J] -M:V]17H,TV88Y76%&,HIS2H+3GM4LL!K)S'%6MO=TK9_$;<4(8><4[T)X#3=] -M+7F<2+0!!&3!+"C4=]#`FEQ$,W=R:"\UOTV%KY,%5SR3\0::HDQ,0=OG.5;T -MJ=_]-QIV&J\@-A/A-6Y6ISH*,2(N>9B("XQ'))/-,;@XK59A`P`R.8Z3)[F! -M-JQ/VP"!]1<5SQ];79[!.,@1&=[;ZW\/CJ8SM:#FO-[C*UF(6/UB!1&9MG": -MEGUR)RM.)A.VR(ME2IHM=.Q'.+D%^\B@I/L^W$\]NX]X?<4H\8^Y\#&?82XC -MY9:K+\PXT$6*#WYPO!?>5R^0T2MA6H7CLVZ\BGL^"47&W2EP<_/I_<_G-5J= -M)E/,5,W8E2-1LCS5-W5^2?8<_9R&^$\-%:]/!JY6SW>JT>2'.??@M_O$+.^+ -M?>:I='P-+U9>`,!-TS/*:>+PLTD%T#V!8)#J8M?3FOJ@ -MF9L:)NJ>BZ]:3]25$;,,$G7E`?J(EP1AR+5S)T`O_S*$8RJ6[134+7U_5&HU5]Z)B/2:!P+3$/47NX!C&-W/^`)D["RUP:G'\_WR4.(B -M9%TM@AR%Y441[206*2YF!3/R:85]+>DQ=AP:K,BBD6X[`[&_YB8D@KB8WE1@^7">B$N<3W.L=PBH[J\9K)`*Z%6;1^E+]5;$ -MB!_W0D,=$'E:2*-J9WNHKP;4FS5I.GQC3FFO.S5F+,">CI#WTS5)^?EQQDV_ -MR?^L'8X#,I^S>=W/YV[659[SL'J/[!`7NZRLIV9-A&>?UJ7V:WL:7M9'9MI/ -MGPM`J8'1?]R"9+0S2;O2N!KH7^*#9XX`0.365;,9YX+N\`+"TS\1E2KB]131 -M=4$?!(,#PCLZ+OHQ(YG'&)#?]ZN2ENLMHTN4F\03V$&K$4IUHG.DTR>-CK_/ZL0D -M?;/NNLV;VKM!E7GJZXU(RGO2BC)EG]?;$7WLXZ)%7.9W7C\$`&Q<@K-K%!K\ -M0Y]6S=ZB3IUXUHSB'#D607WME?VRC3?U;5:J$CV-%*$=U*.^'M(+1(G%&X/9 -M5T56YKH7G@6TCO/[,"S8-`_\50H/FEEE!E25EV]K4P`7$XD#RVC>W,/;X4)^HJ$ -MO):Y:2`I&K_=5S"75E6NJR:TA-W'34Z\G3J:L(:#L;WK&MJA/='S`=X)A#(L -MNR%"A804BUFCL=QFC]P2P5`SK!2*4G:BA9(*Z#=/&6(K\"@T6>@4B):DM2U" -M[7W80D8CD;518$+>%O$;I"!0QT6_V -M2&7O^J`+7C$5;$WBA_X;MW1Y3HFL/%3G.HRKI\4!SW`5K,MMD7I_-_)%AVN# -M4T<(LCQ(@4N*^+E%C>VT?`*?_8D5$S#R -M-\`%S.'G6"38#,=A#%.LU@HY%W)C,X2X64@F0P.YD,?VL05(+P*_ -M0>YALC))M>/[C8,]>%-[GJNC1C[$-A;D/@*`A.-7]X9K"XCN,+9^D__@IHB+ -M)\X.F27ZJ#=.@5SB%S.I+,+1L";] -M7SJ*D]-$**&)E'^08Q]WL&0.M>;!"GNE.6UD%JW -M9U-*UJBY5GY\'K76_(*_\/E.-*\1Q&_M@6E:#?`/X0"))&@1>7$=6V@;7S6& -M^\,4`QD#3[=?1Z`<+^H)*]<&`8TX<=PF'L./9[#MDWFA8QCAHL@ -M%?E1J.ZK*5O[/P+;?_HX@\)VMS0C7?)4Z_S)E3*I^D2!`E-WS&>IQ3:MA%3K -M#KWPTUW69`.`('*@C$7:_/_4UZR^+J&EJI\`;D4`2Q&;TWSJBX;#$1@X@N?# -MC&EBOSZDR("ZOH*;)PO5CU!H&=5-!33M+F)ZJM"&PL:W_/:B;[7SN?QAP(M- -M3&AXQ_MY332?_^TULX8DSN#KW36>*_1=E:U1^S[#4=%:%2^'#D`Y0\\^W?ZR -M/K?R?HUWZUN_[&FJ+J:EP[-F&K$]K)Y2%JGUYLQB^Z+YT_[+8>&$#(^4F/%4 -ML`X=?7)WODUDA]BOAOL\9D[*22FO+A4S_\7%^ZQ_`['@.IB^]:DE%)"`D9Y* -ME@9`5MGJ?S$J3JUQ!VH1U-^K&8>@E;)SETL%V+*^S;]*["9"9YO-"7LT:#ZA -MZ)8'DVH*[CCIT:XVL93)_@,#,KGPF5.3#R%"-6OV%[&W&K*H%9D>%&0HSX1' -MJMG-OD\>?(4U=%&R4!<37,N9RGEYT?A/)Z.T/DF]P;\F1^F\:N[L6;/"!8]: -M*U+UOC7FL[\LBC*2YT3N[7LQ_VFXTPZH7[`'I:)>_A_8V^4E'$ -M*^4N>4XCE?<,53@0G=SV2=U/2-FHKH3F$88ZPE,3`/HAQ!E\??\D0.9M-#G8$/9:Y$0G]\WG>I#8=,P#=R!/D.78:_/"GFK/YG`:`) -M7I@.TJ\4KR&*?WD<>U9;WS9'O(\#'>+KLG>6WSDVKQ?_!-/?5\+[:BR.;D`T -MDU",'08?$/AJ!P=<"`RC)$QQ&0DT:P$?D@A_FF%0YTA4VQ=8YH012>2(A?FZ -M'U7%S:]/O<[;GE1(25T8D]5X[!T/%SVC7RE(SMIN(2B&7)N'<4^ULS-'Z13.+ -M&D&!^-Q<1)2T.5/-))YZ?_@T]9WA?M)$BO,.TN=%Y5@-&+&8S/Y_)NX&>&F# -M?B'WBZN\]0^][`'#+0@\%K -M=JYMP,)M"\(<&EE[B_VA+@(J(P["11:XUM.N-#NJ@+LK4KZ-(YDU0V,?9@%Z -MQY8-U^`=`PQ_Q^W3:^!CAUV,'VE.QA_BD"Z[/:-: -MG_*=EZG99_@.9O@P_/N9UX[R``GL9V/'LX\ZAY5*/;GMZQJ1IT)+P=QJ%+RB -MGY'4=5-5(WH/?C0CF!.)ZZ'Q1`S4$\K6KK#C.,CWWG=2?L=[/RB?4VU3,2T9 -MHH`@I'=,CDA6;Q;$!F0!65S+*:.L?[4JWPN`P#9F>Q:ZJ=ZRHA2[XWPI*=3* -MF(<7O&!!=@YV8OS+Y81U$T`@VBD=GCP">>RY/-=(J;V#NJ'0EM9WVG4IA]W> -MRD*CD/"?+M"^'0LWK+N&[%:_6<0#?OK2?=_2^BEGT.N[!F)DX.3HXO51X`'$ -MW,<,'LSHP?L^1ZM7N^;07X_^QH&L*E]R;(HK!03XS#R)NN`A,@D]V^QU?X%< -M&B>`-F#8_(M+I9*<:^8)_0P\\#"+-:%7H_7X;R/\9>+D5J@)>1("=*`?+6M) -M&QFWPOEVA(D[-8.)_$E*IO<.XH_`I0/D^'V':]/(\>`QY_"<>MLCA[6#19&T -M,D*QSMP8ZR]"D7(#_O&13408?'$4+_!?LO#])U!NF*_EJ_XP"O0CGA*O'C52 -M!-=.1A9>"$ED(I].KGI3:'TBC_Y#7[62*;B@O8RKW0EB#7\RY[^.)"?']RC% -M^*?52$*!C*'K^GC\+$VH!)3*S\FL$$DP/Z+-?<"Q,ZV#RBICY.SR^5@$L3>C -MFDWJBXZAH@SJ=&1K\#K\$U'-6N&T]7CF<_P2O)T=#?"UG[%&.Q,+2HUDCZH53*+0#\/ -M"';.HM!KF[/&07Q#-#9R9E8/I' -MH^:A15@<#XDL!I0]6X0OQDH2(.Y]*5ZKQW)_921P$D.=?8!1X.UBL\ICPDO^ -M.'ZA7T[9.B:O['8M,>EK+$!A@%$Z@0C&.&;XF\9NV^-.AT.A2UX5>PZ3;D;. -MG5WMV&DLJ>*YRHJ-A5RI1C'UPD-K'06\##^;4U_FKAP,V%QX*BR%KXB=@L(3 -MK=2I_#&U#?:-;G,#,V&2%I0LPGZT02(S%>?QCC:'6HMT[W`Y`]L3,=[QT$MW -M!J9]?1?FN82OU'H1EYS2E_319M';RV]E+QY.P^'GSJ8#I=Y.=,1T@ -MWPEBXL9=Y.*Z##EPJ*8]3`W_O[)[@>5V7<<5!$#EPT9]DKE`Q`EL98KPCR36NA`V -M\R@T\(91^^6T6=GMGYP:+7=A* -M>KYS#P^R`%&WBUR[!]$:$=4RQ];'-?M&Z\Y!@EF^"NN -MNGJ+A^A>YT<(V@8DL>;6:%2;1[$$'E@GJSBB8ZW%$VWB8Y>.82BG"[P^8/_?N>'H -MAI(TJ3&S"M\!O:[?<_D1FA9(/V$ZNW9]=Y(5O+O6$H1..8AIXH%=`&<+O-28 -M72#;F1C8*?;A:4WUV"(O#TGHX=(2ZI@IL5*KI; -MF;,,B_)7C"1==H&^PD:&]N)BWU_A4*%=$(3WSK^=EOSYQ.W@84"DLGWKSQ/- -MO/^-HI>DWKL_M%1DE,0$FF.`;0/;<;L/$6MC.=ZQP3_9OGH$/ITLOX"&5`(8 -MW%=#W_.W6[>*>W&4*F1*>VNA:VGZD_[05\Y!_L_=1--]\MK=A]6(/'&Q`9;2 -M[670A3)B4D5D=7-&YZ)VA6\U<+&9M4 -M[[J.+!(EM@G#^IK(XTX5("W\UY$\OP`:N_!>0"'BYVF=`B>$["/^?S0>#91] -MT8&?3ZPY-B225]HKLTT>UUT*THLL -M,Z"`O%P"3)F;+X0-)TD/W.WTU`G<,>>S?Z.;7&./T!W=/FP__YF,\)Y4*Q%O -M)*+;PMC3Z3,T@6,M.HYGP_0L\8Z#J#K_A:I]K9>26>/W@ZB+0K0CYQ*QSB`* -MB)+YU8G7];+HA_(8W3/LRE*F>?7C:(KE8-_$/JMPT];!OQ^*AA?.C;HK&CA9 -M0R);ZO-34Q8&B3KT=C-HUCB$06T%@_0QCG1)2VS!S;UJ-Y:W30>A>VS1&[O& -M0V/(VQ=.T:[%T]J`S-G?PG']&&4QR^MYV=2J"&/.'9(5_;VDTDY!C=TG[D'17R18)MO['8N&LO$;"KN&)_KY$81L*[!0M" -ML7_\>05SP_(E$C*/'-6"83J4>E%%B*5G_C!9$!,\K@9%W-,8FM/L!)K1LYH? -M_.'%;B7&9O`N9=@T$T"#)LBI6L&5_#B#1`^7UI=IV/<2G%SA0$_Z@-D/AMNG -M3)M,OB`0FI/@CN,^F-0A\OG`/HTS3'O51(51^UJ_BGZ\Q*\ENIEV8V*PNZ/2 -M#8+!U576#FW?/-"5_?&/(\*O&%.8O70]/).X54;2RZTCHC6,OLB"AF_.,=<] -MVI\;_UJ]-(S*U2#)9.4HI!*MJ2`OM7(X4:^Z5(^DEB,)D -M(EAWQ-]E6?NH[JW[S6XIG[[8C]0T)^2O-RT5#V&>B[\/A$1,X7ZS!J&F%##$ -M6IWP,Q*X)SG.L7_\@2-3;U50-D-#] -MHQ^C/^%BL02(-1#'Z*5_:0Y4$'UZ53V!_MIV-"^Y%!>Q'''+WF+KB_^IP4RF -M6MCN"JU$AP]"-^$J0=F%<7FZ/WS019*''RR`CB)H@-6ZP#.HMU)7R3M2_BX$ -MIH3QU*B2BIZT,2`RZ"4*_,V'*8!>I0V.]?9L.=Z.P\S63V[XYP/N%%QEQ]HT -MV-/-:^X&+=6EA[Y3W^2;KR+?(:BU\?!CNM4M4\8(N!=8"@0LO1]'I/!68Y0KC)EP8J+^7P -MX/G<>)9ZF++?QC.@E`QWV44:?XD;,S7"4@RZ0ZR4WB-4>5?ZM>GSG3<^F7OV -M5IFT.$+D$8MF-B6I_6^J=JX:#!A.H;^T/U1P'C<.72PKB?"T^'KWJP.(&JOA -M:?)-/N^Y/M=<*'*]!A!?+"22F)!\QZA\L'1B@]'\#P"4SN3T,05JBYYB!S!J -M$Q_]=I@>O"KV)=S$9Q'4GH$V!4R'_)!K6WX9<_RLFK2!6=##EX@P!2`+K]9_ -MM3F01NDX%H3?MV25L4-_X"I,*3=:V37%YD)JH[@X+3!LZF*3A0@OR+ZT>*8N -MI675OT(-*90,<%E6?)I>M4W-:T"JM-)8HK^[.W./Q!'M'>>]7MEN%P`%W_V` -M>-3E2SCAI3^LRS=^9S$<1;D7V;[<)T(8N#D>A2:JGZ=3[L@;(?/,/?YBV)[!#JD7.7H.+QP:8"I9/9+$IN_(^VG4VX`-%X@=)_0R7JU#]GW2'L%B60S93K.1!Z(XA3Y -MX7ITUDL28:?96OXO`S?&F=Q!],/,_,#SSU!I]XT_TEH'%2SNXN\K@OB -MZ4`C45G=!B86$@'1J(/0!F!36DTKD=_"%*(U/C4),VCZO$PBM0C2][&HEU`# -MDP$#*%1(D^=+?[7%/.*Y02"AL1R]:+`L-XS#!U>W$ABQ#&@^*R.KGL7>&858 -M#Z*XS)-%#',:,R3!GJ:=ZG;\WX``Q`+H88/ -M(F1=8B6$33`$M`"_E\P1LLX,::&PG>X6--T):LE8%[/ZU6*ND[`;MBXEF0;R -MISG"F\_[:4^8Y4'<@'&R,AQ+X&E'D3DO+)\@C2^)/%#LDF"%S^#I/,I -MU8MA*,EG.Y10QF1Z.T7P52J$-C*VF1*@/?"OKZ9Q=A6X9V_F8N=3#S/A:5?I -M;?-PN=Q84RL%3U:\@G-=<-C+@4C*`LNK%K`#_G5YHKI>7N"]@MT=@&\\CB;H/W@-X;AK -M'[B[:E+JNZKX#B#L=RAK=5H+G[KW#HM=:S@%<#'DK8]-120+NB&%D8^[`4;3 -MG^01I6OAW!/[1(+S"R+]@=F6Q$]6@88T"):*DZ3#L4CN*&,T(F/RDV"Q'-,E -M:E_'7[POOB/&4B5D;*6\=>7NLCPC-ZSPV"5X1C;TNT -M:V!*O&O0>!V,1760CA0&G[?X<5],560N'Z&8!(M+<*00F""0U`-*^SA3E\22 -M:`JHX]ZN8XP1$ -MQ=3!]W/8@'(KIT@'R'4#)P?;AV"6\7_>84] -M9KAM=`4=4Y9F$F61\ -M)UKQ9&;'Z2Y:*_(C#4A&>XCG?=U[F$SE/`>O*5]5^4=6&\#NQL$G?_U@W[8' -MRN0*RB3R;VJ(G>22.>N&>4G/`SF\;O/D#JZ&1-U>?S!,PS&+Y<=J!B4]2>_/ -M\FQ&R.@&?0$Q."J=K`L0?<*_(]#T&U*^28U.Q1I%D;C#DWB:L?(L`+F/&4I -M-PDDP(=P"S1]PHZ7'^[HCW\)ND@H+"=!C'D3+SGI>9;3("XA?Y?1PG"F?BX: -M?E;$DG##DLAQ@4!NF=*:YO1%.N`$RSXAHVF,]_BFZLW'V%6_M9S(VAWR\.$W -MO)-2K[$,H9S&TD%6J^2H$_@\P0/:;@AT`TE%E<,=B#4,I(XEI`*CJT -M$*ZJ[E3)',STBV$A]-\YTYBB![NGL@=L`FJW3Z=:6>O[85J]\8P5K&+,--,[\`B()T+1`X9K@?&^6!N!F*MP+ -MOT8<7#(0U:$LHP`^:-":0IP<-F -M81"7WEP:W**10DH3IM,PO9^*>N"\Y+TX4,HUYNZ%E,VP72@925R9D9M=-Z\) -M$GB(XERX+25PT?J]X6>@##2;!R6M#<8<^HF7\D=&?:)Y*0,GXFDQVTB=7JWO -MY/CR1/U))12^LP[-%63'>Z.:XMD2LM^XNU5U=Q"C=FMP821N`)=CGPZ81+:: -ME07;IM29JJ1;07#W^Q02JH%"4%W(,:!\_)G"IJ#5A5X%8!K<:71#X[J09G6K9X`-3M!$V1CV6D:T5 -M.!S`*53G)HNY]2%"W.9]P@E)2\T)LN!Z2%O=A(EF9Q2D1F"H'.94U?R0@O_Q -M)Y?L$VJ1G03XDP#,--:!N1M>@RB]L,/T6?6;"&2\8L2XP+74VIW_.VFZS)QN -M7H>N4+)[L-I8%,$C*"I]CF<3RC48]KS#<'H\;!E*A<:_I*6@2X1I;,0/#UA= -M2)N^'`H(PY+PGO_W9*@H*FCJC508[<(J0(+*FPHCKBGYUV1:AW0!WL+3`VX5 -M%L71&K#WKON8?W-.2J+U6,X7!KD)%5@*"#.OG>03YD*%[D[#,S72XW3I_V96P*U,-2C2@>%WO5GC7O2UUD-^@.@LSSSF8 -MJS6:?V_G;UZ>BABW!!S[8@.MDR9ZS2;U(5AQS9&TZL3$,>)1V]4(P]@?G<>I -MI%GVU>$+V0Q3%:]8"OP#UZW5#'G&S=6KV\4T/AO31V\1J263P>F>R"E[;W>O<_N:( -M[DP19%L\Y;5&'V/=,KN1">GTJ+."&80_M_^LH:O-@W<6"A%$/3P0@>^_MP"E -M)T*_A,^YU2+'PQ7FZ"Y*NNN:CLZ!YK6'_/ELD_UX[M\DB`H<$;6.2&^E_K;Z -MY#K9\FI-OGP7&7:-0I3'!$*;+_:O\2&@])+U)RCO28+8>S)^SL@-K(PD,!H" -M]LT&_=&=,M)3MPM&]I0E;'NRYP3$2036\Y$ZN5T%W]"HNR@10N[.P0?\,QQF -M%^F=GZYT\:_>'2&`W#C7;7O;;1[V!WJ32@"3*I3Q][O./2P0ZC"N2P-FW5DC -M)U*(26K:5J)B8Y+XYXO&[!X2;R3^6+7^D;!GO^D3M+1"?0Y*T02ZV/QU\YNT -MZ/,PZ\W2CFI<"R;/S=X2V)`5FWS<^Z_]?7O(/^Z4LANYOC)O=">L4@2)O-SQ -ML!L`EQF"/@.UP""^7_7:/ZB=?9;$6+/66^MK._9-/Y[^*!NK.[UW[##V\:P- -M7;P=]-V0 -M;,'DRPM0!DDLICKDOQ_CET%:OV4&"PFK7N'6.I[W0'NAS4_#8T&FEW'#(*/P -M5D[O=9JC,,/2A/_T-QD!*NJF-N/KSFDC!(%PS#?!*7O9#KFS?]Y;'BL[S:DTT3 -MH4[&\&^"&A:@$EHI.)7MF,?L6`L16'4R%9^+P-0;N'=['XA!\5O"]3B,1&BIE:^@ -M:$^N1/C=Z1#2B$SP%RK15G1H"31MM]`NN7RB>'S70?+18:G35:#9$@`3*^`G -MX7H'D\;G\OBK6R\1J==Q`V.NU,JLU5$VB]9HN2IK*29YYY#%C>+Z\74W427) -MGLG8GIMI?C"?3AEL`[K9/&$493'?W[15^-CX_OC^'!K80&@PB1G!D-OIPCO0 -M%F?R8[@%+>4HFD%S]]PD;&U+,+E+'^EI^W&Y@Y^XJC`B>;I/R(D=]7\5DT0D -M1IJ7P>4JSO/+,EE?)NGL?;ZS^G58='G`+QV4NG/]9(Q"BMF":3T;@^/O=BBU -M7;]^1)H,!-J",Y#+6V7KU0.<7=6Y>)1/*\0!4X+\&)V_-*S5]*[N[$4>998MZFAZD3IOIMM\@\B% -MT8([7"3_O19;,4"4%FY,$`E1U^61Y,4O*N.5N]>J@D1D4+.4^1W01.[0O)IQ5HJ\#)B^]CT99C7)-"U'"`_ -MP432,U;#VH['PRET9O%9(@\#XG[!A_ZM0+G]0=G4BCWP/V6+@#`K&J.CDGW^ -MC^90Z_5L&N221C/J^)!ZUV2[9]MUHB'KC94F;&R-@%&]BAJH?$[*%';FIW40 -M7K!SO6$]@L*X72U'Z2A!`[5); -M(GVY]]8ZQ-^S>P&F^3&W7@Q51)(6:6ZMZS0N9Q7.M1WE>,CC*]MF).R?8*M( -M-A66E'LC2R2#V&)X@3-/H!&P!QRK=G'?1@9V?4_R(U,]_\!MV##['8S?>2J& -M;=QQ2^D,5JS)-HZ<<$%\<+8\=N5.:$>HS,!HK#`KD3_QVI.!$3*XO -M?M,?MRYFMCES$^SB*UWU$=[)K2I&71/[(=:9^D[*/2E@`[\R%U+N0WV4NWQE -M[8D*`>M:=3L`=VJ>9:C8?O1%UZJBZ:%!QU;*FZ5*TM8*HAX^1B?JU0.GAPF, -M"IB;RKS>F9DE)M3S)Z0+QO=IT2@N@,4VS[&VX*MPU2(IBPXCO89'/P$\OM?3 -MF%*%$WG'SW&:^@_E&WW].X@$M[Q1KPW\4^4*VL=JEFN(PFHKEH?$>6?KI.MP -M7"Q!;6`!P5%G#8KH`,"DK!6^PB^1I@4-YYK9K/ -M(Y2YG+A&B<%#?T:KR4F2<-.=D'\-K6A;FU(*+\9+L>MC_=9W[IIZ`1MIF2)]:,E&2<`9<>U'^>+8`*N -M]9`M=BL^-SQ&%HY`N9R%:5@^OWHGQB3S6_'(-2B -M?_6BRI=VNP1VEZAM7]'/K`"JP?2D1)B.?`@<8`H&/Z\%W@B> -ME$+X5SJW@#^+CHUJD"MIR'$&\QO**"3VS[$G23$ZF6FBWI],3^MF+.T/OE.N -M,8&9#,Z1OPYC)4)$`6ZCO&/"4$A9>6FMHF7G+Y2=MP\BJEVOK=?8XR^MS$)F -M<[$$';78[ERJ68KY]S@J"0+^MSC?WDM[[SY5+!46GLO8I4\F^GV_XH1BT3R_ -MX/-A+8M&_`GIW9SJ7#?YKP>]`)9[):U`=3`>$_E&]0[YBP\LH$EK*@V%L>L\ -M;>0FTO7(T8_S\YD#WMK"ANA_H['4H?6@0))Z3?6U` -MM*3;).\PXAVQ>THB4M)!0>K5T;A"CZ>Z0UY#+V%\""=&TN9.&/QIK]TXJ%># -M_@*-_+/X)M.#XL](?@II-W+K_U"02:NFO2)C*.F9RB86&\C?NS48+!LS$"@M -M)@">2B`J:2.="E+1I4$12F)O\TL8-0PNF6=O*/Q"OVD9)I3#Q,W^93@BQR?B -MYI7Y,^%.)%;RVPAJJ1%Z6EB$5C8MT`ON`K)83A##ZS):LRJB@/%47`A%18V@ -M5,K8PM=-MWA46,Y7QDJ[H8==/%,##XHOUKNU4@%*CDRLZJI9[D$@N0 -M`41`]]UD0!=*+ZZ5X'>K,3!T7C73/U)_.&XEHP.(V3Y>0;%17K%427'-;^[B -MS%;8[@>`(Z*1).%XYM4C6HDN2=M*79]7CV;1TR3ECZR8@M6_HFC\L0I)1]A) -MC;=WLL[>/P?`^MH':>AF>Q' -MHN+/7,Y#R'.(_$NX]@5U"+]IX3*E5SU>#LOFWT`,8-?O_6\K;S?4JG$4V]JT -M5E#A67D7?Y%YMAW`'*7O -M(&QJS70OIH'4V_@89<"(FY5S[A_(KF=+W1T&"N$>JMCU:*Q^/M#WUPGK)FQJ -M-ELB&`$(#MWO='%8XYA4_:WHX+&-+6DB`A"*7ANJ=3!4[?*T`W[74$,L75[& -MLT#259,X4T9./8]I;8`C]T(FI/1JG0,)&<;N@O"QQ"DE824;9;A*3NU]MDP[ -MQ/0?$G5&0$T&4-F-S6]YG\8[].B;)T3@1XI[)()O&F,U[!BT!LZ9$(M)#DGO -MW>PY/]MV%9J00EWD61J#[.O0-G+GC%*&5%IX3]_4+C*_SO1SBOCI";H0&`BR -MX*[XHP[L#MIUI4B&N7V` -M:J\@X71BWNFBCNM[L=N!77`I4;$5$AOGTD\H%NER@7)[XWIX>\+TMHO30W1` -MM,B;\DO@4XJ5>43IZF1[*`*K3^;H"6\;('7/V1AM&LHXW9] -MP>6%$/WA4@I7`8PJF!]G-;F]G;6MM3<42X';F:\6FWJL\:8!B=&W!G7VC+M/ -M1K]:066>:!?OQ*%)1F^?+M-2-!7;K9X`@YLJ*^!BR!]+``0_X[#@9[FWY2?) -M[M5$/#>^])C"?&?=H\;J3JRP52<,>>C<QV;Y%0C.=-&OZ@7O> -MAR7JDOZ4=NG'8<"A.XQX$=^J7@0\RF=1K[/TPDAH^G.K>J7#:&X][+M_]F<-)N98H0H8`_8>#,"JA9OM2SO9"H -M'#6-!935$P.!PZS'+PS]\CR`IZ3[.(@($0SVX`[F;+'N;-ID\6/U*P?3P24` -MF-$AYI4INC_](WQ=J3H(7_M'W>J8(/ZSA_"]P<31GFOI`-LQO$$:`CSSKR9V -MT4;-N?W_J5!QMX*FC6PIBK5/1>@X^((1?0^/?R1$MGO`B7^E[)7KO,A^U_`E -M-;PRB'7LQR3=[5_1A.9W\`0OD?V:%,IASL#=$L^[J\MM6>0K:FE2OS>Y#X10 -M\DGG-T"DV)^%^!@S4.:L@YQN[&RF3:SBVBP=1]ZUIT:33M\`*,2A -MU1MKCHMG#A1?B*Q.@\`!>UO0C5=B_$$'[]D9/N$$1];*J->JB$XVKM8PE25U -M#IH*09>V0K14VX$B]T5AZ*02WL`-8-+BH))J_Q_;P"_^];HQD2\UGMM6N<`% -M)$_Y@/GSV1C#=,[X[I&]J>P$%;94!*Q<16H:XN2E@Z9Y;'\:Z5;K-BCD.$,> -M5*]BU.?_,`>V&*]*V00>R<)T7IFIJWN/5^^%3E&(ZK0PCWTR-I3U9FD+4+E? -M+J<,PM/I/V&H)ND6D%8=78MHWO;4PG8Q%?4T2B_2=:?QV"@$8&MNI@C?`VXF -M:NU,6U@QV/QR.[[&N"*8W-+L!KTX$=_/ROZ2&73[%)138_H9]"IB`N7LJ^X/ -M`J@HCK-ZP.ABSH.QKH&-6-_CS`+1@"#;6F$ZFX+0T*RS@9Y.HOV[.UA/[LC# -M55]>H^:E9M76-%U#`F^>4SI5CZ/QI)@[\2="YBD<,R>3N>0/,0.QJY!R+ATU=4GAAMHHO85FUO$:C\.:6Z`4?!T[1.4EUUFKTG_J"] -MP[`N#ZE&SPA0O`HA@1$D\IS?&ZZH+U$+[GX#6XOD>Q@#]V%W)2YS_`%&@0%D -M(8Y8!G;7!6&NS8QK0TZ>PSPN*!)`*=:_$LB@C!N.`*7;D+,9)Q3$PV-VM6C' -M,Z.'$1DJ&SL0^R_R_+$_OWY=\ZO&+@\VU=HWYMBGP4;W+FDDT<\L\[W"!#]N -MTX9!YK4N,%\>J/.OR,X?GNW6])N#I_^K\#\.Y:ANX)FP4D7Y':%#2\0),3K+ -MT6LH!&T6(=(5\EY)BBZ%)ZU>S7T^K0+IF>8X+VB+6!C>@=/#^]URE"U?-A0* -M;]CH@R"*KA2JB[JWDG#86]*M^JT":O^6QWW43$MC\9CJWU"66=/S -M_3TUT;YOK.'LCFO>S2MBUXC0\9RMB+XPG+1)-*4CR+4U;[KWP5P0:3>$@U\( -MX\[C3"\TP`8L2,W(A+N\*_S5%Z%_#2&TH_DL@91VI^JT/J,?,_$(1LQ?GW0N -M[['>(_/"B)NJF>Q#7:X-JFNV=H*8>)[I1%;PSP'^ -M`@8*&L@[U3X;^@EJOAA%M)[,(1?RH<`2]%_V#BY"=I*P`8S%')SB!@^^-E(H -M\+ME.B&$:&Z37XBY72=WP975_3!!%@NQ);5R-0_#]3M:LQH)T5QD0?Q]Z<$;71P@?K^R,!OUCYG9[6L9U%^9(K5*<]YOT-@W -MW.(>&XA([,.MY#J63#E*XZDR9#1_8,KZT.M%[#'E]G$:]*GP`GI:NC20$HGF -MAJ^^XO./O.?EN;W0R!,WM-/0U8'UPT$1X"BE4QLWIMP518>`69?B0+K]^7JT -MO+'+@9=S/4P9/^O9JZ^X[L@>O>D:40-`<$0-J[O_&0QUMTS#CU`!>QY`X,+5 -MQQT%5!NUU[4&3VD9#T^%IVEL;EM89-L-"WB=? -MZG"JK`T*M4>N]B`6BYL3<(OM1;MM=^I/^-*_!??ZTN,+O\;+"(1UDW&[W]LP -MU:JRGMW+TK-&C\J$/!Y/D#4XP&2$O8F#*._V"R;Y4GG06Y92,>'ZLA?OR<%P -MQ7'Y)0E3B%V$7M$1[F5W0`##Y2PI)>IJ(8:52RK_$=]<`K6,+>L$5#\A[C]# -M8>>-W_:FV1NY!1EG\^;'RO_/=<5.1[_-&N:>S;E;3_#,1%(.7T(8L*%&;O0G -M?>'"6BVK"EB(C8;?MYCZ\B-#/RCI">HE0BHB_\#RG(L?Q70 -MSC@&X8-AL7IY/38Y_XX^XL"Z#WLW4C"U1)K%3FH3G-WC;L'H$G]AD?E8F9\* -MRD9\-E8F#'0XS1&S]5E<&1P%14V<+LFF!,4J@B6;E81`LSXYA496@YED(-9" -M]VPYM0RA\J:VD,@&]SU8IN9EMA7TID+:6`7H"$E%<@*H5>8X!Y -M=1'422$R]`DX^["!]^,4X&8(,H$!SZY0M_O#5!Z"'+C"*G8=?)QMEI@U992[ -M/YOW7(HD;^22FM'/7-@".A@UFR1X*T"%2U@KA[_EO8M^^6(K@=@,_U`7 -M/_@$?K"0RJR3BET,\W>TAJ7SUIZQ&+LGT#P`PF:GP'F.K'LAJ5)3NNV(*4A> -MC%^X0XVQ,.;#25#E\!_^*M8><9P,@`' -M\-"7OF"W?JT<&%5.)0_MQ[^DXP?D+#1R<\X?+;YO7XI,^`3V$UO&VZ\)=&-R -M_O*%H98,`,5Y3G[)7#.#]EF"#N]'&*>\Z6FN&'9 -M7V/M%;G?G*J,*Z,)C9BMC)$`=O2S!:2@U`DLR\%Z7\T4+_,6D>PPU_@5YG]+ -MO)7BY/?Y?S4[FW\XO8[GF%?S"K'_$Q8'/(6<)&JAO3X:NYQJ_8_&'Z"5U7Q% -MT59INXA'TZT7LPB->Y.NUI+&M+M;>^_'<,X?PJI!D^ -M-LK>4PHL^+%R/DX3QPA-S%S%@M7;MN#P-Y9#\?1;[MQ'O`6T[TJHBR0!=3;9 -M-9"AR6*GWL)KG%($O+E$(=I0O6>EXAI+WSMJ0,WA#']3LS<$8GW&>UPT -MBN.X6.S1YA=UC%;X(B\GRO))#XZ2*#''+?;1N#S#'AY?[Y_H5V4F.5!LQ1JD -MRPE\`PSBE+-M`08D;T!].E(ABG.CE@L'A&O?6JJ#3I?5:7;PM`B:,9).M/ -ML@?3X"[3YJK2C>F3-6SNI]FN8J!I=2FL(3?XYCO7'Z.S^%!_D -M8TD*3V6*HQP3[N2LFDHO>+@RU^J8GF*?"]:V!I?V@5/W#UY;E\, -M>T6`"OR<1;-'+JQCGK`'%#HFYL+]+:Y:R;TEIRCV(;LMGJ5EQ9A'D5@VQC>O -M%/,\`A$Q)-0H00,SP%`>/[$R3ZV7N.:P]1\NA!*2OW#9U5`\$YY,H:834HIQ -M9L;*:3#/C%A3O]E4^CL@.(A,^F*[S%I/RUA)!'07C*>2<60M$HP!Q%GWS>/8 -MX/HO=Y6#IB<:S<]8_&9D_8C&0Q+ -M)'DVI]5>V<_"S,`M$(8)#)I(I!\&(19SG)_GD@2/G#/9T -MH@O+:7(S(J=:]MI<'MBWEYHQW6($0U&P]T -M_J5_D'E5<;\[<_QFC-./U>UHB3Y!=$#<+)20V^1,CS%17G<:TI(%Q%@\N`HB5^`SD_UEZG&9_X&D_L^KLC^E.LNJ'"" -MM,;O3SYO9H.N,#`3K,+22Z)77;QM\PCI/ -MC^'6)0%(6$2Z+3[.N.!>U[^,7HH&VR0LGU -MR66'G!(@O?B#^W*8N6AI;-\Q&A_$88!RKS65N&$:7=]Z':#^=^%&64TMM.^9 -MO]XY;9=;AP4#UZG8,+LB$?]'4/A<>1T[R]?!TDO&M8_E5\-W(L=ZXPURZ2`Z -M!<"GHALCK$J!'MN6M2J8%2+F;7@IF-U$'#.%LW(30KOPU3?I2+$[Q2$?#3BG -M:.\O]L2&3ZUEN;Y/#/T#4I4GV\\L>!5\""D)HO[1+]/-!#%RB[AKA6<1]4EB -MGI(/1WVJM$9_&>QOF'92V0.V+]8X'D -M/^CF,:-V&8?\]>!!BG2*YIV"^WCZ`(U&V],:'Y^8@'#7Y%Y9& -M'@"N&+7"GRZ1+-@:'9RR.,#Z$(*+#6GH'4;SP\$VC`:^.*Q8?J;VV'/BJ"PI!C.IW$YZN6_(!3BG:4;SCKF`%4H9H,$JZGE5858B9BMH)2@0 -M(3\F!$U4;L0;57>0[_<\L$]^D^4^B*9S!G2E>($`1!8\,NW-33W!SH.`M+_Y -M39.#GG1*ILC),Q`Y^IP9,RW(=`\>4"&N6%4@DN"_,B%"M%63./8>GKO9-FZ. -M(H:R,U(PSJ>SX?%4#.4./\'>0^!D3#`*+W2_LCW2B#$FSBG;G`Q4HC92ZTL&K>5V!@&5Y1A9U33BUU!RMZ.[M)E:_?VEXK"E1>IFU? -MJE/@6S_UYX,T=DA7RC\#T,Y-'_",X&3KW]<$09-R?\JQIA5MD>:4>W?XC1UZ/K8:1[1@- -M5DC/.*:-@:P/2EQ65;W/ST>ZW36S^VQ5F+B^&_V/OT]S2?8#E9VL(BN])"=4 -M5579>].L8E2FQ1G0V=NY-6C0K5="M7R14O8T\#MC5B5$]%Z\19QM:-^M''&# -M7WN$WY<.H/SNA1J_?(*;TF>&--$S7(46KA<4P60A;2-VW$-@6`N7APL#79V9 -M9YE1"Y9U'KU(\*TF^M@=N:P87_1$5^Z -M/:M@CEWZ@Y5`$>G0&L6HNHWUZ;2$OJ5>BGK.NF8+8V'`FO8ZUTCB+.$29!]? -M&]*.ZG?"E#2)5UIZBI_9XH2>](-D!:=W19+,1I-_(-/-#2P^>4&U0?13P`S$ -M_W5+Y=V1N1LJNA/_T`^!T;W%?F+>XL.JV4G<)76!9*.0@Q.HU6%!/.%5#!3# -M4V$>)P>,40Z(,29AC,`"$O@;&;LG[EL"LNUXX:XVMT\K/H@3PH11L!U!XF(I -M*V?:O.`4$@WEZ=*<1CO3+KB:L1M2E"!6ZWX0ZOAJ(3+N -M@+E1>>BA(X7QYPUT.:R&_.:?6WXM)^D3G68/KF&F=EW$%"12`>LF:26L^Y0O -MTY)_H?NG,H(0@1']11W6%`@E%6BRSV485@YQ?@-@[O^:]CC`.]VX168@>@K: -M`EKL!Z!DX(\A2V#<75D<8-+?P&2XN2NH.UN!YEDUHZ387+GC!.O;&J0`Z7Z< -M21V.H1I\C\AY4*72&<#<#(VO&Y3]ERIM63>7J/ZE^/DZ93";:Y';2>OT=ULH'2 -MOMV7V]=IRP8PE+NI*>>UDL27E`7Z6!K)/5Q(;2B@\%R.\?>F:#1F`Z&_C\7RA3Q$9'(6(K,H.!`A1K+O/Q_<32.O%>X09[>(T:`EP*J&F"@7-#%TG1I;2 -MV[UY*G+;V2N@F!3)%$E7=^.7M@JW8_M8QCOK#B57E8D"^HO5086,Q*;K-Z7X?CJ45W%O<@XG9^N49O7R_&>6MFL,\BD->4ZS -MZAT*=M#3]5`O@>0B26ZI2FV5%;26G9FJ2WQF0@M@VQ_Y.?IB/MLWJUM_7SF_ -MF[##"S-QN)?70LH&57-WC`&@5H>X66SU>;/Z+LU.P*W59[!?5W#D2RVP&3U? -MNU\@JGM?5!']I&6;968N=A#9N=UC0AW[R5_0=BAYI\:7)I=RM.W7"DVT*27; -M^\Z\_*L8`!YA5)YS#+&97U;!_X6:MOPE%A;'8C]?%*[_O -M3"921;[BAKOG5%'@7M`;!18(_7%N;MCAS+]/%^''KVFS`AP'97@[!%`+9$CX -M!\=^81H52(_!A5E\`.'+>DM3[OAFI;^EKCG]HM._PIW?FH;J/&;.78?DO_5! -MLG_FS\87NJ["IAT*SG,%H -M/J,0X?\N4,W*./P%S>4)8_@0[,."71],G*V?GW^0=6GD^.O\[_^DRK+HYX'V -MTO,IS@'-NB5+Z92H3"YX#5"^3B1-Z.XO7O/XLM:\O_!5N;N\YDJ'%7 -M!S;BKW=S]15.93Z09:N4UAHZJI8Y*QK.HL?%QN">3Z_PA3?FYO^ -MP\;6H,C[^L@7PW!;EO!F)!6P4H_G4(9NO8S@[41HQ_;VO$X+8=&/`(!P*,(L -MS35`]Z7PP%-<01)F>@(.=8*'N^!ZHU>P((@1F2=Z$U.`;GP)DE<5R&&NT(O/ -M(%([+8M*O#RJ@'6\Q&ID32+KCOB;KQGIEM1@PA$+P=U0N_DT`/TUC;"4.Y*L -M;CDC)ZD[_Z+!1N,#=ET:F&XH?W]NG8;4>79,\KHF>5%L1U$>EZ+Z`O"7%W-/ -M_=_.)!"(;N`49,H%V-;VS2719#.,51O'3F,`SK^8M9V;+!W(\8AX";TR@A24 -MBYAW8,5T#F9IGLVLE-_TX9WAP"&V\PC7%L&+5X">2;O-08Q?+Z%/*A6'PF,, -MTCYQ(G8-0V4GD),F_//B<$.H;K0H-UEMJR>Y1=)5+B\[&P[S1,2_.LOEL@;D -M:OMU$[CG=5T64V[,MTG! -M#15:?'OH&L`JTB[R=/`5094%4Y7B89D&R*H`B7/WY$RV4.EB)`&4D\^G1@2/ -M\?/Z)^*M3`R[N_[ZPL?0L-G'CG]L(38,&#]L7QHLP8)R,BC"DSHXE;"F>"=1 -M?P&K(/7P#@DVH)VMD$(13O.IJ.\AF\.[%#MB<^`I]27H*3"P`&;X:I:FR7UH -M>NZXID?P3)!.'+IT*)>>-MD.U`J*3=#"T96"&9R2#&!7"MLI@?(&&*I2RI=/-=8@#/2.+LT^3TC"L"[$'"_S*(+KZ5:B -M.#F$OR:2GDKI"(VCLP@R9@F9A`T)AOG_&D+LEO<+:?5JK]I0<\?W@:L0KV7]"OO6-X-2#<` -MK?"8G1HI1/0BF!=!L`%S\!.0Y=3E6#>%QAR$I!Q+V^Q)Y?`1(X6YJHHI)85L+;J"?K"RS#]/#*6YR1 -MI2TG/;*6K8Y:'U1V1":(#M+8'$)'M4_?]:;E.^6B:ZY%)4DP\%J0^Z'E^ONC -M(/&"]AUP87%VOQ;LLH%@#<[_^*JG;T]USM\_=*,LE21W%^U,:F53)&BB=/R# -MI4B_W8&*UJ#HW5.>8ZT*Y*`I8W&3G.P\!\0P%%_,S#>',?``.\]`IFK![SO, -M](J=@[JVK7IO]HI1O,=(;]H>#FG"V6."*=V_@$K58,DJJ=_5<*MF`^OC8$>( -M03?B::_%*-R'I6&:$F2#]Q4H?2SL[S];A@>B+L)?]&.C`&G_X6"ZH:0]K^#J -M_QRJWYF*U[-:=$>*658BLW`A"?++`^J%)79P]>`W.54H3#H]1^`[:0%^"D,/ -MHQYB#K,+0S.3U]-.K5SN?`AV@R97;"OC@#H!EUS(5&"#OZN)N':&]O<[J`7D -MX7`E]LR_J-A1L*!\\\B%EI;VYWNT64+U9XG70?Y4V]HHIU\70'2$..K!KU2@ -MR^:ZCRL;9G\4R8N0*8;U'\VBZ^ETDV0+\<%5C.DCYS](K3^IO!'V.Q.^Y@)% -M[=I:78&L.9,2R?>AW(X6IC:(%C/3Z"71:O_GU3GO^E"A?S%\@C=&GW,:!*\) -M"P$>@9\-4C-ONN+>R&5IWXU:6B\5L6=[B%@TX3DF><8;6Y-/^Z$R0AA_V-M4 -M4J8!+4<,=O)"2/^J"UD41]Y=-\ZV"16!H`)&>(=!\\8(ZP5OLN\RQID?C992 -MQ7IZQ67#AE73Y?QK)"!30I`@NS&/H$];UC%;"C'C46#2V+E]W4N"\MX)&5(U8.M+T@(:K-I8;="SW_,/O",'[!]Y.1DW[Y+/`HDDH3" -M5S9%;6.`7-%@_D)B1<`/G3FC38-8GJJG@^4-"MO$@"A0.1UB0WW?Y9>1ATOW -M_L_N@G'G`P\&O%5;@.[^>]K&OU*&/^+!/ -MXJ'JZ1OX-E6.C[.];&V&4AD6\#F@F^%96"\A@%N2C.[C4*5/;T+Z^.#I69B* -MV'*N8L&LE"5%#.>,"E="J0%/D67\BG1?'[X!PEX:L]9]].4/*!HU`4>B&6>@S9QH["6$L1GQ5# -M2KQ9EE_BC&(M2,@G>@U%`K1>]0P>IV#B(HYS2<\-VB(7T2"'W0B\;+Q._T80W$*@$8SP`$9PC):JYN(:-0^UZ.MIQQ6&1,GT5E -MJXK_LXCM?HGC;@8"L%MBAN5O?EK,LQ<*,^/?J:/F`3DI=/B -MO`*KL`C>V!=)QYR/_EVS3UO/B5,]JY7(F5;GK5M43&O'MIR -MU_>E95-&81=&%Q>S7"Y0PMJW*--R_,]$-!HYNL,CB'KD9GPQWF2Z5#Z\TA*DF&`%B#-@.YGXGID2;I/8C8* -MLC/Y56_QJ\1$/H$+043E]/E,Q"&P6XY+I=2B&E9]MHQNP:.M@`28C\K]WQ="-:\6!3 -M73=AUI`N_J0@ZS4LD>?K>D/W2;>`/\TY;X!G.!GE=7=:M4JT;`G-/[%;Q6*CI@Y?^^_; -M8T/*P5UP#+_Q>]$;0?ON,(MH?PUCPL%[RZ$\DBEZ7#A>3T"*UV`R+*W:MAH/5I.3:`\`GMS@,J7+X+4XCW(Y:9L\S-HZ#N=KJ'1KTCGA -M][CN7:Z\.8!MFR3BV-[`G)R)IA2)C8=A,%VUR=G'?_//V(@5.2LWW)L -M<6#?(4:/=)FX3O/*V$?UM,NN23\V(_NR7UVSU+=&C*E'.;=\2'C2R*-S;C#: -M2)G=]MXT.))A36SK*,CJWO]?N,.`424492!2I$Q0V')JP5Q"$%-_H6`(,Z-<'H\J+Z$<[KE -MK<+<,!LFN[5,W3A0LS>](/F.!.'=#3(_Y;K),I%8F1!F!#'#7)O=$9N-@TM4 -M'"^8EH'#.OI%:2D[*3D:CF6)J@=A"R0TQ``P#L)KI$*17*P$X*9S4S0.# -MJXA!T`)2;#F49W'\I_YG&4X4>%>-+3`*C.NJ[CX=56@'Y:D7RIQ]D-FS;,9M -M`L5.=$F.29L#HMKONJ;FV+[N7`W<9S,73G8UE8Z;XM$\!U`*DI`4` -M)+4B$F4Q$;I=R/L"6JUA.Z?1$^$##AYMX*K,N5>P?SZ3K\!A[WZX=`;/:2S\ -MU:U%A>\#R/?9"/YR'>*/E^0+WGX^MQH4CC#F>%5\D]\L\?HF<>G+5JP%2-+]/**+TVA$;)064"92IW=> -M7HK#H)HE6C4G:P$;ZW<-"^EOJPI_YK#A?!#:"A]LFBWV1$3KQ%4-=]#R<7GP -M5/'^A3.%`4QZA5S`/+J;ZJC4!Z%QTEG1XNTC8TE]YH22.!X"*^;(R(_ZM4"6 -MS@1UD8U&[D:C`3Y\?*/B=TM,*.'_I^./;MJ07*<1OC+>'7L'H<74UT3#G#;@ -MCYP_])FE$565,#U<(Y+7_N_._KONMZHJM+B5CH$Y,L?0<>&!V?_$6<2WK#!CW'74 -MGK"QHKD@-&=6<,1>%::UL,S((.F2[Z?\]"'$IU=>,QI&9YN# -M1^KU"U5V/&S-X3?2)%M,W;T4UPL7SG?GT`0ML))4$#ZA+SBTARUBE^916 -M$#ZR#]L^SHS@63=S*WGH1'J_&S9`LI5]G!+6Q-2\6H_M;S0.&/]JODECP@?( -M"I1*$%=R=XEL.&M6EK4<@%9@:`BD_>8T58%O9$DPPU7M.\^Z*M:UU_ZYUNG: -M$`!UKX6=>K3(QZ*F>$W6R?ZO_.]M^(+_>226HP#(\EXQ']KVL]&G")$!7&X- -M<-C>:VNR$U\X.Z<"#]2QT[E#;>R=JG66QRYJ0:;QBU$/]EO8V[P>*,\E(X76 -MX-GGZZ7'[;/"JG@NV`Q[\0K**A=&?E%I^*#1,/_Z2-C^&-3-"H(70BLD4(@$ -M>QG%(`+CK>GW\.-/"#,'Q->)[<$X6F=S+2BU7&;Q(!($?X=B -MI2WNI,S4J4#*5_(#5^R-2XK,E^NN`&6A?;S'[BP$G(:S&T+T%3)@(6!V> -M.)6-0H$QG&\&9E*^/<6"9?@XH]BCN[9IU#]A_[HD@OJ6+$)T@&1)!C^5YII^ -M(8]2I@".&&,T&"_VV>[FS^&)2R+5.?28V:U!%U[G^82H7/93G9%S]=F[0#1D -MW4U+[#7G3\ZLU^`D^6M(GO`\X$(&)&#C40?=?2I)==M_/P)212&A:"Z3AQG^-"(JN#.IF;ER7X,*P -M.Y^4#4=X87SHXAT-LGUT5YT_D1F#:M(.B]QDT@W-K`1E/W76"%AF9^T`9Q4( -M:VF#NBXHD&@T+$E!C<9C2>`.Y7+2=$*%@!A@7'Y4+6O;L'7G=7]1IL&6QI5> -M"ZH*^Y+O+;1,\W8U5'>:JV71)/AX5J$E)BW[VB'G!T,F1#OLU1^C`1B%5Z@. -M\D'M,BRYK6W*'$DM.Z1A -M/]S6`18.XAN*Q-"O)OGKE*6(@Z6A^$';!EK?\Q755`+V'EW,>4NAB13K^%03 -MI/UHN4D.[N;C39'*#=X9(?/6/SC`7CJU@T"#K$"@8XA?CMWYOXAU-20M=%D@ -M%@<9XV0DEPH@I^;F&1Y(/P9`$;8UOL40=WUBZ6Z%P-#^@CR'@FVJ9G7OA;YZ -M;#98N66D'+[B@$?KP(KJ>:5B>0+]R-GM+(H"Q^0,;4/#R;V;7@@ZN]/;4CA6 -M.3UW\I\=.9R=V9Z0_"]%6OUM4N9@,8#K?W5^H?8'YF`=MZE(17@FX2T<&Y@Y -M-7@S>'ZMAG(80#U#TOE!79:/C6`ANFS[*ZXJ?Z77TT(R>(G<_`[6N>_W/'G^ -MBRR+=4?N$J5)**@BUV9L'CF[+Z;+QL(XQE;-T]^J08UP++O:)@X%@N2^+!,; -M9J=L%AJL!AO`6"F5E;C;L^?$3<#4%@(Z25I.:,'DJ7ZVV4#$33HO)(/-!^B6 -M)(CJUI_%)`RF;+UEPN*PE"D?%ST[Z\VJH/5V\LC@X._IS<8>>$ZL"/TMA1&F -M>VLPCHSZ^]\JPD__P"HF"1`]#V13S"1D?(1I4:8]KQ0P@EFH?4!LA?Q&K\9I%Q4%`A% -M,[=E75`*D,/YFE0EG8!!?[N"SC7VF,&%!%EBL^Y#+G'>X7\SMKL -M1+QD9+6-S8KN;.0!W/U0V=$_<3?RUA2[`BQFU1\;=7=?!)8O'>?JEOEX6+D9 -M-M:'C.&S^'+!!,S6=W9'QO^:F:4!?P$?RXW&)6FD74J),L@G<3VI5+;OI>*3 -M5K"62E&0@^=/0K@J'8>-VN617%XX\;31!Q4FW0MY@,)M$W46'WNJ6X%5E!'_ -M"@V*N3\91#N?MDW*J@3=(H%B39KM?#YRCPXPX_?72+%(WOCBQP1$#STM+V+7 -M3GM.`CNW'HS>4W&CS?VDE$DI.R)]R'_A4S9'&AJ+IT_`P_LO;?O([R=Y32KY -M\7_:'2H8\\E7WS=`I5&`%D-SEY-2LMN:)]MXO#IZT=DCZZ>VK>#+R:C`$':# -M4'MUV&(TA83!F2Q+,W^I0CF:F>I#8^NOKY9]E1!;5=8(,TE@H'#RCJ(4#<"1 -MJ[6F33GPJ4%R0)DP^9*XOUA%\T+(XK?F(QR`H6TVV6-?31M]!VYQ-.ET)'AI -M=*V2"4=P#H^!O8JT#QGK>L&!WW0JX3[DE',BYQ15< -MT#'-Q'&^5T9,M;V-%5:/:91W0'Q;4[]G_+GK'>3` -MC[^]9%_#K>^^TSF&OZMIWAMHV^[C^?!:0*G!0?G$S11HM;GV3/+S_ZO'O4]C -M\_5LN%XPX,V,_DF)-@>R$Z)VV9U3.IO-&E@W"*WF;$6XY'K9BJ.&24H;6,\C -MV>?&+W::@]G'_&\L&22PMR-A(AJ$PO*)Z&RA.82M5&6[IMT=KWKKO+=IB5OF -M"K@N8)UF3*2QO_5`W_2ID-?YQ-V7LH@H_[:+;4][&2M+:T]A(^-W -MAFPM4JUUT;E[:",;0M#N84Y(-9RN\1R(H=,QMD]9CZ5RKGN!J2:NR2^2(HC:`K=.3W\=W-#O5"+ -M*`5CIZ%<=3P.%L%D?OG\;Y#>XM'CN7)&`N]%,PKZ!7B5U\!$4$#OJIL+.L95 -M2Y3]E(N:ECYX$T8"VGEK)Q1!X:4M]Y-W\&=%BWR0DG,5;TC.#Z(9`FV=(PMY -M$%,5/0;$6M8*J)T,!Y6)CVD;7>-,HUIWS#TWF5/P7U=-3TF_3.U*6JNR.WT) -M;NLVYW2OI2QR5$:*W8>S?1=ZM.-RDO[<8!_SG:=">ZY_J@SL7ARVHE_W6/ER -M5%'Z)GIAUV\RT+-K"JP:)0!W@[3J25T_$3W'/2EFM&I_]=4\:A=VZ:W-V]T! -M@,__V\@#V2-TVE+4^&W$NK`)&Y>6G]SMZ9K(5LP_$/ZGSNPH9CH6S1MODF2' -M4E)JTB+IB@"(8NYL:@3M5`\;X=[K9DW7-:^3/Z*(0-E@8=RC[ZW:2W_5&&?DTGBBW%W\[Y32LO$2J"]D3G=[L9N'2\SK(S78E"I^- -MU:L*"7=,H,,-$=04J:71!!A71KXNE8&XZ<>`SMKI24+KO[&CK)3X1^EPDA)U -M!#JT(6%KA+:%N84*6B`JT+\`YA@NQ>'-J5GN -MP(@"7'XM$L)450DQH/X>@DZF@(RTH#J;[50J5=(]9NU4R1*+A7L3B5/H@`JK -MI_UP'.+.63+3(E75XN=FL8[# -M]WR):9VLJ&ATPH-G*6?JDQ^%APL8EP;8V7]T+#;R)V7B+EM1HI"E.1L8+CZ? -M(/;=P0N-`6Z'89F(Q(:T=CW\A_5?V?_3@"OC,(:?I]QQP[/[].5Z`UCF$%R/I;S: -M<$GT^T\_7HET,=$*V+*ZBGHVEA:1O.V(GF:+1*B,$EQW.//*QN5)6XM[)"=^ -M!E'*8!%_D%*"1K,$]HVK?T_4+PG6P7)J8K"+O/H.Y`C\]-I/@I,_;J8'C(\DE)[8SQL^$ -MS[$[GO-]5RP7N[^@R-U+=:2:.^_F6$E^PH(ZVOQL\C>#!']T`/TBN7PG\(\L -MBE@G"?HIH$G8I\I^)!7T(A\W$IJ!MBQ;)Q^VOAB4=ZXY(8E\C^+`DNV/+8A$ -MKQD^:R-3$`:-A#'F.WA;<<9'E=9M4S^TF+7Q5"KE"J+K`_FNM'#=?H_;L,'C -ML1S+BRW]I=@)&,MDC?7$#-B(_B"XPW%^]X.\I6Z*P6>)WQ0#0_YWINT78;[_ -MC6*2.5Q8J]L&/K4H]J,@+):0*C?"C46S[HA?.0+-*J]HY4-'PD3TK4[EK^U]= -MF/5?D(WASZIN5>46IBP%*OW)SZ@C7/=4B,,RR14.0\Y*U_"8"MS6%%!Y[PSG -MV,LM:9GM<9VNOD[7HF]@5Z/=,G3%L,3P<2630=:9"#78;3(9XKES'%Y( -M1=.ACJ9XLK'W*1^'2;F849U[!=>9E'#@S+AYSQ)]35&I/%W[^CI6PZ:J@#'M -M^HK7W=!OD=RSX^LT)I./M6&R?9:"]7-+OY,6DPN^DFB5T@YQ&V+E> -M)OL:Q[6Q.Z&+S>^W>(%J/.P1*0[NWO4>)IK#V.XSAWYLKZ^/]H-$/5OYZ1ZO -MY)_P2YZ_+AZFI9`AG(). -M\FI_GNO=O3#2&ZYG+47'OJ&&+5^J+#&EI6&>O0N!*R]C,@M5Z)*5D%%H,)', -M#T<'7]F%2^*R_,1$;PS'>*&X,==W3E-O%W>) -M+,#A%(C[;2CJURO!,U>NX6H#*IR3-;_C>Q"3;W:I#&^]QK[+:")L&:BL^_X]6&3/V,NF9 -ML26-XDASKVX^S:HR6<7NE<;K":*+DD#N13O8;P\OWE17<(S.*^W%C7HM\SW(*AGY^9BC0OVN_).32J -M8MJH(*HTWR_UB>G&3LBX(2=IBFZ;5N`3"DG`;CF4O2X\[OF:T$4S.QG"E2@_ -ML&DD-0\R53A+Y%18GR^4A*IR]#BIL&C#6SW?I-&/G7XT/&$M39;YR?-=3,FH -M-8"@$'@&IY7$:P!Y,]Z#$*9K1X)6IN[[9[$%;1%9R\.)X5"^V`3+',,;[7"\ -MOL2H1?;8)4_:T.`>A1H@I%8ASF@UWB=U55]CF27X^FL^97?J_SE[\<,V!.QB -M(*G_8F0]1RA@ME1<2=SV1[L;]\)CU[NU]BI[C\[(>$8HTM(XH/3%M>PZW?DP -M*25:`#BTUIO.L:/]I;."G_%@<^!`!F0*N<#VG_*D=Z06SU3%87YMM#1#3;F1 -M8VGE.](,P@?;.1S%@ACJY),AX&[9>FAXKT1,1)#Q-(TU/$WW;QWW]XX)\<$" -M[HK+(=G!DF+:TTO,\LBKIR+%`9#?_G6UK3A,5V]IW5F'^:66H,S7Y/VRV^SC -M_02[C8%ML05L)8_BO`QQCG?K2E_](0";E5G-:^Q?X_DA:'YGF8[;`)OI%Y:; -MT7_&7:BI!03?U)'_E.C,C=X%_4&4(/1DX_?N^LR4Y,9CWTMXUUM2P:CO]1)I -M8Y_DO["B0EEA1$%#,?U"3R!ITQ$,*K+'##J]97<-A(1Z9<4=\^7&LWXV4SE< -M8ECD`I>H8W$NDV@A.:P3P!J27AWH+1:X9K=BF51F[4,05K:35VKCUF`JI#4W -M6]YWHKJ8I154*R4".0=2Q@.@9?Z)2RKXT9$G4HV4[?:T(]YDEL,7PBKU_9ZG -MU>D(DIPV686U.]PC"LT:G(]PSF-B`Y62>=^)# -MEF'(,D!CC;TJ[[\:<.A@_I"B.H,>G(D5R/`<)2ZE^C*O.M1JU:;3SBSB%H2<#8Y-& -M\!*FM,`7Q@->J87-_FOM#5+FIU<.9B0OR9S(++HXAFELR#05*1,=4@3(X1M< -M$4E1K)F93,0:/W\W3<*_WJF^U;FL5JW.Z8K`"6R>JSX:;/`V"B<"$EU9OEA8$>I50 -M)O?V:13WWP3=F+H7#A?UFL=1Y=*SK@'!^EOAE%+,@F84VJ7E*'A`FGW;[V.& -MO.WU]!$Q@I:4A=M`=I8"A$#[!CQ-M[CVY,"+"P36E -MV'H*MHE+[XVB4--HN>Z4)2X.8D;H5YZY$/06DK=UV=TC&`<&XWC3-RP0=',? -MZ-/.6Q&;#-I`_::6.:PI^T;M4&_^H"7;QR,E>$N0%GV%#&+W\=`7U=S&<=S; -MA16F1GA*S4JOK]FT[LBG;,7N@`8J[UP2")Z0F1Y^0@H1;'JS,D>_T"GQ#,10 -M?IGQT7QUC';5H6DFFRMPG+TUXRA3:(V>=+J:)O1,]Z5!;C4KRV2")'URQEQ6 -M"DEM]>^,.LD$#>".2AW81A$9PCLMMH8;:X6%U7"K,_%\I7ID.H9>D&96@0X/JK -MD9;4;^=J6T%\"G(>:)##D7R&;$V4HY^-%,7?^DH5_Z[_E[00'5D\FK9_U'W` -MU5B!S;O*:S[;4FM1N;\*=L@1$(P9*&-O( -M[)1VH"*S3E3I\WJ?;GFYJHN=5]K\BN.P9H@V8:^Y!SG$[_LROW:SK[T%:\SE -MJ^HH-Y&W23G(2?P.GR$\.B"8N90GB.#/5KR(/"BG(Y:HZB/WG:R^U5%+=Y*W -M>GNHA4OKH0V?V0X(@U!U6*)IXET38IV\G,IJ=P"$;RB8SCN`Y#"SY -M4'7L,.VZO[U>A55816T:=&2U -M6F:2ZS-[[\G"APW&-3&DU"D4EV,F>/U0FDK$7+.FSVWO1'D!;$//PE^W<5IE -MIL'1;XX;/L>&3)%.PY-.JU-#5(=7LL43`FB<1,>?J(R4K48.3$N-&NEK-$E, -MIA=>M;CM(#]DQ%;U2T_Q,Q;3ZYX\=5,!L08OSOE;5J4]\/2UW\FZ;=M)/#^NU>O#>Y_$U669!G).Q$H^?X3UX:BGO_+"' -M%DN#"'Z%ZB=@N_HAP9F?/"-(Y_`GS#`?L8/7U.W3^40<2.#R: -MOL8L]C"+LE9GB4#;$O\96`L9LZ5%CSO(L4$X;JL%L>ONOWP#L@^#V'?N[I]! -M:<^3E9JP_!-2L2&8-89PW>S8J%`H.B9*<7,L?D\Q?VV+/Y!7:BUR<[\7J981@XY-39F&4+5X>D)NQJ1 -M0ZB&1G#C$&X\RD<;)#JLOKEX((TTPM+_S7,"/ZL2K7SZ`0I6ZC0;:;B1!E"R -M-5YMIB,9$F2`/-8\SD,D&)7:*;.ZY[SV1V/C-P(]WS3D-_RG]7O44@1S)8X] -M5H9G*"XG)^SAL:K=37&-`KL/Q`R#GGVE8FYJ16_K==J:PE$K4:KP!'@37Z0V -MT$!VB->H3F8)1B=/PVGE02).QIL.^;6Q;;[%:J%%H!OC('=S7%,Q4$4A#A0X -MN7-5*L&$Q+)^L)-:C=U'R(T_7#WFDQ9ZV>=!FIL23KMTE_;15'-"XUWBX?UO -ME$AX%5+G'-!1&\5V:3%58VK6YV3_S.&%;@N -M>1[$`3_>+[7SB'`_"_#BS#KO>!'W68(S:G0TQ9;"+WP>B!!TO8Z0?_%`9&=# -M;'C(3R!/H+X/+J0.1Z`F<9^9[9 -M;!OC_A'JP#5/_!"UQ'I%]#^^M>LVRQFW0;O4.8[2J$U]BI]=9C%']Q'CKQ&] -MQN_X^->YC8MB$.:/VTWA48ILBE3+%-3QR%O^S\NFQZ[2^V)7K[X2IVO`Y6GL -M)22@[8.WJE[*Z"\)-GKI""9#,HQ3`=K#NFLI\D+Z+;,5%('-`*E4D2<4]W,! -M`'1M.6H9%PT8BFO[B]*.5C3-9!:IK6E3G#WAN'DD3$U)@X56"S2JK)1"]&3$KM -M)@D,G_1'$X#3`#ZP./_Q<'5O3O,D!Q(PC@ORN)"Y;J[JL!6R5M1VPFY*DQQA -M<`LGYR;J\EH8O>#MC`?+M_#L-;"9<=K>CCZ6_;*Z=P3`,QZ\=63@0'FX$J7J -M4HU]\+9D#X)=;&EXGB@[@9?.E=Z_U_5>)##&K -M-SN0J2OP'"<+7AX?!@#CIN2C?BV\!'.Z)^U,/&5VM^-'1SDHDK!Q.\9T[X)* -M?:#_'HV8(^`!A"Q^:WXI!T#LXMH8-%/ -M`0P.)+G\"R%+*C_GY/TEH!Z$R,9_[C)B"!)!JY!4A;@%;($SUVP!%Q1`4IA5 -MADW@(J(\QG`+FHH!.\&J%M]E?KN*!WT4J9QQJU*4FAU=MC1G,XIN$`>#$Q:N -MI&5G9,5(+I(-UM]CN4-MYBPT61W%(].0M^PCENQ/KF"@#@8H;=Y9T[O+8?$7:W4H(R?;4CNS[7IUY^W=1YL4DE.I6'-$A<=1<$QSBAMU5<4Y8-6RD -M^L.-NZG1[B0[J*=E-EB8KQ^6@W%^$]W;K"WB\]J[_S5O%,:W#D,-9X@QET"3 -M,1S_BS#)[1!!F%[[Y\P9X1!3'SX=9DU$H@3=>F -MJVCP4!EA5DUZV_LF1SO"@9$W5.JJ0%PW90=]KX(36NF)%4C"V[$AN_Q.=%DM>U$VH9U -MM2S#N/A,V4*!F0?"%$=-T#NTFK'>\+Y9;-<^+&$S9K7P#B5ZQ)&)ZT&MK9>D -M-'#[;[,^/X,>\$DI29A<=3>>((S``',@!XEM<="*.JMNF;1).S8B7]XH,?O] -M%D^T5KGVIW2%"DO;CF;*T'QI$$ARJ.-K"AT'M_*'JXSE23&$QGB&OHRMWEY. -M[)EP!HP4T/:*`"-?4/4MJ<_FA)F4B4>-%>@@VJ9U7F5;J0UD?EL?]FY>A'UI -MX!/2AL=;UEES%KG`NI177RL!O[N(GB+:RP?4M(L>B@^,O9JXQ&S3W+G[L_.#FY"X9Y8SUK5HU/_5I(^!)&M`M.7\YKAXHM52UO$UPLRR3"L -MR573FVV&LU8_3-SG*Q-_C_LVVXK+*N.)OP]]O$3M(R01]4<%.62`&NUL5O=V -MD4HX!BWHCZ#P66-Y<)/Y>7R&8\&VDRT8@S3BO^SRM?1_07)ZRTIJ13`CQ*TO -M1+15/VH5""$TO_8>(`L1D2/>X9"^[(9X&'CGFYJUM2#KV -MV-QVPRGXOJ@!%!7L8;J-U;2Y>+`9!>IP(O7.S2U2SRO"__>W:.+&//AP-""0 -MMQUWO;'V.K39+E_#R#6;I_SOBFPCAX1^Z:D]3!_%A'V#R -M(11W'/DA#=4?T;.EDPK3U[FY]3\*0+Q[\1KJ'_X*"(GCFURS(8CA30RKLHM= -MB&,Z=QVN*=J'4I5`R>$FVL\S$:..,?L1V&30>_KH^_8UU1=WZ'6GG)\#[=MH -MI,[$1%7(C@A<\+]SMZNPI-&I0WM3>+\9:I!JUI)F -M!T2FIQD+VR6NBY5,+6SZ=$':39@1E)8*I_(R]&,5"?6(Y85@E$F3& -M^O[D8IRQ^MXNBL+3J@KZ&DGDH;5_G">1-TTBHL#F2P&!M_8GS%==50]S;+/J -M@&F0:7Z)ZIO.*S>YZ%JJ]%R0T:YYWA'>7.;*`.2EGZ_M'E78.B3B]O$W&H$+-[,1/O? -MVU=EU(ENDP@#M8E1M -M1T0&''=?`Q2)LX8D@O%6RR!: -M[EF%:@HR;:FI."@\1P&1->11X<6G:*;)VT227HIXXHF4S#3$@\"A-BP@:/A0 -M5*3[2R#VJ3;Y0*O(Z.:BDG]<^!VFK$="3>*;MLV'<-?`4:$[BVA5*G."K,+^ -M;G4_L4N=37*RXM#;<\#O@EY\`TP'CX^XTN,BU!)? -M[^CZN*Y+&4($$K7R0HBH`,DPCU6)C`TI]M&:>5VXD?XK$<9:SID:^ESVXS*Y -M1K]-+D!KF]1X/^LK8N"#I@>R:3/DJ@TB]FLL\-7-8[!MU_[C.@I!_>9:<&_I -MEPQW"[&FQ$:$&_/;M$ZRE].PDNQ%-\COO,C:VAS+2Q<73[F9WO3AW9.)SS%, -M?CQVV%CCLX*6VX#BO\+=C`CF>;N)],-W%']A7^MY<&]V$1WD63F^=0>DAJM< -M1.I.?UNE[SYK-;IL-RMM26R%7#NU)G4(G;N1\XAU[I&SS)AS^08/RWINB$PU -MHI1GCV1'E7$+._)CKM"7A`60FA*ZQ/9E11&'YJ)*4*9";\Y,/AS-;E`V#!8V`H";'0U[E9[FKBWE\L>:[9@S*!XJ.2)$/R:!K*& -M8L#_P/9R.SL@SW.H@.874QE1FL"-6YR\_@`*J.Y,R+#O%\VD+%39NR4;Q-#` -M8.`A?R7OYLJ4(R`CW3GR[-658T5[;*8%]Z]MB1H0V5BN[>FN+]9)OF9$[(&: -MW!HA03&?),#>VCQ'E`=7P#!2@,(<"GG8)AOX/DK:/[SO?T>\=,/DV7KF=6>1 -M8K1^,O8[7NR"<]#)&7)P19(>-Q"W_Y[U,&;FNR4R@&!*2`"!X[:-GX^1C_/K -MG2%RDM_K6=,3!GVX2S&PA#5=[JSS2ZWQBL'$19IR2*3P8 -MK;._38)53U%$(CN'ZR'AVGHC9SKF-/-Q("#9HO+(K77CD$WY*Y[G3'66!?S+ -M)66J^;5[-6]6BTF*=VLK)=L],V`IXI'F[U["K>BX?NZ8S*P'R)4 -MV@%7I_9YTQ=0/0DQ!5.,Q%U+"GA]"&[/@>J2!K8,L0\%%'R+`2(BY^2K+;4, -MPM&3KZ.BIH=YRM9FWC8@J]@].R93+(R`0PE3OC[\:]$R-A\N*L0C;[!)C>#& -M]-&C6<)>@H#P=^>F'9=R9=5`A1Z?./M:_I)NTPI$FLT_QTTY<"'YCIS -MT<+4QD\-/?A179RK9-UT8JN@OWOZS5P]B#>1B`2#[1L_Y&W,1D[[,PR3,0T. -MZ,C9<(H^*=[C<1,NOJ'T%5S/)<2BIE6NUL9*,]A#%\Z'BE%^9X-5CCVD]6!/ -M6N0U^\;^G[#O+M;%:+8=>G2SZ?A)#S0-K6CIS*8(;?#BT&R79ELI(WNW3#+Y -MS:>B<%;_1/;3B8*W%UU.`>'<'?7K\5RYQ*21?Y_N+\OKWH#LZRK6+HYEK4@8 -MJ#.\ZBA)R5Q[?&6R%G*UH2 -MU'^5_G;+RO`,B&`V71M=F*_XNM[^'+E.JK\'*CMP%]]B#3_Z2F/%9+2[]WP' -MCQX!_E$SYU'D01(Z,H^`GHTDOF7C!LD1VL[.6)D^]AP@9S[Z#B_X5M5,#S`I -MV1M!8/QCJ1E`M4]&^YKK+ELR&C?]7.B\0^*UG77[!DXEO:%F/MH)I-DHB-,L -M.P%B7,O-M,XX>I]NNXL\P89L6#DS2#I4SOS&LEUAZ/C(L9"I^S]14'2\MA$& -MY\OP`OQG;[Z*ERJ8I7)E>SA-U'V6X5H:C=\US?V>B?TYHEPF5V!COUKT`VNH -MP?<'+'\6D&8_E%W$22B\;\_#OA@L>:\=C3\)"O?L37XDG`X6V`0[E9@4X1*2 -M.AJ0E)T;6PT5JP/=WM[@W>D![<,20^T0C^UF4HO!_#W45@:@V=#XR5#3J5-] -MD0V6!,+'S>'J;)F:IN0%S)]AIT*!,25 -M_K]`^XK3*!@UXZ&GY#GFF)JMR1=WIO+O'ZFR:7*GR,K.9=ZGP/L=90,R4\3G -MZSY@0@Q\8+8`WI*DUM"P'JKC12\J7#XZR3G=,BF\G4:\Q]#9C?G)-0ZW`!9W -M)K-B&U%F>57]ZHG<@'%6!Q/U3;<1<6$=M)5D!,28'\K -MH_[)"G5MRC]9B^?^/RA"XB@&Q4T_<\8YT.M%3#QN_$0H0C(<:8\'CZ7,/FP_4!5C*WUKD9PS'H-:4$D:C)J_C>[$Y_2T@\JG0Y[?:.&F2IA -M*282<.(>4!T>:E@$F;L&*3F4)*E_^GA8_&SD*H`A@D;=H583YSZ)&I:04^S%X5-K0L?@1F1=WFRHN,CKB`(]V+'54,! -M0)&WC@P@!GL8OXL*?VU%"76JDJ2'`\DI4(%U0+"Y#&';J+MI\Q!@V -MF/[>GLD8/F0&@QQ'8LU/YC':NQ:+-];`O@(]X_H:@,ZTNZ>$R$E_6TQ0%$.) -MFF*<-*(_/-^52%-DO9N-Z5]$\HJZ8KL,P<;]9J>>=U:!LOPPCW&"*$;0%SYJ -M".O2M6%8&L:;M!6D(/?6-VJ2G6=93F*$$-#U+QNDTFW1P441HXJT8F)UX6R0 -M,I84!WT%$9;Z9%SQ!6=*E*[$Q]4GK"?W4@-MHX1KN156;W2Z[Y[\8M"^MO66 -M>L7&AT]V^$5U;9'\3<=/&0T,*HO8D>S$^51I:B\W1%3]W_7?P":Q;XOAP-!Y -MTZNZ3P)5\FABAYK6H"Q<-'+0W^^8Q8H#X^_\HL5,6,TJ'J8@1;LL%CYN$Y -MAG+O\LY.+?R&WC0=TH;VM\&%JG6U$)YW^'0@8=93302N:CV$CHVL3 -MU<9MDLD;,$$=@;;!S!8V*N;$=RG"D*98<4GWE+/?7/9]?1XFM^'2Q)Y*M7?" -M'=SWGXYKN'OA)9"F50&11'ICY1+;0I57D6P69K\'.IR.2FXDCF>Q6X7"O&W> -M\OKR`4ZO>LI\8N1=U6,FA+[J8#9V<=-< -MEWU@8LK/.R2#P'I:5H+KK0HS[F668%SMM'-++>D;1JX`F7"T,OFW'9?=/1GS -M*3KDHDN^8+P?I4B9\_6\MENE:LLNWQ)$`\F>IW\LXZPN#--UN&X_+0F^R;/Q4*'^^#WXFLXM2T1/4*.;1-KC(SE -M:9F7NNH(=3]^;AN$>TOVK^($=QCI,95,/LRFCTZA-D.(F0;*91G^6L6)W#^7 -M/>[0MU$U6/QDY_^NPXV.C0.A`B+FO8(XA3Y=^*5^>O1`84Q/HP+<9.E$%F,^>MO"'C>B+Y`^**J\M-RD -M(?@&3(MXMJ[7U'WVF0_@D=FP//H@.]#Z2H3&(M4EC=`QM>,`[2K^\R`]%_#] -M5C3,0:NQZ5Y&.JZ?=!@U=H+X-&LYQL*@?/&&\QAW(@T3AIYP7'(@E6_;R`6/ -MC-=VN%.-K1FX3C/@J>*')Q%R#H[Z"D-R -MTDL@%64U?V1L2L3T`'%G=F8Y`\)5#C6'V.3T\?_.@Y+8*.7<1.6A,GF#>HB1 -M6U&%EU_;)@2UEB$B.*Y,$!2NAXVL&&0)=>1+=VGQ!CJ]#8:@]'D- -M!+??J7D+0.M2!XZM@<%"S*#9HURMVG-$X;U8O,6[$WN>)STE/-YP`K\CK>K\&*CZDH""F_V""2Z6-)_WN]+5>`MJ(3&U+WKQXE0E-& -M!FL$5A!T#-?KC[B-?+WO4*&&XY[N$,+?N&J]9;0]X!"4,_NXD20OL\0`J&[0 -MM#P^X=?B6J-=$&HW4GVZ^]>A*=F;R13%E!21%;]EAJ)94,3NU@ -MF&(.1+\"14VA5">6\A.;UL/K@&Q4P$D5LI>9XVA2\@G?VY1[@_ -MG-@Z==M_?A5XL(\_"Z.7DC6"KQ!EO%*1$]SDJ@Z4+P4M";">#(\=([>T?">M -M-E@5ZM+_FNO1]U)Y_$]A1RX%Q4OW(N-:+34;GHR(-_'3X9 -M79$?&KOV.R-D@;6 -MX'39PO,4SE7GD"N#/_9WPX-'0\>T%^EZ[NJI_>=P+3@$%JGJRU(0WLX'A+A9 -MU;9GC_G_2S2V$J62XA`#]]G20XX\T1E!K5-]%/<8/+885.*%RWS%7!DF)Y,6 -M"PATZ$+*`K65.A%G?@@8GBX:9IP?*&#QS!VG*\86H -M+;&IZ/!H=3KPLK0[D%0A%C$OPZRP_K!*MQWKH@5#=VQ>IKT@>!`4FHU_G@Z: -M'WH:ES]/L*:Z"><`2T>H$:!%NJHUL]\V0K_VUUG+R/773LM3"O&2W3HB/H^W -M"L=F.S;:,R!\R%P2D5"(:X&A0S4`7&("9/9$C6+$?8VX[N>^@17`Z[V>/AJ.)+A45'5/? -M&38]%[D5H].*6Q!,`6;CA!E_D+E?O::KP9G*&$3%_HH^,IV6 -M`.S7Q.BG$R0Q&9V+LNAP3$&(8P<:16`XJY$B3TW"/80&:2DX'*,ITRSQ`J'"F -M$0:IM9361]F7G1@4OT3G#0/I8`J%-A.]6*%_+%37S5>R[(F.F]T[B]500$%\ -M/DR63V(I?:$VMD#'\8U)(H.#<1HU#&_L0^DK$LL2?ZL]A.W(1HX`4(G*QC4R -MD$67O$I_(US04JQ-;3SHAF+N:<7+R=_AL=HTNQ@'"7N_45-2J;_0.//]9X5) -MCFT4@RLJ^SL@V@*.P>=Y>U6F`L(#WZ"<%U3F -M5NWI1:*B5T8-0Z#DP)_WW-UI'4.O>S:5=9E5A$WFVG)KH419$N/+D[W(X_2= -MJU=AU,1%'\C[A7,[TD,$!!48^.\"?\#?76E,R'?B.H'I*AMI$[YG^4[5-1N2 -MR_4!<^V$W[>LD4R6&X<.92^1D`E?5T14#;&K&*F5,\";I^QC(H9='R\'[/'8 -MP2T*8WWI[^.0I>'7914(SY;D&@L=LU0H4"WR;+)H/.]T4?O;??>M3VL,T-RS -M@RN64G0G"BB#(%U;^VHU,.INB,9OS-C@_B=^,/.K=@M]BA8.U1PAXD"M1X[TJR/7?SJAJ`87,H>[W[J=D0PVRB=?7_-Q`'-O@W"Q@N;R;)?_*\ENN6= -M))LX@0ZGH@)8PX2$P(@J7]DKK5SM@D44J@-7?(MA(-,\#F#R3]`<4S_:G^*+/;$.C_#)/D%"]0)UE -M.)WN#@^EB27]&,,*W9$_"1F[-CQL=+F:SNT#5::9E/1,7@Q6.GWZ-+M@K1M1(EAS:7+'H.!8M16_OHL#> -MPHUE0[]9274>]3JA3B\068D)23="'NCFB=UZ8_Y"C;_5)#?GQ9%2-'H-CI12 -M&-*-`^NW?$-(43)A5:Z[=/&M=164Q!KM2Q;Y8$X?LF63M>Z_ZP=&2S%./@=%]O@]9,X72QS025J':6_L&D"E]@>#LG-MI>F -MH_I.].AI?F$J8_!4E$H*/J[.K*%%X)9`-\]AA#PP-,>1`4'RG>:@E:[0;T62 -MVO!DV$4,LLR'(I<(&>O!FYCD&W),9.\*OVU0[SN_1A.0YI`9X-MJV,["S0;(_Q4 -MJPT`PT/]ASI\,,`7M:F/9[];IBGGS/56J'Y)">`,C*GI-4G$PB_AU<\E.7X" -MJ`)+%YK'B#!S!QIR(N_#2"4GI#XNXN?Q4MM.@2JB^3H3-D:R_?N%4^BM.E.7 -M-RG/3^[7VA%7-7,X0Y]&HT]8[](A:2,9_.7P7>X=PS$.M>PPI,VOFS)':*>L/=""@S*E]@>[>'RTBVUDKUWRF3B_9<(#X+EE5)%33=E -MQ2Q\?U<[.^S3L%5#D&E4U3&#;O,JY_A>_. -MJQU(YV4]O(_(F\HLCDOB7BI=:OULT.^XM -M,*L6LY?'GWIV,ZVL8+D%1HGHM6H&^;Y7#>@83.7K3:H>',T>G0FD-'-NH'\W -MU[NNF.']P8OC5_]U5-8>#=88SA;^%^T=-5A:T92U,S?6X]^P_@&:GACXR)S5 -MTVI:AD,KN88YZR+BV^4$S#S@Q45DB=?IC55QG5SP'@AT6LNDW\)N'YB$H!TJ -MX#!:VM!YT'YKX$I?UX8E,RCZ_A)5@X28(?U5.OKG/_7)=U -MS5D[_`+>4H^\C?@)5RGD"^;*!2ZHOYD&;#ZU>CLYD3S*L&3FCOZRHC.9VJ!S -M*I)V9%NCWZ/HIYE7(F@O"X>1>S276R=V`-=5C@/^4(.?`9U:<,PUR."+$K)E2A(?.(/;/ZROIV&HKAKLD3@6J9\KB8X%71Z3^V)>1;('8( -M,NN;P&<(A:O;X?]V$^AQ_$"R$:]J,Y(RH"WT2TE'39[#U\M.J6GHBLD/9[ME -M=E0A9="8O-A1(8O[+_>6:/.GG&FKI2*:I:3=4-@V27D2'^_^B/6%&NOUX_ZK -M0J6J"X(D+CK["G@'H_CKN1GAQ062[4IIP1$[(PQ;!W')88ZKP_T'SO2HGRBB6/\U*U,BZ"*SO[1HOI+,#``GV#QG6C_TFSTPP%/["+DU],URY058E -MP*1[P?OFG8[^L6A)4C^*JQQ*3X>J@"3^03<)DMS]$?3K -MZ;OK$T[[@=IW@^FWV7(@.BQ<38,(E6PYRYVJ;/9NA=E)9Q7NGJC[BLE(#+I9L.F -M+GB*/4]@3D>I>Z1SV\S.].9IYYIC'1.,UHE10#XDD,41Q^NI?<3!*WJ^]7*R -MX_]224U"T^GCP>$D0$EJZ:\KQ2;-ZEM9I9@O,\ -MKKO3UVQV6L;%&66Z?MXO)[NCD]NOP5JG/09Z2[K_1*,>1JUR?1\DVO'+]UX7 -MBA[[B-Q1KJ[[\.*EPPV*AFA)S3$630R&JZ7MW.G -MRY/O]PN47YHA\41#(78(AS#=E9#[%XV?UZF8FC`3`!2+FOKM28H58J8@^1>X0_R-Z(P -MH#O>JVO6S),-)]&AG\*S^<7$C^]X:7W^6U/2WF;0UN-VD;V.HSIQV9@1Z.;) -M,S%C!)"]YH*%6M$D%Y%?'B?.O'U=<+Z)*`R8!1= -MD/*V;))4:G96RIABU=:'%)S0K6).EM_7H9\(C'A(-@%4@20:D&OFONWNOTX7 -M)PQ6/L`^PFPJ4%[38;^+LI:C6#,!"]4A#S3($]YC7&9O_>T\3ML?[FNPP>YJ -MY,+,].KF4W8Q^6^3>G)OSKV@,'-Z_M48Q:3"IT]MZR?%X*75?E%[;U`J]ZJ" -M)4VS5>379OR$YCB:V]H81YY$(.B*0$OMFTI#3P3!:W[D6F1P#K%8WL@D0-$M -MV]_(N"@7CWR,M4X%&?IT2$3]/DS#M3O_Z$C`O=`,$1#2L-10V?#8]ZE+2YZ- -M(AS?(+RAF*'D\M/(0Y_85V#'CY[&YKQ&@=H&J2.KJ,:L\@J1U&P-[6@P, -MS*NM=`X_#B61S7"(+G+TMFR79T3>_+#[V<]*:B!/H2Y6S=3M0W(TJ -M;EGCOD"P\Z0BQX*NF<*,;0S]6_2EW -M!-#ZG_>C9?SSJ`#I"8E:DPB):GS3A(6Z$/8).-]7]B)2-`62UO3CJ%:*[_)" -M,7&ZQ_].16*M\1)3YLPV.SD9DC4NE:_I_1_Z4JI2GT>2SD&Q%?;>1[L4#`I, -M``I>])JNAZ;Z#0_*O(1#,>GX^Z"W6%,IFFW/(7#[MJT$>\SD8-#RT/U*QVG) -M4=YU([8BH2#8Z*KG"A2\T/&ZW)1X1%Z`97&,1T>B45B>PP4)>O#>U[@P,W]S -M=_8GKFXZS9CH7RB.F`7$@5GKXYCOUQ/45&:0"IHM1RKD%&UX,!))]Q1QIK1( -M\2*+T![4O17'[*CM0@BW9$3%X#N2JOK0:[Y$>[>7$$&8 -M(S.*]M5BK"04D6*3U^\0]>^]9.BD&7QBSR]!MEEK93 -M_$>])W%1_/GKXHX@2;(2A.@>[#B`%0DSO#24[FR)%T(Y_6,[RGN07^`JI?[3 -MM&$N]FQ:B!I\#FT=TKH_*(S?H)14@I1UH=&5E@=]$+Q-Y""7-,\]QJP#\29A -MXCOD7*];?V;M]5P)$.K"KL*.@67[/D_T^6WG:;V4\,0_%QEUOS4%S^ET<<?N$Z3V[5MMA#GJW)9NF[4F%0*PG:@(VG;!W/+(`;WOTNU -M0[#(-RO*HYQ)X`3ACQ`=:M!$N9G`%H>1!OA9G(*\.`0Z)9]J^M-RGVL1]KU" -M`1.;P[-O2FE'I0B`%^.BQ7"!'5 -M@IXNI.0PR-[D:I2M";=CVAW7JQ3';9#H-C(N>8FVT[J%L\>!5:]*Q6WFP\0= -M\BFAZGEE<&1PBIPSBFHSMGYD>KNR?D*L:OL9@JS0[!-VWTHU4'%7- -MZ4'N]*PEA564JGW2X#:>CMGV(SJ'N[J2\)K:-$#L*(2DJ+;\$/G"GD!RPI\Z -MXS'O5[PBN'$NROPP,K6D$GEL('K-);V+OG53!H"57][,C$HCOAVX$UYY0[F2:4K6`7%T\R\U)!W%!Y5?@$:T-/WW+AXX"]LW[Z_`E -M.PT3]%\0_@\R7&*R`A5BD8X#J/I`M%^Y6VND?AE!*FMX@#*RZ#&[:G4O0RLB -M>G^.[#%D"TKXR'F@D&4;\1>89H(R=/7I%NW[/Z->2_"SPP)^UK^;9\]> -M,*QX829WSP?3K'`B.T\2\`>RP7`K+7_B8)>2B&B^ -MWKGH-$TD)YG%V>4+]@R;?F[-O>LC)]NE6I.^`Q;)N^$S//02*`K/_"997(DD[$/T]] -M+>US;",)PMU^`.Y0:WE9]=$4W)2_:U3`VV@HJ2Q78R`7\&9+JY<0IA,U>-.J -M)2L.#PX_AAJ>@7H'+3UYJ6!$;K][$6EZOW4:,#H[%P@U33$V&?7X.#K5M6H' -MPE0XK^S+[=6>"7QAC%7&4L@&++B##+M?;H1JG@;[ZFA;03B8,$8.%5;@$XZO -M#`8*&)^[SW0'@78T1"+@,_,*"R"9'"&T$)]TD*JI2:)G_W9.[=M+C>RQJ8+: -M?S!.84*!@\;?W.@@''"O>XM[N@B<-Q[^87."#*3W0\_;\&NDS=%`!`MFUOB] -MN3_*NE77X_EG;^%E\%N6'+BC\=*&MQ4`[(/G8PO5&J3A^H',&L/J`?K\I28= -M??@@+'*[^TDT#=67PX/*23`H,D?D47BM9AV<\M[L8CM!9FXA82I.E3X%TML, -MU;?;&=DH+.V2-1=F8;RLIOWVE4N<-G%Q;7Q)HN(3^I<2:Q)#FIFOW&K4?$4, -M!TAF[+W0(,(O/P^M+*^9J;)D]DG5_#U/@K_JU>1(PUF/YQ.I"%(AR;A2;$.P -M&:JI_N9H'"[F(>5VC'I!C@<2+OK&DI7\G+>W]95L1VH4!H4C$YO-/_Q$3Z^? -M(H+LB]3\NP[95FZ?X$#K$'WS\'1-:N<%MR!Q;,XGF&G03[ZD`?1'(6$X/D[A -M\J2>;F@B)53'-P^;8[483[W#""PK5T\1"2)];T.NV3L\G`;I6^T**IK'0T/D -MC_=UJN;DMR/_AOE/FQ[^H?\7SSM!DXP/U)+4EUZ`Z9(1?D$O"U[ACBBOP&4F -M]MO@Y81LZ`'Z#`(.^^FC'I`0&%G&IZ>V^R)ECZ=C'(PARXO],.*:M[L#/"<4 -M],Y8L/Z=]X1C%#/Y:@LP'@C8F<,S93<+@]&JZ9<:K-(NPRA`JP-8"ZS3WJ8U -MTW/UNA5NZG?DN$)",X;4ZH:C#@;2_CW.ZWWFL99FO^/D5)XT1>F.C)CA.^`, -M'V&#*"YMM\Y=CO2:0L@WHSY1'1.28MI366Y -MWR5?+D;<-47!E`'M7L$R_GJI]I(,LQ_=$QJVGX;$$T0A4#MV@L^WMZQP]"-D -M"W/7ZUZ0N*)P@@09V>K+-C\WWBZ3](^]4R/[)!"%]5Q\>VF_8UTG%J4XZ9HQ -MJVQM0%^%KU96/BVY)EFV`X'>,AP;F82B] -MG+4A`S&G!BU=*W39 -M2]N-/P6^:$KU:A*Z4*0.ST:P,'E'9N&_(\S'/"CH[R5"Y`]):O">%1`$H(*& -M)O$.3HQ`??F*E,:G"_3G3\.?VV,9C!>X^#^O&<.&U#1 -MA",70L3SB"B*C@,6!#Y3B<3_3O4]ZSQSU_5HYP>B8C2>2'H+T.1+YB0\Q0/_ -M=@,DB*-.J5,T#;ZR4MS2PVHA44-N<)'N*G@SU',"1[.\M82(<%LA`^EWE*6( -M0+Y/8K?[+$.$AX,")/[90<=[/XB],/XWB;SJL04;NR6(F2=%^\E(Q*U79SF\ -M-FBJ#"+NA9-U?%';U\:!GIU\IUO8H$_V)@7:B748S90J?$=E_=%L4Q2U4%J\ -M$WCW;YGWK;#Z#;N@UY$H87T+U$1A-5=/UM!%JH]Y5B(NLQ`<'Y5$^:=-99'. -M'@MC\0(/+M.M)?O7?8Y:!I+GLA^H([OJ\=WV8#J(=(-T:\_7G#`U; -MK^CJ&'3V\[2B`[_A,315E"3MB7E.Y:J(7E@3)HC-V($J;W.=&N^=!,2\QO+S -MA47#*=#0WO7`">S935N@&[G>$7;VB)Y]#,F]B@RKP.OW"BY#&2#>DM6"7]X9 -M[H63/BQEM^3[NGY&X^9P"%HTH2'S2ITF89!%MN`C$(BCQ`,*,R"J0`$F`A3Q -MZ4Q,,B<%79@RH:5I"1Z9,.@BUJ-(R84F_QM^-ECIGG8:XA)MY4YKAS36\DC/ -M:S>ZG,#YEM.9C\`T#:/+W`:ET5ZR_4#=Q\U$9ON./F;4%<.3?K]+.WG[I-Z1 -M[/I)LF)_0X8T8T'5]QMT3(.(C6L-VG*W0"'T&_J4AV]?RU<(:+BLV,]>GLII -M9ZW4L_#[8A^"&8M$^1DY^G39L:I40X$=0&H'P.A/)Z^]HK\'FW#LF[60#F^Q -MOYOF=O%L`GS$A0))I&-VH&S5M`84P;2S(%20B]#I0<8%5@PT[Q<$`3)([N*< -M3YA3?,*CZ]5910Y1[8W\P^MI:,`6=6FO*N'EZ<6,CW2`GUM-J(X^0+Z%I'"+ -M5`W^<:+)4N7CU:<$U(BI\2HD7-#*Q4:[%'BP,!O)3`!G/[!<518N5W29QW:3 -MC/%%\%%0'-"5XKPKE?P@JX#!P<(Y0@5A+:^4SC1O4)4Y\D!:OG$MCM;FGK*( -M@!LVG:Y"B["X/M#EN2(JJ9<^%SF@[+AT8ZYJ;1^Z[08^^'2"_@>B^OZ5WVIX -M*?OGH&52>H!`EB*?4OE=)8F`IX)",@;L)E$SQ(7ESQ298?4A>I:IUR -M"0S"HSB6@4UAA^']JSUI$B?*M$:['3:X9.I:EPP\=53(;FOT74A-.\LOUP"#V,6=?'U;[:,0; -M4O6*+1:5F*9KV_$-^(<-\XP@BH\=JF#YW]X*&O];0[PNE>1SB7]?4>%>U/&9 -M!H)'^\N25\X5P^+^(KWL4FSB-@%*C\A3'O#Y]/*.J(@8V#@76.!$Y=0J_V(\ -MH4("OV?,QCQ^:1::SP'J;NX?N-04-!Z:=DNR2>ISQXGN>G+7=$)D)YVX>E8) -MA7?LP[$MB2N9%;;*(V3[)X5QK:]2[#@1V=U<33P-%N^#Y5N/CLEE=]GZ,V)P -M2+V=!\?++D!NR&)P%I.\RVE7QY_;T7-A/&?[W^Z)3U6P=^?B!73^-HM50]3( -MPC-;SHZP4&\`QVI2S-.4=PWWKNLSW;UHVS$-GOFFM`P4AQW<=:5691V?`?U! -M6(C7Q$6V#.Z0^0>\>A^>B=&*XOPM[JNX+K?+?['G<1:Q(U990D+OM6=E#8)'_+N0R -M@GGX?'M-V;[LE>(D>\\_H/L;.- -MRR%H89TPM;0>F+?GLNIK;H'52G.B">GG3$$0HN9OH+CXP?BI$_.G3&UJ4ONS -M?$`9@N<_F.2JNV+PW/!*2%W*MTU0:!*8JH_81A[H4N[$R6S,%_%891WU@;V1C%[M7.HUFA*&UTW2EM -M?(21B+)-/1#1"@2,3H-Z*`%9\+R95#3-K!Y*%*4/@-@0Q\4>:)#4*A=E_Q>' -MO_>M?)\*%1FO.D[<_Z -MLNHMI4!58NXG#SUJ<$\UE:M5+_52HI`L[T6?E$N1L!8GS5M?/@$27P=L+N)\ -M60.2`4?W?VR_Y4!KYK?T*KMP"WUPIJDF':#]7]HDT2OUB.+%%IY6[8(2]/P_ -MQ:B6-+G"'W1RB-K^LRT5]S[!I$!17\TOKC+0J8ZA-S_^!X*R5LJHJK<@'[)'O0<#/K=S.EH65GEGD -MSMWQ3*F<83R%3T/]G&]*MSTH"'L8\'V4_.C#^P%GP?MN>HAVGFWD'#1?O?@X -M9QD@/OWP9MKEQHE98!D"*9N)T$FGVY?9CT9%YP#4AG/TR#DU7]^\)2!73*-A -M^.NH:>#C0DOD,V(2":PR4,WQ*P)OR:U!7@\F'*D1=:;X)COS6?JP_A]N`"!J -M(N;:<\8TO8WD7-.(>@B?JW6J,5WLMRKWB#")UAXB4$)##SBA&TR+%@4=5=CE -M9()ET;6S;U3EG-MRZ1;<@9M$B"08?M<5GO/Z:RP>+[*IZ7FF\$4FM@E0W7+/ -M-!B.19[(>^@E3^#!RY2@G00I#$?U'B_V4EIM:-S8W^)!I[^J:;\?-'OU02D] -M^553]MUR9TMI$.]?:ZKQ/3*(D0O9'P_PKMV+`5V96U5O$7_9AQF6T53UPW9$O.5'$:`HLN+Y(HK$Q0Y8E -M5%Y&VK4&TP(RIP>DNORAB373;>8[J=ON752XH_"[L&YD">2[$4<*H#,N=+E. -MN6D!",@6BOT,B5"7[=BAY>Z>X&5,D@="[/RKZ^YP3IS?T6^6^Y!I2:@$J`V$LWVB(%_GUEVA-8]"(PG\MG@?E,UI1< -M6_6)@Z,?L!Z_'S9ZGIR?10\I7RC=;/^@KS82)7FGRU`S6SW_GT]KO/C=QVFT -MB(05,ZW9#DZ5*.S8W,?HXN`EV'7-$F/(V]`",FZWM2.],)>K&@%[M -MQ6$$A[#?<+.>'IAD$B5M -ML,,-S+0B&>3/UTW//I!(&YNURK;!ZZ57H<1Y2+3Q -M112TD?F]5>DT!1I/#?PO->Y3-PV!U?JS3HD"M35(2Q'^R@H9PYG27G@Q6\VP -M=&/:;JT$J^-WMZ=#NEH0I9=I\T.<)1$%Z%/>P,B!W_I)>NKKD/"#BX@*&Z&H -M>%(P61JS7JZZH9T>&PL]1,2G'\U6EXJ>>HQ!#@F*&F7'II@1U)4/X&)T5GEU-L*9'OGMC7/U(M\/=/*M7OCJ\FZ,`!DH5"NJ7 -M\W"H>6V>,+,#A7*KSWTCT"T0\R&U)^_K0`2UY^"RX(Q/WB!2G[)V`:,_QAPV -M\%\0HCW!)ZR6:4:]^8(O]#WUZ8C]'KR';@;HZ9C_7.?` -MNK%%$2T,A9PM87Z,K7+>[-Q-P4]UER"%UA)M^WS["N'O0XY5W?%7A1%(_PA: -M`?SO1[YH7!T6&D5AQ'&V6P0WBG:T>I-\KQQJQRGW9"RY8#NE74*BX8YDIF$F -MLP+,NCJG:\3ZL\=5[D3JK9`JW/`P^9K3;CB0GFB-I2H9^BW3-:!"*/B]I*1N -MQD!W[EUDD1>[#H67'%HCB9Z#%#RB6#UTY$P0>G6MKP*]YZV#K!$O6N[ -M1C(`*RCH%9[K&MP%C?',AR(-"K\]^/[#SC%3W9ZM[YRO,^J)[RE;Z9;+H!O[ -MKD"64&>U"G3>;JM&D93D1'"^R^)!WFUS@U7=1%@L7X2*,!(&?GV8ZO5S_SXT -M\DN6Y7Y53&O>:B9D>\,J_"9'Y7FJ??+%@$Y\6.R#Q*Y6(9+H4*B"!,SVMQ1_]0E*?2'US^F/IB6$D#-XZ -M1["8BR$2+S]$RSR;W1A"8A'-)F#L,H4($RZ*A7$Q']?>UT_YPZ[PP7%>@\K) -MMKGCW@I]EK`WE"''XQFVWX,V/X7;2BU`ZMY4]'ZXS'M39$^$8=!#!,[5($I] -M^*W<'-J1*R5GU`FUE^!*(UM&08'J.5,.1V#X4/]RB;_X%HA%._7%+)DL;8/= -MWE?R4OALR31U2T>`+WHU<[:A)T/5J#=*'%Q3D,Z,-O1`@:0@5T`\O_C[4%@; -M5S^#+>URHRBZM"6:2PB:8/\)%MGRE8?"?JE)L3B25&/JI18,IM-HG0.&+F'TWE). -M-;TNI#R?!<8N'K](U9#2D7[@&M7SRB-BS!^<\1O5%79T4*M> -M#X*FN_RK@-L)F&FF`>02@R70_RJ.>1(O/:RZYJ>9@=EN@!4I>/[:!#!9<$PU -MFTB0`J;",KRF)]?TK;I?Q365(1:/GWH.0:YL6:B>NA3Q//9AZB(Y"66UH")3 -MHAOS,4MZEA7#[F:RF`,ALO])>:V^?TX3O9%)%?KC;;A*3;OIR<--33&^^14Q -MSI=M:TC-6X\=-GC$CIA1/NC]/O$P6->94TG8"Q58VS.^!E5LBA($-%$L_:Q& -M(-YQ\3,*Z:U&UP1_=-XK5'$2RWU44C_Z.>*TY=PR(1<:8UE`2^6\]UG`[DK\ -MDU?&J\%V-4W.AVI,X2L`9%=SWJTCJ+=/%6J?D%\L=5LFC1R_01[-_'UKO7Y$ -M1:24S84S<(?B:7O.*")+C1&NQ3'[Y(A-TD'Z`N"?:4?6K%)"_W+LXG1FQ#"T -M+RX^Y9&.,X+`KFD3!U&BW])6Q'L[E21DLXI[)B09 -MB\+5'W8^:**Q#Y'=+7%= -M_S$J20N^Y4Q-XAX$-N83J.HZDEDN>TGG[_#^@_RGPV`A_%I?Z-7_5DLZ9DCWO#FUQ\OU#&.3FPI1)_2--+_1,H8"!%]4#R -M#ZXMB8:#N1N,HZ/#T1"\[FR/(5?N=(#K5F85F3UXEI+`Y?,[VF1B&NQGB.%C -M8%Y-KLPSZ:;IZ.->+>9&6;F`2"T'@AQL8>-7J+.[VCF%<5"YPX\'(,R1W0GU -M?W58J,.#=,[O%3G,%<$,)_D6J&(6Y6$N!2R%@Y_,Q/9[CRK_@D$U%WUT;+.X -MG=\671!Y*[*6_FPE.L]67G".+8Y<62169F-X-H%L\C\3`!`S8[;T -MV4^.E7CUT+C9K^8.U3YK^%N=%69X>/J-[(.@)5&[Q_`6%)."[O4^$4"Z^K- -MVXV8$/M&7W`@I:EJF'RNQ&L%AR/S`>#\8($U!13(/2W>;H8)E:R"^_>OA[J: -M\)^JF?6!P-YC[EQ2%BW`-9UK!,]?10=QF2:/=-#7\4N7G$X55_6[D,>P8YQP -M"DO\C?H5UHE77A/MBQ=W>\50#_YU8_&3[`E']6E]]-0.CA.\(87G4$1(S5]W -MT284:JY3GC7-;_XS"/\S-7^=/!@1.D;@3RX7VAC_:O.X?9M9>7=408V*5^UQZF(WDR7"%]8/ITF9JU@?0#^!N]&-#QGK;45H^"R&P.%FV( -M"/\.PC(RE#"FG]3&;+]TXQE2'8YM"'!;+;2+5P!/8$`5>*T#FF>=YE(F!B%' -MK3#'I4FKLW]ZGB47[U+A2_,`N.2XLD7(.(6^.\#\&V98NETUC_R+GM7^!A(\\$`FF[EJC)T37%:2U`TLJ\ -M@7<>"'"0*?G73-5CX?%F=JEKV=7<)$*>$SA<'%C&I[9*F\?7$V\B2M6+-^3= -M_C).`%"3S=N\,@A_&7"\@BF78057^<0KL4I::*WCZ^]`?"30N6.7OOJK.F<2 -M6?*8*'4R>EW=]0;#:P33[0*0OZP_.1FU.NN1.@T@Y^TQJSL\7P'#K%-DX2:^ -M(_0U^BD3#:KK?!B`%78VF-M,4V.A>-U-54Q+Z-GK/C]87^;YS[>]&YA_##+8 -M=$".ZI\')GV#5J==*A+JC%EW.<@74`,V"I-E4(:%P)+&_PRADV-T0%.H)2T+ -MXW;*5*?)S -M!!K$R]_VU_EH#L6U+\M10UENVS=4CW)1G+(R+'.!-O<*WFRL0: -MN:N[K0\T::4O(N_\>T/)%U>:`;-/[M!94@%-!)30;#=DBBY7)Y:-=++MFPD]3`C#W5`.OVCK -M=O%Q/'A5K[P5P;?_YI*C'/^8`_PH.U'RGH]B^G>$WB_0;)OKP)>[D<:MTEK^ -M'I%J6H!R/T"(@7P,I&A80&S?#/=S/LQSGZ&&N,Y>88QEMQ>DF#YU';^S(F1F -M&E50X<[OY"?03LZ.BK&JF:IGU0BT$JY:W)V%F'O$]T`BCAX%]J4&%PG9@9)##44RM>0 -MQH!-9G?,5%Q"$2R39;H]Y1QFM6))H#`A3(.E&H/<1D>@N<@2G'GPY#-$K(HG%7/M\A^W]Z_ZS]*W2I^=:D2@$?:+V> -M3732)H/>CSJ>YJQK+\^LD/TULAX;1<2K[:/[\\P;I7/6#XX8N(,K!.'F`N$' -M1"1ASHY/XG]/]D`TM%/6VOY#"8`P*`N+PXM]FXP0O!O[)5.8'QVR6E`4%;1K -MR@<)NLBEN"934AZG"-HD,[T7`0EB=>^D"F04]:AS+C'8TRGH8MP0D0HU2_31 -M4Y1EU.+^.)Z2;#D3!:878Y7F+'>#CN6>9$P)XS&H#^,0L:KY+=I:D!(=ZIU] -M+>*C9VW,O7'(.65ZR@MK#3""F0ZR(CHDJ'M9;.L,@H7*-UQRJ3QN%;R;-"L_00^Q`3PY0E?="SRIVYFRMO[A'X&&1=4$;->RB?TH*H_F:C61I$?@[U -M-U^VM<6G1L/5<"CG^K.HL0S]6=72TK-@I`^LI?W-.>70=*Q9UFIS90N\WR60 -M$4QCPL$S9.85MG$DH`\A)V*H*HG(]4JCWGYWOD.G"J&3>LBN&M_/V_+NP.(% -M;Q^HS(32H[00F>=#C7T\..0)Z)GU6]]`?@7EX^_>@X4/\@?JYG6-HA>G;NJG -M2DP=$J+Q53G1M$B8(*V`>_CTG;&Q.KB[U8%!.[%;<),*@6R5TD$NO[+?+;K^8$E9 -M"2)]M57#$`]8=4Z=PYAS&@`,':T5VR\"INK+"O+$^M$_%SE&^ -M-E::L1<4U?S3I"A-F%RY?YYRH9@VL3M'_5&> -MJWZ9H*GMN8"9QY]L7T@5M*1`J7]9]A$_@N%>D'%R`U'/"VB]RHE+=TS[B-_` -M)>C2Q0BT$-@39R0*S>M\7G/BLD')%1&E.*D@+)KY=26,?LMI3!&K$L%1-F%K -M("=U+#^@\X&K28CQ^;46:ALKK]&J-1B8#61?:EUM_158K0?+HE3E[*I_GY;Y -M;5[]4&5\_[U92G/&!*%R0;1W1@@I%>^U([I4`/9M=D&UO^\;'F+;3FP5I#&[ -M<@0T+[RZ$%_U#U$,I[^N7%Y&`H@=DYZH.N<[M]![;(5G>)\YY;.%FITTR^XO -MTI!38]"8@>"`#W)HJ!^LC"2[P.:2>'8SR>ZQT3)F&*=+TCTWV0:5!4SEDT)* -M"W_L@"92U3@5TJSPRMX<<+_7.E>D85JHPHA_;5B:C2.GYDM_4.C#WW#ZG%%7 -M;5SWKOZ24B#C0$-Z87P]Y*[D=_^[61N^]=LW<.KNMH"U,)F2)]ZM$H7WEIJJ;S+3+UKL=73U6S?@B8#X7 -M;NL'-_=$P-3HVK=/,.M\,KGMR96Z`WUN[&09L)5QX^S7TQ\7=@%Q';0 -MI"R!2-.8MQG>G(?7B$IZ&`*YNZD.RH@^,S1H6?-ZR0P]!+/C5.RGM.@@..EA -MXSFPBO00'R6=8M1@GQ,4I!-GP+*$3!DNWL@$IVK']/L?!N0>@>XV>)4M!01& -MQ^F3-=[H;-^!/AX_DC/0($*H7;V:U"F^J_B:UT[C\8J"5N^Z[=#Z/7` -M9.8+5IA9#7[ZH50?/;\YT:A?#?U1I3WN;9O+DRM[2?W)4V%C"<+SH[R3KZ!H -M3VU-"^E@D/$)^7QB9A3G&Q_QWD+ZPS`,TAAXQ(^;IW2$D,*5729C -M'#!V3`94+`4IOW=O\NC\R%;)C48+.@:@Q!2/:0($%C4_WM6[S0E;(QW`%XBG -M.6%7C7I5&_WB@UUYOVT6M$O?QC.+QR0;9T][Y_*.JXC/!L*H[8LJ<9.0%,%ZE2Q8VCC$ -MHY84U[NKV)<<+VUN*'<_=^#<(9-N&:QN3\<\.SQP+'G@C='=O9USJD`?IC+)="L;P>!K*P9:F.=HFV266YV#L1E -MK;$(CS(HQQ1H.;!8)O_NGVLE[<7]OV\A#Z%^(T]S=7NS;:KY;Z(>),U\)\AT -M:C?M/J4O];9Z0_(76?"^<23G(#]EFJAV>#D'O&K^+W[X&4A&B'*A083`EWU7 -M:13OCW=L!-DR+,YV40S9%D_/QA982%?1UVK6(-!=?$QTO:Q*?Z'-/[$QK(9T -MK/K"$;NKFUE<'2R3;DX!63S>7&C(,SH:AW(I2U^/T>Y&=@_&;>,P?X5>$QFR -M)!I)WL^'4GQ?MG##,,&=Y7ND7<%Z!VW($YFZ:"U.;D>)XCTLV!Z/-=GUF15_ -M_32%MOW+E[('?>AYZ94_Z,EI;A*Y";3$0ZPO"X`_H0X\9IZ;.`A/]]*B,&Q2 -M;>2E>C_QNUM-,&I[8!G063 -M"#S*1>,U)<,)'/Y`;FU1;^K`@7[_@]E+&R22+5<8[4(?&.'L9G+E@S>6FI;Q -MPFHO;VQKS6%2<9CL5NEVD5F./J:C]DEB0.%+-H=7+B,W5,(-'$B(#Y!T(XMP -MX=#,&IBP?U2:@2'!P,*LKJ!+`KQ#("J6@'((YJKZU,:[^]';?Y8V_.J+-^YQ -M^[ZE3@W-UQ,.U=F2D60R[`_(//E1$]Q4N"3!]4'/";P[8<+QTKP52*0=L/S" -M:J^/05V!B>T/?>&$@&(/BSE3>7$FHI(*0]#E!VQ3S/<(H^15CG814.1J5%^B -M$8**G_5HX++S<96'5!4K9P\#V[*Q6,+1$E`P9FZ2T;$506;2*N91`2#696@J -MRR3XQ9H:]OZZ6VY+SP$S6MB]*9]58TI%19?Z7!X\SB*D6]Z"B@=MR0 -MGLG#*!?&[,^RK'4I02H+!?2!Q:F)2=$PN%";=,6'KM>V71II5R%+ -MD.H1=U:4RR+O:"!,AKS?U$L^5\7:3N[`D/QY"R%2M*G-4==&4.T`,BX*C&<; -M+5EJ97^SRI'K`NAT(BHWS=SK$C?8%L]2CL;$W#34<\:U>/4S-YVHIVP<)F2B -M\9/&U$!3P(#]CO:17&+!Y\YF0H+"S6$YYIN7?-G&<\RPSO:)A/N4;=_*(.O* -M+T=HQ#Q\,/15CRA6+XW*AM6T6L#W5&%EV*^K@-(XH3L]80WCEZZV:F/,K;QL -M.1PKC6W=O#!)O5+NP:2SLK(F;U<,F_,'=LC9=G]'4`R5ZT_?W`>'1Y!B$Z@VQ -M!E,)F$WD[L%/[V/*!RM8Q&+2I!/T.\=_+*6$CC=G/('=IS4KF?W5(O<3!RG$ -M,KG:@48].YD$.VJ6+:YY/Q:DW())/<($G-!&LPOTI!%?G7B0'Y1"GW3H@,R" -M,D.U+Q&WBG,``1:>B_07,V+,<13#=QVMO!9<6I5/Z+\DTOTTUT/F==+F1B`$ -MU;DRX/\$(K'[7&_RD>7]*Z,GZ&(3E_K/Y-)4JYXG`C.=977GU(TCB0!LH$=^ -M!''^!)&W"2AKC\?KJRRX-3-<_K??-`)N.3P8^:NI7SVL'^T(]^R6"K,U>'P# -M:S7L5/OL8;TN?19UUQ:[L47QM9S1!1A[Z![5N82J_$0*K#@C5E`!['ZQ\%FZ -M2ARXPNRN--[:2<:9M,3%8K/-U2<6P>9Q5/_G37VJ,37P#GX#[@V>Q`=4`?^M -MAZP6YX]!IQ]UE9JFL9A=D@2LU'9384V=&M7/G-;U3=J;N&)/43S+\_QS&,IB -M[O>N.6#K6'1MAS+,JVGF&7ZI6FEVIXU^J]X4HKFI\+P)3;:(T7!U4D3WENV< -M="0BV?I[7U?!VA^)G=VNYR;IC&05D<@L/'S*DF0JHHG@W\?A$%MBRX12)4'6 -MF)I9!\'L-*U"M)Z8MZ%?L'],WG@9%([9I#=PR)V8B>N2QERH7!+RTYID+7I/ -M!;?5-.3E(:?B?`CIQX8-ZYHORK^V-7+<#BAO4^2.CMQ'$SB0L0*N,'ZAE=D$ -M%[BFL8_*)SLFRT06R^WUV9'O1R,*0G#D;64/35`&FBQ>D"+4.3QU`3H%1LQ/ -MCPM=6PY>"Z^CJU8W`TQ67:\M'0^30&8$1G;\HY&O"_S]#$A?B-;A>L67GVY> -M*M*FQGUN:_>%K8Z5*&['#],A5L[%&:.N"3:]5H>^O+3:8)[DC)RSC&U3T:@J -MF3NDG=(N3Z5HAUY`7W:W$RX5=-\.%N#&YOP]%,"__52)UV.L_)BTQI'U!XSKS:7QI;D7KJA -MK+>PK_1539#+)^BZ;J?4=ZNI?=7&5X-O^B)EF=*Q,5RX_N/5\R(G]QE8R9D" -M?QWC\'7OW#O(2`,@5@39P=45U.+P]&TWS? -MKNP:?S+I3CH87+DP*6?6Q`"VLEW1*R++M^_';R.BLV+ZB\JT[DP[;4SWH:&O -M+[.*J>UX8S$4>Y]2"K@]%KR('8P/>4O6*XR6U*N2_`%$@,BLL)Z6J^!$QW[7 -M57-YVHJ^E2RF,H0/80XSK)DG6EV7>)QJ8SN04LG\10(B:#4\WF0"UZ&DX'/$ -M7O?'5_KW3\T#A4CLY9=V.2IE#4!8&S,?Q645CQ?BO/I$'N6^4]?#T3;#1D]I -M'4%=Z!\;XIH']!+RE,=^%#P,AQ7\$>7A#4-_PSXAF200+6?=R.J$P\L;P\'3 -M-S0,)[>1Y10WI.$Y]L`;FZ<8>9'WTW^'W#2E3$2[).-JGQ0YQDSL"69;K.G< -M+KCUR7Y&8HSUFL$YB$<$:G&/L6("TOR2CEBR:O:2N"%^SV1&>8^N?E*4F%&1 -M-MPMICW(%9=N3!3R.6`4%N@#(M1\*"IC;PYJQY)DRKX5-L%_Y%Y";TLX2:%/ -MBD:C4^:-5NL.^L[B1XB2D-/1$$2!6#OKD)V=-AG+6!CG#G6]Z#(RN*\@RB5- -M'X7\&4,3A]S&XW""8)<,Z"6]>)*!W,I2I*FBVTREW-2^K -MM&T;-1)_?28$"%6C(8C'OD;.5J=Q)KDY@T -MU('P,M39^O<(JXG@B&J=M=Z^FG9"@ZOH-'L46![E"YRT(S$&1(Q"?3B`N%KM7[N5Z -M^6B=5/H6?W`^;66A%,B7+G&\<)0:&`2-.YRA'@>AI-SE+-%39R+Z+%J[%>Z! -M0-=($.QBV[R]MF+(_?UCC5A=GYUOQ[B5.()TM?!)TR;_*L^!B?5HFMP/Q.BZ -M+Q?BO0QN\+&BRHRF$!FQYRK_F^%0920OZ[D,@*V#-N4 -M4LLYP;)^(.$_]XH]&L'A-TVY8%LR$`+#=P,U)<3*.,@S6_^65$>*58#GH+)Y -M\)JS&O7IHL^M'I5*,)7,Z&T40X2`J;C2`@-=KE-MTS':6[=%`[R;1D&_$(L> -M4):9[U8!8QT0$8.A0>./'9)`=5M#\D0I'-O?.?`>IPYNB>_NF?(MST]2%3^X -MS)"!]#3%ZRAD5L(OUL-"8NVLW)0BRX?O^D@OQ0&7.6;-SPS*B4Y>SK -M+C@L$$:%D#QE>JL3=,FY-9%%*4.CF..\ -MKKZ7G?N527[9'.H&6@:F30#N^L_/8[EE\@/A87\,3B%E>R@:_6Y92"P:(!=_)\3W] -MU%=VQRN\2_Y,"$X4`.?P!-_JT"\#;YLNV0(+H1]^+1;LYWDLV6'V.30MPBOP -M&J0=Q@E3'R`'9`>D=5N;B>D[N1KCFQZGG!^1.'S'I0&K(=G?_2^"!$-2K;W3 -MT5D,`9BO'VK)S.&/QG)L/)P,-*04K6-N_%;XGF9DZS72V3,"+=F!"]\*3[)D -M`!+`EW5:2@URN9WGAHJ(CCTBDC1/C`ANU'@4L)GWHEBW*QI.TE -M'+#Y_1C"Y6;F[;G7D_E7.%>,+'Q4OB>X?6Z@/?0H0DQH)V<.OWF%Z<;.H,L[ -M!<5DC*+!Q[]S3+5*JSJH\>[MEEY^^!H<[>L"[#B-JA;NA)7P=:KGHTN#!86@ -MC!8]+H^`E75L);I)(O>-+\DC8\%M*6]B=Y5-1ZJ&J*JM,/S>))B:^_D7CV'X -M08`^K/7Z#XSYZ/0=[T/Q*JW<="\8L#<.!Y25DN4L(YH+$+/S^.9/F.PWJ2@Z -MJL+>KB2X/_`=IO9KH>%"W0G`777QU&G9?N;;#\F-LU&6B"?.[\N(52$G]>,4 -M6V4NRKL#43W249GA_"(KX*'`KWNC3U%9@17@.6CRZQ"4N*Y2&.0_V4E.1*68 -M^DH1&:58<=5.555<5%[4I8M,*;3EH*T'P^S!\!&/SMWK>D?/H!\O$=T`,9%0 -MB&DL'O])WG,5'4W+`^YC^>^ZJHL@4S0C!U7,Q[GA=CMA>9W_$%!.W!#MG)Q4 -ME=E]K$&)NRF[2A;E]Q$YD=77XHY)7[^F59W)IG->F+(.%]46\H6G"-H9GX>W -MO7*A<`-,30MX\S,[SEJC>M&CGE7/LA2Y>B<9Q)6A=#;=X??/W/K3ED1K?YZX -MNGK)53T+N,H&K%]F:QKVRAJZOS'9Q$#>PF7U*DA!.C#UX-RQK8P851^NXG"O -M]9.Z/Z&8AAO*WM!5+%&!2.FB:;3P<:'W^*GKJ68:$,4C$K;[/D7++V**+7$A?X'-):#&\O<#X&-\+%3OL_I/@IW -M9;T=^>OO/3L%8<:S0TVDE';QZP#]B]6X-X.(F58PH%>G^VK=."BWJH;8[I\? -MPFEFRQ4'5!7'F*,>]"VS\]:DY)$3?VW1F_YA]`HF76S]-""JLY=)SXW58@)& -M\`"@J,_@H@4/#2/EP;8C*M$D!5!)A""$8.#.7`\R[[Y(8>2<)-"I%7L))!%& -M=OO9F?9%Y-6J"4GIK3O;GQ24_=&7P%9K!/8L"[,0 -MJ4'_+AKIAGG-V%K(17^5TN@V'L,MU1XMWHMS`(K;.8]B%F]L1V&=4W@>9#*8 -MZQ;!!R%9^K:3?H[_6`GEO[CW[R1#R5'U@@9H,9^9'6JL7-^+F%15QH?5&@L` -M=8G)U'`7&'@=YTZ2E0W.J^^<+=S13_EU,"HQR";.,]PQR$,%8Z1XYM:C6WKN -MHIZ%STB=XY8[8-B5P8`A09S:_4*!\81[1(IX8*OK(S$1Z"T.A$=%#F.ZG$=< -M$\.[=LJQ!FE2$>V`^/\9(Y:F5K*C90_2%"Y-@"Q>[>&=\3$WT.J73:N8IWOB -M*:;AIBW'7$Y;#QDPGWT(\A^UO@8OI0=;DZFK7^@8M"6W$5]H+?5Z^CXW!2W,WGDIUD -MA!98^&B_/6=^-HG` -MPOW;RN-N2?50%A9!MUVBF?Z3(;X]>_3FB33!2^QWWE$\>+[TB>XL!K9(DR!+ -MH"B7)1/C8!PUA^$RZ7TA2"9`(')1U`:I:TX\&]HP(X1D[OJ+4=O,08]X"]K8 -M8)D=U1!QWX7F_O28!LXCW'0N&Q#]EDY$2&.UF&PISD4_/O).PF;2035_"9`. -M.3P$\"F@:TYV;H2?E>V7R=WJG0P6?8T=%=\N`.^0<$XTEM->PIZBMY2^S#C. -MQ6]7"@Z^W^+G`YR$026^6^9C1Q>#]Z__H$B1/@T!$0T$F_$VX\8$I4'T@3(^ -M:H+X5G"Q?'YNQ-#6(/!!?E36B/=G?*YD@7C-TR4JUGQY4/L+OZ*:=3\93OS& -M:*&E)+JTFLTT9150UBF"@)DB%>M5@D4R?)"]%"^81M_R0,J;.`9<&%6JAP1" -MB4WG&JH+V.8.Q^@83FMVICB6G[/2_6,+#ZC6EDB&!?7T`Y\3O>?JA,B\$T,Y -MPMI1%3)@*"P+W.79-9*GE)U!UH+;K?G4[@Y[4Q.Q9!B>QFZ^Z!P6@F"WC/(: -M;*I+[\F4_/5Z7\E:Y1"(?8%++I:6/3/1SS.6=<4J:NSKE23-=B^Q -M8]$B?1&>T_0\B6Q`WA2>$&KDD4%,X!8%P#?)0,H'?=T^2BUCF!]+!'N8Z:Z; -M#2S(]`S_!GI5G@.\J2]X14E(EX.VR])/(LG"GW#U6&./V+BIOBI+?UM$,SN. -M#J3:K$1DZO=VV5)$>`UE?`?\-$8#I#T$#_V]Y\;IBW[A89?L_IKP2:86D6<[ -MOX[GOTECB<*ELYTD5'*[X]J3.C]H)`7V5&X]A07&N(`7>!D'#':F)Q48E[V@ -MRJR0#)3!=E2*FL/\`A>(W,<;1;EX+!3^'.3_L,U]H!+)B4^SC?BLQY -M_-6LBL_2B)5J2C6=(G*]('G-"RJA5!.YP"K%-P63=QI2%)/F&'Z(:_Y3Y0!? -MT'"5WF(`%>7E:G.JE"`,$J+M^_@MK5V87(-NSYX&N]VVE;T@,8Y4,/)(?V)N -M&UW9K-$P/1)YU0E;6:H.TF95VHTRECW"QOZ?7C)$Z+*!0-Y=D^`<9ZOAP&?%GJ-P -M?Y:Y/>[U<"[_>-$0DU#.YU?BOG(0>5.@34%L?L15P%W!`J4QE#IQ%1X;QAP/ -MAENL"WBBH!=(`J+B=,T'"`!4E$?\(-1%2>$-AV1.*H% -MSRM61Y2J=-)Z_)%Q]A,N7=:ROO4WA-TY&]1=5@K(%Y[:7&?X&8>CU2>3P#.Y -M^EOVU=+<$5"]Z+=3_:WLZ:FO$/FW\G:"1`6Z0P8E3<:G2:UT"SB."USG1V?[C]E/+0'%U7Y%/06+^",DK$$4EC6%]Y)[M_V&HQ!#A -M5>PYUL%'(H\"4@VJI31=#-; -M663X%_DY8518; -MZ67SAT,H+&`(N(VN.G3#VZPI&%TLUM5'KJ%3"KJBG=^N02[U)EIZ0:XI-(<- -MD2=L>=YL$4]%8?&+P&N=DI)IED'E>H2D+@6V0XLF\VXMD3[QKUD$\*KX3,/A -M47JXU%@7JW0#%#7\3))D?NJ,W2T)2^9V>&,G5#NSLZ=FSQ21;[ -MR&6FP0F#8[I#6+EN4O#4>]75<(?JPQF/&,D.9/SE-\#^Z$TDY)^I*[#H_[$6 -M;OFH+0*-9:$:II-PQ8,0W7:SDT(:J-W)(->BRQ?+(!/+>,@DJN5UB&DCRU4@ -M;UCE=S(A%SD#W\(-CD!9/\-_'C`*YL3PG`NC"+S:ACJZVH6J\UI7JQ)"F0ZS -MJQ;\_HY?DJ.D/XB<7M@\7TTWZT[=PJQ46^'[\!LT1Y,S%YW:\I-)OUAELYX? -M^$$)\HD;],PIMXU(:0# -M,4!R.P&[,*`Y:=B1F433%88JLI6Y_RLJIJ,CL92X6$2Y=RVDQ77PWRS6F75M -M"9#42]I3E),*7I14Z4J>KX2K^B'P-9.P<'6!:OUHA))U&$YR:Z:`XB-A -M8I5[>)U@COV@!\?W]PO'D$[+_/CPW@`!>H@*GU'\BH3"4B"_L4B*HZ)VX5&X -M8">=01KZX)B2RC,XK#G4"(#0^5(Y9P>WSVQ9VG^-,1#[P__E>P':U#=?5.,J -M5BY#QMPGP&3(Z&6N^7:F.JQPJ8*_L2<8$=G>JU`= -MQAIO]U$THS^F5C9]0M"HU'#^6VA$XK7WD]';M#(\33CZ:_T_<;19NZ!&)XP" -M16*I"+I@:_8#?9X/-N$>"V%GXPB3(@]SK=)CH_8&6+?KC*)\AY_G*4T_:4LY -M!*%89]DZA&4$RVBX5 -M*X;=%$-_@JD#9\K-+CVVH\.A-+XE#I.]U_K&NW]G[XN-38K1G%Z9-](PC1+M -MK\Y6RZZ.Q77]2CZV))-`)CU>1-HXUJ8JN\_LO<^J(SE`DC5)RDBV_W -M;]4`;4%^%Y@`(7Q+*^`&+,^Z"9OTNB\)@TL^KYKEI/6=G/])_SKAO`TQY*K%L\#R^G-[?$X-OGR@JU=S%\51@:#J@9]4 -MEN:.,UO$(3D<1GC5H:,D]4#=#-U%[U`RHD+)3W86PJ7;*'ERHRE\?N@:BEG0 -M0)T>4?QJ\"UC79%54X_X7*>8;2I277'UKXHG[\Q9R1-B7P=P7&.$*_U^V.W= -M-:&Y`+Z?@L1"QL4'(#3S[0DTQTN"@T"N16]SYM*DI.%)ZPUI(\Q4.V@(<1+. -M2#4\;CLWLTZ:O/3F^0BHVVL&U>6N5T2F5PZKVE;-?@MAC%^+#Y^`^_>!?SAW -M50CC8HMFX%*\+NB@S,XG]FT7G>MZF&'*=^0!.^>9NSWBD7RNJRKL[.T7)1#N -M\:LR`DS/7C8@++DAU*0[$E@5Y\[92&):&FDL0QM]9,C0N("`^1:EFK`T/LH5!^0)I9F -MBO`)#[8;?J[9IE!#'G+,#3=_I.-;'_E0TEG"*^+`527QTIK>7CF*;I.2`/MB -M]"O+)503$ZK%8Q!V89YP3:/-QT(0RZF9-G2BPDUO*_3G6_&_DN.0ZPGUQ!EN -M@-W:Q-K0EXRA/QJ7(V)B-#8:]`F3S0]7WQ'#'!@5?7<>)D0MR`3(]>NA@A%6 -MJ/4&\]8%H;B701'&/Q][45',,,!.&V+;5!1F@N%2`Z1%MS9VC\;#U*,+6R*" -M^1X-QPBLS1W.;L:O;]E\7]!HC>9'EZ:REV4A?7!0/-+PJBHIWI8F9 -MI?`L6I(?F>K6DJ'%T8Z&HA9SY:*Z=<-H9]KAX\PA'5!SFG`E>(V"D-QS'O'- -M5P^QL#O/?UAX9#))6:_NV-)UHG>)(#5$S&T6`3C$5'!B`F"]^*_1J773KR75 -M!^6FXBEXPAK32A21)63/,SNNE3W:WO%KK.FZ?,_F?E_6MIY3%0;+U07`^0P0P:%T$VJ:`2KZ(GRVK" -MV3N(W]?G(0'U\P'(O]2T<='T-6FY[Y`H">T+$SCQ_2TSA1'B6FW4OTB+YQA( -MV9T2=\AEYMX%D-MYVI8LH2"WR4$\*MNF,$WEV[:5_&_QM@H]\M'>N72,0MQ+ -M)TK&T%0?D_^"/)B>YVZU:>PKI_*STLC)BO%-!4IY^TTJM0@)@(UJ(/Y=Z&\6 -M0M9V(,#5<-LS/->CHH\;7[JB0'S*E,A!_D/I%HO]H%PFVAN,!/,!9D*["].C -MLULD9ID)2>M%'.FYS%L48GK<(QL,8"T\JLQP!RRQT]S+AN"H:9A\ -M9P1K622J:Y#ADJITT0"?K0 -M^@H9H"G3U8E@:WEK@3P;JL6%$"[T.OABA6Q8G5(/-/Q!5I/>S -M)H[='[84,KY']!-Q\EQS"9T$K])#VV!FM,&O%\NG6"'\@N]A1),GB8<$SK,0 -M"GVY%8T3=M$AZ9.E!Y$V\)%21^J7D>PDI]#*4AC:H2*D5HS6N+/#UK0+0S,6 -MN897=8E7%Z5:6&_CMKD?`D)8.%56US!BF`SP!C9U3Z?Y=X5H*R&\VFJG!J%) -M0_VW,,'8VJFP&;5@;'P.-UH6_$CL!?U+_X57+')NUDU'+?:,]"#J%F^U)2EV -MTZI,M;ENITLGP._S"WU#'R1;1'IN$)-7S\Q,9*LB0[!CA./Y[!-5!:F":`_' -MFLHT[071JR!6BCP?5.-!4SM=S9KH\I>,E"$NB@@%TLQ9HQ&`:C0CG56$.ITG -MRA5Y\YM"*I6=GAB#D'+>VEBGX1?K#AH7C)^9 -M,O;KP-\83#PBF_#O8G4W;G35#AY;B$*5#2\4);&W&8?MG2)`]@=J4M0)/@F: -M[W=G?&:"PX= -M4U@5^[_[R`^C&/>+:V>'?P][N-W_3]IIU7:*OUOJ92\W^-/1IDB`HS&GWOBF -M)$O+GPNDE_C(-'&NJKFK&',6F-#TXB)E?&9QB?_(FWLL3U048S:I+Y":85.1 -M8&XV-U6X4!M!WBEMX8WV`R?,V!M01/*%ENVL=JWAZN^7C?LR]K:,!^5K`F+@8DU-P[_G.A$X>@."SZ5P9 -M*G4)SX=5KF0;R!<`4WOZ#O[9EYN%,/9C-*#:L+L:9C".F;*5@F/J#B$ZGJ>9 -MMIK1+TCDLKL+2GPE;Y^\]BZR>M>BN'\-7I*UGW\+MN9`>+N2$4]*PW]^#%!G -M$%[%?N\EI<7:>-;P;XIV&;]GQ/>>?1G"K#E%RJJOB@@`.]U02.@$N\X_HCR& -MJ2;))W^#"C>'ICR5?/B(4_ND),CQ73)&<)I0052WU@%U/''(->=I+!MUL6&U -M5)I9O-IAF!2Q#]P7\$\EC: -M@/>K"HC;X`*]QC^5P"HG$5\B<'T0`ZHCRKJ375^GX80+-T0P`%N\/*ZX2T_F -M'GK*TG^CBN=MTHVY&4;Z=I\NQ;X*54SA];K\K6O-3C(&9S;'I$N;>)A>M.22 -MR>#B8O,J!I5%5TV3(EMU23K8V*:NOQ>$.BRB4W40BA:0,$4DA>,EW#$3.GZM?[_S7.LFOUM<@L)6Y-@;A3?!LD88IFE -ME7YJ"A$$JE\D-TIMLGY+H\3J_?()':W8<$]I#*0OF>KXTH1Q79!,WX^:%2[: -M%*F([+_<.LX,\]\@T]'GTVVU\-YX,]_)/,*E(>R_X%9V,3.^"9HB2EHK-%06-@TT#K7C`_UAU>J\NO!,5H4%#(N -M-SA5[O@=966E?0/ODVIX_%*-4',+YDR>,=5_75O)$6)Q9M0,E&UN1V(+LAH2 -M2/I+X=E$%?F0`K:L$2\DY*8"'6$Z,B\7V`)KMQ83>$GB@0`YOT9NIS2SK$T!LQKO$ZA$>['H+B2M:$]X!?9'Y=THE^D5N2S -MP9D+KWFR]PY[S5_NUJ>1]?4XTA.^[89)T3,N?T\5L0I?5#4$18'WZZ6XH4=% -M1TH>M@&25C(#&D*%CQSQB6HENJ\>(\OP"%IO*[4J_H1=F^SO;.C,>HO8D#9G -M@(N[AY3.-)9_BF@MK!>!B/V(YU\L_>&0LWI:F467[9,#\Q=EA?70\GFALWV5_!=POU[T[>,,3W$D1-._UJ^ECQ -M$^D;P*4$$)<;!"*_@+/',.+G4%*YLT[W/FJP)BT#H9V!UCC("`1144I$N4@Q -M&9.D7*GZ1F,XVH*)%BZ!\&7-6]#2S9(K9^WNT#PUO#+[G4S]YB'U-+$VM?+5NOS]U?-5654I*;O@7[`*B,:> -MGWJ5YA$T@1&"Y;7S-"C-WI`96_J=(OJN'#;+D7PK!]W0^M>A$-R]<1H< -MDW$IX_W8+[Z/`M:^G/X=*)#M/'>*R_+#JLY7\:62/^Y@@D87/.F5*2=KC0O" -MU^]Z<*N--_I>V'6@M!-##I/^JFUYC"]6,CUR^X-7VWL,7&1`-2>2/S5.6@V> -M7[W,;90#CY_>`RC7(9!>90KH?HBW/4#1\T0T)R(OSH)+JPF5Q(P6\!D.>G7" -MX/HBHC?.;J`<16=5@2+=%R7FVXNZ-%Z;!F)!UC",<^[$_R6PB..IK+$%B=*K -M#$-7/%33+Y=KO>QSNT>ODJ`\D0>#@*#ZN3KRU[@J&B3:6+SFN]GV:^CW0*Y" -M_0G@.F&T%(^S*:TE&H`J8!E;T.DD%)#.]%1N6A[UID]'498[HY+-K1CE=YU` -M+C"TIQ)E-:255:9';?OC:&E:B&A]H$Q89S!+Z_T.-[GTO%B%%XWIBA7'B;+@O\%M*1,7B%H.G*,0YR_7L#C9:[XOQ`B\PY$6D2S0:J -M4Y=C?/`MET3((>'CI%QLWZ1)`K:7H!7.;JB^$$;]V,>J4%/=P$]M@!57 -MX8#4>CE[!ZGAK#K0I-;,&D&M*/?,LW\N40*>TC%L]1.L)+(;C-,NZDOF`.;< -M-(&/['<_S%?0:^U\;8"5PYP"EC+=I^*%4OB+Q5,*8HC!;<.2"@GB3C=;>;_V -MGA.Q$H-.\S_@/ELYC7UN]LAZ>'XE.1!MG:$`6#SAZ/"@@!*LTE>8QVV(ZWJ( -M<7J$@J.=D*SMRV;E@N%M(.&@1RUEH)`MFP2&_KP1)SBJX55P:KUQN8VHF,[5 -MY^^`G8FY,>H"8E(IQNWCW?]"PJ_CS0:"=&=//GDVR@W,Z&`;<JCP_>%RUTV0QX]>]B=DEN/MP0'=OVM=N%CS'W-P>!^0;W-JE="3G9`IV' -M]E^91]2]8L%SN$#J\M#@/3LZ&-=MJWS,]K]*6]R?@9J2[KM9[7^::!9!L%P. -MKRX38H$<29@@0)K)M=XXY#Y8QA;R.2B*76/L"$N#V5>RK+[Z;FLUG2W6-Q4[,_]68GA -M.#*@?_1/9(F>TA-7?(C)Q$J872VY2.(2?RT(?N$Z$A$P+P`AE5^59+-!JC2[VGB2/9G2W9N -M&2M+C`(6BXXTL\T&A%LVH,/"-C$Z-;1>LO;73AATN`4K=R^`;Q!>4[EBM'-I -MMM/\2%$]@\)&30H5TI%#U:HXFI6-D(VJ=0_+AAB/RA_^>J+L%:M^S?]'4WWW -M"?A*2UF6.Z"%:$IBF$+E1?C<^YM-4[L*R;S`G(08)BW+7M&)T^9;,]G+: -M3IL;1CZWHV7%Y,-O2DKWL$QA^>=%#^(LJ]WK_#7<=K"ZROV-P":`SJ#S0;M[ -M9_!IT;T\`BR<><&FSX;HWM:-'36R<&19")6V%)`%$%(<`E=F9 -ME]L\F)Y3Q/\-M"P#^D& -M93@/D#WY1B"((>W_3+]*D7FS46G*$K2%+*J/*V*JP'ZP@B1O/8.X99<6<^G7 -M/L<#/KFP`Z3+&1AL+PJ0Y%;_8#S=2IXVUK:HH -M6M$\",%QD>.?=GM,3CVR,/8K%6CRGN1.IDJ(&0X+^BJ81TFC!KY:DR$(DC7M -MG1HUF*[^3SL6HT%7DO09MVZH8$RVI;?Z,D88<-YKBJ:+^P@%=+EU6L4SK8/_ -M5%$;X4HA*2V5[;6BA#$:D;-AXCEVY7(1H"52W34/RW'9!@JRC-C/E`KHVK'& -M=P>]N<3[Y]]FB1NAM5M2%`')=/>YE_GCTZ2RKA%Q9A*-?K8%J>T])L@0E'20 -M->`-!E"M@S,'TX/L1;$AW*9`CE8LF9U/)_^Q\$Y\$&QIVQ9PW_7(_N'9 -M.Y23+6OZU+^H+YH@RRTDP#OWD-T?=_"GF5Q3@EA-CK6HWT!F84^=6IXFB&"I -M0D:VP[[NR/E%FC3CA(E="=:K0F0&1D1`?87AJ\@I%E3_UM\^AIS:_GRNT370 -M-0&:Z[%LCJ1+"+CC<';<,Z5:V\Z#+T$"4AM5!;HS)QVZV%,"P1/C6F=-3$=3!&;?+1.] -M+SIH/-IHOE*H!-.Z1.8%Q6_!HVQJE@XBKC*,.,ZH6)!@,1\[$`E4GH/+'[P# -M,V@S]UC^RR@2Z92;$DCLP3KTITD[':290%::VA&ZR+NO5]N.R306>4=@AGK2 -M]BIEMF@T+%)XG['*C/GFP_E6^4@Q?H';$9G"&T)1(?333N)-P;/WT9K*K&-,#-H@[+QMEL/@,(:H4*@+_?*TV[(>@,&T1"]FS^2SJ-Q?TZ?:V+?0JR?J:;]A4 -M&WV=DQU/`K.C_0"6+$8<.TWM)-#U'\ZF,ZZ(A8SGO2V'7/:!)85`^`-RA2%9 -M_!`8`P.CMFN]66N=N1PA)RD!"8Z3%=:N@%S577@,"HCQEAD81Y.!>#? -MG%UY;QEN.L::6N1KRQ>%E!_9I*R\H9)3[!FO>HA158Y<.=]E9J_+"^<;I>YD -MHF:Q.P:?M3G-:PMZ*0#^-2F9CO<'%?P=]N9.':J>+,OCJR1=A+A8+ -M@X):_H:.CTM[I07]C.[BY'U?76"0-,8;2Z%F%,>[1E[(W),\@$O?W3TZL1T] -MBL'_C*<48@RN`5!YZAH?H"L`/3V@\/#/$OCE,593FP/!T1.1$YZIQ._`%"?+%>G/N_HU!:5U]VG+G154 -MWF*"SB0^.%MSIG%-'Q41BNJOW^,?N6P)C\FYERDX6(W3XO+Y3Q=SH1W6#3MN -M-W>HX,X;H6L!'*QQBF'%3O2Q7.LU=/"@P14"$=.1/5T3*-A4T]D#W#C:R,31_$Y1?D1J>F+>9;[R=^JFV`U@ZR,LB43;83:X3 -M.X410W)\RAX=[42W-O -M_AR$S@#8,73I#Z9)5&DFOID`+2P,/A2!6H))-]:M`\WC$/6$OA&)3B9.[O])1=^7/%\8UTZWF[5JZ3S_0!4 -M2/MW,>'9G^86OX$2-@(U99=&KC'K2#^F-^D3\R!G_F0>B7,U6^R#2H.SMLQ7 -M,4M3BT.^XFVTH(T1+*X]%1VK$P^G96Z]Y6(3(YW][N1%MA0D[]0*^E -M#3/J9;E4F1A4=36ZW%]H++5$U^![=>%'#E&F4?G%WV''VX3MB1I.C2^-*UI8 -M+\?L(;-[YJS40$]^)HW,%.F:X)NG(GU\!9E -M][+!RX<_S>0P7I)[H)39(MO+35>8++$A>?24K1]B*P/@,GE.==3[,-:Y",:C -MEF[Y;B`@\"G!R69_"72=%A$.*F9(H^!/`\,#&3W*B$_?LJS<#$X@FK>FIT9# -M4QG_7U;[R$4'DOCG4VZ02/\LF61N;5#-+)\F8T8PX=*UJHP@G^XRE;OP1$C# -M(:-A"3>JY'1]D3_/<`?<4BLD`0^(K3VA+K".8'8+DX'D1!&A9#,H+N,1"JZR -M%5T9U\D2-6<^%F;R%P1><,PE4@@481@8%[!;;0%AW6C3PB7Y9GPLE54U%ZG& -MEKAY]1#-&L3*8K'G6;T."0A*M#=&-6><-42)]+]=EK6R(#9+R#HYZQ; -MK&SV%.\/(\%A3P\`>T3_RR$V*6A*0F;3[-Q*T28H0\VEQMC.=C%%O):Q'H27 -MBL4,/B##7ACV55<=P5OT%ZZ0^W*8$40!`%H\JK4*T/K5V`%'_U:/I/=$,]/W -M%%[>)(WMHC(8G&WNE/G"-S_DI3E9ZGS[7->[=Q;;/#PKI5[OJ-X.UG:3#2*/ -M!R(X)D0R;.\)`T&^1#4C3@A]PJ.]],S/=->Y`26?T=%4QSWNF_#S6:TI1YT6E5/N.2*?9.9P*F($W;RX3;')B?J!L#R_H/%A*EY$T1&]O+>[QB`H6"K:2 -M,HGVK(FFH6I3)Y@EDODOPQ3`W09UF2-U)_$)%[0!E@@K-KV5GXC@J0C0DV%P-5=D9]"(`%50Y2>D^VPDH -MVYE[OKX,L`#ZXCRLR8X825:C6@BXRER14S'T(P1FF>:+(!Z@NP9&< -M0B,K_A=?GOY1Q&K/JOJ1>U@IM%54Q_FX\GH)5`J^2"L&"(G1'GM&L6*HN[4/:*W+33[T0UDABCW -MGI__X-1=OB7;OX[>I/S0=LD5=W8-6,<&^N-?S$T[#[^U.#AFD=5SD(RK"[F; -M(!#>"D;(+`A/(K6F[TG#?!CUQH&\$YH-I#B/GT\%_6[D^ -M>578<@B_`-0H3!IGLD\PF:T)+-J2R!Q^M_E(_:1IWO=3?<@+Z18+Y?)A9"0Y -M>6"D(0X>:\6OTC\ZD'$^LD(A(%-;08?&)Y^123S7>Z8^G@*(!V;YA.\]8 -M\8AN?^,?`/8"@^@HQP,[[2Q0KY9DFGS_<)7WG)YP]%LW!?4#VK*YKF3B6`$S -MDV:X;,1U+X.UY#IY&CJ1CD9/_4!8:G0GO'Q(>^KD4YZM.(>.:99"\)_=NR`% -MC(F:+R(F*/1&=Y@+(:\6>_M,KT<6AP.B5XW:_'Q4P"E,%V5O55+\^A7*4RG' -M8X.ER9H73.V%'H'(-KLX_0X^$M%LQA$-0GILQWW\CW$%$U"!*A<1^;0@*B"G -M>*\GH9QSQ<8L^8C7634<>9#7L1%=UQ(ZK)9Y9> -M:#/$:.G(H!X9/&_`UKS&L[PP-S[E:8O -MWM(+S89;]RI3P1$@B]TP&43K;/,DZG;-\$"K&-,UM3`?G#1H,`;U.*^O'9?Q -M,X_RT&Z[D@ED1_RR1TG1CPM\_8TMCY./T4`[ET;V2%@U:C$NLZ#I),\JN8Y(OL"OC:]Q]C[GL2:[ -M2.S`M8[>_4G-S8BW4;XE%G([HA[,YF*_P;F9_D2\]_LO*EDMP6RPEY1?P/,` -MQ*NP&B7BLC,_S7S#Y>\OHM=4WO-JHH$)AG+LG$\J8$XPZB/_!XIWWA$70]($$O`\""M>HH1O=L<.BH8=(Y>PA2'1/GS&FR -MS%$>Y`*=-3@:J9T661L_!@IQ(<28M,UR!E>CN"`@O-B"%"Q`QZ8P@=1K80LP8< -MX'R<%5`1R?-O51Z2IA-D&\56LV(7,>J"$[`9NTHV0\53.V&2_+<6$?DT,?R7 -MK^3[<(^/ZHZ.<54!$#+2C.E9"6K30OG[GC"K>6TK9*,!KQ3C65R$Z498IUP] -M10AD'=JW"F=/]#XL0IQ?MP?<&W8H@JY*LXM]9)5@F62_>,N`,[EB&-?B:W4A -M/P)_X_ZVCQ%U"=BH:>S)_`H'K(>G(JW6AGQ0\,0B-8CU,\^RRQY7#R.H:G.RL0:0&1JM^U]L/5)S,W*]V38JX(QO$D)W_9E4Z=[ -M#L`4^?Z\PK6E#6A"LPJ^I^;A">=5,2XL7N+6);B2ZLSR:^4(K*+^6TU%$$IJ -MA]<4&CV]XA8DT*`F@(9V]G6TU`R]LX?TRY.;!%%F8BD^WUPBF*$2EFE2HRU_ -M^K_9]-T$LH-OS&?<30!K'#P@KTI'A*0Q`H/NLO.F2E&CM=(B]&I -M"%Y[^-71*OA8/8A^[$5&P**;RD0-)IFLN&#N=?D@**PY-["H+?^N'G- -M1&&6WV^8XM#G#J^U+D?)IPT=?B9/^/%^YWSHBQ/,(L,C<56V[N$D*')M5?MM -MK0)UT0;D"G.9BUD2!).PX(2X':04++KR-D6+;^`HEX*?,L8LF\'DQ$PVBUZA -M7#VSOE`O91>#J)BZZ2A$=&6*W213%\]^Y'/]]MUA;M-S)";MP)JQ-BC?R.9.,/_!%T.199.8"I>5TD -MRRBG6'R+5,BK3_U&Q4P,46/\$JE@W*8QJ+.11 -M\YW@]_*SN!\/&@+6ZP$U.?I[W@N]:Z(0_(00G<'XD;T%%#+S-^ -MA&%?KK&"L`Z6,)YBR*RY#AN*_4Y!W!6LRS:3>_Y--"24139(HD]<7JI#UQC` -M'HKC3&K9'*Z:#?>L^G#&/UWSP>'AP(2# -MPD6A%60V^U)'8/'<:GM3ZVL=?1EUC(GN?`).$"D?F!3KBTP:SC)1I;Y*(-WE -MEC7L<)"$.F[_:"KS[UJ5Z110?Q+0`L>=/_L.Y%<&4@)D\R:/Z<^[%V?S9#R^ -M/T(/Y/)"FDV*4R/R"N_>AI9N2X-TT#A\=OI0)'>`QV[;E13!8[^BPCP5X&S% -M(X27O&(V#=[2T#/SY"SQFQ*_/A&_'"AB4-!E\3K)1/!4.VCW3W#K^A*Q' -M$VK=S3XY0.N^-QDDC;OPQ:\Y-!NQU85M^>,2RJYVB'#>/+@.M-H>ER2MCM%2 -MS*\`179I(K1RKZ%3N"06NFZI$F/9QR@H3KRZ9W4^"JK/&Z1W(G!'_VAX%,+. -MHB]Y_,X<3RKM)HQ*+ZD=9>QMK["F?U'(PC39L -MZL2TWOH;'#$14ZR(K`%?3=79J=,WO8&+:(QY4+T*O=2DK"UMITSZ[5\UN7G8Z:4%VM=IP4]]&Z1#H(U[4 -M66\@GP&/AN>$^@<)BF=)"[A.9K0QI<'$?+_K,`M#YTV]-O -M9J36R%3,JVWUJ)^:/W/SX"RR5]@2<`#.@C4!#IU.`NA^T:?!\;'"T4,BE?AJ -M#H%,4EHO4]"$W`?U4T9P4 -M+8/`O-E86=':H;+^>9B/]LW>RJKDU\AK;:`E\X#X!B7;01+O"3**=*2XD;X> -M^3+]@.@DM#.J"]/M9NKZNQ8237P,R]A77AOD67.-N']V+/DLTWA@@QJD=GH,,&0TDBHBX-S;(R=#KR&Y84!>@8!_<78>9"KRD -MQBCC4C;GXMI^,CQRCKC!Y-!Y($BE*P,0C/`RMX/0FZ[!-?=_Z2J44)=;5\VE]__S\@4HNGO\P,?Y?FK -MA1E(K%BI\0JNY0,=LHS.FL3L8136CT8%>I8^<*("M3.#-(@"\+C0LHX4NKJ% -MHB^KD0"?23@5+HH_VDWW'4IK%P>)MD=4K"S)]PHD&Q`MG[GPD&^5HY;:QHB3 -M>:<[!_$6[=,T#'&0(`#?Y,Q7D03.R&$Y'RA)Z8/F:J">NNQ#!'$Y.@+(ABQL -MV)]]8PE'5&'17H%MP4!%""KN=RA+T3T8_\8QFQF_>+4`_+6--#"F1J -M_JJJ[=P0ZFY(#P(L-\4.X1K;RW)-FA'V$#O>D<]U5;,&:9JZZJGW#M-)6VS' -M\T7U:VIN>[9;P.G,'%G%NM9!JT/VE.$47-?Y*-M5K:V$QQU+(P*?]LE-<9)- -M6,Z!KU3'XKT0?X\P2TG%2NFRD_G+;X4$*J%<$I>(?7._GR15D'._=ZK=!R;8 -MHOU2&$5(^2^IMO=-Q@DMZ%KG:+PE?Y/5RQUDU@43S&@&_R+@0[*+DHN\UF>0O_@>I\[XPV"']QXL -MY)(A_WBC6K-+D3A][HY%L(_<3)UQ^`/=FO@%S,PV.6+)P+05S^>D0IEJ&=W] -MF%AN(="IJM24/"RP_L<\MP03BQ9JWV70$OAAWL.U`X3'\`_0#F\.3I/>@OY* -ME/)(]G2402)6=JL4F-QG-Q+-X@+G!^*SZ3<-KJQ8+5;-VP2OK20S.3H"KG1R($L -ME+D_@6B-ZWY_>.^8K-]=R*/KW(-I(<0>QF@1$01UBX02' -M4I%)72,18'X[1I1^X/VB-_J3_H6>!GSX3F^N-I!*H1*5#!]58*68S/E1->&[ -M=#1KE"B>4Y0X&6=EOH\9OD\4E4Z'?F1E&"PQF59_?O>(0^R# -MVTFK]//.\7`W'9L'`>S9`)A4:ZUR/TY\*+FK3SU`%]FS26ATDE/:.JOHLA=> -MMCAJ!O_$4XK1RCA436WV_*"Y>L%G]5@'#^R0=P@C`MI_+&2 -MA"#P."1L*7KV:;0F`8[2C](_RJRTL4(W_EM"_41B.8AI)8BW4W+[ -MY)_EID%X&RF#;K#4V"H[H/#`K&BU[+H,5'NV`+60^>7VBB>2$&7,V$'W]DL= -M<04_E/*GQMP3"1V%;7+HK'-AP](L=XX+JJA5:US(;+H,9M4HS"]C^F&II6/D -M[\XZ1'BE'5DN[F>++GF,WTE9DO4#XQZXU+XE=K>#2_PGTYXI\1D),8HO,STMW3+J -MZL\5&U'&'\\/DLD<>H#-.=HS)LW -M1O7%RPB9&-$2[@;4.L,16)C&A;M'P\'NJTUFO9?\3(K#2+("80*S:R-#6>&? -M9;;')J&N,!EF1-:49MV08T-OW'K5$$!.S)EEK6`%:[!!&L8VB4\QW5`FGK;H -M;1S*A>S;U.VA\12OOJN.3U)A5C2O!HD'ZO>,>LQL6L6]X9,316D:Z^X?$B^8 -M.R>._/[5Q[X\PR+H\5,GUIL$N3,1U($ZNHHOYMDL-0MV\N>P*N+.!E^\L4R1 -M\[SP!TK>P+BL,BXR';!G^F*MLQ;?69XTU/>^BMN5-YF*SD#^0,G1>F50T6;/ -M:>",`G*POH=K040308T5F9.^@O:4*ED[IEJHCZ1']4F`:%$G=*?HS=HOQ#`. -MV%(0NQ^IIW_Q,0Z`3R%7@*<@'MABQ]0=+`GC7'C4SA'-*093_^&7C7< -M1Q/J3/+;#<@R73!DZ6@K":'=U@,-64>-\QQ9A]2I? -MC2ITCY84"F\T6J(7>[><8Y9;S&@+N:+M<.X@DJ^$U5=$CZ8P_.-YKS6N('8K -MIK\5^"_BZ"ZN8B.*[?AHJ=LH:#1L<(X!;&THH32XV3^\K>/WIK&Y;!RE'BI0 -MK'*-(;U_+-9Y/RIQ_=3S[Z@3:]\>F_5\%"5BQ@-0?T"R=:>B?8QMYX*237YM'' -M%L5>D.!:.4MO!/#0:H=7!PT]4!<0AT3#HA&2B5ZS53@JIDZ_B:]J#=V(3U\" -M!)U>_/46'\[!S03!(O;EII9^#-/KL^=R;V!1M&)$RQHSO5LW&,(@=3D>TTM!K..N_,119*1(E1D9;8S4"1XKY5'\0DJ[7?_V7%:G/45T8 -MA%'5&UBSXK+?STRN9ID=65F71O_9@E+8.@.ZCNY$J+8,YMBX&IM!\!P[/27, -MN7$8?A0#MHJW(W4@$?Q6_'<+^: -M1=80JD_O4@X\O(TJUF:_M"#S(=7M^;O'Y8U;F8$3-:&'W\G.%-;D3^%/-@P9 -M'!,)F$8+O)BC*C/SQ\J'K7W[ILJYC3?G,JC'&BYT3]_=MFGGK_A^,"(V!AE) -M+4IIDB7@RKY1NJD."7%UH%NE8'02<4/C1L%.F'I>7]XP&9F+PAYS2E-Z-M9I -MS`?8F-9IPT?RYK#'0)@`@'&3PR%G/43L=PV;XTFE7FB4F/2J)5FY(E53HN": -M05PAYR@+UF?<_S0_@^E0LA0EUW`(JHZ.M(&GY36"KH0+^3OS@JC7EB[UL'X0 -MHR_\L-G#79ZNJFE^0?L.0CI8_TUZ2("4V0;3/\$-N?D81$!:#`/^C#03V@5_"*V*Y%D7/(#6*$8E<[;[N%&6_6M-WHWNOVV&_]'7+[=LR9YI.C$/KG -M%M\!Z3OU)X'&=5(AAI,4>"0M*O[EJ@)9'\!)@;G&:!#V^5=5`1("@3VH&@6C -M[9OW,.@RZ00N5HH4'6$>$["F8?,50$=YCLX70V_9V]8BD/IC#D:\E'Y:5JP1H -MX:LB5MIP]9_E(D2S'*FJ.GJ31EXXD:T#8"&(ZMD^DO*6YLVX3760+7O`?SHN -M]XHEJCT!+;CJ2E;)1MZYVNQBY7^^'B4(I&&W!G4D`L7ZA^,A21W%_C&;9>/1 -MNC#DPD0;^'F3XDPXP"[6D$#+:!`S\B:I3-,[?&$:=%ZDRW\N5QT7%;Q?(S)O -M5ID?D0Q$+:GO="DY98'2N@@/"&?N5X -MQ+-R_8<%.=M4=E-]I-!W,/.\@^9SF8`!1[ -M1F5\7]U(A&/!=.!QO4D6833RF@D%Y=1[C9[7EW7`;M?:;TGU+ -M6NZXX52<73&T1+7;OWAU9^A3%*S75M=R&53?&OM"6!@EL3!'Z'9EO\E#MJXN.KA1.S\N9!O/44.O -M/J7OJ9$1:)7PDCYS)0FR]D7S>VQHK6"U5WS3V_,YW(S#1,O*_K'G1VL"ZV-Q -MMPASFJ5O&GNX04I-WJ9=`&$N=_]5WH&&G_Z-&%BYER2&6H24?[2M#6[RS=9> -M2@R\<:30CSR\S,A0<3_?FV91G%(HNKL24J@>TW0I6W"MM2!_$3Y[ -MN0=Z_H#NO`NG$1?2Q0M!9'>EZV:`/,7('AS(,=.B2XY? -M*VT9?CD2*$!4A$$T25CC`1`WQ*:^#QV0O4?MG3(9=-R^^N>$MC#42DJ#8A\J -MC.`^YA:3U\;%@&MHLZ0F<8/H.6,JZ`#5=,78CNAWRNME)LR@K6#BIN1?C-$G -M27.)-NI\1H#7UR8LYB0L'9IS.8UB]*K9N?'&N>>+XP-.4AXL?6/D<<.RO!P& -M/NT^#5>(R,HTYRS19BG(+MQ@[BO(H)6=2(X@#0[DM)^4[C)66&%*\9O[B/%P -MU)_?PC+K2'8$'TY,/(MG:L(I/\55_;\T>EZT'_3=&ECFCT?MH:9Z:8:&F+GW -M7:6YL*<_VZ>!"AE?1[,QXPYL9P%D;XJ=AH-;ID_Q%.%'X7B\.[G5F,059@H7 -MR%4[GWZ%U.0"9@\!P[]KB)Z_M) -MT]IC`XP0Y0U-AR;;WV]K#E"#F5$$.W]Y:#)??;J.CXA#4/\$+WEYL/N84^[R -M:O;UR4MVWYRZD1I1L_P(X%=1Z>Q-97YJ&L-MN9"M*&<;>-F9I"2`I==LWD5B -M43%@V`'XXX2YBWK?(>@DZ%X*X6I[A\X0+K5?43>&KFG>>R[NOG?Z>P;^/#=F -M^A1V*Z]9=0WSFHUO%/MYS-*\FE/1O7KUR10(][UQTVBS5_ME`W:.$^6RW@23 -MO63EHJ&\X\JHQ;YE=<1\DK9E.ZUT,A/OZR0]:2<;\O.JT`OOMH7`28"WS[%" -MM0TV$T/LI0=)NH]\YX+&ZLR>Q=T6:ETL9H1@"P.P/.&?4,.-8TIV@RL(3K]G/5D9\*Q?6O#Y7XH_M8+,/F4G&%Y%?I -M1!F4,IZ]I`3"8]`R\';)ZI/5&S769-NJ1S1PHN8E$M;O(:4]C;T -M5T/."2L#]+IZ+83'0XR,NZQ&TOP4OK&E1:PSD/?+-M1#S`8%O8?B;76P^@8P -M0PO_\6OE2"L5#*H*\GF]>-^1^AAS$5EH>;FY(;6D<8T^6DBR=$>XVK_K]LJ4 -M>OJDTF\Y7$IFEK%Z.H`P('6!;*E;GU4=QZ<3KJIGL!A5LD2RP*V!&:F".SXV -MZE/A<0HV'-H4"%(X)`#^"J7U'NVLIFG*9/%@AJ[;1Q\VXTD42$]2R;ZOAR]& -MNB$#R2^^DS/$0O!@NUO)GQ(-XC;9R_BX:XZ#:=C&@2_AV7J[4ZYB?3'L;O`= -MFT%3'I_C*KN5IFAT"02+X;QD$]4\H?.,$7Z)V;]\PC*IX#;D;EGZW$]$&-E> -MBK`"G:>(LA`2T4.YE!C;]4?EZ^R:DSO`)?K`5.NJ+<+1%--IJ+U61$>-#JY7 -M^U.5BSFX(1WI0<)(HS27[.85K8=!]U;0K$M&75.?J0GZD__4TP?E#_T`_5N( -MV3T_P:?9=I7IOI\V123T>ZES'&7*R\O`S-`WOPC]L#&Q?8$P%R2)8-(V1%N7 -M9^(XJ_GNN.A0[UPH).A-QW$B_7&VX*<':[M -M%:_WW"&3)/94X9Z^-'PCU"XHE,H4LNTOD0[A@5[!4<@8E8^6 -MPQ96\0.]]_VOP>3R)5)6@BH&&,/S794S.^V$-+@]A":C\[7P63E'S5.ZDMZG -MW!KHZVPZ+S:HYZ'@+W0G?G378)>TZ(CV#W##,5^6J@.IO':42.*Z)(JZA9I- -M,I'6.'U`%Q;IDY&!_ -M@&4X[:E2\=Z&TPR8MEK]3L.%-GDI*/1QQ9EGSH5&,RI>.0U(?Z0AY1 -MH::QWO^!B9@-/:WC^"T1?]`^68KU]OR0WQ5OD!EL;'O3]HE!#NRG\9!YH@`8 -M?+G*'58$>J$,1-(J#'4B\\GO;P*JH;?C?9$73*\CE00";]3$%`B8*@DVKV() -MD\SZ`B*$5NNK_>2_?P.2+HUZ>EF%[7A`X0\$80Q[-4_T -ML9N[S74I`18Q5#,H%\,T'A#%%!I$@H"3OX7?CDA1B -MO7C)M.G$5*=`J*\P55I&4`R/LT%Q>$A3M^@@'B3/8[@N -M'`#E4_(5G#TO9N0I,3L+[@'4]-F*\#:(Q(1\R.BQ='&D%KQ1R/46^Z84-OM% -M/K^'I<'H/IMDN)?YW3M2Y:-X>LXQ]V7+?6Q-&^X[6FJCZ@+C,68,='3$D_M[ -M)H/KYHDINM#]2F2ME?_%'^C;FJ=7`BE'KJ!N?I\/S'=X^22CWR9!6GKBZZY2 -M$]T#706X`L/,+:?@CYIO"4*GXWJK/B+]V0U;>(U9$]7)M"JS$#B!`O%)0_42 -MA&2)77-G[>(%KILXB](A\AK>SIHV&<3;4K<.$@>2U*&R=0I^V!+_=B>9,T$R -M.'*^$EC:T?'?U_BU/HMVCGJ/Q.?RULQYIW-'I&\[!VK)5^4%")4;3QY+F5R.3`SYH.'MH/UF -MM[";#TKML1R8LY4PXN2G.,I%6JS--7WVLJEE(1S=U7OY]0".Y.IPUP&H[8*8 -MU[C.$^CY$B'?\N^)*)6"7+P^XA68^MZ97C,EM(WX&A8R:X\KK\F@!IH^!I_@ -M<5<?TGF!H7\\(3M;3OD>.*:!M -MMT=A9\;)#>[I\\;9#":S@IW/0S0H[G%4>H%).<[40:Q(@_B/1+B4;A&(AY^%)@\ -MBI1%X_6FV@^BQ#2\D7"1*S-F@,YO[JI6)J5E`>I@'7N-&6G%[704)![1K+P) -MN?@7PYMO;_/,0F;RY:PE;?L(2BGN%-:"3/N%C%2YM44,R.K#\]VS::]XX[Y;+ -M?K6L.W+4]+9H_*\U'%QP8E5KQ2T`L>55G3W=5T1S,+59CXE39]]:PAN]O#<, -M-"TY734GH:-?VA3R=(IB=XRJC(Y^KN0QXCC]I/0A69?!$7PNBYH7+&7I(")$ -MJN -ME4/M#SX7V#B/N#7F\7$L'BDL'*S?V'^N7O3E<$(TN7`G(1J-!=VB(UU9*X$(,H7Q.E^Q7V?:Y`56=U\4Q -MV5=8I9U+,>`@#V?XH2E5:5GDT_S/@C(ISMZ"[YXN>,'MND^W]*W6A^.V2"H/ -MB?U71=;"'PWKM7>6N,YP3N+M.Z*BF++.X'!5\LN&R?26HQ,.%X;,T0@D^D'= -MXS^>J+7B'76N66J'VX09B7#`QF\S -MY_M[K#3:4ENLR6R:2W0N;+#*V%5>WKY7K`T/N:0Q.MK![>MI9D"S/@E$5'9# -M`<86'5%[!G6Y07*@DL/#]@B_=V]FA\5*+\]/=3:&0OZ2IZ\+G)Z3>EO/F60K -M2.`4?LL[F?CCBYW][:+J/G%RE8'9V^Q2D\\V:/6P/R[Y;ZH4P0531MDP3^") -M/%-5SX75S-?$NM8P0%1EK;0;$I_+\L)S3D)6?SV^72WMSA]);;!)ZL%MDIL\ -M^L+:";AJWWWSS?`VJ/]K4?95P@SC2_S@G6"USX/L9=L0[OLUAV]:^ -MS[$6`I>'Y$4&.^&[ODU<\ST%(YI==NS%E!>;(]K+S.RK^)`=/3.NY1QH^J@5F)T"7W>RP%O8NT/Q -M$C2=N?"D>C!),R>^0B15_G%DVQHG?=.[TK]-B5W -M2=X?3$JJ:]57-1_^D^8_E[P>XLJIR.//J?Z?8/K\CP\18`2F*ULY,R55S4OC -MMT,0M.I=E-C(ZMI4C=CZ=&):K[^`,V`AI@^WW/Q+`_44YP;>,;XJ6[K]77DR -M;;!;O#\$TP:@=_/1;ND[QZO8>JQ[,>?+V!BC38YQ)'0+_O=<"ZHWX+1K"(+M -MV#J!=!2(6L+7@Y\/A[UN1]7REQ*3IM.>+R/H]4;AE[;Z4U^:78S.9>B&RT)4 -M7K?>^+C[\\:(/H*U\8^'X`(OJ*/YCSEMNB60FQ1P$3?`EV5$5+&K6V&M?3S7 -M5Z1R![9Y]7:FW\:TEJ[^YXC_V;G`<(%_N]-Y+M(;'E\"RI,/]P+['KX@^5O3 -M^Q;#'RTS=0R[QSN++EI@%C?Y -M1B7K8[K7A54!],+ALVOH<=>3:/.##J!42R*LCW,X*@U%-)#)F#6_. -M:#Q3I`)DD+A%"JX4?GF?T8*=B<"RRZHX!Q+9:$0V-S1EU[G<+Y"/Y1)\06BH -M)?G\>57NOP-#=OKK*WIS93;]LGT:$2I\H4_NK2F,D`^,C$_"*!$5B)VU -M7-WMH(C]U0M:/(Y/%0/+U'X13H,F5PRXA$+H07=UN)FT0..Y;UNH,M_EL#JC -M.1GBX='&)I%N%4JPJVAQ>>5T4V&JZ6U_QN=%H\W3[Y7&,K6"83F^]/?F:B/&QK%_8]5KJBI(3@PQ -MF7_:V.U#ERTLMPF'(L21HME_IT9>NHQ$&&,2;$(CX*NLFX4LV$$15AJE6LUY -M>2),?V:.3:/![X/8JWXT9V^48?)IV`C[IVB1%%XII#"S5>.^:)"82#P#545M -MRG,B%K%#_R4B;H\EU)Z5(41AW?`ZXCK24)G+DL0QX_KLK<0-:`5;2OA"7'1, -MPM?D;70Q+B;T[TB:EE!E?!(#=(BM>=UTAAY)5$W)%RXBHZCZC[?/KZ,D@V]3 -ME$U^H#%K0)H>7F?Q/,/\*Y;^?QH&BCB[@B)3`:Y-*KRZ`]LN57J1+7$&1V;5 -M25=G>B+W2Q]5NR'J`Y(>-.\/UMWEU;(]Q@_IDRJLY<0WQ5NDSQ>3C-=MP==: -MJ+"(]P:^\>MMO#3L@'[-+!WW,?U*\M;&<*HNF%B_7&(57MO2;8)!HP-YXR/YSO7QS2OEI_1NJ)( -M@J"!'3,5\Q_FN[IC.XN=-*YM39\4E-O;G29TA\;VN<2)? -MDJ80$DELQU/56T&0(H7^\,.P0NW2.`JEI>51(!HJ.`[B"T?YD.VS89%ZGG=Z -MSP4?0=G4B8)HYT"UK$J>.[Z;_@I-MK%^.ME5$\,! -MZE-J118H#`BA;$)-VJ5ANI<0KHJVYK-F#+IJ@TR3?.(??>&:=[FAS#SU%FZ5=/](]M7Y^R1*]]!C[Q&*[RW.3%F.]YJV&J^07UU__ETIHLT%7,"%V@W5]9, -MB;8K719\A>2^6.OZPQ\1AQP!>&KL`P$#%%9JW>ZF)>L^XMK8<`?K=0H$HQ)] -M>Q!`0)I'4'0K>J/$2E-T+F"6DK5=[P7A6=V$3:V*^%_,2!FU*JW\(AAUC26W -MY.0URIDN`H5!T&*(AJ$96SN!#`S?MP(4V[#Y_&23-UL;Q(/&IYB]A2M>DG6K -M)+UKB$D7M0YA0%BC!IH:*;-^=]VR31O"6WC]OH4)(Y/*TGO*IT'\Z,;!I6VM -M@2O6J"+[Q=Z[ST)>Q%[3J"R@?K$>*YC+X)$-P'S+(<3.Z2S/VX?RD!6@V?5C -MT9/XSE3H[Q%&@7`@H=`FXS,F+S`QKM<&O1.92/+JH<6J%9HB+84S+!VB&W&T -MJ/N]$4\_C5#]=AJ"C#B/1;,DYL@%Y%MMV#`'`$XL8?G$JZM&G2O.#$QLKII_ -M-=^*'IY#E!*.(WKIVCW5F=^J6:I:@H@YOYDUESF#GK*%^G,IGL$$'7A66UMH -M*+X*0H[@4+MM;R^JWR(',X4LDCR<'"9ZMJ.S7538>-"XSZ0J9\V>ZU20P+S_ -MGJD"*YIA/('4JJZ[>$(P_9HC<$T[<\G12%H#GU]9J9HH8B:5M@?VOT>^HTLI -MDUI;O?PC"$2+=RIC=P[.H?28^**K#:_Z&&;[^1T4U=ESJ(WF2M;XDE7E[M>Y -MD6Y1YI#UDGND9,A?Q431:]>D".0(SG`!2]E,S%BOHT8D%4W*TN;#?3TRPR$B -MJTM9[HTIS_V04.M&*%%JS=`1,>X'CX6+6;9;60Y\O[&C"\$!N0ZP/F&M)$B` -MEV$B[&'['2/IG4#W4P"/RO_JF=]?@9#2"%FM%-;1>2F4L -M/8U>D!_`,FI:#U."Q8BI;\!-/&/X5/XI77O99'3K -MVSB\$ZP=8X'>3Q!`?@=TZERH08A92)&+GR,3IA"-%#\(I1]F"CN/4V[9HFTK -MU0A#PJW-X_5&4IN2>VEU\/*2&M>,1>;2B.7%Q@7F0;RRWQ#E,$;ZX(9++5-$/M:-S/M^`DN^:= -M_PY=@QEE*1TM+:]*909)9>E`M8'Z&V#FU+%E'R*8NZ.NMB1YP=DIL4E6+.J?T`I3/_^73NT"O*(-V?7+65@ -M\:HD24)RNKY*^5'=K3\F`OMBN#4LDM-.YZ&?)CZ4K[@;?ML#G$P8OWF,E -ML$*0H5R0!`B(78:?U)HEOA464Z]R+/"EJA8INP1P+==E4T_J[?O")#7ZN%', -MP#*YOG&WVDGZ[4*4_JF[`[:N\<3RZF=1?\&_`VOOT(CIG,.DXTWX>\J[SI;% -M/FS,^WB7-`T=_\C8=)(%7+EI(PY?"$]^OBZ+_D\&[>7!2`J*BXTU(+U[D-)L -MIL"!4L4M6WMRV-?*MLW54`2OPR+6Z']!K-2Y!4"#>OS%S"Q=E]PHA+P5_Q@J -M=KL#(Y2B^U5S?I/;2?]'Z"1[S[1U8(H0%S>IJ'3(Y$%;P-NN>)W+&+7J,45_ -MNT*62-NVEXIJI=+HNA -M!SO&.K:Y7M/1"^#06=)U0[,UQT!YU@FX9KP@33'8)`R@NJ][9(W;N_^=G`"@2ZMZN]N=$ -M)/R0\EZ#">O6']$BKB*2Q*2/TG+.QL]>)=TD)6_I'V3!UTT'X#:*R*,A]HD\ -MJ'DA-7%!TP`8,['5BI&\T04"Q.1RIEJJE1Q4A1>L4,P"-()NR@4#D1BP-9F> -MK$*A$2TCPDWP@VW!>E4]1]>%S7:<`(@/U4X>.]FG%3AV=\+0`X95_.K7\'0# -MR9LXAF0NLN2Y:<-F^*!XEL`=Y#[;O=H$CEZ[%LT:6=BK#.I-M^?@))@L?8#.<&^3B&`_MK(CB#?\QP(LH -M3FO9?K`,/R]I\S>_9]U7`(XG5W-0?!;9`($J>3(17GFX!=`C_7P[6LZYX!%$ -M=VT2]16J4VWF\6L>H2&`7?;-F8JG/MA;QY1MC=ZENE58DTS7C/C0JVBXBQZ2A5Y, -M?IH\,:%V>EC/QV._MTGO+M_XHUAG%V+""*V$,:ZD25UZ]HCE)M-GK1[R^8X% -M3LW_=]U^L>ZZ%X/Z3Z.]ZHVC?_;C409VPCXS%%&KBJCTE&JCMW,/Y=TVYSM= -M>&C:;/W(T4:&VC?,:YI0?M.`#]'AQ4GS11!?O]IP&GM1UQ..P4P[(U$TRL`R -MKFT<]2VRI92LTQNH?URUOO+$!'#1&>'OQ@#V__J3!L1?5W%UBJ\\*/>2:4$F7$$OV+"617Z&[U?2):REKKUJ7H;T@&=OX -MB^1*J,*KF8XN],`'#-``KJS[UBA6A57I%7T)A01O@>^2C!YY>XGUBH(=35E. -M*3SI$C3'A6HMYB?J\]L_N/M.W_')4RKQP<(X\(PJ097>&V(3E=\TW),$UXO> -ML'/=/@HACI+:"MKH<;@+N&*96D<_[UC@8./#^`-+;]'59R=%)1E:M17*\FN8 -M6!5\8)#5V&I"#WU1,"ZKP0J5&R678G;VV%AA:T+MY:)10=\NW(W5$#:E;2/S -M?\E<-ALJZ4D5.WP#.T(\A(?N@9VD9@2\VYRKHI@ -M2IQ7`,S+&\*.6AWKCTR\'-W"I5R&RF()X84=IM$=MZ&&^XYUEV._W6K2.ASL -MQ)Y%^$4J?@GMI1I"M+>.=FF_D)XS82/Q69?CNKAF&7YA04-'LS[:_5HX[<#, -MEE'0Z(01_;HO214.\N,.'')Z]3%T.4]+5&YVU5\V#<:36[PAKLW]!W`8"*NA -MF,]UBX'V7)0_?&-M2QJP#X)/J#=*9V!!SB<$S1!=XKMQ4,$GZF4N4VX(0ZZV -M+`"<6M[D(O_EB(@A4S32NT,D.@YV,6UZQ,%^@5#V%L4\9?)D*!NV<%E^$LD7 -M3%#N,3M!FM]/;R/BWJBK+TXEG$9[!8L,8KHP=-\\BQX:B@>P.$I?.0N2`70. -M2M*0L:RP!%J#O:S"H91UZL7%3W&3;(03;/6QU$=Q/S*4M58BRT>'"P@N/$!) -MJ;AL3VDT_JPAJEJ.G2O+W(9#4,(:F%FKQSCD[(Z?[)YVAL&*POOL]DZ[,F90,IEIU-=&&@1W;/Z35C -M5T+!WAXC35^C6,>:-U3@I@LET22IICN0P_+/)H;H?F/3K!R&UR2)56FD(S'( -MW)_&@?)"1[;+I,0RBR"\P.8GHCE:N27(3F6IBQ98:_R@J?#O5+]DA>'8"HOH -M82^D+@+)J_KQ[A)@O<;\-F(D*?WF&`Q9X\7LA"B>I*AYJ(.@E/5,6[1.C5`8 -M/%:RCBOH-V`14I!*_$FD!-CG=32.XWL>C];_WXES&3PC"Y6=&\7]_L;/;Q;3 -M<&\A"/Q]]RH:/1-;UUF%>R#VJG;>"]CKR%DE&XN5F/RMO13=XGI2"]J72G5B -M&W-T^WHEF>#RYKJ/$+(?3TT>IA*@0-=<[LO->$JFQ\,CQ/E@Q=18=_@ATS07 -M=44SU755!+G306R1V>`^7OIN&I&!3Z(ML3GHEU&@GX(1KON^?]TJ(LY?X-A2 -MTQW4H@$R;'R'K>38#6EMW'[=JC%./[NMRYW#[D\A8@'%\APVB*?D]R*]@^+P -M<4;!53=1^UX%92%Q!G&YS6R#8:<@OM"@_?FZ2Q:9*$KES\[4()!FT!*O$HS+ -M/8@?B5]@>Q3E<TV''*:%R`MHB"[N8E1ZRIF#F_!(FK*K -M;.JLN9G4OH+85&"9K&P5*<3>%D29B$)YGRS(Z7HW$':1*GU1]JT]B6D'M!3= -M@\2&SZ*W)340A&<:$D8F,:C5;&*!8=PS9A>*TE-+B?Q>-YMLIS&U@'S*;S8# -MV2CDN%M_H^MS.CA\:$`!2$U)A,2#I-4KJ>8$AIGQLAV"9A,^Y^SPXTKOY\V6 -MOUZ/&&OPO.$_`\-LTX]6:TIFYH0UID\\4#UOL+_YN_OKXRX3L9Z:PFC,;FV_ -M+W<<=+-Q&K;$^7&&(Y'-TE7[O(EW]"#@PO"J2C.CZ!S4VK9@6M=2X"D_L&L$FTS -M\&_.)RKA7N3OCPK_M/?A@0[DSM886N694&-KU_\T#.:$P&>_=SHZ-9L^(P/7 -M`W'+'J#=".J?J3_[,9<^9].K-:S=6Y=6:?#ZJ?LS31K5,RI`/G;.%O8:%4W8 -M6:0?V)(:"DYM#Q=OIH)BFG7:@/C9S4%TVB;TSF6AI9=2^7:67M?0L%>A^!7! -MN]F]9%XHFG7E,Q&@=3U>E\2O:P%C%L'`Z-A8]A/0!"JVQ8T%DO6L64FB]-=O -M:6Y\K!9QB%/(4U21`Q,(-0"D"RR[^S7I`EL0[EV6&U:7>;Z-`!&@#--DU>A] -M=$LR(!\.;9%[850>[M3F4X2-JMDJD,ORVD4>QO0DWQC]3]F6#8B<`"8VCBA4//'`>[Q;P*&&0W"M -MC8118'_ZB,XQ`#B(*`53Q:#W;%(;NDHV>S,&X&?,E8,@U'M%_,8X.@28X]]E -MIZ/:).>VR4AF:%.W!JK&7/<&U/!^!;NGKQCKSX,_^J*4]JE:.NY(5G[SQ-\O@20WS3+K?7:VN?N#@KQ -M9#:%J\S*F!;2.$#U^U2=>7;TC0U)A[FJ)2J\40W%!433[O_G`PT/,\E\_>?D -ML5ZRV]%*8.J;Q2RN>BZMC9Q_G+N"'L+A8PNS=L92'-;TZ6NF75EFL<^_>/J_ -M#3U(#%("[U!4%VY*,SDH7M5RY"@%2B1LG_!2(Z3/WGY2,2?47CG;SP\!SSB3 -M9"J"<]1[LPV@O>2&A&_5E\V*.$U^.H8]1('EOK5'+4/I[F:R::_$CP&'XW?A -M42M/R)M9_M7\/-E]&'#^K4LL:`2`AJ\4FJMUEH!/7:&R4E!7*E.7:RO -MG790HQX/GK%M2)W3'VSY0R-.D5RD>1J0XM0Q=_: -M%[11%?1M$F[G->+X=T8Y%3@SXPP@D8]Q)NW^*V+C?L=LDF<2@45T,-@U2`$_ -M6T_SJD'5XJ`&X-X_]LX:LN\>/N%3N/F!L-&!891.*;5="II5BP<83@=FZ=,( -M0T/%VI><_M^>:?FVTTJ4/YL5,B9!_,0Y^47+I\42ZU8=-;F$2FS;3I!KSY=&R_>D]X("&H(]OFH/-6RAL -MUKJCA7\!49A_=J0^XC0K6ZAUD=WY3N8E_W_9CSF26A-#]1E+B396PT,'5S?Q -M%M#),>4]F+2;G+:,K$\KC>S_IO'*+""RZG8GF<6YO0$D[-I,@:A+;K]>J(": -M+*ROURHN$?:`OV\CBNX/I&`-!`,(7&CYA\08X)3^X75%G'8_BE3G!V9D_Y*1 -M\_^[V,AD07\0+^`OVCQ9L&>&62/-/E6F>9@-"2P-I(U4Z#M*.5[Q&SH$M#+$ -M->63U!IX:U>9<,+#I_R1"D)+-L/SI%))6_*;C#I!=D]ORZKWDLT`PRG+RF7J -ML[T@Y:'%!2NPDS:$=+D3IQ,H28@24SK^PO.]K=-P+AX!)MTJM?!L1@6I]LV? -MX6R)4:G@#?ITFI3<+AH`2JBQU^]C_9WBT3Q(58@_>5[5>[M64IS6Q]:MMA`* -M,+W!*RWM6`#-S:Y3JZ3]:5%<;H'Y'M.X?6-`_U#$E%$2F0[L9]$)%_<.4W8> -ME"V5:XV??//&8&-M=*47K,Y`G?50=X4*+^N^B5Z5`LO5KM!B?V/@"ZV:X+/!39>&AWM,%J8BY-NO'3,`_J>,B4HT%QM\5LF\ -M#>O"6VV+F6_3T18G25[9D77\$`AV$;!:_D'T0R@P91VEVFU@XCM#NP8P+I7. -MOK('FCI(IE.`FP(:[V!JGYSQ\/TY6=],-!K/?Z&\A((4@(B@FNGIF_;'W`'G -M5T#FLP)&T6)\U#+NNX;^\$'$3A\@N#NV#)MU2!L9DE]J::LUL*(&`%E"3\3G -MJ`J9*$EUIG'HXP/,PW=!*C\OK'5-TB9Y)V7"36O_NX'0:WT2U:2;+V;'XL[1 -MTOX(ODW;MVD@CT/]2LV$Y[:'0U0N[T$@4T-GID>_*H-*@`;-H1U)3@-H/6]; -MLLN)V0V\.71QP+,4A[]AN$WTN!^9SQ!G/O$V/CP8D*$-CN=LK7XM#>7A_P'L -MD8'NN(Y&\XIJ`H`2R3_UE:V*C_TF/*XRB%`DVYX#?(!Q!:;!.J4=&U"==^?J5N);1O1J$OG*T@'D+X(K>/&4T!>0L*_B$ -M1[W#,+*>XK>$'$^$F1#5-_=+R5IFI6YA5T1.:'&'A:N8&(-1!$:MY%6910?O -MO-BIAO_"[/--(WLL2Q;`DIUZ-JPP*CEX8WHKE>D=!JMRX9*OR1[9+\ZL!`.J -M\+76$/Q\"^E]C$?DUDR99-6T4C,M?=?8N!BGTWK<_+(52),<\.'??+B'_KU._']](@NI*ZPHE7^YMRXRSTA+::L-P>MK -ME2:84F_F:Q$$JWT29_DM?\';9R(T6U[G,4%VG2D%JG2+'KKA>+;1JRO`V++B -MQ:A__A*3BX'4T??_Y-1B1/P6[.$,H&/-X*HM7[<'1^WH]229U#X2YT5Q'Q20 -M"TO`&]O6^IF]Q?7&T!Y8XDG%#@<]4]/3@#),8(%!G4O=!_,WH-T13V2D#+R% -MZ7.#GS/B(FP9_R1G+XI_9T&[G#^5[W`8&$W/QODP/^S%I(W>)G5`UY[T$T4E -MV$5LPV7%5_^Q38IUJ``*+\0^O/T5"(:Q -M<2-84@L6S:YBKK1JI_0;KC[!W]DF]/:5Z*`Y\A)GC*7),B,;&G@S0JKWGN]` -MCS6YZLF$@QT8$2[%3/];7KFHKW6@#6X-6>M,[=KG`][0/:T\./I2+'&'(,-& -MKA]_C**Y`L7=+XN%U+91"-0JE>8';?!//I?U*SKOI\Y);L7Q7[ZA+.="3TA1 -M[.R97V>)]<\V[L@D.3!4GQN7PI;(B(G]6_D&*XRLMHD?&JOJL-OYX3*BAP5F]:"XA:2^K``@ -MO8V,73N2Z_<=$IMX\-ADL`Z/;QLX]QGHGG8T/R$9G.DVJ)9@BK:R3IJ,4HF4 -M6"FWR$"H0ZGNOD":6A9A9GE6!#MLX($6Y,Z=\^Q@0A-E7;;^H#]Y -MOU:C;/YWZLM_N_%I,^MS44@AL8%Y)[G4' -M38D_V[9^0N"`3$86_@9YN-)\@WP]JJE^9R9K:HNN$N&WN@%B!V2+"F_EV^+% -M1F44X.#S))<.KQQ./>F+"X\(8#E^_9@5]+KD^!C*=B'Z57]]Q0PIVK -MH='.QAPS(8BL'\?M86'BZ#WM,_S!K1'\7?=+YJ]=*W6H)OP;A&2HP&S(XK(I -MRU`-^CQ"[WPXY?3JFA(,GM`QZ+WU$$G#>I,8H3VR#H;_BZ8Y!HQF]NVKUF)7 -M52VQ_\9[5D@W**-A^D!Z<2^P%G/LD`/*>??!A!T$CCXU%MOEW2D_W8'O,F/1 -M>Y*(6$TA`CQ5\M(YOQ+1WJ/J-MK)91WDS3C55ZT?5T;=W)(KZA2J2/MH/)`9 -M[YR>-?Q2=[C&1MXE$12-(A)K55]%*\NG0692@VYZ9$,%09#N.F=[OP-;BN"S -M6DH/#H49@O5B6._EU9B\:6&77/JM$C]>\=@!+E=R/_S](Y?`5A>JF\$_("0T -M>%2F]&V[H@31N>?>6AGV^>]%__`D"!9IVA,8BP81MXC`4#0T;2^14@ -M9R"D=K\$NT9`O/D"_QTXLK,G"TM+%K6HI![>?!>/@;?N#X#4U9G*/<#XN5QX -M-/4%>>M!L^#*?E2V'Z:3@;7#IDB0G[7\#Q[\5,](=H;+R:N<2=JMU>X_ -M#X`H(V"D5_W,WY\J6EEA0\K$S7ZXYC'J=B:BG.P0.5/4PXY.\6.'$BG2_62^ -MRIMF2V.M8$MON5L]HL^989-N>_QXLG?MQ*`/)7;Z?!(A,C?:,:$*Y5DY8M[S -M$,081A$U)6C5=[B/3CSNU/H_\6-$;7_$[=(7%4@+]-X6G(D[ -MG@TL=84L*.!74%`PEX011$#:3'T+FJ8;*.LUF!TC`2#=0*KZRNE1M*;BE_BI -M@6)GA22POY53FAB0L.RVX+<&8L_57&(QOXS+2* -M11Z?NFJOZNM*)'S$-F/-2`G)RMXJMH`9#/Q6J1[%>;137-6SOUBQ[>GG^ZLC?$6F[%<(YM>T%/_ -M6?[L6/7Z(;@HM9U. -M5%Z20,3"*H.QD9.E&SC=E---I?)CR^7(`-A^`TUNHF2-!<8OQFMKN$>NFM!5 -MTN`_3B#>QR?X)P6?!OQ<1YB7,^_D9,?@0E;S)LGZR@>A1,.XD31/>0W&5\`^ -M(8^SE*.,2&L<(*H!8E+<*(W[04')EG"0TW0C!5@6306G@BU=2.*5740J[@%) -M@^;'8IQ0/#H"4X@7_.^+N!]1-/5F,IZ.$!G<[`>S.3!L6YF3AQ" -M#)JED]HQ&R\KW;,#":HVQN(1FME8>5M"M+IB(+TB1AU(6+34-2*#H7QN>:2!88 -M/0AA47)OJ8L_6?&CZ9\F@_TF`69%1Z_U9=(B7_+6M+F@#C#E-ER`AF!^3QMTJF -M*CI6XAO:#IMU\['#-J=KL8\8R9K[6$G&(Z=4#VTW=BSF38W:ICU!%-6[Z:W3 -M_V'&_?ZJS3EWL]%ZB2BOWOP63M"J(F;O4M1\ZZ29-A78%I*ZT)=FPA3C'?<8 -M8EO0?S3T>2PD&KWE0G2%U14G:.V^7_F6]ZK)3ZP"P<7C//%Z57PKQ%H:CS#3:\:%F[ -M)"%NU&F=Z\KNS]E9JOZD'-ZVV?M5^-U^SF/G'&-0NU-.+IU3BJL39-2D>D!- -MO_%[Z+>M,D_"]G/CD)S769W?7\AHA(((L?HUOZR#T9&[5771^8\$2_[N,N)W -MIB<48CRK[8#5_`_AB*&D8L>BK?G#:0$*[HN@M`+W_?=9=U@TT;SPUX&LATJ) -MU+IPWN9V)CVPNYOGI89U?%IQLE31[C@?:CC88D?3:#HLHR<$F=Y/3')XV\X1 -MA9/RR/[\`^%3H,:;12L(EF*>A2;YH2N*\O.NHKZXW/P+5^P=3=M'TMCQ=*V! -MG98JU31SB=FO]&5%NEHFDPQI;6A&Y;O\%57U0=!L*T])JM?F+^[Q0(&%6V'= -MLX5"3B^6)E$4130S(M^CK@WNMGP+X-`N/I\^.TRSL2DO!WJ`TWJ^'M4_+$'< -M2391A01U\^1D[_C59MUUXA;%6EL<44UBS@(`KRD406T@'OR:ATC2M#8IIDZC -MI&:)G8&OY1RY5=>V&L2`DJTKBA:0#S4F5.W1`.Y7Q'!`O57CP24:8;V6Y**P -M?'./68O\ZWU#_?(E$/2(_/P_86*R2JTDT=A^7H]H((CL'6;U%$HI?.Z@UE[T -M'^;K>T(?$TL.-5O^MCQ^>N#O;&!&N#40S$@"OE8TWL2F$"0($K;7Q!.BJ#3O -M&H[!>B`-2\:8]&NF0Z2SF;\NEA;`2KXKPM^&OQ7\X;F@,X?9.CE4<-9F$ -M,O4(Y5]:>-^JDUL+JS'7"E7V]X]7$85E'8X6"JW\*MZ6;K"A2?H[`O3%'&K3 -MY$=R2K%BX2E-QKIR9+A\Y6F`::17I>.O3NB(,CO3?9KC -M5WU;:B6YB@HY4Y>B.E71G@E41516P<(H+[!ML#GUB'&$%3'8!O3@KDK=GCM^I2K.L.'(U61`WTU -M65E,4[,`=29T`UPFL\A0[O)9>S&6F(:RN*CIY9"]VS*J-#*X_7_M&#"JK2._ -M%UFFN-%E-F_'L9&ICO%QV6P=R79R]Q+<'_9_N)S&$J5S_0JI\"3(GA+>FN;1 -MSA*JD7H&6/(,'=^4-X/!+9-AE6M;-"86Q2[5"%1)]JH%1$_#JB%O6@#7EN.E -MV#C:D)[[/49`J39)/U!1]N@*:.(T7=_5^T6L& -MN%A2%:7;;?.5_[FP6L:;O.1/Y56%"2*;/!I/!=/-UAFU%1%A3$-B/9F'&>&; -M?8_0/EW1_;/%)23+0$Z]&MA7K.E0#>;^T3W),FVG0YR'".\U4*B*V\0? -MX1T<9]7M[\89V*;BI?^?\ZL5Y%!:;R95'SMY]J`[Z?M/U2H%`^=GG^/.'>V> -MMX*C9(`K4?N!RN'=C@*L)HK.9#4A>M;%8*4[,[8!M5&T>9(KD**C=TC;8_]>_-GY$UADN(3)*!&G[CE1N)$ -M0H`EH>);3(?23PNH#VBB[8,'45TCS>.V"? -M0C)*46I[-GO$D_XX7\!T'C_WYNEL>?K%AY1):!2Z010F>:!.:-C6XB.(S@"; -M9)$C)&JYR1?-EY7)X1SW6/VF@1'3B,`Y^NDPW"75 -M;*92-WSOX:MR(Y05*F_/X?=$&L*2,;2`1WKV"TO$M\G?0QS,KNQR]J!3.84V -M*]S<`M/TUM.&1%9J!9>'GE1K#W'T-6VIW=<8^6F:[5V8&=?'!CE -MW!*Y2Z(JJQ\461=\.KI^F((]S':;E<@*'OT[JQ2P);<.*@E1S0;B))!1VP&8 -M(BXM">$`LZB5_D-F63=5K.4-PM0Q=BZI%Q_K$=1B?X5@6"2O_C2!)^WH*J7M -MNY"VCK^B=)U8$MV/3?%%X]>`8,V[YPT1=(W!_]I[0R-`C(.\N/R*.IHC/?%[B]%7?.K;,H%NCKFP[LX4"'1+QMHWP1^G&(^;Z(_\/5:(FR6BHDL -M7U2=HY(4VB4A)D(F]@][Z0Q9_VON3@,5^L#1K3;3P2V=!`58TP+ONU*7$8=* -M*2O54!X$Y$H"@`;USL4H[1.*7GYY*9$S\A^J`/"AF<79=_0QW1M3E_Y90`CT -M,&?4V3@Q`6=Y5?K[N[(0$R:5B4XQ*H -M;C&6$VB3+_X;P4B/RRF^#V9I:Z];`AL\N-3`52E:G!L?D.?C.\O^/XJG/U!\ -M/&`-\:[+?JO[$$C\B`D0"W=(V>\(8!]9"UOCVMUF^2CLZDQ;^N!+#,(CMWUI -MCV7GZ`)*36!D:&EXT/]P(-'NA,P;;2T.[!@<3Q)S<9F8D;CI.U>M]]FD9P90 -M:V04X&BW^"99[-J2"+X(1K-E4B/?LZR;UPSP`Q!V`8&5'-UB -M@OO90IA(MGQ*6VP53@XZZ0SH`O$E;GR$Z*'X[^\WP5CV1X9H0GPE5BOYS;QWE[Z9;LV9)K8'"<&U&*($9T\96_^"O@GT]*.Z^O-L$` -MK]A;8M)@4$U`:^)!&TNO#X"5(<#"C4[OP+P<;]SO6U_/PMB9>\O7;/60-DT( -M+YZ736-67BI3N`S\P[L(F(K+9U@4EJV_KK2"/^W(KKBFJFW`]IQANG+'Q-[5 -M6%&6WN(I3QS!_G6OL!BK!51WS9+D6?ZJ*@V7M\W0MB\!?+3G(&?'OG?>Q2_= -MIOG'.(`-=V!#RB?&_#1WC'ZXY&^2?6(&6J'6N;E)Q%41SX]\L2P/04!W3>6[ -MDV:%ZY,0V,G@DZJKO@A8OU9#>09I29XCXEHNT+&W]-O[ND]0NDBNA3/1IH_Y -M&DYN8*^57=\'+X"K%/;`YHV],X`07!:;#X"D$\9=4$J@_834)M24?P"6`ZS6 -M?*%5?J:2#M]7(`A@CV;!1Q>N'L&6EH+;XVFMD<*?A/A?M)U?JF`A.P)/J!9] -M9L8HM"KTX`F"3@S:'[W\%VY__(!(R^%155#/WI#__V-G<4)*C7@84T.M!*2; -M$GA%BW.WVZASR8/34I/X1*;LG$_4T]J0<4)E+0MZ(C<0OF\C9@7%58$GV53S -M\17.U&#$MX$?K*7C-_N<$E5D^U#,E[>NH5_%TPR`DC:=)58VH#5+B;Z1\=IJ -M022H*Q-<.RV$MH0P%":.H%**L*C9L+HUO!;EX`0[P7/H)X`5$;G"A]"C?GTX -M8U(*'Q@2<*5_I:@!W&T.9NV(U4KI0U3B3"<;EIF80C_+,;.`RK_[#%7`$H"J -M,*F=3VEDMQ>I^8:&,F=NNEC!%N6;J&GI&"ZXA4\MRV*I6#0\C3&$CWY*_`R. -M.#R,P!OH3V@+-HZ="D_=D&)D';SO`7_0Q1EEI+%T%P-E<-.89X8L8'&R]#PP -M`[7-(PZHX,U5S&H6'UKCGY?;.H'\QE\/>:\^.P?^SS<=""K7ZJ&&U`>8R#YC -M(/3HKW*:]4&_ULYZK^?7>P!JI1YA\!^QPV9P+CCFNX0!.B6U)1BM:35=V:OQ -MD)GL:QY?7OLH_XYIOL$_/3F>GY'XDHQCIC"5!<(I(#I2$H:T"/5G>("5\6]Z -M`@:BE/6M50S@\(:C:IYPH;@<.YHTRYAAC$4>-)3SYE<5NQ[EY\(6?])87:.[ -M8VQQU0,M)F@KH2>E-T4%,]=_.R[DN)83D)@(V"M(X&(VS_YPBQ_>)#=>;RA286*SIC+!AZLI -M76NE,]V2(*WITOS@4;26U//7FBKJ\C;`H*CLSQ4YR13`P3'9?WM -MV!M-98DOF&1R\!)C\+PL)BW+A16Q<^^LT=*G[5T#QA^V[FF/,3F867O;_(Z- -MEF]LES[AX!..O&=QZ"KZ@/;T?M658G7CF9!:6F[H#[,_62DCD=?I4B;LTJP0 -M+65ZAZPI6XFR8-MIAKS`->)E@9]\JEIV+/)T'I;OY6+#BT!ZKP>0(U)2E\+1;P6AZ`"0^3[AZTAAJ^DS1M`\(O:M'%AT>!;=)=*8!,J+!%K8$`V->*G`!0U>45!],I2KW4`]`7'QH6.#H)GI9O -MQ*+%/F/,0_=<=A>Y%E'H*;I--L&0A5&5=%2>6A)!XY$(]&G5*JU\ACX0MN:L -M,#)2>1B33+^UPT5J0K5,`/Z+TDRE-8[:0!_W@-T_+G_+)"GVWLQD63T1SP/H -M>9-9^67A(>$*JQ^.<5N,PFNSZSG0HU_@0,;$*0@E$X!>7DVY&U!H<>PQ5-M=#PLRYT"P/CW3BUF=KG+JF -M@^[<&"<,DT?P[7-H'[-#TSRH./=O_*NG1W`WC$P%(ZPE[M\/R([_D9>6+R[+ -M%'3%.6%2]XY=YP*T6EWOB)XQ*+(0.:RH3W=<<*&OTUF"2E2+#_>I(+Z25*(E -M;3P(#9^(2G_4S0BP,%%A4D87/U$FTJ*5/G%9']+3TI)5*A7#$@R#5!]M4R4IDTP -M-.V&M0MKV%N>F,5SA.-".E;K\C^IFB@9/ZANJCCO2%/[_5+01]7HU* -M@20HTW2)$MUU&(D@W'@3FPF;3GR[1H3X)%6^,D!G>TGF$8MB#"$>Z4D*7HFK -MEA/A*T._N0**Z=^I==X41B^XRABV=PV;+\XHF]IZF1;SXI(#[L3@G]"YH^Q" -M=7>MV707,&@HE)WQMBV=OZ%?4!EQ+_YM;W/3>EBMM?J6*A&5H*4M$]Q"P[@Y -M"K%:5HBU-.=V<;9-CQ:@KFI5&Z^6Y(9)G^5#X[5'O -MRFZSYV[Q#2I^U@.#-&>6[4%Q7"O[1Z*FM(1!8PFE,JT1NJ@;);M"F/-_CUW; -M*/0WMZL9).,6DX.<@MM$:RDYDS5_:K]"AJ51/#@XON3=`<[5,'?\JVL#!ZK( -MF`+F\0V\'"R23GX/J6U$C*N+Q=KRL`3U.,.[N,_1C<*)C;7O"2>MV9.=VPJN -M@3G*"3S'H:BK.7/A]/3IN[-#4>,>-^S$Y8EU>Z\J-]YW3Q=-2'/W&RXSSG -M359E:WU6D&>Q92B2T!4MIJ[B-HELHMUUXA+-< -M4MR9'R\S,?@CLB1O[;>$'NJ(`XT%#NAY2%6_(EWTI0#'SG/KW=VEGY6F#WU7 -MT^.+XI5=;-6TD60N_!XU`T`#F/#T46(>E9D0!:J*"ZIMJX2J0'<[9`%U`12K -M\4P<^9N!+A(B6)L5^VLHX2DXQL72@FA2WD&Y$`]#Q=JTW9PL*/MLN]H39D#U -M_QG]'70I#]S%FE)>]+C]L-*W)MLR^LP+"#9?MA1G5^.!Q->>X1E6(5YH@`^C -M^`%#&AQ1B'?IK58DR=R.L6&N0=V;RG'>)]"/RR6`UQ#/9]])7SN(7HY!BWW4S70.3)VX>8E-:#L=.6U.E[QG137B'< -MW9TVVG&5->XHMWYIFB)XREPGN4R1RG1;Y/ASR#AN2T&V/W8!H_^.;>LGQ/+1 -M?$WSJ87D()&9F)X2(C8OUU[&L4Z_>`1A%=)SR,D;ZVP\5R-ZI(;8C6/\U+6I -M,EXEU2\UFTYHZX>,O,_.36H#T/7]4B^]Y"[#Y':`VDHUYUE,<2@\\6Q@E\!R -M[*QR*D2%/HN;<SY"-GGSFUYM$=#"<+Q7EM)-4I -MO*1S2KS#B7Y8-P9X/;/0X\>IACFIC!,R%6^9QZ'"FV8VX/T0)@QU0I=]65ZN -MT\YUJV8(1;B%X)9NBKR0#!F?<7[?7&;7$]&*.R^G=[WF[GU6G-POZ-3'%AGC -MGV:[_HHF6`AS#ZO8/F'=O5H+"0TFPO@`HWYU]R:-/^H1,R$=FR`.Y=_Q(GSE)S_II8&DJEYF%&";OK.]S6W9UEG&A]>2"PHA[= -M7KX#T)Z+/4'`2RWMR7PADB,]+L5S:HD1ZC+45!R/0-+@`*SZ2_Q:=G.1LP/U -M'4D@"V(C&=K&"NGZ*,W!42`L9J*)0H<6',9)$('O(9L?:=_B(@*7V:5O?$,6 -M3318H+EAPN#@%@%2D6.6D7_/82/9)HP2Y;@)K6 -MDM,`V7.N[@:6CZ583;NL[-'.??@%(,/U=*\@1*>@-:[G,\+AV?*_.MFNLN)( -MLMRL*3,_X5:T@YHN=F4U0@PI__P0KMI?%/%,N'Z9^+[AELI],#X>IX*2&`Z! -M^IT?N!RBQP3*AX2H@T9Q>DF?G5<$1X_/?WO7%E+U#?E(L9Z6'OR\1<+P($-!P:VHQN#0&DRL -M'W>?\!*F?,838"G?\J4$EMA6`^G8D[TX[I%)#):>.3,#[_,+\M*\;?NQD89* -MEA%!>>A'4@^&H*;D3=*0:=ZP;7*#DSBGH_$BY!6L^7&CH1VZ=P6ZR2$8#9%Q -MNE,9W7AD&A39MAF+^&9MY:]TWI_%"^%Z_UB@),U^U/BHE(!G*;>-)+A2Q(S) -MX]RI/=.)'*A2$QHT5B2=\4U3#V?2`]YBP(V/JN$&LPLQ/`T'%D_3 -ME<64)\8"!928J5-S7@2M`9J3*Y0$+1"5$<`^_I?R#7+?93;8V%D2N]30*H\& -MA+ALF*N(6=3+G[CZ](Y9D8W6S8*22AW=G$S'TSQ"U+CT'0`L4L&Y7M0^I3N0 -MA^20VJ]"QD1 -M1>3X,HRU5],Q[Y07J,^6*)M$$\0*Y\"A?E -M9058Y`V5)TAP^^OGJO-MSD)707?B5H -MJ*410FR+#7*IT=A*&&2X,\GJW9&4^-N1F"Y+G-$R,>7.;8]E7>B:0H!$@@[+ -MM:PROLP,8`4X&2@)K#R'S.5&EVH<;#@X2&`?6D0RH_$47`S/,?I?\ZW5/1;` -M3G!)#CS._GD&K<2%B5E9(ABM$7T)$'7I"0U;J1\(%4S.''HL,'\XA+Q0$-[5 -M<.!^5KHLECH..\>H!@457`-.>@C"\-1`M;2KOG.,3%_C4PS09X03!9)T6L^R -MR/A$BE5*],FVS;TFP,ENN=W;#&SBW5&A%IS,'BO1`=J='?[HCD3U;RIE@ETZ -M';@=I\FW7Z#&0B2C=.(S#G\$3=_"S'4!=X7W`Q(<8Q$(INUR -M>^=4?2S)&)@T&F*7I^$5W9*!=VK@HEEVO*5*0=^HW?Z -M5TN#(.JWJ[#D<;5XNN?/+M#2R-KO0YE/.YS?SE&G9@#%"S"SZ5'?0ZHH89_& -M?=O/,D^/D"/G@`'4KHWD_(/XP[A$B;]ACF\`9/[XH&1Z"=U5G9ZLXYQ6&!@8 -M=9+E)A3\]6IH4+?%`A!?>%VR_D6SD5_*_H(>8=HC[*V&>.)0B%6J=QB[';IO -M$"04.E']6[#Z&[=#EX9M>)-1,P!\-_2D(8CEEN$`/67^_.TM@M8"SSR-92'&*KZ_<(83`6>'7X7H^/)`LLID-']A$UYS1IQ-_RNW-@_J`.W+ -M(G+Q%:7U^/5]&:-VW4BK2TZ/U(`)JR73Y_TXA^#)8ZH2IT"(`(N77!ZS1^Z0 -M;]Y*I,7S.-WIKJO&L"W]&I$EV#4&R([Z9,OS3K!K?``'R>?(C)U/D""XW]E5 -MSU^=(=L(I)JR6*'O+JF]G?(EAPL5@F\0U,/U<`X8J;(D>R[(M-&U7'>B>P^I -M#3Z_KG!+77LWC#A9&J#"!5[&-=Z?S%UM!&$H"FJ:OFZ9^SL./3);)/0)KI"0 -M;L<];:QACH -MPR!'6N#_,>M_?-]EU9=FUR<&*Y,B+CL6YGAF)MW/J;,4:'\]N/^6CR-!U^,Z -MD^T@'PJDY9.3H(3"@*M[XZ[ESYJY6ES;"A`HC$EG(JPOQ?NS\Q$KP.D7^"V2 -M58)-E)D2<#B`IY=6X>DK@__^(FTC\/U":&T$RXUV=4N=8%U50)?)`!%NM95, -M_8U%D)-4@_8T'_%9$JX>%5A+`$@>*H<+A4*R:7LQ%\7];<@>W1[76:7[`(*5 -MS3$B#"H?HQ`L.9NPPX%<39'2E[HXZ^AWQ=F_I@_ZZ@'$@Y%L%R>94K%$]]PZ -MZ,)%@C9+(G9EHOREYI/6`1POYU<4<+F&FT3FH"YRSUDI*?1_L6L+XT\[5<6S -M,XN3JO^`V@0'D07'\B5$RDDQL1\=4,RNK7[N^6'(1+EM/'4#[MU)&-%(][6G -M&0PINIZ5U5E8OQW'V%!(RIHN1"G>).4^H1J+SI&\`ZI^YIYES6Z@6R2XK?T] -MX,)E]`N:BZ,/*748G#&/'OQTLR\MY.'[OF"';NKU17F?9"%^B_-5..:_NN4& -M]=ZSBV&[AGALJXSC?N"F&'!D,J_]WHI#^HH@2&KV18U%ZA1.-*P,LZ]4UX`T -M0#]Z`H8K.`1+D,$1*7'=7(!P*H5Y]\I^)&\FF.HF7*CF3G+'S^+OP]H,F/O4 -M,\#@7&6]58ITIJK@V_!(4;;`N^&'&DI/T&CK1HP5H;?3E/\(E,H8W+L]Z([9 -MKJHS^=,+3Z!Z$*0<[TK;=2)2TEU4"J-F'-';#LLCZE4D*Q:3D<7)OUF2R4C; -M"7?K.L/3&_%B1("$E499VA.ER'%*\#D^RR1F+*EU"$");1Z>^!1J?5_%@K*^ -M3`8.FVYB14/3*J5#12])XN`,->L1[N:4'>9\;'0(,I`G,$BC=+$K.S#7IM -MA^M=K$!GDS1J[EXMW/OU36GG5I9*14/N3[+8@5/J)OK8@72EH;>),"IU@]5%5J3,[I6X6P\4Z#/*D;3=]T#V5E<.2]]HFF;'S%'N5FIA4>PR8":GDXU9I=-0F86%_+D]9X -M=9,5-J$L/]HN.#I5%^&2%^B7Z8L@)/X\X$@5A>R<<4[>GOP9/-`*$@4Q3CY\ -MNDJLIO/S&E#WCS)"!]#5+5)PQ,_+'%^4UKJ0J9_)^X9BU=(IY9-*F-Z5Q=9E -M!5P10U;KF2FQ5_D4J1/%>OH5Q6DAS#E<'C;%5+7WL0X$<"3<,_%"L76>1#*( -M@7MKI0>I(*M)RJ'`!97[.7/"!H9_#5I*I-&*@D".N%K-0`W0>WVM'N^VK2&S -MT8P^A(IZF!,&Y\@O(F&K\L.)M"--K7F]\(/0Q8_Z%DQ,Z]>>J^[`ZDYW7RW_ -MULHP!+2['$8(!*S\G*7KMDJ\3R'%M8$:)M^1K`OP6X0U#+:8T&@0?2MK!/_4 -MPUWJE/#AH`U"X,=U-\?Z>,1B:R.\E2.^IW=T[MWB;+)\.H:?`XIH-GS\B$>N -MJS$#PHW/X5L^DDE7?C*@TA>&]-[Y9[3YRB9N9V*+)!(3`<]+HIU5#7LC>$-N -M*M]-Q5$5-PO3Y_'2%_DNS,J9C6I$1L(KZA,>5V9LAYWL+^)TJQ=<02*'/D)0 -M:^Y2OK+"T;LQ>E.A_+/[?K474K6Q>,'8UWT#-&^K,,*TQ"\ -MB9A.;][_Q7_-4B1#1Q*U$(:"59M8Y0\^S=G!-A1$6O'W3G)EO_T0[V7(;A#) -M)[UD2*8L49\6.8]-NB;QE$Y]4S5E!9BQH3[4#S+Z$O"7_KN-?4.[[EPO5!)Z[N+W70K=/CE4+6N&]-?AO`"M -M0KI_;W4D;/=A-(X"!&G6?#[WX1O[]7W/5OQ`?.L"BT -M1G("OH7P/Q8X$7IBV_K]Y$",YBSVG;8*1D1I$E0*8WM.L;$N*1T9#REHG3G^8GSNU'F\"BD1M9EL(^762, -M.CA2TV?:EFN#OQ.Y6.4JH3;62@3.65:9]F$W0YB?&H>X[G?CZ69LK=XM[5Z% -M+MM15<5AAD96T%M>K53$/Z9WCKEI2#+(0(UY=E+\4**KEF2H+@<=(0V1QR82?[PT\6'6A#%E4 -M;N`Z7RF']*T89?,CQJ!+G:J`];AQ6E.)>>X'W>,<+#3_VEH;S,G8[&9G(5!; -M\66U/>X*HN1S\P5R8W,`4;,JDX[I`I(W0>'@YPA],`BB?+M2?@FAL'F:LN'/ -M!Z1<@ZI?K=2U([?%E4T-92;HJ4<^&.>-^<)C:5T(R'55?Z%O$F<)$,B1/(&-1/"Q!'R0L -MX+W+6L],5?NJ'%X9SF68EP6H/$HP,Q?1Y7G,RGPCB\R-BSC63LBU:=Y]7;,XGSLOVZ] -MZB;A"&O>2O2\B\JQ9Z[WEH-DQRL1&@(KHU'FC[CZ."K)X'=;52#MCNFY6::9 -M-9X=R+"XADN7ZO_U(($P!^7W=!A-*@+ZC:I*H74$$5M&>[`LBS?H\49/$NFO -M+TW88"[%;;A`*@./BP5;4^8-LR9:2_/ME9E2P6*OS)F4'!H[D\/&G4&.8L=@ -M\"VCP-:Z*!/##SZ,9R,_`7&#!+E$5#QV=?O5A'![?V^H -M``C5OF8G_9'X%"!SI:,,/;7/+=W"K(*CO?ATYB;"F -M@I@-6#0-,(X85E:$%[=X'&LYT,2D3F/;9]A"'O-K42`VY74M\E/*@R&'L\^\ -M(8846$9_<,6EL;(**WB%=6)!-+^V#"Y6F<>Z<4`'P7\4(=NPE3:/&9<'-O1W"188*S8%;^YMMHM7!H -M7Q=&KUC?/6FVGPG#^[XJSN$-O=W/80];'-!`&IF$L3&D.XO8>%HA!#H/^Q)B -M2M.Q"1.MIB%),_([@+^"LNGO;@1`D1CF0.+ZCM]N!U8U-XV+>@=B9)-1U(_* -M6YC:$JQTG88X(_1S$64GS'G%&BU@S]U(1]CJ=_`5LN>Q*VS*+EPUKOP2$\TL -M5$;U'U\G"&UJU<'F875+/_Z"PICP5DOS#.POVOAR:#L5M@D6=I(-Y(9@_MM7 -MUU>D=$8030\24WN?XDV_R#KJ7_@1%#1BDJ/;,C/@ZZ$_BI^24QP$3(/629D7 -M1@9/*C?\]HXI;-=*:%'[MA"EX[I=`1DBA*NFN(D:L15[.6WRP(_&9IIC6IDB -M3X]8\*+\I1.#Y0"EZLD>KZN]\?/+?B6!%-9,="/;3(W%.OM>$@B:-6KOCM`S -M'.;"0`;X>S:>;@)0L#.[BDUD%@OR4OIB9;H'JD=T+G^'[9?-!'W(>I+5\X[P -M[W#U`BO_S0T@BX7G&5I1$&$%OTHDAW.Q+YPGT.M#WG*#[R5-O+=W,\8\MQ@! -M&R+!^\;_N>^HS,I>9[_KP12:\]G7A78JB=[S9:`<,O<7>?.UFE>P-O^BO*Y> -MF,>1-2[_,3!+_^P[SG(/'F1\6;4$?J*A"9:&O'<4["\]B,OR)P,T;MA8@OJ= -MP03>4X5[L;5+$]>I[@?F8TN:YFN']SGTIQ31/6[!E^IS[Z[/^AL,D7=X,ICD -MDBP)=37^?8<=X\?\QR+T4 -M8D`4:':X87#DL+!?*/_8*#UD3@J'&(@E2-^N]3GV]>^S^1J75UE/E$.1X=D' -M:/QBRJ.]PT0]Y";1\ICTV5#-+:%K*_%+Q+ABJ9WXV4GGN@,S[?U3P8Z/Q33M -MO<`NH5EIM`:*3:F-4GBDH*+=+'4-L\2Z^Z#5O99^7@_,?W%E(_XCI8+.JSS3:&<7:AO"Y -M3P(J?(!T>5<'0$P39!'[GXSJWQ9>J_#M@")&4'\2(;H@<;&M8R^A_5ESNH:^ -M!3Q$;J&[/?62)NS"H--=<5,Y,MV"E5\EOCK.;TP:9C1[0;[*]RPIG41YZ:N/ -M3W@"3LZ0:XB]#R;BPAMWW,HM;88^L_J/^/?L*I+[J0QQSZ'!T9+:%1F"WD"; -M%2N($-"]>S:,&2&,CG_$XIRO'OR'C7HIFNSI9>C2;O9>ZB#R\Y-,G -M"T%5J."K(:=>4PD3./=--;V]347'Q$M\2JS7\K2:*"$;%S-@#3UKAP;.XH9& -M77_P$`B-W,C*:TXWFO-8I/$%4:09.C)IP6S],)&7@%U\ -M]]&B)XKG#D&5WI<)1[Z3G]P6]:+WT'LPO<97_[WAO*6F=5? -M+%RE-;KI43],6\:PG70%6]ESG-/$)=A2KXJ5&,^U;WVNX?P%F3&H+TF4#I(#JYO -M#IU!1LU8[^TX2R(U?_%0LJ0'@/V&J^@RKQL__N:F@W[KL[C5V8M-_\5H%I.5 -M7BV@/__-Z9E^^FI>Q'\O#)(%>8.WPR$77"Q"Y;,QSZ;'G:Y.OCB.6A!?IG+& -M?H75%OY!P*(3?L>S`&'53"=RB&-"5L/V-\NG[J1FYOU8%A-W0C\M6W'V3ZF4 -M6Y6G!&6]<+5I^N]@_O&WXN&(KZ3(V7R!VVN8RXV#$V/.\P;C0#S3V[45VT./O?-_7NJ^9VX(%C*I6=#8G/2X]?.Z -M*0WHFA7MBL$F-WV0SBJMY&O8*3>"+;U20Z=AWT\+)!\2'Z;?'O$Q"<89\NIR -M25*];_]>VO]%XP+0:`2B\+%A9R[IF;+:A`H`]-#%`+(LD*&_S"(_9ZE5H9*& -MM0PEJE9O?]DEG2G0\1O/>WD1SE>HJUXVH$\3B88.?8(*-QN^4ZVOG2>!U?G% -MXA]67ID)K!>3,2GS^VG;!O -M;%>%S3GY7/I%4_I@#V5U!(LT+>K;.Z+AXJX2O>!#ST2VP?JJ.9G)*[U"Y@)" -M%POPD7QW14EQ?)=QTV;7])/SIA_BT)(``<_ZJ19IJYL6H!6//?]385/QD;*= -MTCT\"6ITO^1%Z[60QDF`H=#OZ=(2.41LILL;H$2NR;WBIQV^5@*B5/+:1WR0?5,B10OE59N>L4>ZPJ -M/'PO.J+05NNATJ/<%1[O=O/_:Z%/'"O<`)+(9X7[1.*^ER\7IN^)_<9@G4K[ -MZ'X&+;ILL''K%TSJ10V"%3YVW[":C#T-]\E`0N@@C4V+W![9C4">6B=UAHD) -M[2U"6?(<=J7C,'&F<3BR$%:2<(-,J>'B^X;3_:7P:3:+J7*@UX/Z84\*:96- -MK,OS"LF;&/GFDR?[\_*A]PLF@K9K*Q/Y92'WX@3!L)CH_TF=U]0&($:"D$\Y -M>S%_.GQD6Q)00AA&:[YU<=++-6M9DOV;$#&AK"&>H2!K%S"6;G!X#3_N8Q+* -M8%"HC5B#9U8+SZNX1U/%#.-JR0_%#[&XH6**B>#BR"C#=].[GPRB1BOOS"\? -M%P,HI]09Y*+<2/&C/'AU*7\P@9)T:PKQ;`&HSF`PC\,O=)SOEQMN6=SCU?B& -MGG[Z_J3Q'+F:WS"V3YD-&0`8RK,18DXZ7291-H$^^OR\2M14P0-&6ISVOQ'- -MI<;0DT=#E.RK#91!9O36?X%K;32F.4HQO3 -M^!R^?1`:W%&2P)^QYK%O5"XJD=@EDEHT,;WX>-9&I8EK'/2"&J"1V\OB1SX@ -MVYC`3H.96QX2K`$1W@0#;GXWJ#8&S010*#F_0[0J32SNOH'!!U:+E]A[W4VI -M[,[8;*=%E;9>!4U&2+BG!ZLWVYH'C.W88P0/^%A;S)@\6SY8 -MQJ\#\5"7?+(SXCT:X\(;R3,"P6BRY7YK\J?ZB;VL^8-G%0GN$]OKL-P$6QP- -M<8S#["(W?_X&^>_CAPO2]PH#W9 -MP$-3RZS?V<7-:&"G5--3_Z$QU\/J7-,B`&=9L.@V7>ZYQ2^3UA0MG?=+?F_L -MCBRU*YL:^ZVD@4M-2'MMK=7[SY!Q/H)GLORZHC7;*VRPM9,[2:3TFOJ.17>/ -M6[^T_=CUZF1>CS0?O#^)ALFD)OBX$(2;.#;NG?(\A"-%T"+EW\6EW,TGZNQC -M$@=F0L3^$#")YW%=R[WTZ&ZO`(V*D8S9=9;9@7S2O.Q#'!+KXLK,2`G!L7IN -MK[.(TI(VGCH$?S>AU[I*27^WG&^%U*_T<0^V$'ZM8O_Q.0K:[0_8A%V[Y/XP -M5.3U*/)L>8?&0=S=[I>`\E`3L*VJ-Q(C(-EM)6)[IE?B,U@857`%CDJD'!=2 -M+`KVF](NT<."3]*B86XW3/MFI,X+^_N2X05?JWM8*_GVK!9)V?-DJB\V#0FNN -M0425C+#+D@4&0H.9<"B=Y%:1]1]LE4^00^/?4,(DGM-'2P>8_^CPTKKIVX]3 -MVXI;J1;J8-^_.Q;#\@RH']32]P4\5-IJ0>*.@2#>G<-`%WW*(62SO#CR.&88"C -M`(*6G8U(>CQ\#FPN6+%);J*9#;UFMR=5^&5/RR[J!>>.=JDZ@SJ*\%9,J3O` -MC2)ADO?@5<+.V,G@J*TOOJ5UY..3THS+`,(Y!P/M!O.BUJOUTCP;X2*:_:IQ -M#^Z(/YJ0&C;#R(\V;MQ`B]#[,P=J,@2V-%>9):2VPMO%/XPI>_X_1;7X43,V35&F.$*106-P*1XKYVF[A>X:"PT51/O.3&)=X'\44]APA]GR_8(U(75M'04; -MR930)/'@IDBQ.SXW4`O5*L014*IH]9=F5=N9S."(57Y9AQD8-ZSABWK-8V,9 -MPAT\*`-S5+X.Y1OTWK7\.\$../0'?E(%[HK?.MWH]"32ZL:[X;!=@M']A8NI -MBK6TWQ<,BP:7MK`V0/@PTS&6O&+X1UZ>D9AB:6+]4\S*N1<+"4V/QUA"54"+ -M:#Y%_\#7FE^\2?\'((&;O"&<$6FU^[1WLU@+J'UO9B]C7]BP+/UR)2[U8#HK -M]`A7`_R#4VE`:F+RSN6"F167!VM^D3V6[Y+7Z]H$!,$H^&4\=#W;K8FC@L5$G[I;M^U)_V93!\.F$7,E&/WJ?3]OXYPM[JA-^ZV@B^YBQ? -M,I^"U'>"ZO49+6"X/F%BFEG[F)H&Y3-$#`TT`GFM>"RB,Q)![E?"_N$?ZVA# -M8]V&")?&>L.?2D60.47+9&;*T-:NE0HW!!X]S5H]"N)_#EY]9ZU)TF1G@Y#O -M^K1+6(N)=9G*D#PN8+P\`WU8/)BN#BAFD83!L,$\_ -M]+-[L3FOEB3^5VEOH=&\R0XATQ]]4\ZC#R?[8ON/)L,OYRR??+_?1$=W@,_L -M,"Z-:,C<@AZZI%A*:(F+P$OZ*Z7YL!WSV^=SK7--9M-^'+I3G3ES?)B`"KJ8 -M#+9L5%E>.VXCO-+*B??QZD!J3.A]_[D$HJ_&!NN/\BIB'TPK"^Y0F#4P4#J-]9\Q,[?M5W-%:-/A\ -M.U]==6H_V56C4HQ8)I')H``5UW<,@USEX)T,,\-H,D'&X7B#T6L$@I?Y.D`: -MQ#"/%M:C\_`1XD0F[&;!#+)7@1_:ZQ05Y%=#C^WVA@A)N@I/OF5B%G7.(N6Q -MJ3QOG>.;)>(ZL**/?_V];B[,[>CA9ON/!YUU]YN,#LSYB#(CZD$"TI9:A0L>2 -MT9+.5N(1*V\#17J,^&(ZIJ&_9U:LK[3$Q+"V[TF=>+3QR$K"?ZE'W0H -M,G0!T:@ESP,\.;9:9>R_H:[R;R>7WL]4_J-:^2"@ZOW>G>I -M7ZS'`#N!T^0GZ]@$&KNKU%*,*P;^#^7TS\#E`MU-B1A$97:_;-_,+I=N/8"` -MSR/@HD6M0/J.'FVY2?YAO,Q!K,Q+D&#:%,;7PL!_TU6)1 -M0+^D*.Q]C@DX!Z<,<#W;H>-_Z2+^'5[Y^>*U)5Y_I)6UL3^\!X@I:8;.Z -MN%3!=8MP>IKNBZH]$7K2_884 -M[RN,?,T8E3O98`!S6OLGJ@+,(NZ1BQ0PX^FN_V/:35SR*'O-='JM#P8I$)&? -M&.\.:_W+[-A)_9`9=.9.4NX!JJ6?%0^J4/.X[M#I$HE'`;^,CK&P0-XOG#]0 -ME/P:V__,7=63W``K#!D=I`5-@U2YON1#PUDR!H`,/TCW.-?QZ:E;QO3TD3P+ -MN%CQM:P>K(@6H97N3.G1-IM5Y:/.X(C(_6;47-[^JG_U-6!A_!W,\P0G>?T, -MK#OZI#&Q?R[Z=TGG/>;YVS")\X!P.ER+`,.>I@/#U)TRLA_W+>&R$4KRQJ0. -M8O3V'*N9%IDI502J2$//P`]>$A#6%K2B^>1I)W1L^_0)69PAYZ[C;Q71$ELL -M@X*'%]W7'+7>(SAK`S#RS:D8U'HRFU]%V027G]JBA\Y$XH&CC.N(5O6Q8\5* -MQ[K*2!<2;HSCD)HSD>.3UXU!57^8W;:#K*Z'/"E;[L&35RGC/9S$.?W3\^&# -M^765-8SL%'SG/`FP0`>,#4G=+61+L>-W4W@_QW8@C)%]K,)VJ#$]8=+4!):I -MXYLJG")6+FX*HS8AS#'?UQ8S@GY#;$*48T@Z:E$Y[DA6(YZ5Q&^F/354"AZ7 -M)PL*<[V#$7]'<`LH:T0DKZ9B<(12OVC)F#-UIV@[<8-6ID6\SQ>YO"F6,)P3 -MF/M&S16*C.4O>D@JI$'*7&[3K6=6YN6K'1QU(<4S,X(V1X['$@J^WP_ED",@ -M*&%T[U+\QU9VQ(/+QQM%>Y'`W0.THH*/6EHJX#+/>B"@48;Z?TX[Q6H['*?B -M:>KG@MYZ:5R+"5KJG?K3@';OF=3!F]8EF!ILV -MA*U5^VC4K^(]['ZM6JR'E;9>WT7!X_Q?[5VMMOA7ZK*;"_+#<&ZY*Z<6F()P -ME9L.BFSZ41FR7+&,F_S8Q`._,,1[^$5W3D/QHD^="3EM!-VJ?4M<10&G]!O7+,^O;G -M7G`%O&\OE8(A`A<6"7*0A^%*-MV[U4]YC`*XN17>>C$G#RX&UZIQ-1GJIPHF -MZL0<_V\-PC>P[(O#+&Z34WXEO4AT4G?F_WD#NXGSZHV=`4$&.8!!Y[9!69@?A\Y -M'0>)-*GV?N5?LD;)+&V5"%Q6.0(*7T43%`H;N7><6B[@(]E-T%BB$IJYQ^%> -M643[+UP5+NU0/RT]FY]]FSA2AQ3BP<-0S`R"T?X4824N!1*ZQ&,J#?4\G1)O -M[V=)"2B!B;5[PDD@J`\3X])!ZM.0,#Z5`+I`5^`''&P8X$W1]#KY-D;QE`"4F=,*(8AF4SK*Z\.[V( -MQ->V(Y"JA5>-9]#\,6.!_/77C!$=$=`-?DV[DV77/M2@(,1AX&43![;KSL43 -M4`C!-?LKC;A/JY+XT-)3^I>0YC28]I@;WZ&!F)8^K`MM>A8H>*RX?>0K@-Q2 -MZI%5[4XU;A;1A44[KX'&?LO=0UGC -M]'^16D;A#1SHO1"D5,!ZL8HL:1ZMTY2Q)6+<"4EPR*IORP"0=,7=JBJW'2/_ -M[HOF-U(K,IGW+A@D_Q5BMX=&\6EZ#'!,")B3ET.MW'YSQ0L]8^PD+=7S]O34 -M0]G8\)3DV?U/2\4N?"'R5`GV' -M&&9SIYPB:NX3IBFK1DRR=FDUJ@T'R8&*0D?1Q"=,V))C@@,8-.D\4+,<@*7M -MY=U-H!S+>M*IF^3KR90PA'Y+E_+\M6;;80H].4R$'W&T?2>WYBV3?D>D;WF" -M3K0)12/TXI4LF0$PI`:D*=C*6$T$TT*TGHIZ1W\5X'%+8#FYSHQ,J:M:0T-; -M(;.P:"ZQF5NYPCI_^V\!L!)Z]S\`(DR@;>2$C=J\JBMR'$Z&O9TUW];(FC7" -MG*7U(;/ER,6&DZJ2@C47A:N%%!!1F]`6Z?S*QX6_L3!(-00!."<.=,9K$LB&K-..7PT,D-_\`I3/1Q"=<*>[5X>NM:,A^[LQ@OR2&NI -M:?CX9;FU76)S.7UZ>21R(%N2Q^%5/*`>>J`+;?@,$#JN4:X(9!AY"E/O$,T` -M)&;/\&M)\LKAU[S!1Y-<:ZX$-W@D84HY+>6*)#25)A6-1)KGDV,7]B$HA]O- -MO5H_`5?^U<*!#"]*$0@9>9$<%,XB4.I]`0"FYG&!]M-)0WJ(_^L(B,`)S-Q4 -M?ZWC_,]V*@C(;Z$0_^.G.D%NM'N?''JO5BP*/F6:D[-:/5P]WO[->%P';4)% -MT?A"/C_,41P>W>E1?YP;VWR#]*<*&` -M#JF(2TPP)F+)G<1AE)T0`]+>[\-:'^=J?-"PT#\D2E6E(@R4"_ACH:@Z4YJ# -MX'ED+G]?)S0OR6Q\-HLF;8HUG/:DQ1IS\UI=QM'4H0TAP(1F.84'4/GP)U0M -MPC8W\>!%&HT.S5Z:#6;%#]5D;"..NJ,?NI:NM&CNOW\A557L_+0W+\5Z'=#B -MNP3LD/D!->4^H%.0NFB:\P6W@':^:`E_^EL88;[_79@;#ZPB>Z42CP=VP+]" -M4,7O'J/UZW]R;=3+#1Q9M*H,-%7ME'(8V'ZE5#B<*O-PU"R]=1%]'KVN8`H* -M+F@J/50#*F]DT^V!(K'61(7TG1ID\4\HH%9H8&190;;[?&8 -M_WT,1_@/I=`)7HE%TY0SP`[NE^!%K*%0;9,G<[1P.,[!1=YG:<8N$%X(&QV= -MKH0%%YOZ[&!\?&X>MJ[O2H4U="_7T4X$IT_]=6_I5%NX'UZ/D@BP5\@KR0X3 -MB`Y^8':%P*[`EREJX^B^5_ON+2DKMRK$>$\RKYA>O3QM2U,?AIRP9B^;4>:Q -M(<3!CP8/G\$93\:.:$+4DW/!=QOR7G+'=SX`(M.5S:1+X%!#S*9P?Q0S;B$% -M.::=W_69J.%6#&[6`R>._3G.1<..X>9\;4<]YV+*65WJ_U!,0!P8VL-%YO0' -M-?@M_DB!]2S>Z!<,%`PII_[U(1ESS[S'-8?L3HS""7!6@1*@ZK5<^)XF2LG= -MK\W,[#?Y8TZ1(EW&P0/1>L"G8Q-`[^:*G7ZZ+T`$Z$$[)(H.[%]W(=BDV@G+ -MYY=*4C(D<&5%<(2YLGB5.\"BK1A/JN%DPHC[R+@$ZIY>W4B-*S.U*&9A -MS23);300,O#98MXI57U3ES$U+OBCXH).-KW]_Z9;`PZ&_&6&= -M2*U1`Y+WSIFZY^49(S1]_808^67`J;5Q[`80YFF0'%@S.V*L]]0$UD?1SM^Z -M(S'(7]!`@;1M\J[ -M@_/1U/SC8[`KZ<#]DZ1K=G`K98L$R$YN6A?`I-Z0*@0\?G5G-Y^AZT:)!UACT'<*Z:K'6U/@:AB75DR*F4_+L58`+ -MP2GRAE#+^L:O>D72%WOMR(BC(.G-2ZJ=3/.HN>YL]77G#9Q%:NDG.G@-550E8^-BR4RE^.H,!\>++]KY -M,I)0J6=503YGU3,"R^03!<=9MEK9;W61E4#UUQ@I+R>0*)5:>;K:C2XH+>6H -MY*H-=.>77%;Z\,U>`H,[,]\@\M[P+*.0`.D:I>_%D11230'__C-L6[+8Q_N*:WM!DJVLH=0!IP]`@29*P,W^9 -M)$EV8P%`$8F:P<_)Y[;P68%7MR\HY2I=.5V?UDR-,ZT7R_M\I"'Q]55KC(/Q -MW@LL14%ZDI-G#7"&FE22((3GAC3C*?8"0AR>*>FL-&K.F\G^3ULXX:`1_BX -MMQ#+9-T]K;I.,1:DO6:U.'^=[/&)49ANH"DNCN6\;,N51AQEP$G"/]U@^&TQ -MZ#!:(S4EX'$!7!6B8!N7T7+_;K#"M-$3+_4G>Q5M6E*/;.M7L;BGN3@6S+2K -MDTE<.MB7(B$XT*:_(&3$UP!CB1>@91-[B38Z@K`2X?@DR]/B/>?:!J9&U* -MO[VTKKRC<.5.5#CQ44!#,US2E8\YPRSD&2DS7FT6$ROS=,M-OK9S"G#*R;#02;EQ>&(HZ1#/E$I,5 -M-;M1A`!=19<]P[?.:0Y":CV$_W;SK.?@A%FB@G]YO4PW91B&2I59\!6"]G&. -M[\JJ1HCC@0XE02QXNHY5TA+_\,!P2;L3:] -M0R8I!G6U\-&@BJS=-:_(4KP,9/P(]6%H48^GWN`&VTE%>=N.JTX1G&4H0`!4 -MW6Y7.HU\,6)`V!J"WN-2FC@2D,^WVW8&\^&,]AL.A'X?X>0AF^=U541@IJOU -M"`%Y,WW@$N>$5RNUI@>`9E%/:G.^^&Q>KG[F-=D=HQHH;/':D -M/4/@=Z[E`IG?Q7V+"LZ\RQ9#JS,AF0B)B3@J`H-\2FC.NPGMS87!@`4QCB-S -M*0VU;,MK]$K);]`U!\BCJ!P,:9-R_Z9?/PUF -M+&+/!EVO^K]PA3Y"O"7(2MR$V=8]R2MV7M=!B!]IP:=0OK:D'/%;13\^HMS_ -M-KK\M]-B3-OQ[4P&U!F[.C?K1E3J$^LYDA$W(Z$-^."9)3;Z&I!ZJC[MPE_[ -MZ-E,C,A2F'*+VU,KZMF\[&R.>R1=A7A45&/@Y&JTL-2YD?I*-)ZSX6@TVO9- -MW"E4"FB>;GF9^ZRL*_D5JK#&M=/V8AS-J)(Q9*`\S` -M_92I^;XV`)JS!2=C.I2(C*!!($_WSW8N%_W+J$D8=6OTWTV70LS1`G-S=J6; -M0B"9E@PMIX_L@IW5=RE:<'%,EEM-"O\TB#/G4#`U*``%DT-A:%<@_NRCR2D$ -MA!Q(3"``"K&F'7!.RX(J29(;1DA);:;Y%E/.)"5V&3/@XRG`F)T):*0))5WA -MDDN6JOJ-EZ=P6BG/TB15&:F8?$^8.8W98#-$0Y8L^?`>-1'T1Y8SJZ8>K]UN -M+W`MC&O;##E55SYJ3+FF>ZQ,U2G$0`&6,0N<#>H^4E$K%<4D,HYM>0!S)!D- -MS'Y=Z_-=(BM816')<0$O-1)%#/O)J&AU93%V--[G@G%EW\%IV?[C" -M!QXS)P[LQOAT>N&/H:>S%T%D"P07PVQ1SV@CIV`ZK[%#CC+F#P]ZU'LPGZ0L -M=762F-W2]P$-`:.@8!=*5+TX4^2QOQ[^5GF202?:%W3=^CJZM>?L/I -M35I/&#)V'X.&/SY -MEEJEYP7-P9[SW$";2I\06L]$P^>LW0M/Z'7;6>3S3)6B8*G06U?)O!^>Y1C@ -M>:PU@&8$&E1#3059'@>J9AGN3-J1MJ1/FZ^?ZN8FC]E%FS5J(T%(]6.9_#E> -M*.X??3B[5)`.4][\2Q*@9//)L')%M.$.?O)J"@$LHSMI+A,9F/O>J`A])H)C -M$%,2)G#B3O.G"4M:!6!!K8C'N](DIN%J>44,(+J'6`MA3-X+H[KJ7P(SNUV^K -MD[ET`NNR)/+C$@#O-[./T/R-52L(7^-CJN#8!Z%D#T"DAQ5=>EE2JK2HGSP% -M^?(*](%SN=)UX/>C6ME$W,05=E#6Z84Y*\5PET$2^JLX&-RAF$"W*D'Q;#Y. -M]M=KY-C0R1/9K+@?*_.!/WKF1)DR-=(E0KW1Q/>/C+SZ&^*^8+/FA^UV548!%W]H$T\KY,V/-B;$+>I -M,])*+;2+B+YA#C[WH^P.RH+3%AX\JP"#K(^@2;XBLCOCIG8>7)U`.G42JKPL -M]M9QI+4C294ZNU3``1A))C#E(M:"[78N+[Z=_RC_S-J"O@4%H;*7)UH+?!N& -M#U;6*/ZBX\,*%$`-PV_;(=A@P%2SZ,__RT,L%FCU2K56%B,J&?M+GR.BUTJ< -M#IW$`YCRU=]!%V'DNEINNBSG;6QJ)OY@MK3,?6Z<,G]];6@"FZ]/"PR.!^W5 -M[\0N9#JK[1&GO`"N#N.WT\$='EO7(0TJW,M/CV8=2"Y#WXF0N`AR(C^M8=U" -MIC__482F&#F64:OP5LR?*9"*XL&&'!%&NXP-9'`K8%F-;*)='N.K40VY)0S@ -M[:GN2#6[IE=S/S8,4;9=[C3P.NF]%IT:<.U`/@VQ?#XY_^]?CSVD'\8+THZA -M)*-Z3ZEI?'\AEKIIE\;;=#OM3]N>LG9&1B,]ZI"D8_GLHG_JDLPN\(;W/NJ* -M'[?Y=>A!114PM'),<<=27R<=9HP)KU -M2\"->:H7H;J75I1#R^5-NGLVTP]P^U$:Z&E.)JQ1`R#@')1\.[J'KNI6U5I' -M$AC'A9AW8K<,H!W:*5NO>&#I69N9Z%[F`JH_LJ+HAYR?S6Y_H55,*R,V$QJ= -M!!A-.;IGY[UBQ<9SI.[)L,<&]LC%":#4-OAP2J94\N/'JCLQI+#/;,*;PS,< -M4)$^3.=E]T1^HP%D]VGRZW)DNY$^^PKU(E.@*0]Y?UZ%G"O#7!K_5#,0.^;( -MX]6KW0XA(\[/_$J.1J582G14[0R\=ZQ]-Z.5VD_QI/.CL-P?P<.83;=3O%PP=Q<`6FI:1"AZMY/300BIG2.<$ -MQ*Y,81!,ZML6!/?T6-YWT%2V'A%4^JU7IE;^JP#OI08JLI]I(F8&WV4([KL9TPQ0:^ -M@1R!:_?^%HJE -M:X`X,%I80'5@Z=O6<6MB4%N -M>6IY:T;-[=`[U()MYFM"D)[R(,E&02DL#@6]\R.G5XN3.*O,IRWO)[-3(%-9 -M[]GGJP=R>]456T'_P?-?G^)T2G$1J-8A.D_[`31:Q55G5$`'?GCA-+M:(IMK -MO@6HHB.8_3YS),V+1,/E@]K3J\@H'F8L]%36!BQ2MB;\S9[=Z-, -M)&!-SQ.8U20AB27(/A3P"R*(73:YF!2A]=$P@9LH1<-9`9G -M2T*O+?@YF]!A6+BA)C#?0O3_N8J9K>1]GK2++7C66>"`'\/I*:C@"M%(X@#0 -M4#'=$]";G]YL41!+0(LNNZ5;._GE@*W*5Q`-*AJWF5N>&_^.:L03]T.\L*E.)3`AOK^ -MZA,?.KJX4DWTPZ/Q-IH(MG1?7"+0-&<.:9A>D]8-!!G(#"#Y3TG#7/*$7*GL -M@+,`\O38_''V19-I/@WECVJ8^.IT0I`%6:@E#DO!/J$KF*1/G0N^P)0_V\+Q -MNW1JSZE!!<6."4&\G0SA]9+1Z>S)W1&GV_M!5&PZ7?7MCO).$,)#;.4!_Q@N -M;\&!ON;]2(@KMCA\1,AE;<#?QBO91`ZL6DM)6K,!#*$7RO%=DW!'764[EQG` -M5>_+CG!O*\60K+T1NFKS5UX]PF'?[4YDMPKFBQY"B58P(G:0E\)]?IXFV$3< -MM^[2=YH1E>WMU@>&,-E9L58F>*[4#]4]PL_CRPB\XY\VH_.,R,+-4O9D5$4#.[8?WS>P$5DX -M[UG8[/==+)5ES;.7I)@7A&&WF:5BE&PYCJ76J)VB[?(RV>>FS*_$!\+PA8(L -MMXK9\ANPAY@:[,3PW<%4EM^VYVM!'4L;]0!.#+J<7AS5>-C/]B7($-::5<'K -MA")'R?EGQIRQR5N^!]I=H??L"=8P0NSA*E1R`]%;+2QF&7DW-(O/!-Z7<'(' -M$DXXZ?`.U5$MXKH\Q#&N0JV^S#L/_\*ZG-M_J(\O.NL8%`/;9SFT@]YPD%*7 -M&;>0]I>-VYVY9HG;M8'\25@L7O1#N6H^.C)\.#I2L,3C@F[LY\3!:3(X=O@9]4U;B@:_?>CLIC]+]]"$)W -M$XR7WD(*UDN87-:`^05(Q]KA[7TDV35GZX]$ML/+!Y0H22,[R?4<&3EE6CNK -MD=/RN;E@#J;`=.:-Z`Q@+FB%+[&B]LAG2'E6>O@!X3`T1;3QMZF?GS2G_4S? -M-%54]!R(-8Q26&&X70#(PS_=\:,19NML7NWBQ92.R++O)'\2Y79DE$CMH0)B -MRQR6X'/Y:$TV9-LCB_=41=ECMA6%$A9\VSI+NH;=N@#U$'O55[:8M$-I[^:4 -M[MZ>PT''2N3:(7\+'5#90_IG -M]JZBYM4G-V5"MLI.D51-+6&=Q2,.-R;;3J);ER$Z?G1W+;#EM8VGU_+W-QB$ -M]H@&/:+RC"KLPHNH2[57&0B634]:X8V'O4$3)W;?:D2N)\&W:/2/\R?(Y?!1 -MBDB_SV3;A+FPFUD,[QJ.%ZF\9;UOGB::7:Z)7#<8$#Z2\^[A*%Q+ -MJ'C717HP,SA##<.ZS'HMY<6.-+3`EB7U!T#HG$I3W6?0<^D6KI -M:0(JXS5,N@/G72CA4/P"MQ]U%LNF:!^0'B*@DE[D>^$DS\`I+;.\2U5P9WE$ -M+MUZ@5;^C@E*0O%:_A-_12Z&U'YS:43;4(6!#.USH7)%:CM!T'2^W'>+<=4% -MVZS"`[N0V)<0-J]N]7C![:\?-06E0S&G4D3IQ_[A1!IK.NV?[B:#W.SCX3&E -MB$C0@@))Y+*ZYV7O*(`/;]+$G1"\#ST]?!7^70\ZOU;B26O_7XZ&.H`V/7W1 -M%";=DMMX)C:&.SB>.'HT@\RV^LEGA^HF"1+4@]SLWA+239!W64H(0BO-3MQ< -M4%QO/\V\9`G)X1EQH&.A;-V2$E!OENFXQE=W$KB7OS/GWC]2=W-GG -M!ZB;P,[Y*R.48@-E4#53S49J&P:O\K'U_,Q'EN>H5]9WG,5E_RP&EO]A.V%$-QNWJXLO&2CD&FPP-Z]`4=^=4&\D\GC,CZ@S([8"/3U -MAA`0*[15G>MK@4'8D>?@P^MRP;`WF`HZQ[?"^PMN-J[,:[[Q#%=L_H+RK\,G -M(Y4`A[(C2$??.6M1U6=3Y=P4>D;=V_4II&X@)-`4QTHX410YD/Q0F*+9-$[, -MH%'4W$#/7."QI=A+I-;)Q8]$<2N,KTA/IM#&3&:<)X$U`Y'%7I`NORRD!@8E -MC-06FQ)&/=2TXBUE$U[+[7`(*Z>/._TTL-'@LAXA7`JWV?#X;XL<\&@/UGY0V9]-C.:86$P95#`=K5\SF/ -MZYGF`"6?Y!%*S-U!AL5>K$K';(7$$+WD3D&+Z3@CG;%$(:')K6QT#`&-[Y8? -M_\J8`H64)FE\ZP[>5+5$E`#8>=4SSQDC4P2\C7>XM:^-0MTE@1A]"?C7J],? -M*I1^EYBDR8GH%NIX5^0;`)3Z\LT5?"1*\'(^\F3=E1$#1OGFL$+KQ,H9=EZ, -M6O_4`]6C](*RM??E6/,86/:"WE&_SD4#(236/>0"=]1'K!52PLA-_BV[ -M'4R$[(%7X2R.HA.H_OBYM;,24CK<<70\6:C_>/349:[M[K0(WG,XV(<-0YJ];D$$NX$3\(%/]A\A3;/ -M+YY#FF\\)Q?J",\FH(=NJM-/Z,0.ETXA!P[SC7`&?$H&[H6HK/>@<%U7>\N_(:W#J\1)"K-*Z/@@%05FJUX%<_6-5"FQ1F-DT'FD=*4S['N0)D4FNRD=1:T3L?#.='N"R1I";-D. -M$U&R+/*(<4I.R]"MYIQWK_T;#C6E+J2=/*`29UK) -MXI'35RGF,3)FP:@7F@#"&CPT,K\6`YS[9_7;"&;8B=)T;Z'HLFGA2#YL7EGR -M(-"SZXFU,GB+\1.\7`"4LA55^YKIPIM^"FG1E?[J7JE=&152#5M=2#8BD%H" -MJ9G`A`BD&]W[8.,#U,)HO"4:EIY['CV@GNV+[2%/ADZ*@&;I-DYJ`'@B".)) -MYOHR][7UC92ZM6G=5EUT?6#+'".#^07&5$*5.$>6X#G:GHR4MR;FE2([AQS= -MHT\>?/[E&V@<(@1'8'1#ST-S/0_S7JI5TP-6"4N%0>YL0;9[W:N;BO%!-#5$ -M?8!E?H8K3EL5T8#/M/#W4"L6,W>#Q'^!%"=LT;L;>G2]B(#-C;P?^&WFYUTP -MIVM+'1,R%6-+*'59*UB9$NI>QHB#I+W?O9;N\L-`7?2T^X$>..P -MDDMTZHM380!Q8U`U%?Y3@`&]^`20W))@?ZI1L\+*S7%IB&CD'5WHZ"D&C^FU -MV1,<::YN>3J"HI$E^./[:APL7W;O`P$FE.-:'%^#2Q62:G]NX^+U%M1/5K5B6WFHNH[`)!<3$J++RH26PH>6YQ^ -MFZ$=/WR'/Z*_6_HN+Q!UV/DT!GUL_TU,,$;:M7Y1"JSQ+I@0'?5%@;/[MN%& -M,*D!>6#&WEV?R2P[=%MQ[A1-GTN)_<(D!X -MYQ?1P9&^ERCRGX%YH[XN&>G('Z)3YUHM=C[?6+?A;Z(P^T#=:V`S -MG^T=-5/UD7B?SMX4!)`<>]_*\YPTC>7B,]'E7ZJE4S`3YS\^138L\5%0)RGP -MZ=:Q"S$C@+DPN`UNI'M+EX2+]AY2$W[-]58PE+FB/KT:?3+XJW7Y+GU -M:_AR%-\<("7Y^_^('U:5]+PI63SX.&;F,-;T5/N_E>^"8KIXSRL8S>=Q&D'F -ML[H5A08E%CN%F$166?T&P(8&&VT(V]`VKVZVIM^>56,67F!.P07Y2FH*'4MF -M==[X;Z8STW,>AY)_L`D9Y%O\\Q+8`3!SU*E@6>.QQDNPF^8ZNMKZ2(AU7#GC -M2#9A!E<>#^:_3SV.=M6W`KL8%=4S/6SD27K$;NZ=0M^#))ZX;8%8#`PRJ.G^ -M(/.(Q(U7A22O:@.>SO3OJBJ9R\$>X,K$"4\K57M7U?KJ"\JU.N=PTEX41PGB"' -M[^DWQM)&::3[U-5J^-6&:U&B7;-P^QX;;9PU'<(2D!2P*DHI*)T9_!VNM,$T -M6`1IG#`AIKR2\9(GYUE=I8;$\=#2>\1;[X0&C-\N/X=8UYU?(<:]WS3CT% -M@V.6H_+1[EKD#-1[GUN6WFRRN:BRR35G.:E,-I^=R)7`.LO-.G55X9PE]BL> -MDJQB(`&L<^S#VHZ!]W7JCG=([UP4%2T_W!D@"),RJ$WHFGT(Z-%=E@KG9&P( -M>'@<.?>],/(756[94)<5NTJ9%G[F8P+S;`27B]3;0]C/[Z19/4ZOA_3 -M2$.!:2Q%L<:TE&'I-\I`GZ:%;[IN'O=LBR6M,]G0_[0J'Y@I+$QD.=_PKMU] -M\M0XEZ?WJ4J%TE6@V_T\D5_2W!HC%SY3';L_:-V$9KB:21#FR?S'+CU;"\7C -M*=J-'2`#]V\_:HURX>W/#" -M:X6K`FW9F5,GW./23,13/.%$CETW8I*[#D@$E&BB]%A5-)4`'?YGOKG$O7T. -MB,)L!<_&$@F,;)7KW4#4K-XA:AHY\D9/[._I/A&A;(*IK/`5A?SZX\[`I3U$ -M?_6,Y:?7AM0.'OU]/UM%BL)6Z#%@0_^=/O5[`\N)R(9,XKX@PDUG:?SL,7M` -M`'Q>$@AI3QD1[9P;4BW?LS"3AJDO>)D5G$:G,Y8`]\/7756-KQ<%S^Y/)W6# -M%4`&X1:;WR?K9G/GE#R>$G6U\`$L)M7:U].?"&@<,;\ -M[1X7)FL&*'3*?-#9=%2"K5(AM5Z+0W$OU_K>U("0=N;BB56?1:LQLB?HCN]2/:L1%!)_S4T2Z<6':4]S*U+#(WO/"QURC9$5 -M$OTB%2=0])1)>X9H_";'*.;CD'F"0T.CF4*BURL<00?P($2;G3(Z'1>FP_M) -MKKL4IHMBAOLOW7T5Y_/UD,*B6+!(%WR[[A<@=(('F=9*F!B!`_HN>O5^D"XU -M]DZ:"O]M".X,J`VL29Y3M5U-)@AL'"P5?Z!!&$+#XM5!D0P%P1)3H\I5R31Q -MDJ""@/UG5%#5V![>?XEX.4WT8P_9Z0R;\N3K,'B721K%V-)>\NR%4ITG@D=E -M[X,KA+MFI_VLHN3^R1].Y(8'IV<4:\ -M,7<[M])-DBNFY;=([C2QZG$--G^&8HZNXKW+&4.$GHI+"(QX;JA?IIBJJQVF -MAP5WCD%^CJMS/1W7W>*V;"_>?7;LD/7^43=3=X/X3RTO)!WT3V3>=(&K00PS -MY?U-%?+9-[4#4KJK^HXZQ@U,A)9]@*(R=5"S>02JIC:S26"R%;@XPPXOEB?G -ML8=0@_?+E!II+E%PZDDZ`/-3%!H0DD7C_X=C$9SS$7/F5M(0"]`[)G\,_&_A -MP6D!55=("4^'U>-AL>VD7#;K0)Q-='1^1;55K:\`P=7QSQ=9S.Q*E$#"44-B -MA'<[FTJ-2@7ZK(TE=S@,UQQ:Y\W7_(;NHR>`)H[^%(][U!P-!&B1%/VX1T\X=MYB*WR9#!90(HU=T6'6MM17[ -M^;#8^'4]!F-(7WCZ"&G$>&WL`X0]OS`,#YP\7S8Y5+ -M+]-2L2.Z:O!.QCB=$4[J`+SF1!HHBBKYR9Z2GV:`:W+9;PELO&TPV=Q^4O.. -MBQB,A\Z*B\!!K)`V'BE$Q`J-?2C>:A)+*^D\0V>>[B=]W^7]PU]\E?I\D%(\ -M7X/VI_TBU#4`=*?2+G!8)&;^ZBKWQ2+WACJ4KE)$(_)X_))4,?4PXE<[]5K2 -MG$O8H<+E8.Z%&M:A=/;&&>P91!P5'C)U.^>R59(YZ&>P5FFVAF$X\=OK=!KB -MP&KE&"YG2X]=8M*8,<1D2L_X0PZ^WNXXTG7<*P-S[YL\BR)'1.^J_7]5!>; -M[<(HJ7;S1Z7+C((''N[<_DM$'*[HLMT7;!J<-(\C$'8!F-_+ -M$^D^9RY?[)AH'N)PR3XHBHW`H#?VT5)W#6-G=1PFK^73D@5^;[]$U+]%^8\K -M>03)Q@4VA-?+LM8S4S7)V[P;SX@,5T?&%1"2DA?E_-R&-2D0`$7?W>'\7]XW -M6:QT".HGY^Y^GP[_0(71UTKC<@4).HILGT]$`JJ3[+!VWFPNM$:I0';@QYZX^30=4F<<8QLH4;0S3G;Q:>6^*S3R -M]L2!1/`)/:AA0HZNZ"2^OV7X6ZDQPYOYM<*7Z`*$@UT3K!T72GO?6D1=Y+#7 -M('6AS70.*09>8[>3Y_L_6&RG2('J;]U'\FKTL+Z,3PN-5X3$\T2BGP0%*L$L -MCFAH:9.Q/#VWZZ4UW0VPBH/6D,G2QZSN(P*?,XXVXB/F,E\?WQ#T3A@_*RF;]X>9E+QIYJX(7+.<4I3'-&'MQ]6XR^K:AV!`_'T1KDOZU8PRQRGK6 -MK.U0"MN=D%-VF_V@RC(G:K7JD/])%;KF,&]BU7L@V-)44QC,CIYA700JF'>[ -M9[BOGAOUA^M)!VZPPSZ:`C8(E*1A5W$GG&J59!L^\&@E<&Q2(5NW/>7L)Z/[F%\%D>`Z';; -M'J+>!8W!:)PD^@P`,1>`5RM&E*+560$DO%]N^JK%BS=>Y8./XI#!LZ[\/&KS -M&6@O4]Y#(*RN/-5!_O5_>R)5(<`'/(V2;ESF1_-+891&&^5Q8M(Y%818?<=, -MAW%U"L%17YO>.H?<"WQ0E+B%/$'"]L!MK'G>61H-TXQO1)J-)[W64R],`8SAM63&BQS"N%U)&<@Y/TL:ZG=(A/ -M<(G5B=9(6N`D84,A[ -MR9=7I->)A@'7B^IX`J5#?J8BG+O9(*/@WTZ1X+9.O%.'B?,OW5H_8;^:]Y,K;>RBJ8#LCCJ,@U*.F -MPF3R0?5"==@H,'TTY7&F\97@?2M/=Y*V)6G^?&\,&+FG#7\`OGJ#CE%<>23S -M<@\45K>A?4A(EY;)*<9_GR!EB,`BFJB/C9S[ -M="_$-9FUGMWE-+1E^X!$_W4\!H^#3%#Z2+#NA":B289T;/9KCH8N$J;$VB".A,+V1Z(?X/)5CY_Z;>/*$#=`S&*TH&45 -M#\3>3ARS,O.$!FW?JW-=3X)K>VUVMPF))J`_'1892L)E)1-4--KC.[#4:1`. -M"/A=PPHA7J%METG,]L-Z5++KF[9 -M]D.K:)PK*_.1'L4`-FR+%-G!>XYJ(Q9,IQ]X(:?NJJ+DE6!=:?R,=^+A_/W> -MHVE7T!L%8H0*`]0 -MN,`ZL>H[,HF]/WR.!YZX>L"G\OZ6[.@/E?,YJ/KZ8"(HA0P)!'\TH&U?G"OV -M/HAW%I\"*N#?I;"-'2W$*V-E3`3%DX0GQFTN3P*L"D8\>KJB>X&'/*`-XS0C -M+TC#H7RDX3!>KX=^U1!EAYA(Q3WC%`Y.1W@;X*%TZI"E>@V:H$ -MWG!)S!\81C"J/3-/JF5I8$M]-/0#MZ@(<2Z06)'C)9.S"DZZYWQP71VEME]? -M6>)FJ=G?HLFQ*&7ZO5%!S)]*9:X8$QQM>^_>0N8IE&;"#5&YZ@^/1IA];WEG -M6F][-DSL\XU"3+P(=5HZD=)C2_V?VNW%_0R+0'GDI_<:D_B^<8CO6Z^K_Q]F -M\+_$YGG2\-==`>`>6CH>?.*_B1XGXT69%IK")DN?^*9M;=&;7+5_=; -M/@&1R?P*`8NFJ6VX;/86#OHQ?P97=Y_@""SDE2JJ(W[YA1U\">]G/: -M&F^94)`.PA+=UHM4YY[R>7'A@R;4`Z9D1;=%??><4D0SZ;;=)0/`PYT@+\FG -M-2F7I7'A?U#I>,SU)S&-+"_=#6,29["]W+S<82WHGY&L?J?&C@BZ4.CA,7)4 -MZ#'WL@P`'!D)A+T=HJJ#(SE,:[^G=!);))""^$-CK'"5]I!?MBD3F*2P^QD. -M*1A&&2E@DWY'6C_R'-=]ILNB*?C,X):);4,4;PQWZ&M3=X"("[>WB9<)\&_S -MB;\A8H2+5+E9](R[T;>909%;UD]]^C%@-(.FR"ID:=-64N&M54^%HV'V=%Z; -M9RUD3GN*`U\\8MO\0!`0Z._2;NI^\*J1OKU)W6>I,E#RQBDZLGJ^O!%SU$<= -M15]J[#9($MJG1*VTRR&+#07-.U)-:KE#?=7]]M("U/8,HFY%;9@BG5BA -M_"30,MLPE]&/K-7H/;C+=\QQI/?\FO7P@^0!V67`,.U4+M9Q&/-2(+5K(V3U -M&77J;[P2<@^%%Y_O3!F%<'2(NH3W];5ANAV$&$*F6J\@FD$W9*.&DSGSM!Z_ -M@XYN#7\;9>;&.'N7>7J6%H0;FHB3_<8[@J@JD7``QWDH@+#@]T\QT[?VW;R@<* -M=SQNE(K',LH0@5\&XBI'I\9:%2BX34W4W.B'KL.BUP?^<]9S4!_W5B!^Y56X -M^]G=!(+MOL_A.->]#"@;XE-&"B9,(@&K9J>SWTM-<5V -M)9RLNWTSI,_?E\TB5->>DF9EP2BC!4H!C^J67'#KG<2:' -MML;O9%MW/6$B:X9QQ#\+07C3*283"(KC1E?UV6H)6Y>F@P']``I*TV8 -M7VE+S(4TV%[[W$&JU:#WJ]B]/P'J5H\X+:!B8J?6-B*XW!X;%]SEJZK*`/)B -MV`NSXICX.&M%)FZ7FTF%6T+`/NT-7,AZ328Q><'&Q-HY;_9O3RDVU*]=68/G -MSW="]P@)T!H;^K='BFO-4QERD^X(`2O0O"-9!VQ6*`G3'ZDZ;$GN.+O2>*`6 -MN%('MK@U,(Y+G.M:`V+[)X*/"CX_/"\G.V=H5MOEY9(FI==PU6^-7M,J"SX/ -M/:CW_=&0$""I_:P=Y7]3OD-^GZ0QJ].F:^,D7?=>[<`OX[16.PU:RNX#G71` -M8)Q?*`&WR:#4>ZE$I&9LN@.%BMB(_Y;+'4L34EN>R?MH,W0*BQ'^WU3*Y"*6 -M0$Q4LES`05>*G4B6D9:+V.TS$G\R]EO%M/:X)-XFE5$N$U?JLI=KNGV'#YY_C3F5J],7(,U"O+N[^] -M)??6^$I"Z&+'HR)Z_X2'4QJA+F$"O>%T>LE;5@Y^P>9Y"'&6E[/!()Y--P*F -M-Q@+I&,K`SZWPG)>T]F*PQ)K;#CMJEL<3RUJE3[13C5>V+V#HGA$I&7OBS/X -MV7S_5TPV7:/!CXE*SO2CUUF[T.O8E'?=.'"\UH>%0R9R:7V6OK"-L&HJZRRE -M=`ME,9?*^S>,&1ZNY/^\$0``;^K$\(/HSJ$5'3J30*2\'D^1D\I(;B>M+CX! -M"7:;/Q)>[I/Z2J*\)J.J^P@3J.;;=DP2?>[0?\XK;><5%M[_#1<#J&2<6!8* -MGDZYZSD^@#9#K1`[-8.1U4P,[E,3`F5,G[D2EZ^0!`,+(ID1D'.D++42;%O= -M*#[CV6+U-I98E[*/!QE^-]-L'F?@GM>!,5CEB0;J(*JZG!X.4;N.QZL^8("6 -MI8'"`;+,9V<1VJA>>#90[[%PKM)UF4]ED\BTA(D`+B2`*&`FB;J:V:$=.!MT -M[B6B=CIAJ:;NR/@_[3)5&1^A*@)-$,0[UF)!VM`HI8LTD=FFO)Z:]3),P/+, -M^:38(^&UR$O+/^:T%`?1PF0WY[BRVSJ)HJCI[24LNQ[-4!TY]]1P)3097;H" -MQJ/;K%<.))<,9]V=TOH$8'4^"]=K'^J=$,@FUIEKO.J@_DB@ZDP(&#+_L5:I -M'JH@+;D'#W4@Z$PXFN[2%OU]!E>)OC(\_49]W*0H"58*1%O?F?;T4*@8XMZV -M,O[3+4YI'M#@%LR@=#Y\)K8T7?)Y* -M<\0G"=[*LWP!VXKK^TG]NA:YZCE[$L2)B/;:BO:1C,+<#KQ& -M*"-O8=CZ@A-&>WL_[2@GH-9&H"BRWCJGN]_ -MFL@7G&1AZ/21T;\W!U-.,>I8!*HI09Z*F*^F`+A90:WQ)RHP6FG-DJ4LL#"V -M33L1C1S&US!:%:+,+X,:%DRLX%]4^-12W#C(1`CC(NA!1>NH%T&O6G;PN@SI -MG8]R-2W6-VE.5)$;47)81F8,:?B]Z[AG*TF:5Z(1F5`JJ`-`V:J<68U&"L<1 -M6PWIJ%X(")L[SOK#(7K5H?H?O\^F0$$S)\GVS-A]T75:`V"(UU8VVM"3#+Y" -M;67EX'M2*>4_:L+GVF29E"U>.[QXHW6G*1\Z]!6Z`WOJAG]E/+[UK;SCPGX_ -M+6D0Y.?$J`[#C6`0/.;&IFM%INH>9=U@Z!W28?\LH^<VS9WVL8AS(]!='5*@F+W<'NN+K):,((]824A+V[C6*!486#)QO8);645& -M;Q6U]AX)?O4KUE:>QV5@M34,8_\;%LEWW[50HM=')."CO5,OX_3#1-3.M*"5 -MA)3S@NJ;/$46DF)P"'HGQC4KLPI;PE>@?F3;1=5*QAM=KY+IU`Y^8(/0+@!% -M%JKJ+G`[\L=3/)4S]Y4-5MF*;WQ61ZK0<.$@T+-^WUDP%UQ=H=[G]L0<3QN= -M%RJ;&>4656TS_9M0!,Z_,;;?U:N&PFMM=3(HT%4-N&8$V[[(;UZ(:LJZKY/B -M<(R^&9CX*D9,VK!0$R5S+8. -ME/$3K%+E4Y.SN&`6#$F'(HR3','\L(()UCM\!\'GEC=9!T\N9R^936U9P3`\ -M3JM9@);C4UR#GVR_\8L@_9"XA`49Y'&6GJ$]Z0^6#(QXDU7BO4S!3!]1'/)2 -M'7PZ5+F1U>:VXIR*T9N*<;"M=W%SA@>)^P]92Z/D#U*@6@R0(0\#M76Y_5-: -MJ'U3YW4BWA/Y3IL[$-[0%,EHO(;6;<2KQSR\HDQL;;QQW69+_++@=M\IS(\% -MO/FZ>5CG/:^AUSG0(Z9K!^MM.6]8)&.#(7J=2']%4D9LHX-\M358(EU5*"'5 -M:0.B3I[,$$CNX1&'1`QY#TMQ>H9!I2$IUX%A.B80AK-I46)Y&^!U@MFSM3%\ -M$(@/[%ZA7,XO,]+X[HHE\4^.H+H4WV;+RZ1W@+,KU0O#7/1^6<4C4B"AYP?V -M?..?:F[K^'GB.]*XA_C/N['_/Y$4MBNLL3HG"?X>USEK40[C6H:H]7GNC^A -MFD3LVZ-\S2YE[>$05`6P5>_$"]>@&-$00G/XE;&P#I;%EPLQA'&)3H;-3[,Y -M9KP?`[_;(V6Z[\9B*F1JJY0YE"=_[T\+$7'K17KBSTQV.W?VNXB<(M]R,+:' -MJ^7`86#&;);A0=),AF$9P"0`,D.!$S8O/B;.A*8^N3NJ>'-W*,&J,'_=;VPE -M_99WMC=1EIV%;.(&4LTR.H:-%K_2$5D]LN_!:KP1>#G_\R38"/X%0<>R%GL?HAB.6._(+9"#/ -MY48OA.F%0 -M20W%3>U#RX3C##@S.W` -MI;'L8B]4-34""Z[00-RJ;LY[B-#Q4K/<4799QVKF;(_5_7LJ%7ZE]#PE:>O( -M%H]>/YB/IE`*"VUAD%J;?JE_JZ@#_\&61N3HC(@A=,NVRJPH2VPW$6.L%OA3 -M@-N;7RD#:8Y_)')QC^-I[1VM8 -M#>_+!I_E-E!G_A(SBVOO;EE;J5SV@VD2ZSVV_@;L9S(#FP^*V+KF.*F?VJSS -M^`8.=ZZ1KD -MT?\R1E8Z?FM+<'E/R0W(NZOO)$!+O"8;&U0C9V^F8:;'RAZA3=FU%_6;GKRO"-6$S]V2=W)@S2Q@IS-2DS119@*7^3&G -M-956<0M8X\==1*3K/%^FMRA,*ZGHS/R]JD#CE,,F^T52H/WH"UW%*<2D^=:M -MY2>.:@"F]V^='YO0J!&E%+7!1WV1.[V9`!^S_B![HH*/PA>PN^S/W4PCMYQ, -MU&9]PXJHYV<&2X%C"%)!=>RS^MI0VLK@YDKEO.2X4]B_)?6.*Y-> -M%>[`:=Y1TJ<'];>M1X246%"M&X]F^%66%1E*GQ==E.C?-8YDVP--#P+NA`(C -M_?UK95!M)SCO?F.;+&W'+98-F+=GV$CM/! -M_$+^)Z6&Q1#TU1:Z:RUJ'_!>1/U&-W%D$V5F*OL/#<6A-1C'P[.4ZC`*ZC%H9XAIJ/JO[6E&J-(Y;.-'8]U"^-W7`NF00N -MD3\6S"\JF1+_H"5HWU6UM=LVFG!$D>WJ946P+1:O7#<#"ZX$4[?_U@P7[ECG -MO]TA;E@;+Z`]=W1[^*OP[WC30S;9V[(-,?2]T#D+"OG/%E6%N^RA=/;PH9VK -M=DWUXY.Z=TTL -MOX"\6H.ZNA]-00K1E:L)WUB=)0E_XI]E^]1#_^[)RN[;^@$=93)+'X4_+[**KMU0_=<-N#(T1$/"_?P)F0SOYX#4D9=9`L'!-R3Y_P -MKSP,W3E\BC5'2UQJ8"$[C\@!\Q'1Z*NZKJ0C,P1Q!V6HDAV@AF)-\Q8\[9O+ -M58-%PAN0\4P#MFI<&[-]\$DLFY;MV*VB$>E4/30W$X=0[>WKHHAJJZJ(B@`O -M\[7^@"9,F?>J;OO?F.[?++B%`1H&-^^6*6613+XFD7)NQ7S8Y!#T3=>Y6Z.GP)W+'#V(^X`O.M];_[KR)9HK5^>B? -MS&AXM#7!VM*`AXD@<",$`Z%4]Y9&?XN3@X\?K]C\@#`(YS\)4MU*7;D>&AJ_ -M<9)RA%-!3EX",C!0N1A?6'-"675V[XP@;"?(24W`<-T]")27^JB!4$9"SI$( -M*#'Q'Q5\E/HRP6=$E`Z$\?$4\)43BWP_`DU8.,B3=ENE1[6HKMJ-UK8NZJ-I -M]FX9G"T/TR^(I%4'T\!#.!H -M2F%6#8MM)IE<@!@W"/RZHA*:"1U&BR+PYAC"'UV#F5=@.FUZ7R,!QGJ3\=42 -MKL2WZ>2.L&-+$*TXE1@,HFPO90QFT3`9O*.?&W:^+G/J"5H%^)71&O23'"%Y -M(R6@&MX6V'JS6U_0WJ4L?KY\7DS=\8Q_0+NX@8F46]9(GPJ4_O.&XQZ)Q4WF -M_K>!SF&&X#=JRH3^O15C!;H1U#@L=OM"\9>L%*GS>_N#$P>\ZL`7A'+B/3]X -MRTQ]$UD2R@+VD:;A;OJHFA8@R69F#!*)W[JJWA@.VI432F'$68!WIQBHN-(: -M^A-7"2,1?"!TMIS)8SF'GP(27C&U]\2O]W?.=)J"M8.Z/7/2&SUB=56HI\'J?Z)4LHAKLOMB+UM([VW'XXN>]PBP81BN#X6G+/J$2O;\7"JX\#2L -M?2\0^JA3&DA_(["AQ3>HZ/:4'HVTOOR2E0L#D^ZVNE*TES@[#QJ8Q$"H][Z< -M)M!2G:1=>H-S-*=BM)KRMNK"`L9GN<;0M92=O&/V`\B9!W\-`5V<5"9,3E:G -M90W"G15C_"""/PSI!".+46+?K73_^DC157U14`S08)#"H?]R2$,OOD"6H*BS -MX:7J$SEKD8:/S56*?U1"O(A\'ZX*K39F6_.\;)G"E?$:94I%)R#K&*#'"]QW -M-]=*_^3RIJ!]>G]H=EA-&-?X6&A>-ZWJFV=';=$6U#>,)_M#A+7\>&20>+EF -M*KT@&\$LVW,6.Y(2CM(SL,#T@D#0SOA])EI]_IN=73H:$C$)2T_CWS(5GP=_<`WOR`COS3N,:1>UUG2@0*@)OG -MH1#0X[;MY@6S$YR%=P6O[<+:#'<.M-"$+%H3;DK2WL^:V67FSWBIG"X<2Q$) -M#+]XL0>!LWP?3]D'`8Y,OB@=G*P'8-'M.ZHY;!;"XZ8*<9=BM(.Q[[H*W-QZW+)<,N*?I]A/Q2 -MFCUH_68X#`8UPK(#I+A?C=7/A.=S,_D'U^],T,/`O!MNXIZ4,_.##8H@G@>$ -MB+@'2*S:JE#.`WAB3GIN>F*4;6)FN@)=']O/@S%!(\3"B%D"4]"^`"]E;^E" -M%RPCQL>6:C3E'X5*X(H[>203Y3H^C#TFN]H]JU+F"-M3-^0=]>Y@)I(E\I6( -M9P5O\NEL['IW.`A7X8FD.=IBLP]A-K)_,/$YZ=:#1]9<"T(+Z*1"(U:^6IP$ -M'$2U0Y*L.8HONV)\01#[ED"FFL/NS1^S_A;_Q9$\&D=(EH+'LC1_$ -M8DE//:2`T,C7NOM<9&QCMN%9L^W`UGE>3'TVSN3I<@(%=(],3")_/1_&Y?I&J[0YT%76*[4]RDHCP5,G7F;:)5N,\`>F -MO*FPB"WYH9>!DZR`V1L=)6J5?0G\JW"`NZ,4"%2#C;&VE;R^-"W?S!C#8_AP*M]6'P46R.GL<[D3>YQ^6#"V3N@/F[T>[G -MQJQW18Y*.,:K3BZGT;X'Q:O_:?-\]['\UB^$PWSM=#OYR0YWW//7]*)>6WL)PO9:II.@#>-+7(CN:\! -MB,)94T;`R#I1D7H=OXN;?Q437Q+A0(1">Q0K$R$[+4'O'AZHZT6)E[>VYU]V -MQ&2^"T=W/-"[=)*UAK^F&=/OXK:EQF<;RJ(HS'71FPN/K3)2;W#49-GDFRSG=1MX -M`"X!K\I)@=(]Y=(1`17JUU`$YA3ZOCN$VHN?D1X@TDU_4TP1(.WIM)JIB.9# -M=C#\>%^HJH"0>ME5!,7/HVUQECB/BP[%M92,+0`94F9)YT,O$L8,#M6QGLF# -MK!K27U@0'JUY[>S&@'8+'/@IP!X6)"T@!]%.9&U"NE3C(F\9,$+\%KW^L)U@,G!#=B6NGJ=WD:Y)-PD-@O5P?Y*[9.F!C -M4U2(!:*Q0]^W+BA-_U3[)`;_>Y2'AQJ)*`[2?+*W(/@Y.&7681F[\.Z,#9@? -M$8>(+0?B$`;-T;0;,-ZRFJ\#EWP4V40PO"9M(+/N)7QWA@;=<4B!");@SBS+ -MH@!L!"#*P`$1EZ.$?\5&)&Z':_<$N@[E`)8A`H] -MFL3H:.FPQU]^W&]#,%,D4$VA7$(RA#HQ^QHD5)1-*DC?4+W2]OCJ($';_PLF -M*?K>JJOX9T6EX#46%CZ9=/)P)Y5D[(M.I*_3@RRR7R=WUS*\9RXHGJDJK!`O -MYL>.G#A>*>Z@.W'S*H,C!`(J?!1SA-KCR[)6P=#A=OYJQ/QU05._+N(7)^QL -MT1EM+7,KQQ-L3FAA3'EIS*W7@,YW1BX/_*7^9%\,!:1$"5$L&V+&VDHRZN-5 -MNK=Y/6?J=\T-EP(:)^`BOS6QFU[D)M):%:2R!$-[\`+$N[.?S*3&0H:*"X4RR6L\'T,B3W%K0>\PJ7DCS8GQRQ\''B) -MO1\6QC]Z+6*>\=D-_I0/\9N&*DBFSNAE-V*,C-*!90?(IMJ+[8]-`R.=?3#M9U5H_\$I'KS -M)=\B14'1]E:Q/H+(!;!5GPZ0ME^5&JF>NQ'5(S,S-*&;[0SJ7C5JG<%6D>P`NJ>3W+@?' -M`NFQ-ZB=3TS7)^]^=JLT7-^S'9D?\=X?O*V)K$P5?$1B_"5Q&V.S8,8`#)7/XLH9!2WM>7`W;O6>;(PU[K"_5\A(#0) -M2HP:7!K/95KL^6'9'HI%#!PR;)`L`4?"A71ZV)=58R#)+)P/3<%8.$;KV<,\J$YZX>)K,&_#(] -M+,E@VR9%D?0>$!:TN7#B5U@_DB:Y()`QWTOW2?'W)&=*NL^LW@QG'PBEC>D= -MIV3,>OP5MEQ8N5=0R9[AQ:/PE*'PZ)^.V$*G07N56> -M*_L@W@_*R*$O!'M&1B1]C-R?YE@._*2/.4A]PD.`M)3AV2^1]ZK(XU7-[XTF -M\!90V64#/NO.CO1%U\]O2@Q(\>6YD3&^UX(+DE2!DT\V*I^BZ!`9H^0:5U67 -MK2"AU/G2Z*BM;Q;1-1I*E3_,**V#&>#LVD8*!#*%P@U--&"KK4F19?(D?^XB -MJ2$J!H_]U^G"Y*).%*=EZ+3!']'$:>`=>F2E;48\:MT&$8PG7F#[-@8*9"%9 -M]69#OGD6WR1"<*N=$Z\$/:Q(HFK0(0 -M^4_*N%ZNZ;;)"5YK&\I(#P456;!VA/CG@G%\(1SG"^D_8KG-*U\KYGHI5 -MV+KTL_/)1ZI03.MKM*:-0G1GL-K[*H"/')A+`YF<-XB*S!^CZSFE5L)KJDC1 -M5>CG![]8&Y_6M5S:1HY.2I4!S\))G33PF&B@1"%6@2-'"?MCB=\>-XN2EZLB -MB2..4AD]@]]JQ^RF75&;Z[Q'[F4*9Z -MF[]/_FM*>#[+^::OC'.-J*3HNGD@Y/#(/6TE[WQ'F+130Q,*3K.4#T8FJ-($ -ME==(F/WI@D17]^];4*86R)NL*Y0%+@.$AM4./?,40O&82'SO1.+GT1!*1LK# -M%)P0H/B5\T?*IP=5.&`9?1+$-&^ZAOH$%AI:.D^W4/5XEI:>;"5*2P$@>-0J -M%AR+?1XB$Z\`)W"CV#=^%X!W)O%IH.<8Y4QUK%BB.^7R!3$`(U7MS[\"-B##Z\W13!%1FI80*6O`+Y%0.W3KB$97).GV`S?>1I,]:\/,;+S+5 -M[O$RA$;QQL>O0#&Q337O'N\7']Z>N9(V)%.!I./\"_T9UR>N[B*DZ$\8++&Y -M'=IB0"!/JR(=;QL:T[CK*BN$M^P<>+>7Q@^F*7[MYPAI0M' -M@0V3`+O:;K.HNEQA0V;CE.%K3>6$ -MZ9>8IX\`23_B4V79MY[HE\>6I"TZ&ETBW3U]X\?=.#1[^E8E7_RWR[C+_]1A -M8EWNL704SNS3%7)`0E=[+1!7VPK/QEOYAT`H9'QP(G7`GO&^L)HB:/)L)K,;,DZ\@-9^F -M/+:A8"J#%NE974D?$/@#:=UXHE[JS0G\HW?\3[F@&`$]&OI$HD1S1Q^G;'XF_9K<7$ZZB/3)E'-\ -MT#;\#)'+C#;=02I4$.!V`HP:=E)Z9>XK[N'>2^_[DQY=+,D7%H$5/=4^$U:. -M?B(O\:?'2*1J'4V6#7:V*G4PRE`L/@DY2^>X+`297Q"S?7MKA>2.6-,9J -MWXJ;Q=9V9#I?4\FOJ45O;0>CTSX'`,C@)Q^3L1*X\OD\7]PUY -M^9<(%W\:-[B*((%6JO1>R[=9MCJ<><`F?%*E:CLGT):%M5&!G@"=LLYDO]_Z -M3P9$3R]@/XO_5SL8,#J/H_9KE$HKBH4[E,WK]CUCPQ-NDBV*%D>M6[=0K&=Y -M4+KRB"Y3N/@H+T"E=^XTFLG<82&)B*8P]7C=@@_2 -M'3=O)UK\24A6@381NKB:#V$3%.,IJ-1DHNTM3F#G3PYY!0!$8"PZ%'4FS*>? -M%QMV?=^"?!F#%;OK;JALH-/@L`(&Z[L_?2I.6FD!C.9/0L'9R6/G>"L-!_.I18$ZL!A:S"'C0]9/=I&Q;8* -M)2VA:T;XIM2%P,7KT'),'-P8[&)-KHROME_05ZKEHO)YNAYV]D?5Z$<[8;C1 -M823JMW9BJX.U1#1`QAF034N3&(_`*W.=^1'7U`.(QRPALCCS[5%P+^TN-Z6K -MA'A[H^@*@7![\W=J9P%0\1'0:GN[_J1PFEO]5XRW9]0],K7NYU%&M54.D'Q/ -MH;0OJ,;:[[ED*GD\KPBJB4=_4?"C2[JP-X+IZ_,N(7F?FKZ);6% -MR>2PLQY]@8;$G0_.7XC6'$/F"JE"*5I_GN!V$E:-]M\)M+(3RP#56%$C'&B2 -M]#2(:DUOTHK`K:=TS5/*X@576]%(K8,FR=<$`[8;=IR5^/G%$M)MC,4?N_)2 -MA&R7N'2I<:0LV1E;FVJHZ+P'N[A0;>F]JU[9@>4]6FRY&;(D)/,+B?*AX#;; -MZWQ&97N]VPZ^+MRRZ,FDH8^6^9WI-64X/;1B40J\.=,]`"-P$\ -M/2F*>R%YJ^BYY._.<9W>Q%QBT@OUCR)S(NK`!7PO%A-/B1:``/_J3*J+W,P9 -M',L/I8EV]71D?VK=#?"'Z"?A'J7,E8?:;%2!1'M+(VE)CO"$65Q6!AC -MD9=2VI]!%T2VQ7JW6%D&QAH/B]5N]S,=K0M?CBH8]!13HDKLP9Z2OU7\C0VO -M*+O._A,$"P2PRC$DTCUJNAS[0K?41;(7O>DD*%']*DNWJ)?$^3:S]@WA$+J;VO+UUKB0N_LO2"^2LE%3JQW?58??TP<< -M,V/R11DFXJ]F"Z>,UD;\*]8;<`8/!F\B'2'80!_FHGHZ#A/G`F'T))@O*24. -M^3\22,W'_!:('&SM57/'[>2]CJQK:U2_S$=-?=`Q_;=UJ5S,0YM8Y)_<]X"R -MN%JH@%?Z]R&H1UHOAHR""K)D$^:K=H_Q[BXI';A4XJ_GH5[`<+"6:T'?%\W=;1NR;@G$L_MRF;MYM_3#PS=-T/07.)I*F8F8Y5M^7 -M&T/`K5FZ^;\@5'IN[@P3^K3"M$G!2;[0C\P%ZBX:P=QP\7RH=Y!@(J;N:JN% -M?X2`WXT:?;ID[D`J5B<7`Y_7O+^([<"ZN='"_8Y,ZEBS\&K_6@'TB(C100CK -M=NP=.J(%H\>#L=?\!0V>-)UV<_+_$[U.`NT](0J4B/Y#`LM0]>OI*!'LXFP&^AGVR(E3$-;A(KLZYNEMWR:\7P -MS6;LX40NKE3X$N7KHD]UPEG%PUKE45&&N=$X)6F<%G+G&LM]- -M-L)##R%16HP0_%X#,;Z6$P98`M!-ZD][L$J+RE2?<0N47-_2L\,T,MK)=HKQ -M`,'CZ@\%9:\O3GK0`DR$U[&3*[H/\:!"1X,T&=I6']L123&U^;U!.3F_H&B6 -M'DO-G\RD6.8Q&':$"PDO-]IM?+0)P<_R8>N\H>Y`#\VGK0JWWG+A`<3Z<5=Q -M2=UH>2FZ,SZT'5$N'Q2[-N#L=45'`HH]PJ]4K8KYS\>Y#0?1/>IVQ=;=%3 -M3,118:SRB#Z4_XBOBYI4=OV$+Y9^_SSUG>>?^BRP(E958\Q-46ZD44G_7R^I -MWW!\?=4P`F7-M0#!W;NI?Z'XQ5%[Y@,!T"#@LA$U.G)#)CTL*W'-F(GH*<0_ -MF\_CKEJ;*0K:*?4N<]KCOO_IV3:K/)R&8AF#>Q2AA?9! -M;VD6XQ-.)I&T&BG7B!!K-&,VF.KRIKL'W;0BULD;W5P)`G0T=NLS7Y9"]7]: -M)*S6&J]"=6S%/7S%^#4NP>[+B)'1?[P!O2Y`\="1(C.<5G7'!,K[6P942ZIZ -M'7&TV`WM/6@2[M17COY-BM,UK(EQQ4I -M-A)*/9?8QYHE1(+W,[7VW$7?H=.!UU_UB#@T:!36J[6V\DU9AGXK!]A??8CR9WB- -M(U7[H39_?XU+,:;-!6%L#K52D!4K"D-=#B0C*8QF$G>C-966U#=O[?_:&VG\ -M3][4GJY,]3#JQA@[PW(B'Q'$WK'!J)F+TA2,FH>P,1&R-8X[4#8RH*7I352W7^N&#TG)D8L/E= -MV%&0WIS\WB9L_(EY(`X3?ZU+3'8\[G^B1>X-%#^!96:P3D\:,[!QH:Q*VRG` -M-6&`[%SM\?:Y5L+9>=D**2+<,];.X]8!T967Z(0>GX^DU]58#L`M+>G9208] -M26<1%]YP_4DCM&7Q-[X6)IT3-Q?%"(,I.RB:LJ:>*"8:D_2,7A&P"Q?*C.[- -M5/F&ZP-US==(YWDH]`"JV$7C?>HA3S_>N51QIR[*5,$+22+EQ@PW\ZW47PJZI"-[$ -MNH00T#S3`P>*K,.GS'K]_OM\OM?8==[O9"]N!AI(!F\Z.[@JJT1];])Z4142 -MY1J8]<& -M[L>8402L>RDKLPL?'O]<`+>S%I7_<(+?V>_V@:2MI/*;5SO"FO^I$Y/R$AX/ -M(EU8O'4#IX0X,]%6_.2-J(ZU0O1=)LPK`A,U69OU0>:F1]9=8]POY(>(93&^ -MPYFG#:OB.*$T^;"YD,1P0,TP:PF8"$6TRTV5!FYY8L;.36,>GNKUD8"!JJ2R -MQ^0+%56(L9K*WG:LV%BZB`IV*:V-@5F&99[X*Q_X"QNPV&@BY"\^"_( -MA?\+T:QTL-B<6\=9/)IO@B:16+TOQ2Q24'G= -MZK&)U,HAW0`O&>R>"8L=RO]0J,>UMW5]CY7A*E=R9%?].@&F84H`H>ZS;PWM -M+F2XTU"+&I;"9LI,+AD,`T`$UT3"L&,>$WG//A5OO@?O5A1-4$>>RMQV/H>2 -M/XI+Q^L/"BDZKW4^SO!G*2M*5E1?B-`'5>I%'I+$N_T>/H!>$#J;&!"4!&!8 -MT;DK,\)O3AQ)A]?:4ACJ@I?<@&FW"-0/2]#(!1(]%SC;#C[NB^1Z'M(YL%DP5 -M/N^M*`97\=_@;E`^_QNAS$):YZ_+L%F!VM4_R)+*HU`HUKO9CR -M8U@>.`M@:>W9J55/+9\/6+M:(_OBU,UOXPIFA@`'"C@VETCQI9QD-)*7H5I_ -MJWZ`N3UP^LNV&N%]P'JI\QUU`*QT*MI_XH#,]4`P9FG*$&MHL4$(-$V8CQA[%2&_V\+;-1Q*K(<\NZ5^J$/Y9<>A!5RE"A5;R]B7WH?R;9?\NL00YMZ-F;&5D+;*#8 -M8.F:9/]UQ0?XP3LE,,6UKX@CP&Y5=%;2MY;(MLA,J'U9U8C?W@@8,J#YE?)' -M:$N%,;/7ZG$<['\+B7H`>)!3%EVR1:[#>V(*H-Z'F]$QU?EJCU[&UC.TU -MH(>=M3HJJ1T7ME9>"@#^:(=ACF=^X1NN3!64C];V>*^EXCQ+G^*N*_F*-`(&5YUBJ'/0X+J^!N'.9E -MO(\L??]C9!5R;.QTI;0Y.;>/_]"(7_'J&+L1\``O\##4H`=F>4EQ7Z[%@?:V -M45OKPFH/ZYLT5?[;J>YG,KD4VR`>WO;5,L_44+4Z/.&*+QL+.W.'EUR^QL"` -M4O&"9Y^$O&8/E<0!J^BRM=2N_2R1W6%H_\&;\F82CGE<5)(CH>CE8JV2WB9; -M9L/<`PE=52QI%"S*@'@G,5>5*8N-7 -M6T5>8Y]3-)F='92(HY1ZT30+*%JD++:!U6J-DCP/NT)ZOPW[R!8TTV73*":@ -M>J4Z)P4!9::YY$:Y`5$?!7PF,+$K5B1^&M_E3R$*6,W/?.,=]!QTB9[8+D22 -MX;MI!^\X?I%FK968(QW9[&*SLFJ0\5_AWL3N[14.@U4JF.%5V&=UL62+9WH*_AJW(99N5%/Z?&X*F]_B]G/P;&W<_A_ -MG!`6XORDKX&[T^^6..6>WK_Y=?E0XM"55W1\8/+:DZNZ4*?+XT94C'@$\O8@ -M@=<4=]WUO4^$3*`,!RO64+PK!#"?5LW*'_-9=8FCY0OA*=`-KD#\MYD=W]M< -ML/\-`DB!^42H2NDENP -MZE]'Y_UMJ#/9]VW!+DZ9+65YF@Q/CMR*8OR0D@HZ&/G9HH?IZ>2,X@K[T4WU -MH;N@HV]#!):V3U!GRU76^O5@1ZX@+50,V/`()1.#IA]Q1!?@4/6HT=S,*I&)KK@@(+NIR -M1P;WTV8;!$)Z\K2NF6[\(?2?.T0--W(<3P19&/%2'T8V9ZY830>F1:LV%DN9 -MG2.H)D:9Y"3L#;*%%/W -M8+ZKNKE'NM@`$:8@?!++`..Y]]0@)*D/T0?M<'`/GEGUU%D"#_'XP2_#60#X -M@/%>I>]UHO<'G#8O2K3-44M:"J_9!JRV([YH,6M5'_E/Z::*\)&/GAP2\IWA -M@MA\BF+`<]VHX%:S-4YXNS4&:H3P -M$7>?F!%]&D\$VK949,Z!I@MCV^=2;0/47D@R]M.>`3C/>`(7'4CVZ;HEW(P? -M(:2R^S_U4[94P/2/`-_MX7\0QRV=U^<7L9'E"A/)Q53UO]D[@\&8FW5P6*&N -M5M`3\#KGKD'6&74)^GM7(3@$;4EGL]CR8"R`C.Z6HEI0%Q`D-AX8$A8O(YQ7 -M2@62X[WE!7I'%V_$W90P?>)!X?(.$6=<4H,AV!&M]F1'#]$*OEZ=\F,5+V+J -MAT(['H\HT]#3^5X)X/D.)3\L+G;DMGTR"D@>*49=-N%X%S3\&$9MD"IWZ<># -MF-`S0O+RK\V*:\3TP_Q/&Y5U1O8T**6Y%:U.YJ]:ZQTF[[=!'5TXY)VS2S!\ -M0+-B@^7``C6`X?;/')H5]T.^MVP8)`NR"JX.(VR]_ND+?I)':YX[^,ATV62] -M2.5]WK61Z^=?FS%,T5>B/[OR-Z15">1+0)NR8L7?VT.XATU8G'"\H==D6A -M0]:3RC*LE&&*SB%6OAOW3%>#NW-P*D']756-%Q1Q;-@1GT8+Y@T-C53KI:P_ -M\:;C2N^F'/VBZ+MN%K2903#U=-4H$?@HP`8_%#/CVG)U[WIM,'`"A;;.W84G -M665N9MSX7@6`WEIY:][=:\'VD[$R72?*A/Y>JDI9_+GDD.AJ?.('#U!'X`HL3[<>8Q6%#%\ -MJ01'9!M-W4`V&($1J"SV/^_QI)(/!J/KY6D -MW0.)VR(38SE7-GTTD2UI?\)AI!)MS"B!*M.YGGW?<&>9VPYRE:=M9?"Q1P8" -M`I8%I\W'CTK<7R6/=C:C6@2Q=I'-83^_,:[IP8-N1(;D_:'K'6H7Q'%[0%!5\G -M:,`!J"8/,ZZ=I[[36O'5G8U:WH2SN(_J;Q-CGM\I0KO@"2=>2JIHGBS( -M\NB_()9PC=O\U^D?VC07&\IO=*3.=![0#!.1=3D++-#^L67LO^9&G>4$J:&( -MVI8=%OZT;P%=DW,Z.!Z'H1_#/LFR9P872X(V?E#9#NW_]^?3+V7B)X/*`\.C -MA2[!E9$)&;?BO'.*2UX.I'08N&*>4H'I84ANB94JM\U*C-N&RT9@;Y+J.YH/ -MP]`EEI^+HD1&MO#?@SK*H--!FNLA+9JMQ"71``A!3PR2B?A/+?FY.[.8`0+0 -M!S;T"JLVL>A((!57)D]>#GJ%$>I8>?<+CUA4Z4&P:8(ZSTRB[^3*%'BFNG$VC -ME`S?5%JBWEUV^[8,!^;_5B&FR5HYNB?,S5H)\L8:HI7]_8N*TL5@^JOYA1]3 -M6Q*KJEZO,&! -MG.G"OQ/!LE06VO5'VH8RC[$I,I#QB$Y6;'M$1R?Z3,?4Y8F"9EP=<;MI*@VF -M'S%*_0YD5,VO;]ZVD<%!1]QWJIEEM*+X$!"OW$"VT_7I>.U&__[!G'IN_]:* -M4I/&$7-8I00?%*45@,C&'K%M%67@ZKY0VE6/T)O+`J46RB#])"YES-C=V]NV -M-J]<7FXQ;R>V9RO.UV,&G=NAL^)7-DXE=J)\3CJ3HV/#\QF2L\"-0MG9\9)7 -MK:KX(7MKEDIW.+M-L=','>MI`_#&5M5M2(I98"A`BBNG!BDC0B[E;!73QF*,:/.NS)\+>;X,AN[AOO@[;/45KG#K? -M:YYJN[7E=TA&"=@&7,K:B+!P.MD)*V?2:9N-Y_;5O&9\;E]IJ534*!9RKS>\ -M4I_6$83IU9^*RKF[MB+#A=UG)WOO^JJ>)G78D["Q4P)5^>'C2K^&V$X<@V*1 -M4;M"PZ.0P456T^B6Z$WY;R`,L[]&!$K8@AV"/9KSY7Z6?<;.SC4**E=C**`6 -M"01]\&(@5Y-](=#[B_O/H?G;TRP^5.`IK -M/:]T^1AG3WE,$+8R$:41_P^N2S725*33(3P);X_^/@N(FHLK)"G4BM]H?<$M]ZKS?XSU"GM(2P&(PF'*7H+-M7X45K\_K;, -MAWU5QKD,?E\4]-/&,4(V1K'@O&B$-IX@5GGSS71D,8M$+(;W[P-F]\Z3ES,* -MN\3E/3HTBZN<-6LSF5_4>)(SSOZRD5:Q((PR-J'/F8?.D+?.UE&>DA:-$\P6 -M2F15O7Q^*!]UM0,DN`IEJ8_$C8#J\Y8I]2IPRV[2N["&7&DG)ZH]Z9HI!,$G -M:&_NR?P2UG?21*4+W`,IW6]&6^[AE@.VD,>IC9XZM]S*YE'NQ_CW2;F/P"R6 -MBH8%R@O+HT:+_IK'6S(/+^1Z#M*"N8-5`;X(R,]MO;XY@*2:#PF4\@:>&9V4 -M:%+_3B'M-]FXEY_>W3_6=$5"K^73JR&)0S'G"<,1`I_.:!-D1TS@"KT2I3L;$$--SO.EX1 -M1%K[G6-,7I2-3WZ@$"_I>1QI&-[V^7)]7/SU2(W(IE2#)?,]/*MWPJ^YIK=2 -ME34<6:\KEXF'!)4'BB?7,"(U%V_RB0!IDIK:ITJZ[")93>>3N[FQE6BV)OI< -MLOJCQGG:D"5JXAM%$B"Z8L(D-UXY@S,<17Y$W]CTBDF=H/8IC39><(SN"^5* -MM<6,55!'E8.:*@JX%?@8\;1MWY'-<:2`\>=,KK%B]J84/TE+5N1BLYHPU<+3P*4B$"PL(2PX=TVK/_4\\BXP(@__U+[8_0\0H450@7J&4_65U=`?_'%';((P][. -M+UPJI"BCBS36(JY58"TA'EZ^0JO7YQY -M[`,*:+DXY[3JQI50M+&#)%>94EM2<@)@N4#/FB)%3?#HQ/I/_ZO`+A/[ -M8;R'"`$EQ)J&#?J23\/_G=C;L@D\F#2K'8W:(U&:MV\V.J_:K/.K; -M'M08(%`5:3&XB>3F=.%W8UPT&A2]';L.&-6%D_[18KYG\ -M8!-V3H*<9"/2(XK!,31D>)HC.<^?TYY8W8&[_-C-!>C$ -MZ6>?*'H]>'J'F!K!*M:JS6^TZ>?@*+RLW8;=6[R+R<4AS\O! -M'4XQ6^HGJ0R=ZYW>GU1"NWW.$C'18NS"3Q>Q!+B7UH>L6&"C4#@?G/=R,?)Q -M=\W4+3&-!8=_Y7_P`CGB\VM(*8K-UB69(#$B6M"IS774FQ)_]W)8;M -MC1KO\4`/*8\6`N&@_(8JO,70ED1S/-`9BP_2W]O!M57#,O!5ZD'VW'Y1U0J\ -MC>FE?_I*SZ`8'0?K=#;4UT;*:XP+_-L3YR%]JW:_J0013R4J -M#X?`(T6T"T+0BL@PVFQJ$WIG/ELU;>Y(_!0E6&.NWNJPD\=/%QI0JU>7=U*_ -M=^B-U[3Q(BHGXZK'[=AU35"3EG0Q7CC`FU:WM[N:6!$^^\[V[XJ>JH>B*'1C -M=(7-14,2/V[14*^XE18T(+/^D?'WT]2>+N.A\6@$6@33Z6X7+F&KG\/#>ZD5 -MY+,*.IQ4/"C[0.3JR4T/DP5X@>7X?_33;R)A(4[^X'.4VQ$/UJ%CF+@2!KM,Z5@/Y`R:+/`+ABO""J+K:>$IZ)"'*; -M)]CI1MFAT),#'B,XJAS_)>L$P_E'C=I%.[T59W]^4&^8_37JW$^WD]7$0V'3 -M7Q=0W>Y&"A&7 -M/1L16B?.\B3>4_-XLC#9EL[N?$O%Q/1X2J6*K1'@$""=5=6;1+F.V5_64K&B -M?PM4.?`]K@]6@\!/LL"*\=6!SV<*ER@D?Z]5/UN`S<&:%O3NJ]=IP_ZXFZ>3 -MSTT8""OXD>5>!EAK(3R+-K)I[0UMW+@C%CHY]'1X8@4\.V;H/XA+, -MF2I"GZ9?S@L5G%ID1[RL,L@Y90043P%\B2W+LX:ONB.FON.+_!SSO6++J'FY -ML%6UZ<#.T>PATYJ%/@#C,NL\N0K3: -M?]EP%5D!$HYE=3SHJX[P>QSQTC?9/OA=W.T;BZ9#NJA]80R\0C:<.""0+404 -M7&`-"N":7V'<_E51//I!`/]Y*U-+9PGK?A3_*_`B&=??OB;K-I-F#U%[?\S@ -MT)*B/:H\1_3ST2Y>_)HZ1,OG)JP<\U)^KE_KM[IMS1FEA'"%W"$Y0[6H/?!! -M*V\6KQ.Z$5Y,4G'@Y>)J]N[!:.,RM@1$"5`"M6%3Z,WXH5W^P!KNK@=#.`]I -M'?/[!,;@&JA39Y<+Q!M#-)*9$:Y1NKJ__43]JM&K]2O1BW4;/[S$OC8ZNW-Y -M77%`S\'OA_[&C8_>EMKB9K3-'";9/5=!4.,K3O<17B9RQ"2AF)EMK.(P.BHQ3K,1DK%T+ -M-()W^A]=`[!'UBZKMA;"$3-G(J:WQ!Y))<%?3RK.BZ#0\+Q[(#LE%.^)!\% -MMR^Q.2BNG!R4JZMN\JD"CXD\3,07R"*J/+RHQ;.:-BSXVU;U$3D$E@(4ZXZPT_. -MK\#1HOPSRPXBE'Y@]:2[-)X%MB2S'W&-N[!XS^\XBO.4S#@?MAW5]8%_" -MQVXLERN+7[AA.];<@4Q!6[2C_BT68AYY'?U-#_T7(K;5MM7K0OB#L0A!81VL -MVU0@G6FY4T'G?$.DZ4>JS!H:$>E:.;^!"K=`.TFV!K_O&@ZCN/SH56*#[9BR -MR(!QE!(ADR@;X[-OS?WE[D6-2+`_#.9:K(L?KW_;#:2S$,2;[\L_2>UY^IW, -MT3V<]7$4,_44+#%YFS]8K7H0+2+1=LSO4[VQPO,87`H,?$O28@7>`-E0\<)C -MOVUI*KH;.VRC0$=IK3OGBSY:"J[IN5L7G2+@<>-D_=JJU)GE!>M6V8M!>CUS -M<9P&>_`9"D%*N/5:_$BG@?+[1@R\(-V)`J=[6N7](X^B.Q-W/:U*AO=YG].( -MLCS.QSO876)T"UYID.E6)AW0S^E5E/.3G4O05*\*,5=7)\K1E8R&`+&"&E&KPXQ<,8P4(BW0&?`4>R=O@( -M8*_HYAA:"^&-1!XO4- -M8>?[%*I1.=)]E]=`X$3,R*GMDZGA)SSN^I9"3\C"20JFJ'][,R05CP6VCL0W -MO8/YYK!8*,PFJO5^)JO7*OC$$`PP1?:5X('+M!/DO1C5*(:W%P-070\ER+M+ -MUAY(FB/9CP)24]4R^ZG_FIRAU])1HJ1\H?&<$&,I\YGX>T;*9LK/J2`"@&-.#$4U9IW'KX?;/*?BK^?[]5/+,$8I-O"W&%=9>?-XD\ -MCET!/D=,6X/H:]-4WJEH.8A((P5FNZ)#G^SBT>ZJ"%I$B'67RU1`*14`5>.) -MG&F>\;]+>,K]@B'^]$XL3E%@D^#8H-O+#Y_G^DQ%*9*66=G&.FIP/V*J:E:2 -MBE1"FF9+<]B@=RJJF[^_AT]5-CG_O+W4LC/IE9;)*$9U\W:*Z)&0O9Y'=B!? -M`8I0/`J.\S21J'\[IO*.V+*6[ZV=\'MYY.N/'FBHW#6QKH<3H(QB@SW'3&P8;AHYFAJVO4S8I\A+_2$0%P),$O -M'?HYYVTXI1>R/WAT#*6Q;;WM,QF.5#KJQ)VW(D53/G?3F0W_^_`=]<(?"O[C -M&X#9+02_%-Y`KZ!+!:XA/`5Q,2QD\(-K^\KM[+>AU$P=#0(Y=I!W=K5B<^RU -MO/L'02TJ^?RYI4_`AOOI-YZZUSGT-D-J5"?[KASGB/VM,R8VJANQ1#DZ2B!% -MRT[YSW^AJ2`4&"=V$F"MRN>ACQDB9Q.0"*$G$9A^<4,.IV0RX'X56PW;G^PF -MXRG@8%K1BW,N%(`XUJSL$*ZE"!V8_+^"&#?]G#GB813NTX`C$M&^_O;43W&P -M!DF7L@2?S9;9/',QW'@&SF'=YIF))!S6K)^Q%8$7;W\<*.`S]AWCU3T-.F7A -M-:20!-4Y^)L&M2);LNIKW`]0M0PZ31HN5JZ9X4L5!V6*6'?V#N$SB;_I-*Q2#EV*LG8$VR:05[9R./ -ML:X0X(V8GHJT6CSF:\_!\1"'G!K>IN5RE*N+$!$-1DKSJ;J]'7M8$XKNL!OH -M%S.F%*:C'OSN3:V0.7GRO-K6HT2NTT/<"'&-U[-1Q_R -M+#0IJ=4+\R6K$C<@8Z,_F3A='!&FG+&BYB'?YB=30?*A=B9QTU<8+^+(69Y+ -MWK,%OR@*S=2?+YU3A]?QIR_5I6BN$A2N&%0PH%A.K*XQ5=S*I@XB<.*'XNJ/ -M-(B+0CB+)3%#6N*ZQ(S;L^\(E?Q=I-F4KFLQJ8J(/T*89+XJB=#>IM<5^-KC^?D2D^;[;72+_3(I5'BAE<.1IZWIVDFH_*8K*^A>N59E=!8VYTN]111_I` -M>$/ZV-@)J1@I7A12;GW7$`#6LD8_@]NUR!B-X\/P/=A3?>,P/0/Q0<0/HADR -MAK/>FE),#M"AY/.E/=(8:@I?9R$@1G8ZP6/:S6.#+2*$TUQ[#8_S``?&J".\. -M?A6#&F1HPYS+5G@ZC5VEKG18!!64(DHW/07C,`L^56^\9N=DPAS!< -MF%;*=B^]H&),F&BXK>>RE9,^,DB9FA*16I5Y1J,'E-TPP("7]X_N:J)STCK< -M.`:@,3D?4V)OB\TB_O8JA*FVWJ3SHBT?1H=F7L>)E6UB@$W(7KX#=?D/%,YN -M`&O/C,U21756-_&__60>(PO_KF<4-E'E>>O_G2E-3&4>#QV``$!P?V^X4L-6 -M<`-#T?O3XD\^&HZV'XI2K%B`"Q/8D<>BC0X_%J3616=NI9VB%BYY-R:Q0Q@J -ME`Z((3_^@$C1#]514!$0STC'Z,0WMKPE=\??QRY0C4^)RXT-4R">);JN?70H -MN8^U`_F._Y=<6*3EM)V,3A4)^6O9HL=PP);/++HR"%O^?(Y&@Z\-0-;>1?57 -M("C5UM;4]8C#B+]YHA>>Y]^_!"46#E:JIETQH,FK\1'Q_T*_$M^\\[SWH\YH -MS&A]H06_!9-$WZ-&2@?K5KD4S1I8^^6IBH"P]E2G-W?A.[LH6ZG44E]HVC*( -MAGVO(D3.063>].*##P:@Y3"9;;A\0=SH^E-A76W?(`RK#Z;.K_'MS.S)#@YJ -M6`?&.=5G]XVB5Q)]SGMUB`RV3C\=G9;+43O5H@.H8[3^:"URZ$R%+WGMIZ+O -MOE;9EZRTZJOEQO2H2-Y#-&A941MS.W-.F@Z`_6W/+>WZD`4B\).-ZB/OWU@I -MQ1`'EJ9\#(2BNXC9P&?42CTE/3@>0Y>U*SN]?E9:*?[&$*8K`(5[B([;G9K2 -MQ)VD=B4?O"9,D_^D,V([/1T()*GF]W5K_9YATI`6M3W%E -M77^;U-=;/HFYI&(D=NX3H:U\0348["LB1SE+*#`3:V8VJ<80>)8S3H!*R/BC -M!NUQ%$-H%5'9=V9KY% -M8#NJ6Z)N34%)3\.W\F1<1Z5CR-^'PSJOE3R:,7PAT98BZ*]E]0YWFCD,4C&N -MNJI7M,8/^^9O-&FN?\.G;U2":4D+5^H]@^3I1>;[2-06 -M(_(9R,`HY@V"7'5GFO1-HV0:O_)@.[SEH.L75%+J4Y":K5JWIE+&++(+J -MRKD?./Y'F/*JDVP.V6+,)W -M6B!%(FH\RP!XV8`J"EF2WA[X6PQ5GJ:`]::,U[T,IM`.8C&)/*0+*ZJ':X(N -MHY)9WY/U-6VSD\ZJR!](V;)K2@.^Z:C-8!AE$@F?Q\&<4E<.[C3D`&"9BX1Q -M%@L1K!YO92BT\5H`(!53!QS()'R"[LS?YK9/&PQ1H&Z\T[3-K5*B,V+GT?S, -M[E<+]O9*)V0"[(R19,+LLDKW+Z.M[7K;G^3GP7B-9Y#Q2(FW@'^97O4*"TZU -M;-U0G1FS]CT)47`B?O;-@J1:NOR&<>''0FCUR8&.:E>"68_B`$3*N((.S]@% -M#X:7K'([0"K1&U,E!_?FUMV5%\%V=O+:.34/@ -MAPQ`I:TG3YQ&#.M>MC&&JLD,^KM7?\6;O.[@#,(FB5@659@*X;=U(/ZH&2RG -M#)'/2;.9&E3^@GFN:\?.?TA7AG#%A]VK]KPZJ36KO\KT+.,I!58PW>*H$R;1 -MD$I'V.8_$S?(G-@64*\Q\HC),&OP^/.F>YSXU>&EZ4!J\Y]X^W0&-0->\7OX$A6+M\(0Q7'?#NEWY$P5TV"DE:=Q'0U`*8IWL$'E.!==:8N63,JFS1U`/X"&K38^:&*[BK_.A-_"$M"'7(=CT>TH -MK]%=I"8(2_*JR0;Z:_L7?9F:F.6!5=(V6V@!8Z'$AFK7I*%*N+R\OI&Z%IV_ -M2V9F>2H2J075S^_4`8Y0%C8@>G7+,_I">0&;K\LMTZ9,1JB@D?3">Z8Y$%5F -M6$EA/Z56-GY@CO+/`7R\KZ9AP$CZIGI=:+M-B\VNJ?^A8*1K.R<+QI^K5MOP -M#B@$29U\HDX(;G!L-*`*^JV@V(F?-,6,*L35_2ZKQA$)DRC!32PC:WLE=1H8 -MW>3<,J62$RV<%/=>\<96BZO$CIAT-.!8;RN>TDC5^]/I66=TK4W<-X`.E[V@. -M#L5GM_W^RYJ3$.MUI>PY0$27LN]=,@8*.C`'X#W'G=6X6R,&+#D43[.],""H -M&?]Y#?9MD#.6O1[##ZVYJ&07F0P9$MY"[/S*@V57VJOO7IPH.X(N:NK^")._ -M[)]B/`\)^PLRMS"(CC!35/J-V,R80C-$:,F3\/;^&Y-)#@.(O$C(C4E/[1'] -M;^^^55(;(]G$1KXSW+=9]/.`"3N':P@SQY/:@0$:/L=5NH8R=7V-4Y=3\^H) -MT"/$\8@9)8E_@:<2$4G]^J;+#7ZJD-V;.I/V`ZH/':\R(O6]JI][9=BJLLC# -M3T+733_(4BCC.U.@@5J#MBY@FHIGOPH1-SB\W5;G.NTK%R$2N5GK,F>7;O`% -M`C,&?%3RWL<@PE[Q+@&2SU(4I#^1@]-$Y'GXCA]!=E4X`,?FA_FBAN17]U'. -M(&L$-&F9VZDUT?RWE7KGDOV5;LSRK^KCF^24G'N)A)!-&(+46VI&EH$J'<$X -M!?;7LQ+*6F107[7I`!P4L3CD)62`?TVYTVO@UE;8T+8P$4"0V^&UHB'A;_"B -MQW]/)F-QYAFD0%#D@7K^N%$I3-3)N@K#B/K2IH+&9YRGC*D+,=>#W+R_Y*@: -M:#1>>=C84*J`/O]8W/`-ZE)#*3B-@%T:]WVG'IA.9+.E[T_>;G*+7K'[B)2895_\!Y6EXU0MJS$2)B18KJ*E4\!UR?#G\%D-&)*J->I0>=[_.K -MON@A$WL2:H8(S*=]AY+D$5#1:Y'J:<;E(";T/H'4*OG7C@`'0/V&W39A\)[, -MG7V07.,C\=HZ?3MQ(/+ZUJ(EMI#8DLKVEN64S5=VQ?+APM\E.4PQ-K@0O;3T -MG;?PQ0+9^G>K*6U<)F#\>#L!;ABF2R9TMXV!(L6_U0\UR@VKJW^5];NX.5UT -M`B:71%LM*I$SM:G:=7."J.;W@S7HXJ_3CUZM*A66MT.`-XNV3KGA26"J_&WO -M/DR1DN?_T0#:?0%47-T879!FB&:4N/]YD.8@>`PR4ASL/T8@+\.$<9QI6;H/ -M@!_O]%*^>OYU+<@<'3QYT02_;GXCP%BKX!C)CAF/2HC3N<1?1?\E3\:QIWOM -MVVHN%:BQ%0F#%FJO'N4Z&??DB,(>3RDSIY5J3CH%BX4G^;IQ?;Y'ZEX-+H1K -M2[8["6T\;0NV*+HM+`4:(`0UR(/L]Z,0LA(-A&E_^+=;_!.7P[]EI6KDGQZ3 -MC3[-R;MJA'*@Y^L,"VH]7466SOX_?#/C]A6F?1)NCFM5$<&>2%H&"ZLSJX1G -MP?'H<1BWM_KPQ-QM".QRO^('=I82I;Y,C_O(T,)T\=BCUT16N-=7C'GAP6J:G,S'.H=:/1X;,^4G3Y?UP"1K29>[([+H2B2I\RVR&DVLZM&,IQ$2 -M;?=,\7=^@8G3]'#8*4]!V<5R1.*UTBG]`R01Z)BWF)_MP`#1QF@>7SA^FQKS -MJ8NOB:2]N.#:0]./>U@HV:BP[$UP3,UTK -MT'5)VOF9P\[].+H&%P6R-T/RUZ-Q='0;$X_:]A69]@B,"V-EK?#)(1F.QK@D -MK]A7I)-59D-?ZC_YA\]")+-#^>;L;?`AGMAVRL4) -M\7_EYR*1P-7Q[`R^,[$KYQ3(<7&S&DW7>S\+H#`"+1(YR9AW(V6=&G;\-;38X:[^Y4:]W6 -M\=)W$IR&;V%D&Y5(QTX@*9%",.B:>^,:L0/FP]>YMB^N>[JP>Q4E+)Z>F3AHEO)&= -M<+]ZOF6=K=-_M&+"7B]`T,\*>M]0Q>FMDMEB>A7?#><@7V]M#Q:P?PML.4(T -MM\?&%_E6W.H8RB.FWV#B'M&FE]A*#GU:&Q2G=5^S3?R.3+H)O%E7^S;K- -MO!Y?3B)@BZ`IH'O5B+Q^1VEGDOW2Q=DX5:8V5\ -MU%:3_^C&^%C)72(E[C*$T@NM$=#6PIV`_A^=>)DZ;;>^>%6B69\)E#-I5@<.;KZ5'(%HY^.5\ -ME+:]"9!"Q*".CL!R`5S'_K;'`PT8BN_IJ,-%A?&]O->\\Y6-4YY76K -MAWHE%S%)O/"[BJ%RXUGW=`E[^(%LC>I)]X]GY2AYGOA-T5!O7BEH2CD$^J:8 -M4P7L;%E`CV.$33JLT/ATC+N::K5@21X+_SRQL?4"`T+3\=%(IA2="(5B';WJ -MX'^Y@6%IT7P=/W?D@`)_1_L#)1.8W`X12D`:6/M)GZ<5-=@A;%13'4^\>^** -MNR!:!Z(8Y>BD4QU&)H6A@37S;D;S-S(?O6X8Q`%<;,&^C%"!L4ZHE9X -M8N!&Z9L]?1L#L*R3'F;>2"'EU[UA9>'-'@L/^/[G#Y*2)6&E]V5Q#J>?M$P1 -M&EFFT]V(@O1]H5'9Y#TF*A>@>V3HA8Q=++FZM_J0$91YL!H#HV?LA8_4SZEZ -M'9)10IJF]8\U'`-BZ\8GU3XPTMK*0Z7CPJO>M2 -MN_94M\GR1KE_G`#[].4<7BJUVA-GG@CB]9NE;,Q/Z9PF<'35SEG7*^WL#(+: -M5SX)/P!LZ[4^R6NG,TT@"DAQ8N:GUC1B.(/T(T$Y[:T$(&8C_&=6W"[0U6M` -MJ2,A\F60!IOK_D4)8IBT\)1BOW -M]E'/_H[+*W1#V#!]8;SJN&4E"[EZ:;:[I6*S)#+_X0*8%._=W*U_-5YK(]7Y -MB'2"!J=87R84O(N(`QY@D,53-LFUL>939-@PW,I>+!D5+1[&F)')BD)N>1>7W[O8/F+/ZH!WENQS:=&Q%3OV" -MQXH>Q9L02SLN:,KR",RHO3YI!@8B29/XF\)CBKG'36FA7++ -M6>J%<"\"2;%XP>W$5\7/Y::M@H]--O=@:]+0>X"TX`E0DMPLJ!#]B%CRS -MXV%-[XIUAU$CJ3K7DK.()2,@DHFZ_?`]^!V>.+A5R%*BU28W[+7&/P)#ULGC -MJZ*J@,''N-$T6WI7C&8"/^3@UE#X\M^X+]LVYS/J72$^UA)?_N*NI;7/@\+0 -M;-V%=$R:JV_ -MSR0R@DZKAJ'^7SR+C='']T#+`O0B=7!SZ,]/6O` -MLCL$=("2F@)871OSZ]#.LFX<^E!TP4H=_#2TL?VC2-EG:5A06Z\8M7_&$0\< -MVN&\O,@[+N$3#D7K]B&^$R.Q>3-4!GSDDQ_SV.@5L+.M3,,9D<=L<''29(4T -MXB<-B@B;@!(F@I=QM'943[F'R@<9/0-`\BP+2+M%J;X5D@9-4&KW_N^RHFNO -MTVC?*CL6C.4,-J<\O9Q>7T2#U8&%P;BLVE_M,78H$YN]7BMJ1.= -M1'0>-LFM_9#6_H5>BPOC,06@5':/8)U2E-@3+'[`$&F24Y3C7M):5FYN/"TG]#Q3T#UH>!_.$I:!#_7:A>6 -MP2XI$>#0LW48DS#(&6KK`!'08E.W9H^ON[+WT"Q;P -MIK$T"$:??_(]#MH*AR7Q@2(;H!M15@"DJ\,J5['K=N\`;LDZ;8,.2"H_9EZ3 -M+Q>4P]$&&8>1':4SXV?VIQEWQCG<>UF$V -M7IK.SWKWKWK+.`5#L`WZJ#$1&8*BQR*E88E\519B7IWW?_'\%2]BA;(FD;%" -MT@%86S4C*9DR\X><+X?;9G>!04K./F17[C@6GZML>ZVB`M'5L2L"CS[;ZA-W -M&T-E:\7FY;2T[,S)-KY-:L,]@Z2KBKCRPSR^Q]M@G(L4<%@2^M18`?=P`!6& -M/XU8'V1\FB5WZQ/Z&?EZO8IWP;[FC*NN+)'I:>S:Y-.!>I7?[W?3WVDD"8>S -M:T#\G"-P?%6VO#U&*P@0[&N&JZF78KR.T/FV2#;^<0A0[$$S80AI;6]F5^4D -M;0K8AY_Q9++U=6_2K.(EJ9+E$+5,=Z/IW$^]!FP`.(;'89VK;B.&ZD -M=R2=F)?/$K`HPP<>=,WY?/326G3ZF+@1/OXZE]B[TZ6M_$V191C$S/Y9YF&^ -M:DP90G;S"8!:2X@[K!"HDMH"R6ED_Y&B4(5(2FXH4);66+-`*M+?\T(,D_PW -M('@M1X^?6'=JU"'TA;*8ZQ6/-8-+'M#BK%&KN0L.=)['!I-(EF.R_QY1&?]_ -MI.OJNPB#U^'T7J+^,&.F#=T:V>"9]PD%4?0YW;3+A2P$L%_KATM"^MTH?%"; -MV(D&G>21W0IOLI'L?(`AI71K9KU -M'M,-ZY-XJ!YB_'4;$14#@CNRH*R-N=P^TC[`4VRIL_\]""P(FLBWI;X-XZ(A -M'GCA+Z^/T`U1/8M`\9(!CS5K,9='\;H!LA-CMJFI'`KKJI_P#]Q&Z;7=E0S: -MH8FU(K!,&(IYOO$5R\KU&2K[*G>C@(@C6=9_J7PYK57[C+X/\EIK9(D#_::*Z)S`< -M3R'\NI*1G$PC5A0U_(F@SJW382W'"N2S&*#;_V/_HNR#2+@^LU$4\H6YR3NK -M0)Y,.\P:!D]3A,J'EIZZ0H` -M1/?)=2M]P7^ZC,)HOR#XU;QB%H53M[M^+Y;X2&*)W?*D(?4R2]21M(RLK2G2 -M=(_FNJ8Q_)>E#CAITCAL/+[1B'0@D`V^+A#O"3DO -M;_951YY$N07:7,&JBO*WE,QDI<21X!Y!D(3H`=IFG)Q#!$ELBJQ)C`C![I]# -M=GN.3"9<;T]\EA>:)AV8=2Z/UEAXH^7KV4+/FW%CM'1C&`%P9@QM.MV3Z,1* -MN)G\-CO7X=?DJ,LIN;7HR+A8'<)*E:5@^E^FI.G63!)^#4HS9\_\4S_0C3U@ -M4Q$![(*VUC"@;C!UF3AKHYR2C$_>"ED-';90$`\\`Y1!H(X(JK172-+)WOD< -M^IDP-F+Z1>\!ZD9$RCR':GR`/0Q:J=V<`"L)\R;/1%G4@F(&L[;#>.O76PU2 -M65;J%-B/"C1']AU]5DX"^C=V4.J-D?F'X=ZQW\-0Y-*>'HH^$$G -M6WO1;!]F4:3"[HPV@GGJ`^:XV<\*ATSWC5/.B4S!D?0)8&8]*+?A^N@CN$`^ -MYFXTFKGW3(XR.!-QX_@9%3#^V[L6YD;FG[?YPJ-B]Q<\Z+]Z_^==D9.U6O0T -MW#;C-LL4#(&LV@GJ0=$&E]'JCQ5X61A2CJ7PK>TL+`75^`>@^,P:W?DV+Q-/ -M>.H8=&6/Y^S*UM'P#CU90J9BXEW6?U*J^KZ-#2?>8B4[YV:V!W40!^'!C;^Q^R0K_M;:PU']T_L^ -M$JIP+X+K8]3]ENC`XIVY%FSBW0&?/+C)LDXJ*(FI2B8SX(9NG6*]SB45F*0N -MR?%'%ET4Q)1O>P+9SVQ#IT%]C27.@S8#JX3NNTFJY/4)3X_WI\Q-<,ZED@X5 -MT8JDBXG$N)@M)T>8-(R^FGN?.F>M<:L=0L(A)RS%C+7'/+K(`:9D/?EWMB#B -M$+/Y69=#YU1I*:HV:MM5=B`/(!`C+=#-*'?=7KC//X^&T\@\+]<_\6[FO37B -MLEW&.@]<"JBT>WT!G8,'"W@*7=)==D!"GG+,?O?5U>/)EDW_S8@R9XNS^$_; -M.KL=IG!T$$")[1RN-7!I!?Q>CEU-2Z[]EK(F]&+"8FQ@6*::9(9QA+::X41U -M*H.JRY=26O0TG3Z\UBW#;L>$[CNG\5.=(24X1'#6PXKR$Z!\D;8&M*#*RA2Y -MB%/H+$"6V4$8BFW=6J4#`%Z[G/O]KL!)9>-@9Q_/S^]X0%;V -M[,.QT+0+SQZUTOM**N'G,]:PH(E$[%*#-]*';;L -M87[$(QD8LZ]4_\Y+XQ\?Q+;6!P/!TNEM2X_=%S@Z>RP>#UW7[1--W:_U*,G7 -M$7"Y_R"A;?@VI^(XD6WOM&W!<;,:8!@5I=BH6[N^Z$,=Y-A#,CJ*10[!VVTJ -MM]D$#LA=$C39TX;&<:*R&WU-].:M&37]WS8._'\\6^PH)^)F%'`.PXNRWR.8 -MT_G]N'E7$OE:I!;*UU]5*P8;9N%W0L8NYVJ;],$86=7!#25E%Y66[/)"8/D> -MLRJ_7:$;\$CBQM:I(=%6J3RNC74YM -M@8YD0%VM^)I\2K])O,PK#D/U$<9[*Q^1$/YU2/6J(C-I[X+Z)S#-3[CR>!@P*[;;W\0I:.^)T(!D%_941;O[P:1FBMY -M=2IF48ENW1;>>$$V6?H3,$YOC'8=$WGN&+R,"A19A0^2H%P`L3$U0-/L1OY@ -MZ)DI26/UG;TZ9N6LWX56U!8@2HQ9Q5'@?K'=S9!E]D4>U1U.]C#";A7MIG?% -M55=SMGH^/R(W!8W/Q,@S1=>L0'*KI.K(>\!(:-DOP;6OB_C.[H*OZ^_&'`I8 -M)]F]/J(BH)R:S7A/(N`0D70$+%!N,,_F$)L,!'_"L=\+B`65/ -M)XK:C2^K;8XL8LW0NN,RZKA6;/3DAE30LTD8(TF7[M"=_<%R'#A!S/N,'\D` -MO=?)3+/,E"AXU=C[[)G+[.WO/I\IP0.MXE1;ST?1W`:EE31]+H44/47Z=1R+ -MB8?^9KH2'3">5QSKCCK,M32HN^8Q_TA;&+:8]'M#%U=[J`)C0R`>G^62-!74 -M@@7/0S!X#$\P]#F,$ZJ\%(:^^#[^#3%J?U/#XB\2Z:H-SC@+0:G]Z_%"*\[L -MM9!)4FU#>:0\)]YU=P>.>TP3[`$=(H$_#K;JQK'@4&KNZ_ -M%92W:QS5Z<(<3D26;L0Z#6ST?68U=5<"<#L@S5F(0=IH0LU2%%;,-7H5(H': -M*>]3F):F:&CIU_F\0A<)QE -M0\@.((%HU0X+#-;])\`@21!F=DO(5I!,.<)ANQ->C,0N813+611T@.Z:@N9' -MCXTU3PB@"S`0;HU@@3">!7P8F)U+B\:#$U6MPYKUB51T"_#FN:QA)X58AS:_ -MAN(#Z(DBQPHH\(#V(*7T^P3"XQ@N5)6@OPSS,&MT,;ZT1A3K)0@(2K1[;SVM -M"NTMRR@[1;#`D!)M.UQ?!G1":\C7_"]E+QJ.1XP>S+!D]LJ3:/X<]4N$& -M0A_$$!/$A6;/50R>:"E^CRH8TD)PO5<&)*5]#*N^FRP1'93P/LN-<20"8EDJ)B1O6& -M"DH*D&@?T%W-N?366"KN%P&8MHA>IU>+A=HI:TNYMGH#QEQS/@]I2PT8D7JL -MY.Q1@,^SRL\:Q0?LF[66/B`=\<=53$:@R0,CHLDZ/";T*_="1;O.AM2;,([A -M'^R/UXQR.YY\RN>4N*"J_ZS,OU;_IF22H4J.+C6S#9[F&,SS:ASQ75>H?1LG,9F$!*-FW_6UJ5)-S);P(>,TX,J72_Q.?R$>TKE)E^%V87_)J -M72%R'O4_F5FR1Z[#-&C$8T#])L.5PM5JE!?AJ?YQEG#3 -MIJ+`,[&?7.SO@W$)[UPC/F$4W+*8;&UX+?+WXM4=/ZYOI^K_BNX7+<\A=SD: -MYMEU9.K,0]=99$WU-01^\%S*Z3#+.$DO2$7LK(E]KXDQSJ7H-9VJ#I6M"&40G7Y5= -MFZ`0-43%'2Q\IZO!15M>D;GX)@SBC&&5A/LI'V&JNL1*N/T^T=*>GX"EE,O/%%<`Y+8K->5G.+_`#2JL*D?L3 -M90*C%>PT*R1Y<]M;V3^AV,K4:\"`Q%D;)WV>U -MR0RSNLL3EI<.W%F2/N\@[FYE47L)%!N?6)["D3"\B72Y]XAB@T_0X7RH5\1 -MB`(WAGI\92&B7^":,FH:F3DQNX@;*H,?PP`[V=PC+Z@S.YYM8YBF(@76D4,/?YO[BJ6_L#@V:!,4C"`4=[B\/]\N-*@/C0+ZXK"^D-[" -MBR[C2,3SB\D> -MM]TU,'=!/#QIE]B6:'XK&N7R6!ZQ88$NX,-55]-%F;6&'O(#YW,; -M9,US8),<9_1P4/QCK]J+$VU^C0OMR:5`[F(J$<)_PK3S]@UH54EF47ZQJ?KTK3'T0NZ3KW!BINEKX&\B7YI>]PJ];B4?B -M)V*:%VP$+W++"#DN6`QK03X&-M)\26^!5;<=+/P)!.&-YXYM5U/8LN'ZM=P"?7YG6,H)C>-3K)"0,&*#F=:OT=`/2+; -MOE7.B1^]MBS**#:(;Y.NQ3]#KP]E5Y)2$#)D8BVDYZ+_Y/WY2A&DK7;>W/[! -M/1HTRY74=`7-0&`Y3C"T81#H'3<*$]$Z-W-#O"#_8OP%G@Q=PS(@0[664XP` -M;R0Z,DE0P-TH&](NC#'X%%%UFJV;D#6YSQJLT*=,JLD]*LXO3L_W!\/U_CJ` -M#0U"M#]_U8,4"($P`4*]J\EF==<@&"T9P=DF&!.NPE10\E#T@J9G.B'PB>49 -MSNV&`SHRWZ?K?3GAC<5/%'M##XO@^%]08@<4>&@=_0Z#Z-EBUZ9PU;OFK$RQ^.8#*U\ZM'([BP2&4.K)0@\HI_@UDZ -M!*[<9NN(;WR2@8A&A5)5Q>/PR9(8IT%SUQ(:X)J3G(!JU,*&Z,[U,E77URWN -MT0VDV)$N+?M?_"926J$]*@I$GD7V1DA>*!B5*IN^])I7)/:L2,FI*_,L+]Y;O+G-N5W,&M@% -MR[;CX7NWD\7_T"ISRKDO)Q9O13R#QPO.%(`4MAE2F-I;GU^WV%B$_ -M'KTID.]%^SY<\GT*!TPG8\I8(&][H;OS&GA%&"&GY'5#0V)54-Z1BA^:ILP\N=73=)')Y?WJTY]:RVD2SLA1MYO0E0E^XOT6BM< -MB.(SH7:S1PP`DS!T7;<2I("M6.`/O>^R_9^N>0!Q'SYB/[;"=.3HGB?$8(C5WD?HK@./]!GKKC%.UI8`J<]65/V?%C0/-$FTK*;>Z*#4,Y1`E(YI21!(.:.6NK1CA -M.OA[8X"C\OHGZ[]$<-"8EQO4`NR(FE\<:WED5SA*71+YK!9'S&7-M!$R*V[EPI2N;PREG(_L@V@$AM(-6)=%1C3D4!9"J';J[! -MQNM0NM+\O]47(`!RZ_LK\UR^!QJ_C>@@(TSEY@3A\J'OP6\)QZTW7R'_N^[) -M?+!K[?[4N@8@S?#?Y-%D9_X>3SKMS.F9?3@",,-\XO6YX>`"!P1)&@\M[O-! -M0D=JO89-UAG[FG_:WVR:0&J#4NZ8D;T2_;P5N!P?G-):XR6\>1K&K_GRA`P> -M]"*4+_!/=,=6J2@.5QMULPJW[#:J2+HWD346V;4T]UYJ*+&ANPENE><.9_Q^ -M)8B"E23K\)';ELK&0P>ZX*1FA&W_RHO(;T`*&L8TQ^'@>T=5?X03B#%N-"ED -M3;NJMYEAO5NF?V3S:2,F@2>JOR+^`0VPW>.A!S6@W]FSZ.+3(L"P8;T,&E/Y -MA%#)A2VX[<-N97XW`C?)U)]@KY[K5XF'@G%KZ#AN*")?U8H"9R2&DN]X:29+ -M@PZ.CDR;@725>='_ERY_%'E67Q+A^XI1#]H`;LS2V6FU8?T+4`;`3D>%H"R` -MN+;&C<:([RYBO;?<#H*ACZ1+IMR,&S1]9!3 -M'.=?WD`^K7/\EH^Q'\Z9M7)E\BAM<5#4,;-N#GT= -M+2\^GC1;EY5*4%D"FC8$_C\C!?@?.STH^U2!WSLKS'!ZS\N9HFM%>+BVMEPZ -MVB%*MAWDT.=OA:``!ARH`RN>G3*X$PWQ7@,6\;[<\U/6KCLW/_\-RR!VV>`8 -MU8GS&(R=EFDUL%AD(YDNVCQ[O:7\<%R&F4:IL@9:E;B/E*PM8:S"\&:T]$([[!'3@PZCR"5:I80X[_H -MQ:Y9+'1D0"<+GF>H%YWQW6SNL8O&=;4Y,B%%9GY1I?V'[HHM+-()K$ -MI9:LC1'QYKO".2+Z:*JVI5>J9"5)5>>CN16\C3*NK"#I7TFE.5<;3Q[9&F`9 -MQ2]A@@($AVPK&'<6&0V-[67_F`(-V?043T(..%2ZMHE[KU0.A7R=!\5%JV!KF\8X)X -M5"F7:--Y`AAS?8`X['WSV2;)/[Z%%D'*M(1&!'IOCC7G=6'MU>89X6.'8BA^R>J! -M%J2WOXXLMQZ0"'_\H^_"AP'/3Q -M"-8/_QW^ZNH3A2;"-62\/]`GRF<6U"=TN;V@-4AHTO9A8!B-\?JP8>+TH<*M -M"H`#IX)/JYFH'ITVX"&/,`>;2S*SB`US$3)@\"?8$ZA;;.+1DJ/+$N$[KH'= -M#&``4%P/GN@TP?"3&9LTHIDHM_4Y##2B%]6DZZ>VQ#!'.55S_,?.1GJPO1`F -M]$8,BR<%I\52):*/XE"9O*;$0[2H@\F9$ZK9H`QAE^\&@=74-1F!Y_WLRE+G)EP;E37&/(F&V*H,W+@V#09V -MHDUA#N'ZLJ'1WP[RZ'%8!?N^M80@5\@-,$H/R%ZNRBI[Y:(&YR5@#MM4+E_N -MDCJ*PTR4!?$RZ<<^YJ(J0NX#"T[^\1>1&#,)R00^]2"I?[LA\B$?L(&S_1B4'X$AQI)R -M6:":(#7X#9WG=/>?Q=NC(;P$V]9.Q9 -M3J@*7N":.6Y^%IG?E1QNE!ZL="6L$/W'L]\JC5_KB/ -MJY>3="5=-E+3S,7-\^42\8M29@E@!AGN(3DF11G?SO):<6M"/-1Z.AZY/M%Y -M1);D$-[;!\"/WWE/7;@$5D=#7:(&QR05VC*K -MZON00V_4*B"LG?6;N-Y+L<=`ZF_Z-"+B?9YF]7(QPM*1?IT"=:@!YLI'^V)^ -M`12]-K-`CD[",Y0(JH38E4WKP2VU3GY`///+]L`^/Y"L.8J%ZPKA!F7Q"->Y -M/18&ETAO(+'Z=.+L0Q@YEOMM`;'^9,=@;8=!*MMKF`;7Q&;1L38"],?<4KB< -M/G!GX4L/`U4,3Z=&^K\BR=7ASSI--1&5 -M\:IW-JPJ>'U&X1EM8=Y&-MG)>>U/HJ'I1@0!U4_\+4)1*H'/)%@S6O)2YE<&O7)(>B8Z4'WZJ'W):J4<*XQ"D(YA&05T><0!F -MPD)G,R2/`'Z6)@\?P4'N"I'")NNW.TNXHW,3W7_O99*QT?J1S7AH -M,"DI5UZ5W=?,VRFNOX$Z]ZW;9+>")[^PDS6O!*Z6"8I]`0W'ND`\V8N;_JK$ -M,*7(*K(3&R*/J-(FOS*?X_N870=$Z!J/3V#?/5`)8<^`JN(7.GH?RAE -M1)5E<;A#A5=A71=ZY0+RH7#A_9KW'^I((K -M8%].R18;.B,2@7'`2`@PPL=,U<-?(5F;.1:319LR_I`>=:#&,XV!%!!GU>J" -M4+T'IC/"BA@B@DD=U^X.$A/4:G="9T/VCF)W8YBQTR\K[#ZTAMK`6&*A6?*@ -M_G:$=0@Y*]&3XG&7@OI\YA@"XIZ1'E\,APBX0&1!QM'R*WXMW)=:RQ]XZ.'46#QM/L%JU7/Z8$L\/:#L1.N< -MS!P\%B2M[Y=D=R,N;9N#$$?JDT1RH$S!62MY*R88H'!P033W'DRK&H;;"S^? -MG`1&LV2Z#/FKN["((+[IH<*49''?>[C-$B1U)Z@BH;IA-?;$*1-8AU$"T20; -MR*U#[IO7/45MF[H)HN0'6WZ*U,4KXE"0\ZXO?'SX@ -MD6Z3"W*UH8AS%RVOL8>[UKCIO=0T39;XCA9/^1/Q30X! -M6PL=WVP?U9S<\2);0^-PWJ995I6>JJC0UU*!4G:-C#^#87.]0LD*59C$Y1G$ -MU=:RYD#K>IYMS**9_E]WDM+A*-5^=!#F+2Z(V%I#^T*"S=>%X"?$>.#+?+3C!I&ADEF1Z(CQ=\PY3SY>]NA/-B\/(3S$6J3:73MIG2"H*K] -M9LG1A1D"!)(?M`BI_`_P6;ZU0HS:GW^;=H?>[?]*+!V8A'#KP0MJ8.%KAUK* -MQZ%A/`BX;7>1&N5F`;0\DB0YOY+VFWY]LSX-M'C]KIV3GD.8262A.I*&5L,Z -M&+[,VWT\Y\M-,\XF!:<1+XUA9'"Q]BM/[EU?'\#;9SYP7<)$!!)2HMRU\*1A -M%YH<5+Q;X&`(;>EE(^AT?80WK(/X2;@$/$,:/C:VK*HW2UV&6RC4$8T0XZ1/ -M]K=]B9?^QTAC/8M3CZOER_,@O*F7"*TJC(&*5P?D";@$:_>[F,7P.R8FHO_K -MD,A)(/;OIXI^\*)QM,&MU9Y'=5!1`B6?HA]`4LB&?5 -M5%K($+Y067YQ-/3;@IS!^W\$UFBLY)+_H$G?`.0:'HPY:@-UP8^1$\LHH'/O -M5%Z\YA$H'6%C6DVW=HDBD:!7ED>CJ\*^E7<+OVU#)7>K<#[.2-#X="%YGCU*?,73^T@]GQI\"=Q@*C4>9J1VGG -M!="5QL>,@V^$%^G&>_XZ2LU^;!LHCOB$1MS[V8!6)8"-MDHSDANWJ122 -M$PCVKO-/H36'R=_=\`(>8:Z!/I[CY3E4I]JC7+DT%WWB:M45?`VS0\"0_;*V -M`4@B@^*?&"D%`-PI#[E.FZ=L/G@=P-?/,TQU6DPB;2I]D-^/,X!'TH:*PKM+ -M`QP>'O'^X?2K=@?U%Q%+,^UU?CT+00+.2O]M'EJ\!^$&D7-(8B.3_WWO.^#+ -M_-ERH78ZUTIQ1ABN@E#*,$7.S^DO9K0VOE1:F9W$0H$]12XU7I';LRUAK*A0 -M)^#&!=HQ)OO[/2,AM2@+3(;/^XG;"VJ>^AD\A;3\*L*I8?G`G[N2VN!C#U1! -M)`H;D09-Y,X?2C*T!$4GT7EB@8(@08K3S91Z;\]A2K@P&[PZM#DD#$86\2WB -M(Q&>'IDCW%%&'6>GY\[RJC@1Z8QEB!'A3)+N;._EP7+Y/2(7-;(,Z&Z_0GW` -M]VCA2LT""S>>A(N"&T6"\)H7*')=Y-^;G/![I0Z5]M#RX2BDSQ/OH?T@]S3/ -M0#Z88?VR0\3P=`FM0/BG]"!L`#/A=0E0MD5R?S5-VYEJ+[+T]-].3Z*>-#QN -M4N2_V!<,#W!EE1(D0+I.QU*3$Z6"L/,\V[LM6*S(6N:A)!@YD6!#%\4BB\\N*Y0N*F9DZ=DC-##BQ\SCQ\VS1W4"3RP -M13F`KPK7U:;:.1S/47/YC4U'2CV_=:]J'6,`15_PY6]$X"VRG#_?:_^^PV?P -MDN<7!L,0YY3H+*+BVT:!R:(_D5)K=]UW,@)D/,"FO=E;3;V>IZD@/:%I:S%H -M/J5Z\S1JWW=@P?OACH.YOV%ED2VYR-=>.GHFE6`X,_"WS"HU.4:J`HP.,N?* -M6#IR,7HI<\I#>3G.E+#[V&&/+IY4.4S>TPLT#IHM>1F",PAO%07HX6IRW+/7 -M&6$@Z'L.1Y`E?12IB4M86V3#$^^BW'O$4"DI?7^K%:LYRI][ -MERNJ$AGWT\>7*-ZI?.E5U97D!+0/I%KW/&5N\5`OSPCLF-Y&7`,DC^9"8[TK -M1Q":$2WRD34.7-&8[$N+RS'R]&NPNB`%"7D!RH?6PZ^_!Q]VC&[Y!%H3FRQT -M9>!NJ@0`)DROS%%=R5I7*'%P[Z)PY\%>B60X)"&#/KP&E]TTA\FL?@!-3Q,= -M!S"2?B;4V+@3@/:8PB=*[2+9+6#R5--?J9O5J69)F$J2.P'X);L.R,(DS*E) -MQ;^LU.RDE\I/-J92J4RAH;/.)$#M21<'C@!(J*5^3.6G@!YXO2U"W)X9L<>B -MJX'STE'\)ZL0W97VDH4%'92X-CV:`-/%9D\3*\G?5/3ICIB_D5A?Q=-(+]6N -M36!^[4;J8-2&_YI$^^3,P-'XQQ0.?&]2"@+D?D*`D8+![]?(N2YXJV-]Y08V -M>'[=BI+,]XLO6C:2(Y&9?='388SI&IMJM@E%$B1\9BNAEF6NR]`$O]'04+-7YM+HD[YL$25)Q!FA)XOXJ,4Y_3%FA\ -M//&:\G?1PAM!]L-22)#)8@CY>KH4ATXZR?=S`%B+F!3Z$V1-DUN'5!3\Y30% -MT?>OG\&UB^:I^?5O42N\B2V^FY:P@[<0\JD`EDW7O2V.1./=9LV?Z3DG_#Y0SS""E$'#QG*=+C[MP.42@NE8\7>FP`.GOG\F=N(&4K -M!+M[&FYGZ'"R8N#*"FHID-R$.Y;98J_(42O;DBMMCQMH,NF,[\Y* -M:$[*7WF,:'X,F05(T2@I.IUTA#!WX_D"=H:$^]ILE9Q#8CW0D1]^[0(8\8UF -M__<6*LJ0$GL+OVI9U,ZU@9%Z(O;52,H*U0?O),275=J=9")?B20ZZOX$9?_H -M3-%/U5$,$-"-_Z((U.1J`QY;8Q@\<4IOP[D:A5<2AW#FJXSQH5X$RL+DQF]^$8KZAEPUBU',`7M^L;WQ-72,. -MX9GZ/G&3Q9X5%QV^`@D6@+HQ_&W"B`X4+DX*)._9?]N4)G<_FBD&/)&8&\L^ -MU(#0Y,@(+B:*2;A?&5/FD70Z//4&9WT=P)P80J<`^=3Y`QT`1?X(^K!#>Q5L -MDR&XU1>#A3(2W9XD\L-"L,LBUGT-(P%7$WZYRA+.P%A"=;1S-1JZ5GX8*[SF -M>0'.A+SS]?J3>.S6*,&QN7V'CVLF<5F7 -MJRJID6V\D!&R)E*8T_M,XVO%699\!Z28HFN9;4:S)NEZ*63W1=`",$1P2+EF:(NYYR5![N5IG5K,)C -MKX77>`YR*UA:RCQU*.G_IHE&!]>-HDV=2?"/@FO<8M9%QXOLG2R\^Z6Q7W$( -M"C26N?Q__O]Q>:#(IL553#L55M,-G$U&\5\>(++AM/0W=2NBUQ_EW*52I%[, -M^\@PW/QIQ66FGSS9XW?15JT>!;0`;);"FE)'1Z_3K!TYW77BNZ@GWTG.,GN8 -MY8$$*&E+PV;<,@EXE.8S%W@R\$7D8M:_L_4`4S4JRN-8NS>V/`)MQ`4BVLM> -MI6I@`?2=9*L1!B7OFY#2MC4O(3G+Z2Z!?:F9X@ABR?V$!ID`0+5NY,H_@="Q\,+!.6JR5X?2T+K.C88<9D -MK!M$N%DJ9LCYW"\7'\VNP(,0'>6;Q0'?8J8DAAL!W-^=1L.OV=3`ZL!E90,` -M:C=ABBMBN>![5UMKO>`;`-=?%;+`I/G(@]"8I^X6Q:WA(^G2,#(CECF)?>=> -M6G+@IG78Z?=G%_]KU[-7D+27EVE=]AK/<`'@@`@(NUB3LNG$;*!Y6TP8D`;\ -M>H_=#2TJC*G38GWI/MTO%9/FZL6%LT*-U+XMZMR?GOLJ9RD!TM8I^LEE#)9[ -MM%`E02.`;FZN!XY:*LJ.5TZN>`+XE`M7[R>&HD_LGA."V70R?2.Z#L9KG;^@ -M"B+)$]C6Q4=IWO49Y)%S.^-Y[^DV2B'$UUW^EES$CW:U+?X@&P'L#P=A#1() -M-+1(77MU.R783802`;$*!_[M?+&24WZN5A!4%&\?-_I8>(46K3SG"C8+C/9_ -MX&?1O]?)ZOU`QQ-C6(C<^@ZC6LI)G5EQ,C]/!]"Q]/:7[NZE\&=F//$W:@I/ -M$?._D,ZV*]Y!C#C[$V.,HF%>9S!8Q1=FA9F))_CH@+M'_^DA&L_Q#N^] -M8$X?^WTEZ>U8VQZQ$[?9XR%=8WQ[!_C'2O998O*R]4JZK4ZEKUM?FQ3?[SDL -MQ+:6,K+(;0M^^Y0"H%9S1\?+9-/TQ@L%VED^Y%Q<^RK4\]B,B"[1IT>^9=!) -M,01X8`/&_AH]?13'W@EJ@GS7FQ7X8KM>4>29J*"_]H?\K7,L[O=,&ZHN4+'R -MI7)PS>1>`^I[/NM`FP4&J*71]R_F-2\A"J^P#;%Y>)Q66@_@:KJ@F@[6,H''5=3HD\]LF:B(EY58Y`UZJFM4*-&'=Z9`C>KG`M -M_Z4QC;'#;'>HB=+SWZLWBO%0M6[X/@OKK:TFT&TJBK*$U,TCD*9DSO -M/77-'R"Q#7-*PD/M="BV<\KX(5R9^-',9X`EKSYMF$JXTJ7:JD?BHV>GV3-VD!D,_9YD0E+H[3)P=SZ]M24(M*>+@3R-S0B)X?H9QQL0V21!7_M9:A -MSR2@JF';1^8T5)/>AWK.J^]'I]I0A7\2N>`"QJZ'0>/'/:];UMJR1N2&\$/^ -M'*52.M%OI=_39ZP(:V4ZVV#*N]/>V/71(LIFV>33FK:::TS93$2,PI$?S183 -M*6E^*K>RE@6"FEBOCC!HU,1_E=7":\/LT/5'V??#"B.C>>L_X6*E,QJG_R-3 -MG4&J[>BC53)2\_PP/\653-CIES$["5."2DA41;=M5I6,'VCU,K;#^4(;H6)6 -MY@>&J'VIX'MCN,[4?1PQ5C`+U1P%T7-R=690/H&[)5&WN+0PO&WM0+PKVK!D -M1\SW\%%87*TW89Y::!=H`VW[KQNKTG]_9H[`-O\Y!VPG+2P/;]I1+Y-=P]:' -MDFM!.\6-[+;B,4RSXC>*]D-%S/4NF:[)(Z\N)V1OG=/V=0PZX:S%BYT\+HE` -M;>1&A;"H9$.U805*G/[YC_6]']!D:WB4$'OHE%?R5M6F756M=*=IWW0YU2-W -MCLV"L0P-M:;`-NO((.]$EU\I*C;.@I@:]`W#T5/2<3%A-XVD],D!T/(LKV1R -M._+'?0=#?(X"INLHWE%_\7?G/NB,?K+["_3;8:#W8Y->&,@IF'_X9:('.%09 -MN8-L+LF*P%\AF1M>%>9=!.CN?P+9D"$X/9Z((D`T)]?[J<`<,S$2]F?ZJ4H8 -MKCG2UW89F8M4%4-L/8.^GG&]KX0__>[@`&NBZ3"9_S36BY$-)4U_GZ@J08B/ -MPN;T["LV1K:,!`3C_!9%8EQT%"V^+T.VASJJ"*[1^,D7MY0Z0E,\4?N^+_RG -MHA;/@087RE@?GP5X$A[[+&U/S+_,L##XWO"@]XO_^@DJTK$NBC!;-Q0L(:^^ -M`J>$X1^F5"2&ZB!@6'\#;"-,'ACZ:^Z(QVY+L*?#\L26-7:BXKT4S -MJUIBZ)RUU2T>/45,_Z!6;Q^#>*7@N2$H`#B=1VE)K*>>R`EUC]S3:\A9EE8% -MP$(?5CUQ.]ZC:BZ,?IC4`DSB/8^2DKD'4`G$#BU@K>;EI*H%;IP8>?0V&UCSE3:$3*84F()3\QNT)0&]F!0:.L?A5L-JU-*6@6TIAO-%]D9T+2C8Q -M:K=&:1L\K#O4(_ -M-MOB'O'W"1CO[XE!MO\$:*_[G$,CJ(>8%+:!.5>AY,J'WG%GO\(%F]\*BJ9* -M;8EQK8VG+#KU4$[7:^';?ZVE&/#8KFXKW4JJB`?IET8*+]MY3_6::D0D#%0V -M:DH*>`B^RR49'`&?*:B!U52=,O6_]IUYCEZ5*>\AY*._0:*6!HI%-2V952EG -M[#J8QS_=0[QMP$B30(\%9#"L,][W3-2B?UWZ3@N$1&$"9:O4W9CA8XG-+"?D -M=X0T2D-GCK/K@:JDS[;!,[R.J!NMT+6B^;B*P0CQDG3' -M]"[#O?I]9WNDX8`BJHYOP6,2#G$+0-JMTF5DHFN[>TU,2U'2*(O1@@>DSHG, -MEHQ6J<.G:[Y&J8#0!?'`Y_'L4%+"%%4ZS&MM[L><19QL1G=<^@`:V2/$W7,I]F8X.?:KC"1U%LJ])TUP$+SQ_%59 -M`3Y6A!8NO7E/U\>F0NXXSA+8CP$?&??9SQ.RZ8XA.(2>;].%?JPL_;;'&V`B -MJ]D@$^T$)*4$_#FU:V70!L;.B;I;^XN<#B*0$6&>X3&%\IZMMIP1RT>?>_Z$ -M,+#I\>3L>&]8&,Q;^KZDQSGWL)8*P=9TO=.4.['K#NE['':-Z=XL@F3:$&B; -M#BF\!2F+.J]BT$6"Q1D@&U1)1ZR!NVZQF3H]&'G1].G -M4%Q>Y-M!-10?1W<6XC:U59VT_NO>L'";_T!1#(H_Q/;3>I!8R"REXJF`0N65U'/Z+9 -M%NJTJXXSJ8?B0:)E5Q'UO/+UAQ9";-<9W/]YQT6,//3IWZLSQM;(>+_P=&EM -MCBA88U2IV=15?@!\-C)@P[DI(V9Q&WG7>096'Q&JU&@IHA]SG5GI2^K -MM*XC_J<^-H:'D#4M:6B&<$$TQ%`Q5^'1"ZRJ19UE7)/%8Z5*/'60\+QY[6(# -MZ[O>-3\AVSH)9-]VP_>0[V>9%W';\[?=)S-@>2Y=;)G\_$)WOT9TL+\QEP'% -MTF"YSGUO?]K?%CCY07#>IRX5'$3#,T>"'13K'[1.M)&CD1A)X>0,[[),D -M\6%DD&*IV.+@J*?;;*L[O2DPR*]#]X/=]J5R`Z]8F58N[Z71G/4I2M'#$0:# -MONK(D772G$,!/]L1D5&?4@:T9E:RM3ILH)4X&ZC#_[\(*LO)KQ]I0I45$];! -MW.Y?\`GTY,'RR67@'F9RVR=RLYYQ"RTTEU8X]+7&T$6;8U/W-?@D$GLV>N(D -MQ`CJABN!EO#+O-6OW6UGV+EG]!?0A4AB0&3UIZ\]X>,R+(K@?U.1I0TP4!?; -MF?5NX`S`[B1#K_M,Y?93O\!++E6X9VEN5.R(R,8W*3?/(1K,)/OT\BS+?G1!)]4<- -MG44"FVW;J?,@:L7ZH"/5,G:D)B];>RU*//STWF!;SS>,^>T7 -M^6--0\I38VP.STM`=YL3X:$)&,[)2SIT`=39J4ISBF5+Z2R=E[.F^1QG]#VF -M&/'RE$(M.CB&J\^0U$1J"1Q9#-13)01D+J:PP02ZL02T)2BEG'2J -M'M_)P2)I+8KS^LXYEHY?J/#@!4>+C7X%*1XR-7/4AN.T9PV)3KEMKMY]\B?J -M5)3\!:)#C*4AV9J_HN\!#(!@CUVQ8*XY38+T'EGEJEO1!04XL=N,E2TEFC0Y -M(S*U@XV$M7%2=&?'7X\1?/RCNHI++/3/Y"R^49"A.?L9?]TS_-#2DL39NN[W -M!=YJV42AQ"9E:5SZ46;B2!(!*)8?_W.[`CD(.&(,_4V>>4[\#<\SF8#L87QP -M_M,!F'0ITXC?)T]S)#:C6 -M:^G,J-K8C>C;,&KXSF3^\3_Z.]7_CS*&E$5Y&\6(,/[#N;1PW'^WU0B<]D@< -MDW7H\I>Q&2#'#B_,"B&;#%\7K-B.X7+-.IXWU-8!T2MLT6$HDBMM.396;$!C -M`(VOE./04,JBTDW"C*4>KXWD2.$WOAT9J+%D`0B^*YY^*)E#R6J_Z:O6V/6**8&"S`(O>1G -MVES!9?<_R@Z>C.0P#+2I%@&\63%S3J -M#6&/_`/IPC!29*I';=TU6_7`U%+*=V[_?K?`#^E.1!'.J(E37I7.=Q*LU7F( -MR:^V`"G,(_BXX<"&>1N!YP#7#[E2N19GW -M62/RS``+ER+"566$P>3AL,$.QQEVY1# -M6.X(/`Q_C">V3MJLW,TW&VV3,HDO_F6@KW8=(/57$CZ=:N(EM#G:;BJTXQ%' -M6N9+;NJ1^8W(19'NX9\BKZRN)25B"JA,B5+)Q$"4['88]R25Q-L\KZ8+(MM$ -M*RD'/P)@9I"G+5^(J5$:A!LRJ]K893H,EVYC>OKCXB17;`MVWQS)0D*">/R+ -M4_Q>+HYKH=="@,F$2'K\-U]B3U)[!MTZ3:6+T[@S5OIE#0'>3#H8@@?T*(F+ -MD5!@]8D?%T-JC_Q8JA0!G;7I3E\67*@>8,",Q#5$N6$)#I+(O8)>"SXC^;1: -M**W:R*[/0O[;]2H<41"PG7&<-[F9#HF,!Q97LQE&D4YMC3A[KJF@GW+LYGW,TB!Z6]QP9IZCAQ5 -M-?J1.)I!VA0S4.I#FR5N6Q/<PU[BXK?F -MYR=51C<6::M)*OB>.771V#Q#;@R>C+3L*O2!>,>[R$#C -M`0\]JH-MPE55PR2\?ACHJF:V35;W67'=I'XKU5N-H3J=RY(";'\EU8:&<[/B -M=`0V`Z1#$F(Z+&<;353)A=>S-XZ]:W:&Z5<_L>QN2FPH3J7B"+1'6KVNF/]/ -M*^U:=,IPY1YX0FW:>1G"1.T26>)\0:ODZM+@&<:=/&T\="WY -MU0N(44J/"O7!K";2>\-',2B7?L%<6-Y?R!;`D[& -M.1($4M%`BWP94>G4<7D'?^E^1O8=/?[@$DT0?OE`R<^A(L^@_)P%+J0&!E<[ -M*P*F&27V'(U(/Y.:^:AP.*ZG`7+(YJB007$F?!<)J*V.,5=MS,[UU)4O?X8]_/*:H3VJT -M]:BC%BM0?CLB>)JSA4U?25]T]Q(@GSX[`N!X7H/RS%/GY_JM4E7(;A,1(=-- -M)&7D[^S@-:K$#M40HU8Q+F)^Z`HK^G8BN.^GX_UH@@U88RWMLP\?;RDZ7=DO -M"YC(P5AE/;2XKI8!_Q:/IAD"X(&%1WEDV![]@F&W]43;?`&L.PO@\5K$-IWC -MUSO"+,EX/WT52>L_*05X)LR,UX61N$1I.^JS" -M*/+ZE8/SA>ZK9Z:"UR?FV?U,1+DVTZLXLT`CZ="&M1#F?W\GKS:[%_694O-M -MJ'6I(A3=.])YBV,[.Q@U_0PESF@$`:'--7[>,*QCZV?IA81`[>6W@RSC67P# -M#A=SKT'HA<+0@BX26)`"-591(@=NG*4K.D%CR+;S[GZ2""M>G[]IW.NHZ9S$2=@_[K7"LT1;3&O -MUF/0&L$M+"\V,M&T&,D#%)?YL::@[2MCZQ-_Y)%Z9.OA?WC:8HJ!:6,,;S&B -MG"K/O3=0KC/A]&!BE5)1K+`54KH!.2R5\[X%%@X/I.5`&!O,2-L$!CLW*=IZ -M.8[:WM;_U0%`KF(Q7!!4$]CH`M3'DM^-"JI@PX(UA92@SJNLJ:47I4E>XJR2 -MX"HS`Q=@N]#"SR+Z<#D`TG$T`>'GM/,LOAS&S>$%NGN%*@N\+-+BN,05'!=^ -MK2_M0O=0S5E`5Q6"YZ\Y78D7''+<_1FM3$)+8F1>35NZT\A&D-LNCW(QISC%8F.&`2/%3S4)R`)Z$S.597>W!.RWU!6 -M"^L?8.&*;K7^[)+IYS1',_Q@`SN^ZF3T->2UMD!W4B5F` -M_\WKDP;(EH<(]`\C"1=HN/S@M[B6+U:ISW8TD49+IZ?#"_C0ZPLL]@>:Z:FL]']7%+3^[#ZR -MN4[$HK'F.+T8$J0$QB<[Y@L.0[R$"/24X2@FV""PU/MHVAE=\K]*9+QPO=H, -M?Q?+8:^C]7MMOXCR\B,6B5SS00\DUF98QM@YU'[6N-&HID^,L!:B2`DU4..5 -M%&3*`ITZJ2T5O1]LH;/($Z"J`U3:G% -M;IUS@_W($5'!AB=1>HB514TL3ZS=/YLA<;U=V`8?,!-KQ#D< -MD*R#;+_S\Y]*_L&Y34!V*F[>V>;EFF&'<[JM7#][00H_L,^";+ -M`>87<-/5(+.9-X08J#5P_05RQTM':<@A\ZH\)+0Z![0<9K^UG14A??!?'=9O -M@F&PUA3_->C/!K+=T9&-'Y3@'6Y@_/M3+>B&&K#\%:6DT_DOO,PC6.?72OA$ -M+:8EXW!,%@Y&L#N>Q?-I5(#^+BW#)8=D*B5=4+ -M:")8#SZSS-26Z^?7KDHY8&ZL?SOMBW6T^W"+9&]`L@?ML32F6.UR1?<@Y1-Y -MRD::GLVXW69GN^W+\E[#7CNCGU5$V[+G8@008K#H$!8_\F")NM]T`,?U>N+C -M03BL)6*C0=UW/J$K":7Z==G8;.D -M*@NE\:2&WS#<8;%(4GGZH3V.>T$$-;:F%;(6LH89.0<:?7[=C"S*%4>4_'"M -MGE*0+:QL#!C=KF9`#`PND`X/%>7&>)&*4B!XL=!GWI*)90LP\2K!]3-7F^;+ -M%_TJS>E3HKDVUF-^[9FJ\%9IY.SS#I!OIR9F/X8:3S?@JBR/[XS)[?B,&\A: -M[=(_FJ#.JX5W4S?2T?1H`6LG[!14-OQ!4AH;S^AU^ -M)VMZ1"RCSY7@I^F`-ND"DHQ\:Q;VP$H_:@V%CH:(02M3L@!]@VH:64?RS0./ -MNN3K[TT>;7&Q"C+5O#+@Y<))S6G4R1M0-%69;#+;&9.@F_Y-ZU^ZV3T7;T9W -MGV7;D\.4,7;Z,!ZWA54:UP<]"V!LA5=JH3XUZD=7:E+6ZYS"\KE$HZPXE@MX -MT-,L0`6YL8^_R\=MF`-&1G]F+3&<]:`<1M>VL<)AP[#D3@_>G:KO>_CM[6Q\ -M_QE3G8@)//P7GA0G;H.OP:1?R=^'0-"63ZT>C]P':@X7BO]1QS%M_!(<87[* -M,7QM-34\Q9Z3GG;?GQ_AYI)528T4`-(WC,JZ4]2:JB?:WRLY;8.'O7-JN4+& -MR"!7;E`JTXL)`O\JF)7ZLB_ESUJX>HICUHS2T*"^H;JQ0F*+6;:7\H*Y;*+1 -M,\S[)7N2Y<4-Y7!6:1RMJI=P+K>][B>:<@(]$VO2M]**(92)![DCT73L973D -M^C>;"I(=XLH?BJU^[GI&%M!.[Y$\"`!PJZA-:F\N@:ZU5;JGOFRL2(A[AD0P -MZ3JDH0?H`3WYRF;7#R4T#FUF#2_9(!W*89-?3>V4@DHQHR`UE-=WIE92#@;8 -M2O%*X_^AC([&]115%:C5_A?^N\-[6-K'V.VWP(R>GX=.)==B4.,+6TOPK0'F -M+E>$5RN#@2_6(Y[;8;ZKY@Y_IV'*4[XJN^($)L]\9\-4&3Z -M4Z`SVEEI&F^':5-?4:^)#?]B)7/]ZO**2^U -M@_&L^<_F8F!!"X1TMP=/IW_U91P:L?]ER*IQ)(H^_<4AY<'PJ,V&0NSE8@>WK)(N>73_FW_J`8OT,K49U:58*MHJ4XW,_@X9:M^ -M0G"#AU^%2-">I.BX19[:D*"V*]!73AU02CY49KY4C%DOM!2_GX=Y@D5YW"R\ -M%*+_(]H[R13+#\!A[QUL9%"&Y-*GY\[OJF(2+>YX+&O-IY$\99[/\DCQ8TS+ -M/<6!6>:^2I$JK-J;F'"G'N^P!6(1,;JH+(X>U&Y`Z#NX]'D)K)-W5QC!30]6 -M2!O?C<6FD\N[])9VGJ,"N(5+O6H^>])G16:N,^$_"8EP)7U0#HCQ'-]Y,+JY -MX)(ZYQ<7\+7VU!B0E&]:?7D+ZW!H=1)RH;(ECG6Z58AU%.SX3\@SS+T -M/!$_D6HBV^R,6=$#[YT09DY6Z#=O -M8?KL&CT2R%B5O?1..65JS<+*C=;9UYLTD9G0)W,_WRF!73#GAH5*HU'?ALP( -M8A-P0F'-`IT;4LY!!*[4YV:?C]XV'2Q__Y,**.8CX3S3"A2@,V/FO61$$:/@;+D@:5:-4)O9!_L[Q9VTH*]E"4"0G=(S,W:+H1CQKD!O$NG1XH%R+EY^>T]@EQQPXE -M_K2$]1@6&1&3WE#C09)J@:Z^0KX!&P/4=!)#)P&D39*";JIDT`2AV9N8&Q89 -M.I$U)?0^Y)P;QTKP_6,W^D=>4D`9,>O[!YA:83.KEUZWH).-#16^^P6I+56% -M)XI-H-8$Z##3\2)F2E+MC02HQRZQU)D]/RJ:((4@!4.5D"Y-U[)`W8?%9-I?NY/^$0(%'--O\6N+/\FW -MZ@O;VR7219-;P``.(DT.M`,E^A+$':`/PN)'4ML,>"!W -M;`P_A:A!MD$@=8IF44J&>1;.T8'JD]9YM6Z+D!8_U#`_`L"XWB0ZD6%+6>2M -MF>;+]G-0OP,!+24F+O@K\83V6,40^_GK)#*Z_X:`9E5O2QLIJ^ITDY6FM*8+4`:5PGB#$RVFYQM3<4PAB-#R!% -M"*^C)"\?2FRK+O980"PTO4C`;LZ?%L'ZZX!2^X$_711?D],"T":V$6\/#YY -MW"UJQ2U!DUA"/Q!6.UT2Y%7EH<+--SPF%:N^K>9H)OK?7_#K3MQ`YG18P*5TH>^EJ_D=Q6%*1N=T^_N_6!3*A5)F3P`DM]P">L\#F:(4]AG/7\L? -MLO>J*Z.T3(:6PS%\61O%=Q-^LP$[GSRWLY$I\5ZS;(<%&=6=J)F,!%FH*QGM2+FJ^PG%!' -MGN20K"!&8>-]EAM/)%5SO;IK9\&WJ4\-KP#JHZ&@231SFR.W21R^,Z&)2ZHA -M+-VF)JO$L-N)+>O1=*S@W6ZZ\0#`!^GG.I;,QUF^S8*U0\A.[GU6E*9_[Q#C -M3^1B?C?*L8X)*[1&BEQWH/<%EAO2<]-!Q3++0_6ZVA\FO@AR -MI90Z$*1_BFBL+$762%4JGQO#3)/ZX9F_"3P3MTBF^@N-)])4`=>N]R/-GS:- -M(\F2LX.[(*^OA:IB=5R!P?W93N>B3U+/[4X*%6\X"K^^NMOP(^UM`GX27_8N -M<7\)"E`ISI13$CSM87)]ZJ7%KF^:=+@+K@R"4T9&;]JT/8*JKE=[!/@_!%L2 -M7/$#8^KAT%"O10E6?FBY^)DODJ;T+5"Y_TOZ*RU54M$*YYHP7 -M2^&@"LJ]9'(D9NT"YR+&!,R`X-@T/Y7!3AOLE0^X?C*`Z9FG_O;JZV53Z5?$ -M^>HTXJ+0GJM#Z4$$L?0"/P`:=)L6J5_]CROQ1M$+_-<\)@I@]6-W\%XA(M/C -MU(F3$T7ST\NL)&=OEBAQSF@IJ5Y^S)T?.G\65#<$B*<"##;:V;F13-8I36MP -M&5_--EOFJRIVM_>U;5#*:AX9YRW`9CN!9WE^^P(>4R-H?$"%$N^=R5D305UO -MA#2=(=E'%RWGJ,"7"5Q*P#G#9><8M$'^9%C=V40[QO0[97X/T3'5,&@Q3ZW( -M1>_7`]&0]=C%JEQ^[FX0&P&=_66CY(6H'E6NZD?LI&)*.H`^$DAVU=H=:O)? -M9SK&ZRIQ[9+HC\-=_\CP[\U;[`/2`9K(Z -MJ\,^1(?0,@/_8]QB`HG1E].+#XC=!5NMJ9F3FL-)($Z&5R!$;8IOF22<&85[EB'/LX&$7^>EP;X+09EGJ(-"$O1-^]$-Z$QT -MY<^KLHB#70"$IK),ZNN&4>2LS8AP!@9R\'D.3Y+^[DD%@]UXX%\F9UO6+6O= -MF]`A8B32VR+2,-S33G -MC=;Y6]S`@8C/62QF1D8[8&XAB6F]?DC>%[;6!S!3)_(H+W'F)]OV\%4>=7L" -MEB!CH:VJ0B+F6&B]@!YR'@LF34-ZP)ELK?H=9*9;:8I`L*(62305$7RO+#D" -MCVNK`+M1:9I.1Q(U2=%"T3UC^Z4QH;8!;W#">/@/"&,9UI2)O@+5M!1`C5V? -MQ6"[HC57E((1(<3_FHH44D!I8"1#EP`]7[KP9B+5?+$%RL..MT#ELQ)$%6C_ -MM)Z*B@N8)F-F-2;!Q$X[N:-1N&L3T)%]7!5.<("?WPI;;H]^T*=UER%Q-"?N -MV)1]ZP55R2D>"5.7*<0IA>.`4K>5"3X*MN?;<20.$-WA*#CU"6[W=N^CII_T -MO^N/I%51DG9H=6]>?]F"__ON;G>_=T=Z&/RR$P@LW&UDOSS9DQ/!*3U@6)(. -MW&D`[/*J2MXN[5V8OD9-Q),P7%V$\RBNEY.V*L>YYIT94JR/V^C-E,".F^9A -M_SS(Q"WX>]8Z][55K$U>$NK:8\4O*5BR7$8^="[^E`]PF-LK:-5=F)KML^XZ -M*Z;HN\^T)I-XK$CG3>R8?T+5BQ'>M9T'=/N43KD>G;QD:Q1F:KK.6CF@KS/V -M>=VX']+TW#I!PZP+!L8N`T0-WSS?PK\(<=\>/*4MJ$D1N=)N]A&0)>' -M@T4R)VSOY`P,3F,7ALFAT*(&OT?++9W -M/6]0O/=^;\LV4:L]MM6%!>2XTNG%6P@,X;S_;*4L.>@&:JE(<.D&33L77^,X -MX9HLZ9";K">%"..,>W&?[?@`MF>X"5%5/-7:Y<=4MD;T`S?CV;Z,&4NBP*^S9[N;M$ZE&>%6L]]('=5Q37W!;U2::J@ -M%-0Q::/*XIA1#J7^H[8=L#D3JD.MKQ%&+?E69M_!E&_0P5G?F!K'/F?@`\GF -MN_$-:RB-H5SG/M-)W\%P_Q"P#,?>9C@UZ*L\I!N2Q:6"SU4(1-IX_G6/8??` -M]1[9(F]DM\58@']7_NB]A2"6=,C&INSXTC;2'7T4B'M:_,!='WE]D*OK28T> -MQBK&4'*!L9,ZS$`,SW8AT8X'!8^<5#%(RXD0+5SJTB&>K0C5R=TTU][U-ORC -M3Q5Z2K)OA1*^C(,LC/6=24RIZ-5A/]EJB5>_UM?PM/&4-)RYZA85EH8;*R=` -MK*A"T-RH'4PB>Z=5[+^HT020E?]AS!1S"\I9L(SMF;G'Q;8];+QH[`W(OYZCX^:/[FJA$@7 -M0DNV:7/2!4^WLHFM=Y8RU@OGNM6PF=T3:FH!,$^?\,)Z!;C]M356?_ZON\^0 -MEI_/ZT!*FB+FK_@3CWGOI0%AR6-]A892PKA5\GNE?6A=5-*=WZGWK;V&$#.0 -M&&O<\':[M)T(IDD,)ES%AE0]H^T^5-7&OW3?54>BEO$IK[:*P=!X&1`*U4CZ -M`?6L!"U<&2&.]!>G:GSF=Z@`?4E-\(36U%$ZYR24HHH`;11IIT)PFF=(GL)]HHJZYG&`B/%D!N)EX^ -MGYI^/\ZYS`)(;SI:3P]_N21:-`&)#C4+?#&M?XRW@_^#NU"DTK&KIZ]@=ZD;V5PAJTS:Y-!^&6J"WK(_!C'2]!.Z/N$_GVS>KW/59/(Q8_+XJ)T7!5BCGNP_S;>#)J"9_VCT$+GAR)?:MFUEPWX)L+WEKRWUW)NC -MC@LD>;\">Z?..%'CBT4?P4(XA+K_[J1;][1$[:@^/ZL$.KSD"'QTHA-PM,S0 -MP1,DF&R@U$:2,%Z7]3=@T+CA'+L*-IA0=#8ORK$U1QJWTB*0'G`\%.[%+H]0 -M4RZZ9'[D%^,I`=@5"'0HJLNK\38W2_W9]4E.2`KY"F;%("_56G5EM5H=;UM( -M8%X:3:N321$:O@!/P)05'BV_90L:E4Y7]5W0ZX/35/B:L$,Z'M^_BMV+;X': -M>)&>\%B\N.N&*B6'_UP76'+"K??%6_8.`5LE?ZZ;,17-J5G:$R.<"=]+8E80 -M[["*MV.1IHGF/-[.&R:*Y4#`]KD%QCC^@\0:$1U@6[L0/]890=JG$A4#<$YX -MV<*@:V0;]0[S(^\<@^BR4G_C/_.`E&_EUGY3MT3S:2E?0773M#-3RANY*X-3 -M^PT\"&31H@8YWRW66EUR4DL>IT.=<(A1U"8X@?K6\T65ZN[#JL`S\?$>!O@A -MMW/6:`L$J>+KX(#(\;OE_421U1!`(R&'45WWZ,%R88\`:>,&[$\N@W8$L/E' -MZO!/D!4"`C5MUR?=&W#B/^$H&W8](HL@ZILJLG=<_TSCQCX8@/SD]TJV:=,X -MG`!*:7LS4Z\RFOMB;`UT] -MZH4IMP@,UD`?AS-F:`:]`WO--!(5K+U2YJKA_"#4I/K.JV_H9B+2,I??9RZI_L\8^=RP7);&G;J_YA5 -MC$+["FV92JK0NF[V0<')=DGB!,)M1+56C4)P>Z;>C+I -M+LP17YH6Y">[O^N(82U3"8*DDG^K'MQ!FJ>;/%WHOR2;>9'H&-K9]TQ`I[T< -MT:*W^$-9D8^^Z.P;I;>+H;/BQ*EI&]QWKYH1W87]SBVM>-">J_#U5\&Q([*UI3, -M69>$T!E\`>$B99JV_;79&<")I7+6#!%V52L%/!LX[UKSX=M:3Z&^:WD-\_S` -MQ$O2?:-\`R`;`1X5_RX^IH7M;@"02 -MS7NO.)8THMW`#<<&(6#FBL?043M<`.\O)PK5A>:YP5F__'XN$&C6JP%MX,`? -M=J\%%<>SJDO9);N%6AVSCZN'8DS#"%A%`4J]_HFN6SJ6G>\"*N>,WZE1 -MW9X;M[?;&A=R",V;0B\YC$[EFB2.1^*?\_37&03HF=A/PVHB]6!7&4WKU$2\ -M>=+B8L>K0I?'@_E>]-#S/N\3QHQUN`[:MTT.LW;H1F5C\U9_43`+Z`+MB;V] -M>Y!&:]6/^(IEHZS$[R;3B>\$72V$YM'`VE6^U\&>2GT-O:W]S_0,)Y,N^)^\ -M$&M-]QT]BK$MW.P1F!C,,`68$,+JB!:IWR\?P7A0%$CJ0^!JN@,7_FZ$V@'6 -MS^4U']Q"$#+"IQPO[=U#M`;L82X.RUFXV`==X>?EXJ"P[XK7>^8).9[\$W4B -M5^"4OK%S>+%\UZV)ZX]865PU?Z%O+PHCXNC"=-](43HEZ1V'4<@7JU["7=ZV -MQ<438A!XS4VE]DMX>Y>IU]T1(ANLRR1W^Y#3%"1Q1?BJ="_=HMMBI/Q5)U177G&K -M7#4C5PAGLO7,7+B?:P#7#R__*QVS%8Y\"1SJ`5U=1(^;CK/27\U`33W%D#K5 -ME8GEC?'X>?Y0GN"'.6MR8B)[*AML4Q,*?3)U+M3T5;!B+>,$?=,2.D4DI6:! -MXX!DN]9Q_.)2GD4W&4ZN>VAT-T3&]GTE/NZ=L,I[V%M,:]#GI=#N5&Z.C#AR -M759J#;X(ROC96'U):42A,^Q5TX;7"!&@=$W"A9Q]2NWWV5Q/*(Q98$2<6,YJ -M3VZE`WZ4/'15V_8QQY5XS<"\I8-A"`J^05T\WW9&MACY,?C7'-*``;84;"Q8 -M1^^:Y`^OGFHZ5A2T3>4EV>6C_2&-108LLP^8]/>I#P2BK,KQE$<-Q"AW?>VO -MA;I(`:=885:U50YZB#N,VQE[U4E.]J4DYPU8DLX%+G>^<>"RXFF45\5%:^ -MC55Q6+O\Y!2"]5IE&,XIVY<04P?[NECMV-N/#Y:8SL)WB6FJDI&U;%;3(^/T -M>R='0B7W)+Q"KP*L:Y$B3U]:ZG>I[\]B\#D+>BHX#H>VCT[P*"OGKQVBC"UO -M0GDDX0=_;SC$9TQA\MGX",, -M8MV%3N[X(K%LA7R[CY1?G`IX)L+([A8[:]NXBWBL)\!*;<*:+5:(^%`99D5; -MVKFPLVN$/&<=WI%P;D#G*EYQ.NVX6(!@-]DC*-BM^NZ$"6\M_D^YJ3".HC`H -MP>?@D\]36[/R7VLU+ND(1M*&GP?A:L3_>XG<,U6&R(0K:\/K"6N8+(S9%4CB -ME0=)5G_>I+R&&INY@6;P-_W%UQ!;U+9@(1#L,8\I?,?XM22#TR8QBD[7@%&F -MH,<6?_@%(J`-U>CTC?=X2Z.`F_'D77H<=LY.`03[0)MJ5FAM>*C;,]`O-W0[ -M-JS:*6GKTX=#.<;5W_^[[-'?X@OY]9?901&!?R2L)Y)Z/Z-P%'NIW:N]K27F -M\](Z?TC/FB319NJFL'`6_)SP\,RV35T;S*)`5VZ4]71#.2LA4CVMHG%5S3QE -M8[HI[Q\UGFBM?1AY1L_OZ\$"VK@$>5Y3R@_S8+H=]+5\>AZG#S?XZ]GUJ;+V -MY_"4%HUWAA&*M2"TN$Z.:7/Z_"\U[&U>)_!-MNRXR]N"2E[Q&F%\LUOK1')W -M\Y^E7=M\W_A54LR\:']+&O$@)_SN4=+EDH\(A9$_-4]?INI=-(AQ@C>-!W:J4-;/.2`<>M;9':<>\&AAE"#YX&^WYD@ -M<@0%9LCW]H^'6L=N<`7M8:MH6_*QE[^GJ#)45=B![+52&=,K=;4DR*6_AOTD -MY]UNJJH)4#TX%0*:8RKXV'&$G^>XVGC2?DVEW?['^E5@7G:"M82]"^\\C!"# -M-ZZ("'B^C2,H3"DKHX'N=7JG;NP7E%GQUVXKZQT)'6QB%\K0SFKT./KP%6LC -M@+[UZ/H2X/]#!K[\WV9'X8_I3OL&$LYSO$R>9"OSJ/'RU(2`:S\`]UMO][;8+:#@F^X$9QV_$\K*/J;NP]"NNI##"-8"]^/POT -M*7_!;-&4A`P;_%N=G:@80^QO,'[>0/]\/H#J:FH`WQ+H3L5CR7OICR!UL_E> -MT7#C:`W/"/;73,+9BGTWB4Y1]2_4@LS$VJ(I,5#+,FEZ[L71KE6XF;U\#U_0=BA)"JYV -M^B\/,73PM-\4NBA"D5TMO$Z7Q8$XVG'65KJ37PW@]URT%&GJG;%_ES:P8T\R -M&3E.UU_'J.+H3X-W=T*NY@DL1WZ9[)LA6F@)^8Y4<])7)"04ET=1^DT -MZ&3@I1PG9'H1V`0DYR6=YX?&B5ED>O<\W\&DY!F'&75K3VFT(^@0D$8/$2R8 -MY@0V9;_R_G$:A-A:",,CF=OR$VDHV-)/\9:H<)%@"@$SX6\J#A`]X4UH2_E7 -M2SFO=D]9V58-PNPA0WB6Z3/C,B(H`.#"QMYP8W]">,?(13CJM -M._6R/H[J -MAQ]5"_N41S8L=@8-Y4;[:]Z!5'\GS)9%2!KAB[Y"OZ)RB^S\607"[L\OT!7 -M,X-_6L."!2I6=]XJZ,:\`$.2DI;^[^J17=0JQS"C,%9Y)//BX)>8F_DW:XA0 -MJ.W)1QH'=L[3H>]6,Q>"U8C:1@^GQER,C8]IE(&==^5,4"O1KX2*BM7)R5?G -M*=GI9WYG))SS]PB[."62EF9N1MIXQ#=4. -M:\)\T+W""$%]+L+YY;G^4I!N#X#XWT,W+@\S(T00W"F%S0.:2>O19J<1W'K+ -MWZ@?E94=2HX`WFW_]$C13]5939$2641;!%_["(_:PPI4)$GM.L'P?62L+P&C -MH'N=^8!R>H2T?M)0LAG+.AT`C6.CPB6-!Q_,W#^".VM:N3N@L6!)R*>0:DI$ -M-Q8-&E%2L2`8*!WQRRB'Y4*#F7^6UMI1H=&+>9EG-KD_Z)0!Y97,XLW -M[2-']X7-([-0I[/D&UJE+!TS_E9N+B2A2WK?$)SN57.9J3Y%R[SRRI*,QZDKGBJ,H_YH6! -ME$F2^)FN82+/WJ.6R29$5'YR]QH1BT7@"@X19U1(>(5J^ITR$1R]H[-ZX?&X`[W\S"4WN,D@ -M=4=WB<-+X7OP#3CU@/6"ZY\,``\TPP,DONV0*UNHU`QP5T1V+36X:AQSG5YY -M2D!32R/*H$;2<9,_9#S`>.6--'+Q8NW#K$4I32ECHK55.01:OHTF)PW4K9!T -M[Q]#R#9AWR)+D+;8SR)`\"BJ*X*AQW-Y<^+]-0*'LEZFW*H;FQ1WPYLJZWU9]FV*+^R5^M4PT,!.2-:*/,9\D*;L.IJB!Q -M6MZ;7UHJI^^`+9:7A3M_]J*?\*B>>E,_7#C="R/H^_YR0*J&ZMT[]L_]O$$) -MC-=+GG$&`3?HI*Y:5$=GJ*:'CB#_\5D$PX -MC"KXP;Z5HT_H;`O8`EXWA%B7,#T<@(SE9*)A'([.!@G+?2&,7@?A'Y4>DUVV -M)&[H@*!C4%3L.2=O?BC+RJ`M78P[+Z`Y?;@D>E''MIZ/W2/[MVT.U6G%-:R; -M_9A_@+UG[5A`D-_S$;??ZSR6^![;UH)]@_L4[SU7C'BV.,M\J_VBM@Y1SS`4 -M"4\NEG+135&=6)FK@'G,9@$'/S(M:WHZKH!#E%4<)W"H.+X'7#1=&.0"%Z/^ -M#W,O;Y/H%P2:*BOCF/U?]7)MS6U"1*L,J6D&'E@&K"3?^L?7WP"PBIGP(-#9 -MUE,RXZH0V]4!5WV.+*,^VO97*D#2E'$<"Y3<*`ZE$<)MAH4/DFO7LI[\><2G -MQ_L=(2(X'ZWM1E8IGT9#ZSSNHGN*S5RV1X,#C!IA"5(*:/Y -MS;8S8:G`:A+:R+SMW"/*-&%1W%'0_7K1BZ9LN8*^TN\6=&<*)SF8*WXHF=^M3J0#-S%P57&W8"$*&:DIJ.MQ -MIAOCWG)-%5JD?+ESPL>#J_?/@W\@8.N;)->/K?MW?O@;[`$'2E)GC0>P8F*XSU2H>\LOQ;=?-D6UERYX\;S5LVUJIH6KT69I8+6?,(8 -MAF>?<:$IH.Q3(H/L=&54!)4S?:GC>\Z:\?83E'Z@&%V;:,[$6\4/`_SN@J,>H[I8=G@HPK-D)$)5PT -M\YGW7SE9$CG?/IO>R\1AM@6$4$,>.9;NFBPP6CX&'2U$M:WS:-37N:1J,3"L -M7:M",[\9+Z`FTA/,K_$@J?HKP_BX8R,*Q#9==_'.[?Z*Y6ES@P!:#'21.B.X -M_4I_/J?&!*/7\8>##38J?"F-:/X>0F_?S#&"?(;4;T\C^F%HP3R)3VJN*[F* -M!*7_VK-2=EBPFT%=X4=WXVD1XS[Q(NT00A`#MWT-[+D8?^&19X#M9KQTVO9" -M$J?W0D+IR'!DN88)->MN5#X3%<,X!?4D`@!3>_'Z<\<+6$8(;OBY="JB!Z)E -MH^A;E6G?V%>\2-1_P) -M[6:BB.O-TX)3FX-,4*0W&I-!VQCC/G4U.H -MRKY75M#K?_$?H?W8_<_[ -M&*^Z!U+_3-BX&?'[1-I88*OUA*!XJY^_H`B)[[56,K2D#J>9(=#!HY9MLO7S -MLLZ=#:1.4Q%I&%/YT6+0>TP>@^N#C_II2K@GYF7V3B+'&M=!NIW52^:@U;PR.SPADN' -MB",0;&T&3T<]*8>.27NV?Q3T?H5Q`S'C3/7J9I;XT#47K]BAXTP$:`M/%0.F -MH-*2?#JXY2"C4,=WL?XUG?V0W76N9+%]*^6EJTVMX>B`ST&K)D50>,B':8GF -ME8Y:T[4VK,#VY[XO=EG_E3:OJT.JT]&P7V%Q -M2F:^L%?8`V#I5U>MS,,^\1A=:V!TT##@"!BET^S0[7KJ:#18>1W19$"2`S.# -M\EUV"O8V`5-JAD=,^(E@/^73+0>%*J@-K;)..-."5)PO+.2+4=].:E.EJC;^ -M,"H/2&+DT",.W9E>_/^A7-O*IY;8#E_[4'U[0D$"/RNQ1W[C,2N;DD9[B%5G -MY^TURI4.M`W0F`-[!>"Q0U)K'EY\",*>Q.U#V.A07\FAV]6A]ISL,UV'R87L -M^A07AOS9.66'#_68X177PWWNE?,ZG;(ZPOFH5F[<0V;#S23FI0$2!>X&769A -MBXPGE:J8HDZ@>Y5,&N2"*\*A\%=<[^)6E45NW'`YPCKS'1F<=U'\Z>YBHV`> -MDK!ZNI[HRRL0H!CAYMRR.:=IEQN_3*:6T%S]-B;F-FB7G8J&L;?QP82G6=OE1F>G/GZ5JC\`\QNT#022P#K4?W -M.Y4/AF3>8%L"2B0/`P8?S74_9X_;3F:>BU"["^R_?+DV_B!#4]<;45P$!TD1 -MO];[S:%>/(I5@"14Y^'_9N5C(?J8%G/2[ZQ=WC\!-!6=R0C2%WZ&'&[A4GS\ -M*0[^^+C]B*VCO*[^&%P+8U8/!LCP/!B\X`*J@PA\$QMRSW5;]Y,(O:65 -MVCQ*MJ)IPW.=[T(P#TR2Y%-^H`3@_3Z4?['QW;ZU5[%"ZCIC$C8,>*]+CIZ> -M1)0JLJ&U,)NNF'^%L)>I,B@*/<[J9YE!>M.S``(,%[V`#\-,*6G"J&HW=95Q -M?N#OL\&BU(L959%BO7TY45]\%0#(9$,VN,:G>/$3\P`C<^SA7MTU**WLE%1W -MOYV<-_QEDOM"<(_S3=N+-V9*@^"`4JZPKXM='I#(L%\=:71DY$#E;.B>U(XJ -MW[R:/]_`H,S>*6_R_\4XZ(34T>H&'Q5G&\LL4E2ICK6W=Y9[=TH$RUZ?8;Q/ -M4ERXJTN*7ISW^BQ;DK(I\T,P?O4]8,X+*Z8`.">UQ'8D02HE(^PU\)Q8]`"G -ME0-O8H>71^*1!H@/!TRQND,-N)M0B^%^;\H*6G$QSH$-M%[^&>2@[3+N&S[5 -MM&7ET_J2@O^M85\"I'WL32-3GF\C57-/8X+9;2DT'#+`RZ\MBUKLX^[2`X7FO7(ZC7Q%)I. -M\O(ZN;4BN[4.*[C\TMG63$P86H_CR:4PP?X``84D6&#!@&N^3YS`=^L::5G8 -MU*=/I2SV1I(+`!=(L4Q0)@QN"W&`]AV.&A@HC7[$_PC7$D9DQU7B&:W7D&&+ -M[Z184H`?TFZ)91;GY/UM':;R(2Y'%9/]8M$;XC^'BHT;&>VR?;TZT'*/*.7[ -MZ-77>,[&2D7>H@4A84`AN-D9GG]RGN[-9\Z+8<.GUD7-K(<;D/;A+DQJ>L71 -M\[+9IBA^2N/@1NB6P0$WLK#/`&JV0]^99``B(L7%659I2^?#HV7K^"DAPA=I -M4RO2;UBO"D'4/4"1`K[JK)K,"3HI*V&YES8X4*FJP6UN],#?#]ZC]$SZ&%]* -M1SWR'<$"#>GB0'.VAR;P>0Q@O?)1C)V5[/"Q]!&0CXRR0OWM`,?:4D[0A[LL -M6S*1@)1EI+<)O^0&YL."_4E.C113HT1[7N;89&C&>V_!!->N6B0Z!"KH1F>* -M4N#E@[Z.S(! -M:O`3*[=PQ/J*CS"&.E*ZWYEYTXUH1RW5J"(;O_7^60^Y!K$;?\#**]520!KI -M`-BM/]U!*4_%&WLJA=8KS;*Q&U#ELQPO3^A88.>WGYOC_*7H^][-^ -MHKP"_,ETW@F\*D-25J?^'(6+6WUY+:25*J+SKN39\VF#=YOJ4)BUMRSD&G&3 -ML+]3T0S\C/-^RO&\+_,`PM$>/?%5O]<.:5Q$!JUM2?:KW-/+H>H\5ANB,QKV -MP0$HX4>4 -MEW"A_8U'6[/26\Z%O\`:6T^&3BF4A^"#FSS+G#::2=3AQ]N,FX*?[XV6.],V -M[N"]=OEHSD%CT\^_7>[(AUF^1/^Y^,DE?E*?IEP9LF:K_`C;;'@_@(-Q9J8O -MYL<\ML2$6?8#J6;-5\>3.X0:]N;V/RJ2.+>D*`^DO"[P]GQ`Y97'TX=!8\<_ -MOMD.=OB:@8+"0[KOXMITH'S6&G:Y:/1PA5=XFW"D'A'*IHMD7"NSGVX56VGL -M**?E-,>;VZ\%-"3%"2*U>8H'8]UA0-QXZ7=D/BR*CI28TX+C#&*5.Y7GVROO -M+M*TOS$"JRRSN7_O/JD:W_NDF\D:MK?''RYLLD.ETR=H"$#J;@'?L,I>X*E6 -MRBW7=U1IB4^*$KH&#R/+;?_E#__?D/I[+5F(:1Q5G..6MCX3TD@P3+-[DTU. -MV\-(=`$LJIT2J>_S&3@+7,?]6Z9EILKRD8,NJ5CI#IJ[)K^K-%D< -MH4/-98_V_M/<;<.I5JS2W@E\R4Z^@$X%NA=F:HM_YR-S)9("6:">;(2S#JRP -M9,KX,8&Z4D"RGDW0<5QRZE@D@'L0+B=AVW5CA`W^\GE%E_(@V!R]\BG'Z]_F -MT<_DDJ-\GOO"2O\T@DB+W@/00MEOX:TUQA738=5N*]7"1ZA_G3)1P7(Q2%\Z -M#=I4Z(9XF0?VO6R<)%RQ.+EJ,W$H'27*H*XLX?K"413*?7O7BMB_N[K+]!TX -M>$/=W7O/7(F*D52=?'*#P36XY=IFA2@1])GBD''<1*P>U4'=%,2W.[47%9SL -MVQX]%G>1><2H-\>PFQ(!+RX=Q^/8+8:%K+=Z`IIZ>WF^`0>AO)MH.]9'U%]F -M8)+;E<]\![YX(8Z9!&*S#Q:FBI7Q4Y14$A4F+GP:8'FE_G.@]QM2I\JY6_^= -MYH4M/+/64YZEKAABRZ7Z(2E6OCB=WP1TAF+Y?'T@#"N&F"_W4'2I/[5%?3^L#E'"9)^C3]Q -MC55CER_]R.E!Y,=98K^A3=B,(+ED2'OI?&GB$$2&/Y!#,)Q@CH]A:,SBB;[% -ME\&T@^!,,W:=!7=5(ZX-V3\MZ>A9A@KQT$C>MO:C[Y]$WI\&Y;,`=CT@#9J; -MK\=65$6"(S3_;D;Y7U]5KZ8D?7/*W)XU=#IG%XBRMA%O%3:B=!$-Y\$NY88@ -M:"=Q=K0[G4N:8UAQ*-.[)TMBVUP7K$'B+G3`\R1H%+9A`"$C,/D.O+M-3/7I -M]K9$$M4:>%C+BK^C(&SZ[MCE=3?'0_W<)R`L4?0VKT^L4>[4-0PG43P\%C/] -MG@A<]<5[5AN!<<9A2(>X`TFU?SZVAJZ>V[]-6O;:EI+F0LCUPHNS+R^'_3B" -MY>='S;=C#*U&-0@0(&M7B'1?<;T1YQ$)^A"+]Y]O_.)Y9].,?%/P@#);5\DG -M4H4Y"U*6!`]MKX;31Y?#_[LT]]^COR:_6Z4&S+CPP%,D[U>FJ;CL1&5KYY.O -M13"L@`],#;92H0*&0F2DQT(,ED -M2\BW=RTHS8:9N-GFO_U`UR-62@S&Z.&GF'#K%:V0W5>MZF60@`.P?>I7EHLF -MV'GRY$45.VN4++GROX'..P!2XPPD\^BP4Y;K;*T_0`=WQ8V]KP_/<7/LU;D(09=L#5T26+NJYT -M05FQMSA2BND0HUVL.H9;Z\^Z?-S]H.-)HOL=FR6&"XN;XTM:-60_-^?30S`7 -M!-QN[!@16G<*Q\*C>,OAT04\"NTZ5DQ=?8AO6B__R-.D]"F$5,3B?X/7.M[F -MXV;[CH6>>US2[LY05+BB0>)8+YR7[A#PX(I4RI7B!1Y$:/?_.H/A?)@:",*[ -M->ACN/5_]IVME$#[**8BK7GC;\?R^TX!X:D)(LL<)>%(*Y<'LCEE8,=M,L`1 -M98X8&HF@G1T'3BW-M&S_=]7GG(C+=T!`B8][O=?M9OQX(0'B^S8"0R(&0Z!$ -MR&-5E[N -MH@$Z[R\XF\I;8B,6YT'^NFN#H1_H!\)25Z1.<'9N -M\4!Q?E3[\SM%#H[;4U7+?V.N$HO/CFK2FCB]1N^9OE06+#I]?\+#T.,Z*:9] -MHW%7I,Z\724KU3[KDJ#J,DE./0^]0PF(U%T_Q!2YF*3H.8FH,#/F#A^M9J%0 -MWW"KEI+ZWS>[C-RGG@9[MKN#86H0AM6NE*HD\"G:S.)]S?(79W -MH71X54YJ_#U#@%?K@X^6?JL]])(1;>L4;)N%*6HGF)O-_;9/FA4":H"HZT8* -M*JD8"UH"I%F^/8@,O'A(Q7>%>!I?W\5S13XN%L8,+?Z\,>M[//70-ID6N-2: -M\5QN2<(B+WC]^`7S?>QR*^$8]:RA>WVE>2"@>Y'MR.ZT0T4W:(O@R*/E6EEY -M_B6_X?,*I"R]PZ3$(S8!A[2B[0$\5>1?WE#Y&7T^&]##'6'U:_4QD2PG<5CL -M3G&4K6-*15DF-/)Q0=)RLF9P/`R6(<%_8/HFG=TR?.]_ -M9#-NZWU:=AP[G"`)UVFM-]QN`FFGC0N@TRN0C=WW)]9T#N'#]R/YK`'?!RA$ -M^%$)VG=)+MF8L2L?N&TV*`YN![(-BVQ`VFO]ZDYBE>KW.D;\D&YHC#Q=DP(T -MM,I)P/"C#Y#,ZR+/M89%OL?UH!LOSP[5ZK=B;VWB#13N!VN$X7'922#5\MY@3R4DY*O)M0K_#R=0=B:@J(LT,.Q?^+OVU]"D]\S8&KVWJ-%C**.MQZ3ND8^'NGQ\#E;B+.4I`K0.II[!,NX=5V]/2U[\NA_:$ -M34C7B(%S$'L\7Z+N$BN"R?^G<^J?&0L*:O;GFL.F@^3(L@L')<@#V$F"FY:D -MF-,@;<_B,M!B8_Z#Y<#ULK#&_$.'K2*QA"T)6Q-O6X&W-,K@/DN]\'54,&SX -M;N)V_(UM8XCH+T6Z?(9NB$O:L?"V,]QMQJ:74*C$ -MW')5])E'S=CK2RVS9_)XD:+BPXI4OL -M#O])L.]-!9.CHWE80.*Q)BZ0),J$;I?K5^C%).?AY_WP9]G3'@";AUW)1Y/$ -M#F\LQ>,V"B/+F^%NY-GA%6>)*U4N:VC$P79CWT[<2@F@FQ+Q#N/C%ES@/D#7V(W0J<_-M[4"RYP\,$$ -MC9P?)[T5=FY:_!QRA5+08[#Y4M1PRXI4(3.D@'@1*K3=YN!B8C3@J""G(2Q3 -M^T:IGP%0%F:<4DI1E/5:D;..];=3/`N3I&IWG15O)=B?GR=6FW$F.]V8]]S= -M3IYP$O66URBI/$P$AL[UL]-AB-C84-[Z'J[PV[4WQLPPX*WQW_)G:*DAP/&/ -M#!39C+''V6B-0!MJ7A)T2&AVG( -MQO_^WX)B\_1H\U=6#ES8[G;./%!8#'+#H]X$"^C=8\`,45S7ZI*$(<'<_ROVZ1U_/ -M88PN(C#X-@YI6!,>U[$`92U6I@#QEZ^Z$],XN=Q2F=.L[REV;VO%ZQ"EC\NY -M-4J*@%:/3[JG.=$_%,6!M:[?P:/XA+KUL_NY#U%<*^#]>MVCUY4(A;@C[_J: -M]`,)_Y;UVL&@%=I98.F`Y;8\X:]SM9"*U?P',-Y9.^1NR_EV?K,;!<$+WB(A -M/G$=[>L5W-ZFI4!)S6R2+<+0[HL!WTDOP_0L*WX+`<4\9`JOH^@7'W.[H@U4R5;)YJ6@6+9(#T3UNL[\LG&J\'NS+G6T%.!&SD -MJK98G[K.KY^4O>%^#_+FH6"H;>D-*L9(DS#?J:I`@W+'"8ASE"SB^HDP7KQN")4VWX[L7RH0[7WE3(FW`DNXY2-:T:M]IG -MB>8*]RJ2K:*M5H^V.)H?J2&JR75*\CJ=?7FU6))S"S[%H]R/(;V-SVO..-+EZJ!A#D^W)^JN^!C3FBHXC2`XU*8Q78^." -M=BUM`1)\(X4TINM)M/._RLSIY839,?]]'6BQRB]"+,F^(^P?VO=1=Y^;3%,=1:=!,)&P;NH -MN4Y&U&B(WX"=IKWR%;->V==-O,&'+>E'(()CS!O`M/@7I"777J<*OV;3(XLW -MS!<_%).-PMO[.8C0`'JQ346U=6>I@+UCR0?L6Y1Z?=%E05K-I!+V&@=\%[&4 -M`/.Z06U!`%&FQ,)C*=CN%&P'QFF!7)QTI7?G\IJ[)%^')F?2+#V6T#2I=M!D -ML`;(6"S;C.+A-,$M82PTN"LIL@%USN#?-L!YW0#0/\];=#XJ"7/#GR\/I#*E -MP0.U,);PY6;+_Q/TBA&)%[$9%,!]33XZG$*>6,6I"&QL6E6_7%6L'V0LPAIT -M#*H*>_Y9(5.CD=`7]?5S5?N#JF>:A]&WQ/I=LDI>697TEI/B_&8AUZS4ZG0_ -M4&(W]X-X>6B1(U"M/K*408_0>\C3\?^!V(9DE:MU+![L,/AJU!VF)CBXX>H3 -M8_SMJ/N79D#"B,D716D,71!AH/ELL)"=\8*(1^H_2VYEFE8R(GK3-LW;-_R2 -MB=W^-R)=XHM58/7KKTP$D>V@@3$-7\ASFDNIC&OS6[=3_Q!5]W57N?8T!Q^87RFRH9W?6I:K&JR,E)OGNY+"U^IQVXV>)9_DE>K:Q,@2;ZM+?(*KE'%)!*:W&XXP8+G -MR/4MC$KRK;X.RT;#C'/JL2QKR\KOXP]8@\,$#%.V.16`TZEX%G)5LU0IP#$D -M=LV-2?*XW)?RVE&@'E=RA4&J5+GQ\815WIB.R('WJ*DUG=F]T;^6*A^,'R(C -M(-LU;B`M0(3$+`<4"S#>WQT+W!#[H)D?@1.W"/9YUA0YJ;MK -M#35B(,3B;GMCQEA[G22S%E!IA*;()1KHX<=SAD'%86@`V:29.R0"I@]WKA3L -MH(U?X*6ZPS0+G?W*&<*THX!I@MGH1F-$1<<(9?8.N58[]O%$./$;(9O7<=_6"\BEV`X0W)P9^-N2JE%QL)K)LW&4^D9C5.IL% -M=Y_Y0727^`\K],HSVQ>:S&LW_/56U+KTF\#*&(]6KP;N*NF\8-(R_U/)<,M< -MU:GI"=$=R2S1_=U6R[!U&TX_4[W\G&OG]$&N -M_MVVA5=/64':N__5))"Y0R*HYQ25>'`6 -M2P32:-:;._J_=!"F2%,:AJEJ0+,MW^".S;,*[L?9?C*H*+IN])?'ZWK09NI\=VC](<:M -MLE!TE6Z/@5,D1N%=3L.O&BS6PM'+SY)T>_@^8EA=,=_S` -MH3@WL*+JOXOUC":2SKE4J=L -M`4OEL8Y&97HV6AP"L)@A2J&`-_&NU852JU<@`4%0#_PV0-:[*,ES@OZ(EU/F -M@U7BKDNA@(!>VX3V'&2NTLZ?S&E\P0R9?8"<)58VO)`JHWC&0@; -M;15)>9ENTV"D$RF@QDB\V46;^K6-:#;G_"..8 -ME5IC^#-:>E]Z]+.W97Y-J*20E"0S9!5L,N0&OB#=IEZK(<,'W. -MLSY&R+(#EIB__U3V'L#C,.];2+3$Y$R@'UFV#`>ACB0O:W\H;4(%92]_86/S]G5YM$NG,LK -MV^_O\H2YJ),=KBJPA4,R-EXW:9Y[X/H^1D_2LPY03$3*S@3I6E1Z=A+:=])T -M]E>?*A`N%=:P>*,Q&:[M_*:IJ(LC`M?O%'U'8"C4SBDR<9P-SWJ1DZG2MPA$ -MD-Q(F+A89>!Z8HO+#<-4:R9CIH=P5:,U1HT"5_@Q*$G:;2"KDW9ICX$8EP#([#W@>[<6L$H_BB5:U#>RH(;K"SL^ -MRU5"911=Y<"F#?V^%=;#2ZU*=IAQ!A,O[Y04@=&@.ES\,_$;NN)RFO3^>Q)B -MV,02;<9KX1?8$OY`#X>05\16F!:Z"A\WU*L8%;#Z`CVP*'CKH_:W'7.-&+Y -M:&2T6+*F;VPOM&F+?5\^WE,B+@&HHYE>([/G,/"N$SKJ1*+>D9I@Y\#W*8\Z -MF)H)9\<&<*Z83E$U+]R!A(),0KN7:1,2`9)DH(<7WGO*3?@\?_1&PXFDH(.@ -M4429+;\4:>>VA^`IV#%PP0N84R9W/K^^23W0N3AC!C4T*M9T,')"4)_H=!E> -M=*P%&U<1]%-N62VY'G62,W&6,9`C=RO@AA)TH;R8&?4-%J@Y3=\MZJ8E$.5A -MF[+A(3ERTV`]YU\=4]#'.6+$K:))=`P%VRE+MLYJD%-B?B75?^]ETNQ$K%(< -M_<^BYL3S7\8W^NG9@;?[0-O2#4JF;.UV3?PE+K;1ADR-43>P%E_\V917%NNB -M>:YC42T4:1P*NPKP%Q)>GL#VK3-O!T]$(Z8W7)+KT3`1X:F?I4HI2$7P$AX[6!XZA>IZBH -MZU:H//WH2*D!AFH]/G=M::L\I+" -ML.32Q;Q=,ZZD_<7T.AD%P5M+YC5\HI`>=:Q2,7L&YR/=6$R'=]9_3U8N50\% -MHH$.T]7G6&8[2F7RSZ$V>V@2VK4]DBI3J6?X2I&"1W\I+M27=73U;THF54(: -M#([7.GKOC9GD46)GZ6(;'8KI/=/)'F!Y5O?WS-JJ=K>/M7OLH[54%KQIM*-# -M;AE*`2J#^>?$W#QBCUVP51CYL$MTKHNFR;VK.4NW@.5UO=+7DW3X_*AC]V93 -M[)FA-T#R7S,'T]Q@^!=W$U/,+1'54J#I/Z'Y1^=9^GS1]VWNM!S>;>82#A$5 -MW=V>0GG*^9B@#`I5F(3IW]Z%WL$&N'9#>G=<*6Q^5K<=/`1^[TZWKQ(:YGH= -M7\ER-V(XOY4P=4_/`"?K4`I15M$WS2O8""=++&DOMNXDSI)-E*$^_1DG[-0\ -M&*F3J5#&[5$:@E*/I9=_ -MI>\`^CUL&FR5\2^T_37&N9/=EJT@;N4#"HH1^JS$VRG8]EFKS07LJ@;26D14 -M9.5J;M?"$NM0G]K=>#K-,WO]YWD4?*A>X`65;_AHUEM2QW'_"!/%JF2.\ZC1 -M`">:OA!+7=1I$UWY&Y9R%N8<2*D1>'$WI5HB=#;X>XEWT-8(3T`VX):V#Y[> -M1.M??@V0F_+?E4\I/JR"`@>EVM'=`WX$QPK<_Z.?UG9)UN2#OL741`IDHCCN4WTD_1M!TS?WM':?HDV8P]W)NVMYG2$G[U$L"2MW -MNR/T/YK8)$-]@"KV<2+26`((BIC!W(3]UW6$FR?4_[C0-_/L=?OI\U27N@3% -MQ2NL(UWB"4.@LG`/;ETNGRSC>Y8R]EJB+`/%R[O31,_0%#*KZ4>E#"'CGXC> -MMMZ(Y>".$*/5W3+I4GL>JKA:MPVI5=9IVL#ZK1C!]?M)HS=Y/-0_O;NPB;<<2U*.18@ -M.%PA5_YV3&^8$W4?M=0M0!W28.)H-:OV,`0([2.NXG-5W?_6J?6$%P(O'7WF -M-\<[0PA=7GC=78+W'M!S('6'NQ6.@TGNP$?8X@^6(+F7HNS8%H.3F^ILD*6- -ME+FPJG%M?F_=AQ0V#0R#!6)E0MF-*WJ:T-)]Y&+/9A'%:"0QKLXD,LP8!\8Y -ME!_0B#U_4I21D:-49Z[W77D"VP4"(G7=GVU1N-7#<632'VXJ/1T&R2*C>Z![ -M'.<79$=/PFN=B\M6(GB6@\A^$R;YSRH/\]'54+>&W=;RD:(!/D]6L^.^\[3T -M.3S.4$*@-ISY,_^_8VOF2AS=>1=3"H!B=(;U##9OGS,=$7 -M/..[U!^NW-\#(]Z%6W&I9+K+?6<^[V[A=B,O,EEXPX:X@K8K;3#:.406);\" -MSA?")7YER;1')^(?3(2:H:7*(]WG^*-:F7ZLJE?=M3;:*3G:&F_\PF_$*3S) -MVTT9_R0($$#!@LZE#M_OJQ_'TID`#&PT5LE"W/'QJP2&Z:`*'S2J&12KIK?L -M_-[R\'\J)IB&!K;[R@6\-#S[!*3&VF<*><4M9U`$M6B%'/].0X0E%\B\RA<7`D#ZF'1Q#BVOZ->[A!`^#FRDNDRJ4*4YA+ -M>U:AT%!I:'FV0NS(@`HJ``U%4$IK"4THS6[M6GC,:`_*C3)*98'LE?HMHX:U -MZ#K+A'[.$8FCHS4UN++C_'(&Z#7+TU+KZ/,(NO!G043RI7O!(5C8^4;XV\V)?GB$2ISM-)<&1 -M#%IXS%A]4OI#!`N_^G5_H/HSV_\!M@`7+R[G$M5#>3(`-'1H]YK:$%L;+G&1 -MP>FVA*H>8O)8K%HGZ`>+^8I"I)XMIJ(`9Y;3PBR[G/V&)W64PS&NS_49_:&Y -M)6CS@VFFJU>7J)J9GM56WAQE5Z(*5D`@0.&\)8,_O$;.9;E.0X8I@?&('7** -MO\-([2LA"B1TAP:6)*@1*HI?!85UFPI,5&.YIW5^9?^=7Z^R;[KF3A^Q=EH\ -MMG(ZN\%W0,=7&7/QGF:/7UHIM#1@@FD-%UY)JUDIC4&^_O7UT+.[+HTD\OI8=/B=AX&D13.J#/!/87B@D4"U51RDM= -MG@XIN.0#DG25$). -M,UR\#!:4@)!Q4&+>TT6CDHEB.O_\A*&@K;$SX8OBMV;*I!,J)`,-FQCC<\IATE#8W?;)447TAV.>8D&:# -MTS69!SOK]:QIR5"5%QK!P$SK`HJUB++P%1&$U/V(8%.5)9R/:IK-R,UO)Q!^Z'^8/4!=DFV,QCU( -MB;3D&]L\*5`%3.;MGJ*<#]`H -M5.1..'!R[>R#\P#Z=/@'H!`D&GM&KP2WF&6#)'6H[*;[2TE;A0M!H6PHB40^ -M3*6U!'-'/*@B@:=LV4=63,P=_,?J0LUK(A1>,R8K%"OZ[1'G\GSHB^&M,^'5( -M\TH[LSRZD.60>:`Q+D=;N`\0&\T?@TK!1:X-RL+A]A,=\4#AR+S8@[;G7?0> -MIN&R&CI>>SO'QI7U)=P'C:TF_"V'8`Q\L(MLU<;LI>]KRSH3,[]9?@$3&L6* -M[9I=L%C0\Q,.H"KK>"M^+/O20W2_@1#MN4-Y4./?<#T*!._\)-C_$9Y=+3.V -MG!'^7\V`\L`/XP-3I[D:=9V2%%\'=*4H$CZ+&_3M2Y)9-J=L([O(S\+^R>W&NB\QP0@;DY(W^Z; -M.T4='348*V"6"`&`F1@#:^]\[B\E<-Y*#J6[P:R)K@-Z"+ZAKSZ+]4T3U\^\ -MA\WEA?17G!%&Y:F_UG\H\/=./XYYE!SRAA%K_Q;5W4:^[I$*DH; -M,.0I2VO"JS9"*$+":HCDFNBN!>KM^1G5[3Z*C*T=;I,(>?$-K**79M.O$OL' -M?DX+E-G@YI80$N*Q3^>))&QAUU7HB-908\XAS,\N7'#+W83$\T)7F/8IK$H/ -M8D2=VKF&%XT_$H4QN`,S_?(RV-3T-OWZ'V6(MCB?0C(R[OZXA\"\T[U#5.(X8_S_22B9[?)4$UYT/FC"YCZ/L2QUWXFJF -M#*ODE/5\?3:KH##.C91Z/7"\A]J4F&W4"!HA(N$@!]'"\,[RV>[XEV[L9+'? -M61A[(5/TKT]3O[&V)"4,*T378[]S?#Q#MWZ-66H6KG3J_,(F"#\//4B*"<%$ -M2!Y)]/D(P3VDZUM>8L:WSQ_3DF2:8-.Z,E(E1E29NO9A0AH$GSKSZ)%M3N-M8;8@(I2 -M:(385]C(62++!?*898B![P;VJW>H3XN817L7DUHU>.VPVH!#/ZK=WHSG_AQ,@%):HL)04`X4X%GM);8W5Q'/2M6'&7R:"CUO4JI1< -MSD+<*E4\*U5_Y!48,F8%%)8;=?KY"+9*BKFC[7S*J\UF:O/*9A_PB4X17-OY -MFV$J0!25;B]T,>KNXLV2WA`V*3HL7N3-3PZTD0ZP.Y\G70]L*&%QL'6U(:0T$1W5STH6V`U:P-7XZ+#32(=+BF_"==D1HZ,685I'>XEYU0\Q_ -MU4;JE50PFMP97"80L[?\P$R`*\&R!V0H9M0C$.Y>/0N*@@QG^75_X7G?1E8" -MV-^JPHB"WKX0KB%[,/F1RM$3A:.V?OC7W%W,YZ/]9(5G=#;%6T]X,@T>?F11 -MSF.D=CRU%VPJ9R42>FLRKJ96FZRH9J:R^C6_HJ<0MQ3C:`L08=>B_HKVQ;64 -MV3[!&(8).C>6T,9=6.F(AK$5!X872-;T7=_S7F9.=_3OP)#A/P,NZXET(Q#@ -M>:GF.#(Q`?=.KJ%9;$Q,$H5(KHVP"N=3`B8TNE`O`[%YTQ[?2 -MS,BKC1R.^9U8(_'-+"B\2P`54Q4#U9"]4>Z-B&V,BW*4K.=Z$A'=\"=3R\96DZON7\[W1PN2*+ -M2UGVR=<$[HBDM$3-:[UL -MGZ,#T;)M1C7;M;';;L&0IXXUD/YQU@:N[;]:M9S=TD>86KSVH$7&&3U&$?19 -M;!)P3M7V62==EL[/QHJ+^R]J(VZZY!B.BI(H6QGRDX\X3X>,H,X4U$\,BQ*+S56")`"\BKEQ*Q*-DU\P8`G%- -MJ5M(X8T\B^9URX*&N2K5[10_-AYNHQ?M/?*\@81.`'9!EL`V?7_[@9,5_Y=S^SD>/%J2JY?K\LF@XT3A,FT?7FS:6A$\% -M(W_\B27(MU'/2LTS8U^>&1*^C(2O:0Q;0Q^I(??(U#X`%E^@*LEN!Z!?7>G& -M&%1%1YO58XT.=@./T&,[5-AAE1YBPDI_/9#KV?_#IA-DD'X]=?D#NV?A&%,S -M+MJ$A*V.`U'AHQ!H]*#6BM5-CXUBH6B/"$^8A'6IIR6HH5WC;O/IY95;,^\B'T/QN-CD9LRG]Q%V%?GB1>O[V<;^X\2EK:$AYHT -M'`\]E-;[%1FFH"J7YSO5$Y?.3\/MC**U8`0"J`T3R.U[0S4D\DFKRK&\7;B5 -M78J#6K@$(?^+BC7PYM?:9)[(FC%1`-*E@46GZRRYPQ34W:]*X;VEMS__H$3! -MD]653965P_'/_'$?&ME;MA).H6L]\I>EY^+CW&-5!T?#O*VI]`?(+4#13OU) -ML:H'1+A%(_+*W^`AI_V`O/]=&4F.;C8K#ZHO"S]QS4\1(Z+*U)^-(JFATFQU -M=,%AJ0S>)G#R%XU)H%<)('VA#/>L7C02\ZV4W5*)$$#EG`DQT&,K?TP5B(/W -MOW>R=XX$M!E301$<82/TI,DQ(^P18/$N[]2*-F,(L5E!7E=M!)9HGI%OG=$Y -M];2`4JT[4E.BCFV:4F>?\@!?BU#O=B!FD5[Q[`HR=GSDWTPHQ'G*'BU4H0`/)IW$`'T<4_(EJN\A[$9W$ -M=C`)G:WIHJ0X[I.1_EB>?=T9 -M-[M^UF8L;7IJ)1>9Z"]&=%2!I=45-\8*B!\_V=#'E`;VD)Q>X)ZO88`0UUK6 -M3M(*R%DM!`-0'`,ERX0GMBA!['BL&PK)%RDHNZ'F;BTN%V_"Y;ZPM/*4C8[I -M:PDD1=C$#JPI:*?-_1E%!;1\6/%E]^!YH36[WF5K5LK\;'2]2!H&C)$^JDKC -M7=)0648#!%)&5WJQF8NMK\-4[&3MO26>Q[@YZR.BSNZWX[TCF1<\@V;KN_0F -MI50]3FYJGR&\U.Y`+&=N:-HY2;I`Q,QL3"`WB^3I<$'-H1Z0GO2?><68!.SR -MSWL8=1+;&0@`"?[BYIE]D'JB=C=$`-(?0:6*SS#.AB*,..;E0%VZZ^;7=-Y' -M&D'>/FX-7,&^CP\G1\D=YT3G2=5MJWF#\U]"\UU<'%)S+<3OF$,$?!92.F'O -M@&YM(>.?+,'+C^T#A-\*9K(_$5M3=8:BS(8>.FW])UIEY((3ZJFI>431FZ!I?H,D+W7YNQ!DEQ8:D!SR$,ITS#R -MOEY,55%++BNJ7'R;%T^U-(8LZ.YG=8)<,Z!DA$+%#Q/&`>6/1D%F*D.V -MCR6+5<`B09HQMV/AIGX2KY'P:U8PU/S[5*XZ51\:[-TDH#\63'9O"B_,V;F' -MDKF@9.Q1&BB/1S2[]O0CZH.)4JI9ER>.%=+*QM^_=GT]_JM078EK\JQ+?_*I -MN_;Q5^H[5B2!S+BC"3^U5U4UPACM)]8PW6UI12V4?-&R;!#`"#8H<>9W!G+Z -M5NK]_^HAS=72I6_ROC@^D7ND?^+&NI#5`B7%=F -M1/-FD[*(!++0"!T81NM;A'_$^C*[-PP.(:#$???(FZ?VYT<@*QEQ@,"6!CN1 -MKE6$J?^,\S#38J+R0EA*]!2WG#A572_@:\K`Q%ZN&FY)TSI4`TKK+TGO^1[$;B!5DVN&7 -M/U$K'?/GE\9C443[\"90MI0QX#XJ=IVT\PR9PY$NW]G'I#3UQR`K?&??SA[D.=I` -M[$`WX?@GSB%5#:$G:YQ^1O21T^%E=#D8S;,KLZ5LYL;Q_UFRU>E(2!'^ -M(=<\%A,JOLWGYX$\0XA63R\`";OP5!8/\0A"9I:94FG-OK`]`!,/H)*]]5$Y -MIS7'O/GDD1W#2A/$Z7@+\!?V,J%;_;DON>R4MQXZY?C.*MDAR.!$RVZTJ7,A -MM@UUU."4!#<:)#W_Z[QQ3\ZV.Y(HZ<9JL>0#%*W"0M.84;'?Y%4OJT.0,3VV -MR!W@KWXE]$Y)P7]!D2Q#93B6O-]`'L6U1Y4'Z:/BY"P:#8)<^*,(+B544P0" -M2V@`O)O>=&MR`M].(6D5D2L%0911/W4$37K;V6$0Z091/` -MS--6SN2.L&U8;%N_&%G=661I"^C/FA[BR$P%=*70B@'#<;_"S>V+UOO%FN2: -MX%WRJZ$#'*/R?X'_`*HH+6],%G_I)Q,+5X6QFW*J"`T]2B5KKP,"#TR"JOSN -MH.E^R)"5H[4>N$E!XSXU7[#;'1GS?JT#KZ+EGCC56\,:Y`=2^`^Q]:R4UK@X>O+"=T"!L+I -M'5UANA)EG[V''8(B7X)<&-:-_BU$^$^_RJ)CD%U.)`'8D"_*`=W4)E?P"-Q<76BX3*"CKABLK>DNIL6J -MA=@K&H5TR3D4=IZX=?B6&K:UV=OE3@_[NB8:'A]M%XH:+(-<&3F+"G0?4J2UYF'UZWUV -M:']0')6^-'C.`J=Z*_=_YYT;`'K%*A)VF4F_\;5[1%#FU^H>E-WII-:9/T'@ -MB6K>JG%Y48R)RMGFG2!XF;/%>(0^_]*8SX&P._"2E:59'2]LX/CE9)?).IUG:!71)8>[ -M.P(29E6(VN3,[XZC."/7]`SRS5`%?=0A+3)U(LJ[T.KL2(C*H)7:"F1\@PC` -M7)1#UW##Q\1/2:.RRCJM3H[FC.A!E.P5858#Q_+!0Y9];A^I:]&@`'$YF'[YV2HA3:7>1S?A4 -M4'A@P6U8`$WN\=+#93,LO,F_VFLSEZ&/WL&^8S\C_OE5@:K%!4^^V(=T9V:& -M?(33X#:9.J*L9^-I%2TBY(M4(EW8F:<$T%C3S'`<;&`!BA_RC+V=V1Y`XQ,, -MW)?1$%C^S/=P/R)KA4-&7>'Z-AKR?SU3V1>`*8LY,%7?LLCBG3\OWLH#G:8E -MJR:5+Q[^NY62\@LJYL7]CLY8CC=2:V44:9/=`*+\6!(9_;^!HJC;6^"ZK$Y< -M'$98V(X'<"5A#^CY76;)V;U^`H>=N"*-E%@N06]^'G>P_K+5!WK:'2G*^=Z! -MCSJ-6?"1J,@$#`+6L`3$+4-$E=[16)J+JR/IV-3.)>X6NP\]"L1,:#$^]Z!L]D!W["P`D=#%H74'PW9V8 -M\+IQ[8L'M&D#=LJE>H"R2W"_=RY;"=BNMJC()S1/V"^+!-!4*9DRF`.ZZ,SZ -MCAI)%28)U56A!U(;U@N"%0K@"LC(BGQR//LFDK3OI4\-Z`=AF-&=^@.7VJH! -M`MYS[,[T[`4:Q>[]+Y;1E\_PF"BMRVXRH+'72KA5M_O>*5U6Q*H9.1^=,=). -M3AZ$X&4G?-5KD16,:/[B-7*&V1,$V1IT!9Z:LN6IDO&+CR%6,3\*9W+P#>G: -M&HOM92&+J(O*Q,AUBJ=!;`W9(;L],5J[$=(A-!OT -M)=/N36=W616"V81VV:+0XIO"/_>_$<),IC*`/M73]`$2?#2^RVI'EI0[0Z+: -M_1F`S+RO?XNFAZ]_[L0JV>:8>+B.J@X9TF,UNRO;*5H(&F6FV\7S-@JH8_', -MO186RWGW9W1G:[P#7I8HC'*E_SDBPP!Y\R6BN5'O*55DSV+=K*5K"::H($8, -MP7_#&C7CJU,[M=2"<88U:!9W^9Z5D"M[)&(]M8R92\Y"RBK^-6Q#X,;U[/G$ -M>?:RFIOA6Q[B!:\!4K`C*PH2PG%'-)A]H,^(LQ=U3[/Z45Y6BOCV1,Z3;`; -MN!TVCW44M;+4Z_$Z[H)^,PT.LVFDNR=&OW\G">EU764&")[U9$X>+GS=P^GC -M386OUYB4I0B9DZWU,)T%;94.`_?&(XT]`0W1%YJF]:R<5-OR8B86:$F/SN`0 -M%0+J#33Y4XP^)>E,%2ABTP8)S/!7?DVUB0"_'GOAI,B!0H6FIP):\UE -M^WE?"AC,52+_E84_?Q=[9VN^8+,GEIVBR6J4SXI&`GZ=PD1HU9PE_&M-_\"* -MO9(>@2!AHM>(+M2^QP#$@$[0H5U#CVL*5F/B:R(0E60!F0!S\'I[2)/U_/<6 -MGZXBP1(C`HEO9#TBY2QRJEW65U\A(NDR6GL9::KD/Q^]^,TOKY#A_7K;'I%D -M>CNFB!2K`5_J"D9S1("FR5-8-Q`,+K%T#7RI*)L`_*B??_O3\;!*1U -MUA2M7`E0_A*@T9TL@B2^YZXB.9 -M)`;8BH-QJA8%N1Y&9\B:\>4W;JO+7=%0'@[YOF)J8`+IUZ*CK#+-Z1,*9O_Y -M]C&3F;2YVG_;716R>V<@XO#SC,T3,6N9D8XJ]5']-X/BUWP=3,?I&#`=S#G% -MO-`R"4SGIH.P@UDLYMR9SA&L_]C8M9FR[X5.$A$+9J4%6\@ACJFXVXGBB0") -M__$?#NH@6-TF`'EG!$:K(14J)$[`4*DBR;<_'JV@)ZRUC)3(0-_G`A4D!OTBUH>AR"G8(R8^C[-Q];OR)I3`E+5OS8#M8Y4#/G,:OFO])`KC443=OR9% -M7[Q$-&RFW\>)W\L@:1]O!-[.US&B:UY^>[LPY^3PX#`.ZK1I-Y9,'2B.PLGZ -MQ*?D@'DX+&NG>C>BJ@P -M*X9[1WH-YMZ9J?RYBE$-&`URJB5:F25=#Q^BYZH0M6%NC'2R^6=',AO'4E[3 -ML1>/\0?[ZA?FB^+\30KV2G?9"=/SE+`46V,L&=#IK@J*NFV9B&V%OL,"3`P% -MREHP@")IHY]_MH/,5Z[6WCV;[]_Y;7K'EQ6E6S)MHD)1T)$X^G)#+56]D>>V -MS*X(LXR7:TT=6NFBK"'#[F&S)H-D4TCM%*'FE$G,*11-\S6&5Z1OEH+Y;AX` -M8$&*N*#GA;*HNWH-Z/G/5_99DIOZ^GL0[&:GPE>8]5Z&5F-9YWN,*]0VHY5= -MKQ$:>/-]7R7O2[E*X`15TG90X'LN;8?YK0S(@/^OXBE:'/E?EG;E2PGN#EA` -M3XH8,;^<^-S=.PO=;21N$3'1@ -M[-\[?QRR-/W+ZA]D.H -MC;-=Q2;Z_E\KC$HZ)/7SD\M5A8ET:7S^1ZZ_8=ZMHWMIPT8#*],(V.0M-UVG -MK2=[.XD^#U9-%?FP%=^^M>7LWC4`M?=GTD]F/JQ\Z0*3/J<6+G1PRB;H,O7I8 -M/1@AV$VH.<'M;/H>@')X%1!UD;;#B0/?+4]IS=;$K-.$YNY2@.#^3&NZ6F'E -M(36Q,6L^+\QIWW1^>S*9#+@$Q1U%!3^<=+QR4%HX'>09/,UK@;3GB[(#M93J -MS+G7>(Z.1.WYO,L,173Q'Q!8C@^LM:?UQU]SR9_.DF%VNXQ=&%D\0!'I2,_&:QDNSEC1QON&<7VK9ZM= -M('`8#;01*?9AE,7JONS%&&>76S`V^:O6D*ZEVKKG@#%CR![A0.@*] -M5FD<6=T&QAG,F+P?5">-6%P7OT@'X=KX4MJ]H#XN5,>4'Y4SD7 -M3-E*GF;-(@RUA*8!CDX7?S*C38O7E\PC<(2D8>LM^'Z1!7)EE`^?)'NRR]%` -MA.Y*1`=53?W4O,+LSLR+2,N'0;YL`"#D/R8,R!P_S2\U(52)7W]*VU[@\:M8 -M/+[-$HZP^@/W?>[9MBU01N/@P<_V_"B,:">3/;#7\@0U7?M2;5GJ/AU2,X_, -M#K$^S)O=I=6,A[YJJ]@)Q6";N#TY"M:M9_3)21-#7$X\KTI6W"?9=&XM&KBH -M>Z,1`8GED)9.?":8Q5G;N1Y6$?N//R_\)!)*!YU_60VIH3@4YM,Y/H>-\<)C -M7:37;;JS3H+)#!G_\"JO!8,C,^>K"#\@YH(@<@G2?+P_"RS@@,UXH?%%!0V/ -M^%`P@;J8A?F`G-"-*XWQ+//,G<^F'5*R@!:X+KJ<@.6:IR$-?XC2K[#?X.G* -M56W3I>+(!'JRG3A^1G`U)&6S4_JW):"58S_<6U^1TU4Y(^4\):4<6.KXHC8Y -MG2_[E]\[@THX%*B8"#C6J>$KENM/%HLP-@;'=8=/NIE_O'GT-59&@V.CWBTG -M\F4_`?TOVVD^F'QZ;H,9\&.`)I%V;>7P(Q4=C;R$;*;]8_?Z:@Y..<6C]5V> -MN^0YFHMLT:[V!(<5RT5FU'_@UJH_Q^X2]\57))W@I12 -M;F>^B'<.4FXW>+F.#^]&.]PTE"\ -M:03W:1 -MLQ-*=`:49PXZE-!/[:VD5/B7<,3H56<@/8JV+MT>5HGSEP(R]I?7^';*&9XZ -M&>\)^)1.@LPF'DN06Y^/=5.1?0T`*0[KY=5-_KH^N+Y=/)\$*C]AFQA4J`'^ -MOV[L_N\6H\8R77-;VN"3*#'Q4O]>4G@#823Q"12]@:[6=-G7%YL9.Q9++$:F -MT#!,J1S-A'R"/Q&B&3FFP-&0=NB7V]%MEMDJ\E0HN4W1XLG=7MH0[B]4V-I* -M%G!WGK??QT1)*H#(Z:T+G,84-A*K,[(5`H@E[TB_V70/*]CZ%S_&=MU%B@[EL8[%J@1;.>K4E/DB/PJ_>T -ME/UT*8[A2:_C/_1LE%9"";X`5;SMFW;PDNEVV^*`U-7,R3\,7V!5#N22V.!) -MDHO5WEFNMQ/"I+X+]T`5+0%U5JH""!.T9BI^6#`9]@>$B.(-2@4QG*0,E8J@ -M?RG*5JTW_J2*S!%\=V[G\\L8/NM1SF^"@*M?M+ETDW\OH'0A'KQZ.G[T&>F/ -MC1.R8,KO*%',F#&3?G)^B2IC!ZO/*N+P91,!Z-R#_ -M4(,_\P:G]%?LJUQ!^]#@/_,1LHIJ+AK\0'EU)0#V1PQ($U3GD10`&+1(L/W+ -MN$A\0A#O6EZS/D8TQ5)"G^1RA;6;C="JXEQ.;5Q]K#KF_^,^-23=6DQQK2^M^+CUF[$WXW[4E0PFRB.? -M<+`P&7!VT_ME/#,3RVW/3/@Z@+FVEW]"R=/3VB_M.1-@A8MK:L0;*R60.OZT -M9-Z=E'!^J2ZQPN^&*C$Q1L-.J#(4:X%U1BU&PYQ^ZA%-MB8?:(S'FA@/4UBJ -M(CZ&YY&9;*91GZM__91&@`^?*:*UH@83",Z-.JJ$%B5L!TJ:S/L>X3^:8S\H2J6ACYVRY_ZFDG<&_@"_)+A(7ZD@8QTAS#UB3X1C$\OOL -MO$$R2O!P2H3H$,IYM!N45NP5^3'TQH,:N4&2`&"(1=!M6W#@!+-6R$GB$W*' -MGW3:D>[D>AO.=B)+2-,*5HQ*)?JQ60U%FP<-1YWM7B3W)"2ZG+:_N;M[,3SK -M+P],5K_68_.8TWH7)JT.MYP7H]&V,2G1PTA_#],1!NS9M;X=C.24@<^DJ5P/ -MHHMX98.RRA#7.<8SR;OJ!]>XEJ08!1G4;C\&ISIDUIGA7R&RQAMB@VETZ;M9E<:I&>`C -M7.\#0M8+?6""/Q+"5I%&*K'%TC'W_='3)`\K?^4CD61I3\87"<;@\>,DPB@X[D&8OA1YB*C&6B$&..>S'Q.GF\MKD0Z;1B/"M72T -M..9]SBAH<)@H",R\L_+XX^NE=:H!I>L_9#D)#HF=3=*!,=XGBEG.0(Z&YVNW -M8+9._JCD==5IL\9`S\J*'O-8L8T['3FL6/8YTR.O80ZS>5OK"U-- -M"OELM4+.KE,>MJ6M_\\AANF\M0S`<8(FFUK]E:Z6-50]:7W5S8V_R\0!HO_- -M-<_IGR@T,Y'FL\LL9&]5I/B)^Y`_80(4%B7A9@8"SC\J,)U^A7OT/A'(!YTMV4Z1:=)NG -M\/M7[CHFFN##/Y8-PZ+2#UQ6U?94BXN$#-3AF]N[@B?KG!^F?B'@RX/U)SKJ+7`HDT5!M7%X7S\TX&=OGC7>L -MED/8,9?&-5-BQX$L2I,BK=28SGWZ5@4#FYP<'5)C)Z3*R\Y2.B( -MWF5=8Y6BVWS/C)KN/G3(;>@=R(:%`4,3=QK;B<8D[/=&!R>L?Y7Z]Y)U8.'H6MRQTVDV -MGI&[B(DY5T54S^PM-[SDI)PS'!:""6[1WOZ\T/EDE-_.?2GQXV7T(O(`#UCI -M:$.ZYEOBFE>B?VYC7TF5]V#K7G[3[#0K+ZBBD,W#3<2Z-ID`A\$IA\!,9]/E -M&?X!:.E&]AA0I8C)=\.L!ABU003_.4_7(/D8*@T^%,1A-OP/4#`$,`]]WNT+ -M\ZE'N$,Y\M,_]G`+U#-<`IYR$Y.N$?541,C2L2,7EQU)"9#1K+7L\M/[>W>N -M#Z@PSXE*.V'%@*-!@J9]J_>`7^>$"H*7^T)9[8/EC=;1%>\%J3_PNUD&X(IK -M<#[K!H:FT0M*CH]XVN8<^SS/Q?@^U(BVBZ9N99,+`__Z0^BR;6S*\D-T8[]DVN>OG\Z7*`,5/#X.5>-,V5H*(R`75_TSZS -M/$_TN7(M&2T^:8N=L#ZVWJ$8A5DE?/O2'1$JMH].@QM*-]K&+=$TV]HI]'EQ -M0Y5?*+1S04+1"25APDO6C^S/)UXFUH^U_K9++EN^G3H_#F1N<7$(;L_E?(F2/R^M;EO2^_R+&-1:S'Y -M,YGMQ56K\\W-M11L0(]0":[?BI^H?_B,?F&;P^4@LNXDD3^&[DJP]A=NO98B -M@?:^X/&T0ACP>/7L25BX*5#>DH4&6F=G!H0"O'%KE)`+W7)!TVBW,CZX2IU! -MUYUYGN'IYR=^T=9^V"U0/H-5,O[_(2GI4AX$C[QZTO@`6M69"W;E06),8%YV1G&'Z]\Z?>JQ$`6*2&@IDRR>RWCQP`USQ2)JTY)+6 -M:8/1TT&-G_9PB._']4&]ODL/77-YEA6P[_;)&]C=2YN+HUCHA-N\$E=<",>" -M-N#CNT$^I0CD:O.[`/F=HOD+9T?'7_:TRA]KGD]@&63C494HG\Y[4\SQ(L5_ -M(C!\8:MUL"%BN:=WC?V?55<-DZ$T/`QH^[@4-8>46_W9?4")QX-4\QMD'X'6 -M&AJ!IWP!LZRWK-*@BBWS`2E-W(W+=G_LKC"QK2\J`$(+947IXN(-+(!2F1(Y`(.C[X@$\)2(+ -MO8Y;2)1B*I'+X.T=88Y6X[ON5"'NI6(OA73#9W)= -M(4B0,HRHA5P(*RU@V7IWN`4E42#)ITUH5*@/TF*60E8L>B?<`G@89/OA->%$ -M3\@$/V\;]+:?L96$K2)5CKR_'!6[@#!KJ4'&39G>#[1ZEL;3ZHO! -MP5$7-BI>')I,NVQFC@7=42#:B4+S\?YR'\9BY8:ET64P+*O1O;7O,YA%G.ZV -M.V"\)4G](G'Y>-&G54=9]QYBXON[SQJH4\!'_P-Y0^`SZ;)3^N9DWC[/VHU2 -MYD;?-S=IT(?9&+WW'\4(&2#^<%`]5IN]'P!,9VLIA2[B]:WSZ37$'] -MP.@1C)OV8`?/RYLS-MYJSFW#65>)>3?K3IZ8&(W1=EJTJQ$DT>RDM@>U;^F&8F@Z+RK$U,HWZ -MT0:9Y0408-+)-L&ZNYR>JVUR:ZPY%'Z_65SPSI:LE@U$R;+'3PC0)*>#]!0/ -MREX<:I0GX%?,>*>>7NYW.A%6BL]3]V=:`P(S_9KW:[PYJ4 -MG*+E+Z"W>5BSB%,T1(CC,_:9J+3<98$I'0?PU?!(!`JN^5H_@2O'$9_T\?=< -MSR+;APRAO#L-F>#H`9""O-3A,*VZ'^3L)09-CW,DH]YIV;OEN`GL6P<(U<^J%R)PH?&&+S"J\"&&8:^NM&]#K"7(F::1CU>I=B!:>:'^WLV'F:#,B7)3DIE:5)4V'6/>ZW,@:BGN5 -M,Q;;Y1Q<`I#Z-CMN]S-`J#XQ3^,[6[8@#W<>_.UW-M>/+$87P=Z-L[XOG"1/ -MYAW5IHN1L@%L)>:"6?A?,%)BO\JPO3AC0985[X=R%]9$Z7>B2CRL(-V6X/G@ -M`)_^:A#UERVPGC2$!\L7PE%NJQDVZ>N4R5I8AY$R:'Q-%CH91R?6V[`HIL!2S^>.8=F$[J&50/BH)&NW/'"V>FX]!Z*5:WS -M<&%70H.FT$'#XD?*!:(2[M@Q,LIN+OQ?G:-]/L(YZI@.CX30_=,4[I:U>FS' -M#:8*>"7IG3:H;YWKR#+B_SK5F426<.>(;$F1/J"-F&K'TC^$0[=.<[3104#& -MFJ/`*0.F!JO=U3]#6R@6R7*CB$G -MO,I\4<1B -MFR90GOXC^7T4'\'DI]U#MWV,D9<-F+>1SN!Q3(3^LZI69I^D.(&],=Z*3B11$VUXK00(0$@[5KKI0*5T)6![_98W$5'C\AO?_;E\>+=/&Y46 -M:CY#3P5H5R$F@!-'IYGO5=GA%$%V9\VK]^P)$SNN$0>^F?]?;6W<2%MV;2WC15_*!L_ -M6TK0C.6SU<=L'Z[>YM-M(>%&S7J55XH#NW9REF`YSW1"VJG!:*O==\!;W^6YF1UV-`L/U1A( -MS@>1'G,1YO:*X_R.'EG>Y+HF0M8-=]%R0E.=:>?D&5V7W30T'R;<%NL?W*?< -MDL3SF--=T%<XT>,0IF3H:N$Z_WYJPSO0VS3N(F']4@R2M!A^30TZ&>P%3&3 -M-N@ZX9LI:]B^`%N3=<4*!`NL;3I2\^E4\(8J3>C95H/O3C6)I[+98E:%>1E0 -ML"[S?--]7T],9$G]9CG&NT.>&[)>V2=O5.WV_U&VHDZMCSSRK'Q15-:.%`C@ -M18Z@<*EA%J8>LP7E_,T841?K,9DT[/A#KKJD@S`#+_$8LM:772T]Y]!6$H5' -M`"=_S?0W.W(05CZ.N+HX,8_[B.+@9[EM^ZH)U'+RN;TYU<`DJC"%=<47\9,P -MD.,>E$O4Z?S'JGZ8VG5$4L?SO08#(E%%_O!E=8OE],*$GXAHE`9'R+#F0QUK]YYY+1,K&=AYG$MG\7W0@Y$^6G'4_9RXJ<39ZJ-D-3&X55" -M<`].'I5ZV1?(/>+;<-JB/T3])18*T_M>+EJR1B4]Y[VM^6-%B"R^/E+_9X[. -M2Y>QD)V:)+UX51IY";BD^TA6UY]5G6< -MN)CSY[KSSU@?9$]]5Y.=#!8L#<`'V*:MZJ2.#?.H9V]))`K,\T.3H^;,C70` -M=ZS%H_:Y6,??M!\J0SPP#&<^; -M.O:2M>XF+Q?H)$3Q^$G4.\MEN*B"F2FD6D]+^SP,^+>RKJ7AG/_NSX>)_2!P -M+D`8"(D*%:)Z^.B4$1M:P%(/&6Q8U`KJ0[6=D]BXMZ./=1'\*^E -MV>S'W:\W@^CEL:%<6?X!>S([-86G/X5#QKIOC'O[YXR^\'9I>XXS7^&.7ZK/ -M'^58(?_O^LZFO.3PNWJ+A6]@506B+,!\>_94[Z#RM#N/QZLY=-E+0VH;/T>< -MNIRJ2WKWMORT6">MMH*W+).BI+O8U'E(N]6O@K:WY?$2>?9S]'7&Y+-,Q3S" -ML6NO)6`QO2_JO_Z)]`I52(]8?1G@3_/4OSTN]H_N.RVQA104?.+3]:;O'*"U_#N%)+97)B%*PW>Y98,,EG'TU77MK!P(#)"OOUU-&,R&>(Z$?*\\L6$EZ:9LG58Q>W -M)J`&;QZI$H:;$"B$5TY9(.QB/KX#9#9_+3[H7W[YT.QQX-65+LRP^K*6,A`) -M:);K1,F^D&?8;;CO\B@QZ/P>L"H]K6>/'F/WB"&-]#!1Q.F -M8N[RCXM7$+\C8;$-:R5,'JN5@6D0L&#M_,&_9PF3VCH\264?T6=FXG%HN.R6 -MXYOB4$Y_#1AA7 -M$KMK5>..X0^H5))^.?6D)8B`G\)G1$'/U*@4HN7]CBP?*A>_%J"A_,<2^3;2 -MLV^GY#UOOYN7OGS4#_#`3`FDI//.+[(BW6'#,0(GG/JY/PH9VMATDM-3?@[C<7S%1`60XP">*TNA$`J"1Y_I>Z1^!3>%&70?0_D="RY7FL/Y0E*F -MDXI3DH5]Z<(T'ZW'Q^LP/^7=R,4.3D(8ON65OD/O=IC%/:L]#_@OL\7#G0:( -MY\8P+GP(=->[_."-OS[@7[I8/*1XL2"OR6T3:MBN>_QGY_1A1GGP+4#^@+,M -M.#"#](X&"@YF+Q-R+MHP?-/\LCJ.FGDR'RQIP8LSF%Y^MR&$*#W?7Q('&TY# -M=85NFH5UK_DRFW`TW'("O5X&2UR.48I\& -M*/^*RLLN3'0MVCVX:ZF)F<#]CW?P/F!!4:"4^NW)7*(-/&8U/%3#`OW>V@U% -MUA-F_KFNA;HH9!'1:7*_PHCPLP8AT=!>;?.(F]M9/4:/*2,W]0E1[IJO@V4? -M+<+1UMA5(M7X<`E50((EKX4+R9^-NEXD3F,',..?J]JX?*'I9B#YL74N#TQ>9! -M^2?GR2Z[+J+D:L -MY0W]/4#`\C;RRDX+WD7$#XA73$_TWA1P?=7SYX\@;V8\"WY"/^`<8535-_ZQ4XV1 -MH'4C*O;$(C2HF]H/;O\;6WYQ@,;(7&CGGP11!0^3`0\5W=7-7JX'.%_$@*"8 -M6WD=Y=CSM=GQIIDW&99S/I?S<-#>>%^\P.]@NY1OY2FC:W04NS*NO86.;Q'] -MJ64>*(Q9P4%I!-T.3,)AV)=_R<)7<&?I,B;-I(N/Y",)8LUI%-UPY6:2IH>- -MJJS^`@#4SV/F$CMZ3Y.K&P680S0R5#M$A!M]4#_4U -MX1./FA\%_S='-'/0$+G@A+]+`=J?98EM<,C)$?0W_+W;;DT^*V-:S%20<3&/ -M"1@.9,\K+7)=0R3SVH32FY822"S(Y2?]1C]@OTI:AQV8"1JSI`,0>5YM$Z2E -MR>A\EOWB1.Z!9>(.8M:-*S>N@LX/9,T;DK*$:/';'L!UNI;:!>:T?B5U(G#9 -MRA[1M8=9WFF1$ZSG6A8,QV*!5&7?G>:PC/`,>490FOC?UBY@/`GVJ=`HSZ=L -M,UMFPV4/O(O$&/E<8F65CY*C&ZA79SN.!QT(9@50M583+EG4WGH9LA5 -M`6KF`Z(.@V@Z27V!PINZ$2=:1<9&B.^*XYQ8.?^$?.K?2QM\G'T,/_'I-(N@ -MIDD>\_ZF14M/DF4#!:ZRSI+N(=:I:-E^.!6DFVH\TNEX>(X4B_\C=AX4 -MQ7A0:@[=#MV#)@X_P1&W".<29H>SV0W1(D.[ZANOEJ-@?;KV(HXO1OSZ#J/F -M1\?PN`M_M:DPQPGS:_>CA.P`M>;&'0[O5N<@0P)7Q_(L1S`>(^C9(FLOQ,%/ -MB_QH4=!,X.Y\O-IA[(S6FC>F,A5$B/AQ&)'"C&UX3;*%S9J)QO?.4=%E3;=W -M"3?)E9>=)6Q$7E-)<-5#*P#JJ-&M)S43/H>AT"AS].Z03+`Z)`LV-&%ISA7\ -M!SS+RY,9I;V^"N8<6![9?R)L*!<@I2XN9^BH?M*@A.CQ+V!>PGJX"31(PM?B -MXI7"G&QQA7X/%748H`']_<#>G`EAQU^0QB-"M6E=?IXR;U*H5T"K81K(X@/7 -M^)?CC-.$V8C@!5X\+RZ>N#>HYX[>TE%0:+0$JMN!,7OL*0:=OT6`Q4,M:53X -M.5U;,_-U$)2@X;&!;NX][@'V.Z@XG'1+%Y1JV8. -M=X#9'@14A;HX='DM[GOJ/X):@EM-V-],,`=P<\EJ\!DP-UW'9X3'BYQK)B"P -M3:S68E_2,I%9Z<=8F)9YW.)^T,8PTQ<4N5BW7^+@HCT[>^2:$U_][2<,$\J9 -M1-_8-*?SZE#`$:SJ=8]*+6YE-ROO[PT)ECQ:./`2[LFZ[HO204G-1AS?^"2P -MO5#.[[I5VI))QJ\AE.3TP/ -MNVLZQ0'M;;99@HXRA88^BS=DQ1TQ/@O$&DD&`VANY* -MA=X['ZK`^E'SDX-RIUMD<'G)*^ENI=&O53M?_S_CLO3$H/V/11;/9&.OK*3- -M\](CU9I!\FNUPUV+VGJHC5R"F*0A0W'ZLKY)VT3*F4RGWSOUDRK(>*>6'Q=& -M0^3!*]CAOB^I::QZ)]L"IL[Z*!Q<_"WX^Z/`$:BAI4_I<$15V]YV -MP#+RR`%+PO7+$AT3QE%_7YP.20FQU+!2WVW)-%O)?@PW(2VE7*[%U/_R$4,< -MZG6"^CM0BL;F,N_5XJ?^9\'&TE+[/&V>Y\039%;09XH -MX8;R-'OH\5'!0'6ER_X"9'5\>F>Z`"F3G;>C+P:RH])U[P[4Q+8W!D3W\:!W -M(N>69L.D1^/FI@[6LFE.++!IJPLM+9,E'\0E[^M%14G\!XY2CH>P^_"'$SV -MB2CVJ"1.02ZN]MH/#/._S;]\Q%4I%B%F*R#5"->;_F[/`M0\J>^W8UL2:I/G -ME=,38OT^2!B>W(R:[S0,V,1ZJQG#CF+'VA1BS4\0X=?#>;:LZDYDY"@F#$3P+%9-D>0=(=Q.ZPW0CB)9POMX[BE($99/ -MONA#B15`]?L\.]5^#EBV1_U/:P;['0-#BUX.VJH#:1S1+/U#D3I,X,R4[BGA1$A&C(K04]-HJWJT&\.N$-KAH6XR:VDKPW36=R%? -M]!:Y_4M:<^L[P$).QEJ558@S(I?[T@$+5(+5OY)6]]!N+;I(83?*WP%Y\,0? -M0.,:WL1TK_8!,KF$MV,T!:1]8L#$T47+$@8VNQ!"LWUT\;.C -MR@0L4U;?-12KTNA4*S:!HF_(B4@#$)?^!60I3Y4=_\BV;8`(+>L#KTN.Y_Y8 -M25ON$'X)6!?_+`7)>*;[3^;$04>*89&"`L6X8?.IFNR\O=4%9T(9B"UZM*(4 -ME_@,;5NDR-Q3`>$,.Q-%WJ9;G7LHU^-#9GX51F#&/6E$&H^,:LSOVN?(>A3L -MI"7.TZ,86=8+R[=J*?^J*.%J=W+""/:MCQEL4DU^KB'?[TM=1=KXR"OF];'! -M)+C[B]@.LI&G#RA7SJE10YRK/Y1.I3A.NL@@"/=7@C8[X,A$_M;Z8I_6QV#> -M^/[XLB6KP9#X/I8YP9Y!UI=."8`K!`D+RIRKQ79`E&-?0@QTDE%4.&#UCN:X -MFW2_5,-.7]Q9L(REG2\\W)?@T4`0^$2OZ(4L)DXXG-6I0DD=9K=L&?]M<8^^ -MTKA=\G&RN6'3-%(RJHSH)Q:*\-VC6/S8'F9_!K6$0^WZV3@8;U:(_75U%*%Z -MAPCBH9;@>/6GVUEH=/XJG![HK/J1YJV'0M/]#'NCK4'*<6?YVQ7Z=9X!M>3?PRE4G\$ -M](EM<]TU$E,57_!5]M@A'#@T/SF6++J_'V4*(JS9+<*E9.?!2K+;[ES2]YP[ -M.$`7B!8^_;,75OFT'WW85DIA74VR8KPG/CABK#7"_[8:MOTF@E&_#+L$JM9` -M#9_CBA]GH=,+$,,#TWPS:?*`#A77/-?5*0*[66R!9UA8MJ:A6D4?K[+;>+BV -M"@4F_-WIF\:(8AR'UNNL1TF9\3D#ZP66^(%.-483DX6%A)1$70>!K^#+=N@^ -M2=NR3UU[6/U)C:K2W]!,B;-!L)1:Z6F`=3+;]V)VZ]2W95FHA-F;%'R^,R-@ -M$:9[]VY_[3XC[^#72#AT016I1'B^K5-OY6Q-UXI@_QQ,8E*D\B4G>)Q]#,#= -MVO5<&\J'BVZ.\TK=#D70O.?E.FD5+P:[MC&`XPL])\&PXI7^<0`YI1`E;9XN -MN,!/,MU?6>;!S23G$9#5`&,7N9M:=BA\T/`WS@U\N&0(777^D=^$X5@,M)A% -MVK=>Y;@*:(S/7VY`'P3NZ<(1',E)BR/G=G%#@Q-GH;E"T'M]I7.?AP.1'=8G -M`1]NKEG!'^RP:RI6U'L'M3A2$S@7=#^K8(G<3;T>X=E,\N!ZLG^'E)RU5^J< -MF`!*VX>YC*+BN08AJXN#=\H]^Q%^7&"TSH%UJB)J%:OELRZD!L8]QQQ*B4J_ -M%S"_VZQ,V$,GA[_9""96#3KSD74\/I/J34Y+VS6 -MVV2#S]?03&FW;'-%MK(]*:*(:.">6O?YNJ3&7?$+8I$8/^(5??#C.F22:-"ASKXT&#EX;9 -MA5PZ]'_L8FI9L"ZP<(":)3?%=!#--!$8DBH:?R)60.'QWAGJ"]F!EJK'I.S_ -M\D33W9E0$1&2XRC&/FD1"TY)7_KXZ^FJM)P_NO%0A4Y=G&O9&LM@R2KY"@/C -MF;0K(-W\$X4HKFV;[[W[OOKJ*^WE_4J-T7^IF1+#V/-;^M>=FW9FFEF%9?*X -MK5>EC]CJ''8S4#_LOP/Y+_VZU"=BW!=T!/3\19,6HZO^^WPV)>>18F`*83N' -MV40PX@?)Q%7674EDW*7G+)8-EJ4.:>C:NO&5BC=VS5:6<2UJB7F0?0F,"DDQ_6(XK@48350+C9[-=21UPUVNB54.1C%K4((L%(@:Z -ML2`,^_TVYCVCW4MY!W?:YV*)C]U$6('P?W41Q3$J]UG<\MB8%#NR\/#@']>. -MM*Q_2+:SF+3AL,Q&BUW_KNB@]6S<+9N51=(^KM'KW%L\V`T&VU,BW/T5!!N> -M51=<5AFQF0:TFJ^L-2A&N7JGK`[OI?N;98W_LFS#:[3:4'$@%[/)+XM(QV5* -MJY5+JIKX\``?_PIF.J1SJ^%`5,CFI?E -MJ>`B]6)39;72$*?GQOJ6"R1=6=>T`Y"&E?!',1_K;-[ -M"+P$2`:&KB+4YV>%"B%*Y0,Y>%7/E[Q=3$N&U#22?S2O_&A7!+(SW$(M%K9D -MC+PNQ&$^ZV_:>XP1#Y^VR8ZN>UQA[KP2_\EU80-NAJ8P,V8T:@4X9M+\%CP6 -MO5U=E4^*^6=<.0B#]$X6&Y.JIH&M12TO6U,[_9"5,NO;Z,-DA"K>!=*ALX;% -MLDQ`PPNB%=E""V0E[L[&R-]!F8&]N4)U<`N7AL.4Y>-985U&6RPA?&Y%3.M5 -M/5MBB+OPSU-0PF-T9!E=]H&P:C@-/QDT?8_!B\;UR"@TAIZM!UO;$3##S`_# -MUCKNI4W"&>F\^\Q[7[B^&2RQ`:X9SBW)?52O3#_NVIPO&15MN;!!U!T1VJJ+]?/3`KG -MB+LG"#&9(ND'@S@NN1LH`O_&*XXTN0C.E.#GT]>B#@;IA@8N$>Q%X:-O/#D# -M*^68#;K"A+HW@>K!A7%!(T8:KM]_DZ#6H(JL"Z567_=]%@P):WHM?P3?P2SE;"=";3,-_L@#T&# -MC?U4633F&UN"N:T+-#-2'6H#.\L1_OJ2]@LNN60&Y!*(22S.N4^TL#":8%H# -MLO[%#BC,?6^X(RIOH5ISRX?K.IR_X)J4OK>4`8G!K$"R#?<1>@Y^52HX`%3` -MM;G#9$7UJI7$,@DG7/HLDWDK4RW+Q?O2\0!?9(SN8Q=VBW&:]AC`(>O6\"SC -M8UC^%W18NO8S7!,HX7T:MJ3'7,N7R/(GL5;.]][O93*A5Q6'B?,)_US$@#=T -MYHA#^-.@@E3OV#>J3<4T,W,_@7`IGM$L4S20%V.REI-L;U>>@07\_Z`R/G]N4P0-K\#'[R3C]!I_FV)@7#LT__` -M;@M-X?_Y4>\4+'DU1/NAY_*`";MW:T1"1B$K^?J(G,3@QSNNYMA())%\OQXAS+#6B!I@J`L -M7Z'8WYSIU:-UC'F`7S%C_*3WWA;9MB-<9EE]%&H;;O-GM,^5[ML3R@4Q^4WB -MZE0N:8/U+A#:][24U?2R6&BXW3NR0=1CH:51DB//C40/^R2@H,,N(!S16L-1RIEUZ,U4`^&GWSNJ/Q -MJ4K29XPVUDYJ)YA!&6GZC&'*/XE3+M>6ZRY&HZDV/J72D,0>L.55VA4(L`;&L[K<0?C1GO!]U5%PYKS'L(;CS`RB=_^'<; -MSLZW('>M9@6VBVKA9V/,D&;MXW8$=1K)G,>C2>;PCO)V(?1YCBQ0G8C5QI)[B`E:R`,XXI.] -M&C5J>;9[JW$<::9BG@+0U%M;7:O!OOI]ZT]0Z!X]7U6'Q:"GW3.P2I)`;#:C -M!ZJ*I$;G`4J30=U0=[*XE[A/C2K-4KO>-+8I`)X*,`9$D8U2X&W5Q-D<^>'9 -MN1Z$R"RQ4&4:1TV0[>Y+8A93XV+;STT6B!A=KXXPS%=MQ='!A[XK$L^CWB1Z -MB?PS.JA8\^DI)FA%N]=10-85%0YPQ`D$%_Q1IR*A5`.@#%HI-`?>G%2T-15F -M%>7'R3?HT8W;E&K3U+PB%#"K$',(1EJ5'P.GSC4H:>ZV=W`P(\06#LN/QL+^ -M8=L8<#SXXFW/X(`XE#9E9M][_*A,[62BG03@`H,IDV]-S.W5;L\'1=A`BGSR -MA0;.:CTEKP=T?7_:O`&;).6/@5F^KNN'A)Q0S.HW=Q"-8\>[KLZ=+\0-?;^R -MY-:#'PF]2(+`-;Q"*,V?^:]6!T"]YF1;/9.XIM6P:-O-HV9T++LZ^5C -MK_TOX=$Q#U?C47=LH\F&VZ?:6QJ!_#CU/#*:\=BL_'`GL\3ZJ!:.U?`)-D1= -M.BBTO$7XR6*MIWVNLHQ"09@\SE/"/7WLTX7AB=>F'EHB!_.Z9)N -M1B^1<#"&H@/88KEDF:!Y!0^?SY#^`4[R-GSG8EQA?`ZPZ)FC]^RL_JR#8 -M@-0)>"@8GKB".,KJ$6!:^"I;J(Q*W=5H7?V+C@%#7?GC9!,LC6 -M_^-S8U;MK,*HIOK]$O70*R)K?&'I[$B_NQ)41>I$$OR6Z(B&ZAO;Y77KZ1*T -M;5,VK*3[Q?8`Y6WD02=!9ZYJ8']N."<#\&7-"HU.:J26PP<=X]9S#V1-ES:" -M?U5(&J\B'>E%$R>,7LMUCYQ+YMV`8;\7X@W)-&[>TC!MZQBIW7E5[+)ZE-W! -M"=N&L3(2#@':"YT':BRS`6N3F'3Z-(K[65AK*C&W>+53!PV%W8^M]=`N,8%( -MLTX$NP6L1^";.1,JW?4[R'/IO,<#DE^M;M-($BO=%6@*PKEGQ@Y'JJWE)+S" -MM)"Q%0WB0L<+5$U<%?U#?K=@\$C(F1A3>;R?B?^,;TCSM$]*\&HJ.8_&,.L5HG>;P\S'#%]M3GE6@,_-\7+ -MY%OI)>AEG/.V-?]IB,(_5B""?#"F`LB[^>`O!4[Y%S^$R-+$F9O -MI'YV?M<6G8_NQ_G4NX^H>PN_LFP\."X2=V(GWT7.R52@7/ -M63+&PC]*?UX;.#!_U,>"IC8'3!+8,0,:S(V$*^RT&,8RMDV_,=@D9B3!T:II -M6?M!]%YNA%W#=VBQRD-O2:,?DLI_(S,SL!YEJ(QKJ#^^.]'&T:]!*@DTE#F- -M!'B9"$X*BX&.*;@(\5MB42A5#BO04M^>[2(Q)DC^&_VY/OIPXY173[K4ETOZ -MH`@8;FP5G8D-IV4V5EGSX2P'S6H70)#+[L-9CGDV(+,!4IO0"I;?F$)>UX#L -M25L?<*)%V9:EE&PHSFN7S=)=9.0!N?`28B1U$\;7Y_P>]K-HL?4-U3":9-W; -M!8B`)A<.V`N?GMCNV7#I6Z"`X1[73/UJCC\!+WO!V3N'7 -M0#C>[_MXM0&\T.C'66NCE/])QN58IB1?UFDI[=\:C_I-FA,5(DM]N\-SX?0R -M%")*NQ-F3O/`X.MW'1=V#T&LN'A!;7Q#',O0L9&&K^=9%EH;78E4R!^6&'U_ -MF=-N!MWKCWET%\_C5L$W]@!!23/^J-(Y!,V<%I1V7`5BLP:=E6/OCL9=XC>D.K9KI0L=`/`- -MF0)6-HPO&]&S-3R$'=>($/.V#WYM_DT-:*$G-NV2O$G6'KP3&69<+RD*5^3NC(,E<_5J_:7KD,5 -MJ#P`W\5*ZG>Z2Q.5"8L7369\A]8 -M@0!IL.5C)@,;D8_7(;+=MP6"\G$XQM-[_>!M_Z?"WES:-,&W#:$*BWUQAVF\ -M>.;$4?MI_9UE[DV&,YF?J67AXVV1%"R.Q%EF!@`J,(+O?YW8:F$0U[39'>T8*WG^DN5QA)%RK:@N\GW!^.[RO!4ZE -MS/*!F6E2Q_('PTB6+'S]6Z(]?7HJD;`)Y$J\M1AE69\HD,BO+B"05SLM=BE* -MCE0_>+Z##$J]H*LD@."6S&J)X1,^W:=G^V`QT*N)50D/P.6:_`W@.]I';P#? -MK-)?#.53J?D#5;H0;E.#%\JHU[YC`9',CXXFJ*"D]'4^L0R@D,4Z[[*+95+? -M24I(W3J7ZT&D_F'V9[I1&F\2@%P&H37^@.%Z?RS#IOK\S>Z$DY)/U0]5@A.> -M#YCB+),U)^WNX4#A[R*EY0FE%2H!+JY]#D1:KV;(8.(X+<-K/`MEJ_1B&61A -MB6TS$\RRBBLXXP5#(9.RM_'[5MF"QY1A035JDNB= -M@^R!\!/KN1S,QIW?8M)=TLH+M49X=Q:K4&?PK/I)IA["'4&^1'O7PO5CPAGV -M":J;\#/`RPB_2`\`J-3Y006LB4D&")]`QSWS\KC*U`\[%".HJ47!IE++ -M55L,2PQ]C^$J0)X\\/9;!>@9AM];W6JE?FJ-+]Q!:B.]PA@_V"7X\DEUMET/ -M^$PH3[7B_N-8'R-!K'.A_P1E$W[+V&>N]@T^I@ZK07(P.0TH*"+PQ;?M_2@6 -M#+&%$S^37'VPD4D&O0\(I"W9JMOEJ#QD)$U,K+S<*<%8[W!A\I$!VI\9+.^S -MN\&Q$%Q,"$P':N_`M$5M1",N?Y>8\+XS@$$33\FUJ9*F#XK+(^-_*K -M0?DAN3/UB,O:3LI'?S9L;IA1TR;1;+`3I&7(4?#4!'N2%9*VD?0;(3CS6?46 -M/SK4\I:G&)-GO\)^#3JTDV`/4`@)C"K3#T=7F+^1;29&#O;CMC1A0/6'?.(V -M/"D`T,JA`9K_]4$1AMZ$VV+`>[E;'K(/><$L(2EBROKW/\R%S>(77_ -M']AV>^QD]#N%W1]4XL2TU2O,_7241U>\FNI.I-L!P'AB.YH]N?M`_RU7T6;J -M;IPZ&Y2HM5XA'&O)UKE$(3Z1.<()IURE%9I(%"/2)LN.3+"0JCD867ZR'-KB -M(V86^)I:;FB>;"QE/,V666QV2PP?:J$$U@R\,,B)[61\"*CPW8Y:P+/15.;U -M:&OYV845OPCOG4U7GHV+)0$>VTOV=?M]Z3ZFA=1#OG("IHKR.U\\,[8[/CGN -MD&C_&+NA))ZF]0T]]_$]3H2$RVP.CE*9'5V(*)=SN1AH>%(&7Q7\*D0M$+<< -M:[BX+T.U9WWZF)%WA0`2*V0B6IC7WF=^8]T:-E1E9\GX)2SG62*4VL=X-^!7 -MD419`SP)1#]BL$-IS6VHL-*>PX[NBK>[D%DN7W`UV'^KN2U'6P/S:P#AXS^& -M"SG7VTUX44IQ*I43?5B+BV*?)NHTV&H17T'`&&FK=<[(EKQ06^5664WGMR)=*;JJ226?SH!,)Y8[3+JQOUAD51/^^M0R4; -MX``K'ZQ!4A6C5%5,AMM!A5.S4L@(+I]9@U;A^9S1:)H.C)SO+JU&]^Z,T:&9-!*= -M5]&%V&9`K`TK"$3G,KE<+&3^6U1;<]HRD"Q#&&BPVI?25T`^V8.:UTTN,$I3Y5-P-M,JI57OC7`+%ITW58>EMV9=P_I#OX8 -M_LX1/\\ZZP,6#FBR: -M`XC)E`V7$/@;Q5=\%-T_($'4LVK.77Z9PFU%+*;UX=8O9J/F8*BM7BQ>M3JQ -M#-$AM&Q-(8.`3-<-P()YA7G4W%_/7Z"L047Q%=*:6!0;!XO8V\B*20L,0_'X -M[QB/-EE]A'`'4),`(O\)W%M'"\O'E!YVUJ6[37<')JLU5/^MX -MR?M8NBCA6_00;,PY#!@2;=%P/@_#]9<]]!:DH8,&8EJ=7FXE<=A=QI+"#-;3 -M>[.JB72TC$&(K`\U=1@'^)42P\B41^?#&0^]CF#IJ<8SB51P./B_+PB0\,AH -M8#F9I]L?>C6Z1U,,M*HL1(Q'!N)G=GD1KI-XS\KS?!*5/?7--!DA!E<(G7"5 -M&?6N67CC`4?SZYY*:C4ND0DB"84("1#<(*M3?Z[3.)6;[9Q)>MT0PQO234R( -M8WW'+7'!+HUU(*)OGD=O;H@&*MA;$*D;:F4%X!JAM)F@,,F(E*8=>1@C895Q -MBT=;R//YQ+CP/L[@TJ(\G92QB5QKR,=2Y]_2ZVQ7FKUA8>.QK]R_@3W$H0_]!O\2PBJ@H?_C`$H*W1?/>DK%T#4")Z[H40:D:P>F/-=^&@I;Z=J"6[`-,V&;SL'MRNU_R9#\A -M%+O!CG+>U6'7_WU_-S#/L:&@6[>U"Q/-V9TP,I85)ZH>ABAZ2>$W853I?SG) -M\'B^NKUU'+KZ"9JV"8"0(EV<)*%A29>(*FZHLIP7;#UCP%7%)A01[9^8T?QF -MRGN4P&>6[#/V&+=+K[E"Y0]N@(+^ZU,)'1KMH9:KZ<# -MRNM+!IE!;*,=C\O^\G-C@0RGS"DL7+8)3C4Q+!4(1K`\4I-^!<3$!O1#-[^: -ML`/\JNM=]Z;$+5_D>X%J3Y&N5O]^QB2I=HOA2/GR3\4ZN -M-[RO;53!3S-9+::U3F:2;K$A'#BHZP;Q(A4X1I*HU9TV?9)":2$.S:<4E9PE -M5F.5Z7(,-W5@JYNR^P46CD7K8+\RT[[\M9&[!N/RE?NIO&XMB<,EWDR!##!# -M>`;J*]=)1ELZ1K.R+(XDX9G?I#XDO_%D5A/N5D!VF#=4_P*44/&1X?!?6IO; -M)!![LE0N*[4OJS'[G,]$J[DH1[2M4G75+P.&-\,NJD49_G*T!RWX58#.'O8D -MW57+%^Z#%>*HE+=NVQ.+R)8D-ANL:V_#@5`3RE@'3'JY1([$1@5DL6_9>8]Z -M"F5QN5&84@/:40_KK_43[3Q7?HRM"]\&JOF_9:YX;F>1[9+X.5PR*/06E':]:@,?@?EFO+ -M];G#T!HRE)>M439&CG-?(T4Y9P7H-.5W0I+#6*WLJL':/3MWY%LP75\,V^TE -MAD">P#;_8)@!M_0OMN!%RH(`]IEJ'#]]TOUKG8\VN1SFJ]#0U)9^^U1U+5[. -MW_=IZZOG570(_;SOVD?#N,_:V`6JOWQ-+K3L!V_3W%DKFJ\_DNDDA\R@^[CN -M1H7E-S#DA9?QU"__"FFW;!XVDP3UGT]?-&>,43,N4U>A7Z^X_#"F0=RMX[H, -MBY,L;QES5W&#[5/6,6\:\1-H#[3(TBC1?0L4!M=DX-X%G)MW>2X^X -MMUJ5"L8OU[IMIAPTOT3C5E9-+F'??Z82[&4K4=+]Z'I*1<,<<545>!;D_U8X -MJ6D[45[>3Y@6@M04"S]SV0%'T[1OD.H:_GTDEH?T\&ROUJ=K`58S*3/$,&()<6"J+4J%2QVV4 -M'VB$*Z\LL(D-ES*X3BU?JIL$Y#]JHB&.7\"<+HVAAF3+26M:\#]<9TO!6TM[ -M$24=OG$`)M$CAA:NA3Q=RU_(1O"+\I#4$S<3\`(1]^/&F``D_[.[*'?TH-MB(0L#WW?N7'IV&5@DX/@R:)EW_S3SK? -MX-O?7DNN@'>GV=`7`X.+)O<7)=@E+_U4_B??[V*$3J`ERQ25($S -MA+1\L*2ZAQ2*[]1B>AA#F>($@0F/MFWBA.607M8^TX,]]/W[T8H:%8^.?%X; -MY3AU-(>28%P/X@;\AC&C^_5VJ2S7_Z1J -MQ^[''T<_PI#F*'$A-K*BSS9OVJO530:`^V"00@H[?.(??=5&3=EIN6B>E`36 -M,PQ.V*[6NA>3&S:O.L$DQ/3_(T)OXUE7PJF#_@R=)LZ87SZPF%;=,(L#N4H) -M2.(&7:38P\%[6:QII_1VYX4[>-#W0P"%9)]&QFD6=B<']YUQR<[.<#DFI=OM -M\RFP7FRSEL0\4A -MJ;SQ(%-ET+C[#N31^^8E0V0O=]--!S^3)%VG@[,H(=PP0F!MI[SDOC"0B/I0 -M5%4]DUX@*>+1&B[GH]_?#4!QRTD+Q%3GX"8"NFS^TU%SKV%#U+=+"W$R,X6X -MD]<-7N@_1WI^VB?[%^?FB44V#KV]MJ5?4DPK6_(PPG93FWL2]08]'O>,EQV0 -M^,Y9&P)[XAC_=:#PR',O86:`\`[0+%K[7,I2D47^JE@Q="QE8FX]U -M2Y@I&ESD=Z_=-+W;;YGR7>\@`&YFQVFWK)7PRE.H6`>-/K$&**QSM4?1+R0' -MB"W^[/I$^9$?DH+)G&P-B.P*Y,G+F71&P,Y#T9@7S),!I197QG#/#_'"A;WN -M/6@GL"5W[4PR)PYHNDN-?3/V0XYUU6G+\ -M=0DK5O$T6.[J7?G]PO<)Q63^601*'0]H5R?2Q=B\OU7!)QQZHI[483_'DGK[ -MSEKF-[M$5C.+3(W$'5HU(4?U,LL0AZP%0JC+ZB@J+;G9Y@;4%8#*C\O_L! -ME`I])RT5:-9T0(Q\N_/!I'`-5Q%B5Y#45*M9.3S@MM_MB^$I2B)C^B&NF2IH7#`B91V=/J -M2$NE5^0H*XV7%WF,W=LM_ET8YLBHI(24$&H5[N_+73?D9V[C'DVBR(@D0O2! -M$`0_$SB0KC],DX8`\'F$C*4?PE@I+#2SDZXR6>1W+_?LNOH7LI=\N8&6]%H) -M?H(7IK?CMJIP3:LK42D$KGU@CUGV#87WU3IF%SS#20E-!"CKTEVT&C:8%+NN -M0+1=U)RF">WW\\[>[BQUUK#G/.UF61IUJ-MF6GIGKK"XNL7MI=$#5T=-4=.^ -M'G/EL)\O*UV@#'CQ`MHX3USWQ)B`Q*WM7_-TSMJ15J5/?.?JI0;P51&'U*`A -MA$-=I+>E+ZUM(%=@\=2F';FIS^]!'-NZP8BD=KC[&S$R)/K$A$6,PW,M3:C3 -MXK,&NU,I).4L2DFK)C'")KRNPB_P_\%H$M&5D5RV4N54%$3G^LGC?+V8!E8S(?8]YH:.^'KZFM69;T^S3]\;0$[">'5Y -M4&F;)PKQNP125/A(3[:F][_ZZFBB,+M>^Z._:[CY8_`L`LDL:D!>4R)\+&`F -ML-2\0?WA9,B9`:O8D)&P;C22ILHAMO*U&'&0"?CW5VXNXBED*[T7:1!FFC)X -MDW'E;6HZU_(2<]A!KOKQY>S?IMWFH1A;P%V8)9+2QG7D_;\X*XDBKT19Q!DHD"M1%6[Q& -MNI7W+YBC^&Y5![>,3+@<_$;MENEQXH@%P%6_U0-DM(JD"W@#O2GF6AP8RBID -MA6J?M0KS*]6XV&U0W5W[W1QI9.>T]9H>^KIF>2I5/;TA@!&@4B=/N*9ZVWP` -MM/80Q>711[`)]&.\.X_D_.-ZPHX7&/X".P'8*.9.F4*STA-C;.F:S7C=*,JT -M1[^),("&+FY"2$`UOKK*-LT$`!Z#I'F+G+5"#`8B*$VQ@H/\ -M;2C,@=/NBFL8,O/#*CA5W:L-]<<5NQSPQ?^><>W\HLIWCM]U#L*3[FW^V)41 -M/EML<([^4`#3YE>!JYY.:3[-KJU2B=_$,9"<\'K'\7S!BX%U@SU!CI$'%R(X -MW43X@)54*E%8TER\+%*'.;Y2F%0YN&X4B\/LID?K -M]$T)J0LC]?Q7,G00![AU;6;S=18K.:8V3-98;H9K#?KYF6?-`L&:V>E/R+.B -M0KK@>INQ\WSZVU:N^+^U].6@FQ -MM)&<'4LIZA+1`X)_:E$0B(+`[E.NW(7(7*CQ -MZ#DD6+M>16C#93`Z[UI%DS]^*F00=_],R_IQLO>A8.\EOB1<,!I;>0;SN%X/ -MXAP5NU'XG/5HG6A6WG(E"MO)!P8PJ2[.$-$O0-]6,/2R[,&]5&9C727Z'NLU -M$^9OF,HD_!GHZG"X*CL[?-Z(^7(&F@WT.04TO[L>UPVY)N:5+^56;74R,>,N*.\-V[5."'NF=4(VP\47=?DD; -M7MT?/;SXQ$[,$RLQ>IM!B;E]7N&X5B,V])'_J?\Y+Y2$ZN-UZSE.]'FXQS2; -MFE"YBMG+2%V8&A"X:(M(KZ(+9:HBR'E^3LFE,NXPU.[A*N0_Y+(6,W -M':ZM6>Y752HD:303NO;0#BHEG.`NHRY3G!P8_82_'Z8H^H$?B1N6T6;_Q55`FRO$4;\ -ME=B8)\A<_W5S]52I`1T4XO;RE`&OZD=*W3A*=R20"IW$8!/F@38>)__%A[7" -MZ9=5[4-@C17A)AVC%'!IQ,JFYNNVG%2>%.]@=]H`B"ZM0UDN*9>`P$(P/C0H -MC'HYK':8?T-$`O5ST:PY.)"&^.KW"%T0`$SNAP69D!G7+_@$%[_N,8!=DPS_ -MSJSXB^.J2@DTO:#3X>U5A2Q7)ATC>CP05PC-15XC0J!10@F30$?-^5]EOCS1@TM8'5;)\I&4^G_9L3OG# -M`I.LZ8>(&YERRV4^D`]T[2JJBJI588?5O^:X_IZ<"X`#GF;[M9+V&$:RM=^S -MHKH'J9T`_"PCW`V,0ZY90*C21.U@TW/[5R[%@[V!6Y@`ES1,OSBA?!"QO3B& -MD>-RB5;.8Z,@$PG`C?C",C>J;B%I6SD=@3:A:8G#7>8G(6D#K<"PE!)Y`AK$ -MCL^`;S#4K8K52'/2#I#>^T&TLJ,BE^7W]!JJ,9L>23?1TT\*J.'0763!:4H)K?/4;^9XKJ!OMI?U_^/U"X>HQ1 -MC%;-XZTDY&Z^Z)9XH[M+?UT/AH!3%UJ\A@J5.B=*8&LE1B3\>"1G_RF?-VB@ -M>+`,M>?8T_:+*2J3*#K,`U62G@0>!J@_6>]<@D18[>Q_"$'DZ$I/`=)@<>5D -M9((%2['-]_I&8IV.2MBIW($\RR9,3/5Y)@@_#5;&B!!W3\TN)^63QF`)!CR=']&V/O&?J5(6.L1&LH>"-5D;&J]=-XO.\_(BGYQ1>!' -M_,E$,OV3)6WH]*IV?P8:ZN0:V8B#XO+P6XEM4F8:*U7H61BQJT9,6OJ%1O+8 -M=>>"_B@<1H"FZ//!!UMZ;,>._-A0&S0J+5J(:KIOYQG-R7N#ZQ@I)Q6)A6\G -MA_0'A(*1Y-TI[8E,%VIGF"R).42?MHJ-Z-F/BT:89\2,L%J" -MAA,-ETF?TCF-)PV*-S%[IA>'+XP;4F%51U9BFEG;^"4-NHC#"\TV-JWVK.(+\%6SN7EWMEX?B5":?HLG>`*E3)R'-K_]]/,`\`6(#,AI6?D8]053 -MSSA3OH(G\G4BAR!1Q0`7<+\!,K<<<'5YEJFMD:#K^[.5R#V'A,;$>I],N=P+ -M"-8L8L+!8)/\(!E=8Q\/3)1X",>NM_`#^30N"_X"8TH(>=C"C#H&YAR9H\Q$ -MRT-^/@$-.O:9'67";RU6UGS*YN/\I0VG/H#A^98+;WBCLE;>TX.A4AD"9HTH -M0/C`_0*>9RILUKYS%8<0+XX2E63?;&;L/,9)8F;YP$JWW>K3K%%/*J/@#L$` -MYT6\&%U.(F!:#R.0S632$[GZQ3K5N2"EQ*W&,`H*A@^+/.4VAE+-F;B4QD*C -M;XCWI3`IL>8,]&$*3^E<>OEX<,$(^K-G -M_O\8;.Z14H=^JYX?M8VRN-9*-(.SX_0:&"A>>S@0?[C+TQ-&3F"YJ^7^@O7/ -M1^0\L%^32];]]EV::N4O:%RE:7*]C#@",H/3_41C5T -M"$*KO@NJ'#-L0JD2I?V0OFS.4.43+5T5$KV1ZJ7[4B9^-/41O7\K/,)O:!H( -M4@RZ-XRZK\9;-M_@PAN_TI/[AM+ -M_5?X8V3HC$Q8GIFG6_5&ZXPMT\"G5,,3Y48OYL::#E/VNYQ9,I(`3#*%G5DX -MB?%9N](^;]Q$[A_QV:O^N@JUSR$<>"':7'(KML\\%'2;OKL&K6PML1S)7[E% -MPQR.@=V>SD"_AQSL9Y#8US\I0*SFB+MOW(^H$&(:L,[I;NNN;92:A2\>#9<6 -M)U>],4LZC=8:$W">Y](?`4U_K[!"?7)K*]+O2P:5%BF`=6-N6>8844K=\O<( -MM&;9RAH2KO=8[0OI!Y-F1W7M=5ECY\I9(FR]M.DOM2 -MQ:<=A#)2=>H251#*^?*];XRS2<.I3?3^DG6>BIMW3S\6%C!^$$;U?.R:!GME -M-B;0Z+:B69!Y<$_5>KB(7W'Y^(JU,`K>I"+HA^O04E5"W]WL;ZS_=2I40#,^ -MU_$*[9D<*]IW?TD]](''(!SJTJIOB2FXGNCV;YH`\)$'P[_$I/@Y;#*VBYMUV.`*@0ND&C?HG#L -MDH[=VI7(:.N6^9@#+%$V;QL_[,P4&1\7M*DL"JR`LL@ILQ-`8YFTU'8^E`93 -M\=]Y:'@I)U"G%^8H1HJBZ\,D0Z#;/ZO#I/EEN1*LK8:!9XED;9]%W"4\N\BJ -M08+\BQTQ`NO%<0D>19BB@XJ.`U*FT!-'T?D$/_U<$3%VJ.^D2F?"]]GZ<)0/ -M?:H`3IUBR/UGA-#R^@T10'#,6BM,\/T9+KT\@$VR/0/AF@D4C)^ -MIU`X,0`I`J8D&K;%8;=1%2'?:(]KLYUA["@"0^67\O5K`,E>'+-AU3.V*A8L-\9$RVC5,M<_J?D]@=W5I15SIX.3O^?O22\.01/(% -MLP)(#-BZ!+ZF<0'3@T%V]IKV?1%N46O%,Y:WPKZ\22J4S0`K-,AI)1=] -M07ZZP[`A&I>!?(C>J6%R3@#N&X(CAY96XVVF!%\=:JS.)MR^6T1"?-C?L0?_ -M\55*_7H`MU1$E!FON$#AW-;#^''%JI-WJ+UTX6^3T@79C(^PD9I;=C$<,.3R -M5>+1^G_//!W(=G'_7E;/K&WW@PZOMW,>U^ -M_&6#TKX+EFTE`"X^8]X@9;>DQ&URYFANMXQCDVLV\_D@"H=68NS73;4M@24_ -MW;=[<<>X.`[!'+K&0J!'*HS"1+J294H2/AAW.'$Z:QYTLB5*(Z<&U&0CVQIP -MGH/%AVO:S0Z8Y9&I4C*MN#R6.>5;Q#F.2C1`0;9SQP)?*\$SF!54`*/)@*#= -M1:9-C0O\[S_VS(%KX^X`WRIJ="A6"@`[$'@;4LYYQ&%R`U]8)REJW+^@5JZ; -MTDKT+NP4K[QBUU?R71^]R@36=PF]\Z8ZD.(>Y325^.%,Q4(_\$5)KU3*'T-H -M/X(>;QWSQ``>/G460Y8Y>P`])/?7^&N;"S3I1NMG�ZVI2,C,N,[FUQ6?[& -M%WY'2L"N9R;$#&E;*D.L*$*4:^9?ZMO6U2BO@;12">>?W!5S6T)6^[=]K#A0BRAKJ7J7/5Q*\C0P-@F8`3KND//3/^U&GUU1NN@-&9_=T_E)?4S -MF$PA)9*>#.-^5/G@_O9AZ5]6QPS+%T&_:M!V^N?+ -MM+=;[&WW+/9,06AQO)O=A$LU3.72*2D!A=TBSC:MJ3#^_AHEI+(4`_2Y]+MPQ&;&,L!\[MZU11GSQZKFXY( -M&U6NA:QVG"S0_U+>]4/H`46PZ@!4;B-#A(`94E,)L""[^,\Q_*UK^++5/SR@ -M,S?]"_5(JQMAG<&WBWKZFJ$0?#_63[>EN;-U=[#=J%MNNLDDYKN)5S)@532/ -M`U;[SS[[J*H%[]3<(ZFV2/6Z&Z3E.1L)^2ISXT/S'2F+4+YK$YY`C+,M6"(S -M@;,Q_AVG@[BE3$>IU3`OE:#B3=4Y1*ZM)ODP0JFG$K:QLK](;NF"-!'7)/G] -MC.+]-`J8:D?@_VA2_LMGN)L`*`=M_MU3;#2G/_NN7K:#WU:7DWR1EE\K3L3+ -M?I./G<(J'Z5((H]2Q;$WF=7XP'@V@`I-"^\NCP\1. -M(??+I%N6?2*`RG[%.S4_S)]6NGK.ILPS8&`IJ++2M"_16\5.NO:,YEN -M>L&KZ74*]/3GLNOC3&!X"- -M7)(KC`@;(A_E[TIE\[]=M@!1_68@[A*7\'Y(R`YQ>BA=')@_1X`GPY)*:8-! -MK(I=._1]](ZD6%/D.=$D.8/1X2[A.M/NL06(%^;)&W0V#1`[HM1I^C[*QBJ) -M6(@<<7&.QK*;BN%E:;BOI>.(^_3'N?29"=FV+2V%_^3,8$K+TWF;_S8&W^B& -M0\`ESO90]T+`6?(?Z>2Q]A%]"R_0I28E#M\OZLM]$@U96MTW#\O,SK(B\"_Q -M6N//XK`'O-=^\8@W,TH1:7CYA*]C!B"^H[:D689%C+#,9:`)@%A?\18;-^47@S%76SN7$F0%&F_G7RY4/Z>G!OWWI=UA(R[9GW9[U<)+N*_F -M9*">-X%;X,TT>"1^Q):?@HZ\>TC3Y>'$#)I0([D(-LI:&'()3^,TFE6V0K3_ -M@O+]\VZ33\DF#8L@XB@Q9/+6GC+F$TXP3!E#)\!$F?$ -MNG#3O9`MEE3YS`RQ/>_5^K)>"`V2CVO6/RA#+?8*2CJO(J6=@35=?+S4Z'.T -MH!4),&PMT6,7!-%+K;S&H@@U1M\A+-/_C1QZ;DE$D'+1Y"FN/(6!'V^]V33P -MC7^SEAX*:&MV">)!5]CZ&H6.NMD:]2%QK3F((UFA5-YI+W;J1KM?Z%0F[&>` -MV-U9]PQ`4+:HEM\7Z,FRRO4UG%^7NI&FQ,3RA\>)%B^<=:V'^P0:%RRH/N"S -M'85XT.Y!_H1CR9QDB*<%BRB4HH-/M*3EI[1-.)'^OT3&EJ:(R$H-\X#K,K^! -M>ASA%2I85%OC,_Y'5KIG'@'D-.=:OYSX<"#N;/7R8H0"^9ID%)L'6ZWWSGSD -MN"TREQ<=+?`P`4US)/RVT]8ATN/Q:C%RET:*RH3KW>DO)_@1I-0*+6L")L`? -M'VDGP-N[F3BAG&I^[5.L_T]79U'QEB7_[K>;!RTBE^Z9U\G*U\?.'^L/"[$# -M8*]R@6=U3`Y -MK$>?I#-=V^H\R^,6?*-1Z'2?D*'[JB3<1_B3KE"Y$']K8#,`-)9"6)F%YU)E=3[808.M32#XQ]5UU'] -M\=NNF$J!;-4?-2[>OGUH#2(JWZ=H%(V#/UN$FB"/L=-E4,+_;R1]_^Z%E./% -M(4Q0JW&^CNGF%;!\K(L=BH]P+ -MJ%G2H,;>:9'W63`+IH#@`Y*T'KHVH)C[6RCX;>K#E5TR5,["P"A:PWZC=C44 -M+A=@?^Q*G%3Y8#]D:.&O]&B4WRF52Z+W%RE@V(!)'Z#YP&]8WOK?8\K="E\; -M$RN.(->]%0@6U0TALAKP4CC,\\@[0;.8XG(>CL;`'.>R4,\WM<]9SUUG?+,# -MU1X2,-Y=4;OK2.]+O$G8V;D.Y5_IEI&T<6YX<"H!,PW%2>/0PSA*`C5.5F/2 -ML`$53Y(-Y?]\EE1G1/W(1-D*+&W&!X1SQVUJ\7GL#&G47'T-W_1Q8H[/"*L@4L< -M63HB^DDG-5&+$2_\`"%H)G'1NV?"-%)M1(:4I_?<@.C!T$:0K5VXB`VY8/YQ -M&"GNPNZ[UV#9"'W%89=HN?^P<+ZJ;QUWE1!)[1@.6>R&W9EQ1?^&*3G_I7$N -MW@!#4R:2_\?V(#@@0.6*,:SU7/A:IP[H7=&TXHM(AGV>`2CK?()U6ZT$=34: -ME3[BKA;N& -M&!9D=0A32]1;3[VB'"I,IKF+O7\4CR:) -M"J"9_/1#Y\',VW4'.7"8#5*T=+IDU[$7YBFH0GT7'Z\,3=WC&R6-+Z519$N* -M(WI'8GX2\YY$T:JHZ+AY`G3Z@3Z^A`,4#M6MRPXA*@JS24PW$AX\ZC837;2@ -MH$!'N5I>,7Q@>K",2,N-N@YZX:,&6]QE/EKG"CW@JE$S,Q),.AR!)V')0*8( -MG(D2F,:I14XU5O(>XRVF%1BT,Z@X=LYY+(ZQ@X9K=*C\',"G4H0]5.XX9\TU -M-"@!S=ECD!]]F<:>X>&.-P4`&K\7@296YI$1-+MNJ+0@31R(/\R9OO2+F0,TLT;!KV)600>] -ME[A9Y/6S4G>.&/M_/F[XI$G?B*&^S5Y=^)QJ30%O%WO=FO^E\SO/+FQ$1_$W3U3(M[MMDGE&-BNAT\VJ#8<&90/MD&)`?!.K'-!:CH?2L[^=NO'9,6;M5#@AU%Z7SC$ -M-=>;[7J3K::_9@;+DL;B.V?R8L7D"8R[[56CVRU(KF/BBXNY!=C_(>47-,^E -MH\4[OG$K@]KN-FM9A==$&3<9&RT?JWDMK<$KGU>(TG`7ION569YR-LD0D#\5 -M.3Y":A#)+#?`X#%;[!^<#K[J.E.5L4ZOJ[W1U+M_;H[^C7 -M&LM-QM^=6B;E!QH)O#1ZEX+)N;!]K89%8`X%;;OE.U"MO!B[7/.DAD488_V( -M1^1'S(3`QVG-4^01'^U"LH4(YRP/13Q44ADO2Z@_4`&$W(;D,"@8_HUJ/K/) -MA8@9P1F1A6JH%H2`Q7MU+,HDTGX]9'JH/>W;VMBZ,%_@%"V9]);D#?EOA6 -MTSTSW/TE%?W21D8,&?+5]TE\QI?8XM-@LCP?8%QL-6*/UU;F;@^9H5YCWZ\[ -MD6]H;',Q@IMY<"F)@#([MK'9GQ@/@E`=CF83D/WS(MM";'V#Y`573%).>C92K -M-B#A.LP6L^8[YV`*O+ -MX2J/`XDV'=71+I8`\X5C%H6)F#MET0F!1/E$.*PYXW>/1_4/PF7#-CH7?'[< -MXCT1@(L'2ZDGK8O,86:'SE^V&?NZ339#VCA?DOL_/&HX3B[BBNW3UCL+7NM* -MTQ61+?2O8;W?2->8]8F_ZZK`)&?<>\TP?@!.16#J6+E)?=Y:#U#F5\B/[K[& -MC)N6WL'45Q%=*YR.ITP5=SN7(+RW,2@)!1A.`A369:;+GDE@= -MF=WXB:@QF;V_D.*!T!I+B8TTJH,*[FLHADSE6(:XV1T9$;5-]PR!2*Q2:JT, -MU8"%/!O%X+-^!XBE]B8VT%L@8K7&_H(:T,^.>]RNO`>BVJG.6S?N4!]$X$82 -M)*CX14D*VM'.41_HQD@:4(ZC!)K;T/')KV?.XZRSLGE'A[PU7(J$(/8@(P/J%K;E)NCQ+C#DR] -MUC*Z9Z%18>G!LRN!?M>6>MQ`$1\LY@N*WU'PW=R.RW=?`AZ9;N -M6Y059*+-1IX-!FRSTE-4")KXP':X(&7ND>E`\-0C))GLC%'?:J-(-#/V<)@T -MJW=M3KKQ7M+UZA!B6CFB^Z<5,*C"J.;369RL5KJ9HE9!?E)U"?(]:R,ZYE\P -ME*J4'\4SG$V4OQ[F%@'U`"@C),H\\O9C)@C391)X?G4,Y:`?,5JV-^%UL4'" -M^HFQ)`0=H=C\;GF88)VJT0T6=M>#:X[SS+K. -MKZ=!S4%*$%;B/GY\O]`P^[M75\(4K`I>6H_HCY@Q(E2Y]5]'=#MS%=,QUE"S -MTK1_QICT]U.L@;454+5>\G*_-NITC1]$@V,*KUJ"*.O1K$7-B^_:."`^Y$QH -M9/(=/[T-HL^2>E_(5W@T#&-SY19L/%VSGA;GJZDOS&QU$K/S0$U7E"B?].M# -M6N)B@ND*W!P`*KK>1HFZ4I14C$*L]L?!NSU?T[;)R5C=!FG>SKT(-TZY'#6EO+QIKR0WI!.?_E)ZOSH -M!K#%D24=EXH%&S$,N#Z@SF>KQQ>V$#SH/M.YPE -MK:"CAR':OQ#19D+!7?C+X`P?'N9D)'Z[U3T!8H(E;I0.\\/,(SALV.T`A.:U -M*::Q.`47CH+>3F2LWXT!(.`IEUD,1.IEBJP])/Y@!N0/7\79:2"CHSQ3#NTN -MQ\ES4M:R.:=4UA(IHTUO@U0O\#DTH*;5/M:&SB41EK4@^YY+3=U,#7XZHJ@R -MFY'0\*=P,,7&]I5>IR^Q'+/AI+Y$SRA;@#!C+>IB&P5/_<-C:J0Y2.K3RJWIV7&-^O0BMS -MT,0H0EEY?,0%-!J(BT)!:8-W5A*RW4;FR/[QGK`\2)YJD59/&Q&/HH+34&1[1345"WE0@3V+?`L.G/VB`MFTNUN -M'V\=Q?!"[K]4S>'$\%8`MM@8S+28HT-!JTEIM5B4HSC)R^%%D/Q&P.DC)].I -MD"_CRSLF.T.E+'K15,T(Y6(E36GF=Z102"44Z7.JUZHCJO59`AK#@=CIU"%M -M5T>;+PS98I;#,[@N4FW:QAPV)'!ADE^8I?^],P>FK`<92 -M\G]Z!$9&TV&$DI-64-CEU^]'3)^A'8&B9#*2^,!L7^/3C662SDX9!F'J:`\' -MK:OSG1XM?S^Q+VD&AI*+Q)NLY42PI!PA83HJ!VNDW-94H2(GD`Q"1-X7"TI1 -M:CK+C].WAGS8J".?V>TOGT,UMCR6/;_Y(.G#5AHDPWX%2=2&OM$.(@BF\D?8 -M]GB*FHZ0JWKR7V`[XO7!$,`.C/*#.E](IH,`,6K.^(*L).L*J(?<-I>8/@!M -M;UKN4365)QT7?\HZ+KVO7#"NW.E?@JL&:(MUN-V;G^Q;*M3(&-;A -MDWT=^B`H0D,/E,Q"&:9$Y`4UT&@`8+H`AL*MH$?+QR=%\!P#B`V$;9IMQQJ@ -MF5XD/303*PJ=7[Q_G5BP![2?1Y[#9#$@'VQW3ZO-?8L,4!^=3N(J#LI+(NF* -MW^'FE[[VQEUOIW:77AJSE_.Z#O1=T,Q6"%2:5Q,6J9?_@:^2M]B+;`\I^S(T -M[AUT++0RP\^&)$W3U8P+0#1S^L?Q-\)E -M]<)3O3O@9+>K.(7[P=!'YHHGC"@_-EPFXK+Y;M$EUN,\AYUD9 -MD4"=P_SP(>Y=J#TDN[')FN7]4ZG>(Z+^9!8HGSK?,65G^$I*FS+@[N>K.^9\ -MYOA3AV"^1ATM[28'@@-G&$`,<#R45C@Q[[%8I38/MJ`WQ79.)]RYA07G?_9&HOVU$CR$]7IZJ2>JJ:#[G?I'2ZKF'_ -M0@D[N,L%Y7@0;GT:[;`R2Q/@>66O*Z*B0N&Q]%23+"M,Z"\>O';>,X>6;]DX -M34HP@RY<15K$JMD=5P<>:"/5PA_T$CE/+%;9KIR*#N:4\4;`)96:XO;1=<+7 -M!1NSEI7#S98_\!;DTB[D%9*3#S_LQB&)3'VD-^IF%GB*IT[2<8&'S)RD9>&P -M-I^WSPW$4P$OPSQ+VJW=0@K0/K@K$&Z#_;_P<>`!)771UXQDF/LPHLUY/ -MI0&E-;FE5`I$GWWS2Z`$,%-'UEU/,ZR)T*98)A0!"M$[*!P)/D]IZFZ5+.3B -MHN@2(X>&23VW0,25,P;H;AQRDQ&]#+!EGGJ[I:\!HUY4+_BP)WOXT"PV('$7 -MP%0IHE3H&PI[*5R%6R@FRB3B:`&F[M7GP421JG8)^C@_Q/H?7+N.'0SC?6D4 -MUB37!@^FHFJ7GI$&JX61/+^L_)>J[`&C8SNX*5-S@C -M_)4;JZH02X5OM;UQ@M3PJ)O'Z\KH=;M]_E@_RQB6Z=*4;M&SRB-UOH''$2^F -MM>YF*BYX&N\M7N0;B^[2KCW!H1ZF#(MA^/&!R.Q!H*F%^DFQ).G4\:C@L.;< -M?5_-I124UR+!**?/P$>D#!([$^3JZ5QIF46&&Y0M."0%JD@97Q-5-#3S@)H7-V*T>VAE1+(O=O6ND5VV!)F)UOP,<;A/QN1=XB8F -MG2Z"R]"_4^-2`5HBDJN%5CHT0-GQM`#SY]+5N'K&?6@25"OF>=4O(T"9;?K$ -MA3%=[9>GE\5XZDS0[GFC168?%2?!A\^Y&)+Z\X1_U=V*Y9E)SO\!&I&FL6+5 -M:V[@:_H]]$J!L,0X6W!C(Z&MV'#QMPWK6P[2ZM,?:X1,VB5)4>WR8B-YFL>: -MUNG>2I@8%ZG;`V2AA?8DC_D8T53^7.&-*@D%=8(:6X;U6LR%CL:96@ZRR3`X -MHQ9B^+OZ[AF4)`TF#BX.13+ZBHS5E]T3GSG2J-YPA2A1&GDTR,8I@BK&B-ZC)JSAJ3YP@ -M2"!2U*B$Y.\%KHVPN&-Y+(YOU2^NHKNS#4"9+,5K^[I=(.&.J11_4I?_&PYR -MJ3BS)/OQ'TB_-"X>"UZ*O60"YYH'`51P>^+SFWR-O2@`-JAA[2\\?F]ETX'Y -MW<990G50EA0D[PH#+C\^;49:';^.B*R)!O40E_+@8XK(7.M -M5%A)J2G*YEC12-\LGS&5W:G&0#+1Z%Y'R6%1?<%M3C.\'2&89'`8LX#)@H%W -MXR@C%J7#?P^++.,9P*5Q"Y^-=&OD35V]<(H0LV*EPEW>9>1MO%NZ;TMT-+-U -M5B.E[GF]"&!&,C^'[F_[]/CA1DK$=5"`&0%F;SE*":"ZL8R<<4A?<

    %W#\ -MX93?3S0%#0A\9JG[>,DQP!&129IL:[3V62.;)#E9^G\)-6",@@#_ -M#K0CS@@+FMPE3%O)1B8P,DZK5^/4\@/R('1\7]^HZ,C#5D->!@JT+Y+R."=` -M>(:-2&#\_9&9G0<[J1\:ALM?5@U"E\I%E-;1Y_$C38:1`O6Z&$RTI_[CB]@/ -M^67H(TDN2=NN+OBER$$U/&"GW)S;QD=QB"6A_!A@XU*5'2 -M4Z\+-E[68(34,A]*D2\.$X^ -MNQF+10D'M_Q8T-.N&J3QMZ59_/"P"F/K9G@J=,'/V):_4-IJ;TV-TH='D+WT -M@N+/HS5P;U3)%D2`[*XL.L6GXQ@J+H[?_$K^DP-&_O8F(6UW-PW^NZ#)Y=65 -M%<.>1#9QV#>M+S+`^"!LL']36>T0@T"%VNJ3.;&"X\"F@Q4BPT_T"^3^+W-U -M:DZL77XQ@9']12LL3]:^0!`_#B.LRZMR;ACD.\;$F<@MC -M*SR*%"B=(5Q@`Y[]6\P^V?WEP.=@._J>@#FR.GP8]4H;M/Y]QU#G29R+R\LQ -M25M31W9=C.<`WX@0'FX/UJV="3,LU/>$$Z8;>$ZGJ)HU+8(I1>9^:_,H"QN? -MXQY++0'K$0SR1''VQ432WMB&K.O@K@3L0J4DXN`6!(_MZU9$DC`=N^CN6M%\ -MNZ)9\9&&I1J:=QJVK[]@4@,IZ2CB&T:1*X00+^#YR)H?NB9>!9*7';&&)PC\ -MM5S^1-\GWI)*]/@S0J7PA?=$4.+4&=-T?1MZAUZ<<.M3\MAG%3H]B$J(/E+; -M9V#`#T6%`-?X+(X441Q#56@6J",-?A_1R:WRA5$%.N918O#).(NZ([D(2&E. -ME>;E4YZ+FRZ=6@,$,43C: -MK#0^&<[N%+I-$S_Z'97"?N6"`BV$72?WL:GB>5W?H.L:S3]%<2_W*A-S4+'7 -MGJ_LM]X)Q,8OSH>7;R<#LAOPKNEU-8,A@"O];^6(DC.0HO[QSDEY5;P*C#[1 -M]6&S_N99^?A%LC6?EWGTUYFA1Y/Q7P8(;=D;!UXAAHSO'G?/79T1N'*S%KAR -MA8,;%D;1!B49X?D>!(T<=&99>A/]EJ2?%8<2]AW;ZU5Y0H+DG_X^=95*J%G< -M?CD>C%B=Q+8.+/XI9RIM%RQ=33=_1J8]C[O!Z$7D'^:$C;YH[`.#2+%W7>8" -M;;@V34SWV*$7$)W>4E+V;D5KY[.M2^8\\BX1VGZU&(H2B$E;YGSH0`.< -MS:'`&=!&#Q,]O_\H^T8)&YW43*>\%\GT]MTOMA.\96J'Z*[L)>#GM1S,LMW[3'8`UPC^=J,RR%V">-TTQK3F8^_C\\,<48*" -M;%(<7W=-TL\I"K.G,5]8D3KSZR/GVBXZZN;TD\%`-8I<:+.KC91R:P[T5>9D -M?Y-CFK2-6$@!*!?Q_(MESCV$%Z'0*)Y2]B$I2!',+:M,,94N5M^=U*L'DN!5 -M#`JMIP(R+5_I-A**R+A&&,)]S!5$./"$/$52_0W7,Q6J;P!&UR,+4(,>.O'_ -M,`(?.6Z&,2S#8_#B3W,DLD-T52?6FM+6MQ:*1KX!7[-`AMBQ2A>/G(_B"X!3 -M8>O'MBK`](ON.8L"]F>/.\R,>NBE9=E^-WH(4[@U\4?-F'`B(?5]H"!I-HT> -MJ>`BL%4$9R[.5:JO.$U!2."JC."=>4:]2'S&L7V4'3T;5T`P:/S\[@X,*3\A -M_:OV\GN/3_2_0&PWA(VLKRKC++X8=DAQ^'\$<_"(/)RI;90.$;MO?3]F3\QV%S6!\UU -M)?4QU]PY_2(2@#F"R:?9^>/C@HT,I@O,EQY9,FYY'!/OP\+2P<\>H=1SA="M -MN_0B(%*SW/LYGD%T.17^-D,/C5''S1GS)*1EUO2I0ZQ6KZX9M:4-4UV#\K@&'9^053W\#>!])W2KO.=KA-]7Z8YV?(54P@>[\_$2D"O+H/J -MQJE^[3GJ/*VB.K:,0V0IY1E;'#]-7/V+^8II53-,[1'CT/1D5PK&T+3>=CY% -MGJPNRYXN,%G\]2"4K,V.!8X,MGF$AVC;@-B9:Y$9/.FEM(!&J4XO-/%>.!$)F0?M" -M\=.:5Z/-P)AB]?"J_PNJTP^JB*G><[M_\YM9A:C'*CBLX"J("REMJ*\^C`(, -MEMT)"3E"/%0HD)%N#\7RC6;\MFN1Y7\'=/*Z%HP]R6,8?%`'8\U(A:1>%R8H -MP5=BV>=D9G>,'&"P4L$X#W`TM=N+^'#XAB]%"P#I+:2J"]%`G!P#Y1^Q2)XG -M?Q:`D2.+HZ."^9[1L'YD%4:;C_ADS97(YYG/9+$=;<\8$"#N#RA -M6%Z]&VV,W0.8QG66E&+XH_G+?>X3N.K;E4;,*1:G':K'[,JO7!% -MZ03(QNV.4,%N00U,>N\;2($<:_U=7Z%F],\'%>%NIVV2(4VM9);!C3\AD`"Q%1A1W>"X$;YH]=HC`LYNIUU/1SJP\/0M5OU -M4:M=E?4R#DA7M-2Y[MP9-0#L_.,7O.&&$ZQM=_X:"@L\[4^X9,69+APO#-#_ -M3;0&E+9CP2X_C?*A$IN(N-\4S)MZ9%.BP5Q*\:#J#RW$'*&X?]BV!^\Z=4LG1$;%-HRP4>?,C%('="^TG.LR2#%DQU*4*W>0ZK>S;P&A -M?1]"MYL_J,\LV*9_F`0)!9>&D`6!)`E_\2X`UQ=G/MH"+B6FIPC4<(JQNX,) -MH1SB^=0H*JMK5#R+`M<=%ICK$?SSH*>2+*B_;OW]*3G,;"*7'>5PT3&O]W7! -M#],(2?UURA,4V'RM)QO-8U^FSJJCZ -M4[3;38OIRHKM(Y?\/\O(T*@7R3)Y]('9:]$U?HY#>)Q`T7-A9[J#+EB6B[); -MWYH-M*%H`/=_W;Z%\)0ZDC"@50B`"R;PA6DFZB&ZK0QM>@^RJ`NP5#3)02T> -M3J5XYKRB/-?H6&6G91]\S#*VES\/+PKO7SN$S?R^T!4UZ,71Q0VA'%F:U8HO -M-#2]&\M5R@=>,]F"E@KDH!#BLX9R6L9].]U=6_?F/SLH*YG`=()[`QE2RQR[ -M`G_?O`,EPO%=2G[8/H9-K9E&84-J8/E+?7E5C1;=\IZLRHPP>/P6IO -M*=Z_9I9_]&:H2B0GR*[:YS;M8605S"@"M#`G494I==!=F\T>SZ(&1NEPX.R?U -M20Q4QN)I,GHNA]G:R`X;*M.@9&1A4`@[@&(M:2!(\5HL+"G14+-MZD$9.5A/ -M<3\YG9ME=:_PK=&>_0Z0W4DF?.SW#;;<>X4%;/;20+E2[]M%HW4TD,<79E*B -M8\E)-(NMP^M(0L4MKS5IB."`T:T2_CW9M^_N],.]&HF'X(%;FUM`\=/BKCP^ -M-97(>E6G!GXYRWP;B$%)=]U'\$MH?#J4*J$H)+ZC@#"ZV1--)@ -MBHA(KCO-@^,6+9MV!#$]#!GY*27>7D=JV;-4#OC'"^;97G]+>94N?*!E,L!* -MG/A#YQ,7*-;-6`WA(Z[+Q4R0-Q)DU8,ZK+.%-B86VQU["9<0`^1T8B_+,=.) -M^.1%C1U6<-#BH@6$+]O=>)=AD!TU%";`"?966.-MFRPD?M#8HT68X!SGZ+5ZU)5]T[79_3P+Y*Y2;8K%JSX-+SK)5 -M[[ATBQYZ+%^-C7A>6-15E?#;#1C>!4374K/A'A<1(2R@0:_]A\T:]W<"T[). -MB'GL*NO%AOI8;@\4RR^P98U`(G?&*Y"#0?(#'1QP20FM`,<,UX7.A!`U3P[P -M9T2`16E6T]'^D5>Q>D-)RC!^P5E?IEEG,A.Z0;,,1&Z'#ZLS$"<@MC=PL``R -M^I9-L]!3/YSL`J!'UNW+4U+_.KDRP;`]DZU>T((Z=9"`A8\[3L%HCG^T2:_- -M[D1J[(>`7[R!GZ#A/(JUXTQD'+]LRQL&>!#^>.K:5/QHV[^AZ4Q&+%,6%^%7 -M^0`L4@["?R-1+_:B<1)+^WGN1":;L4(!NB/WQ@8$._@-V4#]S&`9$VG$U*'F@*A%@%1)H?(,?ZD:*%O2`AKLC]G#,TIPM -M&Y\R`]2."A290U:=Z$SL'UY7B#Z)3_;&PO,+6D.0]Q-]"A@T+W&#*786. -M"WPC2XNZ@%R$CX/])Q25UCOKC"!E*?$?>FSA2//=&[M^["Y%,_,ZL+,',UT5 -M0[\#7*$X[9UO.(HPYQ*V2DRM7KFGFF>87#NKK+U`;WW2D$TE78'H#84%D9NB -MKK)3,Z3DC?6L?^%4D@MF?V)CY"EO?LX+Z8N"5&Z9-]P6;XG0ZHV8_?T%KBTE -MXMO:G7S'?([2U#JV8U6.S4S-^/RVC'JW;?36NZ=?$+BHK"W0'[`\>S+8O-<" -MNA$M.8"\#JJHM4E35:J#/."9HXD8';)W4PF-;A7DR0J/`!"[-I3D^O/N+MV= -M+R=H)GM@/GQO-9F,#5QX2A"^+FZQFE1]-*XSF`1D=0E!*+4EJ<<<,5%`4[Z-:8>7LS.]PGW2%'LL&A&;(.N`G,> -M.?FC?$3X94#H0%RQ]DWGQY05^W<6Y(\303VWXJN^A\[5VZCNM?T^OBA)[H/4 -MCF,+K\P+WDAT-338_8/HXVDZ,/WFV![E -MK.546 -M$L\@\IG>[AIRGH2S*EV!I-SCFWB-H`Q8*E=U!)V#ODA$FF**]ETS2 -M+^@Y@4;K?K,$KJ-.$Y_A7VT9OW)/=;IRC9`&MEZZ\?":[(V7KQ($=;N7#!B& -MC+R<#?+L'9&2CKDR&U],*;K$6WLL^MI.5$"L-G$VDMR-B%8G5U4[W))NUI1T -M1#?BX%BE7M;K=),A[[%3JQ_-KB -M,#'3QH.CRK%=S?4#&<1Y2-(C;,J:M\>OCDMI?#HV8T6L.V^3Q-ZVD\"@(B_\QC8`6SE!BCDD=G#N3^0'L!>>#LWH0B2I -M=;=IGHO=+AO$"_+;CBZ3+A"%OX@1C-DS;&$F4F_Q+WM8QT -M+1S71<'\>.(>6X!A.\Z,J\$VE5$HU.N;?.7PS&0D1U(K!4_J;_1"1BYPDD$H -M006XAD'I;CLO*MK277M&PDD#)GN:KKIU*C2P%8_"V,\;FH/7V*]H?0GHRVW7 -M*OO@_+"-<&2BQ!2V.,"0$_17U8MCQ<2"S+;GTU;V@RL&U,()]9%4=U8SO]Y-D#K&@1D"A_19Z-)CCT"0]6MKH.Q07GT1@/H>@%>ZV8\;'6!;W3LVSVP"%V8:[; -MLO/@ET+]DO#(AF93T\#4E)Q<(N7=07*R[Z@RWS2MJG;$$EG`4LT>47MTHA:_[IEQ6QE/_QTL!V5R75O=0>?1UT?[EFJXD)2>HV[;"-: -M:L8>I1[HZ-;_R&]_BLR4DJ>%,&DUD4W@D^$!=?[I)D\P(M9,^*Y]*?@[BE:/ -MZ7R'*829\'KFX'N^5/<-6C[K?G_K$'8&)_AE8-D:QJ--$'6M?A8K"-:LTW.4 -M7G<]!M`_5U4ZD*;>(/Y_(:F9V&DWZ[)`G27_71KFK!UK>A0L7?#YK#6 -M",D(!W;@O+YQ)T#2*#?LR9R>8_U!4T8D6+IV!PR.O1%78.I16Z=AD`^%GR -MBS3JKY5ZR5>\:RJF6$P,/I9;34%9`').(XKT6+0Q\H?@_3$#$=ICC;SR?""P -M9HL'+\N+/X_,6;;31_T3N)]Q:QJF,)QQ*W\F2=6G,[]Q-E[0C?$_X_QWB<@> -M9B8WDG71](6;'B#K22B1R39VN_(0VU[R\)#0G/;;HYJOIM@\3$FO]!;890=Y -M!_O'+$S8%7)?YK=QCSFTM%1CV5!!B96]B]%RHI:AZ!Y[_3INN-S>9M(CJ510 -M^-6&58JUA/I;R(@/2:4\ZDDT6??6#RL08W]3&-@P/Z7%+.0N3!^$#3M'I7E@ -MOV1IS)V8\3&[R3ZXOW4F1@V44<078Z?&IPY?;.)W+=/HM>^ZI"?:*BS^FWY* -M.&?UTY6_'7AC^.Q.'.*R5Q8RC:[RU>?KU>+,\-8QDD*BU4F&@I$;8:GN]-:\ -M:[VBJ&=VU[S@!SHLR+N^C;_*J>SHIRC[3.$67%+Y&@]"ON;0.9S -M<:WV63(G3-PW-;>;E6'K6N/[';Q,./=KTZ5RFK'J_',A[J+Z']SX5[[LI?)+ -M[4V`3XCAG'=BK`D[\H?@B[^.PLL-W#.GP9C((!#K5OY70^/JE25RNL#A9":! -MS[:VBN@S+Y-P6!1>]'HJ4;@$-(4`*:(,MA3'!+DP@)_^2UJ&E-`T4Q;C5K5@ -MVMKTE0IME]1_,$Y$XA9'_`$A1RQ/:]3,(NH2 -MA+S!H2?!58Q''"=^$/`'3#^LKKYMU)\XX2O$ZBY_)P\PGT.*55\WOX"58IHU(\%U,&X_-*?\0^A,$8=#4"NNY%MR`?D/?A2X+ -M\@*IA']L%Z,;;M&U-K]^YJDA>8/)*0WQ^T49E_2%G3IJ2X2H#F[GTCZADK>D8%Y09U:!>F:\.&/3-)*960N,4K'?Y -M%&N"93'N)Q@->^H)*5-_J](+8F9DLKGMAULB?*8*I@YGC2VX\LWM';0Q>[:^ -ME -M(@X[@%]W4/IR#H#Y)9*,)P'G&^F-*S_F8,Q8ZT8K2$"#]U.\99T7@"/.%%D/ -MFW&W2RXGW"C;=8#H]M_Z%GRFH**4E#(!S%8P03<'=N]K5]WRYD]R#Q`E@:L/ -M4F>+,>^-5(+6-ET4M"!>=10E!71K@Y[ZL=]=^VS04ZI>3`>!S*X06$V40W^C -MS=3^!,7FB::@#74REFB=C0@GWT*2SF>SOR)?3]L4UMQ>2U1DOYU>"]9=\/L/ -M.^.VIZ3)-W![MFN]=-@&ID9KU?;K_SER;O"+OC4H6 -MEE9^Y*Y3KZK_B:QQ)D-Y3U2>/"OC#VJB5OF0G&XX=XBO=E3-"C_0E/TR2O[7 -M#&PA28+SF;&)34942\(HB+'7""VYU:??GM-.D.E@?P5*N4]LGT.6MC#,'JU, -M@8XV0YU`YE:G1-SM[".V1ZB2D)ZC]/=2`-D,.H(AAP=`?E6-G*$5N=O5",H3 -MZDQU$_Z"1L0#-(+`Z.];_`],ZZZSSTR3]!)V_:$G]*X\R89^V)4'S4_)B< -MP'8&D"&'1$/UGW!Y>\9._E[86CKOV]?NNS^_'B23E.`//:\,VE+QO7FV)&J_ -M!<1^LT^*;Z/FOR7*[,)K9NIO\G`F2Y!AQ:[I;_7L> -MCZB3UM%*',N$Q`,);!DS']V)2[NIIQK:.`W?KP8(_-M<8E([TZO;SK=*30X8 -MR+1=1J;U-IM'%\]DIG%K[U4(PL)RN<>I\KC2)[3.&/8,M$9165M/;GF%&;%G -M!*+"-][0MQW]8.#^"0965&;U%0P@&BY=-+;?,TJ+BEFO#,HV-`-&&'TT9UOW -MBK5H-(SK* -MF]1I-#X')/,?Q*N"J7\RWUE[>A\1D]2K0K!GLII=$8V2-!9[?1\L -MEP/F]`0,O.R5"MD')'U;5&SK>/F[ -M-+HF[;!-;#";HDD'<@-`%YDT14I+@O;QHILKEB?O+"(D[1`C&5K0]PCY\N<( -MJZ;V#.GU,D]%QS#=`^D5I*ONI1);#:<_SD;!:TH(1QRW\<[K^;PK!CQ%NMC% -M]-HGV;F4H5MOX_HUV_K>S5:18TV"YLZJ5.\M3%JX3[:H3^E8%>[(:[ZR?461 -M@*Y1)5S,FH61;FI`GB2$C)2_#&_2STRDCU^`IER%6ZK]R>Z^5G#T>L\.AF(2[M3(\G\`T1`O15`L%2;5E>;@1OZ -M,"/N>W=:!<<[J8ZQ:SA)APHH4-$X_.L/(:\:J'W\YNTZO>;>F#$P$E$'$CGV -M^(S+0I-D.K!**:NF'\J2-@T%[*'Y2\OGB5B[8ET:"/^]`]4OQWU4*1AQ41^N -M!J<.'2]PO1+`3%0:/GEDGK2X3`]WMGL2V=,1-X;/=SQ8=(-AL/$@DB4+<",P -MDN4=Z,KSWN[J(C`0*AYR8Z?)-MVMV]Y-)_Z+Z[LQ=5[0XC&Z"GK<"RKJ0DV; -M^:2J+K4\-OF3=M-/R'=2=WQWV6AN"/8]H` -MV@P81SK(#!G=OY)ON7Q1/)ESF+RJ\C.>U/:-;\@':L_$B##=2N,>R"=ZP\A\CK4&NHI]SP2(2\]3HE?Q0JH*];FW1N/#P\_:`[Z.T,Q&L-2+:J -M3'TNZ=+8P@S>,(\#,8*RPB'.[822>,]1][)&7(T7*S+DV)7=Z0$4\+YK>W2` -MM%;7N\:D4+?:>"URI.S%+K]#(N'\?$,F^MH2&I*9DGVW4O5L*&- -MSG?:;*&L.Q;'5+?%3E%O6N+F+9R#A+\YJX\[BL[7*,JH&-XZ9)EJ8];]$T)8 -MR\SN2;QF,HJM$5:3*HU`#%?,OVC<(F:9>0#GU6G5/2PV.P'Z4CFX\BC:E -MO*-M\34PXF*P@_/8X?99`]8\EHU^<9\.0Y!T]E&I#TV*KV0O8HF#*W)U0F<, -M`UJ+$2\)24+R_V>X!=[&7@R!>+4O(_3^4.20[K>8!`9 -MB//_Y<65BF:D'X'TL].O77*%-HZ=VF<'W"1%4\VWESPUR[,P-"G2`1C7+S\% -M_>&S5?-AT7*DR/!F'!#JZ$"W(I,\RE!/09G8:^B7N+%Y;B)"6YU-EDI(2$8T -MK_XRH7V.+HUQ$*"-5'$VHP]TU=$`4K3R`)39\$G$=,"_"&=T., -MG**)O\2W=!W8E!M4APZ#?AS@-V]?@JQLP2()$;/P/:99WW^>8^?[M`O8).QZ]:WQG&2=#^.I!J* -MR&^K?M^MA7D3XM'Z`.G!MBI^'Q'$:P/VC"@#S&DNO/_Q[[KAD60QYF,R&+)? -M69\L-B,PW*%L!)2!K."O[U598!>Q>Y;,$(O?#RZ":W1;6K27!?.?HG9TN.$R -MQM?Z?YA6;OW@4._YUM5G+ZGRME8]&CT*5ZCMUYNUPS.^Q7*X74MXXP1+Y_:? -M?[*?[+[KZ'Y!BG&0X>/SQ*C-UW?;P0EY49N/,&3>//%T%$]"(*ZC\#R+V8Z.OQWPH!=`#:P/WD#KX%"[H1T,>HHVF>-&U5O7M(9@;> -M4J*`M]]0A3#Y75G&XEI]T -MUD`HKY=8A#C@)HE*SDC)/>$5)#MQI+:HY/YB@<=/'1))\Y?]QJO$DT76KF]- -M@J$%K1*V]A(>,Z"RF`L#X5!7,>PBVB]BG'%QW-Z)LM\'J&38*%N#ITA#MO]* -MM\Z0@R`:_UQQ0CC]1G3Y[:(XIW&MTN/*)8*^ET\5SS\JLO%[67S;H@[CA+CU -MRQ4IQUXMD[MX`3)!7GBX%Q(U[^W!J&)%9MK7D&4DDKGAI90W?Y!!7_PP6!.% -M1HVDGJ("W\3N+(C1"/H>IUY7B!=1B4PWY=&-!/]U3,NBVRXJQ$3)=-HT5,;? -M%5#FR`34OPLUFV(J[O#:1TR#ONM"E!QGA*&_4<09@XM^U=SH:XFA$:6FH,=:JWN$OT8".+BZ5GU$OG>">6 -M%R$^EW6#VSKNO=G?=20V`A(%).?T7KY+@-Z@M0:C2U`>Y1\&77+KMA1F]\:K -M&V#C"/E174738MXXO@JNFJ\(H-ATA[_>ASG#XYY**H -M8GVE#J/LO\U0NZ#-[Q!FO39&FZ!4"O18(,&7PY6>R>Y0FDH^G/,Z$@8!,LVUR9$>58[E8KC -MR*`JF[-,E86#/"?^(B\(AHZEA$6>0!HOYP( -MQ3=\@#8#`MLTJ1[FD&=])%$U38"#LXGG1O7R';;KMA475N'5>1VR<3(TW.]_ -MOQ)C&I>)=O -M_LL!^I?)1`_J^.>G'@@^GN>/0K>P(1%-&EEG%10: -M]6F/&#P<]5`<,M4@$?6J,DA:R>)Y/"<.1/`*`,1W*H#Y^CZSBJ'$6CC,0QYI -MAA);2&2>)T\JE;0HZ[Y252]^9$%8$32%EB4QX"8VD7N4%N\_-H%H-^++079I -M\:C1@D+#LJ3.WFR$,8V[[7'P6:XT?>#^I"6%G.LXD![>/).O_?A'WF/+(WTT -M"CA`V(J5A,!,:Z@^/\M,Y;;PHHC<3&,;%./E+M7^"1G&A/J6%.:A\.0*9^?OO^#I0(S,+D.%F29D82;\Q,XLX05 -M08Q9LM3\D;DQ2^_4T\,CLE.X43:1NEM`92V=EKVXTCO'O*;\L:OI($+?ZY'B -M;PW'TECA:A%%$1]17V;.-K,/E;3"MF.R=*48GY"W$RAJUD=V7#:PM'0L<#[K -M^HNX@Y1CS89B7<&$\:\A.^-?..+"Z&LGO$'],-&S4?Z'))/I>G:T[RXG%^Q8 -MB2"E@@`+4;0E,#`8IN!?__C'%KY)AVH8?%54HE3HX%D5>B0-;#N7O!$1OWJ' -MGX]I:9BR^%%LJ!&#YK#%)GINO_F:)X\^.E.B*&]KT;BF;602TY']K0N!X2OF -MA@-)>\VHB]B:PN6@1%K,LT]E"H0&8E:COBC7$8FI.OW&]F`JCM<&.NP:F2O; -M8J!I<6&.GC=P#9K7)[:'-5OK@YTI2N.4-S[-M49Q)1ME&]=FA`EFS%-G]>=I -M=#F#3+*3VH0V$/Q#$;RKKIE[QMTNKMDT,-CVM?1@[F&/`85(OXV+-_6!5^GP -MFI-,J^1/`SFYI\?>+;ZKCJ_N%KT%N];F+2 -M^+)$[^#%V2GX!(4R_!EO*6,"VJ%?=;FIS5[8HS=>Y($/9KWG68Z-C(!D[\-F -MS22QY/XJGU)/7EZ2&+J0/]83J)&S[@[W;D]9S,9Z_]OVM4-)24WD1`9A'((P -MEZH$$%,H[UF*-/^,+3S;?X:VVY&0F/PE65^[4+/4I:%IK@'$D(G>ZNK0HUHZ -ME4`BYWFJU,^C(Y;IFDU7_&!/]%DW*&-/B&6 -MY9"^,YY0R^W+GN,*AO,+Z>5;_:8C1BOK.6E-BP"?&$1U]"&LC:^IA44&E/Q" -MJ(MBQ1B.*KD5!;P78*C&"[5*BMG6ROPEF\'+!7&ZVX;GH\Z/1A[CSX^^B&^; -MZ6D@M,?.N$5GF37BOOM22\K8S#1@&#G'LKPMQNDK_EYY(-U,3!#*/#$M -M&\!'*&+Z,2*L]!W9(T&^2EX<7+%L#!-5'@CIJ`&H*5@P'?4VN@,'Y8O.4`<` -MIQK6.:Q8RR"K&]?:]2P&$&$N6=EM59- -M"42]D5ER]/9[J153P%6\\S%59SFF+=[@,N):3_$S8A6(*:5$+Z;U%-Z/T7;*2I:3\XD?KC"'MLU#W[A=,%DKJL)L%0L5BRI4 -MD1Z\SSKLBWH?W=P2"OZW`22]O(VREV3CO#0H&6CR0?R)7,!8;I,[]X/CXS7N -M:DQB6C__[[&Z$&%L/;AZ\X"ZB*-^TIER4T]P7S6S6<9OF3U$=;)*,LL!+J,' -M99VC$PAEI)OF7^Q$;?_2%7X)N&Y9(B`'DB<E@O -M7.#T\PNO4`?]U&1<5Y0Z*2).[[(H8%;G@E@4AEM$E`GZZR^.`XRKD)AE1/(E -M'!]M$0-OUF@0:JL1OFO1)>3]@M3_]631D*)G"PJPP7Q'436^Q`>NU]+J*CR^ -M]1YAHTVT6540(B/Z6XAK(`-CS&KB?W;5/J+@!5FCFDGX -MB^*RW8`"?-)F)+&RHO8"WR,*6'*"AZ"^T:(QSUD33/X!Q -M'(!+$[Y[,*M/'GBC&$,0!CLXH/S(QL8``>$CN<;R/O\N8^_B_]:5Y2()BK4D -M+GXAY.X(X#LQ`;UYE28X=F^;"W^S0TBY=/,5WVOL*IZH;!VC$!U&2T$_,)[P/ -MB*'\U+(BK>R2>'AV`SA&'4M49MY1IC3MF-4Z*4?I72/&1%Q<(B-WY#,"8706 -ML1X7T&?*WP^U5*1"\HF&:XOPL,0WL*K-RHAEM@!_N`BEY4VQ9PY+25H*_O7G -M>L,"\2-1J=?4`^YY[])`R@+62!"#>[%Z@25/K:$>I1E7#Q^4N62K;IH3@K^< -MHC^81,M0`1_>I2VCFRF_=]AF,OUC.MP#7Q1K<*R-@81MA&8C5PVWZY4+_L". -M/X>A,]*0TC)]CH57O7'T^)(W^C7297$\CSZY -MEG_^@$41/=00#5$_PO2):0IOWNJ!R3+6OC1CU!;.)8ME`"];*(YQQ]SO^X+S -M>R.3"ZF.2/Z6#A8'>6;KU$Y@/WE_ -M_J`UX$W4]FNTK3BC#+`U'+8ZY.70'NZP0[>F#+N%;^(B(.J/@0]T4?EP363V -MU'P/FD>X7CJ/;7"=K*I=Q=8ETUJX)]^_K._',,GC+`-".'DI8QL8O14!L#_O -M;X)7T6[S.5#18=>,`.;0]9KEGC9GV_G3%84ENV?KVQQO=V-":"J,MPA**.L+ -MLC&`,]W6\M.1\P'%/:.8..9%U`4#=)?[YA;8.=^+%-8+?%VL+QL;-A&7W$9# -MB&X1[VUZ)W,U8NPOTOUTJV&!H-EX<04^C5T#6?;7P[%A[[!D42L16ZNSSCGS -MG]M]P'3.$.9/KRCP=#(OH9.'-FKB(3U*;C?G'PK`S]82M:KQ3D -M+7"2DEAD_JN"(*?2P(,O6?@N*HF/SPO<"`+6L]=%R+28/FRJ]YA_@S;;<`[:YZMT5MEVJ/C2Q2[SC(:,.I2>=OI%%4`7 -M*WP^8[*C>TV!=`%D3>0H6;QY%J*.S'=@D4>0'U:5`.6:H4-.TM9K! -M,A3IGYDKG%7K)PV#S/Y2^KT7_R(=V&5OP9)S@UOY[/6H5Q_*">+$7S(PNLSN -M-A'UCZ_3N#=/P:<)%)G9VKVNBB-74^LFJGEHHV0)`CSGVW0N"2<``]N!IES' -M!-P'U;5-2Z/MN7@,EW+%:O>@:+=C`4BXK\\>".P#(I,Z>FQP>S\:M5F=6_D= -M,1/IMJMT.#^?PB.WT6;W1704(M8/W%QO*8579QE[$6?4P)TH_I,IR[7C(@@D -MQ1&#SQPJ6A]13O`1#%9#AOK$.4;[$M6HMXUBI56V(GLJTFU$X6?);2"Y1SO@:A!L^OKP/B@A0Q1_Y6 -MY6K/P3O%:I"3GMN$T`0Q!AK'L+:[\-W328'_G&TX`-9NZ%G9LL/&&Z]%D#AL -MYN8O)050F&IY3K_EIJ5F#]RHKH$^?"TAQWIS"[BR@^GSWX+A&3Q6@KP]JX2W -M7N,Q)\BIV,#Z210R*6T\A-?P&#\K5D!D(1>[A6C2T6L5C@Z^(0DH1]\R7*^> -MH5547L[Q>'%;,?V&B^%B'+5#`O/G3J0HPI'/-,3>T/--6OU'#(,C%.19]R:\ -M_?UG1S3(GXW^TO=B2=`EJO7%38&*](5K'7:)(Q_](HCA1]#=0'!`"/V]\\E85@FK'*6"O/8G2JF/P!@ -MJ'9?11H-OU;767`;\E -MO_AA*+^/0!'&Y[@)@PI+&UV19Y5VZ&>`L;M=B#DO$\6:LEB$MD(A87J#D -M1Q$&^?7"1A-IK\:NX1'/JBO!/03;T]^)>FG^SA+U\_>\;%5YA_3E%:R\Z\L^ -MG=-A@*^S1U*T]T\X2@^R;;3S()G<\EAG53\0:3`0SIU-W_]U=!:E+(SJ*[FE -M-X+C#[H][.=4R\9]XI-E1X;B2Y,/.-U8%ID#3F>M\9Y$ -M>97[8\)P:/=>%C5@CQLF@IDL>$, -M:D5J&G`6MWU$&%41RZO3\T]KD>=>#13%L@?IWA9S!BN"C4M'/03:=928J/5B -MQVAGPR)!(J`:0)'@7SC`_DH6M.[Y*P3.KJ):$**ACI1_2@8(G$GB,@`0HXV` -MG#KZIB!]$^,JW);@IWOX(3QI5*#GJ'@KK]`XNRR0T=]LK+^S`MS7FFE66*C_ -M_:TVRN:8`EB-=EF-L::"60MH?V]CGJ'-9(:'F["NZZWEB_'6O4@S\_<4*\C] -MBPO`L]TL:!2.0L(^YH.MCFRASUE1G:+*'EO09PQ(CK$UDI'8/2#!MKY.-P[I'4>T@K)A -MWL^*WX+6*M,EA1=I^R7JEFX75!\EN6>?*(V+L\:6JJ6JV08F1U!0)N^T;0#H -MWY#S`>=3>ZB[0R;&#QSC+_>NPX:Y9.S7S'G!Q5DTK(N-+)A0WYB+VZCB!D@7 -M;9#)RE:[0,DAHU!83ROC(LZ]V;7BF68"Y3IEP7=2!:;6(@4K58JV<-[0%,K\1)^O!:.]Y53DOT^J'\@$W81,V&],^!+TA_]5&MAZ`# -M,O4Z'>X]&-X.Q`^=$,;WB:HP1LZ?TN,ZKJ*'4[)CA:X_>5ZH&]P>^H&JGB++ -MCB[YU1'6'_'X+Y_@PBF*5R%EL.'!NZ?N6\XMSM+0Q?(<\N+]5\Y/U-]I(?5_ -MU0DV*T8H$6;3C/9YQIO9YO$?9V!=F9:D@#=Z@!=YD+2HB;L!UNAJC$]SGK -M[;/F=[%_?I]@T\UH3P8"-RM6'MF(;Q%WKL@M8QXC&,\N,19K7QRLMJ"(*EA6 -M-GAHM5T4(WT9;4O4=?]J'W\:!;RA*FZ+C"#K4VUM`C9;^J[6[8)L=+1H=? -M!'2RB7H3&>=F+D#G>1>5AD;#4"WV`7\"A698*)MVLPU1USL@'KU)P.FAG;1_ -MG/N^'4?\[V8?TDF4?4)])$-J&F#$5:E1`_%%A6U'87&>M,'S$=("UY?5#H-` -MDSF$9&JCXMS3:0\(CO@4P*S"@=H99I"WFTK#"F!V+5[BSRWC`^PJU'C(X3KV -MW*Y2CZ'%!'19S;MQ0*@CRQ/X>3V'&R([_9#30_OD?JGJ@IT60GUFW.S>&9== -M0CW!EK6,.)$C(VDMAHG2Y2C+N7:"F4MQC01]V[7T!Y]I2I/L%BUJNL2'$@8? -MC*_CW!C`3?>FV%.$%2?.]??:S#8]4<[W'L>-]K0'+WT+4VQQ\>J2:W('D)+C -M0*YQ!C+_L,B6G9B/6I#R)1%+9W@!4H=*/A\TBI:H;&4VU*FFW#,&.HRD[`_< -M";5M3O)NH+5$9LH5QS_[2=/--/YN(`0&B*FQCSO/M=_2][!F'=MP\#66S;S5 -M:C"F_3C4_&RO)O_[]-,**W`'1U6.*Z4L3W$]S,Y='8ML^M68-->,?UU,WWC^E-U:FA;DH.6D&BBD`/75R_$I![I\E3V`*6 -M.XY*)U%+0`CZ%U&N;#_G[[:*5GC+PJ(1XCP!");;(BDY?KWOM3#X#_[O*[)? -M6B28K1LL2(Z&829$.9@DA.%0C>X#\=PCD/]-@FM-3CJV5I@2WW*]W"73-V"V -M/8[^LUCL6'4GETGO-DKJZ)ZK\3,(^.Q>JP6H^"<5]A].8-C9C9A-3^9-3UMB -MH&GAU3[!FED&XS2*QI8H(*A35N9%JL7:4LJG4Y"_#+>4<9T'Z,?*Y]I/[B.E -M/^7Q=F,UYY+(O/_]T7BQ5-\+J4)IM09(@$]=^S>8BH&JXA2?CJ(@3@]@TVI@ -MMP#04=<@U]HY@5Z80/H6]`/-B;GC(-=-.;1G7<(6%I*PL<^A7X7O;* -MU(W(*]?%HHC'=2I=/KHS_/SI+[./(+D\"WB]Z3H`TH>A[L,"BHI`OI&T!8A\ -M]U(Q.'8X^D>A#N9\.U";`5'IIM#EF,Y#T=*EM_9 -M*@GB4MR[0Q,V -MO@<]U?+ST?B5",2+\.I@Y3@\/'1<7]:>`M!EA/+/]XI7]B,"L -M%6=9.E!1"9EH5SR0Y4W=PD++16A`_S]A)YMK[#W6*@F0C7*;`:JY -MC@3:MQY?@9T0_=!\8V/L3:RK#8S(`3;MQ$%?^;W=;'"G=EU+7$T-K"SOC[XE -M-B,N\[/NG`E=*JR2O`R."??:ZNKV]:X\Z8RQ0:?HB6/.E[:57T_B6()O>KE7 -MWM0FJ3>XAA#DJI/^@\^87-X"05E37T')P'2S(7S\]7\SC?@YZJ<'/8D(WQ3M -MTJ@E&`GZDR$PU.)-3YE-767IZCYFU3W3,%I?B7-NEY88V]LL/8>8@7 -MSQO9(LU^IBM`N];E![5Q::3CE4/-"%3E*<5XFJ"T=;B?IC"A;<$^/@?E@=C[ -MS,34#A^I'H+9PIGX9^3"V3-E*MO"'Q:*#=G]%GGF::-HL*>7BA7\<[,Y2/1* -M6HY@U*@HW8:\.A9,1I&RC(^_UQ?C=/D/1)1X-N

    4RLF/)3X; -MX;#19,8N+0JO>&D)NNH^YTO\7;ZY"U000--NGS7.!Z\LS9F*V(XXN[#'2[FQ">\E/R`[(YCB+`HIU<_]. -MV^[K\0"R2J`HG-K2Y(Q8-:GQO$LM+!5%F0BRON!6*PLIN*T+Z]*.M0$6@9.5!RRU -M`PXE>H6T79*3IOJ<>J0Z;%#C.!`@N89!_\TR9;GRRWFB%@G_U">E=B,**:?, -M`L312SCT*INEJ(50U??R?,URMBWR:MV_8@CR``G)_[$`]T:@&LWL*+%JSWR0 -M1M0D^=SGUI=.1B>;P^UAK!*IM,+)Y03)DF48'3391P;HT@0MF4!3EZ]L]+%+ -ME8V)5X(,KH#"H42^`%Q!Z=1;H@[Q":Q80^3VX%D.I6:$;L<*K%7FL)JG+N,I -MJ_H#R09M0>V__L>PR^=D6Y_^T-ZUPDY_?64A:4B7ZSIL\!E0F_4>82>U9_,S -MO_K]0LKZ)P3Z2OHEP!L,\QN>%TRFWJ^1^=0WGE*_0IV=.$B0>]H^ZALYU81> -M:5W!IDRM9VW<3:X`VW1;PDPXLZN_-':4(ZK:?4/98FE:CL$,-_^QRC,UA6UG -MY5RCA8\4;A,7;OZ#;;SSVF([GOG8Z$.H:(_A;>4'(2V]'V,BC_VK2P\+;7!C -MG>R!9(N0^)+B7MV!TR'8EOXT)5B4JO<;Z`?M%K9J(0;`OK)B$C/F-\&VRLEH -MQIG4]/6R<82A/+X53GK[>?S4S=6/5"Z=M>%25QT`QH:2. -MB-\'Q)``FRS&YSL][-T_7I^;+[L?9K?E.7J-T*S1>`V^!6"\8O)\Z%CCWDC$ -MLSC9K=ZP>$<;2S(GV\:/?BM>ZGP0B;S3%*WA!/S&CXUP2_F#$9?^8O'H-H)K -M)*#/D8]@JT-`3*,WRC]UQAI6A7`5\B/7@?RA:QD+XY'H8G>SG%:F,;28P?C) -MA4F?36(!_+H,)V):5Z:LJ^\#3^AFO]AXJR,?/=/N"&]I*H`/.^SW_J*=CCFQ -MH#7BFI5H1I#&I36:L/D%*J?]LAH9+MP4(&,O_/*.;Y'JB?]^V9Z6+SZ7`->'"K(V$R`\\E/BBUGT-/9C -MCJ(KEDH!5&QL2)(]E'2E"A-8E61#5%P02H\T-V)HB'>C-`L<#@NPSN!D!A:4 -MRNV72R+<<;&$1#FH%ISP$!EQ#_XK'!BB_A66AV_=%.( -M;6:2TRI&",40<&9%>H*P2*!C^6>C2D\HNSBC?8J>BX(E4[,'VP_S:"WSAQ$_ -MZY%+UWDCL43>B4%4=JN&SF\,7L@A2]IADAZY.0$L^=BA)@3Z.!LR34:?JU.H -MKNQ_.]Y$PX@PA>P"-KQ(1F8:"YZD0<`B;W5_=8/O^6N9< -MMVV,[]Z8"FR-,RZGL<#NK:]BZKHQJ,#KL5X_@`;_>PZ#`@C"W67%D7AAF8BK -ME$]-++QZ0ZH)+9]R_24VJ&+'!+`#4%$K$M9R&5FQE/MX/^BZR=\[C57GYL-F -M!K1%^MFCI#IARY=[S[0(YG#_-E3`2E:RG5$ACU$+XK:R<)'-0`Y^JQ8J0!O3 -M6M[@B5/$SG[B()8^4B)YZO9_V-T`"=ZFI4V<^(H(>I]I3$FJJ:^>_KY/^0,5 -MOZ+>7B'3"<'/'7WE"ZTMDD@"?11GJ:&TYH0>@Q8L4A/Y8[B_=%%51;!WS`D* -M[*4'>M6Z.FAJG#XJ2>?J51'Y-,>'(+0(UK3U>BW+,Q@J#D'U9W(Y'$'UL!H0#6LE2NI:@;ST]G\.FU/U#8:P2=:LM-H\O -MJNI?;&:.LE#3,I@OKOOO%TT$X4;C`"9*B`O5%.*9RVI/Z>0\F1"\TQGZOI?1 -MXL][&4*XW`.Q)432PTYV=R5D(C%I\.]9H2P^1\AC:CGF,`($*Q[0.[4][YT -M_36Z0HY39Y.+OSV.:FU)PO]T<7JTG%5\^^OEJ85QS6+>M,7?Z]`,F3TKP -M9")#EMQH8]!N^:M3RZ=3D9>?A_=F(WEP`)%\ZV`$6^PRPP*JPX#L2XA"3M1.)";+9.BK07D]XWQR(]EN5#$MI7AT -MFEO=>XK"45R_WY,:K7&O,+62`-?/2/S2ZB5>E];T-85Y1MZ0+$M>8LNC'&I5 -MLJ\6D13/H-5TGHI%4?O\\1ZD'6T&,(,@!W\?:;/;.<:L3RM.9)[W:T;KJ@-15M2:4CJ3VDQ2U@KM;;(?SB6/[?)!0 -M+FR'JFPH+T3-7LQ9SZ'$5BO.LX"(4RJXJ!]*U=)NW.'_'2#S50Y[/[<# -M!PY4]*GB!OGU\K8FJ6('J3O!`I9I'&HTY/5A=,C=-J-CL>R-EP*,"H?&R\#L -M*9N#\/("9_V7X"\:5"<"CC),VRLVL.W,=HO$\7#LG@PH^*(.OUG+RRJ/%.#M -MKG;;T]JTG3HD5+(9OR:V"4?E"(;O9UM@4$51Q3O\C@DO/!F.2%4X[+QKTAW! -M)X!"\?UB7%6^1+9<"L8)BE_NPZ:H9A:,>-`M3CH7%`U-C8;)[(T4OC-IT4-%BW^W;BV122I'0JZIB- -MG&"[)'+3%:WE=0Y=MG_!;-"!2"?2'N&B4,LW":;*<;S)A?0[7OX)=E6"C"U0 -M^*D&-4#48*E\_*;;?7]5"M)-Y_7!.G`WSN1($UPSS7L8A_9O4S&^$GN'!8%' -MD-49W="R?-1+QOU[<0!#Z"\3[&4H`:$Z@H)>J%V_?-LY!3; -MNCM1$+=#R9;B$-@%KJ755B3V3G3&?W5^'_!F$#8S+UY([6%]E[?;)2K\/FJ< -MM"^6L(O`*`^#J0^E0`0WW(A8Y9!+,30PW3*@ -M(A%8WB3N/__2D9T+HDJD>OCO'>1?OU\,$BD$USE_](^2ZX6>N=3Z\OKE-+BJ -M^M2-8*"(PAEU?$@D0YUZ0?'*;PS&:2$BK(QZX+V;U3*YR!X$PG^[$I:NP.[> -ML-G_`@ZV[_7-OCJ4K^H;6?7M(N"/X7V5=TI0WTO&VIE[?+@ION(JA@[]T2;Y -M,S@&ACP\:L18-YJR_4;M$[*^81);9-B4[\#?T/\6O^@BCA2730QMENI:N>19 -MTGU-^4M$,0GH8RLI9A*('JAY9B_7')5&LT#PJX7$=X.E.!1]-ZZ*78!`)H6 -M$3RF*"O*"-PU&7"FZ9GBOID0YL\F5OT=N!>S"<$T7F\Q$[Q/V56#0A+ -M;8M'GPS.E=FELMK55$,@C%KU+?1+*\+M2TF>H*S"0_Z'CF)HJXV-P\RV#N:D -MI+1`^M,?GMA($$,2]_R^"*CAN,6KDA"%U_-*\]%P;A2HLF^4(D^/5Q\G2Z>W -M#53MTZK%Y+FE2]=,&_'WE[ZYO,)/`4E!D:Z`=!=.F#_I9F7*=;1^=H$&6V*! -MB5^^97[ZX^.$5ZS=#4?<[4X%NO"UWE-OWX6J_H64D(X["\QAC.Z!T?I83]5] -M7:X^.FZ-E"S;<068+N\TH%Y0C!$UM\C^:_W<_#\OCUF';@)'$GGXCLNRWXQC -M68A5NE'>1&#[KK=&O,:.%@QNNL):NE/'?3@#O]VZ-0/.UNAHIRW%DIPMF0#2 -M4=JOOX1RCXX*>(?)XQV"XD^#X8`*`5)ICK$^SB1[,;2#*S72^D4T.%QT1*5M -M;^@N6I[PJ.U70?64?L+]$M`W]E^'MM;LA$)S(*LEB4D%'+X!N(;`]7T:;5T -M0,T+CWS7BFV3J3G" -M*!3`"?DH7MH,W1'X.SUK'3.QT?=#M@!*ICO'(Z"E#=3=&ZZL1L%("OXM;BU^ -MM3?(3,^EE>K!R-##AP>P5J1!U"OE[V-'*GYP%8E5C3Y_< -M]D3#X+E2FP.N)!P\MQU70DU81@6S/H\Z8PNA#\D/JYI19L^$6#M+JW[;^9SR -M;\W?PX_M04!D"5,W`?/!JY_$&N^$W1-5[?M)'^+;6^8O)/5G\:9Z+";@+RJA -MAD5+=&P7D[/;'J7:D`L#ATN(G+)%JC6QUEODG@M=H+#4P)=$['JJW8STU?H# -M4I%O2H^#5*XN:-1Q5-.=C#G-1/CMFBE']1-AV2_E -M_%C$(*1HKF.2?8\`72))F^<'IX@@PU3$0A0!\U=L@NQFNG&(I65U_^/+0!\) -MCI-A]E9(;[M"7.]YORK.GRMN]K5;1Y03GO\K@_[78-=VZ(26)N^/$ -MH86`.O%,X#CS/AD,KBFC[13\+V9O.PU%Z)@%&$!8!'M3':P-(VIU%R&-!@2# -MSL!4ND]O>9-FH6F8"9_R$H]&YG-E]'B5PP7`/9?5UTW[+K?[&&4H_"C_\SI+ -MM(?!F*X,"#++=!_J!:9W37DD7THQ1/U -M$J[EBW?;@US'I[;LZ_:+G]B+D?S9IH_J"QI)F1S;"99N0^;8$Q -MGQI[0\#BP"@:2'R-4;RHLEQ"OG[Z.NY3?G]/$'=]6MEUNL2!]%Q$,TD0*NZ)5VW+-E -M.N3[&]E0ZPPW36U=Y#[[U5VS;%-?\$].:U+*Z^(:>H!8*1F6\E*L4_9L`'TZ -M;QNVG/2Q&.)?Y_>JN=@/(D.P*-/5>4LA;=UBJF4`RH%C,;'9[""[+_,Z%!PG -M>D5GV0UX"&M&3X^L^8667T,M"PR\(72N"5:R/'.O1EW[7`48(K*5D&:932HX -MP2PGP3<""U4ACKYK76HFQ74 -M(<(#6G6AFC`LN%VD!;S968F?O+!FNCD5-9U!4T8O\@_*_6J:$O!7;"H$`$R8&YAOGFE(@+$G-GB=O.K6CY -M!D7K]B9)99OBA$G[S8T2M3,L0`(VNJ$I2&(KR;8=K'W(['XU1+T!CH2XTVW6BTP<.>#B+ -M1O`X:PS)&.T_YBMW4)TPI?$AP'Z^7Q7)Y89DE*!63LXK=HP[#=B!0KQAVU1L -MV`A>69X'@Z45;HU8G(K6,O4[SU\?+E(]*R:_D$8J9(]S(J&8R]1WO5S$/YH+ -M`,%W)#<-'^MF+/QH,,,L!V(S<=G(8^=^HZ^8+V4#>SI-`!*;(8I"XV^C/O)P3>)>_?ZD::5X^BRHV'ZQ;["+@@/GBE52 -M`3>,Z^J@WH..+_("H]QDAUB^;ONJYMY9Y&&I/)YR',VU8WD%T-/]`2Y1B -M'D7=E5&SW6DAK+W:H6D7.48VMO_WYHY)^_(#_8G!\`]'_H7%D1*LY!>`E<>7 -MWL8:(1;6QDLIG[RL\'V7_9%O?.&^?TE>7?>5E_"5H&YS -M3!L/W401S2ND]'QPE@^S.LL1?8291%?PW*FFZTT8LXQ?K)S$U+8<2@K1P<(5 -M/G6B#OHR2[AMGM_IBX$_8N6Y]_`N_``.;XKT_]QW&1['U12O"X,O!A&]O/F]4KQ="Q\T=.DN<>I`K.K_6S -M2>J?W:UV/$F7DKUE^(&/#I614N*,^DPD"7J^F4>T>%#VIBO[J!)N -MXXXZ^WJ`+^2O'^*;B,&+V='YD"G;\_8JGV!ND$42H^V[Q5[B2`:-QH'`/$Y) -MONLR'$]>Y:D/=>GL)Q#S>F>E>KT$C -M:,):Y?;@`IY0G7L`WB+W4F42,V+G3W\>W?Z42VI&NOO7UXG%- -M![#0[V']!A2>3IVS0FQA-8M0,)<'_Q0(5>H-0#*BHWS$^W*92XOZW@:Z,D+X -M8@%J\4:/G2@JE,L$.J$X'/V)=D5C05!FGI]8RI*2WL2K6,YVG5JU_=<:C@84 -M*SAM?.61LJ!-S^Z!%FEOY:%0"([;KSM\ZETNEU.P2#9EL:^@I+,=<#E@&,%1 -M+L4TS9]02F';Z]:MVH!'$Q#D'D+E>-\?6O<2]#2(*!ZW+,]2`R%[0L")5@GO -MERP:MPO.16S5]_5>_QFL0ODO1?*Y")_(<_095)LAJ[1'$G57U;R*=*TA*\>U -MERJ`W?P8AF)"&+PZ$FP8,IYS)-RIIVT0EQB-`H7SG/,=SM7CZJLU3Y%B@P)F -MPVMK;6PU5Q]S?;/GQ?]S1M>ESX#)Q/!Z"I -M-DE%7&4KE*X'G,]VN7V!12X:P@1[5[Z%X=+$KR=-1=*B(,193+6AC*KMCY2J -MXPZV9E+`DD77/F?)L/X-R4!5_L%-B9 -M%>R'0X#T&7%``R/`+. -M,8!91\^=J1QN/T7'38SPC[]QGA``I(&':ELV=EGN2W5U]^^S_T+X#^SE@4@C -MM6\M&V=8)VR%3E/O`?XI_A8Z;_R)B1D]=KB&>/SR-#K42:O8*XARB9W+6OJY -ME;@DUM18(+>EJW3QB(3F`62D&8(B2]QP_7FTF89$*XMY@!I7/_.Q:UX$-"@( -M$--@]E!L_3A?PY8$%%EV2E3FA87DH**.@9#0!&MB@>HZ2QT;Q*=.;)F-?#/[ -M0TO"[7)!$LK;<'Z8PH.1D")2Y46##IO+_RT,#;_ -MYYQIRT,B$3TC%V&@E!`GMAXAWD-.#;^I-`A6\[T$^C[!?QO8%IBHFV;JZ[2L -M&X#2W"R08H9)`_GPH>V(%8>75^R\VB&Y)RH5X;2T_^)Y%N9+)\M0.YAX&:66 -M'X5S-J*`!G_EUJC@H>&S6@PO^N*_XT,5L5F3Z3P)N'2VL&IS9)&N2?PK=R?W -MGR7GCZBOD:U>!,R65`J#)?Y*MHQ7:?]F5N$;&[RQDR8">:H0`9"_G1@O[%L;EVBT6B4_"^M+AL5G"O?(3;`!UT="4F4'U#LM -M8./>N8U(S)Y\Z7RBVM)4&,[C[[ -M,$CN_EV(KLMTX[,>-3:5)DWGRV)OKW0QPS':A;QNV8I)=A5_!?DQLQW_BHA# -M:K$UBB],J#$':<8NO*A0PHB5P%Q!.Z`VQ;ZHAZT/WDJB475F&BHO+^%J\S#[ -MJ$L,7@B"E<8AGGL-K'EG*"K%&R[?CEX$<.%HXV"CMOC]G;:A>D+7'J>UM'$^-YC/F0_ -M`EI&\X"!HQJW*1DA-(CDKF!D[(;C#Q=N\.VX?:T#<$9TA?:.J].P%1,OLVB# -MS^D,JU:+N>3+)[2VRSE_DVM\2(B.B"M[W=!-/G^D,^`8+&=DO`,(EM>S\0-I -M&D]*-BP3/UT9P7$?HDF]'HQ4P#_]&`[OU9>R$W$VXZ%ZSB03J>5EVT1V4\6_ -M)57K<"P'Y,&:]Q*U`YR+H`8O%=J6%\IF-_IZ%WB*M0."ID!YR`O2Z-F5+YJ8 -MH;FC9G&R?7SN^^$=!.Q+[RI+SOO501/G"@;[FN-;>H`UV+_,J/4CC%,;D6)R -M/&^DGTSZG":7E99@RWBF$!!S!1EJ=WZ89#?\Z>_4EHD3ET="L8!0F0X1,++1 -MU]\\/9\STB`SO31$3=K^4&P62^F%TKK.>(2C,-(CQL?47I.5 -MJA<3!1YEBC;P_,;N>1;>,UOC9_83?NNP"7^!4RI,SP:3JZIDXFWMUSG# -MYU4AVPNQWHK./2F=J7NX:]*VH;?K.OT_OR=M&+ZL?4&/L"C%[;']/R`P%G;-#Z]:>:)%\WV!,P^AM#F+2HERQ?]=3AF -M`V1NFP"KG>)!;3UB0*F[^(IJKWN8R2&IUT9W,Z$K^^LYUJ?E^Y/AE%#8QA(& -M';ZM1&QFA*;):F*7UA."#U7+`=8ROJHF^@2(LPT)$C>UMCW;<"">)._HG_$P -M6*-O-%PI-K*CSDBEP3';OW&Y-/GTW8;^`;5&3J=W_>ZB#7ZFA[X^9R0/=1J! -MR[2YN3WJG8ZVVQA_/[290UN;-N->]3*@4R7KT$]0S5`KPF)PO+;!/4RK,SCZ -M*[I(F*?93\/,>-?A;$.':5+;@+T/D5!Q`2"D2%SLQ$D4_M<6$\M+Q>>,;7:Z -MXA(38D!(K/,HET&[!JJ%V0,7J800@+!ESWCEI_#)Y.TD#N-A5S" -M39@H_"W'P?_?2%&FF%"1$LU1Y",!X)CYKIN$TO/KLE+'#'>_8;J.)@@@(WX0C2B1''MPQ3&!)<'A55_33+>H8F/$NSALP_ -MO85%J''"B3QZCFZ!:BN=O>-.]&'%*-YHJL)1YXO?C0H%#35X4"=7UI/B_?>$ -M6IDDDM?5K;E[/D6`\_/S9UTV09[O9X^AKFY/(.]W>$K/#FK4^4,M^I?)M67C[E)_MN"^F87-IW1[FFX4PDIT -M&2`-+_P@UD(V[G\6S5WUJ6_B^GPF7G#KO9&`WZ`NAR0L@0M@LK<#\^\EM\]A -M)E8BJIG6H*Y='T1\?(\&2#JE(SU%JM=KUZ;RJIEDU@D6N4D\KE= -M(IWDB.'Y'5!A"I!]HF3NK$`G3?CLWC+V-H:#KS%SE4EJ#DB3%70ML6=VE-WJT<&"5WGIJ@L-8"7PX,;O.D%"##"(C$:/E -M:/\`R4P4]DIGE"`G?1VDOV+K_K[9?83DX-IX11L2"V%#*H94B$M\!N,\;;J%^/43 -M9?1YNV]FY[2DY`I-O#Q.CM4%QT-<>(99]U3(SL1<,HK"W^W0(ESR>.]XO6_L -MW4GW^P,P:`/__0YDGI-N+B[IJ0RM@W.=`R/@=>\:&,9]1S&F#%/-!\93B\FK -M*\,.6OGZ&II\3^1S3RASR49TL#RM_ -M+H697S`O,7H.&A7$:G7V.%T3>::L45Y%5!4!F8+P6H9U^G)_:`,P`14LOC"0 -MNV/!HEH/]S5>7+BE(I6B<)_H06`#"FS!Y!2\ -M6LV\JP45Q<&/6%1D-H$J..4F(OH:D!]497HUIJTTJ?WDZ(WY4=*[=<=Q-:3 -M#$?9RU5LQ/4+@)P[NMM]<:B;0=LFM(76=L3ML;PXX8D"0^!#YU5@I6V,D'<5 -MU^8Z3K2`8R3)W@/(L")B4K38.K$%1^ -M_'\0CC``^\0/RX?3KV4(XQ0.=G8Q,NWDGWI;@W2;IS<(N_\R;MTIL%WU_]KU -MH+6M:EM_#T/>VH@EK?$7;V*`T$(B'L%=@,%=8$[OT''@RV1>4D:&E?5*%1)( -M+BXKTU)MMH;EM!6H>B`]V,JBA^PIU_D#AIO/Y'NWP9K?@77)!+=2!9EM]B4[ -MEX0P5I2(O'DUC1C(D=.I-N?FB9OURA3)&B#^U]@LN98@GQB)$8I;I-_T+OA[ -M9!F3KGC!:>?J-5`1GI(K' -M^2O#_O+KGKH[CJ@/<$M/-%W80P$RI4K7FJ-"7&=A_"4"+J#86E3H-_Z-PSKT -M%\D)P\"5'[.B(X<)K^ZQ6KV]=E1,Y+J\+IBW#CN1GX")65E[$<9Y+E!+Z3O*BVB2'[_ -MZNC9*ZG,]94RF.))!,5=I6APWOC8B]Y%O4^;BF28&06;J*?J(O3R\BU\(;K] -M!\\""(45)O4LFU1LE^%J`I(Z"0I[T_*L2*)O`PD?Z")?"UV -MUMQ90*#79E."[L*=BM=\3[$UPASE@7M3SN!*N@>.V.&"0.GSFMAF>?]8&^-6,5=4:9I0KR);L^SREKUHZVF&+W -M]6%`$4ON<=]Y_5$#?R8K?I,9HI\4R^N_0!N*("3_@**)=+(NY(T=D6RR[BOR -MHLJY^Z%%;JZ+WNU_F_\I,_F8'@6Y_L.JE"0*[`,IAG@^DX7S#C-'IJT.*)-T -M6_$%P]=M:)LLS^"+>"%O?ZQ-T6_Y(>. -MC?VN@HJ.G!$)9C4.L8[H+KAH/^2]@&F-$I5'R?9?6P<2"G-IRYIC;&6?OV459-ARM#\G34],&8N;=QCQFF&F -MA$?2U:B0K^N:'G02!5EX]?@'+*'H@CAW_`%>XG^$>=*88`$`#<;8TK!SC#=N$O -M,\RNAP3.W@IFIEV3::LW;6'V=\$^GCF-'O?%4B5RXU)&QBB/TBG&81G.G'*G8+\JTC#]+7H/ -M=N?DE+CD![)>B9\DF+QF@1Z1!:$-5OZ#R@G[T12Z?Q&M/L/\]M&AK@V.36$, -M%OR8*Y/!I4UC?=NE@_Q9](O:47VK=0V(,.1*D'<#PG]DKW"V4$D"TE<=+*4I -ME-9F9H!!$2`8TAH7AH\$3"%1^_Y2TF(509F60(EXMNN654#S^>42% -M+UP'BG2K'MA?*%7BM'H:W@X(9O9GH"%^?_HL[E)R#6(]KDKQ#H4&:T89^$=ZYCNH;QYDS2S>+>^\CBHA._Q92&UASF -M%.]9.D/G\I2RY(,31K>^PB@S"P)C42)R3-$;:,8Q32#3L6; -MOR_5Z"-0]X2/(>K,::;UC_?DP/%U95J?21<];\*E1\R220UMZ@[K+`4E3T%9./3^J(Q'F7= -M'QU&\Z-U5H$'=%%AN8\M1%WU/"L;Q1*NK=/XOS2NFGKHD!OP?@\:BZ9$0`!# -M$E=C-!:3%FAAS^-;<#[T>06QKRKDE:N##<4(;V0L&H98O/!Q(?C8")PS@N>H -M(&K&"6`=;$1#W"+Z2*#$]'3+5I5TO?#)S'4VWI++_-\$*:-Q%N/TD8SLKJ$0 -M11OE<(0+D(+J(-O+)^SH03N>P$U$R3T1_0+__(.QO^?%NF3Q96`F'X?1P!O\NSI5'-_=I(.!]"ONKV(9%M'N=FK\E1L9=2$M[K:O$0Z-5;5>(.> -M-^)+@SST'OGA;U[ZH?1Q.DV^B&9-`;;A3ZP)_V1R<&""U,U1Y)6]EE.QK*U3 -M:BC!MI!AJK&)Q5^?C=!=##'1-4]$PU%8@H55#C-:5-2:,MVUAJ4(04JR\5D3HY(E_ -M97X/^F>:$.)-5^&_\/OV(NHDS0,XPZ&'*U[^(@L">F7RRN86=GC,M4SSU/+% -M7UL6@+;`L'N*SH,S_,43;:"=ZS+%X1)AL)BUVYREP?2%H`9H)@$&,3QT'"#L -M/E90M,R6K6HRQE'YX5]C=/L((T/N/>X%0Y3=[S%>ERD8V5@=G#[O6V[WYP5.H^XU3Y$=.I?]\].Z"F6,J*-4P3J^A$SF>- -M;E.5`OQZ'T&)X8[+6?.VBU=-LQ%&":5J#IY[`B2KVH%FOMS[0\B%!;]MD!`F -M.S3]YG>0P0L^Q0&T*9/&<^F"*S$<#SAS4@RN^!KDEUSF,^+*ZL':@(B+)"Q" -MTQ/SQ10,<9U8)4%.<&`MEAG$['I`=(*)7^OP-:0MW9JBH24AO0FC[)Q!D9;? -M!J_B.;28@0Y0IA$C-3)W4W_K8C:K=1M)+[TQ=@:*)F4Y%@1EY$LL2^K4KK:F -M6>*"@)ER"WKAP\25[2GM?S^_O3;Y;\)=\$ORUYG_D`%!QM\KVZ1+X`T8YLA. -MNJDQ*-5FL4O-ZKSGJ+1NJHN/"MJ'*%SPA(7G;00Z[-OQ_U[TX2`H>0/CJ%87 -M;M@P8WRGGOVSX_MY;]UZ#?E>L1&A@D"/=MNS$'"M -MJ3:DVW#/D-)(4BD>*CN\QD-O"LV@^2R+P[3)%M@%D]ACD$M/5Q">JH5"#;K, -MN5HAC!OP816N.%0U'K9X#7/+]28QZ&>QDJ\(`&?JBXK79,5-49_=( -M[CY":LXXASN`70P/"RB[_2-$;9H->!';M*!1%!6)Y\5F=A]T<$']!$"2!6EV -MR,+VL8"/-[@XP)F?IZ5V7HZ7%\!,$HR6/OU -MC4J$]_)<_>S?O^[X*4O$PB6"\9XC#74.U^?@<&O\7/;=*R-P@#]P%&@D0S`#2(AA89;MC=I,(22&:P%-Q55* -MI76C9^SOUR*WL;!>.=;6UH8C1`\*_'X.]R)77S#)I_CK6I&0*Z%@Y%O'O([, -M=%OZ/3B1N3L'5JTAO7FN2-B4^742B=R -ML.-X0^EC6"7<[*$J=):;46>=HE]?\4\0P2C<59,F:EH0H#KQ#[_B-T2SVU`' -M."P/+9[:+X__:^C#Z,:FW=Y?I4Q2FY7."TQ>"./4[A)";^?K:*(-,L&-CJXEIYP(1YU5P99R -M"25#6D#.T%@Y8L'K>BY;I"1I@$0\(_ZBJM*BF$9)Z+`@=,^CA:-<(2UYO].^ -MHH=[Z:['[+B5GRE"`-409T3L&Q/0`T-3J1<8RJW^$&-#=F,FS]H0N!7GJ9'E -MBY/X*8'W/=1A.DV]<5H[S9@%9,G'?RW76#AKD,@A_:'4V#?->8.EA&.A;&58 -M`8='AG4QP9PM86Q`&V&/&`;#@#WO>WN8#[*H+,BX2C:WIEK2P\<>I -MC50=A)HJ75K[C?^V_/YF"#:-BE[O7_%NG3)=`YEU/2^EB\36TCEJ\@ZP5**; -M&5.CL1$@-:9K[T)9908=SNOM#_N]'TTNE<\WM<'XB/[06P`Z2&OHCN)0;OM8 -M\(VB-?KIC5*]E'A*NOE@18VF/74;NA'0&EI+$%';GT@90/?$/!7EN[:<:ATB -M4%6@%:$.\C2+03BR&TG@KM2G,40_-F]FRQW<;#;WQPE9L_[RKT\\ODJG;XJV -M1BHG/[)#>FR8N\CU]ON3W3)G@Z5%D?19OS;=GVD.,DS'>WY<':KD1$7O0'%U -M#"OC#:PI?O(B=U'K2W<`/;+I4,+!<4%/Q+ -MCX,=C?N_^N6L[[="&.M7[%-O?+J[S?1))+348FB7J2U6AE*_;#-M; -MARJS[Y:^->EE`W=@]46!MZ')D@X*,+>@U\>(K.L"3@T;?T0`AW.;_*'UG+V< -MKF)8/#:KCBJY<`,^FU[W1K0V*R'XD%)*LYS0?:@OWP4LS -M/O1UN%52Q`&%='O(=!;-O>@-^,!@&@WW4E"K?LE3R,IMM32U_Y2HD$;^!+2W -MUKP:B=%143DU/4#9.%9Q:WR\RO@4#]U%L`Z#V=C^ZD;_3>DPXZ*_7+QD"ZR\ -MU^`5D;H*Y0J>:GSK8X>_RS9QM*1P70FC,RBJ&C3`T5+2T.+Y:D=8O@HZI-4` -M$'7*Z;FV5_FMMGN\]+1+B/P+8]O/"UU)K:Q:SDIOU)AE`S3+7XOGZZ@J0"ZQ -M#%!1_[ON5:(B199A;@+AU874BM<#L3N0I/)#\X:0VR##,*B7BFZR)V>A4T6U -M-4\4`P*5#)=*NU%Z3,D:N:MKYT,V(/4'5P#*]5CH0'ED3DL,$!L>8X"!FQ"R -M#?T@8O+'Q9,K<(^]7$0^"B6S%J6DW.P]#M\`G=VIG8)F34'*9!09I:4?\>'!(]Q/U$PV-4.T8HNK:9@+UHL2_0R,@DU^I`TT0H^FL%I_%63=(F?OSX(`C^LAT_I_Y*+]Z+7Y%5-^18U!M> -M9GS06&G/L"&(\;7!FLIGBYL6_^V$*;^3+GO -M#'7<6)I;$]$5KLA&]JOJ1>K[!0RO?VN)5`CE*C65K(_OEU-"A'36NG?F4XL8 -M5`8;_B";E<-:FO*HCZ!SYJB9N]%AF-$TK+>:Q=I0I_\D$PC.X$53`DZR0.@B -M/THPQ=PHD01^?@3`+=U5[<$TRFIH8+I+%X>;8Z,_;S,FY'IT@1??PS"H#$P1 -M1[ICU_/=+P5C[L=1Z!AYB?,N`@],-2JKPF85&ZG-U"3]M- -M*,LW#A/:E+!G?D"],YP06D3D:H!;#VO4MUMI1YU^E][Z"U\+A(A3DU>L,TE. -M8***(V)6?,H8RAA/1MR -M\<@7GIBIH'K$?A>\*'^?MZ"Z\:U_IJVKDV:DL.AW,-?Q`4Y6PYOJ+@ZWD[1^ -M3^*\JD,%Z>9Y1"KZU,N$*(QV4;,[JL[8Q090F.9Z\-<$W(F=_)4Z@EJC:#:[.[&7,-SI)LZ/K2] -MQ,LFI),`,.-L[YLS0OQN35R&^):CI8E5B^2<.)LA+_E/@;-#[P>[:=Y%"26] -M,!?Y0AUF`YI,NX4^-/K:B&,RZ7'VDLF./(MD -M2+"D//:]^97SZ$Q_Y#(^KL"^H?)#3@-BID!`*>,'!><7-D!R]E;EZ[IOX -MC@7.0<`AQB^='9V_?2,9G@79$]%7/Y@H4(*UVNA1BH4(IG6:T.LR(C![OO$K -MH'!=!CJB%8Q$''$`F&R0O?^Y[@-R=%F?KE5(EJ?=/I$F(LN%)![ -MA%6Z6V_)44K6!;1Z]*[E5&Z8"*FB+^.B4].'01#C`] -MUT24?MZ5Y4(OAG*/*?^,P"C!/IJJZV/Y>=0#)C`GE21]W?9.](O3;R]Y[4RG -MZ\N16MM?"M#-YX*<\0.018AL9S_1C!//+=J\.;S9T6"S\^>"+2-QBP;_?HLG -MST_XGU-^6I$0+;FO-'B4O_0L5^@*8OQ`2Y@_?=C7VIB%OZ!J5H$@9\GC?^MDVL168=I,7*7DQ^%;"5TT)=N6V9 -MJ*#UA/]GZIELMEXT;EMZ;*?X)%[QJ?1_OKGYDD+P=T64XMRB?'H1TWM%HWV$D:]GA5.5:PT=-)DP@N>==8C^LQ/.KLBR=R?="]?B@!@1Q -M/PG<-E$AU_GW$]6-]-4KI4_4;=L6]Q4FA*ZNAO^_-4WA\8@`9>W*M`T./.5D -MP@L^2.,,'*\SH?^"*:_*E=[SROF(!8)-N';UER=1-VQ-"#FVA#5P1F`G%/I#W=MJ8 -M)Y>1CPW3&+Q\H8$%$%T/TAUA)M]C:-T7DYN2TT*RTCA1V94QX(TL+M?B,F2F -MC0"_M9,U7P3<[DD@H%3MA):2Q/2X=+NA(G%@#4F;;$R3VIAH;'NQD,_$1"`, -M%B1+Q:5,\YAI:UHK=1R%M3^4:SYP<5Q,^[68-<=S<4V'&!`5\GW3JSBG^4BF -MA0&-(:TD$C;,_@A"#0:VY3&"T3U>(EY<67"^3%4Q+<BM)0J*2YRT%6=]C4]0R\]0 -MIB3SLHAX:RT66NYI[[^P[\&Z)BAGIX?=,[H386!V3JI/#FS_R.1V%\8P[,=V -MR;HW\<:#P;)-K+O.VO?L[*J7,V63LJ$')/RBGF$)SK")GR_GF8QA+-;O9":6 -M1*7^%YO:AN3TG%[DUWMA=_H%Y/^`3?-UVEE<,QK_)^-Q[`_6?4Z`:U?`.7'5?#]*D0_]5FKDCQ@)!\2<$V1X%TP$+-^ -M?HT++M$7&"'1/'VX6E83"E4V%?,Z6]9>S$JG*I;G^(&"[,Y-N/,YP)B";CVA -M`^Y9CR&*$C#JE5V^:.0V*@C?/`C.T./]@(*^^=$32!,$H#"CI+,=68MI3D$= -M+&0N@:5&XVY*P0Q'BTU$Q9.Q/6JE)E"D51,T'`4H=$EQ544X6:H\][FX*7.N -M#_2)K%;N:#'=3T8B*W/J)LCJ^YPT_^'Q8F>)9OP!HNS_Q=\9CE&3VB.LN -MEU:N3JP)@+:!I8#Y=Q?ENV73#&7!RMF=O(9JE'ZGL_\+#@/*N+L1SMS5J#+Z]\7 -MT6`-L:%$>U#<4U*YI_B2N=Q5P.5?`F:'`L(M2V&"V;(@2JOZU781*_`8<4@2 -M`5`6,[Y2S1U:Y2'#!]!%U)B;Z%7;3UJ5==>1AM/BY21CJ%CDYJ61PO%//`D* -M])VE60 -M\,*6CK9D@S_(P2MQ>.Q"8792;;7%ST -M*&YWTC`I($$*"1&*N-_C@QY+A@VK -M/'=K!^VN6KD'1ZW.(J8OF8BD-JQ=G97\^K^80M?K!97-.L&1UU<=)?'"B4>! -M`*Q:%%?X%#^@`I%QE8?6JPH3U]`?4HE"W^'.(PT+[#5A-R_0,F144R/&*&&L -M92D/XI@1:&OH@S@O(^\.YLPL"BM[<)H$'T=+VLM1(4^661I<7+S5N5(O'%4S -M-12P<7SY3>M,M+,S/4GA5@P+K`OPP)6CL7M@..2`0D_AKLE`JFI;1A/\/B3- -M;6Q`72WP6E*0P>]KKR/,@P_,)\?&::6Y7_T6E'LP2"C7`IR6"18%(W^4T(438KB&[Z%JZ?14FWJP4KK`2CRPQ7AN1 -M8@4K[\%O;@'J;=GC6FOAH'+?86'(PM?M^L(8F[Z&O$M'G0>JLN#(NFW3$>.] -MP$9UVH$""VK""S6?!;=TZ'UNZ1U\*;-7;U0R+9*<3+A?<'M%N@FU\=VAFISJ -M%"DC;^UG-,Z0@<`R-8;L([EDTF3_3N;2\WRVO^5/U(F4"H_-XKU(RV@QK5AF -MZ"*LORRE3..4!I*&PBO%S;!5B$4,FK>G7%9^Z;'C:H$\!(G<1!"RZ_@A+2'Q -M(76B1M`OUE.D*;,C6?`4TR_8`*=@)]7$X4GDJXLR^N(-$PW(34^YH(O&UG_] -M$FJ$VAS53W:`=*=AX-@NXM98X)N$(,(.*0;AQ3XN<^"8[KM;?,-(CRS767;. -MG,`E8[L];B_//:4PY5,MX1OI2N>].>_14'_>=95J=^P2V!S>T@?`=RF -MC-I760T8A20`W+6RGELC=B5BG$D"P,@)<6EOXIKDBU$46N6>TQ*R$+*55V/) -MG)0YD'\GQ7:.UHJJ8`]SKKC#S>>`N;%]QP:TOSV)7K.XEFB/3%4,(V$+S\.2RQZR -M9<;UDK;\T=_W)*.Y;6&)DV?52+BH\4YFXM1?4LT#U?(A]9+3>._0`G6#Q%?0 -MT@<(H-E"A[(N9D;R[FEH\W;UV%*5C9)D3#%XAZ8;X(C$@,G34788(U>U'(9U -MJCW^94W+=Z@^J?3;F_6R'O?SQ![RT)#CUFAL^[`?VUX_@YB'Y#+>-6J.X\Z--SP+(2LBG%E -M9J:A-']])5MS::)^P#"?\6N!FHF1K_.J8'F^[Q\,*9+G?"8AB4+*/_/:'(K2 -M=LLYG?`R!*=PX=VF62P2G$`)/Y,M;>'!ZG)X%UC6Y6@O,X*W!(&10E%X5D7XR'GV!N' -M=77/ZKA,*?H)7'KT'4X7"=0JX]#;+!:RFK*!32SRJP?DZ4@4W#.Z%^4'*2V; -M6V1K0%^LA\7QE3^J5(L)+ED)2:F\"4E8^'0NN(Y$41A)14<-YAW/_N*?`;GK -MP$Y7KE3K0AF8XE",+^''E>+=E;H,DBO[+;=09:\'6%V$*W.8F?JL,RB7WBZA -MZ37JD^V+JQBA!WOF`F%FVQ@[W',OQB=R)M@9F8&H`OF48X`;W;Z%FWIR>*W5 -M=&1S;$G,:V%@&[R9E_CRCSCB`S.@IG,\@27+J\\&QZ&^F6\6(9+<79 -M8&KU_G.O]7V$#1&9YBL4,P^-]((%9'IRP$SP:]496@]/+:R3OV>\I4`FBNL( -M#RO"38CIK$KE6"52.Y94=INZ#J"QV3JY+]2B`5[H/.-I1\R@Z'8,0]/,XPM<>\PHP:9M@$-;MZ>L-D5=JU']J:6J*M#!7Y6:%1<& -M`X-`<)X%R`X7!=$F*P>`GFP87R-I9-H:7^[X,P/-R;935$^I'^7B*K`0/\E! -M%HZC"V6=PE*F`?)RJ_V!_Y"90TW($'HV3FL"08:JN(4B)("DZJ7*/PL)E<8'LL'Q77C/K+"< -MHG4UEXO%&3?WU;`@L,B0Q>*?!R4YVZYM5H@A@#,%F]"49OZ&?@#]O(TL'N -MDK3O@!9(:Z+3S95.TV#@`SGD=E))3+XP>W' -MQR-L&DQ;89=(&VZ:)D@Y:$J=#GL;3&A!>W%*RO(G''+#Q"INEN4=3#Y@B'./ -MI3(YQNUZS69/$8``&'MA;DT=D&X>_J7-LT,B)-']/R-XC<7U6RVO8XGZSK9++8%;I;#(P0PZK$ -MSY!3.`QK!)\H7_?:2X)7#_TR3G< -M*4;^768#`3]VWRSA.L'[$=>ZTT[3V;F9?U+7_7\Q)2Q$0D_G)-OR.!AP-P/Z -M,WF_IG88R+3-MCI[E73=9#Q%_;V-/FL8P8GGE^$#YX$[8M[4V_NQ3SQO*`?` -M_R1X\?I7TK^0N$L>/&$S`\&=-0,# -M=%2(B/_OZTO-O]*Y>BN_^UO]F'$4?^M%@JT$4^[&(^L_93LM-C-1@(*2=;;P -MP'/,L\LJOB^)2PWV(Z&Y;!:E$H861$I9G:Z!A#<#%0(EH*^Y-'%B^D@?\R+5 -MODR31,LM+)]7^12##(!OPV:T!CMRUKPB^^N$$=&_\?[">=_M5UV'YVR? -MPS8X2U^';F_OVMO'D1];`EDQT2208=6P7[+`2'43@W`#3! -M'IG#E9VJ$A57TC#HG(HE#GB``M<;A/$F]9)\BHR!C"WU]Q$D*=$^GYC&_!@X -M`K8CLD.(ID_8,=H/8C0EHA)8_PGAY*NU443VTD#+OP0;W`\0 -M"A&?.2/ZV5JMB87CBK -MFM.=&S%]MH\ZJ3M6&*SZW@NF#@5_+_QJ5>`@1YT;V`TD;`>%=*+K`]?_:F\) -M]+XQ^&6"UE`\\4(\QGT?FIE!O)!6UI@ZQE/I`9,\GA+!U8;C/!%5-IBJ'F%H -MY'A*SC=94U`OE.1 -MI>XY-7L]?//*M4[5&P;O.,Q:-PG%$;GDPBV'TW)CQWJ"D'H*]FLP;T=+1PJT -M@S=6(\@%V"3_TTGJKU-O"_)\7)1;_'8T:T"6NHAUFE:_IHR+'/-O -MJ.^5Y1I$1/^N_^PZ10/QAL!X8OP>-3`8?>9X@,.XB#RT&"TP4(UF&;H'M;VN -MX00";FCD$T,#AO1_HLQ96(#VX$2$-6-!#0R%+%[/@05Y0:SBR7=T.UJN];+8 -MHTZ/OF=W*;EU.?OC&,#H&R8G]3V[6@"X35C\SQ42J(,W^%B#H`WNO9P\ -M0LA@PGO\EQFD:5/NKLVU@F63'[99C2JY?*,O.O[8`;#$HBA);08_ -MT$=TX%]PM]N.X@"_^R:N[FK"8)P[+]]XOZ_/(_"UU`7,0D*-N","]&=PBK/I.3I4=&*"\J\Q_9 -M:T9)U02][LR2^![=:]\T$/PU85J\RJUM*,]U=L"-]"")-_"H=%$D0209.HG% -M$C^J.7[K_.WC-US.P6%;6G41H7`!V+J,8'@8M(JC8;\T\(%[_Z'FB&Z3Y1NR -ME+WQ+Z(?US8G'-@6=-]AS9Z-[X>P?DK"'2%U]V?'>:1<)S4.[(RRXQ=R1A1( -M$"?H(+-B&(14!_4!#YPE3T]57E*M!\.2?,=S6<1C'K[H$/;'[P][ -M<@1H!H8I0J`F8'>@#Y?<3(%C29`5VCDT"K)4R:`R-7K:PFV\BS.\,H@*/A66 -M^$2KQ*T>DW]M$5ZE0]X5-HY34^[.@ZX6-M_^%1F> -M<8K=023M%N$NQ>>OUDG-UFMH1^!UT?&ZN2:1,T273Q]T/++)&F@(1Y5BJ\9/ -M3T%K:GFD_'<5=2P<96=6ZU8,Z3F`$Z>"Y\9082Y=3H='.TTV+=29*NS6^M?# -M'$:7TPZDFE#].YU7-/OZ-JQ(_P2>:S9"([8+4?$_F?5`-8 -M"5K?-),#S3%*2<$7ZB+6)R;>^\9]V7K#6]^=TFJ-.[=#%J:3"S67[":PMC0) -M&;J\25'C:P^H:PF)TP.TT/UZ6"M1>OCG+<19_61K+LAEP*FUJ#@UJ\<2BR%% -MN'#HJTY2/,S))H`[5&!-3HT<]OL(.?$2F'O#LXRAEB,4W#]9'J"`SB#!J -M(C`/'G:%)+Q@AL7F+&.F1,C(0A#E!"X9&V1+LK!O`>&S&_&WW;RZ#E%XI'`G -MC6DF"SQ/43,W@H?7Q^-GKE0G,H-;#C.-%C//MX2,R5PE4\%;S[E/`$E[C-5$ -MF%Q[!(1ZO8+-=0NH*-T++'/L\$7\5:`EO),6MK4\@\1M&I\T;]&PTF1$U7R? -M7>XO9"!+=@%T]LN)R<<&:R6XZLPIHRINK-E<7>2KG`%O"_PLXJ/CANH/*\93 -ML;R[O/!UWAHK>INY'LDJ$D=_EQ!E%6TT2H'`CUCUCP>Q8Q4>"`@(>2/_GBG` -MLW5(\LK5I+JHQ,0.2H;G%B+?O;(RW"YE`,&65T36(K[9F3HX1'Z-=&!%&=+, -MFH'GUI'\D$'R7X![LTW'\%?(#4_!C)UX%`5FIP:W0?>]*-.>WM:84[P\[F&R -M(KERS<2.QH$TO<6]]'_SP^FHVW%[9LR;_32I6"BGF,82DH2\(N*)21HR1>UE -MERGB_-:62G:MKP(MO,AC93(D:NS'J+T"H&J*@A -M5>$?.>>:%,)`:[LK?M;71!O;47AZEQ[\/:_U8+;LKGDCP!@@*5E[VV -MCHM+?#,G&=4-*W:XGT&R$[CNS6\%#S27."J9PV'N#G7,,>JB -MC6$D:9AIJ_%$=.P0F=#,";F@GJ_'_AG -MT>8$96=9^YZD.YS.-V60OQ`E!QR.HC`CYRX7WX=[A&R9I^?X",Q5G*&8Y']% -M*+H;$(35&?JPB/8>PLG:B2_FZA'/Z_LI/1.R$85F$M>W][QQQ.2CFEJ8[NC. -M)'9SUF%UJ@I39OM:5I5"S?+L4!;^(<"[9Q":W]U;1%^U^1P++,EOKG^`\.G= -MAENH9?)WT/%4N!WW(I)\N*D+?0N,;,MFLZYAME\[&X,&D\MO8/=BHQ>VA0A[ -M7-%&G:.+6U^=Z(O`*Z-9C%A]&23E)IJQ+]+8X?[='&TT@'3;UO`A;1`BJ>VWW]%P0'`BM:U=E]CE+3#FE0Y:BFR=QC_05, -M!=GQKZWC/FG.R#W"`OC]W+@PMOV,LR+BHIHJA$0[D/$ -M()^PR5P!6`;YL#&#(*'?Y7'&^HE:8^*Y[+1>2J,1N)^W@2VJ::Y%+OZNXFD/ -MKTK$K;D-=#ORE8O+:Y;[_8HH0\>"/8QIP>\A'2?WIQB9HM1=! -M13U=@$/6!@9`F=01J['4.&GI3-.A=S30%DAF3MZL&CA=QAUB(.Z0R9J]P"^7 -MTE(R5&C"\5%_)0$Z3DK\&@1*-R1L%]V%I&>J@?*2_BOYI1'MBX*[Y'GC3H&) -MG)8,)]L;?;1BDN]5^.N%[G64P%I7?,(\.8LXH%<\9[]8'W>(;('GO*?(,MW9!H*"CB.5*0_Q/O -M\BBU5?W(QDG,NC#L0'O6/6B2WX@*T+N[HMR=0$I1,FG8V"W=AROX3565]F27 -M8@-UE=_MB1`"1A2>K^'8-J%.W]TX("4D1$DL>7WS'TQ1J>4$KVL2P3L&M;,4 -MO1KFME_):LH(0&-13QDAZX=1\,P.]:\HDU""Z%G!*7U+VPE'4]M[#$QB1>IJ -M?%$4"'2_G2>/./C4@S,A?CR)S_D!H70<50P7A!+3B_@J-U:!U.AE^W6+/Z]* -M3F>29OG=-57M!1>Z$G%;W=V6/GXK?=^#`(6'?.#U^":@`<7%I= -M?RQHXCN7&FM=\6C,O:D#ODGM3I17T*"CGS#7N;9/+$PKAS`CX_M#I4ZMOX'N -MLR"\T7V3"8L8!)^0\X>LELVR5>;5;N"7!WBW4V3)0AYLRN/Q:C?X#NTZ7BJ4 -M/TZV:M9S][5M8=@%^A/1OU/=##A)),+5.@SM&ZR.96XRK<>/8TM)9I\CINF?/W,R!-5'M@V.FO.828?I$?VL>,XI8C -MX)D;<"EJY/JG[()?H;9R^?@5"MW&RFWH?1.8V.;L78(V+7[E*)^C35-8W4!J -M"I2(2H84XU4!X3^Z)BH3Y_7ZVMO8N''>L8H869CTU[ZJ+KWKHG'E.M8=OB?O -M7)9[:=!\&HYLV9T"1N\6EU]$C4D#$@A-Z#@6C7"-(_)M'W"\MSG!C"D9BQ0U -M7%;_X-7ABY)O5-8R.#T;NY-:\';XZ6W1>>J9$D^=JD&YRT1@4TMOR"$6-^MR -MDCM4Q1V==D7LKQ:7)C_@,:7!JQB`K:#\9O1/KF5<2P$U[_A.)AQ:EMN.MG,8 -MG<:A+_-5Q)5N8N_0[_O=W'HP32;'I-Y7@]00N:T5W(AM],0@>WRW4E%F`%3A -M:D,)#J/JY4Y*2QRQ<'[%)KQ_5KG:@65>;+LN%@.R80AX8TE?@.B;Z8&P&FA" -M/EV\=A9PWKO6=(EVYCU!0'EIG_,L_[TU7*8Y-\BYAD1$GB@_X0QOV-4>VE42 -M/3E(FH$&SL'RCUK*I>\=9=40K(/CF6/NC"Q.FB"1PEP/E*+).:HJYZZ9(ZD"PDYS_LIGN6^"/!(&*XPTEY+19[U/^/OB@R9(7&7/1$[@`Y2YY'ROMJF -M)+]:`J'O=M2/?;;G0I;>5(:?`;:<,L4H:4!]Y]>PD(-_CQ%!:9(F35_%UC8N -MK,#P^^UI*C]@]^&@/BC3+`+B?RA,".)'P*(/U+4(M!F^89DK0<8":^QL<@\M -M(2TS5C4V=#CQ:W/%C@C\DR)WIT,%_Q^Z*XKWIL>>!4[58-*C70W:(%?NK:@= -MC/=]1(+\=)KC5[^Q<-K-$HBWKG4Z)K#(';T3&`16G-CQ9&T4IVVPW)?4@IL< -M(25*[JZ&O$,GPA5$J[ZF-KW?V$>#,UHXZ$]>PJJ>LP+7JK>3Z@<7],';THV- -M!!Y2E7-J[=)9I$*ZXCAY`@0UL4E;+&J[2M8$MM-VMY35PKDU'1A(/`T0ZIKV -MF5:SK#%)\L]\$`%9=7J?XL#-GN*%SN<__"0PX`_88&HXB,MWD#LDNL -M@?F=3XO<4-'%.V[1&!<%5L+]M>&M<57#J:9"0M836BXBOBO>B/$@YW^0L8'* -M7ALY"N4>1NW_X*Y0^0,#M4%>"ST@BA1O:@5:G;D+@FLCL9;GA*$ZF!CW'XWS"#D8)T")J#\NJ"Q!Q,0DE -M"J?%)866+E+_"?NV7Q^41YGTX;D(UHF16W!3%&YS6EW%P-5V3CF8CIQL[]ZU -M*B]L89,=-91*L:JX'GBX.DX@<0`1R8[4-=7FC,LP`Z(2E\(D826=/^M$[< -M_4@+1W4K,W;'%3!(SC;3#Y>%OE<-XS9#!Z>"!N*/)ZV&@ -MH4_GH=';P8'4]?M^"`S,E<(<6QSH<.)RH*JODW?N>&W?@Q<2^W3C8-*W!#Y0 -M27E>I`;5VJ8LP5`BNQ,:\]=<'#]'$P@38L@@(DQ]R#4Q8W&J;\Q._P=C/I+J -M8']\HB0V<]^Y!DN@_Z36(=,EIGB+[-9*J+O=?$E50WAN,X"!EE-E-M%/X%_$ -M,OVU"<0/:K6'EA>SE#=YO4&WI`N;P?CR4_H^175#G]?BVVS<@W#RL3(-[^=]P -MW,'TI%FY+)L5IFS;2QR%_J;*S#T`D/;W*B,GJ6AD*A="1-2S[K:7$$<-[Q=` -MI=7PN0A;]^93"W^7K<0S&F*J)T/4MY=?0Q4#;-!SYGT8)IM?C6[_?+^5B^MJ -ML6YOSYC-;M^@&V!^_82I53AA5A_P\CO!F3S2I=G5@JT]_^T`9&G=O[WM:+__ -M!O>VUO?7`-_3>#EA,@77 -M,&A$V-MK>""LPJM]OW;XU^9P%+NZ&QCPX0*!)H6)P1D\>Z-->B8ID*_++E]K -MD2UGU3UGPWU3F:/!VM$%OX"_(NT6"%NR_I`C`1>(@`[H+>T18C<,)VTU,?Y#/(H-XM8&7!+'_S[QYP>HNU!/BE>\PQS1$J\7+^/OA;D\U>X&N9!%"' -M'-D[?T,3A'7#9PAH2!S*3G%O??-6,]FO57AK6KC4/O_XZEMWD68@4U.NIA4E -M4C$!%_>:0Y-OACCQ"@A=O[C7_2B:1XMQ$[M/4'9&^3,LX07:9YO6/XYGTT\S -M;+H%_V&JV'JV26W(4PR?*#9/TY4BRFSR.KH@M1R@/AO,^'I[3<,X=O)-/&)] -M\I'./@53#<)/<]25"(G>R:%L/4^"O9=71VMF%AX?G:[U#Q!HUKSH^)H2'Q*< -MYX)_.&N_!IR?O3ZMG7W0SB7KM:Q-KUY8CI47)#H-+Q@_SK<8D973"W>V[#>: -MBB%A3V?C*4'";@EN!;`B&2"0&Q??+UZN -MK[P',FC9GM)$H:)&J@5DWW`B@1E\\;VLM$BKTMZ!/YA>38B7_H7I<@X@[7%(K#C;%U(>8LQ[^-D6?K)W<:[B -M:3`03-'!@XU(D'BT\OP@O*2C?$3,R3Q(15&4HVG6I5X53J+51*7A7#FD5AZN8H^#U8A -M;D>&(F9N)9SBXI1VY-_F@U@$)$``[0KGAJ.0Q6>P"&C(6Y(D:O&),,``'<1, -M:6)L;M(4[C_6SL/P%VL8,M-FJ4#ZX7T%`H8IVE5(""0VA8I%H6[NY"^+IC)6 -MS=J42X8<4/[^/$_7YW)8!H4RXF2>&.A5`B]O4#9$]W'!3X_J=HCZV&3!;X$E -M,C^CQBLU&MY;AZ9"*4+`_:XQ$B&=Z66NGM_)RWT'ON=+(H)#;V2FC()`E"(# -MGV%#PVC5L+_L0L,&-:X??B&5)^R;#1Q-P>H=*[QC%]ZSVDA:7$1SB%;N$8?Y -MMUZ/T/:XTN$V(*R]EX^@L<:P?`Q`D7ZH:@L>,)B5IDO35I^)-_4<_>0TAQ-4 -M2]B"M+5AW=Y4J9?WT['>@LC;J2T_=S9Y^<)#"9-OT*3!PQ?VW3_`)[-@MNKL -MTU]#/!2V-*&_7_^#GN16R_Q'[%G__I%2XZL1UL["[EZ-T6H,@9"4/P#C]7;- -M1#A7N,89[(Q*[J057#6+7WSC()"?<0,FP&\CPQ+\_1O7X\1?YWW -M'$([QO).02S'3;IWRBY1K-H[`_,JI -M,$FDP,IPN[@BN)_:,U6UJH"+JXV:#/=4@)%,YNW*]"F6T6EX;AGT"Y]8($'E -MQ8L76033C-(JS$$Z@]-@U5&ZFW7N3H%`QC$5(\R%)6BZE,??AK'(*]YOG%#Y -MM_Y\Q_L3VFPGU;OT\(BBN_2P1CC"5R`<\5+@@P(@P -MG>9GODVYI_D2BYQPW)H/^3YUYR[SNKC_-A\D#_4NQJF-)CW6"NP>G)SAQ%LB -MY2:$W=`S+\I!V([*F;9Z0*?D?WR`Y:E"/:,.%U_5V(H],$!HK03#;MP,C$^Q -M+FK7>LX4/"TFZA>P:USKC6!F4:ZG4V"`E^*J.$8 -M6C1TP#CN.-\6K4W=8R4T);BW.6>NC3G5NJ__XPX+K>T;9OMV&[,+=T;*^U", -M0HJ\=BD<30!Z&!YWT-L,8QSV+$FS_,$5V+@YDL8C,9![R%CV==5K>=0\BJ9EP25ZBALK`XXCUE0L+*!GCT06KH5"<:5HK? -M\#(W-DT$6V&--:0=C9@F@C*:$LTSXFWB79SG8\'<1#:-3#&E]>K5K.O0R6\< -M:M'T45M08&4YLX*U;P]A`%I2]2H`KKB'(10\9]GQ/%@+/"_0]&5G/N&/E^]( -M#8\%6[NC%BFKR>$;%/>L@S6#NL]=T:AP!FJ%#4JC_?#!7[C'YPIM$J-_.VSI -MD63Q%%+S>[=/E._7Y8^1P)U4S_"I&,;V$P;W'-@\J]S:+*P$M9^W`3\M1(V\ -M9Z`KO[3%LIRD'N94Z4EMH1EM;'+BHJT@\97NU9Q#JZ@FV&@-$!H__P"?G.-^ -M(015S>7@>R@O"L<->"-KNG!1(D'D#K>5)RA]`;?O;PRI:V?[13U!X;FTV"6" -M%Y=-%K<-0*^MXA.8YE!<>G8\K.-J;A2G89)K<.[K=3Y;_*];=-&]$FYYA(): -M+_P>D&JM#(JES(X2NP'R)M`=I2LGL[F\ECC -M!1.0<1JHMBG4#^T`\"O)SS[?-0K=I?F,[(H0Z7JR],+O'C<"UM0T24I$KCTK -M"8F##+1BC9=9>B73M+XN^6_/E*Y\7I0)#OYP:&@@=Q'*(>@P:.!%`(P;9(#4 -MQAF\W=!O8W@G^F2^)L'.(VK263SRY?HRSG0?32WP%_!A!TY=G5%^_-&3[T.[ -ML?`8`0*C"&@R)2&C$LX5$FF6\(2/HF?A+)ZT+'JJ0W7]2FF" -MFZ-\MJ4>UA'^SGY[G*Y_Q.K&PXL3KYK2LPC/D'4]6K22:I]'#O-;XJT".>0^D8^9RJZ# -M*Y*Z"=D6)O:,-,H&*$MN[:%U!AGE0VM4HOLJ84J]H>3\`G12C12LV0%A<`3W -MEE!GA7+>1Q6U$9L=$J36XASYL1[X]2M/E@^X\"4*!$TYG2F26.+ -M`X::&\L2%I;[:.T!*2SD94DKI"$WFMV -M83.R43/R^(LU%`\:?H!HC)B0Z9/TXCL"KAA^KIL]-=?Y?%)__(!(C7V544$1 -M"X26X2\!@H/RN@)J+@Q#34F.%'/"Z/.[LMW!SV>3$#(2,Q'\)[!(20`>.HKE -M8I^@X=G/M4'#E^%B<,.:*`T(B=7H!3)L-:8U($>ZL.UI+]`4&\Y'SE^Z"&(@ -M1BPH#"^3*^IF@ZO(-5[_\HB8?KKO/_+?,8B,I9SCP$-+VMK!SOHU -M6F`4!4XXD([Q>)<*_S[FK13%N -M+,3YT3"IC'24&U+(X"WLZLEFK6I%D>&(25B7,VF8'$;Y`J/;[>/+8P>BEB6P -MN/I('J,F%J`HU#AG?E\*!$4?G"M_10;1349@=SIUF9)G:C5=P2`#0# -M0G5PVD.VY2WB<]=?@N_'?$HD92_1^;M5]5.K]<^-%9!JIJNO\(!D*RH%CVX1 -M!&E/&6MU.`!ZX%IA!V=0^#Z/[2&U=-1;39_8O]F91-=0TDS?LN?*TCQ'3&B0 -MF0LGM'&IH5G^H$T^.C+_<41W!6V7*2MA`U8&0$DLFX>BX(5_/W$6?G=>-#F9E'P?G.C+2;ZV5%X0%4\2\()TMFL@L3!,6Q[Y9,9\&I/I -M;R>;3B:^9G(>%9KR-TUD*S:])K+TQJU`3_K3T9O9^]>-:+#.=M5PGP[O]C@^ -MQW3K;1&T]6UAF_[!DWDHUD56IC@H]74Q%#[8$T#4YCFS.*,LB?10?!(I70*:#6!,1)V(&]L23=/NQG4'=S*KJUR?KZVV/DSG@8G -ML]FP"G((5/-5$M%Q'3.,A4LN&H625*\E?>$@"('4FCE"!DN$H;--$.Z+N6P+ -M@2+^IL_@DM8=HF+2:1C;+"NQJ>!+QL)G1ABC9Q9'H/=^WU/'-W[_\9FYEA`V -MVZ9#B4ZVKVZ8+]@4994$C=(USOL)FLYP*[SZ,<]"UF>DJ>..4B9U*<:0>K9' -MH:WD0%M$.[OM=A'[O5/LQPL0(*M_&RP@#)&(#DAQC4PJ-=&MFRK%9Y -M:"IU\\9,\+\QI5R810-.D%*DKGH1*)W'!3F%W9GI@N-[&Y<8ZXO>+ZMM+W.L -MD835AY;.5%I%Z314^K5^$\VP=_01?!F!ZO1X".-EY+*T5()&XI291RM\S5`= -MA_P0%X\+QV/_2SGS+C=XVI_;RHCJ&40??$GR7^YJ?B"'C>A]0M9>T8!UQUSF -M#;K^/6;/N.S\92[D'``28\D>*,VYYO1PX8))%ZEF&X*S=5V5PZ\*)E"-GGD/ -MXVFJ6WZ(4\\^DU.2?(@5M>R4852KRX6LAX$MO#:MB&G&.CDE)_W&Q3/A]BM$ -M0`'55^-`7/HQ:R??L^09_RR&PCS&OCAD$$?:5<0$.)=1$]=!V_G/+;%O,FKMI0\Z(+?7.B;\^EA8,4;[GI65X?G1CNRIP?NG$KL -M%J,%-8"$HBP/FS.L9BE"=MWA]GY/"TJSMH,]X=J1Q[I:H]/9_'G0G&TXJKVV -M6C*?>I!N8_9%6CNEKMZMN%V!J.(XYG"'BG!V\.LNF:7F&"H(=4[?YW&J4.2DO0@&\C+OR$B:_VF`GXXR9RRK;X$#99C\SRY-ADN8ASW['6)E^>7MB9#02 -M5':Q.9GQL&VDHM<7/2H:_*WO+RAE,V,7^Y"HLQ7HSL:)F=&&,L8UTP#8R7+% -MV+?TTU.5,`R9G([T8U?>^83U%_SJCLP%1_8H79%'IB)G4;#>C-OV-Z4P8S0- -M#+`Q"Z%*#A)WF?5QO4ZVR0.Q,8;%^NO&'I(*;@T#%RDGS,9.%U"ZC32[&Y-H -ME$PJ?YDIC=@LE'/,KBJ#97:-@S+\X@LD<1;\]Q)>@Q@8$,9T6*.X*W0549"& -M4H6^8L;\_`4G,X.^E/375#S8V><9AIC^LHD?\&DMJ9Z6EDK,#R!&+!'.ZZ/O -M1:=`A>V&5^G3W-6@^PG!PA6]>*%+^#L&[*&OJ<"F1+V(@['Q-+><*S=%N5F=,& -M%*TJ16M5"#_[>$BO_WO0N[_TW8-2M0U4\,'.-T\<4P]R_=.3E3C::>73^ -MS%D<@85GY(8/IRM2B+D75T#@N>D0@UROSZL(=C%=3_>:4*!O&-Z;-7^+_N`4 -M=J\03N4UWBI9*;'M&9-O:3G"Y!N4U_01[[ -M'9$KZ[AJE:L@K+\!R.$QM)LH!+`H:(HLK(+F2(-G/]]%H\7+V1G1D-=ILTPJ -M7W0O!(276MI)Z<6QRM)JM<2P:*UF5H":""A6[83MI?\K%;@HYB0,O**LVM5< -M*G&X^D^+VU<<'(:.F"X8B&`2Z?[6NV0H(2Y41&L^]7F7FJZOY6*8J;?"_!&2*-C(N0 -M:($,FI.Y(Z[\3=ZNBS3]%?518H&1WJW;O/A71'\)G%8(1E<,SM24PZ]1HU5) -M`[*#1EQ^JC2]HKM=EPW;=LBH*D&[H+F=2P9\_-`F*7DE6T9[S"UF/I8)SZZT*O^;;G55Z]<%-T/SMW:&Y\[-D3 -M*M,"M\824.W\0':_^UFMB)\#YX-BXO(QH6/%8Y_?RN62M1B>3@6BEO_7E"I% -MX\U@>1#IT#/UXP&B8BQ(EZ#&JL`3P55?E2[E3E[&J%;OX_T(=WM"XZ6(BP&2 -MBG!XNR,10:"T#)2GL4ZN?Y-EI1D0_&E6\SJ.>8Z*AE.J"=@BE*NI"W^1HZ3' -M8SQ^4/"9+IJWCD$F-)*NM$?8XE+6S;]3?UKR=%`'").T+/=6WL5K3QRM -M4<=LX-BO2K-"(S/V(VI@*$`%][J]/]D-;P6?/=2IOK453^X?9Q'1/.8K7JSY -M%MB][%QPUN-\,7NXV5AL75,WREN,TA)Z]E\%F9\_<&[*=?_!L6&"N6\!"A;, -M:1+IUE+'J2I_/XUD7V*^R_TET:4J-)]5.&PI$U.N)MRO-;-5'IM[!D4T,U3_ -MLYKP^AY9`QA9K9P_U/SQW2$I"86EAB[52W8F]7F.SP<,_ZU02&[L.5QQ=3B" -MG2;6,W%BO)AZ:@4J-F5URO=4;-_[,B0:VRUGU?^*!I7#%A,QP8`$,YQ2W.O4 -M:@@C;;<(1Z2,Z@X^KO<,C18:\.'L1O;^`B1P6)WG4IF'WUE;:R(80BGA);.I -M30+"TTC4!C$EHZ72'AE(GOXLV>V[FH?&:'.!ZTJM6,:&@NP6UPDJY+BZ7]#< -M4.7Y=@&NK8!OST^RN*HS^,)KC!Q\2*_JUDA/'6(%3C(+'QO\,)D4H\^+^JZB -MJ#.S-UU9PXKEH$_CR'&\J0&0)GJY0.D\C,F1?FICCLF=CRG'(/U-7Q-N)OKH -MYK/#_`RYJCTPF-!"8WB"]TI3KTWN0Z!GOV;G5%09MII,@)U-EMQ%T*$B@6J* -MJ'8ZLT%98O..@C^BEU-QY:OU>S$WF-B]MTS-C0\N84O=`Z;RDA(=3^/4M<+Y -M*"UBZW4P[33$@9UY1^HGB-41>MX6ST(\&SID47X$920+"*N!' -MA\_GURBA'=#T">%$6N1I[*`^U('OCO+C>/79IEH-ZSK]^TM?*J,S5.Z41X7_ -M802S)/PU-8?AL:+R,L4T+0<4FMT87=PTA21$"RK".V`&:T0'\A\,\U8F[`X" -M!6M_^I4]?O`@[:DL/"@%,AKDV)E>N="**%K#[$,)WB?RX#X48,W^7MK_9-X[ -M"0$UCLNMCXT\N6^'3J][J4?:S3^3MJL(""I6:2'G7[%,;LY"!2?W*MB`X;+/Z44 -M%F#BY=P>J'T(#:W2@L#[<_][E4;C@I;LE`N]TF;#=,H]F"1/8\\-`"9/YI.' -M.3P]AS1A0M%O5I;=C:5Z5XLYE0;&"8CL@/#-ONA2UO:]D,$O!DN]A\U+>L:B -M_N)=62_9UV3?>#4+QX#._JGI#2=T#_4@00J='/'='P15"]UD$O"50VUQ#,8Q -M2XT&8W=6(*/V2==H8\"X*(=#9@K'C-0?8I*U)%,&ETN68H"U'Z^D%XT^*4FN -MVT2E<^2@)VXVX[_$-T.%!VO/[:.@"]G>PJ$P>_]DN]3YN`95*!^',ULC$FD9 -M.18K4BB6BTUQX.[3,JO`2SLAB*<`S?CTW=E*-_'K`*3#0^^1?=KO(`3?TD&E -M/;(V\R=E;E2=L(#%&H8_U(3K?C!63&PO0Y"9[!2+O,ZS?A-X)I4LM@/ZQ=N? -M/<`R625PG/^?D8(KM7O'7U+2G"U.(J4ALSKDGD!"`H8RO;G(#L[HA.Y.ZK)7 -M/V&><+C'59A;_PGV<$URC`L8[LF2GVJ=EA'W8RFTK4L-VYVAALWCCOT@0Y4X -MMOAR6V:Y'#6$OP3:@S`2NM^6EQU0!.7+/D%-APBYG9:%61GVW^D`Q9YFT90X -MH(69=F1^IUTV!:KY#/,JB(2G\.P`!RU?_Y54EUJ#&[M.49S'>]Y%8UJ30;J, -MQ!E80!.\7F@U,(*XH1\<'7ON!YT0&-^?M_37:^)7B*-?9<)<)5AL\6G_H[`* -MD,SVA=:'_.3+L5)U9WO9BCC^4%0ZVE],L9`[S_J/U8^WH,_SC/-,OT";QKIUB98G.FT;6P0=!&$E07(98,31_@$ -MR>`,(G1$&.P6?_[Z.F,@=F))R3JZ0^P%$L*&YZ_'9S!?K9?1?A3/.4<,>\2[ -M'=YK6E#L:8\+7O1-7\9+PQ\W#9.`JC.$[;M]T(QW*1U]*0(^`1XUN"#4LXHG -M`RVM4WWEKVCX9S,')[L;>-S(41O4Y7-QN[4%!DLDJ0U4V&O`F]K+H):I&73! -M`P-1\^ISTD&=%X;MTIMZGLI16!AB=;`-NG,8FV^C06Q1_G=NTH']-=9V;F;C -M8#(G0!I;)Q)$H))B=C-XQ1VI:FI6?H!3Z7BSS'6RW@TE,8\=L.9_M$ -M.(=_!7Y:%%H:3?4G4XUD1C-<^ZQYT=Z_01L$F]D)8-?7)%+VK/FSV5D?%&L) -MXH53/Z[)\]&6C`DZ5NK6AG@@5YZZ+][ECSZ"OZ5;FLFL?1UMIQ9:1:['@A.7]#@M.3+EANT -M3FM3)>Y/,HRGL*>X*@^8[0=P!.1+R=J8F?\QS-J@&Q&][S4P,/,?)\;LQ2S/ -M#^8R7D#*)+X,<;OW\\Z@CLIX=!GK>]/;_,B6@E -M$0L0N%@J36QQ56%H,03;FC0M!O/DIM];XY?V;]%VNZ- -M,Y[V;>6S(M/WE)/B"!P5V_YH,B"U$-/S^.';UV6_C'MZ_0WQ5]:7C3%T$+^( -M9#=O4[ENXX6!R5#+PWYB?&&N4KT)[I,FV]>=0L3/-F7:2&5R76*:Q^^1Z@"H -M$E8.EN1#_8G_LK`'&;5;9R=^Q^7O9R_.'<$(>_%Z+0@3Z*VK3CJ,3R#5T)6G -MVVB$>V-L0R!UTY=A6E[IQ%BI<"E'N@.UT*;P:,%5>N&)$PNA7C'R/1CQC>#M -MO_Y(<./-]U66B6ICC9O*$@]GL*?@WR:"@9_4D)UC1!SH[R8XJN8U\SFB#>-\ -M#`5(B"L/!*#VKZ62\3'+/6S^8/UV,Q%!L`)\MB!M*NSC@>IU>NJD0EKG``$& -M$9HC+&N7%&W5JA$-,>WX2(*G5QV^-@K>[TCE>NR`8=ELAP&2,19):332>+K,\OIYU -M!M#(_U,2N#ZQ5%"VB.9:%G7$.![,(48YD^[FZX3%%PE<2<]X]]T,D%N4WH+B -M'A:A_(B%F875]*O`+>OF;3.UZR+U8*2(J7KO8< -MKG*)XO/JC][]7_ND=@][\%L0/1+ZEH_'UT9PX1I-W*5`?!N6+'IK$PW!D8.) -MOKST?SH#$W`PVI"P]HHC1_9]4H".R@L7DO^G;W -MO`<4"8+9FDHH0V@2VA&/Q)R*-V&7;;<5R.DTR)@DRTY\,76X#CN?G"60O8)YF"$2%7N'M\CP($/U6^R= -M4?_HOS^1$I*QY<+4Q:H1U>(T??N1[(Y^1F(Q`&VC!MP2$O4QT-;J:Q3>GT&6 -M!SO9#7MR,5DLOS)3]3JL@FK\K^VFO5U*^ZX*(LE*\).X;=]1`,T6T3TL-(>@ -MSDQ"Q)0M-NSQF/?4EMPS>Y\XV7&03M;;O:-H\74(J#KR#N-HAW5JFP'%V*L] -MXP>B(B5F;X++`&J9%8,VS+H1!("P)+@M[-W)!]9'Z.B6,\2%0"3(;L&[$V]9 -M-&D0G`>\];9B@:4?Z9VN[&J$'7N]+8/%@>MZ9Z-A>AA'6681.?Q8^&0'&QIW -MU_S3QNU`IS,]Q"7+.)$0Z^:12$:@0]F% -MV5)#N'\%*%RKIR=!_WG[L^O7E]1(@Q4?8HI;S;JJ^N-Q/O-W]T_23:V%&X$P -MXL-"3[@\/XZ],_U'Y=RZF6HMWN2V5^TT'`!VE;R3\"^!]&#&P6/?;E2?W:)$S4;A4&IC\J$*M+E48T3'&P+_"0#1^.O,[V -M+!D0-'5?C^-J%9F^JOL4WGM3=;I]'D`WH:(1L*3B+_8!%P!Q`IR?@8:!_W>N -M?RN$ODTT'#:-V#5L92>IAK/$$KHL!\0$N2Q7$;"D0U6(!C"I>#%U/4\+71] -M&3T-"5H$4VXA$BN%C]?QZB]RXL>"Y)C4H).[TLZ"-CPC\!^*=9*;8Z^FO'-< -MR4-#67]SC=,4N!1`<$M2X91X0,G]J[+<\H=BUIP8;SGY/SD_].BZO<'1CP8V -M-+\.39X=;;XE*"`DFDR&;36!T@*\Z"7Z!T3&*D!V@NLY+!SL(2`?<&"IG,): -M/:%9A'<*9E82OB>@;.O/0WYBX!:?0KNB.2*VS1G<4AWXYL)-S.+"]6 -MC[O32RMY1&IO`W'.+N]=`YZ`GL]GF_=/Q]Y^YH+#Q`J>;L9GK@?/GM*2]EEWMC,4VFZF#>U[FL=56B-I -M@&&0[.'D3'D-EY:&!,;=FC-_A2.50`V+LPB\+(=.0W.:=!DS-=]Z.;-!5RQ8 -MO.41WO_G.)26WY-Y3,JQ6`V$32(1.ED*&&I%CYXTR]$-Q`%9^-17 -MV?+MO6%$P/&[?@P/WA6PD==?L]A1:3\?^`M-6,93[XN-ZJ#9T39)K0!$T)@9 -M7`'O]B#&QXT*F'5CHLTI2P*[M<,VC^J8'YOT6'85B(X^G@E/FUN6&!HRC'KX -MC\5R2L!10H69*YL!?K\:57NTQ9 -M?U@R,GG=N&[>NB@D-]8SXW+NP'9XF++^P<1"X%W0:"I7<6S;S=88O.CYX=3% -MU]"&^$CXIC"7,*7ERV!Z0_)YT!4]^+6D%_!4=TL=#^0YM5/K<(^]>CO?&S\G -MC*YI2M%A@`"FXU4=H)4G:_J#JD795!+10U -M#2RO*##N3(!6+&=71'5XH5YKZR(3W;<] -M08DR^`2$;(=6!>*=/^+?;IGFCTKTV%%KTP%2H_=2G4"^"U0;59-U.S?8R^J6S].*>3)LR@,.(Y=B=MY:DL@2Z/H@:;*&2T_ -MQT-W69(Z=]2QV>GY_%M4Q0?X?64-+-2_7Q0H1OTLG9E7NW&F?5'<80;>INKR -M%9-::->G4!\>SZ.V>W-7-PP65E9X&MJ[S+&29IYK^(-A<_OY,:42W>6BMZ;F -M_VX,D'L.*#T2I)(RU'TJI::-\;_^:"'W>G^2SBU/1$B)V226S%)]=@=$]Y#> -MQCCA95_6^IA]BU"-F._:NO2#"`GK#F3GRU@N$P8!QGX.Z=<*6@=6[\SX -M3JH#"1G78HM+(QB2'8GQXA>P-#R:$^,O/;\.JZSYZ1W-9?:% -MHU%Q.)1+U5A3?1V"Q9$9:.V2@J^+T0$\&([TZCG56([J: -M6FC]:/!P0,\T^)3&WWS7EQE96X**W)JZ.6K(T1@0FVN+EX1KO/'VRO\4>]`' -M"7CO$RRT8/9_.V9HTS#=J`JB,1>2H<$=Y?Y@*XKMFPBV(Y/9WSB/$S5EL0J- -M7NUCT4<0+89\OXR>/\ESDF]VT%4\==3(>'KA9!4'DJLN#;'OF+,0LWOM)W#Q -MW':4N=/#F@*3CYT)RS))9'D7W[LP\W(.(B/,:)9G1F3XST@5-I%UD-+:@?CQ -MT''T]E7,4W>R@SB`/VG%&1C\NV2;\01"C)+.C?_&>M4F_C%)FI01;1@E>-:UY0 -M3JU1[LL[2/60B^^DC(#46HC6.`-F+_+45:1]#+`&1"N!;MR$R(TA!M'+8LJXU? -MF[F3RCF++Q5F\.F0-<>$KX1+^$XP)8*1N3_U&"5E[XTA6-)V^$7FXCG!%R6M -MM01295)I[GXSPXW#$74`7J1D&7[H\J(&0<(%(KB2,7O#HB[K^Y`F%P\P#*7G -MEB_\DM)]>[:UL007NZ33)!QFEA?MO:/.L+87>A5B/FB4G8W>+G[_$7[D6!K= -MB&FC9(NN$X&H)N"(HR_MI*J:`BB-(Q:C0+S0F37:6`B!Q1?=$UY!Q!B? -M0GN,`O7AJ?IR^>#BU#;O57X%)(5I>1VB,J'QP5^[SC>7(8J`)95JL*4EO%TJ -M9XZ'04'/+1-L@X[8XZ-_3&)WGN7QC[Z/+<`LY42VP$7=;K&N'N](+Z'ZSE`Z=;:A5/%P*98%(M$^ -MW4GQO%"=J8^>1>3?XY(%#\;$OTY)_P2U,@,T]8/%3\O-5Z-?"JPT;N8<+)YOP9;U?`]S(O?:EA[`Z8#.Y:$='>P[%T=O\.&(H.AJSH4-Y<2S>$OBW(IR`-5#,#%ALL4A7-$%/0'7O5TP$:W:CQ6 -M4HG^;ZO89?(I-S]N'"*(MP(@^R0=QL*"SNN<>P*[#H5J4S%SI.'73H.V9DSM -MCOH/;%[.("1O*YK=*`2\JUH##]POPO@ZJ[S_\C7Y=\BI_DGM65@@P]/.<;E) -M'1X=+>XH?Z#^'XQXG%<>8.,\X$3(,",IKV3X#C[U!"PK!G%Y"`=[\U@5YX3, -MLLY(5/F5&)`Y]+]4!P]79%9QF!>91=>\=3^=+,06.)T)2PD[(GF9"'K!1(A[=\CAOO@>^7>J409JHB]D"B(/ -MLV]YA_B@I%VT$3'K_DZ/&M(W63R:@PK][NE'Q=CGI$IN;4]G9`:*;/P7#^ZC -MN%NP:UJS<5I'RO9%X%^;*&B.1I,'GO1V6<%][,PRMZZN^$\<5V)UV7!3-?V6 -M#`[F,`X((M00"&7>TAKQ84>&/( -M6QF[GS1V%HTWXH*D_QDVC)(<3M(^R2;PL.'(U_E$=<_CHNGW`-51"QB2V6]B -M"0I@>HKN)9+\=2/Y-;>M@69H%UF&/,C>GSRH6T/'>1D;[B`EM)`VN`&$3A[7)(U -MLCL^8;O2#*+O5V?PD,E8?/)R$]I;>^00OP0_6[UF+@^7L-X.:YNU!E7`)%^. -M`^[[2$"#8-=;%9Z1TT,;'@0Z73*MY7!957O[%T+L5^)D88H+JT6>AA6'BXO) -M@'0G5\>0YC8#RQ=(?'0@1-"+1#B\/E+.!=)'/]-6Z1R3>8)4G7PH"7IHK7$02)DYZ](^HXN01K%.(P!S7VN!;.1!XQS&7S-7 -MPZ?0RA!*;;&;6I<$HI9%;@8L+7AQK'(V_P^J6ZAO1W,0=5H"MQ.OBORYV;^QJYC/,P8_IUL8W4TD/P!P]'V4"<"]KCR!Z!I>$\13V -M%7&HFF]LTY.?G[^QK[O:8@8*@=A%-,6V&2WK"A':!_<0(#TU -MZ4NL[B@HEC+I-QOLN("$RBCBMXHU9[/EL`'*L&$C>#!8)MB7,!@_UK*EN?^LQ*RA!R7?JZ#<'(JVJ.B^Q)E8IKA'<$3.JL]/I%/NL=:N!?/P0](AFP -MD8"]\[6-M$3_C:?-L^W'Z\\1)+UY0M#VZ&855BF`*UWT7*H`'7/U9.--ED'1 -M\BA9WT&/_'N2O*G@.F.DU6..NM9OLE@^(QFND93'OIZT*BT]HU-EL"J7['1&)EA25AK -MS$[15O\YA.,)=+#]N?U$\N>)35,S)Z66^@UJ@E"6HH!,<*^NO&$JZWNZS3=?T[M, -M",?@48B*!DL.@U6>1R;UD@X1V0XWE<+2L:6_P=A[A"M&SE3=I`J':18GF6'FMSS/*'E5_HE_K/-S"CH?C\5&0]2: -M(='4.^%W6KX?BKQ@)SPY!2C&,64M.KJH)FB*F-+,:4T-/LY>^2D<>I:F`-&B -M;3*``RP5;=:DOBMBY^GCD/2KHXQP124TT_>C-G?T>P]%$HD`P?+/3;;3'HTH -M"W:Z6EK8C4/M_O1.;@=FV`3$/*H6;4S40@0=L%ZD2T#A!`*[R6\-%Z_8J(D# -M3LO&$!ZODE4,Y/&UWVUVWOY0/&%CZTPS#,^TLB#L\Q>C5V75M?SP2*TU%A:( -MQ>*-!9/DTWJ\VC^'7()=J6R)VV,*[@7FX65I3C6I3[KVV39(>W*WU+;C%\^$ -ML/^,=$(H]#!UDEQ&2_%"CNZ'57(.2F/CV^]1Q*`Q,S,/D^!AA"KR]7ABI,[,CH^:UM18_&[#HY@2BL7](&BUQ2SW)'Z!;!Q: -MH%7_!$>5#6IE@X#OI4A,#W7;9&&O#0GAU$^+Y?[.IUR*T*;>W@5*Q9;LP6L5 -M8M;UV&(@PSF*>W[B6N\0P'=J**-`*T7)^*00!+7%D0RV[\&;QS&9(]#`+PA= -MUSZVJ1]U[4Y8/T3R:M'AQ*8=SPC=<.[DY5WV"#[[,OTS8:15B'[;YR'Y;OUD -MZ4M[ZV=(H=A`"QY%:!\K>)A\%_Y8UT1V+'[(5CQK35PXGV#HS&Y`*L(6L)4" -M(3;2ZT6U:45QI![!HM+!_/YVZWIOP?.MO<,;$V`PLLV*C3^V0X(6"(Y$.-@Q -MNZP_P0V,@*O0I^>Q>7_M0[1\4-02[5=%GLMQ=K!86G70\8 -MCJ)\L2VB,(CNFC-@F;)R+-_06!^R,I\'^)X.X`3:KH-:2&S^'*[/W% -MF"&87G;7TZ0G-#Q\[Z:TL:`[TJ9`*M!V!^+KCP"(_K. -MO4DX&W,5`%D!!V:XG;"RL5Q18M;.-)-'4I7.;$2+,X1`KW%]8?UY$A%+U>87 -MV:)3JO?F5>$W^/R\ST%\F;5HV#$+MMP'FJ7;_$5U<6V6MV9:AU91YE9)!BR? -M.`!I"&\:ES>*M6[;2(F-M5W -M&]&WB#H1>5#FX\'_#`)A>[>6^I:IBGZB^V>]NPAUQ,M]0$B-]1_D6;6L%]E` -MCBJ=BN/D$"],GZNBQ].1ZBZ1-NG5*R%]9_:="NL'/=ICM08Q1X<&1B^8,M0] -MR9)_+V0B?1W<*CO%)M-56^"T99ISXT%`RV"KR"`>C'8+(1IJIMC);WH^M?82 -M2F:1((20$T4:LA,`R@V\XSQZT^N!:2E?J)+Z`QULB>"W><8:9(=2+]6T^S%. -M+W%+T=]G<+8W/E.E>X`I$;$M-9UVZVUF>"0-*^']9Y=`7@<=R1F]G,2O@*\? -M[&,Y>.&#//\-0'O]G_^J4LH+XFM&>1Y,6TJ4G0.<`.'+B:G6++A2]S*8,(3% -M@O@3-)A+%F*S?THBC;U&:: -MZ5YV%B3_BF+!2K9?J((!S>U.=D*AJ[6LX.`]@ -ME*L13?E$"<94"(JT*W$*&0POSOBX;"LUEGK8O-Z)45I9#>3:JIB!A.*UOZ@^ -MHI+G?H&/;'E*9+L.R-M-6F=&9_AD_5&CU&:C4V+=90V8@8V255"1]+W[@6^A -MI>(,;![RQM'WTB$\WG@8>>Z;'_D/SE^U.R>0_ETW'(E -MDW`.><2*9;I>8D1()%#DL]9*MV&IUU9R.,XHZ`N[UY^A,A3.P'N(PQ6L>AB# -MEW36;-04!><%2NIP>\)B0_O!1U0P,R[TNYIR"S@XA%:A7?1[ZGF2@ATF\XLA -MIMVSO,BLEVBXC%U_N'@5/[5AZC4>QI@3F_=787'E-8_^>%VZC#_*SMKUS/() -M:XI42*JC&>NAB\AY_P&;1QB:`#>UAS$6+`%C0E4_J%U$[%/Z'=S2KP,WB+:, -M$(NF0D-JE`.(JX,/K3+-79=-C=9JX%J3R/"LAQSZTT(DB -M]/@1=/2?%&.DH>V5&'!?H;GNP@(%FKM(!SSZ7JZCUU9C^X\]VT'"& -MS3),#/:9KS9&7J4*LAY>S4B6LSG*?'$JO-E:>][J$G;FH+:\;G""S,/9/ER= -MJTW='2M%NC"YL+4;:<;2G]^<,,^$X<-'D#?IB&W8D0RW>/)_%NPB):-ESVX& -MQX!0V/:N;Q(508NGV=+9;;^:2W)?`LGA<04'G81!A@%VLG6L=V>Z@VZ5Q\\] -M!.-?G9!3-:OKS?1'O[`SW'/'H[[Q@UV'=?SIDZU_DA#G3E>&,&D$?/.K^HS9Z=:U8M!Y/4E?MT9F"7]_R2$B<)_2$E3^C1SP^2]2[Q3HAW@LC* -M9J4@D[)/!>=ICYE"_C63$"]>B_]??S=CF6$>^0/"EHK&\OL++FU'04Z=J2V5 -MOC[?W1QE@.P7$!G&OA*=$8=5EG`*9](2XK@#4^*LF3`:F)V'Q$'M>?$>7W6: -MN!)>%SO@._&^UJP<0,.&`(A@LT;/[.J/]L!0?=8G -M;S!Q64O+*$B$VJ:&U+R?-F_9C,SU$V9Y7U:K!'J[/_'A-(3?3@PG0'-U1D`_ -M69-XUF4$5[&TQ"/T@`B]S?DI/G;1O7A."%`Y0,-F97=,#,M7).\H@T09+:`E -M%`!J4MJ1NDBPI`4W5N.#>_"E;^3H3^1"S&O^NKO/\HV]!`QH#* -MGTH7"V-M;#0M@T-MN[`FBV9U@V)#5/TB@.H,#+,A\ODLS3==6NEWLG3=)9>6 -M%'6)341>V&&!CQ4@L4\A'`3A#;`"/<)V.CDH:P2'DN<'+\VYY?@+2)KB2+GK -MK0=?X[+@:'DQ(KZ)+??\8])HQS^(KE@-V5LO+/KD-6$#5Y*AL]$K!Z_?20(0 -MHQ0_*2`>-6*^M`TDE]\WU50#.3#:+V3AA-*!&8J@\F,2O_T3#VO^Z(%O= -MO13R_OKT%.#<90)4XQ!&[\[\T!P5ITO&/;I2A*2N62,!/,%-3!& -M7V0_MJL1J3/EDESZ?S:.P'.&W3.E,D$_Z>S!-.`I"-(GFR5^5'0^`YG3;^!5 -M2<*(9"5AX0UU$2D5$Q&2>N9V+F3D3$9ZD'O'^^Q#9((0Z#[5< -M7>4TGIR45K^WT/X-XSR+OG69OU52@/R`,V[D($ -MZJK:Y_R>?T?L5;5W>ZC(_W_5S4TP"K8UK.UJ8\QR:\0-XN>%'962``ILI)6& -M=X(2!30/^KO<2'!+*BH>I3UK+C&Y_BUJ33E -M_A:?1#88S;:N,)]^;VEH`*+7Y8M)S4ST'((;"P5U?+8-O+I>)GKK+L:4+6^B -M:?!G$3`/%Z@L@2#.@7'T#`!2;X>PO\LAG\9=]FS6P9!B-VH2W);@"]B.C8OV -M>V",*YO^UO!S"NSU;QH!C317R=L;ZM8?;`DQ_="YSNSHEK=J2]@28X\DVJ`/ -MKE\=IB%7YNZ5X8GQ84I:5;0^_;*9TQ>LH+MHUC_#_8JL=Y:@M9)SRU%42:C_ -M08^+`Z5I48`U^!STF!.\2QC$0T@#Y:-VY.7*W67582IO%H>X-T_]\M(9JE1' -M*I$Z27/I+[),/YTWR<5@5;`6X"C_O-_UW=M`@.1DQ0:+FJU&F?S!X43JW?I\?8M2I3B -MO4![V:=Y34DKX7WN8J[A/=L'P<4MTE%L:&8:\7#2"WZ-LM@/1D0;-DRX^J0Q -MI37KV2D7^IV'SPEYJF'G^QD5LMQ:X8&L_%EN+*O5>+%,I)?XR?9CGE_ -M3@VEW"\7#:%>V^A$$2^<;W5&&:0]5L63A/I,HWJ#E-UG -M`3/TG7**K&8<,&1?,_UMH$OUCX:L!]H\O70U$II559P[5-"4*1H]H,%0IU2L -M>QR08@)5",7>'8KYK,^^2&D4B,_HST]/[;]]9PV,/B5R4X!YYQ1(!Y/"5A5$ -M#XS$?W[II=\%GK/EFP]MPS`^$K>QDAO2]I=QZC@+ZI\QK'"RUOXIK]HIR)+_ -M9NV+@G$=EIK1>&H:$X\]UG0PX9>+[(#$G55M?"*KEN -M.9@=LM#&BJN-ZT'&Z@.8NL]UP;!GAJUMI[?O-K-N#8JQ-#S#:$4=JT!!8B-' -M6R<0*$/9KTNY3@*41V>]D7N_ANH1Q_)#4\KY7ZS(Z[OI9#ERN:;1[^[C.FZ' -MNL#KU4-0D*T(['4@[JF:_\2%H9=\!I-X9E=5KI514B`=*Q7<$P)FBHA'&']AMH'=@F5^ -MA&A0,[$&TL"-X_]\00G=$N5"0M5O\P%/E^^'/$[L,JWDF=D7%WP/]F-)5"ZE -MRF[7PGU*EYJ@!]C2=?P^XH`W3B2+O>XQ[:IB67B$Y6P8;FD)`:M_F)5U?>PG -MNGC@'K`Z*!RV=$5G!)8O7%63!F#Q7EV`M(50:#66\_?://U3NX@:B]F8XE,O -M\+'2N_V]J68DOG.5;7Y3)%Z@FF8%\_ -M9)M)NE3N"\?*?LO0+K9E]O0/,#6HGU3X+#*I5ONUA.@:!#H -M:@GL2(#@]5A4<;RDO$3YO9'FZ'CY^!J_W;6.349GI1:7*,&$,IQ-U;6J)[/!6:;??BX -M)9(,DRT\*N&\^.BKN[\7-EWUBUMZD,YEML73HOB>M>OOW@=08".EQ%IVP9@$ -MT[6;^BMM$,/6L#,DA/"0'_+?1LMKD-M5C)%J!$(15_FL-UDHUT1B`)B=!?'] -M*[&#/ZQ#BNN+(<8-<[W486'C= -M$2R"E,I-V\VF+<0N6SD>VHK\&CZ8;-%KZ`;+!54.JM(B%ITN]N]::->$IPZL -M6'R_F$@WI8'D0>\8G)$>7SC>Q+LE_ZVRCWC0PL(*+"Z-#&;LXI/;7[UDB&+> -MA->FEB6[!!,$(<_J]K/FU'4&.C&V@`]R$X'E&WI++S_1&O9%1)Y"/T#WZOW0 -M2%L"D'.[;IL8-G`"Y%QG?SK?;%G$KN6/Y$ZZ`N:F7L'T.<0[G\7;I%!("@D4 -M`M(B*>2&"^Z=RD*,:::XR0#@+*MR\\BV"CA`W27$7@$NF7CC8N\0JX%>GB6C -M;<%2K"-SQ[?3HJ9-6BC>;SE]7'*=ADT$MV>X7@COE-B%@OEC+&J-<622=S@5 -MFYHW04,41?R(Y@6=&#G4#!A1*3K,9"4:2BM%OP!D/]DO*KMIYO'F&1@CD<]F -M^+S8NEV[^Z4PC31WS;-:#C]7DM?2J@32Z/>6]$LZ<)5OW9@HS\9(@Y1L.=7P -M9N,MX!:_X^`>W0U]4FAD^J%-LHIE,5BGK^L -MZY*7#')Q2@$O&681D&?"Q>>ML.,.<+K5'J9_4C(3$0;(@A*W15SN$V%^?ZRU -M:.V'5#L1>)O!'7_T5@4T14^HL,MUI9HB83ABI!1=:XZ`L"__#!]<+K'% -MTNJV5LB$9S?Y9,$8`E3_J<:``&7RH.0RG=>90[.'3:]?#,;;(S77=]@K],7? -M'QZ17``[T"OQTP85_BQ:^)_=5M!A%2\F>N&TIXY -M8M^M(0;+.&YN=3E7:0JD=XCV1K%9>[$S,/?0DIH)%YC)K_LV!N<()X3+<.Y1 -MX*&A,V<06Z?M6F/JX'7_&;@Z^_1__T$C4_94`P-$*#1?]2HJ@ -M,TKY$E)R060>Q\0>I^T>!\2ZX8%1!'`Z6JA47P_'4Z$C4HOU">:=BJRT#F"]+S$G>JO::T&JGJ$8GZC@U]%IJI*J<*)%" -M[\3FL%GW;3QC.0A4N`I-H:#W&0?2-;$BT&!F]@W7!,$6Q.T$-'OP&@D2H!.; -M1]\=K90#1;@V39SEEK^;/_K/I];+T^)S.QUO%3[Z`Y#<7`*V2.DV*?'\?`8+ -M7=Q1(TDT;PR808\NL2.!XLU94:2?_$>Z&J+<=6B`'0`K/[>MI"!"$:;*29$F -MM9ZWW.2(90< -MFB:$6;]/91[$3QS`M9^;XEGP.+-"O;%AUD24P9L$>#_E%\,A/K -M1+KJ&@6::^B>`5'P>.L\$J;7JI4SQTRF"3\CU/)[PZQ8?9*;F-0A2/HDO -MOW0<9Y=BX,E1`3.-:YNLHJS0$BFE`%[LWHQ8[F43[90;:$]^MPNW_(D&;U>W -M):Q0"##,%J"1CG!F]+I22"-?>66]K4*&M@J,OBTLFH<<;.F45P!41ORB8[FW -M,AC''O$35MJ5R,<.N3$Y*E<\'Z8`3T:_CUS?[LLMA"-_E%W-(+LC.^W%Z@Z_ -MOJ!$ES7Z-_\4$5_-3A3';O`CBIC597ZE_N#8"R*MFW='/6PDO?I!39_J(:(L -M@CP77)(%VF9+9S@ICVDG2$XO.3(33A6)2IIZZ"Z)E/#X?S.MT7W<`T@#69;Q -M>(%Y>.^7;3&/OR.W-NO"[(L,78K9B5//1.^A4C#J\3,O5 -M6[J5=.PIA)Z!1DP^#AP;G`(&NK'C"25KX&:V[!,C#X7J1;$L-#/,124MKY$/ -MW=D`)*^7Q#L!C*^K(N_'//TI"K"7++(ET-"L&>PA!DK%47K'TFX5D/"=1=SR -M<=[D3BLL\=V>`GQ?6XQL,C%[9%T$8[O"0@S;)S.E#0-'%\$::N`,V?:>\3[K -M@0%J.K?A`T'3P8;L`QAB;E`Q2C@NV%WQ+HTQBI]].]K(Z8;UG@A,&?OKO(IL16L^JD- -M1G_2\K6(A9,)AE76U9/O4\;7/""E%%"H7*+^U`M\1%@G5^FVGLDK]JA=8X/% -M!N941.;J/2FU+3;M.^=>`9]'=G_D&LY.VY-0.%D_R#!HOB&;=K4,])PJ(@W+ -M6PW@A5VMCWWOGI9O=#`1_H//0MO&R]F#5U&RZ6.R1+Y&L&-FSQ%X2_Z6LT8A?GND6I2`4K/0@7]\69KU%?D'RIZD8X#T["IT[]_`"QDR0 -M!<"1F@*PGLTO%6QQ54,]:<-3HCT,#@#,%F[X)G\::`<=Y\O7>I#>`X`N><>3 -MEX4^ZU.N`5##1J,)707Y`PSC"%-X@<7!+Y\:F:"PRC!=ZCT7%1/=A`JW6@6F -M:AB@7"&AN4N`#&C>H\77>).,\'8)7T#/@\V?9<[)$LJ=`=*TE+#@\G$;D[.1 -MW&@QH%5VGX_.O'LAG2[)X`-4E"K,OL\`;A&5S:.QK;YB]GT%Y6;2:7'3H_%/ -MN/\J9Q]V#I:*"A!8;GR6L4YWM8HN)Y0O6QC?`>(NC1V'(8$#%E&@U*T07ID1 -M9A&G`^'-KSG]*QY4D6'7&*9)DN4PTDE'0H9D>3IO'TZKOK$A_G -M1OG'D;PUI1U\;"*H=@:AV;%B?'+\295)3LY#S_AJV$3[ -M#IN_>ZX7N+^I,>DR!>I+(!'Q:"?>#UYH%3B=H4(0AG)-K^W(QN157IN7&#D! -MOQ#6`Y5+PK,E.#@_.D7[<-C6Q+XY/?R%'W9."^]#-BE!`DT(C%&?G0JG_PM6 -M"\2[^Q7`;.$F=N!'07:.Q4W[+50L:,PMIU#H^[X]+R)@-,TP$,\+QE4CP/9[ -M[RP68>W`5(50.^O>Z4'DBNXL$$.;3)4]`BCL -MM7$2.$1'UQ$:XRG.Y)06X8Y/5PFR.6B<=KB7.8VXE2F3!?KHGI^1:57N??FF5C$"U0<;;@;K\:(2` -M0JZP(Z[H&?.(+G.=!LNR8W:G5P.X9`\G6Y\YS5!3"(A+@D?6N'?5['<16Z#8 -MS6,$BFA?I2]AQ+D=__7JSI.[02JHT/=I3TY!3SML/>-3@QO=:[^/.B&6I'-G -MM;HB9N^G_3O>!V\35$/%-SWJ5Z+/O"+?P]IB@&[#ST0#3+FZRC=-);$H4+5" -MN=(0G=H^=(8]#U;GEV#QXU6Y?\(IK^\E7*''I_`GNW%?L;F9?!P6A.[NP>>%XU`%20^M -MCT4`'ZSEYR>WGI_I)'4IO06.2"EK@A7)6LI]!<3J!>[Y'/.!Q -M9WH)U/:_A+5@'R>;#[_-QB6'I3H[F)E%DZ^_+X#7LYBMIB](7E;9 -M%%S@?^ZIO$^R&E#-=]P4K="JKWL$L0E2/Y7,AKA+N0J[NR&6ZR^'` -M=A1)[)/?(_M\8/V',\3Y*HDD[%:'>GCV6Z^WV*$$!=PH4/:+YXL;T._A;9N' -M)3;?@J1X?H0'M**[U%Y;X&65=:;W%L#,-F48QAZ?Q]W22DF9(G"!&$[%A>![3X`XKD(M-6\4,=3]1G5$,] -M=H60.3X]#/`&0KX0D3&7]1K<'84+,^2:4"6S$-TB3['67YA(6^(\0IJ,I$?8 -M:2/T"P5E+=Q1.:]>;&JGMA-5-NV:(`I^-S:RV"TJU2K^X@E.FK)Q)QM+?$.. -MBIS/X$.:6X@I#?A\'HOF0*>B>7[OD&KCY2A<'BF$/CD -M6TOJ<+U[/ZM/D_$F_W3;&C]' -MVU)T`&AI>CJ'B:J'VS5A;,SX!5A.!^VW#.J7F_O*\?_\@N=-DMP-&1Y^WX:/ -M$\A6!_^LV$O-#RM!]TNN4LY*^99?C/N,G2#(DS4_>EJ`[!\&CA\-KY(G2O!^ -M/3/L:FU0"KDQ68(WRT.>O]"_N@]G-VO0#P#4]O[ESV%3O\;H>\P')6Y7`I/Y -M;B/HKAZ]>73T^0!$OVDHP*>IZ\]TX%FY"'3V\,04-@-L,=#K22Q^/)NF=<:# -M(R-G>.EZ:\W_<9,QWJ2BO:<+L.`X(%W.UH&3'@9:W[!-V$?QMJ$Z<.3\ -M.HWJ0J1'Z?/9,&C2;T5?X!&C[XGZ(_J>OG@!L'S^)7*3BVFV+]$1A./?0.E] -M2,\Y&U!HEK+P([\?6O!Y>$PPXA,KYZU6#[>J02D+T?T3BC[4$B=F3_^'X!(( -MY(N35MD)G$IT;7.PW=IRFW^>S)(Q#!JF+^*OH0K5I'GT)?@(CW142PAB(GCL -M?]>/"`0?MLH^4,=`"<:E?YZ>B!Z9(U#XB+M2[`'$<6V$-+IN9($D-"-E@LEY -M=Z*Z\*%HY,#2)7DTP(YP9EN%114<+![*!TB9^%L2YS])+L(F.X$A?J[W -M*T)'JT3:H169;BC/%>GE3FD\CM^(@`=B&PP)>]#:DB[T<]1K>/&0#]6E$5*K -MKBX2+FK(V,W^_778X]NFIH"R-.R$;Y!/E=>,^,32F[>:+P(#$;OF+/TN`\:/ -M%>8L+JD6(.;0Y\'W^/2EU"F9<'LH0^@+^+KN(-Y"];:+KT4YGUO]J$!J&&*& -MK"DTCVGN;:'9I39.E-N"IH'''3$%61G'^X7]98I*ESV(BT,!4<>(IFK7U@_F#W&_DO* -M-G=?SP/.=D[LO+F*=WL#G2]CJ7HTMR\0+2Y@%;I0_ -MPHL$Q2]#(U:W*6Q#K\"^B(O7?P:"!'!LIK:#+O7M>%5C>OU/#&,N'1#0]E.P -MT,BI7!(Y4%B$'B'9-U?N_+-T?U5:T-"&W*NGH3:B&HX_L<321<5N,W'JK+J( -M?:(=>.?C?K4QNEIR08%:QQ,5$?5TY\]!A?NH(:BZEA]!',)+$#5H@(2OO]@< -MLH7C9$%^@<$4=O&GEM`ER7]`%"A/Q_4[RFW@Q=5+B9XVT&;A1&A/5JT6)JK -M`@YYGNF?D(M2.KEGVNH6'!EOZ^+\`>3K+9*X7=/-3=D"[]H2Z\Q78\:WVCLO -MV*ABMGG,9O1 -M;RJ7WO2I>)#`_3)%H/>((UU"&M)ML_C1JT(BZ0&STL8>Y0<6;E;ME.QES=RS -ME@Q';T`_KZ\5M.>^#N"=JTYB;SNJKLIVL]X;?,!LOC7JK%%F9Q^*RS`13>4Z -M).*8]9W&3(B`2,B9G,)PGX-7>J@;#K@3G`O?M7A_GBR8J06*4B -M-K.:5:MV*1'.S"9Y\^F2+HQ."'B=+R<^-AM>3U+!FEH1I#XSEG!/8I81]`85 -MH0_5YQ#*BH/'6":>S>4+^PHX?_BFR3#?.)-R>B6[PI*[A.RN[%#Y927 -M4O'8WKAN^M,YT8+8>8>BFLDF'%&_* -MPL.DUM -M!TLS1X7.]YGYO[N8SW]F=R$FW37W`LDC^+B+F^$\RH>[A:_PM6TC3C*;'&"X -M[\+H5)'#LQH^ZITO3.OUUWX>6`JA#@<`M%NQ4)OXL0=3?"YFJTN:P-2SO;H^ -MF`[>ZE\1X*$6YT:UNQ=`)=O!!ZX7'?.-(_3M(K`5V$B`:AS-1WGCN%XR.G!Y -MFH?NFFTN5#C08>JFN7I[[&GZ>9F0B5[8QY*78%=_N\V'V!^.*NK!(^#3A]JH -M$?6>?PM2/3'GL-]`8O@/,'<:QL/N5OS#]T7>XH"S]FV'![GHGA6AKZFRB9Z) -M5)N7$^FNY:[J\X%44GE^>*F-1Q6<>?OPX+VHG1)VCW,L6!9.&^%AG=60XH4T -M/9'H'J=].E@?]5G[[$C,/MB.EHQH:X1+8!B'U/RXT?N1)KSF7?V<6K6E$:0N -M_,N'DZXJ50`M?`CEJ@(6/@-&4!3X-86<4G,/A5&+HMI*74(T#S]@%T,P;0K[ -M#AQURW&INS/M27X+6<"&X>JBV8Y^VC("ME@@]%.TMVWQ>GZ6>5( -M;9+E$'[=$0/ZY%/"$`B`(=AB0^>(6H0Z'1O\LV8Q4%C1"'-&`Y!2J8C5ZVA7B[-QYH*6FZVJ -M09W9FE&,*Q5]U&88==0F>W^KP"[P4>#N((";,+^V6Y67;:PA_'6`T+E,Y*ID -M:ZO"6B,`ZR@67"LQY1YSG+!#''KRL;-R@8KM.*I2X2;Q:>8!$VF9]BV;*K^% -MO^^>LV]_4<.WM^;3(KID<=N6(;.HPDN$?KQ%Q%0(XMF -M8J['?+,S3)Q(@XP9@70M;.U3;2W$R',%`QPLNQLTR1#P,Q^ZS4\0_F!O($[P -MT:;+C3EOF.*#=+:\\?[6/C10N9XJMAH;87'6J8>V`B5I-QGN)UUF9D$N^<#4 -ML9RO8"483OIE,R>F-<`8)S\ZA]=1``$&S3AP$>@J/@,/9?'/-]C -MT`6N(*DD'+AC\I\O[3[^7 -M3/OIC>2.,Y]#LL4MB2M(P3)`ROLN_.68ODVL^D7N(UIF.]T=TU&D7AF:F$UY -M>&?6/?6!<->(&R5/;EKG<2V*TX1"&I.E^9)71O`7;P'/VLE@W/9VZB0WKZ@1 -MEH-Z["@4DD!)GQRY&,4EA)]"(M\O563>%FD8J#[$;DH;01L.(R(JIK$:$0`. -M)VZ=/:)T(/@0A;(OZ*M'PRU:=\)7BR_SE13U\&_-.V5;[P5CXTTCG\V38)?T -M#)!U.5YP]#/H8VO8$=_SLJ@M%MG=-?07'1<%N?+$Z2]"2(=O;<;46[+?<[0, -MHA\LEZE2+=S'53@&:VCQELWT\,K\8O65P+:F0WTMALX_.Z(0S`59:[?EV;_5 -MO\2N]LK(%?:S#D:?1Y>7)(YNT-=AKQR0_802P)8/=$T.I$._`5P:;%; -MPK%'=<'1[Z[#]'S:>(`<#BC&H@*U>UEF[Y3Z=5/N;!L!M$-81@X-0&A=L#I[ -MWB3OI[#69!DDG'AW:*63_73:5I,*_2.'CI(8FM^PK]'/*(9P++R1!#A6&-W3 -M=,\[F>!)-+>#FIP%*I+XE!C>XN?]7ES]/BDY28/45$*6&W*W^JGG&HGL?'^8 -M8/IJ;],\L\CBU'!A1W@U@:?D#8BN9(X=C*)I0^7\%=UHX7AI&F3BBI-9TMP4 -M%ET422,LK*&AI*KUQX@9OONAO;[:.8"`MOU\)OS2`?U]AQC%XE'$HZM4VZ:- -MQB<)&/X$5"^]"U]U7?-#!=;C1.ET2DIR3R!]F@VNJ,0-(BNK+(P1DY0@OSIL -M3/BZ56A^EK]NH7[4<"TP6R! -MOY^&I52F:B=ZV@A/<>JFK3T9L.S&/P/A6N9"!H\?K,:ES -M7S^@G@5.!G?*&SGA?R)X9)`6C^-N7Z_XR=I"/Z8@DAK1E)2W%:*MOLDY`8%^ -MBX[/\/#8Q02+4*Q][)D$7Y*EEHC:"/DO7B6_PAR%QXJ)FH3;:RX&E>F?"-717\A(>GOC<&$3LM -M,01Z3A+4B!65Q%J]A):C7Z]1?Q5SVK)*;5PG2D?B8$'-K]>B'#8H%0.DJQG% -MAA>8=2X)4WV#+P'&24-K7$;2O#HQ+<-$^'O0UI3J>-MILZL02=E&#\0!KNN= -M3M_0-7_UC\A[A+&G$LI)/BL]_PPF+)J,,[2\D.0L)!@2AE^(%+S*S?YAI=DR3XP9=[Q5:)8<*#'19=AON$%4H>/'G:-HY&S@QL@Q&51!YO#][= -MJ?.]KBZ0_E'E73PT0L"Y8WT[=BHK2I+C9VIGRFUYKG?T"@F[YP)X$)*S>0`3 -MR,SET3RP5LR7K)CL0W^5>\3UA-CI82*LFLE+G.J_D5YQV-/J;*9)' -M9,C4L'4J_X9=KV()8!&78']W^NZV!:2CL/B+]E_=:^(CPK\#$I'9 -M>4=YCQBC6WI/[40(OH'2>170][\M##+@&JML(-2G(P3?>.[T^9'Z!^T[%V.( -MRX.H/MY])B=17J=\7;X/46[G/+VHD*O'%)4]77+WF=G%A1C9SM -MYW*7B!`@KP!DUJ,^'K*.!@V'N'D^AMO^M;.EI=3)WJ1IKW"YAFF@3^)P2O.B -MT1V7"MC4&:M -M)(?H\?RSN6XCN=E[NWIKL.7)3\RV*8NIFQW!"*U601VM+S^;/*TX''U&#L!) -M!?,G7XLA3'W'_VFY[R*,!4KU/1VXOYG&6&>@!)_(4)G397OP)F'U=OO,?5$B -MV&VU<5'1H$"$Y./J5@,APZJCO95T\!F_YSRZ6_OIB1R3(?8#>-)'6]T`5.2? -M+(J<0O-]>&,:M$^+MEH2P7+CK-/DNA.]^?&(R2DBP'%7&0J2&^-:XW?!RY_- -MQ^H7DW*-/OBIWM3A,FW-;(3&6SY[@CU@N2VQ1,>_>JB-Z>F14/;5-HEOV-7> -M-N%%B1T2)L]N0-QT#8E]CE7]5'F(PU@\GCX#P3P/C7$33:#O(ECTR\K_ALN/ -M6>$W9(KF1A`=A%&"/=C-N&$XJ$I/[0^:TC9_"%7M#%BK[J3LLKZ>4-3T$P.4/B9BGJ@A;F'L$/?:_B\,%XADD9:'\T#JT^1,(2H2EV6V[@D` -MVD(.-D7Q:_5@M8X$;K'G#4^7&?Q\Q85J38*)ZXK+ZKF;KDG\_^3):O?"_LPQ -M5SW(+PI?RN39ELII1A)?*AY40LZ,0!`+=3DB4/5>&Y4Y"M;*06J'DV^\I1J) -MU(?!I='3KK$``);-WE]B4-D_Z+FLGWJ^(0T0,2;ZJZO>U%^-2IO;87BE##XRG;"2DG%20^$:4_1*29#)'+J,(-V?TRXX[](CV -MC"QR[R%S40+=2>+EKB3VD=)XLQB[%V+S;3O1=_$K**_/THDACX0 -M"]\:!":?*+<\_-4SLV=^."$*7":RN5R!H8S[Z,:VB??^_\TAX[5U8+L82X>' -M(V1C4U"W?.G&-O*H<_Y1-G;FO0Q`8SM&7K>-KY&Z,#U*>.'."Z1_.'0D-1\_ -M+.KC'T9_G+"[X&#?%'%&3GU([8^EQY<3OSRMKN[ML-Y",/=#B4BA58MK';.3 -M_G#%P>[AA9D,2A+Y$JA8EFIN*W'UXR.$3,M=$C00$'Q1=$0P&ZLH_E@`4,9` -M_QR`9L?*I]&X0F`J0LB^,\:V&S\5IESDZG.+(%)`7R-K;C5V2LOUB?+$S0_\ -M-;.&BR+U,LHBR'67:S&6--,+P\4&.^2]P>5N*&G(8XAF[X*SC\E2/Z]<&ZW] -MA``2V@.B?(&`$H*),G>7N;,"DP89$N]X?S:?$\6OG=/"9IE._B&;\JTO!^3 -MN$`CBYI"<8*\-(?UP_]!^>1'SZC$B1'TH[SBT'@I>HDJZZL?#2%\CE*%Q=VS -MM/,"N>\P9"I,Y)6:I[93;Z+H1;SKK3[!XJ,M:YIQR,.'B:*U.N@TF`>18L!4 -MM*D<=[0)71(@4O@]4VZDZ!XZ34/EY^!J,`V_&GZV&:\5H:X0WN>Y3X2R6GY_ -M]8T^SJ,,-?<38TLU[R+#JG\Q"UK.]VF^GH9%)@._+/F$^=WNIJ=AD!I*[,!XE@^;:=R1G#5[+$[(,6%?"S$O['&7*_`=+J&_5X9WGD6YK;N+0+!2% -MB?W\28@F1ENW0<2DR>]$(/WZESAG[-B%.C'"!:X[/WIV@0&%^0&:D$;,2@`^ -MFF.T:B?!W3+UT,OA']\'A?XF>ZB&<(,D,@O7%L=@)O=52Y)RU/ZMFVUD(X-; -M(UK?)_H\%AF'O?^7N2;2_MQV<&::9+1N7^>U+\M2D7UUD&3"S:513NZXS;_` -MFBI2",R4^19MI-I5'J3Q_-DG=`_*XFW6-1<`D?P5+\YD7MQX%$BEF`5428V& -M0.\5/;U8@.KMBX05L'315Z^-F>6'F'L(N<'TN3Y -MC+,^A7/?U(=!Q-U&F=-^5L.B%?=/HYB84[`J[^`\8@!OU4V:G*7T)`)T':]\ -M>:]^NV'I:\WNWT&T&;LG+'*,3Q*J5\70=G";YCEWOWF^0E[@W;]E'6]`%F -MQ1GYT%* -MI>-=@'&BS43C3*IH'"]?%KEI3!:"&#*_QG)4,CXEY]U8/V^I]WTMZ3Q,M;I+ -M^(7$L&M#Y$5\)G$KG9MEV[F@X_+FDDA3I$":)$*DZS?U=LPY.3#E"(S3X\`; -M[;-,\2R/'OJ4:$T^F!->OJ0/O8HYZ:C"5R]_^&-=$^ACHU7CK7J&&?BE2$5X -M\4B91@*J*EH:R*;MB@^C*H;7H^^@0Z=:P+TNU65R;V@[4L#?@<"=>83)CS_>]@2C:3/))XO)T(JP!(*3\2J!:6`F'082QL!Z^=FDR9:A/I9*+?"W*X6\:8+SNM3PAS[$:6MSSOK- -M;MQACGR]R"6$[^OS>;)50-5%J0Q`8.JQ!"!26M^M^:*8;X"FL=%&CN*^H4]T -MJ%MU-U38";FS5/E4!@#BML4=Z3+NP>!8N"RK-'`4W@:TF3&= -MY>:P]!BTXZW?`G#VU+%5"\"7*5Z1*^YL+M$:^2_/>YI>CRWP@T"H -MYVBR63#*3L(SVJIV*8$,.S'EISZ(//7TE!M-U1(+-;A5]-L87-%1:ZT06 -M@+^"7V.+'7>H(4F.S.)=7/>#2JK@S:Z3^F:=1& -MO<;8*/(9%K-V0(YI^Z5-P5_$PR+VR_EG`+GA?-E6*I`6?VQR[Y35V89O3-H7 -MG[W])ZLE9X9_N2'ZY_5U"_KV3AJYT:/%$;FLL=8(%=69)HV'+TFT;5I50Q]) -M^DG-_3@`1&*VW,V=59K_%'XWD7OW]?!E>)H18?"#+T178J\P>\=_$0K,!QQ7 -M#M&GRD+.(N9Y42_76-CA\+""/6WW;%CK?,9&A=.<.G?KK5./#R#,:*(4`R,H -M".AR&7?>>5_A0AUOUV>?AYSS.+7D\+HW]B/)Y>L86*` -M[(0VE$=#?B&5>[,=YX.0]BMO95MG=O5_4VR;Y^CCU_;.#C.5_\>+!&I1G0_W -M@"/$V!LJ'Q+A>]W\Z=D"(B[2601,!P*`9II09'8;N`G0@#:H<80GS%*<'^F? -MG367][94*4RD"G-OCT@*[AP\B38&^/1N!IU>OBH<+`&Q?/K'G/U9Y[@K5@FE -M24;*N&SC,LI0EO)O+QQ>+F*>%YR,?VSP4Z:\DQXLD--]3[;W&_^?33'%O"F8 -M+U/1RVHE%"#CL:OAGG(.($@V^FO-4FM:WY#__4\H8HK&DNJ6.(:E^*CU`UL8 -M*=YPVOX.0]SZ!CWV*XF+I5V\2VVD!9N.8Q:`9RWGWZJER%UGM6G(>V -M:B3_S,7`(O]TBYL)*>-X'A$&S-HN+O*7IG/7`\)>@\DJ>D@M7=KC$C@XLNY7 -MQ9"R0]7Q5A5Y<+`&_/0F<+G"B8WS>C-(Q!S9@K")*95[A+ -MXF)3B5J5DM(0I^#89HH4:U=0AJ":&J>F:N]EY0NKN,7+B]8=,-+4/!UDA;4I -M6CU+:YC:75'NF)C3N2C'+Y8JU?,-%@$I+-YODAJK'VJ3X9*&5!FDRT1\/,BF -M-YVOM=E^43O%ML"&XGT?8'!#@$RQF(C981D1^/BJP(+Q2L`L#:0#3$8EH8RA -MH=/>X9;A8?U^!]#;*+9%#M<.0!H;]*2;HE:J-R_<-\98??77EWB@_YCMP/1L -M-2E$O*_JNMSZM.CUP(TW-J@Q]SFZG-B[1M8T#WWT[9,N&Y8B=[R;F(_5*M,) -M2.S'Y.0[`S#D6F$B0T)NOAF:)@"R,4G,?0*P6=W@'<@=/1&[^(P3;HN+:% -M'F)34B()N7V?5&'GB1Y\,JE$2VJ!0ED=J=YJ(Q^@N*8>:HT*%G^H)7TG=CFQ -M_*+IX$_@N)I\(`LW;AZF*!5?&W_LMTMFG?0H^46U=3(NM\T&[?52HU82W(C[ -MD)LW0[N,+T2'*Z\9`00&>'OS",)U)%XN&H3-I,-Q$\^U$68PG(3SR361JW#F -M[&?*)_1^QS2-T$M65,@3=#EP$2XO"SA3("%GC\EN(IC"7[,AC%2U[7"-2DY8 -M_>-67-5P5V6I2O!AMN#^(*^.QE%DALZ-__E(Z,R&V""$'7I@(FT.02\.%*LZ -MQR>5XO?D((N^"YT/@W>Q%G"\4?>#4G"K>(J_]_XY&".147_K>KM4!HU(`96? -M0*EM`E2?N^(&GL\Y)QY/"XEK48>,REDA7J*'J2=B7C5JL%!:X";="V.=*GU2 -MUVZP9)#XG0YRE$75($,1\4VJD=]@40EG&:#55CY[-]V3#."E&C+G$2"4H)IKKBH'C2'5?=%D1V:%A`@;HFUG0 -M#!RYN6P=&8X-7>QB -MMKN23H"-#@R=#57]@9?>#-%_DZ -M4M\%SPZ"%JKS=X_8$MNP,IGP?C+-Z4=;4*(!:8LK,D#_L-M"=`"[L%EE,N;` -M\YJKCJ(/K%PS=?"5="@]+*H4P4X"9N#$6?+2@X`O,5]G(8565H4E2)Z:$G8_ -MHM_#P75EK<@YV:3_V+J2V6-9>W]]3'09+(JU:]70.A]DIC%\:]'5_+8>U[Y; -MI3=N/V"(3\R!;[4YMH`?'K@R;D,N(T@%L)UY7>8)='R>;4L"NI2\4I0Z>_#` -M"T5R]N&R4-0BX-1@",Y;>:\7;'2M),K!\3%;K -M`O>W\PSP%V#"V/$QW]L$-@.\'1-[E:^?`W2`/W?"HUL"15;@X3'/]%O:@,9H -ME(H,6S=!%V"V@'.HQIY";Y!:9\;U-"0B8MC(H/Y;6*:MV)4GQQF*D6H3^!RC -M[>RF5[-]H>QTR/GMOM:_:J(;&R@@[_EVS(T)VL+0>ZW,CNVFCN=,L=,;F=B" -M$>QNCL$\O_85=FOIVX1VHPA[6H[V_+(2,0V)"1^8''!W73L-ENVA2 -M]00N,5O37RR6"@,V.:919HLYJ;'[=^A"'/ZOCPCC].19`7"O6`Z[2S^J;]0< -M!QE0L(^R5K^=B/C8BETY;S?D`LP86">5HS((V3O*?L1KL6*I#(;03`WO(49O -MJSD<'0`K?A>KUG#QA#CJ`YK,[I:GQR8@#^GRN22\OV^V`PXRKSBS*ZZV@-B7 -M;,ZM;$"B1'`JF'C8)E5$LDB%\$0B#B_ZI7/T<@L.8(UAT`P#3=6(0#G5RBOZ'@-M)QCII(R65'#<(<5&Z -M*;!F]!-9";@;U.2@[(KI_;_2P8MLE+\"1QHS-0-"II7QFTOQ1W4C7ZM8[5_S -M^V<:+LUX=?0M:#R.7_NS2CYGCP7LMI7.Q/6Q9U!V$!VUO4Y'R5RPFQF7DN3E -MD?7977164-C8H$+Y0L`TQ-/:>Y&"E0X%U\4$N&5,%6&;-H4IG -MBG)+3+"%<<@R4IV&[8T`O4W085JN-2;K-#G,`'?WY[-R.KK0"M@6Q2&*]W=H -MR/\FRIDT=CVIO^'MK>I+W^*K@P[-<=-&K"@K1337OS?)%1`\ZW#W].AA;94. -MSP%S-IT[JMGA,,5W/>&EU>.5S719G-YF;N9J1CIY>U-@!5+Z,@/?CWFCP%$H -M5@_[E!^QS71O9,C.U/SN%S"=,,ZSO -MMX6Q!;Q&MX"0^OA!H4?P96C1NHT#^L/0$WJ\JCP&,@^RY'DM(!^!(@?;JA-^ -ML52Q,\)`)'\ZLI^N;KBN-[6PJ<(E"/0U\[G4KT% -M'",:^"0)Q^[LO7$T0SE)[,1BC)EWPMC -MHI9NO^'S;.=TX1(D2MAB:[*%]`0^F1^#V'-6I*>827N$;?6[!QP@UD]Q''UP -MA\:-!)QS@44]Z$R8FAC;W1/#W^)(+).2DI/50F7EL-T,"JOM('):("P!S_#D -M.LHXKJJ.=C_\/HP&:5.ES=!5Y3=5ADTISB@"&QR[%#X",;2PBDS4383.2>62 -M&K1F&=,G"<_@KZ/;1&0N8C$VQC.*KB[S)R,2344F%GG5D/%BB0.;%*IYI8>$ -M`>1%7XJZIH5Y'Z*O=<2E$$@XGKC1ITNWW*B+2FQ.DPD7W48T.;LUF[9JS8G3 -MH@C"*Y,D,#'#Q`OUN#T%F)B?=8KY;Q%";4Y@N6(B/])*#`;J\T&\A,1B`?1^ -MT[0_F&]^WX"%P5;<>Y$7%WN]R&E=$OA^-IRXC((`,:8I_6^O3!UE4B!.V -MH9C.2O*(9+-3+6*#]A5'V1`)1UIYWY#`?`LXO>=9)%W1:^M4KJQW-A<3>#=1 -M>M7JCFHN#@ATO4S6<57GT^3:FN_YV>ELUBFYL3;SYJR_'_7J>3K\AS9MC)J+^0UH]TB?784:MYI,YDTC/]:)N9\1Y,^@7$24Z:2X -MEVQ'U%J44(Y?XVJ2P0#@X\$&_@4[5O^DO4KV$?<6HB.<$3LWBZ"GD;8!KUW -M13F/+1IH)B5OHPV4(+3`@JLRA,\Z8G@5.DOTD&)N'I,?6PON^::.QZ!;H2&E -MV]GK2^^7'_97C\VCL,MQ35(*^4:5C2%Z:^HN3@PLJW%>T>NWO[!(.QELB5]! -MXX'Q'L+!,S*O+Y@='\T1NTR!<['BV*4MN/KB$RTN"*<1W:D2."]2LYJ:$IA! -M#EVE3*Q(T&YBK?LTMP!J/1=8R5/TFP#8-E,Y_RT#RL!NL+_FG8?#81OC0M50 -M)H.K=J\II7GHN(19W1)W*Z7IW/1T_H:,EN9:/8)[1J=K&A?5.C&`HXA.41:< -M61.IN5]2),0)..7$[M;)JJ@SLOJ&NPA'KI\*]1D5+*Y-225:9MB7O<56X3C409'3)=4Z;!N$@+1,X;(<@BJUF, -MN2'`A'\(U42#PTW-8I'0PYY4'3W/[H/3;?^)2X2O-M-/7*A415(X2G6"0@Q3 -M+%$.=_R;T(^=#&^FRN[?:)$!5BQ<,[CF2SPFX$;P>,-P!B9D^,T$D#@8UW,5 -M"_DYYQ,.>ZQ:I9@]AY7RX(J-?%"+K)B,M6K#2AR@#T./_%PJ/]U(\H;JA16G -MYM:'QBC#`Q%(N"[8ATG9=LT/V$(.S%2(5V5'BU[HUSA0*JEY,+'!I+1?B%@& -M?ZI`F%/#\_^:=V"W"F=*UNS"[9CU/L3VYT1._LMG&X$``_O_XB&#C-3J#.12 -M[.,AUT<$*^SPM..1'HAM%B7`)7M&+[WSAGQ[;+"CM4:K&OJQV1E5P]30@WX(6?(6/ -M?"H/-S+-O+`G%7`A)(+*S8$9+VG5FQ#%O0=JZU51W<*2"42WH&LISQ-)VX_D -M*X6N]8JM\$8-2RM!>>(]L\=8/1.!LV^38"'V@SIL/[#M,8-_<91$JL@MY>4: -MZ3O6R?PY$FW\EM@B?43K@-VI^_LDV?Y?]K_5#1O!M(H-,@X]=GN*1%I'`V.A -M%#LE36D14K()PH#I,%-2_N*>:E@>G3\B/F+E#$+9S]G%4+I.*[(INRK&Z5I4?S>U:3L"*H:78_&@[O):(='-=-S>34EQX%C%4FOG -M35,6MIS5,K+LRR@72MSOSAM6!):$8S]J&S$.=NO\'BB:(%?;R"]))\R(N;>B -M)V!*W&VN$Z+3ICP]3Z>2J0^_#?/^;Z:M3D@5O=2S&,"2(84/%TP*<-+H"3I5 -M^2@O_L!Y.4L<4&0GPGD*=TJ1T,=5H/^)_18G3M=XC\9 -M\AT#._O)W(%\V6+G,N(0W -M#V>=()#800SHWD&XF+EQCU#I2',[6JY<[E5@>MQL/&D-BW%#Z4Y[-R.+@#\V -MD?'Z\^0M38NT&/,HGP6TD]UP>Z&@S'ZIZX[X#N!L#?XV/LYSA3QL)ZZ(8%R8 -M-U6'U"QO4IB(6\J5T3O/SC@:"O/2B,I1AZDHQ)[PSZ*5<6]](;VNJ-)UE8[N -M>M`Q6]'G.1HAD9M$0G^>-]<2!W';;3@H(0A,!E.84$P(VHJ8&.-D9DQ2%B@O -M<%(?>%AZ[,%UTE;$!S*2W83H:8;RV4)XJDO5H!EL]:$!^< -M:O'A?>YIYJ@J]CWAO@^(CN]0M+V\\CGV.@OVS5W50)$"NR:2"A -M1H>@U//^?_FQ"IY]UNJ+GH<++R/:64M&KR+G6FIUVUK9E]*4M3"ARNU?:8]3L/65<<(^ -MB!H0^JZ\OP6PIPU_%HAY718N`*C7SNN3L:+/[*EVY?L^@825U9D<+JH%GGG! -M_V1>Y=(,:B=9(O2L=JF!$^5*FTL"^B!/Q'_JL4#.%F?D]];"+Q'7]%&5J+/MW-%/7M5H_!OV@J1]8]84\S#+L4.C -M%)MS,`$]4GKX)TXV`>U$\S+-58#B#.[GD2W4L&4>!\B5JS.P`;U%,4N2RSA! -M>-RNLY)+M`6#`EB1=?_&$YDH+L8:3TM[&DG%?DVX_ARF-_SKKR!=/!G6A4,# -M/#L4$FLS>M&)**+:J,\NU@&J*Q>SES0F&$%1'F8%,91ALXY3Z'A`&\XCK6/3 -MLO,TQW"SH=`!V"P,@Z'S_WN>-<4N5?(93F0W!P.(J4+='XA)E]4K^BJTK01E8>I%^:+E;./W>H;%6D'#T">"!X5``HJU8/E12*6L(6.O -MN#@H<8O59:WASH/2UC%-%8F'CO8J%'"VU>)$Y<0?4H['QJ!G^AX\L_;WUD.& -M'5T_G=2(8@@L!7P2!.JA)IP,`N*V)MAY]KT'BR\(P/N!:)5R;$?7@P. -MR,L`^3(2^CO0>B<=W/UL22NH.2;6Q_"4\W#BH1+?Q(WL#Z%>I^H4Y&5WM7^B -MBUA[$I@=WYX?>RQ.8D%E2WRTDN/6[/J"-AFZWWR\,E8^<5S;7!B]GYPMTA71 -MF@Z>B#5XQI3_X>\KN<_U!%ST$[P22QW99X(ZI"6"^G:<1F`6-C?R@:S0IM[R -MV&.URXRI7#4P>CR&N1"8&(V$+_BT(Q`2`E.?WNHI;UH4I?F1\1B+#[ -M.S,-AG,UBK!O&%2FR5+.6RLYNZ?5_#(R=\FA%\+)O[/YRH>A)`SX5&)DYP)[ -M.((?M?NTE_!O\<*BL(`\C'#[I,R]X>LD9LH=>O:CB(S6%[S1%FFX+:SSAVFG -MPM57K$&S!`4T=P_L2@EIHYH4:SF)Z$9*JBRT/UD3R25TE'PHA*53T2@#%WGRP@:D -MGY.S2_,S4;E?X,WS,B8\G[E%,&\*6 -M@U`[N6!J')8$9<'RR!WWH26Z@T;W0<>CXA\0DN5UU'D6^@N'E5JP!9R.]#C7 -MKMN-`(7(?>M&UI9DB6UDS?R#^7;)G5])W-8TO;X$EP--$= -M0)<,PKBJH&\BV&-V?9ZX>=$^6Y"UAKTO!2>X&Q'\ZR]-U[N;5=7:65R,-I,J -M5)L/\S_SV,(6^?B -M"B2D%LA`SRDIU?$JZ6R!O%Y;68+L%#AF<[MR\NVQV]D<$#[!NJC,*\4B7J1. -M*&B-'%<;'I:)TM"YIS$0DMWY/2C&B.G`49Q#R=TQY5]G_>SV'C3':9(6#XF< -M8=1(G.C60_Z$B&\_9[FFK(GY+Y:KM)-=[#Z!_(LS782>%A%QYU:^CNI-(-/M -M0;+#'ZZ8KXW=?`T_%V2U]W?])P#)2B03OT8@W6H+:#P-J7*=L1FFR/AN1G;61P#6J&X&,% -M$6S=14C<38_)@_'BH:E^FY#(0%\XY-?I)L84[JVK26UT)>VP2R#Z3Z1E9Z@4 -M#:FOA:^-GMYT<]LW]\QY+Z`M) -M]3RN0,`XS>'XO-"QAR[VVA/N;I1KME9:G$#F4I.B4`/=`!@G2&`N:#,,!AW# -M],;!=5A0$C6+C9$M%"D6\*HB7(Q"N(6R3= -MD96R\!PE<+9?]&V"._$'6*_#W(H(^)QP6".)>`-E^>TI -MPU6CJIY@;A\G&U\:ENPIKH(UXS3#RY8TTQ#!4B?=8\4W)&P-&"J,Z<3&-P!S -M-_[<0;HQIC#@(^4#5]`0M%J8X862K]89B-MV4IP;Z[^Q'>;Y5!!3HVGQ$6Y% -M,A1%=&(G:SFNJ%!9A-KM0GWY4]'6@EOOB#Q\C@$QL`XO.?4G".9>P:,CNMDZY*,'.X&,>)#B&IR2ILPYR'()>#1OA9WLC+XJ=, -M7_')PZZ"S5(#+YT&87K/^_<4;\0K3+[VV_P^V( -M-RO>D^X)3%0GZW$J^!5($DE(X=1:.LP-\9QU8HQ..EB`L&\>ZE/_PG0+A!GC -M^#]!,,$YU6RU_3*+'`/B%F.9[<]Z5ER0]CL(T&W1$TI>5WP<6[O%;8TX[%/J -M>R'Q1,=@Z/F$'N3\.^Y!DE/7`=%:@>E.4V";(3#X^&?8 -M@1*\IR%^`E##P;!4QL!G\8OFFO?%AJ]HXA0[8.<);4R]=59YHDS$L!]C;S!I -MQ[],A![XM,^UCS5)S,L:@\"=W;\EU0L]0*13"7Z*'&_OJRU5'`Y=158"]X2\ -MB45;'[Y<4'J)UL^5V3B[!="!G6+QTQE+E=_@&4*G98+&*J^>&"DJIV!&&&$3 -MT^S]95"3!=PN[>9A:*/PO5ZUE\:D=1$/]_+[8!K\VNZ[P7:#1QG3,]/`[RX9)).A\*[AK3*61-%%-?_;=>G`ISF3 -M^+8D!LQ9.$L\4'.<\2ZL6YCU2ME$BP*VM3YZQRCDN/`E*?Y2ON_I?LO_LXQ_]Y>`^Y>!2UMVA'" -M+M7)?9;.A%CQNL-+4::&_UJQ*P"PPW:>)I5*8)7^>6(\]!Q"^9YCE>>`9OG8 -M)X5E9'++N.-A41X$;]R98SEXT&=@/5 -M$W%[DJ21-IBD^"CQ4330W8#JJ,Q89!0A+ -M`07]Z6.D_.Z7VEF0(I0:0AO:-YP)J>S[OA=NP'32BYK"*AL=ZA=+"@3RO!KN -M^S2[`5$;.VMYT\AZ%*4GEH%UIW,KB:S;#\/Z1@@B2;M?IKHN+]E%?F:3A\EB -M9#ZV4W*B5TK.=B*V7;>]N\FH\\].P3-W[8=3JY3NCX0BZDA[<)A7I5MY]7XI -MYR7V_=.M5\9/<9?]ND!REXEH"YH/3*@AWAR5 -M:R@\PI^;.K+V_!<1#UPKT/L?ISC,)^T3"(A(PKFL-89Z\,4E/9J,<5RR_88U -ML8RV2_J%\11&JOJM6]SR(=U"+H)KF3/!>;86D"*D+7-_C[L_,JU>D"VY!^GX -MBFF!S6U6&^(G&![FH"$743K1(0C5%X).%64QWBJX5>GH(:_.B&2PHL[*_47W -M^"Q^Q%EZ=>Q8+RH(5&):%QS#`JKWKRMVU,J:*HSC8[X+,O:]N6H3(*&[$@Y5 -MOGK$18U[@NV7HH/;XR2_:KOOOJ_X,'W1$'9;Y`J:L?[6AMCI(^7Y4_X8*)4E -MI?-KB.V)3J*QXUB5?]>6K`=]G[!9[D>E]NS6KY?L$'=,0\`NIK<@%ONXAA/K6J&60??AX`[_:)D9X_6CH6+O3*1-M8MNE=^1*=UQF -M73]I:3M.B2OV`WM]BSWLKS/!K;O/L';@->):,E$="8U^3,06(@[@[_L2-QN!;BI9UAS3VSEB-/353HA@^;\Y0 -M)5+,#%*P-S^R*>VCP1\'-X=FZ>%:XWDR5**".81_PV/X=AP_>A)N -M$VJI@1S2#);$U6NES.>S:+*$Y;B<9*=VWM#-#,<*(L>?![ -M9#NQ-]:L%B"P,X^H)V>1;RKU\!994*3&`)JTL(*\GL`0_HL+$+A&-[K-%!1C -M+8,>&EXPGW?;^U5?QYM4?R';U![72EFLK;C/W=8'+RHWPY@!%,%J#=VEC/N= -MP*]'P_#'O$Y -M#TL<;8YZF*FDO!EC;(9`]^M6UF*(#IC@87EU\*KAW$OV?B'#O>T6C\7.[LV0 -MFG\3H.@ZAZ_=Y<'AW$-..D`G$L] -M26O__G3',:MQD+XWXI(?0=#8*0U/LX.-)$<^#=RV')0AF(;+[,F^")E#['G4 -MI1E-.6,P66^<(#)B/#8R_M)!-YM\:3OQQP^=1\A!BWHK"P;235?(ON6\WD9] -ML](+EK*36H356X*K@9;:TTP4W<74"^QDAIUN$ER/?D>E]$H[F=QUDV$Z2*5V -MS#ROY,Y`_X$E=\^@U/.!][1.CY$<35"Z#IYM,OJ+(=:-<-+06SS6*":(2Y_) -MS\_W=L.V8J(7=<\X95Y?3>+L`L+"K.KV^1&KA5)F*7-^[//D5<*PE2P4A+1$ -M7C!Z7G:T=+6-<[9,CW85OMSB/%ZY/3!DRBV0O1;_\+(@JA`);Y_#YV29<_21 -MI=$^1WQ.&K\ZN!D&:UD"YHT>NNN%XEDQ>J6]H]TURS66IOQ.Q^4AE!MVZ?XA -MV*!/C6[&RA#->5+&^U\ -M@7!:Q5:@PFY566,-^\/!5N`2;)[FXE*`ZMS3BC$,1;553\MTK][$DULF -MUOO`D\!Y$0#:9ST7D;Y -M\]I^1KD:O\3Y?K%2?I&R",F5"]/904FON2NFRSV9_)>YS<`Z!UYM`/OB6H!M -M0X.+6-#Q8`;$6]&M,Q40S0!XVN6RMP!%V4S/T+\=(&=*#D>OP2EO/H42T(>O -M2!WL86?9E\R13R_0CC(*LA*.L20,P5E:229_8G<&+'%DQKQCT82NXFY0*6FI -M6*0_9;I)GE6\4RF''\F2I0!A&=VF_VF*C&CA#,6X\T\RW>M>-X)D8FG``RWA -M86:C2RI)M@.LSD,[C:D1[MHQRJQ$\YM61!KN%!K)7&3^:,NQCGN(OE3#/0T&'E5S_5-W]!/4!^3'"0K'O)*JT7.@^=D?/RIL?7W5: -MRE+'YNC=3S5'`B24(9B$O+/D.V.Y+JY,T;8M^]<7$N4!_,JBJ%5$53(<6]T3 -MB!X:1ANU&)7;SIC[X!%_L^-WGP(7W@,5S3)< -MXP!5')5ZG/J8&5&LOW+"8]<@6;7M!049WWI^14>UK'M3R(*PF<;/20-0(8#K -M)M1I`EF3*Z^-/_5W3C4Z7R%?TC7@U>GA8@Q$QG#P=A1_A`-\TKWCOT) -M-*9MK%%[1^>$--_DI8^ERF]4?"?(N0S42WT3#[;\]NE6$4CNCM"\C' -MI#JM(0]DVVE^Q[`MA17:'S2N"R0F#1RH-/?JC8!S3_/-C1=V;X1)YO[BEQ=-X>EC+OP(59I6YEX8N2:Z -M#6['@AS<;>I:?VDH9O/^9?EM&ISI]F'D7O^35)YC-5:'=0Y0/W@44R3TS1F< -M-&)9B;0^10N((,ZY^"39$*Q(,]-VP6F;[KJOW\C^UGE9CD<#BM[G+[[_?&>4 -MMCWAAX+(U)FD*]UKW@K#K@'\<=.";M?Q;M/=']AIMK9$G>1J@_0\$(5]FG>G -M"(H8WBM2G.D]<$?OY"S_%@S^R]F0BP5"*K7[$4\?PH:%./#Y$U&0YOW!]!W. -MRE[Q?5&57I*Q?J]7F^S[64N1OVE,MQL:Z/%FN2X\5[&VM -MA$U?XZ'OD+Y"`_2HQ"A1I2("=0/$Y"5@XC/E`0EI(Q/I$!]A9I)N/KQR!:^4 -MG_^WZ]O1_%&5W'$,HN$\LV[B&RD:]5L[[I+V1!3N#!*-*(-GIB[N0J)WLMUK -M#WAV-LTVTS#YI,60 -MN%OPF;4?X8#_,JG5J*M++?.MAQ]&:_""#?')'E0'=APPUYP;"G,*1VNG8A0A -MFDPDE4/\JIVT:2&?(HJ_U&)O>/.G]$D\O'\G#2JFJ@8;X3RVT.HPGN'5W,8E -M*C[ST+_!X7U2XH%)(65M];:=LW%!`]=*BHNVJ/>/O/'4\T05B]"UDN8GE_43 -M3#'.X'7'&;!V?J:H<7K(XM(;^3ZD+5#VD,.=;D!9MO(&WE)5Q5V3#C&+>-G2 -MW]W+/&;%X)9A-"RR-D%.#%2_ON-+OJ6ZF>K+['T`G`I,=8BUF8/V`T7'V?0Q -M%+(/&0)7,W!$J[1=C-/[E'$E^J"@7OY9TX]'5?\4+F+1:NT^\#A:#&@BF1D$ -M>8\/.(]^/W8*KJ0M-2G:#>ZLHL%3L("")*9#T+=-<1H`M*E5[1.AACBRT57? -M8G'3;=5O)TJ;QX#"/1[Z_]0TU5#;N8P%*YL.W7^T]8.MDXDZ0W\R=^4L(Q&W -MM3F$0,)&)F][;Z!7W>P4/H&@>+\5U?;>$_5:<9`K?+32,1F7C?!AS:.CD5@+ -M@2@J5LC*Q#[K5S*/`F&!2TAL(X4+Q"V?[E(-5CE"HI,@'J%.>')8W9K2V>^W -M1C>\E^%G5VB+!.O9.L^3EI%!"@D1]?K>`T;$K3T:J@C)U4U@CAN6+LB7]OCQ -M\0"8>KE/()%FV\0];:Y$R<0#O34A>9SG.71&%F#3RY$N:6P -M"7]Q2"1EC5%].YGJA:=&3H-FR@\V+_R`&!5A\N=#)HG,#X90J+=JO -M&Z?[S@GJI-B0E,O+3L&-$YQ5C=Z%'K_R7RRPU*7 -M2NG-@?PUF:?$:9+;(^KW]ZE8:1,N[EXW^(7H^Z1]`7/)(\])CB2K+6I&D9W. -MUZW`HGHT!#8.F\%)`($[(3/V^;R\&0CV11;=A3$?+E>,[1<[JN!H8BHZK+OG -M8%T]CJ]FA$;@/%_-"2%0:1+_78>/K>G[;GS:)%0T,3='F1B+]1;Y1:^YD'J] -MZMNN'HL!D>Q8SU@`%;?Z)L?P^&(V!3P_L&>N0T@S`]8X+S5W@2:KJ$IW'!,M -M'=/DU1:CQ'_BW5#!!B?GZ`\]0F?S!;X_QE!F4T6C[Z?JJ6+ULQFCJV6EHR>Z -MI7HNN#KB>%38H0HG0(N3(SYO'-W6AT_VO2H1#\"1 -M,).ARX\8O1S]5.L\\50[CJSE(?O2&QH*+DPP9=YM`UK[@2]HN28+6C,&YN+] -ME,H0OTL')?U>`Z@#E3`N/X>&*63\\H2]BEJ=8PZJ&+V<4%Q+.R-Y\*)F@-QD -MV;OFH0;*EM%)0+9WRS:UR\J]R[*W7.A8_B9[*J3_()DB,E@B:YW8\EL=&7H, -M>-F!*,$OF<`;'8E-3UXH,)H/I[])2A;W^/DHMQ\:,8),>0;@CDP[3T0_GBXO -M8(4]ZWZ>T/TL;)VB(\PI]!158EA*T*"'JHV`0/W.8@OOS?SY@EH\]0M`HSD< -M^I*%SX["-\^V5)9!/E&DC+BG5QQBS(';O_9H+8:U./4MH@=57*1@>9OWW[BL -MF[8DK;G"DR+4L.W$,XLH.KA6GU$Y;L(7.X/(T=X5R646#2_>>U4V-`(1P[H, -M`O>_FJ5$/S;V\+!;*L$TP(CV<#4X@P=](^W@Z6@Z]@3XX'*#7SCD^FU]L:.L -M.$%>R2_6S77H&8MQ>UI2T>C&+WD$_0R;>NHI]",M&+BR@KCE-Q];=M"]1ZME -M@O0R2EF_VCGE&M)%+.$+B6K$=(#O1N<[@5M)>D9']>L%+,Q53,UU1+T+M++6 -M1O&"NMBZ?,J]H$3';J$B]+1;-9`)NG6>L$"KE.XPK`#V^P+Q.%_,X]#"JN'6 -ME:*7WDW/S#F4A&KI5N"K#J'!_CB-YQZ%/=H/QM$$YV"[(/,59[DIQB;YKG9E -M/ZM)9#>1Z`X;!*IB5L@*T::YG7VODQ[R/N27/:">3S')AK@\$B?A&S`!E8ML'*DU,Q6Y%=_3"7HU&2@O"Y -MK>+"HPDE`.53"!X#NZU@J$1?-3HQK]DAPU"=J@3I6J4M,N56A$BJ\E,M'AT# -M"I16)3J4/JAM#LI63E",5G!!PH-@&NWL^WWZ5B=]T',60#4ESNSS0OV7.Q9, -MYVJD`GJ&S@5U-5SS^IRQ>K_C*2'?-;,Z`,L@"Y[ -M4)A>N5L(_=-\JME_&*B>RP]@ZN,,7$@ZR?0>:68214.9TQGC10-27HH3SB"A -M7A2')&AS#G'ID/%7]/2EQRAU0Y+02;ALL(?$:^%_LX#\IY<'PE6B!GJY!G3X -MI>\ZT3(3IZ/[6R9\*4GBF%M_?"091YVZR!E?C>HUHN$SST2%2M)=ML'&7G]3 -M"8F;+_0(^Q7*X2E4MQ/.4=CX&#L5=W==OBAHC2(;>-9L63(9Q(N](+KN]5[X -MLO-,E.7V:S7OVXDW0P4<^MZX)K\?_:9!&/J<[A".+>;9NFYF.HD7&GO,S%_I -M>;PE37(UM<8&4RH>D)[+498\T;\BX9R<1^Z=%Q3[K9-VL_WKR?ONN)0H5,FU -M?9^P!TLQ%$I*W+T/0$6VT44K'P+(.IR'H%#P'&-]1P8>6O+`%(6T?5#SFM7# -M=V!66:,Y/@1'?1+WYJ,W%%:N\Q93)T35W)PNOW6N);HPRL"'#X:$@3?^*S8: -M**Z)W7[7LP+HE05NL]!.[4J18^,:`D%%3>S8?7'GTD([V+Z&+0SJ7,OZW*FV -M.#!]$=$#)$SQ6[Z=18F8_9):Y^>P&I-NW'/GX1"7GTNR7>]/`7D;53Q"'FUI -MBM'LWXW"49W&2E.J<5FC$;:1IHG%!)X^Y -M5'`+>#[Z]&^R7+@?RDF,HNF_0#1NL]!(Q_FQ6H5RC3V$7S-S1VS-MV37CHD8L,1J7OU$=T;!K6YUL4'# -MHZ'4+3+0BQ57!QHD?B[=_&H92B%C-@^F?6[\\%]J@/3V4;79\C"-#VY@\VK% -MSWU?;8`405L/X,AN?64$1?[$!)\S2N`2<[V -MRCXN\"E$585(V/Y8PLJR@;8;V58=+\[XJ1<.&A:#U@?9)$=U@X"F=:SI4ER1 -M8X=>,9.TS:*,YK]'S7[1!W(GK%C>Z\#A2?",2!(V[>.3H:P3A&M6(MNCF0!, -MQ8LE6?UQN-NI1`U5DP;67`6/3;;*K1\?.(D?#=Q5\J*^D)A00=6*>"73&.%# -M-[B65UNG!C2^^I"6?`Z\GQ/B.!O2V3R)X@IO1@0V9I>+!I#'4_5N#<%.;KA`>J!D0]D.?AVX9L=*5TX-E)5 -MB("[?P=G1D\;IMHG7'F^K_CX&0].*;?1"`Q>]4S_GKA_'B]]A)@IE0D8,<;( -MW;D;_K+!=6`NU!;2\,E3]!;7'16&[UF/%A[299TXVNR,;>RDX0LHQV**._^[ -M(U?Z1EI6L>$1]+UI+2HQN-OB:Y80][IJ1NVTGL:USEGMS8Q%9=(5=V7"1JFV -MP_T;^'.O%0E4=QH2^:QOEF.X1SI+"Y_BFKZ(-4$.I2)\XVD=YN&1!MG95UU; -M_(K*N&BHYYAIK+@CK(W@_AS@,B)@6@2##?[1I<3EXG,T->D@UK^,Y7LY#EZ9 -M^ZSF0.GXG'C%QI]-.:"?]-]35II['D15]=3VK2C,'XWL=.P1//-;"Y;JDWWA -M(#@DQ7^(^Z_SB/17+[_4U.RI-O4LUDOW^$B".=F],%A70+.!Y[KWAU7N_52- -M(AH5Y1((_$1,<1%_W%41"M2[8]@#"\_E^2A!T)(-OD0KM?QF0!..&J__7^)' -MU9Z=^6WZ3CH[F8?W,^-79)IDLM.ZHQPM'Z>Z -M3*HQ)&..C#YL%`$W=HYO$B)G%R.4*J(@@80R;KJ])[QA;>HN$RC+%@ORUCF` -MSHS:WW`3F13`]B;X$:_X#:&D$=OO$+%=Q1YM_1K/5"5X'0_`GK/Y%N;^MVM6 -M_MS2<*%[$=WP)5"PJ93!(Q-ATZB85R95C`(E:U*#^4MV:3$#C_@%.C=G]R-G -M7AMEO4G$P83A]DCC6QO.`$BZ\--X['P6H)F&U%J1\4H8U8OU74A[BN)SR8"J -MZM=PX+5_]&Y'&2[A4H)1^W[M%@QL=?34^[0>:(;VVI1YHF6Z -M)7(PVN.#VJGDZ3^W'(0I'@IU7V/WWG73Q@6"*H#E+@1I>],AO,#N:&SC'/SX -M>X4C1_+'5JII)+JB@Q$*YU6B)_`W<^AIZQ><\)\_2URX"VV4OD-!+&3$E+W+ -M'6\#%8YUYB%^UO8B(X`:@W^//P)-JYJ^?4.+5'XN#$FXNSL45?#P.'F$=.-J -M%B)[1!?$^@XR'Y?FMOUO\4BX69QX#7!>H*R\V@)AOJSI,85#(4;\38Y\!E77 -M]K)_/YCO8Y"4TIWP=>F1S/6^#OKN=[J;-UJRCH""I$T -M]@@T(QM=XK9/WB"KI+[`IS(WA1_!MO#BT%(V1#<3G/&6C-(`>?.W80!P?M^87>KBI%/`V8?"3Y/>7S060 -MBCI'?$I=$XU3/L7[^J\8BU,\I.B2KC7G4. -MD.HS^8?K+_ZLY)I<5+X(Y1=@36;+5+>Y0BI46>\6!"S1V=$7@F*AF!F553DI -MWJ<(&_>G0/2UOQ+#:*"J[Y8SF+3!S;)%:^`>_M5`WG9;O:ZNE/$:VH-(D6M* -MF_*?']6!NT?XC-4/%'&^I(236JA'`K?'*3^/Y^QC#&@ -M-A,^HAM[;W/39JV&2'+-D>I?Y4KIX[GV'JJ/I@&*14[GDTFD`O- -M&JER89X9Y!$2!"#0#&YJ.9L=>>&P[]4"@^ -MK((Z0TJG()Q,@)7?Y8]S>,`;E`I;IZ>\1^9LK0"G)E1H@9L)]-3;!EY/#_UL -M!)IR7IFRLKL$#GQ51AKG&]_QO!U'4NPR_%T_V)1O`G0-4]F%313BGZOA/-). -M/"&WU$L\;^"Z4)9''HPBY,T1_XQ.[3>8J@+P+V%,MK1X&`,?$O_^4MDEQ[`) -MI"'(3)>H9O%0,5H[UM6ZUOD/#U?6R:5EZ)1C95F,QDN6N83FOOD89+7+*B66]8\^P9;@*.$KPPEWNPTD*E?L&^+="`^1^1#-,=*%2'/\BB -MC]H1+(=A)8Y_Z(V+-UU#<,)Y]5F*4`H(07^N4V%SPIL[JR4M]6+FN3)?\<[3 -MU57+L0JT6BI!0]E&&5S(N^GE"8KHCH:FEB#R-)Y2[VXNT#QZ*)[^U&^UKLGL -M=]#FY2I1D!<'PQRZF^@@1T]6=YEA1I$"ZTAYSU+D0I;1.F+W%NI(G,0O -M\(B!_('LX7RZ=&/M#D=KUJV2XMZO*2Z.[V=4+V03*:3D3@M9N;'M^6%1#L&` -MTVW@D->5:M()2DE'J/A46SJ+WWS/5H#9P8@+`B,51FU6L%5$4-\V,&-:MEOE -M.&`\[UQN=?A;:E7Q2;VU^-EJR9>I#$#[E##RB)AC-K=*\`>$.GT%_?++6\HC -MHKRTWA'9$[E"'"Q[]%@;^J>I%KHES]?1\,6-E/9X`NB,47,8(K_L1,+3K+:C -MW:F8I"%?7`S!_="?&4F1LRJ@W*1B5$Y,C>W/<`IM8,?229>J;.[335AL6E_K -MX/ZLGF7IP>!/M;@3M&$[(:)VI_6CYH5/WLO:,8:WHMO-R79D5+\X,(V$*B@6 -M:0K,KZ[7EI2/PNQ:6+Z02Y -M&W?@P;\[IS^ -M7HQ(O8'A-I-T^RR_DA7F8T87PH1M23!CYK:KZ5CL'"(NBKRF]'E$94OUIBE' -M[^L/EBI,5"VS]`5N))Y%XJ:RJ\KW'W3ILE$:&MA/U_WF%'%%+Z^C9SW.'8,' -MEIRU+RC07+OP&MFETCP1\]^??#M(M@.?$U5.'C`IW:`A\I8A>+]JW:C8"\H1CL#(/5&5%EPA#,83#Q'.%Q;+9+ -MDO4EG`;AR8B96TE,1TAD@&HZ0J[?]Y1RV-A`:-,UT#972-WC#.D)SRYJDPB* -MB*,A47L2!_EK^U%"^@GD>_7^3F/IMF$UQQ0:*?>0;*H4MQ9>7$K"RITJI<4F -MUU8*$/`I#;*R.'(2#R^]74%K@1V(FJC^3!OZN6%N\XP%NZF>T(F3!$.FPS"E -M+1F)4(.)I/&4;))/)3Y(@_H!_.()'6FVET2$;(G59SJDZAI8W3;K=[?I-BE^5<840B@ZX!)3U?A]Q+YS&-*QF5;2%YX6Y.K/GZPJ5)Z' -MO+ENY^!CO!JK;(L9B[N59^88!=NP8[JBO"=;!5+=OT+">5=8(C1UI1X$CRNK -M30:WLE>E.`)GH#38,.SQ!>MN1A6ACQ6'7,*07O/-14N.:4=&?2^[)8IV^G[[ -M^!U[0L/@(=,]/>WM,<$^F305DX5AO0M$*,N;T]]ID!.4!9+1".JL\H+?>W%SJIG07I1 -MZD=?`)+$ILRAZO&LII%UB_[O65O5+<*#-ZV'/76DL?CYQ.F%J`76>Z!5)J>Q -M'W(_@X$;;\;PX==EE>FWEE9/66BDZ8@O/Y>O'R-`@7:S90 -M%,UYRD0B]P8B[4V[R1'2`MZT7@8Z[G3__(!X?W2@D$(`/W8``&I_```#35DU -M-&N7!S\=-1@`I($``$QI8F%R8VAI=F5!9&1I;F=497-T+F]D=,#,:Y<'/VN7 -M!S\0'4S93-$5U!$9E@-JRUB!JTU@=K$;5MK";6$FFDU@YJ\^QV:KDU,RV]S- -M$@@D`$Z&AXC\6%DV-#0L1^_`C4`B"?@B/G'%G>69]D$.4Z&K/*52&H9UWBC(\:4E."21^.2%M,+!O -M'/&G8G^"?V>TVBDH>CFGBK::BN[N;Q2+JA8G_H[B(R,N_>N=-$G'0K49YQ>: -MS-:A_C=3+L^45 -MCG-S;Z&'F]RT&SV,[%A$S9!G]EHG,G/XY%-09-(7O:_6LUDXN14M5$QAVK3] -M,16L%15#I'FE`Q5:`FDDRQ9&<4$4:;.A'?]Y="9I#S5M/4A#H6.CL@U3>7"L -M,\BMV[;-E$HFY,->6:*>3.V_B!<==UD1XQ?8)MQW:0AKZ*T^DXH1ZZE-YEZK\OJ/ -M!&=:1N%@=N-AJ^\)K>8^%Q_\*V,1<7L@F)HI^E1^!8>I1=[JBJ^)U3)LU(;OM=[-P%>;_M'2Q?&A1G\G\#D;9$,2T&'QE -M>Y:3*XN?BG:L+Y6KPYI*:J?*LB4-75CU;LJ!?CX:RVTJ'CVWF1XL[I$IQE?7 -M$C)=5&"]8.X.U;18&H-JG*FV]OU&KUW59Y;; -MZ=.>QM^`=J%13B:.QA6J'0AB,1>P5@51A?68@'#HYJOE4\7X*M%FI.14*'0Y -MD69=7'+@QA/H1#RT^DP"\-O?';-ZI(*LWP"OJ@UU+64+8Q50@\\JV\ -M#-HO=FLP;F-#1<['U`IJGV;Y8H)A\GUPZD<%NMR.(\U[1GE/!K[P@Z6LI'W- -MPCQ[9/E,/^#$7-5&7KU7I2\T\DT;9:3I-;*W5#1E3_GJH+ -MY-P%(5BQ4HE_UI%DR:$'!MZ+BLNU=P81-S^C8@!T?/?=@HWJ3;*5X-6'Q^>W:4.UR&H<>>0T=COA.J!6.SG.P[>"W+MRW08R!18@= -MKF,)74V:['S-A$=V91S4:9!<[USH)*W$VHC>2X8G56^.C2H'$7)RQ.? -MCV+K9\**"G%OVG\LP5#]":Y@+$FAK1&\[ALPS;2ROA1[".(L'H=W4]*#^F:+5S>,?ERA)>4RORLGAT75"OVU3;66AYQ?:/&>4'!R -MVM8B8L*C":K`PFWJLZGS[=5S?\Y7;JMEBS!+OF`@V@Z0M&5N+HUDP]S%`RXN -M"T9LG@818-"3PSC]4&''JMB]H43)@HV2=\=[S'_&UVKH[].->GW@6AWC]=OZ -M\[M"/7EYPFHT=L5DS+MH$]S!+TT/6^^>\U6FW/VJ_5I6\]`,@]V?3^5/_!&0 -MV72^X_=8O1MUOFE#4Y16+]I9)MK":0RZ;G69853GD%J$?0U_QH+F'UK1&>Z` -MXQIA`66L%UIVT_^>/^R)JY^SI2'T\*1R[VG^$*)5\TD -M-S`7.=::20@'C7>X%VUTN_3WPFFH3:4)P[,D[PSJ'K*<\PQDEGV&(.SP^[(= -MAS>1??[K6F^1NT`_IIV4:Z>5O-M_"+-Y;*25W3)5\_(\`_Z4-"[R3[G1T6WI -M0!8WP8'(K7`GNNZ)H9C+/&5)WW//PB&1\)[]EWQJ^![?IQXKX`:5\O>-)(EA -M.+(P+[P=U3WE"A?FCUM'-VNQ,'!!`_>G7K#,X?K\M*I]ZZ9]*#]<%W.>E\2` -M2-P[JU%:3/XN1XMX!KSQM*/:DJ//`.S78V2YN13T_V#Z=.,FTI"$0V0_<=1G -M)&_.>3@&Z=RZ*H;J3XL"'OYA -M\=J=G9;]3$6.B0Z%\11=@/@DB]I(2:F0S+8>IP,,O5%1\EOV)VCSN>=#GC`V9@P44J'OA[B;=D -MVK.\G@WPR)4K3HS/N.8LRWW(\ZXD:OPS&?GU^;H2R8<5RM.:[@80Y -M3*079AC9((1[SI@T\9D9XCP.MG[ZP*:/]4/ZRPG5D$X0/SN8&);!H,K=":87 -MZ6KUC"L2W2IX3D#)72L#Q(_/:-DJJ[J*!XG`1(WDTLDRQ0/I262;V892'R=E -M?:5P3'T#WKM3Q3MN9]WD(<*/]W:#!.DL"`/#0UWJ=>E,O-;[F`O$_L@7`)@N -M42+F5C2YIJ8()-F/7"+>G8*4"S45@$?&8N*KA_)5"&0)**:&%,0\^! -M3X7??'(OSE;O@CU)#@C#M*J&##D[E2[Z0&[HG*?G."S1U+%.+Y]YP^QYJ&ZS -M4+TUO.RWI,A!$WXJ$8X2]HE"PLDEFA>\0'UH[+N1_EWM.?"T_/$*6\566A=C -M^I/;5=`5T?`1Z)W.V[<+HPJN/V$;BV`KR&VE[?)00T!LJ%0@I2#'=5HE&,:Q -M8?>?#!FG"8MP:>@`P*%?F(JS%W;$N>RG(]#+/:=J<"[.QO.)2X$)L"\'S+S! -MS-_G*$\<2`WF_03/*SV3$*A#=KR7ZU6^OW-2F+.WA(-2/E98/D?P9Y-LAB""KP:NV2!0#31;;%8FD30MN -M[.%2);(VU@:4Z8I19)XM)F^G%B$)1$]5:`:2(3.2P-V@B=DY%,J+"$QG1"QY -M:!6TMLNGI.9D`AK@5`&3:F4X[06-#+#J8SBIZ),=?$>7F=DDN7HZ!D8;D,AN -M(NF+A$KJ.+!(B@MT%E(.IARD+:*I?C`.,V%&#(O"4"^EO/I.=9ZP*53%HPD; -MI(Y'HFIJ^?,6HI"EM=4@X4XCO5FUAT[1JVQKY;8*]`5,*IXF-(-6`ZB8)\T5F<>W";Z$I44"($ENOFD -M97D$IJW!=?2*KY\TYU+E'22[R^5W57(K83`%%@AWF8<[/J(E*FSV_UCEE-#D -MFU3QJ=FP@^._-N3:VU:#-&88U3J!0A-'O@V%[J6><'$&?/.@,_G&\;"5<,@- -M60*]O3SF@>R=*_`>M9XVFDWZG'!XU:YKNV)4N=PMFLQZ]$GY!<)";QH4^2(> -M+1[50G>-)_T".K-^*6'0*?Z>&/]6DSN$RAXK%0L,OLR;6B0-)HL1CCX3@)8H -MZZPB$1XU;EVA/'5'T20MC17;.:=SM0F -M-SZK@]^8''8@M,RGUNR.LOVPK`_D5ZM&7S2Y#:R< -M)NZJ(/.C;Q?[GD%I$85S#VO#'X_F(AS$>X-].,(>>NI<@C$&ED_.#YU;EAG< -M`*/8.#6?=JK]_S3P8J2^K95J';77=Y3U#35IY>)R6H_NOQCN=*=?#;@#GY"W8%R]/"5#%,)!/A -MI!1N3D./8$XW8D,BZE6^&K=[!Q8.JV.MBC7@2$5O:_Y'G?H%ALU-9+;NGXEL -M:$*'4$!\JR7-DM=F($IWF:6J"<^^ISL[0;[N"H9I'<1$VT$*%;(7KJE8K3%-"#TO[[_'&`GLS(,J -M@A[G?J):E'KR%)8=1URZG4!*M)>6OY%KJMUHG"\#4/AN,P=J6-H/7CJANAM" -M]*70Z-2A;XF?UW(R!MX3IHB!(060%,#]I^-AW*C1E$.=8UE$>(K+_F&-N<"* -M9]OIR(%."L&X5;]DJPP/#Y+:O*`JWMR6SL@=V4^0]V9L%V_,S.DWD2"Z86(? -MW-R(HY:WGL.:4=AQ)N\,E)_2W>\9?;8@5J39?1/E\U?)##N*!K-&2EUF%*?F -M7*D9,(MVA2%/6O#I3""L\4X[F2Z%E5>ZF'W6@7H1WPD+<*K#N9RI5D`3AZO= -M(3K")7(F[7IMAGX;HTSD6/IY^J)XG\<*QP.[JS"-JO9&!V9;@]!Z,.-0!GS. -M2=WW\7!WT+/\F9QQ$IX;&*JYPE:G]N6(H`G%:<.%4R9MNIBE6&GE))971;I1 -M)LL\=924/VJ%]7^,/7A7]K>-ZELC'X1;2NIGKFMZ<_15ZT%LYH>W?+Q!;9@MR_4^4-YD^`.M\,](DK9RS4*:T: -M_#-M/;E?9AEW'`"F8=G6A)HESZ`A7R%8.TA26^LUX@<%#3/2"W) -M2%SB#V^X.=G3#Y=[SG]SC`E'P=.Y<#VA$O$WX]9)$65$D/V$GQ4*!Q)*K`P+ -M(^HL328"/0(F`V"!7]Q4J[P1P,`@!RA<7K,M84$8]CE![EKW=);D4>HL[/TGLF5Z9IX: -MN9(G1$Y?RPEML\N"VZ%T&I#5Z\+5@J:2=66)OE[5%)58LVI4%?CNU'$Q20>L1HOZ!]*A\N>VU"Z4%48QEI_AI#,M"@L#_82CNH#&B@"J"G,8%4; -M'AZZU?:@0N>@PH7;;WD;=MMK'(=X'Q'W4BRMX?FPH&J=<((1Z0_8\CPOY@IZ -MWQ&612VI?I++#&'#P9:]S3]COX63C9[&/1'$Y#_MDX'YZL'*EA`VRU"*?.CF -MJ4D!1>5TUOZNYCE2K]!_3!?$"NYWLF\@^I#RV7X^NG9]=:7'+XR/= -MGTX_I\;006&6X4:[*:XE03QY>>#UGD](#P=:KSJU-?KT3R',0B/YEF"OEF#A -MJ%'2J,O2XHFT=/U*B5."I@'AKQJ/91;PY:?Y'.[>]- -MA%)JQ387E*T5'I]I#!>UG=J7JY,IO4MX%XA]A!.2\K#=?>H>Q-HZV@8I8(W* -MI(J"+2?9S=U.Z.KOI^YE*HM5$X%"^5[5D`,58*$IO`_585X5M)3C^P*K50W]HX:`@^>E]U0YV= -M7U2K]-9M8EE$:/G'A*'?C#C`%K^?OOMX^VY>7=Z\]CJS\5R6;O*M]*[0)R/9 -M@,YQB;O'GR,;IN#XOG4^#>A5'C%1K0V/-/;\58.ERB2"JNU`X=,5ZU`X6N'G -M`Y*\A.)`2"KP55WS$TH_P-H\.IMQP\$.[< -M-![;_+R[OZ3N;6&;IW'S']0*S\H%/1WW`=_;5+T+85@]D?1`=R.L$S4-W -M:`,9R!J4U'JW;8@$-C6U.3E4RP(J#&23@6M1JLL^`X@457*%47X)T.O3HHF' -MT*S$X&T[-P;X1G#B669WC=(-1`_Z\:PT#(^C\N.Z3(A"&%M.3E7+JGE-WN#4 -M5/KS3`O48(+#(=%M>>A90L[F/M)DB*B%EMT=3O&ECQ27WHO=J/VLVNS43M.L -M;3U?P3*GSFKKD@-4YDE2*XD:/+K)"LYQI]9+U6BD!;];RV -M3;<&$KRG(`(NJ+CXPZ%YG&EY`8%@_0*Z&GY$),=<;%QCL-W%'O'#\_4/K:XW.]9PO$2'M -M6$/#K9.?"QFD, -MVCX,:ODI^M4VELPUTFZ-&TW=QF3'@"KM.WVRU+Q-J@%'*7G)QZ1&ZW,H?Y=C -M'DJ`E0A+>"G6=,])"M>[6B(5O/`LO*Z(]G+Y`M+T*MD1/RGUT&(&F\1D?8Q- -M'A^K&G;P/.AS?Z?9]!D@)J>,&`OE=/SA[YG#S]RZ4>YK_#TR_7+9GXV7PX'_&?%_I4(V8,E%(+L -MB&*^J3U*.1=+;>K-W\`6T)(6AVH\?#'C\MO/U>S=&82^>C&$R6TJ&*PW!NWW -M'@*QM4"GV"&9B#P-1M-1H@EAREIC^%8+@_-)F*U.TDY^R*#6JLB(U:VDC\54 -M;5;CX['-%_T(4AXPXB#D0H2(?+B0,/>3O'`5ELT'.X19BDG9GJ6SP'ZB91%T -M3`VWSG("+W]X6ZWOR-@=]R$<&?@^9T!PU6A1/4IEM12^*J;IV\-.3=-'*^(W -MS(#%-^;M1'*S$O>2K37?[Z6`GJ[5V,OZ?2=B`]DJ3UZ#HI_"?3E,\%_PV<;B -MT@,!V[[[QS7S+37:*V>=[23PZ':U&-D#E^'-#,L+W#MXVY&K_(*]+MW -M7FGT9Y)MC&`M\B\^U,/(DX5K*TQ]NJDBS%$OR#AMG8)@U[8M@47@W1.0J!UZ -M8C[JY1VVUJB`DP5IT9-+/W/Q?P1B52F!"%Q;;^)#06:+)9?77KZ*P/MI<&1R -MT:UZ],2.U#ZGT-[:&V8]@67D5,"<4).:MM(L6"4`;FQ"U\R$0L>"G6%4;:;1 -MONR,Y_-K'$&PZ!R-WZG`.O](&3>9FT=W3,V';%3L.;.?M/!G7\S:9B6Q3I6! -MAX:U`DD7W8:Y7=Z7P%6<%LFOZ%`=9Z3U==\A0[LA$-ZPVY8L%NPVYL*CWH^0T&]G&71B#V>.9U -MP7?[@RC7GLD["2:2L_H_E/&#`XRL5"1+G?P5>8NLJW=+$'B.T<+=SYL+1H*U -ME&PN3P'/%ZX1,9;51N[P7D]FHQ9`R!OFK:?YKA -MFBX'LY.$TD[5*0P5(GA*R%Y^.Z+\.6GB3F=5?=W?U$ZAZF>B]PX<_!9`_:4E -MDZQP1F*'^:'L;R?J/T'DDJLQ91>#Z/(AIE-#.X8:7Y)=_28F(8IV1NHV/9(A -MXFN\68IA*WIZ@P=8[N3?1L;Q$1VT[T -M#"W+#Q5X+;MPA>,#V^T"N?$TKE5:\E[=CIIM3D -M."$^"S\:F(GE`V]E(\J[K(V4LD!-DPH#,?#$2ANMQAKQ@)#7N@!&0=T[IC$# -M1\OBQQ2@TO[RLQB-]F-GY@.O"7E])21%&/&>*S_@;8J4.9D#*P8%$&N`D*EJ -MW%9>;J&D&E\B\@HTNW?VMS*\9)`_> -MX1S(\!PT>0@_M%]0DWFONVD(B$WY==M(L1OB!N'Y",#V5\TR';S'"I-.V-DI -M^/+3<`N;%'=)P,"E=HNG9@L3.-O6I+LG/6M^33^]263=`TV?;-=M -M%P70JU4>*^,4S9Z8>.<.Z>LA^W9[]M)H=SWX]<_#I9?%R!:!$5T0;$Y6G80E -MR;1BW'N9HLL&1??0O+L@K=\=VDE_8'/@R7X>:#**YZ_:CL:G.S08HH0F"FRW -M(#&PG1L!W$R'A`7($D3_6;.H*KA+OYX'1:V>E%(DBP\9%6"<'(@=36-D#1P* -MXSZ)?/IEU>T7?L^4D9*6!`AT)WE36I>[)%.A<84J=O?M)2K/]X-U?1V,G%"# -MBXN7PR9&&TK'_5KC6(++](?4*Z,V(Q'^U:TIJ$ZC\M128OFY2E/H1 -MP-2NYK%LR7U0HVM>7"1"_R-6@1@@D>N602[4HW<2AG,K$!T[>B/4?2A*5`<[ -M[D[YNN1?5O#2)1Z8P<:$8L1$'T@KF"I\,[E?A.L"J)%J(W'5=/IP^5*4V]S`^9J^E5Z>(::?192_O^S,LJDQFDXQ<^N3Q -M,.QNR4H6C9;J*IQBSN<=S%18:)QP[P817["]:,T@P]C&W#U[;_\(9SM.-2?Y(X4_M*$D?4]Q,G?EDC?2%GNL=Y3Y1CH)MQ^PM -M=QPRLAN<&H_A(#/\._(;M1 -M)--@-0+TUWZ!*_F?."BP?`;7KG.DF'W9>36VMIM>ZU&RK&$>[+OFY4(^800? -MO9(]IISIJKFL\]&.>?O\Y\!N-,!%/P&&5MM+/;%@CMU/II%3NR1&"Z?57[1C -MC"%E(E98:9K8I1R"6E$HK&4^I&MP*VPF<"$;%CMWL\N.*H+<5/(M>3\`CC"M -MOWU[Z]B.(R&VP6=Z0ZK?[W2]%S)#K6KC07C>=>?S^3]Z!!&Z/;"^R2_>PK2@ -M"0E=^\,^+$H.S7ZJBWIH_,50;C!+5[KO#RN9145)OU'L!:(A8.0](*0^R;%Y -M75?#._&Y?O^Y9JFQKZ"^O86'FIXL;+>QLINRG."U,X=*9^FPD)S1$V*D&@&(LFLT#R\C8&/K@/*OJ0G:S2 -M)L'GQ#)8HV3$,IE0\KV26VB-G3Q7+F+O[1MZ*BOY!.*V,UT<>"5#BN"L3/L2 -MP+V/ZG/Z\&4D2*Q0]=4E1HZA%X_<>P9Y=?!10FRN1]WU>49,7`004%G%F][[ -M&JDVYYK6F*/7F+?@IKNXQ0^NA0A"`=W2[]@B[*9HHGF"&O(J1[5-:@18O=1M -M*XAX^A&$JK!/Z\05:+`6OM^IN/>%\M`UO"E'!XXJ&/;P@U#ZD42T7".+I2ET -M3<,[!I/`]<&I7Z-0ZOD(NF$_(DV+R_5+*?-!1XER8#(HG>#Q+A#XT -MSM7Q1`A@GP#OC^-TUEW!&`GQ\_`0_/F<;M]W[*%;X%^0&C`G)Q^)QZA?>(DL -M6ZEH&+O#RTK>KS#^$[@]K#5YVG@L/XJ?RZ[%8N`,*0*KI8S8CGG=23R,?*GR -MI'FOI_*_UC-PN03DS7HC+99(\.'[`:8&5B8&%=82@P8%U="M?]BNIX(8NHR,$@X^Q(@BT;*')5H,8#* -M#F0%_*\!<(@5B4!BCK_I_O8%^DUCT\,>K]$5!/TMJ7FMF8V)P<2YO86.@C:Q -MK@#`51'2XO&]C\G]7AP=A99"S9[FZ!T).NO5WRD=Y/7NA\R=$%/.R^S.L^W" -M[]@Z^O'CG'#E"QX)/&1$U%7RM*SSX9OT`I_()_+PHIZ/II9/EM(VE7=]/%/` -M\;J+-U2FV@APZT.[!.?B4(BH9;K\!I9T>@R7RRQD*,C5,U=IUQ!V.$0I:PB? -MI4ZAVXT[_#%WE^JNZNH2?D\NGC#MC;* -ME'G#*CU3!$XM_<:I?I\QOP#-[G>NYG(L[:)_K\NO=+B/[%4`Y5WP[S$U<:#A -M8I2OI$C[>[X]>,O>>R9.X3__;\AG]UP<79I8G`!T][J+*O%[1L)O>LN+Q1A7 -M&&=:<)R1).@`@,=W256Z$SQM"`DR&..^T51Z5JR:K6(BE(KTJSSI(%=1X(,* -M96+'MRC27LA)KM1#YVOHD46*FV91IW%%HF-"7<8]SS[^LW?.7S\N@?'V61C0 -M8O497Y`Y=!9-^0X+R"1Z3F;:4&%L#BS+3O<=GJE)3Q!JQSTX@@DPK?`_:T5XOMIC`I5AB-!EUD[&P= -MV8H-K'.TGDLP<3T@.6QH`O0%+[/7?I]X(5X%22NT7-I`Q2(K8HN&EU%-!44K -M>_B"=0-8Y!F[]Z-3=S9%;S#`E)J_'AJ_8#;GMB#@M6IL#7!4"A(L?H)8::R8 -MW/2CO-EVRG4JOAV':%!6;%+'8^/K1#X<6XYG5C2?YR.22=_?8V?1 -M1:;NJ(,'5QGG(%G*8P7V0)OC`IEE;\LQZ'GO?%EA_8BSA`PE%V]P\?+OGE-P -M%F.S._K"?3\.T;O>X#^<7;!=]4+Q4CO>^RK;:MX`_-ZM[.*V;ID-\1'Q#NBY -M%9+HQZX_[+\&3(2QYBBG(?;;7?F#-C?7P5W:^4!*-0&?" -MPAZB+\IMZ8*1^IRL4H7S57"R`@RN'/RVP,&8X`J[!E&H\!E?I>5/2)%4FT\0 -MCG@7&!Q&V1=N".7N44UA+_5T`GO?@U:MD7!-B[\W\?$:A4'F>TSJ8N718S)K.?M*R_^'9 -M9X1:[0(>&Q(%VO?:]Z!AOC;>P+'.;R+6+;.VD"W)4[M#G!\_N1[1RV3H]%Q3 -MW827,6SH.Y]S!,DOU*NG;;1(J -MY]S&`/+@P)4&U3C@I"C:($I)=*,_ODR7"L/G(,4J)8DUELM:%J8I`T.S@P_X -M[-?T&"'4VI6I-NFN:BX!QA(9EDS]$#NBL53/^'/Q_1Y&`#1A_[#9(H4%H+,O(H8GUG+XB5XV]X&K.V6" -M^&^'MJ)PTXAB\JKF:2)"BUOR[[[`]ABUR2?`R6K.%I(JO_`Y2)S;[DB2^"JH5;P@K'6C.ZTIR4-1_&Z'8Q>DJML0/LS21I -M4[=$#+]=(1$#FRR(\Z0/C5F>J/K&+EI>VEN*UH2GU'OY)J6;3PO'3LLEL8'R]2L]QR5EL1*'U5]5(8SFP>D>Q -M&/G(8=U&)@3[1P\*$;UR1=YZ,$](KI;WZ]/B\[K&%2\H)NK-.X.K<'KJ(;I! -MK/@O;Z^I`DDV]VE+T3)$>0@GH50EU>F;GF&SWR#.%!;C#*L*)YL2J@B5F6V" -ML.\O7"/E0S.[;2=:DF%8C`0(+&*=+LZNI2`V8)?-2"G:L#Z+8>6-E#&)3ATG -M]9/N$()]%)S&4<=*HIWE-JA#9G/![E1RJ[95DC?/-\+R6Y7!1-Q^$]`,55#) -M;W[S>VT,I-T'7ZO9^A=#MAHN0ZM1_6T*JCCM7O@T5_F## -MZXS;7^QK,!Q355;M+,[Z1]B#H2?\@N\KS2]V!$=*-1W2LA]0@X;6RL!#PSMHVCR2?#.GM:X$HLQMS'UKN:PY)S; -M2&P:=9VFY1$3Y7_Y2I@YT/'CZ&KSJ]&!&B>EBX_T=3_-?QU*K-APR#M4I>YM$/)CA'"%7QHY5< -MR%*LT,M/9=#Q4(<;$79R(,_GPU6IGG(2'&[\30U<*]J>Z3J6EE%?'[9:]IEL -M/;%LD@Y)D[O;ZS)G8UD5E>-GOHTFW92A&D<*7Q(H/M3Y][!!1;1;K0?:FH3W$-RG)M#IHH -MX-@]QKP@R',XWH/)OY!/28&9AIKN)W3G4V/DN#_U:D^;^+(6ZKFBX_ATV!HT -M<-J9%"?,>'PWG3:2]3);B8.>(2K<+5`'?8WDF!T?@-Y,WWH]XWM2R2NGG\(B -M6P),+AR8'EX"_V-2';5J!Q/-IC&M[@3:TBN][GL"VG@WP.V2NN[EQ#"9]7\/ -M=&`\N0;]P58/H7_WJ"^X=^2_NRYZ\"-%-C"@FQQ"W$7SX+E<0+6I!O8X$0PB -MKPK!3D>`CES@!RY$]M@CO>\^T'W6VW+#.MI);`4TGGEA961:2,N?4E;?SW>96UP]_XZ -M3>Z0$M!#ZA!9N%1DA0KFGZX^MYK6[:E]U%7&45AXVSN<,*CW(V9B2[U+T7GE -ME^5<:DQQ\#HFHHV$1161IB$*)E[SZMY=GE=TY_3304K-R;'$6<`%L728Q\>$ -MT'VIK/*W<],G,$9@6RN'X#Z('-B;W!F;&L](C$N,"(@8 -MFM@;&%F:V3]LIJ2*6G!$?GP8>-C&QLS`Q'7_?=E2W^<:0?HM;@=?YNOX8Y-[ -M6=?SW;)TUKW[]_A<6`Z_V[N0=?[I9U_67_\V+JT_>MH_^V5Q<6TZ+R]T_4+G -M0S+FQO9"\Q.?_LO_J]_TDL+!_XGFW[W-/])S]S+V)I8OYR5P_B)<8E_^D/\Z -ME_^73']Z_WTLV?J?^9?_E,_SKC^LL,C`P-"__/G_I+9&]A86G_BP@!"9EX#4 -MJ]]W2US9F)T(_XC_VWG^S]#+]#^E)^&F]>^YC'_%VK^>^$_^*T!JEP_KOBY; -M^E?TO_^5<`-89%[JX-+C^W86,R`4'9<`\"(^_U"/\LQ_<_IF6!O8OZ7!:`T2 -MQ'WX6,3$M,#C]8W4C$X.C7]$T/"__@GO\X/_D=G!Q`7?^#[M$']6_ZR^TL1: -MP-CE^]?BLP(O\VC-^/&3^WK8OL[$P./_[M6W_9`;?^6;?_<_6;67_5P8F9K_ -MW=.GYW8?]6ID9G)C_W;,#*`PWW<8F__S"FAR:&1$7_CQA8#K_BU9R=?QW^Q_ -MJ\_RTS$PLWY6:V3\ZN3?_3>'R'8'9@`44A\8GA?_QMO\H -M?S0UL0#%?D$^2F9?;V)-_S#LS+C,D4VMF=2#_:T7&UO;/Y=5^^&9@U&)R2>Q -MR9FG\[?L_]+S_\4#PO_]1NE__'E(??^P!\";C/E;`*67^?@Q_=4F7^%+[6O? -M>%P+W'_7]%S;^/(9.3$8/#!K^:7P/]J.AJ`#]P/^@#^XP"JT`F0_F1?_"?P' -MM0T%2=9?D>G:0%K_KOIT[-D -M!R@G(AB,B&*K4*3!D+L@@4UPH2KD<\0!1D261"&'IN%%2V -MN],/;Q!@?#Z=$R]VK19J;U:\-):).<4%Q<;3)Y0(QJYFP+,N9OTD6X4L7__O -MTD%R@A08=9[,.5[N-*&;YZ>3QRV>"EQDU-:UBV:T,*$\S^Y=[?765D,=OV\, -M^YV?"TTZX"28W<+3@Q0[12[>&;;!ESJ)M8,6N63:0QVPZ;6![U&B3//OWI -MH;-FGNY+'6/O+GO:JW[%B8.G+=R)BU^_'A4^ZU$!@P7>?7N_']_7(_+H1H7(*ZJVS+AZ\:A9L=G(_&9_;M7XVE35H'G33;HPVPE1,3,C$^!60 -M_N_G^4/SGU?>)KLMB/33ZSVXY)@P\;".^C5*C1T?BT='CN22YR_'/6WCFMS> -M?JV;-H8RKSIOK1\-$X:"26[PO6SS=,K;F -MXB53#@=.W.^2\9NLC[>EW"O9!`DBQ>32B%Y$<'/7'R8 -M@C1LU;9%]XU]ZWNSD..DAU%OC94Q8$5K:^4)'WG*I%$GN&ST:]&O9IIZ[+O0 -M(RDA,>7'L=9[\;P-+[YZB4+>F'0>;'/FU?/_'JW$O$Q]ST%[PBJ*'H=LB@H:G:]2T`E`"UV#!BK^?L'KQ[/SD -ML6_ETXO7^.KT@^MKK>;7T[>')Z)A/(+Z//7U3T?)RIQ".W3E>;X21BSW6@K! -M$!CNX@NMNLX@P`0CNWT8I)!)GW'-VG0Y^.NR1YR^2>!+<83XTR@<6+)%Z,D) -M3_]O/F?#&.`W@A#5#V,L9Q`&@`>4'WW+2TU2"']D^;<:C->K;.P!ISH#I4RJ -M[3R"3O9&O]\!UG`(L8,DMN](%L97Y$LA,GKQV#_ISA*`7(X]E" -M?I8-&>(+H;SVP!A4IYRD$)V&+:RP$.(@[$16%)BX0/NY=A4SDT?B0GN$&I]U -ME04A=-MD[;,,3^RVC`<-?_UA;7!/B\^?7GE`C#$+F(KYA#2%E/"@%S#[QQUE -M)US1/""<.*DG``W;8%__`USU!=ERVG$E!9)>#MLDIBG;N_7>`Z=\D07]Q(^) -M9![9?+C),7*(&+J;CP9_+V.(%.$@S-*##^\95'$4'M>%;`Z+=>G`X\\S(Q'HHT-IA'"4<91Q"YL6&:GA],&'MU5-"47I. -MC:P?MV6-S,'[YZ,U%,,:15F9<;->G"NT(S.KAMX4:!>U]ZI-N&C9IPD;JWY\VK-+[GRV,^Y -MJ<4[&S=KU'36^TLBZSOQ=0:7M,C9(DRH3FV1==[ZC_GOT)?`H0QM0.K!:=YZ -M\Y5?_BVG'$J2VA^^'S[EV?1DFGGIPV#`B>#,H`U[*5"V! -M6&#MJ*:>W=/3Q+;]5R(TC9]\^P`"(AX#'CRM1[K5L04'+Q/A+"Q>MGK?MO\0 -M7GWA"#[V?;LG`$+Y+&[8\>/)DV+87X&/7G6$HNQ39HX&?/G=L0EUHH!/=6PP -MN\_S?OCQ?*D!1QZZ+\7R94UB%F;[K^.J`&U56UIAVW92,_@7(O7L'N;N[TV- -M75\_=M1>\:I`+(K@V(P]X7I#[QU*W;C16<*5B[]::,2-*IXO?W[RX]]=-:+- -M@TU2C1;O']-9;<&;-<\1L!ER,:&W%)RVMS/D"5T]1@-+S#CF>VBF -M)$?Q$V:/H]V;ORUS"HOVI.F7)JNH*G/+X7;B%=5MK@?&,2$M*(J:0?.Q*`EN -M9,0D^LG;-/9_^4=BQU'/2`!>?0`'63S+J1=2T`@?L_KF))G$ZSY\U=DQY,Q( -MRF`F7,0)1: -MI5K)DS/-;=29BR);]N[!/^SASBL_/_M%'?*<;<8A>@"0UJO?Y(=-1RSZM>O9 -M/;%4.E`#RG;GQR9DQ8@"32&>VT`<60S]1M^WS66QJ``.EU"FS3W -MJNV\@DTR`B]LW#>W?[A%$!8KDEDY_+RB=-F3EP)JER"YO!'GAI[./Z8U25XD -MRU)OK0Z2[<`Y$;[?\-A&C,S0!_II@^/1@C_1$<0`=A)K>:X\8H7TK%LJE.F% -MH'`+7Z^XVM$F:4@8@?)[]*<0@GOB+/@@11,9?E1Y:%ZCV!N0`IX?Y_&DHIF' -MX/4^`)8VZHIAS0`!K"_\W;)C@CF:`DW6?.I2%)`3`K%BUO0`205%A8B&4D"3 -MKWK?@D>*/I&J"K?3F0HJ<]3Z]FNN%3K]RKJ_4ML=.\B'X%">G9N'UU+28Q)` -MP/9KM_!YQF3JVIPE'.)+DO_Y1@*$R4<`(/H?]0^\>,S;JT4G=Z8]8G>@S<7T -MYW.&CQV<9'%GD=XIN-T@'BPRRAAT$31%(I*I(Z"!UOS8PX=WO&S?(DS%"E:? -MS%JXAY*88Q-BUYKC2KV;-^+1GU*U9]-?FIC@;[QH3YGJLN^:^WE@L\\DU5QX -M<+%)>Z1>BM*-B*"L.0`*_5NR>@@#CQ-J_0!*[]\LRH0`@LJTZMT9B27\@"/[ -M[>G;<]&_@C[YI@'(OQ=J`"`_1`$/L*)$8"=8YX`RR39TX\H`C#[`)=\;GJ^-(T;9]-4!.ONO0OF$9'Q\!$KCUU^N -MI`8E\4O/6_"8OZWX4%0<(&(5>\_#K#QHT`1<$N4<;;H#:<\`0.N.@O0DX%WL -M)ZD9^9=3VD\PAW-^`F.SAR`(Y0*E+EC:4NF@>UM*=1(A.!['6JW=B<"`W:?$ -M!P&A&'?+F&0NKA:9E")I9N_7P[*I#&2K_$U.B3)AL!3KGN@5/U`$EN+D%T3Y@28O64 -M2WX^8*5!H^=/*`!]P`C,G+2UK_%6X,4Q -M:;;L'PH*6<-[(1$E[].]DMEWZ@];-QN$F!(P=`LZ(X1759:Q]2_P#'/JHMC(@\SS%R%X$L12`9TNA@3^08%)84M"JK/(4J:,UYSF7&.-\*-6+7 -MJ0\'M%YJJ@"B)<0&^\)B.WJ[$U(-,#C[(%9BL0_C`\:LZE%CQZ0 -M*'HI:9W8]ZPH??I^^7(DETU"\`L5U -M"50$4=FB<@!1,.V"U5*=-#+-;^@&&R,H31-ZR)00'-Z0Y74W0//CD68%R@+P -M-C!>/U*Y]H(7O+;DJ>ELT``.&6X7@#`#TN\]%GRQ8AHN`,"U`AZ(+)@#;9;) -MY%!2<<8$*I%^W-T"*86U4J8QK,.LI35?=0>>AA!TJ0"]"2.L,:*]<+^`1EL. -M`./KCL]LFP106EJBV`Y>@A33X0L<@?1*]P$^,4JC(UKK@L`9GS1JWTF2%^ET -M^.T8,;_9,*/3F(M@>L2!#SUT\!#";`?+L"VT#XE@5<84@DSA6V&>\5(B56;C -MLP)(QPQRW.L77.2&`F95N6M?PQE^"(6YF`%S@F6" -M'UPR>:71["'A -MZ^+/]2$7:*BG)UU5.&S?0R4^SH"=\OSGT`2-L"B@RP1B*:JN!JW"VF!(96;V -M``"F+^HP:`.$)>O`Q!3%Q,YJQ9_Z*RZ#$@F"C<&Z+YW[!8DP&F"X!/:'U!?' -MC=^%@K&7`$C`,>]R2;!7"9UDMO'V0/ -M:*$@C\$%X,25>,G^RUQ*'S`Y`5LM*F\RY\^1L0(P&:B@/,]0!!4Q8<(1A2Q8 -M2T!%3D2K1R!)HT9C5B"X6;:%G$*$G6P+R`K/A>SG8MDII0IRXJ@.C1-'01D$ -M?&433@WG#VM_3^?WHUDQKX0D75>'VT-]9/"?C;*3"2Z-RT+U7S[/5LZ[):_C -MS"_&&P(>B_N@B&2LO=O'_V^EJZ-F!$+^4#7!(O8P-/05T%`@J0,O\M!'+2@%+BJ.AUJC)X)H8Y]`Q%$5>/IBQ^&BSX4N/I -MA][V`,"9D"2L#,F!B%ED*3"8;WK;MN>M=$@VG`AE`=P)ZLIB`H#LDZP$_T)I -M;HZ5Z%V#MV3+SIRX0;"!XV\*HD#%3U300')$"7C%H[WSNA -MDN&`JR)T,;G"-`V=IQ&EX#N!S8EN5H!1)Q3Z$`:D91+H`5YU@W/4W3GT"^0E -MJ\J]4:?1H]L)M=9Z[=0#"1RK8\<:MCQ=;4\53OB_^DP8L`1(O0`Z4;W8]F;N/+?%/2WM[]+I^!=[]F3V@4-9SZ$E@G&YX-1!+?]@33(AE(=0 -M!A:R\TN>$FAT8`$[]7G,XSV%'1PKN2-UV3@5@S1JO[^"+18M67.`(X -M`%IA^D43)^^@=*Q?S3W"_#^(!7<)Y*OI%@P#!^+Z:^8G;COY7+J6L\BZ/.G= -M2$]LN!'R4D;KMT!0HAX2+F=B8FM!/UP!L+SBE^3@5$_?1`\0%I2&AX_L@@[KLM,LNBKF`3`HI&B)Z`'@69/-$ZXA1H( -MH"17S5'-&02[4"?CJJX]078FRYPGN(D:4MW:=/AQ53(#-*?891@$$NN-%/;I -M-A^->^RI1C1EZ= -MGV/+-G0(G1U?LD0%"MJ=@CY9$"/,F)P4&%\9+9,-<*F1)]&O* -MP>Q/WD!+2:,0NS(I,26'#3&EV/0$#YY)RAM%#58>( -M`>CK07"*L4<]$[%,HPK-62%0!PA)*HW*]0=<5&.QQ.9'H^<69LA)_&;?'?LX -M\/\UP:,X>PS'F;XI_YG]PT"N\L%3`FAKGU8-/6G.PPC^U;)@'^\"5I5M6+V# -M#+(&3FN[@_$#[(D.^[@@)V&M,_Q>->)18M4SU=?@ -MZ'8NG%87^@GV=>&[/3D=E9L2QV!LE7*693G'://EZU<1MVFF,M7]6]!JGYPI -M;.G2/S6R5*FGM0B@=REDJK;!RT.2=_^H2)%=F=F!F541%8L>EA)*2)52PZ(E -M)`DL>I42Q2632P*I70&2Q"@*"!#,(P@$R@1J=:#WPU[L9V^NCN>^HPX$EB$1 -MG/A__<_$RD30`$Q@-G.@SP&]-T09;=V/%P`;,3<\P4F[;3>(M5/0@479 -ME(&OJ2H"TMO'.-8-VI\@"181O47-OU',^.13!P4&)5BT9(9?((6.M=^)&_CV -M.@`#9%:&2#I&?-.^)*'TECOT,'>"W*C0)&4HY`T:UJHQ-`TZW?!_LL\%&T.! -MS[C$'G(-DH@-8.D)4'T%<4T@_+J*Y>)0%HUS"0?<^\=B";QK]-EQ)+)$J -M0(B2S:.@G^/>/H[25@Q=A[8IL1H>O%<&CCN+9&44C4([&RG^9@Y%5GQBMOPB -MC[5.\%9^GMV$O:GN_IH+-$V$>IMVK^VK;A$9:DH75\H<2%,^&&]%::<<.8\;!`U]:P -MI"_.&,>D8;*1,`B3N`<BF6A-T -M>'%4>H_*]8AB(,/SBPIK'870N)_D8#B/U8G/=<@-5Q)9SU4>P5"PO:FHF=4V -MTM;MM.?02/%0]K%F3=PXQ%'(XGW3_S\#+W2%4HL(B^=FU*?7H]/US%3VH'!4 -M$Z&]TMT=0JT^EC* -M%RW?@SUZ0*K.W&F5[RA]Z<`!24T@N]E-[]FRS33/1!M#C=*+(-`**]D.E"):`&-+`Y8A=:1LA3]+.:T:['=>Z`!(E. -M_3^Q"Z,<;+$MAB>SMZ/;+;82!&?+9MR_]OZFB4IBB5+-``$CNBL0=YX5``_6 -M:V2N51N&UN;F-\.[J][?6UKAK7H&JY;+I)#@S&ISZ5&TZ&G -M=J2XWEAEXI=;K6#$]!%IU0`%N;]%0L2@0NHE`RNW-\\MA -MORDA3G:W]N5LC4AHSI0"+[KDOF;W'*&&K[4R)RE3K/\^KD5`WS2@N^GTF]JL -MGIN)^<[^.:E]\B^A6*L5_2?#!OC#IO0';2IS]26ER(GKX\4:@$:"B_#R(M -M>_R(5!KMFW9LSRX]3K7T*H'2P%D^0B]R`TG<)[]6Y>\;+&43K"KV*@XB1@=& -M9TP>9K/$"\^L^W']I/"*/'Q.>^5^'+09`U54W;@!4@E'1?;U,[9M5$C@4MFD#KH16?85G,)P`L"MHUWN]3\\=P!>A:5*F^K?I\*OSXG@ -M(QH\Y0!Q?4&730I[/W)>">P\0O00Y#I/*7BY.G+A#@XZD*LDC3R"G>`\TX$M -M]'(.Y_D9V=661U@4QJ..E`8Y77;VMK-I_(WY$XC+9!8O;@KI6@FJ*#YZ=S>$ -M5!F(CZSYG>IP^Q%ASQ/D=SV$PK`%R/PG/$EWXKAF2&.$9'@85A:&8VZ`?C4@ -M\B*TU*Y8P\8KZ^#X=::I"#`24_)-L#\3S[1"QQU7PMD^T=I,EI#2CYHLG;1D -M!7HZ^"K]6K=/MNDJ6C6L8CL-4RXX)&Z;C*4^2&$>?;F&_70#T]SX=+O0G3IA -MC#0#9^VB(J1_0UJX&K,H9DO?1./!I*^(*>Y0V7X>XV85NPEGM>S0A&4>]7(F -M%):U*]

    X6^'9XY9^;UR_@U_E$D.\3E(5TG[ELX8$C)\`"ER])A[G`T9/OU -M[NHQ(.!;Z1^T!^EA?:;V^$#7'G@`Y@OF'W=MH+_X?+X<&B&]>4`&2@T$*8M> -MKJ%]3H$@SEZYRMD=,%B,Z#G`<7RQ6\6[\O0UNEY>")1]OS\)P3J`E -MK43)[XL8SEDB7H\!A[DU^EXZ9\F;#F>U9@PW6/JKMIR5_8>S,:!"81"560B1 -MT"#SH-70XZ$M]08_I\/UOQU4S(:A@HLF03K2AA.(.P=J2)A_UBFE=Z<+O$3& -MH]7'J16QGFE&)/^&^-'Y[H:X;2;)!'!9^X7*$FPN"/[ELD.5N((#6@(.46/P -MDM\*HP]#K](XRXC^]:XJ3V<,PL%;"EJTZ:EK!\C]GR)7L@1E6X>?)R*Q)`P` -M1/V1%0$8W7(#JXJ/44WVX4:_:4="!4'H*!1\B+`,X&/.? -M+#I-+(''@&E4AX'XC"%I:0*L&9[(W\B`'#H($`L&>PDV>[Q`@M688N1I4S:( -M^O3CB=D=NU0\5>1RCG*?")#UZ'MX"0T7`-Z>,`FP`LR=TSF(8IDV4HA.YR"# -MHT5;Q6-ELE?"C<.2`I=&F25.'Q(@H)@)Z=D@#%G80K(#N^=>4J+SK,_,'@,' -MNK(PC%96R2?PDV10!/Q,:?;YXYP(O&`]/#+2.JH>)L-P+X+'>6GVIHDZ0+^' -M!R.@OU`95Z]E97*GVQBB0N0$O$>BB)AH>>ESP0-10@W;1^+J1`8#)/N1*I,; -M$."-/6Z:&1/$'$9>+>^T$A,-"O@H?)\"A/B*]!0"D]"IU$O5M_I,@LVSLFM7 -MG0=44XIE`(;I&J%W"P[KS(-U:\+>4/MEB(6F\CU50`C'#PX2!5_#TO_")>\/ -M%YT/ME4O$'+>#ARDOX(/37&(D@HZXZ6*+]S+;6((.`"UQ[:A1[H2HTAHNQCE#6_SU=CW;M+OJKE'&;>R( -MW'ZK7"@@S.G"7!3`YNBA3&)11U_N**VHH%A]Q[U2JJ.E*S_6XD3QFQ&U.SHW -M*/-#YO*H=DK\>KAP&GYW.,$V56#O5CDY))Z,!;(3?J>(?H&PU&SJ,!-%#F1N -MC(W>4JO!%]D7WT2IFH:MI@>+%`8TMIKFRK<_97%ED:>%6-M>/R*G`7%_!E?/ -M?N!%ZDD?2I`MR\4TLR!]V>AN1<1*AWH9J,8`YH]@!S2!)O-NA6?E/KS/;!-7 -M>TUKGDSHMQ?[%11%]]2(8@XDE/X_&5"<0#K+P@'9?*6?$M7,D -MMMB$>MVK-,ZA-NA<2J(?F]H#QQEI:SG_4ESUOF[VWU$X#)ZDZ@EU="?Q'LA2 -MW1[?9U&5LKR*+F\R2)X$AT@MK&7A6-ZH6Z\02G%^S,4CPXK.\VZB\\3EM]2D -M;425?0!8Q361J_IJ<"(:RJM>M1P&:_]8YTBW6C)6Z76$19=X[^C -MCXUIIFMJNKS$_ZESD8B7NB1/W;;NQXB[BQIBH#-4(M,0CR0!0M9`R1]YQCU^ -M%)^,'WUAW*A9=:_;*L/U5AZ2TM&%_L:S`@/U@^.ZNJ#U`.'94:MIE,CB5RJ/!IK)_ -M;H="9*_J`5FH46(RM6-*BOZ+1/PAR7LIQ:+H;?(31STVS)G@\*/I3I?KMZ_8 -MG&FK[:.E`)#J1Y:C-^"VZX9<\U/1$U*YI63;$48,9 -MA@RM9JA?MSR3>[A(:U>7KX!SLHN%)8B$[W`I'`3!^.A%&2E'7IIK:\LR34UA -M>-`\I.VHRE#:^B'-IE(!. -MY-B>=Z<00F_Y.X.U'-8YT!B^5SLDS^*&22-N\'5V#@DC@`BZYVL^_VR_7G7- -M\=G$P3!Z%)#V'0Z#KGMT5\3UT0#NR>F>6C^GX3]8_% -M\5D]>+]TJND2*M(=Q1';Y<2%5<]EFPV22,]MLZ8JK&@76R)']KC4K-+QZUJB/+V`M;[&%&?7&8/H&:-#]39?S-Z"&-.^O[MPS#">NSJ:PI8A8\ -M>T<=A5ES**U_A:YR*_]?S`S";>^.U+UKW@*?_7-XT@7%9:6M"I73T$%/^@LU -M?EBK8*V.6(G22,(N&K/N4'8VF!I(\OZ0C0W#J*NXUR+*`N<`I=,?DHS,`P^UBOH"ZIDPW>:;]*FE/=M$B@%L2B1#D=W'';2AUP]-,>_VQKM>^G)3.` -M=HXX/T:T\H#.0)U8:53A^GOM1MRK#3!]A"]NM2X!K54/8)Q>V>,7&R_#?S9_ -M>!9Y=:3D`=)1&<6YLA6:]:TK1?#2/4K;B$GO9,3T9?49E\K\#,F]=^PD6[%+ -MYC_?7FO&JA](%1"2X`TZ+M7JZ>3/"86V@Q:,@LYY\.]H[G$J`/W/;"<@& -MP&R>#-8M9)D!TR&L/WK-L8'QIID4$RE04+^TU#BGE?,2/+CKUIEXYJ,7IIK( -MTI)P1(\JK0(AS;#-FK7UX.-(Q3&2GO&6>;F<5TQ1*/I>0BO>B9A,A)/[I-C- -M(^%9EIM4(R3(*PN^.\-2,M%<>]L."\'4AZZ@%!ZE#A(IK:>)"!N.-JPD+;M_ -M>HLMWFPJ+"0<]3KQPRP_E.VA55D.Q>U:#;W5FXT?H\,)B[QF.KDT -MZMO$HM0M(SMXL@2.N*U4E']8UKJK0C(9.=H -M[C5,U#2F#1_K'G2LULA/K^3T>XEMN5TU,G78()0G5\AQ7/;0FC%SMY/$9C+R -M'"L7>`#^CH=7[RPV.G`V)CCV[KS/L)ULM0P4RJH[RT]]<7S++5G5$,F6$T#7C]"U*YEB%9!&\ -MR6*1?-04UF#]V2:'V=&^:-"M@KKIQ=258=*.TV+SSTTD84I>N$#V)*[`%3A$ -M`([-0AK6S1.B2'@_CL@*!?*)_M_7)SWQ7][$XC(UT5,YU7FPX7!0YW -MF5?26<$.D`#,Z$E_>ZN64;*NDE*-=WK'0D>'3J0F#A1;]4!5R.5/M9 -M9)/*FZ#`,W49V5->!]^!A;;&.T'!&PE,/MTE:FX9T?>;`1WM7U_E6C5SQ`VW -MUEL_LE=#>(TCW1MT$Z5'[6U=3*W\B8#H((?WC''QX2_3<=S1O!OQYG)@`BW_ -M%\#\)V/SDYB]KX,P.#U.X*8/O_F4/G*_P:Y!>-R*]K#64VDP;[2U!J!(&YP& -MNAI)RTY$!^*5776EQ?'DN%B3CAIRBWML>%\PRT?$*@Q:OQ,O`1@SL^*7X)00 -M)4[[.''$5\TR*ENUX/`%(FGDR`/6C/!J;<`4';"A:(*J+K`\N*1$?""Q8+K6 -M)+E3YQGB+!&D@)@89IDDN4M)4QA3C@BD;"*UD4'6`56L,M#/T8RPAB0%PSJN -MC1Z`?*%+"J2Z$OKRDJ,N<@W(B[!&XB.CKCN5-GJP\(62R*5V'``#>9&QJD3) -M%%)J,/_8'5D$/HWTO_P;\)Q,73@?K)0S\?]FIN_G@F]L.%AAD0RS39"Q,]^Y -M4S".Z<:W2STS -MDW30U""R@%F<43L='I%@;.(+JJ3E_1'`+='1%O2IO:N@BAO3]N"URK,"2_QT -M9C(825B7:W*KDX"!_.R7QT49*A^9)$?0L)"7]OS42'!#_M\[SZ_"0JH-;, -MP+:(RX:N,CP8-Q/ON9\%&XD(5/B+MV>$X(JA7#E,143V$FP&*2\XAT3,8-,T -MU37XRC11>)^IU^W=HJ&!0?._^^\*F8V;HH,F?-\=%G".WLF3]:;^"0[_3.D, -MSD\KWBF5&+$AWZ.!S7.EH!^D3#>0RCQT%0JB#+_JFU!FU-9G"C=B.2S#X[Z"6 -M1CB87K%?VSHW^CPV#+;+MTU[YLUAZV@3C52J:.@T:.`4^8W-E&.Z2/5,')RG -M\CHN+//%BFPDUP8GRPYRMV;%X",XMC(9!2U<(X@5&QLXE;*)\>(1WMPW1=A! -MV\Y@4,9U%.\LW\JVRU8M+R3TUUK3"MFKUPU_SN.3*&7?;D_W3.(GF-&6V#G^ -M>SYW@?':)GI$UOD13P-4B+S%JV%T*BD\)=+B&ER$4AF9L/1T;#-O5V\X]H=-AP`!" -M+%LMQ?>4MV!/4]/%F!(4DZ.&GGRM^YD6WV -MD>3"+M\\';YUN&#M+=N[&KAFC:82ZRX0Y+HR7;\%@]UC#$%HDX%NET)Y.F[7 -MY``&@`&;XZKVWM2.)9AU6Z47X4QDRJ!.SE8N;N)L$I4E/G`I7$9*'8^=%*?$ -MM&[2L#+REK[Q0?CK<5G42NFA(VN\E7Y;/5>C3KHS,3ZJ5^O4KHV_6:LL0122 -MZSS/H@WL'M1@^^M.YZ%BDYAKX,'67\N2B[9:;#-3;*,JZC;T'5:-WOENN6W[ -M)HTMQ_#QKX\:/(DGG]V%OT.FOZF:%[P5831DE`[SU)?EIZC[`\;6<"NF#F&I -M"0D`61[0K^JP7(S04L^8-D:9HE:7M9Q&8`]:;6NQC3Z>LKIW\]"T@14>_Y8> -M_VKQO6((DGZCT7]J<%1U(:=\P2T&.Y'+;\=M$6J3))),-T&$?8I`ILD?#)X((Y` -M'.(8NNX*1S_<5?"RS,&O*PQN?EV37HWT3]GZ75*O+>3D\+UAQ6+[MHLK\)`) -MZN:%(_`2RM:`:K6F0/Q1'WZ)0E#;Y*KK%%JK;]N;Q7I]!.XT*.GJ]7UN7/<]DJ8]'Z@G&*J;9MVH4O+H8,E(4VV]D[[^?#-C;E*I=Y8&[ -MZM4.V4H?I";@1Q=O"J/EI)R<12LWRNR+.!5:3Q'PE -M:>-YMQ"#9K^>;&-'$,,W3HMP.^BR`;W$9V7XTP""=.%X)G#FZJ@YT&2:H'E1 -M"$\6./,=['<,KW3E+'8/U"W$9(F*\))P"$(DU<]YW)8YZB2 -M8'QS2)HT5C:3WR*7385<@1KPPVM%!\8[B43W*2Z^" -MM(Y(TV_&$OHB6&D:M(&!_!!?;%PQT5@3O>.-<.918QYDDGOU(ZHP7>\YZ<4' -M3-AT9CPD?$#VVTA:NM0KGN%^+.(_(>5JH'P:JLAQ+RTMCZIXYT;^&':E])![ -M&8V+IA).RZY,&30:"L&_EG!WIVI$BQE#K3K/+CP#?B']\!> -M];?.C1ZH9A!%N+\2=3'D$VZF/I2+,Z`+!MA81QFJECZN%J$%LQH>C1W&/F3, -M*)(SL)!?4#&_BQ?@DK:3,&-<,OQ1=WC`#RU$58`$;^='4?N^BB$B?KOT]7+C -M@RF88CYH9H?^4*TG#"0"25@FZ,\)_"HQLTW:_HE8_Z@]**#F?5?1,%SH*B+> -M*N:KN^86)LZ'S7\X@E+=;A#ED3/E'K6B498KUA,@!+000@-N.-WJ0Q-+:#"" -MP11`=7>&=*]LUKQ%'=\]'/>R&&JOKD'/(<#D)5-GXZTH#7\1#!VBVCV;@T$I+8E#&MH%I5- -M7ZYV`N"JC]9ZX,Z4PN3\#FIM-&A:I#&WE_`>%T/\-=9AD*]V]J>!7W4LD_5' -M=OJPLFS3(PGCU]VF\,6T'ZTE:PF,E)6,-R@<:QE[22A*_1I9&4[K4TRP+6Q#U.K'_LT3>=P\K'M^5XT"KW'*#!JJ9-3,A[`/<" -M=L>>X/%_Z!N,_;`D>F%B9D+2*?J.D$Z/D_!:P4;:X=A#12B^N"RIU&+\.;#F -M(PL-Q7&S770/3T%E]"RI3VD.*%\:,/TZS4Z\)0+-_`-L-RW2(4R(1Z&]>K22 -M,R\C)7BWS0BZMAI\`P([XL;C=-4260R+7G1J"+/]LB4^T_+F(GM#W=O=8O4I -M?#V_L!M.3'^'$T13E'ON,`Q@A=_RE;[:W?].)@_!6#)#!)>WFJ*_AAFG\@)! -MNYWK$(!\D^&1$-%)=8%13>D5%^)Q$6, -M97*#6N`C=[*P]][YWU>VNG_[AFV`7#>K!E![0Q9TKZN&S2W2\ERKSM3)$`C. -MX#D1@$%6P19Y9SI>LXO`W)L)-F`Z'PH6"`4'Q?AIS>3PG&2I^KD%([G6/+R5 -MU,XV=`Z/H:ZR^14J"=2R@VW?>$9WAO-W))%WJ2*"Q[2L6O"D.$XMW.K%NB(" -MO1*Y%4DE2*K&JY8!/,6,;M4KUKE:4C?4#\'6OZBC"*B]\QFR:^$91 -MN7B0&IC"AX_Q%.`)ORA2N22HJ+1Y)X:?'8[-`I\8L9T.@4WLBWI;(N+&P#:V8/&T,9P"PF^'%&1$+!^NN?%-#5C)F[TLD^Q -M'R"5M!\+RMI/KZPL6'O\WSR725\^!IS"7S3IXG=&Y[:.:C27'#-M*?[[B&>E -MU`35G$=([P9()77+J/UVRV/>OE<7_DA2"8MI:>:\56&(G=*,DFG:0#9[7$"' -M6OW9G9K;R'IY%YB[P"O?(4R]!;1D:1R!N3+F`YS@*%[`D?Z4THHJT#MI4M+' -M-*IH8R"7D.#:?0>5RJ&)ML!SU42L^4BEE:%:QM)A?P*VJT1*^BNML?%,N7KX -M?+JY(PAC$P(F/>(TU[<0)7??&3"52TV<%:E*%$);,GMG%0!%^R[-O]X*,BTY&H+LYPB?/0XS8IT]S6_X]@$$]TW`-:S(V/]$0S*L3>$<>GG#_K2Y"A-3,`72Q.IAB09O.D-1\)C -M:IK$7B`D$N%,7%G!%KV;UNTBB$+>``@-&6>5>RDD/+NV:IF%P[<";YI_DNG= -MOVYFBE(?'VC'`74(>.P;-$<#UFB7,SQ(1=YQV5AN9JYC8NTSLO0>KA(9ZD54 -MAL0Y10>HJ["FZPGX\O3MN2./&!$TD;AIJ7]Q&TXQ:*Q/$C7.OY=D33JK@J5J -MV=P5`G2(/T+"F09/TQI@].WT\%EH.+<\#72+9H;-J/Q*Q\/!N'U`8\1GSA." -M8)N]+SMD;^JG*PO.5T3\Y6*D#I;MIDX2&#+\%U`?:;),4F]!#VJ+U!Y:7(OW_Q*V(2R8G28_ -MYE,/`*IB&H4A-0;0\Q_#^'3P7;3YR1D3(^(V6)>/,G]>Z\&=<>=212#R`M_\ -M!U<'=\T7UT[#O6SU\-_(,W9*Q5F@T'%6](]LB9\!M^F!$1G!]XF.EY:8Z8=/ -MCWVO#KCV,X9KL"&GVOG&,-.8O@T4]9.N%([*+?#5*#2#I -M<8VMVSMZ^9<5![HCY5:!Q]L94O9']N'/E* -M!N`]Y'//[3[8B5NO9DJY,`P^7NGCU)BM(W`Y_H+GNG6//0S.&U)KT^EB^/#").\%/)R6_)=6'#UY_J^A=.UX=RM -M-H1XK;N]V890:M3-_ONNS]1R0P%#LK'W\$-#$3Q7:7:!J]!N]77SXKD;T:8" -M[B_4YPB$>U201WNY`"V$-^HENZ",`+XL$Z<2J#C3NJ,S8_25PZR@TPAQ()YN -MB8]Z**`'XN0;:N?XQJ9YI=74#(.](/O&N:MW8Q@*ZN5%`!#P=&PP@\-8`O6[ -ML>WVOWI`C#II!BY?%9^_S:CKG@%TL7XZ]:%6ZV>#FBH=Y70%K??_P+&H/RTB -MONP_DT6CMEG;#=A7;/;%0=]K*["O?@\[V':B41G:"*WYCDR$,RJ'& -M\/TYAG2,I5H6BP.>:956N^XZZ3ALIC4/('8:A?%?'P=";11^T-Y+Q#A>P@>1 -M+7GU7@&\NX\"96&.G!+2U]I#FLH@`?U',N2>T=@8UJNW7^U$X%.`^W(3)T[5 -MS-:K7R1-C&O-V;4HN-^Q`4:'"F;)KR$I>1CP`AQ%X/_F5SDTK&_][/=6L>$Y -M^U#(>"QZM5[&0TG('X",CJ$:#1W=&OW+X9\(*]CMHMP[7P6#L2=Y+.8U*Y.. -M/D3I"E(VB'A+#D/-34:.^^%SBH<3="_3K,$T8+AX.6_**\R>`"/#S>L$,V\# -M@=<%BRYM>Y6,_K?9<+ZOIQJ6\HODM[R$?B@FCD<3]20U\9V0"B9ET:IZ4)Y< -MH339O59.[7[4+N)T>2;?QRW:J;KC6,IM7(J$&V=]>;0H<9V"?HZ91T8?,'0O>09U=Q%YVM89#XO,L$: -MT9I>I6F!H;.WDQ4^@L!`UU2*45*GN,%<"(M:E6RT]4X/)=*1>N:@Z%'_35[^ -MIPO/*L.IB:1PH/QQ%]M_BV*6``Q^%H4+B*I&`BXR+3YV;2T>-,P=$3H;UZ.P -M4WL,LC.'5N?FON^I)%QA-TPE0G"?DJV]+M=5V=W)YV^UF;?YJ^DIRD*?KX"2 -M?\LV[&">P81#&4,('7_J`V6I[[I]7&J*I.X2XK,L+*22KBOXG0/A37=O3Q%0 -MP%1VL,W,:3C10^?[1X1.]\-`G2"CO'IKG@'I@(Q,0AIHV3;[H11SRI,N&@[,-?CJ,8AV)E(&4.1L9RP>^2YSW+&*L -MEF2^UY^)*GIE`"]8QK9H0'R#L&XDSD"%7>/VN/'(UYL3]$EQ8?@DT -M@&ZZ_MK]Q50"O:TD.3/]&&],FXLT+D8B/\R!G3;"R8VE40_A(^9D/]E-Q&5R -MU]*11!J-[?A\GZ'TDGT7JU.I%[QI+W:(4M#ZLIE41N+*VO^*W9[IE@=0F_1K -MC!5P(>19?6!_KXAWY1(W-CVYV%)X^0AL8%37!$7=%ZAT*@`I^+WO`?Q^M<;7 -M&^A"%]^73'>LGE-W6OWY1TO7IAS.D.F_F"=]JPQA-O`!B$NU1]F#)ZJ\ -M9CW$^2_72%4!8F`%&[]T=+AKJ2@277=\5 -MUN))UD-50Q=O=9-JR<(/W)]5[5_=%:CJZ9F5[7TSM`G!;&L&0'@Q)&)N3S3' -MVD70*Q"J;()Z]L\4PE3"Q,P2*-C`:=4P=UCIU?&X?5JWH=%@)<@13X$QN"3# -M!A7B&4]R2I=3)EU4[L.:(%XQ, -MF])DAIK(T>=LO0>XG5P"Z=ZEZZXIO*GLPKLW3@SHI!EGJ$RN_I-H&CD!.U8B -M8#7+R'(Q1B:BJM"*Y;L["[[@0BPW,"['JV[XSJS5RKW"BG;33^SB"^:Z#GAQ -MOJ."A/1\+`55MI;=91DC5#++-K4WVJ4S_L71_ -M_LX9?U$6C179:O>A7$`II!.2E-)JD=A@/X4YK_/)#/_N?W]B_DAO;F9I9_[T -M#)S_MMS$C1IC2`N+:^@\31?'>CNIER,CZ_GTIH3X -M!CEZ,CAD,:V=.KIVIGC(,_TRD -M:GF^.\ETP*WKAY>1/>\.;'KI=C;+0)3(2A35O73?"G_4:GIWZ&A^C2W[ -MYFH-UW+;D)7T7C6K'CX2]GR7/UNNB!F^H?K#G!U=N+6\!T3)R9>?7I.KKY+_ -M6!O9QX#;91.;(Q^H4JF#ROEL?*?6>A*_L\U?P%!O]DJ&,V[0B1TT_$.(_D._ -MD+I(7^@,E>F72RY544SR60\;'>FQB3SE4:CNP.!Y"L@\EH+,0GK55?\3!:^0 -MQ)0BX3;?.W6C+3'D.NL_N_$9H3XNGI_-5IR8J/*M7W_Q-X5]>'Y*G[$E%[,V -M/AS6YLO%2WW:5SHXA>%/=A6*O#&S#!44^L,112=F.UMZU:6GQJEPEF5E?L66 -MQ_N\:_)])!KN;2RW/!*#`J+4W=9`9\J>3?&Q(2%H(F2B$4E;KY2Z -MCN&1I!)_91Z,&DG*1P]IA?[XJ_Q`6%RW9%R!Y(!?HY^9$DO"PG-)%WK0'%^C -M5=)USWPS7]?PH_$Y(ILVDTZ5(<*E>H+<[Z(_!TCT^!G?@3KS`S@T+A%5/Y"DG+Z2/%BMR"XODJ(T*(]H#-^:+)*45 -MOCR"0Z/\+]?WB=FI!`,/\&8X&*+E3$G)A@K="-P0(,G@"E+?) -MU.*HBSI["NMGPCL@Z0]LN\8+,M3$,4C:F)Z,H.*5,5>EZ%+*T:1@6<7$1"3W -MP3_7R5FU?-WS?'CP,BD&ZW`BU@5MF(DW$V@]1`RT71AIH7Y#055.86ZWDO/HECM`JJ_J,8Z-6?!0^F8D.E*M.,[XW\'WNWS[-RSF)> -M@BF??_(>3-IL\BN,J215SR]W"\L3[#K:T':)A#`Q[:Z@$X*#;AYE@9=')O%` -M\39QUG>(TQ]H>)!(E+GAU!EP1 -M9]8>W$F[K_0-?.,^5%[6WW'OVH>_-%#'K4@XV -MF+]VGVR_\H2GNQ-[VD=!SD%=$VT:X&TP,E51[FB6>/#(AF'<1B.3"+@.E5 -MZG"I\B<6[8P[%]9X=.69*F.QAQ/)DI(3N5L&\S$WRJ8(L\(?X+HV5D<[V(9; -M>-LCFZF4"'TURI,8!>K,-B-<.[=6%IQ7;?LF'A7Q9GW.+2\PLK`A2*^-JP'M,@^HHI-ONKI[L%0*6Y3? -ME6&`_#PH*F"K_15D8?_IM22EA&-4Y32S?_%5[@'N+&34E.^.!J#ZIDKYR`N$ -M%DQ:EP3+5,*$95`D,R/[]EPN.;IS=!/':+V)U*[V7@\WOF(8P^(.QX%&R2BB -MPH4_3(#TK2%>RSLQ9U]KL,O40T^UFSP;E"X@;#,"V:"9K/JY#;M+8#3H8B:` -M+%U/E(%!I4V@5./8= -M+W?51B8@]=X_\DX>=8S!5?5`^D9B5C#MH>D7LI/9[:XF.IDJID%H5D -M!J5*=$;P=F7Y!>FH@M$'+T3[7DYHC=0UQJ=.]W?3@A$$33YV\8FJY6,GY]`Q -MM/BR./W19?`BO20<"R1C?SF2>^">[WF4SF*0EUK)1J7.^>?YF1U*+DP'??9N -M\:,RZ"X0VEPQ4Z+TB@K>J(I!7P,O;Z\%E-PID)YL?Y/)=H_F -M>?&"8/S6`)NE._#/(6%!4:)?TP+#!X*_F]U0_C^?]>ZNO\6?_'?7]U85!7_X -MU+^'NJ3_S:?W5@L%OT=*5_PK#__Q:OY*PF?H!(L_A6%O_SBO[J<0%/_K+BW] -MU7>/\6C^2G)7Z!]-?_^G+'_FS_^*4X_0/YS_-2HK_NY_\\V?_0.;C_O3;O_= -M[?IX_06W])_C-P_GNK^.9NG])_[F\?SW.2?T9FY?ZYP'^[=`/^D_OG$?[N5Y -M?_Y/_/Y(&GV"#Q#\_"'`/VF#O^.F>OS_/_\@Q#U[`$`'```` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar_compress_best.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar_compress_best.rar.uu deleted file mode 100644 index 22fde0f8b..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar_compress_best.rar.uu +++ /dev/null @@ -1,274 +0,0 @@ -begin 644 - -M4F%R(1H'`,^0J&?_1OUJ=Y7J9V45- -MIF0'97^*.^+__"SO/I(.MP.7!P7!DL#G$T\^K,^^=@6>9IU! -M]1L+14"5EZHLTQLNZE*M8V]_NS[5.(N7ZDV)#A@T%ZLGY1?TZ:KDIW%%#T%Z -M:I_-!OKZ+RD5=I2"AM"&%<F9T)4;8EZTP_]:ZQ\:ZL$ -M+8ZCW'*P$KI=7`JAW&B`X"L$74EEA\0F)4\,?$*=)^FMK.)('5=PI]2Q2Z^_730[/($"GS+O_!&9U!*C)X?'A@?Y*C896K8#TVO&DM$D2 -M2E7*N*(B3^,?S\OU5%]PRV!S7PKRSV"SOT!T,ZT,PL4R*@,RXD:/S2>+!)2O -M#+.:Z:,Q8_^.2Z6&R*2J+V7[\:22)H5L&)BIB?-HXT:'EJVWE_5G?, -M9\AF!,+P_UEW#5]\G0%G#)VXCP8-TS?AB&NAMH_.N5%/VO(#*WC.-;_ZGB5; -M*IK_;@LW5I.H!'+^BMQ[-+NO!WBBNN[D;Y4S@#^6HS$7/#O!UIN3`'9`$\5( -M)9:$%$A(@LT,;V4GJUA.@TBYDIMY.GL?09TH9A\)&P041M.E;WF>U>2&#?F/ -MWE'F,BO*ZHXRMFG.4]R\XF#HL38`X.\XZIB8X^4Z+=#]D0-G0JB%''.S*'*% -M8Z!;J`%`KA\Y&7/KZS6^;]PS16V'DY-JLE4>,SV/T*`LO0H#YW`)*`$IKHJJ -M"QZCA"SM7<&"Y@8P^"NJ%/LC/+9!MDH-[NF-@8B_Q:5_!6.\OY3$Z6*!7\LQ -M(QTK#:_"+C%[IC`35R0R1;7ZI,Y'=?$4 -M:=//'-XW24FT,WT.C$L@1QY_*;"^'_P\/Y.@EFU-O" -M'D4^K5<5GE]_U!6JBS;%JZAJ[\JLBO3XWR&CBN\!CPZ<-=8'E_AIA>6$9[C_ -MBEU3*RW\.[B7DNO_<%OK+?T)F12>Y(<55,;K=K"(G&R@ -M7H(+?[%\=>>(9Z@6TQE!(E&WM26(RN;K4PWW']QAM3&8-' -MBI_6V=>67EETJI58I/%^V'Y`)QVJ_-PMX]'D!@K=_+9>*F5IB.48.SQQ#>+S -MP;(Y4"(##2,,M0SQA@*5#))W!,>O-<\UI28HY\8FJHQ'H024"3S^?UK8"Z7/ -M=\K'0+LR"^RG,84.3AZ];N!L-GH#K04MI]9.=!?BB$Z]TC-BS^R'^![STM'0 -M-'25OTU"3,__$G[1Z2"`^20%[@MH"Q2?86#8@C1Z(*C]I:QL=F6) -M`;KY@H_,T5L"L:6B;=')"FI%Z_?\H?Q0*=F(',D@2=WK5_P7-S=2XP"?&(,C -M3_T.XL3CZ[K9Z%['FYSEQMM/8@ -MC?I",[7*J9#'<#$38ER^&CDX+%/!23F(@$9333&F/+`;A>+LC:<$\63EC95#B$MZIA(SH*0.J:-R]2?N3)]G -MK;TL0',."`?@?@LK@,.KHWH)O?^Q_#S;S(W+/=:ST\HC*W*[P;&6X:&X8EK) -M!CYW6-Z0<'CJ*)1CRWP%2QPT;C"_88ZV*0X([8Y\83!'!3.7?CWC;GD^2UFZ -M6UC*J+""K@"V8/"2,I303I'KH4C;_CD.[A$N)@7SJQ[`@#=F?>_')=IS!XMA -MQ..0&L#!;L(.%B@PL9+)-@(2E.J=[@][BYHA=^?S).>%M<`]TGO@R#.@+*40 -M.C:Y#]ZX&1/YFF7Z2>*IG8OFJV#FFM;\51V_79C4'[XBKA@(\G0!44;221&B -M/;''5VV2I?VH\)5KI3$%"2#0?AUSM(BS][#.V@HFBC:DVP1]/X(R\X;0E%:N -MRT"[#D``*IGFTL;GZ`<%\@NG#C(T!A2&3F9H`9<$@H-R[]/">I9P5\\V$6S@ -M\6&LO4USF:\\)IO\5SLB)[&#KV**6`Y%J'Z_.=ID2W[OUORZ#%,C@O>S=,9M -MV%(CMAP)/!ZEE7X%S9*TCCD8.YT*T;!Q^SOU1,L+SM#9?/,;8#AGKJ^&>TW+ -MOJ_PZIW\\;!NS]:K77N:KM;EE$"\F+=ZZFVJ7[FI4;-8BH`_0%+,TP>18F`> -M>C3RS]*C81!3K7S.^49,D#O"+V`:N-_`>9!QCTE#GBQR&#/FF+YT__RE!AL$3WT4U-0NFF.# -M\CT',T83SUZQ&Z[[Y=K9SLGGRDJ7G9M#?-6;F1,%:O*;F:56.:E]\JHWSJJ4 -MPQP4R%D<$*]@E8_?7=W>#)SMT01Q&1$.>!2YKF6$@%1](?_RA0FL>D"O'C_1 -MUB^1'83'4>8Y95+1L3Z4'8'P6?*9Y:J"H4.;3 -MIGS2J"[,S41\8^;Z\U2.%GI^L=FS/*!>?5:!O`7Z3OF(,#F+-D?)S@,%_Q7/EG\`;NF!1XU'VE$)*Y'@"8&Z_SES.X!! -MNU'"4$W9(%QFJCZ*D@PI9A57VGZ7X>^X=KV4WJWR=6Z1E>+R].WV">O68NY/ -M8L(`R&D:F1LU>Q!&==(8>(NVEA.([@?W9^J"07@OY[5*;?VOMHS&^D-Z=8:) -M,#87K9%[T.4=IAM^9:^=C;[3'9M%7]4T[=$T".LQV,DG[_'^&;V8ZA'.&X+> -MOXJ!';3$T;[L!=29I4WU]%M+5JZ(#?WL,D2#-J=H/'+%EPE_9M3J1<$VTAG] -MPX;@N5,:NC,_K0P*"H%3NB6?>&A'H;<47.VL43,@#&4PKY9\Y: -MW;:6'Z@#EYH#KYPHP3%P)!+'@G'3IN]D7G"ANL@B!?7V\"S&L&4Q].41A!40FOA1<;$W?A/*)?C9_-A?@K-5O]J[&U4I>), -M)58Y(JUFO@'/OKK(?G`T4LMH(W9AJX?SD5BB'`L0/>$KN,@NAD\F'#525+IK -M[EK(7K[WI,!=_&VN!=4$J-CG'Y+`M`=_$)S"+XG1P/;R#]+]L1G(=]<2RS[GU*A9"'@XZYSC_QN10%A)4F"1#0MDLQOB -M(FF[$EX-.G-%IL"R>^D'L&QN,;DGL`$WOBX/M7L^N:`I%A988+J./SL,0JKT -M04D(`-+9":HAZ5*5@N@7TU!5P$XG*WDP,^]PE55\4^%;)1WRE<4S7W?9R-(7 -M'D=Z`MK%P\X]4O=6TW&T=:2^8"\(D0C%K!Y#X+08([X!N:CD0`%FG1%H;(26 -M[+%(1Y$6$,8K+Q19:>#NJ5>F@0!`3&*X/X-SYY,H]2`9[95F\2*A.K"O19)L -M-((WX1C7+\,"C_O&Q3T#B89[/)-^"!.+APK^IR\D-H,QP;Y6E%P#OX)G+GCB -M]*9G2%Z>-P<56E`'6OJ9R\GV5:0R\0SS0%EB?]$;\(K?(G)#G,"H6U,%NDO1 -M/]T]UM`IG37ZW[(,_QBCF$/''KW"A(V=G@@W@-`E^_-W-R.XJM'S!>U_H8/- -M/BJ]GR;;5BY`TQ(XFX%Y=Q?#.N;8$SUGA!U['SG,(MZ -M"DJ!#T#@5/O%'.A]$)V4[ZF/=-B33C+IHFHXQ!#09]X]26N4Q11"G($O]S'?ST_P&^?6CP-)=``;)M?+Z3,GZI1-;E.@9BU@ -M.KI!/3G[+XW\,QO\RKBL]R'#REC_#0E:SN:"A?7[GQT?FQ1&I25+93T70E@?M-HYDJY&(!CB_!>)P<,YN.HH"<1EP]'JHG&D#, -MA._*]W/3/@A;,@L_N0NW^5*M[45V],^_;68V_GF],J="MSOD(6K@'@<-/ -M-[!E%QCDVTWHA`+']4U!5JK_F3_.U>R!DT6Z4F:Y9G3KM -MO`V5@/SE2&'*JD`18?T@"_RW5?>GEPN/H(J0_,UGLYUYPM6M6>#>X(")AJNB -M4J/_%ORC\FOX2;+2?P=R5"_.`G5F)4PD@H`/6K,%UY[_.J.QG02T)3K -M6ASJ70;13G6.EP)JRUG["E+`9^FP..Y.I$C\=5#LPP>.:IT7776=E',!QM#> -M;?Y([:G8%ZH]"6'[O":M?%N$CTWBX*^@-8363][.?N"AYP19U^X,8TAC4$OV -M8#]=(EUSOT`Y_3O:`Z_C'.S`2QQO_7UP+,59<4!\.X_C!)2F4H9J;D\_UYPV -M$X#VS5&/!>/L>+Z(_R96"G9)2J,W]G2-#;]B48;!%.+[#H`PY9#`O]#FY0E6 -MP4!G[X&?L\-)Y9=`,2:EGK>03ZCO%317A@%Y,I6\VJJHV#5<<&:`7G.KOLD0M>."GN1^:5+BK8,=9&1 -MNU+A+8ZN=2FTZC2$@5/3J5JDW4E_.-[(Z.*5,X%M&.2B_>LTQ/(L@>IO%G2O -M]VAXF5D=R)JT]WQ1LNHP>+-UU'[2C+6@?K28JFI':_2^,M!0*J4@VKI3U9L\ -MH/V@9D(]1YV2:F\==Q23"PV,*J=(0?`3[.\H<(Q=UOI2TTVF_(MBQ=>N;D78 -MEN.=960%?1'RP;FKMNKSH$'T%[]BR!3S\L5&8D'TTTD!A@1\9_3( -M9M!N`5QCNJ%VN(GKYK57YO70.]H[?2[XJ?>,FTENF:!WL:&[:E8E7 -MB-70,W54\6+37TL:S$4WJP,M-$.[HS=;[:S0N4)+B3".WU*1Q]48OM.!8]7* -MPPT9M``F84D^%&"M352>U(M6.!#E5_V*T?MY^XY9V]-V4="E.(LTG]ABY*3M -MN`AZ?;5AQZOZAIXU,D]19D@BBIQM:.IVNM+@$<'Q5CV_;+3SM&3877WTML/# -M5=N]D"`:QNY#O5+F#=*$V*^8`AR-DY:[FT8>UOA -M+:X'!VUK8ES23Y_10,7UAB'DQ*/@6#!*F7,5@2I@0J0.X0@_DI9C4$E-,_37 -MN^'W!8A(-A+(0R2C?=I];Y[<8:M"@S-()5QZ')N`KYPQS/%B3OK3L`Q-6&`I -MQ1!2OU!<\5!7KAJ-4:1+"2"2>8F?Q-:'"_G;D^Q?X3KS^0Y^QO'E.H1XS>X3'SV -MZ;1\IN[J?^T,MKS_'KO->#9M_M`:I;_^_M -MH&")7-%&):P%<`MLZC6-FH2Z>T@W[\2@\__'YX#-KR],)%@%3_]29?*@]-.[-I<9^[3=D!^JI:S-__CZG#FH'HU!W?#N\Q&O_=$!_L1?>4WB(Y*^PV -M">CGONWUA$&T[L\<,G*BT&GK&?T0G#+WN]'#LI01B?@[S*J/[D$F!C_8` -MCU47J9\%`3=6>BR&"61K:2Y^#;N,PIE@.<4;81#<'LN6H,_ULVI7]KF -M)]"7("7/*1,T(IM_VEC!]1\Q`\6)LXTO$JZ;KJHQ.C4D5?L*`&@)!5F,.GD( -M(TL+N,T]!@A2EZ6$H!N`AP01RS!2(2)J7U\/4S!CC&XZV:/FO,Z^^+6LUQD?@\+T>;(3/W%3.#V,*W7AA2C!M -M:9:D1G#EQ6XZ'UHQ.'1+II?@$ZS<+.>S@9'?KY9K54#X7:HH*BHE+%[)R``< -M\O7&XO'D"1O,Z#O%E>T+FGX#9*SA!%EJ$U2HV-QAO$M)V__:DM3^/G43`33V -M'.E7I*[!'PC=2[,H^]C%'E8^76XKW4@0-P,?W1\U>_J*MJ-4I@0/P[P`Y]2) -M:)]"@[:>_I(A-",```"_B&?VJ?_41/%T()`R`!D````9`````_'3_!$):O8^ -M%#`(`/^A``!T97-T;&EN:\`("6KV/@EJ]CY,:6)A%0P/&L'[WB2!U7< -M*?4L4NOOUTT.SR!`I\R[_P1F=02HR>'QX8'^2HV&5JV`]-KQI+1)$DI5RKBB -M(D_C'\_+]51?<,M@,F]PE+VS]2/>+LTL^)KU -MF2N[8ZO?.RN>$#S?0H]0YSYGBDJB]E^_&DDB:%;!B8J8GW*JO9*/%:M1X$FF -MP^&O`[RU:XM%UY]0#EF9\,:3">!<)ETSY)F5GC:.-&AY:MMY?U9WS&?(9@3" -M\/]9=PU??)T!9PR=N(\&#=,WX8AKH;:/SKE13]KR`RMXSC6_^IXE6RJ:_VX+ -M-U:3J`1R_HK<>S2[KP=XHKKNY&^5,X`_EJ,Q%SP[P=:;DP!V0!/%2"66A!1( -M2(+-#&]E)ZM83H-(N9*;>3I['T&=*&8?"1L$%$;3I6]YGM7DA@WYC]Y1YC(K -MRNJ.,K9ISE/HX0L -M[5W!@N8&,/@KJA3[(SRV0;9*#>[IC8&(O\6E?P5CO+^4Q.EB@5_+,2,=*PW' -MV6\5:'`GU$42X'+ML^24T+V!U"[7`*WU5Q]A$I;.G*JG3N>M(\%C1N33':_H -MHW*]Y@\[G\VP2BSYTEQL1Z8P$U -M-TE)M#',SS=QF:;,%!X>FAS*\$LTE:N;-E6JH>UCSZ1^*'21$RTA7<71W\*'6M7UH/$P-#82?]^*:&%&S?D\9SP=W8=U"D#*O8TJ'P -MI?QPA5Y[1`3&LES]V4]=\A6GM]#HQ+($<>?RFPOA_\/#^3H)9M3;PAY%/JU7 -M%9Y??]05JHLVQ:NH:N_*K(KT^-\AHXKO`8\.G#76!Y?X:87EA&>X_XI=4RLM -M_#NXEY+K_W!;ZRW]"9D4GN7+!"*$"@E$<G,@,C`8B[OV4TA+G:`EC40T>@O"I -MY@;Y\2/JDD=V1M![(CNP(_,E2-0U^CX,9BJE=-CP^H-4\+4&D]^J`VAH[`_" -MEO\Y>#/O3GZ<`Z:6=C5[_!MCXBCD:8T=_894T$+.WU/1Y`8*W?RV7BIE:8CE&#G*KAR=I-M!\(2S -MH1`)U-_43!QP@2?TY36!`,FTEU"+G+UR\DX'0Z_/'SUZY'L\<0WB\\&R.5`B -M`PTC#+4,\88"E0R2=P3'KS7/-:4F*.?&)JJ,1Z$$E`D\_G]:V`NESW?*QT"[ -M,@OLIS&%#DX>O6[@;#9Z`ZT%+:?63G07XHA.O=(S8L_LA_@>\]+1T#1TE;]' -M*1$!&)GM0DS/_Q)^T>D@@/DD!>X+:`L4GV%@V((T>B"H_:6L;'9EB0&Z^8*/ -MS-%;`K&EHFW1R0IJ1>OW_*'\4"G9B!S)($G=ZU?\%SA7*9M^EL80./SNR$4)E*K:0!TT,*59F65;WNQYN2Q. -MZ,L"-H?=(U3A>/=1R/Y!KMGFG!/%DY8V50XA+>J82,Z"D#JFC -MD'!XZBB48\M\!4L<-&XPOV&.MBD.".V.?&$P1P4SEWX]XVYY/DM9NEM8RJBP -M@JX`MF#PDC*4T$Z1ZZ%(V_XY#NX1+B8%\ZL>P(`W9GWOQR7:

    +8<3CD!K` -MP6["#A8H,+&2R38"$I3JG>X/>XN:(7?G\R3GA;7`/=)[X,@SH"RE$#HVN0_> -MN!D3^9IE^DGBJ9V+YJM@YIK6_%4=OUV8U!^^(JX8"/)T`5%&TDD1HCVQQU=M -MDJ7]J/"5:Z4Q!0D@T'X=<[2(L_>PSMH*)HHVI-L$?3^",O.&T)16KLM`NPY` -M`"J9YM+&Y^@'!?(+IPXR-`84ADYF:`&7!(*#Q@Z]BBE@.1:A^OSG:9$M^[];\N@Q3(X+WLW3&;=A2([8< -M"3P>I95^!NIMJE^YJ5&S6(J`/T!2S-,'D6)@'GHT\L_2 -MHV$04ZU\SOE')DN?ASL1NN^^7:V<[)Y\I*EYV;0WS5FYD3!6KRFYFE5CFI??*J-\ZJE,,<%,A9 -M'!"O8)6/WUW=W@R<[=$$<1D1#G@4N:YEA(!4?2'_\H4)K'I`KQX_T=8OD1V$ -MQU'F.652T;$^E!V!\%GRF>6J@J%#FTW+I/CY_;U,E7%R2F"W:/F]OYT`W/7T#4Z=_; -MLS/5@2B`\A(2,WZSA?974DF3$<^RA?!ACA!^T/=BR4X+!8F3^V075'/DF0UX -M9\E0VYNLUQJ.-$%SA9?S?8%ZQ#'_7KP% -M^D[YB#`YBS9'R-1]I1"2N1X`F!NO\YU2FW]K[:,QOI#>G6&B3`V%ZV1 -M>]#E':8;?F6OG8V^TQV;15_5-.W1-`CK,=C))^_Q_AF]F.H1SAN"WK^*@1VT -MQ-&^[`74F:5-]?1;2U:NB`W][#)$@S:G:#QRQ9<)?V;4ZD7!-M(9_<.&X+E3 -M&KHS/ZT,"@J!4[HEGW.#\NPS=&7V&Z>>=?0"-TW"#E7/V3CW_*1@*VI;B@^? -M21EF6?.^)_UN@CL82I]HIT<;:R<>@2+;+#RMMY6I*/U]FZGQINO=(L/3*#_E -M5U3,F\8F_^)ZI`^%#0TR`*7(=M'GAH1Z&W%%SMK%$S(`QE,*^6?.6MVVEA^H -M`Y>:`Z^<*,$Q<"02QX)QTZ;O9%YPH;K('*2`L;>F?*ZC0C^Z=G4^9(Z)%V9Q"G7_SY3!5I`B]/7H@7 -MU]O`LQK!E,?3E$805$)KX47&Q-WX3RB7XV?S87X*S5;_:NQM5*7B3"56.2*M -M9KX!S[ZZR'YP-%++:"-V8:N'\Y%8HAP+$#WA*[C(+H9/)APU4E2Z:^Y:R%Z^ -M]Z3`7?QMK@75!*C8YQ^2P+0'?Q"%Y#R%#PY?T$G""_TAOMOQHP89`J)7F\@W+<_BQ/#K!1_LAG]AD:E2F-"8 -M]9EGWWO2_;$9R'?7$LL^Y]2H60AX..N -M#3IS1:;`LGOI![!L;C&Y)[`!-[XN#[5[/KF@*1866&"ZCC\[#$*J]$%)"`#2 -MV0FJ(>E2E8+H%]-05@+: -MQ0^"T&".^`;FHY$`!9IT1:&R$ENRQ2$>1 -M%A#&*R\466G@[JE7IH$`0$QBN#^#<^>3*/4@&>V59O$BH3JPKT62;#2"-^$8 -MUR_#`H_[QL4]`XF&>SR3?@@3BX<*_J -MGC<'%5I0!UKZF7<7PSKFV!,]9X0=>Q\YS"+>G+V;#>"-"%-)1:#D=1.TV56\ -ML3$1T/BORY6(_1U4=%8([W3PHIR[N'6+5L.G:NJ`W=78>FS+G)>MXH:?N@U` -M&MJQ/P!F)D8/IFOA`*`51"H5&SFB:@@E2%,G)!O<[(BW%`Z+FD5DG@I*@0]` -MX%3[Q1SH?1"=E.^ICW38DTXRZ7,1T=&6/("@U*2!7J)J.,00T&7*=+9DO<0Z -M3W$.49(DMD':OZV[$'2VB+GR@7\@71JU(9?8F*!<3)&)*)@)8"[%UCD/\7O> -M/4EKE,440IR!+_!)AH")KL8J\Y1[0_LR4`I@JMCEH'M%T)8'[3:.7`6S#1:?%1# -M*>54`%8Z2P4#]S%B&_V61"Y,)("&PB4(`.?[C%?-J(?!-P_VKA:8H"G!Q2H] -M.,.F'`T0J5+ZRVZ85AWI*N1B`8XOP7B<'#.;CJ*`G$9U%=O3/OVUF-OYYO3*G0K<[Y"%JX!X'#3S>P91<8 -MY-M-Z(0"Q_5-057,XS7*28Y')2*J7JJ_YD_SM7L@9-%NE)FN69TZ[;P-E8#\ -MY4AARJI`$6'](`O\MU7WIY<+CZ"*D/S-9[.=><+5K5G@WN"`B8:KHE*C_Q;\ -MH_)G++W<[U"$K08NWP\U=SCFS"-;X;)SD4^*G#,CA('):_*S3*`"[MN"U\78 -MA]Y^<=^7K^$FRTG\'>_SJCL9T$M"4ZUHJ/0EA^[PFK7Q;A(]-XN"OH#6$UD_>SG[@H><$6=?N#&-(8U!+]F`_72)= -M<[]`.?T[V@.OXQSLP$L<;_U]<"S%67%`?#N/XP24IE*&:FY//]><-A.`]LU1 -MCP7C['B^B/\F5@IV24JC-_9TC0V_8E&&P13B^PZ`,.60P+_0YN4)5L%`9^^! -MG[/#2>670#$FI9ZWD$^H[Q4T5X8!>3*5O-JJJ-@U7'!G(I[[1".^J"/]&L'` -M?EZ/V4Y=41%=ZW]WF@%YSJW-2(I?"GK[)$+7C@I[D?FE2XJV#'61D;M2X2V. -MKG4IM.HTA(%3TZE:I-U)?SC>R.CBE3.!;1CDHOWK-,3R+('J;Q9TK_=H>)E9 -M'=DFIO'7<4DPL-C"JG2$'P$^SO*'",7=;Z4M--IOR+8L77KFY%V);CG'\H -M4(:WG65D!7T1\L&YJ[;J\Z!!]!>_8L@4\_+%1F)!]--)`88$?&?TR&;0;@%< -M8[JA=KB)Z^:U5^;UT#O:.WTN^*GWC)M);IF@=[&ANVG)0HN6WI6)5XC5T#-U -M5/%BTU]+&LQ%-ZL#+31#NZ,W6^VLT+E"2XDPCM]2D?N.6=O3=E'0I3B+-)_88N2D[;@(>GVU -M8<>K^H:>-3)/469((HJ<;6CJ=KK2X!'!\58]OVRT\[1DV%U]]+;#PU7;O9`@ -M&L;N0[U2Y@W2A-BOF`(W&&K0H,S2"5<>AR;@*^<,IOOFQ!U'L7^$Z\_D.?L;QY3J$>,WN$Q\]NFT?*;N -MZG_M#+:\_QZ[S7@V;?[0&J6__G*)]4W)`\_0^XZ/R3:#K@K6:\'O[:!@B5S1 -M1B6L!7`+;.HUC9J$NGM(-^_$H//_Q^>`S:\O3"18!4__4F7RH')EA?'O33NS -M:7&?NTW9`?JJ6LS?_X^IPYJ!Z-0=WP[O,1K_W1`?[$7WE-XB.2OL-@GHY[[M -M]81'*WAM.[/'#)RHM!IZQG]$)PR][O1P[*4$8GX.\RJC^Y!)@8_V`(]5%ZF? -M!0$W5GHLA@ED:VDN?@V[C,*97#R42-NTMYJN?T'&^9*DHBGSW7<>Q=B%,(O& -M;%V222=;"N<4?;@TEI_N7=;L5%TK7H#G%&V$0W![+EJ#/];-J5_:YB?0ER`E -MSRD3-"*;?]I8P?4?,0/%B;.-+Q*NFZZJ,3HU)%7["@!H"059C#IY""-+"[C- -M/08(4I>EA*`;@(<$$AKE?.DQ,&/UQ0/K.V5HX5`-"?VMV*WQP$G>?H1+KU,L -MQ3-+`GS.=>!$H2PGKS.OOBUK-<9'X/"]'FR$S]Q4S@]C"MUX84HP;6F6I$9P -MY<5N.A]:,3AT2Z:7X!.LW"SGLX&1WZ^6:U5`^%VJ*"HJ)2Q>R<@`'/+UQN+Q -MY`D;S.@[Q97M"YI^`V2LX019:A-4J-C<8;Q+2=O_VI+4_CYU$P$T]ASI5Z2N -MP1\(W4NS*/O8Q1Y6/EUN*]U($#<#']T?-7OZBK:C5*8$#\.\`.?4B6B?0H.V -MGOZ2(30C````OXAG]JG_U.L^=."0,0````````````,`````ZVGV/A0P!P#M -M00``=&5S=&1I61IMJ;G<[Z6"DBFSK*16$E -M-Q31OW?HQ-Y&TBESE5=DVFTW&]`WUZ-R-,JS5W=>+E5=6_BE?P@_5^Y56:"L -M($`^[S?PV_AZK/Z?'U_X_+T^W=]3_AKZVM^?C]70;=G;7Z/)8UW[, -ML%^:*>*2_!'DK<]_A]#WF/V'\;FUMXSP>;W;EG:'H6?C7W/_/EN_W\_A]7P] -M]G*FS7.1>%]GZY&GA^<^MQ3WH_*_;XH)9H9_/AGNU_Z>$D2SNV?;N>CS:R_E -MI5]^UT67']VK/PWG"9[8K4L/PNW8K<+_CL>-]_4^5^+YZOAZGM>K>W/ -MW-S;Q[V=?8V-?[]G[_+L_4\?W=*U^MZ7LVO?_7'__N\GW8\W\[V:E\[C9MJW -M-,GT?PKU^A\'_>"#AS-?Y?O9Z>&*_^3^O8_#\>C?_T/J^-/FKVI)YY+Q^W7_ -MICSV;'V/NL+*0F3R-`45O[_2(KOAK/S'\M]>W_C -MCZWI^F*>@R6'IS_]Q[>6X3;X:5<-6$^.]N=V*N8R]E')-@@MPKD& -MSV^Y]GN&?V;/^[GU>N45:R)$"Y>LJYGF]/PV_T?]H4`\_AAS+?+?HFV]W>"M -MMG>1?C8?]63-_?_9B`LB;M&\LES#;)]01=@87X^@((SKV^*+DHJBF?HUY7\P -MF9R*7]G[>>;!'#\W\$4(T1)=?F^O/RY6]+GXH)WY<.:K(M][*^_AO!)IP-R* -M[=Z3F.R;ESE%GIEO36']H8_I,F'AXND#1=`V'/FF6],F&*B@C>!U,F#'/\A4 -M$Q17^&A2',5@R#/E-!?N)]>5>7,I^I,^NX9^FPEI[(-!#US,3XLB!FB#CRH^ -M=#D_,Y1WTW;1#1CBS$`W?Q3>FU?SNS1<-^BJ*WE].PB4+R/QTF.K9H](-;6L(*$7SHKK/39S\,>93/IF;MDTN7L4(_;$FM#N/F))6Z:)6ITBGV9B -M;-$.;*BC(7[D(^P&LYC*BA4>[Q0N:$<-AD[EH3XT,8F'D>#9$-^X?1O4[;TB -M=O,UQ;Z:!HSL[@!#X-[#?OGYCW>"R,5P?&63AE@O!PO03M?LW&)F'-B:"*3*#B@"7DW(]@4I*ES -M.UFZMQ30S)F6@D8JS)@Z[H9CG:Q280H##<*<>$D8H:Z#ED5D(**77LQ -M)851WS^32G\O:6X/;N^BAU]&Y?/X>JYLZ7X:.$,5'&_@R^XCD9T%*148GS?R_7#EUY.%PS45/1:*+`@A&@8<2D@;YR1)*JDN'",GD -MN#]%1,?&F:/7G,W.;B_"JP4F:U&Y$5)\4<=*IDV#/0'BR&O\UFSUFXJ\O,9&]%`N! -M#')JJ=U*U\K\,/A!@&G_K19&<4]=7?XH6-6*D9QK#@T=O%@9<27=S,&]0CFM -M!;N1XO*UA_=QEV"W/6?EJ>+S=5/<'"7Z<[R -M$E_&Q&*=>#K!4^%@Z!_ADDN*Z2D9#\J=..O%T>$]##'R,8`*E!SNWT92'&ZD -M+\\9?.G*W7=2YV<,X8C?@7PA@M^\/\(@!(L8?CH;HOJ.FT-22];[R`?+84`C -M?2G92OU`O)F/$#KW%^5.CM[PS]\KZ"[;/'L_M;DP8F>*KP6+?Y;'X#U=IJ%F(GR"`_ -M!#M"*M^N$(@9[&C^-?SZ^G^B,.MI]0N0-E__I_QULC]*R-D39U?/7V.RT)ZU -M4BV?O\F2X@J`S$>-FP.&&>X&]&>7R?MQ0QX.IH2Q]0!?986K;27HIS!_'G:: -MMGOH]):D+[\@"7W`\=%F8K"Q^:--0SV.L#AW6'7MT!PL? -M82E6D0,,U`ALSPL!H$!/2C$F$)SQ?;,!A!J9=`1PU+,M&!$&XI. -MNTM1/8XH,"[%G#G1K/+%N#K'Y$K6H:*PK.8#6E!#*XJU4!%C2H.=F.$M)?&2 -MU]@:`FG+Y=1MK_TRRD71!+(E`PH+#<[G)D$]J(Z'^2WJ&)(Y.'$LEPJ"3];V -M/>C)3NQ$`9`!OD?R77W9LI0[Z.55^69K<;$H3EV -M?MBWE09(R03R^Q,XTI9.3K+PB9&P9@BJ"5@0` -M&NH*G0J_NXKV'A&&,S/!8+A^R]OI*G:29SF.4WTVX6;BG%OW'QKE2( -M^>P)-CT/02N:=$J#;S]PD,9)+2MAJ?I#,BID1V8`UCT5XOKS/!]0'^&ZX>&` -MJ@YRTT?PY6DN:`C1Y`4&=;5J!]>PL!(%9)N>4DJCF(H5S[9D)<$ZN9M*M\BJ -M"3YW1?2+`BXU9Y72"::*`U^^*U$DT6B5N3/SGRP_M_]N_%LAJPUO=]^YP6=S?LZG4T%JM@U_YZD1;6_FD1D5)?#@=B)O_SUNIB513J:D#_G;I7 -M@*4>`4*K4U=5_^&1O?\O;[=7RZ;U]P@,``^U-K>]7LW?[YI?A_:MU,1U/6=R -M*;,X4NIM`B:0HQP!PKF+U?^5ERH#['*1+82@=YP4P7>#&H#@_X6E2R.F1'(< -MR%9'&O0[&OL^37Z^G5_`2]O%G57Q@H^JF_/QP*"'U(&!Q8(> -MQT"X5=^CT.8]3'9K/E?=]_KUO=M>_=]86RL>[UK]-67)J_@;,[:B9)HA#M*S -MZN8_^C_RS9=Z"W+(P,Y3*)12BF:\.$O9PYB#0\P<7AM:<2M9?DW(D<^H#D29 -M@T!AN9AEKO]^)<(=2M>#.'Q6J'SO?9WQ0H?835R@HE%!H3@ZI`#Z]HSKI -MH.DL*4A>IW\VJG)HP<%T!.!IHT"U"A_=W -M_@83+:$3V9=<+0'FDRM9A97[VH?6J[BIO\Y)?:-USW^G$!"/31!TK/).VN&4 -M9A$TFH"!0!FH?L]1/FRCIJ=_*Z.C!?EJV'M^$IF;HMFA%JU,*/B0;0,*JL22/3Y6!PJ`=00P.(QH^S-$UG-35'9OV,6K)*8YH8YBQ9C -M54=:KU,.3.9.H9X`O6SP$V@>$"-JHO+*&D(BN8YXE?/CE*BZB5UFEC/RJ)J$ -M_O1(*)AGJ&>+#7N140C@JXZ?L!V=%,OS(:7DQTA\9Y%X*Z'1HYK[N94T;E%.T -M$HY(M9R%](CU62ZQ)J5#-:E:&6(@-3:N#J?"^\>10%=MSUU<+O620$15S2[1 -M"@6!=D4AM"8]N7$8J*&YF=2CK`AD>=#IUX:-P@SB5@5-=&M$34O6E&LQQM>Q -M.<($17Y3U.6=\0I+DQI@[T%RY5PI+H=RSQ:+M@L3(/DAF;,<'TCL`49@,1Y4 -M\,B2GR<3\C#-T5C:3E0:UE9@/KAG,9\_$SBTE6I[[/,CE8][=_MN>CU4.(]O -MCC0V_[@7;MRQ8!-PS(*"(H$STDXKU=8_@#HUIH`^8%GB@`>_#R -MA#6`CI+9<"$6U4FD?LDDA:,#/*J\')-RQJ]XG(/47!T*[Y,)`4[UW@5^5*TP -MC/P"KB,A4EMU*:[#Y8EP+*^^)!_P.UF3NVD]X/EIURBWAE3D4BP$*P[WG;`0 -M--5J!KAKO)"W;K9U8_Y?DJ`I/>!KRA)-)D?HG]/HZ4Y0:K!.TU?`X\5&X'5IV5K,JQUIJ:Q8XMZDVES4M=F5F.B>#DAT^:::B,:$.%&VDH=D%V&/$4$A^ -MDBLG^SQI355JCM'FDKV8Q%\H7.(T`2X;C[RIJ>9@6E:6T9;:&8;FCC"CE+61 -MKE'#HHZUC2\=/HL%'6!*C`M+`E_J7\=5BZKC44..J%N^FWWH0D&980UZ&\BZ -M=EQ7^*=G!.T=BEG)RV4>).(G^L:H!`SU65"X>&>1'X@@T`L\84OBO]6A'CY% -M@/O)_T?"IJ4JUPW%08R#H:S,,H,.4NSNJL2NB"C"K0?609[Y)UHC`Q_+EN8S -M-J:2/"/@9/CK+F]J%"^+'Y'`@KXN6E"@-\[V/RD)]OF``K"#O&"DYL#C&E," -M/,=OX6Q'66%[AFT>.`;BZ])-8-=@F9$T[>AG?Q#HO@X/CD6SZ_AO>YXT(UM$ -M9)\89:7O\R5[[^(XZO+)YT*U1-)P-T-JO?Y>ZA2T)J$E]A@2"V`UY^PI6$A= -MHXI*\G5-A]?=#E/EU?*W3'^JIK/J.B1)0JYV16&I`U/-N%Y(5])+YP+U5F%T -M@RO<+)2J]H%+2(`)'1P]18#BC2Q`",Y'1X%Q*>!I;-S&L1P+RLOL'RXD6H0' -MQ2H6)9R4AT\^(P2#V4A -M!^ZP8&WA[`+(\`KRS\6A%S6>Z^?SS(.,'(J6+(],-T(*1ZIE;X@HW0&1KS0L -MZ<85@DP+5;;_/0D+Y.6MT6&=!F4E]KX`U5[I-P58'O+HM>0\X%;Y5T-M.S]] -M+H&SH#2DE>:.B=@-Y)SQ26QZ&*&Z_7?56]7H.0!/V61XBQW?59EK]BXV)5[,N;LV]#P_;T'E,W0-;MB9H&![4H'3N -M_%](?M%,XCW\S-W,J>X\9UI35L3I(+*C[')+;&;X/7C5FA'B -M*[H\PNH-IZFV&5M+244Y/@C6V5A>2W$@YBFY8;#V]U[9H$W-#<-SSRI -MH^>31F\;V&:=*-0RV.7IY#^ZV"JLX13H,7<%&X`&=XX\P*6W"%`YN862'3QS -MBQJSMU[LN+$`4=4P,K:<<-5IVIM#MO;L#,$]]DO:RW'-'8H.)]HBV,.%"0YO -M'\QKERWD2;.M3#\%B+J!SGL(K5C.>(A;R<+)*1#Y8-#EMNK,=Z2WM$!2`")V2$"R!OLV(U3"]W]`!(:! -M#6<]@]?27!)6;<&:!03HSN5;YVY)C>I/1WYV.WAXD+W-&.W.Z`RMOX(VNKWN -M@6,]$?$YX:F)XA-6LW^&_N*!.>$9BED8S?4$*5406C'2'Q[[G#0DQ&G]4(;6 -M?T0>C0VM(7]RQX3?:+2)J:OE5/QDUQBOHMVO3)>DHK>TDZBVG+,Y'_X*:;'W -MS:*:7#E-BS!;P$T!%>,FC:%'?-_-,@NLZ&ZJRJ6*H-5C-*B"G"[+R*P\985O -M\=`H^7B&O\V6$W'\*&C6%0FJ55IE<*JD"O&D4Y"EH\Z-K&&F-_-OK`J=\WV9 -MGCJUVYK&XHT5H6!:N^D,*#M;:2]I\(P?3Q.W="@O%,*J([?E*)07*<*\+.WF%6VVB6W0UV,9AP -M6-7F^`.$1.K->EV0V?*2;6G7CS-`#4=5[6=9GI,H`@KN)+>*@N -M&KW6L]G&<33PNY!9G'K8O:3!#9=9BY@_P,XLMSOJT]P^X%AC)%]]7HC9#SZG -M37/@9OHNP2QXWC1V(-M8C`%.,_P0VXZ"+A9#J:]Z-`B"R6@577;36U(&SN'? -M-;"+'*>`DY^MT9H[296"#300JKFOIY%(U,@\^%/(M5;3GTQO4VV>/W;N>!OK -M:FJV]R4Z=*MBBJ+/%D/'G,>G#0R++M@SFB+F/#%>Z]$;&SLF\94M2Q`\MSF1 -MG\9FZ_0C(#A2QF:JET$0C9EJ&<*EH=6=%+8+Z\#_WJJADJ\#%W9CS1*9"L94 -M_6]CX4@\T9&>]FSVO-MVG;-"<*=7U/8VDI;.C8\GZGJ)$"!,*L0J04"VXE\R -MR[#FEKY#_M9\IMQ5H@]MA:EOOOP0EY&OEAV5=+NJS1C6QIT:ZGI&^N-;O -M=CIE*FNK\J93!#;$X`."6^@BX>(NEN4+;U!8N[H`UDJ"G:(&7`=1!CFD7W/O -M)]S!_1P.YDTGW55@XF#=T?5Z")ARQB7+VV -M&YWU`BG_Y`'"N0'CL_W[_>ZL!S^+(9.G^7YZ&Z9Y*=I-W6'NXO!A.>Y"Z1K\ -MMK%/#-I.F7-)'+!5QNU/3'7K+;479/L16X:1IYJGY\@]-."QGD4('I;6YS"3 -M2:$#I*ZA5O5(P76ZCNW01(2#J@H-;X\2]9F,_G2=6#7K;;R63\$`XJNW^+1?I+Z%,,AR*,R2:-6$?3 -MU-IZ[*-I&].AW+[B6S2)>&&J]S:>>UT%.0981-KV`<(.-"WHC=44R\W(O.!G -MIOJ:.1"S6^7"=AFT.NI38@<>\;,OFIZIDT,AY:;+8;1DE"^"N&R1,M(;2OU* -MK];K+9=B7%`(_T1+0M$=H7KN27_7A^GTQS(RI@/@?QV[#*?NU>=`R:. -MN4A1M!^S1F"<%^KD%Z#A-\O;T(C6=R1DR -M"T;#41I(#6I6]L$S"W6W3=]9MPW(VCG<"8TLWEKC+?1MF!3@-#>GHH16C3=H -ML47Q'H'TDR<3^3'TW)8E]PMJ.A#MR&-"P-IH(88*A9<(0R%[H[^?D*,5V&B9 -M'?S]+X<.8Q&$Y[(ER2<<+=EI./N8A/(#\.''7 -M5B92ZDY#)K"[50-EB*4KHO,<&.]1TSO09W)HG>57;VCI8=.8:6EON]'X9 -M525-&NC$TN\Z=4N34'77V!RAZ63P[4+.R2VI:OP2%NJDR_D:&7/E*BJ2 -M%EO;SUA]TQJ6'_;/20MN1LRIKO\"H6ZTH"JL'5N'ND<$O#.!G4_VMVIY4K+> -MD;RCZGV#>`M(Q91ZF7+M&A\BTGAU+N91$9ALO+[S`=%8\UJ/6V`2Y8#&^,M& -M8GTHZGC5*GU8!Y+V!26*0]"=!`<"B-4.DEI"Z%-IY=S`>K9UJ?X2HZ;4N9D_ -MAK(`0S(Z/W"EWA^D6`DRT/SLO5="QS/F\X1887E?@:J[-0;'&UQ-ETG.5 -MMTWZT->L7R^G3"R'B86E`:-A4P?N"?$?YZ11$5)\*ZYZ+44YLGW?5N_K(58Y -M)0"0XP)HO!^J<)W@3G>I^QE3>`H,>7FPUJ9MJ2Y%#3?J:_LWV6-L1I5N3>XR -M!GS>^JTH?G?%,X8'G*>'-T`VZP"T[(P?H`WH/44@AJ>]]W2JUFLA*&&X1C8A -M!A1:"'"M1R6^-YFE6UDI)7-O\$>RYK],SVA29)08;X7Z#HI%QX;MT?P&+I=: -ME&ZK53),FU"0+9'!B:FAO6@V*N.+BFI,'L%"N>EK%+K4C^E?T%(39% -M2\DB@]C_7<=2-K6CH+=@J`*:G%3V..;7<<$H9*8BVSN5C*NA2;2DI4L)P8K(D%07B=Q0P!IB+Z+SP3VA_'!E4%-=4YQ?FF,)UAK, -MO#V*^Q3-CW1)):*=.2(>.H:8*E2$$DRV&X+!.D,]/C7H+G((,\'#5P_@(X/! -MEO'B9;U'*C;*DUE3K;1O9,*5U]UM5DVXY,ZF010,,Q1I=7,[023J7VD1>5E7 -MVG3D(X`"/AL4:7Y6K3MKFC9HXK8NRX(W$6D<[HPDK.DAH\\1:MG\=^I,U5/, -M+(T22K%U8R^H!L6VR71C#:.,M+RO`X.[*?4).3^(D-JE5'0Q4$=5K?Y_L2'O -M)-T/=6^V\K;AR*Z\??@7L00(E"+'''E=:.8VM)50G#1"%]I`IZ*:ED6F2E0\ -M6JAW2LV+F?(.*Z3,ZGYY"#M&A'Q[-<0EM-)1C3?`O3#K4LG'#I&B$+AZ6QH" -M4$EW@_>Y(EAJC'2`S&-WVC[`J.T^"`#(_HSWH7AWMUFBN#$'_$N5_\(HI\SS -M2MN(/>:@9YAT()!+`+,;``"/3@```V.F!5XVL]H^'3,A`*2!``!T97-T9&ER -M7$QI8F%R8VAI=F5!9&1I;F=497-T+FAT;6R`S'*H[3YSJ.T^#!U1#,S1%\6= -MF]T/PH[-`V-[U)/P29F;F3P#KD;FQC9X>MJ;G<[Z6"DBFSK*16$E-Q31OW?H -MQ-Y&TBESE5=DVFTW&]`WUZ-R-,JS5W=>+E5=6_BE?P@_5^Y56:"L($`^[S?P -MV_AZK/Z?'U_X_+T^W=]3_AKZVM^?C]70;=G;7Z/)8UW[,L%^:*>*2 -M_!'DK<]_A]#WF/V'\;FUMXSP>;W;EG:'H6?C7W/_/EN_W\_A]7P]]G*FS7.1 -M>%]GZY&GA^<^MQ3WH_*_;XH)9H9_/AGNU_Z>$D2SNV?;N>CS:R_EI5]^UT67 -M']VK/PWG"9[8K4L/PNW8K<+_CL>-]_4^5^+YZOAZGM>K>W/W-S;Q[V= -M?8V-?[]G[_+L_4\?W=*U^MZ7LVO?_7'__N\GW8\W\[V:E\[C9MJW-,GT?PKU -M^A\'_>"#AS-?Y?O9Z>&*_^3^O8_#\>C?_T/J^-/FKVI)YY+Q^W7_ICSV;'V/ -MNL+*0F3R-`45O[_2(KOAK/S'\M]>W_CCZWI^F*> -M@R6'IS_]Q[>6X3;X:5<-6$^.]N=V*N8R]E')-@@MPKD&SV^Y]GN& -M?V;/^[GU>N45:R)$"Y>LJYGF]/PV_T?]H4`\_AAS+?+?HFV]W>"MMG>1?C8? -M]63-_?_9B`LB;M&\LES#;)]01=@87X^@((SKV^*+DHJBF?HUY7\PF9R*7]G[ -M>>;!'#\W\$4(T1)=?F^O/RY6]+GXH)WY<.:K(M][*^_AO!)IP-R*[=Z3F.R; -MESE%GIEO36']H8_I,F'AXND#1=`V'/FF6],F&*B@C>!U,F#'/\A4$Q17^&A2 -M',5@R#/E-!?N)]>5>7,I^I,^NX9^FPEI[(-!#US,3XLB!FB#CRH^=#D_,Y1W -MTW;1#1CBS$`W?Q3>FU?SNS1<-^BJ*WE].PB4+R/QTF.K9H](-;6L -M(*$7SHKK/39S\,>93/IF;MDTN7L4(_;$FM#N/F))6Z:)6ITBGV9B;-$.;*BC -M(7[D(^P&LYC*BA4>[Q0N:$<-AD[EH3XT,8F'D>#9$-^X?1O4[;TB=O,UQ;Z: -M!HSL[@!#X-[#?OGYCW>"R,5P?&63AE@O!PO03M?LW&)F'-B:"*3*#B@"7DW(]@4I*ES.UFZMQ30 -MS)F6@D8JS)@Z[H9CG:Q280H##<*<>$D8H:Z#ED5D(**77LQ)851WS^3 -M2G\O:6X/;N^BAU]&Y?/X>JYLZ7X:.$,5'&_@R^XCD9T%*148 -MGS?R_7#EUY.%PS45/1:*+`@A&@8<2D@;YR1)*JDN'",GDN#]%1,?& -MF:/7G -M,W.;B_"JP4F:U&Y$5)\4<=*IDV#/0'BR&O\UFSUFXJ\O,9&]%`N!#')JJ=U* -MU\K\,/A!@&G_K19&<4]=7?XH6-6*D9QK#@T=O%@9<27=S,&]0CFM!;N1XO*< -MOQ,V+I597=%5*XV'MJ.?B2!?VVARCU3,A8.AG$54X;[$=HX-*V"D)WW:RZ6J -M?B89CFR08V^J(1\,KS?8YVG>UA_=QEV"W/6?EJ>+S=5/<'"7Z<[R$E_&Q&*= -M>#K!4^%@Z!_ADDN*Z2D9#\J=..O%T>$]##'R,8`*E!SNWT92'&ZD+\\9?.G* -MW7=2YV<,X8C?@7PA@M^\/\(@!(L8?CH;HOJ.FT-22];[R`?+84`C?2G92OU` -MO)F/$#KW%^5.CM[PS]\KZ"[;/'L_M;DP8F>*KP6+?Y;'X#U=IJ%F(GR"`_!#M"*M^N -M$(@9[&C^-?SZ^G^B,.MI]0N0-E__I_QULC]*R-D39U?/7V.RT)ZU4BV?O\F2 -MX@J`S$>-FP.&&>X&]&>7R?MQ0QX.IH2Q]0!?986K;27HIS!_'G::MGOH]):D+[\@"7W`\=%F8K"Q^:--0SV.L#AW6'7MT!PL?82E6D0,, -MU`ALSPL!H$!/2C$F$)SQ?;,!A!J9=`1PU+,M&!$&XI.NTM1/8XH -M,"[%G#G1K/+%N#K'Y$K6H:*PK.8#6E!#*XJU4!%C2H.=F.$M)?&2U]@:`FG+ -MY=1MK_TRRD71!+(E`PH+#<[G)D$]J(Z'^2WJ&)(Y.'$LEPJ"3];V/>C)3NQ$ -M`9`!OD?R77W9LI0[Z.55^69K<;$H3EV?MBWE09( -MR03R^Q,XTI9.3K+PB9&P9@BJ"5@0`&NH*G0J_ -MNXKV'A&&,S/!8+A^R]OI*G:29SF.4WTVX6;BG%OW'QKE2(^>P)-CT/ -M02N:=$J#;S]PD,9)+2MAJ?I#,BID1V8`UCT5XOKS/!]0'^&ZX>&`J@YRTT?P -MY6DN:`C1Y`4&=;5J!]>PL!(%9)N>4DJCF(H5S[9D)<$ZN9M*M\BJ"3YW1?2+ -M`BXU9Y72"::*`U^^*U$DT6B5N3/SGRP_M_]N_%LAJPUO=]^YP6 -M=S?LZG4T%JM@U_YZD1;6_FD1D5)?#@=B)O_SUNIB513J:D#_G;I7@*4>`4*K -M4U=5_^&1O?\O;[=7RZ;U]P@,``^U-K>]7LW?[YI?A_:MU,1U/6=R*;,X4NIM -M`B:0HQP!PKF+U?^5ERH#['*1+82@=YP4P7>#&H#@_X6E2R.F1'(H^JF_/QP*"'U(&!Q8(>QT"X5=^C -MT.8]3'9K/E?=]_KUO=M>_=]86RL>[UK]-67)J_@;,[:B9)HA#M*SZN8_^C_R -MS9=Z"W+(P,Y3*)12BF:\.$O9PYB#0\P<7AM:<2M9?DW(D<^H#D29@T!AN -M9AEKO]^)<(=2M>#.'Q6J'SO?9WQ0H?835R@HE%!H3@ZI`#Z]HSKIH.DL*4A> -MIW\VJG)HP<%T!.!IHT"U"A_=W_@83+:$3 -MV9=<+0'FDRM9A97[VH?6J[BIO\Y)?:-USW^G$!"/31!TK/).VN&49A$TFH"! -M0!FH?L]1/FRCIJ=_*Z.C!?EJV'M^$IF;HMFA%JU,*/B0;0,*JL22/3Y6!PJ`=00P.(QH^S-$UG-35'9OV,6K)*8YH8YBQ9C54=:KU,. -M3.9.H9X`O6SP$V@>$"-JHO+*&D(BN8YXE?/CE*BZB5UFEC/RJ)J$_O1(*)AG -MJ&>+#7N140C@JXZ?L!V=%,OS(:7DQTA\9Y%X*Z'1HYK[N94T;E%.T$HY(M9R% -M](CU62ZQ)J5#-:E:&6(@-3:N#J?"^\>10%=MSUU<+O620$15S2[1"@6!=D4A -MM"8]N7$8J*&YF=2CK`AD>=#IUX:-P@SB5@5-=&M$34O6E&LQQM>Q.<($17Y3 -MU.6=\0I+DQI@[T%RY5PI+H=RSQ:+M@L3(/DAF;,<'TCL`49@,1Y4\,B2GR<3 -M\C#-T5C:3E0:UE9@/KAG,9\_$SBTE6I[[/,CE8][=_MN>CU4.(]OCC0V_[@7 -M;MRQ8!-PS(*"(H$STDXKU=8_@#HUIH`^8%GB@`>_#RA#6`CI+9 -M<"$6U4FD?LDDA:,#/*J\')-RQJ]XG(/47!T*[Y,)`4[UW@5^5*TPC/P"KB,A -M4EMU*:[#Y8EP+*^^)!_P.UF3NVD]X/EIURBWAE3D4BP$*P[WG;`0--5J!KAK -MO)"W;K9U8_Y?DJ`I/>!KRA)-)D?HG]/HZ4Y0:K!.TU?`X\5&X'5IV5K,J -MQUIJ:Q8XMZDVES4M=F5F.B>#DAT^:::B,:$.%&VDH=D%V&/$4$A^DBLG^SQI -M355JCM'FDKV8Q%\H7.(T`2X;C[RIJ>9@6E:6T9;:&8;FCC"CE+61KE'#HHZU -MC2\=/HL%'6!*C`M+`E_J7\=5BZKC44..J%N^FWWH0D&980UZ&\BZ=EQ7^*=G -M!.T=BEG)RV4>).(G^L:H!`SU65"X>&>1'X@@T`L\84OBO]6A'CY%@/O)_T?" -MIJ4JUPW%08R#H:S,,H,.4NSNJL2NB"C"K0?609[Y)UHC`Q_+EN8S-J:2/"/@ -M9/CK+F]J%"^+'Y'`@KXN6E"@-\[V/RD)]OF``K"#O&"DYL#C&E,"/,=OX6Q' -M66%[AFT>.`;BZ])-8-=@F9$T[>AG?Q#HO@X/CD6SZ_AO>YXT(UM$9)\89:7O -M\R5[[^(XZO+)YT*U1-)P-T-JO?Y>ZA2T)J$E]A@2"V`UY^PI6$A=HXI*\G5- -MA]?=#E/EU?*W3'^JIK/J.B1)0JYV16&I`U/-N%Y(5])+YP+U5F%T@RO<+)2J -M]H%+2(`)'1P]18#BC2Q`",Y'1X%Q*>!I;-S&L1P+RLOL'RXD6H0'Q2H6)9R4 -MAT\^(P2#V4A!^ZP8&WA -M[`+(\`KRS\6A%S6>Z^?SS(.,'(J6+(],-T(*1ZIE;X@HW0&1KS0LZ<85@DP+ -M5;;_/0D+Y.6MT6&=!F4E]KX`U5[I-P58'O+HM>0\X%;Y5T-M.S]]+H&SH#2D -ME>:.B=@-Y)SQ26QZ&*&Z_7?56]7H.0!/V61XBQW?59EK]BXV)5[,N;LV]#P_;T'E,W0-;MB9H&![4H'3N_%](?M%, -MXCW\S-W,J>X\9UI35L3I(+*C[')+;&;X/7C5FA'B*[H\PNH- -MIZFV&5M+244Y/@C6V5A>2W$@YBFY8;#V]U[9H$W-#<-SSRIH^>31F\; -MV&:=*-0RV.7IY#^ZV"JLX13H,7<%&X`&=XX\P*6W"%`YN862'3QSBQJSMU[L -MN+$`4=4P,K:<<-5IVIM#MO;L#,$]]DO:RW'-'8H.)]HBV,.%"0YO'\QKERWD -M2;.M3#\%B+J -M!SGL(K5C.>(A;R<+)*1#Y8-#EMNK,=Z2WM$!2`")V2$"R!OLV(U3"]W]`!(:!#6<]@]?2 -M7!)6;<&:!03HSN5;YVY)C>I/1WYV.WAXD+W-&.W.Z`RMOX(VNKWN@6,]$?$Y -MX:F)XA-6LW^&_N*!.>$9BED8S?4$*5406C'2'Q[[G#0DQ&G]4(;6?T0>C0VM -M(7]RQX3?:+2)J:OE5/QDUQBOHMVO3)>DHK>TDZBVG+,Y'_X*:;'WS:*:7#E- -MBS!;P$T!%>,FC:%'?-_-,@NLZ&ZJRJ6*H-5C-*B"G"[+R*P\985O\=`H^7B& -MO\V6$W'\*&C6%0FJ55IE<*JD"O&D4Y"EH\Z-K&&F-_-OK`J=\WV9GCJUVYK& -MXHT5H6!:N^D,*#M;:2]I\(P?3Q.W="@O%,*J([?E*)07*<*\+.WF%6VVB6W0UV,9AP6-7F^`.$ -M1.K->EV0V?*2;6G7CS-`#4=5[6=9GI,H`@KN)+>*@N&KW6L]G& -M<33PNY!9G'K8O:3!#9=9BY@_P,XLMSOJT]P^X%AC)%]]7HC9#SZG37/@9OHN -MP2QXWC1V(-M8C`%.,_P0VXZ"+A9#J:]Z-`B"R6@577;36U(&SN'?-;"+'*>` -MDY^MT9H[296"#300JKFOIY%(U,@\^%/(M5;3GTQO4VV>/W;N>!OK:FJV]R4Z -M=*MBBJ+/%D/'G,>G#0R++M@SFB+F/#%>Z]$;&SLF\94M2Q`\MSF1G\9FZ_0C -M(#A2QF:JET$0C9EJ&<*EH=6=%+8+Z\#_WJJADJ\#%W9CS1*9"L94_6]CX4@\ -MT9&>]FSVO-MVG;-"<*=7U/8VDI;.C8\GZGJ)$"!,*L0J04"VXE\RR[#FE -MKY#_M9\IMQ5H@]MA:EOOOP0EY&OEAV5=+NJS1C6QIT:ZGI&^N-;O=CIE*FNK -M\J93!#;$X`."6^@BX>(NEN4+;U!8N[H`UDJ"G:(&7`=1!CFD7W/O)]S!_1P. -MYDTGW55@XF#=T?5Z")ARQB7+VV&YWU`BG_ -MY`'"N0'CL_W[_>ZL!S^+(9.G^7YZ&Z9Y*=I-W6'NXO!A.>Y"Z1K\MK%/#-I. -MF7-)'+!5QNU/3'7K+;479/L16X:1IYJGY\@]-."QGD4('I;6YS"32:$#I*ZA -M5O5(P76ZCNW01(2#J@H-;X\2]9F,_G2=6#7K;;R63\$`XJNW^+1?I+Z%,,AR*,R2:-6$?3U-IZ[*-I -M&].AW+[B6S2)>&&J]S:>>UT%.0981-KV`<(.-"WHC=44R\W(O.!GIOJ:.1"S -M6^7"=AFT.NI38@<>\;,OFIZIDT,AY:;+8;1DE"^"N&R1,M(;2OU*K];K+9=B -M7%`(_T1+0M$=H7KN27_7A^GTQS(RI@/@?QV[#*?NU>=`R:.N4A1M!^S -M1F"<%^KD%Z#A-\O;T(C6=R1DR"T;#41I( -M#6I6]L$S"W6W3=]9MPW(VCG<"8TLWEKC+?1MF!3@-#>GHH16C3=HL47Q'H'T -MDR<3^3'TW)8E]PMJ.A#MR&-"P-IH(88*A9<(0R%[H[^?D*,5V&B9'?S]+X<.8Q&$Y[(ER2<<+=EI./N8A/(#\.''75B92ZDY# -M)K"[50-EB*4KHO,<&.]1TSO09W)HG>57;VCI8=.8:6EON]'X9525-&NC$ -MTN\Z=4N34'77V!RAZ63P[4+.R2VI:OP2%NJDR_D:&7/E*BJ2%EO;SUA] -MTQJ6'_;/20MN1LRIKO\"H6ZTH"JL'5N'ND<$O#.!G4_VMVIY4K+>D;RCZGV# -M>`M(Q91ZF7+M&A\BTGAU+N91$9ALO+[S`=%8\UJ/6V`2Y8#&^,M&8GTHZGC5 -M*GU8!Y+V!26*0]"=!`<"B-4.DEI"Z%-IY=S`>K9UJ?X2HZ;4N9D_AK(`0S(Z -M/W"EWA^D6`DRT/SLO5="QS/F\X1887E?@:J[-0;'&UQ-ETG.5MTWZT->L -M7R^G3"R'B86E`:-A4P?N"?$?YZ11$5)\*ZYZ+44YLGW?5N_K(58Y)0"0XP)H -MO!^J<)W@3G>I^QE3>`H,>7FPUJ9MJ2Y%#3?J:_LWV6-L1I5N3>XR!GS>^JTH -M?G?%,X8'G*>'-T`VZP"T[(P?H`WH/44@AJ>]]W2JUFLA*&&X1C8A!A1:"'"M -M1R6^-YFE6UDI)7-O\$>RYK],SVA29)08;X7Z#HI%QX;MT?P&+I=:E&ZK53), -MFU"0+9'!B:FAO6@V*N.+BFI,'L%"N>EK%+K4C^E?T%(39%2\DB@]C_ -M7<=2-K6CH+=@J`*:G%3V..;7<<$H9*8BVSN5C*NA2;2DI4L)P8K(D%07B=Q0P!IB+Z+SP3VA_'!E4%-=4YQ?FF,)UAK,O#V*^Q3- -MCW1)):*=.2(>.H:8*E2$$DRV&X+!.D,]/C7H+G((,\'#5P_@(X/!EO'B9;U' -M*C;*DUE3K;1O9,*5U]UM5DVXY,ZF010,,Q1I=7,[023J7VD1>5E7VG3D(X`" -M/AL4:7Y6K3MKFC9HXK8NRX(W$6D<[HPDK.DAH\\1:MG\=^I,U5/,+(T22K%U -M8R^H!L6VR71C#:.,M+RO`X.[*?4).3^(D-JE5'0Q4$=5K?Y_L2'O)-T/=6^V -M\K;AR*Z\??@7L00(E"+'''E=:.8VM)50G#1"%]I`IZ*:ED6F2E0\6JAW2LV+ -MF?(.*Z3,ZGYY"#M&A'Q[-<0EM-)1C3?`O3#K4LG'#I&B$+AZ6QH"4$EW@_>Y -M(EAJC'1/`[S9UA9,WT5`&I*2B-\5*XZ>SW"Y0.C)1^;.UK]$ -MXK@UJ)SH93P!`!P`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar_encryption_header.c b/thirdparty/libarchive/libarchive/test/test_read_format_rar_encryption_header.c deleted file mode 100644 index 81965eb67..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar_encryption_header.c +++ /dev/null @@ -1,71 +0,0 @@ -/*- - * Copyright (c) 2013 Konrad Kleine - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_read_format_rar_encryption_header) -{ - /* This file is password protected (encrypted) with AES-256. The headers - ARE encrypted. Password is "12345678". */ - const char *refname = "test_read_format_rar_encryption_header.rar"; - struct archive_entry *ae; - struct archive *a; - char buff[128]; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - assertEqualIntA(a, ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW, archive_read_has_encrypted_entries(a)); - - /* Verify regular file but with encrypted headers - as a consequence, all meta information is invalid. */ - assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae)); - - assertEqualInt(0, archive_entry_mode(ae)); - assertEqualString(NULL, archive_entry_pathname(ae)); - assertEqualInt(0, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(1, archive_entry_is_data_encrypted(ae)); - assertEqualInt(1, archive_entry_is_metadata_encrypted(ae)); - assertEqualIntA(a, 1, archive_read_has_encrypted_entries(a)); - assertEqualInt(ARCHIVE_FATAL, archive_read_data(a, buff, sizeof(buff))); - - assertEqualInt(1, archive_file_count(a)); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_RAR, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar_encryption_header.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar_encryption_header.rar.uu deleted file mode 100644 index 5bd48d7a5..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar_encryption_header.rar.uu +++ /dev/null @@ -1,8 +0,0 @@ -begin 664 test_read_format_rar_encryption_header.rar -M4F%R(1H'`,Z91EQMQ=@1S -M,[$:0Y\;'G8_C0D%2L":*;.B*LM0!,!.2!RBU?+`DTN9KXD\<4RGSC+#KCC:\R -M$)P&_/D2I'(4,7$^#2[\,Y"D.2T$@B1#J-Z$]R6_*($W7+!JH\,(XH,'C7FC -H@B,\$1>+CX-=`-%F3C6%I^,NJV2G7':,JF?4KS:6=TAK%$V=]2+N^@`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar_encryption_partially.c b/thirdparty/libarchive/libarchive/test/test_read_format_rar_encryption_partially.c deleted file mode 100644 index 81256a96a..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar_encryption_partially.c +++ /dev/null @@ -1,79 +0,0 @@ -/*- - * Copyright (c) 2013 Konrad Kleine - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_read_format_rar_encryption_partially) -{ - /* This file contains one file that is encrypted (foo.txt, password=12345678) - and one file that is not encrypted (bar.txt) The header is not encrypted - on this file. */ - const char *refname = "test_read_format_rar_encryption_partially.rar"; - struct archive_entry *ae; - struct archive *a; - char buff[128]; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - assertEqualIntA(a, ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW, archive_read_has_encrypted_entries(a)); - - /* Verify encrypted file "foo.txt". */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0664), archive_entry_mode(ae)); - assertEqualString("foo.txt", archive_entry_pathname(ae)); - assertEqualInt(16, archive_entry_size(ae)); - assertEqualInt(1, archive_entry_is_data_encrypted(ae)); - assertEqualInt(0, archive_entry_is_metadata_encrypted(ae)); - assertEqualIntA(a, 1, archive_read_has_encrypted_entries(a)); - assertEqualInt(ARCHIVE_FATAL, archive_read_data(a, buff, sizeof(buff))); - - /* Verify unencrypted file "bar.txt". */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0664), archive_entry_mode(ae)); - assertEqualString("bar.txt", archive_entry_pathname(ae)); - assertEqualInt(16, archive_entry_size(ae)); - assertEqualInt(0, archive_entry_is_data_encrypted(ae)); - assertEqualInt(0, archive_entry_is_metadata_encrypted(ae)); - assertEqualIntA(a, 1, archive_read_has_encrypted_entries(a)); - assertEqualInt(16, archive_read_data(a, buff, sizeof(buff))); - - assertEqualInt(2, archive_file_count(a)); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_RAR, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar_encryption_partially.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar_encryption_partially.rar.uu deleted file mode 100644 index 0c9727f1a..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar_encryption_partially.rar.uu +++ /dev/null @@ -1,7 +0,0 @@ -begin 664 test_read_format_rar_encryption_partially.rar -M4F%R(1H'`,^0'2>C_^E6-T51TBV:OLN/8KJ<5S5/Y4G6N&PG<5GX;P= -MF_YJK^@\`3\09C!T((`G`!P````0`````[[BD,VF3#%#'3,'`+2!``!B87(N -F='AT#!#)/HRW]%5!"GXA#4D)_]J&++4FP^?OH,0]>P!`!P`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar_filter.c b/thirdparty/libarchive/libarchive/test/test_read_format_rar_filter.c deleted file mode 100644 index 46c574743..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar_filter.c +++ /dev/null @@ -1,57 +0,0 @@ -/*- - * Copyright (c) 2003-2021 Wei-Cheng Pan - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_read_format_rar_filter) -{ - const char *refname = "test_read_format_rar_filter.rar"; - struct archive *a; - struct archive_entry *ae; - char *buff[12]; - const char signature[12] = { - 0x4d, 0x5a, 0x90, 0x00, - 0x03, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, - }; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString("bsdcat.exe", archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertEqualInt(204288, archive_entry_size(ae)); - assertA(12 == archive_read_data(a, buff, 12)); - assertEqualMem(buff, signature, 12); - - assertA(1 == archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_file_count(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar_filter.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar_filter.rar.uu deleted file mode 100644 index fe08c6dd8..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar_filter.rar.uu +++ /dev/null @@ -1,2099 +0,0 @@ -begin 664 test_read_format_rar_filter.rar -M4F%R(1H'`,^0`P`"20.Q32)L250= -M,PH`(````&)S9&-A="YE>&44(945#(D9W!8B+N7`S2#`=A.D%X2[-NGU(*VLHG0+KG" -MV2*8G'[N``/\NP%@`$+_T&``$P!_EV`L``NK^@D``H@/\NP%@`%Y_T!@`$0! -M_EV`L``OK^@0``B`/\NP%@`%_?T+@`$P!1]UJDRA-<"D?]Z],JM,_I>F-Z%2 -M=^K_AM;?TWL7W;=)5IVMR9/,?&MR_?>)XGBMEOV_`6YMOX -MBW[EQ,WWWEOYN-]^!]8[[SC%LVA'\\]-V=G\K\Z<>_:\R8JS_&^V6^,^ -MV^YE\P01SFQM(R,N_\F435/L*/M\R_%3=*FE9*_]$FUXM4V3GD]5[0ZK.9%Y -MY$N^2YBE#R3_)-FE")5N80#3:6-1HW3F_.[=R;:_/#4L3BU"[P"JJ=N?"X*0 -MF5-`^3%TDHYL`S>7,'(K2*#E]33/,Y>!X7BB=$24B6GL+A.:G.,3?_N?C-U)ZS -MH5":OVIK,W'#FV:$NRDX)LZK9-J)W_3KK=558VQ(E)U\[VM!`[5"3Q13)U,; -M*O3CQL9[9.Y:6@O82?2"6*YL3])&?)%/.\+TI2%BSJ_"(%:_ -M$G[Z8Q%:;S(!W>%+2W7F3BU3YV='K8R%9,S5\%<;;KC6>85MA!0\"^+!L+0Z -M\Y-)-WZ"D]4VJ@`V0*2[+SR6*?SAJ'VEO`=WRA_C6J#69P6_8H1/#NK2LW.3 -MFEC5RQFIFY<MR7<906S%@N1#4;35-<^^A:%$90V(2('6PXK""6[N)4]F%% -M:G($3N6[WN[HEX@#*S2H@+23U9"/[Z%LS`=6@8_[%,#OFQ_\5!F5MVO=[6_$ -M:(*Z*DS[FHFIV"5\(H[UMV0M>Q4`9AM@]86(6'C]RL,18T22^$)OM=8G/Z*0 -MU3VZ1E7?H'_\`EJGZK%1">A(< -MR_XXWIO%/V8*5XTD:T!:,Q#W]'W$]W-N/;$4Q5SDJUL9TJ0[_B]PSL^"T72"Y]KP4*%6L!8NE.0?:01DP,>XA@21Q?$=AW0RT:;4!FZE^R'2+""4 -M0]X2-][9G(!"RY/"B=/U4/TPR;#N&!Q_()X5^JT9B)7\@KIDA]5QQH"[A` -M^TC&?OK?QU>KP#"2!DK]N?9O:PO15/6_3(U\ZQTE:/1;(4J2+ -MTVF+OH4KGH_+3O2.%0E^M>0CH;UWPQE9,RPU5.?3]BWRL&"K3I&X,JB#$9Y1O?03CQ1-WG/HB4`$MA:/.W"Y -M2W^HJBUN+/Z&TU2(S6.(T,5"U9SFA5(V/K7@04Q.F=A8$/-.KPS$4=[81'IJ -M?;\>#,QZ/MVXZZ[SRZ56Z5Z9.#:B#]7JT\_)-YX&O/9CO_:3E=3]J"]_HT.7 -M!+C0S:PSAF:9%`W#I``G?+K!LKA%[B($XV*P`^W_D\40H\FCJN-#8],3J`'K -M;IVB%\!!JL5DU%4W'L#XXY[907E"[5IR./)X#NM94%.J;=Z++-\D!5!3$Y63 -M+SGX:U_YA^8X'V$]LKHH(1`12Y,K-4K[PB1'JB:S!8%6&68=ZPRM>19W3`YD -M3!#&RSRR(FGUH@]4/GGK$+0\_J]HU>C><4!D`YG%#C28,[SY>2ZMSJQ'WQ_18D?+@".L%%R1G$[6]W7P -M)T6--F,8"PP!F46R91PV6C1"U.CVAA_2]F/&UQ#Y)X$J+%(VA@!P^.A)(U2: -MZ\(2Z@SV)K]R/=5<1M-H;:`VX2?D@W9F70&E>`OHC<.1K3R0]F8-(DZ\KAV: -M-RS\RUH4_7DH+NC\)#_:NB3UT,K(Y/$?\7G1FN_Z;08#^+[7E"O`?HKJO>`B -M3U85W)%+=2_1#T@HW/H].@?3)AWKUQ8UIC@(SGZ^3=27UFKA&SV)JW!L]Z:M -M>;`/9[K6X@]]47()MMPCB/(69'6\\SL*\L%]F]KZFAPR88*%'Q`#:,U9XV)P -M2LOF!Y$5^$*^I7ICE$`!)Y'DHW_98B&0/I<^+;..0];]*1W]=!!F,-_9-NH2 -MQH0K;B:%(M_J>3%5NL_A-&K$Y;<\9+UCW9P0TGT%Y*3)-7I8S+L6/_XH1`L_ -M7U?-!];\*$WET)JP1MI,>4[7SU8"7.2`!?Z`++T^J*G/:PJ?^NON^7AJZE^S -M+$KL/6^%,P`N%5N^GGKO*BMW%KPF\JB6!RU.-"I6MY>>K)"2/F64!\5^PHH. -MDEWQ'4)731$(D=JA86^)#\O3%!:T0MKBXL+/S`5,GKC84IC2,*3;#F3B95'K -M-JA23=&$JO00HR?8F&#KMN?=\,">J^$"R/):#^X/C"]Y@]W21G$/&?+#VOO` -MK+\H?.?S;*+R2B@$IOPM0,-+#+0B@08HV1$DCD?*HTU0QRDK*KWS-]2-1^EM -MNEK;`XM-4AJZ!2MP=9_L1E'(?AFRL(,X\,^?<1'1)^TL.P$^S9R133ZY[?J\ -M,O31\D&7KV>9L:6#VG\XPS45L.+3HD&E$K^88ED]A#<;&E:./[IV^X*KCW%. -M/<(PH80@)YMTT<`0\LI:YNY6/9CL/Y$LJ_E/(56_;_'/<:'/^54?+W4$'W1& -M5(65Z#;V7V,&I9EAB`:@(U98#X]@DXKYFX^(>M_RSIQ7(@T,IM1750SBIHCA -M9"UM3ZIH]K,94T,.)OQ@LWU)TC4K$(_=[!=FT,OTFGPPPN,WV$.7(3KO*KSC -MKJB-148Q]N+"^)B\<10']/%.EN\,])"MOWY^P7#L"6#"N92NICY2.W[C*,.X -M(WB>X@O1ZM61!.I:H?3";_`JG/?<_6^0Y3%TRE(U\%>F_>>QVW=^JP+JB?Z, -M#"E75?E?@!?CQC*Q20A/[2.=SXSZDG2*=+%:O=/%I\:&KIJ6=)M"3S"^?)S5 -M,[X:+%7_4,A@PME>*K96KAZG;X<'WL*0PA.=912<^`F1&R^X1_%IP\"*R>\) -MO@.:E0(:-^^\)6$1$^]"A^M`.(Z) -MXL'8I,[XD'\,;Y.8.7&J(".]YW=?=US`NDCW12OLE;(7/M\L-US9M[X:NA*Y->:U(9TIOIU!C_C5FU=8[@I$01O]F5I1:.O*YG!FL=%-= -MO;_]3<@"PA81A:&4AA,M4*ZW61#>18LWOHD\HKME8:3-IK^HCR:63BTRLPC) -M'6`!+_]\%DT$N,V,]O0I_N[KR0Z7Z>V2%:EY.:@B\ZQ$A6X=X7HQU75[:,&@MQKT0?O?)@=7=1Q_ZG6?\$A)HS -MY/8-?MIBC&5SIO#%?VE@F/@\Y?0$DQ14S5=L,W?2]M5L$Y2/WR*+CW4M),Z# -M'YJ#,27;*W&O.DXR5*T)I9QX5Y_IA'WT&=SG>K"Z/4M5&R:!;GPT&OH` -M-;+'?+MYG!/=PY_P#S7S^N*Z:!/U'#@,/NLEF",-6,P)FHT# -MYOW(EYE#4<`L*FJ*^^]V4/)M@7M<<^L.70K*4`L;/5FQ<$#P73'"-740,2HL -MP/_GSL2K=&IJ9HYE#VY1F2,]01G-I^.8+PT,4U=\^=\,C)PT(O]S\IYT5/'3 -MP45@8^U?D\L])M8#V&;X9TS6[_<9\4A\TW!3(E9(A`2'LD&)_8I$/8]F'`R) -MX1"G((X"*W'#Q*?AGGVDY94K@WS%*/!@OX^9!W6/"!_K9;F!SJ=B -MX(W9.B`6$IPCW-WE2C!XQT#;#O:^Z5H'PBDI1[K/P@U6ZC*QXY][+5]XP7N- -M_(WLCT'^I614ZQR>]PL%%LKJL&&2A+!]`DL8<:!>F;RP"W]GUIN^A*>>-,LB -MOK(Z9@X=IX!\(TM3*JWQ\<7X"SNI[?LZ#"5&1912PR\GS`4:&3P"IHZ5!7?9 -M^@=42==Y)'NYS$H6;$G,$I7Q79;8%7@[VD,537-%%Q.5.`2"31Q0X!-HM:3- -MWN#GX9^<1N=5X0K5)=!D`V>Z4G^X[0@V0'.#Y`Q*:5'P%Z8H]'.0RP"X3[3`M;_'L?_&G.- -MHP)E4\L^%9#TN9I\C<(HZB[%FQY%B7C"RQP`*]69]=`,M@*-18P[V#U]L-). -M71;DK$#][8BUQ>):,5^S--<;YEQ6]/>Q4;A,;OM3^KRG]8+NP=)N535$L&B# -M6RB2Q(`ZPL$'0%C#C'B#9=(:FCG!6-X+5#Q\C-GK`O76RRHX8L%5?P21+O.Q9Y>N(IZ'=ZNT -MM3VN]C:)DY==?M"!D,"^-K]%;?$L'M8C9ZE-/B,3?K&L5^T<8K3 -ME]$B^DZ1IE[%GF=S">HWL1/R/6DD94)[/(JR[R=B9,N8DPJ/?B]-^W/[/./T -M_CZ+Y30%[0GU\BQ2I[-&+)+OSYBS----(Y$GDQF<.L:]//0^T6Z84Q(9NA9K@TQ\5FK:\=FG\:*%.;&XN -M7#O'L3]8,2U2:FW2'G&X,J.Q?8_/OJVYI6Y;:-EJ*`X5'I-^-C&J)QH:$#S$ -MB7DUNL[DJ)JD5Z;W#YX_'$]T`=TTQVGJAV.'@+K4LF0GE*XUE85VK9G/<1@4 -M_+R<0**9HUP>M[)3='#?HU>0#-/8O=56'KEV0OLBT7;%LUTDFUG.*\W+.PV" -M)KVPM$X<,MTA;;=@STH;@0[]'B2!K`]=Q#3O:8($W82D=D9.V_MM)S^\)W$T -M%^C`2(5%LG(=7UQ;^4VH[NJKHH'/!+-?3][*K-_-HVZB(Y19@K(C*K<4]Y0P -M_U`4@]%CWY#04?2S"%5)07)NL"P<1:`H"4EU>^QXI^H=E%1PR1FN*WNV -MZ-!P5J5UKG28S_K^I_HQOFQA)S_D#MO58Y/30FPO9UO"4/9CZOT)TDLK?IP# -MW;GKO:.J26YV#6*-88/1$HW!!=BNL,[29`(E6E;P8K2'WRDZ-TT=B9A=V"HA -MCLUC1RQP`59#S#2P8IYDDQZ0\UIF`5GO<2`01RZ0R;0LI39$0K!38R%*1%N% -MVQ5/459KFW6%$LTIG:-0:9>A8-#3H/UFL]TAMRB=^P<%!U3H[SGU_1/TUWIF -M=X(S(/T&MI0T))0OGQ_SQWJ>E$GX*'<(F*I[!>I1Q!41!9QJGSJ3:?]BA"#: -M#(=G51_1/ET0KT:>VMV_(=\:%9!V)BQGR/HU@V2''9.L&._\QGLE<^^J$^"]IC.F("';W[)#^VJBF_/#V -MUQ9M5&AQ_;6'JC'%/Y6R^^DU^O5B[8:.30=DE?.+"99D[VK,[-/KRQA$05UV -MJ=[,>+Z2,+HQT.#-*DK>'`CEFL(2D:X:"%#/>V5`4^U8/?=8..3@U>I;BX\+ -MKN]],T==QU/-76P^Q;A&$9H'C98*>@F"#R-XVT.\;&M!KC-M6'MA$0T-`'BC -M>^B9ZXU/6_QO/R)>X[E=1C165F"`01W]%V%X``P:D9K(A+R3;VCF:(K''%#) -MR:*ZK7`*>V?&FZ<%G:(?W!!C^J,U(1N>;=:3ELVCVR0M2/+^W&J=P%2_?@H\ -MAY/:D-"R[EZ12,CZ3APE=RX."Z5@]L$G-(P..C/+[!%[KN#8<&HXD0_4G30?)L&`*T\V:10WY!_8"@`G -MEC]/.5@%V?X0)M9(PA2ZD[V`/Z?H-[O6-Z_5-[ZLWK]`WOL3>O$&]]8;UT)O -M?9FZ%#\D!`MMS;II(,I;3.,PF -MQA1(+OA.\^&@"%LA_B@.ILM\"B(LBL_.3^EJ58"/B=81!/D1S0E[2`D4UGA6 -M*P=]F9HPH[*`=]A!+9#"GQ85?%FWD\/?9&LK,S^R$3(3*,R'NC9`85G?>1IE -MF2&B=7?X5M?A.("A_V5NV8"/H5"5@>>?!EQ$.44!XR96KG;M!,(9Q8OG_4)Q -MA-^A.K$BLL"=ZIJEUAL7!>A/#NM473W]KT"0HS+-*!"!7O`'SB(4!/>%S2\^ -M2$!Q,.5AG0>>5MHSF?3\:^\`0"Y^>2AYG>ONXH_"14QERG4V\F9$GQ^$@,NL -MU>0LWNQ7>R5'S>\.)O-$214$`WJB-]+I0H=RV/21)Y!,:LHCUPO?/FIK5#[^ -MF>-7A?=?97NGWJT[[4]RE,=VE0:"Z?Q$]67HHQ$>AQR$^BY\)9F#JD3N]K@G -M\..S:3JWL8]5*8/+R`$&=K^L8![!@,SR4%UK"9N\S.0%,8R7YS?>F,I[9`'> -M@50$=KI11*9+OI#*3GQ3[]LY[=%T7OV%VMB##\',\>=0'-E*K3DIPI@X7BV_ -M^>T&YN".A,!\>(.4EHPY=&='L\\EX\G*F5_/`6BPBTD:#\5 -M\C:!QUYT-,.J-5%Y-3D4N$@*391%]&<]GXKC98<39%+VZDZOTDC0KZ:!J]_8 -M)$\!U!D>M)4$+PU-$8_0G-6(.ZW=Z=:FC`VTX?0I9R]WT,`C<<]Z7.7&T_J( -M3K9E'0DV:==I:/9C\WX8Z^R,8)/_'HG%2,R=NJ+A%76:1IASO-SRC9>;RGV^ -M]$S8D6]NT3O8)^;RT3LY\=^RY1J(\OVN6;;<&B%J$DU],YC!'%<5T>$*TV6Y -MH]%X"RBYBTWG)+44(2)N.CQ5!6LZ+JR'2PKCX#E;+XF -M;VN8S]#SS<+?ZNFTE^\X_!&:6HT`P$SZO:SE>24]3QX#A7JU3#4-4P7W5Z?3 -M;)OQ8?^;56$D0:@'QUC'4>/A*=C`$R61=?CW-0Z%S=0>,7;9SC,*[]7I#P36 -MJ^\<7>,2\OV7,6Q!RKUM?82^S@SVAUE],41S&ML[J/M%9.8R:A'RVK[]*E]X -M73FE.EA=Q"/M]F3?:]]9I4W"\QCKJ>E,CNVO#?ECNLK;/]J0SI7U-&7@9:[8 -M0>_#ZG48AW,9'S4]T@@C[W'8CU>_49/6)AD_4^'[29UHURLK]FMIYRNUKT1M -M*GJJYO@JL:VCIUUBWZ.Z*@08H1*+)+$)6)<6"FJK-)PW&APJ9LJ*/D_W\U]C -MPO5_T\P];#%P5'L%!7!WJTP(S$R4>4R;#MTC/0PVR?*WLE#(GO=(YRD)U^>^ -MA_=C<4/RV/DMPX<*P]LL5#!#>56R;T"'+AX:$J\===_4/QPHMLM!YFOJ$87B -MT.CKPLDKJO:.ID]%?/R0B6G7=:)6V3P-CUK?L;ESBUWZ&B`*?U]:0/YE;"/_4P6#?0.(#H##B?DF_5GOS\ -M@B:\`E'?#`;Q.NZ8J_,(&;6$^`OY???"'PCQA,VPJ]1F[]%W16C0_ -MO";N360K[J=O,\K]EC-?:2O9K:=@NV+>B8E)S138$9=Z_I#ZGGUA.(5A[1T3 -MRZQSG0)/[&EMA(*0MF0TNI9%@O_%]XY0:"G1&7J#+E?\FFW_Z,]P:\C`59$9-PC/U -M68?NL1\JTP_ON.<`+F]90.,U3X^$%Z[M&(VJ]-]1+3DJ2H(%GUBZQ@<.LY]Z -M-%R<_B8-1LM[WH,8%&QV?F2?/$=J8?[_Z`8?S(78\CS=X#JKF^ -M22T7A0:Y,Z:[]"`GWJTNZ0\Z9>;%5LCP@)*75)=9W:W6DH'2,Z7A^BWXS_\H5GWS-4/H/HNM#[&+JB4FNWD[3!SY(/,F%"QS^B:)X_D-L -MDD?-\,6)_WL9!E<]2875K=4PUYU<;G]:60,?.%AK?&]F.3Y1(=HO+G7S1,3` -MT97`O18!"QVW@!VLNCC7^7\/-9.[QHD\!26?5WV:.??H*.MT7`@/? -M1C4MBZUT4I;JP"L"&!O$-LC<2+AL.9PKZ3>E:>\:T$6HJ7,/^4-75FX[*14+ -MR.Q@87LTF0.;KZZ-AJYK$B+?-&9;-%=3"D!Q@Z9_"<6D=1)%D8/J("A,W"C- -MNSQJ4\S2)="OZOEFB=\5\KS4R.RM@)#E@&AIA-W%-5Y\:)LM3-5,_#3%[EY7 -M(1];N'7*'.1FD,EK>UE30R29O -MQPV`BQTR+1XP5)HSHK80=#-NJ%S#5=69OZ(MU"?T-U8N-6J(6"N,:GRU,V%>K)H*YBR,6=Q723OU>S1!6%,;V2-E=]9K$HGI5?J*%/$H+N -M#7>QZK8B"KB"7[VMHBN@+0,M<1H!?PVQ53GX4&TY7T?N2>*!:^C:M%GQ@0,L\;.0@UO-*@/I/E$Q9`!&B@1/O?1 -M[5K+RI,$QBAU^2HVI.HBK0#O#Z5V3Z&-:L\^_TVO[6W6RM-?0W6':.A\6R*^ -M(OGN)1@]5)GX^BC$$ORC)#OL*\5._Z!*4Q0X!VOEA[1&*,JKY&^DA%[B*%E] -MN4?,4;DE5Q*PZO3?Q.RU8U4A\$&909,U2^A2XRORO<'H$-D'E3R#/CV5=/#M -MA5_,9N+"2"X'8YU9L4W9V",>./EK26H5/8K[VL@W\-1M[3D=D6SCT*?_=N,. -M/CII-@@"=-YZ9&N6CKN!%W(C+K!4ET*W1&G:F&"$*$1B_],-UQ70OM'E`>=/ -M*\,!!T!ENFS.YZ[49%/3UKM40KZA.*PXK9(A"^!1OSB(BNXA'OE.*9,P@V[* -M8A)U#!/&GW`-;M(AKS';U0RM;,&O,H#8 -M&'%KX[?L"VG/#$:*-Y'-]B9(;!'(U">&?,O81RR7'NKXZ^_KX0N(SR^T9IX? -M97_7'?]BIOT-#7G%_$P5LN)#">:Z0=:$3X=S2B/AH?0&\)L$3=01\1'=$SQ9-J,Y* -M,W5#`H?AZU9UOSR1*3JZUSRI.4/0@':$,O;HI -M=R+3?TJC,!%@FEI!X$C0`H$0I@O9=-M=T,(R6<[K[2>+77D#U@H373M;1F!E -M*DC4YTF2ND5&IY2A'&XMI-OPZLCW$H(5LW?A,"5 -ME-)*HP0SIO4\A/(;4Y:H5L-9A#%3::')THQ(AS653R+[GL(ZP0;A:Q7[=B7K -M=2V1<5ME""WX,)MWV=O=%`%[I5'+_TM;Z9X[UV)ATA,I[KOJ39NS/NK4G1A! -M:HNI>DDK?*K-A!#5":O9C_EP=RF0:S"E&/L*#]/.(!>KJ$G^2Y-6O/U)NM[L -MJ/NF%79J4?2?8MO-712-@(I`__38WRN.;]=AY!O\O+\@W+:&@ODS0]W-6!K2 -MGR3P]QWD(X5Y2-@NF;"I_FCP*M>")5;U6F3)8)*?I-*0T5:+([94]]_Y+RNZ -MG!PY)>36-4-FR0LDJ35^EU=6Q8<=W6\C"H5U:[PRBR^Y7)MG^)M%;0ZQ^8.O(+W,(&KH%7W<(%QXBUVGZ.,]>EYG$Z\"@AT?]DH -M4C2\.L1:/WZ/=-@^Q/-\T$0.ONEMB:.FS,NO[95MV!ELL!^V6;?:??#601;3 -M!2Z<,YG\SZ)4V_V&3SI1V?I,\&8X9FL,;0SOAC\3Y=LVPT@/V')1?2:TM2:R -M.D6D=`Z/.\0@!@+I,D?:FO9,`][`S5SKO"XT+O.24EX9IJA9G\VI+AP#/9OH -M)[CFPY(:#*198M2C:_(.F%F9Z7W2(R4`7E\8!@[U[)%_WS]8)]J:[OU1^HR, -M#V8WE3&-SD7.BVD-QO8,S&5-.7=](/N,%TPU%!8P[;;5G.6;?X[T5=$*[8PZ -MN/9L4-G"SN/N6.'V3BU69[KFW4N':=MA2_5_&^+)T$DLM0 -M9/%X[-_;/NP?;X9WPQ^Y\T==HCO2%3H">J -M&B<;6P5FPDOJ5FH4X""?;)PDRXK(9BN&*?T=30NIA7[,GO0#*=RG8(5L5%AA -MZU75=D6K.*Z[(@=P>%D#.5[F;+:R_T5.A[Z(W?R9:I([[M[WO3YM`8E:*9N: -ME&]!QFY4J0HT-,FAK_K.>YVHL2QFJ;6W]+1-)U2,EANGTL_C.ZA&_"G%"S\E -MF#)TG+)<9J*FTZRIME2O3Z(>>ESZGK&'<_:;JH3<^JR7%F4=5TGV^(XM5 -M,.O]"5$VNR1@;]`QJ(?;C0K02]8E"!B*D%#RE/#_*(.\8><8MZ*\ZI`_OUMQ -MVV'*R[96/WRV_1E"62,GF$8%*'!BV2Q^_JMCI"O9>D"JN'5/Z8E6JMB6> -MO^DIE$O/L(^\9QCD=88^DSFXX@V-%WR>]15$[U20&CZV+/0XSSO1IW()#UZ, -MF.YFR;*OH7S^AIFTW=$D;3)!L5-1/G641#\MNI"[0LIBD>S%KH4=Q;_.?L&+ -MU"PO+X'/PGC9G=-Z['%-F1SAF_9$<$WG[HW[/8B\F]8`UF^!1-V;WZKHTN$A -MDE4+G-D'-4#A-DD;HOW<[F_;=:0QAW -M/LL%T4%VA9R9G845*>?.<.^.F:O -M9^9'WWE+[;C%GY@'^2.QW+85^N/9]#6..!PKO:]>"H4&TP]3/X9OT86:/QMY -MD%?27&K5K=7GIAXH&2ME6N<\OA%I0BZ=,.7!]K?3F(\ONQ.(%9O3]*0N# -M)X9DD$[O+#4!TT>C),4G$]D3 -M&KW,(+@/';I1D:#7C"]ZT_[VE"F;8`:J`Y[$]VQ%&A]5&N_JK<#BJ@`**'BUVO@)C0:.A5U7#.WB^41% -M8+^21*A"\LZ%,Y@&7KR2E@P&,-1*1=MC:=Z6C(=X!/;9#)-3W,L4*Q"R&RR? -MTF$)?X]I#7UHAH05AV"NBW#F7VXE,61?8=OH";P]]#/J],49<:Y>B:E -MD,42UIQ^*PADL7.APLY7>>PX]JAR*K=:/#Q\]&M5(Q?^]W$:M@]5NKJGND^4 -M2D6+0K;"B/=]Z@MJ7*&&\N!KI%>IY!#K!2H$&M01("BR8,*>N"\$,D$T1^W2PCBC5!: -M392G;/+[J$QCA,J)^1FI<+!V\5^SYF2RHH2-'SFW3BAKWE]. -M]N]WP'MBYHF<6NBI*-=]:OR+\?+D#U-HYSZH3@UHV+5`YE@,Z+(V.\P4A;\M -MNC4(498;_;?5(;/M8'.U:9>L>>W=F&'B5!R&C5[)10,M&;A,,L1 -M4`G.96%X$D:G9!1:)P4A=8.SWM*8S^?));G"B\Y$0')?#BPASPCL:O5R3-[! -M5BZ*%)42W=\"^C.#$0$.!(?(*X<3-3H00$/Z90V[&N*>^0[:_>?!M?]N[H(D'^CFL/_]IB++UV7#3=/<35( -M2_=6,`,G*GRHV(M71;9S+LA*,-+:HXC//,4&9MS5&XN[V;O(W.>\'H%3<[W/G&Q$NTQB6B3#$1\!OS[,SCH,?_]8@8 -M@U$1Y^\`8&(:>"-]14EI](1&WG$[!H\LDJV.^+(X:SF(/[MK(?EUP-B%70(L -M$8=QN.IAFNK+FS%RS);W'%5'?+U3[A;>Z5U19;E3I*4=OWSD8S@=3!/"\(5\ -M[RN42SK3[UK@H4%J+".=?:GMD[Q'LC-9QN?.PGR]]UA28:RE/GHE!MB^+"UA -M\>-O"8J8.LCY[O4^N46$Y$-FB,0!R7V(-.6980P28,KZMCC:5.09O+`0YOAI -MU*>,OIH;@MYV9#8$]GPD(MP?J?XB!3;+%NU[C%E'04*'YTA[%SAJ'?-[%A$K -M=RWKHUQ[J8\H>M,PZI%5TR1;DO2&&S,/MA&RA'DK'"\-$J3;QQI+D5Z?SCI7 -MLA3$5+'+"VR?QV:`,B3L=G=N!Z$E,/P1?4Q0L;J^VZ7M(T[$W[[YS)Y0#L]- -M\?<5Q*)OOE+=*?YUM&/XK\[@U>V9C#&2KP]F+3Q3J2;8," -MU)6U;Z -MIFNEW@,#;S""]4NDW9=U^JZ:]6==)60ZF/C$V**/L1Y9AU+\#A\PHI^6-,?= -M03*-KT'_0F23G9WQS8@(DK'/?G11>F)I=WFGPX_NO:P)0VF)-;[6EGVO;=TT -M)JL4IC23J;:4S:NY+]GGZE#;V^'!MO"-5^-WGHV#/&)4J][*T)O'F:RIKH[> -M(;$VTC@?*2DWV:,LWU+[RV_3,-9.BHV"20>K*&FPP)+I&LRQ5L;&-+7=O%CD1M' -MAM?8>&DN;OH7AK?\/#?;3/#>(U6`D,%ILQJM.<_:;%*?)GXAU+VV,BWA^)YG -M#NU1J6G0%#@>=IKT>9U5[%UHE%/JE\_ZGHG4P5)@>'I&A;^Z27[PB7&>F[L; -M8(V:B\WZG4>5^82^Q"AUWC$(7\FP.X7G3#ZG%K@%>GSB=+(]W?"<6TMG5B%< -MPK7YDH,F6QM&"MCO7= -M1)E63:5&H//$U#@^G8R]\YDE5TRF(,2D:(R3N"LM#!S*T$N.I[(W>H9PRG.+ -M![U_.,[F/M-KC-VK1SB;3[?>BO-X7!.._CJ1+S-(65YDN\2S6/UO)%<(C>WL -MP]!G&DG[ZWGF,/7]!H`L@58=XB6#+`\HD8_;7\@]R>^(\-GYQ1^H*.&H-Z2@ -M>(R.3MJ'@ -M*]/0#QQ'>:PEJ_0A#QC)5BKQH1&]I+,QF^LRSA\9?DNYDZ8+QY7VZ]*JWROC -MZ4?2;Y0'WAZ`TI9!VEI9\6,DHW8G-!K4E8%#[_HD6P[T[[RS4L3&'!J"-5MH -M1U7OLX^J7V9*8DGZRYFI,N[,U1EDC.&0VQ[]K;=43]C)#7/W"PVGC^^2;3EO -M%+;#OE3;H70;Z[)[B[DK%&>Z#CUKT1#)NK#H/,V]]8.EZV1N6%P.J_L:29O1 -M(WPCQ\T99_NFE(W^A])9QX9ZTK^PAIA`<6DLXML`KQM=',"%0V'RFE]-W"9] -MWGRFMYWR_[WP`3$P:],;V;;^IK8@WKB^3YM6W3I6WPQA/GL&25V%S#.(9(2M -M9[G!_E[.>$9:C+$&?54B%M[:*Q.T6,4.,P]S!'6'_J$G*7Z;B`X/CL$-Y(9P -M[?GF=`*2K=9L8#[K&[RT_MESSMH8@RV,:FE2A=X#0B=N,WU>GC=J8_90($A` -MVE@16Q?6G\P!RG%^'Z9RJ6`TI"^R'>J?7Q]*/I-\I-:(NAZT:KV;?5.N*TJ= -MOXQ3O`C]4@AK`%Y)=ZPV:M]?WTN^EC69B-5WU\1G+RB -M)/X-./D4_X9!'JG2EM@>'3V!\B=,DE@'*+ZR/0A9@\\P@`V:_JBR22#C-&[K -M+K;@:#:Z7!;NT`<63HAYE3[N:"@8HLGO"?IH61+^/XT -MF7RT-1Y2K-RVAF0E/]/E-RMGV"^0W'JS:U]>!>+__N-G.F&3[NGWBOM,^\]] -MS3;"V/G<:RK/DR?DII%JT]&FC0H!^`^CI]/7+LL#+C*+I]M*B?")!;1O*L76,OKOT+^# -M)9-WE<(=0]KY#/*C9E?Q98UMX78YSTV\Z=+/=Z;X^:AC[^,:??KYDM_O>$N+ -M[=D0B3"##,]8Y:]UD$TO?L(SH%3=94Y]5?AF_F=OTM\=W\9M=]HYQ$T.$,KBM*O[@I"[CJW! -M)ZF,_X:9%Q=,WNPYBV(]&;>6GKE-!J3NXH8KI30 -M%PQJN@W"Y?3%A$!**"6G[KJE59^$O_O2%.<5LS"[M+KD7I4D`.(!`*&C;JG0 -MS/E0WJ*9;^!S%@_VM\M9%C09G$0^*Y,>P:DPT&%AFZZKIW+U[1H?XN+[(2M -M^P]HE+-IK/M^!X/W/$ZK[??3W&UJ;DD1;?ML[$&'!6L`Z/P8T"@2CBXM3-V7 -M<0SZK9-H>UHG;3=R7UM.N+90WFFEX0 -MJ8<<&PSUV[J*MY,:Q.CZDYHCI9P]>3VR:+M^KJL*)D32;@AU:#C$Z&6K<7PO -M!UY)9\L3OEM)S[+=>4]4"@P^S1?_Y=8PT\%?6:NBW((1($#;XH_,F?;)+7 -MC5>6!$0.5J,&PTO8E.FZRG@'QU/B+6]\]HEQUYT@]V!J*2CH(B^/'I59SP.O -MQ3=A$H\>6A"['VI6CN8X!.?OP3Z2?*L94U&`4+6S$& -MM;?R3*+EOVJC=G2LG:QM_&N]\C\W*+B[:1WH_O.%.%DJ!^VW\QSG?Q>A`4GH -M8:&ZHP<1W6J$3W!O^?-46MD27('"=>^@7K3,'$8EH5O]>83J_*&P#(J:>_*Z -MKGBV$D1R;119VF*\4DN=<95X-O5'_8&HHI&CO()O:]YVB6'%IP_#C8J".=](V9_2_^2E;N=4G`A]USCA=G#^VCCD=4KT^WY1U)Y"( -M9.6+-=6J_+]H2`@0_VI'#B2%%N@3_T5$%/_,G;_'"J'\W]D`=!(U8WE,1WU# -M@\\HY@#5(4/NF*(:DGC3*TSX7"8DLN^R`]1`4&]S23]Q(5"E-)PU":Z3XZ-1 -M9-'ZDZA8,.F+'XWO@PGE-^;3(E92HZ$U\"?$5+WXF]\RF[3M040A+\K@`UL@ -MBZ#VW*1A#Z,TO7@<$BJGKX:L'\5UID9^6F3?Z/#^):VJXK]?`8.IG;]MUQ9A -M$Z95C:<2A/Y5/5@SI`JS`+>KOGUA13)Z6YSBU&%%O.N27.?V_";8+E_QSAP+ -MH7C'[-L99@Q_HY2-1LC)Q6ANU6[9;)1DH1]6HFL^T0HT=4;W6ICG9]JGPVL4 -MRO4Z>2/N@LOCI^F93WR0I9:)5QF#C23:D@)F@DC#D]:9?'+!:WLX9BF^0@[V -MXML[Y.>1BOC*2+W$TR>\T49!5#Z`..J0*BPD>*'C4)%@YSRRGU1;EOT:[Y5; -MJU!&QHK\ZZ*QTH1:;J#.PN+;!1KT=-=\B"<)/M-,HY&40OY%**QI.F5]192" -MR.HM\Y]+1QRPB_ENYZIT">_'^!E,1DAPXLW)/+^T>UK^;RH]0.U#`Y`"KRO4 -M?>(2JK9-Y4K:24*VG"*M@AD)LDD/?DC2`/Q)S6[\SMC*J]P>KM'2G.L\6=V' -M>62L=%LWC2/T5C/+7$=@=FFZ -M83MA4S^+@'H3`UM#?I,I\'2W:-K6GEYXZR:T/G)J&^[I]+HDW@>(WV@*1W[? -M8&XR-Q(Y;4B0]ND`@,V$.BG;.AKIS40T*[@0^V2$T+]8K%;RNR*E75Q/6 -M/VH-ET>(6C1.!G6NM"GD" -MZRM1,@NAU0=6"_'5!M8^ZE]E6=7'53:!DF;M80T50_15.B"H>Q>L,QD2]0=3 -MSQ(4_NH15"L.7?*+,"")J -M9:KO\9VGD$""5NG2!TLZC?LRU_R%$O?"<9[Y#I6)S()THT6V\-)&*KAD90(I -MSQZ^-T9!B(50DL`0ZBEF:[;-I6C+X[X>>,@C&(5EQ)61\G* -M)CXM-3XQSTEN^28R;2=;'^>F?J`5'H]RS23WG\%GCI!VB[EZ)DTG.6U4?V>8 -ML3>V,X]/DB.#73_,E3\X[--I`0CC*_*V`\B.E4F!I^ZF>>QM@'YC0%#X([([@F)EANC7 -MWIO)+CM;NIFC0L3\2:-5U>K\FHCHT"[$,EP_U:*Z*S,MH:V9HTN#D-UI%4R1 -M_,M1EY@5AUW"/"T,;PGDXS2O0S-?;FC-]A"I3G/`7LM,\U\"EC9JEV;2 -M2I5[NJ7D[S_?%P+>X9Z7AG^&%2??^7'BY&:+A2?Z`H\AS,(6)9MW@G4'=?-> -MBF2R_W[T>QM?3Y@FT'C//1LYR(*4'[IW,4%YUD!+"H]1-39>8^=!#4VJ+M=+ -M8H1*>@!CG]9JQ6/33L8,U^' -M^'XT]6T$+@P<<%8TUT$JWJ>D[7[?+::WVL9X_]?>\SW-Y"4QKIY[3RMB`:1` -ML4.K%].EJJ**ECY]HNK,WT/:.I8(=*YGQ^"SK?FZ#[E=4_@\Y-.6.9K>_>28 -MX03L`LH$Q2)`)J;$-+GO_%0`DR]RU%.N.A'6W&IGDEH6LH8%CF^B#)=@WXTX -M_`-DQG*QAF:R0`E*-6$P]<3*M!_/L>\G+?%-`L;84N?/ZH$6J`>=H3A?GXV(MGEZT^`1 -M@AE:U3!WO##D/U,2)_8,">/TU,7Y]X0,?2S]TB -M&YS^!`72FB@;\?[AWJ=+&WIO@X -M-=`SC%E2Y'PO/SO58P;_.D`\.9W0[5JA%LK;2IZ"E`<>7TMC._C?A<1:0Z9CK`&(:+]-^@@/P[JM$+ -M"-5$]NCT5HS*H7FS8)3\^-,Y@WP(*R?T2YN'M&(>08EB2]7 -M4@5ST<8;1$4%QMMFS+38U$;?!-CO#S7!/[#/BR+_(_JMC%T28#GAC+%XTY64 -M1V`TW::0/T<<>3@/V3:H5\;MO3EE$[KD<)/("@DT5XVS&&CHS+;,C7NN*RV: -M/#(I.']^8XD^2*Y/\S9(Q=%8)L6);J,@YK*(Z<_X1EXH[<66N>@',V:2IN;B -MU\-MC[DDRG/:?Z!$C$O\WZ#QMN/Y'[C[/ZZEN\/]7JMJ*.N9]&6[WY^/Y]:4L1GG0G/VV@\N;B-,]LJ=S+8XN48O(, -M]P=RB_E*F'FUYX6(2^(`1QWBQ-A-K\[!$\I7IA_``;BP4`$J`K^Y9_+.-KMP -M48<5=TH5[4-Z=18_D*6K]F5@A]@SKU.XMLJWRU/08^2;]S`>A4]FWE!X2C:A -M,\2W9#I*0@=E"?CU3IA^6!;7!YV_7+:,!2<'GN@'MOW8MU@Z2T(E]+[#@)EU -M)/'*E1X!Z(]U'XB1W\TS#D\&UI:1DA]1Z[[U]2PWH5*==6ML@S=8]3JAPHZK"8;J0F"Z/\.-I371^I+NI -MAMMT=MSX\]]%@J<;'DL@ZXNBCS/[9K]0;)BC]A7$KSSYUVHVZB:R!Z^_8+C( -M,[!Y4HL'J2`E>E]Y`,<`D3^!@_^$<&')@Z"(('S!]"3]_&?Z,>FW[-&,V%;R -M?@;/&"QGA450;I>,95UC%O.+/FOB.$5R=FNWN;6$=?B`<<1*6R=[4-0(_FZD -MV.V(4]NKU>"DKQ@E#('(,F:_M\HEOA'(:(.[;8'9VOHC<,]#BBFUJTYLJI[! -M.$B47Z@@>G6'>Y;O*^')?-,,"9/ZLCBJ9IK]LD'Q;@PT]I'Y/BI+C>AJZQ>4 -M\06U/N&\V+!^W%#TS81)FRM%`C\&+]8Y.S>V`<+^QZW=.F'X/3Y3:3J;;QV\ -MJC*60F5\N?VZQQ6;]Q:Y)7IY4F";SAZ=-?,KYA*.VITZ_F#11N'O!)S%1)]@ -MJ.&R[*GD?=;++D\(!3D>.VE&>7[RU')QZY0G?:#H/X]4..AB)$T7?`WDWZ^` -M9Z./OP^EK]FUL"^ZPJRU@EQ_C$X'TT:M_N&#[>'+Z\EQ[QZ8TLZ4ZL?/O9RS -M#P_>8NI.],D1%09)"3$"Z$G\&ZF*W:%QV!FK961?9KK25*Y7A -MB=<=/C'%#C$S?ZR&SU:$_*RF".H1*^S,Y9752:<^#3L_9D/D(B(9*L09Q8#1 -M"1&#PJ]S00\_)&)DK-B30C$@"PK&%3:^*VIZ%N-8D3U4E4:HU*#97Q\+MK;^/31KR$ -MC30<_JAS.H2'U;&W%6>,24K^1SS9,&=K?OAR3#_J_O&6%,>B^DA+II3_T_B= -M^Y(V2A2CUC2TF7[DI#.`XT$5@?3.>KNW/8!N$H1U6MF4>%^RL]%'[0_;=X7$M^ZK"!>DA$0 -M:"N\F08C2;18$_-U(0)UYZVUS]GXH/)=\?B45G8:4]5\UPQ6C^+TB&ZSUD1! -M;-EQ$D?Y^7ZQH$KMBN*KWY?6--^W^0=]6INW.3UNJLV>6K[LIXP9E$A0R4R- -MF4T!;,_V,=RWNK@0B9AT;9)8-"_[\?^`J9ETIY1P>D/MYJU,V-M842U.DNFZ -M20EO]FY@,!?7:)<)ZH!E'S:K55-1T8M,Z[M.W^O6C^*Q77:5L7BP[&0WY)LA -MXQ(N*6RJZQ+2['LF;K)7XE0Q).:BM?,*M'*.QQ^*OSJ8^[8IT5]M>CK07<'1 -M#V#*?.[YG0^@XOES8[$1*V44AUE!KD9JYSTZ?D"D<+@_Y.Z"BA+D[$-GC!`4 -M_VFH9Q/2]C'=F75V)#7MR^6'S\%5XX.GQS8%>1H@=71E"I*!*?<*P?ZQ76V` -MNP9V=`=)Q`%:81=0W._I_-Y>,,&3.1AT<)ZIH$N,ZL[02/$A7@EY7=8.-%B!@.!V^M?-LD!C+XD9O#\T)$ -MO!X"$3]$^7-!^&YW8$5YV(-?Z3HV]&%0X*OKOU=4E](_:@F\@07T:'"4<"XN -M+:.-20D^!/QF0Z`^Y.#%K:N@+M325/I-H/H*'5@4,IB-85J8:@-HM-J*>/I= -M\?D'_(Q%>S,^K$,ZACZL@_QTVCA*1G9"><_N#5G::=TFNBH:QO.1[1X`AW2W8 -M0>F'&J7-D>4+Z'`/T^'5_5%F6(>@EQ_5.W;F\F-^2*,&@&)S>HE^&(PF/K]7 -M7WC$=YHD+LR"_Z40/IND1^.2%3482WX=AUYM*#KS?]^_7F_K_/UQM_O=<;'Y -M:\W&3MJXUV1M.VKS>'8]<:W6=<;\3N("18?09>^AVDVXMH;4N'>``BPHCF.( -M8_$)2GP&F(,X4]#,IFS0^=>D84`.^5UDBQGW>%#FM90PV)2&J.-+7\)F? -M[:I]TZB4&ERQ=[7\)]`T90\E?W5)B8W(K&#A;K3@1[6L9_%*F_'A^="W8))C4/L!W/6)._ -M[3?$'CNNL,]K&J':JF2&QHZ!.VZXH_4A6EJN&Z'\;7E2327JB_B2&*3F3`=@ -M717M="?BMR(K5N6_\V#I>G9Y-`%%_=:M1=S2,R*MR)KTO\>E -M.O.$5\4F?&^?I'O+T/!G,;MY@_XK;J2+E-(X"0P6$/0CU2&@%Q07PIU92)YB -ME"NJ:@@S!P]3Z1B,7&H.(=WK_AS8[?4K1]/121P80%A3[>I*DY\R -MWR7M>IW[HZF/2*LUOE.SK:T>.L^HC9B2O::W#NM7\X["?5DD<7J/5`ZM)]6A -M&H_0U3<"D0CY=('>>>IV6J*%'QP#P6?S#T\XP$=(^H"Q4U>`93H\)]'Z[L_( -MF%B?XWW`'`,R^M0GR_4Z)]P"J>;'8L%=G6\QWK;""^81[N*',E3#&@Z[`Z8?Q5UWEBW[L>"=]82?V.+E(&`V-U+]?[:<27R&L&/G$ -MFEB3Y.(DO7>R>\4S4$_=ZHI^/?3K.J2-_HY%I(##]ENKG_"6RYLX>N1MP9M -M*0GN4J9FHTAGXP-?W\$TB.QO/*&K5&OCO]=9ELS\U=>A!\M"Z]W.W'G%[[0Q -MMQ=A1GC*,I?)5G7:6@329'$OI#E-#:D+EO9@>ZH]R -M>&C3-UI(.H*;9^-_E/D_0;4&@?*_(ZJ].'XH-",.THR$\P%*+-'CX%YWR,OL -MT5"#.S'?P#1#D#N=R7G&3O7^?&U_MJ-TCP;B;,;%)F]6H[*+"2%=4T//$^<( -M7\=\09QU1S2"&14ZI>%:?,`?A\P;G-H?FD&K4:A3@R5`AE\_2>&NE_&L\;(4 -M;WPMUOR1X&&FR(NF%`FES/+D6:CE'_DEY#>HC&('X#?O-_=FU$BX84"/R -M]YNL.8G(+"X^K!!OOA[_RR(%]B*S.(1/FQIEN!J&V"/\")7E\DL/>VY4[F`Z -M(P-WU6,,6AKHI'0E%8+!>K8,=FJO#9O>W!;Z1><"-#F4EHQ'F6UJA](XE')4 -MJY&FB%8$9>*%:WG8[GF;_0TG.7=OC&$?X3")5U/=B$]L(C=ED]#E6^#A7Y[3 -M;H_&&&:3H@.<)GC:AZ5O]L7U"I&`G,T99)/"0VP,:;%K)1FHLWF%JTZ7;@84 -M@_--791P2]KS@)O[B7\#D)_Q&)SX@_14^?>0I?8\O\C/Z'V(O4:JRI3W[/// -M)'Z[6[_B.I;\BT^4K$?PH[P2UR;FQ_"-;C03H/L\%'NGS&5?$U(HZKB0)D## -M2@HX+53(PP0[=4Z\C:A0^<6N&5Z?K3SMH(M('W71D$UO0/WUA:4+H/&50JJS -M&EY'9A0_M\&PL&2I>.W6E^BI(G9Z9$2R,RB&$-`J93SV'-X;-DA77-WC5BY\ -MR:JP3@7OY\N_T3%SZ\N60'$7]W/F'71=;2@QWSAJ!34^V3W/;1[P0-RP?P=9 -M&KBT\,,(8>/>[A0[9O=BXKU0]N;X7&KI)MW.EY6&0 -M`ZY$-SD[2%DAKAZIXBE@`$OB*[9#85KM56\%4HL:NJ68Q5Q^ -M"A6SE=N7:BN@LIS-9AEUB?CM.$::5T*H+++J3ZT*-S0E@\579&-:\P?J=BK< -MFMXBE#;.."K<5H^Q$RD1FCG8:#BV5YYA#)SV+./[Q6)^X;D/1Y)N97!],E#P%<5IY0 -MW853,KZGE(VBR-[`[C[!,$YX\RS!N;1#MYN+W6VBI#8$M_2HMSP$[F*:@RF0 -MQ+7W.3;#C,EBEMTB_4%P(N+SVH:S76HD=@;)( -M\"]_T6&=&8V3:8!K>PE)=9>F%QY+QBS*1]R"(5*`T/>_ORMQJD1Z -MI&*''7;ABKQOT%$*,Z1BY&'Z%JAVRRC'9/0?QF%A'V-S=I,OK)C.;)A.;FB= -M2U_&".!]DKQU<5,=10P(]94C+3/6TFQ7U,..#?-WQ)S?6F8.G?J$1X_>F-S4&-AN>($PXJ:6 -M@*`%$)?2([M;7FK!+I23$UQX9H_+IZ -M3IO6*\QD.-9NWJS]V8'M;2:1E['&;CERA_YMZ1!A%P=1B0-0(>+4SQ7=BZ;0+W:P'[,IP@?0VKO"ZM&+(E)=$9>V,5?))7ESO\49%@8 -M1&T]KZ&T2+X1ERVGU1%Y&O/_.#+^P5^SMN/9#)=76)\S2JJS<@H/Z1)._QCX -MB4Z;X0^IRE*(T)&?;=TNW"$$0NTXVM8+JX)7_%?0D^P81QG15=D=)".:U./",M@+*U#C@*PJ%.*Q2]KH&\VI1/HS^EMA#-$RO3G.$Y' -M1P!,F&3GVM,D92R/:]5'\ET)V<[\CXI%2Q8;R%2YOT'%KSV-'5'F -MKCJJ0'O[!.-*L4;H[A^+`'<:>#7FE2!,UBA,FC_8=9[9,73#GG>5]JW2/PI4 -M?P,^!CG\=6;X25[WC:LW)(F6MQO9HDWQIHZ(DS)#MZA@HV;"@='(/_! -M``:1FC_Q!]1PBTS#=\&*OLA='",\I_X0LJWYE0S>%>KA?!W`KC%+MIG -M:$B\4G)-\%?_"TS6PMUICR#<\][M.P<6JS.!H'V8E-WQ!UG-\!K(0"Y3349L -MV1JM,E^LD9>Z;]TXKI)=[^[OB1(=P`SPKX*2 -M_2AYV=SWR-03IO"V-400X"TAE*OKY.5JBS2(:+!E=\+N5#*H#!/GDE(![,@X -MA$?4B1L@^+()'[H9#UOOKO?VQ75JOR,"2#X9?VEY!T@--\MJ(10#OX_E1^F; -MD;G4^P;KCKV]"1]T9/E"!5$??HW7M$?$<_>,?I"`?[80C@21B7]"N.;O>#^B -M2*])>]7D#A^,,[9DB1NZPHS`3T5%@G&T](U6Q0M4JN -M_GZYN263Q&RIW'("7[Y92\*%=TI\LRFKV4S?CL-+R)(67S?C'RL@MD'RKADM -M,G.3D`%I=$=+11BB#*-*R&+$Z9ZJU-S0KH -MV+_'F,]9#3$/8`?>GQ4*-O$>`- -M`H?D-';@'R0T6ZA@U[_?8F,][`FN[XC"<^%@Y=%;V-8E@G/Y$@4*2"B+1TA0 -MPXKPZ.-?WZ:ULLD2NTI2:\YEE;_`W(6OAO9*2:&`%:489J4+OW9!`3T9U`'3 -M\?G"`I#9H\T)3GOQ68JH'9.RI+C\U&[,=SFJ=F8#W:(Y^C:-?+F#9WK>]Z_& -M-^!7K?O-_7VYJ24(=/QO_C7LB]S75N=R,X%;)E/YW#A, -M)P.A3).43S?WWJ.8OZH11)1]`.*9`QN?Q@]V=V1/KM0@O,CD`3X3!+C^,L8 -MZ#ZN(`'A36'B!8$%N@H$#` -M(8)2J;$`(!5XQ4A3A@F!52,PS`<O@K'`KSJ6; -M;1\A\5!'<$+"_29=%GL@2W++)L/=DK*T)CP@C%(]9/8.<$K9K46;A;8#\DV: -MSZ:M$DRBWHF0G/W%L0G.=>4P.;DV+:2Z0%]LXF()PX5#+N;:THX#Z+3= -M%Y[F<A<)J30DSK9G#'D=$3"Z!UL41[`NZ6GE$8^V$YTSO]OISK]N -M;@RV'BVEBBB;,"::@J-S+&!5X=>JBO#7.8UU5!TX1BX(?UG%(KXPNGXJMQCX -MZWP='CZ[1_R\H1V$@IE^SC]:0U\PEMR-`*O'!_MA*Q(\?]Q+@$=(#F'5PBL" -M"=U/H0EAB/+4Z,#^[3T82>BTD:V$;4%*X/40E^82W_K"/-U1+^1&W]4EW00D -M,_"/)$!N?75N#JY7=?VB+@:<=DW32H0SA72DL6A6:M&N&O#G[J=$OZ;"F@]6 -M>!S>$AU1,U6)VVPNW'9I!E`;&3L35&+E4Q3,=QL%'3MMB;/] -M]&73X2'QWQEG<0B2>R@+C"-OAN]H7,P+X(;#RPYQE"K>W>GWAUO6S/"2$3M^ -M/&`(4??#/X)61%D4NG"/'-!4_,Z]FO,01_"JG=0S40M/QM>_$%G+I$@LRB_2 -MAZ1VQGN#[,-SPN;D=">(MA@L-#B@X54'O)<4/=__2`QY"=JKUC>OR -MHP?9.HN?8\WX,-S45/W1T)I7`!-8?H.^\PK3C^'5@+TBX_867^A8TI='1`]Z -M$`(;NQKWFC;HT2$>9\T[T_AXH^,%4;SO/JIT"64']D10K$ -M#WT`=.\8:HF*.[VCBGD6`'U:U?GSJNSFXM3)1,[8A'%"^I-M[!DRP<90HC15 -MC$5$6`%IU6$E7_I^#;^VJ47<\Z3[;[GCYXS+Z)JQ;B(1D<1U?(Y^D>)+%2?>X4\"1TE!OJJ"YO8@GV$0+\;L_ -M!3T++YLR#[M>%**VGMY)7/:=&)GZ?#P,9$=APYSW`9<1AB>(UGO<-\K55+?/ -M?,:V'C00RU=S]EWEHF.;6=[A[58=E:U)@TU@^KDHZ$=E/++:\D>O,1_8_`'^ -M3#2D&:<>T-@3)_AP=29]FU>=9ZGE16:5/;Q+[3?V)F)^?2WU:M<P)9KEJZR;K=O<,=G -MI4%XC@AHJ,(_8O0!'0(,&>/H11_%/[X@5F+2@J?"->B\.T@R+Q$:Z,>]1(ZYQ+(AZ1%EIKBHA#U+?[E[NF&6K6"2V.59"&:R*=G[ -M/S[\+2#H.B62ATOVNGW_IZ;):K]>I[QMO[)O/>\VL8#=;R%[`F6V5KJ;=13+ -M6UFIQX?=RRCOE0A]#.W8``KTRI<+5%RDLI=E)=1>I=U+PI,*3*EY4O2C!`C* -MUB@2H52#"JQL&0(M`ALK6F)M;8(<4K@Y1'6!SMQ'WTA&6;0E>8]V&@KH0V3V -M8^2K:Y:MW@$89-__WY?M76Z$D,84N+Y=!&,@3"/PQ%;11;KK2MH4A:A[EBTF -M`F%/;@7G%-\[9A0"0>AIUYXN0:H[/OE*OUEZN"><_\B%_,G+>1BI.L@?ED-T -M_'G&*$V84V?5G$+WU/W3RY+I4]Z=9+3!I\TTUUHF_B_;<8ODQP[L*A>/UH^7 -MZ=6UNI'W$*6H8(T+\2]5&HQ&&SL03GKQ2'D=0CJ1T]3#23YYLEQ2 -MIA&">\)U6\()6:RG]2!?AW<.`;IQ(%W'^\6`MI%OM4C(6U/6BV2V$:+6N<&V -M3O0Q(V=XIC#"P7VSJ[+@Z*]%!6)5ZU%DY;U@!K5'U10-?FL`/AHOPH-7B.Z% -MS,I!@-ZLE8=[C,[M*(".EM4(3;1A1V+2-J=DPD:,WVMC"5C#U&\:\6YUA5[L -M:X2UIBZ^("RSU\Y!\K"IW`=#D(PJMD.D#>]6<_(B@7LCT`1B=:3/X#IHS5W17K^I*FP*^%WVTJY1$&KNO-T@U*.\-$G!>R!2 -MWYGVZ5/JPH03^Q`:N_-G!J>CM?B3W:`3LY0GQ"1YU(-'G=01/K.!)SRX8@B] -MQN\Z;]]8&'WA]2B$@;^0<-RH?=0DA=\_&6%5]__15D@5FU1A&%$"XTD/+*JK -M&R%JZP:ZSL/`'QE2K%P2H0!B#KSY0I\LN6G*DNT/[8=Y+:/V%AVPE8JND@R1 -M-ZX<6L)O,1!.YH41?G^)C0/;-Z86K6<.^_\#J;Z@%,ZJ]@ZF^C[V -M9U@^RYR8@?H('4LM=F>@-ND^>US5:%<>N6#TYLW%G$C:R(5H1,6CR)T@.,C* -M_B_:]*>V#06X]!/Z>U2VHNQ/8;7=+=M"J'VT2=KOS!2\.?[Q=L5!D)H=5M7$ -MP@L^QW5JG/!&#MQ1CP6W6^]0;2`NX^G[R9R=-LA,*@1.N.5D7=8*8KGH`7LP -MJ?F.+[>2)A1C@L%<`;C@V@[9]`SV6W8>!\HR*7"^VP7"29<,%W#N!,=*\POI -MR:'%(P:/HT7N`HV,T(=I^DAQ7*Y=WIJT/9ZQC1YZ\@SZ"P%NT%-7,_"K$@6: -M,DL3:_$MW9H`*]6=&!,#*(F9M8@DK0_P-#9>7T_L_(FOC1\/ZG+M*N^RJ/QI -M*K#SBO8#-?A[$R!XWN5.1AR'?[T&$!1FOJ>O.8)G#S&R)@7:[P34=\8C5Q*6 -M44E8>*;\BT=L:"L?M+0/(89!D]]C?1NMO`^YXA`%@@RL[ZR)T$EX4#;%T^EH -MJO4AFJ];K*5.E`C*1-SA[4]\+.SVD=/4047/T+R>6V<..T;J=QD3+EFDZTZT -M^>X\"+V(4L6%58U3'50FREZG[@<38TOU9D<4KB#KAJ%Z=06O'AT:CN^SB3KA -M,*?G@JSDD+>)YBEX2"O3Q"RU?(XUVLE8?US%.NDKJK1)E6U@-)[<<9"X6W%( -MT"BP&356CWU:Q"A>R`X,-NCM@-`8@!8 -MWERD8AQA5Q-K\8H#SP)N@[+!<(Y'+>!%696;#P.V.K(V4]8,M$B<;-7J2N;8 -MSMX("LH<]4T58UEB7UM*MV23+7,'7H([K%5%?64KQLL2JS&P:XB^5_]W6'A1 -M<+DUEO:?&2?>2GMB$;U6`:>G'NTL7;)Z,9K\W#W-Y2QC:1E\\2H7Y=)/;;)Z -M.Z(?@=.!,2('GD`+;_2OW0_TZ^E)-XM@0<97--DGG6\33^9^SCF_W-CNK5K$ -M>[;[C/+3AX1*'KQ3B$?L&3#AA-F]N(=<3DFT"^ -MTM?[A#EXMW@U&"UJ>G;LJ^G[I.^SC^L"8AOJT5`2&(T7%XD8&P@9`595\\4G -M16V%1L3)?`\E_+B1Y.E*][+HO+A`A1G)=1,7K^.3/6:;W/UZ*T">WCO\84T^ -M$>+M@@Z!/;N-`/D(S[CJ.]P8]/7AQ*?:) -M#&T\^?K.J;@AI[/#.F@Q(U5:Q5G`&U/JD)ZK,3,H:F@W_NNT=451;G>C5;S, -MZ;BG4*.LH'8++'YD?%=0PV1MYX#TP`&=YN0^UA"&\^/?#W5>*9P@R3/WT,!& -M12W!%C64#VOCF&CBNT.`V!QW@:MT:]],[@]<^[-E,=_"QQ9TJ_!Q":;@I2($D\N35;VZ5[<,@"G#%6)>&7+ -M3KOIER!;_!7JKL/\'(^\$X4%Q]]KAF`;.O\6F.,$-LX-FL'&!5N^+CK=RQ15 -MD2ZXR?D=2%V1/W3\%!Q2ZC5S$R8/:E%6QDM"9'0PPIH=0B%$J$">_*9 -M.)_$0.\6%E[6M3;'F"ZPO-6L)XJ,DRK7-YU&C,E._?W'^P+V80:DW!6\YX.S -M.`+\>"*N4RCY"[!&7>D(1J%JUFW=6B9H9;A\?G&=7G,'R.KR*'*KQROX8O(B -M9]WF,+RF4IEP$%=6BGERF?3X!M^:VS?YK;A&F?:^$='Z<@M^O*,_!^85Q;F% -MCG^$I['J%6H6H\.RX/)_!_F9/"SWN7Q%Z>XI*#WU;G;Q+R^S25CP6V2K66`T -M%(P;UH_MJ+TDI$_>%Z3AMY3^1R67I*L*2G:[VN2.UQZ#@'%AD17A6UZ94.%= -MRS1(^H[P8EMUYYPD]-H>C@P4(GXU;JO>&S,W#GP06MAOQ,7'8PP[":!W^9JY -M6/]GSI:GV)(4.T5*@%=+9`X,J'M&`9C84I!:S9_ZSG", -M-F)QS^FU4[`_1%*\,S/7(G9F>0E2B]G(N?-D,/"FER(C9Y7O)WR/`C*5<6U- -M+#N\JQ95[!T-@R+=/]1SZ1-I!7_X6IX__.,&+Q?=_>P](;(YV2Q>`AF`-7DA -M;&W:6`ZP8O6/'4V*C\AL7IM'F/*&BL`T4:C7POQ"V\`F-/T%26/#,H,\<#_BF4\=-IY6+VFJ!_>,[8D&.M:K."]S -M,K.C):(-GCSD?+GJ`ZV'K"!;D'&;23VD'8&7XY1&AV6T`/OL$2$;<;_2?K&4JB'_@E(3F=$(@DPX8(U(ILP -M1$LN2?YO9<9>LMD^AZ!;=]Q2SA152BLV,0^Z=:M<)LTF6SIZ<2(TJG`)A-XE -M4/]!D86Q'?)[L&2FB=%.&G$URT6GIW:L30-,,SG*>[`P+:-VB:9I5_BF7?&% -M2,'<(=E+LAWG#,C.\=-X2L@2OGK+FP!U;:'DW7G)_<,_UT;):6E#VU]CS=@( -MI:O.J>=`>P(>,IVP-YY:7$9X;),7&+&F:\=FCF:M8GI.--JP=3CT`WE8"9"' -MZV@TO@HF%Q3%WI+M*%JD?/#9&<<_J,WAX[1/5*K3MZ7O-T_1.LH;)UMJ76.*-HUL7R3KX%@)1E1-OKA%DUB. -M1X"?M9ZBZF2VL"'G]6"G]0M5-NT=X\4D=HYYTEBL!$0)5VC2)494NB!R0IYZ -MYYFQ.+%'=^BJ=.WY+]9J+W+,PGK1:0&8);8:5[06#+8`S)BF;_*!*'$GE2N/ -MY$OG%9=$/PU9-BQ_QW:$J\Z).)\%63?\0*2.L)CHYSK9H2/1(RD>?Y!7AX^: -MI#DH&E6Q;$UC.+57B2MTR15HL[`E-PBD3]NVFM8E6B++:%&T*H0U5FP3K1): -M.VK)B+9@Y,E]K\KKX6#WX424F'SO+"27OEQ7X$GXY;$A;%GG>P7?>S4F3!R0 -ME"'4%8@]E)D?'+XUDF7RQR>R10DTAAL&D<`B.I^XT-$'U<8Q8I*QJMT!(;"- -M%YA.U.%PE$%KY21K-VZ^)3XF,QO!?"HOD;!2`GP)"?JW6$T'9&14`L`4`&)` -M5R0;=/5T9EC&4_PH]6E;8E.V);-361=!"8,+NC&1%^D`]L13F_7SQ('BIF55 -M!^X$22"(`$F`)QG;K+I>8D'C_:=68=A4^XA1Z[=%.N,67=D".PRD^(JA7MC+ -MEZ6E78%Z,572U?UHR[Y!/QD_1M+0=8RXL6T]!Q/"_,/]Y<99:$W$J5SMU_UT -MR[YA,2N;\Z2!FO'%(*[!F>XF9#,P3JG9%R@UYF8G:`R,,/;-"53[UF@@0(]5 -M4,HZI!B=H3URRZZ*OCEW@(?V8`ERABY4$F@->R""Y)-]N0E%:WP0!.*>'W:U -M`)R*?=12PKXIBQ2%6R):HF(NPO2B@BNQ-I8Q_NJQ<*6Y -MQE:*%3+_%.WN='0%VIZPS5>V%'84;#HT@;*Z=$']FEM14TV0GKLE*PZ&"M"V -M*;1X=_J?GY.<1^:1`+-R442=5Z:8E/E.0)84I:DJ$IQI+#DU5FY:QFJ[9$DUXTYV)Z+05`UX=6ZZ#N6B>*G`KL92\2B+PL7] -M]3(V2O@ZXZSB\,F:SAFLHQ6,FP=S#6$SQ)>[HYR8L7<,6T&40=M7M2'HG%XU/"1<7(,&28[F%,;;5!]O'^1+R_ -M\G-1)C694ZYA@;A%^\P1>5E&%5,HMFZL9WDL8JWC#OR\<7`;:$2TZZX/4L-! -MI0>&M1AF&A3(-9P/**'U'.JJF*+AUS4=]+R*A<8G*[-G>5H3;K'*XQ%8(J\F -MKM!V`WS8\&'G9!4,(.''X#JU7$L>=`.IXDF!V)=&2K=-Q+E/7 -M>BQCKDOG[<1V8Z#[)'_S,5#]G.J8?J03OPRZ,"PWT=PG_Y\O*22RK1W:K.\[(63$_8*W#Z%C],6#M%PD20#OW+#?_/?_TC^_ELS!?S^:+'97"R_\:V\P'V9+^+ZK+S%4,D`>;^EK[\ -MQ_Y\?\X7=O.<+_NPT6H'KY:QQ?$ZU[9+@M3J9KIM94S1R"6#2M:#6(L,0Z1BAO19 -M,2ACX2)1R);]]S8M2U1ZJ!(2CC>*5MQ$;F.:+VEI8XFU?.K -M*7-(.BWM1?`N9O,FSRVLNV:O*$0R)/>/\7<$0_`E+`L[*:+VF!*U./,$-ZT0 -MNB`HW<__4;%WP#1V)[&FL+J>0C.&!E!M-1V&(`[N_?&1H'@CUQA0NFDA/-R2 -M1+II?_FE/L,DV022YZ=KD@0N@$V5CWR]I5Z7F^>[@YWC(N29;7ONHI(V0Q"W -M3/][\:+ND1V4C+;,-%BA)2XR91^*R/9;AHPZ_<836H$&&J^>?N2%^%"]5Z)< -M=GGXKU"GJUF=^0%$MR86:6>[!N\=>USTI:&U.`8Q$0FC,(FKQ7$7ZW7!7D7> -MIVCB^JYAGQF$,Y%U%;!<[VDJPU$S'+5?C8Z4WK)BUH1RJQ_Y>ZMS16"NBE=L -MK^7B'.ECI(Y98"W@188,;4[>A#ZB@NK.^,-"U_O!@P)9#YD@ET"G9W#XF^W! -MZ?+Q9`,L*K>#.^,R`V^2J51796L'WUK5;7`@R5S'F23FYC`,A1E8L-%]M%%X -MR\`.:1;L:0,U`U-PKB>?*9;OL;<*-^8OQ>U+$U8N:*GZ.$EM=T%C3@>-`&." -MA=&)X6V2UDAM0JO5?\I(:X@?JY.D(VP$^9,FI!WGDG*>!,R1WJD6>^EZYTBZ -MK6Y[J(V7MQ)O;@5_>`TFTDG70UW#*P:,.NVZ3+8A7R;T\==647[914TR;7*O -M3&:WRMBO"KY;K;`%L_QW)XU'R`5I7FZTDAO71/.B[BS+LG3S;UI5M:V6[3CV -MN?8,>_2.W)W1?%\WL>[FQ2T7)!R[S -MV9!G]FT-6-M,,%97W]Z5)[B+X;_'F9RBNI^TB,/),8C;*O3'6!I&.B$@J7Z) -M/2IHGH6V35;8(5HLL8^I*I5!=C4*I0Y,1PNI5R.-SB%2^GP5:4,7].CA1.$- -M&5?WV(;IS$:'O%\HX[2.DLN!:#-1879$&(%SNI3IYMI/"Z30N;88[7=H43:> -MR/$P^\?^!NY14Z@"UNR.5*H$*T7^ADF*FL+AQM/^R8;U">6*?E6[X7.T**4Q -M_AU!OO?]6UR0O*K"U.>EX->_YK=\8`#9Q/8STSH,_$L`PS80*'L-%1@13K[G -MW[KYI`<*U#_97"N&Z3Z='_O9>]=4@V'A?QW9FYZ]J\F3OL>4HHY_/PT[.7DR -M,UD\NO?6'(MAH?WF^=-21QM`<@4$[Y<7(.BA[&@9CTCO-6(?_F55T&Y#PRC1 -MY^/BP%P@K*!$4%>$P>980,?VN[1;P8%X/TG*ZD>8?LUNT-_G=W#@YSLC(K4L -MC%B!;42V%(;!B^5!7L@M)+581!G6IFC+G!3;A/2NC+0:Y6L,NLRT3,MK;)O( -M+&'OVC-TD%QH6J*`B[>+EKT^"@MV26IT153(QQ_)+:CW#6S3_L%O>F79C^W`^?+V#@Z00^U+-_\&\Y4M-AH?V?(8,W(M=!! -M9XL"/*#BM`=:+GD7^DWR0(RY`,[04]M&?T4UHKT>F!E3S1IH.(C`.F -MAK*P9#@06'@_\<15N&\5JCS[9Q?(OK\9'^[(Z@AF/BBJ:-?6A_]_MW[P45T> -MSEB$>JN*:8N0]31E6X*&C*&N8B-VT`!L#L9V0!T;0D>2TB`YBC\P`E\=`70\ -M6YK'M'G6\-)Z_E:0>&*J];9*P=5L,'59PQ(N83#UJQ)*](*4F/R([D.L)NRF -M$X3JRF$S^C']*JVCB=BX3*B=;(5#[S%P0^>;T5O"R>N16D_%25?CH=G^1_P' -M04%D#H>OEPJ73=TDYFHI8T50,=_`%[O).P,W6QC8[J^'#..]!UL-(*C-=#!%&WQE00.3`>_?[>* -MZFZ&OB)VTFDU!:*TF9/>X%ZYV$BD=DW6GRITJ[&Y*O^2<_WEW^P3Y\4]6[E -M0?7MCZ:#\%I#_K09P"!5LU*1/;(0`D(!EK/ZH1L`J-!GVDV^,3"G8-68Z`FW -M2;/;D]&!:)MW30,S1SB'IL6'A!\N@$NP:)7Z9-6_US"&^[]37$I@=`UQ4";6/]-J>'/>X@3I] -M[7);-.I1?G>&Y$>/:O"][?Z/$8`_XYV94BV7Q?H;&1 -MC&_^OA%0&$@L&I_9*H)M;K[;``_U`@-V0A#MI$]?$7$.BR4N"*4?5-2C63AC -MT8')INM>3-,+LUHF'J5/C'$F3$,+=):.B3T2'$5)\!BE466\2O -M%A`8)O;6PPLYE+"5DXPPEA5W@5+%%!5@-L,7_;'.^()"-\EEJ%7!W\7'W!%" -M2>P1@1H0MA96%26UW:3KXF"3WXF(`B9RC28WMM/?(>1Y.Y;&(6RCG\B;6+^/ -M[?6LB&**0D#BHIOJR)Z55M(S`5MO2Q`HD5%8^!C%3V<5OTYF\#%2T;5[Q&-1 -MN=XTO#^!>XJVK'<)%S.$>QRFF$?8BKP<0J>[3Q5#R'YVC)^PJAH\K(LME1WM -M]E$*38?4$-Q@E5WXR"`4-NM*Z1=#$L?I++:;(\"OBCO$8G8.Z,$^6$@.FL<@ -MPT5<#E,J)N.``_,1+.">!90'QTU<.GC)H)0O1*X5\_VX'%@\KAO:7C!X`F%$ -MS0;1&$X$]E& -MA`29G:CI`@]1C5_#C?JT/`G@9\#]"YT2@ZN[K(*KK2,MWG?:0-V(<9/M:0_< -M3F=!(F`>OUYS!VX^7'6VX]:>BB(_)%CL0]`\(K>OC,,Z]`0H-L2WW5DK*0;` -M"@/N5$V!,HPOB8?Q0E($U;P0A]R;()TO+,!'TRXO*S+"J_ -MMN;>\39ZZ+R^_HM^R8PI"5.5\&6GNB\NA)2I7Z;ZF]+]Y*EY5,2J;*WCWI[H -ME=W_&\O1DKX17G\DC<;KVZ@L2+)?)CZ4+RD7??ERMERO/W7?_ZS_^D?]26R4 -M+^;"%LJ)0O&-AT?E`$..C,NJ@9`O^H_4+#>^P>O@P=1_L?3T!%!M+:X9&9+M -MPJTP@VFW!ZZ&&0)"U0M9@R862]J9\IQI*A5>%6487)8 -MXIQQ)J4Y@ED":,+VPV;D'I'HW?DM$?B,-S.RAVH[4=J1+)GAX2W;OGV@Z!I1I62A10DLLS4IRR -M[6NT;87'5JQ_,GQ+SB/0?DNLW2GF$8&`2T9"SY"7J$,OE):HAD$NW50B@"7Y -M_"$=5O"7MD>AO27K_.I2_0I\1'K;XE\HM9G:PCPN`2F@$.5X<)<$C"A;M>V. -M_<2_(^O7\95A'4W^UR1_"4_ -M.U'V87*%!6,+W=N/8@+B3$38_H1B(L;O$4W&6.$&<]%NU]O8? -MQF:?=Q>&$%IX"YJRV6=^9J\ZY>;4%$B/TK-8EP^0\-8:5"O1>K$!$21K=6D( -MH2.*3_R;4GU&;818D(M;G(JE3VW6O+[ZXVA\SVVI9[9-N,K@WH?1+IXTP%\P'KQ9UWYFT6OP8Y%;F[NV9<)@Z\X_0S^Y%&^H[X):>MBCV1NYY^$S7PQD)7DO<:SVL^B':6\=5S$9.'CK;K_D'^XU?,B7 -MS.)?BZWC_!L!^[2$:^'/?MO//T*Q#Y]6X>='CK">S*/XAWV=I/%VMH8LW9*R -MN+]LF[+:9ZHC"UT;JL[_"-Y[?!%1\#D58-=,[::]-IU/#`%+H]09*6E)Y)6P -M3!3(_V&+KII2;4/<`8>JZMQU_OJM:A$1;IZYJPI'H^B.YFU?,#1-%@V&DS"= -M8A:!_T.OK+C])'<]+/S;>TD,G*VOIC:DC^V8$8Z-Q7Q4/M-9[^9L* -M`4094U<1*/+ZPB#K@/"]/OV^HA(SP(8!3'M@C6]#NYZV^HE/?UC5,C3%_<-\E6N9AJBVA53=%R_=Y-2B'&;(^V3CK4)_6?]-)\UJN@("QU -M7(S^\2J,ZOQP=9E#P[UF/8TTX&6"`89S8_06D>:#H*`:TSK@S;#0O55-AS/J@5B>BT/EH%GLH.Y&G=Y -MS-:)73YLYD*B%$4"HSG:2CCF-2,8\)UMPD[K&?:++DX&_*#:!VE"YC!Z*0NN -M5G!_Y-2@N>@,7;C``;TI(B/E/4'CEBW&Z5[-K=N3!!%*BY/<=2&`G4=]/S$0 -M&Q'][:GO*<13+@0/R\8\J^$EHZ_NPCY(1C5)19*\<7<=A;EJIA]A4A5MRB*: -M:N_!+@0E]ZA/(-;_A`(MH9C,H.@WS7#4[%QE6X(#")$,L+9@]PA`5\FS@8(] -M*08=I+U=Y&S9BC->8:I_V$&_?A]4E%&H!MPR0UBC%*']-*3:DZI/J4*@K(.O -M`"]J=,4;@NXJ+56*H3VJL(:\ES11FZ%!COEFSN\?>,`W7?(R]$47A`8-6+:# -M9`W9MM46=NP%_WC$2WK83[$22$KKNHYOQP7?BQ,E1RCNT8]V(,&J?JVWE%1D -M'0/HX11J4:E&I1LY&02UU;M?V:\1RXNR#)U<>N?R-JH5WI0L#+4MH/^;. -MZ=DU]W>)3$C(TH%W@I;ZNEW.YB@\)U_67B>^.S;+>$ -MW'W=WCW+8R_24"VD3QBYLZKN79I"UK1.I_,,8%'X[0\$8H25\)O-#BN*I&9\ -M<)+X3J?`&`1E7P'9=X`^2/A1@$!W6HZQ\ST`;T'=JY'],3K^^@MI/TKS'CZ- -MBPN$G1F=8C8Z?-`3P"R2A:-WDMJ/QC5;ALGLSUHOPUX""*>6^@I*V=WS.[,D -ME[92S9;6(91/;IWN)3[PV7U/.=SP]IL*0">O;X:]B@L?KO2I!TC'H]L+\!S+ -MR.^)ZFF@B&N;PVW^X#6**^&3;C+'A$/N611\^C5-M]B@ST#6.00GC)^+O>6Z -M)98H(7=>,L[WV`_`KM^>/=8__KP0N5J^WWKCJU!^.6*_N/67'>Q(JT@_0B%@ -MT`^>6KK[7Y-!7]#($^=."'VV(?[G*`UXS5V#%S9YPY`(=Z^.JCA)&QSU&733 -MSG?$1UGEACGCUEOQT1F:CI,NU8N)ALC7Q25X0USX[;W^)F -MAU=O+E$V1^Q]3[,R5+B3WY5K.H^$.=.HSJ_,'!VL^\5PCXJ57)7&]F)664]>S4@8!H[P -M0!K.%&(D3P8A0,0,TRN6UN0-$RDM8MA@7BWVB?R6HEGG._$>I^3^E3LT;)8F -MK+[S%Q+/NU$PD1?WY,SMX06$_P*(VYXYWF9G+O?<][;3+\3Z"PY7O,3+/]VB -M9OGB%J"$<1"=A+(ZH3XD*83E;M"BA-B!>TIJAEL*;58@(!S/O3\\)Y-P;9GY%$]G<%5D1UYI#]%\LRB&`5^R#Q33./7>*QU6@>*,T%:%`Y7"\T? -M+`!Z5&J,=,,+R^S63/*H6IO*'7,DXH\NB*;]P;*-^."0<6X]UB$.2H81C91S -M@CN9.;J=:Y8HX*K#9SW?W\$4O!:L!UNZ/&I\>MI)B4<*42>.3'C[TD'BUPTO -M':?2I,[`%QI%XI*^M1Y@73[7T=,C7RW%4S[62)56)ZC(9BSQ6GV"%.-H$6MY&8RG -MKKK=F\\6R;W'W\#-OO._8GN_J@!*CS`N1Z+_*2J-"C3!EYGEB."MTR&6J"+- -MD=B[Y%[*+Z;$#*V2L]@%$*025(LE@MXD'&39Y6@<-9(E+/_A,EZCRAZW[HHJ -MONLRRLN-NJ2W]_^G%@NV0+DTUQ)2;8;J&#KQK>D6%,5&$%N<]M]N\LBY-XG] -M,@A0Y3?6R?_\?,6*-9;$XPN&\YD7VU[>40S;(;+M,D+^)W\FK(L[<+0NCIF(T!,C+F=;>1E8O##1GO^[.Q/T51A^?M$FZ,+`G#AHO -MRL"@K=60M0*'2![9U/M5X5O'IS7[G_Y\6.GI@:@SA -M/DJ2QZ)A0'""T('P.K0D^0.H'!9#&JEU7_SZ3KBK3WS5\RU=('U*(\$20T/XF)2YK23 -M]OC$FN?]DS2MRT0+[;GHF;L#_-`!G^D/[>VK[3]RJPD7LK?<(EM?G/:6`GGS,<6^6E\,$4.G8O>S/G0]CD!I%QQ?V[) -MV?@I[L;>@5C`([="3X`Z+$>=`]'Z-B+05C='3&E5UFY6C(J#"!J-MM -MM=RB_ZF\QBA2NEVSQF*K<^H;.[K->PT':FU^-EF[B\XIXNO;8-`(^HK3$S#[ -M%`%PH"A*R)/+4Q&4`6=$I7T:%-\.`=-KAH:HVAIGG5U$`9O#VS,,Y$VP=C;" -M;-+4'[E#_S,*9Q][&]51Z=TB!\9$PG,/N$YM%J%R-C>A_C_]ROD"NJYF.AKA -M)C;=:`*]B45E0@6``(_QL>R)67@=2-V4`$F+Z7GWVDZU&8?'@F#T&70! -M`?ZRY3M6\^QD&:"_!WH*P[@TJ"F?(H5&99IU*N_SO7OFB`66P_AF&(R0B$]L/#J#HMOK-^;)R+"I1G58"`+SW`: -M_A#.WUJN;@E$V1]TI`G)^3;*;19AB/Z:4"4;VCM#@(%*[SEIN^FX$TXL2RR@VC87!^M>L/3:,8-<:DL3Q3VL2=RC+;4_2C+/@$P_E5M=(53-\JUUX&S&) -M7A2$=:R"Y]]^>SS4\Y[[NBQ$QD=G3\ZV>4T$,3]/<4\F5D88*(C6-5NS?>3^ -MD3G=F%>OL3>H%A/F^D`ZJG\')W#4;&G7&JWDG7W$,RKL/$K+J&=[ -M1M`C&T"@;&%1YUO=CC(4O2#^%?3\-P$%9L8M*3OPIX1FY9EZ6/P=\WLK!QU\ -M6;@RPN[(^#4?J:,5(RQ)-UF.ZD7Q0-.E7:9]T0^Z%23,4CO2'![CI#@Z!ZR& -M.P,_[)Q4EVN/[2N-@N^ON+B(./T6#'F(NJ>F1TT4=RU7JE'6B=K2:*$13^<= -MAO'YUG!V6I\(C.D[13XZJA#IXI%3QH\8BK*/*;$O+[I7/G8.OI%&DM#3PH]* -M?T?/1#/S1-[;L="?^>Q#OL9?CT`#VPKNE_2TM%Y,,:6#%JI*_YTH[+K+ -MA__.&DYA>=%+[K8,1/\_'E[$'BZV+KV/G`F(3`4]_Q3R^W@^\?VR&<#U)$!% -M)A[DG7D#WXJ'FH0Y;X^"7;VLN7,.>V+E:*E\X/_0C -M0).??VN_)N.F+K+7@NF9+K_13%S!=/7*XQ7O)6?RMZY3U6Y'A7JZH,YE@4PRUW)>']!5R3MSC&X17^]CR -MDP,17:>$_WW+'?L;V6S]A:'_-\Q=#[QHG%_XY;X/D4[6^%MVA;N]OI;:TMW5 -M7XMOEENQ=_+;ZQ;NDYDMOB%N631;>Y+=N%*3FBYMU2IE?+_4M*OA:\V6[]I; -M^8YPMV;+?_$N4@K*V"04_^0=CI'__.`Y)[2?!L<"6A_T$WRI3'Z;H<[]SY:$ -MU$%V-^@NMWUA:']5@K318EI;3A:'I:>[Z$M&J+30=$6CS"T_>Z,M&N+2RG2T -M>:H9]X-P82BRGZ%LRVX5M72$C/WO?B7O?C7C!P$Q,:Q/>"LZG`V[TN/QA0B- -MGE]:)U[#U/R9?+DGKZ88><]9;RGFD[,/B;TYW,=2+=]/"RV2V36O8'/SUGB' -MF%0HB9Z*4(ZB8>A')G,F?GGK`=N3=Z`X)D`5@2CRYU&$`9@`7&#`&VP#?_T` -M#[A?.]OHR^`D\\#F`F>.Z3]**2#=Y:B+9[C5Y2^H^[G^\-SM@M_Z8A.EV0(+ -M]A.'S5V*_+C^A$;X6D3>M,%20#1"FKKO@O]KNW9!1LU?36TF<$U9=IW\,?11 -M`=)()G$HUMP)FDTH1=M4>5,<3-#5[N5S4)N5>)4)1K+ZWI7BYO'QK5`K5`@5 -M`RA\RLN4CXH]$2_GJU$O*VD>9A9DTG<2`M<(#?W8NWT-F%)813XZ;;!/0.#& -MW>">R>A+I=E6\,[;NS2=<*7BW+UW)R+:=$7: -M)J0&$SB1-=B4!]_WYIY6YQ]_+H2^7^,OF>./(P5IT$-O\/+".OJP$O#^^2R#@ONI:I%KI%P^LGK9A1#1KLS+(,K- -M+O!6CY:+"M!@.RQI$]JE@MK1/)GFTENQN<@]7T!=H-U=?&[$A@I._>MI!HXK-W5!_9DM=&LR]&,)L_3?PE35Y4E4*(2"] -MOSR`8]0^$\240DR8BKPJ\+&@TD0?WL1#4M>P\#T!?8H[:]_Y8Z(P47HQ%B/8 -M5(`&+HQNK4^`J06(NJ# -M?+2*MY-SBS<\Z7?6`Y.US[UA]0F:RHC:X3Y24RNT(@C2Z$7C1J$7O91/1.'; -M*]01U[M*R?BKJKQ-1YT8_*%`32Y[5Q;#33FB^#15:Z[B=%$_%RG5]_Z"K:#H -M"=KXR(].4B`!C^@`VCOL?*'B\4P&`'Y\QZFUI,8H=1+J@D'IXR%$.`;'7XK1 -MY^+@W,4_2?33*,/4T4YVXO]2W0%6#KW5ES$G)0%H2J4/NYP_N_IYA]82'$FV -MJ/T(/[<6:K*"!/L"S3Y3E`+S!?4_/@"]GHE49D`-K)]#KBB%OY6=G#_42!ME-IE,H7C'!-S`2PYHOH<:7T5E- -M%]#ER^BL^9+Z&I+Z)B7Q)*U7"=H%JVZL[M3RSJLXL"6/#VC5[92]*\T4YD6O:&Z9S8X*N8=]Q?_JU'6D0E_X:EJW]^_]J/GA?,P2FHOI?+Z\OZTG6LK`` -M5(GN[4\5=3WI%P(AY3[\;AVH9_"LAUMDK'=6IU;CYWBH[['2!^WI@ZBQR -MDH?HFJU-K\,1/]#!]%%.U>P;Q8$/YMGWOG8083PB_T/7O)E#+"\1%:?%#!X8 -M^L'/H^-85418_TE%<9+?NEN3,M,[Y]CBCZ0NV/CJ\G(D*8JSR'B`K4"`@UUS -M!/S>8+_<8\6A>TQ6EID6AN!00NAXQ),%3UU%:+7QJ*%6W/R`=&IZ9J!M$TD9 -M[DCQ7_V`;<7LOJ`I5N5"#:L2_1@%4R/D[?C*/_@E54NA4&`$,(,'^6`X/38O -M_W*).JWAF#2/@?Y`08/N4"+WY-/8QJWK_`[_<1:7Z>]P6 -M_1$:W>"&8)@"<.N?UI/?A5V"^H\US$3!8?3++ON.UN->JTR9>C]?H^"O=:@ZYXNZ"VDS@T*L&ZU!Q$A2>*: -MK8'CGW^TE/I+41,WVY@C+%Z-@6WJ247+EP(>-;*W62#,!D/0\:0#4@%HA_*D -MJ\+E'^@+C#@ER_1EB\3+%T_;=O_C@70E[4+MRQ1*O\?[Y>K)]#I2B%OXVAY+?3R!_\K#` -M,@!,"7T7H+B^AHR_7T'+,#THB%_P]M]<)%-^;(A*OJ9P8^7HCX8AC]0\>8R7 -M:C*W]2NT*WM%>D*W\"!\)U(\)ZYPO.[6/_]`[FEA7#QK2QGRT+BQW!:)8L-B -MT78L=,0?S*M-%Z++)%H8%E]PM#$LN>+1>RRXJXNO,21J^ZNM -MY]+XI67!VZDK?\E>@*WY2OA"MWI7PI6[5\, -M5MZM4^VI[Q79%:N*^'*WFE?K"MXA7^X5L\5_NE;\!79E:F*Z16PQ7OI!X/*H -M(*,=U"=YH3GK@]+\1`MBI;^?;KRQS)/UBQ-$_.+'-$_U%CFR>D+'.$ZHL8`P -M7<0;;)SY7Y\G@2OT!.]%?!$^)Q2M.$_D(,MF2Z= -M"3]TN?1$ZTN?1D_VESG2>F+GTA-T</U?QW -M5XL&3[59;N'36\^#6X.W3E;J2OU!6YLALZ]6K6JVDEVSM6!'/-U4 -M%S?TDU9B1R2IA;]B?*-JTX@Y#M.F2!#.8[J03PK)9=B?7/Z4+1YS!VJ/^\0CS%/64V2FY4^A26Z8ES)'2*-%,>I -MW*GXU/#4\M2M4W"GQ*473AYPAPH\4_6I["FW4WJEXZ@E@B,.IV*G=*:%3R%- -M0IM%-XI>)\E.$?<4QRF94_.I^]2O4]]3YC[^V)<41OTZE_46BBSSG&*!3$J8 -M]3NU'2GBJ>8I["FU4^-3A*,,(`3A#$2OP<(:J=NHK]7U=6UU_<-D]ZDFUOO( -MK-UP%S#0^>C092:/,TSR1V+7J.K3&[NLY@(0>9:[IE*.:#45@FE?9SS!]IH? -M)%B&U:_S^R?<.-N^6SR"?Z,<*2]/=T=4TG+C+FP<(*&)`#XA>.!+$%K#(-JF -M12IBCU]1II!"G*,-([JQ]79 -M(@V:I*")"RBBTL-*L=AY*EYU$D -MO*X:A'QN8+W)BD-#'(PDCHLNV#\959^UFMR'$\.PB&SZM,0?[YY58=M<(!FR -MQ*?YEST!6_05?O4UQ%U`>S+$WR<&U)6\JI[99618K"Z -M>"5OUE7KJ;8MTIVQ59%TT96\LJK%-N64W:8E,D7/\I6_855JGO0MS,L3=ITT -MI6\TJ]E3^,++(EAF73\Q#9Y4=ODE?5_<0>2F1]FLD05_-`,2E>SX8,$KJ^41 -M_K-.IY"G^ZGEJ>:IYZGI*:=3U5*Q3V5+!3VE-FI[:FW4_BI9* -M?V4?*?(IO%/[J6:G#4E,F7"XK+U)E1BI?5)I3`*3:DXI.J8-2?4PJE"IAU&: -MC11JHW4IE,:ICE,@ID2H5JBK0%L([>W\^4_#QI&H'G[I1!@G+CRIZXS0_TM. -M^HATK[('6LD]*XN%Z@_V3Y;3A>I,J2DM;/>%PO4F2IJ\9L5:4':DP@[1L=., -M)_GI9.$'@=QJTP_#)EJ;9'D_/OE,2OY$Q5@"U;&X<&*K=Y>3L(VO_,7?77!79OHTTC2A";.N!%7JC33TGC;+/J3R#M -MY=8JUPVSEN3'"`FF(T?`LLWE16$R`@W)^XV90+156SIUDHV6["#N1F3 -MC]IJ\Q*P6",9;PK`\,_P#Y*=;XZX"QQ>JCO4I2*'G07KA-I`7Y.OHV:Q9^]9 -M$$=9$0.()<\J:F<41FKOV4#E=E(A?()] -M&C9SMC&L'&348C&)0+_%SE8TMZ-\'F8"']+J#9@.-JM452,8EK!M%'H*Q__F -M'J`^7$@S-(LB]2)#(S(V?V84U2OF.(X-9;/$9^B&]3A^+O-O]E;/@X'&==T+ -M"XGYY<(@.3Y4XS+M:_TBODOJHPG@XL/;L^E^(/NA7.*N$G(I=V)]OQ493Z-T -M]C2AIRP\SM?;A^*5E_#O%;GO=:LK'-WOD>N&5BP8],[\9W3Y)&8=E.;SB0KX -M?5]*/]9/@/$65*3F)\>_:S($`IS,7';'57:/P_Q1%4 -MV9%LK']IE/44]M1:"7_NPCD\Q/TVR]]ZGZN5RWS_V_43^DVQWK*2@WT=2VRR -M-.F;1'P&DONX\=&6.MV)P,>C+'*LX<$F)@KRY@P84#D0XY++&!H[G]8S9K&^ -M&S:]Q>&G(6+A=A-;`E?065;5)NGL(G6J.*BS;/NHX/U.V#0'7\-!4_O@BLC- -M3^6,*.2..W+C-?!KK@`UNLN5$OX\!N -M\SR;/IB^VV_#6W_'GR>S%'&A!FN\FNUALUZ5X^83S3DEE="BIL\ZU_:Z$^,V -M4U"_:+%XZ+I7T2[A*U%K,9[N,QPMFIK`R$H-)M`:XM5BQIX19MX2B$X,M3R\ -M:,^/2U7=L-KS(,G4I[7#.TN?2>9;A*[GU:$'X8R7X^%Q_H?*=\45X^(W2&DO -MYGJ:A[-5'`69H?/8/^@6(L;L]L*-Y@^:26Z\>KFAFA;>TN97$&.,,PU6;%@Z]%& -MKP;?J5O6O,!558>A[Q\D.4K;]2PH`/LZF#%VCBS-[I'E'+-!>-5YBFUM)//> -M/5T5!]+#8@7B$[[@M0;$,D2BT*YO^HFY&W50W7X(.N2H- -MG`\P-DOU;01(^FIR-[MTAUK@YAO;X=2TH7DPTGK+"7C$"9=6"Q6%%MJ6-*RV -M3#P*Q"[P`V1G;$;:1,VD[NS9,5?G=+C+RG9/'V-;?\"'6I8GRI=((1G9/08: -M2C[T,$@EYKRA?['LCHE3])0>^"%77%7,-!Y,C/]FE>8N5]@\R\Y[@2,^_^MX -MHKCYSAX=JY[@=O8+"5;.+<.L<]F`HM7>'5DM>V4U,5I^./+\"^U_#1O."K:2 -MIK'$NDMKN.P)9*>KE`T\K-5&Y6U&M:I5<59#?$%J()-?,K+57CCU$L#9;_'Z -MY=UKR9YEJRV+#P,Y)S^6`HIILG77`2:-WFW8I=BCD,BI(PCX]%2V*>ZCK;98 -M3&<7;Q+>(SX^>7[]$;H]SRQ\NHX-*'"X/+KU>+Q_TVBUBW>9)B*V"'D]!K6B>'T')--WFVUWM7WEK&%3S@BY/?Q";\;ERTG7Q2[5;]$/]BV6_ -MWBJXA<$/+LI9L!,-UNS'>MM^J546%Q=I'32I^\VVL`2TBJ/NAG&&'"+*=`-M -MOZX[S+1Q+RCR\>UX>#$,I:A_><_N1P;"S#U[9+J2I^5Q=A,+JX"X3":L? -M?L;$VQY-/!%T0;L#<;X+;QYZU+/V1^[G_@/V8OMDM5;]Z;S%;!L!WWEM@JVE -MF(M)N-8TJP50>@T56`T1TL24J4S1):4S<2[Z=JQ+SC\L=`.OZ0'<%K#0:M!? -M0N#]Y?KP-R6HK4%\2/\6SQN)C67(,BP\#,R*#K$D=!75%.X2J/QK(#GKSUP''^ -M7B1P9JT7%1TO%QKCV4,OJ8!G9:\HEX,Z+S+^K73Y>]?2J<1M6'X9?-X07P=` -M&X%YWPELLU^=#;`<>6XU#?)R?'#P-]+3_P);5Z*=1RGG26T,P'!(_:8;//\E -MU&#G]X%.1[.6>'WC"J-GZL'J;PM.GO#*S4S)2NO`/5(EHG':LATK20=FEXE9 -M`B;O)$+*O*-<4UL]7.GRZQ?1^*.K-\/[Y410ZC6[RUHC,Q&S%J9E42T-;,FM -MA*M!T:NE9/Z-#J?`[,H$B@S1(9$E==`GV)5*EL\/GBU?7SK^+NKWU;(U:8X) -M3KBA4DE9JEJD+B#48WU;6..9?Z`>>&7?N>^)F/6LP]8YS!\$55:J -M36LMB=94NB#N%>4UZ";NA@P?NRCU_?W6Y6;^+IZ=BPU.Z7O?@O\QLT]6"'(_#R5G -M)^DWU_\T@)]T0-";L7J#SWK\/P[?0FNCEG^?*,"1ZGZQX3X",/KFDCIJ`Y%X -M,T,HY^TFU71W(/6'>LF;Z4)BK6@V@L7.+UE'32B&;ZWWWVQ)N\Q$TKG(9Y0E -M7`EKB+?END6!V*R_A1R.;VFDN@V"(DTYR.S4O=',S=[3<'9'>/7\?IV*G>HV -MTGTRNQ;!%K'])&]T<6N]'"ST,B4Q(]#84T3O5J4=E(U-:$"[=39ASL!9W -M9L\OOW.11X6B>SI9[6..HT;#TQR].=@L;+=:#*0,M36+E.M'"FV/Z/_5CNXL -M0!Z@'>XDC3$Q7@JH%-0['W37/-N(3&X9`_$II_-BHANE//<,;@+I4FV=E"// -M\(N+THCSHY(]!I&4;G!K(KH2LC);Y0D]F$&O&W)G##T-(L+!C%19,=NC@V`- -MN6'X2:85@7!CYU.W5WF3/+]^7"AB3O?)>>L;:J1PS!Y/1C@>^VKC!"O.50CS -MX6":D8"=.V&GR:13.N%JR<_$*=D..H)FZP=8$/IIKF)I?NNY@9FSTOG -M'1.GG'`ZKC1>9F?CX[[,_\XJ)'-"W-'PRT@['[,VC@*)V1]OTD,!MW]& -MC^/MCPOF/&8LI:H:-5=I:0T!^\@JZ=E)XQ@X49`(%R"&X&X.1:8T,M`%S!R' -M,A=QA$2#<3QA@`^=XFS/3;YW+VEA>ZSJOFC#/6/\2`C1![_-'TS"F=(^DOH\ -M]Y5B>O1Q#&YY'-\JS/C>-@[8P!PLCE/>EXZ@.1P)D]UR>S/`1,T-URJ`%&WR -M'@0PYY'IN?:D4ZKJOC>+3H1GV+^/:^M)*WH*QNRU8OE9/8(!;N)!5=KYG8PX>N=U25( -MYP'4%3C.\?8AAB'&[$2&VY_M[%CRM564J:X-\`P7/H'4;YN;'IX"*=PEN;"F -MI./JRVJ?`H1F!R=#J@?MOX+1(F$MY1C4G_F>0+7%X=<&[.>8?Y`\AQTHS3M9 -M7#\'^^U.7-&G'\?H<>K)QWU:DTH#H[ULG8\>UQS:X]_*@"890DJYOG7-G -M,](T^(:6_@^V*U.V=[?E`_8>I17@$_9-E+3YS=I\`')I-9WL^4,*H:%YB0:X2`RP879`N'"F>NQ*?WV(EU.E0\(6(8P@;K<#FE57WUOZMU+B -MI'4J+SDZ*!ZKR5KG\+K[<6SN$\6Q=<%AF^S:"FD%%]:FE29;-S1(Y`,^#!&Y -M!UK:`H8ST<2BX;8VR"T)#K*LS?/[ZM6NC/\#4(I$FU2ZE3 -M9]=]*AWCCS0^=/^0&+D]'R#KYL]V(K?FE[[]+PS&>)!V]=(6X`]$_4(K%?**PDD1CEZ/T7S5<'.:*ILKSI5/E>A* -MF97%SKK,U=C;4:E*O\]@KPAD)MET@F]D]857CCR.N_7L&&A#9-0&.8ELHKQ, -M,;%-\^8A`/9+NGB)^^L00.L\O#C3C$/22KFJ&0WF7U['4HYT',;.9'RV;C"C -M5D+(G!XYQR*#:/O^.H1I`7_5!%&R?=4C1Z]A4GIE,&'T!S#=+#D#0Q;>^Z.Y -M>^(>FA`?;%7Z2@_27DL3-(T&C[<:*9N)S.&HKY\'/<\%CE\8LC<5-PSBA?1; -ML)7]?-HAP<-7\B'QI"/C9\DT3LH2<]@.$#%UK&+9E_3,V*(G:LO/,P$;ZL\X3C"HV.:@4EN)\1`X[D3RYO*'.JE9]99B@QF\>=`;LD5@VIXJN\D(^,5!E6 -MYJ['1)==-I:AC -M(5L,V&)>PKV8E,1-(0ZTGF+B5WW`5KO&9E-7'G/#Y+0=^VY`JD&:=ZPJO71P -MFL<*.;ORLPT)L,'^M;;S9M7#+2H?/7(M_U"^Z`.Y\D?2#H>&[I?F\P/]8YO\ -M(W=7\?^_-OMGTX;?-%08%618-=.K?'AS9;F/LRL,VE)?''\\O?>3+4J1R%3ZF=N6Q=]KDKX-K/NAP"U%W -M3^'E]&3UL'FCFQ;JZ8Q1[-)/K+;C[+_1/ -M$ARWZC@Z21IF&;LU98J:AAYB-F[#6O=3\A$Z1;!STNL8-'HNM\:=HQD)5$-Z -MA&F-:(=;,*37",SX8_-6^ZNWB/'GZ#(DGYB'[;PRYP4;VDY,A7I1%)Y(O"*K -ML@'?1,2`?*V1Q(O&6HL/<2J.$%/VL&;TV,6Q]6GTP3X>G1*HTVE4M5N?VSE> -MC18='$F"9;$^4<[OR:(-:X:C7L-!_RB-'6F5<&)+3%/EJ39+0DW1Z>$04"80 -M*)`G8`I\IJVJD^8-%]TX!.#6(TUP:@`]_MT::GSZL*(_`FI]H.#EI5UCIW8Y -MV#TU\1.N<3TL-`1?8Y@DJ0_2LJ^,/\`->T`L0-_;/)G!M(IE"?NSWMOO>JP@ -M2H[4Z]^C2KFWD_5:V4+E5:>44JCI,:E!6CS%3K[(?XBFR.U`TWV*#AJ";YZ. -MD^-5S2>?)?I\I'%8Y_!RH*M"X5O/F.E>A<,;@,MH'+:0^06I?>DK-RM2VKZ) -M]L"VKTT^W6N9H3K(%4ZU1_B[,UJMY'L5:3]WH*RVO)H4347DJ,9:U')T>,,\ -MB6QP_O2*MEX)+@D6?A6V+HW\]57&R/7+63^:U`U*1?+ZBV4Q"O(*C05AR^=K -M3P,B%+N\IKQ;J7I4?KM4>?(O(MN(2^$(H*0E.E)R>5%*^OG]^,I`\T#_?2IN -M')\A8$D'_O#^;33[UND0;E=5Q%%U]):P^&M)6]X]9U6M5TW1 -M.7$*/!+@:BCA2T*J&7TI%K;&H^&&DJ9+3E'3JZC+(85\53P+AJ,I$A>FVGMJ -M@BU@0!CYO<9X7P;C,=2SVP"2^V88F.JRK6&@T!BHGJTS%F@S1];Q<8ZL<'T` -M_Q04SE%-6S_#S["%#UL3Q!'6DKN1D:C562#0G,MY(+O,5G$^P7TJW5OE_T!E -M/&.\X7A`M?WY8B2XAU)BBURQ;V2DCBIS2FK9SR)+^Q0`-=A]H].&HZYI4\P< -MCAL^8Z,2QB/V%/WR$,B&8P"9AB4:1W>JF0BOA[.?XCW:9.F7C"HYU!DD,KN8 -M5/J[>G?T*-3#P]FJ]]U/SG<2`C1YWN83W@N]D#A<*ZH(;939/D^^)-<-]JG. -M\\^LDPE.R8#V`A6IK$6\@0/C,XU$"CC0AR75(IL2\C`!%W0=%R$Y33J]=YZ(&V+9W]]B^[??*Z -M;!X!$UP656H59T*J!/]:SBW"IE\`YNHIG/2==`/?-H3^MZOHC5T6G/DY:XQD3Y*135A7.I -M]L01AE#(`'I9B)&(B!\RCK[BS,R[#T_7.PSCE -MI/&EXON,/$K*MTCE%5C)/EP-K/^HME0)TI81,_<]+E.3WZ4^JKRC&[@?#](V -M]_^_(Y1JZ5/F;EP!_B7:>*CWLN`YEVYK3O,Q**G)T6E/<.<1)-Z -MC!YDA7SGJ\:>K1JNL=:#?=L<-&N:F;XMPVQ'&D0^;(C[S?_T2-`<(AXB`8R. -M(BAH`DAF.:J*CA:E`P#.="`2)!H*N4&TNM5M:X"6@!`DC)UZ1!2-!Q\PN*^. -M%'`N,$60$2:,RJ8-H+<"'Z"!Q`);0(!)`1$3"#^3XG\?/OSVOBX*@``20A#H -M?/U_CC"0U2#)9.Y[O7,Z=Z>]=[_/:$$+J885WB4?Y@-%SQ.N\@8RR?]G]',$ -M'YOX+@6Q'Y#)NTKN3URR^G*6ISD(%/N4/5W29XI90LW\"IWI2_3033.)>$=P -M50[-)L<$-$9IM5E_U0NDKY&$])3"Z7&W;K`4,E#DG?3(_&YC4 -MDLA66`>RJKGIM0\"%EU(M_![!6+WLM5+!Y[;520"DB[NK>E!#PO#-%Y2]2R& -M7W`:"QR362)!V734-QJ(_,3-=S-()U]]-\(;OA;0^N!KB:[&O -M9H3B8#'G\<]\,,<1AH<=%O"FN]5GA;T1I^"?.H<0=42O!?=/]S7)+S2][(@".7R:)V?;K`5?/@9?BW1'V33F"PV^`J##M=\`CCVLILF6C<"$BLJP!]"F1EA.5!'4B/!=`^-]`\^L2$I=:6 -M->:#$MK*GO?+A8RZ8+>/$JN6WQ;1L'-M69),HKLH9?P"`I&2IVU7PDPI"PC. -M[DX?V=%@7][R9"&584_]7.*E+`TS00JXP(F)Y1O -M$($(TD5'$D>P5/%YP64+ZT/9@GA=I<2\4S8`J3CZI:[*Q?E.\[6^?"9/*`T+ -M;F,_\Q]5H2YTEHO%H[K+F[65AP0IGP$\%2?Z;%H*K@AE&H^B -ML]G^!W$`)E%^HX#GHUS4BOF/+5P/JWSVB<\>27X"(R@>D/B^1@A5?WR,`UB% -MRK;TA>WR-)2H=D/#.H`R[J?E$"5#U*?S_G+(;NQ[5@96YVX^YBSYH$0>+JKT -M>8GX(?SS?^VPAP2+<0B7M5*D-?3E69(A@JK+AWSZ^@9T\PBJ7),YA"R^B1=8 -M2B$DXYP+*X?PT">)C=5,>CQ=)Q^`DQUV),FX.;M'DQ&_/LI*G@DRR\#!WMMV -M+>WM@`Q0>TL1?P3Q=I]T+G2,?QPX)).Q_/3BS7::(6@2<6$W?8YT`X<@)>@I -M495R9I^$$%MG%T[BTN,N=_879;%^MWEDC`\-Z -MYQG+S3"V*"]6.S1CW'0]5Y=@ZRE<#DI\Y2E1^WS8V<)WN:'9 -M>).7X^,3RA);V.9"/TN#>9#L,(?RT\\RDL\$Q+SIQOXJO!_BVK-MA5?!_"HK -M1]PE<[C[5)T!KN:RGHDYZ^S*XP9@G@^30.$>&E%JXA@X\J]`B7.)-V37>H3@ -M<#!4ATZ=L1CS[UK"X:1Y+=5;0X6E*76:5S]/SPT;UV/ER\,16+1+.Z#3<(!) -M,*/$

    @OI@CS+=1F3;+[+&!IF/B"6G6U$@0-B1JE*#-$V=@7V9.`TJ+&*6( -M5CQG\`X)`\_/)2FG$V&Y#W.B3KENTP!G!+-Y^P)T.@OEXA<3I -M=A?,8!8'A_\8X9A8^_XPFNBS$B^8SBS&"^99%G#7S*S+OT5Q -M$8RUIR<:9,FH$!C/N/$TY.[V&+@SG)0L[:OP=X0Y+](J`6P)3]30@Z!W) -MV3@"1-/-*[V\FOE;>9D-+TX+Q%"A1-).4TE_`+D-+TNW^?S)XWV08PXN^"4G -M*26,^HHD-K5^.I/OZHM;?]AZJGLHHY"^GU#4".[,7U^.IC6BH\G^@BD(Y,N7 -MXP/(-F!R+S5S3XY,6]4\Y?FIL8/51N<+`C -M;@$4=KNGN.@ORA;@.2WR%"\_ZF;6^U4'@F?RFY0IOU.)"OM_-!DH?Y@%>;YQ;ELS-<>BWNT4&J8=^)0MJR!$,%1W364H1"Z&GK1V6 -M8I/B.C%0"%X6F"I)U/SA#)3F%?N"PU"4T'>0>X)L3RX0\`?^"Q$8@3\#JTT6 -MJ7*/(TA&*.E]+X>[D -MM,I#`6Y=;24^J16_DAZM,D0O4(LPU=`QAYCBD<4RH1\4AB$+/&RG-!W"6[1S -M`\Q&"6K(&A4.LS+^&M>'%-X,ETFQ1]49J$)I;+(JF>^4Y31Z%()])AHG"%X1 -M"JYBG5261"=2.SBT'06^9GB1V$9`@,0F>"PYGJE3/3Q3/E)H$J$_Q"3`^CD! -M-DL>H36D05(D=P5H)H$0-`4/C[5,#?,RZ+WI.MJ0@0_MX;%T21" -M#K*2PNIEU;Y87@C-HY!Z&5^E;@+2WU0(IJ]-./Q!Z.-*1[A4>\C_ -M(17,$DGO$(M@!C*3!2,F/@8\-453!:6)@M0UO04T>I3X)+R9I@$TH3/IT$[\ -MMP@4\AM8A:6@!%(+:'K6IZ]+"RI%'HD[@$%S#XPQG93(DQ^8-)&U1P11;F(_ -M&[N-4+YG?TNQZ68)H(*!4'$EZHX:.2ZM\N`*0S$K -M_`S001U6YX^B\"C7M$IVM'>!2^),[OB4/`D_6^T2;^FQPE*',]DA#'U.P6)Z -M]`20/;%052:26[Y;'[0`75S+7.REZ!.N:]5Q0--,D+HE2\W\4\GP,*AV8UB] -MT?J47$<%H.U+:X!-J6/!3O'^'ZI8BV0)"M`3BN0H@H!,202!+]U9HDA0#)1*E.;3\1286MJ8@-(2@R5H%-\O$4R;X -MG$'@0@M\Q-BE8DY:Y6P[5T7HEP^@I-],I-!7$$A&A/G<5LM08I%/XG^",2W. -MY\DCTI-2DT6ILM-0FC8F_D$\(M1XOM\VAQ/9(5-N12" -MJ&.T$09R2_[XM:]P`4\DW+ILKA*4^Q\!BGB[!,*(*YM_`J"V("!3KX -M=UM5L"D)C^Y*;A#'`1KJ`\4)MX&`$QQ;,G,$HDY8&YE/O%I!594.W"MGL@0,YI"O5!=D=&CE)Y`EK-IEU` -MD%*@E,^":ZP5DR+I@$/"CS`"%LC=3-0A-!HWY;'P#:4YA*%\-BZ)7@!9AS6Z -M[JBJ)Y=;"@(%`KG!Y&*-0%$15&>K4):B2,6)52T)7(*5:W.J0I8C)264XA)Y -M26-HIL'SWP45%.),BZIAXBF[E7UI1!Y&_EQU/-@E;9,!<(+("0H,3YY\LOF@ -MCX1!HJLM0.HS"=);ZI#GY@\H_$2?=H\*%CC5E>FA:\`L*D_'T?X4\2DV0Y$V -ML%2TH+R1P))4*$ZA$HBK[B.N?O1+)@+`KOJ;A[)^%*GDKRM)-?%@%-RK_*WI -M1;*?&?%9Y3MX*LYD*,DNA;G)2B*5310E*WI+=`%A$`APL'F](\$.DIQ0GI!W -M1^N6ES%J:%T%3YPA^-\)!)TCMGSR'/+&IX6Q;L(HB5%/(%\$S]C:5OF*[ -M,(A9<$W`E?/7:\@MB$"74ZH*Y`$,S'EFQ"9<#S+8-%\TFF$;6"E2X%E*^U`B -MK@"ZR%F_(%6?P!BZ'M@33%-@!XI4$L-6^:-^&P\JHI=%30(:-$P!5K3J@=E; -M"WKS!YUW4]`)TE;G7')7254-+LITPM[,Z!$UU8*Q65*"#X,U!R+DV_@%/S+" -M.`HG7&H%&@)B^I>*BH\O%*DT"7!%PS,>H*F2\,Y-5*J7>KBI+OE`(T3HJ*G? -M.@CP+"51%1$$TMI+:F%HE!.)!8T!3.C1QSU9W"*+Y%O4R5+L\H8];%VY`L47#QJ5*M![ -M8"%0K5%;\6P29(>TM4;OREP?/5 -MU5`?J()IL@4S3RS:`4/F"H)"=-45.U6E2!/)*51$`+SJ+P1+F;%`E_*5\]9N -M!3<\B5BE\I-^LEG-H*QEH36`)X>`.@4XO32$+6PX5ZH6">I@5("A/9-*7&%" -MX8SUO"Z?N02_,2LJI@$7P6X27`C[0I?YJJMORZJMC]5?E-=8/0%Y9Z@X+/23 -MB_%(P5M!+%?!:G[&C42U.@GDQ@>0]`(\C@.5Z;[SZ1]6,.5KZR%&" -MW0-`6,M1<2U`#Z^@BD%J>#B?>$Q%0\IZ(S"24V0F((BY!]1@^1@)KD]J`SUQ -M^4F2U'+Z6*U/U0(T;Y6F1\Y@O([&J4[:@@++9/@5C.6T-@AH@A<1-.86%=\M -MS3DM2X?5PU[#GML$M2JKS$-J4($MW^JH6`Y,RS5ZRBXJ+(E1_WRLRA"M*6P% -MD2URR$%<9;'056\574F%@LJZ+14,UN;'J9$DMVDR6UB$J.5/:PGHG&IO9" -MVLH\\+8@6X695>E+F%74"S^%=2\%(5G!#L-V)55VTN5GT'1#!:W* -M3EF958:D+80?;#[E*N5*&\E^.,N:GR-EBT0?6,$V'=FIUI>`'E$QX'8OE"B3WV46?%G_[;D"#,IHY*')-//$$TW -MG=,3D;5$\2MD4AD\H+,_6@]F'/?"R>AP@^`9=JQN#NEWJG':S(3I2?5^&(X" -M^'XKY\KJNRWS%#M<4HX=$[ANE)=US?!DKV[1'"7X31!@C+#'WRJZ!)]M -M1A)TK#'86G*VD(D"%39OQX32I_WL"]/+D.:T@]%;Q.=+>W;BB92^QM-/'.=& -M5T!9_E^W7@PPD&\ZY,NEEQ*',^E6Z'PS+.I2^J_X$(+?$@84OX@TT7:8A^)+ -MB&BE<7&H>%))4I<,GQ*K`[YBA6[KT -M=;YUW4X1MA>`IZ$\?__&2;K'$0L(]HF4_ES>IU$]"Z39]8YY3=E7,A(:PQ@= -M&EAAQZ6GU]#\@Q2\SP+H*=>)D#8Q`-)3@)*_609T3`;.I+P:4#S[.DCUX>9O -M>Q\@D+A4@:*^B2D#83R5Y3IUY&^E)$ -MFGSYV)-(39])(B3SXI'7\F`HY74GP$:Y@@;<:P2&H:*1%YJ=:!`&GP,TN],'(_7;%)HJ*5""*P".JQEE%6":YF\_SCP+IU\6N -M!7Q&Y-3]U8@E,CML#CM418KT'#2/`'+2=DF2GDZ'Y3OX^S"S@)-04F(^MET< -M#EH-&Z9;2UZ"(*YA8"ZZ)C1;#75E29H(H28`GL[Y0)($N]G28807\ISTHP)/ -M`^A-'.I.H>>C#..;"BFDOH`;?R=BBJ"0%0\F,I3A -M.\IR$C(JQMU7IQ2NJGI-G/>=>`\^KN -M`\-'(=X&8P,I70P^ES9@Z9:]4P>9T1+;+'L3+M0WR<]X`]!QF\(FX/O3]:5_ -MCK34]"`O+)U,.H\D%`4M+,T(&J.7((JBF6X+-/W4H# -M#U*,K;@?PPKAA>C2G9+:LV1S)A#P09PW%@)Y-WX88'+'XGC++Q;:"#,S"J,D -MG!/U>C[@G>N_K#!Y=V$9D_*_Q=O9&\HNZ8FZFJ_"B2?@Q,NL0.4TN]2$]22- -MJ8]`00W@\ZXHO(]Z(WI$A/Z!S=II<1+54=Y1D[N&(.'A<1JG1$(FQ=!"&FP@ -M4:4O,([A,'S:DRJG2+RN:E"4S4;F:T+0A,[DG3!-+@3Q\:Q)-'QX/?>@)(;24/"]-=A7 -M^A2+(-D]MJ)/Y3'<7Z8/Z@75Q;K"OVS&MZ4_5Z*QY-)UO.(1"[B[0PG'B[3( -MF,%Q?Q"6:DTJUEMCZ^FFK5$P!7MO&?KK2'N[

    +?-O++?N5!J' -M+):@%)CS>>5'5^$<@O`/P/,K]7J$J5RF5LCK(>!.((7*&DJ^4)]TDHOEG9M$ -M&IJ7+4VEG.=F#MKH5*R"XGQVZZDUI[1AJ-DGV`R[?:T"OH)T -M\5YB]Q(0HR4YTA"@N>D<@D\*\4F6HGL.9*LF'(.-&OG]L)*;XX3F3R];`B5O -M#%2UW%5\$;)/@)0LG*[:HZ5+(91V@63=`P'E>DB;EOA9F[A^:PL@_;=B6B`SDSR#Z\ -M6^79=LY5U./",Z<$V#)>%C'F'CT_"!,5I=[SR(]GE,"QO%YEHVL2@=G1PUV( -MPF(EVKM]-OY)/?#^0T\GE6DSX",:P!YUX-ZT4^S.A7EZ#G).@!6)X!+5BS?0 -MD%]V^*O-D,AI5D*CCM$,(3JCUS-J%6-(V$:<-(&I)!5+*I\M6Z@\*3P6'_SE -M!:1Q`^0:$#7*`[J2%-MJ\?%;LRNE.Z&JOQZ=+P%>G6A'ADZ -M.X>M678+"`3.YN7V]-K^BWD7&S$A'IL@V<*#+RSI:]660B-;JSIZNK-35@$2 -MBBAN(S7!;3E1GMZ,E5(&C=Z\@O)GO5M[J3ZS"R6=MP?9`@%+0#1OJ8J`M*<, -M^N]1[/TSO%-4V#;A"0D?QH62E3>3\'M22!47-P@%\<:$4TWV"()%RJZU@YGV -M'N3P03_Y-@:4G8)+]3!:/E!0'=UWZP&;+\R@Q6`]791,G:O+"(C_;&5@PU.O -MZ-+B'CF>S/2TI^NN@JNEB8Q;O0NI6>*^E#U2I]`G)5(N'U8K40:GZ)+Y0!+ -MDL^4IG.`6*R6H+/DUE:B$05T4EARKN>O7SA.9GV46ZF!AY"-AZF9UX6.(;WT -MND>"S`-0M\Y*A-[/]Y-77P,OS3`EV)'Z]L1\6N-,KP("FLQ@FHP2KLMI-V3N -M75];3-KI>Q>H;L;,<2?P!;#(5'!!$TFA+:\;@^E:P2#:[0+M>D_^`A21:!=J -M_)[@BT]6'`0<5(4XV)KJQ -M@GN^P^M+'(/:@UDU+R"D:U>"^I66][T+Y5CV -MJ]X]>J+(^T7N,)NL2[L/11I9.@1R+2'D%?0MMK+]TM'!>QR[T8&FSE)\!$Z9 -M]=Y`,NV%UB+I/&^E?$.DJ[45Y\&6M9"K"/0N\(:JCME_C^V&.K"E*6"%Z4V: -M76)Y/'M.#(P`R3@[-=99/1G;\;P+-R2QRY^R]Q,`]V..D@VV2.C@'R(-(PU& -M&K'$7S4N"YU+3,7B8D,0I-W8!JF!@4._J#`G5.B[^8,7+S3"./<*>$9OS"%T -M6OE$!Q!I,7IG72\SL@SE%+3/7J>D&239(X0XJ/H<029EJ+V&B)-$S%L-9%*L -M$0F]+O9A+:L*%D4]3EA:RYN8-/=[T+5\->S;\;'L(GL"TD-V1O<'KO&^`WQ& -M^0WS'BJ^:X&RZ;OCE9`J]BPL?BK74_%A_M6+`6N.& -M/H_^T+`M7'(#@VP["A:(]=MQ`?2O+?P -MJQY#]Z,5;C7`W!FQ)N5-T)OTF]Q`0VIO$-Y9O6-\1JYY1;L@ZW&WPU[-QQL8 -M;S4(G_$W@(-^K0H1NFMD;]9N=-B37LV]&V8U:-[WH0+`[>F^9!_5?-#Y1QUP -MC=J;0&]4W3F_:;^AIW3/YZJWA*`6XWS';RPK-FZ$T[I[0`>*KN]6&_$%;LZT -MYK8@#N(Z$34$;ES=4=2YO&'=$W.JB'51N@WK(YG-M(Z>0B?[1S[5BQ]H[K'7 -MZ#MJAOR:$':C9<$=JCD?O-<-C0V>I@XF,*PR<'&QT/%Q16:8A(> -M)@XI_R,''-GI,:2]UC&]LNK8VH">`CH*!?X\2UIDK_ZL@X5/9X/>HZ/@H>*O -MAD,A!\?RZDH$;DN:8@V)A -MX!.12%#U&Z-6?9'E0=;B>_HP91.54S(-J;P&5N2I];FRY-CKN@BZ58X(R -MQ'H[YBQG;_X_(RRG@[-9SM^!"`>QSC81;U0HQ!WU2,6]Z.5?$)/GZ-@W^"?H -MJ#RD>_0P,8.-5/[W3PFR/D/4HX.*@FN+A&LB0S95H.'Z'U/U1]%P,08[A;$1 -ML4_Q*=T;&Q<;>$>#BT<)ZL!(UWQ6%4XR$5`EF.IRA8>."!'S]^L0(%0E'0?L -M'>$]3!^Q``7T:_J&7Y/0/L1#QC\0K$V\&HI4+C$_U/`(LP"DF(, -M]=_*P'[I"0/WP(,?O%-K4@7KP$C#A1*.[(?`FGR,'D:B*20,F[Q633AAX)'4 -M65%&4J-JA2!AX2'6#0J@W]-4R4+/'5G\AE:F)T#MJT#T9&Q>344J&T0%N_Q4DH-AXD$1XXB-@3-0,6"N]"D`*T<1U51LPT5 -M&@'X6*A\J$<(1_0"20;V":"3,4[OS]5'E4-7Y5"E%ZEU3K%R$+#(XZ)IF>21 -M[X@04:"0\6J,=[80@(>"+2/U>B!0TC!ZN-0[#QYVRRW1J@[VD8/#P_5AE#1C(^2`2JMYRZD9HZ -MFFO[F`J*9$QS?XJV1]3)L')^J"*?T9)U"V7``JIG5*`Z#>_A(T])HB1J.V6J -M.MGLW=\%L^(1RA"//GP'$]%L\;XB-AP--4N'KT!TV5&C]"*EV5_!RB4:M*^?$P#ZIK('UH(D -MR',@%!IBA6!,A@9Y,R#,?@=\3[#^6?C:8W&7(QO,N9ET,NIEV,<#+N8Y&7XQ -MS,=*A-1Z9@#'8QW,P)F",>#'DS!F/1CV9A#,+4+F/IF&,P]0>`ABC,6$0,B`)_D3(HR+,C#,D!,QQD>9(&R)F4,DC,J=H,ZE@_`:N*M)(O@J+$.1_Z6%$[L['"(V6%+0B7%+8B8%+ARB'M>$+0I?$6M:%M@$;Y` -M`PB/MLPMU@1OT'=C$<5"%LI!K2P&JHUJEI?5^D=?YIC1TJY?TJ6L_E37!5K5 -M5^EP>B9J>:.W3H`EXWU+3ZP4*<`8ZG^-/U&_K_HFJ5Q^M:H%QVVIM%1K]$E" -M&TN!VD;*TB)%1+0=V\\_2H\2P9?X=_2Q7+ZNF"'&.U+MUQ/!/Q0I@?X\B]08 -M7;^):TJK2]%SCNLH%WYLZ;HF#'?>>7FMAM]8PXE;A=:EL7/ -M=@8?-C`V9Y'TFFX-"XH@N7MWJW"$0?=32HJ6:-[X$@;/;P'2C72;/0K8K:TE -M9*B5+W4M^NESXJ+8)7GR.,8E>G)_2XWQ/>Q1-D:E.MV[F./7I>1;^#=)VUT$]9@068['2YA;DL[\E. -MN:ROY/N?D*#1Y$3INHH:2^%+P4H%B"[]<^>@I(=+F5NCV_"IO)Y[S+:6DS-, -M,DG0BVR,#A)WSE+2)TL27^DOE2_SYF'S>$)0IRI<[\`?3\"=^"K-5"M$FU2Z -M;(B#W7(IO8M^FI$-JL`F*,KM,WL/IX5>TWG2>";O/:38P3=B'CJE[O43WX5% -M2)*7KTB>G18O%3\']Z$NK`T_J]8E#2Q[WX?<4[4M3\`>IPTJ']T_R]L]$P0J -MC@J7P_F'=1I2W_8)I4+`'U=#NK[1$8KZ+VSSZ%PRE,Z1EL3[,H@_@4'`WIGT -MS+('!/J,&,\9:DPE*'[0NF=`RUF<\RQF,1=I`Q/2L(.)V=`-_7#ZPE@1(=_? -MJNL99?[+GRNBZI&(9\ITP*UI_ZUD1%?/[&^I4;=8[24P72>*'\`(2&`%D$P, -MQA"96@%?JD1'$'8^!D"P'!=B`N"'B;P;GB95NLR5.3K'PLQ8&M.R7_O+BIBJ -MI(;_S+DS_"71Y=V;JF(%XEIHB(^E("OY3I9$1B#E[AZ3?/52@!+%EJ03'_2; -M*LS6`.J!*M[]NULA)=?]WRE.J18:)5C;3QY:D,I%F$_^47'?[]+_E(KQ&"_> -M"R4LU(9_OOAIIHOC2ESP$ -MR57:?/="X[8^JL+?0LA__N+BK`2AW_["Y]R72R7:#'DBSL#*4"?I26F*BHD( -MW"X\#RA]V]$$GA#;-!]\:6B#C'/2=SIJQYXE;'T<4O&5)P_8A5-4:JV;%V(1 -M11JWHRDI21G5`E#:@%E=U8<@:FDIIQ/,$++*A*4:$+6CHP%OL77S]4MQ5!=Q -M_ITN?[])^M!21)F8%FTXB<^9^()UJ/-TP"].:17<55*EI&,143S`"N?"Y>N* -MA*,_HDJK-?2^@OWW(*1IZ$-JL`#6@,]W"*.@F?.`)-@#Q2E??>FY!+BJG_14 -M5471=$+DRD0_NEY_;/7<./+!4OFVMQ+&]*E0^ -M'L*17L]D\GLECY2)1>A6YT:N!T2MO[&"++B9_OO@O[__MFE5JK#OK/]]<50O -MI\)O#!?L_[ZF4/\^:+\@Z?R8+\^:::/[SW^]2TEHZWB;4M%1=='13]'0T;IM3>GZU426C3@]#8LO]%0-B+RTZ>9M\I(4VT/6:!91U43 -M#Q.?S4%%;*%>H:(@S\Q(KGZ1*C)L3=$"!Z41)R-<\T#Q19U[(E8$.$AV+22" -M^(\++L`4_]I<4BJ*AWF8O_4N0%WNRZI>S4EVE[*HO-Y?A8&.$F4BVB!@P%V4 -ME&N`UI*!C]V],)?IV$_B7"&O!QKR)?!T[#15=E@8"VR=:,"#*5/&EX[JE[R6 -MNA]!@'&,>4K,RNB?(5V3M=2A')I%021B4*Y-^!JHOKH^Y'L)#;RD=%'ZU2KZ -M*AI?4F,%'3^&/K!QO*V9[1U`K@Z72VB5*6Y1&?TV7[/T)$N8L/9L,-F:YW:= -M?GIA'T7@KWUK%U'-PBD,7:-<]*#%:"/P1VAP3],K+5$A_>Y!2%NJ_RL`JV>3'">1A_68 -MNT>6<0C%>P17QIIHOOL@'UJ6R_OV]B#^BF(ZPZ>$6M:%OJ"+8*ZHB90!?[$=@=V!&`0BOLB(4 -MCID$18ZLG -M1RRCCEF$84ZK0B-'5LZ.:X..:Z(PQU7A$@.KYT85&Y:/>QMR.,4.;QDD*SAQK4$&\Z,T:V=O/"-**SXCY -MQ6@$?0*^,1J16A$?@*^01KA6B$<(5^2$+(L%_-``F?T$;$=^HC:"M>(VP[]A -M&X%;`1PQ7"0=V!!SWYUQ!&\37%30WC".".Y0CDBN6=$A8>"S^O+A]'=$FB.Z -MV(KBX=M?&+PIC$6(4R"&="%UD0T$!QEA.B,[N(:@94@+.(%JF>>(G3KH".<.Z*$;C?Z'#>D(L`KIB+L*ZJ!JRKMQPWK( -M.Y`7KCDSV!%F'=D1?!7:$)!7;$3XKN"&L5W1#R*[R$T"17WT#@(S\"#NF?". -M&^(C6XUM'7,0WBN&(FC=V;Q!4X(=F("P<8&;-"N(FB`KLQBR_IC#F[TW>&\PV:-F4UP#> -M:(X0J7$<-!NF<"&B]N'V^&X(W`(,WA!WQ`CGF\XWA&]$=QQ'](-SGI"NF(M; -M,++4F&PU>L8L71%T-8#5]-5@0PBF,0Q"JR(9!5;$5H5>1%X%7L1>A3B(O@IR -M$7T4YB+\*,/ZR5M0A$,?Q2T(OR"_5;&0`I<0=V@0NBAJ\.;A"^*&L`B:07X8 -M1G9%5@0Z(#5B$00YC31RR#CFLCCEE''+,.M@BM"AM;'-8BN"AM=$5M$>K5KP -MRN"J^=$)NP#CEG$.J$+L(B#'6(Z;1%C%#;((:EH]5"RC+:*LPB_H2ELXB$'( -MQ&`0K*[0,A15I$.R`*T"(8S#VQQS?!#R@3=]$9$]G..0`)E^''./$/B`U?Q$<.@$'QN0$/J$5Q`B/'1*#N<')G.CB'%^(<0=R -M3HYY0XYY8XYY@XYYHXYG!QS.B.(=@(U8[HH.YS_0XYZ0X -MYZ8XYGAQSU!QSU1Q)=_V..>L@KK&]<<-[!T0:]D<QMZ30V]CAM\'#;Z.&N(C>"G) -M-#;\(3(USLX]C71-#74<'+S88N.?MWAC974N\N*#-5OOQB;6Y%_EOJUO`C_2 -M>J7-SZDC%U4!.JAV]4WW9@;#"LNZEY)&GQ5# -MJCJ_5CGJJ)`#@$O=Z@LX:';%$_2^4C^7MC(3;_0->.<#P>:OVG;$:?\WB]L] -M4AW8J`G4,%_5_Y>HB?_M[2;H3X'^3)REO_N)8J>5NW\S$!6$9LR0+6._H%WE -M:(R'*SVYCD?OHZ6EH:&CX-6IM=^K-^.;NT_MXNT5$3TSXN?\L/G\+=2DQL)> -M,[]:[[BX;.B7>5B/,985%>^HUKCH=??F+HUVM4O/ -M2^-6H#Z]"EI;BE[B6>.,A[3KYNZ:[Q>V>ML?U]O^"$L4Y$[;6EVD[;0J6:O> -M=KK&?]?P(<$))],6^H@QZRL6K+)9`^J95*>+3TO3&=(?T?^XY>[_WU?\+P/Z -M50TB_[/G^(?D/\K;&?_P)B_\)==CV/Q)T1"2=)MZ/"X0NPXITB,%0#P=@]H/ -M#"[3@!)V)_M=HG^J@Z51HK((HO$V=)`7'Q*5SZ76[%88F-DK+*S5JMURN5VO -M5\RP&,]A'BB:MUJD_1BMJL`AQ5X?7ZNX,*!)&>S^>R`#[__M? -M_;-WWWC#O5_UB%5?(6%3<1"8'Y9/)U4594X.\JH>WHA_3IUFPFJ8:J0/9`R$^?NI3++59C_5[!#I=A9'JMI5175J'Y`DZN??V4%/ -M1I0@WL?BS#ZR,_8F(J0(@N1*J>9-IBPNR`G>PKC^&_MR^&"]4^6DL -MH*(!`,SP^38#.GA!6(9[KY[4=#Z8>P+X1]N?UDG2GIX7A@8/8B'8JL>'_1^A -MA]LU_R&:65,:S#O60.J[X151T59+!N]R9'K3\V(SW1/NCZS=6$=A%T5@9^P1 -M485@MIV=/1"ZLZ3XK%HY`UZKK4$<_^<^B):6UQ=7O654F>M.:PA5.N`MM;8;<6T2&0WP\;P]\-AT -M,;M,JF14V*Q:##WL8L.N-,QS\+,>3BGQ/D!`U4>04&8/V0A>3PA^<,8+W8?( -M%Y,$'YQ)^[(U+C%189%QINHWV2,C`1$-DK)?7Q0ED")8\#*GYZZ'0_^:QF$L -MK9@_]Q&3UT.M*IL>G:TF)OOMJM9WFB'_[3!?SK0O?6QUR;3M.%UN1CKAG-K<\&8;@7L6\%A1:([#1HT:9@+\ -MW.#:WMHRY-[<"S-V=;]A77$#,6UTY-9[F[WYYN5V;SJ[&N`MI^#KF;=!;N[: -M*/`%+P9<[DVG3>:?!RR?'-V;A;0&Z@:Z';(#D^.[X]5$ZB2[M:8JK=O%S=!< -M7*K`&\?-7&+H+FZCYNQK@;=Q>%DKA]F\7-T%P.'X;QGQ55_J8.]_?6O`N[XLMWX6WQ!VPSX3ZUJZ`Q]!L\!B6MUPV%>GMR3^5-PB -M-.K"J8'=S3=G-UJK^A0M=WE[]D[OJ?SH/A1$!8\!A75U -MP2P`54'1])TNKPGZZ!`DV\"Y*<2TKCK!/2=Q!Z=THN>4V+$0?79R=UD@/M1G -M@G1?XHQ6W>X.+C(F#MD.IX=(.*R+_&A7DND@&7SN#@X^&@X -MV)I[@HXL-5.]^@XF%AY`E>PZQ4+$DA&&3^#+9Q\CW_U4O!U!\'$/Q-I8^,=I -M!30_A`TZCV*&6V'>GXD/0\"_)I4[QY#.)VDWR2PWJ\48%_C'\L\16!V8*+49 -M`#%W%RXA&R,'494Y(VJ_1<1D7J)MK\)?R#6J/[7@Y**IG'1%5?C'N+*>X-Q\ -M9TPC8^0A9`:>R?RV5MWF#RD/`Q8A2[!#4R&8MK[(1L0P"1Y&P09B%K(A&@!Q9L29)#\JH$ -M#WZX2,@W\[N/:B]_3PR[5@S,BLQO5`@>ZJ$Q4'(F(9 -ML'X.+A#"9HJ`DY"!E_6#_?;ZKS`7D0S`A5J/[\",D09Z^8(%;LK=R9 -MOT`WN)T]X5ZP&%!F[(3,<8,RIB!BBN.AHN0B1Y`59X.U/88_-_?#U3- -M\#,^#W&8:K9P@/:P&5AXPEC5JN9BY^\+]!WD?S1L6ZR&4_F7H*$AGPH=]RP`DIJ4U*:E-2FI34.^;2HJ -M$;4V8NV^XF1:H[V$SE3F]!4]`9LN::T`>6&V`JLAVU^/;YA_/WSRM_/VPH&P -M9[@ATS[$B?$?M46#/_00JR27_L0$'!&AGG0=^\CQ8,D`VU07L4 -MMZLV)%^C8(##W"CYRMS5;UB+YWH!^.CW_>Y!`3Q%5$$:#?11-5=]@/K(CX -MFT"!HDW2OX>URF5(3>1?SRE5GN,>`=E[W`!4I[+G]G'>W*$6FR0C%>=):QG+N=Z@SX\+,>(L7"MTC(L)W -MH")@U8#V-`<(-AHJ(4]R,54YQG_;JQ\IE?70[/&(>,4%86#42A3DBH4^!`0L -M20BR9UZK(.YX5S;[E5(@>[J25A8^J9VP,;8U!=/ -M&U=,>++26)O]DEB+JU"8CA[&5,E1C,/455E"W`9A%:-K9M<-#W?B)BBM?$6`_NHM81>[8A%C/YD -MYLI,4H0M\I.#4M!A^$B-"&$=VI#%)R<-?:C@EE<3-O0Q1#6,;$.+0.+44H5\JIV5\!BK -MN^]S8]H\X+C*QT?!*MY]E(]E9H%?EFJ'*X#]2'Q$A,NM+$\%I"?5G0GW9$)^ -MSE?33`FF%#?6$'MB%WKZ$+.65`;LR#FJ016T'>T&HT-]T'.1KF@W>T(7A3I\ -M36(0B?%($+$CLB@-8Q!$$:@6J\@`S"!=YE#?FD'^3-S:`GT:"+>H0;ZM`@?> -MA$-8;MD"1QD'^<-9U\\RN,#^OH?57S#&!?'080GS^, -M)/$Y#'$IRQX0P^(&$%$",((G,80"BQ@V.,+9CRU"&%)9<*-P@<.3JTE13%'W -M<_1OA9GZ?-_)V-#4F/3!JD-Z/3BWCQ7@^FJIP"_RHDJ9,"2T!!>GA -M;B4?X*)DOFOZUL8/?U?$S)PE\%.[RCD% -M7@MP%HS5T9+3:HX_&TE&*5:D";]@9C*ZP1QE;#JA)@)-N"JUAWIC,O@D_8,>'T)!L.J/GR8,PW*3!FAE^-ZQJ^;B -MS;$;\QKF;E3;P;RS:X;D#;<;^YI#@T`C`F^08NFX(R9MU-XAK -M*;"&VLW]#2'AG1%_-[@QA-QQ>SG##]8R!-RYM\-Z)MC+09'C8(W1M9-T)N#- -MHT)\8016@EB3'9(0W&RXI_$6@W[341N9-J*Q0BPF_**DA%W-Y(J'$6TW9 -M&D*&?$.YOB'8817J9L"TB'N0$70WA"H,1:C?R-(:&<$.HSM"L:(LIOTBO@$7 -MLWGBLB(:S?X-((2HAY-H1Q(+7!DP*CA#>;,BB'5:!GXE[#W@-.=CF([`KWB] -MIDF'3#O?$7DWFBH@1;S=J:00E!&"-\P[$"+`+O(B+L;QA4*(MANO-)$/B$8` -MWO#GXO6N3#J!WPB+Z;TA46(N)N[-3/R"'HVE_X4\2PN=6;U#=&;R#=B;X1?# -MP14;LS?&+X>&+G\S>V;]1O0-W)M$+X9H7.L-[)OSFSANV- -M\XOAXXN?V-[YNI-Z9N\-2I_KJ(RP>G15Q=K1EC]6S5I=4GV$>+E>77(RRFN- -M/]1>SCQ:KJ[:#+(:CK:ZHOL0\8*^NYE3>!='8M!`9DVPB6<6+XE>%C^)QXL7 -M!*V+&X2VBQD$L8LEA;,K1;<+4=)[J&5X+8+3HQ!:'&,.`)9#:R8B+;NX<+M9 -MC0NF2/0NEA'`^K#Q#-D$+O[6;P8#`4H:+@A;57^](TP@DYRW;R1V5P=`6PD2 -M_PL<3`E55D751?C8%0=#QRK$K]2($\2_40:I^B8.*A5)1;5 -M^5>(7![FC#Q"V4+QX -M`:VLA>'\-&7Q/-*2ZR#^G"TNTQN-7BI4_JBO*GGV<'+%P_6=UZSN0R4(_QJ, -M_Q*?5,Z"6PQ5.ZLNZJ*53S4_-,VK\C<'^L][^,(P_18=]D5_Y/)D(RZ?A`S_ -MW:6"U%RSW0K/W[?HR5FG^9/9[G\;5A_G+;'+K[7M^SH[+O-%!,VVLOB -M1[#(.V2W'CZ3EN\W\'+Y]B[?6_K(X3:ZV(@LKZ("D[G! -M@]`]8Q%7>=$KT#`WMEH?*R,$KP$<5><L!RUS!4 -MF<9.3$;2L?A0ZW:72)T^ROW-X.YZ#CZ-U^G]Q,[CBKWR/S_1 -MMYUKO!G2PF8PDYP*^_S>\VGD_>T-&^V>'^C2_QQV7\/YV^HVZTU,&>77[9)@M&BQ -MD#V/)A(B(@'^)LDZVP>/+9NONZK;N>6Y? -MAT\#.:6=40[[D??1>3F\K(3\.YT?.BKG?\]"_K-[?'\^.:UQTZ]E6V]^>*Q^ -M7!RS)_5ZR2Z]_DY+5L9F9BW>=1L?!M6TAL1L\Y%HV'EPFXU/6?^-6?1TL=I^ -M#SK;:=/-[#]];.35@O>SQ699/W;+SC/YVWZQ/\;U')[?N[79[SZ6/J[5;^GD -M[&/N^`YG:_:1Y/V5ZU]!;O,%\U\R&19-;B\AE6+CUGK?8E8 -M=);->96-CJ%_X'32,O@Y/W,'Q0WB16:EEUZ'QN(@//PX6#S&2NL38>RO1$5D -M['RZ6>M_*S^+RO/9N)@?ZA8OI[CT>CO[O0N>[VU@YFAV&/2?=S>;E])R-7OI -M>=<,+XNF]>&%W/(A<1NOQ_I>VE]P5UV3MS[>R3KQ8ZQ^WFP*W=?XW[4Q?SLOEQ?[V];VDIJ.=<++K^E[VPEX+ZK7 -MXH'N?7]V0D*QI,BM:Y>8?KOMUK/;SD*OQME\/'V6`GTNT;;)XOY_G02_\<)MTFS?/Q^[]VE=NLW_ -M&D7ISBVW$=)]WD+SFALRL)L]O@7_?+5CAL;\UOB[==MVQ?OJ]"QS%CZ:[BY7 -MOK1/&HUR;K'8'FM,Y/3!H.=P'?MI^CSE]?M-"UR>HX]DT_Q82MR^!9FCG/G*C/)E/EQM+M.;33V339N37<5I['FF?7&?5T*%KV'T\.ZZ[&XV1[%DB8E+T[ZYRW_/_+7IX]O4 -MW]T:N)$1_`G_B:WJ7F;(^]!%H*]\SCN:S*R:1H_&7YSAO&3?ZIP -M>/)N;1\FLTU8XVFE:XPF<3&.S=..LI`4,5PGSJ2+[C=S_%>B=5]W-OLKGOGK -M.FT;WIYSI5K7<2:Y-#U.YI.'0^7&3D!&V7L241TMH^N.IS;UBL36ZS7["T5Y -MEY\8X-/U.31>]9$4D'V,7V,M:F'AXB"<)O!_=K]&BZNIT#/:.)K&_'TFZMW[ -M=1I_7O3=]_=KDZWJ8G9,.=_-I=N#VJ\^3=MO^7HH:1@^KYI*^W';.S3=8^QL -M-ENENK:YXMT^8+9RKMA8SI0]5P^)0W702> -MY7]'].4?=UL;O!ZS6X+3R=YK&NT]IX-#M&'/^_5F)\E_XM]YV1^. -MLR\>YUO%^-::'+M2T9$RV8]N<7 -M#:=)(N?.YT3B[,]-=>?LO=6/ZVNQVS^K(9?*V9I]P^-TGJM%`:^4Y#YM/EK^ -M_\G]8CR=_??-K)?O\S3<[S3^Z7]?K96R;:(Z3=]=N[]NSG=DHCA?H[1G*B[' -MC:!LMU_ZG4NO2A-4O[_X8%]2/MI@_&\]?Q[):^^7UUCA='FVVUZK4VW;Z_?] -M;T:GI4EXXGCYOOTB3C[J(UV8I,7LOHOC#J=E\+AF_SV#39+AX:\OW2Y7^W6: -M.D6Y?_?J1CMY9N(PEUD[_E9'98V!PP-;TW[,31 -M*[7@1FJ^S/N6YS=_QK0MK\2X6+?7VO-VT,EALSPX!X -ML^_<,SCO(T:?[-96=GT=-7ORL9C[U\6W/5']$!`3DZ^27&L#UU'?#Y>A>]*U -MSGO\NR<2`KF@E6O"[G37/1I-S9YOG:I>[GCR^._67@\!%:-VB;CJGR0276MW -MC7+["T9!]:6"WP=]K76DM9IOP=MU\D)8]']]LMV@_F>W7#\6KE9OMP%1EO6C -MO]CG?SU-U7:.;UC)?9/06O+[+1WW<-,W&4%>X;_V+]404GO;2(@^CY,7E -M]_=F%\[V3<';S['7L.W\&IK>K;^)?=!&TC3I"=(MY"7117+S:WBMW?UKHZUA -M7^W+\->V66E5S.5]Z7=OA*Y6?DO/(9>;G/G9.IW\,QP7HL2@G23K!6&O45B] -MX#&,49]UKLF`X/6LMFD?ML]MLN/LWZ,5QL?U/_=L4OT_S9_+M(>P\#Q72MI= -M/YZY^-KV-:T;Q',U=Q=ZKS0VTM=RNAV]?>>ME;!/7]Y<)RX?)=]#\O!O.XH& -M*\7KO.E]8LWG;YA;QO;U!O:U>\38,==8OX/KNUUF.?=$6N9[GF]YB&[9\S2M -MO:B.5=\'9WS!24AH\#1P/2>N&PV3!_+ML6\?A_6G>=/].^O_[>!>P'FP;BZRS3F -MG1TN7%%]A5IOPU\W4AB&'F[;#_'O:!\W/Y7C"] -M6NY9[YF7W>$27?JXOIOB/WL[W83%;'XOOQ-ST?;QJW16W&8MUB\=D;C^K]F+ -M'=.IMLEYY[ONQ$MU;BDY6>[L_H+K^?;_G&0_:\&WKE)-HB?GI=^R]NY\R[N+/ -M-<3#XB7HKUI9C[ONG$<\CG>+8N -M5O>.U[A:XSCIOVTTT]<79'Z,#N6[ZO@Y'C^EMNF?E5]^P7QX[J, -MFAAY3C_)W/LS&@Z'GOTIFG=)I, -MW`_CA,Y>&>P?$R1O,SNJF^KKOG_A'K>,N0GY>B*^_\\ME.WK\%6[;^U;_2+_ -M6U3/Z_HSYGPZRX]MO_')X:0^]RONV_#?6V@U7C<[QJ_RI,M]WV?/N_MFX[?; -M3LV%>_?=ZQQVN?XN:VS'T.+LKSL679P#*[['#09\V[= -M]>CW'[Z#I;J3GK)_//QV+WG=N>GW9S!PNZV\IP&'\N]^VTK>(^>`^2Y>#I7; -MHOT1:MPX3GV=]J_??Z!Z8/@@I[^8M%\2*^_T_UUDU"N;!&R%KB^-Q8SX?UTM>9ZTUT6V^^ -M^ZB;9_BMB3CV*_?)'?;^B.9V'!P&58+Y^URU7O<#0L^TA;S6)LSXME#N#W<6 -M-^[GS]7P8K.?%\_7O?(^+.P?[SUX_K%O7R<>^M2C7.LW6[7]R.)PK).]UQAM -MYA*#5T%O\&^U/SNUN;;2G%B-1U?-%N_PZ1@\LU\&L<>8S[VCR.#F]3=+?MFB -M5W[/IM3JOAMULL.`I/XRR-R6OE^3R,WG2.VMO>)KOU8F^ZUHVNBLK=RO/J\_ -MD./DZZRZWA?IU%_X=WF\?,+W)C-5CMM8+)V,5M]=Y+UTZ\\9SLR_(GLQEX>L -MW'A^_$.TC,?:RLG#FH;8QUMFEQ_>-5M^=Y=/%NFB2\JCR[W"=ZQW;GX=YMFX -MK+4XKNUF>_L/O^[/,=DL6PZ&9^&B:D^58(:ZRT:RZ"2X=VQO6U[WU,8XI7W!VK3I -M/-'9Z4U]?[]VK]`XYI<^RV7S=--GG[0Y93#?1^TY/2G"V&,;[SM<5W<=R.OA -MM@IPP',L/<2Q-HO,`PW_XN?V9^Y<#-:'0QG+U'=:MCZ,)HG[#];-7ANQ-XDV -M'Y-9V(IOL[!+9UDR/XWC:??U''^:94:[<;:[V#`X/R_MX\G:;EIJUJ-!E-W; -M]/9>=\Z/!<'R91LU[MO=ZBI.3^$(Y9"R8[3>>2N]N>OGTVIQOB\+1UUVPQ#S -MC\O.>70\B`[/;VO2?L+H6&7NT_M,KSK^9#;JT;J;[3=T\]\F'@6U_]'-M*YJ -M,A]/\_C_*_.RR+>76*_?]7QA8*]].#C;*EMO&_"M9WW]M']2:9>+SF;Y=;N_ -MTMU_K5A<&C)_AF)"$F9UF197'TNOX\;]7!CN%:?#]^(P&F9^_KKO^M)Q,=6G -M5>[SSDX'/^'C2MK=.BD[PGU7KH76V9NZ?1\NF>Z5L;/HW#[:Z/I)-16\EC?CD:_U+GQFR -MZZ[\W?0*&.Q?5M'F9/;C;7,16SS^3RW-[W"WT7S;+BJQL=7U.M9J[X\S):W!3D/PZYL -MJS(_GC-7+[B[S.719BEUWU]?Z*\TL5UU5UBL)9-#K*_"9V7R7/_^0$C5%5P= -MG8&0E5GQP<.P3@@=H4>$%6/#\L5WF[7@!OA<>"AV!'>#,(\?S7H!.0281_`(+A9)!:=8!+1=#;6R\WLW5Z<-)5?CIH0T(,R=-&NF -M]7*W1^0Q\Z#"ZQ)*WFG=[/;KBT)B;4>BAZM$E]EIB#DY:]L17^T/M/R9^2\- -M&EL[W-DU:<_9$!>BK/(J:^S3]MW+O4ZPK!?_,6`UA,7@AGSNL1.UZ'"@_G\[ -M207R2R"2UE+9]LS+$V-IT"[.,D`V2B8X?`=TX&5;,:5<_UG]1(L^A8W^7167 -M4>F6:S["%J+#AHY8?B4.,=JQ-G&%$G?P*)81T -ME76"56-)$[=<'J&L82T[<=$^B0/0;`B -M1QR"RX:/"Y^(UA"1&GIE#[$* -M:#LMBE]GD-I>6`-F9D[F'6=<78!@,,WD70)+9PB.WQP#G'9]"N:WYQ&Z5&"F -MSKP4K=U-]=I7?+MKX-W7=(>U!?/+4:&R'?E[,E)8$JH7%4YJT[X35D!-^38F -M&NCZDX?'>;'9DWC731D9?-V(#)NLOF:<[MHV*#0\];KL5!!BUN,P4>^/O#$G -MU:0>[WZ:#MAT3@A][[0-$A*_#B"!5&.K)2!J@*FO8T,OH=657G]D0Q`V,"_#W!@%2$[P$RM/Q -M",8@P05-8X^!\C&R!%QW_1=5%E[8&+!&VH9K;1`6Z:(RLO+FMR8QHQY-\VXNDS4Y$_&L6+CG;)48CRK" -M-)%J#5(S0\KSZ4,'$DU!4?H/@9U6]1;X;F?8M12,6F(X4-DM'3!7*F&LF%^\ -MA*U8\NGL>N:X0>TJ+,-*"NJ5XM8J64&N,SPGJ -MO%Q#$LSI7U^G3I!Z37[BF^:]R$S@RS4H"-$8&2@6$4&\(&IXVA+%``X$J"L= -M:H[[KUSJ+.U.5T@=6#AO%X\1)_'*M`]WT>&M#=#4(8'(Q\GCR=<_8]*IZ?+G -MOS2^6@QA]%>3>EJIG+6&JU$8B9[!GARYD)35YZ!3#Z/O;[.A0K&N+%&Z^'#+N(MH?78X\*NF5'7$Z)@/NKKR@W"86P6@HCMY -M&B\*!PXA8GLZ1[C]:F^=<&\O=AY#8\R2&1\][!6'C_@L80$%H688HK3UKOK< -MM90P+"Q65&:EV<7@X<\RXJ/$)#3S)%-O<*@$_GK=>/S]>#&-J[F+#,Z;0\>J -M-7IJR8_RPP("BJ(BY&-DANUYYV1GTFP=S-/.X#D`BI@A9*EXINO@<5230U"R -MVN9SV$0E5EW+=&2:U+5'F+P2PH_%L"%U#/?HI)0XJ@+_+L>4,IUV!R8R\\=. -M@U)$6M'@L<;P84*C1(4++D3T6'J71@TVM;>>$QV]KE[^_NN+7*Q8IWPL&7.W -MZ%->OVQ038T]DHN<_/,!QYWZ12"*1H`P+J^N_$J3!@_5PK*8A\S.(-&<>8;? -M<"$-RJXH@?(^(P2W9VNWS7(^>Y`US$2(+=H(G`*KN[(2N5@(@2HY?B.4%Q-F#_%,13+2Y-LW=)7=VG+=67RX1SB;G<[/=` -MS64E4*_=42P7Z*%_-WHL'22F-`D7XQ\J0S(),7)N16O6JDYFQ>=U0WXU7EFH -M*(]9#D8;[I=KOG^Q/H0%(UE#\ANS_OH7/+HH -M$!"`8DR1/WE1H`52=.NV25W!?'PWN_+(D?,M5(A/>[WB\?H_%1`ASM3#%7S% -MU=DO@Z*&:C:R8,IO6\J;MF%LH!TP8@!`53JX1QO/[`^0@,L.4N'6"_)U+X5FQB@&2I: -M&!JPB'8Z3336/;-^B>69>_BX@Y#>FO/$'@.O -M1`OX:=6QRGG8(FL!JM#*J;2CPU&F?3%OIOR-=2DDBER=V(-J2(B$DY1 -M@,;"UL'>8LJ7&Y+N>^]I>;3-&U^V'MFQ5V_HW#ZM2-NB9R3E&$HZXIR85MXS -MQMKAE2:$\PFBYO216)CP'A0P[XBZ0NCVWS;F?C\8Z@TO@.UY@=S/9%U,T/*# -M!-1OUZ;3UQ.ZS5<"SLKE\_2QF*>",G*;FB[2O04O-`N>+A70L*WNVZ*<'1,TU[M2QT+P4E7K8M*D=*<0 -M[KVR*($<5*A'J7T(+Z26Y]AF2">B*JW'Z-M%2!ZX8>4>-C35(S!&)4<++T*= -M;EA:ATVT,GG/OL4UW%M=.M'G*5]T:QH./>K]&RMUZ?$X-ANG,[:.JE8V^_.9OC7,1ELNH>#\),CF_!LD -M`C\YF54]];YES<+]?9W=^#R-ZA-87Y,BQ9]PK7<7;C8][WR#/*^"D$4'7Y!( -ML[,UU'.J5NC_I6*1PY0+=1>2X?GKB?SLFXT-4$^8+/HWGP2N:^D/'=?0F>&' -MG.:RMYM@;*F?VP@AH>C8.--LY[+4J9;UZ7.0X^B;)'QS&8.S')X19NUKO$KJ4C2>\SRIYO1H]1KA44\*YCCKLM\ -MA]F;83W([!2J6?P/9=RU]?NUY?AHGQX2"$M^'`M"!B6V1Y/@"5Y;%4L>>Q+1 -MVN465GY=&;I0-Q\[Z)207U&ACB+Y?(+"0]["#? -M"AFVGJI-YS=Z4I%$BC:J(4HJ.\)9[C?!J=,]XOFW!2<9RM/#Z7Z2FZF#E`Y9 -MIW[O?,VDA[JNZ;L6J"!O;K#V>M*U]PX2HP]`.J1&G\].C"*[3>M@4K',(F.P -M%T7U5RAT!%?%2AC9:<+568[JOUJKK6?:2/FW_[:KK)B8/>%WWK%*NEX/8NR" -MH;:?$9$K-ZM'W9AO7W=44<+P%)D*U6>JOY@#D`B/EVM=R,N;I:NHY&:JO"2F -MFC:I+;DX8=?6)2PL?T72V:CM;7S%>SU&X-H4@8?P:B:.HWIK+1,:%SR;K>R" -M&L65\F)N$\RW>P_IKP@H@IU1+^7,J7T#41?>D,\[%5U$$!8I>FF[)(?/U!T` -MK<6N=_&0@F"!@L;2.=6JQ/8F*_VQ*#SY;(E`IZJY;![OYH?TIUJQ\17TS"+( -M2UTKD1@5:\JJ)CTC-71>\X5&91[//#1VVPT:2V*EPY'6E*IB/1-9"3'TR!9QQ&6BP)\1M'H)U@BY6W -M]:EVO'VAT9K>:@KE9)%]0ZQKC;@&1Y>]5VP2\0N7)%9L$/$?X.IV.]7`:]*< -MZNETE!:I'G[!A37E3SS8<$*\G2JP'/2B;IN&\'0Z#FGS0IO(<,68]%> -M.YQ48T^7F\Y-]`5^]L2PQ1>>093&*N_5(*VHAW2$F(^E3^I.\>)8=\7J?-#+ -MJZ$49,98OF3M8(V<2+8WZ27Z>AU/9@O(6VI,QY+RF0_7O5;FK&,ND*(MNRLF -MV"L:R;2):CX'O1N2)+2>N#;A@VX1@&?3WILO03^XAW?*222DYGWKU<^:_2+9%I"['[@.V93YAG/I'K0ZF%1PZ+,M'R'Q(^/D2F8;!^? -M,>5O;7<:(]6G6;UP%Q">ZU>Z;,8$AYV*`Y`)!ZAC\OXH4_819?4N>UEE08)_ -MM5J!V^;1U32:BX4%J`\VI?MG/@4^%:[0(F(WNLWQ8EG89516D^;C8FAO;>,+@MNH&)-N)2=^`W7\FJ3?&1<(U'HG=1G%`A":UA.*5P!'PXX1>T4$FAU -M_I/MSJ+W1./HP?\R@34^?O>W+M:GJO-T-0IB&&^(079A)9`DZDTZT?RCXW:;DF67=QA*FZP.#+5A[ -M+:M:8IPSE%A_92)]T?!7!9,RA2^(#[_H;$#J< -MTP+",3WHSVRX+&K3+(W(KT8+!GSBIZ[:CIH/1G8H<@_U#"S@&PK_$;+!`@-36Z-K( -MQ,?V,,3@X-"TR,#$V($K[T,Q`?+[.`L($"@0,!`X$$`02!!0$%@08!!H$'@0 -MB!"8$*@0R!#@%Y0(C`BL",P+S@2`!*`$O??T"?@*:`KD"V/QTG"`;4S_CP)_ -ML"GU%?J+?47^O[I2OQTEA]B?R0X!CPAX`+&P(A`C$"/@)<`GP"M_]>!OG^+[ -M6`H&#`80!A0&'`8D!C0&0`9@`/_6_ZC/Z&_Z$/$3C`#P,_4:^HW]?)]1SZCO -MU'OJ>_5,2/YN4H(2-L,:XUM;`TL"^&.3'_W$#HU.!`Y?;/]Z.'B -MR'YN:@`'\MSI^-!`_ZA@_>GZ'7V;`$L&>*WK5]@OOX6?@#_.@8/X&_?OZ('X -M%?B78`E?\L`2SA_V_ZR?=UG=/&.B?^%UYP;?'!#Q%'\U[^Y&!Q`$NX?<H@`&<9"X`3GB%A@"_QP:?O5_U -M7CD5?SDA`,R#[;`+J@$D_>S_RY;!_(@N-WV#;?'+/AC+]C6_\IK`"MJ^SWW6 -M_U9;XLJ'\(#^]_N.S@"(`#1C^Z#!^2U\:89^1=`:'D-Q?XZ'S-Q9^#[`$OUQ -M>``Y1]U?&\?]"P+[.Z%/X45`:%U?N9N#`%1XOD2`4>-OZ+7\:)+`#G$;]7Q^ -M"%86H!'=(`5W.?\X!7GZ9]<`L1^-]XYN%QB7/^D6!G\O@C]R`#7?N=]D_&K_ -M^/AAI(/N0W_N=G_#C*^(`M<7'Q9^@`-RK^5^?SGD_T[@.E@`6*ON"]_`?XNX -M7@-Y^C6@$,K[)XYVH!4P,(/M2U`+W_P*O]M#U_*_UH7'0`''$`5WQ$69T_YO -ML`0^`45S\[8M_!G_^U^D;^0`!/2^`?"SQWIN:@`.(S[_L0`ZP!8XT_RBT_1DQ0;OQ>(#("6@%EO$!^#.?B]3"R`/8`?8G -M]U,'Y6\\2#XASQCM/-).W__1X_D]C``XD/%(W]3]-__&7.`'GXR:/Y'"-_$? -MXR67%@_1?F=D9F#\8U_L8V_K#];__,D0`'_^_QXO1``:>_^+'_[&1?8/'(-_ -MR&[^44^,<>6IA_VK-XX>ORKOXWQ]VP&�`:4SQ5/^(E_G,(`$9^[6?QN#_Q -MSD?O;[)-S>R,7BYZ&__>12!$#L8.9*8&[G]M?Y]7CQU0B!`0`2?X`"35W]\@ -M$[(">@-QS^6I'._S7Q9^%:/MM_39`(^9S`N-OT!])*O_O5C`?!5*VAO_@<"; -M6\K;6?\_"B"?\>?SQZ3U[:OY^'&)_/JFM?[,A_)1U6_^:?%_<$G#]G^=)4TW -M]S^UK;S_9@_[&*Y?_>_"/V.)U_:`3^@+M^T`K]K=_V@%_L&#Q^T`7]6E[_9Z -MKU^?7\T___K4A^OU^OU^OU^OU^OU^OU^OU_;\Z8I6SM;4+9UQ7671+:=>^=K -M]FK?2_.>^P2T2"HMTAK,&Q=$@^8&J9'$S$!R.YO\5W3W43TKEH86N-()KZ^R -M&JMF5H]K.O=$'D3]\])S\Q6X[D&@*?(EV7X8M(MOMYHQ*;R\_$T$?L32J,G3 -M`9?G42G#-0:Y'8*<744/MSK@Q?;V]4$3':ONX'8Y*DN0-U"'WF;Y7BMZ0A./+@E+&7S9 -MWIU;;"!,?5"]L(T95Y57J;(Q@*0TS(I(B4/+"=[=1G&8*Q.[1U.8K/^1\H,5 -M?F,W.=A2W#U`%%5D(R]%JP7W=,HO2Y1M7.W(XDUGX.(*F[MM-P/0RF0?CE74 -MO0:R1F'8GO+Q,QRH5N@*F<*&/Z\%6%&"FC+F33;G]]RF8!%L=SJ&OUM[_MU! -M>150+!*,,*#KG@0Z&2%.^A]9[P%4.R/?-C'Z+(SGU/L?GPU -MO(Q9&&\C;W%&Y1#+$$`GK#,2)PC&EQ!A^;6WWE#;+,['XKY`DBW/[0W38Z&M -M`783+V,SN.LN(0QHTYY628&,9B4V0SQ:W^D)9;IM8OW=2(GQ7X(GS:KN@I8&R=N9RD" -MM(&!ES!ZK$G)7!S@98A?XFV5.82IN.%9]*6[EI"+T-P7W6:W<,FQL*(7/NJ%JPA&FLKSR/F@*\H'OB_ -M]+$A7**EDO>JQ8.D[EBP-AO;W9K![DX&ZE[DE#5P50O:QHLGB-FWM7E7%'2I -M47S:KT91L]B#G-[1^&FQJDG+HE>=1?7?AT`WJTRHDWVD%0<6T=-F0$$U_]ZR -MF^9%WW11<#L%YC*'*HT1]W1569;J9+WW3C?>I4,+=*]97:VN'+3%96R:UP,.X#A4%#.).XA2IE5Y!-DU;@6;T(3 -M1;7>7M$X2Z9[Y#4'H@F,R^+".YM?1Y%R-WP@1#N4@(U<5"O:Y\:(-*#R>F"\ -M-[O49H@328VG>?G9FA*NVEKW!@RL4-?G3O8K>OHHPEU!@K))L2=G:A&!7#@? -M;%"WI8?CZU1IMDCQQANV@"G<8%-P(\$DUIQI^EFTY=[7-S<+;-=I,+7Z' -M.K+.=G#%41O\X&NF*AB3^X<\*$=46_C=23CO4V;H'G9)RLB@'!ANQ-^E4*`P -MIN:2EZY9@&<#VN=0-WE2.LR>:5]<(=_T"H@.3]#'O>V@0SY6=?)"ZR/Y9!!D -MD!8^6]F9Z8;^L3]L+I:IXK/A7%%8O1^;I1F&&ODEV*1P2IH)D?S4BL,WN5Q' -MF"O#1G[E.I#I"YGA;B$E*8(S=E3A51/G1Z>N>!F -MND.(:O3^.LM45-/>9>RSF>JW#R(-7]-YML"B^2&U/59#YB94Q+;*!VT -MG0[)QBB]C9MA:P6ED\75_O!.[XKEAAZKOY1^RK:=G*#$6M6_KS1:F'WB]^>5 -MD5;FH.+"22/P4R&`9H!X2[OZ;M\MDE6"UU,.1OES;+[@?IF#-R9R>/FS#Y\`F.C:1<'N/\:;)43U>@ -MY;I4(=]67O&1N7D0L3[E#8,_1B9SDQZ*^B#,H*N+=;0;H[&TVDP!'V/H2CL?%&86&1X@2-14ET69_=G8 -MJ8)UC6;`>UB&0%-%"!*,Z#MML02\Q*;U4/[@F)X=5GVMJ0+'D9W>0F5ATA0G -MV$I]0=U/>AQ=OAV=*6/<[IFV:XYVW4SEP%[MB:94PLH>XT=T]:Y6N45IJEX[ -MZ!2%Q%W.)+/H]3XT^^-.%JEA)2'Y3\R\&*ZD"SSB)_*M'?MI1B:(QY.5/S^? -M4YJ.CVL'&(R])ZGCS%'72,>P^CB",$]\-:4)80WI+&3%B8U6RH -MMCDK/@WADAGK1T=(,=DWU*T^WGYWZM"!7%@*S_?R.J66*E`*;8V-Q8O98'PT -MQ2N5U6M9@B,$?2"Q'O@_4A`W7@W,P4R`4WR=OU8R+[C)Z.0O^)-U2>OO2FKM -MZ&!U`R./4OY5!KE.E(G+2'N\FX8BI(FSD/D>[FDN?-?9S!8=#S+B'<%_>C;UC8 -MG^"EA59:2W/WV6<$;G.$^<7I_:I!80=JKM/,2U]MCB:G!T9.Z:#3>AI-\U>P['>L5#I_C7_>38ERU1=U57XCIK'38Y16M.C@ -M&H.&\N^NFK\;D;+5L.#*G(--IJYF,(![H$_T2*)\'_/LN7O,(S&-BIVU7XA# -MD,/\M"_5XMHDI((>86B0=`J*W=RB,%UYF`E>E'JBKE.Q2;P_;F"5YOMD/H@Y -MZ<9C;M8L\\%>*Q_.6T/*C@EO]':LP'O2-^8G&H;P3;03^-=[)S@Q"E) -ME8+4Z8[B=&#V#2+C/[5P>JPOBO>I[6'<:%4LKB7(/)R?(8@T/67"[0[(3RM7 -M%WU^M\%9W4KLNS[[4O-YWR:=*CIOJL2&EB!ZRJV$L"OLK"P+W6)AEZ[?=I8H -MIS1SVK3R=.-]PP;Q:HPNQ*CG,,Y!IEZ?!#DFK<5F$('W&J$5J*O2;D^CPF:: -MZMI37)%X18F^BCK&4=HSY8A<#_I:Y00]C;3D4*)GYNCK(EQYL7EOT!Q>/ILU -M-_VQ@NH[3L2:N^'/H7[D%OLX\SQR"&T-B-@J)"\E>&O=)4.Y,9S\:,P4UL4\ -MNF.!`+(()`PBU\JT[4O<)U+,@?M%6X,WZO@$@=_5 -MQQM(LDERMM;+ID^[O,CM:,>'>7ZY8>PCR-9669B'WTC$!S]TC8IYN64Q+*T_ -MOPZ4'F+`+^>-R>"KGP"M=VS0QMF#Y/AX<]F&I'?@4>7LD4HN\*DSBBP=9HV5^U3)X;U:Y9V=3T:BM]@G:^TD2462,>A^GT!JQ4B-JJ75`8LB -M\SP"Z+8`TY]O91-WK61F=EP6:H\R<]%;]Q86R13(&?>'Z4T)(IQ;&-:W)2(3 -M>->XF&%UL&\>K=6+/;_)/`:]A`5UF7KDNH^E+*'?E[G/G'+ROM!B%W'$5ZW* -M@D$>I8`^8Q+R+H9KL"-($J@-G3%HWQ2H&/6UQR#`(6Q&TNC#1ING-#?IH`=_ -M/C[S&".:@)(M`%*@7OPG@))3_8"?9$=8@COZ^(:J+!!;5>#87=AE6.?'(*QQ -M,\M\.VT4ICK*LI@O2JF,+@\F9"D*+T0H09Q68V+O5F(G3*9K*^B^-?-R8QYQ -M]*8>>GS41ODV!D;O+C*E2U2@15S+VP6NV^\%N,0KY(+%?626FV-D9BR01')S -MBFNN/5?+NB:%;`H6-6P=3E1,YT\&3/'T^,S#9XF,U3R[#I&%3PZ'&U*O-8Q@ -M3R.S8VY9U)!.3%##@-A08D8"4=R]E5$_#8)9@@,;62W#ZU -M>90%]7"O9?(I0IJ:*^^VK3`_[<)D]FF2&NX]$AWP^F'R)$XQ]OK&_<>XI;K@ -MV^,3=US,(78I/#.%F4<)A/"XRX/)P\V"JD:KG.?7>9V.:DNFLUUCI_1OF3K,D:C4Q1DZ/L6SXKSE)E)5Y8:2L>8%&27FH-`Z[F?&F>Z\'C[K1HS4Z]CU -M-VYQ267/AV\GOA%J -ML\OK1]23"CJ4@;(G5`_C$S0%V>(6(@"Q-C-XC=9%?WMLGR'YJM!@F6KX$B$J -M%R[&:C!"XF*3:(0BNM;WX]PX&Z/U")EEO(4).[R'.>/4?_#L/G]2-IE^SZ\Z?FMPSX#SJ"#`14M//H^)G#[5:1!ZVS -M,M/7H#BS#*,=K-4KIO?'*MZ2*279 -MG_DVVDP7N9!,0%5/58]QJU;@D<=T)+MS=H]<-X -M")GCN"#ESCMGW2>[03^->R'\^?V$_TN>37[EGD13&TY[VU(.=H;I[+Z,LXRU -MCR9^-D1J#C.BJLYMDGW.:,2I!J20E::AGHBF&*@\-AU]^U8!JB<>!*>OH(R&94R7?V17/3A$[FGA9;M)\UK`ZD6-4FI0,T.N(\$/KC6X"XV&Z#X -M-D7![3FJ/KFY]R7)O3;;`[UFAU`T=.4;-">-Y++I2".RN7I4%ZH3L->&O<7+ -M\@*TR^=ZBX2XK]X$KJF#I%SV[Z1>H/DROVA(.5F&#M%EJA.98+PF3Z#1-1_1 -M+2E`<"0H;'%AIEQ@]9-,890TH&RO'X9MQ*Z.+,WADBUN9FPJEV=`*[+93>0A -M=B[R>NMPQX&.%`>I.?P$8@L7!$DU7T*H6D="@.9!P.ZGY,#:5]S"-;Y;00D$ -MW_]-:BOU[P&N'0'_Q4?JI_KY_Z\P-_8"/Z=TE#^6$Z_OK];_^]_\T_R4#UK_ -M]]?LD/['_.W_0`&_]@?Q?'_78(_:(3]0KZA?U_1P%']L_F!;D"_OGQN3_3HW -M5]D/\`5]1+ZD'U/?J`[2&97_WU?58MH+98"D8K%MY6DZ.>=,G'I/$$Z&8P>3 -MH>ZW$<*8#B1J+-TM][^WH^C04RQG -MP?4XIZ=Z)%HO#&?OB<%IKUZ5K7E#=6\1(J>RDY>P`AB*2D6@`RM)SKLJ;S5(<.G"/[\U+3,"4]/*U%S'P/OL -M;VI>G',6<[Y_"@2]ANOPM(G>9TV;^DUU6G(YMEY^CM-7JG@6T22ZI],N>SZH -M:O_-YO#;H=UU]Z(9K7L\'^YQ798`RCM.?9WWS'WXBID*`H=!;(8YLS4%,PK -MU'@@?XT_GMO.YK@\XT*_Z-#!1F$S3C>8DW@F.(U/@=^K^`I>-W4U2'EA'B2R -M>O&T#$Y=3>RI+)=2`@78ARC!"Y@JR&1[0C>4<3D2[WT@ZD-:Q\7YY;2&),

    _AAI:TCX=^9]9E0<\U6KS?'-`AT#W8E7O,UN:RZ7<>'29?J+5[" -M5UK2XIOSEW**=-M[);HB;4Z2+TN^DSW!"&Y3[8FS"`CL=U*1%:&>\PN'[EQA -M(+%G?YF&A[U+E1=BB@:KGY.+HI7TT>PP7]/ERBAMX5*H59B2"+?!%M9T]+J5'VSV8Z-\Q'P*".XVJP-F -MQA/A("$W:*>GQ^>-8A%NN6[GM(,UAE>XG;>Y:_*W'_TQ<4K=]A6D:J6:3DE3 -M$%<[V`5UB_\,U?W&]BD&>* -M;1:*_=`ZR&]/7WITFH;6>B\)5O?/I"US1#,9/K[J,O&J<$$I)^ZRC?;&,7+= -M'-J59=GD\S`G[R(U7NY)G//N=1'N^FENQ1`$E9`';;VU9[2"[12[FMQ6')"E -MHW!6BI7I-X"^^I/J84G+*@W]$?&1,K>]IZ5/35LH^R2F4)>; -MY88]F8O9-*7TL:RIX"!C.9\=JP^9$-`05.P?V-/M]Y-<7;3$<.G_S)Q##Y -M=-E=\J,)>.V5+-44TXC-PWMA`;@21,66FS7(FR5"F0K)B<=I;0\0W>D\+8MZ -M8[%0>WZTRQ%V[X%^R:`L=.HAC?)FBZ'FL4-+4DKIH)IY>`Y!,(PS,TGL3+CE -M/;(6DWM2)3*MAP^T<,-6IVNBW*3\1@LR.5&>_+4T@R2L -M4W-O.Z%)H3XBHQRCK(.@6[KT@[8SR"S7G#K[1Q[9,AX-HRO>Z3;8IH`)"A[K -MY#MSXC5P^6-RHF/6JQ4E8Z4&]H,M>LE@2"H@3^?]8.5L!,5(CT^G(?Y16] -M]4E.8Y)I57\$]'6X$Z]T\';<`\7#0KZ@V-&KFGL\WP90KW]BSH*SD)>:[F^O -M-V_/Z(+C](\W"!]&VTJ#6#73!]@W>`WA:&29KE=$H;-FLKTF!LW7PS<_`_Q2 -M<':*VL[1L'PPD1`)$WBI[F:&MDGX+*6:Y#;!88)O#0VZ:Z;]E?"CC_L0:"=> -MIWSZ.&S-@\UC#F'ZXH!HT*1UI6S'*:D*P(:_EBY>#M -MQ];-#0D01;)26,9E=R\5`>97N5/L=E?Y,W=;;E:I;NG&^1F`\/PI*?!LV.U? -M,8>K&7*.LWI"2INF+V!^*H>CA]44LI]J-7`E7'-44"_ -MJHTSRG`8O^?YX2>R1;2KZI/-!_PBL48^$;(_;/9?*1&$Z&!B7.UM$D[4RLRZRF>D= -M0M[ATUJ&1Z".4UYTD:+A)6431(`C7W&Y$)X@S+.)6J/%9A4&0JR*\^IS$>T' -M)J!VET+_?\=%G#7>5,(Q8G4U?(S@S+1*#V$W1TY&Z92*;/'YTDW4F#AE:E1$ -MP'QK,T3&WGS.74>IJ!_0F2*,7*!0RKFY)_1=>)-HMGO$]N@$SP)+$^$22!2+ -M&JW;,6'OOR@K'C$OMTQ1_J!%(?QXJQ%NFZH^37F*\DY<>@&15L^-9"^?NI\] -M*T5U&>+>R*_<]\1A&QU";_-@0["E8YV_.CC)N4,ZVZ&.&>`[(A+Y*Z$D.Z#@ -MH/:DP/AQ5_%7;/(JUHWOJ;9FX,,W^K&]+V%2`^'UD`DQCHVS\%#N9\NT! -M<<]Z^6?!4*R_1=D$@N9WL;DL$HV_)JX6/Z8./A,Y!5\!EXWK2>H=AY;0R.-9 -MM=ZRE+$C%JV!JO4?VV^\BLCAQ-)_PEG#D2;EV4T1'...S".NN''DG'VZ3UEO[;]5]AH^@>U`$`=*4 -MJFM5WT@SV*6H$$*HA<%H%*^FW*`RON^NR)[$0>*FS+7`]-<><5%[JI0`99^S(J]+UJ_G>OT7>*=%Y8)-8.;Z6'X-;Z%_-G3^EX;%^&PE -MOU!=&6]'.2^9%\FC?'KT/WZ%O!T;CA'T]VP1&%&$7=/,<&1J\<;9*O/U6T4+ -M$1JO!7,8GR+3)D*L5:AN,,+3\#773)N -M/Z]2`%HQB/LXU4K3=E8^ -M*@)LL5+/4YC>AE<YJ@K[ -MA.:%7\_H'*G'0'W'F+BROQ_AJH.V%7G!H(IEU@`RNT5UQKCK045_3\]Y(8ZG -M8A0EYBYDZ_/']`AK085TW*`]1$;X9@HB9-:`$.+W0'=#4[D#TM/.3$MCC)?O -MM*"J6$^`5J_$203+9'-11?*)1-*]EG(^$92@L]X)>#7RN&6+EZ#N+S[$KQ<,67M+68E,"BH'R>:K:T)L;S")$45XJI@HF=W:^T3Q_$ -M3B52Y!EPR4E;*@C-]O+'4^GYS;"833\^:VEY/2APY"S^M:\.-[[HZ!8R<8G) -M#@V5[3HRU5]OE\QXDY-T''66%!$B,OI@8D^:KAC2S+Y-YJ"ULME-DBN[=-@N -M]U?A\\NHY>`V=D3TIS_"JH4*77"?\[5P/I2<:]22F;OV6S0@NHV&3YO`IR-Z -M[]3.3YJ!UJ1KJF&P5'I4&1CX1^HLZ(4#;>W)$G.>_+UB?NK#0PR0K=6W,"M0 -MTI!QJF)(N\UWB:QH8>0P>;/J0@6#[)=TH7KS,MFUWH<=RJN.[IXO9+67G^CU -MU#`9:TQJ$4LX_MRGLD(OIGIEU-`V6;(@.R[V_I4*6F1*WH%PV06CKNFTW[A;\T8J;A,.CR.MS1=!R*6YN4F*(EB"`GE$DL%/M9MH5P;<&_YCK -M1KL2\]%/.H1I\XB;D):4L4ZV?E)$N1"XKHV-0S4FKD5^9)*MVG4J,64[/'G/ -M0._D+`,R]@9Y6?UW:D2RCMUYX'WSY0T4,ZBN8SVSRJ4SU)W&W%[Z#J[#I_TY -MNSL(,?A1#XJU,D*I^-.0<'C#ZONV%5(YB.-U43K6'-,`6RICVV%]5*!&?YX]?VU2N)CP6OF=ZC*FKAJ70CEP]QE/&SD4(QD/; -MFD)A3<3XX;V"FY00Z_:3:.7N$C050TUN(.P6?QT)A^-(8B"L"#?-*(C`-H[=VGXP[R(M8S4O -MBM4=A5#;+20-19'%:OR9=Q^4288'#OUMK>HBM:@^42-:WT)];HJ6<&1'RBN/552C/QW/<&JI,\]";?! -M=(T8_P'9F6!S`'DY-I?,",BZG+$P],<2)>L'2*@0AR;VTW2AH&GC56PK46K" -MZ^XMD'EB=]V,JKD5NBZZV-`3D'(PSCZ248'Y?O)&BL[#DC^:B>GUB&?)Z>2V -M@%Z(;D_;?3T7N3&XD7BOINUD$D+EX1`\=O89BSTT.K^3DCUSEH?OX.$I$C(( -M\AO(!#Q+!+^.:8H3-D7T**(DLV(2P'Q)9GKUN;-@Q;G[V.1'H8NTK^]LO3Z: -M8C+/LP7$51L^8\8WF1GX0;./A7$09C+:4YT0F'&!>#+C@LVZ;,J>^:+J7358 -MMHY=\U6JWNP,X>2E^XK&*GL+I+W4%#0UM_`W-D1OFP%IIL_,_6?U -MQ\X+0RQ2/K!IY'Z&211UP,O*S66E3J$8Z?%E;0(15`%_;MY]SDK:^27-@SO# -M%:HAN^M@&,]'/.F=GI-:R2/4Y!,HP/&U6:(,,I)%#"!'R8HD6>[S8D)>!DRO -MCO>9<4B"?CSGWRO%Y;>:H&(=($"VU[7IBH?DXA`4K/G=)25+BL8`H>]+SX/-E3!U -M:.T#?F=,;%%;;.^<,':T7;#]V"(/SWQHYFEBQ;+6YR3JVHM84;WI!,EE-"RS -MR`]I!)7:WKHG?2[O:&^B?ICL8B>+VMZ-8@G'I.WHS#F\-SFF$Z7W:&&$L012 -MCI_TXR'1,UW#A0WGNFDRX[MW6N[=#`37?*M6M?L2*<(5F-X[[![T6>^(I3G@ -M"RC)O)/RQ\G[=LD^O7>4=HL''D-SM94RQL')&@SU/OD::3!T[^,EZ*N,?2VQ=1LJC3C! -MB%>KOH4,JB8O6QF8+S[0G1;0),HPMOEW&FV0G'FW&U')WE_<++ZTV/291/4\ -MI+@EDAZ+D=\R%7`4@BM=R,JW5@]9%K0G0GWEAV&@R[IJX[-D?ZH$UIV5!+"# -M6--V+<0?;2O7-S3<\'.O8_1WI'"&;"G+]V_LQL$EMZV1K7GK9,1M0]&Q&Q3B -M3#X!RT:?^`G/U"KF0HX)F55RQEAJPOIR+7"/,'WJN-BAHYS3MM -M?R9B!$E`)/+J@B@ZP+KP+;PARC*N*NX*/=BD2;>:)LD-3U1?FP$]F'C3(&XC5,/3/,6N:F"APN=B3%/I5[B,5 -MX[HRL%45ILV4I)KBKQKV4'NKU('\I69+O%D729WD`>>(;0Y1.D=)/,5A.UGG -M1LW"K##'[HF(Z-FANUD&=(?.,!9JJW\X=9-DO%,N.=9U,*/,8E"5#`8*OFLD -MR/&RMIA:`,XR6\"FW!76*3JH;==.;X#&,PA'RPR,'=K'Z)(;>#JKA@Z#&%&> -MLQDNU96=?XR[KS#F1EC5KZA3A"E0PQ&[JM[K1`=?1\\Q:C-Y$\J3WRM!!&H9 -M!`Z%*+OR6)/#V4N:/%C7*!2]3]?F,8.O5296TH`PEDRC>V5;2UGGT]M<7/4* -M[R0T&Y^\#^;`D/:VS3B0M_T9B[IE[CHM?:!VM0?7]_KEEJ'-"[E092?97N)W -M[3K54]N&;')=\,C"V?ZY&ZVC3X28PC(FWUMX/T.^:'A'&D73EP]2QO#6P(^2 -M`8Q@,%=%/HO/H7Y2(^Z2MTY'?KX&F=RV0[)Q:3;RD=&6%IU[#H@>1R+E=BB( -M%RK<>D1H$HK6AL)J-(C2Y:$QV7-262EC:SV:+#X5D-!_1!IPYI[6C[`FE,.2 -M(7@TSAWZ38%H!58H\TS8EA*!<\&L81.%>7N47F>8]2IYF8&36K[#P@W#T="] -MQ*?(PV7@)%(R#>!'A]#7)/_B;F@R0WP)))CV"XNS/GNNLHRQ[:+ZH1D#]$5` -MDD]01%WIM83`A/##WL3IC%^CY:RZ"= -M8)]9K=5+#<*X^O&T]#OO>]3MS#*V9IL/?B/BM -M_.,8Z5-ZCR7'M&QX[?9A1XR?':U05WJOK&O9>;LOYH_:5D&A?C%YZBSZ;K5GH26[3[R",/AC64/(Y*\PV?P$%BZ2-7K4STRJ[;/;BH(856Z -M-.T1G*^L^$BP9Q-A#4!R2L;%[\PVBU<]2U'3#.%/,2P_?-V=9TU+;.#R`QVI -M[;-'+%IMQC03HOKIDZ4EV#72LZB$E3#$6X)-YXO[+)"F(?SBO288Q>87N>-7 -MK0Q13\-=0-`SH9V"B>-"-?F!OSV9ZT.@8=88%PW_4;><^Q3>\,GFM7\F/M3WU,9-7>^65?GZFV?ZS[^!=UN;!TMA3"./E>B3P)G:/DIT2MS&>-.P1T=BHN;\'88OL1A&I)2F"QN>6!S"^)S!- -M>L26;3_>.NX65-2$K1Q]@5LE3,*%DPL]I!77!)>]V3N!WB)"\*9A@R_^NMG% -MD:'@?T?;L,I1.B3>E8H(N#(8N>B65P/*MK<.41`2U=/PE+#Y6>)UO_6=;]CW)!RP<8+3!Z!T_%#WS]V6REDI9[:>&CBSN70X%EZG -M?=4KL4(J9[V%8?C)98C@9@AL1Z#89]Z#Y$:ZSC9FU^A2KR$]C"NEEF2DW&K] -M`P=P[Q_`'+D5IN*9[?\R;2,\7=M_@0^#WXQ43>E-YS&$PV;?-3E?=F.\490V -M+8N(^'/NJBNB`MT7]^6&?/JIAP.UY"W?(PA3M_=G_UQ\Z,P6$2U"\`]7("L@ -MV0MI>=?UW!AUY4S)FN"J(-S*;!RHB:5]Y--*++?76]A71VQ)(LP7O![:V$3M -M408!/C3V_A.J5&,Z7-]O(JI1TI)2'09+_\Q)R%<)$OXF$S)*$=OA(I)1V6.9 -MQD$`48$1I&C4*S7,S3/@S?'NM$+[JP]^&&"3)3.Y2R#WIIW<>^Z_HO`[.:X-GN>&SUJ%IUOAS&; -MQUG\),0#%/5UGFY#^X7LQ4*`G)E5Y,YPN9W;]E"M\,7406<3IW]@"O"YNET'9/1Z9P@B\G75N\[RT%6ST\7N)L0'28 -M]7\J;DBLVMU0-'6E^Y(8OC[0;#\-#MG'%7/B]R6K[WCY$:_*:7B/'.G>R!K0 -M)MYY7E2(VD=!;];G;3^=`%X:4P5"E$GGY?>#SG/>X!-]0)(W5C61L@9'O5#2 -M8CD+\JDOQ;6EL/P-:=MXEPD-36@.7G:>!D,>NC98H5'Y$/?QJ92J@RL%`0Z+ -M4I3431IXF[DN?C9N_A\A6_ZT;1"3A1S.4=FCV9%9.DWRMF[%HXF+7S#] -MJ#&FBL`>Y:QA,S*=0.PRSM'L)?/ARF]N`NYA^U$Z#)!\,E<^TXR)N0T@J]!3 -M-VYZC?<>MYTH@=G/Y4K-E)HX+Q[]*Q3F)>D4!.`;U]-CX -MNXBD#K-%D@;M5UPE5IF%%-<9%B;D8SPF*]%Y7$1:TYH!B;C9NPWMJ("&DY]?Z#U\/ -MS^&PE1Z((A>T?IY?L_[]\\YYHX>>[C&?">'Z];A[W -M26^$G&//H;KJU&FNVX\QSS(.5)YIX']LK=KWA,WK5'+N?"M_ZM]Y -MKZE^_L+@O&V?!,3D; -M\<)1YSK=;GY:DR'1F="I\M]T4Y/2UZ=OS02W?Z6?UUJX$1=&7DN?R9G^-3N7 -M?Q<3^,'Z.=>NJIZ?ZQMG?/JQ<@SN>S]]N/<#?Q-1U,72:_ZM?N]C>/B_KH]_@&.>],7BWZ/19#`6:$[=[\[9Z-IU-?\&PZJ\:WWG3_%GM -MMC<%O3TAII_YTEH][P;_[.!@=?H])`^+$.4)O.RU:I32==_M8CZK:1?8UO!M>-BWN$_3.\C!S?A1XC+]+NP?@RNQQ<5N;7J$?2 -MLYW:MC3,77(^ASY"F,YG*X?(O3=BG_Q?8^.KK=+_^FDDMQ]&(\NQ^Z5J'C,8 -MO6Z#N)G.5?XM]Z_,[;U<_TA,EO#[1_&P]Z]:-P=;KI;)UW7^?5BGS,?7XSMZ -M^+0_'>F,9SY=W[.M?E%1(62/H]VT?'9=_%Q6FYOCI'37S'/F:.:T7[Z?@;J' -MM-RX^#Z65L[U?TCW,)CK=]+JW[[E:-LU;%%SKBHDL-:/%"):;6\7:Z7L8 -MC08_>]Y38T&+CG:T-^P\'+\3_]MYO?%16U2@S6`R-OJ6OI42>(T6>25/)IIR -M8C^YQ,[KW6S:7<!PW[X=IL?KP5BPK%KVC<;2T1LI:JGQ\;D^B -MU?<\6S$^'ORVLC/_\'.YOEM2B1ZI_#=OI\-Z^JFQO[-'(S=QH?II+CPGC -M;1T[+S,E=O -M)B^%!9I5)F,-=H*(V+Y"_;;]5L&//SG3Q.FD-[D/+D.1[L%T.SO8F$HOZXM- -M4=[^=-Y>XEO]ET+]8_6G++=[;/]K@9#N9>`X7P\[8:?`82+_/E7W3;^YR;EM -M;QJZ)%JH[X%._^7RGHFHQS9;,-TY_]^;\F&EY'D]U':W -MBZ9)0XE/\;/YTLN^P/F=]&W\#(VSA-.4@OY8HWY_%=CGC9[50977/O<1O%4) -MIO,\#T]+W+G*9O2V_#Y1(I/926SW&V\+K.[MUB>`]0UZZ/\7#0;#\N6V_UI9'[--]$OSG!S;;1T\8S5-\ -M>OSI>1=_#J,E)'/VHO%A);Y:C47#RN%K8XW[HCHXGBQMQD9Z@OC](9;(SMR^ -M0^DT/$1]U=IW86%E=V?\>#B7B<9=A0G8VJ:T,$S/F>9$<0;)A -M];MEP^].%^9`MUAR\CE./5\._TF`MU0(!NZ1O&,/,AG=84/KMNZ^^:D@OAN[ -MJM?`Y?,$F.`,^1#V_/[KCGMZ)A%[`L0R$)L+X;=1D[OI;W&$W)B-)N]D,<18 -MN"1Y&Z$C&N)L60E(W?R,2Y-B<31"A9`1D49WNOA+@(D6&ZYR)ADD/!$(EV1Q -MVM'_)5$%ELP*%=8Z1,4D@74R1LDL`OXBXC>$[/YA"8G,*@OS*93 -M8U;,QV(B-4G2U%&B_>(C7$->G!W-V+:8!E*[&95_JTB)M*3(?`WJ_&-Q#ELV -M7W*>&>96(WS)YAYDW$19RS<4OD077,'L`!,L6T$'V$+A8AG!(TJQ_:!W=G'? -MFU395%D36MCK'V."66G!%,($E#=>K]K)2;!-V]@D4+F[6_$C]T*OX>=8UEA(5B@B!C?QX^ZK=_%=@4F7!%8,!(8<8<8<8BYAR/ -MD+*.NGLSL2N*V[BD7YN(#W$=Q'<79N4'+LN+NR18;(_'34K/B,B,LX?SY"RD -M8,1Q889:`Q(,?.PKFOAG'U>F^@^'\`>4G4:LM8H(")L8\;:*O\<&:`3P4#H# -MRO'/5NI*R58R8=?>'&=D&9W9E4,:,\B8D)*T%#0[KFVAV/HV5$R(3A]FX".&P+.-BX-L?UV[8!Z;'9J4-"-G1'&^ -MK[>$XF\=O=P;OUF4MBAK1N%M(+,[MQ)N&M2!:3V),9*4GP#@LA.F$Q(UY()5 -MY(T)&O9%C6`-PM82$*T)UE!\=V(DY?CPU^=P6X_,_LJB1$82$#IA1[\#-2PA*^&:2FB' -MH#XYA23V!:Z=H(6H:SP5DJM_L8\595-D46-.TIEV[@YKOVEWM!0OD&9$9DF3 -M1"<9E[;,_,:@M1A<0SAE,H-@@8Y=HK5A%G&E;-I?F92).[6ZUE[J"V-_0"3) -MT*3$@X3::\>27P&(>T3F@(0)##C#C$7)EF(3X[*1+<0-P*";AVYV;%+6H:DP -ME&.'N"'MI#9B#<$4%)6.'+F!G(;$.S$4I;E%F3MB:O -MN;.0V(BSH4.B2QB-3!7$3*A9$!:`=VRJ_,%!3;5MMBK(C:T5C-J-,Q$BH$?B -M-+#=(\D^$&:#MFSQ7PR8I%WZ#ZB1&K2Z2"H,H""Q3IE+0WLNXQ@L8"0PXJ6U -M=AK`&(_@E'*!F\ -M$>.2XMR"AEG+46>+4"P.XUVB"06,*L+&.*J@X=. -M#%V7"YA56\\0DT9+@?Y)FOAN%M6SLARSK[U)]0R)S+'8E62Y&IUN7/\Q+#]F"%-?#.-M8.VY:R*;&H:4[.F9D -M9E+Z-6JZ:^@0/'0L-:EA%C6`,X6@58><;PJ9`E3>.W@JNNJ.B@RI(T$<[A=V -MD9S@ERKF_NE5N[F.<;[`]UMU/[*6FB*W$&A!CS0FPE@# -M"ZJ`F,.,1Z#D,^T%H&>IV -MTA6$M0Q^"PN8U@#.%GA(""Y3!< -M+._5UR@NTI%!>0PK.-A:2LWO\ZN?O+^O7NP66B[%ZB-4G\UQ*`)G,\44YIZL`9M70/(^QY!A6E> -MQ:C$AM0H2_((AKU9-'H23Z="0^`B:^&98$:B%I':"#[+(H<+96;M85"@NM2A -MC35UZ(E(AL75MB1N"8+.,AT9!=/F'FC82PAA642#^R19@P>X($*?V(LUNFD( -M/@TAD@+G&#F,.,1Q&L`9E!3*.;4[FM,0=@&/_A-J->T+&L`=>ME5N%&,#F@! -MFN80+V!:V;&/EF%BW-3)_:1D4<0-'T#\I@\]D67@]LA#8R"=:AL$`_]@8I-- -M+"&*TT*EM:L8A]J!JVOAER!_/UZXK"E34$%FU(Z*BKKE@@[8#(:B*DJPIJ&5 -M$6![%2E7@SC2L]IBJY1U:W(H#V?^"L8$D"B1,!%&#.4:]U\,M6858-H'-M!. -M"N.ZVT%K"C0`P_XC'EA#,K^5\699L;"&R#KOW+[":&7WC40M(X8<(HG(8;EM -M#!,MK\YJ;2HM"=P3%]"XA.-#&,T2)>%^IRYU71>_=`I,N"1L"`7/GW\>:^XH -M;?O5B7Q&S,!W&'&'&(NU.SBI;U#<;T/2STVO6K5`Q -M/W5S"MD87'440BZ"J*84BC:X@3&V87.V$`HH*!9GA -MD%*##W(5R7;S%?-EX3%[[2[!T)C:QE#O^E5G-XN[$YEGM6BQE&P@K_6?QPWI -MT$ZC:4Z7U7BCRUPMN\Y`^'`*[T]A4_>)7HJ>AL&1R/1!B&`U]B"\L# -MF%B8A<,;'\-C&#J_ADK\(BP5U$,A6FA,1E8<#\#9T\_+HH(1?A9VEYX=D+)8 -M'N'D,'!YD16@D,*#V]D1@HQ9SW$K\D)>54L']I3[%K5P:,;J"=<6D@F$9_)[ -M%KE8J!A!197R78Y@8M'#0H95/QI?7Q;=:\QO7CQ6=A-2VU]&K-8>!1YX+*2N(>)SB\SX"8%DM?KX6ZPXLKEG*91[RAFS -MKZ@S\Y<*P,T2XC`D\6VM:YT"D1$D$+5G.E[.[JSD -MAFS_5`$@2^PXLF#OX:MPPMFJ+P[C80D$6_69O+F2X,_C97++M5YEQ!]$D%%K -MR[*.MT$7^5!UO*Q4%DW.,PD-U@1=5B5,0@2$*4"2Y6TS$76.Y2(RH(,9U;"*S -M&<#+>7RE;E>ML')=[G(7U\07M$LN!AU&E?^TO[P9`@-^AQ2(P;K1C6T$B%,9 -M?S#EES$4/`=2^S*",H$],=<"!D;@.T9-MM!J8_M^(&&SS7K$!9K@+1]%+\ML -M"EZ%**W:`>GV$IF%LU,-QAE1$&OZ+,L<,CN6IY$:G>P(!;\N&P=EW@.=]KT< -M-<3=H`V-:@BZ"RC#+C9@84O*X@`ALJCA;I#YNZ9VKMT`JNA:UFZ0UWNE4F+O -MWL.\4N1#LX7_\"H%/M6&B8G,Q:,W-B>P2R0[<>>T3&-A5Q$6O)QD0$-@]Y_ -M;]CJR8O]@L$PJ#/PEKWRR\^*L=?Y.VO8W]@FE;7"^AB?RO= -M')T:FJ=&XF*BM$>M_1JJTJ>$Y_?3JJD?U>B#=*A509+^N]XFFDJ6E43)^N;9 -M?F-\YS7=*%H63#.ZHYQDOO]YM9)K"G#FZQ%3Z*6=>>$I:YZA4A_@_,='BJFJ -M$F!!>O&4*#*JXUDCS0U1/5O>9^]/;3B_E*_-@>&\S.-=N?MIM1>LK\4_%1'4E]RFYE_IYZW -M./!PL!!H^XE2U?$W,VLV!Q:+8[9/LX[J8U\O%T1;2YYZSY-'\_NSO&3VET[O69]'U -MV3?(,IJ;=?>*,JJ3JH[4,53ZQ49=5%TW;$J5'#E15YB#6:(-*9@.57U:=%\U -M_SBR:L+5@.5H-@$U*PQ.!($%A0;"R]U`0<.%%2!>6`L\(J`N`^E8'XK1/&(@ -M,ND@=%KUVP0W$_)TO9;?PB`,P7=;X+O@'8%%^$5`=2RJ@QK_ON"/Z]09W1`- -MY90KK)W,UF!E3-9L:\8O5E&!`/>`WQ)+%$N<)0]H/#"NQYQ!W](\2K9T'-^)>`/!#_D.+V2SI@9NBG,E*@'E -MQ*>\(Z`/_::SHAS^@?-&Q/D@1H2D/O"YMP;X(S6IMH) -M=B.I+T3NAOJ.F$_>)=J4B]D_6Y6TP_B'^TE_,&?2/MBG?DNX!WV(\>2BOGWM -MDL<4B>G,4I%(IM"'E#&1G$!GWE(>UOAN$4VDS:RW9S-:Z]N;"7$'.^&9LZ/!+QQ/%;^)+. -M$N-#GDQ],9FT%?#I*`O.BC"7:C_..+?>F#(`S7/FU#GY`'^4>]C],S75N\%* -M4EU)F;-3Z0LI+T%:H%"S--"WO -MX,MH!L9PO7"`:ZU>XK>:.*98DTUITRAM.K>R.&N8<&9K;4+V!_[ZMX0J;DS6 -M]I$4RAIBM1IASR%O*>$/Q-5]^MF<'<:?^6-KOT&Z73: -M;<-HBH?)3(T/P?A]R#O2T-M.-^"JS4WCG;EHGU]UM1FM[M,/,7J+J-7Q\/Z^ -M8(IJH?Z,>2S$/NMW+9 -MEB^N`Q'Q^KG(N]%/'U<7K7TIWN:;<9C -M_H8X>8V^,G+C"L>JZF*]^?U&#@`PT@LW -M-5"LS`65<5FX8@L\`6&&^+%8@=P]V=5)TRT+!9O0LVCO<[;;-,]JJ(&H<6=` -MV]T`:K0@WQ@"TYKF+GJ#1^Q-(X"O*)BME*A\/8M/SVGJ^%/2VX`:KF@;S@"T -M!KF+GF31^3-(R2O*;N6QM0,_8J)*HZK/--MN`&JTX-]:`M":YBYX4T?DS2-" -MKRE8NW2I_#:K2]VEQ\(W_P\7\BWP/5^L'^OCT27JO,O=_>[_?!_Z(2H]XWF[ -M/2N;N3GW@@6"!GOE9O`1+!E-Y*SY!R=6XT@G5M>K#Q;"XKUW^[QIAA2$97]J -MG]5/Z:>HIZ8]1GO.>I3U$>8CW;/,9ZAIV>G\=.TT_6#G8AYX![(/R@(;!Y\' -MEJ'WAH;>/K#2A\?6&P2X#S9L4>!XD!?@!SN`$NZ!.YJWS*UX5M2K;F.XAS;R -M5N`>T`0='/@\:B,B#GB%BZGY,=WX\HVW&X\MCD+TVSGX;V6D/5GJ;7^6+]G4 -MR$/OW+='OQ_;IZ*A[O)S5_YD!LJ/(9G:^>!C\[EH3X;WKM@U<:'T_3F([\+A -ML=7-%\3GN];9^//8_D/D]R'OC).%R-+!]?0]!]R?-WW5_:<\?[YE^[3CV_IB -M-+F]?'?1I>YO.QS]5X>7^F9I+KPNKYI+GI8;I1VL>N;-1G.2J.EUZ"9TW,PL -MWS7Z7_>_(#IQGG])_F^:CHYM32Q%-]?I7*DX-!\_J_6T<5-U;QY_C<[)&V>^=3:>?+=*!\'H -M]',Z/$\/,Z'(\*EK?>-\J/R]BB\N=BMIYM:I]"GA:>@Q7-U7)^SI^#">?G_; -MONMLW:0GOIX2C]OVQ2X?@ZI4_3>+=/'WM'X^U(\WD77PP/VZG8<6;BLQUJRG -MO8O@1\I]O$G[)2UN>57\.#3<[[ -MKO:+:D8O]F-U(>A>T$=-]5@*J@:H]<+`?!#*DS:%K%[01A56@`/J*W:+_ZDG -M54U`U;M!?Q<%E1L7XH?PVSQJ\5-;M#?!.(BE08+J_Z57I+?\86%YQD=C(LDR -M)H*"".HS:(15WC(Z!Z6QJ2S,>H-5;% -ME4P].1[<]OY.%L]]R>)OMION#R>#L^!P.757]!$SQQ4-_ON/_^=GEKV_BE-< -MQ8=LYE0TPWA]7E\^98_+0^1GV_^/6D*Z^1Z[NLKO>C%X^]7YCQ4Q*3G?X]T8 -M^IU.YY;S(K48[746@&JX4/[>T3JZ,;\9O#38V&0KC+A-ZF^WV;:%QSOREFPQ?X -MN1,SPM4Z&;$(0N4\Z3M"MQ5MYHEYC6[S:^2/>9-_HE"B-'IKZN#FXZ;HL#LZ -M*GGDT,T3UF7.J>LNPN"1:!\2T@=>BL#I@DT#]!(5[JW=8"BA%B`"''66L;Z$#Z:YJ>N;0[K=P6L -M6,NXR.I/T4:CCQH("Q^,)OT%!0KWL#D7A4M-3*P1E -MEQ=`E&/))\4CSU?NPZ;8-J/I?4'\Z<#IQP.GF16Q#HPNGM%V+@\+8CD!]"Z -M=8$YAA#C$74G*=C%MPMCQ>$L`5UJ6(OL?+U,9(<+_*<\;%7J/%B/4R>E:59I -MTRV+%QQD5">Q<,8"V4+FJRH9?02!)BN+#[(C-_1?.Q+O/.6&<%Z -M5H0QKLL%HI*I$1YZY#0"@/JD:0ZG8HS/8Q@:SU867(RK&E935YB8::8#*,;% -MA49FIR+&-Y2-%"FR>0G5666F!V;*5?8V>,P2N0\;8-2TU7K+XB&RJB(6B\57 -M;*4^(J*U_:[C>[/B;[D[[B3`6UO?;45M,,_Y2_.U]GVZ\__WW7SI/I7]G6W> -MLR%+9)^Q^K)>GR4M+#4;%Y?'O",<^Z?[ZVND>WP_OW%]VC'PNIT<9C\?DF/; -MOL&JU$QSWKR._X*N==E=E*-,Z30R5.GTU#W=G'H$\'LDT:CW88U$:)!&O,?& -MH$V-CJ2)FD':V?YO.CUM5WDZV-4*9JJ>2EAN.L9YJ_&]%+_"[-1Z].AFA?DT0HB!9* -MY2/7*U8:TPA:X!,,Z59>4I)^X8U._'ND:-'HDP]'U>)N4NW?-/&^*24>+B^- -M=8O'7Z<'=_(BG^IV5Q"A/&SH8U/`HX,]C]&1CPM<^/1(U,:E:T"BL82^8EX< -M>-_,UL%#C]U8ZG[4+Y]U0=U`C76]QGI?$F\A6.KU^9H)]K4KLXUT7MK;(JPA -M-WW[>EA\GZKA;-$GEK=K=;Z_HH--U>I -MDAJ3<]9T=O=&46'5/_J1O9QKA4,16G&([K#%/S#&C$Q7\)N-`(ZY[V)Z_^TX5#*_:?SPUEH^;:LA4=^F_JCT -M/;\C3XIP0VZ\X8GKY/7R/>S@OJ_8,C?9'G"%`1RLQXO5)_!]79H?[*)J^W^, -MAX8W+D_7ZWW>ZH+>Z0<07N>TJ\+4K=6`&?=_@LK#+00:PL]!YNWW_X&FQ7T, -ML/F'#*N^"#Z(S:R(N*B+WFX&$6&272'A0RP_(G+A\\_X>]K`A[KG+NN&63$0 -MN76^28VOQ="#;HZ7U)%1:QP_3WAL';81\OO6PMX#]+Q(%:N%29XT,!+#=(.( -M5CYR%AH/,5H$/G=M -M8F7K/%TZP+M716NW^<5UEV`U5>K9/!(\79@C``&_X.$YP7P.B"2>))YDGR20 -MR2*2C)*-DD$F\R-L^;9#MA>]^4)*UI6]+ -M<$J!*\53(O,BED9>1/R37)8X([HPC(Z2CY)+)2\DGE)^402KQ*ODJAE4LK+R -MN\E4U6=GCMG<-L*"/(0T'P(R7['((FU[)OV3ILKALD&R>-D\[)\V0T>8;'@) -M"?)/'2:*3A).,DXZ3UTG+R>\DYZ3GY.ADZ:3/RC?*7"4>)1YE'P/!(+IS((C -MEXR7/S#I,7"8FIB>F$\Q/S"B8%[Z<%_&3NE7^N@'MY2H4J)*C2QJ6/2U1-)4 -MR5.E4)5*4:0:Y!TD$$@\R"&012".0C9"/D$LA-2":03R"B04R`TBUR+I(H`E -MB&112*.1C9&/!!4U(II%/(J)%3(C`@TZ22`)@0EH)&EH.S4DFDD\DHDE,D-) -MM342:F3&E&N4=)1`$FD,HBE$E9^5H96FE3\LWRUPEGB6?);'2T -M)+1DM'2VNEI>6WDM/2T_+4,M32Q^7;Y>X2[Q+H9?'2Z*7A)<2)QLO'2\?+ZZ -:72R]434OO)=-+STN,1U\CTC_TL0]>P!`!P`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar_invalid1.c b/thirdparty/libarchive/libarchive/test/test_read_format_rar_invalid1.c deleted file mode 100644 index 61dea1648..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar_invalid1.c +++ /dev/null @@ -1,44 +0,0 @@ -/*- - * Copyright (c) 2003-2016 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_read_format_rar_invalid1) -{ - const char *refname = "test_read_format_rar_invalid1.rar"; - struct archive *a; - struct archive_entry *ae; - char *buff[100]; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data(a, buff, 99)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar_invalid1.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar_invalid1.rar.uu deleted file mode 100644 index 2380399d4..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar_invalid1.rar.uu +++ /dev/null @@ -1,5 +0,0 @@ -begin 644 test_read_format_rar_invalid1.rar -M4F%R(1H'`,^0B$4= -2,P0`I($``'1EM#'TZD7E[>^E"B3)2K$2:-U -M5%)EX,^[Z/T)6TB:)CD1,U4E(I-+`,]6V+:-&:B>1$ -MSVZ_1\FQU\.SEQ<&;'GQY.#%O^;#M^+%ES69_ -MHXL^[K_Z?#!$V>[L_=W/I^?K5_-Q5_#M>BYO_I+GV]C]S[MCRV9 -MM&&7@GAMW)P9]?=Q;^/>X^4D&3Y&Q0BO#W_2,>[\.MAS1^;O7V_]_'ZWI_5C -MSZ#,MGIV'_:?M\MYIM^'3C\^]+W]G*NS5A/R[W<]V*O,9O\H\F;AQ;=E<@[/ -MM]S]GW#/]G9_ZN?:^O"*NM1(DUR^M5]1?CL8?KY,[_?6H"Y$[NC?+DW.+;@^LR+V)X7\OIF@CG7V_%C\FBK -M'FPZ-?+AYA.9S'E8=OGFX=ZS],/#CLGHC)NX?R\K?2\_BQ9\.7BYJN1> -M#!ROX.+?FDV,#N8]W=])YCN3>7/*+GIR[^;8P]J>/])R<7A\7I$]%Z!N+GSI -MEOIF:>*QXM[!,ZG)D\=A\D*"<>/@\.A2SF*X>0<_*;%P;E/KY5\N#15CV^7V>TB:%\F'>TF.UN:'EYO<6Y!'W\D];;7%,H8_TT5ZV#-SG\ -M6]S*<^G,WMP:7E[CLG^W'36D;C\TR9;M-05M.D:?9S$[.B'FRT4/-9FIF702-"LU,'IR>#GAF/.UQY.*:@-FY"W3"]!COP56VQQG.]T' -M,%Y"-OPPT:$S3T)0I=%1'G[R9/'!!F]2L\N#DF:_>C+>B;Q:AK_GV=GUFXM?+YIR-].@7AH8ZFJL]]*W! -M"_%I\,7#/3_[6/D:\I[?7?\5EK5E4C7FL/!T=O0P-7$P[NMP>#0CS6S+>YO< -M?S1E_';L7I59;^BM2N.Q@[6]G\5(%_MM#PCVIF9K!Z&>.%4[."U'='!L+85( -M5_W=:NEM3\3BS1FU(,=WJSA'V9<%WL>>Z=[;&'NRF[BV\^MARZGB^;U4]XO# -M#]//@H2<,KCB*=OS=853Y#!V+#X2U@"%*( -MSO;]'"0]Z^D+^DIP1IS6]=U+SL\6>;$>'%7PS8+P[\_\@0!2+'-^/0W4/J/3 -M=#63+ZWWP`?AL+%.-]EC957ZDUY.8^<[GK+8?Y<&UFX? -MFTP5J1,8$\];/O\/6O)TV.SU^O_/7Z_9U^Q_+9[/8V/CZ^Q\G7]._8P6D#U' -M#'E]#O0E"8`6:@F6'G-<1;^.MXN0K-$>/?ZVITKZ=,U'C]#YYUO/<'2Z:R2O -ML_;KK"WV>Y6%U/W/EN5[[.Q_'8_GS:8L.O?>&W>6WU^O\M,L\%VV^Q;^_*_0 -M7MV^/LMO)P\=OBU>#8V_E['\I^KVKD+6HGY!F'X@.U.*M_;BFB"WV.C^.O]' -M7Z?Z-Z;K;/U(<@=G#_XP_'K@.++ISC#L\_W/U3%=?^'7_G_+4MY.$GHWV_'./%ZV*C7M[#P4NEP -MW7OX3-X\?#PSPLU^^]W(BO8(>G_M8MR;@7>Q\$UI9N#X6BFUQN>^@`NA'QJX -MHN7SI#J^"&H\VW.59V_%:PGN7#,ZN")NO=VT+E3:&:KB.WT\'P=%DCTO=F+X -ML\6@&T*'CS7L_C+-W0]1W!SO3&/SU?X=BZ.%[H#1O$Z;6&CG1%M^*H!C+[1M -MWWG)?LR9?;02-:8(/]P('4'W<*5];/?I^J&I(??P`)PW@\>BSF*XK7YL]-69 -M]CU@@,V>'R]1MN']>662NB(+,Y0.:@MFY -M[G)D0>VB.I_YEW]#&3>R>'CK)<503'UX)=]&2GOQ$)F0F&^H_DW<-^;*J'?H -MY5K\N9KN71',-9+>'BE%3<>;5':@R4206"OL9KS2FS&3 -MUEX9S(W#S!0J#"N>@3?LI1&K*:AR<-M$VS8(SC?Q4`!UU!J="U_>\KW-X1Q; -MT3/$,%V?IBC5FM@Y>\%)4[I)G/-&4\%-N0S="<;ONCQURJB/L'#2;'T/8LM[ -M3LY4';Y^[(#&9,NE;#J?ULS45,QQLR8:S!CWX?7Q/!^H#_FW79X<4*@\Y=-' -M^'E;!?;F0R\.>KF;I5OJ*H4G -MSO1?KCX:+C:V"KI"FFH0'7[\>UCI-%T2MY.?GGRXG_WN_E=(:VFKS>X!!,/; -M[GV=W\.YX-GN=_9ZGJ:"ZMT&O_CU(BW6_SI$9G4E^+AOQ$\/^?6]3$U13U.I -MBP_1=I7P0E'P3H574ZO5P_XM?R+-S.0EVFT($TS48\$W"O,7U?^ZRZJ`_8Y3.6PRS'>>#3!=\ -M$K0'!_V6E89'ID49#S(:U'&OH>QU^S\G7]?3M?Q-+W>AG6KXR;E3+Q](EJOX -M]GJ/U4W\_'@J"'ZF*T.+BL]CH&\5>_H]FYCZDMQ6?-?N_A]G6^_M?AW?LFME -ML??]E?IU9=35_@NF=NI3).B$.Z5GVN8__)_^K-E[^+;RY+0SFF42QY9TS7P\ -M4/9YN8IM#YIN+YMK9YRMKTT9/@NIB<(IHV*M0HP]WO_C$)FZA$^S+MXM3'F -MP976M+-?ON0_6J[SJ;_GF3@N&Z\]_U<T85^75V,'?LA,UVB[="5JU-E'Q,SF6A+[8HN'%3SV4J -M'6"Z@8:JL3!'T^6T.%H!ZDX8'BB-'[,T5S.=351LW]S%U9)ICK@QUJQ<1JM' -M75P:8F"]NG@,W0/#,1MJB\VT-*<17F.P05^?'E+1=2E=9TL9_-43 -M5.?WT23HF'/5//*PU]S'HAGP.<]/X+Y!B_NY?6>#;XYUL?P:+?!BH&5J -M&)CZ<,L@^]9'+I`P\\HQ[GGU^Z$TPR[P2Y=0W)\*'9O;M8^UU8LM<9XO',M\ -M[&HP6KUL$\?HYYGYM&;DV/;I27I4B7XT?5O.G]B;L['FK\X#2^26J'QSY*\% -M=9T:.;AOYEIHW-%.Z"4>2-KG(KZ4#U;9=:";2H9UJ5LV6,N>Q7N$"@5_">L\,[\6@UKE9PQZ -M\V9GRL?>[O^O<^GZ]#E'M^]O4-O_>37;V\N/AG-PYJ"@ -MH%`Q/29YUZO6C\3'1UIH$_G,6?.@F^6SURC;XLM.12A@*=8=]YVQ-`V;5J" -MYPU[R0N[NW3JT?YP9-0%+!\%SRBDFE;'Z@_L>CTIRIM5S)W35\#QRS0ECS70 -MBXG=ND(=`'5*,M-;3@N!A4=G?!;*YYO63YI6=T[-Q1_W!QUEY:-P7UI[:UG/ -MDO\'P>R6HIO6L=;-IK%EY;VDVEYM5KLU68]$^+R6=/FG341CH0X:-M4H=F+= -MLWN.$$S?I45D_Z/&E7*K:CM1S26_S&47RLO<1I,)=/^F -MW[UDT@YJPAM^S?HNGLWE?\>>W@G=']]^"*$;=1&8/C9ETO?\U*]]_C/CJ^66"^ -M%:T39/!=H;JX/^,'J%+H34,%^TP,`MIC7L.Q4K3D+NCBJ5Y/5-A^ONB]3Y>K -M\UVF/^=4UGZCHFT63.+/2T`!+>1TP3+E*>!TMFYSUC/@7JLOVCY>.BU%`?&E0N==\Z;!494NP -M?3D6&?_-U[&5_W=N'!=N'HQ!M[<".H;UU!_9QS//,V/:]<"_]/W1SXEHD'V4 -MA!_>VC`[N'LF+(^"=>6PX^A%SK/=?I^G,A>8.HJ7.R/8ANS051ZIRM^*:C>@ -M.!KUP6>G&%<.3AK5;>#SZG(7Y/+K>BXL]!F63@N?`157O2=R=6!]Y=%UY#SP -M5;YJZ&[5^?OTN@=GH#2J2O.CJ#L3;RISQ5+8]FQ1=K^N^M6]<&+R3"?VV1Y1 -M8[WU6:M?LIR:LZL;\ONL]7[!7/IYZG6_=*OWV;\LT*>[\4C$'&@!F+0&]GD' -MWSE'XQG[^MHQ/?X]_>\T\X[4J^S+G=S=ZS -MP_OZ#Y37:!UO;$SH&!]J4(T[W\?ZV?O%.,1^'FN;W,J??'&==*:NU.F2=E1^ -MW,G&([D"A_<\Q_#0E>QO[A7^NW/_WRULV?IZ_H^\.2;K&;\'V2M7)>GR899I -M]>V:)S84]^V7MMMQSH[%F<3]XB['%Q4)%[>/])ZYO6\C!L]; -M3#\G8BWDLJB3HIGIO+VHH#V+HS8[,.CO"_]@4K0.]T/6@ -M<[!Q3K5EO/$67;+= -M@U5`P4WU2IW\A_IKVW+ABYW<45Z*.BXS.39ENEL)V!!,"=OS-]S8SU39@]_0 -M!!#H$-MY[#!P4EP8*UUP9T"@QHSW*M\]O)FB]2?1\&>UV]/Q4+WFRUVY[H#* -M[?XT;7J][T"[T=$?G.>14Q/BG-6V[_FW]XL5.>$MQ59&.+Z@LI51)VC'I#X^ -M^YQ<$F@:?ZH0W6P]$'I<&UTA?[UCPQ?:-Q$ZG5^:J?HDUYXK]:W:]FI>DLZW -MMDSU%M7K,YG__%IIL?OFT::7FY3M68AO"JYYIJ(-.%VKR*T_'#"O!X]`L_E\4]?\V7%%Q_3H:.M.H3:E5=,KAJJ0- -M>-(TY#2T>>C:QD4QO]+O6F5/?-]Q,\>K7;KF-YT:+:G8%M=]4,+,[7;I+VQX -M\G!7>>C7F,YON1/)S7\A0;7IP*\;'I>X%O`E9?98:L0_S;AX'6>RK2','P>O -MP#WO.\OP^+1GSN3)>3IK27^WM3YQ"T='63&I9`DX9&[C\.QXJU9?3GE&#]/$ -M[>Z%"O%,55$OWY31*%,XN'8ZOF_"9PH$ZVZ]AV1 -M=/E4FUL]>/,Z`&J-5]KG6M]*V@"3KN,.6(\\,^:81\[>*Q;D5>[:Y[/'&)T\ -M+O`+.,?6Q>Z3!%TNM:N9/_)LXVVYWZM/L6V?/][MSXKO -M6ZG5NOAJ++W09XHB\1X<>_Z]$;GL[DWQPI;2Q` -M^6\9E$_CFNU_0C4!PTL9G54NIHAGLS:LSS5+H=7/12W%P5X'_WJJAP5?!:N[ -MFCFB:9#6,K'UX)>0D'S9;&>^WL^UYMO:OV:%>*>KZL$KI*79Z-CR?VCJ)&*@ -M3#5B*I!H%MXZ^:LG+#W:?-+<$!_[F?--N*W"#[K"UAOOWX(3@HU]6'9JZ7=J -MS2UK:*='74^D;[>:WP>QTS2IKU?E9JF"GMC/,`Y.6^Q8_#XH=+>6:V^H+%[N -M@#K4J"GM$#5P'J(,O:1PWOO@^\0?Z.![UP\ZMR0X[JE[RQ]&//7W])_Z6-;! -M$N@8V\&[/I1&7=Q;=N*X\&[272M*L[1=QZN4BMTK%0PMXBV][56#Q6C=Z/J^@B:?+&4N7NZ&Y[Z@2I__),.%N8HX[/^_O^^]6`\ -M_RLAE?/]7Y]#=.?)IVE=NN;W>=X,4Y[F:Z45^7:X\]F;I.F77$CRXM7&[:>F -M.X-FZU%[9]C'MV:1I\53^/)/TZ<%CGR5"!]+:W/,)FR="!U2NH:MZTC!>MU' -M>[04$*@ZJ:@VWX^.O7)ZV@;MYZH]B=DGU$"EGDYM.Y8LOJ%F(DO[JK'O<>F> -M4NM+>_SG-`#O,G@FM-EBXZ/C\])U8.O6V\%+)^F@'CU=O\K1?LG!0IS9#R5&94FC:PC]/4VL -M&[EGM*+TZGW+[Q5LTC+X;-5[FZ>>UZ"G,S+3B;;_#/A!YZ%W\<75%FKS< -M#CIOM-'40M)W%FZ'74LW',X^_%F7YM/5,K@R'S:;+8NHR50ODZX;DQVV -MD-TK]35?K>M6R[*7%!./]C@M3M$>X+U[DE_[.+]?UEG(U4P1X,,MWX96'=U> -M>,SN[%?91M2]#1W,EE=)8O#'66IJ+STKQ=`V$3:'*3AXLO#'+18Z(/SVMY;> -M7E/?@RPHI#SJ9DZ.N:0H[@?N;>B"=-?KLFX_FG'UGY$:8P4;H -MBS.J2M>+=O=$-]'6=RHR9BVHL-2C24QK66[M@G,+NW73=^U=<-U&T>=R:8Z6 -M;S""[#,]L?B+4$NJ&^"[B -M^+QS+489X[(EY,GCLNV72NK*93?2=0R=87=5`[;$4TKHX+7 -M!E_J.G.]BYW,V._RJ]W:.JPZ>$4X-4F7^<4,O/REHJE0LW=O/K#[TQJ;3_W3 -MTEEUR-Q*FW_X%16ZTL4*K3=6\7ND<&'AG@MZG_$[2 -M,K*/:9M!T:TBG00+P42Y0[)ETA=(3;'+N<,=6SUM/\)4OFUAS-3^&LS -M`0YJ.C^Y"7?#^N/A@F;4_SV<&KH6/,_%YPSL,+YL.*Y5W-H-WMZY*TM5`:70J<7]Y.?$P^?5%$9U)^:NO/1M8\\63[WZ -MMW^LA6UR30"1>8$Z+P?U3A7^!.O]3]WH4WQ0@S!7FPZU,W:R;F.S3?J=?VN] -MFUMC>I5N8O<:@9^+WUK2A_/?BS7C`^>:>'-Z`;>L`NG9&(^B8WJ;U&D$.I[\ -M-_2M:S7`2BTW%&-H"#3HM$!PMK>R;?CP6Z5NK)5)7.[^"/MI1O5:K-29-U"/F4J9_5;WT1![O3RQ3D;F+]GZKR4_JX[S%.W,I9-^@6S>Q<=R:+NM!V -MJN7EQ8J3$=@HJYZK6*;[4F'I7]$)"ND5-^DBA@E_;^.TC:ZT="MV"T`4ZG%6 -M"67MKWG!-#)9H%MQN6UE7H4FV$E52Q2X"9WN]@NG8YA%*0W?8,5P)!J"\IW% -M#AFTQC_6O/!8.A_'!JJ"Q75//*_.FVTP$_'-.MFM;>'N/@M4SM>Z4DEL -M>>G)$8(U#I@J:D(4DR[3<0P3TAGL\K@Q;GDG!GQ>'5P_DR/,\'+?>X[;>H\M -M&V:DVVIUW4;W)Q4KK]]M6V;E_+5XGP=W*?J03J?Q$BZJ5:.IXK%O:K6_Y_N -M.A[X)O0]VM]M\K=R,BW<$>_BKV(*9$T(VN./FOM'6MK9-5"I_3D*;M'0C\?9UYPENFDHYZ;\%>F';67)X -M[.D:(H7)VY'T1*$-.0_>\F.L-6>YNFX^2>EOX_);D=:+-%TQ=6G2/J9!I_E3 -MG(>"ET[=CK?)AS1U#C4H;[6_S/J[WTVX?K?5^/;_K'YC^WX```````````````"]OP````O;\````````````O;\```"]O[V_7M^` -M+V_``<`%[?@````O;\`````````#@`7M^`````````````!>WX`````````` -M`````````````````````````9@``````'P`#``````!>WX````````````` -M``````````````````````7J_``%[?E[?@````"]OP`````````````````! -M>WX````O;\```````%[?E[?@`````````````%[?@````````7M^`%ZOP``` -M````````````````````````````````!X```````````````O;\```````` -M`````!>WX```````````````"]OP````O;\````````````O;\```"]O[V_7 -MM^`+V_``<`%[?@````O;\`````````#@`7M^`````````````!>WX``````` -M````````````````````````````9@``````'P`#``````!>WX`````````` -M`````````````````````````7J_``%[?E[?@````"]OP``````````````` -M``!>WX````O;\```````%[?E[?@`````````````%[?@````````7M^`%ZOP -M```````````````````````````````````!X```````````````O;\````` -M````````!>WX```````````````"]OP````O;\````````````O;\```"]O[ -MV_7M^`+V_``<`%[?@````O;\`````````#@`7M^`````````````!>WX```` -M````````%[?@``````!>WX`````````````!>K\``!>WX`````/````````` -M`````````"]OP```!>WX```````+V_+V_``````````7M^```"]OP``````` -M`+V_`"]7X````````````````````````````````````\`````````````` -M`7M^``````````````O;\```````````````!>WX````7M^````````````7 -MM^```!>W][?KV_`%[?@`.`"]OP````7M^`````````!P`+V_```````````` -M``O;\```````````````````````````````````,P``````#X`!@``````O -M;\```````````````````````````````````+U?@`"]OR]OP````!>WX``` -M```````````````O;\````7M^```````"]OR]OP`````````````"]OP```` -M````+V_`"]7X````````````````````````````````````\``````````` -M````7M^``````````````O;\```````````````!>WX````7M^`````````` -M``7M^```!>W][?KV_`%[?@`.`"]OP````7M^`````````!P`+V_````````` -M`````O;\```````````````````````````````````,P``````#X`!@```` -M``O;\```````````````````````````````````+U?@`"]OR]OP````!>WX -M``````````````````O;\````7M^```````"]OR]OP`````````````"]OP` -M```````+V_`"]7X````````````````````````````````````\```````` -M```````7M^``````````````O;\```````````````!>WX````7M^``````` -M`````7M^```!>W][?KV_`%[?@`.`"]OP````7M^`````````!P`+V_`````` -M````````O;\```````````````````````````````````,P``````#X`!@` -M`````O;\```````````````````````````````````+U?@`"]OR]OP````! -M>WX``````````````````O;\````7M^```````"]OR]OP`````````````"] -MOP````````+V_`"]7X````````````````````````````````````\````` -M``````````7M^``````````````O;\```````````````!>WX````7M^```` -M````````7M^```!>W][?KV_`%[?@`.`"]OP````7M^`````````!P`+V_``` -M```````````O;\```````````````````````````````````,P``````#X` -M!@``````O;\```````````````````````````````````+U?@`"]OR]OP`` -M``!>WX``````````````````O;\````7M^```````"]OR]OP```````````` -M`"]OP````````+V_`"]7X````````````````````````````````````\`` -M`````````````7M^``````````````O;\```````````````!>WX````7M^` -M```````````7M^```!>W][?KV_`%[?@`.`"]OP````7M^`````````!P`+V_ -M``````````````O;\```````````````````````````````````,P`````` -M#X`!@``````O;\```````````````````````````````````+U?@`"]OR]O -MP````!>WX``````````````````O;\````7M^```````"]OR]OP````````` -M````"]OP````````+V_`"]7X```````````````````````````````````` -M\```````````````7M^``````````````O;\```````````````!>WX````7 -MM^````````````7M^```!>W][?KV_`%[?@`.`"]OP````7M^`````````!P` -M+V_``````````````O;\```````````````````````````````````,P``` -M```#X`!@``````O;\```````````````````````````````````+U?@`"]O -MR]OP````!>WX``````````````````O;\````7M^```````"]OR]OP`````` -M```````"]OP````````+V_`"]7X````````````````````````````````` -M```\```````````````7M^``````````````O;\```````````````!>WX`` -M``7M^```````#^!$_L_$HKIR@3W\%I0\````+V_````O;^]OU[?@"]OP`'`! -M>WX````+V_``````````X`%[?@`````````````7M^`````````````````` -M`````````````````&8``````!X`!@``````O;\````````````````````` -M``````````````+U?@`"]OR]OP````!>WX``````````````````O;\````7 -MM^```````"]OR]OP`````````````"]OP````````+V_`"]7X``````````` -M`````````````````````````^```````````````+V_``````````````7M -M^````````````````O;\````+V_````````````+V_````O;^]OU[?@"]OP` -M'`!>WX````+V_``````````X`%[?@`````````````7M^``````````````` -M````````````````````&8``````!X`!@``````O;\`````````````````` -M`````````````````+U?@`"]OR]OP````!>WX``````````````````O;\`` -M``7M^```````"]OR]OP`````````````"]OP````````+V_`"]7X```````` -M````````````````````````````^```````````````+V_````````````` -M`7M^````````````````O;\````+V_````````````+V_````O;^]OU[?@"] -MOP`'`!>WX````+V_``````````X`%[?@`````````````7M^```````````` -M```````````````````````&8``````!X`!@``````O;\``````````````` -M````````````````````+U?@`"]OR]OP````!>WX``````````````````O; -M\````7M^```````"]OR]OP`````````````"]OP````````+V_`"]7X````` -M```````````````````````````````^```````````````+V_`````````` -M````7M^````````````````O;\````+V_````````````+V_````O;^]OU[? -M@"]OP`'`!>WX````+V_``````````X`%[?@`````````````7M^````````` -M``````````````````````````&8``````!X`!@``````O;\```````````` -M```````````````````````+U?@`"]OR]OP````!>WX````````````````` -M`O;\````7M^```````"]OR]OP`````````````"]OP````````+V_`"]7X`` -M``````````````````````````````````^```````````````+V_``````` -M```````7M^````````````````O;\````+V_````````````+V_````O;^]O -MU[?@"]OP`'`!>WX````+V_``````````X`%[?@`````````````7M^`````` -M`````````````````````````````&8``````!X`!@``````O;\````````` -M``````````````````````````+U?@`"]OR]OP````!>WX`````````````` -M````O;\````7M^```````"]OR]OP`````````````"]OP````````+V_`"]7 -MX````````````````````````````````````^```````````````+V_```` -M``````````7M^````````````````O;\````+V_````````````+V_````O; -M^]OU[?@"]OP`'`!>WX````+V_``````````X`%[?@`````````````7M^``` -M````````````````````````````````&8``````!X`!@``````O;\`````` -M`````````````````````````````+U?@`"]OR]OP````!>WX``````````` -M```````O;\````7M^```````"]OR]OP`````````````"]OP````````+V_` -M"]7X````````````````````````````````````^```````````````+V_` -M`````````````7M^````````````````O;\````+V_````````````+V_``` -M`O;^]OU[?@"]OP`'`!>WX````+V_``````````X`%[?@`````````````7M^ -M```````````````````````````````````&8``````!X`!@``````O;\``` -M````````````````````````````````+U?@`"]OR]OP````!>WX```````` -M``````````O;\````7M^```````"]OR]OP`````````````"]OP````````+ -MV_`"]7X````````````````````````````````````^```````````````+ -MV_``````````````7M^````````````````O;\````+V_````````````+V_ -M````O;^]OU[?@"]OP`'`!>WX````+V_``````````X`%[?@````````````` -M7M^```````````````````````````````````&8``````!X`!@``````O;\ -M```````````````````````````````````+U?@`"]OR]OP````!>WX````` -M`````````````O;\````7M^```````"]OR]OP`````````````"]OP`````` -M``+V_`"]7X````````````````````````````````````^````````````` -M``+V_``````````````7M^````````````````O;\````+V_```````````` -M+V_````O;^]OU[?@"]OP`'`!>WX````+V_``````````X`%[?@`````````` -M```7M^```````````````````````````````````&8``````!X`!@`````` -MO;\```````````````````````````````````+U?@`"]OR]OP````!>WX`` -M````````````````O;\````7M^```````"]OR]OP`````````````"]OP``` -M`````+V_`"]7X````````````````````````````````````^`````````` -M`````+V_``````````````7M^````````````````O;\````+V_````````` -M```+V_````O;^]OU[?@"]OP`'`!>WX```']'_`95WX```````````````````````````````````9 -M@``````'@`&``````"]OP```````````````````````````````````O5^` -M`+V_+V_`````%[?@`````````````````"]OP```!>WX```````+V_+V_``` -M```````````+V_`````````O;\`+U?@````````````````````````````` -M``````#X```````````````O;\`````````````!>WX```````````````"] -MOP````O;\````````````O;\```"]O[V_7M^`+V_``<`%[?@````O;\````` -M````#@`7M^`````````````!>WX````````````````````````````````` -M``9@``````'@`&``````"]OP```````````````````````````````````O -M5^``+V_+V_`````%[?@`````````````````"]OP```!>WX```````+V_+V_ -M``````````````+V_`````````O;\`+U?@`````````````````````````` -M`````````#X```````````````O;\`````````````!>WX`````````````` -M`"]OP````O;\````````````O;\```"]O[V_7M^`+V_``<`%[?@````O;\`` -M```````#@`7M^`````````````!>WX`````````````````````````````` -M`````9@``````'@`&``````"]OP````````````````````````````````` -M``O5^``+V_+V_`````%[?@`````````````````"]OP```!>WX```````+V_ -M+V_``````````````+V_`````````O;\`+U?@``````````````````````` -M````````````#X```````````````O;\`````````````!>WX``````````` -M````"]OP````O;\````````````O;\```"]O[V_7M^`+V_``<`%[?@````O; -M\`````````#@`7M^`````````````!>WX``````````````````````````` -M````````9@``````'@`&``````"]OP`````````````````````````````` -M`````O5^``+V_+V_`````%[?@`````````````````"]OP```!>WX``````` -M+V_+V_``````````````+V_`````````O;\`+U?@```````````````````` -M```````````````#X```````````````O;\`````````````!>WX```````` -M```````"]OP````O;\````````````O;\```"]O[V_7M^`+V_``<`%[?@``` -M`O;\`````````#@`7M^`````````````!>WX```````````````````````` -M```````````9@``````'@`&``````"]OP``````````````````````````` -M````````O5^``+V_+V_`````%[?@`````````````````"]OP```!>WX```` -M```+V_+V_``````````````+V_`````````O;\`+U?@````````````````` -M``````````````````#X```````````````O;\`````````````!>WX````` -M``````````"]OP````O;\````````````O;\```"]O[V_7M^`+V_``<`%[?@ -M````O;\`````````#@`7M^`````````````!>WX````````````````````` -M``````````````9@``````'@`&``````"]OP```````````````````````` -M```````````O5^``+V_+V_`````%[?@`````````````````"]OP```!>WX` -M``````+V_+V_``````````````+V_`````````O;\`+U?@`````````````` -M`````````````````````#X```````````````O;\`````````````!>WX`` -M`````````````"]OP````O;\````````````O;\```"]O[V_7M^`+V_``<`% -M[?@````O;\`````````#@`7M^`````````````!>WX`````````````````` -M`````````````````9@``````'@`&``````"]OP````````````````````` -M``````````````O5^``+V_+V_`````%[?@`````````````````"]OP```!> -MWX```````+V_+V_``````````````+V_`````````O;\`+U?@``````````` -M````````````````````````#X```````````````O;\`````````````!>W -MX```````````````"]OP````O;\````````````O;\```"]O[V_7M^`+V_`` -M<`%[?@````O;\`````````#@`7M^`````````````!>WX``````````````` -M````````````````````9@``````'@`&``````"]OP`````````````````` -M`````````````````O5^``+V_+V_`````%[?@`````````````````"]OP`` -M`!>WX```````+V_+V_``````````````+V_`````````O;\`+U?@```````` -M```````````````````````````#X```````````````O;\````````````` -M!>WX```````````````"]OP````O;\````````````O;\```"]O[V_7M^`+V -M_``<`%[?@````O;\`````````#@`7M^`````````````!>WX```````````` -M```````````````````````9@``````'@`&``````"]OP``````````````` -M````````````````````O5^``+V_+V_`````%[?@`````````````````"]O -MP```!>WX```````+V_+V_``````````````+V_`````````O;\`+U?@````` -M``````````````````````````````#X```````````````O;\`````````` -M```!>WX```````````````"]OP````O;\````````````O;\```"]O[V_7M^ -M`+V_``<`%[?@````O;\`````````#@`7M^``````'\!'_`95``8`````` -M+V_```````````````````````````````````"]7X``O;\O;\`````7M^`` -M````````````````+V_````%[?@```````O;\O;\``````````````O;\``` -M`````"]OP`O5^````````````````````````````````````/@````````` -M`````"]OP`````````````%[?@```````````````+V_````"]OP```````` -M```"]OP```+V_O;]>WX`O;\`!P`7M^````"]OP`````````.`!>WX``````` -M``````%[?@``````````````````````````````````!F```````>``8``` -M```+V_```````````````````````````````````"]7X``O;\O;\`````7M -M^``````````````````+V_````%[?@```````O;\O;\``````````````O;\ -M````````"]OP`O5^````````````````````````````````````/@`````` -M````````"]OP`````````````%[?@```````````````+V_````"]OP````` -M``````"]OP```+V_O;]>WX`O;\`!P`7M^````"]OP`````````.`!>WX```` -M`````````%[?@``````````````````````````````````!F```````>``8 -M``````+V_```````````````````````````````````"]7X``O;\O;\```` -M`7M^``````````````````+V_````%[?@```````O;\O;\`````````````` -MO;\````````"]OP`O5^````````````````````````````````````/@``` -M```````````"]OP`````````````%[?@```````````````+V_````"]OP`` -M`````````"]OP```+V_O;]>WX`O;\`!P`7M^````"]OP`````````.`!>WX` -M````````````%[?@``````````````````````````````````!F```````> -M``8``````+V_```````````````````````````````````"]7X``O;\O;\` -M````7M^``````````````````+V_````%[?@```````O;\O;\``````````` -M```O;\````````"]OP`O5^````````````````````````````````````/@ -M``````````````"]OP`````````````%[?@```````````````+V_````"]O -MP```````````"]OP```+V_O;]>WX`O;\`!P`7M^````"]OP`````````.`!> -MWX`````````````%[?@``````````````````````````````````!F````` -M``>``8``````+V_```````````````````````````````````"]7X``O;\O -M;\`````7M^``````````````````+V_````%[?@```````O;\O;\```````` -M``````O;\````````"]OP`O5^``````````````````````````````````` -M`/@``````````````"]OP`````````````%[?@```````````````+V_```` -M"]OP```````````"]OP```+V_O;]>WX`O;\`!P`7M^````"]OP`````````. -M`!>WX`````````````%[?@``````````````````````````````````!F`` -M`````>``8``````+V_```````````````````````````````````"]7X``O -M;\O;\`````7M^``````````````````+V_````%[?@```````O;\O;\````` -M`````````O;\````````"]OP`O5^```````````````````````````````` -M````/@``````````````"]OP`````````````%[?@```````````````+V_` -M```"]OP```````````"]OP```+V_O;]>WX`O;\`!P`7M^````"]OP``````` -M``.`!>WX`````````````%[?@``````````````````````````````````! -MF```````>``8``````+V_```````````````````````````````````"]7X -M``O;\O;\`````7M^``````````````````+V_````%[?@```````O;\O;\`` -M````````````O;\````````"]OP`O5^````````````````````````````` -M```````/@``````````````"]OP`````````````%[?@```````````````+ -MV_````"]OP```````````"]OP```+V_O;]>WX`O;\`!P`7M^````"]OP```` -M`````.`!>WX`````````````%[?@```````````````````````````````` -M``!F```````>``8``````+V_```````````````````````````````````" -M]7X``O;\O;\`````7M^``````````````````+V_````%[?@```````O;\O; -M\``````````````O;\````````"]OP`O5^`````````````````````````` -M``````````/@``````````````"]OP`````````````%[?@````````````` -M``+V_````"]OP```````````"]OP```+V_O;]>WX`O;\`!P`7M^````"]OP` -M````````.`!>WX`````````````%[?@````````````````````````````` -M`````!F```````>``8``````+V_````````````````````````````````` -M``"]7X``O;\O;\`````7M^``````````````````+V_````%[?@```````O; -M\O;\``````````````O;\````````"]OP`O5^``````````````````````` -M`````````````/@``````````````"]OP`````````````%[?@`````````` -M`````+V_````"]OP```````````"]OP```+V_O;]>WX`O;\`!P`7M^````"] -MOP`````````.`!>WX`````````````%[?@```````````#^`1_"\2RMN6#O^ -MAZ6/```````````````````````,P``````#@`&``````"]OP``````````` -M````````````````````````O5^``+V_+V_`````%[?@```````````````` -M`"]OP```!>WX```````+V_+V_``````````````+V_`````````O;\`+U?@` -J``````````````````````````````````#P```````*GZ#$/7L`0`<` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar_multivolume.part0001.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar_multivolume.part0001.rar.uu deleted file mode 100644 index 7378a9b55..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar_multivolume.part0001.rar.uu +++ /dev/null @@ -1,1337 +0,0 @@ -begin 644 - -M4F%R(1H'`%IND``&I!9PX#@*>#,/AM$C\= -M-1T`I($``'!P;61?;'IS[/K1`L^BJ7QHH!,TI;W];?!5Z -MF=E%3:9D!V5_BCOB__PLW,UT8MG.V$Q7KSZ2#K<#EP<%P9+`YQ-//JS/OG8% -MGF:=0?4;"T5`E9>J+-,;+NI2K6-O?[L^U3B+E^I-B0X8-!>K)^47].FJY*=Q -M10]!>FJ?S0;Z^B\I%7:4@H;0AA7'(3P&:[\JU(8)'5$62(J&$W\)QVW45M^2 -M9P3SADC_"!&+;L,CD'5DHA4.Y/8103RTR=4"1_^^"?<=_K`2[*UD!5]5ELOO -MD904KH(C.D_I,E_*W4G%?:"JL3FS&'X'!M8\]_4N^GIF="5&V)>M,/_6NL?& -MG-!'+L%_B<.$R[@F\:]E.SEGZX8JG*P!=:4?BQID^?>^$K):ZA*;%AT&QG4H -M87NK!"V.H]QRL!*Z75P*H=QH@.`K!%U)98?$)B5/#'Q"G2?IK:SG--F<>%0P -M/&L'[WB2!U7<*?4L4NOOUTT.SR!`I\R[_P1F=02HR>'QX8'^2HV&5JV`]-KQ -MI+1)$DI5RKBB(D_C'\_+]51?<,M@,F]PE+VS -M]2/>+LTL^)KUF2N[8ZO?.RN>$#S?0H]0YSYGBDJB]E^_&DDB:%;!B8J8GW*J -MO9*/%:M1X$FFP^&O`[RU:XM%UY]0#EF9\,:3">!<)ETSY)F5GC:.-&AY:MMY -M?U9WS&?(9@3"\/]9=PU??)T!9PR=N(\&#=,WX8AKH;:/SKE13]KR`RMXSC6_ -M^IXE6RJ:_VX+-U:3J`1R_HK<>S2[KP=XHKKNY&^5,X`_EJ,Q%SP[P=:;DP!V -M0!/%2"66A!1(2(+-#&]E)ZM83H-(N9*;>3I['T&=*&8?"1L$%$;3I6]YGM7D -MA@WYC]Y1YC(KRNJ.,K9ISE/HX0L[5W!@N8&,/@KJA3[(SRV0;9*#>[IC8&(O\6E?P5CO+^4Q.EB -M@5_+,2,=*PW'V6\5:'`GU$42X'+ML^24T+V!U"[7`*WU5Q]A$I;.G*JG3N>M -M(\%C1N33':_HHW*]Y@\[G\VP2BSYTEQL1Z8P$U-TE)M#',SS=QF:;,%!X>FAS*\$LTE:N;-E6JH>UCSZ1^*'21$RTA7<71W\*'6M7UH/$P-#82?]^*:&%&S?D\9SP=W8 -M=U"D#*O8TJ'PI?QPA5Y[1`3&LES]V4]=\A6GM]#HQ+($<>?RFPOA_\/#^3H) -M9M3;PAY%/JU7%9Y??]05JHLVQ:NH:N_*K(KT^-\AHXKO`8\.G#76!Y?X:87E -MA&>X_XI=4RLM_#NXEY+K_W!;ZRW]"9D4GN7+!"*$"@E$<G,@,C`8B[OV4TA+G:`EC40T>@O"IY@;Y\2/JDD=V1M![(CNP(_,E2-0U^CX,9BJE=-CP^H-4\+4& -MD]^J`VAH[`_"EO\Y>#/O3GZ<`Z:6=C5[_!MCXBCD:8T=_894T$+.WU/1Y`8*W?RV7BIE:8CE&#G* -MKAR=I-M!\(2SH1`)U-_43!QP@2?TY36!`,FTEU"+G+UR\DX'0Z_/'SUZY'L\ -M<0WB\\&R.5`B`PTC#+4,\88"E0R2=P3'KS7/-:4F*.?&)JJ,1Z$$E`D\_G]: -MV`NESW?*QT"[,@OLIS&%#DX>O6[@;#9Z`ZT%+:?63G07XHA.O=(S8L_LA_@> -M\]+1T#1TE;]'*1$!&)GM0DS/_Q)^T>D@@/DD!>X+:`L4GV%@V((T>B"H_:6L -M;'9EB0&Z^8*/S-%;`K&EHFW1R0IJ1>OW_*'\4"G9B!S)($G=ZU?\%SA7*9M^EL80./SNR$4)E*K:0!TT,*59F65;WNQYN2Q.Z,L"-H?=(U3A>/=1R/Y!KMGFG!/%DY8V50XA+>J82,Z"D#JFCD'!XZBB48\M\!4L<-&XPOV&.MBD.".V.?&$P1P4SEWX]XVYY -M/DM9NEM8RJBP@JX`MF#PDC*4T$Z1ZZ%(V_XY#NX1+B8%\ZL>P(`W9GWOQR7: -M

    +8<3CD!K`P6["#A8H,+&2R38"$I3JG>X/>XN:(7?G\R3GA;7`/=)[X,@S -MH"RE$#HVN0_>N!D3^9IE^DGBJ9V+YJM@YIK6_%4=OUV8U!^^(JX8"/)T`5%& -MTDD1HCVQQU=MDJ7]J/"5:Z4Q!0D@T'X=<[2(L_>PSMH*)HHVI-L$?3^",O.& -MT)16KLM`NPY``"J9YM+&Y^@'!?(+IPXR-`84ADYF:`&7!(*#Q@Z]BBE@.1:A^OSG:9$M^[];\N@Q3(X+W -MLW3&;=A2([8<"3P>I95^!NIMJE^YJ5&S6(J`/T!2S-,' -MD6)@'GHT\L_2HV$04ZU\SOE')DN?ASL1NN^^7:V<[)Y\I*EYV;0WS5FYD3!6KRFYFE5CFI??*J -M-\ZJE,,<%,A9'!"O8)6/WUW=W@R<[=$$<1D1#G@4N:YEA(!4?2'_\H4)K'I` -MKQX_T=8OD1V$QU'F.652T;$^E!V!\%GRF>6J@J%#FTW+I/CY_;U,E7%R2F"W:/F]OY -MT`W/7T#4Z=_;LS/5@2B`\A(2,WZSA?974DF3$<^RA?!ACA!^T/=BR4X+!8F3 -M^V075'/DF0UX9\E0VYNLUQJ.-$%SA9?S -M?8%ZQ#'_7KP%^D[YB#`YBS9'R-1]I1"2N1X`F!NO\Y -MU2FW]K[:,QOI# -M>G6&B3`V%ZV1>]#E':8;?F6OG8V^TQV;15_5-.W1-`CK,=C))^_Q_AF]F.H1 -MSAN"WK^*@1VTQ-&^[`74F:5-]?1;2U:NB`W][#)$@S:G:#QRQ9<)?V;4ZD7! -M-M(9_<.&X+E3&KHS/ZT,"@J!4[HEGW.#\NPS=&7V&Z>>=?0"-TW"#E7/V3CW -M_*1@*VI;B@^?21EF6?.^)_UN@CL82I]HIT<;:R<>@2+;+#RMMY6I*/U]FZGQ -MINO=(L/3*#_E5U3,F\8F_^)ZI`^%#0TR`*7(=M'GAH1Z&W%%SMK%$S(`QE,* -M^6?.6MVVEA^H`Y>:`Z^<*,$Q<"02QX)QTZ;O9%YPH;K('*2`L;>F?*ZC0C^Z=G4^9(Z)%V9Q"G7_SY -M3!5I`B]/7H@7U]O`LQK!E,?3E$805$)KX47&Q-WX3RB7XV?S87X*S5;_:NQM -M5*7B3"56.2*M9KX!S[ZZR'YP-%++:"-V8:N'\Y%8HAP+$#WA*[C(+H9/)APU -M4E2Z:^Y:R%Z^]Z3`7?QMK@75!*C8YQ^2P+0'?Q"%Y#R%#PY?T$G""_TAOMOQHP89`J)7F\@W+<_BQ/#K!1_L -MAG]AD:E2F-"8]9EGWWO2_;$9R'?7$LL^Y]2H60AX..N#3IS1:;`LGOI![!L;C&Y)[`!-[XN#[5[/KF@*1866&"ZCC\[ -M#$*J]$%)"`#2V0FJ(>E2E8+H%]-05@+:Q0^"T&".^`;FHY$`!9IT1 -M:&R$ENRQ2$>1%A#&*R\466G@[JE7IH$`0$QBN#^#<^>3*/4@&>V59O$BH3JP -MKT62;#2"-^$8UR_#`H_[QL4]`XF&>SR3?@@3BX<*_JGC<'%5I0!UKZF7<7PSKFV!,]9X0=>Q\YS"+>G+V;#>"-"%-) -M1:#D=1.TV56\L3$1T/BORY6(_1U4=%8([W3PHIR[N'6+5L.G:NJ`W=78>FS+ -MG)>MXH:?N@U`&MJQ/P!F)D8/IFOA`*`51"H5&SFB:@@E2%,G)!O<[(BW%`Z+ -MFD5DG@I*@0]`X%3[Q1SH?1"=E.^ICW38DTXRZ7,1T=&6/("@U*2!7J)J.,00 -MT&7*=+9DO<0Z3W$.49(DMD':OZV[$'2VB+GR@7\@71JU(9?8F*!<3)&)*)@) -M8"[%UCD/\7O>/4EKE,440IR!+_!)AH")KL8J\Y1[0_LR4`I@JMCEH'M%T)8'[3: -M.7`6S#1:?%1#*>54`%8Z2P4#]S%B&_V61"Y,)("&PB4(`.?[C%?-J(?!-P_V -MKA:8H"G!Q2H].,.F'`T0J5+ZRVZ85AWI*N1B`8XOP7B<'#.;CJ*`G$9U%=O3/OVUF-OYYO3*G0K<[Y"%JX -M!X'#3S>P91<8Y-M-Z(0"Q_5-057,XS7*28Y')2*J7JJ_YD_SM7L@9-%NE)FN -M69TZ[;P-E8#\Y4AARJI`$6'](`O\MU7WIY<+CZ"*D/S-9[.=><+5K5G@WN"` -MB8:KHE*C_Q;\H_)G++W<[U"$K08NWP\U=SCFS"-;X;)SD4^*G#,CA('):_*S -M3*`"[MN"U\78A]Y^<=^7K^$FRTG\'>_SJCL9T -M$M"4ZUHJ/0EA^[PFK7Q;A(]-XN"OH#6$UD_>SG[@H><$6=?N#&-( -M8U!+]F`_72)=<[]`.?T[V@.OXQSLP$L<;_U]<"S%67%`?#N/XP24IE*&:FY/ -M/]><-A.`]LU1CP7C['B^B/\F5@IV24JC-_9TC0V_8E&&P13B^PZ`,.60P+_0 -MYN4)5L%`9^^!G[/#2>670#$FI9ZWD$^H[Q4T5X8!>3*5O-JJJ-@U7'!G(I[[ -M1".^J"/]&L'`?EZ/V4Y=41%=ZW]WF@%YSJW-2(I?"GK[)$+7C@I[D?FE2XJV -M#'61D;M2X2V.KG4IM.HTA(%3TZE:I-U)?SC>R.CBE3.!;1CDHOWK-,3R+('J -M;Q9TK_=H>)E9'=DFIO'7<4DPL-C"JG2$'P$^SO*'",7=;Z4M--IOR+8L77 -MKFY%V);CG'\H4(:WG65D!7T1\L&YJ[;J\Z!!]!>_8L@4\_+%1F)!]--)`88$ -M?&?TR&;0;@%<8[JA=KB)Z^:U5^;UT#O:.WTN^*GWC)M);IF@=[&ANVG)0HN6 -MWI6)5XC5T#-U5/%BTU]+&LQ%-ZL#+31#NZ,W6^VLT+E"2XDPCM]2D?N.6=O3=E'0I3B+-)_8 -M8N2D[;@(>GVU8<>K^H:>-3)/469((HJ<;6CJ=KK2X!'!\58]OVRT\[1DV%U] -M]+;#PU7;O9`@&L;N0[U2Y@W2A-BOF`(W&&K0H,S2"5<>AR;@*^<,IOOFQ!U'L7^$Z\_D.?L;QY3J$>,W -MN$Q\]NFT?*;NZG_M#+:\_QZ[S7@V;?[0&J6__G*)]4W)`\_0^XZ/R3:#K@K6 -M:\'O[:!@B5S11B6L!7`+;.HUC9J$NGM(-^_$H//_Q^>`S:\O3"18!4__4F7R -MH')EA?'O33NS:7&?NTW9`?JJ6LS?_X^IPYJ!Z-0=WP[O,1K_W1`?[$7WE-XB -M.2OL-@GHY[[M]81'*WAM.[/'#)RHM!IZQG]$)PR][O1P[*4$8GX.\RJC^Y!) -M@8_V`(]5%ZF?!0$W5GHLA@ED:VDN?@V[C,*97#R42-NTMYJN?T'&^9*DHBGS -MW7<>Q=B%,(O&;%V222=;"N<4?;@TEI_N7=;L5%TK7H#G%&V$0W![+EJ#/];- -MJ5_:YB?0ER`ESRD3-"*;?]I8P?4?,0/%B;.-+Q*NFZZJ,3HU)%7["@!H"059 -MC#IY""-+"[C-/08(4I>EA*`;@(<$$AKE?.DQ,&/UQ0/K.V5HX5`-"?VMV*WQ -MP$G>?H1+KU,LQ3-+`GS.=>!$H2PGKS.OOBUK-<9'X/"]'FR$S]Q4S@]C"MUX -M84HP;6F6I$9PY<5N.A]:,3AT2Z:7X!.LW"SGLX&1WZ^6:U5`^%VJ*"HJ)2Q> -MR<@`'/+UQN+QY`D;S.@[Q97M"YI^`V2LX019:A-4J-C<8;Q+2=O_VI+4_CYU -M$P$T]ASI5Z2NP1\(W4NS*/O8Q1Y6/EUN*]U($#<#']T?-7OZBK:C5*8$#\.\ -M`.?4B6B?0H.VGOEB?`0L$[CWO0RV;PQG[]YO4([OS^KUC!*VS;,:7,B@%/B- -ML,D]E.)F'Q)BX=J>QGX66+-A([-<4XT!"502XQSFA0'$.ZXX!39$L*F)I?UU_TX"L.M-<1SPH)CSO_O -MA8MW[+D&\>VQP,&#GUYN7_]:`O*R:X7CX8Z!!BVU2QBP<531RE'BN,(?(.K$ -M_/1ZJ6?\ZWC_%H$EZBK^[><0D/]$7S^D?T.:$(4@*$_V -MZ(`````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````8``````````````````*$OPP`Q?VO4_^?______________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_______________^@$?\B__K'_I_________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_________________________________________________________Z!' -M_(O_ZQ_Z?___________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________________________________^@3`'1%0R-%\6=F]S/A7.S -M5W8"T;9`[O=G2*&IP\3W2`(833>H2:8/`,[&-M/&Y!GWK4@ -M,-D75WT2#SF#E*Z5VOR5^KBL`````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````````````````````````````````````````>K] -M7T\[_GZN?T/^/I_GT/4O.Q?SYW0Y_K]^YZGQ].4NQT.+`?0]2.AT80FY^38M -MC-UH&0]R&?>\/3Z/1^X4ZT^!N4Z4:9*:-$CN+!,AN>Z5('3INPWS_NJT>I`Q -MEA^_#-(OO7'F?`N31Z78C35VD7F4.&08ONMK'Z/IW^>?SOHYT6)%!7H['=ZO6]0\WN9L] -M'/S_R?R[&QY8,@B&!L_=C>&?P",_X=^*>'IUO9+ -M!I_[\_Z8<@.GXJ4\>CJ)&GB\`A!8TU=.$"I:?N=I]G]/<]'-T^M!=`D`XCE8 -M!JN7'E&K`DR"8\?V]-7J,5K7UQ5'<+]FEU.;$!Z4&1SM88*"?3W?+[\X)U>A -MH^#]#>$#56&'M?;J>.KMZ57@N-):N7[XVZ;1QQ;]1WA815)8\@RDMF"/+!(/T>IU? -MWK4OKS=:NG&%]=]*GRD($O%=%K]D%*E2C([A*)0WS=*OR3)?UZJ?1?%ZO+K] -MD&B@AY_W88M'73TMN!`>QOM7_-,4)_7>&W]L&3[?T^O_CYNE>^5_+W/_:R>8 -M&Z.WI9_@C:M]"Y\/W4G'3^Z+?@@J68M.)BZ/`ETX[^-^Z"[SJSX,)F&O/0HZ -M0PV66N,;O7>B\5ZX_>#AUFU*WVI\?&E]W:O[6[?0GQJ>MOWGAI^V)\"68D>& -M2/QE?L_#D"*?D5ZV<\L]1++_QO/P@DUZM6?[Q$%DXZ$[R\N0FZ([,@15!+0L -M!=9%K?M7= -MA:YU^7TJN7R`O'VY%71U(S)-WO;4&+1*YXM.65%X90P;)CC4=H$29N95RL -MRS#O),+>/5R.$9X*^/#N=GV$-TE:7,^."D3YWR48+\6.9(7^'M%":>`)GZ4R -M:N*>"^03M8ZJ74[FGT3>#9D960OE@UX%O&6._ZNJYLCB!,W-B\[)W7['!:PB -M\'XY%V/XRP=KA./R6^X<`T;BS9D,V"+I;FS-Y?XJ$K73X^QY*R2."*'P;UJO -M7E$H&N\X@/C%[1L5_;U7SR]WCO/9):4Y?(EI+>S$%V\]''EIWE6,$>6(O@+3 -ME[G#\?");LM@E?-3?CP*;D*S(U:ON4N?E<%T8)JF54U2VJU7FD,O@Z>QJR-2 -MZ]$'[.JA1.GM]KK]*3WMIN@Q8]9=O^N=OZ0OF$'83HEE&QW&8=Q9SC&7(HZ! -MT\56]-ARZ0CWLE=RG0:U[2V)E.'_K,KXFGKD,JPH2W)[CP\?_D'<+S8C_%+] -MEF32B&FU2Y,@:1B;SG3MZD%#;'BC"9%TM*_796%NG31&MW62'&8VV7G2&W*2 -M8_"I^'X>SX96^#80^^+?/@?3A_FU&%BKB"A6'M_R+O`W;3UFK8'X@2EPRF"B -MB.C*H#7`0[(C!G>Y?E@TZ^!XL9IZ9E*Z5Q"L),WOXAO=#HS/?P^GS03$?ROO -MBVREKR,\I>K(/.)^J/,R(!][,]7T6A38[L;5*M -MPVE56+MFK`W=K>U(0(/$!VRF)'4[YX]$*QA:#)'L^(WZY)E"Q)1K^B:IO3ZK -MA@.6L6=`"_YLZ(0Y&3%,0_)L67=S;-O4#B,0'6 -M)R[=^,ZP/SWX0 -M@&.8'L81\%H:KS8?+YM;=WC9+O^/@B!''YT.F5OPU\[;]SX+9M#%'>I]%&&W -MG1`U:.-"-[8';;(*FK?I\/LS.-T9XCHO61;2M@$\`6CG'QY4.\P!GUA3?ITK0 -MCW<&SL8L,37TB/+XZ90SU^_0EB>ZOK]_1MDA*F4]:`/,ZQR;5C2@1O+7Q/$52F4OGN\/,_'+"G,R[7/2I -ML$FBRTX>+,"R`D5>')8'I&,]:7?]56WD.)^0#G"0U,68W%CE(W]/6PQ0MZ). -MEB[;?2AL.OC$%1A/+!#J/''Z]?K%@_&YC/\*V^;9#_'SSHD]N\V0$ -MIHKP^J$Y6AY=(?^EEA[BZV[/+6@$A"3V*>`XXEYGQI+%"%?@DKWC,5,9XRBG -M(DCB3:DC7,O:X1##E0=;8G*N,KDE4="68,2VHU`0SLDRPH(H$Y%RN%;TG->M -M7CEJU'K(37^^OJ7O,S+C%JL8X<2NN"?]\NON0;:O0Y^=/?!#'GEP9VO@VX(# -MO7]M?X]1HA445@;>0V`BP8$E=-_:ZTAPQIY[9A\I2Q_=L9@>&,5(2KFQQ\4* -M*J.*B+AW*?*`5[E.3JD;5XL%UE<[5R+HJ*^O*J4MBU*7)5S4_#J\_&(UO -MF-HZ@43FIH#,4-FD4T6"!9<O"/P;L9Y0\$;5>\< -M;Q]KP2?\5:G'1*;2JR2L'T?#/L4Z- -MGC21?PUWK.CGG+[7ZT8.C)'8_7G=L6D8=%L9<$O#1RM>'TQU#I3K..2U.S!< -MG1N#^&'R6-J&&N&RG5WZN95X/S(V[ -M2D03%@"S:CD[T],"*J\LOZQ]K+%H3[(9Y<^Z0#>U9D`\NU,NSZ?:N?X/3?QI*:J(L6>($A+QV[!$AQ8)46R\6"NEJ5\U?;TP3K0" -MU=5=I'H=;4U\[\8:5_?#VZO-2-P(!N,YCV/$&*U=*H256[0JSR89H)LY4XPT -M5TM\KS63+<@_!J;63WE0P!Z//K2TON'^XDKUL3+KA -MDX)KB4#CP3?2";-\^G*COB>2.&;FO5]JT=/^7\KM#RYKM7V_K5^E%>[Z/*X. -MTR*_CYZ_0DJ@8/1(I2Q7S@SD>/^WD&=5=70Y2B]C4!5^7+IL)S&C;)5@>\6# -M5ET-3EI4?=W.`GG8I@F2(!!$:V,5]4?O:'3\5?+%^M66W]%&>O!"[MZMB$/D -MRR?VZ4"2L?S$[1D#@=M95,6MKTC\C&%[XM+Y[N">&]*BY9?3`;8O;M>-B?KQDWU&&LKY -MO*7BN&Z)?.1LJ9O&\SL.%4K;C4F@!9NMF:=/8UM.OVN_[WZR2-K._^\9OGE/ -M8Z4/D)G&82NF::OD)F;4KU#B?LB_ON7)G*2`48/P@BRROKP^*$_2R0G^YH=[ -ML9>R6.]N[.33"H=?,_CT.?FQ98>3V_Y09`[MO>)F+Y9DU7KK_H\=2!=E-_'L[\&W'RYVML>6W -M2B5XVTKCM8$=QWDW7T)C=H/2`M>F>1Z.EFT89XYM6]Y`.74[6+UO9V-#+L2* -MRG?O$G&H]`_8.C5?AT",*;PS'GFM70XN>WV4Q427^(`*\/X#CB^ -M$(`_Z;QM?B78W;%ULSQ]SP7'831UC7'T-)1'M@\&T\A :U"^,-";S5OB:6 -MG$,M^1P8+(5[>J-K6.5*L'$0+)C=0HM;#!4F--U/NZDV&E#R0UWL[7NQTR?( -MK-5,,P+(U-G9HX8/FZ7$?96E_ZGDBWBI,:/#Y=^S;#LY:>^CB6&-NY)Y7X[_!HZ6Z,D&]`WT!%WRJ<9];OD]9 -MY>24+=]B3T1H[A.%^F.1/,DM#4>!\9]0K>"FYBN[!+*PDPZ'TMGH"-NLKU?X -MK&8!'XW9[RE.P5>/,E6Z?%N:LC`<1CX,4F<@B!KO78!YO$IQ`''Q7JO"IX\? -MBBR#]:TMSQ5EEG7D[+^G+:=BG2QFL>/BO -M-QZJZ$.H`J_PPEC.-JXBK7]T=G#'\]ON_/CN":U"TF8LK:^LVXWN3E`F6;_# -MF@\C#/D]9LWKT#%HA\3BFCW4MIP#\!5<]$0Y$=*]?;JE'.^>7#5O5WUX9)44 -M:))UM76AT?_M55^=35MH -M8SBP1JTK'D6Y=#^?WQI>=*9C8FR=6JV)]+T%__'6]A[DT)F]% -MM.9/8%$580S)=?9\16F`[F7>"]22&A^BE$`:%]89YK8LMX4\?*>YWLG)25RK -M*.K)901`V]&IJZOJ1J_6GW!LR>I^"`[07J:]@%V?5BQJ?SP/;WQ=6$)VG)G> -M,CD;"*2]BO';UTABY)#56A_?JZ>CVO<+0[/9T^Y#1S1\ -M'1BO@_7G[F+:SX]=K^LYM7V:F+!8@8VWCQE9ON?5'U;4?[#8J%5Z%VJ6=4&'1J4HO;()4E6Z9]B#F&EOGA"Y]OY\)@Z$KQP\]L>4<',^O+3P:'OZ[N0-$59`T+&V[RU6]6;[V-V/2 -M\DOQI9RJV8A[VJ&3N-FHO1'WX^C$`6&2L/DNQK)5_WUI\QDNC?X],*1X0H=% -MT;6[0R[0Y+&X>-&5*QYNCCJ;63LCPVSZ%<=8_&<$7YI5O82X$^Z<##T4I_XS;/-5[M4JN)*<.,PUX=<@21*+8?\@!8`NJL$\VJOXQXJ9_D -M3.WKH>4UTR@[R57^/8HS5-09>'[^!EC_/B&H.[#.Q3A=.O\W-$D=K*48D@J19KZ-UX@W5I(05CF6[ -M[(CXM-/'Q^C,.*&X3^7'/##8'_F>E+Z+.!7!K[5XEI)C,E`)2K9=PC^3W!*> -M/=^JWKV#J"(QKCPP6:'6E9)Y.J(:%'W-59W0K-G+@+-9/@"A""&TDQUZZ*Z!(7K==%W;K&"$J@J -MALS;75>P>"E5\-;N4E/M -M0A%P9LKU*,B)FLB7(LC%+GP-Z^OAE/&,`'46Y6\TGV,SB'PST\;25YCUTI@) -M"8'KR_&OC2FE?A7ZGV6/IWY1];IKK:><9*`-O+^*CC4T2?\3C -M_M'7BFGLD;Y)8-WV+?F70"PKR_K2?DS;!F2K#Q)U^)[$X!XV5*%UYZ=7A]'N -MJRJW(KWG&Y:)'M=LW^%%XYMC7J/SQ2BQFE=9%4H:KU#/U&Z)XW&/F1DY^*&? -MKF)^:[Y;RQ8402:`0.G!SK912WR+3;6S1-%I+>%40ZT<0YQAHQO;* -M\@_]:\Z&\O@X6JRH!7L'0]=%F\#4G+=W3O;]?@ST(*H"J*!>=9,1I"NM^<5$ -M,?M3##_F0@61;>:`LF\VDL')];&<]T56:4]2!OY.9(`/*6V>1@]'8#"*GU77 -M;#NK:^GSZ[&-$_(WYR<(5I51ZVR&>0E=MYM$UWTOV5=5'&,CR -MBKOW;AR"NES,-/?Z>M505*><)/.8)UL,A0CY:\.+IC`GC%8_TJ5_HG*`HW#K&]2WB/L(8";`73ZE8Y;1D(J@(T,=])2H!$P7 -M0R:0/B15*(]<*@J1D[43+>O$MZ$A&')!G0?"`I/RWJEW*L#<#D!I$\V:\",/ -M[J!XYT&0)B+9L6#"$>!0#V` -M*;I#]B(J/TC[I-H4P\V$J3&_7VBB^Z,]'9,8PUO5QM2^Y5?P -M1\:_.IO%T4N"#U2-1H8Z]$6"3B%^+CQZ7CM4]>!+A*F1!\CK@_PCBB3,5V$W -MFK@M_W+2%)';;*J7&Y01`W``3(_X7]KVPYX0A2`H3^W1```````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````%`2_#`#%_:]3_Y________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M__________________________________________________________Z` -M1_R+_^L?^G__________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M________________________________________H$S/],17/Z59'_P````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M````````(``````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````````'!,`9$53(T7Q5F;[,_%5R8N9`6#;(',YDX1 -M0Q.'4\P@"&$PSB$FF#V!OD8VT]MR#/_42!R0!DOIUT[>VQ[89(N+GPD'O6]7 -M5U=W5U===[_)5Z$7E>5T:I72NUXE?QTE8``````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````````````````````````````!ZOS?3SO^?JY_0_ -MX^G^?0]2\[%_/G=#G^OW[GJ?'TY2['0XL!]#U(Z'1A";GY-BV,W6@9#W(9][ -MP]/H]'[A3K3X&Y3I1IDIHT2.XL$R&Y[I4@=.F[#?/^ZK1ZD#&6'[\,TB^]<> -M9\"Y-'I=B--7:1>90X9!B^ZVMRLSBZ9H3>*UL(X9WO3T;88(NBWJ;FWYMCU: -M_`%SO[.K)IJ?V@]X?H^G?YY_.^CG18D4%>CL=WJ];U#S>YFST<_/_)_+L;'E -M@R"(8&S]S/W[H'VO3[-G[XE?]16`H7C7$6F?`7.ERJ_\NC3.&L[XU<8.@9'& -ML'1%!-IUL?&T8$DS.,.S_X.*MFY1YV-X9_`(S_AWXIX>G6]DL&G_OS_IAR`Z -M?BI3QZ.HD:>+P"$%C35TX0*EI^YVGV?T]ST4:L"3( -M)CQ_;TU>HQ6M?7%4=POV:74YL0'I09'.UA@H)]/=\OOS@G5Z&CX/T-X0-588 -M>U]NIXZNWI5>"XTEJY?OC;IM''%S(ZHSSRMS1_9,TNG9F9*F04#YUGBD(U/- -M>&+/_<==8H-%>N,41#3C!FNWYH_9"0.>;IUU'VT]?W7S>YV]+1\&G+.*[KK$ -M#3UQL@WJ0$J6U([]?U5-)YOU'>%A%4ECR#*2V8(\L$@_1ZG5_>M2^O-UJZ<8 -M7UWTJ?*0@2\5T6OV04J5*,CN$HE#?-TJ_),E_7JI]%\7J\NOV0:*"'G_=ABT -M==/2VX$![&^U?\TQ0G]=X;?VP9/M_3Z_^/FZ5[Y7\O<_]K)Y@;H[>EG^"-JW -MT+GP_=2<=/[HM^""I9BTXF+H\"73COXW[H+O.K/@PF8:\]"CI##99:XQN]=Z -M+Q7KC]X.'6;4K?:GQ\:7W=J_M;M]"?&IZV_>>&G[8GP)9B1X9(_&5^S\.0(I -M^17K9SRSU$LO_&\_""37JU9_O$063CH3O+RY";HCLR!%4$M"P%R2C.-H4T+? -MC(5%67(4L1#KH$O:A2=CZ)I=,W#/<=T<&R;OD^+GR7]R>;S\[^F=SHQ[7Y?2JY -M?("\?;D5='4C,DW>]M08M$KGBTY947AE#!LF.-1V@1)FYE7*S+,.\DPMX]7( -MX1G@KX\.YV?80W25IT4)IX`F?I3)JXIX+Y!.UCJ -MI=3N:?1-X-R+CMH^S0QQ>.!3VST>W\OZO1/ARI:U0G<^O;3?@AFLT3F^I]O8 -MV(QKO1N<6+Q&9-K=QA#.ND9M!7LK*_-MU6##8]^H@N)@J;S3BOVQ,LPCG>58 -M2+:*V35;YCEAI24B(J0M\Y2JU<8P+_FJF;]*S-YF1E9"^6#7@6\98[_JZKFR.($S42@:[SB`^, -M7M&Q7]O5?/+W>.\]DEI3E\B6DM[,07;ST<>6G>58P1Y8B^`M.7N:0R^#I[&K(U+KT0?LZJ%$Z> -MWVNOTI/>VFZ#%CUEV_ZYV_I"^80=A.B64;'<9AW%G.,9R5W*=!K7M+8F4X?^LROB:>N0RK"A+*,)D72TK]=E86Z=-$:W=9(<9C;9>=(;W_(N\#=M/6:M@?B!*7#*8**(Z,J@-_B&]T.C,]_#Z?-!,1_*^^+;*6O(SREZL -M@\XGZH\S(@'WLQS%ONS2;9EI`:]'J]Q($R)P>2I_(_!G;?HH[593:IE9]G0N -M7S-](4?7E>^>4@I>78H-U)&4K?"-R8TN"?![U?1:%-CNQM4JW#:558NV:L#= -MVM[4A`@\0';*8D=3OGCT0K&%H,D>SXC?KDF4+$E&OZ)JF]/JN&`Y9RTDR+%8 -M]^*4''I8+H\7)5ZQ9T`+_FSHA#D9,4Q#\FQ9=W-LV]0.(Q`=9P_H\#:E^/YF -M=;M#E_.?M8*%`9].H%QA'P6A -MJO-A\OFUMW>-DN_X^"($=$#5HXT(WM@ -M=ML@J:M^GP]S@I5F3)6[EI$<8?3D9#S8$P;-.DD>1K$W7P;>-/K4K#]U>BD`I:`94LW0A136V-35Q0\D*D4T-.9G4K\]6 -MS1LQRXX;IZS,XW1GB.B]9%M*V`3P!:.[P\S\D8SUI=_U5;>0XGY`.<)#4Q9C<6.4C?T];#%"WHDZ6+MM]*&PZ^, -M05&$\L$.H\(J=%/63*%6059 -MI5S;NN4@+*&;)3H3XYQ[U^L6#\;F,_PK;YMD/\?/.B3V[S9`2FBO#ZH3E:'E -MTA_Z66'N+K;L\M:`2$)/8IX#CB7F?&DL4(5^"2O>,Q4QGC**.6K4>LA-?[ -MZ^I>\S,N,6JQCAQ*ZX)_WRZ^Y!MJ]#GYT]\$,>>7!G:^#;@@.]?VU_CU&B%1 -M16!MY#8"+!@25TW]KK2'#&GGMF'RE+']VQF!X8Q4A*N;''Q0HJHXJ(N'9O^=R)+AZ\(_!NQGE#P1M5[QQO'VO!)_Q5IR -M'1JT;BWYEV@ON#"YHZ%6D3QO2/EJIZ<=$IM*K)*P?1\,^Q3HV>-)%_#7>LZ. -M>=VQ:1AT6QEP2\-'*UX?3'4.E.LXY+4[,%R=&X/X8?)8VH -M8:YR2\>?]/](B1SKD^/_1!`&*R=_?9X;*=7?JYE7@_,C;M*1!,6`+-J.3 -MO3TP(JKRR_K'VLL6A/LAGES[I`-[5F0#R[5R,D'<'5V7FO&[/DNM65XR[/I] -MJY_@]-_&DIJHBQ9X@2$O';L$2'%@E1;+Q8*Z6I7S5]O3!.M`+5U5VD>AUM37 -MSOQAI7]\/;J\U(W`@&XSF/8\08K5TJA)5;M"K/)AF@FSE3C#172WRO-9P%3( -M%W9*KVMY,MR#\&IM9/>5#`'H\^M+2^X?[B2O6Q,MS7E0A;A2;>E]NW%CUQV. -M7+EER,>/:W=G;V*-1B.2,#MO`)O[>S@U]+2[-66W]:PCNAZN&3@FN)0./!-] -M()LWSZ09U5U=#E*+V-0%7Y=BF"9(@$$1K8Q7U1^]H=/Q5\L7ZU9;?T49Z\$+NWJV(0^3+)_;I0)*Q_, -M3M&0.!VUE4Q:VO2/R,87OBTOGNX)X;TJ+EE],!MB]NUR,[$M7-\<\+Y#,;N]_M1K)GI77QKEBYM>4MI;7+,J#B?E7"&?@C-PLV15)1(A)GD)$8@P.MK)YXV)^O&3?48:ROF\I>*X;HE\Y& -MRIF\;S.PX52MN-2:`%FZV9IT]C6TZ_:[_O?K)(VL[_[QF^>4]CI0^0F<9A*Z -M9IJ^0F9M2O4.)^R+^^YNO^CQU(%V4W]RLQE88IE2.BPQ -MAKV,CR\8MSJNU7777A5*'O2[F\\/>IT9MX>SOP;3=?0F-V@]("UZ9Y'HZ6;1AGCFU;WD`Y=3M8O6]G8T,NQ(K*=^\2<:CT#] -M@Z-5^'0(PIO#,>>:U=#BY[?93%1)?X@`KQRVC3SHS%X_@..+X0@#_IO&U^)= -MC=L76S/'W/!<=A-'6-V#P;3R$8-EK4+XPT)O-6^)I:<0RWY'!@LA7 -MMZHVM8Y4JP<1`LF-U"BUL,%28TW4^[J38:4/)#7>SM>['3)\BLU4PS`LC4V= -MFCA@^;I<1]E:7_J>2+>*DQH\/EW[-S9EQ.TXS="/O>]BNW50:/>O+OQ.-JE0 -M`3%YL.SEI[Z.)88V[DGE?CO\&CI;HR0;T#?0$7?*IQGUN^3UGEY)0MWV)/1& -MCN$X7Z8Y$\R2T-1X'QGU"MX*;F*[L$LK"3#H?2V>@(VZRO5_BL9@$?C=GO*4 -M[!5X\R5;I\6YJR,!Q&/@Q29R"(&N]=@'F\2G$`J\*GCQ^*+(/UK2W/%6 -M65P'F=(FR7*_.?DKCM)DEZ=>3LOZY.4"99O\.:#R,,^3UFS> -MO0,6B'Q.*:/=2VG`/P%5ST1#D1TKU]NJ4<[YY<-6]7?7ADE11HDG6U=:'1_^ -MUS+C>IC^`2INA63>GEDM8_P[N/1; -MET/Y_?&EYTIF-B;)U:K8GTO05S`3*R`L,0%2$9*[SBV? -M!*ZO]N9R/A+ZMG>$V;_'R[?U7HS-EWC#[[MO:ULV2U+.DLLTV""@#FZ,$'.G -M=,/;L0_9^'0IV%K/Y0/%:^#FQRKI;\V#@V][_\=;V'N30F;T6TYD]@415A#, -MEU]GQ%:8#N9=X+U)(:'Z*40!H7UAGFMBRWA3Q\I[G>RIKV`79]6+&I_/`]O?%U80G:GB,BX@'\MT1.ND3\+D9RKS%4LC94+WR+O -M#I5%G-L=8]R*!I#5.V7#`,HCNP2_"#-G$GE4B69\7+GGUVOYNE_6D(71'WCB -M97ETLMT2"Y6BK*)9>L3>+.]%KG4)T^(G\+`A$[K'-B27U"2YM;=F1'6BV4KA -MCWJ=LQ8I`^%[V*\=O72&+DD-5:']^KIZ/:]PM#L]G3[D-'-'P=&*^#]>?N8M -MK/CUVOZSFU?9J8L%B!C9S?Y<:8[6A]GMO3T.GV>C]G;[?9^OM]JK?:ZV1LB/&5F^Y -M]4?5M1_L-BH57H7:I9U08=&I2B]L@E25;IGV(.8:6^>$+ES#DK\KE=G'6IM? -M8LV;4$.OB5MK?5`!1L]O:0T$GNQTV3].>,)]:3S@E6U9KDKAPNN5+9.2::]/ -MN:/;N:;5S,+0T)\0%=/2[&AW>KU*!SK=:J,@(2N"PW%9W!KB\T>WT[3%?)+Y -M[V_GPF#H2O%R8)_`P9'B__T&"X-I_\KV0>A("_D/:L>!3(?BJ2Y"RVW7$:-= -M2G^'Z",NLI#;QDHK&K(;<;_]?;H%)^9E2*BV.C;($ZV->]'M7_KNY`T15D#0L;;O+5;U9OO8W8]+R2_&EG*K9B' -MO:H9.XV:B]$??CZ,0!89*P^2[&LE7_?6GS&2Z-_CTPI'A"AT71M;M#+M#DL; -MAXT94K'FZ..IMS?4VM*[>-&8[B#UHSF.2)!7WRJLA$AJR#L;>/NJS\*9\JXP -M4:2'U)]W2EC2#[BP9%1GY)R*=CJ]/^^G"CHO5AO,[W4Z1*BZ?=]P.]V]/V3[.[H>Q='K>Z?5NF;D>W\K)STYV/HOPQOZDH@[MU;7`DDVF=L1+MBC0[>WK2J%+` -M!PK6QT>.I+5Z?'8Y5R\-6]78Y]K9`\U^8BL-RIT=/P)W=MUW`<`+7@7.J_M% -M?&GL*GT`9Y9.R/#;/H5QUC\9P1?FE6]A+@3[IP,/12G_AS*3.>)L-E>+_%NQ -M=[-L\U7NU2JXDIPXS#7AUR!)$HMA_R`%@"ZJP3S:J_C'BIG^1,[>NAY373*# -MO)5?X]BC-4U!EX?OX&6/\^(:@[L,[%.%TZ_QP]`!V<@\;EL@[&7&E -MD&AW(BSGW*'RLG2C+__M/40````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````?^TO(_HQ?VO4_^?__________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M___________^@$?\B__K'_I_____________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_____________________________________________________Z!'_(O_ -MZQ_Z?_______________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M__________________________________^@1_R+_^L?^G______________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M________________H$?\B__K'_I_________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_____________________________________________]"'A_UBY2R"4]W" -ML*RE:_OGG3#+\L@,>,PN7D[&4009/5G@?.;JM:BXCPHCK]VV[!W!8P -MYAI3ZHH(AMZ-VR@&&VJ'#SQX0QE)?R4N3VT'614`IIGL^R($79%MI#B-X4CY -M2<,-?%!I-[HQ#M]PYYZ?6SOAM+5LW -MF&<#GI93057E-9"T'5(%972#)X_X&MZ%%>,"#R0K[^%DUAQ_L=6WC_=;3^$B&IX@7 -M6#\FJ!/@DO,_:Q4&@$=1%+9L9'QX-`*25C]4+S1EM<'\+&/@+SZ!Z;8S%PZ; -M(==I$41B7WFK6VK3@'SRI+W`+B[X)G@4O0_W,7;CI_)#=I9$>48_/@*[!9_P6E;Z30VBMPXWC4A -MRUON:T2OHRGTI6-N1.9O4Q7!K2]V<9LB\ZOK`;O-+6./K\O;V>YL3U0;<@G] -MLA2,Q)]X^--?L#,";:,7QJQN4A;W5Z;,Q7 -M)^5/T,L?'O%IN1VBJHSYE"_F##3P-7AKO2*<+FA"Q7SX?[-K1*!"L]\N9+:. -M0,0/+O.NFOO8/98)R4T.=YUS'P05OYLC5UIA3#;.%]R3H86ZW$_$0R7#/%`, -MXN35/Z7_EIY(DISE:VN1+&?5:$\/OB?_.UY_;YHU]1>KOO^1>SO&=^G!C.=( -MELO]V=4)15`MSI")D`+9IQ_M4>U*+:4'_Z>[O6X((_Q"?<;ZJ5$<+9V6$EU40\:$&L%"BJB(8<0I[G_ -M!\`J./DJ`+W_1/'D9-O>\"'>)A+>%(A^RMG>^['D=3[P%6?=^<0A-E2XHAZ& -MM=M"/D&+NG;>+:_<_&(J-_X/$>`%(*^FHJEU.9*6OP.!?U:YX0_DSJ)4K>;9 -M<`K%R=FAF@5??,.T'?Q$9N9;%S:]GTXV!-OLL]NJ;\1'O+T/NS/BRH>?$*/D -M[P!,C_A?VNV'/"$*0%"?VZ(````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````````````````````````````````````H!+\,`, -M7]KU/_G_____________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_____________________________________________________U95>P]` -/%`##I8[U```````````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar_multivolume.part0002.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar_multivolume.part0002.rar.uu deleted file mode 100644 index 696ff565b..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar_multivolume.part0002.rar.uu +++ /dev/null @@ -1,1337 +0,0 @@ -begin 644 - -M4F%R(1H'`!EZD``&I!9PX#%Y:4IOAM$C\= -M-1T`I($``'!P;61?;'IS?$J_A%^K -M]7@Y2NE=K\E:7/38```````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````'J_/Z>=_S]7/Z'_'T_SZ'J7G8OY\[H -M<_U^_<]3X^G*78Z'%@/H>I'0Z,(3<_)L6QFZT#(>Y#/O>'I]'H_<*=:?`W*= -M*-,E-&B1W%@F0W/=*D#ITW8;Y_W5:/4@8RP_?AFD7WKCS/@7)H]+L1IJ[2+S -M*'#(,7W6UN5F<73-";Q6MA'#.]Z>C;#!%T6]3K7X`N=_9U9--3^T'O -M#]'T[_//YWTH>;W,V>CGY_Y/Y=C8\L&01#`V?N9^_=`^U -MZ?9L_?$K_J*P%"\:XBTSX"YTN57_ET:9PUG?&KC!T#(XU@Z(H)M.MCXVC`DF -M9QAV?_!Q5LW*/.QO#/X!&?\._%/#TZWLE@T_]^?],.0'3\5*>/1U$C3Q>`0@ -ML::NG"!4M/W.T^S^GN>CFZ?6@N@2`<1RL`U7+CRC5@29!,>/[>FKU&*UKZXJ -MCN%^S2ZG-B`]*#(YVL,%!/I[OE]^<$ZO0T?!^AO"!JK##VOMU/'5V]*KP7&D -MM7+]\;=-HXXN9'5&>>5N:/[)FET[,S)4R"@?.L\4A&IYKPQ9_[CKK%!HKUQB -MB(:<8,UV_-'[(2!SS=.NH^VGK^Z^;W.WI:/@TY9Q7==8@:>N-D&]2`E2VI'? -MK^JII/-^H[PL(JDL>0926S!'E@D'Z/4ZO[UJ7UYNM73C"^N^E3Y2$"7BNBU^ -MR"E2I1D=PE$H;YNE7Y)DOZ]5/HOB]7EU^R#100\_[L,6CKIZ6W`@/8WVK_FF -M*$_KO#;^V#)]OZ?7_Q\W2O?*_E[G_M9/,#=';TL_P1M6^A<^'[J3CI_=%OP0 -M5+,6G$Q='@2Z<=_&_=!=YU9\&$S#7GH4=(8;++7&-WKO1>*]6>HEE_XWG -MX02:]6K/]XB"R<="=Y>7(3=$=F0(J@EH6`N249QM"FA;\9"HJRY"EB(==`E[ -M4*3L?1-+IFX9[CNC@V3=\GQ;DZ96QH>C%MN4HE9"R03,]B.#?5\%/.LBUOVKNPM[@^$)19E-9HX1W=F7.%0/ -MS:+=WTNWQ[?%D&'W%BA>CT^2_N3S>?G?TSN=&/:_+Z57+Y`7C[V>CV_E_5Z)\.5+6J$[GU[:;\$,UFB(S)M; -MN,(9UTC-H*]E97YMNJP8;'OU$%Q,%3>:<5^V)EF$<[RK"1;16R:K?,=D[K]C@M81>#\<0'QB]HV*_MZKYY>[QWG -MLDM*>CCRT[RK&"/+$7P%IR]SA^/A$MV6P2OFIOQX%-R%9D:M -M7W*7/RN"Z,$U3*J:I;5:KS2&7P=/8U9&I=>B#]G50HG3V^UU^E)[VTW08L>L -MNW_7.W](7S"#L)T2RC8[C,.XLYQC+D4=`Z>*K>FPY=(1[V2NY3H-:]I;$RG# -M_UF5\33UR&584);D]QX>/_R#N%YL1_BE^RS)I1#3:I4O5D'G$_5'F9$`^]F.8 -MM]V:3;,M(#7H]7N)`F1.#R5/Y'X,[;]%':K*;5,K/LZ%R^9OI"CZ\KWSRD%+ -MR[%!NI(RE;X1N3&EP3X/>KZ+0IL=V-JE6X;2JK%VS5@;NUO:D($'B`[93$CJ -M=\\>B%8PM!DCV?$;]4'S=++['9N4X&O$Y=N_&=8'Y[\(0#',#V,(^"T-5YL/E\VMN[QLEW_ -M'P1`CC\Z'3*WX:^=M^Y\%LVABCO4^BC#;SH@:M'&A&]L#MMD%35OT^'N<%*L -MR9*W;`F#9ITDCR-8FZ^#;QI[C]X%!XD7Y#F]CJC'^^0,;#OR, -M[U:E8?NKT4@%+0#*EFZ$**:VQJ:N*'DA4BFAIS,ZE?GJV:-F.7'#=/69G&Z, -M\1T7K(MI6P">`+1SCX\J'>8`SZPIOTZ5H1[N#9V,6&)KZ1'E\=,H9Z_?H2Q/ -M=7U^_HVR0E3*>M`'F=8Y-JQI0(WEN3^?%=([E;=GW/@>2I!>_FP<`^U''F?CEA3F9=KGI4V"319:M+O -M^JK;R'$_(!SA(:F+,;BQRD;^GK88H6]$G2Q=MOI0V'7QB"HPGE@AU'CC].== -M>OD5NHF7YD$TK.H`)PSKM<"9?\@G+5NJ#,ME=_'G!"YSD;<;AE$;_G@T,]N: -M6](`V=`FY?E-&*;K4-JT%2M\YU[BC:3Q%3HIZR90JR"K-*N;=URD!90S9*=" -M?'./>OUBP?CW>;("4T5X?5"HT0J**P-O(;`18,"2NF_ -MM=:0X8T\]LP^4I8_NV,P/#&*D)5S8X^*%%5'%1%P[E/E`*]RG)U2-J\6"ZRN -M=JY%T5%?#!JWE5*6Q:E+DJYJ?AU>?C$:WS&T=0*)S4T!F*&S2*:+!`LN.<4D -M3H<7&1^;S-_SN1)"-JO>.-X^UX)/^*M.0Z-6C<6_,NT%]P87 -M-'0JTB>-Z1\M5/3CHE-I59)6#Z/AGV*=&SQI(OX:[UG1SSE]K]:,'1DCL?KS -MNV+2,.BV,N"7AHY6O#Z8ZATIUG'):G9@N3HW!_##Y+&U##7.27CS_I_I$2.= -MF!%5>67]8^UEB -MT)]D,\N?=(!O:LR`>7:N1D@[@ZNR\UXW9\EUJRO&79]/M7/\'IOXTE-5$6+/ -M$"0EX[=@B0XL$J+9>+!72U*^:OMZ8)UH!:NJNTCT.MJ:^=^,-*_OA[=7FI&X -M$`W&UO)EN0?@U- -MK)[RH8`]'GUI:7W#_<25ZV)EN:\J$+<*3;TOMVXL>N.QRYQ1 -MJ,1R1@=MX!-_;V<&OI:79JRV_K6$=T/5PR<$UQ*!QX)OI!-F^?3E1WQ/)'#- -MS7J^U:.G_+^5VAYQJ`J_+ETV$YC1MDJP/>+!JRZ&IRTJ/N[G`3SL4P3)$`@B-;& -M*^J/WM#I^*OEB_6K+;^BC/7@A=V]6Q"'R99/[=*!)6/YB=HR!P.VLJF+6UZ1 -M^1C"]\6E\]W!/#>E1!7CZ9V'"J5MQJ3 -M0`LW6S-.GL:VG7[7?][]9)&UG?_>,WSRGL=*'R$SC,)73--7R$S-J5ZAQ/V1 -M?WW+DSE)`*,'X01997UX?%"?I9(3_W=G)IA4.OF?QZ'/S8LL/ -M)[?\H,@=VWO$S%\LR:KUU_T>.I`NRF_N5F,K#%,J1T6&,->QD>7C%N=5VJZZ -MZ\*I0]Z7\@'+J=K%ZWL[&AEV)%93OWB3C4>@?L'1JOPZ!&%-X9CSS -M6KH<7/;[*8J)+_$`%>.6T:>=&8O'\!QQ?"$`?]-XVOQ+L;MBZV9X^YX+CL)H -MZQKCZ&DHCVP>#:>0C!LM:A?&&A-YJWQ-+3B&6_(X,%D*]O5&UK'*E6#B(%DQ -MNH46MA@J3&FZGW=2;#2AY(:[V=KW8Z9/D5FJF&8%D:FSLT<,'S=+B/LK2_]3 -MR1;Q4F-'A\N_9N;,N)VG&;H1][WL5VZJ#1[UY=^)QM4J`"8O-AV@;Z`B[Y5.,^MWR>L\O)*%N^Q)Z(T=PG"_3'(GF26AJ/ -M`^,^H5O!3/Q19!^M:6YXJRRN`\SI$V2Y7YS\E -M<=I,DO3KR=E_3EM.Q3I8S6/'Q.9N*P5/7FX]5="'4`5?X82QG&U<15K^Z.SA -MC^>WW?GQW!-:A:3,65M?6;<;W)R@3+-_AS0>1AGR>LV;UZ!BT0^)Q31[J6TX -M!^`JN>B(OMU2CG?/+AJWJ[Z\,DJ*-$DZVKK0Z/_VN9<;U,?P"5-T*R; -MT\LEK'^'=Q[C_A1[%C_@LS>&O*J_.IJVT,9Q8(U:5CR+<6SG">\*[[L0?/T?<3SX)75_MS.1\)?5L[P -MFS?X^7;^J]&9LN\8??=M[6MFR6I9TEEFFP04`P]R:$S>BVG,GL"B*L(9DNOL^(K3`=S+O!>I -M)#0_12B`-"^L,\UL66\*>/E/<[V3DI*Y5E'5DLH(@;>C4U=7U(U?K3[@V9/4 -M_!`=H+U->P"[/JQ8U/YX'M[XNK"$[3DSO&1R-A%).5$7Q!_$Y';T\1D7$`_E -MNB)UTB?A8JED;D<+DAPAN&+4#[5-U]'SS*A>^1=X=*HLYMCK'N10-(: -MIVRX8!E$=V"7X09LXD\JD2S/BY<\^NU_-TOZTA"Z(^\<3*\NEENB07*T591+ -M+UB;Q9WHM]3MF+%('PO>Q7C -MMZZ0QNU_6AT^ST?L[?;[/U]OM5;[73E4T^41=^;!/L1"OKHRR4 -MH+K@4KZ2SLKOW&WQC6#.^B-:[,5*;VR-D3E6/;QXRLWW/JCZMJ/]AL5"J]"[ -M5+.J##HU*47MD$J2K=,^Q!S#2WSPA<$JVK-I0.=;K51D!"5P6&XK.X-<7FCV^G:8KY)?/>W\^$P="5XN3!/X -M&#(\7_^@P7!M/_E>R#T)`7\A[5CP*9#\527(66VZXC1KJ4_P_01EUE(;>,E% -M8U9#;C?_K[=`I/S,J146QT;9`G6QKWH]J[EYMXRF"G,N5VPDP/8>>V/*.#F? -M7EIX-#W]=W(&B*L@:%C;=Y:K>K-][&['I>27XTLY5;,0][5#)W&S47HC[\?1 -MB`+#)6'R78UDJ_[ZT^8R71O\>F%(\(4.BZ-K=H9=HM&ZG3C^!8+G(M0@?))-OP^6W[._H]GJ:<*3) -M=&#H!T>UU_KR)473[ON!WNWI^R?9W=#V+H];W3ZMSF7P^*/_3?C&=BY+*B?% -M3TSG.Q]%^&-[D-JQ0HZ5P=N_D#W4E$'=NKER,[9$K4[.HLZL1A=T -M:G.8W,U*[\@+NI*PUQDSS:X$DFTSMB)=L4:';V]:50I8`.%:V.CQU):O3X[' -M*N7AJWJ['/M;('FOS$5AN5.CI^!.[MNNX#@!:\"YU7]HKXT]A4^@#/+)V1X; -M9]"N.L?C."+\TJWL)<"?=.!AZ*4_\.929SQ-ALKQ?XMV+O9MGFJ]VJ57$E.' -M&8:\.N0)(E%L/^0`L`756">;57\8\5,_R)G;UT/*:Z90=Y*K_'L49JFH,O#] -M_`RQ_GQ#4'=AG8IPNG7^.'H`.SD'CDR````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````Y?C_Q[O\?H[OZGR_P[GIYZ^E_ -M#YOX>G__+:2Q1_Q*=6?_1I\;_^NGE>L.A>"$BG>H5PH<%D4*^S`T'!>&1:+) -M"4O#P*AC8[^7\IS&7!O>S72H0ZD0SA*YNYG\/'#I(BP[V:2*1Q0[GKT:+:V. -M]*WYZ-^F:7M!0R>&RG3CF5FDO72W4\LTIFB;]$X]2:^LW/),H3'Q\R^;/%>W -MS?'QRC>"J+MHNHC0R%HR>:20#FF]Z96/AGJWGAY\87]Z$8?U^]P\DW9=,^YP -MZ;16UC9_>-[P38>$-MB'GYHV;L%PO)NQM+S=S4,.1G2BB7GXK9:B]K\HU>X$ -MH?BNB0B9IM4MK)'#*-LS5<4F&V&C8@_5/8R=GSW42Z(]'@OTWU)$YE<>WX>/ -MAX8_>7N[DV.75X(W?R29IG!D_VC6TMD)-TR0< -MG:]_14#F!"JMDGJ2ZJNY55Y_+E6[FK.A.IR-`,T['?@\SBO,N[56(X"GO:.> -M;AOFDST9.3!MH<66]EW789MP"BM<-^\'N.,&_$=2<#O)FJ^@?V/1G]5]2<#* -M7G-+\ZF\`\4`S:DJ^\X/ES[^]J0=KZZF,;NU;S?Z5:HO,\1U][8-9R]OW;F6 -MP8$M0]B271S@P^CLV[60$.@XU9"PQC._J$8,7"-:%IX]Q.S;+E%!&N7>AH:< -M$5RNK?WZ/LR.0(5.I4@7\_LUJRUHLO'"0!FU>+(0L9@97084^_GS^:+AG)X]H#&M1(#F]( -MWC[..'+0(+/HRS'D]QV)T4B.2>U^M1X.U2AA$Z&[S=XNI!2G#`?%=\,4L-7@ -M>XPW_+EQN7O&-AMZNGH$&I:8)W5L=TY(0]G&_R?1&'UD(_6@RX\E8`X[5W>W -M]/EF8O]]D>./=16BS<-5_F7'Y1D+9IE;`N)QT:8D&8[>K.E4-O8]1 -M?K::?EX\DJ"Q\6!1?1T>>ZRC).Z=CE,T'3HN2GAE(Q'!">%Y*:_RR+CSV -MZ@M1^]YVL_%[GSUA(R2D[)=`M)FT@Y)-F??ND_3Y[\G>'O^X%A.KR=Y -ME:9S&$GGY-/!Y_DQYM?+V]KYNW^^_4NK<'0(, -M6:"\,M^:T=\]:O^T_'R>7UE)YMYN#4>=4MJ/->[W+M;EK/RG3^W3.%?9[]#7 -M4O<^>P/<413]FF38[71HC3+RU]?M_//#-NVF^Y7^Y+8F;=KX^ZW<_GY*^+#P -M;6[\_<_E+U>];A:O$\I!VTSA>N3.?EQ!7V-7\=O^?;U_P;\B6VGL01`[NQ_U -MV/EV?6_[KUMZT[O9_GVNYTV1/KH!%W?X_-$Q6Z*VCY:Z`\F73*L5=?+\R5(5 -M^AD3:_4FPZ;!;9^"3#]R[T>>VT\2BI\L[AOC&B]JMVN_Q>W[)OSM7;_AV_\O -MY8!>:*,6^1^+],QGW%9XO+6V;MX[)*$5_/*RR#[\/?@Z]=!4^=::8E1311V% -MRF!#BWNNH`6H?QP7P:$Q(8=<#1R8"'K?=\M1$]ZR9G0@1-I$T1LX+]>?B]\9(V;OBT_`1`Z(?=DI7W,=_I_6!I+X?QP1X]B^)PI8_(/; -M:]Q#A\%=U]V3*MJ6PXH!IAF0;TC;,)_4^:80)[^-XR)WIO9*Z(;.RY;.ZCT3 -M34X)`;^7`)G!CJ;U5;_QWC172EQ5)6DA^I]KN8I@#C)'Y\TL_IF+YAP`2F?+J:F1&]L^.I?YQ<'.Q -MGW\_DY**7%."8^.[EOJJ4^I!8LAMT8'W*)(_KSZ:PS!2,3M/EOH!?3V-&(93Q1@]%>'('N10B'[ASSP(7E_+)&;-F[@P<5G16<]$X9 -M$C`X%NCG&WS1XZ85/CZ[%/J-^79*H.[NT;%V?BO"P['_B4;L9IM5*3!+D[3L -MW!!:^%X/H(?\AZ\ODR0"#[2YY/I(->I2G^:%![5NS8#7%`9,;<^B+JE`R>7> -MEK;V(<7GI)QFM"^J;$DOG?M?GFG3N'9NH20GEJ.`Z?/FW,TUHN?*TH$@S\?K -MK_SX/[V4-:[5Z.H(@FQ]7?^OP?=1Z&]CH9"[-C-?^_0.+?)_C,XS)I+\?GQG -M$]C_'Y.A::<4]CL9-C^=LJ[<\/T_V\'_;V2_?_GL]"T=#UL>!5=R.WA-/VW(@K["^S_S6'4X#Z7"9*V -M'%).\V[S+NWRDT.#_DLJP*//`HP'V(;,R&O[/<[?=^;M^[EVGXER]X8%UH6, -MD14XN36"A-7)J)A>CM=J%AFQ/_8S4LD9 -MEL4&Q;XT:A^F[X.N.=2/8GFZB%%5_TQY9$J9('W!JKKM84)DR%\"?UFIS#(F -MW,OKO+29,??;54.TUVIA(`J?ELM&2<77#.I3M'WMZV\'X??!IFS")Z>_<5]2 -M3S8V5V:WS3Y[4Z($%$`R*0+_3& -M^=6.G3=_F=OZ*5FX[.U=^$44(MDNN1*-:FD-5<-F0!4Z+CD(&ZS`PP:Q,7/? -MY;W<_V)&P/+!Z/I]HK"YTVJC1OP+704FTUIQJZH1='G]V;KS3?Y)T/"H;7WLW/# -MPQ+^MU<"T=21B_LYO9=O=Y)-L?;Y[=O)-&5HC$Q\.QRN-]Z*.6L1AY81FWLN -MCX2)ILQ]_#=?74B]R[[,U`28+FMTC(`+SV:&E:+,9M%^'8GO53 -M@OWCY>E$\5*(473SU#:(T7E6H1ZL)-IQN0*$K^<<92A6F3)E2%V8K0OY,\U3Z;I^F(S?)\L4:%EZ\A&3>KV8 -M_$0/3``,OWR\5*LWQ=6QV)NB:'_!E]$N&O/"=)NP0$A+:PA03]]:&GY"G<$B -M).]M=GK"Y!],0%M37/1F*OG`]$VTQ,7Z2*O(\AH]PYM>NKZ/1FI8:M]^4*\8 -MVS)U;*?AD66TTPC=X^*;Q2B+VYSY>$[T9MNA*=H/!C"GJVLY/+^[XNF"HGK6A];1>V+,07LUM+TQ1NS4 -M%CYYY0F3KL4US$8U#<,QVIL.S)X\L0LC)LU4*P?\%VE6!6PW:A])<'L,F'EE -MQ.C22)=Q:='60-8?,$:@OA#FI^^N*8A%,3+6F-S6FJ^UK7=/JB%4HG1:O;%* -MB=4_'1$NP=J,]QZ<+==VW\-)P]@F]P9>"8:?BQ`_YM-7$[S]R99TWMEO\DW1 -M/^M#4`R5]6K0NG"*TZ7W0`WYI`7YN'HL(^D5F]:'X@L+/,L`UY:0^Y4SI#9F -MEA$&Y8)G=$(FF2-C'3D_W.#/NSZ:,1C/Q1%H,(X,5-\RS:(7N!F^]10O[U+D -M;[H7EJ+4,7_78&$+:5%4]JE[24+M6U3;R>"V'[NJ -M,3/E[/T6RQ_[P6L^@2)X;4!J@&'#@:]]N04D@/2*Y<;]V$&%WH97VY]&G%[4 -MKRUG`$7/.I"7EEN++*T(`E7CI=*_)L\#6P;GBB)6J?+R6C>K1>`7)65#WX,<:ZF<_/)*_:IH\F[YKK%,52UCU]RP+ -M_Z;=*J_^/=@@76SS$@W=V$CJ!]<$?V1\SU+1FW/=07_Z?9#_$JD@],H0?H53 -M`[.>R4J,R;RVQFU#N=%[K\OR]B&(0Z8)=9Z9EP52)Y_CD`W=\6*5D9NPJM&8 -M\_#EI34W9_:XYT",S\-BP$-5Z47?Y=[K)(NCP\VZ#\T)#=[&OWWD@?%J)I4U -M7FL4&9IOXJ<,>R$HMG^FNL-:W83P1GH$=UT&:C?LF\U9-8WY^JKU?2`YZ]>I -MV?@WK]N7@K.H?5G4C!G&:`S$(#=/@$HU>BV?#SM%I_#DX-_TKS5>GOSP:/#E\GP\A\QK9!V??79J;`^]O",N_AF_/+\ -M*\XM'W>DT=3O3[8=G6MVKILA3MRSWVR<6COPE#]3Q'[N=+%;?@7O]-84'GK-B6*/6+1+#M7>'W89HDMS9=Z(GGXIY/TY]5;QX)2& -M[N9;X8YNG.)U(!5HN$7Y#B5K,2`-C=Q]9(FB%+\F+4TH)#O=SE#U<:=NZ9UB -M211ZU;J5F-07PXYJZ%EN)\*Y=KCXYW1BUC_K.A,5^XHN+_I+RJ@[V-Z -MSD7#CDVK*OXC+9YPU4I)[Y>?4>VW16.]9#VDT*3)IZ9";HZ`ZNQF(#YW.=7] -M?+M;M#7<",7M"^S:4STF9&.HM,6&=Z41G60DI,^O+Q5&[F!5BXWWN>S)6B*> -M'0LT]=3:=_J7Y=JL2X9/:[DAO11(N,MRXF4&73`DH?5\&GXY+5M=?Z<]*9*<-;5AV4)$U71",=Z/CUW&+(DT -M)I_11#=G8U4/2R-K>B_XH'AB.T;7)V.S]%.?H4UY6K\Z1:]HG&DLFWMGTT2V -ML4&S8^N:1GE>)N%C]='T4FF"*8<;DF._$?-5,NUD-V@2LX%4EFOCXL -MN%PT>'UIG%B:"+J]`R>S+CB(_I,-'9DT)L`5;U7#!I`T=I%^`W?%A\5H6,AF -M-_E;UI7IUS7<+/'1;MUA-Y,:+V?44--9]'H<_9Z>=4[YU -M1D*%\/LL.90.B]E1D.7?%TD_$*IT=%,:<$"3 -ME^[:\M&LO?CENGP9NG;JEX4=3%`1,<>4SY0U*^'U?"MH;1@=V0W[$+/"@^N.EI%0S)?Y(7&L.=]%GN1[D@AH4B^NAT;]3>?0 -MDUS[X6^H)@P)Y;I:NG!NYR08%BV4I2YNY^.INJQ7J&!%()+4O7&3:L.IDLNX -M=*W2TN/5,:.]>^:M -M6_/;AFI3S"(W/\=]?XIH<,X&9P:74N(9:,W,NF0)<]U=,P+>]Y.,M\N-T1/L5YX?%=RE]Y=W5@>3_U"BQ -M2F8>%HIR#;HT#)O54Y8H2S=$EB8)!EH<5PA\:ERS]M_2:.C+6DPVG3R="NQ6"+%U?@#Y)M!3WG`U+!T.# -M,64=C%\\;[P9_F0'Q1#SBZC]D0(GP]Z(^#-II[]^_\X&MBY+&,:N-V4E$<7C -MR;M;5R7>.:NE6]90B[FP>D5^./AF_#8DFF?43E*;$S3= -MYEJ]6B:5TXE[L;48,3?W,@TH;\NYR2N#629=:Z/1DP=NU\F.W>*T*+U7V*=0W3)00U/X\ -MDO3FXL:T&EUL+V0HN*:=5(`;=\W)27)Z0@;NZ: -M<>TZT5T5I:/;4L07U`3$*7]FK'O\EZ\I:$M\;\YF@.^Q.Z04W%$1T=2YX^K- -MH\V,6R/[Z`K>'/7QRA$*7S^#Y/OV.]_?P2@GZ7,?L9WX_.LE8.DMMW3@GZ7` -M/)A-_E&+]GX:49G\6>B9E-:-H:/OE-J[QRZW*B-.HJ0C2#2.+R9<(W-O?VNH -M!S+9:1S;@\\G(/+(O!FB*HM&SA])28DWV>3I\+6'YQ7=QZ-274K=QN2@'JTJ -M961D/HO@MBS&2HB^2;AN?-6$AM:74PCUO9I!=DXB@ETY_%]2A$>R+UU+E_Z^ -M/\_SY7EI]"%8\&QRSC-E;'CP\\8G:8K\LQU,1M&U:5,GDB66I`+RRKQZFV$+ -M:',3S\?%YX>T6:?!^FH^6[Q'+.L:?N%R(RQ=,>B(,ZFJUY/'BD0W]NB[E,4S)N1`:DQDI)K5_?#7L% -M\=HIN_6M$-TQT?:Y+F.<&\V(9?A,=G)3<"R-[$BA0%'/5NS.D)\HH(T3=/\; -M'WQ)9..X;-'2$=OGEE4^*G]ZG#%4J&L0A2P&[]OA]O,@&.U7:*I]_V]?C8BC -M'@K2<_9M2T#1>T-[K.OC%N97C"G<>>?S9;:+FN/XK1/R2WXQ;CTS9/"6>.*;L%,O_2&&7IYBS!2G? -M-IO/H;[O/4UW_LO29;1(W"J;CH%12*TH["-D2MX^J'P8*&;=93_L/;/RS;+> -ML'RW^A\FQ3Z"&3&NO5R]R&'S*$GI2EWHHD1P;9NI[U4.C9A]:R];N2NOBR0> -M^A6CMVY?@JGX6"Z<;`S5BI[T3D$#$BB6`.S\5Z+I'-L/=SSQ*V>S?0E3'MK! -M&:=#69($.B9(_OQR['6R$K7'5W5V$A8^Q^?T3@R[\H_9L"[HYS=_?L&128FX -M))Z8"WGKVR-?,S+A23JU]40-+&J_8Q -MY5HV:X1**[<3$VA$&DQ:(1PMS?S[OFNKE6S9*FJYVH(]S9[7[SVVR`FFJ#2U -MQ3X(R5,,>=.%XH5_;<"@56B:R;@DY3H`YO9^>OAO3WY=55P?9PK6-YLWL4IL -M_A#WT'![>GQ0SD;"7^+^N+E/^O)B$IW97EGX)HMF_DY+>0S&;\Z/X -M*[4HX-0`6&ZIZE3]YXSVHG.&W:\]&U[FTV'$NGEC$7?F2]H3)D)IR7Q1-YY( -MATC&DUB;1>N,WG:ZG[:[`2\_&1F?)Y,'/Y*YY;PLM/:Q[D3(`2X^EH7?Y*90L^+\6 -M-W0%CC5P9:B@9'R14RFLDAS*>3"KK1WZ_9K!>8HHT9^*AW6Q;S13I3>9(RNV -MF(5JCUXDX[N8_8B[IT1(LU*J]_SWPM_[?N2>]\7;J>[2.V^9N]&!>.Z/?R4F -M(*5RD7>_'-0VK+4V -MN=\DLK?Q^:N!T8LT13%V9R1]/`+Z5.>L[IQ3MW/D^;8GW*#@`;__[3HX```` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M````````````````````/_E+Q/[,7]KU/_G_________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_____H!'_(O_ZQ_Z?___________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________________________________________^@1_R+_^L?^G__ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________H$?\B__K'_I_____________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_________Z!,`=$5#(T7Q9V;W,^%<[-7=@+1MD#N]V=(H:G#Q/=(`AA--ZA) -MI@\`SL8VT\;D&?>M2!R0!DOP\\./&QXPV1=7?1(/.9RZNKNZNKKQWGQ*OX1? -MJ_5X.4KI7=_DN>RP```````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````>KO]/._Y^KG]#_CZ?Y]#U+SL7\^=T.?Z_?N>I\?3E+L=#BP'T/ -M4CH=&$)N?DV+8S=:!D/EV(TU=I%YE#AD&+[K:W*S.+IFA-XK6 -MPCAG>]/1MA@BZ+>IN;?FV/5K\`7._LZLFFI_:#WA^CZ=_GG\[Z.=%B105Z.Q -MW>KUO4/-[F;/1S\_\G\NQL>6#((A@;/W,_?N@?:]/LV?OB5_U%8"A>-<1:9\ -M!E!D<[6&"@ -MGT]WR^_."=7H:/@_0WA`U5AA[7VZGCJ[>E5X+C26KE^^-NFT<<7,CJC//*W- -M']DS2Z=F9DJ9!0/G6>*0C4\UX8L_]QUUB@T5ZXQ1$-.,&:[?FC]D)`YYNG74 -M?;3U_=?-[G;TM'P:I`2I;4COU_54TGF_4=X6$526/(,I+ -M9@CRP2#]'J=7]ZU+Z\W6KIQA?7?2I\I"!+Q71:_9!2I4HR.X2B4-\W2K\DR7 -M]>JGT7Q>KRZ_9!HH(>?]V&+1UT]+;@0'L;[5_S3%"?UWAM_;!D^W]/K_X^;I -M7OE?R]S_VLGF!NCMZ6?X(VK?0N?#]U)QT_NBWX(*EF+3B8NCP)=.._C?N@N\ -MZL^#"9AKST*.D,-EEKC&[UWHO%>N/W@X=9M2M]J?'QI?=VK^UNWT)\:GK;]Y -MX:?MB?`EF)'ADC\97[/PY`BGY%>MG/+/42R_\;S\()->K5G^\1!9..A.\O+D -M)NB.S($502T+`7)*,XVA30M^,A459Q'!N;6ZY-6C.JLQ%/Y52F+3EE1>&4,&R8 -MXU':!$F;F5"OCP[G9]A#=)6ES/C@I$^=\E&"_%CF2%_ -MA[10FG@"9^E,FKBG@OD$[6.JEU.YI]$W@W(N.VC[-#'%XX%/;/1[?R_J]$^' -M*EK5"=SZ]M-^"&:S1.;ZGV]C8C&N]&YQ8O$9DVMW&$,ZZ1FT%>RLK\VW58,- -MCWZB"XF"IO-.*_;$RS".=Y5A(MHK9-5OF.6&E)2(BI"WSE*K5QC`O^9R67Y] -MC5FY)L.*-/U(/D;#*)DM75HT%ZJ9OTK,WF9&5D+Y8->!;QECO^K]7-D<0)FY -ML7G9.Z_8X+6$7@_'(NQ_&6#M<)Q^2WW#@&C<6;,AFP1=+M5Z\HE`UWG$!\8O:-BO[>J^>7N\=Y[)+2G+Y$M);V8@NWGHX\M -M.\JQ@CRQ%\!:!3]M-T&+'K+M_USM_2%\P@["=$LHV.X -MS#N+.<8RY%'0.GBJWIL.72$>]DKN4Z#6O:6Q,IP_]9E?$T]'C -M_\@[A>;$?XI?LLR:40TVJ7)D#2,3>L -MU;`_$"4N&4P441T95`:X"'9$8,[W+\L&G7P/%C-/3,I72N(5A)F]_$-[H=&9 -M[^'T^:"8C^5]\6V4M>1GE+U9!YQ/U1YF1`/O9CF+?=FDVS+2`UZ/5[B0)D3@ -M\E3^1^#.V_11VJRFU3*S[.A_"$`QS`]C"/@M#5>;#Y?-K;N\;)=_Q\$0(X_.ATRM^&OG;?N?! -M;-H8H[U/HHPV\Z(&K1QH1O;`[;9!4U;]/A[G!2K,F2MW+2(XP^G(R'FP)@V: -M=)(\C6)NO@V\:>X_>!0>)%^0YO8ZHQ_OD#&P[\C.]6I6'[J]%(!2T`RI9NA" -MBFML:FKBAY(5(IH:[@V=C%AB:^D1Y?'3*&>OWZ$L3W5]?OZ-LD)4RGK0!YG6.3 -M:L:4"-Y;D_GQ72.Y6W9]SX'DJ07OYL'`/M1W)6<2,?0QP#R^)XBJ4RE\]WAY -MGXY84YF7:YZ5-@DT66G#Q9@60$BKPY+`](QGK2[_JJV\AQ/R`XHVD\14Z*>LF4*L@JS2KFW==$GMWFR`E-%>'U0G*T/+I#_TLL/<76W9Y:T`D(2>Q3P''$O,^-)8H0K\ -M$E>\9BIC/&44Y$D<2;4D:YE[7"(8DYKUJ\/M>"3_BK3D.C5HW%OS+M!?<&%S1T*M(GC>D?+53TXZ)3:5 -M625@^CX9]BG1L\:2+^&N]9T<\Y?:_6C!T9(['Z\[MBTC#HMC+@EX:.5KP^F. -MH=*=9QR6IV8+DZ-P?PP^2QM0PUSDEX\_Z?Z1$CG7)\?^B"`Y"\,5D[^^SPV4 -MZN_5S*O!^9&W:4B"8L`6;4GI@157EE_6/M98M"?9#/+GW2`;VK,@'EVKD -M9(.X.KLO->-V?)=:LKQEV?3[5S_!Z;^-)351%BSQ`D)>.W8(D.+!*BV7BP5T -MM2OFK[>F"=:`6KJKM(]#K:FOG?C#2O[X>W5YJ1N!`-QG,>QX@Q6KI5"2JW:% -M6>3#-!-G*G&&BNEOE>:S@*F0+NR57M;R9;D'X-3:R>\J&`/1Y]:6E]P_W$E> -MMB9;FO*A"W"DV]+[=N+'KCLUN[.WL4:C$`3?V]G!KZ6EV -M:LMOZUA'=#U<,G!-<2@<>";Z039OGTY4=\3R1PS7-=J^W -M]:OTHKW?1Y7!VF17\?/7Z$E4#!Z)%*6*^<&D?D8PO?%I?/=P3PWI47++Z -M8#;%[=KD8Y.O:0K:=/8[%R58^">39H]V):N;XYX7R&8W=[_:C63/2NOC7+%S -M:\I;2VN694Y+0'@5X^I7P&OL7>#B?E7"&?@C-PLV15)1(A)GD)$8@P.MK)YX -MV)^O&3?48:ROF\I>*X;HE\Y&RIF\;S.PX52MN-2:`%FZV9IT]C6TZ_:[_O?K -M)(VL[_[QF^>4]CI0^0F<9A*Z9IJ^0F9M2O4.)^R+^^YN -MO^CQU(%V4W]RLQE88IE2.BPQAKV,CR\8MSJNU7777A5*'O2[F\\/>IT9MX>S -MOP;3=?0F-V@]("UZ9Y'HZ6;1AGCFU;WD`Y=3 -MM8O6]G8T,NQ(K*=^\2<:CT#]@Z-5^'0(PIO#,>>:U=#BY[?93%1)?X@`KQRV -MC3SHS%X_@..+X0@#_IO&U^)=C=L76S/'W/!<=A-'6-V#P;3R$8-EK -M4+XPT)O-6^)I:<0RWY'!@LA7MZHVM8Y4JP<1`LF-U"BUL,%28TW4^[J38:4/ -M)#7>SM>['3)\BLU4PS`LC4V=FCA@^;I<1]E:7_J>2+>*DQH\/EW[-S9EQ.TX -MS="/O>]BNW50:/>O+OQ.-JE0`3%YL.SEI[Z.)88V[DGE?CO\&CI;HR0;T#?0 -M$7?*IQGUN^3UGEY)0MWV)/1&CN$X7Z8Y$\R2T-1X'QGU"MX*;F*[L$LK"3#H -M?2V>@(VZRO5_BL9@$?C=GO*4[!5X\R5;I\6YJR,!Q&/@Q29R"(&N]=@'F\2G -M$`J\*GCQ^*+(/UK2W/%665P'F=(FR7*_.?DKCM)DEZ=>3LOZY.4"99O\.:#R,,^3UFS>O0,6B'Q.*:/=2VG`/P%5ST1#D1TKU]NJ4<[Y -MY<-6]7?7ADE11HDG6U=:'1_^US+C>IC^`2INA63>GEDM8_P[N/1;ET/Y_?&EYTIF-B;)U:K8GTO05S`3*R`L,0%2 -M$9*[SBV?!*ZO]N9R/A+ZMG>$V;_'R[?U7HS-EWC#[[MO -M:ULV2U+.DLLTV""@#FZ,$'.G=,/;L0_9^'0IV%K/Y0/%:^#FQRKI;\V#@V][ -M_\=;V'N30F;T6TYD]@415A#,EU]GQ%:8#N9=X+U)(:'Z*40!H7UAGFMBRWA3 -MQ\I[G>RIKV`79]6+&I_/` -M]O?%U80G:GB,BX@'\MT1.ND3\+D9RKS%4LC94+WR+O#I5%G-L=8]R*!I#5.V7#`,HCNP2_"#-G$GE4 -MB69\7+GGUVOYNE_6D(71'WCB97ETLMT2"Y6BK*)9>L3>+.]%KG4)T^(G\+`A -M$[K'-B27U"2YM;=F1'6BV4KACWJ=LQ8I`^%[V*\=O72&+DD-5:']^KIZ/:]P -MM#L]G3[D-'-'P=&*^#]>?N8MK/CUVOZSFU?9J8L%B!C9S?Y<:8[6A]GMO3T. -MGV>C]G;[?9^OM]JK?:ZV1LB/&5F^Y]4?5M1_L-BH57H7:I9U08=&I2B]L@E25;IGV -M(.8:6^>$+ES#DK\KE=G'6IM?8LV;4$.OB5MK?5`!1L]O:0T$GNQTV3].>,)] -M:3S@E6U9KDKAPNN5+9.2::]/N:/;N:;5S,+0T)\0%=/2[&AW>KU*!SK=:J,@ -M(2N"PW%9W!KB\T>WT[3%?)+Y[V_GPF#H2O%R8)_`P9'B__T&"X-I_\KV0>A( -M"_D/:L>!3(?BJ2Y"RVW7$:-=2G^'Z",NLI#;QDHK&K(;<;_]?;H%)^9E2*BV -M.C;($ZV->]'M7_KNY`T15D#0L;; -MO+5;U9OO8W8]+R2_&EG*K9B'O:H9.XV:B]$??CZ,0!89*P^2[&LE7_?6GS&2 -MZ-_CTPI'A"AT71M;M#+M#DL;AXT94K'FZ..IMS?4VM*[>-&8[B#UHSF.2)!7 -MWRJLA$AJR#L;>/NJS\*9\JXP4:2'U)]W2EC2#[BP9%1GY)R*=CJ]/^^G"CHO -M5AO,[W4Z1*BZ?=]P. -M]V]/V3[.[H>Q='K>Z?5NF;D>W\K)STYV/HOPQO< -MAM6*%'2N#MW\@>ZDH@[MU -M;7`DDVF=L1+MBC0[>WK2J%+`!PK6QT>.I+5Z?'8Y5R\-6]78Y]K9`\U^8BL- -MRIT=/P)W=MUW`<`+7@7.J_M%?&GL*GT`9Y9.R/#;/H5QUC\9P1?FE6]A+@3[ -MIP,/12G_AS*3.>)L-E>+_%NQ=[-L\U7NU2JXDIPXS#7AUR!)$HMA_R`%@"ZJ -MP3S:J_C'BIG^1,[>NAY373*#O)5?X]BC-4U!EX?OX&6/\^(:@[L,[%.%TZ_Q -MP]`!V<@\;EL@[&7&ED&AW(BSGW*'RLG2C+__M/40````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````#_V2\C^C%_:]3_Y____________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________________________________________________Z`1_R+ -M_^L?^G______________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________H$?\B__K'_I_____________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_________________Z!)#_4%IS_=3_\````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````$````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`!Q,(=41#,T1`!85O9S\*.C/!I9I1:2;N[&-B[`5MIBT,?1836;F[OB11)I) -M5B)-+34%IEX-^[V`4GT(E*.1T3,T512)P;F^.L,(DS43'5SOBOB7/\(/W/[] -MSD1P3SPF!'I,@``````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M````````````````.7XW\>[_'Z.[^I\O\.YZ>>OI?P^;^'I__RVDL4?\2G5G -M_T:?&__KIY7K#H7@A(IWJ%<*'!9%"OLP-!P7AD6BR0E+P\"H8V._E_*C?IFE[04,GALIT -MXYE9I+UTMU/+-*9HF_1./4FOK-SR3*$Q\?,OFSQ7M\WQ\F5CX9ZMYX>?&%_>A&']?O\$V'A#;8 -MAY^:-F[!<+R;L;2\W&/WE[NW#\"VZ13S4Z -M)=:V3Q#TU/+GI-CEU>"-W\DF:9P9/]HUM+9"3=,D')VO?T5`Y@0JK9)ZDNJK -MN55>?RY5NYJSH3JV#6/<3LVRY101KEWH:&G!%)MZ=CQ\GZ46;81TIWET&%/OY\_FBX9R>/:`QK42`YO2-X^SCART""SZ,LQY/<= -MB=%(CDGM?K4>#M4H81.AN\W>+J04IPP'Q7?#%+#5X'N,-_RY<;E[QC8;>KIZ -M!!J6F"=U;'=.2$/9QO\GT1A]9"/UH,N/)6`..U=WM_3Y9F+_?9'CCW45HLW# -M5?YEQW,@;`6'N49"V:96P+B<=&F)!F.WJSI5#;V/47ZVFGY>/)*@L?%@47T= -M'GNLHR3NG8Y3-!TZ'+]3GRB>+)PE;U"26?49/=@L;K[PEX?V2FO\LBX\]NH+4?O>=K/Q>Y\]82,D -MI.R70+29M(.239GW[I/W*1+WD^>_)WA[_N!83J\G>96F?Y,7.F -MUW>WV_\NUV^[VNY_+Q=WN;7R]O:^;M_OOU+JW!T"#%F@O#+?FM'?/6K_M/Q\ -MGE]92>;>;@U'G5+:CS7N]R[6Y:S\IT_MTSA7V>_0UU+W/GL#W%$4_9IDV.UT -M:(TR\M?7[?SSPS;MION5_N2V)FW:^/NMW/Y^2OBP\&UN_/W/Y2]7O6X6KQ/* -M0=M,X7KDSGY<05]C5_';_GV]?\&_(EMI[$$0.[L?]=CY=GUO^Z];>M.[V?Y] -MKN=-D3ZZ`1=W^/S1,5NBMH^6N@/)ETRK%77R_,E2%?H9$VOU)L.FP6V?@DP_ -M+RUMF[>.R2A%?SRLL@^_#WX.O705/G6FF)44T4=ALF9T($3:1-$7*>D-%"$=?3N^+5%(_=^.27QEDR"] -MZTV@X8_&&>/G>F3@B!^/)-IU:J"_U:B;$#85>RVGU'%[P=WK."_7GXO?&2-F -M[XM/P$0.B'W9*5]S'?Z?U@:2^'\<$>/8OB<*6/R#VVO<0X?!7=?=DRK:EL.* -M`:89D&](VS"?U/FF$">_C>,B=Z;V2NB&SLN6SNH]$TU."0&_EP"9P8ZF]56_ -M\=XT5W*Z(8%\ZC[&:UCV8_:+VW,O/7*'4,FO@'.<6`99O;Z<2@48FVBZ,8DT*HLE,P -M8$A:?WB![D4(A^X<\\"%Y?RR1FS9NX,'%9T5G/1.&1(P.!;HYQM\T>.F%3X^ -MNQ3ZC?EV2J#N[M&Q=GXKPL.Q_XE&[&:;52DP2Y.T[-P06OA>#Z"'_(>O+Y,D -M`@^TN>3Z2#7J4I_FA0>U;LV`UQ0&3&W/HBZI0,GEWI:V]B'%YZ2<9K0OJFQ) -M+YW[7YYIT[AV;J$D)Y:C@.GSYMS--:+GRM*!(,_'ZZ_\^#^]E#6NU>CJ"()L -M?5W_K\'W4>AO8Z&0NS8S7_OT#BWR?XS.,R:2_'Y\9Q/8_Q^3H6FG%/8[&38_ -MG;*NW'*.W)A5=CL]G8_Z>MON_T^S[.S]&N]?OP@820/NQWO#]/]O!_V]DOW_ -MY[/0M'0];'@57&!=:%C)$5.+DUG+5/QT^8^CS? -M[>-NB$/V,E4<7)EZ7(.*]?PTP@@=BA%.&SYVO!]WU_)]O>^[P?7(++:^WZZ? -M#AAT\W[=EG;L3P351#M:+[3$?^\O^HME\&24S_T1G+U1+-Q79*PV'(J5IS:) -M$+]VKO&E0R'-2I['@H35R:B87H[7:A89L3_V,U+)&9;%!L6^-&H?IN^#KCG4 -MCV)YNHA15?],>61*F2!]P:JZ[6%"9,A?`G]9JMO!^'WP:9LPB>GOW%?4D\V-E=FM\T^>W#]&KO) -MIO^I9^&R;K[;\*L#7CZ?:*P -MN=-JHT;\"UT%)M-:<:NJ$71Y_=FZ\W).4!90;+G\EEX#1J;PR2-L#O-6&E(X -MK[#KM-8=]C<.;=9O$SI)Y23;'V^>W;R31E:(Q,?#LBCEK$8>6$9M[+H^$B:;'+>[EJJ)]A)U. -M2]L65(9R>I<#C8;!8>M=*W\_/L?B$S;X3>UO(F,]'V<1)_:NAODT_>$:7\>6 -M)[XZ<]'%=EU8T[QXE>QN9@=S24?7&Y[2*>E2E,K"3:<;D"A*_G'&4H5IDR7-$12A*,D+W*3C1W/%Y=4FQ%&*83)\NB -MRQQ'I4A=F*T+^3/-4^FZ?IB,WR?+%&A9>O(7.6/;&:KK2H%3UU>9E.D_@_S[ -M_]/IYW)E;XEL:43.SFZKSR6X=$TH+SSA8+GADWJ]F/Q$#TP`#+]\O%2K-\75 -ML=B;HFA_P9?1+AKSPG2;L$!(2VL(4$_?6AI^0IW!(B3O;79ZPN0?3$!;4UST -M9BKYP/1-M,3%^DBKR/(:/<.;7KJ^CT9J6&K??E"O&-LR=6RGX9%EM-,(W>/B -MF\4HB]G+UFY/IEP-HPS!8@UUFXK35!Z(_SASX(*5WQ7S576EW5-_8]'6[E2& -MKE=VN;X%:[NYM%C1<+NVLN.:!U-C+2"TX;(84R9WQ55<]'N<^7A.]&;;H2G: -M#P8PIZMK.3R_N^+I@J)ZUH?6T7MBS$%[-;2],4;LU!8^>>4)DZ[%-/+$+(R;-5"L'_!=I5@5L-VH?27![#)AY9<3HTDB7<6G1UD#6'S!& -MH+X0YJ?OKBF(13$RUICG"W7 -M=M_#26D/N5,Z0V9I81!N6"9W1")IDC8QTY -M/]S@S[L^FC$8S\41:#".#%3?,LVB%[@9OO44+^]2Y&W-*^@BU1%`MY[N7=Z) -M]^&?@M&6F)V"QN;DQ":81BC^''8X[6`O>/1JNX"UK[5]VU37^_PD[J^:5V-%:YYL^W;(W9N -M_WNZ%Y:BU#%_UV!A"VE15/:I>TE"[5M4V\G@MA^[JC$SY>S]%LL?^\%K/H$B -M>&U`:H!APX&O?;D%)(#TBN7&_=A!A=Z&5]N?1IQ>U*\M9P!%SSJ0EY9;BRRM -M"`)5XZ72OR;/`UL&YXHB5JGR\EHWJT7@%R5G)QE[`!E^/RF>#SY9?YPZ8;%\ -MO2ZZ0GE0]^#'&NIG/SR2OVJ:/)N^:ZQ3%4M8]?Z_+\O8AB$.F"76>F9<%4B>?XY`-W?%BE9&;L*K1F//PY:4U-V?VN.=`C,_# -M8L!#5>E%W^7>ZR2+H\/-N@_-"0W>QK]]Y('Q:B:5-5YK%!F:;^*G#'LA*+9_ -MIKK#6MV$\$9Z!'==!FHW[)O-636-^?JJ]7T@.>O7J=GX-Z_;EX*SJ'U9U(P9 -MQF@,Q"`W3X!*-7HMGP\[1:?PY.#?]*\W+[Q:_[28_V%L^#?/U9N*L\^]:U'7 -ME7I[\\&CPY?)\/(?,:V0=GWUV:FP/O;PC+OX9OSR_"O.+1]WI-'4[T^V'9UK -M=JZ;(4[[Z/6")-H&;V_KY -M2A$N_R;'*[R)OVP;(F!9:KV%I2CB;Q[V$?(Z[JOA>B&U=?##-(7,P9'F%!YZ -MS8EBCUBT2P[5WA]V&:)+B)Y^*>3].?56\>"4AN[F6^&.;ISB=2`5:+A% -M^0XE:S$@#8WG,%I^7PA.V>D/?> -MWM6ZE9C4%\..:NA9;B?"N7:X^.=T8M8_ZSH3%?N'.F:UC?DH$6_&DMBZO,\] -M9>]2@.E)&;7=@D=U)T"42`L>@*>'J+B_Z2\JH.]C>LY%PXY-JRK^(RV><-5* -M2>^7GU'MMT5CO60]I-"DR:>F0FZ.@.KL9B`^=SG5_7R[6[0UW`C%[0OLVE,] -M)F1CJ+3%AG>E$9UD)*3/KR\51NY@58N-][GLR5HBGAT+-/74VG?ZE^7:K$N& -M3VNY(;T42+C+A7N)E!ETP)*'U -M?!I^.2U;77^G/2F2G#6U8=E"1-5T0C'>CX]=QBR)-":?T40W9V-5#TLC:WHO -M^*!X8CM&UR=CL_13GZ%->5J_.D6O:)QI+)M[9]-$MK%!G,O_R7LV/KFD9Y7B -M;A8_71]%)I@BF'&Y)COQ'S53+M9#=H$K.!5)9KX^++A<-'A]:9Q8F@BZO0,G -MLRXXB/Z3#1V9-";`%6]5PP:0-':1?@-WQ8?%:%C(9C?Y6]:5Z=3&BW)0!;375:#7?5-7MGU%#36?1Z'/V>GG5.^=49"A?#[+#F4#HO949#E -MWQ='-_6]9?=\?/G[7)SKUK%'4Q0$3''E,^4-2OA]7PK:&T8'=D-W*VB6X4).M<^P3(LOE36 -MUM-'>9J(-49K[WT_97TJL`31ETP18CSP+Y>:/NG1^.37NW,F[YK,[*;EWA"S -MPH/KCI:14,R7^2%QK#G?19[D>Y((:%(OKH=&_4WGT)-<^^%OJ"8,">6Z6KIP -M;N`T/*Q\=W+ -MJ.0?2ZGGO>3C+?+C=$3[%>>'Q77=U8'D_]0HL4IF'A:*<@VZ-`R;U5.6 -M*$LW1)8F"09:'%<(?&G`6L#]]>1";IC?4-V827=ABFSA3D2>9[TWW%3#WIB/@S::>_?O_.!K8N2QC&KC=E)1'%X\F[6U0,(EMS<-;TGOCCX9OPV))IGU$Y2FQ,TW>9:O5HFE=.)>[&W.N\" -M4W__&2.%O9(=V?Z9_2<+!ZMT4,L>_U/WU-4Z<]^DK:KD5WE&#$W]S(-*&_+N -MD(&[NFG'M.M%=%:6CVU+$%]0$ -MQ"E_9JQ[_)>O*6A+?&_.9H#OL3ND%-Q1$='4N>/JS:/-C%LC^^@*WASU\

    C4EU*W<;DH!ZM*F5D9#Z+X+8LQDJ(ODFX -M;GS5A(;6EU,(];V:079.(H)=.?Q?4H1'LB]=2Y?^OC_/\^5Y:?0A6/!LIMA"VAS$\_'Q>>'M%FGP?IJ -M/EN\7,?&9E@!2"G4MDYDN9FH[(?NC?@R=(/K>R<&3R1'+WARSK&G[A3QXI$-_;HNY3%,R;D0&I,9*2:U?WPU[!?':*;OUK1#=,='VN2YC -MG!O-B&7X3'9R4W`LC>Q(H4!1SU;LSI"?**"-$W3_&Q]\263CN&S1TA';YY95 -M/BI_>IPQ5*AK$(4L!N_;X?;S(!CM5VBJ??]O7XV(HQX*TG/V;4M`T7M#>ZSK -MXQ;F5XPIW'GG\V6VBYKC^*T3\DM^,6X],V3PG'R=/9.AKN@`=51G"LJ]IHZH;I]I='PU1EOXY'XJU2:;1TR9/*]V/=6")LTZ[AJCE -M4ZBGEG.3/1EYXE5SSYX'GCBF[!3+_TAAEZ>8LP4IWS:;SZ&^[SU-=_[+TF6T -M2-PJFXZ!44BM*.PC9$K>/JA\&"AFW64_[#VS\LVRWK!\M_H?)L4^@ADQKKU< -MO]5#HV8?6LO6[DKKXLD'OH5H[=N7X*I^%@NG&P, -MU8J>]$Y!`Q(HE@#L_%>BZ1S;#W<\\2MGLWT)4Q[:P1FG0UF2!#HF2/[\F`MYZ]LC7S,RX4DZ -MM?5$#2QJG)[0N.?8@\P$9-)^0.OMHW,VF()]_"@]_N<*U(DS02,0@FJ4'Z.X -M6-PG8Y3]WX`WR1P9=1]AT[_LS[T=5-U8D=/ZM[-1V-^;6YB-QIHS\8;">P]` -/%``FB51Y`0`````````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar_multivolume.part0003.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar_multivolume.part0003.rar.uu deleted file mode 100644 index 91b7f28c5..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar_multivolume.part0003.rar.uu +++ /dev/null @@ -1,1337 +0,0 @@ -begin 644 - -M4F%R(1H'`!EZ*%?VW`H%5HFLFX).4Z`.;V?GKX;T]^755<'V<*UC>;-[%*;/X0]]!P>WI\ -M4,Y&PE_B_KBY3_KR8A*=V5Y9^":+9OY.2W-%I:#J"YC[#9]&6)@HH1ZHV*<8 -MTFQK2]$+2^(@3/9+1"6W2O)L -M"JZC)MCDJG+%_;+=UEV.2(I,V[T@EI4_>>,]J)SAMVO/1M>YM-AQ+IY8Q%WYDO:$R9":>2(=(QI-8FT7K -MC-YVNI^VNP$O'+G7+LUC#W-PU`SJ5TG3!'3-Y$71F&\RIAPA-3+KMQ`A.LV> -MT\I=DWOQD9GR>3!S^2N>6\'-??Y*P]1Z)]:MSNVK3KLQO<_'-NOXQU:K;F)9 -MUV*]@/U`:IFZLT$S[=SKY$R`$N/I:%W^2F4+/B_%C=T!8XU<&6H -MH&1\D5,IK)()..[ -MF/V(NZ=$2+-2JO?\]\+?^W[DGO?%VZGNTCMOF;O1@7CNCW\E)B"E\79I]#\?;E*)GX0XO'&S/8K]`A_E[O -M:W-?VBQ++>W23#MSBS^;+K!B)WYOZGT*KTU5WI%WOQS4-JRU-KG?)+*W\?FK -M@=&+-$4Q=FH2:8/`,[&-M/&Y!GWK4@,-D75WT2#SF#E*Z5W?Y+GLL``````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````' -MJ[_3SO^?JY_0_X^G^?0]2\[%_/G=#G^OW[GJ?'TY2['0XL!]#U(Z'1A";GY- -MBV,W6@9#W(9][P]/H]'[A3K3X&Y3I1IDIHT2.XL$R&Y[I4@=.F[#?/^ZK1ZD -M#&6'[\,TB^]<>9\"Y-'I=B--7:1>90X9!B^ZVMRLSBZ9H3>*UL(X9WO3T;88 -M(NBWJ;FWYMCU:_`%SO[.K)IJ?V@]X?H^G?YY_.^CG18D4%>CL=WJ];U#S>YF -MST<_/_)_+L;'E@R"(8&S]S/W[H'VO3[-G[XE?]16`H7C7$6F?`7.ERJ_\NC3 -M.&L[XU<8.@9'&L'1%!-IUL?&T8$DS.,.S_X.*MFY1YV-X9_`(S_AWXIX>G6] -MDL&G_OS_IAR`Z?BI3QZ.HD:>+P"$%C35TX0*EI^YVGV?T]ST4:L"3()CQ_;TU>HQ6M?7%4=POV:74YL0'I09'.UA@H)]/=\OOS@G5 -MZ&CX/T-X0-588>U]NIXZNWI5>"XTEJY?OC;IM''%S(ZHSSRMS1_9,TNG9F9* -MF04#YUGBD(U/->&+/_<==8H-%>N,41#3C!FNWYH_9"0.>;IUU'VT]?W7S>YV -M]+1\&G+.*[KK$#3UQL@WJ0$J6U([]?U5-)YOU'>%A%4ECR#*2V8(\L$@_1ZG -M5_>M2^O-UJZ<87UWTJ?*0@2\5T6OV04J5*,CN$HE#?-TJ_),E_7JI]%\7J\N -MOV0:*"'G_=ABT==/2VX$![&^U?\TQ0G]=X;?VP9/M_3Z_^/FZ5[Y7\O<_]K) -MY@;H[>EG^"-JWT+GP_=2<=/[HM^""I9BTXF+H\"73COXW[H+O.K/@PF8:\]" -MCI##99:XQN]=Z+Q7KC]X.'6;4K?:GQ\:7W=J_M;M]"?&IZV_>>&G[8GP)9B1 -MX9(_&5^S\.0(I^17K9SRSU$LO_&\_""37JU9_O$063CH3O+RY";HCLR!%4$M -M"P%R2C.-H4T+?C(5%67(4L1#KH$O:A2=CZ)I=,W#/<=T<&R;OD^+GR7]R>;S\[ -M^F=SHQ[7Y?2JY?("\?;D5='4C,DW>]M08M$KGBTY947AE#!LF.-1V@1)FYE7 -M*S+,.\DPMX]7(X1G@KX\.YV?80W25IT4)IX`F?I -M3)JXIX+Y!.UCJI=3N:?1-X-R+CMH^S0QQ>.!3VST>W\OZO1/ARI:U0G<^O;3 -M?@AFLT3F^I]O8V(QKO1N<6+Q&9-K=QA#.ND9M!7LK*_-MU6##8]^H@N)@J;S -M3BOVQ,LPCG>582+:*V35;YCEAI24B(J0M\Y2JU<8P+_FJF;]*S-YF1E9"^6#7@6\98[_J_5S9'$"9N;%YV3NOV."U -MA%X/QR+L?QE@[7"O*)0-=YQ`?&+VC8K^WJOGE[O'>>R2TIR^1+26]F(+MYZ./+3O*L8(\L1?` -M6G+W.'X^$2W9;!*^:F_'@4W(5F1JU?!NVGK-6P/Q`E+AE, -M%%$=&50&N`AV1&#.]R_+!IU\#Q8S3TS*5TKB%829O?Q#>Z'1F>_A]/F@F(_E -M??%ME+7D9Y2]60><3]4>9D0#[V8YBWW9I-LRT@->CU>XD"9$X/)4_D?@SMOT -M4=JLIM4RL^SH7+YF^D*/KRO?/*04O+L4&ZDC*5OA&Y,:7!/@]ZOHM"FQW8VJ -M5;AM*JL7;-6!N[6]J0@0>(#ME,2.IWSQZ(5C"T&2/9\1OUR3*%B2C7]$U3>G -MU7#`_%*#CTL%T>+DJ]8LZ`%_S9T0AR,F*8A^38LN[FV;>H'$8@ -M.LX?T>!M2_'\S.MVAR_G/VL%"@,^G4"N=%Y0?-TLOL=FY3@:\3EV[\9U@?GO -MPA`,

    YP4JS)DK=RTB.,/IR,AYL"8-FG22/(UB;KX- -MO&GN/W@4'B1?D.;V.J,?[Y`QL._(SO5J5A^ZO12`4M`,J6;H0HIK;&IJXH>2 -M%2*:&G,SJ5^>K9HV8Y<<-T]9F<;HSQ'1>LBVE;`)X`M'./CRH=Y@#/K"F_3I -M6A'NX-G8Q88FOI$>7QTRAGK]^A+$]U?7[^C;)"5,IZT`>9UCDVK&E`C>6Y/Y -M\5TCN5MV?<^!Y*D%[^;!P#[4=R5G$C'T,<`\OB>(JE,I?/=X>9^.6%.9EVN> -ME38)-%EIP\68%D!(J\.2P/2,9ZTN_ZJMO(<3\@'.$AJ8LQN+'*1OZ>MABA;T -M2=+%VV^E#8=?&(*C">6"'4>./TYUUZ^16ZB9?F032LZ@`G#.NUP)E_R"<$+G.1MQN&41O^>#0SVYI;T@#9T";E^4T8INM0VK05*WSG7N*-I/ -M$5.BGK)E"K(*LTJYMW7*0%E#-DIT)\6M`)"$GL4\!QQ+S/C26*$*_!)7O&8J8SQE -M%.1)'$FU)&N9>UPB&'*@ZVQ.5<97)*HZ$LP8EM1J`AG9)EA010)R+E<*WI.: -M]:O'+5J/60FO]]?4O>9F7&+58QPXE=<$_[Y=?<@VU>AS\Z>^"&//+@SM?!MP -M0'>O[:_QZC1"HHK`V\AL!%@P)*Z;^UUI#AC3SVS#Y2EC^[8S`\,8J0E7-CCX -MH454<5$7#N4^4`KW*54I;%J4N2KFI^'5Y^,1 -MK?,;1U`HG-30&8H;-(IHL$"RXYQ21.AQ<9'YO,W_.Y$EP]>$?@W8SRAX(VJ] -MXXWC[7@D_XJTY#HU:-Q;\R[07W!A//^G^D1(YUR?'_H@@.0O#%9._OL\-E.KOUF_C24U418L\0)"7CMV")#BP2HMEXL%=+4KYJ^WI@G6 -M@%JZJ[2/0ZVIKYWXPTK^^'MU>:D;@0#<9S'L>(,5JZ50DJMVA5GDPS039RIQ -MAHKI;Y7FLX"ID"[LE5[6\F6Y!^#4VLGO*A@#T>?6EI?K[5HZ?\OY7:'ES7:OM_6K]**]WT>5 -MP=ID5_'SU^A)5`P>B12EBOG!G(\?]O(,ZJZNARE%[&H"K\N7383F-&V2K`]X -ML&K+H:G+2H^[NT.GXJ^6+]:LMOZ*,]>"%W;U;$( -M?)ED_MTH$E8_F)VC('`[:RJ8M;7I'Y&,+WQ:7SW<$\-Z5%RR^F`VQ>W:Y&.3 -MKVD*VG3V.Q%\AF-W>_VHUDSTKKXURQ/ISFG9V+O!Q/RKA#/P1FX6;(JDHD0DSR$B,08'6UD\\;$_7C)OJ,-9 -M7S>4O%<-T2^-YG8<*I6W&I-`"S=;,TZ>QK:=?M=_WOUDD;6=_]XS?/ -M*>QTH?(3.,PE=,TU?(3,VI7J'$_9%_?\3,7RS)JO77_1XZD"[*;^ -MY68RL,4RI'188PU[&1Y>,6YU7:KKKKPJE#WI=S>>'O4Z,V\/9WX-N/ESM;8\ -MMNE$KQMI7':P([CO)NOH3&[0>D!:],\CT=+-HPSQS:M[R`SL:&78 -MD5E._>).-1Z!^P=&J_#H$84WAF//-:NAQ<]OLIBHDO\0`5XY;1IYT9B\?P'' -M%\(0!_TWC:_$NQNV+K9GC[G@N.PFCK&N/H:2B/;!X-IY",&RUJ%\8:$WFK?$ -MTM.(9;\C@P60KV]4;6L'R[]FYLRXG:<9NA'WO>Q7;J -MH-'O7EWXG&U2H`)B\V'9RT]]'$L,;=R3ROQW^#1TMT9(-Z!OH"+OE4XSZW?) -MZSR\DH6[[$GHC1W"<+],9):&H\#XSZA6\%-S%=V"65A)AT/I;/0$;=97J -M_Q6,P"/QNSWE*=@J\>9*MT^+NP#S>)3B`./BO5>%3Q -MX_%%D'ZUI;GBK+*X#S.D39+E?G/R5QVDR2].O)V7].6T[%.EC-8\?$YFXK!4 -M]>;CU5T(=0!5_AA+&<;5Q%6O[H[.&/Y[?=^?'<$UJ%I,Q96U]9MQOKOKPR2 -MHHT23K:NM#H__:YEQO4Q_`)4W0K)O3RR6L?X=W'N/^%'L6/^"S-X:\JK\ZFK -M;0QG%@C5I6/(MRZ'\_OC2\Z4S&Q-DZM5L3Z7H*Y@)E9`6&("I",E=YQ;.<)[ -MPKONQ!\_1]Q//@E=7^W,Y'PE]6SO";-_CY=OZKT9FR[QA]]VWM:V;):EG266 -M:;!!0!S=&"#G3NF'MV(?L_#H4["UG\H'BM?!S8Y5TM^;!P;>]_^.M[#W)H3- -MZ+:P*(JPAF2Z^SXBM,!W,N\%ZDD-#]%*(`T+ZPSS6Q9;PIX^4]SO9.2DK -ME64=62R@B!MZ-35U?4C5^M/N#9D]3\$!V@O4U[`+L^K%C4_G@>WOBZL(3M.3 -M.\9'(V$4DY41?$'\3D=O3Q&1<0#^6Z(G72)^%R,Y5YBJ61N1PN2'"&X8M0/M -M4W7T?/,J%[Y%WATJBSFV.L>Y%`TAJG;+A@&41W8)?A!FSB3RJ1+,^+ESSZ[7 -M\W2_K2$+HC[QQ,KRZ66Z)!BUSJ$Z?$3^%@0B=UCFQ)+ZA) -M.WKI#%R2&JM#^_5T]'M>X6AV>SI]R&CF -MCX.C%?!^O/W,6UGQZ[7]9S:OLU,6"Q`QLYO\N-,=K0^SVWIZ'3[/1^SM]OL_ -M7V^U5OM=.533Y1%WYL$^Q$*^NC+)2@NN!2OI+.RN_<;?&-8,[Z(UKLQ4IO;( -MV1.58]O'C*S?<^J/JVH_V&Q4*KT+M4LZH,.C4I1>V02I*MTS[$',-+?/"%RY -MAR5^5RNSCK4VOL6;-J"'7Q*VUOJ@`HV>WM(:"3W8Z;)^G/&$^M)YP2K:LUR5 -MPX77*ELG)-->GW-'MW--JYF%H:$^("NGI=C0[O5ZE`YUNM5&0$)7!8;BL[@U -MQ>:/;Z=IBODE\][?SX3!T)7BY,$_@8,CQ?_Z#!<&T_^5[(/0D!?R'M6/`ID/ -MQ5)C -MVKN7FWC*8*6G@T/?UW<@:(JR!H6-MWEJMZLWWL;L -M>EY)?C2SE5LQ#WM4,G<;-1>B/OQ]&(`L,E8?)=C62K_OK3YC)=&_QZ84CPA0 -MZ+HVMVAEVAR6-P\:,J5CS=''4VYOJ;6E=O&C,=Q!ZT9S')$@K[Y560B0U9!V -M-O'W59^%,^5<8*-)#ZD^[I2QI!]Q8,BHS\DY%.QU>G_?3A1T7JPWF=[J=./X -M%@NIIPI,ET8.@'1[77^O(E1=/N^X'>[>G[)]G=T/ -M8NCUO=/JW.9?#XH_]-^,9V+DLJ)\5/3-R/;^5DYZ<['T7X8WN0VK%"CI7!V[ -M^0/=240=VZN7(SMD2M3LZBSJQ&%W1J&K>KL<^UL@>:_,16&Y4Z.GX$[NVZ -M[@.`%KP+G5?VBOC3V%3Z`,\LG9'AMGT*XZQ^,X(OS2K>PEP)]TX&'HI3_PYE -M)G/$V&RO%_BW8N]FV>:KW:I5<24X<9AKPZY`DB46P_Y`"P!=58)YM5?QCQ4S -M_(F=O70\IKIE!WDJO\>Q1FJ:@R\/W\#+'^?$-0=V&=BG"Z=?XX>@`[.0>-RV -M0=C+C2N8>KJLO2#0[D19S[E#Y63I1E__VGJ(```````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````!_[$O(_HQ?VO4_^?__________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M___^@$?\B__K'_I_____________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_____________________________________________Z!'_(O_ZQ_Z?___ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M__________________________^@1_R+_^L?^G______________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M________H$PAU1$,S1$`%A6]G/PHZ,\&EFE%I)N[L8V+L!6VF+0Q]%A-9N;N -M^)%$FDE6(DTM-46F7@W[O@!2?0B4HY'1,S15%(G!N;XZPPB3-1,=7.^*^)<_ -MP@_<_OW.1'!//"8$>DR````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``!R_'_CW?X_1W?U/E_AW/3SU]+^'S?P]/_^6TEBC_B4ZL_^C3XW_]=/*]8= -M"\$)%.]0KA0X+(H5]F!H."\,BT62$I>'@5#&QW\OY3F,N#>]FNE0AU(AG"5S -M=S/X>.'21%AWLTD4CBAW/7HT6UL=Z5OST;],TO:"AD\-E.G',K-)>NENIY9I -M3-$WZ)QZDU]9N>290F/CYE\V>*]OF^/CE&\%47;1=1&AD+1D\TD@'--[TRL? -M#/5O/#SXPO[T(P_K][AY)NRZ9]SATVBMK&S^\;W@FP\(;;$//S1LW8+A>3=C -M:7F[FH8QD[/GNHET1Z/!?IOJ2)S*X]OP\?#PQ^\O=VX?@6W2*>:G1+K6R>(>FIY<]) -ML9=VJL1P%/>T<\W#?-)GHR3-5]`_L>C/ZKZDX&4O.:7YU-X!XH!FU)5]YP?+GW][4@[7UU, -M8W=JWF_TJU1>9XCK[VP:SE[?NW,M@P):A[$DNCG!A]'9MVL@(=!QJR%AC&=_ -M4(P8N$:T+3Q[B=FV7**"-.$ -M@#-J\60A8S`RY)V*;Q-O3L>/CE@^>$N6G$T>.>*710.G)7=C:YCT_2BS;".E -M.\N@PI]_/G\T7#.3Q[0&-:B0'-Z1O'V<<.6@06?1EF/)[CL3HI$,;#;U=/0(-2TP3NK8[IR0 -MA[.-_D^B,/K(1^M!EQY*P!QVKN]OZ?+,Q?[[(\<>ZBM%FX:K_,N.YD#8"P]R -MC(6S3*V!<3CHTQ(,QV]6=*H;>QZB_6TT_+QY)4%CXL"B^CH\]UE&2=T['*9H -M.G0Y?J<^43Q9.$K>H22SZC)[L%C=?>$O#^SEW_QJ(!`%$8W>R>,7(7^M681K -M69W26]\GSWY.\/?]P+"=7D[S*TSF,)//R:>#S_)BYTVN[V^W_EVNWW>U -MW/Y>+N]S:^7M[7S=O]]^I=6X.@08LT%X9;\UH[YZU?]I^/D\OK*3S;S<&H\Z -MI;4>:]WN7:W+6?E.G]NF<*^SWZ&NI>Y\]@>XHBG[-,FQVNC1&F7EKZ_;^>>& -M;=M-]RO]R6Q,V[7Q]UNY_/R5\6'@VMWY^Y_*7J]ZW"U>)Y2#MIG"]S_/M=SILB?70"+N_Q -M^:)BMT5M'RUT!Y,NF58JZ^7YDJ0K]#(FU^I-ATV"VS\$F'[EWH\]MIXE%3Y9 -MW#?&-%[5;M=_B]OV3?G:NW_#M_Y?RP"\T48M\C\7Z9C/N*SQ>6MLW;QV24(K -M^>5ED'WX>_!UZZ"I\ZTTQ*BFBCL+E,"'%O==0`M0_C@O@T)B0PZX&CDP$/6^ -M[Y:B)[UDS.A`B;2)HBY3TAHH0CKZ=WQ:HI'[OQR2^,LF07O6FT'#'XPSQ\[T -MR<$0/QY)M.K507^K438@;"KV6T^HXO>#N]9P7Z\_%[XR1LW?%I^`B!T0^[)2 -MON8[_3^L#27P_C@CQ[%\3A2Q^0>VU[B'#X*[K[LF5;4MAQ0#3#,@WI&V83^I -M\TP@3W\;QD3O3>R5T0V=ERV=U'HFFIP2`W\N`3.#'4WJJW_CO&BNY71#`OG4 -M?8S6L>S'[1>VYEYZY0ZADU[EBH0J[,X11@\E+BJ2M)#]3[7%AV/_$HW8S3:J4F"7)VG9N""U\+P?00_Y#UY?)D@$'VESR?20:]2E -M/\T*#VK=FP&N*`R8VY]$75*!D\N]+6WL0XO/23C-:%]4V))?._:_/-.G<.S= -M0DA/+4>!1@/L0V9 -MD-?V>YV^[\W;]W+M/Q+E[PP+K0L9(BIQ;_;QMT0A^QDJCBY -M,O2Y!Q7K^&F$$#L4(IPV?.UX/N^OY/M[WW>#ZY!9;7V_73X<,.GF_;LL[=B> -M":J(=K1?:8C_WE_U%LO@R2F?^B,Y>J)9N*[)6&PY%2M.;1(A?NU=XTJ&0YJ5 -M/8\%":N343"]':[4+#-B?^QFI9(S+8H-BWQHU#]-WP=<Q/-U$**K_ICR -MR)4R0/N#577:PH3)D+X$_K-3F&1-N9?7>6DR8^^VJH=IKM3"0!4_+9:,DXNN -M&=2G:/O;UMX/P^^#3-F$3T]^XKZDGFQLKLUOFGSVX?HU=Y--_U+/PV3=?;?A -M5@:[ECDQ[*5LD\IT0(*(!D4@7^F-\ZL=.F[_,[?T4K-QV=J[\(HH1;)=_RWNY_L2-@>6#T?3[16%SIM5&C?@6N@I- -MIK3C5U0BZ//[LW7FY)R@+*#9<_DLO`:-3>&21M@=YJPTI'%?8==IK#OL;AS; -MK-XF=)/+DO[\\F_R3H>%0VOO9N>'AB7];JX%HZDC%_9S>R[>[R2;8^WSV[>2 -M:,K1&)CX=CE<;[T4/$KV-S,#N:2CZXW/:13TJ4ICF.KISXJPYR%8B*IZA@]C[^&Z^NI%[EWV9J` -MDP7-;I&0`7GLT-*T68S:+\.Q/>JG!?O'R]*)XJ40HNGGJ&T1HO*M0CU82;3C -M<@4)7\XXRE"M,F2YHB*4)1DA>Y2<:.YXO+JDV(HQ3"9/ET66.(]*D+LQ6A?R -M9YJGTW3],1F^3Y8HT++UY"YRQ[8S5=:5`J>NKS,ITG\'^??_I]/.Y,K?$MC2 -MB9V>2W#HFE!>><+!<\,F]7LQ^(@>F``9?OEXJ59OBZMCL3=$T/^#+Z)< -M->>$Z3=@@)"6UA"@G[ZT-/R%.X)$2=[:[/6%R#Z8@+:FN>C,5?.!Z)MIB8OT -MD5>1Y#1[AS:]=7T>C-2PU;[\H5XQMF3JV4_#(LMIIA&[Q\4WBE$7LY>LW)], -MN!M&&8+$&NLW%::H/1'^<.?!!2N^*^:JZTNZIO['HZW#&%/5M9R>7]W -MQ=,%1/6M#ZVB]L68@O9K:7IBC=FH+'SSRA,G78IKF(QJ&X9CM38=F3QY8A9& -M39JH5@_X+M*L"MANU#Z2X/89,/++B=&DD2[BTZ.L@:P^8(U!?"'-3]]<4Q"* -M8F6M,;FM-5]K6NZ?5$*I1.BU>V*5$ZI^.B)=@[49[CTX6Z[MOX:3A[!-[@R\ -M$PT_%B!_S::N)WG[DRSIO;+?Y)NB?]:&H!DKZM6A=.$5ITON@!OS2`OS98!KRTA]RIG2&S-+"(-RP3.Z(1-,D;&.G)_N<&?=GTT8C&? -MBB+081P8J;YEFT0O<#-]ZBA?WJ7(VYI7T$6J(H%O/=R[O1/OPS\%HRTQ.P6- -MS_89W^$B1>WM_W]:^+Z_ -MO\/VW0PC;,1F-\5_T3;WW^$G=7S2NQHK7/-GV[9&[-W^]W0O+46H8O^N -MP,(6TJ*I[5+VDH7:MJFWD\%L/W=48F?+V?HMEC_W@M9]`D3PVH#5`,.'`U[[ -M<@I)`>D5RXW[L(,+O0ROMSZ-.+VI7EK.`(N>=2$O++<665H0!*O'2Z5^39X& -MM@W/%$2M4^7DM&]6B\`N2LY.,O8`,OQ^4SP>?++_.'3#8OEZ772$\J'OP8XU -MU,Y^>25^U31Y-WS76*8JEK'K[E@7_TVZ55_\>[!`NMGF)!N[L)'4#ZX(_LCY -MGJ6C-N>Z@O_T^R'^)5)!Z90@_0JF!V<]DI49DWEMC-J'+7_:3'^PMGP;Y^K-Q5GGWK6HZ\J]/?G@T>'+Y/A -MY#YC6R#L^^NS4V!][>$9=_#-^>7X5YQ:/N])HZG>GVP[.M;M739"G;EGOMDX -MM'?A*'ZGB/WW]?*4(EW^38Y7>1-^ -MV#9$P++5>PM*4<3>/>PCY'7=5\+T0VKKX89I"YF#(\PH//6;$L4>L6B6':N\ -M/NPS1);FR[T1//Q3R?ISZJWCP2D-W[G*'JXT[=TSK$DBCTY@M/R^$)VSTA[[V]JW4K,:@OAQS5 -MT++<3X5R[7'QSNC%K'_6="8K]PYTS6L;\E`BWXTEL75YGGK+WJ4!TI(S:[L$ -MCNI.@2B0%CT!3P]1<7_27E5!WL;UG(N'')M65?Q&6SSAJI23WR\^H]MNBL=Z -MR'M)H4F33TR$W1T!U=C,0'SN7BJ-W,"K%QOO<]F2M$4\.A9IZZFT[_4OR[58EPR>UW)#>BB1<9;D -MY>*RMA*`()49ZEM][,99IRW=?X`BXYHAM7]A=PS5P:=(%57=H108R9U)M\_5 -MGT1&I/[?#IJ3>EXIW]Z74FYU1#*^K[YCKT*]Q,H,NF!)0^KX-/QR6K:Z_TYZ -M4R4X:VK#LH2)JNB$8[T?'KN,61)H33^BB&[.QJH>ED;6]%_Q0/#$=HVN3L=G -MZ*<_0IKRM7YTBU[1.-)9-O;/IHEM8H,YE_^2]FQ].BW;K";R8T6Y*`+::Z -MK0:[ZIJ]L^HH::SZ/0Y^ST\ZIWSJC(4+X?98M;C_]N])^(53HZ*8TX($G+]VUY:-9>_'+=/@S=.W5+PHZF*`B8X\I -MGRAJ5\/J^%;0VC`[LANY6SC\^UV?3T2W"A)UKGV"9%E\J:VMIH[S-1!JC-?> -M^G[*^E5@":,NF"+$>>!?+S1]TZ/QR:]VYDW?-9G93%!]<=+2*AF2_R -M0N-8<[Z+/N,FU8=3)9=PZYG:1V/BAP2>K'@EBF-DRU2#88(6$37W -MO%*&F1#_"TYZ-5N;_3EK6(;/E_=M3Y+>MV.S:-R9R=+2!1:)9\H(>A^8_OI9 -M&OGQN&^O)=DR\5NEI<>J8T=Z]\U:M^>W#-2GF$1N?X[Z_Q30X9P,S@TNI<0R -MT9N9=,@2Y[JZ9@6Y.&CA_ZTU0XO7;J&[HA]$SP&AY6/CNY=1R#Z74\][R<9; -MY<;HB?8KSP^*[E+[R[NK`\G_J%%BE,P\+13D&W1H&3>JIRQ0EFZ)+$P2#+0X -MKA#XTX"U@?OKR(3=,;ZANS"2[L,4V<*F^XJ8>]+EG[;^DT=&6M)AM. -MGDZ%=BL$6+J_`'R3:"GO.!J6#H<&8LH[&+YXWW@S_,@/BB'G%U'[(@1/A[T1 -M\&;33W[]_YP-;%R6,8U<;LI*(XO'DW:VKDN\D]\C) -M@[=KY,=N\5H47JOL4ZANF2@AJ?QY)>G-Q8UH-+K86YG4L;$8ZFW4,-:S/!>Y -M*.]LA1<4TZJ0`V[YN2DN3TA`W=TTX]IUHKHK2T>VI8@OJ`F(4O[-6/?Y+UY2 -MT);XWYS-`=]B=T@IN*(CHZESQ]6;1YL8MD?WT!6\.>OCE"(4OG\'R??L=[^_ -M@E!/TN8_8SOQ^=9*P=);;NG!/TN`>3";_*,7[/PTHS/XL]$S*:T;0T??*;5W -MCEUN5$:=14A&D&D<7DRX1N;>_M=0#F6RTCFW!YY.0>61>#-$51:-G#Z2DQ)O -ML\G3X6L/SBN[CT:DNI6[CS2"[)Q%!+IS^+ZE"(]D7KJ7+_U\?Y_GRO+3Z$*QX-CEG&;*V/'AYXQ.TQ7Y -M9CJ8C:-JTJ9/)$LM2`7EE7CU-L(6T.8GGX^+SP]HLT^#]-1\MWBYCXS,L`*0 -M4ZELG,ES,U'9#]T;\&3I!];V3@R>2(Y>\.6=8T_<+D1EBZ8]$09U-5KR>/%( -MAO[=%W*8IF3K=F=(3Y101HFZ?XV/OB2R<=PV:.D([?/+*I\5/[U.&*I4-8A -M"E@-W[?#[>9`,=JNT53[_MZ_&Q%&/!6DY^S:EH&B]H;W6=?&+$X^3I[)T-=T`#JJ,X5CEJ0,QRCI[7LGM?/`\\<4W8*9?^D,,O3S%F"E.^;3>?0WW>>IKO_9>DRVB1N%4W'0*BD5I1 -MV$;(E;Q]4/@P4,VZRG_8>V?EFV6]8/EO]#Y-BGT$,F-=>KE[D,/F4)/2E+O1 -M1(C@VS=3WJH=&S#ZUEZW[GGB5L]F^A*F/;6",TZ&LR0(=$R1_?CEV.MD)6N.KNKL)"Q] -MC\_HG!EWY1^S8%W1SF[^_8,BDQ-P23TP%O/7MD:^9F7"DG5KZH@:6-4Y/:%Q -MS[$'F`C)I/R!U]M&YFTQ!/OX4'O]SA6I$F:"1B$$U2@_1W"QN$['*?N_`&^2 -M.#+J/L.G?]F?>CJINK$CI_5O9J.QOS:W,1N--&?B-]:,H?U'QXJ4>>I7NI?1R/\8OR>]^QCRK1LUPB45VXF)M"(-)BT0CA;F_GW?-=7 -M*MFR5-5SM01[FSVOWGMMD!--4&EKBGP1DJ88\Z<+Q0K^VX%`JM$UDW!)RG0! -MS>S\]?#>GORZJK@^SA6L;S9O8I39_"'OH.#V]/BAG(V$O\7]<7*?]>3$)3NR -MO+/P31;-_)R6YHM+0=07,?8;/HRQ,%%"/5&Q3C&DV-:7HCD*RBIP344+N7SC -MMU]1`IE!*18+-`IP(57D$KG&-<(7DYQ0\\AF,WYT?P5VI1P:@`L-U3U*G[SQGM1.<-NUYZ-KW- -MIL.)=/+&(N_,E[0F3(33DOBB;SR1#I&-)K$VB]<9O.UU/VUV`EXY -MYN&H&=2NDZ8(Z9O(BZ,PWF5,.$)J9==N($)UFSVGE+LF]^,C,^3R8.?R5SRW -M@YK[_)6'J/1/K5N=VU:==F-[GXYMU_&.K5;UCW(F0`EQ]+0N_R4RA9\7XL;N@+'&K@RU%`R/DBIE-9)#F4\F%76COU -M^S6"\Q11HS\5#NMBWFBG2F\R1E=M,0K5'KQ)QW_DI,04KDYT:D./HU!O:U?RO83D,0BGM313Y@ -M:P*+>I2SWB[-/H?C[FJN](N]^.:AM66IM<[Y)96_C\U<#HQ9HBF+LSDCZ>`7TJ<]9 -MW3BG;N?)\VQ/N4'``W__VG1P```````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M````````````````````````````/_E+Q/[,7]KU/_G_________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_____________H!'_(O_ZQ_Z?___________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________________________________________________^@1_R+ -M_^L?^G______________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________H$?\B__K'_I_____________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_________________Z!,`=$5#(T7Q9V;W,^%<[-7=@+1MD#N]V=(H:G#Q/=( -M`AA--ZA)I@\`SL8VT\;D&?>M2!R0!DOP\\./&QXPV1=7?1(/.9RZNKNZNKKQ -MWGQ*OX1?J_5X.4KI7=_DN>RP```````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````]7?Z>=_S]7/Z'_'T_SZ'J7 -MG8OY\[H<_U^_<]3X^G*78Z'%@/H>I'0Z,(3<_)L6QFZT#(>Y#/O>'I]'H_<* -M=:?`W*=*-,E-&B1W%@F0W/=*D#ITW8;Y_W5:/4@8RP_?AFD7WKCS/@7)H]+L -M1IJ[2+S*'#(,7W6UN5F<73-";Q6MA'#.]Z>C;#!%T6]3K7X`N=_9U9 -M--3^T'O#]'T[_//YWTH>;W,V>CGY_Y/Y=C8\L&01#`V?N -M9^_=`^UZ?9L_?$K_J*P%"\:XBTSX"YTN57_ET:9PUG?&KC!T#(XU@Z(H)M.M -MCXVC`DF9QAV?_!Q5LW*/.QO#/X!&?\._%/#TZWLE@T_]^?],.0'3\5*>/1U$ -MC3Q>`0@L::NG"!4M/W.T^S^GN>CFZ?6@N@2`<1RL`U7+CRC5@29!,>/[>FKU -M&*UKZXJCN%^S2ZG-B`]*#(YVL,%!/I[OE]^<$ZO0T?!^AO"!JK##VOMU/'5V -M]*KP7&DM7+]\;=-HXXN9'5&>>5N:/[)FET[,S)4R"@?.L\4A&IYKPQ9_[CKK -M%!HKUQBB(:<8,UV_-'[(2!SS=.NH^VGK^Z^;W.WI:/@TY9Q7==8@:>N-D&]2 -M`E2VI'?K^JII/-^H[PL(JDL>0926S!'E@D'Z/4ZO[UJ7UYNM73C"^N^E3Y2$ -M"7BNBU^R"E2I1D=PE$H;YNE7Y)DOZ]5/HOB]7EU^R#100\_[L,6CKIZ6W`@/ -M8WVK_FF*$_KO#;^V#)]OZ?7_Q\W2O?*_E[G_M9/,#=';TL_P1M6^A<^'[J3C -MI_=%OP05+,6G$Q='@2Z<=_&_=!=YU9\&$S#7GH4=(8;++7&-WKO1>*]6> -MHEE_XWGX02:]6K/]XB"R<="=Y>7(3=$=F0(J@EH6`N249QM"FA;\9"HJRY"E -MB(==`E[4*3L?1-+IFX9[CNC@V3=\GQ;DZ96QH>C%MN4HE9"R03,]B.#?5\%/.LBUOVKNPM[@^$)19E-9HX1W -M=F7.%0/S:+=WTNWQ[?%D&'W%BA>CT^2_N3S>?G?TSN=&/:_+Z57+Y`7C[V>CV_E_5Z)\.5+6J$[GU[:;\$,UFB(S)M;N,(9UTC-H*]E97YMNJP8;'OU$%Q,%3>:<5^V)EF$<[RK"1;16R:K? -M,7^*A*UT^/L>2LDC@BA\&]:KUY1*!KO.(#XQ>T;%?V]5 -M\\O=X[SV26E.7R):2WLQ!=O/1QY:=Y5C!'EB+X"TY>YP_'PB6[+8)7S4WX\" -MFY"LR-6K[E+GY7!=&":IE5-4MJM5YI#+X.GL:LC4NO1!^SJH43I[?:Z_2D][ -M:;H,6/67;_KG;^D+YA!V$Z)91L=QF'<6TMB93A_ZS*^)IZY#*L*$MR>X\/'_Y!W"\V(_Q2_99DTHAIM4N3(&D8F\YT[ -M>I!0VQXHPF1=+2OUV5A;ITT1K=UDAQF-MEYTAMRDF/PJ?A^'L^&5O@V$/OBW -MSX'TX?YM1A8JX@H5A[?\B[P-VT]9JV!^($I<,I@HHCHRJ`UP$.R(P9WN7Y8- -M.O@>+&:>F92NE<0K"3-[^(;W0Z,SW\/I\T$Q'\K[XMLI:\C/*7JR#SB?JCS, -MB`?>S',6^[-)MF6D!KT>KW$@3(G!Y*G\C\&=M^BCM5E-JF5GV="Y?,WTA1]> -M5[YY2"EY=B@W4D92M\(W)C2X)\'O5]%H4V.[&U2K<-I55B[9JP-W:WM2$"#Q -M`=LIB1U.^>/1"L86@R1[/B-^N290L24:_HFJ;T^JX8#EG+23(L5CWXI0<>E@ -MNCQV!VVR"IJWZ -M?#W."E69,E;N6D1QA].1D/-@3!LTZ21Y&L3=?!MXT]Q^\"@\2+\AS>QU1C_? -M(&-AWY&=ZM2L/W5Z*0"EH!E2S="%%-;8U-7%#R0J130TYF=2OSU;-&S'+CAN -MGK,SC=&>(Z+UD6TK8!/`%HYQ\>5#O,`9]84WZ=*T(]W!L[&+#$U](CR^.F4, -M]?OT)8GNKZ_?T;9(2IE/6@#S.LB3I8NVWTH;#KXQ!483RP0Z -MCQQ^G.NO7R*W43+\R":5G4`$X9UVN!,O^03EJW5!F6RN_CS@AW-+>D`;.@372'_I98>X -MNMNSRUH!(0D]BG@..)>9\:2Q0A7X)*]XS%3&>,HIR)(XDVI(US+VN$0PY4'6 -MV)RKC*Y)5'0EF#$MJ-0$,[),L*"*!.1>V8?*4L?W;&8'AC%2$JYLY3DZI& -MU>+!=97.U4/!&U7O'&\?:\$G_%6G(=&K1N+?F -M7:"^X,+FCH5:1/&](^6JGIQT2FTJLDK!]'PS[%.C9XTD7\-=ZSHYYR^U^M&# -MHR1V/UYW;%I&'1;&7!+PT#\R-NTI$$Q8`LVHY.]/3`BJO+ -M+^L?:RQ:$^R&>7/ND`WM69`/+M7(R0=P=79>:\;L^2ZU97C+L^GVKG^#TW\: -M2FJB+%GB!(2\=NP1(<6"5%LO%@KI:E?-7V],$ZT`M757:1Z'6U-?._&&E?WP -M]NKS4C<"`;C.8]CQ!BM72J$E5NT*L\F&:";.5.,-%=+?*\UG`5,@7=DJO:WD -MRW(/P:FUD]Y4,`>CSZTM+[A_N)*];$RW->5"%N%)MZ7V[<6/7'8YOT)*H&#T2*4L5 -M\X,Y'C_MY!G575T.4HO8U`5?ERZ;"K8A#Y,LG]NE`DK'\Q.T9`X';6 -M53%K:](_(QA>^+2^>[@GAO2HN67TP&V+V[7(QR=>TA6TZ>QV+DJQ\$\FS1[L -M2UE=?&N6+FUY2VEM0D1B#`ZVLGGC8GZ\9-]1AK*^;REXKANB7SD;*F;QO,[# -MA5*VXU)H`6;K9FG3V-;3K]KO^]^LDC:SO_O&;YY3V.E#Y"9QF$KIFFKY"9FU -M*]0XG[(O[[ER9RD@%&#\((LLKZ\/BA/TLD)_N:'>[&7LECO;NSDTPJ'7S/X] -M#GYL66'D]O^4&0.[;WB9B^69-5ZZ_Z/'4@793?W*S&5ABF5(Z+#&&O8R/+QB -MW.J[5===>%4H>]+N;SP]ZG1FWA[._!MQ\N=K;'EMTHE>-M*X[6!'<=Y-U]"8 -MW:#T@+7IGD>CI9M&&>.;5O>0#EU.UB];V=C0R[$BLIW[Q)QJ/0/V#HU7X=`C -M"F\,QYYK5T.+GM]E,5$E_B`"O'+:-/.C,7C^`XXOA"`/^F\;7XEV-VQ=;,\? -M<\%QV$T=8UQ]#241[8/!M/(1@V6M0OC#0F\U;XFEIQ#+?D<&"R%>WJC:UCE2 -MK!Q$"R8W4*+6PP5)C3=3[NI-AI0\D-=[.U[L=,GR*S53#,"R-39V:.&#YNEQ -M'V5I?^IY(MXJ3&CP^7?LW-F7$[3C-T(^][V*[=5!H]Z\N_$XVJ5`!,7FP[.6 -MGOHXEAC;N2>5^._P:.ENC)!O0-]`1=\JG&?6[Y/6>7DE"W?8D]$:.X3A?ICD -M3S)+0U'@?&?4*W@IN8KNP2RL),.A]+9Z`C;K*]7^*QF`1^-V>\I3L%7CS)5N -MGQ;FK(P'$8^#%)G((@:[UV`>;Q*<0!Q\5ZKPJ>/'XHL@_6M+<\5997`>9TB; -M)JNA#J`*O\,)8SC:N( -MJU_='9PQ_/;[OSX[@FM0M)F+*VOK-N-[DY0)EF_PYH/(PSY/6;-Z]`Q:(?$X -MIH]U+:<`_`57/1$.1'2O7VZI1SOGEPU;U=]>&25%&B2=;5UH='_[7,N-ZF/X -M!*FZ%9-Z>62UC_#NX]Q_PH]BQ_P69O#7E5?G4U;:&,XL$:M*QY%N70_G]\:7 -MG2F8V)LG5JMB?2]!7,!,K("PQ`5(1DKO.+9SA/>%=]V(/GZ/N)Y\$KJ_VYG( -M^$OJV=X39O\?+M_5>C,V7>,/ONV]K6S9+4LZ2RS38(*`.;HP0:V++>%/'RGN=[)R4E -M(R+B`?RW1$ZZ1/PN1G*O,52R-R.%R0X0W#%J!]JFZ^CYYE0O?(N\.E4652)9GQ?7:_FZ7]:0A=$?>.)E>72RW1( -M+E:*LHEEZQ-XL[T6N=0G3XB?PL"$3NLIVS%BD -M#X7O8KQV]=(8N20U5H?WZNGH]KW"T.SV=/N0TV]/0Z?9Z/V=OM]GZ^WVJM]KIRJ:?*(N_-@GV( -MA7UT99*4%UP*5])9V5W[C;XQK!G?1&M=F*E-[9&R)RK'MX\96;[GU1]6U'^P -MV*A5>A=JEG5!AT:E*+VR"5)5NF?8@YAI;YX0N7,.2ORN5V<=:FU]BS9M00Z^ -M)6VM]4`%&SV]I#02>['39/TYXPGUI/."5;5FN2N'"ZY4MDY)IKT^YH]NYIM7 -M,PM#0GQ`5T]+L:'=ZO4H'.MUJHR`A*X+#<5G<&N+S1[?3M,5\DOGO;^?"8.A -M*\7)@G\#!D>+__08+@VG_RO9!Z$@+^0]JQX%,A^*I+D++;=<1HUU*?X?H(RZ -MRD-O&2BL:LAMQO_U]N@4GYF5(J+8Z-L@3K8U[T>U=R\V\93!3F7*[828'L// -M;'E'!S/KRT\&A[^N[D#1%60-"QMN\M5O5F^]C=CTO)+\:6]JAD[C9J -M+T1]^/HQ`%ADK#Y+L:R5?]]:?,9+HW^/3"D>$*'1=&UNT,NT.2QN'C1E2L>; -MHXZFW-]3:TKMXT9CN(/6C.8Y(D%??*JR$2&K(.QMX^ZK/PIGRKC!1I(?4GW= -M*6-(/N+!D5&?DG(IV.KT_[Z<*.B]6&\SO=3IQ_`L%SD6H0/DDFWX?+;]G?T> -MSU-.%)DNC!T`Z/:Z_UY$J+I]WW`[W;T_9/L[NA[%T>M[I]6YS+X?%'_IOQC. -MQM*H4L`'"M;'1XZ -MDM7I\=CE7+PU;U=CGVMD#S7YB*PW*G1T_`G=VW7!PJ?0! -MGED[(\-L^A7'6/QG!%^:5;V$N!/NG`P]%*?^',I,YXFPV5XO\6[%WLVSS5>[ -M5*KB2G#C,->'7($D2BV'_(`6`+JK!/-JK^,>*F?Y$SMZZ'E-=,H.\E5_CV*, -MU34&7A^_@98_SXAJ#NPSL4X73K_'#T`'9R#QN6R#L9<:5S#U=5EZ0:'J&?_1OUJ=Y7J9V45-IF0'97^*.^+__"SO/I(.MP.7!P7! -MDL#G$T\^K,^^=@6>9IU!]1L+14"5EZHLTQLNZE*M8V]_NS[5.(N7ZDV)#A@T -M%ZLGY1?TZ:KDIW%%#T%Z:I_-!OKZ+RD5=I2"AM"&%<F9T -M)4;8EZTP_]:ZQ\:ZL$+8ZCW'*P$KI=7`JAW&B`X"L$74EEA\0F)4\,?$*= -M)^FMK.)('5=PI]2Q2Z^_730[/($"GS+O_!&9U!*C)X?'A -M@?Y*C896K8#TVO&DM$D22E7*N*(B3^,?S\OU5%]PRV!S7PKRSV"SOT!T,ZT, -MPL4R*@,RXD:/S2>+!)2O#+.:Z:,Q8_^.2Z6&R*2J+V7[\: -M22)H5L&)BIB?-HXT:'EJVWE_5G?,9\AF!,+P_UEW#5]\G0%G#)VXCP8-TS?AB&NAMH_. -MN5%/VO(#*WC.-;_ZGB5;*IK_;@LW5I.H!'+^BMQ[-+NO!WBBNN[D;Y4S@#^6 -MHS$7/#O!UIN3`'9`$\5()9:$%$A(@LT,;V4GJUA.@TBYDIMY.GL?09TH9A\) -M&P041M.E;WF>U>2&#?F/WE'F,BO*ZHXRMFG.4]R\XF#HL38`X.\XZIB8X^4Z -M+=#]D0-G0JB%''.S*'*%8Z!;J`%`KA\Y&7/KZS6^;]PS16V'DY-JLE4>,SV/ -MT*`LO0H#YW`)*`$IKHJJ"QZCA"SM7<&"Y@8P^"NJ%/LC/+9!MDH-[NF-@8B_ -MQ:5_!6.\OY3$Z6*!7\LQ(QTK#:_"+C%[ -MIC`35R0R1;7ZI,Y'=?$4:=//'-XW24FT,WT.C$L@1Q -MY_*;"^'_P\/Y.@EFU-O"'D4^K5<5GE]_U!6JBS;%JZAJ[\JLBO3XWR&CBN\! -MCPZ<-=8'E_AIA>6$9[C_BEU3*RW\.[B7DNO_<%OK+?T)F12>Y(<55,;K=K"(G&R@7H(+?[%\=>>(9Z@6TQE!(E&WM2 -M6(RN;K4PWW']QAM3&8-'BI_6V=>67EETJI58I/%^V'Y`)QVJ_-PMX]'D!@K= -M_+9>*F5IB.48.SQQ#>+SP;(Y4"(##2,,M0SQA@*5#))W!,>O-<\UI28HY\8F -MJHQ'H024"3S^?UK8"Z7/=\K'0+LR"^RG,84.3AZ];N!L-GH#K04MI]9.=!?B -MB$Z]TC-BS^R'^![STM'0-'25OTU"3,__$G[1Z2"`^20%[@MH"Q2? -M86#8@C1Z(*C]I:QL=F6)`;KY@H_,T5L"L:6B;=')"FI%Z_?\H?Q0*=F(',D@ -M2=WK5_P7-S=2XP"?&(,C3_T.XL3CZ[K9Z%['FYSEQMM/8@C?I",[7*J9#'<#$38ER^&CDX+%/!23F(@$9333&F -M/+`;A>+LC< -MN#ZSUEL'U^<.&%VP+^OO.!0"$M9%QK`Y8X%?_X)[D&NV>:<$\63EC95#B$MZ -MIA(SH*0.J:-R]2?N3)]GK;TL0',."`?@?@LK@,.KHWH)O?^Q_#S;S(W+/=:S -MT\HC*W*[P;&6X:&X8EK)!CYW6-Z0<'CJ*)1CRWP%2QPT;C"_88ZV*0X([8Y\ -M83!'!3.7?CWC;GD^2UFZ6UC*J+""K@"V8/"2,I303I'KH4C;_CD.[A$N)@7S -MJQ[`@#=F?>_')=IS!XMAQ..0&L#!;L(.%B@PL9+)-@(2E.J=[@][BYHA=^?S -M).>%M<`]TGO@R#.@+*40.C:Y#]ZX&1/YFF7Z2>*IG8OFJV#FFM;\51V_79C4 -M'[XBKA@(\G0!44;221&B/;''5VV2I?VH\)5KI3$%"2#0?AUSM(BS][#.V@HF -MBC:DVP1]/X(R\X;0E%:NRT"[#D``*IGFTL;GZ`<%\@NG#C(T!A2&3F9H`9<$ -M@H-R[]/">I9P5\\V$6S@\6&LO4USF:\\)IO\5SLB)[&#KV**6`Y%J'Z_.=ID -M2W[OUORZ#%,C@O>S=,9MV%(CMAP)/!ZEE7X%S9*TCCD8.YT*T;!Q^SOU1,L+ -MSM#9?/,;8#AGKJ^&>TW+OJ_PZIW\\;!NS]:K77N:KM;EE$"\F+=ZZFVJ7[FI -M4;-8BH`_0%+,TP>18F`>>C3RS]*C81!3K7S.^49,D#O"+V`:N-_`>9!QCTE#GBQR&#/FF+YT -M__RE!AL$3WT4U-0NFF.#\CT',T83SUZQ&Z[[Y=K9SLGGRDJ7G9M#?-6;F1,% -M:O*;F:56.:E]\JHWSJJ4PQP4R%D<$*]@E8_?7=W>#)SMT01Q&1$.>!2YKF6$ -M@%1](?_RA0FL>D"O'C_1UB^1'83'4>8Y95+1L3Z4'8'P6?*9Y:J"H4.;3IGS2J"[,S41\8^;Z\U2.%GI^L=FS/*!>?5:!O`7Z3OF(,#F+-D?)S@,%_Q7/EG\`;NF!1XU' -MVE$)*Y'@"8&Z_SES.X!!NU'"4$W9(%QFJCZ*D@PI9A57VGZ7X>^X=KV4WJWR -M=6Z1E>+R].WV">O68NY/8L(`R&D:F1LU>Q!&==(8>(NVEA.([@?W9^J"07@O -MY[5*;?VOMHS&^D-Z=8:),#87K9%[T.4=IAM^9:^=C;[3'9M%7]4T[=$T".LQ -MV,DG[_'^&;V8ZA'.&X+>OXJ!';3$T;[L!=29I4WU]%M+5JZ(#?WL,D2#-J=H -M/'+%EPE_9M3J1<$VTAG]PX;@N5,:NC,_K0P*"H%3NB6?P]` -/%`!8UZ=L`@`````````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar_multivolume.part0004.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar_multivolume.part0004.rar.uu deleted file mode 100644 index 0bfad779e..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar_multivolume.part0004.rar.uu +++ /dev/null @@ -1,208 +0,0 @@ -begin 644 - -M4F%R(1H'`!EZ5J2C]?9NI\:;KW2+#TR@_Y5=4S)O&)O_B>J0/A0T-,@"ER';1YX:$ -M>AMQ1<[:Q1,R`,93"OEGSEK=MI8?J`.7F@.OG"C!,7`D$L>"<=.F[V1><*&Z -MR!RD@+&WIGW-?>ZZ^_[)-77?FF6P7=.]0P[ZG&Q:S^`6\IB_@_1WBNHT(_NG -M9U/F2.B1=F<0IU_\^4P5:0(O3UZ(%]?;P+,:P93'TY1&$%1":^%%QL3=^$\H -ME^-G\V%^"LU6_VKL;52EXDPE5CDBK6:^`<^^NLA^<#12RV@C=F&KA_.16*(< -M"Q`]X2NXR"Z&3R8<-5)4NFON6LA>OO>DP%W\;:X%U02HV.0\A0\.7]!)P@O](;[;\:,&&0*B -M5YO(-RW/XL3PZP4?[(9_89&I4IC0F/699]][TOVQ&#CK -MG./_&Y%`6$E28)$-"V2S&^(B:;L27@TZP;&XQN2>P`3>^+@^U -M>SZYH"D6%EA@NHX_.PQ"JO1!20@`TMD)JB'I4I6"Z!?34%7`3B3`S[W"5 -M57Q3X5LE'?*5Q3-?=]G(TA<>1WH"VL7#SCU2]U;3<;1UI+Y@+PB1",6L'D/@ -MM!@CO@&YJ.1``6:=$6ALA);LL4A'D180QBLO%%EIX.ZI5Z:!`$!,8K@_@W/G -MDRCU(!GME6;Q(J$ZL*]%DFPT@C?A&-.+TIF=(7IXW!Q5:4`=:^IG+R?95I#+Q#/-`66)_ -MT1OPBM\BO<*$C9V>"#>` -MT"7[\W$'7L? -M.*&G[H-0!K:L3\`9B9&#Z9KX0"@%40J%1LYHFH( -M)4A3)R0;W.R(MQ0.BYI%9)X*2H$/0.!4^\4JHQ!H:'=2VRCP1`%NG14 -MP<"#A;@MF=G$*%LRY%A-!VF)^Y!W3T/[,E` -M*8*K8Y:![1="6!^TVCEP%LPT6GQ40RGE5`!6.DL%`_JB<:0,R$[\KW<],]RQZ"%LR"S^Y"[?Y4JWM17;TS[]M9 -MC;^>;TRIT*W.^0A:N`>!PT\WL&47&.3;3>B$`L?U34%5S.,URDF.1R4BJEZJ -MO^9/\[5[(&31;I29KEF=.NV\#96`_.5(87"X^@BI#\ -MS6>SG7G"U:U9X-[@@(F&JZ)2H_\6_*/R9RR]W.]0A*T&+M\/-7?G'?EZ_A)LM)_!W)4+\X"=68E3"2 -M"@`]:LP77GO\ZH[&=!+0E.M:'.I=!M%.=8Z7`FK+6?L*4L!GZ;`X[DZD2/QU -M4.S#!XYJG1===9V4+@KZ`UA-9/ -MWLY^X*'G!%G7[@QC2&-02_9@/UTB77._0#G].]H#K^,<[,!+'&_]?7`LQ5EQ -M0'P[C^,$E*92AFIN3S_7G#83@/;-48\%X^QXOHC_)E8*=DE*HS?V=(T-OV)1 -MAL$4XOL.@##ED,"_T.;E"5;!0&?O@9^SPTGEET`Q)J6>MY!/J.\5-%>&`7DR -ME;S:JJC8-5QP9R*>^T0COJ@C_1K!P'Y>C]E.75$17>M_=YH!>Y'YI4N*M@QUD9&[4N$MCJYU*;3J-(2!4].I6J3=27\XWLCHXI4S -M@6T8Y*+]ZS3$\BR!ZF\6=*_W:'B961W(FK3W?%&RZC!XLW74?M*,M:!^M)BJ -M:D=K]+XRT%`JI2#:NE/5FSR@_:!F0CU'G9)J;QUW%),+#8PJITA!\!/L[RAP -MC%W6^E+33:;\BV+%UZYN1=B6XYQ_*%"&MYUE9`5]$?+!N:NVZO.@0?07OV+( -M%//RQ49B0?3320&&!'QG],AFT&X!7&.ZH7:XB>OFM5?F]=`[VCM]+OBI]XR; -M26Z9H'>QH;MIR4*+EMZ5B5>(U=`S=53Q8M-?2QK,13>K`RTT0[NC-UOMK-"Y -M0DN),([?4I''U1B^TX%CU3$H^!8,$J9[X?<%B$@V$LA#)*-]VGUOGMQAJT*#,T@E7'H< -MFX"OG#',\6).^M.P#$U88"G%$%*_4%SQ4%>N&HU1I$L)())YB9_$UH<+^=N3 -MYRR-IW4/+MT-Q^(B+XP2[3]2_K*=YS)`;8_;;H8V0[D04ZA'C-[A,?/;IM'RF[NI_[0RVO/\>N\UX-FW^T!JEO_YRB?5- -MR0//T/N.C\DV@ZX*UFO![^V@8(EC4'=\. -M[S$:_]T0'^Q%]Y3>(CDK[#8)Z.>^[?6$1RMX;3NSQPRL9_1"<,O>[T -M<.RE!&)^#O,JH_N028&/]@"/51>IGP4!-U9Z+(8)9&MI+GX-NXS"F5P\E$C; -MM+>:KG]!QOF2I*(I\]UW'L78A3"+QFQ=DDDG6PKG%'VX-):?[EW6[%1=*UZ` -MYQ1MA$-P>RY:@S_6S:E?VN8GT)<@)<\I$S0BFW_:6,'U'S$#Q8FSC2\2KINN -MJC$Z-215^PH`:`D%68PZ>0@C2PNXS3T&"%*7I82@&X"'!!'+,%(A(FI?7P]3 -M,&.,;CK9H^9SAI!%_..5#/M=O)1P&R5M7Z]:,-WH:Y7SI,3!C]<4#ZSME:.% -M0'-4/.3'C0G]K=BM\&%*,&UIEJ1&<.7%;CH?6C$X=$NFE^`3K-PLY[.!D=^O -MEFM50/A=JB@J*B4L7LG(`!SR]<;B\>0)&\SH.\65[0N:?@-DK.$$66H35*C8 -MW&&\2TG;_]J2U/X^=1,!-/8DKL$?"-U+LRC[V,4>5CY=;BO=2!`W`Q_= -M'S5[^HJVHU2F!`_#O`#GU(EHGT*#MI[^DB$T(P```+^(9_:I_]3K4'3`D#(` -M&0```!D````#\=/\$2J%$C\4,`@`_Z$``'1E'3`"+*!$C_3@1(_IQAS[Y;82LZ= -M4#-R:O8OE21=#P_TUX6[``"_B&?VJ?_44IATP)!+`/(6``"/3@```V.F!5ZR -M@1(_'34A`*2!``!T97-T9&ER7$QI8F%R8VAI=F5!9&1I;F=497-T+FAT;6S` -M"+*!$C_3@1(_IQ@[Y,&O-%WTZIVL0'K=[L^M$"SZ*I?&B@$S2EO?UM\%P_[# -M*[0L[1)9)\]U]*;T*VY-H-V?:#KQ512.@3PFR-]M+$AU5@KH[FU"*J*5<[>J -M&?_1OUJ=Y7J9V45-IF0'97^*.^+__"SO/I(.MP.7!P7!DL#G -M$T\^K,^^=@6>9IU!]1L+14"5EZHLTQLNZE*M8V]_NS[5.(N7ZDV)#A@T%ZLG -MY1?TZ:KDIW%%#T%Z:I_-!OKZ+RD5=I2"AM"&%<F9T)4;8 -MEZTP_]:ZQ\:ZL$+8ZCW'*P$KI=7`JAW&B`X"L$74EEA\0F)4\,?$*=)^FM -MK.)('5=PI]2Q2Z^_730[/($"GS+O_!&9U!*C)X?'A@?Y* -MC896K8#TVO&DM$D22E7*N*(B3^,?S\OU5%]PRV!S7PKRSV"SOT!T,ZT,PL4R -M*@,RXD:/S2>+!)2O#+.:Z:,Q8_^.2Z6&R*2J+V7[\:22)H -M5L&)BIB? -M-HXT:'EJVWE_5G?,9\AF!,+P_UEW#5]\G0%G#)VXCP8-TS?AB&NAMH_.N5%/ -MVO(#*WC.-;_ZGB5;*IK_;@LW5I.H!'+^BMQ[-+NO!WBBNN[D;Y4S@#^6HS$7 -M/#O!UIN3`'9`$\5()9:$%$A(@LT,;V4GJUA.@TBYDIMY.GL?09TH9A\)&P04 -M1M.E;WF>U>2&#?F/WE'F,BO*ZHXRMFG.4]R\XF#HL38`X.\XZIB8X^4Z+=#] -MD0-G0JB%''.S*'*%8Z!;J`%`KA\Y&7/KZS6^;]PS16V'DY-JLE4>,SV/T*`L -MO0H#YW`)*`$IKHJJ"QZCA"SM7<&"Y@8P^"NJ%/LC/+9!MDH-[NF-@8B_Q:5_ -M!6.\OY3$Z6*!7\LQ(QTK#:_"+C%[IC`3 -M5R0R1;7ZI,Y'=?$4:=//'-XW24FT,WT.C$L@1QY_*; -M"^'_P\/Y.@EFU-O"'D4^K5<5GE]_U!6JBS;%JZAJ[\JLBO3XWR&CBN\!CPZ< -M-=8'E_AIA>6$9[C_BEU3*RW\.[B7DNO_<%OK+?T)F12>Y(<55,;K=K"(G&R@7H(+?[%\=>>(9Z@6TQE!(E&WM26(RN -M;K4PWW']QAM3&8-'BI_6V=>67EETJI58I/%^V'Y`)QVJ_-PMX]'D!@K=_+9> -M*F5IB.48.SQQ#>+SP;(Y4"(##2,,M0SQA@*5#))W!,>O-<\UI28HY\8FJHQ' -MH024"3S^?UK8"Z7/=\K'0+LR"^RG,84.3AZ];N!L-GH#K04MI]9.=!?BB$Z] -MTC-BS^R'^![STM'0-'25OTU"3,__$G[1Z2"`^20%[@MH"Q2?86#8 -M@C1Z(*C]I:QL=F6)`;KY@H_,T5L"L:6B;=')"FI%Z_?\H?Q0*=F(',D@2=WK -M5_P7-S=2XP"?&(,C3_T.XL3CZ[K9Z%['FYSEQMM/8@C?I",[7*J9#'<#$38ER^&CDX+%/!23F(@$9333&F/+`; -MA>+LC:<$\63EC95#B$MZIA(S -MH*0.J:-R]2?N3)]GK;TL0',."`?@?@LK@,.KHWH)O?^Q_#S;S(W+/=:ST\HC -M*W*[P;&6X:&X8EK)!CYW6-Z0<'CJ*)1CRWP%2QPT;C"_88ZV*0X([8Y\83!' -M!3.7?CWC;GD^2UFZ6UC*J+""K@"V8/"2,I303I'KH4C;_CD.[A$N)@7SJQ[` -M@#=F?>_')=IS!XMAQ..0&L#!;L(.%B@PL9+)-@(2E.J=[@][BYHA=^?S).>% -MM<`]TGO@R#.@+*40.C:Y#]ZX&1/YFF7Z2>*IG8OFJV#FFM;\51V_79C4'[XB -MKA@(\G0!44;221&B/;''5VV2I?VH\)5KI3$%"2#0?AUSM(BS][#.V@HFBC:D -MVP1]/X(R\X;0E%:NRT"[#D``*IGFTL;GZ`<%\@NG#C(T!A2&3F9H`9<$@H-R -M[]/">I9P5\\V$6S@\6&LO4USF:\\)IO\5SLB)[&#KV**6`Y%J'Z_.=ID2W[O -MUORZ#%,C@O>S=,9MV%(CMAP)/!ZEE7X%S9*TCCD8.YT*T;!Q^SOU1,L+SM#9 -M?/,;8#AGKJ^&>TW+OJ_PZIW\\;!NS]:K77N:KM;EE$"\F+=ZZFVJ7[FI4;-8 -MBH`_0%+,TP>18F`>>C3RS]*C81!3K7S.^49,D#O"+V`:N-_`>9!QCTE#GBQR&#/FF+YT__RE -M!AL$3WT4U-0NFF.#\CT',T83SUZQ&Z[[Y=K9SLGGRDJ7G9M#?-6;F1,%:O*; -MF:56.:E]\JHWSJJ4PQP4R%D<$*]@E8_?7=W>#)SMT01Q&1$.>!2YKF6$@%1] -M(?_RA0FL>D"O'C_1UB^1'83'4>8Y95+1L3Z4'8'P6?*9Y:J"H4.;3IGS2J"[,S41\8^;Z\U2.%GI^L=FS/*!>?5:!O`7Z3OF(,#F+-D?)S@,%_Q7/EG\`;NF!1XU'VE$) -M*Y'@"8&Z_SES.X!!NU'"4$W9(%QFJCZ*D@PI9A57VGZ7X>^X=KV4WJWR=6Z1 -ME>+R].WV">O68NY/8L(`R&D:F1LU>Q!&==(8>(NVEA.([@?W9^J"07@OY[5* -M;?VOMHS&^D-Z=8:),#87K9%[T.4=IAM^9:^=C;[3'9M%7]4T[=$T".LQV,DG -M[_'^&;V8ZA'.&X+>OXJ!';3$T;[L!=29I4WU]%M+5JZ(#?WL,D2#-J=H/'+% -MEPE_9M3J1<$VTAG]PX;@N5,:NC,_K0P*"H%3NB6?>&A'H;<47. -MVL43,@#&4PKY9\Y:W;:6'Z@#EYH#KYPHP3%P)!+'@G'3IN]D7G"ANL@B!?7V\"S&L&4Q].41A!40FOA1<;$W?A/*)?C9_-A -M?@K-5O]J[&U4I>),)58Y(JUFO@'/OKK(?G`T4LMH(W9AJX?SD5BB'`L0/>$K -MN,@NAD\F'#525+IK[EK(7K[WI,!=_&VN!=4$J-CG'Y+`M`=_$)S"+XG1P/;R#]+]L1G(=]<2RS[GU*A9"'@XZYSC_QN1 -M0%A)4F"1#0MDLQOB(FF[$EX-.G-%IL"R>^D'L&QN,;DGL`$WOBX/M7L^N:`I -M%A988+J./SL,0JKT04D(`-+9":HAZ5*5@N@7TU!5P$XG*WDP,^]PE55\4^%; -M)1WRE<4S7W?9R-(7'D=Z`MK%P\X]4O=6TW&T=:2^8"\(D0C%K!Y#X+08([X! -MN:CD0`%FG1%H;(26[+%(1Y$6$,8K+Q19:>#NJ5>F@0!`3&*X/X-SYY,H]2`9 -M[95F\2*A.K"O19)L-((WX1C7+\,"C_O&Q3T#B89[/)-^"!.+APK^IR\D-H,Q -MP;Y6E%P#OX)G+GCB]*9G2%Z>-P<56E`'6OJ9R\GV5:0R\0SS0%EB?]$;\(K? -M(G)#G,"H6U,%NDO1/]T]UM`IG37ZW[(,_QBCF$/''KW"A(V=G@@W@-`E^_-W -M-R.XJM'S!>U_H8/-/BJ]GR;;5BY`TQ(XFX%Y=Q?#.N;8$SUGA!U['SG,(MZ< -MO9L-X(T(4TE%H.1U$[395;RQ,1'0^*_+E8C]'51T5@CO=/"BG+NX=8M6PZ=J -MZH#=U=AZ;,N"DJ!#T#@5/O%'.A]$)V4[ZF/=-B33C+IHFHXQ!#09]X]26N4Q11"G($O]S'?ST_P&^?6CP-)=``;)M?+ -MZ3,GZI1-;E.@9BU@.KI!/3G[+XW\,QO\RKBL]R'#REC_#0E:SN:"A?7[GQT? -MFQ1&I25+93T70E@?M-HYDJY&(!CB_!>)P<,YN. -MHH"<1EP]'JHG&D#,A._*]W/3/@A;,@L_N0NW^5*M[45V],^_;68V_GF], -MJ="MSOD(6K@'@<-/-[!E%QCDVTWHA`+']4U!5JK_F3_.U -M>R!DT6Z4F:Y9G3KMO`V5@/SE2&'*JD`18?T@"_RW5?>GEPN/H(J0_,UGLYUY -MPM6M6>#>X(")AJNB4J/_%ORC\FOX2;+2?P=R5"_.`G5F)4PD@H`/6K, -M%UY[_.J.QG02T)3K6ASJ70;13G6.EP)JRUG["E+`9^FP..Y.I$C\=5#LPP>. -M:IT7776=E',!QM#>;?Y([:G8%ZH]"6'[O":M?%N$CTWBX*^@-8363][.?N"A -MYP19U^X,8TAC4$OV8#]=(EUSOT`Y_3O:`Z_C'.S`2QQO_7UP+,59<4!\.X_C -M!)2F4H9J;D\_UYPV$X#VS5&/!>/L>+Z(_R96"G9)2J,W]G2-#;]B48;!%.+[ -M#H`PY9#`O]#FY0E6P4!G[X&?L\-)Y9=`,2:EGK>03ZCO%317A@%Y,I6\VJJH -MV#5<<&:`7G.KOLD0M>. -M"GN1^:5+BK8,=9&1NU+A+8ZN=2FTZC2$@5/3J5JDW4E_.-[(Z.*5,X%M&.2B -M_>LTQ/(L@>IO%G2O]VAXF5D=R)JT]WQ1LNHP>+-UU'[2C+6@?K28JFI':_2^ -M,M!0*J4@VKI3U9L\H/V@9D(]1YV2:F\==Q23"PV,*J=(0?`3[.\H<(Q=UOI2 -MTTVF_(MBQ=>N;D78EN.=960%?1'RP;FKMNKSH$'T%[]BR!3S\L5& -M8D'TTTD!A@1\9_3(9M!N`5QCNJ%VN(GKYK57YO70.]H[?2[XJ?>,FTENF:!W -ML:&[:E8E7B-70,W54\6+37TL:S$4WJP,M-$.[HS=;[:S0N4)+B3". -MWU*1Q]48OM.!8]7*PPT9M``F84D^%&"M352>U(M6.!#E5_V*T?MY^XY9V]-V -M4="E.(LTG]ABY*3MN`AZ?;5AQZOZAIXU,D]19D@BBIQM:.IVNM+@$<'Q5CV_ -M;+3SM&3877WTML/#5=N]D"`:QNY#O5+F#=*$V*^8`AR-DY:[FT8>UOA+:X'!VUK8ES23Y_10,7UAB'DQ*/@6#!*F7,5@2I@0J0. -MX0@_DI9C4$E-,_37N^'W!8A(-A+(0R2C?=I];Y[<8:M"@S-()5QZ')N`KYPQ -MS/%B3OK3L`Q-6&`IQ1!2OU!<\5!7KAJ-4:1+"2"2>8F?Q-:'"_G;D^Q?X3KS^0Y -M^QO'E.H1XS>X3'SVZ;1\IN[J?^T,MKS_'KO->#9M_M`:I;_^_MH&")7-%&):P%<`MLZC6-FH2Z>T@W[\2@\__'YX#-KR], -M)%@%3_]29?*@]-.[-I<9^[3=D!^JI:S-__CZG#FH'HU!W?#N\Q&O_= -M$!_L1?>4WB(Y*^PV">CGONWUA$&T[L\<,G*BT&GK&?T0G#+WN]'#LI01B -M?@[S*J/[D$F!C_8`CU47J9\%`3=6>BR&"61K:2Y^#;N,PIE@.<4;81# -M<'LN6H,_ULVI7]KF)]"7("7/*1,T(IM_VEC!]1\Q`\6)LXTO$JZ;KJHQ.C4D -M5?L*`&@)!5F,.GD((TL+N,T]!@A2EZ6$H!N`AP01RS!2(2)J7U\/4S!CC&XZ -MV:/FO,Z^^+6LUQD?@\+T>;(3/ -MW%3.#V,*W7AA2C!M:9:D1G#EQ6XZ'UHQ.'1+II?@$ZS<+.>S@9'?KY9K54#X -M7:HH*BHE+%[)R``<\O7&XO'D"1O,Z#O%E>T+FGX#9*SA!%EJ$U2HV-QAO$M) -MV__:DM3^/G43`33V'.E7I*[!'PC=2[,H^]C%'E8^76XKW4@0-P,?W1\U>_J* -MMJ-4I@0/P[P`Y]2):)]"@[:>_I(A-",```"_B&?VJ?_4NIQTX)`Q```````` -M`````P````"R@1(_%#`'`.U!``!T97-T9&ERP`BR@1(_LX$2/YN==."0-@`` -M``````````,`````MX$2/Q0P#`#M00``=&5S=&5M<'1Y9&ER@`BW@1(_N8$2 -5/RRE>PY`%`!/(RA<`P`````````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar_noeof.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar_noeof.rar.uu deleted file mode 100644 index 7cf88e7c6..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar_noeof.rar.uu +++ /dev/null @@ -1,5 +0,0 @@ -begin 644 - -M4F%R(1H'`,^0%0P -M/&L'[WB2!U7<*?4L4NOOUTT.SR!`I\R[_P1F=02HR>'QX8'^2HV&5JV`]-KQ -MI+1)$DI5RKBB(D_C'\_+]51?<,M@,F]PE+VS -M]2/>+LTL^)KUF2N[8ZO?.RN>$#S?0H]0YSYGBDJB]E^_&DDB:%;!B8J8GW*J -MO9*/%:M1X$FFP^&O`[RU:XM%UY]0#EF9\,:3">!<)ETSY)F5GC:.-&AY:MMY -M?U9WS&?(9@3"\/]9=PU??)T!9PR=N(\&#=,WX8AKH;:/SKE13]KR`RMXSC6_ -M^IXE6RJ:_VX+-U:3J`1R_HK<>S2[KP=XHKKNY&^5,X`_EJ,Q%SP[P=:;DP!V -M0!/%2"66A!1(2(+-#&]E)ZM83H-(N9*;>3I['T&=*&8?"1L$%$;3I6]YGM7D -MA@WYC]Y1YC(KRNJ.,K9ISE/HX0L[5W!@N8&,/@KJA3[(SRV0;9*#>[IC8&(O\6E?P5CO+^4Q.EB -M@5_+,2,=*PW'V6\5:'`GU$42X'+ML^24T+V!U"[7`*WU5Q]A$I;.G*JG3N>M -M(\%C1N33':_HHW*]Y@\[G\VP2BSYTEQL1Z8P$U-TE)M#',SS=QF:;,%!X>FAS*\$LTE:N;-E6JH>UCSZ1^*'21$RTA7<71W\*'6M7UH/$P-#82?]^*:&%&S?D\9SP=W8 -M=U"D#*O8TJ'PI?QPA5Y[1`3&LES]V4]=\A6GM]#HQ+($<>?RFPOA_\/#^3H) -M9M3;PAY%/JU7%9Y??]05JHLVQ:NH:N_*K(KT^-\AHXKO`8\.G#76!Y?X:87E -MA&>X_XI=4RLM_#NXEY+K_W!;ZRW]"9D4GN7+!"*$"@E$<G,@,C`8B[OV4TA+G:`EC40T>@O"IY@;Y\2/JDD=V1M![(CNP(_,E2-0U^CX,9BJE=-CP^H-4\+4& -MD]^J`VAH[`_"EO\Y>#/O3GZ<`Z:6=C5[_!MCXBCD:8T=_894T$+.WU/1Y`8*W?RV7BIE:8CE&#G* -MKAR=I-M!\(2SH1`)U-_43!QP@2?TY36!`,FTEU"+G+UR\DX'0Z_/'SUZY'L\ -M<0WB\\&R.5`B`PTC#+4,\88"E0R2=P3'KS7/-:4F*.?&)JJ,1Z$$E`D\_G]: -MV`NESW?*QT"[,@OLIS&%#DX>O6[@;#9Z`ZT%+:?63G07XHA.O=(S8L_LA_@> -M\]+1T#1TE;]'*1$!&)GM0DS/_Q)^T>D@@/DD!>X+:`L4GV%@V((T>B"H_:6L -M;'9EB0&Z^8*/S-%;`K&EHFW1R0IJ1>OW_*'\4"G9B!S)($G=ZU?\%SA7*9M^EL80./SNR$4)E*K:0!TT,*59F65;WNQYN2Q.Z,L"-H?=(U3A>/=1R/Y!KMGFG!/%DY8V50XA+>J82,Z"D#JFCD'!XZBB48\M\!4L<-&XPOV&.MBD.".V.?&$P1P4SEWX]XVYY -M/DM9NEM8RJBP@JX`MF#PDC*4T$Z1ZZ%(V_XY#NX1+B8%\ZL>P(`W9GWOQR7: -M

    +8<3CD!K`P6["#A8H,+&2R38"$I3JG>X/>XN:(7?G\R3GA;7`/=)[X,@S -MH"RE$#HVN0_>N!D3^9IE^DGBJ9V+YJM@YIK6_%4=OUV8U!^^(JX8"/)T`5%& -MTDD1HCVQQU=MDJ7]J/"5:Z4Q!0D@T'X=<[2(L_>PSMH*)HHVI-L$?3^",O.& -MT)16KLM`NPY``"J9YM+&Y^@'!?(+IPXR-`84ADYF:`&7!(*#Q@Z]BBE@.1:A^OSG:9$M^[];\N@Q3(X+W -MLW3&;=A2([8<"3P>I95^!NIMJE^YJ5&S6(J`/T!2S-,' -MD6)@'GHT\L_2HV$04ZU\SOE')DN?ASL1NN^^7:V<[)Y\I*EYV;0WS5FYD3!6KRFYFE5CFI??*J -M-\ZJE,,<%,A9'!"O8)6/WUW=W@R<[=$$<1D1#G@4N:YEA(!4?2'_\H4)K'I` -MKQX_T=8OD1V$QU'F.652T;$^E!V!\%GRF>6J@J%#FTW+I/CY_;U,E7%R2F"W:/F]OY -MT`W/7T#4Z=_;LS/5@2B`\A(2,WZSA?974DF3$<^RA?!ACA!^T/=BR4X+!8F3 -M^V075'/DF0UX9\E0VYNLUQJ.-$%SA9?S -M?8%ZQ#'_7KP%^D[YB#`YBS9'R-1]I1"2N1X`F!NO\Y -MU2FW]K[:,QOI# -M>G6&B3`V%ZV1>]#E':8;?F6OG8V^TQV;15_5-.W1-`CK,=C))^_Q_AF]F.H1 -MSAN"WK^*@1VTQ-&^[`74F:5-]?1;2U:NB`W][#)$@S:G:#QRQ9<)?V;4ZD7! -M-M(9_<.&X+E3&KHS/ZT,"@J!4[HEGW.#\NPS=&7V&Z>>=?0"-TW"#E7/V3CW -M_*1@*VI;B@^?21EF6?.^)_UN@CL82I]HIT<;:R<>@2+;+#RMMY6I*/U]FZGQ -MINO=(L/3*#_E5U3,F\8F_^)ZI`^%#0TR`*7(=M'GAH1Z&W%%SMK%$S(`QE,* -M^6?.6MVVEA^H`Y>:`Z^<*,$Q<"02QX)QTZ;O9%YPH;K('*2`L;>F?*ZC0C^Z=G4^9(Z)%V9Q"G7_SY -M3!5I`B]/7H@7U]O`LQK!E,?3E$805$)KX47&Q-WX3RB7XV?S87X*S5;_:NQM -M5*7B3"56.2*M9KX!S[ZZR'YP-%++:"-V8:N'\Y%8HAP+$#WA*[C(+H9/)APU -M4E2Z:^Y:R%Z^]Z3`7?QMK@75!*C8YQ^2P+0'?Q"%Y#R%#PY?T$G""_TAOMOQHP89`J)7F\@W+<_BQ/#K!1_L -MAG]AD:E2F-"8]9EGWWO2_;$9R'?7$LL^Y]2H60AX..N#3IS1:;`LGOI![!L;C&Y)[`!-[XN#[5[/KF@*1866&"ZCC\[ -M#$*J]$%)"`#2V0FJ(>E2E8+H%]-05@+:Q0^"T&".^`;FHY$`!9IT1 -M:&R$ENRQ2$>1%A#&*R\466G@[JE7IH$`0$QBN#^#<^>3*/4@&>V59O$BH3JP -MKT62;#2"-^$8UR_#`H_[QL4]`XF&>SR3?@@3BX<*_JGC<'%5I0!UKZF7<7PSKFV!,]9X0=>Q\YS"+>G+V;#>"-"%-) -M1:#D=1.TV56\L3$1T/BORY6(_1U4=%8([W3PHIR[N'6+5L.G:NJ`W=78>FS+ -MG)>MXH:?N@U`&MJQ/P!F)D8/IFOA`*`51"H5&SFB:@@E2%,G)!O<[(BW%`Z+ -MFD5DG@I*@0]`X%3[Q1SH?1"=E.^ICW38DTXRZ7,1T=&6/("@U*2!7J)J.,00 -MT&7*=+9DO<0Z3W$.49(DMD':OZV[$'2VB+GR@7\@71JU(9?8F*!<3)&)*)@) -M8"[%UCD/\7O>/4EKE,440IR!+_!)AH")KL8J\Y1[0_LR4`I@JMCEH'M%T)8'[3: -M.7`6S#1:?%1#*>54`%8Z2P4#]S%B&_V61"Y,)("&PB4(`.?[C%?-J(?!-P_V -MKA:8H"G!Q2H].,.F'`T0J5+ZRVZ85AWI*N1B`8XOP7B<'#.;CJ*`G$9U%=O3/OVUF-OYYO3*G0K<[Y"%JX -M!X'#3S>P91<8Y-M-Z(0"Q_5-057,XS7*28Y')2*J7JJ_YD_SM7L@9-%NE)FN -M69TZ[;P-E8#\Y4AARJI`$6'](`O\MU7WIY<+CZ"*D/S-9[.=><+5K5G@WN"` -MB8:KHE*C_Q;\H_)G++W<[U"$K08NWP\U=SCFS"-;X;)SD4^*G#,CA('):_*S -M3*`"[MN"U\78A]Y^<=^7K^$FRTG\'>_SJCL9T -M$M"4ZUHJ/0EA^[PFK7Q;A(]-XN"OH#6$UD_>SG[@H><$6=?N#&-( -M8U!+]F`_72)=<[]`.?T[V@.OXQSLP$L<;_U]<"S%67%`?#N/XP24IE*&:FY/ -M/]><-A.`]LU1CP7C['B^B/\F5@IV24JC-_9TC0V_8E&&P13B^PZ`,.60P+_0 -MYN4)5L%`9^^!G[/#2>670#$FI9ZWD$^H[Q4T5X8!>3*5O-JJJ-@U7'!G(I[[ -M1".^J"/]&L'`?EZ/V4Y=41%=ZW]WF@%YSJW-2(I?"GK[)$+7C@I[D?FE2XJV -M#'61D;M2X2V.KG4IM.HTA(%3TZE:I-U)?SC>R.CBE3.!;1CDHOWK-,3R+('J -M;Q9TK_=H>)E9'=DFIO'7<4DPL-C"JG2$'P$^SO*'",7=;Z4M--IOR+8L77 -MKFY%V);CG'\H4(:WG65D!7T1\L&YJ[;J\Z!!]!>_8L@4\_+%1F)!]--)`88$ -M?&?TR&;0;@%<8[JA=KB)Z^:U5^;UT#O:.WTN^*GWC)M);IF@=[&ANVG)0HN6 -MWI6)5XC5T#-U5/%BTU]+&LQ%-ZL#+31#NZ,W6^VLT+E"2XDPCM]2D?N.6=O3=E'0I3B+-)_8 -M8N2D[;@(>GVU8<>K^H:>-3)/469((HJ<;6CJ=KK2X!'!\58]OVRT\[1DV%U] -M]+;#PU7;O9`@&L;N0[U2Y@W2A-BOF`(W&&K0H,S2"5<>AR;@*^<,IOOFQ!U'L7^$Z\_D.?L;QY3J$>,W -MN$Q\]NFT?*;NZG_M#+:\_QZ[S7@V;?[0&J6__G*)]4W)`\_0^XZ/R3:#K@K6 -M:\'O[:!@B5S11B6L!7`+;.HUC9J$NGM(-^_$H//_Q^>`S:\O3"18!4__4F7R -MH')EA?'O33NS:7&?NTW9`?JJ6LS?_X^IPYJ!Z-0=WP[O,1K_W1`?[$7WE-XB -M.2OL-@GHY[[M]81'*WAM.[/'#)RHM!IZQG]$)PR][O1P[*4$8GX.\RJC^Y!) -M@8_V`(]5%ZF?!0$W5GHLA@ED:VDN?@V[C,*97#R42-NTMYJN?T'&^9*DHBGS -MW7<>Q=B%,(O&;%V222=;"N<4?;@TEI_N7=;L5%TK7H#G%&V$0W![+EJ#/];- -MJ5_:YB?0ER`ESRD3-"*;?]I8P?4?,0/%B;.-+Q*NFZZJ,3HU)%7["@!H"059 -MC#IY""-+"[C-/08(4I>EA*`;@(<$$AKE?.DQ,&/UQ0/K.V5HX5`-"?VMV*WQ -MP$G>?H1+KU,LQ3-+`GS.=>!$H2PGKS.OOBUK-<9'X/"]'FR$S]Q4S@]C"MUX -M84HP;6F6I$9PY<5N.A]:,3AT2Z:7X!.LW"SGLX&1WZ^6:U5`^%VJ*"HJ)2Q> -MR<@`'/+UQN+QY`D;S.@[Q97M"YI^`V2LX019:A-4J-C<8;Q+2=O_VI+4_CYU -M$P$T]ASI5Z2NP1\(W4NS*/O8Q1Y6/EUN*]U($#<#']T?-7OZBK:C5*8$#\.\ -M`.?4B6B?0H.VGOEB?`0L$[CWO0RV;PQG[]YO4([OS^KUC!*VS;,:7,B@%/B- -ML,D]E.)F'Q)BX=J>QGX66+-A([-<4XT!"502XQSFA0'$.ZXX!39$L*F)I?UU_TX"L.M-<1SPH)CSO_O -MA8MW[+D&\>VQP,&#GUYN7_]:`O*R:X7CX8Z!!BVU2QBP<531RE'BN,(?(.K$ -M_/1ZJ6?\ZWC_%H$EZBK^[><0D/]$7S^D?T.:$(4@*$_V -MZ(`````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````8``````````````````*$OPP`Q?VO4_^?______________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_______________^@$?\B__K'_I_________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_________________________________________________________Z!' -M_(O_ZQ_Z?___________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________________________________^@3`'1%0R-%\6=F]S/A7.S -M5W8"T;9`[O=G2*&IP\3W2`(833>H2:8/`,[&-M/&Y!GWK4@ -M,-D75WT2#SF#E*Z5VOR5^KBL`````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````````````````````````````````````````>K] -M7T\[_GZN?T/^/I_GT/4O.Q?SYW0Y_K]^YZGQ].4NQT.+`?0]2.AT80FY^38M -MC-UH&0]R&?>\/3Z/1^X4ZT^!N4Z4:9*:-$CN+!,AN>Z5('3INPWS_NJT>I`Q -MEA^_#-(OO7'F?`N31Z78C35VD7F4.&08ONMK'Z/IW^>?SOHYT6)%!7H['=ZO6]0\WN9L] -M'/S_R?R[&QY8,@B&!L_=C>&?P",_X=^*>'IUO9+ -M!I_[\_Z8<@.GXJ4\>CJ)&GB\`A!8TU=.$"I:?N=I]G]/<]'-T^M!=`D`XCE8 -M!JN7'E&K`DR"8\?V]-7J,5K7UQ5'<+]FEU.;$!Z4&1SM88*"?3W?+[\X)U>A -MH^#]#>$#56&'M?;J>.KMZ57@N-):N7[XVZ;1QQ;]1WA815)8\@RDMF"/+!(/T>IU? -MWK4OKS=:NG&%]=]*GRD($O%=%K]D%*E2C([A*)0WS=*OR3)?UZJ?1?%ZO+K] -MD&B@AY_W88M'73TMN!`>QOM7_-,4)_7>&W]L&3[?T^O_CYNE>^5_+W/_:R>8 -M&Z.WI9_@C:M]"Y\/W4G'3^Z+?@@J68M.)BZ/`ETX[^-^Z"[SJSX,)F&O/0HZ -M0PV66N,;O7>B\5ZX_>#AUFU*WVI\?&E]W:O[6[?0GQJ>MOWGAI^V)\"68D>& -M2/QE?L_#D"*?D5ZV<\L]1++_QO/P@DUZM6?[Q$%DXZ$[R\N0FZ([,@15!+0L -M!=9%K?M7= -MA:YU^7TJN7R`O'VY%71U(S)-WO;4&+1*YXM.65%X90P;)CC4=H$29N95RL -MRS#O),+>/5R.$9X*^/#N=GV$-TE:7,^."D3YWR48+\6.9(7^'M%":>`)GZ4R -M:N*>"^03M8ZJ74[FGT3>#9D960OE@UX%O&6._ZNJYLCB!,W-B\[)W7['!:PB -M\'XY%V/XRP=KA./R6^X<`T;BS9D,V"+I;FS-Y?XJ$K73X^QY*R2."*'P;UJO -M7E$H&N\X@/C%[1L5_;U7SR]WCO/9):4Y?(EI+>S$%V\]''EIWE6,$>6(O@+3 -ME[G#\?");LM@E?-3?CP*;D*S(U:ON4N?E<%T8)JF54U2VJU7FD,O@Z>QJR-2 -MZ]$'[.JA1.GM]KK]*3WMIN@Q8]9=O^N=OZ0OF$'83HEE&QW&8=Q9SC&7(HZ! -MT\56]-ARZ0CWLE=RG0:U[2V)E.'_K,KXFGKD,JPH2W)[CP\?_D'<+S8C_%+] -MEF32B&FU2Y,@:1B;SG3MZD%#;'BC"9%TM*_796%NG31&MW62'&8VV7G2&W*2 -M8_"I^'X>SX96^#80^^+?/@?3A_FU&%BKB"A6'M_R+O`W;3UFK8'X@2EPRF"B -MB.C*H#7`0[(C!G>Y?E@TZ^!XL9IZ9E*Z5Q"L),WOXAO=#HS/?P^GS03$?ROO -MBVREKR,\I>K(/.)^J/,R(!][,]7T6A38[L;5*M -MPVE56+MFK`W=K>U(0(/$!VRF)'4[YX]$*QA:#)'L^(WZY)E"Q)1K^B:IO3ZK -MA@.6L6=`"_YLZ(0Y&3%,0_)L67=S;-O4#B,0'6 -M)R[=^,ZP/SWX0 -M@&.8'L81\%H:KS8?+YM;=WC9+O^/@B!''YT.F5OPU\[;]SX+9M#%'>I]%&&W -MG1`U:.-"-[8';;(*FK?I\/LS.-T9XCHO61;2M@$\`6CG'QY4.\P!GUA3?ITK0 -MCW<&SL8L,37TB/+XZ90SU^_0EB>ZOK]_1MDA*F4]:`/,ZQR;5C2@1O+7Q/$52F4OGN\/,_'+"G,R[7/2I -ML$FBRTX>+,"R`D5>')8'I&,]:7?]56WD.)^0#G"0U,68W%CE(W]/6PQ0MZ). -MEB[;?2AL.OC$%1A/+!#J/''Z]?K%@_&YC/\*V^;9#_'SSHD]N\V0$ -MIHKP^J$Y6AY=(?^EEA[BZV[/+6@$A"3V*>`XXEYGQI+%"%?@DKWC,5,9XRBG -M(DCB3:DC7,O:X1##E0=;8G*N,KDE4="68,2VHU`0SLDRPH(H$Y%RN%;TG->M -M7CEJU'K(37^^OJ7O,S+C%JL8X<2NN"?]\NON0;:O0Y^=/?!#'GEP9VO@VX(# -MO7]M?X]1HA445@;>0V`BP8$E=-_:ZTAPQIY[9A\I2Q_=L9@>&,5(2KFQQ\4* -M*J.*B+AW*?*`5[E.3JD;5XL%UE<[5R+HJ*^O*J4MBU*7)5S4_#J\_&(UO -MF-HZ@43FIH#,4-FD4T6"!9<O"/P;L9Y0\$;5>\< -M;Q]KP2?\5:G'1*;2JR2L'T?#/L4Z- -MGC21?PUWK.CGG+[7ZT8.C)'8_7G=L6D8=%L9<$O#1RM>'TQU#I3K..2U.S!< -MG1N#^&'R6-J&&N&RG5WZN95X/S(V[ -M2D03%@"S:CD[T],"*J\LOZQ]K+%H3[(9Y<^Z0#>U9D`\NU,NSZ?:N?X/3?QI*:J(L6>($A+QV[!$AQ8)46R\6"NEJ5\U?;TP3K0" -MU=5=I'H=;4U\[\8:5_?#VZO-2-P(!N,YCV/$&*U=*H256[0JSR89H)LY4XPT -M5TM\KS63+<@_!J;63WE0P!Z//K2TON'^XDKUL3+KA -MDX)KB4#CP3?2";-\^G*COB>2.&;FO5]JT=/^7\KM#RYKM7V_K5^E%>[Z/*X. -MTR*_CYZ_0DJ@8/1(I2Q7S@SD>/^WD&=5=70Y2B]C4!5^7+IL)S&C;)5@>\6# -M5ET-3EI4?=W.`GG8I@F2(!!$:V,5]4?O:'3\5?+%^M66W]%&>O!"[MZMB$/D -MRR?VZ4"2L?S$[1D#@=M95,6MKTC\C&%[XM+Y[N">&]*BY9?3`;8O;M>-B?KQDWU&&LKY -MO*7BN&Z)?.1LJ9O&\SL.%4K;C4F@!9NMF:=/8UM.OVN_[WZR2-K._^\9OGE/ -M8Z4/D)G&82NF::OD)F;4KU#B?LB_ON7)G*2`48/P@BRROKP^*$_2R0G^YH=[ -ML9>R6.]N[.33"H=?,_CT.?FQ98>3V_Y09`[MO>)F+Y9DU7KK_H\=2!=E-_'L[\&W'RYVML>6W -M2B5XVTKCM8$=QWDW7T)C=H/2`M>F>1Z.EFT89XYM6]Y`.74[6+UO9V-#+L2* -MRG?O$G&H]`_8.C5?AT",*;PS'GFM70XN>WV4Q427^(`*\/X#CB^ -M$(`_Z;QM?B78W;%ULSQ]SP7'831UC7'T-)1'M@\&T\A :U"^,-";S5OB:6 -MG$,M^1P8+(5[>J-K6.5*L'$0+)C=0HM;#!4F--U/NZDV&E#R0UWL[7NQTR?( -MK-5,,P+(U-G9HX8/FZ7$?96E_ZGDBWBI,:/#Y=^S;#LY:>^CB6&-NY)Y7X[_!HZ6Z,D&]`WT!%WRJ<9];OD]9 -MY>24+=]B3T1H[A.%^F.1/,DM#4>!\9]0K>"FYBN[!+*PDPZ'TMGH"-NLKU?X -MK&8!'XW9[RE.P5>/,E6Z?%N:LC`<1CX,4F<@B!KO78!YO$IQ`''Q7JO"IX\? -MBBR#]:TMSQ5EEG7D[+^G+:=BG2QFL>/BO -M-QZJZ$.H`J_PPEC.-JXBK7]T=G#'\]ON_/CN":U"TF8LK:^LVXWN3E`F6;_# -MF@\C#/D]9LWKT#%HA\3BFCW4MIP#\!5<]$0Y$=*]?;JE'.^>7#5O5WUX9)44 -M:))UM76AT?_M55^=35MH -M8SBP1JTK'D6Y=#^?WQI>=*9C8FR=6JV)]+T%__'6]A[DT)F]% -MM.9/8%$580S)=?9\16F`[F7>"]22&A^BE$`:%]89YK8LMX4\?*>YWLG)25RK -M*.K)901`V]&IJZOJ1J_6GW!LR>I^"`[07J:]@%V?5BQJ?SP/;WQ=6$)VG)G> -M,CD;"*2]BO';UTABY)#56A_?JZ>CVO<+0[/9T^Y#1S1\ -M'1BO@_7G[F+:SX]=K^LYM7V:F+!8@8VWCQE9ON?5'U;4?[#8J%5Z%VJ6=4&'1J4HO;()4E6Z9]B#F&EOGA"Y]OY\)@Z$KQP\]L>4<',^O+3P:'OZ[N0-$59`T+&V[RU6]6;[V-V/2 -M\DOQI9RJV8A[VJ&3N-FHO1'WX^C$`6&2L/DNQK)5_WUI\QDNC?X],*1X0H=% -MT;6[0R[0Y+&X>-&5*QYNCCJ;63LCPVSZ%<=8_&<$7YI5O82X$^Z<##T4I_XS;/-5[M4JN)*<.,PUX=<@21*+8?\@!8`NJL$\VJOXQXJ9_D -M3.WKH>4UTR@[R57^/8HS5-09>'[^!EC_/B&H.[#.Q3A=.O\W-$D=K*48D@J19KZ-UX@W5I(05CF6[ -M[(CXM-/'Q^C,.*&X3^7'/##8'_F>E+Z+.!7!K[5XEI)C,E`)2K9=PC^3W!*> -M/=^JWKV#J"(QKCPP6:'6E9)Y.J(:%'W-59W0K-G+@+-9/@"A""&TDQUZZ*Z!(7K==%W;K&"$J@J -MALS;75>P>"E5\-;N4E/M -M0A%P9LKU*,B)FLB7(LC%+GP-Z^OAE/&,`'46Y6\TGV,SB'PST\;25YCUTI@) -M"8'KR_&OC2FE?A7ZGV6/IWY1];IKK:><9*`-O+^*CC4T2?\3C -M_M'7BFGLD;Y)8-WV+?F70"PKR_K2?DS;!F2K#Q)U^)[$X!XV5*%UYZ=7A]'N -MJRJW(KWG&Y:)'M=LW^%%XYMC7J/SQ2BQFE=9%4H:KU#/U&Z)XW&/F1DY^*&? -MKF)^:[Y;RQ8402:`0.G!SK912WR+3;6S1-%I+>%40ZT<0YQAHQO;* -M\@_]:\Z&\O@X6JRH!7L'0]=%F\#4G+=W3O;]?@ST(*H"J*!>=9,1I"NM^<5$ -M,?M3##_F0@61;>:`LF\VDL')];&<]T56:4]2!OY.9(`/*6V>1@]'8#"*GU77 -M;#NK:^GSZ[&-$_(WYR<(5I51ZVR&>0E=MYM$UWTOV5=5'&,CR -MBKOW;AR"NES,-/?Z>M505*><)/.8)UL,A0CY:\.+IC`GC%8_TJ5_HG*`HW#K&]2WB/L(8";`73ZE8Y;1D(J@(T,=])2H!$P7 -M0R:0/B15*(]<*@J1D[43+>O$MZ$A&')!G0?"`I/RWJEW*L#<#D!I$\V:\",/ -M[J!XYT&0)B+9L6#"$>!0#V` -M*;I#]B(J/TC[I-H4P\V$J3&_7VBB^Z,]'9,8PUO5QM2^Y5?P -M1\:_.IO%T4N"#U2-1H8Z]$6"3B%^+CQZ7CM4]>!+A*F1!\CK@_PCBB3,5V$W -MFK@M_W+2%)';;*J7&Y01`W``3(_X7]KVPYX0A2`H3^W1```````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````%`2_#`#%_:]3_Y________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M__________________________________________________________Z` -M1_R+_^L?^G__________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M________________________________________H$S/],17/Z59'_P````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M````````(``````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````````'!,`9$53(T7Q5F;[,_%5R8N9`6#;(',YDX1 -M0Q.'4\P@"&$PSB$FF#V!OD8VT]MR#/_42!R0!DOIUT[>VQ[89(N+GPD'O6]7 -M5U=W5U===[_)5Z$7E>5T:I72NUXE?QTE8``````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````````````````````````````!ZOS?3SO^?JY_0_ -MX^G^?0]2\[%_/G=#G^OW[GJ?'TY2['0XL!]#U(Z'1A";GY-BV,W6@9#W(9][ -MP]/H]'[A3K3X&Y3I1IDIHT2.XL$R&Y[I4@=.F[#?/^ZK1ZD#&6'[\,TB^]<> -M9\"Y-'I=B--7:1>90X9!B^ZVMRLSBZ9H3>*UL(X9WO3T;88(NBWJ;FWYMCU: -M_`%SO[.K)IJ?V@]X?H^G?YY_.^CG18D4%>CL=WJ];U#S>YFST<_/_)_+L;'E -M@R"(8&S]S/W[H'VO3[-G[XE?]16`H7C7$6F?`7.ERJ_\NC3.&L[XU<8.@9'& -ML'1%!-IUL?&T8$DS.,.S_X.*MFY1YV-X9_`(S_AWXIX>G6]DL&G_OS_IAR`Z -M?BI3QZ.HD:>+P"$%C35TX0*EI^YVGV?T]ST4:L"3( -M)CQ_;TU>HQ6M?7%4=POV:74YL0'I09'.UA@H)]/=\OOS@G5Z&CX/T-X0-588 -M>U]NIXZNWI5>"XTEJY?OC;IM''%S(ZHSSRMS1_9,TNG9F9*F04#YUGBD(U/- -M>&+/_<==8H-%>N,41#3C!FNWYH_9"0.>;IUU'VT]?W7S>YV]+1\&G+.*[KK$ -M#3UQL@WJ0$J6U([]?U5-)YOU'>%A%4ECR#*2V8(\L$@_1ZG5_>M2^O-UJZ<8 -M7UWTJ?*0@2\5T6OV04J5*,CN$HE#?-TJ_),E_7JI]%\7J\NOV0:*"'G_=ABT -M==/2VX$![&^U?\TQ0G]=X;?VP9/M_3Z_^/FZ5[Y7\O<_]K)Y@;H[>EG^"-JW -MT+GP_=2<=/[HM^""I9BTXF+H\"73COXW[H+O.K/@PF8:\]"CI##99:XQN]=Z -M+Q7KC]X.'6;4K?:GQ\:7W=J_M;M]"?&IZV_>>&G[8GP)9B1X9(_&5^S\.0(I -M^17K9SRSU$LO_&\_""37JU9_O$063CH3O+RY";HCLR!%4$M"P%R2C.-H4T+? -MC(5%67(4L1#KH$O:A2=CZ)I=,W#/<=T<&R;OD^+GR7]R>;S\[^F=SHQ[7Y?2JY -M?("\?;D5='4C,DW>]M08M$KGBTY947AE#!LF.-1V@1)FYE7*S+,.\DPMX]7( -MX1G@KX\.YV?80W25IT4)IX`F?I3)JXIX+Y!.UCJ -MI=3N:?1-X-R+CMH^S0QQ>.!3VST>W\OZO1/ARI:U0G<^O;3?@AFLT3F^I]O8 -MV(QKO1N<6+Q&9-K=QA#.ND9M!7LK*_-MU6##8]^H@N)@J;S3BOVQ,LPCG>58 -M2+:*V35;YCEAI24B(J0M\Y2JU<8P+_FJF;]*S-YF1E9"^6#7@6\98[_JZKFR.($S42@:[SB`^, -M7M&Q7]O5?/+W>.\]DEI3E\B6DM[,07;ST<>6G>58P1Y8B^`M.7N:0R^#I[&K(U+KT0?LZJ%$Z> -MWVNOTI/>VFZ#%CUEV_ZYV_I"^80=A.B64;'<9AW%G.,9R5W*=!K7M+8F4X?^LROB:>N0RK"A+*,)D72TK]=E86Z=-$:W=9(<9C;9>=(;W_(N\#=M/6:M@?B!*7#*8**(Z,J@-_B&]T.C,]_#Z?-!,1_*^^+;*6O(SREZL -M@\XGZH\S(@'WLQS%ONS2;9EI`:]'J]Q($R)P>2I_(_!G;?HH[593:IE9]G0N -M7S-](4?7E>^>4@I>78H-U)&4K?"-R8TN"?![U?1:%-CNQM4JW#:558NV:L#= -MVM[4A`@\0';*8D=3OGCT0K&%H,D>SXC?KDF4+$E&OZ)JF]/JN&`Y9RTDR+%8 -M]^*4''I8+H\7)5ZQ9T`+_FSHA#D9,4Q#\FQ9=W-LV]0.(Q`=9P_H\#:E^/YF -M=;M#E_.?M8*%`9].H%QA'P6A -MJO-A\OFUMW>-DN_X^"($=$#5HXT(WM@ -M=ML@J:M^GP]S@I5F3)6[EI$<8?3D9#S8$P;-.DD>1K$W7P;>-/K4K#]U>BD`I:`94LW0A136V-35Q0\D*D4T-.9G4K\]6 -MS1LQRXX;IZS,XW1GB.B]9%M*V`3P!:.[P\S\D8SUI=_U5;>0XGY`.<)#4Q9C<6.4C?T];#%"WHDZ6+MM]*&PZ^, -M05&$\L$.H\(J=%/63*%6059 -MI5S;NN4@+*&;)3H3XYQ[U^L6#\;F,_PK;YMD/\?/.B3V[S9`2FBO#ZH3E:'E -MTA_Z66'N+K;L\M:`2$)/8IX#CB7F?&DL4(5^"2O>,Q4QGC**.6K4>LA-?[ -MZ^I>\S,N,6JQCAQ*ZX)_WRZ^Y!MJ]#GYT]\$,>>7!G:^#;@@.]?VU_CU&B%1 -M16!MY#8"+!@25TW]KK2'#&GGMF'RE+']VQF!X8Q4A*N;''Q0HJHXJ(N'9O^=R)+AZ\(_!NQGE#P1M5[QQO'VO!)_Q5IR -M'1JT;BWYEV@ON#"YHZ%6D3QO2/EJIZ<=$IM*K)*P?1\,^Q3HV>-)%_#7>LZ. -M>=VQ:1AT6QEP2\-'*UX?3'4.E.LXY+4[,%R=&X/X8?)8VH -M8:YR2\>?]/](B1SKD^/_1!`&*R=_?9X;*=7?JYE7@_,C;M*1!,6`+-J.3 -MO3TP(JKRR_K'VLL6A/LAGES[I`-[5F0#R[5R,D'<'5V7FO&[/DNM65XR[/I] -MJY_@]-_&DIJHBQ9X@2$O';L$2'%@E1;+Q8*Z6I7S5]O3!.M`+5U5VD>AUM37 -MSOQAI7]\/;J\U(W`@&XSF/8\08K5TJA)5;M"K/)AF@FSE3C#172WRO-9P%3( -M%W9*KVMY,MR#\&IM9/>5#`'H\^M+2^X?[B2O6Q,MS7E0A;A2;>E]NW%CUQV. -M7+EER,>/:W=G;V*-1B.2,#MO`)O[>S@U]+2[-66W]:PCNAZN&3@FN)0./!-] -M()LWSZ09U5U=#E*+V-0%7Y=BF"9(@$$1K8Q7U1^]H=/Q5\L7ZU9;?T49Z\$+NWJV(0^3+)_;I0)*Q_, -M3M&0.!VUE4Q:VO2/R,87OBTOGNX)X;TJ+EE],!MB]NUR,[$M7-\<\+Y#,;N]_M1K)GI77QKEBYM>4MI;7+,J#B?E7"&?@C-PLV15)1(A)GD)$8@P.MK)YXV)^O&3?48:ROF\I>*X;HE\Y& -MRIF\;S.PX52MN-2:`%FZV9IT]C6TZ_:[_O?K)(VL[_[QF^>4]CI0^0F<9A*Z -M9IJ^0F9M2O4.)^R+^^YNO^CQU(%V4W]RLQE88IE2.BPQ -MAKV,CR\8MSJNU7777A5*'O2[F\\/>IT9MX>SOP;3=?0F-V@]("UZ9Y'HZ6;1AGCFU;WD`Y=3M8O6]G8T,NQ(K*=^\2<:CT#] -M@Z-5^'0(PIO#,>>:U=#BY[?93%1)?X@`KQRVC3SHS%X_@..+X0@#_IO&U^)= -MC=L76S/'W/!<=A-'6-V#P;3R$8-EK4+XPT)O-6^)I:<0RWY'!@LA7 -MMZHVM8Y4JP<1`LF-U"BUL,%28TW4^[J38:4/)#7>SM>['3)\BLU4PS`LC4V= -MFCA@^;I<1]E:7_J>2+>*DQH\/EW[-S9EQ.TXS="/O>]BNW50:/>O+OQ.-JE0 -M`3%YL.SEI[Z.)88V[DGE?CO\&CI;HR0;T#?0$7?*IQGUN^3UGEY)0MWV)/1& -MCN$X7Z8Y$\R2T-1X'QGU"MX*;F*[L$LK"3#H?2V>@(VZRO5_BL9@$?C=GO*4 -M[!5X\R5;I\6YJR,!Q&/@Q29R"(&N]=@'F\2G$`J\*GCQ^*+(/UK2W/%6 -M65P'F=(FR7*_.?DKCM)DEZ=>3LOZY.4"99O\.:#R,,^3UFS> -MO0,6B'Q.*:/=2VG`/P%5ST1#D1TKU]NJ4<[YY<-6]7?7ADE11HDG6U=:'1_^ -MUS+C>IC^`2INA63>GEDM8_P[N/1; -MET/Y_?&EYTIF-B;)U:K8GTO05S`3*R`L,0%2$9*[SBV? -M!*ZO]N9R/A+ZMG>$V;_'R[?U7HS-EWC#[[MO:ULV2U+.DLLTV""@#FZ,$'.G -M=,/;L0_9^'0IV%K/Y0/%:^#FQRKI;\V#@V][_\=;V'N30F;T6TYD]@415A#, -MEU]GQ%:8#N9=X+U)(:'Z*40!H7UAGFMBRWA3Q\I[G>RIKV`79]6+&I_/`]O?%U80G:GB,BX@'\MT1.ND3\+D9RKS%4LC94+WR+O -M#I5%G-L=8]R*!I#5.V7#`,HCNP2_"#-G$GE4B69\7+GGUVOYNE_6D(71'WCB -M97ETLMT2"Y6BK*)9>L3>+.]%KG4)T^(G\+`A$[K'-B27U"2YM;=F1'6BV4KA -MCWJ=LQ8I`^%[V*\=O72&+DD-5:']^KIZ/:]PM#L]G3[D-'-'P=&*^#]>?N8M -MK/CUVOZSFU?9J8L%B!C9S?Y<:8[6A]GMO3T.GV>C]G;[?9^OM]JK?:ZV1LB/&5F^Y -M]4?5M1_L-BH57H7:I9U08=&I2B]L@E25;IGV(.8:6^>$+ES#DK\KE=G'6IM? -M8LV;4$.OB5MK?5`!1L]O:0T$GNQTV3].>,)]:3S@E6U9KDKAPNN5+9.2::]/ -MN:/;N:;5S,+0T)\0%=/2[&AW>KU*!SK=:J,@(2N"PW%9W!KB\T>WT[3%?)+Y -M[V_GPF#H2O%R8)_`P9'B__T&"X-I_\KV0>A("_D/:L>!3(?BJ2Y"RVW7$:-= -M2G^'Z",NLI#;QDHK&K(;<;_]?;H%)^9E2*BV.C;($ZV->]'M7_KNY`T15D#0L;;O+5;U9OO8W8]+R2_&EG*K9B' -MO:H9.XV:B]$??CZ,0!89*P^2[&LE7_?6GS&2Z-_CTPI'A"AT71M;M#+M#DL; -MAXT94K'FZ..IMS?4VM*[>-&8[B#UHSF.2)!7WRJLA$AJR#L;>/NJS\*9\JXP -M4:2'U)]W2EC2#[BP9%1GY)R*=CJ]/^^G"CHO5AO,[W4Z1*BZ?=]P.]V]/V3[.[H>Q='K>Z?5NF;D>W\K)STYV/HOPQOZDH@[MU;7`DDVF=L1+MBC0[>WK2J%+` -M!PK6QT>.I+5Z?'8Y5R\-6]78Y]K9`\U^8BL-RIT=/P)W=MUW`<`+7@7.J_M% -M?&GL*GT`9Y9.R/#;/H5QUC\9P1?FE6]A+@3[IP,/12G_AS*3.>)L-E>+_%NQ -M=[-L\U7NU2JXDIPXS#7AUR!)$HMA_R`%@"ZJP3S:J_C'BIG^1,[>NAY373*# -MO)5?X]BC-4U!EX?OX&6/\^(:@[L,[%.%TZ_QP]`!V<@\;EL@[&7&E -MD&AW(BSGW*'RLG2C+__M/40````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````?^TO(_HQ?VO4_^?__________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M___________^@$?\B__K'_I_____________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_____________________________________________________Z!'_(O_ -MZQ_Z?_______________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M__________________________________^@1_R+_^L?^G______________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M________________H$?\B__K'_I_________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_____________________________________________]"'A_UBY2R"4]W" -ML*RE:_OGG3#+\L@,>,PN7D[&4009/5G@?.;JM:BXCPHCK]VV[!W!8P -MYAI3ZHH(AMZ-VR@&&VJ'#SQX0QE)?R4N3VT'614`IIGL^R($79%MI#B-X4CY -M2<,-?%!I-[HQ#M]PYYZ?6SOAM+5LW -MF&<#GI93057E-9"T'5(%972#)X_X&MZ%%>,"#R0K[^%DUAQ_L=6WC_=;3^$B&IX@7 -M6#\FJ!/@DO,_:Q4&@$=1%+9L9'QX-`*25C]4+S1EM<'\+&/@+SZ!Z;8S%PZ; -M(==I$41B7WFK6VK3@'SRI+W`+B[X)G@4O0_W,7;CI_)#=I9$>48_/@*[!9_P6E;Z30VBMPXWC4A -MRUON:T2OHRGTI6-N1.9O4Q7!K2]V<9LB\ZOK`;O-+6./K\O;V>YL3U0;<@G] -MLA2,Q)]X^--?L#,";:,7QJQN4A;W5Z;,Q7 -M)^5/T,L?'O%IN1VBJHSYE"_F##3P-7AKO2*<+FA"Q7SX?[-K1*!"L]\N9+:. -M0,0/+O.NFOO8/98)R4T.=YUS'P05OYLC5UIA3#;.%]R3H86ZW$_$0R7#/%`, -MXN35/Z7_EIY(DISE:VN1+&?5:$\/OB?_.UY_;YHU]1>KOO^1>SO&=^G!C.=( -MELO]V=4)15`MSI")D`+9IQ_M4>U*+:4'_Z>[O6X((_Q"?<;ZJ5$<+9V6$EU40\:$&L%"BJB(8<0I[G_ -M!\`J./DJ`+W_1/'D9-O>\"'>)A+>%(A^RMG>^['D=3[P%6?=^<0A-E2XHAZ& -MM=M"/D&+NG;>+:_<_&(J-_X/$>`%(*^FHJEU.9*6OP.!?U:YX0_DSJ)4K>;9 -M<`K%R=FAF@5??,.T'?Q$9N9;%S:]GTXV!-OLL]NJ;\1'O+T/NS/BRH>?$*/D -M[P!,C_A?VNV'/"$*0%"?VZ(````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````````````````````````````````````H!+\,`, -M7]KU/_G_____________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_____________________________________H!'_(O_ZQ_Z?___________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M__________________^@1_R+_^L?^G______________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -MH$P!T14,C1?%G9O?$J_A%^K]7@Y2NE= -MK\E:7/38```````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````'J_/Z>=_S]7/Z'_'T_SZ'J7G8OY\[H<_U^_<]3 -MX^G*78Z'%@/H>I'0Z,(3<_)L6QFZT#(>Y#/O>'I]'H_<*=:?`W*=*-,E-&B1 -MW%@F0W/=*D#ITW8;Y_W5:/4@8RP_?AFD7WKCS/@7)H]+L1IJ[2+S*'#(,7W6 -MUN5F<73-";Q6MA'#.]Z>C;#!%T6]3K7X`N=_9U9--3^T'O#]'T[_// -MYWTH>;W,V>CGY_Y/Y=C8\L&01#`V?N9^_=`^UZ?9L_?$K -M_J*P%"\:XBTSX"YTN57_ET:9PUG?&KC!T#(XU@Z(H)M.MCXVC`DF9QAV?_!Q -M5LW*/.QO#/X!&?\._%/#TZWLE@T_]^?],.0'3\5*>/1U$C3Q>`0@L::NG"!4 -MM/W.T^S^GN>CFZ?6@N@2`<1RL`U7+CRC5@29!,>/[>FKU&*UKZXJCN%^S2ZG -M-B`]*#(YVL,%!/I[OE]^<$ZO0T?!^AO"!JK##VOMU/'5V]*KP7&DM7+]\;=- -MHXXN9'5&>>5N:/[)FET[,S)4R"@?.L\4A&IYKPQ9_[CKK%!HKUQBB(:<8,UV -M_-'[(2!SS=.NH^VGK^Z^;W.WI:/@TY9Q7==8@:>N-D&]2`E2VI'?K^JII/-^ -MH[PL(JDL>0926S!'E@D'Z/4ZO[UJ7UYNM73C"^N^E3Y2$"7BNBU^R"E2I1D= -MPE$H;YNE7Y)DOZ]5/HOB]7EU^R#100\_[L,6CKIZ6W`@/8WVK_FF*$_KO#;^ -MV#)]OZ?7_Q\W2O?*_E[G_M9/,#=';TL_P1M6^A<^'[J3CI_=%OP05+,6G$Q= -M'@2Z<=_&_=!=YU9\&$S#7GH4=(8;++7&-WKO1>*]6>HEE_XWGX02:]6K/ -M]XB"R<="=Y>7(3=$=F0(J@EH6`N249QM"FA;\9"HJRY"EB(==`E[4*3L?1-+ -MIFX9[CNC@V3=\GQ;DZ96QH>C%MN4HE9"R03,]B.#?5\%/.LBUOVKNPM[@^$)19E-9HX1W=F7.%0/S:+=WTNW -MQ[?%D&'W%BA>CT^2_N3S>?G?TSN=&/:_+Z57+Y`7C[V>CV_E_5Z)\.5+6J$[GU[:;\$,UFB(S)M;N,(9UTC- -MH*]E97YMNJP8;'OU$%Q,%3>:<5^V)EF$<[RK"1;16R:K?,=D[K]C@M81>#\<0'QB]HV*_MZKYY>[QWGLDM*>CCRT[RK&"/+$7P%IR]SA^/A$MV6P2OFIOQX%-R%9D:M7W*7/RN" -MZ,$U3*J:I;5:KS2&7P=/8U9&I=>B#]G50HG3V^UU^E)[VTW08L>LNW_7.W]( -M7S"#L)T2RC8[C,.XLYQC+D4=`Z>*K>FPY=(1[V2NY3H-:]I;$RG#_UF5\33U -MR&584);D]QX>/_R#N%YL1_BE^RS)I1#3:I4O5D'G$_5'F9$`^]F.8M]V:3;,M -M(#7H]7N)`F1.#R5/Y'X,[;]%':K*;5,K/LZ%R^9OI"CZ\KWSRD%+R[%!NI(R -ME;X1N3&EP3X/>KZ+0IL=V-JE6X;2JK%VS5@;NUO:D($'B`[93$CJ=\\>B%8P -MM!DCV?$;]4' -MS=++['9N4X&O$Y=N_&=8'Y[\(0#',#V,(^"T-5YL/E\VMN[QLEW_'P1`CC\Z -M'3*WX:^=M^Y\%LVABCO4^BC#;SH@:M'&A&]L#MMD%35OT^'N<%*LR9*W;`F#9ITDCR-8FZ^#;QI[C]X%!XD7Y#F]CJC'^^0,;#OR,[U:E8?NK -MT4@%+0#*EFZ$**:VQJ:N*'DA4BFAIS,ZE?GJV:-F.7'#=/69G&Z,\1T7K(MI -M6P">`+1SCX\J'>8`SZPIOTZ5H1[N#9V,6&)KZ1'E\=,H9Z_?H2Q/=7U^_HVR -M0E3*>M`'F=8Y-JQI0(WEN3^?%=([E;=GW/@>2I!>_FP<`^U''F?CEA3F9=KGI4V"319:M+O^JK;R'$_ -M(!SA(:F+,;BQRD;^GK88H6]$G2Q=MOI0V'7QB"HPGE@AU'CC].==>OD5NHF7 -MYD$TK.H`)PSKM<"9?\@G+5NJ#,ME=_'G!"YSD;<;AE$;_G@T,]N:6](`V=`F -MY?E-&*;K4-JT%2M\YU[BC:3Q%3HIZR90JR"K-*N;=URD!90S9*="?'./>OUB -MP?CW>;("4T5X?5"HT0J**P-O(;`18,"2NF_M=:0X8T\ -M]LP^4I8_NV,P/#&*D)5S8X^*%%5'%1%P[E/E`*]RG)U2-J\6"ZRN=JY%T5%? -M#!JWE5*6Q:E+DJYJ?AU>?C$:WS&T=0*)S4T!F*&S2*:+!`LN.<4D3H<7&1^; -MS-_SN1)"-JO>.-X^UX)/^*M.0Z-6C<6_,NT%]P87-'0JTB>- -MZ1\M5/3CHE-I59)6#Z/AGV*=&SQI(OX:[UG1SSE]K]:,'1DCL?KSNV+2,.BV -M,N"7AHY6O#Z8ZATIUG'):G9@N3HW!_##Y+&U##7.27CS_I_I$2.=F!%5>67]8^UEBT)]D,\N? -M=(!O:LR`>7:N1D@[@ZNR\UXW9\EUJRO&79]/M7/\'IOXTE-5$6+/$"0EX[=@ -MB0XL$J+9>+!72U*^:OMZ8)UH!:NJNTCT.MJ:^=^,-*_OA[=7FI&X$`W&UO)EN0?@U-K)[RH8`] -M'GUI:7W#_<25ZV)EN:\J$+<*3;TOMVXL>N.QRYQ1J,1R1@=M -MX!-_;V<&OI:79JRV_K6$=T/5PR<$UQ*!QX)OI!-F^?3E1WQ/)'#-S7J^U:.G -M_+^5VAYQJ`J_+ETV$YC1MDJP/>+!JRZ&IRTJ/N[G`3SL4P3)$`@B-;&*^J/WM#I -M^*OEB_6K+;^BC/7@A=V]6Q"'R99/[=*!)6/YB=HR!P.VLJF+6UZ1^1C"]\6E -M\]W!/#>E1!7CZ9V'"J5MQJ30`LW6S-. -MGL:VG7[7?][]9)&UG?_>,WSRGL=*'R$SC,)73--7R$S-J5ZAQ/V1?WW+DSE) -M`*,'X01997UX?%"?I9(3_W=G)IA4.OF?QZ'/S8LL/)[?\H,@= -MVWO$S%\LR:KUU_T>.I`NRF_N5F,K#%,J1T6&,->QD>7C%N=5VJZZZ\*I0]Z7 -M\@'+J=K%ZWL[&AEV)%93OWB3C4>@?L'1JOPZ!&%-X9CSS6KH<7/;[ -M*8J)+_$`%>.6T:>=&8O'\!QQ?"$`?]-XVOQ+L;MBZV9X^YX+CL)HZQKCZ&DH -MCVP>#:>0C!LM:A?&&A-YJWQ-+3B&6_(X,%D*]O5&UK'*E6#B(%DQNH46MA@J -M3&FZGW=2;#2AY(:[V=KW8Z9/D5FJF&8%D:FSLT<,'S=+B/LK2_]3R1;Q4F-' -MA\N_9N;,N)VG&;H1][WL5VZJ#1[UY=^)QM4J`"8O-AV@;Z`B[Y5.,^MWR>L\O)*%N^Q)Z(T=PG"_3'(GF26AJ/`^,^H5O! -M3/Q19!^M:6YXJRRN`\SI$V2Y7YS\E<=I,DO3K -MR=E_3EM.Q3I8S6/'Q.9N*P5/7FX]5="'4`5?X82QG&U<15K^Z.SAC^>WW?GQ -MW!-:A:3,65M?6;<;W)R@3+-_AS0>1AGR>LV;UZ!BT0^)Q31[J6TX!^`JN>B( -MOMU2CG?/+AJWJ[Z\,DJ*-$DZVKK0Z/_VN9<;U,?P"5-T*R;T\LEK'^' -M=Q[C_A1[%C_@LS>&O*J_.IJVT,9Q8(U:5CR+<6SG">\*[[L0?/T?<3SX)75_MS.1\)?5L[PFS?X^7;^ -MJ]&9LN\8??=M[6MFR6I9TEEFFP04`P]R:$S>BVG,GL"B*L(9DNOL^(K3`=S+O!>I)#0_12B` -M-"^L,\UL66\*>/E/<[V3DI*Y5E'5DLH(@;>C4U=7U(U?K3[@V9/4_!`=H+U- -M>P"[/JQ8U/YX'M[XNK"$[3DSO&1R-A%).5$7Q!_$Y';T\1D7$`_ENB)UTB?A -M8JED;D<+DAPAN&+4#[5-U]'SS*A>^1=X=*HLYMCK'N10-(:IVRX8!E$ -M=V"7X09LXD\JD2S/BY<\^NU_-TOZTA"Z(^\<3*\NEENB07*T591++UB;Q9WH -MM]3MF+%('PO>Q7CMZZ0QNU_6AT^ST?L[?;[/U]OM5;[73E4T^41=^;!/L1"OKHRR4H+K@4KZ2 -MSLKOW&WQC6#.^B-:[,5*;VR-D3E6/;QXRLWW/JCZMJ/]AL5"J]"[5+.J##HU -M*47MD$J2K=,^Q!S#2WSPA<$JVK-I0.=;K51D!"5P6&XK.X-<7FCV^G:8KY)?/>W\^$P="5XN3!/X&#(\7_^@ -MP7!M/_E>R#T)`7\A[5CP*9#\527(66VZXC1KJ4_P_01EUE(;>,E%8U9#;C?_ -MK[=`I/S,J146QT;9`G6QKWH]J[EYMXRF"G,N5VPDP/8>>V/*.#F?7EIX-#W] -M=W(&B*L@:%C;=Y:K>K-][&['I>27XTLY5;,0][5#)W&S47HC[\?1B`+#)6'R -M78UDJ_[ZT^8R71O\>F%(\(4.BZ-K=H9=HM&ZG3C^!8+G(M0@?))-OP^6W[._H]GJ:<*3)=&#H!T>U -MU_KR)473[ON!WNWI^R?9W=#V+H];W3ZMSF7P^*/_3?C&=BY+*B?%3TSG.Q]%^&-[D-JQ0HZ5P=N_D#W4E$'=NKER,[9$K4[.HLZL1A=T:G.8W,U* -M[\@+NI*PUQDSS:X$DFTSMB)=L4:';V]:50I8`.%:V.CQU):O3X['*N7AJWJ[ -M'/M;('FOS$5AN5.CI^!.[MNNX#@!:\"YU7]HKXT]A4^@#/+)V1X;9]"N.L?C -M."+\TJWL)<"?=.!AZ*4_\.929SQ-ALKQ?XMV+O9MGFJ]VJ57$E.'&8:\.N0) -M(E%L/^0`L`756">;57\8\5,_R)G;UT/*:Z90=Y*K_'L49JFH,O#]_`RQ_GQ# -M4'=AG8IPNG7^.'H`.SD'CDR````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````Y?C_Q[O\?H[OZGR_P[GIYZ^E_#YOX>G__ -M+:2Q1_Q*=6?_1I\;_^NGE>L.A>"$BG>H5PH<%D4*^S`T'!>&1:+)"4O#P*AC -M8[^7\IS&7!O>S72H0ZD0SA*YNYG\/'#I(BP[V:2*1Q0[GKT:+:V.]*WYZ-^F -M:7M!0R>&RG3CF5FDO72W4\LTIFB;]$X]2:^LW/),H3'Q\R^;/%>WS?'QRC>" -MJ+MHNHC0R%HR>:20#FF]Z96/AGJWGAY\87]Z$8?U^]P\DW9=,^YPZ;16UC9_ -M>-[P38>$-MB'GYHV;L%PO)NQM+S=S4,.1G2BB7GXK9:B]K\HU>X$H?BNB0B9 -MIM4MK)'#*-LS5<4F&V&C8@_5/8R=GSW42Z(]'@OTWU)$YE<>WX>/AX8_>7N[ -MDV.75X(W?R29IG!D_VC6TMD)-TR0;AOFDST9 -M.3!MH<66]EW789MP"BM<-^\'N.,&_$=2<#O)FJ^@?V/1G]5]2<#*7G-+\ZF\ -M`\4`S:DJ^\X/ES[^]J0=KZZF,;NU;S?Z5:HO,\1U][8-9R]OW;F6P8$M0]B2 -M71S@P^CLV[60$.@XU9"PQC._J$8,7"-:%IX]Q.S;+E%!&N7>AH:<$5RNK?WZ -M/LR.0(5.I4@7\_LUJRUHLO'"0!FU>+(0L9@97084^_GS^:+AG)X]H#&M1(#F](WC[..'+0 -M(+/HRS'D]QV)T4B.2>U^M1X.U2AA$Z&[S=XNI!2G#`?%=\,4L-7@>XPW_+EQ -MN7O&-AMZNGH$&I:8)W5L=TY(0]G&_R?1&'UD(_6@RX\E8`X[5W>W]/EF8O]] -MD>./=16BS<-5_F7'Y1D+9IE;`N)QT:8D&8[>K.E4-O8]1?K::?EX\ -MDJ"Q\6!1?1T>>ZRC).Z=CE,T'3HN2GAE(Q'!">%Y*:_RR+CSVZ@M1^]YV -ML_%[GSUA(R2D[)=`M)FT@Y)-F??ND_3Y[\G>'O^X%A.KR=YE:9S&$GG -MY-/!Y_DQYM?+V]KYNW^^_4NK<'0(,6:"\,M^: -MT=\]:O^T_'R>7UE)YMYN#4>=4MJ/->[W+M;EK/RG3^W3.%?9[]#74O<^>P/< -M413]FF38[71HC3+RU]?M_//#-NVF^Y7^Y+8F;=KX^ZW<_GY*^+#P;6[\_<_E -M+U>];A:O$\I!VTSA>N3.?EQ!7V-7\=O^?;U_P;\B6VGL01`[NQ_UV/EV?6_[ -MKUMZT[O9_GVNYTV1/KH!%W?X_-$Q6Z*VCY:Z`\F73*L5=?+\R5(5^AD3:_4F -MPZ;!;9^"3#]R[T>>VT\2BI\L[AOC&B]JMVN_Q>W[)OSM7;_AV_\OY8!>:*,6 -M^1^+],QGW%9XO+6V;MX[)*$5_/*RR#[\/?@Z]=!4^=::8E1311V%RF!#BWNN -MH`6H?QP7P:$Q(8=<#1R8"'K?=\M1$]ZR9G0@1-I$T1LX -M+]>?B]\9(V;OBT_`1`Z(?=DI7W,=_I_6!I+X?QP1X]B^)PI8_(/;:]Q#A\%= -MU]V3*MJ6PXH!IAF0;TC;,)_4^:80)[^-XR)WIO9*Z(;.RY;.ZCT334X)`;^7 -M`)G!CJ;U5;_QWC172 -MEQ5)6DA^I]KN8I@#C)'Y\TL_IF+YAP`2F?+J:F1&]L^.I?YQ<'.QGW\_DY** -M7%."8^.[EOJJ4^I!8LAMT8'W -M*)(_KSZ:PS!2,3M/EOH!?3V-&(93Q1@]%>'('N10B'[ASSP(7E_+)&;-F[@P<5G16<]$X9$C`X%NCG -M&WS1XZ85/CZ[%/J-^79*H.[NT;%V?BO"P['_B4;L9IM5*3!+D[3LW!!:^%X/ -MH(?\AZ\ODR0"#[2YY/I(->I2G^:%![5NS8#7%`9,;<^B+JE`R>7>EK;V(<7G -MI)QFM"^J;$DOG?M?GFG3N'9NH20GEJ.`Z?/FW,TUHN?*TH$@S\?KK_SX/[V4 -M-:[5Z.H(@FQ]7?^OP?=1Z&]CH9"[-C-?^_0.+?)_C,XS)I+\?GQG$]C_'Y.A -M::<4]CL9-C^=LJ[<\/T -M_V\'_;V2_?_GL]"T=#UL>!5=R.WA-/VW(@K["^S_S6'4X#Z7"9*V'%).\V[S -M+NWRDT.#_DLJP*//`HP'V(;,R&O[/<[?=^;M^[EVGXER]X8%UH6,D14XN36< -MM4_'3YCZ/-_MXVZ(0_8R51Q"A-7)J)A>CM=J%AFQ/_8S4LD9EL4&Q;XT -M:A^F[X.N.=2/8GFZB%%5_TQY9$J9('W!JKKM84)DR%\"?UFIS#(FW,OKO+29 -M,??;54.TUVIA(`J?ELM&2<77#.I3M'WMZV\'X??!IFS")Z>_<5]23S8V5V:W -MS3Y[4Z($%$`R*0+_3&^=6.G3=_ -MF=OZ*5FX[.U=^$44(MDNN1*-:FD-5<-F0!4Z+CD(&ZS`PP:Q,7/?Y;W<_V)& -MP/+!Z/I]HK"YTVJC1OP+704FTUIQJZH1='G]V;KS3?Y)T/"H;7WLW/#PQ+^MU<" -MT=21B_LYO9=O=Y)-L?;Y[=O)-&5HC$Q\.QRN-]Z*.6L1AY81FWLNCX2)ILQ]_#=?74B]R[[,U`28+FMTC(`+SV:&E:+,9M%^'8GO53@OWCY>E$ -M\5*(473SU#:(T7E6H1ZL)-IQN0*$K^<<92A6F3)E2%V8K0OY,\U3Z;I^F(S?)\L4:%EZ\A&3>KV8_$0/3``, -MOWR\5*LWQ=6QV)NB:'_!E]$N&O/"=)NP0$A+:PA03]]:&GY"G<$B).]M=GK" -MY!],0%M37/1F*OG`]$VTQ,7Z2*O(\AH]PYM>NKZ/1FI8:M]^4*\8VS)U;*?A -MD66TTPC=X^*;Q2B+VYSY -M>$[T9MNA*=H/!C"GJVLY/+^[XNF"HGK6A];1>V+,07LUM+TQ1NS4%CYYY0F3 -MKL4US$8U#<,QVIL.S)X\L0LC)LU4*P?\%VE6!6PW:A])<'L,F'EEQ.C22)=Q -M:='60-8?,$:@OA#FI^^N*8A%,3+6F-S6FJ^UK7=/JB%4HG1:O;%*B=4_'1$N -MP=J,]QZ<+==VW\-)P]@F]P9>"8:?BQ`_YM-7$[S]R99TWMEO\DW1/^M#4`R5 -M]6K0NG"*TZ7W0`WYI`7YN'HL(^D5F]:'X@L+/,L`UY:0^Y4SI#9FEA$&Y8)G -M=$(FF2-C'3D_W.#/NSZ:,1C/Q1%H,(X,5-\RS:(7N!F^]10O[U+D;[H7EJ+4,7_78&$+:5%4]JE[24+M6U3;R>"V'[NJ,3/E[/T6 -MRQ_[P6L^@2)X;4!J@&'#@:]]N04D@/2*Y<;]V$&%WH97VY]&G%[4KRUG`$7/ -M.I"7EEN++*T(`E7CI=*_)L\#6P;GBB)6J?+R6C>K1>`7)65#WX,<:ZF<_/)*_:IH\F[YKK%,52UCU]RP+_Z;=*J_^ -M/=@@76SS$@W=V$CJ!]<$?V1\SU+1FW/=07_Z?9#_$JD@],H0?H53`[.>R4J, -MR;RVQFU#N=%[K\OR]B&(0Z8)=9Z9EP52)Y_CD`W=\6*5D9NPJM&8\_#EI34W -M9_:XYT",S\-BP$-5Z47?Y=[K)(NCP\VZ#\T)#=[&OWWD@?%J)I4U7FL4&9IO -MXJ<,>R$HMG^FNL-:W83P1GH$=UT&:C?LF\U9-8WY^JKU?2`YZ]>IV?@WK]N7 -M@K.H?5G4C!G&:`S$(#=/@$HU>BV?#SM%I_#DX-_TKS5>GOSP:/#E\GP\A\QK9!V??79J;`^]O",N_AF_/+\*\XM'W>D -MT=3O3[8=G6MVKILA3MRSWVR<6COPE#]3Q'[N=+%;?@7O]-84'GK-B6*/6+1+#M7>'W89HDMS9=Z(GGXIY/TY]5;QX)2&[N9;X8YN -MG.)U(!5HN$7Y#B5K,2`-C=Q]9(FB%+\F+4TH)#O=SE#U<:=NZ9UB211ZU;J5F-07PXYJZ%EN)\*Y=KCXYW1BUC_K.A,5^XHN+_I+RJ@[V-ZSD7#CDVK -M*OXC+9YPU4I)[Y>?4>VW16.]9#VDT*3)IZ9";HZ`ZNQF(#YW.=7]?+M;M#7< -M",7M"^S:4STF9&.HM,6&=Z41G60DI,^O+Q5&[F!5BXWWN>S)6B*>'0LT]=3: -M=_J7Y=JL2X9/:[DAO11(N,MR -MXF4&73`DH?5\&GXY+5M=?Z<]*9*<-;5AV4)$U71",=Z/CUW&+(DT)I_11#=G -M8U4/2R-K>B_XH'AB.T;7)V.S]%.?H4UY6K\Z1:]HG&DLFWMGTT2VL4&S8^N:1GE>)N%C]='T4FF"*8<;DF._$?-5,NUD-V@2LX%4EFOCXLN%PT>'UI -MG%B:"+J]`R>S+CB(_I,-'9DT)L`5;U7#!I`T=I%^`W?%A\5H6,AF-_E;UI7I -MUS7<+/'1;MUA-Y,:+V?44--9]'H<_9Z>=4[YU1D*%\/LL -M.90.B]E1D.7?%TD_$*IT=%,:<$"3E^[:\M&L -MO?CENGP9NG;JEX4=3%`1,<>4SY0U*^'U?"MH;1@=V0W[$+/"@^N.EI%0S)?Y(7&L.=]%GN1[D@AH4B^NAT;]3>?0DUS[X6^H -M)@P)Y;I:NG!NYR08%BV4I2YNY^.INJQ7J&!%()+4O7&3:L.IDLNX=*W2TN/5,:.]>^:M6_/;AFI3 -MS"(W/\=]?XIH<,X&9P:74N(9:,W,NF0)<]U=,P+>]Y.,M\N-T1/L5YX?%=RE]Y=W5@>3_U"BQ2F8>%HIR -M#;HT#)O54Y8H2S=$EB8)!EH<5PA\:ERS]M_2:.C+6DPVG3R="NQ6"+%U?@#Y)M!3WG`U+!T.#,64=C%\\ -M;[P9_F0'Q1#SBZC]D0(GP]Z(^#-II[]^_\X&MBY+&,:N-V4E$<7CR;M;5R7> -M.:NE6]90B[FP>D5^./AF_#8DFF?43E*;$S3=YEJ]6B:5 -MTXE[L;48, -M3?W,@TH;\NYR2N#629=:Z/1DP=NU\F.W>*T*+U7V*=0W3)00U/X\DO3FXL:T -M&EUL+V0HN*:=5(`;=\W)27)Z0@;NZ:<>TZT5T5 -MI:/;4L07U`3$*7]FK'O\EZ\I:$M\;\YF@.^Q.Z04W%$1T=2YX^K-H\V,6R/[ -MZ`K>'/7QRA$*7S^#Y/OV.]_?P2@GZ7,?L9WX_.LE8.DMMW3@GZ7`/)A-_E&+ -M]GX:49G\6>B9E-:-H:/OE-J[QRZW*B-.HJ0C2#2.+R9<(W-O?VNH!S+9:1S; -M@\\G(/+(O!FB*HM&SA])28DWV>3I\+6'YQ7=QZ-274K=QN2@'JTJ961D/HO@ -MMBS&2HB^2;AN?-6$AM:74PCUO9I!=DXB@ETY_%]2A$>R+UU+E_Z^/\_SY7EI -M]"%8\&QRSC-E;'CP\\8G:8K\LQU,1M&U:5,GDB66I`+RRKQZFV$+:',3S\?% -MYX>T6:?!^FH^6[Q'+. -ML:?N%R(RQ=,>B(,ZFJUY/'BD0W]NB[E,4S)N1`:DQDI)K5_?#7L%\=HIN_6M -M$-TQT?:Y+F.<&\V(9?A,=G)3<"R-[$BA0%'/5NS.D)\HH(T3=/\;'WQ)9..X -M;-'2$=OGEE4^*G]ZG#%4J&L0A2P&[]OA]O,@&.U7:*I]_V]?C8BC'@K2<_9M -M2T#1>T-[K.OC%N97C"G<>>?S9;:+FN/XK1/R2WXQ;CTS9/"6>.*;L%,O_2&&7IYBS!2G?-IO/H;[O -M/4UW_LO29;1(W"J;CH%12*TH["-D2MX^J'P8*&;=93_L/;/RS;+>L'RW^A\F -MQ3Z"&3&NO5R]R&'S*$GI2EWHHD1P;9NI[U4.C9A]:R];N2NOBR0>^A6CMVY? -M@JGX6"Z<;`S5BI[T3D$#$BB6`.S\5Z+I'-L/=SSQ*V>S?0E3'MK!&:=#69($ -M.B9(_OQR['6R$K7'5W5V$A8^Q^?T3@R[\H_9L"[HYS=_?L&128FX))Z8"WGK -MVR-?,S+A23JU]40-+&J_8QY5HV:X1* -M*[<3$VA$&DQ:(1PMS?S[OFNKE6S9*FJYVH(]S9[7[SVVR`FFJ#2UQ3X(R5,, -M>=.%XH5_;<"@56B:R;@DY3H`YO9^>OAO3WY=55P?9PK6-YLWL4IL_A#WT'![ -M>GQ0SD;"7^+^N+E/^O)B$IW97EGX)HMF_DY+>0S&;\Z/X*[4HX-0` -M6&ZIZE3]YXSVHG.&W:\]&U[FTV'$NGEC$7?F2]H3)D)IR7Q1-YY(ATC&DUB; -M1>N,WG:ZG[:[`2\_&1F?)Y,'/Y*YY;PLM/:Q[D3(`2X^EH7?Y*90L^+\6-W0%CC5P -M9:B@9'R14RFLDAS*>3"KK1WZ_9K!>8HHT9^*AW6Q;S13I3>9(RNVF(5JCUXD -MX[N8_8B[IT1(LU*J]_SWPM_[?N2>]\7;J>[2.V^9N]&!>.Z/?R4F(*5RD7>_'-0VK+4VN=\DLK?Q -M^:N!T8LT13%V9R1]/`+Z5.>L[IQ3MW/D^;8GW*#@`;__[3HX```````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M````````````/_E+Q/[,7]KU/_G_________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_________________________________________________________H!' -M_(O_ZQ_Z?___________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________________________________^@1_R+_^L?^G__________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________H$?\B__K'_I_____________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_Z!,`=$5#(T7Q9V;W,^%<[-7=@+1MD#N]V=(H:G#Q/=(`AA--ZA)I@\`SL8V -MT\;D&?>M2!R0!DOP\\./&QXPV1=7?1(/.9RZNKNZNKKQWGQ*OX1?J_5X.4KI -M7=_DN>RP```````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``>KO]/._Y^KG]#_CZ?Y]#U+SL7\^=T.?Z_?N>I\?3E+L=#BP'T/4CH=&$)N -M?DV+8S=:!D/EV(TU=I%YE#AD&+[K:W*S.+IFA-XK6PCAG>]/1 -MMA@BZ+>IN;?FV/5K\`7._LZLFFI_:#WA^CZ=_GG\[Z.=%B105Z.QW>KUO4/- -M[F;/1S\_\G\NQL>6#((A@;/W,_?N@?:]/LV?OB5_U%8"A>-<1:9\!E!D<[6&"@GT]WR^_. -M"=7H:/@_0WA`U5AA[7VZGCJ[>E5X+C26KE^^-NFT<<7,CJC//*W-']DS2Z=F -M9DJ9!0/G6>*0C4\UX8L_]QUUB@T5ZXQ1$-.,&:[?FC]D)`YYNG74?;3U_=?- -M[G;TM'P:I`2I;4COU_54TGF_4=X6$526/(,I+9@CRP2#] -M'J=7]ZU+Z\W6KIQA?7?2I\I"!+Q71:_9!2I4HR.X2B4-\W2K\DR7]>JGT7Q> -MKRZ_9!HH(>?]V&+1UT]+;@0'L;[5_S3%"?UWAM_;!D^W]/K_X^;I7OE?R]S_ -MVLGF!NCMZ6?X(VK?0N?#]U)QT_NBWX(*EF+3B8NCP)=.._C?N@N\ZL^#"9AK -MST*.D,-EEKC&[UWHO%>N/W@X=9M2M]J?'QI?=VK^UNWT)\:GK;]YX:?MB?`E -MF)'ADC\97[/PY`BGY%>MG/+/42R_\;S\()->K5G^\1!9..A.\O+D)NB.S($5 -M02T+`7)*,XVA30M^,A459Q'!N;6ZY-6C.JLQ%/Y52F+3EE1>&4,&R8XU':!$F; -MF5"OCP[G9]A#=)6ES/C@I$^=\E&"_%CF2%_A[10FG@" -M9^E,FKBG@OD$[6.JEU.YI]$W@W(N.VC[-#'%XX%/;/1[?R_J]$^'*EK5"=SZ -M]M-^"&:S1.;ZGV]C8C&N]&YQ8O$9DVMW&$,ZZ1FT%>RLK\VW58,-CWZB"XF" -MIO-.*_;$RS".=Y5A(MHK9-5OF.6&E)2(BI"WSE*K5QC`O^9R67Y]C5FY)L.* -M-/U(/D;#*)DM75HT%ZJ9OTK,WF9&5D+Y8->!;QECO^K]7-D<0)FYL7G9.Z_8 -MX+6$7@_'(NQ_&6#M<)Q^2WW#@&C<6;,AFP1=+M5Z\HE`UWG$!\8O:-BO[>J^>7N\=Y[)+2G+Y$M);V8@NWGHX\M.\JQ@CRQ -M%\!:!3]M-T&+'K+M_USM_2%\P@["=$LHV.XS#N+.<8R -MY%'0.GBJWIL.72$>]DKN4Z#6O:6Q,IP_]9E?$T]'C_\@[A>;$ -M?XI?LLR:40TVJ7)D#2,3>LU;`_$"4N -M&4P441T95`:X"'9$8,[W+\L&G7P/%C-/3,I72N(5A)F]_$-[H=&9[^'T^:"8 -MC^5]\6V4M>1GE+U9!YQ/U1YF1`/O9CF+?=FDVS+2`UZ/5[B0)D3@\E3^1^#. -MV_11VJRFU3*S[.A_"$`QS`]C"/@M#5>;#Y?-K;N\;)=_Q\$0(X_.ATRM^&OG;?N?!;-H8H[U/ -MHHPV\Z(&K1QH1O;`[;9!4U;]/A[G!2K,F2MW+2(XP^G(R'FP)@V:=)(\C6)N -MO@V\:>X_>!0>)%^0YO8ZHQ_OD#&P[\C.]6I6'[J]%(!2T`RI9NA"BFML:FKB -MAY(5(IH:[@V=C%AB:^D1Y?'3*&>OWZ$L3W5]?OZ-LD)4RGK0!YG6.3:L:4"-Y; -MD_GQ72.Y6W9]SX'DJ07OYL'`/M1W)6<2,?0QP#R^)XBJ4RE\]WAYGXY84YF7 -M:YZ5-@DT66G#Q9@60$BKPY+`](QGK2[_JJV\AQ/R`XH -MVD\14Z*>LF4*L@JS2KFW==$GM -MWFR`E-%>'U0G*T/+I#_TLL/<76W9Y:T`D(2>Q3P''$O,^-)8H0K\$E>\9BIC -M/&44Y$D<2;4D:YE[7"(8 -MDYKUJ\/M>"3_BK3D.C5HW%OS+M!?<&%S1T*M(GC>D?+53TXZ)3:5625@^CX9 -M]BG1L\:2+^&N]9T<\Y?:_6C!T9(['Z\[MBTC#HMC+@EX:.5KP^F.H=*=9QR6 -MIV8+DZ-P?PP^2QM0PUSDEX\_Z?Z1$CG7)\?^B"`Y"\,5D[^^SPV4ZN_5S*O! -M^9&W:4B"8L`6;4GI@157EE_6/M98M"?9#/+GW2`;VK,@'EVKD9(.X.KLO -M->-V?)=:LKQEV?3[5S_!Z;^-)351%BSQ`D)>.W8(D.+!*BV7BP5TM2OFK[>F -M"=:`6KJKM(]#K:FOG?C#2O[X>W5YJ1N!`-QG,>QX@Q6KI5"2JW:%6>3#-!-G -M*G&&BNEOE>:S@*F0+NR57M;R9;D'X-3:R>\J&`/1Y]:6E]P_W$E>MB9;FO*A -M"W"DV]+[=N+'KCLUN[.WL4:C$`3?V]G!KZ6EV:LMOZUA' -M=#U<,G!-<2@<>";Z039OGTY4=\3R1PS7-=J^W]:OTHKW? -M1Y7!VF17\?/7Z$E4#!Z)%*6*^<&D?D8PO?%I?/=P3PWI47++Z8#;%[=KD -M8Y.O:0K:=/8[%R58^">39H]V):N;XYX7R&8W=[_:C63/2NOC7+%S:\I;2VN6 -M94Y+0'@5X^I7P&OL7>#B?E7"&?@C-PLV15)1(A)GD)$8@P.MK)YXV)^O&3?4 -M8:ROF\I>*X;HE\Y&RIF\;S.PX52MN-2:`%FZV9IT]C6TZ_:[_O?K)(VL[_[Q -MF^>4]CI0^0F<9A*Z9IJ^0F9M2O4.)^R+^^YNO^CQU(%V -M4W]RLQE88IE2.BPQAKV,CR\8MSJNU7777A5*'O2[F\\/>IT9MX>SOP;3=?0F-V@]("UZ9Y'HZ6;1AGCFU;WD`Y=3M8O6]G8T -M,NQ(K*=^\2<:CT#]@Z-5^'0(PIO#,>>:U=#BY[?93%1)?X@`KQRVC3SHS%X_ -M@..+X0@#_IO&U^)=C=L76S/'W/!<=A-'6-V#P;3R$8-EK4+XPT)O- -M6^)I:<0RWY'!@LA7MZHVM8Y4JP<1`LF-U"BUL,%28TW4^[J38:4/)#7>SM>[ -M'3)\BLU4PS`LC4V=FCA@^;I<1]E:7_J>2+>*DQH\/EW[-S9EQ.TXS="/O>]B -MNW50:/>O+OQ.-JE0`3%YL.SEI[Z.)88V[DGE?CO\&CI;HR0;T#?0$7?*IQGU -MN^3UGEY)0MWV)/1&CN$X7Z8Y$\R2T-1X'QGU"MX*;F*[L$LK"3#H?2V>@(VZ -MRO5_BL9@$?C=GO*4[!5X\R5;I\6YJR,!Q&/@Q29R"(&N]=@'F\2G$`J\ -M*GCQ^*+(/UK2W/%665P'F=(FR7*_.?DKCM)DEZ=>3LOZY.4" -M99O\.:#R,,^3UFS>O0,6B'Q.*:/=2VG`/P%5ST1#D1TKU]NJ4<[YY<-6]7?7 -MADE11HDG6U=:'1_^US+C>IC^`2INA63>GEDM8_P[N/1;ET/Y_?&EYTIF-B;)U:K8GTO05S`3*R`L,0%2$9*[SBV< -MX3WA7?=B#Y^C[B>?!*ZO]N9R/A+ZMG>$V;_'R[?U7HS-EWC#[[MO:ULV2U+. -MDLLTV""@#FZ,$'.G=,/;L0_9^'0IV%K/Y0/%:^#FQRKI;\V#@V][_\=;V'N3 -M0F;T6TYD]@415A#,EU]GQ%:8#N9=X+U)(:'Z*40!H7UAGFMBRWA3Q\I[G>R< -ME)7*LHZLEE!$#;T:FKJ^I&K]:?<&S)ZGX(#M!>IKV`79]6+&I_/`]O?%U80G -M:GB,BX@'\MT1.ND3\+D9RKS%4LC94+WR+O#I5%G-L=8]R*!I#5.V7#`,HCNP2_"#-G$GE4B69\7+GG -MUVOYNE_6D(71'WCB97ETLMT2"Y6BK*)9>L3>+.]%KG4)T^(G\+`A$[K'-B27 -MU"2YM;=F1'6BV4KACWJ=LQ8I`^%[V*\=O72&+DD-5:']^KIZ/:]PM#L]G3[D -M-'-'P=&*^#]>?N8MK/CUVOZSFU?9J8L%B!C9S?Y<:8[6A]GMO3T.GV>C]G;[ -M?9^OM]JK?:ZV1LB/&5F^Y]4?5M1_L-BH57H7:I9U08=&I2B]L@E25;IGV(.8:6^>$ -M+ES#DK\KE=G'6IM?8LV;4$.OB5MK?5`!1L]O:0T$GNQTV3].>,)]:3S@E6U9 -MKDKAPNN5+9.2::]/N:/;N:;5S,+0T)\0%=/2[&AW>KU*!SK=:J,@(2N"PW%9 -MW!KB\T>WT[3%?)+Y[V_GPF#H2O%R8)_`P9'B__T&"X-I_\KV0>A("_D/:L>! -M3(?BJ2Y"RVW7$:-=2G^'Z",NLI#;QDHK&K(;<;_]?;H%)^9E2*BV.C;($ZV- -M>]'M7_KNY`T15D#0L;;O+5;U9OO -M8W8]+R2_&EG*K9B'O:H9.XV:B]$??CZ,0!89*P^2[&LE7_?6GS&2Z-_CTPI' -MA"AT71M;M#+M#DL;AXT94K'FZ..IMS?4VM*[>-&8[B#UHSF.2)!7WRJLA$AJ -MR#L;>/NJS\*9\JXP4:2'U)]W2EC2#[BP9%1GY)R*=CJ]/^^G"CHO5AO,[W4Z -M1*BZ?=]P.]V]/V3[. -M[H>Q='K>Z?5NF;D>W\K)STYV/HOPQOZDH@[MU;7`DDVF= -ML1+MBC0[>WK2J%+`!PK6QT>.I+5Z?'8Y5R\-6]78Y]K9`\U^8BL-RIT=/P)W -M=MUW`<`+7@7.J_M%?&GL*GT`9Y9.R/#;/H5QUC\9P1?FE6]A+@3[IP,/12G_ -MAS*3.>)L-E>+_%NQ=[-L\U7NU2JXDIPXS#7AUR!)$HMA_R`%@"ZJP3S:J_C' -MBIG^1,[>NAY373*#O)5?X]BC-4U!EX?OX&6/\^(:@[L,[%.%TZ_QP]`!V<@\ -M;EL@[&7&ED&AW(BSGW*'RLG2C+__M/40````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`#_V2\C^C%_:]3_Y____________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________________________________________Z`1_R+_^L?^G__ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________H$?\B__K'_I_____________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_________Z!)#_4%IS_=3_\````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````$````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````````````````````````````````````!Q,(=41 -M#,T1`!85O9S\*.C/!I9I1:2;N[&-B[`5MIBT,?1836;F[OB11)I)5B)-+34% -MIEX-^[V`4GT(E*.1T3,T512)P;F^.L,(DS43'5SOBOB7/\(/W/[]SD1P3SPF -M!'I,@``````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M````````.7XW\>[_'Z.[^I\O\.YZ>>OI?P^;^'I__RVDL4?\2G5G_T:?&__K -MIY7K#H7@A(IWJ%<*'!9%"OLP-!P7AD6BR0E+P\"H8V._E_*C?IFE[04,GALITXYE9I+UT -MMU/+-*9HF_1./4FOK-SR3*$Q\?,OFSQ7M\WQ\F5CX9ZMYX>?&%_>A&']?O\$V'A#;8AY^:-F[! -M<+R;L;2\W&/WE[NW#\"VZ13S4Z)=:V3Q#T -MU/+GI-CEU>"-W\DF:9P9/]HUM+9"3=,D')VO?T5`Y@0JK9)ZDNJKN55>?RY5 -MNYJSH3JV#6/<3LVRY101KEWH:&G!%)MZ=CQ\GZ4 -M6;81TIWET&%/OY\_FBX9R>/:`QK42`YO2-X^SCART""SZ,LQY/<=B=%(CDGM -M?K4>#M4H81.AN\W>+J04IPP'Q7?#%+#5X'N,-_RY<;E[QC8;>KIZ!!J6F"=U -M;'=.2$/9QO\GT1A]9"/UH,N/)6`..U=WM_3Y9F+_?9'CCW45HLW#5?YEQW,@ -M;`6'N49"V:96P+B<=&F)!F.WJSI5#;V/47ZVFGY>/)*@L?%@47T='GNLHR3N -MG8Y3-!TZ'+]3GRB>+)PE;U"26?49/=@L;K[PEX?V2FO\LBX\]NH+4?O>=K/Q>Y\]82,DI.R70+29 -MM(.239GW[I/W*1+WD^>_)WA[_N!83J\G>96F?Y,7.FUW>WV_\N -MUV^[VNY_+Q=WN;7R]O:^;M_OOU+JW!T"#%F@O#+?FM'?/6K_M/Q\GE]92>;> -M;@U'G5+:CS7N]R[6Y:S\IT_MTSA7V>_0UU+W/GL#W%$4_9IDV.UT:(TR\M?7 -M[?SSPS;MION5_N2V)FW:^/NMW/Y^2OBP\&UN_/W/Y2]7O6X6KQ/*0=M,X7KD -MSGY<05]C5_';_GV]?\&_(EMI[$$0.[L?]=CY=GUO^Z];>M.[V?Y]KN=-D3ZZ -M`1=W^/S1,5NBMH^6N@/)ETRK%77R_,E2%?H9$VOU)L.FP6V?@DP_+RUMF[> -M.R2A%?SRLL@^_#WX.O705/G6FF)44T4=ALF9T($3:1-$7*>D-%"$=?3N^+5%(_=^.27QEDR"]ZTV@X8_& -M&>/G>F3@B!^/)-IU:J"_U:B;$#85>RVGU'%[P=WK."_7GXO?&2-F[XM/P$0. -MB'W9*5]S'?Z?U@:2^'\<$>/8OB<*6/R#VVO<0X?!7=?=DRK:EL.*`:89D&]( -MVS"?U/FF$">_C>,B=Z;V2NB&SLN6SNH]$TU."0&_EP"9P8ZF]56_\=XT5W*Z -M(8%\ZC[&:UCV8_:+VW,O/7*'4,FO@'.<6`99O;Z<2@48FVBZ,8DT*HLE,P8$A:?WB! -M[D4(A^X<\\"%Y?RR1FS9NX,'%9T5G/1.&1(P.!;HYQM\T>.F%3X^NQ3ZC?EV -M2J#N[M&Q=GXKPL.Q_XE&[&:;52DP2Y.T[-P06OA>#Z"'_(>O+Y,D`@^TN>3Z -M2#7J4I_FA0>U;LV`UQ0&3&W/HBZI0,GEWI:V]B'%YZ2<9K0OJFQ)+YW[7YYI -MT[AV;J$D)Y:C@.GSYMS--:+GRM*!(,_'ZZ_\^#^]E#6NU>CJ"()L?5W_K\'W -M4>AO8Z&0NS8S7_OT#BWR?XS.,R:2_'Y\9Q/8_Q^3H6FG%/8[&38_G;*NW'*. -MW)A5=CL]G8_Z>MON_T^S[.S]&N]?OP@820/NQWO#]/]O!_V]DOW_Y[/0M'0] -M;'@57&!=:%C)$5.+DUG+5/QT^8^CS?[>-NB$/V -M,E4<7)EZ7(.*]?PTP@@=BA%.&SYVO!]WU_)]O>^[P?7(++:^WZZ?#AAT\W[= -MEG;L3P351#M:+[3$?^\O^HME\&24S_T1G+U1+-Q79*PV'(J5IS:)$+]VKO&E -M0R'-2I['@H35R:B87H[7:A89L3_V,U+)&9;%!L6^-&H?IN^#KCG4CV)YNHA1 -M5?],>61*F2!]P:JZ[6%"9,A?`G]9JMO!^'WP:9LPB>GOW%?4D\V-E=FM\T^>W#]&KO)IO^I9^&R -M;K[;\*L#7CZ?:*PN=-JHT;\ -M"UT%)M-:<:NJ$71Y_=FZ\W).4!90;+G\EEX#1J;PR2-L#O-6&E(XK[#KM-8= -M]C<.;=9O$SI)Y23;'V -M^>W;R31E:(Q,?#LBCEK$8>6$9M[+H^$B:;'+>[EJJ)]A)U.2]L65(9R -M>I<#C8;!8>M=*W\_/L?B$S;X3>UO(F,]'V<1)_:NAODT_>$:7\>6)[XZ<]'% -M=EU8T[QXE>QN9@=S24?7&Y[2*>E2E, -MK"3:<;D"A*_G'&4H5IDR7-$12A*,D+W*3C1W/%Y=4FQ%&*83)\NBRQQ'I4A= -MF*T+^3/-4^FZ?IB,WR?+%&A9>O(7.6/;&:KK2H%3UU>9E.D_@_S[_]/IYW)E -M;XEL:43.SFZKSR6X=$TH+SSA8+GADWJ]F/Q$#TP`#+]\O%2K-\75L=B;HFA_ -MP9?1+AKSPG2;L$!(2VL(4$_?6AI^0IW!(B3O;79ZPN0?3$!;4UST9BKYP/1- -MM,3%^DBKR/(:/<.;7KJ^CT9J6&K??E"O&-LR=6RGX9%EM-,(W>/BF\4HB]G+ -MUFY/IEP-HPS!8@UUFXK35!Z(_SASX(*5WQ7S576EW5-_8]'6[E2&KE=VN;X% -M:[NYM%C1<+NVLN.:!U-C+2"TX;(84R9WQ55<]'N<^7A.]&;;H2G:#P8PIZMK -M.3R_N^+I@J)ZUH?6T7MBS$%[-;2],4;LU!8^>>4)DZ[%- -M/+$+(R;-5"L'_!=I5@5L-VH?27![#)AY9<3HTDB7<6G1UD#6'S!&H+X0YJ?O -MKBF(13$RUICG"W7=M_#26D/N5,Z0V9I81!N6"9W1")IDC8QTY/]S@S[L^ -MFC$8S\41:#".#%3?,LVB%[@9OO44+^]2Y&W-*^@BU1%`MY[N7=Z)]^&?@M&6 -MF)V"QN;DQ":81BC^''8X[6`O>/1JNX"UK[5]VU37^_PD[J^:5V-%:YYL^W;(W9N_WNZ%Y:B -MU#%_UV!A"VE15/:I>TE"[5M4V\G@MA^[JC$SY>S]%LL?^\%K/H$B>&U`:H!A -MPX&O?;D%)(#TBN7&_=A!A=Z&5]N?1IQ>U*\M9P!%SSJ0EY9;BRRM"`)5XZ72 -MOR;/`UL&YXHB5JGR\EHWJT7@%R5G)QE[`!E^/RF>#SY9?YPZ8;%\O2ZZ0GE0 -M]^#'&NIG/SR2OVJ:/)N^:ZQ3%4M8]?Z_+\O8A -MB$.F"76>F9<%4B>?XY`-W?%BE9&;L*K1F//PY:4U-V?VN.=`C,_#8L!#5>E% -MW^7>ZR2+H\/-N@_-"0W>QK]]Y('Q:B:5-5YK%!F:;^*G#'LA*+9_IKK#6MV$ -M\$9Z!'==!FHW[)O-636-^?JJ]7T@.>O7J=GX-Z_;EX*SJ'U9U(P9QF@,Q"`W -M3X!*-7HMGP\[1:?PY.#?]*\W+[Q:_[28_V%L^#?/U9N*L\^]:U'7E7I[\\&C -MPY?)\/(?,:V0=GWUV:FP/O;PC+OX9OSR_"O.+1]WI-'4[T^V'9UK=JZ;(4[< -ML]]LG%H[\)0_4\1^[G2Q6WX%[_37'_AWUXLOY>[Z/6")-H&;V_KY2A$N_R;' -M*[R)OVP;(F!9:KV%I2CB;Q[V$?(Z[JOA>B&U=?##-(7,P9'F%!YZS8EBCUBT -M2P[5WA]V&:)+B)Y^*>3].?56\>"4AN[F6^&.;ISB=2`5:+A%^0XE:S$@ -M#8WG,%I^7PA.V>D/?>WM6ZE9C4 -M%\..:NA9;B?"N7:X^.=T8M8_ZSH3%?N'.F:UC?DH$6_&DMBZO,\]9>]2@.E) -M&;7=@D=U)T"42`L>@*>'J+B_Z2\JH.]C>LY%PXY-JRK^(RV><-5*2>^7GU'M -MMT5CO60]I-"DR:>F0FZ.@.KL9B`^=SG5_7R[6[0UW`C%[0OLVE,])F1CJ+3% -MAG>E$9UD)*3/KR\51NY@58N-][GLR5HBGAT+-/74VG?ZE^7:K$N&3VNY(;T4 -M2+C+A7N)E!ETP)*'U?!I^.2U; -M77^G/2F2G#6U8=E"1-5T0C'>CX]=QBR)-":?T40W9V-5#TLC:WHO^*!X8CM& -MUR=CL_13GZ%->5J_.D6O:)QI+)M[9]-$MK%!G,O_R7LV/KFD9Y7B;A8_71]% -M)I@BF'&Y)COQ'S53+M9#=H$K.!5)9KX^++A<-'A]:9Q8F@BZO0,GLRXXB/Z3 -M#1V9-";`%6]5PP:0-':1?@-WQ8?%:%C(9C?Y6]:5Z=3&BW) -M0!;375:#7?5-7MGU%#36?1Z'/V>GG5.^=49"A?#[+#F4#HO949#EWQ='-_6] -M9?=\?/G[7)SKUK%'4Q0 -M$3''E,^4-2OA]7PK:&T8'=D-W*VB6X4).M<^P3(LOE36UM-'>9J( -M-49K[WT_97TJL`31ETP18CSP+Y>:/NG1^.37NW,F[YK,[*;EWA"SPH/KCI:1 -M4,R7^2%QK#G?19[D>Y((:%(OKH=&_4WGT)-<^^%OJ"8,">6Z6KIP;N`T/*Q\=W+J.0?2ZGG -MO>3C+?+C=$3[%>>'Q77=U8'D_]0HL4IF'A:*<@VZ-`R;U5.6*$LW1)8F -M"09:'%<(?&G`6L#]]>1";IC?4-V827=ABFSA3D2>9[TWW%3#WIB/@S::>_?O_.!K8N2QC&KC=E)1'%X\F[6U0,(EMS<-;TGOCCX9OPV))IGU$Y2FQ,TW>9:O5HFE=.)>[&W.N\"4W__&2.% -MO9(=V?Z9_2<+!ZMT4,L>_U/WU-4Z<]^DK:KD5WE&#$W]S(-*&_+ND(&[NFG'M.M%=%:6CVU+$%]0$Q"E_9JQ[ -M_)>O*6A+?&_.9H#OL3ND%-Q1$='4N>/JS:/-C%LC^^@*WASU\C4EU*W<;DH!ZM*F5D9#Z+X+8LQDJ(ODFX;GS5A(;6 -MEU,(];V:079.(H)=.?Q?4H1'LB]=2Y?^OC_/\^5Y:?0A6/!LIMA"VAS$\_'Q>>'M%FGP?IJ/EN\7,?& -M9E@!2"G4MDYDN9FH[(?NC?@R=(/K>R<&3R1'+WARSK&G[A3QXI$-_;HNY3%,R;D0&I,9*2:U?WPU[!?':*;OUK1#=,='VN2YCG!O-B&7X -M3'9R4W`LC>Q(H4!1SU;LSI"?**"-$W3_&Q]\263CN&S1TA';YY95/BI_>IPQ -M5*AK$(4L!N_;X?;S(!CM5VBJ??]O7XV(HQX*TG/V;4M`T7M#>ZSKXQ;F5XPI -MW'GG\V6VBYKC^*T3\DM^,6X],V3PG'R=/9.AKN@`=51G"LJ]IHZH;I]I='PU1EOXY'XJU2:;1TR9/*]V/=6")LTZ[AJCE4ZBGEG.3 -M/1EYXE5SSYX'GCBF[!3+_TAAEZ>8LP4IWS:;SZ&^[SU-=_[+TF6T2-PJFXZ! -M44BM*.PC9$K>/JA\&"AFW64_[#VS\LVRWK!\M_H?)L4^@ADQKKU]5#HV8?6LO6[DKKXLD'OH5H[=N7X*I^%@NG&P,U8J>]$Y! -M`Q(HE@#L_%>BZ1S;#W<\\2MGLWT)4Q[:P1FG0UF2!#HF2/[\F`MYZ]LC7S,RX4DZM?5$#2QJ -MG)[0N.?8@\P$9-)^0.OMHW,VF()]_"@]_N<*U(DS02,0@FJ4'Z.X6-PG8Y3] -MWX`WR1P9=1]AT[_LS[T=5-U8D=/ZM[-1V-^;6YB-QIHS\1OK1E#^H^/%2CSU -M*]SFZB-O0P7.9&(^"2;U+Z.1_C%^3WOV,>5:-FN$2BNW$Q-H1!I,6B$<+U^\]ML@)IJ@TM<4^",E3#'G3A>*%?VW`H%5HFLFX -M).4Z`.;V?GKX;T]^755<'V<*UC>;-[%*;/X0]]!P>WI\4,Y&PE_B_KBY3_KR -M8A*=V5Y9^":+9OY.2W-%I:#J"YC[#9]&6)@HH1ZHV*<8TFQK2]$+2^(@3/9+1"6W2O)L"JZC)MCDJG+%_;+= -MUEV.2(I,V[T@EI4_>>,]J)SAMVO -M/1M>YM-AQ+IY8Q%WYDO:$R9":>2(=(QI-8FT7KC-YVNI^VNP$O'+G7 -M+LUC#W-PU`SJ5TG3!'3-Y$71F&\RIAPA-3+KMQ`A.LV>T\I=DWOQD9GR>3!S -M^2N>6\'-??Y*P]1Z)]:MSNVK3KLQO<_'-NOXQU:K;F)9UV*]@/U`:IFZLT$S -M[=SKY$R`$N/I:%W^2F4+/B_%C=T!8XU<&6HH&1\D5,IK)()..[F/V(NZ=$2+-2JO?\ -M]\+?^W[DGO?%VZGNTCMOF;O1@7CNCW\E)B"E\79I]#\?;E*)GX0XO'&S/8K]`A_E[O:W-?VBQ++>W23#MS -MBS^;+K!B)WYOZGT*KTU5WI%WOQS4-JRU-KG?)+*W\?FK@=&+-$4Q=FH2:8/`,[& -M-M/&Y!GWK4@,-D75WT2#SF#E* -MZ5W?Y+GLL``````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````'J[_3SO^?JY_0_X^G -M^?0]2\[%_/G=#G^OW[GJ?'TY2['0XL!]#U(Z'1A";GY-BV,W6@9#W(9][P]/ -MH]'[A3K3X&Y3I1IDIHT2.XL$R&Y[I4@=.F[#?/^ZK1ZD#&6'[\,TB^]<>9\" -MY-'I=B--7:1>90X9!B^ZVMRLSBZ9H3>*UL(X9WO3T;88(NBWJ;FWYMCU:_`% -MSO[.K)IJ?V@]X?H^G?YY_.^CG18D4%>CL=WJ];U#S>YFST<_/_)_+L;'E@R" -M(8&S]S/W[H'VO3[-G[XE?]16`H7C7$6F?`7.ERJ_\NC3.&L[XU<8.@9'&L'1 -M%!-IUL?&T8$DS.,.S_X.*MFY1YV-X9_`(S_AWXIX>G6]DL&G_OS_IAR`Z?BI -M3QZ.HD:>+P"$%C35TX0*EI^YVGV?T]ST4:L"3()CQ -M_;TU>HQ6M?7%4=POV:74YL0'I09'.UA@H)]/=\OOS@G5Z&CX/T-X0-588>U] -MNIXZNWI5>"XTEJY?OC;IM''%S(ZHSSRMS1_9,TNG9F9*F04#YUGBD(U/->&+ -M/_<==8H-%>N,41#3C!FNWYH_9"0.>;IUU'VT]?W7S>YV]+1\&G+.*[KK$#3U -MQL@WJ0$J6U([]?U5-)YOU'>%A%4ECR#*2V8(\L$@_1ZG5_>M2^O-UJZ<87UW -MTJ?*0@2\5T6OV04J5*,CN$HE#?-TJ_),E_7JI]%\7J\NOV0:*"'G_=ABT==/ -M2VX$![&^U?\TQ0G]=X;?VP9/M_3Z_^/FZ5[Y7\O<_]K)Y@;H[>EG^"-JWT+G -MP_=2<=/[HM^""I9BTXF+H\"73COXW[H+O.K/@PF8:\]"CI##99:XQN]=Z+Q7 -MKC]X.'6;4K?:GQ\:7W=J_M;M]"?&IZV_>>&G[8GP)9B1X9(_&5^S\.0(I^17 -MK9SRSU$LO_&\_""37JU9_O$063CH3O+RY";HCLR!%4$M"P%R2C.-H4T+?C(5 -M%67(4L1#KH$O:A2=CZ)I=,W#/<=T<&R;OD^+GR7]R>;S\[^F=SHQ[7Y?2JY?(" -M\?;D5='4C,DW>]M08M$KGBTY947AE#!LF.-1V@1)FYE7*S+,.\DPMX]7(X1G -M@KX\.YV?80W25IT4)IX`F?I3)JXIX+Y!.UCJI=3 -MN:?1-X-R+CMH^S0QQ>.!3VST>W\OZO1/ARI:U0G<^O;3?@AFLT3F^I]O8V(Q -MKO1N<6+Q&9-K=QA#.ND9M!7LK*_-MU6##8]^H@N)@J;S3BOVQ,LPCG>582+: -M*V35;YCEAI24B(J0M\Y2JU<8P+_FJ -MF;]*S-YF1E9"^6#7@6\98[_J_5S9'$"9N;%YV3NOV."UA%X/QR+L?QE@[7"< -M?DM]PX!HW%FS(9L$72W-F;R_Q4)6NGQ]CR5DD<$4/@WK5>O*)0-=YQ`?&+VC -M8K^WJOGE[O'>>R2TIR^1+26]F(+MYZ./+3O*L8(\L1?`6G+W.'X^$2W9;!*^ -M:F_'@4W(5F1JU?!NVGK-6P/Q`E+AE,%%$=&50&N`AV1&#. -M]R_+!IU\#Q8S3TS*5TKB%829O?Q#>Z'1F>_A]/F@F(_E??%ME+7D9Y2]60>< -M3]4>9D0#[V8YBWW9I-LRT@->CU>XD"9$X/)4_D?@SMOT4=JLIM4RL^SH7+YF -M^D*/KRO?/*04O+L4&ZDC*5OA&Y,:7!/@]ZOHM"FQW8VJ5;AM*JL7;-6!N[6] -MJ0@0>(#ME,2.IWSQZ(5C"T&2/9\1OUR3*%B2C7]$U3>GU7#`_% -M*#CTL%T>+DJ]8LZ`%_S9T0AR,F*8A^38LN[FV;>H'$8@.LX?T>!M2_'\S.MV -MAR_G/VL%"@,^G4"N=%Y0?-TLOL=FY3@:\3EV[\9U@?GOPA`,

    YP4JS)DK=RTB.,/IR,AYL"8-FG22/(UB;KX-O&GN/W@4'B1?D.;V -M.J,?[Y`QL._(SO5J5A^ZO12`4M`,J6;H0HIK;&IJXH>2%2*:&G,SJ5^>K9HV -M8Y<<-T]9F<;HSQ'1>LBVE;`)X`M'./CRH=Y@#/K"F_3I6A'NX-G8Q88FOI$> -M7QTRAGK]^A+$]U?7[^C;)"5,IZT`>9UCDVK&E`C>6Y/Y\5TCN5MV?<^!Y*D% -M[^;!P#[4=R5G$C'T,<`\OB>(JE,I?/=X>9^.6%.9EVN>E38)-%EIP\68%D!( -MJ\.2P/2,9ZTN_ZJMO(<3\@'.$AJ8LQN+'*1OZ>MABA;T2=+%VV^E#8=?&(*C -M">6"'4>./TYUUZ^16ZB9?F032LZ@`G#.NUP)E_R"<$+G.1MQ -MN&41O^>#0SVYI;T@#9T";E^4T8INM0VK05*WSG7N*-I/$5.BGK)E"K(*LTJY -MMW7*0%E#-DIT)\6M`)"$GL4\!QQ+S/C26*$*_!)7O&8J8SQE%.1)'$FU)&N9>UPB -M&'*@ZVQ.5<97)*HZ$LP8EM1J`AG9)EA010)R+E<*WI.:]:O'+5J/60FO]]?4 -MO>9F7&+58QPXE=<$_[Y=?<@VU>AS\Z>^"&//+@SM?!MP0'>O[:_QZC1"HHK` -MV\AL!%@P)*Z;^UUI#AC3SVS#Y2EC^[8S`\,8J0E7-CCXH454<5$7#N4^4`KW -M*54I;%J4N2KFI^'5Y^,1K?,;1U`HG-30&8H; -M-(IHL$"RXYQ21.AQ<9'YO,W_.Y$EP]>$?@W8SRAX(VJ]XXWC[7@D_XJTY#HU -M:-Q;\R[07W!A//^G^D1(YUR?'_H@@.0O#%9._OL\-E.KOUF_C24U418L\0)"7CMV")#BP2HMEXL%=+4KYJ^WI@G6@%JZJ[2/0ZVIKYWX -MPTK^^'MU>:D;@0#<9S'L>(,5JZ50DJMVA5GDPS039RIQAHKI;Y7FLX"ID"[L -ME5[6\F6Y!^#4VLGO*A@#T>?6EI?K[5HZ?\OY7:'ES7:OM_6K]**]WT>5P=ID5_'SU^A)5`P> -MB12EBOG!G(\?]O(,ZJZNARE%[&H"K\N7383F-&V2K`]XL&K+H:G+2H^[NT.GXJ^6+]:LMOZ*,]>"%W;U;$(?)ED_MTH$E8_F)VC -M('`[:RJ8M;7I'Y&,+WQ:7SW<$\-Z5%RR^F`VQ>W:Y&.3KVD*VG3V.Q%\AF-W>_VHUDSTKKXURQ/ISFG9V+O! -MQ/RKA#/P1FX6;(JDHD0DSR$B,08'6UD\\;$_7C)OJ,-97S>4O%<-T2^-YG8<*I6W&I-`"S=;,TZ>QK:=?M=_WOUDD;6=_]XS?/*>QTH?(3.,PE=,TU -M?(3,VI7J'$_9%_?\3,7RS)JO77_1XZD"[*;^Y68RL,4RI'188PU[ -M&1Y>,6YU7:KKKKPJE#WI=S>>'O4Z,V\/9WX-N/ESM;8\MNE$KQMI7':P([CO -M)NOH3&[0>D!:],\CT=+-HPSQS:M[R`SL:&78D5E._>).-1Z!^P=& -MJ_#H$84WAF//-:NAQ<]OLIBHDO\0`5XY;1IYT9B\?P''%\(0!_TWC:_$NQNV -M+K9GC[G@N.PFCK&N/H:2B/;!X-IY",&RUJ%\8:$WFK?$TM.(9;\C@P60KV]4 -M;6L'R[]FYLRXG:<9NA'WO>Q7;JH-'O7EWXG&U2H`)B -M\V'9RT]]'$L,;=R3ROQW^#1TMT9(-Z!OH"+OE4XSZW?)ZSR\DH6[[$GHC1W" -M<+],9):&H\#XSZA6\%-S%=V"65A)AT/I;/0$;=97J_Q6,P"/QNSWE*=@J -M\>9*MT^+NP#S>)3B`./BO5>%3QX_%%D'ZUI;GBK+*X -M#S.D39+E?G/R5QVDR2].O)V7].6T[%.EC-8\?$YFXK!4]>;CU5T(=0!5_AA+ -M&<;5Q%6O[H[.&/Y[?=^?'<$UJ%I,Q96U]9MQOKOKPR2HHT23K:NM#H__:YE -MQO4Q_`)4W0K)O3RR6L?X=W'N/^%'L6/^"S-X:\JK\ZFK;0QG%@C5I6/(MRZ' -M\_OC2\Z4S&Q-DZM5L3Z7H*Y@)E9`6&("I",E=YQ;.<)[PKONQ!\_1]Q//@E= -M7^W,Y'PE]6SO";-_CY=OZKT9FR[QA]]VWM:V;):EG266:;!!0!S=&"#G3NF' -MMV(?L_#H4["UG\H'BM?!S8Y5TM^;!P;>]_^.M[#W)H3-Z+:P*(JPAF2Z^ -MSXBM,!W,N\%ZDD-#]%*(`T+ZPSS6Q9;PIX^4]SO9.2DKE64=62R@B!MZ-35U -M?4C5^M/N#9D]3\$!V@O4U[`+L^K%C4_G@>WOBZL(3M.3.\9'(V$4DY41?$'\ -M3D=O3Q&1<0#^6Z(G72)^%R,Y5YBJ61N1PN2'"&X8M0/M4W7T?/,J%[Y%WATJ -MBSFV.L>Y%`TAJG;+A@&41W8)?A!FSB3RJ1+,^+ESSZ[7\W2_K2$+HC[QQ,KR -MZ66Z)!BUSJ$Z?$3^%@0B=UCFQ)+ZA).WKI#%R2&JM#^_5T]'M>X6AV>SI]R&CFCX.C%?!^O/W,6UGQ -MZ[7]9S:OLU,6"Q`QLYO\N-,=K0^SVWIZ'3[/1^SM]OL_7V^U5OM=.533Y1%W -MYL$^Q$*^NC+)2@NN!2OI+.RN_<;?&-8,[Z(UKLQ4IO;(V1.58]O'C*S?<^J/ -MJVH_V&Q4*KT+M4LZH,.C4I1>V02I*MTS[$',-+?/"%RYAR5^5RNSCK4VOL6; -M-J"'7Q*VUOJ@`HV>WM(:"3W8Z;)^G/&$^M)YP2K:LUR5PX77*ELG)-->GW-' -MMW--JYF%H:$^("NGI=C0[O5ZE`YUNM5&0$)7!8;BL[@UQ>:/;Z=IBODE\][? -MSX3!T)7BY,$_@8,CQ?_Z#!<&T_^5[(/0D!?R'M6/`ID/Q5)CVKN7FWC*8*6G@T/?UW<@:(JR!H6-MWEJMZLWWL;L>EY)?C2SE5LQ#WM4 -M,G<;-1>B/OQ]&(`L,E8?)=C62K_OK3YC)=&_QZ84CPA0Z+HVMVAEVAR6-P\: -M,J5CS=''4VYOJ;6E=O&C,=Q!ZT9S')$@K[Y560B0U9!V-O'W59^%,^5<8*-) -M#ZD^[I2QI!]Q8,BHS\DY%.QU>G_?3A1T7JPWF=[J=./X%@NIIPI,ET8.@'1[77^O(E1=/N^X'>[>G[)]G=T/8NCUO=/JW.9?#XH_ -M]-^,9V+DLJ)\5/3-R/;^5DYZ<['T7X8WN0VK%"CI7!V[^0/=240=VZN7(SMD -M2M3LZBSJQ&%W1J&K>KL<^UL@>:_,16&Y4Z.GX$[NVZ[@.`%KP+G5?VBOC3 -MV%3Z`,\LG9'AMGT*XZQ^,X(OS2K>PEP)]TX&'HI3_PYE)G/$V&RO%_BW8N]F -MV>:KW:I5<24X<9AKPZY`DB46P_Y`"P!=58)YM5?QCQ4S_(F=O70\IKIE!WDJ -MO\>Q1FJ:@R\/W\#+'^?$-0=V&=BG"Z=?XX>@`[.0>-RV0=C+C2N8>KJLO2#0 -M[D19S[E#Y63I1E__VGJ(```````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``!_[$O(_HQ?VO4_^?__________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_______________________________________________^@$?\B__K'_I_ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_____________________________Z!'_(O_ZQ_Z?___________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M__________^@1_R+_^L?^G______________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________H$PAU1$, -MS1$`%A6]G/PHZ,\&EFE%I)N[L8V+L!6VF+0Q]%A-9N;N^)%$FDE6(DTM-46F -M7@W[O@!2?0B4HY'1,S15%(G!N;XZPPB3-1,=7.^*^)<_P@_<_OW.1'!//"8$ -M>DR````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````````!R_'_CW?X_1W?U -M/E_AW/3SU]+^'S?P]/_^6TEBC_B4ZL_^C3XW_]=/*]8="\$)%.]0KA0X+(H5 -M]F!H."\,BT62$I>'@5#&QW\OY3F,N#>]FNE0AU(AG"5S=S/X>.'21%AWLTD4 -MCBAW/7HT6UL=Z5OST;],TO:"AD\-E.G',K-)>NENIY9I3-$WZ)QZDU]9N>29 -M0F/CYE\V>*]OF^/CE&\%47;1=1&AD+1D\TD@'--[TRL?#/5O/#SXPO[T(P_K -M][AY)NRZ9]SATVBMK&S^\;W@FP\(;;$//S1LW8+A>3=C:7F[FH8QD[/GNHET1Z/!?I -MOJ2)S*X]OP\?#PQ^\O=VX?@6W2*>:G1+K6R>(>FIY<])L9 -M=VJL1P%/>T<\W#?-)GHR3-5]` -M_L>C/ZKZDX&4O.:7YU-X!XH!FU)5]YP?+GW][4@[7UU,8W=JWF_TJU1>9XCK -M[VP:SE[?NW,M@P):A[$DNCG!A]'9MVL@(=!QJR%AC&=_4(P8N$:T+3Q[B=FV -M7**"-.$@#-J\60A8S`RY)V* -M;Q-O3L>/CE@^>$N6G$T>.>*710.G)7=C:YCT_2BS;".E.\N@PI]_/G\T7#.3 -MQ[0&-:B0'-Z1O'V<<.6@06?1EF/)[CL3HI$,;#;U=/0(-2TP3NK8[IR0A[.-_D^B,/K(1^M! -MEQY*P!QVKN]OZ?+,Q?[[(\<>ZBM%FX:K_,N.YD#8"P]RC(6S3*V!<3CHTQ(, -MQV]6=*H;>QZB_6TT_+QY)4%CXL"B^CH\]UE&2=T['*9H.G0Y?J<^43Q9.$K> -MH22SZC)[L%C=?>$O#^SEW_QJ(!`%$8W>R>,7(7^M681K69W26]\GSWY. -M\/?]P+"=7D[S*TSF,)//R:>#S_)BYTVN[V^W_EVNWW>UW/Y>+N]S:^7M[7S= -MO]]^I=6X.@08LT%X9;\UH[YZU?]I^/D\OK*3S;S<&H\ZI;4>:]WN7:W+6?E. -MG]NF<*^SWZ&NI>Y\]@>XHBG[-,FQVNC1&F7EKZ_;^>>&;=M-]RO]R6Q,V[7Q -M]UNY_/R5\6'@VMWY^Y_*7J]ZW"U>)Y2#MIG"]S_/M=SILB?70"+N_Q^:)BMT5M'RUT!Y,N -MF58JZ^7YDJ0K]#(FU^I-ATV"VS\$F'[EWH\]MIXE%3Y9W#?&-%[5;M=_B]OV -M3?G:NW_#M_Y?RP"\T48M\C\7Z9C/N*SQ>6MLW;QV24(K^>5ED'WX>_!UZZ"I -M\ZTTQ*BFBCL+E,"'%O==0`M0_C@O@T)B0PZX&CDP$/6^[Y:B)[UDS.A`B;2) -MHBY3TAHH0CKZ=WQ:HI'[OQR2^,LF07O6FT'#'XPSQ\[TR<$0/QY)M.K507^K -M438@;"KV6T^HXO>#N]9P7Z\_%[XR1LW?%I^`B!T0^[)2ON8[_3^L#27P_C@C -MQ[%\3A2Q^0>VU[B'#X*[K[LF5;4MAQ0#3#,@WI&V83^I\TP@3W\;QD3O3>R5 -MT0V=ERV=U'HFFIP2`W\N`3.#'4WJJW_CO&BNY71#`OG4?8S6L>S'[1>VYEYZ -MY0ZADU[EBH0J[,X11@\E+BJ2M)#]3[7%AV/_$HW8 -MS3:J4F"7)VG9N""U\+P?00_Y#UY?)D@$'VESR?20:]2E/\T*#VK=FP&N*`R8 -MVY]$75*!D\N]+6WL0XO/23C-:%]4V))?._:_/-.G<.S=0DA/+4>!1@/L0V9D-?V>YV^[\W;]W+M -M/Q+E[PP+K0L9(BIQ;_;QMT0A^QDJCBY,O2Y!Q7K^&F$$#L4 -M(IPV?.UX/N^OY/M[WW>#ZY!9;7V_73X<,.GF_;LL[=B>":J(=K1?:8C_WE_U -M%LO@R2F?^B,Y>J)9N*[)6&PY%2M.;1(A?NU=XTJ&0YJ5/8\%":N343"]':[4 -M+#-B?^QFI9(S+8H-BWQHU#]-WP=<Q/-U$**K_ICRR)4R0/N#577:PH3) -MD+X$_K-3F&1-N9?7>6DR8^^VJH=IKM3"0!4_+9:,DXNN&=2G:/O;UMX/P^^# -M3-F$3T]^XKZDGFQLKLUOFGSVX?HU=Y--_U+/PV3=?;?A5@:[ECDQ[*5LD\IT -M0(*(!D4@7^F-\ZL=.F[_,[?T4K-QV=J[\(HH1;)=_RWNY_L2-@>6#T?3[16%SIM5&C?@6N@I-IK3C5U0BZ//[LW7F -MY)R@+*#9<_DLO`:-3>&21M@=YJPTI'%?8==IK#OL;AS;K-XF=)/+DO[\\F_R -M3H>%0VOO9N>'AB7];JX%HZDC%_9S>R[>[R2;8^WSV[>2:,K1&)CX=CE<;[T4 -M/$KV-S,#N:2CZXW -M/:13TJ4ICF.KISXJPYR%8B*IZA@]C[^&Z^NI%[EWV9J`DP7-;I&0`7GLT-*T -M68S:+\.Q/>JG!?O'R]*)XJ40HNGGJ&T1HO*M0CU82;3C<@4)7\XXRE"M,F2Y -MHB*4)1DA>Y2<:.YXO+JDV(HQ3"9/ET66.(]*D+LQ6A?R9YJGTW3],1F^3Y8H -MT++UY"YRQ[8S5=:5`J>NKS,ITG\'^??_I]/.Y,K?$MC2B9V>2W#HFE!> -M><+!<\,F]7LQ^(@>F``9?OEXJ59OBZMCL3=$T/^#+Z)<->>$Z3=@@)"6UA"@ -MG[ZT-/R%.X)$2=[:[/6%R#Z8@+:FN>C,5?.!Z)MIB8OTD5>1Y#1[AS:]=7T> -MC-2PU;[\H5XQMF3JV4_#(LMIIA&[Q\4WBE$7LY>LW)],N!M&&8+$&NLW%::H -M/1'^<.?!!2N^*^:JZTNZIO['HZWV*5$ZI^.B)=@[49[CTX6Z[MOX:3A[!-[@R\$PT_%B!_S::N)WG[ -MDRSIO;+?Y)NB?]:&H!DKZM6A=.$5ITON@!OS2`OS98! -MKRTA]RIG2&S-+"(-RP3.Z(1-,D;&.G)_N<&?=GTT8C&?BB+081P8J;YEFT0O -M<#-]ZBA?WJ7(VYI7T$6J(H%O/=R[O1/OPS\%HRTQ.P6-S_89W^$B1>WM_W]:^+Z_O\/VW0PC;,1F-\5_T3;WW^$G=7S2NQHK7/-GV[9&[-W^]W0O+46H8O^NP,(6TJ*I[5+VDH7: -MMJFWD\%L/W=48F?+V?HMEC_W@M9]`D3PVH#5`,.'`U[[<@I)`>D5RXW[L(,+ -MO0ROMSZ-.+VI7EK.`(N>=2$O++<665H0!*O'2Z5^39X&M@W/%$2M4^7DM&]6 -MB\`N2LY.,O8`,OQ^4SP>?++_.'3#8OEZ772$\J'OP8XUU,Y^>25^U31Y-WS7 -M6*8JEK'K[E@7_TVZ55_\>[!`NMGF)!N[L)'4#ZX(_LCYGJ6C-N>Z@O_T^R'^ -M)5)!Z90@_0JF!V<]DI49DWEMC-J'+7_:3'^PMGP;Y^K-Q5GGWK6HZ\J]/?G@T>'+Y/AY#YC6R#L^^NS4V!] -M[>$9=_#-^>7X5YQ:/N])HZG>GVP[.M;M739"G;EGOMDXM'?A*'ZGB/WW]?*4(EW^38Y7>1-^V#9$P++5>PM*4<3> -M/>PCY'7=5\+T0VKKX89I"YF#(\PH//6;$L4>L6B6':N\/NPS1);FR[T1//Q3 -MR?ISZJWCP2D-W[ -MG*'JXT[=TSK$DBCTY@M/R^$)VSTA[[V]JW4K,:@OAQS5T++<3X5R[7'QSNC% -MK'_6="8K]PYTS6L;\E`BWXTEL75YGGK+WJ4!TI(S:[L$CNI.@2B0%CT!3P]1 -M<7_27E5!WL;UG(N'')M65?Q&6SSAJI23WR\^H]MNBL=ZR'M)H4F33TR$W1T! -MU=C,0'SN7BJ-W,"K -M%QOO<]F2M$4\.A9IZZFT[_4OR[58EPR>UW)#>BB1<9;DY>*RMA*`()49ZEM] -M[,99IRW=?X`BXYHAM7]A=PS5P:=(%57=H108R9U)M\_5GT1&I/[?#IJ3>EXI -MW]Z74FYU1#*^K[YCKT*]Q,H,NF!)0^KX-/QR6K:Z_TYZ4R4X:VK#LH2)JNB$ -M8[T?'KN,61)H33^BB&[.QJH>ED;6]%_Q0/#$=HVN3L=GZ*<_0IKRM7YTBU[1 -M.-)9-O;/IHEM8H,YE_^2]FQ].BW;K";R8T6Y*`+::ZK0:[ZIJ]L^HH::SZ -M/0Y^ST\ZIWSJC(4+X?98M;C_]N])^ -M(53HZ*8TX($G+]VUY:-9>_'+=/@S=.W5+PHZF*`B8X\IGRAJ5\/J^%;0VC`[ -MLANY6SC\^UV?3T2W"A)UKGV"9%E\J:VMIH[S-1!JC-?>^G[*^E5@":,NF"+$ -M>>!?+S1]TZ/QR:]VYDW?-9G93%!]<=+2*AF2_R0N-8<[Z+/N,FU8=3)9=PZYG:1V/BAP2>K'@EBF-DRU2#88(6$37WO%*&F1#_"TYZ-5N; -M_3EK6(;/E_=M3Y+>MV.S:-R9R=+2!1:)9\H(>A^8_OI9&OGQN&^O)=DR\5NE -MI<>J8T=Z]\U:M^>W#-2GF$1N?X[Z_Q30X9P,S@TNI<0RT9N9=,@2Y[JZ9@6Y -M.&CA_ZTU0XO7;J&[HA]$SP&AY6/CNY=1R#Z74\][R<9;Y<;HB?8KSP^*[E+[ -MR[NK`\G_J%%BE,P\+13D&W1H&3>JIRQ0EFZ)+$P2#+0XKA#XTX"U@?OKR(3= -M,;ZANS"2[L,4V<*F^XJ8>]+EG[;^DT=&6M)AM.GDZ%=BL$6+J_`'R3 -M:"GO.!J6#H<&8LH[&+YXWW@S_,@/BB'G%U'[(@1/A[T1\&;33W[]_YP-;%R6 -M,8U<;LI*(XO'DW:VKDN\D]\C)@[=KY,=N\5H47JOL -M4ZANF2@AJ?QY)>G-Q8UH-+K86YG4L;$8ZFW4,-:S/!>Y*.]LA1<4TZJ0`V[Y -MN2DN3TA`W=TTX]IUHKHK2T>VI8@OJ`F(4O[-6/?Y+UY2T);XWYS-`=]B=T@I -MN*(CHZESQ]6;1YL8MD?WT!6\.>OCE"(4OG\'R??L=[^_@E!/TN8_8SOQ^=9* -MP=);;NG!/TN`>3";_*,7[/PTHS/XL]$S*:T;0T??*;5WCEUN5$:=14A&D&D< -M7DRX1N;>_M=0#F6RTCFW!YY.0>61>#-$51:-G#Z2DQ)OL\G3X6L/SBN[CT:D -MNI6[CS2"[)Q%!+IS^+ZE -M"(]D7KJ7+_U\?Y_GRO+3Z$*QX-CEG&;*V/'AYXQ.TQ7Y9CJ8C:-JTJ9/)$LM -M2`7EE7CU-L(6T.8GGX^+SP]HLT^#]-1\MWBYCXS,L`*04ZELG,ES,U'9#]T; -M\&3I!];V3@R>2(Y>\.6=8T_<+D1EBZ8]$09U-5KR>/%(AO[=%W*8IF3K=F= -M(3Y101HFZ?XV/OB2R<=PV:.D([?/+*I\5/[U.&*I4-8A"E@-W[?#[>9`,=JN -MT53[_MZ_&Q%&/!6DY^S:EH&B]H;W6=?&+$X^3I[)T-=T`#JJ,X5CEJ0,QRCI[7LGM?/`\\<4W8*9?^ -MD,,O3S%F"E.^;3>?0WW>>IKO_9>DRVB1N%4W'0*BD5I1V$;(E;Q]4/@P4,VZ -MRG_8>V?EFV6]8/EO]#Y-BGT$,F-=>KE[D,/F4)/2E+O11(C@VS=3WJH=&S#Z -MUEZW[GGB -M5L]F^A*F/;6",TZ&LR0(=$R1_?CEV.MD)6N.KNKL)"Q]C\_HG!EWY1^S8%W1 -MSF[^_8,BDQ-P23TP%O/7MD:^9F7"DG5KZH@:6-4Y/:%QS[$'F`C)I/R!U]M& -MYFTQ!/OX4'O]SA6I$F:"1B$$U2@_1W"QN$['*?N_`&^2.#+J/L.G?]F?>CJI -MNK$CI_5O9J.QOS:W,1N--&?B-]:,H?U'QXJ4>>I7NI? -M1R/\8OR>]^QCRK1LUPB45VXF)M"(-)BT0CA;F_GW?-=7*MFR5-5SM01[FSVO -MWGMMD!--4&EKBGP1DJ88\Z<+Q0K^VX%`JM$UDW!)RG0!S>S\]?#>GORZJK@^ -MSA6L;S9O8I39_"'OH.#V]/BAG(V$O\7]<7*?]>3$)3NRO+/P31;-_)R6YHM+ -M0=07,?8;/HRQ,%%"/5&Q3C&DV-:7HCD*RBIP344+N7SCMU]1`IE!*18+-`IP -M(57D$KG&-<(7DY -MQ0\\AF,WYT?P5VI1P:@`L-U3U*G[SQGM1.<-NUYZ-KW-IL.)=/+&(N_,E[0F -M3(33DOBB;SR1#I&-)K$VB]<9O.UU/VUV`EXYYN&H&=2NDZ8(Z9O( -MBZ,PWF5,.$)J9==N($)UFSVGE+LF]^,C,^3R8.?R5SRW@YK[_)6'J/1/K5N= -MVU:==F-[GXYMU_&.K5;UCW(F0`EQ]+ -M0N_R4RA9\7XL;N@+'&K@RU%`R/DBIE-9)#F4\F%76COU^S6"\Q11HS\5#NMB -MWFBG2F\R1E=M,0K5'KQ)QW_DI,04KDYT:D./HU!O:U?RO83D,0BGM313Y@:P*+>I2SWB[-/H?C -M[FJN] -M(N]^.:AM66IM<[Y)96_C\U<#HQ9HBF+LSDCZ>`7TJ<]9W3BG;N?)\VQ/N4'` -M`W__VG1P```````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M````````````/_E+Q/[,7]KU/_G_________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_________________________________________________________H!' -M_(O_ZQ_Z?___________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________________________________^@1_R+_^L?^G__________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________H$?\B__K'_I_____________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_Z!,`=$5#(T7Q9V;W,^%<[-7=@+1MD#N]V=(H:G#Q/=(`AA--ZA)I@\`SL8V -MT\;D&?>M2!R0!DOP\\./&QXPV1=7?1(/.9RZNKNZNKKQWGQ*OX1?J_5X.4KI -M7=_DN>RP```````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````]7?Z>=_S]7/Z'_'T_SZ'J7G8OY\[H<_U^_<]3X -M^G*78Z'%@/H>I'0Z,(3<_)L6QFZT#(>Y#/O>'I]'H_<*=:?`W*=*-,E-&B1W -M%@F0W/=*D#ITW8;Y_W5:/4@8RP_?AFD7WKCS/@7)H]+L1IJ[2+S*'#(,7W6U -MN5F<73-";Q6MA'#.]Z>C;#!%T6]3K7X`N=_9U9--3^T'O#]'T[_//Y -MWTH>;W,V>CGY_Y/Y=C8\L&01#`V?N9^_=`^UZ?9L_?$K_ -MJ*P%"\:XBTSX"YTN57_ET:9PUG?&KC!T#(XU@Z(H)M.MCXVC`DF9QAV?_!Q5 -MLW*/.QO#/X!&?\._%/#TZWLE@T_]^?],.0'3\5*>/1U$C3Q>`0@L::NG"!4M -M/W.T^S^GN>CFZ?6@N@2`<1RL`U7+CRC5@29!,>/[>FKU&*UKZXJCN%^S2ZG- -MB`]*#(YVL,%!/I[OE]^<$ZO0T?!^AO"!JK##VOMU/'5V]*KP7&DM7+]\;=-H -MXXN9'5&>>5N:/[)FET[,S)4R"@?.L\4A&IYKPQ9_[CKK%!HKUQBB(:<8,UV_ -M-'[(2!SS=.NH^VGK^Z^;W.WI:/@TY9Q7==8@:>N-D&]2`E2VI'?K^JII/-^H -M[PL(JDL>0926S!'E@D'Z/4ZO[UJ7UYNM73C"^N^E3Y2$"7BNBU^R"E2I1D=P -ME$H;YNE7Y)DOZ]5/HOB]7EU^R#100\_[L,6CKIZ6W`@/8WVK_FF*$_KO#;^V -M#)]OZ?7_Q\W2O?*_E[G_M9/,#=';TL_P1M6^A<^'[J3CI_=%OP05+,6G$Q=' -M@2Z<=_&_=!=YU9\&$S#7GH4=(8;++7&-WKO1>*]6>HEE_XWGX02:]6K/] -MXB"R<="=Y>7(3=$=F0(J@EH6`N249QM"FA;\9"HJRY"EB(==`E[4*3L?1-+I -MFX9[CNC@V3=\GQ;DZ96QH>C%MN4HE9"R03,]B.#?5\%/.LBUOVKNPM[@^$)19E-9HX1W=F7.%0/S:+=WTNWQ -M[?%D&'W%BA>CT^2_N3S>?G?TSN=&/:_+Z57+Y`7C[ -MV>CV_E_5Z)\.5+6J$[GU[:;\$,UFB(S)M;N,(9UTC-H -M*]E97YMNJP8;'OU$%Q,%3>:<5^V)EF$<[RK"1;16R:K?,7^*A*UT^/L>2LDC@BA\&]:KUY1*!KO.(#XQ>T;%?V]5\\O=X[SV26E.7R): -M2WLQ!=O/1QY:=Y5C!'EB+X"TY>YP_'PB6[+8)7S4WX\"FY"LR-6K[E+GY7!= -M&":IE5-4MJM5YI#+X.GL:LC4NO1!^SJH43I[?:Z_2D][:;H,6/67;_KG;^D+ -MYA!V$Z)91L=QF'<6TMB93A_ZS*^)IZY -M#*L*$MR>X\/'_Y!W"\V(_Q2_99DTHAIM4N3(&D8F\YT[>I!0VQXHPF1=+2OU -MV5A;ITT1K=UDAQF-MEYTAMRDF/PJ?A^'L^&5O@V$/OBWSX'TX?YM1A8JX@H5 -MA[?\B[P-VT]9JV!^($I<,I@HHCHRJ`UP$.R(P9WN7Y8-.O@>+&:>F92NE<0K -M"3-[^(;W0Z,SW\/I\T$Q'\K[XMLI:\C/*7JR#SB?JCS,B`?>S',6^[-)MF6D -M!KT>KW$@3(G!Y*G\C\&=M^BCM5E-JF5GV="Y?,WTA1]>5[YY2"EY=B@W4D92 -MM\(W)C2X)\'O5]%H4V.[&U2K<-I55B[9JP-W:WM2$"#Q`=LIB1U.^>/1"L86 -M@R1[/B-^N290L24:_HFJ;T^JX8#EG+23(L5CWXI0<>E@NCQV!VVR"IJWZ?#W."E69,E;N6D1Q -MA].1D/-@3!LTZ21Y&L3=?!MXT]Q^\"@\2+\AS>QU1C_?(&-AWY&=ZM2L/W5Z -M*0"EH!E2S="%%-;8U-7%#R0J130TYF=2OSU;-&S'+CANGK,SC=&>(Z+UD6TK -M8!/`%HYQ\>5#O,`9]84WZ=*T(]W!L[&+#$U](CR^.F4,]?OT)8GNKZ_?T;9( -M2IE/6@#S.LB3I8NVWTH;#KXQ!483RP0ZCQQ^G.NO7R*W43+\ -MR":5G4`$X9UVN!,O^03EJW5!F6RN_CS@AW-+>D`;.@3< -MORFC%-UJ&U:"I6^72'_I98>XNMNSRUH!(0D]BG@. -M.)>9\:2Q0A7X)*]XS%3&>,HIR)(XDVI(US+VN$0PY4'6V)RKC*Y)5'0EF#$M -MJ-0$,[),L*"*!.1> -MV8?*4L?W;&8'AC%2$JYLY3DZI&U>+!=97.U4/!&U7O'&\?:\$G_%6G(=&K1N+?F7:"^X,+FCH5:1/&] -M(^6JGIQT2FTJLDK!]'PS[%.C9XTD7\-=ZSHYYR^U^M&#HR1V/UYW;%I&'1;& -M7!+PT#\R-NTI$$Q8`LVHY.]/3`BJO++^L?:RQ:$^R&>7/N -MD`WM69`/+M7(R0=P=79>:\;L^2ZU97C+L^GVKG^#TW\:2FJB+%GB!(2\=NP1 -M(<6"5%LO%@KI:E?-7V],$ZT`M757:1Z'6U-?._&&E?WP]NKS4C<"`;C.8]CQ -M!BM72J$E5NT*L\F&:";.5.,-%=+?*\UG`5,@7=DJO:WDRW(/P:FUD]Y4,`>C -MSZTM+[A_N)*];$RW->5"%N%)MZ7V[<6/7'8YOT)*H&#T2*4L5\X,Y'C_MY!G575T. -M4HO8U`5?ERZ;"K8A#Y,LG]NE`DK'\Q.T9`X';653%K:](_(QA>^+2^ -M>[@GAO2HN67TP&V+V[7(QR=>TA6TZ>QV+DJQ\$\FS1[L2UE=?&N6+FUY2VEM -M0D1B#`ZVLGGC8GZ\9-]1AK*^;REXKANB7SD;*F;QO,[#A5*VXU)H`6;K9FG3 -MV-;3K]KO^]^LDC:SO_O&;YY3V.E#Y"9QF$KIFFKY"9FU*]0XG[(O[[ER9RD@ -M%&#\((LLKZ\/BA/TLD)_N:'>[&7LECO;NSDTPJ'7S/X]#GYL66'D]O^4&0.[ -M;WB9B^69-5ZZ_Z/'4@793?W*S&5ABF5(Z+#&&O8R/+QBW.J[5===>%4H>]+N -M;SP]ZG1FWA[._!MQ\N=K;'EMTHE>-M*X[6!'<=Y-U]"8W:#T@+7IGD>CI9M& -M&>.;5O>0#EU.UB];V=C0R[$BLIW[Q)QJ/0/V#HU7X=`C"F\,QYYK5T.+GM]E -M,5$E_B`"O'+:-/.C,7C^`XXOA"`/^F\;7XEV-VQ=;,\?<\%QV$T=8UQ]#241 -M[8/!M/(1@V6M0OC#0F\U;XFEIQ#+?D<&"R%>WJC:UCE2K!Q$"R8W4*+6PP5) -MC3=3[NI-AI0\D-=[.U[L=,GR*S53#,"R-39V:.&#YNEQ'V5I?^IY(MXJ3&CP -M^7?LW-F7$[3C-T(^][V*[=5!H]Z\N_$XVJ5`!,7FP[.6GOHXEAC;N2>5^._P -M:.ENC)!O0-]`1=\JG&?6[Y/6>7DE"W?8D]$:.X3A?ICD3S)+0U'@?&?4*W@I -MN8KNP2RL),.A]+9Z`C;K*]7^*QF`1^-V>\I3L%7CS)5NGQ;FK(P'$8^#%)G( -M(@:[UV`>;Q*<0!Q\5ZKPJ>/'XHL@_6M+<\5997`>9TB;)JNA#J`*O\,)8SC:N(JU_='9PQ_/;[OSX[ -M@FM0M)F+*VOK-N-[DY0)EF_PYH/(PSY/6;-Z]`Q:(?$XIH]U+:<`_`57/1$. -M1'2O7VZI1SOGEPU;U=]>&25%&B2=;5UH='_[7,N-ZF/X!*FZ%9-Z>62UC_#N -MX]Q_PH]BQ_P69O#7E5?G4U;:&,XL$:M*QY%N70_G]\:7G2F8V)LG5JMB?2]! -M7,!,K("PQ`5(1DKO.+9SA/>%=]V(/GZ/N)Y\$KJ_VYG(^$OJV=X39O\?+M_5 -M>C,V7>,/ONV]K6S9+4LZ2RS38(*`.;HP0Y-"9O1;3F3V!1%6$,R77V?$5I@.YEW@O4DAH?HI1`& -MA?6&>:V++>%/'RGN=[)R4E(R+B`?RW1$ZZ1/PN -M1G*O,52R-R.%R0X0W#%J!]JFZ^CYYE0O?(N\.E4652)9GQ?7:_FZ7]:0A=$?>.)E>72RW1(+E:*LHEEZQ-XL[T6 -MN=0G3XB?PL"$3NLIVS%BD#X7O8KQV]=(8N20U -M5H?WZNGH]KW"T.SV=/N0TV]/0Z?9Z/V=OM]GZ^WVJM]KIRJ:?*(N_-@GV(A7UT99*4%UP*5])9 -MV5W[C;XQK!G?1&M=F*E-[9&R)RK'MX\96;[GU1]6U'^PV*A5>A=JEG5!AT:E -M*+VR"5)5NF?8@YAI;YX0N7,.2ORN5V<=:FU]BS9M00Z^)6VM]4`%&SV]I#02 -M>['39/TYXPGUI/."5;5FN2N'"ZY4MDY)IKT^YH]NYIM7,PM#0GQ`5T]+L:'= -MZO4H'.MUJHR`A*X+#<5G<&N+S1[?3M,5\DOGO;^?"8.A*\7)@G\#!D>+__08 -M+@VG_RO9!Z$@+^0]JQX%,A^*I+D++;=<1HUU*?X?H(RZRD-O&2BL:LAMQO_U -M]N@4GYF5(J+8Z-L@3K8U[T>U=R\V\93!3F7*[828'L//;'E'!S/KRT\&A[^N -M[D#1%60-"QMN\M5O5F^]C=CTO)+\:6]JAD[C9J+T1]^/HQ`%ADK#Y+ -ML:R5?]]:?,9+HW^/3"D>$*'1=&UNT,NT.2QN'C1E2L>;HXZFW-]3:TKMXT9C -MN(/6C.8Y(D%??*JR$2&K(.QMX^ZK/PIGRKC!1I(?4GW=*6-(/N+!D5&?DG(I -MV.KT_[Z<*.B]6&\SO=3IQ_`L%SD6H0/DDFWX?+;]G?T>SU-.%)DNC!T`Z/:Z -M_UY$J+I]WW`[W;T_9/L[NA[%T>M[I]6YS+X?%'_IOQC.QM*H4L`'"M;'1XZDM7I\=CE7+PU;U=C -MGVMD#S7YB*PW*G1T_`G=VW7!PJ?0!GED[(\-L^A7'6/QG -M!%^:5;V$N!/NG`P]%*?^',I,YXFPV5XO\6[%WLVSS5>[5*KB2G#C,->'7($D -M2BV'_(`6`+JK!/-JK^,>*F?Y$SMZZ'E-=,H.\E5_CV*,U34&7A^_@98_SXAJ -M#NPSL4X73K_'#T`'9R#QN6R#L9<:5S#U=5EZ0:'````````````````````````````.:3$/7L`0`<` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar_ppmd_use_after_free.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar_ppmd_use_after_free.rar.uu deleted file mode 100644 index 136338653..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar_ppmd_use_after_free.rar.uu +++ /dev/null @@ -1,10 +0,0 @@ -begin 644 test_read_format_rar_ppmd_use_after_free.rar -M4F%R(1H'``1G=$Q26`!W````>U!+`P0R`'#_J7\`+@TU'`#]`0`7__]"0D)" -M+W5NTQ26`!W=&@`[E!+ -M`P0Q`'#_(````"`@(+<@!/T`("`@("`@("`@("`@("`@("`@("`@("`@("`@ -M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@ -M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@(`1G=$Q26`!W```` -M>U!+`P0R`'#_J7\`+@TU'`#]`0`7__]"0D)"+W5NTQ26`!W=&@`[E!+`P0Q`'`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar_ppmd_use_after_free2.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar_ppmd_use_after_free2.rar.uu deleted file mode 100644 index 03c2eadfa..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar_ppmd_use_after_free2.rar.uu +++ /dev/null @@ -1,10 +0,0 @@ -begin 664 test_read_format_rar_ppmd_use_after_free2.rar -M4F%R(1H'``1G=$Q24`!W````>U!+`P0Q`'#_J7\`+@TU'`#]`0`7__]"0D)" -M+W5N)B8F)F=I9`UD#1T+``!"`````````&%R(1H'``3_________`F@`H2`` -M``"`P\/#2\/#P\/#P\/#P\-3PP"`P\/#PYZ>AYZ>GI[#4\,`@,/#`L,@(""= -M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@(/______ -M__\@("`@("`@("`@("`@("`@("`@("`@("`$9W1,4E``=P```'M02P,$,0!P -M_ZE_`"X--1P`_0$`%___0D)"0B]U;B8F)B9G:60-9`T="P``0@````````!A -0$```````````````````````````````````,`R`0`< -M```````````````````````````````````````````````````````````P -M`0#``@``````````````````````````````````+G1E>'0```"8&0$``!`` -M```:`0``!```````````````````(```8"YR9&%T80``%1P````P`0``'@`` -M`!X!`````````````````$```$`N9&%T80```"S_````4`$```(````\`0`` -M``````````````!```#`+D-25``````0`````%`"```"````/@$````````` -M````````0```0"YR$````!@`@``0@```$`!```````````````` -M`$```$`````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````````````````````````````(#Y0',6@/D@+5"08]]CWVH/8`(E$)!R)5"08"\!U&(M,)!B+1"04,]+W\8O8 -MBT0D$/?QB]/K08O8BTPD&(M4)!2+1"00T>O1V='JT=@+VW7T]_&+\/=D)!R+ -MR(M$)!CWY@/1<@X[5"04=PAR!SM$)!!V`4XSTHO&3W4']]KWV(/:`%M>7\(0 -M`,S,S,S,S%=653/_,^V+1"04"\!]%4=%BU0D$/?8]]J#V`")1"04B50D$(M$ -M)!P+P'T41XM4)!CWV/?:@]@`B40D'(E4)!@+P'4HBTPD&(M$)!0STO?QB]B+ -M1"00]_&+\(O#]V0D&(O(B\;W9"08`]'K1XO8BTPD&(M4)!2+1"00T>O1V='J -MT=@+VW7T]_&+\/=D)!R+R(M$)!CWY@/1<@X[5"04=PAR#SM$)!!V"4XK1"08 -M&U0D'#/;*T0D$!M4)!1->0?WVO?8@]H`B\J+TXO9B\B+QD]U!_?:]]B#V@!= -M7E_"$`#,48U,)`0KR!O`]]`CR(O$)0#P__\[R'(*B\%9E(L`B00DPRT`$``` -MA0#KZ<.+5"0$,L"`.E)U*X!Z`6%U)8!Z`G)U'X!Z`R%U&8!Z!!IU$X!Z!0=U -M#3A"!G4(B(&P<0``_L#"!`!J`/^QK'$``/^QJ'$``.AX2```PU97BWPD#(T$ -M/U"+\>@DF@``B0:%P'4.A?]T"KE\7D$`Z"@B``")?@2)?@A?B\9>P@0`5E>+ -M?"0,5XOQZ/69``")!H7`=0Z%_W0*N7Q>00#H^2$``(E^!(E^"%^+QE["!`#_ -M="0$@\$P4>C$G```]]@;P$#"!`"+1"0$5HOQ`48$BTX$BT8(.\AV+XO0P>H" -M5XU\`B`[SW8"B_F-!#]0_S;HR)D``(D&ASH#____XO.Z/)!``"+V(M%\(/`\%#_=>R+SNCN2```,_^)1?R% -MP`^.@0```(M%[`/'@#A2=4-0B\[H5_[__X3`=#>`OK!Q````=#:%_WXR@_L< -M?2V#??P??B>+1>PKPX/`'(`X4G42@'@!4W4,@'@"1G4&@'@#6'0(1SM]_'RM -MZRQJ`(T$'VH`4(F&O'$``.C%1@``@+ZP<0```'40:@>-AEA*``!0B\[H8$@` -M`#/`.8:\<0``=18Y1>P/A-,```#_=>SH:)@``.G&````.47L=`C_=>SH5I@` -M`(O.Z&8(``"+SNCF_?__9HN&PG$``&8[AKA*``!T(6I\Z""/``!0C888!``` -M4.AZJ@``65GH@?W__X!]"`!T>@^WCL!*``"*AL!*```D`8B&LG$``(K!P.@# -M)`&(AK%Q``"*P=#H)`&(AK-Q``"*P<#H`B0!@[[(2@```(B&M'$```^5P(B& -MM7$``(K!P.@&)`&(AK=Q``"*P<#H!R0!@+[,2@``)(B&N'$``'83:@&Y?%Y! -M`.@C'P``,L#I3@$``(3`=`WWP0`!``!U!3/)0>L",\F`OJA*````B(ZV<0`` -M=`B$P`^%[0```%:-3>#H+9\``(N&J'$``(N^H'$``(N>I'$``(E%^(N&K'$` -M`(E%_,:&MG$```#K58N&I$H``(/X>G57:-PR00"-AA!8``!0Z`2:``"%P'4' -MQH:S<0```?:&Z%<```%U%X"^LG$```!T%;@``0``9H6&P$H``'4'QH:V<0`` -M`8O.Z(7\__^+SNCW!@``A") -MOJ!Q``")GJ1Q``")AJQQ``#H<)X``("^LG$```!T"8"^MG$```!U(XU&%U"- -MAMUQ``!0Z,^8``"-AA@$``!0@<;>=0``5N@GF@``L`%;7U[)P@0`5FH!B_'H -M[=0``(M&!(L.BE0D"(A4"/]>P@0`BT0D!#M!"'8+*T$$4.C*U```ZP.)003" -M!`"+1"0$.T$(=@LK0010Z"+\___K`XE!!,($`%:+\3/)C88P#```B0B)2`2) -M2`B-CD0,``#H*M@``(V.:`P``.@?V```C8Z,#```Z!38``"-CK`,``#H"=@` -M`(O&7L-6_W0D"(OQZ!+\__^$P'4B:GCHAXP``%"!QA@$``!6Z.&G``!966H" -MN7Q>00#H1B```%["!`!6_W0D#(OQ_W0D#.A*0```A,!U!#+`ZRYJ`(O.Z,?[ -M__^$P'4?:GCH/(P``%"-AA@$``!0Z):G``!968O.Z%`]``#KT+`!7L((`%97 -MB_GH3.4``(MT)`S_=@2+S^@,____BT8$AP@0` -M58OL@^P,4XJ9!%@``%:+=0AJ`%:`XP'H>@T``(3`=0\'G`HU'`5"+SNA] -M_O__5_\V4^B>V```BP;&!`<`_S;H#)8``(OX5XO.Z%W^__^#?0P`=!6+30R- -M1?10Z$+___^+30Q7Z%S^__^%VW1'4^A>E```ZS^+70R%VW0X:@"+SN@+_O__ -MC46\G""`!35597B_'HMSL``(V.(`P``,<&X#)!`.BVD@``C8YH#@`` -MZ&:!``"-KI@3``"+S>BG7P``C;Y\2@``B\_H*=8``(V.T$H``.C6_?__C8[@ -M5P``Z,O]__^+1"04,]L[PW4"B\6)AI`3``"*@($M``"#CFA*``#_:AB(1A93 -MC8:X2@``4(B>L'$``(B>L7$``(B>LG$``(B>LW$``(B>M'$``(B>M7$``(B> -MMG$``(F>O'$``(D?B)ZW<0``B)ZX<0``B)YX2@``B)[`<0``B9Z@2@``B9Z@ -M<0``B9ZD<0``B9ZH<0``B9ZL<0``QX9P2@``!P```(F>=$H``.B8DP``:@U8 -M9HF&PDH``#/`7V:)AL)Q``!FB8;>=0``B9[(<0``B9[,<0``B9[0<0``B9[4 -M<0``B9[8<0``B)Y@#@``B)Z($P``B)[=<0``B)[!<0``B)[<<0``B)ZH2@`` -MQX:\2@``Z0P\``!6B_'HS/____9$)`@!=`=6Z*"8``!9B\9>P@0` -M58OL@^P85HOQ@+ZS<0```'4',L#I[@```%-6C4WHZ`2:``#VAL!*```"#X2( -M````BX:\<0``5VH`@\`4:@!0B\[H0$```(O.Z"<"``"+?0B+7P2%VW9.BP=3 -M4%")10C_%7@R00"+=0R%]G0YC4,!4(O.Z-K[__]J`(O/Z)S[__^-0P%0_S;_ -M=0CH!=8``%.+S^BA^____S;HR<((`%:+ -M\>C6/P``BXZD<0``.\I_(GP*BXZ@<0``.\AW%HN.K'$``#O*?"Y_"HN.J'$` -M`#O(=B)J9^@%B```4('&&`0``%;H7Z,``%E9:@&Y?%Y!`.B!&```7L.*@=A* -M```DX#/)/.`/E,&*P<.`N>1*```"=PWV@?1*```(=`0SP$##,\##BH'D2@`` -M/`)V'(J!V$H``#/2).`\X`^5PDJ#XO"#PB")D?1*``##@#WX34(``'0*N?A, -M0@#II=@``(M$)`1`P@0`5HOQ@+[P2@``%',5]H;T2@``$'0,N.````!F"8;8 -M2@``@+[D2@``!G(+R\9%_P'H2#\``(/X"'05B\OH#O[_ -M_SEUS.G(!P``QD7_`.MRBX.0$P``!1@H``!F.3!U,FB`````4(V#&`0``%"- -M0Q=0:@+H.1```(3`=1:+R^@W-P``:/\```"Y?%Y!`.C8&0``@+O,2@``)(VS -M(`P``!K`_L`/ML!0BX.0$P``:@!J`%<%&"@``%"+SN@=$0``B77D:@>-3XV#K$H``%"-3N-N[1*``!7C4W,B8.P2@``Z$1Y``"-L[9*``!6C4W,Z#5Y```/MPYF -M@_D'```BT7T`8.H<0``@Y.L<0```.D;!0``C;NX5P``C;.L2@``I:6EC;/`5P`` -M]@8"=`^-@\17``!0C4W,Z'MX``#V!@@/A.D$``"-@\A7``!0C4W,Z"1X``#I -MU00``(/X=(V#T$H``'0&C8/@5P``B_B-LZQ*``"EI8E%[(/`#%"-3R-1A!0C4W,B47XZ!YX``"-1A10C4W,Z+%W``"-1AA0C4W,Z`9X -M``"-1AQ0C4W,B47(Z/=W``"-1B!0C4W,Z(IW``"-1B%0C4W,Z'YW``"-1B)0 -MC4W,B47TZ)%W``"-1B10C4W,Z,1W``"X``$``(U^*&:%1@AT&E>-3)EMP, -M``#HQ>___XM-^(L)`\&)AN`,``"+1?0/MP`3U[__#P``B\^)EN0,``!F.\%S -M`P^W^%>-A83O__]0C4W,Z%AW``!H``0``(V-A.___XU&,%%0QH0]A.___P") -M1?CHL,D``(M&!(/X>@^%AP```(M%]`^W``^W?@HK^+@`!```@^\@9H5&"'0# -M@^\(A?\/C@T!``"-CC`,``!7Z)_U__]7_[8P#```C4W,Z.QV``!H[#)!`/]U -M^.B-C@``A<`/A=T```"+AC`,```/MD@+#[90"H/`",'A"`/*#[90`0^V`,'A -M"`/*P>$(`\B)BVA*``#IJP```(/X=`^%H@```+@``@``9H5&"`^$@P```(U- -MK.BJ$```C86$[___4.C"C```BTWT#[<)C;XP!```.\%U+6C_`P``5XV%A.__ -M_U#H\L\``&C_`P``_W7X5^@7SP``_W7X_W7XZ/+'``#K(6@`!```0"O(5U&- -MA`6$[___4(V%A.___U"-3:SH41```&:#/P!U%+C__0``9B%&".L),\!FB88P -M!```B\OH./K__[@`!```9H5&"'01:@B-ACP,``!0C4W,Z-YU``"+100#&@\!Q```!Z*L0``"`??\`=!5J`(U-S.B#=```]]!F.8.L2@`` -M=7+_=?CHF,<``%#H4L<``%!J:.CC?P``4(V#&`0``%#H/9L``(/$#.M*C;NX -M2@``C;.L2@``I:6-@\1*``!0C4W,I>AV-3?@``4%;H/IH``,:#>$H```'K-XN#K'$``#N#I'$``']0 -M?`Z+@ZAQ```[@Z!Q``!W0&CP,D$`:FCHI'X``%"-@Q@$``!0Z/Z9``"#Q`QJ -M`[E\7D$`QH/`<0```>@8#P``.7W,=`C_=R`0``@+X`6```)`^'I0$``#/;.9[L5P``=1#V -MANA7```"=0>P`>FF`0``C;YH#@``B\_HBW(``%>-C0R=_O_HN^P``%.-C0R= -M_O_HW?(``#E=#'4@_[;P5P``BTT(Z(/P____MO!7``"+10C_,(O/Z/MS```/ -MMX;H5P``J`1T38N.D!,``('!&"@``(E-_&8Y&0^$`0$``(J.`%@``(#Y)!K2 -M)0`$``#^P@^WP`^VTE+WV!O`4XV6'&0``"/"4/]U_`^VP5"+S^@^B9U0``C8T,G?[_Z$#P``#K*8V-#)W^_^@S\``` -MZ6[^__]H<`0``.@[?```4('&&`0``%;HE9<``%E9,L!?7EO)P@@`4U565XOQ -M,]OH/O7__XOXA?]T.8ML)!2#_7MT"8.^I$H``'MT)T/VPW]U!>A]Q0``.:ZD -M2@``=!V+SNB3ZO__B\[H!?7__XOXA?]URS/`7UY=6\($`(O'Z_565XOQZRR+ -MAJ1*``"#^'MT+(/X>G43_W0D#(V.X%<``.C)ZO__A,!U&XO.Z$GJ__^+SNB[ -M]/__B_B%_W7),\!?7L($`(O'Z_=5B^R!["P"``"-1?Q0_Q6L,4$`A``@V7P`(-E]`")1=R-A=3]__^)1>2+10R)1>A6C47<4,=%[$$` -M``#_%;`Q00"+\(7V=00RP.L?5_]U$%;_%;0Q00"+^(M%_(L(5E#_410SP(7_ -M#Y7`7U[)P@P`58OL@>Q8#```@WT4`%-65XVUJ/O__W0M_W44B\90Z-&'``"+ -MQE#HGX<``/]U%(VT1:K[__]6Z+F'``!6Z(F'``"-=$8":(4```#HMWH``%!6 -MZ)Z'``!6Z&Z'``"-=$8":/@R00!6Z(F'``!6Z%F'``!J6#/)9HE,1@)>5E&- -M1:A0Z!6$``"+10B)1:RA>%Y!`(E%L(V%J/O__XEUJ(MU$(E%M(M%#+\`!``` -M5HEUQ(E]R(E%V.CU4@``.\9U%E>-A:CS__]0Z-S^``"-A:CS__^)1=2`?1@` -MBQTX,$$`C46HQT7<#`@!`%!T"/\50#!!`.L"_].+^(7_=2K_%3PP00`]`C`` -M`'4;,\"`?1@`9HD&C46H4'0(_Q5`,$$`ZP+_TXOXA?]?7@^5P%O)PA0`58OL -M@>P("```4U97,]M3_W40Z,%2``"+30B)11#H<\$``+\`!```Z:P```"-A?S[ -M__]0Z(12``"+\`^^!E#H]DX``#A=#'0A.L-T!(@>ZRY3C87\^___4.C,40`` -M4.B93@``A,!U<>L5.L-T$6C\,D$`C87\^___4.C_A0``@+W\^___*HMU$'4S -M#[Z%_?O__U#HHDX``(3`=")75HV%^O?__U#&A?CW__\NQH7Y]___7.C?OP`` -MC;7X]____W48C87\^___5E-0Z`I2``!0Z,Y+``"$P'4?BTT(5XV%_/O__U#H -M9\(``(3`#X4\____7UY;R<(4`+`!Z_6+B0!/``#I`<$``(N)`$\``&@`!``` -M_W0D#/]T)`SH[<$``(3`#Y7`P@P`5HOQC4X0Z++1``"+SE[IJM$``%6+[%9J -M!?]U$(OQ_W4(_W4,_[;X3@``Z*O^__^$P'0$L`'K+3/).$T4="2+AOQ.```Y -M2"!T&6H%4?]U"(O._W4,4.B`_O__]M@:P/[`ZP(RP%Y=PA``58OL@^P,4U:+ -M=0A7C48P4(OYB44(Z+Z"``"[``0``#O#75OI']```%:+\>A-____B\Y>Z91+``!6 -M5XOQZ#S___\SP+^H````5\:&PS8```!FB8;4.@``B(;T0@``9HF&]$8``(B& -MP#8``(B&P38``.CUA0``687`=`F+R.B6OP``ZP(SP%>)AO1.``#HV84``%F% -MP'0)B\CH>K\``.L",\!7B8;X3@``Z+V%``!9A)A@1/``#HA84``%F%P'0)B\CH -M)K\``.L",\!?B88`3P``7L-6B_'HXDH``#/`B\Z)A@!/``")A@1/``")AOQ. -M``")AOA.``")AO1.``#H"____XO&7L-5B^Q=Z?J;```SR6H(B\%:J`%T"='H -M-2"#N.WK`M'H2G7NB02-P%%!`$&!^0`!``!\V<.#/<1100``=07HR/___XM, -M)`B+1"0$5HMT)!!7A?9V&_;!!W06#[81#[;X,]?!Z`@S!)7`44$`3D'KX8/^ -M"')_B_[![P,S`8/!"`^VT,'H"#,$E@(,P25P%%!`(O0#[;"BP2%P%%!`#-!_,'J"#/"#[;0P>@(,P25P%%!``^V -MT,'H"#,$E@(,P25P%%!`$]UAC/2A?9V -M&E,/MCP*#[;8,_O!Z`@S!+W`44$`0CO6C3MP``BT7\)?\_`(!Y!T@-`,#__T!U0FH76?]U&(U%T%"-A1C___^- -MM73___^-O1C___]0\Z7H0K@``(M%_(I-X)F!XO\_```#PHM5^,'X#HB,$"\" -M``"+^O]%_(%]_```!``/C%O_____=1B-1>10C85T____4.@!N```C9\?`@`` -M,_:+^XM$M>2#910`BTT4@T44"(O0T^J(%T>#?10@?.Q&@_X$?-ZA:%I!`/]U -M"&G`*@$```7@54$`4.C5?P``@WT,`*%H6D$`#Y7!:<`J`0``B(C@5D$`@/D! -M=1%J"/]U#(V`X59!`%#H>WP``*%H6D$`BDT8:<`J`0``:A"(B.E600!3C8#` -M54$`4.A8?```H6A:00"+??AIP"H!``!J$(''+P(``%<%T%5!`%#H-GP``*%H -M6D$`0(/@`Z-H6D$`BTWX,\`X11!7#Y3`4U#H-WH``%]>6\G"%`"+=11I]BH! -M``!J$(V&P%5!`%"-GQ\"``!3Z/![``!J$(V&T%5!`(''+P(``%!7Z-M[``#K -ML0^V1"0,4/]T)`S_="0,_Q5P,D$`4/\5=#)!`,(,``^V1"0,]]@;P(/@"5#_ -M="0,_W0D#/\5<#)!`%#_%6PR00#"#`!5B^R#?0PP="2!?0P0`0``=2B*12`D -M`0^VP%#_=1BYB%Y!`/]U".BU;P``ZPW_=0BYB%Y!`.A7;0``,L!=PAP`B\$S -MR8A(!(E("(E(#(E($,-5B^R#[`Q35HMU##/2B]F*#D(SP%>+?12)7?B(30\Y -M51`/AJT````[11@/@ZD```"#>P@`=0Z*##*(2P1"QT,("`````^V2P3!Z0:# -MZ0`/A/H```!)#X3/````20^$J````$EU7@^V##)"A,EY?(H<,H/A?T)!08A= -M_XE-](7)?C\[11AS.HM-"&8/O@P(9@^V??]F`\^__P```&8CSV8/MGT/NP`! -M``!F#Z_[9@//BWT4_TWT9HD,1T"#??0`?\&+7?C`8P0"@T,(_CM5$`^"4___ -M_SM%&'($BT482#/)9HD,1U]>6\G"%`!!0>L6.T48<]"+70AF#[X<&&:)'$>+ -M7?A)0(7)?^;KN68/MDPR`;L``0``9@^ORV8/MAPR9@/+9HD,1T!"0NN69@^V -M?0]F#[8,,KL``0``9@^O^V8#SXM]%&:)#$=`0NER____9@^V##)FB0Q'0$+I -M9?___S/`B0&)003&00@!B$$)B$$*PS+`P@@`:FOH!W```%#H/88``%G#58OL -MN``0``#H/-[___\5A#%!`(/X`W5Z5E>_``0``%>-A0#X__]0_W4,_W4(Z')' -M``"-A0#X__]0Z(5\``"+\(V%`/C__U#HOT\``(3`=1Z-A0#P__]05_\56#%! -M`(V%`/#__U#H67P``(UT!@&X!`$``%\[\%YV&5!HKP```.A[;P``4&@`,T$` -MZ->*``"#Q`S)P@@`BU0D!(O"2'0*2'04+?T```!U!8,Y`'4"B1'_003"!`"+ -M`87`=`6#^`%U[\C:_O__:@B+SNBI____7L-5B^R![``(``"`/6Q:00``5HOQ=3!H``0``(V% -M`/C__U#_=0S_=0CH5D8``(V%`/C__U!J=NBC;@``4&H`Z`**``"#Q`QJ`HO. -MZ%G___]>R<((`%6+[+@`$@``Z,?<__^`>0D`=7135F@`!```C84`^/__4/]U -M#/]U".@#1@``C84`^/__4&ITZ%!N``!0C84`[O__:``%``!0Z$!]``"#Q!#_ -M%80Q00!J-6I^B_#H*FX``%"-A0#N__]0_S7\P4$`_Q5H,D$`@_@$5@^4P_\5 -M@#%!`%Z*PUOK`C+`R<(,`%6+[('L``@``(`];%I!``!6B_%U,V@`!```C84` -M^/__4/]U#/]U".AV10``C84`^/__4&@$`@``Z,!M``!0:@#H'XD``(/$#&H" -MB\[H=O[__U[)P@@`58OLN``0``#HY-O__U:^``0``%:-A0#P__]0_W4,_W4( -MZ"9%``!6C84`^/__4/]U%/]U$.@310``C84`^/__4&IMZ&!M``!0C84`\/__ -M4.BZB```@\0,7LG"$`!5B^RX`!```.B(V___5E>^``0``%:-A0#P__]0_W4, -MB_G_=0CHQT0``%:-A0#X__]0_W44_W40Z+1$``"-A0#X__]0:F[H`6T``%"- -MA0#P__]0Z%N(``"#Q`S_=12+S_]U$.CE_/__7U[)PA``58OLN``0``#H&]O_ -M_U:^``0``%:-A0#P__]0_W4,_W4(Z%U$``!6C84`^/__4/]U%/]U$.A*1``` -MC84`^/__4&IUZ)=L``!0C84`\/__4.CQAP``@\0,7LG"$`!5B^RX`!```.B_ -MVO__5KX`!```5HV%`/#__U#_=0S_=0CH`40``%:-A0#X__]0_W44_W40Z.Y# -M``"-A0#X__]0:G3H.VP``%"-A0#P__]0Z)6'``"#Q`Q>R<(0`.GK_/__5O]T -M)`R+\?]T)`QJ`&H`Z"____]J`HO.Z,[\__]>P@@`5O]T)!2+\?]T)!3_="04 -M_W0D%.AF____:@6+SNBI_/__7L(0`/]T)`C_="0(:@!J`.@C_O__P@@`_W0D -M"/]T)`AJ`&H`Z&O^___""`!5B^R#[!13,]LX'6Y:00`/A90```"-1?Q0:B#& -M!6Y:00`!_Q5X,4$`4/\5"#!!`(7`='96BS4$,$$`5XU%\%!H-#-!`%/'1>P! -M````QT7X`@```/_6BSTD,$$`A%P'01_Q6$,4$` -MA6\G#5HOQC8X4#```Z&"V``"-CC@,``#H5;8``(V.7`P``.A*M@`` -MB\9>PU6+[+CD0```Z!S9___HTSL``(7`#X3I`0``BT405C/V.\9T%&8Y,'0/ -M4(V%_.___U#HEW<``.L4:`````&-A?SO__]0_W4,Z-JW``!F.;7\[___="EF -M.;7^[___=2!H7#-!`(V%_/?__U#H7G<``(V%_.___U"-A0#X___K#8V%_.__ -M_U"-A?SW__]0Z#QW``!35XV%_/?__U#H!'<``(VT1?SW__^+10B+N!1D``"+ -MF!!D``"-A?SW__]0T>_HX'8```/'/0($``!S%%=64^BMMP``,\!FB01^9H,^ -M.G01:@.Y?%Y!`.B*^O__Z0\!``"-1@)04.CD0P``C8TK__X3`=`N-C=SC -M___H<1H``(V-O-?__^C[&0``@'T3`'0T4U-65XV-O-?__^CN&P``A,!T(8V% -MK-/__U"-A:33__]0C86R<(,`%6+[(/L#.C3.0``A<`/A)L` -M``!35HMU"#/;4XU%]%"+SHE=](E=^(E=_.A0ZO__A,!T;.CM_/__:@=8.!UM -M6D$`=`-J#UC_=?10.5T0=`O_=1#_%1PP00#K"?]U#/\5(#!!`#O#=3C_=0SH -MT*\``%!HY`,``.A>:```4('&&`0``%;HN(,``+Y\7D$`@\0,B\[HM];__VH! -MB\[HT/C__SE=]'0(_W7TZ#UQ``!>6\G"#`!5B^R+10B`N'0M````5HMU#'0A -M:&@S00"-AA!8``!0Z/=S``"%P'4,_W44_W405N@:____:&0S00"-AA!8``!0 -MZ-9S``"%P'4,_W44_W405NCR_/__7EW"$`!65XOQZ"JS``"-?BB+S^A#7@`` -M@Z9,!0```#/`:/!B`0!FB89<$0``Z/EV``!9A+R.B6U@``ZP(SP&H` -MB\B)AD@%``#HL=P``%^+QE[#4U:+\8M,)!!7Z`H?``"+?"00,]N!QQ@H``") -MAO@$``")EOP$``")GE`%``")GE0%``!F.1]T$%>-AEP1``!0Z"1T``!F.1\/ -ME<"+SHB&7!(``(B>[@0``(B>71(``(B>7QX``,:&604```&(GEH%``"(GEL% -M``#HW[,``%]>6\((`%:+\5>+OD@%``"%_W0.B\_HS-H``%?H*G8``%EH``$` -M`&H`@<9<$0``5NA><```7U[#58OL@^P,5E=H```!`(U-].BFU?___W7XBWWT -MBTT(5^A-70``B_"%]G1'4XM=#(/^_W0],\`[11!\"'\$._-R`HOSBTT(5E?H -MAUX``(-]$`!\#'\$A=MR!BO>@UT0`/]U^(M-"%?H!UT``(OPA?9UOEN%_W0& -M5^A<;P``7U[)P@P`58OLN%@R``#H@M3__X-]$`!3BUT(BH/#-@``5HMU#%>+ -M^8A%\'4X@+_N!`````^$=0X``/]U\(U'*&H`4%;HL^8``(3`=1%J`;E\7D$` -MZ(GV___I40X``,:'7QX```"+AJ1*``")10B#^'0/A+$```"#^'9T!8/X>74' -MQH=?'@```8/X>G5&:&PS00"-AA!8``!0Z*)Q``"%P'4'QH=?'@```8"_71(` -M``!T:(V'7A8```^W"/?9&\DCR%&-AUX2``!05E/H5?W__XM%"(/X>W5"]H;` -M5P```0^$R@T``/]U\(U'*&H`4%;H".8``(3`#X11____:@#&AU\>````_[:D -M<0``B\[_MJ!Q``#H;1P``.L'B\[HV=/__[`!Z8D-``"`OU\>````QH==$@`` -M``^%]0C8;02@``4(O+Z&#L__^%P`^511.`?1,`=`V`?>\`=0?&AUD%```` -MN``"``!FA8;82@``=`WHH;,``,9%_P&$P'4$QD7_``^V1?_WV!O`C8]>%@`` -M(\&`??\`B47T=%*-A4CF__]0C88`3P``4.A$/@``:`````&-A4CB__]0C85( -MYO__4.A!L0``A,!T(XV%2.+__U#H3$,``(3`=!.-A4CB__]0C85H^O__4.B( -M;P``C85H^O__4%#H^3P``(O.Z!O<__^$P`^%O_[__[@`"```9H6&V$H``'1/ -MBX.D,@``@_@!=%R`?>\`=5:%P'4#B$43:@"-A4CF__]0C85H^O__4.@@1``` -MBXND,@``23O(=2MJ`8V%2.;__U"-A6CZ__]0Z`!$``#K&(O.Z)W;__^$P'4- -M@[ND,@```78$QD43`(O.Z+#;__^*AMA*``#0Z"0!B(?N!```QH?O!````(N& -MJ'$``"N&J%<``(N.K'$``!N.K%<``&H`45"+SNAM&@``@'T3`,9%#P#&10L` -MQD7K`'41BH:Q<0``B$7KA,`/A$H+``"`??!)_W7K#Y3`#[;`4`^V@^(M``!0 -MC85(YO__4(V%:/K__U#H97D``(3`#X1#"P``]H;82@``!'1;C8=<$0``9H,X -M`'5/:(````!0C85(YO__4(V%:/K__U!J`>C0[/__A,!U,&H`Z.!X``!9C85H -M^O__4.C^J0``4&ISZ(]B``!0Z,5X``!96<:'7AX```'IWPH``(V#$`0``(V/ -M7A(``%!1B4WXZ.AM``"#NT@M```$=3*`??!8=2QJ.NC)-P``A,!T(8M%^,9% -M"P'&``"`??!%=!>#NT@M```!=`Z-A6CZ___K$L9%"P#KXXV%:/K__U#H:CH` -M`%#_=?CHM6X``(M%^`^V`%#H7Z@``(!]"P"(1>IT1X"_7Q(``%]U(P^^AV`2 -M``!0Z$8W``"$P'02BD7J+$$\&7<)QH=?$@``.NL;BT7X@#A?=1.`OU\2``!? -M=0K&`%S&AU\2``!<@'W_``^$GP```(V#$`@``&:#.`!T#U"-AUX6``!0Z'YN -M``#K&&@````!C8=>%@``4(V#$`0``%#HO:X``(!]"P!T"3/`9HF'7A8``(!] -M\$5T$8.[2"T```%T"(V%2.;__^L,C85(YO__4.CM.0``4(V'7A8``%#HDFX` -M`(!]"P!T,&:#OV`6``!?=28/MX=B%@``4.A\-@``A,!T%6HZ6&:)AV`6``#K -M"3/`9HF'7A8``(!]ZP!U#?:&V$H```'&10L!=`3&10L`@+M$+0```'4)@+M% -M+0```'1K@'WP170&@'WP6'5?C8VHS?__Z+KU__]J`(V%J,W__U#_=?3_=?CH -M2B,``(3`="^-AA17``!0C8V\V?__Z$ZM``"$P'0F@+VXV?__`'095XV-O-G_ -M_^C5K```A,#K!X"[1"T```!T!,9%"P#VAMA*```$=!IF@[]<$0```'40:@&Y -M?%Y!`.CE\/__QD4+`(J&\$H``#PD=$$\'70]@+[Q2@``,'0TC85H^O__4.B. -MIP``4&ILZ!]@``!0C888!```4.AY>P``@\0,:@&Y?%Y!`,9%"P#HEO#__XV- -M2.[__^BS$```_[;T2@``Z#(:``"$P`^%,0,``(O.Z/+7__^$P`^$U`$``(!] -M"P`/A+H!``"`??!0#X2P`0``@'WP10^$I@$``(.[2"T```$/A)D!``"`?>L` -M#X6/`0``_X=,!0``@+OB+0````^%?`$``("[ART```#_MO1*```/E,`/ML!0 -M_W7T_W7XZ%P:``"%P`^$I0```/]U]/]U^.@Q&0``B$4+A,!T0_]U]/]U^.B4 -M&0``4.AQ&0``A,!U+O^V[$H``(U%"_^VM%<``/^VL%<``%#_LR0M``#_=?3_ -M=?AJ`%/H;@T``,9%"P!J`?]U]/]U^.B[&P``@+N'+0```/^V]$H```^4P`^V -MP%#_=?3_=?CHTQD``(7`=""`?0L`=".`NX``!0C888!```4.C_>0``@\0, -M_W7TN7Q>00#_=?CHAN[__[E\7D$`Z/#,__]J";E\7D$`Z`;O__^`OUT2```` -M=$2+@[0R``#WV!O`C8Y<5P``(\%0BX.P,@``]]@;P(V..%<``"/!4(N#K#(` -M`('&%%<``/?8&\`CQE#_=?3_=?CH%!L``+,!C8U([O__Z+D0``"*P^ET!@`` -MC8U([O__Z*<0``#IU/C__XJ#XBT``(3`=`J`?0L`=`3&10\!@'WP170*@'WP -M6`^%*@$``(!]"P`/A"8!``"$P`^%&`$``/^V[$H``(U%__^VM%<``/^VL%<` -M`%#_LR0M``"-A4CN____=?3_=?A04^CU"P``A,`/A>$```"(10LX1?\/A=L` -M``"-EUX6``!2_W7XC888!```C4X74%&Y?%Y!`.@;\/__:@FY?%Y!`.CQ[?__ -M_W7XZ((\``"$P`^%H````&A6!```Z$!=``!0C888!```4.B:>```65EH``0` -M`/]U^(V%2.+__U#HW*,``&H!_W7XZ*P\``!J`6H`_W7XZ,$9``#_MNQ*``"- -M1?__MK17``#_MK!7``!0_[,D+0``C85([O__:@#_=?A04^@U"P``A,!T!L9% -M"P'K:(V'7A8``%#_=?B-AA@$``!0C4874+E\7D$`Z&7O__^`?0L`=4.`OK%Q -M````=#!J`6H`:@"-A4CF__]0C85H^O__4,9%ZP'&10\!QD4+`>CZ<@``A,!U -M>C+;Z5'^__^`?0L`#X2*!```@'WK`'5C@'T/`'57@'WP4'11C8U([O__Z,L. -M``"$P'1"_W7XZ*6C``!0:`8$``#H,UP``%"-AA@$``!0Z(UW``"#Q`R-AUX6 -M``!0_W7XC888!```4(U&%U"Y?%Y!`.@$\/___X=,!0``_X=0!0``,\")AQ`% -M``")AQ0%``")AQ@%``")AQP%```XAK!Q```/E<"#CS@%``#_2(F'-`4``("^ -MY$H```!U/&B`````C85H____4(V'7!$``%#_%60R00!H@````(V%:/[__U"- -MA6C___]0Z-2H```SP&:)A6;____K$XV'7!$``%"-A6C^__]0Z%UH```/MX;8 -M2@``J`1T#`^VCO!*``")3?3K!(-E]`"`OO!*```DC4\H&M(E``0``/["#[?` -M#[;24O?8&\!J`(V6#%<``"/"4(V%:/[__U#_=?3H+%$``(N&J%<``(E'2(N& -MK%<``(E'3(V%2.[__U!6C4\HZ.I0``"*10^*3>N(1U&(3U*$P'5Q.(;`<0`` -M=6F+AJA7``"+CJQ7``"+EK17```/I,$+P>`+.\I\3'\(.X:P5P``=D*%TGPG -M?PR!OK!7````X?4%L",L#VAMA*```0 -M=0G&AUL%````ZRB`OO%*```P=!^#OK17````?!9_"8.^L%<```!V"X3`=`?& -MAUL%```!@'WK`,9%_P!U7X3`=5OVAMA*```$=!DXAUL%``!U$8V%:/K__U#H -MA:```%!J<.L/C85H^O__4.ATH```4&IQZ`59``!0C888!```4.A?=```@\0, -M:@.Y?%Y!`,9%_P'H?.G__^A5Q___@'T/``^%^0```(!]\%AT"H!]\$4/A>D` -M``#_MO1*``#H!!,``(3`#X76````.(-`+0``=`>#IO1*``#?@'W_`'08@+N` -M+0````^$M````(V-2.[__^CT"@``BY.T,@``]]H;THV&7%<``"/0BX.P,@`` -M]]@;P%*-ECA7```CPE"+@ZPR``#WV(V.%%<``!O`(\%0C8U([O__Z%0.``"- -MC4CN___H80D``(N+M#(``/?9&\F-AEQ7```CR%&+BZPR``#WV1O)C8845P`` -M(\A1C8U([O__Z(0*``"`NXL`#X5R\O__,L!?7EO)PA``58OLN("> -M``#HT,7__U97_W4(B_&-C8!A___H<O)4S/;,_\XG3+3__\/A*````"-A9=A__]0 -MC84`_/__4.A]8@``C8689?__4(V%`/3__U#HU6,``/:%0*S__Q!T#8"],-/_ -M_P!U!#+`ZP,SP$!0:``$``"-A0#T__]0C84`_/__4.C',P``C8U@W___Z*/K -M__]J`(V%8-___U"-A0#T__]0C84`_/__4.@K&0``A,!T$HN%8.O__P/XBX5D -MZ___$]CKD8V&*`4```$X$5@$BWT(C86`8?__4%>+SNCA[O__BH?#-@``6SQ4 -M=`0\274'QH?B+0```8V-@&'__^BOQ/__C8V`8?__Z%?/__^-30M14(V%@&'_ -M_U!7B\[HUN___X3`==V-C8!A___H>,S__U\SP%[)P@0`58OLN*05``#H0<3_ -M_U.+70A6B_'&AEX>````BH/#-@``5XV-7.K__XB&[`0``.C*ZO__OP`$``"- -MAEP)``!7C8Y+C5SV__^-AB@%```!"(N-8/;__Q%(!%?_=0B-AEP%``!0B\OHHMS__X3` -M=;>+BP!/``#H(IT``.MJC8,8*```4(V%_/[__U#H/6(``%.+SNBT_?__B47\ -MC87\_O__4(V#&"@``%#H'V(``(-]_`%TR6H`C85+C5SV__^-AB`%```!"(N-8/;__Q%(!%?_=0B-AEP%``!0B\OH -M%=S__X3`=8"#ODP%````=3*`N\,V``!)="DXAEX>``!U%6A#`P``Z+Y4``!0 -M_W4(Z!QP``!966H*N7Q>00#H/N7__U]>6\G"!`!5B^R![``,``!35E>+?0B[ -M]@,``(7_=`Y7Z!)?```[PP^''P$``(MU#(7V=`Y6Z#%A```[PP^'"@$``(-E -M"`"%_W0=@#\`=!A7Z'$O``")10B%P'4+5^C57@```\>)10B#90P`A?9T'V:# -M/@!T&5;H9R\``(E%#(7`=0Q6Z.-@``"-!$:)10PSP#/;QH4`_/__`&:)A0#T -M__]#A?]T)(`_`'0?_W4(BT4(4UL",L!?7EO) -MP@@`58OLN,`P``#HC\'__U-65XV-0,___^@PZ/__,_]7C85`S___4/]U"%?H -MP14``(3`#X1O`0``9CF]P-O__P^$8@$``(V%P-O__U"-A4#3__]0Z*4K``!0 -MZ!ZB``"%P`^$00$``(V%P-O__U#_=0CHB"L``%#H`:(``(7`#X4D`0``9HF% -M`/C__S/;O@`$``!F.;T`^/__=5Y6_W4(C84`^/__4.B1F0``4VB8,T$`5HV% -M`/C__U#H0"L``%#HDV$``(/$$(V%`/C__U!7Z%H,``"$P'0),\!FB84`^/__ -M@\-[@?L0)P``?*9F.;T`^/__#X2O````5O]U"(V%`/#__U#H,YD``(V%0-/_ -M_U#HZ2H``%"-A0#P__]0Z-PJ``!0Z!M?``"+-7`Q00"-A0#X__]0C84`\/__ -M4/_6A#C__]7 -MZ`H&``"*V(V%`/#__U"-A0#X__]0_]:$VW06C8W@X___Z/$"``"-C>#C___H -M:P,``(V-X./__^A5!```L`'K`C+`7UY;R<($`%6+[(M%'('L!`P``(7`=`/& -M``!35HMU%%>+?1!65\9%_P#H5@L``#/;0^F[`0``@'W_`'5E:``$``"-A?SS -M__]05E>(7?_H_B@``(V%_//__U#H^_W__X3`=#^%_W07@#\`=!)H`````5>- -MA?SS__]0Z$.>``"%]@^$90$``&:#/@`/A%L!``"-A?SS__]05NC]70``Z4D! -M``"+11C&1?\`@_@"#X1?`0``@_@#=1A65^A._/__A,`/A24!``"#91@`Z1P! -M``"+30B`N6@M````#X4;`0``.\,/A!,!``"%P'0)@_@$#X7W````,\!FB87\ -M\___5XV%_/O__U#H)5P``%;H=)8``%"-A?SS__]0Z'U=```SP#E%#`^4P%#_ -M=2B-A?SS____=23_=2!0C87\^___4.@7=@``#[[`4/\U`%!!`.@46P``B\LK -M#0!000`#P3O##X27````:@)9.\$/A*,```"#^`,/A*<```"#^`0/A*D```"# -M^`5U4HV%_/O__U#H;2@``(V-_/O__SO!B\%05W4&Z%HH``!0Z(5;``"%]G0] -MC87\\___4.B;*```C8W\\___.\&+P5!6#X7,_O__Z(0H``!0Z<'^__^#^`9U -M#VC_````N7Q>00#HF^/__U97Z),)``"$P`^%/?[__XM-#(7)=#Q35E?HQ0,` -M`(3`=#"*P^M3BT400#H?]____^&'`P``%Z*PUO#5HOQ@WX,`'0$,L!>PX-^!/]T!>AC -M____@'X3`'3KC888!```4(/&%U;HX@@``%[#58OL45-6B_&#RO\SVSE6!'4: -M.%X4=&V-AA@$``!0C4874+E\7D$`Z/C?__]7:@&-1?Q04_]V!(E=_/\5;#%! -M`(OX@___=23_%80Q00"%P'0:.%X4=#*-AA@$``!0@\875KE\7D$`Z+G?__^+ -M1?QJ`9E34E#H(KK__S/)`\<3T5]>6\G#B\+K^(/*_XO"Z_#_<03_%6@Q00!( -M]]@;P$##P@@`BT$$@_C_=0,RP,-0_Q5D,4$`@_@"=`B#^`-T`S/`PS/`0,.# -M>03_QP&P,T$`=!:`>1``=1"`>1(`=`7I[O[__^ED_O__PU6+[%%35HOQ,]M7 -MB9X8#```.%X6=`3&11`!QT7\````@#A=%'0'QT7\````P,=%%`$````X71!T -M!\=%%`,````SP#A>%0^5P$@E````"(OXZ.H=``"%P'0@BT4,.\-T&68Y&'04 -M4U=J`U/_=13_=?Q0_Q5<,4$`ZQ135VH#4_]U%/]U_/]U"/\58#%!`(OX@___ -M=17_%80Q00"#^`)U"L>&&`P```$```"#__\/E443B%X2B5X,B%X0.%T3=&.) -M?@2+?0P[^W0:5^@O60``C40``E!7C888!```4.B>5@``ZPDSP&:)AA@$```Y -M70AT&/]U".C15@``0%#_=0B-1A=0Z'A6``#K#V@````!C4874%?H-YD``/]V -M!(O.Z!O]__^*11-?7EO)PA``:@!J`/]T)!#_="00Z,3^__^$P'0$L`'K%/]T -M)`BY?%Y!`/]T)`CH".#__S+`P@@`58OL4U8SVU>+\3A=$'4(B5T0.%X6=`?' -M11`!````Z,$<``"+?0R%P'0?._MT&V8Y'W064U-J`E/_=1!H````P%?_%5PQ -M00#K%E-3:@)3_W40:````,#_=0C_%6`Q00")1@3&1A(!B5X,B%X0._MT#U>- -MAA@$``!0Z$]8``#K"3/`9HF&&`0``(U&%SE="'0+_W4(4.C(5@``ZPQH```` -M`5!7Z$R8``#_=@2+SN@P_/__,\"#?@3_7UX/E00!J"8O.Z(S;____=0R+SO]U".@AW___,L!> -M7<(,`%6+[%%65XOY@W\,`;X@3@``=1,Y=0QV`XEU#&KV_Q50,4$`B4<$:@"- -M1?Q0_W4,_W4(_W<$_Q54,4$`AL",MLX -M10MT"8U%]%#HLI,``(!]#P!T"XU%Y%"+S^BADP``A-MT"XU%[%"+SNB2DP`` -M#[9%"_?8&\"-3?0CP5`/ML/WV!O`C4WL(\%0#[9%#_?8&\"-3>0CP5"+1?S_ -M<`3_%70Q00!?7EO)P@P`58OL4?\%<%Y!`%;&1?\!,_:+AG!:00"%P'0MQD`4 -M`(N.<%I!`(!Y$@!T!^C`^O__ZP7H-/K__X3`=`F#IG!:00``ZP3&1?\`@\8$ -M@?X`!```00"*1?]>R<-6B_'H?OO___9$)`@!=`=6Z!I8``!9B\9> -MP@0`5O]T)!"+\?]T)!#_="00Z%#^__^$P'4:.$84=!6-AA@$``!0@\875KE\ -M7D$`Z)?:__]>P@P`5FH`_W0D$(OQ_W0D$.@<_O__A,!T%(O.Z.'Z__]J`&H` -M:@"+SNB@____7L((`%6+[(/L&%:+\5=6C4WHZ"I9``!J`FH`:@"+SNA\____ -MB\[H&OK__XU-Z(OPB_KH,5D``(O77XO&7LG#58OL48-]#`!6B_$/A/\```"+ -M1@R%P'052'0'2'4/:O3K`FKU_Q50,4$`B48$4XL=3#%!`%-1?Q0_W4,_W4(_W8$_]-(]]@:P/[`A,!UR<((`%6+[(/L#%-6,]N+ -M\5>)7?2)7?@X7A%T"^C4^/__B47TB57XOWQ>00#_=0R+SO]U".C\^___B47\ -M@_C_=4''AA@,```"````.%X4=#(X7A%U-SE>#'46C888!```4(U&%U"+S^B7 -MUO__A,!UO(V&&`0``%"#QA=6B\_H<]K__XM%_%]>6\G""`")7?PY70QV[K\` -M`@``,\F+PP-%]&H`$TWX45"+SNBB_?__BT4,*\,[QW("B\=0_W4(B\[H+1"0(AP`!```5XM]"(7_#X23 -M````@#\`#X2*````4U;&10L!B]^+\ROW@?X`!```?4*`.UQU,%97C84`_/__ -M4.@54```:@!J`6H`C84`_/__4,:$-0#\__\`Z#7___^%P'0$QD4+`%/HH+S_ -M_XO8@#L`=;*`?0P`7EMU)U?H!AT```^^`%#H>AD``(3`=11J`&H!:@!7Z/G^ -M__^%P'0$QD4+`(I%"^L",L!?R<((`%6+[('L``@``%-6BW4(,]L[\P^$C@`` -M`&8Y'@^$A0```,9%"P%7B_O1_X'_``0``'U!9H,\,UQU,5=6C84`^/__4.C+ -M4```,\!09HF$?0#X__]J`8V%`/C__U!J`.B#_O__AP@"```Z`84``"%P`^$ -M(0$``(M%$%,SVSO#=`C&1?X!.1AU`XA=_HM%%#O#=`C&1?T!.1AU`XA=_8M% -M&#O#=`C&1?\!.1AU`XA=_U>+?0Q7_W4(Z`#]__^)1?B#^/\/A-,```"H`0^$ -MRP```%-7_W4(QD4/`>@+_?__5F@`!```C87@]___4%?_=0CH'QH``%-H```` -M`FH#4VH#:````$"-A>#W__]0_Q5<,4$`B_"#_O]T?#A=_G0,BTT0C47@4.A: -MC```.%W]=`R+312-1>A0Z$F,```X7?]T#(M-&(U%\%#H.(P```^V1?[WV!O` -MC4W@(\%0#[9%__?8&\"-3?`CP5`/MD7]]]@;P(U-Z"/!4%;_%70Q00!6_Q5\ -M,4$`.%T/=`S_=?A7_W4(Z%7\__]>7UO)PA0`B%T/Z3O___]J`/]T)`S_="0, -MZ#?\___""`"+P8.(!`P``/\SR<8``&:)B``$``#&@``,```!PXN!!`P``(/X -M_W0'4/\5?#!!`,-65XM\)`R+\87_="57C88`!```4.A>3@``@#X`=0QH```` -M`597Z'2.``#&A@`,```!7U["!`!5C6PDF('L4`H``%-65^A&$@``OP````&% -MP`^$D`$``(M%>(7`=!5F@S@`=`]0C848]O__4.@'3@``ZQ!7C848]O__4/]U -M=.A.C@``BW5\@\O_C848_O__4#E=<'4[C848]O__4/\5C#!!`(E%<#O#=5+_ -M%80Q00"#^`)T#X/X`W0*@_@2=`4SP$#K`C/`B(:<%```Z:L"``#_=7#_%8@P -M00"%P'45B5UP_Q6$,4$`@_@2#Y7`B(:<%```.5UP#X2``@``C848]O__4(V> -M``0``%/H:DT``(V%1/[__U!3Z!@9``!0Z%=-``!75E/H=HT``&H!:@!J`/^U -M-/[__^C*K/__BXTX_O__,_\#P8F&``P``(N%&/[__XF&"`P``(U%3%"-AH`, -M```3UU")E@0,``#H"DT``(N%'/[__XF&@!0``(N%(/[__XF&A!0``(N%)/[_ -M_XF&B!0``(N%*/[__XF&C!0``(N%+/[__XF&D!0``(N%,/[__XF&E!0``(V% -M+/[__XV^%`P``%"+S^@MBP``C84<_O__4(V..`P``.@;BP``C84D_O__Z7L! -M``"+172%P'04@#@`=`]0C848^O__4.@-2P``ZQ!7C848^O__4/]U>.B-C``` -MBW5\@\O_C84H____4#E=<'4KC848^O__4/\5A#!!`(E%<#O#=4+_%80Q00"# -M^`(/A'S^__^#^`/I;?[___]U-A@`$``!05N@IC```:@%J`&H`_[5$____Z$NK__^+C4C___\SVP/!B88` -M#```BX4H____B88(#```5XV&@`P``%"-15@3TU")E@0,``#HXXL``(N%+/__ -M_XF&@!0``(N%,/___XF&A!0``(N%-/___XF&B!0``(N%./___XF&C!0``(N% -M//___XF&D!0``(N%0/___XF&E!0``(V%//___XV^%`P``%"+S^BMB0``C84L -M____4(V..`P``.B;B0``C84T____4(V.7`P``.B)B0``B\_HVH@``(F&#`P` -M`(.FF!0```"+17!?7EN#Q6C)PA``4U565XM\)!2+\3/;ZW-7C88`!```4%8X -MG@`,``!T#VK_Z(+\__^)A@0,``#K"_^V!`P``.AO_/__@_C_=$W_MP@,``") -MGY@4``#HW??__XB'$`P``%>(G@`,``#H[!4``(OH:+@S00!5Z())``"%P'0/ -M:+0S00!5Z'-)``"%P'4.B)^<%```.!YU@S+`ZP*P`5]>75O""`!5B^Q6_W4, -MBW40_W4(QH:<%````.AO$@``A,!T!#+`ZS16_W4,_W4(:O_HX?O__X/X_W3I -M4/\5?#!!`/^V"`P``(.FF!0```#H1_?__XB&$`P``+`!7EW"$`!65[\"@``` -M5XOQZ%1,``!95VH`4(E&".B"1@``7XO&7L/_<0CH+4P``%G#B]&+0@B+"@/( -M#[8!5@^V<0$/MDD"P>`("\;!X`@+P6H(62M*!%[3Z"7__P``PXM!!`-$)`2+ -MT,'J`P$1@^`'B4$$P@0`Z;;___]6B_&+1AC'!F`T00#'1@0D-$$`QT8(Z#-! -M`,=&#,PS00"%P'0*BPA0_U$(@V88`%[#BT0D!/]`$(M`$,($`+@"0`"`P@@` -M,\#""`!6BW0D"/]V$/\58#)!`(7`=0-`ZPN+1A"+3"0,B0$SP%[""`!J$/]T -M)`S_="0,Z*E,``"#Q`SWV!O`0,((`#/`P@0`58OL@^P04U:+=0B-1OPSVU>% -MP'0%C48$ZP(SP(M]#(D'BT40B1B-1?!0_W80_Q5<,D$`BT44BTWX4/]U&(E( -M"(M-_(D8B5@$B4@,_Q6@,D$`BT4+ -M"%#_401?7C/`6\G"&`"X`4``@,($`+@!0`"`P@P`N`%``(#""``SP,(,`(M$ -M)!B#"/^X!@`"@,(8`+@!0`"`PA``N`,``H#")`!5B^R#[!165XU%[%#_=0B+ -M^?\5N#)!`(UW&%9HZ#M!`&H%:@"-1>Q0_Q6P,D$`@SX`=$V+!HL(C54(4FBH -M.T$`4/\1AR<($`%6+[%%15HOQBT88A+\3/_.7X8=%N+1AB+"(U5_%)HJ#M!`%#_$87` -M?$:+1?R+"#E]"'0F4XU>'%/_=A175E=J^U#_42R+1?R+"%/_=A175E=J_U#_ -M42Q;ZPU7_W845U97:OU0_U$LBT7\BPA0_U$(7U[)P@0`58OL5HOQ@WX8`'0[ -M@WT(`'0UBT88BPB-50A2:*@[00!0_Q&%P'P@BT4(BPB-5AQ2_W84:@!6:@!J -M_%#_42R+10B+"%#_40A>7<($`%:+\8-^&`!U!#/`7L.+1AB+"%#_402+1AA> -MPXO!,\F)"(E(!(E("(E(#(E($(A(%,.`>10`=`;_);0R00##5HOQBT8$APXM)"(7)=!'_="0(_W0D"&H`:@#H6/[__\((`%6+ -M[(/L*%-6BS60,$$`,]M7B5WXB5W\_]:+?0B)1?2+!XU-^%%7_U!(AOY58OL45%6BW4(5U;H840``&O`#`4``@``4.B'0``` -MB_B)??B%_W4'B\;IN@```%-HL#1!`%?H840``%?H,40``(O8B\9F@S@`#X2) -M````:@1HH#1!`%;H-X<``(7`=3^-?@1F@S\-=2^+1?B-!%B)1?QF@WX&"G4? -M:)0T00#_=?SH%D0``(-%_`B+]XU^!(/#!&:#/PUTVHM]^$9&ZRT[=0AV(&:# -M/B!U&F:#?OX@=1-HA#1!`(T$7U#HW4,``(/#!NL(9HL&9HD$7T-&1F:#/@`/ -MA7?_____=0@SP&:)!%_HV3\``(O'6U]>R<($`%6+[(/L.%-6BS60,$$`5XE- -M^/_6B47\_]8K1?PSV[\0)P``ZU&+1?B+0`R+"(U5]%)0_Y'@````@WWT!'0\ -M4U-34XU%R%#_%4@R00"%P'0AC47(4/\54#)!`(U%R%#_%50R00!34U.-1129HE%Y(M%^(M`#&H" -M:C_'1>R6````BPA0_Y'8````7UY;R<.#;"0$!.F*^O__@VPD!`3IL_G__X-L -M)`0$Z8_Y__^#;"0$".F%^?__@VPD!`SI>_G__U6+[%:+=1"%]G4*N`-``(#I -MD0```%>+?0QHF#M!`%?HE?G__X7`=69HV#M!`%?HAOG__X7`=`R+10B%P'0[ -MC4@$ZSAHN#M!`%?H:_G__X7`=`R+10B%P'0@C4@(ZQUH^#M!`%?H4/G__X7` -M=!*+10B%P'0%C4@,ZP(SR8D.ZQ1HZ#M!`%?H+_G__X7`=`^+10B)!HL(4/]1 -M!#/`ZPB#)@"X`D``@%]>7<(,`%:+="0(_TX0BT80=1"+SNB+^/__5NAF1``` -M63/`7L($`%6+[(/L#%-7B_F+1PPSVXE]]#O##X0V`0``5E-34U-HZ#5!`(E= -M^(L(4/]1+(MU"%:+S^CW_/__5HA%"^B500``C80```(``%#HO#T``(OX._L/ -MA/<```"[V#5!`%-7Z)Q!``!H4#5!`%?H_D$``&@P-4$`5^CS00``9H,^((EU -M_'4-@T7\`HM%_&:#."!T\VH&4_]U_.AAO0```C40``E#HF3P``(E%_(7`#X14`0``5HO/Z*O[__^+??R(10L/MP9F -MA<`/A#((``(7`=2UF.09T1&H(:``V00!6Z&*"``!&1H7`=`AF -M@SX`=>?K'8/&#NL89H/X/G001D8/MP9FAR<($`(-L)`0,Z53\__^#;"0$!.GU_/__@VPD!`CIZ_S__X-L -M)`0,Z>'\__^#;"0$!.DL_/__@VPD!`CI(OS__U:+\3/`:A!0B484B488C48< -M4,<&8#1!`,=&!"0T00#'1@CH,T$`QT8,S#-!`,=&$`$```#H7#L``(O&7L-6 -M5XM\)`R+\6HLB7X$Z`M!``!9AB&]___BTX(:@'H[/?__XM.".@P^/__B_B%_W0G -MBP=3C5X,4V@(/$$`5_\0A@```"+!U?_4`A;_W80B\[H -M)?S__U]>P@0`58OLBT4,2%:+=0A7BWT4=$A(=#.#Z`-T$H/H?'5,_S=JZU;_ -M%3PR00#K/VKK5O\50#)!`(O/P>D040^WSU&+R.@S^/__ZR-JZU;_%4`R00"+ -MR.CR]___ZQ%JZU;_%4`R00!6B\CH!?___U?_=1#_=0Q6_Q5$,D$`7UY=PA`` -M58OL@^PP4U:+=0A7,_]H`'\``%>+V<=%T#````#'1=0H"```QT78A')``(E] -MW(E]X(EUY(E]Z/\5-#)!`(E%[(U%T%#'1?`&````B7WTQT7X4#9!`(E]_/\5 -M.#)!`%^),UY;R<($`%6+[(/L$%-6B_&`?A0`5W42:@#_%:PR00#_%3`P00#& -M1A0!BQUL,D$`:@#_=0S&1A4`_]/_=0B+SNA;____BT40B480C47P4/]U#/\5 -MG#)!`(L](#)!`&H"C47P4/]U#/_74&H`_Q4D,D$`BT8$AO?__XO84XO.Z&'[ -M__]3B_#H)C@``#OW=!!6_W4,_Q4P,D$`5N@2.```7UY;R<(,`%6+[(L-"%!! -M`('L%`$``(/Y_W4\C87L_O__4,>%[/[__Q0!``#_%9PP00"+C?S^__^+A?#^ -M__^+E?3^__^)#0A000"CH%Y!`(D5G%Y!`.L%H:!>00"#^0)U"\'@"`,%G%Y! -M`,G#N`$%``#)PX!\)`@`#[9$)`1U!U#_%9@R00#""`!5B^R`?1``_W4,_W4( -M=`?H63H``.L%Z!=U``!=P@P`58OL@'T4`/]U$/]U#/]U"'0'Z(LZ``#K!>AC -M=```7<(0`%6+[%-65XM]"(MU#`^V!O]U$%#HD?____]U$(K8#[8'4.B#____ -M1X3`#X3%````/"IT*CP_=!PZPW0?___X`^`'7HZ5C___\SP(3;#Y3`7UY;7<(,`%6+[('L -M``@``%.+70A65XM]$(O'P>@?)`&!Y___``"(11`/A!D!``!3Z)&*"T```,```#& -MAH0M```!QX:L,@``!````(F&T"T``(F&U"T``(F&V"T``(F&W"T``%[#5FC` -M-@``B_%J`%;HR30``(V.6"T``%[I-(0``%:+\3/)C898+0``B0B)2`2)2`B- -MCH@M``#H<78``(V.K"T``.AF=@``B\[H2/___XO&7L-6BW0D"%;HK3<``(7` -MC41&_G<"B\9>P@0`BT0D"(7`=!-F@S@`=`UH@#9!`%#H6#D``.L9@WPD!`!U -M!#/`ZQ1H=#9!`/]T)`CHR34``/?8&\#WV,((`(-\)`1<=`N#?"0$+W0$,\#K -M`S/`0,($`#/`@WPD!#H/E,#"!`!6BW0D"%;H,C<``(7`=A-F@WQ&_EQT"VB( -M-D$`5NBR-P``7L($`%:+="0,5XM\)`R%]G0>._=T&E?H_S8``#M$)!1R!S/` -M9HD&ZSY75N@5-P``9H,_`(O'="DSR5-F@S@O=15J7(7V=09:9HD0ZPF+T='Z -M6V:)'%9`0$%!9H,X`'7;6XO'A?9T`HO&7U["#`!5B^R![``$``!65XM]"(U% -M"%"-A0#\__]0O@`$``!65_\5H#!!`(7`=`T[QG,)C84`_/__4.L&.WT,=`E7 -M_W4,Z"-1@10Z+@V``"%P'0K5X/``E#HJC8``(7`=`U]>6\((`%6+[(M%#%97BWT4AP@P`@#WX34(``'0*N?A,0@#I"7D``.E_,@``@#WX34(``'0* -MN?A,0@#I&WD``.F3,@``5HMT)`B*!E0%1Z/*?__^+R(H!A,!UXH7_=`2+Q^L<@#X`=!6-?@&`/SIU#5;HSY___SO' -MC48"=`*+QE]>P@0`5HMT)`A6Z!`T``"+R.L.#[<$3E#HH/S__X3`=1E)>>]F -M@SX`=`IF@WX".HU&!'0"B\9>P@0`C41.`NOVBT0D!%:+\.L(4(OPZ'2?__^` -M.`!U\XO&7L($`%6+[('L``0``%:+=0B*!H3`=#2-3@(/OL!0Z$+\__^$P'0< -M@'G_+G46@#DN=1$/OD$!4.@I_/__A,!T`XUQ`HI!_T&$P'7/@#X`='!7B@:+ -M_H3`=`N`?@$Z=06-?@+K*#Q<=20X1@%U'VI`&*!XO/A,!T((K0#[["4.C&^___A,!T!8UY`>L%@/HN=0=! -MBA&$TG7B._YT!X`_`(OW=9)?@#XN=1"`?@$N=0J-1@*`.`!U`HOP@WT,`'0A -M:``$``!6C84`_/__4.C5;```C84`_/__4/]U#.B*,0``B\9>R<((`%6+[(M% -M"`^W"('L``@``%>+^&:%R70_#[?1C4@$#[?"4.@\^___A,!T'F:#>?XN=1=F -M@SDN=1$/MT$"4.@A^___A,!T`XUY!$$/MT']00^WT&:%P'7'9H,_`'1]5F:# -M/P"+]W0*9H-_`CIU`XUW!&:#/EQU*&:#?@)<=2%J7(U&!%#HH3,``(7`=!)J -M7(/``E#HDC,``(7`=`.-<`(/MP:+UF:%P'0E#[?(#[?!4.BO^O__A,!T!8UR -M`NL&9H/Y+G4*0D(/MPIFA+?"0,5T[HQOS__RO'._!\"E?HNOS__XOP -M*_=65XM\)!A7Z`\P``#&!#X`7U["#`!6BW0D$%>+?"0,5T[HY_S__RO'T?@[ -M\'P,5^C9_/__B_`K]]'^5E>+?"085^@\,0``,\!FB01W7U["#`!6BW0D"%;H -ML?S__XU.!#O!P@0`4XM<)`A65U/H -M:RX``(U\&/_K!3O[=@Y/#[X'4.A7:@``A,!T[@^^!XOWZP@[\W9"3@^^!E#H -M/FH``(3`=>[K%(H&/"YT+`^^P%#H*6H``(3`=0=.._-WZ.L8:BY3Z-C[__]0 -MZ*+[__^%P'0&.\9S`HO^B\=?7EO"!`!3BUPD"%974^@E,```C7Q#_NL&._MV -M#T]/#[<'4.C<:0``A,!T[0^W!XOWZPD[\W9'3DX/MP90Z,)I``"$P'7MZQ@/ -MMP9F@_@N="T/M\!0Z*II``"$P'4(3DX[\W?DZQAJ+E/HK_O__U#H*#$``(7` -M=`8[QG,"B_Z+QU]>6\($`%-55E>+?"04:CI;A?\/A.T```"`/P`/A.0```!7 -MZ.O]__^+\(7V=15HT#9!`%?H82\``%?HU/W__XOPZS*-;@&`?0``=!YHS#9! -M`%7HI&@``(7`=`]HR#9!`%7HE6@``(7`=0MH<#-!`%7H`BX``(!\)"``=4%7 -MZ(K^__^+\.L5Q@8P3COWB\;K#8U(_X`Y+G0-Q@`PB\'^`#@8=.WK$,8`0>L+:,0V00!7Z'$M -M``"+?"08A?\/A`L!``!F@S\`#X0!`0``5^@-_?__B_"%]G45:+@V00!7Z!PO -M``!7Z/;\__^+\.LSC6X"9H-]``!T'FBP-D$`5>C*<```AB[ -M<```AAR+@``@'PD(`!U45?H"?[__XOPZQEJ,%AFB09.3COW -MCUF/__B\B* -M`83`==XX!G02:-@V00!6Z)8K``"%P'4#0.L",\!>P@0`5E>+?"0,@#\`B_=T -M88!\)!``N-@V00!U!;C@-D$`#[X.45#H^"H``(7`=0LX1"00=`B`/B!S`\8& -M7XO&*\>#^`%^"(`^.G4#Q@9?@#X@=1$/OD8!4.AO]?__A,!T`\8&7U;H:IC_ -M_XOP@#X`=9]?7L((`%6+[('L``@``%:+=0AH``0``(V%`/C__U!6Z(;[__^- -MA0#X__]0:@#H[/3__X3`=`2P`>LL9H,^7'4'9H-^`EQT&%;HJ/;__X3`=!,/ -MMT8$4.@`]?__A,!T!3/`0.L",\!>R<($`%6+[%97:CO_=0@S_^BW]___B_"% -M]G04C48!4.C5+@``@'T0`(OX=`/&!@"#?0P`="IJ._]U#.BH+0``B_"%]G0: -MA?]U"XU&`E#H_&\``(OX@'T0`'0%,\!FB0:+QU]>7<(,`%:+\>@:XO__@V8, -M`(O&7L-6B_'_=@SH72X``%F+SE[I'^+__U:+\8-^#`!U#F@$``0`Z$XN``!9 -MB48,7L.+1"0(BTPD!(D!P@@`BU0D!(,Z`HM"#'4-BP`#0@@E__\#``-!#,($ -M`%97BWPD#(O/Z!_B__^+\"4`P```B\]TP@0`58OLBU4(N```!``[T',>BTD,`\HY -M30QT%"O".440@_*```7<(,`%:+="0,5O]T)`QJ_^@YJ/__ -M,]+WT#/).8$\4$$`=0@YL3A000!T#X/!#$*#^51RYS/`7L((`&O2#(N"0%!! -M`.OQBT0D"(M,)`29@^('`\+!^`,/MA0(0%8/MC0(C4P(`0^V00$/M@G!X`@+ -MP8M,)`S!Y@@+UL'@$`O"@^$'T^AJ(%DK3"00@\K_T^I>(\+"#`!5B^R+31"+ -MP9E6@^('`\*#X0=7B_"+P6H@62M-%(/*_]/JB\B+10C390S3XL'^`S/_`_#W -MTHH$/B+""D4,P6T,",'J"('*````_X@$/D>#_P1RXE]>7<(0`(M$)`16B_$! -M1@2+3@2+1@@[R'8QB]#!Z@)7C7P"(#O/=@*+^8O':\`H4/\VZ`LF``")!H7` -M=0JY?%Y!`.C;K?__B7X(7U["!`!7B_GH(N#__ZD`@```="6+3"0(@R$`P>@, -M@^`'B4$$C42'$(E!#&H$B\_HY-___^F6````5HMT)`R+SZD`P```=2Z`?"00 -M`,<&`0```'0/P>@&)?\```")1@1J"NLU:@+HKM___U?HD_W__XE&!.M9QP8" -M````J0`@``!U'<'H"H/@!X-F"`")1@2-1(<0B48,:@;H>]___^LOJ0`0``!U -M%,'H"8/@!XE&!(U$AQ")1@QJ!^L&@V8$`&H$Z%/?__]7Z#C]__^)1@A>7\(( -M`%6+[(M5"(/L4%:+\872#X[=!```@_H"4U(#/2B_N!^P#@`0`/@Y0$ -M``"%VWX@BT8,B@P00H#Y`G4,B@P00H#Y`G0#@,'@B`PX1SO3?."+1@PK^XFX -M',`#`(M&#(F8(,`#`.E7!```BTX@BT80BWX,,]N)1>2-%`F)CR#``P"!^0#@ -M`0`/@S0$```A70B%P`^.*00``(M]"#+``_GK$(M6#"H$&D.(!#H#?>2-%`D[ -M^GSL_T4(BT4(.T7D?-CI_`,``(M^((M&$(MV#(T,/HE]V(E%U(EU[(E-T(F^ -M(,`#`('_`.`!``^#T@,``#/;.\.)7?`/CL4#``#K!8M]V#/;:AQ3C46P4(E= -MW(E=X(E=](E=^(E=_(E=".@[)```BT7P@V7D`#O'Z3\!``"+1>"+5?R+R"M- -M](O[B]F+3>P/K],/M@F+]P^O=0@#\HM5^`^OT/]%[`/RBU7@#B4W,)?\````KP8M-Z(@$,0^^=8#5HE-X(E%W.CS*@`` -M`46PB\8K1?10Z.4J```!1;2+1?0#QE#HURH```%%N(O&*\-0Z,HJ```!1;R- -M!!Y0Z+XJ```!1<"+QBO'4.BQ*@```47$`_=6Z*8J```!10?=7:+ -M=;`S_S/)B7VP08U$C;"+$#O60J -M`8M-S/]%Y(-%Z`,/ML"(!`Z#Q@/_3?2)10AU@?]%^/]%[(-]^`,/C$K___^+ -M5?"+1="#PO[K#HI,&`$`#!@`3!@"@\`#.\)\[ND>`0``BT8,B44(BT8@/0#` -M`P`/@PH!``"#^!4/C`$!``"+7BB#P.O!ZP2%P`^.\````$C!Z`1`B474BT4( -M#[8`@^`?@^@0>&B*@(Q000"$P'1>@V7D``^VP&H2B47,7XM-Y#/`0-/@BTW, -MA<%T-VH$C4<84/]U"(O.Z/7Y__^#^`5U(FH45VH45_]U"(O.Z.#Y__\KPR7_ -M_P\`4/]U"(O.Z![Z____1>2#QRF#_V1^KX-%"!!#_TW4=8#K9HM&((M.#(MV -M*#T`P`,`/R`PNB%_WX]B@%!_T4(1CSH=`0Z -MPG4IBP&%P'T.C1P&A=M\$@4````!ZPD]`````7T$*\:)`8-%"`2#P02#Q@0Y -M?0A\PU];7LG"!`!5B^R#[`Q3BUT(5E>+^<=%_$!X?0&-0PA0B\^)7?CH^_?_ -M_XOPC4,84(O/Z.[W__^+"X/Y*`^'=@4``/\DC8.20`"`>P0`=`H/M@"(!NE? -M!0``BP")!NE6!0``BDL$A,ET!0^V-NL"BS:$R70%#[8`ZP*+`(O.*\AU!6H" -M6.L.._$;P/?8@>$```"`"\&)1S#I'`4``(M-^(I9!(3;=`4/MA;K`HL6A-MT -M!0^V`.L"BP"-#!"$VW0:@>'_````=!:+P22`#[;`]]@;P"4```"`ZQ"%R74% -M:@)8ZP>+P24```"`.\H;TO?:"]")5S"+1?B`>`0`=`>(#NFT!```B0[IK00` -M`(I+!(3)=`4/MA;K`HL6A,ET!0^V`.L"BP"+RBO(=05J`ECK$#O1&\"+T??8 -M@>(```"`"\*)1S"`>P0`Z[/V1S`"#X1F!```BS8[=0P/@VD$``#_3?R#??P` -M#XY@!```:_8H`W4(B][II?[___9',`+I`0$``(I+!(3)=`4/M@;K`HL&0(3) -M="@E_P```.L9)0```(#I\/[__XI+!(3)=`4/M@;K`HL&2(3)=`2(!NL"B0:% -MP'79Z;O^__^*2P2$R70%#[86ZP*+%H3)=`4/M@#K`HL`,\+K)XO!)0```(#I -M4/___XI+!(3)=`4/MA;K`HL6A,ET!0^V`.L"BP`CPHO(==7I%____XI+!(3) -M=`4/MA;K`HL6A,ET!0^V`.L"BP`+PNO:BDL$A,ET!0^V-NL"BS:$R70%#[8` -MZP*+`"/&Z6_____W1S````"`Z?#^___W1S````"`ZQSV1S`!Z=[^___V1S`# -MZ=7^___V1S`#ZP3V1S`!#X4Q`P``Z<;^__^#1RS\BQ:+1RR+3PPE__\#`(D4 -M".D3`P``BT,` -M``"`2=/BP>H?BTWX"].)5S"`>00`#X0:_?__Z0S]__^*2P2$R70%#[86ZP*+ -M%H3)=`4/M@CK`HL(B\+3Z(7`=05J`EOK"(O8@>,```"`2=/J@^(!Z[.*2P2$ -MR70%#[86ZP*+%H3)=`4/M@CK`HL(B\+3^.O(@'L$`'0%#[8&ZP*+!O?8B\@/ -MA'C]__\E`0``@(/(`>F`_?__BT -MBUCT``)X]``"V/0``\CT`` -M58]``&Z/0``EDD``DH]``*N/0`#VCT``+)!``$N00`!OD$``HY!``,F00`#5 -MD$``])!``/R00``'D4``.)%``%N10`"*D4``Z)%``&B20`!>DD``58OL4U:+ -M=0R+V8-C!`"#(P"X`(```%<[\',"B\:+?0A05_]S".@G&@``,\DRP$&(10L[ -M\78+,@0Y03O.@(:@B+RX@'Z,_2__^+10S_ -M10@Y`W+$Z?\```!J`8O.Z%OR__^+?A!K_R@#/HO+Z+_2__^+RZD`@```=0?! -MZ`QJ!.L(P>@*@^@8:@:)!^B)TO__BP?V@!!000`$=!V+R^B.TO__J0"`__\/ -MELC -M/8@```!\!RT(`0``ZQ*#^!!\!8/H".L(@_@(?`.#Z!`#1A")1PS_1A"+10PY -M`P^"]O[__VH!B\[H4?'__XM&$(U(`6O`*`,&B4X0C4@,B4@4C4@6UW"#`!5B^Q35HMU"%=J'(U&+(OY4(U'$%#HIQ<` -M`(M&&+L`(```B44(.\-R`XE="(-]"`!T%/]U"(M'#/]V%`4`P`,`4.A[%P`` -MBTT(BT8D*]D[PW("B\.%P'044(M'#/]V((V$"`#``P!0Z%47``"#9S``QTBT80AR<($`(M!%#M!$',0BQ&*!!"+ -M5"0$B`+_013K!XM$)`3&``#"!`"+012-4`$[41!S*(L1`\)F#[90`68/M@!6 -MO@`!``!F#Z_69@/0BT0D"&:)$(-!%`)>ZPF+3"0$,\!FB0'"!`"+012-4`,[ -M41!S,(L1`\(/ME`#5@^V<`+!X@@#U@^V<`$/M@#!X@@#UL'B"`/0BT0D"(D0 -M@T$4!%[K!XM$)`2#(`#"!`!6B_&+1A17BWPD$(U,./]7.TX02@`=%Z+02R%P'17BY$`!0``5HNQ -M!`4``%>+^@O^=!B)51"+D?@$```!50B+D?P$``")=10150S_=13_=1#_=0S_ -M=0C_L+17``#_L+!7``#_L?0$``#_L?`$``#HVB4``%]>7<(0`(M$)`2%P'0# -MB4$LBT0D"(7`=`.)03"#B<`$``#_P@@`58OLBT4,,])6#[P3_#X3P````4/]U_(O+Z-3!__^+^(M&.(7`=0:-@]!*``#V0`@"=!97_W7\ -MC9X0!0``_S/H%)/__XD#BUWTB\>9C8[H!````0$1400!??@!??PI?0PI1B"+ -M1B`95B0+1B1U)SB&Q@0``'0?#[:&Q`0``%!J`593Z"Z)``"$P'1]@WT,``^' -M.?___XM&+(7`="V+B*!Q``#_MM0$```#CN@$``"+@*1Q``#_MM`$```3ANP$ -M``!048O.Z,#]__^#__]T)X.^&`4```"+1?B+^'09J`]T!H/@\(/`$%#_=0B- -MCH`"``#H1Y/__^B440``B\=?7EO)P@@`@\C_Z_3&AL<$```!Z_)3BUPD"%:+ -M\8!^#`!7BWPD%(E>'(E^&'07.WX0=R)74_]V%.B-$0```7X4*7X0ZQ"`?BD` -M=0J+3C!74^B,O___C8;P!````3B#4`0`@'XJ`'415X'&#`4``%/_-NCFD?__ -MB0;H%5$``%]>6\((`(O!,\F)"(E(!(A($,/_,>B"$```PU6+[+@L-```Z*UU -M__]7:ES_=0B+^>A^%0``A<"-A=3K__]U)V@`!```4&H`_Q6H,$$`:ER-A=3K -M__]0Z(45``"%P`^$=0(``(/``O]U"%#H"A0``%:-C=3S___HS[?__S/V5FH! -MC874Z___4%:-C=3S___HO[G__X3`=1"-C=3S___HC;G__^DP`@``@TW\_\9% -M"P")=?A3@WW\_P^%#0$``(V-U//__^BBN/__B]AH`"```(V%U,O__U"-C=3S -M___HF+___XE%]#/V@\#P#XBJ````@+PUU,O__RIU(H"\-=7+__\J=1AJ"V@, -M-T$`C80UULO__U#HO1(``(7`='EF@[PUU,O__RIU*8V$-=C+__]F@WC^*G4; -MBTWT@\'@._%_$6H+:/`V00!0Z`D4``"%P'1!@+PUU,O__U)U)H"\-=7+__]A -M=1QJ!&CH-D$`C80UULO__U#H71(``(7`#X1,`0``BT7T1H/`\#OP#XYA____ -MZPG&10L!`_.)=?R+1?1J`(U$&/!J`%"-C=3S___H%;W___]%^(%]^(`````/ -M@O/^__^#??S_#X0!`0``BT7\F6H`4E"-C=3S___HZ+S__V@"``@`Z)P.``") -M!XV-U//__X7`#X3:````:```"`!0Z'>^__^`?0L`B4<$=`?1Z(E'!.LSC40` -M`E#H9PX``(OPA?8/A*4```"+1P2+#\8$"`"+1P1`4%;_-^B64@``_S?H60X` -M`(DWBT\$N```!``[R'<"B\&+#S/29HD403/),]LY3P1V7(L'#[<46$-FA=)T -M4&:#^EQU,0^W-%B#[B)T(X/N.G0:@^X2=!&#[@1T"$Y.=21J">L.:@WK"FH* -MZP9J7.L":B)#ZPYF@_H-=`9F@_H*=0-J#%IFB11(03M?!'*DBP7\G"!``SP#D!#Y7`PU:+,0^W!E=FASO__]0_W4(Z)U0``"- -MA>SO__]0QD7K`.@(#@``4(V%[.___U!7Z+Z-___WT%!H'#=!`(U%[&H*4.A9 -M$@``@\00C47L4(O+Z*/^__^%P'16C5@4:@Q3Z&(1``"%P'0(*\/1^(OPZP6^ -M_P```(M%$(U(_SOQ=@CWV!O`(\&+\(M]#(7V=@A64U?H)A```&HB,\!79HD$ -M=^A/$0``A6\G"%`!5B^R! -M[``$``!35E?_=0B-A0#\__]J`6@``@``4&@T-T$`Z)3^__]J*HV%`/S__U#H -MRA```(OX:F1;A?]T(8V%`/S__U#H25,``(MU#(/'`E>)!N@[4P``BTT0B0'K -M"HM-$(MU#(D9B1XY'G4(.1EU!#/`ZP,SP$!?7EO)P@P`58OL@>P`"```5E=J -M`(OY_Q6P,$$`:@6^0#=!`%90_Q6L,$$`A!'1H!]_P!T,X!] -M$`!U<@^O1?AH!@(``)EJ9%GW^0/&4(M%Q`^O1?29]_D#QU`SP%!04/]U"/\5 -MB#)!`(!]$`!U/V@`!```C86\]___4/]U"/\5C#)!`/]U#(M-\&H!:``$``"- -MA;SW__]04.@6_?__C86\]___4/]U"/\5,#)!`&H(_Q60,D$`:@7_=0@K\/\5 -ME#)!`(-E"`")11")1>SIV````(%]"``"```/C=,```!H``0``(V%O/?__U#_ -M=1#_%8PR00!F@[V\]___`'0J_W4,BTWP:@%H``0``(V%O/?__U!0Z)S\__^- -MA;SW__]0_W40_Q4P,D$`@'W_`'1FC47,4/]U$/_3BT78*T70:`0"``!`#Z]% -M^)EJ9%GW^5"+1=0K1`KQ@^O1?B9]_E0B\>9*\*+ -MR(M%S-'Y*\$K1=QJ9`^O1?19F??Y4&H`_W40_Q6(,D$`:@+_=1#_%90R00") -M11`[1>QT"_]%"(7`#X4@____7UY;R<(,`%;_="0(B_'HF_C__XO.Z*S]__]> -MP@0`H:A^00!`HZA^00"#^`AR!S/`HZA^00!35<'@"@6H7D$`5HOP,\"]B%Y! -M`%>+S6:)!N@<^___BQV$,D$`OP`"``"$P'425U;_="0<_S5X7D$`_].%P'4. -M5U;_="0<_S5T7D$`_]-J`&H`5U96B\WHB4(,P@P`58OL -M@^PH4U97:B#_=0B-1=A0B4WXZ/H(```SP&H$,\F)10@SVUJ#^`H/C]\````[ -MVGTBC72=V(EU_#O*?1F+??B--(&-?+<4BW7\`57\0T$[VJ5\Y3O*=09`B44( -M,\D[VGS#@_@*#X^B````QT7\L*Y!``^V=>6*1=@RAM"O00`/MG7FBI[0KT$` -M#[9UYS!=V8J>T*]!``^V=>0P7=J*GM"O00"+=?PR!C!=V_]%_&H#B$78C47< -M7S/VBEPP_#`<,$8[\GST`\)/=>TSVX-]"`I_.SO:?2"-1)W8.\I]&HMU"(M] -M^(TTL8U\MQ2+\$,#PD$[VJ5\Y#O*=07_10@SR3O:?,F#?0@*#XYE____7UY; -MR<($`%6+[(/L'%-65X/!)&H$B4W\QT7T"0```%\SP(M-_(UT!>2#P0*)??@/ -MME$!#[99_XJ4D+!^00`RE)BPAD$`#[99_C*4F+"*00`/MADRE)BP@D$``\^( -M%@/W_TWX=+^8V'M````%#_=0B-1?!0Z!S^__\/MD7PBP2%L)I!``^V3?TS!(VP -MED$`#[9-^C,$C;"200`/MDWW,P2-L(Y!`(MU#`^V3?&)!@^V1?2+!(6PFD$` -M,P2-L)9!``^V3?XS!(VPDD$`#[9-^S,$C;".00`/MDWUB48$#[9%^(L$A;": -M00`S!(VPED$`#[9-\C,$C;"200`/MDW_,P2-L(Y!``^V3?F)1@@/MD7\BP2% -ML)I!`#,$C;"600`/MDWV,P2-L))!``^V3?,S!(VPCD$`C9^D````B48,QT4( -M"````%-6C47P4.A&_?__#[9%\(L$A;":00`/MDW],P2-L)9!``^V3?HS!(VP -MDD$`#[9-]S,$C;".00`/MDWQB08/MD7TBP2%L)I!`#,$C;"600`/MDW^,P2- -ML))!``^V3?LS!(VPCD$`#[9-]8E&!`^V1?B+!(6PFD$`,P2-L)9!``^V3?(S -M!(VPDD$`#[9-_S,$C;".00`/MDWYB48(#[9%_(L$A;":00`S!(VPED$`#[9- -M]C,$C;"200`/MDWS,P2-L(Y!`(/K$/]-"(E&#`^%+O___XU')%!6C47P4.AQ -M_/__#[9%\(J`T*Y!`(@&#[9%_8J`T*Y!`(A&`0^V1?J*@-"N00"(1@(/MD7W -MBH#0KD$`B$8##[9%](J`T*Y!`(A&!`^V1?&*@-"N00"(1@4/MD7^BH#0KD$` -MB$8&#[9%^XJ`T*Y!`(A&!P^V1?B*@-"N00"(1@@/MD7UBH#0KD$`B$8)#[9% -M\HJ`T*Y!`(A&"@^V1?^*@-"N00"(1@L/MD7\BH#0KD$`B$8,#[9%^8J`T*Y! -M`(A�^V1?:*@-"N00"(1@X/MD7SBH#0KD$`@\<45U96B$8/Z)?[__]?7EO) -MP@@`58OL@>P$`P``4U8SP#/)0+X;`0``5XO0@.*`#[[2B(0-_/S__XB$#?O] -M__^(C`7\_O__0??:&](CUHT\`#/7,\*#^`%UT#/)7XO0@.*`#[[2]]H;THB! -ML*Y!`"/6`\`SPD&#^1YRXC/;B5W\ZP.+7?R$VW08#[;##[:$!?S^__^-C?O] -M__\KR`^V`>L",\"-#``SR`/),\@#R3/(`\DSP8O(P?D(,LB`\6.-!)T````` -MC9"PGD$`B(O0KT$`B$H!B`J(B+.B00"(B+"B00"(B+.F00"(B+*F00"(B+*J -M00"(B+&J00!T%0^VT0^VE!7\_O__#[:4%17]___K`C/2B)"SGD$`B)"RHD$` -MB)"QID$`B)"PJD$`A,ET%0^VR0^VC`W\_O__#[:,#?W\___K`C/)B(BRGD$` -MB(BQHD$`B(BPID$`B(BSJD$`#[;SB\[!X0,SSL'A`C/.`\F+T<'Z"#+1@/(% -M=#*+SL'A`S/.P>$",\X#R8O1P?H(#[;2#[;),]&#\@4/MHP5_/[__XV5^_W_ -M_RO1BAKK`C+;BTW\B)G0KD$`A-MT%0^VRP^VC`W\_O__#[:4#63]___K`C/2 -M#[;SB\[!X0*(D+*.00"(D+&200"(D+"600"(D+.:00"(D;)^00"(D;&"00"( -MD;"&00"(D;.*00"$VW02#[:4-?S^__\/MI05P_W__^L",]*(D+".00"(D+.2 -M00"(D+*600"(D+&:00"(D;!^00"(D;."00"(D;*&00"(D;&*00"$VW02#[:4 -M-?S^__\/MI05ZOW__^L",]*(D+&.00"(D+"200"(D+.600"(D+*:00"(D;%^ -M00"(D;""00"(D;.&00"(D;**00"$VW02#[:4-?S^__\/MI05V_W__^L",]+_ -M1?R!??P``0``B)"SCD$`B)"RDD$`B)"QED$`B)"PFD$`B)&S?D$`B)&R@D$` -MB)&QAD$`B)&PBD$`#XR/_?__7EO)PX`]T*]!``!6B_%U!>@,_?__B\9>PU6+ -M[(M%"(/L(%:+\5.)!C/`5XM]#(H<.(O(B]#!Z0*#X@-`C505X(@!0B\[H?/C__X,^`74'B\[HA?G__U[) -MP@P`58OL@^PD4U97BWT(B]F%_P^$E@```(MU#(7V#X:+````C4,$:A!0B44, -MC47<4.A,`0``P>X$B77\B74(A?9V5HMU$(U%[%!7B\OHL/G__XU%W%"-1>Q0 -M4.C<]___BP>)1=R+1P2)1>"+1PB)1>2+1PR)1>B+1>R)!HM%\(E&!(M%](E& -M"(M%^(E&#(/'$(/&$/]-"'6M:A"-1=Q0_W4,Z-L```"+1?S!X`3K`C/`7UY; -MR<(,`%6+[/]U"&H`_Q6X,$$`4/\5M#!!`%W"!`!5B^R#?0@`=!+_=0AJ`/\5 -MN#!!`%#_%;PP00!=P@0`58OL@WT(`'4*_W4,Z+?____K%?]U#/]U"&H`_Q6X -M,$$`4/\5P#!!`%W""`!5B^Q1:@&-10A0C44(4/\5>#)!``^V10A0_Q5\,D$` -MB47\:@&-1?Q0C47\4/\5@#)!`(M%_,G"!`!5B^Q1@V7\`.L'BT7\0(E%_(M% -M_#M%$',-BT4(`T7\BDT,B`CKY(M%",G"#`!5B^Q1@V7\`.L'BT7\0(E%_(M% -M_#M%$',2BT4(`T7\BTT,`TW\B@F(".O?BT4(R<(,`%6+[(M%$(M-$$F)31"% -MP'8ZBT4(#[8`BTT,#[8).\%]!8/(_^LGBT4(#[8`BTT,#[8).\%^!8/(_^L2 -MBT4(0(E%"(M%#$")10SKN#/`7<(,`%6+[%&+10@[10QS$/]U$/]U#/]U".AC -M____ZRB+11!(B47\ZP>+1?Q(B47\@WW\`'P2BT4(`T7\BTT,`TW\B@F(".OA -MBT4(R<(,`%6+[% ?P`BT4(#[X`BTT(08E-"(7`=`F+1?Q`B47\Z^:+1?S) -MP@0`58OLBT4(#[X`A+1?Q(B47\@WW\`'P8BT4(`T7\#[X`.T4, -M=0B+10@#1?SK!.O;,\#)P@@`58OL45 ?P`ZP>+1?Q`B47\BT4(`T7\#[X` -MABT4(#[X`ABT4(#[X`A?___UW""`!5B^R+10@/MP"+30P/ -MMPD[P74@BT4(#[<`AL$Z]SK!(-E[`!H?%Y!`&H,Z+[___]968E%^(-]^`!T#8M- -M^.CZ@/__B47HZP2#9>@`:(A>00!J%.B6____65F)1?2#??0`=`V+3?3H4>C_ -M_XE%Y.L$@V7D`&@XTT$`:`A/``#H:____UE9B47P@WWP`'0-BTWPZ)EY__^) -M1>#K!(-EX`#)PS/`PXM,)`R%R70CBD0D"`^VP&G``0$!`8O14U>+?"0,P>D" -M\ZN+RH/A`_.J7UN+1"0$PU6+[(-]$`!U!#/`7<.+30R+10C_31!T"HH0.A%U -M!$!!Z_$/M@`/M@DKP5W#BT0D!(7`?0+WV,/HX_[__S/`4%!04.C5+0``PU97 -MBWPD#(OQB\^)/NCSH/__B48(B58,BX<<#```B4807XO&7L($`(O!BPB+4!`[ -MD1P,``!U#6H`_W`,_W`(Z!RF___#58OL@^P<5C/V5E965HU%Y%#_%4@R00"% -MP'0A5E96C47D4/\53#)!`(U%Y%#_%5`R00"-1>10_Q54,D$`7LG#58OL@>PL -M`0``@SVP4$$``%-65[\`!```=3%J9(V%U/[__U!J#U?_%%]@^$HP````^W!F:%P`^$EP```(M]#(EU_,9%"P!J(EIF -M.\)U2(U.`F8Y$74A@'T+`'44.W7\=0\/MT8$9H/X+'0,9H7`=`>+\6:)%^LQ -MBET+A-MT!L9%"P#K#5)1Z*+[__^%P`^510LZ70MU%`^W!F:#^"QU!H!]"P!T -M%F:)!T='1D8/MP9FA6\G""`!5B^Q148U%^%#_%:PQ00"-1?Q0_W4,:@#_%:@Q -M00#_=0C_=?S_%;0Q00"+1?C_=?R+"%#_413)P@@`BT0D!&:#.`"+R'0X5@^W -M$6:#^EQU(`^W<0)F._)U#6I<6F:)$$!`@\$$ZQ%F@_YN=01J"NOK9HD00$!! -M06:#.0!UREXSR6:)",($`%6+[(/L*%-65S/_5_\5S#%!`(LU7#!!`%")1?C_ -MUO]U^(O8_]:)1?R-1=A0:AC_=0C_%4PP00"+1>`/KT4,F?=]W#M%$'T#B440 -M_W40_W4,_W7X_Q50,$$`_W4(BS54,$$`4XE%]/_6_W7TB44(_W7\_]9H(`#, -M`/]UX(E%\/]UW%=74_]U$/]U#%=7_W7\_Q58,$$`_W4(4__6_W7P_W7\_]:+ -M-60P00!3_];_=?S_UO]U^%?_%<@Q00"+1?1?7EO)P@P`@SU$(D(``'4G5FH` -M_Q7,,4$`B_"%]G07:EA6_Q5(,$$`5FH`HT0B0@#_%<@Q00!>H40B0@`/KT0D -M!&I@F5GW^<($`(,]2")"``!U)U9J`/\5S#%!`(OPA?9T%VI:5O\52#!!`%9J -M`*-((D(`_Q7(,4$`7J%((D(`#Z]$)`1J8)E9]_G"!`!J9.AS____@_A]?0]J -M9.BJ____@_A]?0,SP,,SP$##4XM<)`A65U/HZO?__XOX,\EJ`EJ-1P/WX@^0 -MP??9"\A1Z&?Z__]9B_!3C48"4.CN]___:B)89HE$?@)FB096,\!39HE$?@3H -MU??__U;H+OK__UE?7HO#6\($`%6+[(/L8%-65VIH_S4`PD$`_Q5P,D$`@#T4 -MTT$``(LUT#%!`(OXB7W\N[$```!U,HL-U+!!`.B=L?__:@57_Q5L,D$`:O]J -M`%-7_]9H-#=!`&H`:,(```!7_];&!13300`!OP#A]0575U/_=?S_UHU%H%!J -M`&@Z!```_W7\QT6@7````/_6,\!`@'T(`,9%N0")1:1T'(M-J('A____OPO( -MB4VHQT6TH````,=%I`$``$"-3:!14&A$!```_W7\_];_=0QJ`&C"````_W7\ -M_]975U/_=?S_UH!]"`!T'HM%J(/@_@T```!`B46HC46@4&H!:$0$``#_=?S_ -MUFA8-T$`:@!HP@```/]U_/_67UY;R<((`%6+[+@`&```Z`%8__^+10B%P'0F -M9H,X`'0FC4T,45"-A0#H__]0_Q7$,4$`C84`Z/__4&H!Z++^____!?C!00#) -MPU6+[+@`%```Z+]7__]H``0``(V%`/C__U#_=0S_=0CH`\'__X!]&`"-A0#X -M__]0=`1J9NL":F7H1NG__U"-A0#L__]H``8``%#H-OC__X/$$(V%`.S__U!J -M9?\U`,)!`/\5U#%!`.@V^O__,\`X!?+!00`/E,#)PA0`58UL))BX4!(``.A# -M5___4U>+?7`SVU-3:(`W00#_=7S_=7C_=717Z`AW__^$P'0(,\!`Z0L#``"+ -M170M$`$``%9T:4@/A?8"```/MT5X:@)>*\9T&(/H:G1-2'032'1#2'0\2'0U -M2`^%TP(``&H%7E-3:'$!``!J9E?_%>0Q00`[PW0'4/\5X#%!`%97_Q7<,4$` -M,\!`Z:<"``!J!NO0:@/KS&H$Z\@S]D;KQ&IL5_\5<#)!`%#_%=@Q00"^``0` -M`%;_=7R-A1CN__]0Z!XO``!64XV%&.[__U#HUKW__XV%&.[__U!J95>+/=0Q -M00#_UV@``0``:+0"``"-A1CV__]04XV%&.[__U#_%:0Q00!3_[48]O__:'`! -M``!J9O]U0P00"-15A0C45(4/\5X#!!`&HRC46`4%.-15A0:@)6 -M_Q7<,$$`:C*-1>104XU%6%!35O\5V#!!`(U%@%"-1>10:($```#H:>?__U!H -M;#=!`+L``@``C87,^/__4U#H4_;__X/$&(V%S/C__U!J:O]US\__\S -MVP/!$]-24.A?^/__:(````#H]^;__U"-A1S___]0:&`W00"[``(``(V%S/C_ -M_U-0Z-KU__^#Q!2-A+`00!0_Q6(,4$`C4584(U%4%#_%>`P00!J -M,HU%@%!J`(U%6%!J`E;_%=PP00!J,HU%Y%!J`(U%6%!J`%;_%=@P00"-18!0 -MC47D4&B!````Z$OF__]0:&PW00"-AS`00"+#>C`00!T!HO1"]!T16HRC94<____4E!1Z%OW -M__]H@````.CSY?__4(V%'/___U!H8#=!`(V%S/C__U-0Z-OT__^#Q!2-A@Q00!J`>O@_W44:F96_Q74,4$`,\!` -M7EW"$`!J`/]T)!#_="0,Z)7V__]0:`($``!J:O\U`,)!`/\5Y#%!`,(0`%6+ -M[+@`(```Z-92__^`/?+!00``=46+10QF@S@`=#Q6_Q6$,4$`B_"-11!0_W4, -MC84`X/__4/\5Q#%!`(V%`.#__U!H!#-!`.B(^O__65F%]G0'5O\5@#%!`%[) -MP_]T)"#_="0@_W0D(/]T)"#H:/___^A!]?__PB``58OLN&`>``#H7%+__U;H -MU2D``&C0-T$`:/L)0@#H@.___XL-+")"`&C\,D$`Z!,M``#_=0AH+!I"`.C. -M\/___W4(OCC300!J`(O.Z/-J__]J!%BC[`5"`*/H!4(`H^0%0@"@Y^@7X___4%?H"FC__X3`=#O_-5`B0@#K*FH` -M5_\5W#%!`.LH:``$``#_-5`B0@!J95?_%>@Q00!J`>O?B350(D(`5FIE5_\5 -MU#%!`#/`0%]>7<(0`%6+[+@`%```Z`51__^`?0A4=`^`?0A8=1#'10AY```` -MZP?'10@+`@``:``$``"-A0#X__]0_W40_W4,Z"VZ__^-A0#X__]0Z"6[__]0 -M_W4(Z'/B__]0C84`[/__:``&``!0Z&/Q__^#Q!"-A0#L__]0:@#H>/?__\G" -M#`!5B^R![`0(``"#9?P`4U:+=0A7ZP)&1@^W!E#HSB@``(3`=?$/MP9FA<`/ -MA&P!```S_S+;A-MU#0^WP%#HK2@``(3`=4N!__\#``!S0P^W!FHB668[P74E -MC48"9CD(=19F.4X$=02$VW0.9HF,??SW__^+\.L/A-L/E,/K"6:)A'W\]___ -M1T9&#[<&9H7`=:0SP/]%_(-]_`%FB81]_/?__P^$#X4.____:``$ -M``"-A0+X__]0:!+*00#K=L<%#,)!``(```#K"L<%#,)!``$```#&!1;300`! -MZ=G^__]H@````(V%`/C__U!H$M)!`.M!#[>%`/C__U#H0S$``(/X3`^%L/[_ -M_V:#O0+X__\`#X6B_O__Q@41PD$``>F6_O__:``$``"-A0#X__]0:!+"00#H -MG"<``.E[_O__7UY;R<($`%6+[+@`(```Z.9.__]3B]E7BWT(A=MT`\8#`(M% -M$(7`=`/&``"%_P^$H0````^W!V:%P`^$E0```%8S]C/)#[?`1T=F@_@]=16# -M?0P`=!N%]G47A=MT`\8#`8ORZQMF@_@-="AF@_@*="1FB0*+111"@\#^0CO( -M?PL/MP=!9H7`=;SK"HM%$,8``>L"1T>+70PSP&:)`H7;="]FB0.%]G0H:``0 -M``"-A0#@__]05O\5Z#!!`/]U%(V%`.#__U!3Z,PF```SP&:)!HO'7NL",\!? -M6\G"$`!5B^R#[!Q6BS7L,$$`5VH*_W4(_]:_`@$``.L9:@%J`&H`:@"-1>10 -M_Q5(,D$`:@K_=0C_UCO'=.-?7LG"!`!5B^R!["`(``!H``0``(V%X/?__U#H -M&V0``(`]%=-!``!U:VH&_S6<4$$`C87@]___4.@&N/__4.@\+P``A#W__]0Z`'L__\SR6H>9HF,1>+W__]1C47@4.B\Z/__:A18 -M9HE%\(V%X/?__XE%Z(U%X%#'1>0#````_Q6@,4$`R<-5B^RX!"```.A!3?__ -M4U9H```"`.CCY___B_"%]G4*N7Q>00#HZV___S/`9HD&,]OK;6:#/@!U"F:# -MO?S?__][=%UF@[W\W___?71WC87\W___4.APZ___`\,]^_\``'=BC87\W___ -M4%;H\>O__U;H5.O__XO8A=MV$8U$7OYF@S@@=0=+2$B%VW?S@'W_`'4.:%@W -M00"-!%Y0Z%/K__]H`!```(U%_U!J`/\W,\F-E?S?___HHOW__XD'A<`/A6__ -M__^+QEY;R<-3,]O&!?'!00`!.1T`PD$`=!9J?>@BWO__4&H"_S4`PD$`_Q74 -M,4$`H0#"00")'?3!00#&!?#!00`!.\-T2VH!4/\5;#)!`#D=)--!`'4(.!T4 -MTT$`=`@Y'?C!00!U(E-J`6@1`0``_S4`PD$`_Q70,4$`ZPQ3_Q7P,$$`Z-GN -M__\Y'0#"00!U[#@=",)!`%MT!>D0_O__P_]T)`16Z(?J__\SR68Y#G0GB\8/ -MMQ!F@_HZ=`QF@_I<=`9F@_HO=09J)5IFB1!!C01.9H,X`'7;P@0`58OL@>P( -M"```4S/;.!T0PD$`=&QF.1W8L$$`=&-6:-BP00"-M?CW___HE____XU%^%"- -M1?Q04V@&``(`4U-3:/0W00!H`0``@/\5$#!!`%Z%P'4L_W4(Z-#I__^-1``" -M4/]U"(V%^/?__VH!4U#_=?S_%10P00#_=?S_%1@P00!;R<($`%6+[+@,$``` -MZ"!+__^`/1#"00``#X2-````5O]U"(VU].___^@7____C47X4&H!:@!H]#=! -M`&@!``"`_Q4`,$$`7H7`=6&-1?Q0C87T]___4(U%]%!J`(V%].___U#_=?C' -M1?P`"```_Q4,,$$`APQ00!H'#A!`(V%Y/?__U#H]"H` -M`(7`=6%J\%?_%4`R00"#X!\\#G51:@!J`&AS`0``5__3B_"%]G0_C47D4&H8 -M5O\53#!!`/]U[.C\[___4/]UZ.BP[___4%;HY.[__U!J`&AR`0``5__3.S78 -MN$$`=`=6_Q5@,$$`:@)7_Q64,D$`B_@[??QT"_]%"(7_#X5/____7EM?R<($ -M`%:+="0(:B!6Z&#I__^%P'0:9H,^(G045N@TL/__9H,X(G0(5NCI[___ZP*+ -MQE["!`!5B^Q6BS7P,4$`@#WFP$$``(M%#*/HP$$`BT40H^S`00"+112CX,!! -M`'0%,\!`ZRF`/>?`00``=`5J`ECK&_]U"&BNND``_S4`PD$`:(`W00#_-71> -M00#_UDAT3TAT7DAT0DAU(_]U"&CZO4``_S4`PD$`:*`W00#_-71>00#_UH7` -M=(:P4NLP2'0.2+!.=2C&!>?`00`!ZQ_&!?+!00`!L$/K%,8%YL!!``%J`/]U -M"/\5U#!!`+!97EW"$`"P3NOW58OL@>P`"```4U:+=0Q7BWT(:``$``"-A0#X -M__]05E?HT['___]U&(V%`/C___]U%/]U$%#H!?___XK8A?9T$V:#/@!T#8V% -M`/C__U!6Z.[F__^%_W07@#\`=!)H`````5>-A0#X__]0Z/HF``!?7HK#6\G" -M&`!5B^R![``(``!F@ST2TD$``%9T$?]U&(MU%&@2TD$`5NF+````@WT(`J$` -MPD$`B_!U#5#_%?0Q00"%P'4",_9H``0``(V%`/C__U#_=1#_=0SH*['__V:# -M/?#`00``=3&-A0#X__]0:(.^0`!6:+0W00#_-71>00#_%?`Q00"%P'4/BW44 -M9HD&Q@7RP4$``>L.BW44:/#`00!6Z"OF__]F@SX`=!!H@````%9H$M)!`.A% -MYO__,\!F.09>#Y7`R<(4`%6+[('L``@``%9H``0``(V%`/C__U#_=0S_=0CH -MGK#__XV%`/C__U!H.\!``/\U`,)!`&C4-T$`_S5X7D$`_Q7P,4$`@WT(`(OP -M=!1H`````?]U"(V%`/C__U#HSR4``(-]#`!T#XV%`/C__U#_=0SHD^7__XO& -M7LG""`!5B^RX0!```.C;1O__4U:+\3/;9CD>#X0;`@``5NA`Y?__/?8#```/ -M@PH"``!7:CQ?5U.-1%P`^5P(3`#X2O````BS5L,D$`,MLX -M'0C"00!U!3A="'0VH0#"00"%P'074/\5]#%!`(7`=`QJ`/\U`,)!`/_6LP%H -MT`<``/]U^/\5^#%!`/]U^.CY]O___W7X_Q5\,4$`@WW\`'01:"PX00#_=?SH -MV"4``(7`=#"`/0C"00``=`V`?0@`=0=H6!L``.L4,\`X10@/E,!()>#\__\% -MZ`,``%#_%?`P00"$VW00@'T(`'0*:@'_-0#"00#_UE]>6\G"!`!5B^RXV%`! -M`.B>1/__@WT,``^$$`L``&@`$```C44/4(V%T,?__U#_=0R-3?^-E2AO___H -M@/7__XE%#(7`#X3D"@``4U97:@:[``0``(V%T,?__XVU**_^_U]64.@9Z/__ -M@<8`(```3W7P,_;_-+6X4$$`C84H;___4.@*)0``A`0``BSU$,4$`:@"-A2BK__]0_Q74,$$`@+TX -ML___``^$J````.@6IO__.\,/A)L```"-A=#O__]0C870]___4.@=K/__C870 -M[___4.APJO__C870]___4.BAX?__B_"#_@1R$(V%T.___U#HCN'__SOP=Q:- -MA=#'__]0:@#HW:G__X3`#X77````C84HJ___4.AHX?__,\EJ'F:)C$4JJ___ -M48U%T%#H(][__VH46&:)1>"-A2BK__^)1=B-1=!0QT74`P```/\5H#%!`(V% -M**O__U#_UX/X_W1JC84HJ___4/\5;#!!`(7`=5DS]NL!1E:-A2BK__]0:.PX -M00"-A=#O__]34.@QX___@\04C870[___4/_7@_C_==2-A=#O__]0C84HJ___ -M4/\5<#%!`(7`=!%J!&H`C870[___4/\5^#!!`&H`C84HI___4(V-R+O__^CF -ME?__A,`/A:C^__^-C__]F -M@[Q%SO?__UQT$6B(-D$`C870]___4.ABW___5NC%WO__B_B-A=#W__]0Z+?> -M__\#^('__P,``',<5HV%T/?__U#H-]___^L-5HV%T/?__U#HN][__VHBC870 -M]___4.@4X/__A`(`=04SR6:)"(V%T/?__U"_V+!!`%?HB][__U.- -MA=#W__]0Z*WT__]J9O]U"/\5<#)!`(OPC870]___4%;_%3`R00"+'=`Q00!7 -M:@!H0P$``%;_TXV%T/?__U!7Z-#>__^%P`^$Y@4``(V%T/?__U!J`&A#`0`` -M5O_3Z=`%``"#/0S"00`!#X3#!0``#[>%T,?__U#HKQ<``(3`=!0/MX70Q___ -M@^@PHPS"00#IG@4``,<%#,)!``(```#ICP4```^WA=#'__\KQW0K@^@P=!-( -M="-(#X5U!0``Q@7GP$$``>L'Q@7GP$$``,8%YL!!``#I604``,8%Y\!!``#& -M!>;`00`!Z48%```/MX70Q___4.C^V?__@_A&="2#^%5T$\8%Y3` -M00``Z1P%``#&!>3`00`!Z1`%``#&!>7`00`!Z00%``"#?1`$=2%H<#A!`(V% -MT,?__U#HS]W__X7`=`Q7C8W0Q___Z*CW___&!2C300`!Z=$$``"#?1`!#X6' -M`0``C870[___4%/_%?0P00"-A=#O__]0Z)VE__\S]E;_-9Q000"-A=#O__]0 -M:&`X00"-A=#G__]34.CVWO__BSU$,4$`ZR%&5O\UG%!!`(V%T.___U!H8#A! -M`(V%T.?__U-0Z,W>__^#Q!B-A=#G__]0_]>#^/]USHV%T.?__U!J9O]U"/\5 -MU#%!`#/_9CF]T,?__P^$,`0``(`]%M-!```/A2,$```SP&:)A=#[__]J+(V% -MT,?__U#HG=W__X7`=4WK(8TT"8V$-=+'__]0C870^___4.@BW/__,\!FB80UT,?__V8YO=#[ -M__]U)HV%**_^_U"-A=#'__]0Z/S;__^-A2C/_O]0C870^___4.CIV___C870 -MQ___4.@&XO__,\!FB870U___:B2-A=#[__]0C870Q___4/]U"/\5:#)!`(/X -M!@^$6P,``&H!_W4(Q@45TT$``<8%\L%!``'_%=PQ00`S_X-]$`GG_?__@WT0!@^%Q0(```^WA2BO_O]0Z'W7__^#Z%!T(X/H`W05 -M2'0)QT7X$````.L9QT7X!P```.L0QT7X"P```.L'QT7X`@```#/`9HF%*)?_ -M_V:)A=#G__^-A2C/_O]0C870[___4.B]VO__9H.]T.___R)U0XV%*L_^_U"- -MA=#O__]0Z*#:__]J(HV%TN___U#HS-O__SO'#X2R````,\EFB0B#P`)0C870 -MY___4.AUVO__Z9@```"-A=#O__]0Z)F'__^$P`^%A````#/;C;70[___9CF= -MT.___W1S#[<&9H/X('0&9H/X+W53#[?X,\!FB0:-A=#O__]0Z%V'__^$P'0X -MB]YF@_\O=19J+UAFB870Y___C48"4(V%TN?__^L/1D9F@SX@=/A6C870Y___ -M4.CQV?__9HD[ZP-FB3Y&1F:#/@!UEH7;=`4SP&:)`S/V9CFU*$___W03C84H -ME___4(V%*$___U#H+J/__XV%*(___U"-A=#O__]0Z!NC____=?B-A=#W__]0 -MZ(??__^-A=#W__]0Z"6B__]F.;4H[_[_=!^-A2CO_O]0C870]___4.C=V?__ -MC870]___4.C]H?__C870]___4(V%T+___U#H4=G__XV%*"___V8YM2@O__]U -M!HV%*,_^_U#H\:3__U"-A=#W__]0Z);9__^-A=#W__]0Z&JG__\[QG0/:%0X -M00!0Z$@;``"%P'01:%0X00"-A=#W__]0Z&;9__]J`8V%T/?__U#H"8C__XV% -M*(___U"-A2B?__]0Z-C8__^-A2B?__]0Z,NG__^-A=#G__]0Z+H1``!0C84H -ME___4.BM$0``4(V%*`___U#HH!$``%"-A2B?__]0Z),1``!0C870]___4(V% -M*(___U#H;$\``&8YM="___]T)6H`C870O___4&H%:``0``#_%9@Q00#K#8-] -M$`=U!\8%$,)!``%H`!```(U%#U"-A=#'__]0_W4,C4W_C94H;___Z)_J__^) -M10R%P`^%(O7__U]>6\G"#`"0\\U``.W/0`!^T$``G-!``'W20`"^TD``2=-` -M`'S30``UU4``;=5``'[50`!`V$``!]-``%6+[+CX?0``Z#XY__]3Z+<0```S -MVU.-C0B"___HW3____]U"(V-"(+__U/H:3[__XU%]%"-1>A0C8T(@O__B5WH -MB5WLB5WPB5WTB5WXB5W\Z&!!__^$P'0WBT7X5E>--`"+^(U&`E#HC=/__XM- -M#(D!.\-U!#/_ZQ`SR59FB0P&_W7T4.@ZU/__BT40B3A?7CE=]'0(_W7TZ'73 -M__\Y7>A;=`C_=>CH9]/__XV-"(+__^BW0/__R<(,`%6+[%-7BWT(,]M34VC4 -M.4$`_W44_W40_W4,5^A36/__A,`/A=P```"+10PM$`$``'0>2'4.#[=%$$@/ -MA+L```!(=`W__VIE5_\5<#)!`&@` -M``$`:@"+V&@U!```4__6:@__%0`R00!0:@!H0P0``%/_UFH#_S48TT$`5^@A -M\___@ST@TT$``%YT+%?_%?PQ00#_-2#300"+#="P00!3_S5T7D$`Z`R9____ -M-2#300#H7]+__^L):@%7_Q7<,4$`,\!`7UM=PA``58OLN%QI``#H=S?__U-6 -MBW4(,]M34VBX.D$`_W44_W40_W4,5N@\5___A,!T"#/`0.FM!P``BT4,+1`! -M``!7#X0"!0``2'4/#[=%$$AT;TAT/H/H970',\#IA`<``(V%Q/?__U!J9.C. -MR/__4%;H14W__X3`#X1D!P``C87$]___4&IF5O\5U#%!`.E/!P``B1T`PD$` -MQ@7RP4$``3D=],%!`'0,.1WXP4$`#X4N!P``4U;_%=PQ00#I(0<``&@`!``` -MC87$]___4&IF5O\5Z#%!`#@=\<%!`'09B1T`PD$`.!WPP4$`=`?&!?+!00`! -M:@'KOC@=\,%!`'0/,__&!?+!00`!1^G.`P``:FA6_Q5P,D$`B44,.1WXP4$` -M=2&+/=`Q00!J_U-HL0```%#_UV@T-T$`4VC"````_W4,_]?_=0S_%=@Q00`X -M'0C"00!T#&BF````Z-_'___K2XV%Q/?__U"-A<#O__]0Z+C4__^-A<#O__]0 -MZ'GL__^-A<#O__]0:*4```#HK#^`5U!,9%#P'H1)C__X7` -M='(X'1'"00!U:CA=$W1^_Q60,$$`4&A\.D$`C87$[___:``$``!0Z!+6__^# -MQ!"-C:3?___HP7?__S/_1U>-A<3O__]04XV-I-___^@->___B$43.L-U#_\5 -MA#%!`(/X!74$QD4/`8V-I-___^AN>?__ZP,S_T.1WXP4$`=18Y'2S300!U#FH$_S48TT$`4^@.[O__5U=6 -MZ%!2__^)'?3!00`Y'?C!00!^5S@=\L%!`'5/:GW&!?'!00`!Z$/$__]05U;_ -M%=0Q00"A?%Y!`(/X"74%C5AZZP\SVX/X`P^5PTN#XP6#PW]J,&I^Z!/$__]0 -M4^@,Q/__4%;_%6@R00#K"%=6_Q7<,4$`B\?IFP(``*'0Q -M00!6Z'CG__^+/7`R00!J:%;_UV@``$``4V@U!```4(E%%/\5T#%!`&@`!``` -MC87$[___4.@@2```:F96_]>)11"X$L)!`&8Y'1+"00!U!HV%Q.___U#_=1#_ -M%3`R00#_=1#H"4@``&@DTT$`:!C300!HX+A!`(@=%--!`.@V^/__.1TDTT$` -M=@YJ!_\U&--!`%;HP.S__S@=%--!``^%A````#/`OY8```!FB86DEO__B7T, -M.7T,=0@X'2C300!T-X%]#)<```!U"#@=*--!`'4F:.PY00"-A:26__]0Z##0 -M____=0SHS<+__U"-A:26__]0Z!O0____10R!?0R<````?K`Y'0S"00!U&XL- -MU+!!`(V%I);__U#_=13_-71>00#H1)+__XL]U#%!`#@=*--!`'4@:*L```#H -M><+__U!J:U;_UVBJ````Z&G"__]0:@%6_]1____ -M-1S300#H*LO__X,]#,)!``%T.%;_%?PQ00"#/0S"00`!="@X'1'"00!U(%-H -M;]E``%-HU#E!`/\U=%Y!`/\5\#%!`(7`#X2'^?__:@'_-1C300!6Z&GK__^# -M/0S"00`"=0I3_W40_Q5T,D$`.!T(PD$`=!)3:F=6Z(]/__]3:F96Z(9/__^A -M#,)!`#O#="0X'?+!00!U'%-J`6@1`0``5H/X`74(_Q70,4$`ZP;_%00R00`X -M'?#!00!T#6I]Z&'!__]0:@%6_]__\X -M'1'"00!T16@,.D$`4VH$_Q4,,4$`B47\.\-T)6@```(`4U-J!%#_%00Q00"+ -M\#OS=`A6:-PZ00#_UU;_%?PP00#_=?S_%7PQ00#K"%9HW#I!`/_7:``$``"^ -MX+A!`%93_Q6H,$$`5FC,.D$`_]=3_Q6P,$$`B_AJ9%>)/71>00")/7A>00#_ -M%0PR00!J9?\U>%Y!`*/D4``%:YB%Y!`.A' -MP/__C4W`Z#.'__^-3=SH*X?__VIDZ&_4__]J9(E%V.AEU/__4VA\VD``B47T -M4XU%P*/4L$$`:+@Z00"-1=Q7H]"P00#_%?`Q00"-3=R)'="P00")'=2P00#H -M]H;__XU-P.CNAO__C4WXZ%9%```X'0C"00!T!>A2X/__:``!``!3:/#`00#H -M:\G__SD=)--!`'8+_S48TT$`Z-3(____-=RX00"+-6`P00#_UJ'8N$$`.\-T -M`U#_UCD=?%Y!`'47.!WRP4$`=`]H_P```+E\7D$`Z"%0__^A+--!`,8%\L%! -M``$[PW0&4.BAW____Q6T,D$`_S5\7D$`_Q7(,$$`S%6+[(/L)(!]$`!35E=T -M$FI`_W4,NZ`H0@!3Z`3)___K`XM=#(`]F"A"``!U3#/)OEPB0@"-00&9:@5? -M]_^-00*)3OR)%IGW_XU!`X/&%(E6\)GW_XU!!(E6])GW_XE6^(7)=`-)ZP-J -M!%F!_IPH0@!\PL8%F"A"``&+=0AJ!5F-?=SSI;AD(D(`B5T0BW40BQ:+RL') -M"('A`/\`_\'""('B_P#_``O*B0Z+/R+?+W<@T40!(UTM=R) -M=0R+<`2-=+7<,_J)=?B+06#YP\S!+N#X0\S!(LS!M'`B0:+OR+?+WAZ]EN`3#!"0+_11"#PA2!^H0E0@!\A;F`)4(`QT40*````(E-#(M% -M$(U0_8/@#XTT@XU"^X/@#XL$@XUZ!8/G#S,$NX/B#S,$DS,&T<")!HM1_(MY -M"(LQBW2UW(U4E=R-?+W?B+202+3(W6UW"$`!5B^R#[!!6BW4(,\"+T(/B -M`VH#62O*P>$#@_@$&]+WVHM4EA33ZD"(5`7O@_@(_O__,]N)7?R+1?R+50S!X`*+##")#!#_1?R#??P% -M!(0@!`H^!(0@"#^`1R!S/`H^!(0@!6P>`+!>`H0@!H -M``0``(OP5O]T)!#HKP4``#/`9HF&_@<``(O&7L($`%:^Z$A"`%;_="0,_Q44 -M,D$`B\9>P@0`@V$,`(-A'`##BT0D!%:+\0%&!(M.!(M&"#O(=BR+T,'J`E>- -M?`(@.\]V`HOY5_\VZ#W!__^)!H7`=0JY?%Y!`.@-2?__B7X(7U["!`!6B_&# -M9@P`@V8<`.@<$0``C4X0Z!01``"#9B``@Z:D`````%[#58OL4XM="%97B_&% -MVW4%NS(W00"#?0P`=0?'10PT-T$`BWX$4^@VPO__0%"+SNAD____BP93`\=0 -MZ!7#____=0R+7A2-?A#H2,3__T!0B\_HM";__XL'_W4,C0184.A;Q/___T8@ -M7UY;7<((`%:+\8M&##M&!'-#BTX<.TX4Q,0@"#^#)^+(`]\L%!``!T'E97O_\```"^?%Y!`%>+SNC&1O__ -M5XO.Z`%*__]?7ND_Q___PV@`.T$`_Q6P,$$`AIFBT8(9HE%[F:+1@QFB47P9HM&$&:)1?)FBT849HE%]#/`9HE%]HU%^%"- -M1>A0_Q4<,4$`BW88`77X.77X7G,#_T7\_W4(C47X4/\5&#%!`,G"!`"+$8M$ -M)`0[$'4UBU$$.U`$=2V+40@[4`AU)8M1##M0#'4=BU$0.U`0=16+410[4!1U -M#8M)&#M(&'4%,\!`ZP(SP,($`(L!@^@\P>`$"T$$P>`%"T$(P>`%"T$,P>`& -M"T$0BTD4P>`%T>D+P<.+1"0$B]"#XA\#THE1%(-A&`"+T,'J!8/B/XE1$(O0 -MP>H+@^(?B5$,B]#!ZA"#XA^)40B+T,'J%<'H&8/B#P6\!P``B5$$B0'"!`"+ -M3"0$]L$#=2%6B\%J9)E>]_Y>A=)U#HO!F;F0`0``]_F%TG4%,\!`ZP(SP,($ -M`(O!@R``PU6+[(/L(%97C47X4/]U"(OQ_Q7D,$$`C47@4(U%^%#_%>`P00`/ -MMWWH#[=%Y@^W3>(/MU7@B7X,#[=]ZHE&"(E^$`^W?>Q(B48@,\")?A0/MWWD -M0(D6B4X$B7X<.\AV%+_L4$$`4XL?`5X@0(/'!#O!R<($`%6+[%%15C/V.3%U!C/`,]+K'HU%^%#HUOW__VH!5E;_=?SH -M+R#__XM-^#/V`\$3UE[)PU-6B_&+3"0,5^B_____B\Z+V(OZZ+3___\[UW\+ -M?`0[PW,%,\!`ZP(SP%]>6\($`%-6B_&+3"0,5^B/____B\Z+V(OZZ(3___\[ -MUWP+?P0[PW8%,\!`ZP(SP%]>6\($`%;_="0(B_'HQ/___X3`=1/_="0(B\[H -MK_W__X3`=00SP.L#,\!`7L($`%6+[(/L&%:-1>A0B_'_%2`Q00"-1?A0C47H -M4/\5'#%!`(U%^%"+SNA@_O__7LG#,L#"%`!5B^Q1BT4,4S/;4U/_=1#&1?\! -M4&K__W4(B!A34_\5E#!!`(7`=0.(7?^*1?];R<(,`(M$)`A3_W0D$#/)4&K_ -M_W0D%+,!45%FB0C_%20Q00"%P'4",MN*PUO"#`"+1"0(5C/V.70D$'8?BTPD -M"(H1B!1PBE$!B%1P`6:#.0!T"49!03MT)!!RY5["#`!5B^Q6,_8Y=1!V+8M- -M"(M5#"O15V8/MD$!OP`!``!F#Z_'9@^V.68#QV:)!`IT"$9!03MU$'+=7XM% -M#%Y=P@P`58OLBT40BU4(2%.)11"*`E97BWT,A,`/A!H!``!J/UX/MLA"B\&! -M^8`````/@L````"#X.`]P````'4CB@**V(#CP(#[@`^%ZP````^^P(/A'R/& -MP>$&"\%"Z9,```"+P8/@\#W@````=3:*`B3`/(`/A<````"*6@&*PR3`/(`/ -MA;$````/O@*#X0\CQL'A!@O!#[[+P>`&(\X+P4)"ZU&+P8/@^#WP````#X6& -M````B@(DP#R`=7Z*0@$DP#R`=76*6@**PR3`/(!U:@^^`H/A!R/&P>$&"\$/ -MODH!P>`&(\X+P0^^R\'@!B/."\&#P@/_31!X0#W__P``=BK_31!X-#W__Q`` -M=RV-B```___!Z0J!Z0`H``!FB0]')?\#``!'+0`D``!FB0>*`D='A,`/A>G^ -M__\SP&:)!U]>6UW"#`"P`<-5B^RX`!```.@5'___Z,R!__^%P'0>:O__=0QJ -M__]U"&@!$```:``$``#_%2@Q00!(2.LZ5KX`"```5HV%`/#__U#_=0CHH_W_ -M_U:-A0#X__]0_W4,Z)/]__^-A0#X__]0C84`\/__4.AR]O__7LG""`!5B^RX -M`!```.BC'O__5KX`"```5HV%`/#__U#_=0CH.XC__U:-A0#X__]0_W4,Z"N( -M__^-A0#X__]0C84`\/__4.@G]O__7LG""`!5B^SH&8'__X7`=%565_]U".C) -MO/__BW40.\9S#/]U".BZO/__B_CK`HO^_W4,Z*R\__\[QG,*_W4,Z*"\___K -M`HO&4/]U#%?_=0AH`1```&@`!```_Q4H,4$`2%](7NL+_W4,_W4(Z$G___]= -MP@P`58OL@^P@Z*:`__^%P'0+_W4(_Q68,D$`ZTE6BW4(,\!FB47B:@J-1?10 -MC47@4&:)=>#HB?S__X!]]#]U!(O&ZR'_=?3HK_7__XA%]&@````!C47@4(U% -M]%#HE/S__P^W1>!>R<($`(M4)`0SP.L29H/Y.7<5:\`*#[?)0HU$"-!"#[<* -M9H/Y,'/EP@0`58OL@^P45E>-1>Q0,_96B_G_%3`Q00"#?>P!#Y?`B(<``0`` -M5O\5+#%!`(7`#Y7`B`0^1H'^``$``'+H7U[)PXM$)`0/MA"`/`H`=`N`>`$` -M=`6#P`+K`4#"!`"+1"0$5NL7#[;R@#P.`'0$0$#K"@^^TCM4)`QT"4"*$(32 -M=>,SP%[""`!6BW0D"(H6,\"$TG0A5P^V^H`\#P!T!$9&ZPP/OM([5"00=0*+ -MQD:*%H32=>%?7L((`%:+\>A`____B\9>PXM$)`P/ME0(!(M$)`@/MD0(!"O" -M:](,`U0D!%8/MG0(*500#HLS[__S+`ZPZ-1##TB8=8`0``B1^P -M`5Y?6\($`%6+[%%14U97:)@```"+\6H`C8:X````4.@#M___BSZ+QYF#X@<# -MPL'X`VH,6S/2]_-J##/2BXZL````B8Y0`0``B]AKVU0K^XO'B47X7_?W:@PS -MTD!KP`R-/`B+1?@#R(F.7`$``%F+P_?Q:@1:4HF^5`$``(F^L````%EKP`P# -MQXF&M````#/`0(A$!@-`2G7X0(A$#@1!0$"#^0A\]$#K"(A$#@1!@\`#@_D, -M?/-`ZPB(1`X$08/`!(/Y)GSS,\G'1?S7____*77\B(ZJ````C48JQT7X@``` -M``^V5`X$BWW\,]L#^#O7#YS#`\N("$#_3?AUY5]>6\G#58OLBT4,4U:+\0^V -M7#`IBT40#[94,"F)70P[VG4%BT4(ZT2-C):X````5XLYA?]T)HM="&O`#(L7 -M4%-7B1'H#[;__XM%#(V$AK@```"+"(D+B1B+Q^L/4E/_=0B+SNC3_?__BT4( -M7UY;7<(,`%-55HMT)!"+AE`&```/M@"*A#!L"0``B(9N"@``5XUY`HM)"`^W -M"0^V%P^VE#)L"0``#[9?`0^VC#%K"```P>,%`].-C%'X!```BY9D!@``P?H: -M@^(@`\H/MI9M"@```\H/ML"-EG!*``#!:@@.BVH(`\B+0@0K`C/2]_6-#$X/ -MMQD[PW-&B;Y0!@``BD?$H```^W`0^WT(/" -M(,'Z!RO"9HD!QX:`2@```$````^W`8J.;`H``,'H"@^V@!0[00")AE@&``#' -MAE0&```!````#[8'B(PP;`8``(.F4`8```#&AFT*````7UY=6\($`&@``0`` -MQH%L"@```6H`@<%L!@``4>AOM/__PXV!>,H``(L0B9%\R@``C9%TR@``5HLR -MB3"-@7#*``"+"(D*BTPD"(D(7L($`%6+[%-6B[&,R@``B\8K10RZ__X_`%<[ -MP@^#L````#OR#X.H````BY$TS```BWT(`\(#U@/W:@B)L8S*``!>._YR/(O/ -MP>D#BAB(&HI8`8A:`8I8`HA:`HI8`XA:`XI8!(A:!(I8!8A:!8I8!HA:!HI8 -M!XA:!P/&`]8K_DEUR87_#X:"````B@B("H/_`79YBD@!B$H!@_\"=FZ*2`*( -M2@*#_P-V8XI(`XA*`X/_!'98BD@$B$H$@_\%=DV*2`6(2@6#_P9V0HI`!HA" -M!NLZ@WT(`'0TO___/P"+L33,``"+F8S*``#_30B+T"/7BA0RB!0>BY&,R@`` -M0$(CUX-]"`")D8S*``!UT5]>6UW""`!6B_&+CI3*``"+!E>+^2OX>00RP.MA -M/0!```!^'(7_?@V+3@A7`\%04>BTL___@R8`B;Z4R@``ZP*+^8M.#+@`@``` -M*\>#X/!0BT8(`\=0Z/2?__^%P'X&`8:4R@``BXZ4R@``@^D>B8Z8R@``,\F# -M^/\/E<&*P5]>PU:+\8N65,P``(N&1,P``#O0BXY`S```5XN^4,P``'\[?`0[ -M^7,U*\\;PC/_._A3BUPD%'P(?P0[V78"B]F+3@Q3_W0D%.CFH/__BT0D%`&& -M4,P``%L1OE3,``!?7L((`%6+[('L@````%.+71!6BW4,5VI`,_]7C47`4(D> -MZ#:R__\SR3O?=A6+10@/M@0!@^`/C42%P/\`03O++ -M30R+3(V\`PH#P/]%#(EZQ(E*!(/"!(-]#!!RTVI`4XU%@%#HYK'__XM]$#/2 -MA?]V(HM%"(H$`B0/=!,/ML"-1(6`BPB)E(Z(%```08D(0CO7 -M`\+#B\&*2`*`^0=S%/Y(`W4/9M$@L@/2XO[!B$@"B%`#PU6+[%%15HMU"%>- -M??BE9J6+=0R+?0BE9J6+?0R-=?BE9J5?7LG""`"+`87`=`90Z/FO___#5HOQ -M@3[B?P``?@7H.OW__XL.BT8(#[8$"$&)#E[#5HOQBP:%P'0)4.C+K___@R8` -M@V8$`(-F"`!>PXM$)`16B_$!1@2+3@2+1@@[R'8QB]#!Z@)7C7P"(#O/=@*+ -M^8O'P>`"4/\VZ*RO__^)!H7`=0JY?%Y!`.A\-___B7X(7U["!`"+1"0$5HOQ -M@V8$`(,F`(-."/]7:@2)1AA?BTX8Z%S___^+3@3!X0@+R$^)3@1UZE]>P@0` -M58OLBX&P````@^P0.X&T````=`/&``!35HU%\%>)1?B)1?2->02-D;@```#' -M1?PF````OO__``#K*(L"BQB)&HU=\(E8"(M=](E8!(M=](E#"(O>B47T9HD8 -M9@^V'V:)6`*#.@!UTX/"!$?_3?QU\HM5](U%\#O0#X30````ZRP/MW@"#[=: -M`@/[@?\```$`?2J+>`B+6`2)7P2+>`2+6`B)7PAFBT`"9@%"`@^W0@)KP`R+ -M_@/"9CDX=,2+4@2-1?`[T'7FZ8````"-0@2+&(/""(LZB5\$BP"+$HE0"`^W -M1@(]@````'XHC9!_____P>H'0HOZ:_^``\>+N4P!``")/HFQ3`$``('&``8` -M`$IUZ0^V?`$I#[94.00[T'0>#[9<.0-/B]`KTRO":\`,C921M````(L:`\:) -M&(D"C82YN````(L0B1:),(M5](U%\(OR.]`/A7#___]?7EO)PU:+\8"^J@`` -M``!7BWPD#'4?QH:J````_^B#_O__C8R^N````(L!AP@0`C9&T````BP([@;````!T!H/`](D"PXV1N````(,Z`'0'BP*+ -M"(D*PVH`Z-_^___#58OL4U:+=0Q7B_D/MEP^*0^V1#XJ.]AU!8M%".LNC48! -M4.A4____B44,A -M6UW""`!3B]F+3"0(@<&,2@``Z&O___^%P'0>5HMT)!17,\E!9HD(BTPD%(UX -M`J5FI5^)6`B)00)>6\(,`(O!,\F)B(Q*``")B$0&``")B$P&``")B$@&``## -M58OL@^P44U97OP`!``!7B_%J`(V&;`8``%#H?*S__XV>C$H``(O+Z$_U__^+ -MAF`&``"#^`Q\`VH,6(/)_RO(B8YH!@``B\OHW/[__XF&3`8``(F&1`8``(-@ -M"`"+AF`&``")AEP&``"+AD0&``!FB3B+AD0&``"Y`0$``&:)2`*_@````%>+ -MR^A&_O__BXY$!@``B4$$BX9$!@``BT`$B890!@``BX9H!@``,\F)AF0&``"( -MCFT*```SP(N61`8``(M2!(@,$(N61`8``(M2!,9$`@$!BY9$!@``BU($@V0" -M`@"#P`9!/0`&``!\S8-E_`"-AG`*``")1?"+7?R+1?"#PP*Y)#M!`(E%](M% -M](E%^,=%[`@````/MP&9]_NZ`$```"O0BT7X@T7X$/]-[&:)$'7D@T7T`D%! -M@?DT.T$`?,G_1?P!??`Y??Q\K3/2C4X#C4(":A!KP"A>QD'_`V:)0?W&`02# -MP01.=>]"@_H9?.!?7EO)PXM$)`135HOQ,]M#5XB>;`H``(F&8`8``.AK_O__ -M:@EJ!(V&;@@``%#&AFP(````QH9M"````NCHJO__:/4```!J!HV&=P@``%#H -MU:K__S/`B(0&;`<``$"#^`-\\XO0B_NY``$``.L/3XB4!FP'``!U!$.+^T)` -M.\%\[6I`:@"-AFP)``!0Z)BJ__]HP````&H(C8:L"0``4.B%JO__7\:&0@8` -M``=>6\($`%6+[(/L(%.+V0^W`XE%Z$B)1?R+10B+@%`&``!65^L,C7#Z5E#H -MG?G__XO&.T,$=>^+2P2`00$$C4L"9H,!!`^W$0^V<`$/M](KUHMU"(E5^#/2 -M.99R#P`:) -M5?`#UM'ZB%`!9@^VTF8!$8I0`3I0^W8UB_"-?>"EB]!FI8UR^HOZI8/J!F:E -MB57P.U,$=!"+5>"+=?#!Z@@Z5ON+UG?=C77@B_JE9J7_3?QUH$"`.`!UR-??"E9J6+5?#! -MZ@B*VM#K*M/1^(/X`8A5\7_JBT7HBU4(BW7L0-'X#[:$$+5*``"-A()$2P`` -MBSB)/HDPB8I0!@``C77PB_FE9J7K/HM%^(O0T?HKPF8!`8M-Z`^W`T'1^4#1 -M^#O(=!9048M-"/]S!('!C$H``.C:\O__B4,$BT,$BTT(B8%0!@``7UY;R<($ -M`%6+[('L"`$``(!]"`!3B]F+@U`&``"+BT0&``!6BW`"5XV]^/[__W42@WD( -M`(F%^/[__XV]_/[__W11BT4,A#QP2#>0@`=<[K`XM(`HV%^/[__SOX -M#X2%````BA9&B77Z#[`B%_W129H,_`70\BW<$.`YT'X/&!C@.=?F*1@$Z1OMR -M$(U&^E!6B47LZ,/V__^+=>R*1@&+3>`\P[@^A+``!SSCE5XG0\.47B=Q!64HO+Z./] -M__^)1>*%P'2T_XM*)1>R+@TP&```SR3N#1`8```^5P2F+W$L` -M`.L2BXM0!@``B4$"BX-$!@``B47BBX-$!@``#[9-X0^W,`^W>`(K^2O^B77T -MB[-,!@``1XE-Z(E]\(EU^#OP=1J+1>*)@T0&``")@TP&``!?7EO)PXMU^(M] -M\`^W!HE%_(/X`71:J`%U']'H4/]V!(V+C$H``.CC^/__B48$A<`/A`K___^+ -M1?S!X`.-3@(/MQ$/M]([PHM%_!O2P>`"0CE%]!O`0&8CT(M%_`/`9@/2.T7T -M&\#WV&8#T`^W`>M4:@&-BXQ*``#H#/C__X7`#X2[_O__BU7XC4X"B_&+^*5F -MI8E"!(I0`8#Z'G,'`M*(4`'K!,9``7AF#[9``8M]\(MU^&H#6CM5]!O2]]IF -M`Y-8!@``9@/0#[?"9HD1#[?0C4(&#Z]%Z`/7B_IK_P8#P#O'B57XB_IS&L'G -M`CO'&_]'.]`;P/?8C50'`0^W`8/``^LF:_\/.\<;_VO2#$<[PAO20@/ZBU7X -M:]().\(;P$"-5`<$#[R+QVO`!@-&!$>)2`**3>"("(A0 -M`6:)/HMV"(EU^#NS1`8```^%JO[__^F1_O__BT0D"%.+7"0(B8-0!@``@$`! -M!%>+^6:#1P($BD@!.DC[=B!6C7#Z5E#H$O3__XFS4`8``(!^`7Q>=@A3B\_H -M-OK__U];P@@`58OL#[=!`E-6BW4(B8:$2@``C9YP2@``BT,(,]+W -M6UW"!`"+AE`&```/M@"*A#!L"0``B(9N"@``B99\2@``#[8'BI9L"@``B)0P -M;`8```^W`8F&5`8``$B#IE`&````BI9L"@``@^\&2`^V#XB4,6P&``!UZHN& -MA$H``(F&@$H``.N6BT0D"%:+="0(B890!@``@$`!!&:#00($@'@!?'8&5NC/ -M^/__BX9H!@``_H9L"@``B89D!@``7L((`%6+[%$/MP&Z``$``%=F.\)T9E,/ -MM_B+10PSVU:+=0@YAE0&```/MI0&:P<```^?PXE]_&O_"XT$DP^W40*+20@/ -MMPDSVSO7#YS#*TW\,](Y30P/MHYN"@``#YS"C01#C01"`\&-/(:+S^C5\?__ -MB8:$2@``7EOK$XM%"(VX0`8``,>`A$H```$```"+QU_)P@@`58OL@>P(!``` -M4U:+=0A7B]D/MSLKOE0&``!75NA-____B47\C87X^___B44(BT,$@^@&@V7X -M`(J.;`H``(/`!@^V$#B,,FP&``!TZP^V4`&+3?@#RHM5"(-%"`1/B4WXB0)U -MTP&.A$H``(V^<$H``(M'"#/2]W<4,]*)10B)1PB+1P0K!_=U"(N6A$H``#O" -MB44(?`- -MOHQ*``"+S^C`Z?__:@&+S^C+Z?__:@*+SN@:]O__7U[#58OL45-65XM]"(OQ -MB\_HJ_#__XO8B5T(P>L%@.,!=%*+S^B7\/__B47\]D4(0'0,B\_HA_#__XM- -M#(D!5XV.<$H``.CY\/__A-MT18M%"(/@'T"+V(/[$'X&:]L#@^L@C8Z,2@`` -M@_L!=13H.^G__^L)@[Z,2@```'6O,L#K'8M%_$!0Z#;I__]3B\[HAO7__S/` -M.89$!@``#Y7`7UY;R<((`%:+\8N.1`8``(N6W$L``%<[RG8EB[[D2P``.\]W -M&V:#.0%T&XM!!#O"=@X[QW<*5NBY^___A,!U#(/(_U]>PU;HFNK__XN.?$H` -M`(V&>$H``(L0B_H/K_D!OG!*``"+OH!*```K^0^O^HDX@[Y0!@```'0W@[Y< -M!@```(N&4`8``%,/MA@/A;T```"+0`([AMQ+```/AJX```")ADP&``")AD0& -M``#IM````(N&<$H``(N.>$H``(T4"#/0@?H````!___XL/P:9X2@``",'A"`O!P:9P2@`` -M"(D'ZZB+AMQ+``"+CD0&``#_AEP&``"+20B)CD0&```[R`^&$____SN.Y$L` -M``^'!____P^W$3N65`8``'3,5NBU_/__Z>W^__^+SNAY]___@+YL"@```'4' -MB\[HK^K__XN&<$H``(N.>$H``(T4"#/0@?H````![__XL/P:9X2@``",'A"`O!P:9P2@`` -M"(D'ZZB+PUOI??[__U-65XOQZ%M8__^+5"00BYJ$````)?[_```[1)H$)3@3!ZP,!'BL$ -MNFH062O/T^@#1+I$.P)R`C/`BX2"B!0``%]>6\($`%-6B_%7C7X0B\_HF?W_ -M_XO8@_O_=0Z+S^C"_/__@Z8PS````%]>B\-;PU:+\8U.(.B![?__C4X4Z'GM -M__^+SE[I<>W__U97BWPD#(-_&`"+\79/BX90S```4XE'1(M'%/^V4,P``(/` -M)(V>`$P``%"+R^A%=?__BX90S```BY94S```L2#H:@#__U"+1Q2#P"A0B\OH -M(W7__U>+R^@*AO__6U]>P@0`BT0D!%97BWPD$(OQ._AT.\:&2LP```%S,HO( -M]]F!X?__/P!1BXXTS````\A1B\[HK.K__U?_MC3,``"+SNB>ZO__QH9)S``` -M`>L3BXXTS```*_@#R%=1B\[H@NK__U]>P@@`58OL@>RL`0``5HOQBX:4R@`` -M@^@9.09^#>CEZ?__A,`/A&`"``"+1@3WV(/@!U"+SNBZ5O__B\[HRE;__ZD` -M@```=!^-AOQ+``!05HU.$,>&,,P```$```#HG?O__^DC`@``4S/;B9XPS``` -MB9Y+SNAE5O__P>@,#[;`:@2+SHE%_.@\5O__BT7\@_@/=3B+SNA$5O__P>@, -M:@2+S@^V^.@>5O__A?]U!\9$'>@/ZQM'1^L,3X/[%',*QD0=Z`!#A?]_\$OK -M!(A$'>A#@_L4?)UJ%(V&/+$``%"-1>A0B\[HR^G__S/;BX:4R@``@^@%.09^ -M#XO.Z-OH__^$P`^$W0```(V&/+$``%"+SN@?_?__@_@0?1F*C#.\)@\<+:@>+SNAA5?__ZQA/@?N4`0``?6**A!U3_O__B(0=5/[_ -M_T.%_W_DZT%U$>A15?__B_C![PV#QP-J`^L/Z$!5__^+^,'O"8/'"VH'B\[H -M&%7__^L23X'[E`$``'T9QH0=5/[__P!#A?]_ZH'[E`$```^,&/___XL&.X:4 -MR@``QH9H3````7X$,L#KCK4___C4X0Z,GM__^- -MC@!,``#HMG'__XV.-$P``.C-4___,\F-AD!,``")"(E(!(E("(V&3$P``(D( -MB4@$B4@(C8983```B0B)2`2)2`B+1"0(B48,B8XTS```B(XXS```B(Y(S``` -MB(Y)S```B(Y*S```B\9>P@0`5E>+\>B84___,M*I`(```'0(BT8$L0%`ZPZ+ -MR(M&!,'I#K(!(LI`0(OXP>\#`3Z#X`>$R8E&!`^4P(B&:$P``(32=12$R70+ -MB\[HD/S__X3`=`4SP$#K`C/`7U[#5HOQC4X4Z)?[___V1"0(`70'5NA7G___ -M68O&7L($`%6+[(/L&(-E_`!35HOQBXZ0R@``BX:,R@``*\$E__\_`(.^4$P` -M``!7#X;-`@``BU7\B[Y,3```P>("BQPZB57XA=L/A*$"``"`>PP`=`G&0PP` -MZ9("``"+4P2+.XE5[(O7*]&!XO__/P")?>@[T`^#=0(``#O/=!A748O.Z'[[ -M__^+AHS*```KQXO/)?__/P"+5>P[T`^'?P(``(T$.B7__S\`B47L._AR,X7` -M="^X``!``"O'4(E%\(N&-,P```/'4(V.`$P``&H`Z`QQ____=>S_MC3,``#_ -M=?#K#(N&-,P``%(#QU!J`(V.`$P``.CGA-_O__BX9,3```@R0#`(M%_$`[AE!,```/@PT!``")1?3K`XM=^(N&3$P` -M`(M<`P2%VP^$\P```(M%Z#D##X7H````.7L$#X7?````@'L,``^%U0```%?_ -M=?"-C@!,``!J`.CE;___BT,0BXY`3```BSR!BT@__?__BX9,3```@R0#`(M%]#N&4$P```^"^/[__XM.#%?_=?#H287__XM- -M[(V&4,P```$XQH9*S````8-0!`"+AHS*```KP27__S\`_T7\BU7\.Y903``` -M#X(S_?___[:,R@``48O.Z/;X__^+AHS*``")AI#*``!?7EO)PXM5_.L8BX9, -M3```BP20A-CEA, -M``#HX^7__X.F9$P````S_SF^1$P``'8=BX9`3```BPRXAZ7;E__^+P3/)B0B)2`2)2`B)2!2)2!B) -M2!R)2"")2"2)2"B)2`R)2$R)2!##5HOQBX8TS```A3__XV.0$P``.C>Y/__ -MC8XT3```Z-].__^-C@!,``#HH6S__XV.G$H``.BWW?__B\Y>Z<%.__]3,]M6 -MB_$Y7"0,#X6I````5VH04XV&<,H``%"(GFA,``#H&)7__VB4`0``4XV&G,H` -M`%")GH#*``")GHC*``")GH3*``#H])3__[\T&0``5U.-AFQ,``!0Z.&4__]7 -M4XV&H&4``%#HTY3__U=3C8;4?@``4.C%E/__5U.-A@B8``!0Z+>4__]74XV& -M/+$``%#HJ93__XO.B9Z0R@``B9Z,R@``QX;\2P```@```(F>,,P``.@V_O__ -M7XE>!(D>B9Y0S```B9Y4S```B9Z4R@``B9Z8R@``7EO"!`"+1"0$5XOYA6W49N7Q>00#H -MHQO__^L-B8+^8VW -M-$P``(-F!`"#)@"X`(```#E%$(EU_'\#BT404/]U#/^W/$P``.@"E/__C8\` -M3```B4WTZ"MK___V10B`=!Y6Z&%K__^+V(E=^(7;=0F+S^A;_?__ZQ%+B5WX -MZPN+AV1,``")1?B+V(N'1$P``#O8=TD[GUQ,``!W03O8:F2)GV1,```/E$43 -MZ#B9__^+\%F%]G0*C4X4Z)#]___K`C/V@'T3`'1_@?L`!```=A:%]G0):@&+ -MSNB.^?__,L!?7EO)P@P`C9]`3```:@&+R^CKXO__:F3HZYC__UF)10R%P'00 -MC4@4Z$+]__^+10R)10SK!(-E#`"+AT1,``"+"XM5#(E4@?R+AT1,``!(:@"- -MCUA,``")1A#H./C__XM%#(-@"`#K$HN'0$P``(L$F(E>$/]`"(E%##/`B47P -MB47L.8=03```=C^-GTQ,``"+"XL,@8O0*U7PBP.)#)"+"XM%[(T,@8,Y`'4# -M_T7PBU7PA=)^`X,A`$")1>P[AU!,``!RRX72=1*-GTQ,``!J`8O+Z"GB__\S -MTD*+AU!,``"+"_]U_"O"B32!BT4,BT`(B48(Z/!I___V10A`B47P=`>!1?`" -M`0``BX>,R@```T7PN___/P`CP_9%""")!G09_W7\Z,!I__^+5?B)1@2+CUA, -M``")!)'K&XM%^#N'7$P``',+BX]83```BP2!ZP(SP(E&!(N'D,H``(N_C,H` -M`#O'=`XKQR/#.T7P=P4SP$#K`C/`:AQJ`(U>0%.(1@SHOI'___9%"!"+1@2) -M1E"+1@C'1DP`P`,`B494=#V+3?SH;TO__XM-_(OX:@?![PGH24O__X-E\`"+ -M3?`SP$#3X(7'=`K_=?SH'&G__XD#_T7P@\,$@WWP!WS>@'T3``^$CP```/]U -M_.C\:/__B_B)?1"!_P```0`/@P#^__^%_P^$^/W__U>-3>#HE/;^_S/;A?^+ -M?>!V*HM-_(L!@\`#/0"```!S.NCI2O__BTW\P>@(:@B(!!_HPDK__T,[71!R -MUHM=#(M-](U#%%#_=1!7Z,IV__^%_W0>5^A@D/__ZQ:%_P^$E?W__U?H4)#_ -M_^F*_?__BUT,BT,4B48@BT,DB48DBT,XC4C_B440@?G^'P``=QB-?C10B\_H -MUL[___]U$/]S-/\WZ,20__^#?BQ`P'````BT40_S"+3?3_=0SHUF?__X-%$`2#10P$_TWL -M=>/_=@2+3?2-1QQ0Z+IG__^+3?1J`(U'(%#HK&?___]V"(M-](U'+%#HG6?_ -M_VH0:@"#QS!7Z!.0___V10@(='F+1?R+"(/!`X'Y`(````^#M/S__U#HF6?_ -M_XOX@?_`'P``#X>@_/__BW8LC4=`._!S#XO'*\:#P$!0B\OH_LW__XLS@\9` -M,]N%_W8MBTW\BP&#P`,]`(````^#:?S__^A[2?__BTW\P>@(:@B(!#/H5$G_ -M_T,[WW+3L`'I2OS__U6+[(/L$%-65XOQZ`I)__^+^(M&!(/`",'O"(O(P>D# -M`0Z)??R+V(/C!X/G!T>)7@2#_P=U%(O.Z-U(__^+^,'O"(/'!XU#".L1@_\( -M=1N+SNC$2/__B_B-0Q"+R,'I`P,.@^`'B48$B0Y7C4WPZ'KT_O\SVX7_?D6+ -MAI3*``!(.09\$HO.Z-#;__^$P'4'C4?_.]A\38O.Z'U(__^+3?#!Z`B(!!F+ -M1@2#P`B+R,'I`P$.@^`'0SO?B48$?+M7_W7PB\[_=?SHM?K__X-]\`"*V'0( -M_W7PZ"V.__^*PU]>6\G#@WWP`'0(_W7PZ!B.__\RP.OI58OL@^P44U97B_F) -M??SH1O#__XOP@\O_B77X._-U!#+`ZWV#Y@=&@_X'=1"+S^@F\/__.\-TZ(UP -M!^LB@_X(=1V+S^@1\/__B_`[\W31B\_H!/#__SO#=,;!Y@@#\%:-3>SHD?/^ -M_XM][#/;A?9^%8M-_.CA[___@_C_="B(!!]#.]Y\ZXM-_%97_W7XZ/KY__^* -MV(7_=`97Z':-__^*PU]>6\G#A?\/A'+___]7Z&&-___I9____U6+[(/L#%-6 -M,]M7B_$Y'3Q.0@!U3(E=^#/_BQ2=:%%!`(72?C92C8?\34(`B\M3QT7\`0`` -M`--E_%")5?3H;)3__X/$#(M%^(D$O3A.0@`#1?Q'_TWTB47X=>I#@_L3M -M`P``@+Y(S`````^%@0,``(.^,,P```$/A><```"-3A#H#NS__XO8@_O_#X1J -M`P``.Y[\2P``#X6W````B\[H2.[__X7`=12+SNA'[___A,`/A3[____I3@,` -M`(/X_P^$10,``(/X`@^$/`,``(/X`W4)B\[HN?W__^O3@_@$=50S_\9%"P`S -MVX!]"P`/A1<#``"+SNCR[?__@_C_=0;&10L!ZQ(/ML"#^P-U!8E%].L%P><( -M`_A#@_L$?,R`?0L`#X7C`@``BT7T@\<"@\`@Z:\"``"#^`5U&HO.Z*OM__^# -M^/\/A,`"``!J`8/`!.F1`@``BX8TS```BXZ,R@``B!P(ZR:-AFQ,``!0B\[H -MX.S__[H``0``.\)]&HN.-,P``(N6C,H``(@$$?^&C,H``.E?_O__N0\!```[ -MP0^,'P$``"O!#[:X2%%!``^VF"Q100"#QP.)?0B%VW8EB\[H]$3__VH062O+ -MT^@#^(M&!`/#B\C!Z0,!#H/@!XE]"(E&!(V&H&4``%"+SNAC[/__#[:8_$U" -M`(L\A3A.0@!'A=L/AI4```"#^`E^;H/[!'8GB\[HH$3__VH462O+T^C!X`0# -M^(M&!(U$&/R+R,'I`P$.@^`'B48$BX9@S```AL)BU'\B1%(@^D$A<,H``.@6Z___#[:X2%%!``^V@"Q100!'1XE%"(7`=B2+SNA=0___:A!9 -M*TT(T^@#^(M&!`-%"(O(P>D#`0Z#X`>)1@13B9Z$R@``B;Z(R@``5^M>/1`! -M```/C6+\__\/MK@=4$$`#[:8%5!!`"T'`0``1X7;=B*+SN@&0___:A!9*\O3 -MZ`/XBT8$`\.+R,'I`P$.@^`'B48$5XO.Z.C4__]J`EB)OH3*``")AHC*``!7 -M4(O.Z/W4___I`_S__\:&6,P```#K%HU.$.C(Y___@Z8PS````(O.Z(+O__]? -M7EO)P@0`@WPD!!UT!X-\)`0D=0G_="0(Z!S[___""`#_="0(_W0D".@]IO__ -MA<`/E<#""`!5B^RX%!@``.B,[?[_4U:+=0B+AI`3``")1>R+AJ1*``!7B47X -M@_AZ=0N-CN!7``")3?SK#HV.T$H``(E-_(/X='4*]D$(`L9%"P%U!,9%"P"+ -M?0R%_W0_@'T+`'0Y@'D@%'(SBT$8@_C_="OWT#F'$`4``'0A@\$P4>@WQO__ -M4&IRZ,A^__]0C888!```4.@BFO__@\0,B\[HD##__XE%\(E5](7_=!*+SHV? -M^`0``.@X-O__`0,14P2+SNBX+___C4874(V%[/O__U#H`8K__XV&&`0``%"- -MA>SO__]0Z%F+___VAL!*```0=`V`OK!Q````=00RP.L#,\!`4+L`!```4XV% -M[.___U"-A>S[__]0Z$I;___&10\`Z:$```"%_W0.@Z<`!0```(.G!`4```"` -M?0\`=5Z-1A=0C87L]___4.B*B?__C888!```4(V%[.?__U#HXHK__VH!4XV% -M[.?__U"-A>SW__]0Z/!:__]J`&H`C87LY___4(V%[/?__U"+SL9%#P'HB##_ -M_X3`#X6&````BT7L@+AH+0````^%G@```(V%[.___U"-A>S[__]0Z#+^__^$ -MP`^$@P```&H`:@"-A>SO__]0C87L^___4(O.Z#PP__^$P`^$/O___VH!B\[H -MQO#^_X!]%%2-AA@$``!0C4874`^5P(T$A50```!0Z'V:__^`?0L`B\YT<_]U -M^.@2`?__ZVZ-A>SW__]0C87L^___4.BCB/__C87LY___4(V%[.___U#H^XG_ -M_^N>:G?H!'W__U"-A>SO__]0Z%Z8__]963/_5U>-AA@$``!0C4874(O.Z*8O -M__]7_W7TB\[_=?#H"S3__S+`Z9@```#H[?7^_X.^I$H``'1U*HO.Z/CT_O^+ -MAJAQ```KAJA7``"+CJQQ```;CJQ7``!J`%%0B\[HS#/__X7_=%J#??A[=0G& -MA\8$````ZR.+1?R*2`C0Z8#A`8B/Q@0``(N(V`P``(E/((N`W`P``(E')(O. -MZ/,S__^#I^@$````@Z?L!````(./$`4``/^)A]`$``")E]0$``"P`5]>6\G" -M$`!5B^Q14XU%_%!H>#M!`&H!,]M3:"@\00#_%;`R00"%P`^,C````(M%_/]U -M"(L(4/]14#E=%'0,BT7\_W44BPA0_U$<.5T8=`V+1?R+"%/_=1A0_U%$.5T< -M=`R+1?S_=1R+"%#_42PY71!T#(M%_/]U$(L(4/]1)(M%_(L(C54(4F@8/$$` -M4/\1A+?0AJ4(V%8/___U!7_Q7L,4$`AA?]T"6H05_\5O#%!`%_) -MP@0`58OL45%65XL].#%!`(OQ@V8$`(,F`&A<.T$`_]=H0#M!`(D&_]>)1@2- -M1?A0QT7X"````,=%_/\'``#_%2PP00!H*$]"`/\5K#%!`%^+QE[)PU:+\8L& -M5XL]/#%!`(7`=`-0_]>+=@2%]G0#5O_7H2A/0@"+"%#_40A?7L.Y?%Y!`.ED -M"___N8A>00#HV7+__VB$*4$`Z+2*__]9P[DXTT$`Z#8$__]HCBE!`.B>BO__ -M6<.Y^$Q"`.D4R___N8A>00#IL'+__[DXTT$`Z38#__\````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`$!*`0"F20$`ODD!`"Q*`0`:2@$`"$H!`/I)`0#F20$`TDD!`(Y)`0`````` -MU#\!`!$``(``````;$D!`$!)`0!820$``````!9)`0#R2`$`V$@!`,A(`0"Z -M2`$``$D!`"9)`0"N2`$``````%A!`0!F00$`=$$!`(A!`0"<00$`J$$!`+A! -M`0#*00$`VD$!`.Q!`0#\00$`$D(!`"!"`0`P0@$`1$(!`%A"`0!N0@$`?D(! -M`))"`0">0@$`L$(!`+Q"`0#*0@$`W$(!`.I"`0#\0@$`0D$!`"A#`0`Z0P$` -M3$,!`&1#`0!^0P$`FD,!`+!#`0"X0P$`R$,!`-9#`0#H0P$`^D,!``I$`0`@ -M1`$`-$0!`$Y$`0!@1`$`>D0!`))$`0"B1`$`N$0!`,I$`0#<1`$`Z$0!``!% -M`0`010$`+$$!`!9!`0``00$`]$`!`.1``0#80`$`&$`!`,I``0"\0`$`KD`! -M`)Y``0",0`$`@$`!`')``0!>0`$`4$`!`$!``0`P0`$`$$,!```````(``"` -M`````/!*`0#>2@$`RDH!`+A*`0":2@$`C$H!`'9*`0!>2@$``````/H_`0`` -M````3D0![`&8`;P!N`'0`+0!F`&$`;0!I`&P`>0`Z`"(`00!R`&D`80!L -M`"(`.P!F`&\`;@!T`"T`0!L`&4`/@``````/`!S`'0`>0!L`&4`/@```#P` -M+P!P`#X``````%,`:`!E`&P`;``N`$4`>`!P`&P`;P!R`&4`<@``````4@!A -M`'(`2`!T`&T`;`!#`&P`80!S`',`3@!A`&T`90``````*C\``%]?````````!E``````!)`&X``!T``````!4`&D`=`!L -M`&4```!0`&$`=`!H``````!3`&D`;`!E`&X`=```````3P!V`&4`<@!W`'(` -M:0!T`&4```!3`&4`=`!U`'````!4`&4`;0!P`$T`;P!D`&4``````$P`:0!C -M`&4`;@!S`&4```!0`'(`90!S`&4`=`!U`'```````%,`:`!O`'(`=`!C`'4` -M=```````4P!A`'8`90!0`&$`=`!H``````!5`'``9`!A`'0`90``````3`!) -M`$,`10!.`%,`10!$`$P`1P``````(````"(`)0!S`"(`"@`E`',```!R`'4` -M;@!A`',```!W`&D`;@!R`&$`<@!S`&8`>`!M`&$`<`!P`&D`;@!G`&8`:0!L -M`&4`+@!T`&T`<```````+0!E`&P`(``M`',`,@`@`"(`+0!D`"4``!?`&$`8P!C`&4``!N`&$`;0!E````5<`````:P!E`'(`;@!E`&P`,P`R```` -M```9#@D'!04$!`0#`P,"`@("W3P_'[]9\TBA9+Q:,F918$4`1`!)`%0````` -M`'(`:0!C`&@`90!D`#(`,``N`&0`;`!L``````!R`&D`8P!H`&4`9``S`#(` -M+@!D`&P`;```````^10"``````#`````````1H`CU7\'3AL0KBT(`"LNQQ,8 -M`0```````,````````!&$@$```````#`````````1A8!````````P``````` -M`$83`0```````,````````!&&0$```````#`````````1@``````````P``` -M`````$8`!`(``````,````````!&818,TZ_-T!&*/@#`3\GB;@L!```````` -MP````````$8!%`(``````,````````!&0#T!````````````[#\!`"PP`0#0 -M/@$````````````,0`$`O#$!`(`]`0```````````!Y%`0!L,`$`V#X!```` -M````````HD@!`,0Q`0!$L!`)`Q`0`` -M`````````````````````````$!*`0"F20$`ODD!`"Q*`0`:2@$`"$H!`/I) -M`0#F20$`TDD!`(Y)`0``````U#\!`!$``(``````;$D!`$!)`0!820$````` -M`!9)`0#R2`$`V$@!`,A(`0"Z2`$``$D!`"9)`0"N2`$``````%A!`0!F00$` -M=$$!`(A!`0"<00$`J$$!`+A!`0#*00$`VD$!`.Q!`0#\00$`$D(!`"!"`0`P -M0@$`1$(!`%A"`0!N0@$`?D(!`))"`0">0@$`L$(!`+Q"`0#*0@$`W$(!`.I" -M`0#\0@$`0D$!`"A#`0`Z0P$`3$,!`&1#`0!^0P$`FD,!`+!#`0"X0P$`R$,! -M`-9#`0#H0P$`^D,!``I$`0`@1`$`-$0!`$Y$`0!@1`$`>D0!`))$`0"B1`$` -MN$0!`,I$`0#<1`$`Z$0!``!%`0`010$`+$$!`!9!`0``00$`]$`!`.1``0#8 -M0`$`&$`!`,I``0"\0`$`KD`!`)Y``0",0`$`@$`!`')``0!>0`$`4$`!`$!` -M`0`P0`$`$$,!```````(``"``````/!*`0#>2@$`RDH!`+A*`0":2@$`C$H! -M`'9*`0!>2@$``````/H_`0``````3DP!);FET0V]M;6]N0V]N=')O;'-%>```0T]-0U1,,S(N9&QL``"D`%-( -M075T;T-O;7!L971E``!32$Q705!)+F1L;`"_`4=E=$-U7!E`(@`0W)E871E1FEL94$`CP!#!%-E=$9I;&5!='1R -M:6)U=&5S00``8013971&:6QE071T4$``($`0W)E871E1&ER -M96-T;W)Y5P``+@%&:6YD0VQO'1&:6QE5P`Y`49I;F1&:7)S=$9I;&57``"3 -M`D=E=%1I8VM#;W5N=```$057:61E0VAA71E`+,"1VQO8F%L -M06QL;V,`I`)'971697)S:6]N17A7`/@!1V5T1G5L;%!A=&A.86UE00``^P%' -M971&=6QL4&%T:$YA;657```4`D=E=$UO9'5L949I;&5.86UE5P``3@%&:6YD -M4F5S;W5R8V57`!@"1V5T36]D=6QE2&%N9&QE5P``RP)(96%P06QL;V,`2@)' -M9710%<`U@15;FUA -M<%9I97=/9D9I;&4`AP%'971#;VUM86YD3&EN95<`5P--87!6:65W3V9&:6QE -M`(P`0W)E871E1FEL94UA<'!I;F=7``!Y`T]P96Y&:6QE36%P<&EN9U<``%<$ -M4V5T16YV:7)O;FUE;G1687)I86)L95<`10)'97105<``#\#3&]A9$QI8G)A5)E -M8W0``!0!1V5T0VQI96YT4F5C=`"F`$1E'17```1`U5P9&%T95=I;F1O -M=P``;@!#%<`"0)-87!7:6YD;W=0;VEN=',`9`%'9710 -M87)E;G0`G`%'9717:6YD;W=296-T`#P`0VAA7-T96U-971R:6-S``"C`4=E=%=I;F1O=U1E>'17``#&`E-E -M=%=I;F1O=U!OP%' -M9713>7-#;VQO<@`V`E!O4$``*H"4V5T1FEL95-E8W5R:71Y5P``,`)296=#;&]S -M94ME>0!^`E)E9U-E=%9A;'5E17A7```Y`E)E9T-R96%T94ME>45X5P!N`E)E -M9U%U97)Y5F%L=65%>%<``&$"4F5G3W!E;DME>45X5P!!1%9!4$DS,BYD;&P` -M`-<`4TA'9710871H1G)O;4E$3&ES=%<``'L`4TA"%<`?P!32$-H86YG94YO=&EF>0``4TA%3$PS,BYD;&P`$`!# -M;T-R96%T94ENF4`;VQE,S(N9&QL`$],14%55#,R+F1L;``````````````````````-'>%- -M`````+A+`0`!``````````````````````````````!724Y205(N4T98``!2 -M4T13Y=F'&1/$=TB(PEFYXP9LD0$```!D.EQ0')A````#^):3<#````'0```'T'!@X&```` -ME0```,A=+!P$````V`````'GA;P%````*````&#%N48'````!`0&!@``!P<$ -M!```!`0``$@W00````````````,```#D-D$`````````````.4$`$#E!`!PY -M00`H.4$`-#E!`$0Y00!8.4$`9#E!`'@Y00"(.4$`G#E!`+`Y00#$.4$`'P`` -M`!P````?````'@```!\````>````'P```!\````>````'P```!X````?```` -M`@(#!`4&!@8`!`@0($"`P````````````0$!`0("`@(#`P,#!`0$!`4%!04` -M`0(#!`4&!P@*#`X0%!@<("@P.$!08'"`H,#@``````0````"`````@````(` -M```"`````@````(````"`````@````(````"`````@````(````"`````@`` -M``(````.``````````P````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M````1"E!`$XI00!D*4$`>BE!```````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````````8``@```$```(`# -M````6```@`4```"(``"`!@```,@``(`.``````$`@!@````8`0"````````` -M```````````!`&4````P`0"````````````````````$``$```!(`0"``@`` -M`&`!`(`#````>`$`@`0```"0`0"`````````````````!@```'0$`("H`0"` -M1`0`@,`!`(!>!`"`V`$`@#`$`(#P`0"`$@0`@`@"`(``!`"`(`(`@``````` -M````````````!0`'````.`(`@`@```!0`@"`"0```&@"`(`*````@`(`@`L` -M``"8`@"````````````````````!`&0```"P`@"````````````````````! -M``$```#(`@"````````````````````!``D$``#@`@`````````````````` -M```!``D$``#P`@`````````````````````!``D$`````P`````````````` -M```````!``D$```0`P`````````````````````!``D$```@`P`````````` -M```````````!``D$```P`P`````````````````````!``D$``!``P`````` -M```````````````!``D$``!0`P`````````````````````!``D$``!@`P`` -M```````````````````!``D$``!P`P`````````````````````!``D$``"` -M`P`````````````````````!``D$``"0`P`````````````````````!``D$ -M``"@`P`````````````````````!``D$``"P`P`````````````````````! -M``D$``#``P`````````````````````!``D$``#0`P`````````````````` -M```!``D$``#@`P`````````````````````!``D$``#P`P``\'8"`+8+```` -M`````````)!D`@`H`0````````````"X90(`:`4`````````````(&L"`.@" -M``````````````AN`@"H"`````````````"8BP(`A@(`````````````:(D" -M`#H!`````````````*B*`@#L```````````````XB`(`+@$````````````` -M`(4"`#@#`````````````*B"`@!2`@````````````#8DP(`+`(````````` -M````")8"`,X#`````````````-B9`@`2`@````````````#PFP(`"`,````` -M````````^)X"`'P!`````````````+!V`@`^```````````````@C@(`N`4` -M````````````"`!3`%0`00!2`%0`1`!,`$<`#@!2`$4`4`!,`$$`0P!%`$8` -M20!,`$4`1`!,`$<`"0!2`$4`3@!!`$T`10!$`$P`1P`,`$<`10!4`%``00!3 -M`%,`5P!/`%(`1``Q``H`3`!)`$,`10!.`%,`10!$`$P`1P`*`$$`4P!+`$X` -M10!8`%0`5@!/`$P`````````*````!`````@`````0`$``````#````````` -M```````0`````````````````(```(````"`@`"`````@`"``("```#`P,`` -M@("`````_P``_P```/__`/\```#_`/\`__\``/___P```````$`````'`P`' -MAP```']'8@]_)B`']RNJ3_^JH']P```/_P``!P<##____P!P?\=`___\0`?W -M3V8/_\9@?W````3T```'!P,``(```'!_!Q45%140!_=;W=W=W=!_E?\`UX?_`-)]_P#0 -M>?\`RFS_`,!C]`"U6N@`X-O9`![%Q0!:`I(`4P*-````4```@(``%A%-`!(. -M/P`K*RL`(D-3`'3-]P"U8P8`_\MY`"1'6`!>N.0`I^'U`/^=)0#_KS$`4#(` -M`*=8``!W?0`EF(``)]6``"(30``>L[U`-3X_0!4ILX` -M4!D``&6[Y`"!RNT`4X,!`.'UNP"/RAX``$,5`%FKTP!ANN8`D=<(`)O?%@"2 -MW````#81`$AP````N;D`>;$/`%J*``!2G<(`K.'U`%>GS@!8B```5X<``$)G -M````3AD`.82E`%JUW@!"A*4`0$!```Q*+@`A4FL`.7N<`"%*8P`````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````0$!&`$!`0$86)C9`0$!`0$ -M!"\G6RQ<7#!=7E]<7%Q1!"\G'5)35%4P5E=865I(!!H;'`U('4E*2TP]34Y/ -M4%$3%!4O!`0$!`1&'4<$!`0$!`T$)T$L-#M"0QT^/D1%.04$)QTZ*"PT.SP] -M/CL_0`0:&QP-,ATS+#0U-C4W.#WM[<`![>WM[ -M,````````+>WM[``M[>WNW,```````![>WMP`'M[>WNW,```````M[>WL`"W -MM[>[>W,``````'M[=W``=WM[>[>W,`````"WMP`````'M[M[>W@`````>WMP -M````>WM[M[>W`````+>WMP``![>WNWM[>P````![>WMP`'M[>WNWM[<````` -MM[>WMP>WM[>[>WM[`````'M[>WM[>WM[>[>WMP````!W=W=W=W=W=[MW>WL` -M`#@X.#@X.#@X.#A[>#>W```#@X.#@X.#@X.#AX.#>P```#@X.#@X.#@X.#@X -M.#<````#@X.#@X.#@X.#@X.#````"")G)$3,`571$3@X.#```(,B:B1,3`%5 -MU5$#@X.#``@X(FHD1,P!5=45$#@X.#"#@R)J)$S,`575$5$#@X.#"#@GNRQ[ -MN`>[=3@5$#@X,`"#(F)T1,Q\`/6P``$!P`````'\`8P!C`'``<`!_`'\``$M+ -M``!.7```46```%=H``!;:0``6VP``%]M``!5<```7W```%QX``!C<0``97$` -M`&-T``!E=0``9W8``&=W``!I=@``8'\``&)_``!K>P``;7L`*V]W`)L```"A -M````_P```,)0``#/7@``_U,L`.=]+0"03T\`_W!``!"`(``5@R4`7Y```%N6 -M"P!NJ24`,:-#`$#`7P!;SG,`3]YV`&K_:@#UD30`_YLX`/^P0`#_N58``&2" -M``!I@@``:H(``&^```!L@@``;H<``'&```!WA@``>H<``'.*``!TBP``I(``'^0``Q]F0!&>H4`D`"0`)8+F`"6 -M#9@`FQ6?`)P9GP"@$*``KR"O`+!*O@"W5,8`OU_0`,=RU@``@)```("8``"` -MGP``E98``(^@``";I```H+```*>S``"ML@``J;<``*R[``"TN@``L+\``+;# -M``"[P```NL<``+W$``#"R@``R<\``,W.``#*TP``S]``'L_5``#0T```UM<` -M`-C8``#7)RGK^_O[^_O[^_G)RWIZ>O[^_O[^_O[^GIZ_O[^_O[^_OYK:VMK:VMK:VMK:VIH:FIJ;X)T<6UX>GK^_O[^86%A86%A -M86%A86%A86%A86%A86%F?FQE46UU>/[^_O[^2DI*2DI*2DI*2DI*2DI*2DI* -M2F%I95%286UU_O[^_O[^)R'@(96 -M5%,0$Q(1%QHH1D3^_OX<)0@,,S4\`"LN,D``$EQ<8%9E?6(0$Q(7%QY$_O[^ -M_OX<"`PU-X@`*RPRB``27%^(5EICA&$0$A<;'O[^_O[^_OX(AXB(AP6'B(B' -M$H>(B(=95EAC?F,2'1PE1/[^_O[^_OX(AXB(AP6'B(B'$H>(B(=95A-C;A)! -M(R-!1/[^_O[^_OX(AXB(AP6'B(B'$H>(B(=7$Q-3$B`C(R`<'/[^_O[^_OX( -MAXB(AP6'B(B'$H>(B(=6$Q,2_O[^_O[^_O[^_O[^_OX(AXB(AP6'B(B'$H>( -MB(=6$Q+^_O[^_O[^_O[^_O[^_OX(AXB(AP6'B(B'$H>(B(<3$O[^_O[^_O[^ -M_O[^_O[^_OX(A_[^AP6'_OZ'$H?^_H<3_O[^_O[^\``#__```?_P``#_\``` -M?_```#_P```?\```#_````_P```/\```#_````_P```/\```#_````\````/ -M@```#\````_@```/X```!\````.````!`````(````'````#X```!_````/X -M```!_````/X``#__```__X``/__,8S\```$`!``0$!```0`$`"@!```!`!`0 -M```!``@`:`4```(`("`0``$`!`#H`@```P`@(````0`(`*@(```$````*``` -M`%T````N`0```0`$``(```!."P``$PL``!,+`````````````````````&8` -M*&8G`&````"`````@("``,#`P`#___\`____`/___P#___\`____`/___P#_ -M__\`____`/___P!=,P``73,``%TS``!=,P``73,``%TS``!=,P``73,``%TS -M``!=,P``73,``%TS``!=,P``73,``%TS``!=,P``73,``%TS``!=,P``73,` -M`%TS``!=,P``73,``%TS``!=,P``73,``%TS``!=,P``73,``%TS``!=,P`` -M73,``%TS``!=,P``73,``%TS``!=,P``73,``%TS``!=,P``73,``%TS``!= -M,P``73,``%TS``!=,P``73,``%TS``!=,P``73,``%TS``!=,P``73,``%TS -M``!=,P``73,``%TS``!=,P``13,$1!0S``!#,P=$$S,``$`S#400,P``/S,/ -M1`\S```\,Q-$#C,``#LS%40-,P``.#,91`PS```W,QM$"S,``#0S'T0*,P`` -M,S,A1`DS```P,R5$"#,``"\S)T0',P``+#,K1`8S```K,RU$!3,``"@S,40$ -M,P``)S,91`$T&40#,P``)#,;1`(S&D0",P``(S,91`4S&T0!,P``(#,;1`8S -M'$0``!\S&40),QQ$```<,QM$"C,<1```&S,91`TS'$0``!@S&T0.,QQ$```7 -M,QE$$3,<1```%#,;1!(S'$0``!,S&405,QQ$```0,QM$%C,<1```#S,91!DS -M'$0```PS&T0:,QQ$```+,QE$'3,<1```"#,;1!XS'$0````` -M`````%<`:0!N`%(`00!2`"```!T`'(`80!C`'0`:0!N -M`&<`(`!A`'(`8P!H`&D`=@!E````"`!-`%,`(`!3`&@`90!L`&P`(`!$`&P` -M9P`@`#(````."`!0``````8`"0`]`+H`;`#__X(``````````(`"4`````!+ -M`),`"`$(`&4`__^"`"8`1`!E`',`=`!I`&X`80!T`&D`;P!N`"``9@!O`&P` -M9`!E`'(``````$(`(5``````2P"=`,0`&`!F`/__A0````````````%0```` -M`!8!G``\``X`9P#__X``0@!R`&\`)@!W`',`90`N`"X`+@````````!$"*%0 -M`````$L`"0`(`8,`:`!2`&D`8P!H`$4`9`!I`'0`,@`P`%<````````````0 -M``!``````$L`I@`*`0$`:0#__X(````````````"4`````!+`*\`Q``(`&L` -M__^"`$D`;@!S`'0`80!L`&P`80!T`&D`;P!N`"``<`!R`&\`9P!R`&4``*T``````$,`;P!N`&8`:0!R`&T`(`!F`&D`;`!E`"`` -M<@!E`'``;`!A`&,`90````@`30!3`"``4P!H`&4`;`!L`"``1`!L`&<`(``R -M````!P``4``````$``(`U@"%`/____^``````````````E``````"P`,`,<` -M"`#_____@@!4`&@`90`@`&8`;P!L`&P`;P!W`&D`;@!G`"``9@!I`&P`90`@ -M`&$`;`!R`&4`80!D`'D`(`!E`'@`:0!S`'0``&4`__^!`````````````E``````"P`Y`,<`"`#_____@@!7`&\`=0!L -M`&0`(`!Y`&\`=0`@`&P`:0!K`&4`(`!T`&\`(`!R`&4`<`!L`&$`8P!E`"`` -M=`!H`&4`(`!E`'@`:0!S`'0`:0!N`&<`(`!F`&D`;`!E```````#``!0```` -M`!L`1@`2`!0`9@#__X(````````````"4``````V`$<`G``(`&@`__^"```` -M`````````E``````-@!1`)P`"`!J`/__@@````````````)0``````L`7P#' -M``@`_____X(`=P!I`'0`:``@`'0`:`!I`',`(`!O`&X`90`_``````````,` -M`%``````&P!L`!(`%`!G`/__@@````````````)0`````#8`;0"<``@`:0#_ -M_X(````````````"4``````V`'<`G``(`&L`__^"``````````$``5`````` -M#P"-`$``#0!L`/__@``F`%D`90!S`````````````5``````3P"-`$``#0!O -M`/__@`!9`&4`0!P`'0`90!D`"``9@!I`&P` -M90`Z``````"@`(%0``````8`&@"J``P`90#__X$``````````0`!4``````D -M`#``,@`.``$`__^``$\`2P````````````%0`````&``,``R``X``@#__X`` -M0P!A`&X`8P!E`&P``````````(`"4``````&`!``J@`(`&8`__^"```````` -M``````#`",J0``````4`&P`O`%L!X```````3`!I`&,`90!N`',`90````@` -M30!3`"``4P!H`&4`;`!L`"``1`!L`&<`(``R```````."`!0``````8`"0`] -M`+H`9@#__X(`````````1`@!4`````!+``D`"`&Z`&4`__^!`````````!`` -M`%````````#)`%T!`0#_____@@`````````!``%0`````-,`SP`\``X``0#_ -M_X``00!C`&,`90!P`'0````````````!4``````6`<\`/``.``(`__^``$0` -M90!C`&P`:0!N`&4```````````#``,B0``````<`.P!+`,(`BP``````3@!E -M`'@`=``@`'8`;P!L`'4`;0!E`"``:0!S`"``<@!E`'$`=0!I`'(`90!D```` -M"`!-`%,`(`!3`&@`90!L`&P`(`!$`&P`9P`@`#(```````<``%``````!@`$ -M`+8`:P#_____@`````````````)0``````T`$`"H`!``_____X(`60!O`'4` -M(`!N`&4`90!D`"``=`!O`"``:`!A`'8`90`@`'0`:`!E`"``9@!O`&P`;`!O -M`'<`:0!N`&<`(`!V`&\`;`!U`&T`90`@`'0`;P`@`&,`;P!N`'0`:0!N`'4` -M90`@`&4`>`!T`'(`80!C`'0`:0!O`&X`.@``````@`"!4``````-`#4`J``, -M`&4`__^!`````````````5``````@P`D`#(`#@!F`/__@``F`$(`<@!O`'<` -M65S -M(C\^#0H\87-S96UB;'D@>&UL;G,](G5R;CIS8VAE;6%S+6UI8W)O0T*("!V97)S:6]N/2(Q+C`N,"XP(@T*("!P3X-"CPO=')U3X-"B`@("`\87-S96UB;'E)9&5N=&ET>0T*("`@("`@ -M='EP93TB=VEN,S(B#0H@("`@("!N86UE/2)-:6-R;W-O9G0N5VEN9&]W&UL;G,](G5R;CIS8VAE;6%S+6UI8W)O2YV,2(^#0H@(#QA<'!L:6-A=&EO;CX-"B`@("`\(2TM -M5&AE($E$(&)E;&]W(&EN9&EC871ES,U,3,X8CEA+35D.38M-&9B9"TX93)D+6$R-#0P,C(U9CDS87TB+SX-"B`@ -M/"]A<'!L:6-A=&EO;CX-"CPO8V]M<&%T:6)I;&ET>3X-"CQA`!T`'(`80!C -M`'0`:0!N`&<`(``E`',`"P!3`&L`:0!P`'``:0!N`&<`(``E`',`&0!5`&X` -M90!X`'``90!C`'0`90!D`"``90!N`&0`(`!O`&8`(`!A`'(`8P!H`&D`=@!E -M`!\`5`!H`&4`(`!F`&D`;`!E`"``(@`E`',`(@`@`&@`90!A`&0`90!R`"`` -M:0!S`"``8P!O`'(`<@!U`'``=``E`%0`:`!E`"``80!R`&,`:`!I`'8`90`@ -M`&,`;P!M`&T`90!N`'0`(`!H`&4`80!D`&4`<@`@`&D`0`4`%4`;@!K`&X`;P!W`&X`(`!M`&4`=`!H`&\`9``@ -M`&D`;@`@`"4`0!T`&4`0`@`'0`:`!E`"``:0!N`',` -M=`!A`&P`;`!A`'0`:0!O`&X`"0!!`&P`;``@`&8`:0!L`&4`0`N`#P`+P!L`&D`/@`\`&(`<@`^`#P`8@!R`#X`.``\`&P`:0`^`$D` -M9@`@`'0`:`!E`"``9`!E`',`=`!I`&X`80!T`&D`;P!N`"``9@!O`&P`9`!E -M`'(`(`!D`&\`90!S`"``;@!O`'0`(`!E`'@`:0!S`'0`+``@`&D`=``@`'<` -M:0!L`&P`(`!B`&4`,@!C`'(`90!A`'0`90!D`"``80!U`'0`;P!M`&$`=`!I -M`&,`80!L`&P`>0`@`&(`90!F`&\`<@!E`"``90!X`'0`<@!A`&,`=`!I`&\` -M;@`N`#P`+P!L`&D`/@`\`"\`=0!L`#X`````````%@!4`&@`90`@`&$`<@!C -M`&@`:0!V`&4`(`!I`',`(`!C`&\`<@!R`'4`<`!T````````````'0!%`'@` -M=`!R`&$`8P!T`&D`;@!G`"``9@!I`&P`90!S`"``=`!O`"``)0!S`"``9@!O -M`&P`9`!E`'(`)`!%`'@`=`!R`&$`8P!T`&D`;@!G`"``9@!I`&P`90!S`"`` -M=`!O`"``=`!E`&T`<`!O`'(`80!R`'D`(`!F`&\`;`!D`&4`<@`````````' -M`$4`>`!T`'(`80!C`'0`$P!%`'@`=`!R`&$`8P!T`&D`;P!N`"``<`!R`&\` -M9P!R`&4``!C`&4`90!D`"``)0!D`"``8P!H`&$`<@!A`&,`=`!E -M`'(`'3POU/A"V-A$C_CG0963R<_1[*6=&5S="!T97AT(&9I;&4- -M"J/L=""00P!'`0``N0$```(WUUQ;QV$2/QTS$``@````=&5S='-H;W)T8W5T -M+FQN:[#_XWD7N&$2/[,"!)U3*3\I8@<)V1&0R]7`VWF-"-",24*"IU"$:&01 -MK>H6"P:E!#@11Y_B$[TA"'?P3O8]S9!^#-2"+:U(+2B**@T(-*+:@H-J-K0@ -MI[.G(=TDWWG@:&A^";N;N^&[N?(],I\W,PP,_8;F_"LT/L0D6P5KT0S#,W*Q -M$8G\W`QTZG:AWY"6T=4_GNV378/<@[G?R@F!C`W.^ZM4XY#Q]B`T,Y8PX9Z7KK6-?Q=AUE.[5KHYHQM/A\\*%BRTE)K$^HL1 -M'2POU/A"W5A -M$C_#FG^F3A<_M<$T=&5S="!T97AT(&9I;&4-"OLV=."0.@````````````(` -M````=6$2/Q0P!P`0````=&5S=&1I61I6$2/P/-8AM4*3]41RS$/7L`0`<` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar_subblock.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar_subblock.rar.uu deleted file mode 100644 index 5c55ca11d..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar_subblock.rar.uu +++ /dev/null @@ -1,7 +0,0 @@ -begin 644 - -M4F%R(1H'`,^0H5JAD)Q_9XLAN3)VO("$ -M4G0@D#(`%````!0````#0J+(OK=VVCX4,`@`I($``'1E."H>."I..#JP"(:&A@,(@P7*K5,*$PI##K,.:\HN6ME^F5M^.!A..# -ME>."H>."I..#J^60C6QO;F.#B"YT>'0`D/\0?^2Y_">#,#TN'-+$/7L`0`<` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar_windows.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar_windows.rar.uu deleted file mode 100644 index 05fa8db85..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar_windows.rar.uu +++ /dev/null @@ -1,22 +0,0 @@ -begin 644 - -M4F%R(1H'`,^0'3POU/A"W5A$C_#FG]U81(_PYI_=&5S -M="!T97AT(&9I;&4-"D."=""0.P`0````$`````+Q$M:7;&$2/Q0P"``@```` -M=&5S="YT>'2POU/A"V-A$C_CG09L81(_4^$+=&5S="!T97AT(&9I;&4-"H[- -M=""00P"Y`0``N0$```(WUUQ;QV$2/Q0P$``@````=&5S='-H;W)T8W5T+FQN -M:_#_XWD7N&$2/[,"!%U,%S^RB8E,`````10"``````#`````````1IL````@ -M````8[VJ;\%=S`'3/CJ#P5W,`5/_T7G!7````$0````,```!;L.$D$`````!#.EQ$;V-U;65N=',@86YD -M(%-E='1I;F=S7&]W;F5R7$1E'0```H`+@!<`'0`90!S -M`'0`+@!T`'@`=``G`$,`.@!<`$0`;P!C`'4`;0!E`&X`=`!S`"``80!N`&0` -M(`!3`&4`=`!T`&D`;@!G`',`7`!O`'<`;@!E`'(`7`!$`&4``1GM0(`"<.&<7\'E#X,!WD3;OM++F5PEDYM-U6H;/)X!&> -MU`@`)PX9Q0````#%`73@D#H````````````"`````'5A$C\4,`<`$````'1E -MF%Z897!E<&5P97!L*&PH;"AL*',`;AYN'F -MX>;B`B("(@(B`B(<@AR"'((<@C?B-^(WXC?B4L)2PE+"4L)N(FXB;B)N(HCB -MB.*(XHCBH\*CPJ/"H\BZQK3$>Z`M3P```96P=EB)(F#:0C*.B=E8YJH8[61W -MV+Z)DM;2)*Q8Z4V[T6O1*GO&@Y3UWQHV$QNX==:0U"G4XC@H"!]-(J(@'D/? -M@(SYTVUR+"E#9NEU?4F/)3&DAC2@Z%6S^G>N30VJGI%L62FLU1@^LI27SAJ\ -MAE7)"Z[IC/VMTH6><,,*6=1B_>=>!,RS3:UOL>+6(/[321O:>SY39A-MM;Q$AVID_52A79OI7GLR$& -MSF*I)!#&@`%Q#EY!`,.RR%*'&\:EF1QI5(J]X(-6,[J'"6>D\2[%OX:S*/?P46S?=U=PV5MOW^%-?Q -M"-,Z'1F[U]*D5IJX<+]WA,(L9NKCB>[D-C3H[!`U7VI[+9C9M9:A -M3'3YOJJE-5E\Z$7102[J,RG1VXIIC',\]YQ3C.:890?))T[97M[+-*8XQY&W -MIH_F5(+RXB"?$"!HHBA%2^8,)-!3&H29["AH7VT*^HIG\Y^_U;GAW,\!)WGV -M&],S7-,TY;['3(@ZG`VXB\VVM&^?"X!RVCO\T02FIP`U;[V.JPQGC64RBRT4 -MUY0&N\%%_CDP*E%B_.L)Q%IB\M:L5+[&I0_%2T.JE&DSJ\F.HTZ_HGFV49Y: -MC`"$AQ,D=<3^/R?B54&T*A&33@,V;Q7#IJ$==HB_(T7H(#)O*9>_":$02^K" -MF*F5#21OUT-KRQ]\L0"FP^9B'>[1/3**.N@"OB````7M\#3O$=.;64K*60;( -M,]2>I1YH\R)I$TL26+"'A#Q(8D+O!W@^'?#M86L+?5OJO77KL:6-2E)2DKC5 -MQHT4:*6!+"=3.IGX3\1=8NN9D,R$7"+A.DG2+C%R#&/"^9?*X#<"-<&M[Y5\L[_=_1,(F$):$K+4EJR-I&M(FD3/ -MDGR64K*=:6M(.$Q](FI95+*I%-(>I9E++I$-(4I9U+,I"](+I:=+1I!](`I; -M-+6I`E'RI;]+;H^U'CI==+FH]%'1I?=+TH[%&WIAU,$HX%&8IEE,?HTE%NIK -MU-)HO]$GIU=.(HHE"HJ(-/[H<4]LJX=3^H!L:'H>H[!FC6*`3@CA)3!E[+&6LWYN# -M1&I/L>\[9XD4HC0@A=+*4T@I(4.H%."=E9*L4XJ);BUECK,8*O]>"]F6LH8R -MQYJK4&@M&;ZWAM+;G2N@J)4JUMI[%61P#?J[-X,QY/7S^ -M!!A0XD6-'D294N9-G3Z%&E3J5:U>Q9M6[EV]?P8<6/)ES9]&G5KV;=V_AQY< -M^G7MW`%/B`"Y@?X"'Q```0!\T``'S@$_P``3_0(0T``R`!`,@&0````$#__X -M'_^!__@?@?_X'_^!^!__@?_X'X'_^!__@?@?_X'_^!^!__@?_X'X'_^!__@? -M@?_X'_^!^!__@?_X'X'_^!__@?@``"!__@?_^```@#YH``9`!R@\C(R&ZKFQ -ML]VG'6NK;7Y'YR_*2;6$.#`H3IT%@:D4DL9DAIUJ.-A"5-S[1?*=.G\Y*:'1 -M1KZ6E`1&3E36NH7)B!2(Z,%9;J:8I;R%A;D%KE3`J3R4O.]L0J^):=TM0O*. -M\2.HMA=FQ.2(#*``+0#__RQ`^FC6'9C\M-VY1W%.XY7!&\H5`"+,W&V_=W\^ -M_77O*T?R-^O4X)'`Z3U.Z1X5.M50:RX+XQ#';7;^I6W+O"/4^>9R1RG!Z1^: -M:>8FK#]*MUP\U+YH#IT%O_MOI9`M^L8R)"\'@`\Q$O@``4=AV`+M`SU9^H'X -M9ZFNQQ-0CUX*.""6+X'2R]-H;+96%JR-5HW)NY[/(B9T/2$Z,30K8-_0/9C+ -M-7:)?(99;O+XYLW$/Y(?+U8G^=LTGNZ:2Z'"G8R['JXC>ZW8VK#*5P[&]Y!7 -M(4XT+*1XM?)29BO)=9)?%%8T1___PX77'!5!9,V\L_>>[=7X1I8K?."<=)*) -MMQ(IE -M3*?-I+]6DJZ___G?+6HC]^T+#5G,/$>(M"IY_F>+.3THA1TWV#8R2@W:,SB% -M;4+BDGXR0^$/44-L-'" -M),O9S0>/PWNA#L#-&!*T9TSX?AZEJ&$LLL@]$`#L,&2TZA;RY*]+\74Q1=#P -ME9*X;4Y9E##F*M+0M5N0U#)+.2>*)+#6#3IAVY5R<69:&V"?__ -M]XEC]%^&4693BM$.(L;Y'RKS/)&2$@A$K(7BL)4:TA=:_V'/=C@T9I[K7UP? -M>S`:!,T9`N`;I41,6P[ -MJG&?KE50XF!\1TYPJE_`5R<0X#12A0_M]+_HOO(>:]EYCGFVN0=:U]ES/FDP -M4?@WZ+:X5(JC6VN%)2A&IG\->?E(Q'R.%.+<"\``@Q2/__^`RJ5L!E6DGZ?Z -M@J6*'B7N.GG>N`X):Y*6+>5DU'8EN%A,]=6C7U>%38)2D),4T4Z+@U4]2HB" -MI0`=!:($>Q@'\(1+`8$Q.`0!`7!4`!T%4(`N((JRA(0MD&/4=$I.X[3K1A+4 -M82-/$Y3=)%L5-2U;6A9UD7-H&07U@E365H$TBJ$G\B*0)9C-_:NI^@Z6R&YK -M6P/=-.QC3'___7922)<0Y5,>Q2VKBW36LFTSS.VZSGO.^+T/I`KYOX_<)1G` -MT+QG#T+P-'#QR7+D7O^^\7R6F#1QY*D)R8]L)M\>,%$Z>B]$$7Z,(\1*>+JN -MJ.+`V"_,"X\60HGD=Q'`[R0?$D8Q4^S_PW`CJ/2_+S.*WSNNFR#1N4S*YK

    KVVW5BL'"S3RI&ZR$\M4* -MK5<+$V&@H80`)A,%0F?C4/BJ@TJBT&G5HSD(MV>MU6GUHM%4DU0JE,L6(N%8 -MRF2+:D3:CV7C+:$#@+#4#EC;)0*`1B+,!&*Q_'Q,*A4%@M%0C%0G%HV -M%XQ&`Q$@I&`J$8F%HP$@D%@^(`V%(\(@X%1#)))(!')H^)Q8(8_&9'?__^OD -MT:L1&`T*B4ZF25ZK^1PJ,1N0-%`MJ&-U<-A[K@GM1Y.!7)=@L)!E4EL,L&UC -MK@LF$\`4$!88`05#@`#\9"DF#<2B\D%46!$:&0Z'0WG=:IDUL`WIA3JIA*E; -MK]C,=,-)F,QH-1Q.!F-MW.-O)!2M%!/1_/N!.2!O9I0>1Q!^QB2R2.PZ,1>% -M/___UB$XV>8$F+"4I'EB-+R$A(2)%E%8@*SPP'C^7(@P%)T,E&4^)A@QA3P8 -M*.C%&E7*!7V988%Y94SQ-8E,I*28F*P89+09/)!4H`!P*%0@2-0T -M3#@H9$!08'0X/$X=S.8\K&!D<2BM7,#Z-,L4HU"E.@1IU`8:5`(3YQ$-/FPYP -MZ;,)41Y.R4(U;___X8@5#U%6!PL`"0DF1@D/$0\+)FP[#B`]*!,I@Q\+#`>GIKO8,'6D`%BS)LV;O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ -MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ -?O?OW\./+GT^_OOW[^//KW\^_O___``8HX(`$%FC@4``` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_tar_empty_with_gnulabel.c b/thirdparty/libarchive/libarchive/test/test_read_format_tar_empty_with_gnulabel.c deleted file mode 100644 index 83f20bb97..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_tar_empty_with_gnulabel.c +++ /dev/null @@ -1,53 +0,0 @@ -/*- - * Copyright (c) 2019 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* - * Tar archives with with just a GNU label (or ending with one) should - * be treated as valid (empty) archives - */ -DEFINE_TEST(test_read_format_tar_empty_with_gnulabel) -{ - char name[] = "test_read_format_tar_empty_with_gnulabel.tar"; - struct archive_entry *ae; - struct archive *a; - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - extract_reference_file(name); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240)); - - /* Read first entry. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify that the format detection worked. */ - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_NONE); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_tar_empty_with_gnulabel.tar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_tar_empty_with_gnulabel.tar.uu deleted file mode 100644 index c5aa393db..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_tar_empty_with_gnulabel.tar.uu +++ /dev/null @@ -1,231 +0,0 @@ -begin 664 test_read_format_tar_empty_with_gnulabel.tar -M;&%B96P````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`#$S-#8W-S,V,C`S`#`P,C8R,``@5@`````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -9```````````````````````````````````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_tar_filename.c b/thirdparty/libarchive/libarchive/test/test_read_format_tar_filename.c deleted file mode 100644 index 9ee8e813f..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_tar_filename.c +++ /dev/null @@ -1,394 +0,0 @@ -/*- - * Copyright (c) 2011 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD"); - -#include - -/* - * The sample tar file was made in LANG=KOI8-R and it contains two - * files the charset of which are different. - * - the filename of first file is stored in BINARY mode. - * - the filename of second file is stored in UTF-8. - * - * Whenever hdrcharset option is specified, we will correctly read the - * filename of second file, which is stored in UTF-8 by default. - */ - -static void -test_read_format_tar_filename_KOI8R_CP866(const char *refname) -{ - struct archive *a; - struct archive_entry *ae; - - /* - * Read filename in ru_RU.CP866 with "hdrcharset=KOI8-R" option. - * We should correctly read two filenames. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia.866") && - NULL == setlocale(LC_ALL, "ru_RU.CP866")) { - skipping("ru_RU.CP866 locale not available on this system."); - return; - } - - /* Test if the platform can convert from UTF-8. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_tar(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=UTF-8")) { - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - skipping("This system cannot convert character-set" - " from UTF-8 to CP866."); - return; - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) { - skipping("This system cannot convert character-set" - " from KOI8-R to CP866."); - goto next_test; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular first file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\x8f\x90\x88\x82\x85\x92", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Verify regular second file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xaf\xe0\xa8\xa2\xa5\xe2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE, - archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -next_test: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - - /* - * Read filename in ru_RU.CP866 without "hdrcharset=KOI8-R" option. - * The filename we can properly read is only second file. - */ - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* - * Verify regular first file. - * The filename is not translated to CP866 because hdrcharset - * attribute is BINARY and there is not way to know its charset. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - /* A filename is in KOI8-R. */ - assertEqualString("\xf0\xf2\xe9\xf7\xe5\xf4", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* - * Verify regular second file. - * The filename is translated from UTF-8 to CP866 - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xaf\xe0\xa8\xa2\xa5\xe2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE, - archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -static void -test_read_format_tar_filename_KOI8R_UTF8(const char *refname) -{ - struct archive *a; - struct archive_entry *ae; - - /* - * Read filename in en_US.UTF-8 with "hdrcharset=KOI8-R" option. - * We should correctly read two filenames. - */ - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("en_US.UTF-8 locale not available on this system."); - return; - } - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) { - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - skipping("This system cannot convert character-set" - " from KOI8-R to UTF-8."); - return; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Verify encryption status */ - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE, - archive_format(a)); - - /* Verify encryption status */ - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Read filename in en_US.UTF-8 without "hdrcharset=KOI8-R" option. - * The filename we can properly read is only second file. - */ - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* - * Verify regular first file. - * The filename is not translated to UTF-8 because hdrcharset - * attribute is BINARY and there is not way to know its charset. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - /* A filename is in KOI8-R. */ - assertEqualString("\xf0\xf2\xe9\xf7\xe5\xf4", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - /* Verify encryption status */ - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* - * Verify regular second file. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE, - archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -static void -test_read_format_tar_filename_KOI8R_CP1251(const char *refname) -{ - struct archive *a; - struct archive_entry *ae; - - /* - * Read filename in CP1251 with "hdrcharset=KOI8-R" option. - * We should correctly read two filenames. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia") && - NULL == setlocale(LC_ALL, "ru_RU.CP1251")) { - skipping("CP1251 locale not available on this system."); - return; - } - - /* Test if the platform can convert from UTF-8. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_tar(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=UTF-8")) { - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - skipping("This system cannot convert character-set" - " from UTF-8 to CP1251."); - return; - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) { - skipping("This system cannot convert character-set" - " from KOI8-R to CP1251."); - goto next_test; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular first file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Verify regular second file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE, - archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -next_test: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Read filename in CP1251 without "hdrcharset=KOI8-R" option. - * The filename we can properly read is only second file. - */ - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* - * Verify regular first file. - * The filename is not translated to CP1251 because hdrcharset - * attribute is BINARY and there is not way to know its charset. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - /* A filename is in KOI8-R. */ - assertEqualString("\xf0\xf2\xe9\xf7\xe5\xf4", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* - * Verify regular second file. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE, - archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - -DEFINE_TEST(test_read_format_tar_filename) -{ - const char *refname = "test_read_format_tar_filename_koi8r.tar.Z"; - - extract_reference_file(refname); - test_read_format_tar_filename_KOI8R_CP866(refname); - test_read_format_tar_filename_KOI8R_UTF8(refname); - test_read_format_tar_filename_KOI8R_CP1251(refname); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_tar_filename_koi8r.tar.Z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_tar_filename_koi8r.tar.Z.uu deleted file mode 100644 index 80b4568a4..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_tar_filename_koi8r.tar.Z.uu +++ /dev/null @@ -1,14 +0,0 @@ -begin 644 test_read_format_tar_filename_koi8r.tar.Z -M'YV04,+@05(F#)DR3.FQ9O7%@,[A`B[]L:6($5"-5D#Y>Z57;=ZM"&3 -M9N^?.'7RG/'81E`8MJ,77=KTJ<>KI;&3%L[2J_3OX%/+?AB^O/GSZ-.K7\\^ -M?,"!!0\FA"8MV;5BU-IO_QB2)6_?*O76G7`@%5?33SV)Q%-E-]`0U%#ZV4:= -M4U!I5Y:%9'$7'%<1=GC>67OU]1;AD$06:>212&)$GWWX)5D6;OW])J"4``K7$G$S'6A9 -M#3[MU!E-SSF)VH361355=F?NYYV&8K9)VGBTN2GGG'36:>>=>.:IYYY\]NGG -(GX`&*NB@%P$` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_tar_invalid_pax_size.c b/thirdparty/libarchive/libarchive/test/test_read_format_tar_invalid_pax_size.c deleted file mode 100644 index 0a03cb677..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_tar_invalid_pax_size.c +++ /dev/null @@ -1,53 +0,0 @@ -/*- - * Copyright (c) 2020 Ben Wagner - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* - * The pax size attribute can be used to override the size. - * It should be validated the same way the normal size is validated. - * The test data is fuzzer output from - * https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=48467 . - */ -DEFINE_TEST(test_read_format_tar_invalid_pax_size) -{ - /* - * An archive that contains a PAX 'size' record with a large negative value. - */ - struct archive_entry *ae; - struct archive *a; - const char *refname = "test_read_format_tar_invalid_pax_size.tar"; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualInt(ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualInt(ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); - /* This assert will pass a normal debug build without the pax size check. */ - /* Run this test with `-fsanitize=undefined` to verify. */ - assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_tar_invalid_pax_size.tar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_tar_invalid_pax_size.tar.uu deleted file mode 100644 index 71309eab2..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_tar_invalid_pax_size.tar.uu +++ /dev/null @@ -1,38 +0,0 @@ -begin 644 test_read_format_tar_invalid_pax_size.tar.uu -M+B]087A(96%D97)S+C$T-#8S+V%A80`````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````#`P,#`V-#0`,#`P,#`P,``P,#`P,#`P`#`P,#`P,#`P,S$R -M`#$R-3,Q,30U,S``````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````!U='-A<@`P,``````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````S,"`@("`@(#T@("`@("`@("`@("`@("`@("`@ -M(`HS,"`@("`@(#T@("`@("`@("`@("`@("`@("`@(`HS,"`@("`@("`]("`@ -M("`@("`@("`@("`@("`@(`HS,"!S:7IE/2TQ.3',205,'f',29,170,227,'[',179,139, -'\'','L','o',211,':',178,'0',162,134,'*','>','8',24,153,230,147,'R','?',23, -'r','E','8','P',144,237,7,140,'W'}; - -DEFINE_TEST(test_read_format_tbz) -{ - struct archive_entry *ae; - struct archive *a; - int r; - - assert((a = archive_read_new()) != NULL); - r = archive_read_support_filter_bzip2(a); - if (r != ARCHIVE_OK) { - skipping("Bzip2 support"); - archive_read_free(a); - return; - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, archive, sizeof(archive))); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_file_count(a)); - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_BZIP2); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_tgz.c b/thirdparty/libarchive/libarchive/test/test_read_format_tgz.c deleted file mode 100644 index 9fba89657..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_tgz.c +++ /dev/null @@ -1,63 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_tgz.c 191183 2009-04-17 01:06:31Z kientzle $"); - -static unsigned char archive[] = { -31,139,8,0,222,'C','p','C',0,3,211,'c',160,'=','0','0','0','0','7','5','U', -0,210,134,230,166,6,200,'4',28,'(',24,26,24,27,155,24,152,24,154,27,155,')', -24,24,26,152,154,25,'2','(',152,210,193,'m',12,165,197,'%',137,'E','@',167, -148,'d',230,226,'U','G','H',30,234,15,'8','=',10,'F',193,'(',24,5,131,28, -0,0,29,172,5,240,0,6,0,0}; - -DEFINE_TEST(test_read_format_tgz) -{ - struct archive_entry *ae; - struct archive *a; - int r; - - assert((a = archive_read_new()) != NULL); - assertEqualInt(ARCHIVE_OK, archive_read_support_filter_all(a)); - r = archive_read_support_filter_gzip(a); - if (r == ARCHIVE_WARN) { - skipping("gzip reading not fully supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - assertEqualInt(ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualInt(ARCHIVE_OK, - archive_read_open_memory(a, archive, sizeof(archive))); - assertEqualInt(ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_file_count(a)); - assertEqualInt(archive_filter_code(a, 0), - ARCHIVE_FILTER_GZIP); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK,archive_read_free(a)); -} - - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_tlz.c b/thirdparty/libarchive/libarchive/test/test_read_format_tlz.c deleted file mode 100644 index 7c7a14319..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_tlz.c +++ /dev/null @@ -1,63 +0,0 @@ -/*- - * Copyright (c) 2009 Michihiro NAKAJIMA - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_tlz.c 201247 2009-12-30 05:59:21Z kientzle $"); - -static unsigned char archive[] = { - 93, 0, 0,128, 0,255,255,255,255,255,255,255,255, 0, 23, 0, - 51, 80, 24,164,204,238, 45, 77, 28,191, 13,144, 8, 10, 70, 5, -173,215, 47,132,237,145,162, 96, 6,131,168,152, 8,135,161,189, - 73,110,132, 27,195, 52,109,203, 22, 17,168,211, 18,181, 76, 93, -120, 88,154,155,244,141,193,206,170,224, 80,137,134, 67, 1, 9, -123,121,189, 74,137,197, 63,255,214, 55,119, 0 -}; - -DEFINE_TEST(test_read_format_tlz) -{ - struct archive_entry *ae; - struct archive *a; - int r; - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - r = archive_read_support_filter_lzma(a); - if (r == ARCHIVE_WARN) { - skipping("lzma reading not fully supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, archive, sizeof(archive))); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_file_count(a)); - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_LZMA); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_txz.c b/thirdparty/libarchive/libarchive/test/test_read_format_txz.c deleted file mode 100644 index c082d7e5e..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_txz.c +++ /dev/null @@ -1,66 +0,0 @@ -/*- - * Copyright (c) 2009 Michihiro NAKAJIMA - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_txz.c 191183 2009-04-17 01:06:31Z kientzle $"); - -static unsigned char archive[] = { -253, 55,122, 88, 90, 0, 0, 4,230,214,180, 70, 2, 0, 33, 1, - 22, 0, 0, 0,116, 47,229,163,224, 5,255, 0, 73, 93, 0, 23, - 0, 51, 80, 24,164,204,238, 45, 77, 28,191, 13,144, 8, 10, 70, - 5,173,215, 47,132,237,145,162, 96, 6,131,168,152, 8,135,161, -189, 73,110,132, 27,195, 52,109,203, 22, 17,168,211, 18,181, 76, - 93,120, 88,154,155,244,141,193,206,170,224, 80,137,134, 67, 1, - 9,123,121,188,247, 28,139, 0, 0, 0, 0, 0,112,184, 17, 5, -103, 16, 8, 73, 0, 1,101,128, 12, 0, 0, 0, 30, 69, 92, 96, -177,196,103,251, 2, 0, 0, 0, 0, 4, 89, 90 -}; - -DEFINE_TEST(test_read_format_txz) -{ - struct archive_entry *ae; - struct archive *a; - int r; - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - r = archive_read_support_filter_xz(a); - if (r == ARCHIVE_WARN) { - skipping("xz reading not fully supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, archive, sizeof(archive))); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_file_count(a)); - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_XZ); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_tz.c b/thirdparty/libarchive/libarchive/test/test_read_format_tz.c deleted file mode 100644 index 4ba7bcb3f..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_tz.c +++ /dev/null @@ -1,60 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_tz.c 189381 2009-03-05 00:31:48Z kientzle $"); - -static unsigned char archive[] = { -31,157,144,'.',0,8,28,'H',176,160,193,131,8,19,'*','\\',200,176,'!','B',24, -16,'o',212,168,1,2,0,196,24,18,'a','T',188,152,'q','#',196,143,' ','5',198, -128,'1','c',6,13,24,'4','0',206,176,1,2,198,200,26,'6','b',0,0,'Q',195,161, -205,155,'8','s',234,4,'P','g',14,157,'0','r',',',194,160,147,166,205,206, -132,'D',141,30,'=',24,'R',163,'P',144,21,151,'J',157,'J',181,170,213,171, -'X',179,'j',221,202,181,171,215,175,'`',195,138,29,'K',182,172,217,179,'h', -211,170,']',203,182,173,219,183,'g',1}; - -DEFINE_TEST(test_read_format_tz) -{ - struct archive_entry *ae; - struct archive *a; - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, archive, sizeof(archive))); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_file_count(a)); - failure("archive_filter_name(a, 0)=\"%s\"", - archive_filter_name(a, 0)); - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_COMPRESS); - failure("archive_format_name(a)=\"%s\"", archive_format_name(a)); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_ustar_filename.c b/thirdparty/libarchive/libarchive/test/test_read_format_ustar_filename.c deleted file mode 100644 index 5c2717cdf..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_ustar_filename.c +++ /dev/null @@ -1,547 +0,0 @@ -/*- - * Copyright (c) 2011 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD"); - -#include - -static void -test_read_format_ustar_filename_eucJP_UTF8(const char *refname) -{ - struct archive *a; - struct archive_entry *ae; - - /* - * Read eucJP filename in en_US.UTF-8 with "hdrcharset=eucJP" option. - */ - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("en_US.UTF-8 locale not available on this system."); - return; - } - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=eucJP")) { - skipping("This system cannot convert character-set" - " from eucJP to UTF-8."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xe6\xbc\xa2\xe5\xad\x97.txt", - archive_entry_pathname(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xe8\xa1\xa8.txt", archive_entry_pathname(ae)); - assertEqualInt(4, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -static void -test_read_format_ustar_filename_CP866_KOI8R(const char *refname) -{ - struct archive *a; - struct archive_entry *ae; - - /* - * Read CP866 filename in ru_RU.KOI8-R with "hdrcharset=CP866" option. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia.20866") && - NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) { - skipping("ru_RU.KOI8-R locale not available on this system."); - return; - } - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) { - skipping("This system cannot convert character-set" - " from CP866 to KOI8-R."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xf0\xf2\xe9\xf7\xe5\xf4", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\xd2\xc9\xd7\xc5\xd4", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -static void -test_read_format_ustar_filename_CP866_UTF8(const char *refname) -{ - struct archive *a; - struct archive_entry *ae; - - /* - * Read CP866 filename in en_US.UTF-8 with "hdrcharset=CP866" option. - */ - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("en_US.UTF-8 locale not available on this system."); - return; - } - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) { - skipping("This system cannot convert character-set" - " from CP866 to UTF-8."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -static void -test_read_format_ustar_filename_KOI8R_CP866(const char *refname) -{ - struct archive *a; - struct archive_entry *ae; - - /* - * Read KOI8-R filename in ru_RU.CP866 with "hdrcharset=KOI8-R" option. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia.866") && - NULL == setlocale(LC_ALL, "ru_RU.CP866")) { - skipping("ru_RU.CP866 locale not available on this system."); - return; - } - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) { - skipping("This system cannot convert character-set" - " from KOI8-R to CP866."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xaf\xe0\xa8\xa2\xa5\xe2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\x8f\x90\x88\x82\x85\x92", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -static void -test_read_format_ustar_filename_KOI8R_UTF8(const char *refname) -{ - struct archive *a; - struct archive_entry *ae; - - /* - * Read KOI8-R filename in en_US.UTF-8 with "hdrcharset=KOI8-R" option. - */ - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("en_US.UTF-8 locale not available on this system."); - return; - } - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) { - skipping("This system cannot convert character-set" - " from KOI8-R to UTF-8."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -static void -test_read_format_ustar_filename_eucJP_CP932(const char *refname) -{ - struct archive *a; - struct archive_entry *ae; - - /* - * Read eucJP filename in CP932/SJIS with "hdrcharset=eucJP" option. - */ - if (NULL == setlocale(LC_ALL, "Japanese_Japan") && - NULL == setlocale(LC_ALL, "ja_JP.SJIS")) { - skipping("CP932 locale not available on this system."); - return; - } - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=eucJP")) { - skipping("This system cannot convert character-set" - " from eucJP."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\x8a\xbf\x8e\x9a.txt", archive_entry_pathname(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\x95\x5c.txt", archive_entry_pathname(ae)); - assertEqualInt(4, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -static void -test_read_format_ustar_filename_CP866_CP1251(const char *refname) -{ - struct archive *a; - struct archive_entry *ae; - - /* - * Read CP866 filename in CP1251 with "hdrcharset=CP866" option. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia") && - NULL == setlocale(LC_ALL, "ru_RU.CP1251")) { - skipping("CP1251 locale not available on this system."); - return; - } - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) { - skipping("This system cannot convert character-set" - " from CP866 to CP1251."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* - * This test only for Windows platform because other archiver - * applications on Windows translate CP1251 filenames into CP866 - * filenames and store it in the ustar file and so we should read - * it by default on Windows. - */ -static void -test_read_format_ustar_filename_CP866_CP1251_win(const char *refname) -{ - struct archive *a; - struct archive_entry *ae; - - /* - * Read CP866 filename in CP1251 without "hdrcharset=CP866" option. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia")) { - skipping("Russian_Russia locale not available on this system."); - return; - } - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -static void -test_read_format_ustar_filename_KOI8R_CP1251(const char *refname) -{ - struct archive *a; - struct archive_entry *ae; - - /* - * Read KOI8-R filename in CP1251 with "hdrcharset=KOI8-R" option. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia") && - NULL == setlocale(LC_ALL, "ru_RU.CP1251")) { - skipping("CP1251 locale not available on this system."); - return; - } - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) { - skipping("This system cannot convert character-set" - " from KOI8-R to CP1251."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - - -DEFINE_TEST(test_read_format_ustar_filename) -{ - const char *refname1 = "test_read_format_ustar_filename_eucjp.tar.Z"; - const char *refname2 = "test_read_format_ustar_filename_cp866.tar.Z"; - const char *refname3 = "test_read_format_ustar_filename_koi8r.tar.Z"; - - extract_reference_file(refname1); - test_read_format_ustar_filename_eucJP_UTF8(refname1); - test_read_format_ustar_filename_eucJP_CP932(refname1); - - extract_reference_file(refname2); - test_read_format_ustar_filename_CP866_KOI8R(refname2); - test_read_format_ustar_filename_CP866_UTF8(refname2); - test_read_format_ustar_filename_CP866_CP1251(refname2); - test_read_format_ustar_filename_CP866_CP1251_win(refname2); - - extract_reference_file(refname3); - test_read_format_ustar_filename_KOI8R_CP866(refname3); - test_read_format_ustar_filename_KOI8R_UTF8(refname3); - test_read_format_ustar_filename_KOI8R_CP1251(refname3); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_ustar_filename_cp866.tar.Z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_ustar_filename_cp866.tar.Z.uu deleted file mode 100644 index 359fc2b34..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_ustar_filename_cp866.tar.Z.uu +++ /dev/null @@ -1,8 +0,0 @@ -begin 644 test_read_format_ustar_filename_cp866.tar.Z -M'YV0CR`A$E1($H"#"!,J7,BPH<.'$"-*1`BCXHT:-4``J!CC8@R-'#V"K$BR -MI`T0,6+4H'%CA@R5,#[&?%E#!@`0,";JW,FSIT\`=>;0"2-G(XPQ=AM'4NVK-FS:-.J7!V2O)C1:,<:'_V*-!J5Y,F4*UO2C(DSA@P;CF_FS$OY8="A12LV';MY -K:^&I)*M6'DT::]>O84NK7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,K!``` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_ustar_filename_eucjp.tar.Z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_ustar_filename_eucjp.tar.Z.uu deleted file mode 100644 index c6ab11043..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_ustar_filename_eucjp.tar.Z.uu +++ /dev/null @@ -1,9 +0,0 @@ -begin 644 test_read_format_ustar_filename_eucjp.tar.Z -M'YV0M(+MTN>"#AXZ`!(J7,BPH<.'$"-*G$@1`(R+-FC0`&$11HP;-6)PO/@Q -MY,B+*%'&@`$B1HP:(6O(D"&3I4<9-V;$```"1L6?0(,*'0J@SAPZ8>1T'%.G -M#%&(3)T^=9CRXLF4'*=JWBBGXYTB0HE2!D7].J7M,L7(LJ,&SN6%"D8).&J53>ZA/ER9LV>,63`N.&S9]_+$HTB57HQ -M:EK/7Q%?19D5L^G37-FD.8JZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'T[< -!(0`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_ustar_filename_koi8r.tar.Z.uu b/thirdparty/libarchive/libarchive/test/test_read_format_ustar_filename_koi8r.tar.Z.uu deleted file mode 100644 index 15e0d6316..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_ustar_filename_koi8r.tar.Z.uu +++ /dev/null @@ -1,8 +0,0 @@ -begin 644 test_read_format_ustar_filename_koi8r.tar.Z -M'YV0T*0ENU:,&H"#"!,J7,BPH<.'$"-*1`BCXHT:-4``J!CC8@R-'#V"K$BR -MI`T0,6+4H'%CAHR*,T["B#'#(@`0,";JW,FSIT\`=>;0"2-G(XPQ=AM'4NVK-FS:-.J7O7L&/+GDV[MNW;N'/KWLV[M^^$ -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_warc.c b/thirdparty/libarchive/libarchive/test/test_read_format_warc.c deleted file mode 100644 index 658ab8a6e..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_warc.c +++ /dev/null @@ -1,82 +0,0 @@ -/*- - * Copyright (c) 2014 Sebastian Freundt - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - - -DEFINE_TEST(test_read_format_warc) -{ - char buff[256U]; - const char reffile[] = "test_read_format_warc.warc"; - struct archive_entry *ae; - struct archive *a; - - extract_reference_file(reffile); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, reffile, 10240)); - - /* First Entry */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("sometest.txt", archive_entry_pathname(ae)); - assertEqualInt(1402399833, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_uid(ae)); - assertEqualInt(0, archive_entry_gid(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(65, archive_entry_size(ae)); - assertEqualInt(65, archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, "This is a sample text file for libarchive's WARC reader/writer.\n\n", 65); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Second Entry */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("moretest.txt", archive_entry_pathname(ae)); - assertEqualInt(1402399884, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_uid(ae)); - assertEqualInt(0, archive_entry_gid(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(76, archive_entry_size(ae)); - assertA(76 == archive_read_data(a, buff, sizeof(buff))); - assertEqualMem(buff, "The beauty is that WARC remains ASCII only iff all contents are ASCII only.\n", 76); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - - /* Test EOF */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_file_count(a)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_WARC, archive_format(a)); - - /* Verify closing and resource freeing */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_warc.warc.uu b/thirdparty/libarchive/libarchive/test/test_read_format_warc.warc.uu deleted file mode 100644 index f89592b9b..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_warc.warc.uu +++ /dev/null @@ -1,23 +0,0 @@ -begin 644 test_read_format_warc.warc -M5T%20R\Q+C`-"E=!4D,M5'EP93H@=V%R8VEN9F\-"E=!4D,M1&%T93H@,C`Q -M-"TP-BTQ,%0Q,3HS,3HS.%H-"DQA7!E.B!R97-O -M=7)C90T*5T%20RU487)G970M55)).B!F:6QE.B\O2!I -D9F8@86QL(&-O;G1E;G1S(&%R92!!4T-)22!O;FQY+@H-"@T* -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_xar.c b/thirdparty/libarchive/libarchive/test/test_read_format_xar.c deleted file mode 100644 index 1c8524520..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_xar.c +++ /dev/null @@ -1,863 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2009 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -#define UID 1001 -#define UNAME "cue" -#define GID 1001 -#define GNAME "cue" - -/* Verify that a file records with hardlink. -#How to make -echo "hellohellohello" > f1 -chown $UNAME:$GNAME f1 -chmod 0644 f1 -ln f1 hardlink -chown $UNAME:$GNAME hardlink -chmod 0644 hardlink -env TZ=utc touch -afm -t 197001020000.01 f1 hardlink -xar -cf archive1.xar f1 hardlink -od -t x1 archive1.xar | sed -E -e 's/^0[0-9]+//;s/^ //;s/( )([0-9a-f]{2})/0x\2,/g;$ D' > archive1.xar.txt -*/ -static unsigned char archive1[] = { -0x78,0x61,0x72,0x21,0x00,0x1c,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xc6, -0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x70,0x00,0x00,0x00,0x01,0x78,0xda,0xc4,0x54, -0xc9,0x6e,0xdb,0x30,0x14,0xbc,0xe7,0x2b,0x08,0xdd,0x55,0xae,0xb6,0x45,0x83,0x56, -0xd0,0x4b,0xd1,0x7b,0xd3,0x4b,0x6f,0x34,0x17,0x89,0x88,0x36,0x48,0x54,0xe0,0xe4, -0xeb,0x4b,0x52,0x52,0x0c,0xa7,0x71,0x6f,0x45,0x01,0x01,0x1a,0x0e,0x87,0xa3,0xa7, -0xf7,0x06,0x14,0x8f,0x97,0xb6,0x01,0x2f,0x66,0x9c,0x5c,0xdf,0x9d,0x32,0xfc,0x05, -0x65,0xc0,0x74,0xaa,0xd7,0xae,0xab,0x4e,0xd9,0xcf,0xa7,0x6f,0x79,0x91,0x3d,0x96, -0x0f,0xe2,0x22,0xc7,0xf2,0x01,0x08,0xdf,0xab,0xf0,0x02,0x42,0x8d,0x46,0xfa,0x70, -0x22,0xf7,0xae,0x35,0x25,0x41,0x88,0xe7,0x98,0xe4,0x88,0x3c,0x61,0x7a,0xa4,0xe8, -0x48,0xb9,0x80,0xb7,0x92,0x74,0xa8,0x36,0xea,0x79,0x9a,0x5b,0x30,0xf9,0xd7,0xc6, -0x9c,0xb2,0xa9,0x96,0x38,0x8b,0x3b,0x40,0xf4,0xd6,0x4e,0xc6,0x97,0x48,0xc0,0x15, -0x25,0x76,0x72,0x6f,0xd1,0x5c,0xc0,0x04,0xa2,0x05,0xdc,0x3c,0xd2,0xca,0xba,0xc6, -0x00,0xa7,0x4f,0x19,0x59,0x6d,0xd4,0x9d,0x72,0xd8,0xaf,0x70,0x72,0xab,0x03,0x88, -0x36,0x41,0xcc,0x0f,0x28,0x47,0x38,0xca,0x10,0x3a,0xc6,0x07,0x07,0x59,0x7b,0x95, -0xc9,0x7b,0x3f,0x17,0x64,0xf2,0x2a,0xab,0xc6,0x7e,0x1e,0x4a,0x35,0x1b,0x01,0x17, -0xb8,0xb0,0x4e,0x97,0x18,0x21,0x1c,0xc8,0x80,0x12,0x35,0x4f,0x66,0x5c,0x74,0x09, -0x2d,0xdc,0xbb,0x6c,0xde,0x64,0x6d,0xaf,0x4d,0x89,0xf6,0x8c,0x85,0x62,0x22,0x4c, -0xa4,0x7f,0x1d,0x0c,0x68,0x5c,0xf7,0x1c,0x66,0x94,0x95,0xb5,0x1c,0x75,0x5c,0x08, -0x18,0xf9,0x45,0xd1,0xc9,0x50,0xd0,0x75,0x23,0x2d,0x53,0xcb,0x62,0x97,0x6e,0xdb, -0xb5,0x75,0x5d,0x4b,0x2f,0x13,0x02,0xa2,0x31,0x5d,0xe5,0xeb,0x92,0x50,0x01,0x57, -0xb8,0xf0,0xeb,0x38,0xc8,0xed,0x64,0xd6,0xd1,0xe0,0xfd,0x75,0x34,0x81,0xdb,0x72, -0xb3,0xcd,0x57,0x0e,0x43,0xe3,0x54,0x0a,0x01,0xbc,0xe4,0xd5,0x9b,0x1b,0x32,0xb8, -0x4a,0xe5,0xa8,0x6a,0xf7,0x62,0x74,0xfe,0x31,0x13,0x3f,0xbe,0x7f,0x0d,0xd5,0xd9, -0x82,0x52,0x4d,0xac,0x56,0x98,0x53,0xc6,0xa9,0x3c,0xb3,0x82,0x4b,0x2d,0x09,0xb5, -0x85,0x3d,0x70,0x6c,0xf7,0xc4,0x2a,0xba,0xe7,0x45,0x98,0xc3,0x47,0xa3,0xad,0x96, -0x8b,0x1f,0xa5,0xf2,0x77,0xbf,0xb0,0xd3,0x07,0x76,0x56,0x67,0x75,0xe0,0x9a,0x5a, -0x7e,0xb6,0x4c,0xda,0xe0,0xcd,0x8a,0xa2,0x40,0x86,0xed,0xc8,0x7e,0xc7,0xac,0x41, -0x8a,0x87,0x1c,0xff,0xe9,0xb4,0x34,0x0f,0xbe,0x77,0xef,0x9f,0xc4,0xee,0x73,0xd9, -0x7f,0x8c,0x5d,0x3f,0xba,0xca,0x75,0xb2,0xf9,0x4b,0xfa,0x2c,0xfe,0x24,0x77,0x41, -0x15,0x2f,0x0d,0x01,0xd3,0x15,0xf2,0x1b,0x00,0x00,0xff,0xff,0x03,0x00,0x88,0x32, -0x49,0x7b,0x67,0xbf,0xc6,0x01,0x29,0xf2,0x1c,0x40,0x05,0x3c,0x49,0x25,0x9f,0xab, -0x7c,0x8e,0xc5,0xa5,0x79,0xe0,0x78,0xda,0xca,0x48,0xcd,0xc9,0xc9,0xcf,0x80,0x13, -0x5c,0x00,0x00,0x00,0x00,0xff,0xff,0x03,0x00,0x37,0xf7,0x06,0x47 -}; - -static void verify0(struct archive *a, struct archive_entry *ae) -{ - const void *p; - size_t size; - int64_t offset; - - assert(archive_entry_filetype(ae) == AE_IFREG); - assertEqualInt(archive_entry_mode(ae) & 0777, 0644); - assertEqualInt(archive_entry_uid(ae), UID); - assertEqualInt(archive_entry_gid(ae), GID); - assertEqualString(archive_entry_uname(ae), UNAME); - assertEqualString(archive_entry_gname(ae), GNAME); - assertEqualString(archive_entry_pathname(ae), "f1"); - assert(archive_entry_hardlink(ae) == NULL); - assert(archive_entry_symlink(ae) == NULL); - assertEqualInt(archive_entry_mtime(ae), 86401); - assertEqualInt(archive_entry_size(ae), 16); - assertEqualInt(archive_read_data_block(a, &p, &size, &offset), 0); - assertEqualInt((int)size, 16); - assertEqualInt((int)offset, 0); - assertEqualMem(p, "hellohellohello\n", 16); -} - -static void verify1(struct archive *a, struct archive_entry *ae) -{ - (void)a; /* UNUSED */ - /* A hardlink is not a symlink. */ - assert(archive_entry_filetype(ae) != AE_IFLNK); - /* Nor is it a directory. */ - assert(archive_entry_filetype(ae) != AE_IFDIR); - assertEqualInt(archive_entry_mode(ae) & 0777, 0644); - assertEqualInt(archive_entry_uid(ae), UID); - assertEqualInt(archive_entry_gid(ae), GID); - assertEqualString(archive_entry_uname(ae), UNAME); - assertEqualString(archive_entry_gname(ae), GNAME); - assertEqualString(archive_entry_pathname(ae), "hardlink"); - assertEqualString(archive_entry_hardlink(ae), "f1"); - assert(archive_entry_symlink(ae) == NULL); - assertEqualInt(archive_entry_mtime(ae), 86401); - assertEqualInt(archive_entry_nlink(ae), 2); -} - -/* Verify that symlinks are read correctly. -#How to make -echo "hellohellohello" > f1 -chown $UNAME:$GNAME f1 -chmod 0644 f1 -ln -s f1 symlink -chown $UNAME:$GNAME symlink -chmod 0644 symlink -env TZ=utc touch -afm -t 197001020000.01 f1 symlink -xar -cf archive2.xar f1 symlink -od -t x1 archive2.xar | sed -E -e 's/^0[0-9]+//;s/^ //;s/( )([0-9a-f]{2})/0x\2,/g;$ D' > archive2.xar.txt -*/ -static unsigned char archive2[] = { -0x78,0x61,0x72,0x21,0x00,0x1c,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xe8, -0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x84,0x00,0x00,0x00,0x01,0x78,0xda,0xb4,0x54, -0xcb,0x6e,0xa3,0x30,0x14,0xdd,0xf7,0x2b,0x90,0xf7,0x8c,0x1f,0x40,0x82,0x23,0xe3, -0xaa,0x9b,0x6a,0xf6,0xd3,0xd9,0xcc,0xce,0xf1,0x83,0x58,0xe5,0x25,0x70,0xaa,0xa4, -0x5f,0x3f,0xb6,0x09,0x4d,0xd3,0x30,0xdd,0x8d,0x84,0xc4,0xf5,0xf1,0xb9,0xc7,0x97, -0x7b,0x0f,0x66,0x8f,0xa7,0xb6,0x49,0xde,0xf4,0x38,0xd9,0xbe,0xab,0x00,0xfe,0x81, -0x40,0xa2,0x3b,0xd9,0x2b,0xdb,0xd5,0x15,0xf8,0xfd,0xf2,0x9c,0x96,0xe0,0x91,0x3f, -0xb0,0x93,0x18,0xf9,0x43,0xc2,0x5c,0x2f,0xfd,0x2b,0x61,0x72,0xd4,0xc2,0xf9,0x8c, -0xd4,0xd9,0x56,0x73,0x82,0x10,0x4d,0x31,0x49,0x11,0x79,0xc1,0xd9,0x2e,0x2b,0x76, -0xb8,0x60,0xf0,0x96,0x12,0x93,0x0e,0x5a,0xbe,0x4e,0xc7,0x36,0x99,0xdc,0xb9,0xd1, -0x15,0x98,0x0e,0x02,0x83,0xb0,0x93,0xb0,0xde,0x98,0x49,0x3b,0x8e,0x18,0xbc,0x44, -0x11,0x9d,0xec,0x7b,0x10,0x67,0x30,0x06,0x41,0x02,0x2e,0x1a,0x71,0x65,0x6c,0xa3, -0x13,0xab,0x2a,0x40,0x2e,0x32,0xf2,0xae,0x1c,0xb4,0xcb,0xd1,0x0e,0xd1,0x3f,0x3e, -0x73,0xa9,0x23,0x61,0xed,0x37,0xb4,0xf6,0x4a,0x13,0xdf,0xd0,0xc4,0x95,0x56,0x8f, -0xfd,0x71,0xe0,0xf2,0xa8,0x19,0x9c,0xc3,0x19,0xb5,0x8a,0x63,0x84,0xb0,0x07,0x7d, -0x14,0xa1,0xe3,0xa4,0xc7,0x99,0x17,0xa3,0x19,0xfb,0xa0,0x1d,0x17,0x5a,0xdb,0x2b, -0xcd,0xd1,0xb6,0xf0,0x3d,0x8c,0x61,0x04,0x1b,0xdb,0xbd,0x26,0xee,0x3c,0xf8,0xb6, -0x85,0xaf,0x06,0xdc,0xf8,0x94,0x00,0xce,0xdb,0x61,0x87,0x4f,0xe7,0x36,0x20,0x0c, -0xc6,0x55,0xc4,0x3b,0xd1,0x7e,0xc2,0xe3,0x2a,0xb6,0x31,0x68,0xdc,0xb6,0x70,0x99, -0x84,0x12,0x4e,0xc4,0xc8,0x9f,0xa9,0xbb,0xda,0x1d,0x38,0xc9,0xfc,0x49,0x73,0x38, -0xe3,0x97,0x11,0x91,0xdb,0x69,0x5d,0xc6,0x85,0x37,0xd7,0x71,0x79,0x6c,0xf1,0xd2, -0x32,0x73,0x31,0x0c,0x8d,0x95,0xd1,0x18,0xf0,0x94,0xd6,0xef,0x76,0x00,0xf0,0x42, -0x15,0xa3,0x3c,0xd8,0x37,0xad,0xd2,0xaf,0x3e,0xf9,0xf5,0xf3,0xc9,0x57,0x67,0xca, -0x2c,0x53,0xc4,0x28,0x89,0x69,0x96,0xd3,0x4c,0xec,0xf3,0x92,0x0a,0x25,0x48,0x66, -0x4a,0xb3,0xa5,0xd8,0x6c,0x88,0x91,0xd9,0x86,0x96,0x7e,0x36,0x5f,0x85,0x96,0x5a, -0x4e,0x6e,0x14,0xd2,0xfd,0xf3,0x84,0x42,0x6d,0xf3,0xbd,0xdc,0xcb,0x2d,0x55,0x99, -0xa1,0x7b,0x93,0x0b,0xe3,0xb5,0xf3,0xb2,0x2c,0x91,0xce,0x0b,0xb2,0x29,0x72,0xa3, -0x91,0xa4,0x94,0xc1,0x7b,0xa5,0xb9,0x79,0xf0,0xa3,0x7b,0x2b,0x56,0x9c,0xff,0x0c, -0xb2,0x66,0x45,0x4c,0xb7,0x28,0x45,0x38,0xd0,0x90,0x37,0x98,0x7f,0xf0,0x9a,0x15, -0xd7,0x69,0xff,0xdd,0x8a,0x9b,0x3c,0xff,0x6c,0xc5,0xe0,0xae,0x24,0x18,0xaa,0x02, -0xfd,0x68,0x6b,0xdb,0x89,0x06,0xf0,0x83,0x18,0xd5,0xaa,0xf9,0x82,0x4f,0xef,0x7c, -0xe7,0x59,0xe1,0x22,0x61,0x30,0x5e,0x2b,0x7f,0x01,0x00,0x00,0xff,0xff,0x03,0x00, -0x2b,0xab,0x4f,0xf9,0xbb,0xf7,0x90,0xb5,0x34,0x8f,0x7c,0xae,0x72,0xa0,0x80,0xd2, -0x69,0xc7,0xa2,0xe7,0x44,0x53,0xeb,0x75,0x78,0xda,0xca,0x48,0xcd,0xc9,0xc9,0xcf, -0x80,0x13,0x5c,0x00,0x00,0x00,0x00,0xff,0xff,0x03,0x00,0x37,0xf7,0x06,0x47 -}; - -static void verify2(struct archive *a, struct archive_entry *ae) -{ - (void)a; /* UNUSED */ - assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); - assertEqualInt(archive_entry_mode(ae) & 0777, 0755); - assertEqualInt(archive_entry_uid(ae), UID); - assertEqualInt(archive_entry_gid(ae), GID); - assertEqualString(archive_entry_uname(ae), UNAME); - assertEqualString(archive_entry_gname(ae), GNAME); - assertEqualString(archive_entry_pathname(ae), "symlink"); - assertEqualString(archive_entry_symlink(ae), "f1"); - assert(archive_entry_hardlink(ae) == NULL); -} - -/* Character device node. -#How to make -mknod devchar c 0 30 -chown $UNAME:$GNAME devchar -chmod 0644 devchar -env TZ=utc touch -afm -t 197001020000.01 devchar -xar -cf archive3.xar devchar -od -t x1 archive3.xar | sed -E -e 's/^0[0-9]+//;s/^ //;s/( )([0-9a-f]{2})/0x\2,/g;$ D' > archive3.xar.txt -*/ -static unsigned char archive3[] = { -0x78,0x61,0x72,0x21,0x00,0x1c,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x38, -0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x3b,0x00,0x00,0x00,0x01,0x78,0xda,0x7c,0x92, -0x4d,0x6e,0xc3,0x20,0x10,0x85,0xf7,0x39,0x05,0xf2,0xde,0x05,0x9c,0x9f,0x36,0xd6, -0x84,0xec,0x7a,0x82,0x74,0xd3,0x1d,0xc2,0x93,0x98,0xd4,0x36,0x11,0xe0,0x28,0xe9, -0xe9,0x0b,0xe3,0xa4,0x69,0xa5,0xaa,0x92,0x25,0x1e,0x8f,0xef,0x8d,0x86,0xc1,0xb0, -0xbd,0xf4,0x1d,0x3b,0xa3,0x0f,0xd6,0x0d,0x9b,0x42,0x3e,0x89,0x82,0xe1,0x60,0x5c, -0x63,0x87,0xc3,0xa6,0x78,0xdb,0xbd,0x96,0x2f,0xc5,0x56,0xcd,0xe0,0xa2,0xbd,0x9a, -0x31,0x88,0xce,0xa4,0x85,0x81,0xf1,0xa8,0x63,0x4a,0x94,0xd1,0xf6,0xa8,0x2a,0x21, -0xd6,0xa5,0xac,0x4a,0x51,0xed,0xa4,0xa8,0xab,0x79,0x2d,0x57,0xc0,0x7f,0x23,0x14, -0x6a,0xd1,0x7c,0x84,0xb1,0x67,0x21,0x5e,0x3b,0xdc,0x14,0xa1,0xd5,0xb2,0xc8,0x27, -0x0c,0xdc,0x7e,0x1f,0x30,0x2a,0x01,0xfc,0xa6,0xc8,0x0d,0xf6,0x33,0x17,0x07,0x4e, -0x22,0x97,0xe0,0xf7,0x1a,0xb4,0xdb,0xdb,0x0e,0x99,0x6d,0x52,0xdb,0xb7,0x32,0xe6, -0xaf,0x76,0xaa,0x7a,0xb9,0x7c,0x4f,0xc9,0x7b,0x1f,0x0c,0x7a,0x92,0x72,0xfd,0x2c, -0x4a,0x21,0x33,0x26,0x44,0x9d,0x3f,0x99,0xb0,0xfe,0x81,0xe9,0x7f,0x30,0xfd,0xc0, -0x0e,0xde,0x8d,0x27,0x65,0x46,0x04,0x3e,0xc9,0xc9,0xb5,0x8d,0x92,0x42,0xc8,0x64, -0x26,0x45,0xd6,0x18,0xd0,0x4f,0x1c,0xa9,0xc9,0xfb,0xc6,0xc6,0x3b,0xd6,0xbb,0x06, -0x95,0x58,0x2d,0x16,0xa9,0x99,0x2c,0xc9,0x6c,0xf0,0x6c,0xcd,0xa4,0x13,0x61,0x07, -0xe7,0xd5,0x3c,0x0d,0x66,0x52,0x37,0x57,0x1f,0x93,0xce,0x26,0x09,0x8a,0xf1,0x1f, -0x39,0x88,0xd7,0x13,0x2a,0xd3,0x6a,0xaf,0x4d,0x44,0xcf,0xc2,0x09,0x8d,0xd5,0x1d, -0x70,0xf2,0x89,0x18,0x74,0xba,0x54,0x8a,0x64,0x08,0x38,0xed,0x68,0xea,0x79,0xd0, -0xf9,0xf9,0x39,0xbd,0x3f,0x70,0xfa,0x1b,0xbe,0x00,0x00,0x00,0xff,0xff,0x03,0x00, -0xab,0x43,0xa3,0xac,0x76,0x40,0x1e,0x8b,0x95,0x0d,0x28,0x79,0x79,0x43,0x49,0x4e, -0x16,0xa1,0x56,0x99,0x1f,0x83,0x77,0x41 -}; - -static void verify3(struct archive *a, struct archive_entry *ae) -{ - (void)a; /* UNUSED */ - assertEqualInt(archive_entry_filetype(ae), AE_IFCHR); - assertEqualInt(archive_entry_mode(ae) & 0777, 0644); - assertEqualInt(archive_entry_uid(ae), UID); - assertEqualInt(archive_entry_gid(ae), GID); - assertEqualString(archive_entry_uname(ae), UNAME); - assertEqualString(archive_entry_gname(ae), GNAME); - assertEqualString(archive_entry_pathname(ae), "devchar"); - assert(archive_entry_symlink(ae) == NULL); - assert(archive_entry_hardlink(ae) == NULL); - assertEqualInt(archive_entry_mtime(ae), 86401); -} - -/* Block device node. -#How to make -mknod devblock b 0 30 -chown $UNAME:$GNAME devblock -chmod 0644 devblock -env TZ=utc touch -afm -t 197001020000.01 devblock -xar -cf archive4.xar devblock -od -t x1 archive4.xar | sed -E -e 's/^0[0-9]+//;s/^ //;s/( )([0-9a-f]{2})/0x\2,/g;$ D' > archive4.xar.txt -*/ -static unsigned char archive4[] = { -0x78,0x61,0x72,0x21,0x00,0x1c,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x34, -0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x38,0x00,0x00,0x00,0x01,0x78,0xda,0x7c,0x92, -0xc1,0x6e,0xc2,0x30,0x0c,0x86,0xef,0x3c,0x45,0xd4,0x7b,0x17,0x07,0xd0,0x0a,0x95, -0x09,0xb7,0x3d,0x01,0xbb,0xec,0x96,0xa5,0x06,0x32,0xda,0xa6,0x6a,0x5a,0x04,0x7b, -0xfa,0x25,0x2e,0x8c,0x4d,0x9a,0x26,0x55,0xea,0x97,0x3f,0x9f,0x2d,0x37,0x29,0x6e, -0x2f,0x4d,0x2d,0xce,0xd4,0x07,0xe7,0xdb,0x4d,0xa6,0x9e,0x20,0x13,0xd4,0x5a,0x5f, -0xb9,0xf6,0xb0,0xc9,0x5e,0x77,0x2f,0xf9,0x2a,0xdb,0xea,0x19,0x5e,0x4c,0xaf,0x67, -0x02,0x07,0x6f,0xe3,0x4b,0xa0,0xed,0xc9,0x0c,0xb1,0x22,0x1f,0x5c,0x43,0x7a,0x0e, -0xb0,0xce,0xd5,0x3c,0x87,0xf9,0x4e,0x41,0xb9,0x58,0x95,0xaa,0x40,0xf9,0x5b,0xe1, -0xa2,0x23,0xd9,0x53,0x18,0x1b,0x11,0x86,0x6b,0x4d,0x9b,0x2c,0x1c,0x8d,0xca,0xd2, -0x8e,0x40,0xbf,0xdf,0x07,0x1a,0x34,0xa0,0xbc,0x11,0xa7,0xc1,0x7d,0xa6,0xe6,0x28, -0x19,0x52,0x0b,0x79,0xef,0xc1,0xab,0xbd,0xab,0x49,0xb8,0x2a,0x8e,0x7d,0x6b,0x63, -0xff,0x1e,0x07,0x8a,0xb7,0x58,0x79,0x9f,0x43,0x60,0xc3,0xa8,0xd6,0x05,0xe4,0xa0, -0x92,0x06,0x50,0xa6,0x47,0x45,0xad,0x79,0x68,0xe6,0x1f,0xcd,0x3c,0xb4,0x43,0xef, -0xc7,0x4e,0xdb,0x91,0x50,0x4e,0x38,0xa5,0xae,0xd2,0x0a,0x40,0xc5,0x30,0x12,0x47, -0x63,0xa0,0x7e,0xf2,0x98,0xa6,0xec,0x5b,0x1b,0xef,0x5a,0xe3,0x2b,0xd2,0xf0,0xbc, -0x5c,0xc6,0x61,0x12,0x72,0x58,0xd1,0xd9,0xd9,0x89,0xa3,0xe1,0x5a,0xdf,0xeb,0x45, -0x3c,0x98,0x89,0x6e,0xa9,0xf9,0x88,0x9c,0x42,0x06,0x2e,0x93,0x3f,0xea,0x70,0xb8, -0x76,0xa4,0xdf,0x6b,0x6f,0x4f,0x22,0x74,0x64,0x9d,0xa9,0x51,0x72,0xc6,0xbb,0xad, -0x89,0x1f,0x14,0x75,0x16,0x50,0xf2,0x92,0x8f,0x3c,0x9d,0x72,0xba,0x7b,0xc9,0x97, -0x8f,0x92,0x7f,0x85,0x2f,0x00,0x00,0x00,0xff,0xff,0x03,0x00,0xbe,0x66,0xa2,0x82, -0x3a,0x54,0xd3,0x61,0xaa,0x8e,0x30,0x4c,0xc8,0x36,0x3b,0x7a,0xa4,0xb9,0xef,0xfc, -0x7a,0x5d,0x21,0xde -}; - -static void verify4(struct archive *a, struct archive_entry *ae) -{ - (void)a; /* UNUSED */ - assertEqualInt(archive_entry_filetype(ae), AE_IFBLK); - assertEqualInt(archive_entry_mode(ae) & 0777, 0644); - assertEqualInt(archive_entry_uid(ae), UID); - assertEqualInt(archive_entry_gid(ae), GID); - assertEqualString(archive_entry_uname(ae), UNAME); - assertEqualString(archive_entry_gname(ae), GNAME); - assertEqualString(archive_entry_pathname(ae), "devblock"); - assert(archive_entry_symlink(ae) == NULL); - assert(archive_entry_hardlink(ae) == NULL); - assertEqualInt(archive_entry_mtime(ae), 86401); -} - -/* Directory. -#How to make -mkdir dir1 -chown $UNAME:$GNAME dir1 -chmod 0755 dir1 -env TZ=utc touch -afm -t 197001020000.01 dir1 -xar -cf archive5.xar dir1 -od -t x1 archive5.xar | sed -E -e 's/^0[0-9]+//;s/^ //;s/( )([0-9a-f]{2})/0x\2,/g;$ D' > archive5.xar.txt -*/ -static unsigned char archive5[] = { -0x78,0x61,0x72,0x21,0x00,0x1c,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x16, -0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xec,0x00,0x00,0x00,0x01,0x78,0xda,0x74,0x91, -0xc1,0x6e,0xc2,0x30,0x0c,0x86,0xef,0x3c,0x45,0xd4,0x7b,0x17,0xa7,0x83,0x31,0xaa, -0x34,0xdc,0xf6,0x04,0xec,0xb2,0x5b,0x95,0x1a,0x88,0x68,0x1a,0x94,0xa4,0x13,0xdd, -0xd3,0x2f,0x71,0xe9,0xd0,0xa4,0x4d,0xaa,0xd4,0x3f,0xbf,0x3f,0xff,0xb2,0x6c,0xb9, -0xbf,0xd9,0x9e,0x7d,0xa2,0x0f,0xc6,0x0d,0x4d,0x21,0x9e,0xa0,0x60,0x38,0x68,0xd7, -0x99,0xe1,0xd4,0x14,0xef,0x87,0xb7,0xf2,0xb5,0xd8,0xab,0x95,0xbc,0xb5,0x5e,0xad, -0x98,0x8c,0x4e,0xa7,0x1f,0x93,0xda,0x63,0x1b,0x53,0x47,0x19,0x8d,0x45,0x55,0x01, -0xec,0x4a,0x51,0x95,0x50,0x1d,0x04,0xd4,0x6b,0x51,0xaf,0x37,0x92,0xff,0x46,0xa8, -0xe9,0x8c,0xfa,0x12,0x46,0xcb,0x42,0x9c,0x7a,0x6c,0x8a,0x70,0x6e,0x45,0x91,0x2b, -0x4c,0xba,0xe3,0x31,0x60,0x54,0x20,0xf9,0x5d,0x91,0x1b,0xcc,0x57,0x0e,0x97,0x9c, -0x44,0x8e,0xe0,0x4b,0x06,0xbd,0x8e,0xa6,0x47,0x66,0xba,0x34,0xf6,0x3d,0x46,0xff, -0x3d,0xce,0x33,0x7c,0xa4,0xce,0x65,0x0e,0x26,0x2d,0x49,0xb1,0xdb,0x42,0x09,0x22, -0x63,0x00,0x75,0xfe,0x44,0xc2,0xec,0x03,0x6b,0xff,0x49,0x7b,0x49,0x58,0xfb,0xc0, -0x4e,0xde,0x8d,0x57,0xa5,0x47,0x94,0x7c,0x96,0xb3,0x6b,0x3a,0x25,0x00,0x44,0x32, -0x93,0x22,0x6b,0x0c,0xe8,0x67,0x8e,0xd4,0xec,0xfd,0x60,0xe3,0x82,0x59,0xd7,0xa1, -0x82,0xed,0x26,0xed,0x90,0x24,0x99,0x71,0xba,0xa2,0xea,0x8c,0x47,0x1d,0x9d,0x9f, -0x24,0xa7,0x37,0x55,0x86,0xd6,0x52,0x25,0x45,0x90,0xa4,0x35,0xe5,0xcd,0xe4,0x7b, -0x71,0x3a,0x98,0xe4,0x74,0xbe,0x6f,0x00,0x00,0x00,0xff,0xff,0x03,0x00,0x23,0x7a, -0x8c,0x2f,0x78,0xe9,0x69,0x28,0x93,0x14,0x72,0x68,0x8d,0xeb,0x42,0x7b,0xf6,0x0f, -0x70,0x64,0xa3,0xff,0xb9,0x35 -}; - -static void verify5(struct archive *a, struct archive_entry *ae) -{ - (void)a; /* UNUSED */ - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - assertEqualInt(archive_entry_mtime(ae), 86401); - assertEqualInt(archive_entry_mode(ae) & 0777, 0755); - assertEqualInt(archive_entry_uid(ae), UID); - assertEqualInt(archive_entry_gid(ae), GID); - assertEqualString(archive_entry_uname(ae), UNAME); - assertEqualString(archive_entry_gname(ae), GNAME); -} - -/* fifo -#How to make -mkfifo -m 0755 fifo -chown $UNAME:$GNAME fifo -env TZ=utc touch -afm -t 197001020000.01 fifo -xar -cf archive6.xar fifo -od -t x1 archive6.xar | sed -E -e 's/^0[0-9]+//;s/^ //;s/( )([0-9a-f]{2})/0x\2,/g;$ D' > archive6.xar.txt -*/ -static unsigned char archive6[] = { -0x78,0x61,0x72,0x21,0x00,0x1c,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x0e, -0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xe7,0x00,0x00,0x00,0x01,0x78,0xda,0x7c,0x91, -0xc1,0x6e,0xc3,0x20,0x0c,0x86,0xef,0x7d,0x0a,0xc4,0x3d,0xc3,0x64,0xab,0xda,0x46, -0x94,0xde,0xf6,0x04,0xdd,0x65,0x37,0x44,0x9c,0x16,0x2d,0x84,0x2a,0x90,0xa9,0xdd, -0xd3,0x0f,0x9c,0x66,0xd5,0xa4,0x69,0x12,0x52,0xbe,0xfc,0x7c,0xb6,0x2c,0xac,0x0e, -0x57,0xdf,0xb3,0x4f,0x1c,0xa3,0x0b,0xc3,0x9e,0xcb,0x27,0xe0,0x0c,0x07,0x1b,0x5a, -0x37,0x9c,0xf6,0xfc,0xed,0xf8,0x5a,0x6d,0xf9,0x41,0xaf,0xd4,0xd5,0x8c,0x7a,0xc5, -0x54,0x0a,0x36,0x7f,0x98,0xb2,0x23,0x9a,0x94,0x2b,0xaa,0xe4,0x3c,0xea,0x1a,0x60, -0x57,0xc9,0xba,0x82,0xfa,0x28,0x65,0xf3,0x02,0x4d,0xbd,0x55,0xe2,0xb7,0x42,0x45, -0x67,0xb4,0x1f,0x71,0xf2,0x2c,0xa6,0x5b,0x8f,0x7b,0x1e,0xcf,0x46,0xf2,0x72,0xc3, -0x54,0xe8,0xba,0x88,0x49,0x83,0x12,0x77,0xa2,0x34,0xba,0xaf,0xd2,0x5c,0x09,0x82, -0xd2,0x42,0x2c,0x3d,0xe8,0xaf,0x73,0x3d,0x32,0xd7,0xe6,0xb1,0xef,0x6d,0xec,0xdf, -0xe3,0xc8,0xe7,0xf7,0x5c,0xb9,0xcc,0xc1,0x94,0x27,0x94,0xbb,0x0d,0x54,0x20,0x8b, -0x06,0xd0,0x94,0x23,0xb3,0xe6,0x1f,0x9a,0xf9,0x47,0x33,0x0f,0xed,0x34,0x86,0xe9, -0xa2,0xed,0x84,0x4a,0xcc,0x38,0xa7,0xae,0xd5,0x12,0x40,0xe6,0x30,0x13,0x45,0x53, -0xc4,0x71,0xf6,0x88,0xe6,0xec,0x47,0x9b,0x16,0xcd,0x87,0x16,0x35,0x6c,0xd6,0xeb, -0x3c,0x4c,0x41,0x0a,0xd3,0xed,0x82,0xba,0x73,0x5d,0x50,0x82,0x90,0xc2,0xc1,0xf8, -0x25,0x24,0xa4,0x17,0x2a,0x8f,0x52,0x56,0x25,0x68,0x57,0x4a,0xd0,0xe6,0xbe,0x01, -0x00,0x00,0xff,0xff,0x03,0x00,0x44,0x19,0x8a,0x2a,0x82,0xbc,0x8c,0xae,0x97,0xa7, -0x7d,0x65,0xa5,0x82,0xdb,0xaa,0xc2,0xcb,0xbe,0xf0,0x1f,0xd1,0xf9,0x56 -}; - -static void verify6(struct archive *a, struct archive_entry *ae) -{ - (void)a; /* UNUSED */ - assertEqualInt(archive_entry_filetype(ae), AE_IFIFO); - assertEqualInt(archive_entry_mode(ae) & 0777, 0755); - assertEqualInt(archive_entry_uid(ae), UID); - assertEqualInt(archive_entry_gid(ae), GID); - assertEqualString(archive_entry_uname(ae), UNAME); - assertEqualString(archive_entry_gname(ae), GNAME); - assertEqualString(archive_entry_pathname(ae), "fifo"); - assert(archive_entry_symlink(ae) == NULL); - assert(archive_entry_hardlink(ae) == NULL); - assertEqualInt(archive_entry_mtime(ae), 86401); -} - -/* Verify that a file records with directory name. -#How to make -mkdir dir1 -echo "hellohellohello" > dir1/f1 -chown $UNAME:$GNAME dir1/f1 -chmod 0644 dir1/f1 -env TZ=utc touch -afm -t 197001020000.01 dir1/f1 -xar -cf archive7.xar dir1/f1 -od -t x1 archive7.xar | sed -E -e 's/^0[0-9]+//;s/^ //;s/( )([0-9a-f]{2})/0x\2,/g;$ D' > archive7.xar.txt -*/ - -static unsigned char archive7[] = { -0x78,0x61,0x72,0x21,0x00,0x1c,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xbb, -0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x8a,0x00,0x00,0x00,0x01,0x78,0xda,0x7c,0x53, -0xc9,0x6e,0xdb,0x30,0x14,0xbc,0xe7,0x2b,0x04,0xdd,0x55,0x2e,0xa2,0x16,0x1a,0xb4, -0x82,0x5e,0x8a,0xdc,0x93,0x5e,0x7a,0xa3,0xb9,0xd8,0x44,0xb5,0x41,0xa2,0x02,0x3b, -0x5f,0x5f,0x92,0xa2,0x1c,0xbb,0x59,0x00,0x01,0x1a,0x3e,0xce,0x1b,0x0d,0x9f,0x86, -0xec,0xf1,0xdc,0xb5,0xc9,0xab,0x9a,0x66,0x33,0xf4,0xfb,0x14,0xfd,0x80,0x69,0xa2, -0x7a,0x31,0x48,0xd3,0x1f,0xf7,0xe9,0xef,0x97,0x5f,0x59,0x9d,0x3e,0x36,0x0f,0xec, -0xcc,0xa7,0xe6,0x21,0x61,0x76,0x10,0xee,0x95,0x30,0x31,0x29,0x6e,0x5d,0x47,0x66, -0x4d,0xa7,0x1a,0x0c,0x21,0xcd,0x10,0xce,0x20,0x7e,0x41,0x68,0x57,0xe0,0x5d,0x51, -0x31,0x70,0x4f,0x09,0x4d,0x27,0x25,0xfe,0xce,0x4b,0x97,0xcc,0xf6,0xd2,0xaa,0x7d, -0x3a,0x9f,0x38,0x4a,0xfd,0x4e,0xc2,0x06,0xad,0x67,0x65,0x1b,0xc8,0x40,0x44,0xa1, -0x3a,0x9b,0x37,0x2f,0xce,0x40,0x00,0x5e,0x02,0x6c,0x1a,0x61,0xa5,0x4d,0xab,0x12, -0x23,0x9d,0xed,0x28,0x63,0x2f,0xa3,0x6a,0xa4,0x99,0x94,0xb0,0xc3,0x74,0x61,0x20, -0xac,0xc3,0x4e,0xcf,0xbb,0xb0,0x83,0x18,0x08,0x30,0x14,0xaf,0xfd,0x78,0xed,0x4f, -0x98,0xe4,0x96,0xaf,0x30,0x61,0xad,0xea,0x8f,0xf6,0xd4,0xe0,0x9c,0x81,0x08,0xe3, -0x46,0xb4,0x88,0xef,0xdd,0x6e,0x7e,0x51,0xf9,0xee,0xd7,0x17,0xb7,0x69,0x6e,0xa7, -0xe6,0xe3,0xd8,0x1a,0x11,0x46,0x03,0xce,0xd9,0xf1,0xcd,0x8c,0x29,0xd8,0xb8,0x7c, -0x12,0x27,0xf3,0xaa,0x64,0xf6,0xff,0xa8,0x9e,0x9f,0x7e,0xba,0x33,0xea,0x3a,0xcf, -0x25,0xd6,0x52,0x20,0x9a,0x13,0x9a,0xf3,0x03,0xa9,0x29,0x97,0x1c,0xe7,0xba,0xd6, -0x15,0x45,0xba,0xc4,0x5a,0xe4,0x25,0xad,0x19,0xf8,0x20,0x74,0x75,0x73,0xb6,0x13, -0x17,0xf6,0xcb,0x4f,0x14,0xb2,0x22,0x07,0x71,0x10,0x15,0x95,0xb9,0xa6,0x07,0x4d, -0xb8,0x76,0xe2,0xa4,0xae,0x6b,0xa8,0x48,0x81,0xcb,0x82,0x68,0x05,0x05,0xa5,0x0c, -0x7c,0x54,0x8a,0x33,0x04,0xef,0x43,0x64,0xe2,0xf3,0x7c,0x90,0xfa,0x8f,0xfb,0x95, -0x5b,0x30,0x1c,0xaf,0x0b,0x18,0xd1,0x0a,0x66,0x10,0x79,0x1e,0x84,0x3b,0xff,0x20, -0xc7,0xeb,0x6e,0x78,0xfc,0x1b,0x1e,0xbf,0xe1,0x1d,0xa7,0x61,0x19,0x1b,0xb1,0x28, -0x06,0x56,0x18,0xcb,0x46,0x36,0x08,0x42,0x17,0x02,0x8f,0xd6,0xda,0x32,0xab,0x69, -0x65,0x06,0x14,0x8b,0x57,0xe2,0x72,0x25,0x76,0x83,0x54,0x0d,0x2c,0x09,0x71,0x96, -0x3c,0x5c,0xab,0x21,0x62,0x3e,0x48,0x37,0x69,0x8b,0x71,0xd3,0x77,0x61,0x03,0x9e, -0xb4,0x86,0x38,0x22,0xd7,0xe1,0xaf,0x13,0x03,0xe1,0x72,0xfd,0x03,0x00,0x00,0xff, -0xff,0x03,0x00,0x8d,0xb1,0x06,0x76,0xa6,0x7a,0xc3,0xbb,0x13,0x3d,0x45,0xe2,0x2b, -0x3b,0xd0,0x88,0xc7,0x58,0x7b,0xbd,0x30,0x9d,0x01,0x44,0x78,0xda,0xca,0x48,0xcd, -0xc9,0xc9,0xcf,0x80,0x13,0x5c,0x00,0x00,0x00,0x00,0xff,0xff,0x03,0x00,0x37,0xf7, -0x06,0x47 -}; - -static void verify7(struct archive *a, struct archive_entry *ae) -{ - (void)a; /* UNUSED */ - assert(archive_entry_filetype(ae) == AE_IFREG); - assertEqualInt(archive_entry_mode(ae) & 0777, 0644); - assertEqualInt(archive_entry_uid(ae), UID); - assertEqualInt(archive_entry_gid(ae), GID); - assertEqualString(archive_entry_uname(ae), UNAME); - assertEqualString(archive_entry_gname(ae), GNAME); - assertEqualString(archive_entry_pathname(ae), "dir1/f1"); - assert(archive_entry_hardlink(ae) == NULL); - assert(archive_entry_symlink(ae) == NULL); - assertEqualInt(archive_entry_mtime(ae), 86401); -} - -/* Verify that a file records with bzip2 compression -#How to make -echo "hellohellohello" > f1 -chown $UNAME:$GNAME f1 -chmod 0644 f1 -env TZ=utc touch -afm -t 197001020000.01 f1 -xar --compression bzip2 -cf archive8.xar f1 -od -t x1 archive8.xar | sed -E -e 's/^0[0-9]+//;s/^ //;s/( )([0-9a-f]{2})/0x\2,/g;$ D' > archive8.xar.txt -*/ - -static unsigned char archive8[] = { -0x78,0x61,0x72,0x21,0x00,0x1c,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xb1, -0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x42,0x00,0x00,0x00,0x01,0x78,0xda,0x7c,0x53, -0xcb,0x6e,0xdc,0x20,0x14,0xdd,0xe7,0x2b,0x90,0xf7,0x0e,0x60,0xe3,0x07,0x23,0x86, -0xa8,0x9b,0xa8,0xfb,0x4e,0x37,0xdd,0x61,0x1e,0x63,0x14,0xbf,0x64,0xe3,0x68,0x92, -0xaf,0x2f,0x60,0x3b,0xa3,0x34,0x6d,0x25,0x4b,0x3e,0x1c,0x0e,0xe7,0x5e,0xee,0xe5, -0xb2,0xa7,0x5b,0xdf,0x81,0x57,0x3d,0x2f,0x76,0x1c,0xce,0x09,0x7e,0x44,0x09,0xd0, -0x83,0x1c,0x95,0x1d,0xae,0xe7,0xe4,0xe7,0xe5,0x39,0xad,0x93,0x27,0xfe,0xc0,0x6e, -0x62,0xe6,0x0f,0x80,0xb9,0x51,0xfa,0x1f,0x60,0x72,0xd6,0xc2,0xf9,0x13,0xa9,0xb3, -0xbd,0xe6,0x19,0x42,0x34,0xc5,0x59,0x8a,0xc8,0x05,0xd1,0x13,0xc6,0x27,0x9c,0x33, -0xf8,0x59,0x12,0x0f,0xb5,0x5a,0xbe,0x2c,0x6b,0x0f,0x16,0xf7,0xd6,0xe9,0x73,0xb2, -0xb4,0x02,0x27,0x61,0x07,0xb0,0xd1,0x98,0x45,0x3b,0x8e,0x18,0xdc,0x51,0x64,0x17, -0xfb,0x1e,0xcc,0x19,0x8c,0x20,0x58,0xc0,0xc3,0x23,0xae,0x8c,0xed,0x34,0xb0,0xca, -0xa7,0xbd,0xdb,0x28,0xe1,0x44,0x44,0x80,0x75,0x7a,0xb8,0xba,0x96,0x13,0xc2,0xe0, -0x0e,0x37,0x7e,0xf7,0xcf,0x3e,0x87,0xda,0x63,0xe1,0xf2,0x1e,0xcb,0x73,0x47,0x21, -0x8e,0x84,0xc5,0x34,0x75,0x56,0xc6,0x5b,0xc1,0x5b,0xda,0xbc,0xdb,0x29,0x4b,0xe0, -0xae,0x15,0xb3,0x6c,0xed,0xab,0x56,0xe9,0x9f,0xb7,0xfc,0xf1,0xfd,0x9b,0x4f,0xcf, -0xe4,0xa4,0x28,0x4a,0x94,0xcb,0x3a,0xcf,0x9b,0x26,0x93,0xaa,0x92,0xba,0x29,0xa8, -0x2a,0x89,0x29,0xa8,0x50,0x22,0x97,0x45,0xa1,0x71,0xe5,0xeb,0xf6,0xc5,0xe8,0x48, -0xe6,0xe6,0x66,0x21,0xdd,0x3f,0x23,0x14,0xaa,0x22,0x8d,0x6c,0x64,0x45,0x55,0x6e, -0x68,0x63,0x88,0x30,0xa6,0x36,0xa4,0xae,0x6b,0xa4,0x49,0x91,0x95,0x05,0x31,0x1a, -0x49,0x4a,0x19,0xfc,0xea,0xb4,0x55,0x0f,0x7e,0x94,0x8f,0xc9,0xbf,0xf7,0x15,0xd5, -0xbf,0x7c,0x0b,0x8e,0x86,0x02,0xd6,0x47,0x88,0x69,0x85,0x52,0x84,0x53,0x94,0x5d, -0x10,0x3a,0x85,0x0f,0x7b,0x59,0x7f,0x97,0x89,0xff,0xc8,0xc4,0x5d,0x76,0x9d,0xc7, -0x75,0xe2,0x72,0xd5,0x0c,0x6e,0x70,0x63,0xad,0xe2,0x18,0x21,0xec,0x49,0x8f,0x22, -0xb5,0x2e,0x7a,0xde,0x74,0x11,0x6d,0xdc,0x87,0x6c,0x3d,0x64,0xfd,0xa8,0x34,0x47, -0x65,0x78,0x02,0x11,0x46,0xd2,0xbd,0x4d,0x1a,0x74,0x76,0x78,0x39,0x27,0xe3,0x6c, -0xaf,0x76,0x10,0x5d,0xc2,0x5b,0x31,0xab,0xc0,0x31,0x18,0xb6,0x37,0xe1,0x20,0x7c, -0x5e,0xc6,0xfb,0x45,0x10,0x1f,0x5f,0x78,0x6f,0x61,0x0a,0x60,0x1c,0x03,0x06,0xe3, -0x50,0xfc,0x06,0x00,0x00,0xff,0xff,0x03,0x00,0x19,0xcf,0xf5,0xc0,0xf9,0x65,0xe8, -0x78,0xc3,0xfa,0x5f,0x0a,0xf6,0x09,0x17,0xd8,0xb0,0x54,0xb9,0x02,0x8d,0x91,0x31, -0x9c,0x42,0x5a,0x68,0x39,0x31,0x41,0x59,0x26,0x53,0x59,0xc1,0x52,0x36,0xf7,0x00, -0x00,0x03,0x41,0x00,0x00,0x10,0x02,0x44,0xa0,0x00,0x21,0xb4,0x01,0x9a,0x0d,0x46, -0xa5,0x32,0x38,0xbb,0x92,0x29,0xc2,0x84,0x86,0x0a,0x91,0xb7,0xb8 -}; - -/* Verify that a file records with no compression -#How to make -echo "hellohellohello" > f1 -chown $UNAME:$GNAME f1 -chmod 0644 f1 -env TZ=utc touch -afm -t 197001020000.01 f1 -xar --compression none -cf archive9.xar f1 -od -t x1 archive9.xar | sed -E -e 's/^0[0-9]+//;s/^ //;s/( )([0-9a-f]{2})/0x\2,/g;$ D' > archive9.xar.txt -*/ - -static unsigned char archive9[] = { -0x78,0x61,0x72,0x21,0x00,0x1c,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x98, -0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x47,0x00,0x00,0x00,0x01,0x78,0xda,0xa4,0x53, -0x4d,0x6f,0xe3,0x20,0x14,0xbc,0xf7,0x57,0x20,0xee,0x5e,0xc0,0x25,0x89,0x1d,0x11, -0xaa,0x5e,0xaa,0xbd,0x6f,0xf6,0xb2,0x37,0x02,0x8f,0x18,0xc5,0x1f,0x11,0xc6,0x55, -0xba,0xbf,0x7e,0x01,0xdb,0xad,0xba,0x55,0x7b,0xa9,0x64,0xc9,0xe3,0x61,0xde,0x78, -0x78,0xf0,0xc4,0xc3,0xad,0x6b,0xd1,0x33,0xf8,0xd1,0x0d,0xfd,0x01,0xb3,0x1f,0x14, -0x23,0xe8,0xf5,0x60,0x5c,0x7f,0x3e,0xe0,0xdf,0xc7,0xa7,0xa2,0xc2,0x0f,0xf2,0x4e, -0xdc,0x94,0x97,0x77,0x48,0x84,0x41,0xc7,0x17,0x12,0xda,0x83,0x0a,0xb1,0xa2,0x08, -0xae,0x03,0x59,0x52,0x5a,0x17,0xac,0x2c,0x28,0x3f,0xd2,0x7a,0xcf,0xaa,0x3d,0xaf, -0x05,0x79,0x2f,0xc9,0x45,0x0d,0xe8,0xcb,0x38,0x75,0x68,0x0c,0x2f,0x2d,0x1c,0xf0, -0xd8,0x28,0x86,0xd3,0x0a,0x12,0x83,0xb5,0x23,0x04,0x49,0x05,0x59,0x50,0x66,0x47, -0xf7,0x37,0x99,0x0b,0x92,0x41,0xb2,0x20,0xab,0x47,0xfe,0xb2,0xae,0x05,0xe4,0x4c, -0x8c,0xbd,0xd8,0x18,0x15,0x54,0x46,0x48,0xb4,0xd0,0x9f,0x43,0x23,0xd9,0x56,0x90, -0x05,0xce,0xfc,0xba,0xb9,0x35,0x84,0xba,0x5e,0x5b,0xa7,0x73,0x52,0x32,0xe8,0x00, -0xa1,0x18,0x43,0x4c,0xde,0x61,0xb2,0x14,0x2c,0x81,0xca,0xf7,0xd9,0x96,0x70,0xc9, -0x7e,0x0d,0x17,0x39,0xe5,0x75,0xe3,0x9e,0xc1,0x14,0xff,0x6f,0xf5,0xd7,0xcf,0xc7, -0x98,0x71,0x63,0x76,0xfc,0xa4,0x4f,0x7a,0x57,0x9b,0x7b,0x5b,0x9f,0x2c,0x57,0xd6, -0x56,0x96,0x57,0x55,0x45,0x81,0x6f,0xca,0xed,0x86,0x5b,0xa0,0xba,0x8e,0xcd,0xfb, -0x60,0xb4,0xa6,0xbf,0x05,0xaf,0x62,0xca,0xef,0xff,0xe1,0xa3,0xd3,0xdc,0x42,0xf2, -0xda,0x43,0xa1,0x3f,0x39,0xdc,0xed,0x9f,0x78,0x0e,0xeb,0xa9,0x22,0xd1,0x65,0xc8, -0xea,0x1d,0x2d,0x28,0x2b,0x68,0x79,0xa4,0x74,0x9f,0x1e,0x16,0x65,0xdd,0x9b,0x4c, -0x7d,0x21,0x53,0x6f,0xb2,0xb3,0x1f,0xa6,0xab,0xd4,0x13,0x08,0x32,0xc3,0x99,0x75, -0x46,0x32,0x4a,0x59,0x24,0x23,0xca,0xd4,0x34,0x82,0x9f,0x75,0x19,0xcd,0xdc,0xab, -0x6c,0x5a,0x65,0xdd,0x60,0x40,0xd2,0x2d,0xe7,0x31,0x4c,0x82,0x99,0x0c,0x2f,0x57, -0x40,0xad,0xeb,0x2f,0x07,0x3c,0x78,0x77,0x76,0xbd,0x6a,0xb1,0x6c,0x94,0x37,0x89, -0x13,0x24,0x2d,0xcf,0xc2,0x5e,0xc5,0x5c,0x36,0xfa,0x65,0x90,0x6f,0x60,0xba,0x74, -0x69,0x14,0x48,0x9e,0x05,0x41,0xf2,0x64,0xfc,0x03,0x00,0x00,0xff,0xff,0x03,0x00, -0xee,0x8e,0xf8,0x75,0xa1,0xaf,0x74,0x71,0x3f,0x40,0x08,0xab,0x13,0x7d,0xc0,0x82, -0x3a,0x56,0xeb,0x4e,0x35,0xf1,0x35,0xb7,0x68,0x65,0x6c,0x6c,0x6f,0x68,0x65,0x6c, -0x6c,0x6f,0x68,0x65,0x6c,0x6c,0x6f,0x0a -}; - -/* Verify that a file records with md5 hashing algorithm -#How to make -echo "hellohellohello" > f1 -chown $UNAME:$GNAME f1 -chmod 0644 f1 -env TZ=utc touch -afm -t 197001020000.01 f1 -xar --toc-cksum md5 -cf archive10.xar f1 -od -t x1 archive10.xar | sed -E -e 's/^0[0-9]+//;s/^ //;s/( )([0-9a-f]{2})/0x\2,/g;$ D' > archive10.xar.txt -*/ - -static unsigned char archive10[] = { -0x78,0x61,0x72,0x21,0x00,0x1c,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xaf, -0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x40,0x00,0x00,0x00,0x02,0x78,0xda,0x7c,0x53, -0x4d,0x6f,0xdc,0x20,0x10,0xbd,0xe7,0x57,0x20,0xee,0x0e,0x60,0xb3,0xb6,0x59,0xb1, -0x44,0xbd,0x44,0xbd,0x77,0x7b,0xe9,0x8d,0xe5,0xc3,0x8b,0xe2,0x2f,0x61,0x1c,0x6d, -0xf2,0xeb,0x8b,0xb1,0x9d,0xb4,0x4d,0x52,0xc9,0x92,0x1f,0x8f,0xc7,0x9b,0x61,0x86, -0xe1,0x0f,0xb7,0xae,0x05,0xcf,0xc6,0x4f,0x6e,0xe8,0x4f,0x90,0xdc,0x63,0x08,0x4c, -0xaf,0x06,0xed,0xfa,0xe6,0x04,0x7f,0x9e,0x1f,0xb3,0x1a,0x3e,0x88,0x3b,0x7e,0x93, -0x5e,0xdc,0x01,0x1e,0x06,0x15,0x7f,0x80,0x2b,0x6f,0x64,0x88,0x27,0xb2,0xe0,0x3a, -0x23,0x72,0x8c,0x59,0x46,0xf2,0x0c,0xd3,0x33,0x66,0xc7,0x02,0x1f,0x69,0xcd,0xd1, -0xdf,0x92,0x74,0xe8,0x6a,0xd4,0xd3,0x34,0x77,0x60,0x0a,0x2f,0xad,0x39,0xc1,0x4e, -0x1f,0xe0,0xb2,0x01,0xf8,0x60,0xed,0x64,0x82,0xc0,0x1c,0x6d,0x28,0xb1,0x93,0x7b, -0x35,0x82,0x94,0x1c,0x25,0xb0,0x38,0xa0,0xdd,0x22,0xad,0xac,0x6b,0x0d,0x70,0x3a, -0x66,0xbd,0xd9,0x68,0x19,0x64,0x42,0x80,0xb7,0xa6,0x6f,0xc2,0x55,0xe4,0x05,0x47, -0x1b,0x5c,0xf9,0xcd,0x7f,0x71,0xfd,0x23,0xd4,0x27,0xb1,0x22,0xb7,0xd7,0x61,0xcf, -0x57,0x8e,0x63,0xeb,0x54,0xba,0x14,0xba,0x65,0xcd,0xab,0x1b,0x21,0xda,0xa4,0xd2, -0xab,0xab,0x7b,0x36,0x3a,0xfb,0xf7,0x8e,0x3f,0xbe,0x7f,0x8b,0xd9,0xd9,0xba,0x28, -0x74,0x6e,0xb5,0x22,0xac,0xa0,0xac,0x90,0x17,0x5a,0x33,0xa9,0x65,0x5e,0xd8,0xda, -0x56,0x8c,0xd8,0x32,0xb7,0xaa,0x28,0x59,0xac,0xda,0x07,0xa3,0x3d,0x97,0x5b,0xf0, -0x52,0x85,0x2f,0x23,0x1c,0x74,0x45,0x2f,0xea,0xa2,0x2a,0xa6,0x0b,0xcb,0x2e,0x96, -0x4a,0x1b,0xbd,0x69,0x5d,0xd7,0xd8,0xd0,0x43,0x5e,0x1e,0xa8,0x35,0x58,0x31,0xc6, -0xd1,0x47,0xa7,0xb5,0x78,0xe8,0xad,0x7a,0x5c,0x7d,0xd1,0xd5,0xea,0x57,0xec,0xc0, -0xde,0x4e,0xc0,0xbb,0x04,0x09,0xab,0x70,0x86,0x49,0x86,0xf3,0x33,0xc6,0xc7,0xe5, -0x23,0x51,0xd6,0xbd,0xcb,0xe4,0x7f,0x64,0xf2,0x5d,0xd6,0xf8,0x61,0x1e,0x85,0x9a, -0x0d,0x47,0x2b,0x5c,0x59,0xa7,0x05,0xc1,0x98,0x44,0x32,0xa2,0x44,0xcd,0x93,0xf1, -0xab,0x2e,0xa1,0x95,0x7b,0x93,0xcd,0xbb,0xac,0x1b,0xb4,0x11,0xb8,0xa4,0x34,0x26, -0xb3,0xc0,0x44,0x86,0x97,0xd1,0x80,0xd6,0xf5,0x4f,0x27,0x38,0x78,0xd7,0xb8,0x5e, -0xb6,0x50,0x5c,0xa5,0xd7,0x0b,0xc7,0xd1,0xb2,0xbd,0x0a,0x7b,0x19,0xf3,0xb2,0xd1, -0x2f,0x81,0xf4,0xf6,0x96,0xe7,0xb6,0xcc,0x00,0x4a,0x43,0xc0,0x51,0x1a,0x89,0xdf, -0x00,0x00,0x00,0xff,0xff,0x03,0x00,0x27,0xf8,0xf5,0x28,0x87,0x01,0xb1,0xb7,0x18, -0xe8,0x34,0x20,0x06,0x5c,0x66,0x9a,0x43,0x26,0xe7,0x94,0x78,0xda,0xca,0x48,0xcd, -0xc9,0xc9,0xcf,0x80,0x13,0x5c,0x00,0x00,0x00,0x00,0xff,0xff,0x03,0x00,0x37,0xf7, -0x06,0x47 -}; - -/* Verify that a file records with no hashing algorithm -#How to make -echo "hellohellohello" > f1 -chown $UNAME:$GNAME f1 -chmod 0644 f1 -env TZ=utc touch -afm -t 197001020000.01 f1 -xar --toc-cksum none -cf archive11.xar f1 -od -t x1 archive11.xar | sed -E -e 's/^0[0-9]+//;s/^ //;s/( )([0-9a-f]{2})/0x\2,/g;$ D' > archive11.xar.txt -*/ - -static unsigned char archive11[] = { -0x78,0x61,0x72,0x21,0x00,0x1c,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x98, -0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xef,0x00,0x00,0x00,0x00,0x78,0xda,0x7c,0x52, -0xcb,0x6e,0xeb,0x20,0x14,0xdc,0xf7,0x2b,0x10,0x7b,0x17,0xb0,0x89,0x63,0x22,0x42, -0x75,0x37,0x55,0xf7,0xcd,0xdd,0x74,0x47,0x78,0x38,0xa8,0x7e,0xc9,0xc6,0x55,0xda, -0xaf,0xbf,0x3c,0xe2,0x56,0x55,0xd5,0x2b,0x21,0x79,0x3c,0xcc,0x39,0x67,0x74,0x18, -0xfe,0x70,0xed,0x3b,0xf0,0x66,0xe6,0xc5,0x8d,0xc3,0x11,0x92,0x7b,0x0c,0x81,0x19, -0xd4,0xa8,0xdd,0xd0,0x1e,0xe1,0xdf,0xd3,0x63,0xd1,0xc0,0x07,0x71,0xc7,0xaf,0x72, -0x16,0x77,0x80,0xfb,0x51,0x85,0x0f,0xe0,0x6a,0x36,0xd2,0x87,0x8a,0xc2,0xbb,0xde, -0x88,0x12,0x63,0x56,0x90,0xb2,0xc0,0xf4,0x44,0xf0,0x81,0x54,0x07,0x5a,0x73,0xf4, -0x5d,0x12,0x8b,0xac,0xeb,0x0c,0x70,0x3a,0x4c,0x81,0xf1,0x1f,0x70,0x2d,0xbd,0x4c, -0x08,0xf0,0xce,0x0c,0xad,0xbf,0x88,0xb2,0xe2,0xe8,0x06,0x33,0x3f,0x5a,0xbb,0x18, -0x2f,0x30,0x47,0x37,0x94,0xe9,0xc5,0x7d,0x18,0x41,0xc2,0x94,0x04,0x32,0xb7,0xd9, -0x06,0x8b,0x7f,0xef,0xcc,0x11,0xca,0x69,0xea,0x9c,0x4a,0x1e,0xd0,0xb5,0x68,0x3f, -0xdc,0x04,0xd1,0x4d,0x2a,0x67,0x75,0x71,0x6f,0x46,0x17,0xea,0x62,0xd4,0xeb,0xb2, -0xf6,0x5b,0xcd,0xf3,0xd3,0x9f,0x60,0xce,0x36,0x55,0xa5,0x4b,0xab,0x15,0x61,0x15, -0x65,0x95,0x3c,0xd3,0x86,0x49,0x2d,0xcb,0xca,0x36,0x76,0xcf,0x88,0xad,0x4b,0xab, -0xaa,0x9a,0x35,0x1c,0xfd,0x68,0xb4,0x79,0xb9,0xfa,0x59,0x2a,0xff,0xeb,0x84,0x9d, -0xde,0xd3,0xb3,0x3a,0xab,0x3d,0xd3,0x95,0x65,0x67,0x4b,0xa5,0x0d,0xbd,0x69,0xd3, -0x34,0xd8,0xd0,0x5d,0x59,0xef,0xa8,0x35,0x58,0x31,0xc6,0xd1,0xcf,0x4e,0x79,0x77, -0xe8,0x73,0x79,0x5c,0xfd,0xf2,0x08,0xe4,0x25,0xbc,0xc2,0xb6,0x7d,0xc0,0xfb,0x04, -0x09,0xdb,0xe3,0x02,0x93,0x02,0x97,0x27,0x8c,0x0f,0xf1,0x44,0x59,0xff,0x25,0x93, -0xff,0x91,0xc9,0x2f,0x59,0x3b,0x8f,0xeb,0x24,0xd4,0x6a,0x38,0xca,0x30,0xb3,0x4e, -0x0b,0x82,0x31,0x09,0x64,0x40,0x89,0x5a,0x17,0x33,0x67,0x5d,0x42,0x99,0xfb,0x94, -0xad,0x9b,0xac,0x1f,0xb5,0x11,0xb8,0xa6,0x34,0x98,0x89,0x30,0x91,0xfe,0x7d,0x32, -0xa0,0x73,0xc3,0xeb,0x11,0x8e,0xb3,0x6b,0xdd,0x20,0x3b,0x28,0x2e,0x72,0xd6,0x91, -0xe3,0x28,0x5e,0x67,0xe1,0x20,0x83,0x2f,0x1b,0xfa,0x25,0x10,0xc3,0x86,0x62,0xda, -0x62,0x64,0x51,0xca,0x2c,0x47,0x29,0xc1,0xff,0x00,0x00,0x00,0xff,0xff,0x03,0x00, -0xf1,0x18,0xdc,0x71,0x78,0xda,0xca,0x48,0xcd,0xc9,0xc9,0xcf,0x80,0x13,0x5c,0x00, -0x00,0x00,0x00,0xff,0xff,0x03,0x00,0x37,0xf7,0x06,0x47 -}; - -/* Verify that a file which is missing timestamp information -has the corresponding timestamps unset. -#How to make e.g. - struct archive *a = archive_write_new(); - archive_write_set_format_xar(a); - archive_write_add_filter_none(a); - size_t used, buffsize = 1500; - char *buff = (char*) malloc(buffsize); - archive_write_open_memory(a, buff, buffsize, &used); - - struct archive_entry *ae = archive_entry_new(); - archive_entry_copy_pathname(ae, "file"); - archive_entry_set_size(ae, 8); - archive_write_header(a, ae); - archive_entry_free(ae); - archive_write_data(a, "12345678", 9); - archive_write_free(a); - - std::cout << std::string(buff, used); - free(buff); - -$./a.out > f12.xar -Verify toc has no mtime/atime sections -$ xar --dump-toc=- -f f12.xar -Dump contents -$ ./a.out | od -t x1 | sed -E -e 's/^0[0-9]+//;s/^ //;s/( )([0-9a-f]{2})/0x\2,/g;$ D' -*/ - -static unsigned char archive12[] = { -0x78,0x61,0x72,0x21,0x00,0x1c,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xd1, -0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x56,0x00,0x00,0x00,0x01,0x78,0x9c,0x55,0x90, -0x41,0x8e,0xc2,0x30,0x0c,0x45,0xf7,0x9c,0x22,0xca,0xbe,0x38,0x2d,0x2c,0x10,0x72, -0xdb,0xdd,0x9c,0x00,0x0e,0x50,0xb5,0x6e,0x89,0x68,0x12,0xd4,0x84,0x11,0x70,0x7a, -0x62,0x17,0x46,0x9a,0x28,0x92,0xbf,0x5f,0xec,0xef,0xc8,0xd8,0x3e,0xdc,0xac,0x7e, -0x69,0x89,0x36,0xf8,0x5a,0x97,0x5b,0xa3,0x15,0xf9,0x3e,0x0c,0xd6,0x4f,0xb5,0x3e, -0x9f,0x7e,0x8a,0x83,0x6e,0x9b,0x0d,0x3e,0xba,0xa5,0xd9,0x28,0x4c,0xa1,0xcf,0x41, -0x61,0xbf,0x50,0x97,0x72,0x47,0x91,0xac,0xa3,0xa6,0x32,0xe5,0xa1,0x28,0x4d,0x61, -0xaa,0x53,0x65,0x8e,0xf9,0xee,0x77,0x08,0xff,0x4b,0xa4,0xe9,0x42,0xfd,0x35,0xde, -0x9d,0x8a,0xe9,0x39,0x53,0xad,0xe3,0xa5,0x2b,0x35,0xbf,0x28,0x0c,0xe3,0x18,0x29, -0x35,0x06,0xe1,0xa3,0x84,0x46,0xfb,0x62,0x73,0x04,0x11,0x6c,0x01,0x5f,0x0f,0xc9, -0x46,0x3b,0x93,0xb2,0x43,0xfe,0xf6,0xc7,0xc6,0x77,0x79,0x14,0x53,0x04,0x91,0x02, -0xd3,0xf3,0xf6,0x85,0x22,0x05,0x5a,0x1f,0x06,0xe2,0x79,0xab,0x10,0xe6,0x04,0xe5, -0x83,0xe0,0xfe,0xe0,0xdd,0x0e,0x5c,0xc6,0x41,0xf2,0x69,0xcd,0xa7,0x35,0x47,0x60, -0x63,0xde,0x0c,0xc8,0x6a,0x10,0x64,0x51,0x6f,0x2a,0x6b,0x63,0x9a,0x01,0x79,0x57, -0x93,0xd4,0x55,0xd4,0x06,0x1c,0x76,0x99,0x10,0x31,0x87,0x52,0x2b,0x16,0xff,0x5b, -0x36,0x78,0x9c,0x55,0x90,0x41,0x8e,0xc2,0x30,0x0c,0x45,0xf7,0x9c,0x22,0xca,0xbe, -0x38,0x2d,0x2c,0x10,0x72 -}; - -static void verify12(struct archive *a, struct archive_entry *ae) -{ - (void)a; /* UNUSED */ - assertEqualInt(archive_entry_mtime_is_set(ae), 0); - assertEqualInt(archive_entry_atime_is_set(ae), 0); - assertEqualInt(archive_entry_mtime(ae), 0); - assertEqualInt(archive_entry_atime(ae), 0); -} - - -/* -#How to make -echo "onetwothree" > f1 -echo "fourfivesize" > f2 -xar -cf archive13.xar f1 f2 -od -t x1 archive13.xar | sed -E -e 's/^0[0-9]+//' | sed -E -e 's/^ //' | sed -E -e 's/( )([0-9a-f]{2})/0x\2,/g;$ D' -*/ - -static unsigned char archive13[] = { -0x78,0x61,0x72,0x21,0x00,0x1c,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x31, -0x00,0x00,0x00,0x00,0x00,0x00,0x06,0xaa,0x00,0x00,0x00,0x01,0x78,0xda,0xcc,0x95, -0xcb,0x8e,0x9b,0x30,0x14,0x86,0xf7,0x79,0x0a,0xc4,0x9e,0xe2,0x0b,0xbe,0x10,0x39, -0xcc,0xae,0x4f,0x30,0xdd,0x74,0x67,0xec,0x43,0x82,0x86,0x4b,0x04,0x24,0xcd,0xcc, -0xd3,0xd7,0x36,0x30,0x69,0x34,0xd3,0x51,0xda,0x4a,0xa3,0x8a,0x05,0xbf,0x8f,0x7f, -0x9f,0xe3,0x63,0x3e,0x64,0xf5,0x70,0x69,0x9b,0xe8,0x0c,0xc3,0x58,0xf7,0xdd,0x2e, -0xc6,0x5f,0x50,0x1c,0x41,0x67,0x7a,0x5b,0x77,0xfb,0x5d,0xfc,0xed,0xf1,0x6b,0x22, -0xe3,0x87,0x62,0xa3,0x2e,0x7a,0x28,0x36,0x91,0x9a,0x7a,0xe3,0x5e,0x91,0x32,0x03, -0xe8,0xc9,0xad,0x48,0xa6,0xba,0x85,0x82,0x20,0x2c,0x13,0x44,0x12,0xc2,0x1f,0x71, -0xbe,0xc5,0x68,0x4b,0xf3,0xef,0x2a,0xbd,0xf5,0x84,0x55,0x07,0x30,0x4f,0xe3,0xa9, -0x8d,0xc6,0xe9,0xb9,0x81,0x5d,0x3c,0x1e,0x34,0x8e,0xfd,0x4c,0xa4,0xfa,0xaa,0x1a, -0x61,0x2a,0x90,0x4a,0x17,0x15,0xa2,0x63,0xfd,0xe2,0xb3,0xab,0x34,0x08,0x9f,0x22, -0x5d,0x73,0x84,0x51,0x55,0x37,0x10,0xd5,0x76,0x17,0x93,0x25,0x8d,0xd5,0x93,0x0e, -0x2a,0x52,0x0d,0x74,0xfb,0xe9,0x10,0x56,0x2f,0x72,0x8e,0x2f,0xf9,0xb3,0xdb,0x52, -0x4b,0x2d,0x4c,0xae,0xb5,0x5c,0x6c,0x3d,0x89,0x75,0xc3,0xfa,0x78,0x6c,0x6a,0x13, -0xba,0x4a,0x2f,0xc9,0xfe,0xa5,0x3e,0xc6,0xe9,0x62,0xd5,0x83,0x39,0xd4,0x67,0xb0, -0xc9,0xfb,0x4d,0x66,0x92,0x96,0x58,0x70,0x4e,0x09,0xa3,0x02,0x73,0x28,0x05,0xa9, -0x20,0xe7,0xb9,0x34,0x98,0x94,0x0c,0x33,0x8c,0xa4,0xd5,0x22,0xd3,0x2a,0x7d,0x93, -0x68,0xdd,0xcb,0x65,0x1a,0xb4,0x99,0x7e,0x5b,0x81,0xcb,0x9c,0xba,0x22,0x3a,0x93, -0x40,0xb8,0x70,0x0f,0xd7,0x39,0x42,0x34,0x77,0xe9,0x89,0x28,0x2d,0xe7,0x6e,0x20, -0xb4,0xc1,0x2a,0x7d,0x9b,0x69,0x3e,0xbc,0xf4,0xf5,0xf4,0x7c,0x31,0xf2,0x0b,0x15, -0x8c,0x0b,0x21,0x08,0x47,0xd9,0xd2,0xae,0xd2,0xa6,0x59,0xfb,0x36,0x06,0xc6,0xb1, -0x38,0x8d,0x30,0x6c,0xb7,0xc3,0x8f,0x64,0xb3,0x1f,0xfa,0xd3,0xd1,0xc9,0x24,0xd9, -0xf4,0xd3,0x21,0x44,0x9d,0x74,0x7d,0xcd,0xc6,0xb9,0xd2,0xba,0x5e,0x99,0x77,0x00, -0x42,0x72,0x8b,0x99,0x07,0x68,0x05,0x27,0x52,0xed,0x07,0xb6,0xf6,0x6a,0xd3,0x1f, -0xd8,0xf4,0xd5,0xb6,0xaf,0x6d,0x81,0x11,0x72,0x04,0x78,0x15,0x42,0x7e,0xff,0x85, -0xee,0x26,0x78,0x52,0x69,0xd0,0x73,0xf4,0xd5,0x78,0x5a,0x8d,0x6d,0x6f,0xa1,0x40, -0x3c,0xcb,0x5c,0x61,0x2f,0x67,0xec,0xe0,0x5c,0x1b,0xe8,0x7a,0x57,0x9a,0x51,0x77, -0x8e,0xeb,0x30,0x4c,0xd6,0x9d,0xf7,0xe5,0x88,0xe5,0xc2,0xc3,0x38,0x0f,0xc3,0xcc, -0xf4,0x7c,0x84,0xc2,0x33,0xac,0xd2,0x20,0x43,0xb0,0xd3,0x6e,0x9b,0x95,0xe3,0x30, -0x88,0xc0,0xbc,0xb7,0xdc,0xf2,0x8e,0xff,0x98,0x77,0xf2,0xc9,0xbc,0x3b,0x98,0x31, -0x94,0x3c,0x67,0x8e,0xfb,0x8c,0x49,0xc0,0xd2,0x20,0xcc,0x40,0x0b,0x69,0x08,0x35, -0xbc,0x92,0xc2,0x7d,0x25,0x66,0xff,0x9e,0x77,0x60,0x19,0xa6,0xd6,0xd2,0x4c,0xd3, -0x8a,0x72,0x6b,0x44,0x25,0x01,0xa8,0x75,0xbf,0x81,0x81,0x32,0xd3,0xbc,0xd2,0xa2, -0xc4,0xc4,0xfe,0x13,0xef,0xf4,0xd3,0x78,0x47,0xf7,0xf1,0x8e,0xee,0xe3,0x1d,0xfd, -0x27,0xbc,0xe3,0xfc,0x5e,0xde,0xf1,0x3b,0xbc,0x3b,0x97,0xbf,0x6e,0x54,0x1a,0x2e, -0x9f,0x9f,0x00,0x00,0x00,0xff,0xff,0x03,0x00,0xe5,0xbe,0xed,0xcc,0x2a,0x10,0x73, -0x9e,0x84,0x13,0x2e,0x27,0xe1,0x8d,0x6f,0xf8,0x9e,0xae,0xd0,0x0a,0x8f,0x2a,0xca, -0xf7,0x78,0xda,0xcb,0xcf,0x4b,0x2d,0x29,0xcf,0x2f,0xc9,0x28,0x4a,0x4d,0xe5,0x02, -0x00,0x21,0x4c,0x04,0xbf,0x78,0xda,0x4b,0xcb,0x2f,0x2d,0x4a,0xcb,0x2c,0x4b,0x2d, -0xce,0xac,0xe0,0x02,0x00,0x20,0xfa,0x04,0xc5 -}; - -enum enc { - GZIP, - BZIP2 -}; - -static void verify(unsigned char *d, size_t s, - void (*f1)(struct archive *, struct archive_entry *), - void (*f2)(struct archive *, struct archive_entry *), - enum enc etype) -{ - struct archive_entry *ae; - struct archive *a; - unsigned char *buff; - int r; - - assert((a = archive_read_new()) != NULL); - switch (etype) { - case BZIP2: - /* This is only check whether bzip is supported or not. - * This filter won't be used this test. */ - if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) { - skipping("Unsupported bzip2"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - break; - case GZIP: - /* This gzip must be needed. archive_read_support_format_xar() - * will return a warning if gzip is unsupported. */ - break; - } - assertA(0 == archive_read_support_filter_all(a)); - r = archive_read_support_format_xar(a); - if (r == ARCHIVE_WARN) { - skipping("xar reading not fully supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - assert((buff = malloc(100000)) != NULL); - if (buff == NULL) - return; - memcpy(buff, d, s); - memset(buff + s, 0, 2048); - - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_open_memory(a, buff, s + 1024)); - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_NONE); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_XAR); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); - /* Verify the only entry. */ - f1(a, ae); - if (f2) { - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_NONE); - assertEqualInt(archive_format(a), ARCHIVE_FORMAT_XAR); - /* Verify the only entry. */ - f2(a, ae); - assertEqualInt(2, archive_file_count(a)); - } else { - assertEqualInt(1, archive_file_count(a)); - } - /* End of archive. */ - assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - free(buff); -} - -static void verifyB(unsigned char *d, size_t s) { - struct archive* a; - struct archive_entry *entry = NULL; - size_t buf_size; - unsigned char *buf; - - assert((a = archive_read_new()) != NULL); - - if(ARCHIVE_OK != archive_read_support_filter_gzip(a)) { - skipping("Unsupported gzip"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - - if(ARCHIVE_OK != archive_read_support_filter_bzip2(a)) { - skipping("Unsupported bzip2"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - - if(ARCHIVE_OK != archive_read_support_format_xar(a)) { - skipping("Unsupported xar"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - - assertA(0 == archive_read_open_memory(a, d, s)); - - // f1, content "onetwothree\n", size 12 bytes - assertA(0 == archive_read_next_header(a, &entry)); - buf_size = (size_t) archive_entry_size(entry); - assertA(buf_size == 12); - buf = (unsigned char*) malloc(buf_size); - assertA(NULL != buf); - assertA(buf_size == (size_t) archive_read_data(a, buf, buf_size)); - free(buf); - - // f2, content "fourfivesix\n", size 12 bytes - assertA(0 == archive_read_next_header(a, &entry)); - buf_size = (size_t) archive_entry_size(entry); - assertA(buf_size == 12); - buf = (unsigned char*) malloc(buf_size); - assertA(NULL != buf); - assertA(buf_size == (size_t) archive_read_data(a, buf, buf_size)); - free(buf); - - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_xar) -{ - verify(archive1, sizeof(archive1), verify0, verify1, GZIP); - verify(archive2, sizeof(archive2), verify0, verify2, GZIP); - verify(archive3, sizeof(archive3), verify3, NULL, GZIP); - verify(archive4, sizeof(archive4), verify4, NULL, GZIP); - verify(archive5, sizeof(archive5), verify5, NULL, GZIP); - verify(archive6, sizeof(archive6), verify6, NULL, GZIP); - verify(archive7, sizeof(archive7), verify7, NULL, GZIP); - verify(archive8, sizeof(archive8), verify0, NULL, BZIP2); - verify(archive9, sizeof(archive9), verify0, NULL, GZIP); - verify(archive10, sizeof(archive10), verify0, NULL, GZIP); - verify(archive11, sizeof(archive11), verify0, NULL, GZIP); - verify(archive12, sizeof(archive12), verify12, NULL, GZIP); - verifyB(archive13, sizeof(archive13)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip.c b/thirdparty/libarchive/libarchive/test/test_read_format_zip.c deleted file mode 100644 index 680964143..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip.c +++ /dev/null @@ -1,1175 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2011 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_zip.c 189482 2009-03-07 03:30:35Z kientzle $"); - -#define __LIBARCHIVE_BUILD -#include - -static -int extract_one(struct archive* a, struct archive_entry* ae, uint32_t crc) -{ - la_ssize_t fsize, bytes_read; - uint8_t* buf; - int ret = 1; - uint32_t computed_crc; - - fsize = (la_ssize_t) archive_entry_size(ae); - buf = malloc(fsize); - if(buf == NULL) - return 1; - - bytes_read = archive_read_data(a, buf, fsize); - if(bytes_read != fsize) { - assertEqualInt(bytes_read, fsize); - goto fn_exit; - } - - computed_crc = crc32(0, buf, fsize); - assertEqualInt(computed_crc, crc); - ret = 0; - -fn_exit: - free(buf); - return ret; -} - -static -int extract_one_using_blocks(struct archive* a, int block_size, uint32_t crc) -{ - uint8_t* buf; - int ret = 1; - uint32_t computed_crc = 0; - la_ssize_t bytes_read; - - buf = malloc(block_size); - if(buf == NULL) - return 1; - - while(1) { - bytes_read = archive_read_data(a, buf, block_size); - if(bytes_read == ARCHIVE_RETRY) - continue; - else if(bytes_read == 0) - break; - else if(bytes_read < 0) { - /* If we're here, it means the decompressor has failed - * to properly decode test file. */ - assertA(0); - ret = 1; - goto fn_exit; - } else { - /* ok */ - } - - computed_crc = crc32(computed_crc, buf, bytes_read); - } - - assertEqualInt(computed_crc, crc); - ret = 0; - -fn_exit: - free(buf); - return ret; -} - -/* - * The reference file for this has been manually tweaked so that: - * * file2 has length-at-end but file1 does not - * * file2 has an invalid CRC - */ -static void -verify_basic(struct archive *a, int seek_checks) -{ - struct archive_entry *ae; - char *buff[128]; - const void *pv; - size_t s; - int64_t o; - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 1.0 (uncompressed)", archive_format_name(a)); - assertEqualString("dir/", archive_entry_pathname(ae)); - assertEqualInt(1179604249, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - if (seek_checks) - assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualIntA(a, ARCHIVE_EOF, - archive_read_data_block(a, &pv, &s, &o)); - assertEqualInt((int)s, 0); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 2.0 (deflation)", archive_format_name(a)); - assertEqualString("file1", archive_entry_pathname(ae)); - assertEqualInt(1179604289, archive_entry_mtime(ae)); - if (seek_checks) - assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); - assertEqualInt(18, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - failure("archive_read_data() returns number of bytes read"); - if (archive_zlib_version() != NULL) { - assertEqualInt(18, archive_read_data(a, buff, 19)); - assertEqualMem(buff, "hello\nhello\nhello\n", 18); - } else { - assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, 19)); - assertEqualString(archive_error_string(a), - "Unsupported ZIP compression method (8: deflation)"); - assert(archive_errno(a) != 0); - } - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 2.0 (deflation)", archive_format_name(a)); - assertEqualString("file2", archive_entry_pathname(ae)); - assertEqualInt(1179605932, archive_entry_mtime(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - if (seek_checks) { - assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); - } - assert(archive_entry_size_is_set(ae)); - assertEqualInt(18, archive_entry_size(ae)); - if (archive_zlib_version() != NULL) { - failure("file2 has a bad CRC, so read should fail and not change buff"); - memset(buff, 'a', 19); - assertEqualInt(ARCHIVE_WARN, archive_read_data(a, buff, 19)); - assertEqualMem(buff, "aaaaaaaaaaaaaaaaaaa", 19); - } else { - assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, 19)); - assertEqualString(archive_error_string(a), - "Unsupported ZIP compression method (8: deflation)"); - assert(archive_errno(a) != 0); - } - assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 2.0 (deflation)", archive_format_name(a)); - /* Verify the number of files read. */ - failure("the archive file has three files"); - assertEqualInt(3, archive_file_count(a)); - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -static void -test_basic(void) -{ - const char *refname = "test_read_format_zip.zip"; - struct archive *a; - char *p; - size_t s; - - extract_reference_file(refname); - - /* Verify with seeking reader. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); - verify_basic(a, 1); - - /* Verify with streaming reader. */ - p = slurpfile(&s, "%s", refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 31)); - verify_basic(a, 0); - free(p); -} - -/* - * Read Info-ZIP New Unix Extra Field 0x7875 "ux". - * Currently stores Unix UID/GID up to 32 bits. - */ -static void -verify_info_zip_ux(struct archive *a, int seek_checks) -{ - struct archive_entry *ae; - char *buff[128]; - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("file1", archive_entry_pathname(ae)); - assertEqualInt(1300668680, archive_entry_mtime(ae)); - assertEqualInt(18, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - if (seek_checks) - assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae)); - failure("zip reader should read Info-ZIP New Unix Extra Field"); - assertEqualInt(1001, archive_entry_uid(ae)); - assertEqualInt(1001, archive_entry_gid(ae)); - if (archive_zlib_version() != NULL) { - failure("archive_read_data() returns number of bytes read"); - assertEqualInt(18, archive_read_data(a, buff, 19)); - assertEqualMem(buff, "hello\nhello\nhello\n", 18); - } else { - assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, 19)); - assertEqualString(archive_error_string(a), - "Unsupported ZIP compression method (8: deflation)"); - assert(archive_errno(a) != 0); - } - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify the number of files read. */ - failure("the archive file has just one file"); - assertEqualInt(1, archive_file_count(a)); - - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -static void -test_info_zip_ux(void) -{ - const char *refname = "test_read_format_zip_ux.zip"; - struct archive *a; - char *p; - size_t s; - - extract_reference_file(refname); - - /* Verify with seeking reader. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); - verify_info_zip_ux(a, 1); - - /* Verify with streaming reader. */ - p = slurpfile(&s, "%s", refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 108)); - verify_info_zip_ux(a, 0); - free(p); -} - -/* - * Verify that test_read_extract correctly works with - * Zip entries that use length-at-end. - */ -static void -verify_extract_length_at_end(struct archive *a, int seek_checks) -{ - struct archive_entry *ae; - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - assertEqualString("hello.txt", archive_entry_pathname(ae)); - if (seek_checks) { - assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae)); - assert(archive_entry_size_is_set(ae)); - assertEqualInt(6, archive_entry_size(ae)); - } else { - assert(!archive_entry_size_is_set(ae)); - assertEqualInt(0, archive_entry_size(ae)); - } - - if (archive_zlib_version() != NULL) { - assertEqualIntA(a, ARCHIVE_OK, archive_read_extract(a, ae, 0)); - assertFileContents("hello\x0A", 6, "hello.txt"); - } else { - assertEqualIntA(a, ARCHIVE_FAILED, archive_read_extract(a, ae, 0)); - assertEqualString(archive_error_string(a), - "Unsupported ZIP compression method (8: deflation)"); - assert(archive_errno(a) != 0); - } - - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); -} - -static void -test_extract_length_at_end(void) -{ - const char *refname = "test_read_format_zip_length_at_end.zip"; - char *p; - size_t s; - struct archive *a; - - extract_reference_file(refname); - - /* Verify extraction with seeking reader. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); - verify_extract_length_at_end(a, 1); - - /* Verify extraction with streaming reader. */ - p = slurpfile(&s, "%s", refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 108)); - verify_extract_length_at_end(a, 0); - free(p); -} - -static void -test_symlink(void) -{ - const char *refname = "test_read_format_zip_symlink.zip"; - char *p; - size_t s; - struct archive *a; - struct archive_entry *ae; - - extract_reference_file(refname); - p = slurpfile(&s, "%s", refname); - - /* Symlinks can only be extracted with the seeking reader. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 1)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("file", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("symlink", archive_entry_pathname(ae)); - assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualString("file", archive_entry_symlink(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); - - free(p); -} - -DEFINE_TEST(test_read_format_zip) -{ - test_basic(); - test_info_zip_ux(); - test_extract_length_at_end(); - test_symlink(); -} - -DEFINE_TEST(test_read_format_zip_ppmd_one_file) -{ - const char *refname = "test_read_format_zip_ppmd8.zipx"; - struct archive *a; - struct archive_entry *ae; - - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 6.3 (ppmd-1)", archive_format_name(a)); - assertEqualString("vimrc", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one(a, ae, 0xBA8E3BAA)); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_ppmd_one_file_blockread) -{ - const char *refname = "test_read_format_zip_ppmd8.zipx"; - struct archive *a; - struct archive_entry *ae; - - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 6.3 (ppmd-1)", archive_format_name(a)); - assertEqualString("vimrc", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one_using_blocks(a, 13, 0xBA8E3BAA)); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_ppmd_multi) -{ - const char *refname = "test_read_format_zip_ppmd8_multi.zipx"; - struct archive *a; - struct archive_entry *ae; - - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 6.3 (ppmd-1)", archive_format_name(a)); - assertEqualString("smartd.conf", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one(a, ae, 0x8DD7379E)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 6.3 (ppmd-1)", archive_format_name(a)); - assertEqualString("ts.conf", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one(a, ae, 0x7AE59B31)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 6.3 (ppmd-1)", archive_format_name(a)); - assertEqualString("vimrc", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one(a, ae, 0xBA8E3BAA)); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_ppmd_multi_blockread) -{ - const char *refname = "test_read_format_zip_ppmd8_multi.zipx"; - struct archive *a; - struct archive_entry *ae; - - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 6.3 (ppmd-1)", archive_format_name(a)); - assertEqualString("smartd.conf", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one_using_blocks(a, 12, 0x8DD7379E)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 6.3 (ppmd-1)", archive_format_name(a)); - assertEqualString("ts.conf", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one_using_blocks(a, 13, 0x7AE59B31)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 6.3 (ppmd-1)", archive_format_name(a)); - assertEqualString("vimrc", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one_using_blocks(a, 14, 0xBA8E3BAA)); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_lzma_one_file) -{ - const char *refname = "test_read_format_zip_lzma.zipx"; - struct archive *a; - struct archive_entry *ae; - - assert((a = archive_read_new()) != NULL); - if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) { - skipping("lzma reading not fully supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - extract_reference_file(refname); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 6.3 (lzma)", archive_format_name(a)); - assertEqualString("vimrc", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one(a, ae, 0xBA8E3BAA)); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_lzma_one_file_blockread) -{ - const char *refname = "test_read_format_zip_lzma.zipx"; - struct archive *a; - struct archive_entry *ae; - - assert((a = archive_read_new()) != NULL); - if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) { - skipping("lzma reading not fully supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - extract_reference_file(refname); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 6.3 (lzma)", archive_format_name(a)); - assertEqualString("vimrc", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one_using_blocks(a, 13, 0xBA8E3BAA)); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_lzma_multi) -{ - const char *refname = "test_read_format_zip_lzma_multi.zipx"; - struct archive *a; - struct archive_entry *ae; - - assert((a = archive_read_new()) != NULL); - if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) { - skipping("lzma reading not fully supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - extract_reference_file(refname); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 6.3 (lzma)", archive_format_name(a)); - assertEqualString("smartd.conf", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one(a, ae, 0x8DD7379E)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 6.3 (lzma)", archive_format_name(a)); - assertEqualString("ts.conf", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one(a, ae, 0x7AE59B31)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 6.3 (lzma)", archive_format_name(a)); - assertEqualString("vimrc", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one(a, ae, 0xBA8E3BAA)); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_lzma_multi_blockread) -{ - const char *refname = "test_read_format_zip_lzma_multi.zipx"; - struct archive *a; - struct archive_entry *ae; - - assert((a = archive_read_new()) != NULL); - if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) { - skipping("lzma reading not fully supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - extract_reference_file(refname); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 6.3 (lzma)", archive_format_name(a)); - assertEqualString("smartd.conf", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one_using_blocks(a, 12, 0x8DD7379E)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 6.3 (lzma)", archive_format_name(a)); - assertEqualString("ts.conf", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one_using_blocks(a, 13, 0x7AE59B31)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 6.3 (lzma)", archive_format_name(a)); - assertEqualString("vimrc", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one_using_blocks(a, 14, 0xBA8E3BAA)); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); -} - - -DEFINE_TEST(test_read_format_zip_bzip2_one_file) -{ - const char *refname = "test_read_format_zip_bzip2.zipx"; - struct archive *a; - struct archive_entry *ae; - - assert((a = archive_read_new()) != NULL); - if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) { - skipping("bzip2 is not fully supported on this platform"); - archive_read_close(a); - return; - } - extract_reference_file(refname); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 4.6 (bzip)", archive_format_name(a)); - assertEqualString("vimrc", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one(a, ae, 0xBA8E3BAA)); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_bzip2_one_file_blockread) -{ - const char *refname = "test_read_format_zip_bzip2.zipx"; - struct archive *a; - struct archive_entry *ae; - - assert((a = archive_read_new()) != NULL); - if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) { - skipping("bzip2 is not fully supported on this platform"); - archive_read_close(a); - return; - } - extract_reference_file(refname); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 4.6 (bzip)", archive_format_name(a)); - assertEqualString("vimrc", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one_using_blocks(a, 13, 0xBA8E3BAA)); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_bzip2_multi) -{ - const char *refname = "test_read_format_zip_bzip2_multi.zipx"; - struct archive *a; - struct archive_entry *ae; - - assert((a = archive_read_new()) != NULL); - if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) { - skipping("bzip2 is not fully supported on this platform"); - archive_read_close(a); - return; - } - extract_reference_file(refname); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 4.6 (bzip)", archive_format_name(a)); - assertEqualString("smartd.conf", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one(a, ae, 0x8DD7379E)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 4.6 (bzip)", archive_format_name(a)); - assertEqualString("ts.conf", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one(a, ae, 0x7AE59B31)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 4.6 (bzip)", archive_format_name(a)); - assertEqualString("vimrc", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one(a, ae, 0xBA8E3BAA)); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_bzip2_multi_blockread) -{ - const char *refname = "test_read_format_zip_bzip2_multi.zipx"; - struct archive *a; - struct archive_entry *ae; - - assert((a = archive_read_new()) != NULL); - if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) { - skipping("bzip2 is not fully supported on this platform"); - archive_read_close(a); - return; - } - extract_reference_file(refname); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 4.6 (bzip)", archive_format_name(a)); - assertEqualString("smartd.conf", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one_using_blocks(a, 12, 0x8DD7379E)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 4.6 (bzip)", archive_format_name(a)); - assertEqualString("ts.conf", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one_using_blocks(a, 13, 0x7AE59B31)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 4.6 (bzip)", archive_format_name(a)); - assertEqualString("vimrc", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one_using_blocks(a, 14, 0xBA8E3BAA)); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_zstd_one_file) -{ - const char *refname = "test_read_format_zip_zstd.zipx"; - struct archive *a; - struct archive_entry *ae; - - assert((a = archive_read_new()) != NULL); - if (ARCHIVE_OK != archive_read_support_filter_zstd(a)) { - skipping("zstd is not fully supported on this platform"); - archive_read_close(a); - archive_read_free(a); - return; - } - extract_reference_file(refname); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 2.0 (zstd)", archive_format_name(a)); - assertEqualString("vimrc", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one(a, ae, 0xBA8E3BAA)); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_zstd_one_file_blockread) -{ - const char *refname = "test_read_format_zip_zstd.zipx"; - struct archive *a; - struct archive_entry *ae; - - assert((a = archive_read_new()) != NULL); - if (ARCHIVE_OK != archive_read_support_filter_zstd(a)) { - skipping("zstd is not fully supported on this platform"); - archive_read_close(a); - archive_read_free(a); - return; - } - extract_reference_file(refname); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 2.0 (zstd)", archive_format_name(a)); - assertEqualString("vimrc", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one_using_blocks(a, 13, 0xBA8E3BAA)); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_zstd_multi) -{ - const char *refname = "test_read_format_zip_zstd_multi.zipx"; - struct archive *a; - struct archive_entry *ae; - - assert((a = archive_read_new()) != NULL); - if (ARCHIVE_OK != archive_read_support_filter_zstd(a)) { - skipping("zstd is not fully supported on this platform"); - archive_read_close(a); - archive_read_free(a); - return; - } - extract_reference_file(refname); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 2.0 (zstd)", archive_format_name(a)); - assertEqualString("smartd.conf", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one(a, ae, 0x8DD7379E)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 2.0 (zstd)", archive_format_name(a)); - assertEqualString("ts.conf", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one(a, ae, 0x7AE59B31)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 2.0 (zstd)", archive_format_name(a)); - assertEqualString("vimrc", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one(a, ae, 0xBA8E3BAA)); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_zstd_multi_blockread) -{ - const char *refname = "test_read_format_zip_zstd_multi.zipx"; - struct archive *a; - struct archive_entry *ae; - - assert((a = archive_read_new()) != NULL); - if (ARCHIVE_OK != archive_read_support_filter_zstd(a)) { - skipping("zstd is not fully supported on this platform"); - archive_read_close(a); - archive_read_free(a); - return; - } - extract_reference_file(refname); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 2.0 (zstd)", archive_format_name(a)); - assertEqualString("smartd.conf", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one_using_blocks(a, 12, 0x8DD7379E)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 2.0 (zstd)", archive_format_name(a)); - assertEqualString("ts.conf", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one_using_blocks(a, 13, 0x7AE59B31)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 2.0 (zstd)", archive_format_name(a)); - assertEqualString("vimrc", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one_using_blocks(a, 14, 0xBA8E3BAA)); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_xz_multi) -{ - const char *refname = "test_read_format_zip_xz_multi.zipx"; - struct archive *a; - struct archive_entry *ae; - - assert((a = archive_read_new()) != NULL); - if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) { - skipping("lzma reading not fully supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - extract_reference_file(refname); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 2.0 (xz)", archive_format_name(a)); - assertEqualString("bash.bashrc", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one(a, ae, 0xF751B8C9)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 2.0 (xz)", archive_format_name(a)); - assertEqualString("pacman.conf", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one(a, ae, 0xB20B7F88)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 2.0 (xz)", archive_format_name(a)); - assertEqualString("profile", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one(a, ae, 0x2329F054)); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_xz_multi_blockread) -{ - const char *refname = "test_read_format_zip_xz_multi.zipx"; - struct archive *a; - struct archive_entry *ae; - - assert((a = archive_read_new()) != NULL); - if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) { - skipping("lzma reading not fully supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - extract_reference_file(refname); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 2.0 (xz)", archive_format_name(a)); - assertEqualString("bash.bashrc", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one_using_blocks(a, 12, 0xF751B8C9)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 2.0 (xz)", archive_format_name(a)); - assertEqualString("pacman.conf", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one_using_blocks(a, 13, 0xB20B7F88)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 2.0 (xz)", archive_format_name(a)); - assertEqualString("profile", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one_using_blocks(a, 14, 0x2329F054)); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_ppmd8_crash_1) -{ - const char *refname = "test_read_format_zip_ppmd8_crash_2.zipx"; - struct archive *a; - struct archive_entry *ae; - char buf[64]; - - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 100)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - - /* This file shouldn't be properly decompressed, because it's invalid. - * However, unpacker should return an error during unpacking. Without the - * proper fix, the unpacker was entering an unlimited loop. */ - assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data(a, buf, 1)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_bz2_hang_on_invalid) -{ - const char *refname = "test_read_format_zip_bz2_hang.zip"; - struct archive *a; - struct archive_entry *ae; - char buf[8]; - - assert((a = archive_read_new()) != NULL); - if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) { - skipping("bzip2 is not fully supported on this platform"); - archive_read_close(a); - return; - } - extract_reference_file(refname); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - - /* The file `refname` is invalid in this case, so this call should fail. - * But it shouldn't crash. */ - assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data(a, buf, 64)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_ppmd8_crash_2) -{ - const char *refname = "test_read_format_zip_ppmd8_crash_2.zipx"; - struct archive *a; - struct archive_entry *ae; - char buf[64]; - - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - - /* The file `refname` is invalid in this case, so this call should fail. - * But it shouldn't crash. */ - assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data(a, buf, 64)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_lzma_alone_leak) -{ - const char *refname = "test_read_format_zip_lzma_alone_leak.zipx"; - struct archive *a; - struct archive_entry *ae; - char buf[64]; - - /* OSSFuzz #14470 sample file. */ - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - if(ARCHIVE_OK != archive_read_support_filter_lzma(a)) { - skipping("lzma reading is not fully supported on this platform"); - archive_read_close(a); - archive_read_free(a); - return; - } - - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - - /* Extraction of this file should fail, because the sample file is invalid. - * But it shouldn't crash. */ - assertEqualIntA(a, ARCHIVE_FAILED, archive_read_data(a, buf, sizeof(buf))); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - - /* Extraction of this file should fail, because the sample file is invalid. - * But it shouldn't crash. */ - assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data(a, buf, sizeof(buf))); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); - - /* This testcase shouldn't produce any memory leaks. When running test - * suite under Valgrind or ASan, the test runner won't return with - * exit code 0 in case if a memory leak. */ -} - -DEFINE_TEST(test_read_format_zip_lzma_stream_end) -{ - const char *refname = "test_read_format_zip_lzma_stream_end.zipx"; - struct archive *a; - struct archive_entry *ae; - - assert((a = archive_read_new()) != NULL); - if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) { - skipping("lzma reading not fully supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - extract_reference_file(refname); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 6.3 (lzma)", archive_format_name(a)); - assertEqualString("vimrc", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one(a, ae, 0xBA8E3BAA)); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_lzma_stream_end_blockread) -{ - const char *refname = "test_read_format_zip_lzma_stream_end.zipx"; - struct archive *a; - struct archive_entry *ae; - - assert((a = archive_read_new()) != NULL); - if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) { - skipping("lzma reading not fully supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - extract_reference_file(refname); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ZIP 6.3 (lzma)", archive_format_name(a)); - assertEqualString("vimrc", archive_entry_pathname(ae)); - assertEqualIntA(a, 0, extract_one_using_blocks(a, 13, 0xBA8E3BAA)); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_7z_lzma) -{ - const char *refname = "test_read_format_zip_7z_lzma.zip"; - struct archive_entry *ae; - struct archive *a; - - assert((a = archive_read_new()) != NULL); - if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) { - skipping("lzma reading not fully supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - extract_reference_file(refname); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - //read directories - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - //read symlink - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); - assertEqualString("../samples/abc_measurement_analysis_sample" - "/src/abc_measurement_analysis_sample.py", - archive_entry_symlink(ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_7z_deflate) -{ - const char *refname = "test_read_format_zip_7z_deflate.zip"; - struct archive_entry *ae; - struct archive *a; - int r; - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - extract_reference_file(refname); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - //read first symlink - r = archive_read_next_header(a, &ae); - if (archive_zlib_version() == NULL) { - assertEqualInt(ARCHIVE_FAILED, r); - assertEqualString(archive_error_string(a), - "Unsupported ZIP compression method during decompression " - "of link entry (8: deflation)"); - assert(archive_errno(a) != 0); - } else { - assertEqualIntA(a, ARCHIVE_OK, r); - assertEqualString("libxkbcommon-x11.so.0.0.0", - archive_entry_symlink(ae)); - } - assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); - //read second symlink - r = archive_read_next_header(a, &ae); - if (archive_zlib_version() == NULL) { - assertEqualInt(ARCHIVE_FAILED, r); - assertEqualString(archive_error_string(a), - "Unsupported ZIP compression method during decompression " - "of link entry (8: deflation)"); - assert(archive_errno(a) != 0); - } else { - assertEqualIntA(a, ARCHIVE_OK, r); - assertEqualString("libxkbcommon-x11.so.0.0.0", - archive_entry_symlink(ae)); - } - assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip.zip.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip.zip.uu deleted file mode 100644 index 4fb534833..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip.zip.uu +++ /dev/null @@ -1,13 +0,0 @@ -begin 644 test_read_format_zip.zip -M4$L#!`H`"````%EFLS8````````````````$`!4`9&ER+U54"0`#&55/1M19 -M_4A5>`0`Z`/H`U!+!P@```````````````!02P,$%`````@`;V:S-CHW9CT* -M````$@````4`%0!F:6QE,554"0`#055/1L!9_4A5>`0`Z`/H`\M(S`0`Z`/H`\M(S```4$L!`A<#%``(``@`;V:S-CHW9CT*````$@````4`#0`` -M`````0```.V!1P```&9I;&4Q550%``-!54]&57@``%!+`0(7`Q0`"``(`%IJ -MLS9X>'AX"@```!(````%``T```````$```#M@8D```!F:6QE,E54!0`#K%M/ -;1E5X``!02P4&``````,``P"_````VP`````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_7075_utf8_paths.c b/thirdparty/libarchive/libarchive/test/test_read_format_zip_7075_utf8_paths.c deleted file mode 100644 index a0a510c8f..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_7075_utf8_paths.c +++ /dev/null @@ -1,102 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2011 Michihiro NAKAJIMA - * Copyright (c) 2019 Mike Frysinger - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -#include - -static void -verify(struct archive *a) { - struct archive_entry *ae; - const char *p; - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assert((p = archive_entry_pathname_utf8(ae)) != NULL); - assertEqualUTF8String(p, "File 1.txt"); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assert((p = archive_entry_pathname_utf8(ae)) != NULL); -#if defined(__APPLE__) - /* Compare NFD string. */ - assertEqualUTF8String(p, "File 2 - o\xCC\x88.txt"); -#else - /* Compare NFC string. */ - assertEqualUTF8String(p, "File 2 - \xC3\xB6.txt"); -#endif - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assert((p = archive_entry_pathname_utf8(ae)) != NULL); -#if defined(__APPLE__) - /* Compare NFD string. */ - assertEqualUTF8String(p, "File 3 - a\xCC\x88.txt"); -#else - /* Compare NFC string. */ - assertEqualUTF8String(p, "File 3 - \xC3\xA4.txt"); -#endif - - /* The CRC of the filename fails, so fall back to CDE. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assert((p = archive_entry_pathname_utf8(ae)) != NULL); - assertEqualUTF8String(p, "File 4 - xx.txt"); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); -} - -DEFINE_TEST(test_read_format_zip_utf8_paths) -{ - const char *refname = "test_read_format_zip_7075_utf8_paths.zip"; - struct archive *a; - char *p; - size_t s; - - extract_reference_file(refname); - - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("en_US.UTF-8 locale not available on this system."); - return; - } - - /* Verify with seeking reader. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); - verify(a); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); - - /* Verify with streaming reader. */ - p = slurpfile(&s, "%s", refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 31)); - verify(a); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_free(a)); - free(p); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_7075_utf8_paths.zip.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_7075_utf8_paths.zip.uu deleted file mode 100644 index 332f99689..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_7075_utf8_paths.zip.uu +++ /dev/null @@ -1,20 +0,0 @@ -begin 644 test_read_format_zip_7075_utf8_paths.zip -M4$L#!!0````(`,$^9D5BZ95P"P````D````*````1FEL92`Q+G1X=`M)+2Y1 -M2,O,204`4$L#!!0````(`,$^9D5BZ95P"P````D````/`!@`1FEL92`R("T@ -M>'@N='AT=7`4``$NSPQQ1FEL92`R("T@P[8N='AT"TDM+E%(R\Q)!0!02P,$ -M%`````@`P3YF16+IE7`+````"0````\`&`!&:6QE(#,@+2!X>"YT>'1U'0+22TN44C+S$D%`%!+`P04````"`#!/F9% -M8NF5<`L````)````#P`8`$9I;&4@-"`M('AX+G1X='5P%``!G[AP'$9I;&4@ -M-"`M(,.E+G1X=`M)+2Y12,O,204`4$L!`A\`%`````@`P3YF16+IE7`+```` -M"0````H`)``````````@`````````$9I;&4@,2YT>'0*`"````````$`&``Q -M6UASCOG/`5^OQVV.^<\!7Z_';8[YSP%02P$"'P`4````"`#!/F9%8NF5<`L` -M```)````#@`\`````````"`````S````1FEL92`R("T@E"YT>'0*`"`````` -M``$`&``Q6UASCOG/`2M.B72.^<\!*TZ)=([YSP%U'102P$"'P`4````"`#!/F9%8NF5<`L````)````#@`\```````` -M`"````"#````1FEL92`S("T@A"YT>'0*`"````````$`&``Q6UASCOG/`5<$ -M&W>.^<\!5P0;=X[YSP%U'102P$"'P`4 -M````"`#!/F9%8NF5<`L````)````#@`\`````````"````#3````1FEL92`T -M("T@ABYT>'0*`"````````$`&``Q6UASCOG/`6#)ZG:.^<\!8,GJ=H[YSP%U -M'102P4&``````0`!`#$`0``(P$````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_7z_deflate.zip.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_7z_deflate.zip.uu deleted file mode 100644 index 75130731d..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_7z_deflate.zip.uu +++ /dev/null @@ -1,361 +0,0 @@ -begin 644 test_read_format_zip_7z_deflate.zip -M4$L#!!0#```(`)@!<%+IO$E_&````!D````3````;&EB>&MB8V]M;6]N+7@Q -M,2YS;\O)3*K(3DK.S\W-S].M,#34*\[7,P!!`%!+`P04`P``"`"8`7!2Z;Q) -M?Q@````9````%0```&QI8GAK8F-O;6UO;BUX,3$NXSL!\]``!HQ```&0```&QI -M8GAK8F-O;6UO;BUX,3$N2_;_5V?5+LGB -MX;Q\HSA:6]+T=J/]D_?LA^>K-9J;LE2+_ -M)+0GZ]QZ0)DP(>^:O#O.:-^^:YM/QX<_>G?G6O^[H[H?774:Z1[?EK&N!OQ' -M:S.^O6S&OP/\2!LS'C(S'I7,^'O2"?(^P("?`?J'`)T3FIGQ&\W-^.669OP$ -M6-<]X/\CV!?Y@/_;X"> -MDR#NP58@_\#/BS+0`W0>!7X>`?PVJ(=YX%PX@'\)G(L>P,]^P.=@7[8#_;>` -M_Q(X=Y-`O4T!>I:#H+\[JEN@9RB(NQK4SW-0#VO!NLX#/WME/KN8 -M=`+_5\&ZYH'Z[P/RQ[ -M+[!?;T#>/@/]KX'_'PQ\7C0#?@#_,=!Y%IS'9>`\?@5^5@(_WP&^&]3)2;!? -M(X">76"_[@&\!O)_&N1_EKP'&O`GH'X&@KH=F>6A`[NV/A]?4;BC\!U6/@Y* -M>;NF'9WKSS\:XBK^AXHZ_PJ_U3K'@W7Y>)_RPSC?X`4^CQ,K2CAG?,[2!;PJ -M(K'!B1,1+5TPPPU\L=2JN"*WF2W<;K)XS?$MU]DFAW/K?(GBS7"M.!8Q\X1G -MAUM9DUWA39LK?(-(N&>%V9UL#47,HR3RN2O\#O.C9)^<4T;+S&4>*P"[,% -M"+8#+[1RC;&C9Q"S0/[HK#B^1,-(Y%4!7!A@(,ZW/!'SNN6F@KM.G*@W#D*5 -MRO^E_YU':ZX+-^:AB+))P/L_9OV=OCG)^?\6I.W:_Y#K3I2DEDNE^S_T#5&0 -MAH;\0>I?.71LX(Y@ME;BL:PF.;68IR@-'Q#`F^4Z5HRB8[[I_"LC"-R(_$?% -M_M6HWA'^.`]^$@5N;`150(*;QHXEQ?F[P19>BP*/5T7=L45F5J;4CT1-=T5? -M>!+1B&B>\W$:5JGQK'AS$2^S&,,5%FV4QR[FBB0-LY@RN<*/G>#WCCM5ZF9B -M"B.7X:V"D<9"FV=$_\A-GK9(4"8J@155E5P*IJV^0/U:@'!MF\DBB\;+MK(1 -M0#RQS::21HLO#KM-*L,&0&)+&6?=/T -M0A:)[,LA#67.,[<$NTY%3K`#SPO\47$P:@PA,M9(B=)XK!H7_1562OU)U+=5 -M3_,Q4B8Y]S,ZC:/1,J+ECI:$21/8!3P_!V"YGEX@K -MG]-Z#FHO;<7O%J;F?6Y;_)^:<2BB;A_>CNSYE?9VVE#\*MGU_[F5?==/+NP< -MM,D`C,-XK+9-[_1.[\]J-:U7K%9CO3YKU5BO6*]:K^@41"$X%0,EE]=-C6S]G\I>5!FT5AFR];OF#S-Y:GGJOK -M?_-U^*72\*WP#'PO/`L_#\_!Y^%Y^`VX.U+V6OD-X0:\"NZ!.'?H@U?# -M37@-W`^OA0?@3O@A#?`0_!&>!C>!%^`-\,7X2WP)W`7/`)OA4?A;?`8 -MO!T>AW?`$_!.>!+>!4_!N^%IN!N>@??`L_!>>`[>!\_#^^$%^`!\!3X(=[RH -M^!#8"3?@+OA:N!L^##?@Z^`>^'JX%SX"]\$WP$WX1NX?[N'^X:/^#&X#^Z'F_#CW#]\AON'G^#^X2>Y?_@I[A]^FON'G^'^X0'N'WZ6 -M^X?/@E^!I^%7X1GX-7@6?AV>@P?A -M>?A-N/_1+V?^6[6\^>3\6/'BQ-1=PU$HQ,2J^2 -MSFB/2U=)I[3'I%=+)[2'I==(Q[1[I:NE(]IMTC72B]KUTK728>TJ::=T4/O/ -MG5+720>T?TO72YO:/Z4;I+W:WZ4;I0WMK])-TB[M+]+-T@[MS](MTH5_TA^D -M77J_]GOI5KU?^YUTF]ZO_5:Z7>_77I;NT/NU7TEWZOW:2])=>K_V4^ENO5_[ -MH;1;[]>^+]VC]VO?D^[5^[5O2_?I_=JWI/OU?NUYZ0&]7WM6>E#OUYZ1'M+[ -M_TI/21MZ_W_>ZR36A3B`XWAG.J5]&M/8(A)1^[[ORZ.6X6]Y]CVI`U%!.,BK -M@^1%&<)H)+A8CFXD+@Z5.-!6+!&13&DUC83+T\^_ -M__]__M^9>H6>!0]D/ST)'L1^>A0\F/WT('@(^^E^\%#VTSW@8>RGF^#A[*=5 -M>`3[Z2][I4>RG_X`CV(__1H>S7[Z!3R&_?0S>"S[Z:?P./;3#^'Q[+?A/#R! -M_?1->"+[Z>OP)/;35^')[*>RGUX&SV/_5W@!'&,_/0N>SWYZ -M$KR`_?0H>"'[Z4'P(O;3_6"#_70/>#'[Z29X"?MI%1;LI[_LD5[*?OH#O(S] -M]&MX.?OI%_`*]M//X!;VTT_AE>RG'\*KV/\%SL.KV4_?A->PG[X.KV4_?15> -MQW[Z,KR>_?0E>`/[Z7/P1O;3I^!-[*>/PIO93Q^"M["?/@!O93^]?5?4ESA3 -M^7M>I`-CY:`XGFU5.PK\A9_0!QQS_A_?/%-N($X'\,<&,;(LK)?"+'<_V%LN -M>YOXN2P4[RC*)?(IQN_@6R$QKF+]Y]U8/_7#;J[_CO6Y[WYAO1.YTCRAW!-/ -MOK?VE9OEG,W"W(SKJ_=+-5^1^_B2PX79?%XND%M:+UO#\C+Y'5%?J;\L+`GY -M(WXOD)(3E8_5YSDK)PISGB_9[=4V.?/GN>7U9SK7?X4M.PIQ?E_@M=76?M^P -ML?I-5].PE2?[VLVV=E_R8]JPXW7R86:*G84)%(20BET8%7IOKRR)-?' -M-#U3<%X&],P#YZ5?;FL]MNZ7+LHO'BN/5=;JH/.F*M^\B:O[2Z59XIZ9WKK[SQ3X+^?*>FO?::X>Z8N=<_D[33N#SOU<7?JZNWD -M]SY+:N*"?B.;*P9#7)+P-@]XD[2J24V_WY5D9W#J44-W)5;GKNQ4W99PRDM9 -MB6&F!-V4U2I&3N+0I%^0(5BML=],YX#>.\ -M5E/5M6H\M2-*[:>VV]VF&PJVN0Q7E]=Y$O4^>J$?I%L)>%Q3%'Z33(A(.],V -M91"D!+$'16+2FDGS>&@JEMA+/]1G5R1M+"&,DF%443BU:3CE#*<,_0`37NU!9(137]Q`3V6G$V/T#Q\ -M!)>PQV+6N0H7>#$-VU?3TK&M?L:F^H"F-S[&1P"$B==%FKSPVD+TRNS0A)UF -M*?`H^.4PC.03]H,WYKOQK@I\NJE\<-[^H`[KP:8M3BZ"@!CI#3[>"OHP*?%: -M;WKDM4K&*)FD#46-Q?6&*G,?OBH-=2,,"_"D:?!B6@RWKR9-.JT*TA/,,O2X -MYHA`DJ'U]#LU1PR(*-O`4[XNTFP7\-%:$G`2$_#H6JF`-TZ'-4NXTW(M!:>W -M-,8Y.HQP1@%O>#W7F'Y4;Z)0LN-=7*`I1!HACK((F$1`;O@%3V^U\7KV.CJP -M,!S8G7Q2@3FI#!]!'R:`^_*F'C%$2(;2!"T.`*X5^`10*PC4F7D(:H9`39-A -MX!)JG!%I%4$U0X@BEGD,TCP&*0(09_$\SM8LKHY>4F,#]PP_@?O"H03N>I\4 -MW#WA'AP>["++%SG&R'SB`+>3X*:Q?!OGQ'Y7N/UI[6$?!L@WTZ"-D""W5L=O=2N2/?[ -M2-;8(23K9G)9_?L"SN\JB/DP8=Y!F"-SM=O"?#@'YIU`TFWI7_<&^M>TCLO: -MR32I6Z)_#0*-6PO!VIA=KT4\AAVPME?M=76@&#D9\:II5T<` -M$K9N!_J[S=!+D63,4QT#UX(6N!;<"=>",.&EU[=IP4;XJ[9SSW/D3XAN/*MW -MJY\L?X3=$$J*V-.W>55T816T[V0X7W0PX;Q`)9P?G"G%^=-*P/9[REB)UR3. -MJZ@J>JG`ZPC&JYSQ:I3S"B&ONTU>ODFDGM0L`6P=46.?&,8BCNKH5<(*D]@* -MT3I:8=T,Z0J[XPK5U@I%;(4[]0:/Q9OWE.(CZ"L-9,::]N=M6%7PI/<-D;G3 -M'L`UT!,<`IG[2DPW:9)'5X=2.[%!K2S8.&3WFJ$2O(OJ>0%UR,%7\:I#E[[_ -MEIID#MAI.N"8P43`!TP'&$E=<00MD0?<0+^+-AIA^XS`-@,9YT(1OYF$W[6S -M"+_G:Z3XI?:"'?W.W'/$X&(Z8;[*;8,D"B59,G:HP% -MU0%7EY.<$0'@`_C/-\Z[E"CQ01.J;3;^9`UAV^$G;%\]2(KM -M^CT`VWQ85UB#E3TF(-.W?![R4>4T3*'_,F,@#PM7/A_$!KM])TVL:)W<'&3JUG30%TON5S(^[_ -ME#X*04JO]6@!->$,J!\[0$2ONLS5,3AJ!:#9@QB`DC"6]*IQ"$!_&@&HF&?* -MA"T4+5M.GFNDS&%"O;4=0E$;),LLJPPM8,DR/GCTY@$H\2V>_!!TXACV='U/ -MAY^1DF^6M.*5E$#[7LS7:`0.<2J/'>!_N>ZT,]VY^"#2G9=GDNZ\>Z!4=_)W -M`WWY%02W,[3>/!B/XCI%)!87[*MXV2K'LE7FRU>Y=UWRF1FT -MR]$,A7VD1E1,(HS->W- -M:0.1A3Z!3*[-$:[]+(]KI.R,:\+*'RQ-ON5[U.2T@TF==MUT.&H,)J)&8CKO -M.R$1&P)='S5TO4!(M"#/\H%R)T"Y84E83J]'42+(8H*BQP/4^_YZ`<]SFH2IYB'OPY& -M`A$H.(C8Y&FAA@9DR%!)\N('NEZ0?ITM)7TU*5RT"0Z$(-`Z[')=?\48`B!* -MW@"2QT#R"$C>#9)W`N"=`N`_DBEGLGH7#1`L"%?"N$:^QC0;]Y>&9]J\NL?( -M0"^9FMU9"G%J)C;Y_>9`TM02+VGJU.E23:V'WRW106$FP-:+H:&8K&7&D:11 -ML0*T!:+## -MAPX5P\4UT`@6U(`0X"==2U^L8?D`CN./J^F)GD[1)H]_.V"]8T4O)* -MP`:>6FAQ`TQL",+>Z#&=/2KQ@0=6%Z2EZH*+*_"A#];I:_0ODP]^1=!6:J$0 -MSF>AFLZ1HTBE-XC8@32X(-=BS&4W2ENPUJ0=4,:A/7V]2=L]'NT6&9.V8SS: -M`8.V^_5G1AHR.6ST[81]"FUN?N)D_RG^N?Y3 -M_:?-E?H8\B*8;WQEN1#L`_<.O7?WFR6Z\-D%5IGW,%!$HFHH!-O$:*U`!O*= -MGIX6QTOGSGF6[PDVCF@ZR\EVY>E'N)^'6W0-D)](X^H4R2^"]J!J(RJ3$SES -M_XQD#Z*3S9^0Y#3NW#2\,FJ/D_G9@A0+$;?81I1G(\J3$SEM1$XY4:&-J%!. -MY,Y)1)YY$RIA$GV!K83YW)>"A^84SNP:9H=`5()$3(\>%+H]AG>?DV#>/=`Z -MLKWK^J?_RHZ%E<9W#.C)H1:\M!ZO-?TOC\$?[F]70PO6J$_C@."(UR5XJAUH -MS2C->^'"S`M_MR=YX8?WE'IA;RG8T;Y@>^`FZ_MI%N,7'3$,#Y'+8%=DE6!X -MO.\I[!,O`W);6[**@KCQ>M9G=M.#0R@Z"PZIR@K&M7M2,+ZRDG:O[BK=?>LV -M8)E%:'K$!$^4F$T\JSHJ,IO(F.W-F&4JI,PJD=FK#L:,!R16JJ]CZ4(=%O-X -M$VI3Y3Q$OM1G%/-`[`:-K>K3J!9U@%A57Y5SNN)5'VHVJ9:0W97F"3FK'F"8Q+,:IM:JHQ`&Q"2";:YZ;,9PB< -MI^&(Q@G!5;IYPC<9%-\PHZ5]]B3I4?-BN@E+S7(;5#,9E"W5P8FD#LAZCT]S -MV-<;'^>PKQ]V(Z6:M9M4J3[WY+"O]S:TKWD?;6A?LZ'/+M(\$*D;1.JD>H]> -M_P`PA[_J8QRHEV&C5!UAU_R3^;ZSJ,[LHZ*)0;7^$Z)*&^]+V'L29^"/L7C, -M%")]W+"ZF6']M2L9UD][$`;W[R3%H&]+T/X`"`:(0GU%G/\MF_\,FW^:?/X= -M.'^6PRJ+;\LL*1-46$$T35?_/F)+/[T.R.L\,3+>AF*X]/?9Y5C"]K$SVT=? -MN70?+MS'*[Q$RRK<>_$FN`,GUZ`G/A+=@8>[`X\&U%>`#L3XHD'T?,V=.,,[ -M55&8*LQU=;7V<=_@X81P<$FD/$PGA;A]LD&\'XK!'`9:BIIQ:EC/P=(W(."% -M$E-'WZBT.CE^X>9;=OX9)EX)]`3Z>#Q+!-LP+^+5AP3#K[6"W2N9+=RQHQ2_ -M]Z>:U8?;%*NN5M-RL=C5_%2]IV;OGK-IX2>LRBSR[ -MI'62*?IX%:W<NW&A,LIH4@C3+GR$\516JC)DRKIC"9 -M8;WM%@$\2-A^;AN7NPS;*++]*/QOR@U_OBY31"+$B*W`..V;!?B-D/.K1FY+;"X35":L -M#&[IQY)BT#CZ^;KTOU:U/-]2MK?CYX6_#!'2%E7I6@.44GXH0/R\"#$GPEOJ&1_";P7YW(?8$+MN10[$%KELB*7Q&,Q9<_@L -M2N$TIWWF#&MF@],`NVEO?L.$9KF9WZVT`^X?$_,[:3'LL8T4PZ;>5([%L)!0 -M"6,[NNA]:.4H;#V_,G=A*[`#*7B#W!B3$P'QW?)9FH#E@H(IY:RHM3D\P6*\ -M(K,)M3N0T:S;D7B>4BKE>1OR7)5GI!Z%MCJ8QZARH>9`.\W;4[+K8RZQ/D9Q -M!VIB26S7!>>5<**)0H7KF7=D%2Y>TYK.:EJ58DWK@A54TRHS)`R%%T"N$`PU -M9$._'E28UY3&X&0M^A:B/R&;_DV+_GT;?1O1S\NF7V+1WV^C;R?Z,[/IYUOT -M%XU79[MTV*R'S1J/]M9?3=HMQZ.]YC>3-J6,0WN859-[?3S:O-]-VEO'H]W7 -MK+>=9VII&YXA#F;`=5N]+;QWC:VWC?>NL/6V\]XN[.7*=?%RPZHG&5VG+I>7 -M\;*3,KK-K8!_T;("O1ISH]&WZ=[#;EEQP9+/6<[SE$!K6FG>AZ5)=&O9CDQ. -MEYO*;\/BH#?(+18C:@* -MOV9;8>346#KBK-'U4Z+X,4]O(W5FQF*[ZW/:VXBWS%TV#%U.6, -MA0<2M]21V&;?6(U(OK$:Z4GFZSVX#_UM5U==88VK"WSC2.#K32DOAZS\YVDQ -MO*I'VFM+T#_SW7G5D4L?(9^/]=->\52IJQVZG5J#NSIP^FJE91/X_]57`9/5%I-NQN0^.9-J -MDPE>+F%U$!GG,N5IF:`HEO(4,<)7D!"K"7%^J4_S$'?B=Z:EM>6BF31D6-@\ -MZ7CM6F/<)QD7K+FY3#H>-PH+35.,`SC0,*L456]S5T<(M7YF3[6].2HACT?% -M2@A/EL[%ZPK+8S/4I.#R>HRW)T([0FWZ@)"ZK:\+,TSOTP@[_D9U/"[S4"^% -M$C>.TWZB3+'D6D2'O]DUK:O14JZJYO<#4`.F`NM+207>DYOZ`9MR%4@U&E_: -M#K\A$?)`&^`9#OBSHR+@M-?K;8!GV([UUA&].0-F5@T"SU$S<\6*3DR/Z_7+ -M9NMJYVR]_K&S].9>.)%(H'69TL25KL;\P7[JEGN5*3QYG-TC[I.33B)2@K40 -M](3W_JF8O47MZF_&:;2KOVIOJ0DD`06(0,VY%Y=ALMW[)OM"-H1F$;?Z_Z;L -M.D.?BH%XW1-;<2*.N*U;4=RB2'&#$T5Q6[?^U?:Y<"]\[HTHBH*BB(CBQE7W -M0$%!1/Q4<#VM'\2]Z^\N]Y:^OVCA]:672W*YY)*[2]+$-'LL%&N%C+(\K@"\ -M*R7U?KD67[(W7/NXA*]S;8Q,CFQ@+XR*/I=P482?VJB]@8K\CX1XE\$1$/=\ -MC!D!Y("&'`#DJ89$P"5`(N&3_3^M($!Y#2@/P,<5$>DVOL."*"1PT5-\^TC! -M&V:D$SJ"8'D$8?=O@L#NSDK$5UE#PQ`R -MRG#;:NN%Z7UYD(>C!\1;W=;JHC/#`>8A9$`JH+-.L8LN@K;R4#)']QA+MG8S -MLSG[^RF/,1&Q=?=E'@?EQ0MVXY5T_/\7?%*IE?&I>5D9/_"#E?'=_-JRC5]K -MUN/5PURV@GZMXAEN(M6U[4V]A.9.$V8DB4H(K7@+L)@/-(2"5CHF-SHS7%P8?>Q;R2"U8$82)9,^70>826[CS" -M=,;2>3A1F]CIZ3NDN$M5!P1S-_#1OO -MR3G$!E`JM1@)1PI'@_5DK&9X'UHN3*Y"<52CS5PC'T-W7&).WLM#.,S)D[I+ -MU5\/\"/6*0@<7GS@)V-:!+(`NAE>_,I>,>NRZ"IU,JB(OC/`Z)+&&Y,VD)., -MX%F#\"J#!/=S1TY()/1%+B*(2,)"PP/*9^U&*.2U[>&,&^*@LDNNPW"GR`@! -M3<,1+;C:LVUB[V>*!)8A.$SM@>2\%#M[E3L.16R"[6FZUSD60$DU#A6PY_2[ -MQ?SCEZ0S^ULN,L*HJ;-QXPV2Y%[4L[.^HCBES9Z3DM)?1<%$570[#BIB8T'@ -MWVCKNPZ94R=JT/<6I3>YEL^RN$_EUYI9>&&>5.%H;&$XVG-].-I_=S@ZY$@X -M&D^%HY/OA:-&.AR=!S)YJP2V,[991ME-'^]`2K=91EG/'7"#C5%%7@XV\QNS -MV1`#P6S6B>O? -M\\I/>77-):\OI?XKKWM`MWZ<#<[K>JYY(>562GGEK,=J2U8++&()(6Z7(BCO -M_R!O,*4=ZDD;+"P06/;..6]:6]*$_74>7^,'0M2AFG\8L9V,N]&+V*BRH -M$9Z)-6I#&W6/#]51?!_ZP.4E!T4SLU-*@:P71ZWW,\)V`ZYGF^0[1NUKLG#< -MKBHT2:P<\_Q_BO*X[D>HR`C%^2PM\^*M#$DY(-Z\3NL.OQF3>;5OMI?9./?( -M?OK?%F0K1*'P\C%RYNW&0EH>(?GYK0JF\=3LG[ZP'GZ$BY34ZG0Z0.>)$3]N -M="A,&+8:>?N4.]29S%0<'C%[28B/.0H3;X'1%/ZSY'LK8FG-@5Z*WK"G,:6: -M-[E>-\F"%L'.<(O`G8E3)X;N[N-IS:6Q/W7%@-3P="8N+YR7#B6;@D#"TP-M -M'=0%ZAL6;$+)\JMZOO]-">T-SOG\T$*SM'FF&>&+OUM9]PB&7BG%:6ZI`R'14)"IK5TG^:O'TLL@Q?PK1%4I@$Z; -MJ<248PF4UP'@B4(OH!K<9L5\2(!XHZ7TOAX()/RRTHGZ4`0@V+8\LPR'M=#Q -M8DIX\0YN&P*U[6WN/9+$0E9!0'4_(3F?GNQ[]K!_GT#WB[ -MG99.F8F05#X18!U^98(!A*`00,M,Q`V6IJ#4$3WO!A:5!8#E-D@.*@LM!_N7 -M`$481U4TJZSI5E\+03/XX#V&^O6#K0YN.!0DW]^;PTI72R[AT\$M4-QFG -M;Q[5!R/*:Q2]-05Q?B%F]8Z:\:J;$W:'(2W_=IEMN'1+JO\K>)`];H7_*M2\#(<8/,.-965Z.NQ=R';]LH,)27O7AXL],D\ -ML*9X!/IE2A08VNE\(97G)KK&[XBDQ\`0JP>\-5VHWL0;P;\'?%OF3[,9<9^T -M>FOFAI=4(2)(>(ME[P#6RHD?/@;S?D91"G-3S7>AB1(,Q8H4QXR64\Q$/%N' -M(I9=CI!!K%U&%>G;4(PIS7T+T62!>,JH0%CS_;D7!,_R9$IH>B'ERUI#H+5W -MH@AY)X@W$8__`D30!$0'3H)7W(&;=F:RIEW6]$3K\B:1-+LR&;WGW#4<6I4BVN.MR/O@EHKN<6"@-1GJ*E/PDY)PUQ-DZ,X:UW3MH -M""H]/*BS&1'0FE[<6WBV%ISO.E2:G,X#)0R/K3O6;/PJ8PV2E:97;F/- -M:<]8\P&")U#1TA"KWS036'D".B1MC@"EH)>30)?`.P+S]=:5,>O)C2E_5?G7 -M3XMSF"(P2@_#8-<*FDHIS`O[\;0Y`SB>7MC[N0+/>SR$VP8::S<\)_%\Q@/8 -M'P__NWZ#]F/&3T\D^^'Z#M6NG6HLY>'?[5LKN@XH/EHE/Z5[?':GG-%QPK:!(V8)4/"$!P#VG3U9M6=$?^H@O'HVVA0- -M2`06`;0FH`?,8SKE2A%"K5,G@4NSG*,Y+"<,<.FCY@R-JX)&P:C3.87T,:$JFJ*O%I -M1L[XT:INM''TC_;JR/=!H7BI)+<9WV0RBILW&-_7=`)+N)EP\TDFTH#,7WUO -M%4N)FCM7^4!>;DA[H&,B#\ZB?3!]JE8MY4=L&TQ#:.#$D9WCR9ZX.^@_Y1-B -MB+I.,^*)I*`7E5&N@!)A48E5@=U2ND'?UYR1/BY7E&D/[^/'4Z/=$&, -M-SDQ<7>V<9XT00AN&%0G%W+U:<(,4)SF'%2W'*!2B20\+!X>Y! -M$P@NP3W!(83@P=T"P=W]@$"`CW>[+[L[0(&?_&"2[7,SSWPC>[/3D]R->$63X/0 -M&3[?)]ZO2]<.75SNT-K`;>I8`-%FAA'5>>J.;9RX,;6,#0R[N+Y\E7)N;![4 -M_]5`L!6UJ%XMT*)>M4#UA@V:^@*-:C8)U*O9,E"MCB]0M4F3JBT#3>NTJHE= -MHZR6-[J\2S]`IT//SCVP"79T!:,B.Z,L;^[^B4.R:U14I\Z142[CG!I7G1IP -M6-MX$.S+*93GIA0=+A]I;`"L;YWL%FWD>4";Y6-L!3>M?M0#P&!9;C^%RTSJ -MT624+,?],DO>Y<#SE3A4KC2A')6$](%(D":^$7 -MKY/`?H=$UH%KCXI<`YN>$/D,9CB)?O%S@&6G12J"_X[2+BP=27$0^.OH+X^'C^KZ-?L,)-]`ONOX5^P1&WT2]8\H[(";`. -M^`S<<1?C=N+,@GL8-YCA/N+!J0]%^H"'P!G@:W`+&/>1R`6P"A@+]@?3)L!\ -M0`]X'_2!21XC'KP%S@`[/4$\N!&\`'X!8\$Z3Q&/[Z3G@Q[P,N@#ES]#/-CE -M.>+!.^`6<.X+Q(/OP%BP]4O$XU<7VT$/Z'F%>'`6V`?<\QKQ8(`:1-;9ZO$&=A$B],_99PL21,DG!;'./,C*ZXNBT7VQL<'R5-&),]8 -M-T62?@F':Y4S5RA8,D\NC75JX"JV2B144#5YRK%QJR=SMD5#]!UQE8`O;/>= -M+3\:5R7X?78?=Q:?']R*WXMK;N1KW>S^%X2_A]ZB?E'&^,\?I -MA=^`Y\&MQ.!"W%OX -MR4K\>#.^(LK;'Q>42&9EONG,^S$?OASV -MA5BE_9=F^[O@DV&_N*_X6Z:_!G\.OHW2?W-K_BA/COVEM])_=_-^9W5@?MAW -M7H2[WU?4^^U%O>S8EXXJ[1TTYQ,%?_@*-GC%CS3])/BB5T7V*//9:HVOHIG,EOCG`%?$+Z0 -MW0+\U?_B/\$'%1YI>?U^O_`#[ -MAN*;6_.''P0_1/']3>^#OPS?0?'MK/G#9\'7%?F5YS"W^1S.@,_]2&29$K_( -MFC_\2OB:BJ]BS1_^!/P\I?V99ONQ\+6>B/B5^,;6_,$A\!.4^-&A^/_I?_J? -M_MTTO(!ROB@3SQ7]7=Q0@V/)B>1TD43-I_DAG^.' -M?"'FDS-?BOD4S-=C/BGSJW(93,9\B[X&,QDPSV/-\CU/9B93TF?]P;_[*CUU -MON+`XK/\#/MW,I\_KL'$S/>B)[2,I(/4>,XCP[3Q[#`M\PG(#*0KLUH^/J,Z -MSMD<7Z(?^OLLQOA3LN`+\O9^OS)?FUY^\*^8K\*!?&0^B?9OIN%AUOM)-EB8C2#\9)&/(L>1,<@6YC3Q$7B(?D.])9Q[V3[K)TF0$Z2># -M9`PYEIQ)KB"WD8?(2^0#\CWIS,O^23=9FHP@_620C"''DC/)%>0V\A!YB7Q` -MOB>=;O9/NLG29`3I)X-D##F6G$FN(+>1A\A+Y`/R/>G,Q_Y)-UF:C"#]9)", -M(<>2,\D5Y#;R$'F)?$"^)YWYV3_I)DN3$:2?#)(Q9*WJU8IZ -MBI9QE2A6O$2QDL5+NO(WP4\&:T?V,@M(:*$Z((_$-%R2K0(9KPO;EY^/_XYO\]^_6;F -MSB+F2=6MF$]5+X%Y1_62F,]4+R6ZDYXDYI%>&O.JZLEX -MGJA>1IPF/47$&U">*I:27A;/)]7+B3CI:<(Y@W*;<,VDO#R>=ZI7$&FD5Q15 -M2*\D,DA/%W'2*XO32RC7!W\IY55%T7+*U9,BWPNLXMU/U8VDA1CG1DR^A=&+ -M.-Y.Z'-`Z=,%7J3X,+CZ?A4P^A<[K@3X=./OQ/AO09^XTF>_D2?.XU7FN.[\ -MV7_TJ0-_#+\!;P)_"_\!/P,OF2#]5"-9^_'"41G>N+FL=UGEU]JZ)XAR8N=T -M62>C3S/D;V7+>CY>E-HB?Q3Y5.1[PR\J[D.?,6UE_03S1QCYN\BG(#\3^78= -M9/T-OA#NZBCK>NBS%GU>H$]9Y'?^V6YG6=?`B3R,_!=EN^>0G]8%QX_\=>23 -M"LW'%2\E\[N[RMJ9B/.%?!7DKO66] -M"/GJ%MD_`_TK(+\:?>[VE?5->"/TV=T/YPE]6J&/"WW*(=\=^<\#<']B'$8A -MWQ_YBL@7(&_#C],^PJ?"2PR6]3/X`OA+^"CLSQKTSRLTG\<=R'<;ANL&^U.I -MO/2CPW$_8/P/H<]D9?Q/PZAR?#OZ3*_MM'R?H2MOL(^:7*]?`&O@E> -M"_[=0M_OUD39_Y,FZU/PJHFRSQ/TJ0EOD$CWR42?7+>LT^$.)M\)^6\^63>& -M]X2OS<=U`L^#/U-\#CQKO-FWP0OA@^`7X-?A;>#/F/W\@/R]`MR?\#2K,3Z5 -M1`?,JQW@=:QRW$[C^]@,>%,KW=]IE?WS0K+VP+NA3P:>U^7A&O(/)\AZ7<+_ -MGU,3?O>QB;SY9I]A./6\9OHLQ':7!'&_P#?`]^3B?,/WPB^'<-U@/X_#KP9D -M/1+Y:U;YW:;Z'+]MY(GWG(?H4S4/\S#\)?P5]K,0_@2^&N/6%?X=_@$KC;;" -M1Y>4/@$GY#X\Q?B_;N)]IFH)F6^/_;D%KPU/Q_$>A=OA48R;"]Y.=[V;^**, -M0V?DZR)O@^?!'\-;PR>ACSJ>FW&\5R)XGN*\S$*?<[@?6R*_&%X1]]UL^#9C -M'(CWMWW(K_=C_H6?T%T0[Y_7C3[$>7\(5]_WWJ-_=B[&"YZ.\]4K1]:3+;@? -M#2?>PQL@WQ#7B0_>'/TG87R&PELAGX)YX`I\1$G'HIVILPWE'W#,)',_G)C,]C_)#AQOR,YT4H`?,`D__,>)]D -M(6S$?%4OB<[W93R0)/?G]3CS=;Z,R>]A_"SCMQG_P'BUTK1W9WPLX],8W\+X -M2<:O,_Z4\2^,UT^FO0WC0QB/,;Z<\1V,'V/\&N//&?_&>.TRM'=@W,OX?,8W -M,7Y<]PS"+S/Y9XPGI=#N9+PGXQ,97\'X*<;?,EXSE787XWT8+]3=1O@\)K^1 -M\>.,WV&\B/$296EO]MM316B,K.=B_NS'Y`L87\+X#L:O,?Z&<4LYVNLQWI'Q -M\8PO9/PPXR\9KYA&NYWQ3HR/93S.^*HT^C[=Q>3/,?Z0\8^,U[;1[K#1^].' -MR<<87\+X=L9/Z5Z'\`=,/K4\[2(S%@EG^O/'9=KMQI=L9Z8G',VWAX3'[?=K -MN8%0T%CS&XX*G2/1F,]G]PA-Z]EYH-:[A[Y$6Q,YWK`W-S\2-9;=!S2//Q3T -M1O1$3DC+]8?&N?U:CK%\7G/')@N/OMS?[XUZ<^S9+H>3#FF^_&"^]GNUK/S] -M'^$+NP->+2<6"$P1FE:LTO1DU!3]^ULC6,8OHF%W,.)W1[W&(NWBY9^UT5K` -M'2GXYUCK_6^9N+'%6-"C:?8L1XN6K8JO#S=]EIV5I9?]!W8=/'B$UFU(W\[& -M4F7YB:-9L57DYG_D;/EWP7C$M+3<''/)[>HI=;,MF[5`!^*SYEGBSXI]S1CZ -M4%`?I8CQB2/+O,`\0JQ/-[7*=IA7JIL__=6ZE?-*#0/AL!P"(7%52#04M$3< -M1_X!`\$ESXP=WLS10Y+=_)`C>_?]E1.]U$1-D6W3_CFP!Z'` -M.`H*ZKH?D(PA=QP^@@6B>53`CAP0S:/[ES>/[CGDF5QV,I8J"^G!6%-$IFA> -MBWT_<,"KRBAFNXH2CTV'TKAW9WDTI5=1H2=9^=!DR*-+L;BAOAU4<:GR*M9% -M:R_I0\>MO7'P,*W*UNYID$=!TMZ?9L;DX!9&8+O<817%992@(H#<3L=DA'AK -MW,7??Y2VS=0$T",I@?9VXH\PNR]^_ES1.SAPJAI$W&M.BH:>N'+NPJ!8O -MGE0*D<0\=S&I:KTWA=-=A`$\\\E\$P-A4(#+BBBS2>:J[28NOP -ME*:U!9X)(A;.BN'1=8'A59J!R_&6L[N=:\WQJ$C5.$C"6!MPG-YA&'$__I#E -MLASC-+U7931=$@KM`8J/7/R"KU:NG!BIMS3YR\=/W9> -M73IUZNKBDEHZ=OS\HA)S.$3E>:U(I"7V"Z.]Q6(49)J*M:`*RZ8(V'4>:6/K -M<.`'HR&S,DS,*_.&4/P6922F.,ACW2\LG#Y_]O@)M<_?YQ_L+#:1?$:F@$RQ -M0HI(Y66>H.SK[_PDGTX*<@/%EB'`C.)_)M!+,$;9:C.VH()&C":9E%6=7;J@ -M[!E(VN<3<(FM2DJ*`P>+;LCADHM/#(AEJ@@AG-6.+JN,07:-3C8X&YP+_%LV -M1+$DKK2*:1%J&N5E18'0QNH>K46T<([[K=/7XV:20Q^Y9OT.TR`/L;4J"F=(& -M1:'SVEO;U@F7FW]2R"`&YOKVP<%WM\0_Z>P1SL8]0 -M2M?D9JJPDE[&2YCSO)$Y>^9$LE'#"L3P[*$8ZM(4WX":)FTYXMSD"Z/EW,9% -MFE*_QZKM3?H<6R>R0LK1G.9J7R=IG=UE[6);+N:`!I -MNA?)3^[99JZ?W$[;.=D%,;<5BCU7$KQ2G[;L[7E;)2X39X_FZQ;TW,<>5]BF -M7=BP9T?5'!7MYJC*-;/4R=1IP>+>[MAQZK9!QW4D=TX3*9K;"2%=O]ECX+\9 -M?2?[:;>D9F#]:2VL!]^R>.?:J$S$??T4K)QNA -M'3[JBC*=^I,?L9@VC.CJFX>P17/CZ[WO63Y0M@Q_[G$M=B[6+NX02HT>!/RU -M0S'CD;Q%KSP:M4=3S_-)Q64P)%KF-1W/GI*TU/Z=I/+YFS'<34',M,9!,?;\ -M\&%"2$-I?-TSU3GOKFBH4#9I:*[C@'%XRN+2\\TW"#_Z=U)Z,!]T/G_DT:#4 -M7.Q]/<;_#8W#W+8,%/])5"-FSW='-(RA/`UQ,;(&DVCD\1SUM,.B\'S:APGY -M@/=??CN02SY`^\LJ27?-Y1;(G\\YK)0+#CSR/2T]@O>K047%$/HW8G[DSPOZ -M=H.==]4R_';0!?`>V'Q\03-0FS\H?V>0ZPX\\DPM_=J0?]"@UY!+CS;GHX+* -M]:\!IKG^$+GWP"-OU=*%'GQA^U`/("CJ`2"_0W^/@3^.-O)@05&/`/QV!_XI -M=+K.UE\(NJG'?IY(/.?52KI6CM_2H,\E'OFWH$)?[O8KB4?^J*5?SC?GE[_7 -M#?R-2M(-/>M_`_Q@)G\EZ8<&@YT-_'N)1WZ&I6L&W?-_E'CD$5MZ8'VW_CYC -MCV%?G*<*VJ5_4/C79HM'7BS1%>*_0W[@.1\*=&7[_T/@41?%%/A;7K?^?V+O -M5]NZ$U#X[T#J?7W#CE[(^3EO&A1_)^Q9_R^)YWP;4,3A03?^-YZ!YSP>4(SK -ML=_5G*%B.)W^65-QYR(B'JL9X[XL\'*+NWZ'?(GMW7'_ZTM -M^&^?D"^VJAO_!U!+`0(4`Q0#```(`)@!<%+IO$E_&````!D````3```````` -M````((#_H0````!L:6)X:V)C;VUM;VXM>#$Q+G-O4$L!`A0#%`,```@`F`%P -M4NF\27\8````&0```!4````````````@@/^A20```&QI8GAK8F-O;6UO;BUX -M,3$N#$Q+G-O+C`N,"XP4$L%!@`````#``,` -*RP```.H]```````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_7z_lzma.zip.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_7z_lzma.zip.uu deleted file mode 100644 index 8ae8df41e..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_7z_lzma.zip.uu +++ /dev/null @@ -1,45 +0,0 @@ -begin 644 test_read_format_zip_7z_lzma.zip -M4$L#!`H#`````.$#)%$````````````````,````7VENA79\GCDS+I*=O.=!+"5(),_1O%5^1102P,$"@,`````]0,D -M40```````````````"P```!?:6YS=&%L;&1I7-I00]!0!=````!``1B$)'BB,SPW````7VEN7-I7-I7-I7-I`L`8(0P,#`P,#`P,#`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_bzip2.zipx.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_bzip2.zipx.uu deleted file mode 100644 index 6d9884aed..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_bzip2.zipx.uu +++ /dev/null @@ -1,19 +0,0 @@ -begin 644 bzip2.zipx -M4$L#!"X#```,`#TQD4VJ.XZZ-`(``)`#```%````=FEME,ID:&U-'E`T&C1IIIZ -M@8&J>$9":`IZ@``'J:/2&#```````!@`2FB$T:31D9"F@8FC0`\H^:+Y;81F -M6OH?UN^\U&IFQOP9(.Z29 -MPY-_:/D\-$@RAM/2I>(FNV$2K!!&6I"Q+LXG0-YLG/4-JQE -M=%^\,6JL1H*""1!1W]4\/.E))/*(3J)$L1_D*SPD -MAZY)I5-#7@)=-5H06@2PP-)YSB5D!.3J63\EJ*\X%RMDE]>>,6XG5O@<^@:T -MT671Y,.:/=ICJ(=@\88>!>M^W)$;,QY(*`F*%Q2YZ^%TF$V^/85:V;L\W53/ -M?9[-IX&M.O38C\;C@Q';$E9[,C'?<#304$$9O&4U<2"$^;O(0X:)KR2UT?=.E*K!>,09(4\>BYUO&*8;D4 -MY=51BK5L/;$+WB"S8Z-?)M+GT/]^;,7$S'N0)))KF]$Z(GL[.L=F*G#!4NC) -M4)I$P%W)%.%"0YPC!DA02P$"/P,N`P``#``],9%-JCN.NC0"``"0`P``!0`D -M`````````""`I($`````=FEM-]>-Q`H``"L:```+````H'J-##(C0U&1)Y*>F -MF4:'E-&0:!H``-``)30B!0]3TFDVD])ZF(::`!Z@`T9#30,)"0@FBGD*9-IZ -MIZGE,F@9``-``&0'`````#````````)$00FC1,(TE/T:,HTVJ?J3/5-#,4]3 -MU#TADVAYI!A\^>RTQ(BD3$3I$[^,/; -MLS`?JD6R.G5Z9H!*U7PV]92S^P:OR\HL0A0_3>$BI8)(/R)[BOOLC2%8YJD( -MA.HIB.`H&#CG`1Q7XZ?+[_/^7_[H%_86(A9>\@A,_,XZ=,XL5W'7 -MHP4M+H9TD.>'-*H@_0+C17D%)P0)RW]IX%[$"C`LP1H=G0_&E!1":MS%AMXQ -M.;)R8XI%.5\07+:U'.MSO0WA -M_'JHZ5GH`I2IS+,0&673'.$+E#O<4'!QIOJ(=A]MS$!DF&L:[UWD`N@'J&ON -MK"9F:A.4,3W/HWR,FFXKDW_PF?19FN: -M8JZ13*&(2TCX35$",$])GPS2BLBY&_H+ZVL;>UD^#7W[$P11S-:X+;I&4P_2 -MY2FF=^Q>)*S'RAW&B*<0LART09,I)(!+E@9";HI&D+G>(HXB:0(%/23%!+S@ -M:NR/5*I%\9CK3:PVI^LQ -MG?A&-RQT6VZ[1QPG2Y9UVU<7W0N_@W]>`:ZV*-IMC1AC'"5PL)0>9PPF\/OD -MXXHMUZ\%[^LVOK%3L]),1F)*MOQ5)H -MBOICX8!01L:?$[E<$R]4`!$&F!"N^Z]2A2JH&\;#/"R\MG<`!XM)L2.#%FT@ -MI$"[T#%/63SY#K=LX#RSQ*%:^J%L1'HN2F*:.2LQ2X?"^Y^<9@U@PV(.4E%C -MNS^(@N"/+X8L:9,0T^E]7FZXBP#;&@K7#\.W[MOUG8-`-,<'O._DJ$2@7*?N -M#ZO8W/#Q7.=4KXGTY)7:1_NJ7-3FF\<6*$<^N]+-!C)W4+U60F$@>:,&%)NE -M6U9J0*F"F4!.R,Y`.G*"*P_*(P>-<7WV6=I7*E]98+HG":L0P4Y,?%RY^X[* -MDSY./:P;H^X)PU&L=#"2/IS$=1]X>MB:/!;68(&.EX`-X^"ZW_F;B,/8(F45 -M`_?U2XOBQ%&$HQ1YCTEC[_A42U:75Z>4-MI3.*/X>72/`C"+5Z>0B4C49O3A -M'N8'1IOJC95M$"-@1RC6(E"P.0[ZZ:;J?E0+#0?LP-6OA,=$^`?$]R)HW%K-',>W@ZBCI&CX:1\Q,YOY&7QLLV_J,<-^S+:AAO&'.A;*V -M3AQROQ<,BPB$?,M'!#1QR@/4P#TM5"<*D.$6U5>6NB0:@2#RD1AD -M(26E6M&U7;I&M?><,-FD48N@:,:2[U9AD#8DO`F8G`NH2VG:1>/.?`E4V(J^ -M#5)1$;.G/E?/U7S,RZJL\[5*#)Y+2^&5-1.L.G9B!:4)5`06C6IFT)6E9!%+ -M2NC400RE=1Y`*MU7P;V=>_94Q:13C>/8$;NI99OUE6QCKTH&-VKEJ+?SICS8UQ>&55 -MS!AN47T#J*?QEQ6,M2+`@9;Z#.*GM;18!J.<)J@Q;$1#.I*.KS4[,-,#$>-\ -M)PO&"I/*D7`.K'08;Q%TA8:$`G^HT8=;C3N5_4;IF)[F0N$3TDH*Q0-P<[42 -M,33G53,R)8(253>'`I(/(`C4Y$P=LZC+Z#,LC!<`8.=$0&& -MHL)>D\@AT(1A;6.-(URT`6J-@0P%Y020G3VP:QRCZPM[@QB;&[&]I'1L3HG6 -MHMV_<`9H[#0AJH/K\46RSPQC,;0Z:L!U8.MI-D=NTHM!=_;/K:@AM+BTH-:,C49$_(R)IC&^1Y -M[EI=1!L8O8:A+.F,:91'!%LGX.Y*[9W'8Q>2DN$BIBQ(Y()FJNVR"%T-;E6?@6^'&XMHR)AAWR$C9972+M#HSN- -M);+!>$HVAW9>(FP:U,1BUS180R6S:<$UD99OL@!``!4`P``!P```'1S+F-O;F9" -M6F@Y,4%9)E-9[2!3B0``35^``!1(A>=")0$"`+__W^!``=V;:TML-3U*>D]I -M3`F]4]-(T9`T:&@T8I`F(U'ZIZ@!H`>IZ&`````P``"4T4R9-3U`$T]$`,0: -M9KMEA9T)[OUF#<]_H_:R!%VW(Z5<8GI,92Q$\@_99'.V;0!9M_JQW(Q83@(> -MU(&RK]97O.4,(?9Q\O->C6^K@,2&/*Q^ -MQ&&;:95MR[%C&6KSOTJXV':CWZ0#H?FO+]L:K$L-@\J??66K"[C''`Q(05A5 -MAA`H<]68]Z8WD3,92%/*1-[+TH^&FHBX0;F(=TXT`&\A85\I0".^@K=W'6BV -M6W7I=FG(:-GP/>J!T.)K9&E&`70E\*O7<@B"XC8N],ESUC>J<#0$&LF`$Q"I -MPFSXM(AMXP]!B.B$A)+*A@FQI7N,888C3<<1)$V8APW#69B,^)R&)J6R?!9U -MVQ?F1G9TTEH&P"PV"U$F)!()!JGQ4/1670D)VLF!P-;I.\BHY"F((+!C$AZJ -MZ4L(AR$T$'4N]0NK3DSCOKGQ@9(O?$J:V8>5Q'*QHI5Q[SIJ>$D/XNY(IPH2 -M':0*<2!02P,$+@,```P`/3&13:H[CKHT`@``D`,```4```!V:6UR8T)::#DQ -M05DF4UGG",&2``!,7X``$'3GX%(B(Y<`O__?X4`",3M`&&IZ4RF1H;4T>4#0 -M:-&FFGJ!@:IX1D)H"GJ```>IH](8,```````&`!*:(31I-&1D*:!B:-`#RCY -MHOEMA&9:^A_6YQ\4L6YH5-&(7`A#+:]%S/&IQ$[W/8H;ZFA%01)[[S4:F;&_ -M!D@[I)G#ES0BEILMLL482*!*U'E=+=]T@I+>3,SRC1"`R6N_&W"N!*6`ETU6A!:!+#`TGG.)60$Y.I9/R6HKS@7*V27UYXQ;B=6 -M^!SZ!K319='DPYH]VF.HAV#QAAX%ZW[ -M2:!4(E-IS87%O<(M4.)02QAK:[^IR!Q:E(+-CHU\FTN?0_WYLQ<3,>Y`DDFN;T3HB>SLZQV8J -M<,%2Z,E0FD3`7-]>-Q`H``"L: -M```+`"0`````````(("D@0````!S;6%R=&0N8V]N9@H`(````````0`8`(#N -M7F'.E=0!`,YV<T*``!T`L``03U`0``!!0` -M``!02P$"'@,*``````"\>V9!ZECJ?1<````7````"``8```````!````[8$_ -M````8G5I;&0N`L``03U`0``!!0```!02P4&``````(` -M`@"9````F````"0`5&AIZW;_.Z31*H"X5"'0#D!!Z[ -MBD.;"\&2M2O8TO4XV[C)FEEI$MIAL&1)R*(X=%*;,XMAB[M*8\Z$';M1TFDT -M'*!QX<8B:3.'+]T`P#R/A8"XYNR.Q\(-`Q:D_@)>61JQ91P&@(=H1L`B*TY< -M._6LN"TE`.1P(RK(OF7'(\`XT5'!(^SDAS7LB_CUN[!'/DN,). -MA?AE%88KCZ_B,(U$QPY]T-DA&UJWP`0Y(7L1VXX;(_O$<@/!#@HR!PQZN)V$ -M\18EZ8U'%\:E.9WTSHU)122D>@W68J7WKN=:\1;(+^0P!-JF+\T0&G."K&F# -M=01DO7$8)JT2A^[U9Y-8+%+7@33=(>+RT['SEP4Q;`:XZF(XHQ=6C%,1+1IH! -M=TK4V`XIMDC]2.!ZLX(MZUX9S%Y;P8JWF0@!VHZYSP-0U"';K'G``:O,PG># -M,,Y).2$7H`1E5T-C-)ZP3)LL>_HR5HM*6A&_+3S`SL[ -M0W8UT7]B9^R4_2?[H0[_HQ[^U8E"^+&.\-,>A%=Z!'`Q>Q!.ZX#W^P"!ZGVN -M(V,TZT\NNKW^V1=NKT,&VB*(YW]4M/BMU?I291#S.Y=T#DL"9Q!,0$VA"-,8 -M&,E9!"$**3*^9&3OP.\V*@EN.X"0I8EL!:\9PY\)N- -MQX.,V=GS'9W\_+PN:-%":D'#GD+$N-6&-)`E5!ZQL\:%?MZ_,$9]??R838S1 -MY4W[0.\7#]J-9_./%?H82"O>*V=@7H]^NQ[/^N?ZX',]?-^?Z#F-GL")6>!O -MF("P!`D!JGO%XS)W36S)QK;3L9>=BH$[="N!KD2VTOX058A8TKO-,&JL.20D -M=U;L6@N/"[;F$$Y\=+0+%58LG\:+[R#(]/K]=`8FF6,`G04'C]P&*TPD1H4D -M"X``J"N"9`:<&*05X#:#L$X?R."7_UHE-`J+G#ICG];;?S#6%;=YYM5IZ%5\ -MIE%P0ZNULUV=-?9:Y9G>)G4(TKAT"&!:M%H@I"9N`B&#ADQCU"\<6E&@QS"5 -MR:>0JH:,@OW.19L9^.U"/)!AV96SM`3G`SEJXH)B-SS+.S=K*Z%<#])9F`<7 -M,SRE=)H"L?47H2.7@81JI=IFHJF_C0 -M[YY#;W.>.:";FL.KF\)?G@= -M8H*]C3C1Z8[&(Z/7'9@?QE.5B/<@3W`]BQPR)N[@/C:4[?:VJPUD[0'G#N16 -M$;=A@J&"XL&_,KT-*Y,0.M=P?-N3'JF9^,T?GX -MTU3J#9.JA(,RGN\P@XA.V9662._W2Z"CHU&6)2=!.CTGXT:[5]8=\W^ED)HZ -M-"6DRZ5KLPC4#@V^8$W>6778T;EY-9X:G\WI^'K2Z[<93^Q6XVK0G5V,)\/> -MU=7%H'LY/7M,F3L(0->\GE)DO/QD=D=3`VSWW!@7RLLLN(Y:&),@T:&J7,66 -M+SJR]!A?FKT>:DV]FCUSC#W(;/K[=-8?FOW/L_X(E\(4.[(%"AK]_M0\'PQR -M.JJ'K/1#O_>KB5_-.:ZQ*RC*1`))^8VJ<,816JN4B!8#5F(RA'0(`/1OI5Y" -MKB>4(*I?Q@,J6%G$PP@L&2#`U<6QZW":,"0!4G0GEV9_U'T_@/BFPA/&KNX4 -M%O#@2BW^YOSHB`<84(XR&#:7#8IM'MQ8TY%281+_[!$R9U#`0?:"U&"0D#/) -M[SK-)U%:@P$Z!25G"T%,2VJ7$M1YM;&IEEUL4DXQ>E-Q5XM"66REC^P6^F$, -M[I+1LLHAY'`/8%4=!.'!6XP'0>/9,]F$925EK! -MXI4"_BT5H^5./3O`> -MP7:'!J+*QM;C\-G8@K`.C)2TM%^B[=1&=!V(-(K"&,O&.\M+.2VQNHFW")\< -MQX['?']M#,Y-&4S1&C+-EF4ZD,Z2:1SN=-:=&3T-?F4()0(/^@-,5'<<`B9Y -M9:>`0%F6"-Y:5<_*(S@\T+L#RH$?\P<22.L0:!_IR1X!H4LN0>,,5$[^!"JY -M.]`Y@BRU?\@39*/2N0*)K_$%Q'N?,\#./^\-&&.%51#]PB'L]N$*8>I?907F -MO4_R#YP!4G^0>:-[_A'^H2+?K#HINS7!W'4*N)8WB_K)+R$SO<9^`&;C6 -M*4@#>()7J%.HCJ/B%]B4)[C[YZA<#/-8&,."@_Q8'MM>2GX"]R;6W'*@O)&6 -M27E5-:?Z=YZ%LE:#9CJK?%4F`W]',Q#LY/[D[R5A>KEBV1Z6&[776S$J2^/@>_\*''49;)(VO6&KD)4V5`'C4(`08?I^< -M+L4Q/LRE@(:E#14X/%=Q1*BR5`%L2:$YWZPY++.803)Y:AKCGGG9GU%^B@X] -M)3<$/@>7-DAIVG?FVKKCIL-MS]Q!R0"IK!I>05IO&A?]P11TCPEJ=W1)">FD -M.VS.?_GNYU^DI7#V7V(KCMW01DG?-2H]]0&]4SP>^3>':IK=@\WNRMC24L!@ -M\Q&*U&E_UGS*0)G:-/Z_H16@9Z<=:(5J7/P)*0JM[VR%?>A"P?QI//D58HV> -MP*L]"BVMC5<,7/4V3!G*PBRV"6-RNSK=*@NK6B=,!MHNVJ.+5NI9PCALH@V -M3@>/NU;\'I["7046-HO(V@1[2(G$L>(5`B7@Y!+Y`HN77F+0RSX\L'&YP/'- -M!M\IU#L8MUSM>_'4VB!H_];A=]E[F*($>_$B"RI*!:M&C*^">]Q.L@]@GHN" -M'W?+?5I$"-QD4L!IY5W@!I[ZVD]"H:2!"UK#%]6PL2%>T_,!+Z=V%JCWD-FT -M$9.WR0-/2AI82"Y-A9XL)V!NTM$3M>-MA.J`5Z5I*(OIO\9\?D@'24RN)+7K -M\0'8YRXJE^!=XY`'CKMLW-S4BWNPC]B*714A,.']9,P^-.=?H8,6X&Y:B,?. -M89H<21!8CV'P(E$9H/Q99YOKX.#*@_2-9P$A. -M\Z$H>-U@9->3AK/8-QZ@T7[_SU.@=<[Q/`]R1F$$;J(9GO?5!T.R'QE?#K5_ -M@`B2CR^#UPU0]3UIA`I6-T;5U59/#".AHYM`UPZ#NT?&IV"RT27Q%F,#IN#, -M6N'Y,R1V!*(;$/7HAC,T#(Z/`^I0#7_@\QNC)PWBVT&5 -M_,7UJ)?''E.15\0S&F4F"K\\'#L?3I6*4F5M8(P=,F/)JJ#-5E::NP'Z(=)+ -M&\\)*)S#'$*)R,&!/]$>[K>_U0P],V]=(@I>,#&USJ_$+`DT3E__N'FP%5!TRWIBBPAL7@\;K$ -M2(*W6E568<0#(;Q'>.50^[7KPPQR.F6YMR`'L,2:3@NDMC-\X*[?Z8?<3M:B -M-`!3P4,57U1_%;'O?>\QP+=5D,Y2%U]@[-]#/_'E*IV,@/`IDWL)EP6 -M!8"^$Q1D#,G8:YUH:$^QS3[FDG6"4FP>5"L#):ZVJ!Q4PZU!S)@@K@G -M&(#RL-!ZS'OF8/LMF0#*BT9B:'VHZM2,=I]."3Y7Y![]8'!O`B2ZT#9KRTV/ -M7#-$HJVZ6S+ED@>%"^AB7;/&/AF6-50*>$G -MU%4)]P&_=";-V`RO`6QIKHP42^ML%[$8KJ-Y7=J)VF,%R70_]MT_`[:Q63%LF$U -MH2IM68/1R?]T!K3@8_;[5=^\-L[-&5/G!G2ZB5<`#]I*A7C=(K##&&]!$N.A -M&UQ^`GQD-9Q^['7D14IFIR()??W9Z`1Q0P%F4Y/C[C%![D@2B:L5)-_4 -MV>6Y<.-D3?>&JDP?YMB!E"G'W+D5XZ[61[`&0R\E?X8P@(377?\R#[S6T4GN -MS$!@P?PXHO]7D?XT$S.X:4'5U34^/XZ0^E)?`#^+TS>OG\HB)8$`ZT,:.]7I -M@VKLEI'19.'Q3^O8NR7#:54(0P=E635R#.]RL25U/4%#!"?MPRCM(*-7@$6# -M7F&#-P%%"O87Q="ZS(8AV'?_D];1RJZ&_CR([WEI'FR+@0%9M,7FWW -MMC6G"`,JB;K+7H[L$X5PUOOIIR.1;(OKH128!!V0VYXEK^S[E'-@2,4J.K^D -M1%>X,=.Q*(O;PC<382=WP,9H-NQ^+@6.ZYT6:'CSN@91:8#O[T]K`)4&^'[U -MI@:PT_`C?!=*.N_W!J`DB@\@3IM)IN578]1FUZ5FQ1;>*T<%2`D(993PE/M9 -M<:#1I*0&8Q5>_\A!>K8(;U;65+U)4=](=,#0#K)D!Q,-#OR>!W/U_%O -MX42S0XIW&IG[%Z@ZM-97>G`UPW@W77DCXW0'&"=`4P8 -MBWWRJ-.^=V4OI:0Q!M/^;WIIJ.O_21J*_G/:U#>Q;GU6G(WMGE)!+3";F%#R -M24'G-PJOI9UCNK]*:0X6]_2)*XU]45@O8!J=P).7BJ0T./'CBT*>;"!R-M7Q -M[,P8]K6[]EN&&W!T#::XFW?9@U4QZ68'Z24ZP^Y_CR?XC16">3'M]W\=YY_@ -M*7O#J_QS@,?O^5?M8]*?3,83N)\;L=[,[@PKL_?6L/\4(,`N9=1?"]`<RT#G+T. -M-P'\Q5\R,9OB;8P!8>EHD);V&G]QM,)3&#T\(_E8Q2M(VV/Y -M"JFK&>O1H@UU$N8FS5!`N`7>X>%L)?,2';:7J<:3JO&D:J@.I*"G-.R1$CPI -MOH:.OXB3<&,S2*]]O"T/3[EYO@-XBZKV;Y?N,H1'`#S]6_0.D08X\,SL[)FV -M`D&$R`7?@6>CZ!+=>Y..?B.&<9B$SEZT*I8'J0PDX\$=/N3N.!XD6^0Q5*60 -MY>DZ$@F4MYAPQ4X:X8.<+;X$=K0U$366$%N?!$*-K7P-I>2KP&LY@9*&5,N4 -MP -M$D+N)N061.CA#1Q5;(O=I2XOD^.YAXGG__EO82`IP\1,X._K+/4#E@`X0;:` -MTPZ&!98J7=A;]&!A0+^@L&R;1_*7+W2G_`@W&CQ$+0K^W2LP#;9[":8413$' -MI;KP1G^G9'YN3-A+@'J;)>02@_$V>QF_A7B&8#%/TCAHYM(WX6^;_0U@_A:W -M6F]OY(V5>FHP@<@%Y,U)^U7[@7L?-%C:50$7C[E#S@;(-DBI%S'G4"*\$*R\ -MU/*DW`JR72X\%:"[^EN6W4""/QC)TIB&I582!`W!_#!(UL>.M<6@`X]C:H`/ -MF':\<,&8D3#?NJ6-?B02IDF$=]'![^!A`VZD)8G+8_JU:#5C.C>'Y^9XJ4U%M&,L$41ETR6"0U==(,#I-T878[Q!4*27^768X@9!K:A6UN'@ -MA@,NR*7+/0U(%7\K_) -MIVASQA:Y08`$*>H>&X9X$V9X"X*4-+-Q3#6`)MA+`(V#!B117K^4?_@%SHLY -MO\RLZNI&-U"8V?4)1\Q(`E"5=V9IZX'Y.YUKKXKM\><;B*1W%\WSX_95 -M\_`8V3<<.V_^SQO:-`*M:/&S\5UL?Q,G0(;7S<,SB\<_:8ZF\YUZ[:W!/`W@ -M&"),M69URX<:I/-.POOI-J>-L]D_1'#N5TX$O8^[G`*(Q,P)B50]5H*_$187>0*4W9="R) -MUIQ^*!1=4;=(:P`/8*HE(+\SM0I:I$?,!HA/>(Q*\@5HI"47W;0PU]S=6\]K -M32#*G$$+8OS$6Y:[JS)5_&FO8Z&58BE:=%G)N2.*2.HGOHA'?#(#R_6BO9SOPQO@ -M]-`)!8+:&V8#,)O-K0V+)XRLR1"X[116$'QBM*XKE,W6]%DJWK$IZ:=)YRNG -MRR8L>Q&S>ROA?]]B("S^%4$<20@^(I84")]P/F.0Y@-?+[)=Z,Z%@6Y7?2L( -MSA!@*K((>^ID2`4%E6C;2#[(P"<1ELZ$A(1A.'D,<&XI$AKH46O9Q?9-Y:W<('YWHGD*19'!Z7K92%([I8;=#&? -M[0=QU3D?J.5_%J*O,Q;_*U$Z)A_KE1C-TP -M_PQJK3K]_[-6J;'_=B3OY_+;]-D1GQC@Q=[)]%$=\->_<%& -M="!4@]?(5-^-$3#IXKH1/S?N?M[+@AC.6A>_SB4G2&[PYM_6?U)GNH%!G8TV -M=W,,IW'A=W<,^Z-)^+7)Z:7K6/]YLQMRODUQ=W:,XUO:U[L;8$ZCZ3KD[TTD -M.(23?G=;35U_H0]?M];_)RW0]/MYG]3Q[P']_S;_+9C)YG^C[[<*/TA5*/Z) -MM$I`W.9!BNUH?>%`FUW_!;41;#?_BT7W6AX2/WGYV*F3(-:9'SCQH<"LR.R[=O) -M@&2;-&CL$H7A;G<&N[2H%L`PE9YVD75#A(34L)$FE$DL/]U:8BE_M>/S_>'9 -M;7+E&`OR'\'/I]?'5X!)/.T?_PCD>\+K`D9K,)"BH1*;,CP2FA/\W`B^QF$I -MI@4V?:RN6UJUZ9)?XMZV[)K/7>#\59>?B4^47T):C)K12^@.XN57H3TKWF=` -M7_%"NSEEF@9F?Y/TL.*WE22@-/[?_5*S"O[J*6+-Y?G2P'1PVST[OZ%]E -M#=H?F@UM@7]6--D[>)$UNJ-/%>WV7SUWVM&GBG8'C3VG'7V2Y$Q:2Z&#+(#N -MU^$VD8+B"NRO4LFAM,GU^5'CQ:Z!,1GVZ%.QC6R"M$@?PN(N9+^;<2H:\399 -M,//;E&NSY]-HWZ.1,ZGRAGPJ=EKSIY)KL^?3:-^CD3.M\H:,!'9:@@25;?9\ -M&NU[-'*F9?%.`I*+(8\2D%T:OCB/A!?'-S=GQXR!VT%M('VWYAL;=#3M!2$7 -M=A'L,QV`>LN:,V8X'?CSXBY\:DX7_KRX"^^HTX4_9UWRT;9N&+CGEEY>'5^T -MVV=V3X5E+MA3VR';U,H^LJFVA]G51>UY%]T>NJV+^O`VNGUT7Q?UX7UT^^C& -MFCZB\UQ-D@['E`Y[0?/DACCN)>TN=8'HJZ*NFL%0O#24C/+,Z0"KE?:`-9A%]UA^)?`7^D/`+2U97("?0VA\M"1%'3$GT@>B>XKVWN!/3]:$2YU -M\`(LM+4`O$+)RW=I+(,N=&:5>6N/Y1/7J[8*;--E.?"\N+<4,)HK4+E197#E -MEY40Q.VR`GQ_3,GU\1UAM4/-=_(=8\73+?3244"SRL;`]RN=0];!$[+_"3@] -M/&&O"O-G,#>R[BZM5)H[H!;^)7QU?GZ\T<0V4 -M\)DX8*\P<;A>EX'%8R8>\-ZY50/_ZM8AK-H+I(4C$*-B+RHS:W+!0\_*)XU] -M:--^^,S\2Q:]M&PO`/+D:#68'B?A!@DB\H"7? -M1HMA77ZZ\(.$+*#%H*XO+[TN9U:X<\F^'5Y>_0:,\=PZR9]9.$?DB-U=>TU2 -MBNTMFR&G?_I-KY!JL9@^:_U_U,[BXC(^V%C,ZBR/T;4IGG!4%+(\Y];'B:7E -M<(+=E2=DDUWGTTPQF45SL%T]MKIBV-;%'QZVY7-'YI)J*W-JEXUJ>OZ10?_$ -MJ']B6).<1==O]7%M.N-<;W'='2^GGT=G)X<6BJ?$V"M@O -M7Z60P3,NF]]+]-N[7C*>T/X\*Z&B1Y=7UQ>PGM -M5;9)4LD74:&3PP_(^?0@:/<>`O7)"A*UI+4O@79^Z:66W2\5ST^\Y7-.L%\, -MZN+FS.<&:UG\)22!P?GQ%)OUOQA53HY@].)47A\*X=>JY84NB4SQ-7VG:)-_%LX1T#TGV0R*1JX\M`NKW\MA\,9[$FP"2D$ -M=5)GP[`S>`KNI]%@D&P%7)HO%1DE5=FI8,.5`;@&B-=44X\#;_L?>.ISX.U5 -M#AR%#!9#(UKH#6D.UMQ:"5JS2K8I`7B_F`8"W(D?"=2*#4O!??2$9ZIZ+`1X -ML%L-N6%Z?+"JPL`7AZ?=HZ\E($OV256I;"O&B>>\,<+UWTE?>:M5C, -M,GB?5IJ?5)U9"O-VA7VTY6N60*4+_?XW6($\X2XEL*LP5%-99R&\"R.))9O5'?+!QX*%7 -MG*V@5PR6ZA5GWGK%8*E><>:M5PP\N,J9/UL95%"%$HA"&#Q=D\]L0;K-VH`^ -M;Y5"91^?'TB>H@L3542J@/I.M/-C+P>4/F^5'$[K_?O?]_R<,OS21`ZF>7VB -M8JZ''YK7)-5ZJOKC,`^@%%M/P<77U2!QG%`N9+_7L/\^FZ=>,YS);L)9! -M73;-\]:-'QO\4A)\4H!U4:&;%Z?FOA2WE+$2V-O/=R>MX_/FE2^+M8_/^4+W -MM,F^R[UEYPG\O'G:.EP)?J404PK?2#)>-,/#!K2""::,SO.NY5YN6KB[@(U@!V&C/O=/WU?TF;1G*(%3 -M+73I7!7%J?Q!HKW7C#VL=V?^UKM!A?6N!**_&#E8 -M9L`[JS;@F"J_1%-$I*J1OWI@_CU -MN(9L..G/4.RF?$DTA[OC\ZN;WS1R\N[][:G?^I:;L,Z\35CO[-MZR\FF"%F^ -M))G?(?,"Z@W1OOGE`?82_S<^KP9;7A?SA8ZB-YX,1&O]+CJS\_?7-Y>?#GUN -MH58,7@CM^/S\\J./@><=04LF3TL)&T&\O/[-C[!)*>,E\_.CNU^X^O%"4+]Z -M^A"E@O)B4">M$R\W!I=A7@SJPD_+UU+.BV$A&MXGD/,=_'-^(28E>`VOG2=" -M.T$7BV9^<6;M,3Y[(06K%S,#>!?]]--W^A+R$L1&6)ZG+(]*VHN6>]6Z\K*I -MHACW0CB79UX^7GGP>-GZ")CG\ISRX(NGUVY]OFM?-3]Y11>_XR>HE\WRT]'2 -M22ZJSSP'T%9\]EFY*8&^:-4`Z*FL?\E6\G&!;\3E^KN -MBU;=/CX[/O0BU%*4?3&LFV,OJ_D76V=^"3B1MKT@FGKU"R&V3IN'>.["!ZO- -M4^I+3H-@7C3]+N`[?91]&41HP]O<7>[B+%WJ+O_P_$JW_L&3]SKQ[ -MOVS_;XY0G]?O1*>]>"[HLQ1DRS.V,WL9>BE([VP%>:%A\'W[P(J7RS,,2 -M6$>W7FDI)AQY"30..UX%WF)]>Z5`9L"\AT*V!"(_:^-WO*C*N%QL$=SV],4) -M4$^8WC@CSWWBA)O#OA1`D$=Y?/_(MYD7#A4%^7C_61!VM=(FZ_:BSWJ<"%XY58 -M>9RAZ(^[]ZWKFP_5V/BEZE7"?]:P[:OCP[N;CW<7[>,*;?=+]FC?GQWT[%?> -MU:=>4MEJ1T38(]]S:_Y9SZ\0&O2@#_\..EZ -MQ*P#=NORT#-N75XD?NQ%I5%8)=,^__7H^.,*DS:O'2^?]/GEK;>03X#];7G5 -M6.-OTLL]Z+Q\+5?-Z^:Y_UJ\+%4,U]=:)>\^L_W""[`8,E8`+0]@^^&,BHS^ -M&YT]6.TQM]LURZSLOV+R]N6C-MQ>+#+W5RYY[?;QL_1>PIQX? -M9:$+?WJ4BMB(^9%\@R1FR\Q!MYZVH"_V:=/%-A9-@/&,VEP>/N`?/5!)8N?A -M^>'7UV6I;!^K<]D*D$R6^0)8\KBTST+Y7>VE"_V$>**5P_CMJ]X5\+R03A^W -M7;3<3X?7-Y?G[_V@X8G%;WDL=XEL,Z.O4+BY<7? -MQ;`\]XO0PZO,S"?_.C/N\RK+)(%/K0LN"N -ML-'@?$B6OLJ\\*SDW7FO@Y>WG9="6XJ2(6<'X0TE+E%`*T(FE)@#2]9,A`O6 -M]=*V2S?7JT"5?WVJ[!7KQ:Q%2BU1.S_[O7T1>PE4SA=NO7CN!]1]2GL)8-1Q -MP(Q_O[SP*U*0?YE["70;B>F_(=E+WTM@G_\J66]SFT*\HIO@%53E(84*-B9Q -M;<0.5&Z90PQ)+:,_VC@\OLHO,Z:$T@.\23&-^E$NL@)9,EJ&TM1] -MO+C%F\C!QO[N[N[>[FY5_4AGC,7PO.I(FCA-N@K1/?T_ZD8\<7U`7E^\)"F/ -MB]&%`1Z)IE_Z,)2D@S!]*!R!A&.>7)Z=@=RUSYKM#R3Y&9/DW$$S*Y]U:BCI -M0UQD\H3G-.6--EKG-$D&04I?TYQ(!*<#"0<#2)R*LV+JJ3-&KC8=!H`,.^7%=#%LQ)FE_Y\W#Z\L%%V@2'+)B2D1N8E^] -MTS?I:UV>1XU.(>GSL^J%@2XN4>CKMGUWJ']?FH$N$#I`N#@.NX]A/X>(5\W# -M7YNGQ\&&^W3C_*&'O1Z=*L7(#/'W@1WT[]"\3J%`8 -M#'$)U\=7E]. -MQRF_2U:80>2WD_4>^T`W%]>YZ55W&`,1+<=][>"N/*!`I/GP4;97!6V0,E8D7J=0-Z$?_@Y5EQ?ULH^W`\DV==N45RGX,+ -MY^7EB=4#GB]E.$W26NGR.%)"/GF9%/U#\YASN9R0Q4CHION17N&99E`1G -M4=Q=+>"'>,,V#>_Q@K9Y/I#?`& -M4SR*V6Q]#O:W@Q8QKTG\79[S^2F^YSG?-<_.],7$]9_4ANY^27#UI=X,^NG% -M;6$$4^B436EFYX>%D:C;_$C9EV4C31\0-@AQ,C^>/O-9&$"",*]N/B"&\*Y] -M?-Z\N&D=MIW1*EJ4#9T?\,-5<)&,VM-D7!CSIGEQ='P^OZ[<]V7P^_S\TL!K -M81"0CR]PC=IW=\X@N>^S02KDC1(:7W$Y,WQ])@]C/F."\4FTI(`:[@;-JU9: -MP']]2U.17M=)Z^E#<$H(PV4NO-#SL!L0O_L<-';K!X7E'C6O42'TMGU\1U+E -M^]8-\EE7JCJ?ZO#?'RR7WJ)&SC6G@;4K#NYB4T7_TVS3L -MS&EI7.7K[O($I7,P9"FSGB;\WKTI(O0UEHIWN"*@O3+<9E3OUX,^7CX+]NIS -MJ:O9"]`&??(#X2AD5YF8;>L5UV?!>8A2B+R`*A$#1T(:Z.=B3_YROL]>P7P# -MB208)=-@/$F^QKW(&M/OHY`H)OT8?6=9!=(GY"+>;#G.8E5WO:6-\M6[1!0" -M/KZ@HTTF3-UI:S2H$K23GX3'4*-^BG;03 -MW92M58#"+ZB)H^EIU'T@*HMVT"/\VM[43T/2T&PE0WI/XLYX^FX70YT!%P_'TB14<5I:?9=<9Z5_)9(A& -M(D<5X(H:/@=07M?&?O"CVG=]KNX9T9+ED6T3'(0Q\QY/56VXSBR#*PR(4DLE -M`^:=&,_*X?**2J&6`[7V:)HT3``,WY@`S`_?XAZ);='WL#LE6:[Q0IG-/>O5 -M>,<^E*9.W3BFFU/Z5SCI&>DO1=G7;'Y!7`SDIG$;+_Y)L]S?^Q?.D@GC/V.6 -M+Y[_"V?)]*UTEC0)O`);-D7&*AN^SM*Y6RFHQX7'JY%,?9@EV`M_VZHX.R2) -MJA18YBQ<%20)1HLOUQ^9)W2X,JA%&C'[I]&(F<=U'@7NHOY3;O3,[TI[S_1? -M=ZMG?M?:>Z;_NIL]6WBU5Y_IJW_E1%\M(4'E_5MG"V@0G_JF@/P -M>#H1P"=1)]@]V"9QI+'WQC5T]Z*O)/^,D:A$H+ZQMD(#TBT_C:)[6!?NTFPVK@SZ"]I;,(INWN8P1CS3",2:\&=+8AI3NH^[%HT*$8TH,!8X0,ZHQY*N;*]?6CB-2]YPRBD=L4 -M5KZIXR`*29R4=ONFW4<28)-92J3Q.VW_,"*]3U]L/IE$T?OV4:%]VQC\]9$9 -MFLOO\3B0HD:,+E)XJ-#M.NG,TND(EEP9B1#B9=9Q??TB^1KLO:R8?:.335]: -MOC`M72#Y7]I#DI&ST5KM2YX>VD.G&T*5C())-C'V7'23R60VGC*6CF=3@6EW -MM:6]8+(+ASB5;'@Z*K,I$)EG_+XX;-<$"X]MQ5$JT'8-M(OH6\#>NQRS^?A8/>KI`TJ]51I<-:NQ7;.5N6-C*7;MAM^->.(49'?Z%FJGO -M9(RQ*",S&[`33&SO.<#?U]O1.-BU&W42?P_P>EDM?4N-H:NP60]?H2_)]=,) -M?8V5TW":KTYZP>-5RY<8[/#B<;#L$_+[]!63&'1O8BF -MA+.X-8]QFMQK]P/3_9(V3"=]!S!WNM=WYJQHR+O/GS];QV&J3A?ZLG$:CL=1B"<&W.UX3ON\_LMLY"#C=?/:8"E^:-@?FKT>=N6-1`76 -M]KX'R9@=C:PW8<-)IYLDCU%NA#W:<%`9F@WO(9O?O@>W-R>U5VJ*IJ6/)\&> -M7?IU=!_"<\;3N$/>_^86*'%"+*=+1Q%UC7]3G)&U&(87&*L(UEOA3X+=[$L8 -M"-N8$%`X`NGV3+`7.BS>G-=;.!X@>#I.'Y4PR)AIA,#GJ1IR^&(:'9-NYB`" -M!0\5`0!OMW`#\3M?:UC*:5W@7I-PE!H$S>Y#??V<#FC?`C@G#9LM->@M]G;S -M&@0Q@3*#CX>O=P@XXV)!=9F:SV#F^O;%\^W'F/KC -M$%)A9H+3NV^"P^9[$^@"@J'S&!QB0^3)]<>K0K -MA\!&W@G1SOM[8"QG@N.%,3U3H0TC,S6A6Z\,@.O(WE-C;'=<#3EZR#UW[;3G -MEPI)S3(]NUK@^5.P9T?\3"1490O\T+!K`4_X'S>6&+[5IV](A)Z"#C"94IZ. -M,=-,2I$ALJDI<>G1V4PS>FC0P%R-;L!A8O;M&P'RW``9_%!6GHV#'055D)8- -MTQ+\7^_T&^&6-5BRZ$_VS-9J,_XTPR>AYJ_<\[LF+MT9X/++320\SDY_1ZFM -M(^H036&2,NH*-+T(P"1"39*6#(5F[A[UP^Z3R[2)%@GEL??@B/?9B0@QX2!, -M?\]0(E"PRG#LYN&9TN/=W.EU6)+AIH1PQ%NBG'B!G#DNF_D4V-@.OLI[#CH. -MB/^Y_!"Z/6T*"<_P#[REZY?"&DHR0G<0\VT!VJF;;/#$4GL0X$&&@?'FD!32 -M?7RRS\">-&^:9P'=5['ZXVJP!P;4RS(*GM:!12@Z#\59_L$>O;!%YACT!SO- -M]<:E$%MQ>Q]FM)'U0K^K[`R)#A&G9Q3O$*E^9$M(FM]P(SF*1(_+5@3(U%B5 -M6H?HLJEF&_H4_HI'"?YBPX<02+:3"JC=#!VZ,]&\"*]1+]C271FT8>]96SD= -MR3?3&+0P?TM8&7J9'>V016XXN!0K'=QHU+^S05HZ/<\ZX?[=QXF5AOAWB[I- -M[9Z.P<65XMG,C"?1!13YI:O=,?BY^RR[-,?CO"<7%\XRZQ+)/=!$SI6=1]@,X^ -M8JL"3N@?.E+RK`!!KC0NBKZT0$(B(=@A/\&XSHVS3Y>IEP$FU/8 -M&/0C3X.FOE6`H&K"#MKR'W<:*LL.PWAT^JFD@Y1/(UP('PN<)@"(5+HT*KK( -M!1%4`Y&83&=C)A.IJM"\%[NO2Y;76+X\UC?DX$I`-)R#(]E`K@[:X?PYS*F3 -M]$D9_Q9.1BI]SF"G^?Z#V\L%,NV!+W(N=`E>"GMN%!N@*.#.]Q\.@JM&R@B> -MDP"$?M2%Z]H5?``B14$?3$V`J!&'`5R2&D'Z5K#1_T%?;\`]VT<^HS`ZNY/- -MKPFLK\33,XJ<)U1,GU#LJ[XNO.E%Q18ZN.]H!G,-7]1?OW:PD9ONVNT#2K1; -MIUP\3&PZS($P$5[6>?OC8;VD3QI]Y:`*#L];A(<@D=G'.^"*3'?W5>5T&\7I -M9MO7Z\6@HS0R(SB"XL0SK<^-NP,T*@?8+0Y@FX()$&X06X'>/Z+CGHWHP+=I -M6_`WW3[@(/X$/@';U]=ZD:,S&W>],1K$1B4WBD$ZBSGH87TMB\D,)$HKX@MH -M]6U5R0S3_=2\OEA?BT?BT>_BLJ6)9>$(;P<=T_F\%[]]/8EK'AW#")6-DW#TS[M71B;'! -MI*(.C41:@&$"(HR:A#D"E:.5XU0X#N*>`SGJQE:^K(*TU!^9"8!_&I!K6'?G+7-JCJ(/M?4^$^:>#QHN# -MER\=$0B-?@N[77&XLUN+*"$"/_2"86FD48#=LZ@`^PFD%6*CV'`B$\1M=@B@ -M71`+X[P@=]X\,]/FEX3.?^JNKSGJ$5*EP8=H-(D?4][Y`F!'6R"T(95@\1@? -MXOY##726V?B4=$YFJC>3&91<5GAQ%2#C?)A->MN`]/[O__%_Z.[]`OMV720# -M2Z^.2P0:\@Z7TZ0[7@A]))/'C -M<01Y0%@A%(CM];42X6H[B*9="<$@F5B$+)Z/DDA5"L5`062(G2T2793I=1B* -M=(N^+EYT=\R5Q4DC,TA(DHI]7Q%B.5';&H(U2#X$II#J,"/V2I.=.'W!X4!@ -ML]LK9!)K"V?3A+8IANGI2:H.C'KQU[A'-V)]365C)\AYB!40SL16RQ-UG*9@ -M)'%-69#2;FOB,&#SRJ?X,:85D&8+!\8#S<.%P`*\#E@7H4C0X)4:'=2TMI._ -MKF*)9HI6=EWG`.59INNZ&;(2[GHA5/'IXN2BR5=9LNMU`3.)[?8P62(%2[>' -M+6$)CGT<)9#9J;.<43S&S:ZY>(W-GWK`4D)(:4B$O+GS@B9+FUX_>:(2_VKN4UH1JZ68P8H'18>&!,)9L -M97,9-YQA"20RT>]W^(J$G?6U/IL5<#*J4CJ]V0(S0HA:9D*MLX,HF_LO8?CX -MF!"_BW$`HS?L=@KHV&&L-%0Q9T7D_A:5KJ(>49?3^)Y$N)C68.JG6:-\0??K:^CY+:3SY/4PMFH//4&+ -MK:VOI,DE=!!3DB.5,5AOJW'FL/RTS0PE308S,<=#C10%V.*@F2*S?T96]K*G -M*E7S8]ZIA/YCE_BFXD6+]34F^P_1@,0;Z*C$EB>A'@F?!F>!Q!"=(;)MS$9@ -M\J.-+?;DK3'*T#9([M@FA(89>!IQ8'-\CWQUT'"K7ICU+TDTZ0?M9$08W('K -M?)*ST,T9YQG'U1[(D`X601('BYC&#%:+3V&O@G0?.,KQXH:=O"5BMTB#6(.+ -M<)'9E42R831*9GV2YYB!DK83L?+%^$6,M@'7,LY-_`R[D) -MI(.<$,.&U@"[&HJ+1,3%65^0F*A85S;K>8?$`+:*5+'WY\YVQ.C*/M*$8+'_\B$B -M,80(\]QD#DG1&N%*=F,B(6]@].'*^(C=;IW>MJ\;@37)!ER^(LUV%Z7VUQU? -M4\8KGZ7,,G!\'#F2\A!>[^60D%P1Y`ZS5FY4QO?J&1+1PQIPR'<\D!(=! -M6O,8&"A!96E+\Y]<(&9[WA-;`A8%UW6H7H_VC'MQV!\EQ)UU4QK/%^%D+1\T6JQ%BC[BZ#PO1*RY9(^[;KT4MC;X!!Q6`G7U\POR@)Z\3U[G*;P:0WC -M5*WOD/.22=R/01FP_6P2BP?J_6>Q81(/8:!R+C`KL5;\$]7#2'\V"&J-5O-W -M%&Y/K2;"B:AI#!?MFV!-`[[&^F/]GCK2QM6327\'3"IRAU1@3$$['-_Q+65M -MUA[PS@YA4C+=@4M^YQ'&HA^#R`D>JPG=&D2VQQ'[BYF^OC'A9\3@O\;1MSK= -MDJ?99,`A:,]?#'M]/&U<1GM`T@T@TM@''Y_$QR3X$\$;P8[/3SB'$%!K(B-7<]VGKUE -M11@TL4M"[CUQ,A;0UM>"8$BSGTT$K(9>B,F9)/=83+VP%.#%"O:VS8O;L[,MW0/CCN$-M*9RC243]BD@L^"2W+S9++RM]S?[8"W& -M).N^%W9)4FD(O^<;S'HR$]F=36OP`0Y(9@WP9`J.@,-(2#690*ZB*Q!Q6)0A -M6YA`;934.&@3R5>"(9*A#V*BGJ3Y>1)F/9+\EF6>J6G/2?_D%>_OU3IP[,-! -M"3!QFKQ^\<*ZKCJ:E#5YDL@6`J4QM)VD]Z31N=FNO<6"6?[F9X?I/),9*VL3 -MJ%%TJD1O8IHVGQ.K`JWV)<8S@3[VJ#@A)ZA-@MH-\Y1()">3,E]L9Z)[>$W4 -MB\:HS8IHITMB\ZH)57TH7MTV[#82L6.$@#=9Z[QAD_-I$/J.>\V<:!@^&:.8 -M*U?]%'/RC?FG<_W`ES&M$KMH9E+V`N7*/9&+ -M6@:)9K,>VQC?8B^>6!\5ILTZ?2UF`IPP)1LD_;@K!EOI(S6Z;#@)6STENA"P -MQ([!IGE%OD8Y_WI>;SRW*/4VB'M$,F%69;<,?MTWZ:+LR0I%DF01!"2*HV]V -M..HF&,;?9V,PF\R.+1.&!!XG!Y..IBQ\_TQ>+L]S/$-_Q -M6[RR7E363IA+-O0^[:1 -M$T1@%1`"RQJ5O6`ZQ[?9'1>#CQ3T$>)M-U,E`F82=2>*!$,;/2H7:>=>S9R- -M9+NH6DD0B"6@+9+7)Y%#!\!A61\D%4KB9/GR&BHFX1A[Y3H^89<3\Y]OR"%7 -M1$/&(/@L")%89`[.AG`I+2V0S@*HCZ3=W#_EI`H8"XCG,3")C6().^S#US#- -M-/.]^NNZ/0'IB7T4EX38V5BT=Q3\S9HHZ;4?6]O6S(:*3"/Y(+QK""\P/*2; -MM9IZ3K>)X0(;MH0CA.K!EUY3)L02!X!4[YY1OJ%2CF>P##;OIY%6-)EQE'Q> -MD.)@?QH*5\_&"+!4FJ3#B&B/1!EPE(#VVV81"\01Z-(K[NOQ=[HK,?MP!CEE -M+(T&]S6C'VG>0-7AB,LN0RBU6 -MB@6P$;/H4$8FB(K#`D+:HP3BL80)21V0F;R#1&\V^/8 -M=:Y:I'%/V09;B<4JS^*B>5TU4M&78QL:@+N$L+O@XA**B--`)A4;R.N%/H?` -MY$C22.A>:>2&-1BH6@VP9EY[%?-Z79B6;9?1=&&:R`N*B]8PHV\%M9#NP+_3 -M_V?T__TV7!.0_&%%-:'_Z%"+Y8+%QO6E"O_\O%X5_%FV'8<*L82!T)'`=9.( -M+,"LC5^9ZCQ-U<"99CBX#-[O&V+9 -M-'Y?@?72P6'&X-F8RX:4Q!7I>E3:GY_F05#F*E30.'HWM`X;?0?RAM)'2J&Y -M8L$P3!_I1D]2<^J[5:?^O#">;2GC$A>S;5578*]P!2H;%DAO -MUNYZHYD)0.'&G7NAZ"7X$PP;[&(2[AS,-\0=+"H6,=DCO&HTTA)S= -MOT:35LLM8@PX4$*0V:8MJ-]!N!`1,H@#3^K@M;3CAC/_'6Z.1FKR,&8=1'$Y -M4MX;%R]%V``5C;[#IIVR,4SZ,7_>.WVOX6>-F_>ZSWLO2_=YWZ4=^7:'0HJ% -M?=^ -M!F=)OP:3]IJ;6XNI)6ED>[!22+<4TTB^D424:C6Z24+$:TBB2W[73E1]3!_C -M\=@)OKGT)F4?N68V?A80Z*PQASH(-"FW]]=;J5 -MPQ[=;E)6:8,EBY"%_59`?<@0V6XB&:LY>AD#=6=RF4DK*P7.C$O@VAV8*(MMU7L%Z_: -MAQCB+BF;J/VE4EQ#_,DZW88-TRS"QO']R')].>QJ&/5B`LZ;P<&OQYP*[]"H*\[S): -MM%-[QDO$\_"FGJL;L1X.;00>3E/"&':4W=OTQ36:A7&QB^P:]Q^F6D>K7A@" -MFUN#S`(:PA]8![&)+9D!2JR!M$5(M%XS>K.[37/`;RID#Q-6?299JY@>P -M5SB'JG8-R1@VD#N1%(+BJ!5E)"(+@HQO;L',]ET,6D:E8+W%2N0ZK\:+RO%R -M\\K:Y6-",CUJ_TU@](!,U11+.,E!$Y-B2JAK$YMP<]5$LF$"(F?IK>(@$N&39=L@E'&66FM>H5&RIZKH'%N?HD^ -MNY?)+PC:#C8U`@FVB2V5@-A\+M8G?E)11MVM&M51L)`*LV_;M1U.8WB7DT*\ -MK7'LS#A'\DM&?]?7-IO&6!_E3",PW!$KSJH$"%TB8MD'[C?JC9>D3HI43&,QR7)+XVG.HT+$;&1,#_=.1R[KPJ4#)LEX -M'&ER(P@Z[.3(UEB#Z]H.T"%VG$4H@T@DWT9L5>??9::[%J^1T5"K"7VM6:(E -M'(.CM^"^GEB[G*8E'52QT)-.( -M:?MH?0TR4#A*AJ'*@6Q,RD7=FL"6JI/?RV]%8\_=BGGB[L229-<2V<+)B`W$ -MXOCGB%X-$)&^6OG9"#X.%)BEB5JLKXE[P<4&>`));=%X1Z[!3%I.+E!3Y37P -M9TA9-&CR2,LPW)P(T0-7,S.A*C(S.-@8*)*W$(0J82$:0CUAAE2R=BD8V:&! -M'[=4U47D,[OTV-GH*#3*A;`Q49;X-.*RD^Q#9YLSY#P@5YJ`2CV);5\""3@N -M%393/A8KQ;0?$6F`>\74+%<&1,]ZMPKM&_FSSMJ=$&]YD/P*CJ9BS%-!3/&6 -MTT9"\2V#M7.P#U2\5$MRI1KQ#?=3P)6&>:-"#A"`LU@'QQZ]2TF8_:LF0.:D -M_I!]+F(_,GY#8#9-OOY:TU98;).!X#GM59H%=`!+'<^1RO7,?1>7U^PH4A*,@&/PEE:[38F -MU&1>1YP['L^TPH@5UY,14)*NQS"&5)[9YI&Q5Z&`-'*V>6YHI0IC$LHHCL+: -M*[>8-EQ[>KX=)W@F'`[<9?6SYIR3Q0C)FS4YC"27<"3!(#+Y.X^1D6SAQ)2G -M0^'ID:O!>H*8BDAH63MA(H`0%MTG?@!BDA90>6\4B0]"WZVMYD+%D`K+S:29DNH#_DE:%E)*> -MNL^M,CI-9HSKFD/Y:#*1R\UG#5=J6CO+?L($U$0I]\;D@-AD1=I?4RL_E^P\ -M/X0KY'##<@FNT=G+GT0C)\$Y]D-CP$M)3L@K+^Q%5>L>%_A=7[M(II9J,S2XWF),9GGVGZ>$;O"\;PG[F?A3=76)CW3!-#G?[KE-T -MQ0!.W)#$"9`UWF541I8D[,>(XVW2'&43=RS,^J3;=\+N(S$K9.!W88?IF6,I -M)R&DOC8*V_T\(\.3R-ZLB3EFE7YY/JD,\PM?F*F9J`A3L!NID=,P]- -MJLWUM&.]3^>1;IM/Z:RS;<(&-:^]_([0?`MT+FO(^^W0EIU<*H4;\:XA*?5< -M"GW)4"]=*<-E0^U<80!'K1"W&$%#'FFBZP2(5,>;NXX8P(1-; -MI&)4]0:#1)H'=;(:3JVSXR/)*L"8H7FX1RL0L=K.Q9^^A4^"42Q-A$3/!"]@ -M\"695?;MC./0WS%2T4+W;+90O"BT8>+[*&357+&3M% -MGMCD&9J\#\UICT>2BD(7CV<*[+1O*DGOG.^';D"],)3XRAR4YKO"ER>YOY>: -MCOU$P&.7H:'2]P"G-HRWU$6M5%RB.-C$N#;=3FMINHO/A3I1*SKH';=ZF!:* -M";_+Z9G+#N/U;"2'1/Q[2[>WDJ#NYK?7M@M:R/#@AT:B"8#)*<;XEL2#*>U# -M/TEZ>O@YH))CB$H?S`]5^R(D#4T8:+GS:K?3<-@*-WR9X[@XKM/6D;5)\%U0 -M?X1>(I@I\*V^MP?TUB)EUILFU)>?P4V2X!ZU)";\3ZY!-I[$7^FB]XLQJR63 -M/2A,UC:48/4!7*@VAI`U02=:38(BVY>IH?`VSB>.^DFP<3((AU'T%*4;B)DD -MKO$?_UL0.Y)RG,,HR\!E",K\MAS:UQGFXG+K+]T)YY7[81J^]G4,"TK",G,N&[?H/LP3'J;6V:H -MABH/%(:TS6&VV3W@1_(X;]-(?W3B6;J#9MB9JCPA1'D$Y1*AJ"7W-3/F,)P\ -MXI4_\9^8V94KFC2[O<+L['5Z3Y)B-[..*N8R1WH3X'6IZ^;AS5W[^/#V^OCN -MXO+H\H;^DYM-S+C80!^'E`S_U%X$3;,`,[=<39;9$41YXD=1:$MZ"+//UWHP -M3S-1(Q4(--]5<$-N$0FA6C1RKK6&?<`T/D05`MVK*L&KX\8S$8VKP`K -M;5':?#EPFSJ@R&LVZ>KX^IPG:;ZX_'1Q?+T=1%S=1%WM8F8PW+9]VY*:+6W0 -M%[@L-*9XOVKZCFZ0;]=D*<--%^=[N\&HMY$A*%X[Y>$E-:IK!393)"8(WHO4 -M,!.CDH3XB4F%%E/OU^5L-UA=IUY)G5J_E7"[R;WY8B,7'#V_D!?YA63M2FRC -MI`X;RX)Q"L/A;A^C2E62@/-H4B,=-C9%]27O0TI%EIAVYXO%`)!YOD^-O+!* -MLBA+4MG?609A!0\V6[W%2%$2KYDIE2"\D4T[FRBA0?0^$DM4SAAB`-(22#KK -MV)PXFH&0"?4DR?A;VW9J"&Z:Q#WA39R*L,.I"0C]@@L,'K!!DCR2X,J`-DWM -MV]RAAEP5C@MS??[\>7,K*\TE'SN#))QN*4KNEL?M[H;[^9-\73Q(W6MS@HX% -MCIUY@EFI92CL!T7M#2YYGIH\.XX8YQJI66:S^D.@_RH_:T,PLT^294D%62:O -M)AGEKJ6841F`C!B/OB8#/E-S0J+::`U45J@,%M0AO;-/M*N2&&<@?8>`C?.G -M,8&_B9:9EL+EJ:2,/64V/VN4UR#R;!N=!:LGO\)OYJY)%B/*%`>"FB=\'^/Q -MYI93ODI\!5G55N?AN<)$LF+-TH:E"%$2V9BGMJDLE%U.EF?BQ$BAF]J2U+(N -MNNCSTWI.(+E..JA+W>[&L\=UDSMO,\Y5!,$-%4N2>L6%+[_((6EC/D+"-GL_ -M&XYMA7U$[=7W;2A6:^?2%E67@('GIANL>NK+PP;BX3W7PE'1JU`GTP:^F)LA -M"`Y50L,4P@'7?1?Q%]7`V:#+PJ,8.N#N!$UD5E6SY\AY7>)S5NMI<4?VZ@>. -M])1O>#F;V^`[OU;V7\N"2XE$:8L^R-E$QF?/\7WO>C^&=0" -MNH8V/Z_UC%D-;@9,-D\<=+1N3!7$AE8TT@.*'$6`W.6,V6$[,)H6X?04_QO9P.ODLC -MI@`GUD_3#S3!1XNTNVD^%A,2#DZ'-F"48C&]YAFAOA<@WD08:*1^J4'SL -MC>PFJ[$^'X^9Z0'\FH`\>2Y38[U`+FCNW0PG0HWUM(;9'D:A@O$D^Q6;5QN7 -M2-T28L'IB'-5O3&I^<)R3%RT)N.N@0\E_.+XDU3U?XL_!S9D5:I7/TB(H-8D -MX*`@T!!-FFD]@YEZPDKU8T1W5,/U:#]F8S!1KCMX[;:EUZ777'"E8$#9!Y40S,*EFU+>;H1.4@:C="]==UHS9%K*/K@\^< -M&IEDO*47P=IF*UJJT?*%+>C\;#I^9L9A5@PE/@3Q0<9F*)HW\)H8A3SJF9J4 -M0&;B7+I'2UP:@?L%8E.)!1!,)E:%*E//E"G7HI+TJG4E\F65FS:GBB"WUOL_#'*H&QA<.16[9Z&H -MK#':L>ZP;X_34&,YTS<.%Y3J95P`4?S7RO:VQ>*%@:_"[\[):P4F5!.H<_DV -M(4D'!<\.GYZ>NO,6D!.KXCA70*0S]\K;7,$K4^NJ\Y27D4V=*AE#:EP!$(>G -MI72%AMS]WQ'`RR5I8.2PAEZ=659MZR$B'10%W8NK8IF-C2DY!U&NSF*Z)J%Z4FG?\5\2E&)A'^,4BWKE6.;4\7K#K\U(_%)_ -M-/L6C_;WZFDRFW3!O(A3CJ+ICNO@.7`*AOX>CW?H_Q?/2UPO1R&2B;G2;!#4 -MSG9J#W(5OFL^>O[^YBC)P9M2I8H5%"?13&2_1)B.J?9!-YHE`7$5!EJIU/RF -M&13G[[>*`]*G[BP-3J.XK]8T:V:!($#H-3`6*J=R7;9WW]-1/*B36M6)Z!8C -M\`MP=W;W=NA/;5X;QM.:4^D%GJ5))R(T'^T`5$:1]241]JT+TR8JROMVR7H# -M>A_2OGZ@JW9.HNMG9R9#^OP]-Q.H@8_39"S%0:&IK>=MLR".\F\-B%.3)#YQ -M'PUX=Q3J`U3FNA15Q/1^N8RO>?*"1$J6K/5_Z-\53$I7H#:0`HU'$!)%"6; -M^+B)7)0X6HN%N91:.WV.>'IE!M=[!HQE.JWO"6\''ZYJMY^W\1K.]V]$*;8# -MJ6;1MZ8M#BSHY2."_B]02P,$"@``````O'MF0>I8ZGT7````%P````@`'`!B -M=6EL9"YS:%54"0`#8ZZ84,8XFE!U>`L``03U`0``!!0````C(2]B:6XO`Q0````(`!*<9T$V32@KLU<``&H^`0`%`!@` -M``````$```"D@0````!F:6QE,%54!0`#Q#B:4'5X"P`!!/4!```$%````%!+ -M`0(>`PH``````+Q[9D'J6.I]%P```!<````(`!@```````$```#M@?)7``!B -M=6EL9"YS:%54!0`#8ZZ84'5X"P`!!/4!```$%````%!+!08``````@`"`)D` -M``!+6```M094:&ES(&ES(&$@FEP(&-O;6UE;G0N#0IA86%A -M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A -M86%A86%A86%A86%A86%A86%A86%A86%A86%A#0IA86%A86%A86%A86%A86%A -M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A -M86%A86%A86%A86%A86%A#0IA86%A86%A86%A86%A86%A86%A86%A86%A86%A -M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A -M86%A#0IA86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A -M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A#0IA86%A86%A -M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A -M86%A86%A86%A86%A86%A86%A86%A86%A#0IA86%A86%A86%A86%A86%A86%A -M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A -M86%A86%A86%A86%A#0IA86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A -M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A -M#0IA86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A -M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A#0IA86%A86%A86%A -M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A -M86%A86%A86%A86%A86%A86%A86%A#0IA86%A86%A86%A86%A86%A86%A86%A -M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A -M86%A86%A86%A#0IA86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A -M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A#0IA -M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A -M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A#0IA86%A86%A86%A86%A -M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A -M86%A86%A86%A86%A86%A86%A#0IV#0IA86%A86%A86%A86%A86%A86%A86%A -M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A -M86%A86%A86%A#0IA86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A -M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A#0IA -M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A -M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A#0IA86%A86%A86%A86%A -M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A -M86%A86%A86%A86%A86%A86%A#0IA86%A86%A86%A86%A86%A86%A86%A86%A -M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A -M86%A86%A#0IA86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A -M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A#0IA86%A -M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A -M86%A86%A86%A86%A86%A86%A86%A86%A86%A#0IA86%A86%A86%A86%A86%A -M86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A86%A -/86%A86%A86%A86%A86%A -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_encryption_data.c b/thirdparty/libarchive/libarchive/test/test_read_format_zip_encryption_data.c deleted file mode 100644 index b56d78e90..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_encryption_data.c +++ /dev/null @@ -1,79 +0,0 @@ -/*- - * Copyright (c) 2013 Konrad Kleine - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_read_format_zip_encryption_data) -{ - /* This file is password protected (encrypted). The headers - are NOT encrypted. Password is "12345678". */ - const char *refname = "test_read_format_zip_encryption_data.zip"; - struct archive_entry *ae; - struct archive *a; - char buff[128]; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - assertEqualIntA(a, ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW, archive_read_has_encrypted_entries(a)); - - /* Verify encrypted file "bar.txt" */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0664), archive_entry_mode(ae)); - assertEqualString("bar.txt", archive_entry_pathname(ae)); - assertEqualInt(20, archive_entry_size(ae)); - assertEqualInt(1, archive_entry_is_data_encrypted(ae)); - assertEqualInt(0, archive_entry_is_metadata_encrypted(ae)); - assertEqualIntA(a, 1, archive_read_has_encrypted_entries(a)); - assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, sizeof(buff))); - - /* Verify encrypted file "foo.txt" */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0664), archive_entry_mode(ae)); - assertEqualString("foo.txt", archive_entry_pathname(ae)); - assertEqualInt(20, archive_entry_size(ae)); - assertEqualInt(1, archive_entry_is_data_encrypted(ae)); - assertEqualInt(0, archive_entry_is_metadata_encrypted(ae)); - assertEqualIntA(a, 1, archive_read_has_encrypted_entries(a)); - assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, sizeof(buff))); - - assertEqualInt(2, archive_file_count(a)); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_encryption_data.zip.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_encryption_data.zip.uu deleted file mode 100644 index d419e7d6d..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_encryption_data.zip.uu +++ /dev/null @@ -1,25 +0,0 @@ -begin 664 test_read_format_zip_encryption_data.zip -M4$L#!#,`00```*UI,4/H*IFA5@$``!0````'````8F%R+G1X=!``2#/PIQFT -M*F$4U*$#L8[-?B`!```#`!!F``$!`)``[SL/J;#"+JV#-X^_V7R?(/NINR^)*Z@-`+PM+G'_/G,@= -MOQI>T\*I"7FDH^[+/([/S3(S=2JR^B1VT7NV=\PU*ILZ(S-9P@#K>HTK<9$X -MG?3>):QUHT4^7JY*;B_X.,6FCSB0]-;K-:!W"\9#7%JT`````(``I>M3N%RW -MKHT3'HV+V7'\SG*),5W`7P-"J01^*X5F-K&;`\FXL%S[!!"J1 -M?4B:)(8&4)C/_^4!TF+`7W`%52=)VJ9U?3H,W@"9S8062TGSY_<:.\=X_SCC -M1?,I!IE@=&J39?KX5+0Y\Y`;^.[MR@]TB?WG-.D/]RONSJ(6 -MMAL3^^^V;)?](;*EA#%$TN]?2U!+`P0S`$$```"J:3%#_\P&4E8!```4```` -M!P```&9O;RYT>'00`(N/OW)U+.F;D#0D]']<[0I5,5G^P3D\Q/LN'ME\GR#[J;LOB2NH -M#7-Y7/%J"13'@"\+2YQ_SYS(';\:7M/"J0EYI*/NRSR.S\TR,W4JLOHD=M%[ -MMG?,-2J;.B,S6<(`ZWJ-*W&1.)WTWB6L=:-%/EZN2FXO^#C%IH\XD/36ZS6@ -M=PO&0UQ:M`````"``".OX15'_!K.OGAW6+M]C;[G8@26,FBSB&/46Q@#[301 -M`"51%C)3[11_TP#)7O_6`&/F?FGG]G9;W.L$";H2&[ -ML$PNS#NDG9Q@BFL$`&S?S3;,D#OS#% -MZ>O6I=M41I^&XX"JLTTKLW]*B=+>(C]+6]H**#DX_EJ;9BBY;,=02P$"0``S -M`$$```"M:3%#Z"J9H58!```4````!P`T```````!`"``````````8F%R+G1X -M=`H`(````````0`8`".@Q.V6L\X!(Z#$[9:SS@$CH,3MEK/.`1<`#``"`!!F -M``$!``````!02P$"0``S`$$```"J:3%#_\P&4E8!```4````!P`T```````! -M`"````![`0``9F]O+G1X=`H`(````````0`8`"4C6.F6L\X!)2-8Z9:SS@$E -M(UCIEK/.`1<`#``"`!!F``$!``````!02P4&``````(``@#2````]@(````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_encryption_header.c b/thirdparty/libarchive/libarchive/test/test_read_format_zip_encryption_header.c deleted file mode 100644 index f40e1f5cb..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_encryption_header.c +++ /dev/null @@ -1,71 +0,0 @@ -/*- - * Copyright (c) 2013 Konrad Kleine - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_read_format_zip_encryption_header) -{ - /* This file is password protected (encrypted) with AES-256. The headers - ARE encrypted. Password is "12345678". */ - const char *refname = "test_read_format_zip_encryption_header.zip"; - struct archive_entry *ae; - struct archive *a; - char buff[128]; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - assertEqualIntA(a, ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW, archive_read_has_encrypted_entries(a)); - - /* Verify regular file but with encrypted headers - as a consequence, all meta information is invalid. */ - assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae)); - - assertEqualInt(0, archive_entry_mode(ae)); - assertEqualString(NULL, archive_entry_pathname(ae)); - assertEqualInt(0, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(1, archive_entry_is_data_encrypted(ae)); - assertEqualInt(1, archive_entry_is_metadata_encrypted(ae)); - assertEqualIntA(a, 1, archive_read_has_encrypted_entries(a)); - assertEqualInt(ARCHIVE_FATAL, archive_read_data(a, buff, sizeof(buff))); - - assertEqualInt(1, archive_file_count(a)); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_encryption_header.zip.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_encryption_header.zip.uu deleted file mode 100644 index 8ba23d322..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_encryption_header.zip.uu +++ /dev/null @@ -1,32 +0,0 @@ -begin 664 test_read_format_zip_encryption_header.zip -M4$L#!#,`02``````````````5@$````````!````,1``X3'*9,%K7_13)[I3 -MUO.*N2`!```#`!!F``$!`)``M'BJYI=VDZMXC4&]B1)Q%WJ/M`8VS -M%S*.0\5[MJ34[W"H8*AO==S@TG'S'J'3A;8C`````(``4-?ZX*L^`*0786KZ -ME7<\#%<[_`^#/MO"P\3FX5`^9`Q%(S:FDO98B*C`BC%'XQ0*X"FMO8[@3'S@ -MX(JO5(Q:8-&AM8(OPBY40\O!"%Z5'>I\/<_(AA-%)*TBI6YT6!WEM7L,-"W( -M/GE:7T.B39$3C.W)X2`A=KV-UB4C7I?6B-!F<"?VLE!+`P0S`$$@`````````````%8!`````````0```#(0 -M`%(U7N:0Z+,VS3SNJBRE_=`@`0```P`09@`!`0"0`+1XJN:7=I'+8EUNW[TZ -M9--K0QS.:Q+!FI.`8[!4$,6L*CF!QS:J1.BO`?`/13>YAU`IT$;$9 -M?;.\]/UPBB3_SV=KT;*]:?(9JYM:X+6&:R4J*4S0N)^KE,\XI>AO)H,GWNK> -M(U!O8D2<1=ZC[0&-LQ[:DU.]PJ&"H;W7CYF;:)G.8S3 -M%AT<])L+^"37+I@-S&ALBA\_10'AM,+6C"RP!FEV@VW1"2PDL->Q5HL*M[X( -M];^?-43F%4=UMP/U>83:C4K&OM*'&=DS[_V!*YK9X(6G9R,]GJ\\0`!A&@I%F4R!H=;RQSVWL,/D@ -M`0```P`09@`!`0"0`+1XJN:7=I'+8EUNW[TZ9--K0QS.:Q+!FI.`8[!4$,6L -M*CF!QS:J1.BO`?`/13>YAU`IT$;$9?;.\]/UPBB3_SV=KT;*]:?(9 -MJYM:X+6&:R4J*4S0N)^KE,\XI>AO)H,GWNK>(U!O8D2<1=ZC[0&-LQ[:DU.]PJ&"H;W7A2^EL1N!T3'%DP<< -MXY=DJB$8LS8KERBNN[I*X]M"?A\FYX"B`IP_XMQ-.*H3#`XY.,-K% -M0`Z%4:U*W#IM_DBOP-$^?R<8,!%#Z6F1`?;Z:=LG6@'C+#0I[]^+E$0'L5!+ -M!@9,`````````$``/@```````````````````````@````````"F`0`````` -M`.H"````````"`"F`0```````-(`````````$&8``0$``0`$``"$P.)02P8' -F`````)`$`````````0```%!+!08```````#__Z8!``#J`@`````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_encryption_partially.c b/thirdparty/libarchive/libarchive/test/test_read_format_zip_encryption_partially.c deleted file mode 100644 index 77af235d5..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_encryption_partially.c +++ /dev/null @@ -1,79 +0,0 @@ -/*- - * Copyright (c) 2013 Konrad Kleine - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_read_format_zip_encryption_partially) -{ - /* This file contains one file that is encrypted (foo.txt, password=12345678) - and one file that is not encrypted (bar.txt) The header is not encrypted - on this file. */ - const char *refname = "test_read_format_zip_encryption_partially.zip"; - struct archive_entry *ae; - struct archive *a; - char buff[128]; - - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - assertEqualIntA(a, ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW, archive_read_has_encrypted_entries(a)); - - /* Verify unencrypted file "bar.txt". */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0664), archive_entry_mode(ae)); - assertEqualString("bar.txt", archive_entry_pathname(ae)); - assertEqualInt(20, archive_entry_size(ae)); - assertEqualInt(0, archive_entry_is_data_encrypted(ae)); - assertEqualInt(0, archive_entry_is_metadata_encrypted(ae)); - assertEqualIntA(a, 1, archive_read_has_encrypted_entries(a)); - assertEqualInt(20, archive_read_data(a, buff, sizeof(buff))); - - /* Verify encrypted file "foo.txt". */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0664), archive_entry_mode(ae)); - assertEqualString("foo.txt", archive_entry_pathname(ae)); - assertEqualInt(20, archive_entry_size(ae)); - assertEqualInt(1, archive_entry_is_data_encrypted(ae)); - assertEqualInt(0, archive_entry_is_metadata_encrypted(ae)); - assertEqualIntA(a, 1, archive_read_has_encrypted_entries(a)); - assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, sizeof(buff))); - - assertEqualInt(2, archive_file_count(a)); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_encryption_partially.zip.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_encryption_partially.zip.uu deleted file mode 100644 index ac19d3133..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_encryption_partially.zip.uu +++ /dev/null @@ -1,18 +0,0 @@ -begin 664 test_read_format_zip_encryption_partially.zip -M4$L#!`H``````*UI,4/H*IFA%````!0````'````8F%R+G1X=")D871A(&]F -M(&)A'0B(`T*4$L#!#,`00```*II,4/_S`925@$``!0````'````9F]O -M+G1X=!``=Y31BJ>9'GG$*/<^F6_&OGLZO5E%/W5NJ591,`8BB:/5/7M)AK8/IJ0=@ -M`````(``QS1<"+$&V4,T_.3PQ&HBEXWEA;,\K(U'9+L4P -M=:(P%7DH*U7(2#M.IB;M\7X??Y!F]%PMN<#((2`+)9A+<(W[1K0X@&5:`QJV -MQ:NR:QT5U'+D!K^/_N*M>SJ-)-^@^N6]4VD&Z@L#X(!-7@-6#-G3WV`1:PL" -M!4FWNU]+#`:$,2UI5U`@#@BY.)#$HP6(2`PH``````"-=CTW$\L?V`@````(````! -M`!@```````$```"D@0````!A`````%54"0`#TE@57-M8%5P```0``````$L% -3!@`````!``$`1P```#T````````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_filename.c b/thirdparty/libarchive/libarchive/test/test_read_format_zip_filename.c deleted file mode 100644 index 4dd2e8ad6..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_filename.c +++ /dev/null @@ -1,1224 +0,0 @@ -/*- - * Copyright (c) 2011 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD"); - -#include - -DEFINE_TEST(test_read_format_zip_filename_CP932_eucJP) -{ - const char *refname = "test_read_format_zip_filename_cp932.zip"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read CP932 filename in ja_JP.eucJP with "hdrcharset=CP932" option. - */ - if (NULL == setlocale(LC_ALL, "ja_JP.eucJP")) { - skipping("ja_JP.eucJP locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP932")) { - skipping("This system cannot convert character-set" - " from CP932 to eucJP."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString( - "\xc9\xbd\xa4\xc0\xa4\xe8\x2f\xb0\xec\xcd\xf7\xc9\xbd\x2e\x74\x78\x74", - archive_entry_pathname(ae)); - assertEqualInt(5, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString( - "\xc9\xbd\xa4\xc0\xa4\xe8\x2f\xb4\xc1\xbb\xfa\x2e\x74\x78\x74", - archive_entry_pathname(ae)); - assertEqualInt(5, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_filename_CP932_UTF8) -{ - const char *refname = "test_read_format_zip_filename_cp932.zip"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read CP932 filename in en_US.UTF-8 with "hdrcharset=CP932" option. - */ - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("en_US.UTF-8 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP932")) { - skipping("This system cannot convert character-set" - " from CP932 to UTF-8."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); -#if defined(__APPLE__) - /* Compare NFD string. */ - assertEqualUTF8String( - "\xe8\xa1\xa8\xe3\x81\x9f\xe3\x82\x99\xe3\x82\x88\x2f" - "\xe4\xb8\x80\xe8\xa6\xa7\xe8\xa1\xa8\x2e\x74\x78\x74", - archive_entry_pathname(ae)); -#else - /* Compare NFC string. */ - assertEqualUTF8String( - "\xe8\xa1\xa8\xe3\x81\xa0\xe3\x82\x88\x2f" - "\xe4\xb8\x80\xe8\xa6\xa7\xe8\xa1\xa8\x2e\x74\x78\x74", - archive_entry_pathname(ae)); -#endif - assertEqualInt(5, archive_entry_size(ae)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); -#if defined(__APPLE__) - /* Compare NFD string. */ - assertEqualUTF8String( - "\xe8\xa1\xa8\xe3\x81\x9f\xe3\x82\x99\xe3\x82\x88\x2f" - "\xe6\xbc\xa2\xe5\xad\x97\x2e\x74\x78\x74", - archive_entry_pathname(ae)); -#else - /* Compare NFC string. */ - assertEqualUTF8String( - "\xe8\xa1\xa8\xe3\x81\xa0\xe3\x82\x88\x2f" - "\xe6\xbc\xa2\xe5\xad\x97\x2e\x74\x78\x74", - archive_entry_pathname(ae)); -#endif - assertEqualInt(5, archive_entry_size(ae)); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_filename_UTF8_eucJP) -{ - const char *refname = "test_read_format_zip_filename_utf8_jp.zip"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read UTF-8 filename in ja_JP.eucJP without charset option - * because the file name in the sample file is UTF-8 and - * Bit 11 of its general purpose bit flag is set. - */ - if (NULL == setlocale(LC_ALL, "ja_JP.eucJP")) { - skipping("ja_JP.eucJP locale not availablefilename_ on " - "this system."); - return; - } - extract_reference_file(refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=UTF-8")) { - skipping("This system cannot convert character-set" - " from UTF-8 to eucJP."); - goto cleanup; - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify directory file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualString("\xc9\xbd\xa4\xc0\xa4\xe8\x2f", - archive_entry_pathname(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualString( - "\xc9\xbd\xa4\xc0\xa4\xe8\x2f\xb0\xec\xcd\xf7\xc9\xbd\x2e\x74\x78\x74", - archive_entry_pathname(ae)); - assertEqualInt(5, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualString( - "\xc9\xbd\xa4\xc0\xa4\xe8\x2f\xb4\xc1\xbb\xfa\x2e\x74\x78\x74", - archive_entry_pathname(ae)); - assertEqualInt(5, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_filename_UTF8_UTF8) -{ - const char *refname = "test_read_format_zip_filename_utf8_jp.zip"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read UTF-8 filename in en_US.UTF-8 without charset option - * because the file name in the sample file is UTF-8 and - * Bit 11 of its general purpose bit flag is set. - */ - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("en_US.UTF-8 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify directory file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); -#if defined(__APPLE__) - /* Compare NFD string. */ - assertEqualUTF8String( - "\xe8\xa1\xa8\xe3\x81\x9f\xe3\x82\x99\xe3\x82\x88\x2f", - archive_entry_pathname(ae)); -#else - /* Compare NFC string. */ - assertEqualUTF8String( - "\xe8\xa1\xa8\xe3\x81\xa0\xe3\x82\x88\x2f", - archive_entry_pathname(ae)); -#endif - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); -#if defined(__APPLE__) - /* Compare NFD string. */ - assertEqualUTF8String( - "\xe8\xa1\xa8\xe3\x81\x9f\xe3\x82\x99\xe3\x82\x88\x2f" - "\xe4\xb8\x80\xe8\xa6\xa7\xe8\xa1\xa8\x2e\x74\x78\x74", - archive_entry_pathname(ae)); -#else - /* Compare NFC string. */ - assertEqualUTF8String( - "\xe8\xa1\xa8\xe3\x81\xa0\xe3\x82\x88\x2f" - "\xe4\xb8\x80\xe8\xa6\xa7\xe8\xa1\xa8\x2e\x74\x78\x74", - archive_entry_pathname(ae)); -#endif - assertEqualInt(5, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); -#if defined(__APPLE__) - /* Compare NFD string. */ - assertEqualUTF8String( - "\xe8\xa1\xa8\xe3\x81\x9f\xe3\x82\x99\xe3\x82\x88\x2f" - "\xe6\xbc\xa2\xe5\xad\x97\x2e\x74\x78\x74", - archive_entry_pathname(ae)); -#else - /* Compare NFC string. */ - assertEqualUTF8String( - "\xe8\xa1\xa8\xe3\x81\xa0\xe3\x82\x88\x2f" - "\xe6\xbc\xa2\xe5\xad\x97\x2e\x74\x78\x74", - archive_entry_pathname(ae)); -#endif - assertEqualInt(5, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_filename_CP866_KOI8R) -{ - const char *refname = "test_read_format_zip_filename_cp866.zip"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read CP866 filename in ru_RU.KOI8-R with "hdrcharset=CP866" option. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia.20866") && - NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) { - skipping("ru_RU.KOI8-R locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) { - skipping("This system cannot convert character-set" - " from CP866 to KOI8-R."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xf0\xf2\xe9\xf7\xe5\xf4", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\xd2\xc9\xd7\xc5\xd4", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_filename_CP866_UTF8) -{ - const char *refname = "test_read_format_zip_filename_cp866.zip"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read CP866 filename in en_US.UTF-8 with "hdrcharset=CP866" option. - */ - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("en_US.UTF-8 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) { - skipping("This system cannot convert character-set" - " from CP866 to UTF-8."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_filename_KOI8R_CP866) -{ - const char *refname = "test_read_format_zip_filename_koi8r.zip"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read KOI8-R filename in ru_RU.CP866 with "hdrcharset=KOI8-R" option. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia.866") && - NULL == setlocale(LC_ALL, "ru_RU.CP866")) { - skipping("ru_RU.CP866 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) { - skipping("This system cannot convert character-set" - " from KOI8-R to CP866."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xaf\xe0\xa8\xa2\xa5\xe2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\x8f\x90\x88\x82\x85\x92", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_filename_KOI8R_UTF8) -{ - const char *refname = "test_read_format_zip_filename_koi8r.zip"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read KOI8-R filename in en_US.UTF-8 with "hdrcharset=KOI8-R" option. - */ - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("en_US.UTF-8 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) { - skipping("This system cannot convert character-set" - " from KOI8-R to UTF-8."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_filename_UTF8_KOI8R) -{ - const char *refname = "test_read_format_zip_filename_utf8_ru.zip"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read UTF-8 filename in ru_RU.KOI8-R with "hdrcharset=UTF-8" option. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia.20866") && - NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) { - skipping("ru_RU.KOI8-R locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=UTF-8")) { - skipping("This system cannot convert character-set" - " from UTF-8 to KOI8-R."); - goto cleanup; - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* Re-create a read archive object. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xf0\xf2\xe9\xf7\xe5\xf4", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\xd2\xc9\xd7\xc5\xd4", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_filename_UTF8_CP866) -{ - const char *refname = "test_read_format_zip_filename_utf8_ru.zip"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read UTF-8 filename in ru_RU.CP866 without charset option - * because the file name in the sample file is UTF-8 and - * Bit 11 of its general purpose bit flag is set. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia.866") && - NULL == setlocale(LC_ALL, "ru_RU.CP866")) { - skipping("ru_RU.CP866 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=UTF-8")) { - skipping("This system cannot convert character-set" - " from UTF-8 to CP866."); - goto cleanup; - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* Re-create a read archive object. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\x8f\x90\x88\x82\x85\x92", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xaf\xe0\xa8\xa2\xa5\xe2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_filename_UTF8_UTF8_ru) -{ - const char *refname = "test_read_format_zip_filename_utf8_ru.zip"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read UTF-8 filename in en_US.UTF-8 without charset option - * because the file name in the sample file is UTF-8 and - * Bit 11 of its general purpose bit flag is set. - */ - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("en_US.UTF-8 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_filename_CP932_CP932) -{ - const char *refname = "test_read_format_zip_filename_cp932.zip"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read CP932 filename in CP932/SJIS with "hdrcharset=CP932" option. - */ - if (NULL == setlocale(LC_ALL, "Japanese_Japan") && - NULL == setlocale(LC_ALL, "ja_JP.SJIS")) { - skipping("CP932 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP932")) { - skipping("This system cannot convert character-set" - " from CP932."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString( - "\x95\x5c\x82\xbe\x82\xe6\x2f\x88\xea\x97\x97\x95\x5c.txt", - archive_entry_pathname(ae)); - assertEqualInt(5, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString( - "\x95\x5c\x82\xbe\x82\xe6\x2f\x8a\xbf\x8e\x9a.txt", - archive_entry_pathname(ae)); - assertEqualInt(5, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_filename_UTF8_CP932) -{ - const char *refname = "test_read_format_zip_filename_utf8_jp.zip"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read UTF-8 filename in CP932/SJIS without charset option - * because the file name in the sample file is UTF-8 and - * Bit 11 of its general purpose bit flag is set. - */ - if (NULL == setlocale(LC_ALL, "Japanese_Japan") && - NULL == setlocale(LC_ALL, "ja_JP.SJIS")) { - skipping("CP932 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=UTF-8")) { - skipping("This system cannot convert character-set" - " from UTF-8 to CP932."); - goto cleanup; - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* Re-create a read archive object. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); - assertEqualString( - "\x95\x5c\x82\xbe\x82\xe6\x2f", - archive_entry_pathname(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Verify directory file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualString( - "\x95\x5c\x82\xbe\x82\xe6\x2f\x88\xea\x97\x97\x95\x5c.txt", - archive_entry_pathname(ae)); - assertEqualInt(5, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualString( - "\x95\x5c\x82\xbe\x82\xe6\x2f\x8a\xbf\x8e\x9a.txt", - archive_entry_pathname(ae)); - assertEqualInt(5, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_filename_CP866_CP1251) -{ - const char *refname = "test_read_format_zip_filename_cp866.zip"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read CP866 filename in CP1251 with "hdrcharset=CP866" option. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia") && - NULL == setlocale(LC_ALL, "ru_RU.CP1251")) { - skipping("CP1251 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) { - skipping("This system cannot convert character-set" - " from CP866 to CP1251."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* - * This test only for Windows platform because other archiver - * applications on Windows translate CP1251 filenames into CP866 - * filenames and store it in the zip file and so we should read - * it by default on Windows. - */ -DEFINE_TEST(test_read_format_zip_filename_CP866_CP1251_win) -{ - const char *refname = "test_read_format_zip_filename_cp866.zip"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read CP866 filename in CP1251 without "hdrcharset=CP866" option. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia")) { - skipping("Russian_Russia locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_filename_KOI8R_CP1251) -{ - const char *refname = "test_read_format_zip_filename_koi8r.zip"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read KOI8-R filename in CP1251 with "hdrcharset=KOI8-R" option. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia") && - NULL == setlocale(LC_ALL, "ru_RU.CP1251")) { - skipping("CP1251 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) { - skipping("This system cannot convert character-set" - " from KOI8-R to CP1251."); - goto cleanup; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_filename_UTF8_CP1251) -{ - const char *refname = "test_read_format_zip_filename_utf8_ru.zip"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read UTF-8 filename in CP1251 without charset option - * because the file name in the sample file is UTF-8 and - * Bit 11 of its general purpose bit flag is set. - */ - if (NULL == setlocale(LC_ALL, "Russian_Russia") && - NULL == setlocale(LC_ALL, "ru_RU.CP1251")) { - skipping("CP1251 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=UTF-8")) { - skipping("This system cannot convert character-set" - " from UTF-8 to CP1251."); - goto cleanup; - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* Re-create a read archive object. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -cleanup: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* - * The sample zip file was made in LANG=KOI8-R and it contains two - * files the charset of which are different. - * - the filename of first file is stored in KOI8-R. - * - the filename of second file is stored in UTF-8. - * - * Whenever hdrcharset option is specified, we will correctly read the - * filename of second file, which is stored in UTF-8. - */ - -DEFINE_TEST(test_read_format_zip_filename_KOI8R_UTF8_2) -{ - const char *refname = "test_read_format_zip_filename_utf8_ru2.zip"; - struct archive *a; - struct archive_entry *ae; - - /* - * Read filename in en_US.UTF-8 with "hdrcharset=KOI8-R" option. - */ - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("en_US.UTF-8 locale not available on this system."); - return; - } - extract_reference_file(refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) { - skipping("This system cannot convert character-set" - " from KOI8-R to UTF-8."); - goto next_test; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* Verify regular first file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* - * Verify regular second file. - * The filename is not translated because Bit 11 of its general - * purpose bit flag is set and so we know the conversion is unneeded. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -next_test: - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Read filename in en_US.UTF-8 without "hdrcharset=KOI8-R" option. - * The filename we can properly read is only second file. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - /* - * Verify regular first file. - * The filename is not translated to UTF-8 because Bit 11 of - * its general purpose bit flag is *not* set and so there is - * not way to know its charset. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - /* A filename is in KOI8-R. */ - assertEqualString("\xf0\xf2\xe9\xf7\xe5\xf4", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Verify regular file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82", - archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_filename_cp866.zip.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_filename_cp866.zip.uu deleted file mode 100644 index 52c677060..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_filename_cp866.zip.uu +++ /dev/null @@ -1,10 +0,0 @@ -begin 644 test_read_format_zip_cp866.zip -M4$L#!`H``````%VEAS[,X8$4!@````8````&`!P`CY"(@H62550)``-!HYU- -M0:.=375X"P`!!.D#```$Z0,``/#RZ??E]%!+`P0*``````!=I8<^S.&!%`8` -M```&````!@`<`*_@J**EXE54"0`#0:.=34&CG4UU>`L``03I`P``!.D#``#P -M\NGWY?102P$"'@,*``````!=I8<^S.&!%`8````&````!@`8```````!```` -M[8$`````CY"(@H62550%``-!HYU-=7@+``$$Z0,```3I`P``4$L!`AX#"@`` -M````7:6'/LSA@10&````!@````8`&````````0```.V!1@```*_@J**EXE54 -L!0`#0:.=375X"P`!!.D#```$Z0,``%!+!08``````@`"`)@```",```````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_filename_cp932.zip.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_filename_cp932.zip.uu deleted file mode 100644 index 90c22f2d5..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_filename_cp932.zip.uu +++ /dev/null @@ -1,9 +0,0 @@ -begin 644 test_read_format_zip_cp932.zip -M4$L#!`H``````/94=#Z"B='W!0````4````1````E5R"OH+F+XCJEY>57"YT -M>'1(96QL;U!+`P0*``````"W5'0^W)UO0@4````%````#P```)5<@KZ"YB^* -MOXZ:+G1X=&MA;FII4$L!`A0+"@``````]E1T/H*)T?<%````!0```!$````` -M`````0`@`````````)5<@KZ"YB^(ZI>7E5PN='AT4$L!`A0+"@``````MU1T -M/MR=;T(%````!0````\``````````0`@````-````)5<@KZ"YB^*OXZ:+G1X -7=%!+!08``````@`"`'P```!F```````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_filename_koi8r.zip.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_filename_koi8r.zip.uu deleted file mode 100644 index 05c669560..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_filename_koi8r.zip.uu +++ /dev/null @@ -1,10 +0,0 @@ -begin 644 test_read_format_zip_koi8r.zip -M4$L#!`H``````+&CAS[,X8$4!@````8````&`!P`T-+)U\74550)``,>H)U- -M'J"=375X"P`!!.D#```$Z0,``/#RZ??E]%!+`P0*``````"QHX<^S.&!%`8` -M```&````!@`<`/#RZ??E]%54"0`#'J"=31Z@G4UU>`L``03I`P``!.D#``#P -M\NGWY?102P$"'@,*``````"QHX<^S.&!%`8````&````!@`8```````!```` -M[8$`````T-+)U\74550%``,>H)U-=7@+``$$Z0,```3I`P``4$L!`AX#"@`` -M````L:.'/LSA@10&````!@````8`&````````0```.V!1@```/#RZ??E]%54 -L!0`#'J"=375X"P`!!.D#```$Z0,``%!+!08``````@`"`)@```",```````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_filename_utf8_jp.zip.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_filename_utf8_jp.zip.uu deleted file mode 100644 index 00c2af337..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_filename_utf8_jp.zip.uu +++ /dev/null @@ -1,15 +0,0 @@ -begin 644 test_read_format_zip_utf8.zip -M4$L#!`H```@``,E4=#X````````````````*`!P`Z*&HXX&@XX*(+U54"0`# -MBEJ%3;[UBDUU>`L``03M`P``!`$"``!02P,$"@``"```]51T/H*)T?<%```` -M!0```!<`'`#HH:CC@:#C@H@OY+B`Z*:GZ*&H+G1X=%54"0`#WEJ%31KLBDUU -M>`L``03M`P``!`$"``!(96QL;U!+`P0*```(``"V5'0^W)UO0@4````%```` -M%``<`.BAJ..!H.."B"_FO*+EK9`L``03M`P``!`$" -M``!02P$"'@,*```(``#U5'0^@HG1]P4````%````%P`8```````!````[8%$ -M````Z*&HXX&@XX*(+^2X@.BFI^BAJ"YT>'155`4``]Y:A4UU>`L``03M`P`` -M!`$"``!02P$"'@,*```(``"V5'0^W)UO0@4````%````%``8```````!```` -M[8&:````Z*&HXX&@XX*(+^:\HN6MERYT>'155`4``VA:A4UU>`L``03M`P`` -;!`$"``!02P4&``````,``P`'`0``[0`````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_filename_utf8_ru.zip.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_filename_utf8_ru.zip.uu deleted file mode 100644 index 9241776d7..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_filename_utf8_ru.zip.uu +++ /dev/null @@ -1,11 +0,0 @@ -begin 644 test_read_format_zip_utf8_ru.zip -M4$L#!`H```@``,NC/S[,X8$4!@````8````,`!P`T)_0H-"8T)+0E="B550) -M``-.G49-'J"=375X"P`!!.D#```$Z0,``/#RZ??E]%!+`P0*```(``!KI3\^ -MS.&!%`8````&````#``<`-"_T8#0N-"RT+71@E54"0`#6J!&31Z@G4UU>`L` -M`03I`P``!.D#``#P\NGWY?102P$"'@,*```(``#+HS\^S.&!%`8````&```` -M#``8```````!````[8$`````T)_0H-"8T)+0E="B550%``-.G49-=7@+``$$ -MZ0,```3I`P``4$L!`AX#"@``"```:Z4_/LSA@10&````!@````P`&``````` -M`0```.V!3````-"_T8#0N-"RT+71@E54!0`#6J!&375X"P`!!.D#```$Z0,` -7`%!+!08``````@`"`*0```"8```````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_filename_utf8_ru2.zip.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_filename_utf8_ru2.zip.uu deleted file mode 100644 index 651f8b1f8..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_filename_utf8_ru2.zip.uu +++ /dev/null @@ -1,11 +0,0 @@ -begin 644 test_read_format_zip_utf8_ru2.zip -M4$L#!`H``````.:PCC[,X8$4!@````8````&`!P`\/+I]^7T550)``.`\:9- -MI6>G375X"P`!!.D#```$Z0,``/#RZ??E]%!+`P0*```(``!KI3\^S.&!%`8` -M```&````#``<`-"_T8#0N-"RT+71@E54"0`#6J!&357SIDUU>`L``03I`P`` -M!.D#``#P\NGWY?102P$"'@,*``````#FL(X^S.&!%`8````&````!@`8```` -M```!````[8$`````\/+I]^7T550%``.`\:9-=7@+``$$Z0,```3I`P``4$L! -M`AX#"@``"```:Z4_/LSA@10&````!@````P`&````````0```.V!1@```-"_ -MT8#0N-"RT+71@E54!0`#6J!&375X"P`!!.D#```$Z0,``%!+!08``````@`" -+`)X```"2```````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_high_compression.c b/thirdparty/libarchive/libarchive/test/test_read_format_zip_high_compression.c deleted file mode 100644 index 16cfbb182..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_high_compression.c +++ /dev/null @@ -1,153 +0,0 @@ -/*- - * Copyright (c) 2016 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD"); - -#include - - -/* - * Github Issue 748 reported problems with end-of-entry handling - * with highly-compressible data. This resulted in the end of the - * data being truncated (extracted as zero bytes). - */ - -/* - * Extract the specific test archive that was used to diagnose - * Issue 748: - */ -DEFINE_TEST(test_read_format_zip_high_compression) -{ - const char *refname = "test_read_format_zip_high_compression.zip"; - char *p; - size_t archive_size; - struct archive *a; - struct archive_entry *entry; - - const void *pv; - size_t s; - int64_t o; - - if (archive_zlib_version() == NULL) { - skipping("Zip compression test requires zlib"); - return; - } - - extract_reference_file(refname); - p = slurpfile(&archive_size, "%s", refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, archive_size, 16 * 1024)); - assertEqualInt(ARCHIVE_OK, archive_read_next_header(a, &entry)); - - assertEqualInt(ARCHIVE_OK, archive_read_data_block(a, &pv, &s, &o)); - assertEqualInt(262144, s); - assertEqualInt(0, o); - - assertEqualInt(ARCHIVE_OK, archive_read_data_block(a, &pv, &s, &o)); - assertEqualInt(160, s); - assertEqualInt(262144, o); - - assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &pv, &s, &o)); - - assertEqualInt(ARCHIVE_OK, archive_free(a)); - free(p); -} - -/* - * Synthesize a lot of varying inputs that are highly compressible. - */ -DEFINE_TEST(test_read_format_zip_high_compression2) -{ - const size_t body_size = 1024 * 1024; - const size_t buff_size = 2 * 1024 * 1024; - char *body, *body_read, *buff; - int n; - - if (archive_zlib_version() == NULL) { - skipping("Zip compression test requires zlib"); - return; - } - - assert((body = malloc(body_size)) != NULL); - assert((body_read = malloc(body_size)) != NULL); - assert((buff = malloc(buff_size)) != NULL); - - /* Highly-compressible data: all bytes 255, except for a - * single 1 byte. - * The body is always 256k + 6 bytes long (the internal deflation - * buffer is exactly 256k). - */ - - for(n = 1024; n < (int)body_size; n += 1024) { - struct archive *a; - struct archive_entry *entry; - size_t used = 0; - const void *pv; - size_t s; - int64_t o; - - memset(body, 255, body_size); - body[n] = 1; - - /* Write an archive with a single entry of n bytes. */ - assert((a = archive_write_new()) != NULL); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualInt(ARCHIVE_OK, archive_write_open_memory(a, buff, buff_size, &used)); - - entry = archive_entry_new2(a); - archive_entry_set_pathname(entry, "test"); - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 262150); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(262150, archive_write_data(a, body, 262150)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Read back the entry and verify the contents. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, used, 17)); - assertEqualInt(ARCHIVE_OK, archive_read_next_header(a, &entry)); - - assertEqualInt(ARCHIVE_OK, archive_read_data_block(a, &pv, &s, &o)); - assertEqualInt(262144, s); - assertEqualInt(0, o); - - assertEqualInt(ARCHIVE_OK, archive_read_data_block(a, &pv, &s, &o)); - assertEqualInt(6, s); - assertEqualInt(262144, o); - - assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &pv, &s, &o)); - - assertEqualInt(ARCHIVE_OK, archive_free(a)); - } - - free(body); - free(body_read); - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_high_compression.zip.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_high_compression.zip.uu deleted file mode 100644 index 094288033..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_high_compression.zip.uu +++ /dev/null @@ -1,18 +0,0 @@ -begin 644 test_read_format_zip_high_compression.zip -M4$L#!!0`"``(`*=Y]4@``````````*``!``(`"``8VAA -MD5>>))%7GB215W5X"P`!!/8!```$%````.W=06K#,!`%T&E)P8LL?*2XC@N% -M)#5QO>AM@9WDJ6!%\6$K/Q6T3LAX]N/GQ'Z9G&KA^*K1'S -M.`[GOIM*[TP_Q_>O0[G_:3X.Y\^^V/X2<>))%7=7@+``$$]@$```04````4$L%!@`````!``$`5@````L"```` -!```` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_jar.c b/thirdparty/libarchive/libarchive/test/test_read_format_zip_jar.c deleted file mode 100644 index 912e67137..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_jar.c +++ /dev/null @@ -1,59 +0,0 @@ -/*- - * Copyright (c) 2016 Peter Wu - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* - * Issue 822: jar files have an empty External File Attributes field which - * is misinterpreted as regular file type due to OS MS-DOS. - */ - -DEFINE_TEST(test_read_format_zip_jar) -{ - const char *refname = "test_read_format_zip_jar.jar"; - char *p; - size_t s; - struct archive *a; - struct archive_entry *ae; - char data[16]; - - extract_reference_file(refname); - p = slurpfile(&s, "%s", refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip_seekable(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 1)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("somedir/", archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR | 0775, archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualIntA(a, 0, archive_read_data(a, data, 16)); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); - free(p); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_jar.jar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_jar.jar.uu deleted file mode 100644 index 0778c9315..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_jar.jar.uu +++ /dev/null @@ -1,6 +0,0 @@ -begin 640 test_read_format_zip_jar.jar -M4$L#! H @ $AQETD ( 0 `Q0`"``(`,NJ,C\@,#HV"`````8````)`!@```````$```"D@0`` -M``!H96QL;RYT>'155`4``W[#=DYU>`L``03U`0``!!0```!02P4&``````$` -,`0!/````6P`````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_lzma.zipx.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_lzma.zipx.uu deleted file mode 100644 index 24fdc8e7c..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_lzma.zipx.uu +++ /dev/null @@ -1,19 +0,0 @@ -begin 644 lzma.zipx -M4$L#!#\#```.`#TQD4VJ.XZZ.0(``)`#```%````=FEM)82Q1PWAL -M+U`,N0L_$]^&650C/X$D6#4QFD$\A/"_![4!O/5O/!KH`WCQ*4?T2*]4P#/D -M0'9I?EZG=N69Z0V;H0I=CP*$?".I\ -MGMG/80.A'^W>R4J'S/CZ%P`8`>F=R>R&R$2T@EM#X)"OQH1?A7,`:4IU9WV! -M#2W*DXT',;.4YIN4A:-X)O=IREL201ZSOC=YSAU[C4-::/YV8\)%"L17+>VC -M%/'B]ZCQN$2(Q*9*\KJZ`Y131`]5C&G';@1S-QES_RZF!2OX45@58+??ES%( -MUJ<(\`11M$NO)HK#/MK-9RT"15.2I:IZN8VTM1_?$G\L#BH67]$S%[4 -M%C-$\Q<+./&HV](4,7)OL-@C^M0F"2O!0N$OHOW54H87^QLBQVH*D%A<#SI% -M/#+-5U(W';:KC)RE>0Y^5YI!RECQNR"R4.UW9IR!@:B!UB8?_D5$FT8YCJHJ -M2[2"-&-_D2BJ6#XK[6G=%K"%;'^-+0]FHCY4ER#`^-]>-A`H``"L:```+````?C+)VT(T,`U9;I1/'N)!6C.3M-O9LO]H<^=OZF\ -MXD\QEZIMP!JM4)W+(F]%N;U#&+F]WZ%S9>>]&^75:X)0Q-5>)IRT/%INC887 -ML0UF,PS8J@3;WGH95EW4\KBH,6ZK9,'![3$-(WL/C<[0.6%L9@]0;]_>&[A'#Q^##`6+*PM@YT+]E[B9 -M;QK38:)CO+S]4X2KF'=)BVO-GM+_#]PB0'*J89+$Q11IG\\+84M](58^RW.E -MGM3S6RH]#73P.KV0V,2=,/A!;G>2Y4R!!.4(0U+D<.'5V*%./ZZYD")=W4*4 -M\SL"IUJLN])WM`-&4L&!9&U_-1%%SPU0N4*.^L5&33"A5MZ;@8F+I^D7JB'K -ME&,P>"UI]NT;ZX`UU->]V$?KZV(DX&-6L>? -ME,(J<;DNA6/2.<9$>?-P]_!S8L3/2P@[C'H$FOA$WUOB>;X$)E7;K+7#X9M( -MM+H^AK#CML0LXTO#P#I)J_5"@O -MMGH9+OXD^P7AG@<%QGH<>FIWE]/>L)6Q2Q\CC=[?TCG262"1EO)'_W_C_K4< -M8.7YNR"3\9WTQ"0-!>^,M>WT.Y0A&3AK.4/YN5EW]"&HQ1=8Q-NHQABVH7$% -M24Q:J/<8%F1EI)-!HND&FP_;]E,JI$*AGE&]Y#FJ5R6<(UM;;>U?KU@OQ,M_ -MI/+:;0^0'8JA"==H5/;]Y10P&PS,1_M+D1I>`%>_Y\&F[_R/##784#0AQ1!O -M'8>IBY?;&;(VAOI$+Z[VMI>]WC!['W$&Z5/D+"6["[[.[P!/?9C/;CD66^J/OC) -MO0JXP'Y6]PGW8N@X(#-XXWMP"A%E$A8L+X>QIC[0P,UT0A!IYQ/#+>E60KX/ -M2JC'F-Z@_,-/$7+F5F$1\#^"CTSY;H2EAE,/8>F$^'5H!M2@D?2O@+NJ2&-O -M6IV-[<6F-JG0(,W-YJ%PJ<7T.F")'/+F_`F6B-HG436 -MJM-VK0?>9*R?K#]OHC90!]BCG'^D&%!JZ2T_&[RWV?0Z?T:#_\B`?:MRC$D5 -M1Z.)!/;3/=GT*T;DC/XLR;7S%VEP+U-M)-*V,1?M<377S9-`J]S4[OI4SR>V -M_?_H2WWH>\@*$V@`LZO?-'Z[4_4"T2R@=%! -M!\1]:4M((1B=ATAJ)23HE7>]=,7I#SK5'2OUZLX0LX*_67!+6S:*0UL)^GS6 -MM;$2!(-TY%4ME1>*'M)S'[0JP^&J%"-&A[C1YE;1:X_4Y&K9*2 -M'14NC*]O(JXNLX#M_(LDE6$G<0,+V/;44]-*^S%7G*.\$W&>2=9,EYB)/@XK -MX+E4?>NIP=*X]Z>3T,V?!"5:/M@X-H%DZEV,*9WIK;T_C18UC5$%^Z5PY8;USNB?S]`D-K2V2 -M-C#0-45C'YFF>#*$9JZ!$>%0;=VQ@LGY"J<.C.10"1'JL^B(VXPNK^]Q97E\`HX0MG2)F=>38R,IFGK\R -MVH!.V3_)_D,II8A=SL;X1!2D9E67=.$P+_D6&'X^1;4%:`ERV>!,''7<#=NE -MP')[\,A89G35\;ZN:IIY5DDSB$(8D$[G>7-L!(+(-7=LQ0Q3=S`L-)R9YT;S -M;%ZYVD%6)M=I]*QS>!3='"SB'E/4>J#EQ.&]0*U0H/Y1%DM].)E/UFD0?Q)B;_;;)-K_]6Z<)D_>^[=?49%4D4B@REC` -M,_KU,KX-N,44CL/:*^D>7X(;6_1&C;<;&`K3+4NY[=4%K2K:U"Q%T9)',7," -M+PC``PBBDVNY9V-LN'V')B4@4;OH(\/M%UBX$S."4_!;&=9W\L`!2O\!ANM5 -M8+""#5J&/M[2;M?47WN=0[4C*$7D#QB&`!*@5_0 -M9(5SZ7,Q"N?0W!\0WGQF,0JKH[G-(<6^PMJZV&VHQIT?VKJ^7^!EW?)`EC`$ -M0%,=?X0ME@T_&5UXJIJ9)5(<[=W]M#Y.$.96:_T8WM/H+"T_Q;QZN"`5DC&' -M.+(^")0XO=#&#@KVL2R9+.#F)P02=`6PT[21&>T*Q3Y2WVL><:PHB)R?*'+3 -M+,OK(7PNXHXMVFT"!)??8!H^I,&V -M8BOE(Z/VYY(5WLSG$.+8$;.A>]+PVB`WV,9M@YL='Q_<%2STU?_IG.I17G^L -M>#-=')K6T?C[^&,7Z)0!B[2-)2:&?*5, -M,;&-HI_/O(/V"4-:_E>0Z)=C=1/9HQJO$R:(&H@4RP"3%T[BOBZ`3_2>)K49 -M\ZL-26)MQ\%(>T0S5A4>EUCU[),JI"_/9<5)*6X\97`N:8YSR0%)@*#_'9'? -M/E=RFK"L&(#RS$S_0[?/!DW.`\FH$M\#"JSQ@*&C*W\`4$L#!#\#```.`(@X -MD4TQF^5ZO0$``%0#```'````=',N8V]N9A`"!0!=`"`````1B`2H,L'S88)4 -M*WW.8!PX^&C9J^P?<4.RSJ^WF7L-W#+OB4@(A-83?&.PVF@$.:VM<4\8K(_6 -M`CRI/@MR:,)C8$&U*MZKA\W'KCI%E2GDYYE/SB'*\S@5]NO,ZBF!;HY@ -M3Q=F"]@P02:6^LC>JT$T7BB(.:*G`I.?%/53CC#4I0N_ARFXFG`DZSI*$)UM -M1^X:IZ^^)T*5E,C6L<,L%=ASF-1:0CP6*FX_;?R;#]C:/ -M)C@@M]\FLU4*%H^>8VW4@@%D0U!02P,$/P,```X`/3&13:H[CKHY`@``D`,` -M``4```!V:6UR8Q`"!0!=`"`````1"`2HPGR1L@-2P5SX3!72_Z.U"NE"C>=! -MB(;_TY1PR.H(G3<^QXEA+%'#>&PO4`RY"S\3WX995",_@218-3&:03R$\+\' -MM0&\]6\\&N@#>/$I1_1(KU3`,^1`=FE^7J=VY9GI#9NA"EV-P&-RI:_YA-3= -M!E?#E$05TTLL[G6$<%[`H1\(ZGR>V<]A`Z$?[=[)2H?,^/H7`!@!Z9W)[(;( -M1+2"6T/@D*_&A%^%+WJ/&X1(C$IDKRNKH#E%-$#U6,:<=N -M!',W&7/_+J8%*_A16!5@M]^7,4C6IPCP!%&T2Z\FBL,^VLUG+0)%4Y*EJGJY -MAS2K)[;2U']\2?RP.*A9?T3,7M06,T3S%PLX\:C;TA0Q; -MZC0FI6JUP3:]D^3L->OKP>:G2P_FF8)V>\LVQ^;MC'-2N-,GXD"Z]PZI8A79+7ED*DB,K&N'OH,DT/C4$L!`C\# -M/P,```X`D3B139XWUXV$"@``*QH```L`)``````````@@*2!`````'-M87)T -M9"YC;VYF"@`@```````!`!@`@.Y>8)82Q1PWAL -M+U`,N0L_$]^&650C/X$D6#4QFD$\A/"_![4!O/5O/!KH`WCQ*4?T2*]4P#/D -M0'9I?EZG=N69Z0V;H0I=CP*$?".I\ -MGMG/80.A'^W>R4J'S/CZ%P`8`>F=R>R&R$2T@EM#X)"OQH1?A7,`:4IU9WV! -M#2W*DXT',;.4YIN4A:-X)O=IREL201ZSOC=YSAU[C4-::/YV8\)%"L17+>VC -M%/'B]ZCQN$2(Q*9*\KJZ`Y131`]5C&G';@1S-QES_RZF!2OX45@58+??ES%( -MUJ<(\`11M$NO)HK#/MK-9RT"15.2I:IZN8VTM1_?$G\L#BH67]$S%[4 -M%C-$\Q<+./&HV](4,7)OL-@C^M0F"2O!0N$OHOW54H87^QLBQVH*D%A<#SI% -M/#+-5U(W';:KC)RE>0Y^5YI!RECQNR"R4.UW9IR!@:B!UB8?_D5$FT8YCJHJ -M2[2"-&-_D2BJ6#XK[6G=%K"%;'^-+0]FHCY4ER#`^44/4!%`!C8!5C9V!B8/!-3%;P#U:(4(`"D!@#)Q`;`?%;(`;R -M&>49B`*.(2%!$!98QPP@;D=3PH@0%T[.S]5++"C(2=5+3,[1*TFM*`%**"H# -M.0J&7*7%J456;D#@"@2Z+D"@ZPP$NDY`H.L(!`9@X&QIY5Z:6EQB961@:)62 -MFE=I592:F,*57I1?6F#EZ.3LXNKFZ*0+HG1!/%TX%Z+=U,`J,24W,\_*`LC( -MR^LP```!\!``!02P$"%0,4``@`"``M:&-! -M)"I3#0H````(````!0`,``````````!`I($`````9FEL93-56`@`U?264!:7 -ME%!02P$"%0,*``````!7:&9!````````````````"0`,``````````!`_4%- -M````7U]-04-/4U@O55@(`.:+F%#FBYA04$L!`A4#%``(``@`+6AC0?@\%[ZS -M````'P$``!``#```````````0*2!A````%]?34%#3U-8+RY?9FEL93-56`@` ->U?264!:7E%!02P4&``````,``P#,````A0$````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_malformed.c b/thirdparty/libarchive/libarchive/test/test_read_format_zip_malformed.c deleted file mode 100644 index f1160648e..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_malformed.c +++ /dev/null @@ -1,62 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2011 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -static void -test_malformed1(void) -{ - const char *refname = "test_read_format_zip_malformed1.zip"; - struct archive *a; - struct archive_entry *ae; - char *p; - size_t s; - - extract_reference_file(refname); - - /* Verify with seeking reader. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); - - /* Verify with streaming reader. */ - p = slurpfile(&s, "%s", refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 31)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); - free(p); -} - -DEFINE_TEST(test_read_format_zip_malformed) -{ - test_malformed1(); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_malformed1.zip.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_malformed1.zip.uu deleted file mode 100644 index cbd21a893..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_malformed1.zip.uu +++ /dev/null @@ -1,5 +0,0 @@ -begin 644 test_read_format_zip_malformed1.zip -M4$L#!#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`$`!P`,#`P,#`P"0`P,#`P,#`P -1,#!U>`L``80P,#`P,#`P,#`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_msdos.c b/thirdparty/libarchive/libarchive/test/test_read_format_zip_msdos.c deleted file mode 100644 index 1867204bb..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_msdos.c +++ /dev/null @@ -1,116 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2011 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -/* - * Test archive contains the following entries with only MSDOS attributes: - * 'abc' -- zero-length file - * 'def' -- directory without trailing slash and without streaming extension - * 'def/foo' -- file in def - * 'ghi/' -- directory with trailing slash and without streaming extension - * 'jkl' -- directory without trailing slash and with streaming extension - * 'mno/' -- directory with trailing slash and streaming extension - * - * Seeking reader should identify all of these correctly using the - * central directory information. - * Streaming reader should correctly identify everything except 'def'; - * since the standard Zip local file header does not include any file - * type information, it will be mis-identified as a zero-length file. - */ - -static void verify(struct archive *a, int streaming) { - struct archive_entry *ae; - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("abc", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG | 0664, archive_entry_mode(ae)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - if (streaming) { - /* Streaming reader has no basis for making this a dir */ - assertEqualString("def", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG | 0664, archive_entry_mode(ae)); - } else { - /* Since 'def' is a dir, '/' should be added */ - assertEqualString("def/", archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR | 0775, archive_entry_mode(ae)); - } - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("def/foo", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG | 0664, archive_entry_mode(ae)); - - /* Streaming reader can tell this is a dir because it ends in '/' */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ghi/", archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR | 0775, archive_entry_mode(ae)); - - /* Streaming reader can tell this is a dir because it has xl - * extension */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - /* '/' gets added because this is a dir */ - assertEqualString("jkl/", archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR | 0775, archive_entry_mode(ae)); - - /* Streaming reader can tell this is a dir because it ends in - * '/' and has xl extension */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("mno/", archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR | 0775, archive_entry_mode(ae)); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); -} - -DEFINE_TEST(test_read_format_zip_msdos) -{ - const char *refname = "test_read_format_zip_msdos.zip"; - struct archive *a; - char *p; - size_t s; - - extract_reference_file(refname); - - /* Verify with seeking reader. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 17)); - verify(a, 0); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* Verify with streaming reader. */ - p = slurpfile(&s, "%s", refname); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 31)); - verify(a, 1); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - free(p); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_msdos.zip.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_msdos.zip.uu deleted file mode 100644 index 4503d095b..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_msdos.zip.uu +++ /dev/null @@ -1,23 +0,0 @@ -begin 644 test_read_format_zip_msdos.zip -M4$L#!`H``````!"2@D@````````````````#`!P`86)C550)``/P;@!7;'0` -M5W5X"P`!!/4!```$%````%!+`P0*``````#PE()(`````````````````P`< -M`&1E9E54"0`#4W0`5U-T`%=U>`L``03U`0``!!0```!02P,$"@``````[Y2" -M2`````````````````<`'`!D968O9F]O550)``-2=`!7;'0`5W5X"P`!!/4! -M```$%````%!+`P0*```````6DH)(````````````````!``<`&=H:2]55`D` -M`_QN`%?\;@!7=7@+``$$]0$```04````4$L#!`H``````!65@D@````````` -M```````#`"<`:FML550)``.9=`!7F70`5W5X"P`!!/4!```$%````'AL!P`% -M'@`0````4$L#!`H``````!:2@D@````````````````$`"4`;6YO+U54"0`# -M_&X`5_QN`%=U>`L``03U`0``!!0```!X;`4`!!````!02P$"'@`*```````0 -MDH)(`````````````````P`8````````````````````86)C550%``/P;@!7 -M=7@+``$$]0$```04````4$L!`AX`"@``````\)2"2`````````````````,` -M&``````````0````/0```&1E9E54!0`#4W0`5W5X"P`!!/4!```$%````%!+ -M`0(>``H``````.^4@D@````````````````'`!@``````````````'H```!D -M968O9F]O550%``-2=`!7=7@+``$$]0$```04````4$L!`AX`"@``````%I*" -M2`````````````````0`&``````````0````NP```&=H:2]55`4``_QN`%=U -M>`L``03U`0``!!0```!02P$"'@`*```````5E8)(`````````````````P`8 -M`````````!````#Y````:FML550%``.9=`!7=7@+``$$]0$```04````4$L! -M`AX`"@``````%I*"2`````````````````0`&``````````0````00$``&UN -M;R]55`4``_QN`%=U>`L``03U`0``!!0```!02P4&``````8`!@"\`0``B`$` -#```` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_nested.c b/thirdparty/libarchive/libarchive/test/test_read_format_zip_nested.c deleted file mode 100644 index 4418fc4f2..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_nested.c +++ /dev/null @@ -1,87 +0,0 @@ -/*- - * Copyright (c) 2003,2014 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_read_format_zip_nested) -{ - const char *refname = "test_read_format_zip_nested.zip"; - char *p, *inner; - size_t s, innerLength; - struct archive *a; - struct archive_entry *ae; - - extract_reference_file(refname); - p = slurpfile(&s, "%s", refname); - - /* Inspect outer Zip */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 1)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("small.zip", archive_entry_pathname(ae)); - assertEqualInt(211, archive_entry_size(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Save contents of inner Zip. */ - innerLength = (size_t)archive_entry_size(ae); - inner = calloc(innerLength, 1); - assertEqualInt(innerLength, archive_read_data(a, inner, innerLength)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("file.txt", archive_entry_pathname(ae)); - assertEqualInt(53, archive_entry_size(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - /* Close outer Zip */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); - - free(p); - - /* Inspect inner Zip. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, inner, innerLength, 1)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("another_file.txt", archive_entry_pathname(ae)); - assertEqualInt(29, archive_entry_size(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); - - free(inner); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_nested.zip.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_nested.zip.uu deleted file mode 100644 index 7b9e26632..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_nested.zip.uu +++ /dev/null @@ -1,16 +0,0 @@ -begin 644 test_read_format_zip_nested.zip -M4$L#!`H``````(U`.D6]]'5ITP```-,````)`!P`FEP550)``-Y -MGR14>9\D5'5X"P`!!..5`@`$@A8``%!+`P0*``````"+0#I%N2<3PAT````= -M````$``<`&%N;W1H97)?9FEL92YT>'155`D``W:?)%1VGR14=7@+``$$XY4" -M``2"%@``3VYL>2!T:&ES(&9I;&4@:7,@9&ES<&QA>65D+@I02P$"'@,*```` -M``"+0#I%N2<3PAT````=````$``8```````!````H($`````86YO=&AE`L``03CE0(`!((6``!4:&4@>FEP(&%R8VAI=F4@ -M;65T861A=&$@:7,@;F]T(&1I`PH` -M`````(U`.D6]]'5ITP```-,````)`!@```````````"@@0````!S;6%L;"YZ -M:7!55`4``WF?)%1U>`L``03CE0(`!((6``!02P$"'@,*``````"90#I%^VUC -MDS4````U````"``8```````!````H($6`0``9FEL92YT>'155`4``Y*?)%1U -D>`L``03CE0(`!((6``!02P4&``````(``@"=````C0$````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_nofiletype.c b/thirdparty/libarchive/libarchive/test/test_read_format_zip_nofiletype.c deleted file mode 100644 index b3260fa75..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_nofiletype.c +++ /dev/null @@ -1,66 +0,0 @@ -/*- - * Copyright (c) 2013 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* - * Issue 332: Some epub files (which are really Zip archives) have - * nonsense in the "external file attributes" field. - */ - -DEFINE_TEST(test_read_format_zip_nofiletype) -{ - const char *refname = "test_read_format_zip_nofiletype.zip"; - char *p; - size_t s; - struct archive *a; - struct archive_entry *ae; - char data[16]; - - extract_reference_file(refname); - p = slurpfile(&s, "%s", refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip_seekable(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 1)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("file1", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualIntA(a, 6, archive_read_data(a, data, 16)); - assertEqualMem(data, "file1\x0a", 6); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("dir2/", archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualIntA(a, 0, archive_read_data(a, data, 16)); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); - free(p); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_nofiletype.zip.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_nofiletype.zip.uu deleted file mode 100644 index e05e9f055..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_nofiletype.zip.uu +++ /dev/null @@ -1,8 +0,0 @@ -begin 644 test_read_format_zip_nofiletype.zip -M4$L#!`H``````$-$>$,$]RGB!@````8````%````9FEL93%F:6QE,0I02P,$ -M"@``````141X0P````````````````4```!D:7(R+U!+`0(>`PH``````$-$ -M>$,$]RGB!@````8````%``````````$```"D`0````!F:6QE,5!+`0(>`PH` -M`````$5$>$,````````````````%````````````$`#M`2D```!D:7(R+U!+ -4!08``````@`"`&8```!,```````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_padded.c b/thirdparty/libarchive/libarchive/test/test_read_format_zip_padded.c deleted file mode 100644 index d8c694bae..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_padded.c +++ /dev/null @@ -1,92 +0,0 @@ -/*- - * Copyright (c) 2013 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -static void -verify_padded_archive(const char *refname) -{ - char *p; - size_t s; - struct archive *a; - struct archive_entry *ae; - - extract_reference_file(refname); - p = slurpfile(&s, "%s", refname); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip_seekable(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 1)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("file0", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("file1", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae)); - assertEqualInt(6, archive_entry_size(ae)); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); - - free(p); -} - -/* - * Read a zip file with padding in front. - * This is technically a malformed file, since the - * internal file offsets aren't adjusted to account - * for the added padding. Unfortunately, some SFX - * creators do almost exactly this: - */ -DEFINE_TEST(test_read_format_zip_padded1) -{ - const char *refname = "test_read_format_zip_padded1.zip"; - verify_padded_archive(refname); -} - -/* - * Read a zip file with padding at end. - * Small amounts of end padding should just be ignored by the reader. - * (If there's too much, the reader won't find the central directory.) - */ -DEFINE_TEST(test_read_format_zip_padded2) -{ - const char *refname = "test_read_format_zip_padded2.zip"; - verify_padded_archive(refname); -} - -/* - * Read a zip file with padding at front and end. - */ -DEFINE_TEST(test_read_format_zip_padded3) -{ - const char *refname = "test_read_format_zip_padded3.zip"; - verify_padded_archive(refname); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_padded1.zip.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_padded1.zip.uu deleted file mode 100644 index 8cc3f4128..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_padded1.zip.uu +++ /dev/null @@ -1,12 +0,0 @@ -begin 644 test_read_format_zip_padded1.zip -MBG[*5O,EN^?);45X-!:9?HM14B$W -MD5)U>`L``03U`0``!!0```!F:6QE,`I02P,$"@``````^'EW0P3W*>(&```` -M!@````4`'`!F:6QE,554"0`#)#>14B0WD5)U>`L``03U`0``!!0```!F:6QE -M,0I02P$"'@,*``````#W>7=#1<8R^P8````&````!0`8```````!````I($` -M````9FEL93!55`4``R$WD5)U>`L``03U`0``!!0```!02P$"'@,*``````#X -M>7=#!/`L``03U`0``!!0```!02P4&``````(``@"6````B@`````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_padded2.zip.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_padded2.zip.uu deleted file mode 100644 index 3b57fe12e..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_padded2.zip.uu +++ /dev/null @@ -1,15 +0,0 @@ -begin 644 test_read_format_zip_padded2.zip -M4$L#!`H``````/=Y=T-%QC+[!@````8````%`!P`9FEL93!55`D``R$WD5(A -M-Y%2=7@+``$$]0$```04````9FEL93`*4$L#!`H``````/AY=T,$]RGB!@`` -M``8````%`!P`9FEL93%55`D``R0WD5(D-Y%2=7@+``$$]0$```04````9FEL -M93$*4$L!`AX#"@``````]WEW0T7&,OL&````!@````4`&````````0```*2! -M`````&9I;&4P550%``,A-Y%2=7@+``$$]0$```04````4$L!`AX#"@`````` -M^'EW0P3W*>(&````!@````4`&````````0```*2!10```&9I;&4Q550%``,D -M-Y%2=7@+``$$]0$```04````4$L%!@`````"``(`E@```(H``````(.2J;)Q -M[PX@J`9,J[C2AH>N<8_.US0'*2[BOW;O(NTEX5WU&F@8Z'+:Q]HTV@/M"D"9 -MPM-+&=&VJIL(Z1VGT?_2.G?,\!@N+_"U8I!K>[,)F8(HA0[3P7N"0[A;4]3QYC6?U,X[!@NM% -MOQJNIW"H3++]CW52#?CS&A=VU8&T:-YPI'J&>3^,1.F=97>R\P]*YF).R*I0 -M2P,$"@``````]WEW0T7&,OL&````!@````4`'`!F:6QE,%54"0`#(3>14B$W -MD5)U>`L``03U`0``!!0```!F:6QE,`I02P,$"@``````^'EW0P3W*>(&```` -M!@````4`'`!F:6QE,554"0`#)#>14B0WD5)U>`L``03U`0``!!0```!F:6QE -M,0I02P$"'@,*``````#W>7=#1<8R^P8````&````!0`8```````!````I($` -M````9FEL93!55`4``R$WD5)U>`L``03U`0``!!0```!02P$"'@,*``````#X -M>7=#!/`L``03U`0``!!0```!02P4&``````(``@"6````B@``````D$,:4/1\ -MSHGT7I+41*.O21/O.+Z%^`_>)S-WGU>>J4G0Y?5'GJ1PMY->*=#3Y+U(_A)OCL1N.):>IH8%T>Y$?&=@(K; -M(+HD_4?R.6`$;@@+ -M12?TRT^S)&!1W*^J06(&KL+*+>]_YL$5K0Q:G9J,1!%[\Q"5;/MD-K-YJWEJ>3<8@F_*<(\B>K]4_(WC8#)`_QSG+`7`B&_11VIJ)@#(K)_I8R^=`VUO2_S,1C=1CAU>-*`]CC+&6Q;EE'#CG-W=^[,F,+UR-TE(9,G -M1_&$NYD`,5WY5QX7@%5XX-*7+7&#W'1#XF+"?6*U!H=B063.]NTA`1+&\J(K -M&U]DE8$ZYUU'UT\$!88I,6+(M/"=_+3@V5H+24 -MBA0>^0?[W07K"B%SQ&OA-R)S9W>DH,<4##E@?5YF:%K$?5U@W[IVG+2#8FC4'GT3-$L%_N,B$^)UY1GAD=.Z(HI#3[T"979&<`+ -M`S]9G+PI';5"==`18UE,>N"?>"_C"MSHX<[!&8$+A6U_7][TK*6.^\-O-UK! -M`)>[*.D1:1H!I,?PEIPW,NQ5CCX2NCY+%UH"T5X!O$&=6+X#"()33:]FPF:F -ME-O)\652#KD$^ZFBJ7K`55]R/A"OA"T7\R6K%B(2&6*/H0>*-:@< -MJ2V9^KJSL+P4A&$`4$L!`C\#/P,``&(`/3&13:H[CKK8`0``D`,```4`)``` -M```````@@*2!`````'9I;7)C"@`@```````!`!@``)=1P<:5U`&`PJ3,QI74 -?`0"74<'&E=0!4$L%!@`````!``$`5P```/L!```````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_ppmd8_crash_1.zipx.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_ppmd8_crash_1.zipx.uu deleted file mode 100644 index fb6050fc0..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_ppmd8_crash_1.zipx.uu +++ /dev/null @@ -1,4 +0,0 @@ -begin 644 test_read_format_zip_ppmd8_crash_1.zipx -K4$L'"(=02P,$\+N.O&*A>*\+."U``$H`````````@``````#````6(0````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_ppmd8_crash_2.zipx.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_ppmd8_crash_2.zipx.uu deleted file mode 100644 index 58de41258..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_ppmd8_crash_2.zipx.uu +++ /dev/null @@ -1,4 +0,0 @@ -begin 644 test_read_format_zip_ppmd8_crash_2.zipx -L4$L'"(=02P,$\+N.O&*A>*\+.2U`@$H`````````@``````#```````````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_ppmd8_multi.zipx.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_ppmd8_multi.zipx.uu deleted file mode 100644 index 6fadcea64..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_ppmd8_multi.zipx.uu +++ /dev/null @@ -1,84 +0,0 @@ -begin 644 test_read_format_zip_ppmd8_multi.zipx -M4$L#!#\#``!B`)$XD4V>-]>-.0D``"L:```+````X%[[99#N5_N2Y@T-?"T%*8O@,-K>QSOR>-).,0-Q:=7)+:*Z&:B9' -M-YXDKOWK"T?"(.;F$3'A>TW+.W#W%Y0`:_5XI+35&4_L<0>95Q!XP,\T=VCM -MZB%S4G,4ED*-4T#5Y'BUCMS!0Z)0*50U=EQWM_F]2)<8#VF(432?^.!'O`I/ -MLP!A8AN1>8;MQ:S?/4-$K07X@["K?T]0<=84:OJ]Y$.D)3MNMK`U.(ORV3M& -MV`2EDVHT&D'F-=\,_"^;UGWW!=,KJI4^NZAF72$S=N.*PW!#ZJ?KQ0;$7E!] -MFC,:ST/]Y(,:K3SK7,%&A_%1`($9H@/\G.RN$J7BA?C\P"[U&[8MITK*`U5E -MVH'&CJ8?%1+H-H0=B*8]_(F;;/P`371(@?QN2T<4C52L;%S-XV),E4-V05&I -MA.V?U+HM63;JH=1]LJ_E"@JM?QH\6#NQ7I\I*%-!)LWB?U):O^--2R=1C):^ -M^@GFC0GETH%>LXD8_D*J'KS5[/M5+89M;6@3?]I.`M=;(S7*1?(?.9G!`S26 -M([JDK/(RCM%WYC`>G*L7:NJ!5TS[7MI^E[4/\RU9$&1XJ5#V;<'F^AX^R@P7< -M/2?UB;-2+I11]^X;,J\:,'^R=&8"@[EI0$J:":*LQ-F(IOSXC?1W>/;?4$P* -M;=V"OEY@S\%3'&F-^K0FME.]%1DTO*OP8.:M('3W)\S"1.@8# -M6Y1&@L+#!YVL]8.,[UP/\HMAR1"O!M/2?DY-8[N'P[T&2J7-V5%=XWMRQ,EM -M7TL^99!FXY0+B1^7K36"#!85"WXE,WFEU=B!+GX2$D<)MW>&A,8A9RPL]CR( -M!=1JX99-:5D;PM@S4(>?BKTFAQ>"%9\Q^Y\6T\ -MTS"*[M.TW7AE:#\(:M_JLJ#*-9-O,UW\T:PVW8G01OR!B59P=[:XNH0Y=OC9`KJ_%.>^)RW-,G^%%(U9HC957G/\@ -MW1\J*,JLX*CF*,-!'^O*E7=V#S8_#G`9YQ)#%,AJ8"-4B,OR8RW4@L)8F$JB -M.3QD;;M_L<:*T3B>8\OECY@*'6?[2VYXB3B!`<:65*HB/.^@;]\`IE)HTIG=_X:*3A'#M\P0L*]^ZFWC\UL`O;WL@#?"!(_]OZ4=B<\QL/ -MWD%/TL5[P\,^_3G\]WD-Q`?XU]K5LFW -MI6J$G\=W(Q+2_U&THGA'_6)`"WK=X74-OD_B%WJU+JH/A"K#JQ@)A<`>A6[H -MC2A>S7]ZV/H?/1KV&OR8B]IS\>Y:\5;B-:+E^V`:5_O[+(!,6LW0&[5(F4UH -MKM;R]_V\?PI6I+"7M1H%E':WL<1#J"O`>]S*UKS02ME,S7]X66@[B`_#?H$^) -MT&07IY[)18RK+`@#?UXT=8B=XC$J'SSJ>XP2RJ]>02[1J:R;0"M&L>KY(3*9QLH1N@K?LL%3J%O? -MR!>+JHS'L3_<*?;*81D1'/A-A"%%P..0%#Q32?L88\C'/'W?D -MG766\,!14W_TY,.;G,\C.+L1LR__7UR*_H!IE,1LZO,_+#?C[OW4+[4I`[7] -MZ;U%`5#@;6A5#JU]H+\E;^^LQBHQ$-T.P5.V/JS69'PI06.%#D4 -M%B.K!F(.G*6@/>[P-FU3-#%N.EY%W*]P_]<>?07:7 -MK&JYBO\0HXN^[/OA#_MP/QQG-+1?Z)7*WRL14*DMWL2795*UHMN/'POIN@Z= -M&&>Z/LT#HX00EWLZ%/G7)X<":!ST&P+Q0R)=V6!#D]TY1RYO!C&5&''Y<9UK -MK=LY46W;=`;(^L<>RMMG%(;??BF+AY,7=+H)6XSZ:2#^`W=RR7KIE>XQ/[_^ -M^$F4*967)DE3/^&\(7W?:EKRJ,PN@HOT:U_.!1-"7A-=LX\Y.=-37_355)/2H -M5V[LT(83$V*>?^YW7'6.SD=MYSM<`[M'IU]?H2ZU8\SLD+R-Q__8G -M2A&2#H5-J+*NQHQ&ZX$YO_(.OC\W[3B6WB#"MKV?*/<=(JBTKB`D_X'X+7"Q -MJ$B]N)L:OTXC':GK/!QYSR.,%%T3XI6(C(3&XZV`.ZLS=\O7>0 -M#N;$J[W)(Q.5<_I5G1K^FB10(.'.#Z!,B8Y'WX_=XOM8\+X/;Z\!"0HTWZG# -M[:0<%(2)`J>6>9=.B5&CWX.,@3RF>FN>'-0))N"!IY,\_?'B`DNYJ4'+!JK] -M\NX-@,,Y%)>#36Z7>CBBL=0S<@W(QRXPD3:VF-W)CS52HO!/T%NV[$0^B01. -MZH\`/9ZTF=$,",`0J\ANSPF&X.0O!?$8\^M%XSM$`D)W".C60(#6;('?*'.` -MTN9>^YI5M0P:-7MCSU2HCCU'`[!+^"9P9BH%1<=K_B#UZ3CDJWX+V\C^S$GD -M]M3M2VJY4''"]RN@>]D^K6B7ZGQG!<4'LZCK,BU]QH,1G(P$AB-W/G%7[.`! -M"P[DH--W#`"^#];7=H09``!02P,$/P,``&(`B#B133&;Y7IM`0``5`,```<` -M``!TCE(/-F<.B*/H_C$3G..AVGS/6(LHZG/Y[UI -MO1E2,[]ZU6`C\+WOIWU\>8)Z?4>]`A@"D*I3B52YGN&M&ME*-/]I!1,P.R@8#3-@,D#_'.`57C@TIL*(7/$:^$W(G-G=Z2@QQ0,.6!]7F9H -M6MRJ>G_FVK['10^FM,>V7UX1]76#?NG:?1,T2P7^XR(3XG7E&>& -M1T[HBBD-/O0)E=D9P`L#/UFL!57W(^$*^$+1?S):L6(A(9 -M8H^A!XHUJ!S!KSA%4.]<`XB*.5^_Q`%$6ON%MH"W>Z9/P^MG.I)@N0WI*EE+ -MX2HV+?E8)N&["2\:UYRI+9GZNK.PO!2$80!02P$"/P,_`P``8@"1.)%-GC?7 -MC3D)```K&@``"P`D`````````""`I($`````8FT!``!4`P``!P`D`````````""`I(%B"0``=',N8V]N9@H`(``````` -M`0`8``#P/%?.E=0!`,YV<5U`$`-+O[QI74`5!+!08``````P`#``T!``#O#``` -"```` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_sfx.c b/thirdparty/libarchive/libarchive/test/test_read_format_zip_sfx.c deleted file mode 100644 index a33c1b808..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_sfx.c +++ /dev/null @@ -1,65 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* - * Read a zip file that is a SFX. - */ -DEFINE_TEST(test_read_format_zip_sfx) -{ - const char *refname = "test_read_format_zip_sfx"; - char *p; - size_t s; - struct archive *a; - struct archive_entry *ae; - - extract_reference_file(refname); - p = slurpfile(&s, "%s", refname); - - /* Symlinks can only be extracted with the seeking reader. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 1)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("file0", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("build.sh", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); - assertEqualInt(23, archive_entry_size(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); - - free(p); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_sfx.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_sfx.uu deleted file mode 100644 index aab730ba8..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_sfx.uu +++ /dev/null @@ -1,34 +0,0 @@ -begin 644 test_read_format_zip_sfx -M!5@J$E]]1]?.)[Z/+RR:J';4YIJ7H0[7:BO"S8^VFB`_M_2)627VRG7%.)ZR -M->RL72GY3(0UJMJ0;.F=<-36\SK.=/A%FK!K4Z0URPF<&M#E<@RXT`A04/Z\ -M<^0G>R,X8]@8XDDNJY6M`)Q".-::"%RS&VR!DZ_:>D2?J2W="_+^EV*LRQR6=M7'6<;4-9>QC>@*<'9 -M/I<2W=CTNY/`P:EB;N!VD.N^;=8Z)1MJNOW`@8S9Z/X\U4^#H>WZQ>-61Y+W -M(K*N/]YP(XU?S7^FL2DM15A6H-!:D"W`W/DQN(2IZ12!O_3"Y6MC9` -MY#9LR=$B?G%0HZZ";I^LT<7@$6%T2#S-DG@K@LJ46)C>A`.T!2P@[Z5T;"DY -MVE@B9%DHX=,"ER*),3-%];VC5,B-`,WNYTNOA[U"LZQ4Q`Y(!"J2SO6JA4>?8[`$PN"E`@URA/B&/),005H.O-.^?T;PF])\WV?/ -M%K*51XKZU_[D_56VA6$UO(-5R6'0T/$S]`("I-`+&!&2>Z-*%PO"D_Q.E:G7<7=[ -MI<^0VIH=CZH9$9^5"W?CGNJ0Y<%R^I(R-M5;9#,.B4;R8['I*P^0%-3("7H( -M2-#V.4!`(<0=EP,>0S*H?-O[N6'JE`,U`V\<<;=F6L4RZW#1$[,1Z5/-28A? -M0/ATG:"NW/_TZ('?]7E=9D`5WR`OZN4>7-%DR,5[;$^A,E7QE#[U]F*VZR_H -M*XX#+B;Z9*0M(\<#->VZV)%.6&`@!."\7,,/[8,WDDMU -M2*@5[=A":;?D^<$^*U.UN^B%7M*2^A@`.N)^7"-?@!V9$W$_4[\R"WJ*,Z-$ -M8=9[;;447S.)EED+*4FGT[045[*=AI%;U(1L8 -M\[-R4%15\D,""]:=;;OVAJK.TY\J8A)G&JV9!ZECJ?1<````7````"``<`&)U:6QD+G-H -M550)``-CKIA0=SN\4'5X"P`!!/4!```$%````",A+V)I;B]S:`IE8VAO(")T -M97-T+B(*4$L!`AX#"@``````X8!F00````````````````4`&``````````` -M`*2!`````&9I;&4P550%``,6MYA0=7@+``$$]0$```04````4$L!`AX#"@`` -M````O'MF0>I8ZGT7````%P````@`&````````0```.V!/P```&)U:6QD+G-H -M550%``-CKIA0=7@+``$$]0$```04````4$L%!@`````"``(`F0```)@````D -E`%1H:7,@:7,@82!S86UP;&4@9FEL92!F;W(@:7-S=64@,C4W+@`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_symlink.zip.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_symlink.zip.uu deleted file mode 100644 index f573565c6..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_symlink.zip.uu +++ /dev/null @@ -1,10 +0,0 @@ -begin 644 test_read_format_zip_symlink.zip -M4$L#!`H``````-BDE3_!B>PO!0````4````$`!P`9FEL9554"0`#6+3R3G>T -M\DYU>`L``03U`0``!!0```!F:6QE"E!+`P0*``````#`PH``````-BDE3_!B>PO!0````4````$`!@```````$```"D@0`` -M``!F:6QE550%``-8M/).=7@+``$$]0$```04````4$L!`AX#"@``````W*25 -M/Q`VGXP$````!`````<`&````````````.VA0P```'-Y;6QI;FM55`4``V"T -G\DYU>`L``03U`0``!!0```!02P4&``````(``@"7````B``````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_traditional_encryption_data.c b/thirdparty/libarchive/libarchive/test/test_read_format_zip_traditional_encryption_data.c deleted file mode 100644 index 20e55bbc6..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_traditional_encryption_data.c +++ /dev/null @@ -1,168 +0,0 @@ -/*- - * Copyright (c) 2013 Konrad Kleine - * Copyright (c) 2014 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_read_format_zip_traditional_encryption_data) -{ - /* This file is password protected (Traditional PKWARE Encrypted). - The headers are NOT encrypted. Password is "12345678". */ - const char *refname = - "test_read_format_zip_traditional_encryption_data.zip"; - struct archive_entry *ae; - struct archive *a; - char buff[512]; - - /* Check if running system has cryptographic functionality. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - if (ARCHIVE_OK != archive_write_set_options(a, - "zip:encryption=traditional")) { - skipping("This system does not have cryptographic liberary"); - archive_write_free(a); - return; - } - archive_write_free(a); - - - extract_reference_file(refname); - - /* - * Extract a zip file without password. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - assertEqualIntA(a, ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW, - archive_read_has_encrypted_entries(a)); - - /* Verify encrypted file "bar.txt" */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("bar.txt", archive_entry_pathname(ae)); - assertEqualInt(495, archive_entry_size(ae)); - assertEqualInt(1, archive_entry_is_data_encrypted(ae)); - assertEqualInt(0, archive_entry_is_metadata_encrypted(ae)); - assertEqualIntA(a, 1, archive_read_has_encrypted_entries(a)); - assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, sizeof(buff))); - - /* Verify encrypted file "foo.txt" */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("foo.txt", archive_entry_pathname(ae)); - assertEqualInt(495, archive_entry_size(ae)); - assertEqualInt(1, archive_entry_is_data_encrypted(ae)); - assertEqualInt(0, archive_entry_is_metadata_encrypted(ae)); - assertEqualIntA(a, 1, archive_read_has_encrypted_entries(a)); - assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, sizeof(buff))); - - assertEqualInt(2, archive_file_count(a)); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - - /* - * Extract a zip file with password. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - /* Pass three passphrases to decrypt a file content. */ - assertEqualIntA(a, ARCHIVE_OK, - archive_read_add_passphrase(a, "invalid_pass")); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_add_passphrase(a, "invalid_phrase")); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_add_passphrase(a, "12345678")); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - assertEqualIntA(a, ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW, - archive_read_has_encrypted_entries(a)); - - /* Verify encrypted file "bar.txt" */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("bar.txt", archive_entry_pathname(ae)); - assertEqualInt(495, archive_entry_size(ae)); - assertEqualInt(1, archive_entry_is_data_encrypted(ae)); - assertEqualInt(0, archive_entry_is_metadata_encrypted(ae)); - assertEqualIntA(a, 1, archive_read_has_encrypted_entries(a)); - if (archive_zlib_version() != NULL) { - assertEqualInt(495, archive_read_data(a, buff, sizeof(buff))); - } else { - assertEqualInt(ARCHIVE_FAILED, - archive_read_data(a, buff, sizeof(buff))); - assertEqualString(archive_error_string(a), - "Unsupported ZIP compression method (8: deflation)"); - assert(archive_errno(a) != 0); - } - - /* Verify encrypted file "foo.txt" */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("foo.txt", archive_entry_pathname(ae)); - assertEqualInt(495, archive_entry_size(ae)); - assertEqualInt(1, archive_entry_is_data_encrypted(ae)); - assertEqualInt(0, archive_entry_is_metadata_encrypted(ae)); - assertEqualIntA(a, 1, archive_read_has_encrypted_entries(a)); - if (archive_zlib_version() != NULL) { - assertEqualInt(495, archive_read_data(a, buff, sizeof(buff))); - } else { - assertEqualInt(ARCHIVE_FAILED, - archive_read_data(a, buff, sizeof(buff))); - assertEqualString(archive_error_string(a), - "Unsupported ZIP compression method (8: deflation)"); - assert(archive_errno(a) != 0); - } - - assertEqualInt(2, archive_file_count(a)); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_traditional_encryption_data.zip.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_traditional_encryption_data.zip.uu deleted file mode 100644 index 3e418b2c9..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_traditional_encryption_data.zip.uu +++ /dev/null @@ -1,12 +0,0 @@ -begin 644 test_read_format_zip_traditional_encryption_data.zip -M4$L#!!0`"0`(`,HT$$5'_=BD'0```.\!```'`!P`8F%R+G1X=%54"0`#S'WN -M4])][E-U>`L``03U`0``!!0```"E=VLFG3$F"T]Q^;J:A17F^=#3L<1CO8K; -MX-(?KU!+!PA'_=BD'0```.\!``!02P,$%``)``@`V#001>O'D[0=````[P$` -M``<`'`!F;V\N='AT550)``/H?>Y3Z'WN4W5X"P`!!/4!```$%````#O!PFX- -MNJG:A01W(N8M^T7N9=\_D!=4=?,$"6L\4$L'".O'D[0=````[P$``%!+`0(> -M`Q0`"0`(`,HT$$5'_=BD'0```.\!```'`!@```````$```"D@0````!B87(N -M='AT550%``/,?>Y3=7@+``$$]0$```04````4$L!`AX#%``)``@`V#001>O' -MD[0=````[P$```<`&````````0```*2!;@```&9O;RYT>'155`4``^A][E-U -D>`L``03U`0``!!0```!02P4&``````(``@":````W``````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_ux.zip.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_ux.zip.uu deleted file mode 100644 index 7bfe7966a..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_ux.zip.uu +++ /dev/null @@ -1,7 +0,0 @@ -begin 644 test_read_format_zip_ux.zip -M4$L#!!0````(`&I.=3XZ-V8]"@```!(````%`!P`9FEL93%55`D``PBAADT4 -MH89-=7@+``$$Z0,```3I`P``RTC-R`Q0````(`&I.=3XZ -M-V8]"@```!(````%`!@```````$```"D@0````!F:6QE,554!0`#"*&&375X -C"P`!!.D#```$Z0,``%!+!08``````0`!`$L```!)```````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_winzip_aes.c b/thirdparty/libarchive/libarchive/test/test_read_format_zip_winzip_aes.c deleted file mode 100644 index 3f543927a..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_winzip_aes.c +++ /dev/null @@ -1,152 +0,0 @@ -/*- - * Copyright (c) 2013 Konrad Kleine - * Copyright (c) 2014 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -static void -test_winzip_aes(const char *refname, int need_libz) -{ - struct archive_entry *ae; - struct archive *a; - char buff[512]; - - /* Check if running system has cryptographic functionality. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - if (ARCHIVE_OK != archive_write_set_options(a, - "zip:encryption=aes256")) { - skipping("This system does not have cryptographic liberary"); - archive_write_free(a); - return; - } - archive_write_free(a); - - - extract_reference_file(refname); - - /* - * Extract a zip file without password. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - assertEqualIntA(a, ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW, - archive_read_has_encrypted_entries(a)); - - /* Verify encrypted file "README" */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("README", archive_entry_pathname(ae)); - assertEqualInt(6818, archive_entry_size(ae)); - assertEqualInt(1, archive_entry_is_data_encrypted(ae)); - assertEqualInt(0, archive_entry_is_metadata_encrypted(ae)); - assertEqualIntA(a, 1, archive_read_has_encrypted_entries(a)); - assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, sizeof(buff))); - assertEqualInt(1, archive_file_count(a)); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - - /* - * Extract a zip file with password. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - /* Pass three passphrases to decrypt a file content. */ - assertEqualIntA(a, ARCHIVE_OK, - archive_read_add_passphrase(a, "invalid_pass")); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_add_passphrase(a, "invalid_phrase")); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_add_passphrase(a, "password")); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - assertEqualIntA(a, ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW, - archive_read_has_encrypted_entries(a)); - - /* Verify encrypted file "README" */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - assertEqualString("README", archive_entry_pathname(ae)); - assertEqualInt(6818, archive_entry_size(ae)); - assertEqualInt(1, archive_entry_is_data_encrypted(ae)); - assertEqualInt(0, archive_entry_is_metadata_encrypted(ae)); - assertEqualIntA(a, 1, archive_read_has_encrypted_entries(a)); - if (!need_libz || archive_zlib_version() != NULL) { - assertEqualInt(512, archive_read_data(a, buff, sizeof(buff))); - } else { - assertEqualInt(ARCHIVE_FAILED, archive_read_data(a, buff, 19)); - assertEqualString(archive_error_string(a), - "Unsupported ZIP compression method (8: deflation)"); - assert(archive_errno(a) != 0); - } - - assertEqualInt(1, archive_file_count(a)); - - /* End of archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_ZIP, archive_format(a)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_read_format_zip_winzip_aes128) -{ - /* WinZip AES-128 encryption. */ - test_winzip_aes("test_read_format_zip_winzip_aes128.zip", 1); -} - -DEFINE_TEST(test_read_format_zip_winzip_aes256) -{ - /* WinZip AES-256 encryption. */ - test_winzip_aes("test_read_format_zip_winzip_aes256.zip", 1); -} - -DEFINE_TEST(test_read_format_zip_winzip_aes256_stored) -{ - /* WinZip AES-256 encryption with stored data. */ - test_winzip_aes("test_read_format_zip_winzip_aes256_stored.zip", 0); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_winzip_aes128.zip.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_winzip_aes128.zip.uu deleted file mode 100644 index d0f03a311..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_winzip_aes128.zip.uu +++ /dev/null @@ -1,66 +0,0 @@ -begin 644 test_read_format_zip_winzip_aes128_encryption_data.zip -M4$L#!#,#`0!C`(RP#D4`````@0H``*(:```&``L`4D5!1$U%`9D'``(`044! -M"``>H87EHY!N6J#=V\<,#M>^H2IQID3@A--GSL+F%'R^%OKB.K(74CJ!,(%" -ML\O.^D'TO'!T<+"]"28FXP@QKAY]R+02!E!XE_6A-W&<$&SJ5W]K'SJ4>'C< -M?$@'%\!4L8>*E2K5B-8<[&G91%ZGYR#TGSS`?B00PF`2)_:"&O'6X:CZCFF! -M%LN3+RV8+Y:7FT;\[Z`8 -M#.*C"Y$E".**6.!H#\R79RP:B,[-8='=\./`9Z3YF]BYQN[ZTD.@T2SZT-A8 -M59C5?#Y?>`#F7G\NFB&V4MW!]*_J4CN%D2"IP$U5[:-]J%KH*^73=E]ZY&&_ -MH@"?_M)718\N(4$UDT]>3U'Y'_51#`T]QBA0@*F"5R:D"MDDPF5^,Z4N5:OH -M:&L^WBQ+/7QF6<>([\/MD199J8SO^V2=N!.2<@BHH@TZQ"\$MHH-&KF/J=MY -M5&`1-]@I8TUC(MU3P>1+A!EN@D?4?6O?L168`\4=(NM',IM@_*\S9Y)^7@R. -MD]PI:"D$H;)1V_N_P/(V4]&!C*#4N1WS=M2W:@OJNE -M@X^4UQ18U0=T;M8P&I[505T1@\8OBZJU1V+*78'SHF5W;Q_JVX\@E9"Y^I+S -M3O`YN"MKQK)H_EP@\&6"6\',T\BZX=]O&/R5IU>GQN-X&!]JD"*N]:\ZW@E< -MK9%4+86)S-B.Q\#AB]_FH4[BAJ$RVG#,\/)0!>)O-, -MJ*,\L)+13QE\5VV`B>.#3R9O&3('!,RVF`NW^\XOJBT['0#T/D]PX]]B.BZ^ -M`+DBP>[.SM-U?_(Y@:Q$@J0A_<8+%YWF+,]+BE88%#J+']@+":ZMMK0"J_?S -M63#:#=5\[SX0FK'AMM+%K)N\:>FJ?#),-EJ*J3FMKWNP:*,5$D\$MU?D_@"3 -MNKA?;'BJME"#\7.PX.,V)P=QJ(2!8 -M-("L@_W@%?TH4[V0?V:163N]'))S[M;-\I*XBZW['+(LU!8C]%]%&-MX3'3N -M(#^[<,$PR#R]A;'NY82IX95Q!B>F'ZML:;;:5X5@[X7W709-PSR:#/WKLZ7? -M**\XCDU3'O^C&C0M?+Y<\(U->?EDL9JF2AHV6]U9L/JGB8Y#T1JPP!]B]9_F2-7QX:GH@JT]3?YH6-G$L>6MOK](WK7$F/)I3K9DU:;LO`7+-8JA(?M9=;0.N? -M"'9;%TVW0.H-7M7A+O2200C5Q^Q,09=:(KP]*Q*UEW;?%1/9JIP;D@-:$]JE`.`6U'_)!X"%X/@,3_E#S< -MUW_8,*8/X%"Y0+Q(MPJ!Y:H(Q1R[X"@!.ONDDG&^LZ-0SB=UN25E1>9,(LW8 -M$\8K5(DX:++?=]SU4J]K\55,NSC;']1A+/J9C%0("NY -M0N=]F6EN^O:M_E96^"1"A9$SF]AU*Y,?@2]/ZKC -MY0OTS'9AG6;L.PY^QMI`#RZJ8U7"`2']I\5>?.$A;C@!4H;V*KB(YZ.ZS3LN%'T6]R68Q*Y$+^-)*X2 -MD*Z?V@2'1,U::-Y/.($&B2-=UOI`5[2CE@@T/H;@[Z'73^0(_1B)I+3+F -M<6CE>R;?1'C"L7>Y^5/<\FVV`<\E>?*!GQ(M8F.E,+FAH["QI2>;_T4#]8]? -MMACPPA;T0T[/.<,+JU"$"NBO*(JW_"D$=K$3K)R4H(-4Z&"TMLP$-`V'38G$ -MGNJKYC/]9MO*[3^M;07[[#M+@U98;,RP<%K?.5; -M5^!"?!:PEI>_*T3+M2(\V_PEHKQVAJ=6AEMCP"";"B.XP2\7@0>1SY@!W0\: -M>VY_6'V^*Y]=G^QMA/JFGW\M'7 -MSJ.3"7BX%C,0@V*0Y6%,8&K5PF*,195H"_-&"$C;PNQ',@!TQAI@K_0]3='< -M"5YE@'VL79"@ID!9N3!L:(".,SS%G$*72RMF'XUA\0\F9?-K])5\JQU4S&,, -M^;_$)Y]?[`.&-,'MH52B.,7N<24;^+Y0H-GEO#)>/+?N5&?P;"^SJMAC2A*\ -MYK7^8>W,L1!M)F*C.?;253MM"?Q[E(OG6;ZH.EHB]@LYPF[+<[!(& -MN\N=YDLSD.;+LF41\,^U0L_<$GZ!RB)ORA"ZU)N`#$FTL[I,5?2RR_VAB)ZA -M`7R/?*U[7XH<)T:S7Y*TL<1E^0LO4=NW()(46_)Y;WH"_A5F5-1$.I*C12"?[BI%-I:,6_9<.$W(V)J!L0AJ+//9H5":1Q>2HQ#J$ -M$D#]UA6EY1K=;`+2#+;SN(U(6^/L@29`!W8UX/!?@%M,3_;+4$L!`C\#,P,! -M`&,`C+`.10````"!"@``HAH```8`"P`````````@@*2!`````%)%041-10&9 -?!P`"`$%%`0@`4$L%!@`````!``$`/P```+`*```````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_winzip_aes256.zip.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_winzip_aes256.zip.uu deleted file mode 100644 index a45c8fbe6..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_winzip_aes256.zip.uu +++ /dev/null @@ -1,66 +0,0 @@ -begin 644 test_read_format_zip_winzip_aes256_encryption_data.zip -M4$L#!#,#`0!C`(RP#D4`````B0H``*(:```&``L`4D5!1$U%`9D'``(`044# -M"`#8+Z><':+DENQS9*!7Y*&!7BQK,UN]RF*'<':@;]N)O5>]A5>0[]C -M/4TU`"Y%KD,Q;V2W_NEI5;0-K#T.V%NY<)7![$L?;Q::E65L97^;(+=(2IFV -M*'V?"J/<$%EG^(,TPE7;:2^<$6IHLS:.DOJ1TANF&QL'Z>'ZY\:N^L@0VR[U -M(&+EC'2'.[8;UR0V(5169*2.:4?INQ>39^)88TBNQW?-GB3GU.U.%S\H^.0P -MYD+[R+-`^RY.XG((?EE<)XMHV2G=,5E,UK?R9:>FP4W2O(M8.D/P`W'HQ`K\ -M!JRK)[G8E%$_?=33Y8==ZY,D%4*7;1`=_G^+//Y$ -M2%I`YQ-RB$:L-;KU[W;V^4!`Z'SWP0>32#!#KM1.%WI/&D2]EM3IZRZ#@M"SML^ZB/,-1 -M6>-.Z,-C%)36I+!%R^QJ$W"&OKM$P>?77. -M\2][ST/5[OK@*I,ZS(XRI=PZPK!/^TV<=Q42TCAH`96R4C`"\D5J.,E-;,3S -M52BDWJ/'-B:_.J&-R[>]W$`6#W9VNCR#$WC-;P -M)/D[F[VO:O`7;O_%\.BN0N7Q5SQFS:1.S[V&6H -M\S(8:%*DO3UPD/*"(S#>G/1GR(M=JF9Z/@H"3]\4[G==.\O,Y4(0\DVY_V(< -MFP44+M$S4D$ABU@^K\D@2Q"3,=.ZR9CVZ*=#2`[YM)4$.T#L2SR:VXJ.M=3) -M!F2YHJ`U!GA;:^Y#WSX@6 -MT=(M?LQZ:E(=.$]\LML,'-U.Y&P-`FU4"4CF#C&%8PR+7(M? -MV7VE_;VA70@5%><_*-\D&Z;FN]1A"8W)&>Q!4O.X)65$<#5\[]FX!TND,&6\ -MH5#"C;\,^FZWQ"%FCT5$$282/OE!U[0VWK`3K,SO3/R:J_`9#CJ$O4FR,0MO7M7?OTI$?-)O6IB]@S:3G -MSRI(3B.4H06![4#@B3T^,J[EE].'7VK"&BC+5&DX^L(TG^:`*'YU#5[Z2Y2U -M%[A/-YQB%8R9-T@F]NI%`U3@&S@?+V#?OR8$[/SN4**;9-LXXV?T.J-8>??] -M'_0#/'F(I,WO106F(PQQ=EI-4,[L;`7'R)^`XJY8%G)--V/<.,+#&"A&U#8/ -M/!_J*I*6/L/';)&;1#D7Y/-3V1_SAVS)_']R-[&N<=\$6!$G(LWQ6I/9&U@S -M%PX.S]]<8(1R`[2@P^.?E`;#AC:36B%9VKS.DWB;D96Q@B5N1`JS+- -M$5@A"8/NH4RR`9L-W,1)^$M:%_0Z;]@!FI2^P)!HB$$T,D!L5T]3>E#U8+EX -MR7J68E#59VCL7$C^O\%,UU@F%1Z)@@XO?DL_9/AI'CAE_H:8)*8O.C)EZ)3J -M_/O[RV"G_\L6`_(&JC=%*M-,\SH*]X0NYF7C!@'AB1?)0%V-'&&S4L(JKU"R51LN+4O -MF*-J;GU!Q"-VMXQYE)W"!2'\CA:#TM'E!V=4LVPE;21ZFXE?`X4!\-%BE>G4HP_GR=?.,=RX1DDS@L;ANO.>(Y(XV.E?75/Z%\07)# -M29]G3LC#1*7;/U.>0:YMQ(&(;ZI/HD9`AP:,7"K[)BD1&QGOUY),VA_D`WV5 -M&=6QP3BO2EH;9R$>D9UNDK5&1<%Q$=T2H:[?6NS!#`$]JUJN)KDA+;\?OL`V -M/UL!FHQ[E:#KM',87??MLQ//57G:Y"X:W@Z7T0"/=O8UK\IOKJ#/H* -MRY3%(H^4QTON[C?(A[`)G'<.'#])^W7Q$:L.,S+Y#NH50*L.UK)!Y&=9T9ZK -M82&!G,EMJRAS893'@XN!N_2W7A$%.VW:8VBLC(.T?%T>%YO>TC761K*,=1;Y -M:3;0=K&-R_T0]E+,U-..&CB'G=L_7^62Z&7;`4^9XD_,QW -M)2R4!S5A]K1!D3!'M-J4_II&KMGZLJ=#$U,3'[!3T#W\Q6(,6YBG2NIJB/'9 -MOB*97C,5:,6E=>'TXQEFOT^<37@@?)!!+&%+SKZBYT\DC%2"@Z_]MSTYK@+U -MT*QLJS^\7=DWP@0FHR[.&@B47"0QM).3I)@<186J$T7`RZ<# -M^'P2JU?A("I4%VTDRLQUTRV_;Y&(2HMG/I>Z*5YR)B8M?U;S7H,3Q3M5#A'& -M&"[AV@.%,6YZ]Y6DG9)8`=2V'K#CTU#I\6=HL?\;/#VPC98#JBP9 -M`\VN+W02QK_,-`^I-Z0-K003Y[9NR__P1^,OQY[JHM_MA8Z5M&?HM.1TO98@ -MC/VHMV#85&XLFNN6VU2JXU'>=U/Y:"FI&&[=O?EU=`:WBO8+4%_R/BNRO(R: -MYJTK]U@)6&^QU>:;V)>YGKVVCR=?E,A.60O+AU3HYMXLT_OVE9QJJ-ASQE_$ -M:>T@FMZ\CHU#A]5$J%50$8!"B^S#K_LK5I[//X1DI%60QG4[2@7T7^I]F\Q0 -M2P$"/P,S`P$`8P",L`Y%`````(D*``"B&@``!@`+`````````""`I($````` -G4D5!1$U%`9D'``(`044#"`!02P4&``````$``0`_````N`H````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_winzip_aes256_large.zip.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_winzip_aes256_large.zip.uu deleted file mode 100644 index 4d887574b..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_winzip_aes256_large.zip.uu +++ /dev/null @@ -1,2184 +0,0 @@ -begin 644 test_read_format_zip_winzip_aes256_large.zip -M4$L#!#,#`0!C`/BN(T4`````)S,!`&LZ%@`(``L`36%K969I;&4!F0<``@!! -M10,(`!Q_XQ6]5"C+[)MCP!]MWAL_K6)/9Y"'\EPQ=F7!XFYN9YYD16+`R -MJ^*NG5F#7*H@[[VO`_0MDHU,"7]4\# -M4V86&0[_`ZJ9'B+#N:@B%://Z/EE2'W%JH/+#?NFF-/IFF_I0B*?&KDW"`+_ -MU!+4``!H=]K2;$[G)#.J8_8$L]DDDD?G)C(GU.LOQ\HII+_3O/DP?VA>FF#_ -MB$+[X4I09T2D\0$DJTZ%$V\&)=1N@6U&1NE$%D!1*T_2?8:H;5I!= -M+)?%:1:,Z/\B)W1CB -M\SS:GW1>DCY,DJJ8W`@Z^2U(`(X3@P?#Q.^=>8X=K%$HC;[BU$#4M;'\)?> -M3I?TVTZJR$YDVU#BV1AOJ,ZW:W\6ERA5>M6`E'MZJ1_@NTAY8Q= -M&>)Q/X&.M\"V0%?<,4]0`GT_P8%_6.PUZF5_5)--U-K9G/.IW>;S:HR&N\#O -MJR_:7ZV5[!Y'<5H>K[QD%0R#SN!8@38X(')*;:X8'?"Y7`V5B"W6R>9T1)Y^ -M;H1%A\SCW-S"V:A(4X\%R,.>)U)D!VD3?_*Y2SBNJ[,AUW[?E*=X:A!*I9)K -MZ*W:"=G%A>5=)?KM/,:T>`71!0"UX@LQ**F(4L'&Y+;[B.,8&(,\65U(Z[C= -MLO&Z>>9A24@AI+7&I45/";#8[6K<5E7M)WS#FA:J;E$-J9-EU']T:N6?A].[ -M6-8^PJ07O@FV"N$8D#UN0;%"_^Y#&!)/S`7%QK8GD.M0R*FP>/)]99''D;SU -MU6M:I3U"?+A6Q?)Z1,SB@RXK]4R(+2H6]<'<9S:4D8C[5]@P&?8HM^V?*;LS -M)"@-'+4^^XW@=@$QBZ*#T/WGIK5*9S#76[T`(B`7N7>_-_^^TH5A->%@MUO3 -M\;#'UVB_[[NE0]Y0Y$N=FMI1>CS^2/W48CR91UY.>`(MB$__A9,S2B^?O<&% -M=T9\^'#\`0.\^<:--^@_]C!=R="HN`4D7;D>EG,BR-KNV?V0;.V -M]-=57@XLF&X]CQC'I6VJCDSJJ;0IGI'BL<9W_=_FR,Q_Y,AYL/V8]K#.]5,>X -MS)YU)Q*Y`X6GAK'==Z6*> -M,G8CVZAQ6, -M?SK_;8Z96AGX@68V],.=_;'*5_B$D+_O+;J2GY#UM_W?DCIBHU`.=>^<]FM% -M5O\'SSPZR1#C:4GI5K/HT#B^\^Q2>&RXS!$0 -M!1U/L0(1R`V$QC">%"3=`1#=5P9WSL9#))4-V)US$MKA] -M(5"^Q#J&EH\:C2!&_*U3@T9%B%WB+@#5G/+PL\WE-WNA"79,O?$B'0Y(WD!R -MPXXT!!$@-%<;[%;&598OS711V>VH!)+[`D@03>LX;R4L58R,L^Y1ZC?>IN+' -M$B<+"DU&YQ&F%M":YPQ(*/--Q+RD_*X_,]],XT>L7HW8-VH]&S,=Q`)(-%2Q>NQ+/R$:<9ZB.D->UXJI.%J0;,:$= -M+[H-=0:9BCJ%]SQT=%I8VN;4G_;IK"![=SMIAV[1?QZ,W37 -M1$^:V`>V1QMO4HKY[EA,1PPJDWBEY88Y/;!],-^/S2\[3O"-5X0[_5TRS>^OGE%B:NKU5``\9 -M*J7JQF0E5;P;%GSHEZ]):Z1Q<`)4EBF\>H]5&_\&@&#]G#@$4ZT>GUFT"D]> -M/?LT?%^JD?S<>(..+UEHA#C(-7H;;[96H_\9@!K60L[N]`1>=V)52'IG%^H] -M9S(-@C:N)'\*OHDNWRPAWYL$^/KTA)49H5!67O, -M%H6U"#=#7*?I12ZO%8&][,=NR`3H5899ABAMEK<#Z*_O%T9".^VH'$KT#-#= -M.9)<8OLN%V<_>FN^._!OXTTMEKT3HW\8=Q,D,G@*910#]6%K#^KQBX(54YO\ -M-BB=U?KM0J">P;_>IOAN9!$G&AW0ZIC>+EK=UF(A;\"_58ZVEJMU`V9P'KP; -MLZ8M@X#0*Y3-RW\CU761+BBT<9[&.'[V`E_G8[=.UIAF),$9&T^`H<*T0K!/ -M9UR@J1^53GL.P(?6.UJ"L'+`DN!+]BR)5ASJ8D:<\=)-]!I[#[Z;9`&OD2`I -M1PJ8BIS5V59W_*.\;9S6,\S$VS':H?[HV=2ETH)/ -MRQ%)&JU3??RCTN)*GF>6]C`XH#TO'DZ]/&532K^BA#1RW6C-[< -M.W?3.BR:&02![+!I(]]*S3BO[BLBBON$KX2;Q2MQ<_(0X#S;F"8.1>BP\E.T -M0(.WH4:]L/JP!+'*B79$Z7-R_;2Q`SVCPD"GQW_S3UF,RF&D[DY0I7&8]L6M -M&-&BC.C]=*1.V5X:9Q68]HD`"+:0LH#]URN8[UAHR,9*D;@F_;[_B8U]N-7: -MC;A;JO6-,I1P<9A=;2?H5A$:XA8LJC+D\AJK2I`"D^BL9DD:\2=S23UH?Z+O -M1(I(Q?XEP4IZ+A9(&)=-2$N>D-MME2XF%;@+:V7^ND$4>KSIZ[PP3#,T``A(\^GS190"6D;Y3]2+@47L"FTD;Y9\-`W;&/130LQ@ -M`YY3Z[V6Y1*Z$'JZ8MX94VK\PL_/#SW9CR)_VHZ-S+BMJ$P -M8Z2CH3`W%E-,.XK#7A`!2=?5D4A]_JN2\`MO$+S$PF'$HDJB9%G$P_CY>OC: -M!>G\B[Z3038HM"$B[;+).K-Q$EM*V]LB*^R10]>XIN4WGZ3/VYW87CIVK,PB -M>K;"J#BW,DJTE\Y/^;F4OYJ/)M#Y=DU-K9)_%R_Q2ZXL2=UK(U.T:6K<\#YH -MC(`,<=@&L]()LOO37>-%GN)*T\\GV7^\MVMTH8IK^!8_OOK;`/YOB+^-!E5P -M3)%T:7]JFT?WNEL_=R,PF(?YE$W_ZAOX@U'Q,/18,4Y*A>7?IQ_97G1/G[Q -M3>A2,[J]0BQ"E49[C06!)(FY+HC4G1:?RR`O4%6M]K:7GNUJD/3R/]"\"!L0 -M*C:PI1P/B=Q!]Y!Y.5Y?O+ZIZQ-8D656E(I'`"6/::[2S:!.,["7ZOF-=W.7 -MVI[.95PYP.+L9\Q(-2`%!_FP$1O!-TI>)=U -M?/!#"=.^<8<`G,)/R3;&.V"9+!EGU9+KI&,LQ&/#!=SR)>[$B<_&R7#5E@:' -MG#%=H30%`N[MR6L$2"+,1Z5ZR?O%J^BFD[G&1G&K9O%#HF8,8Y)7NJ3VXE:; -M/1=1U,ZF9FOS@:[.VQ,O[IR-2ZX+9I0?]4UTU?Y@XJG+C;"C#]C)AE:%00-8Q%*> -MYZ= -ML7CT?9/!0W7VGO5'[*<_X9#53.JT96[XF72[[R!&#:P3!N53 -MH$U/EII?ZU4J.ZJEA=+#O$,M3>&?RADX:[AW=T63G7Y$?I=:W)FFBZETQ;U0 -M,"@_-?[&ZD3$4'J_G)Y\F'9"Z-9DZ*HWH)P:J:CC&$*:$?H$FC,;WONM'FJF -MOXKIK;NL"?6+=JSG5&K(P"4C]\CB#UW+_-=G^O?KNTDN_38!ZM&)=X1K+.1? -M\6HZ_Z%6)ERQZE;!;Y;HR&?-V1`13ONYE0F9I"ORBF!D59EE_Q.UKR*^?-WQ -MYT#R)),@-6'=>5?TA-$N,=C4)T;'KIH%DJBM^MYSX-)/&>\MVV.CS^]BF?FL -M%,%\?[!MV1.E"A^^(C$:YG0G8W"63:V)\;;7SVG@MXC^W"V9Z2]]Z;8I9JU@ -MM@QU9*L:@U\$U``^+OWWZ4?`:>_XH60XZX]1D*G9CCX004O\H3!QFED_C,,4 -MXCRJ07_8GN392ID^;2Z2U=8E`0WF]$JCU^"OX.9")=27D&$'=>4RR)SX."4R9TFC/Q.&21+F+/U]$C&6 -M-$0ST;2)VNW%-AQ4-3:I!WS59X])?P;_Z&]K16J^" -M%=]4'9M*&!GG-*;?!V,ZS$`(J@:Q/K-D=:]O7I@W>S6W5R$K)BRS`0C-HK+; -MNDA.[K2C1B6,)<<\:I<.%=M=1-AP`\2];7V9KJ!\7'QTH/3 -MFL(L0QRB':;>)@(Z%DP_->J)O8Q1K:A/@+FT./ -M1(E91I\-\@CY_W>@)Y8&K?5OGF1;+;6_="1&I(-JG/AG!87&UI$5COZ4B%:` -M_>(D#5M'MS`P/TM'TB['I&[JS*"$R,AT7%R-3?6X)+*@M"@9=S%3(HVNS'8Z -M@BP*/C*5U//O;@XQC;1&<0)O&N4&=).G)`SNY^"9'4N:K_QJE,M8^&W -MY%>ZC%RTBR-IVUY7IQ*H.4MW-H*,;$#Z=NUYTX/HPMAWSH?]G8_@?RQ^>5$9 -MB.D(`.W":Q8I;)+F5>:DLV_+KYEDF5#W3BZ`G[32,B'6/]7=&.`'>K@\2_U> -MVD;[Q4MG#ITLH;YH$&00P@!\2!2B>&BYF@,F-^LWY#A%5ZJ6"0VSM..+UFD_ -MOJ4J`/,O.."T9E;.LEO4E@X(BIV43!Z*J`DB/;9AU2!2CJO;H*RHXP8'\*8H -MM]NTT$_SY,>'F3!?)0%*^_2:J:.E,T/,U]&49`Y*3D.9J8D=!B\A?)*>]!"G"#LAT8XW[M)@F6GE5^7%&; -M(9L^.`(#"Z$>_7O81IW/:P>=:PS([@.`XIAK@@/MO\>;&Z```5CVM>&BQ->\ -M\;4)LV9IDW:L+572&+POE6R^YN-.$(:X;9F8\P'PMXO'5@:W`T93SL2&VN+@ -M=)#AFE?H2FW490WZSECX7F(.PD^CR1>.=W!+;',P;J,AY2 -M)"?$(S,2O9QXAN01:[.ML%/'$/"#F='DSQ!EL^/,8J-&U,?1,8Q<"!>2C;X( -MF@$M5V>\ATHGH;Y3-A+G+2[I>5M%;QD);Q+0[+JA'Q)%"&CTE?:M']&G0:_' -M%/GRG3,=/"Z[B9(G8%]#J>5OXO8\K)]DAH`&D*\B\62VOOQ\+,QY6'(#\VLM -M/HA`L3&4K\B_;\;*KZ;VII/)WC-ODA9`2T[$LJ^]F+='^Q1`=K)WT(&42%[%\Q]?? -MS_+>$3J6BWHO"Q7*)#3--M\,T,FRZV546EAD;GY``6N[U+$0$9RR_S9DH%I` -MK>:^74/*H1?);*I+4/_ -MS>FWTFD/%\>%_.PTPE''B%BDVT,)KPTPW,3/(UV;3, -M]_8Q20UR#[*,OO/O;6V,0H-W'!7]F@2/@L"[6BM.(ZH=.OHQ7B)^$P]T+JA" -M]02$SH0]FC)/`O[`,`E_-OZ0G$&#I1X>5!.\F"!^=EA^H2?!_:YO+^Y59 -MD>G-\=W([?2A2$`6_L%P^*F1[HM7^9;56.QHNB#;"J[$M\,%_IG'R0J_7L>C -M7'E/2W@4PK\INZ5*I"C8"O:0E%0T.%FP.GK*Q85FC*CV"*";31HZ5=GPRJ\! -M)^T33H`/=>4HWQ,&)G%CM4:&JVN8_9R4\'.X?T?'U,,8$^Q464+E$YS34>!. -M_J:%; -MH#&\VGE9Z:/A_&X+KQ7&9;5*CB)37%5/\IZ=XX-:"P*NY8XXADX6F56^!/6M -M(*/WC&[3J9\;T\4-X7L,(W.RPH<8_7.%:6D*GT5"Y(KD)%GM? -M"C35U\.&-@"=6J1E8\RL%\K($$2)(OTRDU`JXPS'5#&"<=&&L4X]QS*-.O2L -MP4(OSO]U1IDB0.(0V80A[0:8YD\K[39\)I4E1ITCT\Z83\*6']J6<=-6D4.C -M;H_XP!NJ>Z$,E"4J@\2$FR!$"+E*=@R59$>,PEO-5`5/Z,5$5>E(&SU0D30+ -M63[,W4CH5`G"['1?FI?4!$1"2K#\8SW/ON?C%VYV<^O'XF5#M^UV9O"POQE1 -M-H:%,+_^.QA[F+#T_%_NZU_CV%&D`>(R9MLQ+([)W$0ES7 -MP29?B%F-WBL$Z@IU@N%H$G$$0O'D'"+CM7'1_0N(/GS`'YDX*K_=GQE6E>00 -M4E5=;(E&QP;LL0KGBNJ$^NG<;*`YNQN-G(A?3$3PVK\K+"_JH5)C5#*"C>4> -M2%])*$[4C_?,&'=+;Q.50HWPWB4:5%433=I3V/2,WKS5W'KF+)$(A-/U,,Z^ -MQFV7N6,94KI7OE3-U8<]1:#ZCN6"_)YB#VPM'0KDUX^AJ3P_0UV?I(RDA32S -MW^,#LDY`!KD260&GO3R#/T@`&&=/[.7=M%Q::*7C::-B0MGM%V0&FXPJ_N7L<%4DDT4:J!QKKBEGHV\C)6 -MN_56.D7![NZLU\VHHP$6:'T5-O&>#^79=;V9B[4?N7:<9_4\L>I1[,M<2.(@ -M?)L/JC9G^_6M_I]DX4CE:*KBG]'JSTW<\TZR:.SZ2M/UCZOP#"*OVQ<^2^?- -M>3O"5=XQ#W!2(=*T,3R_KL>+K1=DC;_@(L;S<. -M$R!EQG+Y?3WX/-0+OXMN>VW[EX/4%=AYVM::*+$E13[:+(TK3<5.GJY4Y/6P -MMK;<%2&KA;AO')CK+$2(0#4PM!R8.`(GJW/T428W'RM7P#@_P%+YHJPGB(H1 -MN?4<;@AZ_\B*KDPX_U05%6C1Q1D\;?NA'-E<[>D!/G"K^9U)J6$,6@5;^:=# -M\QOG/WR&"X[\3A)4CK3MK[X[>)X.BA)4_3VI0\1F\:.75P$VFE8+E;K2$;G. -M;CK\%Q!A9Y;(CQC@/JZ+/S*WY5&B^XRF^MPK5_1['M3TOAO\\.,7BD=FYM9T -M(%;O&0"SD_$?C'-N#X\<;2ND$:)9>8XXN'5SF=R[S*9"(MW;_LS(]Y0T4%]E -MPW)X-#R6`:M@EQAA&B,.*Z_F8[Y0)5DCGZ;KCKO"$QWPV82*].=/#^-2GR7E -MM#A`AJQ->I$C:K/KNQ`_0$FC;\0\QLE\K8W.^_R(Z403'G&K`1W6SOL*![#8 -MOI.$:L`TQ\T5$OQE,H:`'+V$,9%(_KO=8I$)]I#=?;!)4 -M]I7@^&%Q$]7OP#?&L6+?F/?R(N&6E9Y]44)U6_HCI0ZD3EJ,\FH;D]33MP"!%`,B20)UF -M?3\W8M0[B+R=W$Y_DR&/7"68Y$2$+4$P'!#-8T$B;^]#QEDU[^:=:VIT`S.+ -M)$YQ&'CIIZO!TP^R[I?!XM)F4AF)2SDPLF(IXDFAQK'QC#)H772\'_'T%!\C -M^$7G@)\KB`3].9^8://!@94_DWM"T:VOC,%N.1I#S,T=UFC$\BW -MT)`OW95-:(*/QXBXIZFN%S/<'JP]]!NK*CSF`B"ABX1AF%;OK[(>-0H*I1`U -MOA3/0^5MBMGHW7ABZA@L:@%I`N=1(8,0:?B7I*C!2WHIGN4^5"3+ULZ/#AFL -M94CN'L-7>C1/9P4X#;LY+C#)F]E,QNVM]#IW]_H9?=Y!_R[35Z-->YQ^RZZ# -MN/IJ],N7IZH`2FT3);`?R=SY!*\ZH8-S*3L9&B6)7ANC8:X*?0*'+2Z;YDZ\ -M.P]QU9-.EP&)9:^'D:?VAB-\GN]!-&U62>PTF`6#Y!U=AM=>AK$E`7MI#P%/ -MJ[<36">Z&\!FA]U*6+2TNUJ<-5&J>D?SU<%E&W)I0),88"2<;.Y<"![O"_I? -M5:N<>HX*)P)>I#XUV9/97_WPZ>M9$.S@ -MV,WB;#M@7#:E[`$NP%I-;;O"V1_DKC*7H@+"#.@LM*6G!7`!09Q0\A03(HMB -ML,6*/#'>C6I5XO^+7:1V7X&>L>17VZL_*1E-J03NH[QWN4H(:O_52#_>BTYN -M[?UNU/J]?``HQ4$E?'*+Z.U7Q1UE5/1(`Y-;'RY!HMZ&J^$X].>6"JXIAAKP -MUU:EJ*&%@B4\SZP'6QLP]"=TQPG48*0'FI8+'5AM6#L^#+/#4.A>(?*'+*<( -MG.7I%+G&<`AX<9YI$`L%0&_!IHOD!_F&H2=F\L[W3Q)I'/89!2;U'?#OIQ6! -M(\O1EMW(1U9K?+4AP8.#_'Q6Y`\:K#^1,JU)HULEA=43#MO,J?7R_.9+TCC- -M)21=`0'=OKMS0P-LCD5,"2J9-,))F,+5$>3?XDB+Q)QZ6MZ%1EVM#FHN565G -M7[Y"(^27/BD9V$`F/Y9&1'SDT51]G]R\?\ED3%D/(9Q`\;6VSB$MGU_K?A&- -MUECQ'0^AA<`DCC`F#:IW_9:Z%A+/4#KC2%&DG4JI'**L%_I)R>,:^+'->FU6 -M[U",'YSS5E8M\F>EEDIZ!ZQK:2PAHZ,G=UQQ.A1=>.?%"W.A$4,7""$=]L>G -M4U.?+^V\6B;J*K*]R_MV&9[C.R\S#)G#&>0C;=6*$1.+U;=Z:*+`[UJTC?K> -M(%YL5RKX,ER-0%B+-];!!*IKWT -M-@NN_,CC7%#],<7BVTTO',C7RK,PBUM&#:OY1,XN(XP94HR/!3\;<1!<>9IV=)E5==:.V'HJJ#NXJU -M5;&B<7^NO[G;^F]5--!_Z.CC)?9=X4>@B9]]=O1<.=,Y(HE.M?B)J"[OI@(7 -M_%$8X_Z)QJH8IO$F74U34NL&^\@R?H9<`_.Q>"'UP)8<$:@.(^$T8NK((S\% -M+/\XWJ8IW\4;9M.=+I?@5]A/,##_8LK2=R>YQB?XI)/4%@H2E+4$XFG9'0.J8.^I7V -MQ&>>.3Z;N&3A6(`[!=\U?&2%##>1C?U_2[1X?JS=(GTY7>8$2@_#(R?6Q^$X -M6VL0;/S.-0_$Z$V3DNK]J--4-]!MNBL^813EQ74G#M<5>)W^5%Q.H%6>'`?` -M1"O^%''"[X>I$@>XERB\]`7A1A%UW[CF*"5X\,K(-3N?T^M3+I*_C?]NR^J# -M(G3PBFQNU>)?1VG'!>N&/116)FWH\C2/,+7P,1QL`>!>K%\1G8.P0T$4^?0$ -M`WNL2D&M=SR@^4Q2@L)DCIO"G:[0NGDS#L%Y"PB7EG&*&U-/F4;]//Z&8C(< -M1A]_6W#])3E,](#*>6>6`/EJ(*AVQ>)M#YX)0:^?YKL\6,D)>K]^0/2P9I.887C^%NKWB4LR4'T3*:\8$1IC:N1E* -MNI##WR(^['0?+)OL1@#-=TQ.A-.VR4%;.MI)&L@=]J_NAR$"A&9[*[_1F4F" -MAT_OG!B@-2_;RR0BEH[C_)8RRZH=U88R*DB^CKZ2J^T8X=(T1-3A7^A]9S@$ -M*B/9#;A&3=FQU_;E*:?%V=7@ -M7DJLV^!K8I;PH7@8I&3&IVGKCE"4AH/89_2+9(^Y[[5$V+&N)E4U]L,[7%TDUR:"U9=#@7JXBT -M?`#N,+<$R+7%PEC,S'D,VI5$,6FS%"0!`$K`2NK^.Y%M]V`R7,9?FL#&%WH: -M/S0#?AI<)SIC-$;(=YC**35:"ZBXU$AQC[U?@JGIE6.#3,BLM^<,L8!<:!J# -M((:H)]5(L23"3%4+4N$!N*%I858^MFR=M2\#(:?9)Z5&C60.("N_A&EH1!`6 -M6F?D`F]+YMZ?U`^I5?FBQ6Y_,L?!R#C4;$4*1!9]([L&;-[W9!'$NWP`NW'.[]?D9?2>)U4!5HH -ML8@()=3SAF -MG1Q4EE!U!VN&ILJ&J?*9K8U$;'/HV0F%SGU+-".]/0V\R)*_G209[4J3I)H# -M&8.JJ6N1!-4"EI>`JU%%S6[7:^FX<(45X'6U0;96;&1H*UPK6O9NP&>"*K-J -M\]678BZ!$'4`E6R"%IVCFY`1';^0H_*P]WW*-D\4!E>J_44%)$G2Z98A8L9G -M?D>&M[LQ'IM]%OL'R`5`V<5"_4_@@`P0L/:"U.N:RK<[,5XGX$=1X^GRZ4%O -MR7?Z$Z.!T4:4]%QPAD#3>]-9SL6NBT_"MEEWUP;D7OHZ[$>;T83@:6=V7_@R -MCZW)_)AB:BN\U+E1BQ`(3OO5A0X!MJW4,'OQQ(.:J&CVBZ]'X@62*GJ4 -M:H5D!!+R4$!?^:_G]0L$[O^@T#EIT-XNACE8?? -M*=^![>+6C#FQ0I]966J1,*EO1[CZAF9='NAI]`*383%,0I5U05FR0Q$G.%#Z -M)1Z!X$+H5^':E%]RX>%Z?#JOMOH\Q-J\&R_(:B:X\[""CV`%E-@IC1==,$^I -MCQU5/KIFDB5T,>_-Y4GTQ-!G9QNUBX -M!CN.ON/2D^!88650-I(2T]T.EC@@/GF`,+/YD/,L`EKM\9ZF!CT0![AE'L:CNFE)NE+[N -M`F>M:`NJ%(3*'MD"OMOG",-0-WQK3.(89):CE$J!+5:RGL/OSCAY]G7[_+`(S9MY7%8BI(8MZ9R-R& -M(YR`D1/Z+;;QY=5MOTS4H$#/*I_XH^D^AFXT@S1FIYW)5:FRHZ?^C#S!IPBE5O -M'6W.S:7JFL_*67Z^.L,8!_,U)P16##)]%2A+;8"S/-0PID@\FQ.\IZH4)<-' -M?[PAGT$6%5`4/Y4VI8.O6"9\0JG3,(.2\0:*8US#JL$*M!%(J&^VFP,7Z4T2 -MR2-4XIN6OO#*^/73CH>@$!Y[3$"@M0]Q,0YRXS/1M9VA[OR8K+:D-MHFI<5? -M9=S1F=.(_F8`ZJ2_Y/C$<5]5$VWLFK.40-?`\Q+XS=*_'&,+,9:9A(NQ%T"; -M/0D39!86#V$0P,&1YV;H7;,A0J?T)2!]>PSG%H6TO.5"A1CNA')+A#8&6 -MO[V^N)_LO48V/WJY8[4O^;&Z$?Z4DCT<#G+C"W!@RM_,3-:_!O?@":G7%KZ/ -MRVM%ERP#(%U_^GCU$JSS'A%1[.*_.MH8!]LSA$TL1J')L07J3^^5A]9!1RH& -M=$[0F43PYVH!]_Q=%&&>=P,PNA2#3Y5;C@)W\8<[:U#66P&*?8JRVPZ%>DM` -M!=/>:R&N(B(,>?RW -M!*M4AO'M^>;W=(Z>:1_6PZO?R.Q;2W"+Y+5_GWTT%'GUHN,%9G>8&Q*?10$< -MZZ#I>T1KH`P.8GS$PCD)>WF>*];$8W@XWL]>(64DQ8N$+K>99=C@^EM'@N?7 -M#6^^`[T?@BW@I%$B7H,!-^![_AO9&KZI6&&`@CC?@6;WN+EZ1! -M9#`WD514=^9@2@('MKJP[J`&WSSNCA9X$6^F/*P9Q*.E*EED_+'0A0K2^-<@ -M\F:T4,X5"[[Q\V4^S01/,L3TKF7;'H(6'KZ2WL.?^R$6LVQ"K$,9O)2U<7F] -M@VIJ:D0+9U,P)Y*H@W_'*PMYWVU>W8@U.Z>5JGF5,)I9C)LW2YVN&(B8]@]V -M;[-F5&9D5V'Y)O@RB-:N!B:1YFH%@RA;;YK2:VHS;VM9_W$^F)Y40^L?`NRL -M*=V@L*O#I?=I`H@NE:64;V%"B3\$R#]00L4 -M5.>=-^SNCS4WREOJ;3450]'#B+>U[)SF!M15Y(JWD\M%73RZLZI)EW+8=Y`.&_ -M;"CKOJ&OY.TY1@_0@C'F:(<[6).'ESBAW).J\\C'W9!/[H?E2NO1'9V;'=A^ -M5?@@PH8P7(I:AS,\//'\KA!8@BMS(XJQP(CH,X%F$H8]F-,((JUM6(%7IJ=' -MK%@^PY8HI'E86J/V?A(V+/'`--7O$4^ZZ/I0E:<%JKE]YB#)MIFRVCIU>B7= -M'\\\S;'S@`(J+U1U3;8?I">/W\R`39F%]8#]SE.!&^9Z6_D_=M1R-LLL!YL] -MI%EW!%Z^VTW"UX#"C,UU`KISSP8@FDQ,3`0AA!.`U-&%!:``=.J-*?LYAPW; -M[2L"N.FGU1;9$YY_IT(NO6Q6%`K.*`>%O3&^"T^K9Q&D1)C3KOKY750.^$PZ -M-!?$R!_Q20ZXJDD1@-EL?DR1`_WSW%*DILZ8`BH[* -MRNY1`G!G($O6'K\>1H5*!1V96&?0%.$="J*YECDE3=+KOD#UZ']\R)QP2O(S -MU%U#(-@\5]%_5!55=XK)[[8;2K#&\8MI+?$NL?AG@<$@K_G4$9,80I3F8K[' -MEDYC#HO]+!)1&7X0Z%I@@7\[JI.69)0*G`.`D)L7WN[$T_\2@KFVB,FOB*/; -M?2:&L_Q:=ZDP6I`Z1*N'<,L66ZFRB`.D.*5KX!(TAJA9BNS/0QMI2]A9$0*FD%Z9*4PRXQ&5>, -MV?IX28^O2NJT[PSPNEU<4TK6?+Z7LH&@XH9\Q+9IP6IY**8:TKB*9U;YV%B3 -ML.JYRM4/13X$&[OY(G6!%=;Z,4RZ;I:#P,JG'FJJ"#P;4P9,]2E2-K/8XG\# -M=/Q-QH7*2S-"$+I3PD?#;\FR^<$'-M_FK';=H[]YK-Y>4.541ZS]YFL+PJ;K -MSD>*)LD7OF1VF.9*<5W-"5\XH-U@)CMA9%7.O7>E0/VQ7P)UX$0``K*!;C6& -M*02W_M698YK8F])S]#.V/UCTVW)6[_=L+:2.K]`NR*`5A6+&(E6WO/7*K!?M,C&B3-[Z9=]\-738!&V8(MKW.P)YDC&UO'3R'"?3HA]Q4 -M`:O)\]174NF:>BCAT.M<@JLI(NW$_$5&0=;^!^SR=3H!CA*X.F36WTOM'"7^BZIIZ)$V+J74EFYCC:'U9T4Q&\MJ']=.&!+4;4.JD#K2D4)O4# -MO1T"3RI[[6.D>0[0Q1[;EKR97YGN$VN3\1V9D?K.`(`[UU#I/EQ`$5KD1$B+ -M^>B2?J!O%@5ZJ#R`/AKR0JG"7X[0*Z08&C';!-W8R:`3"_]X<,+'_CK;">L4 -M-GD6@"7*P+.7@16E`CQ+;G.!W(Y/?:!G1`5M:BNFEV%D=0=W:2N5#O$9UE%Q -M0_@S/;W7)"-#=L97XMVI72O\M>>!ATT!NR6A:=Y_P(KRYU,.GFX&&ZBMMC"R -M0L<&U:D:4^QK97`1$4;3S?6Q@YYWKL#0K1"R>7-9\J5P`BC//>[WT` -MX.QI+&)>D.6%IPXSD$\ST#:#A*<%IKZSK)B^L[QVA<:_V]C7%[CI@E?R)=2` -MEP=+&L]EDE:N4J)R4SQ@I6(TIV23*ZQ/,&4LXFDA#<$V#^A3E)/;NW)N5'\= -MNK3;@VL9+WCQR@Q=0@G9[.F68#3=M.V2I7%<@EWHM%R&;B08/=BC(\-XR:2H -MG@OH6G5?T%AE@Z/$.G&_QH031LZMI"F^!._7]X7X]"/]H/\M&3$>_2N%CX`,DQ:Y9$;FGJ>F"'<*"4[KM5;G';0IZV4CDS!BD5Q#(J6*UB2#_*%-ZI4.@^"`J[V;9L -MGK\U++*_:J:4#4SO9I6E\$;[#4#N`\-"\SJUV[)W'V8'LDU=?VUE -MO;[5NG'=@V``1*""G'&.G^3ZD,O#M,8\P)^0&`M^>HS>3\>=_6E""R--S*Q# -MD;)@3BK8QO$G7+Y@QG:T&N4X(NZ"+Q)@[W&J6X9T(RJ2VU=Q#!=`U8Y%\O8[ -M%>#V)1'_G\SONF#O1"5*F_-J%/ER5FK;9.YI=\(9B1PG5]14TCT`2#X14 -M]S&:S%,$56)G=7(S[[NI,&9;3!T&OG/`.9R'Y&L"'IF;I>"?1]>/H`G7-?7 -MHM#]W/'>TQ5FPO2'\G)X0K&O(P4+U8;*H"P71M"-5^*G]U-]N'\'<(NX$LD# -M]"H85,2?+(5U(JA=$:"G-J?QQV%4_3\F]5BA8_>(&J,/L$"/>.V%LW;-:7F" -M&GS\":?7ASSZPNT0=6Y6RA4*$0)"3>0P/)-AZ),E2E%0=V*+\C,W'"T__BGT -MF?:)^G^25@U>X@I"NH5L2U4$%`>&6KZCG>C% -MO/\&2<(]^*4/MWFU'E^::)*=WU)JW*TW)CZ1-3IAI6Y=\$!$H -M[#'G`@D@!RS&6VYPKP&A6&-29'LBN#NY\`7%/[40&`63G;,`@+,]=KF6=/-4 -MS-L,&6Q.?MB#57W9,*<$PE=OTKLY6;M_VKTYP29%B@)P8N;KF!07W]9UO]LO -M&LHYQABJ"*Q?-EA+O.C)>H^?.*=8Q\AN'JR,+U"C(^WAR+Q%S5R-8BYG/^DM -M]_Q1@SSQP6PDX8(.M]TLBL_KLC3VN1NV-^%E")'%IR2>?9W#5*E,0THQX)GN -M+[#%H)>-H@$I#:YV8...5F?*U'1?-\1*FL]48%F!0:DM&`SV"^WD0& -M$GZ9#J#I"J==$`RU73N8:>W!%5>;_,P&G$#L2V#`FRW>/1+"T:05GH]EIY/O -M"!:6FBEJC9;HR&;O6UG%>9M+.3J)TT=:$`IY`$($K3"2@M'#B*][K0DI<9PB*2%E; -M%O2\?%I.QH8HU8T/[$CMUE:[41Z<$B"S:E1?/RD7!#,/KDR.+@[4*7&`Q@-Q -ME8`49I>]1Z!:@;!4T![VB''$O;R_?-":%WBV/4JYKU*PF'F/UDXK4(4^].Q. -MA'P%U_,^`3Z).9#!&>SO?L?MB0^%]N&M'L8VG738"Y,G\UFEECH4?U!E.Q>%^]VA,R3XIFQ3R[ENQBPC%_ -M#Z^BI*!$<.0*`(8Q#M=(=&>DF1OGBB0;IS6J)S[G+6V_608"9N2SG:TJQ9(9 -MN">"3H1RE/;"P59B)#>7)..6<0.A#*7P$1.ER^B9DE^+U&Z;QQ-(P>U -MD51K8^=O>95BN6)C917X?LL:>"P3=-?@NXB`;T\7O%1\I'7K&X1N6;>5AFEY -M^V\%];=;ZM0[:10R\YU'9Q:*-2AAYHX]12#*@71?]EMKPH5!3I[J47@SIPL5>&_M_W&A -M#&S&P2-Z&:[N%O%ESSW3/0$8B(TX#]OB&C="V&=RA72I<6TD;-.69,7(F*.O23* -M)TC']<[3IUAR&^360Z5O@9].J3V!%6@?&:*=7NV# -MH.C76[S"W>&1@5TP:RF2@GK!;DI2I75,6!D391"I>(GC3.A/W0\C1JB=&F5E -MG\U:&BAL\M=?A[-5=#]_BT8R[[#W#9-=PO/'@)S7T1[[CVB#3=SQ%_Z_C4S07 -M0*$@'J'W7I*LY3G0*DQE:@RZ?M/#7.9G%MPDK;Y:)-R(69BHN3R07+XS(S6'@.)>V5%\^I0HWB[U-!Q>1UDCV -M>,OF(4QJD_^V7)(K*7RBMU`M:)WB^OFWR"9T/T[\4O^P[',KE108I==>*+I#4+#&/?I;F/2''^:!6X'2AAB -M],!0OOI7>ZOX3GS(LC#;*>`@/3@?%OQ8.3RK"MJ8J&,##/"QW/`CKV^,)3B@ -MHS(DX`WL1,^(3.&P+\``\%TXKE$832N1/1QIY^$+2259 -MZLL]++351G2P]"T#]BXGX&7#DEF%9EO%?GRW4?H\#J2:D;/X/T;OA?K#<+N/ -M\?_#3()<]OIU4IWG6]F+0_II6N7V1@!$A9DX'7!"/_X'X5F+!C!F.MKVL2*= -MQJQ])P;];+MIY'82XC,_B_N(,,VL7&?.G1RD9M0AM2M'?WMTBI7/K(`YZ[R*8 -MV5?ZH?*III(ZCX`RZ]L\B#.TY1!1Z:M='([C<;;X6L1/ZVQS`[F+G@5A4H?A -M<+:"$UT7-$*V!'"78OS0SJH9V;WS[?8<%;Z8*`=&ID]`B1!OZLA7BO.=N;G< -M@L#?49G<7[IVATBCOIOO2_].N[U)7QK6N*"`YGV'$O0B=69-6@'#QRK'<'*< -MFX'3'(9Y-;MR1P;(WV*A&.P@/N9Y/!UUN%/N@:[(L?;?,PT&U^QYI(+Q$?^.]'T^7%)J^/FFJ8^_)\]N[B<)U*`._?DN[_-W -M/,*T&;9DX!0X95]$5OH:/9^A^^.`(_1I92!X7Z'(O1Q:KPA5XYUTWEV*A@X9 -M)J.)=N%`60-^#@B-Q37Y5P44;Z,"ACMY-N::[TR:AJ>K_P7.AQ]>+2.F -MT&;):GF2>/'YICV(F:96PFF*T;YV61(4%3I*<.P)ZDX&7B?6"O#:ZPH!"%"G -M<0][F5\+&9F92Z<[[_>A#$JP/D=CP\NPX-@*[IC',M*/#Q92UA<&EM?P%62%"K@:O -MUC.X:4#VM!.=!20OW`R7H-L0`9D$&=&5-'K0;;T7V3F_))<`8@G5A#2WP)X3 -M8E<]5KFTCNO&W?*[[DZS8=#`UZ'T05$?=09`F[EA$&I&[E^KBP.=[PX]Z,3^ -M"^`7855-48NH%X_=RTK_J)EKO<-!J7H7N#AHMDO\W6])PF_$#H/A@HUO."O256 -M>J&\'JX]2SP.P`&SJ^].1S!`6#%$%:;QM9&-5NM.I)RDY=XN@OS4 -M]I7W$=E'ADA2)BH3$#ZUJC=;&?G+?U_1.1M#A:@P+ -M=U4UVTAXU`;1`QP#3=COA\E4*YLC[.X)AQD[4)P[/AXH*2PH+_G[VEPP?_9G -MLU3>QD&A>*HWM&6870;'&@Y?I=I[/"2'>947_&%+IB6.9=[Y.?J!@?-P?+)Z -M(3\,L?TM!?E@X$EL7QN3PWYP)/5#Q:8+(:+W&XE -MKUQ@AUP>R,707Z9'H4W88PLV5AE0?H1QOX$9"MC=#5$SBPG5=5#P5D:TA6S, -M\]QSRA/.(T/F?9=VPZ$8IN\A -MW=]^\Q+9(/^Q5VJDU;&.I90C`[@XBC5@+RN0YFO^6)V#T(O3/?I]6(Z'][9/ -MAZ%#<(=:)-)`=)-U\R"Q[LC1;P)5S4UQTE3/`D@_R.7*[`C"M)'&`=&1W& -M-X,3;6T&^&6#!2)]_\/2P5*(-"6=FM\/N&"G2T"&8(EBJ;I;473TKRCS+B6` -MF29!&4!D9`3<1%2KXZ,B\2G^P[R?"UQDUE,^DCHX*=3=@YHL>P?F][/U16!N28-/+,+>MKJ/[4U1>\ -MY(2,DQDV3/ZA=50S3XZ5[H#X2,N=8V/%^I7O01+O-==.D -MGIXCD^YM&.UPIS-P;OKJ#N!(6)/-`\FT\@!1ODCQYX>QULF?RGG5P^IX\H?- -M:X-RZRC=LBK.]31\WD!?$D=7+C1#)J=EWNJ>'6&A]/W2@\U+2>&I1)KK0T4L -M$RO?-.%DQ%">$J%H()B`(KG"F1`]7BZ2NUSR*KYUZZ>4!]/-@1S,Z)!-U;`N -MWHT:='/_'D!G7UXX;S,=VHHKUH)IZ]]]S"6`[6#D6K2_3@2NBX)U6RN6,)-- -ME:KT>$7]5;7D>K[I]P'3R7+12Q52S@KR`$6OT$@5]OXS.Q-`YPR3&:OIW"Q] -M&TE=XPV5R*JNFJ)\:0UM(^WVI%X@LA0/0P3 -MAX4[AW5<\7ADN&-5A68%M+\H=]P3SH\DIDI@P6R?5M!I7N`6+4SD(W>S]%>8 -M%A9T?U%0`/-;9A.F%QEGF+#@Y;1*P&&I0'/]N>KWLRJGU`2XW?V`RC?7T3974A99T*K7X -M@A\:2XW-2'J3N>&0(R&58$VUHZIS`D;SOTNQG\,R!/;^JS!&B>##=X^-J_M7 -M6(_$4V/4&[$."`,U4::^ISXB5AG"BR+.`K%GDD^"UB"D[12+J&`CPKW0X*H9 -M6'*5'D:;*-F=*#(W9-DY93WA\"F`*:^ -M)2?FW$?F4'!?#IOU_,$';.U\E4<7C*';V)L*&UC?G\S."FDR\FXE)SUN$QV8 -M?&J*L$_-[52\NGL^[J+:RLG=&$_DB27\ZU1E#::C?6-M.3')/?<+31#*77;-N"*051'` -M;^D!BBL53;!DM?[_.'5V^+Y8B>%+:^2/JG@N(GXA[=.*XQ:LR0!/%,S;>?3*_-GEC1%_S479PO8 -M[0H$Z^LW+98/R*_)0?#IGS9CR)V>]V+:C5HW-[N7^#6H-V*6P.;K/NN07"HH -MK)(_9LIEFW3!&\0R*L)2)JR-O'?1H`8;XOHAH?^`C1<608=]Q15?BI5?@D+OP%.:7Y?O -M[WHW/SXJ@3XCHWM5UBM?SS7)M-,=TPW70%+289=A2*.D-JTMOVIZ@^6?9S"^ -M1^C>8HBL$!*TC+@%_[88ZXD5`8@RG5;Y`-S9Y^(E)/SG3>=ZE0Q%Z:O#?SL/ -MOYJN-YG0!GV^WZ4<:'X4JNRLEUTO%YU#BN;>?D-%WI+TX;#1A6G'H:E@+>UB -M;HD^;<\,TIS9*@R6)5$H>8B&@X&ZM#K)$IA+A3P"%S8ZOXHR1MS9L[?TM?QP -MYA*URNH".]U#KLHCY6/W%_Q.1F*WBB.NI67_G+9M`*(UY*%0S)X<7',,I2C4 -M/0H39>)8TA[9L@SNS!&O8/8E&_P`\&GC-%K]19_QLW_4.I4U!)0#9\Y3O]V. -MKD\S>@_^VZ@R$_/?@ZC'/Q\QPW?AP`RW*=1K$^5::_L1':R3TUR1AYOX*H*8 -MTU%A70D08$>E(URTMH>>XC1[Y1,&UQ",UQQ",_Q&?KYAVBBO]5N@4%K[E5K- -M:M"6+07(Z-M1!\L4!.CIGBWT29YT_#H`47C[9F;3+52/0@M1X6&%PI;WO -M'Z*R%&[,8[/>4-[O/[A@'1YY?-HR9GI+3&TMQ+G-<8"_/!VBCQ=K&"LB"8(Y -MIR:LMN/_+GFH),XE987[#PAELYHRZAUCI'QP*`FL3%A+Y.D_]#J_0#$W?2O" -M-,D,T*)E1PHPJ'6L[@J0S!]S$_=:7^/N5C0]-,L7CT%K9ER;\M*7LGM<0>C$ -MYI4-]DZVJ!(\DU@[_8!J#+QXZXX9CYLVS>9_DTPH4+2K\`L -M"G3"F"BIX6_H[O[?"30_#>=A7)>MI78#U(_915Q?M.">P"C@<6!7B)5FH7J3 -MQVK4IMQ/M>C:)X)]>:/B!.`#RAW&%XPH#A%UQ8`HS2EMKR5EFTR\F]6@'1>D -ML%#+5_LDX<\[]\I470(>>BO&*[O>9A,+ID9[R,ZWD6Q\73C='KA"F!B0KN\K -MI`[+2N@B"^))+XQCU.=H=J4/!#M2,BG2\;T%H*QSE5W';VGN2C0*3L)PGF?2 -M=9$#R%ORF:J5R5N""55UKUPW^.W<>Q?0WJ=)!=>&9&P;59.XK%!SB/X96U83H7NW5TUQ^P0\`OXL -M%4(=CLFH0O)+=/.#8RM^&`/`K*K[JV?,O<7,'GON#VHFV>G:=?ZKN&!+V`;. -MCDDX;L34O^HINU803-)H,*$JA1EB5;96&JTNXZET2RC4I'HR%XW(SY;;$'6G -M-YA/K8NLBS`!UX8WDOXU.K+AU4IF#Q]AJI9U;15T9=-]6I14%`*$Y[B'?XND -M(PGUH[2\B[#,(V+?I9AZ([OJ')\%.SF/_=MB;QL::WC3R2BGD9-9V?JHO=R%F+5_N![;C_('!J!X[-F[B/T$3&F -ML0#B+)Z"$'D6!`T`=E\6)2\9V#>3L7=Z'52["_J>WFY[52_=QF;.D0T2A06M -MIL3$/:RGPV5PXB<,]*O9S52)V?);4%0KK=J]`.ZIY8!K[MFQCS6)NG[!F(X\`8I!A!=HS`*>*3#8BBXJ9*,@==;T)-1G=,T!^>^KVQ;W4IQRZK`HS#P3^J?"KQ)A.SH\92 -M&AT5]TH;%6X;U;A/`5IS`9(#WB^X4K26H6V!)P?266:@\X_PU/B:U.<\YH%N;]+4>SHG%+!"2_=5,SE*904%01(:* -M$+DF1/0X--YPF(LX"$/3D1(ZL"%V6S[>,@JIQK!D6B+8>X.HP[2%N[!M0L)\1F("6&7A#AC@([]IP*^JM0O=&21QOX[2PJL' -M>P`B,AGP?"N)NK3D-2S!P=AH/5%E;`DLO-2/_%<>O$ED\VK&BK\&]H\I#=72 -MMBE1ORYH_Z045LQ`J11%SN;Z1W2D)DNWFNY,Y13HAS@+;0.APLHF[&V[#K,$3C*"(/_)N -M)Y)OLMGP-^AUH+S;@L[``KYJ9O+T%@[^E*H9FW9C#A9GK(.O#SFJ(P%K;,O,-)&_>>G>]R$!"R8CD+ -MU(,P2O#8==$8\EMW4"8_I`XKIEL=>7CQ9\R1,6S]X/9X*(NCC/D1)>Q82&]O -M7`5(H_,8YO[L;!`>=M?;^:LFW6Q1+O?VI<-TTS1WH#\YRT^8;7^RT[+]+@I] -M4BBXT7M/;6L@^9U(?Q629\1EU?=D7]?;PGRV:`/5`45&A\@*>4``X7INY%/* -MZL0]4&?(6;33^W:H>D<9WSRA7?;YE6I6HLV'4+7,T+Y$>7`3XI*(;=,<;PS^ -MT5DM@HH;#)F,_(F9^87]_G@P%G8.;![OH*+9?>A#Z<49OB,1&;E@2]+$7.6S -M6<8?OAIULC,'NA/;K;MZ@>J(P6[IF6Q]2FFNT!(9@`PPI#+?RR-:XC249UF"V%-/"*CHD\K1 -MV+8\6NU6Z5-J]>5R45I57^Q3\1SB%6T<1XR%#'R#5I>?:8QL9;.5BH&Z*LZS -M;JAMM!`K\L:VIB:,_N9/T':@,5.*WX&FHHU1VY(=T%$)&'>V_,[>10K6<3]Z -MBT'PAL/LR\?A.33(75^CG(I_O7VW!EDOD!8H]0MX[5DS`GXC^UI25:N]G/P7 -MSQ)"1D3:3>C"8-\RQ)4OPE>8\P]-S/7[7RKS?:81(W&A4>^:89H`8!]297!4 -M+?U0<37-5ORSWLQ^I3CC[.U@T2H/]]GZ\AA.EIJ7L,$!0+>YWK,-7[VE^ -MT92ZD2'%;VS^SO=\WO?%LBB)4!:-JP*B"&W]TM[1, -M?[+C"W3VL*CJ++]JCKK]F`%S3C9;`M8&V,>!#OB`11])@J/1^_'RA#;0/9)( -ME#IO71OX,S*3/0NK9I^PR14')IBM)QQ<=Q)6+B%.$2KF[HW6?'1-WTN,5%E9 -MFJNVOT95T1!7<+=K'UJUQJ00;G%D5&^2\`:-0#4HMD4A0WU!&1VDD8,$:S$B7Y4H'J,"SX5?MS_5U>DL0;)8&UI.#\\FJ]+ -M(BR*KIL8?[#N']RZ+2A&1:Z8@CN`M3_2WG(VVH.)9I/4!&,@%]O;GMR)6_\[ -MK8H]IUW]X#J'=-&VL$-D0F0REFIOW''9]E-B@>RKREU!O^<.Y:MG_+D)P!]-;P=FHD5K]W*-%R -M5?;"6\*BQ"M+K3`B%DV+RRNCWR\=IXL=X54*X1!9H`X)7`;_Z,@.F(+$>N@U,V2IL?]Y9^,&5P^Z5/BEMW$(6T.("_^$?^C@_X_H,1%5X4F*@9OIEZWUP`-G7)08Z++3!W33O%:%0?!6TX8MS= -MC-9#S$VS>$K%`OTTX^2SL]CV_"&IF/=*B+6?Y$\E3A(.-,_Y=RD$C`0.HP&= -MLBJV"\IYB+1>=&]O6"#3>/+T:?Q9:0X7V'#U891UPK?OW5$9C5CV+='0GV<[ -MXEZ6)Q1O]T2F]\*DARKE9W1]4+Y28/[M9*FI]%E<*)793'_X*J0+=#"^Z`.' -M''HT;(L6VPR',DPK/_?EJQZ)CF0FYX6\G2J -M,`@P4:&E-V[:QD=/)A"J;,3'CW%@C=_=<#_LSL-#+I?5FC#\;OZF]8,U6`U` -MVHG81Z>3%*9-],@5RL_WGH?P[;F!RP]C380XW$N#(_ZNDQ$4,%_YFM>XO.@KNG&+IQ`"<.5'&?;^"QT)!*0-+( -M0V2@7\E3@&#[P0Y/N3NB#"I_&6P`[)I>_;_$S:R``NKT`A'?_BC](B='C@0)QTY?UEJ1C.;?^=;T]51M6+Y_2* -MJG/X\F3/W#W=%-86B2';*VMS#^*R@L2:&954V[6RSDX!Y0::12K>8CCK6,^" -M)I[F`)J2^VWH8T76?-TU[U\S*LB:F7\*$`]LV>MC=L>%_C54M$9PV-V3-AT/ -M4NS]F/M?>+:-T>+/-IYO2"Z(-;(+ST9B/=Z'M_V^X,V2-;Q01'H54R,*2-?Z -MZ#MC1`O]_=O$1S9YFP(6O8FXL8--)%:43EY.*1,#M_8.'(WB!;V[%;ADY/'1 -MS+Y$\KX$6DF[:9UO5=R=KGBA;1T(@Q`MVU'>6.\%5A+Q*3A+B3A7_.\1U_A/ -M3*T/*6:8V2W^)CZ9J"7DD?85!8+Y6'2RG^3TZBHC'+Q4ZRUZR.U(>V$R?BZ_ -M'OQ)QW0X+283$?"P;9W"\E)19DO9Y@U/X0+X`PKM[ -MMRE>.Y/N"(LW6J>3EN-H<"ANS,TPPXR5:?CYQ-5889AN8I5@/+IEOM\O)WJ6 -MG*=K\69DM3^<,B.%"^9\X`\!Q&UM>MU!X`3DIDLM'==W',*J_N0N#<8T^&40 -M#A[>-0V\CH<9MZZT;47:MOS+1NV)/QP9.UOW^9XE.`V>NE\ZN^OA!-DW!B<< -M6@.RY*&D-4)AC/Q8C#G(!QRQ$9>!XDSYEP$%2EB+5(*@&.W6/Z"HR`F$F'0^ -M7YH2"ZJTYX8X?8_D#(5EI`D[G9S2YP+$IMVU/SO4^C9]-JC`/,V?X>%90^#+ -MQF_S\'LY@YF)A[%:4^J\50.Y1*]'1C6)*^030"$@0^J/:'PO18Y*#=XR#:Y"YO;?8A#\V[U'WPM -M:QEX4(G;@3;#F%=C::/BY?@S+NVKAH+ZN5!Q@H5+MJ6:(,RIP&VN$_HM_"DM -MRU'ZOT)04I^Q),E+&O-*S)17A@S2LRLR$7\D4;++:[Q,9X!A,O*C5ZB(.!Z@ -MM9>TG`A3>$%WJG#-7O;4QK&7:B4(IZ82`3M\$B2Y/!_N0)G))VL:V'9 -M&YC%+P5!<\1(H8[>34*50"I56U&FE.%C(5$+5E8?=;LM\!2L-?;VV.BI -MQ)5=/2O`MGPW-V8&J_ID;9I+#601.YYQ^9XI -M("`5>(R%^+RW]I`2[S<41-1*0[E(G+>EB4J],?6"ERF<*7NT1B?4:YESNM&5 -M=X_@!^QN0!!$&J49BY3?SD/,K?@6FA0"+@1$#QM-GTK1/2CJ(0&F=J`GJGOZ -M>>ODW>3G!JOFA8%03[I:EZEF@RSD:%<$@9,_HJ?V#+\R%U[Q_= -MO>8]).LRRQS0="I@E]X\''E(PL)WSM;CRBU&K`;L\<)M5G;9"G\,8I> -M$CJ@)/5[0VZU;">)I88)M32E5PSFZ0<'E9BJNQO`^%XH6F6TL6^JW]M>CK^J -MDHZ^2A@I`];)/*'95($VK[,0/1@GK0\K6Q=M]5<^,LNLY\*#\D!Q,2*$\HI! -M9:A"Z`B_;,K.9V')H@Y"PT!8F,B4?\Q!]]NM=7V/N<.;7'!+UD1_`1TO-._! -M\22/F#N2AE`N$>H/$_2P=W!-_Q1//=GN(XF3'@"2,%Q&1C!5#2OD+'(QX'<& -M;SH.%N@BAM4Y[@0N=Q -M\ZJ!NL/"Z+P:.$OYK+:1GO3%XZ4/>P:A"<6=@5@N9DG_#<:P=\,*G.P@'7?" -M;UXJ)X.ZT?3>G@>I8Z$WIJ2PX'0IN0^>JVY4FP&?)YSGYG?3NRZ8[[TMMEU_$AK:".-F$SY*IOC1#?Z48"7V5HO9;@"(<((TNP&RD5U]'=FLE4FH0;O[CN\$3/05+ -M'!Q(6K!CWN*?<1%Y4_U^`;%*BJ,I/YLD^W3&+AL)W>@U=J5\%&=`/5J8(%%W -M2UZLG#Z/L\0LY>Y;WZ?0J>$/7*!M&J -M/\[)O*!F'\6I#2CCQS8XZG3&.?+((+5-3W7`ESEX69F$(VK)_:U-[O2`)RR/ -MK]W:SN3\E1?WU-B]^H2N%X''F7IH)RA;JV]LK;Q^4RO-'8J'_\_8>XI]7#31 -M]B7\>$$N"9U:]R$)_R&`N$(N66'V/CT?E3D)X\;QDA7-[)>K`>6U=2AU'#?I -MP^QC6DT$`*R%NOPD76,M:&/S%XN:9"2;^*U*J'+L(D_R/6IDF]%-(2N]K#$3 -M=?L=B$AS.S9F7(!@[@X7)&XXHDA1FMC*P2'+0RT1+]$M"B\9:00YLFHA&SY" -MSCX\4>VHOE!;@6DV'='+105`_\`U\$^5;#NH5-\.XXK.0@=Y"IN%Q -M0$Q(WL6;'>9E`UMN^7LVV&I'16TAW9R,&"C+0XGU>Y10&9%-\`SL=^IJ%`=NV=`\ZMDS%P$%*22V@5]$%NUJS[7JHY-H^%[ -MP%5B_NR7RL'PW*4NQU#+76B5+9ZB:1N+!(_5\>8L611/D8>+'757^+3!$."X -MD&O3^X<!!Z9Y#,DHO?RS=CT)M_EQVYUTB40)4GTLT,] -MU1S%88W%7*B^&1*(UKC7T_R-E"-YL9GON8)XV*_J8T3PSF*:U$J5&?`N.O59L+WDYR:1H`H=;W!$F[ -M\A`_RYK$PB_\;7-OE-=>H;=E9]__-*O;3G9"DBSU\D^T?E-)/@Y?#'FCB/FY -MZ'XR$!DM7G$ -M_EXZG#-I80"JN%C62SP=[H!8,.BO`\\'`42/J*XS(=ZRIYU55THO"1S4;9J# -M/3A2O)?0&8?<-_:#H(V98>9G`BH]2]]W^.;0*V_/I;GCF#2WQX8.>[S1^5%. -M$KDA"$'!V;]<0>9=AG03JD,JI-E-@"BU=*00;JT"5IX'O".^+;T:J\Y!"2\&OF2,2*M?GI:OQP^QZ8M'C@5+I`^`$,TYU-QN<&5ED;=X_68IP+7F -MAFX\+8N^H(F4E2_T#!%E+ETZV7U?M,O9)\G>9SN;A7C"W)7QMED3EB4?"3/>@?)]%#0)7899E'.#;4D#9& -MEL"7Y=6D/?GI<5.`*47Z$)+-I]-@UWZT3_9+5#NZW'9+$%[LF[)WA#]B4"KT -MZFZ3!6:C0C78O1Q<,8K[2/B];A5NEP]<#8?"@&,HNT3@+[L3GR!;@`Y>2A67 -MP*QER4/]JCA=!>X][-I$W$B*35:$<_1_9V%0@X18Y&6=<:_=:C,6X*YYM!V[ -M^A6=!=)>(9RU;*ZN5&@$H<-?J(:YDE*J%6U*__L#B#V[_*1R-R83L8((XC:B -MK=_J:[X-OD0]2A"OS.EP:S4]E^W!'?[R_<%`5-;V!CH2(06 -MWPF-U($<.?+9V[EZIV)J4L_TAW+3@UY8H`0+6R_[?2%D;!4"E/6A![@(7BSY -M/1\:,1XV3!)0$4R#CWP_I(POA@U3`$>XLBATMBRD835$OSB<&R&\OI]3EX=;J=$.% -M>]!:KC:PO*8&.4XD_U4!:T2(X$5U>I`AU(0.\F+MA:KTG+DJ'*U7\T_@)44M -MV"5K=FUW%3T+<4DXO)N`&/3^/=@6B2N6WE3OTX^ABC`7".J[Y@L60+<*&>)9 -M2O:Q@MZXU,D$U\4\AR@8&N`=WLDMM70D@EODNPXXXI+.8=>=3WGETN5[5\B6 -M9R3W7V5;#C/RG:9KTZWE#03?%_*GN-=DLTH><`EBP)07A1(9X0_PBZY%?YM& -M_S6Z;=Q5R!]N_3I>\7X^`ZP^74?G"U8[I:Y^DZ'[D_P1DD8`"CVA-R>:+'WS -M[O6*)OM1L=G;>N7$6&1?8>@;<7-J>:2K2YT!22L@AB@ZF<-?WTV.)SB7YOJ> -ME;4$`3C)GGCU-@H#,'!Q^B6@X,3X0-FTF,]Y4ME76!I"Y>N,L/`IF*W2O>.4 -M@5TFHWE\I^,?@:MH.@(F_HNE*X#1/@=M7CUU=KN0$M>TI?7>63DD5>Y/3<'O/2PP1B@^5#F -MJ?'M9.+&ZZ#Q[R+3CWEC2>:;_M^X3<'_D*I?"!3;K:<%Q*2`'8/X2$!^[08' -M)_,#[1!'>O_5+=*W/7:1']X/:Q_UU8PPRL;N&#-F==$9@'<4(`J"=?-8E^^Y -M!*#"F6Y!\D8MW=Y?N,2LFN&4GJW?R``&`,W,%C@(DDB*Q/`^$/0GFJ%5#D$0 -MGBNA;5;8>FV!^3FIOSC8UY\[TS;NK"9YG;###)06JS."\G]J]TFXK7*T\Q%& -M1&,DWFEN%94]Q6_7VUUK%.B+XR.LGWOT<]`U16(]?7*FF7$/@*DP`R^GDT"& -M(65%UH8>]XB6(K^AM'XUEX,;EL;)&R,?N9>;C_+]?D\]QJA,.HLJ9-,'J0@0 -MM2-H0(8"14\']<">"_I^_GJ*J67&X"'A1_=3O3MQD/<2*'=$5ZC%+U_B('%= -M6J4'*T75U67-I\U=E-6X^?6WLU/KI2JCY610&#&@BX(1#*J3`,V/02.'M0S' -MM<^._9^RG)1A,3XJ^"M<91P&'81GLSNSESJNV'@'RE%0UFC)O#"6H@"#^R%P -M&AQ/L9[,*6U`6]P>BQ^<$"VS58+U"]+O?;FZAUR!H<_5:9T31^I3Z36JZEDJ -M8V4N-+9+0:-,$LE=8WD\W2F4Z9?PRP[JB6GG14+P]DD^K;1R%#7E=>=9LT_TM7[,0MRFCRAL4@;.3F -M5D!8\`#D*.)M2O9KXX(^ZM'M^BX+$N"+1A0".=ZLPE^01?S<;7C:T'%W3MF4 -M?W4)&PJ@\Y\O*9#.LNUF(V>VK?R$=MMCEXQ -M!J(9EMV#I[9&\^?_'X^B_XMP!OI@VB*R8SS>F8>"LP:YPA\XMH1E^`6D@3_, -M8.,3HWLT@$+T(H:QD&__A\Q#*:MGLQ'==+NR`)MH]`61YN%Q_+/X^YSIZ?=N -M523ZB"5O96N$-R]"^G\8`ZBQ[XK0[+9A]%F0K#BA*#9K&RFWP>[V!^J3!S#D -M`CN1+/748:&H2@2%0/]*JJ](3F\)S@_:I&R+8U:US9D_^<_`C4DAK -M7J>=-FY(S_MS&T*`"_3*/$#C;O+K_/3-E]E?#A%!Z)""*<)9&P?4:W#9%LJ3 -M_:=3#5@JL`JL^].=7B4W2KJO*$:N99#CN1>65G"X!1:RZ9J2TC7750ADAW:\4"575].9^P3&%4\ER*PR-2= -M/T6NP!5)$`1FO6(Z`2&_X=_02OBBR'R[0*HY7,WA+WPPQNNP9Z?=Z_--0(&K -M86-\_$'E$E,R#9])`6Y\8-155OL-N%)-[$\@%KR&[)(>>X7Q%C=1PK,Z/]>H -M8*G.Q^OSA@NPTST,Z#.#ME="J;(@U,;K(:#62A[`!^(T--JY_EOYYL67Q(G9 -MR875B*:(\00>K(=L]8.F`7GE:3?>@L^2*M8MT$<[672B_EKW:0;A!^L&^Z-A -MBI;)NG33C=EP),Q.7@>+@O1XCM,(CR*5>2(H;$)X4"TFC#1Y-4 -MQO5\7[2+..$2:(@!/ES7LO,C*F>6$4`+7@10BY%ILXTEU0XY:!.I)[#=K^+C -M#"-]N-Z"PKBOA:QVY1P^RATM^4D_;7/]*K$B&TZ0#+[;'8:&<.CX8[$]*%$/ -MJ23-;B2`%C84)\?<0_;WY1X8/)KF$^0$50E).,NXZP,X\]]<_)>#US'`"ZUP -MCALXB\C#3B\Q;<6V66",RT#3&].N.>97D62NNJL>+]S()>QT@DJV8IA!_8-J -M7+E?I\\!^%)*"W7#\*@HU',]$#\A`:D@KJWRFYN;0H]."E&=:[0SUS7!M9M4 -M$_5*`^6M99-=MB58V4^C0F&^L1L,V]5R'^BGHV,.?+]/.M5Y4UEB*FJB':!H -MRJ33;Q^EJ?QZ8]=O/J/W`=&+Z4CJ`]9SA>IVRRM@O:9`G8W;I,4T:B4J>.'P -M#^_2S#B%5G6!%9+KVV]^'U9"?T"M(?P;Z^!&+]$B.*(/E,TKEA[ -M(!Z1MX][PDK6))5^S>L_=![D5N"M#P$J6BN]OHX!/H>@3WX)KJ5?.^HU'4D; -MJ#NJ];ML@'S4Z,HZ1=T!Q_J\'5C6\4,G$70JWW4SYI;_/WM>_CJZ3+>Z(;"+I!2OP -M/>A!5W]^OX?8)XEB2I0\MV+%?<97:;VMFA"&7M>GD+KA-)4HK/(?+KK*2`=QY:HPO6PQ5,/P'JR,[V,4UWQ65RL`-R7$ -M>D^.G\N'ZJ7FC6Q>K<48EO)_O`DIG5T5H3$R_3AMMGT-.-@)I4@6E84N2N&J -M/!!-G12\G9^4][6J3SE!R-X9M99>UG -MK$H/W>;1[\:T<],UAKA$6O:R]%D9$-V:@A3H8)N["X]BF6"I*[X8,22\HC(I -MS7LT_;',`D9TIZ&=S(X_@9!'.HB803U/$H3CGQ-,^FGCU\*E9\3Q&B@Q5OJL -M'H`W"6R6+^$_;?D(7C.Z]6<&0+'/X"!`EW8Z$_PC[#-:IP"['J#1KZ=SC0\-@R< -MQ\N!^M4HTCL8QWG0P@@"Y55V5V*&8HQGBS5EV4!GE*"ANB&K&O7&3B+VU:-) -M`W1,7DVO@%#9>UIQ\]CXK2'HEX3V``;"3D=Y3'O@/9`%?!94ERX5+[V,'F\#;Y&1GCTNF^3> -MCID3P?,?MS^F@+!SG">_!(KR;#A,2ZY,R8O47HGF#M_.".3`R\F0T:>48)S7KR4M'L!"E>*,07S!=I -ME.#Y*5W5KZ_U48#!L)#2]HE?2#BP.O+@Q[R%*P]I<&WC![9!;LM3>)Q^=X\J -MX*WXVV44AQC4C[*29\QEA$&<7C1+D%?FPXH$7KR2J4I,\AUG]74*2+4%^R?Q -M0B3XWAT<2FWY!;N,/4>RK(%7I8EO[@:K,[^W>4I=K'#ET<%L6KBW@9F/WK<8 -M:LO9**C^:)TC77"47.4\)!:*^/V0F#F\<-Z05<1JJZQ9YZAAAD[`!QN2^'0[ -MZ&X+^D'6%G#Q]W704R4!+FT2212DAG2MESI]/WZC5HYTS43UYY?VV1])B"^F -MX"1C^J;?MO<'S:*TL&!C)MAL1R^HED$])7.4*,3:MHIUK\"=G9K961\ -M1$`$5;V+:@:FG!_`I&1.%*FOIWNK,PP"AR,_5A^%M`_]5;\=8Z>K?`;>+LNS -M*U]@_$5"UE?!.HS(O6R74W?YAO?OWJ:7V]^)+SUGWQ<9=7R^+9'<%G'MJF!"1#/:LVA(T/?%F[;#VI$W%'Y)1@X. -M#N`>,H+_N4C,V@FXN\1NY&7L/ZH$1*1=#VC%LN*?SE_2F1+I2.!+K3D..P8- -M)Q"#?DTX.+[$8E#>V^E#V_[`!YAY+G%P(C>OHYKM+88.[I5#>BHXGNI$I?R# -M/]R,/[2^E5\,.@^6!''AMP#;/$BQ*@6XR.)K -MCE]^*#_\Z7CWG<,I'X21['[SX6J/ -M^S"ZO>,P:8.BN5[*)"W63O)'>4'KNKYC*1"HA&*QIJLK4Z9',!G56V6_$T/U -M;SD2_M=W!01&1.80Q7C]/^M:1$U1[ZE> -M-9R5_Q06;KK+,^:0GY0_+@<\J.8 -M[BMND!#V0C62/12#$5D5@+*^@@CL.%%UQ -M2!2Z[R,_A:27AY)P!%JB?4[,E1UHFD?TP\=S@%?[4&[L".E[+E<^K#<7&/`1 -M('Z]7B]M[W;+P3;UB#S2I&IFRB>=&LS9\2F$I@MPEK5^GY':!47OI]7/"D&L -M_(H,=8B"Q$O6!$/%K8QM\:RF86,`7RXP!3]'9&9*Q:_:Z54A"UB\S6(X&Q-V -M)JNAL678TB-[:Q0(A#T0H@=(%]3$5[&Z!=]D'A7G07%FQ""-6[T@Y"E\'EEB -MTE5B.EIISB2*3\:X'-A<0,E4-95TI+N:^Q_R6O%*+.$=:*"ID1(KP8RNIA&U -MINRA80TO`.5C!]R%X[%^W#H0$K_1SFD'Y'YEB;-ZJ%VF\7B14+-"3,",@?:3!Y,AX@` -M.;?Z`DXI0QM:$4$&F_%CL6N&QNT/EHL'1O<$QEW4&JB -M-E>/;5#HM$=:(06VC;XG@[S6G[Z2>4=@$I^F^9,VO[H!BTY<,M(H@H.YAK+- -MB58*B$=SUHKX8RYQ#44%A&TE,9$"799ID4?.*%D("?PN_^`E)2JE5,^R)_2? -MSG$-,=C3H(FF?TEG9+$[@.>!$>1O&Q*AB?)0 -M?GSU9DK8CCJ^]J5S0#4=CN2R9R)\C^0D%5X#6T:J'FMY"FX,OW%U#N2\J9MA -M)!..1$DG32(CA32G+/LH\]-Z8,/2P8"6F[.RD$Q7W7[@L7"1[_DI2A*L1V4& -MD:;$R19M`NEF8L=QT"`INQ(M>0F/[K5J\@,:]C-5TE(V7EMLTIU5S4*2A$/3 -M+*PHA&7K*!UV[(_`$>ZTM(U^FD!M'K>G-<@&]PLU**G.LL1#!W9]-'S[5TG? -M*RUS^WN2:QA+^;JB+2>6W9RLOB&D;O%-UR+E<[Y6E%1@=9 -M$TI8RG`.BT")CQWYN2G7B=,"BJHV6E;?55U)I>S,#!M>[YLL13]*9ETXY+DK -MQBU9?,8T+\28L+$UH6:B/E -M68I=L]-GQL7I"SS]?-(1:-&.`#OW57V^0.-?=/U3Q[&Q-#.N[*&C>V/H:!>& -M2XBE2=.Y]!V!1#&)5JIK2TU6Y5V_0"3MQ,)3HE\]OHR@$VFI_%P2U9W_2E=M -MSS"QQ4V:/A'S%'NOG;:B0'=A:QT;3GP0C_#G`YYR_U.]<**%J/!1-734/W6) -M$E;P/MB6Y$VL>(VUY24WAWR>6$MM\1&%$Z2#Y8MWF1))=_0?`3(Y\P'N,EFB -MTH^/?(*:+7X'(W:2UUE#BS%_FJW0GL#?[YIK;^-3UUWF+F#\,NUPE3J^H>5>(1U`2/;?-FI4 -M"?4DJQ=U9<^G%*,HZK#<@<2@EVK8N>^+2ZL!G&@IC?QSR=B*_5>/VVY\SKU& -M>H_-<3?/=*+DY"F#34BKS?[)[G7SAF=3Q&&$:A35S\9EI<7R!K6..5,E\+.W/K1IO38$5RD' -M4,:!;[GO?8.>K']"TL'5W^J\K?4`*"HV^G&5?7:,H.PJ+MV?["#_GC4KW<6U -M7,A1F\,%Y!"6(1FB*=ZZRF' -MQ[%%JSX45CI>Y!,K.U;7GSAL-]Z8F>#5P/IF_\FO,'*4"_XT"`:Z1A$!9)W" -MY:;0"IA$D%VBPR468')7T5V5G:YFQ-5OY,:@!B,`.`YXGG.*+Z[YP))Z`4N) -M@PJ!DC'KM!A2D42,'3Q*F4,;9)XVF!IC,)^>W;(H7\F\QG"7G7V6UIUS&%EZ -M"/=0UHE.&$AE!S,01FY33:RFQXQH8/\B5D^',OLKZYDAUB-5BYY@;`:>EQ!$ -MG<4QN+"C!(S4T7S("FTQ&U6;_>V4HDVY7&.$PZ%ZQ"O7.-TJ5*>%R_&4F;B* -MB5\TDXO0F\ET?^PW-_1ZBY5"X+6."$Y(9?F!=I.;P&T#G6M(F -M;OA1%OODQU?C`AK3^IXECL)_J7Z;H4B%,)O4\_C3_WF\=R8$N`_+*8SZZ;=J -M@3DU>'$9O?TD7C;X%27T5MYPI$8KO0T[.!(OBJ81`',\($^HQE^I`%866$U4O3OHC7(BOH$<$6E%IM=S;4=[SZ&R64;RUSF-2R7$'Y& -MNS>3N#`OL)R%+X?W0WG:,U4UKC6'XH3?0"]9F)SD8-I"6O73W;,/>;YQ+[K@ -M1FWA5=WF2F?L><@A>^.2?/$A4%9O`]RM8-1QCL< -M-U:Y?4Y&2UYIS_&HX!J&WGG6B+G(0B_S+!XA?4,M!5D0^`!2ZT.;!$+8](]VV".[5CS'F7!!!17H?MIT$;A#^V_U"8JE*P^K -MT*-5)'!'C`Z'$A;.D8EUG`QA;E1UC3Z+R)\1HKJ`[0?F_$H3-1"PJHL`D[IM -M]WW$??6T,NUJ/E3ZB*Z>MUKZT9S;QUF_(VH:6M1Q8CPL.K5FB>/%G%L"MHOK -M/>SD2R7A9L[:@U7M<6U/L1U5=U$^E;M+ -ML+X&7`S03W0B2'6.2R*379Z8IPPG+IX8)#[3M\TANE%JAZUG*1+5I2?I#1M+ -MQQ<3B]4_#YYS5;_UCY=?>,,ZW>B]]]U16G32?1$3X(KU.]LJG`=T/\T-A.Y''O%M+P\9F63Q\D2 -M63#;&8H[P%LE%#HB5A92%VD1L6:&T-!9'GTKOHCG-3E]<(5L8@RZ@7Y>#-0A -MIL-^.(]-:UD<58K2:DBL>EG8EA;C)K2(`RZ0H_HA/Y8*``>;0'RLZJ3L!I$" -M4,7H&R'D18*88+?^4X8.UD!/PLCAG!>ZPJF!3=)[T$\)DVEIP(#0Y6UEDY2N -MY+F5[_H*R=O>A!E*\-KI&B"Z@D3RO8?&'.3ZKQL?0&.3&BP)Q23]-*KA(AF# -MV^ONU:DYFC-.L^SU?'HG=>%+VM?$B0RS@9>I3F'/E&H+,VV@]^N&C^%@-JV8Y4 -MTBM:/9-?7HJUC5Y)A(RVIVZJ`5;]=)HQ`N#F!_L]")1AY?[*7."@G'Y(PH_. -MX:RB!@/EV0X2+"`1#F]9>[%R6X^D[*J_^&WHAFO*.^Z7B\@PSD-GM(2R_/..=NZE.S7O6EU\+WGYSIE -M/>22_PN@3!][;2 -M,7FHH^%J86#4YM6C;M[T/%#\>X:.R#5+0KAQ;"_D[`@YDZ"?IAC5F_R-E9(; -MXOX$^^LV_JD]R]+/SEO-L^K2-*S=HF!L+T)\U^"= -M:KP@8.&8L[N[TGO!]J$<'#.\/"[_9Q+=7TJ.<,__]MD?-$8*JO'^Z2^]O@84 -M;N.^L-[=9$5SC[G+=V>N'L9%X`P_)G".7[KZ2,9]+U_5 -M,J6>@%WOID4/!95>0$W;>M<HYF[ -M8'+H"9@64'H;O3Q?M6;0L*K9;;HZ(OXE7YA["9 -M^BWV/-CK\/#WR&G)6][P5:,;FP8HO5;I:)P50V)!"%WD1=J6?T8(3CI5`+D` -M1B>%AZ88_[/NORX2C#@QA9'71G'>5\/R@*#B/S2G4\^";E:S/XA%N,78VG!`P#%`PWO1.Z7KMGQ98C"KE#%G?*T.O%5:F\O -MY\H(TRY12BR#[ZG8/A+@K&>%IGFS&2((*9NW2Z5\0QQ[Q17'+TNUQFD9O.WN -M"\3V5-ZRQ=9$.D]/Q:WDROGJU=3&/D2/E6+].9%*OUV>/418RF_+-^`J__*: -M$("CV'C8W3) -M.B-JG#^SP>ZETD\E"&=2TJS/]HWG8%WRT;3?;DV%$A0^;O@GPD.%FIO5S2]F -M\=5;R59*_9=G+X)A4D!DP5!;CL:=F8!]4\DU>/6ZX3IGH-0=U#L!W%BRW`T -MM6.[D:72;DI??VF@5WKV[-T;N%GY)^$AD6C5(J'8'N -M@OMWG;YX`6^*HFP6.DF%[7>M/`#6[.KVTA5K02K3CMG=#&U#I\/RLLCSS=PRZNTJT(W$7H8OQRNB*#O= -M*BP!BYMQ+%'.-V*KM"W3\*JX0!!@A[W^M/<46.UU]A7%/I(LPU2P2`8>,C#8 -M'X-+E(@?YA(%TQEORW#6)Y+@VZ:ZE4/UT0)4R>OH>HS#][OE?.\*>18/@`_&6IR&0= -M&2E`M5(M,[GPJ,NXBN.;%#;?1L!$%29NE4?^F9#I?2)7.U1SY8:!C,,E*K?] -MQO=JVK+)KL9C>'HCBD"G -M9VRH5I,XCWRU`9N^][SMV+\?E( -M`CEA1#W,/#F2+9?"STNIJ+?<92#C\-"264'C%F[B9=C;8M6:^633V9?>E3(] -M*3\FI[:8R4KN#("OX,".U:8X#?G^%"M$7K8E[M*N'!CYD".2^=M7YCN2+3X% -MK8/RP"T7'9P>G&->]+_X69Q;*!F)S40.H?>!IZI7VU -MN6B=4.N[Z_X.`)X+P$MRJ8I,OHMAPG]V:F;O(NV*WQ3O)?H]9\,7D2OUB$*, -M-)R?4G2>2NLTXL[SU<4\"?%=0=@)#4D1M>H*$7>IB@&TW>Y_!?=Y6&ENNG1( -M)#7EJ,GF;=FHX^LU475!U\N80-DU%04/-P`5W9$_:>_EZ.=NP=[:*7`MY:%U -M>0&;G21S3AK,`[/[0R9M+'D`OYM9XVB!YCL@PB$32Z+`IO08,RH+J6-=&8`6 -MTZ9&`/_$3UCZ\%XZ^S1`K.?],S7,2@Y8[\2^;KH5P[X6A\>+-0"BA.C9 -MKZQW&0I`Z[6;]T9J587T-'\>UO`W14<5P=JX(2TU8FBF^"),J[!G"!0]I>@CR=G].ZEP)W:(B3:-5 -M2%-@AMZT`]7O#^\QMER8(+;V$'&E3$IAYTLSY]S;&7OJVX]5D@VI]16)3@_@P("F@!; -M/26UF_SW\6@#-'_C!C0:Y2LH]>^@.\7?X\K\N%X)V+3PM]#Y?SPJPJ@FH40J -M`[E&$2RMY!-G7RK\+&5`R*\F0RYE:O^R8SA;NCRITUG""OC*3-W?\7&4E!6YX$-3;^SOGO6"H2;&JV3') -M2]+4H!?`&J"/,!Q!J/1LG2\2%RMNU$:5[#GH0:VG)G'Y.1B9`([\3'G^`% -M)O8,(<#OQP9TI'M*W77@U0(PB<>^:((DBC.>>$XD+28:Z8R<;PE@3>:[9W7I -M/O-?7&PSKA>9Q5(#DB:%YVK`.[<'9JG5GM2&R->#,3;+CZC -MD$SDEKHOOFY$C(]-,OPLM5#GUF62S20@)DL1<1S'IN2)T9&R7&\_4,H4``*, -M2S/X@0%:"!6QNDB8>V9NHZKJVNCGY^6Q5+\R-"$Z-SK8$M$X?$?!AF_#,2[* -M43UX=2YP:@_>0!X^0`:=8I6,`0<<8BO<#W%W8K4!6C^H2OVP9EQ10WU$P3_Z -M&T)J[)_58'XYN+5#=EBD]S48M0Z+4!*S?K6'5V8BX?:X`%;-Z.C=R]#!W5HV -MK#Y9[>%@2=>K%TPTP-?/*CH"23'7*)7&?.J8U.;^-KKS+_CW5=)MYWR5R*,V -M7;FN__-00'P(5G)UN\G_@`*3<6%MTAU*AE0>&+W#3[9V\[5\4LU@*DK=&=<` -MOS`L]>&:I]$`@7YI02I_-OAK`IV>6](F1D5/`4S< -M6H;+?$,'&B-#DXIP?'=`M7[()[IZ4:?_S\-'OH^9/3;@^X;LD&OJ;1`/>(J) -M#L)*YX#3)-J&12$V.&.W+/`5;_%HZ"(_A]=L_NLMJ\1;80H8<-$.[$H[4P70 -MSRDM!"[RA?R*X-55!$IF*+"@PIG&MR/,AZ9:O?T_LA^J>T"18*=:3[I%T2=2 -M.KI!XVK)N7S4^1LHG']E2UNWA0_Z\;B8,U0AQ2,W>F8%PP"B>P,KK<>@>=B+ -M61N8O=1L.2I,57QD6TP:^@%PIAAK.@"N8DAH>05$R:KHXT;XE^6OF,TD0*9F -M_]K_I9F\[E.?'?U8!)FXO/\O:(#*,??\>T;I.*#_@)UB8S$6;MQPQ`J -M")$7Z-"DKDLQ2A:,-1/J_*?.3:2]P*#K!*(P[F`[2VRA_3QCRXT71-J>N@G\ -MBRN;EUWIGPY>X+%&\(NK==Y$`$P0C=`$ -M`BK1&2H6D[R^EG%1EZI+U06F5MV4N;G#)`1+X!HE-5H3IC@_MGM\7"9NTU1( -M]!C?:",=TDNG_R4'EGB.N^H%4H52?$=V'PM9#K`H?OH-M-JI1$RA^)O%X5Q+ -MB7;OMV55F$P3H_!?&&O[DGU.464.)TNN;8U;`J"'RA$`>PXD&'!YN@3\HZY: -MB7(C87<1RK<8/V0Q75U4`9G!CV9RD?O,,5<\S<8<*WM?P@;P'MY)VB0Y-;/Y -MJ#ZCOX$("`Q.+&X/DNFH56@FM!Q=T*!NZ%S?Y>E)RP3%WU^U"GALO&7P;*:O -MX!3R-$^[TME]_(3/3=Q]R'KE@*;6%'2-DN;\55WA!'0>AV^$4`]56">1E&E@ -M7VK4JJF3R9:DGS[+27)-9IUGM5TR,/B3MB?-1/_DTGLHXV3@78`RW!:$UPI$ -M`#YQ_W).@Q!80S*U)3RWK5B,9Y?FH;P9I$3'*)3ER2-,AXWQAJ_TINY(QV0( -M,`GJ3S-1]=#,ZY?5TOO+^<\2K9GV%9" -MSK6JA&CQD?W.I?:$-9X71*D1U66%$^3];8*@WAA9DRGK7KB4^8"5TUSI7G@: -M'A#T#(_JH%#X.6"(MK9/H44D/I%/IY*"A=BHBTTGD"H>9:/;X5)*[9.LOY&?6V%Q9PZ2W#9A4$-HPR4/<=U1S0'X,&2@QU_1K(@P#!>:7+.9KMKP`6B_IO?^^<843Q&Z=WTZLXJ59OI9 -M8,'+W:KR-)QB>J0%`K?!BBV([.[>^C?LKIOZ`4%_@QN9XWWHBG/R"3@W`TWL -M50>+0R'YA>E`@20N%EDJ25B*,-G!`G4K?;:<#2&+UBPOV"%Q@H2U=0!OD@'F -MY)M.A*!>\JOV$=-X&A+I>P6$?-Y-[BBC]4].7U1NOME)7`Z(:T_7XGN]FW9> -MJ.`-@WGS107\[1\A/O88`MJ%]#>BW(S,EU7$Z@0A`>0NG0?_=<2&\=UL=47\1M@"T6U!:! -MG^"YV7Q&-V;#Y^C)J>BRP0">:E[3WIMG'Z>@FM(Z5XM9EZJV;J^WCCO:4]ME -M#EK6KOS#TTCOCQ$I-P,-OD]W$]W)'`CI\;2O]M(AHDGB6X8B:P==0*U(5/ELR[GB*8C2=1%/ -M*,MYGV)$)(.X^4!YM;Z:?9AZ4QO?0`4)ZI>KIW/&F1/Y8]K:0R_0X$M?0E_R -M44)JUT^',>R>X$@ZW:G@YW-(MUNY`PZ[CULS!#H)SRW\02($2_D(;OEE;M?) -MCDCX=A?W13_JJBF&P^GQ#0%H^40-1@H(@?UH5CNUT57D%OV)EYCW71X2<,O; -M-.B'KJP7Y5)_N?/_BH=3Z\0Z<&UFW7GZ96!H9'HK-WOBS:+4T_9NE:P-H9& -MJC`#GN<9_SPDTTT7,B+Y]2*1B7)[*Q&IOBUR465!@<-#VO)A_O;W3Y*M#F]# -MCMX9CW%'HZU$WNSSZ8M+)UX0'VBNL;!8?*3()I4KLJL^GQTGBG`0`\R>1![< -M*`7_32)%(FMV#>.'6U8N)C[EY:SB:'/*X9N)CY')IDP2?]]SP'[5MJZN2^&V -M=*`397`2&:/6/JB:W%KF=Z>DP,17UM[:6Q!F'OM`?`!Z96^R=_LW2R#(4N(B=72D>UVAY0?^5DHV$7#@9T2<`>.IKY, -MT_-`3=_AY5DMQ#5(*\I#LYASLEC"'M/""ZL,($HLW!BG>R2:>2]KBO2'JO_] -ME&_E(Y!T#''([;K#V_Y0_:C%G*:,'=`^CK#CR&03K(QRHXM:":@2KMR<2.!3 -MQ/;OOR7Q'K4C!A_)%YSAH%'S@%]Z(+`ML$_+\/4.-#Z3W4/,52E]<"UEWD*Z -M+KPY;^L3J.Y^"-GUZ?*V+_%A*55RW!,'+U6U@9C7>^9Y?UQ/D+2E0;<3-%%W -M=UBQE(,HIO_LC-W&497+*FK"*#F&V6CC*.:4]N,-,,/'>*)'[7')^1^WZ$I/ -M2IO>>%!B6,?)R01,60]&4&WO]D-,81:`+%[C,:CRAGO&*Q]F:[12+69"I%\` -MW)MFR*<&%TP-PC3R+9Y98E,W?W\C_89%V`TI'V%T0^RAJ$G#DXMZLI]^*;GB -M&Z89-66!GAZM -M?"7&$S[3!5+`JCN;4L.X>O>V.7]:!H"'V%:OA"8RVO#*)N4L"=:5J`33CF(* -M0O[TJI-64L?A=<:`-;9A;GSSNA3'(HN^B>V'%SQ21MR#*#TU=I]/,(6I[CUH -MGC)W[2/[@(A@;"_P'BSIVQH8G]9HO?Q9QEV8^9NMA;]&,##0R,NY*H-M)']E -MN%#WC&_-%S/O/%.JAIIB8+;/PBPB<5R,JJ?6U,1TN]J5$FI^XSG4^S%KH#F& -M_4Y0%<:%7QO0Z(HJPP(5I>X6L]NGR'2:"QD#.+;9B57T\#4K4%D[O(\0_&JH -M,K,P]^*"93LQ\ -MD7R>^8B%IFR9!8]%^::A!D] -MB:!1#46ZY(&C&/U#Y-4AA]$X9/?EA_>QY%V/FV=S0!:UA_;JP]8/N"\>@I$B -M3T*6-HLNCWR7_7,_1?#17TBEK8B982EF)*#\9MTPZ9'3Z#L>Z$^T,:;!E)DU -M3GF<1X80/NBL-](G.6B#[RZG^U%'YD99/PO\/>DBIT0E(K?]0/HKS$ -MV_Q\_%21K@D&E0J9L;8YAKBZK3@]>@/)(WX,@-$)8FNE@%RL=PODGD]X=,#Y -M%M=;C.T(_#(`"'9%0Y>5UK4L?BQ(-'C+$K9X7&33^@)5Q--[U9N7Y$^;ID', -M=6"?A&V-&?QYT%#I53NR4N8[6^84&P&CZG(-.'H@6R;?>1,J`F&QI<.>XL\& -MJ$6MNX;-";!6CD1N36>>29=6WHP!$XQU[MT8T]C(Y$J>Z@?#O)]P#<]YM?KZ -M`[FY"RG7QE%^54HSXSK0S:H`\/%H!<0][?M:\LF$,VLJ;Y.TAY8!B@TVA&C< -MJV^W+WP>SK&X1)F\GRWIX<'H@O*31RZ"ZN?ZER%[:DZ(16002-_$"Q*?OLJ` -M`D>OT,X9U&T!2.C:"AJ8QE.K&2JWH!"._M&X=U`L_)RIT0*_M!?/W;"%%84M -M7\FNMJ-_K"4%@V-SVI:,)"2^%QF842SBXT9?^FR$7V^+Q:&.TSL&XB3$\N"K<3\XEO75%;F/;D%E?3M'?\![MCTLSDTSCESS5LNYVF! -M7L?4:[P%HOOZ'U:Z!Y0;V>RS:[4=X7(3;`:-S9A)_O?WWX>U!EYQ2M@//,8; -MG]Q[N1B?J6<$@Z*O"GJ'\G!Q]1@6[)*LO:LWF30R$(&==$:C/^HV%SC77A`E -M;]1L1@U]KX27^T4*"(WFZ3>&2/3DN9L(?+_I&[\YU+"JW:0%1*;78"+FF9I! -MQH]/TQ=B0*[R%>(J$^/+0"Q0.P_'[.'FO;JBS\/(%.ZL"3JA`8J_QC_Y#JY, -M:AV&20VJHO"R6X'BP-'9@'`C\;I8.K!&\/HSF1)2E9A6U'&CEP"$+2_Q]3KU -M13]5&K?$`V@_"8&X&)MJI(:,N6R(J;D(4/V`VYP!1.V!BCR/\+5,Z^L<37R. -M:4>*.HZ"SS+R;$_N4Q='&LZ1K%>P-JX#VU9XQ/B0DEMDF^&=K4#3H=T5.-\, -M+I5=6!^I&[N:=S+06G'T#NBLZ!X0\3:Z6G\8V8'DR/JMBHA*Y=V;F]M3@L?& -M&(7,9UJK>B'NGA7X3" -MS6PY8B'&?OHW63SVSH)O2D6"1>;FH&AUD<01#&1XZQQJ^<4.L5UHTT`#)@\: -M/^88QRLS=&0XR[]0]>TV;S;1LR]7_L,[N=C]T7\E<8`JJZ2Q@CP!B0]<'P]Y -M!#))S=`!U3XC)!S&<@S'XQ\\@%?:YS+OS`/^!Y^64S<G]59H\%G`56M+$86?)FK,;WR>-&+I&PN3F[\[DW=^2P5WQ+.U,`_5%926`% -MS"2,PN"YC-P<#^`P+Z#630QSU_DP+ZR$X^Q0F$*&;D,6B.EV4WAROEZ-(7F< -M9??(H^-[DLS4Y*_<1L?,I#"]&;OB.#J9J1C`=4"!Q/B%%KX.SRBS3-T8RXL) -MJFZZ)[?IUTUXC8[6B^=?_['Z&(8!2SDN3WD;`PVF\87)`[DRG5U8\1V[;Z$C -M[C315L]E^A>343Z6/=Y!,Z3R7?\CA.E2#+\Y( -M8O'JVJ�)XX%$&63-BFZ#3R4`N.#-F)8/1J;=I7CV8T&MT<(5:U%UD71<7? -MI6LYC.LJTT*;^K&("39@9[1.5_,Q&ID6S!7I*F(6$U6*U47N@Y\G6&MC[2KV -MEO;Q%+,YJ@YU0'B:GPYDFK`1F`3AIPC^E/573,@2#N.H^U9.!G#(R<&V5 -M13,B6VXY_:XAWO#A\L%""JPI*NM-N1MIR`F(/C=_ATZ=!=/]ND1K.H -M799IRRI:3C:A]B1/UD:[)UC/FB;J@K2:B)Q@6=3?=^NR]_R3'?'+3I[I.1_O -M\"^:,GDZM*2RXS*Z`\,YKZRKW4'\-84EPRHWFB*&/W<5=IK\7:C<-F&4J&PX -M.K9D<58#WQ;I8;OKW-+MF$L#1%+]0@0TCNCC`H^,)DFDT5[$?5-R%^3*D6V: -M7/40LNQ9YXD](*X+6_.VB92)NUI'Q0O29"ZQ:OV?7@*A>#W9KB>@TCBA:*PM1-LTOJ3OMVSG4"' -M)&PGU7UA`@KD'1C>0U76?G!4U9!C(4[()?!Q("7)G-U:N*C]DN332;0@SPBB -M4[-W.V^0\)YL1V"JBE&BM(4$63(D@H0UK4D@QLV[Y:<]#N?:K`D7KQXGH*#R -MJF;RKH]?A7:N$S9[3,+TF&S&$-I1O(-6JM4T>ZI4 -M6EQ4$B'X7D)EN6D*MF4]6K<=7"@4YX@-"21+K))0]E+Z1D[G";+@_$!$_ -MGH!GZ:1YT%A-J#Y>WT",#V,,0($NTW'Z3XC;;62=U"K)."PG!!P;GZPK^&HR -M4M/1^VW@$`K"9_T#%U'E/L!BZ80O93QLPF=_<&*I7A*+,75N`5\F>9(NGX*! -M)<(VHXDNRJQEUL_Z+$HIV*FSW0E\1H;.>2BP@QAE57TA>F*&O0X9"T3+)84Q/ -M&@GFH&8U'W';75+(1##*S[V5RV@J:BHD:@Q:X1<]@E8,*\A_^W+4&L#]U+=O -MVN`TNQ<8T./<63@Y4G?+_?WB^ -MW?0QJM]UHK=8;M:[CD4&-5+*9K>,M'BRCAI4\[M!W1TV6)#O3!]REGXUF5IB6+Z;#[LP)\M'7THEU!"N/GF39A>C -M92+!9QY%&OK8+&MB]+1]5Q?^APR?4]L6FEE69'O69\'>PX_&1N*8,F#('*E< -M+@S:#4=-:8-9YZ!NM[,&I&`7.F90`ZB8CY"\T -MFC?_9BZ\('.;!,_=Z'-KYSQ7@NR+<[,&YOQL0@D"UN=` -M.&WH!3`2[N^42F(=(/]$Z#U(.D26<]=U1WRA-%#KO",S`42C+'=51*DL:3-U -M09>WLV#'0CY%G-#^.$(V5A;_O>^2^3'>*N#-+@_PBSK!X&`LD)IZ+NX\R&`_ -M=N'(<480K=]T"1.-T"R?K"]*,+HS?II-&RN[!57;^6(VP:.%26QFB^A"/V2B -MK706CBRRVG`G!/396UP_>_C5SH2B-CD'(IVE1+:I8)B,=IWM!?];;AU4:JS/ -MP-B^%U70KE4;INT\4Z[[[)'ELCF0\@16RAM)/O1B)8'43%^Z@6QB+(G'OI6^ -MR7ZWM_,B;#^EXNHH?,GP86/]$#)^BTFZS2B'-%-?I^U=G".#E/H@V>(\6[*B -M2SF,XN@',]L(BG%;$=5>3G.F@?C<\^S$/4"0G":W8P]\QFGNN@MA^HCD2"TL7KFVVZR#);-9KRZLL+&+.7V_"Y/",ZOM33[$`+67M'\@PW!A4<:XX^;$ADCCR?^CG]6(UCKFBL+XQ)9G@5ZWM[XV/7 -MO9@LC2C+I]NJRK<)05!Y2R@Y*V.T&B?,7RK;QMY>?T-D(K&^2([&PN?3&F\"WG$ZXBT)W=W)2#(&D -MA/YYH/*2HC_17LX4:T$A-O_.\<$UOI$B!H+_O7(PC=`BA*1^HS7H@'LW)_?JSZR]KI^BR"&@JV -M_H:!6&R=`_^;X=N^19D7$(P[$1292=N4(2]..+?RYKG@&7.#`"_7]G!%_9!> -M2.0:&&P?5F21\R&6YFH[NL:_YN2EKP\X"<,$S+<-]D/3RY)%(0S][:'W(EHO -M5#<\!.8'#H0[C,M=\#:(>C_/DA(Y[);-?,Z]&YQT[Q7*Z1;#`,=8AL7ZS<<$ -M#H4=QJ[3J;/R!-#4].$VK\SY!Y++E\5,:[>D"3(\6Q(_E#6^.?Z=/OGWWV#] -M5F_NKFOB"1Q7NGH\VH?B;\PZH87L67R.';E'_2N$S]/56Z_!4J0U-R=JA?(XRL+SN@-2-]FEI!F -M?H]37@7B5BE'7JFN\0N7'!#%8MJU[R$-BL/;P"W*9.NDG0^'S+&HU\87RL'> -MRD15@"G)2[!C>?V#4Q(F38/<_M0,T$CY2>C;HC=JRL=L4K[]1#_>*;LG?.-" -MMYEHCY+CPE0>:XW2TY]=1@'T4AI'"_HC42SM#>K)Y)?*UZ/L>&BZD$C,RFW8 -MV-"6@>8-]S\SGQ3)"=%F@1"'`-0A(@O1QSV_U -MLLE\^B#`^`NEX%.>-DC#%^"6'2/_SS^<-)=)S]4HK3MWI`8"IZN?H$*6X>BZ -M`(9*$O)#S*,W7PQ3,J&#%+`34.1A:A,H^5],:EJ`=N#1A)=GXJ=Q5IL]YNM% -M<2&L=YI:1GR]:"XQU?&Y1/)>?2,^8++:93A/7H@>1A5^S6/N_%D;#0YD5W&\ -M%ZFO0R0]FV@8K@+$*`WR5V@%`4:`*Q=5.<\.WQZ-32@-&3DZC1^GI?8YXP\ -MHT9,::O*?4K^BOGWP$484IK-S)>Q?73$6X4_M4H%RGJ$3:+QY63_1YBY`5GW -MGOZ[1 -ME5JAG+RZ!]G(TJ8&P47^\2.?(+C!0+A3M0$&PV3'1K6W.RF62OBA;L"TT);2 -M+\VOV@&CL^A?595J]L@Q=YBYW/ZH<#`/'O)GVM7=JQ!U&(\`\\AUOC&]'30& -M+-VR]M*W#5M\H+4R/!&M)B/V&D31N;MH91F4AKLJ7W&,_@U: -MZ,>YA@:G/I,I_%>!*"32\LXD/U!\T>.#XGI2H8%IP3F>_]INU?#YWJ0C>\DO#3;N>*#[A'G$C*9<[8IER@ -MJFA-Q6GZ]"NXW6^QM)]T4?1S_`'#=NPN#CJ?XD!0/;2O3(P!)E\6*9;S0!G# -ML-;'N0!!=O7&M1"?`<6'"":VG*3"$XPDZYM8DD!N512)W85[#.!MKPH.K^.N -M#UZCU1NKES8\JKAJ8"(@;XJ!VB$09/?KOX@+H8A.#32,C0'+@2-\I:X;,S1% -M5+]FQAQ5DNFZ$,EBM>'=S$:?3JTE.`E+QK$S#WU48ZW4ZG1)Q,"AN0`%#G&` -M]^#)/$6A-]8NK>78CDD1;56/44]*IGUMRHL^E;XREL8]Q" -M!^&R@C"FW^@VS9'S6B<*00SC!C5T9YAFZB[9VACK")ZL[`Y91(DMZQ=,6;W_ -M$#Z9"ASU:?%MAQ(]Y"KT*W$\?"B+!63^J-:W+3U)P%(Z-TDM0X:1)!("G$^B -M+E\9NMF_E@\Q0Z&?K!(C"@U>V*N4@F@U^1<,9EKG\+`W5K6Z=6N4!BZ72N"' -M`<,0$"F@1=X#,9!*CE6/VL8;/,.='B9/W8[8_&MKG=IT`(#YP"J)PQ8/FO;+ -M\9!F(Q0P/8TY(]!0AZLERBD'V4][/ZSYE6(U_7F->8Z=I@DSL&56>DB8;YHQ -MG]^J+E-)))S@'+&LS.N31GM9-&OGD=VPAI9`V@P,^L'W(M*"U[,/K65#X_@P -M^DCWJLD,K-Z:7Z#@OAT349`$%,K-W"^YVCW*.\T%J(3E55':`P97T`;=Y9:P -M?,22RD$V`^]>_[\+;,Z8BZAP%S,$:UC&L*4X!XV0*FU\;*(*)PHBD$(D&GD> -MK%#+DV)E2%E4P)-V*9T"XLH>AG,.9SRSM&?7R$<58-\5C>!S11?H?7DK][/R -M%[N0W9@M[AI^GDJI7J28J1N#;B$7\\]O1X;$HF?QH*-!+W`:2-.BM2A]>M/Z -M/C[5`21/W1HY8Y+RZUX"'DB-*<,4YL]M0ST!"%=4<1Z""RF:"ZD/?`%G,6B- -M.=GJ.Q]]$3GVZ9J:>%*/(>P`(M6?+.>;,0SY%OD_P)I3KB-:]W)_01$,'2:"$MW*9FR*(TQMMB4MH?+T,>"E?V*+";8Y5"WKZE8^@I9?V^6(/KM -M_-8%2MM5>SG5'3C.L69>6ZN:6TGJ>6"MORQH;_@2?C,/8-:YT):922X'Q:1MBLJA, -M4\*F#X%]:$=C"YX5!_?'.A[R1>:^1MR"U+KCIEGP@>._JA(<%1:HL=OHZ6 -MHVBJ0QB@1)/+!(*5^U%2]?')%4LS+AF06QYY8TQBY8P1J30L2;G(&,A0\"*@ -M])V<5*K_>#9F^3=CX*P-BY=32N*.#M1L)>F@/B*-A'X$^+QZ[8";[C5<`;#U -MJM*UV2&!P=-';.AE/"YR8[9_J=>>#$;8$ -MS2"<7PB%[6,W_X*Z;]3N+H3GM:,,/B -MW:)32@0//IS*\5*KUD@<8+UED#RS#AWDX:EWU:;X&B0G)O05K%;7.H2JM!`H -M/YB,U,FTT'WI'S;@G;P/:S5D=3#BP*/?VS"*QHS$H(QL-'1:N&3N$0V,14R\ -MU1VS?XSPY&D\+79*_:!IG^8[NMZT,2Z72-O!99A(/H^H\+%DG&U1V,JO\0*H8W=YWQ;_2?%)&0IM]'Z'%Y5\LY;L -MH=Z>)5?K@L1Q"0L!C<733I#)NSRWKVP-!X+IV^-B*@SN^%4RJPTN3D+*'ZPC -MV7C%'+HF8)D_+Z#YJNHR;A)NRYC`W:[^^4@Z2Q]4NP.0=E2`N`)M*"%H[1%Q -ME-_8I0CKO#?['0V(_B:+D><%`*('*A"(F@VFD":'$30+^F#$!R'ZE"RZT&@< -MC\L^ADN,`+BQ9\1?>9(!O`K+36U2,]]`GDFO9Y9'.!9TO;#NJQ'9?E`=^#^[ -M'HR])H93N[[0Z])>C76&9UK<-F*3_IT^)_Y:K.364*@45>7+! -MB"J#4@NG9,*J%H?D`@'[U/2MW>C'683FSU1`3!V9I_.*PX0DUY'2\KSF!5=3 -MF`K]+C0096=O./3A/>@+9P'OM**M"+!XNZ3S3A[<.:D/H3)!64`47H_[@1,K -M^J9,T*\PM[O$7N-]!(M?^.Y)XP+3`H/4U!`P'\C`#$D&J`VT1!1GK^0S'-\G -MT4HG@/K%%@M1\VF>^G:^#H8+QU]2(-$`)D0$GKQ>HJ%N_F7.2!DL@.H@G:S' -M*=6,:&6'#K6&7)X,JAYHV*]]+4AFL!_@/#+/"2Q45!ULY:.B:EFJ6XY*[."6 -M)?W3O5%7#:D[GT)Y!^NGAJ'AIUWX12$+NK&358K3 -MOD(+?RZ\-D>LTQXCV\)0FCX#"BE:(Z]BM/[@&C4W[\`OUN_9"N'?VE<.9)>B -MQR)#Q;BPY6Q9._;R;^&S(B`!OIHH5$#`2A]@$]!*LX1JI)1MIE"12VCI\G>2 -M7P+R$H85V\35C,*8;I@1?HQE/+&PAFA[0-A**83?WZ):,(C65POTW;K-8-9J -M2H9.$7-M1?S^SE/^C?U0%RATSMESZ<,.NHC>Z -M#'HU440X@.ET$+T\I56RPX]\IZ#X.X:?LL.9X^\(*U\;T.J\D^U]BT,8E2SN -MXL"!;![W&*2?I';;I6QK@^S0\G]>8V@L4M]PEE=.N1K%M^3CMA#2?6D7GWZS -M;XVL;$/YV6O)G>;*A9>IP%G<>-AD^A9L1MR^\)NLV'`J#Y730K!D)Q.Y/PR? -MIKMQ5@-$HV*U,@!6T%,?!">/4O%)?4*(&?%GH$<2S-OAU+S)H1QB>+",)_); -M`49/!@O&<`6X3@0_00HSKCGJ0?>*56<*@&2[%?C/9,?\N2P=RZ7"K6O$:DJA -M!KPGK,%TLS218IW(YBBU)7-%U9INY/>#,C- -M7!4MR,LZ!D:`9L>EDM_URX]?5+S0^RW*6@*/%J*&WV:_R%!K^\_\'E%(J*2^ -M5+^FN`"T5,T_^_2JW*W5S>W7-QCT>%.YRB\+(^Z)/<-YHA%=BJVI -M(\QX]9R+8TLXDX+`A`\8P`D`_+OV!L'VZ9Q?+M*+^-\Z"2RY8J.1B6&=(I.O -M"HF<;9JO^A-@Q>(L]K:Q:7[P%N,U_QQDZ\8R-6*IWY(<.:+D]N^^+>>8^$)@ -MT,K@_O^>$N+P`$HN_7FY=B"0+H6X?SAE9Q^ -MT%<,?2$P[3EMXU8F;&H:`0H_^%R\,^XFC<";4#%D=%EK?IN?XYHR:49A/FU9 -M&IC0Y-;.&T[@#I5<;BXI]-P,L<1K=08RT#U=-,$HZ?9+N68C7*JL(KN^1_G% -M)#*-B""W#BY,=8Z$#1AA`//<[T5[:1N+$!U4=YQL]TH9V[05R^:JOA^B!=0J?PQR%GX6O.39^PRGP1AK<&#;C'DZ -M/`$[,74XBRF%O4;X,P>J8B`ZH->^ZWT:&/ -MY&CM4UQ(,9\5:H#XL3TC@Q%]#MH%F)V>.!KO'DN09-UO95FQ0ZOT?/Z$CQ,Z -M7S59XVV-4J8.VP7="N0:&\`CH5;Z%[]GA7VR>XC9K*1ARYD< -M%J.YK6LB:P1$04S"6)B+3>"G(N<:Y$.9(O_;>,G0'?LI&$:!-QD'/C1_S0,H -MZS41"0?TBP2T0Y1$_Z$^KNPT<,Q,"#F'5M)':!C^%\'*0]HOQ-]HAWXW9K?" -MPUA9UXG(M";5$>^V"#V+0QY"P>-BG6>O8(9:9!%`@6OL,L]V4R<(PB-`XJ75 -M;],6]HE$%X$J$764!FN]T<8PD?H<6FPC\_-Z``Q[AQ0/^F@?/R\U\A,0IO*? -M<_\\AZN0D),CJBK\RQ]%1X! -MZ8")6%#1C:$*8[CHMO5B?_2SM%W9@0;-[Z<+PN@-3;75;.>2@XP<97',;&_^N^$9$/D:"BI$N^GUO3?Q=V(M6H$ -M:_7T,2\1-R@6')O*QNA$<)-,6F*D9`XVZJ`^DP3@.*"L8MGS.YO[3EC(*D3< -MB#H6JOIA4.^DU^3Z##T&=WTL.7?`;8G,7=!":SAM44'8ZQQ?WC8>9+\X1J#W -M;QM3Y(!/J47C-2'A8N_J856.DOX^H86&&'WVNT6/\JJMQDWDO4 -MO95BB];Q9)Q!X>4'&.EF!7)G!^%@G/-_Y -M_\IQ\BU6R,#3&)(P4<:J"Z6< -MRZ5RD`HF[>%)'T`"""4P(>W@FL"HBQP`[/.S5L/6GYA/!EQUG=Q2NACB7;1^ -M%L"#TQ'AU0I`MD=^G"@:=*%RBFS1_2N5=4;2-=EQ0YK -M!IDX[[^)53L/5)#BT4OQ,<:[M*WNBS"\K#9,Y3%U]^9#'B-0*:"#)CA4D7$Q -MMO'>1?5D]D5MR;.IR*4VH9\O_=BLIZ^RURI\KSN_[^8RP=-`UAZ4:J/0K!8* -M>U(Z\D*!OK^6,T>"`Q81>Y\O.O9+^"D&-?>$2B]E.,![C87&YU06,2O5?-Z$ -M"2G=C9"[#O:-[W.RM`1L`YJ"1'_75U-FUWPS\EYOV'%K);8T2A\\UK_B&;J" -MUN%Y]B\VA8Y)0DS683AMWT+H?8/Z`E91(^5U4LO-"UGX4GQQTY<3=$X`JLEP -M6)$\&8K[/>^0 -MPQO-0'#]X/T?E;02KKG\)TN@/[1^:B65;,5KY/8XU[2+MJ`LQR/ -MG#D!/"\P:AQI==!;>G]O@ZI)HGYRF;\HI5*=QVP0E+%!OM=`N=CR;%F#!`N?5OH#+Z"+"6/QK;>-MTW -ML'%W65P'+BX8IH-7IW2Z.],+88ABUBZ\E29T/%-8+3@$HE(WB4:]^6^/ZTKVZ$(53^]*KDAMF">.(W/IRH1C+X9AT(&@.%3`J -MPAQWE_4WV%`"+S`X98$<9Y/,?*VB;-DJF.4#HP2"M3$TI"CM>FAR])6`?-GE -M`.X5R"UL\YW?WQCBQQ\%^SZI%:DY^Y8'($8H#E*+TN&T,"9-,PWE=XAH8`].VF;_O'40Y$<',Q`MU@IA@>LQ9(E\+\";:12D**@1Y;N@W*^/7PK: -MA@YAV(+PQJXD]I]/<00H7C($4JQ\%8SD=H`67$2=`?L9IO -M2FCI86'R0>HR)^!X8"K,J&0)J.&K68TR/_)*?]<1?UG:=C+V?MVIJNT=1P8% -M4Z;VFS#HQ;2RKA_:TT&^45DOS96M_MORDI[Y06C78=1^3BULT&,954`LJ&9& -M7A)U'[K\@A'5*C/"?ML(9M#^*M`G\0X"L`P/NA9QR?R3N5_\*.2V+C>3-,(8 -M2_N7/F::$\T-00V_\!1IP2P4!JYX;6`PA0L%ZMR_OFH.&Z64O+1LG5T]0QBZ -M@!1!3=_S<8BG%0R5WGQOB1LKO:Q.DNJS[H/96RZJ*#H%]H2B`,E4P65<_:X -M/B.;E(ED/"8Y)_;N$?G6@_?^_PW[>*_%847_H5B8,5TEMTO9K>>1L&?D00Z$ -MI`D]G!65:TD-X1EPGT7-3\#%^[J.6RIA41)-)O1/K0^V[\S6CNA>#3N,9*3I -M%'B0ZNO`M:O?6DUV6)Z\V/:F/;PFW0[=C!0K3"7,U.>2R,E]L;*;#N%Y`P]8KN7'L-9[;=8IE'0;%@C*@F;"@+E+"+<.MMJ#+>^=7WD*(?= -M9;*F+B'EE7_7"`8[T.'?Z:5>4^*4/>G;6LQXZK2VFR1PP][4H\%@(6-1[>@[ -MMND%RDU1*FC76ACK3#E5G\=L'84:X2VPBOFCO(AJP8)B1Y9P)*//VRR8O!:$ -M[C>N\8^..R/[I0+\JS0@]%X=&8H'-2@CDTVO6(A]<2^PWP-D6)_.?:$ZU>49 -MK>^,::@JZ@3A#0BTHU!1,HO%30C?78HJZ1*T9`<[\Z=UD?.Y\"FW$_=C!3DR -M_7^"-WHADPJLAUFY%?9E@=U"87,DQ)V$\Z/7BH@C0)X`DF_8'OW0">@'E-Z* -MMVC6``DO5OO]"B'W\-%;M7F`+=W&^(]Y\DC+C4H&PH0S3FA[78UP;3;)Q37TXHS2/R.KR`R>S#H:"2ZJ8+V;KE[*8]")(NG=^: -M0/S(M_PWS,.O9Q2\[XXD'/4<"*WFJ4F/EJ%`B@XG="&I.&IW[+YH1.L?4$&' -MMKQ_@@%'C'QSZP">SC0CK^#KNT8\\[T7#XIY`0D*T:KZF!OX$>$NQ;$LYL<( -M;UC#;QG#>PW$<^H[CNZA,UX+WJYB\%6SDS>MH'WEKUX>J66SR>'$NO`HQHC0 -M(X.TLKKC?IE\W3LHKY27"*O;_\%;MCM,!1,H#@^X="@U0I38N3G-* -M0A]V\^"45R8E?&!V[,)EP>9DK"9TG(-G0D38^1%N=I_GN#&=;M[+[+DW)9%D -M:MNJ[4-S#<=6JX0^YK86A%5I7KN8CSMQ9,2C8+@W! -MJ].8*R&R`7O;VTM/BS#Q3QD36E^X.**^;^[<)5J%:%CT[V<:)U%VQFE5%,2" -MA49^+?X6'$`%H]34^H4\/"7EZ<>9?P4/VH#6C__IBNPQ3XL//S-[CS_@R!"? -M$0)CD=282\U::342,+8=R@]`'L]?*4[*;/9J_04_:W)PKM*.[#9W:0;4_Q&\"V?^-@?BS^P -M$7H9H\Y%""GI@U&RF@V+C]AA:E(@D4VE;VP`O`:!"AT[2*I#G..`MN.TPIQ\ -M^O<;K:P;\5>PI7N2[D8T=,:G=6$AR[U"IGB`X=W75R@6 -M)_Q,.+:^_[6W%GH%5#S@2@XQN:D9-_K)[-VE9Q9#:HX>&/V7'R!?4(F31PK0 -M4'"$7NK(];*T\>^P0R/=5[T*GCA[#>,)=_G`7'OJ$;!_SV]#JZ=R^$A=(JN5\@`4,ZA?TLEST& -MYJ9/VNQ!OR!NH`L5W&KJLY&=VW/&DQGHV;G98FX4WLHL]'=83!0?$V+MTVVQ -M_@M(Y+&U1/96E+3HQ-`YW@H;7]9QM0%JG+VZUB*#9(6#%[!T$,OZ:T53',?3 -M`Z/R<&[-G;V)F#R;-GNX"&:I':;%"QMKQC=71>E -M!!S+@(QD+P,O45II>?%.;;RN''EY@$OMA_!J>:MH.^!;APS(6.A3('*]R!<26"U-:PQGB:GJXC]!$;E4@_P$RJ*4>OD358)6>AJ.Z3A&,+GV04E.K>:<$C5A:(1&'&7"#!U,6 -ME>1B$OG/W7KD+*>DI%?IQGJZFU;?BNM]-PC$EL[V)A92@)!%-8JAG+S%<54UI.L7NC4\/R?F3'7IMJ;UQ0920'/G7RNGWCYS'>D[!/ -M0XU\D[,]9.VRR*H8"&:5H)?`P5\"$SY/X67@K.%)7& -MF9>Q&NAQ"CU.N5+:\C)I.D>U0[09#@#?5:3)C=#1RZK9ZT0J%+VAV4HR^=WN -M&Y?=>?&X7\/2/+77RX1/6)DXC9CH9Y$W0>`B$3C1H%GY>XQ[U(*#.N^WB9&K -M)Z9CPRZ$$FI_L8F3]ZWFM%GGP>]3=H.F>WA+.X.$A07IK;)TP*,:EPV#\\$N -M[@.V]Q3A#N1B0*V'.6M:_>S)21.;;F%XN>"I2<1%+#._"D4"0(J79ML($J&0 -MG(T:GQ!01XOC9/.6H+,U.150N@[/0Y%47#;21'.Y)%L>7P93+ID+5>3NM"`I -M&E*1:VE!9]?*YE^?&Q6==#P;M>E=\],N_/D@%1 -MA>X$5C_BG.?3:VA!U3%O2=GJ>A'!A9.0?5];'RF\[N4#BI4M!'SA?=8='&^X -MD`M+\X/^2C.QI?)Y'E<.`6QU<9;,&\*""?O*0I:%#WI$6CU9:-LA(?N&4X,% -M-23H^SL,Q;9FQR[Z@6GL#XBZ*<0]%GST>@]?*?-MC,3[QESMY5MLUY;@Q*>I -M_T]9GX$'))$A%1ZZ5"PSFJ"4'9%:]*UHOP6C,N+_T-VY\8(G9?2"$$'X?N7W -M@R3GV9;CJ%(3?^JZB=Q9JO&>C]D*9:SYS=K>G%Q<5'YYE$?&Z366JCD+/6%_ -M-K9=]48U9L,2+ZHM75QY&UZ[_WG!$M/&/N$WD7)\2N,26Q+V2.I>\J4_ -MU?./B3AG1Z-41'K1"#9B\G5 -MX2/2#C6YY8AA=O\9Y=/ZNWF\'S&&?JIJ"HDJKW(WM"'E*2]_]LGS,Q97J?M- -MB<@IVPJ;?@?H7$3=/0(KE6BU=*0+' -M.V8D"HYH#;L9N0):(><0K8I*A\`@`N[7HJ2E]VIV(,D4C]O'N]^C-??*GXS6 -MTGZ`6OM#O;B;':_TR1Z2N.]"/$#;10,T8MU2#-MH3AI,C#I66&Y:$Y[K26,) -MK1"PQ82L^0=8`\*^G-RU?H7:?\R,-&)^(O=YW@/\,N^/S=NHX-$J'_KT]>% -M->-I4]"[>88B(H54%"$";=SYC,<5&=M]5R+E@X@5G/D)3-05K^*=4*@'$M_G -M][P$U"'--A.W[[(*YG -MOFM25.<"YJQRH)\6?3((IUCCLK;/[K6!],R5`E=HC?.#N)*U+5>"N/DZ8;1C -M^8)`$T!8ASN+'/,0KIBXO[]1O#FO(OW,J!DV_*$U"1!X0O&X\%AXF8AM#H:O -M0+OO#!'9'=QG(/P?2"D3[9S769`5=MZ4L"W[#JSR[)F\E((#$3'T:!(&>VSJ -M?SC?0^6VQ1<^2X>3DBKV.CZ=]\;Q`&UM,3PM]!;K>O2&V#G(71J_]#9.+GE` -MU5DF,:9^K%@,8D5C!LRWF5U=C>8_+/TK%6R!=UH9>1;!7N(^!N7O-$M_A807 -MTS1SZ-HZ%$Q+.$\LLU%"6X;'1QZ\ZU?G6>R;>;TKB0`Y<#\])7\MK1=8R?0( -MOE;\/*EY!\FEJ'Z>F^<8_0C71-5\@AL6ZBO$:6S#4CFL2\-]5[_QJ#]3%HPC -MP?EMXDK4X52AHJBIJ+.4''9L4TH#L*]+"J$+RR7<,GY4U@FZBW3,S'>O@V,Y -M<2.ZAW*5MG6E8*FGHBAAI9^W]F<$O88VZ+@+G+XH)2ETK=.`1%)+^*G[F9B& -M-H4*U?`.#3%I0`.[XFW!$/(EV"R&W>7]I36?'I]:^,-,BFZSJL;?$=%%E!BP -M+1+.[=)QG>;83HZ#XRBDM#G1_XE-)T%Q'2D+<;!.!6TF]S6^BD34L".\,9_R -M.4"R4R&)JB0)3C[EBD8(SPM#W-6.+F41R?Q=0`L5!H&_0(L6RPQ6KRD7/=ZX -M+T9X'Q]&,83-9ET<**8G>!7U3Q/=%_2NS::;9_;:@NK0"CQE*7UU:@9?5HQI -MG^K8,`Q]FVGEKU7)!#669G.W:)ET_4&64$RPX@9#9-\8%TIO>N&OM+_F$#OL''FD-]Q\U -M!E<0<$#T6EO4RTU\^<07HG0HC)#2-M0IB`\,>TBG#C@G;6.9+Q&)?/Y>3J+A -MG1JIPH]EBR/>1&P-K,WLKN@%K[17K<8WD,`%DL,_4\^P0N!SZKV+'6`L15>S -M$2,MZ,CR\2=W$L=([=HU$KEI__RH4TF>1[V4?",!?#N[=^ -M]XD:;OAX\1"*SV+:\MM&)9$\:2LSC`A6D\TQNFU1_77\9?DY$[M[_KOQ;-A$ -M:I"VR6]3%#]%3T!2UM^><#'@2[>90)0JT,PV"HW1>XDJ6#=8NLO[^3-0/I-4 -M'"2RRT&I;A.X%F-CG?>DA.O)6SZ;^-1PXQG'\%35A[;#-V[6><-5N3"3X4,B -MU2CGHY5H:.S\G.9JH4NI3\7Y`:G%GAF'E)/=@YYDO2>-@.8HR3T[1D206T7_ -M6+ZD'!1U(KOFY@'.)3`9*`/U,4[K`^$ZPM]V7SV8_Y7+$&6QHA?4DDI9,)?' -M/C.9J-\_4<2T@&]E.X&V2E$P_YJD(E08I$QH*QQ.?VTS^QV$;,WJ%-A=C6@9 -M-L^A8Y0M1!Y>9Q+>I\!F89.?4XGV$]VJ0?U*HE:G5@^'-%=/1^NO[3JT,ME" -M($&#LY+POLE2F!B8CT\:ZHM`G1*>'L4"%:R:.!CPNA>M)\T'!RV-S -M(QU'??_XE622!6?'*5G"F+>J'BT)F\7P$5YQ)*+OG@AI'!CV./\-V?YT.+O" -M1_1FO9J#1\8ISS+B1?]S@:1(<2XJJ%G$VCVN_H%@#C[76?Q,=, -MJ-(3/,31JE#Z9!@;:V9;96$H.5.Y>^`GBA/M%@D#%E4TN@96KS3R/C=C$]8W6M-,22C"T8-QM21W2->[2IT*WWK@":2,'M-]V)*F!7Z@$;7-2==._'`4&=HD'_^(Y:G#3# -M%;=P3H(M;'F%O`K50C3(TTIE'TGEO[DCHFLV366V10*;KX-KT.R,S(1&T.6E -MP9Q+A>-5Z!>_K3%B@$8*QG%+3!WH(5TY8S_EE4!ZDPS%+L'P$EY(R!YJ7,EVZ%?P5M&>P;\B1YB9;TXA%(TOB\*!,B56OC"!;>$_W"FQM7PT -M;K9$_XTL+OI(UUOVB -MN;\WCH$C'4[7>L.LQ7-@`JILK]+DKX]Q_\9-Z>H\F-2 -M5K#OQC)PDXGP5#X_]M0\H^#<]NYBG8=7$SZJ:16DMZA^P?.PX(.`LQTKPJOH -M23.=+K#ISR\O#L]PW^^`H=7;&UAWJ^%H)3!YG3KJ<$6D4(NQ%3@-B:N7?\K# -MBUSMV&5C9LSOT#-N1/G<'-W>"N[H$`@,B!"@CF,GD&7R3'[(!7`]/(EK*S6^ -M&R5!["@DP_N+OA`A!IBB(R-N7H<+)J&7O>?>\6NAE%^/S.U^S^2D1YWP -M;BN!#';-_+Y*289U`C_6G-^R2/NZ^!<'RRF%ZJ"SP<9N..*B@I\GD2W9&*0D -M?_;1"B;5J6;H=WS60E5&<"49BAM&PC6?=]I"O(E?Q(<1]/;?`+Z%E,^VUW:/ -M9]R#PI#;W/9'S!5%@>!,"VV'3NOI2J@)+?5C9M)=2BOPWTUL@(X($WJ^ -M9F/3@-+#C@5=%_[DQ5`(*,#]\EQM?.9G83P%X".-<$P+H]T$[:T*%W4-O;?I -MO=BE'>TH;O>@G'A%:\:^KB&5N;K-WI=KPNWYT%M]W@D!:7BE',G_A+KF'E!V -M)8#+IB*=2A*=Y7D@N4-0'-DAC/%URJA^RY]RF%;Y$T:^3$2-=A88(X(@\<4U -M/:ET%7=OY#17II89X$BM7T'&,XPN0X"^H5F"_UA#) -ML?$0I`#I!EA]3@]T]#BY<'/9=X%1GO3!SBFJ"X1!GS`I.(]F^ -MU?C7F$`$B`%^C$XBY(U;0>(@^I#^HAF)KTFW"T+EW!KC-T8+%YMA'M%"%00( -MD5FN^_ZYP])&K?#)#D]<[X\EFL^G/U\>Z<(IE`C^\O3MVO(&!+#`Y*EI/I6K6!FGM(1IM8LWLX/HB4D'H5F%KSRA[U8/>! -M-QZKMJV."%#=M?3[RG%N7>\?I-RYZ!9+G?D#$N^\.3KF_P\?,8\YNF%Z\X3P -MJO627@%OQK<`?.FV,:\\ZDP&=AW]'C",_AT/TW_#>H]^'CH*05UND=#+$#G# -M)=,_DJ[W-8![H/S35+/.(!>U4+*MVH\+T856=5WGQ&#IB:;<7*8YCZJY^QZ( -M.6PV8!W#0W%PCAO0X5.M+@S<8G/:FI2,5PM'@<.Z`R"XU6A;DCZI:CYAVBX_ -M&>.W"(SO,=$)K+Z85?_*[_EZ:M!IL>RQAUV`B&,/1T[WB0-K26MWYG.#OJZQ -MDX0=_I^P:]0!SMS_RI9&H#MI?2:L<:V:"V2JR%J=%\QM[66B::V$,7WNYSTG -M7`HI/`MZX.15YF(!J`Q3[_)X8P_QY=^J,V$">Z+S;S*Q;U"4 -M7BZQSEXEC)37T)";"H(J_7>G@"8&`Z%-WB8>KS5SDP`(J4^6^V[NH27J2$X- -MOOE8""4%8="I_`#8)"=:+++@S1NIJU*J"GF`!PQ2N&$[&@>#E"^O]XA#$BT: -M)!V.1M`M7NZ*EFTK$:`8(DOHI_"0H%5Z5]F'I>)=[J"&AQ9P?L0]!F*ST']G -M"I/4LF%8??-8>KOX'J$_I/J8NA\REY)*\]MX(A6+O<+3I\P[S'KJU?_54VO< -M2';J1U*ZF(;#"`2QU/SQ&X.^[>7T)B4M2+&BWM(8XV)R-9(C56?KG;J:JTYY -M9*6"LBO8/RLFD#'I(H?B-@%D,5B_Q39\R1!:!36KJ)8(SL:.C640(E74K&:G -MWY@+(+,>PI79X"BO0'E@/#>":\:85@JPCT^$FAL>O/(.Y76(7VK"& -M(M4.U5W>VITF&C[22E&*%[AB0HYM?.-"BL^2*D,_$M3I/O8\BSQ[DH8P!94M -M'@T5@F6R/I\6_G46GHUDXN1QZ6,["/U=(YJH&M[;EV2&)Q:A\XQ2=M^?776? -MVA$)U)_;!`#EH:! -MR>3#/'X`"F(R_*HWS,DS&M5A,S:CU+*:7.]2#UX1X83>`^VXNF%GY+#<@B5-\*0 -M[_H+4%&H87._I*?@]KKXEAQ2_/*P]]6.8E*7^-)J55.&>+JTIAY\B91%E>>R -MP"ZB0[IREKL(-0D1G[69=OO!(Z8$3T42&S5\-\&HGB,.I!B!9O60N`[&''ZH)I+-[@>R[5W>Z>3N.NH;TL(L@99[KJUI^?[ -MGHF?O6T&QX2%<3B(+VH()X@@+-OO,Z7:1Y@CG,Z81&7A:I[G0U;W$;P"VTL0 -MV;D!RFS?)J[E=W,+LH#($'Z/K3&5,=.0QXS=W`#56AGM%U*B;)#HA75UA4NB -M5UZ%(>S%+ECW5+-B34L/&<)AGK>^$/O"KIH.4(F]66:']DW?:?2!*KJ9)ZSZ -MF1U(&EM>A@"1&6(I8/KP/N2D`M@'8.-H*-NVTJ4G&OQ_=:%H+V84SO^PN:1& -MW(^:`OEH1P1O.G0[6EUG^GE`5;JO]I>]&W9.MI?\&'JEVK^E5S_Y[M6N[HX0 -M9ZQ'J=1/V_L9(M>1M6H-`4U^Z0W+MM`RGJP2B[R6$EPU/^RD!'HFGQW%5D^3 -MIFUJZW&W,2Y+B9OKP-WGM<+N%=LB.S5B'+/*_$Q+^F(=/O;]P5NON-]B0W\8 -M'U;HE((; -M%\/]G['%N0N6+`S'UUVS@.E(N.&MFTMOD.TQWC6@,+T%QJ2;M1=+$=G.+9#_ -M3VT\*K\IB$;(XAG:-_KY/P*-+`PY74$)GCU5ZW`@F/S/T!-'A29[^0;_8`M? -M'L?OKW=WNL3=G,9P7QVS_"U80^EJ))*'E^$H68WESN?J=LLKK8ZB/X9KWW4S -MJ00B9':DJ4(WR&^4'ZA/FO,"E\A"DT4F$OW3H+@GX3,)4-/C\L%N,'2/&076 -M$I&P)[>M$UY'TW-C**C71#+%+N\[NG;59?1SY!3_8TK(HW]<[H5+:PC:-FX, -M1^]XO,O5,D()%HB!LC'WAB^YPG6+$#`/U7<%5<2CVK*=#A@Y:^\8F#S4.4 -MG!%8KQM*M7LVJBG!<3H@N6HRZ[61:.285`I@0D]/S08#)_8Z]0G^;QY\T`6+ -M2%%4@?T2[.ZQ\I"]"61QF%1QMN2%1K'68/*1KXP%QZ!7\M-HC_519P_:Q^6Z -M"]7/F%S)K9C:EY`RURJ2/\<+S>7$3,]C*..UB%2+D"`R:JD_@, -M9J#57=,MP5/MQ(.TX\U)%9ZBC;TLE=3'Q__*RSB+" -MWT*`"#BC_?P*M*:IFLI/OH@P'$4$Y$\T[)/O(%\0\6-[4*J%T%-;OQ2W.`,_ -M:`,\_,]7]P)[]575C!3B"#<:)8LR?1LQD1@YC+!->^%?R7X'"TW=FV+NY_'? -M -M7%F*^OK.+"-)V>JY,@643.)F=8R**GB(3^\W@,DGL:C8;87T5SS'_U2"#HO/`.X5&);[-9.(V)]1&>NJ54Y4?UWYQ:";_:.%T7\KF*?"J -M+@@^%4TB&*SR:W)-T5#B304V11G%-QQ<><*RDS+'J/:FM1YOU\>`!U(4I9UM -MI5T7]150YJYL9(!,\^$J(D(PP9`P8!=GVWIL;E5`7Y<5)W03U1.6CX!&)WHT -M?8*[P5?[-,)YY,[?SQ59]BF$7MSF7E'6LJ1Z)]T>C:(Z6R]F+>]2_R5;ZS=C -MSQ"PO+A\52-A)M8RYJY:47QQ02+&(?K.DW0*^3)B%K!(N:T);!<5>,&\GRXP -M1]"'V!`%X3GWC>4P(D?D#$/U8OH5GZ_U".3 -MR*D6R&>`K)S&TWN11P[PS:3&@YI7HC[=8A_+7^='W=Y@I&FVUY)NU6X&-]U9 -MHS'L3P.S>N^\T'N2U"QOG`!)0S3J@&O/\+\L"C]-4'=G"T@)G>0#D1-9TFBQ -MP6-K1@2'RK,X(NQ^7O,`K6:VDE&>?`SMBN9!,'!N+R/@VM[9GJ50?9U$Z'$2((NJ7M%IRM(K13%=M@EW*0GU_>@!Z][,RR6+LC83"ME4GO/_D -M6/7QW]_]B(?=1_S:3.ZUDYCJ)._#H:Z$[53&FC^2'6@G0-00`Z>D@,?T`HS] -M&HFAX4+0;W0Y2]*BKJC[_%/BZ<8ASHD=ELG)S:54&C/`+8VDG>16X-Z9E;%; -M-:Z]H2]/V2Q[SSC,]-YS1PC((&=O'-O"B,\.^:GE%]=^4`8EF`HXM8$C"2:2-I&= -MWOWJ-'%?)8!96(N$=_9^]4.XE^S_KQ+!0!TEOM\C3GG+ -MRR+=Q;45L,+$6=Y#6\$54!;`NTDOMI>1I:+E=4G9)>Z4"Q`>-Y4(E#*YX-Z0 -M/$W4>296K'T/VYQM[[2"#W`&I`H[;.G.L'@(5[J@J -M&2'](:G14"\5!I96X:+ON&PC81K/)Y\IQ^``:VX2*E=RWY4+^;!W\"$:GKY8 -MOC`^W<+\#2?P'07L -M_F/W1N>>NO9!8)OP^5A<$/D\_9X2K^D43KF8_P@E7'6U6)E@(YZ_;8M1L%ZV -M:75`:*\4N8F8!4[*=G3+Q=.1`U`O+W>PM:M]"Q;K#?\_IXN&XOW*(4@D$ -M?DI1S_R2RA)8R@0OE-`AND6Q*64.\:PR1\VE34R.-;:;NJD=N`F6M[[(`_6[ -M@KX\H;J=A;Z.IGP-!8_BXD+[D0B[Z].G]T`=5:FP4;#,;:`:-:1@9"GP&"0R -MSCUHINYB((V,0,/(QZ37SW7]>)%;@]'[7>O8LWU[`M8^BJ5T!FM[1\-N_)^T=.@H5ENS\'<@4Q;J$*OB$L='#B(HQ&L$!R\S*4Z\\TNFO7=[X-F'<):47AN&_F13'D0)XG`!@G)"(A$YBK9<:KMD/ -MA^__4R+QF(3D:GHZ>]+S.5C_;D(?#-=Q02&YI.^MP1?7:4)K8V2V49S7EK^$ -MME%M$TRSU;"_^KS0ZF8)SZ:1BG<9^T()*S;X<6(B9[`E8MYK^[)7?KMN0$3GXY?7FOSWCPL^W69V/ZQ!Q -M_K:)_O-P9G!>8C.\2=:L'XA&C0]6_.N'Y(^*T?5J -MM+E,XH]JJO6+IMF8#3LP:G+11JEE'GBO91&SX?4*#8"%DE0K'PW$'HM4DT)Y -M2V*76Z2WMT:@?4Y2)%8>TF).NW4,F/GEO9V!5%_WGYTM^&I^6[FW;LYHF -M]*=^ROX=9YMQ80B4;2R[4J(6!=2-K07%8ZCTRX,Q*VT[F!T&`O -MW1BC5"?[FF':E5=`^:,^NIXXH9P^@S%_Z*2&T'38$5^X%` -MSERU/)$!7G/5:[Y\]>^&R-!5L)QU$//WNGJR@3:1Z%O(6H67S@KTZEF&,5M8 -MA3G.^B;P&RG8:!^P%T_#HW&/V$7YE&DX6^!U#KA5RQ&Q)D=E7=_]0ZG('-A7 -M%Q2B,*DR5?^?6:)6#62!YWR964M0:]@19K>66\I3Q -MAF3V\]G+'E_DT.G[8K1K[6+9>O/R?_(B9(D)[J>]/.JNRZA_PD06/>UMR)6^ -MRAM'YRX%A0Y:!+_INZV!8$S/[7@20G;O;]2DL']!R$D0[(DWJ,BXMC%DHC<7 -M3@W=)2KE0(7C_M'.L69J]X((;)'&C@E[;W8O(O9/UEBU,R\LR>&(D?CKW_FD -M#>`:^BD4DPC8PPDR[M530J_F]0^WMK^I*M;KPQ"Y56W4((&^-S_QMMZ&J0GM -M:?9R"B43S0$\(-RL>OTN^7R<[(ICV?):G)E:_7;>9TMFR^_OP-+2NVUGNBA] -M%!=L[R>0X[S-UQ*FCO:=TX=G[0"C?RB&R$:LEKG]\"BKD;B_3`&`L,=7LKUSQH%!^ -M5+'^A5_WG%Q;.&8*2SN"+]\EKU0QP+AIV#25E?E`>E_NQ9I8-A1X!92TX#S- -MM&0Y"%;`JUQ6-"<^JHUP3W=UE06D^"W7E@65D(@WJ-*>U^XVEQQFMOM+FIAC -M55OY['AEVI<4@TQ$5U]'6LU49A,?\QU_.N>IJ[L([)22VR@*8`AEW2]!&G+K -MQN(=='!Y1!;91O0;B)X&V&:_**O368I'(KG'UOAO"`-\"5#*+T)*_+,H3SU: -M$GQXD[(`*6(^QZ0HG-W%:MZ9+^$C!,5-5@"> -M1OI.;"/-A:`F#4T\<8_K]=I+QQ[[A)3)4^W&I1^8KRA3"S%_0Z&2>'4?,=LX -M*R)7%'["0D55B4CD5+0OO<+6`R&H%()V]`+BB:1=:^HSEEDB(P.S(!FRC[49 -MYM1".??6[7U\.%L$:2^_67D%E;O-G1H:C3^8YV.$W;&HLGMF/!%RTV?TU[,- -M:>**00NCEJ)W_P8M%QN-$';.I:/Z5I/JA:T_?8]+%?>7/("/]5:X_#D,;L?3 -MDTL9W0O@NCL#_:3+A/[^(&$6Z94I#L`YKZEICFYCJ<1K6YT^"4Z7W_P.TFEJ -MT7("SL>=A:9C']VZ5%P5NO'K\G%^/HNZ5%0PAWY"TJ.+GA/Z5TGA=#[Q3M'' -MX#N)=59+(41NTFG95^_?\M[)`^]1A_BP$U_/5G`%.T2/Q.S-AQ40+/#0^+NG -M)<<;S*10=F#;I!_C=M/.0AH_.SN3UJX-%=_I#R+)HHUC/O"'8:#GY_>+M?"RS/I"#;#$&F$S:.XYW@,T[.\2&_39!**HWR\-Y==RIH-+^(*`F*/ -M?)H6'8S71YQ1;DT<@_SB/TK+2O]-9@](')G.Z,(46(K6![ALM(9MZM>**:!T -M,;:O^X-_8C0+\6D?.'I1`KCYEYZD[R[,#=YLM`@!L-!W<_C2J#<2OBT('W7X -MRY-ABP77\+&Z[*>:?6"!\N08^-`7W[`,4DJR!R(][`Z3 -MMEX`E*P:/1X^1O&GK)XXA<3STA6WE33,*C3HY,[NL??[$+6SUQ'*5^Q\<(1P -M^QBRV?_O,4L["B^BBI;(Y[X05 -MJN1F$XZ*MIJ>]*K:C+Q&=30&OIU47W5Q0%3[IWX9JQNYS82=!T/>2OA$KG/( -M(GZ+.V=P1"HNQIN[9YC.IH7:;"M!68'JY9D.,M68^S2C3I][0>?R%`>M-SOI -MO@45#= -MCL"%NP@5C-H.?A&$U37AIKAP/'(\3D3^J5\X#!QM9R`NXE3N/GW*T1F8?=2Q -M/]+C`I2;AYT`%[@2-OA<2H!8D%_N]_R:(4+;MS,F`S&N[<\$,\7P7'U`T9XD -MY].\%)A"W/!C2HGGDL\D6EHY'Q;K9@/3-*ZQ69')<_#0?03:MAJ1^$%L\N7X%$9M?`LX&UE27NG;$<^! -M^F`,Q"5EE47V7R5")17\HCWW`=@-EGNTFDS>V:%#/!3NP2R()FN=T"O!YYH/A$1%:\-B9X.%O2AC)66BI6@DGMM=[1AY+\H_ -M1ZZ!'._\XVI7M`ZC?17B'W0=$+EGT4]OH%)-H*=B[F_:C[$AO4`T/Q'3$L^6 -MEO)JL8G%>D16DSLE5H-W-%N**!H>%,#ZRS\6*UK.W&)NH#">,9PTU<=31^/& -M79Z"-OFUY5V(V_"BO#)5)L;DE0T`A^#PY)/4U`?@KWCFAU='@NZ'>X<:=8>T -M#+G^J0.TLK!:S6\7!'*5RJR+-SW7PP$67$9/NNE=]QD#<5"G\XQI+GGI[:$3 -MFN#0JN?[R"T(,XY\`C.B1V4TK-0P0$S_AD76^K3P&X2$Q%Y^8W'B+K-*QUNT -M.>4U/R"W$-)P$0P%FBE_YW?\V?EU( -M\/EZM>I$_YT*FY`0QPF4Z@D@6WD*1]A -M-_Y_4'D>4H'F44-@,#R+M*D0$BLH"@7T[C[EXI4#$0X-\;&)LFMU"6QHI#MVPA@D5XH&5POIC$K#I7 -MU<(L-;-UDUACH5,`P#B:%*'H>B-;^PH7;43.BU_9Q/"G[L\[)Q>8%)Q`ZG;% -MC??84-`<<1OX`L -MFAA+Y'T@6R!I\A]K*]/U48G_S?&:CE23"[-S_/Y=K[@AD4&@/IZV>2_&^,P^ -M)(;(CC[9>PO0+1J7`S$#$LE1*YFS?8!`AE7Z[OWH;M:8,Z$K_*?JNJL.D86B -M?C$X!R%J1RZV]I9`0P3N17(1TA'M>JB/TF<`ZTPA0XB":QBG>TN995*JX$2E -MZ;RD5,L1MLZ+OD;610'T]5W[:A@I9\(?^O+5!'"A9B"9[&P(;J+HINZ)*7[4 -MPLG&H\'"=I'J+O0@5>R;:JR-/4#-./!GO\MN&.:CF,"R+@9U(-EM^C%_$A/_ -MPZFR.OPD<`Z4\G4N8M;!8LBEG1X:D]3EVI0F -MXO/7B/K -M2Z9[5%UU0&P_?IV9/A(8&V,L'U7V-II9 -M,)%"FZ`NU!,BJZF.!"]PP*-FPM<6Q,2[B40D"6/X?0LKL0E$0T0P1^E(=-1( -M^^$Y@6(M]+OOC)#1M-^(>[89RT==SC]]=P4`ZCG"+Z8>5W"BZ'>.S8Z3AS2Q -M)V]"\9L66Y"OX%T"NBZ@?5+^IZ$)`N.%4;A.3W(MAY$8R+CU05=E@-A.P0M- -M-N-8(K/R;S5ZLT2>:4\$.FQ^HO4I^L9PK5+:]D1SZ2&%-9TQS -M\@O,YW\D?VR"])KMK17_Q4X]8YVY'5REQ!M8F.3UR=JO`K3HR-[$PCD`->/P -MO?@CYE'_PQ;%4%1MHW3%-U'[PG8K,3:J@9!Z0B-^-%-(LXU.&U.,-I;/O[DM -M?:`0S@-UP5(BYN3)ZDLYA`?R!1(DW\?+!X2 -M#:*UXDDAW[XP]T[$Q$D_`^:^8M\>LR.;=?@D1\W/&VF9\_L.\+-EW.8M9_1H -M1CYL")K/6=[+FH$A-!6A'0<_B>;CDYY)\JYQ%_[L$R"P>D2)D8E5H;Z2*VK[ -MK8Q-Q?>C1OW0'PM=,R?C'*'P;'"N^']Z0$>4;KW)R8"UL7=0>C_>EQK54P/F -MT43=Q9DE6(XMVIK>4OZG]S-%`"4IE_I0Y\MFE"MK35Q`O;\$(3LVPN]8/+?= -MDN[C<%LE>UL<)B5PR;Y(BKY6#CZ$B?$NV!.,S+E[SRYMO>)UI`]#"C[K/]GX9*\(X&$F-%EJ`A/&DS -MM%X*N>51U4G#DZ"MH)]T=C\T%`+UA+)'L?5%XK/ -MR/(G<-AF/_"_''W17*)@(]:AK3&'V"G.W-_9?X^3!D'35O6M4C\F_H%=*DHU -M&WY4\E?]'M^4/P,BPIT/BZEZ6R)<1R*^]A.5B'%IT7JX.U@I5N53R02KF4+\ -M[.&Y6O8THB9:K=TV^P/M2_."/V>HTS8)^DBX0]8-LA@*I#HNFRNOQOTDCM^- -M:%,%UQ=O3?5"-ZC'BV-_I,8RF'0Y\Y8$XN*4TJMTE7B9O8:QN=\2*>55+NNZ -MT.)X)N"0I)RR8QNJERN%)P*W7ZZN%Z4*,S_7X#<.+Y6H;02F>=[V*#<`DX90 -M;RG$E*A.G7[V^J\OR4UJ*#_^WD=X!,)+LH/8Z-(PXTRA5^/<:J"LIB#DIRTB -MXA4>'-#@.YREG['LAA%=4WIWWFSE>.J%8]DW8#AHR5R"OR0;6!3`WY\\(9NA -M:,A#E`GZ]I?O1;L;HD,+]%/C0_QB6F/*,>8E:UB);(:_%ELYCV47\1Q\\-^> -M%P^7S#1_L_><8\#-:-]"'NINLP+H82#Q0ML^UBVS]'?WDWABTZD8V2?KIU+C -M\@*&%T(M4;<;M,/)4+[8XJK]K[U'\%^?A%$'E^@@+LW3'U0K`N.I.VHH+?"S -M=6)ZB*DJ>*N^UW0PAH87&*\C8'S^A\J`PS#S1[DN<"\%PK6A%U\!H^(MTN"] -M@T&"=E^%RRYL+[-Q3*:(2'.@U#Y?C$S#ATRR0K$&389\&O:1-%C#08:A -M:9-57ISI:PVI5+JX\\&O^"7XDM,H\#QSA-P^6#&V)F)?I>Y6IU.C;IE,;0#S#3 -M"G3?YNR@ZQJMCUV20N!L0PAJHF?DW7I,R$"WJUF6BDSE(`\K"HP"@5S.ORH= -M8S9HF`[1F\9`+Z%-4S"\;/@D2K>9OCF\Y,Z6*]&EUN0Y84L9+!9,=)MD8Q`6 -M*C2VT0_O<0)828ZWSOL:6N+L[OK70"O33&=RE$O=7,N>2XUK7!\WW$."S -MEYDQLQM;%*+.K@43PKFDC!*5JP!SVQBI7MNHSW35-C322$U3I-CO:O+ -MQ$=R6G6BQJ@DY)N]:.7+=_NQUFY'D.ES+VI9H3#:7ON:KH8_LN.NYJTP?K)Z -MIS1D00L)202IGUSCTCPQ13URFK;@VX#7GY:QPST0YL!`,@PTQJDX\XC;C&U@ -MJ^U>9V]L]M$$T(+",!;M0#!P!7Y_Q9_N>M-+#V_PC9?YS5,Y45JSOI,]-2L: -M-D+`:&?IA+W$!8?N!8MJ4D8TF0#L>ME3L4U -M\::Q^\RBQ6]IBDP/HAL<_VWT9V>$TE\HM4<6 -MB>YL)+":)/^K`75S<"<<2J(#!)2,5XL?''F?2=-ABK57D$^9N./1U22;5^/[ -M8MRQG?4B%XWD3XG.:XW2*X-7@2<2GT'A\UEQH5O-5L^YR59[RQ@ND7H,&+J1 -M@A58I1*H^MA5`8X]QVG<>4RU&:A[@"CM*?@$FO6+2D"Q0!3Y3O]$2BXZDO4O -MZ8J^,AB/&.%UY+F]UM)CJ"V-$M&B4LU(?.M"DEW/R54?<%2664"R1Q2O5\HW0:G\.,3%BE*%S0[*"V -M(QU5OD,"L(GQA&EK_97E3[+T:P<@=MNZU<-N&5/:H_V5\1_J_%`G''EZA7+% -MGR+U:X@58O3JC#-OQ!CK0"P$2OI7],1NP$U;9YC"%3U-9NUGAW@0OH,?5-#A_Q@SV]0T*0`*+5(0G]#V,G -M2(IUT9KW`89ZWJB]"\/H[6):H]4,.+6BG_B4P0D0*8_-Q`ESX6?:.[.L]64O -M!N+2)@H8T'1UY`WJP*4J@Q@D:Z]0P:DHZ@IX!975<[C]P@^_E**T7[^"\+#5 -MDA8":(F0\C642!@/[LESK*Z&STD$\@2LYB1$C!O48UEVV\$@]VI?O@-;$/;8\42#PZ-`RH`2%"G6>F('`8'(8V&_&:T(_K#>[I9O8RLU?%4S6AV12:UPV_=4UZ*!J -MPYG<7Q_0,->(0,N-'BWN'O3H@P;T-LSM3Z)(@B8PQ25$A'CFM+'Q+&N/+>;\ -M<(Y>]ZR[#N3;$0:C\SF`?WB'A_I:5N0PBY%=(.3H9B%/,31)AZP+>44"P@9E -MH^4R(B."_%UF4_U9OX?/'#[SL-_$`:_R`3*]3'O?0K$68O*].H=!+:^(2"Y/(E>2_Y1J'G -MCE-.:J+=<"7`W:3W5R4^,$8QKXVL/"_ET)PZ'@0SA!O9R%_R5`98.QF]XLFM -M6?0O6ES@(>NSNW6$ET#W[#QM]&VU5*,&L7?Y3WBATO\LX&5?-&!0T[& -MZYWQZMUFE6X0*9'=#ZEMI#;[@,C3`\G"N\;D3;!$5:`E^LWBW7'9H'#QS4"> -M+J=O6&*EJ&0%3<BF?MX%33D@8:K>,19?DB'(GN,V/O@ -MY4BNKT:9RM&8,[C<(;&9IS2/ZQ-)5AJL.$'84[WD_1U_M-@,F02\D?0O#R(M -MW&KT#I&:*(<0YK!;A/>5K\688VVE_R7]U0$2PB^*5"VFIR#>;)I%0N?]PJ,0 -M))`2J=__CL%T@\2`]LAR:KL."2TQR)2+[28M#6KV1;2+[RT><`Y#Y1%[8JBV -MWAV$8&](VEQE^CE1]P"#@&C1T9./B=L[14G;T'[1+!YXT-R$ -M$9K,LZAQ49UZS@<#K24)RG`.8?7I.J9%0OXL19!^MY#[?/^+8?C&JR#Y"=G( -M)!KU_4*."=4>S.^2F)TB!$6'!]<+4L.:;E=0=\<]\V;G2(GSY"$D56-`TT -MV#TT7<777*@\,:P+!S;2RQ/]57(@3`)2$4HOV[OAN><`]J]YQ^5-WP>S#+Q,#S@?$N_HGS^5O]_D"F>(O9BOX<)$E-'TI" -M_'&OHC;\Y:]F?+9[9,A\XCA?LSMKEZ]\%6X@"=M]D;\2KW,V'GDL!%7+6Y2& -MR5.9>^2>$#?>%03?!S^QK):1RWM0`^>Y%BW*[8_B[G!4U_1C.>UPQ&J:^KYY -MQ?TTD>8&>Y?I1PS<5KFJ3>].MWOMP\HIP&>Q?BEA6+Q"X/.':8E.OMY-LFG:T?(UJT>4 -MW@LC9,>`?[5S-5L[*Y\:?EMQ@)I&3>MOT^]G*S9E1;<],+A9$-W"PU' -MP(8-F!(5BO=T)@-GA,8:T8_L%I_!/>AX8K[7;*;81VPO"`-KDK-`G+'LFLOX -M)++&:^WN17SGCU]2,VO8\ZD\Y1R7I?0LRI>"(@YPFZ`2=8_B[KP_,&@X/9HL -M*+GGCQ2TW0TU<*,-;*V294,G;7*2Z5U8B?<$.UF8F@VUC5ND@5NY&"'"'.:( -M`O\H_)_27V86H'+_'1?>,+XE*^EF(-?UHL4DPL4!;MLV?`8K$NW0Q_0I9:U3 -M!NE&U;/G$7VTFQ74"*F:@X#<5=HA]^A:61FM,8HLD>,40'2!!<2X4IP+3EG& -M,G^K/7$-;)W=0.;#VOA::MYEHT!+@4F8SZ6C1N+D=9SF+(F+%RY.+(N)PL,; -M,ULB[N`"')`7E:FPP!I_WLARO1[PCLR_/$#ZA+5,X&/`9(=+'R@MZW/ -M6B+W9I3NW/E)6QLI*F.T')YJ\(;7/Y))9+)$G/1?FZ+57M"EIR@+%I%E@"%K -MIG",'/"5L5H]/+1BQ1"Y5V^FC?K@FCL&!&>Y#'9UV*UMDIP[=L$5\[XR7M,:&#HW2>2.][N#/&_>.(98YX6EI(6?D*SHTS3^M -MRR>/U);+`=E7\'BEA('H/DPP.MK[7@[*\^G%DG;?X0N\XWPA%]_KZY-=D2Q: -M^`>+A$I$T\B`.RH:Z$J_+L8)U*\N]G5E3!;V_U!\;E/@K;@_1M,*P:?6E#-X -M',6KMY?QQX6`SB$\'%<*^SI=WK`WAZ(YBL,]AY`.DCGKQWN1BP1>W!DMLE55 -M5:1ADE5+\$XP-CN+G3>YK1HT>4!!RK0$]QV>F%#ER?F1!)Z5S=:'?O)"K%WM -MFE6*#2")$R,-@#\P[T-:=.S1!)),9FB3-A@%.^=0;K5KL43A4`S\>VJYUP%J -MYL5]I:IK^O7XT^@[*^CR,=I>>>DD#5B2SIX/P?65'S1^(0B(D=.B(A@'*7^G -M!KYH0(]FINN@[$B\L?"GT$W0P]/OP6B?,VUX=8YR0(JZXQQ=\8T-$J=?+@]. -M('VZ4UQH9K"C+3V*XI@QE[L#?K^L6;&RL*TVF?[-I-+^R'TDK8T&L:1^G:UQ -M9%0HY5<]X\^!)ZN97NNH[[DR12FCK=>_).O3?!Y1>*"Z)(RM(((.V(C1',4] -M^]=X@J>D5D:=Z6KG1XL0\$JY[G;%^:^J18C#O1FHV5#?)?V@ARET*/.YKGPU -MND2Y64ANR/2+_,&COJKIHK\Q4SC6U`#I8L"?&=(OS)6I?718V0]"6;/X0#EV -M(+M@B9-:&70OS8RRRTV42N%I=^.Q8HD)_=`C53>;%1;_LVV`PKKCKHM/_6% -M(-#:=_\CL3B6RXF>B,"XCF1ZYBXN*WG66J4)T!%9LXQ<"UY:9PJO%:P8K.U% -M>!I9YWD/%<[_JZ088$9"(J:HICA9R\?+W=+#`^%`=R12"@QY'B&J:,%Z+U.4 -MLOMX"]RE?1.-WI.\V8`MJ[8BE<@SMI[]TL5X[2.`OGC`![&'A-6'1AK&IQ$F -MO8],B\QN+6S=(``J,%#0/[SLHGI23^IP2;=4JTW7>"\L95USR%#>?,BHJ.Y( -M:L:LI8?4ID-^"Z-`4OW@5G7M43`=U=D(8:%*NTC!&(K5%A.K<]/OA]U(!#O, -M*Q95_S&H987P3YQC^K&"^")Q>TF\7'OFX*'B#YS@SFD7KFVGT8&;-8&=F]'H -M;#[MAX,T]VU#>]HZ;OXP^;\I3?Q!_P9"@F]I:$](+8GUB"O2?XTV\Q-H^=D$ -M;LQQ\VX>/H<]J7).'5HV()LCE7F7T)\/%P).3[0!BH@;8K'I5CN7O@IY((<< -MX,A!S.@HKH[WO-D!&*Y#B[TE&8CIIT1=Z%%A>4?!1(+)FP^K3`G.'Z6GJFRM%,5*W8K-.!Z@3VZ`Z@ -ME_L<$?L`>2+V\LN8J/`'DIQ""8=?E5SO8QN())[GIP;7#-_@=K&L='C05CN/ -MW23,)ML=P90NA#*63F;,-C+*Q$@6SG_I\^HL7)3-K0.[2/1#CA02MX@'\+'' -MD*4W=.PS(:ST -M3<2!QH-\"YAV4^/MEOZWW4EP2N+&<_J\$2D'QS/GW0%WY1=5?8VH3?=<7 -MS4LC4F9YXLPN$&%D=`^?KDW7W*Q?!V=31@9SBN?`CT6WB,++W-,; -M/G`:1(##>6\C&A_)*2X,+;"2-QOWRNT:$$!+Y -MV6O])=W<+#S<2;<+<2)D#)%BYBG:2P$'*6T%FOUV[X+/KM,++(CML\]YS-*C -M<77SR[/8FNBU8)=4`9"J"DUAB%2$_:YE%55!5QVTI\T7UXX_9=$Q;--/K/L#JX.L,VN&3>%^E%JO0!*Q04"`F#LO%1LZ5-[\P!%_2IG?4'&)V(ST>T] -MG]9$8!3_:.,/]0!.$!6<[F$"1:PU>"NV(IKQB$M!6\>V-1=((H76#O,%4W"< -M;WUCI%MAVP.+E^_+T2)U)BVR@5$ -ML@):?1]06X-0A=Y7\(FIRR[NH^Y;4OD8G".>B?1#:J=35DEINUK\RE?XA6\Q`+D60O3GV*M*>4&F% -M"U_RE\'6,'6=%L=I-"@)J=VF4+GL`/;H-O7I]R5J',5W!RF`T97U"MMG>X83 -MB$W>BE=1EJ0]O3.49`\\QYO;/H-*->V3:!"-K3BOIKI444M144C(<20)H4JQ -M+(F9G/"4MD##F`=01H4]Z_PA^EWPD9M -M10VIAQZU*(#44PDQ;Y-"#<[J:/JQJBAX&(2#!4Y7VIKW0>W.P6N/)2&/<2S] -M00?-UMI>=VL?D[=7CM-UERTE;Y[4!3PW.\`_#J6V#2ER->$*+1#?+(72Q^ST -M,9QG)?*9B9"L=-;-B(;40=D358+?GR+T)5F'9:NRB92E:SE$("ACD*P/UZ#& -MNE,*D3#?8?]D44G9="!W':$^2-_9+Q"\^K3&V\L/Y")\>FDIW13?R?A6[G!E -MYI>I^YH2RYS'/\^Q8B8\R#:NQW[)A/:E7\9^96,S_-C8S/9U$Y% -M.`C(.*K?^V^JAZW-$OM:.#`IY^`=?ZV]VG`Z&?]RP/#SH:SW]*?_0=D_F)3* -M[8;G$LG,H]24N<%K1@E45>"3KW7UD%NUE^Z`5:RN7\;8L[$)>$IY%<)E^,HJ -M3-'\XW*7H#1SI%GU!P&2UT7K.9:5_IHICHA1-L(2>/MOVZ1*Y#69Y-2:'L?Z!59@;LK](UGF5U53KW%_%29X47E*KG -MA@J-JJ6/(%:9"%EV@$.<96HT)"=D&,[#.(+"BIDQB>E:7+<0KG!-_0.$6`Z/ -M]!GK8H]OURNFWU%[,`@4FV_JW2V9.]]I-IHCHF4Z$WAK&-9O71_*IA;;++W2 -M-!$A/)TA_W$NKCTM?+)@//XYR/VPX51T699)C_#9'1%>H_8S#]`Q,)!NGI;2 -MI35"V8`&E^%BP -MP_VJ5-48)G]DBO'B[-8%@3)@Q]2K9%4QJ"/,.++#R?RP\,!MT%H*%P)3+3M) -M&%XB^M2ZB?HG"YXQG2F:H8N38"O7`;78@WAQ!H3S-,*(IGB[_+_HTG]D=P[@ -MURDI^2VD5^$#LSX:RM*_`O):'NIT6`J),RZ/46`!>K>:?TL_4I`6&WTQ"XAC -M#'/M&_5Y#R.*V4(8C0.4WKIA4::VD=BC99M(+X?7XER4':$I^+*Y=Q`;]%E@^FS5XZ&6: -M)Y_8I?(:#%C)S7@SWWQ.H7"(Y+R[1Q1!%(,.<8T22IJKG.(1=L[DJ?*KIX5K -MCN]Q:S%/NCA"E]*;53QNKE.A`P#?3X#9PS:I@JFQ/POHZ%0+E("31"D6TOK8 -MWXUII;\O$/3?F'K0-C5@CB;(26:'1:0UI.JO&;L7X!S^:G?J:N,+`*F9WON@ -M6BTXGN^J%7.P8*D";J\N5H*QW:_P*4*K_&XF.UR-3 -M$CNO?V%\OU57M74S%G156DIC%PT#C(RQ]DN^K09/=DA[1$J1_S -MXM,@$0'147!GPV)F336#3L.?Z@L3%F92]14*PE7?*U5WTKGSMD`^2I6KRSCS -M@U/0ZKY]"ZDVWWV'/?"R1I+XLJNG@Z,F -MR)*/07TK;]2/W25&>I]%,4TC2PKC2:/NW27OF74S),OW8%.%$K#\Z&J.@4D) -M=8?8*K6U204I#.[%<`.F@P2::F:N43&=NCD48(OOCNJ/'M7<0,29.6`\H,OK -M0F%JSB,;O<'JMKT\@=@"V%()8U\`_D7:[WZPS"-(6=&6;VTB)GWE%3X@^W*4 -M:?)L]3-@1_@5W':+3WB%((YF#\(WHJ:QF*WGIU85%#]*`65EL#VHUNVWI!/PG'>==>\G?J4E? -MU8%/R?J,-3.LRL9V/K/@HQ`]\HSP!D+:JIK!=;(CQS'U_/CXI^&M,DVR;"A) -MC-+;7__Y#GF?H#$(WZ2V7:;@'/I&NE,?DQ,*]'K@+FSL&CYY#W"R)VBX+8%N -M7O>*#&TW"@@V``N/4E4@&OOCRF'JZSXCL0R$(.DA*W%ORR!!ODJ1$27TCV,. -M_?0:]A6]YDWC0!H5EGC\&$C"Y*Z^_;$<7&'GW-\?:M?/QI?#!^Z7$HKP!9/X -M]&WU>N^VB?P*B!+W:/.'\]_2>A9'?MM4PE(QG.[GM_!KK@S0I\[I*!9W=7Q6 -MFX$FW&$MM*5@L^]`H:P/-*\N*D?@ELW@Q'MD%J?%ZS=Q?3G,-"[[++)"+N;L -M'O`F\T$WI\;Y,F%-DCPKR,$>?*@9"H<1T(TX9GUIR%&+LP&!X98,B((H@(Z. -M*#9T/B:-1P[Q\]*P8&TG;S\E[4OPMWMU;];U@<%%U_Y-705,[MHEZ-;,%G_, -M4H`9%L]"CB@_J,844.P_2+:'MDK1I2N'X#DMYQU!/)?*+FP.AZ:).9=52E:O -MF.(9_9*!L7"5/1,V:M:.I -M$G-&(;R_PM?F<]'3Q\9UU1@<4Q?K+7O*6NZE55`U;QV@Y^5L3&YFU"%D7*HS -M#NP6'>4:T==MBU`$\OGVB8M-449\BW^A!!A$CV0)Q,-5!O!),YJ_KHV*VWI) -M+]^9["?^)<13RX%?97P&'RUKS^?<3L#PY2]AO`/1&M_4V\MI$T*=3K:@#E>C -M;9M0"Y`4\79K0J>Q%OE^4AD9]5$:[35;J!L&^9E,!W'I]@[EXA%7.ROA)*CE -M%QQ!S.I/1`;V3NZ0)C]L9HVD-ZIJ_$'?8IQA0<.07ZK;"=U+-J5;C^+/OCSF1^NU>!;1_=XZM'P2QGVWT -M;W1G:(V!C&J]8 -M`WBIY*UG;?BHYV4=LB&T6?'8@T3_Q!8LT+U;^[HF"2V&9UKLY>U(..+X,H5\ -M0#>!@!W?NDW8NDNMS2KR[F-H!FIA@>.N9UB]`>-@0UYV#DE\Q91#XZAV73_M -M_Y!/;.[-!J\W\MC4F2MIV1>;/W@"8=*UC7FT -M`"JY/S@MXPF^ON(W]Q<+!0SE`=FVF\>:J>DO"T<>J(NINOU]I'BQL#2OF.E+ -M![1;-"9_H"?\V=^G&8_+#>*CX%7>N0_/J\7\B5KETC>.-D%X8RY.L&G\-21! -M-?ZNV:)7O"5D+18_DR92`,9ZR%+`0\?Q?*\>%-DQ.W;I\++XV]`1?73ITJZJ -MP%+*K!U3YSNP7FH4)5N?CP7:K^VK+8S,GRO^C[T=(0$H')*WWT/YH)4BGVZ& -MWIN`^]T=#;#'.9%[<%.ZXUY)2&><5[D8PN\JZATVX#CD(;D5RJ+PCE4ABG3; -MLW<:._TY33P-.!B5WE;*9K`2K6=#O1;5^F/BO?[']LO\3MNU/<>:&ZPOA\K"]H20MKJ7OBLY10?3%O&JPE*B%^.AY -M[F%YYU,6E[S<;$G3+X.(6T$HIMJ`)TQIV4"<+'CPMXKB1S-E:,]W:3ZI/ZJ# -MTOW,%@'?Z@ULT@=AL/FPMC*LTXF)ER2IT9)(LG98@%6.&%G6PZRC20A+''6Z -MX0<\*!5]+B\S\'/SG`'2"Y+=X'?%<;"5B7R?GW-,P%>0#N_5];ZF;02%$!A"1$67.HV,"PN#8?I*)O3`2 -MK!#LA`3D!H?[8>23-VO@MS.CYBW1G4EL;64B2OV$]K].%?+EKMWF_J/W^"=& -M^WR8UI8R=AN[?1I\N.IQ3VWH9?N.Y49I:./&`F/QXE\P@_R5P"<[_)VF=U-] -MJ6`SIK4TW$T\@\6&KIM#(%*?!0SJ66+T,1:#Q6GY1/\6.5@'KA5M`/A.VTRK\(1C7[R+K*Z^YE$S+B_7F -M,HJ]ZYACM#3**&73;U$*]3*RL?OQ#[5H)(6Y.K'*:PO4C#8)=HK,0@Z`E@`S -M,;LI5F47KEMJ*-_,T]I3'(,0UOO,/H`7H=V%6>^HN&`T'3IM'?KKT44H,C,G -M[0Y:OZLO\-_0_UI:&$O;P99X.MTEX]%HW*`!:UZ4T/N=9&Y?@TD?.6%M6D.[ -M&6Z/B$)Q7-H+^,H%9+/;]!3(C?>KL3])G<89+7LJV'Y+[.@U[,9ID$/SK_:QG).P#-FLAF&\0X,%5\ -M3/:%_?&5Q*_O#8?EPZ,$R -M!!;W4@EN`.^;S:!QB4^47T>ULJK5`W!RVP7]:EQFK -MYMBLA!D16BI2;$PD\>@*?QPQ$`!/>\WEWIPT0FE.?U__`N,F`4S*\/,4\P:: -MN7DB^-;VS1XYTY*GT[[RCK4F!NI6@RX1]P>J7ID(%1^M#9\VRW+Q;":(^B7I -M7F*SUP&I(+&J71V#,/F0#U!Q234"4(VJTN>L;89,A<2D61W]DIWSVGSW![<# -M1(IZ(D/^%!<$:ER9MPWZ=K\:K!ANE=6`K_&OLA?@RH'GR2$,<0D%.VB*$6HK2"[/ -MOX.VVLLIOW\1,Y__4JQQ42O71\UZH\XV>X6^P/K\O33;W/#+F4#-4@L]P$D! -MW]P")>A$#!\8/O%.*/`CK4)*5`="=2JW"@SDIVN-]:Y'FP0?U$&>M++"#\`4 -M,Z7NSLNCW^)V5(X0JYK4>""*W3A+R'O\RKQ+<,NXQ.#-N*?MAM&0'XI-C/]_ -M'-&Z290]=J$I$LGJJ2Q.P?*@KZ@@8M14ME222$2.U`V*T6\=\_C(3'N+1.4' -MK>A_TE5PJ9UN#LH:'GABK&3QK^`HO';A]S>=1.7YYB&A0)G(3]`QGD/C6WDQ -M5K]D+#&.ZH+`&Z>9[Y8UZ!CYF.H(WA4:D,;*_M$C28<)`HJITK%*T'[$9S43 -M'L:$^?U1RO0W2!J)=]*W!LN)NT_)'W'P>ZUJP_&WT$2'.QZ<7?#E]Q.C#3:) -M!PSJM?K0Y]0$L>)^T1G^'0*D09'&C`M%NK>=`<4D8J(!V.*6$I)RA-W1H%,D -M@K'1T[@0T:.H]'0RU-5\X$T[UK`R_/Z#'Z.J:EVS:)+B$\@R]:A:IV"_'4`U -MSM^\<\N'2`VB36?+NL$G),'A,(^ -M]=N0Q\./$OHC<:Y.V\[F8P8J9@`_+J74%5'+%?H_XJH8_`M,4IC^(TZU?U(, -MD8>ZAESK>C*SA[%=JIE.=@X1J&-!?PVJ^Z!KJ%)'^:JW9;8H%2MB$%^$V+X? -M'6P(.TR.&9^[!2VV!U@$[(D//NU/NCV,)D'`ETV6N\;[=^$Y`@PO6#>E);>: -MQ(`B=2OM/73JQH"X_9STM^Q+@&+V&!4H+RSV0TB43$"&J&N;8G`+Z7YH_PK! -M\.X_"WEPU,Y;S*FM#W(R:06KWA'_2]&^[80Q2&@97H@6\2M8JX!ET:2I[_+) -M%^V-`K$-+E=T1D:@$XCB-"P+'2<;;,`%Z<2[6,"JPE%[0'G4-YC: -MU4=NDP;WW`#:IF?TNWXJ*-LNQT:&]02MN;FY\;LA)VDV0>&W$#.2*3[-B$7. -M,Z`GHN)ZJ@VU!T0:T<,SKSR7D^^/JZ`EA,Y5KG8#P]O%B"SO'5@'*A -M:_GPXA/:6^3/RI62]G'N.(;CJ5DZ#V2M]_0T!_CWM/U'V4,33YG##*31W89R -MG6%@_D\Y+H$AK3;G=8B*^GUO'!:+@`Q!I#S:]JC:JFGYZW'^=->&X,SHG@&J -MX$M;\11OQ)FL,M)'BTKW?R*!&/QU#0QKU[8JI_`#^@;ER\/R48]67BS7Y6O@ -MD8;;&I!UDS_JDXM(/9'WI-^ -MC*CIHVQ`KE"0N8I8`\((=9PQO%E*P0'>@U"#][?*+1:U&I?!`WRB#VR$J\** -MZER)GI6=&ZU')_U?BB3$0I'-?28WS-\XI@G>:`SXGVN"-Y>A*CMF!UPT'LI8 -MT5TM")Y%^U0RVCE],]2O+B`4IMP.`561T52P--3M"IL:+'5E_DKF'D#(U@*E -M"U](2:@`GR#-``[L7!W?`[JFV>T0P6[:>6RH]K,'PC"D#O5L[SC*21TI -MGF&R/CI4$_#-]_%SQF2.8\L1#%0?$FWQNNH8O4@/2?`Y0\8?;J*ZL0)1OVYL -M1#*V9+^CE%Z'7:83.*'&^5-[%%7U\-A6@UJSO^L00C)!:>/,/C)?F57AS>EV -MMO0ME-2@:O8+CMP.WV.LY4S-%T3IUB,2ZB'[ME2>B&]XAYS-TS`QZV84(`0Q -MBK5V5BFQ.CAB>X,@%*<56[7S&2O2W)<&A,A3)WS]-Y)-C'ZB&]E*[F0U)4\- -M18!(OU63_^O*SI]3N$%1O,%KG`1M4(6TU36=!69U,LH\]6I468]R4ZAX/QWJ -MCCG")/BSSXR7`X]1!3(_?C8;'AWE+XV:^@-[9E:2] -M@=O*LX8R9@J2_$7LASH\4Z#U7HNS"PN8[I%3CP%&!6[QKH9+UYG*..A3SA'M;)(AM<@%TI!"O% -M;S1UA<%H4LJ-/'(ZV@5^)7->$#H3!Q:5B3A=RN,X+=R5^WX^E7/8Q>#OHFJS -M8KG)=H)JDI[KJX2IM17L&-\A[RDYE8=/E!P?211F1/AH87!FBJ]A7ETO?*;[ -M%0FB>A7_6?;;#?;K_1W,\)3%(.R&(DV$)VD@'+3/A]DNGT:Z-!=P&\=.FH+K -MPAJ%,K"HE49F_L>KYAN?*ZDNT"5X@%.MA+!?OE0Q;L)4CRTL$!E/8E#_9HTK -M1&\[2`3':DL6R#WB_*2(/J7]Q3688]8OA&UR47,3E -M?@M<*@EQ`RH_%!#)9=D3?9X4>?:]_QA$_&TT/&HM'?4MX.SW(WP14QOWWW36 -M5]8;S&&2BJG\8"SZ#!6WL,"MK6D?L'ZJS$+`CG%6,88FYKI`NU/>BL<@1@M? -M.Z%W8K]`O@NLD%S&PTL%3P/0GNB\BDDEN;)5E?TL@A%,Z@R&'G",`=2T@GHK -MZ<'2UKD]']VSS\_G#-W18[;EES)LG`_^U`F$K!<4/'?*FOPZ@E_LQOKNW=V# -M^G(RTXR@W/6=P7Z!]PDRA17F\&DE& -M#'(]2`J"3I8O(9KRSM?66HOETP!154"_"GD#0KK6#M-M+(:M!)WQSHF`*U/X -M))?+6IS0?AH%9G?D7!:T79:LK<^KTQ^YSJ];;Y:_U=LSZ5_@#3#@(O'R5]\A -M:$K?4U:;:GU3R-LL?.8/`TF*X6\NZUR,FH9ZI<$;A9!X%_6EF1M+=&EC[_'6SI*P-8UJ?"*J9ME,6^B3,S$R&DNV=T -MW0]@A:ONO40BG-G:U_7M@?+O*"@"V.E$RE\0TJA*'E5E0CE=QV^M8!-X9"_; -M@4J;U--"8J9LI9>$I7"]@O0G%AEO,Z?8>T"-C\*4*B=N5#'G[@)FXL1TFB1< -M#T9[9:+^IRF&R6NM?$P4.4"OO_'O,=$9Z4V`5G2_<.V?"L92U0`F:QM:?7FP -M!^'%/'M.X9E3M/*N:BU"A^B.:NRQ_8\0.:AD-^!RAW+@&AB^:OA9WX]/[OQ] -MF&23]\Z'Y@&.0W??#OEYE91),-7H*%7+;[#I)5@#;;#\,&>3$\X#-VQ9GKV4@+9O0%1JE-2+9N -M(ZKE7JPIN3^3\4:J[D(HQ"COA;&MXE7*!]3+["5^IY-]X]TNZ*Y-]+O*\`,%$Q#LLTSA(*2!^RS*^I@#7M@ -MS>!4"1T$9+`G%HA[KM7:K6>AK47L2[7MPX2(30V=KNR3Z$,F4>B?;+6D&LBW -MF3P%$GL\0+.:I2F.X>=CTCF3"=CZ+J>@`7-;\`/4?&[YM.J'1M^OYODG'(&! -MCQF85J?5HVH$@],(HDL8L+1#N<$2*HT7)[LCIP@.VR[O('7'^SI0;%Z3B"8$ -MI@T"U%_0#LGTL2,^466X0TT)ZSWI7*2"YL/H/\=B,,O>^A?'[<*A9.X>.B0+=(#@V'(E?F*L=`O:H.&K% -M"4=(].#;'5A-ORQ>0`A.GM!"?Y%02P,$,P,!`&,`C+`.10````!J*@``K7(` -M``0`"P!.15=3`9D'``(`044#"``Y+PUL0H:'H6%+_WK5A(0@'S.R`@BTB^H! -ME=_0_2$!MWR*L_4FZSM/-"& -MN@)49@\G=4 -M2FS3?77_M/D86Q$@5KG7MM&CX-"Q!N@PY*-H&U&_8&B*-0GDYULR;06R/7F$ -M]_=T.\K-?"ZZM75UK`Z -M<5)"\%S:MJXW'Z5OHSVHZA"-1/$13RDD[[<1634#-]^V[U4EK^P(,SR?/#GZ -M"0C3T;$9UV5D9"UU"SY_]2S:5,^+U)Y1F[-`A?+&\D726&`4U';G"X=$X\3)A%U5+8"F3?,J9]>0#*I=9EP(8K-"=H9CB -M#V'/D.3NB0LGK%H-LJX-Z[^GG#ENG/@8K>1O -MXJN#XEX')D'P/O3Y9],EE4`GX_&F3O*'X$L=)96J5$;0EI=BQLEE8^;)"H5Q -M3&-425D$_<=ZS1Z#/]O6J6.G_>XB%<:=ES?\T[#Y!^>L*"N0IJ<;JK69ZLN-&R-0BLA(FQ/S#;7*77+&>.J@$4E6UB6_MK -M[L:")0`HD[G44%KV1)H8EC-DMV@J601;V#D#Q.X<)7HXBP]#%N!K62O&)>9' -M,)@P0X9G3T_@1U%UJ`&B2$@OJ;B<-?T5`)#1?[JRR$VEB0Y-WO\>;TZJ\.\$ -M[`*`JP#$NTX=_4R@0U,EOQ6RSMXV@\LH;9AEN:6:]&T+ -MR!2,#:-3:VCO6*=.P^W& -M1L-6I7Z<<=K%CUZ#5[$S,>/3Q.Y2&%?9!M -M(/#?:_*T<[R/.6=R>\P#?QH -MR+6['-"L/IQN4]HY7@[$&36B'"M:CQO]9?=D7T)!%;#&9<;4@!EQS7K7;RD_ -M'Y*+WD=H=TG=[([YNG\H,A5V)EQBI$\K -M>6:F)43@*D_[]2P8:`2B;S05`";T_1]^E('7-]##NU8C.WAV7ZE.UIF7OF=$ -M$-0`)_X^&!3-%T03BR60[\%\(.AE=6%\#6UWE*A_D*0]SY71$E0GHY?IQ@0-7TN/OR!65V -MOG=0H#1MXL'/Z.B@T>L9U@SQO*5[T488=I,ACIE;:VR:+F`9[+_Q("8"GECA -M3P$VH9I+%HZ>F4/G$^YK%&'(VDQZZ"]#^*^73EAIVJY@[.T7C-/\MM=0I=:] -M_44%^$TJ22E=$GM7 -M!B[6W+6-7"^LY>N^2`D2`%9&T6;NSL@J8=4P17.'V$4/M!IW`X4]5N_,U39N -MW>%E`N?3KR*Q>8FDW$AD*K8"(46_M@CY%A\W?8MFX;S%0W*1AM0B -M_^2J$?0=2?H;;7\Q&':7$36O?R4`"T,6$L+=(3J04_)P?TEHM1@FZ/+O/`BJ -M-2NK4-V,*/7)#6H/F\BSHP4J3X -MH$J3P]-K2'\J_&2\"7'!.1WIFT9-%S3>;X'4V*IN;'*8]F%?9@]HL!,.7]"/ -MF`KMAS!Q[?T&RP\/L32S8S+HA8>VS5*GG,PLK!VP.O:C$)LO:V#5.L7_CK*E -MM+\*OSIQA"92VM)-L]2*OB[M0`%/+F917*`0H#+TTLQQAWJNE4HL7WD[[49% -MB=Y\;73M%7SMY"\51%>R5CW$\%86^*LX36#,JVM.ARU$QHYE%\"8'K8@N7T> -M5&G'O&5%6)DALL_S8N1&#%+C\,>Z=-'YW(0(.U81.6O@*OQ.[.`N_=-]==4H -MU^08!IISTRV8I#=`F,H=*2XV8(+C@<"X\"7'"XGWM[54UV2TW_J3\LC`K -M^X5`^))X)EEB,)OT.-XEU6Q!A,&/[4CQD9_4<.?U94FE0?SNY/TN+O$/Z]-' -M*K3L39ORTOQ>8MO-YI=SGARE6R]N#O0>&?%`Y0>QDG`O -M8F4.$EI9I!-=Z-1Y)EL.V"4[31HPDC70MO`*W.[A(C@;J&GCUOS/2=TT+N^C -MP*OY;OO%+SL!5H2%H(XV<$83%DA_V\AU,':\UUF.8--PZL^`5<)\GFU5T#I* -MYD#;>BA8X?L';^W6^F1%"HL+$@DS)27W*OO*\W"D<,V84.).!!U;#[Z48V_P -M666#F(QDAXN+!*R39!5;G2T4=BP'>115^@F$F'B9Q\(G.^&5.+AK -M0V!@.Q)Y&ETUCD,Z@U^&6]`USDIK9BLTM!QB680IYI;\,7Y,06VW>#E,?%2I -M&L)FQ4(^L63W*;(^6LSZYCG#`54ZC.3KX$_'M;2":AC[J/O1U"!4,=%*P=GE -M%X`OH,_1\_.\O473"BO?`\[@H&";R>E1-5MFE@<^G]II5UF90=O!R&8C(>OR -MSO:2NF*4U12[9:Y-%A7F>)@#O[EOT0]#2BK'1X=E>'\9PFHD$_I_8=NGU:EW-)6,B -M2--'A\YJV0C"`!S.2'@K1D@8W8UD[<_ -M!4W81HB?)C`%,+AE5G_O\2G*%\DOHH331!F?9F/-"='O=S$\NWM)-6 -MW$OG[Q2&@9+#)TBXX'V]WG@C(G&6G'-O)H2NJ"_=P]E8C8 -M\A*7,,33MT;_?NI"I6!$S-?%R@PQ53''M'C2#&L,\32HV(X^U=R#NMX>J6>) -M?Z%U8?)?I0_Q*)^:N[7O?)+_C@X-/6,29+!ZV',6W/"J_L+B[WVDD[5-(U06I2 -MIMB1QS6`TLP&#D27:[^82+M/OSFA%P(,@W'1TR\G;^=>"DA1_AHS'.3 -M2TI:"G"*8G5&NC8NVS+8Y]\]X:D9VMRJN\G -M`62:>RH0"`2Y9ZDN,U+COF$R6G#']IG9#F+3:-WW@-ZWZQ,Q!OH9O#<7F)][ -MLA5S/!E%]W#7S/E?.<1L+M3D(?8GN6OY-*Z6`+AS`^,KLY'QA993\K7H_)@- -MF@!R`\[KZ<633M@ED+MK[QM14VS'JW@>`:76-4N[QMFH#CK)<\V%$^,%VA&[ -M*4H%B]5,HUMQ`/1WRL`1I#"V:$D"X -MQ+:"DRU./.]T8+B#0*$:W=$X'2MZT3<-(QAO94(G$-&\M+6!J\3AUZT!B`GK -MN=KM-M$9KHDG,&RV0Q=`A71K;')^SX?1;PQ,(CY2MH=RQ(0I0K*^/$3F!XJ( -M^IH7`\5F7C,"9S\35IRO!CF9'=UQ_,0N"],=4+5;S/?^*$]+YS*8*9Q$+H]V -M]KRM`C05I:)/_36Y]J$69?>;N!B`$LWIC!$K),9>>#+.:!.2IL!7AE+7<.GQ -MH3(8%E9X\+DQQA\MG'`9I$6@G7==:W80H$@E0E-`NZ`E\X*`EK?(LU[&$\L> -M6\;K%&X43K6""\(2W.P%(056>NT^#]A157Q@J)YCS6.E^377$*48K>_/9$^& -M^QW@:`&3Z\!WHZS@;01:P^_&QK&L'=(\\F-@3LK7,K.9[4D,/(!Z` -M([LV+`+5GZZA!&:^`&L46!XD(N!N@)0FT9:"7"J1)#KL -MVL]:V`6H0YP5M;[3J=]J,W3`A?];HGFY=H/NBV?1;.%!6P_BX@E(',K@#@`M:9&)&$J*,KO$>#1DJJG9\WD -MP.L_GV-6?(W8_VX#'(,G;$_`/D8Y:XSVIXKK'K;&]]H#^C=&>B\S\F\Z\C,% -MOIAA+7YUJA!@K%OL0+D+FV/FPL+<'952F'+!?P__FJ2Z4*ZPAS(I&>"6[R3& -M/':PPTQRT.B2^YO,FA--2`M=DW`DPD[VCXC#M1TE4N<#>FP=,\DD?--'IYT1 -M8HR<$C.VJK6=LJK<7'N7R$I!FFW.JJFX$ZR0LU@NR?LDWNFB]KJ%X9%%"6,] -M-.T=7)Z-\4A<(;C46`^^RC6B\]0BPW;]*PK"8^[^($,XC0.-!EO!"1AX67&* -MQLZ,X450TZAVSB&E=ZO3OLVC%LZ-H"B+B-6$/OQ0$.K%+Y\,2_`VPFQ+YLA$N\IE)A_3*T/6_"5?^)-*6E:RR?!(?@!`W1<:)NXH,1AG -MZU?/>BVK?F4K73L]2#*S=ED3AXYZ[I<4*!&[?L@X+>DU\_"?I<#GEBMLTN]# -M3;]%.= -ME#?_U%18/*CHR5D\W&L'"6,YLJ`LEQ4=`9SS0S:C'0T -MT42)W*UD),*RIQF9I-"D%'V6FL%__?W`T>Q76J5R\7%G([WA4%RC_?3KR9)G -MW.C+Z(;)*D>`I-'6M!T*$9D@O&:>9IA.3IIPS89'FP/'BPSA1IO/E:_:%/2- -MVRU\+0:^OJ"3K4=$5K)#?EZ`PHK&_-`0`1W!!=H11GC]YP=,TL%]AJKL%7^3 -MQ+Z58FU;Y,*P-%-=-W@^!]%E:/M<@7349@P%^1S`4$ZF)3ERYD!$-!>"$,JDF'9<8IG9@_.K/Q6(NT -M%E?;R&O4*2R_*++]#G,&O3-"WO:.'5Z'NXRTU-:%I[O%(*-E&'>X#>B/5!4D\"!`,:>S$\O16PIU`>]D#X$ -MN25EV%0CDG0@7MK1`!2A1\AJ'7)&M'UFE`$AXHIJ5\EPVH19-RW^-JRAO._&IQA]:Z&F@J.L'2KU02*"I9L+WB0I%AX7X-I5Y3N1N,S05_^PG+ASS:&=KT:*OE%T'_;UHJR( -ME`3:8HV> -M+[W:F>RS(3D/)#8:1J4-]/M63)LWJ)>8.= -M%&!&XN'DF^7"G9D.6/V^Z1.(P33917AVCY%WZ!;QO`B`_U=SDF7.,"->AN04 -M#0K"1^#WB`ALYQ+0R*I`3F/OSMYO*;KUGL#GH);C.8_[T(T=2*%"G,[ZE]5D -M0(3N_+2G`I?_TG@BJFPVYTF;AFJ_"!GEDX'QTA#$E-;,K:3[K)VPNJ^4!'$' -M]E$81+('&O)&56T:'*A[[XHC-R:[<8`8"KK#ZW-K+WD)@NN]\2(J8-9G0MC. -M[UL-6)WSF`&F],<>@^@P*/4S9"Z9#OV`G\)#9;#QUAW(IBE-3@S';KJ[8Q>- -M4X<#L1PBC1LY;*V-(#.5[#)]FXK_!`'$1`95L_S$U]SG7[[P/3U$K7BD$0NAU&3_P_!#[`13]:&Z'R#O/CWF1([[Z+C!P77R7]F'< -M$$9ZU&`I&W96&PJ:Z"D(`C^6X.>AD0T^0*KFUEB8TBJ;PS_&C9#9'D0`L0Q! -M6[])RH>I3DEQ/>.;L9DGL!/D' -M?2PEN/>%9FUT@4HRM^L5'U!:K7H++MT62NAEB>WS]V1;XP<0E7`B%RL5J[8# -M!'7`D/Y$0/=Q:%#)"HQE'Z3MG7`T:23=M9N'8M2O)[#E#0FUY$KOC^T;3'_C -MU,.JD1F(-G+%VN:"ACDR5V=JG20NH94ENTJQ`Z:E3/];WS" -M.4"#?NCXKSXTWQB;Z(JH"Z1M+ADD#N73"B^C`WT!`Y0$#STS=8>_0#Q*W*2Q -M-L5N5H<%?_=HYOWK)_A@X-,I5-G9UXZM/M( -M0-F!S>:0"!G\1J$+-F0=QQ1;W3=A*`SG-$&>+]4R]W5G#R?O"H_OCI,HOS/] -MXO#EF@VSY[)W3>S@FPB)G)]&1Z/Z7:P+6RHVEQWQS52Q7!49;D6LRC.]#:/K -M&[6XX"AU+WW$&_N=/59F5+N],9:*4VFO1244:SHQ]F*7YCP!\@:56P4\#<=^=S -M`ASB]7,J;.,TXKCQJB>'&R8]&B\<+-KN\V,$9+"478<=PL2$(SX$]""O.>-? -MQ#:?%#-O=('FU*^AD\12E@(-QF?KSQFH)7W4A6BU9"J8812T;2Q<5(=`K)HJ -M6.8;3^&PB+Y+BGR,Q3<#:2\S5A;:JZ:F2=+TKLU4"#\=V,ATY<+ -MVL>UHU>76..;Z.%B-3)4?193#L8`K;OQQL"<"H6E)6R4@A=#UL0]"#ES8N+E -M:/`GATG]N11P8[_OD$`3#M7B`PCF:C]6]\K$*661#ZIU;Z@C2Z5S9:L2050.MR4C-3.X`T%NSY"$OH/+-&[BY96R_^K8TR[^<< -M<<2=KZN>N36,KAT*Q3!!5D%2&!5+KQW"` -MNDO@)6G2'PC"&F2X]`^P0RP@;1@\#OS!BGYI7+DTH/=LYH"\/(C5CRT3@U5I -MRU+B`=TM[S^C?>;A<+;=6T10;1R=0VB@?U.Z@IN3)-B%7,AAM'7Q$[M@FCDD -M;N6Q.Y4F!N3>";*LG!(95+^X"Y.-HA'1;Y0TKJ!'P&ZP:MW7MGYH6*3M3\KI -MC^20^)_P^JA-]CY_\+*SD"_:F/Y6P>`J46'LM[;7A?2"%=R=W=3EIJSY.`V` -M=-+*1[C7"\`GS5]5"I962M:$%$2!;+/_8O!&5.I?N[ -M\)M_(9Y$MT/<_!*+%5<*5UGH1$1-""F,Y+`]&?@0`39@&B4D%.D_US2I^;]_U)TT9ZI(2/&4A4 -MY1'!KV`00V>6*R<=JBS(NDODP<%^/'.U9#J!1/`8#"E!X]&B -M%C`*7*7,'4>U8B+*!N*`:3();\V1E9799I5ER"J:B=E]F"8C[57;!S';BZ^E -M4=`08I-7O#KA30H=2L>R<\I.]Y_;1+=,2U1-3Y8%6J;N@5FH6_(KWX.X)!C<2R(5K%Z].54V+! -MU0]J8>8HFH8^8/8QX'A&#`;4%%N[/KSUYD%G1L>Q?>>4"!Y-GK!7@B8#?7C/W@S5&0RZ4*I].M'/[_5PQGU?'6_O^9^'%J4V]R\- -M)MK38G<\,6X_8NR2'6G3N/Z2*YP#?LWA;6.AX1#^UT:!X$""VB6MV@;$&XVX -M^^3[](CI7**_8/=8*4[Y#<@G>G5\T0$PQO4V$S8_R%G -M0J_]O)QB9N5L^)[C,'H-)7*G5VWX1F@3`A,R;IEQ]&D_&$6^%5 -M4&VW!=2SH.B'9`0$O)$ -MC;PUZ]C!>]HK7BYZ@TZOG6Y>^&]8<&_E1-8GM;I^B1;==CDR:T.[<.NH`@N> -MT1C*_6IR5R"6&RN-FL_=5[5+^)ZCOGH@Q-GNWW55E35C9_;0[C;I=HK*%1^> -MX%=0DN&')JNJV#OR=:>QE46^:.KMRN_SI4"\H+'(V2@".0IG8/Y7N=@^2C!H -M1N\#6;/C/.SQYJH"^?&A)RW_R#V[Z9*5*:-#8B;[T$Z0G1Q>D:LY?@X*V%!# -M6WY4)D0\MF)POEDFZ_&5M?L]Y\@GG&2*=933"0J%,6@:L$)ETC"&Z+0Y4E*0 -M%L*BR[^:`;03[%*4-TDQYA`HY(R0;OI/A)R53V8//_R[]/[$3YR,2)RV@-09 -MD^9CVU+,^T]\5502O7^Q2;9]^4;JSE^!RR^(D\XHE&Y4)L.1E6("I\F\.Y.2L>#9Z#^?9CZ`=HB!O<`-?9U)!2%CM@ -M>&<:ICZ#,7>8HY[5U,A1P12'Z!=:=):,N([N_42.HQ.TN4Q(VYCJ??_0..-` -MV'11;>,!^GQB_F)$H10;E='^/=9R]X3=>)&IH(@I\P#S,15#:W=';XR*[)"_ -MS2Y3?KZ;"UFPJP*5EQB^#NXM)8[%3^+8'*E8[&$V!)8)B]S_(QZ>RP9XE!`R -M0`IXG?IC/^O=EC+.ZB/"@IK6/B+.L0E1F^#MA@?U>E-)X"4_]%X-:2)6.KM'EA,;MW0R!?++)>-1_LTT+`"ME1##1%@C*`WV;YC^+[#V*/; -MA)9/^2:%8+`PY!HS<"Z<>(@1QZJ]K"W80F0@:PCD[2]]H//NM6">NMPXT?\! -M0\+=`:Y"AG>*M>?:&[X[O\&8^IQ;[A.9PS0DN0'6%4J5>4%Y/,Z+:9%`S% -M^N)%JX6HSY)RV\&]4#$880*"TJH',C;&/QP5%XQ,\-29WD15C'S?;,5Q1I`9 -M0-;^M]&LJ;7.X)D.A./A%WAIC]$Z%5$N4&=UF'*M+I#+DC&K^CN9;F_-=%T<3<438;8 -M^&M&@>%#"R)6$^E&VSHU[87(83NL"%I7FLCQEV5ONZSE -M],>I4@?85G!V7R+K@ZLA7-69S88REA=LS\#.D!LJ,&WL0.2A>K[!*OW03Z&_ -M2T2KHY#%,A96;@U3B8.#7;<`Q2CT.FES!=0@NU`'5&;C# -M.NM*Q)-5DPC:6`5A+CU5%.8L(45)EBT,JXAIR90^0+LJ,Q'%S46<$"(9GAEX -MFZTFU]1A=HV!B(^A^`$G90V;QO"DK?YJPJC=%TTYMGT' -M^A]X''%])$/9X=)07M--103,8ND@)R]IB_5_?]!2"_6U^!I`3_76&)^U,UG& -M2G1B;5X>*3RO(X@:[H48D\:"])HS6;2CY>>3`AS00V<*O"5]J4R!W_/A5//= -MYN1=*ECU#]]H"X:6FWA]%K48#3$CBF@N[6V^U9Y"5F,3G\$_NF@.+$[S$$LC -M9#`]4XY0^HH(^-&\JL53[EN0T5^SJW/F,[;?R%CV=TU^)RN;@PP)J*''JO=^ -M&+\5[\"\7NTB`.`%DQN11GLHD)@ -M6'467J?ZB6D[:X;#0BT'\-Z"U3%Z**C%X()\X@_C6WS;*O.G7^OCIM_J1L#; -M:30GLHO?AC.'&&%G.7'L'P(HNKOF=N1&,'CHM5(\<]K"#RV=)#HN=D6F.7Q\ -MJT:AR@T(62ESL';63^E$EV747`+:[H'7$5THB^G2W\(@QSB$O7S4F"N>>^7N -M(4QMT$2UNKY>+@M(J/BXMA1QHY'HUM0RR3<4,/DH1C*UKL#.`E2`0T>=N34?)E!;2=T^!`\00AL -M*CUU1L([CP.PL7OPMQ+_.N+A2@A#LZN*R>0BR']Z=/WH'[U_]EY#"9SXH3-` -MTM4%9+UB5^JS$H9GFTTVH;:JA1_]#$D)UB2OE-)B2K.F1XJ0`EN.C!#X,YNO/@>?_9.\=#;HB4$3$ -M.IJY2=X[NN\'X95@'PFF8L91NP/8W`+#W:RLU[O<3U60#5D(.D8'_7C\YL1Z -M%XZ$KU-?WI?5%S,_T*-U(IFV2Z%J4^J2BX$%#FE0I`*>&5QFD5*/]A7-GUN> -M?."&,NYW4DO>>('];->E\%2$-Q%83*)N`HG*AB6=]?4NN;R\\Z0/\C<)E=>L -M!0[B32?S/UXC4`1%F8*ZS;']O[_+/]06;K/G.-OHC@T\$ZKNC$M46@!82AQ' -M840N7P:.WU1M\WGS'B`&X;[U]Y1U#@(F#M0??!.H6R:W$IQPK_REXE=E^D4] -MF-T0>7&S/PY0DS9*U^QSM5""BFNM+SD2XE`IS05?TLA@*3]!;W44LBEWHXJE -MUDZ)F?[#V\AL%?+V8',..&"!A:!Y%AH'9W1H6#N(AR)[A;[L:.T9@BU[G1/O -M;EHB -M:<[:_0LPENIQ)44TWYRMU98)K:KKXY4LX -M4UR](55WFOZFV^JT-&J&$3=6Q'49U(F1*Z>P`7?@^%3QH]$0>\?GFN>"I -MC!JQE[KW"#D"0K[M-V^%`VD)B^6SJPPB2QN)^'T$-Q"X8BJY=>R8W+K=YC_# -M!T7IQF1])M@U=Z6#@.IW6]S`J;M=(<$H4%A#&JM69:$<)&LU(;4G_IQ[Q*$M -MUFFAJP$";WW8><0&-_+JY0N2.FJ/VM/_9`S/@3/P+LD;V_TS_Y+`>@DS)P:1 -M?J-B"![HB_H'3G.KS?HV^RSN/F5OD5N:1'GM6C#>3%"+?VX8!GRRQ0(NQ?2T -MG+#5%`XK23E:&:5:-`:R7YM//'\SK1NQ_)7`)?KC3?L_$L_O80H6<06?5)Z- -M%$@9>"50@T6/%IW[QYTN93*J6L/W06C5!HY_-![TLGZ2>X6!T/\U*KZ=FQ$7 -M(L;>%KW1G6?"T+$.N((>F>79#5C[,;8]HK%;-\/P;\:J+,3N>S$O.0'A4>3L -MUAQ8\USS87%NZ\1,&M)HLZR -M,*(/YH)E/J\VXJLW\)G6J@1#YD- -MH7VSJ8Y=5(9!H.-!,Z&ZOV^FV1P#QV;NP(16=MNT>K=W#[T$IOQ\,H(/F58. -M6,4RG3O<! -M.0<)!N(-Z1T'(TDUC_JZ#.IGN!5$-74RMOR1*-]"* -M"Z^<6^T]1.SE?9:E*N_2Q9,SGMNC"A=L#42VG0W5N$0F$U/E([$"^3%YC,9+ -MI;0DA3^J][T4`/?2_KE-"=\HA%@P_3EQQUAU4Q&`JFNL6&\DXUF>X&5M3<\5 -M.-HW>X?I'61]T3S40I:Y3H_.%;6H"@ZWJ+"+KJ>(QBZ6_AH,C]0OJ465ZSIKL+3B)];$]0&Y -M!;HUD"PO9BAP;!4`UB+&<=E8V&$K/-6&U30D@FS#291YZ:@MW`U>0N?Q&P4' -ML\--&.U5@KM`&"&VEGK%9)0Y9/`6*J%I5IKP09%KZIV=T#6;^?S$ISI%Z575 -M&(N'OQ^16HI[T!B6G-@T3BY3!`]Z3"K-#2(*B)"CC+Q"N;%2^C9?DOC@<5FF -MZQ$E-@_$;WAE1SL[`)K/E80Q_PT2#9*+]8I(B0IK+2/4:_N(%AVL=7*"V:)# -M]SOHW>[QSTC/W?)["XM%/3?OD(H -M&T$4\ZD)Q`S%?Y=?V3BF*^"Z.^$$[Y?0<.K8SW5-"X>4SS]U>?/P)V[,#7^M -M?/P56NC;])5.7P5;;!."O,"B+RTAH5S_X:O2VBB)FUDE[+]^"RO[(K2+K_7S -M>S?.X2Q7*#=IZW$_08(Y^RS^4, -MO<4%NWXSOPZ!92^H.2,5DVT"`3[^11BM.3UH5#QW&IU3AIK[;U=+GVO^ -MFPU.\$DD8XHH.[;#E8OHMKFX4!FD#`IS&0Y:?&5JLNRISI"`"BN7V7M?1ZG*,AB04VF9D5O;:JYJR7!:D04`833-N+K\0(JUAH+_MNNPKN)/'RBFT"^#97 -MFT+-J;'1"7-&D^))H,\CD#3!V:#06%-)?33@\TPY/J%TRI6XHP,!^Z2VU?.^ -M/E738'J.`+$%D-Z"`-ECE4SL#QZA.+6LYBNM98!D%70M?Y"I.A2M6Z"]N]KUI_&/""S9,:!T>!Q -MI#K91V>#'&8>S9P(0Q-J399?:9`'SX"WA+=M$4+0,:J)B4$SW8:8&Z.3S/L, -MDF'.5A`%S@C*17:L*"8NQC5^;*/*_A((5$;HPL]``]ADUEPN^A1S=)K=0"PA -MW*TCA"5PA.A:F2R3L8.37"Q=H(+P/&R=%>L+%FV'+J('>[MW5`$D$)X++2X# -MMKJCN&.=E_^RFRK64?X>[5#'.1BZSR6EQ0_-;*1]U1V&DH0AEP)?3E -M]5+DS=V:M+)QN$262-QJ_BQ)W)#3@5UE4T.81/O`W'8>7#>JU5P1=,];]H1_ -MN)(=G>UA])BQ2TZ\0ZI`+0 -ML#HQ:9:'1Q7$K4GMEB/+@!+PWOA_$ELG47=?CC[8#QM3[9G@LNH9T3I^>=N% -M8+V32"*G=!)HEGQ.L^&\"E<)]@^_]Z!.B6G9F<'B#,CO>9,^.)+`S^M51>59 -M)U)1BHZJ7IXRK7O2!WRSRX&1BXZ@>"^H;%VK1-7IT[B&C;,\;EARAQ-H_%4H -ML3XJ"BV5:N.01R)NB(BXXKQW!B4PXZT9/&7S&A$WC351'0@Q]8F5WD[!<,/" -MF'9%Z.MNY7'K%\QO.F5*T":>ZRL>RM\@!X>J[C`%##8=OV#QSWBH(WF,B].4 -MT0:TE^@,;^,\039<`ZA5B>:3`,PE"8>U"]7M@RQWY7:ZY-.V`,BAIS;FM3W? -M/OIP0/Y;TJ"GA"X3I2LH.@F?`VU$V)XXV";+$B(C03R!DWGQ]=A@C=3SOG7@ -M)_TYK:KFQ^+XI@L7GZ8L.9":5)'R%TR^[>&)_E^MGU@T@`1SP5(90-8V-7;- -MBJ9X8\RSDQSSCJ39J-7\F4 -MX31'%$E"\I1XJ7:<%)@8WK=AAWPVIK)8S!P8_B838*RI_;&!+G*A;F)1",R5 -MW=0W/5MJ[5-@HRH\NL."]?1\5#5+XT,1A$3=8]`">[\FXPC$:Q[(.Y;#,E$[ -M@/XU;."!XO%JXLAUP;4M`@OS6!4Z?,T6Q];8VCUMR7Y)MVI%(>Z+L\)!"1O* -M)H24V"Q((Y\4LBK`9CF!.=7>Z^WCS:EQC)JR[!6%1`Q+47F"&P3A$`9:I`WT -M=.U8^6VITR<[P:5ITU3R1[#^1E4H2EF8$B=K"Z##-_-4J!QV&Q63]0DDB?"^ -M\9&*3T?&J@N;2Q`F^99HP,E)*R,@)](7D'BM*FR-?2-[\O_)'PD -M47,2/@!I$L,V5J,'XCT/3T<\MYE/KR;0)/#3CLD!,S')RG-Y2-[5FH6)L=\! -M8NK.$7]NI#DC0"S\6YC@&\9)N?\W>.E*@$@6TT-C5/!V#**.!EXQSKSC4RNC -M\-K>_/^?]2V0ES9B%K;_V3D_XAVO4/Y00.RP2Y900N])1$!D]^36 -M2F+6I^&=%_Z#FHV[_C.KKQ<@=4Y',-A1S]\E;$#62)O#C;*2(CN.XP,O/YJ,2\_./9X@]\UX<(^D>*F0+ -ML21Q;W-,#@Z*8=G-FUHY_I[+[H^P)ISYC92RFP4`H.\G3.O*\F@*\ZJX%2VE -MI*;<*@FGTWX%)X6T4XSE7G90[KLJ1]K!X0!CK_(0DU]>@[FW`'RVBKK,C:B4 -M'L+6"SQ:;#0SF`@TR3H^U-#3>,33_2Y335TDPG@A!S4#P -M8*;;\MV8>7P,.3B`.O\<=]J./E'0.WE_VX7779>880"@4YNK&X;'-RX$?]1A -MV1#=BK0<*>EZ$%32>K0'&F3VD38"QS:F!-U8]@OW'_F:PC'R5-RGXH`^#!IZ -M;?<&%DQH3(VKK6=:;;`E0RT9R\"IJ>"1BRTE`"JK>_%?[6NVPO4SM9DF,!>. -M=V',SK\>I2*H_RP8S?T$J)A6X-KQ6.%5_@D<@,)+Q0LE2M)"3VNN@71,OQM/ -M/-J.L;RLK8IR&"8-P&U9HV0PP3!)BS6A-3K^>TFBM-V?2]>8EI"0\&C!Y?_! -MTH@%K6:.M<>8BT&#[Z0Y*3KP0S7N-N!^J4D0_:U+9'04C_*@W[$7?=>5ZG=R -MXM/1%<4!^9?'"/*MMZPGV]IQ2F"EAP.ZXM&!JXMN;RRN.\7,FLQ:^`!2ZGJ2 -M0DX9"T2<%JDIST3'@@N'"45SHFW:F!Z<(3<067ZVO)@NG?'^D[Q%@3;5\_#! -M00!S'%4TL#^(SR'JA@[\Z0!2?Q- -M/6V+V#"U['H"TTL+02RTYKOXPE:`2I`%UT([+WMCD76`?`D[^M'Y-6+.8:T` -MLI8^`V&K;+.A?+IU!EG4+`:8(U,)%SNK6\X4_/VII06/<(&%_Z'+15DWP!6) -M$"C@.T4M#//>@DY8OZF^JA8WG^\;;\8/8RK0$/+5=C>9F!>#I=2!0X\8@W!DD!4FH0 -MPNKTJ;I(IT[_7I2#WAF#!8]O>9NHU8EK]5IIB;/-8@8'+IF\/S;SDM)*SPMS -M?K\5ATC+3(0H$*"'`;R7DO):*>]18LBX -MNA-M,*G6^WM8MY\6ZH^N%*QMW%P*^O_6&4"'K@"CW&E%H7CQ -M='Y2+!5F=BQVDM!TQF.;T00"/XI6U2@)QSR`"A+DX8@L^S#';MX5@2.5`9!0 -MT/.5C -M?)OF[/#D_Q^*(AQ.VSP\B*;IM2/E:R#"\L2%A/F2TK^J'QQ:<:3!?#3\N^^) -M#=,Z@C!I")JYA3#9HD[A(""X04M@EW%&PM`@T#"64JWQR!7\84GT/XF8Y^86 -M-*VCG>]8E^2C$=PR%VFTZ63;=\^M>Y*#R*[J5\Q'Y$^'/A9!SG.S<)E(=AQ= -MFT;O07NH54:9($,$%A*H/_2',1 -M9*V=(TR^E>+;X^L5"0'FNRE@E5[-E:*AM>D/99QWYDH -M*=+ZPZPGR-,KAH9P>R2JK!&K[3%P7ITZ?>CB-37"Y/!*%Z:/;QF/D`\^9(T= -M+U3])PBEWXX?(T%@/8Y)L;UB)P8?1^(Q(Q'RXE\U#(CF% -M,SP"%'L!AMAUP,7MVD$OOZ?MQ>#WC[X%DL1IOJM?JORSJ]-W"I.>"QW1600` -MP@$L4W"1RU<]VQP\A(R,O1>"UDN@<\A3%THBEUY'1FO/$N1#*`T,JLY,JA(] -MOA10OT&S#(IM7=G>2@5^U:]RKO7K35.N/+[&<^J''(DBZGS_^6R>J8N[L-\P -M=^GZ?__5[U_`O(JAT>DFNXB?F&,AK[V>)55H@8$551O#LM)?&A*(DSVF33[V&8X)T-V"M -M5V39OP:H[-I(-UF!7BP+<++5@C7RB0.5]Y9/]#56G^\`1B;H4RA=!^#[E#SL -M#(``NBVPI\6TO[]K_9B(]2F(_DW:X_4(.:64KJH34>Y].VOU"CMOH(K\Z\UX -MUC.2P,4$(,'O4PQ:#*(DC,OCR\8OD?_DQ_ZS-7DM_7O";7!.F.=(5)@O9.H_ -MBF=%=E+;VN%COM1A4\_P-5=0^=FNG6'Z?1XR^2S(!7!$JF@<3\RB)%$0,9HD -M9V,RXG%`H[7@C]BZ;S45GD('?#6>%3E,@C6#,#KM<4[VWU=ALO -MCN/WRG*&0F5&^`"^*@<0==U.[I7D?'6$*W451MR/`C%DMY`GZ4$IN?*$$)]ME"/SX+_XA\/FL+#/F@( -M[K*#3E9Y'[P%*H5Y0,'1>\(>$%7-6U+"ZMS$>P12LI:FN2.E2-EC_ZV':.0L -MW"/!8"ARTH;ZTET9&VL(@AQ:5%" -MV0@XB&\$?&8U?[3/NF8_"X%],H2AS_2S`D2`)=#A:57W\2_HED*1>NAXU(ZI -M-9AVD,,3&,_\/`;.46KURN&U07$%U9NQEUP)/=]YPGB_JN]5/RN'H_@2"N?N -M(PH?I`7229)\R_C)9[CR9(0H,"GN-+$[1?*"L5D%\/$7:NG/."M8/;BC^"^' -M4#'!V(7W`PFQV01OO'P52,22F -M7*?L,FN'9C_KPW#"`6XH?^\#XAA^;=EO#Z+[AI_;%TSLY3JGD&OB*-A:97-+7S>5*+Q>6A8PZ]?-](W$<$DOMQ60H;F29 -M(<4D+0BFL)I;9(RO6[UF`.N,;Q%[2/GZ1L*33N_A7&=."_)SGNE?2!J="TYG -M_]B9L5M=/<&P!98)$0.=IW_ARB,"G@;=_V''M3FM'@XJ.](=QKM+`_Q)`L#L -MN6V@+M#]Q\8DG3=8YG+>0!IK'$C% -MKC5"6T+)BA#Z+E^%`A3_QL>G&B)'A,@Q*FKV&WQS1&@J.97H&;< -MKIM%RD*D1@;YMP?2A$T9>ES6&\-U&H+E!%H\LUBXZ[LGOAJ4/N]IP1.^!_04 -MQ4+ZSZOBQ_5H"'E=M(3>I=X066TWF=B"DB,AT]R4U?4_"J_?DG^HM5XY:ERX -M``HJ@D"G^S_/2REEO]S>,VP1$W2S_88B+^ZF$0Z"`0LEU19$.0^]O;7JAM'5 -M('*2@:`&1";PY'+(F!UL(EKK,XZWN.FY*CC@+R;H)U^T<`#!>7C*O(O', -M8E.K5L6:X.S?!JNVB3I*>&W"&96(+,O_O-$5Q@^N`),\.HJMG9,`U4:+-1O' -MF.:']F`X$)#=H[/$&P>*N8$$0?`/[Q[/C6VXBVL/U=$^BYIO+X24?)\7"CV/ -M'JV"D,[1207PN*%I/!R'T)&<>*,7ZJ?8,>O,B-R?G-O]C135"A*Q`-85P'8# -M<5,)X:<$/#&V3*W`Y1SMPDRH\N/##R+#WJ#DUOAD&]6E9[#^,O0#V':#!T)= -MW=^(GMY8/]*+J56I,0A?$7ZLQ8QFUMQ09?/.JWE;SA!A?'^-W6,,\U$'7'YV -MI(PA=.TQM9(WFM)2&AF1)O=/4;B6QRS\;14VNEJ#9TX?S,:2W0="CN\CZ)?E -M86T^<3@5:'AGS5'P4_U12QWJ'SV%T$,P6MX1-;?0@5S,&ZXE:'M-=E@%L4$4 -MP2SGS>5=.61\5JI=#MY&VMTK9SR!.KQ%6\%8KBI2CJ=Y8#CA*HVQ^MYRAX%F -MJ#;JZABX'ME_7&V"?:U;LH-[R%$!WQX>V(R:[5P;N3YE=4T"LQ'$/7]"WO0R -M68I,#USF\9''8\ZUHS*F\)D":Z^U)GT%V>49"4AC;5U5Z3J2K+6,3."$G:RG -MN"^!XUMY9JKN-4$=RST8JZWYOI-97)&("7/-&B;3#(8;F&615JX,OPJ]JUOQ -MY]X9A3<_I0):T$;D[XU59]?+5E1&'^+4`:BD[+K$O=8XI40*VJP1P1#^:O;H -MET[YP-+^LX]AU]MA4/V1SLR!TBK`W`(S\"TT1Z)6:)T?O&U,`98$AF.!HYC! -M&^09LQA&!>'>X%SA&:HM0TYLKGS&E]DV&0KE#,.42!E-5V!F$O!J$G;U,B5R -M-$:.8GVUO0T"0'F"'%(#3.X%ZX\\WNXJG9#AQ-O-@<#XS"Y[F';6%J9*C;5E -M!9Z'R$?LOX(T_4S__0$9C\Y92.J3).DPE>07.FDD>;_T/A<)%'#<+Q9H+BNG -M($BQ!WRMW>N^_B1)7'_3(^48-K5%]/9I!;2G\$+?7.#V2]'T0A7#;_Z0E>!6*LB -MBIE`;8[3G6A_+@@>?>@D%AU#MSN3HZ.*J5CQIYVB=8%/?2YS8(=].(_#Z-M,ZY= -MM<9[AG<=)()#@719BYHH)2)>] -M[Q[H9Z.@-I,B/N(7;]TVJ4IGTL,/#0W, -MU=BBMHDFK$C!&WIHQM$SQ]Y-1.D\$=*=&"G8+M.AN)H&I#IS>+?%:%AZ1)?- -M\GX-4_<]`'']:HQ4'U[M%&_GK46`#:NJ^5'0$]%1FCK]K_\66E!=$-_,0H>* -M.:5_,.S24**\FSQ@7MK,W[!;4$RAG;I(Y/D`RF@>2"X3$VP$E5N@SIZRHURI -M.U>$8D"/?D=>G-K]FDO._#O#%U9\.7?RX/3;WPE2=OU3F9!R"5[/B08UM)PC -M*]2N/L5`@[-8\143^L5:+1Q -MR,52'ULAEWY^Z5528*HO^\M*%U$*E]G3M8@LAQW73M-P_8>8;M]R^]97OJ3GL-;TA& -MHO]*;K'#:7LO6[[:">^7U7U4BB#"2HM^>V2&CW0>UIP5+?ZO`]D1+JR+56LE6Q"-6K)PVT/@P()BC:_P_J]K7F!&/%*C606ZU/U,!`;)N^;]9:J:OGM570$EE4\#6&:3^T]7S!U: -M^[E4%+T-W:AN(JDQVCI<.DE&!E;$$.?T,!N*ED51=(_RW950<&\X.VM8[*&W -M_;&ZJEBEK'TRN#VUO%;)H#(N/D_;N`>D+E[WI99'UC-RO5?XL$55]8?D0H&$ -M*8.F":L&T#9;UME%2E7V>97_@%^[BV8&635*^LH56LAZF)_ -MX2X['`.;M.'2/[YA$RX5$[FQ;0/NE[$<_.JY_-/=F'A:I`Y?[J,FI(HM9AO+ -ME:U?A/N5<'=S=]F6PMLKH!J\;!:0\7Y/^A+=0Y#KE&T1$6`FH*@'<,WE/1&( -MJK_"D.C>^']CM+<3)!!8!+\?G-IXLQ!R?(D[E@&O1CJ(1+7%W-0=U-A0(/T% -M_TM[/]FC,S.)+$"V]95*B!HZ4A,E5*N-#F=*^.,BB*08OL?G`DJ]SC@+KF-X -MP+#*>6,W7D)#5@[+G9JV*7)G[+H!A2O9X1[6)RA4&";8B>NE -M":T&>:$7A-,1%QN/<[S$IJJ%^DK[BVF]+,*<4IM4PN#+$RHA_;CG6.G8;-L# -M6OFZY'!"&.F;#67!J+B1P#%(HH=]CO*"?4D.]HH*[M2/RJA7%XA%X5 -M'TDY9EVV@I?@.2I@0A%&,(BG1)EBN7[YT-N))TP,=G9\F8P-;S2S&.?XRU!+ -M`0(_`S,#`0!C`/BN(T4`````)S,!`&LZ%@`(``L`````````(("D@0````!- -M86ME9FEL90&9!P`"`$%%`P@`4$L!`C\#,P,!`&,`C+`.10````!J*@``K7(` -M``0`"P`````````@@*2!6#,!`$Y%5U,!F0<``@!!10,(`%!+`0(_`S,#`0!C -M`(RP#D4`````B0H``*(:```&``L`````````(("D@>]=`0!214%$344!F0<` -M`@!!10,(`%!+`0(_`S,#`0!C`*>+#D4`````3!4``)M_```(``L````````` -M(("D@:=H`0!C;VYF:6!R(9&J6OW+%/X2D%.HLH/4@[H=,;4@&P$:E>NK#GQM>2SUV&GDS9/G@ -M#J5^X(O,+,<&,^D*&]*S\[._['H;H(Q_@TY#%3(7ISR#T4<+FKD -M-'UE@M9HUNOF^9MZR#O0-#3>B]`@TJ]>?X)52Y;GS"R3N$GK%N3U>*,.QPGC -M;.A^EBBCJ^;J2`$0=15"S/(-HTY$S,RP&`]-F).(Y6:IZW -M7Q$X7=3@$DJXHXHW.R,6AA('+_8!`0MPO*EN3=90VQ[;;:4#)FB%;O@;==TN -MUIODRIYX5A?)/*":="9HP.[TN_G`P57[R16<\9W2T3#$S$&_&>/BHK[17P\B -ME_6B>`J^8YK:0!*/65&B<]:)W`8[46&N&0FRD2<\-9VR.)+Y<4ZF6?;WRP30 -MYG7\7`5:2OPD'DHO866#4U/#@$1D(W-]H[0%?*2 -MH>)PD!IL'/X;6!J+W-(785MSV)I?B_: -M:&_ONZ)K#.-?;ABX?DD9K5E(0\*^QLEGN44VF@^7@47AQ/I1SF^KRMC#QWU$ -MXA=^RQ5-2J2;_AY:JKS-?)>L;&_A9R>M?$Y6=^A:%K+$7%E>X:2JUDX397!U -M8$CA([")9K[.MGT#&Y+.VX`K5Q8HR(&-K;ANB!,ND,+3JJJY;S$&CQ2(;#4U -MC>8"_W'[2%A;H69FAB3R;]**#["CIEV]VW,`\J[A-E%`A42,$LNF(_U%QX8>^^BOOKHG#S.;IH+\7S+?2H_E,6WE?CJ\ -MEZY4F2&QH,(.K*8\CYYJA/Z;O,C6EYZ6X!-/=ZN;9,KDV>@G93A*\*@X:KH` -M%$;5M_5&QWJNWC;602%0(F>BETMY+)MSI>$+;GG\1KV<03_G2!(%T]8-/=9; -MUC`8Y^B;A@/Q),\*+H;M8OV,Q;8NOPY50W2#)50`VP836D>R0Z';AS%]"V5*(5BAV+P$>6*W5TE._HB.O[%H1YF#]&4$`](9Y -MP@5P\G.*V1]^2)$A$'TZW[W?AN$E\7''X7N=!U!")BU6T9\=?$1YO2*!^D&^_R6% -M]FKV"\514HQY9!\#<"1NDS85\KC0V*#LONDTV%*A)!;&>)F#8.#4!-*HT$B),T8-\-WO,W -MLM\Q&O['(&M1=-DG4O068^=J#\)^33.JJ\5R@:S;+;N_*:VM2QC3TH5X#EQ. -M_O=Y`=0,&%^>,P/,'N%8'5%TO2K3%GPLY@;G@MCBMW^R&JQ*U=XXEGPS`OTV?!3I];X)ZX(=AF+G7IPQ*\!M=KEO;0;HP"0TP9MY@7B-RN?H,>%1LE&U6A/[`]3C.0_KV]$+*2O(&$>V%4-3<=]G,%O -M!`JBSY93:XW8Z9AA+!L^IO#!]+ZR63)?MH9N)HFY? -M-.?$SZ68*UXULE*OHO>MAL:$7TSY3",VS:4;NHSVWQ?D;<[XQN]$:(+Z#)BI -M6:@7XQM-VSI3N@$=^WT%^YWOEVWC'J0T&D^C'2QO"^;.Q"5E%7&*;8BUHKIN -MCSX:051L^"5D=E.GBR3BSZRMOD-U1$3[P=.-K*OJ#OV3WU!1@9R!"#6L#]A< -MF.Q/J!!\VL`;'VMQ5I-XU$S+>IS)"I/T-XB67"!Y7>]@1ZYU!:_[D'N,.WM=E`G3)K@D5LIJ])3 -M<6;R)I99QA=[&)$-DDDUB9N<)S"B:V4A!3[)4=UYP3Q+C*9'UG)FQ3V[YJ6+ -MME<:)`J!8[&2!?M12?JZY#O&Y3&_/G4Z,IW%G\072[-*`.PMYTDWM^X*UBL49-"!.X=)2'MO(:X0$W__\80X8E:"L]*F$COJ=L][03;IC, -M\:_Z4]@\G"I9`>Y@'L+[ZJ*U,LX?]?4N0F'G_/^%0J5K7;G`4`]2D/ASCFR; -M[I:DJX1O)/9=-*OKS8G50PE$YKR#\G[XA"0]K5R4[#U\H+:7/NM,#$T9.G:? -M#E#UFQ_]";#E=:]DAU<)M#QLS[HN')L'HNO.51+V#36F%YJ5#[^@];DYA1UG -MY.&+\XG3*@3[9Q8G=#$S95)E:5`4Y#JX,\RM8M4;R5;$B+Z"P0CT]+H',L^J(-BWG^4=I)QD -MIU2_?ED:=W'K$]E`E/9]*S%V+5IFKRRY8S1W&7K7N6-!H?2E/B&J5PR%:?MK -M=331,'0Z!H+:W'F!RA0U5N<45+;!4&X8JIVF`;^$4UJT^P;<[4CUE!%7LHB3 -M;:U##\:5\2V`^E1.!E!^"J>(`A=R9WF1SNRH^#TI#F$.N%V-U(A+]<,#R[#D -M9?2@!B==^V+J+-V`%[JWR.(9RR`U6?"D7D:F:)_;11RW8%M):(&?4$'8?Z;V -M^6$Y)TR3AJ%IA$PE@5$T]U1!//6D<[QX%&3L2KK+B3)9WYSDP:DQ";XLB%BP -M):?)VIG.0U-NH:P$0,WVALS*B6\]UUI6]Q<&"V_N_&&'=AW%HL -MR4E([I&V[`\[$+9S!4RZ%D+NELG/2T.0-7@4OBFWW3UK^\=WHFF?E+/,,'.` -MG",(1S.#R\`URH#JB&A%;1@'-P.[Q7J![QLLE8G%,=E^JYX5N&UBZ%G0$-($ -M`R%<+YPOA:EC6#8)U]\WRH($6$R=,]88\Q8/EK#$&G-R86@5//LO%U6@0-JW^+5O*B_Z!?I=WT#=K-"F$W -M/1;Q\'$3:H5KTCILI4.9'Y>GY]I#J;@A$%@0!0W5MQ.[O;AQ&BFQ_3(UK>9]BSWQ5IDDKJ=:X -M!!![8:'7:`>#N(AK`]X^-DO:M5MT4FW)R7H@.=\A5W82=E'K\Z]?AL?6CJWJ -MU7WT?V/9)\O%0 -MFYH]"*$OI7+6VQV'J)55UH5^V#M0L*-G%/LU64R^ARM%F&T?R'WL?8(F9NGW -MG/&"&&Q2GQ[2!/*<"UJ"JHGS_LDGBTA^;89WDT^W.&0--BH]TNXRHF*W_`8; -MU)Q8#][%\Q&X_'"@I_PW^>JEC/Z6I'X$DYC5S^"%,I0RND-<=JHD7B02Q5Y5 -MV1N,6:':N*IW7"$1+_<,<]E+GT:L@X75DA$JV?N6SY^]8!H=4Q<]/E&81<@' -MIH?HN\=`N\,-17_+2E;D6/C#;I3#UE/)MLD3Y@$JJU+Z>SY(_7&]"K5R.V<' -M<*B(2(5"@VIJ*JN<7'OHOG0_(&G*_N*A,1N@N478HU^UPAU-'Q;:TB6K5RW9 -MNYD`-G5O'S(0*>-&4N)$9V'\UR;X:0#`3Y?]"N>2=I9>A!CH$NQ.2VOQ8R -M"T51RL`LP3W"^@3I%QF-L*J>BVLHS.C>=!A\LSXDN$NOJ^3AGJ6?M;\:04@` -M$PK^Y[Z\*0$9?I -M*(>$AA=G%3#&S\1/]P>FJA`-K%S\#YN$9LJ;W#>SL?UI9Q[*X=O"8,#VW40( -MO4$,EE,!,+R!R'AM-:R/*)/4MA*CLHQ?)8^/5(TYC5K?LO$Y7'T``%+;ZS_7 -M5V4M_]Z>$*[2<.T\%K?B[!B=QY62F\*UVIU.9,!]!U6(F=(NU/>G:DA?L:DL -MNW1J)??.!-H/QR=+P;NUP57X,UQK="_S+$!O.KZCZ"N:\3W/K -M?I:YY\5:EZ+(\)Q)S!CFWP/&582L#`W5!>'EP&V#&AY.LF+-$VM4@J\;\N2K -MK-%:1>,#G,W!U8%((A>Q@R1RPZ)3_8WAADXS.-@Z;[A''J`B3'G]1>%RKIE, -M7G+?@WLK5`Y#U:U^7(_`L3YI2QS2\?9 -M_WA62*X<,CAX:!+GGH$&&]J"6Z.##467^XRJ!?E"*&Z^9\M&DX7\9_ -MRBCV#7E43O'_\UHJ]P=-*]KD0/&VB9NM*D[BU[:7VYX@)53KN2JRG>Z'^CA/ -M+*?JTM)!2L^2S&`B!;QOGN%*[$PK/,@LM`"5DC;C"`+.-R>*MF'C]R\F1H/*?A;O]+2CR[R^3?7>7/?1V%.QVDN\1]7YM(/03F@PB6--%"X]:NG. -M2*&QWAYYY]!9/W!EX(,L'N\#'9<4R_J?JX+"YX@2KKF3J -MQ#[_YJ>QYM,/UOZ-O2"=/\?1$O^"!%1IN6I&B0[9TPIA.KKHT0:5L`(OM;_*[+-S]\&8=;DO60ZV3S6/9(OZC#C0@`WLZBY/ -M7I+J9_!XC0A#7$I?Y60(.;BJW3[E;[!*G(5]Q?1]*Y^JOQ6B73IRF5;=G#K: -M.OU]5QVW!NN3)'(&6^0&NH^#/G'EO2=CEB5`!U&LM']9+QI^>6=0_]"C=E7W -MPUNAT'&-4/TL%$1'_]7,O&)J%SSA46@^-Q$T`%X,;3TL#]TE^5>.K^`(@P_! -MCXOA"?%L^RF$KEQWY*#T+M(%DD6"[14E8%>_93KV4/27!I*^5507.GF/]4"U -M2V[\B5"PSN+%6^]VS0LW[KTC1CBX!.$L]$=O&GNWZ3O`Y+-J*@"/Z)HV6:*JBIWUK2,\M^,_6^N$[:Y-]=8> -M`ALIRF@IB57=6@_+%"S#YCZS5@`*.T*.FK+WQ:D.;3=RD7S")L#6(.4,XK10'./2QS#=Q4A-:Z1IE.;G -M,%YN)B0<0SIM148!I1ES9*O3CG>R@L0,*>0VBQ>#3V0ALU$\*@L"%4!AY7I[ -M`NP:"5X)$HDSN<&1LE%39K302=P"T`F91!*Y:I](D`].-'[R0?@N"1U6:>3K -MMM,S4$EFRBPP]R8:;Q"RR[!3VG$J*PZZ(:#MH%9B-KH3"\J!^:SLQC9X\,>X -M(SMO=(;;R2A2'4L8K8O)3$*;`,DO9KYHV]*V:A+>A\CJQA5>6JV?^K?]+(@2 -M*QP<,A3"X8K050>U,4D1:X%;N)1L_W(0")]F5:EM3J#L^$LHI+&_243.PST= -M<=<_L]Z_*-X?S04H(GP)FG_2??Y:?-S(=N"CJ(@&G4A4N)`U$:_&_^K.O-\\JV@]6"A9H.:7G5WW0FOR-' -M#?R7YD]EG7\81+LR:=H2.%@%-(J[K&T\.YF1"^:E8L%E!_N+3+RR&E=M!`4= -MG6--\@]9)[^ZC]"@B4O";_']UIS5&`9"I!YLJD-ED[HL!U[%Q"Y>SD5BYT\` -MR(J>4SI>2(I*MH&$?"*\(+J(M`3X7\YO(Z,CLO1^36R+G=L,.B69E;#2PS>$ -MDHLU-M\!#,JII-DHM%JW%'8JTB9))6CH>V:U298/E*,O<"_=?]W;(T3/@[R5 -M*!SR=:!'(@=I?-G!F8!?VPP?LQ*5;\5-#\*BKV3*@Y3G2'T6?CA6,5$V>B&7 -M\@6F'A[7^43YY!YSQ9TG3Z_J3X7<15)ZY?QQ`KI<"[E9QT_20!WFJJ_OP<&KSVT3FA,@<`.-6*S1&>_2)ZH8;]N -M83/;=V[ -M?'&*](J#)IL.,":+V\BEU;&Z##^2'KRF-/ID=853@9"BC[N.^.JW(JJG6=K& -M/K1B:]XE\`$."8$HK2#*\4^<1XUP22[]-T!0Y&U7._+NE5T:;XQ\WM26?,.@ -M";QFXC3@X"VQA#FD(%1]PIC^([AC9?-T]O.BR\H*7N%)W\G8!WAD$=X1W#@A -M[+?0[6[3H7BIM"(UGS'5V@B,!*C@/H?F)!B":J`[1[\-&\33WN(`/)994LQR -M,]6F_<<=!+[\W")`@FH6O@K+8&Q79I6/ -M1E8A/65;.7IQP,I3^#8$=#_7$NL_7;)/C2X;F;3U6-U52A73Z&OY&QL=--L/ -MTT*1Y'UMZI![[ZP6YXQ\(KF,%GGRNDSN-GT(X/@CM&%''4B'9-/[ -M:7(4%V+8B_I_G@XO!1Q5:DW$I?&QI\P`@RU$KVES`B^>,QU?S).4?X1@(0[2?]C_##22\J`G86//K[JRGGH+"Y)HLA%4_9V== -M5P(C0&F8,O.R)P>54%T76]#>@LXO63MZ001?L+'O!K>5XS>K]:T:[@>,B:;IB2F*GGO8&\R#"$?)HPC+#D'AN$-BB4DCN*:APG]7"W%3B*5"(U2T4X= -M@9C.@/8;.JZHG[SVJT15QY!L.)V[L,D%N(/,7EV<6T2M8]4DBT%,R/89LA8U -M>U\)64S)#*.)'0[!#/\9.6^W_>#"!B@NBL?7JZ1.$I"VID$2&TI'0Z@\P'\G -M6SR9!0NU^`IV_ID8U%=3*(^+"4T1X((6_FBQC)9$PFBUL]<1,]S!+>#PJ[%H<2H0"6A -MIYB7=GGPH!_8+Q:$I09*"\)&%HUP2'X^1_;,\T5=!'^A#5>U*#)2^Z>L/*E5 -M%Y=SZRY&`Q_\(3_!//$I\E.SDZXL)WCSE7*0<#ZW/W*WM?^3CV,,)YEK01]T -MT,<7Y)@5O0':C!S_0^WG/9:,_0!\NG>*V2&:&Y6HU["3TUJ[%2F5'QVDJ49T -MXGT,!*J&0,&"B11L_MOP3I7+N6GR9P(1N,#/>TI'$'P9K@^7G77Y&\%&7G#U -M.(1KPE@G:PEDVEKT='HZIP\2CZXN#7@$BKO\_/`A&S$A2;^3%0VJ0B<>6Z7* -M'(W4;J5SB-RW4&#Z`/N2.@8_6$ -M@.Y1A%M"F_0Y9)K*3PGD$TRK,@"9C'8J9SEZHM`Y$LI/?PG%_42+$3TP@+I` -M+:FR6X1[JU^A\'RX,7__;W>6RC#^PQ8?M\"W+\9N+5D6E<,I6YVTKS#\$JVA -MZ;K0DY^(!*H9_',HH[YJO:)!+$6'J^.N'A`#`W;24DHV[N/$M_I"<*S-?4"H#MX!C`%KOF),."`K?#U%$R3O$^-3L$B -M4!;(W2EW.X`!YA8N;NJ=9MQ+0L:V/,NE<$C'^^VK:'5:ISTE3397ZF]A-RNV -M_0['T/F3^RM,C)6LKU.-W*KX4K%_0E/L1N*_EGPJ.$1^?N[5CQ%1QVWW7=PQ -MRBO*[C$);8)1VXE3/D#0,<6UN<]Z2^" -MDK"/$_T4Y*0'L%^0ZU9V*83*/A7Q58HO'/N:&4-[4C;Z"VG4F*YB&&-DUJDN>P.WW_W/(C8EWN-?5&H` -ME(KXMK!7NU+"*$'9`APUBFPA)L:VI),V)&P9=E5XX@LEL0`6F[B]V<#9XN[& -MRCL*9L(.?C[(@XE%VY>?B<'!&6!:!_F-/_H10MNL_AK01%_7!^2_ -MK-;P"DF0A;4'A4:'>AL55U%9:8*0`4^?W8+9DT"V0RD8LG/39(VE@V_M&V+K -MAMS@CU$V!O(Z>CG.!!.(;UXV'W%\:.5'^#G(S+5'+V!>C07US+?DIUL/62Z: -M&B4VHH.FA1S9(^$W)M3*NTHC:"FCSF;3$8P4Z@>L4)!K1Y*\<:F0-]$9L=HB -MY)E#TDD5?I!S4M5OOCCC'R/!D.`9%'K&$F[4E5VH"YP$-,%9!F'3#+:9192$ -M+UB^3S-M%M@;228EH`````````&9"<41``!4)ENHJ``*_`(``````%E:4$L# -M!!0```!?`$DZ/4N(?PNR0`4```8*```+````<&%C;6%N+F-O;F;]-WI86@`` -M`/\2V4$"`"$!`````#[C.DH'JHS8W0 -M#?$V8!+]F!+4KI<$@5HR#OF&_!+?L]N#167^N/Z\RR?GT6KQ]?CNM8>==$!O -M=?@QVU.*S@O@?_!ZYES=OXHQYJ$K_DR%MMLC^2[U):T3="8KH6E\^#TM[(#:A4]+,_]N-'V@&OOT`,J)*`1$6H.A\AQ<:=18H%@ -ML;39WZ/[&[?/?SG0:`)Z@@QK2DRGY04F&/;-K*Z2%^"N_BP_F6O6MO(I/U.T -M,L^0$-SQ!\_E:AA7X(VUV.Y`_]<]=`A6(D?^?S$N7OB; -MT(0U)^NL7%.Y4Y=[UNW8JWFUU2Z%N5G/Z:2V?%%%6/';]$%?%<3`>;=\3"TZ -MOQH>DR`T^1`8>\&>-+PCS8;)$M]WJ2O3&-M5NR) -M$WG>P*D3/:ZM,!QAAXTJ^?^DMH4:%0+):![`U`''+%K.;9,DM-OWB^)49!83 -MO-XVJ-N?)]_]87HXQ6(V0%4!R+DSR&(F=2*,KFTT2V$[`UZVVMLSI3T^B.%" -M3D->'YYCN2Z9EC%"/S^=W%139%7:"`%-3":\73B.TK]C)8:O)4=W6=.WU7J2 -M@Y#"B90[N&9_-Z@-5-#!_EI#N]D^NX!(OD[^I4G/L<]:Y&KD/P[5G?Q)6SR. -MDWT*.9G^KK"3^&1]@*+P6$#\Z4SCR,)E-_G'AVC:U4C%35O[,9B\$>QS9A// -M4-6)6TL?R;D":$KYVE+4" -M&J><3=ZH:XM&"9ZG5-4HEZVM9YO'8X@P#G1HSFI) -M2W.U-!_N1K4*.N#AAUV?:`+5)2Q\ST04<\TLD-92B`V7$2.54`>G]G_GE!`] -M_IBNF"]3MS#G]1S*N!MZE$UQX#1ICZMB[T'>_#A&8:3CP,B^UU\D$[3QNZ\P -M=]=4'BLWD`?H@Z@Z1;^A03I/VJ2$9]*>-&-,(=@TI22.6-'S#KS*+AT&AY64ZN7$Q'B,&TN<$OCO2W@';2/5 -MEKGSV4@OF10@NP4EBO7\Z_Z/ET#+&R::*OH_-<8/2\VF!^Y["EA#=>3&>K=? -M3^N#$@0V@=Y#K\T!ZU-B?E02#N6U>="G!A6&D?[?!.55MDR7@#`#^[T2I%,A -M+@+0O`/8^4,FN!XRSE;S@C93NICEP.5CEB_787X1B`&3L2FW@E,@?%HW,)36 -M&;CMA--B'7O,LRD\RJ3&]S+/5/3#/?F.Y/5_]51?5DUT3'R5UY.+M -M3HA.NI":EB`FI,"L@%9/?/J.E'FE+AIF8,A&N_G:M,4%DNJM5&/OK\3N="=5 -MYWM9VORAD0```9P*AA0```_X7#"H``K\`@``````65I02P,$%````%\`2J/! -M2E3P*2/$"0``R1D```<```!P`!&(!PA/3V#P('SF^\W3.1N]J/".J]^]]U@ZBN`&LJSNNZ7/6,;7A:'$J$`EH:>8EW9Y\*`?V"\6A*4&2@O" -M1A:-<$A^/D?VS/-%701_H0U7M2@R4ONGK#RI51>7<^LN1@,?_"$_P3SQ*?)3 -MLY.N+"=X\Y5RD'`^MS]RM[7_DX]C#">9:T$?=-#'%^28%;T!VHP<_T/MYSV6 -MC/T`?+IWBMDAFAN5J->PD]-:NQ4IE1\=I*E&=.)]#`2JAD#!@HD4;/[;\$Z5 -MR[EI\F<"$;C`SWM*1Q!\&:X/EYUU^1O!1EYP]3B$:\)8)VL)9-I:]'1Z.J-8JFWEH.CT0J&T-]!<(2-ZX3@)RN\J -MD0J4H/6N:=KFT$;\&+`]@#Q%F@SF+-%(65*CB7!$HAZK&W*TS\4$TS&_-!XUFUI$7*A-;',>)+^5/P,ZD`[HWR.A9G^#C -M-6KTNK(S\@+HL$6:2FA5[-R2LQ[3WK4@G[G^^#%XET%6G82[QS;7(S,^%>P. -MYKA-5S)0G[)N+EKS^1K@1W;SU#4':SY-Q*(HA+6WR\"M,7!$$QQVKNVE\P[0 -MBBWM8'\!):GY@^BZZ/>2OU-EQ9/907=8"CMA,Y1-O?0VM$[ -M,QLUL^VK@(FD@-<=6)L`J(Q]$R2&TIS@=/S2CA0:)DA&H\H`$K>#+BZ#L5!& -M]8O1Y2#,@L6`*Z_D^1@3[G%I48$DK(:8@ZH;WXDD0/L?(I^Z'Y4Y+\D8XG`( -MSAG!!38.H:+L%5M[]Y^`-CTFJ#CX<7/IC$#M`L)E=Z68`.Z15.!\)150B=YZ -M<&XZF>5(BYL_(:&P;,V^D';WU2KR?A0+4-E:0%O1F9`\";RR09,+G:>77.C7 -M]KV`K:4D9*B)Q7-\>:1&]N#JUDJ(<;NGJG2;_\!+&29%3S'E+/YN\/.CP_`+ -M2C&6BOI"R]9V%EB^`F/J&*.2?`KS5D\7+CM*1],_W<7&0.MI\<*%EQY7Q@SQ -M]J35[E'P\:C"YF9--<<]IB4/#I9@9S3^CAVB3]UU"M=C#6^!]'`R!N<"BA3D -MN!$ISF;-DTGCY>18H,[#4UN),"U;=7J/F]7_C]K`/LRZ> -ML--U<[]+X!IV+&GCQ]@_E!=D2Y1SD_+@R,2:B,26E+GCGX,S56]3OA<@OBVL -MP`N1,^ZJXI1U"XKCE:I(CGLU!K\^_VU7+TJ2/;81PC?GHW(SPC^[!L2+DA`2 -MY\B!@>P$N?Z%:.G%!3DJDM;N*"DN*/0 -M.&`?D?G/MZ-/H^LA*3<3>4'L">#EY&"!H9TB4M/1;]:<*%/-*%*ZZ2,FF"T` -M1-VLYD+N -M@QH1*4'INB@E6X<9,1=\T'`K<_PIF!F*CV&59B&:2$-.E\%OM2!\T"\X#?W) -M_\E.2DS4TN&FVR:GZQ#7+A4-!3L*KI`(NX#-0JA_OH3'J@OJ/G'C\>/BB@8\ -MO9AR=;IRPX06AZX1'^R/RE>AE,'6#4](`V?FM0=BN]-3P7I*Y1N1VF>PL"IJ -MGF]0@PM>JH[PYGC*F^0"*N9OI-E(9C^LSD&NHWHEQ=_$X4]3I1L][E,)5C%OKU.]ZXIDSD]%)$8-'2>$@08,C&F")$0X!^:[H:2 -M77[$CGQ]J0)I&=%/9U>ZZ!2Y93+,3^<38JQEC-]%YBW9?`S,U]*_N)5*MF1; -M6\2$>DXDY!G'+D3!)U47?ELRTEI9>)&;2]..PL(AM-=O/69L[N:Y:FYU$4OV -M^,N@H"C'ZH#0&TGK?'HWAY=!0Y!^[6!S_P:>A)^@YZ;N82NGABF]X@0;_,-? -M>;?A^0=`'34QXH8VW08:$;&O]MLZDV-KC!/$@J-K$9[N0&GOS+2GI;?LN)L!M0MJD)X0D:^^ -M)C-S@Y6IMQ)#AE,[..:E&_PK.Y=^1&=;H[0VN#H>-LQAW3+GYKV6I=X6B3=8 -M.@Q5EULK;>80C>Q2*R&+D7DQ0E3,-2X+C]$9NN9R62RYTV[PC,4H>F[\5?A# -ML..XN!<+40H+7WGS&4<3H)3#?4%;XFXM&K'OQ*Z'L*"N<J@/Y%[H1GLJ4SH:YM^-V'+5CKLSP:+]J--=`-B,9Z+53^H2Q]->KE@3ZYY -M\OZ`-KB^'V-<@\MC.J++G-TJ>RS-M>)-3OU&NT5CLUM2@\\A+I;`GDR'T11U -MAW1H\ZECZZD*=!@DMO3,60R-`\W7_X6C,8FB3C-2V -M(@S*@2LK1T%!';G7&%\&D>=1/;=64G$92-FPMB(<+37:DLED52:_VFEY47*O -M3ZKVJ;/.\O<_2Z?IB'U9W2:6S6_,X$F=(#VZO.@V-4CY<68\B@A`UKG0$AR1 -MC3-VV!4W/,85QD39F&!67\SGM$KS:=TRN]$V"EC=+O7\PN8.A__Z)$@0>8,] -M!NHPA*?U=-A#U>OEK!#NG,RB2Y@@`5JNHJR0;9A'3FP'V/.UYMG+D*L*">.% -MKY&BW>NHE92\QT;V$D8_X^)[*WA-4GBAS.]:Q0"SGL>J*KNDX)76,LF["/13 -M[SM72F%\\//WRT1^2GJA553G>V*&$Z9ZK.*:"0K;06@IC_N`Z$&Z4?!2=`CN071_Z=#```````!G1/),P``5\:%:*@`"OP"```` -M``!96E!+`0(4`!0```!?`$JCP4K)N%'WP`0``,4(```+`"0```````$`(``` -M``````!B87-H+F)A$,`````__________\!`!0`+0$`$``````````````` -M````````2\O,237@`@!02P<(1<8R^P@`````````!@````````!02P$"'@,M -M``@`"`!/>7A#1<8R^P@````&`````0`````````!````L($`````+5!+!08` -1`````0`!`"\```!3```````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_zip64b.zip.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_zip64b.zip.uu deleted file mode 100644 index 99bef749b..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_zip64b.zip.uu +++ /dev/null @@ -1,7 +0,0 @@ -begin 644 test_read_format_zip_zip64b.zip -M4$L#!"T`"``(`$]Y>$,`````_____P8````!``P`+0$`"````````````$O+ -MS$DUX`(`4$L'"$7&,OL(``````````8`````````4$L!`AX#+0`(``@`3WEX -M0T7&,OL(````!@````$``````````0```+"!`````"U02P4&``````$``0`O -)````2P`````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_zip_zstd.zipx.uu b/thirdparty/libarchive/libarchive/test/test_read_format_zip_zstd.zipx.uu deleted file mode 100644 index 58a295844..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_zip_zstd.zipx.uu +++ /dev/null @@ -1,18 +0,0 @@ -begin 644 test_read_format_zip_zstd.zipx -M4$L#!!0```!=`#TQD4VJ.XZZ&P(``)`#```%````=FEMI.97\6@M?/P$SA1R6+RFRUD<*@L-#!$.$A`-#!,!;_I.?CH\]WK(I'HJ -MC1"P;([X:RD\"4NZL[X9?H=*YI9Q^9SUG`U"%GS.%'JF0M<\[PV?3#MR">63 -MU+);7<0EM,_'U]+()+7>.MS@IFGS.GUF -M'S5\-@V=Y=MW6",,P^\(`,FALG&E(V`ZX;1&#G$;^?8[^=%R^:Q[GB1^JPZA -M-SI]3O>XY5O/>)70LG3/QWO;L^DZJQ/Q)"5'6^UGS\CUT,:'[<)XDMY"B%WV -MPK$('N2MJ]2M61L`\D@@2E$0?$HA-^YDM0T959VUCN4BS.J<-=[ -M6P)HFD)TO47V[FWT;?<:9=HN25KX&K(SA?9*P8'"=&]T1G?9G8^[AR>)P11R -MY'H86B0%XTKA&U$O;*N]M,>LJ)E`K77)I'N2E`(B(!!&C.+TY**V^BU(V9R8 -M!ZLXW)6;"!YPP'E,4_F\OB!T"4Z:6/#"Z823+@5V#BNHGHC-+4@`)>?""C,) -M2+G'/1,#D-1'B&&R288:'(KD,I>"_/85-]>-'@L``"L:```+````+!_^R$5-5D[3>O4AU,N^VP>S3+^79Y-P+W?;_&!3.]_D3K-7OY*9 -MR]UN$D)9?2_/*/9(FB13Q!*YTT"H42F^;(9P^_V^L)?+=AI^5S^^6_'%I]C. -M9Z)^65,*(B*9*!+I`,KD;LHM>DSQNK>@Y,P6C^]6?!12PCM-YG)LFS/\JU3JFDR`5XNOHZ0N^P8+&#R!1]OO -MVOBBS4MIQG>:9>T9Q:[)S%W4/VZGC-8[OR,X![]8K^OG=J7OBK4\VOC@YV9W -MFHWR5[_MCQ4?:Y^R7Y3899^7>IAUK^2;'[3VLMQI&JC1>GRGD9AHN)X7\Y;: -M^7ZOWM5WNA/:>0C?=J=I`+@#PY2O0,.QX&@L(&@\@0,*@`$E-!B.,QP-R!>< -M!,"=IK&FC!A*V5%BT;9MB\5"UGU]@=_7TNR+R88[31-545)1L>].?^1Z*L:? -MLOK"5SW*USHUZU514E^883K="9+:RYTFHYC6C\_OLCR*\G4F;]#*=Y#!]VJW -MEJ6P^EZ<)N[5?Y^;47@$2V0Z@!QU6F17TJ,I0O;UK)^Z6:84_%S$)!55+`'Q -M84Z/04]X!7I"PI,`>2!?`)UZ<<\[-?BTBO+P*787=[K31`@)!V\)`U,VM1,# -M;ELI":%NY97\:E`QW[3R^)R&'\@5#-#:Y4[S($`4&@>WW*T##RHV96P(0GL( -MO0'Z!:+0Z&RIBGU\3D-!Z6Q+PNF/)1T^Y9R4A[76YELJD8?):1J$!V.!8!$Y -M/.!@+*)H,1V<)^A17D)7Z.IX@5FW<)H(4PCTX(RZJ;5.=YI;4<+K,7U`CL?= -MK=TS[-9#J%-D6DSYB"4R+2*6R)OG8[C3-`E?`)TK%%O$ASD-:X_A2IYP -M!0.93:UU;H9M7_:M^+J7OYC7&N"DI5W?%+BLEY#!KH'Y2X'Y2Z6#/5,,>7VQ(C%-+[J49OQ!=/B$7K*[.!. -M\V2F,B^U\2WC^=T`(N(1;]+%MP`C+XOI!.'6[L+@&'%61I@BTUO&@T?#P="M -M#X$>=U&S($RF`G8GPY^#*SB-@@/R>#@D.,/0]%U,4KJ#&DP%@DN`306CS/TQQ3?05=,[X`:49NP+`&$@#>Z77!V -MZ^)VQ4Y_Y#11J=;KZD=R:\8GH#,NH9:5^C[J75Q^:P7<:1@^K:Z&NE<&QH@_ -MHJ#VHMYQX>/?:2+NN%B4\V'B7L(0F:8H%PM-Y'8^7G>GB=Q&K?JSXIO-E]AM -MQ\469MA[!CY`=_%Q$(RJ2AZ+4^LSKF#NM?V9D$!.DY#@N`(!/I&N0(`W/M>" -MBCUJW?7\G&;C@Q;PYD;"BQICRGXTR -M3K6T"S9?]>4)A@`4&I^`GD"A<4D%O6&_T%#3:B<*8<4']Z+PO*]Z3C[<,CT0 -MQU"OWT20_.F'/?@J(DA_EHH[MZH>PN221WHF7]#4SBFI.!$Q(>/8E426\BW5*!/N4UZ$\&3:17\LPP\G\B?6I0!EVV8I[6 -M`*4UB!OLE#"H9,P[LXK]5*A9.\][4:W8M]4MXEX;Q0!*Y;R69GSP*1]&K[UD -MJN<>*NAI@#YE)7OJ]LDD,'@FZM2FK*IGLXSECRP)H=OJ30UO@'[W -M_F0N+FKSGVP7\I^YF.4G(4Z91#P\3@A5)1=1'E257'A1?FY!^1TB!UPNYC$_ -M;&[V9Z&2WRBCSH6RV0*Q>%@X/!#/L_"B&(GM_`/A8J9B?QYM_<)FF?Y.IT@D -M8'F!P:@Q,5/(S(B(B$B2)!D.<02$&,6>IE2R*7%*T&;?1.FK+IYT!&_5B-5DP39XE!D% -MU4I&#GB2.ZRXY2=4I)"45?,9GE*1:>%CGS]Y$T?]!<.L!XW0S]DV[J]^RZUO -MU-$)H:Y^.=7_&D-=/U?:N2=I9478#((F??EK=-I1S/+>G(J&!8#8Z!:SN/"0W!8-Q[JFX -MM_*65-,=T<$H_5R>$A*!B@?!QDT)A2&MH8F637:F%R6%";@](C+4@\6'16DZ -MU_HU?%3PJE\R1U+@1W,+`-#RU%+^+.>.!"M\UT,*C&33WQRGB1G26U$9^L)A -M)I%").6%$Y@_%NBBIU(1:BFRY39*=(')Z1KA$&)]OJ(+#I`/%M!VE>6H1^\D -M,#X7\>\,NQ2.]95_3M#!#:N(IC^E6(GHYRO+<3#5PU)A=@0# -M%[=9[_H%";U],PMX`<<#,:#K?!05",0@;1R(1:[N>SE]`N+W-AW20?"87U?W -MK[3+[+`]MO)(%2XN0H\@:S$OM_]EM=8!3:[TE;@FRJNCP6'V]PP'1<*B?KO! -MU0BW]X&T&QIBOH<8K/(#;Z@8%W[DDI%8F[B.+3D$C,J"\(`6XIX"'LOA0+`7 -MB)&X$P@K>MMV>X/MQ8*7P8-UY,(L_Q?%H5JB#>I4V^NXD34"X,<3K.RIA,_` -M?(#'XE!-6,8R!_)8X4;0H%5C7*"G;B"^H.GQJA^21KE)P!?PA)KD#RQ&%K(I -MX\:E'!D\^5@D'RPX,&RVW'G!BHTTI-]S4 -MD8845O$($J+3Q-60RN",_F/"AL>>K)JT2M]0$E`:/I!9&4\N/KB'Y^@,IEH' -M24"9!VN@A)H:Q?\A`.0A848 -M(`]O]_OU)'H%IJ@(?-M*9'K)&RCLM@T%=-)*31^"9Z1TS:;@S5]#J4..*-FE -M,/B;48CTK8-ZC76,F34<-E(M:`YL4:7L>QH0(`<:3R#$LW-\-LR\E^AG; -MI)[_`WT'-5!+`P04````70"(.)%-,9OE>IH!``!4`P``!P```'1S+F-O;F8H -MM2_]`%B-#`#6G$T?4$W3!D_TVC/9!E7:MTFZHMQL#\'FCNWU"^^36;A/#48` -M00!&`.H\A"5RGEETHH(5QQ%1V?#T(&R.*[7D]R#N_$0E[^.<6>(Y2SZSOC[& -M-:,6X0J5Q0$*P+/1^N-MYBU7C&((R=%@NK,V;$'M>)X8I2EYSU^EO7):4J]6LF)7DU;\IOL>*,<7S5>#A4! -MW:L#`DX$ID628(-DP6F6,+#@0UNE-8G\PZSD?UZ3A'UL]2XVSW:@7X5C(LE=*@ -M!P0),F$$.4@0"6:1X42K292OO'F(,_2?/@ZHC*Z015*;CIS?-8,)D!W9=FT'5M;6,=/5CUA)1X -M;1VP`U!+`P04````70`],9%-JCN.NAL"``"0`P``!0```'9I;7)C*+4O_0!8 -ME1``)BAL(R!OVP;,O[!>_2;=8,G_;[\MQ(&0),2W`I@S1AQ.5@F0@D!A90!? -M`%X`D5WYN&K*O.'RM]&3E$R[/8?P[:^%R]/I1X^K7-Q;OFKX`7;=U@C#,/O"`#)H;)QI2-@.N&T1@YQ&_GV._G1YXD -M?JL.H3)+> -M0HA=]L*W-DU=-H/GA"![DK:O4K5D;`/)(($I1$'Q*(3?N9+4-&56=M8[E(LS -MJG#7>UL":)I"=+U%]NYM]&WW&F7:+DE:^!JR,X7V2L&!PG1O=$9WV9V/NX-*X1M1+VRKO;3'K*B90*UUR:1[DI0"(B`01HSB].2BMOHM -M2-FK.-R5FP@><,!Y3%/YO+X@=`E.FECPPNF$DRX%=@XKJ)Z(S2U(`"7G -MP@HS"4BYQST3`Y#41XAALDF&&AR*Y#*7@OSV%7.AC5\0]IEE%P502P$"/P,4 -M````70"1.)%-GC?7C1X+```K&@``"P``````````````I($`````IH!``!4`P``!P`````````````` -MI(%'"P``=',N8V]N9E!+`0(_`Q0```!=`#TQD4VJ.XZZ&P(``)`#```%```` -I``````````"D@08-``!V:6UR8U!+!08``````P`#`*$```!$#P`````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_large.c b/thirdparty/libarchive/libarchive/test/test_read_large.c deleted file mode 100644 index 8dbf48d84..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_large.c +++ /dev/null @@ -1,92 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_large.c 201247 2009-12-30 05:59:21Z kientzle $"); - -static unsigned char testdata[10 * 1024 * 1024]; -static unsigned char testdatacopy[10 * 1024 * 1024]; -static unsigned char buff[11 * 1024 * 1024]; - -#if defined(_WIN32) && !defined(__CYGWIN__) -#define open _open -#define close _close -#endif - -/* Check correct behavior on large reads. */ -DEFINE_TEST(test_read_large) -{ - int tmpfilefd; - char tmpfilename[] = "test-read_large.XXXXXX"; - size_t used; - struct archive *a; - struct archive_entry *entry; - FILE *f; - - fill_with_pseudorandom_data(testdata, sizeof(testdata)); - - assert(NULL != (a = archive_write_new())); - assertA(0 == archive_write_set_format_ustar(a)); - assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used)); - assert(NULL != (entry = archive_entry_new())); - archive_entry_set_size(entry, sizeof(testdata)); - archive_entry_set_mode(entry, S_IFREG | 0777); - archive_entry_set_pathname(entry, "test"); - assertA(0 == archive_write_header(a, entry)); - archive_entry_free(entry); - assertA((int)sizeof(testdata) == archive_write_data(a, testdata, sizeof(testdata))); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert(NULL != (a = archive_read_new())); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_open_memory(a, buff, sizeof(buff))); - assertA(0 == archive_read_next_header(a, &entry)); - assertEqualIntA(a, sizeof(testdatacopy), - archive_read_data(a, testdatacopy, sizeof(testdatacopy))); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - assertEqualMem(testdata, testdatacopy, sizeof(testdata)); - - - assert(NULL != (a = archive_read_new())); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_open_memory(a, buff, sizeof(buff))); - assertA(0 == archive_read_next_header(a, &entry)); -#if defined(__BORLANDC__) - tmpfilefd = open(tmpfilename, O_WRONLY | O_CREAT | O_BINARY); -#else - tmpfilefd = open(tmpfilename, O_WRONLY | O_CREAT | O_BINARY, 0755); -#endif - assert(0 < tmpfilefd); - assertA(0 == archive_read_data_into_fd(a, tmpfilefd)); - close(tmpfilefd); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - f = fopen(tmpfilename, "rb"); - assertEqualInt(sizeof(testdatacopy), - fread(testdatacopy, 1, sizeof(testdatacopy), f)); - fclose(f); - assertEqualMem(testdata, testdatacopy, sizeof(testdata)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_large_splitted_rar_aa.uu b/thirdparty/libarchive/libarchive/test/test_read_large_splitted_rar_aa.uu deleted file mode 100644 index a6c3b3cff..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_large_splitted_rar_aa.uu +++ /dev/null @@ -1,892 +0,0 @@ -begin 644 - -M4F%R(1H'`,^0%0P -M/&L'[WB2!U7<*?4L4NOOUTT.SR!`I\R[_P1F=02HR>'QX8'^2HV&5JV`]-KQ -MI+1)$DI5RKBB(D_C'\_+]51?<,M@,F]PE+VS -M]2/>+LTL^)KUF2N[8ZO?.RN>$#S?0H]0YSYGBDJB]E^_&DDB:%;!B8J8GW*J -MO9*/%:M1X$FFP^&O`[RU:XM%UY]0#EF9\,:3">!<)ETSY)F5GC:.-&AY:MMY -M?U9WS&?(9@3"\/]9=PU??)T!9PR=N(\&#=,WX8AKH;:/SKE13]KR`RMXSC6_ -M^IXE6RJ:_VX+-U:3J`1R_HK<>S2[KP=XHKKNY&^5,X`_EJ,Q%SP[P=:;DP!V -M0!/%2"66A!1(2(+-#&]E)ZM83H-(N9*;>3I['T&=*&8?"1L$%$;3I6]YGM7D -MA@WYC]Y1YC(KRNJ.,K9ISE/HX0L[5W!@N8&,/@KJA3[(SRV0;9*#>[IC8&(O\6E?P5CO+^4Q.EB -M@5_+,2,=*PW'V6\5:'`GU$42X'+ML^24T+V!U"[7`*WU5Q]A$I;.G*JG3N>M -M(\%C1N33':_HHW*]Y@\[G\VP2BSYTEQL1Z8P$U-TE)M#',SS=QF:;,%!X>FAS*\$LTE:N;-E6JH>UCSZ1^*'21$RTA7<71W\*'6M7UH/$P-#82?]^*:&%&S?D\9SP=W8 -M=U"D#*O8TJ'PI?QPA5Y[1`3&LES]V4]=\A6GM]#HQ+($<>?RFPOA_\/#^3H) -M9M3;PAY%/JU7%9Y??]05JHLVQ:NH:N_*K(KT^-\AHXKO`8\.G#76!Y?X:87E -MA&>X_XI=4RLM_#NXEY+K_W!;ZRW]"9D4GN7+!"*$"@E$<G,@,C`8B[OV4TA+G:`EC40T>@O"IY@;Y\2/JDD=V1M![(CNP(_,E2-0U^CX,9BJE=-CP^H-4\+4& -MD]^J`VAH[`_"EO\Y>#/O3GZ<`Z:6=C5[_!MCXBCD:8T=_894T$+.WU/1Y`8*W?RV7BIE:8CE&#G* -MKAR=I-M!\(2SH1`)U-_43!QP@2?TY36!`,FTEU"+G+UR\DX'0Z_/'SUZY'L\ -M<0WB\\&R.5`B`PTC#+4,\88"E0R2=P3'KS7/-:4F*.?&)JJ,1Z$$E`D\_G]: -MV`NESW?*QT"[,@OLIS&%#DX>O6[@;#9Z`ZT%+:?63G07XHA.O=(S8L_LA_@> -M\]+1T#1TE;]'*1$!&)GM0DS/_Q)^T>D@@/DD!>X+:`L4GV%@V((T>B"H_:6L -M;'9EB0&Z^8*/S-%;`K&EHFW1R0IJ1>OW_*'\4"G9B!S)($G=ZU?\%SA7*9M^EL80./SNR$4)E*K:0!TT,*59F65;WNQYN2Q.Z,L"-H?=(U3A>/=1R/Y!KMGFG!/%DY8V50XA+>J82,Z"D#JFCD'!XZBB48\M\!4L<-&XPOV&.MBD.".V.?&$P1P4SEWX]XVYY -M/DM9NEM8RJBP@JX`MF#PDC*4T$Z1ZZ%(V_XY#NX1+B8%\ZL>P(`W9GWOQR7: -M

    +8<3CD!K`P6["#A8H,+&2R38"$I3JG>X/>XN:(7?G\R3GA;7`/=)[X,@S -MH"RE$#HVN0_>N!D3^9IE^DGBJ9V+YJM@YIK6_%4=OUV8U!^^(JX8"/)T`5%& -MTDD1HCVQQU=MDJ7]J/"5:Z4Q!0D@T'X=<[2(L_>PSMH*)HHVI-L$?3^",O.& -MT)16KLM`NPY``"J9YM+&Y^@'!?(+IPXR-`84ADYF:`&7!(*#Q@Z]BBE@.1:A^OSG:9$M^[];\N@Q3(X+W -MLW3&;=A2([8<"3P>I95^!NIMJE^YJ5&S6(J`/T!2S-,' -MD6)@'GHT\L_2HV$04ZU\SOE')DN?ASL1NN^^7:V<[)Y\I*EYV;0WS5FYD3!6KRFYFE5CFI??*J -M-\ZJE,,<%,A9'!"O8)6/WUW=W@R<[=$$<1D1#G@4N:YEA(!4?2'_\H4)K'I` -MKQX_T=8OD1V$QU'F.652T;$^E!V!\%GRF>6J@J%#FTW+I/CY_;U,E7%R2F"W:/F]OY -MT`W/7T#4Z=_;LS/5@2B`\A(2,WZSA?974DF3$<^RA?!ACA!^T/=BR4X+!8F3 -M^V075'/DF0UX9\E0VYNLUQJ.-$%SA9?S -M?8%ZQ#'_7KP%^D[YB#`YBS9'R-1]I1"2N1X`F!NO\Y -MU2FW]K[:,QOI# -M>G6&B3`V%ZV1>]#E':8;?F6OG8V^TQV;15_5-.W1-`CK,=C))^_Q_AF]F.H1 -MSAN"WK^*@1VTQ-&^[`74F:5-]?1;2U:NB`W][#)$@S:G:#QRQ9<)?V;4ZD7! -M-M(9_<.&X+E3&KHS/ZT,"@J!4[HEGW.#\NPS=&7V&Z>>=?0"-TW"#E7/V3CW -M_*1@*VI;B@^?21EF6?.^)_UN@CL82I]HIT<;:R<>@2+;+#RMMY6I*/U]FZGQ -MINO=(L/3*#_E5U3,F\8F_^)ZI`^%#0TR`*7(=M'GAH1Z&W%%SMK%$S(`QE,* -M^6?.6MVVEA^H`Y>:`Z^<*,$Q<"02QX)QTZ;O9%YPH;K('*2`L;>F?*ZC0C^Z=G4^9(Z)%V9Q"G7_SY -M3!5I`B]/7H@7U]O`LQK!E,?3E$805$)KX47&Q-WX3RB7XV?S87X*S5;_:NQM -M5*7B3"56.2*M9KX!S[ZZR'YP-%++:"-V8:N'\Y%8HAP+$#WA*[C(+H9/)APU -M4E2Z:^Y:R%Z^]Z3`7?QMK@75!*C8YQ^2P+0'?Q"%Y#R%#PY?T$G""_TAOMOQHP89`J)7F\@W+<_BQ/#K!1_L -MAG]AD:E2F-"8]9EGWWO2_;$9R'?7$LL^Y]2H60AX..N#3IS1:;`LGOI![!L;C&Y)[`!-[XN#[5[/KF@*1866&"ZCC\[ -M#$*J]$%)"`#2V0FJ(>E2E8+H%]-05@+:Q0^"T&".^`;FHY$`!9IT1 -M:&R$ENRQ2$>1%A#&*R\466G@[JE7IH$`0$QBN#^#<^>3*/4@&>V59O$BH3JP -MKT62;#2"-^$8UR_#`H_[QL4]`XF&>SR3?@@3BX<*_JGC<'%5I0!UKZF7<7PSKFV!,]9X0=>Q\YS"+>G+V;#>"-"%-) -M1:#D=1.TV56\L3$1T/BORY6(_1U4=%8([W3PHIR[N'6+5L.G:NJ`W=78>FS+ -MG)>MXH:?N@U`&MJQ/P!F)D8/IFOA`*`51"H5&SFB:@@E2%,G)!O<[(BW%`Z+ -MFD5DG@I*@0]`X%3[Q1SH?1"=E.^ICW38DTXRZ7,1T=&6/("@U*2!7J)J.,00 -MT&7*=+9DO<0Z3W$.49(DMD':OZV[$'2VB+GR@7\@71JU(9?8F*!<3)&)*)@) -M8"[%UCD/\7O>/4EKE,440IR!+_!)AH")KL8J\Y1[0_LR4`I@JMCEH'M%T)8'[3: -M.7`6S#1:?%1#*>54`%8Z2P4#]S%B&_V61"Y,)("&PB4(`.?[C%?-J(?!-P_V -MKA:8H"G!Q2H].,.F'`T0J5+ZRVZ85AWI*N1B`8XOP7B<'#.;CJ*`G$9U%=O3/OVUF-OYYO3*G0K<[Y"%JX -M!X'#3S>P91<8Y-M-Z(0"Q_5-057,XS7*28Y')2*J7JJ_YD_SM7L@9-%NE)FN -M69TZ[;P-E8#\Y4AARJI`$6'](`O\MU7WIY<+CZ"*D/S-9[.=><+5K5G@WN"` -MB8:KHE*C_Q;\H_)G++W<[U"$K08NWP\U=SCFS"-;X;)SD4^*G#,CA('):_*S -M3*`"[MN"U\78A]Y^<=^7K^$FRTG\'>_SJCL9T -M$M"4ZUHJ/0EA^[PFK7Q;A(]-XN"OH#6$UD_>SG[@H><$6=?N#&-( -M8U!+]F`_72)=<[]`.?T[V@.OXQSLP$L<;_U]<"S%67%`?#N/XP24IE*&:FY/ -M/]><-A.`]LU1CP7C['B^B/\F5@IV24JC-_9TC0V_8E&&P13B^PZ`,.60P+_0 -MYN4)5L%`9^^!G[/#2>670#$FI9ZWD$^H[Q4T5X8!>3*5O-JJJ-@U7'!G(I[[ -M1".^J"/]&L'`?EZ/V4Y=41%=ZW]WF@%YSJW-2(I?"GK[)$+7C@I[D?FE2XJV -M#'61D;M2X2V.KG4IM.HTA(%3TZE:I-U)?SC>R.CBE3.!;1CDHOWK-,3R+('J -M;Q9TK_=H>)E9'=DFIO'7<4DPL-C"JG2$'P$^SO*'",7=;Z4M--IOR+8L77 -MKFY%V);CG'\H4(:WG65D!7T1\L&YJ[;J\Z!!]!>_8L@4\_+%1F)!]--)`88$ -M?&?TR&;0;@%<8[JA=KB)Z^:U5^;UT#O:.WTN^*GWC)M);IF@=[&ANVG)0HN6 -MWI6)5XC5T#-U5/%BTU]+&LQ%-ZL#+31#NZ,W6^VLT+E"2XDPCM]2D?N.6=O3=E'0I3B+-)_8 -M8N2D[;@(>GVU8<>K^H:>-3)/469((HJ<;6CJ=KK2X!'!\58]OVRT\[1DV%U] -M]+;#PU7;O9`@&L;N0[U2Y@W2A-BOF`(W&&K0H,S2"5<>AR;@*^<,IOOFQ!U'L7^$Z\_D.?L;QY3J$>,W -MN$Q\]NFT?*;NZG_M#+:\_QZ[S7@V;?[0&J6__G*)]4W)`\_0^XZ/R3:#K@K6 -M:\'O[:!@B5S11B6L!7`+;.HUC9J$NGM(-^_$H//_Q^>`S:\O3"18!4__4F7R -MH')EA?'O33NS:7&?NTW9`?JJ6LS?_X^IPYJ!Z-0=WP[O,1K_W1`?[$7WE-XB -M.2OL-@GHY[[M]81'*WAM.[/'#)RHM!IZQG]$)PR][O1P[*4$8GX.\RJC^Y!) -M@8_V`(]5%ZF?!0$W5GHLA@ED:VDN?@V[C,*97#R42-NTMYJN?T'&^9*DHBGS -MW7<>Q=B%,(O&;%V222=;"N<4?;@TEI_N7=;L5%TK7H#G%&V$0W![+EJ#/];- -MJ5_:YB?0ER`ESRD3-"*;?]I8P?4?,0/%B;.-+Q*NFZZJ,3HU)%7["@!H"059 -MC#IY""-+"[C-/08(4I>EA*`;@(<$$AKE?.DQ,&/UQ0/K.V5HX5`-"?VMV*WQ -MP$G>?H1+KU,LQ3-+`GS.=>!$H2PGKS.OOBUK-<9'X/"]'FR$S]Q4S@]C"MUX -M84HP;6F6I$9PY<5N.A]:,3AT2Z:7X!.LW"SGLX&1WZ^6:U5`^%VJ*"HJ)2Q> -MR<@`'/+UQN+QY`D;S.@[Q97M"YI^`V2LX019:A-4J-C<8;Q+2=O_VI+4_CYU -M$P$T]ASI5Z2NP1\(W4NS*/O8Q1Y6/EUN*]U($#<#']T?-7OZBK:C5*8$#\.\ -M`.?4B6B?0H.VGOEB?`0L$[CWO0RV;PQG[]YO4([OS^KUC!*VS;,:7,B@%/B- -ML,D]E.)F'Q)BX=J>QGX66+-A([-<4XT!"502XQSFA0'$.ZXX!39$L*F)I?UU_TX"L.M-<1SPH)CSO_O -MA8MW[+D&\>VQP,&#GUYN7_]:`O*R:X7CX8Z!!BVU2QBP<531RE'BN,(?(.K$ -M_/1ZJ6?\ZWC_%H$EZBK^[><0D/]$7S^D?T.:$(4@*$_V -MZ(`````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````8``````````````````*$OPP`Q?VO4_^?______________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_______________^@$?\B__K'_I_________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_________________________________________________________Z!' -M_(O_ZQ_Z?___________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________________________________^@3`'1%0R-%\6=F]S/A7.S -M5W8"T;9`[O=G2*&IP\3W2`(833>H2:8/`,[&-M/&Y!GWK4@ -M,-D75WT2#SF#E*Z5VOR5^KBL`````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````````````````````````````````````````>K] -M7T\[_GZN?T/^/I_GT/4O.Q?SYW0Y_K]^YZGQ].4NQT.+`?0]2.AT80FY^38M -MC-UH&0]R&?>\/3Z/1^X4ZT^!N4Z4:9*:-$CN+!,AN>Z5('3INPWS_NJT>I`Q -MEA^_#-(OO7'F?`N31Z78C35VD7F4.&08ONMK'Z/IW^>?SOHYT6)%!7H['=ZO6]0\WN9L] -M'/S_R?R[&QY8,@B&!L_=C>&?P",_X=^*>'IUO9+ -M!I_[\_Z8<@.GXJ4\>CJ)&GB\`A!8TU=.$"I:?N=I]G]/<]'-T^M!=`D`XCE8 -M!JN7'E&K`DR"8\?V]-7J,5K7UQ5'<+]FEU.;$!Z4&1SM88*"?3W?+[\X)U>A -MH^#]#>$#56&'M?;J>.KMZ57@N-):N7[XVZ;1QQ;]1WA815)8\@RDMF"/+!(/T>IU? -MWK4OKS=:NG&%]=]*GRD($O%=%K]D%*E2C([A*)0WS=*OR3)?UZJ?1?%ZO+K] -MD&B@AY_W88M'73TMN!`>QOM7_-,4)_7>&W]L&3[?T^O_CYNE>^5_+W/_:R>8 -M&Z.WI9_@C:M]"Y\/W4G'3^Z+?@@J68M.)BZ/`ETX[^-^Z"[SJSX,)F&O/0HZ -M0PV66N,;O7>B\5ZX_>#AUFU*WVI\?&E]W:O[6[?0GQJ>MOWGAI^V)\"68D>& -M2/QE?L_#D"*?D5ZV<\L]1++_QO/P@DUZM6?[Q$%DXZ$[R\N0FZ([,@15!+0L -M!=9%K?M7= -MA:YU^7TJN7R`O'VY%71U(S)-WO;4&+1*YXM.65%X90P;)CC4=H$29N95RL -MRS#O),+>/5R.$9X*^/#N=GV$-TE:7,^."D3YWR48+\6.9(7^'M%":>`)GZ4R -M:N*>"^03M8ZJ74[FGT3>#9D960OE@UX%O&6._ZNJYLCB!,W-B\[)W7['!:PB -M\'XY%V/XRP=KA./R6^X<`T;BS9D,V"+I;FS-Y?XJ$K73X^QY*R2."*'P;UJO -M7E$H&N\X@/C%[1L5_;U7SR]WCO/9):4Y?(EI+>S$%V\]''EIWE6,$>6(O@+3 -ME[G#\?");LM@E?-3?CP*;D*S(U:ON4N?E<%T8)JF54U2VJU7FD,O@Z>QJR-2 -MZ]$'[.JA1.GM]KK]*3WMIN@Q8]9=O^N=OZ0OF$'83HEE&QW&8=Q9SC&7(HZ! -MT\56]-ARZ0CWLE=RG0:U[2V)E.'_K,KXFGKD,JPH2W)[CP\?_D'<+S8C_%+] -MEF32B&FU2Y,@:1B;SG3MZD%#;'BC"9%TM*_796%NG31&MW62'&8VV7G2&W*2 -M8_"I^'X>SX96^#80^^+?/@?3A_FU&%BKB"A6'M_R+O`W;3UFK8'X@2EPRF"B -MB.C*H#7`0[(C!G>Y?E@TZ^!XL9IZ9E*Z5Q"L),WOXAO=#HS/?P^GS03$?ROO -MBVREKR,\I>K(/.)^J/,R(!][,]7T6A38[L;5*M -MPVE56+MFK`W=K>U(0(/$!VRF)'4[YX]$*QA:#)'L^(WZY)E"Q)1K^B:IO3ZK -MA@.6L6=`"_YLZ(0Y&3%,0_)L67=S;-O4#B,0'6 -M)R[=^,ZP/SWX0 -M@&.8'L81\%H:KS8?+YM;=WC9+O^/@B!''YT.F5OPU\[;]SX+9M#%'>I]%&&W -MG1`U:.-"-[8';;(*FK?I\/LS.-T9XCHO61;2M@$\`6CG'QY4.\P!GUA3?ITK0 -MCW<&SL8L,37TB/+XZ90SU^_0EB>ZOK]_1MDA*F4]:`/,ZQR;5C2@1O+7Q/$52F4OGN\/,_'+"G,R[7/2I -ML$FBRTX>+,"R`D5>')8'I&,]:7?]56WD.)^0#G"0U,68W%CE(W]/6PQ0MZ). -MEB[;?2AL.OC$%1A/+!#J/''Z]?K%@_&YC/\*V^;9#_'SSHD]N\V0$ -MIHKP^J$Y6AY=(?^EEA[BZV[/+6@$A"3V*>`XXEYGQI+%"%?@DKWC,5,9XRBG -M(DCB3:DC7,O:X1##E0=;8G*N,KDE4="68,2VHU`0SLDRPH(H$Y%RN%;TG->M -M7CEJU'K(37^^OJ7O,S+C%JL8X<2NN"?]\NON0;:O0Y^=/?!#'GEP9VO@VX(# -MO7]M?X]1HA445@;>0V`BP8$E=-_:ZTAPQIY[9A\I2Q_=L9@>&,5(2KFQQ\4* -M*J.*B+AW*?*`5[E.3JD;5XL%UE<[5R+HJ*^O*J4MBU*7)5S4_#J\_&(UO -MF-HZ@43FIH#,4-FD4T6"!9<O"/P;L9Y0\$;5>\< -M;Q]KP2?\5:G'1*;2JR2L'T?#/L4Z- -MGC21?PUWK.CGG+[7ZT8.C)'8_7G=L6D8=%L9<$O#1RM>'TQU#I3K..2U.S!< -MG1N#^&'R6-J&&N&RG5WZN95X/S(V[ -M2D03%@"S:CD[T],"*J\LOZQ]K+%H3[(9Y<^Z0#>U9D`\NU,NSZ?:N?X/3?QI*:J(L6>($A+QV[!$AQ8)46R\6"NEJ5\U?;TP3K0" -MU=5=I'H=;4U\[\8:5_?#VZO-2-P(!N,YCV/$&*U=*H256[0JSR89H)LY4XPT -M5TM\KS63+<@_!J;63WE0P!Z//K2TON'^XDKUL3+KA -MDX)KB4#CP3?2";-\^G*COB>2.&;FO5]JT=/^7\KM#RYKM7V_K5^E%>[Z/*X. -MTR*_CYZ_0DJ@8/1(I2Q7S@SD>/^WD&=5=70Y2B]C4!5^7+IL)S&C;)5@>\6# -M5ET-3EI4?=W.`GG8I@F2(!!$:V,5]4?O:'3\5?+%^M66W]%&>O!"[MZMB$/D -MRR?VZ4"2L?S$[1D#@=M95,6MKTC\C&%[XM+Y[N">&]*BY9?3`;8O;M>-B?KQDWU&&LKY -MO*7BN&Z)?.1LJ9O&\SL.%4K;C4F@!9NMF:=/8UM.OVN_[WZR2-K._^\9OGE/ -M8Z4/D)G&82NF::OD)F;4KU#B?LB_ON7)G*2`48/P@BRROKP^*$_2R0G^YH=[ -ML9>R6.]N[.33"H=?,_CT.?FQ98>3V_Y09`[MO>)F+Y9DU7KK_H\=2!=E-_'L[\&W'RYVML>6W -M2B5XVTKCM8$=QWDW7T)C=H/2`M>F>1Z.EFT89XYM6]Y`.74[6+UO9V-#+L2* -MRG?O$G&H]`_8.C5?AT",*;PS'GFM70XN>WV4Q427^(`*\/X#CB^ -M$(`_Z;QM?B78W;%ULSQ]SP7'831UC7'T-)1'M@\&T\A :U"^,-";S5OB:6 -MG$,M^1P8+(5[>J-K6.5*L'$0+)C=0HM;#!4F--U/NZDV&E#R0UWL[7NQTR?( -MK-5,,P+(U-G9HX8/FZ7$?96E_ZGDBWBI,:/#Y=^S;#LY:>^CB6&-NY)Y7X[_!HZ6Z,D&]`WT!%WRJ<9];OD]9 -MY>24+=]B3T1H[A.%^F.1/,DM#4>!\9]0K>"FYBN[!+*PDPZ'TMGH"-NLKU?X -MK&8!'XW9[RE.P5>/,E6Z?%N:LC`<1CX,4F<@B!KO78!YO$IQ`''Q7JO"IX\? -MBBR#]:TMSQ5EEG7D[+^G+:=BG2QFL>/BO -M-QZJZ$.H`J_PPEC.-JXBK7]T=G#'\]ON_/CN":U"TF8LK:^LVXWN3E`F6;_# -MF@\C#/D]9LWKT#%HA\3BFCW4MIP#\!5<]$0Y$=*]?;JE'.^>7#5O5WUX9)44 -M:))UM76AT?_M55^=35MH -M8SBP1JTK'D6Y=#^?WQI>=*9C8FR=6JV)]+T%__'6]A[DT)F]% -MM.9/8%$580S)=?9\16F`[F7>"]22&A^BE$`:%]89YK8LMX4\?*>YWLG)25RK -M*.K)901`V]&IJZOJ1J_6GW!LR>I^"`[07J:]@%V?5BQJ?SP/;WQ=6$)VG)G> -M,CD;"*2]BO';UTABY)#56A_?JZ>CVO<+0[/9T^Y#1S1\ -M'1BO@_7G[F+:SX]=K^LYM7V:F+!8@8VWCQE9ON?5'U;4?[#8J%5Z%VJ6=4&'1J4HO;()4E6Z9]B#F&EOGA"Y]OY\)@Z$KQP\]L>4<',^O+3P:'OZ[N0-$59`T+&V[RU6]6;[V-V/2 -M\DOQI9RJV8A[VJ&3N-FHO1'WX^C$`6&2L/DNQK)5_WUI\QDNC?X],*1X0H=% -MT;6[0R[0Y+&X>-&5*QYNCCJ;63LCPVSZ%<=8_&<$7YI5O82X$^Z<##T4I_XS;/-5[M4JN)*<.,PUX=<@21*+8?\@!8`NJL$\VJOXQXJ9_D -M3.WKH>4UTR@[R57^/8HS5-09>'[^!EC_/B&H.[#.Q3A=.O\W-$D=K*48D@J19KZ-UX@W5I(05CF6[ -M[(CXM-/'Q^C,.*&X3^7'/##8'_F>E+Z+.!7!K[5XEI)C,E`)2K9=PC^3W!*> -M/=^JWKV#J"(QKCPP6:'6E9)Y.J(:%'W-59W0K-G+@+-9/@"A""&TDQUZZ*Z!(7K==%W;K&"$J@J -MALS;75>P>"E5\-;N4E/M -M0A%P9LKU*,B)FLB7(LC%+GP-Z^OAE/&,`'46Y6\TGV,SB'PST\;25YCUTI@) -M"8'KR_&OC2FE?A7ZGV6/IWY1];IKK:><9*`-O+^*CC4T2?\3C -M_M'7BFGLD;Y)8-WV+?F70"PKR_K2?DS;!F2K#Q)U^)[$X!XV5*%UYZ=7A]'N -MJRJW(KWG&Y:)'M=LW^%%XYMC7J/SQ2BQFE=9%4H:KU#/U&Z)XW&/F1DY^*&? -MKF)^:[Y;RQ8402:`0.G!SK912WR+3;6S1-%I+>%40ZT<0YQAHQO;* -M\@_]:\Z&\O@X6JRH!7L'0]=%F\#4G+=W3O;]?@ST(*H"J*!>=9,1I"NM^<5$ -M,?M3##_F0@61;>:`LF\VDL')];&<]T56:4]2!OY.9(`/*6V>1@]'8#"*GU77 -M;#NK:^GSZ[&-$_(WYR<(5I51ZVR&>0E=MYM$UWTOV5=5'&,CR -MBKOW;AR"NES,-/?Z>M505*><)/.8)UL,A0CY:\.+IC`GC%8_TJ5_HG*`HW#K&]2WB/L(8";`73ZE8Y;1D(J@(T,=])2H!$P7 -M0R:0/B15*(]<*@J1D[43+>O$MZ$A&')!G0?"`I/RWJEW*L#<#D!I$\V:\",/ -M[J!XYT&0)B+9L6#"$>!0#V` -M*;I#]B(J/TC[I-H4P\V$J3&_7VBB^Z,]'9,8PUO5QM2^Y5?P -M1\:_.IO%T4N"#U2-1H8Z]$6"3B%^+CQZ7CM4]>!+A*F1!\CK@_PCBB3,5V$W -MFK@M_W+2%)';;*J7&Y01`W``3(_X7]KVPYX0A2`H3^W1```````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````%`2_#`#%_:]3_Y________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M__________________________________________________________Z` -M1_R+_^L?^G__________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M________________________________________H$S/],17/Z59'_P````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M````````(``````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -H```````````````````````````````````````````````````````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_large_splitted_rar_ab.uu b/thirdparty/libarchive/libarchive/test/test_read_large_splitted_rar_ab.uu deleted file mode 100644 index 43869789a..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_large_splitted_rar_ab.uu +++ /dev/null @@ -1,892 +0,0 @@ -begin 644 - -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M````````````````````````````````<$P!D15,C1?%69OLS\57)BYD!8-L -M@];U=75W=75UUWO\E7H1>5Y71JE=*[7B5_'25@```````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M````````````````````````````````````````````````````'J_-]/._ -MY^KG]#_CZ?Y]#U+SL7\^=T.?Z_?N>I\?3E+L=#BP'T/4CH=&$)N?DV+8S=:! -MD/EV(TU=I%YE#AD&+[K:W*S.+IFA-XK6PCAG>]/1MA@BZ+>IN -M;?FV/5K\`7._LZLFFI_:#WA^CZ=_GG\[Z.=%B105Z.QW>KUO4/-[F;/1S\_\ -MG\NQL>6#((A@;/W,_?N@?:]/LV?OB5_U%8"A>-<1:9\!E!D<[6&"@GT]WR^_."=7H:/@_0 -MWA`U5AA[7VZGCJ[>E5X+C26KE^^-NFT<<7,CJC//*W-']DS2Z=F9DJ9!0/G6 -M>*0C4\UX8L_]QUUB@T5ZXQ1$-.,&:[?FC]D)`YYNG74?;3U_=?-[G;TM'P:< -MLXKNNL0-/7&R#>I`2I;4COU_54TGF_4=X6$526/(,I+9@CRP2#]'J=7]ZU+Z -M\W6KIQA?7?2I\I"!+Q71:_9!2I4HR.X2B4-\W2K\DR7]>JGT7Q>KRZ_9!HH( -M>?]V&+1UT]+;@0'L;[5_S3%"?UWAM_;!D^W]/K_X^;I7OE?R]S_VLGF!NCMZ -M6?X(VK?0N?#]U)QT_NBWX(*EF+3B8NCP)=.._C?N@N\ZL^#"9AKST*.D,-EE -MKC&[UWHO%>N/W@X=9M2M]J?'QI?=VK^UNWT)\:GK;]YX:?MB?`EF)'ADC\97 -M[/PY`BGY%>MG/+/42R_\;S\()->K5G^\1!9..A.\O+D)NB.S($502T+`7)*, -MXVA30M^,A459Q'!N;6ZY-6C.JLQ%/Y52F+3EE1>&4,&R8XU':!$F;F5"OCP[G9]A#=)6ES/C@I$^=\E&"_%CF2%_A[10FG@"9^E,FKBG@ -MOD$[6.JEU.YI]$W@W(N.VC[-#'%XX%/;/1[?R_J]$^'*EK5"=SZ]M-^"&:S1 -M.;ZGV]C8C&N]&YQ8O$9DVMW&$,ZZ1FT%>RLK\VW58,-CWZB"XF"IO-.*_;$R -MS".=Y5A(MHK9-5OF.6&E)2(BI"WSE*K5QC`O^9R67Y]C5FY)L.*-/U(/D;#* -M)DM75HT%ZJ9OTK,WF9&5D+Y8->!;QECO^KJN;(X@3-S8O.R=U^QP6L(O!^.1 -M=C^,L':X3C\EON'`-&XLV9#-@BZ6YLS>7^*A*UT^/L>2LDC@BA\&]:KUY1*! -MKO.(#XQ>T;%?V]5\\O=X[SV26E.7R):2WLQ!=O/1QY:=Y5C!'EB+X"TY>YP_ -M'PB6[+8)7S4WX\"FY"LR-6K[E+GY7!=&":IE5-4MJM5YI#+X.GL:LC4NO1!^ -MSJH43I[?:Z_2D][:;H,6/67;_KG;^D+YA!V$Z)91L=QF'<6TMB93A_ZS*^)IZY#*L*$MR>X\/'_Y!W"\V(_Q2_99DTH -MAIM4N3(&D8F\YT[>I!0VQXHPF1=+2OUV5A;ITT1K=UDAQF-MEYTAMRDF/PJ? -MA^'L^&5O@V$/OBWSX'TX?YM1A8JX@H5A[?\B[P-VT]9JV!^($I<,I@HHCHRJ -M`UP$.R(P9WN7Y8-.O@>+&:>F92NE<0K"3-[^(;W0Z,SW\/I\T$Q'\K[XMLI: -M\C/*7JR#SB?JCS,B`?>S',6^[-)MF6D!KT>KW$@3(G!Y*G\C\&=M^BCM5E-J -MF5GV="Y?,WTA1]>5[YY2"EY=B@W4D92M\(W)C2X)\'O5]%H4V.[&U2K<-I55 -MB[9JP-W:WM2$"#Q`=LIB1U.^>/1"L86@R1[/B-^N290L24:_HFJ;T^JX8#EG -M+23(L5CWXI0<>E@NCQV!VVR"IJWZ?#W."E69,E;N6D1QA].1D/-@3!LTZ21Y&L3=?!MXT]Q^\ -M"@\2+\AS>QU1C_?(&-AWY&=ZM2L/W5Z*0"EH!E2S="%%-;8U-7%#R0J130TY -MF=2OSU;-&S'+CANGK,SC=&>(Z+UD6TK8!/`%HYQ\>5#O,`9]84WZ=*T(]W!L -M[&+#$U](CR^.F4,]?OT)8GNKZ_?T;9(2IE/6@#S.LB3I8NVW -MTH;#KXQ!483RP0ZCQQ^G.NO7R*W43+\R":5G4`$X9UVN!,O^03EJW5!F6RN_ -MCS@AW-+>D`;.@372'_I98>XNMNSRUH!(0D]BG@..)>9\:2Q0A7X)*]XS%3&>,HIR)(XD -MVI(US+VN$0PY4'6V)RKC*Y)5'0EF#$MJ-0$,[),L*"*!.1>V8?*4L?W;&8'AC%2$JYLY3DZI&U>+!=97.U4/!&U7O'&\?:\ -M$G_%6G(=&K1N+?F7:"^X,+FCH5:1/&](^6JGIQT2FTJLDK!]'PS[%.C9XTD7 -M\-=ZSHYYR^U^M&#HR1V/UYW;%I&'1;&7!+PT#\R-NTI$$Q -M8`LVHY.]/3`BJO++^L?:RQ:$^R&>7/ND`WM69`/+M7(R0=P=79>:\;L^2ZU9 -M7C+L^GVKG^#TW\:2FJB+%GB!(2\=NP1(<6"5%LO%@KI:E?-7V],$ZT`M757: -M1Z'6U-?._&&E?WP]NKS4C<"`;C.8]CQ!BM72J$E5NT*L\F&:";.5.,-%=+?* -M\UG`5,@7=DJO:WDRW(/P:FUD]Y4,`>CSZTM+[A_N)*];$RW->5"%N%)MZ7V[ -M<6/7'8YOT)*H&#T2*4L5\X,Y'C_MY!G575T.4HO8U`5?ERZ;"K8A#Y,LG]N -ME`DK'\Q.T9`X';653%K:](_(QA>^+2^>[@GAO2HN67TP&V+V[7(QR=>TA6TZ -M>QV+DJQ\$\FS1[L2UE=?&N6+FUY2VEM0D1B#`ZVLGGC8GZ\9-]1AK*^;REXK -MANB7SD;*F;QO,[#A5*VXU)H`6;K9FG3V-;3K]KO^]^LDC:SO_O&;YY3V.E#Y -M"9QF$KIFFKY"9FU*]0XG[(O[[ER9RD@%&#\((LLKZ\/BA/TLD)_N:'>[&7LE -MCO;NSDTPJ'7S/X]#GYL66'D]O^4&0.[;WB9B^69-5ZZ_Z/'4@793?W*S&5AB -MF5(Z+#&&O8R/+QBW.J[5===>%4H>]+N;SP]ZG1FWA[._!MQ\N=K;'EMTHE>- -MM*X[6!'<=Y-U]"8W:#T@+7IGD>CI9M&&>.;5O>0#EU.UB];V=C0R[$BLIW[Q -M)QJ/0/V#HU7X=`C"F\,QYYK5T.+GM]E,5$E_B`"O'+:-/.C,7C^`XXOA"`/^ -MF\;7XEV-VQ=;,\?<\%QV$T=8UQ]#241[8/!M/(1@V6M0OC#0F\U;XFEIQ#+? -MD<&"R%>WJC:UCE2K!Q$"R8W4*+6PP5)C3=3[NI-AI0\D-=[.U[L=,GR*S53# -M,"R-39V:.&#YNEQ'V5I?^IY(MXJ3&CP^7?LW-F7$[3C-T(^][V*[=5!H]Z\N -M_$XVJ5`!,7FP[.6GOHXEAC;N2>5^._P:.ENC)!O0-]`1=\JG&?6[Y/6>7DE" -MW?8D]$:.X3A?ICD3S)+0U'@?&?4*W@IN8KNP2RL),.A]+9Z`C;K*]7^*QF`1 -M^-V>\I3L%7CS)5NGQ;FK(P'$8^#%)G((@:[UV`>;Q*<0!Q\5ZKPJ>/'XHL@_ -M6M+<\5997`>9TB;)JN -MA#J`*O\,)8SC:N(JU_='9PQ_/;[OSX[@FM0M)F+*VOK-N-[DY0)EF_PYH/(P -MSY/6;-Z]`Q:(?$XIH]U+:<`_`57/1$.1'2O7VZI1SOGEPU;U=]>&25%&B2=; -M5UH='_[7,N-ZF/X!*FZ%9-Z>62UC_#NX]Q_PH]BQ_P69O#7E5?G4U;:&,XL$ -M:M*QY%N70_G]\:7G2F8V)LG5JMB?2]!7,!,K("PQ`5(1DKO.+9SA/>%=]V(/ -MGZ/N)Y\$KJ_VYG(^$OJV=X39O\?+M_5>C,V7>,/ONV]K6S9+4LZ2RS38(*`. -M;HP0Y-"9O1;3F3V -M!1%6$,R77V?$5I@.YEW@O4DAH?HI1`&A?6&>:V++>%/'RGN=[)R4E(R+B`?RW1$ZZ1/PN1G*O,52R-R.%R0X0W#%J!]JFZ^CYY -ME0O?(N\.E4652)9GQ?7:_FZ7]:0 -MA=$?>.)E>72RW1(+E:*LHEEZQ-XL[T6N=0G3XB?PL"$3NLIVS%BD#X7O8KQV]=(8N20U5H?WZNGH]KW"T.SV=/N0TV]/0Z?9Z/V=OM]GZ^WVJM] -MKIRJ:?*(N_-@GV(A7UT99*4%UP*5])9V5W[C;XQK!G?1&M=F*E-[9&R)RK'M -MX\96;[GU1]6U'^PV*A5>A=JEG5!AT:E*+VR"5)5NF?8@YAI;YX0N7,.2ORN5 -MV<=:FU]BS9M00Z^)6VM]4`%&SV]I#02>['39/TYXPGUI/."5;5FN2N'"ZY4M -MDY)IKT^YH]NYIM7,PM#0GQ`5T]+L:'=ZO4H'.MUJHR`A*X+#<5G<&N+S1[?3 -MM,5\DOGO;^?"8.A*\7)@G\#!D>+__08+@VG_RO9!Z$@+^0]JQX%,A^*I+D++ -M;=<1HUU*?X?H(RZRD-O&2BL:LAMQO_U]N@4GYF5(J+8Z-L@3K8U[T>U=R\V\ -M93!3F7*[828'L//;'E'!S/KRT\&A[^N[D#1%60-"QMN\M5O5F^]C=CTO)+\: -M6]JAD[C9J+T1]^/HQ`%ADK#Y+L:R5?]]:?,9+HW^/3"D>$*'1=&UNT -M,NT.2QN'C1E2L>;HXZFW-]3:TKMXT9CN(/6C.8Y(D%??*JR$2&K(.QMX^ZK/ -MPIGRKC!1I(?4GW=*6-(/N+!D5&?DG(IV.KT_[Z<*.B]6&\SO=3IQ_`L%SD6H -M0/DDFWX?+;]G?T>SU-.%)DNC!T`Z/:Z_UY$J+I]WW`[W;T_9/L[NA[%T>M[I -M]6YS+X?%'_IOQC.QM*H4L`'"M;'1XZDM7I\=CE7+PU;U=CGVMD#S7YB*PW*G1T_`G=VW7 -M!PJ?0!GED[(\-L^A7'6/QG!%^:5;V$N!/NG`P]%*?^',I,YXFPV -M5XO\6[%WLVSS5>[5*KB2G#C,->'7($D2BV'_(`6`+JK!/-JK^,>*F?Y$SMZZ -M'E-=,H.\E5_CV*,U34&7A^_@98_SXAJ#NPSL4X73K_'#T`'9R#QN6R#L9<:5 -MS#U=5EZ0:''_6+E -M+()3W<*PK*5K^^>=,,ORR`QXS"Y>3L91!!D]6>!\YNJUJ+B/"B.OW;9S0PY- -M[L'<%C#F&E/JB@B&WHW;*`8;:HS[(@1=D6VD -M.(WA2/E)PPU\4&DWNC$-S1*M!@9RNMO!$E8(8PG`/TI.T!;DYUZWW#GGI];. -M^&TM6S>89P.>EE-!5>4UD+0=4@5E=(,GC_@:WH45RH*Z^GG^_6M*!D+I<>`C -M[7(;3L,O#V0T3]>=1R1C=I=NREUG:Y&'*@99):YR$62SH0=V?^K"I=,1:66T -MGW_Z!J/L2=IG2'>;.8I!N8RVA_(VK^<.U-YXP(/)"OOX636''^QU;>/]UM/X -M2(:GB!=8/R:H$^"2\S]K%0:`1U$4MFQD?'@T`I)6/U0O-&6UP?PL8^`O/H'I -MMC,7#ILAUVD11&)?>:M;:M.`?/*DO<`N+O@F>!2]#_-2'+6^YK1*^C*?2E8VY$YF]3%<&M+W9QFR+SJ^L!N\TM8X^OR]O9[FQ/ -M5!MR"?VR%)SK0`HFMR,+F;N/EV.*Z6/:<9)XS$GWCXTU^P,P)MHQ?&K&Y2%O -M=7ILS%\6FY':*JC/F4+^8,-/`U>&N](IPN:$+%?/A_LVM$H$*S -MWRYDMHY`Q`\N\ZZ:^]@]E@G)30YWG7,?!!6_FR-76F%,-LX7W).AA;K<3\1# -M)<,\4`SBY-4_I?^6GDB2G.5K:Y$L9]5H3P^^)_\[7G]OFC7U%ZN^_Y%[.\9W -MZ<&,YTB6R_W9U0E%4"W.D(F0`MFG'^U1[4HMI0?_IYS/(R6AB._6`_8]2E3@ -MVK\FWLQ+$Y&<=MR7LHXJF@O9D8*`K!GFU#CA?Y\8^`&'KKKR?5&3J,8SZLF. -MW:9TU>%-C&(J2X&4V/Y-51[N];@@C_$)]QOJI41PMG982751#QH0:P4**J(A -MAQ"GN?\'P"HX^2H`O?]$\>1DV][P(=XF$MX4B'[*V=[[L>1U/O`59]WYQ"$V -M5+BB'H:UVT(^08NZ=MXMK]S\8BHW_@\1X`4@KZ:BJ74YDI:_`X%_5KGA#^3. -MHE2MYMEP"L7)V:&:!5]\P[0=_$1FYEL7-KV?3C8$V^RSVZIOQ$>\O0^[,^+* -MAY\0H^3O`$R/^%_:[8<\(0I`4)_;H@`````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````" -M@$OPP`Q?VO4_^?______________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M___________________________________________^@$?\B__K'_I_____ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_________________________Z!'_(O_ZQ_Z?_______________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______^@3`'1%0R-%\6=F]S/A7.S5W8"T;9`[O=G2*&IP\3W2`(833>H2:8/ -M`,[&-M/&Y!GWK4@,-D75WT2#SF#E*Z5VOR5I<]-@````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````````````>K\_IYW_/U<_H?\?3_/H>I>=B_GSNAS -M_7[]SU/CZGT>C]PIUI\#N/,^!\/ -MT?3O\\_G?1SHL2*"O1V.[U>MZAYOR6#3_WY_TPY`=/Q4IX]'42-/%X!""Q -MIJZ<(%2T_<[3[/Z>YZ.;I]:"Z!(!Q'*P#5O[KYO<[>EH^#3EG%=UUB!IZXV0;U("5+:D=^O -MZJFD\WZCO"PBJ2QY!E);,$>6"0?H]3J_O6I?7FZU=.,+Z[Z5/E(0)>*Z+7[( -M*5*E&1W"42AOFZ5?DF2_KU4^B^+U>77[(-%!#S_NPQ:.NGI;<"`]C?:O^:8H -M3^N\-O[8,GV_I]?_'S=*]\K^7N?^UD\P-T=O2S_!&U;Z%SX?NI..G]T6_!!4 -MLQ:<3%T>!+IQW\;]T%WG5GP83,->>A1TAALLM<8W>N]%XKUQ^\'#K-J5OM3X -M^-+[NU?VMV^A/C4];?O/#3]L3X$LQ(\,D?C*_9^'($4_(KULYY9ZB67_C>?A -M!)KU:L_WB(+)QT)WEY/MR*NCJ1F2;O> -MVH,6B5SQ:286\>KD<(SP5\>'<[/L(;I*T -MN9\<%(GSODHP7XL_407$P5-YIQ7[8F681SO*L)%M%;)JM\QRPTI*1$ -M5(6^,L=_U=5S9'$"9N;%YV3NOV."UA%X/QR+L?QE@[7"O*)0-=YQ`?&+VC8K^WJOGE[O'>>R -M2TIR^1+26]F(+MYZ./+3O*L8(\L1?`6G+W.'X^$2W9;!*^:F_'@4W(5F1JU? -M!NVGK-6P/Q`E+AE,%%$=&50&N`AV1&#.]R_+!IU\#Q8S3T -MS*5TKB%829O?Q#>Z'1F>_A]/F@F(_E??%ME+7D9Y2]60><3]4>9D0#[V8YBW -MW9I-LRT@->CU>XD"9$X/)4_D?@SMOT4=JLIM4RL^SH7+YF^D*/KRO?/*04O+ -ML4&ZDC*5OA&Y,:7!/@]ZOHM"FQW8VJ5;AM*JL7;-6!N[6]J0@0>(#ME,2.IW -MSQZ(5C"T&2/9\1OUR3*%B2C7]$U3>GU7#`_%*#CTL%T>+DJ]8L -MZ`%_S9T0AR,F*8A^38LN[FV;>H'$8@.LX?T>!M2_'\S.MVAR_G/VL%"@,^G4 -M"N=%Y0?-TLOL=FY3@:\3EV[\9U@?GOPA`,

    YP4JS) -MDK=RTB.,/IR,AYL"8-FG22/(UB;KX-O&GN/W@4'B1?D.;V.J,?[Y`QL._(SO -M5J5A^ZO12`4M`,J6;H0HIK;&IJXH>2%2*:&G,SJ5^>K9HV8Y<<-T]9F<;HSQ -M'1>LBVE;`)X`M'./CRH=Y@#/K"F_3I6A'NX-G8Q88FOI$>7QTRAGK]^A+$]U -M?7[^C;)"5,IZT`>9UCDVK&E`C>6Y/Y\5TCN5MV?<^!Y*D%[^;!P#[4=R5G$C -M'T,<`\OB>(JE,I?/=X>9^.6%.9EVN>E38)-%EIP\68%D!(J\.2P/2,9ZTN_Z -MJMO(<3\@'.$AJ8LQN+'*1OZ>MABA;T2=+%VV^E#8=?&(*C">6"'4>./TYUUZ -M^16ZB9?F032LZ@`G#.NUP)E_R"<$+G.1MQN&41O^>#0SVYI; -MT@#9T";E^4T8INM0VK05*WSG7N*-I/$5.BGK)E"K(*LTJYMW7*0%E#-DIT)\ -M6M`) -M"$GL4\!QQ+S/C26*$*_!)7O&8J8SQE%.1)'$FU)&N9>UPB&'*@ZVQ.5<97)* -MHZ$LP8EM1J`AG9)EA010)R+E<*WI.:]:O'+5J/60FO]]?4O>9F7&+58QPXE= -M<$_[Y=?<@VU>AS\Z>^"&//+@SM?!MP0'>O[:_QZC1"HHK`V\AL!%@P)*Z;^U -MUI#AC3SVS#Y2EC^[8S`\,8J0E7-CCXH454<5$7#N4^4`KW*54I;%J4N2KFI^'5Y^,1K?,;1U`HG-30&8H;-(IHL$"RXYQ21. -MAQ<9'YO,W_.Y$EP]>$?@W8SRAX(VJ]XXWC[7@D_XJTY#HU:-Q;\R[07W!A//^G^D1(YUR -M?'_H@@.0O#%9._OL\-E.KOUF_C24U418L\0 -M)"7CMV")#BP2HMEXL%=+4KYJ^WI@G6@%JZJ[2/0ZVIKYWXPTK^^'MU>:D;@0 -M#<9S'L>(,5JZ50DJMVA5GDPS039RIQAHKI;Y7FLX"ID"[LE5[6\F6Y!^#4VL -MGO*A@#T>?6EI?K[5HZ?\OY7:'ES7:OM_6K]**]WT>5P=ID5_'SU^A)5`P>B12EBOG!G(\?]O -M(,ZJZNARE%[&H"K\N7383F-&V2K`]XL&K+H:G+2H^[NT.GXJ^6+]:LMOZ*,]>"%W;U;$(?)ED_MTH$E8_F)VC('`[:RJ8M;7I'Y -M&,+WQ:7SW<$\-Z5%RR^F`VQ>W:Y&.3KVD*VG3V.Q%\ -MAF-W>_VHUDSTKKXURQ/ISFG9V+O!Q/RKA#/P1FX6;( -MJDHD0DSR$B,08'6UD\\;$_7C)OJ,-97S>4O%<-T2^-YG8<*I6W&I-` -M"S=;,TZ>QK:=?M=_WOUDD;6=_]XS?/*>QTH?(3.,PE=,TU?(3,VI7J'$_9%_ -M?\3,7RS)JO77_1XZD"[*;^Y68RL,4RI'188PU[&1Y>,6YU7:KKKK -MPJE#WI=S>>'O4Z,V\/9WX-N/ESM;8\MNE$KQMI7':P([CO)NOH3&[0>D!:], -M\CT=+-HPSQS:M[R`SL:&78D5E._>).-1Z!^P=&J_#H$84WAF//-: -MNAQ<]OLIBHDO\0`5XY;1IYT9B\?P''%\(0!_TWC:_$NQNV+K9GC[G@N.PFCK -M&N/H:2B/;!X-IY",&RUJ%\8:$WFK?$TM.(9;\C@P60KV]4;6L'R[]FYLRXG:<9NA'WO>Q7;JH-'O7EWXG&U2H`)B\V'9RT]]'$L,;= -MR3ROQW^#1TMT9(-Z!OH"+OE4XSZW?)ZSR\DH6[[$GHC1W"<+],9):&H\# -MXSZA6\%-S%=V"65A)AT/I;/0$;=97J_Q6,P"/QNSWE*=@J\>9*MT^+NP#S>)3B`./BO5>%3QX_%%D'ZUI;GBK+*X#S.D39+E?G/R5Q -MVDR2].O)V7].6T[%.EC-8\?$YFXK!4]>;CU5T(=0!5_AA+&<;5Q%6O[H[.&/ -MY[?=^?'<$UJ%I,Q96U]9MQOKOKPR2HHT23K:NM#H__:YEQO4Q_`)4W0K)O3 -MRR6L?X=W'N/^%'L6/^"S-X:\JK\ZFK;0QG%@C5I6/(MRZ'\_OC2\Z4S&Q-DZ -MM5L3Z7H*Y@)E9`6&("I",E=YQ;.<)[PKONQ!\_1]Q//@E=7^W,Y'PE]6SO"; -M-_CY=OZKT9FR[QA]]VWM:V;):EG266:;!!0!S=&"#G3NF'MV(?L_#H4["UG\ -MH'BM?!S8Y5TM^;!P;>]_^.M[#W)H3-Z+:P*(JPAF2Z^SXBM,!W,N\%ZDD -M-#]%*(`T+ZPSS6Q9;PIX^4]SO9.2DKE64=62R@B!MZ-35U?4C5^M/N#9D]3\ -M$!V@O4U[`+L^K%C4_G@>WOBZL(3M.3.\9'(V$4DY41?$'\3D=O3Q&1<0#^6Z -M(G72)^%R,Y5YBJ61N1PN2'"&X8M0/M4W7T?/,J%[Y%WATJBSFV.L>Y%`TAJG -M;+A@&41W8)?A!FSB3RJ1+,^+ESSZ[7\W2_K2$+HC[QQ,KRZ66Z)!BUSJ$Z?$3^%@0B=UCFQ)+ZA).W -MKI#%R2&JM#^_5T]'M>X6AV>SI]R&CFCX.C%?!^O/W,6UGQZ[7]9S:OLU,6"Q -M`QLYO\N-,=K0^SVWIZ'3[/1^SM]OL_7V^U5OM=.533Y1%WYL$^Q$*^NC+)2@ -MNN!2OI+.RN_<;?&-8,[Z(UKLQ4IO;(V1.58]O'C*S?<^J/JVH_V&Q4*KT+M4 -MLZH,.C4I1>V02I*MTS[$',-+?/"%RYAR5^5RNSCK4VOL6;-J"'7Q*VUOJ@`H -MV>WM(:"3W8Z;)^G/&$^M)YP2K:LUR5PX77*ELG)-->GW-'MW--JYF%H:$^(" -MNGI=C0[O5ZE`YUNM5&0$)7!8;BL[@UQ>:/;Z=IBODE\][?SX3!T)7BY,$_@8 -M,CQ?_Z#!<&T_^5[(/0D!?R'M6/`ID/Q5)CVKN7FWC*8* -M6G@T/?UW<@:(JR!H6-MWEJMZLWWL;L>EY)?C2SE5LQ#WM4,G<;-1>B/OQ]&( -M`L,E8?)=C62K_OK3YC)=&_QZ84CPA0Z+HVMVAEVAR6-P\:,J5CS=''4VYOJ; -M6E=O&C,=Q!ZT9S')$@K[Y560B0U9!V-O'W59^%,^5<8*-)#ZD^[I2QI!]Q8, -MBHS\DY%.QU>G_?3A1T7JPWF=[J=./X%@NIIPI,ET -M8.@'1[77^O(E1=/N^X'>[>G[)]G=T/8NCUO=/JW.9?#XH_]-^,9V+DLJ)\5/ -M3-R/;^5DYZ<['T7X8WN0VK%"CI7!V[^0/=240=VZN7(SMD2M3LZBSJQ&%W1J -M&K>KL<^UL@>:_,16&Y4Z.GX$[NVZ[@.`%KP+G5?VBOC3V%3Z`,\LG9'AMG -MT*XZQ^,X(OS2K>PEP)]TX&'HI3_PYE)G/$V&RO%_BW8N]FV>:KW:I5<24X<9 -MAKPZY`DB46P_Y`"P!=58)YM5?QCQ4S_(F=O70\IKIE!WDJO\>Q1FJ:@R\/W\ -M#+'^?$-0=V&=BG"Z=?XX>@`[.0>-RV0=C+C2N8>KJLO2#0[D19S[E#Y63I1E -M__VGJ(`````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M````````#_V`2\C^C%_:]3_Y____________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________________________________________________Z`1_R+ -M_^L?^G______________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________H$?\B__K'_I_____________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_________________Z!'_(O_ZQ_Z?_______________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -H_____________________________________________________P`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_large_splitted_rar_ac.uu b/thirdparty/libarchive/libarchive/test/test_read_large_splitted_rar_ac.uu deleted file mode 100644 index 0ceeae1b7..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_large_splitted_rar_ac.uu +++ /dev/null @@ -1,892 +0,0 @@ -begin 644 - -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_____Z!,(=41#,T1`!85O9S\*.C/!I9I1:2;N[&-B[`5MIBT,?1836;F[OB1 -M1)I)5B)-+35%IEX-^[X`4GT(E*.1T3,T512)P;F^.L,(DS43'5SOBOB7/\(/ -MW/[]SD1P3SPF!'I,@``````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M````````````````````````````````````````.7X_\>[_'Z.[^I\O\.YZ -M>>OI?P^;^'I__RVDL4?\2G5G_T:?&__KIY7K#H7@A(IWJ%<*'!9%"OLP-!P7 -MAD6BR0E+P\"H8V._E_*C?IFE[04,GALITXYE9I+UTMU/+-*9HF_1./4FOK-SR3*$Q\?,O -MFSQ7M\WQ\F5CX9ZMYX>?&%_>A&']?O\$V'A#;8AY^:-F[!<+R;L;2\W&/WE[NW#\"VZ13S4Z)=:V3Q#TU/+GI-CEU>"-W\DF:9P9/]HUM+9" -M3=,D')VO?T5`Y@0JK9)ZDNJKN55>?RY5NYJSH3JV#6/<3LVRY101KE -MWH:&G!%)MZ=C -MQ\GZ46;81TIWET&%/OY\_FBX9R>/:`QK4 -M2`YO2-X^SCART""SZ,LQY/<=B=%(CDGM?K4>#M4H81.AN\W>+J04IPP'Q7?# -M%+#5X'N,-_RY<;E[QC8;>KIZ!!J6F"=U;'=.2$/9QO\GT1A]9"/UH,N/)6`. -M.U=WM_3Y9F+_?9'CCW45HLW#5?YEQW,@;`6'N49"V:96P+B<=&F)!F.WJSI5 -M#;V/47ZVFGY>/)*@L?%@47T='GNLHR3NG8Y3-!TZ'+]3GRB>+)PE;U"26?49 -M/=@L;K[PEX?V2FO\ -MLBX\]NH+4?O>=K/Q>Y\]82,DI.R70+29M(.239GW[I/W*1+WD^>_)WA[_N!8 -M3J\G>96F?Y,7.FUW>WV_\NUV^[VNY_+Q=WN;7R]O:^;M_OOU+J -MW!T"#%F@O#+?FM'?/6K_M/Q\GE]92>;>;@U'G5+:CS7N]R[6Y:S\IT_MTSA7 -MV>_0UU+W/GL#W%$4_9IDV.UT:(TR\M?7[?SSPS;MION5_N2V)FW:^/NMW/Y^ -M2OBP\&UN_/W/Y2]7O6X6KQ/*0=M,X7KDSGY<05]C5_';_GV]?\&_(EMI[$$0 -M.[L?]=CY=GUO^Z];>M.[V?Y]KN=-D3ZZ`1=W^/S1,5NBMH^6N@/)ETRK%77R -M_,E2%?H9$VOU)L.FP6V?@DP_+RUMF[>.R2A%?SRLL@^_#WX.O705/G6FF)4 -M4T4=ALF9T($3:1-$7*>D- -M%"$=?3N^+5%(_=^.27QEDR"]ZTV@X8_&&>/G>F3@B!^/)-IU:J"_U:B;$#85 -M>RVGU'%[P=WK."_7GXO?&2-F[XM/P$0.B'W9*5]S'?Z?U@:2^'\<$>/8OB<* -M6/R#VVO<0X?!7=?=DRK:EL.*`:89D&](VS"?U/FF$">_C>,B=Z;V2NB&SLN6 -MSNH]$TU."0&_EP"9P8ZF]56_\=XT5W*Z(8%\ZC[&:UCV8_:+VW,O/7*'4,FO -M@'.<6` -M99O;Z<2@48FVBZ,8DT*HLE,P8$A:?WB![D4(A^X<\\"%Y?RR1FS9NX,'%9T5 -MG/1.&1(P.!;HYQM\T>.F%3X^NQ3ZC?EV2J#N[M&Q=GXKPL.Q_XE&[&:;52DP -M2Y.T[-P06OA>#Z"'_(>O+Y,D`@^TN>3Z2#7J4I_FA0>U;LV`UQ0&3&W/HBZI -M0,GEWI:V]B'%YZ2<9K0OJFQ)+YW[7YYIT[AV;J$D)Y:C@.GSYMS--:+GRM*! -M(,_'ZZ_\^#^]E#6NU>CJ"()L?5W_K\'W4>AO8Z&0NS8S7_OT#BWR?XS.,R:2 -M_'Y\9Q/8_Q^3H6FG%/8[&38_G;*NW'*.W)A5=CL]G8_Z>MON_T^S[.S]&N]? -MOP@820/NQWO#]/]O!_V]DOW_Y[/0M'0];'@57& -M!=:%C)$5.+DUG+5/QT^8^CS?[>-NB$/V,E4<7)EZ7(.*]?PTP@@=BA%.&SYV -MO!]WU_)]O>^[P?7(++:^WZZ?#AAT\W[=EG;L3P351#M:+[3$?^\O^HME\&24 -MS_T1G+U1+-Q79*PV'(J5IS:)$+]VKO&E0R'-2I['@H35R:B87H[7:A89L3_V -M,U+)&9;%!L6^-&H?IN^#KCG4CV)YNHA15?],>61*F2!]P:JZ[6%"9,A?`G]9 -MJMO!^'WP:9LPB>G -MOW%?4D\V-E=FM\T^>W#]&KO)IO^I9^&R;K[;\*L#7CZ?:*PN=-JHT;\"UT%)M-:<:NJ$71Y_=FZ\W).4!90 -M;+G\EEX#1J;PR2-L#O-6&E(XK[#KM-8=]C<.;=9O$SI)Y23;'V^>W;R31E:(Q,?#LBCEK$8>6 -M$9M[+H^$B:;'+>[EJJ)]A)U.2]L65(9R>I<#C8;!8>M=*W\_/L?B$S;X3>UO -M(F,]'V<1)_:NAODT_>$:7\>6)[XZ<]'%=EU8T[QXE>QN9@=S24?7&Y[2*>E2 -ME,K"3:<;D"A*_G'&4H5IDR7-$12A*, -MD+W*3C1W/%Y=4FQ%&*83)\NBRQQ'I4A=F*T+^3/-4^FZ?IB,WR?+%&A9>O(7 -M.6/;&:KK2H%3UU>9E.D_@_S[_]/IYW)E;XEL:43.SFZKSR6X=$TH+SSA8+GA -MDWJ]F/Q$#TP`#+]\O%2K-\75L=B;HFA_P9?1+AKSPG2;L$!(2VL(4$_?6AI^ -M0IW!(B3O;79ZPN0?3$!;4UST9BKYP/1-M,3%^DBKR/(:/<.;7KJ^CT9J6&K? -M?E"O&-LR=6RGX9%EM-,(W>/BF\4HB]G+UFY/IEP-HPS!8@UUFXK35!Z(_SAS -MX(*5WQ7S576EW5-_8]'6[E2&KE=VN;X%:[NYM%C1<+NVLN.:!U-C+2"TX;(8 -M4R9WQ55<]'N<^7A.]&;;H2G:#P8PIZMK.3R_N^+I@J)ZUH?6T7MBS$%[-;2] -M,4;LU!8^>>4)DZ[%-/+$+(R;-5"L'_!=I5@5L-VH?27![ -M#)AY9<3HTDB7<6G1UD#6'S!&H+X0YJ?OKBF(13$RUICG"W7=M_#26D/N5 -M,Z0V9I81!N6"9W1")IDC8QTY/]S@S[L^FC$8S\41:#".#%3?,LVB%[@9OO44 -M+^]2Y&W-*^@BU1%`MY[N7=Z)]^&?@M&6F)V"QN;DQ":81BC^''8X[6`O>/1J -MNX"UK[5]VU37^_PD[J^:5V-%:YYL^W;(W9N_WNZ%Y:BU#%_UV!A"VE15/:I>TE"[5M4V\G@ -MMA^[JC$SY>S]%LL?^\%K/H$B>&U`:H!APX&O?;D%)(#TBN7&_=A!A=Z&5]N? -M1IQ>U*\M9P!%SSJ0EY9;BRRM"`)5XZ72OR;/`UL&YXHB5JGR\EHWJT7@%R5G -M)QE[`!E^/RF>#SY9?YPZ8;%\O2ZZ0GE0]^#'&NIG/SR2OVJ:/)N^:ZQ3%4M8 -M]?Z_+\O8AB$.F"76>F9<%4B>?XY`-W?%BE9&; -ML*K1F//PY:4U-V?VN.=`C,_#8L!#5>E%W^7>ZR2+H\/-N@_-"0W>QK]]Y('Q -M:B:5-5YK%!F:;^*G#'LA*+9_IKK#6MV$\$9Z!'==!FHW[)O-636-^?JJ]7T@ -M.>O7J=GX-Z_;EX*SJ'U9U(P9QF@,Q"`W3X!*-7HMGP\[1:?PY.#?]*\W+[Q: -M_[28_V%L^#?/U9N*L\^]:U'7E7I[\\&CPY?)\/(?,:V0=GWUV:FP/O;PC+OX -M9OSR_"O.+1]WI-'4[T^V'9UK=JZ;(4[[Z/6")-H&;V_KY2A$N_R;'*[R)OVP;(F!9:KV%I2CB;Q[V$?(Z -M[JOA>B&U=?##-(7,P9'F%!YZS8EBCUBT2P[5WA]V&:)+B)Y^*>3].?56 -M\>"4AN[F6^&.;ISB=2`5:+A%^0XE:S$@#8WG,%I^7PA.V>D/?>WM6ZE9C4%\..:NA9;B?"N7:X^.=T8M8_ZSH3 -M%?N'.F:UC?DH$6_&DMBZO,\]9>]2@.E)&;7=@D=U)T"42`L>@*>'J+B_Z2\J -MH.]C>LY%PXY-JRK^(RV><-5*2>^7GU'MMT5CO60]I-"DR:>F0FZ.@.KL9B`^ -M=SG5_7R[6[0UW`C%[0OLVE,])F1CJ+3%AG>E$9UD)*3/KR\51NY@58N-][GL -MR5HBGAT+-/74VG?ZE^7:K$N&3VNY(;T42+C+A7N)E!ETP)*'U?!I^.2U;77^G/2F2G#6U8=E"1-5T0C'>CX]= -MQBR)-":?T40W9V-5#TLC:WHO^*!X8CM&UR=CL_13GZ%->5J_.D6O:)QI+)M[ -M9]-$MK%!G,O_R7LV/KFD9Y7B;A8_71]%)I@BF'&Y)COQ'S53+M9#=H$K.!5) -M9KX^++A<-'A]:9Q8F@BZO0,GLRXXB/Z3#1V9-";`%6]5PP:0-':1?@-WQ8?% -M:%C(9C?Y6]:5Z=3&BW)0!;375:#7?5-7MGU%#36?1Z'/V>G -MG5.^=49"A?#[+#F4#HO949#EWQ='-_6]9?=\?/G[7)SKUK%'4Q0$3''E,^4-2OA]7PK:&T8'=D-W*V< -M?GVNSZ>B6X4).M<^P3(LOE36UM-'>9J(-49K[WT_97TJL`31ETP18CSP+Y>: -M/NG1^.37NW,F[YK,[*;EWA"SPH/KCI:14,R7^2%QK#G?19[D>Y((:%(OKH=& -M_4WGT)-<^^%OJ"8,">6Z6KIP;N`T/*Q\=W+J.0?2ZGGO>3C+?+C=$3[%>>'Q77=U8'D -M_]0HL4IF'A:*<@VZ-`R;U5.6*$LW1)8F"09:'%<(?&G`6L#]]>1";IC?4-V8 -M27=ABFSA3D2>9[TWW%3#WIB/@S::>_?O_.!K8N2QC&KC=E -M)1'%X\F[6U0,(EMS<-;TGOCCX9OPV))IGU$Y2 -MFQ,TW>9:O5HFE=.)>[&W.N\"4W__&2.%O9(=V?Z9_2<+!ZMT4,L>_U/WU-4Z -M<]^DK:KD5WE&#$W]S(-*&_+ND -M(&[NFG'M.M%=%:6CVU+$%]0$Q"E_9JQ[_)>O*6A+?&_.9H#OL3ND%-Q1$='4 -MN>/JS:/-C%LC^^@*WASU\C4EU*W<;D -MH!ZM*F5D9#Z+X+8LQDJ(ODFX;GS5A(;6EU,(];V:079.(H)=.?Q?4H1'LB]= -M2Y?^OC_/\^5Y:?0A6/!LIMA"VAS$\_'Q>>'M%FGP?IJ/EN\7,?&9E@!2"G4MDYDN9FH[(?NC?@R=(/K -M>R<&3R1'+WARSK&G[A3QXI$-_;HNY3%,R;D0&I,9*2:U? -MWPU[!?':*;OUK1#=,='VN2YCG!O-B&7X3'9R4W`LC>Q(H4!1SU;LSI"?**"- -M$W3_&Q]\263CN&S1TA';YY95/BI_>IPQ5*AK$(4L!N_;X?;S(!CM5VBJ??]O -M7XV(HQX*TG/V;4M`T7M#>ZSKXQ;F5XPIW'GG\V6VBYKC^*T3\DM^,6X],V3P -MG'R=/9.AKN@`=51G"LJ]IHZH;I]I='PU1EOXY'XJU -M2:;1TR9/*]V/=6")LTZ[AJCE4ZBGEG.3/1EYXE5SSYX'GCBF[!3+_TAAEZ>8 -MLP4IWS:;SZ&^[SU-=_[+TF6T2-PJFXZ!44BM*.PC9$K>/JA\&"AFW64_[#VS -M\LVRWK!\M_H?)L4^@ADQKKU]5#HV8?6LO6[DK -MKXLD'OH5H[=N7X*I^%@NG&P,U8J>]$Y!`Q(HE@#L_%>BZ1S;#W<\\2MGLWT) -M4Q[:P1FG0UF2!#HF2/[\F`MYZ]LC7S,RX4DZM?5$#2QJG)[0N.?8@\P$9-)^0.OMHW,VF()] -M_"@]_N<*U(DS02,0@FJ4'Z.X6-PG8Y3]WX`WR1P9=1]AT[_LS[T=5-U8D=/Z -MM[-1V-^;6YB-QIHS\1OK1E#^H^/%2CSU*]SFZB-O0P7.9&(^"2;U+Z.1_C%^ -M3WOV,>5:-FN$2BNW$Q-H1!I,6B$<+U^\]ML@) -MIJ@TM<4^",E3#'G3A>*%?VW`H%5HFLFX).4Z`.;V?GKX;T]^755<'V<*UC>; -M-[%*;/X0]]!P>WI\4,Y&PE_B_KBY3_KR8A*=V5Y9^":+9OY.2W-%I:#J"YC[ -M#9]&6)@HH1ZHV*<8TFQK2]$+ -M2^(@3/9+1"6W2O)L"JZC)MCDJG+%_;+=UEV.2(I,V[T@EI4_>>,]J)SAMVO/1M>YM-AQ+IY8Q%WYDO:$R9":>2(=(QI-8FT7KC-YVNI^VNP$O'+G7+LUC#W-PU`SJ5TG3!'3-Y$71F&\R -MIAPA-3+KMQ`A.LV>T\I=DWOQD9GR>3!S^2N>6\'-??Y*P]1Z)]:MSNVK3KLQ -MO<_'-NOXQU:K;F)9UV*]@/U`:IFZLT$S[=SKY$R`$N/I:%W^2F4 -M+/B_%C=T!8XU<&6HH&1\D5,IK)()..[F/V(NZ=$2+-2JO?\]\+?^W[DGO?%VZGNTCMOF;O1@7CN -MCW\E)B"E\79I]#\?;E*)GX -M0XO'&S/8K]`A_E[O:W-?VBQ++>W23#MSBS^;+K!B)WYOZGT*KTU5WI%WOQS4 -M-JRU-KG?)+*W\?FK@=&+-$4Q=FH2:8/`,[&-M/&Y!GWK4@,-D75WT2#SF#E*Z5W?Y+GLL``````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````'J[_3SO^?JY_0_X^G^?0]2\[%_/G=#G^OW[GJ?'TY2['0 -MXL!]#U(Z'1A";GY-BV,W6@9#W(9][P]/H]'[A3K3X&Y3I1IDIHT2.XL$R&Y[ -MI4@=.F[#?/^ZK1ZD#&6'[\,TB^]<>9\"Y-'I=B--7:1>90X9!B^ZVMRLSBZ9 -MH3>*UL(X9WO3T;88(NBWJ;FWYMCU:_`%SO[.K)IJ?V@]X?H^G?YY_.^CG18D -M4%>CL=WJ];U#S>YFST<_/_)_+L;'E@R"(8&S]S/W[H'VO3[-G[XE?]16`H7C -M7$6F?`7.ERJ_\NC3.&L[XU<8.@9'&L'1%!-IUL?&T8$DS.,.S_X.*MFY1YV- -MX9_`(S_AWXIX>G6]DL&G_OS_IAR`Z?BI3QZ.HD:>+P"$%C35TX0*EI^YVGV? -MT]ST4:L"3()CQ_;TU>HQ6M?7%4=POV:74YL0'I09' -M.UA@H)]/=\OOS@G5Z&CX/T-X0-588>U]NIXZNWI5>"XTEJY?OC;IM''%S(ZH -MSSRMS1_9,TNG9F9*F04#YUGBD(U/->&+/_<==8H-%>N,41#3C!FNWYH_9"0. -M>;IUU'VT]?W7S>YV]+1\&G+.*[KK$#3UQL@WJ0$J6U([]?U5-)YOU'>%A%4E -MCR#*2V8(\L$@_1ZG5_>M2^O-UJZ<87UWTJ?*0@2\5T6OV04J5*,CN$HE#?-T -MJ_),E_7JI]%\7J\NOV0:*"'G_=ABT==/2VX$![&^U?\TQ0G]=X;?VP9/M_3Z -M_^/FZ5[Y7\O<_]K)Y@;H[>EG^"-JWT+GP_=2<=/[HM^""I9BTXF+H\"73COX -MW[H+O.K/@PF8:\]"CI##99:XQN]=Z+Q7KC]X.'6;4K?:GQ\:7W=J_M;M]"?& -MIZV_>>&G[8GP)9B1X9(_&5^S\.0(I^17K9SRSU$LO_&\_""37JU9_O$063CH -M3O+RY";HCLR!%4$M"P%R2C.-H4T+?C(5%67(4L1#KH$O:A2=CZ)I=,W#/<=T -M<&R;OD^+GR7]R>;S\[^F=SHQ[7Y?2JY?("\?;D5='4C,DW>]M08M$KGBTY947A -ME#!LF.-1V@1)FYE7*S+,.\DPMX]7(X1G@KX\.YV?80W25IT4)IX`F?I3)JXIX+Y!.UCJI=3N:?1-X-R+CMH^S0QQ>.!3VST>W\O -MZO1/ARI:U0G<^O;3?@AFLT3F^I]O8V(QKO1N<6+Q&9-K=QA#.ND9M!7LK*_- -MMU6##8]^H@N)@J;S3BOVQ,LPCG>582+:*V35;YCEAI24B(J0M\Y2JU<8P+_F -MJF;]*S-YF1E9"^6#7@6\98[_J_5S9 -M'$"9N;%YV3NOV."UA%X/QR+L?QE@[7"O*)0-=YQ`?&+VC8K^WJOGE[O'>>R2TIR^1+26]F(+M -MYZ./+3O*L8(\L1?`6G+W.'X^$2W9;!*^:F_'@4W(5F1JU? -M!NVGK-6P/Q`E+AE,%%$=&50&N`AV1&#.]R_+!IU\#Q8S3TS*5TKB%829O?Q# -M>Z'1F>_A]/F@F(_E??%ME+7D9Y2]60><3]4>9D0#[V8YBWW9I-LRT@->CU>X -MD"9$X/)4_D?@SMOT4=JLIM4RL^SH7+YF^D*/KRO?/*04O+L4&ZDC*5OA&Y,: -M7!/@]ZOHM"FQW8VJ5;AM*JL7;-6!N[6]J0@0>(#ME,2.IWSQZ(5C"T&2/9\1 -MOUR3*%B2C7]$U3>GU7#`_%*#CTL%T>+DJ]8LZ`%_S9T0AR,F*8 -MA^38LN[FV;>H'$8@.LX?T>!M2_'\S.MVAR_G/VL%"@,^G4"N=%Y0?-TLOL=F -MY3@:\3EV[\9U@?GOPA`,

    YP4JS)DK=RTB.,/IR,AY -ML"8-FG22/(UB;KX-O&GN/W@4'B1?D.;V.J,?[Y`QL._(SO5J5A^ZO12`4M`, -MJ6;H0HIK;&IJXH>2%2*:&G,SJ5^>K9HV8Y<<-T]9F<;HSQ'1>LBVE;`)X`M' -M./CRH=Y@#/K"F_3I6A'NX-G8Q88FOI$>7QTRAGK]^A+$]U?7[^C;)"5,IZT` -M>9UCDVK&E`C>6Y/Y\5TCN5MV?<^!Y*D%[^;!P#[4=R5G$C'T,<`\OB>(JE,I -M?/=X>9^.6%.9EVN>E38)-%EIP\68%D!(J\.2P/2,9ZTN_ZJMO(<3\@'.$AJ8 -MLQN+'*1OZ>MABA;T2=+%VV^E#8=?&(*C">6"'4>./TYUUZ^16ZB9?F032LZ@ -M`G#.NUP)E_R"<$+G.1MQN&41O^>#0SVYI;T@#9T";E^4T8IN -MM0VK05*WSG7N*-I/$5.BGK)E"K(*LTJYMW7*0%E#-DIT)\6M`)"$GL4\!QQ+S/C2 -M6*$*_!)7O&8J8SQE%.1)'$FU)&N9>UPB&'*@ZVQ.5<97)*HZ$LP8EM1J`AG9 -M)EA010)R+E<*WI.:]:O'+5J/60FO]]?4O>9F7&+58QPXE=<$_[Y=?<@VU>AS -M\Z>^"&//+@SM?!MP0'>O[:_QZC1"HHK`V\AL!%@P)*Z;^UUI#AC3SVS#Y2EC -M^[8S`\,8J0E7-CCXH454<5$7#N4^4`KW*54I -M;%J4N2KFI^'5Y^,1K?,;1U`HG-30&8H;-(IHL$"RXYQ21.AQ<9'YO,W_.Y$E -MP]>$?@W8SRAX(VJ]XXWC[7@D_XJTY#HU:-Q;\R[07W!A//^G^D1(YUR?'_H@@.0O#%9._ -MOL\-E.KOUF_C24U418L\0)"7CMV")#BP2HM -MEXL%=+4KYJ^WI@G6@%JZJ[2/0ZVIKYWXPTK^^'MU>:D;@0#<9S'L>(,5JZ50 -MDJMVA5GDPS039RIQAHKI;Y7FLX"ID"[LE5[6\F6Y!^#4VLGO*A@#T>?6EI?< -M/]Q)7K8F6YKRH0MPI-O2^W;BQZX['+ERRY&/'M;NSM[%&HQ')&!VW@$W]O9P -M:^EI=FK+;^M81W0]7#)P37$H''@F^D$V;Y].5'?$\D<,W->K[5HZ?\OY7:'E -MS7:OM_6K]**]WT>5P=ID5_'SU^A)5`P>B12EBOG!G(\?]O(,ZJZNARE%[&H" -MK\N7383F-&V2K`]XL&K+H:G+2H^[NT.GXJ^6+]: -MLMOZ*,]>"%W;U;$(?)ED_MTH$E8_F)VC('`[:RJ8M;7I'Y&,+WQ:7SW<$\-Z -M5%RR^F`VQ>W:Y&.3KVD*VG3V.Q%\AF-W>_VHUDSTKK -MXURQ/J5\!K[%W@XGY5PAGX(S<+-D5242(29Y"1&(,# -MK:R>>-B?KQDWU&&LKYO*7BN&Z)?.1LJ9O&\SL.%4K;C4F@!9NMF:=/8UM.OV -MN_[WZR2-K._^\9OGE/8Z4/D)G&82NF::OD)F;4KU#B?LB_ON7)G*2`48/P@B -MRROKP^*$_2R0G^YH=[L9>R6.]N[.33"H=?,_CT.?FQ98>3V_Y09`[MO>)F+Y -M9DU7KK_H\=2!=E-_'L[\&W'RYVML>6W2B5XVTKCM8$=QWDW7T)C=H/2`M>F>1Z.EFT89XYM6] -MY`.74[6+UO9V-#+L2*RG?O$G&H]`_8.C5?AT",*;PS'GFM70XN>WV4Q427^( -M`*\/X#CB^$(`_Z;QM?B78W;%ULSQ]SP7'831UC7'T-)1'M@\&T\ -MA :U"^,-";S5OB:6G$,M^1P8+(5[>J-K6.5*L'$0+)C=0HM;#!4F--U/NZ -MDV&E#R0UWL[7NQTR?(K-5,,P+(U-G9HX8/FZ7$?96E_ZGDBWBI,:/#Y=^S;#LY:>^CB6&-NY)Y7X[_!HZ6Z,D -M&]`WT!%WRJ<9];OD]9Y>24+=]B3T1H[A.%^F.1/,DM#4>!\9]0K>"FYBN[!+ -M*PDPZ'TMGH"-NLKU?XK&8!'XW9[RE.P5>/,E6Z?%N:LC`<1CX,4F<@B!KO78 -M!YO$IQ`''Q7JO"IX\?BBR#]:TMSQ5EEG7D[+^G+: -M=BG2QFL>/BO-QZJZ$.H`J_PPEC.-JXBK7]T=G#'\]ON_/CN":U"TF -M8LK:^LVXWN3E`F6;_#F@\C#/D]9LWKT#%HA\3BFCW4MIP#\!5<]$0Y$=*]?; -MJE'.^>7#5O5WUX9)44:))UM76AT?_M55^=35MH8SBP1JTK'D6Y=#^?WQI>=*9C8FR=6JV)]+T%__'6]A[DT)F]%M.9/8%$580S)=?9\16F`[F7>"]22&A^BE$`:%]89YK -M8LMX4\?*>YWLG)25RK*.K)901`V]&IJZOJ1J_6GW!LR>I^"`[07J:]@%V?5B -MQJ?SP/;WQ=6$)VG)G>,CD;"*2]BO';UTABY)#56A_?JZ -M>CVO<+0[/9T^Y#1S1\'1BO@_7G[F+:SX]=K^LYM7V:F+!8@8VWCQE9ON?5'U;4?[#8J%5Z%VJ6=4&'1J4HO;()4 -ME6Z9]B#F&EOGA"Y]OY\)@Z$KQP\]L>4<',^O+3P:'OZ[N0-$59 -M`T+&V[RU6]6;[V-V/2\DOQI9RJV8A[VJ&3N-FHO1'WX^C$`6&2L/DNQK)5_W -MUI\QDNC?X],*1X0H=%T;6[0R[0Y+&X>-&5*QYNCCJ;63LCPVSZ%<=8_&<$7YI5O -M82X$^Z<##T4I_XS;/-5[M4JN)*<.,PUX=<@21*+8?\@ -M!8`NJL$\VJOXQXJ9_D3.WKH>4UTR@[R57^/8HS5-09>'[^!EC_/B&H.[#.Q3 -MA=.O\#?N]@%)]")2CD=$S-%44B<&YOCK#"),U$QU<[XKXES_" -M#]S^_GGKZ7\/F_AZ?_\MI+%' -M_$IU9_]&GQO_ZZ>5ZPZ%X(2*=ZA7"AP610K[,#0<%X9%HLD)2\/`J&-COY?R -MG,9<&][-=*A#J1#.$KF[F?P\<.DB+#O9I(I'%#N>O1HMK8[TK?GHWZ9I>T%# -M)X;*=..96:2]=+=3RS2F:)OT3CU)KZS<\DRA,?'S+YL\5[?-\?'*-X*HNVBZ -MB-#(6C)YI)`.:;WIE8^&>K>>'GQA?WH1A_7[W#R3=ETS[G#IM%;6-G]XWO!- -MAX0VV(>?FC9NP7"\F[&TO-W-0PY&=**)>?BMEJ+VORC5[@2A^*Z)")FFU2VL -MD<,HVS-5Q28;8:-B#]4]C)V?/=1+HCT>"_3?4D3F5Q[?AX^'AC]Y>[MP_`MN -MD4\U.B76MD\0]-3RYZ38Y=7@C=_))FF<&3_:-;2V0DW3)!R=KW]%0.8$*JV2 -M>I+JJ[E57G\N5;N:LZ$ZG(T`S3L=^#S.*\R[M58C@*>]HYYN&^:3/1DY,&VA -MQ9;V7==AFW`**UPW[P>XXP;\1U)P.\F:KZ!_8]&?U7U)P,I>G8\?'+!\\)/LXX3W'8G12(Y)[7ZU'@[5*&$3H;O-WBZD%*<,!\5WPQ2PU>![C#?\N7&Y>\8V -M&WJZ>@0:EI@G=6QW3DA#V<;_)]$8?60C]:#+CR5@#CM7=[?T^69B_WV1XX]U -M%:+-PU7^9<=S(&P%A[E&0MFF5L"XG'1IB09CMZLZ50V]CU%^MII^7CR2H+'Q -M8%%]'1Y[K*,D[IV.4S0=.AR_4Y\HGBR<)6]0DEGU&3W8+&Z^\)>']G+O_C40 -M"`*(QN]D\8N0O]:LPC6LSNDMZY*>&4C$<$)X7DIK_+(N//;J"U'[WG:S\7N? -M/6$C)*3LET"TF;2#DDV9]^Z3]RD2]Y/GOR=X>_[@6$ZO)WF5IG,82>?DT\'G -M^3%SIM=WM]O_+M=ON]KN?R\7=[FU\O;VOF[?[[]2ZMP=`@Q9H+PRWYK1WSUJ -M_[3\?)Y?64GFWFX-1YU2VH\U[OQ!$#N['_78^79];_NO6WK3 -MN]G^?:[G39$^N@$7=_C\T3%;HK:/EKH#R9=,JQ5U\OS)4A7Z&1-K]2;#IL%M -MGX),/W+O1Y[;3Q**GRSN&^,:+VJW:[_%[?LF_.U=O^';_R_E@%YHHQ;Y'XOT -MS&?<5GB\M;9NWCLDH17\\K+(/OP]^#KUT%3YUIIB5%-%'87*8$.+>ZZ@!:A_ -M'!?!H3$AAUP-')@(>M]WRU$3WK)F="!$VD31%RGI#10A'7T[OBU12/W?CDE\ -M99,@O>M-H.&/QAGCYWIDX(@?CR3:=6J@O]6HFQ`V%7LMI]1Q>\'=ZS@OUY^+ -MWQDC9N^+3\!$#HA]V2E?F]DKHAL[+EL[J/1--3@D!OY<`F<&. -MIO55O_'>-%=RNB&!?.H^QFM8]F/VB]MS+SURAU#)KW+%0A5V9PBC!Y*7%4E: -M2'ZGVNYBF`.,D?GS2S^F8OF'`!*9\NIJ9$;VSXZE_G%P<[&??S^3DHI<4X)C -MX[N6^JI3ZD%BR&US3+R>/8QK95$=^9%6L$M=^QQS8HI;P44G21[1@?Y%"(?N'//`A>7\LD9LV;N#!Q6=%9ST3AD2,#@6Z.<;?-'C -MIA4^/KL4^HWY=DJ@[N[1L79^*\+#L?^)1NQFFU4I,$N3M.S<$%KX7@^@A_R' -MKR^3)`(/M+GD^D@UZE*?YH4'M6[-@-<4!DQMSZ(NJ4#)Y=Z6MO8AQ>>DG&:T -M+ZIL22^=^U^>:=.X=FZA)">6HX#I\^;ST+1T/6QX%5W([>$T_;ER#BO7\-,(('8H13AL^=KP?=]?R?;WON\'UR"RV -MOM^NGPX8=/-^W99V[$\$U40[6B^TQ'_O+_J+9?!DE,_]$9R]42S<5V2L-AR* -ME:QX*$U;J(457_3'ED2ID@?<&JNNUA0F3(7P)_6:G,,B;WK;P?A]\&F;,(GI[]Q7U)/-C979K?-/GMP -M_1J[R:;_J6?ALFZ^V_"K`UW+')CV4K9)Y3H@040#(I`O],;YU8Z=-W^9V_HI -M6;CL[5WX110BV2ZY$HUJ:0U5PV9`%3HN.0@;K,##!K$Q<]_EO=S_8D;`\L'H -M^GVBL+G3:J-&_`M=!2;36G&KJA%T>?W9NO-R3E`64&RY_)9>`T:F\,DC;`[S -M5AI2.*^PZ[36'?8W#FW6;Q,Z2>7)?WYY-_DG0\*AM?>S<\/#$OZW5P+1U)&+ -M^SF]EV]WDDVQ]OGMV\DT96B,3'P['*XWWHHY:Q&'EA&;>RZ/A(FFQRWNY:JB -M?82=3DO;%E2&^.G/1Q79=6-.\>)7L;F8'TBGI4I3',=73GQ5ASD*Q$53U -M#!['W\-U]=2+W+OLS4!)@N:W2,@`O/9H:5HLQFT7X=B>]5."_>/EZ43Q4HA1 -M=//4-HC1>5:A'JPDVG&Y`H2OYQQE*%:9,ES1$4H2C)"]RDXT=SQ>75)L11BF -M$R?+HLL<1Z5(79BM"_DSS5/INGZ8C-\GRQ1H67KR%SECVQFJZTJ!4]=7F93I -M/X/\^__3Z>=R96^);&E$SLYNJ\\EN'1-*"\\X6"YX9-ZO9C\1`],``R_?+Q4 -MJS?%U;'8FZ)H?\&7T2X:\\)TF[!`2$MK"%!/WUH:?D*=P2(D[VUV>L+D'TQ` -M6U-<]&8J^<#T3;3$Q?I(J\CR&CW#FUZZOH]&:EAJWWY0KQC;,G5LI^&19;33 -M"-WCXIO%*(O9R]9N3Z9<#:,,P6(-=9N*TU0>B/\X<^""E=\5\U5UI=U3?V/1 -MUNY4AJY7=KF^!6N[N;18T7"[MK+CF@=38RT@M.&R&%,F=\557/1[G/EX3O1F -MVZ$IV@\&,*>K:SD\O[OBZ8*B>M:'UM%[8LQ!>S6TO3%&[-06/GGE"9.NQ37, -M1C4-PS':FP[,GCRQ"R,FS50K!_P7:58%;#=J'TEP>PR8>67$Z-)(EW%IT=9` -MUA\P1J"^$.:G[ZXIB$4Q,M:8W-::K[6M=T^J(52B=%J]L4J)U3\=$2[!VHSW -M'IPMUW;?PTG#V";W!EX)AI^+$#_FTU<3O/W)EG3>V6_R3=$_ZT-0#)7U:M"Z -M<(K3I?=`#?FD!?FX>BPCZ16;UH?B"PL\RP#7EI#[E3.D-F:6$0;E@F=T0B:9 -M(V,=.3_X&;[U%"_O4N1MS2OH(M410+>> -M[EW>B??AGX+1EIB=@L;FY,0FF$8H_AQV..U@+WCT:KN`M:^U?=M4UW)HJ*\K_HFWOO\).ZOFE=C16N>;/M -MVR-V;O][NA>6HM0Q?]=@80MI453VJ7M)0NU;5-O)X+8?NZHQ,^7L_1;+'_O! -M:SZ!(GAM0&J`8<.!KWVY!22`](KEQOW8087>AE?;GT:<7M2O+6<`1<\ZD)>6 -M6XLLK0@"5>.ETK\FSP-;!N>*(E:I\O):-ZM%X!P`9?C\IG@\^67^< -M.F&Q?+TNND)Y4/?@QQKJ9S\\DK]JFCR;OFNL4Q5+6/7W+`O_IMTJK_X]V"!= -M;/,2#=W82.H'UP1_9'S/4M&;<]U!?_I]D/\2J2#TRA!^A5,#LY[)2HS)O+;& -M;4.YT7NOR_+V(8A#I@EUGIF7!5(GG^.0#=WQ8I61F["JT9CS\.6E-3=G]KCG -M0(S/PV+`0U7I1=_EWNLDBZ/#S;H/S0D-WL:_?>2!\6HFE35>:Q09FF_BIPQ[ -M(2BV?Z:ZPUK=A/!&>@1W709J-^R;S5DUC?GZJO5](#GKUZG9^#>OVY>"LZA] -M6=2,&<9H#,0@-T^`2C5Z+9\/.T6G\.3@W_2O-R^\6O^TF/]A;/@WS]6;BK// -MO6M1UY5Z>_/!H\.7R?#R'S&MD'9]]=FIL#[V\(R[^&;\\OPKSBT?=Z31U.]/ -MMAV=:W:NFR%.W+/?;)Q:._"4/U/$?NYTL5M^!>_TUQ_X=]>++^7N^CU@B3:! -MF]OZ^4H1+O\FQRN\B;]L&R)@66J]A:4HXF\>]A'R.NZKX7HAM77PPS2%S,&1 -MYA0>>LV)8H]8M$L.U=X?=AFB2W-EWHB>?BGD_3GU5O'@E(;NYEOACFZT+ -M[-I3/29D8ZBTQ89WI1&=9"2DSZ\O%4;N8%6+C?>Y[,E:(IX="S3UU-IW^I?E -MVJQ+AD]KN2&]%$BXRW)R\5E;"4`02HSU+;[V8RS3ENZ_P!%QS1#:O["[AFK@ -MTZ0*JN[0B@QDSJ3;Y^K/HB-2?V^'34F]+Q3O[TNI-SJB&5]7WS'7H5[B909= -M,"2A]7P:?CDM6UU_ISTIDIPUM6'90D35=$(QWH^/7<8LB30FG]%$-V=C50]+ -M(VMZ+_B@>&([1MV?31+:Q09S+_\E[-CZY -MI&>5XFX6/UT?12:8(IAQN28[\1\U4R[60W:!*S@526:^/BRX7#1X?6F<6)H( -MNKT#)[,N.(C^DPT=F30FP!5O5<,&D#1VD7X#=\6'Q6A8R&8W^5O6E>G7-=PL -M\=%NW6$WDQHMR4`6TUU6@UWU35[9]10TUGT>AS]GIYU3OG5&0H7P^RPYE`Z+ -MV5&0Y=\71S?UO67W?'SY^URY'N2"&A2+ZZ'1OU-Y]"37/OA;Z@F#`GE -MNEJZ<&[G)!@6+92E+F[GXZFZK%>H8$4@DM2]<9-JPZF2R[AUS.TCL?%#@D]6 -M/!+%,;)EJD&PP0L(FOO>*4-,B'^%IST:K2[)EXK=+2X]4QH[U[YJU;\]N&:E/,(C<_ -MQWU_BFAPS@9G!I=2XAEHSNW4-W1#Z)G@-#R -ML?'=RZCD'TNIY[WDXRWRXW1$^Q7GA\5W*7WEW=6!Y/_4*+%*9AX6BG(-NC0, -MF]53EBA+-T26)@D&6AQ7"'QIP%K`_?7D0FZ8WU#=F$EW88ILX4Y$GF>]-]Q4 -MP]Z7+/VW])HZ,M:3#:=/)T*[%8(L75^`/DFT%/><#4L'0X,Q91V,7SQOO!G^ -M9`?%$/.+J/V1`B?#WHCX,VFGOW[_S@:V+DL8QJXW9241Q>/)NUM7)=XYJZ5; -MUE"+N;!Z15RKBGD#");K=%#+'O]3]]35.G/?I*VJY%=Y1@Q-_"]R4=[9"BXIIU4@!MWS_R7KREH2WQOSF:`[[$[I!3<41'1U+GCZLVCS8Q;(_OH"MX< -M]?'*$0I?/X/D^_8[W]_!*"?IK2IE9&0^B^"V+,9* -MB+Y)N&Y\U82&UI=3"/6]FD%V3B*"73G\7U*$1[(O74N7_KX_S_/E>6GT(5CP -M;'+.,V5L>/#SQB=IBORS'4Q&T;5I4R>2)9:D`O+*O'J;80MH*1#?VZ+N4Q3,FY$!J3&2DFM7]\->P7QVBF[]:T0W3'1 -M]KDN8YP;S8AE^$QV653XJ?WJ<,52H:Q"%+`;OV^'V\R`8[5=HJGW_;U^-B*,>"M)S]FU+0-%[ -M0WNLZ^,6YE>,*=QYY_-EMHN:X_BM$_)+?C%N/3-D\)Q\G3V3H:[H`'549PK' -M+4@9CE'3VO9/:YHS8WJO::.J&Z?:71\-49;^.1^*M4FFT=,F3RO=CW5@B;-. -MNX:HY5.HIY9SDST9>>)5<\^>!YXXINP4R_](89>GF+,%*=\VF\^AON\]37?^ -MR])EM$C<*IN.@5%(K2CL(V1*WCZH?!@H9MUE/^P]L_+-LMZP?+?Z'R;%/H(9 -M,:Z]7+W(8?,H2>E*7>BB1'!MFZGO50Z-F'UK+UNY*Z^+)![Z%:.W;E^"J?A8 -M+IQL#-6*GO1.00,2*)8`[/Q7HNDVL$9IT-9D@0Z)DC^ -M_'+L=;(2M<=7=782%C['Y_1.#+ORC]FP+NCG-W]^P9%)B;@DGI@+>>O;(U\S -M,N%).K7U1`TL:IR>T+CGV(/,!&32?D#K[:-S-IB"??PH/?[G"M2),T$C$()J -ME!^CN%C<)V.4_=^`-\D<&74?8=._[,^]'53=6)'3^K>S4=C?FUN8C<::,_$; -MZT90_J/CQ4H\]2OQ2FS^$/?0<``` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_large_splitted_rar_ad.uu b/thirdparty/libarchive/libarchive/test/test_read_large_splitted_rar_ad.uu deleted file mode 100644 index f736f13c7..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_large_splitted_rar_ad.uu +++ /dev/null @@ -1,892 +0,0 @@ -begin 644 - -M>WI\4,Y&PE_B_KBY3_KR8A*=V5Y9^":+9OY.2W-%I:#J"YC[#9]&6)@HH1ZH -MV*<8TFQK2]$+2^(@3/9+1"6W -M2O)L"JZC)MCDJG+%_;+=UEV.2(I,V[T@EI4_>>,]J)SAMVO/1M>YM-AQ+IY8Q%WYDO:$R9":>2(=(QI-8 -MFT7KC-YVNI^VNP$O'+G7+LUC#W-PU`SJ5TG3!'3-Y$71F&\RIAPA-3+KMQ`A -M.LV>T\I=DWOQD9GR>3!S^2N>6\'-??Y*P]1Z)]:MSNVK3KLQO<_'-NOXQU:K -M;F)9UV*]@/U`:IFZLT$S[=SKY$R`$N/I:%W^2F4+/B_%C=T!8XU -M<&6HH&1\D5,IK)( -M)..[F/V(NZ=$2+-2JO?\]\+?^W[DGO?%VZGNTCMOF;O1@7CNCW\E)B"E\79I]#\?;E*)GX0XO'&S/8K]`A -M_E[O:W-?VBQ++>W23#MSBS^;+K!B)WYOZGT*KTU5WI%WOQS4-JRU-KG?)+*W -M\?FK@=&+-$4Q=FH2:8/`,[&-M/&Y!GWK4@,-D75WT2#SF#E*Z5W?Y+GLL``````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```'J[_3SO^?JY_0_X^G^?0]2\[%_/G=#G^OW[GJ?'TY2['0XL!]#U(Z'1A" -M;GY-BV,W6@9#W(9][P]/H]'[A3K3X&Y3I1IDIHT2.XL$R&Y[I4@=.F[#?/^Z -MK1ZD#&6'[\,TB^]<>9\"Y-'I=B--7:1>90X9!B^ZVMRLSBZ9H3>*UL(X9WO3 -MT;88(NBWJ;FWYMCU:_`%SO[.K)IJ?V@]X?H^G?YY_.^CG18D4%>CL=WJ];U# -MS>YFST<_/_)_+L;'E@R"(8&S]S/W[H'VO3[-G[XE?]16`H7C7$6F?`7.ERJ_ -M\NC3.&L[XU<8.@9'&L'1%!-IUL?&T8$DS.,.S_X.*MFY1YV-X9_`(S_AWXIX -M>G6]DL&G_OS_IAR`Z?BI3QZ.HD:>+P"$%C35TX0*EI^YVGV?T]ST4:L"3()CQ_;TU>HQ6M?7%4=POV:74YL0'I09'.UA@H)]/=\OO -MS@G5Z&CX/T-X0-588>U]NIXZNWI5>"XTEJY?OC;IM''%S(ZHSSRMS1_9,TNG -M9F9*F04#YUGBD(U/->&+/_<==8H-%>N,41#3C!FNWYH_9"0.>;IUU'VT]?W7 -MS>YV]+1\&G+.*[KK$#3UQL@WJ0$J6U([]?U5-)YOU'>%A%4ECR#*2V8(\L$@ -M_1ZG5_>M2^O-UJZ<87UWTJ?*0@2\5T6OV04J5*,CN$HE#?-TJ_),E_7JI]%\ -M7J\NOV0:*"'G_=ABT==/2VX$![&^U?\TQ0G]=X;?VP9/M_3Z_^/FZ5[Y7\O< -M_]K)Y@;H[>EG^"-JWT+GP_=2<=/[HM^""I9BTXF+H\"73COXW[H+O.K/@PF8 -M:\]"CI##99:XQN]=Z+Q7KC]X.'6;4K?:GQ\:7W=J_M;M]"?&IZV_>>&G[8GP -M)9B1X9(_&5^S\.0(I^17K9SRSU$LO_&\_""37JU9_O$063CH3O+RY";HCLR! -M%4$M"P%R2C.-H4T+?C(5%67(4L1#KH$O:A2=CZ)I=,W#/<=T<&R;OD^+GR7]R> -M;S\[^F=SHQ[7Y?2JY?("\?;D5='4C,DW>]M08M$KGBTY947AE#!LF.-1V@1) -MFYE7*S+,.\DPMX]7(X1G@KX\.YV?80W25IT4)IX -M`F?I3)JXIX+Y!.UCJI=3N:?1-X-R+CMH^S0QQ>.!3VST>W\OZO1/ARI:U0G< -M^O;3?@AFLT3F^I]O8V(QKO1N<6+Q&9-K=QA#.ND9M!7LK*_-MU6##8]^H@N) -M@J;S3BOVQ,LPCG>582+:*V35;YCEAI24B(J0M\Y2JU<8P+_FJF;]*S-YF1E9"^6#7@6\98[_J_5S9'$"9N;%YV3NO -MV."UA%X/QR+L?QE@[7"O*)0-=YQ`?&+VC8K^WJOGE[O'>>R2TIR^1+26]F(+MYZ./+3O*L8(\ -ML1?`6G+W.'X^$2W9;!*^:F_'@4W(5F1JU?!NVGK-6P/Q`E -M+AE,%%$=&50&N`AV1&#.]R_+!IU\#Q8S3TS*5TKB%829O?Q#>Z'1F>_A]/F@ -MF(_E??%ME+7D9Y2]60><3]4>9D0#[V8YBWW9I-LRT@->CU>XD"9$X/)4_D?@ -MSMOT4=JLIM4RL^SH7+YF^D*/KRO?/*04O+L4&ZDC*5OA&Y,:7!/@]ZOHM"FQ -MW8VJ5;AM*JL7;-6!N[6]J0@0>(#ME,2.IWSQZ(5C"T&2/9\1OUR3*%B2C7]$ -MU3>GU7#`_%*#CTL%T>+DJ]8LZ`%_S9T0AR,F*8A^38LN[FV;>H -M'$8@.LX?T>!M2_'\S.MVAR_G/VL%"@,^G4"N=%Y0?-TLOL=FY3@:\3EV[\9U -M@?GOPA`,

    YP4JS)DK=RTB.,/IR,AYL"8-FG22/(UB -M;KX-O&GN/W@4'B1?D.;V.J,?[Y`QL._(SO5J5A^ZO12`4M`,J6;H0HIK;&IJ -MXH>2%2*:&G,SJ5^>K9HV8Y<<-T]9F<;HSQ'1>LBVE;`)X`M'./CRH=Y@#/K" -MF_3I6A'NX-G8Q88FOI$>7QTRAGK]^A+$]U?7[^C;)"5,IZT`>9UCDVK&E`C> -M6Y/Y\5TCN5MV?<^!Y*D%[^;!P#[4=R5G$C'T,<`\OB>(JE,I?/=X>9^.6%.9 -MEVN>E38)-%EIP\68%D!(J\.2P/2,9ZTN_ZJMO(<3\@'.$AJ8LQN+'*1OZ>MA -MBA;T2=+%VV^E#8=?&(*C">6"'4>./TYUUZ^16ZB9?F032LZ@`G#.NUP)E_R" -M<$+G.1MQN&41O^>#0SVYI;T@#9T";E^4T8INM0VK05*WSG7N -M*-I/$5.BGK)E"K(*LTJYMW7*0%E#-DIT)\6M`)"$GL4\!QQ+S/C26*$*_!)7O&8J -M8SQE%.1)'$FU)&N9>UPB&'*@ZVQ.5<97)*HZ$LP8EM1J`AG9)EA010)R+E<* -MWI.:]:O'+5J/60FO]]?4O>9F7&+58QPXE=<$_[Y=?<@VU>AS\Z>^"&//+@SM -M?!MP0'>O[:_QZC1"HHK`V\AL!%@P)*Z;^UUI#AC3SVS#Y2EC^[8S`\,8J0E7 -M-CCXH454<5$7#N4^4`KW*54I;%J4N2KFI^'5 -MY^,1K?,;1U`HG-30&8H;-(IHL$"RXYQ21.AQ<9'YO,W_.Y$EP]>$?@W8SRAX -M(VJ]XXWC[7@D_XJTY#HU:-Q;\R[07W!A//^G^D1(YUR?'_H@@.0O#%9._OL\-E.KOUF_C24U418L\0)"7CMV")#BP2HMEXL%=+4KYJ^W -MI@G6@%JZJ[2/0ZVIKYWXPTK^^'MU>:D;@0#<9S'L>(,5JZ50DJMVA5GDPS03 -M9RIQAHKI;Y7FLX"ID"[LE5[6\F6Y!^#4VLGO*A@#T>?6EI?K[5HZ?\OY7:'ES7:OM_6K]**] -MWT>5P=ID5_'SU^A)5`P>B12EBOG!G(\?]O(,ZJZNARE%[&H"K\N7383F-&V2 -MK`]XL&K+H:G+2H^[NT.GXJ^6+]:LMOZ*,]>"%W; -MU;$(?)ED_MTH$E8_F)VC('`[:RJ8M;7I'Y&,+WQ:7SW<$\-Z5%RR^F`VQ>W: -MY&.3KVD*VG3V.Q%\AF-W>_VHUDSTKKXURQ/ISFG9V+O!Q/RKA#/P1FX6;(JDHD0DSR$B,08'6UD\\;$_7C)O -MJ,-97S>4O%<-T2^-YG8<*I6W&I-`"S=;,TZ>QK:=?M=_WOUDD;6=_] -MXS?/*>QTH?(3.,PE=,TU?(3,VI7J'$_9%_?\3,7RS)JO77_1XZD" -M[*;^Y68RL,4RI'188PU[&1Y>,6YU7:KKKKPJE#WI=S>>'O4Z,V\/9WX-N/ES -MM;8\MNE$KQMI7':P([CO)NOH3&[0>D!:],\CT=+-HPSQS:M[R`SL -M:&78D5E._>).-1Z!^P=&J_#H$84WAF//-:NAQ<]OLIBHDO\0`5XY;1IYT9B\ -M?P''%\(0!_TWC:_$NQNV+K9GC[G@N.PFCK&N/H:2B/;!X-IY",&RUJ%\8:$W -MFK?$TM.(9;\C@P60KV]4;6L'R[]FYLRXG:<9NA'WO> -MQ7;JH-'O7EWXG&U2H`)B\V'9RT]]'$L,;=R3ROQW^#1TMT9(-Z!OH"+OE4XS -MZW?)ZSR\DH6[[$GHC1W"<+],9):&H\#XSZA6\%-S%=V"65A)AT/I;/0$; -M=97J_Q6,P"/QNSWE*=@J\>9*MT^+NP#S>)3B`./BO5 -M>%3QX_%%D'ZUI;GBK+*X#S.D39+E?G/R5QVDR2].O)V7].6T[%.EC-8\?$YF -MXK!4]>;CU5T(=0!5_AA+&<;5Q%6O[H[.&/Y[?=^?'<$UJ%I,Q96U]9MQOKO -MKPR2HHT23K:NM#H__:YEQO4Q_`)4W0K)O3RR6L?X=W'N/^%'L6/^"S-X:\JK -M\ZFK;0QG%@C5I6/(MRZ'\_OC2\Z4S&Q-DZM5L3Z7H*Y@)E9`6&("I",E=YQ; -M.<)[PKONQ!\_1]Q//@E=7^W,Y'PE]6SO";-_CY=OZKT9FR[QA]]VWM:V;):E -MG266:;!!0!S=&"#G3NF'MV(?L_#H4["UG\H'BM?!S8Y5TM^;!P;>]_^.M[#W -M)H3-Z+:P*(JPAF2Z^SXBM,!W,N\%ZDD-#]%*(`T+ZPSS6Q9;PIX^4]SO9 -M.2DKE64=62R@B!MZ-35U?4C5^M/N#9D]3\$!V@O4U[`+L^K%C4_G@>WOBZL( -M3M.3.\9'(V$4DY41?$'\3D=O3Q&1<0#^6Z(G72)^%R,Y5YBJ61N1PN2'"&X8 -MM0/M4W7T?/,J%[Y%WATJBSFV.L>Y%`TAJG;+A@&41W8)?A!FSB3RJ1+,^+ES -MSZ[7\W2_K2$+HC[QQ,KRZ66Z)!BUSJ$Z?$3^%@0B=UCFQ) -M+ZA).WKI#%R2&JM#^_5T]'M>X6AV>SI] -MR&CFCX.C%?!^O/W,6UGQZ[7]9S:OLU,6"Q`QLYO\N-,=K0^SVWIZ'3[/1^SM -M]OL_7V^U5OM=.533Y1%WYL$^Q$*^NC+)2@NN!2OI+.RN_<;?&-8,[Z(UKLQ4 -MIO;(V1.58]O'C*S?<^J/JVH_V&Q4*KT+M4LZH,.C4I1>V02I*MTS[$',-+?/ -M"%RYAR5^5RNSCK4VOL6;-J"'7Q*VUOJ@`HV>WM(:"3W8Z;)^G/&$^M)YP2K: -MLUR5PX77*ELG)-->GW-'MW--JYF%H:$^("NGI=C0[O5ZE`YUNM5&0$)7!8;B -ML[@UQ>:/;Z=IBODE\][?SX3!T)7BY,$_@8,CQ?_Z#!<&T_^5[(/0D!?R'M6/ -M`ID/Q5)CVKN7FWC*8*6G@T/?UW<@:(JR!H6-MWEJMZLW -MWL;L>EY)?C2SE5LQ#WM4,G<;-1>B/OQ]&(`L,E8?)=C62K_OK3YC)=&_QZ84 -MCPA0Z+HVMVAEVAR6-P\:,J5CS=''4VYOJ;6E=O&C,=Q!ZT9S')$@K[Y560B0 -MU9!V-O'W59^%,^5<8*-)#ZD^[I2QI!]Q8,BHS\DY%.QU>G_?3A1T7JPWF=[J -M=./X%@NIIPI,ET8.@'1[77^O(E1=/N^X'>[>G[)] -MG=T/8NCUO=/JW.9?#XH_]-^,9V+DLJ)\5/3-R/;^5DYZ<['T7X8WN0VK%"CI -M7!V[^0/=240=VZN7(SMD2M3LZBSJQ&%W1J&K>KL<^UL@>:_,16&Y4Z.GX$ -M[NVZ[@.`%KP+G5?VBOC3V%3Z`,\LG9'AMGT*XZQ^,X(OS2K>PEP)]TX&'HI3 -M_PYE)G/$V&RO%_BW8N]FV>:KW:I5<24X<9AKPZY`DB46P_Y`"P!=58)YM5?Q -MCQ4S_(F=O70\IKIE!WDJO\>Q1FJ:@R\/W\#+'^?$-0=V&=BG"Z=?XX>@`[.0 -M>-RV0=C+C2N8>KJLO2#0[D19S[E#Y63I1E__VGJ(```````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````!_[$O(_HQ?VO4_^?______________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_______^@$?\B__K'_I_________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_________________________________________________Z!'_(O_ZQ_Z -M?___________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M______________________________^@1_R+_^L?^G__________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________H$PAU1$,S1$`%A6]G/PHZ,\&EFE%I)N[L8V+L!6VF+0Q]%A- -M9N;N^)%$FDE6(DTM-46F7@W[O@!2?0B4HY'1,S15%(G!N;XZPPB3-1,=7.^* -M^)<_P@_<_OW.1'!//"8$>DR````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````!R_'_CW?X_1W?U/E_AW/3SU]+^'S?P]/_^6TEBC_B4ZL_^C3XW_]=/ -M*]8="\$)%.]0KA0X+(H5]F!H."\,BT62$I>'@5#&QW\OY3F,N#>]FNE0AU(A -MG"5S=S/X>.'21%AWLTD4CBAW/7HT6UL=Z5OST;],TO:"AD\-E.G',K-)>NEN -MIY9I3-$WZ)QZDU]9N>290F/CYE\V>*]OF^/CE&\%47;1=1&AD+1D\TD@'--[ -MTRL?#/5O/#SXPO[T(P_K][AY)NRZ9]SATVBMK&S^\;W@FP\(;;$//S1LW8+A -M>3=C:7F[FH8QD[/GNHET1Z/!?IOJ2)S*X]OP\?#PQ^\O=VX?@6W2*>:G1+K6R>(>FI -MY<])L.$@#-J\60A8S`RY)V*;Q-O3L>/CE@^>$N6G$T>.>*710.G)7=C:YCT_2BS -M;".E.\N@PI]_/G\T7#.3Q[0&-:B0'-Z1O'V<<.6@06?1EF/)[CL3HI$,;#;U=/0(-2TP3NK8 -M[IR0A[.-_D^B,/K(1^M!EQY*P!QVKN]OZ?+,Q?[[(\<>ZBM%FX:K_,N.YD#8 -M"P]RC(6S3*V!<3CHTQ(,QV]6=*H;>QZB_6TT_+QY)4%CXL"B^CH\]UE&2=T[ -M'*9H.G0Y?J<^43Q9.$K>H22SZC)[L%C=?>$O#^SEW_QJ(!`%$8W>R>,7(7^M -M681K69W26]\GSWY.\/?]P+"=7D[S*TSF,)//R:>#S_)BYTVN[V^W_EVN -MWW>UW/Y>+N]S:^7M[7S=O]]^I=6X.@08LT%X9;\UH[YZU?]I^/D\OK*3S;S< -M&H\ZI;4>:]WN7:W+6?E.G]NF<*^SWZ&NI>Y\]@>XHBG[-,FQVNC1&F7EKZ_; -M^>>&;=M-]RO]R6Q,V[7Q]UNY_/R5\6'@VMWY^Y_*7J]ZW"U>)Y2#MIG"]S_/M=SILB?70" -M+N_Q^:)BMT5M'RUT!Y,NF58JZ^7YDJ0K]#(FU^I-ATV"VS\$F'[EWH\]MIXE -M%3Y9W#?&-%[5;M=_B]OV3?G:NW_#M_Y?RP"\T48M\C\7Z9C/N*SQ>6MLW;QV -M24(K^>5ED'WX>_!UZZ"I\ZTTQ*BFBCL+E,"'%O==0`M0_C@O@T)B0PZX&CDP -M$/6^[Y:B)[UDS.A`B;2)HBY3TAHH0CKZ=WQ:HI'[OQR2^,LF07O6FT'#'XPS -MQ\[TR<$0/QY)M.K507^K438@;"KV6T^HXO>#N]9P7Z\_%[XR1LW?%I^`B!T0 -M^[)2ON8[_3^L#27P_C@CQ[%\3A2Q^0>VU[B'#X*[K[LF5;4MAQ0#3#,@WI&V -M83^I\TP@3W\;QD3O3>R5T0V=ERV=U'HFFIP2`W\N`3.#'4WJJW_CO&BNY71# -M`OG4?8S6L>S'[1>VYEYZY0ZADU[EBH0J[,X11@\E+BJ2M)#]3[7%AV/_$HW8S3:J4F"7)VG9N""U\+P?00_Y#UY?)D@$'VESR?20 -M:]2E/\T*#VK=FP&N*`R8VY]$75*!D\N]+6WL0XO/23C-:%]4V))?._:_/-.G -M<.S=0DA/+4>!1@/ -ML0V9D-?V>YV^[\W;]W+M/Q+E[PP+K0L9(BIQ;_;QMT0A^QD -MJCBY,O2Y!Q7K^&F$$#L4(IPV?.UX/N^OY/M[WW>#ZY!9;7V_73X<,.GF_;LL -M[=B>":J(=K1?:8C_WE_U%LO@R2F?^B,Y>J)9N*[)6&PY%2M.;1(A?NU=XTJ& -M0YJ5/8\%":N343"]':[4+#-B?^QFI9(S+8H-BWQHU#]-WP=<Q/-U$**K -M_ICRR)4R0/N#577:PH3)D+X$_K-3F&1-N9?7>6DR8^^VJH=IKM3"0!4_+9:, -MDXNN&=2G:/O;UMX/P^^#3-F$3T]^XKZDGFQLKLUOFGSVX?HU=Y--_U+/PV3= -M?;?A5@:[ECDQ[*5LD\IT0(*(!D4@7^F-\ZL=.F[_,[?T4K-QV=J[\(HH1;)= -M_RWNY_L2-@>6#T?3[16%SIM5&C?@6 -MN@I-IK3C5U0BZ//[LW7FY)R@+*#9<_DLO`:-3>&21M@=YJPTI'%?8==IK#OL -M;AS;K-XF=)/+DO[\\F_R3H>%0VOO9N>'AB7];JX%HZDC%_9S>R[>[R2;8^WS -MV[>2:,K1&)CX=CE<;[T4/$KV-S,#N:2CZXW/:13TJ4ICF.KISXJPYR%8B*IZA@]C[^&Z^NI%[EW -MV9J`DP7-;I&0`7GLT-*T68S:+\.Q/>JG!?O'R]*)XJ40HNGGJ&T1HO*M0CU8 -M2;3C<@4)7\XXRE"M,F2YHB*4)1DA>Y2<:.YXO+JDV(HQ3"9/ET66.(]*D+LQ -M6A?R9YJGTW3],1F^3Y8HT++UY"YRQ[8S5=:5`J>NKS,ITG\'^??_I]/.Y,K? -M$MC2B9V>2W#HFE!>><+!<\,F]7LQ^(@>F``9?OEXJ59OBZMCL3=$T/^# -M+Z)<->>$Z3=@@)"6UA"@G[ZT-/R%.X)$2=[:[/6%R#Z8@+:FN>C,5?.!Z)MI -MB8OTD5>1Y#1[AS:]=7T>C-2PU;[\H5XQMF3JV4_#(LMIIA&[Q\4WBE$7LY>L -MW)],N!M&&8+$&NLW%::H/1'^<.?!!2N^*^:JZTNZIO['HZW#&%/5M9R -M>7]WQ=,%1/6M#ZVB]L68@O9K:7IBC=FH+'SSRA,G78IKF(QJ&X9CM38=F3QY -M8A9&39JH5@_X+M*L"MANU#Z2X/89,/++B=&DD2[BTZ.L@:P^8(U!?"'-3]]< -M4Q"*8F6M,;FM-5]K6NZ?5$*I1.BU>V*5$ZI^.B)=@[49[CTX6Z[MOX:3A[!- -M[@R\$PT_%B!_S::N)WG[DRSIO;+?Y)NB?]:&H!DKZM6A=.$5ITON@!OS2`OS -M98!KRTA]RIG2&S-+"(-RP3.Z(1-,D;&.G)_N<&?=GTT -M8C&?BB+081P8J;YEFT0O<#-]ZBA?WJ7(VYI7T$6J(H%O/=R[O1/OPS\%HRTQ -M.P6-S_89W^$B1>WM_W]: -M^+Z_O\/VW0PC;,1F-\5_T3;WW^$G=7S2NQHK7/-GV[9&[-W^]W0O+46H -M8O^NP,(6TJ*I[5+VDH7:MJFWD\%L/W=48F?+V?HMEC_W@M9]`D3PVH#5`,.' -M`U[[<@I)`>D5RXW[L(,+O0ROMSZ-.+VI7EK.`(N>=2$O++<665H0!*O'2Z5^ -M39X&M@W/%$2M4^7DM&]6B\`N2LY.,O8`,OQ^4SP>?++_.'3#8OEZ772$\J'O -MP8XUU,Y^>25^U31Y-WS76*8JEK'K[E@7_TVZ55_\>[!`NMGF)!N[L)'4#ZX( -M_LCYGJ6C-N>Z@O_T^R'^)5)!Z90@_0JF!V<]DI49DWEMC-J'+7_:3'^PMGP;Y^K-Q5GGWK6HZ\J]/?G@T>' -M+Y/AY#YC6R#L^^NS4V!][>$9=_#-^>7X5YQ:/N])HZG>GVP[.M;M739"G;EG -MOMDXM'?A*'ZGB/WW]?*4(EW^38Y7 -M>1-^V#9$P++5>PM*4<3>/>PCY'7=5\+T0VKKX89I"YF#(\PH//6;$L4>L6B6 -M':N\/NPS1);FR[T1//Q3R?ISZJWCP2D-W[G*'JXT[=TSK$DBCTY@M/R^$)VSTA[[V]JW4K,:@O -MAQS5T++<3X5R[7'QSNC%K'_6="8K]PYTS6L;\E`BWXTEL75YGGK+WJ4!TI(S -M:[L$CNI.@2B0%CT!3P]1<7_27E5!WL;UG(N'')M65?Q&6SSAJI23WR\^H]MN -MBL=ZR'M)H4F33TR$W1T!U=C,0'SN7BJ-W,"K%QOO<]F2M$4\.A9IZZFT[_4OR[58EPR>UW)#>BB1 -M<9;DY>*RMA*`()49ZEM][,99IRW=?X`BXYHAM7]A=PS5P:=(%57=H108R9U) -MM\_5GT1&I/[?#IJ3>EXIW]Z74FYU1#*^K[YCKT*]Q,H,NF!)0^KX-/QR6K:Z -M_TYZ4R4X:VK#LH2)JNB$8[T?'KN,61)H33^BB&[.QJH>ED;6]%_Q0/#$=HVN -M3L=GZ*<_0IKRM7YTBU[1.-)9-O;/IHEM8H,YE_^2]FQ].BW;K";R8T6Y*` -M+::ZK0:[ZIJ]L^HH::SZ/0Y^ST\ZIWSJC(4+X?98M;C_]N])^(53HZ*8TX($G+]VUY:-9>_'+=/@S=.W5+PHZF*`B -M8X\IGRAJ5\/J^%;0VC`[LANY6SC\^UV?3T2W"A)UKGV"9%E\J:VMIH[S-1!J -MC-?>^G[*^E5@":,NF"+$>>!?+S1]TZ/QR:]VYDW?-9G93%!]<=+2*A -MF2_R0N-8<[Z+/N,FU8=3)9=PZYG:1V/BAP2>K'@EBF-DRU2#88(6 -M$37WO%*&F1#_"TYZ-5N;_3EK6(;/E_=M3Y+>MV.S:-R9R=+2!1:)9\H(>A^8 -M_OI9&OGQN&^O)=DR\5NEI<>J8T=Z]\U:M^>W#-2GF$1N?X[Z_Q30X9P,S@TN -MI<0RT9N9=,@2Y[JZ9@6Y.&CA_ZTU0XO7;J&[HA]$SP&AY6/CNY=1R#Z74\][ -MR<9;Y<;HB?8KSP^*[E+[R[NK`\G_J%%BE,P\+13D&W1H&3>JIRQ0EFZ)+$P2 -M#+0XKA#XTX"U@?OKR(3=,;ZANS"2[L,4V<*F^XJ8>]+EG[;^DT=&6M -M)AM.GDZ%=BL$6+J_`'R3:"GO.!J6#H<&8LH[&+YXWW@S_,@/BB'G%U'[(@1/ -MA[T1\&;33W[]_YP-;%R6,8U<;LI*(XO'DW:VKDN\D]\C)@[=KY,=N\5H47JOL4ZANF2@AJ?QY)>G-Q8UH-+K86YG4L;$8ZFW4,-:S -M/!>Y*.]LA1<4TZJ0`V[YN2DN3TA`W=TTX]IUHKHK2T>VI8@OJ`F(4O[-6/?Y -M+UY2T);XWYS-`=]B=T@IN*(CHZESQ]6;1YL8MD?WT!6\.>OCE"(4OG\'R??L -M=[^_@E!/TN8_8SOQ^=9*P=);;NG!/TN`>3";_*,7[/PTHS/XL]$S*:T;0T?? -M*;5WCEUN5$:=14A&D&D<7DRX1N;>_M=0#F6RTCFW!YY.0>61>#-$51:-G#Z2 -MDQ)OL\G3X6L/SBN[CT:DNI6[CS2"[)Q%!+IS^+ZE"(]D7KJ7+_U\?Y_GRO+3Z$*QX-CEG&;*V/'AYXQ. -MTQ7Y9CJ8C:-JTJ9/)$LM2`7EE7CU-L(6T.8GGX^+SP]HLT^#]-1\MWBYCXS, -ML`*04ZELG,ES,U'9#]T;\&3I!];V3@R>2(Y>\.6=8T_<+D1EBZ8]$09U-5KR -M>/%(AO[=%W*8IF3K=F=(3Y101HFZ?XV/OB2R<=PV:.D([?/+*I\5/[U.&*I -M4-8A"E@-W[?#[>9`,=JNT53[_MZ_&Q%&/!6DY^S:EH&B]H;W6=?&+$X^3I[)T-=T`#JJ,X5CEJ0,QRCI[7LGM?/`\\<4W8*9?^D,,O3S%F"E.^;3>?0WW>>IKO_9>DRVB1N%4W'0*B -MD5I1V$;(E;Q]4/@P4,VZRG_8>V?EFV6]8/EO]#Y-BGT$,F-=>KE[D,/F4)/2 -ME+O11(C@VS=3WJH=&S#ZUEZW[GGB5L]F^A*F/;6",TZ&LR0(=$R1_?CEV.MD)6N.KNKL -M)"Q]C\_HG!EWY1^S8%W1SF[^_8,BDQ-P23TP%O/7MD:^9F7"DG5KZH@:6-4Y -M/:%QS[$'F`C)I/R!U]M&YFTQ!/OX4'O]SA6I$F:"1B$$U2@_1W"QN$['*?N_ -M`&^2.#+J/L.G?]F?>CJINK$CI_5O9J.QOS:W,1N--&?B-]:,H?U'QXJ4>>I7 -MNI?1R/\8OR>]^QCRK1LUPB45VXF)M"(-)BT0CA;F_GW -M?-=7*MFR5-5SM01[FSVOWGMMD!--4&EKBGP1DJ88\Z<+Q0K^VX%`JM$UDW!) -MRG0!S>S\]?#>GORZJK@^SA6L;S9O8I39_"'OH.#V]/BAG(V$O\7]<7*?]>3$ -M)3NRO+/P31;-_)R6YHM+0=07,?8;/HRQ,%%"/5&Q3C&DV-:7HCD*RBIP344+ -MN7SCMU]1`IE!*18+-`IP(57D$KG&-<(7DYQ0\\AF,WYT?P5VI1P:@`L-U3U*G[SQGM1.<-NUYZ -M-KW-IL.)=/+&(N_,E[0F3(33DOBB;SR1#I&-)K$VB]<9O.UU/VUV`EXYYN&H&=2NDZ8(Z9O(BZ,PWF5,.$)J9==N($)UFSVGE+LF]^,C,^3R8.?R -M5SRW@YK[_)6'J/1/K5N=VU:==F-[GXYMU_&.K5;UCW(F0`EQ]+0N_R4RA9\7XL;N@+'&K@RU%`R/DBIE-9)#F4\F%7 -M6COU^S6"\Q11HS\5#NMBWFBG2F\R1E=M,0K5'KQ)QW_DI,04KDYT:D./HU!O:U?RO83D,0BGM3 -M13Y@:P*+>I2SWB[-/H?C[FJN](N]^.:AM66IM<[Y)96_C\U<#HQ9HBF+LSDCZ>`7T -MJ<]9W3BG;N?)\VQ/N4'``W__VG1P```````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M````````````````````````````````/_E+Q/[,7]KU/_G_____________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M_________________H!'_(O_ZQ_Z?_______________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M__________________________________________________________^@ -M1_R+_^L?^G__________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M________________________________________H$?\B__K'_I_________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -H_____________________________________________________P`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_large_splitted_rar_ae.uu b/thirdparty/libarchive/libarchive/test/test_read_large_splitted_rar_ae.uu deleted file mode 100644 index 9f463a4ae..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_large_splitted_rar_ae.uu +++ /dev/null @@ -1,375 +0,0 @@ -begin 644 - -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________________________________________ -M____________________________H$P!T14,C1?%G9O?$J_A%^K]7@Y2NE=W^2Y[+`````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M````````````````````````````````````````````````#U=_IYW_/U<_ -MH?\?3_/H>I>=B_GSNAS_7[]SU/CZGT>C]PIUI\# -MN/,^!\/T?3O\\_G?1SHL2*"O1V.[U>MZAYOR6#3_WY_TPY -M`=/Q4IX]'42-/%X!""QIJZ<(%2T_<[3[/Z>YZ.;I]:"Z!(!Q'*P#5O[KYO<[>EH^#3EG%=U -MUB!IZXV0;U("5+:D=^OZJFD\WZCO"PBJ2QY!E);,$>6"0?H]3J_O6I?7FZU= -M.,+Z[Z5/E(0)>*Z+7[(*5*E&1W"42AOFZ5?DF2_KU4^B^+U>77[(-%!#S_NP -MQ:.NGI;<"`]C?:O^:8H3^N\-O[8,GV_I]?_'S=*]\K^7N?^UD\P-T=O2S_!& -MU;Z%SX?NI..G]T6_!!4LQ:<3%T>!+IQW\;]T%WG5GP83,->>A1TAALLM<8W> -MN]%XKUQ^\'#K-J5OM3X^-+[NU?VMV^A/C4];?O/#3]L3X$LQ(\,D?C*_9^'( -M$4_(KULYY9ZB67_C>?A!)KU:L_WB(+)QT)WEY/MR*NCJ1F2;O>VH,6B5SQ:286\> -MKD<(SP5\>'<[/L(;I*TN9\<%(GSODHP7XL_407$P5-YIQ7[8F681SO -M*L)%M%;)JM\QRPTI*1$5(6^,L=_U?JYLCB!,W-B\[)W7['!:PB\'XY%V/XR -MP=KA./R6^X<`T;BS9D,V"+I;FS-Y?XJ$K73X^QY*R2."*'P;UJO7E$H&N\X@ -M/C%[1L5_;U7SR]WCO/9):4Y?(EI+>S$%V\]''EIWE6,$>6(O@+3E[G#\?"); -MLM@E?-3?CP*;D*S(U:ON4N?E<%T8)JF54U2VJU7FD,O@Z>QJR-2Z]$'[.JA1 -M.GM]KK]*3WMIN@Q8]9=O^N=OZ0OF$'83HEE&QW&8=Q9SC&7(HZ!T\56]-ARZ -M0CWLE=RG0:U[2V)E.'_K,KXFGKD,JPH2W)[CP\?_D'<+S8C_%+]EF32B&FU2 -MY,@:1B;SG3MZD%#;'BC"9%TM*_796%NG31&MW62'&8VV7G2&W*28_"I^'X>S -MX96^#80^^+?/@?3A_FU&%BKB"A6'M_R+O`W;3UFK8'X@2EPRF"BB.C*H#7`0 -M[(C!G>Y?E@TZ^!XL9IZ9E*Z5Q"L),WOXAO=#HS/?P^GS03$?ROOBVREKR,\I -M>K(/.)^J/,R(!][,]7T6A38[L;5*MPVE56+MFK -M`W=K>U(0(/$!VRF)'4[YX]$*QA:#)'L^(WZY)E"Q)1K^B:IO3ZKA@.6L6=`"_YLZ(0Y&3%,0_)L67=S;-O4#B,0'6)R[=^,ZP/SWX0@&.8'L81\ -M%H:KS8?+YM;=WC9+O^/@B!''YT.F5OPU\[;]SX+9M#%'>I]%&&WG1`U:.-"- -M[8';;(*FK?I\/LS.-T9XCHO61;2M@$\`6CG'QY4.\P!GUA3?ITK0CW<&SL8L, -M37TB/+XZ90SU^_0EB>ZOK]_1MDA*F4]:`/,ZQR;5C2@1O+7Q/$52F4OGN\/,_'+"G,R[7/2IL$FBRTX>+ -M,"R`D5>')8'I&,]:7?]56WD.)^0#G"0U,68W%CE(W]/6PQ0MZ).EB[;?2AL. -MOC$%1A/+!#J/''Z]?K%@_&YC/\*V^;9#_'SSHD]N\V0$IHKP^J$Y6 -MAY=(?^EEA[BZV[/+6@$A"3V*>`XXEYGQI+%"%?@DKWC,5,9XRBG(DCB3:DC7 -M,O:X1##E0=;8G*N,KDE4="68,2VHU`0SLDRPH(H$Y%RN%;TG->M7CEJU'K(3 -M7^^OJ7O,S+C%JL8X<2NN"?]\NON0;:O0Y^=/?!#'GEP9VO@VX(#O7]M?X]1H -MA445@;>0V`BP8$E=-_:ZTAPQIY[9A\I2Q_=L9@>&,5(2KFQQ\4**J.*B+AW* -M?*`5[E.3JD;5XL%UE<[5R+HJ*^O*J4MBU*7)5S4_#J\_&(UOF-HZ@43FI -MH#,4-FD4T6"!9<O"/P;L9Y0\$;5>\<;Q]KP2?\5 -M:G'1*;2JR2L'T?#/L4Z-GC21?PUWK -M.CGG+[7ZT8.C)'8_7G=L6D8=%L9<$O#1RM>'TQU#I3K..2U.S!&RG5WZN95X/S(V[2D03%@"S: -MCD[T],"*J\LOZQ]K+%H3[(9Y<^Z0#>U9D`\NU,NS -MZ?:N?X/3?QI*:J(L6>($A+QV[!$AQ8)46R\6"NEJ5\U?;TP3K0"U=5=I'H=; -M4U\[\8:5_?#VZO-2-P(!N,YCV/$&*U=*H256[0JSR89H)LY4XPT5TM\KS63+<@_!J;63WE0P!Z//K2TON'^XDKUL3+KADX)KB4#CP -M3?2";-\^G*COB>2.&;FO5]JT=/^7\KM#RYKM7V_K5^E%>[Z/*X.TR*_CYZ_0 -MDJ@8/1(I2Q7S@SD>/^WD&=5=70Y2B]C4!5^7+IL)S&C;)5@>\6#5ET-3EI4? -M=W.`GG8I@F2(!!$:V,5]4?O:'3\5?+%^M66W]%&>O!"[MZMB$/DRR?VZ4"2L -M?S$[1D#@=M95,6MKTC\C&%[XM+Y[N">&]*BY9?3`;8O;M>-B?KQDWU&&LKYO*7BN&Z)? -M.1LJ9O&\SL.%4K;C4F@!9NMF:=/8UM.OVN_[WZR2-K._^\9OGE/8Z4/D)G&8 -M2NF::OD)F;4KU#B?LB_ON7)G*2`48/P@BRROKP^*$_2R0G^YH=[L9>R6.]N[ -M.33"H=?,_CT.?FQ98>3V_Y09`[MO>)F+Y9DU7KK_H\=2!=E-_'L[\&W'RYVML>6W2B5XVTKCM -M8$=QWDW7T)C=H/2`M>F>1Z.EFT89XYM6]Y`.74[6+UO9V-#+L2*RG?O$G&H] -M`_8.C5?AT",*;PS'GFM70XN>WV4Q427^(`*\/X#CB^$(`_Z;QM? -MB78W;%ULSQ]SP7'831UC7'T-)1'M@\&T\A :U"^,-";S5OB:6G$,M^1P8+ -M(5[>J-K6.5*L'$0+)C=0HM;#!4F--U/NZDV&E#R0UWL[7NQTR?(K-5,,P+(U -M-G9HX8/FZ7$?96E_ZGDBWBI,:/#Y=^S;#LY:>^CB6&-NY)Y7X[_!HZ6Z,D&]`WT!%WRJ<9];OD]9Y>24+=]B3 -MT1H[A.%^F.1/,DM#4>!\9]0K>"FYBN[!+*PDPZ'TMGH"-NLKU?XK&8!'XW9[ -MRE.P5>/,E6Z?%N:LC`<1CX,4F<@B!KO78!YO$IQ`''Q7JO"IX\?BBR#]:TMS -MQ5EEG7D[+^G+:=BG2QFL>/BO-QZJZ$.H` -MJ_PPEC.-JXBK7]T=G#'\]ON_/CN":U"TF8LK:^LVXWN3E`F6;_#F@\C#/D]9 -MLWKT#%HA\3BFCW4MIP#\!5<]$0Y$=*]?;JE'.^>7#5O5WUX9)44:))UM76AT -M?_M55^=35MH8SBP1JTK' -MD6Y=#^?WQI>=*9C8FR=6JV)]+T%__'6]A[DT)F]%M.9/8%$58 -M0S)=?9\16F`[F7>"]22&A^BE$`:%]89YK8LMX4\?*>YWLG)25RK*.K)901`V -M]&IJZOJ1J_6GW!LR>I^"`[07J:]@%V?5BQJ?SP/;WQ=6$)VG)G>,CD;"*2]BO';UTABY)#56A_?JZ>CVO<+0[/9T^Y#1S1\'1BO@_7G[ -MF+:SX]=K^LYM7V:F+!8@8VWCQE9 -MON?5'U;4?[#8J%5Z%VJ6=4&'1J4HO;()4E6Z9]B#F&EOGA"Y]OY\)@Z$KQP\]L>4<',^O+3P:'OZ[N0-$59`T+&V[RU6]6;[V-V/2\DOQI9RJV -M8A[VJ&3N-FHO1'WX^C$`6&2L/DNQK)5_WUI\QDNC?X],*1X0H=%T;6[0R[0Y -M+&X>-&5*QYNCCJ;63LCPVSZ%<=8_&<$7YI5O82X$^Z<##T4I_XS;/-5[M4JN)*<.,PUX=<@21*+8?\@!8`NJL$\VJOXQXJ9_D3.WKH>4UT -MR@[R57^/8HS5-09>'[^!EC_/B&H.[#.Q3A=.O\P!`!P`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_pax_truncated.c b/thirdparty/libarchive/libarchive/test/test_read_pax_truncated.c deleted file mode 100644 index 6a0bb9baf..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_pax_truncated.c +++ /dev/null @@ -1,262 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_pax_truncated.c 189483 2009-03-07 03:34:34Z kientzle $"); - -DEFINE_TEST(test_read_pax_truncated) -{ - struct archive_entry *ae; - struct archive *a; - size_t used, i, buff_size = 1000000; - size_t filedata_size = 100000; - char *buff = malloc(buff_size); - char *buff2 = malloc(buff_size); - char *filedata = malloc(filedata_size); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_pax(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buff_size, &used)); - - /* - * Write a file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file"); - archive_entry_set_mode(ae, S_IFREG | 0755); - fill_with_pseudorandom_data(filedata, filedata_size); - - archive_entry_set_atime(ae, 1, 2); - archive_entry_set_ctime(ae, 3, 4); - archive_entry_set_mtime(ae, 5, 6); - archive_entry_set_size(ae, filedata_size); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, (int)filedata_size, - (int)archive_write_data(a, filedata, filedata_size)); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Now, read back a truncated version of the archive and - * verify that we get an appropriate error. */ - for (i = 1; i < used + 100; i += 100) { - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - /* If it's truncated very early, the file type detection should fail. */ - if (i < 512) { - assertEqualIntA(a, ARCHIVE_FATAL, read_open_memory_minimal(a, buff, i, 13)); - goto wrap_up; - } else { - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_minimal(a, buff, i, 13)); - } - - /* If it's truncated in a header, the header read should fail. */ - if (i < 1536) { - assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae)); - goto wrap_up; - } else { - failure("Archive truncated to %zu bytes", i); - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - } - - /* If it's truncated in the body, the body read should fail. */ - if (i < 1536 + filedata_size) { - assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data(a, filedata, filedata_size)); - goto wrap_up; - } else { - failure("Archive truncated to %zu bytes", i); - assertEqualIntA(a, filedata_size, - archive_read_data(a, filedata, filedata_size)); - } - - /* Verify the end of the archive. */ - /* Archive must be long enough to capture a 512-byte - * block of zeroes after the entry. (POSIX requires a - * second block of zeros to be written but libarchive - * does not return an error if it can't consume - * it.) */ - if (i < 1536 + 512*((filedata_size + 511)/512) + 512) { - failure("i=%zu minsize=%zu", i, - 1536 + 512*((filedata_size + 511)/512) + 512); - assertEqualIntA(a, ARCHIVE_FATAL, - archive_read_next_header(a, &ae)); - } else { - assertEqualIntA(a, ARCHIVE_EOF, - archive_read_next_header(a, &ae)); - } - wrap_up: - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - } - - - - /* Same as above, except skip the body instead of reading it. */ - for (i = 1; i < used + 100; i += 100) { - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - /* If it's truncated very early, file type detection should fail. */ - if (i < 512) { - assertEqualIntA(a, ARCHIVE_FATAL, read_open_memory(a, buff, i, 7)); - goto wrap_up2; - } else { - assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, i, 7)); - } - - if (i < 1536) { - assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae)); - goto wrap_up2; - } else { - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - } - - if (i < 1536 + 512*((filedata_size+511)/512)) { - assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data_skip(a)); - goto wrap_up2; - } else { - assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a)); - } - - /* Verify the end of the archive. */ - /* Archive must be long enough to capture a 512-byte - * block of zeroes after the entry. (POSIX requires a - * second block of zeros to be written but libarchive - * does not return an error if it can't consume - * it.) */ - if (i < 1536 + 512*((filedata_size + 511)/512) + 512) { - assertEqualIntA(a, ARCHIVE_FATAL, - archive_read_next_header(a, &ae)); - } else { - assertEqualIntA(a, ARCHIVE_EOF, - archive_read_next_header(a, &ae)); - } - wrap_up2: - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - } - - /* Now, damage the archive in various ways and test the responses. */ - - /* Damage the first size field in the pax attributes. */ - memcpy(buff2, buff, buff_size); - buff2[512] = '9'; - buff2[513] = '9'; - buff2[514] = 'A'; /* Non-digit in size. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff2, used)); - assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* Damage the size field in the pax attributes. */ - memcpy(buff2, buff, buff_size); - buff2[512] = 'A'; /* First character not a digit. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff2, used)); - assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* Damage the size field in the pax attributes. */ - memcpy(buff2, buff, buff_size); - for (i = 512; i < 520; i++) /* Size over 999999. */ - buff2[i] = '9'; - buff2[i] = ' '; - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff2, used)); - assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* Damage the size field in the pax attributes. */ - memcpy(buff2, buff, buff_size); - buff2[512] = '9'; /* Valid format, but larger than attribute area. */ - buff2[513] = '9'; - buff2[514] = '9'; - buff2[515] = ' '; - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff2, used)); - assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* Damage the size field in the pax attributes. */ - memcpy(buff2, buff, buff_size); - buff2[512] = '1'; /* Too small. */ - buff2[513] = ' '; - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff2, used)); - assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* Damage the size field in the pax attributes. */ - memcpy(buff2, buff, buff_size); - buff2[512] = ' '; /* No size given. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff2, used)); - assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* Damage the ustar header. */ - memcpy(buff2, buff, buff_size); - buff2[1024]++; /* Break the checksum. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff2, used)); - assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * TODO: Damage the ustar header in various ways and fixup the - * checksum in order to test boundary cases in the innermost - * ustar header parsing. - */ - - free(buff); - free(buff2); - free(filedata); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_pax_xattr_rht_security_selinux.c b/thirdparty/libarchive/libarchive/test/test_read_pax_xattr_rht_security_selinux.c deleted file mode 100644 index 609e8d03b..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_pax_xattr_rht_security_selinux.c +++ /dev/null @@ -1,62 +0,0 @@ -/*- - * Copyright (c) 2016 IBM Corporation - * Copyright (c) 2003-2007 Tim Kientzle - * - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - * - * This test case's code has been derived from test_entry.c - */ -#include "test.h" - -DEFINE_TEST(test_read_pax_xattr_rht_security_selinux) -{ - struct archive *a; - struct archive_entry *ae; - const char *refname = "test_read_pax_xattr_rht_security_selinux.tar"; - const char *xname; /* For xattr tests. */ - const void *xval; /* For xattr tests. */ - size_t xsize; /* For xattr tests. */ - const char *string; - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - - extract_reference_file(refname); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, refname, 10240)); - - assertEqualInt(ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_xattr_count(ae)); - assertEqualInt(1, archive_entry_xattr_reset(ae)); - - assertEqualInt(0, archive_entry_xattr_next(ae, &xname, &xval, &xsize)); - assertEqualString(xname, "security.selinux"); - string = "system_u:object_r:admin_home_t:s0"; - assertEqualMem(xval, string, xsize); - assertEqualInt((int)xsize, strlen(string)); - - /* Close the archive. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_pax_xattr_rht_security_selinux.tar.uu b/thirdparty/libarchive/libarchive/test/test_read_pax_xattr_rht_security_selinux.tar.uu deleted file mode 100644 index 495efbcf1..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_pax_xattr_rht_security_selinux.tar.uu +++ /dev/null @@ -1,231 +0,0 @@ -begin 664 test_read_pax_xattr_rht_security_selinux.tar -M+B]087A(96%D97)S+C$V-C0O=&5S="YT>'0````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````#`P,#`V-#0`,#`P,#`P,``P,#`P,#`P`#`P,#`P,#`P,C(R -M`#$S-#8T-S``````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````!U``````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````!UW6X5O?Y6: -M9^':P2MZR[4)$@W?)B6GX0U@<,0M%6YNMO%OG+IS%/.< -M,"A(N&S.F9]=!*5=\).X."2$GUGJ,0C:@+G#$M_E8UQP,LU-G(8IKW^K^<8* -M*3_.N0'%8.^$8S$`D9XOF+DK<<)U34U'_"O5/22YS96QI;G5X -M/7-Y61I`P!#2DTAT@```$*((<0`````__\#`$-*32'2```` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_truncated.c b/thirdparty/libarchive/libarchive/test/test_read_truncated.c deleted file mode 100644 index 1e760d7f6..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_truncated.c +++ /dev/null @@ -1,134 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/lib/libarchive/test/test_read_truncated.c,v 1.4 2008/09/01 05:38:33 kientzle Exp $"); - -static char buff[1000000]; -static char buff2[100000]; - -DEFINE_TEST(test_read_truncated) -{ - struct archive_entry *ae; - struct archive *a; - unsigned int i; - size_t used; - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff), &used)); - - /* - * Write a file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file"); - archive_entry_set_mode(ae, S_IFREG | 0755); - fill_with_pseudorandom_data(buff2, sizeof(buff2)); - archive_entry_set_size(ae, sizeof(buff2)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, sizeof(buff2), archive_write_data(a, buff2, sizeof(buff2))); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Now, read back a truncated version of the archive and - * verify that we get an appropriate error. */ - for (i = 1; i < used + 100; i += 100) { - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - if (i < 512) { - assertEqualIntA(a, ARCHIVE_FATAL, archive_read_open_memory(a, buff, i)); - goto wrap_up; - } else { - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, i)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - - if (i < 512 + sizeof(buff2)) { - assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data(a, buff2, sizeof(buff2))); - goto wrap_up; - } else { - assertEqualIntA(a, sizeof(buff2), archive_read_data(a, buff2, sizeof(buff2))); - } - - /* Verify the end of the archive. */ - /* Archive must be long enough to capture a 512-byte - * block of zeroes after the entry. (POSIX requires a - * second block of zeros to be written but libarchive - * does not return an error if it can't consume - * it.) */ - if (i < 512 + 512*((sizeof(buff2) + 511)/512) + 512) { - assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae)); - } else { - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - } - wrap_up: - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - } - - - - /* Same as above, except skip the body instead of reading it. */ - for (i = 1; i < used + 100; i += 100) { - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - if (i < 512) { - assertEqualIntA(a, ARCHIVE_FATAL, archive_read_open_memory(a, buff, i)); - goto wrap_up2; - } else { - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, i)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - - if (i < 512 + 512*((sizeof(buff2)+511)/512)) { - assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data_skip(a)); - goto wrap_up2; - } else { - assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a)); - } - - /* Verify the end of the archive. */ - /* Archive must be long enough to capture a 512-byte - * block of zeroes after the entry. (POSIX requires a - * second block of zeros to be written but libarchive - * does not return an error if it can't consume - * it.) */ - if (i < 512 + 512*((sizeof(buff2) + 511)/512) + 512) { - assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae)); - } else { - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - } - wrap_up2: - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - } -} diff --git a/thirdparty/libarchive/libarchive/test/test_read_truncated_filter.c b/thirdparty/libarchive/libarchive/test/test_read_truncated_filter.c deleted file mode 100644 index f85ccaa14..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_truncated_filter.c +++ /dev/null @@ -1,177 +0,0 @@ -/*- - * Copyright (c) 2007-2010 Tim Kientzle - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* - * Check that we generate an error message when reading a truncated - * gzip, bzip2, compress, xz, lzma, or lzip file. - */ - -static void -test_truncation(const char *compression, - int (*set_compression)(struct archive *), int can_prog) -{ - struct archive_entry *ae; - struct archive* a; - char path[16]; - char *buff, *data; - size_t buffsize, datasize, used1; - int i, r, use_prog; - - buffsize = 2000000; - assert(NULL != (buff = (char *)malloc(buffsize))); - if (buff == NULL) - return; - - datasize = 10000; - assert(NULL != (data = (char *)malloc(datasize))); - if (data == NULL) { - free(buff); - return; - } - memset(data, 0, datasize); - - /* - * Write a bunch of files with semi-random data. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_add_filter_compress(a)); - r = (*set_compression)(a); - if (r != ARCHIVE_OK && !can_prog) { - skipping("%s writing not supported on this platform", - compression); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - free(buff); - free(data); - return; - } - use_prog = (r == ARCHIVE_WARN && can_prog); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used1)); - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_filetype(ae, AE_IFREG); - archive_entry_set_size(ae, datasize); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "%s%d", compression, i); - archive_entry_copy_pathname(ae, path); - failure("%s", path); - if (!assertEqualIntA(a, ARCHIVE_OK, - archive_write_header(a, ae))) { - archive_write_free(a); - free(data); - free(buff); - return; - } - fill_with_pseudorandom_data(data, datasize); - failure("%s", path); - if (!assertEqualIntA(a, datasize, - archive_write_data(a, data, datasize))) { - archive_write_free(a); - free(data); - free(buff); - return; - } - } - archive_entry_free(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - - r = archive_read_open_memory(a, buff, used1 - used1/64); - if (r != ARCHIVE_OK) { - assertEqualStringA(a, "truncated bzip2 input", - archive_error_string(a)); - goto out; - } - - for (i = 0; i < 100; i++) { - if (ARCHIVE_OK != archive_read_next_header(a, &ae)) { - failure("Should have non-NULL error message for %s", - compression); - assert(NULL != archive_error_string(a)); - break; - } - snprintf(path, sizeof(path), "%s%d", compression, i); - assertEqualString(path, archive_entry_pathname(ae)); - if (datasize != (size_t)archive_read_data(a, data, datasize)) { - failure("Should have non-NULL error message for %s", - compression); - assert(NULL != archive_error_string(a)); - break; - } - } - assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, - archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - -out: - free(data); - free(buff); -} - -DEFINE_TEST(test_read_truncated_filter_bzip2) -{ - test_truncation("bzip2", archive_write_add_filter_bzip2, canBzip2()); -} - -DEFINE_TEST(test_read_truncated_filter_compress) -{ - test_truncation("compress", archive_write_add_filter_compress, 0); -} - -DEFINE_TEST(test_read_truncated_filter_gzip) -{ - test_truncation("gzip", archive_write_add_filter_gzip, canGzip()); -} - -DEFINE_TEST(test_read_truncated_filter_lzip) -{ - test_truncation("lzip", archive_write_add_filter_lzip, canLzip()); -} - -DEFINE_TEST(test_read_truncated_filter_lzma) -{ - test_truncation("lzma", archive_write_add_filter_lzma, canLzma()); -} - -DEFINE_TEST(test_read_truncated_filter_lzop) -{ - test_truncation("lzop", archive_write_add_filter_lzop, canLzop()); -} - -DEFINE_TEST(test_read_truncated_filter_xz) -{ - test_truncation("xz", archive_write_add_filter_xz, canXz()); -} diff --git a/thirdparty/libarchive/libarchive/test/test_short_writes.c b/thirdparty/libarchive/libarchive/test/test_short_writes.c deleted file mode 100644 index 8221cece1..000000000 --- a/thirdparty/libarchive/libarchive/test/test_short_writes.c +++ /dev/null @@ -1,218 +0,0 @@ -/*- - * Copyright (c) 2021 Red Hat, Inc. - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -#include -#include -#include - -/* - * This test checks whether things work correctly when the archive_write_callback - * passed to archive_write_open() does a short write and only writes some of the - * data passed in. The way the test works is that two archives are constructed - * in parallel - one with short writes, one with full writes - and the results - * are compared to see if they are identical. - */ - -struct checker { - struct archive *short_archive; - char *shortbuf; - size_t shortbuf_len; - - struct archive *full_archive; - char *fullbuf; - size_t fullbuf_len; -}; - -static ssize_t -short_write_callback(struct archive *a, void *client_data, const void *buffer, size_t length) -{ - (void)a; - - struct checker *checker = client_data; - size_t to_write = length < 100 ? length : 100; - size_t new_len = checker->shortbuf_len + to_write; - char *new_buf = realloc(checker->shortbuf, new_len); - assert(new_buf != NULL); - - checker->shortbuf = new_buf; - memcpy(checker->shortbuf + checker->shortbuf_len, buffer, to_write); - checker->shortbuf_len = new_len; - - return to_write; -} - -static ssize_t -full_write_callback(struct archive *a, void *client_data, const void *buffer, size_t length) -{ - (void)a; - - struct checker *checker = client_data; - size_t to_write = length; - size_t new_len = checker->fullbuf_len + to_write; - char *new_buf = realloc(checker->fullbuf, new_len); - assert(new_buf != NULL); - - checker->fullbuf = new_buf; - memcpy(checker->fullbuf + checker->fullbuf_len, buffer, to_write); - checker->fullbuf_len = new_len; - - return to_write; -} - -static struct archive * -create_archive(struct checker *checker, archive_write_callback write_cb, int buffered) -{ - struct archive *a; - - assert((a = archive_write_new()) != NULL); - - if (!buffered) - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 0)); - - /* With the default value of bytes_in_last_block, the writing code will - * pad out the final write to make it a full block. This causes problems - * for us because the size of the final write can be different depending - * on the size of previous writes, causing the "short" and "full" paths - * to get different amounts of padding. Setting it to 1 results in no - * padding other than that defined by the archive format. */ - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_in_last_block(a, 1)); - - /* We write a pax archive, but other formats would work fine too. */ - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_format_pax(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_add_filter_none(a)); - - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open(a, checker, NULL, write_cb, NULL)); - - return a; -} - -static struct checker * -checker_new(int buffered) -{ - struct checker *checker; - - assert ((checker = calloc(1, sizeof *checker)) != NULL); - - checker->short_archive = create_archive(checker, short_write_callback, buffered); - checker->full_archive = create_archive(checker, full_write_callback, buffered); - - return checker; -} - -static void -checker_add_file(struct checker *checker, const char *name, char *buffer, size_t len) -{ - struct archive_entry *entry; - assert((entry = archive_entry_new()) != NULL); - - archive_entry_set_pathname(entry, name); - archive_entry_set_mode(entry, AE_IFREG | 0755); - archive_entry_set_size(entry, len); - - assertEqualIntA(checker->short_archive, ARCHIVE_OK, - archive_write_header(checker->short_archive, entry)); - assertEqualIntA(checker->short_archive, len, - archive_write_data(checker->short_archive, buffer, len)); - - assertEqualIntA(checker->full_archive, ARCHIVE_OK, - archive_write_header(checker->full_archive, entry)); - assertEqualIntA(checker->full_archive, len, - archive_write_data(checker->full_archive, buffer, len)); - - archive_entry_free(entry); -} - -static void -checker_close(struct checker *checker) -{ - assertEqualIntA(checker->short_archive, ARCHIVE_OK, - archive_write_close(checker->short_archive)); - assertEqualIntA(checker->short_archive, ARCHIVE_OK, - archive_write_close(checker->full_archive)); -} - -static void -checker_check(struct checker *checker) -{ - assertEqualInt(checker->shortbuf_len, checker->fullbuf_len); - assert(memcmp(checker->shortbuf, checker->fullbuf, checker->fullbuf_len) == 0); -} - -static void -checker_free(struct checker *checker) -{ - free(checker->shortbuf); - free(checker->fullbuf); - archive_read_free(checker->short_archive); - archive_read_free(checker->full_archive); - free(checker); -} - -DEFINE_TEST(test_short_writes) -{ - struct checker *checker; - uint16_t test_data[16384]; - int i; - - for (i = 0; i < 16384; i++) - test_data[i] = i; - - - /* Write a file smaller than the default buffer size (10 * 1024); - * this will be written out at close. - */ - checker = checker_new(1); - checker_add_file(checker, "a", (char *)test_data, 1024); - checker_close(checker); - assert(checker->shortbuf_len > 1024); - checker_check(checker); - checker_free(checker); - - /* Write a file larger larger than twice default buffer size (10 * 1024); - * this both fills the buffer and writes it out, and also exercises - * the "write out full blocks directly" code path. - */ - checker = checker_new(1); - checker_add_file(checker, "a", (char *)test_data, 21 * 1024); - checker_close(checker); - assert(checker->shortbuf_len > 21 * 1024); - checker_check(checker); - checker_free(checker); - - /* Test unbuffered writes - a different code path. - */ - checker = checker_new(0); - checker_add_file(checker, "a", (char *)test_data, 1024); - checker_close(checker); - assert(checker->shortbuf_len > 1024); - checker_check(checker); - checker_free(checker); -} diff --git a/thirdparty/libarchive/libarchive/test/test_sparse_basic.c b/thirdparty/libarchive/libarchive/test/test_sparse_basic.c deleted file mode 100644 index 484c28656..000000000 --- a/thirdparty/libarchive/libarchive/test/test_sparse_basic.c +++ /dev/null @@ -1,693 +0,0 @@ -/*- - * Copyright (c) 2010-2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_SYS_IOCTL_H -#include -#endif -#ifdef HAVE_SYS_PARAM_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif -#ifdef HAVE_LIMITS_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_LINUX_TYPES_H -#include -#endif -#ifdef HAVE_LINUX_FIEMAP_H -#include -#endif -#ifdef HAVE_LINUX_FS_H -#include -#endif - -/* The logic to compare sparse file data read from disk with the - * specification is a little involved. Set to 1 to have the progress - * dumped. */ -#define DEBUG 0 - -/* - * NOTE: On FreeBSD and Solaris, this test needs ZFS. - * You may perform this test as - * 'TMPDIR= libarchive_test'. - */ - -struct sparse { - enum { DATA, HOLE, END } type; - size_t size; -}; - -static void create_sparse_file(const char *, const struct sparse *); - -#if defined(__APPLE__) -/* On APFS holes need to be at least 4096x4097 bytes */ -#define MIN_HOLE 16781312 -#else -/* Elsewhere we work with 4096*10 bytes */ -#define MIN_HOLE 409600 -#endif - -#if defined(_WIN32) && !defined(__CYGWIN__) -#include -/* - * Create a sparse file on Windows. - */ - -#if !defined(PATH_MAX) -#define PATH_MAX MAX_PATH -#endif -#if !defined(__BORLANDC__) -#define getcwd _getcwd -#endif - -static int -is_sparse_supported(const char *path) -{ - char root[MAX_PATH+1]; - char vol[MAX_PATH+1]; - char sys[MAX_PATH+1]; - DWORD flags; - BOOL r; - - strncpy(root, path, sizeof(root)-1); - if (((root[0] >= 'c' && root[0] <= 'z') || - (root[0] >= 'C' && root[0] <= 'Z')) && - root[1] == ':' && - (root[2] == '\\' || root[2] == '/')) - root[3] = '\0'; - else - return (0); - assertEqualInt((r = GetVolumeInformation(root, vol, - sizeof(vol), NULL, NULL, &flags, sys, sizeof(sys))), 1); - return (r != 0 && (flags & FILE_SUPPORTS_SPARSE_FILES) != 0); -} - -static void -create_sparse_file(const char *path, const struct sparse *s) -{ - char buff[1024]; - HANDLE handle; - DWORD dmy; - - memset(buff, ' ', sizeof(buff)); - - handle = CreateFileA(path, GENERIC_WRITE, 0, - NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, - NULL); - assert(handle != INVALID_HANDLE_VALUE); - assert(DeviceIoControl(handle, FSCTL_SET_SPARSE, NULL, 0, - NULL, 0, &dmy, NULL) != 0); - - uint64_t offsetSoFar = 0; - - while (s->type != END) { - if (s->type == HOLE) { - LARGE_INTEGER fileOffset, beyondOffset, distanceToMove; - fileOffset.QuadPart = offsetSoFar; - beyondOffset.QuadPart = offsetSoFar + s->size; - distanceToMove.QuadPart = s->size; - - FILE_ZERO_DATA_INFORMATION zeroInformation; - zeroInformation.FileOffset = fileOffset; - zeroInformation.BeyondFinalZero = beyondOffset; - - DWORD bytesReturned; - assert(SetFilePointerEx(handle, distanceToMove, - NULL, FILE_CURRENT) != 0); - assert(SetEndOfFile(handle) != 0); - assert(DeviceIoControl(handle, FSCTL_SET_ZERO_DATA, &zeroInformation, - sizeof(FILE_ZERO_DATA_INFORMATION), NULL, 0, &bytesReturned, NULL) != 0); - } else { - DWORD w, wr; - size_t size; - - size = s->size; - while (size) { - if (size > sizeof(buff)) - w = sizeof(buff); - else - w = (DWORD)size; - assert(WriteFile(handle, buff, w, &wr, NULL) != 0); - size -= wr; - } - } - offsetSoFar += s->size; - s++; - } - assertEqualInt(CloseHandle(handle), 1); -} - -#else - -#if defined(HAVE_LINUX_FIEMAP_H) -/* - * FIEMAP, which can detect 'hole' of a sparse file, has - * been supported from 2.6.28 - */ - -static int -is_sparse_supported_fiemap(const char *path) -{ - const struct sparse sparse_file[] = { - /* This hole size is too small to create a sparse - * files for almost filesystem. */ - { HOLE, 1024 }, { DATA, 10240 }, - { END, 0 } - }; - int fd, r; - struct fiemap *fm; - char buff[1024]; - const char *testfile = "can_sparse"; - - (void)path; /* UNUSED */ - memset(buff, 0, sizeof(buff)); - create_sparse_file(testfile, sparse_file); - fd = open(testfile, O_RDWR); - if (fd < 0) - return (0); - fm = (struct fiemap *)buff; - fm->fm_start = 0; - fm->fm_length = ~0ULL;; - fm->fm_flags = FIEMAP_FLAG_SYNC; - fm->fm_extent_count = (sizeof(buff) - sizeof(*fm))/ - sizeof(struct fiemap_extent); - r = ioctl(fd, FS_IOC_FIEMAP, fm); - close(fd); - unlink(testfile); - return (r >= 0); -} - -#if !defined(SEEK_HOLE) || !defined(SEEK_DATA) -static int -is_sparse_supported(const char *path) -{ - return is_sparse_supported_fiemap(path); -} -#endif -#endif - -#if defined(_PC_MIN_HOLE_SIZE) - -/* - * FreeBSD and Solaris can detect 'hole' of a sparse file - * through lseek(HOLE) on ZFS. (UFS does not support yet) - */ - -static int -is_sparse_supported(const char *path) -{ - return (pathconf(path, _PC_MIN_HOLE_SIZE) > 0); -} - -#elif defined(SEEK_HOLE) && defined(SEEK_DATA) - -static int -is_sparse_supported(const char *path) -{ - const struct sparse sparse_file[] = { - /* This hole size is too small to create a sparse - * files for almost filesystem. */ - { HOLE, 1024 }, { DATA, 10240 }, - { END, 0 } - }; - int fd, r; - const char *testfile = "can_sparse"; - - (void)path; /* UNUSED */ - create_sparse_file(testfile, sparse_file); - fd = open(testfile, O_RDWR); - if (fd < 0) - return (0); - r = lseek(fd, 0, SEEK_HOLE); - close(fd); - unlink(testfile); -#if defined(HAVE_LINUX_FIEMAP_H) - if (r < 0) - return (is_sparse_supported_fiemap(path)); - return (1); -#else - return (r >= 0); -#endif -} - -#elif !defined(HAVE_LINUX_FIEMAP_H) - -/* - * Other system may do not have the API such as lseek(HOLE), - * which detect 'hole' of a sparse file. - */ - -static int -is_sparse_supported(const char *path) -{ - (void)path; /* UNUSED */ - return (0); -} - -#endif - -/* - * Create a sparse file on POSIX like system. - */ - -static void -create_sparse_file(const char *path, const struct sparse *s) -{ - char buff[1024]; - int fd; - uint64_t total_size = 0; - const struct sparse *cur = s; - - memset(buff, ' ', sizeof(buff)); - assert((fd = open(path, O_CREAT | O_WRONLY, 0600)) != -1); - - /* Handle holes at the end by extending the file */ - while (cur->type != END) { - total_size += cur->size; - ++cur; - } - assert(ftruncate(fd, total_size) != -1); - - while (s->type != END) { - if (s->type == HOLE) { - assert(lseek(fd, s->size, SEEK_CUR) != (off_t)-1); - } else { - size_t w, size; - - size = s->size; - while (size) { - if (size > sizeof(buff)) - w = sizeof(buff); - else - w = size; - assert(write(fd, buff, w) != (ssize_t)-1); - size -= w; - } - } - s++; - } - close(fd); -} - -#endif - -/* - * Sparse test with directory traversals. - */ -static void -verify_sparse_file(struct archive *a, const char *path, - const struct sparse *sparse, int expected_holes) -{ - struct archive_entry *ae; - const void *buff; - size_t bytes_read; - int64_t offset, expected_offset, last_offset; - int holes_seen = 0; - - create_sparse_file(path, sparse); - assert((ae = archive_entry_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, path)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); - - expected_offset = 0; - last_offset = 0; - while (ARCHIVE_OK == archive_read_data_block(a, &buff, &bytes_read, - &offset)) { - const char *start = buff; -#if DEBUG - fprintf(stderr, "%s: bytes_read=%d offset=%d\n", path, (int)bytes_read, (int)offset); -#endif - if (offset > last_offset) { - ++holes_seen; - } - /* Blocks entirely before the data we just read. */ - while (expected_offset + (int64_t)sparse->size < offset) { -#if DEBUG - fprintf(stderr, " skipping expected_offset=%d, size=%d\n", (int)expected_offset, (int)sparse->size); -#endif - /* Must be holes. */ - assert(sparse->type == HOLE); - expected_offset += sparse->size; - ++sparse; - } - /* Block that overlaps beginning of data */ - if (expected_offset < offset - && expected_offset + (int64_t)sparse->size <= offset + (int64_t)bytes_read) { - const char *end = (const char *)buff + (expected_offset - offset) + (size_t)sparse->size; -#if DEBUG - fprintf(stderr, " overlapping hole expected_offset=%d, size=%d\n", (int)expected_offset, (int)sparse->size); -#endif - if (sparse->type == HOLE) { - assertMemoryFilledWith(start, end - start, '\0'); - } else if (assert(sparse->type == DATA)) { - assertMemoryFilledWith(start, end - start, ' '); - } - start = end; - expected_offset += sparse->size; - ++sparse; - } - /* Blocks completely contained in data we just read. */ - while (expected_offset + (int64_t)sparse->size <= offset + (int64_t)bytes_read) { - const char *end = (const char *)buff + (expected_offset - offset) + (size_t)sparse->size; - if (sparse->type == HOLE) { -#if DEBUG - fprintf(stderr, " contained hole expected_offset=%d, size=%d\n", (int)expected_offset, (int)sparse->size); -#endif - - /* verify data corresponding to hole is '\0' */ - if (end > (const char *)buff + bytes_read) { - end = (const char *)buff + bytes_read; - } - assertMemoryFilledWith(start, end - start, '\0'); - start = end; - expected_offset += sparse->size; - ++sparse; - } else if (sparse->type == DATA) { -#if DEBUG - fprintf(stderr, " contained data expected_offset=%d, size=%d\n", (int)expected_offset, (int)sparse->size); -#endif - /* verify data corresponding to hole is ' ' */ - if (assert(expected_offset + sparse->size <= offset + bytes_read)) { - assert(start == (const char *)buff + (size_t)(expected_offset - offset)); - assertMemoryFilledWith(start, end - start, ' '); - } - start = end; - expected_offset += sparse->size; - ++sparse; - } else { - break; - } - } - /* Block that overlaps end of data */ - if (expected_offset < offset + (int64_t)bytes_read) { - const char *end = (const char *)buff + bytes_read; -#if DEBUG - fprintf(stderr, " trailing overlap expected_offset=%d, size=%d\n", (int)expected_offset, (int)sparse->size); -#endif - if (sparse->type == HOLE) { - assertMemoryFilledWith(start, end - start, '\0'); - } else if (assert(sparse->type == DATA)) { - assertMemoryFilledWith(start, end - start, ' '); - } - } - last_offset = offset + bytes_read; - } - /* Count a hole at EOF? */ - if (last_offset < archive_entry_size(ae)) { - ++holes_seen; - } - - /* Verify blocks after last read */ - while (sparse->type == HOLE) { - expected_offset += sparse->size; - ++sparse; - } - assert(sparse->type == END); - assertEqualInt(expected_offset, archive_entry_size(ae)); - - failure("%s", path); - assertEqualInt(holes_seen, expected_holes); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - archive_entry_free(ae); -} - -#if defined(_WIN32) && !defined(__CYGWIN__) -#define close _close -#define open _open -#endif - -/* - * Sparse test without directory traversals. - */ -static void -verify_sparse_file2(struct archive *a, const char *path, - const struct sparse *sparse, int blocks, int preopen) -{ - struct archive_entry *ae; - int fd; - - (void)sparse; /* UNUSED */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_pathname(ae, path); - if (preopen) - fd = open(path, O_RDONLY | O_BINARY); - else - fd = -1; - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, fd, NULL)); - if (fd >= 0) - close(fd); - /* Verify the number of holes only, not its offset nor its - * length because those alignments are deeply dependence on - * its filesystem. */ - failure("%s", path); - assertEqualInt(blocks, archive_entry_sparse_count(ae)); - archive_entry_free(ae); -} - -static void -test_sparse_whole_file_data(void) -{ - struct archive_entry *ae; - int64_t offset; - int i; - - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_size(ae, 1024*10); - - /* - * Add sparse block data up to the file size. - */ - offset = 0; - for (i = 0; i < 10; i++) { - archive_entry_sparse_add_entry(ae, offset, 1024); - offset += 1024; - } - - failure("There should be no sparse"); - assertEqualInt(0, archive_entry_sparse_count(ae)); - archive_entry_free(ae); -} - -DEFINE_TEST(test_sparse_basic) -{ - char *cwd; - struct archive *a; - const char *skip_sparse_tests; - /* - * The alignment of the hole of sparse files deeply depends - * on filesystem. In my experience, sparse_file2 test with - * 204800 bytes hole size did not pass on ZFS and the result - * of that test seemed the size was too small, thus you should - * keep a hole size more than 409600 bytes to pass this test - * on all platform. - */ - const struct sparse sparse_file0[] = { - // 0 // 1024 - { DATA, 1024 }, { HOLE, MIN_HOLE + 1638400 }, - // 2049024 // 2051072 - { DATA, 2048 }, { HOLE, MIN_HOLE + 1638400 }, - // 4099072 // 4103168 - { DATA, 4096 }, { HOLE, MIN_HOLE + 20070400 }, - // 24583168 // 24591360 - { DATA, 8192 }, { HOLE, MIN_HOLE + 204390400 }, - // 229391360 // 229391361 - { DATA, 1 }, { END, 0 } - }; - const struct sparse sparse_file1[] = { - { HOLE, MIN_HOLE }, { DATA, 1 }, - { HOLE, MIN_HOLE }, { DATA, 1 }, - { HOLE, MIN_HOLE }, { END, 0 } - }; - const struct sparse sparse_file2[] = { - { HOLE, MIN_HOLE }, { DATA, 1024 }, - { HOLE, MIN_HOLE + 409600 * 1 }, { DATA, 1024 }, - { HOLE, MIN_HOLE + 409600 * 2 }, { DATA, 1024 }, - { HOLE, MIN_HOLE + 409600 * 3 }, { DATA, 1024 }, - { HOLE, MIN_HOLE + 409600 * 4 }, { DATA, 1024 }, - { HOLE, MIN_HOLE + 409600 * 5 }, { DATA, 1024 }, - { HOLE, MIN_HOLE + 409600 * 6 }, { DATA, 1024 }, - { HOLE, MIN_HOLE + 409600 * 7 }, { DATA, 1024 }, - { HOLE, MIN_HOLE + 409600 * 8 }, { DATA, 1024 }, - { HOLE, MIN_HOLE + 409600 * 9}, { DATA, 1024 },/* 10 */ - { HOLE, MIN_HOLE }, { DATA, 1024 * 1 }, - { HOLE, MIN_HOLE + 409600 * 1 }, { DATA, 1024 * 2 }, - { HOLE, MIN_HOLE + 409600 * 2 }, { DATA, 1024 * 3 }, - { HOLE, MIN_HOLE + 409600 * 3 }, { DATA, 1024 * 4 }, - { HOLE, MIN_HOLE + 409600 * 4 }, { DATA, 1024 * 5 }, - { HOLE, MIN_HOLE + 409600 * 5 }, { DATA, 1024 * 6 }, - { HOLE, MIN_HOLE + 409600 * 6 }, { DATA, 1024 * 7 }, - { HOLE, MIN_HOLE + 409600 * 7 }, { DATA, 1024 * 8 }, - { HOLE, MIN_HOLE + 409600 * 8 }, { DATA, 1024 * 9 }, - { HOLE, MIN_HOLE + 409600 * 9}, { DATA, 1024 * 10},/* 20 */ - { END, 0 } - }; - const struct sparse sparse_file3[] = { - /* This hole size is too small to create a sparse file */ - { HOLE, 1 }, { DATA, 10240 }, - { HOLE, 1 }, { DATA, 10240 }, - { HOLE, 1 }, { DATA, 10240 }, - { END, 0 } - }; - const struct sparse sparse_file4[] = { - { DATA, 4096 }, { HOLE, 0xc0000000 }, - /* This hole overflows the offset if stored in 32 bits. */ - { DATA, 4096 }, { HOLE, 0x50000000 }, - { END, 0 } - }; - - /* - * Test for the case that sparse data indicates just the whole file - * data. - */ - test_sparse_whole_file_data(); - - skip_sparse_tests = getenv("SKIP_TEST_SPARSE"); - if (skip_sparse_tests != NULL) { - skipping("Skipping sparse tests due to SKIP_TEST_SPARSE " - "environment variable"); - return; - } - - /* Check if the filesystem where CWD on can - * report the number of the holes of a sparse file. */ -#if defined(PATH_MAX) && !defined(__GLIBC__) - cwd = getcwd(NULL, PATH_MAX);/* Solaris getcwd needs the size. */ -#else - cwd = getcwd(NULL, 0); -#endif - if (!assert(cwd != NULL)) - return; - if (!is_sparse_supported(cwd)) { - free(cwd); - skipping("This filesystem or platform do not support " - "the reporting of the holes of a sparse file through " - "API such as lseek(HOLE)"); - return; - } - - /* - * Get sparse data through directory traversals. - */ - assert((a = archive_read_disk_new()) != NULL); - - verify_sparse_file(a, "file0", sparse_file0, 4); - verify_sparse_file(a, "file1", sparse_file1, 3); - verify_sparse_file(a, "file2", sparse_file2, 20); - /* Encoded non sparse; expect a data block but no sparse entries. */ - verify_sparse_file(a, "file3", sparse_file3, 0); - verify_sparse_file(a, "file4", sparse_file4, 2); - - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Get sparse data through archive_read_disk_entry_from_file(). - */ - assert((a = archive_read_disk_new()) != NULL); - - verify_sparse_file2(a, "file0", sparse_file0, 5, 0); - verify_sparse_file2(a, "file0", sparse_file0, 5, 1); - - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Test that setting ARCHIVE_READDISK_NO_SPARSE - * creates no sparse entries. - */ - assert((a = archive_read_disk_new()) != NULL); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_behavior(a, - ARCHIVE_READDISK_NO_SPARSE)); - - verify_sparse_file(a, "file0", sparse_file0, 0); - verify_sparse_file(a, "file1", sparse_file1, 0); - verify_sparse_file(a, "file2", sparse_file2, 0); - verify_sparse_file(a, "file3", sparse_file3, 0); - verify_sparse_file(a, "file4", sparse_file4, 0); - - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - assert((a = archive_read_disk_new()) != NULL); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_behavior(a, - ARCHIVE_READDISK_NO_SPARSE)); - - verify_sparse_file2(a, "file0", sparse_file0, 0, 0); - verify_sparse_file2(a, "file0", sparse_file0, 0, 1); - - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - free(cwd); -} - -DEFINE_TEST(test_fully_sparse_files) -{ - char *cwd; - struct archive *a; - const char *skip_sparse_tests; - - const struct sparse sparse_file[] = { - { HOLE, MIN_HOLE }, { END, 0 } - }; - - skip_sparse_tests = getenv("SKIP_TEST_SPARSE"); - if (skip_sparse_tests != NULL) { - skipping("Skipping sparse tests due to SKIP_TEST_SPARSE " - "environment variable"); - return; - } - - /* Check if the filesystem where CWD on can - * report the number of the holes of a sparse file. */ -#if defined(PATH_MAX) && !defined(__GLIBC__) - cwd = getcwd(NULL, PATH_MAX);/* Solaris getcwd needs the size. */ -#else - cwd = getcwd(NULL, 0); -#endif - if (!assert(cwd != NULL)) - return; - if (!is_sparse_supported(cwd)) { - free(cwd); - skipping("This filesystem or platform do not support " - "the reporting of the holes of a sparse file through " - "API such as lseek(HOLE)"); - return; - } - - assert((a = archive_read_disk_new()) != NULL); - - /* Fully sparse files are encoded with a zero-length "data" block. */ - verify_sparse_file(a, "file0", sparse_file, 1); - - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - free(cwd); -} diff --git a/thirdparty/libarchive/libarchive/test/test_splitted_rar_seek_support_aa.uu b/thirdparty/libarchive/libarchive/test/test_splitted_rar_seek_support_aa.uu deleted file mode 100644 index 0344d2ce3..000000000 --- a/thirdparty/libarchive/libarchive/test/test_splitted_rar_seek_support_aa.uu +++ /dev/null @@ -1,159 +0,0 @@ -begin 644 - -M4F%R(1H'`,^0R!M87)G:6XZ(#`N-SEI;B!]"@D)4"![(&UAR!M87)G:6XM8F]T=&]M.B`P+C`X:6X@?0H)"4@Q+G=ER!F;VYT+69A;6EL>3H@(DQI8F5R871I;VX@4V5R:68B+"!S97)I9B!] -M"@D)2#$N8VIK('L@9F]N="UF86UI;'DZ(")":71S=')E86T@5F5R82!386YS -M(B!]"@D)2#$N8W1L('L@9F]N="UF86UI;'DZ(")&R!F;VYT+69A;6EL>3H@(D)I='-TR!F;VYT+69A;6EL>3H@(D9R965386YS(B!]"@D)5%0N8VIK('L@ -M9F]N="UF86UI;'DZ(")":71S=')E86T@5F5R82!386YS(BP@;6]N;W-P86-E -M('T*"2TM/@H)/"]35%E,13X*/"](14%$/@H\0D]$62!,04Y'/2)E;BU54R(@ -M1$E2/2),5%(B/@H\2#$@0TQ!4U,](G=E2X@"CPO4#X*/%`^06YY('-I9VYI9FEC86YT(&-H -M86YG92!T;R!L:6)A2!N97<@=&5S=',@;W(@8VAA;F=E -M&ES=&EN9R!T97-T0H):&]L9&EN9R!T:&4@ -M)G%U;W0[6]U -M)VQL(&YE960@=&\@2!T:&4*/%14($-,05-3/2)W97-T97)N(CXM -M2!S:&]U;&0@ -M8F4@=7-A8FQE(&9O2!F&5C=71A8FQE(&)E -M:6YG(&5X97)C:7-E9"X@"@D\+U`^"@D\3$D^/%`^0F%S:6,@=F5R2(^/"]!/D)A2!T:&%T(&EL;&5G86P@&-E2!W:71H('9A'1R -M86-T7W)E9F5R96YC95]F:6QE*&YA;64I.PHF;F)S<#L@)FYB'1?:&5A9&5R*&$L("9A;7`[864I*3L* -M)FYB5]P871H -M;F%M92AA92DI.SPO4%)%/CQ0/@I4:&4@/%14($-,05-3/2)W97-T97)N(CYA -M2!D969A=6QT+`IT:&5Y(')E<&]R="!T:&4@9F%I;'5R -M92!A;F0@6-L92!O9@IA('1E0IA;F0@87,@82!L -M86)E;"!T:&%T(&-A;B!B92!U2X@"@D\+U`^"@D\3$D^/%`@4U193$4](FUA2!D:7)E8W1O2!A2!O<&5N(&9I;&4@9&5S8W)I<'1O2!W:6QL(&)E -M(')E;6]V960@9F]R('EO=2X@"@D\+U`^"@D\3$D^/%`^5&AE(&-U2X@"@D\+U`^"@D\3$D^/%`@4U193$4](FUA -MPHC:68@7U]03$%41D]230HF;F)S<#L@ -M)FYB"@I(&9U;F-T:6]N -M2!I;F-O;7!L971E(&QI -M'1&:6QE0V]N=&5N=',\+U14/B`*"3PO4#X*/"]53#X*/$@Q($-, -M05-3/2)W97-T97)N(CX\02!.04U%/2)2969E6]U(&YE960@82!R969E'1R86-T7W)E9F5R96YC95]F:6QE*"9Q=6]T -M.W1E"UE;F-O9&5D(&%R'1R86-T7W)E -M9F5R96YC95]F:6QE*"D\+U14/B!W87,@861D960@86YD(&ES"FYO="!R96-O -M;6UE;F1E9"!F;W(@;F5W(&-O9&4N(`H\+U`^"CQ(,2!#3$%34STB=V5S=&5R -M;B(^/$$@3D%-13TB1&]S7V%N9%]$;VYT6]U6]U2!R=6X* -M"6%L;"!O9B!T:&4@=&5S=',N(`H)/"]0/@H)/$Q)/CQ0(%-464Q%/2)M87)G -M:6XM8F]T=&]M.B`P:6XB/D1/3B=4(')E;'D@;VX@/%14($-,05-3/2)W97-T -997)N(CY(059%7SPO5%0^"@EM86-R;W,@9@`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_splitted_rar_seek_support_ac.uu b/thirdparty/libarchive/libarchive/test/test_splitted_rar_seek_support_ac.uu deleted file mode 100644 index ee9f78c48..000000000 --- a/thirdparty/libarchive/libarchive/test/test_splitted_rar_seek_support_ac.uu +++ /dev/null @@ -1,141 +0,0 @@ -begin 644 - -M2!A9&1I;F<@:G5S="!A(&-O=7!L92!O9B!A&ES=&EN9R!T97-T(&EN&%M<&QE'1R86-T7W)E9F5R96YC -M95]F:6QE*"D\+U14/@IT;R!D96-O9&4@82!U=65N8V]D960@:6YP=70@9FEL -M92P@=&AE;B!O<&5N('1H870@9FEL92!W:71H(&QI8F%R8VAI=F4*86YD('9E -M2!T:&4@0IF965D(&%R8VAI=F4@96YT2!A9V%I;B!T;R!R96%D('1H -M92!D871A(&)A8VL@86YD('9E2!T:&%T"FET(&ES('1H92!S86UE+B`* -M/"]0/@H\2#(@0TQ!4U,](G=E2!T:&%T('1H92!A2X*5&AE2!T6EN9R!F:6QE2!T -M:6UE2!T;PIA=F]I9"!UGH@=&5S=&5R/"](,CX*/%`^5&AE(&9U>GH@=&5S=&5R(&ES(&]N92!O -M9B!T:&4@9F5W('1E2!A8F]R -M=',@=&AE(&5N=&ER92!PGH@9F%I;'5R92!C -M875S97,@82!CFEP(&]R(&)Z:7`R"F-O;7!R97-S:6]N('=O -M;B=T(&AE;'`[(&%L=&AO=6=H('-M86QL97(L('1H92!O=71P=70@:7,@F5R;R!B>71E0IE9F9E8W1I=F4L(&-O;7!R97-S:6YG(&$@F5N(&5N=')I97,@9&]W;B!T;PIJ=7-T(&$@9F5W -M(&MI;&]B>71E2!T:&%T(&QI8F%R8VAI=F4@8V]R -M0IC87-EF5R;R!B;&]C:W,@8V%N('1A:V4*<75I=&4@82!W:&EL92P@F%T -M:6]N.@I,:6)A29Q=6]T.R!Z97)O+6-O -M<'DN(%=H96X@>6]U(&=I=F4@:70@82!L87)G90IB;&]C:R!T;R!W2!B;V1Y+"!I="!W:6QL('!A2!L87)G92!F:6QE('-I>F5S("AT87(@9FEL97,*2D@86YD(&EN=&5G97(@;W9E2D@:6X@82!T97-T('1H870@ 0) { - for (i = 0; i < dlen; i++) - *p++ = 'a'; - *p++ = '/'; - } - for (i = 0; i < flen; i++) - *p++ = 'b'; - *p = '\0'; - - strcpy(dirname, filename); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertA(0 == archive_write_set_format_pax_restricted(a)); - assertA(0 == archive_write_add_filter_none(a)); - assertA(0 == archive_write_set_bytes_per_block(a,0)); - assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used)); - - /* - * Write a file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, filename); - archive_entry_set_mode(ae, S_IFREG | 0755); - failure("Pathname %d/%d", dlen, flen); - assertA(0 == archive_write_header(a, ae)); - archive_entry_free(ae); - - /* - * Write a dir to it (without trailing '/'). - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, dirname); - archive_entry_set_mode(ae, S_IFDIR | 0755); - failure("Dirname %d/%d", dlen, flen); - assertA(0 == archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Tar adds a '/' to directory names. */ - strcat(dirname, "/"); - - /* - * Write a dir to it (with trailing '/'). - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, dirname); - archive_entry_set_mode(ae, S_IFDIR | 0755); - failure("Dirname %d/%d", dlen, flen); - assertA(0 == archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Now, read the data back. - */ - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_open_memory(a, buff, used)); - - /* Read the file and check the filename. */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString(filename, archive_entry_pathname(ae)); - assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae)); - - /* - * Read the two dirs and check the names. - * - * Both dirs should read back with the same name, since - * tar should add a trailing '/' to any dir that doesn't - * already have one. We only report the first such failure - * here. - */ - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString(dirname, archive_entry_pathname(ae)); - assert((S_IFDIR | 0755) == archive_entry_mode(ae)); - - assertA(0 == archive_read_next_header(a, &ae)); - assertEqualString(dirname, archive_entry_pathname(ae)); - assert((S_IFDIR | 0755) == archive_entry_mode(ae)); - - /* Verify the end of the archive. */ - assert(1 == archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_tar_filenames) -{ - int dlen, flen; - - /* Repeat the following for a variety of dir/file lengths. */ - for (dlen = 45; dlen < 55; dlen++) { - for (flen = 45; flen < 55; flen++) { - test_filename(NULL, dlen, flen); - test_filename("/", dlen, flen); - } - } - - for (dlen = 0; dlen < 140; dlen += 10) { - for (flen = 98; flen < 102; flen++) { - test_filename(NULL, dlen, flen); - test_filename("/", dlen, flen); - } - } - - for (dlen = 140; dlen < 160; dlen++) { - for (flen = 95; flen < 105; flen++) { - test_filename(NULL, dlen, flen); - test_filename("/", dlen, flen); - } - } -} diff --git a/thirdparty/libarchive/libarchive/test/test_tar_large.c b/thirdparty/libarchive/libarchive/test/test_tar_large.c deleted file mode 100644 index 0da58aa32..000000000 --- a/thirdparty/libarchive/libarchive/test/test_tar_large.c +++ /dev/null @@ -1,289 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_tar_large.c 201247 2009-12-30 05:59:21Z kientzle $"); - -#include -#include -#include - -/* - * This is a somewhat tricky test that verifies the ability to - * write and read very large entries to tar archives. It - * writes entries from 2GB up to 1TB to an archive in memory. - * The memory storage here carefully avoids actually storing - * any part of the file bodies, so it runs very quickly and requires - * very little memory. If you're willing to wait a few minutes, - * you should be able to exercise petabyte entries with this code. - */ - -/* - * Each file is built up by duplicating the following block. - */ -static size_t filedatasize; -static void *filedata; - -/* - * We store the archive as blocks of data generated by libarchive, - * each possibly followed by bytes of file data. - */ -struct memblock { - struct memblock *next; - size_t size; - void *buff; - int64_t filebytes; -}; - -/* - * The total memory store is just a list of memblocks plus - * some accounting overhead. - */ -struct memdata { - int64_t filebytes; - void *buff; - struct memblock *first; - struct memblock *last; -}; - -/* The following size definitions simplify things below. */ -#define KB ((int64_t)1024) -#define MB ((int64_t)1024 * KB) -#define GB ((int64_t)1024 * MB) -#define TB ((int64_t)1024 * GB) - -static int64_t memory_read_skip(struct archive *, void *, int64_t request); -static ssize_t memory_read(struct archive *, void *, const void **buff); -static ssize_t memory_write(struct archive *, void *, const void *, size_t); - - -static ssize_t -memory_write(struct archive *a, void *_private, const void *buff, size_t size) -{ - struct memdata *private = _private; - struct memblock *block; - - (void)a; - - /* - * Since libarchive tries to behave in a zero-copy manner, if - * you give a pointer to filedata to the library, a pointer - * into that data will (usually) pop out here. This way, we - * can tell the difference between filedata and library header - * and metadata. - */ - if ((const char *)filedata <= (const char *)buff - && (const char *)buff < (const char *)filedata + filedatasize) { - /* We don't need to store a block of file data. */ - private->last->filebytes += (int64_t)size; - } else { - /* Yes, we're assuming the very first write is metadata. */ - /* It's header or metadata, copy and save it. */ - block = (struct memblock *)malloc(sizeof(*block)); - memset(block, 0, sizeof(*block)); - block->size = size; - block->buff = malloc(size); - memcpy(block->buff, buff, size); - if (private->last == NULL) { - private->first = private->last = block; - } else { - private->last->next = block; - private->last = block; - } - block->next = NULL; - } - return ((long)size); -} - -static ssize_t -memory_read(struct archive *a, void *_private, const void **buff) -{ - struct memdata *private = _private; - struct memblock *block; - ssize_t size; - - (void)a; - - free(private->buff); - private->buff = NULL; - if (private->first == NULL) { - private->last = NULL; - return (ARCHIVE_EOF); - } - if (private->filebytes > 0) { - /* - * We're returning file bytes, simulate it by - * passing blocks from the template data. - */ - if (private->filebytes > (int64_t)filedatasize) - size = (ssize_t)filedatasize; - else - size = (ssize_t)private->filebytes; - private->filebytes -= size; - *buff = filedata; - } else { - /* - * We need to get some real data to return. - */ - block = private->first; - private->first = block->next; - size = (ssize_t)block->size; - if (block->buff != NULL) { - private->buff = block->buff; - *buff = block->buff; - } else { - private->buff = NULL; - *buff = filedata; - } - private->filebytes = block->filebytes; - free(block); - } - return (size); -} - - -static int64_t -memory_read_skip(struct archive *a, void *_private, int64_t skip) -{ - struct memdata *private = _private; - - (void)a; - - if (private->first == NULL) { - private->last = NULL; - return (0); - } - if (private->filebytes > 0) { - if (private->filebytes < skip) - skip = (off_t)private->filebytes; - private->filebytes -= skip; - } else { - skip = 0; - } - return (skip); -} - -DEFINE_TEST(test_tar_large) -{ - /* The sizes of the entries we're going to generate. */ - static int64_t tests[] = { - /* Test for 32-bit signed overflow. */ - 2 * GB - 1, 2 * GB, 2 * GB + 1, - /* Test for 32-bit unsigned overflow. */ - 4 * GB - 1, 4 * GB, 4 * GB + 1, - /* 8GB is the "official" max for ustar. */ - 8 * GB - 1, 8 * GB, 8 * GB + 1, - /* Bend ustar a tad and you can get 64GB (12 octal digits). */ - 64 * GB - 1, 64 * GB, - /* And larger entries that require non-ustar extensions. */ - 256 * GB, 1 * TB, 0 }; - int i; - char namebuff[64]; - struct memdata memdata; - struct archive_entry *ae; - struct archive *a; - int64_t filesize; - size_t writesize; - - filedatasize = (size_t)(1 * MB); - filedata = malloc(filedatasize); - memset(filedata, 0xAA, filedatasize); - memset(&memdata, 0, sizeof(memdata)); - - /* - * Open an archive for writing. - */ - a = archive_write_new(); - archive_write_set_format_pax_restricted(a); - archive_write_set_bytes_per_block(a, 0); /* No buffering. */ - archive_write_open(a, &memdata, NULL, memory_write, NULL); - - /* - * Write a series of large files to it. - */ - for (i = 0; tests[i] != 0; i++) { - assert((ae = archive_entry_new()) != NULL); - snprintf(namebuff, sizeof(namebuff), "file_%d", i); - archive_entry_copy_pathname(ae, namebuff); - archive_entry_set_mode(ae, S_IFREG | 0755); - filesize = tests[i]; - - archive_entry_set_size(ae, filesize); - - assertA(0 == archive_write_header(a, ae)); - archive_entry_free(ae); - - /* - * Write the actual data to the archive. - */ - while (filesize > 0) { - writesize = filedatasize; - if ((int64_t)writesize > filesize) - writesize = (size_t)filesize; - assertA((int)writesize - == archive_write_data(a, filedata, writesize)); - filesize -= writesize; - } - } - - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "lastfile"); - archive_entry_set_mode(ae, S_IFREG | 0755); - assertA(0 == archive_write_header(a, ae)); - archive_entry_free(ae); - - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Open the same archive for reading. - */ - a = archive_read_new(); - archive_read_support_format_tar(a); - archive_read_open2(a, &memdata, NULL, - memory_read, memory_read_skip, NULL); - - /* - * Read entries back. - */ - for (i = 0; tests[i] > 0; i++) { - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - snprintf(namebuff, sizeof(namebuff), "file_%d", i); - assertEqualString(namebuff, archive_entry_pathname(ae)); - assert(tests[i] == archive_entry_size(ae)); - } - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualString("lastfile", archive_entry_pathname(ae)); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - free(memdata.buff); - free(filedata); -} diff --git a/thirdparty/libarchive/libarchive/test/test_ustar_filename_encoding.c b/thirdparty/libarchive/libarchive/test/test_ustar_filename_encoding.c deleted file mode 100644 index 5e4fba716..000000000 --- a/thirdparty/libarchive/libarchive/test/test_ustar_filename_encoding.c +++ /dev/null @@ -1,393 +0,0 @@ -/*- - * Copyright (c) 2011 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -#include - -DEFINE_TEST(test_ustar_filename_encoding_UTF8_CP866) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("en_US.UTF-8 locale not available on this system."); - return; - } - - /* - * Verify that UTF-8 filenames are correctly translated into CP866 - * and stored with hdrcharset=CP866 option. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_ustar(a)); - if (archive_write_set_options(a, "hdrcharset=CP866") != ARCHIVE_OK) { - skipping("This system cannot convert character-set" - " from UTF-8 to CP866."); - archive_write_free(a); - return; - } - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set a UTF-8 filename. */ - archive_entry_set_pathname(entry, "\xD0\xBF\xD1\x80\xD0\xB8"); - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Above three characters in UTF-8 should translate to the following - * three characters in CP866. */ - assertEqualMem(buff, "\xAF\xE0\xA8", 3); -} - -DEFINE_TEST(test_ustar_filename_encoding_KOI8R_UTF8) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) { - skipping("KOI8-R locale not available on this system."); - return; - } - - /* - * Verify that KOI8-R filenames are correctly translated into UTF-8 - * and stored with hdrcharset=UTF-8 option. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_ustar(a)); - if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) { - skipping("This system cannot convert character-set" - " from KOI8-R to UTF-8."); - archive_write_free(a); - return; - } - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set a KOI8-R filename. */ - archive_entry_set_pathname(entry, "\xD0\xD2\xC9"); - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Above three characters in KOI8-R should translate to the following - * three characters (two bytes each) in UTF-8. */ - assertEqualMem(buff, "\xD0\xBF\xD1\x80\xD0\xB8", 6); -} - -DEFINE_TEST(test_ustar_filename_encoding_KOI8R_CP866) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) { - skipping("KOI8-R locale not available on this system."); - return; - } - - /* - * Verify that KOI8-R filenames are correctly translated into CP866 - * and stored with hdrcharset=CP866 option. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_ustar(a)); - if (archive_write_set_options(a, "hdrcharset=CP866") != ARCHIVE_OK) { - skipping("This system cannot convert character-set" - " from KOI8-R to CP866."); - archive_write_free(a); - return; - } - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set a KOI8-R filename. */ - archive_entry_set_pathname(entry, "\xD0\xD2\xC9"); - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Above three characters in KOI8-R should translate to the following - * three characters in CP866. */ - assertEqualMem(buff, "\xAF\xE0\xA8", 3); -} - -DEFINE_TEST(test_ustar_filename_encoding_CP1251_UTF8) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "Russian_Russia") && - NULL == setlocale(LC_ALL, "ru_RU.CP1251")) { - skipping("KOI8-R locale not available on this system."); - return; - } - - /* - * Verify that CP1251 filenames are correctly translated into UTF-8 - * and stored with hdrcharset=UTF-8 option. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_ustar(a)); - if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) { - skipping("This system cannot convert character-set" - " from KOI8-R to UTF-8."); - archive_write_free(a); - return; - } - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set a KOI8-R filename. */ - archive_entry_set_pathname(entry, "\xEF\xF0\xE8"); - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Above three characters in CP1251 should translate to the following - * three characters (two bytes each) in UTF-8. */ - assertEqualMem(buff, "\xD0\xBF\xD1\x80\xD0\xB8", 6); -} - -/* - * Do not translate CP1251 into CP866 if non Windows platform. - */ -DEFINE_TEST(test_ustar_filename_encoding_ru_RU_CP1251) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "ru_RU.CP1251")) { - skipping("KOI8-R locale not available on this system."); - return; - } - - /* - * Verify that CP1251 filenames are not translated into any - * other character-set, in particular, CP866. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set a KOI8-R filename. */ - archive_entry_set_pathname(entry, "\xEF\xF0\xE8"); - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Above three characters in CP1251 should not translate to - * any other character-set. */ - assertEqualMem(buff, "\xEF\xF0\xE8", 3); -} - -/* - * Other archiver applications on Windows translate CP1251 filenames - * into CP866 filenames and store it in the ustar file. - * Test above behavior works well. - */ -DEFINE_TEST(test_ustar_filename_encoding_Russian_Russia) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "Russian_Russia")) { - skipping("Russian_Russia locale not available on this system."); - return; - } - - /* - * Verify that Russian_Russia(CP1251) filenames are correctly translated - * to CP866. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set a CP1251 filename. */ - archive_entry_set_pathname(entry, "\xEF\xF0\xE8"); - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Above three characters in CP1251 should translate to the following - * three characters in CP866. */ - assertEqualMem(buff, "\xAF\xE0\xA8", 3); -} - -DEFINE_TEST(test_ustar_filename_encoding_EUCJP_UTF8) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "ja_JP.eucJP")) { - skipping("eucJP locale not available on this system."); - return; - } - - /* - * Verify that EUC-JP filenames are correctly translated to UTF-8. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_ustar(a)); - if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) { - skipping("This system cannot convert character-set" - " from eucJP to UTF-8."); - archive_write_free(a); - return; - } - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set an EUC-JP filename. */ - archive_entry_set_pathname(entry, "\xC9\xBD.txt"); - /* Check the Unicode version. */ - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Check UTF-8 version. */ - assertEqualMem(buff, "\xE8\xA1\xA8.txt", 7); -} - -DEFINE_TEST(test_ustar_filename_encoding_EUCJP_CP932) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "ja_JP.eucJP")) { - skipping("eucJP locale not available on this system."); - return; - } - - /* - * Verify that EUC-JP filenames are correctly translated to CP932. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_ustar(a)); - if (archive_write_set_options(a, "hdrcharset=CP932") != ARCHIVE_OK) { - skipping("This system cannot convert character-set" - " from eucJP to CP932."); - archive_write_free(a); - return; - } - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set an EUC-JP filename. */ - archive_entry_set_pathname(entry, "\xC9\xBD.txt"); - /* Check the Unicode version. */ - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Check CP932 version. */ - assertEqualMem(buff, "\x95\x5C.txt", 6); -} - -DEFINE_TEST(test_ustar_filename_encoding_CP932_UTF8) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "Japanese_Japan") && - NULL == setlocale(LC_ALL, "ja_JP.SJIS")) { - skipping("CP932/SJIS locale not available on this system."); - return; - } - - /* - * Verify that CP932/SJIS filenames are correctly translated to UTF-8. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_ustar(a)); - if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) { - skipping("This system cannot convert character-set" - " from CP932/SJIS to UTF-8."); - archive_write_free(a); - return; - } - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set a CP932/SJIS filename. */ - archive_entry_set_pathname(entry, "\x95\x5C.txt"); - /* Check the Unicode version. */ - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Check UTF-8 version. */ - assertEqualMem(buff, "\xE8\xA1\xA8.txt", 7); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_ustar_filenames.c b/thirdparty/libarchive/libarchive/test/test_ustar_filenames.c deleted file mode 100644 index 1a4b4e145..000000000 --- a/thirdparty/libarchive/libarchive/test/test_ustar_filenames.c +++ /dev/null @@ -1,183 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_ustar_filenames.c 189308 2009-03-03 17:02:51Z kientzle $"); - -/* - * Exercise various lengths of filenames in ustar archives. - */ - -static void -test_filename(const char *prefix, int dlen, int flen) -{ - char buff[8192]; - char filename[400]; - char dirname[400]; - struct archive_entry *ae; - struct archive *a; - size_t used; - int separator = 0; - int i = 0; - - if (prefix != NULL) { - strcpy(filename, prefix); - i = (int)strlen(prefix); - } - if (dlen > 0) { - for (; i < dlen; i++) - filename[i] = 'a'; - filename[i++] = '/'; - separator = 1; - } - for (; i < dlen + flen + separator; i++) - filename[i] = 'b'; - filename[i] = '\0'; - - strcpy(dirname, filename); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertA(0 == archive_write_set_format_ustar(a)); - assertA(0 == archive_write_add_filter_none(a)); - assertA(0 == archive_write_set_bytes_per_block(a,0)); - assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used)); - - /* - * Write a file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, filename); - archive_entry_set_mode(ae, S_IFREG | 0755); - failure("dlen=%d, flen=%d", dlen, flen); - if (flen > 100) { - assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae)); - } else { - assertEqualIntA(a, 0, archive_write_header(a, ae)); - } - archive_entry_free(ae); - - /* - * Write a dir to it (without trailing '/'). - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, dirname); - archive_entry_set_mode(ae, S_IFDIR | 0755); - failure("dlen=%d, flen=%d", dlen, flen); - if (flen >= 100) { - assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae)); - } else { - assertEqualIntA(a, 0, archive_write_header(a, ae)); - } - archive_entry_free(ae); - - /* Tar adds a '/' to directory names. */ - strcat(dirname, "/"); - - /* - * Write a dir to it (with trailing '/'). - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, dirname); - archive_entry_set_mode(ae, S_IFDIR | 0755); - failure("dlen=%d, flen=%d", dlen, flen); - if (flen >= 100) { - assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae)); - } else { - assertEqualIntA(a, 0, archive_write_header(a, ae)); - } - archive_entry_free(ae); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Now, read the data back. - */ - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_open_memory(a, buff, used)); - - if (flen <= 100) { - /* Read the file and check the filename. */ - assertA(0 == archive_read_next_header(a, &ae)); - failure("dlen=%d, flen=%d", dlen, flen); - assertEqualString(filename, archive_entry_pathname(ae)); - assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae)); - } - - /* - * Read the two dirs and check the names. - * - * Both dirs should read back with the same name, since - * tar should add a trailing '/' to any dir that doesn't - * already have one. - */ - if (flen <= 99) { - assertA(0 == archive_read_next_header(a, &ae)); - assert((S_IFDIR | 0755) == archive_entry_mode(ae)); - failure("dlen=%d, flen=%d", dlen, flen); - assertEqualString(dirname, archive_entry_pathname(ae)); - } - - if (flen <= 99) { - assertA(0 == archive_read_next_header(a, &ae)); - assert((S_IFDIR | 0755) == archive_entry_mode(ae)); - assertEqualString(dirname, archive_entry_pathname(ae)); - } - - /* Verify the end of the archive. */ - failure("This fails if entries were written that should not have been written. dlen=%d, flen=%d", dlen, flen); - assertEqualInt(1, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_ustar_filenames) -{ - int dlen, flen; - - /* Try a bunch of different file/dir lengths that add up - * to just a little less or a little more than 100 bytes. - * This exercises the code that splits paths between ustar - * filename and prefix fields. - */ - for (dlen = 5; dlen < 70; dlen += 5) { - for (flen = 100 - dlen - 5; flen < 100 - dlen + 5; flen++) { - test_filename(NULL, dlen, flen); - test_filename("/", dlen, flen); - } - } - - /* Probe the 100-char limit for paths with no '/'. */ - for (flen = 90; flen < 110; flen++) { - test_filename(NULL, 0, flen); - test_filename("/", dlen, flen); - } - - /* XXXX TODO Probe the 100-char limit with a dir prefix. */ - /* XXXX TODO Probe the 255-char total limit. */ -} diff --git a/thirdparty/libarchive/libarchive/test/test_warn_missing_hardlink_target.c b/thirdparty/libarchive/libarchive/test/test_warn_missing_hardlink_target.c deleted file mode 100644 index d7fa5eb6c..000000000 --- a/thirdparty/libarchive/libarchive/test/test_warn_missing_hardlink_target.c +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * Copyright (c) 2015 Graham Percival - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -DEFINE_TEST(test_warn_missing_hardlink_target) -{ - struct archive *a; - struct archive_entry *ae; - - assert(NULL != (a = archive_write_disk_new())); - assert(NULL != (ae = archive_entry_new())); - - archive_entry_set_pathname(ae, "hardlink-name"); - archive_entry_set_hardlink(ae, "hardlink-target"); - - assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae)); - assertEqualInt(ENOENT, archive_errno(a)); - assertEqualString("Hard-link target 'hardlink-target' does not exist.", - archive_error_string(a)); - - archive_entry_free(ae); - archive_free(a); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_disk.c b/thirdparty/libarchive/libarchive/test/test_write_disk.c deleted file mode 100644 index e38dbc78f..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_disk.c +++ /dev/null @@ -1,349 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_disk.c 201247 2009-12-30 05:59:21Z kientzle $"); - -#define UMASK 022 -/* - * When comparing mode values, ignore high-order bits - * that are set on some OSes. This should cover the bits - * we're interested in (standard mode bits + file type bits) - * while ignoring extra markers such as Haiku/BeOS index - * flags. - */ -#define MODE_MASK 0777777 - -static void create(struct archive_entry *ae, const char *msg) -{ - struct archive *ad; - struct stat st; - - /* Write the entry to disk. */ - assert((ad = archive_write_disk_new()) != NULL); - failure("%s", msg); - assertEqualIntA(ad, 0, archive_write_header(ad, ae)); - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - assertEqualInt(0, archive_write_free(ad)); - - /* Test the entries on disk. */ - assert(0 == stat(archive_entry_pathname(ae), &st)); - failure("%s", msg); - -#if !defined(_WIN32) || defined(__CYGWIN__) - /* When verifying a dir, ignore the S_ISGID bit, as some systems set - * that automatically. */ - if (archive_entry_filetype(ae) == AE_IFDIR) - st.st_mode &= ~S_ISGID; - assertEqualInt(st.st_mode & MODE_MASK, - archive_entry_mode(ae) & ~UMASK & MODE_MASK); -#endif -} - -static void create_reg_file(struct archive_entry *ae, const char *msg) -{ - static const char data[]="abcdefghijklmnopqrstuvwxyz"; - struct archive *ad; - - /* Write the entry to disk. */ - assert((ad = archive_write_disk_new()) != NULL); - archive_write_disk_set_options(ad, ARCHIVE_EXTRACT_TIME); - failure("%s", msg); - /* - * A touchy API design issue: archive_write_data() does (as of - * 2.4.12) enforce the entry size as a limit on the data - * written to the file. This was not enforced prior to - * 2.4.12. The change was prompted by the refined - * hardlink-restore semantics introduced at that time. In - * short, libarchive needs to know whether a "hardlink entry" - * is going to overwrite the contents so that it can know - * whether or not to open the file for writing. This implies - * that there is a fundamental semantic difference between an - * entry with a zero size and one with a non-zero size in the - * case of hardlinks and treating the hardlink case - * differently from the regular file case is just asking for - * trouble. So, a zero size must always mean that no data - * will be accepted, which is consistent with the file size in - * the entry being a maximum size. - */ - archive_entry_set_size(ae, sizeof(data)); - archive_entry_set_mtime(ae, 123456789, 0); - assertEqualIntA(ad, 0, archive_write_header(ad, ae)); - assertEqualInt(sizeof(data), archive_write_data(ad, data, sizeof(data))); - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - assertEqualInt(0, archive_write_free(ad)); - - /* Test the entries on disk. */ - assertIsReg(archive_entry_pathname(ae), archive_entry_mode(ae) & 0777); - assertFileSize(archive_entry_pathname(ae), sizeof(data)); - /* test_write_disk_times has more detailed tests of this area. */ - assertFileMtime(archive_entry_pathname(ae), 123456789, 0); - failure("No atime given, so atime should get set to current time"); - assertFileAtimeRecent(archive_entry_pathname(ae)); -} - -static void create_reg_file2(struct archive_entry *ae, const char *msg) -{ - const int datasize = 100000; - char *data; - struct archive *ad; - int i; - - data = malloc(datasize); - for (i = 0; i < datasize; i++) - data[i] = (char)(i % 256); - - /* Write the entry to disk. */ - assert((ad = archive_write_disk_new()) != NULL); - failure("%s", msg); - /* - * See above for an explanation why this next call - * is necessary. - */ - archive_entry_set_size(ae, datasize); - assertEqualIntA(ad, 0, archive_write_header(ad, ae)); - for (i = 0; i < datasize - 999; i += 1000) { - assertEqualIntA(ad, ARCHIVE_OK, - archive_write_data_block(ad, data + i, 1000, i)); - } - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - assertEqualInt(0, archive_write_free(ad)); - - /* Test the entries on disk. */ - assertIsReg(archive_entry_pathname(ae), archive_entry_mode(ae) & 0777); - assertFileSize(archive_entry_pathname(ae), i); - assertFileContents(data, datasize, archive_entry_pathname(ae)); - free(data); -} - -static void create_reg_file3(struct archive_entry *ae, const char *msg) -{ - static const char data[]="abcdefghijklmnopqrstuvwxyz"; - struct archive *ad; - struct stat st; - - /* Write the entry to disk. */ - assert((ad = archive_write_disk_new()) != NULL); - failure("%s", msg); - /* Set the size smaller than the data and verify the truncation. */ - archive_entry_set_size(ae, 5); - assertEqualIntA(ad, 0, archive_write_header(ad, ae)); - assertEqualInt(5, archive_write_data(ad, data, sizeof(data))); - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - assertEqualInt(0, archive_write_free(ad)); - - /* Test the entry on disk. */ - assert(0 == stat(archive_entry_pathname(ae), &st)); - failure("st.st_mode=%o archive_entry_mode(ae)=%o", - st.st_mode, archive_entry_mode(ae)); -#if !defined(_WIN32) || defined(__CYGWIN__) - assertEqualInt(st.st_mode, (archive_entry_mode(ae) & ~UMASK)); -#endif - assertEqualInt(st.st_size, 5); -} - - -static void create_reg_file4(struct archive_entry *ae, const char *msg) -{ - static const char data[]="abcdefghijklmnopqrstuvwxyz"; - struct archive *ad; - struct stat st; - - /* Write the entry to disk. */ - assert((ad = archive_write_disk_new()) != NULL); - /* Leave the size unset. The data should not be truncated. */ - assertEqualIntA(ad, 0, archive_write_header(ad, ae)); - assertEqualInt(ARCHIVE_OK, - archive_write_data_block(ad, data, sizeof(data), 0)); - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - assertEqualInt(0, archive_write_free(ad)); - - /* Test the entry on disk. */ - assert(0 == stat(archive_entry_pathname(ae), &st)); - failure("st.st_mode=%o archive_entry_mode(ae)=%o", - st.st_mode, archive_entry_mode(ae)); -#if !defined(_WIN32) || defined(__CYGWIN__) - assertEqualInt(st.st_mode, (archive_entry_mode(ae) & ~UMASK)); -#endif - failure("%s", msg); - assertEqualInt(st.st_size, sizeof(data)); -} - -#if defined(_WIN32) && !defined(__CYGWIN__) -static void create_reg_file_win(struct archive_entry *ae, const char *msg) -{ - static const char data[]="abcdefghijklmnopqrstuvwxyz"; - struct archive *ad; - struct _stat st; - wchar_t *p, *fname; - size_t l; - - /* Write the entry to disk. */ - assert((ad = archive_write_disk_new()) != NULL); - archive_write_disk_set_options(ad, ARCHIVE_EXTRACT_TIME); - failure("%s", msg); - archive_entry_set_size(ae, sizeof(data)); - archive_entry_set_mtime(ae, 123456789, 0); - assertEqualIntA(ad, 0, archive_write_header(ad, ae)); - assertEqualInt(sizeof(data), archive_write_data(ad, data, sizeof(data))); - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - assertEqualInt(0, archive_write_free(ad)); - - /* Test the entries on disk. */ - l = wcslen(archive_entry_pathname_w(ae)); - fname = malloc((l + 1) * sizeof(wchar_t)); - assert(NULL != fname); - wcscpy(fname, archive_entry_pathname_w(ae)); - p = fname; - /* Skip leading drive letter from archives created - * on Windows. */ - if (((p[0] >= L'a' && p[0] <= L'z') || - (p[0] >= L'A' && p[0] <= L'Z')) && - p[1] == L':' && p[2] == L'\\') { - p += 3; - } - /* Replace unusable characters in Windows to '_' */ - for (; *p != L'\0'; p++) - if (*p == L':' || *p == L'*' || *p == L'?' || - *p == L'"' || *p == L'<' || *p == L'>' || *p == L'|') - *p = '_'; - assert(0 == _wstat(fname, &st)); - failure("st.st_mode=%o archive_entry_mode(ae)=%o", - st.st_mode, archive_entry_mode(ae)); - assertEqualInt(st.st_size, sizeof(data)); - free(fname); -} -#endif /* _WIN32 && !__CYGWIN__ */ - -DEFINE_TEST(test_write_disk) -{ - struct archive_entry *ae; -#if defined(_WIN32) && !defined(__CYGWIN__) - wchar_t *fullpath; - DWORD l; -#endif - - /* Force the umask to something predictable. */ - assertUmask(UMASK); - - /* A regular file. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file"); - archive_entry_set_mode(ae, S_IFREG | 0755); - create_reg_file(ae, "Test creating a regular file"); - archive_entry_free(ae); - - /* Another regular file. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file2"); - archive_entry_set_mode(ae, S_IFREG | 0755); - create_reg_file2(ae, "Test creating another regular file"); - archive_entry_free(ae); - - /* A regular file with a size restriction */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file3"); - archive_entry_set_mode(ae, S_IFREG | 0755); - create_reg_file3(ae, "Regular file with size restriction"); - archive_entry_free(ae); - - /* A regular file with an unspecified size */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file3"); - archive_entry_set_mode(ae, S_IFREG | 0755); - create_reg_file4(ae, "Regular file with unspecified size"); - archive_entry_free(ae); - - /* A regular file over an existing file */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file"); - archive_entry_set_mode(ae, S_IFREG | 0724); - create(ae, "Test creating a file over an existing file."); - archive_entry_free(ae); - - /* A directory. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "dir"); - archive_entry_set_mode(ae, S_IFDIR | 0555); - create(ae, "Test creating a regular dir."); - archive_entry_free(ae); - - /* A directory over an existing file. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file"); - archive_entry_set_mode(ae, S_IFDIR | 0742); - create(ae, "Test creating a dir over an existing file."); - archive_entry_free(ae); - - /* A file over an existing dir. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file"); - archive_entry_set_mode(ae, S_IFREG | 0744); - create(ae, "Test creating a file over an existing dir."); - archive_entry_free(ae); - -#if defined(_WIN32) && !defined(__CYGWIN__) - /* A file with unusable characters in its file name. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname_w(ae, L"f:i*l?e\"fl|e"); - archive_entry_set_mode(ae, S_IFREG | 0755); - create_reg_file_win(ae, "Test creating a regular file" - " with unusable characters in its file name"); - archive_entry_free(ae); - - /* A file with unusable characters in its directory name. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname_w(ae, L"d:i*r?e\"co|ry/file1"); - archive_entry_set_mode(ae, S_IFREG | 0755); - create_reg_file_win(ae, "Test creating a regular file" - " with unusable characters in its file name"); - archive_entry_free(ae); - - /* A full-path file with unusable characters in its file name. */ - assert((l = GetCurrentDirectoryW(0, NULL)) != 0); - assert((fullpath = malloc((l + 20) * sizeof(wchar_t))) != NULL); - assert((l = GetCurrentDirectoryW(l, fullpath)) != 0); - wcscat(fullpath, L"\\f:i*l?e\"fl|e"); - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname_w(ae, fullpath); - archive_entry_set_mode(ae, S_IFREG | 0755); - create_reg_file_win(ae, "Test creating a regular file" - " with unusable characters in its file name"); - archive_entry_free(ae); - free(fullpath); - - /* A full-path file with unusable characters in its directory name. */ - assert((l = GetCurrentDirectoryW(0, NULL)) != 0); - assert((fullpath = malloc((l + 30) * sizeof(wchar_t))) != NULL); - assert((l = GetCurrentDirectoryW(l, fullpath)) != 0); - wcscat(fullpath, L"\\d:i*r?e\"co|ry/file1"); - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname_w(ae, fullpath); - archive_entry_set_mode(ae, S_IFREG | 0755); - create_reg_file_win(ae, "Test creating a regular file" - " with unusable characters in its file name"); - archive_entry_free(ae); - free(fullpath); -#endif /* _WIN32 && !__CYGWIN__ */ -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_disk_appledouble.c b/thirdparty/libarchive/libarchive/test/test_write_disk_appledouble.c deleted file mode 100644 index d82d698eb..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_disk_appledouble.c +++ /dev/null @@ -1,239 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_SYS_ACL_H -#include -#endif -#ifdef HAVE_SYS_XATTR_H -#include -#endif - -#if defined(__APPLE__) && defined(UF_COMPRESSED) && defined(HAVE_SYS_XATTR_H)\ - && defined(HAVE_ZLIB_H) - -// -// The test ACL used here is sometimes assigned to the 'Guest' user -// This changes the text and breaks the test. This function simply -// strips the 'Guest' information from the string to help ensure -// consistent results on different machines. -// -static char _acl_temp[256]; -static const char * -clean_acl(const char *acl) { - char *p, *q; - if (strlen(acl) >= sizeof(_acl_temp)) - return acl; - - strcpy(_acl_temp, acl); - p = strstr(_acl_temp, ":Guest:"); - if (p != NULL) { - fprintf(stderr, "Shortening: %s\n", p + 1); - memmove(p + 1, p + 6, strlen(p + 6) + 1); - q = strstr(p + 2, ":"); - fprintf(stderr, "Shortening: %s\n", q); - memmove(p + 2, q, strlen(q) + 1); - return _acl_temp; - } - return _acl_temp; -} - -static int -has_xattr(const char *filename, const char *xattrname) -{ - char *nl, *nlp; - ssize_t r; - int existing; - - r = listxattr(filename, NULL, 0, XATTR_SHOWCOMPRESSION); - if (r < 0) - return (0); - if (r == 0) - return (0); - - assert((nl = malloc(r)) != NULL); - if (nl == NULL) - return (0); - - r = listxattr(filename, nl, r, XATTR_SHOWCOMPRESSION); - if (r < 0) { - free(nl); - return (0); - } - - existing = 0; - for (nlp = nl; nlp < nl + r; nlp += strlen(nlp) + 1) { - if (strcmp(nlp, xattrname) == 0) { - existing = 1; - break; - } - } - free(nl); - return (existing); -} - -#endif - -/* - * Exercise HFS+ Compression. - */ -DEFINE_TEST(test_write_disk_appledouble) -{ -#if !defined(__APPLE__) || !defined(UF_COMPRESSED) || !defined(HAVE_SYS_XATTR_H)\ - || !defined(HAVE_ZLIB_H) - skipping("MacOS-specific AppleDouble test"); -#else - const char *refname = "test_write_disk_appledouble.cpio.gz"; - struct archive *ad, *a; - struct archive_entry *ae; - struct stat st; - acl_t acl; - - extract_reference_file(refname); - - /* - * Extract an archive to disk with HFS+ Compression. - */ - assert((ad = archive_write_disk_new()) != NULL); - assertEqualIntA(ad, ARCHIVE_OK, - archive_write_disk_set_standard_lookup(ad)); - assertEqualIntA(ad, ARCHIVE_OK, - archive_write_disk_set_options(ad, - ARCHIVE_EXTRACT_TIME | - ARCHIVE_EXTRACT_SECURE_SYMLINKS | - ARCHIVE_EXTRACT_SECURE_NODOTDOT | - ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, - refname, 512 * 20)); - - assertMakeDir("hfscmp", 0755); - assertChdir("hfscmp"); - - /* Skip "." */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(".", archive_entry_pathname(ae)); - /* Extract file3. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("./file3", archive_entry_pathname(ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad)); - /* Extract ._file3 which will be merged into file3 as metadata. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("./._file3", archive_entry_pathname(ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad)); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - assertEqualIntA(ad, ARCHIVE_OK, archive_write_free(ad)); - - /* Test file3. */ - assertEqualInt(0, stat("file3", &st)); - assertEqualInt(UF_COMPRESSED, st.st_flags & UF_COMPRESSED); - assertFileSize("file3", 8); - failure("'%s' should not have Resource Fork", "file3"); - assertEqualInt(0, has_xattr("file3", "com.apple.ResourceFork")); - failure("'%s' should have decompfs xattr", "file3"); - assertEqualInt(1, has_xattr("file3", "com.apple.decmpfs")); - assert(NULL != (acl = acl_get_file("file3", ACL_TYPE_EXTENDED))); - assertEqualString(clean_acl(acl_to_text(acl, NULL)), - "!#acl 1\n" - "user:FFFFEEEE-DDDD-CCCC-BBBB-AAAA000000C9:::deny:read\n" - "group:ABCDEFAB-CDEF-ABCD-EFAB-CDEF00000050:admin:80:allow:write\n" - ); - if (acl) acl_free(acl); - /* Test ._file3. */ - failure("'file3' should be merged and removed"); - assertFileNotExists("._file3"); - - assertChdir(".."); - - /* - * Extract an archive to disk without HFS+ Compression. - */ - assert((ad = archive_write_disk_new()) != NULL); - assertEqualIntA(ad, ARCHIVE_OK, - archive_write_disk_set_standard_lookup(ad)); - assertEqualIntA(ad, ARCHIVE_OK, - archive_write_disk_set_options(ad, - ARCHIVE_EXTRACT_TIME | - ARCHIVE_EXTRACT_SECURE_SYMLINKS | - ARCHIVE_EXTRACT_SECURE_NODOTDOT)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, - refname, 512 * 20)); - - assertMakeDir("nocmp", 0755); - assertChdir("nocmp"); - - /* Skip "." */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(".", archive_entry_pathname(ae)); - /* Extract file3. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("./file3", archive_entry_pathname(ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad)); - /* Extract ._file3 which will be merged into file3 as metadata. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("./._file3", archive_entry_pathname(ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad)); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - assertEqualIntA(ad, ARCHIVE_OK, archive_write_free(ad)); - - /* Test file3. */ - assertEqualInt(0, stat("file3", &st)); - assertEqualInt(0, st.st_flags & UF_COMPRESSED); - assertFileSize("file3", 8); - failure("'%s' should not have Resource Fork", "file3"); - assertEqualInt(0, has_xattr("file3", "com.apple.ResourceFork")); - failure("'%s' should not have decmpfs", "file3"); - assertEqualInt(0, has_xattr("file3", "com.apple.decmpfs")); - assert(NULL != (acl = acl_get_file("file3", ACL_TYPE_EXTENDED))); - assertEqualString(clean_acl(acl_to_text(acl, NULL)), - "!#acl 1\n" - "user:FFFFEEEE-DDDD-CCCC-BBBB-AAAA000000C9:::deny:read\n" - "group:ABCDEFAB-CDEF-ABCD-EFAB-CDEF00000050:admin:80:allow:write\n" - ); - if (acl) acl_free(acl); - /* Test ._file3. */ - failure("'file3' should be merged and removed"); - assertFileNotExists("._file3"); - - assertChdir(".."); - - assertEqualFile("hfscmp/file3", "nocmp/file3"); -#endif -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_disk_appledouble.cpio.gz.uu b/thirdparty/libarchive/libarchive/test/test_write_disk_appledouble.cpio.gz.uu deleted file mode 100644 index f2797d96e..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_disk_appledouble.cpio.gz.uu +++ /dev/null @@ -1,12 +0,0 @@ -begin 644 test_write_disk_appledouble.cpio.gz -M'XL("#N]E5```W1E^_VO?/X52A[:CCZ".9<'JV.U, -MN6AG9G6;C%-A,2X*7 -M)%6SN;;CS7_GO;VI,!TR)L^=.SH^/T%'"-W'B?[PJ#_IW[0U=`K!(3XA0(\N -MT$&X411VV:;C`^)]<&3T4S]+B@6)RS)7)$YR4JO7&C:,2Q`ZTYJ5JN04"``\ -M`;`/8`_`+M!]DW\M;QJUJB6G3*9J^28K%:?:O"J:4KJ>/PFFKH?;!;<*;V77 -M;E$9IXML*:\@R?-B+==55BMM]T%-NA^VO]H_'H7N[5T0&H9QV&_\YP_X`B-U -&WD<`!``` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_write_disk_failures.c b/thirdparty/libarchive/libarchive/test/test_write_disk_failures.c deleted file mode 100644 index c563ce1d3..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_disk_failures.c +++ /dev/null @@ -1,65 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_disk_failures.c 201247 2009-12-30 05:59:21Z kientzle $"); - -DEFINE_TEST(test_write_disk_failures) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - skipping("archive_write_disk interface"); -#else - struct archive_entry *ae; - struct archive *a; - int fd; - - /* Force the umask to something predictable. */ - assertUmask(022); - - /* A directory that we can't write to. */ - assertMakeDir("dir", 0555); - - /* Can we? */ - fd = open("dir/testfile", O_WRONLY | O_CREAT | O_BINARY, 0777); - if (fd >= 0) { - /* Apparently, we can, so the test below won't work. */ - close(fd); - skipping("Can't test writing to non-writable directory"); - return; - } - - /* Try to extract a regular file into the directory above. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "dir/file"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 8); - assert((a = archive_write_disk_new()) != NULL); - archive_write_disk_set_options(a, ARCHIVE_EXTRACT_TIME); - archive_entry_set_mtime(ae, 123456789, 0); - assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae)); - assertEqualIntA(a, 0, archive_write_finish_entry(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - archive_entry_free(ae); -#endif -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_disk_fixup.c b/thirdparty/libarchive/libarchive/test/test_write_disk_fixup.c deleted file mode 100644 index b83b73079..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_disk_fixup.c +++ /dev/null @@ -1,107 +0,0 @@ -/*- - * Copyright (c) 2021 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -/* - * Test fixup entries don't follow symlinks - */ -DEFINE_TEST(test_write_disk_fixup) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - skipping("Skipping test on Windows"); -#else - struct archive *ad; - struct archive_entry *ae; - int r; - - if (!canSymlink()) { - skipping("Symlinks not supported"); - return; - } - - /* Write entries to disk. */ - assert((ad = archive_write_disk_new()) != NULL); - - /* - * Create a file - */ - assertMakeFile("file", 0600, "a"); - - /* - * Create a directory - */ - assertMakeDir("dir", 0700); - - /* - * Create a directory and a symlink with the same name - */ - - /* Directory: dir1 */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "dir1/"); - archive_entry_set_mode(ae, AE_IFDIR | 0555); - assertEqualIntA(ad, 0, archive_write_header(ad, ae)); - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - archive_entry_free(ae); - - /* Directory: dir2 */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "dir2/"); - archive_entry_set_mode(ae, AE_IFDIR | 0555); - assertEqualIntA(ad, 0, archive_write_header(ad, ae)); - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - archive_entry_free(ae); - - /* Symbolic Link: dir1 -> dir */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "dir1"); - archive_entry_set_mode(ae, AE_IFLNK | 0777); - archive_entry_set_size(ae, 0); - archive_entry_copy_symlink(ae, "dir"); - assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); - if (r >= ARCHIVE_WARN) - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - archive_entry_free(ae); - - /* Symbolic Link: dir2 -> file */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "dir2"); - archive_entry_set_mode(ae, AE_IFLNK | 0777); - archive_entry_set_size(ae, 0); - archive_entry_copy_symlink(ae, "file"); - assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); - if (r >= ARCHIVE_WARN) - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - archive_entry_free(ae); - - assertEqualInt(ARCHIVE_OK, archive_write_free(ad)); - - /* Test the entries on disk. */ - assertIsSymlink("dir1", "dir", 0); - assertIsSymlink("dir2", "file", 0); - assertFileMode("dir", 0700); - assertFileMode("file", 0600); -#endif -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_disk_hardlink.c b/thirdparty/libarchive/libarchive/test/test_write_disk_hardlink.c deleted file mode 100644 index 184f77a00..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_disk_hardlink.c +++ /dev/null @@ -1,262 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_disk_hardlink.c 201247 2009-12-30 05:59:21Z kientzle $"); - -#if defined(_WIN32) && !defined(__CYGWIN__) -/* Execution bits, Group members bits and others bits do not work. */ -#define UMASK 0177 -#define E_MASK (~0177) -#else -#define UMASK 022 -#define E_MASK (~0) -#endif - -/* - * Exercise hardlink recreation. - * - * File permissions are chosen so that the authoritative entry - * has the correct permission and the non-authoritative versions - * are just writeable files. - */ -DEFINE_TEST(test_write_disk_hardlink) -{ -#if defined(__HAIKU__) - skipping("archive_write_disk_hardlink; hardlinks are not supported on bfs"); -#else - static const char data[]="abcdefghijklmnopqrstuvwxyz"; - struct archive *ad; - struct archive_entry *ae; -#ifdef HAVE_LINKAT - int can_symlink; -#endif - int r; - - /* Force the umask to something predictable. */ - assertUmask(UMASK); - - /* Write entries to disk. */ - assert((ad = archive_write_disk_new()) != NULL); - - /* - * First, use a tar-like approach; a regular file, then - * a separate "hardlink" entry. - */ - - /* Regular file. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "link1a"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, sizeof(data)); - assertEqualIntA(ad, 0, archive_write_header(ad, ae)); - assertEqualInt(sizeof(data), - archive_write_data(ad, data, sizeof(data))); - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - archive_entry_free(ae); - - /* Link. Size of zero means this doesn't carry data. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "link1b"); - archive_entry_set_mode(ae, S_IFREG | 0642); - archive_entry_set_size(ae, 0); - archive_entry_copy_hardlink(ae, "link1a"); - assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); - if (r >= ARCHIVE_WARN) { - assertEqualInt(ARCHIVE_WARN, - archive_write_data(ad, data, sizeof(data))); - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - } - archive_entry_free(ae); - - /* - * Repeat tar approach test, but use unset to mark the - * hardlink as having no data. - */ - - /* Regular file. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "link2a"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, sizeof(data)); - assertEqualIntA(ad, 0, archive_write_header(ad, ae)); - assertEqualInt(sizeof(data), - archive_write_data(ad, data, sizeof(data))); - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - archive_entry_free(ae); - - /* Link. Unset size means this doesn't carry data. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "link2b"); - archive_entry_set_mode(ae, S_IFREG | 0642); - archive_entry_unset_size(ae); - archive_entry_copy_hardlink(ae, "link2a"); - assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); - if (r >= ARCHIVE_WARN) { - assertEqualInt(ARCHIVE_WARN, - archive_write_data(ad, data, sizeof(data))); - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - } - archive_entry_free(ae); - - /* - * Second, try an old-cpio-like approach; a regular file, then - * another identical one (which has been marked hardlink). - */ - - /* Regular file. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "link3a"); - archive_entry_set_mode(ae, S_IFREG | 0600); - archive_entry_set_size(ae, sizeof(data)); - assertEqualIntA(ad, 0, archive_write_header(ad, ae)); - assertEqualInt(sizeof(data), archive_write_data(ad, data, sizeof(data))); - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - archive_entry_free(ae); - - /* Link. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "link3b"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, sizeof(data)); - archive_entry_copy_hardlink(ae, "link3a"); - assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); - if (r > ARCHIVE_WARN) { - assertEqualInt(sizeof(data), - archive_write_data(ad, data, sizeof(data))); - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - } - archive_entry_free(ae); - - /* - * Third, try a new-cpio-like approach, where the initial - * regular file is empty and the hardlink has the data. - */ - - /* Regular file. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "link4a"); - archive_entry_set_mode(ae, S_IFREG | 0600); - archive_entry_set_size(ae, 0); - assertEqualIntA(ad, 0, archive_write_header(ad, ae)); - assertEqualInt(ARCHIVE_WARN, archive_write_data(ad, data, 1)); - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - archive_entry_free(ae); - - /* Link. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "link4b"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, sizeof(data)); - archive_entry_copy_hardlink(ae, "link4a"); - assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); - if (r > ARCHIVE_FAILED) { - assertEqualInt(sizeof(data), - archive_write_data(ad, data, sizeof(data))); - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - } - archive_entry_free(ae); - -#ifdef HAVE_LINKAT - /* Finally, try creating a hard link to a dangling symlink */ - can_symlink = canSymlink(); - if (can_symlink) { - /* Symbolic link: link5a -> foo */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "link5a"); - archive_entry_set_mode(ae, AE_IFLNK | 0642); - archive_entry_unset_size(ae); - archive_entry_copy_symlink(ae, "foo"); - assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); - if (r >= ARCHIVE_WARN) { - assertEqualInt(ARCHIVE_WARN, - archive_write_data(ad, data, sizeof(data))); - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - } - archive_entry_free(ae); - - - /* Link. Size of zero means this doesn't carry data. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "link5b"); - archive_entry_set_mode(ae, S_IFREG | 0642); - archive_entry_set_size(ae, 0); - archive_entry_copy_hardlink(ae, "link5a"); - assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); - if (r >= ARCHIVE_WARN) { - assertEqualInt(ARCHIVE_WARN, - archive_write_data(ad, data, sizeof(data))); - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - } - archive_entry_free(ae); - } -#endif - assertEqualInt(0, archive_write_free(ad)); - - /* Test the entries on disk. */ - - /* Test #1 */ - /* If the hardlink was successfully created and the archive - * doesn't carry data for it, we consider it to be - * non-authoritative for meta data as well. This is consistent - * with GNU tar and BSD pax. */ - assertIsReg("link1a", 0755 & ~UMASK); - assertFileSize("link1a", sizeof(data)); - assertFileNLinks("link1a", 2); - assertIsHardlink("link1a", "link1b"); - - /* Test #2: Should produce identical results to test #1 */ - /* Note that marking a hardlink with size = 0 is treated the - * same as having an unset size. This is partly for backwards - * compatibility (we used to not have unset tracking, so - * relied on size == 0) and partly to match the model used by - * common file formats that store a size of zero for - * hardlinks. */ - assertIsReg("link2a", 0755 & ~UMASK); - assertFileSize("link2a", sizeof(data)); - assertFileNLinks("link2a", 2); - assertIsHardlink("link2a", "link2b"); - - /* Test #3 */ - assertIsReg("link3a", 0755 & ~UMASK); - assertFileSize("link3a", sizeof(data)); - assertFileNLinks("link3a", 2); - assertIsHardlink("link3a", "link3b"); - - /* Test #4 */ - assertIsReg("link4a", 0755 & ~UMASK); - assertFileNLinks("link4a", 2); - assertFileSize("link4a", sizeof(data)); - assertIsHardlink("link4a", "link4b"); - -#ifdef HAVE_LINKAT - if (can_symlink) { - /* Test #5 */ - assertIsSymlink("link5a", "foo", 0); - assertFileNLinks("link5a", 2); - assertIsHardlink("link5a", "link5b"); - } -#endif -#endif -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_disk_hfs_compression.c b/thirdparty/libarchive/libarchive/test/test_write_disk_hfs_compression.c deleted file mode 100644 index 8a2e7df3b..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_disk_hfs_compression.c +++ /dev/null @@ -1,278 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_SYS_XATTR_H -#include -#endif - -#if defined(__APPLE__) && defined(UF_COMPRESSED) && defined(HAVE_SYS_XATTR_H)\ - && defined(HAVE_ZLIB_H) -static int -has_xattr(const char *filename, const char *xattrname) -{ - char *nl, *nlp; - ssize_t r; - int existing; - - r = listxattr(filename, NULL, 0, XATTR_SHOWCOMPRESSION); - if (r < 0) - return (0); - if (r == 0) - return (0); - - assert((nl = malloc(r)) != NULL); - if (nl == NULL) - return (0); - - r = listxattr(filename, nl, r, XATTR_SHOWCOMPRESSION); - if (r < 0) { - free(nl); - return (0); - } - - existing = 0; - for (nlp = nl; nlp < nl + r; nlp += strlen(nlp) + 1) { - if (strcmp(nlp, xattrname) == 0) { - existing = 1; - break; - } - } - free(nl); - return (existing); -} -static int -get_rsrc_footer(const char *filename, char *buff, size_t s) -{ - ssize_t r; - - r = getxattr(filename, "com.apple.ResourceFork", NULL, 0, 0, - XATTR_SHOWCOMPRESSION); - if (r < (ssize_t)s) - return (-1); - r = getxattr(filename, "com.apple.ResourceFork", buff, s, - r - s, XATTR_SHOWCOMPRESSION); - if (r < (ssize_t)s) - return (-1); - return (0); -} - -#endif - -/* - * Exercise HFS+ Compression. - */ -DEFINE_TEST(test_write_disk_hfs_compression) -{ -#if !defined(__APPLE__) || !defined(UF_COMPRESSED) || !defined(HAVE_SYS_XATTR_H)\ - || !defined(HAVE_ZLIB_H) - skipping("MacOS-specific HFS+ Compression test"); -#else - const char *refname = "test_write_disk_hfs_compression.tgz"; - struct archive *ad, *a; - struct archive_entry *ae; - struct stat st; - char rsrc[50]; - static const char rsrc_footer[50] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x1c, 0x00, 0x32, 0x00, 0x00, 'c', 'm', - 'p', 'f', 0x00, 0x00, 0x00, 0x0a, 0x00, 0x01, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00 - }; - - extract_reference_file(refname); - - /* - * Extract an archive to disk with HFS+ Compression. - */ - assert((ad = archive_write_disk_new()) != NULL); - assertEqualIntA(ad, ARCHIVE_OK, - archive_write_disk_set_standard_lookup(ad)); - assertEqualIntA(ad, ARCHIVE_OK, - archive_write_disk_set_options(ad, - ARCHIVE_EXTRACT_TIME | - ARCHIVE_EXTRACT_SECURE_SYMLINKS | - ARCHIVE_EXTRACT_SECURE_NODOTDOT | - ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, - refname, 512 * 20)); - - assertMakeDir("hfscmp", 0755); - assertChdir("hfscmp"); - - /* Extract file1. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad)); - /* Extract README. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad)); - /* Extract NEWS. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad)); - /* Extract Makefile. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad)); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - assertEqualIntA(ad, ARCHIVE_OK, archive_write_free(ad)); - - /* Test file1. */ - assertEqualInt(0, stat("file1", &st)); - assertEqualInt(UF_COMPRESSED, st.st_flags & UF_COMPRESSED); - assertFileSize("file1", 8); - failure("'%s' should not have Resource Fork", "file1"); - assertEqualInt(0, has_xattr("file1", "com.apple.ResourceFork")); - failure("'%s' should have decompfs xattr", "file1"); - assertEqualInt(1, has_xattr("file1", "com.apple.decmpfs")); - - /* Test README. */ - assertEqualInt(0, stat("README", &st)); - assertEqualInt(UF_COMPRESSED, st.st_flags & UF_COMPRESSED); - assertFileSize("README", 6586); - failure("'%s' should not have Resource Fork", "README"); - assertEqualInt(0, has_xattr("README", "com.apple.ResourceFork")); - failure("'%s' should have decompfs xattr", "README"); - assertEqualInt(1, has_xattr("README", "com.apple.decmpfs")); - - /* Test NEWS. */ - assertEqualInt(0, stat("NEWS", &st)); - assertEqualInt(UF_COMPRESSED, st.st_flags & UF_COMPRESSED); - assertFileSize("NEWS", 28438); - failure("'%s' should have Resource Fork", "NEWS"); - assertEqualInt(1, has_xattr("NEWS", "com.apple.ResourceFork")); - failure("'%s' should have decompfs xattr", "NEWS"); - assertEqualInt(1, has_xattr("NEWS", "com.apple.decmpfs")); - assertEqualInt(0, get_rsrc_footer("NEWS", rsrc, sizeof(rsrc))); - failure("Resource Fork should have consistent 50 bytes data"); - assertEqualMem(rsrc_footer, rsrc, sizeof(rsrc)); - - /* Test Makefile. */ - assertEqualInt(0, stat("Makefile", &st)); - assertEqualInt(UF_COMPRESSED, st.st_flags & UF_COMPRESSED); - assertFileSize("Makefile", 1264000); - failure("'%s' should have Resource Fork", "Makefile"); - assertEqualInt(1, has_xattr("Makefile", "com.apple.ResourceFork")); - failure("'%s' should have decompfs xattr", "Makefile"); - assertEqualInt(1, has_xattr("Makefile", "com.apple.decmpfs")); - assertEqualInt(0, get_rsrc_footer("Makefile", rsrc, sizeof(rsrc))); - failure("Resource Fork should have consistent 50 bytes data"); - assertEqualMem(rsrc_footer, rsrc, sizeof(rsrc)); - - assertChdir(".."); - - /* - * Extract an archive to disk without HFS+ Compression. - */ - assert((ad = archive_write_disk_new()) != NULL); - assertEqualIntA(ad, ARCHIVE_OK, - archive_write_disk_set_standard_lookup(ad)); - assertEqualIntA(ad, ARCHIVE_OK, - archive_write_disk_set_options(ad, - ARCHIVE_EXTRACT_TIME | - ARCHIVE_EXTRACT_SECURE_SYMLINKS | - ARCHIVE_EXTRACT_SECURE_NODOTDOT)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, - refname, 512 * 20)); - - assertMakeDir("nocmp", 0755); - assertChdir("nocmp"); - - /* Extract file1. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad)); - /* Extract README. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad)); - /* Extract NEWS. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad)); - /* Extract Makefile. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad)); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - assertEqualIntA(ad, ARCHIVE_OK, archive_write_free(ad)); - - /* Test file1. */ - assertEqualInt(0, stat("file1", &st)); - assertEqualInt(0, st.st_flags & UF_COMPRESSED); - assertFileSize("file1", 8); - failure("'%s' should not have Resource Fork", "file1"); - assertEqualInt(0, has_xattr("file1", "com.apple.ResourceFork")); - failure("'%s' should not have decmpfs", "file1"); - assertEqualInt(0, has_xattr("file1", "com.apple.decmpfs")); - - /* Test README. */ - assertEqualInt(0, stat("README", &st)); - assertEqualInt(0, st.st_flags & UF_COMPRESSED); - assertFileSize("README", 6586); - failure("'%s' should not have Resource Fork", "README"); - assertEqualInt(0, has_xattr("README", "com.apple.ResourceFork")); - failure("'%s' should not have decmpfs", "README"); - assertEqualInt(0, has_xattr("README", "com.apple.decmpfs")); - - /* Test NEWS. */ - assertEqualInt(0, stat("NEWS", &st)); - assertEqualInt(0, st.st_flags & UF_COMPRESSED); - assertFileSize("NEWS", 28438); - failure("'%s' should not have Resource Fork", "NEWS"); - assertEqualInt(0, has_xattr("NEWS", "com.apple.ResourceFork")); - failure("'%s' should not have decmpfs", "NEWS"); - assertEqualInt(0, has_xattr("NEWS", "com.apple.decmpfs")); - - /* Test Makefile. */ - assertEqualInt(0, stat("Makefile", &st)); - assertEqualInt(0, st.st_flags & UF_COMPRESSED); - assertFileSize("Makefile", 1264000); - failure("'%s' should not have Resource Fork", "Makefile"); - assertEqualInt(0, has_xattr("Makefile", "com.apple.ResourceFork")); - failure("'%s' should not have decmpfs", "Makefile"); - assertEqualInt(0, has_xattr("Makefile", "com.apple.decmpfs")); - - assertChdir(".."); - - assertEqualFile("hfscmp/file1", "nocmp/file1"); - assertEqualFile("hfscmp/README", "nocmp/README"); - assertEqualFile("hfscmp/NEWS", "nocmp/NEWS"); - assertEqualFile("hfscmp/Makefile", "nocmp/Makefile"); -#endif -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_disk_hfs_compression.tgz.uu b/thirdparty/libarchive/libarchive/test/test_write_disk_hfs_compression.tgz.uu deleted file mode 100644 index 35e26aed4..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_disk_hfs_compression.tgz.uu +++ /dev/null @@ -1,1800 +0,0 @@ -begin 644 test_write_disk_hfs_compression.tgz -M'XL(`,'#B5```^R]ZWK;1K(HNO^*3X%1O$=2EDA=;2?RSEI#2[+-1+9+]4.?'>8']8J_SYZ)30!5U?>Z=77U -MV/6FG+:-\_>\=/GN^;^WM/3\X@/5_>'!(Z__P^9?U_SG^\/A;XR"T/'=@ -MA\.I^]ZQ!@M_Y#F=5NO_63A1[`9^]%^6U8LB>/JOEF597UO3.)X?[>PD.)V) -M&T\7@\XPF.U8;F3%4\>:!C.'2`?^)'#]":):>CDCY[WC!?.9X\?;ENL/O<4( -MP*Q1,%S@.QN+WK9L?R0Q_3N@'!!QCWCFA9<=,731I&(R@,4$P@0[`QLRU1NX09K2#!:EBHL5@ -MYE(QCC^U_:<=:)GC;UMQS;"B=8;D\VYHO/`]J^2_L9.N]:UNOW?@-]&%2 -MGP@JI'6L5A/M)Y*)6JW;*73["&H6NH,%]IP81M&Q#H_)./"\X`/V%A"%;8VALNVQ8\>+T!E9&PC`S:4_,&2>+7IPL'"]&*:.5B\N -M83AW@Z0(?$J5,7+'8R=$&JX?.^$8*,)X:,4X401?7=OS'HA.9.-$7?A#[#;; -M<^,'+LFYMV:(T64Q"I8-'8;GL13X,PLC[`%(/!?;#^)==[ -M!^<3]MJ\[>$BA3X-G6$75S_W+EX#[`?9H4-85*.`JP?M$H"]BYO;[MD9 -M`$(M8A@2+A0?P@4-H0`4S*U-N%0IU9%C=P(3$#[)WTPC&H;N''A1Y#BJ&%P` -M(P>:[$G>C4 -MEWF=;4,E83Z,>&2=UH:J^X:HK.AFK!)2Z]@SX)A#+QC:7F=VN)TTMF,/Y6QH -M,TV8,Z*>:=:Q#>L.UH;O.",N&U@LC;H31JGR7%^6T9G"0VL-NMN!66W'T#)9 -M]:3'N=*MUNN%.\(F6R(J`'K?S:8H;2V8,E!?3E%!3+!7\R -M@%R9`@491#D.0NA(VLH[L";(VI"[!^^=\+WK?)"(DD':R'(^3`.<75]+9MA' -MEMDYV%;/R#:=S(L^=/H=O649IV.+;UBQ]]A7/`>A9V!D2=Q%*#E`WD0T\[!* -MB$9D!)]VK.Y5+]*K!1T=/@!1,:$):YW7C0FS;L%$0$YH#3T[,F@04P4V&265 -M@V%"!@G=BTL;IMS4!2.?@#B\,)]#3;ISKWL@?!@OAC1/QB'H"` -MA5DEM0U1M*ZP3.UPU(Z#-C%_V;5$!@G,0*,(?:J.K(+U'CBX[:.V@@QA9OL+ -MZ)BY/7$(#TK!A2]J.9(,8@,Z8D-C#K#:;,M?S`:@Q<"D3,2>[+I6ZV?@HM$T -M6,`BAP$+:(80K6$P)Q$"DHB[%LI8E[-^NLX5!883!8MPB.`C1TVS*"4`\?TL -M"!W%)BWKBH6-Y\2PUEIW?O!!="M*&2<,4>J@8C@#C0H9-K%[[#ZH\_$BQ%9X -M#]OF.EO$`8[0D,0V%`6]$%$]L5%I<31&6))!7UNO+]Y2IW.W6)O)P.$7+Q", -MV`WPF4"YA -M%'Y\3F":SO2U=75YTWMGD26B/<_M>UXS+"4%90T@&,9.W`Y"%SH+V0(,*-?L -MQ^M#JWMSW.LE[\HQ7KH^]C#-T,V!.VE#>UQD>6@5Q+'GB!?B.H-Y`Y/O`?L7=VY"G;O#,(B"<6P==U_JL&=OND3\[)$<>213'J0L2>;MP!GC2G+>V]Z"U4%2U(1>3D4MD.L'..%H.M([5B2H"Z^O -MSH'YVW/@J_1I\A&:*WL/.I]>#N#E?N:M?-XY^^6GS$?OX\R&U0&(O"3N/QH@ -M1IM1<1O"LHR=9("!P>2V6#"KH^66PCJ4#[,!)O9HG>#XVS9(9'"6I16)2L3:/1IF+'!@()K/6VB0[.<4O<'UO6TX\W.JH56YR -MG+IK=MUW/@S7DY?1-,TI_IP5(Q=\^2(R5\!/4T=,`=U$W!9J2K0`TPXGR8!X -M*HPL5%)9(>DI8D[[SSJI+X+8B1*-(%G4V"!KZ;3*$47=PQR#R2#%!2QPJ&U#^4[%9Q4"]5X!W0P7VCW3B*2N6!T\ -M."3G!J0BH0"V!Q[Q>M0[Z3?IQ=P'0IL`>,>&12F+(T53D`#1[\RQIGZL>LBF -M_T#B(V\+_+3;YR?WSI5JO?`N34'/@'9SHPT+&GOJTJ>:;J>[0#:&RO,^V`^1 -MX-?0;8;6P61Z&ZB?Q6CEQ-S/:-G/W(^@&:$9,V3M80[3EXPI:$]O3`K.*/`W -M:*RQUN[0!1T'&OX^N'/0&T1-)553^$>LS6B!W149<\,FI30!UAL32):S!>II -M;'W`\JP)B%[T$9$B229LS]<(`*16.[UJP.%H(#5@Q$X5.'+T%Z*FVT21RT!BU$3:+D)E7:T&`KO5H2#`.R# -MQP&'K(VEHGF`*HY+8H@&P'_OAH'/JN\'FFTT/VF@-P-:^8P46)3OT.U40-&]VG)&]-K"'=[A^QL!;L2_F8%.99,&`06D)L]"* -MW1FM"52K9_:KVIG26,=3/&(+7U0$%SHV/6_"=SU1/0F-9%T`=+QQMBEV,<[ -MV$J`!6HTCV2/2Y]>)(>$A`Z-"ORKW-`N-Q]&!WDK>B':,V>&)M9@@3:5Q3H" -MF]3Y-Q/'FD4',XLM;S -M5==U,7$1!5N8M2"WL0@8U3G6\(.4NJAR@OG]`+/A_N[1\5;,U9Z+V9 -M!A&I0[&Q256Z#=@J(KX1I;;@0+\DURQ2IYTWZQAWX?0B:F_+E11J[!.*0K4R -M7X?!8HY\]L096ON'1&+/Z)2#SFYG'Q#)N35BN`,))S=EQNX],).9$T[00D>) -M\@J$/AA;*?B;AQGIB5*W@[J@386,"7O;,, -M@]5$?TF[(-Q`T#1_`MD)B@UWT-Y!05?NVJFNW%4=]G8^0H<#VN_.J"W5+E`6 -M29$%[01U:98EJ9WW@\Y]Z\:96[NJHUZY]R06VM$+81'KW@7>%`QX0P#=T#BE -M=B(UM091[,8+WA/K+B;6WC?_?NG28V64^!CV#.(BMAVY,\-"!WT6%EH^6K=\VMQNW]>^&,)(-PAAWN6(,0;"VCA'WH<.0R -MZ)/#K@#=!D7VV]M7[6_0DA_ACE=W'EK[JNG7SMA&!SQ5HX]*V^86;WG@QB[8 -M64.VUL$,`8J>T\9M6IB>9%F\T$U]%.F!-TJVJ2,T]H3SCHO=VU>K$.RRF#04 -MP1BXS,@!ZPS;Q@XF7)AB_N+*]!RUMR;H[:96H-A8"7`S%M@QT@6V[$=R@B;K -MH=,ZAP$Z4`3.T5'Y(0CO6)\"B]67KGVT[TC''*O=*GL`+=[<(AH)-\-!PX*A -M=[3AFJ$VRHWDJO$DM\Y?'M\DKC^2YLVVE"`QDHN9K%)"$)S-A=+4SFXCK_=3?6`-AN2Q4QB-NFY5\0ZL9NZ -MO7?;UNWUVV>'[%`+4)FV<#L8!R%B8<9S>O>(W.UB,=.'7?GA[$UW!YWN:J5[ -MUNZ!_"@"*50D1A(^@0LHO86J;9@!"#)AVV.>\JTD>([SS4VM!V2*0HXP2W$' -M;,MI_&B7!\&S0=B'PE@D?X*/&VP/:G^?#"Q9->9;WT@"UXY:IU"1H75YH[N< -M#7Y(F+NJVMFFHJ:FA)YJ+<[S!VM?E8B>6J%;X(<]U1:4"?]]JYCA"^425$1`XE$73+2BM0 -M6GKL+1;%[4E(E/]B31^QM&Q/W!'^3193N[V@IP4^,3?_1A^_:Y#2`P\7/Z]$ -MF,?)Z.\(;JNI.L!3B*6`6@)!)-;X)!T=R;V\"&])4"<1ZV#$^IG -M*,RA'5RP-H4()_Y[YOJ+>YY54F+CID-'9P=B]#B>@T!Q_\[#V:M)._*9(8V' -M)-*"EO*^-AT]D'^Z/$1G&G0**,_`@D`+F;D1NBLPK,-S:;7@M)LXOA.B0=N2 -MH5SHY.=M'R#A#N\>K.[U\9O>CZ?]5]W;[ID%ZQ5Y0SS%I6&]=R/A/1""@JKU -M5$TH&`\Q9^F#&GH6BR0QX"^QA\Z2$=567+W3!71D)X5WE8PA\"&0]#3%V<&! -M;L3(['"UZT+,E4(S4@2)&_OQL\-^K#/=8#SNQ]MH3_4IR#'`?V`ZXC_LQ8.? -M3&HWF0X<\$#^>AAJW8]%C%>MLQLAZ93?S5PE9`P]3X9V1BHW.J;$K-3FQE[G -MGL-%".DP0<+U-W8#I0W1=S5UN]+1I^V0*X;I/;`M("8_HZH>ZP$_F9#NTIUC -MW36VAPM'9X8CLCTY/DF.+SL06]_#J!_LI3N$]K+;/[92K3$TOV\ZNXD*CV22 -M=8QKB7299"5@E3:X#2X01AA'Z7904;*0H\)+&A3)>H$,W`B41)MCQ -MP^2#Z[<(..E$HUK/.]_N[B?&A;498WRH>*1J0-6W4A2$F;"#L/17_X/0`J%0 -MX$JO?\I!$-X[('R7DC06DH@89:\`A1<(3S5D$F&\F!.;B(0)37VQ^VU.\_:J -MFT?V!@]<#HD];>!`-^"E@W`X_FA^6(-@`L;X!SOTA?8)"L["O_](\+R`)#S. -M%QX76`3/63SOI0%PIW#G_J,VP85%2A/+TN@VN8R*[JR>[[`"39&&1ZPI%-1D7\:>[.<<^+9-.S@B[4 -MYKYF&60`GW6^_5:;C02ZJ[H/I\1-[_55[^I4^'1(`F%%J%GG-S\>=W)P(MPZ -M`3D)JASJUL7ST#;V\?HX5[BZN]\45GUN89%+H_M2]OFBM42@9$!U2.'J@1#AY -MW4?V/,8*^`YN+T/QG9SF39QX_N'K/KNHX&$2XD-2+$>)X71L1_;8B1]83TD6 -M`MI\ANH*W#3NLW39W]R2H1M0R04YF/:?_L_6&L67.6/0&5T1X<9R3-3_!<_[ -MEQA5!RLM1,M)E+LOR[TZ>25],!&;0[Z(N`/2/FV94*"\BK?3(V*)F*1T;O^& -MNR?"])5:H6`AK(*!=G0,9A0N\Y^`(R(!D$0[^430*43;"8RK]E!G081[&4#K -M''K$G;IA8%UT?^A^WSOO5M#[$90TF.4W\6+D*OVZB-):UY,+`OL!-R<[FOXE -M%^V),\#N?0F,^:NG>\^>/G^NJ4`(]+,]'(JX!HR2`4XH(HAEI/$+BQQCI"J@ -M_T1N0$&W`9L`:;,#!%6#2!FG!NGUIII)&!%9IK6OZX]@4D76&\CY% -M6+,68-J`25!>QAMW,FTCGR4Q'H/-24+U-ER@D4L&+RX%U''>+,+1-E)Z^=O_ -M^?]@[7V/_NT.:P:*7YWF*#1RV(2KF(/.2.V'`5DC5IH$-S'!A*MA>S*V((?Q -M]G%9]%'<@/J!89C2UJ>HI=9:CG)%L4S(&FA#7.S28GUDI#0;A2(PI+5&,0H< -MVY+8=5@4V!83T7BVW;&NI$Y*G8&0I-KWWJ%P$_:M.:-..DRAM19JN"CAD,$F -MJU><%\$84R-2E/;DU69H:TWHQC(L=H";UM`"F#.NLO+8'(U-G<"U-DIE@''R)WC -MRBZL2:;6*:&J:2,$]S07[BGHCD]M$U3H+7F@ARE0H4[F@1YHH.3,_[80=#\- -MFM^FIZ:>FP*]07V9?"*ATY;*+[)@:6J8_2-V&)Y+='T9R35S1%J`J4V$L!YH -ME?RV`+UF;0@L#^8SK0D1_@'K9^#&J$AX#VU47$0 -M20X[G(`%8\"-Q@U@;5T.8RF(H'L$JV+6:.AC+'H8?D^-<4^>3:#&V5.J*&W8 -M'^%""&/I[Q*\QA:>;B+#'AA1+!WP$IYL(>82:4BQ+J`RP?<^O@)EI[7&!TQP -M9(1)J6&3!P;#(;S$A=JA#:*D[M_;]MU=`/+.Q0'PCSAL5)[>R#M%1_AJ*ETY -M(^`NK]TQJ'`NM,$-XRE*.N64,\'/W3LOB*P?[=]\^XBL(GW+$FQ]>``)H>PC4#?IAI6;5A!1V]N0?U?H5X.`\UA;#-8.[2/44T` -M^P-W@\:M-1EP8E%[:+8*##&":K;VWH,E%\!`Q*!'"L&@=EOE9@[I3]LD4**` -M`PM%_#<9P&H.&J=X:++2+GLDM&J,*P?"%*R%O40K%2P'4`*)[4\=#]0;M%%! -M+.,N``T)C08%U[FH.J/*MK[P4$/)$I/RRCQ!@N[QN2LYCV% -M_0+6_50SCLL!!Z8G8C?-@\B"<\2Y3K(+'#]83$"?(P$*UH[#858XOT#0[N'6 -M,HX;[S/L9EA:;VS95MOC(%-RM["I??KNY/3';=YW4.>DA".2?1K?9FC9B3U, -M8>U**P8!-*`-2U)KJ1WLTV-*3PTEAL_%8J]RM!KK7(/%A"Y]F_XZ#*B77"1%CW8OR+$^?K-,(CC=76<5AZ%DD@S<1R2(MPET@\.M/X7!]I#-59'#2P*HATY\D3O -M0AZY-6N()I=^O@O8>QLUS4`$6.-VS$3P71FG"/K<&(,RMU5!275.;%"!T0EL -M3ST,>V&G*^V1!D!+G#7!DY$4^FE6YA@,+1^7Y-`%%G*$3I_>Q:M+C"*$GV]O -MKOQ=-U+6VO*9&5&Q&)#!P^BAQ)9"6'@]/(T$P.0N#@9-7+ -MEA&_^F"C[X+#/J/Y@D-PB*1RCZ$`!:JD;;')$>E$9/>\!+&$L\BZ[J#I=:?& -M>.3:$S\`Z2PZ9>^P;$ZV(R/LPMB+%AYKIG)01H76%;,MG?4)U,I%H5:#QL31 -M2]A:DU^$"$C.#,Z=4!W&(STO"-V)BYR!#DZC(\CUQ.X_J0VA.T,'E;:`R8A5 -MZA^;'E+[4T%0:]`:#":&D9>6"&5JB%SZ3-:L&>&<'9E(0[^"6_,X=.HL^>GKZA#;S+3X;3G].:+^8 -M^.N1##\#`8]G?SNP2AX6H41@QF -M;.`)LPS8,_NRA2@9AG8$*Q0)*1;>GN?Q/B2)8+@E,+?OCZQ34/Q#>09JY(84 -M06$Y9!M;&SL;+\@01IXX!"5W#)*,SZ^N6=8,:K\(7?W4$[N<07-WV=6+G@(0 -M#E/:;1V[CC>B!D&?IQM];H=W0A5A#46$5'#(M!-3/>SA<$'[0JH.Z(H#L(4; -M3;%`/'J1H&ZN@Q+"<1<^!9*@P;-Y\?;L;$OT@=R.H0Y4KG(9^$OBDTDFP25& -MO@X&*T-1.`041@*F -M28AZ%2P!A\*B)-O""K3]H(V:Z]CUY1&*`>84(&8B=I*R]829=0?Z&VU),.]D -MUQXR(V9_W.*#_?8`-_9Q@Q+)N%&`Q[QD7PTX=`/&B"-;.+4%'9D/1G1("ZT@ -MU6LOL,&D?R,;P/$,%F2LA13W/'"`W[AX/@7'B4P!>:Q,!/JHH>+X]79HM6]% -MO+K(5@"6$]0H#2>C>ZA-;8S5M]J+]+0332+WJCKEG%ZZ-^BWX8@=J00<)="F -M8W,8B'03N*Y)$F'V#WEN4-.KOG+'""R?>1BP^9I!IP56Y;`0(V:3X@:*M*== -M0WO2`24'H0`1!Z<`A0R)PM]=N3N0U+2'DPAX&86[@[&#%7+' -M#QQB)Y*Y4#8/GVP+R?)::[C0R"))^"''!$U<)TJ7PKYEX4)0SK:L.,W@H5S& -M:N7X11.7<'$';+# -MEG$B<=!2A).0UY.C"Y$6^S'(-2\FWUZ^_#KL[!VJ*?7"GP/GYB+Z9K>9!,?&W?XANUZXK":9OF$E9FFVNV;5%T,=:.:@)*!#()1\;2 -M86U4.!U6!GW2RK6[/AV%(G1Q/7&?\^C?O+UI8_F=5&U0I:?R,*G&%%D!A]F* -ML(YO=#AY3(99K'%0=QNU->L'V[5^`N::POT[3\U_H'I%B:GFJ$@+3Q+'MXQ` -MF1DZ8H\G\72BLVQ=K+=U0Q%!KX`Z03I,%IBHXXMDC;/#!^=6))BWZDRA$9"0 -MZ&A1)%BTM*.,2#M]:1H^DNVT:<5!((J!]D!?#QV-#Z"$)7L03"B.D]6/@G8DCNTVV+G=!L$+LZ&+98(MMC!9ZR8&#''`SP.CML3(D:`M-(@FCEXMI;/>B!Y@;=-*A8R1YPN -MHW2_GM[#6G%I#\>2`N9!C8TF4F&UZ.:6 -M*$GNQB03@C@S],SF3Z05,V&I9L&@^#*(BL(";.BC`-5C#A-$+8S86F>+-UC$ -M(GB>G<1:R(P)B,&[(Y&4#+5%CGM*.EAI+,IXYBV:;XM*2N_E*$!),2S.R!SK7['/#`M2GJS>>:4JIMPV4!GZ7VX-3(FN%JZ+?L##%``S7P -MR%JG,-ZA]3O'\]ZOLV=3[OLRK>?:'*89O$"7%L9V9.**1'N$MI^MYE,K;ZM0 -MD,:AUT/K*'<7LC?@T)'@T)17;&9'=WS,5997-.J'J?(4'&]9R7QI<@ZVVWA& -M9N`Y[7O4-7ANJ7?VT(/!3EQ]-_9LX;G6S2*`CG#\JKH<%-4EF3YG]AS^6@". -M[PKVR4H%[B927A*V-*$*^7!8A=]*2&3$TR%A)-TD[G)S9^!=I^@H8GD8<8+$![>Y[$ -MT9F+[+:B);"?6@*%@"G6F\"=L_!$-6<;]VHG4ZH33N!1,,2#X1C3S!I4)#A+ -M:TW%.4,%<0.RD.=KC-B$XW(EPT=U/9D[PG(!*G1PIY-"O:2L(`M?SP)B+T2( -M/XHD<51Y`':7[XL0^X -MQ6'2I3D""9>'=.M@%)>FY1WI\Y*5#>2BSCWZM"-RAC$>R>?]UR]%^-G>[4O1 -MS_O/<_OY0.<=)MPQLV*1"\!7<75),CPZM8Z=]:SQT)?,->6 -MV2_0O^V5,!^C.W<^UX+OS1Q-:,,Z]S8*.K0\500\3+?#UZBS"/^6YF>A8IZF -MBY'N0&T*;?[G-Z^WC-DCNAN,5>A@/D5(RG[/PM2?KNGG1P>!/.\AX^)E2CZJ -M@UI-/:'3R/@OQ!3Z!"S]>#CEM"@B^1[RN!=6#]3*8"YS#[R'3N%M5I$\-Q*) -M57!_26;2$]H<)C_DJ2P"4;)3^="QJYHQ< -M($Z=0<&OIY>O9(*..'Q`ZE0MBZN*P./L+RCF=X2X5\<7UZ`6R`91!UL2!Q1[`Z&+\*#UFK2;]6[*$+\M -MT,DMSNM"$W-;N`64CS"2"4AD\`%Z43$6SW>'\F`0MQ/8D=;:6)QUEDXU( -M]8F3K6`Y#OM%X["?&H4:]$C@S)B2QHPZ.+&D')*8F>\)!#PKE$5.8NNI@$ZYQ38EN24U`I4&/5FWJ*9B"GIL.0?`8I?TI2]K._41['?,SMK2 -M`W+2H[*O&VAT-C_'GMU/]!<,VK8V1002^B:V9$([=)^S]PGC9,5_A7B#4AD3N,=I"@\985"(713H1',:7')#E;ZL;&C@HP -M,U^Z'L8:X@!S0E'J@#"8SQUQN!$9NLBX54ZPL*G%0B+^8B^A; -MLX>W=6%*.RZ@C>P,^*01\7:_M88ZD.T',UOH@>1,,J)N96!+T4S:EF8W^[.?E#2'!@13%-X*4-5N&:XP49$\?`6 -M!J%R6(@(H0Y)(.6T_0.?*H""[[:$J8N1S[2E1YN-FD$CI!!VC),@SI6%16LS-'48:X+HB;F:D`1%CO5LT[??, -ML4[@7H%LF?+Y"HJFHIDG%#$Q;^G8B,U[RRC:*=@'33R,B>),EASQC=M/T,Z1 -MPQUE4X``)3[FPK&/_A?FDO]/<0#2T/IMVG-A_Y'<-\29#97O?"N.K9#:Q@7A -MSNFHT"T@"E#<\1R/,!_[").D!"'**!Q+9=VZD<.R#B2W.U]X9B9=F*TX)6%Y -MS%S4RA/?/)[8*S!`]@S?/`$JK4*ZA!*.(VCMYWM,]W1_N@E'!SP#"@<>DOG9 -MUL9)S0@^-RO/,()>0I$$F#&>S^_<.5*SI=MU*+D@[O3PTB`[@5U%H+2LO2(F -M@"$LHI]F>!IN0>[K^9\)I[CO@OACN0CQ: -M'8'%H]?V\/+&>B=*R&>P>X:N9\"=>C"^/N=+@K;3`0*8+^;\I$+)<23\<2R) -M(I&Y(DH=Z5%9+)()^J*U9I)T^20@;3XMF$VGYC\?J\(C)2.Q?:Z,T3A8T%P7 -M9RCOY$GD?/?9GJXUK9TEG[`"PD7)ZT:>`5&'%:%_Z>2&>V\>=LX6H2LY!)BO -MP>T-]LV1V#,T.,U_J%^"81HOM(LJO'N83P&8PT40*ZY-TD0.!0\$*DET7Y!9 -MHK%SN4Z23,KLOC@>SO0K5$O -M.Z-M<0C[SJ%XF\C@;+P=BVY]L.TQYRH(*SR!/T0_S$@.2SX+`?-U+]7=APD; -M#AVULD(YS$+?H6`(Y`-5Y%/<+E<')B>P3[&FE#.'_9@;.QLXO3!,#SHCR9-J -M7-[`1/,-.+`)4PPR`3PW#]7A>0:5L%@S$^CFH21`-_%CFM0XV]Q(WL(S@?&( -MU)T\T6*P+<,&Q;GV_#4"]4WQN020^EOC+3O&40H]XEV$I'2,(_0Y13W7M0Q= -M#-T8B0$TL\94?&E*YL58:8EU\LI]:I9K:K+"KXMY@OAPA6=/),7"EARF*"K) -M*WW_8-9B"I>!QV>01*31(A(W0.`WD?F>U$*A_)V&ORJ\)BVF('(]>`"Z(4-APAHN+@=HV5+EW*I-+J_`6W -M'O$B!Q>K-1$+T3.!P^I[HPC-+98;^,69K9JA)6V+?"^ -M$ED"K,F"=C(TSSJBBTS#>.<7764P>"^OV>&M-GDH0$:1-F$#/^-YX?(% -M=MQO9Q3G3I<3V;Z9*(HK"S.$/*^VF=%"S(O=?-T"YL6>.2\2P*XPRVEVLCZQ -M2354UQSQF7;M9@*J*]Y -M].1B1^?UPN=!`OF]);JWD*'NFMVKX*P>GO#`*8H;B4",1]'%MZ`>Q-`/DR`8 -MB<$WB/(90\ST0?)06%\P26T9!IJ_>;4[V-/$"@$^-R0N#M?KWHGR2=!:$/L1 -M8A&AFP+?RMM*87J+)&5J-XVY[Y3,W,`:8RZ)D'Y2#K)YZ+Z'A3Y)QZSF5/9I -MJK(*D(/5/=Q"53&$9`EJT6H<%'ES&4D.K^)\7&<26.NO/'OF.`].M(XQDR`U -M_L__RQ/;X72<,R05%& -M%*2#'OVY;?3:TUP#05'9$X=%/2&L_:1J6"VE"''-*&^?-YS.@M'FEBPJ7[V' -MHO(#A5';IC#;9!U@"G@^MRFU/QCQY+B#.&$GL_+8J,IC4"XPBG8P;LLR9W9X -M!ZQ51+W(VN4;FE"[_53MU')Z"9KB,/&.BIE+$NG(ZI^^N[WN'M_V;TZ/WUZ? -M]B\N3RYOX?^\LD$8IP%N?CX_ZUW\P"?\([40U*603B+5N)D#GBCH,Z-SHB,, -MLS=S/+RIXO3ZVT]S3^43&X&*6UOWO8X -M9\L-\A?>3%"\7H>*YZ-1R?V-,DF, -M9;U,W[!!MW2@2P4:TYET>&S7R5P'K*`#T"\XW"X:9%$U7+O99#%(2%XA*YR\ -MZ)7DF\#X.I.(#3STV8I5C$>4>-=,IDI@V4BNG4U,H0'\WF%/E.$,D02A":"= -M#=29.*@!LPFQD\3E;VVKJF%P4T@WH6+T(!V7H*,)=">(.]K!'3`O".Y`<25" -MFS+WK3&H-F6%H\1<[]Z]V]Q*4G/QX\`+['A+3,G=_+C=7?O`',EOTP,I^EJ. -MH.:!H\T\>:V=%"BT#XJY-RCE>23/V=E\6Q*8<,G)9K$?@O:OD&=TW[*X!BG2 -M#A4D)WG%(2-C6;(;E0APB7BYDD=C*D>(31N1`Y4,*CD+.JB]TY[H4&AB=`+I -M'A5L''\H$^=O(-),<^+RB(^,/20^/^64%T'D23=J#18[^07[9GJ;N#%L3,G+ -M8T@YO7/GFUM:^BIULZ`(N4N._Z4KDB1K9AC2(MA()&>>\$TEH>P\LE03+48* -MT80O27C6V18]?-TQ%)+K8(!YJ6^&[H*N?S)/G*NK5J4G2>R*LUQ^9DS2O6R$ -MA`)[N9C-589]C-KK'*A0K-[.I4JJS@$#AQ(-O7K:'3:OP*;1/1P%6*D\F2KP -M1:X,GN!H2J@[Q?DF;E)_,1LX.71)>61'!VYW(D\D4=56XTCGNGC/67A/TSVR -MWWFJ:4\FX.4BIIPWW9<]>=5V-K70[@M+774K+IT55Y\-G"F>^/S*'8^<\0:: -M!;`,U?D\N@6-G=[HLGF@H*.6=%VH`T!<;B=5,Y5>-6FJ:W+V'>'31"UX0\LH*47'"%&-MW(P5I^78;0)3=X)!3^Z81P?? -M10YQ@%=JGV9BB0,^(DF[?LQ'S82`@M/I7B5A%+/KU12$XKX`>5&12(2B)N,Z -M+NSU9"4+9[T9CYG8`72;`-TR(*I&=@$O4./>#"U"C>RT/=D]-(52SI/D*W9> -M>YZC=7.(!1U'S&3UYAONTHGEB+F(G(R[DCX:X71#/!TAQK\]%;+*V:NG'"(H -M!;NJ0C.H[QYG+<#WHC\4GUUSJ -MS=OS\^YU[_1&>)>^+5IC*2^"")!YE@[,RFFU2N:H1>5@U"Y=V-629I-#-KJM -M+H@BG["4+2,'O6TJHZ5P6CY3"9TWXOF&+(=$\0>Z>Q&8#Y[8M-GRQGD-@B(F -M#U$DCP22$*?4/2+%I52XGV%L*H@`O)\+F4$JR]2&$,IM)^=X54LP^;S,S9OJ -M=F?VZ[71Y=+92I=][03AQ/8I'9F>AA-TO"%N%Q_IEVCBN#ITL_?DHYP<8AL8 -MI7+$?L]44EGIM"/;X4`-I^3&/*9'FA3D[&64`)'WKX78VV:/%Q9\9=]K(R\R -M,&$V@0ZE;V.6]#2ULT.C)T9=NPM(BU71-E>022?;*R^,A%*=#9RIA@; -M1$;F)NTX4@B-?!D&H(>1MJ[DH#CP2PG:]B5M#-.BR[I%`@294%3,VA!':?"MI'.LAI,;Q--$;-)2HBKJ"^)K'*K'F?:U_4N@DD[L(S?%G%'^ -M+-/R>!W1;3,$??X'FJ)0S]Q9WOP'_/#G.V -M7DYL/$Q,F68MJWVVTY[R4K@7Y]'-]6MPDJ='N485&2C:03/6_0(6.C+;!ZQH -MT@1XJ]`2F4KE-W&"XOSE5KI`>!HN(NNUXTZ$-TVY67QYZ:OP4&F9ZY*^NX]\ -MU^N`635P8!5CX!?2W=G=WX&_!7A[YL9M+=,+[BR%`P>FN;_#=\Y*CBQN$J&] -M=1;:P$6IWR[);D#L8^C7-[#4SD%U?:?59`;/]T9-T`R\BX,Y)P=%2ZUE^F;I -M&E?Z+0+BA$L2GPA'!+QK!O53S+CC<#0`#`/&FVEAZ%+(D)*)*J^Z\Z3]P?;N -MC$,$DO%14MIGDKA,QJ$1)0QR,;V0T:.Z)2+RFW/U#H4DQ%#1MLK^[YA9Q3AY -M`>8&$E1M#XU$-K)!CLO(18ZC5;/0.%*KJD\13]_(PL4Z4[=[W@0>1M!L6V^N -MVF_?;>-M./_M/_UR_^/G^/-5UU]N#_ -M(AUQK/-P$)Q?QNHP+^LM[%=+EP![.6@OT7&;8L8"["$<8PLP'J% -M1BO%ZB`5T'*Q)10@I5=:7M8<";07*HM9'B6@P'E<,70`Q`X&NB7AJY1K9TXN -MAAV*Z8BDCNC&6`=B;'0(GOV0^JWON/',>RH_VXO3FQGIU>6UU`?^J>WW;.WY[UKVVKMY>@Q)V"HWC/_.[ -M"9XP`>%F?6<]V12_M[1L;@@BT_@+J.0Q#0A/$HA_Y@`X]\Y0`Q*/!J`]Z_>' -M(X`X/KGJWK[Y;OW)DW__V*^HKWVWA^??VS`(>J4->75^^ONZ>YP#K4#?'U[VK -MVSR@WL7-;??LK/_FM(N&,$+(5UB)K1;=^(9Z/WT3$ZJOWO91M]MJ75Q>GW?/ -M^@(50(]:5]>GYO/ES:WQ0N"\O4ACI=X@GOF*M'VH`Q[QC.&->_#-L[9(0=L6 -M\?_?=G9;>$]M#;"!Z\M^O*%6XB">OCL]?7?;W]LRG_>W6K1!IB.D3A(_V638 -M%.;!EO5K:\UX=;C5NCV]N6U$(TW@*WSDM#[]/2#T:^LK[6CSCK$U07D5^H/I -MV.T,U];6"D"36P/$K4%EP!)DNE8-,RR#41M#9:5RAF\T7C6PEM$'^Z(/UC"C -MA,C1EU2RZ$N*R($D0KD>*"%-BD;V`Y"(%H*'=%HG/9BUQY?GYY<7\'P-J^O\ -M5(R=$G_]D3./MA*N)!;AC9@H4#W,QD@C$X\NKGWL7KRVY$LEI!O!,$S4$A-V1T4V9UTE`8BX6?0[1 -M7"Q`A=[-080^Q!+3.(+-M:-I#HX78U:73I0I29S):8&=?WD,O.G\D/B!WA_V -MD"[P[,P.B=>+Q_[LD$83P(LZ/6D.\8\H'N$65Q]W!8!8)1;=[5D'T+/[=*-< -M+5AWT/9&M2$QM5!-6%!&QNY]36CTXM0"C87U6`\X6DS`.*P%*C:+Z@'_[V`0 -M!1B^G0N>:+?VL)5=[TK`I&8.\H'CRXM7O=<8E'%R>G5Z<7)Z<=P[E>P@F9-; -M1):!^\AHCL].NQ=]W*]"42*72VS'%&Q(3T,\<2(?O&`"-#4]''>&_,#$%"]; -MLSNQEC#\.:M"C%JB(DJ#D`Q(?C!K5\J!3)0?25$2B-3F]\@>^O;HMS[?;_6= -MQ;V.JNW\NW_2A7SKBA6N6[];N-VQ$?W>@?]--O[YPJ2"E<7PIB=/Z%SBK^0# -M2#CIUUO66!%],I?DUJ/?__O)$ZW@G=]_7__GBQ<"G[``7+QP(GO(Q1)LGP6$ -MI(LE,]4V'C3Z_;\[7P,U65'9T3/['G`.=^FE'PR@SH*:[`8LJ5Y7[/S]'YV_ -M0_U__?7KW_^Q\RO\^>L.]$R&M"!*^[/8.4^><#:/46`E/4*7PCI)"Z!K,CVC -M4T82:@%D&[+UHKI,RRB7VLUC8J5*MGY_L;YA[5B=KW_=V?E+A#_@OYT75K3] -MZR:^W=KY^W_O_./K)T^V?]W;WA#$8)W]],.6M?'R]'7OPOHW[RW]?;VS_@^H -M]_JZ]8=Z]^3)/K[3'M;A?T^>[,F)X(ZMS?_X#U\`RE9K8[JU)2`M($IIT@&= -MSFI*DB\LB6[MOC#+I;K\(0@`K\!Z0;]MXOQRQ6T06X(JO)-4X><_K#\V:%#T -M(9$=N?'DR5\N7I3_%>W\ZN]8,&NT`B^)[WK+65QK9MO -M!WA3$[X%_F=\F-G^7@X\O#XH1'B:@Z"X4#Z69BRNM\YNSWHOKVE_4-I_?>T= -MLF\_P"8:;ZGA.C-'';VE*?L@K?7/:G&8.$S'1+NY?'M]#!]1`!@&A-*I0<)T -MAMBJ_&]]#$^U8\QFG`_#BLK,GKA#H),',,-]::>P$/&]NJ!P>+#?F>8607=" -M%Y=`GRL+P`U.V\\O09Y6+<*D,]AE7]FJ0J%93L7,/E$%2[?$5Q1:SD5:-`HCGA2VAK]7M*"L@'!12AT_Y*&#S%R.10\".;3SH&/3'59`Y -M%P[6P*!D(G7@*KHF@02=HD^AYW8XZG/@9#E]&4!:"H0Q.Y5]P$"5#5=@Z$6K -M`6`M?H'NZ9J39GQ`NQY`?G=")[R2S3"D&%*C9`F(933#*,I@M>X".]C -MT`P!-^,;(?U.50$KS>"+!6T>^`"E>8F, -MR\,9VB7\-@\>$]LU0:!H_T88XO:.1CC>U&X$S[FDFF"$#0"+A?L6?`R -MJ9Z!+A7I&>@J>9Y!6"R:#FZ)?&987&#BT%A=P'(IGH$NX;H9V'IS44,H%:ZY -MT'W,?%H?I4JT9A#*Y60&?&Y7L4P-&`->ZT-3>%-]\/?/&X%/_$4C^#+IFP&N -M-\&*+!IV\O5E9D##`M:WE/,%E@91XD'2]]8K+5.U9US4)+G9G"NFJY!SMM*+ -MFZ3M7Z./D?SG]FRN')$>IPGHCX)X2W[DO7)QBHZB#JR:80=>4`29[9QBV!H0 -MV3[(`N?U@A=@-R1`Z&F]?/G]Z7$J2L-PLA+I*@]J,9#PHGI!B0.T$)L=E.6? -M-0]E!:#IHJP`%H[%*J@:Q4K78@48^Q8+@:1_,;\CV:]7B"QY1SYRXA@L),!N -MO7ST<%",1ZZWTJ^F[ZT"-,_Y5@.%65\-P#P%O!Q->M7*H:2:7@>JNDVFFEX# -M5JCIY9"ZC*F`S+K-&B&P2MT(1:G5C;!8M6Z&TAC#:UX(J=F-,$C5;H0AU>U& -M2.@_:X2P6#2#!PV])KRF?#?":#`;E<;>"%YZT1HAH1NM&0*J^HTPV)'6"$6J -M^XV0T)76"(%MA$8H8=-!06]:(X2X:0GW31%*9Z[PFE5\5[ZP0CCRA^6+9>D- -M*\1ECUCYY\0E5@>N0LY6>+HJ\"IE:-K751>P7(IFO5T5H)HCJS:DYLEJ@"/< -M!PTPR@5OL3.K/DJ%R,UW9]4'KQ"V^0ZM^N#E8K;0I54?0_FTZJ.4BN.3/3GJUFX.S:JH]3*>P*G%OUX=&[51^:W%OUP=F_51^>'5SU -MX86'JSY"J4#,]7'5@"XT0+*>+`!A)XYRU6RE8L\2UP8!YG[<:G7/^S_VO21R -M\ST\])]L_KC%<6GTF/X(.">GK[IOSV[Q[-/+RYO>[<\Z_"X@M-L1"I_+=\3&_$Q"OSKJO99RT^:K=1L?"=Y3"]\GF -M\?'9B:!V+`#@I8Z=JLF)@E(_V]"I?]-K/!:5?MD].>$XY#:=BU''C_3/^_P9&4ON]P.%;AYA -MTF$.$QHI(.,`EGXBB_$E4BKJD8_AJ#!$=2K'^$V[:LF!'2V$*^=X3\Z[H>GO -MW)?^3H(4%6L;&$\VL7]%VV75DR$Q$47M%8ZJK4Y:^VPNZ?VM5K8``DF]3N#^ -MS/6EZE"XLO3&X92B*T50B8]V])G33M[G=S=]3W5)0CC3RTRT>##HPE\#ELX0 -MU0&DFNS6!QU@?L_ZX$WJS/>SL$..581?EL0;?-Q?$A/TWV4QET7TEB[26QYQ -M9B^-&BR)>=^@MD+K(!6Q-M*$GCFG1WTL5EF:+`&!\;*_P)1[C?&.E\3[?DF\ -MLR7Q?ED2K\',$AB)]=P4L\'L$!BCQACCQAAL1#?%PLM5&B-YS3&6JEPSCJ&0 -M@N8ES1IC-%_LB^88BR5GJ#R\V12O";<4*`^-,9J4@7=3]GE3M382WH,43^FZ -M>-RCA_\OAQMBXDZ]X)8.7Z1;ZM]2&*EC388%TO%LJ=6CN9!2ZI/S^:#&:P^D -MQVN']S5%'M\F9@`]879E'`"PF3G^`=^*J[^4R -M5F2S)D@N&)'?K0N88WX4`V-D25U8VGX3+L.Z*$*[Q;>_+(.4,5/JH65LE)IH -M2V%EK).::$MBI;6,NGC!,FAI&5N,56B/%*-DU;EBV#++H!+KS5)8N59!)=;E -M4EBW2V&]70KKW5)8M6>=M%B:PN=;.)5XSCV=\FZ(-7%'?;JUC2HQ/FM -M(?Q=4WC'F>.ZP\T#2J7=##W'VJG&:<"%"BV=2I3:LE'"4Q]@&MVFB,%H,6M: -M.TIIODQI_VH(WW2E-IT`F&YHL<1:R#?X*M'JBY1\$ZP8?DYW$OJUVT^A)WU, -MQXCQH76QHGCDUI:EG!V%SH;YF#6[-A[?%8;QW'51$%`7U)>O/^2\N)+R@OC^Y>4%^[[+RDOOJ2\^)+RHA+C2\J+ -MVA'[7U)>5,;J?TEY40/C2\J+LMC]+RDOOJ2\^)+R(A?C2\J+`H0O*2^^I+SX -MDO+B2\J+(FG9*.6%OEV?_!31'[F?C.J18Y3VX-.ET9<<(S8-@G]E1*#Z0BY+ -M,80\4GO9994/[8^CPPI0`5+X/6]9IB"JJR0&R)Z[?7&#=PWHH>?889\N\JT# -M7>"2S8',]ZQF`8O<=EE(WS8*2="8^HBX\7M_2D=EBFP+&L@YIEF!6C8 -MPJQV6`!,+)^9$S/S1H@L*YHC+HM1N\^%(5D#'(G77>O*YJP'B'=OR&VM:AQ- -M!#<3D0.78,1FHF9U5C3-`(!OUW+D9-K2V4@2(B9`SI> -M#5;%X"7NF7S04EFE`^9M>A1"UEE$!@JZ9>QQJ7C-P`^*+,]"\/XO31$&C5I` -M&!_+-(E'K*[E[FM6 -M859H7<5(RY0VK#W=JJPR'7:B2]HF.+5GV40%RC>`KU31=`PW"FKW#<(29^[S -MA)&RSA!`?#(!LCA769;X(B[#FG3-5)889ALQ8! -M?*E7)`ON.Q\:%P'_GP7OF[3C(_PWCAH4E+?!70C9=$WE>_GS85%?K%_MO%WS -M(L@RIXP.66Z3IB"%M=*P0Y;@2_&@+D^*:W.OV*L-65NZQ74!:<.E:2_D[8OD -M0]:77BBRZE:CEDV"4S@.%_[0CJO7K`IKJ("K35`!%FV')_`LB,0QOF(P?9S* -M='V2A14=9(YZ&343LH[IF.SMU`*2IG)9)33H&LX2#;H@^B(7=NZ$LYJ5B)QA -MN26DPU:I&3HL'P*H!XP;#=7UK8RQ*$*H<#`:P(7A$@7P%4IM!I;;BIGLZV)5 -M6=TF<"/84BTS!5MJSANPU5:Y`5X855$`7RHX!&0M2]R`+14#!F2%(SH#6VE@ -M9#%R8R3*$,H-.0.^('"@`+HH_J(G43=)I!IB-A>/U=FZ6%7J -M9A:X;^,][8O8J=IQS4$=>G94+C^+D?JN/RJWTW)PQV//GC3KC+X/9K8#\L". -M2S?/&D1\]5(*0'S]4@%"N -M]:9!F[6W`=-%>=B4-LX\*:3+M=SJL-`T[$>^#5ZGWX]@@I>-G*[L:SJEF9?E -MF7ED,/G)AQKE0SJT23\.:5P?4T0@&_/4F,3RB-E`J-HT\B*DC&0EJB>?U^M) -MW.4T#I/6P-$/8#;&S4N$6`>/PX*:HO%>Y5)8VOG)Y?#-S7ET*6^_XK("_=C6:TP/(DA&:P%`$]#FHY -M`MGCGH]!AQT>CT%)>4,>@UA._IEE*3T6H9S\,D%#[29,)MSL>@$S]2?>X?BWTX?1'H9*3&7@9 -M4LLJG`6'W%^23>&=N72Q683U5=A -MU/8.YF)3&_).SZ]&A8[,+T=B!=0R%E&!N7RKQ1O]X/[R5/0#_2M0J=C?JT&A -M?*>OFD#5/E(U!3UAP*I4LEF'ER!""0:6)U*]9U5-(Y.0X/%(51J02Y.LL@IK -M$LY/;+`BT6S"@T7@)[@87E:18D?'H7B(TVH3**(QR.US)02B26:(QH))Y9&+S4K -M*[$G989%-7:9,5")[:V(G;XWHQEVB0^H$AL38RR-G$V8L32I="*-E0EI"3:6 -MIF4DWEB:BCKEOC2%$C]6)>YR,U-/[+$$=FD0705>92A9"7XJ04AS"D;BD"70 -M,:%(<[3"1"/-2=6+(2S&-Q*3+(N^3,]7[^K4P%U2=\]/?-*<3CHARK(4\%C< -M"KCY"516(5@W/J^"5E5,7`5Z)A'+\G2J-X3JT2C?QZE)8SD!7I7H936*5;LY -MC:AHB6%6H[>"*,TDDEF-Q%*Z9CKQS,H45F%Z^8EJ'H'.H*E7N)!,^G;0Y0D- -M'J6'9"*<1R*5OEAT>4I+VA_%"74>B=92BFMQ`IY'H(7G.1^!3"IASV-17-(* -MK4CP\T@$ARLOQV6]EL6)@AZ!ULJK,$DL]`ATEC99LXF(5J=A)"A:G9Q,7+0R -M)2VAT6/1HD1'CT4L7%4YR$N,M#+%,.?B["7I++6;4YQ@Z3%HJ<1+*Q/3$C*M -M1JLL=+DVA61+?5HR(1/JU$IBY^N2V&9S:ITXJB5*:032JU.\+%(#5:5 -M:?'*4C%.WV3?G,+*VF.\*H%4XJO5B)7%+-6CL+IV:"306I+42KXM,^'6LD1D -M(JXE\5>N0"9Q5W,Z1D*OYNAF:J[E\)<=R'1BL%4IK.)RU1*)K8*<)!A;B!$92N1$`G,5J.QK#F3D_!L)2*<"&U9$K7/6=0EM.1&>7Y"M17I -M+.ET*$O`MB*U9;WJV81M*]-8RJK/)GA;D<;RWOC\A'`KTEE*,?HS$MHMR*5JK,9S>Q22,B'?8Q*3B?H>A:9(X/G%R>G%<>\T.7.FO^SO;;5. -M3E]UWY[=]GL7QV=O3PBPW>NT1LX$PY$;;NT,%JXW -MVK$7<8"WXNX(>#HU![^Q>5%_9C\,'"`A7]#7V7MX`W^UQZWCR_.KWMDI%7)\ -MC"5`;6[$OT:M\)W^NWO>/[ZZ>G76?7U#_0[XZI&_J@?QJW5VJQ=WUGMY>WEY -M)J!_['OQEM5NQ_;DN^-C?B<@]#+,5^TVADE^A\V&QJ6:0/"-6J$W@;!S6T&5 -MA2K*X7P/#_TGFS]N\8%%>DQ_!!Q9DQ]/KU]>WO1N?];A=P'A;\YP&ECKE@6T -MX<^Z]>1O+[@P.];HP<+4"X/'],?2P@"""FL='Y^=R&%OG?4N?GCD04&'!5$_ -M.RF:$*J3ST[4)_6S'4`'R,X6597]=7:2ZG!XD06HZ'2`274[E*)W^^O3"XTH -M/!F%XG/FG(0CL5QW;F5KZ/H**4XD8P@50K=-2BU@@T -MK44IK+QFI2JK?V;LULSV]X#34M/@-S%=?(` -MOZ-X]!V-YBM@SEP4C2VPZ_/+BRWYJ'7>[>F[WL6K2_H-$O.Z*[ILY`(MT0%7 -MW>,?NJ]/M]JP;*"V/:#40OFEPXC?O$1"!_>OM>^_MBSKWW3LV_J+U1Y9ZPG" -M.GVTK-]_!X@Q&#SFQW;\,'>L$:*A']AJ[^_N6FWGWAE:PRGP)VOQ'Q^L?_]A -M;;S8$(3HSU__:B'P.#2HO;#^@/_S=.]>'[_I_2@Z24)T4`N=?&R]_J5WU3^] -M^!$E>'L`U:;^6/BN#PJOYW$28`]>D2P&**IX1]1V#'7%+$Z$A$>+_;H(W>.S -MR^/N&=;IWZ0J_&'M3(.9LS-<.#OS,,##EYHBE-8<9BYH4_X$ZAPN?,L>>L'0 -M]MI[G;T]8(2WW>O'H0M]U,KCCT!]MT6%(`!WKY0R?3%QX./>_A&,X1&`8M_; -M4:O[]O;R^/+BU2.U6KPFLKR^'H\PGS`ETN?='TX?C_#,OG/$0/V$`MRW/]RU -M7MZ<'%_U+F7?]6]NKWL7K^'K06>W`WUH(P0,:PD`J3>3X1!^@+9Z?GERRCHD -M279X?]!B$8X3'>ISN=\"S8E1K/9I2ZI1I,GN+*)PAZ;4CN!?N2^QW?]U_`Z^O3GHX_BJ=?+V_.IE#R=7Z_3XS67_6/W"=VV??]_2V]?7 -MI]A`JMK`]7M?+>MWH7-[?=LS/]O>`25GLHO_:E -M5/BW>/&'U9Y9SPX/%<#5]>7KZ^ZY`:,^WAQ?]ZYN"[[!F%_IZ)NB^'XT!>4+ -MAC%JD=:EJN>-6D(YP];"`I5K54ZCB[?G+VG5'.SN[L(TRH/)3C4`ZL'P_2B+ -MXG&'R8#_N7@.MA,%5OLG;[L=HMN-?IJ02`-,,%DOFA<>;ES`/X./,*.\CY;5 -M/C.1X"U/-_B8\XU*AG]G@.GY3AQ[3DLPI:Q%1NN4A#T@TS0[ZUU=4G6@R9A5 -MWJ?^O-4:6USF=;IUMUK[D'^@Y'T<'H+\P_7'`6HDO5>G(-]$`X]:YS_`0NKC -MQ$U1$/.D'4UIFHQ:%^?Z-/%!?KZ$=ZUY`4 -MOKJ\/M=89>NZ>P$C#;]"V\>!OSDU%F#DC.#5;5^(D!:-/@+0QVF+EC0\XQ'R -M>2NG&N_.S_8%JS17&Q+`Q=!FS;-E#R(UIQ&R9'X1+'LDZD#JJZ4N?$WJP_XP -M[DL]@I^4&.-'C=^CNBFET7>6E#)D$H"LQA/XHP"M[@Z](R^S1`,]AA8?J49_ -M@#H9@!X&^N(3^`#U7">@A9\"NP>@%O2S4'S_C:IH?QXZ8_?^#^S_%O4*UN7@ -MFV?MA7_G!Q_\MCC&^6UGE[_W;<^U40\4C\/Y0J"(%P$IB6FL]XX_"K!<0;>E -M#4&GAZ*.L+KJXG=8H&.9A[<#[G2?_3JT<(/;>5>"$ -M^4=+ZP.=?FL:1'%)3^#GI"/H2>L'>DYW`[W,],(TGGGI.HFID&ZRG"'(+'-; -M35PT$:'+LN>$N:(O,7>R(&>`__!=T7=\;M'2=G(KRY\8`F^\R#3W/2PAME^S -MR/"^-;N#GWWV39H"L$I8!-#C>A<3%Y*].Q^-T^.AID?"KEKR3%T,?#)"9S4E -M]4/.MWT/_VO-HS25J&CEX8<6S>=1;D>@#%'\I].*'B)L5AK*B8>M&$/)M'FI -MNB69X:T4]^NT#/;6409"__+J%G@W"@5HGN-.?"M:X&QHBT0ZTN+K=\\313LE -MJ%NMKUI?63]-[=B*`_YFP9!:8DC@*\R4/BD7U]UK=E`G$[/CV2T_0-A"D/Z8 -MH*0/PTJYKI1O(W$WI5Z1+R=Q@;Q\VSO3_4E93WX4=Z9H1QK/2$5_T;H%/>8& -MS?#>]27H(1>WZ9IE`+0J%GVCNF8_0@]WO0_V0Z1U,/DK!@&HJDR37@H28+A: -M>#C5`J&Q078^FO@;Y%LX?G-Z_(.0SV^O3_MJ9-N.;P\\IRW(Z<](L\5NFGYB -MDOU$9L1/O(^C?K0IG,V-'Z#2MU/'PN1'%F8>L]S(@HD^#-/%BJ;N?(Y*HZ8BA0X(RLB).D"L%R.%A9_0,/$Q5O2N`[;9CWH=*=4. -M_HM'HN'?A;\`#0=^P'(XP`]'A&\'-I1W/[7`MB`4`=."V3.YC?"&?#[W2WJ&*KK\0F/P*UCG6 -M;(V?@-N)7\Z]/9M[3L1/QN37O'69;^0#S0"(E:&_7\LX5O.P:,WDHB5>7-UY -MR(-P2O,A7*##"R:N1;VRF,,W6B1GI]T+Z:;,W>Y#'L#M3G$*T3<9?L'%GB5S -MF]TUT;85!8MPZ&Q;P-\["-1*.6!-)B4YYS3GI4@(,M5W"!/7=RX=2@*3OAM. -M^P9RQ7V/2?NF!3#ZG6/#O`)DXL&B0L3WZH+"X<%^?K-%9L+"$NAS90&@N+FP -M,DHZMJ@`T>UE7[5+RTJII!*+5,"2AE51<'6SM?O,RLNK47V95*8NI-J#$[H6P.NHFO*+R(KI2^3JY0" -MR?P\-8`J&VYFW:D&+;@JU`"LU3]ZDKM2:CFW@#6!S[_>O`RC\([S,J1)[C7D -MI1A-$?)O.B_%R+N6O`R!+A%H@E!TF7D9#F8S:`*_6#0"S[D`/1]<"V)O@E!_ -M`JH(]R;@\G:J)CB8AJ81?-X=[64(^;<0EV$4W8Q>AH-'K9O`Y]\[7H81-AP, -M/*/L$%D5-RB5EU`EK],W(M6$*Y78U;=[FY#U -M.D"[[ZB<7.Z]1O51Q!TG]1%*A7SQ?42U,_[]0K6ARP5[_GU!M:%+17KA -M_3^U$=1IM-H8)?(Y$B9T]:P@+-W -MRJ2Q-0A`Y;A/>PZ\?83!]ZVOK+8?M!?^R!F[OC.R9G9X%UDQ>H(U=_DK;N,6(T92YX?(;:7)]5YV3SAL.HD[H?:>V_[[IY -M,TC#U?9SRGQJ!\*=6NA)0BVC$@A]:NZ8J96ZRNQX&E5#T9'_*BCRE576C.X/ -M*8$BETO%=\[*4`6D3_WBNI->6$**M;\J@,H:95=CMDK$I)^N98DD/[F(PL_H -MB7)"'Y/R9LDG/]O,/B(NS(1BOIQ7"V1C3]&K;W5'(U+(;4]?RQQ+6['-H]4U -MO=^3UVNN/PH^`.8U&M]/.=#)']#&R*1Y3O.B+?Y<*>1-CR%\A.U:%N'KN+2MC>@ -MULG[G>0G<^O\3V)G!HK5FJN715]3W\PRB\Y2K,F-L6QEM_)F%.X6T5U?PZ*O -M62=?/AS^Q5M115]S[_<:U@.GV[A*2DZN[!I6U8`4F4J@I'K%<*+[]2NWRIHC -MP/6[M>J`R[VL&C61FU(U0-6>1PU8_0JL&C76[KJJ#4U"J0:TMD]2#9RYIFH) -MG,1,7Q95V>3U".3?+U43.7N/U!*(Y-ZJA\;W0M7MUNR%/36+R=[+TP!1831% -MB>KCB"N::L`G=S'5`1;.NQIK-'N]4G47%5VCU`BSX;!DKD6JT0TYAE0ACKCG -MJ)3!&U<:E76N?GE1#3BZIJ@.'%F-U7!>;;B970\NJ$4/+PZJ`9:](JAD+`ON -M`JJ/H5WZ4SSZ>9?[5!>AKAZHT6CT4U5#50VJCC'=[O6`O4;`51RRZF:6 -MBJY)^]/K%92]:J5>,3I?*X?7W>65K4^\Y35!:2.Z/JRQM&KAJ"M.FB`,W%+E -MH^#2DJ88@V:MD->0-,69?&R,(K2+ACBD:33"N6]6M1KV4N[-'TW*2%WQT:"D -MY"J/99"6*6U8?]))BZ\6L'G91KU*R4LUFA0AE=/:"$K)JX7"]V$T`#8NOJC7 -M;/V"B_HE:3=9U"Y&O[&B*5)8:E)674%1NS1QU43]HOA.B4;P\O*()I52ET34 -M1M(N@ZB'0Y%(->68<;U#S<:+'=EZP/+"AIK@80-YS0Z@>K!5)F_%O0KU.C[% -MJNKA#,HMM?25"+5AO0:P%=9BZD*#NJ"IJPOJ]>%]@X%JH@<:UPY4C4U-H\:\ -M2:"*J(I.JZ1KT*P)JB*;BA&,?/]EE,W<^E60U9V5SM9?'[:6,:IMK)91SDNU -M7XMJ+1]--GE^/6#>,J]9;Y$/OQ[E:@4E)\-]/6A.95]=Z6P075T,Z?.L!9U$ -MQ-5$F%38VF6)Y8O96$X"^;IE>,V`RU75;.[WNL`U#/[\;.YU$2H$339!>S7A -M6F9^-N=Z7<):%UP%W36#YTSGE1,^+Z-Y0Z0:2D)9 -MAO*:6)6*:V7*\28%J=3BRR#)%.+#!J@B4WBCXHR,X(TPTYF_Z]541C74`M92 -M>=<=M"H]OR`[=P/RM>5J)M]V$PP1/%H3HTII+LB579=\E9Y=D/ZZ`?ETGNNJ -MF9@*]"D'+DY<75Q,?H+J82L3[F2DVC/S0R>@F4^LZF+8D_IDY##3*V2U3[1$ -M;C>WW=O><6X*A735SD[R`E`UJ+Q$'5I1^+E/1_V_^^=P9":_?D$YJ^8?1O_, -M5/?L^I?>U7<7EYQ((U.KDF@^ZGZ9*Z!H9&1L%*Z/Q:(T0$H4FXTYB._CSB^$ -M782K[[WW]SIHI5-AM>#W:\.3X-_KD$92!YX\CWM)VZO`<1H#^*1>;0A\OS:X -M)ZA[#<#W&X#/[$;4`;PA]8,&X,%<]#O\K(^RWQSEH!'*S!ZVN5Z_U(;?;P"? -M#9Y(<"M0TS$4`H4.OT/J^8)M`'C:`/&T$_;03]K!'T\\[]/"J'QA`.Z#O -MU`'S/DXKP/*C(ZJF1XCYMG`3YSW8#X"H=N`I_+V#^_![G9"(Y(G!NC3V'X'& -MP2/0.'P$&D\?@<:SIC0PPY6@8`Q*[8%-$]A?E\FHS>#-LRP=RXW.5::D[7 -MIGC+]=!R6)C"JS$2'PAVAWS>O?Y@@"2J,J;3<7][B6I9%V6_.N,FA!#$UTSTVNB`)-<`HDC -M!#7,9HB4(<4)M?HVQ*<8R&61PV!X%[JCB=.<@A$?VA@[I^#FN!@ON7S)N$.^ -M"KH*I)0TZI*0(;+-6RYVFYLAZA&60C`+EU-=;#[ONJL\5Y! -M,UQT585--&CT?H&F:84W1FNMY'+-T# -M3A0M18#=?N3JV]W=E?[&%4CLKT[B8'42APU)^($3C!L//^6'IA'0]G.;%1R- -M[SO.?8-U24B+`0UYXPHO?)="Y)KBR70TS?`^=&A1-5"B%$YMC)SX^`9:\ZK: -M?BI`>`F+)1UBW-QD25%8HA7H?J_<'RN*7Q>-%OA+8*,2LBPV-W99;&EAKX0? -M+I:OOC30&^(#]B2>XNW=CC]JBBR#J^6`U\5;W-><(Q2"#^:;Y\88DX?LP[:K -MB\I#&RR'-EP.;;0<6@VU**\SFF#4<;WE=4$3C%$YA@$<.]9!WIXRPZ_[`SUAZGVD+IW`S\DE\_0$]0] -MIL!()Q:OL#7B)R@_D^UNREB>G5Z<7)Z<7QSG7FV5O -M,OM*8'ET%YP[I'L6,Z_:_$M!#X<9:.U53O"DA)+QD>6U2H5/"MSEPCX-VLF= -M9[*Z6[EAG:JVR?59J4Y1,.G82FTV[-&DU6:$D1(QY_U0OL_F/Z0)D\H)VU+C -MH>4O;65?Z552*#)WH8:BO>(W+6UM4"1ILA:(=Z7R#M*[_,2"ZEHJ+:.@\1[_ -M$CD",^_[NP(C\R$Y5Y?SD?91"[ZQ+JT.)^1!<*H2TIU_J0$C#MQ60&'`2`VH -M.D!>+5)>/:`D2U095%"#UGU1@4+)DH=T -MU`$ZJP-T60?HM@[0VSI`[^H`V>6?!Q6?]7.!A5#./66)+2.LP$185$X$_>!B,50A^Q#?BS[/[1BS*Q?5E&X? -MH8TCF7PT!RB*1R*;7^['D,)L9O/`=_RX8)H)LQ,3:A44DN1@S/VL5(&6(6DU -MW0=0EE9_]>S9R6D55FL9]WL:A>]QQ-(_W>4#&*;J75\/.^O;PY -MN>U>:\=F5'VU@S.,_V3S]-TI*&Y;`JGNL1O9;J,9>0H@C:>XJ[=(6B;.JW(0 -M5"QX$[@8AN-0*V`^5I?EU:!#QS>L*IB978-04`ESGU^?(M8ON[00HPQ$LA!Q -M@H2=304@!]4@A\4@)C/*K9%I`:BLX/)*Y6)#E4)3$L6<;GY-[$Y^Y`M'DM\T -M2=6C;K@:-N;!EBJ@N9%):"DK,_U.-S/I6\K.3+\K,#0)+&MI"MO2K&O&TB3D -M1S,UC1H7VIJBPH:Q:?1-`I7F-C1JXJ,P.).!-.S-[.NA>IVU-QDZU^`TKC#' -MD2FX7R,'U*QM0BTE(M+OY*7?^A+0[-'D9N7Z!JFY+M:,U[0`S=3WR7O\*TEF -M;[[7#=74EY2EFOIJ5"3[6=I7U-!?:D%)<[0"3-JC56"UH+QZQ+R:4(E-6@X7 -MU`&[+RHTSRQ-@4QX%=/)J2(8(5]V*[Z_3%EX^5!I*S+[J.+[N.*[:7+FPR2^AD(0K^I[C6(,8[(()*BB,JOX7C4K -M%U7?%W6&S;!<"J$T`RX?X*'B>S$^WC+15YD@\D#F=A3%TS!83*;]41"/@KB@ -M23I@Z&#+'&%R)<+DS[*Y2,'+&EVJ!856EU'[(OTG$;I"%\U*WO0'4^+*IR+[ -MK/`CV%K'5[W+:@L-*1@F&J+5M=%4-YG-R=6;:#Z(Y`>%\H/CRF6401D,6VI5 -M4.+,8!54'2"O%BFO'A!9;-5@00VH^X(2=4$*RV[J"< -M(X8MKPK8OA]$#S-1X?KP7.WZ\*+R]1%*FI!(RWERNJ10P%3"Q+5@(F"ZBSB_ -M_R70^R*HM-$+5L01+/27;WMGMTJ#M]@J`6L$N.!Y]X=3-*NZYWW\R9P0+^AJ -MV[-6JW/S]M6KWKO3FR/MIP6F;\<+K`[^?_!;RYZUV]"?H1--CUIK?SMJ/=F4 -MG!BK0\?%7/_(LG+>VS-+F,A0B;2`L`5G6UT^>P+NOM^2S93G#:6!M6,3Z1$6LO_X5V_[V]I+[H8V7 -MQSGNQ-]XD>")HD9;-?`0:PT^.O=N;.UJ1.C%W@OQQHGL(?TMR[?`N#J][)'T=YXX9CDA:O/*O0WEY$,'QB -MG/XK&92O#9!D:$3;GVS>O#D].]NR.B:M9"R*(&2W9DAF!25W:#X9Z\G?Q&## -MS"%_&)C>#P-G*ZG!(Q'D"M,L:+5*._+(2NDVTY61'Z;MS>&1VD+9T1! -MG7"Q#J?.\$Z6G"%]5+@F2Y<"5F<+:':/SRZ/NV?]\\,M1>L'0]OJSPVI2 -MC+Z5_.QWSX6&ED_LJ-62+.W(HH27[>D>S$!WS+<,_L5JCV$H7N"%C6(JAC-\ -M)V%?R$62SPT-,,>#:7WTPAJ[K9;\H"\169,Z2\2L!3#R9K-+\?'GHQ`X?YM!9142G-(; -M(H_*>RDU_4M)0:,;]R$T1+C;VD"+7)G7W>L>BCFZ![*OO4*A]&3S`FP&F).] -M"UAW0)$OHK3:'ZUU=5WFNO7[[SB;?CCI7?>OMO#+"2C?\+25P``QU)R_V\B6 -M`_R&B?IIHH3Q@L/'HG@??J*49!GY!%\EIGQ*&LDX5)M_"QQDMNOH">;;A<4*$D]B$:FOXKG=QDN5OA.=#Y]EAR8_ -M@;-=]Z[ZB+!ER;INY/3EQKI:P9^C"KG#237XH]5:^`7S29\\;R^2Z;/2+"@< -M?5[AO.=*BV#ED5(-$\PS;R!VGCP9KS88Z5+R^AI+65?3$Y@_,:%,=[?-A6GT -M+74CEY"[S$O&I+#+H6K?K?^3NA@6E/6[%>%%W*`#1;_O_/V_=_X!&NGOOV_\ -M4W8/U0Z6$Z"M6W_Y#G_.J5I(I_-"'S"NZ*\`\6_X^,=.%/11`M)]?;^N2X*R -MPW*`LKWE!]C/Q1W&WXO[+.>[UFTY7__O[SDM/%@H=6Y(,FZ+U[9B]UIP+)A# -MUG]:Q9@F45#A<*+7)I^@Y!540$TO4CJV,-6=%QR55#1UAKH1==(V^WQ`\!.6 -M(K:`/F$)?`7PIRN`KR3\Q/0YTPW=9_^I2S*O&OS4I8D6OD)2Y%787^Z$F9T8_6GHR^OQ?UT)23W;G_",N:ST?-/2#\*CC -MTY+G>T%=/P[P'M-/75;>Q9]89H;R)RB78OTG%"NOE?K\)6,BO,]? -MZF+Q)Q1Z__&S%IJDWOP3BOWO]GU+JIY<_?'O4 -M)[1WQ/54$9W$&G_"@BAMQZ2=EG?)W7OZ.5\6O].JJ1/[.#)7G;XJI4RYG\.EE"WT3RCSD]2ILS/X$;*E/EY -M?$B98M5IM,]_5ERX[CS_=G\ -M*R9T)Y:D0Z0>ER''6LL(2T/:%'RMSE[BK+;&4Z<&/=9/:T\\X[G.6TR -MV.T<9R\&.RT^7SKS+HL/K\^]S^KAL9EW6GUF?>:=/AXO"^QU^O,S@UW.B?KI -MKDO7'?DVI^F/UI6["N]>/1QFN;>D>0/+A"UR^CUT9SFFVYF:")/MY=-D6S\N -MT\PMV6Z^^?W77[[XMKS37_]!>U#M6?$DV._^N/GWS8L7+[_XN+_MRS_\Z7]^ -M_.R3K+A'[EG[``!\7\7KC;[XHG[:X-_4,1[:S\URT0GQ2OD=;7W3`!?>E9^U/?+3W$J>2^A\GW,)(3#X`4 -MK)(.Z[.?:LUC0'>'XY__]9M_^=??_;%\IJSX8&'SW^X'RFY;[UP/E#7;*,]? -M:#O1GR-2/8X_1U0]05$\D%$]'U8\!/'LK\76Q>,9'YY_T;YBXOGS7_SBP^JG -MMZ\.R?Y9L?`W?Z=?E8[T)]&*'2O_V3Q\63Z>UN[RMCOMWX=/I74C*1X4.?WV -M_/-/__X7/__Y;X^_??5A_>S(IW__UT__^F'E_EF]V;7=L#?^WS[_*,^VQW,A -M`SXN?GS>_=Y,KISWGWY;_-_YY_]Q_/FSGS_6O]P2Z'_=OGOU7-:C_^VSW^?/G_^]OBPA]5&ZQ -M^\_B@99??7S[J;RT\NQGNY_]_-FNMM]IUN4C?A\]?_[K9Y]_?HOD9Q_7>RVW -M:O_U9\7S7L]_U3[!7(:R]?YP\WX;P;.?_:+8ZK.?5YO^5[.+6Y$4D[DEQT>[ -M(CM*KQ^KQKN?=[OZKV$.Y.].^V+LU4;=$S_=XXG- -M_.LOR@W:M2]LE8<12[_JPXC*0V[-,WQU)11O4_F8]E3:X!'!QF?Q4&`Y!/UQ -MN+K(RI&WS\,]FWM()DK4T;[%JWPCP?/BS0KUZ,HUK\I(J1 -M?OZ74?YH['G6/ASVZE:$_\==RRT`*@0,*OLORO.MQ^;YUBY"O^Q>S_"S9Q\5 -M+P`PK?2'Q4/&Y6-D/^O"7S\4>C,Q\KHU:2R:9_-Z$7?'=FS([:"JN/Y'\T1W -M]8=!(B@+5H>H[[<<#G3!C)WB+_#Q-2$I'R$S!:5ZMFQU82E?^3(N*\L7/E8: -MTK1UXP*F4?6-=;3VIHB=-+X8MI&G]DHB^E[YF;5^"6FK7T3V4+S;K=&KW+C5'#G0; -MUNMOM]2=PE+,9&+:D2W.RD;JB\L^Z?ZN+F93U.;Q#WZ%)$ZU.^%$+U_K!*C- -M\H5M2EF:[#2/B+K7+0Q[<<]`"U'Y9MA^?$P#;H-$VT^Y@K^<;4_5&VI[.6;? -M(W=WAD2;=H>]E^@NL]_B%8'+[+EX[>!">UYJQ\EB4TZ6V_'3=K%=IPOM^3IC -MM-771<^V4^T%U+/MM7VE]=Q[;%Z2/?=^7RRTWZ\7VN_+A?;[PT+[G9&,@Q>B -MS[WG&>G4OK5][CT^S+['ZK[*N?=:OJM^[ITF\^]QD>#.JYC4=_[/O=.GV?NAR&X=1R^??Q,]BZ4_.M%\`=]4]D;[/^3/JGF+=9GFZ_(?U)_2EI9<[UW/NBYS]VGVK7ZZ[XB[VT51>&:U.%L5+;9N_V"U/*YT*G -MO9[3?C[27?[%9DKEFZQ4=W"NZ`;#73C'KD:K?ZW%-M0F3RC[*"/[RUGV,KC& -M,MF>BON99]E1^1:/^BF-?D+;]LG;H?*Q^<%EG.EW:;B",_U.#1=O9MCI`OLT -M7+*98:>+['-XVF&.O0ZNT4R_T^$!XS3['+DT,\T.^^?E)F/L^/6):297[_.K -M!?9IN2XQZ3Z_66"?WRZPS^\6V.?W"^QS)K@VUWGFW9OMJM*D>]U?[Y/+S/M\ -M/.PVC^63W;/NU70A8M(]OIYU;V_FW=M^?RJ:9HWKFFR6V*F/\ZZMWE5P+RPN=RZU67V -M;F6[`#GI3N/@\^SSG._V)$^MN -MN,>LU;?[BGL6T^/^F,\4T_.[I_*K3;=MY]FAX2K\9"&U7#)A[$O9A>D*2KG7 -MX86.\L^CUU+`5TE=>^E=4U%>[*`\P%Y&J/F/XBVBO967?26%;RS+K"!9>BN;S=PL.H?HR -MWB(#:#Z:M\C.JR_1+;+KYG58B^R\^PK?,KLO/]"WR*ZSP>C.8ZJWUW@RG?9^]-R,R7JM;<#A>C<9X]6O!X1BN5"TW -MFO*-^MZ,IGG7OC<#*C[CZ,U@+H/GNI8;R_#2QQ)C4=[L[\UH/.F<[0<(O!E+ -M\T%);P94?&?2G\&<#@N=.+9_E=*;X31?7?!F0,4W++T9C/&Q@^6&D_D$G>)# -MF-X,)O?!K-8!Z\_LKG@OMOO;RXRAOZ#DO/MN?EJYR(['SS/.?.N-^VW -M/I<>PX*GB1U?"%UP3(N>INU_4]2'02QWHG;X)=(%AZ%\I-2+4=@?@EAJ//4G -MZ#P9S7+GC>T?0?5C.`N>,39_,M6/H2QXKMC\@54_AK+<66+KYUC]&(WMMO.% -MAK/46=G!=UV]&,6")X9-7X+U8R`>=.C^MV/]&8KQL?F%QK/H.4_+!VC]&$OQ -M75H_1E)^KM:/H51?L?5C+-7';?T82_W-6S\&L]@Y5^,7R2+W/`V_J;OT -M$Q/EYW87ODW3\$S5C!FQZ,Z'W^]=+!^G&T#Y%%GUVKS^`+J?!H\*=D:&_6J_ -M`B9N>C[/^@W=Y]L'FZ*\NZ\JS#\JS%QN<"@C@_GS_P8D3\C&=?=4WX8/;DV\Y@@#T3./*12C-PGZ?GVX]O#O4?!ZH\,O=Z?S]\`_;F'8WC -M_H1Y!_,X?B%SYL&,7T&<=S")7X,9OOMXP<&,WD0X[V">MF,WU\P[EM/VNE%^ -M_[4'I[;KD9W39)L=SN570\:?$%EF7$7DG&^WFW=H1:A>;;/BU/+@M>Z+#>IR -MV>T=]X;..Z#1NT/G'8H7O*X^VN5Z%&RNP3A>WSGG,`"O;IQK.->\>(5C5A676OWKPIPDR>C14`K#_7V>WMIIGFV+LXS; -MX3UV2XX/_K[2.8?F?D?GG*,I`E,^_78]G/.]#RV_&1;D(HS?GP>/3D5CMU>/X<[E>C`CT"N<"(?#B' -MK8YG_"UPRPS((PFJC:QX1'+[X,,ED<&P[A:^Q]XZJN'GV3T9UYV/V54.;/AQ -M>4]&-OP8O"<#\^,"F&5H/EP.,P[-AQ/B@X%YC/YTY\'UN\&HSC]EGU6W#3A> -MU[SH`/VX7FX?F\>QN_>MA7IRI[`ZI$?U#+R'0_.M*Z.K## -M.?6M"HLAE2=1BG.&'IV;ZT9W3;/L]D_O!O8Z30[[W#^=W0VM^!ZPKV/+/#N! -MT8VLOI5Y[\$UO=X`L\S+;+L-RX<'T(:C.N[?^AJPV_^>TI\\S+'WM_]_./L7 -MMO%O!2PS($^EHNLM8PL,J;@$[UU*C7]B89$!>?!LHCH@+VZ5[PVHON'0S]+S -M]_@QO_/LV#'W[6`V3WP;D&]G5G//QE.^K='3>AM_2>$"`_+NS&EQNM2SM?/I -M1KQ",N79Y7B_S;TY3"A>&>7'HZ#E<'P+3SL>]^J0/+F>I@[IW9-WZ5V\ND`^/;RA#`^/./0?"S(9FS^7$PP#J^ZL\:SP7ERK\AP3)OMW3E- -M+OG>D_?3&T9XGVS/7IQ7MX]M:\/VVS;>[# -MVW\-`_SQDM:7F7PDGA>?N-%&5'QBTLO>Y9\TROV-E&?GH)6!N;X;NM2X7-\0 -M76)<7MP9TQ^1ERGOWXF+XI2OIY$JFG9S\MZ+6U2J`7KUPG*]': -MG&]*QP.PJO>$S7W303F,YQ]]^?V7U:Z>?]3[;5.,XL6W__:QX:>;^R__],67 -M?WKQAR]OOW_P=_^4/3W[Y.&9S?L'?_?\H]_]$K/>?*N^%S=\9-B96]1_,T;S/\"JMQVVKE'?LN%U`ST#\%ZMJZ -MC-8OD=OW[I@"V:#G45K5KVJK3M_]P#'6'K#`FS]F[UGF+.N$M_.$::U>!:/8 -M6XL"8G[%#KYN>OHY:)#E8_G?U>NCD:;5IS;0A52;_7YS.9W4.R(QQB\XQE]S -MC%]RC'_@&&,3LC8SW.J!,K:[AW-#+VWXONRF]Y)$I#E:7L^YZ^R -M]/+X:K-+\UV*75+50;8O@FP:@J++&S&K?9S#M6&2CFUQ_VI__V;SM'TT2C>' -M@<.U5=N-;.QPV?MF,F#;<8>]CQ^X-P6XNVF%T[O-W:N'`\*Q8@3>Q>UPS)1R -M`"/(+BROL,<:0G;5/T<)M@`Y1T8)'*#!MRK@)A#WU^+[$QCGE<&XZ\%'OB$; -MC[OL?>79O>FXN\'GZ2`;C[LT?(L:MKG#[>EI]P]`E^6FX^ZR.YBOVW8.1_NM -M25S:MG0[J]ZX?SCFJ?;5!IP99#>C+X>GF4-W6SRF=\7NK#*"[J(X?WB#RW&W -MS7:#1SKH+J"[MY]>`ID!=C-X@S[8`N!\\-$0L`78.2[=.AO,#O1+ST@[Z([Z -MY\Y15H"=&#\CBK*"[*3ZN'%SC^PV`6I>FS%^E[UG+6CF^-T.'Z<@>\#OW':B -M`&5.V"UOK[2=VDXTH,P)NS6?:L!8XW=:?$J$OM/2&K_3P4,`5`?X76LOE:48 -MXW=Y,9V;@=OB=V@\LP*WQ>S0]%@`R1J_4R+X.V/"+H''719;_`[OBH-SZ*'D -MF`/\KK6O4%",";LT7Q'%6.-WVKL%@V:.W^W@KGFJ`_RNM=?_48SQN^S=&DTS -MQ^\VXQ1L1JI8[;US%&/\+G/.+'/2+*^<75Y)NV2U&'>'.>>9=GL,8%N(P\WY -M=/M';KHZY[89W\$E/P`;8+GEN+.?#EE^V0+]-1N/NT2=5X"=3>A]&=F]*<#= -M9KL;OF,(987;R>AE99P]=L?O-O"S#%9K[$[AQ\H66^0.<4?)=G/D;A''QQ9; -M[`X9^R/L#G%,;+'%[A!\-&PV1>X.?AQL-D7N#G4$;+5&[G3D8C_*'+E;Z.&H -MR1"RJ_)T-/C2=\\&O`/$A8"!%7@GY$L!#A_@`>":]M`.LB/4&7O=!.X>?,Z^ -M;X3:!;:?8D[;C]SSCC.#[*9(FDHK8_:B6.%V@CAC9#9%[@YZN&(R1.Z*H+(, -MULB=PL^("7NK31%[J[W0"'!%KG#WI."!%OD#L&G8XR6R)W1R8T!-^HR\M#,O)M: -M5]Z&`])SP\W=;D$"RF1@=MW]:W5_:/,?3KEK,P3?UVEU`+E[TVH,N$_39@NX -M)7/4%'K[)<")^];!<2>(6RC''4%ND'1X8$X%=+/CN`O`#8TV!Z#;%FW&@%O_ -M;*8@.MF,@;<=6LW=MQ?:3%VW$EKMG'<.CEDB;A,<=X.^#=#M#M`%W$[01^UN -MEZ`V,NH&=-/=J`?0<3K``V^9$,?:;C^0`^E1+V!I,NX%>0L;QAG@A#O&'>QT -M.L8CX$PYRIVH-\!I;I0[YTELC#?W.6J,-]`I:(Q#YZU5&&>NFZ8POEPGH&&^ -MH">N,-Z$*A]VD@OC"W3C$<:A\W8BE#/GZ2Z,-\`=0!AWH!-&&(?.^W4PS@!G -MEC#NG'?8X)PY[IW!.'.>@L$XQV%)L/]QTG-DO0[24V -M8Y86!MPR,FH*OCT$Z@5Z_P?<'^2"`]P;73X2;\4`NV,(1\+=$V!7#,E(N.D! -M[(HN%FDW*X"]P>Y"`+NCBCO,O0,`'XP3"9SK_P"??'SRS@2@KLH#G7"!QSX9 -M@+MJ#O7".+I`7_(&.Q+H+Z@KU2A7@*O08'^0B\M@9ZRC`,KU8+`OYZ5>L"?W -M=5RP*\`U6K`OP.57L"^R\,=?-G5[(IUX1%[S'#,'=9+RG39]+Y:W#+K,<"=N -MC2[*%^K<&OSFX59!=^?=YOAP_DS"3QG+7SF* -M]MM<^\@BS57QQLULL\^RU%%U`%>0R]0`-X`+UFXOH,N4;C?E1W?]L/7O@MY-5Y.A#HLXBJXY0&T%/9SJN&6/5B -M.:^52!#V.HD[F?2ISXER?17#$ND7D'.K4"^;^_1H?S4BRJ$B(R7S;J!.I=U. -MXX^<>G>WC*/SNGK'+^34J-.'^_#7Z>+1>73C=N$\&'&Z2"1<&%_*BG/A.E_J -M=/&T=9P_<'JXR?"-\ONOR:*\]G=.DVUV.)=^(3?X@1T67S%QGNMT>BN\W`[\ -M=_KGPDFN+I?=WGTJV.G&=0K8Z8"1RZ7T@5QE&G'AOK'580R["W/$R34O[L%L -MCFVI;MK+/I`-X[AW@ -M@'-<4N!,;&FZ^TIO:'LDCZF]X9+MH/@,RNW8*KT58YYM"_6W3OAG._I9=XX`U[7A3D"7(D%.F+(BKZ?[A#\ULKIQ]ZJ6]#U -M6)2KS?GP>&2=PE.=JLOX\=XZ-[NY*)6NC-^[(?NS_CY'KH[SJ&6Q2']P,OHD"[`!^[$RT+[ -MBCO3U_FG[+/J-(#[9F>L6\XQN=VC^#CO94J9=<98=?2H*GXQAS(57+J2*K9' -MTT=;Z>X.9_,7TDB.2HE3Z$NV(NQ\7M,LN_U3R-WK-#GLG-$OSPU]'?=O90=W^]]3^I-8[-[?_O_A+#5$ -MYW,!8#>B``7,$?L]-??I1FBL2`H-A7PQ47$$>>0`Y.NVS)XFYG??WC).BJB/6D9OJZ-V34+"+ -M>_:8,<(]T@;UQKG/0O,$>P`-Z(QS@F;@J`I^OGV2<0,+YVMREQF\9TQW*+6KCD7N@8'1:G;<1<G=/D -MDN]9]_(;_-XGVS-#Q]L];@[''>,TL<'QPT.R?11F^FU[;YO3[B@UN -M?[RD]4&67(8R'@'2_!2/\@E6HQ3$APQ1W@N46$-\"3BT!OC#,X?3^" -M"R`E4`H!+3JJHN2;@P7&21GDP^4N1\7`BIO?E9%MSC=`> -M"7W8;Y+M)WO'-2JKD?$=M\:MBV?WRK-3CM-13F-EE[?:^L7=>7?[QR?5/PR> -M!]N,//2J;&M_VE#=Z#:DO%S#O:G]*5M:WK>I;'&^W)T=3BQOZU&VL-VU7&Q2 -M)E$=@C*!+(_P&KU;V\X:VBV*-_&B#*IK)38!-F)7W3=9$MITR1QF -M:;Z2!;-]S$Q'B$!;NFG"V*WQ.@O4U'CF`&IL.N:$V1J/P^VF=?NP'$G:[5[M -M$U,;M!M4#S]M7FPNIY.1AT[3K^BF+^FFW]!-OZ6;?D==KA6WAB5PYB/-WMM$R3'6._/U*,2`P@ -MI/8'96=_.-QN,W(<4OQC^[, -MRK\[C?1=`6S,U[E[=A_L#N>\>*?+\9,BP#>H_F/KZ^\_S;=WG]Y_\,'A6':D -M9\6X?_'\HR^^_/,7?_C7CYN9M$=6?TZ=6Q:7&V";M<%T;E[-SC:(XL9;UQV-4'*UY>_KPP6J_0NF_==,^Y=,^Q^8 -M]H2,'1P#43T0LJVVW)$M'\B6U>$3U;H\X4`U3NB6K$'3B*8>%E&-G\B6=`A= -MZ)879B4T8I1J3Z%^;?J.;$G99_'>O$UU^0]M?-J>S_FK++T\OMKLTOSV/YZ/ -M;%^$71N(<@6G\]*([.*U+7].@!NKW_B#&S5Z$&Q0O1H1O'WUFA/O]0(;=.^( -MA)N4W\L#;Y[=(;8MKM.AMM:_A8@LPP=#T=GJ"F_;@&V7:O+T$ -M9]6\.8=BA0^O_IX<@FU]UP#.4GT_'M)R^!TZEH/JSFV6B_:6;9:76B^S7+`] -M)/Q!5#J6XZ'\#`C+0W/;-,M)\1H"EH/+A6=?J%2:O7)S-Y??O=-+!=>?<5>.OF^VA@`[2&JN[UPFVN?ON,;*F>JZ/[J+]! -MP_"`DR;V;YG172!%B?F;971SI!PQ?YN,;HX3(M9OD-$]="?*R"XP(J+W?3&* -M'?)`S?$=,8H?&F;P1UW];X11#2F0(!UX#;[_1;9$*DO3=[[HQD2N]K_GQ3.O -M+_Z1?=0/S=$=H-6@Y?M<=/OB,1ZZ=?D=+KIY]0P+W;YZ:H5NCQ*`QN]J$:S! -M)TR&W\]"F8`)VK^CIOF/LGD0;;4+`50?P_M$7W5@&.M7D3@^ZE. -MUK/\]"XQL'R=!Q>T*$[XD@6A<7/JBFY740AG'OL@C+D_$J"=MCC7ZV'Z,R9WLUW,^(]]1>8>$X::4_ -MWPE[X7J'!6Q7S4$"QY&F/5B.#-=N!/W5YTL$/79G4`2=#FZ,XGN4=CBX#8KO -ML7=W$]MA=6Y&T&%[MD;09WD)2=#?Y2+J3K\-BN%./2L@Z%`.$-UY!T%W[<4I -M09_EM2I)?[TG#-@.ZRM9@A[;4QF"/LOK7(+^ZI,E@AXSX60L+XH)^LN%QW<5 -M]L=A37-!C67>75\CNJDNMQ&-VZMO1'NN^JZOS7&LM4MU0H[,=]DS738GG,4< -MLG3JR&4^*8\\A6JY""CEC:=-+9<(I;RQ5*G]`J*40].-]SR/#`G9O]K(=\,[ -MX>&Z%LEW*P)=]NF*P85+&3\"C)0X8S&\RBGDB'=X8[P&*N5+ID,-KI!*>AL\ -M+;)5R5EU[E?)67XJ5!CO1;T'P_J.^B\*@%L"STP[O)3/IMU$0_/UY\WQX?R9D*LRM+^R -MU2[4F\"`[#4/]L"?2OV7[>FP>=A77UOE>RO>KY%M]EF6VHH3Y6WT:C_*T]AU -M?XRC\:NZ&$_EU=7J.5`Q;^4K:J2<%1\%$'#FNI*,\54RYCY)S[@?M%YW+J];IW>O]?4Z$_]#Y<7\M7A%8O+QT]/PPR[']!"?: -M;1%AVPD8M+-2'U2-M>KLHHXKX2'O>"J/8CE5G^X5<%<,3JK7C)XYQCO:W*=' -MP[L,B#X5O2J -M[$=#""^)D)M[3P'PDGQT3[E]U]SC@1JE^VHM@ER-'+#QCC6U]CE:[0OGF#I -MN^I.$MSD`>OL@.IY_"(VT=OF?'@\>1:X585RRMKCJRWUI( -M\"0!8I;"ZTU\>+.'P3C2"IF0> -M]UE\LHX"C3Y9PG_@<8JB*;[C*>CN_%/V676Z8N3N=;IGYED#N],I1GLO5N[< -ML^*JKT?U2$/2IUB5/[:?1!+TQSYGH7H\G%.QM2U\ETVS[/9/ -M.8^OT^2PSP5;1.>S^/B%N--,2OQT+NOS[7O.H6S/=2CLJ[&:57T7X3(M:3G'I6OZO+ -M=2ERSK-`6)Y=CO?;G-]3BCO?F)>32S]B`VH=C3_Q!/%7">'A-Y20;M0\YYSK -M*[4^,P'TJI,X(:][Y,RO>WY#Q$ES*49F2!(72Q5OHX^Z('V=]MF3T"3/^WO> -MF5[5%_P:,X<3RRB_3%/*@U\56N1;Y_$ -MO'*O^NC.1'VQSM+T?+$N1VF^^%>--'>.!Q_1_EC"M?8DQM_.(WJ;G.7IIQSE4:?HLO<.!4X3#'Z -MK4XW27GEGLX9.MML[\YI\\^`&WP\/R?91 -M=K$VQ_0F+6]Z<)NS;@XW>/[QDM;'>J*9RWLD3'-5/`0J6ZZ"Q,LG&)N4\E<\ -MCCWZ2G(X]O`KVB'OK%/?E>QZ"(J>0J]+CZT@0W.0PCN+!'VQ`=Q7,;SBX09E -M?)OS#6"+$\8/^PWR?:3?69[,;;#L'B$LSQ5UOMP1_%U^%!4O-VMV&67_2\+8-SX_Y[9HT;G2]W9[>K_@NC -MC!L-[A`OMNKE0!V7IJK$UU76<@Q4"F]6?! -MB[_^P#'N78?#FO<^#H\V9UDGO)TG3&O]7`3>/N687]&#KQM&_T@48MK_OC7$ -MQOX)=H3U5RQKP^?7$=;?L*R_95E_Q[+^GF6-SNKFD_%4.]/97X3]_EJ:$*T? -M#[O-8_^H!V/?/U>*L'U-M'M#M=OO3T7][ZMK30.-`70S.#V,L250T_+)>80I -M6C,T=F6L\E=;LH-T=WFBCCI-=KR]_TBTHY*#FE"76PU>H.E^.,,>WTMH0 -M;7?:YOD^.Z+C5+Z[M;QGL7]N#6)]SG<'M-8H'OD_E8=MZ7%_S-%#KJ\V%L]T -M84T-[QB`F)D.G(J_%P699;0.ST'<+,S!?\&],//KW_-/W'#_[N -M^4>_^^/FWS9HFGQ_3 -MV>4BK_>JY&^^?_#[[_]YIN7Q9[+/R;Y;4>?Y-O'SU^\ -MJ/Y6;_'/+W_W+_]6;*;_]R>?%`^W?UX,^2;IRLD4&WWQY3__6_W/WWWW\MO- -M'_[TXN5W7WQ9_DW]]_[`-R_^_.=V3^J_WP;RHONAV?EM<4&!T-8?=7JN2Q'8 -MCOY2\/79)P_//C2$_L-G?_WKLS*I/WS^T3F[OS6GCW_QX5_&%FF;?]PE)'KD -MZ#.1UK0VSJ;)P4']=&33TP-#@H?H`0Z2W8ULB -M:$L#2@CS8M+@TI\9^:H%$#:]V0*AHX?R;_#Q)?<^*`Y^FH.@]BK2C3[EWYO_ -M[@$'%ZSF"`N-!?/0M/HO-QDO)?/[YNTOAX=GMBC^]EG^:G]\IA\& -M#K;9)^=];YLNZ(.M'PY_\;\N[EX'7AD++6ROHHH;;=M64?R'#Y54#@I41,66 -MM@JJO/3Y4\YQ%#YZ%$`%T`QC['=WZM=#,^=].9M`4YZW$J:,[1J`5SD+1+\S -M:\ULJ`(V`H9F`P`5FDW1K)\KU8/E^P(+.*R0]MJ)RO;VCY[42S=(:-6T%B/5 -MHW@U$*>+@8L\AFA!"T0;)F0[4,&H0[<63C?[<,MG@A4@JL2 -M*ZJ40(\C2]L0AB[-A-*#O"BQD'N4;PGP@7*MW79!_];,E*V4'T2*M?2'KEC( -ML+7"1=W"T%4P:#\=+BUQLB#3%56M*M$3P-ZT8:U3ZZ2:6H4$:9F2)237T;CQ+6;F9MLX$7]%)=>,J2]B]S-`5=#7C2 -M2TVT^A\9)$`]ZQ9F]=SW.MOEI^'@(-MQ3[CWIAM6I4VW;F/5,,W%*?%Z`!U/ -M$BK"_PM67E12:%W+OQ6O:K#8JSZN\I'2IB>5/Y=_6;H*;0,=5F&YI24;2YM> -M'5H]]QBGQ&*,*JM+9R -MUFGKW43$)B9.)@Z"AZLY9;#0;6%UUTW`47E-&**H/.$U=561WNN\KR-LO\-6 -MDIUX;>@=S%.V`U)/L:!W/G^J,)(.Z%%&C-9P]2J?83>L_NYI)=>#)M1R90FK -MYV8O5I+6,8+1M!]00GUV@\=LCZC3=D*06JW#$T^U3K/>D.HS=-$0ZH_430D5 -MZ&!HLRP0CG;;8EC:63$[K)<5'%/']3-C1AG0O^K7.?'E>H=KX`0*6*Z`./=D -M93/H>M-8:`G5/+CB`;9`5+3M*H@K5/'4])2K#ZM,0W\.I39)/9I8G0[J0JY@ -MF;?&D!=^'3/L^HZI:_N=0:.,:-XX6O[Y!T,3[VW@*2_ZTR!`H^<"QH[!?JV( -M[\<11GIK]`DX,$R09(B`PW#2$$;T@QH/*&9/%U3M&V1"F-5/$@TB]>]H`(-5 -MA?0!@Q&F'1C,F;HB6)#$I#G"S3PXDXI7USL42;%)"%0JI\*E4N&$P*5JW[!6 -M4\:3T&ST=>!"I9DHT90*EGKR:+24`8X4+?,E#Y(++K42%!GXBH7#!DSOJ-88 -MW3T:,W+_:!Q(:I<0,1.MA@DR$^',*KZCX]`RQ28A$*N<"I=7A1,"KZI]P]I1 -M&4]".]+7@0N99J)$4RIDZLFC(5,&.%+$S)<\2"ZXM$Q09.!K&0X;,!VD6F-T -M!VG,R!VD<2"I94+$3+1:)LA,1##++64"X96$D*&Q"M&)B(U(5,30X<)@"Q$M -M$0N8>;(&1P*G>`F'!0+2A4P#5+N@=0MNLYA`M03&E7@52V@9"&=4XC[SD@1R -M?)5(G'E):$=7">+@.2$>/">B9UX2^B%1PC@D2HB'1$G$9U[F2QXD%USB)2@R -M\.4+APV8]I'0CG<3[O%N,L&9EQ`Q$ZV."3(3$"4A9&BL0G0B8B,2 -M%3%TN##80D1+Q`)FGJS!D<`I7L)A@8!T(=,`U2YHW8+;+"90+8%Q)5[%$EH& -M8ACUM'7KE=LV85"JF`R?4CX=VH"*FI!ZD+0:?,?5DJ;9TSE0!()"F -M"'.TI)DQA["4<&N9H#@AH6>6KP#6F*^FL\A5^M>!*NUIPE;S&="6?"[[2SP5?:>>"K_%>8YHI:W`D<(F7 -M@%C`ERYT&F#:Q95TAO_*/,-_E;_&%!I7HE4LP67@**,>TNQIFV^.^[>F-[^K -MOWI*)FT"!":I]C`>Z7NT]A@M=K#^8@XW@1S]2>&M$,3H311""RV$\7!BKLR` -M5[1!<816TR2EP:QJ!]_U!82PO6^!X7K?EJDJ@F)#3"HBK`P;9Y -M039H/WO*&'T*!,1H#F",Z>W3VB#T^,$ZA"7F!$`,)D8P0R"B/UD((_1`QH.( -M&1,$4=\&$1%>A9-D!+O&'9COK2.$\P,3#.@'QDPM$1PJ8M(3X67:*'/24WY( -MC\;/L;8_>4J:;N@$QK3&,+XH^[*VARY>L-9@B"\!!MI$D"8("*B3@P"@"U@\ -MI3]Q$@#KU*`+PJE4DAX@UZJ#SLI:0EWM,O=[_3((PX_>; -MR^FTS^P=OMG`;WJTTZ`3I'&!XDBW7Q?TVSBBT#^,/AT+Z@1)AGA$*)-&@*(- -M:G2PF"]=4+5O5PV!53]'0?#J']8#NE5%=`+5B-`/5',9?1$>2"+4'0%F'H1) -M+UQZY$401'K!UR,O*#QZ`6XP+T@-9AA].D9>4#'R@HR1%R2,O(A6C\R7+JC: -MM^N1P*J?HT=X]0_K"B\H7>$%KRN\$- -M_<.ZPM>4KO`UKRM\+:Y'P@-)A'HDP,R#,.FE2X^\#()(+_EZY"6%1R_!#>8E -MJ<$,HT_'R$LJ1EZ2,?*2A)&7T>J1^=(%5?MV/1)8]7/T"*_^85WA):4KO.1U -MA9?B>B0\D$2H1P+,/`B3?G#ID1^"(-(/?#WR`X5'/X`;S`^D!C.,/ATC/U`Q -M\@,9(S^0,/)#M'IDOG1!U;Y=CP16_1P]PJM_6%?X@=(5?N!UA1_$]4AX((E0 -MCP28>1`FF5[(WO[D-X5HKU]OC5'<&7U1=A:>U_N$?9\CS,)PHR[WWRV -M/]ZGN[V]QW>;^$T092ITCG1.4#Q1]^W"OQ)/5!LPK0,=$OI$B:9X:&B31\!# -M"7!T")D[>9!V]_\)P8#YS>_H#CQ0,`ZP](K#^(]/8' -M?+$_$(K]`5GL#Q'V]JF2`%BG]MX>0*5R>CN^5F%$?L`1^8%*Y`?!WNYON4?8 -MVSW.)`@S'K/WAY.]OU<_^TV.>@IT=E0.4/QH]NE"?1T_%.[[,:>#H)L8P0P/ -MA':R""C4@8P."W,D"**^[;H@H`KGZ`-ZC#XT -M$T7@H0IA=&R8/#/@%6T7$<'4-$="4*L:AO5Z`1%4;RT(4&]M9=1#&&R(4#D$ -MDF$0QB1VR9!XSI:$(Q82'%,20#-(D)T@$1$("9X`":'\$V3M)Q&*@JF2`%BG -M=B$00*5R)`"^5F%H3G!<3JA03@1[OK_E'F&?]SB30,P8O\J0!'`.,N%>94CP -M9R`3X$GDA'`2N1]S!@AHIPX3XJG#A'#J,(GT*L,<"8*H[Q%=$$Z%L_0!N<:! -M=,>?^TTXYWX3X:L,X:`B1@T13J:!F//^:>3%1^6OGO.FG``#-H4]CC75'IW= -MHHP=KEGHX680HID4WHK`AWJB&#R4(8R/#5-G!KRB1T1$*#7-DA#$J@9BO5I` -M#-4;"PK4&ULA]1`$&V)4#F%D&(PQZ=B)B.)7WPF3\DY#%/9(OJ2@8\PR=LC> -MD`J=@F@FA;>BD"%%'U24(8R0"Q-G!KRBQU1#(#7-4PVTJH8R/<4>"S86)*:G -MHN<<@F!#E*HAB`R#,.;)+AF>/&?+$T\`1X(I3_ -M$[+VGR(4!5,E`;!.[4(@@$KE2`!\K<+0_(3C\A,5RD^"/=_?GGM.C)S3VW,<+W(`UG,DUG.1WI[CBSTG%'N.+/8\PMX^51(`Z]3>VP.H -M5$YOQ]9Q*$&1=[;[]X3HP+I[=?<+RX`+!^ -M06+](M+;+_ABOQ"*_8(L]DN$O7VJ)`#6J;VW!U"IG-Z.KU48D2\X(E^H1+X( -M]G9_RSW"WNYQ)H&8<7%]&*G=PG-^7/B?16I]X%AR`7_7IHLEK@$,EX!!APOU -M4R6M)8$5%]*'2KK0QL>-.;,&1X(1$1$:"UB2@DD#8%NX4+X]HUE1FL1%_!M( -M87(E1D429@9"&/73/CO?_FD7*\T&?O.IG08=3HT+%)NZ_;I:3AM'5,<91I^. -M$W6")$,\3)1)(UC2!C4ZD,R7+JC:M\N3P*J?(TYX]0]K#-VJ(OJ":D1H"ZJY -MC"X)#R01:I(`,P_"I.M[NQ2Y_>8WAXK!TP%TLT:QI]R;JX\4,4.U$"W(=$;4 -MD\':X,E031`!A2)LT=%@PER`5JU=1`11MQSI0*E<&+;+)4,0N]Z>`.O:4D8A -M^%W]$:H!SS,*PI!W]L;_SG-^O..T_7;TS8[&^]U5'[UE1OJ!"C@4.R! -M[-#V:*>\&CL@Z(WAIA"@-RF\%88#^D1!*%!#&!$+9LH,>$6;A$!@-4V3`[RJ -M=J%<6T`0S7L6**#W;+GJ("0V1*44@LJP4<:*012$RA"V,!"B":$#=PF,[D&I);4&J#T%U%#R38E5(X6?H!_DV*R9Y -M^\Q>M0'U]2=84*SUQ5^/2=8"U/6%KW7P[SM]4]RYO8)HX7,2)+>%J/$Z&UK -M[5V+Y_L"G40NXV=?0[5.[I]VR>&X;_#>_.?2==(.RUTFS:;&.NG\Z%AIYSG" -ME6$LW$FO#F9T`U?:*P,TY'T[K0#37F9)C#G=]WC8`]6^+UX\V0$`)J=N;ZTCWV".0 -M-OEJZX:D+O6RNV,-59[T)E5 -MS6V$5;W)N^NA'8#]5U?^-X,RY'TUB0"SG17]868VG<&CW(1T`E=VFBA0!\E: -M_>WOSJIOM\01?HZ,#I+@LZ^96@?GR]VY/5BH_F/I.JB'Y"Z#:D-C'30^=%#4 -M\QLA13\"[K3N!C'RLRNQVX$9,KN>2H")S5T$0YXVP/8J4R'(=N>J"0!-K*P$ -MZ#9P(J#;%,?MN1(\2'8OLG9J75SR0]+@N_SWI6NB&I"[(,KMC/50>]"I4#,B1U-8D`,YH5_6%F-L#V*#O8U4^O@;7;(V^NQU7\L70?UD-QE4&UHK(/&APZ*>GXC -MI.A'P)W6W2!&?G8E=CLP0V;74PDPL;F+8,C3!MA>92H$V>Y<-0&@B965`-T& -M3@1TF^*X/5>"!\GN1=9N>.?9YNWAN$O?GO7[)MN_+ETG_4%"[T9K+4;N2E.\ -MFN[EZV+@O*?/$"[H?6?:0"';P>Y#4P=OO1^M"T"`]3/A&HY5B7Z?IK=U`K]O -M$U$ZC94.[O]*/.@NQ4WN;`!^7S`<4!RKG9I'O0H?QS -MV=6ZC90?)`J6]@P38-!Z[7;;]W-V8*G4,&`O"C'-,;)!TQ%1O2:1P\=L/UJC -MMBFU9>J.T"+%2GWJ9XD5AU1@V3'#J\%^!YVJ"@9:C6SM]:` -MRWBAKCMA(?N7-*5F;IXY;,?\M#TUX3A*%*D -M*DQ'$&J`K0Y>.BFRNQG.(OM>Y4_\FS6FP&BJG% -MVL91C:UG`^N:6+AH-X@9IK248<*V!)57-_31`FMF'WZ!B:[C>+5HGL%U -M+US%6&'6AGL<9\IF,*`I!M0^YD6QQ=#/?$F"D4J]VYX/]\/>5OW9QWJM!XRN -MV,H.4K7-'FR,K&,#XF0_CN@R[(8-WQI>CNU4W"591R62HIQBC=U5-NR)WM<9 -MH3>B*VT^%6HT_=/#)!FI]/OT]&[83LN_^ECEU7#1 -M)5Z:02J\]F_#;!47$&5[(4379SMD\,;PZFRFX2[.*AZ15*;XXCKK:MA`/:\L -M0OM$UM8X%^LU`&"QW1)!Q=:&U3E]JLQHNJ9GR3%2V?NG4_YN\Y1G^_VP<:H_ -M^ECEVN#1I:Y:0RI>WYN-NUK,0/@U1QE=R/WI8&W@9=V;HKNZMM.:C:)31J5O6.DUE?-`"@^P8(3O=-6;T\%`1$T^<#2JHQDESS;'N?;XJ_ -M_F!0`=K/7K)$GP">)9H]B":]/5KYK\<.U@$L\<;C8#`MO!4""?VI`J"@1S$6 -M*,R8&_"J-BB$T.J:HA*XE>V`>F\)(5@?F&#`/C#FZ87``!&/;@@OR8"DN7O_ -MZW$%46S@.VO*2;!84WC`TJ;:*Z1;E#%$]PL]\BQ8--.CV-&`44\9AXPRHA$B -M8YY,P53\N+H(IN:9"H-<]?`&4"THL@4T1L0FT)B+:8V0\!&EY@@LZ8`D>LS> -MCVN/8@/?.51.@D6AP@.60M5>(1VEC"&ZH^B19\&CF1[%C@:/>LHX>)01C1`= -M\V0*IN+'M4!:D&1;:`Q(K:!QEQ,>X2$CRBU1V!)!R612WH$ -M0"&V\"`0"-Q,2+U$3G00H4%F!@49D0J.Z5,$4>,.L1%&E7.E!JW.$3>3.;"3$0Y.$ -M?&B24`Y-DDC/;,R3*9B*'Q<;P=0\4VZ0JQ[>`Q+*06;".\A,I,]LA(2/*'5' -M8$D')9%+>@1`(;;P(!`(W$Q(O41.=!"A068&!1F1"H[I4P11XPZQ$4:5$_>XII,-ESRHIT@RI/*CFC:6($5D^B.H -MI`.2Z.JXYG+U_VSLE7O-Y8H_%WN%GE"_4DZH7\6NN5QIYU"OU'.H5\(YU&N< -MUUQF2!%$C8^+C4"JG"DUB'4.9_Z5E@;>!(Z$W1 -MS0,MH\W&D#U82`'>##0+S!FN6 -M&@B1%]&HAD"3S4V>KQSJXBO_N?,55UU\A:?.5]#6\16E=0R#3J7%5S1:?$6E -MQ5<$6GP5I[J8*T40-6Y5%R%5.5U=<.H$FCQ,DYU,5>* -M(&K.I\"VT= -MWU):QS#H5%I\2Z/%MU1:?$N@Q;=QJHNY4@11XU9U$5*5T]4%I\Y!P/^6`/QO -M6<#_5EA=!,6+V-1%:,GF)L]W#G7QG?_<^8ZK+K[#4^<[:.OXCM(ZAD>N([ -M&BV^H]+B.P(MOHM37;YWJ(OO_>?.]UQU\3V>.M]#6\?WE-8Q##J5%M_3:/$]E1;?$VCQ -M?9SJ8JX40=2X55V$5.5T=<&IP3!UV<,&V!]0T,;0HH`W3=`]].W\4IKDJ?9N%!]6C5 -M`+Y7)+WO8VL2A%_@YP&TK?'(%?@6A<]5'5L']S5YW&2XLW;J.Y^Y<$?OU'<8 -M*MRY@7V'`_:=0*>^P];T';ZF[U`U?1=;IYYFX4'U:.W4OE5G5LG=K7Y`&0X3>?[8_WZ6YO[]CM%CYSHIL&F1:M"PPUE/VZ -MP-[%$05X0_C)+-"F2#+$LT&=-IP175PC(\6L"8.J?[M""(P`#,7`9`"L"2CK -MBF@&FA6A*6CV(LHB1)I$ISP"33XWF?;7^^0RHDN:WSUF4CL%*H\:!P@:=?MT -MM)'05VWPR%>M)=1&4+R(366$EFQN\CP>=IO'X_;)KB^Z+3QFCS(-*GLZ%PCZ -MJ/MU-!$ECI@V8@H_E1WZ%$F&:'YHTP831(EK7`29-V%0]6_5'J$1@*X_N`P` -MM05U7>&-0;?"MP;=7D*)!$F3V!1)J,D'(%/V_F#X8I7VJ\\\JH9/)E%ICJ%0 -MO3]74ZGBAFHHO5"3>=%."6V$YT0S33@CJOA%1H?)DP)4FRVNK.GCM,T]>TU7!:PQ%7KO!_QH' -M_=<"*N`UMMY?XVO]-:K.7\?6]:=9>%`]6KN\[Q5)[^[8F@2!]S4*NJ^)P'TM -MULF]K.K8.K>OR>,FPQMKIW[C,Q?>T#OU&PP5WKB!_08'[#<"G?H-MJ;?X&OZ -M#:JFW\36J:=9>%`]6CNU[Q5)[]38F@3!]@T*MF^(L'TCUJF]K.K8.K6OR0,@ -MPWY_VASW;_?9YN&0[,_VQMW?T&=J#"9%1DC?$X8HPU&XV#^(,:H5V%>(#`_3 -M]#GV>+080@(GS6`%(L/.\AE&(8Q=B@3-&(90$:4,K!,-$P'1F$S&A#YE6+#5G1Z*<*D=9,P&;W#(?']NFC"N\,AP5X536`7LQ/\Q>Q^J*F<22C7,Q/: -M]A$]`Z'((@0FYH( -M);D`9'G_9'_98_FCSU0I!T]&2F&-(4JU-U#[`=P3$IP'\3RHW28Y6`7#T -MF2!'>NL_8LAQ=&/^B&/\4:#='[&%?L17^1%5XL?86OPT"P^J1VM;][TBZ0T= -M6Y,@ZAY1R#T2>7L4Z^!>5G5L7=O7Y`&0H;P3('^U'6G9W28^DT*9"!D8G0\, -M.=0]N^BNQ!*%>=,:D)&@3Y-FB8>$-G4X+93H1@:-N?,&1P.[8`B.!PP)P28" -MK"^HRXMH$+H9H5/H#D3T1JAPB4Z3!)R$`%*EN\N3_3I#_;//?*HG0"9398^A -M4K-'5Z^I8X?J,_UXD_'130MOA<=&.U4X,NHH1@:+.7(#7M5V[1%,73,T![FR -M89AOEA"!^,Z$@/?.6$1?A`*(Z/1$0$GF)DV:[%SG/91-/.:-.A$J<10?".IH -M>W;T#366F-YA7`,J.GK3I%FB$:)/'8P1-;IQ@63VO,'1P*H]PN,!78/PB0!J -M$]KRPEM%SPS?+GH.)'1)L'")3:>$G(1N4OUHE2L_^DRE'^GBY$<,@7YTMY0? -M<9WD1P'A\2,6"3_B2?`C"@`_QB8JIEEX4#U:!8/O%4F7!]B:!''X1Q1^?R12 -M]T>QCN]E5>9N%!]6CMU+Y7)+U38VL2!-L,!=N,"-M,K%-[6=6Q=6I?D\=-!OM+ -M([U^@QOCM9"H-[0!7LN'?`^?Q*L=T2]%([P%#??:L^A>SSC-PH/JT=JI?:]( -M>J?&UB0(MKA7S%'?*2?WYD,OJSJV3NUK\KC)<#GL-I?1KS]W6WC,"64:5%IT -M+A#44/?K`+L21PS@3>&GLD"?(LD0S09MVF!&*'&-BQ3S)@RJ_JT*(30"T!4# -MEP&@)J"N*[P9Z%;XIJ#;2RB+(&D2F_((-?D`9+KLC_?I;D28-!OX3*5V$F0D -M-1XP1.KVZNHQ;0Q1+688>3)$U.E1[/`(4:8,)T@;T+D6"JGF& -M$&%5/:P3=`N*:`2J$:$/J.8B&B0T?$2G/P),.C>)KN^MJN/VD\?L*09.9<[- -M%D&;!QD`U-3``BFC%5?B3K3^L.JT*P?_ZI*L" -M?(6"H%PN$QS']>9X$->&$GW?VR*/K;_[G$1N4MC;N->48#1Q%"$`"$<27**! -MHTN;4-FXPHZN>4^S\*!ZM#9NWRN2WK:Q-0GB+0ZW5-K*=6POJSJV;NUK\HR0 -MX;3-\WUV--PQV/[B(Q>Z8:.IT)I"J*#LQP;L+DX@8!O"BJYI;0HH`WA-J]-R -MUW07IT@J>M*%!]7CL%,'4I&$3DVLR7'8*NL#@*VV-0*VFAVK4_M&8;Y+T^'BS>F7HU_KO7C*B-P4\)W0'(%KT]VG%>2]^,*C;@HZO_N'4 -M"&8($@RF"^!!+Y:Q,&'>%$'4N$$#A%?E%#W`KW,'WOLK"8'\T`:#^J$U3RT$ -MR(MX5$28R39"GG.^.Z1#45']V4?*U`-&HZ6R@Q"EV8.M&]2Q`36!?AS1Y=X- -M&[XUO+C;J;AKNHY*)(4\Q1J[JVS8UKVO,T(31U?:.$6;I0#`L]L4P]\?<<'Y]L(6?U=^?!@$#/1D'20"2%!!A@(O]@W4%M0&# -M%:HC&.R9"B)![VU -M18.`NV>`87;/E*<5`D%`/+H@G*0:()\T("=X>CKOTK>$"0?.#CQQH!XVF0&,) -MH4"W%QN9VQB!R#R,*+J(U>%CMH<7L3(E=Q&W$8JDA*=;<4@%#GMQ$#5(Z,6D -M*AS':KK&O91Q-+_8X:3ZX!7B;W;\Z_+3_1?>OU=B;_]C> -M)T5#5K94?V'1H+=+/!&@P]>@H!AU:3YFWI$!O+\.V;:X69CM#+-6WZ2IH(W& -M*MT^O:;4H3&;M]IYJ;=T,H#KMFCC05=NKZ'/4+M]2EO7S(CID:U'.3UB9^WN -M,57_W-U^QOKW,J$@!+E_M;]_LWG:/A[N+0I`W<)[GFC3H5-%=8.BB[[_T::@ -MQ17>',S+06=&?ZID8R1#>M-'L$2+<8Q$F3N)T)RP*(YP2<%1(#*L`#00?:VA -MC:1OA6TH?7L9I1(X=>)4,N$F)(A@3[OD<-S;5$[]J__<:J;!(%;M`D>K=K_C -M#:F)(Z(9#4+/X(HR-9(AEB?==#$L:6(9)45F2!14O=O42G`5SU(IK)J'-(-V -M/<&-0+%`-P'%5DB1A$6.2!5(,`D'(E#V[I2G-L%1_>@_?>I),-!3><"1I]GK -M>`^I8XAH(?VH,X#138MBA\5%.U4,+>HH1HF*J3,$4^$VB1%8C;,$!J/*(;1O -M%A(,^\X`S?K.5$A;A(.*2'5%$(D&(<[^F&?O+)*B^LU[VM13H*.F*_H!IQ.BFQ+!#,F'=IH(/-3QBY$-TZ8&HJ8M(B*LJN9("'I=`[C> -MK"`4Z]WV6*IWEC+J(1`VQ*D<_$\P,&$V]^GIW>:<;_,Q_:!L%09SU&DQV:.X -MPE-(&X>[F:AQ1K85XQ(Q^=*;.LL!A3EZ.+#T46,?+8462C`27\:T3-"$8>L; -M,<9`6Y*6!ZCFU+,DM:F>#T%%%`^Q(E9.420LG(#E2RFR_3E-?MIGHRI+WS(0 -M#O:FQR6A[HY`P_YX`$VQ%W=L8[0M&Y=EPU"PG9"8-@@/FFN]-8F7;,LG'YE+ -MH^HL!C+Q59HTF\#-KY\CN`8XM*8UP:$?2>46+>UB5G(Q)C2U2XYK/HH9K>LH#B3U4]`0BEDCA9J8"**Y+A^&=%Y? -MYJ(A]5P^_$H.[2*.\`5"SIEV^DEV\OGUV"\&SI0]6#*,*YW@V""@H8QTN>^9((S8E1'10B*?@:B,L*<'MIUAK7 -M7#HK6FOI["653[#4B5GQA)B0$((][O/=-K>="6I^]9Y;[33HQ&IT -M(;5QA#>C8>CI7%&G1C)$\D29+H(E;2QCI,@O+'JC^LU[]M13H'.G//H!IY.BFQ+!#$F)=IH(1M3QBY$/TZ8&HJ8MFB*LJN;H"7I=`]#> -MK"`4[-WV6*QWEC(J(A`VQ*D>_$\P"&'24WY(CV>+;FA^]9XQ[33HC&ET2;1QA+>)8>CIG%"G1C)$LD*9+H(6;2QCI,4<2B."9,&'$W"YP&@ -M3:BK"VT4N@VV5>C6,NHD4*[$J5+"2T`0H4Y/NW^P*97R-_^Y5$V!0:32`8Y& -M]3['6TP5/T1[Z06<08YV2@0S+#&::6)H4<4O2DY,FAJ(FK8ICJ"JFJ4TR'4- -M`7R]@F"XM]NCP=Y:"JF*,-@0J8KP/L$@A,GN+)+A]H/W9"D&3X?*S1I%E')O -MH[V@B!F\$6@1ID.@G@;6!EG^U=00M5]$*\:RGR0+H)5J$0*AU"I'`E"J%<#F -MYQ]WL]$`A%CO]W9NGOQD__,*"?`8$9ACZ-&M<=Q -MOI>Q0Q!>CS6C])OIX*VPY5]/$0.`,G)1`F"ZG(!7L:WS!U3'K.Y/K&0(N*NE -M`Z.[V1P-[\902`?X#X-(]8#7B04ERF:WS;>;PS%/-P]C(D'?+@C2]*;&@X[N -M#$V@_EB<3:07;UQ'L2T6CS+#$#!=$/@S"`L21KUUB)5+RZ8;D3TCTB9\^G!% -MCRQ_@%VKGQ68%C:TI?2SH1#UGZM'DX)+8W -M=-BW#X27QJERJ6ER2J"G>6R`MFI<#VQ['5]4+@5M(1)R1:*B)6QH.AK7+5Y& -M^IBF3-:-JL+8:,=7B5/R#MQTS=F$:[XV'[0F;/,FJ297Q]&8U>::"@!'Z%-Z -M/ER=&K3:*B`6U].2X&_EBDC=9AS`IEW'F=*J^TLDP;]NZBP'9-:UX2`1KHY] -MW%2;/\%(?''JOE`)(Z/Q)!B#:F=-'N";6&=);UV=#VG%%@6Q8E=BH2PTKF?<'/4YA048Z=2,,5)21D].S4E4ZS9G&KZ1V_S0V[K- -MH[0J736#8U>S:RT0,.'WUSS;WMN^L:YM$@:]VPDQ4=WXP9.Y&X&[V[>Q13;W -MX9HP4:A.EVY-`9T2`BS7VDA'"[%Y]D?'8QG-)F'PK)T0DV:-'SS-NA&X>U<;6V3O -M&JX)$T'J=.G6%`0I(<`BJ(UTM`":-Y?PU!C308%R@ZV#!,@!;3?=DJ/:C6I& -M:C>J`T$=%#:$(M9!P28FDFB.1Q^ZC4)BFL1##ITG*M6@]XDK,2;U,=$'%_1I -M<^SI4"+>3ZM$/7(LS9M9%**X55*03!%22FRJX)H2X49IW9#1F"9X)B`.1$6O -MG0).5#SQCMLGF(XJ-PR,>]7DI,A7>F/0KQX-HOM5,:=VP-Z*2<&K#0/7!PMB -M36C((*M6(WZ4+91U5!*!]%>X+)+383(T0K>Y.CEHK:XUYK6[ULT4VBPJO*U! -MJ\62R#AB/NV?TNR=4[G5FP7$RF9B$IRL?1$IV8X$V#N;6%,ZYV"=)'"F3)_G -M@8RR+B0DD#4K$#?$%LDS&FVR^49C39C^BMPWK#UER!QH&U,3P=4&^N;DMI8WXF@ -M_HH+8!'KKV@2%T[$R^F49GEQ!BW?9YMMDHS*L.'6@=#1,$TN(H%J2!FS:EQ#PE,)?/?^`U\?ZBRE*S"Y&0*P%RMF%CLK->M[6PTX\T9;(.H3?#IYVTYI3E -M';$--]G$:<2=#XE6W'F;3GVN@*/K4:%Q%P"5T,5*9OOS^+5FBTF0E.XF+(OI -MUB^;U,H(T5V_6QM>XS>LL2Q:M7#)>1,`K!I")F.[E5P+9#W+73X5$=(U%BY* -M"]@IR$CLXDJ*<1JYYD:BEVL.I].S*X/N>K3M>@J#2O3'[":7$2*WVCY(DM=3 -ME85XY91-\&9L:'%0KP=/&?0759:N78B$7`EPM0T;$ZKUNJV%IWZD*9-U".D: -M/NVD1:LL[XA=N,_`R<;^+B4Y!PU,XKT'A%^^X,NC-N -M<*Y([*NLY]^I"F3=0CY&3[MI`6H+.^(G3@1./F3B)[\268X^[D"CJY'B<9= -M`&1"OT]18K38/$PZEQ,51G/ADT_F:F3X#E^N!;/!Z^LIC,\F/#*>).!9AXS+ -MSG+%5@/.Y?.31S>,_`R<;^+B4Y!PU,Y;I1&K\38N1/INXVQ"W1DW.%>D.:-- -M?"J1C^EQ]"LTILV#Y'$U45D:ES[9-*Y'AN[GU5KP^GEO/66QV89'QI,`-IN0 -M,;%9K=A:H.E!?O+HAM";H?--6F]*$H[8=NLTXK3=UH5$VVV=3:O1F -MO(E/)?(I2Q^S[1-"!U^N+RR+%5#)>9, -M@*A*^)A0;==P+53U*6G9'$2(TSA(*"U1Y5E([-==;G%:MNI%HFNK_J93K"NB -M['K4ZSH*@DKP[(11L<7607*[G*8LL0N7;%I7XT(+@'(=>,U?7TI9CC:A$7$D -MP,\Z7$QVEFNU%FHNG9@LGB'4:-A$DU:A/;/*6HT+W[&(->"U;6T590-9AD?`C -M@,-@^1M,4E9VMX\LFE;C@K=H8LUX'5H;15EP5B'1<*/ -M`!BK4#'!6*S26K"X:$9R"(;0C"$S3%HS2E&,V$K+Q.&TTMJ!1"NM74VG&2-% -MXWHT8WR)CB=NFCUM\\T_0%]XI&P>&'/5B4HQ5_')H*XV,D2O5M>"VJV-ZRF% -MR5YX9#RQ4*F'C`Q+=<7BAZ4W^RYX3;?G -M;`I]N0IPKD%GQI[X5"*7W[@'X[C\CGR(-"ZG*8OBPB6;Q-6XT*V\7`=>)]>7 -M4I:736A$'`G0L@X7$Y;E6JV%E$LG)HMG"($9-M&DY:4_>;>[3'>QEE[I%D.1MIRL+W\8MF\#=^-"MNUT77O\>+J\L.]50B3D3H*@2 -M/B9*VS5<"TU]2EHV!Q'R,PX22@M1>182.W676YQVK7J1Z-FJO^D4ZHHHNQ[5 -MNHZ"H!+\?GN'4+'%UD%RNYRF++$+EVQ:5^-""X!R'7C-7U]*68XVH1%Q),#/ -M.EQ,=I9KM19J+IV8+)XAU&C81)-6H7),(S;;*G\XC;;Q(-%D&U_3* -MA1EGPI,)?#JD&$E9;!XF@O"Z>G]19>G9A4C( -ME0`_V[`Q`5JOVUKXZ4>:,EF'D)_ATTY:@,KRCMB)FVSBM.+.AT0O[KQ-IT)7 -MP-'U*-&X"X!*Z,,Y_>^_^UT91G=N&53NAL?NN&WZ\)K^OM@@56VP=)+?+:!U_SU -MI93E:!,:$4<"_*S#Q61GN59KH>;2B;;'/#-?;1\D@^NIRC*X=M.O6Y`HZN1X7&70!40F>H%W]FH;XU+Y-_]64;R7H^Y;6N-_R&_?;"17E6RE. -MOI7AY%L13KY=DZ)<-C%9/$,IRI"))J\HI9A&;K!OV0WVK6"#?3NYHHR6E&M2 -ME#$F/)7`.>H<91[J$7TN?XXRESB>SVFG@G+^J:!\PG.4N=21=RYSY)V+''GG -M:SI'N71BLGB&4)1A$TU:44W[NN$BO(JQO(IR\KDE1+IV8+)XA%&78 -M1)-6E'),(S;8*[O!7@4;['5R11DQ*=>C*.-,>"J!WQ]."$59;!TD?\MIRM*W -M<,FF;S4N=.,NUX'7N/6EE.5D$QH11P*(90E&&331I -M12G'-&*#K?*'TV`;#Q(-MO$UG:*,F)3K491Q)CR$P.<\.QP?+0*R_M%[NC:3 -MH*.T]H`B9[O7T1[;Q!#>4@=1IP-+F1;%#HFC;JH(^C11C!$UDV<(IL(MDBJT -M&N<()DZ5`[I#NY#09J`88-FOF,IHFX!0$: -M;=4$Z#PK[5$4J_JV,&[52_6=+2TT\%;(3'23!$!CRIR,0)CPIR`5[%% -MK814QQQE0JUD`-SKI8,BO=T<"_+64$9G!`"#./6#WXD%(ZJTTZ!CI7&!(DNWW]&6T,81WA6&H:?S09T:R1!)"66Z"%"TL8R1%',D"JK> -M+2(BO(KG2`E>S0.XWZTG%/VJ!9;^JJV,L@B,''&JC'`2#D*@M]DAMWTUH/K- -M>_;44Z!SIW*`HDZSS]'V4<3HIL2P0Q)B7::"$;4\8N1#].F!J*F -M+9HBK*KFZ`EZ70/0WJP@%.S=]EBL=Y8R*B(0-L2I'OQ/,#!A-KO#^V\[ -M7=';*`SB*)-B@J?SA">0.@IW'U%BC&PHIM5A@D6?-L>>@AHM%%CF*%&/%CU+ -M9!:%*&/B)6"FL.6,$%6@_4=-`%0CT@U)'4EW(:A]XD!4Q/HH^$1%$N^4G@]7 -MMXJJ-@N)>?7$1)A7^:)2KQD)M.?5L29UO?XZB>"JFS[/`QU9;4AHT*I7(')H -M+9%G--JX%5:PO!%262+$P36P)AT(+:PS932QSHFXWHH%8-'KK@@2%TG$\S[? -MG//M<;?-=ILD3=]<;"_=<1B%Q$KCI$6X:?),I:AYE-#N:EPC4J\=7VT10-K" -M)NF/#D]+*&DH-:YJY%CU.Y,EB.E6E%$R4TAM3DY-7$,W)QRAO=L<,9J]S:6X -M9ET[DJ/7NBLN%#CQT]/^N'G8C4KB9IM`:-Y.B8ONQA&!U-T8`"*@C2^VYP\7 -MADM&=M;N5Q;4JUHW4E -MU8.D6@N>23$KK9`3%$NX0S)Z-[VR55",*Z!Q+$])"@&::N0+P`6RS/:+09E6-A\X8OQN2(`^YD6CK@ -M&EG/E-;'>DXD=5A4`(M9@\62N!0B;NY^\]G^>)_NQB]_&@V"8Z0Z63E6*EY9 -MU-1&A^JDZIK0>ZIQ9>4@V`N3E"\F&/70,1"IKMX:4.E5MG+)!U2%L;!/4BE. -M03]"$]:2BMJ.>TZXC;GG;AIMN2*LKD.#KJ,0:,1^MW'>J&?8/$!6-Q.5Y'3M -MDTGI=F3(GM^L!:?C#]93$J-*>&0\L1':A8P%T&;%U@%/+_*31S>P&@V?;[)* -M5)9PI.;;IA&]]2HN^(U7<3:5_HP>G&O1G3$G/HW([P^G7X/59KEQ@"RN)BG) -MX=(CD\+UJ)!=O%H#3@_OK:(D*-NP2/AA0[()%0N1U2JM`X\+9R2'8&!%&3;# -M9-6D',5(#;5.''H[;1WPFVGK:BH-&2T:UZ(=8TQT$G&+IO@Z$H4:/0%0"+T8W93M%`I6FT< -M'IGK20I"N?+((W(S*EQ?K]>`T=3[JR@(S"XL$GZXJ&Q#Q>%DO4JK0.32&C'*!.=1ER,9`R4MN*" -M48"TI.;,[LW3B44A((KP4`*'*Q**2Z8B@UE@D1@RM60EHA2W2'V3VS;ENN;4 -MZC!*%JY%&<:6X"3")I@SB4F@1^&)^)G$1.`8/"&=MTG8YVWZJR@(Q$3H<#D1 -M.5Q.)`Z7DQ6=25PZ(SD$@XK$P!DF*A,%*4;IHPGW!$LB=X(EF?I,8KQH7(E> -MC#+1:<1]G\(E8[%M@+0MIRB)VL(AD[35F)#-N8P_IS?K"RA)Q"8D`F[8/*S# -MQ,)AN3[K8.&2J*0L%J?57!PT51D,`NJ"H.FEJ@J%.,6I6G6&4-NFJT]NVFVGB92A7&R<"6J -M,+H$)Q'VE*6/V?8)*@R;S<.C;#M1022L@XG&Q7;!6@]",_>72#2L@(^"8J)(4)1^FV71J1&Z[J@MUS56<3ZD;NI"@*Y=K'F;2(6N -M@Z,K4:+1%P")T-?W4!UZVS(\)A?3$V3QS1V/PN5X<(V\B#NCA6O+)LC&.A1L -M)UP>5N'AD+!8DU40<*'D(W,)JAF#)9.H3A1A$Z4UECE";HJU-;L=UGXF4H)Q -MT6XEBB^:A(83]+S/-P]I]K3-1V6=LED@Y%0GQH6FXHM`3&TD@&ZJQAK;2HWK -MQ,5:;_H\#R2@Z2%!TTQ=@7A!MEB>T6@S*M;"Y@U?ILD1!]S/M'3`-;.>*:V3 -M]9Q(ZK*H`!:S%HLE<2E$W/R#Z[4U_6V#(V,]13DX5@Y9A&S&A&J8=?SI7;._ -M@'*$ZT(BX(;)NC9,#.#5Z[,&YBV;B@QF`:56XOI"7+UYHY'U7(\N`9LR2J(MU#RD;D$U7W!DDE4\XFPB=(.RQPA-\/:FMT* -M:S\3*;VX:+<2A1=-0I,(>O=N<]P^C3_68=@\/)*V$Q6$:>.31]1N9+BNVZX% -MH_4.UU,0AVIX9#QQP:B$C$/'=L56`4@_\I-'-ZA(C(!OHG)1F'"4/MNE$;G9 -MJB[8'5=U-I&.C!^<*]&642<^BB$*-+<#)A-\?]VWN,-*P,PB1M/5EAV%9>^<1M1H?O -MT?6:,!MU?V6%8=F%2:O#I2[9RR8<1F!&P3UQJ"M./VI.; -MI&(UYLZ)2'?NW$VH0=>!U17ITN@+@43LPSG][[_YS2^A2K79/#Q6MQ,5Y'3C -MDT?I;F2XGM^N!:/C#]=3$*-J>&0\<1&JA(P#T';%5@%//_*31S>H&HV`;Z)* -M5)APE.;;I1&Y]:HNV(U7=3:1_HP?G"O1G5$G/HG(3WFV!]^?66T<'HOK20IR -MN/+(HW`S*EP7K]>`T_E>B_J!*;1-3S*_B;>LIMPR-J-45! -MH)8.>42MQX1KO%7\&9VWMX""!&Q#(N"&R\`F3!P(5NNS"@8NFHH,9D%E8-#4 -M$A6"8MRB=,PZ8\@ML[5G]\S6TT1J,$X6KD011I?@),)>SCE<%E8;AT?8>I*" -M@*T\\@C;C`K7C^LU8#3D_BH*`K$+BX0?+A+;4'&86*_2*I"X=$9R"`85B8$S -M3%0F"E*,TD>;Q"$WTLX!NY-VKB;2BO&B<25Z,-*Y$,T:9Z"3B/AXO"-%8;QT><9MI -M"@*W=LDC;CLN7)MNUH'1IP=+*)R>(95$(& -M3S11$2G*-$IW;?.'W%X5#^S^JOB:2$G&3 -MV<2]$CKUE=FFKU.)QZL(#Z\",+SR27A=C6!<+@?IE(**Q(`Y)2H/A4A%Z9-7 -M7I.\2G7(Z[1Z,#[XK40#1I78)**6']V&\;3\MG5P/"TG*$C3YA/S]*2K1H3K -MN?7'Y,D]5U\[0?0UX>![X:*O#A$'?>7*K`)\R^4@G5)0W1VS,V>VQ<321[HL/?BO1?5$E-HZHZ2D_I,>S4_0UVP5$TG9J$A!MG!$) -MVHT%V&3;>%,Z['"Q)"BGAH#I@LPW)2PDN+7K$#?7EDHW(GN<4BYD^LB(."G^ -MH+I'O -MWO+0,!4\!8=.0/0S[=O8!@WQ=+>_L47`4\D\1:(ID$+&:0/H8XAK3,R9/VV0 -M+.BII+!I0%%%G=YN[5P\%R)JF_E;>LLDZ+?A37=X4ZAAN.8_20?A!G^`&]?8GH1UNFJ;,< -M((^T#.%`'&<-8A\3E7Q(,!)?+&>+PB<,YTR1+&,`!]G#/(`>8ILLL0?8)A\R -MYXZ*7!:@;R""8P<<2J3F1=QQE\$&Z[9%Q)&5: -MC2AQY4/644DT>C-W^"SBW\XM2R/P_;#$0VR+,>V.V(G.$D6,MTCU6)2)#+V? -MTRS:3%MX2TCC='AW=**(:-Z_\W9=1&\<7P[>'9EH2)F,"7=EXK!DC'%,-%HJ -MB="<&+GS.TQ2<._^YK,">`,NO,W8K"@WXX#] -M/]A$4H].BI\'PW_:'HZ])80QV]`_C"VP#(PM#)(9QR@QS#$E,88!291COZ/BR6$H1&&)2 -M',%3A*Q$1#GB:C"&E0]3S8/V7Y_ -M=]Y5[\7YU=ZDEJS;^LT[^Q2)U+,ZA--O9$SVUF>//[`%`A:02++1D`BXP9!M -M+$Q0PMG7)SK.>9>*#&:9U%ETU"*KM4FYY6J.(QD#:I*C]JAF.>I)0-6MAX41 -MJKY5)#B>L,>'\V<@25AN&!A9J\E)0;7TQB!J/1I$[ZUB3FV\O163@EX;!JX/ -M%NZ:T)!95ZU&_)A;*.NH)`()O7!9)"?Q9&B$[GUUR>*<8]!Z@;4\@W -MI,C?$\6\_L^Z[L^YWK^">Y[F3BD"0\:53J`4$5`\`AR!-Q[BK1S\6SBFNC"9%K8H"3E`@X>J_;$^'S<-^FU^R$;5DV#8$WIFFR**>P2&6?L8QN5J?*?ZH -M%CBZ@"R264(BX`9/-G.8<(0SK4^DG/,H%1G,LJNSB*C%5&L3<0O6'(T9@VB2 -M%GM"L[1X$E-U:V!AM*HO\@3'$?8^V6^SS3[+TLRI"M5M`^*K-D4)NJH.B735 -MQP1LQ5K\*:W8O(`2).R'1,`-F82],)%(J*U/W!ST(149S'*JPABH):,*I;F% -M:IIZQN";9M^>WC3[GJ158=0LC%T5QIK@2,(^[9+#T7V>L-DN)*XV4Q,A:NV, -M2M-V+-"VV\2;U'('BR5".R4$3!=TRG5AH1&N68?(V;90NA'9XU9V`=-'2-$) -M\0?7Z-JL(#0YQ9;1X!0OXNHM)IY%K]8B26`D(;-WISQUB[-JLY#H6$],!(V5 -M+RH9FY%`.V4=:U*C[*^3",:ZZ?,\T"'6AH3&L'H%(@?8$GE&HXU;C@7+&R$Q -M)D(<7"=KTH'0R#I31A_KG(CKL%@`%KT&BR!Q<41\W.>[;>X^.]9L%Q`1VZE) -M`+%Q1B1B-Q9@F.P\62H)@:`J8+,L>4L)!`UJY#W!Q;*MV([''*L9#I -M(R/(I/B#ZFQ=5N!;FVI+[VVJ%VE5%A7/8E=FL20PCI!/V_S^U29]>]R[[VA3 -MMPV(D]H4)4BI.B324A\3L(5J\:>T4?,"2I"N'Q(!-V3B]<)$HIZV/G%SSX=4 -M9##+J>QBH):,PI/F%JI1ZAF#;Y9]>WK#['N25GU1LS!V%1AK@E,(>]KFKX"B -ML-PT.+I6$Y1#:^F/1=9Z1*@N7,6>WH1[:R>'P#8&@^^%B;XF1`ST52NS!O`M -MF(-T2@%U7\BZ4;FM:-@GFZ:%@.R$33PL/"7C*FL1- -MNV63C\PEI]`+G4PR,D^23:A>J.8(OA7JUO1.J/N15GA1TBYV=1=;0N,(FNVW -MN\U]DIYO/[X]W+O/ZPT,`J+I<+(22!UX)9+5,#I@_QVN":4-CZRL!!R-89+R -M14:E*70D8@Y7+VYL>IBM7/(Y)61<[),1E-/1#]6-#4F%;\I&)_3>;'0GK3E7 -MA]78]>B:"H%'[$UZVA\W#SNT9FT-`^9W-_DI*-YZ%Z*Y,EJB2NC63$(M&#)@ -M"AAK893V*09G-;0BD.Y6>UVH]CC+I4B+ULAQL78:S3P=;5G204E&OH30G,E) -M"+.LS#[QUM(";L'\T^9+M(-W*>IFG7 -M4E#9#/-C0NRKX9W&LW0+4$(NV0C:C%AE,PBC'F3I357]$?)[TB.`B0DN(6*Z -MM!63,JI+<4&C.I_I^.!OC6*8>.MN%7\K/-+QQ-,ER0^G9+_9;?/MILK,,^Q8 -MPFP:6A^R!$"L`YG]<[J/;<08K619.[).*Z\%6$-,Q[]EY5<` -M_I!R7H["L&."J#DL>"PP&XGQ4L26FD098G?'E"!VQY/H_K_!WI177[MWVVV3^=\G&3]7GGA,#M"MGV+5]>%4-ML0T6%9K\P*`+ED#M(I!5.C07-*4'F*D0K?/)M4 -M(;;,SIS9*#M'D^C(&.&W"GT866(3B'K>Y\6]R?E-0::G_)`>81IP:!8:9PT3 -M%R/NT#>'OJ:18OJU8:W(O7MLW<5P:@Z?K$<>9HTAI2/7L,(K@*_O>2U#4YA6 -MC9*G@AIV!7#=#RD3U_H*KP76'N>U -M#$T1^CHVGDKKZRF)2I0)O?3CR(2!*PF9,'`ZG;Y>.;#7HZ_76SC$CH`5U@%W -M@$FDM!#QR2)#1%U,*Y<%L2O&6RG0KDP2>Y*F3-;!96\$M!,6NL*\HW5HB=8L -MVY/G4+%KX.AJE&KD!<`B-/"];*I!N(26?`>;ZE6&T-AW3VEK(M#L)WFW6C], -M4KZD<,I\H8ZV>JO"J0_9RB4?5IP&SKY)Y*D@_3C]F?$"IKX3L0X]X5O,UH35 -ME>G4J`N!0NS+Z91F.5"GUAL'Q^EFDG*$KCVRZ-R."M7IFS6@=_G!*LJ!4PF+ -MA!\F,+M0,6#9K-(:,+EX1G((!M2;H3-,4F=*4HS05MO$H;94Q0&WG2JNIM&4 -M$:-Q'1HRSD3'$;=0G?LL2S.G8.RV#(BTRO0D(-NY(Q)6'0^P)2MQI_1CT[)) -M,%`/!=L)F7Y:>$CH4]8D;NHMFWQD+CEE8.ADDA&`DFQ"=40U1_#M4+>F]T+= -MC[3BBY)VL:N\V!(:2=`\.QP?W;*NVBPD@T6CC%FO!\D9(IHD0!]?/FG0@-+/.E-') -M.B?BNBP6@$6OQ2)(7`H1-_?I\:=]=H8\R3*T"(Z2VG3E<*FZ99%3'Q^JG6KK -M0N^LYN658V$_5&+.F(3LA8\!2VT-UT!-WY*6S4&@2(R'A)+2<1H6$OJRGEO4 -M%MWWPNW6?7_3*,Z5478=ZG0]!8$C^-OLD.]-+XER4-QF%Q#+K5.7X+G-.9'J -M]K$")8-UO2C"P;WX$C0>"Z&P2S*91\)*XK-UG>-F="CI+<16IT:.F:XR>GDN -MOJ*D@CT+\8)AS!==-HQYE5;3?^/WBMXU^K<"8JIOU`M';79A]@?Y5X[:G/.[ -M`^WEC-;U8LJ3"5\[.A9"89<2]!9YD9UUG5?#;J_36XBM&/4='5W%U?>D?*6* -M!_:K%,=\B8B'R=]"^C=^K^A-I'\K()[Z1LOND#O"-$);J@/0M8>,Z)A83$M2 -M6`Z_8MQ=FV#V)ENYY$.(XAC8)RV#I>E'[-LB#5NX4\^B<5>"U?7HV/@+@4=L -M]\M*AQ8!$UOH=:5#MT+$1KP"TK`N$AI`^I6EYE").1.C*_WU>H8U7!==_4A: -M-@?1TC5T$DXC7B59R.K:M-UIWF"Z2LJN3<7&7A`P@M]M=YN'G56V -MUC\'0.9F(AP(USZ0Q&WW[.C:32PQ+7H0?P[>E.G1+-'@ZJ:,HE03T3B!-$N^ -MX*K?*M;"JW^>#.,1`-1/VF6%-P_%!-\I%&,IG10<2&+5-B$E'HQ(1S1\^J%`(4B/ -M>IP86BBS*$2Q*IVPF<)3/7)4`36B7@+`V]'`$-^4!BZD-%$TB(I5*\60J"CB -MW9\.J4M"E=N$0[MJ2@*H*QW12%>/`=;DJO@2>EQO803(U$Z984[E4A,&"I:J -M>$?-I%E3BL`0EV@*DB(BDHG-$4P?JE<>W89:.W(7:CT(JZ6PF12Y4@HV05&$ -M>\RW]B^QJ-N$P[=J2@)T*QW1Z%:/`=;2JO@26EIO802(U$Z984XE4A,&"I&J -M>$?-HUE3BL`0ETH*DB(B*HG-$4P3JE<>W81:.W(3:CT(JZ2PF12Y2@HV07&$ -M>W\X.552L4U`?"NG)$&WPA&1;M48@"VMC"^EI>D+(T&D9LH,S9E2!(8X55*(%)%125R.H)I0M?+X)M38T9M0XT%:)07-I-A54J@)BB)< -M`E!)25A\2Z144D*G6X)I:0FUI27B*BGA$2GA$"EA$"F)7R7-FE($AKA44I`4 -M$5%);(Y@FE!";$()NPDE$ZFDL)D4N4H*-D&1A'O:NE72;9N0^%9,281N-T=4 -MNI5C@+:T(KZDEJ8MC`B1ZBDSS.E$JL)`(U(1[\AY-&-*$1CB5DD!4D1()3$Y -M@FM"Y!<4AK646`J=2XII1\#II@# -M_Y1ZX)^*GTM*><=M*>>X+64*B> -ML@_5TXG.)87,I.A54J`)BB+)9**3<*A6SDA`;05?FADJT8`ZV9E;`G- -M3%\3`10UTZ5;4T%4AX#"H3+244-HOES"4\,EBP+DAH@H8I(#TW&J)4U&CT,5NYY',IN\C8)Z+Z)J0?IO&: -MD@K=ALU.R$W9[$Y8.ZX/JY%KSE45`HK8YS399H?S)M]FF^U]XE*J_/;UU,`HZ;PR'BB(M00,@I`!RL6-3S]RD\>W5QJ -M-"*^B2C1B0B':;[#-$*W7I,+%T>&-RRO(TEZHQ)QQB:J'CP-5=0U7057/ -MDI;-0:@XC8:$HA)U$A92^K666^26W?/"[MH]?Q,IUG51=B7J=34%@2)X(8-? -M;;-=>A%5DW"R,7"U& -MF^`HPEXNN_U]NG.>U6RW"X>KW=0$B-HZH]%4&0NL[7;Q)K1Y68M]137U(O_MD#WAO&.2\89[Q?//Y/'LR7 -M2WAJN(1/@-P0D3Y,;M]DA -MMU^+4[<)@&C:E#A`4QTAB::/P='`M/AB.IAY83@DZD^988YF42\,*!AI\8Z3 -M14ND%($A5ED4,D5XPDB*(Z`.I*\\O`7U[?`]J.]!2AU%P:18%5+H"0HDW#'/ -MWMGU4?EK"$RKIL%B6>D"2[%ZOZZF5<41U:YZH6=QIIT:R1#/EF:Z.*I4L8R4 -M)I,G"JK>[5HFL(IGZA=&S<-:0KV>B&;06A#:0&LKIE!"(D>T2B20A$,0:'/. -MLZ>QNZ3UK4+A43.`-)PNSNC&8U@B-F^TJ;,&-2\@#9H#1+8J/2?(@JI%B(%;6"BB!A@02\ -MYML\SS8/V7Y_=][9-59ONQ`8V)\:BX$]9U@*#L;B:H7]>*.:H76Q6/0RA(#I -M`D^P85AP#.NO0Z0,6SC=B.RQZZ\(Z,/48,+\@;6U058@&IO!EM#:#%[$U%B, -M/(M6E466P#!"/AR2?)]M[M/+,;=*,VVC`,BH3XH#1IQHFJAS*(0Q2JXPF8*3VK)4074HWH)`&]0`T-\ -M=QJXD-)6T2`J5CT50Z("B7=Y;W^0O_PQ!+Z5DV!1K?"`I5FU5U<'*V.(ZEQZ -MU%F@::9%L<.#I9XJ#BAE%"/%R+09@JEPNY8)JL:9VH5/OC397LC]NG_69_O$]WA^.C56=8#0+@DGVR -M'%)9O2+I-3(Z1U>RKPFF4P%6E@.MT3!)^4+#;2QT*.#95R].!'J%)'!_'(XVWHLSIG?;EHC#P>'460[0Q!N$`X6Y7NSC -M)-MR"4;BBU4&ADX8GN"39`RHH_7S`-[&AI;XWC7T(:7_?G#YO=@*,=\WK!Q0B(;X(&O-I[X7B;U/*$Z1:(ID3GXYVS:N,;, -MF>G3!LD"A_`)BP820IHQQS*29*XG0 -MG'!HF?!((:%G>*Q`M)1JK;%-I;&BMI7&7E;9!$J=N!5.>`F))%AQ"Y);[91; -MA<2Q:EHB)"M=46E6CP/:N*HXDYI7;XE$>-1.G>6`SJ4F'#0V5;&/G$ZS)QB) -M+VZ5%"AAA-22`&-P3:K.`T*C:BT9S:KU(:Z@8B!6](HJ\(2%$?"TO2(>)#1O -M'0`/+=/D4-'L$DE'V[@-5PH_EG6*DX*^I>8 -M+)Y9E5UL1.,IO2F9!FJDMOR!-U2[!WQCM?N24H2K(F6LBG$M"0\C<+;?[C:[ -M;;[=)-OLT7[6KK]=`,P=3(W#VKXS)&6'8W&TYD&\,4W9OE@<^IE"P'2!)IXA -M+"C6#=8A3L8MG6Y$]EAU7PSTX6D]:?Z`VMTP*^"-SF2+;W$F+U)J+DJ>Q:K: -M8DM@#"$/YS<.759L$0P3R^GP65BX(5&PVC^H(99QQ;="?3GXC&JF2C8F -M/H%(98QC)M'_W][9-[=Q'.O^_FM^B@T/*WJ)2%J6%5?(4FX467%4L667).?F -MQ+(A$%Q".,);@*4(R?+Y['=>=V=V%\1,=Z^`F9$KL4EPIC'3W?M['NPN@(_5 -M1-ZR4#AQ?19#?`'ZQF$VN?U?J^AE!J4!CNS3XKX<%D[^Y/F>[ -MT:@+S&FL+R\-B]M2118,0>"6]`'AVZAA[-3=Q:9%<]#!%,=%0BHKW!T+/76\ -MV5L0"6^+@E'OMGCTCC=!RL;O;M,Z(#P(GJ^8$QZL_YYS:U`HE"XWA<:RC@0A -M<;4*%TTO<^PMX\WJH$%H;ALS'X8[(Q7^A"NS'C'2/GYG08ARO0T,EBD$9H^$ -M*NX*5C6`IVB9$X$Z988@]6HQ("IJWQ5XHWH0CWNOWG0VS5>C99%/-YBIQNA0 -M"-C<)AJ$C9`0(K:LRT46FW7PUL=K2HGF6VMJ2`+!B->6+G_T-6L5,0%WJC%1 -M/+O>RD5$-`)SUQ'3W%6TI7\\Y;0U`E!76V.1.L%42!FU6TR@X?T(7.2+WG#Q -M?C3?Z":KD0%QU]@>!7&K<$#:FNMQ%&DC[Q"!;BL;!0OM5*"#@!EHI0?$/Z,F -M<9-ON\T'YM)&5Q@ZF6C<("6;O$31[!%_0;1GP\70CD/M_**D7>Q.+[:&]B?H -MV-G9C4/DYYC6V8VQ]!S[B^L8)Z[ULE&Q;DS!NC&>=6,TZ\:I.+OM-1^82T[. -M+F0RT3D[*C9Y"^$8)81C(B$<=^KLHJ-="LXNIH8&$/3]S-'8\8&AT5-LC@R= -M/!J&G'(U/KHJ<@Z65;MB9)#3:<#&P"%.I09..%&-!/"VG:Z#DLC-R@7+(D(C -M1T(C?]63S0$4/3T9J7DZ3"<>+B:\)>'?(FED&#%[D\MQ,9J/\]Z\OR@V?&#. -M-?,"I&ECZY1HK0='DK:Y5D]!;M0+H\_KBT])T;84$H=$,[8EK2CD-NJ7BPV?L[AV5IC,-;=-S%XC-)["UCK]Q=NL$U+&6TM.S--:ZD@# -M4C#63B>6MF9MDZ'NCC8T"3]]O&I4!"7WKYTQ%"KY5M^AQ+\6B<0&U&)VZ'C3 -M)71"SCC)`\9?`2XOS_/![-S-.)>#`Z-]M4DJQ)<1$60W5N7A(:H:0*U#2Q6I -M`&NEA2(."J=FJL`4K:H4/SIWH",Q!'.RKN$SC,ZHTE+,6V6-QH&)JQ4`IZE6 -MJ"Z\9]1H3,%7QMKH/L2=+2;]HO?5YK>G&P.#X:RY.3QAC6@@NEJK<5)C,^?^ -M2MQ:,3S\:FG`Q@!"STX-`'AF-6)&W5:[#DJB#;XO=!91^#U*&GG(G]4`7BA]A'[S,8;9S<69B\H7-F>.)XBYEH!YB4J:DX -M(5-!NO!C40`L!1\6>N/Z$W'0/W,R8'Q<8$046Z,"(@^&(*)!(SS5]I -MC?X!RJP5`:FQ5JQ.G&;LI$S"74;<\$`"GXVF[H:2#PZ1OF*3I.CE$;'DE:OR -MU6Q1`Y1DVU4D!:1."T48=8T5C,KXQPD:'$[?W;R_7R(8'RER^46KFLI@$U!4K`V@U -MKP56K:UZ4F-2I866^]/'-V\'&78?*-WE72$`PNN:".< -MY*H0-**K@G7I+Z,&9TH^,];&1Q#YS/$&36-\J$0^H[P]TPA*0>0SW]O=S'J@ -M5?VLDULS:RDB"D7#SS/D#41FW1+BYPZT*9)U?O8S<-IU8$`)>0=7XC/$36BU -M&$1:?-;AO9BI<#0I)QKQ`8`A]/LO/.THFQ`LH?EFZ0'-HI(06JP.I/6\)GBQ -MMRI+#U.5)JI81#B5J2/@*:]>2CC=B6[%DL_3G(;.OB[L*27]$/HLF@HKT"H( -ME4*K<-UZU`2PFI9/C?M`0!![^-[/JK+QH=*:;Y40?78]%-2#E6,8C4 -M6$7KU)7&SM&D'&G$!P""T&/7+Y.Q9X3*Z#'IU\O882DH/?;^ZH]:7="2/^[F -M*VB:J2(+1L/5,?;K&VHU3(BL.].T:`[Z>=4(2-B!7R5F(5RRQYBO"VE&(9+M -M<9??A),<99-RL`D<$"B"3_J^3I;-")???+L=T)N%I:&W6!_,%/"Z$)@"J[P= -M,%:EBBP8%6-E^B@8RVN8%&%WI&G1'/1ULL&3L!,G2\I"C'"+WD(+MXI")MPJ -M7L=.-@W*)N9DHS\@$`1?>=XAL`KWFMFJBSL$5C17S%;02Z\KBDNOJT[O$%C1 -M7=E:45W96A%=V5JE=8?`#K0IDG5^7C5PVG7@4PEY!Y?D%<$%TA7I!=+51[A# -M(':.)N5*(SX`@(3V^S(F:T:(C.[@ZYBLL%A*`[_BQJX+2O*[_$JF1JK(@N&Y -M2O/U(78-$R'K3C4MFH/N7C42$A+[U0Y8")-L_-?2-*(0R';WW]"4&F63<;") -M'!!`@L_.!^XFE@\.D=IBDZ2XYA&QI):K\M5^40.4[-M5)`6H3@M%'#PV5:IP -MQ!152@25V^U(#,'<[6?0#",VG604@RFK;!R$J.H`!'JJ0W7F+6-%8S(^,L)& -M!Q)W^7;Q9>_L_6C^16\QG[C;Q]J\$"EQMIA6'X7J=$^'QCK8-&EV(L`DML0@< -M0TO4SESR)WXGY*@3/X`P"C'T^GB":DJPJC"D_X""*BZ)$@QA[_8V:H,W(+4: -MTZ.Y3!==-"(@ZQ02L'B8T@<5[%KOXJGH:9ECX&(71IF:C`AU'Z+?H&V'H=+T -M,F"W?C@AZ*;E?=,X,+!$!YQD+J<%S?6N3C&7L@8-0A`'_!E\?)1@$^@WBY6;)V3\@^`[Q:G40IS%`?Q-]L[+D$!X0?>FW -MCD4#W@'%%W^7U4L(M;O1K5CR^;G@X-G7@?,EI1]'59PN -M'&%TM$O!]<74T/X$'1;]A=\G:=DS`N-I;;M45+7#(NA:7Y^'"-?J`A7C=>6E -M8F0S563!4,QLI`_,SEH-XR?H[C4MFH-.CC(F$M(YS*Y8Z"W0]=Z""74S"DZP -MF_&Z<*+)438%IYK2`0$D^-#MVPGTV!"9/23\5@(=$$MIWR^"+_./$OQA%]]" -M8*:$(`R>ELCOU"[KDP@?M]B*"&:Y^\V`J47L,8FX!9-1Q%>NF_,)I'/8W3<) -M1,O"9-QB9`T.)*SSMZ]6HT-D+.VWKE8AL93U_^)*HPXH6>[H6U;MU)`$PK,1 -M_9U_1JT2H>/6&Q/%,W?/&#C1B'TC(=-@THKZ@D@[`H&\=OI-J=&3,ADG&6G# -M`PF\G/<72X_KY6I\B`S66R5EL`J*I7"Y-E\)U_5`B7BCJ*34-%)$%`I/SBIM -M.';JNB7"SAUI4R3KW/UF!+0C]IS$O(/)<-E-""$V8A!(L1&M,_>9`D>3<:&1 -M'P#^A!XM9XYO'YCR$7.4=*N'ULE&QL4H%.@B*AV5Z -MP"14-8F?@-MK/C"7G#QCR&2B\XE4;/*61MTC,%&L9N/DL(K3A1.,CG8I.+Z8 -M&AI&T,GEN!CU\E613PMGDV=-"I"J]J8I\6I%1I*VMDI/3;9KA)'G-=6F!&=EDD9R*[TWQ0($1?S5;+-A_G>VQ'A\@YF?OOW#UH\:,\!AM;I>0T498'*6M]?D) -MOED7A.2WEI>0J;54D07#-1H2DOK53E@(D6RK -MM\"B78N"ENU:O(Z<:UJ43<3!)G-`8`@^GDV'GE963`F6X'+#]``7<4D(KE8( -M<@:R-GAK4*LQ/6K+=-%%(X*M3B$!;64E4X+M#O4NGHJ>QC8&+G9A;:G)B-!R -MU6)8,2_#4*EY&;!;?YL0=-/RN&D<&!BB+Q:>+I=-");E?+/T'&=122@N5@=R -M"+PF>']@598>LBI-5+&(`"M31X!77KV4T+H3W8HEGZ>3#9U]7;A82OHAA%HT -M%5:F51`JD5;ANO6N"6`U+<\:]X&`(?;;?+$8%2V]CZ_0(KX*3 -MD-Q<*\@@&/7"^X2VXM-3V$XA<4@B)EMI)4"S4>>4^+R[[4W$5D]3'!==N[#( -MW?$5X1/,+L3:!3L6E6NPHW;KHA/G=UH..]T#"*00BX7/?;UJ='A:H+=)R'\5 -M$D?].;JD:0Y"VW2PM?'19- -MX&I]WM)=U@6GW\WRTK+33!59,`**&NE#HK2L82HTW:6F17/0PW[&04)J(TK/ -M0J!25[V%D6LS"H5FF_&Z_?]BZ7/&UI@1'LW- -M[1*BW`B+([FU/C^;8-8%X1):RTO(VEJJR()A26NG#P-:LX9)4';'FA;-05=C -M&PT)26UM)RR$:+?56V#IKD5!*W.-BW*)N)FDSD@_`D^?MUW\J]\7&"L -M%ENCXC,/AJ"R7(N'Q(M\0X7=+A85'74*D"%0)%1I`?-/U"%^YFVCW8#LI6 -M+/E<36(D[".UC1W0#Z+#9E.!!=D.@E9F.UQ''C,=K";B0Y,X$/R)/2D6N9M) -ME2,#([3:'A6893@$D?5Z/*1=Y1VJZ?6R43&R2@4Z"(J*97K`.%0UB9^"VVL^ -M,)><+&3(9*(SC51L\E9'W2,P6:QFX_2PBM.%(XR.=BFXOI@:VI^@\_[*^3Y' -M/38PAI9;I&*H#HB@:+4F#YDM\P\5VF8!J'H>.4KEU<8N;SJQ)U=X6EVA:79%9)F5VFXLX_?;D#V.+JS,.E#Z<[P -M_`&(VQ5"W*Y(Q.VJ0W<6"<_2<&?A-[`_(0O'*]>"\IS9P7NM6OA>S*C -MP)S,*#HY=U;@7VL6V->:!?*U9I'&N;-MM!N0/4[N+%3ZT+DS"OYXBUN!./50 -MD)QZ*#H\=Q8-SU)P9S$T,(B0O7PR+][YO?>V95IX]&QLG!"E]=@XLC97ZJ>\ -MC5HAA'A]W0FQV98^VHA8J+:D%,/81H63`.YN]S4-35WM9X0\)36G'1,5HOS- -M]@,;@;90:%_0%K0CG_L)V(EXY*0/')@B>#OKD#6@&S=-17VXTZ#Q&!V[9DK\ -MTH&7#+FIN>,=ZE8L^9Q=M8I%14:4`&0+'0)D6./IX'1+@ -MW1;:#<@>-Y,8*'T(+2$!?_QU3W0%4.[47*3*J2B=N+Q8>):$@XN@@0&$'#JZ -MLV%X?!Q2NK,ACHY#7[D<8N1RV(D[&^)I-L32;(BDV3`-=[:%=@.RQ\V=!4H? -M0G=&P!]_<1LBQ&U((F[##MU9+#Q+PIU%T,``0HX=W=DX/#Z.*=W9&$?'L:]< -MCC%R.>[$G8WQ-!MC:39&TFR/FS@*E#Z$[(^"/O[B-$>(V)A&W -M<8?N+!:>)>'.(FA@`"%7CNYL%1X?5Y3N;(6CX\I7+E<8N5QUXLY6>)JML#1; -M(6FV2L.=;:'=@.QQ!TH?0G1'PQU_<5@AQ6Y&(VZI#=Q8+SY)P9Q$T,("0 -MCN8L/#I26C,<&7V5$B.4G=@R/,6P$$,R+`U+]K'[#$8;-SL6)&\(S1B:./Y* -MAA`R$AWKT(?%`+`D/%C@C>M/Q,NE][M4:U,"XV1]PU3$K,5%T+.Q0@]-K=<& -MJJ]K:TR%Q)9TT45#H;*90C`VZY6,'Z`[V;MX*CIYQKBX2.$K`+'YHD=%/PK:D=&/Y$7SE^$O4JO,^"75%^$O4*]TFP*]^/!EYA -M/AIXUAOM!F2/DX4,E3YT9I&"/][JMT)\ -MD.^*Y(-\5QU^$G4T/$O!R<70P/Z$?#^:.[DS/BXP/HJM4=&1!T/04:[%0RY% -MOJ%R:1>+BF8Z!<@0*)JIM(!I)NH0/\NVT6Y`]CBYLU#I0^?.*/CC+6ZR*V#B -MIN?BQ$U'Z<*=1<.S%-Q9#`T,(J3?%6)K0GC$[.#JL!451U#@U36[)@B1[?*J -M<"--5+&P>*2Y-&%7+PE<[E*W8LGG:A(C81^I;>R`?A`=QE_B:@1!*W/WUWV3 -MPFHB/C2)`\&#V./^8KC!G&)H>[,.F2>TI1-0TH/E4`4M\5 -M,H2B]D^!-J8'T>;]5:]87$X'_2(_O]X/V4-#X5MM@VC*V?$@M*NOR$7C:KGW -MUKIUM4.CJYD.?!08RAHI\D=:K3(1@VT7>A!.J>O]5Q2<(O!CY*1RE\%ZJWC* -M87,Z4!:;@4A]6\SPB]K71=K8/D2=+4?%:#;=8/GTJ&`H6FX+CT\="D3.:AU. -MTEKFV5]5FR7"<\W<.BH`D&9&.@`@*W,?,\&VT6`@OFPP:^$2AL*BT3#&0[^J -M/O"5+G,F5+7,&+1.+!)BQ>VZPF]8#P(ZGE4+[Y4JY=DTW.M3WS,8F+,7G9P] -MP[]XQ+YP1+YH3.-LV;;Z#$:;ZPU7T+PAL%QDQ''7,,0)`Y*3!1V>`8L)8%%[ -MKT@:%T)$?I]8D6_X/(_&Z.#H6&Z3#I$Z)(J4U;J\I+.L`UQ!FZ6DXYV9&I)` -M2/H9Z4)`L*Q5"B3 -M4QT,Z!K;QLSWQEH]%5XTL[,>)\*VU%D0HJRUY5H398\*@'BU;6&`9X?R)%Y]'1ODKI9G -M'[U;5R(,IYI;1P7P)E4C'5ZHJN4^3E)MK\%`?%EKJ4(G#,Y443+&2:WJ?>`N -M5\V9_GK5C$'EK*(B5JSN*I:&=2?@]1]L48T(A'L$'VM1A0'0SO&#"(R\^@H= -MY4=:V%L%3P:Q"/96N=4DAD@+OCK"LUV`[)GK8>*@3XX/T7-'R^6CY9JT!-88$0&%S0QCL&G$\ -M26NM8(-*F[GU$>;6FF!05]LN?+8WT.P4>#',S'21/C;56+EQNX`P; -M#3F<5,DJN;L0U:;Y:T\M`)7?"AY"L7JGD!O3EVB]B_YH?+FXYKIIV]B@"&=L -MD09T54`P\C/K$S;ONMB&"6@QT+ -MGUI4!HV66Y[*:'8,1"+M^1BMM"/1N[F(61B_XXNSP;T)^[J_.!^/IBZGR:JQ -M8?&UVB(17X"K/,.E-]&V8C89Z0"'03#O2H]4.KIFD1/O"TV -M'YA++KXO:#*1>3XR-OG*8=DC(#$T9J.DT(C3@=.+CW8).+RH&MJ;H/-\,7&Z -M!"P'AD5/M3DB=,IH<'+JU;CKJLHY4%;K%2."7)4&;`P,XLK40`FGJA$]WK;5 -M=5`2N5BY@%E$9N2(:.2K>KHY0*)7349I7A6F`P\7%]X2\&_1-+(W,9?YX'*Q -M_G/>FB/#(J;>'A$P53@X,@IUZ/A[BJO$/%M5XV*M95J4`'0;&N3`^8=:HF\9-N -M>\T'YI*3LPN93'3.CHI-WD*H>P0FA-5LG!!6<;IP=M'1+@5G%U-#^Q/TW<3U -M[15Z:&`$U1ND`JB*AR!HN2(/A=6YATILHW94R#/2@8^"@EZ5(C#U=&7BA]Y6 -M>Q!.*2>C%S:GZ*P>':F\M;%L%9@X&M-QZF@$ZL+O10F_%#Q?;(WM3=1B=-U7 -M5#0&AL52M3DBCLIH<(KJU;@KK'XV8H(HVK(R)XUMUL)?::^I)QZ#K>FAB01$ -M8EO*`&!L5BQF..Y8?^+HML$5QL0W"H?8%>$\1+:EC7REMC4$5'!;@]'ZQX3` -M&;>O3*/Q(41^/YI_X>@UQ=#@."PW2$=@$0]%7[4B+^V6N8?K=JUV=&@LTX&/ -M@D2B3A$"A[(R*8!PBST(IY2C9PR94Y1>D8I4`*E4K0*5R7(Z5B++0-WXP@CA -MEX8/C*NQ`43E!5ODRTT7BNNC0Z-JM4TRK)8A,60UUN4CP54=P"K<4DHR'EJI -M(0F$HZ*9+C@8JUHE0,:=:$P4S]Q,8@1$([2*Q$SSUU6C?X#2:D5`JJL5JQ/G -M&#LIDW"1$3<\@,!#9DG=W*08&1IWY?;(B"O"86BKUN,CTC+O8(&NE8V,A64J -MT$%P#-3I@?-/UB0!\FVM^6=C45_XN'QC#DA,M7<,BE;CGJ)U&'$_->B;"U1UL80)&NOO-B"A)[$$[XB1,QJU.0PAZ+0Z!M-.S*$ -M5NG`1\$!LTP1G).J,@G`<9L]"*>4F_T,FE.$9I.,5/[*J5L%*)C5=*1.5H$Z -M\8\QPB\);QA98T.(ZF[[@J0IL>E#DQ0@MTBU[[B:6@002=]5V?'1H;'3[X]0GJR -M<#AZBO7XB2O/.T)$V2(-V6F@_,)5=G%RR92)T= -M"9L@0BAZ!"R$:C9:"%6 -M^9\VF>%.F\PZ.F@3\\9<[ -MT15`H5-SD1*GHG3BYF+A61*N+8(&]B+D;#'I%[VO'-ZQ:XP,AY'F]@@8:82# -M4=):CYMPFGD'2&=KV0C85DL%.@B4;W9Z((0S:Q(UX;;\1;!VFRP#-;B$#NY.&D7N:.+KJ$!!.TOW'P=&Q<:._G6R+C)@F&H -M*=;B(ZD\WV!!M8I%1C>5`F0('-ED6N!]R\6Z#T(?1M!/SQ -MESC1%4"!4W.1\J:B=.+68N%9$BXM@@8&$'(P'\W<_)D8&1HCY?;(&"G"82BI -MUN,CG#+O8.FLE8V,;64JT$%P?-/I@1-.UB0!PFVM^@B:F@@07OY9%Z\<_=W:GR(+-5;)>6I"HJE -M:KDV7^G5]4`)<*.HI%0T4D04"D_(*FTX3NJZ)<+*'6E3).OU@(G\+5ZTN*S3`]-)`)XZI0AV2DKE@HX=Z`_<73SL)^A\XW:?%(2 -M#JB\JHTPPEN&H-#=,EAWOC-R<*;C.>-M?"B19^<^=I./#I+&8INT*.8AT226 -MZ_*6>1C,L(E&;2_IF`;4 -M6-D_&(G5$2@45L?JSEE&3,IT7&6<#0\@\'!Z6;B^ET6-#8V]>HMDW%4!,=0M -MU^0CUSK_8+%N%)",C$9*",+@J%BE"+CE5D0PR\TS!DXM0K](R"U_ -MZ2P[!BB#0"%MND@RP -M.B*&L-6J?/2XK`%8D)M5)`.BF1:*.#@D&JF",[&L4@)(W'Y'8@CF9A*#9QBA -M322EF+^.5HT#%%(S`%))S5"=>,68T9B$7XRTT>'$[9W-9H67<90S`B6OVBXU -M?&58`@+K]0&D6]4%J]_U\E*SLTH563`2BI;I0Z-4U3`=FNY.TZ(YZ&4_8R`A -MO1&E9B%8J75OX>2ZBD*CV56\+AUJ,I1-R;6F<$`@".[Q-G-[2J@$IWZSN1V7 -M@N"0]_+6:H.V!IV]\;R9+KIH-+`E>.=DK9()P7:7>A=/13]C&P47.["VY&2$ -M:SGR[;G-,$1JWO&[U%.$;E(>-Y$#`T'TB]$XG_8G&[^5>LVL4*E>;9L9J -M@V0(E_$PY-8K\G$%*O=@,U"O'1E"JW3@H^"`6:8(SDE5F03@N,T>A%/*S7X& -MS2E"LTE&*G_EU*T"%,QJ.E(GJT"=^,<8X9>$-XRLL:%$[?7/EK/Q)7MTWB]> -M>[C`VL0@65O?/"UW:]'1%&ZLUENYZS7#Z?C:#J"%:TL:J6,2@+>96B2&Z]5. -M!6&B;5!Q\6K0K5"?U]2U@;I2)HU)D:TF2ZZ:!18 -M-E*(!7)9R61`O%N]BZ>BCX..A(ODKKD#,D(%OFHQE+2;84A$W0S8H2]."[H) -M^=]D#@PLT7NCZ7D^=?STL=:90=.]W'XWB-?AR4A?K1=L)\JZT;B*9AMTPV@S -ME>1!"8EMI)<(W&7-4Z/W+C<[&7+K%*J+!X=2C7YV]2=%V0YJ11 -M7F)&&ZDB"T;!Y"I]6!;K&B9#X!UJ6C0'?1QT%"0D=\SD+(0*>ME;*"$WHI`( -MN!&O0R><#F43EDSXJ!=A;4HQE>Z/RR<`]C)ZGH["/58^4 -MP^2&_2.0&.HZFJV),AYMX4B\1UO@#OW[)]B?I_8YRI\.+.QG*\_[*S<7SP>& -MIA5B)B)R#?8==,3+8ZC1@8^!`JE(#QZ:H1@*(W$[704GD -MYF2#91&A2R6AD;]0RN8`RJ*>C!1!':83+QD3WI+P@)$T,H"8R]?]A<_7)QOC -M0Z.GN54RA!I!,22UUN8CM&8]P'K;6E0R&M921!0*QT8[;7!$FG5+@),[U*9( -MUKF9Q$AH1V@9.^"=O^Y:W024WUH,I`K7HG7B*E/A:!*.,X$#`$#HHN]X0RX? -M&!J1Q>;(0,RC80@L5^.CX2+G8/&V*T8&19T&;`P]OI.BB) -MW$QBL"PBM(4D-/+70=D<0`'4DY'*I\-TXOEBPEL2OBZ21H81T^=$8A'L*^NB -M@].(!*2DI/(T5$H?#\K-*&`ZBN6R+\W)$V1;+.W7Y&0#MB -M`TK,.Y@2E]V$D&(C!H$6&]$Z3%)]5>F@BX>%9I@S'3E6Q1,"Y"_V)HYN[_0R>;\3F -MDY1P,.75;800WBH$@>Y6P3KSG;&#,QG/&7'C`XG\]BLOORF'A\ACM5%2&LN8 -M6!KKE?GJN:H%2L_K]23%9I4>FDAX;)8IPV%352P1:.Y"?^+HYNXW@^<;L=\D -M)1Q,=G4;(62W"D$@NU6PSOQF[.!,QF]&W/@`(J]8J0`:O2-WE"DG=E;=B -MKU!:O>K&1:X(,+A"`W"%1=\J$;>XG:Z#DLC-%0;+(D(G2$(C?Q%<8>1O12-\ -MJRZ]7DQX2\+31=+(,&+ZO#.G&AX@.\G?F5/%1%(4],X'HQ88I>WNG3EV>F@B -MH9%(<8.Y4;$TX+@3_8FCF[,K#)]OM`Z1EG`@D<6^0<$.@1?+V8\):$IXND -MD6'$]#E76`T/D)WDYPJKF$B*@L[%&+7`*&UWYPKM]-!$0B.1XB6O4;$TX+@3 -M_8FCF[,K#)]OM`Z1EG`@D<6>,K%#X`6WZW.%*8`S%5\9<^,#B3R=]7@=%_ER -M.9I-W8UG;5Z(A*YOG134M>!88C?6ZBO^]7JA7,#:XI-2MR6%Q"'Q'&ZF%0?D -M>IT3X?*.MS<16]UM;X1T)3;"'?,5YA`:78BP"BVQ"#Q#2]3.7/,G?B?DK!,_ -M@'P48C;/I[U)/IDM-IWH-4<&HP'6]O#,-\.!*&^OQ\E86'GWMQ+M9<.SM9X* -M=!`@/VOI`1#3JDG,A-QV\X&YM,&KAD\F"C]*RR8/R;1[Q%LW6\9Q='QQ$W>O6ZB31 -MU]3+7[!=BH^GZ?4I)`X)).VU:05P]YHZQ\S@<-J;B*T;O&K<=*7PL1^/KQZ6 -MX+HN]#4(U\>"VH7KH]*ZX4_\KO51H@1/[`!R4P@>YV(TSJ?]2=[+IX/9^6@Z -M7.NYVT<'H`5KMHGA?WM(3^JO6]<&L[&F#CX68U,I,=Q=GQJ20-Z,79LN+[*N -MJ56<--V]QD3Q;*W/C8UH.$_;)=.JD*>['UVN)CP_=T^&L_V]EK_N+C(CMA#RZS'_UT]:*Q! -M_MUX8.W0WD5S-'],3M@['RV+-2M4#V2#V?1B-#P:%WNCZ;+HC\>'D_[T[@E+ -M%?MO[[N'3Y_?VOOL+PO[BX;??LL=D*=]G^V+D79['?:YL -M!S>_^P?KWMX/M_B?6/>]X+UL#&+AQFQ=#V[PNHH@TT:0?#4JLL]/6:=_]FMV -M,5MDHVS$&N"`3SS-SF=2/_L5^6=W[YZ9>[/__T^>&?U(KOW+USNKHAGX3_PR76Z3`;_/!M-M>Q?)8;^Z/#CXORJ4*E[9;"Y= -MF?'#@:LAST*/#[LEDUS+X;)*7758B74NQ5)^W9`4-;8])]+4C1[P^^/2AU]V!]TH\YW655W6_F0W. -MUQ0Y^_WO,T'V_:JJMW3EV:PU)=:S]"1>6Z.P][R%X)Z+$-S;(`3W=D,([@4E -M!/>L?KR7K!#<0PK!O0B%X!Y0".YY"L$];R%H/=2W)@2M1_PF(:`[\'!"<`\D -M!/>3@CN@X3@_F8AF+\9RO-%O%FX(I0/R/;9J`OE -M^(WB8(\LVZ;QE'8?->,K1*G#,>J2G'MI\T*@)&P\9 -M)%[6W/$&%ML.5[J4]>F=./Q4BOUQ@,&7)@M'B]F+CV. -M%FLSC6-E[\G7_,#0>6`_/O_^QV>/Y(6K;Y\\_X'_]\7#;Y[W_O;DV\?\B-$I -M-,89LUNF2!%GM?K/92Y35W<32JCMYA[IYE:)':D6E[^632[^4+:Y:2D.;C[\ -M?_]@'O57V<(_'1Q\_C/SOG=/LRD;Q3]Y1?[V6V44'C_]FHD\6\=-/>16)@W0 -M3;%F$>A6-E^,ID4V$C;L-U76R9L1*_?%DZ_94N5>]XK^<'F2\4SL[?%_GV1K -M,JTN!+T^XFF1J?OZ\0]L,8^?/GK"![#XGUDYU9GFKQ"*;"56\#I?L/S.K\[E -M@JZKD_V$R=9L^7IT48B?RFT(ZC\6F7CX[)OGMPX.;NMZZKV=F"^-C*-9C>*' -MLTK3249@O]1' -MJCR6?Q_RCLH.1^S/WQ@+8`7AS[1O7E\7O5=>7.>#,T9A,2O[YIG\S_/__H[] -MF]]^D/'A>WN#U_G@S>$+II+"&(H?N$&XZ+/7R[Y -M#\LWH_D#J=5RU0_*-F"]L9K/%D4F?S5/;'K%V+/A?I3ED*SPZ+D\[Y&/K/)D]SAC%W21[9(V?%,^G -M]M1[_/2?3YY]__2[QT]?<#/W*QO]FQFY;&R>TU2M@^WV\YYO9/+[.7G_TLPLL?;TMFR/KHZ.*W*OYGJJ[Z -MS_)7X^^L"@S7B_S\E+G>Y8-__?#P^7-C9:?&S^KYY(SA8BIG7#,A7_8'+>EG -M7I85.L^^^NJCIDGT.AVI1X@NO3X)G8:P+6TE2I5B8/.?T4_)=& -M2L2SG(TOY;,\_\>3'\J_&CVK7P7]RL;_QE>U9#\OB_/?3N21L&_PNZ;8^Z(4 -M^\S1_X?3VBP8__ORP3[_3W5V[R&KX;[^U=R-,7I9&\[^E>F'RE4;"Y#)E6NH -M.0=CE*AIZZ`L.^M/ISD_J`_8<\GF8AOG2\GX`<."KZE`>WR="/[()4^\^D%I -M9/WAI060:U=SEK_NOV6-U%]RI.:#@OU\4_=K^8A,"8]\:[]9;W,'YOKY3C?F -M1S7R["*S%Z9JX)"FZFETFD2*EP_X?U2&C$>NRE&M,\>HS0 -M-]7!+>9WPS2TNI[?6I;MUYC*[8A:A9:Z17?$,KS0.5)A]?F5ID!T.7F6' -MX[SZLTI$]=H97>3<$K0FKCR@>>JX[3%.0OSP\-$_'G[SN/?7 -M'[]Y]OB'[Y^]N+5O)T['_8&YH&6N?LT*[DI;Y[9N7']8X(V:WN7'>O^J*#UF]4YJCRT1^ -MR&JYK9^!$\MAH0H[3'/C_&00W]0)!X-TO,Q9<;OZ]9/G+_3YF/*]\.<%;)?Y.PY1US/AOD-M;WLS\?G^=OCZ>5XW-9/ -M^6(Q8WF]F%U.SS,>F,]=\I>417\T'4V'?$[V\M5DM%SRW_0";O"#;MP?Y).< -MO1`K\E5QLI_]^?=?G%I+/AQ#5RT/E!O+XU^.,_W/\0WK&=390OD/BW8Q6O'% -M3NYDZM1H^;QWV+-.9EPFV"87N?&T>;7GT_UKHK^;CP8LXCN>B?X;/FLD$I0O -M#L4KL1O9U8@]H7H:OHI:-'Z2\ZYYN)Z4_6,TNGIM),/T5->7I^7%V4W]H#C< -M)F_8C]:C[*"0';HL%L(XRO;3;;M?)?:GGX]^^N7@X.7+VS\?OV3__/YXJ%]( -MS^:M,8P7JTYQ]-%9';(W-![97WK&"65Q_;[UG#+_2\OE4O8B8/F!/:NQSN,/ -M'TZ+_8K1Y1A[.\I.;XY?'Q[\Y/V1H^5`5BS[:\<_S3+\?R2NP-_\V)JK,LM?&:OM'^M[&,R+U,;F -M7C7Y:/6PGE]W11>C:>NX[)`=B&SIV>^RPWG.3WI\]?GG[&E7^2`;O)[,SK/+ -M/RRN5MFOOV4OJY=7;9@^M\Y?B91I"\+VG?WN069DQU[<@&'M8OZL&_B/ -MQ^J\&_]1G7:3MH`=H2KJ`T6>"GS&'ZH'2ZX'L#PM5$/Y&);&"WS4#?/GEETP(1],WR^RN -M5=#^'Q8.LVM=X#:)/Z68Q"^""3'L+5_+=U1-=`@91>9!QCY\)OYFZ8E(Z?#] -M:'ZB\\X$HK^0Y_[TL.JT)OL3OX[ZS;^?_,#^SO_#3Y'=RG@$_O1_KB8=L;%' -MP_?K1$\^\QF;]X774XL9V>&?VI[M[/T7US_=^/VD[_5L?,*:)^-_NO[95N^] -MGFOUONUI5ALRR,;\V^MI].<9M#W9OZ]_KN7K_L)X+OYK9CR38U_P:1L;P^Y( -M=0;<",+^OO>9"+[X3^UQX]=KGT/BA!T['[WU_RM[P1TQ&S7,B^R267@2Z9L^6?[9NQ$/F416+\'5[V%_UID><\2+\H -M(RU&9Y=\,/?ERWQ\<:AL/]/RLW?,X[[ACK\_G;'Q"Q:)K8(_]9&\`,&O(LC$ -M*..DG%[OX;-'?W_R3^[VE'VZK;9[6\%]38;.!UDC0^5=&B('MY@U*N.Q8UD' -M5(=\,P`;W@U0N@1J#:'23G@Y[6.WY?CWU9SGXJ=5W.\JZ__/3+R>865B9%3:6A3[/M?$X^/7%=_S=TH?'Q63^VW%_PA)]>,#^.=XO -M)X@GOCJ7]R64C[8O2.Y%CSDZ.M8';^NQ,:4C4&_*7XA[&=^+*N2GV)^5U-O/\C*':I^MO>Q>W>O"7 -M;[=J9V/NOA;_5B>VQ<]S\>^5(.O!P?R&^F%U8Z]927G7H@;C#;F99DO<$C>V -MZQ?JKUJ'\06KFT3DJ?NQ/+%_5S6+Z!.9L\?/GGW_[$3>4I*-\XLBZU\4^:)J -M\I/][-1L5NLD;7F?8>/TA7GZ\*8LLAJ;+2_G_,2X<4U"OHJWGV?3QJS!97/S -M$XY[=G.=5,W&,JR77WT$Q8WL07:4F>NW,E/KU$%_FLVFXW?\VE)VL9A-2NLI -MY*M,EEQ1IN^0^NPO9KFJ>.VEXN?_R^9?7RG6G%(SV3;R03%;O%/%*Y^C5KSK -MGMT<9Z=3WBO3GYSP&Q/8?]>?MCB0E>[]\.S[;YX]_.[YK?5#C1MP]E29#F[^ -M]<H-XFO>+KCFS2/7W2*_]H;@UK/HND4LK+I'_G9F2JW_#?SK^?]HE_]E?_&_UJ!J6(4?WRO^KEJU+]L6HQZ -MSL:S[%EDM@R8N41Q-OUD_9[UG>ZJD?C9.OW0\Q?/V*L4]0=][JXZ3^4RQ7Z< -M/^6#PZ4,]$K7D]\NR?]\ZX9Q\58"I;8X_HKI@1C+'WA03=Q_I==E??*.N((T -M&ISH#]NI?J_NS2L?TZF:#A]_J+E[SK`D7CWHG$E -MYT.V+K"@\L;PYJCR%,I@/IH9GW0E55EAWB"5'K?^;XU:-H6L&\`^I8D9RO'2) -M9@ZN#S&:5[QBY3W9TK*UO^WMU:^]&D?:7^31+4Z>#6:3"3])-N)7\8I\RK`O -MC&TU?16.'[U3_HQ0XS5(X+%M<=4$L1E3/W96X9<9]8' -M=*&R):#_3U1^NZ -MH\T^7EIZO[6%R^UH.[5G;K8JCY$#?LZ.^ZX&\H53*!]\?6Z8TK(`QB.S0=_\ -M7=ZD??YV=,+/ML@2B/\R=7E=3)CV\W^+Q]4/)URR+V9S5Q -MKSR%_;:Q\F%^.P1;?NN;,8UH?'7&+Y8)*5=;,QK5#+.C-[C+0[EE\S?KR0_YN/,5\:0Q>VF.7 -MUM#R!4>3-NTX`AZ%U%\=Q_[*83;XL\J-!GSUQP`=K2V9L7#5SIPY6ZR,5 -M68IK]+-_M_^N`=#B#.L@58?]WI[H&]TO99_P_E!]H?O!-/BFW3>/G75O`N7/ -M7OVM)@36!R9D:]YW7?M*O`\1+$74V6+=U>1*RVESY -MHWA!P>;^\/?OG_ZW>D>5>B\+GZ%&]R>'AXO\8I$O7UNQQMMLMV(W?! -M;UKD75E=GC#QN8:>%B1K!5U+3VN2#=#-8+1GUX"[]U]9_U;V2*1H=EEDR]DD -M9_.G>2Y>N8B7(_SUC#[A.;1I[M'P[K0U>._;& -M[?^]L7G,$85R>3^K:T'5W\35 -M0'[3L3J/WY@K'-,U`<2`]BC<<#5FL@?7CVY_,OV7]GG"/S;F\$>O&=_^1.6? -M:C/%+3-YML_/ZA^]WI?WR/S/)1O''UF*@V-V(>Y\46\@8G'YC2ZCJ?DW^ -MY?-C^VSV-C]J^08%OM[J+#Z_EZ:HN?36SPEGW9Y]D'?9?_WX;T^>/A9OALS^ -MW/)YZ?P9]O;*XKD\93GX^N>JQ=S;JRKG\BS5Z.N?IAY55#MG57N;+_C7[BRS -MG^X=W?_3G7M'?[QWBY?RFZ<_RN8H9N+-4.JMR;S0;_N+4?]L+&O\/;^SZ6JT -MS'DIWRV+?,+2-V$%O\EA^?S=\I\96S1_DU%Q2YP&.LM9K(%`\M'>T=/O'_^+ - -#endif -#ifdef HAVE_SYS_XATTR_H -#include -#endif - - -#if defined(__APPLE__) && defined(UF_COMPRESSED) && defined(HAVE_SYS_XATTR_H)\ - && defined(HAVE_ZLIB_H) -// -// The test ACL used here is sometimes assigned to the 'Guest' user -// This changes the text and breaks the test. This function simply -// strips the 'Guest' information from the string to help ensure -// consistent results on different machines. -// -static char _acl_temp[256]; -static const char * -clean_acl(const char *acl) { - char *p, *q; - if (strlen(acl) >= sizeof(_acl_temp)) - return acl; - - strcpy(_acl_temp, acl); - p = strstr(_acl_temp, ":Guest:"); - if (p != NULL) { - fprintf(stderr, "Shortening: %s\n", p + 1); - memmove(p + 1, p + 6, strlen(p + 6) + 1); - q = strstr(p + 2, ":"); - fprintf(stderr, "Shortening: %s\n", q); - memmove(p + 2, q, strlen(q) + 1); - return _acl_temp; - } - return _acl_temp; -} - -static int -has_xattr(const char *filename, const char *xattrname) -{ - char *nl, *nlp; - ssize_t r; - int existing; - - r = listxattr(filename, NULL, 0, XATTR_SHOWCOMPRESSION); - if (r < 0) - return (0); - if (r == 0) - return (0); - - assert((nl = malloc(r)) != NULL); - if (nl == NULL) - return (0); - - r = listxattr(filename, nl, r, XATTR_SHOWCOMPRESSION); - if (r < 0) { - free(nl); - return (0); - } - - existing = 0; - for (nlp = nl; nlp < nl + r; nlp += strlen(nlp) + 1) { - if (strcmp(nlp, xattrname) == 0) { - existing = 1; - break; - } - } - free(nl); - return (existing); -} - -#endif - -/* - * Exercise HFS+ Compression. - */ -DEFINE_TEST(test_write_disk_mac_metadata) -{ -#if !defined(__APPLE__) || !defined(UF_COMPRESSED) || !defined(HAVE_SYS_XATTR_H)\ - || !defined(HAVE_ZLIB_H) - skipping("MacOS-specific Mac Metadata test"); -#else - const char *refname = "test_write_disk_mac_metadata.tar.gz"; - struct archive *ad, *a; - struct archive_entry *ae; - struct stat st; - acl_t acl; - - extract_reference_file(refname); - - /* - * Extract an archive to disk with HFS+ Compression. - */ - assert((ad = archive_write_disk_new()) != NULL); - assertEqualIntA(ad, ARCHIVE_OK, - archive_write_disk_set_standard_lookup(ad)); - assertEqualIntA(ad, ARCHIVE_OK, - archive_write_disk_set_options(ad, - ARCHIVE_EXTRACT_TIME | - ARCHIVE_EXTRACT_SECURE_SYMLINKS | - ARCHIVE_EXTRACT_SECURE_NODOTDOT | - ARCHIVE_EXTRACT_MAC_METADATA)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, - refname, 512 * 20)); - - assertMakeDir("hfscmp", 0755); - assertChdir("hfscmp"); - - /* Extract file3. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("file3", archive_entry_pathname(ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad)); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - assertEqualIntA(ad, ARCHIVE_OK, archive_write_free(ad)); - - /* Test file3. */ - assertEqualInt(0, stat("file3", &st)); - assertEqualInt(UF_COMPRESSED, st.st_flags & UF_COMPRESSED); - assertFileSize("file3", 8); - failure("'%s' should not have Resource Fork", "file3"); - assertEqualInt(0, has_xattr("file3", "com.apple.ResourceFork")); - failure("'%s' should have decompfs xattr", "file3"); - assertEqualInt(1, has_xattr("file3", "com.apple.decmpfs")); - assert(NULL != (acl = acl_get_file("file3", ACL_TYPE_EXTENDED))); - assertEqualString(clean_acl(acl_to_text(acl, NULL)), - "!#acl 1\n" - "user:FFFFEEEE-DDDD-CCCC-BBBB-AAAA000000C9:::deny:read\n" - "group:ABCDEFAB-CDEF-ABCD-EFAB-CDEF00000050:admin:80:allow:write\n" - ); - if (acl) acl_free(acl); - - assertChdir(".."); - - /* - * Extract an archive to disk without HFS+ Compression. - */ - assert((ad = archive_write_disk_new()) != NULL); - assertEqualIntA(ad, ARCHIVE_OK, - archive_write_disk_set_standard_lookup(ad)); - assertEqualIntA(ad, ARCHIVE_OK, - archive_write_disk_set_options(ad, - ARCHIVE_EXTRACT_TIME | - ARCHIVE_EXTRACT_SECURE_SYMLINKS | - ARCHIVE_EXTRACT_SECURE_NODOTDOT | - ARCHIVE_EXTRACT_MAC_METADATA | - ARCHIVE_EXTRACT_NO_HFS_COMPRESSION)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, - refname, 512 * 20)); - - assertMakeDir("nocmp", 0755); - assertChdir("nocmp"); - - /* Extract file3. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("file3", archive_entry_pathname(ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad)); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - assertEqualIntA(ad, ARCHIVE_OK, archive_write_free(ad)); - - /* Test file3. */ - assertEqualInt(0, stat("file3", &st)); - assertEqualInt(0, st.st_flags & UF_COMPRESSED); - assertFileSize("file3", 8); - failure("'%s' should not have Resource Fork", "file3"); - assertEqualInt(0, has_xattr("file3", "com.apple.ResourceFork")); - failure("'%s' should not have decmpfs", "file3"); - assertEqualInt(0, has_xattr("file3", "com.apple.decmpfs")); - assert(NULL != (acl = acl_get_file("file3", ACL_TYPE_EXTENDED))); - assertEqualString(clean_acl(acl_to_text(acl, NULL)), - "!#acl 1\n" - "user:FFFFEEEE-DDDD-CCCC-BBBB-AAAA000000C9:::deny:read\n" - "group:ABCDEFAB-CDEF-ABCD-EFAB-CDEF00000050:admin:80:allow:write\n" - ); - if (acl) acl_free(acl); - - assertChdir(".."); - - assertEqualFile("hfscmp/file3", "nocmp/file3"); -#endif -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_disk_mac_metadata.tar.gz.uu b/thirdparty/libarchive/libarchive/test/test_write_disk_mac_metadata.tar.gz.uu deleted file mode 100644 index 216b6ef69..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_disk_mac_metadata.tar.gz.uu +++ /dev/null @@ -1,14 +0,0 @@ -begin 644 test_write_disk_mac_metadata.tar.gz -M'XL(")$=EU```W1ED^J[X=\E-1`VU$L -MDD1X!Z"E_TCQM_]^_6."M_1/+&R5]_]OP%]<3_BC4ITE)24E!\8G]#K>=@`0 -"```` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_write_disk_no_hfs_compression.c b/thirdparty/libarchive/libarchive/test/test_write_disk_no_hfs_compression.c deleted file mode 100644 index 0af44d246..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_disk_no_hfs_compression.c +++ /dev/null @@ -1,231 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_SYS_XATTR_H -#include -#endif - -#if defined(__APPLE__) && defined(UF_COMPRESSED) && defined(HAVE_SYS_XATTR_H)\ - && defined(HAVE_ZLIB_H) -static int -has_xattr(const char *filename, const char *xattrname) -{ - char *nl, *nlp; - ssize_t r; - int existing; - - r = listxattr(filename, NULL, 0, XATTR_SHOWCOMPRESSION); - if (r < 0) - return (0); - if (r == 0) - return (0); - - assert((nl = malloc(r)) != NULL); - if (nl == NULL) - return (0); - - r = listxattr(filename, nl, r, XATTR_SHOWCOMPRESSION); - if (r < 0) { - free(nl); - return (0); - } - - existing = 0; - for (nlp = nl; nlp < nl + r; nlp += strlen(nlp) + 1) { - if (strcmp(nlp, xattrname) == 0) { - existing = 1; - break; - } - } - free(nl); - return (existing); -} -#endif - -/* - * Exercise HFS+ Compression. - */ -DEFINE_TEST(test_write_disk_no_hfs_compression) -{ -#if !defined(__APPLE__) || !defined(UF_COMPRESSED) || !defined(HAVE_SYS_XATTR_H)\ - || !defined(HAVE_ZLIB_H) - skipping("MacOS-specific HFS+ Compression test"); -#else - const char *refname = "test_write_disk_no_hfs_compression.tgz"; - struct archive *ad, *a; - struct archive_entry *ae; - struct stat st; - - extract_reference_file(refname); - - /* - * Extract an archive to disk with HFS+ Compression - * the file was compressed. - */ - assert((ad = archive_write_disk_new()) != NULL); - assertEqualIntA(ad, ARCHIVE_OK, - archive_write_disk_set_standard_lookup(ad)); - assertEqualIntA(ad, ARCHIVE_OK, - archive_write_disk_set_options(ad, - ARCHIVE_EXTRACT_TIME | - ARCHIVE_EXTRACT_SECURE_SYMLINKS | - ARCHIVE_EXTRACT_SECURE_NODOTDOT)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, - refname, 512 * 20)); - - assertMakeDir("hfscmp", 0755); - assertChdir("hfscmp"); - - /* Extract file1. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad)); - /* Extract README. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad)); - /* Extract NEWS. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad)); - /* Extract Makefile. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad)); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - assertEqualIntA(ad, ARCHIVE_OK, archive_write_free(ad)); - - /* Test file1. */ - assertEqualInt(0, stat("file1", &st)); - assertEqualInt(0, st.st_flags & UF_COMPRESSED); - assertFileSize("file1", 8); - assertEqualInt(0, has_xattr("file1", "com.apple.ResourceFork")); - assertEqualInt(0, has_xattr("file1", "com.apple.decmpfs")); - - /* Test README. */ - assertEqualInt(0, stat("README", &st)); - assertEqualInt(UF_COMPRESSED, st.st_flags & UF_COMPRESSED); - assertFileSize("README", 6586); - assertEqualInt(0, has_xattr("README", "com.apple.ResourceFork")); - assertEqualInt(1, has_xattr("README", "com.apple.decmpfs")); - - /* Test NEWS. */ - assertEqualInt(0, stat("NEWS", &st)); - assertEqualInt(0, st.st_flags & UF_COMPRESSED); - assertFileSize("NEWS", 28438); - assertEqualInt(0, has_xattr("NEWS", "com.apple.ResourceFork")); - assertEqualInt(0, has_xattr("NEWS", "com.apple.decmpfs")); - - /* Test Makefile. */ - assertEqualInt(0, stat("Makefile", &st)); - assertEqualInt(UF_COMPRESSED, st.st_flags & UF_COMPRESSED); - assertFileSize("Makefile", 1238119); - assertEqualInt(1, has_xattr("Makefile", "com.apple.ResourceFork")); - assertEqualInt(1, has_xattr("Makefile", "com.apple.decmpfs")); - - assertChdir(".."); - - /* - * Extract an archive to disk without HFS+ Compression. - */ - assert((ad = archive_write_disk_new()) != NULL); - assertEqualIntA(ad, ARCHIVE_OK, - archive_write_disk_set_standard_lookup(ad)); - assertEqualIntA(ad, ARCHIVE_OK, - archive_write_disk_set_options(ad, - ARCHIVE_EXTRACT_TIME | - ARCHIVE_EXTRACT_SECURE_SYMLINKS | - ARCHIVE_EXTRACT_SECURE_NODOTDOT | - ARCHIVE_EXTRACT_NO_HFS_COMPRESSION)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, - refname, 512 * 20)); - - assertMakeDir("nocmp", 0755); - assertChdir("nocmp"); - - /* Extract file1. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad)); - /* Extract README. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad)); - /* Extract NEWS. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad)); - /* Extract Makefile. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad)); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - assertEqualIntA(ad, ARCHIVE_OK, archive_write_free(ad)); - - /* Test file1. */ - assertEqualInt(0, stat("file1", &st)); - assertEqualInt(0, st.st_flags & UF_COMPRESSED); - assertFileSize("file1", 8); - assertEqualInt(0, has_xattr("file1", "com.apple.ResourceFork")); - assertEqualInt(0, has_xattr("file1", "com.apple.decmpfs")); - - /* Test README. */ - assertEqualInt(0, stat("README", &st)); - assertEqualInt(0, st.st_flags & UF_COMPRESSED); - assertFileSize("README", 6586); - assertEqualInt(0, has_xattr("README", "com.apple.ResourceFork")); - assertEqualInt(0, has_xattr("README", "com.apple.decmpfs")); - - /* Test NEWS. */ - assertEqualInt(0, stat("NEWS", &st)); - assertEqualInt(0, st.st_flags & UF_COMPRESSED); - assertFileSize("NEWS", 28438); - assertEqualInt(0, has_xattr("NEWS", "com.apple.ResourceFork")); - assertEqualInt(0, has_xattr("NEWS", "com.apple.decmpfs")); - - /* Test Makefile. */ - assertEqualInt(0, stat("Makefile", &st)); - assertEqualInt(0, st.st_flags & UF_COMPRESSED); - assertFileSize("Makefile", 1238119); - assertEqualInt(0, has_xattr("Makefile", "com.apple.ResourceFork")); - assertEqualInt(0, has_xattr("Makefile", "com.apple.decmpfs")); - - assertChdir(".."); - - assertEqualFile("hfscmp/file1", "nocmp/file1"); - assertEqualFile("hfscmp/README", "nocmp/README"); - assertEqualFile("hfscmp/NEWS", "nocmp/NEWS"); - assertEqualFile("hfscmp/Makefile", "nocmp/Makefile"); -#endif -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_disk_no_hfs_compression.tgz.uu b/thirdparty/libarchive/libarchive/test/test_write_disk_no_hfs_compression.tgz.uu deleted file mode 100644 index 8db28259a..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_disk_no_hfs_compression.tgz.uu +++ /dev/null @@ -1,1765 +0,0 @@ -begin 644 test_write_disk_no_hfs_compression.tgz -M'XL(`/2=D%```^R]^W[;1I(PNO^*3X%5?$9B5J1$2I9MZ3$ -MR6:&"Y(@B0@$.`!H24[R4N>/\P+?BYVZ=#<:=X#4[)SOM_9,;`*HJK[7K:NK -M)[9C=?[E'_MG;V_O\.#`P']?';ZD?_>Z_,Q_.GM&I[MW<-#I'!Z\.C3V.IU7 -MG8-_,?;^P?6B/\L@-'VHRFAI%<(!V&12\)U;8JA__P_Y8PY'8VLR;?RSZ_'U -MSS_GS[7Y^,$RQY:_>W/6.[TX^T>44;;^.R^[:OV_W'\%ZW__L/OJ7XS'?T1E -MDG_^AZ__[IXQ"NVY]5UG_R7T_L&KEYT&O#.C=YW7;UZ]:>R_-L[[;WLW)Q_Z -M/YRU1[X%$)ZK0;U\<_BJT7UMW`+$^4_MR<0QI\%W(V^^\*T@L,9?./J/AF$8WQJS,%P<[>Y&..VI'K8[151#+V=L?;8<;S&WW'#'L-V1LQP#F#'V1DM\1SQFQS#=L<1T -M[X&R1\0U,G/3=A#/L8,P:',%[SS#MQ:>'P(ZU`>JOF,L`XM0Z=$(?7-T;_G` -MZYBZ:-+(&T-C/&\*'8"-66B-W"7,8!<+4L4$R^'`_86\F;/A;H&1]R6B.015`Z>?--_HO$# -M=D\#`R-A//AVB+^A',N7_L"0.:;HP>'2=D*8.EJ]N(31PO:B(O`I4<;8GDPL'VG8 -M;FCY$Z`(XZ$5@Q()A)?I.$]$)S!QHB[=$7:;Z=CA$Y=D/9IS&+G@R+C%J1S, -M`4.^E$5BMYJA\>0M81Y"=]G01S#1H)WM.)%=Z"R;>L>DOC='(1:,I,;6'-88 -M3$CJ69RFWD1KMB`T`H$+8WMD&#^8ONTM`\,.+2@_$/,-:CC$]MC^V%B8?FA; -MP;'6:#$%D0H6C>TVE^',\P/C`:88#.Z3\7>YWMLXG[#7%BT'%RGTJ6^-0@\F -M!!&PW>1TLEV8*7-:LM`)V&E.8%&-/:X>M$L`]B]O[WKGYP`(M0AA2+A0?/"7-(0"4#"W -M%N%2I51'3NPI3$#X)'\SC6#DVPO@18%EJ6)P`8PM:+(C>HTZBA`I[[,ZFP3*@GS8R'3:\X.=J+%M[LHSV#!X:&]#=%LQJ,X26R:I'/+^TQ-MDXU9F] -M'%'98*A6\!0`/6CEMP8SE'8'EA30EU-0+!?\R0!R90H49!#%.`BA(VDK;]^8 -M(FM#[NY]MOS/MO4@$26#-)'E/,P\G%W?2F8X0);9WM]1S\@VK=2+`73Z/;UE -M&:=CBV]8L<_85SP'H6=@9$G=3_0JP4=[3\! -M43&A"6N3UTT<9M.`B8"]2=605C,_`P4T7M15D"'/374+'+,RI17A0"BY\4] -M!]&M*&4LWT>I@XKA'#0J9-C$[K'[H,XG2Q];X3SMQ-?9,O1PA$8DMJ$HZ(6` -MZHF-2HJC"<*2#/K6>'_YD3J=N\78C@8.OSB>8,0N:`$PK/2,JJ8A7F`1`0C4 -M@.=>T"2BMQY,"N!/;X"SA):+PY1=1N_D7*!F(^\9EA*"LH:@#<*K;#E^39T%K(%&%"NV0\W!T;O]J3?C]X58[RU7>QA -MFJ';0WO:@O;8R/+0*@A#QQ(ON!G]VZLWAX=[QLEIZ^;JPK#G-&VW24I["U:A -MC!MO=._;8Z@W$/F+Y]@P$ZBC:+B9T,_]:]41`A]T,.4R0,S-L35!4;)I:.^1 -M0=ER''`(<83>WIX:6ZANQKIVBQ;_EMYYKUH_VXLXU(4]\KW`FX3&2>^M#GO^ -MH4?$SW_^$,>XZ=W$7WS27]"B5O,6UYT^76$XQP[)E"@\ZGET-X -MV4V]E<^[YS__F/KH?)F;L#H`D9?$XY<82*S-J+B1D\B*!A@83&:+!;,Z6FTI -M;$+Y,!M@8H\W"8Z_[8!$MD.886C9ENM\CC'J;IF-UWK8;09O0QF24[QSUDQ_"!-/;EU`[E=Y`56030*P$LLAML3IX<$C.#4E%0@%L#AWB]:AWTF_2B[D/ -MA#8!\)8)BU(61XJF(`&BWUI@3=U0]9!)_X'$1][FN4FWSX_VO2W5>N%=FH&> -M`>WF1L8X#%Z,FT'(3*NUX.1+>K0`'`=@'CP,.60M+1?,`51R;Q!`-@/O9]CV7 -M5=\'FFTT/^H+2A'EN%B&4;\Q1O^"@"M -M('S"^;``3%K'R)^YY5"'F8FN6&#L-AH'LJ+,`,@`!$O/5;4SI+$.IGC`ECXH -M"#9T[.:?!>YF)'JCFDBZ`&DY$^Q2[.-=;"7``C6:1[+'I4\OD$-"0H=&!?Y5 -M;FB;FP^C@[P5O1"MN35'$VNX1)O*8!V!36KN<6!MV%6A6CT/=C"+<2ZRB(41 -MC=BJ+C3^P@`%*^D)+4=T2&Q2!Z%FL;.)^@3P*7-A#I$`S7K9!:K!;-Y383K7 -MIV%!AFI#$6A7"NF/E6"A0!T@>#7V&B*!W!V;(38+#;ZCJ+=8>Z*%RW.=;$T$ -MA0$3W833T1R/5=]HBA8)'F$)3VP?UKWT()OD*/+8RXRNI*C,R%8EMSJ*"1P; -M]FW$%@'W`\YNJI(:2FV((O[[`":WZ`6M$Y7FA](XN*>U(L9PY+F?+==&+TML -M_,BL-^\MGKC`P*P1>Y-Q/'FD4',X,C:S5==-,7$1!5N8MB!WL`@8U076\$%* -M750YP?Q^@MGP//L_Z)U]'DKY?XKW_PY?'70/H_V_`XK_>=DY_+K_]]_QYYTU -M-/9>[AC=O4[W*&=KSD#OS3-. -M6B.C>T`D.K%.V6_OM;N`2,ZM,4(E$2L*U7$2*:+)^-[JN&4?49\E!"ZD3B7VYIWTN5!N8@50_A -MX=&>HS`#H1)5C&P-U"J6I"'3]@C35+W:%UC1-F)4_%9T2 -M[)K`LN[C="25P+A]]\F(&:QQ]+>T"\(-!$WS1Y"=H-AP!W7V<[IRSTQTY9[J -ML(^+,3HH2[,L2>R\[[Q=X4]#C#0%T0^.4V@W4U!H&H1TN>4^LMYP:G=XYXVB;.D!C -M3SCON-A.5ZU"L,M"TE`$8^`R`PNL,VP;.YAP88KYBRO3L=3>FJ"WEUB!8F/% -MP\U88,=(%]BR&\@)&JV'=N,"!FA?$;A`1^6#Y]^S/@46JRM=^VC?D8XY4;M5 -MYA!:O-TD&A$WPT'#@J%WM.&:HS;*C>2J\20W+MZ>W$:N-R+549SN"M;7S%RB -MF:MS#^A)L944F1.BJ"2%.Q1'6C\$M'MAC7F#8S@*D%M!6X(=60(ID[*WT%?K -M[1+'!RR_15KAQ`9\VHVUJ+2]-]$T&GE3%PU6\KAI+EQT-K'?A=5D5.W)(<`4 -M(C8#1H.-*JKH(^B`4%7AHVO3IHTV%*"QDHM9;!*"T)POQ-)4#JZ3-WN)'M!F -M0[282.6"=V4Z__:<>XN_EX>,`.-0^5:0.W@W$0`A9F/*?WCLC=+A8S -M?=B3'\X_]';1Z:Y6NF/L[SP(C@G"WA?&(OD37-Q@>U+[^V1@R:HQWWHM -M"=Q8:IU"14;&U:WNFJ%;H$?.JHM -M*!/^=J>8X;%R"=D4B$-L2LATWG-36@H7$55-,)>Q<*0)?BBG@5P:(S`NGQ;( -MQ,1R(B('D@BZ9:45*"T]]A:+XCH2$N6_6--'+"U;4WN,?Y/%U&HMZ6F)3\S- -M7^OC=P-2>NC@XN>5"/,X&OU=P6TU50=X"K$4,`N9J;Y2,PD]@6!R"QR2[M;4 -M'#TEMP2(\ZAU<$K]#(59M(,+UJ80X<1_SVUW^]@$2]NC^R1#QPX-WO;O>N0'K%7E#.,.E87RV -M`^$]$(*"JO5232@8#S%GZ8,:>A:+)#'@+[&'SI(1U59X6K7A9@KA68D"!(W=L/#@T&H,UUO,AF$.VA/#2C(T<-_ -M8#KB/^S%@Y],:B^:#ASP0/YZ&&K=CT6,5ZVS6R'IE-\MODK(&'H5#>V<5&YT -M3(E9JJ1I0]6:"@C`3=A&6 -M_AH\""T0"@6N]/['#`3AO0/"]PE)8R")@%$Z.2B\0'BJ(9/PP^6"V$0@3&CJ -MB[TW&/[`T>N`P2'6W@0#?@I8-P./YH?AA#;PK&^(/INT+[!`5GZ3Y^ -M(7A>0!(>YPN/"RR"5RR>.TD`W"GE,$U3&1/]63OLP>2;`(R/>+(<49%_&EA+W#/ -MBV3384X7:G-?LPQ2@(?M-V^TV4B@>ZK[<$K<]M]?]Z_/A$^')!!6A)IUI&W3<>VR)`A28X.JW% -M5BF'`>H%='(+V$L6H$`_4H3M',0*VOTN#/?2I^O-C:B#3'>KP5E'1>@LK>%22:%[H^]F\O&!H62`=$1 -MA:-[2H23UWUL+D*L@&OA]C(4W\YHWM0*%P_?#MA%!0]3'Q^B8CE*#*=C*S`G -M5OC$>DJT$-#FBZFNP$W#`4N7[G93AFY`)9?D8.J^_+\:&Q1?9DU`9[1%A!O+ -M,5'_8Y[W;S&J#E::CY:3*+VO__O_A;7W%_1OMUDS4/SJ+$.AD<,F7,4<=$9J/PS(!K'2*+B)"49<#=N3 -ML@4YC'>`RV*`X@;4#PS#E+8^12TU-C*4*XIE0M9`&^)BEQ;K(R.EV2@4@2&- -M#8I1X-B6R*[#HL"VF(K&L^V.=25U4NH,A"35OL\6A9NP;\T:MY-A"HT-7\-% -M"8<,-EJ]XKP(QIC&(D5I3UYMAC8VA&XLPV*'N&D-+8`Y8RLKC\UQJ$(\.IUC -M4!H;O&%`[A4]""60\2>108\*O"BPS4H13X/7PND@7&N[\>7*GFCB:%G+-44H -M+C+UK9LY&>'Z+H0P?$8XMG:(>H2#A/+51R#L;!\`]XK!1>7HCZQ0= -MX:NI=&V-@;N\MR>@PMG0!ML/9RCIE%,N#GYAWSM>8/Q@_NJ:1V05Z5N6.(-A -M=#GXP>BCXP?JCJ%!P&Y(7\/H'S_FH"%[5H`R1XKY -M!,:#Y3B@-I+(XB!,UPN-)PLP.81M#/HVU;!LPPHZ>KL)]7^'>CD,-(>QS6'M -MT#Y&.0'L#]P-FC0V9,")0>VAV2HPQ`BJV=K_#):TD>1!:<)#3,G=PJ;VV:?3LQ]V>-]!G9,2CDCV:;Q) -MT3(C>YC"VI56#`)H2!N6I-92.]BGQY1>QI08/A>+O11*(LW%<4B*<)=(WUO0^I\M:`_56!TU,"B( -M=FS)$[U+>>0V7D,TN?3S7<#>6ZAI>B+`&K=CIH+ORCA%T.C*30SWAE3L#0PL:&_")$0'1F<&'YZC`>Z7F>;T]MY`QT/: -MGC_=12$5.P,@B,FS)$,?YCY9LVJ`=W=A)GGA+F[)[]ZCL^B+HZ=/:#'?XK/A -M].>4]HN)OQ[)\#,0\'CVMPVKY&GI.Q2"=G`X'T_%:.9:%OL:0]N(YUBX%3Y0 -M)>IIQ&#&>HXPRX`]LR];B)*1;P:P0I&08N&M11;O0Y((AEL""_/QR#@#Q=^7 -M9Z#&MD\1%(9%MK&QM;MU3(8P\L01*+D3D&1\?G7#,.90^Z5OZZ>>V.4,FKO- -MKE[T%(!PF-%NZ\2VG#$U"/H\V>@+T[\7J@AK*"*D@D.FK9#J88Y&2]H74G5` -M5QR`+>U@A@7BT8L(=7L3E!".NW`ID`0-GNW+C^?G3=$'1UAK?\FZ.[G6<`_0L3!8&8K" -M(:`P$C!-?-2K8`E8%!8EV196H.5Z+=1<)[8KCU`,,:<`,1.QDY2N)\RL>]#? -M:$N">2>[]I`9,?OC%N]W6T/\Y)]->30#1@CCFSAU!9T9-X; -MTR$MM()4KQUC@TG_1C:`X^DMR5CS*>YY:`&_L?%\"HX3F0+R6)D(]%%#Q?'K -M+=]HW8EX=9&M`"PGJ%$23D;W4)M:&*MOM);):2>:1.Y5=W%M"<=4'(0"A"Q<`I0R)`X]R%4XT@V$-=&Y0GL4V(9(IC'&8MC[&(W -M''2DOZ!Q9(ISPLQ!I!N#S[(V-F3AH-K".V"=:,A3^+LM=P>BFO9Q$@$OHW!W -M,':P0O;DB4/L1#(7RN;ADFTA65YC`Q<:6201/^28H*EM!(Q]\43V*`MMLNE;-C%@CSB9 -MXTWM$3ML&2<0!RU%.`EY/3FZ$&FQ'X-<\V+R=;+EUT&[/T6Z8K$F2"H(LBJ)O=BGJQIC;C\L%"IO(C\T51@W.QO@^]$;!8A+9 -M7BP1@TG#T^9]_,A>3-9R/YKXVK[%:[7KBL)IA^825F:':[9C4'0QUHYJ`DH$ -M,@E+QM)A;50X'58&?=+*M;LY&_LB='$SU$;5"EI_(PJ<8, -M60&'V8JPCMFG]%]8H24RU0D1:> -M)(YO&8,R,[+$'D_DZ41GV:98;YLQ102]`NH$Z2A:8**.Q]$:9XDD"L3TRV-A2)DN5&&+!G")7AI@G4F2/T`ULWD -M*:95H+,`9!X1X]@HTK#E^4EEF7?;;]IJ!!@3^Y&W)-C/1JJ]9N!OM]A(;WUI -M[B@W&XAT+0\*[L[C+C`E=VBUQ,[I#@AWNXF9@7)&B8/_/>!PX2U8M,>CA,SQO#\8$O:1^+<0-[@\)9=-*&$GTL*F"Y)64W,M1@)+@ -M'DS8/7EVDU/,/=AC=I"W$S@G.),M/D9B8\ZVN,-`F-64ZZ>A11=GU.M-HEH* -M+N+I+#3G?*`\[@V3]I;1,F$-_!W^.X?_)CNX-8&:/WI19>@_(K1L7F"VW/H2 -M!G^Z7J\3^UD*CD*%2,-()C;@(UDLVKY8OM>BP\,O-5YI2JFW#I0$/$WMP:F3CX6KHMVR/ -M,$`#-?#`V*0PWI'Q.\?S/FZR9U/N^S*M5]HX2VGZ[F -M2R-KJU"0QJ'70^LH=Q>R-^#0@>#0E%=L;@;W?,Q5EI)\A0<;UG)?&ER -M#K9:>$9FZ%BM1]0U>&ZI=^;(@<&.7'VWYGSIV,;MTH..L-RRNNSGU26:/N?F -M`OY:`HYK"_;)2@7N)E)>$K8T9RA(-/(CW$5&M8IG*^ZM"'8S7&+20#W2N+&Q -M"?)\BEE`0G1-;!J419A.QHD"Q"YZ5$.F)AD+B29II_,3&[\"K1NAX4GD$08+ -MT-Z>(W%TYB*[+6\)=!-+(![71&=<()//9&>#`<8YI9 -M@PH$9VELJ#AGJ"!N0.;R?(T1Q^&X7,GP45V/YHZP7(`*'=QI)U"O*"O(TM6S -M@)A+$>*/(DD<51Z"W>6Z(H225#BO`M`RHB6-*LYUX(4B#'&Q'#K"O8:$ -MM3,.AHC0Y8!^#!?A<.XMW"R9MM"EO:&?K<6J>8&E,,@HA%6*U?`>0",2"1\6 -MO@?,:PZJ2[S7W@GS,;BW%PLM^#Z>HPEM6.O11$&'EJ>*@(?I=O`>=1;AW]+\ -M+%3,RV0QTAVH3:'M?W_]OAF;/:*[P5B%#N93A*3L]PU,_6G'_?SH()#G/61< -MO$S)1W50JZDO=!H9_X680I^`I1^.9IP6123?0QYW;/1!K?06,O?`9^@4WF85 -MR7,#D5@%]Y=D)CVAS6'R0Y[*(A`E/94/XE-Y[V4TE7&+:$E6CJBLY+HA+T9, -M<)E`(EE&:1AEM.6.4/MY5^V#C>HN&)LP:%&J3MI/5LD^99AFDC8.WY?HK"^% -M70X(GT""?\&:\PGH[5\<4- -MJ(7<8F?=E=)OH@-M*N)$HB*PR0=3!EL@!Q=Y`Z"(\:+TA[6:] -MFU+$[W)T4C#&0"$AE\@%Y4C,5S[9$\&$2M,J>A.4V5) -M1]ED`U)]PF@K6(Y#-V\D5P\9B0R([:/S*D'1"9FNP)!SW(ET=,8>JJ@TVX -M`64YQ[G?:G5=@<>!&[2/\*\2:D,AM1MN/T'C+"H3">#?`HYC28Q*=+;7# -MV(X*,#-7NAXF&N(0**AU6+^VE),*TH71-FU?.67$\>27N:,V6%\S!*",&'4:?8; -M\Y>=I!;>V(AO(,1IROUC-*0T3ZF,\SWYX98VUMLJ)UVVM!-?=>MK4\-68P$B$NV;RXJ\OJ -M.%S6R3FT3S4570M/VZ'$6*B#@Y(LO+`B\%TX5TRQLJC$02'N -M -M%9VNWA5IYJ[%DD3+$D\+>Y2G<8,W_BFB5P2(,.Y,9&T1BH]&!=W2P"T:&[R] -MH,\&W`D$LT7$.Z(%A%9.+%!3Z&LHGU'+POQV]^:3DN;`B&":PDL9JL(UPPTV -M(HJ'MS`(E<-"1`BU3P(IH^T/?*H`"KYO"E,7(Y]I2X\V&S6#1D@A[!@K.OB$ -M5JG80R>?,^IY.+D"#[G4$_OV.9"`XE+19TK#HK28VWN,-,!U1=PLE@9$C/5> -MWK3OQ,"_N/Y+XASFRH?/N-.+9" -M:AL7A#NGXURW@"A`<<<+/,JU)5+BX]'W+6JS-M@\TS".G;*U6"`VA?[JTP%K -MD0Q?CX?$F6V.9B*`G9DU>L!<["-,DN+Y**-P+)5U:P<6RSJ0W/9BZ<0SZ<)L -MQ2D)RV-NHU8>^>;QQ%Z.`=*)^>8)4&D5TB44<1Q!JYOM,>WH_O0X'!WP]"@< -M>$3F9TL;)S4C^-RL/,,(>@E%$F#&>#Z_'T]QWP'TQ -MW(5XM#H"BT>OS='5K?%)E)#-8#LQ72\&=^;`^+J<+PG:3@<(8+[$YR<52HXC -MX8]C212(S!5!XDB/RF(13=#CQD:2]/(F>[SSJZUK1Q'GW""@@7):\;>09$'5:$_J63&_9C_+!SN@A= -MR2'`;`VN,^S&1Z(3T^`T_Z%^"4;<>*%=5.'=PWP*P!PNO5!Q;9(FB6Q]L>\RY"L(*3^"/T`\SEL.2S4+`?.TD -MNOL@8L.^I5:6+X=9Z#L4#(%\H(Q\@MMEZL#D!'8IUI1RYK`? -MPC.%\0C4G3S!.T&<4 -M]4K7,G0Q=!M+#*"9-7'%EZ9D5HR5EE@GJ]R7\7+CFJSPZV*>(#Y`F=Y)'*]MC0'$X@O2W5 -M;Z5I<`)@OH-/!2*`]C6ER@CFC<,'D<.+E9K@6.1\<)#J[B1`8XOU-FYA:JM& -M6&D[`N\;D27`F"YI)T/SK".ZR#2,=W[150;#S_*:'=YJDX<2A,RV\<(94'F@ -M3(Q=3/;-CY&G76U."I_GD3SD)A)OBF-%/'L\E;L](&;&7K5O`O.C$YT4$V!-F -M.VJ8;JFB,^TZ[=3$`UQ=DI?=!B;L?V?F`%M!-%\5Z9-J5IK=#B\283 -MSNDX]9@\]C):J/`>R0D?QC&@""\5)I@'"Q?+5/;G8T7F]='F00'XW1??F,M2]>/O-H;=C2Q0H"O8A(7A^M]_U3Y -M)&@MB/T(L8C038%OY6VE,+U%DC*UF\;<=T9FKF=,,)>$3S\I!]G"MS_#0I\F -M8U8S*OLR45D%R,'J#FZAJAA"L@2U:#4.BKR]"B2'5W$^MC7UC,UWCCFWK"8`I[/;4KM#T8\.NX@3MC)K#PFJO(8E`N,HN5- -M6K+,N>G?`VL542^R=MF&)M2NFZB=6DYO05,<1=Y1,7-)(AT9@[-/=S>]D[O! -M[=G)QYNSP>75Z=4=_)]7-@CC),#M3Q?G_M)*@3BO"O/#5Y%H(2*I)$I:!'V@:YQO$I%]E6>XC74 -MXQD),!7/2.X5G)4J*6T\';@Z.B`FK^RDZ[.;"ZJD?''UX^79S8Z>YA]*)C># -ME+:W'_N*YZ-1 -MT?V-,DF,8;Q-WK!!MW2@2P4:TYZV>6PWR5P'+*\-T,<<;N=/Y(O-6'!TNB&' -M\89$J)@S -M1!*$)H!V-E1GXJ`&S";$3A*7W]Q15[R+.V". -MY]V#XDJ$MF7NV]B@FI05CA)S??KT:;L9I>;BQZ'CF6%33,F][+C=/7,_/I)O -MD@,I^EJ.H.:!H\T\>:V=%"BT#XJY-RCE>2#/V9E\6Q*8<-')9K$?@O:OD&=T -MW[*X!BG0#A5$)WG%(:/8LF0W*A'@$O%R)8?&5(X0FS8B!RH95'(6M%%[ISW1 -MD=#$Z`32(RK8./Y0)LY?3Z29YL3E`1\9>XI\?LHI+X+(HV[4&BQV\G/VS?0V -M<6/8F)*7QY!R>F\OMIM:^BIULZ`(N8N._R4K$B5K9AC2(MA()&>>\$U%H>P\ -MLE03+48*T80O27C6V18]>-^.*20WWA#S4M^.["5=_Q0_<:ZN6I6>)+$KSG+Y -M,#9).^D("07V=CE?J`S[&+77WE>A6/W=*Y54G0,&#B0:>O6T.VS>@4VC>SAR -ML!)Y,E7@BUP9/,'1E%!WBO--W*3^8C9P -ML_">)GNDVWZI:4]QP*ME2#EO>F_[\JKM=&JAO6-#774K+IT55Y\-K1F>^/S& -MGHRMR1::!;`,U?D\N@6-G=[HLGFBH*.&=%VH`T!<;CM1,Y5>-6JJ'>?LN\*G -MB5KP=I-O_`)E`=4RWMM'.XF9M;I0EK>0LLKR47'"%&,MW(P5I^78;0)3=XI! -M3_:$1P??!19Q@'=JGV9JB`,^(DF[?LQ'S02/@M/I7B5A%+/K-2X(Q7T!\J(B -MD0A%3<9-7-B;T4H6SOIX/&9D!]!M`G3+@*@:V06\0&/W9F@1:F2G=63WT!1* -M.$^BK]AYK46&ULTA%G0<,975FV^X2R:6(^8B<8B@R$E`04'(0\2AF?X6NJE],JKO+6LAP_6@/Y8+%**4;Y!/W-!^!L8_ -MGI^>W7"IMQ\O+GHW_;-;X5UZD[?&$EX$$2!SF`S,RFBU2N:H1>5@U"Y=V-60 -M9I-%-KJI+H@BG["4+6,+O6TJHZ5P6AZJA,Y;X6)+ED.B^('N7@3F@R5O=[LQ^O1:Z7-K-9-DWEN=/39?2D>EI.$''&^%V\9%^B2:.JT4W>T^_ -MR,DAMH%1*@?L]TPDE95..[(=]M5P2F[,8WJD24'.7D8)$'G_6HB]'?9X8<'7 -MYJ,V\B(#$V83:%/Z-F9)+Q,[.S1Z8M2UNX"T6!5M"5S70V? -MXCJRS%/%97".*R1$X6D!+*$YH?\=`W@I)0TZ.92C5]0LRK8UL\`&Q83NR5:1 -MSD;.E-@&42QSDW8)J(35I*5$5]07R-0_4XT[ZV?PE4DHE] -MY*:8-95H>KR.Z;8;CEZ;N\L%V][MMOG,/>AHDI6N%N_H&STLM8>C/]F(7 -M_CL\R-AZ.37Q,#%EFC6,UOEN:\9+X5&<1X^OWQ@G>7F4:521@:(=-&/=SV.A -M([-]P(HF38"W"@V1J51^$RRJ\:0H&HZ:"2RD0UR7$8N7P`3K%C<#:+J7)M46#!.!X1],^^E>^_[P](+-X?VY5' -M#YZ_C.+['_?V.J!^JOL?#_>-O<[!P=[AOQB/SU^5])__X?<_=O>,$:I_WW7V -M,:/WP:M7G0:\,_5WW3>O&ONOC?/^6['QUN9[W?%`D(3J'!YT7S6ZKXU;@#C_ -MJ3VADYO?10;(_Z`U]7_2GW_'W<[!J\3Z[QX<=K_>__K?\>>; -MZ,@9J.-\AU,H;`@9A=EI=S#XG].11P?4V@T-V<#-0H$;!\2=)"VH">SO;T`+ -M7SSQ4;7MDR98W6\.6GA=*RD`(+HG(8IJXQTZEXC/[*`M2I@4QZC3EG>J!P+K -M6"4;S"($%#C=,D;X@':(\:A1E#FEQ%J0)W"70J\":G`&G!XJ]M_WS_MU/V.AW_;O+L]M;X]W5 -MC=$#_.O>S5W_Y.-Y[\:X_G@#MM(9-([_F//!`&?.8.P_X4GQ[XQ?0-7ZC?X& -MA0N^PH?O7.]8O*']YA^^_;W5`NI:6>*+"V_URG#@?`+."LR1_F8,IIX"T3^2 -MUYHK`@1A@(@D?ONCL;B?XC$^L"#@_8MM\;NII:+%[_]?/MA\,/9S6W_ZO+?VG^\V,8/ -M@]LSF)F]NZN;YJ;QIS\9HW%#W'0W"&:#T]Y=3]17OFMBDI'6W``1I4->WUR] -MOX%)D0;6H6Y/;OK7=UE`_##60^]C0@A7V$EF@VZ5A.=*_1-L(.! -M>CM``[K9N+RZN>B=#P0J@!XUKF_.XL]7MW>Q%P+GXV42*_$&\>*OR*4"=7Q].#@\:)F8*+@U-OT'V^W0&9$&7@=>"7!HN[(O;ZFE.)!GG\[./MT- -M.LWX<[?9H$@$'2&1LN'%-L,F,/=Q06[$7ATT&W=GMW>U:"0)?(./G#]MT"$V -M]HV60V(WM@=,"6P&P]G$;H\V-C9R0*/K6<3U;$7`$F2V40XS*H)1._!%I?)5 -M"N@EU,`:L3[HBC[8P-0](AEJ5,F\+PDB^Y(()=6AS%\)&ND/0")8"C[2;ISV -M8>:>7%U<7%W"\PVLL(LS,79*SQB,K470C#B36(BW8J($/G,8_X8<7VZ&W&,@OM'1V46="F%T9[TG8A7!1S'958!_]:U6!H=M*0:&KL+ZE -M<(+%M8+RTIT0DVBU*T#*,Y$Y<"`@N"6:,&@O1FID=(PH]R@($(*+KD?`K-D*+(Z6F$1PGE@^/AVM$,+-SR -M=[TXIGC9F-^+R8;G6M)JR[@A*J*T%LGPY(=X[0J7:!SE!U+.!"*U^3.NGX$Y -M_G7`%Q=^9W"OHS&T^.Z_6)]7K'<35'7<&]7FBB+Y82'*;P>]_>_%"*WCW]]\W_TOIS(0%X.(%J=!4+,$.6"!)NE@R -M4VWA"=+?_];^%JC)BLJ.GIN/@'.P1R]=;PAU%M1D-V!)U;IB]S__VOY/J/\O -MOWS[^U]W?X$_?]J%GDF1%D0I\(9M%$[3!.9)U"-TV[<5M0"Z)M4S.F4DH19` -MNB'-X_(RC5BYU&X>$R-1LO'[\>:6L6NTO_UE=_=?`_P!_^T>&\'.+]OXMKG[ -MGW_;_>NW+U[L_-+9V1+$8)W]^'W3V'I[]KY_"?8G!0W\YV9[\Z]0[\U-XP_U -M[L6++K[3'C;A?R]>=.1$L"?&]K_]FRL`9:NU,6U&)N%O?/\%H-,A?$GRV)#H -MQMYQO%RJRQ^"`/`*K!?TVS;.+UM<\],45.&=I`H__VK\L46#H@^)[,BM%R_^ -M]?*X^*]@]Q=WUX!9HPU`)IX"I.*6KFP[586O&>3EP'8^69BM+SC,!+$I6@2L0UV'E8;(+80#:RJU@0'D(-B -M-IN;,4-9Z(KCIEX4X4@4*$;:P]I`"ZX)2_$43(O3_DU3&;6;\;=#O'$0WP*[ -MCWV8FVXG`QY>[^R!]@ZEE>MA$V-O -MJ>&Z[$(3J*'94B"]]<^*%\1QF$X<[?;JX\T)?$1Y%[//E,D"`K4]PE9E?QO@ -M,0LSQ*S\V3"LN,S-J3T".ED`ODET.?2 -M`C!0QW2S2Y!9%_(P*9=(T5[:R%-?2BG'D9=!*=V$_')9"_SQ2T5PCJ-\5;U35>!E/?A\09L%/D1I7B#CLG!& -M9@&_S8+'!*UU$.C46BT,<0M5+1QG9M:"YYR(=3#\FH/AFP^UX,.:]!]KPA?- -M5;Y&+5NK$-_R&#)_)L:'%_AA#ID2T("LV$EV:7AI<6XU/]L^YA?*QJ0MCEQ4 -M;0.DR+#0P(HEN@Y8(K(TT#HR/3HK4B2O=:@B@9V`*Y38&FR)R&;(:AU@CL>" -MS9:0BP`'P\,#RRUD:6F4IT&%QND(A4(^!5XJX5,8Q>(]#5X+NEBPI\&+I'H* -MNE"DIZ#+Y'D*8;FL.[@%\IEA<8&)P\]5`8NE>`JZ@.NF8*O-10VA4+AF0@\P -M@W=UE#+1FD(HEI,I\(59QC(U8#RX41V:PO2J@W]^50M\ZBYKP1=)WQ1PM0F6 -M9]&PDV\@,]S&+&!]QSY;8&D0!1XD/72AU#)56_)Y39)[^9EBN@PY(U(AOTE: -M>`!%,N%V@3E?*$>DP^EN!F,O;,J/'(H@3H-34(=1,:K#\?(@TYV3#UL!(MT' -M:>"L7G`\[(8("#VM5V__%$=K\`!FHO-#LKBSYJ' -ML@0P[J(L`1:.Q3*H"L5*UV()&/L64'9P58<7 -M'J[J"(4",=/'50$ZUP!)>[(`A)TXRE733,2>1:X-`LS\V&ST+@8_#)PH4/4S -M/`Q>;/_0Y+@T>DQ^!)S3LW>]C^=W>+SL[=5M_^XG'7X/$%JM`(5+&+U%7U*B -MBIADE8B?]]_>75V=8Z2=J%`3*(3F]+N3$WXG(.C*EC)VIRJJ#4SQ9T\9_U&D]$I=_V3D\Y2#OU,5)!B>H(5.PW[;%%IZ.T@*Z,LU09[T9Q -M[V=7>C\)4E2L%<-XL8W]*]HNJQX-21Q1U%[AJ-KJI+7/\07>;3;2!1!(XG4$ -M]\]<7ZH.N2M+;QQ.*;HH"U7Z8%>?.:WH?79WT_=$ET2$4[W,1/,'@ZZQC\'2 -M":,J@%23O>J@0\Q:71V\3IWYUC%VS['"\/.*>,,OW14Q01M>%7-51&?E(IW5 -M$>?FRJC>BIB/-6HK=!!2&"LC3>F9,U55QV(%ILX2$!AO!TM,)%L;[V1%O+^L -MB'>^(M[/*^+5F%D"([*EZV+6F!T"8UP;8U(;@TWJNEAX95AM)*<^QDJ5J\L%-W3X/-U2_Y;`2!QRBED@;<>46CV:"PFE/DJ&`&J\ -M]D!ZO)8I05/D\6UD!M"32+:&%C1'0^!;<>H!?P;+81"*WR*"$G]J(9%9Z1J, -MS$P-,?O@0-H'$6@K@9%46/%;U,,IO/B(:I_3JI_^4>^!/`K4(9GHW#]Y>-1C -MF7C<@3&\N.Y]0!,EWF0YJ;2W"NJ?;*Y0%2I9*R]3UHJTA8N,%0F3:ZN\5'TO -ME[$BFS9!,L&(_%Y5P`SS(Q\8XTRJPM)FG'`@5D41VBV^_7D5I)294@TM9:-4 -M1%L)*V6=5$1;$2NI953%\U9!2\K8?*Q<>R0?):W.Y<,660:E6!]6PLJT"DJQ -MKE;"NEL)Z^-*6)]6PJH\ZZ3%4A<^V\(IQ;,>ZWO->'KKM2Z$P"3$2U76`O9!E\I6G61DFV"Y<,OZ*9=MW+[*1!E -M@-E+,5JT*E80CNW*LI13P]!),1?O@JB,QS=@8G1W591,,SH?/&W+%"BS&9_B -M\.>GM'M&"C;\2J6_(*"O"3`^?TV`\34!1NS[UP08]N>O"3"^)L#XF@"C%.-K -M`HS*\?M?$V"41NY_38!1`>-K`HRB2/ZO"3"^)L#XF@`C$^-K`HP?ID#H'YT@GQVB1VRHG0F*K(KO6(P0)X6";'LJR` -MF&6:Y:!A"]/:80XPL7QF3LS,:R&RK*B/N"I&Y3X7AF0%<"1>=:TKF[,:(%X\ -M(K>URG$T$5QS/%+">P7,E5&*AF0((U&X2CF4/\>>28%EJIHIJ&F64I2&RE)P -M4E!.1:AYVI.3`95AQZ2@YF9:-4X!@6S4=R>[19)2H`1\MS9%165Y$W(1L*R< -M#:T4#A('!7E,%_F40B^78RO3EDI!9MA0*9CBD>+@OVQ_BP:5N3.9^)Z[+:?! -M/8:X*:?TWWQ(9:$OW2)F-5E^*>H"M@245!N0C5K,J8JW1B,X%I>F[13K3N4" -M.=_?DP%3(IMQ3M9I;+2?!G-Z6D1960Q58#"\`10!T*WQ"DCD]*93Q`ZK;]8E -M$C12LH#;%&I7.F:>!Z<0 -M>A#84[?,'-#Q*K`J!B]PSV2#%LHJ'3!KTR,7LLHBBJ&@6\:<%(K7%/PPS_+, -M!1_\7!=A6*L%A/&E2)/(1)D6\=9,C!*](`>G4$O(Q"D4?"F,50;=&Q?I&RGP -MX+-_P.I:YKYF&6:)UI6/M$IIH\K3KP -M`Z]RWR`L<>8!WT]>`^W1\T&#K,I3`/)7S[&ML,82CG`P#+(VDE^5^48HPIZS -MBE2=!*;OUVL1P!=Z1=+@KO50NPCX_]S[7*<=7^"_25"CH*P-[ES(NFLJV\N? -M#8OZ8O5J9^V:YT$6.65TR&*;-`$IK)6:';("7PJ'57E26)E[A4YER,K2+:P* -M2!LN=7LA:U\D&[*Z]$*15;4:E6P2G,*AOW1'9EB^9E580PE<98(*,&\[/()G -M022.\>6#Z>-4I.N3+"SIH/BH%U&+0U8Q':.]G4I`TE0NJH0&7<%9HD,#]Y5[ -M^<6CJR'EA&QDPBXL?UZQYH$U*C:?=-@RW42'Y9,#U8!Q=Z*\OJ6!&7D()5[) -M&'!NC$4.?(DFG(+EMF(R_*I89:9Z'+@6;*%JFH`M]`'$8,M-^1AX;BA&#GRA -MM!&0E=$&^1`YP5M%(,/AIY7 -M9&!DXM3J)HE4039GXK$.7!6K3$=-`P_,8>`YR]`JVZ;-0!TY9E`L=/.1!K8[ -M+C;N,G`G$\>$*M*M*3@TC.^2H`"$[Z"@'H5A53H+6:V\-IHORL"YMG'EUE*>B6-(D+)+' -M'5&-_B"`"5XTO#4:@329T2?@PX[/)Z#DO*&/`>QC*0UJU)Z+D(9 -M26=6I93**[,B(3KX\AR$I!OF.6CAKNUST%DNGX5,,G=+;3*:?^@Y"*V_<)43 -MZCG(R+.XST$+PU6>AG;>@Y:N$7Z''0RTAJN2,E_ILF$ -M>Z//02=\IOH\/A.=5=:^B!M?#4T=/JZ+GDB26@U)GE>NBY>1=[6>[;^*Y9TZ -M^KP&@>=0C>/GG]?!7D6_S3HOO0:-%37VDR?:GX5*1CKA54BMJG#FG(Q?FPQNJ:U-A$[2KTV%M[O6)L.; -M8&N3$7OD:]-915?-/,&_.I&Z_JGTJ?X89CRG_&%\;^9U/'-]DG3T*;ZWDX#+ -MS6#_*GEIV>MD8VA7+EEL.KM]&49E[V`F-K4AZ\C]>E3HG/UJ)-9`+6(1)9BK -MMUJ\T4_[KTY%SP*P!I62_;T*%(IW^LH)E.TCE5/0LPRL2R6=JG@%(I258'4B -MY7M6Y31260R>CU2I`;DRR3*KL"+A[&P(:Q)-9TEX1H)%SJB*Y#BKPII$TJ?[ -MGX-@[-#_,Q!\;DIKSPV9S6%U,E&6AS5H%'OQJA+0LT*L3BLO6\2S4'RF"97* -M+O%\I%:94B(;17W$6):*E=$+S/93-9%7V5GB_? -MU:F`NZ+NGITMI3Z=9!:552G@6;HU<+.SKJQ#L&I\7@FMLIBX$O14]I;5Z91O -M"%6C4;R/4Y'&:@*\+#O,>A3+=G-J4=&RR:Q';PU1FLH^LQZ)E73-9+::M2FL -MP_2RL]L\`YUA7:]P+IGDE:*K$QH^2P_)[#G/1"IY&^GJE%:T/_*S\#P3K944 -MU_RL/<]`"\]S/@.91):?YZ*XHA5:DA7HF0B.UEZ.JWHM\[,+/0.MM5=AE(WH -M&>BL;+*FLQ>M3R.6U6A]4@*YO2VA3]C-NV -M5Z2STFY.?E:FYZ"ELC6M34S+XK0>K:+0YV5*,ALT2M1Z4H?KHJ -MA54VJY+9IM:FD,Q"M3[!YR(U7%>FA6M+1M0CP]GTGHG6LPQ;*OO>,]$36?G6I+:J#Z$TB]^SD)39_9Z3F,SZ -M]RPT13;`9Z$5RQ+X+!23V0/7)+K:^8:\;(-K4GH&SA,^8UW6U613V0R?@5#Q -M`:^*A%9S<>1D15R3T#,H!5$6Q6<@E,BNN"K%]4Y/E65CK$\Q.TNCHM-(("7/ -MH.5\3N.=GEV?79Z>79[TSZ(#;/K+0:?9Z%T,?AA#%]L_-/DP'3XE -M/@'\Z=F[WL?SN\$/9S=OKV[[=S]IT'L`/C&=P%)O.O#FB(MY?W:I48.G6%'X -MG/I<6!R"8(%_MD8SS]@T#"P`_VP:+_Y\K`%A';@*9J@5`=-,KP`\)C\6%@\0 -M5'KT2.5(A/[ER?G'4^KZ5K_=&%L+G#Q4PNV'L_-S/$$8>C"M_-'8]IN[PZ7M -MC'?-9>CA3<>[`IZ(PV^<,,%@;CX-+2`A7]#7^6=X`W^U)HV3JXOK_OD9%7)R -M@B5`;6[%O[%:X3O]-[3TY/KZW7GO_2W-9,!7C_Q5/8A?C?,[O;CS_MN[JZMS -M`?W#P`F;1JL5FM/O3D[XG8#0RXB_:K4PBO4[;#8T+M$$@J_5"KT)A)W9"JHL -M5#$:^9.3V+2`Q^3'PFD!$+%)";13DQ)@:*Z%EX_+FZMT[>.WZWF32N.A=WDJ8`3[` -MT/;N>O1J<3\5M]/CJV;CPUGO].R&P6UWY"S'UD"\:S;.[F!IP2<+%G30.!%/ -M(WZZ/;FZ1GXZ"D:@MN#*NSD[^7ASV__A;'#7NWE_1GJ`^(I='X:88,WQ_&`P -M7L[G3Z+?YU/W.\.WQM\94Q]^.?@X=);PES_]S@C"\7?<9S1ZB$Y#&WSG>@FJ -M:LHF"^*9_0[8/[>3YCD(A(NKRZ9\U";2W=DG''KZ#5K.34],G[$-E1&]?]T[ -M^;[W_JS9`KX"7=4'2@V4D#J,^,WSSK6 -MG',3,%)C7XU6^+2PC+'QKT8+??=&J[NW9[2L1VMDC&;`2XWEOST8O_UA;!UO -M"1J&\:<_&0CI3^*DY.???S=^,P+'LA;&RQS88^,/,7=AZAM'QU`Q:MC"HWVS -M1.MX(.*O!8/IW9Q\@#ER&^NC-MHGTR^-]S_WKP=GES^@)M(:0M\P3C2?$*&% -M/F0:CJ4KUATGH7;@%2D;J-IAO[5%9TV@JS"+&*LHQ8A__=+>_1U6E6]-[,?F[N];\&GJ0S>V/AM;N*(F'JU2^.O%BRVJ,YZL=ZO6 -MMW=R?G72.\=J_4:JV!_&[L<`F,ON:&GM+GP/#Q]KNGM2-9O;8`"X4^A,8'J& -M.7*\D>FT.NU.%Q8L]"H2?O$;_`"9[?_1R!*!`++7($C3;XC!DU)]("8_?.QT -MCV`>'@$H#I,9-'H?[ZY.KB[?/5?=Q6NBRQSJ&2GS06FB?='[_NP9*<_->TMT -M^(^H,YD/]XVWMZA/4_'0WBUUP"MD\D8K;.&5$'A#9@! -MN\O`WQ42`1O\.'>`Q$_OKWMW'P8_HE``/0@M"*)X^J$'LP*'N_]^\`%>7Z/@ -M_,YH0Y6"QNGY.->G5\'3'-.;-$X_7ER_[>-<:IR= -M?+@:8`M_&?'OZ.T=_7I_7U]Q9X^S3&;!L!'F7#?*ND?6^T;^\ -MO>N=G^OOQ?HW6B/Y=2"EZ&_BQ1]&:VX<'APH@.N;J_W+3O[[+ -M^08#?*VC2X5B$,Q`MX7Q"1JDU%+U'.?SO`6CUCIH=W%LD/?OPO.N??CZL&4N -M%H[5&IO^@^UV.KL`T^[L.N.&4)6Q\O,-L< -MG%U4+3%/$H8GK3)BI-!:FD#G_>LKNM-@`02A9OC;I5ZZRZK374FM'*^!ZQ[E -M_C.M?5SWR/Y1&^N_.T,AQDT[:EQ\#T63)R-!02J1P8R&?-RXO-!GI#N'%V>G -M?9Q#[MP:VV$#FP'+!EYXPU]!V5DTV#6#+QI7HD2/>HR>#@^H!D)]B5T*(5\. -MWG[$)7)U#7,8J`F-,$5SC(#9[5()5%\LE1&JTA\-1N%`:@+\I,00/VHL'#4M(3[@ -M4?RBMZ#_H!MQ,/;0P]6F=[0_(=%`%8GK):#7>J`2@3[Z`AZAKIL$MW33D(\` -MUX`>%VKH;\@:!ZR>_8$CT:#>@4^/KP\'AP=Q9ME%5LD0`].Q3=3+Q.-HL51( -MXI6'GS,P/UONV,/2B79#&XYV`\^/RJKA;]_S4/_]HZ$]T$=99=PFL1IC;Y2% -MM0OO=U_\EEA!0.RSK<`)\X^&U@\Z_<8,U/?"WD"`J#/H*=87]";=%?0ZT1.S -M<.XDZR4F1K+9=TIFS!MF$$+)YW_&Y0;JUE5E; -M_L00*'%2[?T,*XHM^C0RO&_,[^'G@%VR0GPT&Q[TIMY]NLK66(PGR;Y6P\]* -M!%:F(0]QAL`/`]S0H"R2R.%V'N%_C460I!+DK2[\T*#Y.LYL(\H*Q6K:C>`I -MP!%(0EGAJ!%B[*(VZQ17BV9P(\'IVHT8)VLK57YP=7T'/!J9/S3/LJ>N$2QQ -MH%LB/,#(W0XV\&C)8A9@]\A4DP("WCIG?# -MFQC1G&L[9L/U$#879#`A*.FP,1)N0^7(B5Q]B5?D1XO\/6\_]L]U7UYZMR<( -MVS,#",6>D8K^HG$'BLLM&N3]FRO0/2[ODC5+`6A5S/M&=4U_A![N.0_F4Z!U -M,+E'AEXX,Y@FO10DP,@T\#2T`;)ABRQK-*JWR&-P\N'LY'LAAS_>G`W4R+8L -MUQP"CQ/D]&>DV6"WT""RE7XD&^!'WNM3/UH4\FB'3U#INYEE8+8M`U/=&79@ -MP$2?6RXL`,-;0NV?P"Z;F$LG1$=B,+,7"]02-57(MT`D!E;0!F+]$"DLW8A& -M'!^#D^_;8&#]H->10P]]#`&\ -M')E!V/K[$MB`.PG'R[>$2 -M([P!+O*OH;'7V#BY`+7Y'&""=O@8;FQLP+MH*4XMMQW,M)=#T'BEKS7^A;PL -M]$I[ASJY_D)@\BM8YUBS#7X";B=^68_F'*17P$^QR:]Y!U/?R/^<`A`K0W^_ -MD7)J9V'1FLE$BSSHNK.2!^&,YH._1!<33%R#>F6Y@&^T2,[/>I?2+9JY)8P\ -M@-N=X!2B;U+\@HL]C^8V.U:"'2/PEO[(VC&`O[<1J)'P-L>9E.285(KZ7%^2/]KO9 -MS1:I,'-+H,^E!8!*9L/**.C8O`)$MQ=]U6[)*Z22R&13`DO*4TG!Y#S-4SEHSMVT,T&A\8[1<4^=3VA3LUUY.$6D8I$/K4[`E3*W25F>$L*(>BM!!E -M4.0K*ZT975A3`$4NEY+OG`:D#$B?^OEU)[VP@!1K?V4`I35*K\9TE8A)O]Q( -M$XE^OEP -MHOOU.]Z*FB/`]15>W6]`U1%8M) -M7P15`U%AU$4)JN.(.\$JP$>7?U4!%LZ["FLT?9]7>1?EW=M5"[/FL*3NX:K0 -M#1F&5"Z.N%BKD,''[M`JZES]MJP*<'0O5A4XLAK+X9S*<'.S&IQ7B1[>5%4! -M+'TG5<%8YEP^51U#NV4J?_2S;I,J+T+==5&AT>BG*HCYD]G5'!0U/WFM41#PRQ"M!9=]5E+^6"F(FBG%4M$)9K5*W#)5U3-SM7@W8 -MJ05F[?:H5H_.U8GC=75[:^LA;7A&4-J*KP\:65B4< -M=:=.'82A7:A\Y-R24Q=C6*\5\MZ;NCC3+[51A'91$XRKQJ -MIDX9B3ME:I04W1VS"M(JI8VJ3SII\54"CM_N4JU2\A:7.D5(Y;0R@E+R*J'P -M!2PU@&,WK51KMGZC2O62M*M3*A>C7Y%2%\DO-"G+[CRI7)JXVZ1Z47R)22UX -M>5M)G4JI6TDJ(VFWCU3#H4BDBG(L=I](Q<:+'=EJP/*&D(K@?@UYS0Z@:K!E -M)F_)11[5.C[!JJKA#(LMM>0=')5AG1JP)=9BX@:-JJ")NS*J]>%CC8&JHP?& -M[KDH&YN*1DW\ZHHRHBHZK91NC&9%4!79E(\0NV"BB'+\,H!B_39]J4!5 -MX`I>@NQK`JHBE$BG=.;_O=]4\R\RXDJW9^FA6UJD%E9??0BL+/ -M`\H/\-U_C<;Q'.#'E-9J\3#^KU1USV]^[E]_=WG%V3=2M2H(`:3NEPD&\D9& -M!E3A^E@N"Z.J1+'I0(7P,6S_3-AYN/J&_:#31M.>"JL$WZT,3X*_TR:-I`H\ -MN2L[4=O+P'$:`_BT6FT(O%L9W!'4G1K@W1K@<[,6=0"O27V_!KBW$/T./ZNC -M=.NC[-="F9NC%M?KY\KPW1KPZ8B+"+<$-1EX(2=M1;0H^@(Z'A<\%5H?N5L9 -M68_AT!99"=;C%X1]_%+"C*(P#0!'@5JE]WG%U('>KP5]4`OZ92WHPUK0K]J/ -MBZ`8&N,^H.]P2^3GDL[F$!%S6`7,^3(K`=CU -ML.,C5`^71D@U>17<[LJXW37*[:Y0[DKS8J5UL^)<6'6IC2T'HQ=76FP1;OWZ -M\L:R`*P['-&N=.UR5VMI?+K6Q5NMAU;#PKQ?M9'X%+$]XD/RU0<#)%&9,9T, -M%NQ$JF55E&Y]E/WZ*$I)'2W>[*LB*V'KP8/2&5$942OW]>&A(E`?WUJ.?EVL -M@7_OV:_]-?"7X>3U8*T:$`5_69]"(D`0_ZN-K@+^:F#'@O+$`"H3OSX!'L$U -M"/`0UB<@706#SKXTS5;`?;4.+A_AW-L3-/(MD'(:G?5I=)ZA'IV]P1RLW8EM -MC>L00Q-=,],KH@"37`&)PPHUS'J(E%;%\K7ZUL2GP,E5D7UO=._;XZE5GT(L -MJ+0V=D;!]7$QR'+UDG&'?!UT%7TI:50E(>-JZ[=<[#;70]3#,H5@%BZGJMA\ -M2'9/>:KJX756Q.NNB+=?&\^916VK@72X"M*K^D@/=CC[%;.NUVD7AQKPWY5+ -MDUORG&NOKV]/>EO7(-$=WT2^^N3.*A)PO4L -M;U)[^"FI-(V`MI];K^!@\MBV'FNL2T):#FG(:U=XZ=H4(E<73^:PJ8?WT*9% -M54.)4CB5,3*"ZFMHS>MJ^XFHXA4LEF1<W@+$X@$N.#(AHXDR4%.W_61"W9SU3B_.Q-4R)]Y\ -M[KD&2E3*_Q@!&Q/?<\$:'@?&-KK$=O!VJV8\J]DD<5-,K#3XNFOY&8&4\L,L -MZX-C3O2K,+(@\-X7GVRC5*QB\ONLD:YNI0A#D=U-7&LE+]L9>Z-`NW)'7#(4 -MM1]O]>&7[9'^,-,>$O=\X(?HLAMZ@KJ'%%-IA>(5MD;\!+TI$/ES\5&DY,:? -M,L=V+(UHMREK>7IV?79Y>G9YDG&=6OKFM&\$ED-WS]DCNKDQ]:K%OQ3T:)2" -MUEYEQ%U**!E:65RK1.2EP%TM8C1&.[IC35:WF1D1JFH;7=>5Z!0%DPS+U&9# -MAR:M-B-B*1@SWH_D^W2^19HPB1RT#34>6K[41OJ57B6%(G,E:BC:*W[3T-8& -M!:%&:X&X5R+/(;W+3F2HKL'2,AC&WN-?(B=AZOU@3V"D/D3G^#(^TA9LSC=6 -MP]6YABP(3HU":O?/%6#$`=\2*(PUJ0!5!LPK4.AG -M\GQ/!L3,3\IQQ%5)_+Z92,N6"XL]+F`C+ -MTHF@GWG,A\IE'^)[WN>%&6(VY[R:TFTGM.4P=M9)59 -M[&==9*K7/4/32+Z/J1AYM^!J^%G?WMZ>WO5NM!,WJK[:F1O&?[%]]ND,%+>F -M0*IZ8D>V.]:,+`60QE/<#9PG+2._5S$(*A:\?YP/PR&L)3!?RLMR*M"ADQ]& -M&<1+]IDJI'W7"-V9C[355`?2.3T!)69O*= -M;F;2MX2=F7R78V@26-K2%+9EO*XI2Y.0G\W4C-4XU]84%8X9F[&^B:"2W(9& -M37P4!FFX\CDW.>1`1JO;40M(2*2[^0EX_H2 -MT.S1Z";GZ@9I?%ULQ%[3`HRGVH_>XU]1\OSX>]U037Q)6*J)K[&*I#]+^XH: -M^G,E*&F.EH!)>[0,K!*44XV84Q$JLDF+X;PJ8(]YA6:9I0F0*:]B.G25!R/D -MRU[)][<)"R\;*FGE9D/]I1)4TL[-AOJY$I19\CUE7&:#Y7:T^#XN^3XI^1XW -M.;-A(E]#+HA3]KU",3%C,@_$*Z,R+_E>-BN79=^7588M9KGD0FD&7#;`4\GW -M?'R\U6*@DDAD@2S,(`AGOK>Q0!_,B?$"\%:YKS1:-]^?/>N_^GL]DC[:8#I -MVW8\HXW_'_[:,.>M%O2G;P6S(P,K@*Z$QL:?CQHOMB5+EJ_;MGMD&!GOS;DA -M;&6NW=*W!F-K$32!$&ZWPV^\XNW%?QR#R8YC91@C,[",K4RD+80E(,/X]L4+ -M>/=M4SX;AC6:><:603Q05,3XTY^P$S[>77&'M/#6.LN>NEO'$9XH:MRL@(=8 -M&_#1>K1#8T\C0B\ZQ^*-%9@C^CGV7(M^Z)73&'1^0;(+N:9Z'1/H5&`QC4;[ -M^N;LI'_U\58;2?GC*&O<<$R2RP"&3XS3?T2#\FT,)!H:T?87V['C/"8_(@?/Q-N9::N*,R*D3KMK1S!K=RY)3I(]RUV3A -M4L#J-(%F[^3\ZJ1W/K@X:"I*_Q][[]HDN7&E:7YN_HH<;EF3;%.1DD8FV8C# -MM9&*[";9)5&F)GNX[$LH,B.R*EC(0!*!8$55L__[!N[N@#MP;@#\0MN>%2L# -M?N!^_/CSOKAO[Y+T;IML'GXS':IJ_D'WGYL__*FV:N9@OW_GG89MO[\I7YKY -M].6OKA5XN*\^;_@_;I[>7Z?BX^)+D<>;[*'X9[/9QS?[Y%JGO__XYOY@;6+C -MI3'(.\U?U873]`^RW\$(M4,?_[9'S[][*\? -M7&>OW\<\/=^]O";LG7>*+W$6W_\[/GVYRWY_=>G5IDT7NC:C'ZS\_7B6>HMB -M--1UT.@<7@=2GXU[>HU5GNG\ZQ_^^D6A@N5G*3?*GPJI>O+^GZ^'%-=*_>+/ -MU]5XC7C]6^&//WEON/D5)F6)/3W>O-M^V?/=FY]^NBE;?%S=)';*?WW]ST(" -M*P%\4ORI$\&F3HLJ??)8EVG-J*KQNU637Q>_O]O(3ENENOA4H=[>-&W*WOQ7 -MW:8@Z;O%$OCG3[_XZ^8O'Q3:^^GUF.+ZKP_:_K_7[$+9[EW#=F7D6@M[\>MO -M(M>KK/Y7O=#:7^M_/WU:?`KJDWJ.KC\W>>_^\XK%OW[QETW1X(.;)A<375^B -M"\:LE#WX[W?>.1\M9:?6V#=_%JHR:W55(*BNW)9KA3U3[;S#28&1.BK6=WIT^^9LI]V6" -MR^5<=.WFI\X]GO:[F_=./_WGO_WG1_]Q-;8_??C3QS>GGSYJ_EG^Z_J_'YW2 -M32&-Y1<$?WI/BY!FU^&<_S98[]?>#)9[/;8G_U7\^M_UC!C^^-]-^HYID7A[ -M!JO?[4DT_*[DT?!K@*E4;D.N/>,A*\7R@VKUMUQ5;L*]'FW=_+\W]I9ZT*M# -M+)8".'S7Q+0C2S1UE\T)M.)M?$GZ^Y&.]A[S1D4OS>RF>H9QQKW4EYIFW$/U -M:>/Y=E!]:G'F^-7+>`H?-?N>]$\HSKVW^C7,L^]FBS^7XFN<,^ZE -M^<3W?'MX*+_$/5_\YG._\^VA^Y[XC/MX?-C];L;XV>VL'[=[KC;9KOF$S@+C+*Y8#/S$)MO -M^2ZRFZ9`EMA1>;_S$CNKW]8_\Z[43[;/O:OZT86= -M7MXNNM/N[:`K['9I.6C?9KK\3F^+DPR[95=M^]+3-?9:WD&T^&ZKCRHMO]_F -MXW'+[[GX^O'R>ZV>IEY^O]DJB[=X_=/R>\U7&>MEE;W.KS_5!ZYF/-ZIOZ!U -M*I_XNI]Q1^7K0>8+_^,AR\_;.?=0O=1DYOC5"9=YK^*HGRB>^1R2]H'CI4\B -M*=\3G/7TCKJ?><_O]/8T\PF>X?<8Y][7=M=^(7VY72G/!"U1C^J.WVS:*5QR -MMPN<6!KL=*&S2H/]+G%*:;C3%?:YQ,FDX4[G/Y,TV.<"IY$&^USF'-)@M^U3 -M;POOMSZ;,^?>"CM0N>@%=[7$&:/!/K?SBYFRMR4U1=GM`B=.C/NLGHI>>,?+ -MG#89[':)LQ>#G19?6%UXE\6WX9?>9_60VL([K;X$O_!.7QS/*^QU_O,S@UTN -MB?KYKDO7BGP=T_Q'Z\I=A;!CM#W_:_.OFV;/G -MGW[0C_?\BS__\P'^*5RU]^FG]S,*_J.,J7L;<&[7U7NSK -MMH.;L`WM!]&Q]WQKK2Q[G)ZQZC73RK^NB7A:O-):KPW#`/3R8.U/?<_U$+F2 -M^QX6Z/U(3=S#RM2T6;]2J]K$[KI?D'XU_^^M4__?4/?RJ?^HA-VU;_=FCZT^[X;-'[0-LQ^:ILW?5I]@FGCJK8TX^=:;N6WGJK'[^S?K@ -MR+5'C_5S<]WC(]6#(Q^U+]AX\N2CC^KG0EZ_/"3[FZ+4KO$>?U4&TI_0*SJ@ -M_+-Y^*T<<+O+Z^ZT_QX^K=?UY.G^YKW'CT^_^/`?/OK%+SX^?OSRO?)/IY\^ -M_(>?/OSIO2K\3;W9I=VPU_^/G[R?9]OCJ3`G'Q0_/NE^;P97COO/'Q?_W^D7 -M_W[\Q<_^W=#]_]CYM/;MXMDG== -M+LV_?W7SWU6G_NMF]\F3)__SXR)#[Y=;[/[CYG]<-_C@^E-YP>?FW=V[O[C9 -MU>UW6NORT87U:;_W>SBNMZ*P5R+X_U=41UEU`_4QKM?=+OZ[V$-Y&\>]T7? -MJXVZQ^JZQS:O,WS]_=UKES^LJ_[ZST_J*2_^\Z-R@W;NB[;*DT9E7/51(V7! -M-,\>UJNQ>)?,![2GZ0:/-C8QBX<9RRX8%V79\W9EWBS=)=/ZK[/=0.!)\3J) -MNG?EG%?+7'W\4D7AY+.7:/B5/1UY<.W=/GNJQ]:*Q?SRN@C_K#:QV!VPS]LGLGQ;LW[Q=O/3#BMWB&NGR6[=TN_?7#K-_/`>O6'02$H$U:GJ!^W[`YTPHQ*\3=X_YJ4E`^VF9)2 -M/?$675K*%]Z,&]GR=9>5:S5MW82`N6)]8SVLS1>J;^I\VCPS^.3]PHY=A_Q[ -M8Z_*]8()6YS6G"%F>P3'C]U_&]GOE9>S*M;4]%KS5FWR-W=X9"FW>'O1<,K[/?XO6)Z^RY>"7C2GM> -M:\?):D-.UMOQPW:U7:VQ>(+[T?I^M -MM-\O5]KO\Y7V^]U*^UV0C(.7Q2^]YP7IU+[1?ND]WB^^Q^I>T*7W6K['?^F= -M)LOO<97D+NN8U.\A++W3A\7WN+Q9.2^_Q_-*A&\^5;'T?I=TV^WG-);>XY)C -M5#[YL=A.#1\1667?S7=)1'>N[M)X5KOLAN'4YOU!]L_"[W-FI/.PVWK]L#SV>JV6DSK&>SV$]Q/ZR]Q*[-JZ$YYEAH: -MT7"ZD!U2_3:]8-SR'66"\4[GVY-H!\L':07C5<^U"@;L?3*>&[GW0=2:!,4> -M]'57_,6Z^H<_JNM>C6^XME4T5A:^>=?V"UO*IUCGO1[4?IISF@W%9@H63*W4 -M<'#HZ`V&NYCLNYJM_K4:6U>;(J+LH\SL+Q?9R^`:S6Q[*N[A7F1'Y9M+ZB=3 -M^@5MVR=OA_6IX^*O@\M`\^_2<`5H_IT:+OXLL-,5]FFXY+/`3E?9Y_"TQ1)[ -M'5SCF7^GPP/.>?8YY^J8SG8Y -M;YZ]/6[S?)\=%ZJ:\B''39(>7Q2/NR^SSU.^TY]GL>Z&>\Q:?=&PN.Z/ -M^4(Y/;UY*+]4==UVF1T:KN+/EE++]13&OI1=F"ZOE'L=7N@H_SQZH<6P1>]J -M"_@BZU0_>E==E-==*,_BESEL_E&\6[57&[(OZK#M6/UXWCH=,#^SL=#.JT_N -MK;+OZFM\Z^U:^5#?BIW0O^&W8D=.QKME%NW!RE/1?!1PQ2Y4WPM#YCW]:_=@W?K4W^V_F1\:K>2MVQZG>&*^/K=@=P[6L]7I3?F?`F=XT -M7R!PID/%QRV=ZGT97AQ9HR_*]PZYW)Z;;YFNLO/!XZ`+[WK3?@%U[3ZL>)IX -MXKNI*_9IU=.T_2^MNM")]4[4#K_/NF(WE$^W.M$+^V,2:_6G_C"?([U9[[RQ -M_=.P;G1GQ3/&Y@_)NM&5%<\5FS\[ZT97UCM+;/U(K1N]L=V8OE)WUCHK._C: -MK1.]6/'$L.G[N&YTQ`&%[G]1UYVN&!^L7ZD_JY[SM'R6UXV^%%_K=:,GY4=\ -MW>A*]6U?-_I2??+7C;[47P)VHS.KG7,U?C=XY9ZL.7; -M-`U/72U8$:ON?/A5X]7J<;X.E$^152_6ZW>@^VGP,&'7R+!?[5?`P$U/\%F_ -M&EQN/?A:L#&&81^6WHSOK6MGW2]TE/T4]U_PUYLVV[.- -M)9O[JZ.\/>TJ#/]JS%RNT*GC_>DW;O3(G9Z,^^XE.^),Q=1_V3X>-O?[;7[. -M'.I4\='/;+//LG3,="[=J`VP#U[7[M_XK8QK]*ZHOK'K -MZVOTJ3S'51U45R>87.Q?=0[.V?XYWC'7(%+?R^I.KXI4.>;[)^^S7:4_F[OT -M:/E&U7I=4\[5N\FQP<4$=SOH>L\<0-GME6`N>-SJT\&3]^PMVYN)^Q.6[O/A]M4Z=S[O]Q+VA -MRW9H].[09;OB!*^KSWI-/0JV5&E53O-L6YQEW`[OL5NS -M?_#WE2[9M>EW="[9FR(QY=-OE\,IW[L@^4VW(`]QKM"EJ0.X?[5:]`CT"NT",7SF&K_1E_ -M"]PZ'7+(@FH]*QZ1W-Z[<$EDT*W;E>^QM_9J^`%W1_IUZV)UE1T;?G[>D9X- -M/Q?O2,?;N^;P[F[SZ[ZUKQQ6!7^Y8Y=@*CZUE] -M*_/>@6MZO0YFF9/5=NV6"P^@#7MUW+]V-6'7_WM(?W2PQMY>_]_]R;VTC7\K -M8)T..6H5I]XRMD*7BDOPSI74^"<65NF0`\\FJAURXE;Y7H?J&P[=7'KN'C_F -MMXX=.^:N'#@Y<=%)I[<"] -M6N7):S=6O*YD#N1&[Y!#=TUWKQIUJ2_-\P@.S)S2*7<>YE,[=7]J/^/BA)0H -M?9O\9M;R77K<9P]N5=5I?^?$;:-JEQRYUJ=VZ*N>,[6$^/;6*OUR -MXPT:6I\`7[]:HUMNW)0SZ%)5[D4$QSKGR-,=>I]<[)(+]Y7TNN3"0S!:EYQY -MR$3K%>"+7FMTRX43JG6'7'JP1.N2"^[6Y35,'[A$T=LW%!=GTS9T+'<;N57?].-8Y1^YC -M&?9IL[T]I-L=T -M<]H_;K-M[L*;B0T=_.&$Y_?T7I4?/[22>URSQKE[F;*L7/02L>F -MOFFZ5K^FOF^Z1K^GXP!8U?O5EKXAHNS&D_<_^_:S:E=/WN_]MBEZ\>SK?_G`\-,U_&=_ -M_O2S/S_[XK/R]VN(O_YA,[[5.W_W?[*'FZ?W-[8^O/-W3][_PY\V_[IY]NSY -MIQ\\>?_Y%W_^9]/.1_KU_-,_?/II\LJ3-\4']XY/B_F_ -MYOKW[_S=TZH?_]!ENOU;<5;I(^L/97)-ORH3,/ESDIK^#@B]N9^*7FVA[.`J -MA\8FQ=^M>RPS67U!5OWYG=WAE%M3F6]O/[Q[YYW#\2XY[_95NKHRO#WMBK\\ -M;;XR^)=TTM':E)^*Q30HD_A+?)/JOCIT,\J8 -MRH;U:_VJTZG?,=L7S^/P(KS(WG(C<`,D["XD_``/6W:(X?+!1;@01E'[D_)R -M`;KQB_+?U8O(\:VK[[90EES=\H^;\^/C/B.W?\9L_R6S_7-F^^^8[0D56[?L -M;MBA1B!46]UR1VYY3VY9O1Z4VOKE/J$W3N@M69VF$:UMG-+W_$!N28?0F=[R -MS%P)S5?3J.TIU*^;OB&WI.RS^.[QICI!AF[\N#V=\I=9>G[Q]>[N]>;1ZV+PI?"&[4^$%P@^ISV^#MJ\]B -MX#:_:OOCF\WMR_L#J>'U$#;'-M0_-(!L7)]_Q;8B=+/YK@>RV:7X!@>\4?,) -M!&W1?P88W>7S8_0Z^>7:+V':_W>&VKMZU?SCF:?&]!F13 -MTZO>"2&*!^@NE(;%.;%KK1YWVVS7/*9`"-,>?*.:-F^3Q[5JOHQ!:85/K_[- -M"4+;^CPHKJ7Z#4IDR^ISM\V=B=L$(3*F`-7]ZJP0[>WEK"BU7V:%8$=(^)VH -M?"PG0O'%`UZ$YN9>5I#BE92L`.!L4*4-U;Q@J1<8NB>-T/*T#.[<&% -M&P"U,NNOER.WOQK[Z__D]_!VQ=40^-8_'K+\O$4T0'NHZMN(N,TWVUW[%@%R -M2_5<'3W&FPW.4@TCX*S)H#W>EPQ"($W)L#VO.=*.#-NCO,B@.BC!P"8R*41UY1)V_4QZYQ!VK:X]&,(S4E#@TS^*,NM1GJL*O7D`()TH%7 -MU;1(O[J&DMT<9P$%KXNH!GS"IT7_=&QC(:A,P0?NW>S7_ -M*,6#V%:[$$"-,;Q/!->^ODQ`;%Y?->"T5B\B\.-4)^M9<7J7&%BQ3H,+6I0@ -M_#&UUR-84>K+$\08[=4*8OOZP@*Q=4L48GOET@8U0G6E@]BZN/!!;5I>!V$T -M[ET6844R7B5A1ZS1SXYC=.;LJ(;[&?&1VBLLG""M]><'84]<[["`':HY2.`$ -MTKP'*Y#AVHU@O/I\B6#$[@R*8-#!C5'\B-(!![=!\2/V[FYB!ZS.S0@&;,_6 -M",8L+R$)QCN?19U+,%Y]LD0P8B9Z[[KJ_-<5IKE^J$`IGOLF>&;$XXBP5D^=21RWQ2$7D.U7(1 -M4"H:SYM:+A%*16.Y4OL%1*F`IAOO>1$9%K)_M9$?AG?"8^I:)#^L"'39IRL& -M%RYEX@@P4N*,Q?`JIU`@WN&-\1JH5"P9A1I<(96,-GA:DA>RN7XJ%8][#&*[ -MNBH5KKS8*A6LNO8J%:V^%"L5KKXR*Q6.<]AAOF[+#D8]E6JXJLN(,*Y%O0?# -M^H'Z+PJ`MP2>F9Z(4CZ;=C4-F_OK*KL][3;'^]-OA$*5J?V5;>U"HPETR+[F -MP1'X0ZG_LGT\;.[WV[SX@`4_6O%^C6RSS[+4MCA1T4:O]J,BC5WWQP0:OZJ+ -MB51>7:V>`Q6+5KY\4RI8\;$`@6!35Y(QL4K&W"7IZ?KCZ\.=1/?Z(2=,N$#H -M<4>-WL'#.;E];_VV>CY859@^PE.=-@B -MP[83,.A@I3^HA+52=M'`E?&0#SQ71+&:JD_W"H0K.B>E-:-GCO&!-G?IT?`N -M`V),Q:\*U^/`"<\0>;:0G)*\+3Z[RJ%\]:*?T5.^B#`CQ^6(*"_L1UB8*/:C -M(4241"C*@^UZ'RJ*]50P(LK#UG:>`Q&D^(BM\ONO.4<"=J -MSZRRPW!F:NJ*`RH&\]BH@*#D9'4W!%"?N]4`OO:[9/-L6 -M3G.;<.P0]FYE<,SQ^WC!88JNE-=@+X=3OF!QI@LXS^(.,>B*;X.*!CN]&/VF^ITQ1E-<#6^4+X3)!/Q<$K%YK:(53JGPL5*F,XN["7-LNO_RD7\ -M/DT.^UQ0(KJ82R/M^^YQS*]B)GF6Q&K_%85RV'X8[[U^)= -MO/[?0_JC9!ZKKVD*=M3^&`@ADC1SQVX1P\8JSF?(IBK1J)=\VB -M%ZD^FRH\H3/H=2P4J[V:4GD7[38C82'+N6?TJ%S>D -MR#G/`F%Y=C[>;7.^IA1WOC$O)Y=QQ#K4!AI_X@D2KS+"PV\H(<.H=\T\=J+.ZQJ1KKS8/5>,%FSB,4AT/.:9JD&L -M:BZ*#U1*1>5>2M*#B<9BG?KIQ6)=X])B\2]%:>$FGJ9$QV.Y8>W3N4J-%I!W=EZ+-_K,&SK:^!-OU'";VS3EG``UQA2= -MYB:HP+&/,6YU#DLJ*O<&XXYU< -M-\2^OT^V+V0GJ_AD^6E_]8/;G'7'N2'R#^>T/H`4K5S>+8\[2D@&-/U*(#\DYE]4/)SH>@Z2G\NG3?"C)('ES+/$5;Q2JZ -M5SPQH?1O<[H"C%/9ZAG&B5,ZQ2?=C='N]YMD^W2?V=ZV/=&P>"ZT//_6^QI( -M\67XKMGM:7?]P]/J?]0.CFQF>G[:N+GAZ53S=M=NEI\)O4[#Y,;]E]<:-SJ= -M;T_3H?IOH3)N-+CMO-BJ5P-U7LKY[S\?/K%Y62Z_Q#88G`"%-"K>AXUM4UTL -M&E@Q4-/Z6^/%7[_C-.Y=W,,V[WUQ'MV#;IYSF%W3G:\'H -M'XE"FO8_F@UI8_^N.Z+UYZS6AF^Z(UI_Q6K]-:OU-ZS6W[):HZNZ^0X]M9WI -M["^B_?Y2-B&V?G'8;5[TCWHP[?OG2A%MOR>V>T5MM]\_%NM_7UW`&G@,8)C! -MZ6%,6P(U+=^Q1S1%>X:F79FK_.66'"#=G1^HO4Z3'6_O/Q#;4 -M&6O0=+XM>RW`+23M\AK)GY -M+H*FZ3L?WGV8_OZ=OWOR_A_^M/G7S;-G'^SVC]<#D/TG?]O?O4QOGOR?FY]N -M3OO=S7NGG_[M/S_ZCW]X\N2G+O;?__3QZ:=__S"]_O&G]_[V\;\7<9Y]]:>_ -M?/'\LP]NGO[IZZ+YTS]]>OU_?[G^OW^\>?*DCO[AUX_IS=.[FZ?E'I[\[YN_ -M__NR\?9ALWGX\8/>AMV_KCW^?Y2^GM)S=K?_Y+TG__N]F^K5+]?__C_O%9HFGQS3FW^_-JBZ^TG;[YMK+Y]=__M/7WWZ6?&/:_2BT#XH-VZC7^'Y@3J< -MKK=5UFZ_9^?M]GMFYOYV;?7__=-?_O#UYYO_^\%-D8>_^91*0_?+W";LDDRT -MFGS^];Q5F>!R^69_8B=3'9):F?HI).,9IVMV>V>:BK_>J1F_QO_BCU]_]=7S -MHAOE'Y/\NJ.G^?;%)\^>57^KM_C'YW_XIW\I-M/__?1I\23])T7_KU:O'%FQ -MT:>?_>._U/_[AV^>?[WYXL_/GG_SZ6?EW]3_[G=\\^PO?VGWI/[WM2//NA^: -MG5\G&90(K0Y0I^VZ4H'MZ&\%=V^>WM^\9TC]>S<__713%O=[3]X_97=7T?K@ -MH_?^-C9)V_R#KC#1/4>?H325MW$@3;V#LB*\)+PNV15J:0H6ZEGF(3347R.# -MAYX8&D34&&"8]'9L*P1M:D`%89Y,&F3Z(R-?U9B&3F^@0/CH6?P90C@(+52# -M[Q0'2L\VNT -MOQWN;VQ9_/@F?[D_WNB'B8-M]LEIW]NF2_I@Z_O#WYQ>'[??A[1"5IK@WLHJ -M;M!MI:/XAPLKJNP4:#$56]I64A6ESZ%RC*,0TK,`6@A--\9^'UT"=:_,]5\. -M)(32Y\V(J7([07"J=H%2,%F]9D94"1L!1+,!@`[-IFCV+U#R8?!^A8D;H<3!'(D"WH0M&Z"=EN:N&HO;8NH&[@ -M@2RC&69R;*5HVN+N6H%K#6ZU6)&E)'H<7=J&,(1I32B:M/92"T:S7"N$=Y1K -M^+8;!:[BIFRE_""R:,MXZ)4+Z;:V@%&W1G0K&;2?#IN6/%G0.955;76B!X"] -M&<2T7JWC:=8L)#\.+%U"D:TW_:`U6-1TMJ; -M6677WX7MA"K/N;3=JR#-65<=GO52%8T#(YT$N&J]A=E5]Z,N=OEJV#G(=HP3 -M];V1>KSBYIN_L54QS\4M\74!.MXDK`SW+WBMO:*\5C'W9KY:B\5>]7Z5C[(V -M&E7^7/YE[=5HZ^AP-99;6JJR;--;C];(/=8IN1BCG2EEP]4%ZB1LR[$5IO59 -M6V.V4?N^QF:K -MP&Y6SB@+^E<-NR"N7">9ZCB!!I8K)Y-[LC(:=)UJ++6$53VX4@)N`5O9MJLG -M4UD*=&W/606P%6K0:U_6*$FSB:MT@KZ0*U_FK3$$AE\']7:=!ZOB;E?2*"N: -M-Z66?_[.(.J]#1SE1G\8!'CT0L`8,MBO%?7]/,*(;\T^`0N&`9(:PB`Q'"^$ -M%?U\!@J,Q>!"Y=FH,2F!,#4XT8C -MILQM#(A9KHB0?)AR+UX1@N]@.(S`:$@UQV@5:9J1=:0)(.EE/,--')[&RXJ$ -MLZOX/M"$MRDV\8%$23/C#Q,$K`R9"BC9 -MH*D&5S1F<#'^\"42!^-;)<)9E4R?F4D\.>Y*),[,)+2CK@1Q4)T0#ZH3T3,S -M"?U0*:$=*B7$0Z4DEC,SRQ41D@]39L8K0O#M#(<1&!E):,?!"?DII##-\ -M`'4LGR2=&O]\+6V@Q*8DY`R_"PK.;1RX6:J(D'R8MCH>$4+"Z-`9@1.3\:_( -M3C1C2`GDT\%!XR86?^-A1<+9=9F\)G7QX_SS1>":U(5T]OD"OZIPH5U5N$A> -MD[J0SQE?2.>,+[1SQI=(KDDM5#TX(DR9&8^8P+VP8'XMK9)SH.YNB5'^N\CY-C?8".UG1UFC#X&`&BT`C#6]?5J% -M0L\?3"DL.2>`8C`P0C,8*OKCA+!"SV&@J%BP4!#KW&`J_%OI)%O!7NL3N._- -M(X3W@R88X`\:,[V%3\@(UE_X5W&C[$D?\T-Z-'YNMOW)4>)T72>PIFT,XXRR -M+ZM,=/F"280AOP0H:`-!-H'!0!T7!`1=K@)%P,S%`%RO!I_@SXHE^0/RFIV@ -MM#)7$$)KFV/HK#5D>@&7EWVPVN]^14'8\ -M.CP3]R=>`25T?^)A!4+8].64/_G2"S)]R?4W#RG(23YW'X -MD^7*!L4`NS_QC`(2[./S)W:41[77S;&,6? -MT1=Z=_E"B0CS5?#:0)!-4&``OW&YRU78*)BK&(#KU>XB/%BQ'.>`7[,P5D/? -M?:UM3N"SR#O875[VH7L`ARL*PH[;W_YF?[Q+=WN[YG>;N$T292ATGG1!4%Q1 -M]STE`TH^47)@F@XQ/"0$QW/P&0%3 -M#'6.$KL)$P5S$`UZO=8WBP8CF>`K]F8<2&OM=1VYQ` -M:)%WA[J\[$/W`@Y7%(0=.[O6[QPGQXZC]3L<-W8`O.^0>-^):/T.O^AWN$6_ -M0R[Z7>A:/UK7>L]6+$O61B9=S@R[ZADW@EJO9/+/G2M=[BB(.RX -MMVO]O>/DN.=H_3V.&_<`O-\C\7XOHO7W^$5_CUOT]\A%?Q^ZUL]5#,#U:M=Z -M#U8L1^OQ:Q9&YGL^I9+X7U'HGEWWH6N]P14'8\2)[>WBTZWWUL]L$J8=` -M9T@5`,619I]3R*_SA\)^/^=T('0#(S1#@:$=)P(.=0[#QL,2A8)8YW:?X-%* -MY_@%^EJ'4;Z91P3INR8$VG>-93R$%\@(W5-X5'$0]KS<)R,6H_S5;>Y4`Z!# -MIVR/8DZ]QRG5J'*'$HU>NNFD:`>%;X7B1#-&!":J[(7-B-DK!+ZR[:;"F[7- -ML134U0W#>SV!"+JW+0AP;]O*N`GG&1&ZD_"DTB"L2>P6(G&<,0G'/"0XMB0` -M44B0BI"(&(8$3X($AX$$R8`D=),P5S$`UZO=&'BP8CF6`+]F88A.<'Q.J'!. -M!#V`D\L^=-UWN*)`[!B_*I%X<*XRX5Z52/!G*A/@R>:$<+*YGW,&$&BG&!/\ -M*<:$<(HQB>&JQ!*%@ECG(S[!GY7.\@ODM0ZD//X<<<(Y1YP(7Y7P`AG!>PI_ -M*@[$GK( -MP429O<`9,7>%P%?VB*GP96VS+`5Q=0/Q7DT@ANY-"PK8B/%G;/!=!6]U0MJ?88\2F!8GMJ>@Y"=<9$;Z+\*+2(*QYL%N( -M!\<9\\`Q#P\XMCP`1.$!J0@/(H;A`4^"!QP&'I`,>`C=),Q5#,#U:C<&'JQ8 -MCB7`KUD8HA]P?'Z@POE!T`,XN>Q#UWV'*PK"CMRN];GCY,@Y6I_CN)$#\)XC -M\9Z+:'V.7_0Y;M'GR$6?AZ[UOR:A9$YQY$YIY(Y%]1Z -M)Y=]Z%KO<$5!V'&V:_W9<7*<.5I_QG'C#,#[&8GWLXC6G_&+_HQ;]&?DHC^' -MKO5S%0-PO=JUWH,5R]%Z_)J%D?F,(_.92N:SH-8[N>Q#UWJ'*PK$CO/4AY[: -M+1SGR)G_F:;I$8!CEGA<0`F$-VL(O1!;420![6YC$_Q"BBA>Q0/*Q#"ILM;NS6Y -M_N8VCXK.TT%T;8UB4+FW*3TIOM"="N6\HX!FXI?\&N?+?A"[_Z_.`/]>,V.QGOG51^=94?Z@`H`%':`QFB[=%.>S5W0.`;TTTA06]0 -M^%9`'NAC!"%!S5ZH3%BH0N`KVV0,/%O;-'O`6]U32-7[S<[-+\^G\&,V'8R%'NF(9#@(\A#(Q!QOU; -M9<245YB:C,X(`2F6`9,;PP!C'C^$,Z8\!PJ;54L*S0Z#7?&;'B3S(LJ/"8$Q -MSCA$9RP-,7)C"<'T-R'`*%CO$TZ%@MF6[8M;+TUG64Q;><"V=D!,M#5Q\&SK -M>@!2LC:W>"D;3@N32.J@Z:WQ3%)R@(52F^T(F+1&9>%),F&3?&0)VR@)T`0A -M1-W$8Y5(;4F5(C6&H%ORF4U1.";_*_6=?)L5@[S^S]/J?PI?U/V1S:QK##RM -M#)W2:%3\KBT#9ZLC8[Y9UJ?>K67^&L:R[OO#S -M.L.GI^0*[I-&2YF1*+TM1LG1V]:J96O6_=K*(E?YB\^ENE[N -M'G;)X;AO<-_\<^WUTG9K>KDTFQK72Q='QTL[SA&^#',Q7?QJ9T8W&"E_I6^& -M^F]'Y'OYRTR-L98;^#M7S1#\P^K9!(TN2L(ZM]67T=:!P%+2=W>O)[TB#T2:6,?PY$Y28!UTN_@]%9C -M*Z;77].RT<;K_;!E2_!5)YUEU1 -M`:B1:W.OKL?K[[M&FFABZ,"HQS="C'X&ILN[Z\3( -MSR,%WO;)4.'U*'PO<.YD&.JU`;A3%0M!^'3-FD#0Y,I*@FZ#211TF^(XOD"A -M^\_R5>9071_G_)`T."__>^VU475H>F&4VQG711U!IT=.70^OLT/>7M^M_K'V>JB[-+T-LG0X77H_"]P+F38:C7!N!.52P$X=,U:P)!DRLK";H-)E'0;8KC^`*% -M[C_+5YG#X1UNF]>'XRY]?=+OTVS_NO9ZZ7<2>M=;VV+D[CP2X'D_<. -M&M(%O;]-ZRADN\G[W=1^6^][Z\;N^SJ:<2['5HM^7ZBSZP5^GRANQ=CO-512 -M/7'/H;8E\-Y#K0WE?M+5UYO_RN5L+;Q3/I]0',"%G.8`YD5%];2*[C]G>ME9MHVF7ZW1R -MUE^TU*>/UIAYR$HL%=2_M=A7U+E6XX"JEHDQ@]6Z\3A;K6UEKDX^>8560[QEYI:U7]R;$TV'<6LR;K-Q*IL -M(QN8U^1BBGJ#G&&6F-)-V)93RZSK]>A":P8>V$(3G<_Q5:,IF=OK!J=FN)5C -MA5J;[G&L*9O!P*8TH.K:VHLN.'USI1A&5NSM]G2X&VI=]6<7UVW=8?3*K=I! -M5F^S!QLKZ]R`>-G/(WHY=MV&;PU:ENTHII=FG9`0%^<<L6-8[*9"@`JNTT1N.P:L?33H04;IIXZ6"PC*_XN?7PSE-?RKRZN]JJ[Z*5> -M-H.L]#J^#;=57D"T[:40O4[;+H,W!JW29@33B[1*18@K5'R2)]?74%`=7V$$ -M.46NL7$^UG,`P&.[)8*.;1N6DCJR0L-44<>*9&2%[Q\>\S>;ASS;[X="JO[H -MXFK7.H]>\FIKR,K7]V;CKY8S$(;-648OZ/YPL&U`R[LWNNE5KB4MQ*6^3%5` -M5_!0JKU:PP3A9JWB<4+KDP8`=;\!@M?]IBQM]P`%8>J^1\4U1I1+GFWO\DWQ -MU^\,KD#[V4FFZ`/`,T5K#Z)*;X]6'=!S!U,"2[[Q6!@,"]\*AH;^*`%PT!,8 -M)!P6K!'XZC8X!M_6-\4U<%?X!-Q[4PC!^Z`)!O"#QCS_X`\H`O41_A4;D#BW -M;W\][BB*#5QG3CD(%G.*"%CJ5'N%J$:90[1NZ)EG0:,9'J4=&ASU:''H*),9 -M.CJ6J1C,RA]W&]ZL?:;C(*]^N!!4$XJ4@J8140R:YF+>PQ.,A.]!/"L^()%> -M9&_'O4BQ@>L\*@?!HE$1`4NC:J\092ESB%86/?,LB#3#H[1#0Z0>+0XB93)# -M1\@R%8-9^>->Q)NUS_0BY-4/EX-J0I%RT#0BRD'37,R+>(*1\+V(9\4')=*4 -M%?&`1FPC0B`16%1(FB)G0HCPH+"#@HX8#,C\I8)8ZQ/FPX_5SK4>M/6.8#\% -M_3SR2[L.][D1@>/PI^B`!$JFSGPD'AS]).PS'PGAV"',QS(5@UGYX^;#F[7/M!_DU0_7@H1R\)GP#CX3Z3,?GF`D -M?!_B6?%!B31E13R@$=N($$@$%A62ILB9$"(\*.R@H",&`S)_J2#6^H3Y\&.U -M0N5^ -M86)2Y)$@)UKZF0RIATAJ2.!(-6(L28J4AD^2A0H'Q8$I+^(-"=A^A,P"C#R4 -M\XH6B+H562+J]H+.Q!NJQ.!0O"M",*'2*:.2>D"GE&U34@*94K#6I"2I2>4L -M2DID24I!24HA21J#/5FB8C`K?\J:>++VV<:$N/HQBI!2!"'EZ4$J[4F\P$@, -M?L2KX@,2Z3)QC>;B_EG;"_<:S05_SO8"/?%^H9QXOXA=H[G0SK5>".=:+X1S -MK9<(KM$L4"J(M3YN/CQ9[4SK05SO<"-\Q^%1T8T0 -MZ#[-'K;YYKA_;?A>AOJCB^31.H^&CMH:0AQ];S;-T'(&$@QSEM&`Z`\'VP:$ -MAM[HIKF@)2U$)"Q3%=`5/#007JUA@G5@K>)Q?NN3!H!WOP&"W/VF+*_@`0K" -M]`<>%=<(45[ND\>A&2C_ZB)!JNZBP5$V@Q"CCF]#>Y47$--[*42OZ[;+X(U! -M*[D9P?02KE(1XLH5G^3)]364:L=7&$&'I8WY(CYMGF_/CXSX;:FGO=Q?7?'\(Z+7?"P"AP&"?-ASW\P<" -MLS7IZ%5N&!JA&6CE#T><2-,%^%IT4T3Z/,)M_&Y^_SYG.LV/L?3YW.HA'Q.D9!ATJG4 -M^)Q&C<\)U/B<0(W/(W`;2Y4*8JU;W89/JYWN-CCK'03^SPG@_YP%_L^%W88O -MW`C:;?A6=-,$>C[A-IZ[SY_G7+?Q'$^?YU`)>4Z1D&'2J=1X3J/&BF"?35 -MA-OXRGW^?,5U&U_AZ?,55$*^HDC(,.E4:GQ%H\97!&I\1:#&5Q&XC:5*!;'6 -MK6[#I]5.=QN<]0X"_U<$\'_%`O]7PF[#%VX$[39\*[II`GT]X3:^=I\_7W/= -MQM=X^GP-E9"O*1(R3#J5&E_3J/$U@1I?$ZCQ=01N8ZE20:QUJ]OP:;73W09G -MO8/`_S4!_%^SP/^UL-OPA1M!NPW?BFZ:0-],N(UOW.?/-URW\0V>/M]`)>0; -MBH0,DTZEQC2!]0T/;0BH!ICU#WRK?I>B -M@%?\/`4`6I=63^#ZRJ3[`.S:!&$8^%D#;6L\>@6^I>'HZ@Y:T5TMHFE"W%J5 -M^]9E/MS2E?L60X?;:7#?XL!]*Z#HM7T;M'+/4P"@=6E5;M=7 -M)EVYL6L3!-U;%'1OB="]%5-NUU9WT,KM:A$!"/';W^R/=^EN;U?P=@N7>=$- -M@TR--@2&'LI^IP#?Y1$%>D/ZR4S0ADAJB&*$.F(X*[J4ADR,10L'Q0&[8_", -M!`P'P60!3`R4>46(@M:*(`Y:>Q&GX1E5PG8BGA;A-*'VE[OD/.)3FM\=9E,[ -M!"J7F@`(*G7[G)"9-G\8D1DFG4H1=6B$9AB"*",%\Z--8\#L6*I4$&O=ZD5\ -M6NUT'\)9[R#\=S,)A[_:!H]^M;6$^_"%&T&[#M^*;II`+PZ[S8OC]L'N-[HM -M'&:0,@PJ@[H0"`JI^YT0$R6/&#DQI9_*$'V(I(88CF@C!I-$26G`)%FV<%`< -ML'H1WTA`]R-<%H#D09U7N$#HK?`2H;>7<":^425HA^)K$0((E;T]&+[`I?WJ -M,I>J[I.)5#;'T*C>WY2X5'E#"4LOU61NM$-"-T+QHADAG!55ZD*FQ.S%`5[/ -M=K?AR8IFN`SBFH:!O9X[!-3;%@2@MVU%'(7C9`C;07A29-.$^=[J%KYWF2O? -MTUW"]QB:?#\M`-_CX/^]@"OX'KONOT>M^>]1Z_W[H%W`/`4`6I=6U7=]9=+5 -M'KLV00#^'@7?[XG@_5Y,V5U;W4$KN:M%-$V(5U;E?N4R'U[1E?L5A@ZOIL'] -M"@?N5P+*_0J[ME^AUO8KU-I^%;1RSU,`H'5I56[75R9=N;%K$P3=5RCHOB)" -M]Y68+"$"(_?YQ<]R_WF>;^T.R/]F%O+^AR_08#(J,DGXD#%F& -MO9C2@$&.49)@GR$R1$S#Y[1'(<:0#3AQ!LD/&3_K5QJ%-'9KXC5K&,9%E#8P -M11H6`D*@3(T)>F4*(^*!`L)7V/XIP.*=)F(R>H=$XOKUU(1WAT2"O9J:P"Z" -M)_B+X/U44WF34*Z#)NCKH`GZ.F@2_!T2\Q<'>#U;;8TO*YIN8*AK&D3[!'WQ -M.F%R\V2T%*TQ9*GV-J4'9.S:!-'WB$+ODYZBO))+%.Y-"Q=/S@JV`V$=UQ@6`HV&6#ZH$XO0BCT9@3%T`.(^`\/(1.V1_&X&`'$2G?G -M!_MUB?IGESE5#X!,J*H]AD[-'JBH$Q@R -M-):H$?CJMGL1;]8WPX.05S@,]\T4(E#?-2%@OFLLXC<\`$78_L*C8ILF3IKL -MILZ+*)LXS!UU(%3R*#$0]-'V/*$?:BXQ&F*<`RI">L.DM<2@1!\U&"=J8@,& -MRN+U@Z."U8OXQP6Z)^&3`207VO3"):/7#"\;O0`2/L5'R`3M6WPNQFEB_6"U -M+S^X3*6XEZS.C:Z@Y:N5TMHFE" -MG`^[S7GT:]?=%@[S0AD&E1I="`0]U/U.`%[)(P;TIO13F:`/D=00PPAMQ&!6 -M*"D-F!C+%@Z*`U;'X!L)Z`Z"RP*0&*CS"A<%O15>'/3V$D[#-ZH$[41\+4(` -MH<[[XUVZ&S$JS08NTZD=!!E-300,F;J]3FE-FT.4U`PS3X:).CQ*.Q1*E-'" -M2=(F,V2,+%K7V&,6&M?I@B=!.*$`2U$4$/U.8BGL0CC(3M1SPL -MOFDB7=Y:71*XQJ:+FEHJ$>!JX%!@?5J,`@ -M*!(5,`!FJP/8*K4Z!O?7*=TEX%:%@Q11Y$"@'(DR24$';W$<2L@`0-?K[M&*]ES\8W&U)QU-@.#1",Q@1!B,%<*&7QB#9L&RI(-:ZP1/XM]HI -M_H"_WB_N!&HJ_"SZ$8(=,IWAW1H,JH_NTB;NL-H -MQ%3M(&1I]F!3A3HW(#'HYQ&][+MNP[<&+?)V%--KNTY(B`MZCKF>7FU#F7=^ -MO1%$';WBQFG:3`4`HMVF"'9VC5@Z[=""#5.#'2R6T16?'1XW14[3X_Z8&\[' -M#[9PDP+]81!PT`L!(\-@OW94]_,(I+8U_82U;Q@BJ2&0",,10^#03VF8E%BA -M<%`<,)D`+TE`L@8B+)C2@,&\@N3`T`JE#(;V3$?A)55"=1]>%^$8H=X\)(?C -MJ\TUG,&D*#\Z226U\W@<*:U!)-+V9M45-6PP5[XM(8IIH*SBB]`B5T8S -MO<#;Y(2XM.>;>DU3B.VFYB`)A5-T8@5FW&TFX'EW.86NUP -M\8P0X?7AN$M?&RXH-#^XR(.VTV@:-"TA-.CV8B-TFR,0H8<912]FM?N8[4&+ -M61G-]&)NDQ/B4IYOYB$K<:C-7JQ%@C:35N,X7KN)`>!5W1B!5[492YL=7,YA -M:K/#Q?/.-=O;[.[EX4<(\/XZ=-OR9F'W9)JU=4X:"KJ19<7;1]8L>6BZ5ESUO!)0 -M=:]7<$_@%UC#?5I;Y\R(ZY&M1WD]TLZJ]H%08%7U7Y`#3A86A"1W+_=WKS8/ -MVQ>'.XLC4+=PGBO:<.AT4<.@**/O?U0+$L7$YH7%@?B+S$XCD2&&0`AT><:*BC]5EAAZ;>7<2[^TB<"9^-O88)( -M]K!+#L>]S?74O[K/KV88#'+5(7#4:O<[+DQ-'A&B-$@]@R_*T$@-$5SI1HIA -M2I/&\&FR0,&@UKW-O7BW\EFNA;7V(:+0SB=8$)06:#%0V@HY%&\($H,C\:;P -M0"3*WCSFJ) -MH4:=P/"1,7>E8%:ZS7)XMM99AH.QVB'4;R82#/VN`9KY75,AK^$%,F+P&5X4 -M'(0\^V.>O;%8C.HWYZE3#X&.G"H`BCC-/D=%H\X?7#/Z":>3HAL2H1F<$^T( -M$9BH4Q<\(^8M$<3:MI@*OU8WQU+0US>`[\T,0O'>;8^E>]=2QDVXSX@(G(3[ -MA08FS>8N?7RS.>7;?,Q/*%OYP1YU6$P&*:'P--+Z,2TJ:IZ1\F*<(B9G>D-G -M!4"R1\\$ED)JVN.@T4J%1N+,F+?QFC1LOR/&&J@T:76`$JE>2Y)<]6((.J0@ -MR!6+DPJB<.$D+%^*D>U/:?+C/AMU7?J6GO"P-SPN$?5P!"KV^P,0QU[>L0)I -MFS8NTX:I8`?!LFV0&33?>M,1">'6+T(RGT;=6@B$XKLV:4:!1;!?(S@A'+:F -MB>$PCJ23"Y%ZT3B[$`L;3M+3XS8[V6Y&UC;QA)S-@+C`K.,02-GV`*"@36ZQ -MTCF8$R["E.'26V.AU8T>3:LFR9%`:M&:PM-CU(#YR0^^Y>(3!*Q%[93C1$AI -M1E,?)8"DG_(51M%X)E\+%$&VJ/JJ+APM5$980X\['.T8(N!X6)>""0KFLPKRB,LM50-]P$X_'\:P@,>3* -M'M+=Q$F?>AMOZ%4/B8^O*A")8$T?0")5YQ>O4_V)X1.H&S*C.9Y#;08(**I3 -M'0V+EBTM`DLFC)"?-)&P0WR>(#2HF7FL#'7MJ$K419!U1_ZR*2*GY&^APDEW -MV>;Y^+U0U1:>,*X>#I=O51@"W9K]`P2MSBM6SOK3P651-U1R8RR'VI&C*52G -M-Q("+5=,:%Z,^B(?B<'W1%QF@&6FF6N&L?(`K=?$(%06V!%0.UK8Q#\8<@$3@2?PH/ -M0J*';7[WTN(_JM^<9U`]!#I_J@`H^C3[')61.G]P$>DGG$Z,;DB$9G!:M"-$ -ML*).7?"->TPZ*QI0J!HT^UW5"S:/,+E8IAZ.B_4H9$:PIFA -MC!1!C3:-P5-CB8)!K7N+Q_!OY7-\!F_M`R2@FT^H"*@ML#*@MI5Q'/X0)`+G -MX4_A04CTN,U?CIW+Z'YWGD7*4.@LZH*@:*3N>U1:E'S"Q<4T"72:Z$,D-H43 -M11LQ@BE*2H-GRG+E@V2"Q9_X206.1^%S`2`7ZNQ"!4-O@Y4,O;6,6_&/+Q&X -M%O\*$42JQX?=[VS.I?S-?3Y50V"0J0R`HU*]SW&IJ?*'D)E>PAD$:8=$:(8@ -M1S-"##6JU(7/BUE+!+&V;0[$J]7-#I=K:Q19RKV-:D*1,[@@:!FFPZ`>!K8-'`/5 -MJ!`,*!(5_/*?I1J@*]9B#'Q9LQQ+0%FU`$:7DP4%=+TQELYU,QD/X.:RCT#W -MW2PH$#GVVYU-[8N?W&='.0`&.XKV.'I4>QSG?)D[!.GU7#,0T`P'WPJ!@7IT -M&!"420L?!//5!GPUVYR`1^N9Y0:(*QH"\&KJP`AO-D=#O&DHY`ND/CP4M-K*(R;7PY+@S^%$EPL!LZ*P"%>6TF2*2KTQX1W98O-!)G)GV@KZ21\7P2K$') -M6E,'>#'K6M(EK(LA[>!\)U=4SLSWPL61\+3/B\]1'7?;;+=)TO35^7'2?YG: -M>,1(XY`E>&D*3*2GN8]`.37.#T5L@0:2GC+^?F)4K"S96&%W1;'+J\VR)*N]1861R5NXUUH8!)O[_DV?;. -M]@UY;1,_*-X.B(GL)@Z>T%T/IE6_S2U2Y(=SPD2B.EQZ:R3PE-%C^=8F.0Z8 -M+5M3>'J,V4)/^<$V?0($@2I5-^4H85*;D71(#2#HS[R%42S>RML"!9,M?=P? -M)Q[S:#;Q@VOM@)A4:^+@J=;U8%K#VMPB-6PX)TP4J<.EMT:B2!D]%D5MDN,` -MT;(UA:?'F"_RE!]L7R1`$*CL=%..DAVU&4EVU`""OLA;&,7BB[PM4"39)AZE -MZ#;RB6T2#TUTD:AT@]YOKN28I&>B#T+HP^:T)\&)>%^NDO"8\+1LA5'(,NV: -MO&2+D'-BTP4G3H0;KO6&#(&:X1D#[U$5EY?RN&#QY#MN'V"^JMS0,_Y5@Y,B -M8!F-0<&Z-P@5K').5<+>C$E!K$T#-P859DU6R$"K)B(RI*U4?50B@?R8OTR2 -M\V4R5$++75T<-,EK&_-DKPTSAU<+!7/1>;=0"AI'SH?]0YJ]F71R]68>,;,9 -MF`0OZUA$6K8]`6IHDVN*@@[F20)KRO!Y$2A(Z[)!`EJ3_(A@MDJ]T:@SZ=;\ -MY8Z,4Y,A#TK4VG+`2YK2E"YH2A!I?Q8"R*+R92$4,)B,Q4WR[2>:[5Q4-_.# -MB]K`F%148^&IJ/=D6A^U7"/UT3Q/3(SUA\^+@,18+QM8C&G)CP-BZ]4;C3IC -M?LQS[K#]F"!YH'*FEP-*SOI-27+6#R+HQX(!62Q^+)@"AI/Q_/B89GEQABW? -M9YMMDHS:LN'6GE#2,$PN*HTE-?SP1/S_J3*TK-+D5`H'D'; -MC#$96D]9E`QUHUR9S$/X3_^I)^U!9;E'E..FFCB"W,60D.0NVGQN-&R>1NI* -MPUX(5%(7TYKM3^/7IBU-O*1U-V!97+=QV<16>HA6_VYN>`;`,,>RB-72)1>- -M!UHU>TS6=I,8)6P=JV$^'1%6-A0^2AO:.0A)5'.EQ#B"KH61T'0MX'S^-A[X -M1NIUXUD@5+*_R*[V&6%ZJ^V])'H]5%F85T'9)&_ZAC8)]7SP'$)_4F4IVZ5( -M*!2/KVW&F'"MIRQ*KKI1KDSF(:RL_]23-K&RW".J<$S>C@J2C*K"``(OJ[P(^-%B`QNI!@UT`5#(GR+.CB;_G"9(YSHXF,F<) -M$NKIID3B=%-_4F4IFL@=S2<"1_.)T-%\$O'943?*ET1% -M3@1."B6B)X62!ERH,*(+F+R"5WU#*_T -MY5PPA5Z?3V&,-NF1B<2$:)TM+D/+R8H3H.O7*8]R&#OJ.>?$S:@@Z:@*7)41 -M2X";$"+ZVP2;T8<&"]!8/6BP"X!*YF-Z'/U*CFES+[E<#526RF5,-I7KGJ%U -MO9H+GJ[WYE,6GVUZ9"+Q\-EDBXG/:K*BA*<#=$!6U:>$GG=KBR>&["L@G= -M]0\M\^V\\)1^.+VR3%53)1:,1U8E282 -M=;NK+8YTJU$DU%N--Y^#C8.VD;K9.!8&E>39(\;5%EM[R>]RF++D+D*RJ5WU -M"VT$RGG@F0!]*F5YVJ1&)!"/HW6FF`PMIRE*>JY=H"RN(=RIWV23=J5R;".* -M;E4_',%M(DB(;1-K/@<:)C$C=9QA%CZ5Q.-_:2PL4@91%\C<@F<-DK -MM'87<\"3;FT694%9IT4B#@^359:8E"PF*$I$KEJ9')(A+*7/+),VE%(T(ZIJ -M63@<4:T#2&AJ'6H^+QD>(B/UD>$5/)6\E[<(#WG=V$ON%H.4I>XU(INZ9:_0 -M2EW,`4^IM5F4!62=%HDX/$!666("LIB@*/&X:F5R2(;PD#ZS3-I#2M&,**EE -MX7`DM0X@(:EUJ/D\9'B(C-1#AE?P>/*FV<,VW_P.^H(E97//V*L.5(J]2DP& -M?;6>(31;G0NJ:AOG4PJ7O?3(1*(B4\\6&9KJ9$4&36?JE$ -M=&CAU4C@3MY>9`($SDG9G -M;.G.YK.6F1`G,RXF,PE*9K':RC4KDT,RC*7TF&7BAE*(9E15S;BBFLEI:C:W -MEPP.D;'ZR.`*GDK>VS>;NW0'>]FFWL)+`K?#E85P$Y9-XJY_:`EOYX6GX\/I -ME66HFBJQ8#R:*IEC(K6=OBBIZE+QLGF(L*-A$%':F,HSD:C876UQ9%N-(J'= -M:KSY'&L(EQML;67_"Z'*4ON(B2;VE6_T$:@G`>>"="G -M4I:G36I$`O$X6F>*R=!RFJ*DY]H%RN(:PIWZ339I5RK'-J+H5O7#$=PF@H38 -M-K'F!4OYX(IX_I\ -M"F.S28],)"8XZVQQR5E.5IS@7+].>93#&$[/.2=N.05)1]7>JHQ8XMN$$%'? -M)MB,OC-8@,;J/8-=`%0R[Q\>\S<(`UIM[R69ZZ'*@KD*RB9STS>TN-?SP5/W -M_J3*4K1+D5`H'D?;C#%!6D]9E!QUHUR9S$/84?^I)VU(9;E'5.2FFCB2W,60 -MT.0NVGRN-&R>1NI,PUX(5%(?3NG_^NUO?XGPITT++UG=#E>6U4U8-JV[_J&% -MOYT7GO0/IU>6K6JJQ(+Q^*IDCDG8=OJB)*Q+QU -MQ1%O-8J$?*OQYG.R<=`V4D<;Q\*@DCQYN46XVF)K+_E=#E.6W$5(-K6K?J&- -M0#D//!.@3Z4L3YO4B`3B<;3.%).AY31%2<^U"Y3%-80[]9MLTJY4CFU$T:WJ -MAR.X300)L6UBS>=`PR1FI(XSS,*GDO@AS_:89_*K[;UD<3U461970=DT;OJ& -MEO)Z/GABWI]467IV*1(*Q2-HFS$F0^LIBY*A;I0KDWD(_^D_]:0]J"SWB'+< -M5!-'D+L8$I+<19O/C8;-TTA=:=@+@4KJ#/7BTS23>UI?17O&8 -M\=_QF,WX^M%,ZN5Z&?OM>IG(Z_6R:%]!NG:!LKB&\)]^DTW:>\JQC2BW&?O5 -MC)G@NQFSV=]&&B8Q(W6:818^G<2O40[SM:\?E:A)>OHW68ZQ8HBVLHA^DSV>0=IA3;R$+[FBVTKP6%]O7L#C-$ -M8D;K,$,L?"J)<]0YS-S7(_U<_AQF+G&7\4T3YC.8=YD:#PA2;@%[Z`7V9TF!\GAH1#N14%%0&F`U0&DJXW7\0$8$/L6/@H.39W-ZO/Y/?C_J-=J- -M/.%0-R@NC=I(!"HIO0`H3)=CK-(89H<+&FW8G/98\*A90`.H2W@D&%JAPBAD -M&?4V_K*%[W5DZ`*6(J4`<)*D-:1)DQ9"TA/YCJIH/)/O!0LAWSD_)!8G5?[D -M/..J`="Y5K9'T:S>XZA^5;F#JU8OUW3$M,/!MX+CI!D=`B)5TH('QXRU`5_- -M%O?BTWKF.!7JB@9`OIXZ*-K;S;%`;QO*^`ZWH1"!GW"[P"!D^?&0Y>>MS2HT -MOSI/EW88=+PT(5"$Z?8[*@UM'N'J,$P]G1/JT$@-X;101HH`1IO&X(FQ1,&@ -MUKW%5/BW\CG6@K?V`?SOYA,J`6H+K`JH;66`IT_50`4?9I]CLI(G3^XB/033B=&-R1",S@MVA$B6%&G+GA.S%LB -MB+5M\1A^K6Z.OZ"O;P#BFQF$`K[;'HOWKJ6,JW"?$1&X"?<+#4R:S>YP>K79 -MWME.9_0V\H,\RJ"8`.HBX4FD]F):3Y0<(X7%-#M,P.C#YK1'(D?+`I8]2L+C -M0-`:%48ARYB9\9@M;'LC1!>H#JD%@!(DO2%)F?00@E[(>U3%XI>\+U@D^1[3 -MT^$R[:JJS7QB7STP$?95L:CT:WH"U;XZUR3UZ\^3"+:ZX?,BD-#59H,&KSKY -M,<%KC7JC46?:<7G+'2'7)4(>G)`UY4"0LJXI0\RZ(.+^*P"0Q>7#`BA@)!E/ -M^WQSRK?'W3;;;9(T?76VO?1GHI%/S#0.6H2?ILA4FII["559XQR1-'=\MD5` -M:4N;9#P21"U9I"'5.*$QX=7MBI8@Y[3##)*=0NYS=GKBA-U<<`29MP5BB+XM -MI+B'C1C-<7G?B!<,G/SIX_ZXN=^-6N1F&T^HW@Z)B_`F$('871\`9J#-+U;[ -MAQ/#):0Z9$9S+/^4#*!QUZ8Z$K8M75H$EHR:1E]IPK>$$CP!ZU?&93-,[+YT+%DNZ0C-Z=KVSE%>O*8V -MFACR#LMOX/1ARKO),%LC=M -M8DQK4\$.0F9;DQDZWZKIB(UPJQ4AF4\PM^8QH01=FQ"C\")8UPA1"-O63#%L -MX\SBY`*B7GS.+J#"1I+T8?^09F^F?5Z]G4\,;88FPL\Z&)6>;5^@TMKDFR2L -M@\D2H9R2`F8($N&ZC-#XUDQ!3&Q;J>R(#)KV8O7R?C9HU93-/**D.C(M()1:!D%I/`(JI -MYAHKF,9YXN*L-WQ>!"S,]&R@6:8F/Q*0K59O-.J,VC._N<,W9W+D`2N:5@XX -M0>LUI>E9+XBD+PL%9-%XLE`*F$+&S>UO?[,_WJ6[\L5(=K!PSE:@L -M>FJ]0RFJ.B=T;37.K!P,>VF2BD4'I)XU!BK5B8L.F4Y5+9>`0)<8"@,EG>,< -M%"2(L5945%GN!>$*="_NV9TCM;^:"H_R#^93$J9(>F4@I$G?(H!W:G_G-.UIG* -MDHXDPFT9T258"<$78"787'XT9(!&Z4-#7@`T,K\]//X:[#[+C3UD,L2")Y&WF,=L?SI!;62[O7_T[88J -MB-\V*(_`2M]PPMW-!T.[#9,J2$TM14*A&.Q4,\;!9S=E\?'3F7)E,@]J.(.@ -MGJCM%.<>18N5:B++L1:#K!S#9+'%[6$Q0?*M>N3`[)H(;3 -MDI=<0,I0%R2 -M2+,U>C[S*`1&+AIIP3[PDDKG/-`:)R!C]8Y`%3R/O -MVQ1N(8MM/:1N.41)Y!8!F<2M^H04Z3+_'(W6)U"2C$U*!,)PN%AGB(7%-L-41!RI8!>92M^X23Y"K_#$GN3:`@$=N4"(1A$+')$(>(U=3$ -MQ\-52Y+!+JA+])I>HBY1C%\4\:PKABR>;7NV>+:19G*)P3$Q1I<87*&32/N8 -MI2^R[0/4*#:;^T?;=J""N&UB\HC;]0RGT.U<,$1Z.)^"F%33(Q.)`4LE6QQ> -MMI,5'S#=J%,>Y:"6,@#.B1I+8=)15+Z-5L6ZS@S.<-@J!>C`PRFL.$D -M/>WSS7V:/6SS49NG;.8)0=6!<>&IQ"*04^L)0%757&,EU3A/7+SUAL^+@`6; -MG@TTU=3D1P*TU>J-1IU1\^8W=_BV38X\8%W3R@$G:KVF-$7K!9'T::&`+!IO -M%DH!4\BX^=W4:W+ZVWI'R'J( -MFR$&^.JIB8Y]ZY8D@UU`:^Y:"F,0#.B=I'8=)1]+8K([+HJB'8RJL&F\E7!@W0 -M&+UFT`N`1.:[QT,*-9_EMOX1N1JB((S+@#P2UWW""7F5?X:*]R90D)1M2@3" -M,!C99(@#R&IJXF/CJB7)8!?44GI-+U$S*<8OBHK6%4.6T+8]6S_;2#.YQ^"8 -M&*-C#*[0R:3='/>O[S!6L6K@)W'KP0I#MXK*)V_3.[Q6UW/"%.S^S`I#LTN3 -M5"PF/MNL<1E:3UR<&'6E:KD$Q!C.`!@H;CV%*4C5YJ:H6`+=!1%1Z2[+S&ZE.#7Q`D;^,;L=J""OFY@\6G<]PVE_.Q<,Y1_. -MIR!.U?3(1&*@5,D6!Z3M9,4'43?JE$31N>H53\WH.&%K> -MGT5!8'9ID8C#@&6;)0XJZPF*#Y-K5R:'9%"'Z3G+1-VE(,THPMH4#EE6NP!L -M4>U"S>0I@T1DC%XRR((GD?=Q>X$ZR&)3_YA;#E"0MT4\'FVK'N'TN7\#<#E=OZ1]9JB()@+0/RR%KW"2?`5?X9"MR; -M0$$2MBD1",-@89,A#@RKJ8F/A:N6)(-=4%OH-;U$C:$8ORC*65<,63K;]FSM -M;"/-Y`Z#8V*,#C&X0B>1]GS*X3:QVM@_TM:#%`1M%9%'VJ97.%VNYX`AS/U9 -M%`1CEQ:).`PTMEGBL+&>H/C0N'9ELTS4-@K2C**G3>&0!;4+P%;4 -M+M1,WC%(1,;H'X,L>!)Y?_P=PD-6&_O'W7J0@M2M(O*HV_0*I]3U'#"4NC^+ -M@H#LTB(1AP'(-DL<0-83%!\>UZY,#LF@'M)SEHEZ2$&:422U*1RRI'8!V)+: -MA9K)0P:)R!@]9)`%3R+OB^,982+KK?TC;S-,0?#6(7GD;?N%D^MF'AAZ/9A* -M04XJJ1$)Q"!EERD.*IMIBH^4#A0HBVM02^D]V41-I2C;*"K;U@]99I4(;)U5 -M8LWD+(,E9HSN,MC")Y'X`K>7%R\)?!$VEA2\$Q;XPY?HREYF\B'#QPH/B -MA4_$2YP&?Q@4!&/TA$$5.(FL -MY4?#85PMO\WM'5?+`0I2M8C'HVK5(YSV5M]%IVNO/G>""&S2P8_"0&"='0X" -MRTF)#X#KU2*=5E`?Z#&O1'V@$+$H,EF5"EDFF^9LF6P"S>0#@X)@C#XPJ`+' -MD35]S`_I\31I`IOM/")J.S0)F#;!B"3M^@(4VS;?%*4=3I8$[=04,$-0.*=D -MA`2Y=@HBXMM:94=DT*2U\YE",J9.BD,HM>NJ`B]U:ENZSJE1I%U<*%R+RKF% -M4LACI+P_)/D^*SS>J\UC>CKT7V4X_-U9+AJ&@J?A,`B(@J9]&^70D,]I&1R; -M!#R=S$,D-IVFD7'$``H94AHL>Y8O'R03>J[);RI07)(<%T;$Q#2[4R)B;@,5 -M#W-KGOOQER\!NQM_"Q%RG+<_YMF;S5WZ^&9S^_+^8#G3U-_*6699AT4_NNN' -M0AW;#?LQ>J@_R#/\0-\^1?2C,-/060'@1V"&3"".OP9I#Y9.+A0:B3.6LTG^ -MDX9S)DF6-8"#[V$=0`^]32VQ!]ZF&#+GC\(A5\#.*KS"A9`PVV]WF]WA]&KS -M^G#&VSG/0L/0Z"P8.07,$'"2&3." -M8)EA"H)GV?IE1V20Q8^%02&.)Y/G$$#>3%4!%3AS6ZS$F:/(N+/PN!:!2PNO -MD$'W08QZ-&^8*.#'2/0#BB!!^B1]%IE">/;0B!./?UJB8%#KWG;7DW/`[,0$GC`P;ND\GP^"X-V+2C]6,O0'< -MFTL]?!^=,>[-D[SC*T,,[.V3C",LTT2$CRT7JH]*I-&;P_UG$O_V<%DJ@>^K -M)1YZ6QK3[JR=Z2Q2F)B+P9\%6=#0^T+-)LZTA;.D-`Z'=V]HO0 -MR/'IX-W9B8:5J3'N[DX1\9@!OY(7+C:T5 -MY69>.+QF>P9C -M]E7;I[9MLHRPMF\\RFA[,ZMG" ^^X'O"TH]:BE^'G0_8?MX=@[MU%N5_[= -MF>.3D:[;CDG*)O;:+QL;CT3&]F4\S%3R-7UP:4JN[0@!.@1DD^FC`6U$AF.` -MD13YO%'GKIK2!G`GQ%-$F*\N;9]'%_W#SL']+LC4G9!]NXS8_AD(@D&02"4\70![L$#/,+E(.1 -MB2&2PSAD1G,@44P9@-)EF.JP.;-::1%88G(@WM.$[$Q$>3(E-(:9!XF.L1U* -M@(P1!%Q-$&P*W04%4:B3I"NSM[U+-O?9?G][VE7OY?G5WN2>K-NZS3W[$(GT -MLP:$4W"D3W8)M.1(Q8#$$;8: -MG!1[!\NSN!;%[KACW*J!N:"'?R")_3Q7SO@'J_0*<^P1BNV=JZ=(B -ML&3<^7A*$P$'),`3N``1;P'AW_HQU[U-/K,I'I?D<:$"25?_9?MXV-SOM_DY -M&W%/AFU]X)YIB"SZ&0)B*6CLTY0$FO*/DL+1"601S9(2@3`HPIDSA".=:6IB -MX)U#)T)HFF)).;R`F=B'"XP\$+'D?8N -MV6^SS3[+TFS2):K;>L19;8@2E%4#$BFK]PDHR5K^*9)LGD`)(O93(A"&0L1> -MADA$U*8F(AZZ4)(,=DVZQ!#H)>,2I?F%$D^]8O#BV6]/%\]^)&F7&"H3HW*) -MH18ZDK0/N^1PG#Z/V&SG$U^;H8F0M0Y&I6K;%ZC\-ODF2>]@LD2HIZ2`&8)$ -MNRXC--(U4Q`3XU8J.R*#IIV>QQ02^4PA&8,FQ2&4PG55@9:D.4(*8:D$A-O4]`*=7R3Y%3 -M\P1*$*^?$H$P%/+U,D2BGS8U$?'/A9)DL&O2Z85`+QG')\TOE&#J%8,7S7Y[ -MNG#V(TF[P%"9&)4K#+70*:1]W.8O@2:QW-0[RE8#E$-L&8]%V+I'*#6NE1U15AB>!U"X&1F)2!I3)-4+`HR35DCD7,X<1'AT\&JY1)PTE*&Q4`9 -M@SD?!5&J;"@JO#@;@]`UVAA.VH/&A->H_&E,"X)'[DWZN#]N[G=H#]LV])CC -MW>#GH'D;78CJ2F^);J&;,PG78*B`.:"LI5$ZI@2DU:R*P+J;Z(B1[7"U2Q$7 -M[9G#8NX\'GH^ZK(LA%*,?"NA!9.S%%K8N;UVS%B/VHO'O*!$E..0[(];P-VF -M$\W]UY`V$3/J2+,/637I>L[S-NU<"CJ<87W,B'\UO?-$%I0")=N2@M`6P\^B -MX,>ZD*4X]2@@0([/>D0P,\DES$Q7MF*61@TI;FS4X`L=+_PL&%K-_2P9/R]` -M\AW+9="'HD*W'&,]DF3NR -M7YJJ!3%)L*=3/BI9"JS9I7?V,_:@7&$%9COM+OGEY_:]]MMD_/.9O8!Y_V,PW -M/3$,7$Q)AK$Y*F+J*<;7&.:*[&G&YET,Z^;TR48DX]R833K*#9,;&\1=KV\9 -MJL*\>I!<%?3HLY,5;QU,Y4>T#>903,M@#CJ+'X\6@9]&#(K*4&E2]I+J0L13JM8.[4:UX).E$Q8N%%M"D5HG1VS9F"V06:Q5<&!L'X_&)@!4X@ZVF? -M%_WL9,5;`5/Y$6V!.133(IB#SN*' -M(P=W?/XY\@5$588T>]CF>+^M-?-2%_2!RZJ"%INM"KV>HOV(/E<\/V*9=UEL -M#](G&Y&'[7XVF=C6)S=*:#M8>S2EEI!H66U>PM4&SM,XG6O@"X%%:N![X-0&_I):\IUO -M:E094F/?<:7-B8#HS_(NMWZ:I&()8)7YXAYMXN+%J@M5RR4@UJQZSL!9[*H@ -M!3DZS7C14S^(F%+/^-:T2/`:LV\->D%0R'U^?$RS'.A;ZXV]XW4S2#E2UQ%9 -ME&Y[A5+\9@[H:C^813F`*FF1B$,'9Y1MW"A^RQ+LTD#V6WI$7&5X4G` -MM@M')*W:'Z`T*WFGZ+)IVB18J*>"'81"02TS)`0JTQ$1_=8M0C*?)FVA[X22 -M,822C$(IHUHC>%G46],U48\C[0!#HUY4KB^TPD:2-,\.QQ?3-J_:S">"U@,3 -M@6<5BTK.IB=05:US39+4_CR)X*T;/B\""6QM-FA4JY,?$]#6J#<:=:;-F[?< -M$;)M(N3!Z5I3#@11ZYHR%*T+(N[3`@!97-XL@`*FD'%SEQY_W& -MT5(;KAPVU;`L@NK]0\FJ-B]TA35/KQP3^ZD2"T8G92]S#&AJTQ<=/5TK7C8/ -M@:8Q'")*6LEYF$C09[VVJ%+=C\)5[7Z\>1QH/+2-T*W&LS!P)'^='?*]Z:54 -M$S2WM?.(Z=:A2W#=%IQ(=WM?@=;!.E\4`S$]^1)4'DNA<$@*H4*-PU@LNGT8BRKMKG_F>(1/L/^\D)AN -M'/7"4UL[/W5"_I6GMN!\E:"]%-(Z7TR;,N-K3\=2*!R227&1%^A9ISA.ACM= -MYD*,Q;CQX"@K[L9GY2S51+!?X3@62\1$S/X6U)\Y'K<;CWHA494";<-]5H9Y -MC+>4$M`]B(SYF-E<2])8!,-B_(W:0#M3M5P"(DQR"`R4ML72%"3JMXAP"ROV -M(IXW?+Q&ZFO#7Q`\XV]SNKC:U_]H#0S4`X,*YC(,G;[GE"O9M<8J1ZD'\.YI3AT5IB -M`-:-%D6K)ID1@&F1NL%1P&K>_.,`SY;Q2`#2E79:X2*B-,$KAM)8RC?Y!)0H -MO(Y/!0@C4S$!VVO;MX?'7UM=BK:1!XS2!\7AE!8)2:M>+R942,\Q1HLLL\,! -MSV#8G/88"/6S@$*1GO`(<+12A5'(8G4^?K.%YX+DZ`(2I%X!P&5IT!`O3H,0 -M4AXI!%1%X9U"*%@4^>X>#^F4I2JW\8=ZU9`$D%<&HA&O[@-,[*K\$K2N-S$" -MA&J'S&A.X%.3`0J>JE3'PZ9%2XO`DBD3Y25-1"P4FR<8/:IG'BU';3NR&K41 -MA-V3MVR*R3EY6Z@HTKW(M_8OQ:C;^,.Y:D@"E"L#T2A7]P$F;55^"=+6FQ@! -M,K5#9C0GD*G)`(5,5:KCX=*BI45@R91K\I(F(JZ)S1.,&-4SCQ:CMAU9C-H( -MPJ[)6S;%Y)J\+50'B==4[&-1YPKAR1!N2(0D7)5'X#25N:7(FWZQ$B0 -MJ1DRHSF%3'4&2&0J4QT1EY8L+0)+)EV3CS21<4UABU$20 -M=DV^LBDJU^1KH:)(EP!<4^(7YQ(IUY30*9=@I"VA2ELB[IH2'ID2(ID2!IF2 -MR%S3HJ5%8,F4:_*2)B*NB1J2XG'"Z-[%S3@J5%8,FT:_*0 -M)D*NBF@"D>O04'I5)C@=&R]44GAY3-LE#?HB8 -M)"9!,,I333E:>)IF9-UI`@C[(R]A%),W\K)`461[W%XVRN^_ODRYI&$#?YAG -M&*P`_X91:30T]0ZFA(8Y(>CBV,P*P,Z<)JE8!!`:LT;!HF'BXD&DBU7+)>"4 -MTPN,@2(N<$8*8@385%1H.38'(8NS.9RPEXP*KS%YT*@6!(K%A&:$EV!2"+,"F8,)^-`J`QN1#HU@` -M)#(7=O;TN,U.>Z@%55KX1V=UN()X5L+R"*WU#R?SZKPPE-XXO8),[:5*+!B# -MK'KF.'!5IR\^NCI6O&P>0LUJ,$04M:RS,)&BVUIMD:6[%X6MWKUX,SG8:&@; -MHYN-9F&@2%[8XI?;;)<[7;^\+4;F@!9VV`TJBI]@0J4AO/$1:J)C0O)CR5-X10\1'L9B!D9QRKM%B4[4>?F!R1=X6)(AG@XPQ^O4U=ZM,,]#>I8]Z>3WUYOOAG&7AO/B>^ -M^)SQWO/(/LFP7$WAZ3%EA#SDAX@58A($HSG$%]RSWV\_TW<8O(113)[(RP*% -MD6W_\)B_V;S.#KG]VIVZC0=DTX;$`9L:"$DVO0\30J;E%Z-DYHGA$*D_9$9S -M#)-Z&4!!24MU!$Q:H[0(++':))]IPC-*4CP!*9$^\W`IZK?#:U$_@I1;\IU- -M43@FWPL52+ICGKVQ^Z7R5Q_85@V#Q;0R!)9F]7ZGQ*O*(TJV>JEG\:8=&JDA -MBC'-2'%TJ=(8`U5F+QC4NK=[&\]6/M//,-8^3!KJ^42(0MN"(`=M6S''X@E! -MXG`FGA0>@D2;4YX]C-UUK6_E"Y>Z8;'IU(:B4$KI!T1XNCRC!<@P16SN:$-G -M!4!S2,T$GD==VF.ATBJ%1N+,N//QF#0"3DB(-7"!4NH`*51:2Z)@:3%$'5,` -MY(K'4050N$`27O)MGF>;^VR_OSWM[)ZKMYT/+.P/C<7"7C`L#0=]F9+$?KY1 -MHFB=+!;%#"E@AD"1;)@1',OZ4Q`#RU8N.R*#['XL``HQ/9DPAV#R-J@*A,`9 -MVA(DSA!%S)T%QK4X7%I@A0PCY?TAR??9YBX]'W.K5=,V\H"0^J`X<-0B(@ZY^%E#`;)6JC`*6:P&S&^V\*R7'%U` -M6M4K`+A0#1KB56H00LIKA8"J*/Q5"`4+)-_YK?W%`>6//G"N'`2+;D4$+-6J -MO4XI69E#E(+I66!`/"@Y&GA?'<_$VRJM+V1^W#_O-_GB7[@[' -M%U;?86W@`9_L@^40RQH52;&1WDVHDWU.,(H%F%D.O$;3)!4+`[FQK*'`9Y^X -M"%#H<-5R"6CU8V$RD.?;YJ<@2&Y'B@HNP:-!\+(\&D[*&\:(URB\9HP+`D;N -MXO7IFVQ_2I,?]YG5L.I;>4#HWK`X4-9#(4G<[\>$G/?RC-%PVQ1Q>#@<.BL` -MAGR#3*!PUTM[!(1;K]!(G+':0M])PS.`DJP!*5N_#N!R-FR)U[!A#"DG%PJY -MHG!GH10NC(3IX_ZXN=\>DG-F?PA2V\@#"NJ#XB!0BX0D8*\7$QJHYQ@C@9;9 -MX0!K,&Q.>PRN^EE`T4I/>`2H6JG"*&2Q6BR_V<(S6')T`:E4KP#@(C5HB->H -M00@I;Q4"JJ+P52$4+(9\]N<;F]^]H1WS><8F"(EP@`?)VGSB-4WJ>45UB,2F -M>/;@G]]I4QH-;^8O'R03)HR07U20L#]T+B`T!/?XE=J&JARRSPWZQI>('(T_ -MA8@AU2&9.AU4;.$-J\KA\%E5A"'1JMH_2(C*O.*E2)\./FN:H9(;XWE3CYQ` -MG#*]T1!GJ6)"\V+"V_A'#`E_PV,&0EJJN<:*2].**B]->UFGXQ]](G(\_A4F -MDF3%+4S3[J?>5<,2(5H9BDJUNA]0`:OR3!*QWA2)<*D=.BL`B4]-)FB, -MJM(>$Z46+S029Z9=DZ>D$7)/`JS!B55=!P3!:ELR1*N-(>ZH/"=77`[+\\*% -MD?!Q>T$\J&C>V@,N6H;)H:,Y))*2MGY-"*9E'C#".365'-[94R,2",,_:Z90 -M'+1,4P0T=*]`65RS.KW0R,9S?G.R#22HMOJ!"ZL]`EY@[;&D'&(LQ(S"0<92 -M^#`29_OM;K/;YMM-LLU>V,_J];?S@+V#H7&8VP^&I.VP+Q,2/<@W1ISMD\6A -MH"D%S!`8\ADR@F+>8`HB8-W:94=DD-4'AD`AGO>3YA!(]H95`1<\4UN\U)FB -M2+F[T+@6A8L+K9`QI#R<7DWXM&(+;]A8#H?/Q"(,B8;5_D'"6.85+XGZ=/!9 -MU0R5W!C/IWKD!#*5Z8V&2$L5$YH7$Y[*/V)(^"@>,Q"24\TU5FR:5E29:=K+ -M.B7_Z!.1(_*O,)$DN_[_LFL1I-F;39YM?]QGIVURFK9#YF8^$<\R1?!H3U]LA%)X+1FDT93R^3&!%@?ZEN&JM.F,5BN"MG+ -M1#XF(O5\6%L4*3=%X:BX*9Z\`XZ+MI&YW;@6!H+D^\O5&=_9O]NN -M;>0+K=M!L?'<1*(0N>L%1-O;'*/E?#@[;""JP^:T1V-/R0*>=&W"8T';\A5& -M(HBL>'>5ZP"/(57NPZ',J1$)A":?*5-X -M!`ZG*182.E6@+*Z-6[N`R"9@]F9B&UQ-#?6#E%5C!**^&F.).L,(B!F/>XR@ -M\'$DSO?9YD7V]O`XZ2Z[+3WBKS(\"?)VX8C45?L#%&LE[Q2A-DV;!!/U5+"# -M4%BH98;$064Z(B+@ND5(YM.D2_2=4#+N4))1*'%4:P0OC'IKNBCJ<:2=8&C4 -MB\KYA5;8>)(F8*>7^,C11-;I)5R*)GB137@BVY\V*>8E$LQ+6,Q+V,Q+HG1Z -MZQ4AF4\@I^2)*>?&*1?F -M:B]UH@&9K-4SR:6N.JUQTM?1PA;A*,:[!D52<3\[&TNITJ_5' -MS!D=<)2DCM4I1[EP\$IP/N_V=^D.9J3;C3VC?C=(*=2W$1F$5WJ%\!+='%`M -MA&$6I4"KI44B#A6K:I;(-.TF*#*$.E"9')*!K*S_+),SKK(T0ZNM4C@TD=4" -M\+15"S6'%PT5D='YS%`+'D/>-'O8YIO?33_^KFSH#6_5P?%)JT0C45;K#4B5 -MU9SC%=DX8WP(]M+`C8&'GYX5`OC4B8@&>:M6'Y5($S[0=R9)^#])*B%D4"L. -MK`3V&E/EKQ=&UNN%A;F(O%U8!8TGYS8#.;GK9IXQLQB8%"^OL1BT+'N"T-`B -MUU0%U>9)"FOU\'D1J$BKLD$&6I'\R&"V>+W1J`-R:WYR1\ZI\QC51YG!I(7`M.J<60B&32%E<5]T?MP]3=]09&OA'3F6P@@#MHO)(JO8. -MI['*G##$UC2S@E#4TR05BX%)+6L<7BH3%Q\V7:I:+@&AIC$0!HK:R!DH2-%C -MM:C(PJP'82NT'FXFSQD%7F/TI5$L"`*Y'P_I9GM_2&'&M=W:-V)WPQ2#=1N2 -M0VJE7QC9[^:!K/F&J13CJ)8:D4!D@JJ9HN.SFZ;8R.E$@;*X!K.C`9!-T(@* -MLPVON$K]$.56B\#46BW6+,XS8&+&YS8#+GPBB6\/1[C!+#;VD<+E($417$3D -M$KCJ%5:[RSE@2;<^BZ*@;-(B$8>%R3I+/$J6$Q0C(M>M3`[)X);2:Y8)&THQ -MFM%4M2H$32[F`NN:FOS*8W+.CTRD;C(K++%AF8Q69%"<_4ZY5$.Y3#]YIR\RY0C -M'5EXRS+B26\=0D9\ZV!S^LU0`1JM[PQU`3#(?`N\P5/9WEWJD$E2#S -M+?8VN?^_O;/O;B)']O_OW\FKZ,WF;`A+D@&&G;/AL'=8AF4Y,P,<8/:W=V'& -M.';'\<5/XW:(8>"^]JO'EM3==B15-;8D.+L3/TC54E7I4]]6MVT]'N#J?MK* -MK9T5%R&9`G/T%'CCD1ZR5#FZ!>D*9)Z;'`V<>BT(4D3N^5?D4\#-:Q4;2#7Y -MM,5[.1/@:;K*-.*%`"'UAUN.\I1T");4=++XH"9644C-1N=5\VE,X$7?B"P^ -M5(6;L&S!LO6N!<$@-R##V[2E;0/E=ITJNC()D8QB,W&YB,`:#S`]=\(*CI5 -MA8N03(&9RCT&1RH-6:H\W8)T!3+/3:P&3KT6I"HB]_SK,LLF8%D6-I"JLK#6 -MJDJ-F*?I*M2(%P*`U"/;'[LQ>X3*ZA'JS]^89C%H/7+^29)*7,"E?]3.3^34 -M785F#,S7$?1G)2KA2Y6P6Y.\8!ZZ:=<(B-B"?D5FHG_I'D%^QJ1N!:E\C]K\ -MI9Z4:)NNHDU@88!(/NZZ*EO2(UR.T^FV0'%B%H?B;'Q^XH#&!4$<&.%M@;7" -M56C&$%C+/8?!6AJ^=$F[)B*TH6U0F0@HXRRUP`1=6T`JXL->R -MLHV>MBDKV^@7!H#D2\<["I;A7EM;MG%'P1+GRMK2]Q+M$N,2[;+5.PJ6>%?` -ME@A7P)9(5\"6"=]1L`7I"F2>FW8-G'HMZ%9$[OF7YB7"A=0EZH74Y6>XHR!B -MGJ:K4B->")ZD=ONQ**-'B*QNX>>B#+-06GO^](X9%U#I;_,GHVJN0C,&XBO. -MSYJ8X4N1L%N5O&`>VFO72(B(K%];8*)?Z8;_7$[-"D+Y;O\7I!*B;9J*-I&% -MX4GR:;]G+VIIXQ#IS2:)BFUJ$4IL/BI7#K*"!/> -MD[S%N_DWG=,/P]FMSGPVMI>3E7XATK@Z=50L5XQ#"5T;JVN!K\8+5.M7!A^5 -MM@TN1#8)8G#=HS`<5T.<(I>W/,V1&&LO=".D+++\;9FS?AJAEH4`N=!@"T$Y -M-%AM334GSO$T%7;B"PE2*09.7W^@N@1;'0;X7X"@[*)4A('?I\BUV,"%2"7& -M^(@NW85G#0YFZ3T$)@^2_2*$;C2-AKE(3MS*E8X6J+U[6?#?;@6 -MA@ILTI+1N1]9"">BFBH-G8`M*&)6"_L6[)WYT'E2VI1&D@BW- -MM:IU(\=KNIHV\@7A3NY\/%N\MQ*MO&5@I!;3PP(T-P<@LQR/0XD7?O>M[=6P -M8;%2N0)LQ)>.I6>\L2C"D1@--Y>$WGRRDI0A$PI/1&(QRKE*RASQ*X^J-ZPN -M*CMM*,28J)><"HPIL=U).EATYV[?W&7V"(RKE>EBT=4T"Z!L=7P.Q;@2%]^B -MO"J\6*RLNPK-F"\[:Y[S9F@E?(F1=/N2%\Q#*X49$Q'Q%&=;3'0NU-7<\BO8 -M=2NPPEVWUX8R38FVR2G7E!:&)\D'=K^6(-N&R.X!XJ\D2(-06KO^@'WI?U#A -M'[3QJPBZ2Q#,@*@)_"WP,C0IR)H3B5]^Y13P4_%Z?X02 -M.FCOEPUB9&*:ZC&R1/)BUIT7#M?71?L062RGBLIB811*XW)LKJ5@S.@5(5W/2F)@U+`.)6QFE8VTV8P0I -MTRNBC0G0FMLP[4&P6O4BB+!F0!-$[99F-`8YK>5H7.S$%:GMT=.KPE<2SK_8 -MUPS!ZW[-9%O:-D4T)ZF#4UPP?N1?3N=S\M=:+LOV`=*^G"HFYJ51(.'5V!R% -M1!D/B(:H!Q63NKJ+D$Q!6*MY#(39,F0)\G5;TA7(/&NA&P/U<.4M-O>\:K3* -M)O_RK-N`5V;=6ELJ-G:>)JE88U\(7J3^G^EHF"\ZIQ]NV>I3K4=XK-:GB\AJ -MS2R,UL;XW`J_'A=`Z6\,+R);*ZY",P;@J^DY"&'U\*5'V"U+7C`/;;5K-$1$ -MU:^M,-&G=!NYY5V\*U;`Y;MBKR4EFPQM4U2TR2P,",E'T\G`4=JR+L&2G$\8 -M'^3,+@K)Q0B]%`*/#5PB5&*,C]S277C6X-"5WD.@+@]BLM#=HAR&T]%1Z,;` -MQS:D+C8A`35=I!BTJ)=FL*IZ:;!=O9L&?!/6O&DL$`C9YW-'U4LZ!,MT.EE\ -MGA.K*#1GH_-2"C0F<)U@1!8?ML)-6+;@H.5>0\`L#5RRB-V*K(42T%'9AL[` -M-E0M)@4!!9LE%;1<"R-8Q5J8:U?+QHW7A#5LW`L"0NYW^;P83B=YWU'"JG[! -M4ER;.C[*E7$4HNMC]1(*6KS@>J$I^/@T-EV(;!+.9L.C"(C60IPLI[A5#98-K"4@^FU795=;H<3UAQI[N0O"K%?.YR7[!H -M'5Y-D--$K`/")(S^Y;C<1(>,`T!JU$*)R%_--2B&`*Q5GH(05H8I/:IN08*" -MN&:K>X,G&ZK&166;3QDN\\>[^&H6P"57L]628HV6F"DJT6@3WY?$/;L?-2@; -M!TGA'N+/&906P03N.7XSO(H!K'3WVO@)`\,M&'9@F.S!OFE;!2A)1&XT,R$D -M`R*U#%^25-VFY`7S -MT$&.QD%$;&&*ST3/BJUR"U*V=2L8M5NWUYYB38.VB:K8-!:&+\G)_\;3=_8W -MPNI=@B2YFC`NR$N[8))K(W16""HV,(G0$&-V0C<:(J+*W%:8Z%/#C=SR+N$5*^`*7K'7DL)-AK8IJMMD%H8[ -MR4?G72L]2]L%QFPV-2Q.4V,`.O.Q.)1ZYF_?`F\&"XN2T@5`$[Y$%![QYB`+ -M06+LVT3:>3+(2D.&2B$\O8C!(><2R+/"K_#)OK!R)ZVTH?YBX%IRJBZ&1/8B -M9>=L.,HGW;'=)Y2,#N&14YLL(D"551A)]=&YU5@M)H!BVQ191"B:;L*R!<"D -MX34(+[7`I8?-;ZTGE79A-(^`*;9IK27,F@=<4 -M=6D2"\*=W./%/+<3K;QE8*06T\,"-#<'(+,W5L&&Q4KD";,27 -MCJ5GO+$HPI$8#3>7A-Y\LI*4(1,*3T1B,L+BH[;2C$F*B7 -MG`J,*;'=23KK+JWODY1M`V-I.44LEDJ#`)JJ,3F4V]+_O@6W'D`L`NHN03#C -M2T'-0]X<+$.3&`,UA8U),N`)KP -MI9WPB#?I6`@28]PFTLZ3059*+U0*X2D\#`XY%SR>%7[%3O:%%3III0TU%P/7 -MDE-O,22R#RDO+=7:97B#+)4:V%2"%.MP3GD4>0N`47N$J7(7;:HUL+G6H)J+?Q$=B?EPG)O -M;1'>6>T">+<[ -MOW&H:BM'(^0JJEAMF:P^"J">?MZ"H,D46!\T&6U)]R8-[A0U<](+R*\R."OM -MD&M!.^H:B_[^B@-':[2LHC$QC`)@-/0FK9:W*&NA!+16Q7$P$%<)XU/0JWBC -ME&WD@OU9M&X*>$U2TZ:P(#S(??K!3K*2=J%1FDX-# -M&\%"HZ-P`="$-PNY1_P12$.0&O#+(3C8%2"%$B(G#(O?ZQK/`L>Z(O -ML-H)*ZVHO@BXEIZBBR"1/4@YL%1K@_`X.N97,`*9N#5M3:`$ZU -M`8!J`R#5!@FJM0VDG2>#[-1:H!1"5&L(''(O<@-`D1N@%+E!BVHM`JZEI]8B -M2&0/4HXLU=HH/$Z.,-7:"$;)D6O9'$'*YJ@5M3:"4VT$H-H(2+51@FIM`VGG -MR2`[M18HA1#5&@*'W(O<"%#D1BA%;M2B6HN`:^FIM0@2V8.42TNUM@R/DTM, -MM;:$47+I6C:7D+*Y;$6M+>%46P*HM@12;9F@6MM`VGDRR$ZM!4HA1+6&P"'W -M(K<$%+DE2I%;MJC6(N!:>FHM@D3V(*6E6`N/DIA2#49(UXH)*9BMR#0XS0`P -M`[(L08GVN?/-CSIV\BQ([B"*,S!YW"L:H*"AU+,6=5G@($M/DP6>P.YDO"B< -M/P5;Z1(8+ZL3QB)GQ2Z`HK41.M36:FQ\Z^S*&&.AL<%=>-9\D5GWGC<^JT%, -M#*1;F<-P.EIIR+CXB*`;9)?`;Y!= -M)OC-V)M(.T\&64G*4"F$)QXQ..1`+Q1>HGRA\++%;\:.@6O)*;L8$MF= -ME!^&,RNU1ML%QDDV-2Q*4F,`2O*Q.)1-YF_?LFD&"XMJT@5`$[Y4$Q[QIAH+ -M06),VT3:>3+(2JV%2B$\M8;!(>.1LX6JR815&4L^K<&9,`,6VS:O(-3=AV0)@$N<2AAFX]+"Y35D+ -M):"M:(R$@:@RL@4*^M1C^*6PFA%PA6[_.G$J>$U1ER:Q(!S(/>K.!U>H5=XD -M%#:+"8%9S.WXT%>.P*9^"]\Z5^QJ3,#H4]/U[^V,MW+V[D`33DX%8)\SI]SI -ML5[I!!%7CL"JQI9_=JVL]1'"^Z5,'&7"G -MFN8)#Z"5;D^&9)M(-"_.7"'>PB4-AF3#88U#'5-YX%K"])Z^U4NW@:O,PB=7 -M0BHL_,1U(*'EKEMX9["8NVVP\U;7G0W(KD8KNVOPDTK`"27P9#+!W;1-Y9L? -M==8+L*"Y@R#!T,AC7\L`&PDHFP@M[I!%`K)TM%@D">Q#1GJ?V2*_XOM#:JV# -MHV0Y33Q42I,@8JIQ.970,@[^E;0>2CSNZ:Y!,>1/0914U7^^)96W0*TPNJVVE&*\1(S0149;^+;D;B8=>=%WCGM -M%L/>2F%I-`J`NN:D(*@U+#D2MC***VJRZ6.74KPB.A#@U:8-Z>^"MZH7G*AF -M.CP!E&THPWS(LE+:A9%@1\IBE'\E7'<479J_C9I>ZM"A&$5_6I@PRX$*OF -M"2=D5=R>`+$VEVA>G%DIL4(G#4QD8;+&JFI5\\"^;-5[NM>MN@TLI14+N9)0 -M6[$DKCT)UW^1AFH1"/\0OD9#F?&@GN47'FA^=2UXF%^A84[5N[,KD_P^LJZY -M-Q$2?;YDJQASI5A_+%:6LYF^7@K8Z6!!*-;D`:,*%6`T><>)6 -M+00)L&O3:>?)H)6:*@8*P?05-H>L2EH]*^P+6U-?]_+69`5+?<7&M21466R) -M[$/*3C[I3?O#R/951$$7UL3F55RT>_F6V*:AX-#1=A&3* -MGXZ&QP"4U$*6'"NW)UV!S+-4B7%0#U,UXG//H_CJV>1;A$T;T&)L6FM'7<;/ -MTP359_P+P8[4E_/A(N_TA\7;E8)4:Q(`C?4)0?"KV7$DKC&"*ZJU[EN7`MT8 -M$PCR*M/U[^T"-G/V3BS3G9P`O#Y[3KG38Z6T"YH*]DZ9]WAZ&*^YCIK4]N@2*=-$0=XRJ`W^?0Q61<\ -MS?]^E:\I@#@D,UV"8,:/;8:'/"&GA28IUFT^)0'LLI!GX=,+2[#A\LNQ0NH9 -MXU,JS?Z0FFE:PE=W<3(Q,0489Z([D_:\.^^/AA.;;335-BS.JBDB4;8TZ$]9 -M;4SV)5GYW[,D-P00B8B&2Q#,>!)1]Y`O$55HTN+AQE,2P"X;E1@\O=!4(BJ_ -M7(NGEC%>Q=/H#RJ>AJ465&*43$Q-)4:9Z.ZD/2LZ-(9$:A;K?N!J39?`J%N= -M,!9Z*W8!!*Z-T*%J5V/C6[Q7QA@+H0WNPK/F"]2Z][RY6@UB8G#=RAR&T]%* -MCL;%1SQQVAXAG2MX+<7\"GF#&5@];S#8AGY-#;[):=O4%H@SV4?3Z=N+F8W< -M%2W#HKB<'A*ZA3E_8I?CL9U;\6-B1V:JX`&_$DI?*,+R!E.-*BX@:3 -MT)M/-H(S:$*AR4LT1KG6RC)'O$JDUAM4&34[+2C&J*B7FAJ,*K&=23K+YV.K -M6R5YP[`H*B:'A%!NS9^@,BQRRNDA@5.8\R=G.1[[DBK][EE3:V%#8IWF"K`13]HIS_CB3H8C -M+=IM,`F]^60C[8(F%)JX0V.4:S4L<\2K'&J]0?50L]."PHN*>JFIO*@2VYVD -M[)?/K)0>;QD81\7TL"C*S0$H*L?C4&2%WWV+;#5L6,Q3K@`;\65>Z1EOYHEP -M)$:\S26A-Y^LE%[(A,)3>EB,2 -MOA_;?DQ9-@V,I'*"6"`5]@`D+4?D4&FE[WU+;2UV6.C3W`&WX@L_Y1UO^LF@ -M)`:_C>:B/ZVLA%_8O,*3?GC$5H["NN\+EGO:U&#`EZR@U0&Y[`*[WBBSL1 -MB+10MZGL\R62C=(+F$EH*@^)2JX%4":'5_E3G4'%3YEI0=M%@[G4-%TT">U" -MSK/A:)'/.Z=_^8;]`,A5EW!KS8-A:'VB<([6;'K1M&%D5K6V'@OWBKLFGG`< -M-KH'QY([&IN\Y0'(>K"2@>26Y2F,HQ)@XAZ$8VR*=0[%M2"/7DMMHPK?P -M-AK#U9-I`#0AG9G&`O`A\X?A[):E]F1-@^,QGR`>B9D]$(7%B)QJ./>]?_VN -MQ`X/D:4[X%;\T2B]`\`B#TIR0-Q@+OK3RE)#ALPK3.V(12R/DBE2Q;=K"N!+<@ZSRRP+MI .C2ZJFFBX;4T"2&L-BZ74JSBX%V- -M&T*)QD7#-2B&O.FH>\H?D"I,J1%R*Q(4Q#4[T1@!V1"E(S+;W.NKEC^>)=:P -M`*RRAJU6E&3$Q$Q/54:<^!XD'A"):J9@Y"73$>EV+-_>Y= -MJ"MA0V-BZ0JP$6\62L_XU)4GYGY*([=M!\6I\0V:I/&96QFF$H;8TQNI9E -M/3Z@`MT8:%1R5ER&:`Y$4].#,*[JH4R1KUN8R@BLM->?$=$269.VQ$N_A.!R1"[J -M0/C>6Q148X>&4N4.N!5O<);>\>>E"$IJD-QD+OK3RDZ.!LTK1/&)1BSW"BI3 -MQ;-PJN[`>JD,M:(G(X-@>EHQL@3W(:N]#`R2JL@B$$Q4C[(+K+IM"4`4],'( -M!P=?FN)O4TGHS2=+X1@3"/AB,]XFTH -M";WY9*OT@B44JM)#891/060YXET016]P011V6E)ZT5`O1:4736)[D71JO:8J[IS>%GB]/W;=3IK#ME&E+>WI3C+/;*>CL=@H^NYTFN:>WH23TYI.M -MT@N64*A*#X51/@5Q"MKZF")M?4Q;W=.+AGHI*KUH$MN#I+/Y=##OCNW$GFP< -M&DW+2:+A5%J$$%6-RJ7FEC'P+KOU***!4'<+AAUO'&I>\B=B&:#4D+CYS(20 -MS$X6!L\R1'&(2C/W2JH2Q[.8Z@:`]50WU8I6C!21Z>G&2!/>@[P7%RX_^5*V -M#HV\:IIHX"U-0LBKC-?KAE"B<=)P#8HA;U+JGO)'I0I3:J3)EQ_LM"5I -M%QI[Z=30F$N,06C+QN)2HJF_O8NS$2PT"@H7`$UXDX][Q)]Y-`2IL6X#:>?) -M(#L=&"B%$+4?`H?\>);0Q;`B,J[@";,2#=B6.GM70XK=I"577342TGA19?8'B3M -MSNUT'FD7&D/IU-#X28Q!Z,G&XE):J;^]"ZL1+#3*"1<`37@3CGO$GV\T!*FQ -M;0-IY\D@.RT7*(40=1P"A]Q+'1(GM2=). -M/IXMWMOK/=$^1*;*J:)R51B%TK4):4%'IJ+D(R12(E,IC,%[* -MD*7(S"U)5R#S[#5D!-1#UI/(W/,KP64V`0JQ9@.A'&O66E.;D?,T314:^4+P -M)?4DO^PYB%/6/$A*\XGB(IK9!!-:C,RYTO-8P`I])9ZX&"W=@V,)!E'I+2!# -M>;"2!.@6Y"F,<@YR-'3.88M13-)Y5F"11I`"7)K`J+^EL?9T:+P`352#QKL` -M?,D\[;O(3]HZ2"JS:>(BF9H$$YF/R[FDLSC`*KH92EQN2M>@&()14W@*"$T6 -MIB2)N>D$!7'-07"&339LN8G'-L]:R_,'4FJE!8Q**VVUIS3C)&:B*C/.Q/<@ -M\6!RL;#];(QH&QJ#Y131^"L,0NA;CLFE;$O_>Q?M6@#1"*FY!,&,-QV5A_S9 -M*$.3&AQ$8_`L0Y2-J#1SKZA -M&8/2M/0<&*DB?(E2=7N2%\Q#)SD:`Q'QA2DV$[TKMLPM6-E65G!JM[+7IF)- -M@;;)JM@4%@:`Y`X?8S>[A$IR[`^SFW8Q2.[S&>%*;,`2H;4/MM?=A6<-#%V$ -M3V16@I@J=+VD:@_#:.'TDA(H36$4TA!R=QX;K4`V" -MJ:Q[$@YF%=94R;R5B8W"43>1'!%)6Y#*+;'47P]H>0>4!(8E)%5@V&Q5.2=( -MZG15=((+!U`)/I`'9X6;GA9]0JT!&,>A?CM%';LCX@,5&+=#H9-9< -MAF@.3&7E03B392A3Y?&6I3("*]TTIB@F@HY_8@!)HJ`:.S24 -M*G?`K7B#L_2./R]%4%*#Y"9ST9]6=G(T:%XABD\T8KE74)DJGH53=0?62V6H -M%3T9&033TXJ1);@O63O=TV(ZNB"OSKJ+Q6(XVJ@DT3SUF<[%G$=E&V,S,56O6U3UU,P -MU)(1(A\:C&&(B0:S[6GG+UA/5'-_65#>E:,WZA;%T/+G"\PN8=:*KAR&T]%%44?"1W05 -MW0(A?0N]2C%0B=?-H!1WW6"+.CD9^*:JAY-9(%"R=X:3?CZQ_+:SQIY!4[Z< -M?CNHE^;1B*_&ZRTKRKCAJ(MZ&K3#:MV5Z$9QR*UY%@G@9;B3IO@V)ST:?ST$ -M=EP$;DMNM\=@H+90.8DA,71KF$I#M]N^(D^;\HFK];07EG6G\0S -M>H19-^1TD:N%,`NO$N7XW,6*C`M0I-3"B\QJS55HQH!L5IZ#,EF&+TT2;U'R -M@GGHHJBC("*Z@D9GHF]A+W,+5-`U*RB%7+/7HC).@K:I*M\D%H8WR2?33I'/ -MNO/N8FKY^[\-_<)DNCEU9*X;QN%TKXS573J8\0(*B!7!1Z9RS87()H&$KGH4 -MRFDSQ&FR>JO3'(FQ+IHY.LJBZ^=6.>LK&2I9"!(.-5LH\J%FM45UG33'4U7= -M22\D[TKQV\5TD?<=OTJYN6N8U:+F`.1R4;4/KQCU$;NKEEKL@,)E=2X@H[W) -MG?A6@8!O\"Z4\;6@IPGY,'(?C\8NTCU2'J,+^,]`9%_U44]-D`!I,H>B09H, -MMZCGOT`_V>]Q_K+`H-_M/.LN[50];1A:S6"30ZL/U!JD&O#1N"@2YG-O_6%& -M#`VZT@U0&]Y`%5[QQR<+1&JHW$SV^1+)3MD&RR1$U8I")?>"R9/#LSS*SL!B -M*,VTHBTCP5QZFC"2A/8@9W'>G;O\W+/6/C2*ZE-%0ZEF%$)48VPN!5>/AW?= -M;0PJ&A4K+D(RYRF+]O<4 -M(P=HDCHSY@7@2>9BUIT7EA])TMJ'2&8Y550P"Z-0,I=CO1R-@'K(@A29>WX5NI+XH7*YWB^8A4EI,%!71W":4T')DKI5>Q`)4Z*OQ1,6H -M<@^.)1!$2V_!&"J"E2)`MR%/892SEZ/!W`L@?!9>@N&3Q&L%.&Y#7D*HYR]_@R><\CZ$Y5T?N57IA&@_"H3".57&6M- -M?T8,T#3U9\0+P(/,2UOEN0R0Q4M4M;D$TG?I7+F7H)J];$=5+A%PN(2`<`E% -MX#)%];B9[/,EDIU*#)9)B,H0A4KNQ7`)*8-+G`*X;%/[18*Y]#1>)`GM1TZ7 -M3_JHY@$R%/V3/LHFD*9>GZ#08@&IN.U]TL=T#XXE"!HQ;E37@I4@)+MC_I$SE`D]29,2\`#S)_&,[LE"=M&!J+ -MV>30&$RM0>C+1^-2N9G/O6NV&3$T*$HW0&UX@U!XQ1^!+!"IH6\SV>=+)#N5 -M&"R3$)4A"I7XFJ>8`,1=]+ -M5#:!-/7:H]%B`:FX[>TEFN[!L01!(\:IL!:L!"&Y%7D*HYRU2@R?<[B*$9=T -M7L46NI5BFH`7WK;W$B,':)(Z,^8%X$GFR;1#@SK/BV(XG=@+T4J_$$E=G3HJ -ML"O&H>2NC=55!%3C!5(#*X./2M\&%R*;!/&X[E$8F*LA3I'/6Y[F2(RUE\$1 -M4A99&+?,63^E4,M"@&1HL(6@'1JLMJ:B$^=XFDH[\87D4BFFLWS2&>?CZ?RJ -MC6"]93"UP)@>G/VZ.2_:F^.Q$AB&W]TE17/8X(RMN@)LQ)VC%<]XD-,(1S*D -MW'02>O/I"NT:/J$P]"DNHQQ*IYDCKL6RVMNW/%;MX"K+^*B7D$*,+[%=2$H% -M8Y$O=,78*1;3^57?VKZZ7S",73-U.&]7&_>B[[JQ6I7J-?%R+]PVP8=3=;T+ -MD4VZ$W>M1SWXNR;$R;`XG#1'8NP5VC5NRF+HVL_'60=IL"X+787">EN^LF&] -M55QU_(7C*H6^D#RYA617*:B=L^$HGW3'>2>?]*;]X62P4H,WMPZ@)JR8)J0. -M-)MTI/^J<5TA.E;$P45J7!5*"']7NP;%D`MK5WK*B;`KPI0`5;APW)W?K\I_L_DO1Z\?+^CS_2UT;$^,U[^\0?KW>^HD]NW=O7>O'7><`GV2Y[ -MYR;U]BY]/L?/,-*XM[>\PD_W/KC6A'B^9RN,B^9O98PUTRNI]^(.NE -M\XR%D:3X2[IZU#'V=UEKK=EN4[/=TOI-UO[W[&PZSX;9<"('E,PR*_(^-;5__/KHYJONX8=? -MKN_M'<^X%\^&[,\GTNSRG*1D-L^[_6S&+#(#VM+:VYN)4?3OB;3OW]M5N;Y+ -M\_=R.ORZ8Q[CXWO(WW$QI9G^Y.[Q8VCZ\?W'W"7\YN#.CKO\M<(U/3/$&7:7;:)5.E25QW"YD3?7/5F7JA0YL=<"=7?%@HU_%T -M^B#'6;"A_'Z%4T3;M6NRR1FRWQ6+E#GADS;]3SL[%Q.#6SJK?GY2H16#52.1 -M3,BPP=Q[4Z/!"AC0E*RQ3^^Z8NE_Y.Y8M_`_23"P]<.77GL+[PUW[7!^KSF` -M=T46E3YG];'HG,VGXPYMH=>0VRW5D-N?H8;XAMP.L8;<-E+Y=K(U -MY#:PAMR.L(;<]JPAMQUKR&WG&G)[JVI(;>';U!"\A;>ZAMQVKR%W6JHA=SY# -M#;EC5T/N;'$-N1-B#;ECI/*=9&O('6`-N1-A#;GC64/N.-:0.\XUY,Y6U9#: -MPK>I(7@+;W4-N>-80V9O!WR#B\:7%I/R!1[Q-26%'KO2VHQ:^689.@&$1B8; -M2+ZB>AB6RW1=543JX]`JB5BE-`MFE02J`EL`UP_9"M.N"]QE":]RC,4J7N$E -MR3,Z>'T1FXESQ6H&)(I8XDWQ$5ID5J[2<@%^_)6LP(\?5ZT3TTOVBV4XZ8TN -M^OD_'][__N'S%W2UB%D&\2[Z:M'L7KE6JF,(>Z5P/Z]8*\UN -M6=7U:B^M6BF5K+ERJ?@F21LK1??1U>MDY_'W=%'(@9.'+Y[^_/P!O[[VX^,7 -MS^C?E_C\X_&/#^EJD7/6VFF]&[KP:DN&\-M%SN=:+?NBHIK9.)39*#PQ -M%#G)GY99R=XH\U*O_7O7[O__'\BZ^IWGW*N]O:]_(2*5K(P):46_8(8_^Z0J -M^L,GWQ,=1L9Q338YR+A2N<;&S`P=9+/Y<++(ADPO?1)Q&+\=DOB#)7/ -M=6?1'10G&?7$S@[][TFVPM/B>M7Y$74+=]WW#Y^1P3Q\\N`Q;4#L?V7X5'J: -M2OE%MF0C.,_GQ+^SR_Z;\JQQ59S,`R8;L^)\>+8P:4U%^;6'S!/WGS]Z<;"W -M=UW&4\[M1#^'T1@O6M$5+ARWM\?&0Q;=\JX)W+V]/V:'`Z:)54V@TV>'/I`/ -M]"O8Y@O:$)4KR""^VRWS3Z):.]\"VJ]8EM5EN-/CJ?Z`Y?J#UG+]2TI?F=): -M%C_0LU@FI]SV$6\?R`?&O1+&"P\:,J%$W,XC%FP)'UYM>GW:;S&==4XOAJ,^ -M]0_=D:)D*K>GJBV%'\OW!S2CLL,A>?N1-@`2$'JDW9V=7M&;SO*3C/\]8BX1 -MT_]#=E@8K^NS?O'@Z;.'!]GA:7;XFY@N>TG-5W]*!F`8DF_SX+4>F6A),U"VHX]7+AZKE2`:\7SOT8T;)>)V:?HP;[QZ_?KXE^LD -M2?_KA#\\R`JJ)?2V=T4ZR_?(6Q>G/-UE(]$F+[J]E3LF#5)SN&N"3^A)99^U -MJ/%+RDXZ&KV-MF^3_>UOU>0[-N.A;B!AU"JC1M,L(_6;Y5OVZ#G_\^*_?R+_ -MI??79+1Y-<;3BX5\.)SHSV93_9E,A?.\]_;P)=%J[%2$/:`Z\JQ+WN_?(]6` -M:#3Z9TE?80]FW:*@#XJWP]D]OH7"77^OC`$ATG(VG2\R_ERK_N4QLGVQ9TM7 -MW8*4I-YT-)T7!S:G*C2D"_+V5;`\(A%9T'?Y.009X=%QN2M%\EK?1C7;::WH -M28>1A<9I!SN>F%/GX9-_/7[^],E/#Y^\I)K_=]+Z$[/,ES5O](_O.\\?$F'\ -M\,'+`S/E,N;K-\1U<]*;/,[^G-U\]S9<.,?;O?]Q__&-'.%*M(/KO^JO7 -MV>NO?F&'Y0^O\PK&XR:MLV?*_E_]^=O_% -M"VUD=[7'XGB\QV`^X3W6="B7JAD6PHIZ,+?I07/SQ^5KZKY;*DV>^D_2+>+OVC-H7ODQCN-A%5 -M:UU4FI/_9!7`&@/@SN5CJ.A8K16+:6.C+#OM3B8Y7>Q[Y%@\N@J,U["_+XFLS7\A7N -M$FKY8+<>;WT&^OCI3*_TCTCDZ5EF#DS$P,)-ZC#23V6-=U:- -MI4].@"?3A7!6S5<,@1<3S5O\.$V^4D*Z6YR3$;%K3/3XLBU==3.RT,NBK>9<=X4TI -M;KB977I!LI<=]MYDAZ-=O[^\Z/G#Y\]??[RH*+@I-UG1%D5N7B:+>@Y4F/?QJGS7L"9 -M"R,K4JFTQI_OBIVUXOCH^-[QX(T3YBCG=UG5;4*K>'?>$(0*^?E0!/QWF]OP -MR5?::!<25=9\K'85;ZWN6[J]UI6_LWYDC:-?X3UZJD!==$+IPJ4XD6U4"W__ -M^,5+N<58[JO*"WY7*%36O'$7M:Y272[A5\]:^MH>>?7R?CDKOF%;321MY'1E -M"?,#XM]LOWN:G>>CV:UQ=Y(-"[)T?KL8DJRABV>0DZ!W%SDYYI`6Q4&^+Z:7 -M_>VXG[\[GER,1DVG4OE\/B5^/9M>3/H9-4S[%G279-$=3H:3`>V3[8^'14&? -MR./OTX4[ZO;R<3XAJS=?+DYVL[_]Z=9=8\2'(]]!\\6V7QS_>IS)?\?[QA'$ -M%0'^CU@[&R[I6,$I+#9GC/-<.FZLIW]U=8_W];-@C%M\3 -M1W3?TDY#YIY\?LA.$/>SRR$YGC@*'43%F+K2DAD98*:Y..WB9CHBYP_D7DV? -MXE6^R-;@^"UY:+Q*E@3/SV(Q9]I3GB[+,_72KZ]^.7KUZ][>Z]?7?SE^3?[] -MZ7@@=X:FLT8;VNZ+E1VY-M6"W9>$)>]TM$L:[,Z1QJL:])V&"_7D/*+X2(ZJ -MC?/XX\>[BUV%^;*-.9WCC]5S?MKMC=H"(0NU'%UY:G+]^/J!?EE-U8:R[2X? -MX%?T\,PUQZ^/C__0OTO&\%$%B!RMN''\ZM=C?@_`OMZ)EL'#BS=-&R7*0>J` -M*^X[8DU);LBX0VN3=U -M.AHY?%S>ZF,*J[/AI+%==DC6(1DZW;>;Y71WY=NOOR:'7>:]K'<^GO:SBS_/ -M+Y?9[Y^RU^H,K0G2?6-#EKE,JA@R[^P/]S+-.^;@>H1J9[/G=0/:@&F8YM5+ -MK"W/K1Q7&3>+$55/\'CYJ@].-"'=Z6%F*P[2T-PXFK;YQNX*O/_#0[&13!^* -MC50N"L@*%5;O"?(H\&EOJ!=+KAR>3Z=O=[XZU"0I92J5-AWBQIQ>8^'MR?"J -MT6@*PYT[;(G60G%C,/WS7`2$?D"0C>`/=0/??/,-J8/#R=LBNVD$M/OGN47O -M2A;8=:*'9)WH55Y^/;'?_V4,2--0SC]<,MB#"-7%XS$C,D@?J1N -M>/KL)1M']?`C&P\L/S@=^]__H8>C\^>/#@_S3]GR0]/LES:')PW_XS0`^=TD -M34?\C\4!B_/N7#L@?9IIA[-,,-K-+L/,X(J->\T2>7_G*W:$^6^5U[6G5Q^( -M$XHLQY/5`.2"J?/R_O-'#^D&Z0J+]_:_.]E??\0_9B^IKB9.'^2+[((HUGG! -M-"\;"J,W%<1$%A&IT\W^Q:Y=\,NC%T0?TZ_RSHB)?$(L$8P/+KKS[F21Y]1( -M=U%:F@]/+VACJNZ+?'1V*,X=B"0X?4^D\EMZWM"=3$G[.;%$1D$/?<0OK]#K -M'-SU0G\)P=BY__S!/Q__BXI&H<*N"V!<%S5B10KT>UF-,>7M1LP']%)4:8^L -M?FE0$*)N@+198V%4CFBT8@"C=0-8EMWI`JUW7J[K_!_9]V*B+[GJBEMA0:P/ -M)X>*/AF]=8$M2V&+-%5C,9<%6R6L&=6T),QEL3F\-%:/+*[FJ_PD1U,97+L; -MK]`B)_M7K2K%5[5@WF_<[W5DK:1WI9G7J,U#B8O4AN[]]=6O)_3R*+](>N.8 -MR%_N#M*6F.[G4K3L_?[R)_IU!X?'B_'LTW%W3#Q\N$?^':O/9+`#7_;Y33KE -MJ\T#XG.1;8Z.CN4*SK/#0W$%\.B(/";I0;0/'4%EJJ5@8RBBJ^_!/Q\^^*'S -MX.F3?SQ^]//SAQU=FV6"4.O:L,&NT7=KWN^_&U[9AE'CRE9R%\"RG9W1\@:Y -MJR="(E2V9L8[(@%6N9^?7E5[E07?S7U4E0WP?2ROK=U1_L8/=(T=/$@\JN -MS\US]E^Q!\\>S]A_EXS">WNS??%@N;]3#R>]/U>>%^[SJ=2SXF!?^Y`-_\:J -MA\^?/WU^0H32>[8?.J47:+*][[++X>*<*)N,W7FE?=Z##F"U=;4QJ)T=?])N -MNZ"$]QA>KSNA%X]ZYW19#R?LBHK/(/B5%CZ4AOXT5.*^,GY]9?2&;]J+^;/1 -M\6P1`^-[::/\;)%USQ;Y7*WQD]WLKKY6C4WP\E;EV@:1OC][C>>X:)L5%S-Z -M(4*[<,3W2_G%YZI -M+%02P6PZ&;UG^45OO2Y5.2ORI;/XB#)Y4Z5(ZC=\5LK>5:%:&RFR++FR(-/( -M>XOI_+T(7GF,2O#6'5UO9[J3W^C4'9_0NT?(WW7G1=SLL^=/'SV__].+@]5- -MM;NG=D28]J[]_>?'/[[LR/O@KNI,1L('=)+]U'V;LY.EO6L_OOSQ\=^?WW_^ -MF-])5PXE$U>@**KYIW#477:OV=TD_)[3\M,FI\.)['PBRR;]FB+M`#NR,=VZ -M/N'[P'QEFY]7(+WXUI7Q*CE`PZOJ.S]6?%!\Q6?_UGV8:.6')QH_QBBW(8W/ -MJ.SQ(BKW!B4<'((F74C")A_2_2_E6_I,?[??7735N_09?5>!23&*OKZC'JM$ -M_>ZJP8ACUHZR8]0D0W_J0V37*TZ,6\[IC9POGS]F]VPJI*P:A_RXB\@TNF$J -M7V)6Y!L'I5Y2FX4VGOY[C[6D+]Q3;M\U -M9D78JW\1&KNN..R=R+M]U7-U)VGYFMRAYG=@L[.HSH,?']Y_(NY"9ZM$;D0U -MO"\-'+&/4VL7^#YFJPRS4G*E>;V5NHEU-IQJ7T`HQ<&<^&(\JS5;\V;EFPQM -MVC:WT+X@[FIS1N,KFUB.L=[CJG;TR^E<[/+VS:T6W;F%+=YJ]7N64]6:KFA` -MOS.0Z/Y186--;UQMHB4OVV6@.=F0LI7W=G:JE^2UE?8=USAL,[0W'8_IIN>0 -M7MQ=Y!-2J]AYB.I>4(%_0V:,S++F3&A2J7C"DM\"(#6#/E(OJ8I"/E1`5I`*J\))["K -MV_*K$#6-D1G?CRB>3::4<7HKTEOG'!V.4H%*$+*J6&Z>T\`*L)3!,K$RKW*E -M"1&-"WWU:EVUVLSUTI#[C2E<3D=JP!U]LBH\F@_H/BP5BS7D,WE3OGC>UY1T -M&0#ME6FOJS]G'RG8Z;\;GM`=,AX"]I=4E_/%F`@6^E_VNGAP0G7&V93JB[.I -MD!WLP)$.&W_CY<,T:'9WVQ%!.Y6@KZDCUT#/Z"DE\ -MR*>L/S,.IKM`3HR[0CTS.M1=,Z:IK7^[GO[DMO[DCNHTZY^I3N2)<0S^7#O$ -MK-`:%V;;PFA:GB75.7=2NQG)8QD:-_<<=R\6T_$WB_RHUR4'#GBQ-GC&Q%7= -M=V*Q&M]P2UQU99ZD:S$[/73?/I;?,I625'5.ZS\R>Q@R_3NMPX -M5I,K'[*S(-+WV3^?/OEO\60:<: -M*CZ"5Y90&4R+@EKVJ==4855]EB]CGXW-C,O$LF;P6R"R\F8,=:=+5MZ=D)57 -MSK/RHGW9?_DADQ>ZL_*ZJUH*#?7+J%9RRE?5+Z-34PFK[GB)W639L7+E@UX+ -MXG6#53=9XEA%DV5-JTM-Z=-45&C5T\N9J()ZZ:J4,>.47N]:/<5GPZQ4(;W] -MBOHJ)F34(KU;);9J6ZZ*0#=@5?#8Q6`KJ2 -MKT8G$[%7H]/L74'RSA^S[D'V@+F(?I"TF(YSTG^2Y^SN8\[S`O2 -MY91TF8Y&Y!6&T?ZT=T'OY&9W?;#F_.?=Z7T?U2L[_,X-1A]R>B0?G-\]N!?+^3M:6^N:GM4O)M4&J]LNW_]?_>O;D,_6&O3K#>=Y[1=[<:? -MX^O'VNZO]JIZG1#>N+>`>))>:SLF&7-,BM'%C-`E/RK.C>^CIV34OQ*?E"[U -MS)1?Q^IK]?^7/'Q5V7DHA_>+N,*GWF/7>.G=ZN+R1*TOTU1K#+`&S5:H)*OU -M)"^N;MU\,/E."M*.O -M%&QQ3,_8O4[BPVO$+KVU:3C1W^._JU$<$7-_IR?^]#HA63HLE&1-\<\.S.;3 -M=\,^N]>JZ$Z&B_=<;F33B2Z$F;05^P!T;9].W^5'#3]]0\>K+D[0NZ<6%1W? -M^,,.)-NSC_S3&=\__,?C)P_9!W&SOS7\P`4]PLY.&3R;0Y:-UQ^K8G-G1T7. -MYBBJ]?K#5*VR:.B_;Y;#(:2C?%XM\3-PW)@&_1F'YXGWQKXP,FG[` -M;7'`-HI. 0); - - /* See what GID it ended up with. This is our "valid" GID. */ - assert(fstat(fd, &st) == 0); - _default_gid = st.st_gid; - - /* Find a GID for which fchown() fails. This is our "invalid" GID. */ - _invalid_gid = -1; - /* This loop stops when we wrap the gid or examine 10,000 gids. */ - for (gid = 1, n = 1; gid == n && n < 10000 ; n++, gid++) { - if (fchown(fd, uid, gid) != 0) { - _invalid_gid = gid; - break; - } - } - - /* - * Find a GID for which fchown() succeeds, but which isn't the - * default. This is the "alternate" gid. - */ - _alt_gid = -1; - for (gid = 0, n = 0; gid == n && n < 10000 ; n++, gid++) { - /* _alt_gid must be different than _default_gid */ - if (gid == (gid_t)_default_gid) - continue; - if (fchown(fd, uid, gid) == 0) { - _alt_gid = gid; - break; - } - } - close(fd); -} - -static int -altgid(void) -{ - searchgid(); - return (_alt_gid); -} - -static int -invalidgid(void) -{ - searchgid(); - return (_invalid_gid); -} - -static int -defaultgid(void) -{ - searchgid(); - return (_default_gid); -} -#endif - -/* - * Exercise permission and ownership restores. - * In particular, try to exercise a bunch of border cases related - * to files/dirs that already exist, SUID/SGID bits, etc. - */ - -DEFINE_TEST(test_write_disk_perms) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - skipping("archive_write_disk interface"); -#else - struct archive *a; - struct archive_entry *ae; - struct stat st; - uid_t original_uid; - uid_t try_to_change_uid; - - assertUmask(UMASK); - - /* - * Set ownership of the current directory to the group of this - * process. Otherwise, the SGID tests below fail if the - * /tmp directory is owned by a group to which we don't belong - * and we're on a system where group ownership is inherited. - * (Because we're not allowed to SGID files with defaultgid().) - */ - assertEqualInt(0, chown(".", getuid(), getgid())); - - /* Create an archive_write_disk object. */ - assert((a = archive_write_disk_new()) != NULL); - - /* Write a regular file to it. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file_0755"); - archive_entry_set_mode(ae, S_IFREG | 0777); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_finish_entry(a)); - archive_entry_free(ae); - - /* Write a regular file, then write over it. */ - /* For files, the perms should get updated. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file_overwrite_0144"); - archive_entry_set_mode(ae, S_IFREG | 0777); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_write_finish_entry(a)); - /* Check that file was created with different perms. */ - assertEqualInt(0, stat("file_overwrite_0144", &st)); - failure("file_overwrite_0144: st.st_mode=%o", st.st_mode); - assert((st.st_mode & 07777) != 0144); - /* Overwrite, this should change the perms. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file_overwrite_0144"); - archive_entry_set_mode(ae, S_IFREG | 0144); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_write_finish_entry(a)); - - /* Write a regular dir. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "dir_0514"); - archive_entry_set_mode(ae, S_IFDIR | 0514); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_write_finish_entry(a)); - - /* Overwrite an existing dir. */ - /* For dir, the first perms should get left. */ - assertMakeDir("dir_overwrite_0744", 0744); - /* Check original perms. */ - assertEqualInt(0, stat("dir_overwrite_0744", &st)); - failure("dir_overwrite_0744: st.st_mode=%o", st.st_mode); - assertEqualInt(st.st_mode & 0777, 0744); - /* Overwrite shouldn't edit perms. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "dir_overwrite_0744"); - archive_entry_set_mode(ae, S_IFDIR | 0777); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_write_finish_entry(a)); - /* Make sure they're unchanged. */ - assertEqualInt(0, stat("dir_overwrite_0744", &st)); - failure("dir_overwrite_0744: st.st_mode=%o", st.st_mode); - assertEqualInt(st.st_mode & 0777, 0744); - - /* For dir, the owner should get left when not overwriting. */ - assertMakeDir("dir_owner", 0744); - - if (getuid() == 0) { - original_uid = getuid() + 1; - try_to_change_uid = getuid(); - assertEqualInt(0, chown("dir_owner", original_uid, getgid())); - } else { - original_uid = getuid(); - try_to_change_uid = getuid() + 1; - } - - /* Check original owner. */ - assertEqualInt(0, stat("dir_owner", &st)); - failure("dir_owner: st.st_uid=%d", st.st_uid); - assertEqualInt(st.st_uid, original_uid); - /* Shouldn't try to edit the owner when no overwrite option is set. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "dir_owner"); - archive_entry_set_mode(ae, S_IFDIR | 0744); - archive_entry_set_uid(ae, try_to_change_uid); - archive_write_disk_set_options(a, - ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_NO_OVERWRITE); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_write_finish_entry(a)); - /* Make sure they're unchanged. */ - assertEqualInt(0, stat("dir_owner", &st)); - failure("dir_owner: st.st_uid=%d", st.st_uid); - assertEqualInt(st.st_uid, original_uid); - - /* Write a regular file with SUID bit, but don't use _EXTRACT_PERM. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file_no_suid"); - archive_entry_set_mode(ae, S_IFREG | S_ISUID | 0777); - archive_write_disk_set_options(a, 0); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_finish_entry(a)); - - /* Write a regular file with ARCHIVE_EXTRACT_PERM. */ - assert(archive_entry_clear(ae) != NULL); - archive_entry_copy_pathname(ae, "file_0777"); - archive_entry_set_mode(ae, S_IFREG | 0777); - archive_write_disk_set_options(a, ARCHIVE_EXTRACT_PERM); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_finish_entry(a)); - - /* Write a regular file with ARCHIVE_EXTRACT_PERM & SUID bit */ - assert(archive_entry_clear(ae) != NULL); - archive_entry_copy_pathname(ae, "file_4742"); - archive_entry_set_mode(ae, S_IFREG | S_ISUID | 0742); - archive_entry_set_uid(ae, getuid()); - archive_write_disk_set_options(a, ARCHIVE_EXTRACT_PERM); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_finish_entry(a)); - - /* - * Write a regular file with ARCHIVE_EXTRACT_PERM & SUID bit, - * but wrong uid. POSIX says you shouldn't restore SUID bit - * unless the UID could be restored. - */ - assert(archive_entry_clear(ae) != NULL); - archive_entry_copy_pathname(ae, "file_bad_suid"); - archive_entry_set_mode(ae, S_IFREG | S_ISUID | 0742); - archive_entry_set_uid(ae, getuid() + 1); - archive_write_disk_set_options(a, ARCHIVE_EXTRACT_PERM); - assertA(0 == archive_write_header(a, ae)); - /* - * Because we didn't ask for owner, the failure to - * restore SUID shouldn't return a failure. - * We check below to make sure SUID really wasn't set. - * See more detailed comments below. - */ - failure("Opportunistic SUID failure shouldn't return error."); - assertEqualInt(0, archive_write_finish_entry(a)); - - if (getuid() != 0) { - assert(archive_entry_clear(ae) != NULL); - archive_entry_copy_pathname(ae, "file_bad_suid2"); - archive_entry_set_mode(ae, S_IFREG | S_ISUID | 0742); - archive_entry_set_uid(ae, getuid() + 1); - archive_write_disk_set_options(a, - ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_OWNER); - assertA(0 == archive_write_header(a, ae)); - /* Owner change should fail here. */ - failure("Non-opportunistic SUID failure should return error."); - assertEqualInt(ARCHIVE_WARN, archive_write_finish_entry(a)); - } - - /* Write a regular file with ARCHIVE_EXTRACT_PERM & SGID bit */ - assert(archive_entry_clear(ae) != NULL); - archive_entry_copy_pathname(ae, "file_perm_sgid"); - archive_entry_set_mode(ae, S_IFREG | S_ISGID | 0742); - archive_entry_set_gid(ae, defaultgid()); - archive_write_disk_set_options(a, ARCHIVE_EXTRACT_PERM); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - failure("Setting SGID bit should succeed here."); - assertEqualIntA(a, 0, archive_write_finish_entry(a)); - - if (altgid() == -1) { - /* - * Current user must belong to at least two groups or - * else we can't test setting the GID to another group. - */ - skipping("Current user can't test gid restore: must belong to more than one group."); - } else { - /* - * Write a regular file with ARCHIVE_EXTRACT_PERM & SGID bit - * but without ARCHIVE_EXTRACT_OWNER. - */ - /* - * This is a weird case: The user has asked for permissions to - * be restored but not asked for ownership to be restored. As - * a result, the default file creation will create a file with - * the wrong group. There are several possible behaviors for - * libarchive in this scenario: - * = Set the SGID bit. It is wrong and a security hole to - * set SGID with the wrong group. Even POSIX thinks so. - * = Implicitly set the group. I don't like this. - * = drop the SGID bit and warn (the old libarchive behavior) - * = drop the SGID bit and don't warn (the current libarchive - * behavior). - * The current behavior sees SGID/SUID restore when you - * don't ask for owner restore as an "opportunistic" - * action. That is, libarchive should do it if it can, - * but if it can't, it's not an error. - */ - assert(archive_entry_clear(ae) != NULL); - archive_entry_copy_pathname(ae, "file_alt_sgid"); - archive_entry_set_mode(ae, S_IFREG | S_ISGID | 0742); - archive_entry_set_uid(ae, getuid()); - archive_entry_set_gid(ae, altgid()); - archive_write_disk_set_options(a, ARCHIVE_EXTRACT_PERM); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - failure("Setting SGID bit should fail because of group mismatch but the failure should be silent because we didn't ask for the group to be set."); - assertEqualIntA(a, 0, archive_write_finish_entry(a)); - - /* - * As above, but add _EXTRACT_OWNER to verify that it - * does succeed. - */ - assert(archive_entry_clear(ae) != NULL); - archive_entry_copy_pathname(ae, "file_alt_sgid_owner"); - archive_entry_set_mode(ae, S_IFREG | S_ISGID | 0742); - archive_entry_set_uid(ae, getuid()); - archive_entry_set_gid(ae, altgid()); - archive_write_disk_set_options(a, - ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_OWNER); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - failure("Setting SGID bit should succeed here."); - assertEqualIntA(a, ARCHIVE_OK, archive_write_finish_entry(a)); - } - - /* - * Write a regular file with ARCHIVE_EXTRACT_PERM & SGID bit, - * but wrong GID. POSIX says you shouldn't restore SGID bit - * unless the GID could be restored. - */ - if (invalidgid() == -1) { - /* This test always fails for root. */ - printf("Running as root: Can't test SGID failures.\n"); - } else { - assert(archive_entry_clear(ae) != NULL); - archive_entry_copy_pathname(ae, "file_bad_sgid"); - archive_entry_set_mode(ae, S_IFREG | S_ISGID | 0742); - archive_entry_set_gid(ae, invalidgid()); - archive_write_disk_set_options(a, ARCHIVE_EXTRACT_PERM); - assertA(0 == archive_write_header(a, ae)); - failure("This SGID restore should fail without an error."); - assertEqualIntA(a, 0, archive_write_finish_entry(a)); - - assert(archive_entry_clear(ae) != NULL); - archive_entry_copy_pathname(ae, "file_bad_sgid2"); - archive_entry_set_mode(ae, S_IFREG | S_ISGID | 0742); - archive_entry_set_gid(ae, invalidgid()); - archive_write_disk_set_options(a, - ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_OWNER); - assertA(0 == archive_write_header(a, ae)); - failure("This SGID restore should fail with an error."); - assertEqualIntA(a, ARCHIVE_WARN, archive_write_finish_entry(a)); - } - - /* Set ownership should fail if we're not root. */ - if (getuid() == 0) { - printf("Running as root: Can't test setuid failures.\n"); - } else { - assert(archive_entry_clear(ae) != NULL); - archive_entry_copy_pathname(ae, "file_bad_owner"); - archive_entry_set_mode(ae, S_IFREG | 0744); - archive_entry_set_uid(ae, getuid() + 1); - archive_write_disk_set_options(a, ARCHIVE_EXTRACT_OWNER); - assertA(0 == archive_write_header(a, ae)); - assertEqualIntA(a,ARCHIVE_WARN,archive_write_finish_entry(a)); - } - - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - archive_entry_free(ae); - - /* Test the entries on disk. */ - assertEqualInt(0, stat("file_0755", &st)); - failure("file_0755: st.st_mode=%o", st.st_mode); - assertEqualInt(st.st_mode & 07777, 0755); - - assertEqualInt(0, stat("file_overwrite_0144", &st)); - failure("file_overwrite_0144: st.st_mode=%o", st.st_mode); - assertEqualInt(st.st_mode & 07777, 0144); - - assertEqualInt(0, stat("dir_0514", &st)); - failure("dir_0514: st.st_mode=%o", st.st_mode); - assertEqualInt(st.st_mode & 07777, 0514); - - assertEqualInt(0, stat("dir_overwrite_0744", &st)); - failure("dir_overwrite_0744: st.st_mode=%o", st.st_mode); - assertEqualInt(st.st_mode & 0777, 0744); - - assertEqualInt(0, stat("file_no_suid", &st)); - failure("file_0755: st.st_mode=%o", st.st_mode); - assertEqualInt(st.st_mode & 07777, 0755); - - assertEqualInt(0, stat("file_0777", &st)); - failure("file_0777: st.st_mode=%o", st.st_mode); - assertEqualInt(st.st_mode & 07777, 0777); - - /* SUID bit should get set here. */ - assertEqualInt(0, stat("file_4742", &st)); - failure("file_4742: st.st_mode=%o", st.st_mode); - assertEqualInt(st.st_mode & 07777, S_ISUID | 0742); - - /* SUID bit should NOT have been set here. */ - assertEqualInt(0, stat("file_bad_suid", &st)); - failure("file_bad_suid: st.st_mode=%o", st.st_mode); - assertEqualInt(st.st_mode & 07777, 0742); - - /* Some things don't fail if you're root, so suppress this. */ - if (getuid() != 0) { - /* SUID bit should NOT have been set here. */ - assertEqualInt(0, stat("file_bad_suid2", &st)); - failure("file_bad_suid2: st.st_mode=%o", st.st_mode); - assertEqualInt(st.st_mode & 07777, 0742); - } - - /* SGID should be set here. */ - assertEqualInt(0, stat("file_perm_sgid", &st)); - failure("file_perm_sgid: st.st_mode=%o", st.st_mode); - assertEqualInt(st.st_mode & 07777, S_ISGID | 0742); - - if (altgid() != -1) { - /* SGID should not be set here. */ - assertEqualInt(0, stat("file_alt_sgid", &st)); - failure("file_alt_sgid: st.st_mode=%o", st.st_mode); - assertEqualInt(st.st_mode & 07777, 0742); - - /* SGID should be set here. */ - assertEqualInt(0, stat("file_alt_sgid_owner", &st)); - failure("file_alt_sgid: st.st_mode=%o", st.st_mode); - assertEqualInt(st.st_mode & 07777, S_ISGID | 0742); - } - - if (invalidgid() != -1) { - /* SGID should NOT be set here. */ - assertEqualInt(0, stat("file_bad_sgid", &st)); - failure("file_bad_sgid: st.st_mode=%o", st.st_mode); - assertEqualInt(st.st_mode & 07777, 0742); - /* SGID should NOT be set here. */ - assertEqualInt(0, stat("file_bad_sgid2", &st)); - failure("file_bad_sgid2: st.st_mode=%o", st.st_mode); - assertEqualInt(st.st_mode & 07777, 0742); - } - - if (getuid() != 0) { - assertEqualInt(0, stat("file_bad_owner", &st)); - failure("file_bad_owner: st.st_mode=%o", st.st_mode); - assertEqualInt(st.st_mode & 07777, 0744); - failure("file_bad_owner: st.st_uid=%d getuid()=%d", - st.st_uid, getuid()); - /* The entry had getuid()+1, but because we're - * not root, we should not have been able to set that. */ - assertEqualInt(st.st_uid, getuid()); - } -#endif -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_disk_secure.c b/thirdparty/libarchive/libarchive/test/test_write_disk_secure.c deleted file mode 100644 index 44b9ea0d5..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_disk_secure.c +++ /dev/null @@ -1,307 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_disk_secure.c 201247 2009-12-30 05:59:21Z kientzle $"); - -#define UMASK 022 - -/* - * Exercise security checks that should prevent certain - * writes. - */ - -DEFINE_TEST(test_write_disk_secure) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - skipping("archive_write_disk security checks not supported on Windows"); -#else - struct archive *a; - struct archive_entry *ae; - struct stat st; -#if defined(HAVE_LCHMOD) && defined(HAVE_SYMLINK) && \ - defined(S_IRUSR) && defined(S_IWUSR) && defined(S_IXUSR) - int working_lchmod; -#endif - - /* Start with a known umask. */ - assertUmask(UMASK); - - /* Create an archive_write_disk object. */ - assert((a = archive_write_disk_new()) != NULL); - - /* Write a regular dir to it. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "dir"); - archive_entry_set_mode(ae, S_IFDIR | 0777); - assert(0 == archive_write_header(a, ae)); - archive_entry_free(ae); - assert(0 == archive_write_finish_entry(a)); - - /* Write a symlink to the dir above. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "link_to_dir"); - archive_entry_set_mode(ae, S_IFLNK | 0777); - archive_entry_set_symlink(ae, "dir"); - archive_write_disk_set_options(a, 0); - assert(0 == archive_write_header(a, ae)); - assert(0 == archive_write_finish_entry(a)); - - /* - * Without security checks, we should be able to - * extract a file through the link. - */ - assert(archive_entry_clear(ae) != NULL); - archive_entry_copy_pathname(ae, "link_to_dir/filea"); - archive_entry_set_mode(ae, S_IFREG | 0777); - assert(0 == archive_write_header(a, ae)); - assert(0 == archive_write_finish_entry(a)); - - /* But with security checks enabled, this should fail. */ - assert(archive_entry_clear(ae) != NULL); - archive_entry_copy_pathname(ae, "link_to_dir/fileb"); - archive_entry_set_mode(ae, S_IFREG | 0777); - archive_write_disk_set_options(a, ARCHIVE_EXTRACT_SECURE_SYMLINKS); - failure("Extracting a file through a symlink should fail here."); - assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae)); - archive_entry_free(ae); - assert(0 == archive_write_finish_entry(a)); - - /* Write an absolute symlink to /tmp. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "/tmp/libarchive_test-test_write_disk_secure-absolute_symlink"); - archive_entry_set_mode(ae, S_IFLNK | 0777); - archive_entry_set_symlink(ae, "/tmp"); - archive_write_disk_set_options(a, 0); - assert(0 == archive_write_header(a, ae)); - assert(0 == archive_write_finish_entry(a)); - - /* With security checks enabled, this should fail. */ - assert(archive_entry_clear(ae) != NULL); - archive_entry_copy_pathname(ae, "/tmp/libarchive_test-test_write_disk_secure-absolute_symlink/libarchive_test-test_write_disk_secure-absolute_symlink_path.tmp"); - archive_entry_set_mode(ae, S_IFREG | 0777); - archive_write_disk_set_options(a, ARCHIVE_EXTRACT_SECURE_SYMLINKS); - failure("Extracting a file through an absolute symlink should fail here."); - assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae)); - archive_entry_free(ae); - assertFileNotExists("/tmp/libarchive_test-test_write_disk_secure-absolute_symlink/libarchive_test-test_write_disk_secure-absolute_symlink_path.tmp"); - assert(0 == unlink("/tmp/libarchive_test-test_write_disk_secure-absolute_symlink")); - unlink("/tmp/libarchive_test-test_write_disk_secure-absolute_symlink_path.tmp"); - - /* Create another link. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "link_to_dir2"); - archive_entry_set_mode(ae, S_IFLNK | 0777); - archive_entry_set_symlink(ae, "dir"); - archive_write_disk_set_options(a, 0); - assert(0 == archive_write_header(a, ae)); - assert(0 == archive_write_finish_entry(a)); - - /* - * With symlink check and unlink option, it should remove - * the link and create the dir. - */ - assert(archive_entry_clear(ae) != NULL); - archive_entry_copy_pathname(ae, "link_to_dir2/filec"); - archive_entry_set_mode(ae, S_IFREG | 0777); - archive_write_disk_set_options(a, ARCHIVE_EXTRACT_SECURE_SYMLINKS | ARCHIVE_EXTRACT_UNLINK); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assert(0 == archive_write_finish_entry(a)); - - /* Create a nested symlink. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "dir/nested_link_to_dir"); - archive_entry_set_mode(ae, S_IFLNK | 0777); - archive_entry_set_symlink(ae, "../dir"); - archive_write_disk_set_options(a, 0); - assert(0 == archive_write_header(a, ae)); - assert(0 == archive_write_finish_entry(a)); - - /* But with security checks enabled, this should fail. */ - assert(archive_entry_clear(ae) != NULL); - archive_entry_copy_pathname(ae, "dir/nested_link_to_dir/filed"); - archive_entry_set_mode(ae, S_IFREG | 0777); - archive_write_disk_set_options(a, ARCHIVE_EXTRACT_SECURE_SYMLINKS); - failure("Extracting a file through a symlink should fail here."); - assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae)); - archive_entry_free(ae); - assert(0 == archive_write_finish_entry(a)); - - /* - * Without security checks, extracting a dir over a link to a - * dir should follow the link. - */ - /* Create a symlink to a dir. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "link_to_dir3"); - archive_entry_set_mode(ae, S_IFLNK | 0777); - archive_entry_set_symlink(ae, "dir"); - archive_write_disk_set_options(a, 0); - assert(0 == archive_write_header(a, ae)); - assert(0 == archive_write_finish_entry(a)); - /* Extract a dir whose name matches the symlink. */ - assert(archive_entry_clear(ae) != NULL); - archive_entry_copy_pathname(ae, "link_to_dir3"); - archive_entry_set_mode(ae, S_IFDIR | 0777); - assert(0 == archive_write_header(a, ae)); - assert(0 == archive_write_finish_entry(a)); - /* Verify link was followed. */ - assertEqualInt(0, lstat("link_to_dir3", &st)); - assert(S_ISLNK(st.st_mode)); - archive_entry_free(ae); - - /* - * As above, but a broken link, so the link should get replaced. - */ - /* Create a symlink to a dir. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "link_to_dir4"); - archive_entry_set_mode(ae, S_IFLNK | 0777); - archive_entry_set_symlink(ae, "nonexistent_dir"); - archive_write_disk_set_options(a, 0); - assert(0 == archive_write_header(a, ae)); - assert(0 == archive_write_finish_entry(a)); - /* Extract a dir whose name matches the symlink. */ - assert(archive_entry_clear(ae) != NULL); - archive_entry_copy_pathname(ae, "link_to_dir4"); - archive_entry_set_mode(ae, S_IFDIR | 0777); - assert(0 == archive_write_header(a, ae)); - assert(0 == archive_write_finish_entry(a)); - /* Verify link was replaced. */ - assertEqualInt(0, lstat("link_to_dir4", &st)); - assert(S_ISDIR(st.st_mode)); - archive_entry_free(ae); - - /* - * As above, but a link to a non-dir, so the link should get replaced. - */ - /* Create a regular file and a symlink to it */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "non_dir"); - archive_entry_set_mode(ae, S_IFREG | 0777); - archive_write_disk_set_options(a, 0); - assert(0 == archive_write_header(a, ae)); - assert(0 == archive_write_finish_entry(a)); - /* Create symlink to the file. */ - archive_entry_copy_pathname(ae, "link_to_dir5"); - archive_entry_set_mode(ae, S_IFLNK | 0777); - archive_entry_set_symlink(ae, "non_dir"); - archive_write_disk_set_options(a, 0); - assert(0 == archive_write_header(a, ae)); - assert(0 == archive_write_finish_entry(a)); - /* Extract a dir whose name matches the symlink. */ - assert(archive_entry_clear(ae) != NULL); - archive_entry_copy_pathname(ae, "link_to_dir5"); - archive_entry_set_mode(ae, S_IFDIR | 0777); - assert(0 == archive_write_header(a, ae)); - assert(0 == archive_write_finish_entry(a)); - /* Verify link was replaced. */ - assertEqualInt(0, lstat("link_to_dir5", &st)); - assert(S_ISDIR(st.st_mode)); - archive_entry_free(ae); - - /* - * Without security checks, we should be able to - * extract an absolute path. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "/tmp/libarchive_test-test_write_disk_secure-absolute_path.tmp"); - archive_entry_set_mode(ae, S_IFREG | 0777); - assert(0 == archive_write_header(a, ae)); - assert(0 == archive_write_finish_entry(a)); - assertFileExists("/tmp/libarchive_test-test_write_disk_secure-absolute_path.tmp"); - assert(0 == unlink("/tmp/libarchive_test-test_write_disk_secure-absolute_path.tmp")); - - /* But with security checks enabled, this should fail. */ - assert(archive_entry_clear(ae) != NULL); - archive_entry_copy_pathname(ae, "/tmp/libarchive_test-test_write_disk_secure-absolute_path.tmp"); - archive_entry_set_mode(ae, S_IFREG | 0777); - archive_write_disk_set_options(a, ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS); - failure("Extracting an absolute path should fail here."); - assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae)); - archive_entry_free(ae); - assert(0 == archive_write_finish_entry(a)); - assertFileNotExists("/tmp/libarchive_test-test_write_disk_secure-absolute_path.tmp"); - - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Test the entries on disk. */ - assert(0 == lstat("dir", &st)); - failure("dir: st.st_mode=%o", st.st_mode); - assert((st.st_mode & 0777) == 0755); - - assert(0 == lstat("link_to_dir", &st)); - failure("link_to_dir: st.st_mode=%o", st.st_mode); - assert(S_ISLNK(st.st_mode)); -#if defined(HAVE_SYMLINK) && defined(HAVE_LCHMOD) && \ - defined(S_IRUSR) && defined(S_IWUSR) && defined(S_IXUSR) - /* Verify if we are able to lchmod() */ - if (symlink("dir", "testlink_to_dir") == 0) { - if (lchmod("testlink_to_dir", - S_IRUSR | S_IWUSR | S_IXUSR) != 0) { - switch (errno) { - case ENOTSUP: - case ENOSYS: -#if ENOTSUP != EOPNOTSUPP - case EOPNOTSUPP: -#endif - working_lchmod = 0; - break; - default: - working_lchmod = 1; - } - } else - working_lchmod = 1; - } else - working_lchmod = 0; - - if (working_lchmod) { - failure("link_to_dir: st.st_mode=%o", st.st_mode); - assert((st.st_mode & 07777) == 0755); - } -#endif - - assert(0 == lstat("dir/filea", &st)); - failure("dir/filea: st.st_mode=%o", st.st_mode); - assert((st.st_mode & 07777) == 0755); - - failure("dir/fileb: This file should not have been created"); - assert(0 != lstat("dir/fileb", &st)); - - assert(0 == lstat("link_to_dir2", &st)); - failure("link_to_dir2 should have been re-created as a true dir"); - assert(S_ISDIR(st.st_mode)); - failure("link_to_dir2: Implicit dir creation should obey umask, but st.st_mode=%o", st.st_mode); - assert((st.st_mode & 0777) == 0755); - - assert(0 == lstat("link_to_dir2/filec", &st)); - assert(S_ISREG(st.st_mode)); - failure("link_to_dir2/filec: st.st_mode=%o", st.st_mode); - assert((st.st_mode & 07777) == 0755); - - failure("dir/filed: This file should not have been created"); - assert(0 != lstat("dir/filed", &st)); -#endif -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_disk_secure744.c b/thirdparty/libarchive/libarchive/test/test_write_disk_secure744.c deleted file mode 100644 index 9b12d4cf1..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_disk_secure744.c +++ /dev/null @@ -1,95 +0,0 @@ -/*- - * Copyright (c) 2003-2007,2016 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -#define UMASK 022 - -/* - * Github Issue #744 describes a bug in the sandboxing code that - * causes very long pathnames to not get checked for symlinks. - */ - -DEFINE_TEST(test_write_disk_secure744) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - skipping("archive_write_disk security checks not supported on Windows"); -#else - struct archive *a; - struct archive_entry *ae; - size_t buff_size = 8192; - char *buff = malloc(buff_size); - char *p = buff; - int n = 0; - int t; - - assert(buff != NULL); - - /* Start with a known umask. */ - assertUmask(UMASK); - - /* Create an archive_write_disk object. */ - assert((a = archive_write_disk_new()) != NULL); - archive_write_disk_set_options(a, ARCHIVE_EXTRACT_SECURE_SYMLINKS); - - while (p + 500 < buff + buff_size) { - memset(p, 'x', 100); - p += 100; - p[0] = '\0'; - - buff[0] = ((n / 1000) % 10) + '0'; - buff[1] = ((n / 100) % 10)+ '0'; - buff[2] = ((n / 10) % 10)+ '0'; - buff[3] = ((n / 1) % 10)+ '0'; - buff[4] = '_'; - ++n; - - /* Create a symlink pointing to the testworkdir */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, buff); - archive_entry_set_mode(ae, S_IFREG | 0777); - archive_entry_copy_symlink(ae, testworkdir); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - *p++ = '/'; - snprintf(p, buff_size - (p - buff), "target%d", n); - - /* Try to create a file through the symlink, should fail. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, buff); - archive_entry_set_mode(ae, S_IFDIR | 0777); - - t = archive_write_header(a, ae); - archive_entry_free(ae); - failure("Attempt to create target%d via %d-character symlink should have failed", n, (int)strlen(buff)); - if(!assertEqualInt(ARCHIVE_FAILED, t)) { - break; - } - } - archive_free(a); - free(buff); -#endif -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_disk_secure745.c b/thirdparty/libarchive/libarchive/test/test_write_disk_secure745.c deleted file mode 100644 index 870b06475..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_disk_secure745.c +++ /dev/null @@ -1,79 +0,0 @@ -/*- - * Copyright (c) 2003-2007,2016 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -#define UMASK 022 - -/* - * Github Issue #745 describes a bug in the sandboxing code that - * allows one to use a symlink to edit the permissions on a file or - * directory outside of the sandbox. - */ - -DEFINE_TEST(test_write_disk_secure745) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - skipping("archive_write_disk security checks not supported on Windows"); -#else - struct archive *a; - struct archive_entry *ae; - - /* Start with a known umask. */ - assertUmask(UMASK); - - /* Create an archive_write_disk object. */ - assert((a = archive_write_disk_new()) != NULL); - archive_write_disk_set_options(a, ARCHIVE_EXTRACT_SECURE_SYMLINKS); - - /* The target dir: The one we're going to try to change permission on */ - assertMakeDir("target", 0700); - - /* The sandbox dir we're going to run inside of. */ - assertMakeDir("sandbox", 0700); - assertChdir("sandbox"); - - /* Create a symlink pointing to the target directory */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "sym"); - archive_entry_set_mode(ae, AE_IFLNK | 0777); - archive_entry_copy_symlink(ae, "../target"); - assert(0 == archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Try to alter the target dir through the symlink; this should fail. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "sym"); - archive_entry_set_mode(ae, S_IFDIR | 0777); - assert(0 == archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Permission of target dir should not have changed. */ - assertFileMode("../target", 0700); - - assert(0 == archive_write_close(a)); - archive_write_free(a); -#endif -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_disk_secure746.c b/thirdparty/libarchive/libarchive/test/test_write_disk_secure746.c deleted file mode 100644 index 99cb882c0..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_disk_secure746.c +++ /dev/null @@ -1,128 +0,0 @@ -/*- - * Copyright (c) 2003-2007,2016 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -#define UMASK 022 - -/* - * Github Issue #746 describes a problem in which hardlink targets are - * not adequately checked and can be used to modify entries outside of - * the sandbox. - */ - -/* - * Verify that ARCHIVE_EXTRACT_SECURE_NODOTDOT disallows '..' in hardlink - * targets. - */ -DEFINE_TEST(test_write_disk_secure746a) -{ - struct archive *a; - struct archive_entry *ae; - - /* Start with a known umask. */ - assertUmask(UMASK); - - /* The target directory we're going to try to affect. */ - assertMakeDir("target", 0700); - assertMakeFile("target/foo", 0700, "unmodified"); - - /* The sandbox dir we're going to work within. */ - assertMakeDir("sandbox", 0700); - assertChdir("sandbox"); - - /* Create an archive_write_disk object. */ - assert((a = archive_write_disk_new()) != NULL); - archive_write_disk_set_options(a, ARCHIVE_EXTRACT_SECURE_NODOTDOT); - - /* Attempt to hardlink to the target directory. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "bar"); - archive_entry_set_mode(ae, AE_IFREG | 0777); - archive_entry_set_size(ae, 8); - archive_entry_copy_hardlink(ae, "../target/foo"); - assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae)); - assertEqualInt(ARCHIVE_FATAL, archive_write_data(a, "modified", 8)); - archive_entry_free(ae); - - /* Verify that target file contents are unchanged. */ - assertTextFileContents("unmodified", "../target/foo"); - - assertEqualIntA(a, ARCHIVE_FATAL, archive_write_close(a)); - archive_write_free(a); -} - -/* - * Verify that ARCHIVE_EXTRACT_SECURE_NOSYMLINK disallows symlinks in hardlink - * targets. - */ -DEFINE_TEST(test_write_disk_secure746b) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - skipping("archive_write_disk security checks not supported on Windows"); -#else - struct archive *a; - struct archive_entry *ae; - - /* Start with a known umask. */ - assertUmask(UMASK); - - /* The target directory we're going to try to affect. */ - assertMakeDir("target", 0700); - assertMakeFile("target/foo", 0700, "unmodified"); - - /* The sandbox dir we're going to work within. */ - assertMakeDir("sandbox", 0700); - assertChdir("sandbox"); - - /* Create an archive_write_disk object. */ - assert((a = archive_write_disk_new()) != NULL); - archive_write_disk_set_options(a, ARCHIVE_EXTRACT_SECURE_SYMLINKS); - - /* Create a symlink to the target directory. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "symlink"); - archive_entry_set_mode(ae, AE_IFLNK | 0777); - archive_entry_copy_symlink(ae, "../target"); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Attempt to hardlink to the target directory via the symlink. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "bar"); - archive_entry_set_mode(ae, AE_IFREG | 0777); - archive_entry_set_size(ae, 8); - archive_entry_copy_hardlink(ae, "symlink/foo"); - assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae)); - assertEqualIntA(a, ARCHIVE_FATAL, archive_write_data(a, "modified", 8)); - archive_entry_free(ae); - - /* Verify that target file contents are unchanged. */ - assertTextFileContents("unmodified", "../target/foo"); - - assertEqualIntA(a, ARCHIVE_FATAL, archive_write_close(a)); - archive_write_free(a); -#endif -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_disk_sparse.c b/thirdparty/libarchive/libarchive/test/test_write_disk_sparse.c deleted file mode 100644 index 36ecf3220..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_disk_sparse.c +++ /dev/null @@ -1,290 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_disk_sparse.c 201247 2009-12-30 05:59:21Z kientzle $"); - -/* - * Write a file using archive_write_data call, read the file - * back and verify the contents. The data written includes large - * blocks of nulls, so it should exercise the sparsification logic - * if ARCHIVE_EXTRACT_SPARSE is enabled. - */ -static void -verify_write_data(struct archive *a, int sparse) -{ - static const char data[]="abcdefghijklmnopqrstuvwxyz"; - struct stat st; - struct archive_entry *ae; - size_t buff_size = 64 * 1024; - char *buff, *p; - const char *msg = sparse ? "sparse" : "non-sparse"; - FILE *f; - - buff = malloc(buff_size); - assert(buff != NULL); - if (buff == NULL) - return; - - ae = archive_entry_new(); - assert(ae != NULL); - archive_entry_set_size(ae, 8 * buff_size); - archive_entry_set_pathname(ae, "test_write_data"); - archive_entry_set_mode(ae, AE_IFREG | 0755); - assertEqualIntA(a, 0, archive_write_header(a, ae)); - - /* Use archive_write_data() to write three relatively sparse blocks. */ - - /* First has non-null data at beginning. */ - memset(buff, 0, buff_size); - memcpy(buff, data, sizeof(data)); - failure("%s", msg); - assertEqualInt(buff_size, archive_write_data(a, buff, buff_size)); - - /* Second has non-null data in the middle. */ - memset(buff, 0, buff_size); - memcpy(buff + buff_size / 2 - 3, data, sizeof(data)); - failure("%s", msg); - assertEqualInt(buff_size, archive_write_data(a, buff, buff_size)); - - /* Third has non-null data at the end. */ - memset(buff, 0, buff_size); - memcpy(buff + buff_size - sizeof(data), data, sizeof(data)); - failure("%s", msg); - assertEqualInt(buff_size, archive_write_data(a, buff, buff_size)); - - failure("%s", msg); - assertEqualIntA(a, 0, archive_write_finish_entry(a)); - - /* Test the entry on disk. */ - assert(0 == stat(archive_entry_pathname(ae), &st)); - assertEqualInt(st.st_size, 8 * buff_size); - f = fopen(archive_entry_pathname(ae), "rb"); - assert(f != NULL); - if (f == NULL) { - free(buff); - return; - } - - /* Check first block. */ - assertEqualInt(buff_size, fread(buff, 1, buff_size, f)); - failure("%s", msg); - assertEqualMem(buff, data, sizeof(data)); - for (p = buff + sizeof(data); p < buff + buff_size; ++p) { - failure("offset: %d, %s", (int)(p - buff), msg); - if (!assertEqualInt(0, *p)) - break; - } - - /* Check second block. */ - assertEqualInt(buff_size, fread(buff, 1, buff_size, f)); - for (p = buff; p < buff + buff_size; ++p) { - failure("offset: %d, %s", (int)(p - buff), msg); - if (p == buff + buff_size / 2 - 3) { - assertEqualMem(p, data, sizeof(data)); - p += sizeof(data); - } else if (!assertEqualInt(0, *p)) - break; - } - - /* Check third block. */ - assertEqualInt(buff_size, fread(buff, 1, buff_size, f)); - for (p = buff; p < buff + buff_size - sizeof(data); ++p) { - failure("offset: %d, %s", (int)(p - buff), msg); - if (!assertEqualInt(0, *p)) - break; - } - failure("%s", msg); - assertEqualMem(buff + buff_size - sizeof(data), data, sizeof(data)); - - /* XXX more XXX */ - - assertEqualInt(0, fclose(f)); - archive_entry_free(ae); - free(buff); -} - -/* - * As above, but using the archive_write_data_block() call. - */ -static void -verify_write_data_block(struct archive *a, int sparse) -{ - static const char data[]="abcdefghijklmnopqrstuvwxyz"; - struct stat st; - struct archive_entry *ae; - size_t buff_size = 64 * 1024; - char *buff, *p; - const char *msg = sparse ? "sparse" : "non-sparse"; - FILE *f; - - buff = malloc(buff_size); - assert(buff != NULL); - if (buff == NULL) - return; - - ae = archive_entry_new(); - assert(ae != NULL); - archive_entry_set_size(ae, 8 * buff_size); - archive_entry_set_pathname(ae, "test_write_data_block"); - archive_entry_set_mode(ae, AE_IFREG | 0755); - assertEqualIntA(a, 0, archive_write_header(a, ae)); - - /* Use archive_write_data_block() to write three - relatively sparse blocks. */ - - /* First has non-null data at beginning. */ - memset(buff, 0, buff_size); - memcpy(buff, data, sizeof(data)); - failure("%s", msg); - assertEqualInt(ARCHIVE_OK, - archive_write_data_block(a, buff, buff_size, 100)); - - /* Second has non-null data in the middle. */ - memset(buff, 0, buff_size); - memcpy(buff + buff_size / 2 - 3, data, sizeof(data)); - failure("%s", msg); - assertEqualInt(ARCHIVE_OK, - archive_write_data_block(a, buff, buff_size, buff_size + 200)); - - /* Third has non-null data at the end. */ - memset(buff, 0, buff_size); - memcpy(buff + buff_size - sizeof(data), data, sizeof(data)); - failure("%s", msg); - assertEqualInt(ARCHIVE_OK, - archive_write_data_block(a, buff, buff_size, buff_size * 2 + 300)); - - failure("%s", msg); - assertEqualIntA(a, 0, archive_write_finish_entry(a)); - - /* Test the entry on disk. */ - assert(0 == stat(archive_entry_pathname(ae), &st)); - assertEqualInt(st.st_size, 8 * buff_size); - f = fopen(archive_entry_pathname(ae), "rb"); - assert(f != NULL); - if (f == NULL) { - free(buff); - return; - } - - /* Check 100-byte gap at beginning */ - assertEqualInt(100, fread(buff, 1, 100, f)); - failure("%s", msg); - for (p = buff; p < buff + 100; ++p) { - failure("offset: %d, %s", (int)(p - buff), msg); - if (!assertEqualInt(0, *p)) - break; - } - - /* Check first block. */ - assertEqualInt(buff_size, fread(buff, 1, buff_size, f)); - failure("%s", msg); - assertEqualMem(buff, data, sizeof(data)); - for (p = buff + sizeof(data); p < buff + buff_size; ++p) { - failure("offset: %d, %s", (int)(p - buff), msg); - if (!assertEqualInt(0, *p)) - break; - } - - /* Check 100-byte gap */ - assertEqualInt(100, fread(buff, 1, 100, f)); - failure("%s", msg); - for (p = buff; p < buff + 100; ++p) { - failure("offset: %d, %s", (int)(p - buff), msg); - if (!assertEqualInt(0, *p)) - break; - } - - /* Check second block. */ - assertEqualInt(buff_size, fread(buff, 1, buff_size, f)); - for (p = buff; p < buff + buff_size; ++p) { - failure("offset: %d, %s", (int)(p - buff), msg); - if (p == buff + buff_size / 2 - 3) { - assertEqualMem(p, data, sizeof(data)); - p += sizeof(data); - } else if (!assertEqualInt(0, *p)) - break; - } - - /* Check 100-byte gap */ - assertEqualInt(100, fread(buff, 1, 100, f)); - failure("%s", msg); - for (p = buff; p < buff + 100; ++p) { - failure("offset: %d, %s", (int)(p - buff), msg); - if (!assertEqualInt(0, *p)) - break; - } - - /* Check third block. */ - assertEqualInt(buff_size, fread(buff, 1, buff_size, f)); - for (p = buff; p < buff + buff_size - sizeof(data); ++p) { - failure("offset: %d, %s", (int)(p - buff), msg); - if (!assertEqualInt(0, *p)) - break; - } - failure("%s", msg); - assertEqualMem(buff + buff_size - sizeof(data), data, sizeof(data)); - - /* Check another block size beyond last we wrote. */ - assertEqualInt(buff_size, fread(buff, 1, buff_size, f)); - failure("%s", msg); - for (p = buff; p < buff + buff_size; ++p) { - failure("offset: %d, %s", (int)(p - buff), msg); - if (!assertEqualInt(0, *p)) - break; - } - - - /* XXX more XXX */ - - assertEqualInt(0, fclose(f)); - free(buff); - archive_entry_free(ae); -} - -DEFINE_TEST(test_write_disk_sparse) -{ - struct archive *ad; - - - /* - * The return values, etc, of the write data functions - * shouldn't change regardless of whether we've requested - * sparsification. (The performance and pattern of actual - * write calls to the disk should vary, of course, but the - * client program shouldn't see any difference.) - */ - assert((ad = archive_write_disk_new()) != NULL); - archive_write_disk_set_options(ad, 0); - verify_write_data(ad, 0); - verify_write_data_block(ad, 0); - assertEqualInt(0, archive_write_free(ad)); - - assert((ad = archive_write_disk_new()) != NULL); - archive_write_disk_set_options(ad, ARCHIVE_EXTRACT_SPARSE); - verify_write_data(ad, 1); - verify_write_data_block(ad, 1); - assertEqualInt(0, archive_write_free(ad)); - -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_disk_symlink.c b/thirdparty/libarchive/libarchive/test/test_write_disk_symlink.c deleted file mode 100644 index aeadfee8a..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_disk_symlink.c +++ /dev/null @@ -1,269 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_disk_symlink.c 201247 2009-12-30 05:59:21Z kientzle $"); - -/* - * Exercise symlink recreation. - */ -DEFINE_TEST(test_write_disk_symlink) -{ - static const char data[]="abcdefghijklmnopqrstuvwxyz"; - struct archive *ad; - struct archive_entry *ae; - int r; - - if (!canSymlink()) { - skipping("Symlinks not supported"); - return; - } - - /* Write entries to disk. */ - assert((ad = archive_write_disk_new()) != NULL); - - /* - * First, create a regular file then a symlink to that file. - */ - - /* Regular file: link1a */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "link1a"); - archive_entry_set_mode(ae, AE_IFREG | 0755); - archive_entry_set_size(ae, sizeof(data)); - assertEqualIntA(ad, 0, archive_write_header(ad, ae)); - assertEqualInt(sizeof(data), - archive_write_data(ad, data, sizeof(data))); - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - archive_entry_free(ae); - - /* Symbolic Link: link1b -> link1a */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "link1b"); - archive_entry_set_mode(ae, AE_IFLNK | 0642); - archive_entry_set_size(ae, 0); - archive_entry_copy_symlink(ae, "link1a"); - assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); - if (r >= ARCHIVE_WARN) - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - archive_entry_free(ae); - - /* - * We should be able to do this in the other order as well, - * of course. - */ - - /* Symbolic link: link2b -> link2a */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "link2b"); - archive_entry_set_mode(ae, AE_IFLNK | 0642); - archive_entry_unset_size(ae); - archive_entry_copy_symlink(ae, "link2a"); - assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); - if (r >= ARCHIVE_WARN) { - assertEqualInt(ARCHIVE_WARN, - archive_write_data(ad, data, sizeof(data))); - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - } - archive_entry_free(ae); - - /* File: link2a */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "link2a"); - archive_entry_set_mode(ae, AE_IFREG | 0755); - archive_entry_set_size(ae, sizeof(data)); - assertEqualIntA(ad, 0, archive_write_header(ad, ae)); - assertEqualInt(sizeof(data), - archive_write_data(ad, data, sizeof(data))); - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - archive_entry_free(ae); - - /* Symbolic link: dot -> . */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "dot"); - archive_entry_set_mode(ae, AE_IFLNK | 0642); - archive_entry_unset_size(ae); - archive_entry_copy_symlink(ae, "."); - assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); - if (r >= ARCHIVE_WARN) - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - archive_entry_free(ae); - - /* Symbolic link: dotdot -> .. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "dotdot"); - archive_entry_set_mode(ae, AE_IFLNK | 0642); - archive_entry_unset_size(ae); - archive_entry_copy_symlink(ae, ".."); - assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); - if (r >= ARCHIVE_WARN) - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - archive_entry_free(ae); - - /* Symbolic link: slash -> / */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "slash"); - archive_entry_set_mode(ae, AE_IFLNK | 0642); - archive_entry_unset_size(ae); - archive_entry_copy_symlink(ae, "/"); - assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); - if (r >= ARCHIVE_WARN) - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - archive_entry_free(ae); - - /* Symbolic link: sldot -> /. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "sldot"); - archive_entry_set_mode(ae, AE_IFLNK | 0642); - archive_entry_unset_size(ae); - archive_entry_copy_symlink(ae, "/."); - assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); - if (r >= ARCHIVE_WARN) - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - archive_entry_free(ae); - - /* Symbolic link: sldotdot -> /.. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "sldotdot"); - archive_entry_set_mode(ae, AE_IFLNK | 0642); - archive_entry_unset_size(ae); - archive_entry_copy_symlink(ae, "/.."); - assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); - if (r >= ARCHIVE_WARN) - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - archive_entry_free(ae); - - /* Dir: d1 */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "d1"); - archive_entry_set_mode(ae, AE_IFDIR | 0777); - archive_entry_unset_size(ae); - assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); - if (r >= ARCHIVE_WARN) - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - archive_entry_free(ae); - - /* Symbolic link: d1nosl -> d1 */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "d1nosl"); - archive_entry_set_mode(ae, AE_IFLNK | 0642); - archive_entry_unset_size(ae); - archive_entry_copy_symlink(ae, "d1"); - assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); - if (r >= ARCHIVE_WARN) - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - archive_entry_free(ae); - - /* Symbolic link: d1slash -> d1/ */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "d1slash"); - archive_entry_set_mode(ae, AE_IFLNK | 0642); - archive_entry_unset_size(ae); - archive_entry_copy_symlink(ae, "d1/"); - assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); - if (r >= ARCHIVE_WARN) - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - archive_entry_free(ae); - - /* Symbolic link: d1sldot -> d1/. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "d1sldot"); - archive_entry_set_mode(ae, AE_IFLNK | 0642); - archive_entry_unset_size(ae); - archive_entry_copy_symlink(ae, "d1/."); - assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); - if (r >= ARCHIVE_WARN) - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - archive_entry_free(ae); - - /* Symbolic link: d1slddot -> d1/.. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "d1slddot"); - archive_entry_set_mode(ae, AE_IFLNK | 0642); - archive_entry_unset_size(ae); - archive_entry_copy_symlink(ae, "d1/.."); - assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); - if (r >= ARCHIVE_WARN) - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - archive_entry_free(ae); - - /* Symbolic link: d1dir -> d1 */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "d1dir"); - archive_entry_set_mode(ae, AE_IFLNK | 0642); - archive_entry_set_symlink_type(ae, AE_SYMLINK_TYPE_DIRECTORY); - archive_entry_unset_size(ae); - archive_entry_copy_symlink(ae, "d1"); - assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); - if (r >= ARCHIVE_WARN) - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - archive_entry_free(ae); - - /* Symbolic link: d1file -> d1 */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "d1file"); - archive_entry_set_mode(ae, AE_IFLNK | 0642); - archive_entry_set_symlink_type(ae, AE_SYMLINK_TYPE_FILE); - archive_entry_unset_size(ae); - archive_entry_copy_symlink(ae, "d1"); - assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); - if (r >= ARCHIVE_WARN) - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); - archive_entry_free(ae); - - assertEqualInt(ARCHIVE_OK, archive_write_free(ad)); - - /* Test the entries on disk. */ - - /* Test #1 */ - assertIsReg("link1a", -1); - assertFileSize("link1a", sizeof(data)); - assertFileNLinks("link1a", 1); - assertIsSymlink("link1b", "link1a", 0); - - /* Test #2: Should produce identical results to test #1 */ - assertIsReg("link2a", -1); - assertFileSize("link2a", sizeof(data)); - assertFileNLinks("link2a", 1); - assertIsSymlink("link2b", "link2a", 0); - - /* Test #3: Special symlinks */ - assertIsSymlink("dot", ".", 1); - assertIsSymlink("dotdot", "..", 1); - assertIsSymlink("slash", "/", 1); - assertIsSymlink("sldot", "/.", 1); - assertIsSymlink("sldotdot", "/..", 1); - - /* Test #4: Directory symlink mixed with . and .. */ - assertIsDir("d1", -1); - /* On Windows, d1nosl should be a file symlink */ - assertIsSymlink("d1nosl", "d1", 0); - assertIsSymlink("d1slash", "d1/", 1); - assertIsSymlink("d1sldot", "d1/.", 1); - assertIsSymlink("d1slddot", "d1/..", 1); - - /* Test #5: symlink_type is set */ - assertIsSymlink("d1dir", "d1", 1); - assertIsSymlink("d1file", "d1", 0); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_disk_times.c b/thirdparty/libarchive/libarchive/test/test_write_disk_times.c deleted file mode 100644 index 568d04c00..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_disk_times.c +++ /dev/null @@ -1,167 +0,0 @@ -/*- - * Copyright (c) 2003-2008 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_disk_times.c 201247 2009-12-30 05:59:21Z kientzle $"); - -/* - * Exercise time restores in archive_write_disk(), including - * correct handling of omitted time values. - * On FreeBSD, we also test birthtime and high-res time restores. - */ - -DEFINE_TEST(test_write_disk_times) -{ - struct archive *a; - struct archive_entry *ae; - - /* Create an archive_write_disk object. */ - assert((a = archive_write_disk_new()) != NULL); - assertEqualInt(ARCHIVE_OK, - archive_write_disk_set_options(a, ARCHIVE_EXTRACT_TIME)); - - /* - * Easy case: mtime and atime both specified. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file1"); - archive_entry_set_mode(ae, S_IFREG | 0777); - archive_entry_set_atime(ae, 123456, 0); - archive_entry_set_mtime(ae, 234567, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - assertEqualInt(ARCHIVE_OK, archive_write_finish_entry(a)); - archive_entry_free(ae); - /* Verify */ - assertFileAtime("file1", 123456, 0); - assertFileMtime("file1", 234567, 0); - - /* - * mtime specified, but not atime - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file2"); - archive_entry_set_mode(ae, S_IFREG | 0777); - archive_entry_set_mtime(ae, 234567, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - assertEqualInt(ARCHIVE_OK, archive_write_finish_entry(a)); - archive_entry_free(ae); - assertFileMtime("file2", 234567, 0); - assertFileAtimeRecent("file2"); - - /* - * atime specified, but not mtime - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file3"); - archive_entry_set_mode(ae, S_IFREG | 0777); - archive_entry_set_atime(ae, 345678, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - assertEqualInt(ARCHIVE_OK, archive_write_finish_entry(a)); - archive_entry_free(ae); - /* Verify: Current mtime and atime as specified. */ - assertFileAtime("file3", 345678, 0); - assertFileMtimeRecent("file3"); - - /* - * Neither atime nor mtime specified. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file4"); - archive_entry_set_mode(ae, S_IFREG | 0777); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - assertEqualInt(ARCHIVE_OK, archive_write_finish_entry(a)); - archive_entry_free(ae); - /* Verify: Current mtime and atime. */ - assertFileAtimeRecent("file4"); - assertFileMtimeRecent("file4"); - -#if defined(__FreeBSD__) - /* - * High-res mtime and atime on FreeBSD. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file10"); - archive_entry_set_mode(ae, S_IFREG | 0777); - archive_entry_set_atime(ae, 1234567, 23456); - archive_entry_set_mtime(ae, 2345678, 4567); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - assertEqualInt(ARCHIVE_OK, archive_write_finish_entry(a)); - archive_entry_free(ae); - /* Verify */ - assertFileMtime("file10", 2345678, 4567); - assertFileAtime("file10", 1234567, 23456); - - /* - * Birthtime, mtime and atime on FreeBSD - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file11"); - archive_entry_set_mode(ae, S_IFREG | 0777); - archive_entry_set_atime(ae, 1234567, 23456); - archive_entry_set_birthtime(ae, 3456789, 12345); - /* mtime must be later than birthtime! */ - archive_entry_set_mtime(ae, 12345678, 4567); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - assertEqualInt(ARCHIVE_OK, archive_write_finish_entry(a)); - archive_entry_free(ae); - /* Verify */ - assertFileAtime("file11", 1234567, 23456); - assertFileBirthtime("file11", 3456789, 12345); - assertFileMtime("file11", 12345678, 4567); - - /* - * Birthtime only on FreeBSD. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file12"); - archive_entry_set_mode(ae, S_IFREG | 0777); - archive_entry_set_birthtime(ae, 3456789, 12345); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - assertEqualInt(ARCHIVE_OK, archive_write_finish_entry(a)); - archive_entry_free(ae); - /* Verify */ - assertFileAtimeRecent("file12"); - assertFileBirthtime("file12", 3456789, 12345); - assertFileMtimeRecent("file12"); - - /* - * mtime only on FreeBSD. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file13"); - archive_entry_set_mode(ae, S_IFREG | 0777); - archive_entry_set_mtime(ae, 4567890, 23456); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - assertEqualInt(ARCHIVE_OK, archive_write_finish_entry(a)); - archive_entry_free(ae); - /* Verify */ - assertFileAtimeRecent("file13"); - assertFileBirthtime("file13", 4567890, 23456); - assertFileMtime("file13", 4567890, 23456); -#else - skipping("Platform-specific time restore tests"); -#endif - - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_filter_b64encode.c b/thirdparty/libarchive/libarchive/test/test_write_filter_b64encode.c deleted file mode 100644 index 5b917e92a..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_filter_b64encode.c +++ /dev/null @@ -1,173 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* - * A basic exercise of b64encode reading and writing. - */ - -DEFINE_TEST(test_write_filter_b64encode) -{ - struct archive_entry *ae; - struct archive* a; - char *buff, *data; - size_t buffsize, datasize; - char path[16]; - size_t used1, used2; - int i; - - buffsize = 2000000; - assert(NULL != (buff = (char *)malloc(buffsize))); - - datasize = 10000; - assert(NULL != (data = (char *)malloc(datasize))); - memset(data, 0, datasize); - - /* - * Write a 100 files and read them all back. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_b64encode(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualInt(ARCHIVE_FILTER_UU, archive_filter_code(a, 0)); - assertEqualString("b64encode", archive_filter_name(a, 0)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used1)); - for (i = 0; i < 99; i++) { - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_filetype(ae, AE_IFREG); - archive_entry_set_size(ae, datasize); - snprintf(path, sizeof(path), "file%03d", i); - archive_entry_copy_pathname(ae, path); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertA(datasize - == (size_t)archive_write_data(a, data, datasize)); - archive_entry_free(ae); - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used1)); - for (i = 0; i < 99; i++) { - snprintf(path, sizeof(path), "file%03d", i); - if (!assertEqualIntA(a, 0, archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualInt(ARCHIVE_FILTER_UU, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Repeat the cycle again, this time setting name and mode - * options. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_b64encode(a)); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "nonexistent-option", "0")); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "compression-level", "abc")); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "compression-level", "99")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_filter_option(a, NULL, "name", "test.tar")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_filter_option(a, NULL, "mode", "0640")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used2)); - for (i = 0; i < 99; i++) { - snprintf(path, sizeof(path), "file%03d", i); - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, path); - archive_entry_set_size(ae, datasize); - archive_entry_set_filetype(ae, AE_IFREG); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertA(datasize == (size_t)archive_write_data(a, data, datasize)); - archive_entry_free(ae); - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used2)); - for (i = 0; i < 99; i++) { - snprintf(path, sizeof(path), "file%03d", i); - if (!assertEqualInt(0, archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualInt(ARCHIVE_FILTER_UU, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Test various premature shutdown scenarios to make sure we - * don't crash or leak memory. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_b64encode(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_b64encode(a)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_b64encode(a)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_b64encode(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used2)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Clean up. - */ - free(data); - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_filter_bzip2.c b/thirdparty/libarchive/libarchive/test/test_write_filter_bzip2.c deleted file mode 100644 index 9e089c0df..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_filter_bzip2.c +++ /dev/null @@ -1,276 +0,0 @@ -/*- - * Copyright (c) 2007 Tim Kientzle - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_compress_bzip2.c 191183 2009-04-17 01:06:31Z kientzle $"); - -/* - * A basic exercise of bzip2 reading and writing. - * - * TODO: Add a reference file and make sure we can decompress that. - */ - -DEFINE_TEST(test_write_filter_bzip2) -{ - struct archive_entry *ae; - struct archive* a; - char *buff, *data; - size_t buffsize, datasize; - char path[16]; - size_t used1, used2; - int i, r, use_prog; - - buffsize = 2000000; - assert(NULL != (buff = (char *)malloc(buffsize))); - if (buff == NULL) - return; - - datasize = 10000; - assert(NULL != (data = (char *)malloc(datasize))); - if (data == NULL) { - free(buff); - return; - } - memset(data, 0, datasize); - - /* - * Write a 100 files and read them all back. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - r = archive_write_add_filter_bzip2(a); - use_prog = (r == ARCHIVE_WARN && canBzip2()); - if (r != ARCHIVE_OK && !use_prog) { - skipping("bzip2 writing not supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - free(buff); - free(data); - return; - } - - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualInt(ARCHIVE_FILTER_BZIP2, archive_filter_code(a, 0)); - assertEqualString("bzip2", archive_filter_name(a, 0)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used1)); - assertEqualInt(ARCHIVE_FILTER_BZIP2, archive_filter_code(a, 0)); - assertEqualString("bzip2", archive_filter_name(a, 0)); - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_filetype(ae, AE_IFREG); - archive_entry_set_size(ae, datasize); - for (i = 0; i < 999; i++) { - snprintf(path, sizeof(path), "file%03d", i); - archive_entry_copy_pathname(ae, path); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertA(datasize - == (size_t)archive_write_data(a, data, datasize)); - } - archive_entry_free(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used1)); - for (i = 0; i < 999; i++) { - snprintf(path, sizeof(path), "file%03d", i); - if (!assertEqualInt(0, archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Repeat the cycle again, this time setting some compression - * options. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - if (use_prog) - assertEqualIntA(a, ARCHIVE_WARN, - archive_write_add_filter_bzip2(a)); - else - assertEqualIntA(a, ARCHIVE_OK, - archive_write_add_filter_bzip2(a)); - assertEqualIntA(a, ARCHIVE_FAILED, archive_write_set_filter_option(a, - NULL, "nonexistent-option", "0")); - assertEqualIntA(a, ARCHIVE_FAILED, archive_write_set_filter_option(a, - NULL, "compression-level", "abc")); - assertEqualIntA(a, ARCHIVE_FAILED, archive_write_set_filter_option(a, - NULL, "compression-level", "99")); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_filter_option(a, - NULL, "compression-level", "9")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used2)); - for (i = 0; i < 999; i++) { - snprintf(path, sizeof(path), "file%03d", i); - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, path); - archive_entry_set_size(ae, datasize); - archive_entry_set_filetype(ae, AE_IFREG); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertA(datasize == (size_t)archive_write_data(a, data, - datasize)); - archive_entry_free(ae); - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Curiously, this test fails; the test data above compresses - * better at default compression than at level 9. */ - /* - failure("compression-level=9 wrote %d bytes, default wrote %d bytes", - (int)used2, (int)used1); - assert(used2 < used1); - */ - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used2)); - for (i = 0; i < 999; i++) { - snprintf(path, sizeof(path), "file%03d", i); - if (!assertEqualInt(0, archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Repeat again, with much lower compression. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - if (use_prog) - assertEqualIntA(a, ARCHIVE_WARN, - archive_write_add_filter_bzip2(a)); - else - assertEqualIntA(a, ARCHIVE_OK, - archive_write_add_filter_bzip2(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_filter_option(a, - NULL, "compression-level", "1")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used2)); - for (i = 0; i < 999; i++) { - snprintf(path, sizeof(path), "file%03d", i); - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, path); - archive_entry_set_size(ae, datasize); - archive_entry_set_filetype(ae, AE_IFREG); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - failure("Writing file %s", path); - assertEqualIntA(a, datasize, - (size_t)archive_write_data(a, data, datasize)); - archive_entry_free(ae); - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Level 0 really does result in larger data. */ - failure("Compression-level=0 wrote %d bytes; default wrote %d bytes", - (int)used2, (int)used1); - assert(used2 > used1); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used2)); - for (i = 0; i < 999; i++) { - snprintf(path, sizeof(path), "file%03d", i); - if (!assertEqualInt(0, archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Test various premature shutdown scenarios to make sure we - * don't crash or leak memory. - */ - assert((a = archive_write_new()) != NULL); - if (use_prog) - assertEqualIntA(a, ARCHIVE_WARN, - archive_write_add_filter_bzip2(a)); - else - assertEqualIntA(a, ARCHIVE_OK, - archive_write_add_filter_bzip2(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - if (use_prog) - assertEqualIntA(a, ARCHIVE_WARN, - archive_write_add_filter_bzip2(a)); - else - assertEqualIntA(a, ARCHIVE_OK, - archive_write_add_filter_bzip2(a)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - if (use_prog) - assertEqualIntA(a, ARCHIVE_WARN, - archive_write_add_filter_bzip2(a)); - else - assertEqualIntA(a, ARCHIVE_OK, - archive_write_add_filter_bzip2(a)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - if (use_prog) - assertEqualIntA(a, ARCHIVE_WARN, - archive_write_add_filter_bzip2(a)); - else - assertEqualIntA(a, ARCHIVE_OK, - archive_write_add_filter_bzip2(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used2)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Clean up. - */ - free(data); - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_filter_compress.c b/thirdparty/libarchive/libarchive/test/test_write_filter_compress.c deleted file mode 100644 index 5cc0fc80b..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_filter_compress.c +++ /dev/null @@ -1,97 +0,0 @@ -/*- - * Copyright (c) 2007 Tim Kientzle - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_compress.c 189308 2009-03-03 17:02:51Z kientzle $"); - -/* - * A basic exercise of compress reading and writing. - * - * TODO: Add a reference file and make sure we can decompress that. - */ - -DEFINE_TEST(test_write_filter_compress) -{ - struct archive_entry *ae; - struct archive* a; - char *buff, *data; - size_t buffsize, datasize; - char path[16]; - size_t used; - int i; - - buffsize = 1000000; - assert(NULL != (buff = (char *)malloc(buffsize))); - - datasize = 10000; - assert(NULL != (data = (char *)malloc(datasize))); - memset(data, 0, datasize); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_add_filter_compress(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used)); - - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, path); - archive_entry_set_size(ae, datasize); - archive_entry_set_filetype(ae, AE_IFREG); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertEqualInt(datasize, - archive_write_data(a, data, datasize)); - archive_entry_free(ae); - } - - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Now, read the data back. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); - - - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - if (!assertEqualInt(0, archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - free(data); - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_filter_gzip.c b/thirdparty/libarchive/libarchive/test/test_write_filter_gzip.c deleted file mode 100644 index 2b7616271..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_filter_gzip.c +++ /dev/null @@ -1,298 +0,0 @@ -/*- - * Copyright (c) 2007 Tim Kientzle - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_compress_gzip.c 191183 2009-04-17 01:06:31Z kientzle $"); - -/* - * A basic exercise of gzip reading and writing. - * - * TODO: Add a reference file and make sure we can decompress that. - */ - -DEFINE_TEST(test_write_filter_gzip) -{ - struct archive_entry *ae; - struct archive* a; - char *buff, *data; - size_t buffsize, datasize; - unsigned char *rbuff; - char path[16]; - size_t used1, used2; - int i, r, use_prog = 0; - - buffsize = 2000000; - assert(NULL != (buff = (char *)malloc(buffsize))); - if (buff == NULL) - return; - - datasize = 10000; - assert(NULL != (data = (char *)malloc(datasize))); - if (data == NULL) { - free(buff); - return; - } - memset(data, 0, datasize); - - /* - * Write a 100 files and read them all back. - * Use default compression level (6). - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - r = archive_write_add_filter_gzip(a); - if (r != ARCHIVE_OK) { - if (canGzip() && r == ARCHIVE_WARN) - use_prog = 1; - else { - skipping("gzip writing not supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - free(buff); - free(data); - return; - } - } - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualInt(ARCHIVE_FILTER_GZIP, archive_filter_code(a, 0)); - assertEqualString("gzip", archive_filter_name(a, 0)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used1)); - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_filetype(ae, AE_IFREG); - archive_entry_set_size(ae, datasize); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - archive_entry_copy_pathname(ae, path); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertA(datasize - == (size_t)archive_write_data(a, data, datasize)); - } - archive_entry_free(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Basic gzip header tests */ - rbuff = (unsigned char *)buff; - assertEqualInt(rbuff[0], 0x1f); - assertEqualInt(rbuff[1], 0x8b); - assertEqualInt(rbuff[2], 0x08); - assertEqualInt(rbuff[3], 0x00); - assertEqualInt(rbuff[8], 0); /* RFC 1952 flag for compression level 6 */ - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - r = archive_read_support_filter_gzip(a); - if (r == ARCHIVE_WARN) { - skipping("Can't verify gzip writing by reading back;" - " gzip reading not fully supported on this platform"); - } else { - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used1)); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - if (!assertEqualInt(ARCHIVE_OK, - archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Repeat the cycle again, this time setting some compression - * options. Compression level is 9. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, - archive_write_add_filter_gzip(a)); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_options(a, "gzip:nonexistent-option=0")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "gzip:compression-level=1")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_filter_option(a, NULL, "compression-level", "9")); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "compression-level", "abc")); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "compression-level", "99")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "gzip:compression-level=9")); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2)); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, path); - archive_entry_set_size(ae, datasize); - archive_entry_set_filetype(ae, AE_IFREG); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertA(datasize == (size_t)archive_write_data(a, data, datasize)); - archive_entry_free(ae); - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Basic gzip header tests */ - rbuff = (unsigned char *)buff; - assertEqualInt(rbuff[0], 0x1f); - assertEqualInt(rbuff[1], 0x8b); - assertEqualInt(rbuff[2], 0x08); - assertEqualInt(rbuff[3], 0x00); - assertEqualInt(rbuff[8], 2); /* RFC 1952 flag for compression level 9 */ - - /* Curiously, this test fails; the test data above compresses - * better at default compression than at level 9. */ - /* - failure("compression-level=9 wrote %d bytes, default wrote %d bytes", - (int)used2, (int)used1); - assert(used2 < used1); - */ - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - r = archive_read_support_filter_gzip(a); - if (r != ARCHIVE_OK && !use_prog) { - skipping("gzip reading not fully supported on this platform"); - } else { - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used2)); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - if (!assertEqualInt(ARCHIVE_OK, - archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Repeat again, with compression level 1 - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, - archive_write_add_filter_gzip(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_filter_option(a, NULL, "compression-level", "1")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used2)); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, path); - archive_entry_set_size(ae, datasize); - archive_entry_set_filetype(ae, AE_IFREG); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - failure("Writing file %s", path); - assertEqualIntA(a, datasize, - (size_t)archive_write_data(a, data, datasize)); - archive_entry_free(ae); - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Level 1 really does result in larger data. */ - failure("Compression-level=1 wrote %d bytes; default wrote %d bytes", - (int)used2, (int)used1); - assert(used2 > used1); - - /* Basic gzip header tests */ - rbuff = (unsigned char *)buff; - assertEqualInt(rbuff[0], 0x1f); - assertEqualInt(rbuff[1], 0x8b); - assertEqualInt(rbuff[2], 0x08); - assertEqualInt(rbuff[3], 0x00); - assertEqualInt(rbuff[8], 4); /* RFC 1952 flag for compression level 1 */ - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - r = archive_read_support_filter_gzip(a); - if (r == ARCHIVE_WARN) { - skipping("gzip reading not fully supported on this platform"); - } else { - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used2)); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - if (!assertEqualInt(ARCHIVE_OK, - archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Test various premature shutdown scenarios to make sure we - * don't crash or leak memory. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, - archive_write_add_filter_gzip(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, - archive_write_add_filter_gzip(a)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, - archive_write_add_filter_gzip(a)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, - archive_write_add_filter_gzip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Clean up. - */ - free(data); - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_filter_gzip_timestamp.c b/thirdparty/libarchive/libarchive/test/test_write_filter_gzip_timestamp.c deleted file mode 100644 index 23b11dba7..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_filter_gzip_timestamp.c +++ /dev/null @@ -1,118 +0,0 @@ -/*- - * Copyright (c) 2007 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_write_filter_gzip_timestamp) -{ - struct archive_entry *ae; - struct archive* a; - char *buff, *data; - size_t buffsize, datasize; - size_t used1; - int r, use_prog = 0; - - buffsize = 10000; - assert(NULL != (buff = (char *)malloc(buffsize))); - if (buff == NULL) - return; - - datasize = 10000; - assert(NULL != (data = (char *)malloc(datasize))); - if (data == NULL) { - free(buff); - return; - } - memset(data, 0, datasize); - - /* Test1: set "gzip:timestamp" option. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - r = archive_write_add_filter_gzip(a); - if (r != ARCHIVE_OK) { - if (canGzip() && r == ARCHIVE_WARN) - use_prog = 1; - else { - skipping("gzip writing not supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - free(buff); - free(data); - return; - } - } - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "gzip:timestamp")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualInt(ARCHIVE_FILTER_GZIP, archive_filter_code(a, 0)); - assertEqualString("gzip", archive_filter_name(a, 0)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used1)); - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_filetype(ae, AE_IFREG); - archive_entry_set_size(ae, datasize); - archive_entry_copy_pathname(ae, "file"); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertEqualIntA(a, datasize, archive_write_data(a, data, datasize)); - archive_entry_free(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - failure("Timestamp should be recorded"); - assert(memcmp(buff + 4, "\x00\x00\x00\x00", 4) != 0); - - /* Test2: set "gzip:!timestamp" option. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, - archive_write_add_filter_gzip(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "gzip:!timestamp")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualInt(ARCHIVE_FILTER_GZIP, archive_filter_code(a, 0)); - assertEqualString("gzip", archive_filter_name(a, 0)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used1)); - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_filetype(ae, AE_IFREG); - archive_entry_set_size(ae, datasize); - archive_entry_copy_pathname(ae, "file"); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertEqualIntA(a, datasize, archive_write_data(a, data, datasize)); - archive_entry_free(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - failure("Timestamp should not be recorded"); - assertEqualMem(buff + 4, "\x00\x00\x00\x00", 4); - - /* - * Clean up. - */ - free(data); - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_filter_lrzip.c b/thirdparty/libarchive/libarchive/test/test_write_filter_lrzip.c deleted file mode 100644 index 2efc2ec28..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_filter_lrzip.c +++ /dev/null @@ -1,131 +0,0 @@ -/*- - * Copyright (c) 2007 Tim Kientzle - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" - -/* - * A basic exercise of lrzip reading and writing. - */ - -DEFINE_TEST(test_write_filter_lrzip) -{ - struct archive_entry *ae; - struct archive* a; - char *buff, *data; - size_t buffsize, datasize; - char path[16]; - size_t used1, used2; - int i; - - if (!canLrzip()) { - skipping("lrzip command-line program not found"); - return; - } - - buffsize = 2000000; - assert(NULL != (buff = (char *)malloc(buffsize))); - - datasize = 10000; - assert(NULL != (data = (char *)malloc(datasize))); - memset(data, 0, datasize); - - /* - * Write 100 files and read them all back. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_gnutar(a)); - assertEqualIntA(a, ARCHIVE_WARN, archive_write_add_filter_lrzip(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualInt(ARCHIVE_FILTER_LRZIP, archive_filter_code(a, 0)); - assertEqualString("lrzip", archive_filter_name(a, 0)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used1)); - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_filetype(ae, AE_IFREG); - archive_entry_set_size(ae, datasize); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - archive_entry_copy_pathname(ae, path); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertA(datasize - == (size_t)archive_write_data(a, data, datasize)); - } - archive_entry_free(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_WARN, archive_read_support_filter_lrzip(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used1)); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - if (!assertEqualInt(ARCHIVE_OK, - archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualInt(ARCHIVE_FILTER_LRZIP, archive_filter_code(a, 0)); - assertEqualString("lrzip", archive_filter_name(a, 0)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Test various premature shutdown scenarios to make sure we - * don't crash or leak memory. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_WARN, archive_write_add_filter_lrzip(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_WARN, archive_write_add_filter_lrzip(a)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_WARN, archive_write_add_filter_lrzip(a)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_WARN, archive_write_add_filter_lrzip(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used2)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Clean up. - */ - free(data); - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_filter_lz4.c b/thirdparty/libarchive/libarchive/test/test_write_filter_lz4.c deleted file mode 100644 index 071fee41d..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_filter_lz4.c +++ /dev/null @@ -1,411 +0,0 @@ -/*- - * Copyright (c) 2014 Michihiro NAKAJIMA - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* - * A basic exercise of lz4 reading and writing. - */ - -DEFINE_TEST(test_write_filter_lz4) -{ - struct archive_entry *ae; - struct archive* a; - char *buff, *data; - size_t buffsize, datasize; - char path[16]; - size_t used1, used2; - int i, r, use_prog = 0, filecount; - - assert((a = archive_write_new()) != NULL); - r = archive_write_add_filter_lz4(a); - if (archive_liblz4_version() == NULL) { - if (!canLz4()) { - skipping("lz4 writing not supported on this platform"); - assertEqualInt(ARCHIVE_WARN, r); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - return; - } else { - assertEqualInt(ARCHIVE_WARN, r); - use_prog = 1; - } - } else { - assertEqualInt(ARCHIVE_OK, r); - } - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - buffsize = 2000000; - assert(NULL != (buff = (char *)malloc(buffsize))); - - datasize = 10000; - assert(NULL != (data = (char *)calloc(1, datasize))); - filecount = 10; - - /* - * Write a filecount files and read them all back. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, - archive_write_add_filter_lz4(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 1024)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_in_last_block(a, 1024)); - assertEqualInt(ARCHIVE_FILTER_LZ4, archive_filter_code(a, 0)); - assertEqualString("lz4", archive_filter_name(a, 0)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used1)); - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_filetype(ae, AE_IFREG); - archive_entry_set_size(ae, datasize); - for (i = 0; i < filecount; i++) { - snprintf(path, sizeof(path), "file%03d", i); - archive_entry_copy_pathname(ae, path); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertA(datasize - == (size_t)archive_write_data(a, data, datasize)); - } - archive_entry_free(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - r = archive_read_support_filter_lz4(a); - if (r == ARCHIVE_WARN) { - skipping("Can't verify lz4 writing by reading back;" - " lz4 reading not fully supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used1)); - for (i = 0; i < filecount; i++) { - snprintf(path, sizeof(path), "file%03d", i); - if (!assertEqualInt(ARCHIVE_OK, - archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Repeat the cycle again, this time setting some compression - * options. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, - archive_write_add_filter_lz4(a)); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_options(a, "lz4:nonexistent-option=0")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "lz4:compression-level=1")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_filter_option(a, NULL, "compression-level", "9")); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "compression-level", "abc")); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "compression-level", "99")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "lz4:compression-level=9")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used2)); - for (i = 0; i < filecount; i++) { - snprintf(path, sizeof(path), "file%03d", i); - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, path); - archive_entry_set_size(ae, datasize); - archive_entry_set_filetype(ae, AE_IFREG); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertA(datasize == (size_t)archive_write_data( - a, data, datasize)); - archive_entry_free(ae); - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - failure("compression-level=9 wrote %d bytes, default wrote %d bytes", - (int)used2, (int)used1); - assert(used2 < used1); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - r = archive_read_support_filter_lz4(a); - if (r != ARCHIVE_OK && !use_prog) { - skipping("lz4 reading not fully supported on this platform"); - } else { - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used2)); - for (i = 0; i < filecount; i++) { - snprintf(path, sizeof(path), "file%03d", i); - if (!assertEqualInt(ARCHIVE_OK, - archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Repeat again, with much lower compression. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, - archive_write_add_filter_lz4(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_filter_option(a, NULL, "compression-level", "1")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used2)); - for (i = 0; i < filecount; i++) { - snprintf(path, sizeof(path), "file%03d", i); - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, path); - archive_entry_set_size(ae, datasize); - archive_entry_set_filetype(ae, AE_IFREG); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - failure("Writing file %s", path); - assertEqualIntA(a, datasize, - (size_t)archive_write_data(a, data, datasize)); - archive_entry_free(ae); - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - -#if 0 - failure("Compression-level=1 wrote %d bytes; default wrote %d bytes", - (int)used2, (int)used1); - assert(used2 > used1); -#endif - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - r = archive_read_support_filter_lz4(a); - if (r == ARCHIVE_WARN) { - skipping("lz4 reading not fully supported on this platform"); - } else { - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used2)); - for (i = 0; i < filecount; i++) { - snprintf(path, sizeof(path), "file%03d", i); - if (!assertEqualInt(ARCHIVE_OK, - archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Test various premature shutdown scenarios to make sure we - * don't crash or leak memory. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, - archive_write_add_filter_lz4(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, - archive_write_add_filter_lz4(a)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, - archive_write_add_filter_lz4(a)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, - archive_write_add_filter_lz4(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used2)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Clean up. - */ - free(data); - free(buff); -} - -static void -test_options(const char *options) -{ - struct archive_entry *ae; - struct archive* a; - char *buff, *data; - size_t buffsize, datasize; - char path[16]; - size_t used1; - int i, r, use_prog = 0, filecount; - - assert((a = archive_write_new()) != NULL); - r = archive_write_add_filter_lz4(a); - if (archive_liblz4_version() == NULL) { - if (!canLz4()) { - skipping("lz4 writing not supported on this platform"); - assertEqualInt(ARCHIVE_WARN, r); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - return; - } else { - assertEqualInt(ARCHIVE_WARN, r); - use_prog = 1; - } - } else { - assertEqualInt(ARCHIVE_OK, r); - } - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - buffsize = 2000000; - assert(NULL != (buff = (char *)malloc(buffsize))); - - datasize = 10000; - assert(NULL != (data = (char *)calloc(1, datasize))); - filecount = 10; - - /* - * Write a filecount files and read them all back. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, - archive_write_add_filter_lz4(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, options)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 1024)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_in_last_block(a, 1024)); - assertEqualInt(ARCHIVE_FILTER_LZ4, archive_filter_code(a, 0)); - assertEqualString("lz4", archive_filter_name(a, 0)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used1)); - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_filetype(ae, AE_IFREG); - archive_entry_set_size(ae, datasize); - for (i = 0; i < filecount; i++) { - snprintf(path, sizeof(path), "file%03d", i); - archive_entry_copy_pathname(ae, path); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertA(datasize - == (size_t)archive_write_data(a, data, datasize)); - } - archive_entry_free(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - r = archive_read_support_filter_lz4(a); - if (r == ARCHIVE_WARN) { - skipping("Can't verify lz4 writing by reading back;" - " lz4 reading not fully supported on this platform"); - } else { - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used1)); - for (i = 0; i < filecount; i++) { - snprintf(path, sizeof(path), "file%03d", i); - if (!assertEqualInt(ARCHIVE_OK, - archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Clean up. - */ - free(data); - free(buff); -} - -DEFINE_TEST(test_write_filter_lz4_disable_stream_checksum) -{ - test_options("lz4:!stream-checksum"); -} - -DEFINE_TEST(test_write_filter_lz4_enable_block_checksum) -{ - test_options("lz4:block-checksum"); -} - -DEFINE_TEST(test_write_filter_lz4_block_size_4) -{ - test_options("lz4:block-size=4"); -} - -DEFINE_TEST(test_write_filter_lz4_block_size_5) -{ - test_options("lz4:block-size=5"); -} - -DEFINE_TEST(test_write_filter_lz4_block_size_6) -{ - test_options("lz4:block-size=6"); -} - -DEFINE_TEST(test_write_filter_lz4_block_dependence) -{ - test_options("lz4:block-dependence"); -} - -/* - * TODO: Figure out how to correctly handle this. - * - * This option simply fails on some versions of the LZ4 libraries. - */ -/* -XXXDEFINE_TEST(test_write_filter_lz4_block_dependence_hc) -{ - test_options("lz4:block-dependence,lz4:compression-level=9"); -} -*/ diff --git a/thirdparty/libarchive/libarchive/test/test_write_filter_lzip.c b/thirdparty/libarchive/libarchive/test/test_write_filter_lzip.c deleted file mode 100644 index ce70a5d62..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_filter_lzip.c +++ /dev/null @@ -1,255 +0,0 @@ -/*- - * Copyright (c) 2010 Michihiro NAKAJIMA - * Copyright (c) 2007-2009 Tim Kientzle - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* - * A basic exercise of lzip reading and writing. - * - */ - -DEFINE_TEST(test_write_filter_lzip) -{ - struct archive_entry *ae; - struct archive* a; - char *buff, *data; - size_t buffsize, datasize; - char path[16]; - size_t used1, used2; - int i, r; - - buffsize = 2000000; - assert(NULL != (buff = (char *)malloc(buffsize))); - if (buff == NULL) - return; - - datasize = 10000; - assert(NULL != (data = (char *)malloc(datasize))); - if (data == NULL) { - free(buff); - return; - } - memset(data, 0, datasize); - - /* - * Write a 100 files and read them all back. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - r = archive_write_add_filter_lzip(a); - if (r == ARCHIVE_FATAL) { - skipping("lzip writing not supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - free(buff); - free(data); - return; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualInt(ARCHIVE_FILTER_LZIP, archive_filter_code(a, 0)); - assertEqualString("lzip", archive_filter_name(a, 0)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used1)); - assertEqualInt(ARCHIVE_FILTER_LZIP, archive_filter_code(a, 0)); - assertEqualString("lzip", archive_filter_name(a, 0)); - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_filetype(ae, AE_IFREG); - archive_entry_set_size(ae, datasize); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - archive_entry_copy_pathname(ae, path); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertA(datasize - == (size_t)archive_write_data(a, data, datasize)); - } - archive_entry_free(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - r = archive_read_support_filter_lzip(a); - if (r == ARCHIVE_WARN) { - skipping("Can't verify lzip writing by reading back;" - " lzip reading not fully supported on this platform"); - } else { - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used1)); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - if (!assertEqualInt(ARCHIVE_OK, - archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Repeat the cycle again, this time setting some compression - * options. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_lzip(a)); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "nonexistent-option", "0")); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "compression-level", "abc")); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "compression-level", "99")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_filter_option(a, NULL, "compression-level", "9")); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2)); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, path); - archive_entry_set_size(ae, datasize); - archive_entry_set_filetype(ae, AE_IFREG); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertA(datasize == (size_t)archive_write_data(a, data, datasize)); - archive_entry_free(ae); - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - r = archive_read_support_filter_lzip(a); - if (r == ARCHIVE_WARN) { - skipping("lzip reading not fully supported on this platform"); - } else { - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used2)); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - failure("Trying to read %s", path); - if (!assertEqualIntA(a, ARCHIVE_OK, - archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Repeat again, with much lower compression. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_lzip(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_filter_option(a, NULL, "compression-level", "0")); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2)); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, path); - archive_entry_set_size(ae, datasize); - archive_entry_set_filetype(ae, AE_IFREG); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - failure("Writing file %s", path); - assertEqualIntA(a, datasize, - (size_t)archive_write_data(a, data, datasize)); - archive_entry_free(ae); - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Level 0 really does result in larger data. */ - failure("Compression-level=0 wrote %d bytes; default wrote %d bytes", - (int)used2, (int)used1); - assert(used2 > used1); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - r = archive_read_support_filter_lzip(a); - if (r == ARCHIVE_WARN) { - skipping("lzip reading not fully supported on this platform"); - } else { - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used2)); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - if (!assertEqualInt(ARCHIVE_OK, - archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Test various premature shutdown scenarios to make sure we - * don't crash or leak memory. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_lzip(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_lzip(a)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_lzip(a)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_lzip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Clean up. - */ - free(data); - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_filter_lzma.c b/thirdparty/libarchive/libarchive/test/test_write_filter_lzma.c deleted file mode 100644 index d055333a4..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_filter_lzma.c +++ /dev/null @@ -1,259 +0,0 @@ -/*- - * Copyright (c) 2007-2009 Tim Kientzle - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_compress_lzma.c 191183 2009-04-17 01:06:31Z kientzle $"); - -/* - * A basic exercise of lzma reading and writing. - * - */ - -DEFINE_TEST(test_write_filter_lzma) -{ - struct archive_entry *ae; - struct archive* a; - char *buff, *data; - size_t buffsize, datasize; - char path[16]; - size_t used1, used2; - int i, r; - - buffsize = 2000000; - assert(NULL != (buff = (char *)malloc(buffsize))); - if (buff == NULL) - return; - - datasize = 10000; - assert(NULL != (data = (char *)malloc(datasize))); - if (data == NULL) { - free(buff); - return; - } - memset(data, 0, datasize); - - /* - * Write a 100 files and read them all back. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - r = archive_write_add_filter_lzma(a); - if (r == ARCHIVE_FATAL) { - skipping("lzma writing not supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - free(buff); - free(data); - return; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualInt(ARCHIVE_FILTER_LZMA, archive_filter_code(a, 0)); - assertEqualString("lzma", archive_filter_name(a, 0)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used1)); - assertEqualInt(ARCHIVE_FILTER_LZMA, archive_filter_code(a, 0)); - assertEqualString("lzma", archive_filter_name(a, 0)); - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_filetype(ae, AE_IFREG); - archive_entry_set_size(ae, datasize); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - archive_entry_copy_pathname(ae, path); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertA(datasize - == (size_t)archive_write_data(a, data, datasize)); - } - archive_entry_free(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - r = archive_read_support_filter_lzma(a); - if (r == ARCHIVE_WARN) { - skipping("Can't verify lzma writing by reading back;" - " lzma reading not fully supported on this platform"); - } else { - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used1)); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - if (!assertEqualInt(ARCHIVE_OK, - archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Repeat the cycle again, this time setting some compression - * options. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_lzma(a)); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "nonexistent-option", "0")); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "compression-level", "abc")); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "compression-level", "99")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_filter_option(a, NULL, "compression-level", "9")); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2)); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, path); - archive_entry_set_size(ae, datasize); - archive_entry_set_filetype(ae, AE_IFREG); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertA(datasize == (size_t)archive_write_data(a, data, datasize)); - archive_entry_free(ae); - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - r = archive_read_support_filter_lzma(a); - if (r == ARCHIVE_WARN) { - skipping("lzma reading not fully supported on this platform"); - } else { - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used2)); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - failure("Trying to read %s", path); - if (!assertEqualIntA(a, ARCHIVE_OK, - archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Repeat again, with much lower compression. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_lzma(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_filter_option(a, NULL, "compression-level", "0")); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2)); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, path); - archive_entry_set_size(ae, datasize); - archive_entry_set_filetype(ae, AE_IFREG); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - failure("Writing file %s", path); - assertEqualIntA(a, datasize, - (size_t)archive_write_data(a, data, datasize)); - archive_entry_free(ae); - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* It would be nice to assert that compression-level=0 produced - * consistently larger/smaller results than the default compression, - * but the results here vary a lot depending on the version of liblzma - * being used. */ - /* - failure("Compression-level=0 wrote %d bytes; default wrote %d bytes", - (int)used2, (int)used1); - assert(used2 > used1); - */ - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - r = archive_read_support_filter_lzma(a); - if (r == ARCHIVE_WARN) { - skipping("lzma reading not fully supported on this platform"); - } else { - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used2)); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - if (!assertEqualInt(ARCHIVE_OK, - archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Test various premature shutdown scenarios to make sure we - * don't crash or leak memory. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_lzma(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_lzma(a)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_lzma(a)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_lzma(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Clean up. - */ - free(data); - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_filter_lzop.c b/thirdparty/libarchive/libarchive/test/test_write_filter_lzop.c deleted file mode 100644 index 18fc332b4..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_filter_lzop.c +++ /dev/null @@ -1,268 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* - * A basic exercise of lzop reading and writing. - */ - -DEFINE_TEST(test_write_filter_lzop) -{ - struct archive_entry *ae; - struct archive* a; - char *buff, *data; - size_t buffsize, datasize; - char path[16]; - size_t used1, used2; - int i, r, use_prog = 0, filecount; - - assert((a = archive_write_new()) != NULL); - r = archive_write_add_filter_lzop(a); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - if (r != ARCHIVE_OK) { - if (canLzop() && r == ARCHIVE_WARN) - use_prog = 1; - else { - skipping("lzop writing not supported on this platform"); - return; - } - } - - buffsize = 2000000; - assert(NULL != (buff = (char *)malloc(buffsize))); - - datasize = 10000; - assert(NULL != (data = (char *)calloc(1, datasize))); - filecount = 10; - - /* - * Write a filecount files and read them all back. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, - archive_write_add_filter_lzop(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 1024)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_in_last_block(a, 1024)); - assertEqualInt(ARCHIVE_FILTER_LZOP, archive_filter_code(a, 0)); - assertEqualString("lzop", archive_filter_name(a, 0)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used1)); - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_filetype(ae, AE_IFREG); - archive_entry_set_size(ae, datasize); - for (i = 0; i < filecount; i++) { - snprintf(path, sizeof(path), "file%03d", i); - archive_entry_copy_pathname(ae, path); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertA(datasize - == (size_t)archive_write_data(a, data, datasize)); - } - archive_entry_free(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - r = archive_read_support_filter_lzop(a); - if (r == ARCHIVE_WARN && !use_prog) { - skipping("Can't verify lzop writing by reading back;" - " lzop reading not fully supported on this platform"); - } else { - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used1)); - for (i = 0; i < filecount; i++) { - snprintf(path, sizeof(path), "file%03d", i); - if (!assertEqualInt(ARCHIVE_OK, - archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Repeat the cycle again, this time setting some compression - * options. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, - archive_write_add_filter_lzop(a)); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_options(a, "lzop:nonexistent-option=0")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "lzop:compression-level=1")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_filter_option(a, NULL, "compression-level", "9")); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "compression-level", "abc")); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "compression-level", "99")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "lzop:compression-level=9")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used2)); - for (i = 0; i < filecount; i++) { - snprintf(path, sizeof(path), "file%03d", i); - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, path); - archive_entry_set_size(ae, datasize); - archive_entry_set_filetype(ae, AE_IFREG); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertA(datasize == (size_t)archive_write_data( - a, data, datasize)); - archive_entry_free(ae); - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - failure("compression-level=9 wrote %d bytes, default wrote %d bytes", - (int)used2, (int)used1); - assert(used2 < used1); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - r = archive_read_support_filter_lzop(a); - if (r != ARCHIVE_OK && !use_prog) { - skipping("lzop reading not fully supported on this platform"); - } else { - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used2)); - for (i = 0; i < filecount; i++) { - snprintf(path, sizeof(path), "file%03d", i); - if (!assertEqualInt(ARCHIVE_OK, - archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Repeat again, with much lower compression. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, - archive_write_add_filter_lzop(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_filter_option(a, NULL, "compression-level", "1")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used2)); - for (i = 0; i < filecount; i++) { - snprintf(path, sizeof(path), "file%03d", i); - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, path); - archive_entry_set_size(ae, datasize); - archive_entry_set_filetype(ae, AE_IFREG); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - failure("Writing file %s", path); - assertEqualIntA(a, datasize, - (size_t)archive_write_data(a, data, datasize)); - archive_entry_free(ae); - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - -#if 0 - failure("Compression-level=1 wrote %d bytes; default wrote %d bytes", - (int)used2, (int)used1); - assert(used2 > used1); -#endif - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - r = archive_read_support_filter_lzop(a); - if (r == ARCHIVE_WARN && !use_prog) { - skipping("lzop reading not fully supported on this platform"); - } else { - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used2)); - for (i = 0; i < filecount; i++) { - snprintf(path, sizeof(path), "file%03d", i); - if (!assertEqualInt(ARCHIVE_OK, - archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Test various premature shutdown scenarios to make sure we - * don't crash or leak memory. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, - archive_write_add_filter_lzop(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, - archive_write_add_filter_lzop(a)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, - archive_write_add_filter_lzop(a)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, - archive_write_add_filter_lzop(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used2)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Clean up. - */ - free(data); - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_filter_program.c b/thirdparty/libarchive/libarchive/test/test_write_filter_program.c deleted file mode 100644 index 9fe264c01..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_filter_program.c +++ /dev/null @@ -1,124 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_compress_program.c 201247 2009-12-30 05:59:21Z kientzle $"); - -static char buff[1000000]; -static char buff2[64]; - -DEFINE_TEST(test_write_filter_program) -{ - struct archive_entry *ae; - struct archive *a; - size_t used; - int blocksize = 1024; - int r; - - if (!canGzip()) { - skipping("Cannot run 'gzip'"); - return; - } - /* NOTE: Setting blocksize=1024 will cause gunzip failure because - * it add extra bytes that gunzip ignores with its warning and - * exit code 1. So we should set blocksize=1 in order not to - * yield the extra bytes when using gunzip. */ - assert((a = archive_read_new()) != NULL); - r = archive_read_support_filter_gzip(a); - if (r != ARCHIVE_OK && canGzip()) - blocksize = 1; - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* Create a new archive in memory. */ - /* Write it through an external "gzip" program. */ - assert((a = archive_write_new()) != NULL); - assertA(0 == archive_write_set_format_ustar(a)); - r = archive_write_add_filter_program(a, "gzip -6"); - if (r == ARCHIVE_FATAL) { - skipping("Write compression via external " - "program unsupported on this platform"); - archive_write_free(a); - return; - } - assertA(0 == archive_write_set_bytes_per_block(a, blocksize)); - assertA(0 == archive_write_set_bytes_in_last_block(a, blocksize)); - assertA(blocksize == archive_write_get_bytes_in_last_block(a)); - assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used)); - assertA(blocksize == archive_write_get_bytes_in_last_block(a)); - - /* - * Write a file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - archive_entry_copy_pathname(ae, "file"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 8); - - assertA(0 == archive_write_header(a, ae)); - archive_entry_free(ae); - assertA(8 == archive_write_data(a, "12345678", 9)); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Now, read the data back through the built-in gzip support. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - r = archive_read_support_filter_gzip(a); - /* The compression_gzip() handler will fall back to gunzip - * automatically, but if we know gunzip isn't available, then - * skip the rest. */ - if (r != ARCHIVE_OK && !canGzip()) { - skipping("No libz and no gunzip program, " - "unable to verify gzip compression"); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - return; - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); - - if (!assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae))) { - archive_read_free(a); - return; - } - - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file", archive_entry_pathname(ae)); - assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "12345678", 8); - - /* Verify the end of the archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_filter_uuencode.c b/thirdparty/libarchive/libarchive/test/test_write_filter_uuencode.c deleted file mode 100644 index 2ce5b8931..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_filter_uuencode.c +++ /dev/null @@ -1,173 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* - * A basic exercise of uuencode reading and writing. - */ - -DEFINE_TEST(test_write_filter_uuencode) -{ - struct archive_entry *ae; - struct archive* a; - char *buff, *data; - size_t buffsize, datasize; - char path[16]; - size_t used1, used2; - int i; - - buffsize = 2000000; - assert(NULL != (buff = (char *)malloc(buffsize))); - - datasize = 10000; - assert(NULL != (data = (char *)malloc(datasize))); - memset(data, 0, datasize); - - /* - * Write a 100 files and read them all back. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_uuencode(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualInt(ARCHIVE_FILTER_UU, archive_filter_code(a, 0)); - assertEqualString("uuencode", archive_filter_name(a, 0)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used1)); - for (i = 0; i < 99; i++) { - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_filetype(ae, AE_IFREG); - archive_entry_set_size(ae, datasize); - snprintf(path, sizeof(path), "file%03d", i); - archive_entry_copy_pathname(ae, path); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertA(datasize - == (size_t)archive_write_data(a, data, datasize)); - archive_entry_free(ae); - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used1)); - for (i = 0; i < 99; i++) { - snprintf(path, sizeof(path), "file%03d", i); - if (!assertEqualIntA(a, 0, archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualInt(ARCHIVE_FILTER_UU, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Repeat the cycle again, this time setting name and mode - * options. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_uuencode(a)); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "nonexistent-option", "0")); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "compression-level", "abc")); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "compression-level", "99")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_filter_option(a, NULL, "name", "test.tar")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_filter_option(a, NULL, "mode", "0640")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used2)); - for (i = 0; i < 99; i++) { - snprintf(path, sizeof(path), "file%03d", i); - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, path); - archive_entry_set_size(ae, datasize); - archive_entry_set_filetype(ae, AE_IFREG); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertA(datasize == (size_t)archive_write_data(a, data, datasize)); - archive_entry_free(ae); - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used2)); - for (i = 0; i < 99; i++) { - snprintf(path, sizeof(path), "file%03d", i); - if (!assertEqualInt(0, archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualInt(ARCHIVE_FILTER_UU, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Test various premature shutdown scenarios to make sure we - * don't crash or leak memory. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_uuencode(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_uuencode(a)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_uuencode(a)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_uuencode(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used2)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Clean up. - */ - free(data); - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_filter_xz.c b/thirdparty/libarchive/libarchive/test/test_write_filter_xz.c deleted file mode 100644 index e2f1ec821..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_filter_xz.c +++ /dev/null @@ -1,265 +0,0 @@ -/*- - * Copyright (c) 2007 Tim Kientzle - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_compress_xz.c 191183 2009-04-17 01:06:31Z kientzle $"); - -/* - * A basic exercise of xz reading and writing. - * - * TODO: Add a reference file and make sure we can decompress that. - */ - -DEFINE_TEST(test_write_filter_xz) -{ - struct archive_entry *ae; - struct archive* a; - char *buff, *data; - size_t buffsize, datasize; - char path[16]; - size_t used1, used2; - int i, r; - - buffsize = 2000000; - assert(NULL != (buff = (char *)malloc(buffsize))); - if (buff == NULL) - return; - - datasize = 10000; - assert(NULL != (data = (char *)malloc(datasize))); - if (data == NULL) { - free(buff); - return; - } - memset(data, 0, datasize); - - /* - * Write a 100 files and read them all back. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - r = archive_write_add_filter_xz(a); - if (r == ARCHIVE_FATAL) { - skipping("xz writing not supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - free(buff); - free(data); - return; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualInt(ARCHIVE_FILTER_XZ, archive_filter_code(a, 0)); - assertEqualString("xz", archive_filter_name(a, 0)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used1)); - assertEqualInt(ARCHIVE_FILTER_XZ, archive_filter_code(a, 0)); - assertEqualString("xz", archive_filter_name(a, 0)); - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_filetype(ae, AE_IFREG); - archive_entry_set_size(ae, datasize); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - archive_entry_copy_pathname(ae, path); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertA(datasize - == (size_t)archive_write_data(a, data, datasize)); - } - archive_entry_free(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - r = archive_read_support_filter_xz(a); - if (r == ARCHIVE_WARN) { - skipping("Can't verify xz writing by reading back;" - " xz reading not fully supported on this platform"); - } else { - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used1)); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - if (!assertEqualInt(ARCHIVE_OK, - archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Repeat the cycle again, this time setting some compression - * options. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_xz(a)); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "nonexistent-option", "0")); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "compression-level", "abc")); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "compression-level", "99")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_filter_option(a, NULL, "compression-level", "9")); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2)); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, path); - archive_entry_set_size(ae, datasize); - archive_entry_set_filetype(ae, AE_IFREG); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertA(datasize == (size_t)archive_write_data(a, data, datasize)); - archive_entry_free(ae); - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Curiously, this test fails; the test data above compresses - * better at default compression than at level 9. */ - /* - failure("compression-level=9 wrote %d bytes, default wrote %d bytes", - (int)used2, (int)used1); - assert(used2 < used1); - */ - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - r = archive_read_support_filter_xz(a); - if (r == ARCHIVE_WARN) { - skipping("xz reading not fully supported on this platform"); - } else { - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used2)); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - failure("Trying to read %s", path); - if (!assertEqualIntA(a, ARCHIVE_OK, - archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Repeat again, with much lower compression. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_xz(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_filter_option(a, NULL, "compression-level", "0")); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2)); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, path); - archive_entry_set_size(ae, datasize); - archive_entry_set_filetype(ae, AE_IFREG); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - failure("Writing file %s", path); - assertEqualIntA(a, datasize, - (size_t)archive_write_data(a, data, datasize)); - archive_entry_free(ae); - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* I would like to assert that compression-level=0 results in - * larger data than the default compression, but that's not true - * for all versions of liblzma. */ - /* - failure("Compression-level=0 wrote %d bytes; default wrote %d bytes", - (int)used2, (int)used1); - assert(used2 > used1); - */ - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - r = archive_read_support_filter_xz(a); - if (r == ARCHIVE_WARN) { - skipping("xz reading not fully supported on this platform"); - } else { - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used2)); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - if (!assertEqualInt(ARCHIVE_OK, - archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Test various premature shutdown scenarios to make sure we - * don't crash or leak memory. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_xz(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_xz(a)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_xz(a)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_xz(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Clean up. - */ - free(data); - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_filter_zstd.c b/thirdparty/libarchive/libarchive/test/test_write_filter_zstd.c deleted file mode 100644 index 3cdbd812a..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_filter_zstd.c +++ /dev/null @@ -1,295 +0,0 @@ -/*- - * Copyright (c) 2017 Sean Purcell - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_write_filter_zstd) -{ - struct archive_entry *ae; - struct archive *a; - char *buff, *data; - size_t buffsize, datasize; - char path[16]; - size_t used1, used2, used3; - int i, r; - - buffsize = 2000000; - assert(NULL != (buff = (char *)malloc(buffsize))); - if (buff == NULL) - return; - - datasize = 10000; - assert(NULL != (data = (char *)malloc(datasize))); - if (data == NULL) { - free(buff); - return; - } - memset(data, 0, datasize); - - /* - * Write a 100 files and read them all back. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - r = archive_write_add_filter_zstd(a); - if (r != ARCHIVE_OK) { - skipping("zstd writing not supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - free(buff); - free(data); - return; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualInt(ARCHIVE_FILTER_ZSTD, archive_filter_code(a, 0)); - assertEqualString("zstd", archive_filter_name(a, 0)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used1)); - assertEqualInt(ARCHIVE_FILTER_ZSTD, archive_filter_code(a, 0)); - assertEqualString("zstd", archive_filter_name(a, 0)); - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_filetype(ae, AE_IFREG); - archive_entry_set_size(ae, datasize); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - archive_entry_copy_pathname(ae, path); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertA(datasize - == (size_t)archive_write_data(a, data, datasize)); - } - archive_entry_free(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - r = archive_read_support_filter_zstd(a); - if (r == ARCHIVE_WARN) { - skipping("Can't verify zstd writing by reading back;" - " zstd reading not fully supported on this platform"); - } else { - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used1)); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - if (!assertEqualInt(ARCHIVE_OK, - archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Repeat the cycle again, this time setting some compression - * options. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_zstd(a)); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "nonexistent-option", "0")); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "compression-level", "abc")); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "compression-level", "25")); /* too big */ - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_filter_option(a, NULL, "compression-level", "9")); - /* Following is disabled as it will fail on library versions < 1.3.4 */ - /* assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_filter_option(a, NULL, "compression-level", "-1")); */ - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_filter_option(a, NULL, "compression-level", "7")); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "threads", "-1")); /* negative */ - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_filter_option(a, NULL, "threads", "4")); -#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR - /* frame-per-file: boolean */ - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_filter_option(a, NULL, "frame-per-file", "")); - /* min-frame-size: >= 0 */ - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "min-frame-size", "")); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "min-frame-size", "-1")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_filter_option(a, NULL, "min-frame-size", "0")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_filter_option(a, NULL, "min-frame-size", "1048576")); - /* max-frame-size: >= 1024 */ - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "max-frame-size", "")); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "max-frame-size", "-1")); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "max-frame-size", "0")); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "max-frame-size", "1023")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_filter_option(a, NULL, "max-frame-size", "1024")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_filter_option(a, NULL, "max-frame-size", "1048576")); -#endif -#if ZSTD_VERSION_NUMBER >= MINVER_LONG - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_filter_option(a, NULL, "long", "27")); - assertEqualIntA(a, ARCHIVE_FAILED, - archive_write_set_filter_option(a, NULL, "long", "-1")); /* negative */ -#endif - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2)); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, path); - archive_entry_set_size(ae, datasize); - archive_entry_set_filetype(ae, AE_IFREG); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertA(datasize == (size_t)archive_write_data(a, data, datasize)); - archive_entry_free(ae); - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - r = archive_read_support_filter_zstd(a); - if (r == ARCHIVE_WARN) { - skipping("zstd reading not fully supported on this platform"); - } else { - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used2)); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - failure("Trying to read %s", path); - if (!assertEqualIntA(a, ARCHIVE_OK, - archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * One more time at level 1 - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 10)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_zstd(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_filter_option(a, NULL, "compression-level", "1")); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used3)); - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_filetype(ae, AE_IFREG); - archive_entry_set_size(ae, datasize); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - archive_entry_copy_pathname(ae, path); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertA(datasize == (size_t)archive_write_data(a, data, datasize)); - } - archive_entry_free(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - r = archive_read_support_filter_zstd(a); - if (r == ARCHIVE_WARN) { - skipping("zstd reading not fully supported on this platform"); - } else { - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used3)); - for (i = 0; i < 100; i++) { - snprintf(path, sizeof(path), "file%03d", i); - failure("Trying to read %s", path); - if (!assertEqualIntA(a, ARCHIVE_OK, - archive_read_next_header(a, &ae))) - break; - assertEqualString(path, archive_entry_pathname(ae)); - assertEqualInt((int)datasize, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - } - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Check output sizes for various compression levels, expectation - * is that archive size for level=7 < default < level=1 - */ - failure("compression-level=7 wrote %d bytes, default wrote %d bytes", - (int)used2, (int)used1); - assert(used2 < used1); - failure("compression-level=1 wrote %d bytes, default wrote %d bytes", - (int)used3, (int)used1); - assert(used1 < used3); - - /* - * Test various premature shutdown scenarios to make sure we - * don't crash or leak memory. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_zstd(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_zstd(a)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_zstd(a)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_zstd(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2)); - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Clean up. - */ - free(data); - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_7zip.c b/thirdparty/libarchive/libarchive/test/test_write_format_7zip.c deleted file mode 100644 index c8fdcd02c..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_7zip.c +++ /dev/null @@ -1,570 +0,0 @@ -/*- - * Copyright (c) 2011-2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - - -#include "test.h" -__FBSDID("$FreeBSD$"); - -static void -test_basic(const char *compression_type) -{ - char filedata[64]; - struct archive_entry *ae; - struct archive *a; - size_t used; - size_t buffsize = 1000; - char *buff; - - buff = malloc(buffsize); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_7zip(a)); - if (compression_type != NULL && - ARCHIVE_OK != archive_write_set_format_option(a, "7zip", - "compression", compression_type)) { - skipping("%s writing not fully supported on this platform", - compression_type); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - free(buff); - return; - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used)); - - /* - * Write an empty file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(10, archive_entry_mtime_nsec(ae)); - archive_entry_copy_pathname(ae, "empty"); - assertEqualString("empty", archive_entry_pathname(ae)); - archive_entry_set_mode(ae, AE_IFREG | 0755); - assertEqualInt((AE_IFREG | 0755), archive_entry_mode(ae)); - - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* - * Write another empty file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(10, archive_entry_mtime_nsec(ae)); - archive_entry_copy_pathname(ae, "empty2"); - assertEqualString("empty2", archive_entry_pathname(ae)); - archive_entry_set_mode(ae, AE_IFREG | 0444); - assertEqualInt((AE_IFREG | 0444), archive_entry_mode(ae)); - - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* - * Write a file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 100); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(100, archive_entry_mtime_nsec(ae)); - archive_entry_copy_pathname(ae, "file"); - assertEqualString("file", archive_entry_pathname(ae)); - archive_entry_set_mode(ae, AE_IFREG | 0755); - assertEqualInt((AE_IFREG | 0755), archive_entry_mode(ae)); - archive_entry_set_size(ae, 8); - - assertEqualInt(0, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualInt(8, archive_write_data(a, "12345678", 9)); - assertEqualInt(0, archive_write_data(a, "1", 1)); - - /* - * Write another file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(10, archive_entry_mtime_nsec(ae)); - archive_entry_copy_pathname(ae, "file2"); - assertEqualString("file2", archive_entry_pathname(ae)); - archive_entry_set_mode(ae, AE_IFREG | 0755); - assertEqualInt((AE_IFREG | 0755), archive_entry_mode(ae)); - archive_entry_set_size(ae, 4); - - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualInt(4, archive_write_data(a, "1234", 5)); - - /* - * Write a symbolic file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(10, archive_entry_mtime_nsec(ae)); - archive_entry_copy_pathname(ae, "symbolic"); - archive_entry_copy_symlink(ae, "file1"); - assertEqualString("symbolic", archive_entry_pathname(ae)); - archive_entry_set_mode(ae, AE_IFLNK | 0755); - assertEqualInt((AE_IFLNK | 0755), archive_entry_mode(ae)); - - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* - * Write a directory to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 11, 100); - archive_entry_copy_pathname(ae, "dir"); - archive_entry_set_mode(ae, AE_IFDIR | 0755); - archive_entry_set_size(ae, 512); - - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - failure("size should be zero so that applications know not to write"); - assertEqualInt(0, archive_entry_size(ae)); - archive_entry_free(ae); - assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9)); - - /* - * Write a sub directory to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 11, 200); - archive_entry_copy_pathname(ae, "dir/subdir"); - archive_entry_set_mode(ae, AE_IFDIR | 0755); - archive_entry_set_size(ae, 512); - - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - failure("size should be zero so that applications know not to write"); - assertEqualInt(0, archive_entry_size(ae)); - archive_entry_free(ae); - assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9)); - - /* - * Write a sub sub-directory to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 11, 300); - archive_entry_copy_pathname(ae, "dir/subdir/subdir"); - archive_entry_set_mode(ae, AE_IFDIR | 0755); - archive_entry_set_size(ae, 512); - - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - failure("size should be zero so that applications know not to write"); - assertEqualInt(0, archive_entry_size(ae)); - archive_entry_free(ae); - assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9)); - - /* Close out the archive. */ - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Verify the initial header. */ - assertEqualMem(buff, "\x37\x7a\xbc\xaf\x27\x1c\x00\x03", 8); - - /* - * Now, read the data back. - */ - /* With the test memory reader -- seeking mode. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7)); - - /* - * Read and verify first file. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(100, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, - archive_read_data(a, filedata, sizeof(filedata))); - assertEqualMem(filedata, "12345678", 8); - - - /* - * Read the second file back. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file2", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); - assertEqualInt(4, archive_entry_size(ae)); - assertEqualIntA(a, 4, - archive_read_data(a, filedata, sizeof(filedata))); - assertEqualMem(filedata, "1234", 4); - - /* - * Read and verify a symbolic file. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("symbolic", archive_entry_pathname(ae)); - assertEqualString("file1", archive_entry_symlink(ae)); - assertEqualInt(AE_IFLNK | 0755, archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - - /* - * Read and verify an empty file. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("empty", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - - /* - * Read and verify an empty file. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("empty2", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG | 0444, archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - - /* - * Read the sub sub-dir entry back. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(11, archive_entry_mtime(ae)); - assertEqualInt(300, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("dir/subdir/subdir/", archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualIntA(a, 0, archive_read_data(a, filedata, 10)); - - /* - * Read the sub dir entry back. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(11, archive_entry_mtime(ae)); - assertEqualInt(200, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("dir/subdir/", archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualIntA(a, 0, archive_read_data(a, filedata, 10)); - - /* - * Read the dir entry back. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(11, archive_entry_mtime(ae)); - assertEqualInt(100, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("dir/", archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualIntA(a, 0, archive_read_data(a, filedata, 10)); - - /* Verify the end of the archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a)); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - free(buff); -} - -static void -test_basic2(const char *compression_type) -{ - char filedata[64]; - struct archive_entry *ae; - struct archive *a; - size_t used; - size_t buffsize = 1000; - char *buff; - - buff = malloc(buffsize); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_7zip(a)); - if (compression_type != NULL && - ARCHIVE_OK != archive_write_set_format_option(a, "7zip", - "compression", compression_type)) { - skipping("%s writing not fully supported on this platform", - compression_type); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - free(buff); - return; - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used)); - - /* - * Write a file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 100); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(100, archive_entry_mtime_nsec(ae)); - archive_entry_copy_pathname(ae, "file"); - assertEqualString("file", archive_entry_pathname(ae)); - archive_entry_set_mode(ae, AE_IFREG | 0755); - assertEqualInt((AE_IFREG | 0755), archive_entry_mode(ae)); - archive_entry_set_size(ae, 8); - - assertEqualInt(0, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualInt(8, archive_write_data(a, "12345678", 9)); - assertEqualInt(0, archive_write_data(a, "1", 1)); - - /* - * Write another file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(10, archive_entry_mtime_nsec(ae)); - archive_entry_copy_pathname(ae, "file2"); - assertEqualString("file2", archive_entry_pathname(ae)); - archive_entry_set_mode(ae, AE_IFREG | 0755); - assertEqualInt((AE_IFREG | 0755), archive_entry_mode(ae)); - archive_entry_set_size(ae, 4); - - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualInt(4, archive_write_data(a, "1234", 5)); - - /* - * Write a directory to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 11, 100); - archive_entry_copy_pathname(ae, "dir"); - archive_entry_set_mode(ae, AE_IFDIR | 0755); - archive_entry_set_size(ae, 512); - - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - failure("size should be zero so that applications know not to write"); - assertEqualInt(0, archive_entry_size(ae)); - archive_entry_free(ae); - assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9)); - - /* - * Write a sub directory to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 11, 200); - archive_entry_copy_pathname(ae, "dir/subdir"); - archive_entry_set_mode(ae, AE_IFDIR | 0755); - archive_entry_set_size(ae, 512); - - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - failure("size should be zero so that applications know not to write"); - assertEqualInt(0, archive_entry_size(ae)); - archive_entry_free(ae); - assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9)); - - /* - * Write a sub sub-directory to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 11, 300); - archive_entry_copy_pathname(ae, "dir/subdir/subdir"); - archive_entry_set_mode(ae, AE_IFDIR | 0755); - archive_entry_set_size(ae, 512); - - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - failure("size should be zero so that applications know not to write"); - assertEqualInt(0, archive_entry_size(ae)); - archive_entry_free(ae); - assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9)); - - /* Close out the archive. */ - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Verify the initial header. */ - assertEqualMem(buff, "\x37\x7a\xbc\xaf\x27\x1c\x00\x03", 8); - - /* - * Now, read the data back. - */ - /* With the test memory reader -- seeking mode. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7)); - - /* - * Read and verify first file. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(100, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, - archive_read_data(a, filedata, sizeof(filedata))); - assertEqualMem(filedata, "12345678", 8); - - - /* - * Read the second file back. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file2", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); - assertEqualInt(4, archive_entry_size(ae)); - assertEqualIntA(a, 4, - archive_read_data(a, filedata, sizeof(filedata))); - assertEqualMem(filedata, "1234", 4); - - /* - * Read the sub sub-dir entry back. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(11, archive_entry_mtime(ae)); - assertEqualInt(300, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("dir/subdir/subdir/", archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualIntA(a, 0, archive_read_data(a, filedata, 10)); - - /* - * Read the sub dir entry back. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(11, archive_entry_mtime(ae)); - assertEqualInt(200, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("dir/subdir/", archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualIntA(a, 0, archive_read_data(a, filedata, 10)); - - /* - * Read the dir entry back. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(11, archive_entry_mtime(ae)); - assertEqualInt(100, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("dir/", archive_entry_pathname(ae)); - assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualIntA(a, 0, archive_read_data(a, filedata, 10)); - - /* Verify the end of the archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a)); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - free(buff); -} - -DEFINE_TEST(test_write_format_7zip) -{ - /* Test that making a 7-Zip archive file by default compression - * in whatever compressions are supported on the running platform. */ - test_basic(NULL); - /* Test that making a 7-Zip archive file without empty files. */ - test_basic2(NULL); -} - -DEFINE_TEST(test_write_format_7zip_basic_bzip2) -{ - /* Test that making a 7-Zip archive file with bzip2 compression. */ - test_basic("bzip2"); -} - -DEFINE_TEST(test_write_format_7zip_basic_copy) -{ - /* Test that making a 7-Zip archive file without compression. */ - test_basic("copy"); -} - -DEFINE_TEST(test_write_format_7zip_basic_deflate) -{ - /* Test that making a 7-Zip archive file with deflate compression. */ - test_basic("deflate"); -} - -DEFINE_TEST(test_write_format_7zip_basic_lzma1) -{ - /* Test that making a 7-Zip archive file with lzma1 compression. */ - test_basic("lzma1"); -} - -DEFINE_TEST(test_write_format_7zip_basic_lzma2) -{ - /* Test that making a 7-Zip archive file with lzma2 compression. */ - test_basic("lzma2"); -} - -DEFINE_TEST(test_write_format_7zip_basic_ppmd) -{ - /* Test that making a 7-Zip archive file with PPMd compression. */ - test_basic("ppmd"); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_7zip_empty.c b/thirdparty/libarchive/libarchive/test/test_write_format_7zip_empty.c deleted file mode 100644 index 9a503e9d6..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_7zip_empty.c +++ /dev/null @@ -1,299 +0,0 @@ -/*- - * Copyright (c) 2011-2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - - -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* - * Test writing an empty archive. - */ -DEFINE_TEST(test_write_format_7zip_empty_archive) -{ - struct archive *a; - size_t buffsize = 1000; - char *buff; - size_t used; - - buff = malloc(buffsize); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_7zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used)); - - /* Close out the archive. */ - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Verify the archive file size. */ - assertEqualInt(32, used); - - /* Verify the initial header. */ - assertEqualMem(buff, - "\x37\x7a\xbc\xaf\x27\x1c\x00\x03" - "\x8d\x9b\xd5\x0f\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00", 32); - - free(buff); -} - -/* - * Test writing an empty file. - */ -static void -test_only_empty_file(void) -{ - struct archive *a; - struct archive_entry *ae; - size_t buffsize = 1000; - char *buff; - size_t used; - - buff = malloc(buffsize); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_7zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used)); - - /* - * Write an empty file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(10, archive_entry_mtime_nsec(ae)); - archive_entry_set_atime(ae, 2, 20); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(20, archive_entry_atime_nsec(ae)); - archive_entry_set_ctime(ae, 0, 100); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualInt(100, archive_entry_ctime_nsec(ae)); - archive_entry_copy_pathname(ae, "empty"); - assertEqualString("empty", archive_entry_pathname(ae)); - archive_entry_set_mode(ae, AE_IFREG | 0755); - assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae)); - - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Close out the archive. */ - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Verify the archive file size. */ - assertEqualInt(102, used); - - /* Verify the initial header. */ - assertEqualMem(buff, - "\x37\x7a\xbc\xaf\x27\x1c\x00\x03" - "\x00\x5b\x58\x25\x00\x00\x00\x00" - "\x00\x00\x00\x00\x46\x00\x00\x00" - "\x00\x00\x00\x00\x8f\xce\x1d\xf3", 32); - - /* - * Now, read the data back. - */ - /* With the test memory reader -- seeking mode. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7)); - - /* - * Read and verify an empty file. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_atime_nsec(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualInt(100, archive_entry_ctime_nsec(ae)); - assertEqualString("empty", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - - /* Verify the end of the archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a)); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - free(buff); -} - -static void -test_only_empty_files(void) -{ - struct archive *a; - struct archive_entry *ae; - size_t buffsize = 1000; - char *buff; - size_t used; - - buff = malloc(buffsize); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_7zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used)); - - /* - * Write an empty file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(10, archive_entry_mtime_nsec(ae)); - archive_entry_set_atime(ae, 2, 20); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(20, archive_entry_atime_nsec(ae)); - archive_entry_copy_pathname(ae, "empty"); - assertEqualString("empty", archive_entry_pathname(ae)); - archive_entry_set_mode(ae, AE_IFREG | 0755); - assertEqualInt((AE_IFREG | 0755), archive_entry_mode(ae)); - - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* - * Write second empty file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 2, 10); - assertEqualInt(2, archive_entry_mtime(ae)); - assertEqualInt(10, archive_entry_mtime_nsec(ae)); - archive_entry_set_ctime(ae, 2, 10); - assertEqualInt(2, archive_entry_ctime(ae)); - assertEqualInt(10, archive_entry_ctime_nsec(ae)); - archive_entry_copy_pathname(ae, "empty2"); - assertEqualString("empty2", archive_entry_pathname(ae)); - archive_entry_set_mode(ae, AE_IFREG | 0644); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* - * Write third empty file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 3, 10); - assertEqualInt(3, archive_entry_mtime(ae)); - assertEqualInt(10, archive_entry_mtime_nsec(ae)); - archive_entry_copy_pathname(ae, "empty3"); - assertEqualString("empty3", archive_entry_pathname(ae)); - archive_entry_set_mode(ae, AE_IFREG | 0644); - assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); - - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Close out the archive. */ - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Verify the initial header. */ - assertEqualMem(buff, "\x37\x7a\xbc\xaf\x27\x1c\x00\x03", 8); - - /* - * Now, read the data back. - */ - /* With the test memory reader -- seeking mode. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7)); - - /* - * Read and verify an empty file. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_atime_nsec(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("empty", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - - /* - * Read and verify second empty file. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(2, archive_entry_ctime(ae)); - assertEqualInt(0, archive_entry_ctime_nsec(ae)); - assertEqualString("empty2", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - - /* - * Read and verify third empty file. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(3, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("empty3", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - - /* Verify the end of the archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a)); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - free(buff); -} - -DEFINE_TEST(test_write_format_7zip_empty_files) -{ - /* Test that write an empty file. */ - test_only_empty_file(); - test_only_empty_files(); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_7zip_large.c b/thirdparty/libarchive/libarchive/test/test_write_format_7zip_large.c deleted file mode 100644 index b7a90d187..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_7zip_large.c +++ /dev/null @@ -1,172 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - - -#include "test.h" -__FBSDID("$FreeBSD$"); - -#define LARGE_SIZE (1*1024*1024) -static void -test_large(const char *compression_type) -{ - struct archive_entry *ae; - struct archive *a; - size_t used; - size_t buffsize = LARGE_SIZE + 1024 * 256; - size_t datasize = LARGE_SIZE; - char *buff, *filedata, *filedata2; - - assert((buff = malloc(buffsize)) != NULL); - assert((filedata = malloc(datasize)) != NULL); - assert((filedata2 = malloc(datasize)) != NULL); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - if (a == NULL || buff == NULL || filedata == NULL || filedata2 == NULL) { - archive_write_free(a); - free(buff); - free(filedata); - free(filedata2); - return; - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_7zip(a)); - if (compression_type != NULL && - ARCHIVE_OK != archive_write_set_format_option(a, "7zip", - "compression", compression_type)) { - skipping("%s writing not fully supported on this platform", - compression_type); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - free(buff); - free(filedata); - free(filedata2); - return; - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used)); - - /* - * Write a large file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 100); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(100, archive_entry_mtime_nsec(ae)); - archive_entry_copy_pathname(ae, "file"); - assertEqualString("file", archive_entry_pathname(ae)); - archive_entry_set_mode(ae, AE_IFREG | 0755); - assertEqualInt((AE_IFREG | 0755), archive_entry_mode(ae)); - archive_entry_set_size(ae, datasize); - - assertEqualInt(0, archive_write_header(a, ae)); - archive_entry_free(ae); - if (strcmp(compression_type, "ppmd") == 0) { - /* NOTE: PPMd cannot handle random data correctly.*/ - memset(filedata, 'a', datasize); - } else { - fill_with_pseudorandom_data(filedata, datasize); - } - assertEqualInt(datasize, archive_write_data(a, filedata, datasize)); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Verify the initial header. */ - assertEqualMem(buff, "\x37\x7a\xbc\xaf\x27\x1c\x00\x03", 8); - - /* - * Now, read the data back. - */ - /* With the test memory reader -- seeking mode. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7)); - - /* - * Read and verify a large file. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(100, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); - assertEqualInt(datasize, archive_entry_size(ae)); - assertEqualIntA(a, datasize, archive_read_data(a, filedata2, datasize)); - assertEqualMem(filedata, filedata2, datasize); - - /* Verify the end of the archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Verify archive format. */ - assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); - assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a)); - - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - free(buff); - free(filedata); - free(filedata2); -} - -DEFINE_TEST(test_write_format_7zip_large_bzip2) -{ - /* Test that making a 7-Zip archive file with bzip2 compression. */ - test_large("bzip2"); -} - -DEFINE_TEST(test_write_format_7zip_large_copy) -{ - /* Test that making a 7-Zip archive file without compression. */ - test_large("copy"); -} - -DEFINE_TEST(test_write_format_7zip_large_deflate) -{ - /* Test that making a 7-Zip archive file with deflate compression. */ - test_large("deflate"); -} - -DEFINE_TEST(test_write_format_7zip_large_lzma1) -{ - /* Test that making a 7-Zip archive file with lzma1 compression. */ - test_large("lzma1"); -} - -DEFINE_TEST(test_write_format_7zip_large_lzma2) -{ - /* Test that making a 7-Zip archive file with lzma2 compression. */ - test_large("lzma2"); -} - -DEFINE_TEST(test_write_format_7zip_large_ppmd) -{ - /* Test that making a 7-Zip archive file with PPMd compression. */ - test_large("ppmd"); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_ar.c b/thirdparty/libarchive/libarchive/test/test_write_format_ar.c deleted file mode 100644 index 058d3b178..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_ar.c +++ /dev/null @@ -1,192 +0,0 @@ -/*- - * Copyright (c) 2007 Kai Wang - * Copyright (c) 2007 Tim Kientzle - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_format_ar.c 189308 2009-03-03 17:02:51Z kientzle $"); - -static char buff[4096]; -static char buff2[64]; -static char strtab[] = "abcdefghijklmn.o/\nggghhhjjjrrrttt.o/\niiijjjdddsssppp.o/\n"; - -DEFINE_TEST(test_write_format_ar) -{ - struct archive_entry *ae; - struct archive* a; - size_t used; - - /* - * First we try to create a SVR4/GNU format archive. - */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ar_svr4(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff), &used)); - - /* write the filename table */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "//"); - archive_entry_set_size(ae, strlen(strtab)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertA(strlen(strtab) == (size_t)archive_write_data(a, strtab, strlen(strtab))); - archive_entry_free(ae); - - /* write entries */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 0); - assert(1 == archive_entry_mtime(ae)); - archive_entry_set_mode(ae, S_IFREG | 0755); - assert((S_IFREG | 0755) == archive_entry_mode(ae)); - archive_entry_copy_pathname(ae, "abcdefghijklmn.o"); - archive_entry_set_size(ae, 8); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertA(8 == archive_write_data(a, "87654321", 15)); - archive_entry_free(ae); - - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "ggghhhjjjrrrttt.o"); - archive_entry_set_filetype(ae, AE_IFREG); - archive_entry_set_size(ae, 7); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertEqualIntA(a, 7, archive_write_data(a, "7777777", 7)); - archive_entry_free(ae); - - /* test full pathname */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "/usr/home/xx/iiijjjdddsssppp.o"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 8); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertEqualIntA(a, 8, archive_write_data(a, "88877766", 8)); - archive_entry_free(ae); - - /* trailing "/" should be rejected */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "/usr/home/xx/iiijjj/"); - archive_entry_set_size(ae, 8); - assertA(0 != archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Non regular file should be rejected */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "gfgh.o"); - archive_entry_set_mode(ae, S_IFDIR | 0755); - archive_entry_set_size(ae, 6); - assertA(0 != archive_write_header(a, ae)); - archive_entry_free(ae); - - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(archive_filter_bytes(a, -1), - archive_filter_bytes(a, 0)); - assertEqualInt(used, archive_filter_bytes(a, 0)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Now, read the data back. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(0, archive_entry_mtime(ae)); - assertEqualString("//", archive_entry_pathname(ae)); - assertEqualInt(0, archive_entry_size(ae)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualString("abcdefghijklmn.o", archive_entry_pathname(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "87654321", 8); - - assertEqualInt(ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("ggghhhjjjrrrttt.o", archive_entry_pathname(ae)); - assertEqualInt(7, archive_entry_size(ae)); - assertEqualIntA(a, 7, archive_read_data(a, buff2, 11)); - assertEqualMem(buff2, "7777777", 7); - - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualString("iiijjjdddsssppp.o", archive_entry_pathname(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff2, 17)); - assertEqualMem(buff2, "88877766", 8); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Then, we try to create a BSD format archive. - */ - memset(buff, 0, sizeof(buff)); - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ar_bsd(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff), &used)); - - /* write a entry need long name extension */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "ttttyyyyuuuuiiii.o"); - archive_entry_set_filetype(ae, AE_IFREG); - archive_entry_set_size(ae, 5); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertEqualInt(5, archive_entry_size(ae)); - assertEqualIntA(a, 5, archive_write_data(a, "12345", 7)); - archive_entry_free(ae); - - /* write a entry with a short name */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "ttyy.o"); - archive_entry_set_filetype(ae, AE_IFREG); - archive_entry_set_size(ae, 6); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - assertEqualIntA(a, 6, archive_write_data(a, "555555", 7)); - archive_entry_free(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Now, Read the data back */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); - - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualString("ttttyyyyuuuuiiii.o", archive_entry_pathname(ae)); - assertEqualInt(5, archive_entry_size(ae)); - assertEqualIntA(a, 5, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "12345", 5); - - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualString("ttyy.o", archive_entry_pathname(ae)); - assertEqualInt(6, archive_entry_size(ae)); - assertEqualIntA(a, 6, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "555555", 6); - - /* Test EOF */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_cpio.c b/thirdparty/libarchive/libarchive/test/test_write_format_cpio.c deleted file mode 100644 index d5df8a8ce..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_cpio.c +++ /dev/null @@ -1,300 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_format_cpio.c 185672 2008-12-06 06:02:26Z kientzle $"); - -static void -test_format(int (*set_format)(struct archive *)) -{ - char filedata[64]; - struct archive_entry *ae; - struct archive *a; - char *p; - size_t used; - size_t buffsize = 1000000; - char *buff; - int damaged = 0; - - buff = malloc(buffsize); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertA(0 == (*set_format)(a)); - assertA(0 == archive_write_add_filter_none(a)); - assertA(0 == archive_write_open_memory(a, buff, buffsize, &used)); - - /* - * Write a file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - assert(1 == archive_entry_mtime(ae)); - assert(10 == archive_entry_mtime_nsec(ae)); - p = strdup("file"); - archive_entry_copy_pathname(ae, p); - strcpy(p, "XXXX"); - free(p); - assertEqualString("file", archive_entry_pathname(ae)); - archive_entry_set_mode(ae, S_IFREG | 0755); - assert((S_IFREG | 0755) == archive_entry_mode(ae)); - archive_entry_set_size(ae, 8); - - assertA(0 == archive_write_header(a, ae)); - archive_entry_free(ae); - assertA(8 == archive_write_data(a, "12345678", 9)); - - /* - * Write another file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - assert(1 == archive_entry_mtime(ae)); - assert(10 == archive_entry_mtime_nsec(ae)); - p = strdup("file2"); - archive_entry_copy_pathname(ae, p); - strcpy(p, "XXXX"); - free(p); - assertEqualString("file2", archive_entry_pathname(ae)); - archive_entry_set_mode(ae, S_IFREG | 0755); - assert((S_IFREG | 0755) == archive_entry_mode(ae)); - archive_entry_set_size(ae, 4); - - assertA(0 == archive_write_header(a, ae)); - archive_entry_free(ae); - assertA(4 == archive_write_data(a, "1234", 5)); - - /* - * Write a file with a name, filetype, and size. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "name"); - archive_entry_set_size(ae, 0); - archive_entry_set_filetype(ae, AE_IFREG); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - assert(archive_error_string(a) == NULL); - archive_entry_free(ae); - - /* - * Write a file with a name and filetype but no size. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "name"); - archive_entry_unset_size(ae); - archive_entry_set_filetype(ae, AE_IFREG); - assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae)); - assert(archive_error_string(a) != NULL); - archive_entry_free(ae); - - /* - * Write a file with a name and size but no filetype. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "name"); - archive_entry_set_size(ae, 0); - assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae)); - assert(archive_error_string(a) != NULL); - archive_entry_free(ae); - - /* - * Write a file with a size and filetype but no name. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_size(ae, 0); - archive_entry_set_filetype(ae, AE_IFREG); - assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae)); - assert(archive_error_string(a) != NULL); - archive_entry_free(ae); - - /* - * Write a directory to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 11, 110); - archive_entry_copy_pathname(ae, "dir"); - archive_entry_set_mode(ae, S_IFDIR | 0755); - archive_entry_set_size(ae, 512); - - assertA(0 == archive_write_header(a, ae)); - assertEqualInt(0, archive_entry_size(ae)); - archive_entry_free(ae); - assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9)); - - /* - * Write a character device to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "tty0"); - archive_entry_set_mode(ae, S_IFCHR | 0600); - archive_entry_set_size(ae, 0); - archive_entry_set_rdev(ae, 1024); - assertA(0 == archive_write_header(a, ae)); - archive_entry_free(ae); - - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Damage the second entry to test the search-ahead recovery. - * TODO: Move the damage-recovery checking to a separate test; - * it doesn't really belong in this write test. - */ - { - int i; - for (i = 80; i < 150; i++) { - if (memcmp(buff + i, "07070", 5) == 0) { - damaged = 1; - buff[i] = 'X'; - break; - } - } - } - failure("Unable to locate the second header for damage-recovery test."); - assert(damaged == 1); - - /* - * Now, read the data back. - */ - assert((a = archive_read_new()) != NULL); - assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_support_filter_all(a)); - assertA(0 == archive_read_open_memory(a, buff, used)); - - if (!assertEqualIntA(a, 0, archive_read_next_header(a, &ae))) { - archive_read_free(a); - return; - } - - assertEqualInt(1, archive_entry_mtime(ae)); - /* Not the same as above: cpio doesn't store hi-res times. */ - assert(0 == archive_entry_mtime_nsec(ae)); - assert(0 == archive_entry_atime(ae)); - assert(0 == archive_entry_ctime(ae)); - assertEqualString("file", archive_entry_pathname(ae)); - assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertA(8 == archive_read_data(a, filedata, 10)); - assertEqualMem(filedata, "12345678", 8); - - /* - * The second file can't be read because we damaged its header. - */ - - /* - * Read the third file back. - * ARCHIVE_WARN here because the damaged entry was skipped. - */ - assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae)); - assertEqualString("name", archive_entry_pathname(ae)); - - /* - * Read the dir entry back. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(11, archive_entry_mtime(ae)); - assert(0 == archive_entry_mtime_nsec(ae)); - assert(0 == archive_entry_atime(ae)); - assert(0 == archive_entry_ctime(ae)); - assertEqualString("dir", archive_entry_pathname(ae)); - assertEqualInt((S_IFDIR | 0755), archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualIntA(a, 0, archive_read_data(a, filedata, 10)); - - /* - * Read the character device entry back. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString("tty0", archive_entry_pathname(ae)); - assertEqualInt((S_IFCHR | 0600), archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(1024, archive_entry_rdev(ae)); - - /* Verify the end of the archive. */ - assertEqualIntA(a, 1, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - free(buff); -} - -static void -test_big_entries(int (*set_format)(struct archive *), int64_t size, int expected) -{ - struct archive_entry *ae; - struct archive *a; - size_t buffsize = 1000000; - size_t used; - char *buff; - - buff = malloc(buffsize); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertA(0 == (*set_format)(a)); - assertA(0 == archive_write_add_filter_none(a)); - assertA(0 == archive_write_open_memory(a, buff, buffsize, &used)); - - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "file"); - archive_entry_set_size(ae, size); - archive_entry_set_filetype(ae, AE_IFREG); - assertEqualInt(expected, archive_write_header(a, ae)); - if (expected != ARCHIVE_OK) - assert(archive_error_string(a) != NULL); - - archive_entry_free(ae); - archive_write_free(a); - free(buff); -} - - -DEFINE_TEST(test_write_format_cpio) -{ - int64_t size_16m = ((int64_t)1) << 24; - int64_t size_2g = ((int64_t)1) << 31; - int64_t size_4g = ((int64_t)1) << 32; - int64_t size_8g = ((int64_t)1) << 33; - - test_format(archive_write_set_format_cpio_odc); - test_format(archive_write_set_format_cpio_newc); - - test_big_entries(archive_write_set_format_cpio_odc, - size_8g - 1, ARCHIVE_OK); - test_big_entries(archive_write_set_format_cpio_odc, - size_8g, ARCHIVE_FAILED); - test_big_entries(archive_write_set_format_cpio_newc, - size_4g - 1, ARCHIVE_OK); - test_big_entries(archive_write_set_format_cpio_newc, - size_4g, ARCHIVE_FAILED); - test_big_entries(archive_write_set_format_cpio_bin, - size_2g - 1, ARCHIVE_OK); - test_big_entries(archive_write_set_format_cpio_bin, - size_2g, ARCHIVE_FAILED); - test_big_entries(archive_write_set_format_cpio_pwb, - size_16m - 1, ARCHIVE_OK); - test_big_entries(archive_write_set_format_cpio_pwb, - size_16m, ARCHIVE_FAILED); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_cpio_empty.c b/thirdparty/libarchive/libarchive/test/test_write_format_cpio_empty.c deleted file mode 100644 index 3ca5c395e..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_cpio_empty.c +++ /dev/null @@ -1,71 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_format_cpio_empty.c 201247 2009-12-30 05:59:21Z kientzle $"); - -/* - * Check that an "empty" cpio archive is correctly created. - */ - -/* Here's what an empty cpio archive should look like. */ -static char ref[] = -"070707" /* Magic number */ -"000000" /* Dev = 0 */ -"000000" /* ino = 0 */ -"000000" /* mode = 0 */ -"000000" /* uid = 0 */ -"000000" /* gid = 0 */ -"000001" /* nlink = 1 */ -"000000" /* rdev = 0 */ -"00000000000" /* mtime = 0 */ -"000013" /* Namesize = 11 */ -"00000000000" /* filesize = 0 */ -"TRAILER!!!\0"; /* Name */ - -DEFINE_TEST(test_write_format_cpio_empty) -{ - struct archive *a; - char buff[2048]; - size_t used; - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertA(0 == archive_write_set_format_cpio_odc(a)); - assertA(0 == archive_write_add_filter_none(a)); - /* 1-byte block size ensures we see only the required bytes. */ - /* We're not testing the padding here. */ - assertA(0 == archive_write_set_bytes_per_block(a, 1)); - assertA(0 == archive_write_set_bytes_in_last_block(a, 1)); - assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used)); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - failure("Empty cpio archive should be exactly 87 bytes, was %zu.", used); - assert(used == 87); - failure("Empty cpio archive is incorrectly formatted."); - assertEqualMem(buff, ref, 87); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_cpio_newc.c b/thirdparty/libarchive/libarchive/test/test_write_format_cpio_newc.c deleted file mode 100644 index 48b0b2646..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_cpio_newc.c +++ /dev/null @@ -1,209 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_format_cpio_newc.c 201247 2009-12-30 05:59:21Z kientzle $"); - - -static int -is_hex(const char *p, size_t l) -{ - while (l > 0) { - if (*p >= '0' && *p <= '9') { - /* Ascii digit */ - } else if (*p >= 'a' && *p <= 'f') { - /* lowercase letter a-f */ - } else { - /* Not hex. */ - return (0); - } - --l; - ++p; - } - return (1); -} - -/* - * Detailed verification that cpio 'newc' archives are written with - * the correct format. - */ -DEFINE_TEST(test_write_format_cpio_newc) -{ - struct archive *a; - struct archive_entry *entry; - char *buff, *e, *file; - size_t buffsize = 100000; - size_t used; - - buff = malloc(buffsize); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, 0, archive_write_set_format_cpio_newc(a)); - assertEqualIntA(a, 0, archive_write_add_filter_none(a)); - assertEqualIntA(a, 0, archive_write_open_memory(a, buff, buffsize, &used)); - - /* - * Add various files to it. - * TODO: Extend this to cover more filetypes. - */ - - /* Regular file */ - assert((entry = archive_entry_new()) != NULL); - archive_entry_set_mtime(entry, 1, 10); - archive_entry_set_pathname(entry, "file"); - archive_entry_set_mode(entry, S_IFREG | 0664); - archive_entry_set_size(entry, 10); - archive_entry_set_uid(entry, 80); - archive_entry_set_gid(entry, 90); - archive_entry_set_dev(entry, 12); - archive_entry_set_ino(entry, 89); - archive_entry_set_nlink(entry, 1); - assertEqualIntA(a, 0, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualIntA(a, 10, archive_write_data(a, "1234567890", 10)); - - /* Directory */ - assert((entry = archive_entry_new()) != NULL); - archive_entry_set_mtime(entry, 2, 20); - archive_entry_set_pathname(entry, "dir"); - archive_entry_set_mode(entry, S_IFDIR | 0775); - archive_entry_set_size(entry, 10); - archive_entry_set_nlink(entry, 2); - assertEqualIntA(a, 0, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualIntA(a, 0, archive_write_data(a, "1234567890", 10)); - - /* Symlink */ - assert((entry = archive_entry_new()) != NULL); - archive_entry_set_mtime(entry, 3, 30); - archive_entry_set_pathname(entry, "lnk"); - archive_entry_set_mode(entry, 0664); - archive_entry_set_filetype(entry, AE_IFLNK); - archive_entry_set_size(entry, 0); - archive_entry_set_uid(entry, 83); - archive_entry_set_gid(entry, 93); - archive_entry_set_dev(entry, 13); - archive_entry_set_ino(entry, 88); - archive_entry_set_nlink(entry, 1); - archive_entry_set_symlink(entry,"a"); - assertEqualIntA(a, 0, archive_write_header(a, entry)); - archive_entry_free(entry); - - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Verify the archive format. - */ - e = buff; - - /* First entry is "file" */ - file = e; - assert(is_hex(e, 110)); /* Entire header is hex digits. */ - assertEqualMem(e + 0, "070701", 6); /* Magic */ - assert(memcmp(e + 6, "00000000", 8) != 0); /* ino != 0 */ - assertEqualMem(e + 14, "000081b4", 8); /* Mode */ - assertEqualMem(e + 22, "00000050", 8); /* uid */ - assertEqualMem(e + 30, "0000005a", 8); /* gid */ - assertEqualMem(e + 38, "00000001", 8); /* nlink */ - assertEqualMem(e + 46, "00000001", 8); /* mtime */ - assertEqualMem(e + 54, "0000000a", 8); /* File size */ - assertEqualMem(e + 62, "00000000", 8); /* devmajor */ - assertEqualMem(e + 70, "0000000c", 8); /* devminor */ - assertEqualMem(e + 78, "00000000", 8); /* rdevmajor */ - assertEqualMem(e + 86, "00000000", 8); /* rdevminor */ - assertEqualMem(e + 94, "00000005", 8); /* Name size */ - assertEqualMem(e + 102, "00000000", 8); /* CRC */ - assertEqualMem(e + 110, "file\0\0", 6); /* Name contents */ - assertEqualMem(e + 116, "1234567890", 10); /* File body */ - assertEqualMem(e + 126, "\0\0", 2); /* Pad to multiple of 4 */ - e += 128; /* Must be multiple of four here! */ - - /* Second entry is "dir" */ - assert(is_hex(e, 110)); - assertEqualMem(e + 0, "070701", 6); /* Magic */ - assertEqualMem(e + 6, "00000000", 8); /* ino */ - assertEqualMem(e + 14, "000041fd", 8); /* Mode */ - assertEqualMem(e + 22, "00000000", 8); /* uid */ - assertEqualMem(e + 30, "00000000", 8); /* gid */ - assertEqualMem(e + 38, "00000002", 8); /* nlink */ - assertEqualMem(e + 46, "00000002", 8); /* mtime */ - assertEqualMem(e + 54, "00000000", 8); /* File size */ - assertEqualMem(e + 62, "00000000", 8); /* devmajor */ - assertEqualMem(e + 70, "00000000", 8); /* devminor */ - assertEqualMem(e + 78, "00000000", 8); /* rdevmajor */ - assertEqualMem(e + 86, "00000000", 8); /* rdevminor */ - assertEqualMem(e + 94, "00000004", 8); /* Name size */ - assertEqualMem(e + 102, "00000000", 8); /* CRC */ - assertEqualMem(e + 110, "dir\0", 4); /* name */ - assertEqualMem(e + 114, "\0\0", 2); /* Pad to multiple of 4 */ - e += 116; /* Must be multiple of four here! */ - - /* Third entry is "lnk" */ - assert(is_hex(e, 110)); /* Entire header is hex digits. */ - assertEqualMem(e + 0, "070701", 6); /* Magic */ - assert(memcmp(e + 6, file + 6, 8) != 0); /* ino != file ino */ - assert(memcmp(e + 6, "00000000", 8) != 0); /* ino != 0 */ - assertEqualMem(e + 14, "0000a1b4", 8); /* Mode */ - assertEqualMem(e + 22, "00000053", 8); /* uid */ - assertEqualMem(e + 30, "0000005d", 8); /* gid */ - assertEqualMem(e + 38, "00000001", 8); /* nlink */ - assertEqualMem(e + 46, "00000003", 8); /* mtime */ - assertEqualMem(e + 54, "00000001", 8); /* File size */ - assertEqualMem(e + 62, "00000000", 8); /* devmajor */ - assertEqualMem(e + 70, "0000000d", 8); /* devminor */ - assertEqualMem(e + 78, "00000000", 8); /* rdevmajor */ - assertEqualMem(e + 86, "00000000", 8); /* rdevminor */ - assertEqualMem(e + 94, "00000004", 8); /* Name size */ - assertEqualMem(e + 102, "00000000", 8); /* CRC */ - assertEqualMem(e + 110, "lnk\0\0\0", 6); /* Name contents */ - assertEqualMem(e + 116, "a\0\0\0", 4); /* File body + pad */ - e += 120; /* Must be multiple of four here! */ - - /* TODO: Verify other types of entries. */ - - /* Last entry is end-of-archive marker. */ - assert(is_hex(e, 76)); - assertEqualMem(e + 0, "070701", 6); /* Magic */ - assertEqualMem(e + 6, "00000000", 8); /* ino */ - assertEqualMem(e + 14, "00000000", 8); /* Mode */ - assertEqualMem(e + 22, "00000000", 8); /* uid */ - assertEqualMem(e + 30, "00000000", 8); /* gid */ - assertEqualMem(e + 38, "00000001", 8); /* nlink */ - assertEqualMem(e + 46, "00000000", 8); /* mtime */ - assertEqualMem(e + 54, "00000000", 8); /* File size */ - assertEqualMem(e + 62, "00000000", 8); /* devmajor */ - assertEqualMem(e + 70, "00000000", 8); /* devminor */ - assertEqualMem(e + 78, "00000000", 8); /* rdevmajor */ - assertEqualMem(e + 86, "00000000", 8); /* rdevminor */ - assertEqualMem(e + 94, "0000000b", 8); /* Name size */ - assertEqualMem(e + 102, "00000000", 8); /* CRC */ - assertEqualMem(e + 110, "TRAILER!!!\0", 11); /* Name */ - assertEqualMem(e + 121, "\0\0\0", 3); /* Pad to multiple of 4 bytes */ - e += 124; /* Must be multiple of four here! */ - - assertEqualInt((int)used, e - buff); - - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_cpio_odc.c b/thirdparty/libarchive/libarchive/test/test_write_format_cpio_odc.c deleted file mode 100644 index aefb42ea8..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_cpio_odc.c +++ /dev/null @@ -1,237 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_format_cpio_odc.c 201247 2009-12-30 05:59:21Z kientzle $"); - - -static int -is_octal(const char *p, size_t l) -{ - while (l > 0) { - if (*p < '0' || *p > '7') - return (0); - --l; - ++p; - } - return (1); -} - -/* - * Detailed verification that cpio 'odc' archives are written with - * the correct format. - */ -DEFINE_TEST(test_write_format_cpio_odc) -{ - struct archive *a; - struct archive_entry *entry; - char *buff, *e, *file; - size_t buffsize = 100000; - size_t used; - - buff = malloc(buffsize); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, 0, archive_write_set_format_cpio_odc(a)); - assertEqualIntA(a, 0, archive_write_add_filter_none(a)); - assertEqualIntA(a, 0, archive_write_open_memory(a, buff, buffsize, &used)); - - /* - * Add various files to it. - * TODO: Extend this to cover more filetypes. - */ - - /* "file" with 10 bytes of content */ - assert((entry = archive_entry_new()) != NULL); - archive_entry_set_mtime(entry, 1, 10); - archive_entry_set_pathname(entry, "file"); - archive_entry_set_mode(entry, S_IFREG | 0664); - archive_entry_set_size(entry, 10); - archive_entry_set_uid(entry, 80); - archive_entry_set_gid(entry, 90); - archive_entry_set_dev(entry, 12); - archive_entry_set_ino(entry, 89); - archive_entry_set_nlink(entry, 2); - assertEqualIntA(a, 0, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualIntA(a, 10, archive_write_data(a, "1234567890", 10)); - - /* Hardlink to "file" with 10 bytes of content */ - assert((entry = archive_entry_new()) != NULL); - archive_entry_set_mtime(entry, 1, 10); - archive_entry_set_pathname(entry, "linkfile"); - archive_entry_set_mode(entry, S_IFREG | 0664); - archive_entry_set_size(entry, 10); - archive_entry_set_uid(entry, 80); - archive_entry_set_gid(entry, 90); - archive_entry_set_dev(entry, 12); - archive_entry_set_ino(entry, 89); - archive_entry_set_nlink(entry, 2); - assertEqualIntA(a, 0, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualIntA(a, 10, archive_write_data(a, "1234567890", 10)); - - /* "dir" */ - assert((entry = archive_entry_new()) != NULL); - archive_entry_set_mtime(entry, 2, 20); - archive_entry_set_pathname(entry, "dir"); - archive_entry_set_mode(entry, S_IFDIR | 0775); - archive_entry_set_size(entry, 10); - archive_entry_set_nlink(entry, 2); - assertEqualIntA(a, 0, archive_write_header(a, entry)); - archive_entry_free(entry); - /* Write of data to dir should fail == zero bytes get written. */ - assertEqualIntA(a, 0, archive_write_data(a, "1234567890", 10)); - - /* "symlink" pointing to "file" */ - assert((entry = archive_entry_new()) != NULL); - archive_entry_set_mtime(entry, 3, 30); - archive_entry_set_pathname(entry, "symlink"); - archive_entry_set_mode(entry, 0664); - archive_entry_set_filetype(entry, AE_IFLNK); - archive_entry_set_symlink(entry,"file"); - archive_entry_set_size(entry, 0); - archive_entry_set_uid(entry, 88); - archive_entry_set_gid(entry, 98); - archive_entry_set_dev(entry, 12); - archive_entry_set_ino(entry, 90); - archive_entry_set_nlink(entry, 1); - assertEqualIntA(a, 0, archive_write_header(a, entry)); - archive_entry_free(entry); - /* Write of data to symlink should fail == zero bytes get written. */ - assertEqualIntA(a, 0, archive_write_data(a, "1234567890", 10)); - - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Verify the archive format. - * - * Notes on the ino validation: cpio does not actually require - * that the ino values written to the archive match those read - * from disk. It really requires that: - * * matching non-zero ino values be written as matching - * non-zero values - * * non-matching non-zero ino values be written as non-matching - * non-zero values - * Libarchive further ensures that zero ino values get written - * as zeroes. This allows the cpio writer to generate - * synthetic ino values for the archive that may be different - * than those on disk in order to avoid problems due to truncation. - * This is especially needed for odc (POSIX format) that - * only supports 18-bit ino values. - */ - e = buff; - - /* "file" */ - file = e; /* Remember where this starts... */ - assert(is_octal(e, 76)); /* Entire header is octal digits. */ - assertEqualMem(e + 0, "070707", 6); /* Magic */ - assertEqualMem(e + 6, "000014", 6); /* dev */ - assert(memcmp(e + 12, "000000", 6) != 0); /* ino must be != 0 */ - assertEqualMem(e + 18, "100664", 6); /* Mode */ - assertEqualMem(e + 24, "000120", 6); /* uid */ - assertEqualMem(e + 30, "000132", 6); /* gid */ - assertEqualMem(e + 36, "000002", 6); /* nlink */ - assertEqualMem(e + 42, "000000", 6); /* rdev */ - assertEqualMem(e + 48, "00000000001", 11); /* mtime */ - assertEqualMem(e + 59, "000005", 6); /* Name size */ - assertEqualMem(e + 65, "00000000012", 11); /* File size */ - assertEqualMem(e + 76, "file\0", 5); /* Name contents */ - assertEqualMem(e + 81, "1234567890", 10); /* File contents */ - e += 91; - - /* hardlink to "file" */ - assert(is_octal(e, 76)); /* Entire header is octal digits. */ - assertEqualMem(e + 0, "070707", 6); /* Magic */ - assertEqualMem(e + 6, "000014", 6); /* dev */ - assertEqualMem(e + 12, file + 12, 6); /* ino must match above */ - assertEqualMem(e + 18, "100664", 6); /* Mode */ - assertEqualMem(e + 24, "000120", 6); /* uid */ - assertEqualMem(e + 30, "000132", 6); /* gid */ - assertEqualMem(e + 36, "000002", 6); /* nlink */ - assertEqualMem(e + 42, "000000", 6); /* rdev */ - assertEqualMem(e + 48, "00000000001", 11); /* mtime */ - assertEqualMem(e + 59, "000011", 6); /* Name size */ - assertEqualMem(e + 65, "00000000012", 11); /* File size */ - assertEqualMem(e + 76, "linkfile\0", 9); /* Name contents */ - assertEqualMem(e + 85, "1234567890", 10); /* File contents */ - e += 95; - - /* "dir" */ - assert(is_octal(e, 76)); - assertEqualMem(e + 0, "070707", 6); /* Magic */ - assertEqualMem(e + 6, "000000", 6); /* dev */ - assertEqualMem(e + 12, "000000", 6); /* ino */ - assertEqualMem(e + 18, "040775", 6); /* Mode */ - assertEqualMem(e + 24, "000000", 6); /* uid */ - assertEqualMem(e + 30, "000000", 6); /* gid */ - assertEqualMem(e + 36, "000002", 6); /* Nlink */ - assertEqualMem(e + 42, "000000", 6); /* rdev */ - assertEqualMem(e + 48, "00000000002", 11); /* mtime */ - assertEqualMem(e + 59, "000004", 6); /* Name size */ - assertEqualMem(e + 65, "00000000000", 11); /* File size */ - assertEqualMem(e + 76, "dir\0", 4); /* name */ - e += 80; - - /* "symlink" pointing to "file" */ - assert(is_octal(e, 76)); /* Entire header is octal digits. */ - assertEqualMem(e + 0, "070707", 6); /* Magic */ - assertEqualMem(e + 6, "000014", 6); /* dev */ - assert(memcmp(e + 12, file + 12, 6) != 0); /* ino must != file ino */ - assert(memcmp(e + 12, "000000", 6) != 0); /* ino must != 0 */ - assertEqualMem(e + 18, "120664", 6); /* Mode */ - assertEqualMem(e + 24, "000130", 6); /* uid */ - assertEqualMem(e + 30, "000142", 6); /* gid */ - assertEqualMem(e + 36, "000001", 6); /* nlink */ - assertEqualMem(e + 42, "000000", 6); /* rdev */ - assertEqualMem(e + 48, "00000000003", 11); /* mtime */ - assertEqualMem(e + 59, "000010", 6); /* Name size */ - assertEqualMem(e + 65, "00000000004", 11); /* File size */ - assertEqualMem(e + 76, "symlink\0", 8); /* Name contents */ - assertEqualMem(e + 84, "file", 4); /* File contents == link target */ - e += 88; - - /* TODO: Verify other types of entries. */ - - /* Last entry is end-of-archive marker. */ - assert(is_octal(e, 76)); - assertEqualMem(e + 0, "070707", 6); /* Magic */ - assertEqualMem(e + 6, "000000", 6); /* dev */ - assertEqualMem(e + 12, "000000", 6); /* ino */ - assertEqualMem(e + 18, "000000", 6); /* Mode */ - assertEqualMem(e + 24, "000000", 6); /* uid */ - assertEqualMem(e + 30, "000000", 6); /* gid */ - assertEqualMem(e + 36, "000001", 6); /* Nlink */ - assertEqualMem(e + 42, "000000", 6); /* rdev */ - assertEqualMem(e + 48, "00000000000", 11); /* mtime */ - assertEqualMem(e + 59, "000013", 6); /* Name size */ - assertEqualMem(e + 65, "00000000000", 11); /* File size */ - assertEqualMem(e + 76, "TRAILER!!!\0", 11); /* Name */ - e += 87; - - assertEqualInt((int)used, e - buff); - - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_gnutar.c b/thirdparty/libarchive/libarchive/test/test_write_format_gnutar.c deleted file mode 100644 index 2a4c383e7..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_gnutar.c +++ /dev/null @@ -1,258 +0,0 @@ -/*- - * Copyright (c) 2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -static char buff2[64]; - -/* Some names 1026 characters long */ -static const char *longfilename = "abcdefghijklmnopqrstuvwxyz" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890"; - -static const char *longlinkname = "Xabcdefghijklmnopqrstuvwxyz" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890"; - -static const char *longhardlinkname = "Yabcdefghijklmnopqrstuvwxyz" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890" - "12345678901234567890123456789012345678901234567890"; - - -DEFINE_TEST(test_write_format_gnutar) -{ - size_t buffsize = 1000000; - char *buff; - struct archive_entry *ae; - struct archive *a; - size_t used; - - buff = malloc(buffsize); /* million bytes of work area */ - assert(buff != NULL); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertA(0 == archive_write_set_format_gnutar(a)); - assertA(0 == archive_write_add_filter_none(a)); - assertA(0 == archive_write_open_memory(a, buff, buffsize, &used)); - - /* - * "file" has a bunch of attributes and 8 bytes of data. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_birthtime(ae, 3, 30); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "file"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 8); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9)); - - /* - * A file with a very long name - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, longfilename); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 8); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 8, archive_write_data(a, "abcdefgh", 9)); - - /* - * A hardlink to the above file. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, longhardlinkname); - archive_entry_copy_hardlink(ae, longfilename); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 8); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* - * A symlink to the above file. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, longlinkname); - archive_entry_copy_symlink(ae, longfilename); - archive_entry_set_mode(ae, AE_IFLNK | 0755); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* - * A file with large UID/GID that overflow octal encoding. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "large_uid_gid"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 8); - archive_entry_set_uid(ae, 123456789); - archive_entry_set_gid(ae, 987654321); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 8, archive_write_data(a, "abcdefgh", 9)); - - /* TODO: support GNU tar sparse format and test it here. */ - /* See test_write_format_pax for an example of testing sparse files. */ - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); - - /* - * Some basic verification of the low-level format. - */ - - /* Verify GNU tar magic/version fields */ - assertEqualMem(buff + 257, "ustar \0", 8); - - assertEqualInt(15360, used); - - /* - * - * Now, read the data back. - * - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, 0, archive_read_support_format_all(a)); - assertEqualIntA(a, 0, archive_read_support_filter_all(a)); - assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used)); - - /* - * Read "file" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assert(!archive_entry_atime_is_set(ae)); - assert(!archive_entry_birthtime_is_set(ae)); - assert(!archive_entry_ctime_is_set(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualString("file", archive_entry_pathname(ae)); - assertEqualInt(S_IFREG | 0755, archive_entry_mode(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "12345678", 8); - - /* - * Read file with very long name. - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualString(longfilename, archive_entry_pathname(ae)); - assertEqualInt(S_IFREG | 0755, archive_entry_mode(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "abcdefgh", 8); - - /* - * Read hardlink. - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualString(longhardlinkname, archive_entry_pathname(ae)); - assertEqualString(longfilename, archive_entry_hardlink(ae)); - - /* - * Read symlink. - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualString(longlinkname, archive_entry_pathname(ae)); - assertEqualString(longfilename, archive_entry_symlink(ae)); - assertEqualInt(AE_IFLNK | 0755, archive_entry_mode(ae)); - - /* - * Read file with large UID/GID. - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(123456789, archive_entry_uid(ae)); - assertEqualInt(987654321, archive_entry_gid(ae)); - assertEqualString("large_uid_gid", archive_entry_pathname(ae)); - assertEqualInt(S_IFREG | 0755, archive_entry_mode(ae)); - - /* - * Verify the end of the archive. - */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); - - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_gnutar_filenames.c b/thirdparty/libarchive/libarchive/test/test_write_format_gnutar_filenames.c deleted file mode 100644 index 655e998ed..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_gnutar_filenames.c +++ /dev/null @@ -1,151 +0,0 @@ -/*- - * Copyright (c) 2016 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* - * Inspired by Github issue #682, which reported that gnutar filenames - * of exactly 512 bytes weren't getting written correctly. - * - * This writes a filename of every length from 1 to 2000 bytes and - * reads back to verify it. - */ - -static char filename[2048]; - -DEFINE_TEST(test_write_format_gnutar_filenames) -{ - size_t buffsize = 1000000; - char *buff; - struct archive_entry *ae, *template; - struct archive *a; - size_t used; - int i; - - buff = malloc(buffsize); /* million bytes of work area */ - assert(buff != NULL); - - /* Create a template entry. */ - assert((template = archive_entry_new()) != NULL); - archive_entry_set_atime(template, 2, 20); - archive_entry_set_birthtime(template, 3, 30); - archive_entry_set_ctime(template, 4, 40); - archive_entry_set_mtime(template, 5, 50); - archive_entry_set_mode(template, S_IFREG | 0755); - archive_entry_set_size(template, 8); - - for (i = 0; i < 2000; ++i) { - filename[i] = 'a'; - filename[i + 1] = '\0'; - archive_entry_copy_pathname(template, filename); - - /* Write a one-item gnutar format archive. */ - assert((a = archive_write_new()) != NULL); - assertA(0 == archive_write_set_format_gnutar(a)); - assertA(0 == archive_write_add_filter_none(a)); - assertA(0 == archive_write_open_memory(a, buff, buffsize, &used)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, template)); - assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); - - - /* Read back and verify the filename. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, 0, archive_read_support_format_all(a)); - assertEqualIntA(a, 0, archive_read_support_filter_all(a)); - assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used)); - - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualString(filename, archive_entry_pathname(ae)); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); - } - - archive_entry_free(template); - - free(buff); -} - - -DEFINE_TEST(test_write_format_gnutar_linknames) -{ - size_t buffsize = 1000000; - char *buff; - struct archive_entry *ae, *template; - struct archive *a; - size_t used; - int i; - -#ifdef S_IFLNK - assertEqualInt(S_IFLNK, AE_IFLNK); -#endif - - buff = malloc(buffsize); /* million bytes of work area */ - assert(buff != NULL); - - /* Create a template entry. */ - assert((template = archive_entry_new()) != NULL); - archive_entry_set_atime(template, 2, 20); - archive_entry_set_birthtime(template, 3, 30); - archive_entry_set_ctime(template, 4, 40); - archive_entry_set_mtime(template, 5, 50); - archive_entry_set_mode(template, AE_IFLNK | 0755); - archive_entry_copy_pathname(template, "link"); - - for (i = 0; i < 2000; ++i) { - filename[i] = 'a'; - filename[i + 1] = '\0'; - archive_entry_copy_symlink(template, filename); - - /* Write a one-item gnutar format archive. */ - assert((a = archive_write_new()) != NULL); - assertA(0 == archive_write_set_format_gnutar(a)); - assertA(0 == archive_write_add_filter_none(a)); - assertA(0 == archive_write_open_memory(a, buff, buffsize, &used)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, template)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); - - - /* Read back and verify the filename. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, 0, archive_read_support_format_all(a)); - assertEqualIntA(a, 0, archive_read_support_filter_all(a)); - assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used)); - - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualString("link", archive_entry_pathname(ae)); - assertEqualString(filename, archive_entry_symlink(ae)); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); - } - - archive_entry_free(template); - - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_iso9660.c b/thirdparty/libarchive/libarchive/test/test_write_format_iso9660.c deleted file mode 100644 index e4e98bb95..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_iso9660.c +++ /dev/null @@ -1,1110 +0,0 @@ -/*- - * Copyright (c) 2003-2008 Tim Kientzle - * Copyright (c) 2009,2010 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -static char buff2[64]; -DEFINE_TEST(test_write_format_iso9660) -{ - size_t buffsize = 1000000; - char *buff; - struct archive_entry *ae; - struct archive *a; - char dirname[1024]; - char dir[6]; - char longname[] = - "longname00aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" - "cccccccccccccccccccccccccccccccccccccccccccccccccc" - "dddddddddddddddddddddddddddddddddddddddddddddddddd"; - - size_t used; - int i; - - buff = malloc(buffsize); /* million bytes of work area */ - assert(buff != NULL); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertA(0 == archive_write_set_format_iso9660(a)); - assertA(0 == archive_write_add_filter_none(a)); - assertA(0 == archive_write_open_memory(a, buff, buffsize, &used)); - - /* - * "file" has a bunch of attributes and 8 bytes of data. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_birthtime(ae, 3, 30); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "file"); - archive_entry_set_mode(ae, AE_IFREG | 0755); - archive_entry_set_size(ae, 8); - archive_entry_set_nlink(ae, 2); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9)); - - /* - * "hardlnk" has linked to "file". - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_birthtime(ae, 3, 30); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "hardlnk"); - archive_entry_set_mode(ae, AE_IFREG | 0755); - archive_entry_set_hardlink(ae, "file"); - archive_entry_set_nlink(ae, 2); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* - * longname is similar but has birthtime later than mtime. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_birthtime(ae, 8, 80); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, longname); - archive_entry_set_mode(ae, AE_IFREG | 0666); - archive_entry_set_size(ae, 8); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9)); - - /* - * "symlnk has symbolic linked to longname. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "symlnk"); - archive_entry_set_mode(ae, AE_IFLNK | 0555); - archive_entry_set_symlink(ae, longname); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* - * "dir*" has a bunch of attributes. - */ - dirname[0] = '\0'; - strcpy(dir, "/dir0"); - for (i = 0; i < 13; i++) { - dir[4] = "0123456789ABCDEF"[i]; - if (i == 0) - strcat(dirname, dir+1); - else - strcat(dirname, dir); - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_birthtime(ae, 3, 30); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, dirname); - archive_entry_set_mode(ae, S_IFDIR | 0755); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - } - - strcat(dirname, "/file"); - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_birthtime(ae, 3, 30); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, dirname); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 8); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9)); - - /* - * "dir0/dir1/file1" has 8 bytes of data. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_birthtime(ae, 3, 30); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "dir0/dir1/file1"); - archive_entry_set_mode(ae, AE_IFREG | 0755); - archive_entry_set_size(ae, 8); - archive_entry_set_nlink(ae, 1); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9)); - - /* - * "dir0/dir1/file2" has 8 bytes of data. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_birthtime(ae, 3, 30); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "dir0/dir1/file2"); - archive_entry_set_mode(ae, AE_IFREG | 0755); - archive_entry_set_size(ae, 8); - archive_entry_set_nlink(ae, 1); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9)); - - /* - * Add a wrong path "dir0/dir1/file2/wrong" - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_birthtime(ae, 3, 30); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "dir0/dir1/file2/wrong"); - archive_entry_set_mode(ae, AE_IFREG | 0755); - archive_entry_set_size(ae, 8); - archive_entry_set_nlink(ae, 1); - assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); - - /* - * ----------------------------------------------------------- - * Now, read the data back(read Rockridge extensions). - * ----------------------------------------------------------- - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, 0, archive_read_support_format_all(a)); - assertEqualIntA(a, 0, archive_read_support_filter_all(a)); - assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used)); - - /* - * Read Root Directory - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_atime(ae), archive_entry_ctime(ae)); - assertEqualInt(archive_entry_atime(ae), archive_entry_mtime(ae)); - assertEqualString(".", archive_entry_pathname(ae)); - assert((S_IFDIR | 0555) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_birthtime(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0", archive_entry_pathname(ae)); - assert((S_IFDIR | 0555) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_birthtime(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1", archive_entry_pathname(ae)); - assert((S_IFDIR | 0555) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1/dir2" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_birthtime(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1/dir2", archive_entry_pathname(ae)); - assert((S_IFDIR | 0555) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1/dir2/dir3" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_birthtime(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1/dir2/dir3", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0555) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1/dir2/dir3/dir4" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_birthtime(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1/dir2/dir3/dir4", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0555) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1/dir2/dir3/dir4/dir5" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_birthtime(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0555) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_birthtime(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0555) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_birthtime(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0555) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_birthtime(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0555) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_birthtime(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0555) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_birthtime(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0555) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_birthtime(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0555) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB/dirC" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_birthtime(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB/dirC", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0555) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "hardlnk" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_birthtime(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("hardlnk", archive_entry_pathname(ae)); - assert((AE_IFREG | 0555) == archive_entry_mode(ae)); - assertEqualInt(2, archive_entry_nlink(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "12345678", 8); - - /* - * Read "file" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_birthtime(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("file", archive_entry_pathname(ae)); - assertEqualString("hardlnk", archive_entry_hardlink(ae)); - assert((AE_IFREG | 0555) == archive_entry_mode(ae)); - assertEqualInt(2, archive_entry_nlink(ae)); - assertEqualInt(0, archive_entry_size(ae)); - - /* - * Read longname - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assert(archive_entry_atime_is_set(ae)); - assertEqualInt(2, archive_entry_atime(ae)); - /* Birthtime > mtime above, so it doesn't get stored at all. */ - assert(!archive_entry_birthtime_is_set(ae)); - assertEqualInt(0, archive_entry_birthtime(ae)); - assert(archive_entry_ctime_is_set(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assert(archive_entry_mtime_is_set(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString(longname, archive_entry_pathname(ae)); -#if !defined(_WIN32) && !defined(__CYGWIN__) - assert((AE_IFREG | 0444) == archive_entry_mode(ae)); -#else - /* On Windows and CYGWIN, always set all exec bit ON by default. */ - assert((AE_IFREG | 0555) == archive_entry_mode(ae)); -#endif - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "12345678", 8); - - /* - * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB/dirC/file" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_birthtime(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB/dirC/file", archive_entry_pathname(ae)); - assert((AE_IFREG | 0555) == archive_entry_mode(ae)); - assertEqualInt(1, archive_entry_nlink(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "12345678", 8); - - /* - * Read "dir0/dir1/file1" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_birthtime(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1/file1", archive_entry_pathname(ae)); - assert((AE_IFREG | 0555) == archive_entry_mode(ae)); - assertEqualInt(1, archive_entry_nlink(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "12345678", 8); - - /* - * Read "dir0/dir1/file2" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_birthtime(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1/file2", archive_entry_pathname(ae)); - assert((AE_IFREG | 0555) == archive_entry_mode(ae)); - assertEqualInt(1, archive_entry_nlink(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "12345678", 8); - - /* - * Read "symlnk" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assert(archive_entry_atime_is_set(ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assert(!archive_entry_birthtime_is_set(ae)); - assertEqualInt(0, archive_entry_birthtime(ae)); - assert(archive_entry_ctime_is_set(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assert(archive_entry_mtime_is_set(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("symlnk", archive_entry_pathname(ae)); - assert((AE_IFLNK | 0555) == archive_entry_mode(ae)); - assertEqualString(longname, archive_entry_symlink(ae)); - - /* - * Verify the end of the archive. - */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); - - /* - * ----------------------------------------------------------- - * Now, read the data back without Rockridge option - * (read Joliet extensions). - * ----------------------------------------------------------- - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, 0, archive_read_support_format_all(a)); - assertEqualIntA(a, 0, archive_read_support_filter_all(a)); - /* Disable Rockridge extensions support. */ - assertEqualInt(ARCHIVE_OK, - archive_read_set_option(a, NULL, "rockridge", NULL)); - assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used)); - - /* - * Read Root Directory - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_atime(ae), archive_entry_ctime(ae)); - assertEqualInt(archive_entry_atime(ae), archive_entry_mtime(ae)); - assertEqualString(".", archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0", archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1", archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1/dir2" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1/dir2", archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1/dir2/dir3" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1/dir2/dir3", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1/dir2/dir3/dir4" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1/dir2/dir3/dir4", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1/dir2/dir3/dir4/dir5" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB/dirC" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB/dirC", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "file" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("file", archive_entry_pathname(ae)); - assert((AE_IFREG | 0400) == archive_entry_mode(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "12345678", 8); - - /* - * Read "hardlnk" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("hardlnk", archive_entry_pathname(ae)); - assertEqualString("file", archive_entry_hardlink(ae)); - assert((AE_IFREG | 0400) == archive_entry_mode(ae)); - assertEqualInt(2, archive_entry_nlink(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualIntA(a, 0, archive_read_data(a, buff2, 10)); - - /* - * Read longname - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assert(archive_entry_atime_is_set(ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assert(archive_entry_ctime_is_set(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assert(archive_entry_mtime_is_set(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - /* Trim longname to 64 characters. */ - longname[64] = '\0'; - assertEqualString(longname, archive_entry_pathname(ae)); - assert((AE_IFREG | 0400) == archive_entry_mode(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "12345678", 8); - - /* - * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB/dirC/file" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString( - "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB/dirC/file", - archive_entry_pathname(ae)); - assert((AE_IFREG | 0400) == archive_entry_mode(ae)); - assertEqualInt(1, archive_entry_nlink(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "12345678", 8); - - /* - * Read "dir0/dir1/file1" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1/file1", archive_entry_pathname(ae)); - assert((AE_IFREG | 0400) == archive_entry_mode(ae)); - assertEqualInt(1, archive_entry_nlink(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "12345678", 8); - - /* - * Read "dir0/dir1/file2" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("dir0/dir1/file2", archive_entry_pathname(ae)); - assert((AE_IFREG | 0400) == archive_entry_mode(ae)); - assertEqualInt(1, archive_entry_nlink(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "12345678", 8); - - /* - * Read "symlnk" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assert(archive_entry_atime_is_set(ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assert(!archive_entry_birthtime_is_set(ae)); - assertEqualInt(0, archive_entry_birthtime(ae)); - assert(archive_entry_ctime_is_set(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assert(archive_entry_mtime_is_set(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assert((AE_IFREG | 0400) == archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - - /* - * Verify the end of the archive. - */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); - - /* - * ----------------------------------------------------------- - * Now, read the data back without Rockridge and Joliet option - * (read ISO9660). - * This mode appears rr_moved directory. - * ----------------------------------------------------------- - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, 0, archive_read_support_format_all(a)); - assertEqualIntA(a, 0, archive_read_support_filter_all(a)); - /* Disable Rockridge and Joliet extensions support. */ - assertEqualInt(ARCHIVE_OK, - archive_read_set_option(a, NULL, "rockridge", NULL)); - assertEqualInt(ARCHIVE_OK, - archive_read_set_option(a, NULL, "joliet", NULL)); - assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used)); - - /* - * Read Root Directory - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_atime(ae), archive_entry_ctime(ae)); - assertEqualInt(archive_entry_atime(ae), archive_entry_mtime(ae)); - assertEqualString(".", archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "rr_moved" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_atime(ae), archive_entry_ctime(ae)); - assertEqualInt(archive_entry_atime(ae), archive_entry_mtime(ae)); - assertEqualString("RR_MOVED", archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "rr_moved/dir7" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("RR_MOVED/DIR7", archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "rr_moved/dir7/dir8" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("RR_MOVED/DIR7/DIR8", archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "rr_moved/dir7/dir8/dir9" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("RR_MOVED/DIR7/DIR8/DIR9", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "rr_moved/dir7/dir8/dir9/dira" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("RR_MOVED/DIR7/DIR8/DIR9/DIRA", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "rr_moved/dir7/dir8/dir9/dira/dirB" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("RR_MOVED/DIR7/DIR8/DIR9/DIRA/DIRB", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "rr_moved/dir7/dir8/dir9/dirA/dirB/dirC" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("RR_MOVED/DIR7/DIR8/DIR9/DIRA/DIRB/DIRC", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("DIR0", archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("DIR0/DIR1", archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1/dir2" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("DIR0/DIR1/DIR2", archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1/dir2/dir3" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("DIR0/DIR1/DIR2/DIR3", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1/dir2/dir3/dir4" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("DIR0/DIR1/DIR2/DIR3/DIR4", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1/dir2/dir3/dir4/dir5" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("DIR0/DIR1/DIR2/DIR3/DIR4/DIR5", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("DIR0/DIR1/DIR2/DIR3/DIR4/DIR5/DIR6", - archive_entry_pathname(ae)); - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "hardlink" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("HARDLNK", archive_entry_pathname(ae)); - assertEqualString(NULL, archive_entry_hardlink(ae)); - assert((AE_IFREG | 0400) == archive_entry_mode(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "12345678", 8); - - /* - * Read "file" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_birthtime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("FILE", archive_entry_pathname(ae)); - assertEqualString("HARDLNK", archive_entry_hardlink(ae)); - assert((AE_IFREG | 0400) == archive_entry_mode(ae)); - assertEqualInt(2, archive_entry_nlink(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualIntA(a, 0, archive_read_data(a, buff2, 10)); - - - /* - * Read longname - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assert(archive_entry_atime_is_set(ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assert(archive_entry_ctime_is_set(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assert(archive_entry_mtime_is_set(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("LONGNAME", archive_entry_pathname(ae)); - assert((AE_IFREG | 0400) == archive_entry_mode(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "12345678", 8); - - /* - * Read "rr_moved/dir7/dir8/dir9/dirA/dirB/dirC/file" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString( - "RR_MOVED/DIR7/DIR8/DIR9/DIRA/DIRB/DIRC/FILE", - archive_entry_pathname(ae)); - assert((AE_IFREG | 0400) == archive_entry_mode(ae)); - assertEqualInt(1, archive_entry_nlink(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "12345678", 8); - - /* - * Read "dir0/dir1/file1" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("DIR0/DIR1/FILE1", archive_entry_pathname(ae)); - assert((AE_IFREG | 0400) == archive_entry_mode(ae)); - assertEqualInt(1, archive_entry_nlink(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "12345678", 8); - - /* - * Read "dir0/dir1/file2" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("DIR0/DIR1/FILE2", archive_entry_pathname(ae)); - assert((AE_IFREG | 0400) == archive_entry_mode(ae)); - assertEqualInt(1, archive_entry_nlink(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "12345678", 8); - - /* - * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7" as file - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("DIR0/DIR1/DIR2/DIR3/DIR4/DIR5/DIR6/DIR7", - archive_entry_pathname(ae)); - assert((AE_IFREG | 0400) == archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - - /* - * Read "symlnk" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assert(archive_entry_atime_is_set(ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assert(!archive_entry_birthtime_is_set(ae)); - assertEqualInt(0, archive_entry_birthtime(ae)); - assert(archive_entry_ctime_is_set(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assert(archive_entry_mtime_is_set(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("SYMLNK", archive_entry_pathname(ae)); - assert((AE_IFREG | 0400) == archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - - /* - * Verify the end of the archive. - */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); - - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_iso9660_boot.c b/thirdparty/libarchive/libarchive/test/test_write_format_iso9660_boot.c deleted file mode 100644 index 433f63309..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_iso9660_boot.c +++ /dev/null @@ -1,276 +0,0 @@ -/*- - * Copyright (c) 2009 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -/* - * Check that a "bootable CD" ISO 9660 image is correctly created. - */ - -static const unsigned char primary_id[] = { - 0x01, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00 -}; -static const unsigned char volumesize[] = { - 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26 -}; -static const unsigned char volumeidu16[] = { - 0x00, 0x43, 0x00, 0x44, 0x00, 0x52, 0x00, 0x4f, - 0x00, 0x4d, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, - 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, - 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20 -}; -static const unsigned char boot_id[] = { - 0x00, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x45, - 0x4c, 0x20, 0x54, 0x4f, 0x52, 0x49, 0x54, 0x4f, - 0x20, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, - 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -static const unsigned char supplementary_id[] = { - 0x02, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00 -}; -static const unsigned char terminator_id[] = { - 0xff, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00 -}; - -static const unsigned char boot_catalog[] = { - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xaa, 0x55, 0x55, 0xaa, - 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static const unsigned char info_table[] = { - 0x10, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, - 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static const unsigned char el_torito_signature[] = { - "ER\355\001\012T\207\001RRIP_1991ATHE ROCK RIDGE " - "INTERCHANGE PROTOCOL PROVIDES SUPPORT FOR POSIX " - "FILE SYSTEM SEMANTICSPLEASE CONTACT DISC PUBLISHER " - "FOR SPECIFICATION SOURCE. SEE PUBLISHER IDENTIFIER " - "IN PRIMARY VOLUME DESCRIPTOR FOR CONTACT INFORMATION." -}; - -static char buff2[1024]; - -static void -_test_write_format_iso9660_boot(int write_info_tbl) -{ - unsigned char nullb[2048]; - struct archive *a; - struct archive_entry *ae; - unsigned char *buff; - size_t buffsize = 39 * 2048; - size_t used; - unsigned int i; - - memset(nullb, 0, sizeof(nullb)); - buff = malloc(buffsize); - assert(buff != NULL); - - /* ISO9660 format: Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertA(0 == archive_write_set_format_iso9660(a)); - assertA(0 == archive_write_add_filter_none(a)); - assertA(0 == archive_write_set_option(a, NULL, "boot", "boot.img")); - if (write_info_tbl) - assertA(0 == archive_write_set_option(a, NULL, "boot-info-table", "1")); - assertA(0 == archive_write_set_option(a, NULL, "pad", NULL)); - assertA(0 == archive_write_open_memory(a, buff, buffsize, &used)); - - /* - * "boot.img" has a bunch of attributes and 10K bytes of null data. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_birthtime(ae, 3, 30); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "boot.img"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_nlink(ae, 1); - archive_entry_set_size(ae, 10*1024); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - for (i = 0; i < 10; i++) - assertEqualIntA(a, 1024, archive_write_data(a, nullb, 1024)); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); - - assert(used == 2048 * 38); - /* Check System Area. */ - for (i = 0; i < 2048 * 16; i += 2048) { - assertEqualMem(buff+i, nullb, 2048); - } - - /* Primary Volume. */ - failure("Primary Volume Descriptor should be in 16 Logical Sector."); - assertEqualMem(buff+2048*16, primary_id, 8); - assertEqualMem(buff+2048*16+0x28, - "CDROM ", 32); - assertEqualMem(buff+2048*16+0x50, volumesize, 8); - - /* Boot Volume. */ - failure("Boot Volume Descriptor should be in 17 Logical Sector."); - assertEqualMem(buff+2048*17, boot_id, sizeof(boot_id)); - for (i = 0x27; i <= 0x46; i++) { - failure("Unused area must be all nulls."); - assert(buff[2048*17+i] == 0); - } - /* First sector of Boot Catalog. */ - assert(buff[2048*17+0x47] == 0x20); - assert(buff[2048*17+0x48] == 0x00); - assert(buff[2048*17+0x49] == 0x00); - assert(buff[2048*17+0x4a] == 0x00); - for (i = 0x4a; i <= 0x7ff; i++) { - failure("Unused area must be all nulls."); - assert(buff[2048*17+i] == 0); - } - - /* Supplementary Volume. */ - failure("Supplementary Volume(Joliet) Descriptor " - "should be in 18 Logical Sector."); - assertEqualMem(buff+2048*18, supplementary_id, 8); - assertEqualMem(buff+2048*18+0x28, volumeidu16, 32); - assertEqualMem(buff+2048*18+0x50, volumesize, 8); - failure("Date and Time of Primary Volume and " - "Date and Time of Supplementary Volume " - "must be the same."); - assertEqualMem(buff+2048*16+0x32d, buff+2048*18+0x32d, 0x44); - - /* Terminator. */ - failure("Volume Descriptor Set Terminator " - "should be in 19 Logical Sector."); - assertEqualMem(buff+2048*19, terminator_id, 8); - for (i = 8; i < 2048; i++) { - failure("Body of Volume Descriptor Set Terminator " - "should be all nulls."); - assert(buff[2048*19+i] == 0); - } - - /* Check signature of El-Torito. */ - assertEqualMem(buff+2048*31, el_torito_signature, 237); - assertEqualMem(buff+2048*31+237, nullb, 2048-237); - - /* Check contents of "boot.catalog". */ - assertEqualMem(buff+2048*32, boot_catalog, 64); - assertEqualMem(buff+2048*32+64, nullb, 2048-64); - - /* Check contents of "boot.img". */ - if (write_info_tbl) { - assertEqualMem(buff+2048*33, nullb, 8); - assertEqualMem(buff+2048*33+8, info_table, 56); - assertEqualMem(buff+2048*33+64, nullb, 2048-64); - } else { - assertEqualMem(buff+2048*33, nullb, 2048); - } - for (i = 2048*34; i < 2048*38; i += 2048) { - assertEqualMem(buff+i, nullb, 2048); - } - - /* - * Read ISO image. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, 0, archive_read_support_format_all(a)); - assertEqualIntA(a, 0, archive_read_support_filter_all(a)); - assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used)); - - /* - * Read Root Directory - * Root Directory entry must be in ISO image. - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_atime(ae), archive_entry_ctime(ae)); - assertEqualInt(archive_entry_atime(ae), archive_entry_mtime(ae)); - assertEqualString(".", archive_entry_pathname(ae)); - assert((S_IFDIR | 0555) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "boot.catalog". - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualString("boot.catalog", archive_entry_pathname(ae)); -#if !defined(_WIN32) && !defined(__CYGWIN__) - assert((S_IFREG | 0444) == archive_entry_mode(ae)); -#else - /* On Windows and CYGWIN, always set all exec bit ON by default. */ - assert((S_IFREG | 0555) == archive_entry_mode(ae)); -#endif - assertEqualInt(1, archive_entry_nlink(ae)); - assertEqualInt(2*1024, archive_entry_size(ae)); - assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024)); - assertEqualMem(buff2, boot_catalog, 64); - - /* - * Read "boot.img". - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_birthtime(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("boot.img", archive_entry_pathname(ae)); - assert((S_IFREG | 0555) == archive_entry_mode(ae)); - assertEqualInt(1, archive_entry_nlink(ae)); - assertEqualInt(10*1024, archive_entry_size(ae)); - assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024)); - if (write_info_tbl) { - assertEqualMem(buff2, nullb, 8); - assertEqualMem(buff2+8, info_table, 56); - assertEqualMem(buff2+64, nullb, 1024-64); - } else - assertEqualMem(buff2, nullb, 1024); - - /* - * Verify the end of the archive. - */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); - - free(buff); -} - -DEFINE_TEST(test_write_format_iso9660_boot) -{ - _test_write_format_iso9660_boot(0); - /* Use 'boot-info-table' option. */ - _test_write_format_iso9660_boot(1); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_iso9660_empty.c b/thirdparty/libarchive/libarchive/test/test_write_format_iso9660_empty.c deleted file mode 100644 index 55c6c3c7e..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_iso9660_empty.c +++ /dev/null @@ -1,204 +0,0 @@ -/*- - * Copyright (c) 2009-2011 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -/* - * Check that an "empty" ISO 9660 image is correctly created. - */ - -static const unsigned char primary_id[] = { - 0x01, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00 -}; -static const unsigned char volumesize[] = { - 0xb5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5 -}; -static const unsigned char volumeidu16[] = { - 0x00, 0x43, 0x00, 0x44, 0x00, 0x52, 0x00, 0x4f, - 0x00, 0x4d, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, - 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, - 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20 -}; -static const unsigned char supplementary_id[] = { - 0x02, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00 -}; -static const unsigned char terminator_id[] = { - 0xff, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00 -}; - -DEFINE_TEST(test_write_format_iso9660_empty) -{ - struct archive *a; - struct archive_entry *ae; - unsigned char *buff; - size_t buffsize = 190 * 2048; - size_t used; - unsigned int i; - - buff = malloc(buffsize); - assert(buff != NULL); - if (buff == NULL) - return; - - /* ISO9660 format: Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertA(0 == archive_write_set_format_iso9660(a)); - assertA(0 == archive_write_add_filter_none(a)); - assertA(0 == archive_write_set_bytes_per_block(a, 1)); - assertA(0 == archive_write_set_bytes_in_last_block(a, 1)); - assertA(0 == archive_write_open_memory(a, buff, buffsize, &used)); - - /* Add "." entry which must be ignored. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 0); - archive_entry_set_ctime(ae, 4, 0); - archive_entry_set_mtime(ae, 5, 0); - archive_entry_copy_pathname(ae, "."); - archive_entry_set_mode(ae, S_IFDIR | 0755); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Add ".." entry which must be ignored. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 0); - archive_entry_set_ctime(ae, 4, 0); - archive_entry_set_mtime(ae, 5, 0); - archive_entry_copy_pathname(ae, ".."); - archive_entry_set_mode(ae, S_IFDIR | 0755); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Add "/" entry which must be ignored. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 0); - archive_entry_set_ctime(ae, 4, 0); - archive_entry_set_mtime(ae, 5, 0); - archive_entry_copy_pathname(ae, "/"); - archive_entry_set_mode(ae, S_IFDIR | 0755); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Add "../" entry which must be ignored. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 0); - archive_entry_set_ctime(ae, 4, 0); - archive_entry_set_mtime(ae, 5, 0); - archive_entry_copy_pathname(ae, "../"); - archive_entry_set_mode(ae, S_IFDIR | 0755); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Add "../../." entry which must be ignored. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 0); - archive_entry_set_ctime(ae, 4, 0); - archive_entry_set_mtime(ae, 5, 0); - archive_entry_copy_pathname(ae, "../../."); - archive_entry_set_mode(ae, S_IFDIR | 0755); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Add "..//.././" entry which must be ignored. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 0); - archive_entry_set_ctime(ae, 4, 0); - archive_entry_set_mtime(ae, 5, 0); - archive_entry_copy_pathname(ae, "..//.././"); - archive_entry_set_mode(ae, S_IFDIR | 0755); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); - - assert(used == 2048 * 181); - /* Check System Area. */ - for (i = 0; i < 2048 * 16; i++) { - failure("System Area should be all nulls."); - assert(buff[i] == 0); - } - - /* Primary Volume. */ - failure("Primary Volume Descriptor should be in 16 Logical Sector."); - assertEqualMem(buff+2048*16, primary_id, 8); - assertEqualMem(buff+2048*16+0x28, - "CDROM ", 32); - assertEqualMem(buff+2048*16+0x50, volumesize, 8); - - /* Supplementary Volume. */ - failure("Supplementary Volume(Joliet) Descriptor " - "should be in 17 Logical Sector."); - assertEqualMem(buff+2048*17, supplementary_id, 8); - assertEqualMem(buff+2048*17+0x28, volumeidu16, 32); - assertEqualMem(buff+2048*17+0x50, volumesize, 8); - failure("Date and Time of Primary Volume and " - "Date and Time of Supplementary Volume " - "must be the same."); - assertEqualMem(buff+2048*16+0x32d, buff+2048*17+0x32d, 0x44); - - /* Terminator. */ - failure("Volume Descriptor Set Terminator " - "should be in 18 Logical Sector."); - assertEqualMem(buff+2048*18, terminator_id, 8); - for (i = 8; i < 2048; i++) { - failure("Body of Volume Descriptor Set Terminator " - "should be all nulls."); - assert(buff[2048*18+i] == 0); - } - - /* Padding data. */ - for (i = 0; i < 2048*150; i++) { - failure("Padding data should be all nulls."); - assert(buff[2048*31+i] == 0); - } - - /* - * Read ISO image. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, 0, archive_read_support_format_all(a)); - assertEqualIntA(a, 0, archive_read_support_filter_all(a)); - assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used)); - - /* - * Read Root Directory - * Root Directory entry must be in ISO image. - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_atime(ae), archive_entry_ctime(ae)); - assertEqualInt(archive_entry_atime(ae), archive_entry_mtime(ae)); - assertEqualString(".", archive_entry_pathname(ae)); - assert((S_IFDIR | 0555) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Verify the end of the archive. - */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); - - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_iso9660_filename.c b/thirdparty/libarchive/libarchive/test/test_write_format_iso9660_filename.c deleted file mode 100644 index 713883bdc..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_iso9660_filename.c +++ /dev/null @@ -1,474 +0,0 @@ -/*- - * Copyright (c) 2009,2010 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -/* - * Check that an ISO 9660 image is correctly created. - */ -static void -add_entry(struct archive *a, const char *fname, const char *sym) -{ - struct archive_entry *ae; - - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_birthtime(ae, 2, 20); - archive_entry_set_atime(ae, 3, 30); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, fname); - if (sym != NULL) - archive_entry_set_symlink(ae, sym); - archive_entry_set_mode(ae, S_IFREG | 0555); - archive_entry_set_size(ae, 0); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); -} - -struct fns { - size_t maxlen; - size_t longest_len; - size_t maxflen; - size_t maxelen; - size_t alloc; - int cnt; - char **names; - int opt; -#define UPPER_CASE_ONLY 0x00001 -#define ONE_DOT 0x00002 -#define ALLOW_LDOT 0x00004 -}; - -enum vtype { - ROCKRIDGE, - JOLIET, - ISO9660 -}; - -/* - * Verify file - */ -static void -verify_file(struct archive *a, enum vtype type, struct fns *fns) -{ - struct archive_entry *ae; - int i; - - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - if (type == ROCKRIDGE) { - assertEqualInt(2, archive_entry_birthtime(ae)); - assertEqualInt(3, archive_entry_atime(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - } else { - assertEqualInt(0, archive_entry_birthtime_is_set(ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - } - assertEqualInt(5, archive_entry_mtime(ae)); - if (type == ROCKRIDGE) - assert((S_IFREG | 0555) == archive_entry_mode(ae)); - else - assert((S_IFREG | 0400) == archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - - /* - * Check if the same filename does not appear. - */ - for (i = 0; i < fns->cnt; i++) { - const char *p; - const char *pathname = archive_entry_pathname(ae); - const char *symlinkname = archive_entry_symlink(ae); - size_t length; - - if (symlinkname != NULL) { - length = strlen(symlinkname); - assert(length == 1 || length == 128 || length == 255); - assertEqualInt(symlinkname[length-1], 'x'); - } - failure("Found duplicate for %s", pathname); - assert(strcmp(fns->names[i], pathname) != 0); - assert((length = strlen(pathname)) <= fns->maxlen); - if (length > fns->longest_len) - fns->longest_len = length; - p = strrchr(pathname, '.'); - if (p != NULL) { - /* Check a length of file name. */ - assert((size_t)(p - pathname) <= fns->maxflen); - /* Check a length of file extension. */ - assert(strlen(p+1) <= fns->maxelen); - if (fns->opt & ONE_DOT) { - /* Do not have multi dot. */ - assert(strchr(pathname, '.') == p); - } - } - for (p = pathname; *p; p++) { - if (fns->opt & UPPER_CASE_ONLY) { - /* Do not have any lower-case character. */ - assert(*p < 'a' || *p > 'z'); - } else - break; - } - if ((fns->opt & ALLOW_LDOT) == 0) - /* Do not have a dot at the first position. */ - assert(*pathname != '.'); - } - /* Save the filename which is appeared to use above next time. */ - fns->names[fns->cnt++] = strdup(archive_entry_pathname(ae)); -} - -static void -verify(unsigned char *buff, size_t used, enum vtype type, struct fns *fns) -{ - struct archive *a; - struct archive_entry *ae; - size_t i; - - /* - * Read ISO image. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, 0, archive_read_support_format_all(a)); - assertEqualIntA(a, 0, archive_read_support_filter_all(a)); - if (type >= 1) - assertA(0 == archive_read_set_option(a, NULL, "rockridge", - NULL)); - if (type >= 2) - assertA(0 == archive_read_set_option(a, NULL, "joliet", - NULL)); - assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used)); - - /* - * Read Root Directory - * Root Directory entry must be in ISO image. - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_atime(ae), archive_entry_ctime(ae)); - assertEqualInt(archive_entry_atime(ae), archive_entry_mtime(ae)); - assertEqualString(".", archive_entry_pathname(ae)); - switch (type) { - case ROCKRIDGE: - assert((S_IFDIR | 0555) == archive_entry_mode(ae)); - break; - case JOLIET: - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - break; - case ISO9660: - assert((S_IFDIR | 0700) == archive_entry_mode(ae)); - break; - } - - /* - * Verify file status. - */ - memset(fns->names, 0, sizeof(char *) * fns->alloc); - fns->cnt = 0; - for (i = 0; i < fns->alloc; i++) - verify_file(a, type, fns); - for (i = 0; i < fns->alloc; i++) - free(fns->names[i]); - assertEqualInt((int)fns->longest_len, (int)fns->maxlen); - - /* - * Verify the end of the archive. - */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); -} - -static int -create_iso_image(unsigned char *buff, size_t buffsize, size_t *used, - const char *opt) -{ - struct archive *a; - int i, l, fcnt; - const int lens[] = { - 0, 1, 3, 5, 7, 8, 9, 29, 30, 31, 32, - 62, 63, 64, 65, 101, 102, 103, 104, - 191, 192, 193, 194, 204, 205, 206, 207, 208, - 252, 253, 254, 255, - -1 }; - char fname1[256]; - char fname2[256]; - char sym1[2]; - char sym128[129]; - char sym255[256]; - - /* ISO9660 format: Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertA(0 == archive_write_set_format_iso9660(a)); - assertA(0 == archive_write_add_filter_none(a)); - assertA(0 == archive_write_set_option(a, NULL, "pad", NULL)); - if (opt) - assertA(0 == archive_write_set_options(a, opt)); - assertA(0 == archive_write_set_bytes_per_block(a, 1)); - assertA(0 == archive_write_set_bytes_in_last_block(a, 1)); - assertA(0 == archive_write_open_memory(a, buff, buffsize, used)); - - sym1[0] = 'x'; - sym1[1] = '\0'; - for (i = 0; i < (int)sizeof(sym128)-2; i++) - sym128[i] = 'a'; - sym128[sizeof(sym128)-2] = 'x'; - sym128[sizeof(sym128)-1] = '\0'; - for (i = 0; i < (int)sizeof(sym255)-2; i++) - sym255[i] = 'a'; - sym255[sizeof(sym255)-2] = 'x'; - sym255[sizeof(sym255)-1] = '\0'; - - fcnt = 0; - for (i = 0; lens[i] >= 0; i++) { - for (l = 0; l < lens[i]; l++) { - fname1[l] = 'a'; - fname2[l] = 'A'; - } - if (l > 0) { - fname1[l] = '\0'; - fname2[l] = '\0'; - add_entry(a, fname1, NULL); - add_entry(a, fname2, sym1); - fcnt += 2; - } - if (l < 254) { - fname1[l] = '.'; - fname1[l+1] = 'c'; - fname1[l+2] = '\0'; - fname2[l] = '.'; - fname2[l+1] = 'C'; - fname2[l+2] = '\0'; - add_entry(a, fname1, sym128); - add_entry(a, fname2, sym255); - fcnt += 2; - } - if (l < 252) { - fname1[l] = '.'; - fname1[l+1] = 'p'; - fname1[l+2] = 'n'; - fname1[l+3] = 'g'; - fname1[l+4] = '\0'; - fname2[l] = '.'; - fname2[l+1] = 'P'; - fname2[l+2] = 'N'; - fname2[l+3] = 'G'; - fname2[l+4] = '\0'; - add_entry(a, fname1, NULL); - add_entry(a, fname2, sym1); - fcnt += 2; - } - if (l < 251) { - fname1[l] = '.'; - fname1[l+1] = 'j'; - fname1[l+2] = 'p'; - fname1[l+3] = 'e'; - fname1[l+4] = 'g'; - fname1[l+5] = '\0'; - fname2[l] = '.'; - fname2[l+1] = 'J'; - fname2[l+2] = 'P'; - fname2[l+3] = 'E'; - fname2[l+4] = 'G'; - fname2[l+5] = '\0'; - add_entry(a, fname1, sym128); - add_entry(a, fname2, sym255); - fcnt += 2; - } - } - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); - - return (fcnt); -} - -DEFINE_TEST(test_write_format_iso9660_filename) -{ - unsigned char *buff; - size_t buffsize = 120 * 2048; - size_t used; - int fcnt; - struct fns fns; - - buff = malloc(buffsize); - assert(buff != NULL); - if (buff == NULL) - return; - memset(&fns, 0, sizeof(fns)); - - /* - * Create ISO image with no option. - */ - fcnt = create_iso_image(buff, buffsize, &used, NULL); - - fns.names = (char **)malloc(sizeof(char *) * fcnt); - assert(fns.names != NULL); - if (fns.names == NULL) { - free(buff); - return; - } - fns.alloc = fcnt; - - /* Verify rockridge filenames. */ - fns.longest_len = 0; - fns.maxlen = fns.maxflen = fns.maxelen = 255; - fns.opt = ALLOW_LDOT; - verify(buff, used, ROCKRIDGE, &fns); - - /* Verify joliet filenames. */ - fns.longest_len = 0; - fns.maxlen = fns.maxflen = fns.maxelen = 64; - fns.opt = ALLOW_LDOT; - verify(buff, used, JOLIET, &fns); - - /* Verify ISO9660 filenames. */ - fns.longest_len = 0; - fns.maxlen = 8+3+1; - fns.maxflen = 8; - fns.maxelen = 3; - fns.opt = UPPER_CASE_ONLY | ONE_DOT; - verify(buff, used, ISO9660, &fns); - - /* - * Create ISO image with iso-level=2. - */ - assertEqualInt(fcnt, create_iso_image(buff, buffsize, &used, - "iso-level=2")); - - /* Verify rockridge filenames. */ - fns.longest_len = 0; - fns.maxlen = fns.maxflen = fns.maxelen = 255; - fns.opt = ALLOW_LDOT; - verify(buff, used, ROCKRIDGE, &fns); - - /* Verify joliet filenames. */ - fns.longest_len = 0; - fns.maxlen = fns.maxflen = fns.maxelen = 64; - fns.opt = ALLOW_LDOT; - verify(buff, used, JOLIET, &fns); - - /* Verify ISO9660 filenames. */ - fns.longest_len = 0; - fns.maxlen = 31; - fns.maxflen = 30; - fns.maxelen = 30; - fns.opt = UPPER_CASE_ONLY | ONE_DOT; - verify(buff, used, ISO9660, &fns); - - /* - * Create ISO image with iso-level=3. - */ - assertEqualInt(fcnt, create_iso_image(buff, buffsize, &used, - "iso-level=3")); - - /* Verify rockridge filenames. */ - fns.longest_len = 0; - fns.maxlen = fns.maxflen = fns.maxelen = 255; - fns.opt = ALLOW_LDOT; - verify(buff, used, ROCKRIDGE, &fns); - - /* Verify joliet filenames. */ - fns.longest_len = 0; - fns.maxlen = fns.maxflen = fns.maxelen = 64; - fns.opt = ALLOW_LDOT; - verify(buff, used, JOLIET, &fns); - - /* Verify ISO9660 filenames. */ - fns.longest_len = 0; - fns.maxlen = 31; - fns.maxflen = 30; - fns.maxelen = 30; - fns.opt = UPPER_CASE_ONLY | ONE_DOT; - verify(buff, used, ISO9660, &fns); - - /* - * Create ISO image with iso-level=4. - */ - assertEqualInt(fcnt, create_iso_image(buff, buffsize, &used, - "iso-level=4")); - - /* Verify rockridge filenames. */ - fns.longest_len = 0; - fns.maxlen = fns.maxflen = fns.maxelen = 255; - fns.opt = ALLOW_LDOT; - verify(buff, used, ROCKRIDGE, &fns); - - /* Verify joliet filenames. */ - fns.longest_len = 0; - fns.maxlen = fns.maxflen = fns.maxelen = 64; - fns.opt = ALLOW_LDOT; - verify(buff, used, JOLIET, &fns); - - /* Verify ISO9660 filenames. */ - fns.longest_len = 0; - fns.maxlen = fns.maxflen = fns.maxelen = 193; - fns.opt = ALLOW_LDOT; - verify(buff, used, ISO9660, &fns); - - /* - * Create ISO image with iso-level=4 and !rockridge. - */ - assertEqualInt(fcnt, create_iso_image(buff, buffsize, &used, - "iso-level=4,!rockridge")); - - /* Verify joliet filenames. */ - fns.longest_len = 0; - fns.maxlen = fns.maxflen = fns.maxelen = 64; - fns.opt = ALLOW_LDOT; - verify(buff, used, JOLIET, &fns); - - /* Verify ISO9660 filenames. */ - fns.longest_len = 0; - fns.maxlen = fns.maxflen = fns.maxelen = 207; - fns.opt = ALLOW_LDOT; - verify(buff, used, ISO9660, &fns); - - /* - * Create ISO image with joliet=long. - */ - assertEqualInt(fcnt, create_iso_image(buff, buffsize, &used, - "joliet=long")); - - /* Verify rockridge filenames. */ - fns.longest_len = 0; - fns.maxlen = fns.maxflen = fns.maxelen = 255; - fns.opt = ALLOW_LDOT; - verify(buff, used, ROCKRIDGE, &fns); - - /* Verify joliet filenames. */ - fns.longest_len = 0; - fns.maxlen = fns.maxflen = fns.maxelen = 103; - fns.opt = ALLOW_LDOT; - verify(buff, used, JOLIET, &fns); - - /* Verify ISO9660 filenames. */ - fns.longest_len = 0; - fns.maxlen = 8+3+1; - fns.maxflen = 8; - fns.maxelen = 3; - fns.opt = UPPER_CASE_ONLY | ONE_DOT; - verify(buff, used, ISO9660, &fns); - - free(fns.names); - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_iso9660_zisofs.c b/thirdparty/libarchive/libarchive/test/test_write_format_iso9660_zisofs.c deleted file mode 100644 index 2140ed8c3..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_iso9660_zisofs.c +++ /dev/null @@ -1,828 +0,0 @@ -/*- - * Copyright (c) 2009-2011 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -/* - * Check that a "zisofs" ISO 9660 image is correctly created. - */ - -static const unsigned char primary_id[] = { - 0x01, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00 -}; -static const unsigned char volumesize[] = { - 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23 -}; -static const unsigned char volumesize2[] = { - 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36 -}; -static const unsigned char volumesize3[] = { - 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28 -}; -static const unsigned char volumeidu16[] = { - 0x00, 0x43, 0x00, 0x44, 0x00, 0x52, 0x00, 0x4f, - 0x00, 0x4d, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, - 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, - 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20 -}; -static const unsigned char supplementary_id[] = { - 0x02, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00 -}; -static const unsigned char terminator_id[] = { - 0xff, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00 -}; - -static const unsigned char zisofs_magic[8] = { - 0x37, 0xE4, 0x53, 0x96, 0xC9, 0xDB, 0xD6, 0x07 -}; - -static const unsigned char zisofs_data[24] = { - 0x37, 0xe4, 0x53, 0x96, 0xc9, 0xdb, 0xd6, 0x07, - 0x00, 0x80, 0x00, 0x00, 0x04, 0x0f, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00 -}; - -static const unsigned char boot_id[] = { - 0x00, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x45, - 0x4c, 0x20, 0x54, 0x4f, 0x52, 0x49, 0x54, 0x4f, - 0x20, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, - 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -static const unsigned char boot_catalog[] = { - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xaa, 0x55, 0x55, 0xaa, - 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static const unsigned char el_torito_signature[] = { - "ER\355\001\012T\207\001RRIP_1991ATHE ROCK RIDGE " - "INTERCHANGE PROTOCOL PROVIDES SUPPORT FOR POSIX " - "FILE SYSTEM SEMANTICSPLEASE CONTACT DISC PUBLISHER " - "FOR SPECIFICATION SOURCE. SEE PUBLISHER IDENTIFIER " - "IN PRIMARY VOLUME DESCRIPTOR FOR CONTACT INFORMATION." -}; - -static void -test_write_format_iso9660_zisofs_1(void) -{ - unsigned char buff2[1024]; - unsigned char nullb[1024]; - struct archive *a; - struct archive_entry *ae; - unsigned char *buff; - size_t buffsize = 36 * 2048; - size_t used; - unsigned int i; - int r; - - memset(nullb, 0, sizeof(nullb)); - buff = malloc(buffsize); - assert(buff != NULL); - if (buff == NULL) - return; - - /* ISO9660 format: Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, 0, archive_write_set_format_iso9660(a)); - assertEqualIntA(a, 0, archive_write_add_filter_none(a)); - r = archive_write_set_option(a, NULL, "zisofs", "1"); - if (r == ARCHIVE_FATAL) { - skipping("zisofs option not supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - free(buff); - return; - } - assertEqualIntA(a, 0, archive_write_set_option(a, NULL, "pad", NULL)); - assertEqualIntA(a, 0, archive_write_open_memory(a, buff, buffsize, &used)); - - /* - * "file1" has a bunch of attributes and 256K bytes of null data. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_birthtime(ae, 3, 30); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "file1"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 256*1024); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 1024, archive_write_data(a, nullb, 1024)); - - /* - * "file2" has a bunch of attributes and 2048 bytes of null data. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_birthtime(ae, 3, 30); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "file2"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 2048); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 1024, archive_write_data(a, nullb, 1024)); - - /* - * "file3" has a bunch of attributes and 2049 bytes of null data. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_birthtime(ae, 3, 30); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "file3"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 2049); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 1024, archive_write_data(a, nullb, 1024)); - - /* - * "file4" has a bunch of attributes and 24 bytes of zisofs data - * which is compressed from 32K bytes null data. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_birthtime(ae, 3, 30); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "file4"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 24); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 24, archive_write_data(a, zisofs_data, 24)); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); - - failure("The ISO image size should be 71680 bytes."); - assertEqualInt(used, 2048 * 35); - - /* Check System Area. */ - for (i = 0; i < 2048 * 16; i++) { - failure("System Area should be all nulls."); - assertEqualInt(buff[i], 0); - } - - /* Primary Volume. */ - failure("Primary Volume Descriptor should be in 16 Logical Sector."); - assertEqualMem(buff+2048*16, primary_id, 8); - assertEqualMem(buff+2048*16+0x28, - "CDROM ", 32); - assertEqualMem(buff+2048*16+0x50, volumesize, 8); - - /* Supplementary Volume. */ - failure("Supplementary Volume(Joliet) Descriptor " - "should be in 17 Logical Sector."); - assertEqualMem(buff+2048*17, supplementary_id, 8); - assertEqualMem(buff+2048*17+0x28, volumeidu16, 32); - assertEqualMem(buff+2048*17+0x50, volumesize, 8); - failure("Date and Time of Primary Volume and " - "Date and Time of Supplementary Volume " - "must be the same."); - assertEqualMem(buff+2048*16+0x32d, buff+2048*17+0x32d, 0x44); - - /* Terminator. */ - failure("Volume Descriptor Set Terminator " - "should be in 18 Logical Sector."); - assertEqualMem(buff+2048*18, terminator_id, 8); - for (i = 8; i < 2048; i++) { - failure("Body of Volume Descriptor Set Terminator " - "should be all nulls."); - assertEqualInt(buff[2048*18+i], 0); - } - - /* "file1" Contents is zisofs data. */ - failure("file1 image should be zisofs'ed."); - assertEqualMem(buff+2048*31, zisofs_magic, 8); - /* "file2" Contents is not zisofs data. */ - failure("file2 image should not be zisofs'ed."); - assertEqualMem(buff+2048*32, nullb, 8); - /* "file3" Contents is zisofs data. */ - failure("file3 image should be zisofs'ed."); - assertEqualMem(buff+2048*33, zisofs_magic, 8); - /* "file4" Contents is zisofs data. */ - failure("file4 image should be zisofs'ed."); - assertEqualMem(buff+2048*34, zisofs_magic, 8); - - /* - * Read ISO image. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, 0, archive_read_support_format_all(a)); - assertEqualIntA(a, 0, archive_read_support_filter_all(a)); - assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used)); - - /* - * Read Root Directory - * Root Directory entry must be in ISO image. - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_atime(ae), archive_entry_ctime(ae)); - assertEqualInt(archive_entry_atime(ae), archive_entry_mtime(ae)); - assertEqualString(".", archive_entry_pathname(ae)); - assert((S_IFDIR | 0555) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "file1" which has 256K bytes null data. - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - /* assertEqualInt(3, archive_entry_birthtime(ae)); */ - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("file1", archive_entry_pathname(ae)); - assert((S_IFREG | 0555) == archive_entry_mode(ae)); - assertEqualInt(256*1024, archive_entry_size(ae)); - assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024)); - assertEqualMem(buff2, nullb, 1024); - - /* - * Read "file2" which has 2048 bytes null data. - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - /* assertEqualInt(3, archive_entry_birthtime(ae)); */ - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("file2", archive_entry_pathname(ae)); - assert((S_IFREG | 0555) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024)); - assertEqualMem(buff2, nullb, 1024); - - /* - * Read "file3" which has 2049 bytes null data. - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - /* assertEqualInt(3, archive_entry_birthtime(ae)); */ - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("file3", archive_entry_pathname(ae)); - assert((S_IFREG | 0555) == archive_entry_mode(ae)); - assertEqualInt(2049, archive_entry_size(ae)); - assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024)); - assertEqualMem(buff2, nullb, 1024); - - /* - * Read "file4" which has 32K bytes null data. - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - /* assertEqualInt(3, archive_entry_birthtime(ae)); */ - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("file4", archive_entry_pathname(ae)); - assert((S_IFREG | 0555) == archive_entry_mode(ae)); - assertEqualInt(32768, archive_entry_size(ae)); - assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024)); - assertEqualMem(buff2, nullb, 1024); - - /* - * Verify the end of the archive. - */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); - - free(buff); -} - -static void -test_write_format_iso9660_zisofs_2(void) -{ - unsigned char buff2[1024]; - unsigned char data[1024]; - struct archive *a; - struct archive_entry *ae; - unsigned char *buff; - size_t buffsize = 60 * 2048; - size_t used; - unsigned int i; - int r; - - buff = malloc(buffsize); - assert(buff != NULL); - if (buff == NULL) - return; - - /* ISO9660 format: Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, 0, archive_write_set_format_iso9660(a)); - assertEqualIntA(a, 0, archive_write_add_filter_none(a)); - r = archive_write_set_option(a, NULL, "zisofs", "1"); - if (r == ARCHIVE_FATAL) { - skipping("zisofs option not supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - free(buff); - return; - } - assertEqualIntA(a, 0, archive_write_set_option(a, NULL, "pad", NULL)); - assertEqualIntA(a, 0, archive_write_open_memory(a, buff, buffsize, &used)); - - /* - * "file1" has a bunch of attributes and 256K bytes of random data. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_birthtime(ae, 3, 30); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "file1"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 256*1024); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - for (i = 0; i < 256; i++) { - int j; - if (i == 0) { - for (j = 0; j < (int)sizeof(data); j++) - data[j] = (i^j) & 0xff; - } else { - for (j = 0; j < (int)sizeof(data); j++) - data[j] ^= i+j; - } - assertEqualIntA(a, 1024, archive_write_data(a, data, 1024)); - } - - /* - * "file2" has a bunch of attributes and 2048 bytes data. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_birthtime(ae, 3, 30); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "file2"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 2048); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - memset(data, 'a', sizeof(data)); - assertEqualIntA(a, 1024, archive_write_data(a, data, 1024)); - memset(data, 'b', sizeof(data)); - assertEqualIntA(a, 1024, archive_write_data(a, data, 1024)); - - /* - * "file3" has a bunch of attributes and 1024 bytes of 'Z' - * + 1025 bytes of null data. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_birthtime(ae, 3, 30); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "file3"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 2049); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - memset(data, 'Z', sizeof(data)); - assertEqualIntA(a, 1024, archive_write_data(a, data, 1024)); - - /* - * "file4" has a bunch of attributes and 24 bytes of zisofs data - * which is compressed from 32K bytes null data. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_birthtime(ae, 3, 30); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "file4"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 24); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 24, archive_write_data(a, zisofs_data, 24)); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); - - failure("The ISO image size should be 110592 bytes."); - assertEqualInt(used, 2048 * 54); - - /* Check System Area. */ - for (i = 0; i < 2048 * 16; i++) { - failure("System Area should be all nulls."); - assertEqualInt(buff[i], 0); - } - - /* Primary Volume. */ - failure("Primary Volume Descriptor should be in 16 Logical Sector."); - assertEqualMem(buff+2048*16, primary_id, 8); - assertEqualMem(buff+2048*16+0x28, - "CDROM ", 32); - assertEqualMem(buff+2048*16+0x50, volumesize2, 8); - - /* Supplementary Volume. */ - failure("Supplementary Volume(Joliet) Descriptor " - "should be in 17 Logical Sector."); - assertEqualMem(buff+2048*17, supplementary_id, 8); - assertEqualMem(buff+2048*17+0x28, volumeidu16, 32); - assertEqualMem(buff+2048*17+0x50, volumesize2, 8); - failure("Date and Time of Primary Volume and " - "Date and Time of Supplementary Volume " - "must be the same."); - assertEqualMem(buff+2048*16+0x32d, buff+2048*17+0x32d, 0x44); - - /* Terminator. */ - failure("Volume Descriptor Set Terminator " - "should be in 18 Logical Sector."); - assertEqualMem(buff+2048*18, terminator_id, 8); - for (i = 8; i < 2048; i++) { - failure("Body of Volume Descriptor Set Terminator " - "should be all nulls."); - assertEqualInt(buff[2048*18+i], 0); - } - - /* "file1" Contents is zisofs data. */ - failure("file1 image should be zisofs'ed."); - assertEqualMem(buff+2048*31, zisofs_magic, 8); - /* "file2" Contents is not zisofs data. */ - memset(data, 'a', sizeof(data)); - failure("file2 image should not be zisofs'ed."); - assertEqualMem(buff+2048*51, data, 1024); - memset(data, 'b', sizeof(data)); - failure("file2 image should not be zisofs'ed."); - assertEqualMem(buff+2048*51+1024, data, 1024); - /* "file3" Contents is zisofs data. */ - failure("file3 image should be zisofs'ed."); - assertEqualMem(buff+2048*52, zisofs_magic, 8); - /* "file4" Contents is zisofs data. */ - failure("file4 image should be zisofs'ed."); - assertEqualMem(buff+2048*53, zisofs_magic, 8); - - /* - * Read ISO image. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, 0, archive_read_support_format_all(a)); - assertEqualIntA(a, 0, archive_read_support_filter_all(a)); - assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used)); - - /* - * Read Root Directory - * Root Directory entry must be in ISO image. - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_atime(ae), archive_entry_ctime(ae)); - assertEqualInt(archive_entry_atime(ae), archive_entry_mtime(ae)); - assertEqualString(".", archive_entry_pathname(ae)); - assert((S_IFDIR | 0555) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "file1" which has 256K bytes random data. - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("file1", archive_entry_pathname(ae)); - assert((S_IFREG | 0555) == archive_entry_mode(ae)); - assertEqualInt(256*1024, archive_entry_size(ae)); - assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024)); - - /* - * Read "file2" which has 2048 bytes data. - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("file2", archive_entry_pathname(ae)); - assert((S_IFREG | 0555) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024)); - memset(data, 'a', sizeof(data)); - assertEqualMem(buff2, data, 1024); - - /* - * Read "file3" which has 2049 bytes data. - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("file3", archive_entry_pathname(ae)); - assert((S_IFREG | 0555) == archive_entry_mode(ae)); - assertEqualInt(2049, archive_entry_size(ae)); - assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024)); - memset(data, 'Z', sizeof(data)); - assertEqualMem(buff2, data, 1024); - - /* - * Read "file4" which has 32K bytes null data. - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("file4", archive_entry_pathname(ae)); - assert((S_IFREG | 0555) == archive_entry_mode(ae)); - assertEqualInt(32768, archive_entry_size(ae)); - assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024)); - memset(data, 0, sizeof(data)); - assertEqualMem(buff2, data, 1024); - - /* - * Verify the end of the archive. - */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); - - free(buff); -} - -/* - * Make a bootable ISO image with "zisofs" option. - */ -static void -test_write_format_iso9660_zisofs_3(void) -{ - unsigned char buff2[1024]; - unsigned char nullb[2048]; - struct archive *a; - struct archive_entry *ae; - unsigned char *buff; - size_t buffsize = 50 * 2048; - size_t used; - unsigned int i; - int r; - - memset(nullb, 0, sizeof(nullb)); - buff = malloc(buffsize); - assert(buff != NULL); - if (buff == NULL) - return; - - /* ISO9660 format: Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, 0, archive_write_set_format_iso9660(a)); - assertEqualIntA(a, 0, archive_write_add_filter_none(a)); - r = archive_write_set_option(a, NULL, "zisofs", "1"); - if (r == ARCHIVE_FATAL) { - skipping("zisofs option not supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - free(buff); - return; - } - assertEqualIntA(a, 0, archive_write_set_option(a, NULL, "boot", "boot.img")); - assertEqualIntA(a, 0, archive_write_set_option(a, NULL, "pad", NULL)); - assertEqualIntA(a, 0, archive_write_open_memory(a, buff, buffsize, &used)); - - /* - * "file1" has a bunch of attributes and 256K bytes of null data. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_birthtime(ae, 3, 30); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "boot.img"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 10*1024); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 1024, archive_write_data(a, nullb, 1024)); - - /* - * "file2" has a bunch of attributes and 2048 bytes of null data. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_birthtime(ae, 3, 30); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "file2"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 2048); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 1024, archive_write_data(a, nullb, 1024)); - - /* - * "file3" has a bunch of attributes and 2049 bytes of null data. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_birthtime(ae, 3, 30); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "file3"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 2049); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 1024, archive_write_data(a, nullb, 1024)); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); - - failure("The ISO image size should be 81920 bytes."); - assertEqualInt(used, 2048 * 40); - - /* Check System Area. */ - for (i = 0; i < 2048 * 16; i++) { - failure("System Area should be all nulls."); - assertEqualInt(buff[i], 0); - } - - /* Primary Volume. */ - failure("Primary Volume Descriptor should be in 16 Logical Sector."); - assertEqualMem(buff+2048*16, primary_id, 8); - assertEqualMem(buff+2048*16+0x28, - "CDROM ", 32); - assertEqualMem(buff+2048*16+0x50, volumesize3, 8); - - /* Boot Volume. */ - failure("Boot Volume Descriptor should be in 17 Logical Sector."); - assertEqualMem(buff+2048*17, boot_id, sizeof(boot_id)); - for (i = 0x27; i <= 0x46; i++) { - failure("Unused area must be all nulls."); - assert(buff[2048*17+i] == 0); - } - /* First sector of Boot Catalog. */ - assert(buff[2048*17+0x47] == 0x20); - assert(buff[2048*17+0x48] == 0x00); - assert(buff[2048*17+0x49] == 0x00); - assert(buff[2048*17+0x4a] == 0x00); - for (i = 0x4a; i <= 0x7ff; i++) { - failure("Unused area must be all nulls."); - assert(buff[2048*17+i] == 0); - } - - /* Supplementary Volume. */ - failure("Supplementary Volume(Joliet) Descriptor " - "should be in 18 Logical Sector."); - assertEqualMem(buff+2048*18, supplementary_id, 8); - assertEqualMem(buff+2048*18+0x28, volumeidu16, 32); - assertEqualMem(buff+2048*18+0x50, volumesize3, 8); - failure("Date and Time of Primary Volume and " - "Date and Time of Supplementary Volume " - "must be the same."); - assertEqualMem(buff+2048*16+0x32d, buff+2048*18+0x32d, 0x44); - - /* Terminator. */ - failure("Volume Descriptor Set Terminator " - "should be in 19 Logical Sector."); - assertEqualMem(buff+2048*19, terminator_id, 8); - for (i = 8; i < 2048; i++) { - failure("Body of Volume Descriptor Set Terminator " - "should be all nulls."); - assertEqualInt(buff[2048*19+i], 0); - } - - /* Check signature of El-Torito. */ - assertEqualMem(buff+2048*31, el_torito_signature, 237); - assertEqualMem(buff+2048*31+237, nullb, 2048-237); - - /* Check contents of "boot.catalog". */ - assertEqualMem(buff+2048*32, boot_catalog, 64); - assertEqualMem(buff+2048*32+64, nullb, 2048-64); - - /* Check contents of "boot.img". */ - failure("boot.img image should not be zisofs'ed."); - assertEqualMem(buff+2048*33, nullb, 2048); - for (i = 2048*34; i < 2048*38; i += 2048) { - assertEqualMem(buff+i, nullb, 2048); - } - - /* "file2" Contents is not zisofs data. */ - failure("file2 image should not be zisofs'ed."); - assertEqualMem(buff+2048*38, nullb, 8); - /* "file3" Contents is zisofs data. */ - failure("file3 image should be zisofs'ed."); - assertEqualMem(buff+2048*39, zisofs_magic, 8); - - /* - * Read ISO image. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, 0, archive_read_support_format_all(a)); - assertEqualIntA(a, 0, archive_read_support_filter_all(a)); - assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used)); - - /* - * Read Root Directory - * Root Directory entry must be in ISO image. - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(archive_entry_atime(ae), archive_entry_ctime(ae)); - assertEqualInt(archive_entry_atime(ae), archive_entry_mtime(ae)); - assertEqualString(".", archive_entry_pathname(ae)); - assert((S_IFDIR | 0555) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - - /* - * Read "boot.catalog". - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualString("boot.catalog", archive_entry_pathname(ae)); -#if !defined(_WIN32) && !defined(__CYGWIN__) - assert((S_IFREG | 0444) == archive_entry_mode(ae)); -#else - /* On Windows and CYGWIN, always set all exec bit ON by default. */ - assert((S_IFREG | 0555) == archive_entry_mode(ae)); -#endif - assertEqualInt(1, archive_entry_nlink(ae)); - assertEqualInt(2*1024, archive_entry_size(ae)); - assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024)); - assertEqualMem(buff2, boot_catalog, 64); - - /* - * Read "boot.img". - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(3, archive_entry_birthtime(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("boot.img", archive_entry_pathname(ae)); - assert((S_IFREG | 0555) == archive_entry_mode(ae)); - assertEqualInt(1, archive_entry_nlink(ae)); - assertEqualInt(10*1024, archive_entry_size(ae)); - assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024)); - assertEqualMem(buff2, nullb, 1024); - - /* - * Read "file2" which has 2048 bytes null data. - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("file2", archive_entry_pathname(ae)); - assert((S_IFREG | 0555) == archive_entry_mode(ae)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024)); - assertEqualMem(buff2, nullb, 1024); - - /* - * Read "file3" which has 2049 bytes null data. - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("file3", archive_entry_pathname(ae)); - assert((S_IFREG | 0555) == archive_entry_mode(ae)); - assertEqualInt(2049, archive_entry_size(ae)); - assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024)); - assertEqualMem(buff2, nullb, 1024); - - /* - * Verify the end of the archive. - */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); - - free(buff); -} - -DEFINE_TEST(test_write_format_iso9660_zisofs) -{ - test_write_format_iso9660_zisofs_1(); - test_write_format_iso9660_zisofs_2(); - test_write_format_iso9660_zisofs_3(); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_mtree.c b/thirdparty/libarchive/libarchive/test/test_write_format_mtree.c deleted file mode 100644 index 5109e0920..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_mtree.c +++ /dev/null @@ -1,272 +0,0 @@ -/*- - * Copyright (c) 2009 Michihiro NAKAJIMA - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_format_mtree.c 191183 2009-04-17 01:06:31Z kientzle $"); - -static char buff[4096]; -static struct { - const char *path; - mode_t mode; - time_t mtime; - uid_t uid; - gid_t gid; -} entries[] = { - { "./COPYING", S_IFREG | 0644, 1231975636, 1001, 1001 }, - { "./Makefile", S_IFREG | 0644, 1233041050, 1001, 1001 }, - { "./NEWS", S_IFREG | 0644, 1231975636, 1001, 1001 }, - { "./PROJECTS", S_IFREG | 0644, 1231975636, 1001, 1001 }, - { "./README", S_IFREG | 0644, 1231975636, 1001, 1001 }, - { "./subdir", S_IFDIR | 0755, 1233504586, 1001, 1001 }, - { "./subdir/README", S_IFREG | 0664, 1231975636, 1002, 1001 }, - { "./subdir/config", S_IFREG | 0664, 1232266273, 1003, 1003 }, - { "./subdir2", S_IFDIR | 0755, 1233504586, 1001, 1001 }, - { "./subdir3", S_IFDIR | 0755, 1233504586, 1001, 1001 }, - { "./subdir3/mtree", S_IFREG | 0664, 1232266273, 1003, 1003 }, - { NULL, 0, 0, 0, 0 } -}; -static struct { - const char *path; - mode_t mode; - time_t mtime; - uid_t uid; - gid_t gid; -} entries2[] = { - { "COPYING", S_IFREG | 0644, 1231975636, 1001, 1001 }, - { "Makefile", S_IFREG | 0644, 1233041050, 1001, 1001 }, - { "NEWS", S_IFREG | 0644, 1231975636, 1001, 1001 }, - { "PROJECTS", S_IFREG | 0644, 1231975636, 1001, 1001 }, - { "README", S_IFREG | 0644, 1231975636, 1001, 1001 }, - { "subdir", S_IFDIR | 0755, 1233504586, 1001, 1001 }, - { "subdir/README", S_IFREG | 0664, 1231975636, 1002, 1001 }, - { "subdir/config", S_IFREG | 0664, 1232266273, 1003, 1003 }, - { "subdir2", S_IFDIR | 0755, 1233504586, 1001, 1001 }, - { "subdir3", S_IFDIR | 0755, 1233504586, 1001, 1001 }, - { "subdir3/mtree", S_IFREG | 0664, 1232266273, 1003, 1003 }, - { NULL, 0, 0, 0, 0 } -}; - -static void -test_write_format_mtree_sub(int use_set, int dironly) -{ - struct archive_entry *ae; - struct archive* a; - size_t used; - int i; - - /* Create a mtree format archive. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a)); - if (use_set) - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_option(a, NULL, "use-set", "1")); - if (dironly) - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_option(a, NULL, "dironly", "1")); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff)-1, &used)); - - /* Write entries */ - for (i = 0; entries[i].path != NULL; i++) { - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, entries[i].mtime, 0); - assert(entries[i].mtime == archive_entry_mtime(ae)); - archive_entry_set_mode(ae, entries[i].mode); - assert(entries[i].mode == archive_entry_mode(ae)); - archive_entry_set_uid(ae, entries[i].uid); - assert(entries[i].uid == archive_entry_uid(ae)); - archive_entry_set_gid(ae, entries[i].gid); - assert(entries[i].gid == archive_entry_gid(ae)); - archive_entry_copy_pathname(ae, entries[i].path); - if ((entries[i].mode & AE_IFMT) != S_IFDIR) - archive_entry_set_size(ae, 8); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - if ((entries[i].mode & AE_IFMT) != S_IFDIR) - assertEqualIntA(a, 8, - archive_write_data(a, "Hello012", 15)); - archive_entry_free(ae); - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - if (use_set) { - const char *p; - - buff[used] = '\0'; - assert(NULL != (p = strstr(buff, "\n/set "))); - if (p != NULL) { - char *r; - const char *o; - p++; - r = strchr(p, '\n'); - if (r != NULL) - *r = '\0'; - if (dironly) - o = "/set type=dir uid=1001 gid=1001 mode=755"; - else - o = "/set type=file uid=1001 gid=1001 mode=644"; - assertEqualString(o, p); - if (r != NULL) - *r = '\n'; - } - } - - /* - * Read the data and check it. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); - - /* Read entries */ - for (i = 0; entries[i].path != NULL; i++) { - if (dironly && (entries[i].mode & AE_IFMT) != S_IFDIR) - continue; - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(entries[i].mtime, archive_entry_mtime(ae)); - assertEqualInt(entries[i].mode, archive_entry_mode(ae)); - assertEqualInt(entries[i].uid, archive_entry_uid(ae)); - assertEqualInt(entries[i].gid, archive_entry_gid(ae)); - assertEqualString(entries[i].path, archive_entry_pathname(ae)); - if ((entries[i].mode & AE_IFMT) != S_IFDIR) - assertEqualInt(8, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -static void -test_write_format_mtree_sub2(int use_set, int dironly) -{ - struct archive_entry *ae; - struct archive* a; - size_t used; - int i; - char str[32]; - - /* Create a mtree format archive. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a)); - if (use_set) - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_option(a, NULL, "use-set", "1")); - if (dironly) - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_option(a, NULL, "dironly", "1")); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff)-1, &used)); - - /* Write entries2 */ - for (i = 0; entries2[i].path != NULL; i++) { - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, entries2[i].mtime, 0); - assert(entries2[i].mtime == archive_entry_mtime(ae)); - archive_entry_set_mode(ae, entries2[i].mode); - assert(entries2[i].mode == archive_entry_mode(ae)); - archive_entry_set_uid(ae, entries2[i].uid); - assert(entries2[i].uid == archive_entry_uid(ae)); - archive_entry_set_gid(ae, entries2[i].gid); - assert(entries2[i].gid == archive_entry_gid(ae)); - archive_entry_copy_pathname(ae, entries2[i].path); - if ((entries2[i].mode & AE_IFMT) != S_IFDIR) - archive_entry_set_size(ae, 8); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - if ((entries2[i].mode & AE_IFMT) != S_IFDIR) - assertEqualIntA(a, 8, - archive_write_data(a, "Hello012", 15)); - archive_entry_free(ae); - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - if (use_set) { - const char *p; - - buff[used] = '\0'; - assert(NULL != (p = strstr(buff, "\n/set "))); - if (p != NULL) { - char *r; - const char *o; - p++; - r = strchr(p, '\n'); - if (r != NULL) - *r = '\0'; - if (dironly) - o = "/set type=dir uid=1001 gid=1001 mode=755"; - else - o = "/set type=file uid=1001 gid=1001 mode=644"; - assertEqualString(o, p); - if (r != NULL) - *r = '\n'; - } - } - - /* - * Read the data and check it. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); - - /* Read entries2 */ - memset(str, 0, sizeof(str)); - strcpy(str, "./"); - for (i = 0; entries2[i].path != NULL; i++) { - if (dironly && (entries2[i].mode & AE_IFMT) != S_IFDIR) - continue; - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(entries2[i].mtime, archive_entry_mtime(ae)); - assertEqualInt(entries2[i].mode, archive_entry_mode(ae)); - assertEqualInt(entries2[i].uid, archive_entry_uid(ae)); - assertEqualInt(entries2[i].gid, archive_entry_gid(ae)); - strcpy(str + 2, entries2[i].path); - assertEqualString(str, archive_entry_pathname(ae)); - if ((entries2[i].mode & AE_IFMT) != S_IFDIR) - assertEqualInt(8, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_write_format_mtree) -{ - /* Default setting */ - test_write_format_mtree_sub(0, 0); - /* Directory only */ - test_write_format_mtree_sub(0, 1); - /* Use /set keyword */ - test_write_format_mtree_sub(1, 0); - /* Use /set keyword with directory only */ - test_write_format_mtree_sub(1, 1); -} - -DEFINE_TEST(test_write_format_mtree_no_leading_dotslash) -{ - /* Default setting */ - test_write_format_mtree_sub2(0, 0); - /* Directory only */ - test_write_format_mtree_sub2(0, 1); - /* Use /set keyword */ - test_write_format_mtree_sub2(1, 0); - /* Use /set keyword with directory only */ - test_write_format_mtree_sub2(1, 1); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_mtree_absolute_path.c b/thirdparty/libarchive/libarchive/test/test_write_format_mtree_absolute_path.c deleted file mode 100644 index e3972f1f1..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_mtree_absolute_path.c +++ /dev/null @@ -1,99 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -static char buff[4096]; - -DEFINE_TEST(test_write_format_mtree_absolute_path) -{ - struct archive_entry *ae; - struct archive* a; - size_t used; - - /* Create a mtree format archive. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff)-1, &used)); - - /* Write "." file. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "."); - archive_entry_set_mode(ae, AE_IFDIR | 0755); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Write "/file" file. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "/file"); - archive_entry_set_size(ae, 0); - archive_entry_set_mode(ae, AE_IFREG | 0644); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Write "/dir" directory. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "/dir"); - archive_entry_set_mode(ae, AE_IFDIR | 0755); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Read the data and check it. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); - - /* Read "." file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - failure("The path should be just \".\""); - assertEqualString(archive_entry_pathname(ae), "."); - assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755); - - /* Read "/file" file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - failure("The path should have \"./\" prefix"); - assertEqualString(archive_entry_pathname(ae), "./file"); - assertEqualInt(archive_entry_size(ae), 0); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); - - /* Read "/dir" file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - failure("The path should have \"./\" prefix"); - assertEqualString(archive_entry_pathname(ae), "./dir"); - assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_mtree_classic.c b/thirdparty/libarchive/libarchive/test/test_write_format_mtree_classic.c deleted file mode 100644 index 9a75fdd71..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_mtree_classic.c +++ /dev/null @@ -1,194 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -static char buff[4096]; -static struct { - const char *path; - mode_t mode; - int nlink; - time_t mtime; - uid_t uid; - gid_t gid; -} entries[] = { - { ".", S_IFDIR | 0755, 3, 1231975636, 1001, 1001 }, - { "./COPYING", S_IFREG | 0644, 1, 1231975636, 1001, 1001 }, - { "./Makefile", S_IFREG | 0644, 1, 1233041050, 1001, 1001 }, - { "./NEWS", S_IFREG | 0644, 1, 1231975636, 1001, 1001 }, - { "./PROJECTS", S_IFREG | 0644, 1, 1231975636, 1001, 1001 }, - { "./README", S_IFREG | 0644, 1, 1231975636, 1001, 1001 }, - { "./subdir", S_IFDIR | 0755, 3, 1233504586, 1001, 1001 }, - { "./subdir/README", S_IFREG | 0664, 1, 1231975636, 1002, 1001 }, - { "./subdir/config", S_IFREG | 0664, 1, 1232266273, 1003, 1003 }, - { "./subdir2", S_IFDIR | 0755, 3, 1233504586, 1001, 1001 }, - { "./subdir3", S_IFDIR | 0755, 3, 1233504586, 1001, 1001 }, - { "./subdir3/mtree", S_IFREG | 0664, 2, 1232266273, 1003, 1003 }, - { NULL, 0, 0, 0, 0, 0 } -}; - -static const char image [] = { -"#mtree\n" -"\n" -"# .\n" -"/set type=file uid=1001 gid=1001 mode=644\n" -". time=1231975636.0 mode=755 type=dir\n" -" COPYING time=1231975636.0 size=8\n" -" Makefile time=1233041050.0 size=8\n" -" NEWS time=1231975636.0 size=8\n" -" PROJECTS time=1231975636.0 size=8\n" -" README time=1231975636.0 size=8\n" -"\n" -"# ./subdir\n" -"/set mode=664\n" -"subdir time=1233504586.0 mode=755 type=dir\n" -" README time=1231975636.0 uid=1002 size=8\n" -" config time=1232266273.0 gid=1003 uid=1003 size=8\n" -"# ./subdir\n" -"..\n" -"\n" -"\n" -"# ./subdir2\n" -"subdir2 time=1233504586.0 mode=755 type=dir\n" -"# ./subdir2\n" -"..\n" -"\n" -"\n" -"# ./subdir3\n" -"subdir3 time=1233504586.0 mode=755 type=dir\n" -" mtree nlink=2 time=1232266273.0 gid=1003 uid=1003 size=8\n" -"# ./subdir3\n" -"..\n" -"\n" -"..\n\n" -}; - -static const char image_dironly [] = { -"#mtree\n" -"# .\n" -"/set type=dir uid=1001 gid=1001 mode=755\n" -". time=1231975636.0\n" -"# ./subdir\n" -"subdir time=1233504586.0\n" -"# ./subdir\n" -"..\n" -"# ./subdir2\n" -"subdir2 time=1233504586.0\n" -"# ./subdir2\n" -"..\n" -"# ./subdir3\n" -"subdir3 time=1233504586.0\n" -"# ./subdir3\n" -"..\n" -"..\n" -}; - -static void -test_write_format_mtree_sub(int dironly) -{ - struct archive_entry *ae; - struct archive* a; - size_t used; - int i; - - /* Create a mtree format archive. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree_classic(a)); - if (dironly) - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_format_option(a, NULL, "dironly", "1")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff)-1, &used)); - - /* Write entries */ - for (i = 0; entries[i].path != NULL; i++) { - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_nlink(ae, entries[i].nlink); - assertEqualInt(entries[i].nlink, archive_entry_nlink(ae)); - archive_entry_set_mtime(ae, entries[i].mtime, 0); - assertEqualInt(entries[i].mtime, archive_entry_mtime(ae)); - archive_entry_set_mode(ae, entries[i].mode); - assertEqualInt(entries[i].mode, archive_entry_mode(ae)); - archive_entry_set_uid(ae, entries[i].uid); - assertEqualInt(entries[i].uid, archive_entry_uid(ae)); - archive_entry_set_gid(ae, entries[i].gid); - assertEqualInt(entries[i].gid, archive_entry_gid(ae)); - archive_entry_copy_pathname(ae, entries[i].path); - if ((entries[i].mode & AE_IFMT) != S_IFDIR) - archive_entry_set_size(ae, 8); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - if ((entries[i].mode & AE_IFMT) != S_IFDIR) - assertEqualIntA(a, 8, - archive_write_data(a, "Hello012", 15)); - archive_entry_free(ae); - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - buff[used] = '\0'; - if (dironly) - assertEqualString(buff, image_dironly); - else - assertEqualString(buff, image); - - /* - * Read the data and check it. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); - - /* Read entries */ - for (i = 0; entries[i].path != NULL; i++) { - if (dironly && (entries[i].mode & AE_IFMT) != S_IFDIR) - continue; - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(entries[i].mtime, archive_entry_mtime(ae)); - assertEqualInt(entries[i].mode, archive_entry_mode(ae)); - assertEqualInt(entries[i].uid, archive_entry_uid(ae)); - assertEqualInt(entries[i].gid, archive_entry_gid(ae)); - if (i > 0) - assertEqualString(entries[i].path + 2, - archive_entry_pathname(ae)); - else - assertEqualString(entries[i].path, - archive_entry_pathname(ae)); - if ((entries[i].mode & AE_IFMT) != S_IFDIR) - assertEqualInt(8, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_write_format_mtree_classic) -{ - /* Generate classic format. */ - test_write_format_mtree_sub(0); - /* Generate classic format and Write directory only. */ - test_write_format_mtree_sub(1); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_mtree_classic_indent.c b/thirdparty/libarchive/libarchive/test/test_write_format_mtree_classic_indent.c deleted file mode 100644 index 6d1c54911..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_mtree_classic_indent.c +++ /dev/null @@ -1,196 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -static char buff[4096]; -static struct { - const char *path; - mode_t mode; - int nlink; - time_t mtime; - uid_t uid; - gid_t gid; -} entries[] = { - { ".", S_IFDIR | 0755, 3, 1231975636, 1001, 1001 }, - { "./COPYING", S_IFREG | 0644, 1, 1231975636, 1001, 1001 }, - { "./Makefile", S_IFREG | 0644, 1, 1233041050, 1001, 1001 }, - { "./NEWS", S_IFREG | 0644, 1, 1231975636, 1001, 1001 }, - { "./PROJECTS", S_IFREG | 0644, 1, 1231975636, 1001, 1001 }, - { "./README", S_IFREG | 0644, 1, 1231975636, 1001, 1001 }, - { "./subdir", S_IFDIR | 0755, 3, 1233504586, 1001, 1001 }, - { "./subdir/README", S_IFREG | 0664, 1, 1231975636, 1002, 1001 }, - { "./subdir/config", S_IFREG | 0664, 1, 1232266273, 1003, 1003 }, - { "./subdir2", S_IFDIR | 0755, 3, 1233504586, 1001, 1001 }, - { "./subdir3", S_IFDIR | 0755, 3, 1233504586, 1001, 1001 }, - { "./subdir3/mtree", S_IFREG | 0664, 2, 1232266273, 1003, 1003 }, - { NULL, 0, 0, 0, 0, 0 } -}; - -static const char image [] = { -"#mtree\n" -"\n" -"# .\n" -"/set type=file uid=1001 gid=1001 mode=644\n" -". time=1231975636.0 mode=755 type=dir\n" -" COPYING time=1231975636.0 size=8\n" -" Makefile time=1233041050.0 size=8\n" -" NEWS time=1231975636.0 size=8\n" -" PROJECTS time=1231975636.0 size=8\n" -" README time=1231975636.0 size=8\n" -"\n" -"# ./subdir\n" -"/set mode=664\n" -" subdir time=1233504586.0 mode=755 type=dir\n" -" README time=1231975636.0 uid=1002 size=8\n" -" config time=1232266273.0 gid=1003 uid=1003 size=8\n" -" # ./subdir\n" -" ..\n" -"\n" -"\n" -"# ./subdir2\n" -" subdir2 time=1233504586.0 mode=755 type=dir\n" -" # ./subdir2\n" -" ..\n" -"\n" -"\n" -"# ./subdir3\n" -" subdir3 time=1233504586.0 mode=755 type=dir\n" -" mtree nlink=2 time=1232266273.0 gid=1003 uid=1003 size=8\n" -" # ./subdir3\n" -" ..\n" -"\n" -"..\n\n" -}; - -static const char image_dironly [] = { -"#mtree\n" -"# .\n" -"/set type=dir uid=1001 gid=1001 mode=755\n" -". time=1231975636.0\n" -"# ./subdir\n" -" subdir time=1233504586.0\n" -" # ./subdir\n" -" ..\n" -"# ./subdir2\n" -" subdir2 time=1233504586.0\n" -" # ./subdir2\n" -" ..\n" -"# ./subdir3\n" -" subdir3 time=1233504586.0\n" -" # ./subdir3\n" -" ..\n" -"..\n" -}; - -static void -test_write_format_mtree_sub(int dironly) -{ - struct archive_entry *ae; - struct archive* a; - size_t used; - int i; - - /* Create a mtree format archive. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree_classic(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_format_option(a, NULL, "indent", "1")); - if (dironly) - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_format_option(a, NULL, "dironly", "1")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff)-1, &used)); - - /* Write entries */ - for (i = 0; entries[i].path != NULL; i++) { - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_nlink(ae, entries[i].nlink); - assertEqualInt(entries[i].nlink, archive_entry_nlink(ae)); - archive_entry_set_mtime(ae, entries[i].mtime, 0); - assertEqualInt(entries[i].mtime, archive_entry_mtime(ae)); - archive_entry_set_mode(ae, entries[i].mode); - assertEqualInt(entries[i].mode, archive_entry_mode(ae)); - archive_entry_set_uid(ae, entries[i].uid); - assertEqualInt(entries[i].uid, archive_entry_uid(ae)); - archive_entry_set_gid(ae, entries[i].gid); - assertEqualInt(entries[i].gid, archive_entry_gid(ae)); - archive_entry_copy_pathname(ae, entries[i].path); - if ((entries[i].mode & AE_IFMT) != S_IFDIR) - archive_entry_set_size(ae, 8); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - if ((entries[i].mode & AE_IFMT) != S_IFDIR) - assertEqualIntA(a, 8, - archive_write_data(a, "Hello012", 15)); - archive_entry_free(ae); - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - buff[used] = '\0'; - if (dironly) - assertEqualString(buff, image_dironly); - else - assertEqualString(buff, image); - - /* - * Read the data and check it. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); - - /* Read entries */ - for (i = 0; entries[i].path != NULL; i++) { - if (dironly && (entries[i].mode & AE_IFMT) != S_IFDIR) - continue; - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(entries[i].mtime, archive_entry_mtime(ae)); - assertEqualInt(entries[i].mode, archive_entry_mode(ae)); - assertEqualInt(entries[i].uid, archive_entry_uid(ae)); - assertEqualInt(entries[i].gid, archive_entry_gid(ae)); - if (i > 0) - assertEqualString(entries[i].path + 2, - archive_entry_pathname(ae)); - else - assertEqualString(entries[i].path, - archive_entry_pathname(ae)); - if ((entries[i].mode & AE_IFMT) != S_IFDIR) - assertEqualInt(8, archive_entry_size(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_write_format_mtree_classic_indent) -{ - /* Generate classic format. */ - test_write_format_mtree_sub(0); - /* Generate classic format and Write directory only. */ - test_write_format_mtree_sub(1); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_mtree_fflags.c b/thirdparty/libarchive/libarchive/test/test_write_format_mtree_fflags.c deleted file mode 100644 index 820d86f70..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_mtree_fflags.c +++ /dev/null @@ -1,135 +0,0 @@ -/*- - * Copyright (c) 2011 Michihiro NAKAJIMA - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); -#ifdef HAVE_SYS_STAT_H -#include -#endif - -/* - * Test UFS file flags with/without use-set option. - */ -#if defined(UF_IMMUTABLE) && defined(UF_NODUMP) - -static char buff[4096]; -static struct { - const char *path; - unsigned long fflags; -} entries[] = { - { "./f1", UF_IMMUTABLE | UF_NODUMP }, - { "./f11", UF_IMMUTABLE | UF_NODUMP }, - { "./f2", 0 }, - { "./f3", UF_NODUMP }, - { NULL, 0 } -}; - -static void -test_write_format_mtree_sub(int use_set) -{ - struct archive_entry *ae; - struct archive* a; - size_t used; - int i; - - /* Create a mtree format archive. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a)); - if (use_set) - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "use-set,!all,flags,type")); - else - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "!all,flags,type")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff)-1, &used)); - - /* Write entries */ - for (i = 0; entries[i].path != NULL; i++) { - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_fflags(ae, entries[i].fflags, 0); - archive_entry_copy_pathname(ae, entries[i].path); - archive_entry_set_size(ae, 0); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - if (use_set) { - const char *p; - - buff[used] = '\0'; - assert(NULL != (p = strstr(buff, "\n/set "))); - if (p != NULL) { - char *r; - const char *o; - p++; - r = strchr(p, '\n'); - if (r != NULL) - *r = '\0'; - o = "/set type=file flags=uchg,nodump"; - assertEqualString(o, p); - if (r != NULL) - *r = '\n'; - } - } - - /* - * Read the data and check it. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); - - /* Read entries */ - for (i = 0; entries[i].path != NULL; i++) { - unsigned long fset, fclr; - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - archive_entry_fflags(ae, &fset, &fclr); - assertEqualInt((int)entries[i].fflags, (int)fset); - assertEqualInt(0, (int)fclr); - assertEqualString(entries[i].path, archive_entry_pathname(ae)); - } - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -#endif - -DEFINE_TEST(test_write_format_mtree_fflags) -{ -#if defined(UF_IMMUTABLE) && defined(UF_NODUMP) - /* Default setting */ - test_write_format_mtree_sub(0); - /* Use /set keyword */ - test_write_format_mtree_sub(1); -#else - skipping("This platform does not support UFS file flags"); -#endif -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_mtree_no_separator.c b/thirdparty/libarchive/libarchive/test/test_write_format_mtree_no_separator.c deleted file mode 100644 index faf42dd52..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_mtree_no_separator.c +++ /dev/null @@ -1,103 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); -#ifdef HAVE_SYS_STAT_H -#include -#endif - -static char buff[4096]; - -DEFINE_TEST(test_write_format_mtree_no_separator) -{ - struct archive_entry *ae; - struct archive* a; - size_t used; - - /* Create a mtree format archive. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff)-1, &used)); - - /* Write "." file. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "."); - archive_entry_set_mode(ae, AE_IFDIR | 0755); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Write "noseparator" file. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "noseparator"); - archive_entry_set_size(ae, 0); - archive_entry_set_mode(ae, AE_IFREG | 0644); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Write "./withseparator" file. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "./withseparator"); - archive_entry_set_size(ae, 0); - archive_entry_set_mode(ae, AE_IFREG | 0644); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Read the data and check it. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); - - /* Read "." file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - failure("The path should be just \".\""); - assertEqualString(archive_entry_pathname(ae), "."); - assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755); - - /* Read "./noseparator" file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - failure("The path should have \"./\" prefix"); - assertEqualString(archive_entry_pathname(ae), "./noseparator"); - assertEqualInt(archive_entry_size(ae), 0); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); - - /* Read "./withseparator" file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "./withseparator"); - assertEqualInt(archive_entry_size(ae), 0); - assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_mtree_quoted_filename.c b/thirdparty/libarchive/libarchive/test/test_write_format_mtree_quoted_filename.c deleted file mode 100644 index 63e927a81..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_mtree_quoted_filename.c +++ /dev/null @@ -1,86 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -static char buff[4096]; - -static const char image [] = { -"#mtree\n" -"./a\\040!$\\043&\\075_^z\\177~ mode=644 type=file\n" -}; - - -DEFINE_TEST(test_write_format_mtree_quoted_filename) -{ - struct archive_entry *ae; - struct archive* a; - size_t used; - - /* Create a mtree format archive. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_format_option(a, NULL, "all", NULL)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_format_option(a, NULL, "type", "1")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_format_option(a, NULL, "mode", "1")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff)-1, &used)); - - /* Write entry which has #, = , \ and DEL(0177) in the filename. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mode(ae, AE_IFREG | 0644); - assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae)); - archive_entry_copy_pathname(ae, "./a !$#&=_^z\177~"); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - buff[used] = '\0'; - failure("#, = and \\ in the filename should be quoted"); - assertEqualString(buff, image); - - /* - * Read the data and check it. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); - - /* Read entry */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae)); - assertEqualString("./a !$#&=_^z\177~", archive_entry_pathname(ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_pax.c b/thirdparty/libarchive/libarchive/test/test_write_format_pax.c deleted file mode 100644 index 4538aac82..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_pax.c +++ /dev/null @@ -1,255 +0,0 @@ -/*- - * Copyright (c) 2003-2008 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -static char buff2[64]; - -DEFINE_TEST(test_write_format_pax) -{ - size_t buffsize = 1000000; - char *buff; - struct archive_entry *ae; - struct archive *a; - size_t used; - int i; - char nulls[1024]; - int64_t offset, length; - - buff = malloc(buffsize); /* million bytes of work area */ - assert(buff != NULL); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertA(0 == archive_write_set_format_pax(a)); - assertA(0 == archive_write_add_filter_none(a)); - assertA(0 == archive_write_open_memory(a, buff, buffsize, &used)); - - /* - * "file" has a bunch of attributes and 8 bytes of data. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_birthtime(ae, 3, 30); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "file"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 8); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9)); - - /* - * "file2" is similar but has birthtime later than mtime. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_birthtime(ae, 8, 80); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "file2"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 8); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9)); - - /* - * "file3" is sparse file and has hole size of which is - * 1024000 bytes, and has 8 bytes data after the hole. - * - * Pad the filename to make it larger than the ustar limit. - * It should still read back correctly. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_birthtime(ae, 3, 30); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "file3" - "_123456789_123456789_123456789_123456789_123456789" - "_123456789_123456789_123456789_123456789_123456789" - "_123456789_123456789_123456789_123456789_123456789"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 1024008); - archive_entry_sparse_add_entry(ae, 1024000, 8); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - memset(nulls, 0, sizeof(nulls)); - for (i = 0; i < 1024000; i += 1024) - /* write hole data, which won't be stored into an archive file. */ - assertEqualIntA(a, 1024, archive_write_data(a, nulls, 1024)); - assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9)); - - /* - * "file4" is similar to "file1" but has a large uid, large gid, - * uname and gname are longer than 32 characters - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_birthtime(ae, 3, 30); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "file4"); - archive_entry_set_mode(ae, S_IFREG | 0755); - archive_entry_set_size(ae, 8); - archive_entry_copy_uname(ae, - "long-uname123456789012345678901234567890"); - archive_entry_copy_gname(ae, - "long-gname123456789012345678901234567890"); - archive_entry_set_uid(ae, 536870912); - archive_entry_set_gid(ae, 536870913); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9)); - - /* - * XXX TODO XXX Archive directory, other file types. - * Archive extended attributes, ACLs, other metadata. - * Verify they get read back correctly. - */ - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); - - /* - * - * Now, read the data back. - * - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, 0, archive_read_support_format_all(a)); - assertEqualIntA(a, 0, archive_read_support_filter_all(a)); - assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used)); - - /* - * Read "file" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(20, archive_entry_atime_nsec(ae)); - assertEqualInt(3, archive_entry_birthtime(ae)); - assertEqualInt(30, archive_entry_birthtime_nsec(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(40, archive_entry_ctime_nsec(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualInt(50, archive_entry_mtime_nsec(ae)); - assertEqualString("file", archive_entry_pathname(ae)); - assert((S_IFREG | 0755) == archive_entry_mode(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "12345678", 8); - - /* - * Read "file2" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assert(archive_entry_atime_is_set(ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(20, archive_entry_atime_nsec(ae)); - /* Birthtime > mtime above, so it doesn't get stored at all. */ - assert(!archive_entry_birthtime_is_set(ae)); - assertEqualInt(0, archive_entry_birthtime(ae)); - assertEqualInt(0, archive_entry_birthtime_nsec(ae)); - assert(archive_entry_ctime_is_set(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(40, archive_entry_ctime_nsec(ae)); - assert(archive_entry_mtime_is_set(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualInt(50, archive_entry_mtime_nsec(ae)); - assertEqualString("file2", archive_entry_pathname(ae)); - assert((S_IFREG | 0755) == archive_entry_mode(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "12345678", 8); - - /* - * Read "file3" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(20, archive_entry_atime_nsec(ae)); - assertEqualInt(3, archive_entry_birthtime(ae)); - assertEqualInt(30, archive_entry_birthtime_nsec(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(40, archive_entry_ctime_nsec(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualInt(50, archive_entry_mtime_nsec(ae)); - assertEqualString("file3" - "_123456789_123456789_123456789_123456789_123456789" - "_123456789_123456789_123456789_123456789_123456789" - "_123456789_123456789_123456789_123456789_123456789", - archive_entry_pathname(ae)); - assert((S_IFREG | 0755) == archive_entry_mode(ae)); - assertEqualInt(1024008, archive_entry_size(ae)); - assertEqualInt(1, archive_entry_sparse_reset(ae)); - assertEqualInt(ARCHIVE_OK, - archive_entry_sparse_next(ae, &offset, &length)); - assertEqualInt(1024000, offset); - assertEqualInt(8, length); - for (i = 0; i < 1024000; i += 1024) { - int j; - assertEqualIntA(a, 1024, archive_read_data(a, nulls, 1024)); - for (j = 0; j < 1024; j++) - assertEqualInt(0, nulls[j]); - } - assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "12345678", 8); - - /* - * Read "file4 - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(20, archive_entry_atime_nsec(ae)); - assertEqualInt(3, archive_entry_birthtime(ae)); - assertEqualInt(30, archive_entry_birthtime_nsec(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(40, archive_entry_ctime_nsec(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualInt(50, archive_entry_mtime_nsec(ae)); - assertEqualString("file4", archive_entry_pathname(ae)); - assertEqualString("long-uname123456789012345678901234567890", - archive_entry_uname(ae)); - assertEqualString("long-gname123456789012345678901234567890", - archive_entry_gname(ae)); - assertEqualInt(536870912, archive_entry_uid(ae)); - assertEqualInt(536870913, archive_entry_gid(ae)); - assert((S_IFREG | 0755) == archive_entry_mode(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "12345678", 8); - - /* - * Verify the end of the archive. - */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); - - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_raw.c b/thirdparty/libarchive/libarchive/test/test_write_format_raw.c deleted file mode 100644 index bd887ff86..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_raw.c +++ /dev/null @@ -1,123 +0,0 @@ -/*- - * Copyright (c) 2013 Marek Kubica - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -static void -test_format(int (*set_format)(struct archive *)) -{ - char filedata[64]; - struct archive_entry *ae; - struct archive *a; - size_t used; - size_t buffsize = 1000000; - char *buff; - const char *err; - - buff = malloc(buffsize); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, (*set_format)(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used)); - - /* - * Write a file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_pathname(ae, "test"); - archive_entry_set_filetype(ae, AE_IFREG); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 9, archive_write_data(a, "12345678", 9)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Read from it. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_raw(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualIntA(a, 9, archive_read_data(a, filedata, 10)); - assertEqualMem(filedata, "12345678", 9); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* Create a new archive */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, (*set_format)(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used)); - - /* write first file: that should succeed */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_pathname(ae, "test"); - archive_entry_set_filetype(ae, AE_IFREG); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 9, archive_write_data(a, "12345678", 9)); - - /* write second file: this should fail */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_pathname(ae, "test2"); - archive_entry_set_filetype(ae, AE_IFREG); - assertEqualIntA(a, ARCHIVE_FATAL, archive_write_header(a, ae)); - err = archive_error_string(a); - assertEqualMem(err, "Raw format only supports one entry per archive", 47); - archive_entry_free(ae); - - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Create a new archive */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, (*set_format)(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used)); - - /* write a directory: this should fail */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "dir"); - archive_entry_set_filetype(ae, AE_IFDIR); - archive_entry_set_size(ae, 512); - assertEqualIntA(a, ARCHIVE_FATAL, archive_write_header(a, ae)); - err = archive_error_string(a); - assertEqualMem(err, "Raw format only supports filetype AE_IFREG", 43); - archive_entry_free(ae); - - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - free(buff); -} - -DEFINE_TEST(test_write_format_raw) -{ - test_format(archive_write_set_format_raw); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_raw_b64.c b/thirdparty/libarchive/libarchive/test/test_write_format_raw_b64.c deleted file mode 100644 index f8f67287e..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_raw_b64.c +++ /dev/null @@ -1,77 +0,0 @@ -/*- - * Copyright (c) 2013 Marek Kubica - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -static void -test_format(int (*set_format)(struct archive *)) -{ - char filedata[64]; - struct archive_entry *ae; - struct archive *a; - size_t used; - size_t buffsize = 1000000; - char *buff; - - buff = malloc(buffsize); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, (*set_format)(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_b64encode(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used)); - - /* - * Write a file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_pathname(ae, "test"); - archive_entry_set_filetype(ae, AE_IFREG); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 9, archive_write_data(a, "12345678", 9)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Read from it. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_raw(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualIntA(a, 37, archive_read_data(a, filedata, 64)); - assertEqualMem(filedata, "begin-base64 644 -\nMTIzNDU2NzgA\n====\n", 37); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - free(buff); -} - -DEFINE_TEST(test_write_format_raw_b64) -{ - test_format(archive_write_set_format_raw); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_shar_empty.c b/thirdparty/libarchive/libarchive/test/test_write_format_shar_empty.c deleted file mode 100644 index 13794b02b..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_shar_empty.c +++ /dev/null @@ -1,54 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/lib/libarchive/test/test_write_format_shar_empty.c,v 1.3 2008/09/01 05:38:33 kientzle Exp $"); - -/* - * Check that an "empty" shar archive is correctly created as an empty file. - */ - -DEFINE_TEST(test_write_format_shar_empty) -{ - struct archive *a; - char buff[2048]; - size_t used; - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertA(0 == archive_write_set_format_shar(a)); - assertA(0 == archive_write_add_filter_none(a)); - /* 1-byte block size ensures we see only the required bytes. */ - /* We're not testing the padding here. */ - assertA(0 == archive_write_set_bytes_per_block(a, 1)); - assertA(0 == archive_write_set_bytes_in_last_block(a, 1)); - assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used)); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - failure("Empty shar archive should be exactly 0 bytes, was %zu.", used); - assert(used == 0); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_tar.c b/thirdparty/libarchive/libarchive/test/test_write_format_tar.c deleted file mode 100644 index a5ccdc011..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_tar.c +++ /dev/null @@ -1,119 +0,0 @@ -/*- - * Copyright (c) 2003-2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_format_tar.c 189308 2009-03-03 17:02:51Z kientzle $"); - -static char buff[1000000]; -static char buff2[64]; - -DEFINE_TEST(test_write_format_tar) -{ - struct archive_entry *ae; - struct archive *a; - char *p; - size_t used; - size_t blocksize; - - /* Repeat the following for a variety of odd blocksizes. */ - for (blocksize = 1; blocksize < 100000; blocksize += blocksize + 3) { - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, (int)blocksize)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_in_last_block(a, (int)blocksize)); - assertEqualInt(blocksize, - archive_write_get_bytes_in_last_block(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - assertEqualInt(blocksize, - archive_write_get_bytes_in_last_block(a)); - - /* - * Write a file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(10, archive_entry_mtime_nsec(ae)); - p = strdup("file"); - archive_entry_copy_pathname(ae, p); - strcpy(p, "XXXX"); - free(p); - assertEqualString("file", archive_entry_pathname(ae)); - archive_entry_set_mode(ae, S_IFREG | 0755); - assertEqualInt(S_IFREG | 0755, archive_entry_mode(ae)); - archive_entry_set_size(ae, 8); - - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualInt(8, archive_write_data(a, "12345678", 9)); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* This calculation gives "the smallest multiple of - * the block size that is at least 2048 bytes". */ - failure("blocksize=%zu", blocksize); - assertEqualInt(((2048 - 1)/blocksize+1)*blocksize, used); - - /* - * Now, read the data back. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used)); - - assertEqualIntA(a, ARCHIVE_OK, - archive_read_next_header(a, &ae)); - - assertEqualInt(1, archive_entry_mtime(ae)); - /* Not the same as above: ustar doesn't store hi-res times. */ - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualInt(8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "12345678", 8); - - /* Verify the end of the archive. */ - assertEqualIntA(a, ARCHIVE_EOF, - archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - } -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_tar_empty.c b/thirdparty/libarchive/libarchive/test/test_write_format_tar_empty.c deleted file mode 100644 index 7ccd435f1..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_tar_empty.c +++ /dev/null @@ -1,74 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_format_tar_empty.c 189308 2009-03-03 17:02:51Z kientzle $"); - -/* - * Check that an "empty" tar archive is correctly created. - */ - -DEFINE_TEST(test_write_format_tar_empty) -{ - struct archive *a; - char buff[2048]; - size_t used; - unsigned int i; - - /* USTAR format: Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertA(0 == archive_write_set_format_ustar(a)); - assertA(0 == archive_write_add_filter_none(a)); - assertA(0 == archive_write_set_bytes_per_block(a, 512)); - assertA(0 == archive_write_set_bytes_in_last_block(a, 512)); - assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used)); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert(used == 1024); - for (i = 0; i < used; i++) { - failure("Empty tar archive should be all nulls."); - assert(buff[i] == 0); - } - - /* PAX format: Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertA(0 == archive_write_set_format_pax(a)); - assertA(0 == archive_write_add_filter_none(a)); - assertA(0 == archive_write_set_bytes_per_block(a, 512)); - assertA(0 == archive_write_set_bytes_in_last_block(a, 512)); - assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used)); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assertEqualInt((int)used, 1024); - for (i = 0; i < used; i++) { - failure("Empty tar archive should be all nulls."); - assert(buff[i] == 0); - } -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_tar_sparse.c b/thirdparty/libarchive/libarchive/test/test_write_format_tar_sparse.c deleted file mode 100644 index 54ac00988..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_tar_sparse.c +++ /dev/null @@ -1,305 +0,0 @@ -/*- - * Copyright (c) 2003-2010 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -static char buff[1000000]; - -static void -test_1(void) -{ - struct archive_entry *ae; - struct archive *a; - size_t used; - size_t blocksize; - int64_t offset, length; - char *buff2; - size_t buff2_size = 0x13000; - char buff3[1024]; - long i; - - assert((buff2 = malloc(buff2_size)) != NULL); - /* Repeat the following for a variety of odd blocksizes. */ - for (blocksize = 1; blocksize < 100000; blocksize += blocksize + 3) { - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_format_pax(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, (int)blocksize)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_in_last_block(a, (int)blocksize)); - assertEqualInt(blocksize, - archive_write_get_bytes_in_last_block(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - assertEqualInt(blocksize, - archive_write_get_bytes_in_last_block(a)); - - /* - * Write a file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(10, archive_entry_mtime_nsec(ae)); - archive_entry_copy_pathname(ae, "file"); - assertEqualString("file", archive_entry_pathname(ae)); - archive_entry_set_mode(ae, S_IFREG | 0755); - assertEqualInt(S_IFREG | 0755, archive_entry_mode(ae)); - archive_entry_set_size(ae, 0x81000); - archive_entry_sparse_add_entry(ae, 0x10000, 0x1000); - archive_entry_sparse_add_entry(ae, 0x80000, 0x1000); - - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - memset(buff2, 'a', buff2_size); - for (i = 0; i < 0x81000;) { - size_t ws = buff2_size; - if (i + ws > 0x81000) - ws = 0x81000 - i; - assertEqualInt(ws, - archive_write_data(a, buff2, ws)); - i += (long)ws; - } - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* This calculation gives "the smallest multiple of - * the block size that is at least 11264 bytes". */ - failure("blocksize=%zu", blocksize); - assertEqualInt(((11264 - 1)/blocksize+1)*blocksize, used); - - /* - * Now, read the data back. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, buff, used)); - - assertEqualIntA(a, ARCHIVE_OK, - archive_read_next_header(a, &ae)); - - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(10, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); - assertEqualInt(0x81000, archive_entry_size(ae)); - /* Verify sparse information. */ - assertEqualInt(2, archive_entry_sparse_reset(ae)); - assertEqualInt(0, - archive_entry_sparse_next(ae, &offset, &length)); - assertEqualInt(0x10000, offset); - assertEqualInt(0x1000, length); - assertEqualInt(0, - archive_entry_sparse_next(ae, &offset, &length)); - assertEqualInt(0x80000, offset); - assertEqualInt(0x1000, length); - /* Verify file contents. */ - memset(buff3, 0, sizeof(buff3)); - for (i = 0; i < 0x10000; i += 1024) { - assertEqualInt(1024, archive_read_data(a, buff2, 1024)); - failure("Read data(0x%lx - 0x%lx) should be all zero", - i, i + 1024); - assertEqualMem(buff2, buff3, 1024); - } - memset(buff3, 'a', sizeof(buff3)); - for (i = 0x10000; i < 0x11000; i += 1024) { - assertEqualInt(1024, archive_read_data(a, buff2, 1024)); - failure("Read data(0x%lx - 0x%lx) should be all 'a'", - i, i + 1024); - assertEqualMem(buff2, buff3, 1024); - } - memset(buff3, 0, sizeof(buff3)); - for (i = 0x11000; i < 0x80000; i += 1024) { - assertEqualInt(1024, archive_read_data(a, buff2, 1024)); - failure("Read data(0x%lx - 0x%lx) should be all zero", - i, i + 1024); - assertEqualMem(buff2, buff3, 1024); - } - memset(buff3, 'a', sizeof(buff3)); - for (i = 0x80000; i < 0x81000; i += 1024) { - assertEqualInt(1024, archive_read_data(a, buff2, 1024)); - failure("Read data(0x%lx - 0x%lx) should be all 'a'", - i, i + 1024); - assertEqualMem(buff2, buff3, 1024); - } - - /* Verify the end of the archive. */ - assertEqualIntA(a, ARCHIVE_EOF, - archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - } - free(buff2); -} - -/* - * Test for the case the full bytes of sparse file data is not written. - */ -static void -test_2(void) -{ - struct archive_entry *ae; - struct archive *a; - size_t used; - size_t blocksize = 20 * 512; - int64_t offset, length; - char *buff2; - size_t buff2_size = 0x11000; - char buff3[1024]; - long i; - - assert((buff2 = malloc(buff2_size)) != NULL); - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_format_pax(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, (int)blocksize)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_in_last_block(a, (int)blocksize)); - assertEqualInt(blocksize, - archive_write_get_bytes_in_last_block(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - assertEqualInt(blocksize, - archive_write_get_bytes_in_last_block(a)); - - /* - * Write a file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(10, archive_entry_mtime_nsec(ae)); - archive_entry_copy_pathname(ae, "file"); - assertEqualString("file", archive_entry_pathname(ae)); - archive_entry_set_mode(ae, S_IFREG | 0755); - assertEqualInt(S_IFREG | 0755, archive_entry_mode(ae)); - archive_entry_set_size(ae, 0x81000); - archive_entry_sparse_add_entry(ae, 0x10000, 0x1000); - archive_entry_sparse_add_entry(ae, 0x80000, 0x1000); - - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - memset(buff2, 'a', buff2_size); - /* Write bytes less than it should be. */ - assertEqualInt(buff2_size, archive_write_data(a, buff2, buff2_size)); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* This calculation gives "the smallest multiple of - * the block size that is at least 11264 bytes". */ - failure("blocksize=%zu", blocksize); - assertEqualInt(((11264 - 1)/blocksize+1)*blocksize, used); - - /* - * Now, read the data back. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(10, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file", archive_entry_pathname(ae)); - assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); - assertEqualInt(0x81000, archive_entry_size(ae)); - /* Verify sparse information. */ - assertEqualInt(2, archive_entry_sparse_reset(ae)); - assertEqualInt(0, archive_entry_sparse_next(ae, &offset, &length)); - assertEqualInt(0x10000, offset); - assertEqualInt(0x1000, length); - assertEqualInt(0, archive_entry_sparse_next(ae, &offset, &length)); - assertEqualInt(0x80000, offset); - assertEqualInt(0x1000, length); - /* Verify file contents. */ - memset(buff3, 0, sizeof(buff3)); - for (i = 0; i < 0x10000; i += 1024) { - assertEqualInt(1024, archive_read_data(a, buff2, 1024)); - failure("Read data(0x%lx - 0x%lx) should be all zero", - i, i + 1024); - assertEqualMem(buff2, buff3, 1024); - } - memset(buff3, 'a', sizeof(buff3)); - for (i = 0x10000; i < 0x11000; i += 1024) { - assertEqualInt(1024, archive_read_data(a, buff2, 1024)); - failure("Read data(0x%lx - 0x%lx) should be all 'a'", - i, i + 1024); - assertEqualMem(buff2, buff3, 1024); - } - memset(buff3, 0, sizeof(buff3)); - for (i = 0x11000; i < 0x80000; i += 1024) { - assertEqualInt(1024, archive_read_data(a, buff2, 1024)); - failure("Read data(0x%lx - 0x%lx) should be all zero", - i, i + 1024); - assertEqualMem(buff2, buff3, 1024); - } - memset(buff3, 0, sizeof(buff3)); - for (i = 0x80000; i < 0x81000; i += 1024) { - assertEqualInt(1024, archive_read_data(a, buff2, 1024)); - failure("Read data(0x%lx - 0x%lx) should be all 'a'", - i, i + 1024); - assertEqualMem(buff2, buff3, 1024); - } - - /* Verify the end of the archive. */ - assertEqualIntA(a, ARCHIVE_EOF, - archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - free(buff2); -} - -DEFINE_TEST(test_write_format_tar_sparse) -{ - /* Test1: archiving sparse files. */ - test_1(); - /* Test2: incompletely archiving sparse files. */ - test_2(); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_tar_ustar.c b/thirdparty/libarchive/libarchive/test/test_write_format_tar_ustar.c deleted file mode 100644 index 7bc38f7b5..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_tar_ustar.c +++ /dev/null @@ -1,354 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_format_tar_ustar.c 201247 2009-12-30 05:59:21Z kientzle $"); - -static int -is_null(const char *p, size_t l) -{ - while (l > 0) { - if (*p != '\0') - return (0); - --l; - ++p; - } - return (1); -} - -/* Verify the contents, then erase them to NUL bytes. */ -/* Tar requires all "unused" bytes be set to NUL; this allows us - * to easily verify that by invoking is_null() over the entire header - * after verifying each field. */ -#define myAssertEqualMem(a,b,s) assertEqualMem(a, b, s); memset(a, 0, s) - -/* - * Detailed verification that 'ustar' archives are written with - * the correct format. - */ -DEFINE_TEST(test_write_format_tar_ustar) -{ - struct archive *a; - struct archive_entry *entry; - char *buff, *e; - size_t buffsize = 100000; - size_t used; - int i; - char f99[100]; - char f100[101]; - char f256[257]; - - for (i = 0; i < 99; ++i) - f99[i] = 'a' + i % 26; - f99[99] = '\0'; - - for (i = 0; i < 100; ++i) - f100[i] = 'A' + i % 26; - f100[100] = '\0'; - - for (i = 0; i < 256; ++i) - f256[i] = 'A' + i % 26; - f256[155] = '/'; - f256[256] = '\0'; - - buff = malloc(buffsize); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used)); - - /* - * Add various files to it. - * TODO: Extend this to cover more filetypes. - */ - - /* "file" with 10 bytes of content */ - assert((entry = archive_entry_new()) != NULL); - archive_entry_set_mtime(entry, 1, 10); - archive_entry_set_pathname(entry, "file"); - archive_entry_set_mode(entry, S_IFREG | 0664); - archive_entry_set_size(entry, 10); - archive_entry_set_uid(entry, 80); - archive_entry_set_gid(entry, 90); - archive_entry_set_dev(entry, 12); - archive_entry_set_ino(entry, 89); - archive_entry_set_nlink(entry, 2); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualIntA(a, 10, archive_write_data(a, "1234567890", 10)); - - /* Hardlink to "file" with 10 bytes of content */ - assert((entry = archive_entry_new()) != NULL); - archive_entry_set_mtime(entry, 1, 10); - archive_entry_set_pathname(entry, "linkfile"); - archive_entry_set_mode(entry, S_IFREG | 0664); - /* TODO: Put this back and fix the bug. */ - /* archive_entry_set_size(entry, 10); */ - archive_entry_set_uid(entry, 80); - archive_entry_set_gid(entry, 90); - archive_entry_set_dev(entry, 12); - archive_entry_set_ino(entry, 89); - archive_entry_set_nlink(entry, 2); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_header(a, entry)); - archive_entry_free(entry); - /* Write of data to dir should fail == zero bytes get written. */ - assertEqualIntA(a, 0, archive_write_data(a, "1234567890", 10)); - - /* "dir" */ - assert((entry = archive_entry_new()) != NULL); - archive_entry_set_mtime(entry, 2, 20); - archive_entry_set_pathname(entry, "dir"); - archive_entry_set_mode(entry, S_IFDIR | 0775); - archive_entry_set_size(entry, 10); - archive_entry_set_nlink(entry, 2); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_header(a, entry)); - archive_entry_free(entry); - /* Write of data to dir should fail == zero bytes get written. */ - assertEqualIntA(a, 0, archive_write_data(a, "1234567890", 10)); - - /* "symlink" pointing to "file" */ - assert((entry = archive_entry_new()) != NULL); - archive_entry_set_mtime(entry, 3, 30); - archive_entry_set_pathname(entry, "symlink"); - archive_entry_set_mode(entry, 0664); - archive_entry_set_filetype(entry, AE_IFLNK); - archive_entry_set_symlink(entry,"file"); - archive_entry_set_size(entry, 0); - archive_entry_set_uid(entry, 88); - archive_entry_set_gid(entry, 98); - archive_entry_set_dev(entry, 12); - archive_entry_set_ino(entry, 90); - archive_entry_set_nlink(entry, 1); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_header(a, entry)); - archive_entry_free(entry); - /* Write of data to symlink should fail == zero bytes get written. */ - assertEqualIntA(a, 0, archive_write_data(a, "1234567890", 10)); - - /* file with 99-char filename. */ - assert((entry = archive_entry_new()) != NULL); - archive_entry_set_mtime(entry, 1, 10); - archive_entry_set_pathname(entry, f99); - archive_entry_set_mode(entry, S_IFREG | 0664); - archive_entry_set_size(entry, 0); - archive_entry_set_uid(entry, 82); - archive_entry_set_gid(entry, 93); - archive_entry_set_dev(entry, 102); - archive_entry_set_ino(entry, 7); - archive_entry_set_nlink(entry, 1); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_header(a, entry)); - archive_entry_free(entry); - - /* file with 100-char filename. */ - assert((entry = archive_entry_new()) != NULL); - archive_entry_set_mtime(entry, 1, 10); - archive_entry_set_pathname(entry, f100); - archive_entry_set_mode(entry, S_IFREG | 0664); - archive_entry_set_size(entry, 0); - archive_entry_set_uid(entry, 82); - archive_entry_set_gid(entry, 93); - archive_entry_set_dev(entry, 102); - archive_entry_set_ino(entry, 7); - archive_entry_set_nlink(entry, 1); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_header(a, entry)); - archive_entry_free(entry); - - /* file with 256-char filename. */ - assert((entry = archive_entry_new()) != NULL); - archive_entry_set_mtime(entry, 1, 10); - archive_entry_set_pathname(entry, f256); - archive_entry_set_mode(entry, S_IFREG | 0664); - archive_entry_set_size(entry, 0); - archive_entry_set_uid(entry, 82); - archive_entry_set_gid(entry, 93); - archive_entry_set_dev(entry, 102); - archive_entry_set_ino(entry, 7); - archive_entry_set_nlink(entry, 1); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_header(a, entry)); - archive_entry_free(entry); - - /* Close out the archive. */ - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Verify the archive format. - */ - e = buff; - - /* "file" */ - myAssertEqualMem(e + 0, "file", 5); /* Filename */ - myAssertEqualMem(e + 100, "000664 ", 8); /* mode */ - myAssertEqualMem(e + 108, "000120 ", 8); /* uid */ - myAssertEqualMem(e + 116, "000132 ", 8); /* gid */ - myAssertEqualMem(e + 124, "00000000012 ", 12); /* size */ - myAssertEqualMem(e + 136, "00000000001 ", 12); /* mtime */ - myAssertEqualMem(e + 148, "010034\0 ", 8); /* checksum */ - myAssertEqualMem(e + 156, "0", 1); /* linkflag */ - myAssertEqualMem(e + 157, "", 1); /* linkname */ - myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */ - myAssertEqualMem(e + 265, "", 1); /* uname */ - myAssertEqualMem(e + 297, "", 1); /* gname */ - myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */ - myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */ - myAssertEqualMem(e + 345, "", 1); /* prefix */ - assert(is_null(e + 0, 512)); - myAssertEqualMem(e + 512, "1234567890", 10); - assert(is_null(e + 512, 512)); - e += 1024; - - /* hardlink to "file" */ - myAssertEqualMem(e + 0, "linkfile", 9); /* Filename */ - myAssertEqualMem(e + 100, "000664 ", 8); /* mode */ - myAssertEqualMem(e + 108, "000120 ", 8); /* uid */ - myAssertEqualMem(e + 116, "000132 ", 8); /* gid */ - myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */ - myAssertEqualMem(e + 136, "00000000001 ", 12); /* mtime */ - myAssertEqualMem(e + 148, "010707\0 ", 8); /* checksum */ - myAssertEqualMem(e + 156, "0", 1); /* linkflag */ - myAssertEqualMem(e + 157, "", 1); /* linkname */ - myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */ - myAssertEqualMem(e + 265, "", 1); /* uname */ - myAssertEqualMem(e + 297, "", 1); /* gname */ - myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */ - myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */ - myAssertEqualMem(e + 345, "", 1); /* prefix */ - assert(is_null(e + 0, 512)); - e += 512; - - /* "dir" */ - myAssertEqualMem(e + 0, "dir/", 4); /* Filename */ - myAssertEqualMem(e + 100, "000775 ", 8); /* mode */ - myAssertEqualMem(e + 108, "000000 ", 8); /* uid */ - myAssertEqualMem(e + 116, "000000 ", 8); /* gid */ - myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */ - myAssertEqualMem(e + 136, "00000000002 ", 12); /* mtime */ - myAssertEqualMem(e + 148, "007747\0 ", 8); /* checksum */ - myAssertEqualMem(e + 156, "5", 1); /* typeflag */ - myAssertEqualMem(e + 157, "", 1); /* linkname */ - myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */ - myAssertEqualMem(e + 265, "", 1); /* uname */ - myAssertEqualMem(e + 297, "", 1); /* gname */ - myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */ - myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */ - myAssertEqualMem(e + 345, "", 1); /* prefix */ - assert(is_null(e + 0, 512)); - e += 512; - - /* "symlink" pointing to "file" */ - myAssertEqualMem(e + 0, "symlink", 8); /* Filename */ - myAssertEqualMem(e + 100, "000664 ", 8); /* mode */ - myAssertEqualMem(e + 108, "000130 ", 8); /* uid */ - myAssertEqualMem(e + 116, "000142 ", 8); /* gid */ - myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */ - myAssertEqualMem(e + 136, "00000000003 ", 12); /* mtime */ - myAssertEqualMem(e + 148, "011446\0 ", 8); /* checksum */ - myAssertEqualMem(e + 156, "2", 1); /* linkflag */ - myAssertEqualMem(e + 157, "file", 5); /* linkname */ - myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */ - myAssertEqualMem(e + 265, "", 1); /* uname */ - myAssertEqualMem(e + 297, "", 1); /* gname */ - myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */ - myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */ - myAssertEqualMem(e + 345, "", 1); /* prefix */ - assert(is_null(e + 0, 512)); - e += 512; - - /* File with 99-char filename */ - myAssertEqualMem(e + 0, f99, 100); /* Filename */ - myAssertEqualMem(e + 100, "000664 ", 8); /* mode */ - myAssertEqualMem(e + 108, "000122 ", 8); /* uid */ - myAssertEqualMem(e + 116, "000135 ", 8); /* gid */ - myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */ - myAssertEqualMem(e + 136, "00000000001 ", 12); /* mtime */ - myAssertEqualMem(e + 148, "034242\0 ", 8); /* checksum */ - myAssertEqualMem(e + 156, "0", 1); /* linkflag */ - myAssertEqualMem(e + 157, "", 1); /* linkname */ - myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */ - myAssertEqualMem(e + 265, "", 1); /* uname */ - myAssertEqualMem(e + 297, "", 1); /* gname */ - myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */ - myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */ - myAssertEqualMem(e + 345, "", 1); /* prefix */ - assert(is_null(e + 0, 512)); - e += 512; - - /* File with 100-char filename */ - myAssertEqualMem(e + 0, f100, 100); /* Filename */ - myAssertEqualMem(e + 100, "000664 ", 8); /* mode */ - myAssertEqualMem(e + 108, "000122 ", 8); /* uid */ - myAssertEqualMem(e + 116, "000135 ", 8); /* gid */ - myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */ - myAssertEqualMem(e + 136, "00000000001 ", 12); /* mtime */ - myAssertEqualMem(e + 148, "026230\0 ", 8); /* checksum */ - myAssertEqualMem(e + 156, "0", 1); /* linkflag */ - myAssertEqualMem(e + 157, "", 1); /* linkname */ - myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */ - myAssertEqualMem(e + 265, "", 1); /* uname */ - myAssertEqualMem(e + 297, "", 1); /* gname */ - myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */ - myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */ - myAssertEqualMem(e + 345, "", 1); /* prefix */ - assert(is_null(e + 0, 512)); - e += 512; - - /* File with 256-char filename */ - myAssertEqualMem(e + 0, f256 + 156, 100); /* Filename */ - myAssertEqualMem(e + 100, "000664 ", 8); /* mode */ - myAssertEqualMem(e + 108, "000122 ", 8); /* uid */ - myAssertEqualMem(e + 116, "000135 ", 8); /* gid */ - myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */ - myAssertEqualMem(e + 136, "00000000001 ", 12); /* mtime */ - myAssertEqualMem(e + 148, "055570\0 ", 8); /* checksum */ - myAssertEqualMem(e + 156, "0", 1); /* linkflag */ - myAssertEqualMem(e + 157, "", 1); /* linkname */ - myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */ - myAssertEqualMem(e + 265, "", 1); /* uname */ - myAssertEqualMem(e + 297, "", 1); /* gname */ - myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */ - myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */ - myAssertEqualMem(e + 345, f256, 155); /* prefix */ - assert(is_null(e + 0, 512)); - e += 512; - - /* TODO: Verify other types of entries. */ - - /* Last entry is end-of-archive marker. */ - assert(is_null(e, 1024)); - e += 1024; - - assertEqualInt((int)used, e - buff); - - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_tar_v7tar.c b/thirdparty/libarchive/libarchive/test/test_write_format_tar_v7tar.c deleted file mode 100644 index 169099568..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_tar_v7tar.c +++ /dev/null @@ -1,259 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -static int -is_null(const char *p, size_t l) -{ - while (l > 0) { - if (*p != '\0') - return (0); - --l; - ++p; - } - return (1); -} - -/* Verify the contents, then erase them to NUL bytes. */ -/* Tar requires all "unused" bytes be set to NUL; this allows us - * to easily verify that by invoking is_null() over the entire header - * after verifying each field. */ -#define myAssertEqualMem(a,b,s) assertEqualMem(a, b, s); memset(a, 0, s) - -/* - * Detailed verification that 'v7tar' archives are written with - * the correct format. - */ -DEFINE_TEST(test_write_format_tar_v7tar) -{ - struct archive *a; - struct archive_entry *entry; - char *buff, *e; - size_t buffsize = 100000; - size_t used; - int i; - char f99[100]; - char f100[101]; - - for (i = 0; i < 99; ++i) - f99[i] = 'a' + i % 26; - f99[99] = '\0'; - - for (i = 0; i < 100; ++i) - f100[i] = 'A' + i % 26; - f100[100] = '\0'; - - buff = malloc(buffsize); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_format_v7tar(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used)); - - /* - * Add various files to it. - * TODO: Extend this to cover more filetypes. - */ - - /* "file" with 10 bytes of content */ - assert((entry = archive_entry_new()) != NULL); - archive_entry_set_mtime(entry, 1, 10); - archive_entry_set_pathname(entry, "file"); - archive_entry_set_mode(entry, S_IFREG | 0664); - archive_entry_set_size(entry, 10); - archive_entry_set_uid(entry, 80); - archive_entry_set_gid(entry, 90); - archive_entry_set_dev(entry, 12); - archive_entry_set_ino(entry, 89); - archive_entry_set_nlink(entry, 2); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualIntA(a, 10, archive_write_data(a, "1234567890", 10)); - - /* Hardlink to "file" with 10 bytes of content */ - assert((entry = archive_entry_new()) != NULL); - archive_entry_set_mtime(entry, 1, 10); - archive_entry_set_pathname(entry, "linkfile"); - archive_entry_set_hardlink(entry, "file"); - archive_entry_set_mode(entry, S_IFREG | 0664); - archive_entry_set_size(entry, 10); - archive_entry_set_uid(entry, 80); - archive_entry_set_gid(entry, 90); - archive_entry_set_dev(entry, 12); - archive_entry_set_ino(entry, 89); - archive_entry_set_nlink(entry, 2); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - /* Write of data to dir should fail == zero bytes get written. */ - assertEqualIntA(a, 0, archive_write_data(a, "1234567890", 10)); - - /* "dir" */ - assert((entry = archive_entry_new()) != NULL); - archive_entry_set_mtime(entry, 2, 20); - archive_entry_set_pathname(entry, "dir"); - archive_entry_set_mode(entry, S_IFDIR | 0775); - archive_entry_set_size(entry, 10); - archive_entry_set_nlink(entry, 2); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - /* Write of data to dir should fail == zero bytes get written. */ - assertEqualIntA(a, 0, archive_write_data(a, "1234567890", 10)); - - /* "symlink" pointing to "file" */ - assert((entry = archive_entry_new()) != NULL); - archive_entry_set_mtime(entry, 3, 30); - archive_entry_set_pathname(entry, "symlink"); - archive_entry_set_mode(entry, 0664); - archive_entry_set_filetype(entry, AE_IFLNK); - archive_entry_set_symlink(entry,"file"); - archive_entry_set_size(entry, 0); - archive_entry_set_uid(entry, 88); - archive_entry_set_gid(entry, 98); - archive_entry_set_dev(entry, 12); - archive_entry_set_ino(entry, 90); - archive_entry_set_nlink(entry, 1); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - - /* file with 99-char filename. */ - assert((entry = archive_entry_new()) != NULL); - archive_entry_set_mtime(entry, 1, 10); - archive_entry_set_pathname(entry, f99); - archive_entry_set_mode(entry, S_IFREG | 0664); - archive_entry_set_size(entry, 0); - archive_entry_set_uid(entry, 82); - archive_entry_set_gid(entry, 93); - archive_entry_set_dev(entry, 102); - archive_entry_set_ino(entry, 7); - archive_entry_set_nlink(entry, 1); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - - /* file with 100-char filename. */ - assert((entry = archive_entry_new()) != NULL); - archive_entry_set_mtime(entry, 1, 10); - archive_entry_set_pathname(entry, f100); - archive_entry_set_mode(entry, S_IFREG | 0664); - archive_entry_set_size(entry, 0); - archive_entry_set_uid(entry, 82); - archive_entry_set_gid(entry, 93); - archive_entry_set_dev(entry, 102); - archive_entry_set_ino(entry, 7); - archive_entry_set_nlink(entry, 1); - failure("100-char filename should be rejected"); - assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, entry)); - archive_entry_free(entry); - - /* Close out the archive. */ - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Verify the archive format. - */ - e = buff; - - /* "file" */ - myAssertEqualMem(e + 0, "file", 5); /* Filename */ - myAssertEqualMem(e + 100, "000664 ", 8); /* mode */ - myAssertEqualMem(e + 108, "000120 ", 8); /* uid */ - myAssertEqualMem(e + 116, "000132 ", 8); /* gid */ - myAssertEqualMem(e + 124, "00000000012 ", 12); /* size */ - myAssertEqualMem(e + 136, "00000000001 ", 12); /* mtime */ - myAssertEqualMem(e + 148, "005335\0 ", 8); /* checksum */ - myAssertEqualMem(e + 156, "", 1); /* linkflag */ - myAssertEqualMem(e + 157, "", 1); /* linkname */ - assert(is_null(e + 0, 512)); - myAssertEqualMem(e + 512, "1234567890", 10); - assert(is_null(e + 512, 512)); - e += 1024; - - /* hardlink to "file" */ - myAssertEqualMem(e + 0, "linkfile", 9); /* Filename */ - myAssertEqualMem(e + 100, "000664 ", 8); /* mode */ - myAssertEqualMem(e + 108, "000120 ", 8); /* uid */ - myAssertEqualMem(e + 116, "000132 ", 8); /* gid */ - myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */ - myAssertEqualMem(e + 136, "00000000001 ", 12); /* mtime */ - myAssertEqualMem(e + 148, "007131\0 ", 8); /* checksum */ - myAssertEqualMem(e + 156, "1", 1); /* linkflag */ - myAssertEqualMem(e + 157, "file", 5); /* linkname */ - assert(is_null(e + 0, 512)); - e += 512; - - /* "dir" */ - myAssertEqualMem(e + 0, "dir/", 4); /* Filename */ - myAssertEqualMem(e + 100, "000775 ", 8); /* mode */ - myAssertEqualMem(e + 108, "000000 ", 8); /* uid */ - myAssertEqualMem(e + 116, "000000 ", 8); /* gid */ - myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */ - myAssertEqualMem(e + 136, "00000000002 ", 12); /* mtime */ - myAssertEqualMem(e + 148, "005243\0 ", 8); /* checksum */ - myAssertEqualMem(e + 156, "", 1); /* typeflag */ - myAssertEqualMem(e + 157, "", 1); /* linkname */ - assert(is_null(e + 0, 512)); - e += 512; - - /* "symlink" pointing to "file" */ - myAssertEqualMem(e + 0, "symlink", 8); /* Filename */ - myAssertEqualMem(e + 100, "000664 ", 8); /* mode */ - myAssertEqualMem(e + 108, "000130 ", 8); /* uid */ - myAssertEqualMem(e + 116, "000142 ", 8); /* gid */ - myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */ - myAssertEqualMem(e + 136, "00000000003 ", 12); /* mtime */ - myAssertEqualMem(e + 148, "007027\0 ", 8); /* checksum */ - myAssertEqualMem(e + 156, "2", 1); /* linkflag */ - myAssertEqualMem(e + 157, "file", 5); /* linkname */ - assert(is_null(e + 0, 512)); - e += 512; - - /* File with 99-char filename */ - myAssertEqualMem(e + 0, f99, 100); /* Filename */ - myAssertEqualMem(e + 100, "000664 ", 8); /* mode */ - myAssertEqualMem(e + 108, "000122 ", 8); /* uid */ - myAssertEqualMem(e + 116, "000135 ", 8); /* gid */ - myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */ - myAssertEqualMem(e + 136, "00000000001 ", 12); /* mtime */ - myAssertEqualMem(e + 148, "031543\0 ", 8); /* checksum */ - myAssertEqualMem(e + 156, "", 1); /* linkflag */ - myAssertEqualMem(e + 157, "", 1); /* linkname */ - assert(is_null(e + 0, 512)); - e += 512; - - /* TODO: Verify other types of entries. */ - - /* Last entry is end-of-archive marker. */ - assert(is_null(e, 1024)); - e += 1024; - - assertEqualInt((int)used, e - buff); - - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_warc.c b/thirdparty/libarchive/libarchive/test/test_write_format_warc.c deleted file mode 100644 index 3a4c2da1e..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_warc.c +++ /dev/null @@ -1,146 +0,0 @@ -/*- - * Copyright (C) 2014 Sebastian Freundt - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -static void test_read(struct archive *a, char *buff, size_t used, char *filedata) -{ - struct archive_entry *ae; - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualIntA(a, 9, archive_read_data(a, filedata, 10)); - assertEqualMem(filedata, "12345678", 9); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -DEFINE_TEST(test_write_format_warc) -{ - char filedata[64]; - struct archive *a; - struct archive_entry *ae; - const size_t bsiz = 2048U; - char *buff; - size_t used; - - buff = malloc(bsiz); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_warc(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, bsiz, &used)); - - /* - * Write a file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_pathname(ae, "test"); - archive_entry_set_filetype(ae, AE_IFREG); - archive_entry_set_size(ae, 9); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 9, archive_write_data(a, "12345678", 9)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Read from it. - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_warc(a)); - test_read(a, buff, used, filedata); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_by_code(a, ARCHIVE_FORMAT_WARC)); - test_read(a, buff, used, filedata); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_set_format(a, ARCHIVE_FORMAT_WARC)); - test_read(a, buff, used, filedata); - - /* Create a new archive */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_warc(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, bsiz, &used)); - - /* write first file: that should succeed */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_pathname(ae, "test"); - archive_entry_set_filetype(ae, AE_IFREG); - archive_entry_set_size(ae, 9); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 9, archive_write_data(a, "12345678", 9)); - - /* write second file: should succeed as well */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_pathname(ae, "test2"); - archive_entry_set_filetype(ae, AE_IFREG); - archive_entry_set_size(ae, 9); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 9, archive_write_data(a, "12345678", 9)); - - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Create a new archive */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_warc(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, bsiz, &used)); - - /* write a directory: this should fail */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "dir"); - archive_entry_set_filetype(ae, AE_IFDIR); - archive_entry_set_size(ae, 512); - assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae)); - archive_entry_free(ae); - - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* test whether last archive is indeed empty */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); - - /* Test EOF */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_warc_empty.c b/thirdparty/libarchive/libarchive/test/test_write_format_warc_empty.c deleted file mode 100644 index 0bd31bd7f..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_warc_empty.c +++ /dev/null @@ -1,117 +0,0 @@ -/*- - * Copyright (C) 2014 Sebastian Freundt - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_write_format_warc_empty) -{ - struct archive *a; - struct archive_entry *ae; - char buff[512U]; - size_t used; - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_warc(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - /* Add "." entry which must be ignored. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 0); - archive_entry_set_ctime(ae, 4, 0); - archive_entry_set_mtime(ae, 5, 0); - archive_entry_copy_pathname(ae, "."); - archive_entry_set_mode(ae, S_IFDIR | 0755); - assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Add ".." entry which must be ignored. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 0); - archive_entry_set_ctime(ae, 4, 0); - archive_entry_set_mtime(ae, 5, 0); - archive_entry_copy_pathname(ae, ".."); - archive_entry_set_mode(ae, S_IFDIR | 0755); - assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Add "/" entry which must be ignored. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 0); - archive_entry_set_ctime(ae, 4, 0); - archive_entry_set_mtime(ae, 5, 0); - archive_entry_copy_pathname(ae, "/"); - archive_entry_set_mode(ae, S_IFDIR | 0755); - assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Add "../" entry which must be ignored. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 0); - archive_entry_set_ctime(ae, 4, 0); - archive_entry_set_mtime(ae, 5, 0); - archive_entry_copy_pathname(ae, "../"); - archive_entry_set_mode(ae, S_IFDIR | 0755); - assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Add "../../." entry which must be ignored. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 0); - archive_entry_set_ctime(ae, 4, 0); - archive_entry_set_mtime(ae, 5, 0); - archive_entry_copy_pathname(ae, "../../."); - archive_entry_set_mode(ae, S_IFDIR | 0755); - assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Add "..//.././" entry which must be ignored. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 0); - archive_entry_set_ctime(ae, 4, 0); - archive_entry_set_mtime(ae, 5, 0); - archive_entry_copy_pathname(ae, "..//.././"); - archive_entry_set_mode(ae, S_IFDIR | 0755); - assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Close out the archive without writing anything. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Test whether last archive is empty indeed. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); - - /* Test EOF */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_xar.c b/thirdparty/libarchive/libarchive/test/test_write_format_xar.c deleted file mode 100644 index 02fd2c0e3..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_xar.c +++ /dev/null @@ -1,315 +0,0 @@ -/*- - * Copyright (c) 2003-2008 Tim Kientzle - * Copyright (c) 2010 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -static void -test_xar(const char *option) -{ - char buff2[64]; - size_t buffsize = 1500; - char *buff; - struct archive_entry *ae; - struct archive *a; - size_t used; - const char *name; - const void *value; - size_t size; - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - if (archive_write_set_format_xar(a) != ARCHIVE_OK) { - skipping("xar is not supported on this platform"); - assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); - return; - } - assertA(0 == archive_write_add_filter_none(a)); - if (option != NULL && - archive_write_set_options(a, option) != ARCHIVE_OK) { - skipping("option `%s` is not supported on this platform", option); - assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); - return; - } - - buff = malloc(buffsize); - assert(buff != NULL); - - assertA(0 == archive_write_open_memory(a, buff, buffsize, &used)); - - /* - * "file" has a bunch of attributes and 8 bytes of data and - * 7 bytes of xattr data and 3 bytes of xattr. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "file"); - archive_entry_set_mode(ae, AE_IFREG | 0755); - archive_entry_set_nlink(ae, 2); - archive_entry_set_size(ae, 8); - archive_entry_xattr_add_entry(ae, "user.data1", "ABCDEFG", 7); - archive_entry_xattr_add_entry(ae, "user.data2", "XYZ", 3); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9)); - - /* - * "file2" is symbolic link to file - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "file2"); - archive_entry_copy_symlink(ae, "file"); - archive_entry_set_mode(ae, AE_IFLNK | 0755); - archive_entry_set_size(ae, 0); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* - * "dir/file3" has a bunch of attributes and 8 bytes of data. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "dir/file"); - archive_entry_set_mode(ae, AE_IFREG | 0755); - archive_entry_set_size(ae, 8); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, 8, archive_write_data(a, "abcdefgh", 9)); - - /* - * "dir/dir2/file4" is hard link to file - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "dir/dir2/file4"); - archive_entry_copy_hardlink(ae, "file"); - archive_entry_set_mode(ae, AE_IFREG | 0755); - archive_entry_set_nlink(ae, 2); - archive_entry_set_size(ae, 0); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* - * "dir/dir3" is a directory - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "dir/dir3"); - archive_entry_set_mode(ae, AE_IFDIR | 0755); - archive_entry_unset_size(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* - * Add a wrong path "dir/dir2/file4/wrong" - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 20); - archive_entry_set_ctime(ae, 4, 40); - archive_entry_set_mtime(ae, 5, 50); - archive_entry_copy_pathname(ae, "dir/dir2/file4/wrong"); - archive_entry_set_mode(ae, AE_IFREG | 0755); - archive_entry_set_nlink(ae, 1); - archive_entry_set_size(ae, 0); - assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* - * XXX TODO XXX Archive directory, other file types. - * Archive extended attributes, ACLs, other metadata. - * Verify they get read back correctly. - */ - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); - - /* - * - * Now, read the data back. - * - */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, 0, archive_read_support_format_all(a)); - assertEqualIntA(a, 0, archive_read_support_filter_all(a)); - assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used)); - - /* - * Read "file" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_atime_nsec(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(0, archive_entry_ctime_nsec(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualString("file", archive_entry_pathname(ae)); - assert((AE_IFREG | 0755) == archive_entry_mode(ae)); - assertEqualInt(2, archive_entry_nlink(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualInt(2, archive_entry_xattr_reset(ae)); - assertEqualInt(ARCHIVE_OK, - archive_entry_xattr_next(ae, &name, &value, &size)); - assertEqualString("user.data2", name); - assertEqualMem(value, "XYZ", 3); - assertEqualInt(ARCHIVE_OK, - archive_entry_xattr_next(ae, &name, &value, &size)); - assertEqualString("user.data1", name); - assertEqualMem(value, "ABCDEFG", 7); - assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "12345678", 8); - - /* - * Read "file2" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assert(archive_entry_atime_is_set(ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_atime_nsec(ae)); - assert(archive_entry_ctime_is_set(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(0, archive_entry_ctime_nsec(ae)); - assert(archive_entry_mtime_is_set(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualString("file2", archive_entry_pathname(ae)); - assertEqualString("file", archive_entry_symlink(ae)); - assert((AE_IFLNK | 0755) == archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - - /* - * Read "dir/file3" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_atime_nsec(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(0, archive_entry_ctime_nsec(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualString("dir/file", archive_entry_pathname(ae)); - assert((AE_IFREG | 0755) == archive_entry_mode(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "abcdefgh", 8); - - /* - * Read "dir/dir2/file4" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assert(archive_entry_atime_is_set(ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_atime_nsec(ae)); - assert(archive_entry_ctime_is_set(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(0, archive_entry_ctime_nsec(ae)); - assert(archive_entry_mtime_is_set(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualString("dir/dir2/file4", archive_entry_pathname(ae)); - assertEqualString("file", archive_entry_hardlink(ae)); - assert((AE_IFREG | 0755) == archive_entry_mode(ae)); - assertEqualInt(2, archive_entry_nlink(ae)); - assertEqualInt(0, archive_entry_size(ae)); - - /* - * Read "dir/dir3" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assert(archive_entry_atime_is_set(ae)); - assertEqualInt(2, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_atime_nsec(ae)); - assert(archive_entry_ctime_is_set(ae)); - assertEqualInt(4, archive_entry_ctime(ae)); - assertEqualInt(0, archive_entry_ctime_nsec(ae)); - assert(archive_entry_mtime_is_set(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualString("dir/dir3", archive_entry_pathname(ae)); - assert((AE_IFDIR | 0755) == archive_entry_mode(ae)); - - /* - * Verify the end of the archive. - */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); - - free(buff); -} - -DEFINE_TEST(test_write_format_xar) -{ - /* Default mode. */ - test_xar(NULL); - - /* Disable TOC checksum. */ - test_xar("!toc-checksum"); - test_xar("toc-checksum=none"); - /* Specify TOC checksum type to sha1. */ - test_xar("toc-checksum=sha1"); - /* Specify TOC checksum type to md5. */ - test_xar("toc-checksum=md5"); - - /* Disable file checksum. */ - test_xar("!checksum"); - test_xar("checksum=none"); - /* Specify file checksum type to sha1. */ - test_xar("checksum=sha1"); - /* Specify file checksum type to md5. */ - test_xar("checksum=md5"); - - /* Disable compression. */ - test_xar("!compression"); - test_xar("compression=none"); - /* Specify compression type to gzip. */ - test_xar("compression=gzip"); - test_xar("compression=gzip,compression-level=1"); - test_xar("compression=gzip,compression-level=9"); - /* Specify compression type to bzip2. */ - test_xar("compression=bzip2"); - test_xar("compression=bzip2,compression-level=1"); - test_xar("compression=bzip2,compression-level=9"); - /* Specify compression type to lzma. */ - test_xar("compression=lzma"); - test_xar("compression=lzma,compression-level=1"); - test_xar("compression=lzma,compression-level=9"); - /* Specify compression type to xz. */ - test_xar("compression=xz"); - test_xar("compression=xz,compression-level=1"); - test_xar("compression=xz,compression-level=9"); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_xar_empty.c b/thirdparty/libarchive/libarchive/test/test_write_format_xar_empty.c deleted file mode 100644 index 97c080887..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_xar_empty.c +++ /dev/null @@ -1,120 +0,0 @@ -/*- - * Copyright (c) 2010-2011 Michihiro NAKAJIMA - * Copyright (c) 2008 Anselm Strauss - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -/* - * Development supported by Google Summer of Code 2008. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_write_format_xar_empty) -{ - struct archive *a; - struct archive_entry *ae; - char buff[256]; - size_t used; - - /* Xar format: Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - if (archive_write_set_format_xar(a) != ARCHIVE_OK) { - skipping("xar is not supported on this platform"); - assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); - return; - } - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_bytes_per_block(a, 1)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_bytes_in_last_block(a, 1)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - /* Add "." entry which must be ignored. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 0); - archive_entry_set_ctime(ae, 4, 0); - archive_entry_set_mtime(ae, 5, 0); - archive_entry_copy_pathname(ae, "."); - archive_entry_set_mode(ae, S_IFDIR | 0755); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Add ".." entry which must be ignored. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 0); - archive_entry_set_ctime(ae, 4, 0); - archive_entry_set_mtime(ae, 5, 0); - archive_entry_copy_pathname(ae, ".."); - archive_entry_set_mode(ae, S_IFDIR | 0755); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Add "/" entry which must be ignored. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 0); - archive_entry_set_ctime(ae, 4, 0); - archive_entry_set_mtime(ae, 5, 0); - archive_entry_copy_pathname(ae, "/"); - archive_entry_set_mode(ae, S_IFDIR | 0755); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Add "../" entry which must be ignored. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 0); - archive_entry_set_ctime(ae, 4, 0); - archive_entry_set_mtime(ae, 5, 0); - archive_entry_copy_pathname(ae, "../"); - archive_entry_set_mode(ae, S_IFDIR | 0755); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Add "../../." entry which must be ignored. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 0); - archive_entry_set_ctime(ae, 4, 0); - archive_entry_set_mtime(ae, 5, 0); - archive_entry_copy_pathname(ae, "../../."); - archive_entry_set_mode(ae, S_IFDIR | 0755); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Add "..//.././" entry which must be ignored. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_atime(ae, 2, 0); - archive_entry_set_ctime(ae, 4, 0); - archive_entry_set_mtime(ae, 5, 0); - archive_entry_copy_pathname(ae, "..//.././"); - archive_entry_set_mode(ae, S_IFDIR | 0755); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Close out the archive without writing anything. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Verify the correct format for an empty Xar archive. */ - assertEqualInt(used, 0); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_zip.c b/thirdparty/libarchive/libarchive/test/test_write_format_zip.c deleted file mode 100644 index a7ca434f8..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_zip.c +++ /dev/null @@ -1,909 +0,0 @@ -/*- - * Copyright (c) 2003-2008 Tim Kientzle - * Copyright (c) 2008 Anselm Strauss - * Copyright (c) 2014 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -/* - * Development supported by Google Summer of Code 2008. - */ - -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_format_zip.c 201247 2009-12-30 05:59:21Z kientzle $"); - -/* - * This test doesn't actually check that the zip writer is - * correct, just that our zip reader can read the output of - * our zip writer. We do more detailed checks of the bits - * elsewhere. - */ - -/* - * Write a variety of different file types into the archive. - */ -static void -write_contents(struct archive *a) -{ - struct archive_entry *ae; - - /* - * First write things with the "default" compression. - * The library will choose "deflate" for most things if it's - * available, else "store". - */ - - /* - * Write a file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - archive_entry_copy_pathname(ae, "file"); - archive_entry_set_mode(ae, AE_IFREG | 0755); - archive_entry_set_size(ae, 8); - assertEqualInt(0, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualInt(8, archive_write_data(a, "12345678", 9)); - assertEqualInt(0, archive_write_data(a, "1", 1)); - - /* - * Write another file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - archive_entry_copy_pathname(ae, "file2"); - archive_entry_set_mode(ae, AE_IFREG | 0755); - archive_entry_set_size(ae, 4); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualInt(4, archive_write_data(a, "1234", 4)); - - /* - * Write a file with an unknown size. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 2, 15); - archive_entry_copy_pathname(ae, "file3"); - archive_entry_set_mode(ae, AE_IFREG | 0621); - archive_entry_unset_size(ae); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualInt(5, archive_write_data(a, "mnopq", 5)); - - /* - * Write symbolic link. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(10, archive_entry_mtime_nsec(ae)); - archive_entry_copy_pathname(ae, "symlink"); - assertEqualString("symlink", archive_entry_pathname(ae)); - archive_entry_copy_symlink(ae, "file1"); - assertEqualString("file1", archive_entry_symlink(ae)); - archive_entry_set_mode(ae, AE_IFLNK | 0755); - assertEqualInt((AE_IFLNK | 0755), archive_entry_mode(ae)); - archive_entry_set_size(ae, 4); - - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* - * Write a directory to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 11, 110); - archive_entry_copy_pathname(ae, "dir"); - archive_entry_set_mode(ae, S_IFDIR | 0755); - archive_entry_set_size(ae, 512); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - failure("size should be zero so that applications know not to write"); - assertEqualInt(0, archive_entry_size(ae)); - archive_entry_free(ae); - assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9)); - - /* - * Force "deflate" compression if the platform supports it. - */ -#ifdef HAVE_ZLIB_H - assertEqualIntA(a, ARCHIVE_OK, archive_write_zip_set_compression_deflate(a)); - - /* - * Write a file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - archive_entry_copy_pathname(ae, "file_deflate"); - archive_entry_set_mode(ae, AE_IFREG | 0755); - archive_entry_set_size(ae, 8); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualInt(8, archive_write_data(a, "12345678", 9)); - assertEqualInt(0, archive_write_data(a, "1", 1)); - - /* - * Write another file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - archive_entry_copy_pathname(ae, "file2_deflate"); - archive_entry_set_mode(ae, AE_IFREG | 0755); - archive_entry_set_size(ae, 4); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualInt(4, archive_write_data(a, "1234", 4)); - - /* - * Write a file with an unknown size. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 2, 15); - archive_entry_copy_pathname(ae, "file3_deflate"); - archive_entry_set_mode(ae, AE_IFREG | 0621); - archive_entry_unset_size(ae); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualInt(5, archive_write_data(a, "ghijk", 5)); - - /* - * Write symbolic like file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - archive_entry_copy_pathname(ae, "symlink_deflate"); - archive_entry_copy_symlink(ae, "file1"); - archive_entry_set_mode(ae, AE_IFLNK | 0755); - archive_entry_set_size(ae, 4); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* - * Write a directory to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 11, 110); - archive_entry_copy_pathname(ae, "dir_deflate"); - archive_entry_set_mode(ae, S_IFDIR | 0755); - archive_entry_set_size(ae, 512); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - failure("size should be zero so that applications know not to write"); - assertEqualInt(0, archive_entry_size(ae)); - archive_entry_free(ae); - assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_finish_entry(a)); -#endif - - /* - * Now write a bunch of entries with "store" compression. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_zip_set_compression_store(a)); - - /* - * Write a file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - archive_entry_copy_pathname(ae, "file_stored"); - archive_entry_set_mode(ae, AE_IFREG | 0755); - archive_entry_set_size(ae, 8); - assertEqualInt(0, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualInt(8, archive_write_data(a, "12345678", 9)); - assertEqualInt(0, archive_write_data(a, "1", 1)); - - /* - * Write another file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - archive_entry_copy_pathname(ae, "file2_stored"); - archive_entry_set_mode(ae, AE_IFREG | 0755); - archive_entry_set_size(ae, 4); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualInt(4, archive_write_data(a, "ACEG", 4)); - - /* - * Write a file with an unknown size. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 2, 15); - archive_entry_copy_pathname(ae, "file3_stored"); - archive_entry_set_mode(ae, AE_IFREG | 0621); - archive_entry_unset_size(ae); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualInt(5, archive_write_data(a, "ijklm", 5)); - - /* - * Write symbolic like file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - archive_entry_copy_pathname(ae, "symlink_stored"); - archive_entry_copy_symlink(ae, "file1"); - archive_entry_set_mode(ae, AE_IFLNK | 0755); - archive_entry_set_size(ae, 4); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* - * Write a directory to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 11, 110); - archive_entry_copy_pathname(ae, "dir_stored"); - archive_entry_set_mode(ae, S_IFDIR | 0755); - archive_entry_set_size(ae, 512); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - failure("size should be zero so that applications know not to write"); - assertEqualInt(0, archive_entry_size(ae)); - archive_entry_free(ae); - assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9)); - - - /* Close out the archive. */ - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); -} - -/* - * Read back all of the entries and verify their values. - */ -static void -verify_contents(struct archive *a, int seeking, int content) -{ - char filedata[64]; - struct archive_entry *ae; - - /* - * Default compression options: - */ - - /* Read and verify first file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - /* Zip doesn't store high-resolution mtime. */ - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file", archive_entry_pathname(ae)); - if (seeking) { - assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); - } - assert(archive_entry_size_is_set(ae)); - assertEqualInt(8, archive_entry_size(ae)); - if (content) { - assertEqualIntA(a, 8, - archive_read_data(a, filedata, sizeof(filedata))); - assertEqualMem(filedata, "12345678", 8); - } - - /* Read the second file back. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file2", archive_entry_pathname(ae)); - if (seeking) { - assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); - } - assertEqualInt(4, archive_entry_size(ae)); - assert(archive_entry_size_is_set(ae)); - if (content) { - assertEqualIntA(a, 4, - archive_read_data(a, filedata, sizeof(filedata))); - assertEqualMem(filedata, "1234", 4); - } - - /* Read the third file back. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file3", archive_entry_pathname(ae)); - if (seeking) { - assertEqualInt(5, archive_entry_size(ae)); - assertEqualInt(AE_IFREG | 0621, archive_entry_mode(ae)); - } else { - assertEqualInt(0, archive_entry_size_is_set(ae)); - } - if (content) { - assertEqualIntA(a, 5, - archive_read_data(a, filedata, sizeof(filedata))); - assertEqualMem(filedata, "mnopq", 5); - } - - /* Read symlink. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("symlink", archive_entry_pathname(ae)); - assertEqualInt(AE_IFLNK | 0755, archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualString("file1", archive_entry_symlink(ae)); - - /* Read the dir entry back. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(11, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("dir/", archive_entry_pathname(ae)); - if (seeking) - assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - if (content) { - assertEqualIntA(a, 0, archive_read_data(a, filedata, 10)); - } - -#ifdef HAVE_ZLIB_H - /* - * Deflate compression option: - */ - - /* Read and verify first file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - /* Zip doesn't store high-resolution mtime. */ - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file_deflate", archive_entry_pathname(ae)); - if (seeking) - assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assert(archive_entry_size_is_set(ae)); - if (content) { - assertEqualIntA(a, 8, - archive_read_data(a, filedata, sizeof(filedata))); - assertEqualMem(filedata, "12345678", 8); - } - - - /* Read the second file back. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file2_deflate", archive_entry_pathname(ae)); - if (seeking) - assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); - assertEqualInt(4, archive_entry_size(ae)); - assert(archive_entry_size_is_set(ae)); - if (content) { - assertEqualIntA(a, 4, - archive_read_data(a, filedata, sizeof(filedata))); - assertEqualMem(filedata, "1234", 4); - } - - /* Read the third file back. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file3_deflate", archive_entry_pathname(ae)); - if (seeking) { - assertEqualInt(5, archive_entry_size(ae)); - assertEqualInt(AE_IFREG | 0621, archive_entry_mode(ae)); - } else { - assertEqualInt(0, archive_entry_size_is_set(ae)); - } - if (content) { - assertEqualIntA(a, 5, - archive_read_data(a, filedata, sizeof(filedata))); - assertEqualMem(filedata, "ghijk", 4); - } - - /* Read symlink. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("symlink_deflate", archive_entry_pathname(ae)); - assertEqualInt(AE_IFLNK | 0755, archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualString("file1", archive_entry_symlink(ae)); - - /* Read the dir entry back. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(11, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("dir_deflate/", archive_entry_pathname(ae)); - if (seeking) { - assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae)); - } - assertEqualInt(0, archive_entry_size(ae)); - if (content) { - assertEqualIntA(a, 0, archive_read_data(a, filedata, 10)); - } -#endif - - /* - * Store compression option: - */ - - /* Read and verify first file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - /* Zip doesn't store high-resolution mtime. */ - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file_stored", archive_entry_pathname(ae)); - if (seeking) - assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); - assert(archive_entry_size_is_set(ae)); - assertEqualInt(8, archive_entry_size(ae)); - if (content) { - assertEqualIntA(a, 8, - archive_read_data(a, filedata, sizeof(filedata))); - assertEqualMem(filedata, "12345678", 8); - } - - - /* Read the second file back. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file2_stored", archive_entry_pathname(ae)); - if (seeking) - assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); - assertEqualInt(4, archive_entry_size(ae)); - assert(archive_entry_size_is_set(ae)); - if (content) { - assertEqualIntA(a, 4, - archive_read_data(a, filedata, sizeof(filedata))); - assertEqualMem(filedata, "ACEG", 4); - } - - /* Read the third file back. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file3_stored", archive_entry_pathname(ae)); - if (seeking) { - assertEqualInt(5, archive_entry_size(ae)); - assertEqualInt(AE_IFREG | 0621, archive_entry_mode(ae)); - } else { - assertEqualInt(0, archive_entry_size_is_set(ae)); - } - if (content) { - assertEqualIntA(a, 5, - archive_read_data(a, filedata, sizeof(filedata))); - assertEqualMem(filedata, "ijklm", 4); - } - - /* Read symlink. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("symlink_stored", archive_entry_pathname(ae)); - assertEqualInt(AE_IFLNK | 0755, archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualString("file1", archive_entry_symlink(ae)); - - /* Read the dir entry back. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(11, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("dir_stored/", archive_entry_pathname(ae)); - if (seeking) - assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - if (content) { - assertEqualIntA(a, 0, archive_read_data(a, filedata, 10)); - } - - /* Verify the end of the archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* - * Do a write-then-read roundtrip. - */ -DEFINE_TEST(test_write_format_zip) -{ - struct archive *a; - size_t used; - size_t buffsize = 1000000; - char *buff; - - buff = malloc(buffsize); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "zip:experimental")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used)); - write_contents(a); - dumpfile("constructed.zip", buff, used); - - /* - * Now, read the data back. - */ - /* With the standard memory reader. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); - verify_contents(a, 1, 1); - - /* With the test memory reader -- streaming mode. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, used, 7)); - /* Streaming reader doesn't see mode information from Central Directory. */ - verify_contents(a, 0, 1); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, used, 7)); - /* Streaming reader doesn't see mode information from Central Directory. */ - verify_contents(a, 0, 0); - - /* With the test memory reader -- seeking mode. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7)); - verify_contents(a, 1, 1); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7)); - verify_contents(a, 1, 0); - - free(buff); -} - -/* - * Do a write-then-read roundtrip with Zip64 enabled. - */ -DEFINE_TEST(test_write_format_zip64) -{ - struct archive *a; - size_t used; - size_t buffsize = 1000000; - char *buff; - - buff = malloc(buffsize); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "zip:zip64")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "zip:experimental")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used)); - write_contents(a); - dumpfile("constructed64.zip", buff, used); - - /* - * Now, read the data back. - */ - /* With the standard memory reader. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); - verify_contents(a, 1, 1); - - /* With the test memory reader -- streaming mode. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, used, 7)); - /* Streaming reader doesn't see mode information from Central Directory. */ - verify_contents(a, 0, 1); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, used, 7)); - /* Streaming reader doesn't see mode information from Central Directory. */ - verify_contents(a, 0, 0); - - /* With the test memory reader -- seeking mode. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7)); - verify_contents(a, 1, 1); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7)); - verify_contents(a, 1, 0); - - free(buff); -} - -DEFINE_TEST(test_write_format_zip_traditional_pkware_encryption) -{ - struct archive *a; - size_t used; - size_t buffsize = 1000000; - char *buff; - - buff = malloc(buffsize); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - if (ARCHIVE_OK != archive_write_set_options(a, - "zip:encryption=zipcrypt")) { - skipping("This system does not have cryptographic liberary"); - archive_write_free(a); - free(buff); - return; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_passphrase(a, "password1234")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "zip:experimental")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used)); - write_contents(a); - dumpfile("constructed.zip", buff, used); - - /* - * Now, read the data back. - */ - /* With the standard memory reader. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_add_passphrase(a, "password1234")); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); - verify_contents(a, 1, 1); - - /* With the test memory reader -- streaming mode. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_add_passphrase(a, "password1234")); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, used, 7)); - /* Streaming reader doesn't see mode information from Central Directory. */ - verify_contents(a, 0, 1); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_add_passphrase(a, "password1234")); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, used, 7)); - /* Streaming reader doesn't see mode information from Central Directory. */ - verify_contents(a, 0, 0); - - /* With the test memory reader -- seeking mode. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_add_passphrase(a, "password1234")); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7)); - verify_contents(a, 1, 1); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_add_passphrase(a, "password1234")); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7)); - verify_contents(a, 1, 0); - - free(buff); -} - -DEFINE_TEST(test_write_format_zip_winzip_aes128_encryption) -{ - struct archive *a; - size_t used; - size_t buffsize = 1000000; - char *buff; - - buff = malloc(buffsize); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - if (ARCHIVE_OK != archive_write_set_options(a, "zip:encryption=aes128")) - { - skipping("This system does not have cryptographic liberary"); - archive_write_free(a); - free(buff); - return; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_passphrase(a, "password1234")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "zip:experimental")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used)); - write_contents(a); - dumpfile("constructed.zip", buff, used); - - /* - * Now, read the data back. - */ - /* With the standard memory reader. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_add_passphrase(a, "password1234")); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); - verify_contents(a, 1, 1); - - /* With the test memory reader -- streaming mode. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_add_passphrase(a, "password1234")); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, used, 7)); - /* Streaming reader doesn't see mode information from Central Directory. */ - verify_contents(a, 0, 1); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_add_passphrase(a, "password1234")); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, used, 7)); - /* Streaming reader doesn't see mode information from Central Directory. */ - verify_contents(a, 0, 0); - - /* With the test memory reader -- seeking mode. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_add_passphrase(a, "password1234")); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7)); - verify_contents(a, 1, 1); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_add_passphrase(a, "password1234")); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7)); - verify_contents(a, 1, 0); - - free(buff); -} - -DEFINE_TEST(test_write_format_zip_winzip_aes256_encryption) -{ - struct archive *a; - size_t used; - size_t buffsize = 1000000; - char *buff; - - buff = malloc(buffsize); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - if (ARCHIVE_OK != archive_write_set_options(a, "zip:encryption=aes256")) - { - skipping("This system does not have cryptographic liberary"); - archive_write_free(a); - free(buff); - return; - } - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_passphrase(a, "password1234")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "zip:experimental")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used)); - write_contents(a); - dumpfile("constructed.zip", buff, used); - - /* - * Now, read the data back. - */ - /* With the standard memory reader. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_add_passphrase(a, "password1234")); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); - verify_contents(a, 1, 1); - - /* With the test memory reader -- streaming mode. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_add_passphrase(a, "password1234")); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, used, 7)); - /* Streaming reader doesn't see mode information from Central Directory. */ - verify_contents(a, 0, 1); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_add_passphrase(a, "password1234")); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, used, 7)); - /* Streaming reader doesn't see mode information from Central Directory. */ - verify_contents(a, 0, 0); - - /* With the test memory reader -- seeking mode. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_add_passphrase(a, "password1234")); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7)); - verify_contents(a, 1, 1); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_add_passphrase(a, "password1234")); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7)); - verify_contents(a, 1, 0); - - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_zip_compression_store.c b/thirdparty/libarchive/libarchive/test/test_write_format_zip_compression_store.c deleted file mode 100644 index b52d170cc..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_zip_compression_store.c +++ /dev/null @@ -1,396 +0,0 @@ -/*- - * Copyright (c) 2008 Anselm Strauss - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -/* - * Development supported by Google Summer of Code 2008. - */ - -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_format_zip_no_compression.c 201247 2009-12-30 05:59:21Z kientzle $"); - -/* File data */ -static const char file_name[] = "file"; -static const char file_data1[] = {'1', '2', '3', '4', '5'}; -static const char file_data2[] = {'6', '7', '8', '9', '0'}; -static const int file_perm = 00644; -static const short file_uid = 10; -static const short file_gid = 20; - -/* Folder data */ -static const char folder_name[] = "folder/"; -static const int folder_perm = 00755; -static const short folder_uid = 30; -static const short folder_gid = 40; - -static time_t now; - -static unsigned long -bitcrc32(unsigned long c, const void *_p, size_t s) -{ - /* This is a drop-in replacement for crc32() from zlib. - * Libarchive should be able to correctly generate - * uncompressed zip archives (including correct CRCs) even - * when zlib is unavailable, and this function helps us verify - * that. Yes, this is very, very slow and unsuitable for - * production use, but it's correct, compact, and works well - * enough for this particular usage. Libarchive internally - * uses a much more efficient implementation. */ - const unsigned char *p = _p; - int bitctr; - - if (p == NULL) - return (0); - - for (; s > 0; --s) { - c ^= *p++; - for (bitctr = 8; bitctr > 0; --bitctr) { - if (c & 1) c = (c >> 1); - else c = (c >> 1) ^ 0xedb88320; - c ^= 0x80000000; - } - } - return (c); -} - -static void verify_write_uncompressed(struct archive *a) -{ - struct archive_entry *entry; - - /* Write entries. */ - - /* Regular file */ - assert((entry = archive_entry_new()) != NULL); - archive_entry_set_pathname(entry, file_name); - archive_entry_set_mode(entry, S_IFREG | 0644); - archive_entry_set_size(entry, sizeof(file_data1) + sizeof(file_data2)); - archive_entry_set_uid(entry, file_uid); - archive_entry_set_gid(entry, file_gid); - archive_entry_set_mtime(entry, now, 0); - archive_entry_set_atime(entry, now + 3, 0); - assertEqualIntA(a, 0, archive_write_header(a, entry)); - assertEqualIntA(a, sizeof(file_data1), archive_write_data(a, file_data1, sizeof(file_data1))); - assertEqualIntA(a, sizeof(file_data2), archive_write_data(a, file_data2, sizeof(file_data2))); - archive_entry_free(entry); - - /* Folder */ - assert((entry = archive_entry_new()) != NULL); - archive_entry_set_pathname(entry, folder_name); - archive_entry_set_mode(entry, S_IFDIR | folder_perm); - archive_entry_set_size(entry, 0); - archive_entry_set_uid(entry, folder_uid); - archive_entry_set_gid(entry, folder_gid); - archive_entry_set_mtime(entry, now, 0); - archive_entry_set_ctime(entry, now + 5, 0); - assertEqualIntA(a, 0, archive_write_header(a, entry)); - archive_entry_free(entry); -} - -/* Quick and dirty: Read 2-byte and 4-byte integers from Zip file. */ -static unsigned int -i2(const void *p_) -{ - const unsigned char *p = p_; - return (p[0] | (p[1] << 8)); -} - -static unsigned int -i4(const void *p_) -{ - const unsigned char *p = p_; - return (i2(p) | (i2(p + 2) << 16)); -} - -static void verify_uncompressed_contents(const char *buff, size_t used) -{ - const char *buffend; - - /* Misc variables */ - unsigned long crc; - struct tm *tm; -#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S) - struct tm tmbuf; -#endif - /* p is the pointer to walk over the central directory, - * q walks over the local headers, the data and the data descriptors. */ - const char *p, *q, *local_header, *extra_start; - -#if defined(HAVE_LOCALTIME_S) - tm = localtime_s(&tmbuf, &now) ? NULL : &tmbuf; -#elif defined(HAVE_LOCALTIME_R) - tm = localtime_r(&now, &tmbuf); -#else - tm = localtime(&now); -#endif - - /* Remember the end of the archive in memory. */ - buffend = buff + used; - - /* Verify "End of Central Directory" record. */ - /* Get address of end-of-central-directory record. */ - p = buffend - 22; /* Assumes there is no zip comment field. */ - failure("End-of-central-directory begins with PK\\005\\006 signature"); - assertEqualMem(p, "PK\005\006", 4); - failure("This must be disk 0"); - assertEqualInt(i2(p + 4), 0); - failure("Central dir must start on disk 0"); - assertEqualInt(i2(p + 6), 0); - failure("All central dir entries are on this disk"); - assertEqualInt(i2(p + 8), i2(p + 10)); - failure("CD start (%d) + CD length (%d) should == archive size - 22", - i4(p + 12), i4(p + 16)); - assertEqualInt(i4(p + 12) + i4(p + 16), used - 22); - failure("no zip comment"); - assertEqualInt(i2(p + 20), 0); - - /* Get address of first entry in central directory. */ - p = buff + i4(buffend - 6); - failure("Central file record at offset %d should begin with" - " PK\\001\\002 signature", - i4(buffend - 10)); - - /* Verify file entry in central directory. */ - assertEqualMem(p, "PK\001\002", 4); /* Signature */ - assertEqualInt(i2(p + 4), 3 * 256 + 10); /* Version made by */ - assertEqualInt(i2(p + 6), 10); /* Version needed to extract */ - assertEqualInt(i2(p + 8), 8); /* Flags */ - assertEqualInt(i2(p + 10), 0); /* Compression method */ - assertEqualInt(i2(p + 12), (tm->tm_hour * 2048) + (tm->tm_min * 32) + (tm->tm_sec / 2)); /* File time */ - assertEqualInt(i2(p + 14), ((tm->tm_year - 80) * 512) + ((tm->tm_mon + 1) * 32) + tm->tm_mday); /* File date */ - crc = bitcrc32(0, file_data1, sizeof(file_data1)); - crc = bitcrc32(crc, file_data2, sizeof(file_data2)); - assertEqualInt(i4(p + 16), crc); /* CRC-32 */ - assertEqualInt(i4(p + 20), sizeof(file_data1) + sizeof(file_data2)); /* Compressed size */ - assertEqualInt(i4(p + 24), sizeof(file_data1) + sizeof(file_data2)); /* Uncompressed size */ - assertEqualInt(i2(p + 28), strlen(file_name)); /* Pathname length */ - assertEqualInt(i2(p + 30), 28); /* Extra field length */ - assertEqualInt(i2(p + 32), 0); /* File comment length */ - assertEqualInt(i2(p + 34), 0); /* Disk number start */ - assertEqualInt(i2(p + 36), 0); /* Internal file attrs */ - assertEqualInt(i4(p + 38) >> 16 & 01777, file_perm); /* External file attrs */ - assertEqualInt(i4(p + 42), 0); /* Offset of local header */ - assertEqualMem(p + 46, file_name, strlen(file_name)); /* Pathname */ - p = p + 46 + strlen(file_name); - assertEqualInt(i2(p), 0x5455); /* 'UT' extension header */ - assertEqualInt(i2(p + 2), 9); /* 'UT' size */ - assertEqualInt(p[4], 3); /* 'UT' flags */ - assertEqualInt(i4(p + 5), now); /* 'UT' mtime */ - assertEqualInt(i4(p + 9), now + 3); /* 'UT' atime */ - p = p + 4 + i2(p + 2); - assertEqualInt(i2(p), 0x7875); /* 'ux' extension header */ - assertEqualInt(i2(p + 2), 11); /* 'ux' size */ -/* TODO */ - p = p + 4 + i2(p + 2); - - /* Verify local header of file entry. */ - local_header = q = buff; - assertEqualMem(q, "PK\003\004", 4); /* Signature */ - assertEqualInt(i2(q + 4), 10); /* Version needed to extract */ - assertEqualInt(i2(q + 6), 8); /* Flags */ - assertEqualInt(i2(q + 8), 0); /* Compression method */ - assertEqualInt(i2(q + 10), (tm->tm_hour * 2048) + (tm->tm_min * 32) + (tm->tm_sec / 2)); /* File time */ - assertEqualInt(i2(q + 12), ((tm->tm_year - 80) * 512) + ((tm->tm_mon + 1) * 32) + tm->tm_mday); /* File date */ - assertEqualInt(i4(q + 14), 0); /* CRC-32 */ - assertEqualInt(i4(q + 18), sizeof(file_data1) + sizeof(file_data2)); /* Compressed size */ - assertEqualInt(i4(q + 22), sizeof(file_data1) + sizeof(file_data2)); /* Uncompressed size */ - assertEqualInt(i2(q + 26), strlen(file_name)); /* Pathname length */ - assertEqualInt(i2(q + 28), 41); /* Extra field length */ - assertEqualMem(q + 30, file_name, strlen(file_name)); /* Pathname */ - extra_start = q = q + 30 + strlen(file_name); - assertEqualInt(i2(q), 0x5455); /* 'UT' extension header */ - assertEqualInt(i2(q + 2), 9); /* 'UT' size */ - assertEqualInt(q[4], 3); /* 'UT' flags */ - assertEqualInt(i4(q + 5), now); /* 'UT' mtime */ - assertEqualInt(i4(q + 9), now + 3); /* 'UT' atime */ - q = q + 4 + i2(q + 2); - - assertEqualInt(i2(q), 0x7875); /* 'ux' extension header */ - assertEqualInt(i2(q + 2), 11); /* 'ux' size */ - assertEqualInt(q[4], 1); /* 'ux' version */ - assertEqualInt(q[5], 4); /* 'ux' uid size */ - assertEqualInt(i4(q + 6), file_uid); /* 'Ux' UID */ - assertEqualInt(q[10], 4); /* 'ux' gid size */ - assertEqualInt(i4(q + 11), file_gid); /* 'Ux' GID */ - q = q + 4 + i2(q + 2); - - assertEqualInt(i2(q), 0x6c78); /* 'xl' experimental extension header */ - assertEqualInt(i2(q + 2), 9); /* size */ - assertEqualInt(q[4], 7); /* Bitmap of fields included. */ - assertEqualInt(i2(q + 5) >> 8, 3); /* system & version made by */ - assertEqualInt(i2(q + 7), 0); /* internal file attributes */ - assertEqualInt(i4(q + 9) >> 16 & 01777, file_perm); /* external file attributes */ - q = q + 4 + i2(q + 2); - - assert(q == extra_start + i2(local_header + 28)); - q = extra_start + i2(local_header + 28); - - /* Verify data of file entry. */ - assertEqualMem(q, file_data1, sizeof(file_data1)); - assertEqualMem(q + sizeof(file_data1), file_data2, sizeof(file_data2)); - q = q + sizeof(file_data1) + sizeof(file_data2); - - /* Verify data descriptor of file entry. */ - assertEqualMem(q, "PK\007\010", 4); /* Signature */ - assertEqualInt(i4(q + 4), crc); /* CRC-32 */ - assertEqualInt(i4(q + 8), sizeof(file_data1) + sizeof(file_data2)); /* Compressed size */ - assertEqualInt(i4(q + 12), sizeof(file_data1) + sizeof(file_data2)); /* Uncompressed size */ - q = q + 16; - - /* Verify folder entry in central directory. */ - assertEqualMem(p, "PK\001\002", 4); /* Signature */ - assertEqualInt(i2(p + 4), 3 * 256 + 20); /* Version made by */ - assertEqualInt(i2(p + 6), 20); /* Version needed to extract */ - assertEqualInt(i2(p + 8), 0); /* Flags */ - assertEqualInt(i2(p + 10), 0); /* Compression method */ - assertEqualInt(i2(p + 12), (tm->tm_hour * 2048) + (tm->tm_min * 32) + (tm->tm_sec / 2)); /* File time */ - assertEqualInt(i2(p + 14), ((tm->tm_year - 80) * 512) + ((tm->tm_mon + 1) * 32) + tm->tm_mday); /* File date */ - crc = 0; - assertEqualInt(i4(p + 16), crc); /* CRC-32 */ - assertEqualInt(i4(p + 20), 0); /* Compressed size */ - assertEqualInt(i4(p + 24), 0); /* Uncompressed size */ - assertEqualInt(i2(p + 28), strlen(folder_name)); /* Pathname length */ - assertEqualInt(i2(p + 30), 28); /* Extra field length */ - assertEqualInt(i2(p + 32), 0); /* File comment length */ - assertEqualInt(i2(p + 34), 0); /* Disk number start */ - assertEqualInt(i2(p + 36), 0); /* Internal file attrs */ - assertEqualInt(i4(p + 38) >> 16 & 01777, folder_perm); /* External file attrs */ - assertEqualInt(i4(p + 42), q - buff); /* Offset of local header */ - assertEqualMem(p + 46, folder_name, strlen(folder_name)); /* Pathname */ - p = p + 46 + strlen(folder_name); - assertEqualInt(i2(p), 0x5455); /* 'UT' extension header */ - assertEqualInt(i2(p + 2), 9); /* 'UT' size */ - assertEqualInt(p[4], 5); /* 'UT' flags */ - assertEqualInt(i4(p + 5), now); /* 'UT' mtime */ - assertEqualInt(i4(p + 9), now + 5); /* 'UT' atime */ - p = p + 4 + i2(p + 2); - assertEqualInt(i2(p), 0x7875); /* 'ux' extension header */ - assertEqualInt(i2(p + 2), 11); /* 'ux' size */ - assertEqualInt(p[4], 1); /* 'ux' version */ - assertEqualInt(p[5], 4); /* 'ux' uid size */ - assertEqualInt(i4(p + 6), folder_uid); /* 'ux' UID */ - assertEqualInt(p[10], 4); /* 'ux' gid size */ - assertEqualInt(i4(p + 11), folder_gid); /* 'ux' GID */ - /*p = p + 4 + i2(p + 2);*/ - - /* Verify local header of folder entry. */ - local_header = q; - assertEqualMem(q, "PK\003\004", 4); /* Signature */ - assertEqualInt(i2(q + 4), 20); /* Version needed to extract */ - assertEqualInt(i2(q + 6), 0); /* Flags */ - assertEqualInt(i2(q + 8), 0); /* Compression method */ - assertEqualInt(i2(q + 10), (tm->tm_hour * 2048) + (tm->tm_min * 32) + (tm->tm_sec / 2)); /* File time */ - assertEqualInt(i2(q + 12), ((tm->tm_year - 80) * 512) + ((tm->tm_mon + 1) * 32) + tm->tm_mday); /* File date */ - assertEqualInt(i4(q + 14), 0); /* CRC-32 */ - assertEqualInt(i4(q + 18), 0); /* Compressed size */ - assertEqualInt(i4(q + 22), 0); /* Uncompressed size */ - assertEqualInt(i2(q + 26), strlen(folder_name)); /* Pathname length */ - assertEqualInt(i2(q + 28), 41); /* Extra field length */ - assertEqualMem(q + 30, folder_name, strlen(folder_name)); /* Pathname */ - extra_start = q = q + 30 + strlen(folder_name); - assertEqualInt(i2(q), 0x5455); /* 'UT' extension header */ - assertEqualInt(i2(q + 2), 9); /* 'UT' size */ - assertEqualInt(q[4], 5); /* 'UT' flags */ - assertEqualInt(i4(q + 5), now); /* 'UT' mtime */ - assertEqualInt(i4(q + 9), now + 5); /* 'UT' atime */ - q = q + 4 + i2(q + 2); - assertEqualInt(i2(q), 0x7875); /* 'ux' extension header */ - assertEqualInt(i2(q + 2), 11); /* 'ux' size */ - assertEqualInt(q[4], 1); /* 'ux' version */ - assertEqualInt(q[5], 4); /* 'ux' uid size */ - assertEqualInt(i4(q + 6), folder_uid); /* 'ux' UID */ - assertEqualInt(q[10], 4); /* 'ux' gid size */ - assertEqualInt(i4(q + 11), folder_gid); /* 'ux' GID */ - q = q + 4 + i2(q + 2); - - assertEqualInt(i2(q), 0x6c78); /* 'xl' experimental extension header */ - assertEqualInt(i2(q + 2), 9); /* size */ - assertEqualInt(q[4], 7); /* bitmap of fields */ - assertEqualInt(i2(q + 5) >> 8, 3); /* system & version made by */ - assertEqualInt(i2(q + 7), 0); /* internal file attributes */ - assertEqualInt(i4(q + 9) >> 16 & 01777, folder_perm); /* external file attributes */ - q = q + 4 + i2(q + 2); - - assert(q == extra_start + i2(local_header + 28)); - q = extra_start + i2(local_header + 28); - - /* There should not be any data in the folder entry, - * so the first central directory entry should be next: */ - assertEqualMem(q, "PK\001\002", 4); /* Signature */ -} - -DEFINE_TEST(test_write_format_zip_compression_store) -{ - /* Buffer data */ - struct archive *a; - char buff[100000]; - size_t used; - - /* Time data */ - now = time(NULL); - - /* Create new ZIP archive in memory without padding. */ - /* Use compression=store to disable compression. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "zip:compression=store")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "zip:experimental")); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_bytes_per_block(a, 1)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_bytes_in_last_block(a, 1)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff), &used)); - - verify_write_uncompressed(a); - - /* Close the archive . */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - dumpfile("constructed.zip", buff, used); - - verify_uncompressed_contents(buff, used); - - /* Create new ZIP archive in memory without padding. */ - /* Use compression-level=0 to disable compression. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "zip:compression-level=0")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "zip:experimental")); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_bytes_per_block(a, 1)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_bytes_in_last_block(a, 1)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff), &used)); - - verify_write_uncompressed(a); - - /* Close the archive . */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - dumpfile("constructed.zip", buff, used); - - verify_uncompressed_contents(buff, used); - -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_zip_empty.c b/thirdparty/libarchive/libarchive/test/test_write_format_zip_empty.c deleted file mode 100644 index 73a557312..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_zip_empty.c +++ /dev/null @@ -1,78 +0,0 @@ -/*- - * Copyright (c) 2008 Anselm Strauss - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -/* - * Development supported by Google Summer of Code 2008. - */ - -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_format_zip_empty.c 201247 2009-12-30 05:59:21Z kientzle $"); - -DEFINE_TEST(test_write_format_zip_empty) -{ - struct archive *a; - struct archive_entry *ae; - char buff[256]; - size_t used; - - /* Zip format: Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_bytes_per_block(a, 1)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_bytes_in_last_block(a, 1)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff), &used)); - - /* Close out the archive without writing anything. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Verify the correct format for an empty Zip archive. */ - assertEqualInt(used, 22); - assertEqualMem(buff, - "PK\005\006\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", - 22); - - /* Verify that we read this kind of empty archive correctly. */ - /* Try with the standard memory reader, and with the test - memory reader with and without seek support. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, 22)); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, 22, 1)); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, 22, 22)); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_zip_empty_zip64.c b/thirdparty/libarchive/libarchive/test/test_write_format_zip_empty_zip64.c deleted file mode 100644 index 8f9975b21..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_zip_empty_zip64.c +++ /dev/null @@ -1,103 +0,0 @@ -/*- - * Copyright (c) 2008 Anselm Strauss - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -/* - * Development supported by Google Summer of Code 2008. - */ - -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_format_zip_empty.c 201247 2009-12-30 05:59:21Z kientzle $"); - -DEFINE_TEST(test_write_format_zip_empty_zip64) -{ - struct archive *a; - struct archive_entry *ae; - char buff[256]; - size_t used; - - /* Zip format: Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_bytes_per_block(a, 1)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_bytes_in_last_block(a, 1)); - /* Force zip writer to use Zip64 extensions. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_option(a, "zip", "zip64", "1")); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff), &used)); - - /* Close out the archive without writing anything. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* Verify the correct format for an empty Zip archive with Zip64 extensions forced. */ - assertEqualInt(used, 98); - assertEqualMem(buff, - "PK\006\006" /* Zip64 end-of-central-directory record */ - "\x2c\0\0\0\0\0\0\0" /* 44 bytes long */ - "\x2d\0" /* Created by Zip 4.5 */ - "\x2d\0" /* Extract with Zip 4.5 or later */ - "\0\0\0\0" /* This is disk #0 */ - "\0\0\0\0" /* Central dir starts on disk #0 */ - "\0\0\0\0\0\0\0\0" /* There are 0 entries on this disk ... */ - "\0\0\0\0\0\0\0\0" /* ... out of 0 entries total ... */ - "\0\0\0\0\0\0\0\0" /* ... requiring a total of 0 bytes. */ - "\0\0\0\0\0\0\0\0" /* Directory starts at offset 0 */ - - "PK\006\007" /* Zip64 end-of-central-directory locator */ - "\0\0\0\0" /* Zip64 EOCD record is on disk #0 .. */ - "\0\0\0\0\0\0\0\0" /* .. at offset 0 .. */ - "\1\0\0\0" /* .. of 1 total disks. */ - - "PK\005\006" /* Regular Zip end-of-central-directory record */ - "\0\0" /* This is disk #0 */ - "\0\0" /* Central dir is on disk #0 */ - "\0\0" /* There are 0 entries on this disk ... */ - "\0\0" /* ... out of 0 total entries ... */ - "\0\0\0\0" /* ... requiring a total of 0 bytes. */ - "\0\0\0\0" /* Directory starts at offset 0. */ - "\0\0" /* File comment is zero bytes long. */, - 98); - - /* Verify that we read this kind of empty archive correctly. */ - /* Try with the standard memory reader, and with the test - memory reader with and without seek support. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, 98)); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, 98, 1)); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, 98, 98)); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_zip_entry_size_unset.c b/thirdparty/libarchive/libarchive/test/test_write_format_zip_entry_size_unset.c deleted file mode 100644 index 13b5f1b2d..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_zip_entry_size_unset.c +++ /dev/null @@ -1,321 +0,0 @@ -/*- - * Copyright (c) 2021 Jia Cheong Tan - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* File data */ -static const char file_name[] = "file"; -static const char file_data1[] = {'a', 'b', 'c', 'd', 'e'}; -static const char file_data2[] = {'f', 'g', 'h', 'i', 'j'}; -static const int file_perm = 00644; -static const short file_uid = 10; -static const short file_gid = 20; - -/* Folder data */ -static const char folder_name[] = "folder/"; -static const int folder_perm = 00755; -static const short folder_uid = 30; -static const short folder_gid = 40; - -#define ZIP_ENTRY_FLAG_LENGTH_AT_END (1 << 3) - -/* Quick and dirty: Read 2-byte and 4-byte integers from Zip file. */ -static unsigned i2(const char *p) { return ((p[0] & 0xff) | ((p[1] & 0xff) << 8)); } -static unsigned i4(const char *p) { return (i2(p) | (i2(p + 2) << 16)); } - -static unsigned long -bitcrc32(unsigned long c, const void *_p, size_t s) -{ - /* This is a drop-in replacement for crc32() from zlib. - * Libarchive should be able to correctly generate - * uncompressed zip archives (including correct CRCs) even - * when zlib is unavailable, and this function helps us verify - * that. Yes, this is very, very slow and unsuitable for - * production use, but it's correct, compact, and works well - * enough for this particular usage. Libarchive internally - * uses a much more efficient implementation. */ - const unsigned char *p = _p; - int bitctr; - - if (p == NULL) - return (0); - - for (; s > 0; --s) - { - c ^= *p++; - for (bitctr = 8; bitctr > 0; --bitctr) - { - if (c & 1) - c = (c >> 1); - else - c = (c >> 1) ^ 0xedb88320; - c ^= 0x80000000; - } - } - return (c); -} - -static void write_archive(struct archive *a) -{ - struct archive_entry *entry = archive_entry_new(); - assert(entry != NULL); - - /* Does not set size for file entry */ - archive_entry_set_pathname(entry, file_name); - archive_entry_set_mode(entry, S_IFREG | 0644); - archive_entry_set_uid(entry, file_uid); - archive_entry_set_gid(entry, file_gid); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); - assertEqualIntA(a, sizeof(file_data1), archive_write_data(a, file_data1, sizeof(file_data1))); - assertEqualIntA(a, sizeof(file_data2), archive_write_data(a, file_data2, sizeof(file_data2))); - archive_entry_free(entry); - - /* Folder */ - assert((entry = archive_entry_new()) != NULL); - archive_entry_set_pathname(entry, folder_name); - archive_entry_set_mode(entry, S_IFDIR | folder_perm); - archive_entry_set_size(entry, 0); - archive_entry_set_uid(entry, folder_uid); - archive_entry_set_gid(entry, folder_gid); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); -} - -static void verify_contents(const char *zip_buff, size_t size) -{ - unsigned long crc = bitcrc32(0, file_data1, sizeof(file_data1)); - crc = bitcrc32(crc, file_data2, sizeof(file_data2)); - - const char *zip_end = zip_buff + size; - /* Since there are no comments, the end of central directory - * is 22 bytes from the end of content */ - const char *end_of_central_dir = zip_end - 22; - /* Check for end of central directory signature */ - assertEqualMem(end_of_central_dir, "PK\x5\x6", 4); - /* Check for number of disk */ - assertEqualInt(i2(end_of_central_dir + 4), 0); - /* Check for disk where central directory starts */ - assertEqualInt(i2(end_of_central_dir + 6), 0); - /* Check for number of central directory records on disk */ - assertEqualInt(i2(end_of_central_dir + 8), 2); - /* Check for total number of central directory records */ - assertEqualInt(i2(end_of_central_dir + 10), 2); - /* Check for size of central directory and offset - * The size + offset must equal the end of the central directory */ - assertEqualInt(i4(end_of_central_dir + 12) + i4(end_of_central_dir + 16), end_of_central_dir - zip_buff); - /* Check for empty comment length */ - assertEqualInt(i2(end_of_central_dir + 20), 0); - - /* Get address of central directory */ - const char *central_directory = zip_buff + i4(end_of_central_dir + 16); - - /* Check for entry in central directory signature */ - assertEqualMem(central_directory, "PK\x1\x2", 4); - /* Check for version used to write entry */ - assertEqualInt(i2(central_directory + 4), 3 * 256 + 10); - /* Check for version needed to extract entry */ - assertEqualInt(i2(central_directory + 6), 10); - /* Check flags */ - assertEqualInt(i2(central_directory + 8), ZIP_ENTRY_FLAG_LENGTH_AT_END); - /* Check compression method */ - assertEqualInt(i2(central_directory + 10), 0); - /* Check crc value */ - assertEqualInt(i4(central_directory + 16), crc); - /* Check compressed size*/ - assertEqualInt(i4(central_directory + 20), sizeof(file_data1) + sizeof(file_data2)); - /* Check uncompressed size */ - assertEqualInt(i4(central_directory + 24), sizeof(file_data1) + sizeof(file_data2)); - /* Check file name length */ - assertEqualInt(i2(central_directory + 28), strlen(file_name)); - /* Check extra field length */ - assertEqualInt(i2(central_directory + 30), 20); - /* Check file comment length */ - assertEqualInt(i2(central_directory + 32), 0); - /* Check disk number where file starts */ - assertEqualInt(i2(central_directory + 34), 0); - /* Check internal file attrs */ - assertEqualInt(i2(central_directory + 36), 0); - /* Check external file attrs */ - assertEqualInt(i4(central_directory + 38) >> 16 & 01777, file_perm); - /* Check offset of local header */ - assertEqualInt(i4(central_directory + 42), 0); - /* Check for file name contents */ - assertEqualMem(central_directory + 46, file_name, strlen(file_name)); - - /* Get address of local file entry */ - const char *local_file_header = zip_buff; - - /* Check local file header signature */ - assertEqualMem(local_file_header, "PK\x3\x4", 4); - /* Check version needed to extract */ - assertEqualInt(i2(local_file_header + 4), 10); - /* Check flags */ - assertEqualInt(i2(local_file_header + 6), 8); - /* Check compression method */ - assertEqualInt(i2(local_file_header + 8), 0); - /* Check crc */ - assertEqualInt(i4(local_file_header + 14), 0); - /* Check compressed size - * 0 because it was unknown at time of writing */ - assertEqualInt(i4(local_file_header + 18), 0); - /* Check uncompressed size - * 0 because it was unknown at time of writing */ - assertEqualInt(i4(local_file_header + 22), 0); - /* Check pathname length */ - assertEqualInt(i2(local_file_header + 26), strlen(file_name)); - /* Check extra field length */ - assertEqualInt(i2(local_file_header + 28), 20); - /* Check path name match */ - assertEqualMem(local_file_header + 30, file_name, strlen(file_name)); - - /* Start of data */ - const char *data = local_file_header + i2(local_file_header + 28) + strlen(file_name) + 30; - /* Check for file data match */ - assertEqualMem(data, file_data1, sizeof(file_data1)); - assertEqualMem(data + sizeof(file_data1), file_data2, sizeof(file_data2)); - - /* Start of data descriptor */ - const char *data_descriptor = data + sizeof(file_data1) + sizeof(file_data2); - /* Check data descriptor signature */ - assertEqualMem(data_descriptor, "PK\x7\x8", 4); - /* Check crc value */ - assertEqualInt(i4(data_descriptor + 4), crc); - /* Check compressed size */ - assertEqualInt(i4(data_descriptor + 8), sizeof(file_data1) + sizeof(file_data2)); - /* Chcek uncompresed size */ - assertEqualInt(i4(data_descriptor + 12), sizeof(file_data1) + sizeof(file_data2)); - - /* Get folder entry in central directory */ - const char *central_directory_folder_entry = central_directory + 46 + 20 + strlen(file_name); - - /* Get start of folder entry */ - const char *local_folder_header = data_descriptor + 16; - - /* Check for entry in central directory signature */ - assertEqualMem(central_directory_folder_entry, "PK\x1\x2", 4); - /* Check version made by */ - assertEqualInt(i2(central_directory_folder_entry + 4), 3 * 256 + 20); - /* Check version needed to extract */ - assertEqualInt(i2(central_directory_folder_entry + 6), 20); - /* Check flags */ - assertEqualInt(i2(central_directory_folder_entry + 8), 0); - /* Check compression method */ - assertEqualInt(i2(central_directory_folder_entry + 10), 0); - /* Check crc */ - assertEqualInt(i2(central_directory_folder_entry + 16), 0); - /* Check compressed size */ - assertEqualInt(i4(central_directory_folder_entry + 20), 0); - /* Check uncompressed size */ - assertEqualInt(i4(central_directory_folder_entry + 24), 0); - /* Check path name length */ - assertEqualInt(i2(central_directory_folder_entry + 28), strlen(folder_name)); - /* Check extra field length */ - assertEqualInt(i2(central_directory_folder_entry + 30), 20); - /* Check file comment length */ - assertEqualInt(i2(central_directory_folder_entry + 32), 0); - /* Check disk number start */ - assertEqualInt(i2(central_directory_folder_entry + 34), 0); - /* Check internal file attrs */ - assertEqualInt(i2(central_directory_folder_entry + 36), 0); - /* Check external file attrs */ - assertEqualInt(i4(central_directory_folder_entry + 38) >> 16 & 01777, folder_perm); - /* Check offset of local header*/ - assertEqualInt(i4(central_directory_folder_entry + 42), local_folder_header - zip_buff); - /* Check path name */ - assertEqualMem(central_directory_folder_entry + 46, folder_name, strlen(folder_name)); - - /* Check local header */ - assertEqualMem(local_folder_header, "PK\x3\x4", 4); - /* Check version to extract */ - assertEqualInt(i2(local_folder_header + 4), 20); - /* Check flags */ - assertEqualInt(i2(local_folder_header + 6), 0); - /* Check compression method */ - assertEqualInt(i2(local_folder_header + 8), 0); - /* Check crc */ - assertEqualInt(i4(local_folder_header + 14), 0); - /* Check compressed size */ - assertEqualInt(i2(local_folder_header + 18), 0); - /* Check uncompressed size */ - assertEqualInt(i4(local_folder_header + 22), 0); - /* Check path name length */ - assertEqualInt(i2(local_folder_header + 26), strlen(folder_name)); - /* Check extra field length */ - assertEqualInt(i2(local_folder_header + 28), 20); - /* Check path name */ - assertEqualMem(local_folder_header + 30, folder_name, strlen(folder_name)); - - const char *post_local_folder = local_folder_header + 30 + strlen(folder_name) + 20; - assertEqualMem(post_local_folder, central_directory, 4); -} - -DEFINE_TEST(test_write_format_zip_size_unset) -{ - struct archive *a; - char zip_buffer[100000]; - size_t size; - - /* Use compression=store to disable compression. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "zip:compression=store")); - /* Disable zip64 explicitly since it is automatically enabled if no size is set */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "zip:zip64=")); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_bytes_per_block(a, 1)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_bytes_in_last_block(a, 1)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, zip_buffer, sizeof(zip_buffer), &size)); - - write_archive(a); - - /* Close the archive . */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - dumpfile("constructed_size_unset.zip", zip_buffer, size); - - verify_contents(zip_buffer, size); - - /* Use compression-level=0 to disable compression. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "zip:compression-level=0")); - /* Disable zip64 explicitly since it is automatically enabled if no size is set */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "zip:zip64=")); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_bytes_per_block(a, 1)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_bytes_in_last_block(a, 1)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, zip_buffer, sizeof(zip_buffer), &size)); - - write_archive(a); - - /* Close the archive . */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - dumpfile("constructed_size_unset.zip", zip_buffer, size); - - verify_contents(zip_buffer, size); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_zip_file.c b/thirdparty/libarchive/libarchive/test/test_write_format_zip_file.c deleted file mode 100644 index 4ccc30360..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_zip_file.c +++ /dev/null @@ -1,261 +0,0 @@ -/*- - * Copyright (c) 2003-2008 Tim Kientzle - * Copyright (c) 2008 Anselm Strauss - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -/* - * Development supported by Google Summer of Code 2008. - */ - -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_format_zip.c 201247 2009-12-30 05:59:21Z kientzle $"); - -/* - * Detailed byte-for-byte verification of the format of a zip archive - * with a single file written to it. - */ - -static unsigned long -bitcrc32(unsigned long c, void *_p, size_t s) -{ - /* This is a drop-in replacement for crc32() from zlib. - * Libarchive should be able to correctly generate - * uncompressed zip archives (including correct CRCs) even - * when zlib is unavailable, and this function helps us verify - * that. Yes, this is very, very slow and unsuitable for - * production use, but it's correct, compact, and works well - * enough for this particular usage. Libarchive internally - * uses a much more efficient implementation. */ - const unsigned char *p = _p; - int bitctr; - - if (p == NULL) - return (0); - - for (; s > 0; --s) { - c ^= *p++; - for (bitctr = 8; bitctr > 0; --bitctr) { - if (c & 1) c = (c >> 1); - else c = (c >> 1) ^ 0xedb88320; - c ^= 0x80000000; - } - } - return (c); -} - -/* Quick and dirty: Read 2-byte and 4-byte integers from Zip file. */ -static unsigned i2(const unsigned char *p) { return ((p[0] & 0xff) | ((p[1] & 0xff) << 8)); } -static unsigned i4(const unsigned char *p) { return (i2(p) | (i2(p + 2) << 16)); } - -DEFINE_TEST(test_write_format_zip_file) -{ - struct archive *a; - struct archive_entry *ae; - time_t t = 1234567890; - struct tm *tm; -#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S) - struct tm tmbuf; -#endif - size_t used, buffsize = 1000000; - unsigned long crc; - int file_perm = 00644; - int zip_version = 20; - int zip_compression = 8; - short file_uid = 10, file_gid = 20; - unsigned char *buff, *buffend, *p; - unsigned char *central_header, *local_header, *eocd, *eocd_record; - unsigned char *extension_start, *extension_end; - char file_data[] = {'1', '2', '3', '4', '5', '6', '7', '8'}; - const char *file_name = "file"; - -#ifndef HAVE_ZLIB_H - zip_version = 10; - zip_compression = 0; -#endif - -#if defined(HAVE_LOCALTIME_S) - tm = localtime_s(&tmbuf, &t) ? NULL : &tmbuf; -#elif defined(HAVE_LOCALTIME_R) - tm = localtime_r(&t, &tmbuf); -#else - tm = localtime(&t); -#endif - buff = malloc(buffsize); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "zip:experimental")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used)); - - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, file_name); - archive_entry_set_mode(ae, AE_IFREG | file_perm); - archive_entry_set_size(ae, sizeof(file_data)); - archive_entry_set_uid(ae, file_uid); - archive_entry_set_gid(ae, file_gid); - archive_entry_set_mtime(ae, t, 0); - assertEqualInt(0, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualInt(8, archive_write_data(a, file_data, sizeof(file_data))); - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - buffend = buff + used; - dumpfile("constructed.zip", buff, used); - - /* Verify "End of Central Directory" record. */ - /* Get address of end-of-central-directory record. */ - eocd_record = p = buffend - 22; /* Assumes there is no zip comment field. */ - failure("End-of-central-directory begins with PK\\005\\006 signature"); - assertEqualMem(p, "PK\005\006", 4); - failure("This must be disk 0"); - assertEqualInt(i2(p + 4), 0); - failure("Central dir must start on disk 0"); - assertEqualInt(i2(p + 6), 0); - failure("All central dir entries are on this disk"); - assertEqualInt(i2(p + 8), i2(p + 10)); - eocd = buff + i4(p + 12) + i4(p + 16); - failure("no zip comment"); - assertEqualInt(i2(p + 20), 0); - - /* Get address of first entry in central directory. */ - central_header = p = buff + i4(buffend - 6); - failure("Central file record at offset %d should begin with" - " PK\\001\\002 signature", - i4(buffend - 10)); - - /* Verify file entry in central directory. */ - assertEqualMem(p, "PK\001\002", 4); /* Signature */ - assertEqualInt(i2(p + 4), 3 * 256 + zip_version); /* Version made by */ - assertEqualInt(i2(p + 6), zip_version); /* Version needed to extract */ - assertEqualInt(i2(p + 8), 8); /* Flags */ - assertEqualInt(i2(p + 10), zip_compression); /* Compression method */ - assertEqualInt(i2(p + 12), (tm->tm_hour * 2048) + (tm->tm_min * 32) + (tm->tm_sec / 2)); /* File time */ - assertEqualInt(i2(p + 14), ((tm->tm_year - 80) * 512) + ((tm->tm_mon + 1) * 32) + tm->tm_mday); /* File date */ - crc = bitcrc32(0, file_data, sizeof(file_data)); - assertEqualInt(i4(p + 16), crc); /* CRC-32 */ - /* assertEqualInt(i4(p + 20), sizeof(file_data)); */ /* Compressed size */ - assertEqualInt(i4(p + 24), sizeof(file_data)); /* Uncompressed size */ - assertEqualInt(i2(p + 28), strlen(file_name)); /* Pathname length */ - /* assertEqualInt(i2(p + 30), 28); */ /* Extra field length: See below */ - assertEqualInt(i2(p + 32), 0); /* File comment length */ - assertEqualInt(i2(p + 34), 0); /* Disk number start */ - assertEqualInt(i2(p + 36), 0); /* Internal file attrs */ - assertEqualInt(i4(p + 38) >> 16 & 01777, file_perm); /* External file attrs */ - assertEqualInt(i4(p + 42), 0); /* Offset of local header */ - assertEqualMem(p + 46, file_name, strlen(file_name)); /* Pathname */ - p = extension_start = central_header + 46 + strlen(file_name); - extension_end = extension_start + i2(central_header + 30); - - assertEqualInt(i2(p), 0x5455); /* 'UT' extension header */ - assertEqualInt(i2(p + 2), 5); /* 'UT' size */ - assertEqualInt(p[4], 1); /* 'UT' flags */ - assertEqualInt(i4(p + 5), t); /* 'UT' mtime */ - p += 4 + i2(p + 2); - - assertEqualInt(i2(p), 0x7875); /* 'ux' extension header */ - assertEqualInt(i2(p + 2), 11); /* 'ux' size */ - /* TODO: verify 'ux' contents */ - p += 4 + i2(p + 2); - - /* Just in case: Report any extra extensions. */ - while (p < extension_end) { - failure("Unexpected extension 0x%04X", i2(p)); - assert(0); - p += 4 + i2(p + 2); - } - - /* Should have run exactly to end of extra data. */ - assert(p == extension_end); - - assert(p == eocd); - - /* Regular EOCD immediately follows central directory. */ - assert(p == eocd_record); - - /* Verify local header of file entry. */ - p = local_header = buff; - assertEqualMem(p, "PK\003\004", 4); /* Signature */ - assertEqualInt(i2(p + 4), zip_version); /* Version needed to extract */ - assertEqualInt(i2(p + 6), 8); /* Flags */ - assertEqualInt(i2(p + 8), zip_compression); /* Compression method */ - assertEqualInt(i2(p + 10), (tm->tm_hour * 2048) + (tm->tm_min * 32) + (tm->tm_sec / 2)); /* File time */ - assertEqualInt(i2(p + 12), ((tm->tm_year - 80) * 512) + ((tm->tm_mon + 1) * 32) + tm->tm_mday); /* File date */ - assertEqualInt(i4(p + 14), 0); /* CRC-32 */ - /* assertEqualInt(i4(p + 18), sizeof(file_data)); */ /* Compressed size */ - /* assertEqualInt(i4(p + 22), sizeof(file_data)); */ /* Uncompressed size not stored because we're using length-at-end. */ - assertEqualInt(i2(p + 26), strlen(file_name)); /* Pathname length */ - assertEqualInt(i2(p + 28), 37); /* Extra field length */ - assertEqualMem(p + 30, file_name, strlen(file_name)); /* Pathname */ - p = extension_start = local_header + 30 + strlen(file_name); - extension_end = extension_start + i2(local_header + 28); - - assertEqualInt(i2(p), 0x5455); /* 'UT' extension header */ - assertEqualInt(i2(p + 2), 5); /* size */ - assertEqualInt(p[4], 1); /* 'UT' flags */ - assertEqualInt(i4(p + 5), t); /* 'UT' mtime */ - p += 4 + i2(p + 2); - - assertEqualInt(i2(p), 0x7875); /* 'ux' extension header */ - assertEqualInt(i2(p + 2), 11); /* size */ - assertEqualInt(p[4], 1); /* 'ux' version */ - assertEqualInt(p[5], 4); /* 'ux' uid size */ - assertEqualInt(i4(p + 6), file_uid); /* 'Ux' UID */ - assertEqualInt(p[10], 4); /* 'ux' gid size */ - assertEqualInt(i4(p + 11), file_gid); /* 'Ux' GID */ - p += 4 + i2(p + 2); - - assertEqualInt(i2(p), 0x6c78); /* 'xl' experimental extension block */ - assertEqualInt(i2(p + 2), 9); /* size */ - assertEqualInt(p[4], 7); /* bitmap of fields in this block */ - assertEqualInt(i2(p + 5) >> 8, 3); /* System & version made by */ - assertEqualInt(i2(p + 7), 0); /* internal file attributes */ - assertEqualInt(i4(p + 9) >> 16 & 01777, file_perm); /* external file attributes */ - p += 4 + i2(p + 2); - - /* Just in case: Report any extra extensions. */ - while (p < extension_end) { - failure("Unexpected extension 0x%04X", i2(p)); - assert(0); - p += 4 + i2(p + 2); - } - - /* Should have run exactly to end of extra data. */ - assert(p == extension_end); - - /* Data descriptor should follow compressed data. */ - while (p < central_header && memcmp(p, "PK\007\010", 4) != 0) - ++p; - assertEqualMem(p, "PK\007\010", 4); - assertEqualInt(i4(p + 4), crc); /* CRC-32 */ - /* assertEqualInt(i4(p + 8), ???); */ /* compressed size */ - assertEqualInt(i4(p + 12), sizeof(file_data)); /* uncompressed size */ - - /* Central directory should immediately follow the only entry. */ - assert(p + 16 == central_header); - - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_zip_file_zip64.c b/thirdparty/libarchive/libarchive/test/test_write_format_zip_file_zip64.c deleted file mode 100644 index 6a00fe14c..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_zip_file_zip64.c +++ /dev/null @@ -1,295 +0,0 @@ -/*- - * Copyright (c) 2003-2008 Tim Kientzle - * Copyright (c) 2008 Anselm Strauss - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -/* - * Development supported by Google Summer of Code 2008. - */ - -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_format_zip.c 201247 2009-12-30 05:59:21Z kientzle $"); - -/* - * Detailed byte-for-byte verification of the format of a zip archive - * with a single file written to it that uses Zip64 extensions. - */ - -static unsigned long -bitcrc32(unsigned long c, void *_p, size_t s) -{ - /* This is a drop-in replacement for crc32() from zlib. - * Libarchive should be able to correctly generate - * uncompressed zip archives (including correct CRCs) even - * when zlib is unavailable, and this function helps us verify - * that. Yes, this is very, very slow and unsuitable for - * production use, but it's correct, compact, and works well - * enough for this particular usage. Libarchive internally - * uses a much more efficient implementation. */ - const unsigned char *p = _p; - int bitctr; - - if (p == NULL) - return (0); - - for (; s > 0; --s) { - c ^= *p++; - for (bitctr = 8; bitctr > 0; --bitctr) { - if (c & 1) c = (c >> 1); - else c = (c >> 1) ^ 0xedb88320; - c ^= 0x80000000; - } - } - return (c); -} - -/* Quick and dirty: Read 2-byte and 4-byte integers from Zip file. */ -static unsigned i2(const unsigned char *p) { return ((p[0] & 0xff) | ((p[1] & 0xff) << 8)); } -static unsigned i4(const unsigned char *p) { return (i2(p) | (i2(p + 2) << 16)); } -/* We're only working with small values here; ignore the 4 high bytes. */ -static unsigned i8(const unsigned char *p) { return (i4(p)); } - -DEFINE_TEST(test_write_format_zip_file_zip64) -{ - struct archive *a; - struct archive_entry *ae; - time_t t = 1234567890; - struct tm *tm; -#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S) - struct tm tmbuf; -#endif - size_t used, buffsize = 1000000; - unsigned long crc; - int file_perm = 00644; - int zip_version = 45; - int zip_compression = 8; - short file_uid = 10, file_gid = 20; - unsigned char *buff, *buffend, *p; - unsigned char *central_header, *local_header, *eocd, *eocd_record; - unsigned char *extension_start, *extension_end; - char file_data[] = {'1', '2', '3', '4', '5', '6', '7', '8'}; - const char *file_name = "file"; - -#ifndef HAVE_ZLIB_H - zip_compression = 0; -#endif - -#if defined(HAVE_LOCALTIME_S) - tm = localtime_s(&tmbuf, &t) ? NULL : &tmbuf; -#elif defined(HAVE_LOCALTIME_R) - tm = localtime_r(&t, &tmbuf); -#else - tm = localtime(&t); -#endif - buff = malloc(buffsize); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "zip:zip64")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "zip:experimental")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used)); - - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, file_name); - archive_entry_set_mode(ae, AE_IFREG | file_perm); - archive_entry_set_size(ae, sizeof(file_data)); - archive_entry_set_uid(ae, file_uid); - archive_entry_set_gid(ae, file_gid); - archive_entry_set_mtime(ae, t, 0); - assertEqualInt(0, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualInt(8, archive_write_data(a, file_data, sizeof(file_data))); - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - buffend = buff + used; - dumpfile("constructed.zip", buff, used); - - /* Verify "End of Central Directory" record. */ - /* Get address of end-of-central-directory record. */ - eocd_record = p = buffend - 22; /* Assumes there is no zip comment field. */ - failure("End-of-central-directory begins with PK\\005\\006 signature"); - assertEqualMem(p, "PK\005\006", 4); - failure("This must be disk 0"); - assertEqualInt(i2(p + 4), 0); - failure("Central dir must start on disk 0"); - assertEqualInt(i2(p + 6), 0); - failure("All central dir entries are on this disk"); - assertEqualInt(i2(p + 8), i2(p + 10)); - eocd = buff + i4(p + 12) + i4(p + 16); - failure("no zip comment"); - assertEqualInt(i2(p + 20), 0); - - /* Get address of first entry in central directory. */ - central_header = p = buff + i4(buffend - 6); - failure("Central file record at offset %d should begin with" - " PK\\001\\002 signature", - i4(buffend - 10)); - - /* Verify file entry in central directory. */ - assertEqualMem(p, "PK\001\002", 4); /* Signature */ - assertEqualInt(i2(p + 4), 3 * 256 + zip_version); /* Version made by */ - assertEqualInt(i2(p + 6), zip_version); /* Version needed to extract */ - assertEqualInt(i2(p + 8), 8); /* Flags */ - assertEqualInt(i2(p + 10), zip_compression); /* Compression method */ - assertEqualInt(i2(p + 12), (tm->tm_hour * 2048) + (tm->tm_min * 32) + (tm->tm_sec / 2)); /* File time */ - assertEqualInt(i2(p + 14), ((tm->tm_year - 80) * 512) + ((tm->tm_mon + 1) * 32) + tm->tm_mday); /* File date */ - crc = bitcrc32(0, file_data, sizeof(file_data)); - assertEqualInt(i4(p + 16), crc); /* CRC-32 */ - /* assertEqualInt(i4(p + 20), sizeof(file_data)); */ /* Compressed size */ - assertEqualInt(i4(p + 24), sizeof(file_data)); /* Uncompressed size */ - assertEqualInt(i2(p + 28), strlen(file_name)); /* Pathname length */ - /* assertEqualInt(i2(p + 30), 28); */ /* Extra field length: See below */ - assertEqualInt(i2(p + 32), 0); /* File comment length */ - assertEqualInt(i2(p + 34), 0); /* Disk number start */ - assertEqualInt(i2(p + 36), 0); /* Internal file attrs */ - assertEqualInt(i4(p + 38) >> 16 & 01777, file_perm); /* External file attrs */ - assertEqualInt(i4(p + 42), 0); /* Offset of local header */ - assertEqualMem(p + 46, file_name, strlen(file_name)); /* Pathname */ - p = extension_start = central_header + 46 + strlen(file_name); - extension_end = extension_start + i2(central_header + 30); - - assertEqualInt(i2(p), 0x5455); /* 'UT' extension header */ - assertEqualInt(i2(p + 2), 5); /* 'UT' size */ - assertEqualInt(p[4], 1); /* 'UT' flags */ - assertEqualInt(i4(p + 5), t); /* 'UT' mtime */ - p += 4 + i2(p + 2); - - assertEqualInt(i2(p), 0x7875); /* 'ux' extension header */ - assertEqualInt(i2(p + 2), 11); /* 'ux' size */ - /* TODO: verify 'ux' contents */ - p += 4 + i2(p + 2); - - /* Note: We don't expect to see zip64 extension in the central - * directory, since the writer knows the actual full size by - * the time it is ready to write the central directory and has - * no reason to insert it then. Info-Zip seems to do the same - * thing. */ - - /* Just in case: Report any extra extensions. */ - while (p < extension_end) { - failure("Unexpected extension 0x%04X", i2(p)); - assert(0); - p += 4 + i2(p + 2); - } - - /* Should have run exactly to end of extra data. */ - assert(p == extension_end); - - assert(p == eocd); - - /* After Central dir, we find Zip64 eocd and Zip64 eocd locator. */ - assertEqualMem(p, "PK\006\006", 4); /* Zip64 eocd */ - assertEqualInt(i8(p + 4), 44); /* We're using v1 Zip64 eocd */ - assertEqualInt(i2(p + 12), 45); /* Written by Version 4.5 */ - assertEqualInt(i2(p + 14), 45); /* Needs version 4.5 to extract */ - assertEqualInt(i4(p + 16), 0); /* This is disk #0 */ - assertEqualInt(i4(p + 20), 0); /* Dir starts on disk #0 */ - assertEqualInt(i8(p + 24), 1); /* 1 entry on this disk */ - assertEqualInt(i8(p + 32), 1); /* 1 entry total */ - assertEqualInt(i8(p + 40), eocd - central_header); /* size of cd */ - assertEqualInt(i8(p + 48), central_header - buff); /* start of cd */ - p += 12 + i8(p + 4); - - assertEqualMem(p, "PK\006\007", 4); /* Zip64 eocd locator */ - assertEqualInt(i4(p + 4), 0); /* Zip64 eocd is on disk #0 */ - assertEqualInt(i8(p + 8), eocd - buff); /* Offset of Zip64 eocd */ - assertEqualInt(i4(p + 16), 1); /* 1 disk */ - p += 20; - - /* Regular EOCD immediately follows Zip64 records. */ - assert(p == eocd_record); - - /* Verify local header of file entry. */ - p = local_header = buff; - assertEqualMem(p, "PK\003\004", 4); /* Signature */ - assertEqualInt(i2(p + 4), zip_version); /* Version needed to extract */ - assertEqualInt(i2(p + 6), 8); /* Flags */ - assertEqualInt(i2(p + 8), zip_compression); /* Compression method */ - assertEqualInt(i2(p + 10), (tm->tm_hour * 2048) + (tm->tm_min * 32) + (tm->tm_sec / 2)); /* File time */ - assertEqualInt(i2(p + 12), ((tm->tm_year - 80) * 512) + ((tm->tm_mon + 1) * 32) + tm->tm_mday); /* File date */ - assertEqualInt(i4(p + 14), 0); /* CRC-32 */ - /* assertEqualInt(i4(p + 18), sizeof(file_data)); */ /* Compressed size */ - /* assertEqualInt(i4(p + 22), sizeof(file_data)); */ /* Uncompressed size not stored because we're using length-at-end. */ - assertEqualInt(i2(p + 26), strlen(file_name)); /* Pathname length */ - assertEqualInt(i2(p + 28), 57); /* Extra field length */ - assertEqualMem(p + 30, file_name, strlen(file_name)); /* Pathname */ - p = extension_start = local_header + 30 + strlen(file_name); - extension_end = extension_start + i2(local_header + 28); - - assertEqualInt(i2(p), 0x5455); /* 'UT' extension header */ - assertEqualInt(i2(p + 2), 5); /* 'UT' size */ - assertEqualInt(p[4], 1); /* 'UT' flags */ - assertEqualInt(i4(p + 5), t); /* 'UT' mtime */ - p += 4 + i2(p + 2); - - assertEqualInt(i2(p), 0x7875); /* 'ux' extension header */ - assertEqualInt(i2(p + 2), 11); /* 'ux' size */ - assertEqualInt(p[4], 1); /* 'ux' version */ - assertEqualInt(p[5], 4); /* 'ux' uid size */ - assertEqualInt(i4(p + 6), file_uid); /* 'Ux' UID */ - assertEqualInt(p[10], 4); /* 'ux' gid size */ - assertEqualInt(i4(p + 11), file_gid); /* 'Ux' GID */ - p += 4 + i2(p + 2); - - assertEqualInt(i2(p), 0x0001); /* Zip64 extension header */ - assertEqualInt(i2(p + 2), 16); /* size */ - assertEqualInt(i8(p + 4), 8); /* uncompressed file size */ - /* compressed file size we can't verify here */ - p += 4 + i2(p + 2); - - assertEqualInt(i2(p), 0x6c78); /* 'xl' experimental extension header */ - assertEqualInt(i2(p + 2), 9); /* size */ - assertEqualInt(p[4], 7); /* bitmap of included fields */ - assertEqualInt(i2(p + 5) >> 8, 3); /* system & version made by */ - assertEqualInt(i2(p + 7), 0); /* internal file attributes */ - assertEqualInt(i4(p + 9) >> 16 & 01777, file_perm); /* external file attributes */ - p += 4 + i2(p + 2); - - /* Just in case: Report any extra extensions. */ - while (p < extension_end) { - failure("Unexpected extension 0x%04X", i2(p)); - assert(0); - p += 4 + i2(p + 2); - } - - /* Should have run exactly to end of extra data. */ - assert(p == extension_end); - - /* Data descriptor should follow compressed data. */ - while (p < central_header && memcmp(p, "PK\007\010", 4) != 0) - ++p; - assertEqualMem(p, "PK\007\010", 4); - assertEqualInt(i4(p + 4), crc); /* CRC-32 */ - /* assertEqualInt(i8(p + 8), ???); */ /* compressed size */ - assertEqualInt(i8(p + 16), sizeof(file_data)); /* uncompressed size */ - - /* Central directory should immediately follow the only entry. */ - assert(p + 24 == central_header); - - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_zip_large.c b/thirdparty/libarchive/libarchive/test/test_write_format_zip_large.c deleted file mode 100644 index e3594c97d..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_zip_large.c +++ /dev/null @@ -1,473 +0,0 @@ -/*- - * Copyright (c) 2003-2007,2013 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -#include -#include -#include - -/* - * This is a somewhat tricky test that verifies the ability to - * write and read very large entries to zip archives. - * - * See test_tar_large.c for more information about the machinery - * being used here. - */ - -static size_t nullsize; -static void *nulldata; - -struct fileblock { - struct fileblock *next; - int size; - void *buff; - int64_t gap_size; /* Size of following gap */ -}; - -struct fileblocks { - int64_t filesize; - int64_t fileposition; - int64_t gap_remaining; - void *buff; - struct fileblock *first; - struct fileblock *current; - struct fileblock *last; -}; - -/* The following size definitions simplify things below. */ -#define KB ((int64_t)1024) -#define MB ((int64_t)1024 * KB) -#define GB ((int64_t)1024 * MB) -#define TB ((int64_t)1024 * GB) - -static int64_t memory_read_skip(struct archive *, void *, int64_t request); -static ssize_t memory_read(struct archive *, void *, const void **buff); -static ssize_t memory_write(struct archive *, void *, const void *, size_t); - -static uint16_t le16(const void *_p) { - const uint8_t *p = _p; - return p[0] | (p[1] << 8); -} - -static uint32_t le32(const void *_p) { - const uint8_t *p = _p; - return le16(p) | ((uint32_t)le16(p + 2) << 16); -} - -static uint64_t le64(const void *_p) { - const uint8_t *p = _p; - return le32(p) | ((uint64_t)le32(p + 4) << 32); -} - -static ssize_t -memory_write(struct archive *a, void *_private, const void *buff, size_t size) -{ - struct fileblocks *private = _private; - struct fileblock *block; - - (void)a; - - if ((const char *)nulldata <= (const char *)buff - && (const char *)buff < (const char *)nulldata + nullsize) { - /* We don't need to store a block of gap data. */ - private->last->gap_size += (int64_t)size; - } else { - /* Yes, we're assuming the very first write is metadata. */ - /* It's header or metadata, copy and save it. */ - block = (struct fileblock *)malloc(sizeof(*block)); - memset(block, 0, sizeof(*block)); - block->size = (int)size; - block->buff = malloc(size); - memcpy(block->buff, buff, size); - if (private->last == NULL) { - private->first = private->last = block; - } else { - private->last->next = block; - private->last = block; - } - block->next = NULL; - } - private->filesize += size; - return ((long)size); -} - -static ssize_t -memory_read(struct archive *a, void *_private, const void **buff) -{ - struct fileblocks *private = _private; - ssize_t size; - - (void)a; - - while (private->current != NULL && private->buff == NULL && private->gap_remaining == 0) { - private->current = private->current->next; - if (private->current != NULL) { - private->buff = private->current->buff; - private->gap_remaining = private->current->gap_size; - } - } - - if (private->current == NULL) - return (0); - - /* If there's real data, return that. */ - if (private->buff != NULL) { - *buff = private->buff; - size = ((char *)private->current->buff + private->current->size) - - (char *)private->buff; - private->buff = NULL; - private->fileposition += size; - return (size); - } - - /* Big gap: too big to return all at once, so just return some. */ - if (private->gap_remaining > (int64_t)nullsize) { - private->gap_remaining -= nullsize; - *buff = nulldata; - private->fileposition += nullsize; - return (nullsize); - } - - /* Small gap: finish the gap and prep for next block. */ - if (private->gap_remaining > 0) { - size = (ssize_t)private->gap_remaining; - *buff = nulldata; - private->gap_remaining = 0; - private->fileposition += size; - - private->current = private->current->next; - if (private->current != NULL) { - private->buff = private->current->buff; - private->gap_remaining = private->current->gap_size; - } - - return (size); - } - fprintf(stderr, "\n\n\nInternal failure\n\n\n"); - exit(1); -} - -static int -memory_read_open(struct archive *a, void *_private) -{ - struct fileblocks *private = _private; - - (void)a; /* UNUSED */ - - private->current = private->first; - private->fileposition = 0; - if (private->current != NULL) { - private->buff = private->current->buff; - private->gap_remaining = private->current->gap_size; - } - return (ARCHIVE_OK); -} - -static int64_t -memory_read_seek(struct archive *a, void *_private, int64_t offset, int whence) -{ - struct fileblocks *private = _private; - - (void)a; - if (whence == SEEK_END) { - offset = private->filesize + offset; - } else if (whence == SEEK_CUR) { - offset = private->fileposition + offset; - } - - if (offset < 0) { - fprintf(stderr, "\n\n\nInternal failure: negative seek\n\n\n"); - exit(1); - } - - /* We've converted the request into a SEEK_SET. */ - private->fileposition = offset; - - /* Walk the block list to find the new position. */ - offset = 0; - private->current = private->first; - while (private->current != NULL) { - if (offset + private->current->size > private->fileposition) { - /* Position is in this block. */ - private->buff = (char *)private->current->buff - + private->fileposition - offset; - private->gap_remaining = private->current->gap_size; - return private->fileposition; - } - offset += private->current->size; - if (offset + private->current->gap_size > private->fileposition) { - /* Position is in this gap. */ - private->buff = NULL; - private->gap_remaining = private->current->gap_size - - (private->fileposition - offset); - return private->fileposition; - } - offset += private->current->gap_size; - /* Skip to next block. */ - private->current = private->current->next; - } - if (private->fileposition == private->filesize) { - return private->fileposition; - } - fprintf(stderr, "\n\n\nInternal failure: over-sized seek\n\n\n"); - exit(1); -} - -static int64_t -memory_read_skip(struct archive *a, void *_private, int64_t skip) -{ - struct fileblocks *private = _private; - int64_t old_position = private->fileposition; - int64_t new_position = memory_read_seek(a, _private, skip, SEEK_CUR); - return (new_position - old_position); -} - -static struct fileblocks * -fileblocks_new(void) -{ - struct fileblocks *fileblocks; - - fileblocks = calloc(1, sizeof(struct fileblocks)); - return fileblocks; -} - -static void -fileblocks_free(struct fileblocks *fileblocks) -{ - while (fileblocks->first != NULL) { - struct fileblock *b = fileblocks->first; - fileblocks->first = fileblocks->first->next; - free(b->buff); - free(b); - } - free(fileblocks); -} - - -/* The sizes of the entries we're going to generate. */ -static int64_t test_sizes[] = { - /* Test for 32-bit signed overflow. */ - 2 * GB - 1, 2 * GB, 2 * GB + 1, - /* Test for 32-bit unsigned overflow. */ - 4 * GB - 1, 4 * GB, 4 * GB + 1, - /* And beyond ... because we can. */ - 16 * GB - 1, 16 * GB, 16 * GB + 1, - 64 * GB - 1, 64 * GB, 64 * GB + 1, - 256 * GB - 1, 256 * GB, 256 * GB + 1, - 1 * TB, - 0 -}; - - -static void -verify_large_zip(struct archive *a, struct fileblocks *fileblocks) -{ - char namebuff[64]; - struct archive_entry *ae; - int i; - - assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_options(a, "zip:ignorecrc32")); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_open_callback(a, memory_read_open)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_read_callback(a, memory_read)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_skip_callback(a, memory_read_skip)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_seek_callback(a, memory_read_seek)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_set_callback_data(a, fileblocks)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open1(a)); - - /* - * Read entries back. - */ - for (i = 0; test_sizes[i] > 0; i++) { - assertEqualIntA(a, ARCHIVE_OK, - archive_read_next_header(a, &ae)); - snprintf(namebuff, sizeof(namebuff), "file_%d", i); - assertEqualString(namebuff, archive_entry_pathname(ae)); - assertEqualInt(test_sizes[i], archive_entry_size(ae)); - } - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualString("lastfile", archive_entry_pathname(ae)); - - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); -} - -DEFINE_TEST(test_write_format_zip_large) -{ - int i; - char namebuff[64]; - struct fileblocks *fileblocks = fileblocks_new(); - struct archive_entry *ae; - struct archive *a; - const char *p; - const char *cd_start, *zip64_eocd, *zip64_locator, *eocd; - int64_t cd_size; - char *buff; - int64_t filesize; - size_t writesize, buffsize, s; - - nullsize = (size_t)(1 * MB); - nulldata = malloc(nullsize); - memset(nulldata, 0xAA, nullsize); - - /* - * Open an archive for writing. - */ - a = archive_write_new(); - archive_write_set_format_zip(a); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "zip:compression=store")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_options(a, "zip:fakecrc32")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, 0)); /* No buffering. */ - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open(a, fileblocks, NULL, memory_write, NULL)); - - /* - * Write a series of large files to it. - */ - for (i = 0; test_sizes[i] != 0; i++) { - assert((ae = archive_entry_new()) != NULL); - snprintf(namebuff, sizeof(namebuff), "file_%d", i); - archive_entry_copy_pathname(ae, namebuff); - archive_entry_set_mode(ae, S_IFREG | 0755); - filesize = test_sizes[i]; - archive_entry_set_size(ae, filesize); - - assertEqualIntA(a, ARCHIVE_OK, - archive_write_header(a, ae)); - archive_entry_free(ae); - - /* - * Write the actual data to the archive. - */ - while (filesize > 0) { - writesize = nullsize; - if ((int64_t)writesize > filesize) - writesize = (size_t)filesize; - assertEqualIntA(a, (int)writesize, - (int)archive_write_data(a, nulldata, writesize)); - filesize -= writesize; - } - } - - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "lastfile"); - archive_entry_set_mode(ae, S_IFREG | 0755); - assertA(0 == archive_write_header(a, ae)); - archive_entry_free(ae); - - /* Close out the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* - * Read back with seeking reader: - */ - a = archive_read_new(); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_zip_seekable(a)); - verify_large_zip(a, fileblocks); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Read back with streaming reader: - */ - a = archive_read_new(); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_format_zip_streamable(a)); - verify_large_zip(a, fileblocks); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - /* - * Manually verify some of the final bytes of the archives. - */ - /* Collect the final bytes together */ -#define FINAL_SIZE 8192 - buff = malloc(FINAL_SIZE); - buffsize = 0; - memory_read_open(NULL, fileblocks); - memory_read_seek(NULL, fileblocks, -FINAL_SIZE, SEEK_END); - while ((s = memory_read(NULL, fileblocks, (const void **)&p)) > 0) { - memcpy(buff + buffsize, p, s); - buffsize += s; - } - assertEqualInt(buffsize, FINAL_SIZE); - - p = buff + buffsize; - - /* Verify regular end-of-central-directory record */ - eocd = p - 22; - assertEqualMem(eocd, "PK\005\006\0\0\0\0", 8); - assertEqualMem(eocd + 8, "\021\0\021\0", 4); /* 17 entries total */ - cd_size = le32(eocd + 12); - /* Start of CD offset should be 0xffffffff */ - assertEqualMem(eocd + 16, "\xff\xff\xff\xff", 4); - assertEqualMem(eocd + 20, "\0\0", 2); /* No Zip comment */ - - /* Verify Zip64 locator */ - zip64_locator = p - 42; - assertEqualMem(zip64_locator, "PK\006\007\0\0\0\0", 8); - zip64_eocd = p - (fileblocks->filesize - le64(zip64_locator + 8)); - assertEqualMem(zip64_locator + 16, "\001\0\0\0", 4); - - /* Verify Zip64 end-of-cd record. */ - assert(zip64_eocd == p - 98); - assertEqualMem(zip64_eocd, "PK\006\006", 4); - assertEqualInt(44, le64(zip64_eocd + 4)); // Size of EoCD record - 12 - assertEqualMem(zip64_eocd + 12, "\055\0", 2); // Made by version: 45 - assertEqualMem(zip64_eocd + 14, "\055\0", 2); // Requires version: 45 - assertEqualMem(zip64_eocd + 16, "\0\0\0\0", 4); // This disk - assertEqualMem(zip64_eocd + 20, "\0\0\0\0", 4); // Total disks - assertEqualInt(17, le64(zip64_eocd + 24)); // Entries on this disk - assertEqualInt(17, le64(zip64_eocd + 32)); // Total entries - cd_size = le64(zip64_eocd + 40); - cd_start = p - (fileblocks->filesize - le64(zip64_eocd + 48)); - - assert(cd_start + cd_size == zip64_eocd); - - assertEqualInt(le64(zip64_eocd + 48) // Start of CD - + cd_size - + 56 // Size of Zip64 EOCD - + 20 // Size of Zip64 locator - + 22, // Size of EOCD - fileblocks->filesize); - - // TODO: Scan entire Central Directory, sanity-check all data - assertEqualMem(cd_start, "PK\001\002", 4); - - fileblocks_free(fileblocks); - free(buff); - free(nulldata); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_format_zip_zip64.c b/thirdparty/libarchive/libarchive/test/test_write_format_zip_zip64.c deleted file mode 100644 index c5f00a2e5..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_format_zip_zip64.c +++ /dev/null @@ -1,69 +0,0 @@ -/*- - * Copyright (c) 2014 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -__FBSDID("$FreeBSD$"); - -static void -verify_zip_filesize(uint64_t size, int expected) -{ - struct archive *a; - struct archive_entry *ae; - char buff[256]; - size_t used; - - /* Zip format: Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a)); - /* Disable Zip64 extensions. */ - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_format_option(a, "zip", "zip64", NULL)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_pathname(ae, "test"); - archive_entry_set_mode(ae, AE_IFREG | 0644); - archive_entry_set_size(ae, size); - assertEqualInt(expected, archive_write_header(a, ae)); - - archive_entry_free(ae); - - /* Don't actually write 4GB! ;-) */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); -} - -DEFINE_TEST(test_write_format_zip_zip64_oversize) -{ - /* With Zip64 extensions disabled, we should be - * able to write a file with at most 4G-1 bytes. */ - - /* Note: Tar writer pads file to declared size when the file - * is closed. If Zip writer is changed to behave the same - * way, it will be much harder to test the first case here. */ - verify_zip_filesize(0xffffffffLL, ARCHIVE_OK); - - verify_zip_filesize(0x100000000LL, ARCHIVE_FAILED); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_open_memory.c b/thirdparty/libarchive/libarchive/test/test_write_open_memory.c deleted file mode 100644 index 3dbed113e..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_open_memory.c +++ /dev/null @@ -1,84 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_open_memory.c 189308 2009-03-03 17:02:51Z kientzle $"); - -/* Try to force archive_write_open_memory.c to write past the end of an array. */ -static unsigned char buff[16384]; - -DEFINE_TEST(test_write_open_memory) -{ - unsigned int i; - struct archive *a; - struct archive_entry *ae; - const char *name="/tmp/test"; - - /* Create a simple archive_entry. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_pathname(ae, name); - archive_entry_set_mode(ae, S_IFREG); - assertEqualString(archive_entry_pathname(ae), name); - - /* Try writing with different buffer sizes. */ - /* Make sure that we get failure on too-small buffers, success on - * large enough ones. */ - for (i = 100; i < 1600; i++) { - size_t used; - size_t blocksize = 94; - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_format_ustar(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_in_last_block(a, 1)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_set_bytes_per_block(a, (int)blocksize)); - buff[i] = 0xAE; - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, i, &used)); - /* If buffer is smaller than a tar header, this should fail. */ - if (i < (511/blocksize)*blocksize) - assertEqualIntA(a, ARCHIVE_FATAL, - archive_write_header(a,ae)); - else - assertEqualIntA(a, ARCHIVE_OK, - archive_write_header(a, ae)); - /* If buffer is smaller than a tar header plus 1024 byte - * end-of-archive marker, then this should fail. */ - failure("buffer size=%d\n", (int)i); - if (i < 1536) - assertEqualIntA(a, ARCHIVE_FATAL, - archive_write_close(a)); - else { - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(used, archive_filter_bytes(a, -1)); - assertEqualInt(archive_filter_bytes(a, -1), - archive_filter_bytes(a, 0)); - } - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - assertEqualInt(buff[i], 0xAE); - assert(used <= i); - } - archive_entry_free(ae); -} diff --git a/thirdparty/libarchive/libarchive/test/test_write_read_format_zip.c b/thirdparty/libarchive/libarchive/test/test_write_read_format_zip.c deleted file mode 100644 index 4f39489b5..000000000 --- a/thirdparty/libarchive/libarchive/test/test_write_read_format_zip.c +++ /dev/null @@ -1,751 +0,0 @@ -/*- - * Copyright (c) 2003-2008 Tim Kientzle - * Copyright (c) 2008 Anselm Strauss - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -/* - * Development supported by Google Summer of Code 2008. - */ - -#include "test.h" -__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_format_zip.c 201247 2009-12-30 05:59:21Z kientzle $"); - -/* - * These tests verify that our reader can read files - * created by our writer. - */ - -/* - * Write a variety of different file types into the archive. - */ -static void -write_contents(struct archive *a) -{ - struct archive_entry *ae; - - /* - * First write things with the "default" compression. - * The library will choose "deflate" for most things if it's - * available, else "store". - */ - - /* - * Write a file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - archive_entry_copy_pathname(ae, "file"); - archive_entry_set_mode(ae, AE_IFREG | 0755); - archive_entry_set_size(ae, 8); - assertEqualInt(0, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualInt(8, archive_write_data(a, "12345678", 9)); - assertEqualInt(0, archive_write_data(a, "1", 1)); - - /* - * Write another file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - archive_entry_copy_pathname(ae, "file2"); - archive_entry_set_mode(ae, AE_IFREG | 0755); - archive_entry_set_size(ae, 4); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualInt(4, archive_write_data(a, "1234", 4)); - - /* - * Write a file with an unknown size. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 2, 15); - archive_entry_copy_pathname(ae, "file3"); - archive_entry_set_mode(ae, AE_IFREG | 0621); - archive_entry_unset_size(ae); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualInt(5, archive_write_data(a, "mnopq", 5)); - - /* - * Write symbolic link. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(10, archive_entry_mtime_nsec(ae)); - archive_entry_copy_pathname(ae, "symlink"); - assertEqualString("symlink", archive_entry_pathname(ae)); - archive_entry_copy_symlink(ae, "file1"); - assertEqualString("file1", archive_entry_symlink(ae)); - archive_entry_set_mode(ae, AE_IFLNK | 0755); - assertEqualInt((AE_IFLNK | 0755), archive_entry_mode(ae)); - archive_entry_set_size(ae, 4); - - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* - * Write a directory to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 11, 110); - archive_entry_copy_pathname(ae, "dir"); - archive_entry_set_mode(ae, S_IFDIR | 0755); - archive_entry_set_size(ae, 512); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - failure("size should be zero so that applications know not to write"); - assertEqualInt(0, archive_entry_size(ae)); - archive_entry_free(ae); - assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9)); - - /* - * Force "deflate" compression if the platform supports it. - */ -#ifdef HAVE_ZLIB_H - assertEqualIntA(a, ARCHIVE_OK, archive_write_zip_set_compression_deflate(a)); - - /* - * Write a file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - archive_entry_copy_pathname(ae, "file_deflate"); - archive_entry_set_mode(ae, AE_IFREG | 0755); - archive_entry_set_size(ae, 8); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualInt(8, archive_write_data(a, "12345678", 9)); - assertEqualInt(0, archive_write_data(a, "1", 1)); - - /* - * Write another file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - archive_entry_copy_pathname(ae, "file2_deflate"); - archive_entry_set_mode(ae, AE_IFREG | 0755); - archive_entry_set_size(ae, 4); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualInt(4, archive_write_data(a, "1234", 4)); - - /* - * Write a file with an unknown size. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 2, 15); - archive_entry_copy_pathname(ae, "file3_deflate"); - archive_entry_set_mode(ae, AE_IFREG | 0621); - archive_entry_unset_size(ae); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualInt(5, archive_write_data(a, "ghijk", 5)); - - /* - * Write symbolic like file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - archive_entry_copy_pathname(ae, "symlink_deflate"); - archive_entry_copy_symlink(ae, "file1"); - archive_entry_set_mode(ae, AE_IFLNK | 0755); - archive_entry_set_size(ae, 4); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* - * Write a directory to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 11, 110); - archive_entry_copy_pathname(ae, "dir_deflate"); - archive_entry_set_mode(ae, S_IFDIR | 0755); - archive_entry_set_size(ae, 512); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - failure("size should be zero so that applications know not to write"); - assertEqualInt(0, archive_entry_size(ae)); - archive_entry_free(ae); - assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_finish_entry(a)); -#endif - - /* - * Now write a bunch of entries with "store" compression. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_zip_set_compression_store(a)); - - /* - * Write a file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - archive_entry_copy_pathname(ae, "file_stored"); - archive_entry_set_mode(ae, AE_IFREG | 0755); - archive_entry_set_size(ae, 8); - assertEqualInt(0, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualInt(8, archive_write_data(a, "12345678", 9)); - assertEqualInt(0, archive_write_data(a, "1", 1)); - - /* - * Write another file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - archive_entry_copy_pathname(ae, "file2_stored"); - archive_entry_set_mode(ae, AE_IFREG | 0755); - archive_entry_set_size(ae, 4); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualInt(4, archive_write_data(a, "ACEG", 4)); - - /* - * Write a file with an unknown size. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 2, 15); - archive_entry_copy_pathname(ae, "file3_stored"); - archive_entry_set_mode(ae, AE_IFREG | 0621); - archive_entry_unset_size(ae); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualInt(5, archive_write_data(a, "ijklm", 5)); - - /* - * Write symbolic like file to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 1, 10); - archive_entry_copy_pathname(ae, "symlink_stored"); - archive_entry_copy_symlink(ae, "file1"); - archive_entry_set_mode(ae, AE_IFLNK | 0755); - archive_entry_set_size(ae, 4); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - - /* - * Write a directory to it. - */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_set_mtime(ae, 11, 110); - archive_entry_copy_pathname(ae, "dir_stored"); - archive_entry_set_mode(ae, S_IFDIR | 0755); - archive_entry_set_size(ae, 512); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - failure("size should be zero so that applications know not to write"); - assertEqualInt(0, archive_entry_size(ae)); - archive_entry_free(ae); - assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9)); - - - /* Close out the archive. */ - assertEqualInt(ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); -} - -/* - * Read back all of the entries and verify their values. - */ -static void -verify_contents(struct archive *a, int seeking, int improved_streaming) -{ - char filedata[64]; - struct archive_entry *ae; - - /* - * Default compression options: - */ - - /* Read and verify first file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - /* Zip doesn't store high-resolution mtime. */ - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file", archive_entry_pathname(ae)); - if (seeking || improved_streaming) { - assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); - } - assertEqualInt(8, archive_entry_size(ae)); - assert(archive_entry_size_is_set(ae)); - assertEqualIntA(a, 8, - archive_read_data(a, filedata, sizeof(filedata))); - assertEqualMem(filedata, "12345678", 8); - - - /* Read the second file back. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file2", archive_entry_pathname(ae)); - if (seeking || improved_streaming) { - assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); - } - assertEqualInt(4, archive_entry_size(ae)); - assert(archive_entry_size_is_set(ae)); - assertEqualIntA(a, 4, - archive_read_data(a, filedata, sizeof(filedata))); - assertEqualMem(filedata, "1234", 4); - - /* Read the third file back. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file3", archive_entry_pathname(ae)); - if (seeking || improved_streaming) { - assertEqualInt(AE_IFREG | 0621, archive_entry_mode(ae)); - } - if (seeking) { - assertEqualInt(5, archive_entry_size(ae)); - } else { - assertEqualInt(0, archive_entry_size_is_set(ae)); - } - assertEqualIntA(a, 5, - archive_read_data(a, filedata, sizeof(filedata))); - assertEqualMem(filedata, "mnopq", 5); - - /* Read symlink. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("symlink", archive_entry_pathname(ae)); - if (seeking || improved_streaming) { - assertEqualInt(AE_IFLNK | 0755, archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualString("file1", archive_entry_symlink(ae)); - } else { - /* Streaming cannot read file type, so - * symlink body shows as regular file contents. */ - assertEqualInt(AE_IFREG | 0664, archive_entry_mode(ae)); - assertEqualInt(5, archive_entry_size(ae)); - assert(archive_entry_size_is_set(ae)); - } - - /* Read the dir entry back. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(11, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("dir/", archive_entry_pathname(ae)); - if (seeking || improved_streaming) - assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assert(archive_entry_size_is_set(ae)); - assertEqualIntA(a, 0, archive_read_data(a, filedata, 10)); - -#ifdef HAVE_ZLIB_H - /* - * Deflate compression option: - */ - - /* Read and verify first file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - /* Zip doesn't store high-resolution mtime. */ - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file_deflate", archive_entry_pathname(ae)); - if (seeking || improved_streaming) { - assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); - } - assertEqualInt(8, archive_entry_size(ae)); - assert(archive_entry_size_is_set(ae)); - assertEqualIntA(a, 8, - archive_read_data(a, filedata, sizeof(filedata))); - assertEqualMem(filedata, "12345678", 8); - - - /* Read the second file back. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file2_deflate", archive_entry_pathname(ae)); - if (seeking || improved_streaming) { - assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); - } - assertEqualInt(4, archive_entry_size(ae)); - assert(archive_entry_size_is_set(ae)); - assertEqualIntA(a, 4, - archive_read_data(a, filedata, sizeof(filedata))); - assertEqualMem(filedata, "1234", 4); - - /* Read the third file back. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file3_deflate", archive_entry_pathname(ae)); - if (seeking || improved_streaming) { - assertEqualInt(AE_IFREG | 0621, archive_entry_mode(ae)); - } - if (seeking) { - assertEqualInt(5, archive_entry_size(ae)); - } else { - assertEqualInt(0, archive_entry_size_is_set(ae)); - } - assertEqualIntA(a, 5, - archive_read_data(a, filedata, sizeof(filedata))); - assertEqualMem(filedata, "ghijk", 4); - - /* Read symlink. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("symlink_deflate", archive_entry_pathname(ae)); - if (seeking || improved_streaming) { - assertEqualInt(AE_IFLNK | 0755, archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualString("file1", archive_entry_symlink(ae)); - } else { - assertEqualInt(AE_IFREG | 0664, archive_entry_mode(ae)); - assertEqualInt(5, archive_entry_size(ae)); - assertEqualIntA(a, 5, archive_read_data(a, filedata, 10)); - assertEqualMem(filedata, "file1", 5); - } - - /* Read the dir entry back. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(11, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("dir_deflate/", archive_entry_pathname(ae)); - if (seeking) { - assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae)); - } - assertEqualInt(0, archive_entry_size(ae)); - assert(archive_entry_size_is_set(ae)); - assertEqualIntA(a, 0, archive_read_data(a, filedata, 10)); -#endif - - /* - * Store compression option: - */ - - /* Read and verify first file. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - /* Zip doesn't store high-resolution mtime. */ - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file_stored", archive_entry_pathname(ae)); - if (seeking || improved_streaming) { - assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); - } - assert(archive_entry_size_is_set(ae)); - assert(archive_entry_size_is_set(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, - archive_read_data(a, filedata, sizeof(filedata))); - assertEqualMem(filedata, "12345678", 8); - - - /* Read the second file back. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file2_stored", archive_entry_pathname(ae)); - if (seeking || improved_streaming) { - assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); - } - assertEqualInt(4, archive_entry_size(ae)); - assert(archive_entry_size_is_set(ae)); - assertEqualIntA(a, 4, - archive_read_data(a, filedata, sizeof(filedata))); - assertEqualMem(filedata, "ACEG", 4); - - /* Read the third file back. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(2, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("file3_stored", archive_entry_pathname(ae)); - if (seeking || improved_streaming) - assertEqualInt(AE_IFREG | 0621, archive_entry_mode(ae)); - if (seeking) { - assertEqualInt(5, archive_entry_size(ae)); - } else { - assertEqualInt(0, archive_entry_size_is_set(ae)); - } - assertEqualIntA(a, 5, - archive_read_data(a, filedata, sizeof(filedata))); - assertEqualMem(filedata, "ijklm", 4); - - /* Read symlink. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(1, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("symlink_stored", archive_entry_pathname(ae)); - if (seeking || improved_streaming) { - assertEqualInt(AE_IFLNK | 0755, archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualString("file1", archive_entry_symlink(ae)); - } else { - assertEqualInt(AE_IFREG | 0664, archive_entry_mode(ae)); - assertEqualInt(5, archive_entry_size(ae)); - assertEqualIntA(a, 5, archive_read_data(a, filedata, 10)); - assertEqualMem(filedata, "file1", 5); - } - - /* Read the dir entry back. */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt(11, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(0, archive_entry_atime(ae)); - assertEqualInt(0, archive_entry_ctime(ae)); - assertEqualString("dir_stored/", archive_entry_pathname(ae)); - if (seeking || improved_streaming) - assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualIntA(a, 0, archive_read_data(a, filedata, 10)); - - /* Verify the end of the archive. */ - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); -} - -/* - * Do a write-then-read roundtrip. - */ -DEFINE_TEST(test_write_read_format_zip) -{ - struct archive *a; - size_t used; - size_t buffsize = 1000000; - char *buff; - - buff = malloc(buffsize); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used)); - write_contents(a); - dumpfile("constructed.zip", buff, used); - - /* - * Now, read the data back. - */ - /* With the standard memory reader. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); - verify_contents(a, 1, 0); - - /* With the test memory reader -- streaming mode. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, used, 7)); - /* Streaming reader doesn't see mode information from Central Directory. */ - verify_contents(a, 0, 0); - - /* With the test memory reader -- seeking mode. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7)); - verify_contents(a, 1, 0); - - free(buff); -} - -/* - * Do a write-then-read roundtrip with 'el' extension enabled. - */ -DEFINE_TEST(test_write_read_format_zip_improved_streaming) -{ - struct archive *a; - size_t used; - size_t buffsize = 1000000; - char *buff; - - buff = malloc(buffsize); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "zip:experimental")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used)); - write_contents(a); - dumpfile("constructed.zip", buff, used); - - /* - * Now, read the data back. - */ - /* With the standard memory reader. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); - verify_contents(a, 1, 1); - - /* With the test memory reader -- streaming mode. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, used, 7)); - /* Streaming reader doesn't see mode information from Central Directory. */ - verify_contents(a, 0, 1); - - /* With the test memory reader -- seeking mode. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7)); - verify_contents(a, 1, 1); - - free(buff); -} - -/* - * Do a write-then-read roundtrip with Zip64 enabled. - */ -DEFINE_TEST(test_write_read_format_zip64) -{ - struct archive *a; - size_t used; - size_t buffsize = 1000000; - char *buff; - - buff = malloc(buffsize); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "zip:zip64")); -#if ZIP_IMPROVED_STREAMING - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "zip:experimental")); -#endif - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used)); - write_contents(a); - dumpfile("constructed64.zip", buff, used); - - /* - * Now, read the data back. - */ - /* With the standard memory reader. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); - verify_contents(a, 1, 0); - - /* With the test memory reader -- streaming mode. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, used, 7)); - /* Streaming reader doesn't see mode information from Central Directory. */ - verify_contents(a, 0, 0); - - /* With the test memory reader -- seeking mode. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7)); - verify_contents(a, 1, 0); - - free(buff); -} - - -/* - * Do a write-then-read roundtrip with Zip64 enabled and 'el' extension enabled. - */ -DEFINE_TEST(test_write_read_format_zip64_improved_streaming) -{ - struct archive *a; - size_t used; - size_t buffsize = 1000000; - char *buff; - - buff = malloc(buffsize); - - /* Create a new archive in memory. */ - assert((a = archive_write_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "zip:zip64")); - assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "zip:experimental")); - assertEqualIntA(a, ARCHIVE_OK, - archive_write_open_memory(a, buff, buffsize, &used)); - write_contents(a); - dumpfile("constructed64.zip", buff, used); - - /* - * Now, read the data back. - */ - /* With the standard memory reader. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); - verify_contents(a, 1, 1); - - /* With the test memory reader -- streaming mode. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, buff, used, 7)); - /* Streaming reader doesn't see mode information from Central Directory. */ - verify_contents(a, 0, 1); - - /* With the test memory reader -- seeking mode. */ - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, buff, used, 7)); - verify_contents(a, 1, 1); - - free(buff); -} diff --git a/thirdparty/libarchive/libarchive/test/test_xattr_platform.c b/thirdparty/libarchive/libarchive/test/test_xattr_platform.c deleted file mode 100644 index df3f81a5b..000000000 --- a/thirdparty/libarchive/libarchive/test/test_xattr_platform.c +++ /dev/null @@ -1,104 +0,0 @@ -/*- - * Copyright (c) 2003-2010 Tim Kientzle - * Copyright (c) 2017 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_xattr_platform) -{ -#if !ARCHIVE_XATTR_SUPPORT - skipping("Extended attributes are not supported on this platform"); -#else /* ARCHIVE_XATTR_SUPPORT */ - struct archive *a; - struct archive_entry *ae; - const char *name; - const void *value; - void *rvalue; - size_t size, insize; - int e, r; - const char *attrname = "user.libarchive.test"; - const char *readval = "readval"; - const char *writeval = "writeval"; - - assertMakeFile("readtest", 0644, "a"); - - if (!setXattr("readtest", attrname, readval, strlen(readval) + 1)) { - skipping("Extended attributes are not supported on this " - "filesystem"); - return; - } - - /* Read test */ - assert(NULL != (a = archive_read_disk_new())); - ae = archive_entry_new(); - assert(ae != NULL); - archive_entry_set_pathname(ae, "readtest"); - assertEqualInt(ARCHIVE_OK, - archive_read_disk_entry_from_file(a, ae, -1, NULL)); - e = archive_entry_xattr_reset(ae); - assert(e > 0); - - r = 0; - while (archive_entry_xattr_next(ae, &name, &value, - &size) == ARCHIVE_OK) { - if (name != NULL && value != NULL && size > 0 && - strcmp(name, attrname) == 0) { - failure("Attribute value does not match"); - assertEqualString((const char *)value, readval); - r = 1; - break; - } - } - failure("Attribute not found: %s", attrname); - assertEqualInt(r, 1); - - archive_entry_free(ae); - assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - - assert(NULL != (a = archive_write_disk_new())); - archive_write_disk_set_options(a, ARCHIVE_EXTRACT_TIME | - ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_XATTR); - - /* Write test */ - ae = archive_entry_new(); - assert(ae != NULL); - archive_entry_set_pathname(ae, "writetest"); - archive_entry_set_filetype(ae, AE_IFREG); - archive_entry_set_perm(ae, 0654); - archive_entry_set_mtime(ae, 123456, 7890); - archive_entry_set_size(ae, 0); - archive_entry_xattr_add_entry(ae, attrname, writeval, - strlen(writeval) + 1); - assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); - archive_entry_free(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - rvalue = getXattr("writetest", attrname, &insize); - if (assertEqualInt(insize, strlen(writeval) + 1) != 0) - assertEqualMem(rvalue, writeval, insize); - free(rvalue); -#endif -} diff --git a/thirdparty/libarchive/libarchive/test/test_zip_filename_encoding.c b/thirdparty/libarchive/libarchive/test/test_zip_filename_encoding.c deleted file mode 100644 index 54cd00630..000000000 --- a/thirdparty/libarchive/libarchive/test/test_zip_filename_encoding.c +++ /dev/null @@ -1,527 +0,0 @@ -/*- - * Copyright (c) 2011 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -#include - -DEFINE_TEST(test_zip_filename_encoding_UTF8) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { - skipping("en_US.UTF-8 locale not available on this system."); - return; - } - - /* - * Verify that UTF-8 filenames are correctly stored with - * hdrcharset=UTF-8 option. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a)); - if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) { - skipping("This system cannot convert character-set" - " for UTF-8."); - archive_write_free(a); - return; - } - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set a UTF-8 filename. */ - archive_entry_set_pathname(entry, "\xD0\xBF\xD1\x80\xD0\xB8"); - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* A bit 11 of general purpose flag should be 0x08, - * which indicates the filename charset is UTF-8. */ - assertEqualInt(0x08, buff[7]); - assertEqualMem(buff + 30, "\xD0\xBF\xD1\x80\xD0\xB8", 6); - - /* - * Verify that UTF-8 filenames are correctly stored without - * hdrcharset=UTF-8 option. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set a UTF-8 filename. */ - archive_entry_set_pathname(entry, "\xD0\xBF\xD1\x80\xD0\xB8"); - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* A bit 11 of general purpose flag should be 0x08, - * which indicates the filename charset is UTF-8. */ - assertEqualInt(0x08, buff[7]); - assertEqualMem(buff + 30, "\xD0\xBF\xD1\x80\xD0\xB8", 6); - - /* - * Verify that A bit 11 of general purpose flag is not set - * when ASCII filenames are stored. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set an ASCII filename. */ - archive_entry_set_pathname(entry, "abcABC"); - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* A bit 11 of general purpose flag should be 0, - * which indicates the filename charset is unknown. */ - assertEqualInt(0, buff[7]); - assertEqualMem(buff + 30, "abcABC", 6); -} - -DEFINE_TEST(test_zip_filename_encoding_KOI8R) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) { - skipping("KOI8-R locale not available on this system."); - return; - } - - /* - * Verify that KOI8-R filenames are correctly translated to UTF-8. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a)); - if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) { - skipping("This system cannot convert character-set" - " from KOI8-R to UTF-8."); - archive_write_free(a); - return; - } - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set a KOI8-R filename. */ - archive_entry_set_pathname(entry, "\xD0\xD2\xC9"); - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* A bit 11 of general purpose flag should be 0x08, - * which indicates the filename charset is UTF-8. */ - assertEqualInt(0x08, buff[7]); - /* Above three characters in KOI8-R should translate to the following - * three characters (two bytes each) in UTF-8. */ - assertEqualMem(buff + 30, "\xD0\xBF\xD1\x80\xD0\xB8", 6); - - /* - * Verify that KOI8-R filenames are not translated to UTF-8. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set a KOI8-R filename. */ - archive_entry_set_pathname(entry, "\xD0\xD2\xC9"); - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* A bit 11 of general purpose flag should be 0, - * which indicates the filename charset is unknown. */ - assertEqualInt(0, buff[7]); - /* Above three characters in KOI8-R should not translate to - * any character-set. */ - assertEqualMem(buff + 30, "\xD0\xD2\xC9", 3); - - /* - * Verify that A bit 11 of general purpose flag is not set - * when ASCII filenames are stored even if hdrcharset=UTF-8 - * is specified. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a)); - if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) { - skipping("This system cannot convert character-set" - " from KOI8-R to UTF-8."); - archive_write_free(a); - return; - } - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set an ASCII filename. */ - archive_entry_set_pathname(entry, "abcABC"); - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* A bit 11 of general purpose flag should be 0, - * which indicates the filename charset is unknown. */ - assertEqualInt(0, buff[7]); - assertEqualMem(buff + 30, "abcABC", 6); -} - -/* - * Do not translate CP1251 into CP866 if non Windows platform. - */ -DEFINE_TEST(test_zip_filename_encoding_ru_RU_CP1251) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "ru_RU.CP1251")) { - skipping("Russian_Russia locale not available on this system."); - return; - } - - /* - * Verify that CP1251 filenames are not translated into any - * other character-set, in particular, CP866. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set a CP1251 filename. */ - archive_entry_set_pathname(entry, "\xEF\xF0\xE8"); - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* A bit 11 of general purpose flag should be 0, - * which indicates the filename charset is unknown. */ - assertEqualInt(0, buff[7]); - /* Above three characters in CP1251 should not translate into - * any other character-set. */ - assertEqualMem(buff + 30, "\xEF\xF0\xE8", 3); -} - -/* - * Other archiver applications on Windows translate CP1251 filenames - * into CP866 filenames and store it in the zip file. - * Test above behavior works well. - */ -DEFINE_TEST(test_zip_filename_encoding_Russian_Russia) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "Russian_Russia")) { - skipping("Russian_Russia locale not available on this system."); - return; - } - - /* - * Verify that Russian_Russia(CP1251) filenames are correctly translated - * to UTF-8. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a)); - if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) { - skipping("This system cannot convert character-set" - " from Russian_Russia.CP1251 to UTF-8."); - archive_write_free(a); - return; - } - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set a CP1251 filename. */ - archive_entry_set_pathname(entry, "\xEF\xF0\xE8"); - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* A bit 11 of general purpose flag should be 0x08, - * which indicates the filename charset is UTF-8. */ - assertEqualInt(0x08, buff[7]); - /* Above three characters in CP1251 should translate to the following - * three characters (two bytes each) in UTF-8. */ - assertEqualMem(buff + 30, "\xD0\xBF\xD1\x80\xD0\xB8", 6); - - /* - * Verify that Russian_Russia(CP1251) filenames are correctly translated - * to CP866. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set a CP1251 filename. */ - archive_entry_set_pathname(entry, "\xEF\xF0\xE8"); - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* A bit 11 of general purpose flag should be 0, - * which indicates the filename charset is unknown. */ - assertEqualInt(0, buff[7]); - /* Above three characters in CP1251 should translate to the following - * three characters in CP866. */ - assertEqualMem(buff + 30, "\xAF\xE0\xA8", 3); -} - -DEFINE_TEST(test_zip_filename_encoding_EUCJP) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "ja_JP.eucJP")) { - skipping("eucJP locale not available on this system."); - return; - } - - /* - * Verify that EUC-JP filenames are correctly translated to UTF-8. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a)); - if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) { - skipping("This system cannot convert character-set" - " from eucJP to UTF-8."); - archive_write_free(a); - return; - } - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set an EUC-JP filename. */ - archive_entry_set_pathname(entry, "\xC9\xBD.txt"); - /* Check the Unicode version. */ - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* A bit 11 of general purpose flag should be 0x08, - * which indicates the filename charset is UTF-8. */ - assertEqualInt(0x08, buff[7]); - /* Check UTF-8 version. */ - assertEqualMem(buff + 30, "\xE8\xA1\xA8.txt", 7); - - /* - * Verify that EUC-JP filenames are not translated to UTF-8. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set an EUC-JP filename. */ - archive_entry_set_pathname(entry, "\xC9\xBD.txt"); - /* Check the Unicode version. */ - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* A bit 11 of general purpose flag should be 0, - * which indicates the filename charset is unknown. */ - assertEqualInt(0, buff[7]); - /* Above three characters in EUC-JP should not translate to - * any character-set. */ - assertEqualMem(buff + 30, "\xC9\xBD.txt", 6); - - /* - * Verify that A bit 11 of general purpose flag is not set - * when ASCII filenames are stored even if hdrcharset=UTF-8 - * is specified. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a)); - if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) { - skipping("This system cannot convert character-set" - " from eucJP to UTF-8."); - archive_write_free(a); - return; - } - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set an ASCII filename. */ - archive_entry_set_pathname(entry, "abcABC"); - /* Check the Unicode version. */ - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* A bit 11 of general purpose flag should be 0, - * which indicates the filename charset is unknown. */ - assertEqualInt(0, buff[7]); - assertEqualMem(buff + 30, "abcABC", 6); -} - -DEFINE_TEST(test_zip_filename_encoding_CP932) -{ - struct archive *a; - struct archive_entry *entry; - char buff[4096]; - size_t used; - - if (NULL == setlocale(LC_ALL, "Japanese_Japan") && - NULL == setlocale(LC_ALL, "ja_JP.SJIS")) { - skipping("CP932/SJIS locale not available on this system."); - return; - } - - /* - * Verify that EUC-JP filenames are correctly translated to UTF-8. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a)); - if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) { - skipping("This system cannot convert character-set" - " from CP932/SJIS to UTF-8."); - archive_write_free(a); - return; - } - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set a CP932/SJIS filename. */ - archive_entry_set_pathname(entry, "\x95\x5C.txt"); - /* Check the Unicode version. */ - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* A bit 11 of general purpose flag should be 0x08, - * which indicates the filename charset is UTF-8. */ - assertEqualInt(0x08, buff[7]); - /* Check UTF-8 version. */ - assertEqualMem(buff + 30, "\xE8\xA1\xA8.txt", 7); - - /* - * Verify that CP932/SJIS filenames are not translated to UTF-8. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a)); - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set a CP932/SJIS filename. */ - archive_entry_set_pathname(entry, "\x95\x5C.txt"); - /* Check the Unicode version. */ - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* A bit 11 of general purpose flag should be 0, - * which indicates the filename charset is unknown. */ - assertEqualInt(0, buff[7]); - /* Above three characters in CP932/SJIS should not translate to - * any character-set. */ - assertEqualMem(buff + 30, "\x95\x5C.txt", 6); - - /* - * Verify that A bit 11 of general purpose flag is not set - * when ASCII filenames are stored even if hdrcharset=UTF-8 - * is specified. - */ - a = archive_write_new(); - assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a)); - if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) { - skipping("This system cannot convert character-set" - " from CP932/SJIS to UTF-8."); - archive_write_free(a); - return; - } - assertEqualInt(ARCHIVE_OK, - archive_write_open_memory(a, buff, sizeof(buff), &used)); - - entry = archive_entry_new2(a); - /* Set an ASCII filename. */ - archive_entry_set_pathname(entry, "abcABC"); - /* Check the Unicode version. */ - archive_entry_set_filetype(entry, AE_IFREG); - archive_entry_set_size(entry, 0); - assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry)); - archive_entry_free(entry); - assertEqualInt(ARCHIVE_OK, archive_write_free(a)); - - /* A bit 11 of general purpose flag should be 0, - * which indicates the filename charset is unknown. */ - assertEqualInt(0, buff[7]); - assertEqualMem(buff + 30, "abcABC", 6); -} diff --git a/thirdparty/libarchive/libarchive/xxhash.c b/thirdparty/libarchive/libarchive/xxhash.c deleted file mode 100644 index beacd2391..000000000 --- a/thirdparty/libarchive/libarchive/xxhash.c +++ /dev/null @@ -1,529 +0,0 @@ -/* -xxHash - Fast Hash algorithm -Copyright (C) 2012-2014, Yann Collet. -BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. -* 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. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"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 COPYRIGHT -OWNER OR CONTRIBUTORS 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. - -You can contact the author at : -- xxHash source repository : http://code.google.com/p/xxhash/ -*/ -#include "archive_platform.h" - -#include -#include - -#include "archive_xxhash.h" - -#ifdef HAVE_LIBLZ4 - -/*************************************** -** Tuning parameters -****************************************/ -/* Unaligned memory access is automatically enabled for "common" CPU, such as x86. -** For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected. -** If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance. -** You can also enable this parameter if you know your input data will always be aligned (boundaries of 4, for U32). -*/ -#if defined(__ARM_FEATURE_UNALIGNED) || defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) -# define XXH_USE_UNALIGNED_ACCESS 1 -#endif - -/* XXH_ACCEPT_NULL_INPUT_POINTER : -** If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer. -** When this option is enabled, xxHash output for null input pointers will be the same as a null-length input. -** This option has a very small performance cost (only measurable on small inputs). -** By default, this option is disabled. To enable it, uncomment below define : -** #define XXH_ACCEPT_NULL_INPUT_POINTER 1 - -** XXH_FORCE_NATIVE_FORMAT : -** By default, xxHash library provides endian-independent Hash values, based on little-endian convention. -** Results are therefore identical for little-endian and big-endian CPU. -** This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format. -** Should endian-independence be of no importance for your application, you may set the #define below to 1. -** It will improve speed for Big-endian CPU. -** This option has no impact on Little_Endian CPU. -*/ -#define XXH_FORCE_NATIVE_FORMAT 0 - -/*************************************** -** Compiler Specific Options -****************************************/ -/* Disable some Visual warning messages */ -#ifdef _MSC_VER /* Visual Studio */ -# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ -#endif - -#ifdef _MSC_VER /* Visual Studio */ -# define FORCE_INLINE __forceinline -#else -# ifdef __GNUC__ -# define FORCE_INLINE inline __attribute__((always_inline)) -# else -# define FORCE_INLINE inline -# endif -#endif - -/*************************************** -** Includes & Memory related functions -****************************************/ -#define XXH_malloc malloc -#define XXH_free free -#define XXH_memcpy memcpy - - -static unsigned int XXH32 (const void*, unsigned int, unsigned int); -static void* XXH32_init (unsigned int); -static XXH_errorcode XXH32_update (void*, const void*, unsigned int); -static unsigned int XXH32_digest (void*); -/*static int XXH32_sizeofState(void);*/ -static XXH_errorcode XXH32_resetState(void*, unsigned int); -#define XXH32_SIZEOFSTATE 48 -typedef struct { long long ll[(XXH32_SIZEOFSTATE+(sizeof(long long)-1))/sizeof(long long)]; } XXH32_stateSpace_t; -static unsigned int XXH32_intermediateDigest (void*); - -/*************************************** -** Basic Types -****************************************/ -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ -# include - typedef uint8_t BYTE; - typedef uint16_t U16; - typedef uint32_t U32; - typedef int32_t S32; - typedef uint64_t U64; -#else - typedef unsigned char BYTE; - typedef unsigned short U16; - typedef unsigned int U32; - typedef signed int S32; - typedef unsigned long long U64; -#endif - -#if defined(__GNUC__) && !defined(XXH_USE_UNALIGNED_ACCESS) -# define _PACKED __attribute__ ((packed)) -#else -# define _PACKED -#endif - -#if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__) -# ifdef __IBMC__ -# pragma pack(1) -# else -# pragma pack(push, 1) -# endif -#endif - -typedef struct _U32_S { U32 v; } _PACKED U32_S; - -#if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__) -# pragma pack(pop) -#endif - - -/**************************************** -** Compiler-specific Functions and Macros -*****************************************/ -#define GCC_VERSION ((__GNUC__-0) * 100 + (__GNUC_MINOR__ - 0)) - -#if GCC_VERSION >= 409 -__attribute__((__no_sanitize_undefined__)) -#else -# if defined(__clang__) -__attribute__((no_sanitize("undefined"))) -# endif -#endif -#if defined(_MSC_VER) -static __inline U32 A32(const void * x) -#else -static inline U32 A32(const void* x) -#endif -{ - return (((const U32_S *)(x))->v); -} - -/* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */ -#if defined(_MSC_VER) -# define XXH_rotl32(x,r) _rotl(x,r) -#else -# define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r))) -#endif - -#if defined(_MSC_VER) /* Visual Studio */ -# define XXH_swap32 _byteswap_ulong -#elif GCC_VERSION >= 403 -# define XXH_swap32 __builtin_bswap32 -#else -static inline U32 XXH_swap32 (U32 x) { - return ((x << 24) & 0xff000000 ) | - ((x << 8) & 0x00ff0000 ) | - ((x >> 8) & 0x0000ff00 ) | - ((x >> 24) & 0x000000ff );} -#endif - - -/*************************************** -** Constants -****************************************/ -#define PRIME32_1 2654435761U -#define PRIME32_2 2246822519U -#define PRIME32_3 3266489917U -#define PRIME32_4 668265263U -#define PRIME32_5 374761393U - - -/*************************************** -** Architecture Macros -****************************************/ -typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess; -#ifndef XXH_CPU_LITTLE_ENDIAN /* It is possible to define XXH_CPU_LITTLE_ENDIAN externally, for example using a compiler switch */ - static const int one = 1; -# define XXH_CPU_LITTLE_ENDIAN (*(const char*)(&one)) -#endif - - -/*************************************** -** Macros -****************************************/ -#define XXH_STATIC_ASSERT(c) { enum { XXH_static_assert = 1/(!!(c)) }; } /* use only *after* variable declarations */ - - -/***************************** -** Memory reads -******************************/ -typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment; - -static -FORCE_INLINE U32 XXH_readLE32_align(const U32* ptr, XXH_endianess endian, XXH_alignment align) -{ - if (align==XXH_unaligned) - return endian==XXH_littleEndian ? A32(ptr) : XXH_swap32(A32(ptr)); - else - return endian==XXH_littleEndian ? *ptr : XXH_swap32(*ptr); -} - -static -FORCE_INLINE U32 XXH_readLE32(const U32* ptr, XXH_endianess endian) { return XXH_readLE32_align(ptr, endian, XXH_unaligned); } - - -/***************************** -** Simple Hash Functions -******************************/ -static -FORCE_INLINE U32 XXH32_endian_align(const void* input, unsigned int len, U32 seed, XXH_endianess endian, XXH_alignment align) -{ - const BYTE* p = (const BYTE*)input; - const BYTE* bEnd = p + len; - U32 h32; -#define XXH_get32bits(p) XXH_readLE32_align((const U32*)p, endian, align) - -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (p==NULL) { len=0; bEnd=p=(const BYTE*)(size_t)16; } -#endif - - if (len>=16) - { - const BYTE* const limit = bEnd - 16; - U32 v1 = seed + PRIME32_1 + PRIME32_2; - U32 v2 = seed + PRIME32_2; - U32 v3 = seed + 0; - U32 v4 = seed - PRIME32_1; - - do - { - v1 += XXH_get32bits(p) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4; - v2 += XXH_get32bits(p) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4; - v3 += XXH_get32bits(p) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4; - v4 += XXH_get32bits(p) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4; - } while (p<=limit); - - h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); - } - else - { - h32 = seed + PRIME32_5; - } - - h32 += (U32) len; - - while (p<=bEnd-4) - { - h32 += XXH_get32bits(p) * PRIME32_3; - h32 = XXH_rotl32(h32, 17) * PRIME32_4 ; - p+=4; - } - - while (p> 15; - h32 *= PRIME32_2; - h32 ^= h32 >> 13; - h32 *= PRIME32_3; - h32 ^= h32 >> 16; - - return h32; -} - - -U32 XXH32(const void* input, unsigned int len, U32 seed) -{ -#if 0 - // Simple version, good for code maintenance, but unfortunately slow for small inputs - void* state = XXH32_init(seed); - XXH32_update(state, input, len); - return XXH32_digest(state); -#else - XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; - -# if !defined(XXH_USE_UNALIGNED_ACCESS) - if ((((size_t)input) & 3) == 0) /* Input is aligned, let's leverage the speed advantage */ - { - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); - else - return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); - } -# endif - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); - else - return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); -#endif -} - -/***************************** -** Advanced Hash Functions -******************************/ - -struct XXH_state32_t -{ - U64 total_len; - U32 seed; - U32 v1; - U32 v2; - U32 v3; - U32 v4; - int memsize; - char memory[16]; -}; - -#if 0 -static -int XXH32_sizeofState(void) -{ - XXH_STATIC_ASSERT(XXH32_SIZEOFSTATE >= sizeof(struct XXH_state32_t)); /* A compilation error here means XXH32_SIZEOFSTATE is not large enough */ - return sizeof(struct XXH_state32_t); -} -#endif - -static -XXH_errorcode XXH32_resetState(void* state_in, U32 seed) -{ - struct XXH_state32_t * state = (struct XXH_state32_t *) state_in; - state->seed = seed; - state->v1 = seed + PRIME32_1 + PRIME32_2; - state->v2 = seed + PRIME32_2; - state->v3 = seed + 0; - state->v4 = seed - PRIME32_1; - state->total_len = 0; - state->memsize = 0; - return XXH_OK; -} - -static -void* XXH32_init (U32 seed) -{ - void* state = XXH_malloc (sizeof(struct XXH_state32_t)); - XXH32_resetState(state, seed); - return state; -} - -static -FORCE_INLINE XXH_errorcode XXH32_update_endian (void* state_in, const void* input, int len, XXH_endianess endian) -{ - struct XXH_state32_t * state = (struct XXH_state32_t *) state_in; - const BYTE* p = (const BYTE*)input; - const BYTE* const bEnd = p + len; - -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (input==NULL) return XXH_ERROR; -#endif - - state->total_len += len; - - if (state->memsize + len < 16) /* fill in tmp buffer */ - { - XXH_memcpy(state->memory + state->memsize, input, len); - state->memsize += len; - return XXH_OK; - } - - if (state->memsize) /* some data left from previous update */ - { - XXH_memcpy(state->memory + state->memsize, input, 16-state->memsize); - { - const U32* p32 = (const U32*)state->memory; - state->v1 += XXH_readLE32(p32, endian) * PRIME32_2; state->v1 = XXH_rotl32(state->v1, 13); state->v1 *= PRIME32_1; p32++; - state->v2 += XXH_readLE32(p32, endian) * PRIME32_2; state->v2 = XXH_rotl32(state->v2, 13); state->v2 *= PRIME32_1; p32++; - state->v3 += XXH_readLE32(p32, endian) * PRIME32_2; state->v3 = XXH_rotl32(state->v3, 13); state->v3 *= PRIME32_1; p32++; - state->v4 += XXH_readLE32(p32, endian) * PRIME32_2; state->v4 = XXH_rotl32(state->v4, 13); state->v4 *= PRIME32_1; p32++; - } - p += 16-state->memsize; - state->memsize = 0; - } - - if (p <= bEnd-16) - { - const BYTE* const limit = bEnd - 16; - U32 v1 = state->v1; - U32 v2 = state->v2; - U32 v3 = state->v3; - U32 v4 = state->v4; - - do - { - v1 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4; - v2 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4; - v3 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4; - v4 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4; - } while (p<=limit); - - state->v1 = v1; - state->v2 = v2; - state->v3 = v3; - state->v4 = v4; - } - - if (p < bEnd) - { - XXH_memcpy(state->memory, p, bEnd-p); - state->memsize = (int)(bEnd-p); - } - - return XXH_OK; -} - -static -XXH_errorcode XXH32_update (void* state_in, const void* input, unsigned int len) -{ - XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_update_endian(state_in, input, len, XXH_littleEndian); - else - return XXH32_update_endian(state_in, input, len, XXH_bigEndian); -} - - - -static -FORCE_INLINE U32 XXH32_intermediateDigest_endian (void* state_in, XXH_endianess endian) -{ - struct XXH_state32_t * state = (struct XXH_state32_t *) state_in; - const BYTE * p = (const BYTE*)state->memory; - BYTE* bEnd = (BYTE*)state->memory + state->memsize; - U32 h32; - - if (state->total_len >= 16) - { - h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18); - } - else - { - h32 = state->seed + PRIME32_5; - } - - h32 += (U32) state->total_len; - - while (p<=bEnd-4) - { - h32 += XXH_readLE32((const U32*)p, endian) * PRIME32_3; - h32 = XXH_rotl32(h32, 17) * PRIME32_4; - p+=4; - } - - while (p> 15; - h32 *= PRIME32_2; - h32 ^= h32 >> 13; - h32 *= PRIME32_3; - h32 ^= h32 >> 16; - - return h32; -} - -static -U32 XXH32_intermediateDigest (void* state_in) -{ - XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_intermediateDigest_endian(state_in, XXH_littleEndian); - else - return XXH32_intermediateDigest_endian(state_in, XXH_bigEndian); -} - -static -U32 XXH32_digest (void* state_in) -{ - U32 h32 = XXH32_intermediateDigest(state_in); - - XXH_free(state_in); - - return h32; -} - -const -struct archive_xxhash __archive_xxhash = { - XXH32, - XXH32_init, - XXH32_update, - XXH32_digest -}; -#else - -/* - * Define an empty version of the struct if we aren't using the LZ4 library. - */ -const -struct archive_xxhash __archive_xxhash = { - NULL, - NULL, - NULL, - NULL -}; - -#endif /* HAVE_LIBLZ4 */ diff --git a/thirdparty/libarchive/libarchive_fe/err.c b/thirdparty/libarchive/libarchive_fe/err.c deleted file mode 100644 index 8c860350b..000000000 --- a/thirdparty/libarchive/libarchive_fe/err.c +++ /dev/null @@ -1,100 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "lafe_platform.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_STDARG_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "err.h" - -static void lafe_vwarnc(int, const char *, va_list) __LA_PRINTFLIKE(2, 0); - -static const char *lafe_progname; - -const char * -lafe_getprogname(void) -{ - - return lafe_progname; -} - -void -lafe_setprogname(const char *name, const char *defaultname) -{ - - if (name == NULL) - name = defaultname; -#if defined(_WIN32) && !defined(__CYGWIN__) - lafe_progname = strrchr(name, '\\'); - if (strrchr(name, '/') > lafe_progname) -#endif - lafe_progname = strrchr(name, '/'); - if (lafe_progname != NULL) - lafe_progname++; - else - lafe_progname = name; -} - -static void -lafe_vwarnc(int code, const char *fmt, va_list ap) -{ - fprintf(stderr, "%s: ", lafe_progname); - vfprintf(stderr, fmt, ap); - if (code != 0) - fprintf(stderr, ": %s", strerror(code)); - fprintf(stderr, "\n"); -} - -void -lafe_warnc(int code, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - lafe_vwarnc(code, fmt, ap); - va_end(ap); -} - -void -lafe_errc(int eval, int code, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - lafe_vwarnc(code, fmt, ap); - va_end(ap); - exit(eval); -} diff --git a/thirdparty/libarchive/libarchive_fe/err.h b/thirdparty/libarchive/libarchive_fe/err.h deleted file mode 100644 index c663103b0..000000000 --- a/thirdparty/libarchive/libarchive_fe/err.h +++ /dev/null @@ -1,55 +0,0 @@ -/*- - * Copyright (c) 2009 Joerg Sonnenberger - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#ifndef LAFE_ERR_H -#define LAFE_ERR_H - -#if defined(__GNUC__) && (__GNUC__ > 2 || \ - (__GNUC__ == 2 && __GNUC_MINOR__ >= 5)) -#define __LA_DEAD __attribute__((__noreturn__)) -#else -#define __LA_DEAD -#endif - -#if defined(__GNUC__) && (__GNUC__ > 2 || \ - (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)) -# ifdef __MINGW_PRINTF_FORMAT -# define __LA_PRINTF_FORMAT __MINGW_PRINTF_FORMAT -# else -# define __LA_PRINTF_FORMAT __printf__ -# endif -# define __LA_PRINTFLIKE(f,a) __attribute__((__format__(__LA_PRINTF_FORMAT, f, a))) -#else -# define __LA_PRINTFLIKE(f,a) -#endif - -void lafe_warnc(int code, const char *fmt, ...) __LA_PRINTFLIKE(2, 3); -void lafe_errc(int eval, int code, const char *fmt, ...) __LA_DEAD - __LA_PRINTFLIKE(3, 4); - -const char * lafe_getprogname(void); -void lafe_setprogname(const char *name, const char *defaultname); - -#endif diff --git a/thirdparty/libarchive/libarchive_fe/lafe_platform.h b/thirdparty/libarchive/libarchive_fe/lafe_platform.h deleted file mode 100644 index 557124b9f..000000000 --- a/thirdparty/libarchive/libarchive_fe/lafe_platform.h +++ /dev/null @@ -1,55 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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/usr.bin/cpio/cpio_platform.h,v 1.2 2008/12/06 07:15:42 kientzle Exp $ - */ - -/* - * This header is the first thing included in any of the libarchive_fe - * source files. As far as possible, platform-specific issues should - * be dealt with here and not within individual source files. - */ - -#ifndef LAFE_PLATFORM_H_INCLUDED -#define LAFE_PLATFORM_H_INCLUDED - -#if defined(PLATFORM_CONFIG_H) -/* Use hand-built config.h in environments that need it. */ -#include PLATFORM_CONFIG_H -#else -/* Read config.h or die trying. */ -#include "config.h" -#endif - -/* Get a real definition for __FBSDID if we can */ -#if HAVE_SYS_CDEFS_H -#include -#endif - -/* If not, define it so as to avoid dangling semicolons. */ -#ifndef __FBSDID -#define __FBSDID(a) struct _undefined_hack -#endif - -#endif diff --git a/thirdparty/libarchive/libarchive_fe/line_reader.c b/thirdparty/libarchive/libarchive_fe/line_reader.c deleted file mode 100644 index c7c4694ee..000000000 --- a/thirdparty/libarchive/libarchive_fe/line_reader.c +++ /dev/null @@ -1,168 +0,0 @@ -/*- - * Copyright (c) 2008 Tim Kientzle - * Copyright (c) 2010 Joerg Sonnenberger - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "lafe_platform.h" -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include - -#include "err.h" -#include "line_reader.h" - -#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__BORLANDC__) -#define strdup _strdup -#endif - -/* - * Read lines from file and do something with each one. If option_null - * is set, lines are terminated with zero bytes; otherwise, they're - * terminated with newlines. - * - * This uses a self-sizing buffer to handle arbitrarily-long lines. - */ -struct lafe_line_reader { - FILE *f; - char *buff, *buff_end, *line_start, *line_end; - char *pathname; - size_t buff_length; - int nullSeparator; /* Lines separated by null, not CR/CRLF/etc. */ -}; - -struct lafe_line_reader * -lafe_line_reader(const char *pathname, int nullSeparator) -{ - struct lafe_line_reader *lr; - - lr = calloc(1, sizeof(*lr)); - if (lr == NULL) - lafe_errc(1, ENOMEM, "Can't open %s", pathname); - - lr->nullSeparator = nullSeparator; - lr->pathname = strdup(pathname); - - if (strcmp(pathname, "-") == 0) - lr->f = stdin; - else - lr->f = fopen(pathname, "r"); - if (lr->f == NULL) - lafe_errc(1, errno, "Couldn't open %s", pathname); - lr->buff_length = 8192; - lr->line_start = lr->line_end = lr->buff_end = lr->buff = NULL; - - return (lr); -} - -static void -lafe_line_reader_find_eol(struct lafe_line_reader *lr) -{ - - lr->line_end += strcspn(lr->line_end, - lr->nullSeparator ? "" : "\x0d\x0a"); - *lr->line_end = '\0'; /* Noop if line_end == buff_end */ -} - -const char * -lafe_line_reader_next(struct lafe_line_reader *lr) -{ - size_t bytes_wanted, bytes_read, new_buff_size; - char *line_start, *p; - - for (;;) { - /* If there's a line in the buffer, return it immediately. */ - while (lr->line_end < lr->buff_end) { - line_start = lr->line_start; - lr->line_start = ++lr->line_end; - lafe_line_reader_find_eol(lr); - - if (lr->nullSeparator || line_start[0] != '\0') - return (line_start); - } - - /* If we're at end-of-file, process the final data. */ - if (lr->f == NULL) { - if (lr->line_start == lr->buff_end) - return (NULL); /* No more text */ - line_start = lr->line_start; - lr->line_start = lr->buff_end; - return (line_start); - } - - /* Buffer only has part of a line. */ - if (lr->line_start > lr->buff) { - /* Move a leftover fractional line to the beginning. */ - memmove(lr->buff, lr->line_start, - lr->buff_end - lr->line_start); - lr->buff_end -= lr->line_start - lr->buff; - lr->line_end -= lr->line_start - lr->buff; - lr->line_start = lr->buff; - } else { - /* Line is too big; enlarge the buffer. */ - new_buff_size = lr->buff_length * 2; - if (new_buff_size <= lr->buff_length) - lafe_errc(1, ENOMEM, - "Line too long in %s", lr->pathname); - lr->buff_length = new_buff_size; - /* - * Allocate one extra byte to allow terminating - * the buffer. - */ - p = realloc(lr->buff, new_buff_size + 1); - if (p == NULL) - lafe_errc(1, ENOMEM, - "Line too long in %s", lr->pathname); - lr->buff_end = p + (lr->buff_end - lr->buff); - lr->line_end = p + (lr->line_end - lr->buff); - lr->line_start = lr->buff = p; - } - - /* Get some more data into the buffer. */ - bytes_wanted = lr->buff + lr->buff_length - lr->buff_end; - bytes_read = fread(lr->buff_end, 1, bytes_wanted, lr->f); - lr->buff_end += bytes_read; - *lr->buff_end = '\0'; /* Always terminate buffer */ - lafe_line_reader_find_eol(lr); - - if (ferror(lr->f)) - lafe_errc(1, errno, "Can't read %s", lr->pathname); - if (feof(lr->f)) { - if (lr->f != stdin) - fclose(lr->f); - lr->f = NULL; - } - } -} - -void -lafe_line_reader_free(struct lafe_line_reader *lr) -{ - free(lr->buff); - free(lr->pathname); - free(lr); -} diff --git a/thirdparty/libarchive/libarchive_fe/line_reader.h b/thirdparty/libarchive/libarchive_fe/line_reader.h deleted file mode 100644 index d092c051f..000000000 --- a/thirdparty/libarchive/libarchive_fe/line_reader.h +++ /dev/null @@ -1,35 +0,0 @@ -/*- - * Copyright (c) 2009 Joerg Sonnenberger - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#ifndef LAFE_LINE_READER_H -#define LAFE_LINE_READER_H - -struct lafe_line_reader; - -struct lafe_line_reader *lafe_line_reader(const char *, int nullSeparator); -const char *lafe_line_reader_next(struct lafe_line_reader *); -void lafe_line_reader_free(struct lafe_line_reader *); - -#endif diff --git a/thirdparty/libarchive/libarchive_fe/passphrase.c b/thirdparty/libarchive/libarchive_fe/passphrase.c deleted file mode 100644 index 1cae6a7bc..000000000 --- a/thirdparty/libarchive/libarchive_fe/passphrase.c +++ /dev/null @@ -1,339 +0,0 @@ -/*- - * Copyright (c) 2014 Michihiro NAKAJIMA - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -/* $OpenBSD: readpassphrase.c,v 1.27 2019/01/25 00:19:25 millert Exp $ */ - -/* - * Copyright (c) 2000-2002, 2007, 2010 - * Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Sponsored in part by the Defense Advanced Research Projects - * Agency (DARPA) and Air Force Research Laboratory, Air Force - * Materiel Command, USAF, under agreement number F39502-99-1-0512. - */ - -/* OPENBSD ORIGINAL: lib/libc/gen/readpassphrase.c */ - - -#include "lafe_platform.h" -__FBSDID("$FreeBSD$"); - -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_READPASSPHRASE_H -#include -#endif - -#include "err.h" -#include "passphrase.h" - -#ifndef HAVE_READPASSPHRASE - -#define RPP_ECHO_OFF 0x00 /* Turn off echo (default). */ -#define RPP_ECHO_ON 0x01 /* Leave echo on. */ -#define RPP_REQUIRE_TTY 0x02 /* Fail if there is no tty. */ -#define RPP_FORCELOWER 0x04 /* Force input to lower case. */ -#define RPP_FORCEUPPER 0x08 /* Force input to upper case. */ -#define RPP_SEVENBIT 0x10 /* Strip the high bit from input. */ -#define RPP_STDIN 0x20 /* Read from stdin, not /dev/tty */ - - -#if defined(_WIN32) && !defined(__CYGWIN__) -#include - -static char * -readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) -{ - HANDLE hStdin, hStdout; - DWORD mode, rbytes; - BOOL success; - - (void)flags; - - hStdin = GetStdHandle(STD_INPUT_HANDLE); - if (hStdin == INVALID_HANDLE_VALUE) - return (NULL); - hStdout = GetStdHandle(STD_OUTPUT_HANDLE); - if (hStdout == INVALID_HANDLE_VALUE) - return (NULL); - - success = GetConsoleMode(hStdin, &mode); - if (!success) - return (NULL); - mode &= ~ENABLE_ECHO_INPUT; - mode |= ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT; - success = SetConsoleMode(hStdin, mode); - if (!success) - return (NULL); - - success = WriteFile(hStdout, prompt, (DWORD)strlen(prompt), - NULL, NULL); - if (!success) - return (NULL); - success = ReadFile(hStdin, buf, (DWORD)bufsiz - 1, &rbytes, NULL); - if (!success) - return (NULL); - WriteFile(hStdout, "\r\n", 2, NULL, NULL); - buf[rbytes] = '\0'; - /* Remove trailing carriage return(s). */ - if (rbytes > 2 && buf[rbytes - 2] == '\r' && buf[rbytes - 1] == '\n') - buf[rbytes - 2] = '\0'; - - return (buf); -} - -#else /* _WIN32 && !__CYGWIN__ */ - -#include -#include -#include -#ifdef HAVE_PATHS_H -#include -#endif -#include -#include -#include -#include - -#ifndef _PATH_TTY -#define _PATH_TTY "/dev/tty" -#endif - -#ifdef TCSASOFT -# define _T_FLUSH (TCSAFLUSH|TCSASOFT) -#else -# define _T_FLUSH (TCSAFLUSH) -#endif - -/* SunOS 4.x which lacks _POSIX_VDISABLE, but has VDISABLE */ -#if !defined(_POSIX_VDISABLE) && defined(VDISABLE) -# define _POSIX_VDISABLE VDISABLE -#endif - -#define M(a,b) (a > b ? a : b) -#define MAX_SIGNO M(M(M(SIGALRM, SIGHUP), \ - M(SIGINT, SIGPIPE)), \ - M(M(SIGQUIT, SIGTERM), \ - M(M(SIGTSTP, SIGTTIN), SIGTTOU))) - -static volatile sig_atomic_t signo[MAX_SIGNO + 1]; - -static void -handler(int s) -{ - assert(s <= MAX_SIGNO); - signo[s] = 1; -} - -static char * -readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) -{ - ssize_t nr; - int input, output, save_errno, i, need_restart; - char ch, *p, *end; - struct termios term, oterm; -#ifdef HAVE_SIGACTION - struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm; - struct sigaction savetstp, savettin, savettou, savepipe; -#endif - - /* I suppose we could alloc on demand in this case (XXX). */ - if (bufsiz == 0) { - errno = EINVAL; - return(NULL); - } - -restart: - for (i = 0; i <= MAX_SIGNO; i++) - signo[i] = 0; - nr = -1; - save_errno = 0; - need_restart = 0; - /* - * Read and write to /dev/tty if available. If not, read from - * stdin and write to stderr unless a tty is required. - */ - if ((flags & RPP_STDIN) || - (input = output = open(_PATH_TTY, O_RDWR)) == -1) { - if (flags & RPP_REQUIRE_TTY) { - errno = ENOTTY; - return(NULL); - } - input = STDIN_FILENO; - output = STDERR_FILENO; - } - - /* - * Turn off echo if possible. - * If we are using a tty but are not the foreground pgrp this will - * generate SIGTTOU, so do it *before* installing the signal handlers. - */ - if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) { - memcpy(&term, &oterm, sizeof(term)); - if (!(flags & RPP_ECHO_ON)) - term.c_lflag &= ~(ECHO | ECHONL); -#ifdef VSTATUS - if (term.c_cc[VSTATUS] != _POSIX_VDISABLE) - term.c_cc[VSTATUS] = _POSIX_VDISABLE; -#endif - (void)tcsetattr(input, _T_FLUSH, &term); - } else { - memset(&term, 0, sizeof(term)); - term.c_lflag |= ECHO; - memset(&oterm, 0, sizeof(oterm)); - oterm.c_lflag |= ECHO; - } - -#ifdef HAVE_SIGACTION - /* - * Catch signals that would otherwise cause the user to end - * up with echo turned off in the shell. Don't worry about - * things like SIGXCPU and SIGVTALRM for now. - */ - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; /* don't restart system calls */ - sa.sa_handler = handler; - /* Keep this list in sync with MAX_SIGNO! */ - (void)sigaction(SIGALRM, &sa, &savealrm); - (void)sigaction(SIGHUP, &sa, &savehup); - (void)sigaction(SIGINT, &sa, &saveint); - (void)sigaction(SIGPIPE, &sa, &savepipe); - (void)sigaction(SIGQUIT, &sa, &savequit); - (void)sigaction(SIGTERM, &sa, &saveterm); - (void)sigaction(SIGTSTP, &sa, &savetstp); - (void)sigaction(SIGTTIN, &sa, &savettin); - (void)sigaction(SIGTTOU, &sa, &savettou); -#endif - - if (!(flags & RPP_STDIN)) { - int r = write(output, prompt, strlen(prompt)); - (void)r; - } - end = buf + bufsiz - 1; - p = buf; - while ((nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r') { - if (p < end) { - if ((flags & RPP_SEVENBIT)) - ch &= 0x7f; - if (isalpha((unsigned char)ch)) { - if ((flags & RPP_FORCELOWER)) - ch = (char)tolower((unsigned char)ch); - if ((flags & RPP_FORCEUPPER)) - ch = (char)toupper((unsigned char)ch); - } - *p++ = ch; - } - } - *p = '\0'; - save_errno = errno; - if (!(term.c_lflag & ECHO)) { - int r = write(output, "\n", 1); - (void)r; - } - - /* Restore old terminal settings and signals. */ - if (memcmp(&term, &oterm, sizeof(term)) != 0) { - const int sigttou = signo[SIGTTOU]; - - /* Ignore SIGTTOU generated when we are not the fg pgrp. */ - while (tcsetattr(input, _T_FLUSH, &oterm) == -1 && - errno == EINTR && !signo[SIGTTOU]) - continue; - signo[SIGTTOU] = sigttou; - } -#ifdef HAVE_SIGACTION - (void)sigaction(SIGALRM, &savealrm, NULL); - (void)sigaction(SIGHUP, &savehup, NULL); - (void)sigaction(SIGINT, &saveint, NULL); - (void)sigaction(SIGQUIT, &savequit, NULL); - (void)sigaction(SIGPIPE, &savepipe, NULL); - (void)sigaction(SIGTERM, &saveterm, NULL); - (void)sigaction(SIGTSTP, &savetstp, NULL); - (void)sigaction(SIGTTIN, &savettin, NULL); - (void)sigaction(SIGTTOU, &savettou, NULL); -#endif - if (input != STDIN_FILENO) - (void)close(input); - - /* - * If we were interrupted by a signal, resend it to ourselves - * now that we have restored the signal handlers. - */ - for (i = 0; i <= MAX_SIGNO; i++) { - if (signo[i]) { - kill(getpid(), i); - switch (i) { - case SIGTSTP: - case SIGTTIN: - case SIGTTOU: - need_restart = 1; - } - } - } - if (need_restart) - goto restart; - - if (save_errno) - errno = save_errno; - return(nr == -1 ? NULL : buf); -} -#endif /* _WIN32 && !__CYGWIN__ */ -#endif /* HAVE_READPASSPHRASE */ - -char * -lafe_readpassphrase(const char *prompt, char *buf, size_t bufsiz) -{ - char *p; - - p = readpassphrase(prompt, buf, bufsiz, RPP_ECHO_OFF); - if (p == NULL) { - switch (errno) { - case EINTR: - break; - default: - lafe_errc(1, errno, "Couldn't read passphrase"); - break; - } - } - return (p); -} - diff --git a/thirdparty/libarchive/libarchive_fe/passphrase.h b/thirdparty/libarchive/libarchive_fe/passphrase.h deleted file mode 100644 index ac7a50636..000000000 --- a/thirdparty/libarchive/libarchive_fe/passphrase.h +++ /dev/null @@ -1,31 +0,0 @@ -/*- - * Copyright (c) 2014 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#ifndef LAFE_PASSPHRASE_H -#define LAFE_PASSPHRASE_H - -char *lafe_readpassphrase(const char *prompt, char *buf, size_t bufsiz); - -#endif diff --git a/thirdparty/libarchive/tar/CMakeLists.txt b/thirdparty/libarchive/tar/CMakeLists.txt deleted file mode 100644 index 6434791f7..000000000 --- a/thirdparty/libarchive/tar/CMakeLists.txt +++ /dev/null @@ -1,50 +0,0 @@ -############################################ -# -# How to build bsdtar -# -############################################ -IF(ENABLE_TAR) - - SET(bsdtar_SOURCES - bsdtar.c - bsdtar.h - bsdtar_platform.h - cmdline.c - creation_set.c - read.c - subst.c - util.c - write.c - ../libarchive_fe/err.c - ../libarchive_fe/err.h - ../libarchive_fe/lafe_platform.h - ../libarchive_fe/line_reader.c - ../libarchive_fe/line_reader.h - ../libarchive_fe/passphrase.c - ../libarchive_fe/passphrase.h - ) - INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libarchive_fe) - IF(WIN32 AND NOT CYGWIN) - LIST(APPEND bsdtar_SOURCES bsdtar_windows.c) - LIST(APPEND bsdtar_SOURCES bsdtar_windows.h) - ENDIF(WIN32 AND NOT CYGWIN) - - # bsdtar documentation - SET(bsdtar_MANS bsdtar.1) - - # How to build bsdtar - ADD_EXECUTABLE(bsdtar ${bsdtar_SOURCES}) - IF(ENABLE_TAR_SHARED) - TARGET_LINK_LIBRARIES(bsdtar archive ${ADDITIONAL_LIBS}) - ELSE(ENABLE_TAR_SHARED) - TARGET_LINK_LIBRARIES(bsdtar archive_static ${ADDITIONAL_LIBS}) - SET_TARGET_PROPERTIES(bsdtar PROPERTIES COMPILE_DEFINITIONS - LIBARCHIVE_STATIC) - ENDIF(ENABLE_TAR_SHARED) - - # Installation rules - INSTALL(TARGETS bsdtar RUNTIME DESTINATION bin) - INSTALL_MAN(${bsdtar_MANS}) -ENDIF(ENABLE_TAR) - -add_subdirectory(test) diff --git a/thirdparty/libarchive/tar/bsdtar.1 b/thirdparty/libarchive/tar/bsdtar.1 deleted file mode 100644 index 1b78fbc04..000000000 --- a/thirdparty/libarchive/tar/bsdtar.1 +++ /dev/null @@ -1,1355 +0,0 @@ -.\" Copyright (c) 2003-2007 Tim Kientzle -.\" Copyright (c) 2017 Martin Matuska -.\" 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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd December 1, 2022 -.Dt TAR 1 -.Os -.Sh NAME -.Nm tar -.Nd manipulate tape archives -.Sh SYNOPSIS -.Nm -.Op Ar bundled-flags Ao args Ac -.Op Ao Ar file Ac | Ao Ar pattern Ac ... -.Nm -.Brq Fl c -.Op Ar options -.Op Ar files | Ar directories -.Nm -.Brq Fl r | Fl u -.Fl f Ar archive-file -.Op Ar options -.Op Ar files | Ar directories -.Nm -.Brq Fl t | Fl x -.Op Ar options -.Op Ar patterns -.Sh DESCRIPTION -.Nm -creates and manipulates streaming archive files. -This implementation can extract from tar, pax, cpio, zip, jar, ar, xar, -rpm, 7-zip, and ISO 9660 cdrom images and can create tar, pax, cpio, ar, zip, -7-zip, and shar archives. -.Pp -The first synopsis form shows a -.Dq bundled -option word. -This usage is provided for compatibility with historical implementations. -See COMPATIBILITY below for details. -.Pp -The other synopsis forms show the preferred usage. -The first option to -.Nm -is a mode indicator from the following list: -.Bl -tag -compact -width indent -.It Fl c -Create a new archive containing the specified items. -The long option form is -.Fl Fl create . -.It Fl r -Like -.Fl c , -but new entries are appended to the archive. -Note that this only works on uncompressed archives stored in regular files. -The -.Fl f -option is required. -The long option form is -.Fl Fl append . -.It Fl t -List archive contents to stdout. -The long option form is -.Fl Fl list . -.It Fl u -Like -.Fl r , -but new entries are added only if they have a modification date -newer than the corresponding entry in the archive. -Note that this only works on uncompressed archives stored in regular files. -The -.Fl f -option is required. -The long form is -.Fl Fl update . -.It Fl x -Extract to disk from the archive. -If a file with the same name appears more than once in the archive, -each copy will be extracted, with later copies overwriting (replacing) -earlier copies. -The long option form is -.Fl Fl extract . -.El -.Pp -In -.Fl c , -.Fl r , -or -.Fl u -mode, each specified file or directory is added to the -archive in the order specified on the command line. -By default, the contents of each directory are also archived. -.Pp -In extract or list mode, the entire command line -is read and parsed before the archive is opened. -The pathnames or patterns on the command line indicate -which items in the archive should be processed. -Patterns are shell-style globbing patterns as -documented in -.Xr tcsh 1 . -.Sh OPTIONS -Unless specifically stated otherwise, options are applicable in -all operating modes. -.Bl -tag -width indent -.It Cm @ Ns Pa archive -(c and r modes only) -The specified archive is opened and the entries -in it will be appended to the current archive. -As a simple example, -.Dl Nm Fl c Fl f Pa - Pa newfile Cm @ Ns Pa original.tar -writes a new archive to standard output containing a file -.Pa newfile -and all of the entries from -.Pa original.tar . -In contrast, -.Dl Nm Fl c Fl f Pa - Pa newfile Pa original.tar -creates a new archive with only two entries. -Similarly, -.Dl Nm Fl czf Pa - Fl Fl format Cm pax Cm @ Ns Pa - -reads an archive from standard input (whose format will be determined -automatically) and converts it into a gzip-compressed -pax-format archive on stdout. -In this way, -.Nm -can be used to convert archives from one format to another. -.It Fl a , Fl Fl auto-compress -(c mode only) -Use the archive suffix to decide a set of the format and -the compressions. -As a simple example, -.Dl Nm Fl a Fl cf Pa archive.tgz source.c source.h -creates a new archive with restricted pax format and gzip compression, -.Dl Nm Fl a Fl cf Pa archive.tar.bz2.uu source.c source.h -creates a new archive with restricted pax format and bzip2 compression -and uuencode compression, -.Dl Nm Fl a Fl cf Pa archive.zip source.c source.h -creates a new archive with zip format, -.Dl Nm Fl a Fl jcf Pa archive.tgz source.c source.h -ignores the -.Dq -j -option, and creates a new archive with restricted pax format -and gzip compression, -.Dl Nm Fl a Fl jcf Pa archive.xxx source.c source.h -if it is unknown suffix or no suffix, creates a new archive with -restricted pax format and bzip2 compression. -.It Fl Fl acls -(c, r, u, x modes only) -Archive or extract POSIX.1e or NFSv4 ACLs. -This is the reverse of -.Fl Fl no-acls -and the default behavior in c, r, and u modes (except on Mac OS X) or if -.Nm -is run in x mode as root. -On Mac OS X this option translates extended ACLs to NFSv4 ACLs. -To store extended ACLs the -.Fl Fl mac-metadata -option is preferred. -.It Fl B , Fl Fl read-full-blocks -Ignored for compatibility with other -.Xr tar 1 -implementations. -.It Fl b Ar blocksize , Fl Fl block-size Ar blocksize -Specify the block size, in 512-byte records, for tape drive I/O. -As a rule, this argument is only needed when reading from or writing -to tape drives, and usually not even then as the default block size of -20 records (10240 bytes) is very common. -.It Fl C Ar directory , Fl Fl cd Ar directory , Fl Fl directory Ar directory -In c and r mode, this changes the directory before adding -the following files. -In x mode, change directories after opening the archive -but before extracting entries from the archive. -.It Fl Fl chroot -(x mode only) -.Fn chroot -to the current directory after processing any -.Fl C -options and before extracting any files. -.It Fl Fl clear-nochange-fflags -(x mode only) -Before removing file system objects to replace them, clear platform-specific -file attributes or file flags that might prevent removal. -.It Fl Fl exclude Ar pattern -Do not process files or directories that match the -specified pattern. -Note that exclusions take precedence over patterns or filenames -specified on the command line. -.It Fl Fl exclude-vcs -Do not process files or directories internally used by the -version control systems -.Sq Arch , -.Sq Bazaar , -.Sq CVS , -.Sq Darcs , -.Sq Mercurial , -.Sq RCS , -.Sq SCCS , -.Sq SVN -and -.Sq git . -.It Fl Fl fflags -(c, r, u, x modes only) -Archive or extract platform-specific file attributes or file flags. -This is the reverse of -.Fl Fl no-fflags -and the default behavior in c, r, and u modes or if -.Nm -is run in x mode as root. -.It Fl Fl format Ar format -(c, r, u mode only) -Use the specified format for the created archive. -Supported formats include -.Dq cpio , -.Dq pax , -.Dq shar , -and -.Dq ustar . -Other formats may also be supported; see -.Xr libarchive-formats 5 -for more information about currently-supported formats. -In r and u modes, when extending an existing archive, the format specified -here must be compatible with the format of the existing archive on disk. -.It Fl f Ar file , Fl Fl file Ar file -Read the archive from or write the archive to the specified file. -The filename can be -.Pa - -for standard input or standard output. -The default varies by system; -on -.Fx , -the default is -.Pa /dev/sa0 ; -on Linux, the default is -.Pa /dev/st0 . -.It Fl Fl gid Ar id -Use the provided group id number. -On extract, this overrides the group id in the archive; -the group name in the archive will be ignored. -On create, this overrides the group id read from disk; -if -.Fl Fl gname -is not also specified, the group name will be set to -match the group id. -.It Fl Fl gname Ar name -Use the provided group name. -On extract, this overrides the group name in the archive; -if the provided group name does not exist on the system, -the group id -(from the archive or from the -.Fl Fl gid -option) -will be used instead. -On create, this sets the group name that will be stored -in the archive; -the name will not be verified against the system group database. -.It Fl H -(c and r modes only) -Symbolic links named on the command line will be followed; the -target of the link will be archived, not the link itself. -.It Fl h -(c and r modes only) -Synonym for -.Fl L . -.It Fl I -Synonym for -.Fl T . -.It Fl Fl help -Show usage. -.It Fl Fl hfsCompression -(x mode only) -Mac OS X specific (v10.6 or later). Compress extracted regular files with HFS+ -compression. -.It Fl Fl ignore-zeros -An alias of -.Fl Fl options Cm read_concatenated_archives -for compatibility with GNU tar. -.It Fl Fl include Ar pattern -Process only files or directories that match the specified pattern. -Note that exclusions specified with -.Fl Fl exclude -take precedence over inclusions. -If no inclusions are explicitly specified, all entries are processed by -default. -The -.Fl Fl include -option is especially useful when filtering archives. -For example, the command -.Dl Nm Fl c Fl f Pa new.tar Fl Fl include='*foo*' Cm @ Ns Pa old.tgz -creates a new archive -.Pa new.tar -containing only the entries from -.Pa old.tgz -containing the string -.Sq foo . -.It Fl J , Fl Fl xz -(c mode only) -Compress the resulting archive with -.Xr xz 1 . -In extract or list modes, this option is ignored. -Note that this -.Nm tar -implementation recognizes XZ compression automatically when reading archives. -.It Fl j , Fl Fl bzip , Fl Fl bzip2 , Fl Fl bunzip2 -(c mode only) -Compress the resulting archive with -.Xr bzip2 1 . -In extract or list modes, this option is ignored. -Note that this -.Nm tar -implementation recognizes bzip2 compression automatically when reading -archives. -.It Fl k , Fl Fl keep-old-files -(x mode only) -Do not overwrite existing files. -In particular, if a file appears more than once in an archive, -later copies will not overwrite earlier copies. -.It Fl Fl keep-newer-files -(x mode only) -Do not overwrite existing files that are newer than the -versions appearing in the archive being extracted. -.It Fl L , Fl Fl dereference -(c and r modes only) -All symbolic links will be followed. -Normally, symbolic links are archived as such. -With this option, the target of the link will be archived instead. -.It Fl l , Fl Fl check-links -(c and r modes only) -Issue a warning message unless all links to each file are archived. -.It Fl Fl lrzip -(c mode only) -Compress the resulting archive with -.Xr lrzip 1 . -In extract or list modes, this option is ignored. -Note that this -.Nm tar -implementation recognizes lrzip compression automatically when reading -archives. -.It Fl Fl lz4 -(c mode only) -Compress the archive with lz4-compatible compression before writing it. -In extract or list modes, this option is ignored. -Note that this -.Nm tar -implementation recognizes lz4 compression automatically when reading archives. -.It Fl Fl zstd -(c mode only) -Compress the archive with zstd-compatible compression before writing it. -In extract or list modes, this option is ignored. -Note that this -.Nm tar -implementation recognizes zstd compression automatically when reading archives. -.It Fl Fl lzma -(c mode only) Compress the resulting archive with the original LZMA algorithm. -In extract or list modes, this option is ignored. -Use of this option is discouraged and new archives should be created with -.Fl Fl xz -instead. -Note that this -.Nm tar -implementation recognizes LZMA compression automatically when reading archives. -.It Fl Fl lzop -(c mode only) -Compress the resulting archive with -.Xr lzop 1 . -In extract or list modes, this option is ignored. -Note that this -.Nm tar -implementation recognizes LZO compression automatically when reading archives. -.It Fl m , Fl Fl modification-time -(x mode only) -Do not extract modification time. -By default, the modification time is set to the time stored in the archive. -.It Fl Fl mac-metadata -(c, r, u and x mode only) -Mac OS X specific. -Archive or extract extended ACLs and extended file -attributes using -.Xr copyfile 3 -in AppleDouble format. -This is the reverse of -.Fl Fl no-mac-metadata . -and the default behavior in c, r, and u modes or if -.Nm -is run in x mode as root. -.It Fl n , Fl Fl norecurse , Fl Fl no-recursion -Do not operate recursively on the content of directories. -.It Fl Fl newer Ar date -(c, r, u modes only) -Only include files and directories newer than the specified date. -This compares ctime entries. -.It Fl Fl newer-mtime Ar date -(c, r, u modes only) -Like -.Fl Fl newer , -except it compares mtime entries instead of ctime entries. -.It Fl Fl newer-than Pa file -(c, r, u modes only) -Only include files and directories newer than the specified file. -This compares ctime entries. -.It Fl Fl newer-mtime-than Pa file -(c, r, u modes only) -Like -.Fl Fl newer-than , -except it compares mtime entries instead of ctime entries. -.It Fl Fl nodump -(c and r modes only) -Honor the nodump file flag by skipping this file. -.It Fl Fl nopreserveHFSCompression -(x mode only) -Mac OS X specific (v10.6 or later). Do not compress extracted regular files -which were compressed with HFS+ compression before archived. -By default, compress the regular files again with HFS+ compression. -.It Fl Fl null -(use with -.Fl I -or -.Fl T ) -Filenames or patterns are separated by null characters, -not by newlines. -This is often used to read filenames output by the -.Fl print0 -option to -.Xr find 1 . -.It Fl Fl no-acls -(c, r, u, x modes only) -Do not archive or extract POSIX.1e or NFSv4 ACLs. -This is the reverse of -.Fl Fl acls -and the default behavior if -.Nm -is run as non-root in x mode (on Mac OS X as any user in c, r, u and x modes). -.It Fl Fl no-fflags -(c, r, u, x modes only) -Do not archive or extract file attributes or file flags. -This is the reverse of -.Fl Fl fflags -and the default behavior if -.Nm -is run as non-root in x mode. -.It Fl Fl no-mac-metadata -(x mode only) -Mac OS X specific. -Do not archive or extract ACLs and extended file attributes -using -.Xr copyfile 3 -in AppleDouble format. -This is the reverse of -.Fl Fl mac-metadata . -and the default behavior if -.Nm -is run as non-root in x mode. -.It Fl Fl no-read-sparse -(c, r, u modes only) -Do not read sparse file information from disk. -This is the reverse of -.Fl Fl read-sparse . -.It Fl Fl no-safe-writes -(x mode only) -Do not create temporary files and use -.Xr rename 2 -to replace the original ones. -This is the reverse of -.Fl Fl safe-writes . -.It Fl Fl no-same-owner -(x mode only) -Do not extract owner and group IDs. -This is the reverse of -.Fl Fl same-owner -and the default behavior if -.Nm -is run as non-root. -.It Fl Fl no-same-permissions -(x mode only) -Do not extract full permissions (SGID, SUID, sticky bit, -file attributes or file flags, extended file attributes and ACLs). -This is the reverse of -.Fl p -and the default behavior if -.Nm -is run as non-root. -.It Fl Fl no-xattrs -(c, r, u, x modes only) -Do not archive or extract extended file attributes. -This is the reverse of -.Fl Fl xattrs -and the default behavior if -.Nm -is run as non-root in x mode. -.It Fl Fl numeric-owner -This is equivalent to -.Fl Fl uname -.Qq -.Fl Fl gname -.Qq . -On extract, it causes user and group names in the archive -to be ignored in favor of the numeric user and group ids. -On create, it causes user and group names to not be stored -in the archive. -.It Fl O , Fl Fl to-stdout -(x, t modes only) -In extract (-x) mode, files will be written to standard out rather than -being extracted to disk. -In list (-t) mode, the file listing will be written to stderr rather than -the usual stdout. -.It Fl o -(x mode) -Use the user and group of the user running the program rather -than those specified in the archive. -Note that this has no significance unless -.Fl p -is specified, and the program is being run by the root user. -In this case, the file modes and flags from -the archive will be restored, but ACLs or owner information in -the archive will be discarded. -.It Fl o -(c, r, u mode) -A synonym for -.Fl Fl format Ar ustar -.It Fl Fl older Ar date -(c, r, u modes only) -Only include files and directories older than the specified date. -This compares ctime entries. -.It Fl Fl older-mtime Ar date -(c, r, u modes only) -Like -.Fl Fl older , -except it compares mtime entries instead of ctime entries. -.It Fl Fl older-than Pa file -(c, r, u modes only) -Only include files and directories older than the specified file. -This compares ctime entries. -.It Fl Fl older-mtime-than Pa file -(c, r, u modes only) -Like -.Fl Fl older-than , -except it compares mtime entries instead of ctime entries. -.It Fl Fl one-file-system -(c, r, and u modes) -Do not cross mount points. -.It Fl Fl options Ar options -Select optional behaviors for particular modules. -The argument is a text string containing comma-separated -keywords and values. -These are passed to the modules that handle particular -formats to control how those formats will behave. -Each option has one of the following forms: -.Bl -tag -compact -width indent -.It Ar key=value -The key will be set to the specified value in every module that supports it. -Modules that do not support this key will ignore it. -.It Ar key -The key will be enabled in every module that supports it. -This is equivalent to -.Ar key Ns Cm =1 . -.It Ar !key -The key will be disabled in every module that supports it. -.It Ar module:key=value , Ar module:key , Ar module:!key -As above, but the corresponding key and value will be provided -only to modules whose name matches -.Ar module . -.El -.Pp -The complete list of supported modules and keys -for create and append modes is in -.Xr archive_write_set_options 3 -and for extract and list modes in -.Xr archive_read_set_options 3 . -.Pp -Examples of supported options: -.Bl -tag -compact -width indent -.It Cm iso9660:joliet -Support Joliet extensions. -This is enabled by default, use -.Cm !joliet -or -.Cm iso9660:!joliet -to disable. -.It Cm iso9660:rockridge -Support Rock Ridge extensions. -This is enabled by default, use -.Cm !rockridge -or -.Cm iso9660:!rockridge -to disable. -.It Cm gzip:compression-level -A decimal integer from 1 to 9 specifying the gzip compression level. -.It Cm gzip:timestamp -Store timestamp. -This is enabled by default, use -.Cm !timestamp -or -.Cm gzip:!timestamp -to disable. -.It Cm lrzip:compression Ns = Ns Ar type -Use -.Ar type -as compression method. -Supported values are bzip2, gzip, lzo (ultra fast), -and zpaq (best, extremely slow). -.It Cm lrzip:compression-level -A decimal integer from 1 to 9 specifying the lrzip compression level. -.It Cm lz4:compression-level -A decimal integer from 1 to 9 specifying the lzop compression level. -.It Cm lz4:stream-checksum -Enable stream checksum. -This is by default, use -.Cm lz4:!stream-checksum -to disable. -.It Cm lz4:block-checksum -Enable block checksum (Disabled by default). -.It Cm lz4:block-size -A decimal integer from 4 to 7 specifying the lz4 compression block size -(7 is set by default). -.It Cm lz4:block-dependence -Use the previous block of the block being compressed for -a compression dictionary to improve compression ratio. -.It Cm zstd:compression-level -A decimal integer specifying the zstd compression level. Supported values depend -on the library version, common values are from 1 to 22. -.It Cm zstd:threads -Specify the number of worker threads to use. -Setting threads to a special value 0 makes -.Xr zstd 1 -use as many threads as there are CPU cores on the system. -.It Cm zstd:frame-per-file -Start a new compression frame at the beginning of each file in the -archive. -.It Cm zstd:min-frame-size Ns = Ns Ar N -In combination with -.Cm zstd:frame-per-file , -do not start a new compression frame unless the current frame is at least -.Ar N -bytes. -.It Cm zstd:max-frame-size Ns = Ns Ar N -Start a new compression frame as soon as the current frame exceeds -.Ar N -bytes. -.It Cm lzop:compression-level -A decimal integer from 1 to 9 specifying the lzop compression level. -.It Cm xz:compression-level -A decimal integer from 0 to 9 specifying the xz compression level. -.It Cm xz:threads -Specify the number of worker threads to use. -Setting threads to a special value 0 makes -.Xr xz 1 -use as many threads as there are CPU cores on the system. -.It Cm mtree: Ns Ar keyword -The mtree writer module allows you to specify which mtree keywords -will be included in the output. -Supported keywords include: -.Cm cksum , Cm device , Cm flags , Cm gid , Cm gname , Cm indent , -.Cm link , Cm md5 , Cm mode , Cm nlink , Cm rmd160 , Cm sha1 , Cm sha256 , -.Cm sha384 , Cm sha512 , Cm size , Cm time , Cm uid , Cm uname . -The default is equivalent to: -.Dq device, flags, gid, gname, link, mode, nlink, size, time, type, uid, uname . -.It Cm mtree:all -Enables all of the above keywords. -You can also use -.Cm mtree:!all -to disable all keywords. -.It Cm mtree:use-set -Enable generation of -.Cm /set -lines in the output. -.It Cm mtree:indent -Produce human-readable output by indenting options and splitting lines -to fit into 80 columns. -.It Cm zip:compression Ns = Ns Ar type -Use -.Ar type -as compression method. -Supported values are store (uncompressed) and deflate (gzip algorithm). -.It Cm zip:encryption -Enable encryption using traditional zip encryption. -.It Cm zip:encryption Ns = Ns Ar type -Use -.Ar type -as encryption type. -Supported values are zipcrypt (traditional zip encryption), -aes128 (WinZip AES-128 encryption) and aes256 (WinZip AES-256 encryption). -.It Cm read_concatenated_archives -Ignore zeroed blocks in the archive, which occurs when multiple tar archives -have been concatenated together. -Without this option, only the contents of -the first concatenated archive would be read. -This option is comparable to the -.Fl i , Fl Fl ignore-zeros -option of GNU tar. -.El -If a provided option is not supported by any module, that -is a fatal error. -.It Fl P , Fl Fl absolute-paths -Preserve pathnames. -By default, absolute pathnames (those that begin with a / -character) have the leading slash removed both when creating archives -and extracting from them. -Also, -.Nm -will refuse to extract archive entries whose pathnames contain -.Pa .. -or whose target directory would be altered by a symlink. -This option suppresses these behaviors. -.It Fl p , Fl Fl insecure , Fl Fl preserve-permissions -(x mode only) -Preserve file permissions. -Attempt to restore the full permissions, including file modes, file attributes -or file flags, extended file attributes and ACLs, if available, for each item -extracted from the archive. -This is the reverse of -.Fl Fl no-same-permissions -and the default if -.Nm -is being run as root. -It can be partially overridden by also specifying -.Fl Fl no-acls , -.Fl Fl no-fflags , -.Fl Fl no-mac-metadata -or -.Fl Fl no-xattrs . -.It Fl Fl passphrase Ar passphrase -The -.Pa passphrase -is used to extract or create an encrypted archive. -Currently, zip is the only supported format that supports encryption. -You shouldn't use this option unless you realize how insecure -use of this option is. -.It Fl Fl posix -(c, r, u mode only) -Synonym for -.Fl Fl format Ar pax -.It Fl q , Fl Fl fast-read -(x and t mode only) -Extract or list only the first archive entry that matches each pattern -or filename operand. -Exit as soon as each specified pattern or filename has been matched. -By default, the archive is always read to the very end, since -there can be multiple entries with the same name and, by convention, -later entries overwrite earlier entries. -This option is provided as a performance optimization. -.It Fl Fl read-sparse -(c, r, u modes only) -Read sparse file information from disk. -This is the reverse of -.Fl Fl no-read-sparse -and the default behavior. -.It Fl S -(x mode only) -Extract files as sparse files. -For every block on disk, check first if it contains only NULL bytes and seek -over it otherwise. -This works similar to the conv=sparse option of dd. -.It Fl s Ar pattern -Modify file or archive member names according to -.Pa pattern . -The pattern has the format -.Ar /old/new/ Ns Op ghHprRsS -where -.Ar old -is a basic regular expression, -.Ar new -is the replacement string of the matched part, -and the optional trailing letters modify -how the replacement is handled. -If -.Ar old -is not matched, the pattern is skipped. -Within -.Ar new , -~ is substituted with the match, \e1 to \e9 with the content of -the corresponding captured group. -The optional trailing g specifies that matching should continue -after the matched part and stop on the first unmatched pattern. -The optional trailing s specifies that the pattern applies to the value -of symbolic links. -The optional trailing p specifies that after a successful substitution -the original path name and the new path name should be printed to -standard error. -Optional trailing H, R, or S characters suppress substitutions -for hardlink targets, regular filenames, or symlink targets, -respectively. -Optional trailing h, r, or s characters enable substitutions -for hardlink targets, regular filenames, or symlink targets, -respectively. -The default is -.Ar hrs -which applies substitutions to all names. -In particular, it is never necessary to specify h, r, or s. -.It Fl Fl safe-writes -(x mode only) -Extract files atomically. -By default -.Nm -unlinks the original file with the same name as the extracted file (if it -exists), and then creates it immediately under the same name and writes to -it. -For a short period of time, applications trying to access the file might -not find it, or see incomplete results. -If -.Fl Fl safe-writes -is enabled, -.Nm -first creates a unique temporary file, then writes the new contents to -the temporary file, and finally renames the temporary file to its final -name atomically using -.Xr rename 2 . -This guarantees that an application accessing the file, will either see -the old contents or the new contents at all times. -.It Fl Fl same-owner -(x mode only) -Extract owner and group IDs. -This is the reverse of -.Fl Fl no-same-owner -and the default behavior if -.Nm -is run as root. -.It Fl Fl strip-components Ar count -Remove the specified number of leading path elements. -Pathnames with fewer elements will be silently skipped. -Note that the pathname is edited after checking inclusion/exclusion patterns -but before security checks. -.It Fl T Ar filename , Fl Fl files-from Ar filename -In x or t mode, -.Nm -will read the list of names to be extracted from -.Pa filename . -In c mode, -.Nm -will read names to be archived from -.Pa filename . -The special name -.Dq -C -on a line by itself will cause the current directory to be changed to -the directory specified on the following line. -Names are terminated by newlines unless -.Fl Fl null -is specified. -Note that -.Fl Fl null -also disables the special handling of lines containing -.Dq -C . -Note: If you are generating lists of files using -.Xr find 1 , -you probably want to use -.Fl n -as well. -.It Fl Fl totals -(c, r, u modes only) -After archiving all files, print a summary to stderr. -.It Fl U , Fl Fl unlink , Fl Fl unlink-first -(x mode only) -Unlink files before creating them. -This can be a minor performance optimization if most files -already exist, but can make things slower if most files -do not already exist. -This flag also causes -.Nm -to remove intervening directory symlinks instead of -reporting an error. -See the SECURITY section below for more details. -.It Fl Fl uid Ar id -Use the provided user id number and ignore the user -name from the archive. -On create, if -.Fl Fl uname -is not also specified, the user name will be set to -match the user id. -.It Fl Fl uname Ar name -Use the provided user name. -On extract, this overrides the user name in the archive; -if the provided user name does not exist on the system, -it will be ignored and the user id -(from the archive or from the -.Fl Fl uid -option) -will be used instead. -On create, this sets the user name that will be stored -in the archive; -the name is not verified against the system user database. -.It Fl Fl use-compress-program Ar program -Pipe the input (in x or t mode) or the output (in c mode) through -.Pa program -instead of using the builtin compression support. -.It Fl v , Fl Fl verbose -Produce verbose output. -In create and extract modes, -.Nm -will list each file name as it is read from or written to -the archive. -In list mode, -.Nm -will produce output similar to that of -.Xr ls 1 . -An additional -.Fl v -option will also provide ls-like details in create and extract mode. -.It Fl Fl version -Print version of -.Nm -and -.Nm libarchive , -and exit. -.It Fl w , Fl Fl confirmation , Fl Fl interactive -Ask for confirmation for every action. -.It Fl X Ar filename , Fl Fl exclude-from Ar filename -Read a list of exclusion patterns from the specified file. -See -.Fl Fl exclude -for more information about the handling of exclusions. -.It Fl Fl xattrs -(c, r, u, x modes only) -Archive or extract extended file attributes. -This is the reverse of -.Fl Fl no-xattrs -and the default behavior in c, r, and u modes or if -.Nm -is run in x mode as root. -.It Fl y -(c mode only) -Compress the resulting archive with -.Xr bzip2 1 . -In extract or list modes, this option is ignored. -Note that this -.Nm tar -implementation recognizes bzip2 compression automatically when reading -archives. -.It Fl Z , Fl Fl compress , Fl Fl uncompress -(c mode only) -Compress the resulting archive with -.Xr compress 1 . -In extract or list modes, this option is ignored. -Note that this -.Nm tar -implementation recognizes compress compression automatically when reading -archives. -.It Fl z , Fl Fl gunzip , Fl Fl gzip -(c mode only) -Compress the resulting archive with -.Xr gzip 1 . -In extract or list modes, this option is ignored. -Note that this -.Nm tar -implementation recognizes gzip compression automatically when reading -archives. -.El -.Sh ENVIRONMENT -The following environment variables affect the execution of -.Nm : -.Bl -tag -width indent -.It Ev TAR_READER_OPTIONS -The default options for format readers and compression readers. -The -.Fl Fl options -option overrides this. -.It Ev TAR_WRITER_OPTIONS -The default options for format writers and compression writers. -The -.Fl Fl options -option overrides this. -.It Ev LANG -The locale to use. -See -.Xr environ 7 -for more information. -.It Ev TAPE -The default device. -The -.Fl f -option overrides this. -Please see the description of the -.Fl f -option above for more details. -.It Ev TZ -The timezone to use when displaying dates. -See -.Xr environ 7 -for more information. -.El -.Sh EXIT STATUS -.Ex -std -.Sh EXAMPLES -The following creates a new archive -called -.Ar file.tar.gz -that contains two files -.Ar source.c -and -.Ar source.h : -.Dl Nm Fl czf Pa file.tar.gz Pa source.c Pa source.h -.Pp -To view a detailed table of contents for this -archive: -.Dl Nm Fl tvf Pa file.tar.gz -.Pp -To extract all entries from the archive on -the default tape drive: -.Dl Nm Fl x -.Pp -To examine the contents of an ISO 9660 cdrom image: -.Dl Nm Fl tf Pa image.iso -.Pp -To move file hierarchies, invoke -.Nm -as -.Dl Nm Fl cf Pa - Fl C Pa srcdir \&. | Nm Fl xpf Pa - Fl C Pa destdir -or more traditionally -.Dl cd srcdir \&; Nm Fl cf Pa - \&. | ( cd destdir \&; Nm Fl xpf Pa - ) -.Pp -In create mode, the list of files and directories to be archived -can also include directory change instructions of the form -.Cm -C Ns Pa foo/baz -and archive inclusions of the form -.Cm @ Ns Pa archive-file . -For example, the command line -.Dl Nm Fl c Fl f Pa new.tar Pa foo1 Cm @ Ns Pa old.tgz Cm -C Ns Pa /tmp Pa foo2 -will create a new archive -.Pa new.tar . -.Nm -will read the file -.Pa foo1 -from the current directory and add it to the output archive. -It will then read each entry from -.Pa old.tgz -and add those entries to the output archive. -Finally, it will switch to the -.Pa /tmp -directory and add -.Pa foo2 -to the output archive. -.Pp -An input file in -.Xr mtree 5 -format can be used to create an output archive with arbitrary ownership, -permissions, or names that differ from existing data on disk: -.Bd -literal -offset indent -$ cat input.mtree -#mtree -usr/bin uid=0 gid=0 mode=0755 type=dir -usr/bin/ls uid=0 gid=0 mode=0755 type=file content=myls -$ tar -cvf output.tar @input.mtree -.Ed -.Pp -The -.Fl Fl newer -and -.Fl Fl newer-mtime -switches accept a variety of common date and time specifications, including -.Dq 12 Mar 2005 7:14:29pm , -.Dq 2005-03-12 19:14 , -.Dq 5 minutes ago , -and -.Dq 19:14 PST May 1 . -.Pp -The -.Fl Fl options -argument can be used to control various details of archive generation -or reading. -For example, you can generate mtree output which only contains -.Cm type , Cm time , -and -.Cm uid -keywords: -.Dl Nm Fl cf Pa file.tar Fl Fl format=mtree Fl Fl options='!all,type,time,uid' Pa dir -or you can set the compression level used by gzip or xz compression: -.Dl Nm Fl czf Pa file.tar Fl Fl options='compression-level=9' . -For more details, see the explanation of the -.Fn archive_read_set_options -and -.Fn archive_write_set_options -API calls that are described in -.Xr archive_read 3 -and -.Xr archive_write 3 . -.Sh COMPATIBILITY -The bundled-arguments format is supported for compatibility -with historic implementations. -It consists of an initial word (with no leading - character) in which -each character indicates an option. -Arguments follow as separate words. -The order of the arguments must match the order -of the corresponding characters in the bundled command word. -For example, -.Dl Nm Cm tbf 32 Pa file.tar -specifies three flags -.Cm t , -.Cm b , -and -.Cm f . -The -.Cm b -and -.Cm f -flags both require arguments, -so there must be two additional items -on the command line. -The -.Ar 32 -is the argument to the -.Cm b -flag, and -.Ar file.tar -is the argument to the -.Cm f -flag. -.Pp -The mode options c, r, t, u, and x and the options -b, f, l, m, o, v, and w comply with SUSv2. -.Pp -For maximum portability, scripts that invoke -.Nm tar -should use the bundled-argument format above, should limit -themselves to the -.Cm c , -.Cm t , -and -.Cm x -modes, and the -.Cm b , -.Cm f , -.Cm m , -.Cm v , -and -.Cm w -options. -.Pp -Additional long options are provided to improve compatibility with other -tar implementations. -.Sh SECURITY -Certain security issues are common to many archiving programs, including -.Nm . -In particular, carefully-crafted archives can request that -.Nm -extract files to locations outside of the target directory. -This can potentially be used to cause unwitting users to overwrite -files they did not intend to overwrite. -If the archive is being extracted by the superuser, any file -on the system can potentially be overwritten. -There are three ways this can happen. -Although -.Nm -has mechanisms to protect against each one, -savvy users should be aware of the implications: -.Bl -bullet -width indent -.It -Archive entries can have absolute pathnames. -By default, -.Nm -removes the leading -.Pa / -character from filenames before restoring them to guard against this problem. -.It -Archive entries can have pathnames that include -.Pa .. -components. -By default, -.Nm -will not extract files containing -.Pa .. -components in their pathname. -.It -Archive entries can exploit symbolic links to restore -files to other directories. -An archive can restore a symbolic link to another directory, -then use that link to restore a file into that directory. -To guard against this, -.Nm -checks each extracted path for symlinks. -If the final path element is a symlink, it will be removed -and replaced with the archive entry. -If -.Fl U -is specified, any intermediate symlink will also be unconditionally removed. -If neither -.Fl U -nor -.Fl P -is specified, -.Nm -will refuse to extract the entry. -.El -To protect yourself, you should be wary of any archives that -come from untrusted sources. -You should examine the contents of an archive with -.Dl Nm Fl tf Pa filename -before extraction. -You should use the -.Fl k -option to ensure that -.Nm -will not overwrite any existing files or the -.Fl U -option to remove any pre-existing files. -You should generally not extract archives while running with super-user -privileges. -Note that the -.Fl P -option to -.Nm -disables the security checks above and allows you to extract -an archive while preserving any absolute pathnames, -.Pa .. -components, or symlinks to other directories. -.Sh SEE ALSO -.Xr bzip2 1 , -.Xr compress 1 , -.Xr cpio 1 , -.Xr gzip 1 , -.Xr mt 1 , -.Xr pax 1 , -.Xr shar 1 , -.Xr xz 1 , -.Xr libarchive 3 , -.Xr libarchive-formats 5 , -.Xr tar 5 -.Sh STANDARDS -There is no current POSIX standard for the tar command; it appeared -in -.St -p1003.1-96 -but was dropped from -.St -p1003.1-2001 . -The options supported by this implementation were developed by surveying a -number of existing tar implementations as well as the old POSIX specification -for tar and the current POSIX specification for pax. -.Pp -The ustar and pax interchange file formats are defined by -.St -p1003.1-2001 -for the pax command. -.Sh HISTORY -A -.Nm tar -command appeared in Seventh Edition Unix, which was released in January, 1979. -There have been numerous other implementations, -many of which extended the file format. -John Gilmore's -.Nm pdtar -public-domain implementation (circa November, 1987) -was quite influential, and formed the basis of GNU tar. -GNU tar was included as the standard system tar -in -.Fx -beginning with -.Fx 1.0 . -.Pp -This is a complete re-implementation based on the -.Xr libarchive 3 -library. -It was first released with -.Fx 5.4 -in May, 2005. -.Sh BUGS -This program follows -.St -p1003.1-96 -for the definition of the -.Fl l -option. -Note that GNU tar prior to version 1.15 treated -.Fl l -as a synonym for the -.Fl Fl one-file-system -option. -.Pp -The -.Fl C Pa dir -option may differ from historic implementations. -.Pp -All archive output is written in correctly-sized blocks, even -if the output is being compressed. -Whether or not the last output block is padded to a full -block size varies depending on the format and the -output device. -For tar and cpio formats, the last block of output is padded -to a full block size if the output is being -written to standard output or to a character or block device such as -a tape drive. -If the output is being written to a regular file, the last block -will not be padded. -Many compressors, including -.Xr gzip 1 -and -.Xr bzip2 1 , -complain about the null padding when decompressing an archive created by -.Nm , -although they still extract it correctly. -.Pp -The compression and decompression is implemented internally, so -there may be insignificant differences between the compressed output -generated by -.Dl Nm Fl czf Pa - file -and that generated by -.Dl Nm Fl cf Pa - file | Nm gzip -.Pp -The default should be to read and write archives to the standard I/O paths, -but tradition (and POSIX) dictates otherwise. -.Pp -The -.Cm r -and -.Cm u -modes require that the archive be uncompressed -and located in a regular file on disk. -Other archives can be modified using -.Cm c -mode with the -.Pa @archive-file -extension. -.Pp -To archive a file called -.Pa @foo -or -.Pa -foo -you must specify it as -.Pa ./@foo -or -.Pa ./-foo , -respectively. -.Pp -In create mode, a leading -.Pa ./ -is always removed. -A leading -.Pa / -is stripped unless the -.Fl P -option is specified. -.Pp -There needs to be better support for file selection on both create -and extract. -.Pp -There is not yet any support for multi-volume archives. -.Pp -Converting between dissimilar archive formats (such as tar and cpio) using the -.Cm @ Ns Pa - -convention can cause hard link information to be lost. -(This is a consequence of the incompatible ways that different archive -formats store hardlink information.) diff --git a/thirdparty/libarchive/tar/bsdtar.c b/thirdparty/libarchive/tar/bsdtar.c deleted file mode 100644 index 75249d105..000000000 --- a/thirdparty/libarchive/tar/bsdtar.c +++ /dev/null @@ -1,1070 +0,0 @@ -/*- - * Copyright (c) 2003-2008 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "bsdtar_platform.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/bsdtar.c,v 1.93 2008/11/08 04:43:24 kientzle Exp $"); - -#ifdef HAVE_SYS_PARAM_H -#include -#endif -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_COPYFILE_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif -#ifdef HAVE_LANGINFO_H -#include -#endif -#ifdef HAVE_LOCALE_H -#include -#endif -#ifdef HAVE_PATHS_H -#include -#endif -#ifdef HAVE_SIGNAL_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_TIME_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif - -#include "bsdtar.h" -#include "err.h" - -#if ARCHIVE_VERSION_NUMBER < 4000000 && !defined(_PATH_DEFTAPE) -// Libarchive 4.0 and later will NOT define _PATH_DEFTAPE -// but will honor it if it's set in the build. -// Until then, we'll continue to set it by default on certain platforms: -#if defined(__linux) -#define _PATH_DEFTAPE "/dev/st0" -#elif defined(_WIN32) && !defined(__CYGWIN__) -#define _PATH_DEFTAPE "\\\\.\\tape0" -#elif !defined(__APPLE__) -#define _PATH_DEFTAPE "/dev/tape" -#endif -#endif - -#define _PATH_STDIO "-" - -#ifdef __MINGW32__ -int _CRT_glob = 0; /* Disable broken CRT globbing. */ -#endif - -#if defined(HAVE_SIGACTION) && (defined(SIGINFO) || defined(SIGUSR1)) -static volatile int siginfo_occurred; - -static void -siginfo_handler(int sig) -{ - (void)sig; /* UNUSED */ - siginfo_occurred = 1; -} - -int -need_report(void) -{ - int r = siginfo_occurred; - siginfo_occurred = 0; - return (r); -} -#else -int -need_report(void) -{ - return (0); -} -#endif - -static void long_help(void) __LA_DEAD; -static void only_mode(struct bsdtar *, const char *opt, - const char *valid); -static void set_mode(struct bsdtar *, char opt); -static void version(void) __LA_DEAD; - -/* A basic set of security flags to request from libarchive. */ -#define SECURITY \ - (ARCHIVE_EXTRACT_SECURE_SYMLINKS \ - | ARCHIVE_EXTRACT_SECURE_NODOTDOT) - -static char const * const vcs_files[] = { - /* CVS */ - "CVS", ".cvsignore", - /* RCS */ - "RCS", - /* SCCS */ - "SCCS", - /* SVN */ - ".svn", - /* git */ - ".git", ".gitignore", ".gitattributes", ".gitmodules", - /* Arch */ - ".arch-ids", "{arch}", "=RELEASE-ID", "=meta-update", "=update", - /* Bazaar */ - ".bzr", ".bzrignore", ".bzrtags", - /* Mercurial */ - ".hg", ".hgignore", ".hgtags", - /* darcs */ - "_darcs", - NULL -}; - -int -main(int argc, char **argv) -{ - struct bsdtar *bsdtar, bsdtar_storage; - int opt, t; - char compression, compression2; - const char *compression_name, *compression2_name; - const char *compress_program; - char *tptr; - char possible_help_request; - char buff[16]; - - /* - * Use a pointer for consistency, but stack-allocated storage - * for ease of cleanup. - */ - bsdtar = &bsdtar_storage; - memset(bsdtar, 0, sizeof(*bsdtar)); - bsdtar->fd = -1; /* Mark as "unused" */ - bsdtar->gid = -1; - bsdtar->uid = -1; - bsdtar->flags = 0; - compression = compression2 = '\0'; - compression_name = compression2_name = NULL; - compress_program = NULL; - -#if defined(HAVE_SIGACTION) - { /* Set up signal handling. */ - struct sigaction sa; - sa.sa_handler = siginfo_handler; - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; -#ifdef SIGINFO - if (sigaction(SIGINFO, &sa, NULL)) - lafe_errc(1, errno, "sigaction(SIGINFO) failed"); -#endif -#ifdef SIGUSR1 - /* ... and treat SIGUSR1 the same way as SIGINFO. */ - if (sigaction(SIGUSR1, &sa, NULL)) - lafe_errc(1, errno, "sigaction(SIGUSR1) failed"); -#endif -#ifdef SIGPIPE - /* Ignore SIGPIPE signals. */ - sa.sa_handler = SIG_IGN; - sigaction(SIGPIPE, &sa, NULL); -#endif - } -#endif - - /* Set lafe_progname before calling lafe_warnc. */ - lafe_setprogname(*argv, "bsdtar"); - -#if HAVE_SETLOCALE - if (setlocale(LC_ALL, "") == NULL) - lafe_warnc(0, "Failed to set default locale"); -#endif -#if defined(HAVE_NL_LANGINFO) && defined(HAVE_D_MD_ORDER) - bsdtar->day_first = (*nl_langinfo(D_MD_ORDER) == 'd'); -#endif - possible_help_request = 0; - - /* Look up uid of current user for future reference */ - bsdtar->user_uid = geteuid(); - - /* Default: open tape drive. */ - bsdtar->filename = getenv("TAPE"); -#if defined(_PATH_DEFTAPE) - if (bsdtar->filename == NULL) { -#if defined(_WIN32) && !defined(__CYGWIN__) - int tapeExists = !_access(_PATH_DEFTAPE, 0); -#else - int tapeExists = !access(_PATH_DEFTAPE, F_OK); -#endif - if (tapeExists) { - bsdtar->filename = _PATH_DEFTAPE; - } - } -#endif - if (bsdtar->filename == NULL) { - bsdtar->filename = _PATH_STDIO; - } - - /* Default block size settings. */ - bsdtar->bytes_per_block = DEFAULT_BYTES_PER_BLOCK; - /* Allow library to default this unless user specifies -b. */ - bsdtar->bytes_in_last_block = -1; - - /* Default: preserve mod time on extract */ - bsdtar->extract_flags = ARCHIVE_EXTRACT_TIME; - - /* Default: Perform basic security checks. */ - bsdtar->extract_flags |= SECURITY; - -#ifndef _WIN32 - /* On POSIX systems, assume --same-owner and -p when run by - * the root user. This doesn't make any sense on Windows. */ - if (bsdtar->user_uid == 0) { - /* --same-owner */ - bsdtar->extract_flags |= ARCHIVE_EXTRACT_OWNER; - /* -p */ - bsdtar->extract_flags |= ARCHIVE_EXTRACT_PERM; - bsdtar->extract_flags |= ARCHIVE_EXTRACT_ACL; - bsdtar->extract_flags |= ARCHIVE_EXTRACT_XATTR; - bsdtar->extract_flags |= ARCHIVE_EXTRACT_FFLAGS; - bsdtar->extract_flags |= ARCHIVE_EXTRACT_MAC_METADATA; - } -#endif - - /* - * Enable Mac OS "copyfile()" extension by default. - * This has no effect on other platforms. - */ - bsdtar->readdisk_flags |= ARCHIVE_READDISK_MAC_COPYFILE; -#ifdef COPYFILE_DISABLE_VAR - if (getenv(COPYFILE_DISABLE_VAR)) - bsdtar->readdisk_flags &= ~ARCHIVE_READDISK_MAC_COPYFILE; -#endif -#if defined(__APPLE__) - /* - * On Mac OS ACLs are archived with copyfile() (--mac-metadata) - * Translation to NFSv4 ACLs has to be requested explicitly with --acls - */ - bsdtar->readdisk_flags |= ARCHIVE_READDISK_NO_ACL; -#endif - - bsdtar->matching = archive_match_new(); - if (bsdtar->matching == NULL) - lafe_errc(1, errno, "Out of memory"); - bsdtar->cset = cset_new(); - if (bsdtar->cset == NULL) - lafe_errc(1, errno, "Out of memory"); - - bsdtar->argv = argv; - bsdtar->argc = argc; - - /* - * Comments following each option indicate where that option - * originated: SUSv2, POSIX, GNU tar, star, etc. If there's - * no such comment, then I don't know of anyone else who - * implements that option. - */ - while ((opt = bsdtar_getopt(bsdtar)) != -1) { - switch (opt) { - case 'a': /* GNU tar */ - bsdtar->flags |= OPTFLAG_AUTO_COMPRESS; - break; - case OPTION_ACLS: /* GNU tar */ - bsdtar->extract_flags |= ARCHIVE_EXTRACT_ACL; - bsdtar->readdisk_flags &= ~ARCHIVE_READDISK_NO_ACL; - bsdtar->flags |= OPTFLAG_ACLS; - break; - case 'B': /* GNU tar */ - /* libarchive doesn't need this; just ignore it. */ - break; - case 'b': /* SUSv2 */ - errno = 0; - tptr = NULL; - t = (int)strtol(bsdtar->argument, &tptr, 10); - if (errno || t <= 0 || t > 8192 || - *(bsdtar->argument) == '\0' || tptr == NULL || - *tptr != '\0') { - lafe_errc(1, 0, "Invalid or out of range " - "(1..8192) argument to -b"); - } - bsdtar->bytes_per_block = 512 * t; - /* Explicit -b forces last block size. */ - bsdtar->bytes_in_last_block = bsdtar->bytes_per_block; - break; - case OPTION_B64ENCODE: - if (compression2 != '\0') - lafe_errc(1, 0, - "Can't specify both --uuencode and " - "--b64encode"); - compression2 = opt; - compression2_name = "b64encode"; - break; - case 'C': /* GNU tar */ - if (strlen(bsdtar->argument) == 0) - lafe_errc(1, 0, - "Meaningless option: -C ''"); - - set_chdir(bsdtar, bsdtar->argument); - break; - case 'c': /* SUSv2 */ - set_mode(bsdtar, opt); - break; - case OPTION_CHECK_LINKS: /* GNU tar */ - bsdtar->flags |= OPTFLAG_WARN_LINKS; - break; - case OPTION_CHROOT: /* NetBSD */ - bsdtar->flags |= OPTFLAG_CHROOT; - break; - case OPTION_CLEAR_NOCHANGE_FFLAGS: - bsdtar->extract_flags |= - ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS; - break; - case OPTION_EXCLUDE: /* GNU tar */ - if (archive_match_exclude_pattern( - bsdtar->matching, bsdtar->argument) != ARCHIVE_OK) - lafe_errc(1, 0, - "Couldn't exclude %s\n", bsdtar->argument); - break; - case OPTION_EXCLUDE_VCS: /* GNU tar */ - for(t=0; vcs_files[t]; t++) { - if (archive_match_exclude_pattern( - bsdtar->matching, - vcs_files[t]) != ARCHIVE_OK) - lafe_errc(1, 0, "Couldn't " - "exclude %s\n", vcs_files[t]); - } - break; - case OPTION_FFLAGS: - bsdtar->extract_flags |= ARCHIVE_EXTRACT_FFLAGS; - bsdtar->readdisk_flags &= ~ARCHIVE_READDISK_NO_FFLAGS; - bsdtar->flags |= OPTFLAG_FFLAGS; - break; - case OPTION_FORMAT: /* GNU tar, others */ - cset_set_format(bsdtar->cset, bsdtar->argument); - break; - case 'f': /* SUSv2 */ - bsdtar->filename = bsdtar->argument; - break; - case OPTION_GID: /* cpio */ - errno = 0; - tptr = NULL; - t = (int)strtol(bsdtar->argument, &tptr, 10); - if (errno || t < 0 || *(bsdtar->argument) == '\0' || - tptr == NULL || *tptr != '\0') { - lafe_errc(1, 0, "Invalid argument to --gid"); - } - bsdtar->gid = t; - break; - case OPTION_GNAME: /* cpio */ - bsdtar->gname = bsdtar->argument; - break; - case OPTION_GRZIP: - if (compression != '\0') - lafe_errc(1, 0, - "Can't specify both -%c and -%c", opt, - compression); - compression = opt; - compression_name = "grzip"; - break; - case 'H': /* BSD convention */ - bsdtar->symlink_mode = 'H'; - break; - case 'h': /* Linux Standards Base, gtar; synonym for -L */ - bsdtar->symlink_mode = 'L'; - /* Hack: -h by itself is the "help" command. */ - possible_help_request = 1; - break; - case OPTION_HELP: /* GNU tar, others */ - long_help(); - exit(0); - break; - case OPTION_HFS_COMPRESSION: /* Mac OS X v10.6 or later */ - bsdtar->extract_flags |= - ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED; - break; - case OPTION_IGNORE_ZEROS: - bsdtar->flags |= OPTFLAG_IGNORE_ZEROS; - break; - case 'I': /* GNU tar */ - /* - * TODO: Allow 'names' to come from an archive, - * not just a text file. Design a good UI for - * allowing names and mode/owner to be read - * from an archive, with contents coming from - * disk. This can be used to "refresh" an - * archive or to design archives with special - * permissions without having to create those - * permissions on disk. - */ - bsdtar->names_from_file = bsdtar->argument; - break; - case OPTION_INCLUDE: - /* - * No one else has the @archive extension, so - * no one else needs this to filter entries - * when transforming archives. - */ - if (archive_match_include_pattern(bsdtar->matching, - bsdtar->argument) != ARCHIVE_OK) - lafe_errc(1, 0, - "Failed to add %s to inclusion list", - bsdtar->argument); - break; - case 'j': /* GNU tar */ - if (compression != '\0') - lafe_errc(1, 0, - "Can't specify both -%c and -%c", opt, - compression); - compression = opt; - compression_name = "bzip2"; - break; - case 'J': /* GNU tar 1.21 and later */ - if (compression != '\0') - lafe_errc(1, 0, - "Can't specify both -%c and -%c", opt, - compression); - compression = opt; - compression_name = "xz"; - break; - case 'k': /* GNU tar */ - bsdtar->extract_flags |= ARCHIVE_EXTRACT_NO_OVERWRITE; - break; - case OPTION_KEEP_NEWER_FILES: /* GNU tar */ - bsdtar->extract_flags |= ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER; - break; - case 'L': /* BSD convention */ - bsdtar->symlink_mode = 'L'; - break; - case 'l': /* SUSv2 and GNU tar beginning with 1.16 */ - /* GNU tar 1.13 used -l for --one-file-system */ - bsdtar->flags |= OPTFLAG_WARN_LINKS; - break; - case OPTION_LRZIP: - case OPTION_LZ4: - case OPTION_LZIP: /* GNU tar beginning with 1.23 */ - case OPTION_LZMA: /* GNU tar beginning with 1.20 */ - case OPTION_LZOP: /* GNU tar beginning with 1.21 */ - case OPTION_ZSTD: - if (compression != '\0') - lafe_errc(1, 0, - "Can't specify both -%c and -%c", opt, - compression); - compression = opt; - switch (opt) { - case OPTION_LRZIP: compression_name = "lrzip"; break; - case OPTION_LZ4: compression_name = "lz4"; break; - case OPTION_LZIP: compression_name = "lzip"; break; - case OPTION_LZMA: compression_name = "lzma"; break; - case OPTION_LZOP: compression_name = "lzop"; break; - case OPTION_ZSTD: compression_name = "zstd"; break; - } - break; - case 'm': /* SUSv2 */ - bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_TIME; - break; - case OPTION_MAC_METADATA: /* Mac OS X */ - bsdtar->readdisk_flags |= ARCHIVE_READDISK_MAC_COPYFILE; - bsdtar->extract_flags |= ARCHIVE_EXTRACT_MAC_METADATA; - bsdtar->flags |= OPTFLAG_MAC_METADATA; - break; - case 'n': /* GNU tar */ - bsdtar->flags |= OPTFLAG_NO_SUBDIRS; - break; - /* - * Selecting files by time: - * --newer-?time='date' Only files newer than 'date' - * --newer-?time-than='file' Only files newer than time - * on specified file (useful for incremental backups) - */ - case OPTION_NEWER_CTIME: /* GNU tar */ - if (archive_match_include_date(bsdtar->matching, - ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_NEWER, - bsdtar->argument) != ARCHIVE_OK) - lafe_errc(1, 0, "Error : %s", - archive_error_string(bsdtar->matching)); - break; - case OPTION_NEWER_CTIME_THAN: - if (archive_match_include_file_time(bsdtar->matching, - ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_NEWER, - bsdtar->argument) != ARCHIVE_OK) - lafe_errc(1, 0, "Error : %s", - archive_error_string(bsdtar->matching)); - break; - case OPTION_NEWER_MTIME: /* GNU tar */ - if (archive_match_include_date(bsdtar->matching, - ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_NEWER, - bsdtar->argument) != ARCHIVE_OK) - lafe_errc(1, 0, "Error : %s", - archive_error_string(bsdtar->matching)); - break; - case OPTION_NEWER_MTIME_THAN: - if (archive_match_include_file_time(bsdtar->matching, - ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_NEWER, - bsdtar->argument) != ARCHIVE_OK) - lafe_errc(1, 0, "Error : %s", - archive_error_string(bsdtar->matching)); - break; - case OPTION_NODUMP: /* star */ - bsdtar->readdisk_flags |= ARCHIVE_READDISK_HONOR_NODUMP; - break; - case OPTION_NOPRESERVE_HFS_COMPRESSION: - /* Mac OS X v10.6 or later */ - bsdtar->extract_flags |= - ARCHIVE_EXTRACT_NO_HFS_COMPRESSION; - break; - case OPTION_NO_ACLS: /* GNU tar */ - bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_ACL; - bsdtar->readdisk_flags |= ARCHIVE_READDISK_NO_ACL; - bsdtar->flags |= OPTFLAG_NO_ACLS; - break; - case OPTION_NO_FFLAGS: - bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_FFLAGS; - bsdtar->readdisk_flags |= ARCHIVE_READDISK_NO_FFLAGS; - bsdtar->flags |= OPTFLAG_NO_FFLAGS; - break; - case OPTION_NO_MAC_METADATA: /* Mac OS X */ - bsdtar->readdisk_flags &= ~ARCHIVE_READDISK_MAC_COPYFILE; - bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_MAC_METADATA; - bsdtar->flags |= OPTFLAG_NO_MAC_METADATA; - break; - case OPTION_NO_READ_SPARSE: - bsdtar->readdisk_flags |= ARCHIVE_READDISK_NO_SPARSE; - bsdtar->flags |= OPTFLAG_NO_READ_SPARSE; - break; - case OPTION_NO_SAFE_WRITES: - bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_SAFE_WRITES; - break; - case OPTION_NO_SAME_OWNER: /* GNU tar */ - bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_OWNER; - break; - case OPTION_NO_SAME_PERMISSIONS: /* GNU tar */ - bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_PERM; - bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_ACL; - bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_XATTR; - bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_FFLAGS; - bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_MAC_METADATA; - break; - case OPTION_NO_XATTRS: /* GNU tar */ - bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_XATTR; - bsdtar->readdisk_flags |= ARCHIVE_READDISK_NO_XATTR; - bsdtar->flags |= OPTFLAG_NO_XATTRS; - break; - case OPTION_NULL: /* GNU tar */ - bsdtar->flags |= OPTFLAG_NULL; - break; - case OPTION_NUMERIC_OWNER: /* GNU tar */ - bsdtar->uname = ""; - bsdtar->gname = ""; - bsdtar->flags |= OPTFLAG_NUMERIC_OWNER; - break; - case 'O': /* GNU tar */ - bsdtar->flags |= OPTFLAG_STDOUT; - break; - case 'o': /* SUSv2 and GNU conflict here, but not fatally */ - bsdtar->flags |= OPTFLAG_O; - break; - /* - * Selecting files by time: - * --older-?time='date' Only files older than 'date' - * --older-?time-than='file' Only files older than time - * on specified file - */ - case OPTION_OLDER_CTIME: - if (archive_match_include_date(bsdtar->matching, - ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_OLDER, - bsdtar->argument) != ARCHIVE_OK) - lafe_errc(1, 0, "Error : %s", - archive_error_string(bsdtar->matching)); - break; - case OPTION_OLDER_CTIME_THAN: - if (archive_match_include_file_time(bsdtar->matching, - ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_OLDER, - bsdtar->argument) != ARCHIVE_OK) - lafe_errc(1, 0, "Error : %s", - archive_error_string(bsdtar->matching)); - break; - case OPTION_OLDER_MTIME: - if (archive_match_include_date(bsdtar->matching, - ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER, - bsdtar->argument) != ARCHIVE_OK) - lafe_errc(1, 0, "Error : %s", - archive_error_string(bsdtar->matching)); - break; - case OPTION_OLDER_MTIME_THAN: - if (archive_match_include_file_time(bsdtar->matching, - ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER, - bsdtar->argument) != ARCHIVE_OK) - lafe_errc(1, 0, "Error : %s", - archive_error_string(bsdtar->matching)); - break; - case OPTION_ONE_FILE_SYSTEM: /* GNU tar */ - bsdtar->readdisk_flags |= - ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS; - break; - case OPTION_OPTIONS: - bsdtar->option_options = bsdtar->argument; - break; -#if 0 - /* - * The common BSD -P option is not necessary, since - * our default is to archive symlinks, not follow - * them. This is convenient, as -P conflicts with GNU - * tar anyway. - */ - case 'P': /* BSD convention */ - /* Default behavior, no option necessary. */ - break; -#endif - case 'P': /* GNU tar */ - bsdtar->extract_flags &= ~SECURITY; - bsdtar->flags |= OPTFLAG_ABSOLUTE_PATHS; - break; - case 'p': /* GNU tar, star */ - bsdtar->extract_flags |= ARCHIVE_EXTRACT_PERM; - bsdtar->extract_flags |= ARCHIVE_EXTRACT_ACL; - bsdtar->extract_flags |= ARCHIVE_EXTRACT_XATTR; - bsdtar->extract_flags |= ARCHIVE_EXTRACT_FFLAGS; - bsdtar->extract_flags |= ARCHIVE_EXTRACT_MAC_METADATA; - break; - case OPTION_PASSPHRASE: - bsdtar->passphrase = bsdtar->argument; - break; - case OPTION_POSIX: /* GNU tar */ - cset_set_format(bsdtar->cset, "pax"); - break; - case 'q': /* FreeBSD GNU tar --fast-read, NetBSD -q */ - bsdtar->flags |= OPTFLAG_FAST_READ; - break; - case 'r': /* SUSv2 */ - set_mode(bsdtar, opt); - break; - case OPTION_READ_SPARSE: - bsdtar->readdisk_flags &= ~ARCHIVE_READDISK_NO_SPARSE; - bsdtar->flags |= OPTFLAG_READ_SPARSE; - break; - case 'S': /* NetBSD pax-as-tar */ - bsdtar->extract_flags |= ARCHIVE_EXTRACT_SPARSE; - break; - case 's': /* NetBSD pax-as-tar */ -#if defined(HAVE_REGEX_H) || defined(HAVE_PCREPOSIX_H) - add_substitution(bsdtar, bsdtar->argument); -#else - lafe_warnc(0, - "-s is not supported by this version of bsdtar"); - usage(); -#endif - break; - case OPTION_SAFE_WRITES: - bsdtar->extract_flags |= ARCHIVE_EXTRACT_SAFE_WRITES; - break; - case OPTION_SAME_OWNER: /* GNU tar */ - bsdtar->extract_flags |= ARCHIVE_EXTRACT_OWNER; - break; - case OPTION_STRIP_COMPONENTS: /* GNU tar 1.15 */ - errno = 0; - tptr = NULL; - t = (int)strtol(bsdtar->argument, &tptr, 10); - if (errno || t < 0 || *(bsdtar->argument) == '\0' || - tptr == NULL || *tptr != '\0') { - lafe_errc(1, 0, "Invalid argument to " - "--strip-components"); - } - bsdtar->strip_components = t; - break; - case 'T': /* GNU tar */ - bsdtar->names_from_file = bsdtar->argument; - break; - case 't': /* SUSv2 */ - set_mode(bsdtar, opt); - bsdtar->verbose++; - break; - case OPTION_TOTALS: /* GNU tar */ - bsdtar->flags |= OPTFLAG_TOTALS; - break; - case 'U': /* GNU tar */ - bsdtar->extract_flags |= ARCHIVE_EXTRACT_UNLINK; - bsdtar->flags |= OPTFLAG_UNLINK_FIRST; - break; - case 'u': /* SUSv2 */ - set_mode(bsdtar, opt); - break; - case OPTION_UID: /* cpio */ - errno = 0; - tptr = NULL; - t = (int)strtol(bsdtar->argument, &tptr, 10); - if (errno || t < 0 || *(bsdtar->argument) == '\0' || - tptr == NULL || *tptr != '\0') { - lafe_errc(1, 0, "Invalid argument to --uid"); - } - bsdtar->uid = t; - break; - case OPTION_UNAME: /* cpio */ - bsdtar->uname = bsdtar->argument; - break; - case OPTION_UUENCODE: - if (compression2 != '\0') - lafe_errc(1, 0, - "Can't specify both --uuencode and " - "--b64encode"); - compression2 = opt; - compression2_name = "uuencode"; - break; - case 'v': /* SUSv2 */ - bsdtar->verbose++; - break; - case OPTION_VERSION: /* GNU convention */ - version(); - break; -#if 0 - /* - * The -W longopt feature is handled inside of - * bsdtar_getopt(), so -W is not available here. - */ - case 'W': /* Obscure GNU convention. */ - break; -#endif - case 'w': /* SUSv2 */ - bsdtar->flags |= OPTFLAG_INTERACTIVE; - break; - case 'X': /* GNU tar */ - if (archive_match_exclude_pattern_from_file( - bsdtar->matching, bsdtar->argument, 0) - != ARCHIVE_OK) - lafe_errc(1, 0, "Error : %s", - archive_error_string(bsdtar->matching)); - break; - case 'x': /* SUSv2 */ - set_mode(bsdtar, opt); - break; - case OPTION_XATTRS: /* GNU tar */ - bsdtar->extract_flags |= ARCHIVE_EXTRACT_XATTR; - bsdtar->readdisk_flags &= ~ARCHIVE_READDISK_NO_XATTR; - bsdtar->flags |= OPTFLAG_XATTRS; - break; - case 'y': /* FreeBSD version of GNU tar */ - if (compression != '\0') - lafe_errc(1, 0, - "Can't specify both -%c and -%c", opt, - compression); - compression = opt; - compression_name = "bzip2"; - break; - case 'Z': /* GNU tar */ - if (compression != '\0') - lafe_errc(1, 0, - "Can't specify both -%c and -%c", opt, - compression); - compression = opt; - compression_name = "compress"; - break; - case 'z': /* GNU tar, star, many others */ - if (compression != '\0') - lafe_errc(1, 0, - "Can't specify both -%c and -%c", opt, - compression); - compression = opt; - compression_name = "gzip"; - break; - case OPTION_USE_COMPRESS_PROGRAM: - compress_program = bsdtar->argument; - break; - default: - usage(); - } - } - - /* - * Sanity-check options. - */ - - /* If no "real" mode was specified, treat -h as --help. */ - if ((bsdtar->mode == '\0') && possible_help_request) { - long_help(); - exit(0); - } - - /* Otherwise, a mode is required. */ - if (bsdtar->mode == '\0') - lafe_errc(1, 0, - "Must specify one of -c, -r, -t, -u, -x"); - - /* Check boolean options only permitted in certain modes. */ - if (bsdtar->flags & OPTFLAG_AUTO_COMPRESS) { - only_mode(bsdtar, "-a", "cx"); - if (bsdtar->mode == 'x') { - bsdtar->flags &= ~OPTFLAG_AUTO_COMPRESS; - lafe_warnc(0, - "Ignoring option -a in mode -x"); - } - } - if (bsdtar->readdisk_flags & ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS) - only_mode(bsdtar, "--one-file-system", "cru"); - if (bsdtar->flags & OPTFLAG_FAST_READ) - only_mode(bsdtar, "--fast-read", "xt"); - if (bsdtar->extract_flags & ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED) - only_mode(bsdtar, "--hfsCompression", "x"); - if (bsdtar->extract_flags & ARCHIVE_EXTRACT_NO_HFS_COMPRESSION) - only_mode(bsdtar, "--nopreserveHFSCompression", "x"); - if (bsdtar->readdisk_flags & ARCHIVE_READDISK_HONOR_NODUMP) - only_mode(bsdtar, "--nodump", "cru"); - if (bsdtar->flags & OPTFLAG_ACLS) - only_mode(bsdtar, "--acls", "crux"); - if (bsdtar->flags & OPTFLAG_NO_ACLS) - only_mode(bsdtar, "--no-acls", "crux"); - if (bsdtar->flags & OPTFLAG_XATTRS) - only_mode(bsdtar, "--xattrs", "crux"); - if (bsdtar->flags & OPTFLAG_NO_XATTRS) - only_mode(bsdtar, "--no-xattrs", "crux"); - if (bsdtar->flags & OPTFLAG_FFLAGS) - only_mode(bsdtar, "--fflags", "crux"); - if (bsdtar->flags & OPTFLAG_NO_FFLAGS) - only_mode(bsdtar, "--no-fflags", "crux"); - if (bsdtar->flags & OPTFLAG_MAC_METADATA) - only_mode(bsdtar, "--mac-metadata", "crux"); - if (bsdtar->flags & OPTFLAG_NO_MAC_METADATA) - only_mode(bsdtar, "--no-mac-metadata", "crux"); - if (bsdtar->flags & OPTFLAG_O) { - switch (bsdtar->mode) { - case 'c': - /* - * In GNU tar, -o means "old format." The - * "ustar" format is the closest thing - * supported by libarchive. - */ - cset_set_format(bsdtar->cset, "ustar"); - /* TODO: bsdtar->create_format = "v7"; */ - break; - case 'x': - /* POSIX-compatible behavior. */ - bsdtar->flags |= OPTFLAG_NO_OWNER; - bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_OWNER; - break; - default: - only_mode(bsdtar, "-o", "xc"); - break; - } - } - if (bsdtar->flags & OPTFLAG_STDOUT) - only_mode(bsdtar, "-O", "xt"); - if (bsdtar->flags & OPTFLAG_UNLINK_FIRST) - only_mode(bsdtar, "-U", "x"); - if (bsdtar->flags & OPTFLAG_WARN_LINKS) - only_mode(bsdtar, "--check-links", "cr"); - - if ((bsdtar->flags & OPTFLAG_AUTO_COMPRESS) && - cset_auto_compress(bsdtar->cset, bsdtar->filename)) { - /* Ignore specified compressions if auto-compress works. */ - compression = '\0'; - compression2 = '\0'; - } - /* Check other parameters only permitted in certain modes. */ - if (compress_program != NULL) { - only_mode(bsdtar, "--use-compress-program", "cxt"); - cset_add_filter_program(bsdtar->cset, compress_program); - /* Ignore specified compressions. */ - compression = '\0'; - compression2 = '\0'; - } - if (compression != '\0') { - switch (compression) { - case 'J': case 'j': case 'y': case 'Z': case 'z': - strcpy(buff, "-?"); - buff[1] = compression; - break; - default: - strcpy(buff, "--"); - strcat(buff, compression_name); - break; - } - only_mode(bsdtar, buff, "cxt"); - cset_add_filter(bsdtar->cset, compression_name); - } - if (compression2 != '\0') { - strcpy(buff, "--"); - strcat(buff, compression2_name); - only_mode(bsdtar, buff, "cxt"); - cset_add_filter(bsdtar->cset, compression2_name); - } - if (cset_get_format(bsdtar->cset) != NULL) - only_mode(bsdtar, "--format", "cru"); - if (bsdtar->symlink_mode != '\0') { - strcpy(buff, "-?"); - buff[1] = bsdtar->symlink_mode; - only_mode(bsdtar, buff, "cru"); - } - - /* - * When creating an archive from a directory tree, the directory - * walking code will already avoid entering directories when - * recursive inclusion of directory content is disabled, therefore - * changing the matching behavior has no effect for creation modes. - * It is relevant for extraction or listing. - */ - archive_match_set_inclusion_recursion(bsdtar->matching, - !(bsdtar->flags & OPTFLAG_NO_SUBDIRS)); - - /* Filename "-" implies stdio. */ - if (strcmp(bsdtar->filename, "-") == 0) - bsdtar->filename = NULL; - - switch(bsdtar->mode) { - case 'c': - tar_mode_c(bsdtar); - break; - case 'r': - tar_mode_r(bsdtar); - break; - case 't': - tar_mode_t(bsdtar); - break; - case 'u': - tar_mode_u(bsdtar); - break; - case 'x': - tar_mode_x(bsdtar); - break; - } - - archive_match_free(bsdtar->matching); -#if defined(HAVE_REGEX_H) || defined(HAVE_PCREPOSIX_H) - cleanup_substitution(bsdtar); -#endif - cset_free(bsdtar->cset); - passphrase_free(bsdtar->ppbuff); - - if (bsdtar->return_value != 0) - lafe_warnc(0, - "Error exit delayed from previous errors."); - return (bsdtar->return_value); -} - -static void -set_mode(struct bsdtar *bsdtar, char opt) -{ - if (bsdtar->mode != '\0' && bsdtar->mode != opt) - lafe_errc(1, 0, - "Can't specify both -%c and -%c", opt, bsdtar->mode); - bsdtar->mode = opt; -} - -/* - * Verify that the mode is correct. - */ -static void -only_mode(struct bsdtar *bsdtar, const char *opt, const char *valid_modes) -{ - if (strchr(valid_modes, bsdtar->mode) == NULL) - lafe_errc(1, 0, - "Option %s is not permitted in mode -%c", - opt, bsdtar->mode); -} - - -void -usage(void) -{ - const char *p; - - p = lafe_getprogname(); - - fprintf(stderr, "Usage:\n"); - fprintf(stderr, " List: %s -tf \n", p); - fprintf(stderr, " Extract: %s -xf \n", p); - fprintf(stderr, " Create: %s -cf [filenames...]\n", p); - fprintf(stderr, " Help: %s --help\n", p); - exit(1); -} - -static void -version(void) -{ - printf("bsdtar %s - %s \n", - BSDTAR_VERSION_STRING, - archive_version_details()); - exit(0); -} - -static const char *long_help_msg = - "First option must be a mode specifier:\n" - " -c Create -r Add/Replace -t List -u Update -x Extract\n" - "Common Options:\n" - " -b # Use # 512-byte records per I/O block\n" - " -f Location of archive (default " _PATH_DEFTAPE ")\n" - " -v Verbose\n" - " -w Interactive\n" - "Create: %p -c [options] [ |

    | @ | -C ]\n" - " , add these items to archive\n" - " -z, -j, -J, --lzma Compress archive with gzip/bzip2/xz/lzma\n" - " --format {ustar|pax|cpio|shar} Select archive format\n" - " --exclude Skip files that match pattern\n" - " -C Change to before processing remaining files\n" - " @ Add entries from to output\n" - "List: %p -t [options] []\n" - " If specified, list only entries that match\n" - "Extract: %p -x [options] []\n" - " If specified, extract only entries that match\n" - " -k Keep (don't overwrite) existing files\n" - " -m Don't restore modification times\n" - " -O Write entries to stdout, don't restore to disk\n" - " -p Restore permissions (including ACLs, owner, file flags)\n"; - - -/* - * Note that the word 'bsdtar' will always appear in the first line - * of output. - * - * In particular, /bin/sh scripts that need to test for the presence - * of bsdtar can use the following template: - * - * if (tar --help 2>&1 | grep bsdtar >/dev/null 2>&1 ) then \ - * echo bsdtar; else echo not bsdtar; fi - */ -static void -long_help(void) -{ - const char *prog; - const char *p; - - prog = lafe_getprogname(); - - fflush(stderr); - - p = (strcmp(prog,"bsdtar") != 0) ? "(bsdtar)" : ""; - printf("%s%s: manipulate archive files\n", prog, p); - - for (p = long_help_msg; *p != '\0'; p++) { - if (*p == '%') { - if (p[1] == 'p') { - fputs(prog, stdout); - p++; - } else - putchar('%'); - } else - putchar(*p); - } - version(); -} diff --git a/thirdparty/libarchive/tar/bsdtar.h b/thirdparty/libarchive/tar/bsdtar.h deleted file mode 100644 index 8f9f79ab1..000000000 --- a/thirdparty/libarchive/tar/bsdtar.h +++ /dev/null @@ -1,237 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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/usr.bin/tar/bsdtar.h,v 1.37 2008/12/06 07:37:14 kientzle Exp $ - */ - -#ifndef BSDTAR_H_INCLUDED -#define BSDTAR_H_INCLUDED - -#include "bsdtar_platform.h" -#include - -#define DEFAULT_BYTES_PER_BLOCK (20*512) -#define ENV_READER_OPTIONS "TAR_READER_OPTIONS" -#define ENV_WRITER_OPTIONS "TAR_WRITER_OPTIONS" -#define IGNORE_WRONG_MODULE_NAME "__ignore_wrong_module_name__," - -struct creation_set; -/* - * The internal state for the "bsdtar" program. - * - * Keeping all of the state in a structure like this simplifies memory - * leak testing (at exit, anything left on the heap is suspect). A - * pointer to this structure is passed to most bsdtar internal - * functions. - */ -struct bsdtar { - /* Options */ - const char *filename; /* -f filename */ - char *pending_chdir; /* -C dir */ - const char *names_from_file; /* -T file */ - int bytes_per_block; /* -b block_size */ - int bytes_in_last_block; /* See -b handling. */ - int verbose; /* -v */ - unsigned int flags; /* Bitfield of boolean options */ - int extract_flags; /* Flags for extract operation */ - int readdisk_flags; /* Flags for read disk operation */ - int strip_components; /* Remove this many leading dirs */ - int gid; /* --gid */ - const char *gname; /* --gname */ - int uid; /* --uid */ - const char *uname; /* --uname */ - const char *passphrase; /* --passphrase */ - char mode; /* Program mode: 'c', 't', 'r', 'u', 'x' */ - char symlink_mode; /* H or L, per BSD conventions */ - const char *option_options; /* --options */ - char day_first; /* show day before month in -tv output */ - struct creation_set *cset; - - /* Option parser state */ - int getopt_state; - char *getopt_word; - - /* If >= 0, then close this when done. */ - int fd; - - /* Miscellaneous state information */ - int argc; - char **argv; - const char *argument; - size_t gs_width; /* For 'list_item' in read.c */ - size_t u_width; /* for 'list_item' in read.c */ - uid_t user_uid; /* UID running this program */ - int return_value; /* Value returned by main() */ - char warned_lead_slash; /* Already displayed warning */ - char next_line_is_dir; /* Used for -C parsing in -cT */ - - /* - * Data for various subsystems. Full definitions are located in - * the file where they are used. - */ - struct archive *diskreader; /* for write.c */ - struct archive_entry_linkresolver *resolver; /* for write.c */ - struct archive_dir *archive_dir; /* for write.c */ - struct name_cache *gname_cache; /* for write.c */ - char *buff; /* for write.c */ - size_t buff_size; /* for write.c */ - int first_fs; /* for write.c */ - struct archive *matching; /* for matching.c */ - struct security *security; /* for read.c */ - struct name_cache *uname_cache; /* for write.c */ - struct siginfo_data *siginfo; /* for siginfo.c */ - struct substitution *substitution; /* for subst.c */ - char *ppbuff; /* for util.c */ -}; - -/* Options for flags bitfield */ -#define OPTFLAG_AUTO_COMPRESS (0x00000001) /* -a */ -#define OPTFLAG_ABSOLUTE_PATHS (0x00000002) /* -P */ -#define OPTFLAG_CHROOT (0x00000004) /* --chroot */ -#define OPTFLAG_FAST_READ (0x00000008) /* --fast-read */ -#define OPTFLAG_IGNORE_ZEROS (0x00000010) /* --ignore-zeros */ -#define OPTFLAG_INTERACTIVE (0x00000020) /* -w */ -#define OPTFLAG_NO_OWNER (0x00000040) /* -o */ -#define OPTFLAG_NO_SUBDIRS (0x00000080) /* -n */ -#define OPTFLAG_NULL (0x00000100) /* --null */ -#define OPTFLAG_NUMERIC_OWNER (0x00000200) /* --numeric-owner */ -#define OPTFLAG_O (0x00000400) /* -o */ -#define OPTFLAG_STDOUT (0x00000800) /* -O */ -#define OPTFLAG_TOTALS (0x00001000) /* --totals */ -#define OPTFLAG_UNLINK_FIRST (0x00002000) /* -U */ -#define OPTFLAG_WARN_LINKS (0x00004000) /* --check-links */ -#define OPTFLAG_NO_XATTRS (0x00008000) /* --no-xattrs */ -#define OPTFLAG_XATTRS (0x00010000) /* --xattrs */ -#define OPTFLAG_NO_ACLS (0x00020000) /* --no-acls */ -#define OPTFLAG_ACLS (0x00040000) /* --acls */ -#define OPTFLAG_NO_FFLAGS (0x00080000) /* --no-fflags */ -#define OPTFLAG_FFLAGS (0x00100000) /* --fflags */ -#define OPTFLAG_NO_MAC_METADATA (0x00200000) /* --no-mac-metadata */ -#define OPTFLAG_MAC_METADATA (0x00400000) /* --mac-metadata */ -#define OPTFLAG_NO_READ_SPARSE (0x00800000) /* --no-read-sparse */ -#define OPTFLAG_READ_SPARSE (0x01000000) /* --read-sparse */ - -/* Fake short equivalents for long options that otherwise lack them. */ -enum { - OPTION_ACLS = 1, - OPTION_B64ENCODE, - OPTION_CHECK_LINKS, - OPTION_CHROOT, - OPTION_CLEAR_NOCHANGE_FFLAGS, - OPTION_EXCLUDE, - OPTION_EXCLUDE_VCS, - OPTION_FFLAGS, - OPTION_FORMAT, - OPTION_GID, - OPTION_GNAME, - OPTION_GRZIP, - OPTION_HELP, - OPTION_HFS_COMPRESSION, - OPTION_IGNORE_ZEROS, - OPTION_INCLUDE, - OPTION_KEEP_NEWER_FILES, - OPTION_LRZIP, - OPTION_LZ4, - OPTION_LZIP, - OPTION_LZMA, - OPTION_LZOP, - OPTION_MAC_METADATA, - OPTION_NEWER_CTIME, - OPTION_NEWER_CTIME_THAN, - OPTION_NEWER_MTIME, - OPTION_NEWER_MTIME_THAN, - OPTION_NODUMP, - OPTION_NOPRESERVE_HFS_COMPRESSION, - OPTION_NO_ACLS, - OPTION_NO_FFLAGS, - OPTION_NO_MAC_METADATA, - OPTION_NO_READ_SPARSE, - OPTION_NO_SAFE_WRITES, - OPTION_NO_SAME_OWNER, - OPTION_NO_SAME_PERMISSIONS, - OPTION_NO_XATTRS, - OPTION_NULL, - OPTION_NUMERIC_OWNER, - OPTION_OLDER_CTIME, - OPTION_OLDER_CTIME_THAN, - OPTION_OLDER_MTIME, - OPTION_OLDER_MTIME_THAN, - OPTION_ONE_FILE_SYSTEM, - OPTION_OPTIONS, - OPTION_PASSPHRASE, - OPTION_POSIX, - OPTION_READ_SPARSE, - OPTION_SAFE_WRITES, - OPTION_SAME_OWNER, - OPTION_STRIP_COMPONENTS, - OPTION_TOTALS, - OPTION_UID, - OPTION_UNAME, - OPTION_USE_COMPRESS_PROGRAM, - OPTION_UUENCODE, - OPTION_VERSION, - OPTION_XATTRS, - OPTION_ZSTD, -}; - -int bsdtar_getopt(struct bsdtar *); -void do_chdir(struct bsdtar *); -int edit_pathname(struct bsdtar *, struct archive_entry *); -int need_report(void); -int pathcmp(const char *a, const char *b); -void safe_fprintf(FILE *, const char *fmt, ...) __LA_PRINTF(2, 3); -void set_chdir(struct bsdtar *, const char *newdir); -const char *tar_i64toa(int64_t); -void tar_mode_c(struct bsdtar *bsdtar); -void tar_mode_r(struct bsdtar *bsdtar); -void tar_mode_t(struct bsdtar *bsdtar); -void tar_mode_u(struct bsdtar *bsdtar); -void tar_mode_x(struct bsdtar *bsdtar); -void usage(void) __LA_DEAD; -int yes(const char *fmt, ...) __LA_PRINTF(1, 2); - -#if defined(HAVE_REGEX_H) || defined(HAVE_PCREPOSIX_H) -void add_substitution(struct bsdtar *, const char *); -int apply_substitution(struct bsdtar *, const char *, char **, int, int); -void cleanup_substitution(struct bsdtar *); -#endif - -void cset_add_filter(struct creation_set *, const char *); -void cset_add_filter_program(struct creation_set *, const char *); -int cset_auto_compress(struct creation_set *, const char *); -void cset_free(struct creation_set *); -const char * cset_get_format(struct creation_set *); -struct creation_set *cset_new(void); -int cset_read_support_filter_program(struct creation_set *, - struct archive *); -void cset_set_format(struct creation_set *, const char *); -int cset_write_add_filters(struct creation_set *, - struct archive *, const void **); - -const char * passphrase_callback(struct archive *, void *); -void passphrase_free(char *); -void list_item_verbose(struct bsdtar *, FILE *, - struct archive_entry *); - -#endif diff --git a/thirdparty/libarchive/tar/bsdtar_platform.h b/thirdparty/libarchive/tar/bsdtar_platform.h deleted file mode 100644 index e73f9828b..000000000 --- a/thirdparty/libarchive/tar/bsdtar_platform.h +++ /dev/null @@ -1,132 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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/usr.bin/tar/bsdtar_platform.h,v 1.26 2008/12/06 07:37:14 kientzle Exp $ - */ - -/* - * This header is the first thing included in any of the bsdtar - * source files. As far as possible, platform-specific issues should - * be dealt with here and not within individual source files. - */ - -#ifndef BSDTAR_PLATFORM_H_INCLUDED -#define BSDTAR_PLATFORM_H_INCLUDED - -#if defined(PLATFORM_CONFIG_H) -/* Use hand-built config.h in environments that need it. */ -#include PLATFORM_CONFIG_H -#else -/* Not having a config.h of some sort is a serious problem. */ -#include "config.h" -#endif - -#if defined(_WIN32) && !defined(__CYGWIN__) -#include "bsdtar_windows.h" -#endif - -/* Get a real definition for __FBSDID if we can */ -#if HAVE_SYS_CDEFS_H -#include -#endif - -/* If not, define it so as to avoid dangling semicolons. */ -#ifndef __FBSDID -#define __FBSDID(a) struct _undefined_hack -#endif - -#ifdef HAVE_LIBARCHIVE -/* If we're using the platform libarchive, include system headers. */ -#include -#include -#else -/* Otherwise, include user headers. */ -#include "archive.h" -#include "archive_entry.h" -#endif - -#ifdef HAVE_LIBACL -#include -#endif - -/* - * Include "dirent.h" (or its equivalent on several different platforms). - * - * This is slightly modified from the GNU autoconf recipe. - * In particular, FreeBSD includes d_namlen in its dirent structure, - * so my configure script includes an explicit test for the d_namlen - * field. - */ -#if HAVE_DIRENT_H -# include -# if HAVE_DIRENT_D_NAMLEN -# define DIRENT_NAMLEN(dirent) (dirent)->d_namlen -# else -# define DIRENT_NAMLEN(dirent) strlen((dirent)->d_name) -# endif -#else -# define dirent direct -# define DIRENT_NAMLEN(dirent) (dirent)->d_namlen -# if HAVE_SYS_NDIR_H -# include -# endif -# if HAVE_SYS_DIR_H -# include -# endif -# if HAVE_NDIR_H -# include -# endif -#endif - -#if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC -#define ARCHIVE_STAT_CTIME_NANOS(st) (st)->st_ctimespec.tv_nsec -#define ARCHIVE_STAT_MTIME_NANOS(st) (st)->st_mtimespec.tv_nsec -#elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC -#define ARCHIVE_STAT_CTIME_NANOS(st) (st)->st_ctim.tv_nsec -#define ARCHIVE_STAT_MTIME_NANOS(st) (st)->st_mtim.tv_nsec -#elif HAVE_STRUCT_STAT_ST_MTIME_N -#define ARCHIVE_STAT_CTIME_NANOS(st) (st)->st_ctime_n -#define ARCHIVE_STAT_MTIME_NANOS(st) (st)->st_mtime_n -#elif HAVE_STRUCT_STAT_ST_UMTIME -#define ARCHIVE_STAT_CTIME_NANOS(st) (st)->st_uctime * 1000 -#define ARCHIVE_STAT_MTIME_NANOS(st) (st)->st_umtime * 1000 -#elif HAVE_STRUCT_STAT_ST_MTIME_USEC -#define ARCHIVE_STAT_CTIME_NANOS(st) (st)->st_ctime_usec * 1000 -#define ARCHIVE_STAT_MTIME_NANOS(st) (st)->st_mtime_usec * 1000 -#else -#define ARCHIVE_STAT_CTIME_NANOS(st) (0) -#define ARCHIVE_STAT_MTIME_NANOS(st) (0) -#endif - -/* How to mark functions that don't return. */ -/* This facilitates use of some newer static code analysis tools. */ -#undef __LA_DEAD -#if defined(__GNUC__) && (__GNUC__ > 2 || \ - (__GNUC__ == 2 && __GNUC_MINOR__ >= 5)) -#define __LA_DEAD __attribute__((__noreturn__)) -#else -#define __LA_DEAD -#endif - -#endif /* !BSDTAR_PLATFORM_H_INCLUDED */ diff --git a/thirdparty/libarchive/tar/bsdtar_windows.c b/thirdparty/libarchive/tar/bsdtar_windows.c deleted file mode 100644 index 41ce6eb78..000000000 --- a/thirdparty/libarchive/tar/bsdtar_windows.c +++ /dev/null @@ -1,298 +0,0 @@ -/*- - * Copyright (c) 2009 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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$ - */ - -#if defined(_WIN32) && !defined(__CYGWIN__) - -#include "bsdtar_platform.h" -#include -#include -#include -#include -#include -#ifdef HAVE_SYS_UTIME_H -#include -#endif -#include -#include -#include -#include -#include -#include - -#include "bsdtar.h" -#include "err.h" - -/* This may actually not be needed anymore. - * TODO: Review the error handling for chdir() failures and - * simply dump this if it's not really needed. */ -static void __tar_dosmaperr(unsigned long); - -/* - * Prepend "\\?\" to the path name and convert it to unicode to permit - * an extended-length path for a maximum total path length of 32767 - * characters. - * see also http://msdn.microsoft.com/en-us/library/aa365247.aspx - */ -static wchar_t * -permissive_name(const char *name) -{ - wchar_t *wn, *wnp; - wchar_t *ws, *wsp; - DWORD l, len, slen, alloclen; - int unc; - - len = (DWORD)strlen(name); - wn = malloc((len + 1) * sizeof(wchar_t)); - if (wn == NULL) - return (NULL); - l = MultiByteToWideChar(CP_ACP, 0, name, len, wn, len); - if (l == 0) { - free(wn); - return (NULL); - } - wn[l] = L'\0'; - - /* Get a full path names */ - l = GetFullPathNameW(wn, 0, NULL, NULL); - if (l == 0) { - free(wn); - return (NULL); - } - wnp = malloc(l * sizeof(wchar_t)); - if (wnp == NULL) { - free(wn); - return (NULL); - } - len = GetFullPathNameW(wn, l, wnp, NULL); - free(wn); - wn = wnp; - - if (wnp[0] == L'\\' && wnp[1] == L'\\' && - wnp[2] == L'?' && wnp[3] == L'\\') - /* We have already permissive names. */ - return (wn); - - if (wnp[0] == L'\\' && wnp[1] == L'\\' && - wnp[2] == L'.' && wnp[3] == L'\\') { - /* Device names */ - if (((wnp[4] >= L'a' && wnp[4] <= L'z') || - (wnp[4] >= L'A' && wnp[4] <= L'Z')) && - wnp[5] == L':' && wnp[6] == L'\\') - wnp[2] = L'?';/* Not device names. */ - return (wn); - } - - unc = 0; - if (wnp[0] == L'\\' && wnp[1] == L'\\' && wnp[2] != L'\\') { - wchar_t *p = &wnp[2]; - - /* Skip server-name letters. */ - while (*p != L'\\' && *p != L'\0') - ++p; - if (*p == L'\\') { - wchar_t *rp = ++p; - /* Skip share-name letters. */ - while (*p != L'\\' && *p != L'\0') - ++p; - if (*p == L'\\' && p != rp) { - /* Now, match patterns such as - * "\\server-name\share-name\" */ - wnp += 2; - len -= 2; - unc = 1; - } - } - } - - alloclen = slen = 4 + (unc * 4) + len + 1; - ws = wsp = malloc(slen * sizeof(wchar_t)); - if (ws == NULL) { - free(wn); - return (NULL); - } - /* prepend "\\?\" */ - wcsncpy(wsp, L"\\\\?\\", 4); - wsp += 4; - slen -= 4; - if (unc) { - /* append "UNC\" ---> "\\?\UNC\" */ - wcsncpy(wsp, L"UNC\\", 4); - wsp += 4; - slen -= 4; - } - wcsncpy(wsp, wnp, slen); - free(wn); - ws[alloclen - 1] = L'\0'; - return (ws); -} - -int -__tar_chdir(const char *path) -{ - wchar_t *ws; - int r; - - r = SetCurrentDirectoryA(path); - if (r == 0) { - if (GetLastError() != ERROR_FILE_NOT_FOUND) { - __tar_dosmaperr(GetLastError()); - return (-1); - } - } else - return (0); - ws = permissive_name(path); - if (ws == NULL) { - errno = EINVAL; - return (-1); - } - r = SetCurrentDirectoryW(ws); - free(ws); - if (r == 0) { - __tar_dosmaperr(GetLastError()); - return (-1); - } - return (0); -} - -/* - * The following function was modified from PostgreSQL sources and is - * subject to the copyright below. - */ -/*------------------------------------------------------------------------- - * - * win32error.c - * Map win32 error codes to errno values - * - * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/port/win32error.c,v 1.4 2008/01/01 19:46:00 momjian Exp $ - * - *------------------------------------------------------------------------- - */ -/* -PostgreSQL Database Management System -(formerly known as Postgres, then as Postgres95) - -Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group - -Portions Copyright (c) 1994, The Regents of the University of California - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose, without fee, and without a written agreement -is hereby granted, provided that the above copyright notice and this -paragraph and the following two paragraphs appear in all copies. - -IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR -DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING -LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS -DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO -PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -*/ - -static const struct { - DWORD winerr; - int doserr; -} doserrors[] = -{ - { ERROR_INVALID_FUNCTION, EINVAL }, - { ERROR_FILE_NOT_FOUND, ENOENT }, - { ERROR_PATH_NOT_FOUND, ENOENT }, - { ERROR_TOO_MANY_OPEN_FILES, EMFILE }, - { ERROR_ACCESS_DENIED, EACCES }, - { ERROR_INVALID_HANDLE, EBADF }, - { ERROR_ARENA_TRASHED, ENOMEM }, - { ERROR_NOT_ENOUGH_MEMORY, ENOMEM }, - { ERROR_INVALID_BLOCK, ENOMEM }, - { ERROR_BAD_ENVIRONMENT, E2BIG }, - { ERROR_BAD_FORMAT, ENOEXEC }, - { ERROR_INVALID_ACCESS, EINVAL }, - { ERROR_INVALID_DATA, EINVAL }, - { ERROR_INVALID_DRIVE, ENOENT }, - { ERROR_CURRENT_DIRECTORY, EACCES }, - { ERROR_NOT_SAME_DEVICE, EXDEV }, - { ERROR_NO_MORE_FILES, ENOENT }, - { ERROR_LOCK_VIOLATION, EACCES }, - { ERROR_SHARING_VIOLATION, EACCES }, - { ERROR_BAD_NETPATH, ENOENT }, - { ERROR_NETWORK_ACCESS_DENIED, EACCES }, - { ERROR_BAD_NET_NAME, ENOENT }, - { ERROR_FILE_EXISTS, EEXIST }, - { ERROR_CANNOT_MAKE, EACCES }, - { ERROR_FAIL_I24, EACCES }, - { ERROR_INVALID_PARAMETER, EINVAL }, - { ERROR_NO_PROC_SLOTS, EAGAIN }, - { ERROR_DRIVE_LOCKED, EACCES }, - { ERROR_BROKEN_PIPE, EPIPE }, - { ERROR_DISK_FULL, ENOSPC }, - { ERROR_INVALID_TARGET_HANDLE, EBADF }, - { ERROR_INVALID_HANDLE, EINVAL }, - { ERROR_WAIT_NO_CHILDREN, ECHILD }, - { ERROR_CHILD_NOT_COMPLETE, ECHILD }, - { ERROR_DIRECT_ACCESS_HANDLE, EBADF }, - { ERROR_NEGATIVE_SEEK, EINVAL }, - { ERROR_SEEK_ON_DEVICE, EACCES }, - { ERROR_DIR_NOT_EMPTY, ENOTEMPTY }, - { ERROR_NOT_LOCKED, EACCES }, - { ERROR_BAD_PATHNAME, ENOENT }, - { ERROR_MAX_THRDS_REACHED, EAGAIN }, - { ERROR_LOCK_FAILED, EACCES }, - { ERROR_ALREADY_EXISTS, EEXIST }, - { ERROR_FILENAME_EXCED_RANGE, ENOENT }, - { ERROR_NESTING_NOT_ALLOWED, EAGAIN }, - { ERROR_NOT_ENOUGH_QUOTA, ENOMEM } -}; - -static void -__tar_dosmaperr(unsigned long e) -{ - int i; - - if (e == 0) { - errno = 0; - return; - } - - for (i = 0; i < (int)sizeof(doserrors); i++) { - if (doserrors[i].winerr == e) { - errno = doserrors[i].doserr; - return; - } - } - - /* fprintf(stderr, "unrecognized win32 error code: %lu", e); */ - errno = EINVAL; - return; -} - -#endif diff --git a/thirdparty/libarchive/tar/bsdtar_windows.h b/thirdparty/libarchive/tar/bsdtar_windows.h deleted file mode 100644 index 308ad1107..000000000 --- a/thirdparty/libarchive/tar/bsdtar_windows.h +++ /dev/null @@ -1,66 +0,0 @@ -/*- - * Copyright (c) 2009 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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$ - */ - -#ifndef BSDTAR_WINDOWS_H -#define BSDTAR_WINDOWS_H 1 -#include -#include -#include -#include - -#ifndef PRId64 -#define PRId64 "I64" -#endif -#define geteuid() 0 - -#ifndef __WATCOMC__ - -#ifndef S_IFIFO -#define S_IFIFO 0010000 /* pipe */ -#endif - -#include /* Must include before redefining 'strdup' */ -#if !defined(__BORLANDC__) -#define strdup _strdup -#endif -#if !defined(__BORLANDC__) -#define getcwd _getcwd -#endif - -#define chdir __tar_chdir -int __tar_chdir(const char *); - -#ifndef S_ISREG -#define S_ISREG(a) (a & _S_IFREG) -#endif -#ifndef S_ISBLK -#define S_ISBLK(a) (0) -#endif - -#endif - -#endif /* BSDTAR_WINDOWS_H */ diff --git a/thirdparty/libarchive/tar/cmdline.c b/thirdparty/libarchive/tar/cmdline.c deleted file mode 100644 index d49e5b0d1..000000000 --- a/thirdparty/libarchive/tar/cmdline.c +++ /dev/null @@ -1,419 +0,0 @@ -/*- - * Copyright (c) 2003-2008 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -/* - * Command line parser for tar. - */ - -#include "bsdtar_platform.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "bsdtar.h" -#include "err.h" - -/* - * Short options for tar. Please keep this sorted. - */ -static const char *short_options - = "aBb:C:cf:HhI:JjkLlmnOoPpqrSs:T:tUuvW:wX:xyZz"; - -/* - * Long options for tar. Please keep this list sorted. - * - * The symbolic names for options that lack a short equivalent are - * defined in bsdtar.h. Also note that so far I've found no need - * to support optional arguments to long options. That would be - * a small change to the code below. - */ - -static const struct bsdtar_option { - const char *name; - int required; /* 1 if this option requires an argument. */ - int equivalent; /* Equivalent short option. */ -} tar_longopts[] = { - { "absolute-paths", 0, 'P' }, - { "append", 0, 'r' }, - { "acls", 0, OPTION_ACLS }, - { "auto-compress", 0, 'a' }, - { "b64encode", 0, OPTION_B64ENCODE }, - { "block-size", 1, 'b' }, - { "blocking-factor", 1, 'b' }, - { "bunzip2", 0, 'j' }, - { "bzip", 0, 'j' }, - { "bzip2", 0, 'j' }, - { "cd", 1, 'C' }, - { "check-links", 0, OPTION_CHECK_LINKS }, - { "chroot", 0, OPTION_CHROOT }, - { "clear-nochange-fflags", 0, OPTION_CLEAR_NOCHANGE_FFLAGS }, - { "compress", 0, 'Z' }, - { "confirmation", 0, 'w' }, - { "create", 0, 'c' }, - { "dereference", 0, 'L' }, - { "directory", 1, 'C' }, - { "disable-copyfile", 0, OPTION_NO_MAC_METADATA }, - { "exclude", 1, OPTION_EXCLUDE }, - { "exclude-from", 1, 'X' }, - { "exclude-vcs", 0, OPTION_EXCLUDE_VCS }, - { "extract", 0, 'x' }, - { "fast-read", 0, 'q' }, - { "fflags", 0, OPTION_FFLAGS }, - { "file", 1, 'f' }, - { "files-from", 1, 'T' }, - { "format", 1, OPTION_FORMAT }, - { "gid", 1, OPTION_GID }, - { "gname", 1, OPTION_GNAME }, - { "grzip", 0, OPTION_GRZIP }, - { "gunzip", 0, 'z' }, - { "gzip", 0, 'z' }, - { "help", 0, OPTION_HELP }, - { "hfsCompression", 0, OPTION_HFS_COMPRESSION }, - { "ignore-zeros", 0, OPTION_IGNORE_ZEROS }, - { "include", 1, OPTION_INCLUDE }, - { "insecure", 0, 'P' }, - { "interactive", 0, 'w' }, - { "keep-newer-files", 0, OPTION_KEEP_NEWER_FILES }, - { "keep-old-files", 0, 'k' }, - { "list", 0, 't' }, - { "lrzip", 0, OPTION_LRZIP }, - { "lz4", 0, OPTION_LZ4 }, - { "lzip", 0, OPTION_LZIP }, - { "lzma", 0, OPTION_LZMA }, - { "lzop", 0, OPTION_LZOP }, - { "mac-metadata", 0, OPTION_MAC_METADATA }, - { "modification-time", 0, 'm' }, - { "newer", 1, OPTION_NEWER_CTIME }, - { "newer-ctime", 1, OPTION_NEWER_CTIME }, - { "newer-ctime-than", 1, OPTION_NEWER_CTIME_THAN }, - { "newer-mtime", 1, OPTION_NEWER_MTIME }, - { "newer-mtime-than", 1, OPTION_NEWER_MTIME_THAN }, - { "newer-than", 1, OPTION_NEWER_CTIME_THAN }, - { "no-acls", 0, OPTION_NO_ACLS }, - { "no-fflags", 0, OPTION_NO_FFLAGS }, - { "no-mac-metadata", 0, OPTION_NO_MAC_METADATA }, - { "no-read-sparse", 0, OPTION_NO_READ_SPARSE }, - { "no-recursion", 0, 'n' }, - { "no-safe-writes", 0, OPTION_NO_SAFE_WRITES }, - { "no-same-owner", 0, OPTION_NO_SAME_OWNER }, - { "no-same-permissions", 0, OPTION_NO_SAME_PERMISSIONS }, - { "no-xattr", 0, OPTION_NO_XATTRS }, - { "no-xattrs", 0, OPTION_NO_XATTRS }, - { "nodump", 0, OPTION_NODUMP }, - { "nopreserveHFSCompression",0, OPTION_NOPRESERVE_HFS_COMPRESSION }, - { "norecurse", 0, 'n' }, - { "null", 0, OPTION_NULL }, - { "numeric-owner", 0, OPTION_NUMERIC_OWNER }, - { "older", 1, OPTION_OLDER_CTIME }, - { "older-ctime", 1, OPTION_OLDER_CTIME }, - { "older-ctime-than", 1, OPTION_OLDER_CTIME_THAN }, - { "older-mtime", 1, OPTION_OLDER_MTIME }, - { "older-mtime-than", 1, OPTION_OLDER_MTIME_THAN }, - { "older-than", 1, OPTION_OLDER_CTIME_THAN }, - { "one-file-system", 0, OPTION_ONE_FILE_SYSTEM }, - { "options", 1, OPTION_OPTIONS }, - { "passphrase", 1, OPTION_PASSPHRASE }, - { "posix", 0, OPTION_POSIX }, - { "preserve-permissions", 0, 'p' }, - { "read-full-blocks", 0, 'B' }, - { "read-sparse", 0, OPTION_READ_SPARSE }, - { "safe-writes", 0, OPTION_SAFE_WRITES }, - { "same-owner", 0, OPTION_SAME_OWNER }, - { "same-permissions", 0, 'p' }, - { "strip-components", 1, OPTION_STRIP_COMPONENTS }, - { "to-stdout", 0, 'O' }, - { "totals", 0, OPTION_TOTALS }, - { "uid", 1, OPTION_UID }, - { "uname", 1, OPTION_UNAME }, - { "uncompress", 0, 'Z' }, - { "unlink", 0, 'U' }, - { "unlink-first", 0, 'U' }, - { "update", 0, 'u' }, - { "use-compress-program", 1, OPTION_USE_COMPRESS_PROGRAM }, - { "uuencode", 0, OPTION_UUENCODE }, - { "verbose", 0, 'v' }, - { "version", 0, OPTION_VERSION }, - { "xattrs", 0, OPTION_XATTRS }, - { "xz", 0, 'J' }, - { "zstd", 0, OPTION_ZSTD }, - { NULL, 0, 0 } -}; - -/* - * This getopt implementation has two key features that common - * getopt_long() implementations lack. Apart from those, it's a - * straightforward option parser, considerably simplified by not - * needing to support the wealth of exotic getopt_long() features. It - * has, of course, been shamelessly tailored for bsdtar. (If you're - * looking for a generic getopt_long() implementation for your - * project, I recommend Gregory Pietsch's public domain getopt_long() - * implementation.) The two additional features are: - * - * Old-style tar arguments: The original tar implementation treated - * the first argument word as a list of single-character option - * letters. All arguments follow as separate words. For example, - * tar xbf 32 /dev/tape - * Here, the "xbf" is three option letters, "32" is the argument for - * "b" and "/dev/tape" is the argument for "f". We support this usage - * if the first command-line argument does not begin with '-'. We - * also allow regular short and long options to follow, e.g., - * tar xbf 32 /dev/tape -P --format=pax - * - * -W long options: There's an obscure GNU convention (only rarely - * supported even there) that allows "-W option=argument" as an - * alternative way to support long options. This was supported in - * early bsdtar as a way to access long options on platforms that did - * not support getopt_long() and is preserved here for backwards - * compatibility. (Of course, if I'd started with a custom - * command-line parser from the beginning, I would have had normal - * long option support on every platform so that hack wouldn't have - * been necessary. Oh, well. Some mistakes you just have to live - * with.) - * - * TODO: We should be able to use this to pull files and intermingled - * options (such as -C) from the command line in write mode. That - * will require a little rethinking of the argument handling in - * bsdtar.c. - * - * TODO: If we want to support arbitrary command-line options from -T - * input (as GNU tar does), we may need to extend this to handle option - * words from sources other than argv/argc. I'm not really sure if I - * like that feature of GNU tar, so it's certainly not a priority. - */ - -int -bsdtar_getopt(struct bsdtar *bsdtar) -{ - enum { state_start = 0, state_old_tar, state_next_word, - state_short, state_long }; - - const struct bsdtar_option *popt, *match = NULL, *match2 = NULL; - const char *p, *long_prefix = "--"; - size_t optlength; - int opt = '?'; - int required = 0; - - bsdtar->argument = NULL; - - /* First time through, initialize everything. */ - if (bsdtar->getopt_state == state_start) { - /* Skip program name. */ - ++bsdtar->argv; - --bsdtar->argc; - if (*bsdtar->argv == NULL) - return (-1); - /* Decide between "new style" and "old style" arguments. */ - if (bsdtar->argv[0][0] == '-') { - bsdtar->getopt_state = state_next_word; - } else { - bsdtar->getopt_state = state_old_tar; - bsdtar->getopt_word = *bsdtar->argv++; - --bsdtar->argc; - } - } - - /* - * We're parsing old-style tar arguments - */ - if (bsdtar->getopt_state == state_old_tar) { - /* Get the next option character. */ - opt = *bsdtar->getopt_word++; - if (opt == '\0') { - /* New-style args can follow old-style. */ - bsdtar->getopt_state = state_next_word; - } else { - /* See if it takes an argument. */ - p = strchr(short_options, opt); - if (p == NULL) - return ('?'); - if (p[1] == ':') { - bsdtar->argument = *bsdtar->argv; - if (bsdtar->argument == NULL) { - lafe_warnc(0, - "Option %c requires an argument", - opt); - return ('?'); - } - ++bsdtar->argv; - --bsdtar->argc; - } - } - } - - /* - * We're ready to look at the next word in argv. - */ - if (bsdtar->getopt_state == state_next_word) { - /* No more arguments, so no more options. */ - if (bsdtar->argv[0] == NULL) - return (-1); - /* Doesn't start with '-', so no more options. */ - if (bsdtar->argv[0][0] != '-') - return (-1); - /* "--" marks end of options; consume it and return. */ - if (strcmp(bsdtar->argv[0], "--") == 0) { - ++bsdtar->argv; - --bsdtar->argc; - return (-1); - } - /* Get next word for parsing. */ - bsdtar->getopt_word = *bsdtar->argv++; - --bsdtar->argc; - if (bsdtar->getopt_word[1] == '-') { - /* Set up long option parser. */ - bsdtar->getopt_state = state_long; - bsdtar->getopt_word += 2; /* Skip leading '--' */ - } else { - /* Set up short option parser. */ - bsdtar->getopt_state = state_short; - ++bsdtar->getopt_word; /* Skip leading '-' */ - } - } - - /* - * We're parsing a group of POSIX-style single-character options. - */ - if (bsdtar->getopt_state == state_short) { - /* Peel next option off of a group of short options. */ - opt = *bsdtar->getopt_word++; - if (opt == '\0') { - /* End of this group; recurse to get next option. */ - bsdtar->getopt_state = state_next_word; - return bsdtar_getopt(bsdtar); - } - - /* Does this option take an argument? */ - p = strchr(short_options, opt); - if (p == NULL) - return ('?'); - if (p[1] == ':') - required = 1; - - /* If it takes an argument, parse that. */ - if (required) { - /* If arg is run-in, bsdtar->getopt_word already points to it. */ - if (bsdtar->getopt_word[0] == '\0') { - /* Otherwise, pick up the next word. */ - bsdtar->getopt_word = *bsdtar->argv; - if (bsdtar->getopt_word == NULL) { - lafe_warnc(0, - "Option -%c requires an argument", - opt); - return ('?'); - } - ++bsdtar->argv; - --bsdtar->argc; - } - if (opt == 'W') { - bsdtar->getopt_state = state_long; - long_prefix = "-W "; /* For clearer errors. */ - } else { - bsdtar->getopt_state = state_next_word; - bsdtar->argument = bsdtar->getopt_word; - } - } - } - - /* We're reading a long option, including -W long=arg convention. */ - if (bsdtar->getopt_state == state_long) { - /* After this long option, we'll be starting a new word. */ - bsdtar->getopt_state = state_next_word; - - /* Option name ends at '=' if there is one. */ - p = strchr(bsdtar->getopt_word, '='); - if (p != NULL) { - optlength = (size_t)(p - bsdtar->getopt_word); - bsdtar->argument = (char *)(uintptr_t)(p + 1); - } else { - optlength = strlen(bsdtar->getopt_word); - } - - /* Search the table for an unambiguous match. */ - for (popt = tar_longopts; popt->name != NULL; popt++) { - /* Short-circuit if first chars don't match. */ - if (popt->name[0] != bsdtar->getopt_word[0]) - continue; - /* If option is a prefix of name in table, record it.*/ - if (strncmp(bsdtar->getopt_word, popt->name, optlength) == 0) { - match2 = match; /* Record up to two matches. */ - match = popt; - /* If it's an exact match, we're done. */ - if (strlen(popt->name) == optlength) { - match2 = NULL; /* Forget the others. */ - break; - } - } - } - - /* Fail if there wasn't a unique match. */ - if (match == NULL) { - lafe_warnc(0, - "Option %s%s is not supported", - long_prefix, bsdtar->getopt_word); - return ('?'); - } - if (match2 != NULL) { - lafe_warnc(0, - "Ambiguous option %s%s (matches --%s and --%s)", - long_prefix, bsdtar->getopt_word, match->name, match2->name); - return ('?'); - } - - /* We've found a unique match; does it need an argument? */ - if (match->required) { - /* Argument required: get next word if necessary. */ - if (bsdtar->argument == NULL) { - bsdtar->argument = *bsdtar->argv; - if (bsdtar->argument == NULL) { - lafe_warnc(0, - "Option %s%s requires an argument", - long_prefix, match->name); - return ('?'); - } - ++bsdtar->argv; - --bsdtar->argc; - } - } else { - /* Argument forbidden: fail if there is one. */ - if (bsdtar->argument != NULL) { - lafe_warnc(0, - "Option %s%s does not allow an argument", - long_prefix, match->name); - return ('?'); - } - } - return (match->equivalent); - } - - return (opt); -} diff --git a/thirdparty/libarchive/tar/config_freebsd.h b/thirdparty/libarchive/tar/config_freebsd.h deleted file mode 100644 index 37aa9dcae..000000000 --- a/thirdparty/libarchive/tar/config_freebsd.h +++ /dev/null @@ -1,84 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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/usr.bin/tar/config_freebsd.h,v 1.8 2008/11/29 20:06:53 kientzle Exp $ - */ - -/* A default configuration for FreeBSD, used if there is no config.h. */ - -#include /* __FreeBSD_version */ - -#undef HAVE_ATTR_XATTR_H -#define HAVE_CHROOT 1 -#define HAVE_DIRENT_D_NAMLEN 1 -#define HAVE_DIRENT_H 1 -#define HAVE_D_MD_ORDER 1 -#define HAVE_ERRNO_H 1 -#undef HAVE_EXT2FS_EXT2_FS_H -#define HAVE_FCHDIR 1 -#define HAVE_FCNTL_H 1 -#define HAVE_GRP_H 1 -#define HAVE_LANGINFO_H 1 -#undef HAVE_LIBACL -#define HAVE_LIBARCHIVE 1 -#define HAVE_LIMITS_H 1 -#define HAVE_LINK 1 -#undef HAVE_LINUX_EXT2_FS_H -#undef HAVE_LINUX_FS_H -#define HAVE_LOCALE_H 1 -#define HAVE_MBTOWC 1 -#undef HAVE_NDIR_H -#if __FreeBSD_version >= 450002 /* nl_langinfo introduced */ -#define HAVE_NL_LANGINFO 1 -#endif -#define HAVE_PATHS_H 1 -#define HAVE_PWD_H 1 -#define HAVE_READLINK 1 -#define HAVE_REGEX_H 1 -#define HAVE_SETLOCALE 1 -#define HAVE_SIGNAL_H 1 -#define HAVE_STDARG_H 1 -#define HAVE_STDLIB_H 1 -#define HAVE_STRING_H 1 -#define HAVE_STRUCT_STAT_ST_FLAGS 1 -#undef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC -#undef HAVE_STRUCT_STAT_ST_MTIME_N -#undef HAVE_STRUCT_STAT_ST_MTIME_USEC -#define HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC 1 -#undef HAVE_STRUCT_STAT_ST_UMTIME -#define HAVE_SYMLINK 1 -#define HAVE_SYS_CDEFS_H 1 -#undef HAVE_SYS_DIR_H -#define HAVE_SYS_IOCTL_H 1 -#undef HAVE_SYS_NDIR_H -#define HAVE_SYS_PARAM_H 1 -#define HAVE_SYS_STAT_H 1 -#define HAVE_TIME_H 1 -#define HAVE_SYS_TYPES_H 1 -#define HAVE_UINTMAX_T 1 -#define HAVE_UNISTD_H 1 -#define HAVE_UNSIGNED_LONG_LONG -#define HAVE_WCTYPE_H 1 -#define HAVE_ZLIB_H 1 -#undef MAJOR_IN_MKDEV diff --git a/thirdparty/libarchive/tar/creation_set.c b/thirdparty/libarchive/tar/creation_set.c deleted file mode 100644 index cfc5a642a..000000000 --- a/thirdparty/libarchive/tar/creation_set.c +++ /dev/null @@ -1,318 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "bsdtar_platform.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "bsdtar.h" -#include "err.h" - -struct creation_set { - char *create_format; - struct filter_set { - int program; /* Set 1 if filter is a program name */ - char *filter_name; - } *filters; - int filter_count; -}; - -struct suffix_code_t { - const char *suffix; - const char *form; -}; - -static const char * -get_suffix_code(const struct suffix_code_t *tbl, const char *suffix) -{ - int i; - - if (suffix == NULL) - return (NULL); - for (i = 0; tbl[i].suffix != NULL; i++) { - if (strcmp(tbl[i].suffix, suffix) == 0) - return (tbl[i].form); - } - return (NULL); -} - -static const char * -get_filter_code(const char *suffix) -{ - /* A pair of suffix and compression/filter. */ - static const struct suffix_code_t filters[] = { - { ".Z", "compress" }, - { ".bz2", "bzip2" }, - { ".gz", "gzip" }, - { ".grz", "grzip" }, - { ".lrz", "lrzip" }, - { ".lz", "lzip" }, - { ".lz4", "lz4" }, - { ".lzo", "lzop" }, - { ".lzma", "lzma" }, - { ".uu", "uuencode" }, - { ".xz", "xz" }, - { ".zst", "zstd"}, - { NULL, NULL } - }; - - return get_suffix_code(filters, suffix); -} - -static const char * -get_format_code(const char *suffix) -{ - /* A pair of suffix and format. */ - static const struct suffix_code_t formats[] = { - { ".7z", "7zip" }, - { ".ar", "arbsd" }, - { ".cpio", "cpio" }, - { ".iso", "iso9660" }, - { ".mtree", "mtree" }, - { ".shar", "shar" }, - { ".tar", "paxr" }, - { ".warc", "warc" }, - { ".xar", "xar" }, - { ".zip", "zip" }, - { NULL, NULL } - }; - - return get_suffix_code(formats, suffix); -} - -static const char * -decompose_alias(const char *suffix) -{ - static const struct suffix_code_t alias[] = { - { ".taz", ".tar.gz" }, - { ".tgz", ".tar.gz" }, - { ".tbz", ".tar.bz2" }, - { ".tbz2", ".tar.bz2" }, - { ".tz2", ".tar.bz2" }, - { ".tlz", ".tar.lzma" }, - { ".txz", ".tar.xz" }, - { ".tzo", ".tar.lzo" }, - { ".taZ", ".tar.Z" }, - { ".tZ", ".tar.Z" }, - { ".tzst", ".tar.zst" }, - { NULL, NULL } - }; - - return get_suffix_code(alias, suffix); -} - -static void -_cset_add_filter(struct creation_set *cset, int program, const char *filter) -{ - struct filter_set *new_ptr; - char *new_filter; - - new_ptr = (struct filter_set *)realloc(cset->filters, - sizeof(*cset->filters) * (cset->filter_count + 1)); - if (new_ptr == NULL) - lafe_errc(1, 0, "No memory"); - new_filter = strdup(filter); - if (new_filter == NULL) - lafe_errc(1, 0, "No memory"); - cset->filters = new_ptr; - cset->filters[cset->filter_count].program = program; - cset->filters[cset->filter_count].filter_name = new_filter; - cset->filter_count++; -} - -void -cset_add_filter(struct creation_set *cset, const char *filter) -{ - _cset_add_filter(cset, 0, filter); -} - -void -cset_add_filter_program(struct creation_set *cset, const char *filter) -{ - _cset_add_filter(cset, 1, filter); -} - -int -cset_read_support_filter_program(struct creation_set *cset, struct archive *a) -{ - int cnt = 0, i; - - for (i = 0; i < cset->filter_count; i++) { - if (cset->filters[i].program) { - archive_read_support_filter_program(a, - cset->filters[i].filter_name); - ++cnt; - } - } - return (cnt); -} - -int -cset_write_add_filters(struct creation_set *cset, struct archive *a, - const void **filter_name) -{ - int cnt = 0, i, r; - - for (i = 0; i < cset->filter_count; i++) { - if (cset->filters[i].program) - r = archive_write_add_filter_program(a, - cset->filters[i].filter_name); - else - r = archive_write_add_filter_by_name(a, - cset->filters[i].filter_name); - if (r < ARCHIVE_WARN) { - *filter_name = cset->filters[i].filter_name; - return (r); - } - ++cnt; - } - return (cnt); -} - -void -cset_set_format(struct creation_set *cset, const char *format) -{ - char *f; - - f = strdup(format); - if (f == NULL) - lafe_errc(1, 0, "No memory"); - free(cset->create_format); - cset->create_format = f; -} - -const char * -cset_get_format(struct creation_set *cset) -{ - return (cset->create_format); -} - -static void -_cleanup_filters(struct filter_set *filters, int count) -{ - int i; - - for (i = 0; i < count; i++) - free(filters[i].filter_name); - free(filters); -} - -/* - * Clean up a creation set. - */ -void -cset_free(struct creation_set *cset) -{ - _cleanup_filters(cset->filters, cset->filter_count); - free(cset->create_format); - free(cset); -} - -struct creation_set * -cset_new(void) -{ - return calloc(1, sizeof(struct creation_set)); -} - -/* - * Build a creation set by a file name suffix. - */ -int -cset_auto_compress(struct creation_set *cset, const char *filename) -{ - struct filter_set *old_filters; - char *name, *p; - const char *code; - int old_filter_count; - - name = strdup(filename); - if (name == NULL) - lafe_errc(1, 0, "No memory"); - /* Save previous filters. */ - old_filters = cset->filters; - old_filter_count = cset->filter_count; - cset->filters = NULL; - cset->filter_count = 0; - - for (;;) { - /* Get the suffix. */ - p = strrchr(name, '.'); - if (p == NULL) - break; - /* Suppose it indicates compression/filter type - * such as ".gz". */ - code = get_filter_code(p); - if (code != NULL) { - cset_add_filter(cset, code); - *p = '\0'; - continue; - } - /* Suppose it indicates format type such as ".tar". */ - code = get_format_code(p); - if (code != NULL) { - cset_set_format(cset, code); - break; - } - /* Suppose it indicates alias such as ".tgz". */ - code = decompose_alias(p); - if (code == NULL) - break; - /* Replace the suffix. */ - *p = '\0'; - name = realloc(name, strlen(name) + strlen(code) + 1); - if (name == NULL) - lafe_errc(1, 0, "No memory"); - strcat(name, code); - } - free(name); - if (cset->filters) { - struct filter_set *v; - int i, r; - - /* Release previous filters. */ - _cleanup_filters(old_filters, old_filter_count); - - v = malloc(sizeof(*v) * cset->filter_count); - if (v == NULL) - lafe_errc(1, 0, "No memory"); - /* Reverse filter sequence. */ - for (i = 0, r = cset->filter_count; r > 0; ) - v[i++] = cset->filters[--r]; - free(cset->filters); - cset->filters = v; - return (1); - } else { - /* Put previous filters back. */ - cset->filters = old_filters; - cset->filter_count = old_filter_count; - return (0); - } -} diff --git a/thirdparty/libarchive/tar/read.c b/thirdparty/libarchive/tar/read.c deleted file mode 100644 index b95996619..000000000 --- a/thirdparty/libarchive/tar/read.c +++ /dev/null @@ -1,419 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "bsdtar_platform.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/read.c,v 1.40 2008/08/21 06:41:14 kientzle Exp $"); - -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_PARAM_H -#include -#endif -#ifdef HAVE_SYS_STAT_H -#include -#endif - -#ifdef HAVE_ERRNO_H -#include -#endif - -#ifdef HAVE_FCNTL_H -#include -#endif - -#ifdef HAVE_GRP_H -#include -#endif - -#ifdef HAVE_IO_H -#include -#endif - -#ifdef HAVE_LIMITS_H -#include -#endif -#ifdef HAVE_PWD_H -#include -#endif -#ifdef HAVE_STDINT_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_TIME_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif - -#include "bsdtar.h" -#include "err.h" - -struct progress_data { - struct bsdtar *bsdtar; - struct archive *archive; - struct archive_entry *entry; -}; - -static void read_archive(struct bsdtar *bsdtar, char mode, struct archive *); -static int unmatched_inclusions_warn(struct archive *matching, const char *); - - -void -tar_mode_t(struct bsdtar *bsdtar) -{ - read_archive(bsdtar, 't', NULL); - if (unmatched_inclusions_warn(bsdtar->matching, - "Not found in archive") != 0) - bsdtar->return_value = 1; -} - -void -tar_mode_x(struct bsdtar *bsdtar) -{ - struct archive *writer; - - writer = archive_write_disk_new(); - if (writer == NULL) - lafe_errc(1, ENOMEM, "Cannot allocate disk writer object"); - if ((bsdtar->flags & OPTFLAG_NUMERIC_OWNER) == 0) - archive_write_disk_set_standard_lookup(writer); - archive_write_disk_set_options(writer, bsdtar->extract_flags); - - read_archive(bsdtar, 'x', writer); - - if (unmatched_inclusions_warn(bsdtar->matching, - "Not found in archive") != 0) - bsdtar->return_value = 1; - archive_write_free(writer); -} - -static void -progress_func(void *cookie) -{ - struct progress_data *progress_data = (struct progress_data *)cookie; - struct bsdtar *bsdtar = progress_data->bsdtar; - struct archive *a = progress_data->archive; - struct archive_entry *entry = progress_data->entry; - uint64_t comp, uncomp; - int compression; - - if (!need_report()) - return; - - if (bsdtar->verbose) - fprintf(stderr, "\n"); - if (a != NULL) { - comp = archive_filter_bytes(a, -1); - uncomp = archive_filter_bytes(a, 0); - if (comp > uncomp) - compression = 0; - else - compression = (int)((uncomp - comp) * 100 / uncomp); - fprintf(stderr, - "In: %s bytes, compression %d%%;", - tar_i64toa(comp), compression); - fprintf(stderr, " Out: %d files, %s bytes\n", - archive_file_count(a), tar_i64toa(uncomp)); - } - if (entry != NULL) { - safe_fprintf(stderr, "Current: %s", - archive_entry_pathname(entry)); - fprintf(stderr, " (%s bytes)\n", - tar_i64toa(archive_entry_size(entry))); - } -} - -/* - * Handle 'x' and 't' modes. - */ -static void -read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer) -{ - struct progress_data progress_data; - FILE *out; - struct archive *a; - struct archive_entry *entry; - const char *reader_options; - int r; - - while (*bsdtar->argv) { - if (archive_match_include_pattern(bsdtar->matching, - *bsdtar->argv) != ARCHIVE_OK) - lafe_errc(1, 0, "Error inclusion pattern: %s", - archive_error_string(bsdtar->matching)); - bsdtar->argv++; - } - - if (bsdtar->names_from_file != NULL) - if (archive_match_include_pattern_from_file( - bsdtar->matching, bsdtar->names_from_file, - (bsdtar->flags & OPTFLAG_NULL)) != ARCHIVE_OK) - lafe_errc(1, 0, "Error inclusion pattern: %s", - archive_error_string(bsdtar->matching)); - - a = archive_read_new(); - if (cset_read_support_filter_program(bsdtar->cset, a) == 0) - archive_read_support_filter_all(a); - archive_read_support_format_all(a); - - reader_options = getenv(ENV_READER_OPTIONS); - if (reader_options != NULL) { - size_t module_len = sizeof(IGNORE_WRONG_MODULE_NAME) - 1; - size_t opt_len = strlen(reader_options) + 1; - char *p; - /* Set default read options. */ - if ((p = malloc(module_len + opt_len)) == NULL) - lafe_errc(1, errno, "Out of memory"); - /* Prepend magic code to ignore options for - * a format or modules which are not added to - * the archive read object. */ - memcpy(p, IGNORE_WRONG_MODULE_NAME, module_len); - memcpy(p + module_len, reader_options, opt_len); - r = archive_read_set_options(a, p); - free(p); - if (r == ARCHIVE_FATAL) - lafe_errc(1, 0, "%s", archive_error_string(a)); - else - archive_clear_error(a); - } - if (ARCHIVE_OK != archive_read_set_options(a, bsdtar->option_options)) - lafe_errc(1, 0, "%s", archive_error_string(a)); - if (bsdtar->flags & OPTFLAG_IGNORE_ZEROS) - if (archive_read_set_options(a, - "read_concatenated_archives") != ARCHIVE_OK) - lafe_errc(1, 0, "%s", archive_error_string(a)); - if (bsdtar->passphrase != NULL) - r = archive_read_add_passphrase(a, bsdtar->passphrase); - else - r = archive_read_set_passphrase_callback(a, bsdtar, - &passphrase_callback); - if (r != ARCHIVE_OK) - lafe_errc(1, 0, "%s", archive_error_string(a)); - if (archive_read_open_filename(a, bsdtar->filename, - bsdtar->bytes_per_block)) - lafe_errc(1, 0, "Error opening archive: %s", - archive_error_string(a)); - - do_chdir(bsdtar); - - if (mode == 'x') { - /* Set an extract callback so that we can handle SIGINFO. */ - progress_data.bsdtar = bsdtar; - progress_data.archive = a; - archive_read_extract_set_progress_callback(a, progress_func, - &progress_data); - } - - if (mode == 'x' && (bsdtar->flags & OPTFLAG_CHROOT)) { -#if HAVE_CHROOT - if (chroot(".") != 0) - lafe_errc(1, errno, "Can't chroot to \".\""); -#else - lafe_errc(1, 0, - "chroot isn't supported on this platform"); -#endif - } - -#if defined(_WIN32) && !defined(__CYGWIN__) - if (mode == 'x' && (bsdtar->flags & OPTFLAG_STDOUT)) { - _setmode(1, _O_BINARY); - } -#endif - - for (;;) { - /* Support --fast-read option */ - const char *p; - if ((bsdtar->flags & OPTFLAG_FAST_READ) && - archive_match_path_unmatched_inclusions(bsdtar->matching) == 0) - break; - - r = archive_read_next_header(a, &entry); - progress_data.entry = entry; - if (r == ARCHIVE_EOF) - break; - if (r < ARCHIVE_OK) - lafe_warnc(0, "%s", archive_error_string(a)); - if (r <= ARCHIVE_WARN) - bsdtar->return_value = 1; - if (r == ARCHIVE_RETRY) { - /* Retryable error: try again */ - lafe_warnc(0, "Retrying..."); - continue; - } - if (r == ARCHIVE_FATAL) - break; - p = archive_entry_pathname(entry); - if (p == NULL || p[0] == '\0') { - lafe_warnc(0, "Archive entry has empty or unreadable filename ... skipping."); - bsdtar->return_value = 1; - continue; - } - - if (bsdtar->uid >= 0) { - archive_entry_set_uid(entry, bsdtar->uid); - archive_entry_set_uname(entry, NULL); - } - if (bsdtar->gid >= 0) { - archive_entry_set_gid(entry, bsdtar->gid); - archive_entry_set_gname(entry, NULL); - } - if (bsdtar->uname) - archive_entry_set_uname(entry, bsdtar->uname); - if (bsdtar->gname) - archive_entry_set_gname(entry, bsdtar->gname); - - /* - * Note that pattern exclusions are checked before - * pathname rewrites are handled. This gives more - * control over exclusions, since rewrites always lose - * information. (For example, consider a rewrite - * s/foo[0-9]/foo/. If we check exclusions after the - * rewrite, there would be no way to exclude foo1/bar - * while allowing foo2/bar.) - */ - if (archive_match_excluded(bsdtar->matching, entry)) - continue; /* Excluded by a pattern test. */ - - if (mode == 't') { - /* Perversely, gtar uses -O to mean "send to stderr" - * when used with -t. */ - out = (bsdtar->flags & OPTFLAG_STDOUT) ? - stderr : stdout; - - /* - * TODO: Provide some reasonable way to - * preview rewrites. gtar always displays - * the unedited path in -t output, which means - * you cannot easily preview rewrites. - */ - if (bsdtar->verbose < 2) - safe_fprintf(out, "%s", - archive_entry_pathname(entry)); - else - list_item_verbose(bsdtar, out, entry); - fflush(out); - r = archive_read_data_skip(a); - if (r == ARCHIVE_WARN) { - fprintf(out, "\n"); - lafe_warnc(0, "%s", - archive_error_string(a)); - } - if (r == ARCHIVE_RETRY) { - fprintf(out, "\n"); - lafe_warnc(0, "%s", - archive_error_string(a)); - } - if (r == ARCHIVE_FATAL) { - fprintf(out, "\n"); - lafe_warnc(0, "%s", - archive_error_string(a)); - bsdtar->return_value = 1; - break; - } - fprintf(out, "\n"); - } else { - /* Note: some rewrite failures prevent extraction. */ - if (edit_pathname(bsdtar, entry)) - continue; /* Excluded by a rewrite failure. */ - - if ((bsdtar->flags & OPTFLAG_INTERACTIVE) && - !yes("extract '%s'", archive_entry_pathname(entry))) - continue; - - if (bsdtar->verbose > 1) { - /* GNU tar uses -tv format with -xvv */ - safe_fprintf(stderr, "x "); - list_item_verbose(bsdtar, stderr, entry); - fflush(stderr); - } else if (bsdtar->verbose > 0) { - /* Format follows SUSv2, including the - * deferred '\n'. */ - safe_fprintf(stderr, "x %s", - archive_entry_pathname(entry)); - fflush(stderr); - } - - /* TODO siginfo_printinfo(bsdtar, 0); */ - - if (bsdtar->flags & OPTFLAG_STDOUT) - r = archive_read_data_into_fd(a, 1); - else - r = archive_read_extract2(a, entry, writer); - if (r != ARCHIVE_OK) { - if (!bsdtar->verbose) - safe_fprintf(stderr, "%s", archive_entry_pathname(entry)); - fprintf(stderr, ": %s: ", archive_error_string(a)); - fprintf(stderr, "%s", strerror(errno)); - if (!bsdtar->verbose) - fprintf(stderr, "\n"); - bsdtar->return_value = 1; - } - if (bsdtar->verbose) - fprintf(stderr, "\n"); - if (r == ARCHIVE_FATAL) - break; - } - } - - - r = archive_read_close(a); - if (r != ARCHIVE_OK) - lafe_warnc(0, "%s", archive_error_string(a)); - if (r <= ARCHIVE_WARN) - bsdtar->return_value = 1; - - if (bsdtar->verbose > 2) - fprintf(stdout, "Archive Format: %s, Compression: %s\n", - archive_format_name(a), archive_filter_name(a, 0)); - - archive_read_free(a); -} - - -static int -unmatched_inclusions_warn(struct archive *matching, const char *msg) -{ - const char *p; - int r; - - if (matching == NULL) - return (0); - - while ((r = archive_match_path_unmatched_inclusions_next( - matching, &p)) == ARCHIVE_OK) - lafe_warnc(0, "%s: %s", p, msg); - if (r == ARCHIVE_FATAL) - lafe_errc(1, errno, "Out of memory"); - - return (archive_match_path_unmatched_inclusions(matching)); -} diff --git a/thirdparty/libarchive/tar/subst.c b/thirdparty/libarchive/tar/subst.c deleted file mode 100644 index 55ad63dce..000000000 --- a/thirdparty/libarchive/tar/subst.c +++ /dev/null @@ -1,328 +0,0 @@ -/*- - * Copyright (c) 2008 Joerg Sonnenberger - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "bsdtar_platform.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/subst.c,v 1.4 2008/06/15 10:08:16 kientzle Exp $"); - -#if defined(HAVE_REGEX_H) || defined(HAVE_PCREPOSIX_H) -#include "bsdtar.h" - -#include -#ifdef HAVE_PCREPOSIX_H -#include -#else -#include -#endif -#include -#include - -#ifndef REG_BASIC -#define REG_BASIC 0 -#endif - -#include "err.h" - -struct subst_rule { - struct subst_rule *next; - regex_t re; - char *result; - unsigned int global:1, print:1, regular:1, symlink:1, hardlink:1; -}; - -struct substitution { - struct subst_rule *first_rule, *last_rule; -}; - -static void -init_substitution(struct bsdtar *bsdtar) -{ - struct substitution *subst; - - bsdtar->substitution = subst = malloc(sizeof(*subst)); - if (subst == NULL) - lafe_errc(1, errno, "Out of memory"); - subst->first_rule = subst->last_rule = NULL; -} - -void -add_substitution(struct bsdtar *bsdtar, const char *rule_text) -{ - struct subst_rule *rule; - struct substitution *subst; - const char *end_pattern, *start_subst; - char *pattern; - int r; - - if ((subst = bsdtar->substitution) == NULL) { - init_substitution(bsdtar); - subst = bsdtar->substitution; - } - - rule = malloc(sizeof(*rule)); - if (rule == NULL) - lafe_errc(1, errno, "Out of memory"); - rule->next = NULL; - rule->result = NULL; - - if (subst->last_rule == NULL) - subst->first_rule = rule; - else - subst->last_rule->next = rule; - subst->last_rule = rule; - - if (*rule_text == '\0') - lafe_errc(1, 0, "Empty replacement string"); - end_pattern = strchr(rule_text + 1, *rule_text); - if (end_pattern == NULL) - lafe_errc(1, 0, "Invalid replacement string"); - - pattern = malloc(end_pattern - rule_text); - if (pattern == NULL) - lafe_errc(1, errno, "Out of memory"); - memcpy(pattern, rule_text + 1, end_pattern - rule_text - 1); - pattern[end_pattern - rule_text - 1] = '\0'; - - if ((r = regcomp(&rule->re, pattern, REG_BASIC)) != 0) { - char buf[80]; - regerror(r, &rule->re, buf, sizeof(buf)); - lafe_errc(1, 0, "Invalid regular expression: %s", buf); - } - free(pattern); - - start_subst = end_pattern + 1; - end_pattern = strchr(start_subst, *rule_text); - if (end_pattern == NULL) - lafe_errc(1, 0, "Invalid replacement string"); - - rule->result = malloc(end_pattern - start_subst + 1); - if (rule->result == NULL) - lafe_errc(1, errno, "Out of memory"); - memcpy(rule->result, start_subst, end_pattern - start_subst); - rule->result[end_pattern - start_subst] = '\0'; - - /* Defaults */ - rule->global = 0; /* Don't do multiple replacements. */ - rule->print = 0; /* Don't print. */ - rule->regular = 1; /* Rewrite regular filenames. */ - rule->symlink = 1; /* Rewrite symlink targets. */ - rule->hardlink = 1; /* Rewrite hardlink targets. */ - - while (*++end_pattern) { - switch (*end_pattern) { - case 'g': - case 'G': - rule->global = 1; - break; - case 'h': - rule->hardlink = 1; - break; - case 'H': - rule->hardlink = 0; - break; - case 'p': - case 'P': - rule->print = 1; - break; - case 'r': - rule->regular = 1; - break; - case 'R': - rule->regular = 0; - break; - case 's': - rule->symlink = 1; - break; - case 'S': - rule->symlink = 0; - break; - default: - lafe_errc(1, 0, "Invalid replacement flag %c", *end_pattern); - } - } -} - -static void -realloc_strncat(char **str, const char *append, size_t len) -{ - char *new_str; - size_t old_len; - - if (*str == NULL) - old_len = 0; - else - old_len = strlen(*str); - - new_str = malloc(old_len + len + 1); - if (new_str == NULL) - lafe_errc(1, errno, "Out of memory"); - if (*str != NULL) - memcpy(new_str, *str, old_len); - memcpy(new_str + old_len, append, len); - new_str[old_len + len] = '\0'; - free(*str); - *str = new_str; -} - -static void -realloc_strcat(char **str, const char *append) -{ - char *new_str; - size_t old_len; - - if (*str == NULL) - old_len = 0; - else - old_len = strlen(*str); - - new_str = malloc(old_len + strlen(append) + 1); - if (new_str == NULL) - lafe_errc(1, errno, "Out of memory"); - if (*str != NULL) - memcpy(new_str, *str, old_len); - strcpy(new_str + old_len, append); - free(*str); - *str = new_str; -} - -int -apply_substitution(struct bsdtar *bsdtar, const char *name, char **result, - int symlink_target, int hardlink_target) -{ - const char *path = name; - regmatch_t matches[10]; - size_t i, j; - struct subst_rule *rule; - struct substitution *subst; - int c, got_match, print_match; - - *result = NULL; - - if ((subst = bsdtar->substitution) == NULL) - return 0; - - got_match = 0; - print_match = 0; - - for (rule = subst->first_rule; rule != NULL; rule = rule->next) { - if (symlink_target) { - if (!rule->symlink) - continue; - } else if (hardlink_target) { - if (!rule->hardlink) - continue; - } else { /* Regular filename. */ - if (!rule->regular) - continue; - } - - while (1) { - if (regexec(&rule->re, name, 10, matches, 0)) - break; - - got_match = 1; - print_match |= rule->print; - realloc_strncat(result, name, matches[0].rm_so); - - for (i = 0, j = 0; rule->result[i] != '\0'; ++i) { - if (rule->result[i] == '~') { - realloc_strncat(result, rule->result + j, i - j); - realloc_strncat(result, - name + matches[0].rm_so, - matches[0].rm_eo - matches[0].rm_so); - j = i + 1; - continue; - } - if (rule->result[i] != '\\') - continue; - - ++i; - c = rule->result[i]; - switch (c) { - case '~': - case '\\': - realloc_strncat(result, rule->result + j, i - j - 1); - j = i; - break; - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - realloc_strncat(result, rule->result + j, i - j - 1); - if ((size_t)(c - '0') > (size_t)(rule->re.re_nsub)) { - free(*result); - *result = NULL; - return -1; - } - realloc_strncat(result, name + matches[c - '0'].rm_so, matches[c - '0'].rm_eo - matches[c - '0'].rm_so); - j = i + 1; - break; - default: - /* Just continue; */ - break; - } - - } - - realloc_strcat(result, rule->result + j); - - name += matches[0].rm_eo; - - if (!rule->global) - break; - } - } - - if (got_match) - realloc_strcat(result, name); - - if (print_match) - fprintf(stderr, "%s >> %s\n", path, *result); - - return got_match; -} - -void -cleanup_substitution(struct bsdtar *bsdtar) -{ - struct subst_rule *rule; - struct substitution *subst; - - if ((subst = bsdtar->substitution) == NULL) - return; - - while ((rule = subst->first_rule) != NULL) { - subst->first_rule = rule->next; - free(rule->result); - regfree(&rule->re); - free(rule); - } - free(subst); -} -#endif /* defined(HAVE_REGEX_H) || defined(HAVE_PCREPOSIX_H) */ diff --git a/thirdparty/libarchive/tar/test/CMakeLists.txt b/thirdparty/libarchive/tar/test/CMakeLists.txt deleted file mode 100644 index 3b6675393..000000000 --- a/thirdparty/libarchive/tar/test/CMakeLists.txt +++ /dev/null @@ -1,128 +0,0 @@ -############################################ -# -# How to build bsdtar_test -# -############################################ -IF(ENABLE_TAR AND ENABLE_TEST) - SET(bsdtar_test_SOURCES - ../../test_utils/test_utils.c - ../../test_utils/test_main.c - test.h - test_0.c - test_basic.c - test_copy.c - test_empty_mtree.c - test_extract_tar_Z.c - test_extract_tar_bz2.c - test_extract_tar_grz.c - test_extract_tar_gz.c - test_extract_tar_lrz.c - test_extract_tar_lz.c - test_extract_tar_lz4.c - test_extract_tar_lzma.c - test_extract_tar_lzo.c - test_extract_tar_xz.c - test_extract_tar_zstd.c - test_format_newc.c - test_help.c - test_leading_slash.c - test_missing_file.c - test_option_C_upper.c - test_option_C_mtree.c - test_option_H_upper.c - test_option_L_upper.c - test_option_O_upper.c - test_option_T_upper.c - test_option_U_upper.c - test_option_X_upper.c - test_option_a.c - test_option_acls.c - test_option_b.c - test_option_b64encode.c - test_option_exclude.c - test_option_exclude_vcs.c - test_option_fflags.c - test_option_gid_gname.c - test_option_grzip.c - test_option_ignore_zeros.c - test_option_j.c - test_option_k.c - test_option_keep_newer_files.c - test_option_lrzip.c - test_option_lz4.c - test_option_lzma.c - test_option_lzop.c - test_option_n.c - test_option_newer_than.c - test_option_nodump.c - test_option_older_than.c - test_option_passphrase.c - test_option_q.c - test_option_r.c - test_option_s.c - test_option_safe_writes.c - test_option_uid_uname.c - test_option_uuencode.c - test_option_xattrs.c - test_option_xz.c - test_option_z.c - test_option_zstd.c - test_patterns.c - test_print_longpath.c - test_stdio.c - test_strip_components.c - test_symlink_dir.c - test_version.c - test_windows.c - ) - - # - # Register target - # - ADD_EXECUTABLE(bsdtar_test ${bsdtar_test_SOURCES}) - IF(ENABLE_ACL) - SET(TEST_ACL_LIBS "") - IF(HAVE_LIBACL) - LIST(APPEND TEST_ACL_LIBS ${ACL_LIBRARY}) - ENDIF(HAVE_LIBACL) - IF(HAVE_LIBRICHACL) - LIST(APPEND TEST_ACL_LIBS ${RICHACL_LIBRARY}) - ENDIF(HAVE_LIBRICHACL) - TARGET_LINK_LIBRARIES(bsdtar_test ${TEST_ACL_LIBS}) - ENDIF(ENABLE_ACL) - SET_PROPERTY(TARGET bsdtar_test PROPERTY COMPILE_DEFINITIONS LIST_H) - - # - # Generate list.h by grepping DEFINE_TEST() lines out of the C sources. - # - GENERATE_LIST_H(${CMAKE_CURRENT_BINARY_DIR}/list.h - ${CMAKE_CURRENT_LIST_FILE} ${bsdtar_test_SOURCES}) - SET_PROPERTY(DIRECTORY APPEND PROPERTY INCLUDE_DIRECTORIES - ${CMAKE_CURRENT_BINARY_DIR}) - - # list.h has a line DEFINE_TEST(testname) for every - # test. We can use that to define the tests for cmake by - # defining a DEFINE_TEST macro and reading list.h in. - MACRO (DEFINE_TEST _testname) - ADD_TEST( - NAME bsdtar_${_testname} - COMMAND bsdtar_test -vv - -p $ - -r ${CMAKE_CURRENT_SOURCE_DIR} - ${_testname}) - ENDMACRO (DEFINE_TEST _testname) - - INCLUDE(${CMAKE_CURRENT_BINARY_DIR}/list.h) - INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) - INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/test_utils) - INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/tar/test) - - # Experimental new test handling - ADD_CUSTOM_TARGET(run_bsdtar_test - COMMAND bsdtar_test -p $ - -r ${CMAKE_CURRENT_SOURCE_DIR} - -vv) - ADD_DEPENDENCIES(run_bsdtar_test bsdtar) - ADD_DEPENDENCIES(run_all_tests run_bsdtar_test) - -ENDIF(ENABLE_TAR AND ENABLE_TEST) diff --git a/thirdparty/libarchive/tar/test/list.h b/thirdparty/libarchive/tar/test/list.h deleted file mode 100644 index e52b7f277..000000000 --- a/thirdparty/libarchive/tar/test/list.h +++ /dev/null @@ -1,70 +0,0 @@ -DEFINE_TEST(test_0) -DEFINE_TEST(test_basic) -DEFINE_TEST(test_copy) -DEFINE_TEST(test_empty_mtree) -DEFINE_TEST(test_extract_tar_bz2) -DEFINE_TEST(test_extract_tar_grz) -DEFINE_TEST(test_extract_tar_gz) -DEFINE_TEST(test_extract_tar_lrz) -DEFINE_TEST(test_extract_tar_lz4) -DEFINE_TEST(test_extract_tar_lz) -DEFINE_TEST(test_extract_tar_lzma) -DEFINE_TEST(test_extract_tar_lzo) -DEFINE_TEST(test_extract_tar_xz) -DEFINE_TEST(test_extract_tar_Z) -DEFINE_TEST(test_extract_tar_zstd) -DEFINE_TEST(test_format_newc) -DEFINE_TEST(test_help) -DEFINE_TEST(test_leading_slash) -DEFINE_TEST(test_missing_file) -DEFINE_TEST(test_option_a) -DEFINE_TEST(test_option_acls) -DEFINE_TEST(test_option_b64encode) -DEFINE_TEST(test_option_b) -DEFINE_TEST(test_option_C_mtree) -DEFINE_TEST(test_option_C_upper) -DEFINE_TEST(test_option_exclude) -DEFINE_TEST(test_option_exclude_vcs) -DEFINE_TEST(test_option_fflags) -DEFINE_TEST(test_option_gid_gname) -DEFINE_TEST(test_option_grzip) -DEFINE_TEST(test_option_H_upper) -DEFINE_TEST(test_option_ignore_zeros_mode_t) -DEFINE_TEST(test_option_ignore_zeros_mode_x) -DEFINE_TEST(test_option_ignore_zeros_mode_c) -DEFINE_TEST(test_option_ignore_zeros_mode_r) -DEFINE_TEST(test_option_ignore_zeros_mode_u) -DEFINE_TEST(test_option_j) -DEFINE_TEST(test_option_k) -DEFINE_TEST(test_option_keep_newer_files) -DEFINE_TEST(test_option_lrzip) -DEFINE_TEST(test_option_L_upper) -DEFINE_TEST(test_option_lz4) -DEFINE_TEST(test_option_lzma) -DEFINE_TEST(test_option_lzop) -DEFINE_TEST(test_option_n) -DEFINE_TEST(test_option_newer_than) -DEFINE_TEST(test_option_nodump) -DEFINE_TEST(test_option_older_than) -DEFINE_TEST(test_option_O_upper) -DEFINE_TEST(test_option_passphrase) -DEFINE_TEST(test_option_q) -DEFINE_TEST(test_option_r) -DEFINE_TEST(test_option_safe_writes) -DEFINE_TEST(test_option_s) -DEFINE_TEST(test_option_T_upper) -DEFINE_TEST(test_option_uid_uname) -DEFINE_TEST(test_option_uuencode) -DEFINE_TEST(test_option_U_upper) -DEFINE_TEST(test_option_xattrs) -DEFINE_TEST(test_option_X_upper) -DEFINE_TEST(test_option_xz) -DEFINE_TEST(test_option_z) -DEFINE_TEST(test_option_zstd) -DEFINE_TEST(test_patterns) -DEFINE_TEST(test_print_longpath) -DEFINE_TEST(test_stdio) -DEFINE_TEST(test_strip_components) -DEFINE_TEST(test_symlink_dir) -DEFINE_TEST(test_version) -DEFINE_TEST(test_windows) diff --git a/thirdparty/libarchive/tar/test/test.h b/thirdparty/libarchive/tar/test/test.h deleted file mode 100644 index 1e1bee807..000000000 --- a/thirdparty/libarchive/tar/test/test.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2003-2017 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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$ - */ - -/* Every test program should #include "test.h" as the first thing. */ - -#define KNOWNREF "test_patterns_2.tar.uu" -#define ENVBASE "BSDTAR" /* Prefix for environment variables. */ -#define PROGRAM "bsdtar" /* Name of program being tested. */ -#define PROGRAM_ALIAS "tar" /* Generic alias for program */ -#undef LIBRARY /* Not testing a library. */ -#undef EXTRA_DUMP /* How to dump extra data */ -#undef EXTRA_ERRNO /* How to dump errno */ -/* How to generate extra version info. */ -#define EXTRA_VERSION (systemf("%s --version", testprog) ? "" : "") - -#include "test_common.h" diff --git a/thirdparty/libarchive/tar/test/test_0.c b/thirdparty/libarchive/tar/test/test_0.c deleted file mode 100644 index b73c7a3f4..000000000 --- a/thirdparty/libarchive/tar/test/test_0.c +++ /dev/null @@ -1,75 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/test/test_0.c,v 1.2 2008/05/26 17:10:10 kientzle Exp $"); - -/* - * This first test does basic sanity checks on the environment. For - * most of these, we just exit on failure. - */ -#if !defined(_WIN32) || defined(__CYGWIN__) -#define DEV_NULL "/dev/null" -#else -#define DEV_NULL "NUL" -#endif - -DEFINE_TEST(test_0) -{ - struct stat st; - - failure("File %s does not exist?!", testprog); - if (!assertEqualInt(0, stat(testprogfile, &st))) { - fprintf(stderr, - "\nFile %s does not exist; aborting test.\n\n", - testprog); - exit(1); - } - - failure("%s is not executable?!", testprog); - if (!assert((st.st_mode & 0111) != 0)) { - fprintf(stderr, - "\nFile %s not executable; aborting test.\n\n", - testprog); - exit(1); - } - - /* - * Try to successfully run the program; this requires that - * we know some option that will succeed. - */ - if (0 == systemf("%s --version >" DEV_NULL, testprog)) { - /* This worked. */ - } else if (0 == systemf("%s -W version >" DEV_NULL, testprog)) { - /* This worked. */ - } else { - failure("Unable to successfully run any of the following:\n" - " * %s --version\n" - " * %s -W version\n", - testprog, testprog); - assert(0); - } - - /* TODO: Ensure that our reference files are available. */ -} diff --git a/thirdparty/libarchive/tar/test/test_basic.c b/thirdparty/libarchive/tar/test/test_basic.c deleted file mode 100644 index b1c49834a..000000000 --- a/thirdparty/libarchive/tar/test/test_basic.c +++ /dev/null @@ -1,135 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/test/test_basic.c,v 1.2 2008/05/26 17:10:10 kientzle Exp $"); - -static const char * -make_files(void) -{ - FILE *f; - - /* File with 10 bytes content. */ - f = fopen("file", "wb"); - assert(f != NULL); - assertEqualInt(10, fwrite("123456789", 1, 10, f)); - fclose(f); - - /* hardlink to above file. */ - assertMakeHardlink("linkfile", "file"); - assertIsHardlink("file", "linkfile"); - - /* Symlink to above file. */ - if (canSymlink()) - assertMakeSymlink("symlink", "file", 0); - - /* Directory. */ - assertMakeDir("dir", 0775); - - return canSymlink() - ? "file linkfile symlink dir" - : "file linkfile dir"; -} - -static void -verify_files(const char *target) -{ - assertChdir(target); - - /* Regular file with 2 links. */ - failure("%s", target); - assertIsReg("file", -1); - failure("%s", target); - assertFileSize("file", 10); - failure("%s", target); - assertFileContents("123456789", 10, "file"); - failure("%s", target); - assertFileNLinks("file", 2); - - /* Another name for the same file. */ - failure("%s", target); - assertIsReg("linkfile", -1); - failure("%s", target); - assertFileSize("linkfile", 10); - assertFileContents("123456789", 10, "linkfile"); - assertFileNLinks("linkfile", 2); - assertIsHardlink("file", "linkfile"); - - /* Symlink */ - if (canSymlink()) - assertIsSymlink("symlink", "file", 0); - - /* dir */ - failure("%s", target); - assertIsDir("dir", 0775); - assertChdir(".."); -} - -static void -run_tar(const char *target, const char *pack_options, - const char *unpack_options, const char *flist) -{ - int r; - - assertMakeDir(target, 0775); - - /* Use the tar program to create an archive. */ - r = systemf("%s cf - %s %s >%s/archive 2>%s/pack.err", testprog, pack_options, flist, target, target); - failure("Error invoking %s cf -%s", testprog, pack_options); - assertEqualInt(r, 0); - - assertChdir(target); - - /* Verify that nothing went to stderr. */ - assertEmptyFile("pack.err"); - - /* - * Use tar to unpack the archive into another directory. - */ - r = systemf("%s xf archive %s >unpack.out 2>unpack.err", - testprog, unpack_options); - failure("Error invoking %s xf archive %s", testprog, unpack_options); - assertEqualInt(r, 0); - - /* Verify that nothing went to stderr. */ - assertEmptyFile("unpack.err"); - assertChdir(".."); -} - -DEFINE_TEST(test_basic) -{ - const char *flist; - - assertUmask(0); - flist = make_files(); - /* Archive/dearchive with a variety of options. */ - run_tar("copy", "", "", flist); - verify_files("copy"); - - run_tar("copy_ustar", "--format=ustar", "", flist); - verify_files("copy_ustar"); - - /* tar doesn't handle cpio symlinks correctly */ - /* run_tar("copy_odc", "--format=odc", ""); */ -} diff --git a/thirdparty/libarchive/tar/test/test_copy.c b/thirdparty/libarchive/tar/test/test_copy.c deleted file mode 100644 index b8175c359..000000000 --- a/thirdparty/libarchive/tar/test/test_copy.c +++ /dev/null @@ -1,375 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/test/test_copy.c,v 1.3 2008/08/15 06:12:02 kientzle Exp $"); - -#if defined(__CYGWIN__) -# include -# include -#endif -#if defined(_WIN32) && !defined(__CYGWIN__) -# include -#endif - -/* - * Try to figure out how deep we can go in our tests. Assumes that - * the first call to this function has the longest starting cwd (which - * is currently "/original"). This is mostly to work around - * limits in our Win32 support. - * - * Background: On Posix systems, PATH_MAX is merely a limit on the - * length of the string passed into a system call. By repeatedly - * calling chdir(), you can work with arbitrarily long paths on such - * systems. In contrast, Win32 APIs apply PATH_MAX limits to the full - * absolute path, so the permissible length of a system call argument - * varies with the cwd. Some APIs actually enforce limits - * significantly less than PATH_MAX to ensure that you can create - * files within the current working directory. The Win32 limits also - * apply to Cygwin before 1.7. - * - * Someday, I want to convert the Win32 support to use newer - * wide-character paths with '\\?\' prefix, which has a 32k PATH_MAX - * instead of the rather anemic 260 character limit of the older - * system calls. Then we can drop this mess (unless we want to - * continue to special-case Cygwin 1.5 and earlier). - */ -static int -compute_loop_max(void) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - static int LOOP_MAX = 0; - char buf[MAX_PATH]; - size_t cwdlen; - - if (LOOP_MAX == 0) { - assert(_getcwd(buf, MAX_PATH) != NULL); - cwdlen = strlen(buf); - /* 12 characters = length of 8.3 filename */ - /* 4 characters = length of "/../" used in symlink tests */ - /* 1 character = length of extra "/" separator */ - LOOP_MAX = MAX_PATH - (int)cwdlen - 12 - 4 - 1; - } - return LOOP_MAX; -#elif defined(__CYGWIN__) && !defined(HAVE_CYGWIN_CONV_PATH) - static int LOOP_MAX = 0; - if (LOOP_MAX == 0) { - char wbuf[PATH_MAX]; - char pbuf[PATH_MAX]; - size_t wcwdlen; - size_t pcwdlen; - size_t cwdlen; - assert(getcwd(pbuf, PATH_MAX) != NULL); - pcwdlen = strlen(pbuf); - cygwin_conv_to_full_win32_path(pbuf, wbuf); - wcwdlen = strlen(wbuf); - cwdlen = ((wcwdlen > pcwdlen) ? wcwdlen : pcwdlen); - /* Cygwin helper needs an extra few characters. */ - LOOP_MAX = PATH_MAX - (int)cwdlen - 12 - 4 - 4; - } - return LOOP_MAX; -#else - /* cygwin-1.7 ends up here, along with "normal" unix */ - return 200; /* restore pre-r278 depth */ -#endif -} - -/* filenames[i] is a distinctive filename of length i. */ -/* To simplify interpreting failures, each filename ends with a - * decimal integer which is the length of the filename. E.g., A - * filename ending in "_92" is 92 characters long. To detect errors - * which drop or misplace characters, the filenames use a repeating - * "abcdefghijklmnopqrstuvwxyz..." pattern. */ -static char *filenames[201]; - -static void -compute_filenames(void) -{ - char buff[250]; - size_t i,j; - - filenames[0] = strdup(""); - filenames[1] = strdup("1"); - filenames[2] = strdup("a2"); - for (i = 3; i < sizeof(filenames)/sizeof(filenames[0]); ++i) { - /* Fill with "abcdefghij..." */ - for (j = 0; j < i; ++j) - buff[j] = 'a' + (j % 26); - buff[j--] = '\0'; - /* Work from the end to fill in the number portion. */ - buff[j--] = '0' + (i % 10); - if (i > 9) { - buff[j--] = '0' + ((i / 10) % 10); - if (i > 99) - buff[j--] = '0' + (char)(i / 100); - } - buff[j] = '_'; - /* Guard against obvious screwups in the above code. */ - assertEqualInt(strlen(buff), i); - filenames[i] = strdup(buff); - } -} - -static void -create_tree(void) -{ - char buff[260]; - char buff2[260]; - int i; - int LOOP_MAX; - - compute_filenames(); - - /* Log that we'll be omitting some checks. */ - if (!canSymlink()) { - skipping("Symlink checks"); - } - - assertMakeDir("original", 0775); - assertEqualInt(0, chdir("original")); - LOOP_MAX = compute_loop_max(); - - assertMakeDir("f", 0775); - assertMakeDir("l", 0775); - assertMakeDir("m", 0775); - assertMakeDir("s", 0775); - assertMakeDir("d", 0775); - - for (i = 1; i < LOOP_MAX; i++) { - failure("Internal sanity check failed: i = %d", i); - assert(filenames[i] != NULL); - - snprintf(buff, sizeof(buff), "f/%s", filenames[i]); - assertMakeFile(buff, 0777, buff); - - /* Create a link named "l/abcdef..." to the above. */ - snprintf(buff2, sizeof(buff2), "l/%s", filenames[i]); - assertMakeHardlink(buff2, buff); - - /* Create a link named "m/abcdef..." to the above. */ - snprintf(buff2, sizeof(buff2), "m/%s", filenames[i]); - assertMakeHardlink(buff2, buff); - - if (canSymlink()) { - /* Create a symlink named "s/abcdef..." to the above. */ - snprintf(buff, sizeof(buff), "s/%s", filenames[i]); - snprintf(buff2, sizeof(buff2), "../f/%s", filenames[i]); - failure("buff=\"%s\" buff2=\"%s\"", buff, buff2); - assertMakeSymlink(buff, buff2, 0); - } - /* Create a dir named "d/abcdef...". */ - buff[0] = 'd'; - failure("buff=\"%s\"", buff); - assertMakeDir(buff, 0775); - } - - assertEqualInt(0, chdir("..")); -} - -#define LIMIT_NONE 200 -#define LIMIT_USTAR 100 - -static void -verify_tree(size_t limit) -{ - char name1[260]; - char name2[260]; - size_t i, LOOP_MAX; - - LOOP_MAX = compute_loop_max(); - - /* Generate the names we know should be there and verify them. */ - for (i = 1; i < LOOP_MAX; i++) { - /* Verify a file named "f/abcdef..." */ - snprintf(name1, sizeof(name1), "f/%s", filenames[i]); - if (i <= limit) { - assertFileExists(name1); - assertFileContents(name1, (int)strlen(name1), name1); - } - - snprintf(name2, sizeof(name2), "l/%s", filenames[i]); - if (i + 2 <= limit) { - /* Verify hardlink "l/abcdef..." */ - assertIsHardlink(name1, name2); - /* Verify hardlink "m/abcdef..." */ - name2[0] = 'm'; - assertIsHardlink(name1, name2); - } - - if (canSymlink()) { - /* Verify symlink "s/abcdef..." */ - snprintf(name1, sizeof(name1), "s/%s", filenames[i]); - snprintf(name2, sizeof(name2), "../f/%s", filenames[i]); - if (strlen(name2) <= limit) - assertIsSymlink(name1, name2, 0); - } - - /* Verify dir "d/abcdef...". */ - snprintf(name1, sizeof(name1), "d/%s", filenames[i]); - if (i + 1 <= limit) { /* +1 for trailing slash */ - if (assertIsDir(name1, -1)) { - /* TODO: opendir/readdir this - * directory and make sure - * it's empty. - */ - } - } - } - -#if !defined(_WIN32) || defined(__CYGWIN__) - { - const char *dp; - /* Now make sure nothing is there that shouldn't be. */ - for (dp = "dflms"; *dp != '\0'; ++dp) { - DIR *d; - struct dirent *de; - char dir[2]; - dir[0] = *dp; dir[1] = '\0'; - d = opendir(dir); - failure("Unable to open dir '%s'", dir); - if (!assert(d != NULL)) - continue; - while ((de = readdir(d)) != NULL) { - char *p = de->d_name; - if (p[0] == '.') - continue; - switch(dp[0]) { - case 'l': case 'm': case 'd': - failure("strlen(p)=%zu", strlen(p)); - assert(strlen(p) < limit); - assertEqualString(p, - filenames[strlen(p)]); - break; - case 'f': case 's': - failure("strlen(p)=%zu", strlen(p)); - assert(strlen(p) < limit + 1); - assertEqualString(p, - filenames[strlen(p)]); - break; - default: - failure("File %s shouldn't be here", p); - assert(0); - } - } - closedir(d); - } - } -#endif -} - -static void -copy_basic(void) -{ - int r; - - /* NOTE: for proper operation on cygwin-1.5 and windows, the - * length of the name of the directory below, "plain", must be - * less than or equal to the length of the name of the original - * directory, "original" This restriction derives from the - * extremely limited pathname lengths on those platforms. - */ - assertMakeDir("plain", 0775); - assertEqualInt(0, chdir("plain")); - - /* - * Use the tar program to create an archive. - */ - r = systemf("%s cf archive -C ../original f d l m s >pack.out 2>pack.err", - testprog); - failure("Error invoking \"%s cf\"", testprog); - assertEqualInt(r, 0); - - /* Verify that nothing went to stdout or stderr. */ - assertEmptyFile("pack.err"); - assertEmptyFile("pack.out"); - - /* - * Use tar to unpack the archive into another directory. - */ - r = systemf("%s xf archive >unpack.out 2>unpack.err", testprog); - failure("Error invoking %s xf archive", testprog); - assertEqualInt(r, 0); - - /* Verify that nothing went to stdout or stderr. */ - assertEmptyFile("unpack.err"); - assertEmptyFile("unpack.out"); - - verify_tree(LIMIT_NONE); - assertEqualInt(0, chdir("..")); -} - -static void -copy_ustar(void) -{ - const char *target = "ustar"; - int r; - - /* NOTE: for proper operation on cygwin-1.5 and windows, the - * length of the name of the directory below, "ustar", must be - * less than or equal to the length of the name of the original - * directory, "original" This restriction derives from the - * extremely limited pathname lengths on those platforms. - */ - assertMakeDir(target, 0775); - assertEqualInt(0, chdir(target)); - - /* - * Use the tar program to create an archive. - */ - r = systemf("%s cf archive --format=ustar -C ../original f d l m s >pack.out 2>pack.err", - testprog); - failure("Error invoking \"%s cf archive --format=ustar\"", testprog); - assertEqualInt(r, 0); - - /* Verify that nothing went to stdout. */ - assertEmptyFile("pack.out"); - /* Stderr is non-empty, since there are a bunch of files - * with filenames too long to archive. */ - - /* - * Use tar to unpack the archive into another directory. - */ - r = systemf("%s xf archive >unpack.out 2>unpack.err", testprog); - failure("Error invoking %s xf archive", testprog); - assertEqualInt(r, 0); - - /* Verify that nothing went to stdout or stderr. */ - assertEmptyFile("unpack.err"); - assertEmptyFile("unpack.out"); - - verify_tree(LIMIT_USTAR); - assertEqualInt(0, chdir("../..")); -} - -DEFINE_TEST(test_copy) -{ - assertUmask(0); - create_tree(); /* Create sample files in "original" dir. */ - - /* Test simple "tar -c | tar -x" pipeline copy. */ - copy_basic(); - - /* Same, but constrain to ustar format. */ - copy_ustar(); -} diff --git a/thirdparty/libarchive/tar/test/test_empty_mtree.c b/thirdparty/libarchive/tar/test/test_empty_mtree.c deleted file mode 100644 index 6f8a5e91a..000000000 --- a/thirdparty/libarchive/tar/test/test_empty_mtree.c +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * Copyright (c) 2003-2009 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* - * Regression test: We used to get a bogus error message when we - * asked tar to copy entries out of an empty archive. See - * Issue 51 on libarchive.googlecode.com for details. - */ -DEFINE_TEST(test_empty_mtree) -{ - int r; - - assertMakeFile("test1.mtree", 0777, "#mtree\n"); - - r = systemf("%s cf test1.tar @test1.mtree >test1.out 2>test1.err", - testprog); - failure("Error invoking %s cf", testprog); - assertEqualInt(r, 0); - assertEmptyFile("test1.out"); - assertEmptyFile("test1.err"); -} diff --git a/thirdparty/libarchive/tar/test/test_extract.tar.Z.uu b/thirdparty/libarchive/tar/test/test_extract.tar.Z.uu deleted file mode 100644 index 92713a544..000000000 --- a/thirdparty/libarchive/tar/test/test_extract.tar.Z.uu +++ /dev/null @@ -1,9 +0,0 @@ -begin 664 test_extract.tar.Z -M'YV09M*P*1,#@,&#"!,J7,BPH<.'$",BA$'1A@T:(`!0C'&C!HR,&SM^U$BQ -M9$D9,T#$D`%CAHP;-&"@Q`@C1HP9-FH```%#HL^?0(,*!5!G#ITP//JW-F?'18\FI0@5;FFOCJV:Q/JYM>NM8,62I6,6K5J!@-V^WLV[M^_?P(,+'TZ\ -0N/'CR),K7\Z\N?/GT*,K!P`` -` -end diff --git a/thirdparty/libarchive/tar/test/test_extract.tar.bz2.uu b/thirdparty/libarchive/tar/test/test_extract.tar.bz2.uu deleted file mode 100644 index 9a37413ad..000000000 --- a/thirdparty/libarchive/tar/test/test_extract.tar.bz2.uu +++ /dev/null @@ -1,7 +0,0 @@ -begin 664 test_extract.tar.bz2 -M0EIH.3%!629368N]6:```'U[D=(0`"!``7^```AK)9X`!```$0`(,`"X#&$Q -M,F`F``,83$R8"8``*J:")M0TCQ30-/%-3*]V3EE!&(DSM8?BJ4J)=TSJ4/"B -M,?#R_6>?9K=+H02NT0V040P3.SHF:(573*)M5&;!-%6RO=6F5":N"+,"YZ;L -AV+<]%F[GWYCR<%FRKAPR=7VY+'+1)_B[DBG"A(1=ZLT` -` -end diff --git a/thirdparty/libarchive/tar/test/test_extract.tar.grz.uu b/thirdparty/libarchive/tar/test/test_extract.tar.grz.uu deleted file mode 100644 index 44651e116..000000000 --- a/thirdparty/libarchive/tar/test/test_extract.tar.grz.uu +++ /dev/null @@ -1,7 +0,0 @@ -begin 644 test_extract.tar.grz -M1U)::7!)20`"!#HI``P``*P,``#U````SP```'<````[-=0OM"R^UP#^C?Z< -MFGU0]I:>SW7]H01)1\WY:59("M_=V4[N[R*'`H&:'E=O@5B(?T,0?@)%-:_D -M;EUP)!JVN)@V_:ABYS3+[[6/R(NU,-::]'X&;,]:,HR[*3#R!@:W)IGC`,&G -8L+IZ7]FP=8U_R?CZ2XPO)"H-ME3@P]$` -` -end diff --git a/thirdparty/libarchive/tar/test/test_extract.tar.gz.uu b/thirdparty/libarchive/tar/test/test_extract.tar.gz.uu deleted file mode 100644 index 19f8bc047..000000000 --- a/thirdparty/libarchive/tar/test/test_extract.tar.gz.uu +++ /dev/null @@ -1,7 +0,0 @@ -begin 664 test_extract.tar.gz -M'XL(""S!:U```W1E26I>27%"OEI"FF@M*#'-=!.&@5T!*`X-Z*Q'23E?Q-3 -AP?_D@0*H:&)P-5? -MZX%NI60,IT@(N<,S%?7H2TLP5)FN#[-;&&[/2A#BNH4(7#C+*&ZP<>K&B)AG -M:Z(;Y=]3<5Q$)_[[5M\7=]N7A$%\ZF:H2/,Q%BK$JA4L!,K(-RZU2X[/`%69 -.9U@/B[!N",NH4]8F,M(` -` -end diff --git a/thirdparty/libarchive/tar/test/test_extract.tar.lz.uu b/thirdparty/libarchive/tar/test/test_extract.tar.lz.uu deleted file mode 100644 index cb380e3a0..000000000 --- a/thirdparty/libarchive/tar/test/test_extract.tar.lz.uu +++ /dev/null @@ -1,7 +0,0 @@ -begin 664 test_extract.tar.lz -M3%I)4`$,`#,:2=:X2EY2J/TZ6]L7]]N4K?J&A)E2#"A'E"T1EP+MU&;(P1FY -MV\,8BTS,N0/O2=#67;G5)%I'C,D.U?*T!NX("FYPYI9I40F>X))?^8\?E?#> -MOP";"GD#8(9*K;XP318HXZ\?_^SZ -6K-(!CH7```P```````"=```````````` -` -end diff --git a/thirdparty/libarchive/tar/test/test_extract.tar.lz4.uu b/thirdparty/libarchive/tar/test/test_extract.tar.lz4.uu deleted file mode 100644 index a10ac0275..000000000 --- a/thirdparty/libarchive/tar/test/test_extract.tar.lz4.uu +++ /dev/null @@ -1,8 +0,0 @@ -begin 644 test_extract.tar.lz4 -M!")-&&1PN:L```!O9FEL93$``0!+Z#`P,#8V-"``,#`Q-S4P"``#`@#_"3(S -M(#$R,#,R-S0P,C,T(#`Q,3,V-0`@,)<`2P("`+)U4JC].EO;%_?;E*WZAH294@PH1Y0M$9<" -M[=1FR,$9N=O#&(M,Q24U'H+5Z^7^*J;G!)OU]O'2D;AZ&0^IO?>-YA]$:-X_ -MD^O)YVM(4`^-MT$X`.D(6)*$]3HNB9KJ_H=1$QKYZ:`:,H_L"H[#"?#Z5A<] -%O_OZW=D` -` -end diff --git a/thirdparty/libarchive/tar/test/test_extract.tar.lzo.uu b/thirdparty/libarchive/tar/test/test_extract.tar.lzo.uu deleted file mode 100644 index 29dd8d852..000000000 --- a/thirdparty/libarchive/tar/test/test_extract.tar.lzo.uu +++ /dev/null @@ -1,9 +0,0 @@ -begin 664 test_extract.tar.lzo -MB4Q:3P`-"AH*$#`@8`E``04#```!``"!M%!R@T``````$'1E?S@M7KY?XJIN<$F_7V -M\=*1N'H9#ZF]]XWF'T1HWC^3Z\GG:TA0#XVW03@`Z0A8DH3U.BZ)FNK^AU$3 -M&OGIH!HRC^P*CL,)\/,MGP``````2IVA+$<(^YX``94!@!@``&X^\DRQQ&?[ -(`@`````$65H` -` -end diff --git a/thirdparty/libarchive/tar/test/test_extract.tar.zst.uu b/thirdparty/libarchive/tar/test/test_extract.tar.zst.uu deleted file mode 100644 index 3df0caf54..000000000 --- a/thirdparty/libarchive/tar/test/test_extract.tar.zst.uu +++ /dev/null @@ -1,6 +0,0 @@ -begin 644 test_extract.tar.zst -M*+4O_010S0,`Y+>!0*5E/PM"$7^K^1VI3SS-AX&_W0KQWY!-Z1(`_4$%[$"]test.out 2>test.err", - testprog, reffile)); - - assertFileExists("file1"); - assertTextFileContents("contents of file1.\n", "file1"); - assertFileExists("file2"); - assertTextFileContents("contents of file2.\n", "file2"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); -} diff --git a/thirdparty/libarchive/tar/test/test_extract_tar_bz2.c b/thirdparty/libarchive/tar/test/test_extract_tar_bz2.c deleted file mode 100644 index b734dd28b..000000000 --- a/thirdparty/libarchive/tar/test/test_extract_tar_bz2.c +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_extract_tar_bz2) -{ - const char *reffile = "test_extract.tar.bz2"; - int f; - - extract_reference_file(reffile); - f = systemf("%s -tf %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canBzip2()) { - assertEqualInt(0, systemf("%s -xf %s >test.out 2>test.err", - testprog, reffile)); - - assertFileExists("file1"); - assertTextFileContents("contents of file1.\n", "file1"); - assertFileExists("file2"); - assertTextFileContents("contents of file2.\n", "file2"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - } else { - skipping("It seems bzip2 is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/tar/test/test_extract_tar_grz.c b/thirdparty/libarchive/tar/test/test_extract_tar_grz.c deleted file mode 100644 index 9c0615e98..000000000 --- a/thirdparty/libarchive/tar/test/test_extract_tar_grz.c +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_extract_tar_grz) -{ - const char *reffile = "test_extract.tar.grz"; - int f; - - extract_reference_file(reffile); - f = systemf("%s -tf %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canGrzip()) { - assertEqualInt(0, systemf("%s -xf %s >test.out 2>test.err", - testprog, reffile)); - - assertFileExists("file1"); - assertTextFileContents("contents of file1.\n", "file1"); - assertFileExists("file2"); - assertTextFileContents("contents of file2.\n", "file2"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - } else { - skipping("It seems grzip is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/tar/test/test_extract_tar_gz.c b/thirdparty/libarchive/tar/test/test_extract_tar_gz.c deleted file mode 100644 index 2fdb4ba7c..000000000 --- a/thirdparty/libarchive/tar/test/test_extract_tar_gz.c +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_extract_tar_gz) -{ - const char *reffile = "test_extract.tar.gz"; - int f; - - extract_reference_file(reffile); - f = systemf("%s -tf %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canGzip()) { - assertEqualInt(0, systemf("%s -xf %s >test.out 2>test.err", - testprog, reffile)); - - assertFileExists("file1"); - assertTextFileContents("contents of file1.\n", "file1"); - assertFileExists("file2"); - assertTextFileContents("contents of file2.\n", "file2"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - } else { - skipping("It seems gzip is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/tar/test/test_extract_tar_lrz.c b/thirdparty/libarchive/tar/test/test_extract_tar_lrz.c deleted file mode 100644 index 56a0fb882..000000000 --- a/thirdparty/libarchive/tar/test/test_extract_tar_lrz.c +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_extract_tar_lrz) -{ - const char *reffile = "test_extract.tar.lrz"; - int f; - - extract_reference_file(reffile); - f = systemf("%s -tf %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canLrzip()) { - assertEqualInt(0, systemf("%s -xf %s >test.out 2>test.err", - testprog, reffile)); - - assertFileExists("file1"); - assertTextFileContents("contents of file1.\n", "file1"); - assertFileExists("file2"); - assertTextFileContents("contents of file2.\n", "file2"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - } else { - skipping("It seems lrzip is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/tar/test/test_extract_tar_lz.c b/thirdparty/libarchive/tar/test/test_extract_tar_lz.c deleted file mode 100644 index 5ec7e9a48..000000000 --- a/thirdparty/libarchive/tar/test/test_extract_tar_lz.c +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_extract_tar_lz) -{ - const char *reffile = "test_extract.tar.lz"; - int f; - - extract_reference_file(reffile); - f = systemf("%s -tf %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canLzip()) { - assertEqualInt(0, systemf("%s -xf %s >test.out 2>test.err", - testprog, reffile)); - - assertFileExists("file1"); - assertTextFileContents("contents of file1.\n", "file1"); - assertFileExists("file2"); - assertTextFileContents("contents of file2.\n", "file2"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - } else { - skipping("It seems lzip is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/tar/test/test_extract_tar_lz4.c b/thirdparty/libarchive/tar/test/test_extract_tar_lz4.c deleted file mode 100644 index 150d57d71..000000000 --- a/thirdparty/libarchive/tar/test/test_extract_tar_lz4.c +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2012,2014 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_extract_tar_lz4) -{ - const char *reffile = "test_extract.tar.lz4"; - int f; - - extract_reference_file(reffile); - f = systemf("%s -tf %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canLz4()) { - assertEqualInt(0, systemf("%s -xf %s >test.out 2>test.err", - testprog, reffile)); - - assertFileExists("file1"); - assertTextFileContents("contents of file1.\n", "file1"); - assertFileExists("file2"); - assertTextFileContents("contents of file2.\n", "file2"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - } else { - skipping("It seems lz4 is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/tar/test/test_extract_tar_lzma.c b/thirdparty/libarchive/tar/test/test_extract_tar_lzma.c deleted file mode 100644 index 2fa2af049..000000000 --- a/thirdparty/libarchive/tar/test/test_extract_tar_lzma.c +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_extract_tar_lzma) -{ - const char *reffile = "test_extract.tar.lzma"; - int f; - - extract_reference_file(reffile); - f = systemf("%s -tf %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canLzma()) { - assertEqualInt(0, systemf("%s -xf %s >test.out 2>test.err", - testprog, reffile)); - - assertFileExists("file1"); - assertTextFileContents("contents of file1.\n", "file1"); - assertFileExists("file2"); - assertTextFileContents("contents of file2.\n", "file2"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - } else { - skipping("It seems lzma is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/tar/test/test_extract_tar_lzo.c b/thirdparty/libarchive/tar/test/test_extract_tar_lzo.c deleted file mode 100644 index 17b4295ed..000000000 --- a/thirdparty/libarchive/tar/test/test_extract_tar_lzo.c +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_extract_tar_lzo) -{ - const char *reffile = "test_extract.tar.lzo"; - int f; - - extract_reference_file(reffile); - f = systemf("%s -tf %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canLzop()) { - assertEqualInt(0, systemf("%s -xf %s >test.out 2>test.err", - testprog, reffile)); - - assertFileExists("file1"); - assertTextFileContents("contents of file1.\n", "file1"); - assertFileExists("file2"); - assertTextFileContents("contents of file2.\n", "file2"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - } else { - skipping("It seems lzop is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/tar/test/test_extract_tar_xz.c b/thirdparty/libarchive/tar/test/test_extract_tar_xz.c deleted file mode 100644 index 860bab75a..000000000 --- a/thirdparty/libarchive/tar/test/test_extract_tar_xz.c +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_extract_tar_xz) -{ - const char *reffile = "test_extract.tar.xz"; - int f; - - extract_reference_file(reffile); - f = systemf("%s -tf %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canXz()) { - assertEqualInt(0, systemf("%s -xf %s >test.out 2>test.err", - testprog, reffile)); - - assertFileExists("file1"); - assertTextFileContents("contents of file1.\n", "file1"); - assertFileExists("file2"); - assertTextFileContents("contents of file2.\n", "file2"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - } else { - skipping("It seems xz is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/tar/test/test_extract_tar_zstd.c b/thirdparty/libarchive/tar/test/test_extract_tar_zstd.c deleted file mode 100644 index d67170ce3..000000000 --- a/thirdparty/libarchive/tar/test/test_extract_tar_zstd.c +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2017 Sean Purcell - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_extract_tar_zstd) -{ - const char *reffile = "test_extract.tar.zst"; - int f; - - extract_reference_file(reffile); - f = systemf("%s -tf %s >test.out 2>test.err", testprog, reffile); - if (f == 0 || canZstd()) { - assertEqualInt(0, systemf("%s -xf %s >test.out 2>test.err", - testprog, reffile)); - - assertFileExists("file1"); - assertTextFileContents("contents of file1.\n", "file1"); - assertFileExists("file2"); - assertTextFileContents("contents of file2.\n", "file2"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - } else { - skipping("It seems zstd is not supported on this platform"); - } -} diff --git a/thirdparty/libarchive/tar/test/test_format_newc.c b/thirdparty/libarchive/tar/test/test_format_newc.c deleted file mode 100644 index 808fa4b49..000000000 --- a/thirdparty/libarchive/tar/test/test_format_newc.c +++ /dev/null @@ -1,64 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_format_newc) -{ - - assertMakeFile("file1", 0644, "file1"); - assertMakeFile("file2", 0644, "file2"); - assertMakeHardlink("file3", "file1"); - - /* Test 1: Create an archive file with a newc format. */ - assertEqualInt(0, - systemf("%s -cf test1.cpio --format newc file1 file2 file3", - testprog)); - assertMakeDir("test1", 0755); - assertChdir("test1"); - assertEqualInt(0, - systemf("%s -xf ../test1.cpio >test.out 2>test.err", testprog)); - assertFileContents("file1", 5, "file1"); - assertFileContents("file2", 5, "file2"); - assertFileContents("file1", 5, "file3"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 2: Exclude one of hardlinked files. */ - assertEqualInt(0, - systemf("%s -cf test2.cpio --format newc file1 file2", - testprog)); - assertMakeDir("test2", 0755); - assertChdir("test2"); - assertEqualInt(0, - systemf("%s -xf ../test2.cpio >test.out 2>test.err", testprog)); - assertFileContents("file1", 5, "file1"); - assertFileContents("file2", 5, "file2"); - assertFileNotExists("file3"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); -} diff --git a/thirdparty/libarchive/tar/test/test_help.c b/thirdparty/libarchive/tar/test/test_help.c deleted file mode 100644 index 3bb517d00..000000000 --- a/thirdparty/libarchive/tar/test/test_help.c +++ /dev/null @@ -1,84 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/test/test_help.c,v 1.2 2008/05/26 17:10:10 kientzle Exp $"); - -/* - * Test that "--help", "-h", and "-W help" options all work and - * generate reasonable output. - */ - -static int -in_first_line(const char *p, const char *substring) -{ - size_t l = strlen(substring); - - while (*p != '\0' && *p != '\n') { - if (memcmp(p, substring, l) == 0) - return (1); - ++p; - } - return (0); -} - -DEFINE_TEST(test_help) -{ - int r; - char *p; - size_t plen; - - /* Exercise --help option. */ - r = systemf("%s --help >help.stdout 2>help.stderr", testprog); - assertEqualInt(r, 0); - failure("--help should generate nothing to stderr."); - assertEmptyFile("help.stderr"); - /* Help message should start with name of program. */ - p = slurpfile(&plen, "help.stdout"); - failure("Help output should be long enough."); - assert(plen >= 6); - failure("First line of help output should contain 'bsdtar': %s", p); - assert(in_first_line(p, "bsdtar")); - /* - * TODO: Extend this check to further verify that --help output - * looks approximately right. - */ - free(p); - - /* -h option should generate the same output. */ - r = systemf("%s -h >h.stdout 2>h.stderr", testprog); - assertEqualInt(r, 0); - failure("-h should generate nothing to stderr."); - assertEmptyFile("h.stderr"); - failure("stdout should be same for -h and --help"); - assertEqualFile("h.stdout", "help.stdout"); - - /* -W help should be another synonym. */ - r = systemf("%s -W help >Whelp.stdout 2>Whelp.stderr", testprog); - assertEqualInt(r, 0); - failure("-W help should generate nothing to stderr."); - assertEmptyFile("Whelp.stderr"); - failure("stdout should be same for -W help and --help"); - assertEqualFile("Whelp.stdout", "help.stdout"); -} diff --git a/thirdparty/libarchive/tar/test/test_leading_slash.c b/thirdparty/libarchive/tar/test/test_leading_slash.c deleted file mode 100644 index 572c45e3c..000000000 --- a/thirdparty/libarchive/tar/test/test_leading_slash.c +++ /dev/null @@ -1,50 +0,0 @@ -/*- - * Copyright (c) 2003-2014 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_leading_slash) -{ - const char *reffile = "test_leading_slash.tar"; - char *errfile; - size_t errfile_size; - const char *expected_errmsg = "Removing leading '/' from member names"; - - extract_reference_file(reffile); - assertEqualInt(0, systemf("%s -xf %s >test.out 2>test.err", testprog, reffile)); - assertFileExists("foo/file"); - assertTextFileContents("foo\x0a", "foo/file"); - assertTextFileContents("foo\x0a", "foo/hardlink"); - assertIsHardlink("foo/file", "foo/hardlink"); - assertEmptyFile("test.out"); - - /* Verify the error output contains the expected text somewhere in it */ - if (assertFileExists("test.err")) { - errfile = slurpfile(&errfile_size, "test.err"); - assert(strstr(errfile, expected_errmsg) != NULL); - free(errfile); - } -} - diff --git a/thirdparty/libarchive/tar/test/test_leading_slash.tar.uu b/thirdparty/libarchive/tar/test/test_leading_slash.tar.uu deleted file mode 100644 index eeb27c3bb..000000000 --- a/thirdparty/libarchive/tar/test/test_leading_slash.tar.uu +++ /dev/null @@ -1,60 +0,0 @@ -begin 644 test_leading_slash.tar -M+V9O;R]F:6QE```````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````#`P,#8T-"``,#`P,#`P(``P,#`P,#`@`#`P,#`P,#`P,#`T -M(#$R-#$V,S4U-34V(#`Q,C8V-P`@,``````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````!Ustderr1", testprog)); - assertEmptyFile("stderr1"); - assert(0 != systemf("%s -cf archive.tar file1 file2 file3 2>stderr2", testprog)); - assertFileContainsNoInvalidStrings("stderr2", invalid_stderr); - assert(0 != systemf("%s -cf archive.tar 2>stderr3", testprog)); - assertFileContainsNoInvalidStrings("stderr3", invalid_stderr); - assert(0 != systemf("%s -cf archive.tar file3 file4 2>stderr4", testprog)); - assertFileContainsNoInvalidStrings("stderr4", invalid_stderr); -} diff --git a/thirdparty/libarchive/tar/test/test_option_C_mtree.c b/thirdparty/libarchive/tar/test/test_option_C_mtree.c deleted file mode 100644 index ccadc3899..000000000 --- a/thirdparty/libarchive/tar/test/test_option_C_mtree.c +++ /dev/null @@ -1,89 +0,0 @@ -/*- - * Copyright (c) 2018 The FreeBSD Foundation - * All rights reserved. - * - * This software was developed by Arshan Khanifar - * under sponsorship from the FreeBSD Foundation. - * - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_C_mtree) -{ - char *p0; - size_t s; - int r; - p0 = NULL; - char *content = "./foo type=file uname=root gname=root mode=0755\n"; - char *filename = "output.tar"; -#if defined(_WIN32) && !defined(CYGWIN) - char *p; -#endif - - /* an absolute path to mtree file */ - char *mtree_file = "/METALOG.mtree"; - char *absolute_path = malloc(strlen(testworkdir) + strlen(mtree_file) + 1); - strcpy(absolute_path, testworkdir); - strcat(absolute_path, mtree_file ); - - /* Create an archive using an mtree file. */ - assertMakeFile(absolute_path, 0777, content); - assertMakeDir("bar", 0775); - assertMakeFile("bar/foo", 0777, "abc"); - -#if defined(_WIN32) && !defined(CYGWIN) - p = absolute_path; - while(*p != '\0') { - if (*p == '/') - *p = '\\'; - p++; - } - - r = systemf("%s -cf %s -C bar @%s >step1.out 2>step1.err", testprog, filename, absolute_path); - failure("Error invoking %s -cf %s -C bar @%s", testprog, filename, absolute_path); -#else - r = systemf("%s -cf %s -C bar \"@%s\" >step1.out 2>step1.err", testprog, filename, absolute_path); - failure("Error invoking %s -cf %s -C bar \"@%s\"", testprog, filename, absolute_path); -#endif - - assertEqualInt(r, 0); - assertEmptyFile("step1.out"); - assertEmptyFile("step1.err"); - - /* Do validation of the constructed archive. */ - - p0 = slurpfile(&s, "output.tar"); - if (!assert(p0 != NULL)) - goto done; - if (!assert(s >= 2048)) - goto done; - assertEqualMem(p0 + 0, "./foo", 5); - assertEqualMem(p0 + 512, "abc", 3); - assertEqualMem(p0 + 1024, "\0\0\0\0\0\0\0\0", 8); - assertEqualMem(p0 + 1536, "\0\0\0\0\0\0\0\0", 8); -done: - free(p0); - free(absolute_path); -} - - diff --git a/thirdparty/libarchive/tar/test/test_option_C_upper.c b/thirdparty/libarchive/tar/test/test_option_C_upper.c deleted file mode 100644 index 538890f58..000000000 --- a/thirdparty/libarchive/tar/test/test_option_C_upper.c +++ /dev/null @@ -1,149 +0,0 @@ -/*- - * Copyright (c) 2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_C_upper) -{ - int r; - - assertMakeDir("d1", 0755); - assertMakeDir("d2", 0755); - assertMakeFile("d1/file1", 0644, "d1/file1"); - assertMakeFile("d1/file2", 0644, "d1/file2"); - assertMakeFile("d2/file1", 0644, "d2/file1"); - assertMakeFile("d2/file2", 0644, "d2/file2"); - - /* - * Test 1: Basic use of -C - */ - assertMakeDir("test1", 0755); - assertChdir("test1"); - assertEqualInt(0, systemf("%s -cf archive.tar -C ../d1 file1 -C ../d2 file2", testprog)); - assertEqualInt(0, - systemf("%s -xf archive.tar >test.out 2>test.err", testprog)); - assertFileContents("d1/file1", 8, "file1"); - assertFileContents("d2/file2", 8, "file2"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - - /* - * Test 2: Multiple -C - */ - assertMakeDir("test2", 0755); - assertChdir("test2"); - assertEqualInt(0, systemf("%s -cf archive.tar -C .. -C d1 file1 -C .. -C d2 file2", testprog)); - assertEqualInt(0, - systemf("%s -xf archive.tar >test.out 2>test.err", testprog)); - assertFileContents("d1/file1", 8, "file1"); - assertFileContents("d2/file2", 8, "file2"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* - * Test 3: -C fail - */ - assertMakeDir("test3", 0755); - assertChdir("test3"); - r = systemf("%s -cf archive.tar -C ../XXX file1 -C ../d2 file2 2>write.err", testprog); - assert(r != 0); - assertNonEmptyFile("write.err"); - assertEqualInt(0, - systemf("%s -xf archive.tar >test.out 2>test.err", testprog)); - assertFileNotExists("file1"); - assertFileNotExists("file2"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* - * Test 4: Absolute -C - */ - assertMakeDir("test4", 0755); - assertChdir("test4"); - assertEqualInt(0, - systemf("%s -cf archive.tar -C %s/d1 file1", - testprog, testworkdir)); - assertEqualInt(0, - systemf("%s -xf archive.tar >test.out 2>test.err", testprog)); - assertFileContents("d1/file1", 8, "file1"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* - * Test 5: Unnecessary -C ignored even if directory named doesn't exist - */ - assertMakeDir("test5", 0755); - assertChdir("test5"); - assertEqualInt(0, - systemf("%s -cf archive.tar -C XXX -C %s/d1 file1", - testprog, testworkdir)); - assertEqualInt(0, - systemf("%s -xf archive.tar >test.out 2>test.err", testprog)); - assertFileContents("d1/file1", 8, "file1"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* - * Test 6: Necessary -C not ignored if directory doesn't exist - */ - assertMakeDir("test6", 0755); - assertChdir("test6"); - r = systemf("%s -cf archive.tar -C XXX -C ../d1 file1 2>write.err", - testprog); - assert(r != 0); - assertNonEmptyFile("write.err"); - assertEqualInt(0, - systemf("%s -xf archive.tar >test.out 2>test.err", testprog)); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* - * Test 7: -C used without specifying directory - */ - assertMakeDir("test7", 0755); - assertChdir("test7"); - r = systemf("%s -cf archive.tar ../d1/file1 -C 2>write.err", testprog); - assert(r != 0); - assertNonEmptyFile("write.err"); - assertChdir(".."); - - /* - * Test 8: -C used with meaningless option '' - */ - assertMakeDir("test8", 0755); - assertChdir("test8"); - r = systemf("%s -cf archive.tar ../d1/file1 -C \"\" 2>write.err", - testprog); - assert(r != 0); - assertNonEmptyFile("write.err"); - assertChdir(".."); -} diff --git a/thirdparty/libarchive/tar/test/test_option_H_upper.c b/thirdparty/libarchive/tar/test/test_option_H_upper.c deleted file mode 100644 index 2c2ad33ce..000000000 --- a/thirdparty/libarchive/tar/test/test_option_H_upper.c +++ /dev/null @@ -1,92 +0,0 @@ -/*- - * Copyright (c) 2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_H_upper) -{ - - if (!canSymlink()) { - skipping("Can't test symlinks on this filesystem"); - return; - } - - /* - * Create a sample archive. - */ - assertMakeDir("in", 0755); - assertChdir("in"); - assertMakeDir("d1", 0755); - assertMakeSymlink("ld1", "d1", 1); - assertMakeFile("d1/file1", 0644, "d1/file1"); - assertMakeFile("d1/file2", 0644, "d1/file2"); - assertMakeSymlink("d1/link1", "file1", 0); - assertMakeSymlink("d1/linkX", "fileX", 0); - assertMakeSymlink("link2", "d1/file2", 0); - assertMakeSymlink("linkY", "d1/fileY", 0); - assertChdir(".."); - - /* Test 1: Without -H */ - assertMakeDir("test1", 0755); - assertEqualInt(0, - systemf("%s -cf test1/archive.tar -C in . >test1/c.out 2>test1/c.err", testprog)); - assertChdir("test1"); - assertEqualInt(0, - systemf("%s -xf archive.tar >c.out 2>c.err", testprog)); - assertIsSymlink("ld1", "d1", 1); - assertIsSymlink("d1/link1", "file1", 0); - assertIsSymlink("d1/linkX", "fileX", 0); - assertIsSymlink("link2", "d1/file2", 0); - assertIsSymlink("linkY", "d1/fileY", 0); - assertChdir(".."); - - /* Test 2: With -H, no symlink on command line. */ - assertMakeDir("test2", 0755); - assertEqualInt(0, - systemf("%s -cf test2/archive.tar -H -C in . >test2/c.out 2>test2/c.err", testprog)); - assertChdir("test2"); - assertEqualInt(0, - systemf("%s -xf archive.tar >c.out 2>c.err", testprog)); - assertIsSymlink("ld1", "d1", 1); - assertIsSymlink("d1/link1", "file1", 0); - assertIsSymlink("d1/linkX", "fileX", 0); - assertIsSymlink("link2", "d1/file2", 0); - assertIsSymlink("linkY", "d1/fileY", 0); - assertChdir(".."); - - /* Test 3: With -H, some symlinks on command line. */ - assertMakeDir("test3", 0755); - assertEqualInt(0, - systemf("%s -cf test3/archive.tar -H -C in ld1 d1 link2 linkY >test2/c.out 2>test2/c.err", testprog)); - assertChdir("test3"); - assertEqualInt(0, - systemf("%s -xf archive.tar >c.out 2>c.err", testprog)); - assertIsDir("ld1", umasked(0755)); - assertIsSymlink("d1/linkX", "fileX", 0); - assertIsSymlink("d1/link1", "file1", 0); - assertIsReg("link2", umasked(0644)); - assertIsSymlink("linkY", "d1/fileY", 0); - assertChdir(".."); -} diff --git a/thirdparty/libarchive/tar/test/test_option_L_upper.c b/thirdparty/libarchive/tar/test/test_option_L_upper.c deleted file mode 100644 index 5697b0f29..000000000 --- a/thirdparty/libarchive/tar/test/test_option_L_upper.c +++ /dev/null @@ -1,92 +0,0 @@ -/*- - * Copyright (c) 2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_L_upper) -{ - - if (!canSymlink()) { - skipping("Can't test symlinks on this filesystem"); - return; - } - - /* - * Create a sample archive. - */ - assertMakeDir("in", 0755); - assertChdir("in"); - assertMakeDir("d1", 0755); - assertMakeSymlink("ld1", "d1", 1); - assertMakeFile("d1/file1", 0644, "d1/file1"); - assertMakeFile("d1/file2", 0644, "d1/file2"); - assertMakeSymlink("d1/link1", "file1", 0); - assertMakeSymlink("d1/linkX", "fileX", 0); - assertMakeSymlink("link2", "d1/file2", 0); - assertMakeSymlink("linkY", "d1/fileY", 0); - assertChdir(".."); - - /* Test 1: Without -L */ - assertMakeDir("test1", 0755); - assertEqualInt(0, - systemf("%s -cf test1/archive.tar -C in . >test1/c.out 2>test1/c.err", testprog)); - assertChdir("test1"); - assertEqualInt(0, - systemf("%s -xf archive.tar >c.out 2>c.err", testprog)); - assertIsSymlink("ld1", "d1", 1); - assertIsSymlink("d1/link1", "file1", 0); - assertIsSymlink("d1/linkX", "fileX", 0); - assertIsSymlink("link2", "d1/file2", 0); - assertIsSymlink("linkY", "d1/fileY", 0); - assertChdir(".."); - - /* Test 2: With -L, no symlink on command line. */ - assertMakeDir("test2", 0755); - assertEqualInt(0, - systemf("%s -cf test2/archive.tar -L -C in . >test2/c.out 2>test2/c.err", testprog)); - assertChdir("test2"); - assertEqualInt(0, - systemf("%s -xf archive.tar >c.out 2>c.err", testprog)); - assertIsDir("ld1", umasked(0755)); - assertIsReg("d1/link1", umasked(0644)); - assertIsSymlink("d1/linkX", "fileX", 0); - assertIsReg("link2", umasked(0644)); - assertIsSymlink("linkY", "d1/fileY", 0); - assertChdir(".."); - - /* Test 3: With -L, some symlinks on command line. */ - assertMakeDir("test3", 0755); - assertEqualInt(0, - systemf("%s -cf test3/archive.tar -L -C in ld1 d1 link2 linkY >test2/c.out 2>test2/c.err", testprog)); - assertChdir("test3"); - assertEqualInt(0, - systemf("%s -xf archive.tar >c.out 2>c.err", testprog)); - assertIsDir("ld1", umasked(0755)); - assertIsReg("d1/link1", umasked(0644)); - assertIsSymlink("d1/linkX", "fileX", 0); - assertIsReg("link2", umasked(0644)); - assertIsSymlink("linkY", "d1/fileY", 0); - assertChdir(".."); -} diff --git a/thirdparty/libarchive/tar/test/test_option_O_upper.c b/thirdparty/libarchive/tar/test/test_option_O_upper.c deleted file mode 100644 index b9c8c0cad..000000000 --- a/thirdparty/libarchive/tar/test/test_option_O_upper.c +++ /dev/null @@ -1,87 +0,0 @@ -/*- - * Copyright (c) 2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -static const char *test4out[] = {"file1", "file2", NULL}; -static const char *test5err[] = {"file1", "file2", NULL}; - -DEFINE_TEST(test_option_O_upper) -{ - assertMakeFile("file1", 0644, "file1"); - assertMakeFile("file2", 0644, "file2"); - assertEqualInt(0, systemf("%s -cf archive.tar file1 file2", testprog)); - - /* Test 1: -x without -O */ - assertMakeDir("test1", 0755); - assertChdir("test1"); - assertEqualInt(0, - systemf("%s -xf ../archive.tar >test.out 2>test.err", testprog)); - assertFileContents("file1", 5, "file1"); - assertFileContents("file2", 5, "file2"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 2: -x with -O */ - assertMakeDir("test2", 0755); - assertChdir("test2"); - assertEqualInt(0, - systemf("%s -xOf ../archive.tar file1 >test.out 2>test.err", testprog)); - assertFileNotExists("file1"); - assertFileNotExists("file2"); - assertFileContents("file1", 5, "test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 3: -x with -O and multiple files */ - assertMakeDir("test3", 0755); - assertChdir("test3"); - assertEqualInt(0, - systemf("%s -xOf ../archive.tar >test.out 2>test.err", testprog)); - assertFileNotExists("file1"); - assertFileNotExists("file2"); - assertFileContents("file1file2", 10, "test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 4: -t without -O */ - assertMakeDir("test4", 0755); - assertChdir("test4"); - assertEqualInt(0, - systemf("%s -tf ../archive.tar >test.out 2>test.err", testprog)); - assertFileContainsLinesAnyOrder("test.out", test4out); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 5: -t with -O */ - assertMakeDir("test5", 0755); - assertChdir("test5"); - assertEqualInt(0, - systemf("%s -tOf ../archive.tar >test.out 2>test.err", testprog)); - assertEmptyFile("test.out"); - assertFileContainsLinesAnyOrder("test.err", test5err); - assertChdir(".."); -} diff --git a/thirdparty/libarchive/tar/test/test_option_T_upper.c b/thirdparty/libarchive/tar/test/test_option_T_upper.c deleted file mode 100644 index f2b65d7bd..000000000 --- a/thirdparty/libarchive/tar/test/test_option_T_upper.c +++ /dev/null @@ -1,160 +0,0 @@ -/*- - * Copyright (c) 2003-2008 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/test/test_option_T.c,v 1.3 2008/08/15 06:12:02 kientzle Exp $"); - -static int -tryMakeFile(const char *fn) -{ - FILE *f = fopen(fn, "w"); - if (f == NULL) - return (0); - fclose(f); - return (1); -} - -DEFINE_TEST(test_option_T_upper) -{ - FILE *f; - int r; - int gnarlyFilesSupported; - - /* Create a simple dir hierarchy; bail if anything fails. */ - if (!assertMakeDir("d1", 0755)) return; - if (!assertMakeDir("d1/d2", 0755)) return; - if (!assertMakeFile("f", 0644, "")) return; - if (!assertMakeFile("d1/f1", 0644, "")) return; - if (!assertMakeFile("d1/f2", 0644, "")) return; - if (!assertMakeFile("d1/d2/f3", 0644, "")) return; - if (!assertMakeFile("d1/d2/f4", 0644, "")) return; - if (!assertMakeFile("d1/d2/f5", 0644, "")) return; - if (!assertMakeFile("d1/d2/f6", 0644, "")) return; - /* Some platforms don't permit such things; just skip it. */ - gnarlyFilesSupported = tryMakeFile("d1/d2/f\x0a"); - - /* Populate a file list */ - f = fopen("filelist", "w+"); - if (!assert(f != NULL)) - return; - /* Use a variety of text line endings. */ - fprintf(f, "f\x0d"); /* CR */ - fprintf(f, "d1/f1\x0d\x0a"); /* CRLF */ - fprintf(f, "d1/d2/f4\x0a"); /* NL */ - fprintf(f, "d1/d2/f6"); /* EOF */ - fclose(f); - - /* Populate a second file list */ - f = fopen("filelist2", "w+"); - if (!assert(f != NULL)) - return; - /* Use null-terminated names. */ - fprintf(f, "d1/d2/f3"); - assertEqualInt(1, fwrite("\0", 1, 1, f)); - fprintf(f, "d1/d2/f5"); - assertEqualInt(1, fwrite("\0", 1, 1, f)); - if (gnarlyFilesSupported) { - fprintf(f, "d1/d2/f\x0a"); - assertEqualInt(1, fwrite("\0", 1, 1, f)); - } - fclose(f); - - /* Use -c -T to archive up the files. */ - r = systemf("%s -c -f test1.tar -T filelist > test1.out 2> test1.err", - testprog); - assert(r == 0); - assertEmptyFile("test1.out"); - assertEmptyFile("test1.err"); - - /* Use -x -T to dearchive the files */ - if (!assertMakeDir("test1", 0755)) return; - systemf("%s -x -f test1.tar -T filelist -C test1" - " > test1b.out 2> test1b.err", testprog); - assertEmptyFile("test1b.out"); - assertEmptyFile("test1b.err"); - - /* Verify the files were extracted. */ - assertFileExists("test1/f"); - assertFileExists("test1/d1/f1"); - assertFileNotExists("test1/d1/f2"); - assertFileNotExists("test1/d1/d2/f3"); - assertFileExists("test1/d1/d2/f4"); - assertFileNotExists("test1/d1/d2/f5"); - assertFileExists("test1/d1/d2/f6"); - if (gnarlyFilesSupported) { - assertFileNotExists("test1/d1/d2/f\x0a"); - } - - /* Use -r -T to add more files to the archive. */ - systemf("%s -r -f test1.tar --null -T filelist2 > test2.out 2> test2.err", - testprog); - assertEmptyFile("test2.out"); - assertEmptyFile("test2.err"); - - /* Use -x without -T to dearchive the files (ensure -r worked) */ - if (!assertMakeDir("test3", 0755)) return; - systemf("%s -x -f test1.tar -C test3" - " > test3.out 2> test3.err", testprog); - assertEmptyFile("test3.out"); - assertEmptyFile("test3.err"); - /* Verify the files were extracted.*/ - assertFileExists("test3/f"); - assertFileExists("test3/d1/f1"); - assertFileNotExists("test3/d1/f2"); - assertFileExists("test3/d1/d2/f3"); - assertFileExists("test3/d1/d2/f4"); - assertFileExists("test3/d1/d2/f5"); - assertFileExists("test3/d1/d2/f6"); - if (gnarlyFilesSupported) { - assertFileExists("test3/d1/d2/f\x0a"); - } - - /* Use -x -T to dearchive the files (verify -x -T together) */ - if (!assertMakeDir("test2", 0755)) return; - systemf("%s -x -f test1.tar -T filelist -C test2" - " > test2b.out 2> test2b.err", testprog); - assertEmptyFile("test2b.out"); - assertEmptyFile("test2b.err"); - /* Verify the files were extracted.*/ - assertFileExists("test2/f"); - assertFileExists("test2/d1/f1"); - assertFileNotExists("test2/d1/f2"); - assertFileNotExists("test2/d1/d2/f3"); - assertFileExists("test2/d1/d2/f4"); - assertFileNotExists("test2/d1/d2/f5"); - assertFileExists("test2/d1/d2/f6"); - if (gnarlyFilesSupported) { - assertFileNotExists("test2/d1/d2/f\x0a"); - } - - assertMakeDir("test4", 0755); - assertMakeDir("test4_out", 0755); - assertMakeDir("test4_out2", 0755); - assertMakeDir("test4/d1", 0755); - assertMakeFile("test4/d1/foo", 0644, ""); - - - /* TODO: Include some use of -C directory-changing within the filelist. */ - /* I'm pretty sure -C within the filelist is broken on extract. */ -} diff --git a/thirdparty/libarchive/tar/test/test_option_U_upper.c b/thirdparty/libarchive/tar/test/test_option_U_upper.c deleted file mode 100644 index d864e13c4..000000000 --- a/thirdparty/libarchive/tar/test/test_option_U_upper.c +++ /dev/null @@ -1,159 +0,0 @@ -/*- - * Copyright (c) 2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_U_upper) -{ - int r; - - assertMakeFile("file1", 0644, "file1"); - assertMakeDir("d1", 0755); - assertMakeFile("d1/file1", 0644, "d1/file1"); - assertEqualInt(0, systemf("%s -cf archive.tar file1 d1/file1", testprog)); - - /* - * bsdtar's man page used to claim that -x without -U would - * not break hard links. This was and is nonsense. The first - * two tests here simply verify that existing hard links get - * broken regardless. - */ - - /* Test 1: -x without -U */ - assertMakeDir("test1", 0755); - assertChdir("test1"); - assertMakeFile("file1", 0644, "file1new"); - assertMakeHardlink("file2", "file1"); - assertEqualInt(0, - systemf("%s -xf ../archive.tar >test.out 2>test.err", testprog)); - assertFileContents("file1", 5, "file1"); - assertFileContents("file1new", 8, "file2"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - - /* Test 2: -x with -U */ - assertMakeDir("test2", 0755); - assertChdir("test2"); - assertMakeFile("file1", 0644, "file1new"); - assertMakeHardlink("file2", "file1"); - assertEqualInt(0, - systemf("%s -xUf ../archive.tar >test.out 2>test.err", testprog)); - assertFileContents("file1", 5, "file1"); - assertFileContents("file1new", 8, "file2"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* - * -U does make a difference in how bsdtar handles unwanted symlinks, - * though. It interacts with -P. - */ - if (!canSymlink()) - return; - - /* Test 3: Intermediate dir symlink causes error by default */ - assertMakeDir("test3", 0755); - assertChdir("test3"); - assertMakeDir("realDir", 0755); - assertMakeSymlink("d1", "realDir", 1); - r = systemf("%s -xf ../archive.tar d1/file1 >test.out 2>test.err", testprog); - assert(r != 0); - assertIsSymlink("d1", "realDir", 1); - assertFileNotExists("d1/file1"); - assertEmptyFile("test.out"); - assertNonEmptyFile("test.err"); - assertChdir(".."); - - /* Test 4: Intermediate dir symlink gets removed with -U */ - assertMakeDir("test4", 0755); - assertChdir("test4"); - assertMakeDir("realDir", 0755); - assertMakeSymlink("d1", "realDir", 1); - assertEqualInt(0, - systemf("%s -xUf ../archive.tar >test.out 2>test.err", testprog)); - assertIsDir("d1", -1); - assertFileContents("d1/file1", 8, "d1/file1"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 5: Intermediate dir symlink is followed with -P */ - assertMakeDir("test5", 0755); - assertChdir("test5"); - assertMakeDir("realDir", 0755); - assertMakeSymlink("d1", "realDir", 1); - assertEqualInt(0, - systemf("%s -xPf ../archive.tar d1/file1 >test.out 2>test.err", testprog)); - assertIsSymlink("d1", "realDir", 1); - assertFileContents("d1/file1", 8, "d1/file1"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 6: Intermediate dir symlink is followed with -PU */ - assertMakeDir("test6", 0755); - assertChdir("test6"); - assertMakeDir("realDir", 0755); - assertMakeSymlink("d1", "realDir", 1); - assertEqualInt(0, - systemf("%s -xPUf ../archive.tar d1/file1 >test.out 2>test.err", testprog)); - assertIsSymlink("d1", "realDir", 1); - assertFileContents("d1/file1", 8, "d1/file1"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 7: Final file symlink replaced by default */ - assertMakeDir("test7", 0755); - assertChdir("test7"); - assertMakeDir("d1", 0755); - assertMakeFile("d1/realfile1", 0644, "realfile1"); - assertMakeSymlink("d1/file1", "d1/realfile1", 0); - assertEqualInt(0, - systemf("%s -xf ../archive.tar d1/file1 >test.out 2>test.err", testprog)); - assertIsReg("d1/file1", umasked(0644)); - assertFileContents("d1/file1", 8, "d1/file1"); - assertFileContents("realfile1", 9, "d1/realfile1"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 8: Final file symlink replaced with -PU */ - assertMakeDir("test8", 0755); - assertChdir("test8"); - assertMakeDir("d1", 0755); - assertMakeFile("d1/realfile1", 0644, "realfile1"); - assertMakeSymlink("d1/file1", "d1/realfile1", 0); - assertEqualInt(0, - systemf("%s -xPUf ../archive.tar d1/file1 >test.out 2>test.err", testprog)); - assertIsReg("d1/file1", umasked(0644)); - assertFileContents("d1/file1", 8, "d1/file1"); - assertFileContents("realfile1", 9, "d1/realfile1"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); -} diff --git a/thirdparty/libarchive/tar/test/test_option_X_upper.c b/thirdparty/libarchive/tar/test/test_option_X_upper.c deleted file mode 100644 index 4916af297..000000000 --- a/thirdparty/libarchive/tar/test/test_option_X_upper.c +++ /dev/null @@ -1,159 +0,0 @@ -/*- - * Copyright (c) 2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_X_upper) -{ - int r; - - /* - * Create a sample archive. - */ - assertMakeFile("file1", 0644, "file1"); - assertMakeFile("file2", 0644, "file2"); - assertMakeFile("file3a", 0644, "file3a"); - assertMakeFile("file4a", 0644, "file4a"); - assertEqualInt(0, - systemf("%s -cf archive.tar file1 file2 file3a file4a", testprog)); - - /* - * Now, try extracting from the test archive with various -X usage. - */ - - /* Test 1: Without -X */ - assertMakeDir("test1", 0755); - assertChdir("test1"); - r = systemf("%s -xf ../archive.tar >test.out 2>test.err", - testprog); - if (!assertEqualInt(0, r)) - return; - - assertFileContents("file1", 5, "file1"); - assertFileContents("file2", 5, "file2"); - assertFileContents("file3a", 6, "file3a"); - assertFileContents("file4a", 6, "file4a"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 2: Use -X to skip one file */ - assertMakeDir("test2", 0755); - assertChdir("test2"); - assertMakeFile("exclusions", 0644, "file1\n"); - assertEqualInt(0, - systemf("%s -xf ../archive.tar -X exclusions >test.out 2>test.err", testprog)); - assertFileNotExists("file1"); - assertFileContents("file2", 5, "file2"); - assertFileContents("file3a", 6, "file3a"); - assertFileContents("file4a", 6, "file4a"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 3: Use -X to skip multiple files */ - assertMakeDir("test3", 0755); - assertChdir("test3"); - assertMakeFile("exclusions", 0644, "file1\nfile2\n"); - assertEqualInt(0, - systemf("%s -xf ../archive.tar -X exclusions >test.out 2>test.err", testprog)); - assertFileNotExists("file1"); - assertFileNotExists("file2"); - assertFileContents("file3a", 6, "file3a"); - assertFileContents("file4a", 6, "file4a"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 4: Omit trailing \n */ - assertMakeDir("test4", 0755); - assertChdir("test4"); - assertMakeFile("exclusions", 0644, "file1\nfile2"); - assertEqualInt(0, - systemf("%s -xf ../archive.tar -X exclusions >test.out 2>test.err", testprog)); - assertFileNotExists("file1"); - assertFileNotExists("file2"); - assertFileContents("file3a", 6, "file3a"); - assertFileContents("file4a", 6, "file4a"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 5: include/exclude without overlap */ - assertMakeDir("test5", 0755); - assertChdir("test5"); - assertMakeFile("exclusions", 0644, "file1\nfile2"); - assertEqualInt(0, - systemf("%s -xf ../archive.tar -X exclusions file3a >test.out 2>test.err", testprog)); - assertFileNotExists("file1"); - assertFileNotExists("file2"); - assertFileContents("file3a", 6, "file3a"); - assertFileNotExists("file4a"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 6: Overlapping include/exclude */ - assertMakeDir("test6", 0755); - assertChdir("test6"); - assertMakeFile("exclusions", 0644, "file1\nfile2"); - assertEqualInt(0, - systemf("%s -xf ../archive.tar -X exclusions file1 file3a >test.out 2>test.err", testprog)); - assertFileNotExists("file1"); - assertFileNotExists("file2"); - assertFileContents("file3a", 6, "file3a"); - assertFileNotExists("file4a"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 7: with pattern */ - assertMakeDir("test7", 0755); - assertChdir("test7"); - assertMakeFile("exclusions", 0644, "file*a\nfile1"); - assertEqualInt(0, - systemf("%s -xf ../archive.tar -X exclusions >test.out 2>test.err", testprog)); - assertFileNotExists("file1"); - assertFileContents("file2", 5, "file2"); - assertFileNotExists("file3a"); - assertFileNotExists("file4a"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 8: with empty exclusions file */ - assertMakeDir("test8", 0755); - assertChdir("test8"); - assertMakeFile("exclusions", 0644, ""); - assertEqualInt(0, - systemf("%s -xf ../archive.tar -X exclusions >test.out 2>test.err", testprog)); - assertFileContents("file1", 5, "file1"); - assertFileContents("file2", 5, "file2"); - assertFileContents("file3a", 6, "file3a"); - assertFileContents("file4a", 6, "file4a"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); -} diff --git a/thirdparty/libarchive/tar/test/test_option_a.c b/thirdparty/libarchive/tar/test/test_option_a.c deleted file mode 100644 index d9eed8777..000000000 --- a/thirdparty/libarchive/tar/test/test_option_a.c +++ /dev/null @@ -1,117 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_a) -{ - size_t s; - char *p; - - /* Create a file. */ - assertMakeFile("f", 0644, "a"); - - /* Test1: archive it with .tar.Z suffix. */ - assertEqualInt(0, - systemf("%s -acf test1.tar.Z f 2>test1.err", testprog)); - assertEmptyFile("test1.err"); - /* Check that the archive file has a compress signature. */ - p = slurpfile(&s, "test1.tar.Z"); - assert(s > 2); - failure("The archive should be compressed"); - assertEqualMem(p, "\x1f\x9d", 2); - free(p); - - /* Test2: archive it with .taZ suffix. */ - assertEqualInt(0, - systemf("%s -acf test2.taZ f 2>test2.err", testprog)); - assertEmptyFile("test2.err"); - /* Check that the archive file has a compress signature. */ - p = slurpfile(&s, "test2.taZ"); - assert(s > 2); - failure("The archive should be compressed"); - assertEqualMem(p, "\x1f\x9d", 2); - free(p); - - /* Test3: archive it with .tar.Z.uu suffix. */ - assertEqualInt(0, - systemf("%s -acf test3.tar.Z.uu f 2>test3.err", testprog)); - assertEmptyFile("test3.err"); - /* Check that the archive file has a compress signature. */ - p = slurpfile(&s, "test3.tar.Z.uu"); - assert(s > 12); - failure("The archive should be uuencoded"); - assertEqualMem(p, "begin 644 -\n", 12); - free(p); - - /* Test4: archive it with .zip suffix. */ - assertEqualInt(0, - systemf("%s -acf test4.zip f 2>test4.err", testprog)); - assertEmptyFile("test4.err"); - /* Check that the archive file has a compress signature. */ - p = slurpfile(&s, "test4.zip"); - assert(s > 4); - failure("The archive should be zipped"); - assertEqualMem(p, "\x50\x4b\x03\x04", 4); - free(p); - - /* Test5: archive it with .tar.Z suffix and --uuencode option. */ - assertEqualInt(0, - systemf("%s -acf test5.tar.Z --uuencode f 2>test5.err", - testprog)); - assertEmptyFile("test5.err"); - /* Check that the archive file has a compress signature. */ - p = slurpfile(&s, "test5.tar.Z"); - assert(s > 2); - failure("The archive should be compressed, ignoring --uuencode option"); - assertEqualMem(p, "\x1f\x9d", 2); - free(p); - - /* Test6: archive it with .xxx suffix(unknown suffix) and - * --uuencode option. */ - assertEqualInt(0, - systemf("%s -acf test6.xxx --uuencode f 2>test6.err", - testprog)); - assertEmptyFile("test6.err"); - /* Check that the archive file has a compress signature. */ - p = slurpfile(&s, "test6.xxx"); - assert(s > 12); - failure("The archive should be uuencoded"); - assertEqualMem(p, "begin 644 -\n", 12); - free(p); - - /* Test7: archive it with .tar.Z suffix using a long-name option. */ - assertEqualInt(0, - systemf("%s --auto-compress -cf test7.tar.Z f 2>test7.err", - testprog)); - assertEmptyFile("test7.err"); - /* Check that the archive file has a compress signature. */ - p = slurpfile(&s, "test7.tar.Z"); - assert(s > 2); - failure("The archive should be compressed"); - assertEqualMem(p, "\x1f\x9d", 2); - free(p); -} diff --git a/thirdparty/libarchive/tar/test/test_option_acls.c b/thirdparty/libarchive/tar/test/test_option_acls.c deleted file mode 100644 index f7451c8eb..000000000 --- a/thirdparty/libarchive/tar/test/test_option_acls.c +++ /dev/null @@ -1,512 +0,0 @@ -/*- - * Copyright (c) 2017 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -#if ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_DARWIN || ARCHIVE_ACL_LIBACL -static const acl_perm_t acl_perms[] = { -#if ARCHIVE_ACL_DARWIN - ACL_READ_DATA, - ACL_LIST_DIRECTORY, - ACL_WRITE_DATA, - ACL_ADD_FILE, - ACL_EXECUTE, - ACL_SEARCH, - ACL_DELETE, - ACL_APPEND_DATA, - ACL_ADD_SUBDIRECTORY, - ACL_DELETE_CHILD, - ACL_READ_ATTRIBUTES, - ACL_WRITE_ATTRIBUTES, - ACL_READ_EXTATTRIBUTES, - ACL_WRITE_EXTATTRIBUTES, - ACL_READ_SECURITY, - ACL_WRITE_SECURITY, - ACL_CHANGE_OWNER, - ACL_SYNCHRONIZE -#else /* !ARCHIVE_ACL_DARWIN */ - ACL_EXECUTE, - ACL_WRITE, - ACL_READ, -#if ARCHIVE_ACL_FREEBSD_NFS4 - ACL_READ_DATA, - ACL_LIST_DIRECTORY, - ACL_WRITE_DATA, - ACL_ADD_FILE, - ACL_APPEND_DATA, - ACL_ADD_SUBDIRECTORY, - ACL_READ_NAMED_ATTRS, - ACL_WRITE_NAMED_ATTRS, - ACL_DELETE_CHILD, - ACL_READ_ATTRIBUTES, - ACL_WRITE_ATTRIBUTES, - ACL_DELETE, - ACL_READ_ACL, - ACL_WRITE_ACL, - ACL_WRITE_OWNER, - ACL_SYNCHRONIZE -#endif /* ARCHIVE_ACL_FREEBSD_NFS4 */ -#endif /* !ARCHIVE_ACL_DARWIN */ -}; -#if ARCHIVE_ACL_DARWIN || ARCHIVE_ACL_FREEBSD_NFS4 -static const acl_flag_t acl_flags[] = { -#if ARCHIVE_ACL_DARWIN - ACL_ENTRY_INHERITED, - ACL_ENTRY_FILE_INHERIT, - ACL_ENTRY_DIRECTORY_INHERIT, - ACL_ENTRY_LIMIT_INHERIT, - ACL_ENTRY_ONLY_INHERIT -#else /* ARCHIVE_ACL_FREEBSD_NFS4 */ - ACL_ENTRY_FILE_INHERIT, - ACL_ENTRY_DIRECTORY_INHERIT, - ACL_ENTRY_NO_PROPAGATE_INHERIT, - ACL_ENTRY_INHERIT_ONLY, - ACL_ENTRY_SUCCESSFUL_ACCESS, - ACL_ENTRY_FAILED_ACCESS, -#ifdef ACL_ENTRY_INHERITED - ACL_ENTRY_INHERITED -#endif -#endif /* ARCHIVE_ACL_FREEBSD_NFS4 */ -}; -#endif /* ARCHIVE_ACL_DARWIN || ARCHIVE_ACL_FREEBSD_NFS4 */ - -/* - * Compare two ACL entries on FreeBSD or on Mac OS X - */ -static int -compare_acl_entry(acl_entry_t ae_a, acl_entry_t ae_b, int is_nfs4) -{ - acl_tag_t tag_a, tag_b; - acl_permset_t permset_a, permset_b; - int perm_a, perm_b, perm_start, perm_end; - void *qual_a, *qual_b; -#if ARCHIVE_ACL_FREEBSD_NFS4 - acl_entry_type_t type_a, type_b; -#endif -#if ARCHIVE_ACL_FREEBSD_NFS4 || ARCHIVE_ACL_DARWIN - acl_flagset_t flagset_a, flagset_b; - int flag_a, flag_b; -#endif - int i, r; - - - /* Compare ACL tag */ - r = acl_get_tag_type(ae_a, &tag_a); - failure("acl_get_tag_type() error: %s", strerror(errno)); - if (assertEqualInt(r, 0) == 0) - return (-1); - r = acl_get_tag_type(ae_b, &tag_b); - failure("acl_get_tag_type() error: %s", strerror(errno)); - if (assertEqualInt(r, 0) == 0) - return (-1); - if (tag_a != tag_b) - return (0); - - /* Compare ACL qualifier */ -#if ARCHIVE_ACL_DARWIN - if (tag_a == ACL_EXTENDED_ALLOW || tag_b == ACL_EXTENDED_DENY) -#else - if (tag_a == ACL_USER || tag_a == ACL_GROUP) -#endif - { - qual_a = acl_get_qualifier(ae_a); - failure("acl_get_qualifier() error: %s", strerror(errno)); - if (assert(qual_a != NULL) == 0) - return (-1); - qual_b = acl_get_qualifier(ae_b); - failure("acl_get_qualifier() error: %s", strerror(errno)); - if (assert(qual_b != NULL) == 0) { - acl_free(qual_a); - return (-1); - } -#if ARCHIVE_ACL_DARWIN - if (memcmp(((guid_t *)qual_a)->g_guid, - ((guid_t *)qual_b)->g_guid, KAUTH_GUID_SIZE) != 0) -#else - if ((tag_a == ACL_USER && - (*(uid_t *)qual_a != *(uid_t *)qual_b)) || - (tag_a == ACL_GROUP && - (*(gid_t *)qual_a != *(gid_t *)qual_b))) -#endif - { - acl_free(qual_a); - acl_free(qual_b); - return (0); - } - acl_free(qual_a); - acl_free(qual_b); - } - -#if ARCHIVE_ACL_FREEBSD_NFS4 - if (is_nfs4) { - /* Compare NFS4 ACL type */ - r = acl_get_entry_type_np(ae_a, &type_a); - failure("acl_get_entry_type_np() error: %s", strerror(errno)); - if (assertEqualInt(r, 0) == 0) - return (-1); - r = acl_get_entry_type_np(ae_b, &type_b); - failure("acl_get_entry_type_np() error: %s", strerror(errno)); - if (assertEqualInt(r, 0) == 0) - return (-1); - if (type_a != type_b) - return (0); - } -#endif - - /* Compare ACL perms */ - r = acl_get_permset(ae_a, &permset_a); - failure("acl_get_permset() error: %s", strerror(errno)); - if (assertEqualInt(r, 0) == 0) - return (-1); - r = acl_get_permset(ae_b, &permset_b); - failure("acl_get_permset() error: %s", strerror(errno)); - if (assertEqualInt(r, 0) == 0) - return (-1); - - perm_start = 0; - perm_end = (int)(sizeof(acl_perms) / sizeof(acl_perms[0])); -#if ARCHIVE_ACL_FREEBSD_NFS4 - if (is_nfs4) - perm_start = 3; - else - perm_end = 3; -#endif - /* Cycle through all perms and compare their value */ - for (i = perm_start; i < perm_end; i++) { -#if ARCHIVE_ACL_LIBACL - perm_a = acl_get_perm(permset_a, acl_perms[i]); - perm_b = acl_get_perm(permset_b, acl_perms[i]); -#else - perm_a = acl_get_perm_np(permset_a, acl_perms[i]); - perm_b = acl_get_perm_np(permset_b, acl_perms[i]); -#endif - if (perm_a == -1 || perm_b == -1) - return (-1); - if (perm_a != perm_b) - return (0); - } - -#if ARCHIVE_ACL_FREEBSD_NFS4 || ARCHIVE_ACL_DARWIN - if (is_nfs4) { - r = acl_get_flagset_np(ae_a, &flagset_a); - failure("acl_get_flagset_np() error: %s", strerror(errno)); - if (assertEqualInt(r, 0) == 0) - return (-1); - r = acl_get_flagset_np(ae_b, &flagset_b); - failure("acl_get_flagset_np() error: %s", strerror(errno)); - if (assertEqualInt(r, 0) == 0) - return (-1); - /* Cycle through all flags and compare their status */ - for (i = 0; i < (int)(sizeof(acl_flags) / sizeof(acl_flags[0])); - i++) { - flag_a = acl_get_flag_np(flagset_a, acl_flags[i]); - flag_b = acl_get_flag_np(flagset_b, acl_flags[i]); - if (flag_a == -1 || flag_b == -1) - return (-1); - if (flag_a != flag_b) - return (0); - } - } -#else /* ARCHIVE_ACL_FREEBSD_NFS4 || ARCHIVE_ACL_DARWIN */ - (void)is_nfs4; /* UNUSED */ -#endif - return (1); -} -#endif /* ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_DARWIN || ARCHIVE_ACL_LIBACL */ - -#if ARCHIVE_ACL_SUPPORT -/* - * Clear default ACLs or inheritance flags - */ -static void -clear_inheritance_flags(const char *path, int type) -{ - switch (type) { - case ARCHIVE_TEST_ACL_TYPE_POSIX1E: -#if ARCHIVE_ACL_POSIX1E -#if !ARCHIVE_ACL_SUNOS - acl_delete_def_file(path); -#else - /* Solaris */ - setTestAcl(path); -#endif -#endif /* ARCHIVE_ACL_POSIX1E */ - break; - case ARCHIVE_TEST_ACL_TYPE_NFS4: -#if ARCHIVE_ACL_NFS4 - setTestAcl(path); -#endif - break; - default: - (void)path; /* UNUSED */ - break; - } -} - -static int -compare_acls(const char *path_a, const char *path_b) -{ - int ret = 1; - int is_nfs4 = 0; -#if ARCHIVE_ACL_SUNOS - void *acl_a, *acl_b; - int aclcnt_a, aclcnt_b; - aclent_t *aclent_a, *aclent_b; - ace_t *ace_a, *ace_b; - int e; -#elif ARCHIVE_ACL_DARWIN || ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_LIBACL - acl_t acl_a, acl_b; - acl_entry_t aclent_a, aclent_b; - int a, b, r; -#endif -#if ARCHIVE_ACL_LIBRICHACL - struct richacl *richacl_a, *richacl_b; - - richacl_a = NULL; - richacl_b = NULL; -#endif - -#if ARCHIVE_ACL_DARWIN || ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_LIBACL || \ - ARCHIVE_ACL_SUNOS - acl_a = NULL; - acl_b = NULL; -#endif -#if ARCHIVE_ACL_SUNOS - acl_a = sunacl_get(GETACL, &aclcnt_a, 0, path_a); - if (acl_a == NULL) { -#if ARCHIVE_ACL_SUNOS_NFS4 - is_nfs4 = 1; - acl_a = sunacl_get(ACE_GETACL, &aclcnt_a, 0, path_a); -#endif - failure("acl_get() error: %s", strerror(errno)); - if (assert(acl_a != NULL) == 0) - return (-1); -#if ARCHIVE_ACL_SUNOS_NFS4 - acl_b = sunacl_get(ACE_GETACL, &aclcnt_b, 0, path_b); -#endif - } else - acl_b = sunacl_get(GETACL, &aclcnt_b, 0, path_b); - if (acl_b == NULL && (errno == ENOSYS || errno == ENOTSUP)) { - free(acl_a); - return (0); - } - failure("acl_get() error: %s", strerror(errno)); - if (assert(acl_b != NULL) == 0) { - free(acl_a); - return (-1); - } - - if (aclcnt_a != aclcnt_b) { - ret = 0; - goto exit_free; - } - - for (e = 0; e < aclcnt_a; e++) { - if (!is_nfs4) { - aclent_a = &((aclent_t *)acl_a)[e]; - aclent_b = &((aclent_t *)acl_b)[e]; - if (aclent_a->a_type != aclent_b->a_type || - aclent_a->a_id != aclent_b->a_id || - aclent_a->a_perm != aclent_b->a_perm) { - ret = 0; - goto exit_free; - } - } -#if ARCHIVE_ACL_SUNOS_NFS4 - else { - ace_a = &((ace_t *)acl_a)[e]; - ace_b = &((ace_t *)acl_b)[e]; - if (ace_a->a_who != ace_b->a_who || - ace_a->a_access_mask != ace_b->a_access_mask || - ace_a->a_flags != ace_b->a_flags || - ace_a->a_type != ace_b->a_type) { - ret = 0; - goto exit_free; - } - } -#endif - } -#else /* !ARCHIVE_ACL_SUNOS */ -#if ARCHIVE_ACL_LIBRICHACL - richacl_a = richacl_get_file(path_a); -#if !ARCHIVE_ACL_LIBACL - if (richacl_a == NULL && - (errno == ENODATA || errno == ENOTSUP || errno == ENOSYS)) - return (0); - failure("richacl_get_file() error: %s (%s)", path_a, strerror(errno)); - if (assert(richacl_a != NULL) == 0) - return (-1); -#endif - if (richacl_a != NULL) { - richacl_b = richacl_get_file(path_b); - if (richacl_b == NULL && - (errno == ENODATA || errno == ENOTSUP || errno == ENOSYS)) { - richacl_free(richacl_a); - return (0); - } - failure("richacl_get_file() error: %s (%s)", path_b, - strerror(errno)); - if (assert(richacl_b != NULL) == 0) { - richacl_free(richacl_a); - return (-1); - } - if (richacl_compare(richacl_a, richacl_b) == 0) - ret = 0; - richacl_free(richacl_a); - richacl_free(richacl_b); - return (ret); - } -#endif /* ARCHIVE_ACL_LIBRICHACL */ -#if ARCHIVE_ACL_DARWIN || ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_LIBACL -#if ARCHIVE_ACL_DARWIN - is_nfs4 = 1; - acl_a = acl_get_file(path_a, ACL_TYPE_EXTENDED); -#elif ARCHIVE_ACL_FREEBSD_NFS4 - acl_a = acl_get_file(path_a, ACL_TYPE_NFS4); - if (acl_a != NULL) - is_nfs4 = 1; -#endif - if (acl_a == NULL) - acl_a = acl_get_file(path_a, ACL_TYPE_ACCESS); - failure("acl_get_file() error: %s (%s)", path_a, strerror(errno)); - if (assert(acl_a != NULL) == 0) - return (-1); -#if ARCHIVE_ACL_DARWIN - acl_b = acl_get_file(path_b, ACL_TYPE_EXTENDED); -#elif ARCHIVE_ACL_FREEBSD_NFS4 - acl_b = acl_get_file(path_b, ACL_TYPE_NFS4); -#endif -#if !ARCHIVE_ACL_DARWIN - if (acl_b == NULL) { -#if ARCHIVE_ACL_FREEBSD_NFS4 - if (is_nfs4) { - acl_free(acl_a); - return (0); - } -#endif - acl_b = acl_get_file(path_b, ACL_TYPE_ACCESS); - } - failure("acl_get_file() error: %s (%s)", path_b, strerror(errno)); - if (assert(acl_b != NULL) == 0) { - acl_free(acl_a); - return (-1); - } -#endif - a = acl_get_entry(acl_a, ACL_FIRST_ENTRY, &aclent_a); - if (a == -1) { - ret = 0; - goto exit_free; - } - b = acl_get_entry(acl_b, ACL_FIRST_ENTRY, &aclent_b); - if (b == -1) { - ret = 0; - goto exit_free; - } -#if ARCHIVE_ACL_DARWIN - while (a == 0 && b == 0) -#else /* FreeBSD, Linux */ - while (a == 1 && b == 1) -#endif - { - r = compare_acl_entry(aclent_a, aclent_b, is_nfs4); - if (r != 1) { - ret = r; - goto exit_free; - } - a = acl_get_entry(acl_a, ACL_NEXT_ENTRY, &aclent_a); - b = acl_get_entry(acl_b, ACL_NEXT_ENTRY, &aclent_b); - } - /* Entry count must match */ - if (a != b) - ret = 0; -#endif /* ARCHIVE_ACL_DARWIN || ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_LIBACL */ -#endif /* !ARCHIVE_ACL_SUNOS */ -exit_free: -#if ARCHIVE_ACL_SUNOS - free(acl_a); - free(acl_b); -#else - acl_free(acl_a); - acl_free(acl_b); -#endif - return (ret); -} -#endif /* ARCHIVE_ACL_SUPPORT */ - -DEFINE_TEST(test_option_acls) -{ -#if !ARCHIVE_ACL_SUPPORT - skipping("ACLs are not supported on this platform"); -#else /* ARCHIVE_ACL_SUPPORT */ - int acltype, r; - - assertMakeFile("f", 0644, "a"); - acltype = setTestAcl("f"); - if (acltype == 0) { - skipping("Can't write ACLs on the filesystem"); - return; - } - - /* Archive it with acls */ - r = systemf("%s -c --no-mac-metadata --acls -f acls.tar f >acls.out 2>acls.err", testprog); - assertEqualInt(r, 0); - - /* Archive it without acls */ - r = systemf("%s -c --no-mac-metadata --no-acls -f noacls.tar f >noacls.out 2>noacls.err", testprog); - assertEqualInt(r, 0); - - /* Extract acls with acls */ - assertMakeDir("acls_acls", 0755); - clear_inheritance_flags("acls_acls", acltype); - r = systemf("%s -x -C acls_acls --no-same-permissions --acls -f acls.tar >acls_acls.out 2>acls_acls.err", testprog); - assertEqualInt(r, 0); - r = compare_acls("f", "acls_acls/f"); - assertEqualInt(r, 1); - - /* Extract acls without acls */ - assertMakeDir("acls_noacls", 0755); - clear_inheritance_flags("acls_noacls", acltype); - r = systemf("%s -x -C acls_noacls -p --no-acls -f acls.tar >acls_noacls.out 2>acls_noacls.err", testprog); - assertEqualInt(r, 0); - r = compare_acls("f", "acls_noacls/f"); - assertEqualInt(r, 0); - - /* Extract noacls with acls flag */ - assertMakeDir("noacls_acls", 0755); - clear_inheritance_flags("noacls_acls", acltype); - r = systemf("%s -x -C noacls_acls --no-same-permissions --acls -f noacls.tar >noacls_acls.out 2>noacls_acls.err", testprog); - assertEqualInt(r, 0); - r = compare_acls("f", "noacls_acls/f"); - assertEqualInt(r, 0); - - /* Extract noacls with noacls */ - assertMakeDir("noacls_noacls", 0755); - clear_inheritance_flags("noacls_noacls", acltype); - r = systemf("%s -x -C noacls_noacls -p --no-acls -f noacls.tar >noacls_noacls.out 2>noacls_noacls.err", testprog); - assertEqualInt(r, 0); - r = compare_acls("f", "noacls_noacls/f"); - assertEqualInt(r, 0); -#endif /* ARCHIVE_ACL_SUPPORT */ -} diff --git a/thirdparty/libarchive/tar/test/test_option_b.c b/thirdparty/libarchive/tar/test/test_option_b.c deleted file mode 100644 index d1b75e350..000000000 --- a/thirdparty/libarchive/tar/test/test_option_b.c +++ /dev/null @@ -1,85 +0,0 @@ -/*- - * Copyright (c) 2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -#define USTAR_OPT " --format=ustar" - -DEFINE_TEST(test_option_b) -{ - char *testprog_ustar; - size_t testprog_ustar_len; - - assertMakeFile("file1", 0644, "file1"); - if (systemf("cat file1 > test_cat.out 2> test_cat.err") != 0) { - skipping("This test requires a `cat` program"); - return; - } - testprog_ustar_len = strlen(testprog) + sizeof(USTAR_OPT) + 1; - testprog_ustar = malloc(testprog_ustar_len); - strncpy(testprog_ustar, testprog, testprog_ustar_len); - strncat(testprog_ustar, USTAR_OPT, testprog_ustar_len); - - /* - * Bsdtar does not pad if the output is going directly to a disk file. - */ - assertEqualInt(0, systemf("%s -cf archive1.tar file1 >test1.out 2>test1.err", testprog_ustar)); - failure("bsdtar does not pad archives written directly to regular files"); - assertFileSize("archive1.tar", 2048); - assertEmptyFile("test1.out"); - assertEmptyFile("test1.err"); - - /* - * Bsdtar does pad to the block size if the output is going to a socket. - */ - /* Default is -b 20 */ - assertEqualInt(0, systemf("%s -cf - file1 2>test2.err | cat >archive2.tar ", testprog_ustar)); - failure("bsdtar does pad archives written to pipes"); - assertFileSize("archive2.tar", 10240); - assertEmptyFile("test2.err"); - - assertEqualInt(0, systemf("%s -cf - -b 20 file1 2>test3.err | cat >archive3.tar ", testprog_ustar)); - assertFileSize("archive3.tar", 10240); - assertEmptyFile("test3.err"); - - assertEqualInt(0, systemf("%s -cf - -b 10 file1 2>test4.err | cat >archive4.tar ", testprog_ustar)); - assertFileSize("archive4.tar", 5120); - assertEmptyFile("test4.err"); - - assertEqualInt(0, systemf("%s -cf - -b 1 file1 2>test5.err | cat >archive5.tar ", testprog_ustar)); - assertFileSize("archive5.tar", 2048); - assertEmptyFile("test5.err"); - - assertEqualInt(0, systemf("%s -cf - -b 8192 file1 2>test6.err | cat >archive6.tar ", testprog_ustar)); - assertFileSize("archive6.tar", 4194304); - assertEmptyFile("test6.err"); - - /* - * Note: It's not possible to verify at this level that blocks - * are getting written with the - */ - - free(testprog_ustar); -} diff --git a/thirdparty/libarchive/tar/test/test_option_b64encode.c b/thirdparty/libarchive/tar/test/test_option_b64encode.c deleted file mode 100644 index 1d0420430..000000000 --- a/thirdparty/libarchive/tar/test/test_option_b64encode.c +++ /dev/null @@ -1,56 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_b64encode) -{ - char *p; - size_t s; - - /* Create a file. */ - assertMakeFile("f", 0644, "a"); - - /* Archive it with compress compression and uuencode. */ - assertEqualInt(0, - systemf("%s -cf - -Z --b64encode f >archive.out 2>archive.err", - testprog)); - /* Check that the archive file has an uuencode signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 2); - assertEqualMem(p, "begin-base64 644", 16); - free(p); - - /* Archive it with uuencode only. */ - assertEqualInt(0, - systemf("%s -cf - --b64encode f >archive.out 2>archive.err", - testprog)); - /* Check that the archive file has an uuencode signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 2); - assertEqualMem(p, "begin-base64 644", 16); - free(p); -} diff --git a/thirdparty/libarchive/tar/test/test_option_exclude.c b/thirdparty/libarchive/tar/test/test_option_exclude.c deleted file mode 100644 index 1345f70aa..000000000 --- a/thirdparty/libarchive/tar/test/test_option_exclude.c +++ /dev/null @@ -1,142 +0,0 @@ -/*- - * Copyright (c) 2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_exclude) -{ - int r; - - assertMakeFile("file1", 0644, "file1"); - assertMakeFile("file2", 0644, "file2"); - assertEqualInt(0, systemf("%s -cf archive.tar file1 file2", testprog)); - - /* - * Now, try extracting from the test archive with various --exclude options. - */ - - /* Test 1: Without --exclude */ - assertMakeDir("test1", 0755); - assertChdir("test1"); - assertEqualInt(0, - systemf("%s -xf ../archive.tar >test.out 2>test.err", testprog)); - assertFileContents("file1", 5, "file1"); - assertFileContents("file2", 5, "file2"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 2: Selecting just one file */ - assertMakeDir("test2", 0755); - assertChdir("test2"); - assertEqualInt(0, - systemf("%s -xf ../archive.tar file1 >test.out 2>test.err", testprog)); - assertFileContents("file1", 5, "file1"); - assertFileNotExists("file2"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 3: Use --exclude to skip one file */ - assertMakeDir("test3", 0755); - assertChdir("test3"); - assertEqualInt(0, - systemf("%s -xf ../archive.tar --exclude file1 >test.out 2>test.err", testprog)); - assertFileNotExists("file1"); - assertFileContents("file2", 5, "file2"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 4: Selecting one valid and one invalid file */ - assertMakeDir("test4", 0755); - assertChdir("test4"); - r = systemf("%s -xf ../archive.tar file1 file3 >test.out 2>test.err", testprog); - assert(r != 0); - assertFileContents("file1", 5, "file1"); - assertFileNotExists("file2"); - assertFileNotExists("file3"); - assertEmptyFile("test.out"); - assertNonEmptyFile("test.err"); - assertChdir(".."); - - /* Test 5: Selecting one valid file twice */ - assertMakeDir("test5", 0755); - assertChdir("test5"); - assertEqualInt(0, - systemf("%s -xf ../archive.tar file1 file1 >test.out 2>test.err", testprog)); - assertFileContents("file1", 5, "file1"); - assertFileNotExists("file2"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 6: Include and exclude the same file */ - assertMakeDir("test6", 0755); - assertChdir("test6"); - assertEqualInt(0, - systemf("%s -xf ../archive.tar --exclude file1 file1 >test.out 2>test.err", testprog)); - assertFileNotExists("file1"); - assertFileNotExists("file2"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 7: Exclude a non-existent file */ - assertMakeDir("test7", 0755); - assertChdir("test7"); - assertEqualInt(0, - systemf("%s -xf ../archive.tar --exclude file3 file1 >test.out 2>test.err", testprog)); - assertFileContents("file1", 5, "file1"); - assertFileNotExists("file2"); - assertFileNotExists("file3"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 8: Include a non-existent file */ - assertMakeDir("test8", 0755); - assertChdir("test8"); - r = systemf("%s -xf ../archive.tar file3 >test.out 2>test.err", testprog); - assert(r != 0); - assertFileNotExists("file1"); - assertFileNotExists("file2"); - assertFileNotExists("file3"); - assertEmptyFile("test.out"); - assertNonEmptyFile("test.err"); - assertChdir(".."); - - /* Test 9: Include a non-existent file plus an exclusion */ - assertMakeDir("test9", 0755); - assertChdir("test9"); - r = systemf("%s -xf ../archive.tar --exclude file1 file3 >test.out 2>test.err", testprog); - assert(r != 0); - assertFileNotExists("file1"); - assertFileNotExists("file2"); - assertFileNotExists("file3"); - assertEmptyFile("test.out"); - assertNonEmptyFile("test.err"); - assertChdir(".."); -} diff --git a/thirdparty/libarchive/tar/test/test_option_exclude_vcs.c b/thirdparty/libarchive/tar/test/test_option_exclude_vcs.c deleted file mode 100644 index 202151139..000000000 --- a/thirdparty/libarchive/tar/test/test_option_exclude_vcs.c +++ /dev/null @@ -1,230 +0,0 @@ -/*- - * Copyright (c) 2019 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_exclude_vcs) -{ - assertMakeDir("in", 0755); - assertChdir("in"); - assertMakeFile("file", 0644, ""); - assertMakeDir("dir", 0755); - assertMakeDir("CVS", 0755); - assertMakeFile("CVS/fileattr", 0644, ""); - assertMakeFile(".cvsignore", 0644, ""); - assertMakeDir("RCS", 0755); - assertMakeFile("RCS/somefile", 0655, ""); - assertMakeDir("SCCS", 0755); - assertMakeFile("SCCS/somefile", 0655, ""); - assertMakeDir(".svn", 0755); - assertMakeFile(".svn/format", 0655, ""); - assertMakeDir(".git", 0755); - assertMakeFile(".git/config", 0655, ""); - assertMakeFile(".gitignore", 0644, ""); - assertMakeFile(".gitattributes", 0644, ""); - assertMakeFile(".gitmodules", 0644, ""); - assertMakeDir(".arch-ids", 0755); - assertMakeFile(".arch-ids/somefile", 0644, ""); - assertMakeDir("{arch}", 0755); - assertMakeFile("{arch}/somefile", 0644, ""); - assertMakeFile("=RELEASE-ID", 0644, ""); - assertMakeFile("=meta-update", 0644, ""); - assertMakeFile("=update", 0644, ""); - assertMakeDir(".bzr", 0755); - assertMakeDir(".bzr/checkout", 0755); - assertMakeFile(".bzrignore", 0644, ""); - assertMakeFile(".bzrtags", 0644, ""); - assertMakeDir(".hg", 0755); - assertMakeFile(".hg/dirstate", 0644, ""); - assertMakeFile(".hgignore", 0644, ""); - assertMakeFile(".hgtags", 0644, ""); - assertMakeDir("_darcs", 0755); - assertMakeFile("_darcs/format", 0644, ""); - assertChdir(".."); - - assertEqualInt(0, systemf("%s -c -C in -f included.tar .", testprog)); - assertEqualInt(0, - systemf("%s -c --exclude-vcs -C in -f excluded.tar .", testprog)); - - /* No flags, archive with vcs files */ - assertMakeDir("vcs-noexclude", 0755); - assertEqualInt(0, systemf("%s -x -C vcs-noexclude -f included.tar", - testprog)); - assertChdir("vcs-noexclude"); - assertFileExists("file"); - assertIsDir("dir", 0755); - assertIsDir("CVS", 0755); - assertFileExists("CVS/fileattr"); - assertFileExists(".cvsignore"); - assertIsDir("RCS", 0755); - assertFileExists("RCS/somefile"); - assertIsDir("SCCS", 0755); - assertFileExists("SCCS/somefile"); - assertIsDir(".svn", 0755); - assertFileExists(".svn/format"); - assertIsDir(".git", 0755); - assertFileExists(".git/config"); - assertFileExists(".gitignore"); - assertFileExists(".gitattributes"); - assertFileExists(".gitmodules"); - assertIsDir(".arch-ids", 0755); - assertFileExists(".arch-ids/somefile"); - assertIsDir("{arch}", 0755); - assertFileExists("{arch}/somefile"); - assertFileExists("=RELEASE-ID"); - assertFileExists("=meta-update"); - assertFileExists("=update"); - assertIsDir(".bzr", 0755); - assertIsDir(".bzr/checkout", 0755); - assertFileExists(".bzrignore"); - assertFileExists(".bzrtags"); - assertIsDir(".hg", 0755); - assertFileExists(".hg/dirstate"); - assertFileExists(".hgignore"); - assertFileExists(".hgtags"); - assertIsDir("_darcs", 0755); - assertFileExists("_darcs/format"); - assertChdir(".."); - - /* --exclude-vcs, archive with vcs files */ - assertMakeDir("vcs-exclude", 0755); - assertEqualInt(0, - systemf("%s -x --exclude-vcs -C vcs-exclude -f included.tar", testprog)); - assertChdir("vcs-exclude"); - assertFileExists("file"); - assertIsDir("dir", 0755); - assertFileNotExists("CVS"); - assertFileNotExists("CVS/fileattr"); - assertFileNotExists(".cvsignore"); - assertFileNotExists("RCS"); - assertFileNotExists("RCS/somefile"); - assertFileNotExists("SCCS"); - assertFileNotExists("SCCS/somefile"); - assertFileNotExists(".svn"); - assertFileNotExists(".svn/format"); - assertFileNotExists(".git"); - assertFileNotExists(".git/config"); - assertFileNotExists(".gitignore"); - assertFileNotExists(".gitattributes"); - assertFileNotExists(".gitmodules"); - assertFileNotExists(".arch-ids"); - assertFileNotExists(".arch-ids/somefile"); - assertFileNotExists("{arch}"); - assertFileNotExists("{arch}/somefile"); - assertFileNotExists("=RELEASE-ID"); - assertFileNotExists("=meta-update"); - assertFileNotExists("=update"); - assertFileNotExists(".bzr"); - assertFileNotExists(".bzr/checkout"); - assertFileNotExists(".bzrignore"); - assertFileNotExists(".bzrtags"); - assertFileNotExists(".hg"); - assertFileNotExists(".hg/dirstate"); - assertFileNotExists(".hgignore"); - assertFileNotExists(".hgtags"); - assertFileNotExists("_darcs"); - assertFileNotExists("_darcs/format"); - assertChdir(".."); - - /* --exclude-vcs, archive without vcs files */ - assertMakeDir("novcs-exclude", 0755); - assertEqualInt(0, - systemf("%s -x --exclude-vcs -C novcs-exclude -f excluded.tar", - testprog)); - assertChdir("novcs-exclude"); - assertFileExists("file"); - assertIsDir("dir", 0755); - assertFileNotExists("CVS"); - assertFileNotExists("CVS/fileattr"); - assertFileNotExists(".cvsignore"); - assertFileNotExists("RCS"); - assertFileNotExists("RCS/somefile"); - assertFileNotExists("SCCS"); - assertFileNotExists("SCCS/somefile"); - assertFileNotExists(".svn"); - assertFileNotExists(".svn/format"); - assertFileNotExists(".git"); - assertFileNotExists(".git/config"); - assertFileNotExists(".gitignore"); - assertFileNotExists(".gitattributes"); - assertFileNotExists(".gitmodules"); - assertFileNotExists(".arch-ids"); - assertFileNotExists(".arch-ids/somefile"); - assertFileNotExists("{arch}"); - assertFileNotExists("{arch}/somefile"); - assertFileNotExists("=RELEASE-ID"); - assertFileNotExists("=meta-update"); - assertFileNotExists("=update"); - assertFileNotExists(".bzr"); - assertFileNotExists(".bzr/checkout"); - assertFileNotExists(".bzrignore"); - assertFileNotExists(".bzrtags"); - assertFileNotExists(".hg"); - assertFileNotExists(".hg/dirstate"); - assertFileNotExists(".hgignore"); - assertFileNotExists(".hgtags"); - assertFileNotExists("_darcs"); - assertFileNotExists("_darcs/format"); - assertChdir(".."); - - /* No flags, archive without vcs files */ - assertMakeDir("novcs-noexclude", 0755); - assertEqualInt(0, - systemf("%s -x -C novcs-noexclude -f excluded.tar", testprog)); - assertChdir("novcs-noexclude"); - assertFileExists("file"); - assertIsDir("dir", 0755); - assertFileNotExists("CVS"); - assertFileNotExists("CVS/fileattr"); - assertFileNotExists(".cvsignore"); - assertFileNotExists("RCS"); - assertFileNotExists("RCS/somefile"); - assertFileNotExists("SCCS"); - assertFileNotExists("SCCS/somefile"); - assertFileNotExists(".svn"); - assertFileNotExists(".svn/format"); - assertFileNotExists(".git"); - assertFileNotExists(".git/config"); - assertFileNotExists(".gitignore"); - assertFileNotExists(".gitattributes"); - assertFileNotExists(".gitmodules"); - assertFileNotExists(".arch-ids"); - assertFileNotExists(".arch-ids/somefile"); - assertFileNotExists("{arch}"); - assertFileNotExists("{arch}/somefile"); - assertFileNotExists("=RELEASE-ID"); - assertFileNotExists("=meta-update"); - assertFileNotExists("=update"); - assertFileNotExists(".bzr"); - assertFileNotExists(".bzr/checkout"); - assertFileNotExists(".bzrignore"); - assertFileNotExists(".bzrtags"); - assertFileNotExists(".hg"); - assertFileNotExists(".hg/dirstate"); - assertFileNotExists(".hgignore"); - assertFileNotExists(".hgtags"); - assertFileNotExists("_darcs"); - assertFileNotExists("_darcs/format"); -} diff --git a/thirdparty/libarchive/tar/test/test_option_fflags.c b/thirdparty/libarchive/tar/test/test_option_fflags.c deleted file mode 100644 index f223feb19..000000000 --- a/thirdparty/libarchive/tar/test/test_option_fflags.c +++ /dev/null @@ -1,110 +0,0 @@ -/*- - * Copyright (c) 2017 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__BORLANDC__) -#define chmod _chmod -#endif - -static void -clear_fflags(const char *pathname) -{ -#if defined(HAVE_STRUCT_STAT_ST_FLAGS) - chflags(pathname, 0); -#elif (defined(FS_IOC_GETFLAGS) && defined(HAVE_WORKING_FS_IOC_GETFLAGS)) || \ - (defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)) - int fd; - - fd = open(pathname, O_RDONLY | O_NONBLOCK); - if (fd < 0) - return; - ioctl(fd, -#ifdef FS_IOC_GETFLAGS - FS_IOC_GETFLAGS, -#else - EXT2_IOC_GETFLAGS, -#endif - 0); -#else - (void)pathname; /* UNUSED */ -#endif - return; -} - -DEFINE_TEST(test_option_fflags) -{ - int r; - - if (!canNodump()) { - skipping("Can't test nodump flag on this filesystem"); - return; - } - - /* Create a file. */ - assertMakeFile("f", 0644, "a"); - - /* Set nodump flag on the file */ - assertSetNodump("f"); - - /* FreeBSD ZFS workaround: ZFS sets uarch on all touched files and dirs */ - chmod("f", 0644); - - /* Archive it with fflags */ - r = systemf("%s -c --fflags -f fflags.tar f >fflags.out 2>fflags.err", testprog); - assertEqualInt(r, 0); - - /* Archive it without fflags */ - r = systemf("%s -c --no-fflags -f nofflags.tar f >nofflags.out 2>nofflags.err", testprog); - assertEqualInt(r, 0); - - /* Extract fflags with fflags */ - assertMakeDir("fflags_fflags", 0755); - clear_fflags("fflags_fflags"); - r = systemf("%s -x -C fflags_fflags --no-same-permissions --fflags -f fflags.tar >fflags_fflags.out 2>fflags_fflags.err", testprog); - assertEqualInt(r, 0); - assertEqualFflags("f", "fflags_fflags/f"); - - /* Extract fflags without fflags */ - assertMakeDir("fflags_nofflags", 0755); - clear_fflags("fflags_nofflags"); - r = systemf("%s -x -C fflags_nofflags -p --no-fflags -f fflags.tar >fflags_nofflags.out 2>fflags_nofflags.err", testprog); - assertEqualInt(r, 0); - assertUnequalFflags("f", "fflags_nofflags/f"); - - /* Extract nofflags with fflags */ - assertMakeDir("nofflags_fflags", 0755); - clear_fflags("nofflags_fflags"); - r = systemf("%s -x -C nofflags_fflags --no-same-permissions --fflags -f nofflags.tar >nofflags_fflags.out 2>nofflags_fflags.err", testprog); - assertEqualInt(r, 0); - assertUnequalFflags("f", "nofflags_fflags/f"); - - /* Extract nofflags with nofflags */ - assertMakeDir("nofflags_nofflags", 0755); - clear_fflags("nofflags_nofflags"); - r = systemf("%s -x -C nofflags_nofflags -p --no-fflags -f nofflags.tar >nofflags_nofflags.out 2>nofflags_nofflags.err", testprog); - assertEqualInt(r, 0); - assertUnequalFflags("f", "nofflags_nofflags/f"); -} diff --git a/thirdparty/libarchive/tar/test/test_option_gid_gname.c b/thirdparty/libarchive/tar/test/test_option_gid_gname.c deleted file mode 100644 index 4e5f51c8f..000000000 --- a/thirdparty/libarchive/tar/test/test_option_gid_gname.c +++ /dev/null @@ -1,92 +0,0 @@ -/*- - * Copyright (c) 2003-2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_gid_gname) -{ - char *reference, *data; - size_t s; - - assertUmask(0); - assertMakeFile("file", 0644, "1234567890"); - - /* Create archive with no special options. */ - failure("Error invoking %s c", testprog); - assertEqualInt(0, - systemf("%s cf archive1 --format=ustar file >stdout1.txt 2>stderr1.txt", - testprog)); - assertEmptyFile("stdout1.txt"); - assertEmptyFile("stderr1.txt"); - reference = slurpfile(&s, "archive1"); - - /* Again with both --gid and --gname */ - failure("Error invoking %s c", testprog); - assertEqualInt(0, - systemf("%s cf archive2 --gid=17 --gname=foofoofoo --format=ustar file >stdout2.txt 2>stderr2.txt", - testprog)); - assertEmptyFile("stdout2.txt"); - assertEmptyFile("stderr2.txt"); - data = slurpfile(&s, "archive2"); - /* Should force gid and gname fields in ustar header. */ - assertEqualMem(data + 116, "000021 \0", 8); - assertEqualMem(data + 297, "foofoofoo\0", 10); - free(data); - - /* Again with just --gname */ - failure("Error invoking %s c", testprog); - assertEqualInt(0, - systemf("%s cf archive4 --gname=foofoofoo --format=ustar file >stdout4.txt 2>stderr4.txt", - testprog)); - assertEmptyFile("stdout4.txt"); - assertEmptyFile("stderr4.txt"); - data = slurpfile(&s, "archive4"); - /* Gid should be unchanged from original reference. */ - assertEqualMem(data + 116, reference + 116, 8); - assertEqualMem(data + 297, "foofoofoo\0", 10); - free(data); - free(reference); - - /* Again with --gid and force gname to empty. */ - failure("Error invoking %s c", testprog); - assertEqualInt(0, - systemf("%s cf archive3 --gid=17 --gname= --format=ustar file >stdout3.txt 2>stderr3.txt", - testprog)); - assertEmptyFile("stdout3.txt"); - assertEmptyFile("stderr3.txt"); - data = slurpfile(&s, "archive3"); - assertEqualMem(data + 116, "000021 \0", 8); - /* Gname field in ustar header should be empty. */ - assertEqualMem(data + 297, "\0", 1); - free(data); - - /* TODO: It would be nice to verify that --gid= by itself - * will look up the associated gname and use that, but - * that requires some system-specific code. */ - - /* TODO: It would be nice to verify that --gid= will - * leave the gname field blank if the specified gid - * isn't used on the local system. */ -} diff --git a/thirdparty/libarchive/tar/test/test_option_grzip.c b/thirdparty/libarchive/tar/test/test_option_grzip.c deleted file mode 100644 index fbff25242..000000000 --- a/thirdparty/libarchive/tar/test/test_option_grzip.c +++ /dev/null @@ -1,55 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_grzip) -{ - char *p; - size_t s; - - if (!canGrzip()) { - skipping("grzip is not supported on this platform"); - return; - } - - /* Create a file. */ - assertMakeFile("f", 0644, "a"); - - /* Archive it with grzip compression. */ - assertEqualInt(0, - systemf("%s -cf - --grzip f >archive.out 2>archive.err", - testprog)); - p = slurpfile(&s, "archive.err"); - p[s] = '\0'; - free(p); - - /* Check that the archive file has an grzip signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 2); - assertEqualMem(p, "GRZipII\x00\x02\x04:)", 12); - free(p); -} diff --git a/thirdparty/libarchive/tar/test/test_option_ignore_zeros.c b/thirdparty/libarchive/tar/test/test_option_ignore_zeros.c deleted file mode 100644 index 26c9320e3..000000000 --- a/thirdparty/libarchive/tar/test/test_option_ignore_zeros.c +++ /dev/null @@ -1,147 +0,0 @@ -/*- - * Copyright (c) 2021 Ryan Libby - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -static int -make_files(void) -{ - int ret; - - assertMakeDir("in", 0755); - assertMakeDir("out", 0755); - assertMakeFile("in/a", 0644, "a"); - assertMakeFile("in/b", 0644, "b"); - assertMakeFile("in/c", 0644, "c"); - assertEqualInt(0, systemf("%s cf a.tar -C in a", testprog)); - assertEqualInt(0, systemf("%s cf b.tar -C in b", testprog)); - /* An archive formed with cat, and readable with --ignore-zeros. */ - ret = systemf("cat a.tar b.tar > ab-cat.tar"); - if (ret != 0) { - skipping("This test requires a `cat` program"); - return (ret); - } - - return (0); -} - -DEFINE_TEST(test_option_ignore_zeros_mode_t) -{ - if (make_files()) - return; - - /* Generate expected t-mode output. */ - assertEqualInt(0, systemf( - "%s cf ab-norm.tar -C in a b > norm-c.out 2> norm-c.err", - testprog)); - assertEmptyFile("norm-c.err"); - assertEmptyFile("norm-c.out"); - assertEqualInt(0, systemf( - "%s tf ab-norm.tar > norm-t.out 2> norm-t.err", - testprog)); - assertEmptyFile("norm-t.err"); - - /* Test output. */ - assertEqualInt(0, systemf( - "%s tf ab-cat.tar --ignore-zeros > test.out 2> test.err", - testprog)); - assertEmptyFile("test.err"); - - assertEqualFile("test.out", "norm-t.out"); -} - -DEFINE_TEST(test_option_ignore_zeros_mode_x) -{ - if (make_files()) - return; - - assertEqualInt(0, systemf( - "%s xf ab-cat.tar --ignore-zeros -C out > test.out 2> test.err", - testprog)); - assertEmptyFile("test.err"); - assertEmptyFile("test.out"); - - assertEqualFile("out/a", "in/a"); - assertEqualFile("out/b", "in/b"); -} - -DEFINE_TEST(test_option_ignore_zeros_mode_c) -{ - if (make_files()) - return; - - assertEqualInt(0, systemf( - "%s cf abc.tar --ignore-zeros @ab-cat.tar -C in c " - "> test-c.out 2> test-c.err", - testprog)); - assertEmptyFile("test-c.err"); - assertEmptyFile("test-c.out"); - - assertEqualInt(0, systemf( - "%s xf abc.tar -C out > test-x.out 2> test-x.err", - testprog)); - assertEmptyFile("test-x.err"); - assertEmptyFile("test-x.out"); - - assertEqualFile("out/a", "in/a"); - assertEqualFile("out/b", "in/b"); - assertEqualFile("out/c", "in/c"); -} - -static void -test_option_ignore_zeros_mode_ru(const char *mode) -{ - if (make_files()) - return; - - assertEqualInt(0, systemf( - "%s %sf ab-cat.tar --ignore-zeros -C in c " - "> test-ru.out 2> test-ru.err", - testprog, mode)); - assertEmptyFile("test-ru.err"); - assertEmptyFile("test-ru.out"); - - assertEqualInt(0, systemf( - "%s xf ab-cat.tar --ignore-zeros -C out " - "> test-x.out 2> test-x.err", - testprog)); - assertEmptyFile("test-x.err"); - assertEmptyFile("test-x.out"); - - assertEqualFile("out/a", "in/a"); - assertEqualFile("out/b", "in/b"); - assertEqualFile("out/c", "in/c"); -} - -DEFINE_TEST(test_option_ignore_zeros_mode_r) -{ - test_option_ignore_zeros_mode_ru("r"); -} - -DEFINE_TEST(test_option_ignore_zeros_mode_u) -{ - test_option_ignore_zeros_mode_ru("u"); -} diff --git a/thirdparty/libarchive/tar/test/test_option_j.c b/thirdparty/libarchive/tar/test/test_option_j.c deleted file mode 100644 index 838234a2a..000000000 --- a/thirdparty/libarchive/tar/test/test_option_j.c +++ /dev/null @@ -1,59 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_j) -{ - char *p; - int r; - size_t s; - - /* Create a file. */ - assertMakeFile("f", 0644, "a"); - - /* Archive it with bzip2 compression. */ - r = systemf("%s -jcf archive.out f 2>archive.err", testprog); - p = slurpfile(&s, "archive.err"); - p[s] = '\0'; - if (r != 0) { - if (!canBzip2()) { - skipping("bzip2 is not supported on this platform"); - goto done; - } - failure("-j option is broken"); - assertEqualInt(r, 0); - goto done; - } - free(p); - assertEmptyFile("archive.err"); - /* Check that the archive file has a bzip2 signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 2); - assertEqualMem(p, "BZh9", 4); -done: - free(p); -} diff --git a/thirdparty/libarchive/tar/test/test_option_k.c b/thirdparty/libarchive/tar/test/test_option_k.c deleted file mode 100644 index e57cc274c..000000000 --- a/thirdparty/libarchive/tar/test/test_option_k.c +++ /dev/null @@ -1,107 +0,0 @@ -/*- - * Copyright (c) 2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_k) -{ - /* - * Create an archive with a couple of different versions of the - * same file. - */ - - assertMakeFile("foo", 0644, "foo1"); - - assertEqualInt(0, systemf("%s -cf archive.tar foo", testprog)); - - assertMakeFile("foo", 0644, "foo2"); - - assertEqualInt(0, systemf("%s -rf archive.tar foo", testprog)); - - assertMakeFile("bar", 0644, "bar1"); - - assertEqualInt(0, systemf("%s -rf archive.tar bar", testprog)); - - assertMakeFile("foo", 0644, "foo3"); - - assertEqualInt(0, systemf("%s -rf archive.tar foo", testprog)); - - assertMakeFile("bar", 0644, "bar2"); - - assertEqualInt(0, systemf("%s -rf archive.tar bar", testprog)); - - /* - * Now, try extracting from the test archive with various - * combinations of -k - */ - - /* Test 1: No option */ - assertMakeDir("test1", 0755); - assertChdir("test1"); - assertEqualInt(0, - systemf("%s -xf ../archive.tar >test.out 2>test.err", testprog)); - assertFileContents("foo3", 4, "foo"); - assertFileContents("bar2", 4, "bar"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 2: With -k, we should just get the first versions. */ - assertMakeDir("test2", 0755); - assertChdir("test2"); - assertEqualInt(0, - systemf("%s -xf ../archive.tar -k >test.out 2>test.err", testprog)); - assertFileContents("foo1", 4, "foo"); - assertFileContents("bar1", 4, "bar"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 3: Without -k, existing files should get overwritten */ - assertMakeDir("test3", 0755); - assertChdir("test3"); - assertMakeFile("bar", 0644, "bar0"); - assertMakeFile("foo", 0644, "foo0"); - assertEqualInt(0, - systemf("%s -xf ../archive.tar >test.out 2>test.err", testprog)); - assertFileContents("foo3", 4, "foo"); - assertFileContents("bar2", 4, "bar"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 4: With -k, existing files should not get overwritten */ - assertMakeDir("test4", 0755); - assertChdir("test4"); - assertMakeFile("bar", 0644, "bar0"); - assertMakeFile("foo", 0644, "foo0"); - assertEqualInt(0, - systemf("%s -xf ../archive.tar -k >test.out 2>test.err", testprog)); - assertFileContents("foo0", 4, "foo"); - assertFileContents("bar0", 4, "bar"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); -} diff --git a/thirdparty/libarchive/tar/test/test_option_keep_newer_files.c b/thirdparty/libarchive/tar/test/test_option_keep_newer_files.c deleted file mode 100644 index 089898cc2..000000000 --- a/thirdparty/libarchive/tar/test/test_option_keep_newer_files.c +++ /dev/null @@ -1,56 +0,0 @@ -/*- - * Copyright (c) 2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_keep_newer_files) -{ - const char *reffile = "test_option_keep_newer_files.tar.Z"; - - /* Reference file has one entry "file" with a very old timestamp. */ - extract_reference_file(reffile); - - /* Test 1: Without --keep-newer-files */ - assertMakeDir("test1", 0755); - assertChdir("test1"); - assertMakeFile("file", 0644, "new"); - assertEqualInt(0, - systemf("%s -xf ../%s >test.out 2>test.err", testprog, reffile)); - assertFileContents("old\n", 4, "file"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 2: With --keep-newer-files */ - assertMakeDir("test2", 0755); - assertChdir("test2"); - assertMakeFile("file", 0644, "new"); - assertEqualInt(0, - systemf("%s -xf ../%s --keep-newer-files >test.out 2>test.err", testprog, reffile)); - assertFileContents("new", 3, "file"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); -} diff --git a/thirdparty/libarchive/tar/test/test_option_keep_newer_files.tar.Z.uu b/thirdparty/libarchive/tar/test/test_option_keep_newer_files.tar.Z.uu deleted file mode 100644 index 74a0f1ece..000000000 --- a/thirdparty/libarchive/tar/test/test_option_keep_newer_files.tar.Z.uu +++ /dev/null @@ -1,7 +0,0 @@ -begin 644 test_option_keep_newer_files.tar.Z -M'YV09M*P*0.@H,&#"!,J7,BPH<.'$!'"F&B#!@T0`";&N%$#!D:-'#UFG$BR -MY$48,F38F&$CY8P8)V/$F,$2``@8$7/JW,FS)X`Z<^B$D3.23IHV/AD:19I4 -M8//JWarchive.out 2>archive.err", - testprog)); - p = slurpfile(&s, "archive.err"); - p[s] = '\0'; - free(p); - /* Check that the archive file has an lzma signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 2); - assertEqualMem(p, "LRZI\x00", 5); - free(p); -} diff --git a/thirdparty/libarchive/tar/test/test_option_lz4.c b/thirdparty/libarchive/tar/test/test_option_lz4.c deleted file mode 100644 index 70fdaac36..000000000 --- a/thirdparty/libarchive/tar/test/test_option_lz4.c +++ /dev/null @@ -1,85 +0,0 @@ -/*- - * Copyright (c) 2014 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_lz4) -{ - char *p; - int r; - size_t s; - - /* Create a file. */ - assertMakeFile("f", 0644, "a"); - - /* Archive it with lz4 compression. */ - r = systemf("%s -cf - --lz4 f >archive.out 2>archive.err", - testprog); - p = slurpfile(&s, "archive.err"); - p[s] = '\0'; - if (r != 0) { - if (strstr(p, "Unsupported compression") != NULL) { - skipping("This version of bsdtar was compiled " - "without lz4 support"); - goto done; - } - /* POSIX permits different handling of the spawnp - * system call used to launch the subsidiary - * program: */ - /* Some systems fail immediately to spawn the new process. */ - if (strstr(p, "Can't launch") != NULL && !canLz4()) { - skipping("This version of bsdtar uses an external lz4 program " - "but no such program is available on this system."); - goto done; - } - /* Some systems successfully spawn the new process, - * but fail to exec a program within that process. - * This results in failure at the first attempt to - * write. */ - if (strstr(p, "Can't write") != NULL && !canLz4()) { - skipping("This version of bsdtar uses an external lz4 program " - "but no such program is available on this system."); - goto done; - } - /* On some systems the error won't be detected until closing - time, by a 127 exit error returned by waitpid. */ - if (strstr(p, "Error closing") != NULL && !canLz4()) { - skipping("This version of bsdcpio uses an external lz4 program " - "but no such program is available on this system."); - return; - } - failure("--lz4 option is broken: %s", p); - assertEqualInt(r, 0); - goto done; - } - free(p); - /* Check that the archive file has an lz4 signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 2); - assertEqualMem(p, "\x04\x22\x4d\x18", 4); - -done: - free(p); -} diff --git a/thirdparty/libarchive/tar/test/test_option_lzma.c b/thirdparty/libarchive/tar/test/test_option_lzma.c deleted file mode 100644 index ab6f13f91..000000000 --- a/thirdparty/libarchive/tar/test/test_option_lzma.c +++ /dev/null @@ -1,61 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_lzma) -{ - char *p; - int r; - size_t s; - - /* Create a file. */ - assertMakeFile("f", 0644, "a"); - - /* Archive it with lzma compression. */ - r = systemf("%s -cf - --lzma f >archive.out 2>archive.err", - testprog); - p = slurpfile(&s, "archive.err"); - p[s] = '\0'; - if (r != 0) { - if (strstr(p, "Unsupported compression") != NULL) { - skipping("This version of bsdtar was compiled " - "without lzma support"); - free(p); - return; - } - failure("--lzma option is broken"); - assertEqualInt(r, 0); - goto done; - } - free(p); - /* Check that the archive file has an lzma signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 2); - assertEqualMem(p, "\x5d\00\00", 3); -done: - free(p); -} diff --git a/thirdparty/libarchive/tar/test/test_option_lzop.c b/thirdparty/libarchive/tar/test/test_option_lzop.c deleted file mode 100644 index 20ef06c5c..000000000 --- a/thirdparty/libarchive/tar/test/test_option_lzop.c +++ /dev/null @@ -1,58 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_lzop) -{ - char *p; - int r; - size_t s; - - /* Create a file. */ - assertMakeFile("f", 0644, "a"); - - /* Archive it with lzop compression. */ - r = systemf("%s -cf - --lzop f >archive.out 2>archive.err", testprog); - p = slurpfile(&s, "archive.err"); - p[s] = '\0'; - if (r != 0) { - if (!canLzop()) { - skipping("lzop is not supported on this platform"); - goto done; - } - failure("--lzop option is broken"); - assertEqualInt(r, 0); - goto done; - } - free(p); - /* Check that the archive file has an lzma signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 2); - assertEqualMem(p, "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a", 9); -done: - free(p); -} diff --git a/thirdparty/libarchive/tar/test/test_option_n.c b/thirdparty/libarchive/tar/test/test_option_n.c deleted file mode 100644 index f36658ef1..000000000 --- a/thirdparty/libarchive/tar/test/test_option_n.c +++ /dev/null @@ -1,142 +0,0 @@ -/*- - * Copyright (c) 2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_SYS_WAIT_H -#include -#endif - -DEFINE_TEST(test_option_n) -{ - int status; - - assertMakeDir("d1", 0755); - assertMakeFile("d1/file1", 0644, "d1/file1"); - - /* Test 1: -c without -n */ - assertMakeDir("test1", 0755); - assertChdir("test1"); - assertEqualInt(0, - systemf("%s -cf archive.tar -C .. d1 >c.out 2>c.err", testprog)); - assertEmptyFile("c.out"); - assertEmptyFile("c.err"); - assertEqualInt(0, - systemf("%s -xf archive.tar >x.out 2>x.err", testprog)); - assertEmptyFile("x.out"); - assertEmptyFile("x.err"); - assertFileContents("d1/file1", 8, "d1/file1"); - assertChdir(".."); - - /* Test 2: -c with -n */ - assertMakeDir("test2", 0755); - assertChdir("test2"); - assertEqualInt(0, - systemf("%s -cnf archive.tar -C .. d1 >c.out 2>c.err", testprog)); - assertEmptyFile("c.out"); - assertEmptyFile("c.err"); - assertEqualInt(0, - systemf("%s -xf archive.tar >x.out 2>x.err", testprog)); - assertEmptyFile("x.out"); - assertEmptyFile("x.err"); - assertIsDir("d1", umasked(0755)); - assertFileNotExists("d1/file1"); - assertChdir(".."); - - /* - * Create a test archive with the following content: - * d1/ - * d1/file1 - * d1/file2 - * file3 - * d2/file4 - * - * Extracting uses the same code as listing and thus does not - * get tested separately. This also covers the - * archive_match_set_inclusion_recursion() - * API. - */ - assertMakeFile("d1/file2", 0644, "d1/file2"); - assertMakeFile("file3", 0644, "file3"); - assertMakeDir("d2", 0755); - assertMakeFile("d2/file4", 0644, "d2/file4"); - assertEqualInt(0, - systemf("%s -cnf partial-archive.tar d1 d1/file1 d1/file2 file3 " - "d2/file4 >c.out 2>c.err", testprog)); - - /* Test 3: -t without other options */ - assertEqualInt(0, - systemf("%s -tf partial-archive.tar >test3.out 2>test3.err", - testprog)); - assertEmptyFile("test3.err"); - assertTextFileContents("d1/\n" - "d1/file1\n" - "d1/file2\n" - "file3\n" - "d2/file4\n", - "test3.out"); - - /* Test 4: -t without -n and some entries selected */ - assertEqualInt(0, - systemf("%s -tf partial-archive.tar d1 file3 d2/file4 " - ">test4.out 2>test4.err", testprog)); - assertEmptyFile("test4.err"); - assertTextFileContents("d1/\n" - "d1/file1\n" - "d1/file2\n" - "file3\n" - "d2/file4\n", - "test4.out"); - - /* Test 5: -t with -n and some entries selected */ - assertEqualInt(0, - systemf("%s -tnf partial-archive.tar d1 file3 d2/file4 " - ">test5.out 2>test5.err", testprog)); - assertEmptyFile("test5.err"); - assertTextFileContents("d1/\n" - "file3\n" - "d2/file4\n", - "test5.out"); - - /* Test 6: -t without -n and non-existent directory selected */ - assertEqualInt(0, - systemf("%s -tf partial-archive.tar d2 >test6.out 2>test6.err", - testprog)); - assertEmptyFile("test6.err"); - assertTextFileContents("d2/file4\n", - "test6.out"); - - /* Test 7: -t with -n and non-existent directory selected */ - status = systemf("%s -tnf partial-archive.tar d2 " - ">test7.out 2>test7.err", testprog); - assert(status); - assert(status != -1); -#if !defined(_WIN32) || defined(__CYGWIN__) - assert(WIFEXITED(status)); - assertEqualInt(1, WEXITSTATUS(status)); -#endif - assertNonEmptyFile("test7.err"); - assertEmptyFile("test7.out"); -} diff --git a/thirdparty/libarchive/tar/test/test_option_newer_than.c b/thirdparty/libarchive/tar/test/test_option_newer_than.c deleted file mode 100644 index 2a5fe04e6..000000000 --- a/thirdparty/libarchive/tar/test/test_option_newer_than.c +++ /dev/null @@ -1,78 +0,0 @@ -/*- - * Copyright (c) 2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_newer_than) -{ - struct stat st; - - /* - * Basic test of --newer-than. - * First, create three files with different mtimes. - * Create test1.tar with --newer-than, test2.tar without. - */ - assertMakeDir("test1in", 0755); - assertChdir("test1in"); - assertMakeDir("a", 0755); - assertMakeDir("a/b", 0755); - assertMakeFile("old.txt", 0644, "old.txt"); - assertEqualInt(0, stat("old.txt", &st)); - sleepUntilAfter(st.st_mtime); - assertMakeFile("middle.txt", 0644, "middle.txt"); - assertEqualInt(0, stat("middle.txt", &st)); - sleepUntilAfter(st.st_mtime); - assertMakeFile("new.txt", 0644, "new"); - assertMakeFile("a/b/new.txt", 0644, "new file in old directory"); - - /* Test --newer-than on create */ - assertEqualInt(0, - systemf("%s --format pax -cf ../test1.tar " - "--newer-than middle.txt *.txt a", testprog)); - assertEqualInt(0, - systemf("%s --format pax -cf ../test2.tar *.txt a", testprog)); - assertChdir(".."); - - /* Extract test1.tar to a clean dir and verify what got archived. */ - assertMakeDir("test1out", 0755); - assertChdir("test1out"); - assertEqualInt(0, systemf("%s xf ../test1.tar", testprog)); - assertFileExists("new.txt"); - assertFileExists("a/b/new.txt"); - assertFileNotExists("middle.txt"); - assertFileNotExists("old.txt"); - assertChdir(".."); - - /* Extract test2.tar to a clean dir with --newer-than and verify. */ - assertMakeDir("test2out", 0755); - assertChdir("test2out"); - assertEqualInt(0, systemf("%s xf ../test2.tar --newer-than ../test1in/middle.txt", testprog)); - assertFileExists("new.txt"); - assertFileExists("a/b/new.txt"); - assertFileNotExists("middle.txt"); - assertFileNotExists("old.txt"); - assertChdir(".."); - -} diff --git a/thirdparty/libarchive/tar/test/test_option_nodump.c b/thirdparty/libarchive/tar/test/test_option_nodump.c deleted file mode 100644 index 815b08ed9..000000000 --- a/thirdparty/libarchive/tar/test/test_option_nodump.c +++ /dev/null @@ -1,68 +0,0 @@ -/*- - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_nodump) -{ - - if (!canNodump()) { - skipping("Can't test nodump on this filesystem"); - return; - } - - assertMakeFile("file1", 0644, "file1"); - assertMakeFile("file2", 0644, "file2"); - assertMakeFile("file3", 0644, "file3"); - assertSetNodump("file2"); - - /* Test 1: Without --nodump */ - assertEqualInt(0, systemf("%s -cf test1.tar file1 file2 file3", - testprog)); - assertMakeDir("test1", 0755); - assertChdir("test1"); - assertEqualInt(0, - systemf("%s -xf ../test1.tar >test.out 2>test.err", testprog)); - assertFileContents("file1", 5, "file1"); - assertFileContents("file2", 5, "file2"); - assertFileContents("file3", 5, "file3"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 2: With --nodump */ - assertEqualInt(0, systemf("%s -cf test2.tar --nodump file1 file2 file3", - testprog)); - assertMakeDir("test2", 0755); - assertChdir("test2"); - assertEqualInt(0, - systemf("%s -xf ../test2.tar >test.out 2>test.err", testprog)); - assertFileContents("file1", 5, "file1"); - assertFileNotExists("file2"); - assertFileContents("file3", 5, "file3"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); -} diff --git a/thirdparty/libarchive/tar/test/test_option_older_than.c b/thirdparty/libarchive/tar/test/test_option_older_than.c deleted file mode 100644 index 4bdd2edfe..000000000 --- a/thirdparty/libarchive/tar/test/test_option_older_than.c +++ /dev/null @@ -1,85 +0,0 @@ -/*- - * Copyright (c) 2010 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_older_than) -{ - struct stat st; - - /* - * Basic test of --older-than. - * First, create three files with different mtimes. - * Create test1.tar with --older-than, test2.tar without. - */ - assertMakeDir("test1in", 0755); - assertChdir("test1in"); - assertMakeDir("a", 0755); - assertMakeDir("a/b", 0755); - assertMakeFile("old.txt", 0644, "old.txt"); - assertMakeFile("a/b/old.txt", 0644, "old file in old directory"); - assertEqualInt(0, stat("old.txt", &st)); - sleepUntilAfter(st.st_mtime); - assertMakeFile("middle.txt", 0644, "middle.txt"); - assertEqualInt(0, stat("middle.txt", &st)); - sleepUntilAfter(st.st_mtime); - assertMakeFile("new.txt", 0644, "new"); - assertMakeFile("a/b/new.txt", 0644, "new file in old directory"); - - /* Test --older-than on create */ - assertEqualInt(0, - systemf("%s --format pax -cf ../test1.tar " - "--older-than middle.txt *.txt a", - testprog)); - assertEqualInt(0, - systemf("%s --format pax -cf ../test2.tar *.txt a", - testprog)); - assertChdir(".."); - - /* Extract test1.tar to a clean dir and verify what got archived. */ - assertMakeDir("test1out", 0755); - assertChdir("test1out"); - assertEqualInt(0, systemf("%s xf ../test1.tar", testprog)); - assertFileNotExists("new.txt"); - assertFileNotExists("a/b/new.txt"); - assertFileNotExists("middle.txt"); - assertFileExists("old.txt"); - assertFileExists("a/b/old.txt"); - assertChdir(".."); - - /* Extract test2.tar to a clean dir with --older-than and verify. */ - assertMakeDir("test2out", 0755); - assertChdir("test2out"); - assertEqualInt(0, - systemf("%s xf ../test2.tar --older-than ../test1in/middle.txt", - testprog)); - assertFileNotExists("new.txt"); - assertFileNotExists("a/b/new.txt"); - assertFileNotExists("middle.txt"); - assertFileExists("old.txt"); - assertFileExists("a/b/old.txt"); - assertChdir(".."); -} diff --git a/thirdparty/libarchive/tar/test/test_option_passphrase.c b/thirdparty/libarchive/tar/test/test_option_passphrase.c deleted file mode 100644 index 337292c95..000000000 --- a/thirdparty/libarchive/tar/test/test_option_passphrase.c +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * Copyright (c) 2014 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_passphrase) -{ - const char *reffile = "test_option_passphrase.zip"; - - extract_reference_file(reffile); - failure("--passphrase option is broken"); - assertEqualInt(0, systemf( - "%s --passphrase pass1 -xf %s >test.out 2>test.err", - testprog, reffile)); - assertFileExists("file1"); - assertTextFileContents("contents of file1.\n", "file1"); - assertFileExists("file2"); - assertTextFileContents("contents of file2.\n", "file2"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); -} diff --git a/thirdparty/libarchive/tar/test/test_option_passphrase.zip.uu b/thirdparty/libarchive/tar/test/test_option_passphrase.zip.uu deleted file mode 100644 index 021ae8585..000000000 --- a/thirdparty/libarchive/tar/test/test_option_passphrase.zip.uu +++ /dev/null @@ -1,12 +0,0 @@ -begin 644 test_option_passphrase.zip -M4$L#!`H`"0```#B91$7D$C4,'P```!,````%`!P`9FEL93%55`D``VS'+U0" -MQR]4=7@+``$$]0$```04````BHPD*"^*I04=XKI\_FQ*TE+#),TD7TTKSP/7 -MR6R35%!+!PCD$C4,'P```!,```!02P,$"@`)````09E$1;VL<`L``03U`0``!!0```!D#6Z\@CI8 -MV1GIJO5TISQF^I:7.;Y3<-G3$YOCL(C_4$L'"+VL -M`PH`"0```#B91$7D$C4,'P```!,````%`!@```````$```"D@0````!F:6QE -M,554!0`#;,`PH`"0```$&91$6]K',. -M'P```!,````%`!@```````$```"D@6X```!F:6QE,E54!0`#><test.out 2>test.err", - testprog); - failure("Fatal error trying to use -q option"); - if (!assertEqualInt(0, r)) - return; - - assertFileContents("foo1", 4, "foo"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 2: -q foo bar should extract up to the first bar. */ - assertMakeDir("test2", 0755); - assertChdir("test2"); - assertEqualInt(0, - systemf("%s -xf ../archive.tar -q foo bar >test.out 2>test.err", testprog)); - assertFileContents("foo2", 4, "foo"); - assertFileContents("bar1", 4, "bar"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 3: Same as test 2, but use --fast-read spelling. */ - assertMakeDir("test3", 0755); - assertChdir("test3"); - assertEqualInt(0, - systemf("%s -xf ../archive.tar --fast-read foo bar >test.out 2>test.err", testprog)); - assertFileContents("foo2", 4, "foo"); - assertFileContents("bar1", 4, "bar"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); - - /* Test 4: Without -q, should extract everything. */ - assertMakeDir("test4", 0755); - assertChdir("test4"); - assertEqualInt(0, - systemf("%s -xf ../archive.tar foo bar >test.out 2>test.err", testprog)); - assertFileContents("foo3", 4, "foo"); - assertFileContents("bar2", 4, "bar"); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - assertChdir(".."); -} diff --git a/thirdparty/libarchive/tar/test/test_option_r.c b/thirdparty/libarchive/tar/test/test_option_r.c deleted file mode 100644 index 287e80939..000000000 --- a/thirdparty/libarchive/tar/test/test_option_r.c +++ /dev/null @@ -1,133 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -/* - * Also see test_option_q for additional validation of -r support. - */ -DEFINE_TEST(test_option_r) -{ - char *buff; - char *p0, *p1; - size_t buff_size = 35000; - size_t s, buff_size_rounded; - int r, i; - - buff = NULL; - p0 = NULL; - p1 = NULL; - - /* Create an archive with one file. */ - assertMakeFile("f1", 0644, "abc"); - r = systemf("%s cf archive.tar --format=ustar f1 >step1.out 2>step1.err", testprog); - failure("Error invoking %s cf archive.tar f1", testprog); - assertEqualInt(r, 0); - assertEmptyFile("step1.out"); - assertEmptyFile("step1.err"); - - /* Do some basic validation of the constructed archive. */ - p0 = slurpfile(&s, "archive.tar"); - if (!assert(p0 != NULL)) - goto done; - if (!assert(s >= 2048)) - goto done; - assertEqualMem(p0 + 0, "f1", 3); - assertEqualMem(p0 + 512, "abc", 3); - assertEqualMem(p0 + 1024, "\0\0\0\0\0\0\0\0", 8); - assertEqualMem(p0 + 1536, "\0\0\0\0\0\0\0\0", 8); - - /* Edit that file with a lot more data and update the archive with a new copy. */ - buff = malloc(buff_size); - assert(buff != NULL); - if (buff == NULL) - goto done; - - for (i = 0; i < (int)buff_size; ++i) - buff[i] = "abcdefghijklmnopqrstuvwxyz"[rand() % 26]; - buff[buff_size - 1] = '\0'; - assertMakeFile("f1", 0644, buff); - r = systemf("%s rf archive.tar --format=ustar f1 >step2.out 2>step2.err", testprog); - failure("Error invoking %s rf archive.tar f1", testprog); - assertEqualInt(r, 0); - assertEmptyFile("step2.out"); - assertEmptyFile("step2.err"); - - /* The constructed archive should just have the new entry appended. */ - p1 = slurpfile(&s, "archive.tar"); - if (!assert(p1 != NULL)) - goto done; - buff_size_rounded = ((buff_size + 511) / 512) * 512; - assert(s >= 2560 + buff_size_rounded); - /* Verify first entry is unchanged. */ - assertEqualMem(p0, p1, 1024); - /* Verify that second entry is correct. */ - assertEqualMem(p1 + 1024, "f1", 3); - assertEqualMem(p1 + 1536, buff, buff_size); - /* Verify end-of-archive marker. */ - assertEqualMem(p1 + 1536 + buff_size_rounded, "\0\0\0\0\0\0\0\0", 8); - assertEqualMem(p1 + 2048 + buff_size_rounded, "\0\0\0\0\0\0\0\0", 8); - - free(p0); - p0 = p1; - - /* Update the archive by adding a different file. */ - assertMakeFile("f2", 0644, "f2"); - r = systemf("%s rf archive.tar --format=ustar f2 >step3.out 2>step3.err", testprog); - failure("Error invoking %s rf archive.tar f2", testprog); - assertEqualInt(r, 0); - assertEmptyFile("step3.out"); - assertEmptyFile("step3.err"); - - /* Validate the constructed archive. */ - p1 = slurpfile(&s, "archive.tar"); - if (!assert(p1 != NULL)) - goto done; - assert(s >= 3584 + buff_size_rounded); - /* Verify first two entries are unchanged. */ - assertEqualMem(p0, p1, 1536 + buff_size_rounded); - /* Verify that new entry is correct. */ - assertEqualMem(p1 + 1536 + buff_size_rounded, "f2", 3); - assertEqualMem(p1 + 2048 + buff_size_rounded, "f2", 3); - /* Verify end-of-archive marker. */ - assertEqualMem(p1 + 2560 + buff_size_rounded, "\0\0\0\0\0\0\0\0", 8); - assertEqualMem(p1 + 3072 + buff_size_rounded, "\0\0\0\0\0\0\0\0", 8); - free(p1); - - /* Unpack everything */ - assertMakeDir("extract", 0775); - assertChdir("extract"); - r = systemf("%s xf ../archive.tar >extract.out 2>extract.err", testprog); - failure("Error invoking %s xf archive.tar", testprog); - assertEqualInt(r, 0); - assertEmptyFile("extract.out"); - assertEmptyFile("extract.err"); - - /* Verify that the second copy of f1 overwrote the first. */ - assertFileContents(buff, (int)strlen(buff), "f1"); -done: - free(buff); - free(p0); -} diff --git a/thirdparty/libarchive/tar/test/test_option_s.c b/thirdparty/libarchive/tar/test/test_option_s.c deleted file mode 100644 index fa799a295..000000000 --- a/thirdparty/libarchive/tar/test/test_option_s.c +++ /dev/null @@ -1,278 +0,0 @@ -/*- - * Copyright (c) 2003-2008 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/test/test_option_T.c,v 1.3 2008/08/15 06:12:02 kientzle Exp $"); - -DEFINE_TEST(test_option_s) -{ - struct stat st; - - /* Create a sample file hierarchy. */ - assertMakeDir("in", 0755); - assertMakeDir("in/d1", 0755); - assertMakeFile("in/d1/foo", 0644, "foo"); - assertMakeFile("in/d1/bar", 0644, "bar"); - if (canSymlink()) { - assertMakeFile("in/d1/realfile", 0644, "realfile"); - assertMakeSymlink("in/d1/symlink", "realfile", 0); - } - assertMakeFile("in/d1/hardlink1", 0644, "hardlinkedfile"); - assertMakeHardlink("in/d1/hardlink2", "in/d1/hardlink1"); - - /* Does tar support -s option ? */ - systemf("%s -cf - -s /foo/bar/ in/d1/foo > NUL 2> check.err", - testprog); - assertEqualInt(0, stat("check.err", &st)); - if (st.st_size != 0) { - skipping("%s does not support -s option on this platform", - testprog); - return; - } - - /* - * Test 1: Filename substitution when creating archives. - */ - assertMakeDir("test1", 0755); - systemf("%s -cf test1_1.tar -s /foo/bar/ in/d1/foo", testprog); - systemf("%s -xf test1_1.tar -C test1", testprog); - assertFileContents("foo", 3, "test1/in/d1/bar"); - systemf("%s -cf test1_2.tar -s /d1/d2/ in/d1/foo", testprog); - systemf("%s -xf test1_2.tar -C test1", testprog); - assertFileContents("foo", 3, "test1/in/d2/foo"); - - /* - * Test 2: Basic substitution when extracting archive. - */ - assertMakeDir("test2", 0755); - systemf("%s -cf test2.tar in/d1/foo", testprog); - systemf("%s -xf test2.tar -s /foo/bar/ -C test2", testprog); - assertFileContents("foo", 3, "test2/in/d1/bar"); - - /* - * Test 3: Files with empty names shouldn't be archived. - */ - systemf("%s -cf test3.tar -s ,in/d1/foo,, in/d1/foo", testprog); - systemf("%s -tvf test3.tar > in.lst", testprog); - assertEmptyFile("in.lst"); - - /* - * Test 4: Multiple substitutions when extracting archive. - */ - assertMakeDir("test4", 0755); - systemf("%s -cf test4.tar in/d1/foo in/d1/bar", - testprog); - systemf("%s -xf test4.tar -s /foo/bar/ -s }bar}baz} -C test4", - testprog); - assertFileContents("foo", 3, "test4/in/d1/bar"); - assertFileContents("bar", 3, "test4/in/d1/baz"); - - /* - * Test 5: Name-switching substitutions when extracting archive. - */ - assertMakeDir("test5", 0755); - systemf("%s -cf test5.tar in/d1/foo in/d1/bar", testprog); - systemf("%s -xf test5.tar -s /foo/bar/ -s }bar}foo} -C test5", testprog); - assertFileContents("foo", 3, "test5/in/d1/bar"); - assertFileContents("bar", 3, "test5/in/d1/foo"); - - /* - * Test 6: symlinks get renamed by default - */ - if (canSymlink()) { - /* At extraction time. */ - assertMakeDir("test6a", 0755); - systemf("%s -cf - in/d1 | %s -xf - -s /d1/d2/ -C test6a", - testprog, testprog); - assertFileContents("realfile", 8, "test6a/in/d2/realfile"); - assertFileContents("realfile", 8, "test6a/in/d2/symlink"); - assertIsSymlink("test6a/in/d2/symlink", "realfile", 0); - /* At creation time. */ - assertMakeDir("test6b", 0755); - systemf("%s -cf - -s /d1/d2/ in/d1 | %s -xf - -C test6b", - testprog, testprog); - assertFileContents("realfile", 8, "test6b/in/d2/realfile"); - assertFileContents("realfile", 8, "test6b/in/d2/symlink"); - assertIsSymlink("test6b/in/d2/symlink", "realfile", 0); - } - - /* - * Test 7: selective renaming of symlink target - */ - if (canSymlink()) { - /* At extraction. */ - assertMakeDir("test7a", 0755); - systemf("%s -cf - in/d1 | %s -xf - -s /realfile/realfile-renamed/ -C test7a", - testprog, testprog); - assertFileContents("realfile", 8, "test7a/in/d1/realfile-renamed"); - assertFileContents("realfile", 8, "test7a/in/d1/symlink"); - assertIsSymlink("test7a/in/d1/symlink", "realfile-renamed", 0); - /* At creation. */ - assertMakeDir("test7b", 0755); - systemf("%s -cf - -s /realfile/realfile-renamed/ in/d1 | %s -xf - -C test7b", - testprog, testprog); - assertFileContents("realfile", 8, "test7b/in/d1/realfile-renamed"); - assertFileContents("realfile", 8, "test7b/in/d1/symlink"); - assertIsSymlink("test7b/in/d1/symlink", "realfile-renamed", 0); - } - - /* - * Test 8: hardlinks get renamed by default - */ - /* At extraction time. */ - assertMakeDir("test8a", 0755); - systemf("%s -cf test8a.tar in/d1", testprog); - systemf("%s -xf test8a.tar -s /d1/d2/ -C test8a", testprog); - assertIsHardlink("test8a/in/d2/hardlink1", "test8a/in/d2/hardlink2"); - /* At creation time. */ - assertMakeDir("test8b", 0755); - systemf("%s -cf test8b.tar -s /d1/d2/ in/d1", testprog); - systemf("%s -xf test8b.tar -C test8b", testprog); - assertIsHardlink("test8b/in/d2/hardlink1", "test8b/in/d2/hardlink2"); - - /* - * Test 9: selective renaming of hardlink target - */ - /* At extraction. (assuming hardlink2 is the hardlink entry) */ - assertMakeDir("test9a", 0755); - systemf("%s -cf test9a.tar in/d1", testprog); - systemf("%s -xf test9a.tar -s /hardlink1/hardlink1-renamed/ -C test9a", - testprog); - assertIsHardlink("test9a/in/d1/hardlink1-renamed", "test9a/in/d1/hardlink2"); - /* At extraction. (assuming hardlink1 is the hardlink entry) */ - assertMakeDir("test9b", 0755); - systemf("%s -cf test9b.tar in/d1", testprog); - systemf("%s -xf test9b.tar -s /hardlink2/hardlink2-renamed/ -C test9b", - testprog); - assertIsHardlink("test9b/in/d1/hardlink1", "test9b/in/d1/hardlink2-renamed"); - /* At creation. (assuming hardlink2 is the hardlink entry) */ - assertMakeDir("test9c", 0755); - systemf("%s -cf test9c.tar -s /hardlink1/hardlink1-renamed/ in/d1", - testprog); - systemf("%s -xf test9c.tar -C test9c", testprog); - assertIsHardlink("test9c/in/d1/hardlink1-renamed", "test9c/in/d1/hardlink2"); - /* At creation. (assuming hardlink1 is the hardlink entry) */ - assertMakeDir("test9d", 0755); - systemf("%s -cf test9d.tar -s /hardlink2/hardlink2-renamed/ in/d1", - testprog); - systemf("%s -xf test9d.tar -C test9d", testprog); - assertIsHardlink("test9d/in/d1/hardlink1", "test9d/in/d1/hardlink2-renamed"); - - /* - * Test 10: renaming symlink target without repointing symlink - */ - if (canSymlink()) { - /* At extraction. */ - assertMakeDir("test10a", 0755); - systemf("%s -cf - in/d1 | %s -xf - -s /realfile/foo/S -s /foo/realfile/ -C test10a", - testprog, testprog); - assertFileContents("realfile", 8, "test10a/in/d1/foo"); - assertFileContents("foo", 3, "test10a/in/d1/realfile"); - assertFileContents("foo", 3, "test10a/in/d1/symlink"); - assertIsSymlink("test10a/in/d1/symlink", "realfile", 0); - /* At creation. */ - assertMakeDir("test10b", 0755); - systemf("%s -cf - -s /realfile/foo/S -s /foo/realfile/ in/d1 | %s -xf - -C test10b", - testprog, testprog); - assertFileContents("realfile", 8, "test10b/in/d1/foo"); - assertFileContents("foo", 3, "test10b/in/d1/realfile"); - assertFileContents("foo", 3, "test10b/in/d1/symlink"); - assertIsSymlink("test10b/in/d1/symlink", "realfile", 0); - } - - /* - * Test 11: repointing symlink without renaming file - */ - if (canSymlink()) { - /* At extraction. */ - assertMakeDir("test11a", 0755); - systemf("%s -cf - in/d1 | %s -xf - -s /realfile/foo/sR -C test11a", - testprog, testprog); - assertFileContents("foo", 3, "test11a/in/d1/foo"); - assertFileContents("realfile", 8, "test11a/in/d1/realfile"); - assertFileContents("foo", 3, "test11a/in/d1/symlink"); - assertIsSymlink("test11a/in/d1/symlink", "foo", 0); - /* At creation. */ - assertMakeDir("test11b", 0755); - systemf("%s -cf - -s /realfile/foo/R in/d1 | %s -xf - -C test11b", - testprog, testprog); - assertFileContents("foo", 3, "test11b/in/d1/foo"); - assertFileContents("realfile", 8, "test11b/in/d1/realfile"); - assertFileContents("foo", 3, "test11b/in/d1/symlink"); - assertIsSymlink("test11b/in/d1/symlink", "foo", 0); - } - - /* - * Test 12: renaming hardlink target without changing hardlink. - * (Requires a pre-built archive, since we otherwise can't know - * which element will be stored as the hardlink.) - */ - extract_reference_file("test_option_s.tar.Z"); - assertMakeDir("test12a", 0755); - systemf("%s -xf test_option_s.tar.Z -s /hardlink1/foo/H -s /foo/hardlink1/ %s -C test12a", - testprog, canSymlink()?"":"--exclude in/d1/symlink"); - assertFileContents("foo", 3, "test12a/in/d1/hardlink1"); - assertFileContents("hardlinkedfile", 14, "test12a/in/d1/foo"); - assertFileContents("foo", 3, "test12a/in/d1/hardlink2"); - assertIsHardlink("test12a/in/d1/hardlink1", "test12a/in/d1/hardlink2"); - /* TODO: Expand this test to verify creation as well. - * Since either hardlink1 or hardlink2 might get stored as a hardlink, - * this will either requiring testing both cases and accepting either - * pass, or some very creative renames that can be tested regardless. - */ - - /* - * Test 13: repoint hardlink without changing files - * (Requires a pre-built archive, since we otherwise can't know - * which element will be stored as the hardlink.) - */ - extract_reference_file("test_option_s.tar.Z"); - assertMakeDir("test13a", 0755); - systemf("%s -xf test_option_s.tar.Z -s /hardlink1/foo/Rh -s /foo/hardlink1/Rh %s -C test13a", - testprog, canSymlink()?"":"--exclude in/d1/symlink"); - assertFileContents("foo", 3, "test13a/in/d1/foo"); - assertFileContents("hardlinkedfile", 14, "test13a/in/d1/hardlink1"); - assertFileContents("foo", 3, "test13a/in/d1/hardlink2"); - assertIsHardlink("test13a/in/d1/foo", "test13a/in/d1/hardlink2"); - /* TODO: See above; expand this test to verify renames at creation. */ - - /* - * Test 14: Global substitutions when extracting archive. - */ - /* Global substitution. */ - assertMakeDir("test14", 0755); - systemf("%s -cf test14.tar in/d1/foo in/d1/bar", - testprog); - systemf("%s -xf test14.tar -s /o/z/g -s /bar/baz/ -C test14", - testprog); - assertFileContents("foo", 3, "test14/in/d1/fzz"); - assertFileContents("bar", 3, "test14/in/d1/baz"); - /* Singular substitution. */ - systemf("%s -cf test14.tar in/d1/foo in/d1/bar", - testprog); - systemf("%s -xf test14.tar -s /o/z/ -s /bar/baz/ -C test14", - testprog); - assertFileContents("foo", 3, "test14/in/d1/fzo"); - assertFileContents("bar", 3, "test14/in/d1/baz"); -} diff --git a/thirdparty/libarchive/tar/test/test_option_s.tar.Z.uu b/thirdparty/libarchive/tar/test/test_option_s.tar.Z.uu deleted file mode 100644 index df690bfa1..000000000 --- a/thirdparty/libarchive/tar/test/test_option_s.tar.Z.uu +++ /dev/null @@ -1,16 +0,0 @@ -begin 644 test_option_s.tar.Z -M'YV0:=R\(!/C!8"#"!,J7,BPH<.'$"-*1`BCXHT:-4``J`CCAHV,&SG*H*&1 -MHTF3(&+$^%@C!HT8,&C(``%#Y0T9,P"`J#&QI\^?0(,"J#.'3A@Y(>FD:2/4 -M8=$P9LPT77@21LF3&J=JWA`0<6%'/TJ]FS"3G:H$$R9,>/5RN.C%L5 -MQHR4*S&ZA"F39HR1=G7"0$NX<$*B1I%65,KTZ].H7JO2K9C5L.7+F+>219JY -ML^?/H$.+'DVZM&G+80F^,//FS6G0:MG&]0C2Y%RW=>^J9+DWYLR:(V7($/SZ -M->*RBY>:?2RUJV3.&2#JGHUGLMMB=>.:IYYX'A3A' -M'FWPN`:?[F&T8FTB:?EBERW-"&8-=N$HPYQ16F@GGPBA.>"0:Q;9)DH*5H;I -MJ*26:NJIJ*:JZJJLMNKJJ[#&*NNLM-9JZZVXYJKKKKSVZNNOP`8K[+#$%FOL -)L<@FJ^RRS.X) -` -end diff --git a/thirdparty/libarchive/tar/test/test_option_safe_writes.c b/thirdparty/libarchive/tar/test/test_option_safe_writes.c deleted file mode 100644 index 7b42e8f62..000000000 --- a/thirdparty/libarchive/tar/test/test_option_safe_writes.c +++ /dev/null @@ -1,77 +0,0 @@ -/*- - * Copyright (c) 2020 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_safe_writes) -{ - /* Create files */ - assertMakeDir("in", 0755); - assertEqualInt(0, chdir("in")); - assertMakeFile("f", 0644, "a"); - assertMakeFile("fh", 0644, "b"); - assertMakeFile("d", 0644, "c"); - assertMakeFile("fs", 0644, "d"); - assertMakeFile("ds", 0644, "e"); - assertEqualInt(0, chdir("..")); - - /* Tar files up */ - assertEqualInt(0, - systemf("%s -c -C in -f t.tar f fh d fs ds " - ">pack.out 2>pack.err", testprog)); - - /* Verify that nothing went to stdout or stderr. */ - assertEmptyFile("pack.err"); - assertEmptyFile("pack.out"); - - /* Create various objects */ - assertMakeDir("out", 0755); - assertEqualInt(0, chdir("out")); - assertMakeFile("f", 0644, "a"); - assertMakeHardlink("fh", "f"); - assertMakeDir("d", 0755); - if (canSymlink()) { - assertMakeSymlink("fs", "f", 0); - assertMakeSymlink("ds", "d", 1); - } - assertEqualInt(0, chdir("..")); - - /* Extract created archive with safe writes */ - assertEqualInt(0, - systemf("%s -x -C out --safe-writes -f t.tar " - ">unpack.out 2>unpack.err", testprog)); - - /* Verify that nothing went to stdout or stderr. */ - assertEmptyFile("unpack.err"); - assertEmptyFile("unpack.out"); - - /* Verify that files were overwritten properly */ - assertEqualInt(0, chdir("out")); - assertTextFileContents("a","f"); - assertTextFileContents("b","fh"); - assertTextFileContents("c","d"); - assertTextFileContents("d","fs"); - assertTextFileContents("e","ds"); -} diff --git a/thirdparty/libarchive/tar/test/test_option_uid_uname.c b/thirdparty/libarchive/tar/test/test_option_uid_uname.c deleted file mode 100644 index 80c061961..000000000 --- a/thirdparty/libarchive/tar/test/test_option_uid_uname.c +++ /dev/null @@ -1,85 +0,0 @@ -/*- - * Copyright (c) 2003-2010 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_uid_uname) -{ - char *reference, *data; - size_t s; - - assertUmask(0); - assertMakeFile("file", 0644, "1234567890"); - - /* Create archive with no special options. */ - failure("Error invoking %s c", testprog); - assertEqualInt(0, - systemf("%s cf archive1 --format=ustar file >stdout1.txt 2>stderr1.txt", - testprog)); - assertEmptyFile("stdout1.txt"); - assertEmptyFile("stderr1.txt"); - reference = slurpfile(&s, "archive1"); - - /* Again with both --uid and --uname */ - failure("Error invoking %s c", testprog); - assertEqualInt(0, - systemf("%s cf archive2 --uid=65123 --uname=foofoofoo --format=ustar file >stdout2.txt 2>stderr2.txt", - testprog)); - assertEmptyFile("stdout2.txt"); - assertEmptyFile("stderr2.txt"); - data = slurpfile(&s, "archive2"); - /* Should force uid and uname fields in ustar header. */ - assertEqualMem(data + 108, "177143 \0", 8); - assertEqualMem(data + 265, "foofoofoo\0", 10); - free(data); - - /* Again with just --uid */ - failure("Error invoking %s c", testprog); - assertEqualInt(0, - systemf("%s cf archive3 --uid=65123 --format=ustar file >stdout3.txt 2>stderr3.txt", - testprog)); - assertEmptyFile("stdout3.txt"); - assertEmptyFile("stderr3.txt"); - data = slurpfile(&s, "archive3"); - assertEqualMem(data + 108, "177143 \0", 8); - /* Uname field in ustar header should be empty. */ - assertEqualMem(data + 265, "\0", 1); - free(data); - - /* Again with just --uname */ - failure("Error invoking %s c", testprog); - assertEqualInt(0, - systemf("%s cf archive4 --uname=foofoofoo --format=ustar file >stdout4.txt 2>stderr4.txt", - testprog)); - assertEmptyFile("stdout4.txt"); - assertEmptyFile("stderr4.txt"); - data = slurpfile(&s, "archive4"); - /* Uid should be unchanged from original reference. */ - assertEqualMem(data + 108, reference + 108, 8); - assertEqualMem(data + 265, "foofoofoo\0", 10); - free(data); - - free(reference); -} diff --git a/thirdparty/libarchive/tar/test/test_option_uuencode.c b/thirdparty/libarchive/tar/test/test_option_uuencode.c deleted file mode 100644 index a28a8e340..000000000 --- a/thirdparty/libarchive/tar/test/test_option_uuencode.c +++ /dev/null @@ -1,56 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_uuencode) -{ - char *p; - size_t s; - - /* Create a file. */ - assertMakeFile("f", 0644, "a"); - - /* Archive it with compress compression and uuencode. */ - assertEqualInt(0, - systemf("%s -cf - -Z --uuencode f >archive.out 2>archive.err", - testprog)); - /* Check that the archive file has an uuencode signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 2); - assertEqualMem(p, "begin 644", 9); - free(p); - - /* Archive it with uuencode only. */ - assertEqualInt(0, - systemf("%s -cf - --uuencode f >archive.out 2>archive.err", - testprog)); - /* Check that the archive file has an uuencode signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 2); - assertEqualMem(p, "begin 644", 9); - free(p); -} diff --git a/thirdparty/libarchive/tar/test/test_option_xattrs.c b/thirdparty/libarchive/tar/test/test_option_xattrs.c deleted file mode 100644 index 79dfff528..000000000 --- a/thirdparty/libarchive/tar/test/test_option_xattrs.c +++ /dev/null @@ -1,88 +0,0 @@ -/*- - * Copyright (c) 2017 Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_xattrs) -{ -#if !ARCHIVE_XATTR_SUPPORT - skipping("Extended attributes are not supported on this platform"); -#else /* ARCHIVE_XATTR_SUPPORT */ - - const char *testattr = "user.libarchive.test"; - const char *testval = "testval"; - void *readval; - size_t size; - int r; - - /* Create a file. */ - assertMakeFile("f", 0644, "a"); - - if (!setXattr("f", "user.libarchive.test", testval, - strlen(testval) + 1)) { - skipping("Can't set user extended attributes on this " - "filesystem"); - return; - } - - /* Archive with xattrs */ - r = systemf("%s -c --no-mac-metadata --xattrs -f xattrs.tar f >xattrs.out 2>xattrs.err", testprog); - assertEqualInt(r, 0); - - /* Archive without xattrs */ - r = systemf("%s -c --no-mac-metadata --no-xattrs -f noxattrs.tar f >noxattrs.out 2>noxattrs.err", testprog); - assertEqualInt(r, 0); - - /* Extract xattrs with xattrs */ - assertMakeDir("xattrs_xattrs", 0755); - r = systemf("%s -x -C xattrs_xattrs --no-same-permissions --xattrs -f xattrs.tar >xattrs_xattrs.out 2>xattrs_xattrs.err", testprog); - assertEqualInt(r, 0); - readval = getXattr("xattrs_xattrs/f", testattr, &size); - if(assertEqualInt(size, strlen(testval) + 1) != 0) - assertEqualMem(readval, testval, size); - free(readval); - - /* Extract xattrs without xattrs */ - assertMakeDir("xattrs_noxattrs", 0755); - r = systemf("%s -x -C xattrs_noxattrs -p --no-xattrs -f xattrs.tar >xattrs_noxattrs.out 2>xattrs_noxattrs.err", testprog); - assertEqualInt(r, 0); - readval = getXattr("xattrs_noxattrs/f", testattr, &size); - assert(readval == NULL); - - /* Extract noxattrs with xattrs */ - assertMakeDir("noxattrs_xattrs", 0755); - r = systemf("%s -x -C noxattrs_xattrs --no-same-permissions --xattrs -f noxattrs.tar >noxattrs_xattrs.out 2>noxattrs_xattrs.err", testprog); - assertEqualInt(r, 0); - readval = getXattr("noxattrs_xattrs/f", testattr, &size); - assert(readval == NULL); - - /* Extract noxattrs with noxattrs */ - assertMakeDir("noxattrs_noxattrs", 0755); - r = systemf("%s -x -C noxattrs_noxattrs -p --no-xattrs -f noxattrs.tar >noxattrs_noxattrs.out 2>noxattrs_noxattrs.err", testprog); - assertEqualInt(r, 0); - readval = getXattr("noxattrs_noxattrs/f", testattr, &size); - assert(readval == NULL); -#endif /* ARCHIVE_XATTR_SUPPORT */ -} diff --git a/thirdparty/libarchive/tar/test/test_option_xz.c b/thirdparty/libarchive/tar/test/test_option_xz.c deleted file mode 100644 index 91da0730a..000000000 --- a/thirdparty/libarchive/tar/test/test_option_xz.c +++ /dev/null @@ -1,60 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_xz) -{ - char *p; - int r; - size_t s; - - /* Create a file. */ - assertMakeFile("f", 0644, "a"); - - /* Archive it with xz compression. */ - r = systemf("%s -cf - --xz f >archive.out 2>archive.err", - testprog); - p = slurpfile(&s, "archive.err"); - p[s] = '\0'; - if (r != 0) { - if (strstr(p, "Unsupported compression") != NULL) { - skipping("This version of bsdtar was compiled " - "without xz support"); - goto done; - } - failure("--xz option is broken"); - assertEqualInt(r, 0); - goto done; - } - free(p); - /* Check that the archive file has an xz signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 2); - assertEqualMem(p, "\xFD\x37\x7A\x58\x5A\x00", 6); -done: - free(p); -} diff --git a/thirdparty/libarchive/tar/test/test_option_z.c b/thirdparty/libarchive/tar/test/test_option_z.c deleted file mode 100644 index 59744999f..000000000 --- a/thirdparty/libarchive/tar/test/test_option_z.c +++ /dev/null @@ -1,58 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_z) -{ - char *p; - int r; - size_t s; - - /* Create a file. */ - assertMakeFile("f", 0644, "a"); - - /* Archive it with gzip compression. */ - r = systemf("%s -zcf archive.out f 2>archive.err", testprog); - p = slurpfile(&s, "archive.err"); - p[s] = '\0'; - if (r != 0) { - if (!canGzip()) { - skipping("gzip is not supported on this platform"); - goto done; - } - failure("-z option is broken"); - assertEqualInt(r, 0); - goto done; - } - free(p); - /* Check that the archive file has a gzip signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 4); - assertEqualMem(p, "\x1f\x8b\x08\x00", 4); -done: - free(p); -} diff --git a/thirdparty/libarchive/tar/test/test_option_zstd.c b/thirdparty/libarchive/tar/test/test_option_zstd.c deleted file mode 100644 index 73965e33f..000000000 --- a/thirdparty/libarchive/tar/test/test_option_zstd.c +++ /dev/null @@ -1,85 +0,0 @@ -/*- - * Copyright (c) 2017 Sean Purcell - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD$"); - -DEFINE_TEST(test_option_zstd) -{ - char *p; - int r; - size_t s; - - /* Create a file. */ - assertMakeFile("f", 0644, "a"); - - /* Archive it with lz4 compression. */ - r = systemf("%s -cf - --zstd f >archive.out 2>archive.err", - testprog); - p = slurpfile(&s, "archive.err"); - p[s] = '\0'; - if (r != 0) { - if (strstr(p, "Unsupported compression") != NULL) { - skipping("This version of bsdtar was compiled " - "without zstd support"); - goto done; - } - /* POSIX permits different handling of the spawnp - * system call used to launch the subsidiary - * program: */ - /* Some systems fail immediately to spawn the new process. */ - if (strstr(p, "Can't launch") != NULL && !canZstd()) { - skipping("This version of bsdtar uses an external zstd program " - "but no such program is available on this system."); - goto done; - } - /* Some systems successfully spawn the new process, - * but fail to exec a program within that process. - * This results in failure at the first attempt to - * write. */ - if (strstr(p, "Can't write") != NULL && !canZstd()) { - skipping("This version of bsdtar uses an external zstd program " - "but no such program is available on this system."); - goto done; - } - /* On some systems the error won't be detected until closing - time, by a 127 exit error returned by waitpid. */ - if (strstr(p, "Error closing") != NULL && !canZstd()) { - skipping("This version of bsdcpio uses an external zstd program " - "but no such program is available on this system."); - return; - } - failure("--zstd option is broken: %s", p); - assertEqualInt(r, 0); - goto done; - } - free(p); - /* Check that the archive file has an lz4 signature. */ - p = slurpfile(&s, "archive.out"); - assert(s > 2); - assertEqualMem(p, "\x28\xb5\x2f\xfd", 4); - -done: - free(p); -} diff --git a/thirdparty/libarchive/tar/test/test_patterns.c b/thirdparty/libarchive/tar/test/test_patterns.c deleted file mode 100644 index e1449008b..000000000 --- a/thirdparty/libarchive/tar/test/test_patterns.c +++ /dev/null @@ -1,190 +0,0 @@ -/*- - * Copyright (c) 2009 Michihiro NAKAJIMA - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/test/test_patterns.c,v 1.6 2008/08/21 22:28:00 kientzle Exp $"); - -DEFINE_TEST(test_patterns) -{ - FILE *f; - int r; - const char *reffile2 = "test_patterns_2.tar"; - const char *reffile3 = "test_patterns_3.tar"; - const char *reffile4 = "test_patterns_4.tar"; - - const char *tar2aExpected[] = { - "/tmp/foo/bar/", - "/tmp/foo/bar/baz", - NULL - }; - - /* - * Test basic command-line pattern handling. - */ - - /* - * Test 1: Files on the command line that don't get matched - * didn't produce an error. - * - * John Baldwin reported this problem in PR bin/121598 - */ - f = fopen("foo", "w"); - assert(f != NULL); - fclose(f); - r = systemf("%s cfv tar1.tgz foo > tar1a.out 2> tar1a.err", testprog); - assertEqualInt(r, 0); - r = systemf("%s xv --no-same-owner -f tar1.tgz foo bar > tar1b.out 2> tar1b.err", testprog); - failure("tar should return non-zero because a file was given on the command line that's not in the archive"); - assert(r != 0); - - /* - * Test 2: Check basic matching of full paths that start with / - */ - extract_reference_file(reffile2); - - r = systemf("%s tf %s /tmp/foo/bar > tar2a.out 2> tar2a.err", - testprog, reffile2); - assertEqualInt(r, 0); - assertFileContainsLinesAnyOrder("tar2a.out", tar2aExpected); - assertEmptyFile("tar2a.err"); - - /* - * Test 3 archive has some entries starting with '/' and some not. - */ - extract_reference_file(reffile3); - - /* Test 3a: Pattern tmp/foo/bar should not match /tmp/foo/bar */ - r = systemf("%s x --no-same-owner -f %s tmp/foo/bar > tar3a.out 2> tar3a.err", - testprog, reffile3); - assert(r != 0); - assertEmptyFile("tar3a.out"); - - /* Test 3b: Pattern /tmp/foo/baz should not match tmp/foo/baz */ - assertNonEmptyFile("tar3a.err"); - /* Again, with the '/' */ - r = systemf("%s x --no-same-owner -f %s /tmp/foo/baz > tar3b.out 2> tar3b.err", - testprog, reffile3); - assert(r != 0); - assertEmptyFile("tar3b.out"); - assertNonEmptyFile("tar3b.err"); - - /* Test 3c: ./tmp/foo/bar should not match /tmp/foo/bar */ - r = systemf("%s x --no-same-owner -f %s ./tmp/foo/bar > tar3c.out 2> tar3c.err", - testprog, reffile3); - assert(r != 0); - assertEmptyFile("tar3c.out"); - assertNonEmptyFile("tar3c.err"); - - /* Test 3d: ./tmp/foo/baz should match tmp/foo/baz */ - r = systemf("%s x --no-same-owner -f %s ./tmp/foo/baz > tar3d.out 2> tar3d.err", - testprog, reffile3); - assertEqualInt(r, 0); - assertEmptyFile("tar3d.out"); - assertEmptyFile("tar3d.err"); - assertFileExists("tmp/foo/baz/bar"); - - /* - * Test 4 archive has some entries starting with windows drive letters - * such as 'c:\', '//./c:/' or '//?/c:/'. - */ - extract_reference_file(reffile4); - - r = systemf("%s x --no-same-owner -f %s -C tmp > tar4.out 2> tar4.err", - testprog, reffile4); - assert(r != 0); - assertEmptyFile("tar4.out"); - assertNonEmptyFile("tar4.err"); - - for (r = 1; r <= 54; r++) { - char file_a[] = "tmp/fileXX"; - char file_b1[] = "tmp/server/share/fileXX"; - char file_b2[] = "tmp/server\\share\\fileXX"; - char file_c[] = "tmp/../fileXX"; - char file_d[] = "tmp/../../fileXX"; - char *filex; - int xsize; - - switch (r) { - case 15: case 18: - /* - * Including server and share names. - * //?/UNC/server/share/file15 - * //?/unc/server/share/file18 - */ - filex = file_b1; - xsize = sizeof(file_b1); - break; - case 35: case 38: case 52: - /* - * Including server and share names. - * \\?\UNC\server\share\file35 - * \\?\unc\server\share\file38 - * \/?/uNc/server\share\file52 - */ - filex = file_b2; - xsize = sizeof(file_b2); - break; - default: - filex = file_a; - xsize = sizeof(file_a); - break; - } - filex[xsize-3] = '0' + r / 10; - filex[xsize-2] = '0' + r % 10; - switch (r) { - case 5: case 6: case 17: case 20: case 25: - case 26: case 37: case 40: case 43: case 54: - /* - * Not extracted patterns. - * D:../file05 - * c:../../file06 - * //?/UNC/../file17 - * //?/unc/../file20 - * z:..\file25 - * c:..\..\file26 - * \\?\UNC\..\file37 - * \\?\unc\..\file40 - * c:../..\file43 - * \/?\UnC\../file54 - */ - assertFileNotExists(filex); - if (r == 6 || r == 26 || r == 43) { - filex = file_d; - xsize = sizeof(file_d); - } else { - filex = file_c; - xsize = sizeof(file_c); - } - filex[xsize-3] = '0' + r / 10; - filex[xsize-2] = '0' + r % 10; - assertFileNotExists(filex); - break; - default: - /* Extracted patterns. */ - assertFileExists(filex); - break; - } - } -} diff --git a/thirdparty/libarchive/tar/test/test_patterns_2.tar.uu b/thirdparty/libarchive/tar/test/test_patterns_2.tar.uu deleted file mode 100644 index eba2daece..000000000 --- a/thirdparty/libarchive/tar/test/test_patterns_2.tar.uu +++ /dev/null @@ -1,231 +0,0 @@ -begin 644 test_patterns_2.tar -M+W1M<"]F;V\O```````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````#`P,#@`````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````P -M,#`V-#0@`#`P,3@`````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````#`P,#8T-"``,#`Q-S4P(``P,#`P,#`@`#`P,#`P -M,#`P,#`P(#$Q,#4Q,C$R-C4S(#`Q,S8V-P`@,``````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````````````!UCHN+EQF:6QE,C4````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````#`P,#8T-"``,#`Q-S4Q(``P,#$W-3$@`#`P,#`P,#`P -M,#`P(#$Q,34P-Ctest.out 2>test.err", testprog, reffile)); - assertTextFileContents(buff, "test.out"); - assertEmptyFile("test.err"); -} diff --git a/thirdparty/libarchive/tar/test/test_print_longpath.tar.Z.uu b/thirdparty/libarchive/tar/test/test_print_longpath.tar.Z.uu deleted file mode 100644 index 05658ffcc..000000000 --- a/thirdparty/libarchive/tar/test/test_print_longpath.tar.Z.uu +++ /dev/null @@ -1,24 +0,0 @@ -begin 644 test_print_longpath.tar.Z -M'YV04,+@05(F#)DR,H/*E$$31(P8$6_0"$H4 -M!`R+-&@``($'IM6K6+-JWO8+O6F4,GC!R<8^J4"//JWC.^&$H8.FA\N6)DF*!(DR,6*6C2&O9#Q9Y6++ASN^4"`# -M!H@Q=-*T*=,CQ@P9-638\%B#L^?!HDF;1JV:M8(9.$`P22(DB)0A2))8*>)B -MC)R"H=^X"3VZ].G4-B;FP*'`K_7KV+-KW\Z]N_?O5S-75BS^,GG'D2F;?ZR^ -M?.87.&'0M(G39XV=]7_&EQO4*-(;2C%U@U,RH`;15#6`IZ!V8Y5UEDQN:1=A -M=OS1U=^"&&:H85@!#53000FYA]YX[&$VXGKIF2@9BC`%-1]0]N'7DW[\R125 -M#/XEM91,-3DU`T0TS#!551L6"5>#9J&EEH1+4BB7A7/%=**(*U+9WI185IFE -M>D;Z)0-#(`A&F&%;JGBEEFB>J::9;"JF4)GGI=EFB7&N6>>;;KSY!IQPQ!F'7!K*\>D<;:M55%V7G';J:896XDEB -MBG>62N>II$8$GXL]YGKW=U2)!!"+TI)[/2PHEJMY"U.%.K,[[JJHPUVB!? -MC@#N&$-J/@(I%574^AJLDF\5VR1VR/;KK;/1!KSLMP*?6"];,Y@6YF"%#0RP -MP^#:27!YVDK\\+\1BUKPBA5K#/'&%F?,;0Z;=;9G;)<>"L-T@UIJZ)\RY'!; -M;KOU]EMPPQ5W'&R5HOQRIC%O>O#07WUL-,8@>XS>JN/25RZZ,4)9(:WM]@0O -MKC3=T"O17=X+X;[7&6M=OT]*N>W$2!]]-L!<>V7MA]FJ'7+2(SLLKGSDYF3N -MTU+/!(,-[`:X4)#QVA#5D&T;Z?6P8%LGME]DUV7VW'(KO;;((27.%0TQT+#P -MF)77G?;HEY,<.MJEGPYPQZ*G3CKE2+...NRNUSYWR9Z!YK.?F>800\N[8TJ1 -M[T(3K3KF%]N.)]-X.ZTWU+'*ZAG5@G<^@X^YUJ`U"`EJKN'BC_<5/E^17W@\ -:W;-;/K?W[+?O_OOPQR___/37;__]^.>OOU<` -` -end diff --git a/thirdparty/libarchive/tar/test/test_stdio.c b/thirdparty/libarchive/tar/test/test_stdio.c deleted file mode 100644 index d6650a5eb..000000000 --- a/thirdparty/libarchive/tar/test/test_stdio.c +++ /dev/null @@ -1,126 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/test/test_stdio.c,v 1.2 2008/05/26 17:10:10 kientzle Exp $"); - -DEFINE_TEST(test_stdio) -{ - FILE *filelist; - char *p; - size_t s; - int r; - - assertUmask(0); - - /* - * Create a couple of files on disk. - */ - /* File */ - assertMakeFile("f", 0755, "abc"); - /* Link to above file. */ - assertMakeHardlink("l", "f"); - - /* Create file list (text mode here) */ - filelist = fopen("filelist", "w"); - assert(filelist != NULL); - fprintf(filelist, "f\n"); - fprintf(filelist, "l\n"); - fclose(filelist); - - /* - * Archive/dearchive with a variety of options, verifying - * stdio paths. - */ - - /* 'cf' should generate no output unless there's an error. */ - r = systemf("%s cf archive f l >cf.out 2>cf.err", testprog); - assertEqualInt(r, 0); - assertEmptyFile("cf.out"); - assertEmptyFile("cf.err"); - - /* 'cvf' should generate file list on stderr, empty stdout. */ - r = systemf("%s cvf archive f l >cvf.out 2>cvf.err", testprog); - assertEqualInt(r, 0); - failure("'cv' writes filenames to stderr, nothing to stdout (SUSv2)\n" - "Note that GNU tar writes the file list to stdout by default."); - assertEmptyFile("cvf.out"); - /* TODO: Verify cvf.err has file list in SUSv2-prescribed format. */ - - /* 'cvf -' should generate file list on stderr, archive on stdout. */ - r = systemf("%s cvf - f l >cvf-.out 2>cvf-.err", testprog); - assertEqualInt(r, 0); - failure("cvf - should write archive to stdout"); - /* TODO: Verify cvf-.out has archive. */ - failure("cvf - should write file list to stderr (SUSv2)"); - /* TODO: Verify cvf-.err has verbose file list. */ - - /* 'tf' should generate file list on stdout, empty stderr. */ - r = systemf("%s tf archive >tf.out 2>tf.err", testprog); - assertEqualInt(r, 0); - assertEmptyFile("tf.err"); - failure("'t' mode should write results to stdout"); - /* TODO: Verify tf.out has file list. */ - - /* 'tvf' should generate file list on stdout, empty stderr. */ - r = systemf("%s tvf archive >tvf.out 2>tvf.err", testprog); - assertEqualInt(r, 0); - assertEmptyFile("tvf.err"); - failure("'tv' mode should write results to stdout"); - /* TODO: Verify tvf.out has file list. */ - - /* 'tvf -' uses stdin, file list on stdout, empty stderr. */ - r = systemf("%s tvf - < archive >tvf-.out 2>tvf-.err", testprog); - assertEqualInt(r, 0); - assertEmptyFile("tvf-.err"); - /* TODO: Verify tvf-.out has file list. */ - - /* Basic 'xf' should generate no output on stdout or stderr. */ - r = systemf("%s xf archive >xf.out 2>xf.err", testprog); - assertEqualInt(r, 0); - assertEmptyFile("xf.err"); - assertEmptyFile("xf.out"); - - /* 'xvf' should generate list on stderr, empty stdout. */ - r = systemf("%s xvf archive >xvf.out 2>xvf.err", testprog); - assertEqualInt(r, 0); - assertEmptyFile("xvf.out"); - /* TODO: Verify xvf.err */ - - /* 'xvOf' should generate list on stderr, file contents on stdout. */ - r = systemf("%s xvOf archive >xvOf.out 2>xvOf.err", testprog); - assertEqualInt(r, 0); - /* Verify xvOf.out is the file contents */ - p = slurpfile(&s, "xvOf.out"); - assertEqualInt((int)s, 3); - assertEqualMem(p, "abc", 3); - /* TODO: Verify xvf.err */ - free(p); - - /* 'xvf -' should generate list on stderr, empty stdout. */ - r = systemf("%s xvf - < archive >xvf-.out 2>xvf-.err", testprog); - assertEqualInt(r, 0); - assertEmptyFile("xvf-.out"); - /* TODO: Verify xvf-.err */ -} diff --git a/thirdparty/libarchive/tar/test/test_strip_components.c b/thirdparty/libarchive/tar/test/test_strip_components.c deleted file mode 100644 index 090fb0dbf..000000000 --- a/thirdparty/libarchive/tar/test/test_strip_components.c +++ /dev/null @@ -1,140 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/test/test_strip_components.c,v 1.2 2008/11/10 05:24:13 kientzle Exp $"); - -DEFINE_TEST(test_strip_components) -{ - assertMakeDir("d0", 0755); - assertChdir("d0"); - assertMakeDir("d1", 0755); - assertMakeDir("d1/d2", 0755); - assertMakeDir("d1/d2/d3", 0755); - assertMakeFile("d1/d2/f1", 0644, ""); - assertMakeHardlink("l1", "d1/d2/f1"); - assertMakeHardlink("d1/l2", "d1/d2/f1"); - if (canSymlink()) { - assertMakeSymlink("s1", "d1/d2/f1", 0); - assertMakeSymlink("d1/s2", "d2/f1", 0); - } - assertChdir(".."); - - /* - * Test 1: Strip components when extracting archives. - */ - if (canSymlink()) - assertEqualInt(0, systemf("%s -cf test.tar d0/l1 d0/s1 d0/d1", - testprog)); - else - assertEqualInt(0, systemf("%s -cf test.tar d0/l1 d0/d1", - testprog)); - - assertMakeDir("target", 0755); - assertEqualInt(0, systemf("%s -x -C target --strip-components 2 " - "-f test.tar", testprog)); - - failure("d0/ is too short and should not get restored"); - assertFileNotExists("target/d0"); - failure("d0/d1/ is too short and should not get restored"); - assertFileNotExists("target/d1"); - failure("d0/s1 is too short and should not get restored"); - assertFileNotExists("target/s1"); - failure("d0/d1/s2 is a symlink to something that won't be extracted"); - /* If platform supports symlinks, target/s2 is a broken symlink. */ - /* If platform does not support symlink, target/s2 doesn't exist. */ - if (canSymlink()) - assertIsSymlink("target/s2", "d2/f1", 0); - else - assertFileNotExists("target/s2"); - failure("d0/d1/d2 should be extracted"); - assertIsDir("target/d2", -1); - - /* - * Test 1b: Strip components extracting archives involving hardlinks. - * - * This next is a complicated case. d0/l1, d0/d1/l2, and - * d0/d1/d2/f1 are all hardlinks to the same file; d0/l1 can't - * be extracted with --strip-components=2 and the other two - * can. Remember that tar normally stores the first file with - * a body and the other as hardlink entries to the first - * appearance. So the final result depends on the order in - * which these three names get archived. If d0/l1 is first, - * none of the three can be restored. If either of the longer - * names are first, then the two longer ones can both be - * restored. Note that the "tar -cf" command above explicitly - * lists d0/l1 before d0/d1. - * - * It may be worth extending this test to exercise other - * archiving orders. - * - * Of course, this is all totally different for cpio and newc - * formats because the hardlink management is different. - * TODO: Rename this to test_strip_components_tar and create - * parallel tests for cpio and newc formats. - */ - failure("d0/l1 is too short and should not get restored"); - assertFileNotExists("target/l1"); - failure("d0/d1/l2 is a hardlink to file whose name was too short"); - assertFileNotExists("target/l2"); - failure("d0/d1/d2/f1 is a hardlink to file whose name was too short"); - assertFileNotExists("target/d2/f1"); - - /* - * Test 2: Strip components when creating archives. - */ - if (canSymlink()) - assertEqualInt(0, systemf("%s --strip-components 2 -cf test2.tar " - "d0/l1 d0/s1 d0/d1", testprog)); - else - assertEqualInt(0, systemf("%s --strip-components 2 -cf test2.tar " - "d0/l1 d0/d1", testprog)); - - assertMakeDir("target2", 0755); - assertEqualInt(0, systemf("%s -x -C target2 -f test2.tar", testprog)); - - failure("d0/ is too short and should not have been archived"); - assertFileNotExists("target2/d0"); - failure("d0/d1/ is too short and should not have been archived"); - assertFileNotExists("target2/d1"); - failure("d0/s1 is too short and should not get restored"); - assertFileNotExists("target/s1"); - /* If platform supports symlinks, target/s2 is included. */ - if (canSymlink()) { - failure("d0/d1/s2 is a symlink to something included in archive"); - assertIsSymlink("target2/s2", "d2/f1", 0); - } - failure("d0/d1/d2 should be archived"); - assertIsDir("target2/d2", -1); - - /* - * Test 2b: Strip components creating archives involving hardlinks. - */ - failure("d0/l1 is too short and should not have been archived"); - assertFileNotExists("target/l1"); - failure("d0/d1/l2 is a hardlink to file whose name was too short"); - assertFileNotExists("target/l2"); - failure("d0/d1/d2/f1 is a hardlink to file whose name was too short"); - assertFileNotExists("target/d2/f1"); -} diff --git a/thirdparty/libarchive/tar/test/test_symlink_dir.c b/thirdparty/libarchive/tar/test/test_symlink_dir.c deleted file mode 100644 index 5836647c1..000000000 --- a/thirdparty/libarchive/tar/test/test_symlink_dir.c +++ /dev/null @@ -1,160 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/test/test_symlink_dir.c,v 1.1 2008/09/14 02:16:04 kientzle Exp $"); - -/* - * tar -x -P should follow existing symlinks for dirs, but not other - * content. Plain tar -x should remove symlinks when they're in the - * way of a dir extraction. - */ - -DEFINE_TEST(test_symlink_dir) -{ - assertUmask(0); - - assertMakeDir("source", 0755); - assertMakeFile("source/file", 0755, "a"); - assertMakeFile("source/file2", 0755, "ab"); - assertMakeDir("source/dir", 0755); - assertMakeDir("source/dir/d", 0755); - assertMakeFile("source/dir/f", 0755, "abc"); - assertMakeDir("source/dir2", 0755); - assertMakeDir("source/dir2/d2", 0755); - assertMakeFile("source/dir2/f2", 0755, "abcd"); - assertMakeDir("source/dir3", 0755); - assertMakeDir("source/dir3/d3", 0755); - assertMakeFile("source/dir3/f3", 0755, "abcde"); - assertMakeDir("source/dir4", 0755); - assertMakeFile("source/dir4/file3", 0755, "abcdef"); - assertMakeHardlink("source/dir4/file4", "source/dir4/file3"); - - assertEqualInt(0, - systemf("%s -cf test.tar -C source dir dir2 dir3 file file2", - testprog)); - - /* Second archive with hardlinks */ - assertEqualInt(0, - systemf("%s -cf test2.tar -C source dir4", testprog)); - - /* - * Extract with -x and without -P. - */ - assertMakeDir("dest1", 0755); - /* "dir" is a symlink to an existing "dest1/real_dir" */ - assertMakeDir("dest1/real_dir", 0755); - if (canSymlink()) { - assertMakeSymlink("dest1/dir", "real_dir", 1); - /* "dir2" is a symlink to a non-existing "real_dir2" */ - assertMakeSymlink("dest1/dir2", "real_dir2", 1); - } else { - skipping("Symlinks are not supported on this platform"); - } - /* "dir3" is a symlink to an existing "non_dir3" */ - assertMakeFile("dest1/non_dir3", 0755, "abcdef"); - if (canSymlink()) - assertMakeSymlink("dest1/dir3", "non_dir3", 1); - /* "file" is a symlink to existing "real_file" */ - assertMakeFile("dest1/real_file", 0755, "abcdefg"); - if (canSymlink()) { - assertMakeSymlink("dest1/file", "real_file", 0); - /* "file2" is a symlink to non-existing "real_file2" */ - assertMakeSymlink("dest1/file2", "real_file2", 0); - } - assertEqualInt(0, systemf("%s -xf test.tar -C dest1", testprog)); - - /* dest1/dir symlink should be replaced */ - failure("symlink to dir was followed when it shouldn't be"); - assertIsDir("dest1/dir", -1); - /* dest1/dir2 symlink should be replaced */ - failure("Broken symlink wasn't replaced with dir"); - assertIsDir("dest1/dir2", -1); - /* dest1/dir3 symlink should be replaced */ - failure("Symlink to non-dir wasn't replaced with dir"); - assertIsDir("dest1/dir3", -1); - /* dest1/file symlink should be replaced */ - failure("Symlink to existing file should be replaced"); - assertIsReg("dest1/file", -1); - /* dest1/file2 symlink should be replaced */ - failure("Symlink to non-existing file should be replaced"); - assertIsReg("dest1/file2", -1); - - /* - * Extract with both -x and -P - */ - assertMakeDir("dest2", 0755); - /* "dir" is a symlink to existing "real_dir" */ - assertMakeDir("dest2/real_dir", 0755); - if (canSymlink()) - assertMakeSymlink("dest2/dir", "real_dir", 1); - /* "dir2" is a symlink to a non-existing "real_dir2" */ - if (canSymlink()) - assertMakeSymlink("dest2/dir2", "real_dir2", 1); - /* "dir3" is a symlink to an existing "non_dir3" */ - assertMakeFile("dest2/non_dir3", 0755, "abcdefgh"); - if (canSymlink()) - assertMakeSymlink("dest2/dir3", "non_dir3", 1); - /* "file" is a symlink to existing "real_file" */ - assertMakeFile("dest2/real_file", 0755, "abcdefghi"); - if (canSymlink()) - assertMakeSymlink("dest2/file", "real_file", 0); - /* "file2" is a symlink to non-existing "real_file2" */ - if (canSymlink()) - assertMakeSymlink("dest2/file2", "real_file2", 0); - assertEqualInt(0, systemf("%s -xPf test.tar -C dest2", testprog)); - - /* "dir4" is a symlink to existing "real_dir" */ - if (canSymlink()) - assertMakeSymlink("dest2/dir4", "real_dir", 1); - assertEqualInt(0, systemf("%s -xPf test2.tar -C dest2", testprog)); - - /* dest2/dir and dest2/dir4 symlinks should be followed */ - if (canSymlink()) { - assertIsSymlink("dest2/dir", "real_dir", 1); - assertIsSymlink("dest2/dir4", "real_dir", 1); - assertIsDir("dest2/real_dir", -1); - } - - /* Contents of 'dir' should be restored */ - assertIsDir("dest2/dir/d", -1); - assertIsReg("dest2/dir/f", -1); - assertFileSize("dest2/dir/f", 3); - /* dest2/dir2 symlink should be removed */ - failure("Broken symlink wasn't replaced with dir"); - assertIsDir("dest2/dir2", -1); - /* dest2/dir3 symlink should be removed */ - failure("Symlink to non-dir wasn't replaced with dir"); - assertIsDir("dest2/dir3", -1); - /* dest2/file symlink should be removed; - * even -P shouldn't follow symlinks for files */ - failure("Symlink to existing file should be removed"); - assertIsReg("dest2/file", -1); - /* dest2/file2 symlink should be removed */ - failure("Symlink to non-existing file should be removed"); - assertIsReg("dest2/file2", -1); - - /* dest2/dir4/file3 and dest2/dir4/file4 should be hard links */ - assertIsHardlink("dest2/dir4/file3", "dest2/dir4/file4"); -} diff --git a/thirdparty/libarchive/tar/test/test_version.c b/thirdparty/libarchive/tar/test/test_version.c deleted file mode 100644 index 1b896c0c4..000000000 --- a/thirdparty/libarchive/tar/test/test_version.c +++ /dev/null @@ -1,34 +0,0 @@ -/*- - * Copyright (c) 2003-2017 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -/* - * Test that --version option works and generates reasonable output. - */ - -DEFINE_TEST(test_version) -{ - assertVersion(testprog, "bsdtar"); -} diff --git a/thirdparty/libarchive/tar/test/test_windows.c b/thirdparty/libarchive/tar/test/test_windows.c deleted file mode 100644 index d619667bf..000000000 --- a/thirdparty/libarchive/tar/test/test_windows.c +++ /dev/null @@ -1,324 +0,0 @@ -/*- - * Copyright (c) 2009 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -#if defined(_WIN32) && !defined(__CYGWIN__) -#include -#include - -static void -mkfile(const char *name) -{ - FILE *f; - - f = fopen(name, "wb"); - assert(f != NULL); - assertEqualInt(5, fwrite("01234", 1, 5, f)); - fclose(f); -} - -static void -mkfullpath(char **path1, char **path2, const char *tpath, int type) -{ - char *fp1 = NULL, *fp2 = NULL, *p1 = NULL, *p2 = NULL; - size_t l; - - /* - * Get full path name of "tpath" - */ - l = GetFullPathNameA(tpath, 0, NULL, NULL); - assert(0 != l); - fp1 = malloc(l); - assert(NULL != fp1); - fp2 = malloc(l*2); - assert(NULL != fp2); - l = GetFullPathNameA(tpath, (DWORD)l, fp1, NULL); - if ((type & 0x01) == 0) { - for (p1 = fp1; *p1 != '\0'; p1++) - if (*p1 == '\\') - *p1 = '/'; - } - - switch(type) { - case 0: /* start with "/" */ - case 1: /* start with "\" */ - /* strip "c:" */ - memmove(fp1, fp1 + 2, l - 2); - fp1[l -2] = '\0'; - p1 = fp1 + 1; - break; - case 2: /* start with "c:/" */ - case 3: /* start with "c:\" */ - p1 = fp1 + 3; - break; - case 4: /* start with "//./c:/" */ - case 5: /* start with "\\.\c:\" */ - case 6: /* start with "//?/c:/" */ - case 7: /* start with "\\?\c:\" */ - p1 = malloc(l + 4 + 1); - assert(NULL != p1); - if (type & 0x1) - memcpy(p1, "\\\\.\\", 4); - else - memcpy(p1, "//./", 4); - if (type == 6 || type == 7) - p1[2] = '?'; - memcpy(p1 + 4, fp1, l); - p1[l + 4] = '\0'; - free(fp1); - fp1 = p1; - p1 = fp1 + 7; - break; - } - - /* - * Strip leading drive names and converting "\" to "\\" - */ - p2 = fp2; - while (*p1 != '\0') { - if (*p1 == '\\') - *p2 = '/'; - else - *p2 = *p1; - ++p1; - ++p2; - } - *p2++ = '\r'; - *p2++ = '\n'; - *p2 = '\0'; - - *path1 = fp1; - *path2 = fp2; -} - -static const char *list1[] = {"aaa/", "aaa/file1", "aaa/xxa/", "aaa/xxb/", - "aaa/zzc/", "aaa/zzc/file1", "aaa/xxb/file1", "aaa/xxa/file1", - "aab/", "aac/", "abb/", "abc/", "abd/", NULL}; -static const char *list2[] = {"bbb/", "bbb/file1", "bbb/xxa/", "bbb/xxb/", - "bbb/zzc/", "bbb/zzc/file1", "bbb/xxb/file1", "bbb/xxa/file1", "bbc/", - "bbd/", "bcc/", "bcd/", "bce/", NULL}; -static const char *list3[] = {"aac/", "abc/", "bbc/", "bcc/", "ccc/", NULL}; -static const char *list4[] = {"fff/abca", "fff/acca", NULL}; -static const char *list5[] = {"aaa/file1", "aaa/xxa/", "aaa/xxa/file1", - "aaa/xxb/", "aaa/xxb/file1", "aaa/zzc/", "aaa/zzc/file1", NULL}; -static const char *list6[] = {"fff/abca", "fff/acca", "aaa/xxa/", - "aaa/xxa/file1", "aaa/xxb/", "aaa/xxb/file1", NULL}; -#endif /* _WIN32 && !__CYGWIN__ */ - -DEFINE_TEST(test_windows) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - char *fp1, *fp2; - - /* - * Prepare tests. - * Create directories and files. - */ - assertMakeDir("tmp", 0775); - assertChdir("tmp"); - - assertMakeDir("aaa", 0775); - assertMakeDir("aaa/xxa", 0775); - assertMakeDir("aaa/xxb", 0775); - assertMakeDir("aaa/zzc", 0775); - mkfile("aaa/file1"); - mkfile("aaa/xxa/file1"); - mkfile("aaa/xxb/file1"); - mkfile("aaa/zzc/file1"); - assertMakeDir("aab", 0775); - assertMakeDir("aac", 0775); - assertMakeDir("abb", 0775); - assertMakeDir("abc", 0775); - assertMakeDir("abd", 0775); - assertMakeDir("bbb", 0775); - assertMakeDir("bbb/xxa", 0775); - assertMakeDir("bbb/xxb", 0775); - assertMakeDir("bbb/zzc", 0775); - mkfile("bbb/file1"); - mkfile("bbb/xxa/file1"); - mkfile("bbb/xxb/file1"); - mkfile("bbb/zzc/file1"); - assertMakeDir("bbc", 0775); - assertMakeDir("bbd", 0775); - assertMakeDir("bcc", 0775); - assertMakeDir("bcd", 0775); - assertEqualInt(0, _mkdir("bce")); - assertEqualInt(0, _mkdir("ccc")); - assertEqualInt(0, _mkdir("fff")); - mkfile("fff/aaaa"); - mkfile("fff/abba"); - mkfile("fff/abca"); - mkfile("fff/acba"); - mkfile("fff/acca"); - - /* - * Test1: Command line pattern matching. - */ - assertEqualInt(0, - systemf("%s -cf ../archive1.tar a*", testprog)); - assertEqualInt(0, - systemf("%s -tf ../archive1.tar > ../list1", testprog)); - assertFileContainsLinesAnyOrder("../list1", list1); - - assertEqualInt(0, - systemf("%s -cf ../archive2.tar b*", testprog)); - assertEqualInt(0, - systemf("%s -tf ../archive2.tar > ../list2", testprog)); - assertFileContainsLinesAnyOrder("../list2", list2); - - assertEqualInt(0, - systemf("%s -cf ../archive3.tar ??c", testprog)); - assertEqualInt(0, - systemf("%s -tf ../archive3.tar > ../list3", testprog)); - assertFileContainsLinesAnyOrder("../list3", list3); - - assertEqualInt(0, - systemf("%s -cf ../archive3b.tar *c", testprog)); - assertEqualInt(0, - systemf("%s -tf ../archive3b.tar > ../list3b", testprog)); - assertFileContainsLinesAnyOrder("../list3b", list3); - - assertEqualInt(0, - systemf("%s -cf ../archive4.tar fff/a?ca", testprog)); - assertEqualInt(0, - systemf("%s -tf ../archive4.tar > ../list4", testprog)); - assertFileContainsLinesAnyOrder("../list4", list4); - - assertEqualInt(0, - systemf("%s -cf ../archive5.tar aaa\\*", testprog)); - assertEqualInt(0, - systemf("%s -tf ../archive5.tar > ../list5", testprog)); - assertFileContainsLinesAnyOrder("../list5", list5); - - assertEqualInt(0, - systemf("%s -cf ../archive6.tar fff\\a?ca aaa\\xx*", testprog)); - assertEqualInt(0, - systemf("%s -tf ../archive6.tar > ../list6", testprog)); - assertFileContainsLinesAnyOrder("../list6", list6); - - /* - * Test2: Archive the file start with drive letters. - */ - /* Test2a: start with "/" */ - mkfullpath(&fp1, &fp2, "aaa/file1", 0); - assertEqualInt(0, - systemf("%s -cf ../archive10.tar %s > ../out10 2> ../err10", - testprog, fp1)); - assertEqualInt(0, - systemf("%s -tf ../archive10.tar > ../list10", testprog)); - /* Check drive letters have been stripped. */ - assertFileContents(fp2, (int)strlen(fp2), "../list10"); - free(fp1); - free(fp2); - - /* Test2b: start with "\" */ - mkfullpath(&fp1, &fp2, "aaa/file1", 1); - assertEqualInt(0, - systemf("%s -cf ../archive11.tar %s > ../out11 2> ../err11", - testprog, fp1)); - assertEqualInt(0, - systemf("%s -tf ../archive11.tar > ../list11", testprog)); - /* Check drive letters have been stripped. */ - assertFileContents(fp2, (int)strlen(fp2), "../list11"); - free(fp1); - free(fp2); - - /* Test2c: start with "c:/" */ - mkfullpath(&fp1, &fp2, "aaa/file1", 2); - assertEqualInt(0, - systemf("%s -cf ../archive12.tar %s > ../out12 2> ../err12", - testprog, fp1)); - assertEqualInt(0, - systemf("%s -tf ../archive12.tar > ../list12", testprog)); - /* Check drive letters have been stripped. */ - assertFileContents(fp2, (int)strlen(fp2), "../list12"); - free(fp1); - free(fp2); - - /* Test2d: start with "c:\" */ - mkfullpath(&fp1, &fp2, "aaa/file1", 3); - assertEqualInt(0, - systemf("%s -cf ../archive13.tar %s > ../out13 2> ../err13", - testprog, fp1)); - assertEqualInt(0, - systemf("%s -tf ../archive13.tar > ../list13", testprog)); - /* Check drive letters have been stripped. */ - assertFileContents(fp2, (int)strlen(fp2), "../list13"); - free(fp1); - free(fp2); - - /* Test2e: start with "//./c:/" */ - mkfullpath(&fp1, &fp2, "aaa/file1", 4); - assertEqualInt(0, - systemf("%s -cf ../archive14.tar %s > ../out14 2> ../err14", - testprog, fp1)); - assertEqualInt(0, - systemf("%s -tf ../archive14.tar > ../list14", testprog)); - /* Check drive letters have been stripped. */ - assertFileContents(fp2, (int)strlen(fp2), "../list14"); - free(fp1); - free(fp2); - - /* Test2f: start with "\\.\c:\" */ - mkfullpath(&fp1, &fp2, "aaa/file1", 5); - assertEqualInt(0, - systemf("%s -cf ../archive15.tar %s > ../out15 2> ../err15", - testprog, fp1)); - assertEqualInt(0, - systemf("%s -tf ../archive15.tar > ../list15", testprog)); - /* Check drive letters have been stripped. */ - assertFileContents(fp2, (int)strlen(fp2), "../list15"); - free(fp1); - free(fp2); - - /* Test2g: start with "//?/c:/" */ - mkfullpath(&fp1, &fp2, "aaa/file1", 6); - failure("fp1=%s, fp2=%s", fp1, fp2); - assertEqualInt(0, - systemf("%s -cf ../archive16.tar %s > ../out16 2> ../err16", - testprog, fp1)); - assertEqualInt(0, - systemf("%s -tf ../archive16.tar > ../list16", testprog)); - /* Check drive letters have been stripped. */ - assertFileContents(fp2, (int)strlen(fp2), "../list16"); - free(fp1); - free(fp2); - - /* Test2h: start with "\\?\c:\" */ - mkfullpath(&fp1, &fp2, "aaa/file1", 7); - failure("fp1=%s, fp2=%s", fp1, fp2); - assertEqualInt(0, - systemf("%s -cf ../archive17.tar %s > ../out17 2> ../err17", - testprog, fp1)); - assertEqualInt(0, - systemf("%s -tf ../archive17.tar > ../list17", testprog)); - /* Check drive letters have been stripped. */ - assertFileContents(fp2, (int)strlen(fp2), "../list17"); - free(fp1); - free(fp2); -#else - skipping("Windows specific test"); -#endif /* _WIN32 && !__CYGWIN__ */ -} diff --git a/thirdparty/libarchive/tar/util.c b/thirdparty/libarchive/tar/util.c deleted file mode 100644 index 403d7ff35..000000000 --- a/thirdparty/libarchive/tar/util.c +++ /dev/null @@ -1,762 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "bsdtar_platform.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/util.c,v 1.23 2008/12/15 06:00:25 kientzle Exp $"); - -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_SYS_TYPES_H -#include /* Linux doesn't define mode_t, etc. in sys/stat.h. */ -#endif -#include -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_IO_H -#include -#endif -#ifdef HAVE_STDARG_H -#include -#endif -#ifdef HAVE_STDINT_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_WCTYPE_H -#include -#else -/* If we don't have wctype, we need to hack up some version of iswprint(). */ -#define iswprint isprint -#endif - -#include "bsdtar.h" -#include "err.h" -#include "passphrase.h" - -static size_t bsdtar_expand_char(char *, size_t, size_t, char); -static const char *strip_components(const char *path, int elements); - -#if defined(_WIN32) && !defined(__CYGWIN__) -#define read _read -#endif - -/* TODO: Hack up a version of mbtowc for platforms with no wide - * character support at all. I think the following might suffice, - * but it needs careful testing. - * #if !HAVE_MBTOWC - * #define mbtowc(wcp, p, n) ((*wcp = *p), 1) - * #endif - */ - -/* - * Print a string, taking care with any non-printable characters. - * - * Note that we use a stack-allocated buffer to receive the formatted - * string if we can. This is partly performance (avoiding a call to - * malloc()), partly out of expedience (we have to call vsnprintf() - * before malloc() anyway to find out how big a buffer we need; we may - * as well point that first call at a small local buffer in case it - * works), but mostly for safety (so we can use this to print messages - * about out-of-memory conditions). - */ - -void -safe_fprintf(FILE *f, const char *fmt, ...) -{ - char fmtbuff_stack[256]; /* Place to format the printf() string. */ - char outbuff[256]; /* Buffer for outgoing characters. */ - char *fmtbuff_heap; /* If fmtbuff_stack is too small, we use malloc */ - char *fmtbuff; /* Pointer to fmtbuff_stack or fmtbuff_heap. */ - int fmtbuff_length; - int length, n; - va_list ap; - const char *p; - unsigned i; - wchar_t wc; - char try_wc; - - /* Use a stack-allocated buffer if we can, for speed and safety. */ - fmtbuff_heap = NULL; - fmtbuff_length = sizeof(fmtbuff_stack); - fmtbuff = fmtbuff_stack; - - /* Try formatting into the stack buffer. */ - va_start(ap, fmt); - length = vsnprintf(fmtbuff, fmtbuff_length, fmt, ap); - va_end(ap); - - /* If the result was too large, allocate a buffer on the heap. */ - while (length < 0 || length >= fmtbuff_length) { - if (length >= fmtbuff_length) - fmtbuff_length = length+1; - else if (fmtbuff_length < 8192) - fmtbuff_length *= 2; - else if (fmtbuff_length < 1000000) - fmtbuff_length += fmtbuff_length / 4; - else { - length = fmtbuff_length; - fmtbuff_heap[length-1] = '\0'; - break; - } - free(fmtbuff_heap); - fmtbuff_heap = malloc(fmtbuff_length); - - /* Reformat the result into the heap buffer if we can. */ - if (fmtbuff_heap != NULL) { - fmtbuff = fmtbuff_heap; - va_start(ap, fmt); - length = vsnprintf(fmtbuff, fmtbuff_length, fmt, ap); - va_end(ap); - } else { - /* Leave fmtbuff pointing to the truncated - * string in fmtbuff_stack. */ - fmtbuff = fmtbuff_stack; - length = sizeof(fmtbuff_stack) - 1; - break; - } - } - - /* Note: mbrtowc() has a cleaner API, but mbtowc() seems a bit - * more portable, so we use that here instead. */ - if (mbtowc(NULL, NULL, 1) == -1) { /* Reset the shift state. */ - /* mbtowc() should never fail in practice, but - * handle the theoretical error anyway. */ - free(fmtbuff_heap); - return; - } - - /* Write data, expanding unprintable characters. */ - p = fmtbuff; - i = 0; - try_wc = 1; - while (*p != '\0') { - - /* Convert to wide char, test if the wide - * char is printable in the current locale. */ - if (try_wc && (n = mbtowc(&wc, p, length)) != -1) { - length -= n; - if (iswprint(wc) && wc != L'\\') { - /* Printable, copy the bytes through. */ - while (n-- > 0) - outbuff[i++] = *p++; - } else { - /* Not printable, format the bytes. */ - while (n-- > 0) - i += (unsigned)bsdtar_expand_char( - outbuff, sizeof(outbuff), i, *p++); - } - } else { - /* After any conversion failure, don't bother - * trying to convert the rest. */ - i += (unsigned)bsdtar_expand_char(outbuff, sizeof(outbuff), i, *p++); - try_wc = 0; - } - - /* If our output buffer is full, dump it and keep going. */ - if (i > (sizeof(outbuff) - 128)) { - outbuff[i] = '\0'; - fprintf(f, "%s", outbuff); - i = 0; - } - } - outbuff[i] = '\0'; - fprintf(f, "%s", outbuff); - - /* If we allocated a heap-based formatting buffer, free it now. */ - free(fmtbuff_heap); -} - -/* - * Render an arbitrary sequence of bytes into printable ASCII characters. - */ -static size_t -bsdtar_expand_char(char *buff, size_t buffsize, size_t offset, char c) -{ - size_t i = offset; - - if (isprint((unsigned char)c) && c != '\\') - buff[i++] = c; - else { - buff[i++] = '\\'; - switch (c) { - case '\a': buff[i++] = 'a'; break; - case '\b': buff[i++] = 'b'; break; - case '\f': buff[i++] = 'f'; break; - case '\n': buff[i++] = 'n'; break; -#if '\r' != '\n' - /* On some platforms, \n and \r are the same. */ - case '\r': buff[i++] = 'r'; break; -#endif - case '\t': buff[i++] = 't'; break; - case '\v': buff[i++] = 'v'; break; - case '\\': buff[i++] = '\\'; break; - default: - snprintf(buff + i, buffsize - i, "%03o", 0xFF & (int)c); - i += 3; - } - } - - return (i - offset); -} - -int -yes(const char *fmt, ...) -{ - char buff[32]; - char *p; - ssize_t l; - - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - fprintf(stderr, " (y/N)? "); - fflush(stderr); - - l = read(2, buff, sizeof(buff) - 1); - if (l < 0) { - fprintf(stderr, "Keyboard read failed\n"); - exit(1); - } - if (l == 0) - return (0); - buff[l] = 0; - - for (p = buff; *p != '\0'; p++) { - if (isspace((unsigned char)*p)) - continue; - switch(*p) { - case 'y': case 'Y': - return (1); - case 'n': case 'N': - return (0); - default: - return (0); - } - } - - return (0); -} - -/*- - * The logic here for -C attempts to avoid - * chdir() as long as possible. For example: - * "-C /foo -C /bar file" needs chdir("/bar") but not chdir("/foo") - * "-C /foo -C bar file" needs chdir("/foo/bar") - * "-C /foo -C bar /file1" does not need chdir() - * "-C /foo -C bar /file1 file2" needs chdir("/foo/bar") before file2 - * - * The only correct way to handle this is to record a "pending" chdir - * request and combine multiple requests intelligently until we - * need to process a non-absolute file. set_chdir() adds the new dir - * to the pending list; do_chdir() actually executes any pending chdir. - * - * This way, programs that build tar command lines don't have to worry - * about -C with non-existent directories; such requests will only - * fail if the directory must be accessed. - * - */ -void -set_chdir(struct bsdtar *bsdtar, const char *newdir) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - if (newdir[0] == '/' || newdir[0] == '\\' || - /* Detect this type, for example, "C:\" or "C:/" */ - (((newdir[0] >= 'a' && newdir[0] <= 'z') || - (newdir[0] >= 'A' && newdir[0] <= 'Z')) && - newdir[1] == ':' && (newdir[2] == '/' || newdir[2] == '\\'))) { -#else - if (newdir[0] == '/') { -#endif - /* The -C /foo -C /bar case; dump first one. */ - free(bsdtar->pending_chdir); - bsdtar->pending_chdir = NULL; - } - if (bsdtar->pending_chdir == NULL) - /* Easy case: no previously-saved dir. */ - bsdtar->pending_chdir = strdup(newdir); - else { - /* The -C /foo -C bar case; concatenate */ - char *old_pending = bsdtar->pending_chdir; - size_t old_len = strlen(old_pending); - size_t new_len = old_len + strlen(newdir) + 2; - bsdtar->pending_chdir = malloc(new_len); - if (old_pending[old_len - 1] == '/') - old_pending[old_len - 1] = '\0'; - if (bsdtar->pending_chdir != NULL) - snprintf(bsdtar->pending_chdir, new_len, "%s/%s", - old_pending, newdir); - free(old_pending); - } - if (bsdtar->pending_chdir == NULL) - lafe_errc(1, errno, "No memory"); -} - -void -do_chdir(struct bsdtar *bsdtar) -{ - if (bsdtar->pending_chdir == NULL) - return; - - if (chdir(bsdtar->pending_chdir) != 0) { - lafe_errc(1, 0, "could not chdir to '%s'\n", - bsdtar->pending_chdir); - } - free(bsdtar->pending_chdir); - bsdtar->pending_chdir = NULL; -} - -static const char * -strip_components(const char *p, int elements) -{ - /* Skip as many elements as necessary. */ - while (elements > 0) { - switch (*p++) { - case '/': -#if defined(_WIN32) && !defined(__CYGWIN__) - case '\\': /* Support \ path sep on Windows ONLY. */ -#endif - elements--; - break; - case '\0': - /* Path is too short, skip it. */ - return (NULL); - } - } - - /* Skip any / characters. This handles short paths that have - * additional / termination. This also handles the case where - * the logic above stops in the middle of a duplicate // - * sequence (which would otherwise get converted to an - * absolute path). */ - for (;;) { - switch (*p) { - case '/': -#if defined(_WIN32) && !defined(__CYGWIN__) - case '\\': /* Support \ path sep on Windows ONLY. */ -#endif - ++p; - break; - case '\0': - return (NULL); - default: - return (p); - } - } -} - -static void -warn_strip_leading_char(struct bsdtar *bsdtar, const char *c) -{ - if (!bsdtar->warned_lead_slash) { - lafe_warnc(0, - "Removing leading '%c' from member names", - c[0]); - bsdtar->warned_lead_slash = 1; - } -} - -static void -warn_strip_drive_letter(struct bsdtar *bsdtar) -{ - if (!bsdtar->warned_lead_slash) { - lafe_warnc(0, - "Removing leading drive letter from " - "member names"); - bsdtar->warned_lead_slash = 1; - } -} - -/* - * Convert absolute path to non-absolute path by skipping leading - * absolute path prefixes. - */ -static const char* -strip_absolute_path(struct bsdtar *bsdtar, const char *p) -{ - const char *rp; - - /* Remove leading "//./" or "//?/" or "//?/UNC/" - * (absolute path prefixes used by Windows API) */ - if ((p[0] == '/' || p[0] == '\\') && - (p[1] == '/' || p[1] == '\\') && - (p[2] == '.' || p[2] == '?') && - (p[3] == '/' || p[3] == '\\')) - { - if (p[2] == '?' && - (p[4] == 'U' || p[4] == 'u') && - (p[5] == 'N' || p[5] == 'n') && - (p[6] == 'C' || p[6] == 'c') && - (p[7] == '/' || p[7] == '\\')) - p += 8; - else - p += 4; - warn_strip_drive_letter(bsdtar); - } - - /* Remove multiple leading slashes and Windows drive letters. */ - do { - rp = p; - if (((p[0] >= 'a' && p[0] <= 'z') || - (p[0] >= 'A' && p[0] <= 'Z')) && - p[1] == ':') { - p += 2; - warn_strip_drive_letter(bsdtar); - } - - /* Remove leading "/../", "/./", "//", etc. */ - while (p[0] == '/' || p[0] == '\\') { - if (p[1] == '.' && - p[2] == '.' && - (p[3] == '/' || p[3] == '\\')) { - p += 3; /* Remove "/..", leave "/" for next pass. */ - } else if (p[1] == '.' && - (p[2] == '/' || p[2] == '\\')) { - p += 2; /* Remove "/.", leave "/" for next pass. */ - } else - p += 1; /* Remove "/". */ - warn_strip_leading_char(bsdtar, rp); - } - } while (rp != p); - - return (p); -} - -/* - * Handle --strip-components and any future path-rewriting options. - * Returns non-zero if the pathname should not be extracted. - * - * Note: The rewrites are applied uniformly to pathnames and hardlink - * names but not to symlink bodies. This is deliberate: Symlink - * bodies are not necessarily filenames. Even when they are, they - * need to be interpreted relative to the directory containing them, - * so simple rewrites like this are rarely appropriate. - * - * TODO: Support pax-style regex path rewrites. - */ -int -edit_pathname(struct bsdtar *bsdtar, struct archive_entry *entry) -{ - const char *name = archive_entry_pathname(entry); - const char *original_name = name; - const char *hardlinkname = archive_entry_hardlink(entry); - const char *original_hardlinkname = hardlinkname; -#if defined(HAVE_REGEX_H) || defined(HAVE_PCREPOSIX_H) - char *subst_name; - int r; - - /* Apply user-specified substitution to pathname. */ - r = apply_substitution(bsdtar, name, &subst_name, 0, 0); - if (r == -1) { - lafe_warnc(0, "Invalid substitution, skipping entry"); - return 1; - } - if (r == 1) { - archive_entry_copy_pathname(entry, subst_name); - if (*subst_name == '\0') { - free(subst_name); - return -1; - } else - free(subst_name); - name = archive_entry_pathname(entry); - original_name = name; - } - - /* Apply user-specified substitution to hardlink target. */ - if (hardlinkname != NULL) { - r = apply_substitution(bsdtar, hardlinkname, &subst_name, 0, 1); - if (r == -1) { - lafe_warnc(0, "Invalid substitution, skipping entry"); - return 1; - } - if (r == 1) { - archive_entry_copy_hardlink(entry, subst_name); - free(subst_name); - } - hardlinkname = archive_entry_hardlink(entry); - original_hardlinkname = hardlinkname; - } - - /* Apply user-specified substitution to symlink body. */ - if (archive_entry_symlink(entry) != NULL) { - r = apply_substitution(bsdtar, archive_entry_symlink(entry), &subst_name, 1, 0); - if (r == -1) { - lafe_warnc(0, "Invalid substitution, skipping entry"); - return 1; - } - if (r == 1) { - archive_entry_copy_symlink(entry, subst_name); - free(subst_name); - } - } -#endif - - /* Strip leading dir names as per --strip-components option. */ - if (bsdtar->strip_components > 0) { - name = strip_components(name, bsdtar->strip_components); - if (name == NULL) - return (1); - - if (hardlinkname != NULL) { - hardlinkname = strip_components(hardlinkname, - bsdtar->strip_components); - if (hardlinkname == NULL) - return (1); - } - } - - if ((bsdtar->flags & OPTFLAG_ABSOLUTE_PATHS) == 0) { - /* By default, don't write or restore absolute pathnames. */ - name = strip_absolute_path(bsdtar, name); - if (*name == '\0') - name = "."; - - if (hardlinkname != NULL) { - hardlinkname = strip_absolute_path(bsdtar, hardlinkname); - if (*hardlinkname == '\0') - return (1); - } - } else { - /* Strip redundant leading '/' characters. */ - while (name[0] == '/' && name[1] == '/') - name++; - } - - /* Replace name in archive_entry. */ - if (name != original_name) { - archive_entry_copy_pathname(entry, name); - } - if (hardlinkname != original_hardlinkname) { - archive_entry_copy_hardlink(entry, hardlinkname); - } - return (0); -} - -/* - * It would be nice to just use printf() for formatting large numbers, - * but the compatibility problems are quite a headache. Hence the - * following simple utility function. - */ -const char * -tar_i64toa(int64_t n0) -{ - static char buff[24]; - uint64_t n = n0 < 0 ? -n0 : n0; - char *p = buff + sizeof(buff); - - *--p = '\0'; - do { - *--p = '0' + (int)(n % 10); - } while (n /= 10); - if (n0 < 0) - *--p = '-'; - return p; -} - -/* - * Like strcmp(), but try to be a little more aware of the fact that - * we're comparing two paths. Right now, it just handles leading - * "./" and trailing '/' specially, so that "a/b/" == "./a/b" - * - * TODO: Make this better, so that "./a//b/./c/" == "a/b/c" - * TODO: After this works, push it down into libarchive. - * TODO: Publish the path normalization routines in libarchive so - * that bsdtar can normalize paths and use fast strcmp() instead - * of this. - * - * Note: This is currently only used within write.c, so should - * not handle \ path separators. - */ - -int -pathcmp(const char *a, const char *b) -{ - /* Skip leading './' */ - if (a[0] == '.' && a[1] == '/' && a[2] != '\0') - a += 2; - if (b[0] == '.' && b[1] == '/' && b[2] != '\0') - b += 2; - /* Find the first difference, or return (0) if none. */ - while (*a == *b) { - if (*a == '\0') - return (0); - a++; - b++; - } - /* - * If one ends in '/' and the other one doesn't, - * they're the same. - */ - if (a[0] == '/' && a[1] == '\0' && b[0] == '\0') - return (0); - if (a[0] == '\0' && b[0] == '/' && b[1] == '\0') - return (0); - /* They're really different, return the correct sign. */ - return (*(const unsigned char *)a - *(const unsigned char *)b); -} - -#define PPBUFF_SIZE 1024 -const char * -passphrase_callback(struct archive *a, void *_client_data) -{ - struct bsdtar *bsdtar = (struct bsdtar *)_client_data; - (void)a; /* UNUSED */ - - if (bsdtar->ppbuff == NULL) { - bsdtar->ppbuff = malloc(PPBUFF_SIZE); - if (bsdtar->ppbuff == NULL) - lafe_errc(1, errno, "Out of memory"); - } - return lafe_readpassphrase("Enter passphrase:", - bsdtar->ppbuff, PPBUFF_SIZE); -} - -void -passphrase_free(char *ppbuff) -{ - if (ppbuff != NULL) { - memset(ppbuff, 0, PPBUFF_SIZE); - free(ppbuff); - } -} - -/* - * Display information about the current file. - * - * The format here roughly duplicates the output of 'ls -l'. - * This is based on SUSv2, where 'tar tv' is documented as - * listing additional information in an "unspecified format," - * and 'pax -l' is documented as using the same format as 'ls -l'. - */ -void -list_item_verbose(struct bsdtar *bsdtar, FILE *out, struct archive_entry *entry) -{ - char tmp[100]; - size_t w; - const char *p; - const char *fmt; - time_t tim; - static time_t now; - struct tm *ltime; -#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S) - struct tm tmbuf; -#endif - - /* - * We avoid collecting the entire list in memory at once by - * listing things as we see them. However, that also means we can't - * just pre-compute the field widths. Instead, we start with guesses - * and just widen them as necessary. These numbers are completely - * arbitrary. - */ - if (!bsdtar->u_width) { - bsdtar->u_width = 6; - bsdtar->gs_width = 13; - } - if (!now) - time(&now); - fprintf(out, "%s %d ", - archive_entry_strmode(entry), - archive_entry_nlink(entry)); - - /* Use uname if it's present, else uid. */ - p = archive_entry_uname(entry); - if ((p == NULL) || (*p == '\0')) { - snprintf(tmp, sizeof(tmp), "%lu ", - (unsigned long)archive_entry_uid(entry)); - p = tmp; - } - w = strlen(p); - if (w > bsdtar->u_width) - bsdtar->u_width = w; - fprintf(out, "%-*s ", (int)bsdtar->u_width, p); - - /* Use gname if it's present, else gid. */ - p = archive_entry_gname(entry); - if (p != NULL && p[0] != '\0') { - fprintf(out, "%s", p); - w = strlen(p); - } else { - snprintf(tmp, sizeof(tmp), "%lu", - (unsigned long)archive_entry_gid(entry)); - w = strlen(tmp); - fprintf(out, "%s", tmp); - } - - /* - * Print device number or file size, right-aligned so as to make - * total width of group and devnum/filesize fields be gs_width. - * If gs_width is too small, grow it. - */ - if (archive_entry_filetype(entry) == AE_IFCHR - || archive_entry_filetype(entry) == AE_IFBLK) { - snprintf(tmp, sizeof(tmp), "%lu,%lu", - (unsigned long)archive_entry_rdevmajor(entry), - (unsigned long)archive_entry_rdevminor(entry)); - } else { - strcpy(tmp, tar_i64toa(archive_entry_size(entry))); - } - if (w + strlen(tmp) >= bsdtar->gs_width) - bsdtar->gs_width = w+strlen(tmp)+1; - fprintf(out, "%*s", (int)(bsdtar->gs_width - w), tmp); - - /* Format the time using 'ls -l' conventions. */ - tim = archive_entry_mtime(entry); -#define HALF_YEAR (time_t)365 * 86400 / 2 -#if defined(_WIN32) && !defined(__CYGWIN__) -#define DAY_FMT "%d" /* Windows' strftime function does not support %e format. */ -#else -#define DAY_FMT "%e" /* Day number without leading zeros */ -#endif - if (tim < now - HALF_YEAR || tim > now + HALF_YEAR) - fmt = bsdtar->day_first ? DAY_FMT " %b %Y" : "%b " DAY_FMT " %Y"; - else - fmt = bsdtar->day_first ? DAY_FMT " %b %H:%M" : "%b " DAY_FMT " %H:%M"; -#if defined(HAVE_LOCALTIME_S) - ltime = localtime_s(&tmbuf, &tim) ? NULL : &tmbuf; -#elif defined(HAVE_LOCALTIME_R) - ltime = localtime_r(&tim, &tmbuf); -#else - ltime = localtime(&tim); -#endif - strftime(tmp, sizeof(tmp), fmt, ltime); - fprintf(out, " %s ", tmp); - safe_fprintf(out, "%s", archive_entry_pathname(entry)); - - /* Extra information for links. */ - if (archive_entry_hardlink(entry)) /* Hard link */ - safe_fprintf(out, " link to %s", - archive_entry_hardlink(entry)); - else if (archive_entry_symlink(entry)) /* Symbolic link */ - safe_fprintf(out, " -> %s", archive_entry_symlink(entry)); -} diff --git a/thirdparty/libarchive/tar/write.c b/thirdparty/libarchive/tar/write.c deleted file mode 100644 index d3e4ca4e0..000000000 --- a/thirdparty/libarchive/tar/write.c +++ /dev/null @@ -1,1059 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * Copyright (c) 2012 Michihiro NAKAJIMA - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "bsdtar_platform.h" -__FBSDID("$FreeBSD: src/usr.bin/tar/write.c,v 1.79 2008/11/27 05:49:52 kientzle Exp $"); - -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_ATTR_XATTR_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif -#ifdef HAVE_GRP_H -#include -#endif -#ifdef HAVE_IO_H -#include -#endif -#ifdef HAVE_LIBGEN_H -#include -#endif -#ifdef HAVE_LIMITS_H -#include -#endif -#ifdef HAVE_PATHS_H -#include -#endif -#ifdef HAVE_PWD_H -#include -#endif -#ifdef HAVE_STDINT_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif - -#include "bsdtar.h" -#include "err.h" -#include "line_reader.h" - -#ifndef O_BINARY -#define O_BINARY 0 -#endif - -struct archive_dir_entry { - struct archive_dir_entry *next; - time_t mtime_sec; - int mtime_nsec; - char *name; -}; - -struct archive_dir { - struct archive_dir_entry *head, *tail; -}; - -static int append_archive(struct bsdtar *, struct archive *, - struct archive *ina); -static int append_archive_filename(struct bsdtar *, - struct archive *, const char *fname); -static void archive_names_from_file(struct bsdtar *bsdtar, - struct archive *a); -static int copy_file_data_block(struct bsdtar *, - struct archive *a, struct archive *, - struct archive_entry *); -static void excluded_callback(struct archive *, void *, - struct archive_entry *); -static void report_write(struct bsdtar *, struct archive *, - struct archive_entry *, int64_t progress); -static void test_for_append(struct bsdtar *); -static int metadata_filter(struct archive *, void *, - struct archive_entry *); -static void write_archive(struct archive *, struct bsdtar *); -static void write_entry(struct bsdtar *, struct archive *, - struct archive_entry *); -static void write_file(struct bsdtar *, struct archive *, - struct archive_entry *); -static void write_hierarchy(struct bsdtar *, struct archive *, - const char *); - -#if defined(_WIN32) && !defined(__CYGWIN__) -/* Not a full lseek() emulation, but enough for our needs here. */ -static int -seek_file(int fd, int64_t offset, int whence) -{ - LARGE_INTEGER distance; - (void)whence; /* UNUSED */ - distance.QuadPart = offset; - return (SetFilePointerEx((HANDLE)_get_osfhandle(fd), - distance, NULL, FILE_BEGIN) ? 1 : -1); -} -#define open _open -#define close _close -#define read _read -#ifdef lseek -#undef lseek -#endif -#define lseek seek_file -#endif - -static void -set_writer_options(struct bsdtar *bsdtar, struct archive *a) -{ - const char *writer_options; - int r; - - writer_options = getenv(ENV_WRITER_OPTIONS); - if (writer_options != NULL) { - size_t module_len = sizeof(IGNORE_WRONG_MODULE_NAME) - 1; - size_t opt_len = strlen(writer_options) + 1; - char *p; - /* Set default write options. */ - if ((p = malloc(module_len + opt_len)) == NULL) - lafe_errc(1, errno, "Out of memory"); - /* Prepend magic code to ignore options for - * a format or filters which are not added to - * the archive write object. */ - memcpy(p, IGNORE_WRONG_MODULE_NAME, module_len); - memcpy(p, writer_options, opt_len); - r = archive_write_set_options(a, p); - free(p); - if (r < ARCHIVE_WARN) - lafe_errc(1, 0, "%s", archive_error_string(a)); - else - archive_clear_error(a); - } - if (ARCHIVE_OK != archive_write_set_options(a, bsdtar->option_options)) - lafe_errc(1, 0, "%s", archive_error_string(a)); -} - -static void -set_reader_options(struct bsdtar *bsdtar, struct archive *a) -{ - const char *reader_options; - int r; - - (void)bsdtar; /* UNUSED */ - - reader_options = getenv(ENV_READER_OPTIONS); - if (reader_options != NULL) { - size_t module_len = sizeof(IGNORE_WRONG_MODULE_NAME) - 1; - size_t opt_len = strlen(reader_options) + 1; - char *p; - /* Set default write options. */ - if ((p = malloc(module_len + opt_len)) == NULL) - if (p == NULL) - lafe_errc(1, errno, "Out of memory"); - /* Prepend magic code to ignore options for - * a format or filters which are not added to - * the archive write object. */ - memcpy(p, IGNORE_WRONG_MODULE_NAME, module_len); - memcpy(p, reader_options, opt_len); - r = archive_read_set_options(a, p); - free(p); - if (r < ARCHIVE_WARN) - lafe_errc(1, 0, "%s", archive_error_string(a)); - else - archive_clear_error(a); - } - if (bsdtar->flags & OPTFLAG_IGNORE_ZEROS) - if (archive_read_set_options(a, - "read_concatenated_archives") != ARCHIVE_OK) - lafe_errc(1, 0, "%s", archive_error_string(a)); -} - -void -tar_mode_c(struct bsdtar *bsdtar) -{ - struct archive *a; - const void *filter_name; - int r; - - if (*bsdtar->argv == NULL && bsdtar->names_from_file == NULL) - lafe_errc(1, 0, "no files or directories specified"); - - a = archive_write_new(); - - /* Support any format that the library supports. */ - if (cset_get_format(bsdtar->cset) == NULL) { - r = archive_write_set_format_pax_restricted(a); - cset_set_format(bsdtar->cset, "pax restricted"); - } else { - r = archive_write_set_format_by_name(a, - cset_get_format(bsdtar->cset)); - } - if (r != ARCHIVE_OK) { - fprintf(stderr, "Can't use format %s: %s\n", - cset_get_format(bsdtar->cset), - archive_error_string(a)); - usage(); - } - - archive_write_set_bytes_per_block(a, bsdtar->bytes_per_block); - archive_write_set_bytes_in_last_block(a, bsdtar->bytes_in_last_block); - - r = cset_write_add_filters(bsdtar->cset, a, &filter_name); - if (r < ARCHIVE_WARN) { - lafe_errc(1, 0, "Unsupported compression option --%s", - (const char *)filter_name); - } - - set_writer_options(bsdtar, a); - if (bsdtar->passphrase != NULL) - r = archive_write_set_passphrase(a, bsdtar->passphrase); - else - r = archive_write_set_passphrase_callback(a, bsdtar, - &passphrase_callback); - if (r != ARCHIVE_OK) - lafe_errc(1, 0, "%s", archive_error_string(a)); - if (ARCHIVE_OK != archive_write_open_filename(a, bsdtar->filename)) - lafe_errc(1, 0, "%s", archive_error_string(a)); - write_archive(a, bsdtar); -} - -/* - * Same as 'c', except we only support tar or empty formats in - * uncompressed files on disk. - */ -void -tar_mode_r(struct bsdtar *bsdtar) -{ - int64_t end_offset; - int format; - struct archive *a; - struct archive_entry *entry; - int r; - - /* Sanity-test some arguments and the file. */ - test_for_append(bsdtar); - - format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED; - -#if defined(__BORLANDC__) - bsdtar->fd = open(bsdtar->filename, O_RDWR | O_CREAT | O_BINARY); -#else - bsdtar->fd = open(bsdtar->filename, O_RDWR | O_CREAT | O_BINARY, 0666); -#endif - if (bsdtar->fd < 0) - lafe_errc(1, errno, - "Cannot open %s", bsdtar->filename); - - a = archive_read_new(); - archive_read_support_filter_all(a); - archive_read_support_format_empty(a); - archive_read_support_format_tar(a); - archive_read_support_format_gnutar(a); - set_reader_options(bsdtar, a); - r = archive_read_open_fd(a, bsdtar->fd, 10240); - if (r != ARCHIVE_OK) - lafe_errc(1, archive_errno(a), - "Can't read archive %s: %s", bsdtar->filename, - archive_error_string(a)); - while (0 == archive_read_next_header(a, &entry)) { - if (archive_filter_code(a, 0) != ARCHIVE_FILTER_NONE) { - archive_read_free(a); - close(bsdtar->fd); - lafe_errc(1, 0, - "Cannot append to compressed archive."); - } - /* Keep going until we hit end-of-archive */ - format = archive_format(a); - } - - end_offset = archive_read_header_position(a); - archive_read_free(a); - - /* Re-open archive for writing */ - a = archive_write_new(); - /* - * Set the format to be used for writing. To allow people to - * extend empty files, we need to allow them to specify the format, - * which opens the possibility that they will specify a format that - * doesn't match the existing format. Hence, the following bit - * of arcane ugliness. - */ - - if (cset_get_format(bsdtar->cset) != NULL) { - /* If the user requested a format, use that, but ... */ - archive_write_set_format_by_name(a, - cset_get_format(bsdtar->cset)); - /* ... complain if it's not compatible. */ - format &= ARCHIVE_FORMAT_BASE_MASK; - if (format != (int)(archive_format(a) & ARCHIVE_FORMAT_BASE_MASK) - && format != ARCHIVE_FORMAT_EMPTY) { - lafe_errc(1, 0, - "Format %s is incompatible with the archive %s.", - cset_get_format(bsdtar->cset), bsdtar->filename); - } - } else { - /* - * Just preserve the current format, with a little care - * for formats that libarchive can't write. - */ - if (format == ARCHIVE_FORMAT_EMPTY) - format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED; - archive_write_set_format(a, format); - } - if (lseek(bsdtar->fd, end_offset, SEEK_SET) < 0) - lafe_errc(1, errno, "Could not seek to archive end"); - set_writer_options(bsdtar, a); - if (ARCHIVE_OK != archive_write_open_fd(a, bsdtar->fd)) - lafe_errc(1, 0, "%s", archive_error_string(a)); - - write_archive(a, bsdtar); /* XXX check return val XXX */ - - close(bsdtar->fd); - bsdtar->fd = -1; -} - -void -tar_mode_u(struct bsdtar *bsdtar) -{ - int64_t end_offset; - struct archive *a; - struct archive_entry *entry; - int format; - struct archive_dir_entry *p; - struct archive_dir archive_dir; - - bsdtar->archive_dir = &archive_dir; - memset(&archive_dir, 0, sizeof(archive_dir)); - - format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED; - - /* Sanity-test some arguments and the file. */ - test_for_append(bsdtar); - - bsdtar->fd = open(bsdtar->filename, O_RDWR | O_BINARY); - if (bsdtar->fd < 0) - lafe_errc(1, errno, - "Cannot open %s", bsdtar->filename); - - a = archive_read_new(); - archive_read_support_filter_all(a); - archive_read_support_format_tar(a); - archive_read_support_format_gnutar(a); - set_reader_options(bsdtar, a); - if (archive_read_open_fd(a, bsdtar->fd, bsdtar->bytes_per_block) - != ARCHIVE_OK) { - lafe_errc(1, 0, - "Can't open %s: %s", bsdtar->filename, - archive_error_string(a)); - } - - /* Build a list of all entries and their recorded mod times. */ - while (0 == archive_read_next_header(a, &entry)) { - if (archive_filter_code(a, 0) != ARCHIVE_FILTER_NONE) { - archive_read_free(a); - close(bsdtar->fd); - lafe_errc(1, 0, - "Cannot append to compressed archive."); - } - if (archive_match_exclude_entry(bsdtar->matching, - ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER | - ARCHIVE_MATCH_EQUAL, entry) != ARCHIVE_OK) - lafe_errc(1, 0, "Error : %s", - archive_error_string(bsdtar->matching)); - /* Record the last format determination we see */ - format = archive_format(a); - /* Keep going until we hit end-of-archive */ - } - - end_offset = archive_read_header_position(a); - archive_read_free(a); - - /* Re-open archive for writing. */ - a = archive_write_new(); - /* - * Set format to same one auto-detected above. - */ - archive_write_set_format(a, format); - archive_write_set_bytes_per_block(a, bsdtar->bytes_per_block); - archive_write_set_bytes_in_last_block(a, bsdtar->bytes_in_last_block); - - if (lseek(bsdtar->fd, end_offset, SEEK_SET) < 0) - lafe_errc(1, errno, "Could not seek to archive end"); - set_writer_options(bsdtar, a); - if (ARCHIVE_OK != archive_write_open_fd(a, bsdtar->fd)) - lafe_errc(1, 0, "%s", archive_error_string(a)); - - write_archive(a, bsdtar); - - close(bsdtar->fd); - bsdtar->fd = -1; - - while (bsdtar->archive_dir->head != NULL) { - p = bsdtar->archive_dir->head->next; - free(bsdtar->archive_dir->head->name); - free(bsdtar->archive_dir->head); - bsdtar->archive_dir->head = p; - } - bsdtar->archive_dir->tail = NULL; -} - - -/* - * Write user-specified files/dirs to opened archive. - */ -static void -write_archive(struct archive *a, struct bsdtar *bsdtar) -{ - const char *arg; - struct archive_entry *entry, *sparse_entry; - - /* Choose a suitable copy buffer size */ - bsdtar->buff_size = 64 * 1024; - while (bsdtar->buff_size < (size_t)bsdtar->bytes_per_block) - bsdtar->buff_size *= 2; - /* Try to compensate for space we'll lose to alignment. */ - bsdtar->buff_size += 16 * 1024; - - /* Allocate a buffer for file data. */ - if ((bsdtar->buff = malloc(bsdtar->buff_size)) == NULL) - lafe_errc(1, 0, "cannot allocate memory"); - - if ((bsdtar->resolver = archive_entry_linkresolver_new()) == NULL) - lafe_errc(1, 0, "cannot create link resolver"); - archive_entry_linkresolver_set_strategy(bsdtar->resolver, - archive_format(a)); - - /* Create a read_disk object. */ - if ((bsdtar->diskreader = archive_read_disk_new()) == NULL) - lafe_errc(1, 0, "Cannot create read_disk object"); - /* Tell the read_disk how handle symlink. */ - switch (bsdtar->symlink_mode) { - case 'H': - archive_read_disk_set_symlink_hybrid(bsdtar->diskreader); - break; - case 'L': - archive_read_disk_set_symlink_logical(bsdtar->diskreader); - break; - default: - archive_read_disk_set_symlink_physical(bsdtar->diskreader); - break; - } - /* Register entry filters. */ - archive_read_disk_set_matching(bsdtar->diskreader, - bsdtar->matching, excluded_callback, bsdtar); - archive_read_disk_set_metadata_filter_callback( - bsdtar->diskreader, metadata_filter, bsdtar); - /* Set the behavior of archive_read_disk. */ - archive_read_disk_set_behavior(bsdtar->diskreader, - bsdtar->readdisk_flags); - archive_read_disk_set_standard_lookup(bsdtar->diskreader); - - if (bsdtar->names_from_file != NULL) - archive_names_from_file(bsdtar, a); - - while (*bsdtar->argv) { - arg = *bsdtar->argv; - if (arg[0] == '-' && arg[1] == 'C') { - arg += 2; - if (*arg == '\0') { - bsdtar->argv++; - arg = *bsdtar->argv; - if (arg == NULL) { - lafe_warnc(0, "%s", - "Missing argument for -C"); - bsdtar->return_value = 1; - goto cleanup; - } - if (*arg == '\0') { - lafe_warnc(0, - "Meaningless argument for -C: ''"); - bsdtar->return_value = 1; - goto cleanup; - } - } - set_chdir(bsdtar, arg); - } else { - if (*arg != '/') - do_chdir(bsdtar); /* Handle a deferred -C */ - if (*arg == '@') { - if (append_archive_filename(bsdtar, a, - arg + 1) != 0) - break; - } else - write_hierarchy(bsdtar, a, arg); - } - bsdtar->argv++; - } - - archive_read_disk_set_matching(bsdtar->diskreader, NULL, NULL, NULL); - archive_read_disk_set_metadata_filter_callback( - bsdtar->diskreader, NULL, NULL); - entry = NULL; - archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); - while (entry != NULL) { - int r; - struct archive_entry *entry2; - struct archive *disk = bsdtar->diskreader; - - /* - * This tricky code here is to correctly read the contents - * of the entry because the disk reader bsdtar->diskreader - * is pointing at does not have any information about the - * entry by this time and using archive_read_data_block() - * with the disk reader consequently must fail. And we - * have to re-open the entry to read the contents. - */ - /* TODO: Work with -C option as well. */ - r = archive_read_disk_open(disk, - archive_entry_sourcepath(entry)); - if (r != ARCHIVE_OK) { - lafe_warnc(archive_errno(disk), - "%s", archive_error_string(disk)); - bsdtar->return_value = 1; - goto next_entry; - } - - /* - * Invoke archive_read_next_header2() to work - * archive_read_data_block(), which is called via write_file(), - * without failure. - */ - entry2 = archive_entry_new(); - r = archive_read_next_header2(disk, entry2); - archive_entry_free(entry2); - if (r != ARCHIVE_OK) { - lafe_warnc(archive_errno(disk), - "%s", archive_error_string(disk)); - if (r == ARCHIVE_FATAL) - bsdtar->return_value = 1; - archive_read_close(disk); - goto next_entry; - } - - write_file(bsdtar, a, entry); - archive_read_close(disk); -next_entry: - archive_entry_free(entry); - entry = NULL; - archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry); - } - - if (archive_write_close(a)) { - lafe_warnc(0, "%s", archive_error_string(a)); - bsdtar->return_value = 1; - } - -cleanup: - /* Free file data buffer. */ - free(bsdtar->buff); - archive_entry_linkresolver_free(bsdtar->resolver); - bsdtar->resolver = NULL; - archive_read_free(bsdtar->diskreader); - bsdtar->diskreader = NULL; - - if (bsdtar->flags & OPTFLAG_TOTALS) { - fprintf(stderr, "Total bytes written: %s\n", - tar_i64toa(archive_filter_bytes(a, -1))); - } - - archive_write_free(a); -} - -/* - * Archive names specified in file. - * - * Unless --null was specified, a line containing exactly "-C" will - * cause the next line to be a directory to pass to chdir(). If - * --null is specified, then a line "-C" is just another filename. - */ -static void -archive_names_from_file(struct bsdtar *bsdtar, struct archive *a) -{ - struct lafe_line_reader *lr; - const char *line; - - bsdtar->next_line_is_dir = 0; - - lr = lafe_line_reader(bsdtar->names_from_file, - (bsdtar->flags & OPTFLAG_NULL)); - while ((line = lafe_line_reader_next(lr)) != NULL) { - if (bsdtar->next_line_is_dir) { - if (*line != '\0') - set_chdir(bsdtar, line); - else { - lafe_warnc(0, - "Meaningless argument for -C: ''"); - bsdtar->return_value = 1; - } - bsdtar->next_line_is_dir = 0; - } else if (((bsdtar->flags & OPTFLAG_NULL) == 0) && - strcmp(line, "-C") == 0) - bsdtar->next_line_is_dir = 1; - else { - if (*line != '/') - do_chdir(bsdtar); /* Handle a deferred -C */ - write_hierarchy(bsdtar, a, line); - } - } - lafe_line_reader_free(lr); - if (bsdtar->next_line_is_dir) - lafe_errc(1, errno, - "Unexpected end of filename list; " - "directory expected after -C"); -} - -/* - * Copy from specified archive to current archive. Returns non-zero - * for write errors (which force us to terminate the entire archiving - * operation). If there are errors reading the input archive, we set - * bsdtar->return_value but return zero, so the overall archiving - * operation will complete and return non-zero. - */ -static int -append_archive_filename(struct bsdtar *bsdtar, struct archive *a, - const char *raw_filename) -{ - struct archive *ina; - const char *filename = raw_filename; - int rc; - - if (strcmp(filename, "-") == 0) - filename = NULL; /* Library uses NULL for stdio. */ - - ina = archive_read_new(); - archive_read_support_format_all(ina); - archive_read_support_filter_all(ina); - set_reader_options(bsdtar, ina); - archive_read_set_options(ina, "mtree:checkfs"); - if (bsdtar->passphrase != NULL) - rc = archive_read_add_passphrase(a, bsdtar->passphrase); - else - rc = archive_read_set_passphrase_callback(ina, bsdtar, - &passphrase_callback); - if (rc != ARCHIVE_OK) - lafe_errc(1, 0, "%s", archive_error_string(a)); - if (archive_read_open_filename(ina, filename, - bsdtar->bytes_per_block)) { - lafe_warnc(0, "%s", archive_error_string(ina)); - bsdtar->return_value = 1; - return (0); - } - - rc = append_archive(bsdtar, a, ina); - - if (rc != ARCHIVE_OK) { - lafe_warnc(0, "Error reading archive %s: %s", - raw_filename, archive_error_string(ina)); - bsdtar->return_value = 1; - } - archive_read_free(ina); - - return (rc); -} - -static int -append_archive(struct bsdtar *bsdtar, struct archive *a, struct archive *ina) -{ - struct archive_entry *in_entry; - int e; - - while (ARCHIVE_OK == (e = archive_read_next_header(ina, &in_entry))) { - if (archive_match_excluded(bsdtar->matching, in_entry)) - continue; - if(edit_pathname(bsdtar, in_entry)) - continue; - if ((bsdtar->flags & OPTFLAG_INTERACTIVE) && - !yes("copy '%s'", archive_entry_pathname(in_entry))) - continue; - if (bsdtar->verbose > 1) { - safe_fprintf(stderr, "a "); - list_item_verbose(bsdtar, stderr, in_entry); - } else if (bsdtar->verbose > 0) - safe_fprintf(stderr, "a %s", - archive_entry_pathname(in_entry)); - if (need_report()) - report_write(bsdtar, a, in_entry, 0); - - e = archive_write_header(a, in_entry); - if (e != ARCHIVE_OK) { - if (!bsdtar->verbose) - lafe_warnc(0, "%s: %s", - archive_entry_pathname(in_entry), - archive_error_string(a)); - else - fprintf(stderr, ": %s", archive_error_string(a)); - } - if (e == ARCHIVE_FATAL) - exit(1); - - if (e >= ARCHIVE_WARN) { - if (archive_entry_size(in_entry) == 0) - archive_read_data_skip(ina); - else if (copy_file_data_block(bsdtar, a, ina, in_entry)) - exit(1); - } - - if (bsdtar->verbose) - fprintf(stderr, "\n"); - } - - return (e == ARCHIVE_EOF ? ARCHIVE_OK : e); -} - -/* Helper function to copy file to archive. */ -static int -copy_file_data_block(struct bsdtar *bsdtar, struct archive *a, - struct archive *in_a, struct archive_entry *entry) -{ - size_t bytes_read; - ssize_t bytes_written; - int64_t offset, progress = 0; - char *null_buff = NULL; - const void *buff; - int r; - - while ((r = archive_read_data_block(in_a, &buff, - &bytes_read, &offset)) == ARCHIVE_OK) { - if (need_report()) - report_write(bsdtar, a, entry, progress); - - if (offset > progress) { - int64_t sparse = offset - progress; - size_t ns; - - if (null_buff == NULL) { - null_buff = bsdtar->buff; - memset(null_buff, 0, bsdtar->buff_size); - } - - while (sparse > 0) { - if (sparse > (int64_t)bsdtar->buff_size) - ns = bsdtar->buff_size; - else - ns = (size_t)sparse; - bytes_written = - archive_write_data(a, null_buff, ns); - if (bytes_written < 0) { - /* Write failed; this is bad */ - lafe_warnc(0, "%s", - archive_error_string(a)); - return (-1); - } - if ((size_t)bytes_written < ns) { - /* Write was truncated; warn but - * continue. */ - lafe_warnc(0, - "%s: Truncated write; file may " - "have grown while being archived.", - archive_entry_pathname(entry)); - return (0); - } - progress += bytes_written; - sparse -= bytes_written; - } - } - - bytes_written = archive_write_data(a, buff, bytes_read); - if (bytes_written < 0) { - /* Write failed; this is bad */ - lafe_warnc(0, "%s", archive_error_string(a)); - return (-1); - } - if ((size_t)bytes_written < bytes_read) { - /* Write was truncated; warn but continue. */ - lafe_warnc(0, - "%s: Truncated write; file may have grown " - "while being archived.", - archive_entry_pathname(entry)); - return (0); - } - progress += bytes_written; - } - if (r < ARCHIVE_WARN) { - lafe_warnc(archive_errno(a), "%s", archive_error_string(a)); - return (-1); - } - return (0); -} - -static void -excluded_callback(struct archive *a, void *_data, struct archive_entry *entry) -{ - struct bsdtar *bsdtar = (struct bsdtar *)_data; - - if (bsdtar->flags & OPTFLAG_NO_SUBDIRS) - return; - if (!archive_read_disk_can_descend(a)) - return; - if ((bsdtar->flags & OPTFLAG_INTERACTIVE) && - !yes("add '%s'", archive_entry_pathname(entry))) - return; - archive_read_disk_descend(a); -} - -static int -metadata_filter(struct archive *a, void *_data, struct archive_entry *entry) -{ - struct bsdtar *bsdtar = (struct bsdtar *)_data; - - /* XXX TODO: check whether this filesystem is - * synthetic and/or local. Add a new - * --local-only option to skip non-local - * filesystems. Skip synthetic filesystems - * regardless. - * - * The results should be cached, since - * tree.c doesn't usually visit a directory - * and the directory contents together. A simple - * move-to-front list should perform quite well. - * - * Use archive_read_disk_current_filesystem_is_remote(). - */ - - /* - * If the user vetoes this file/directory, skip it. - * We want this to be fairly late; if some other - * check would veto this file, we shouldn't bother - * the user with it. - */ - if ((bsdtar->flags & OPTFLAG_INTERACTIVE) && - !yes("add '%s'", archive_entry_pathname(entry))) - return (0); - - /* Note: if user vetoes, we won't descend. */ - if (((bsdtar->flags & OPTFLAG_NO_SUBDIRS) == 0) && - archive_read_disk_can_descend(a)) - archive_read_disk_descend(a); - - return (1); -} - -/* - * Add the file or dir hierarchy named by 'path' to the archive - */ -static void -write_hierarchy(struct bsdtar *bsdtar, struct archive *a, const char *path) -{ - struct archive *disk = bsdtar->diskreader; - struct archive_entry *entry = NULL, *spare_entry = NULL; - int r; - - r = archive_read_disk_open(disk, path); - if (r != ARCHIVE_OK) { - lafe_warnc(archive_errno(disk), - "%s", archive_error_string(disk)); - bsdtar->return_value = 1; - return; - } - bsdtar->first_fs = -1; - - for (;;) { - archive_entry_free(entry); - entry = archive_entry_new(); - r = archive_read_next_header2(disk, entry); - if (r == ARCHIVE_EOF) - break; - else if (r != ARCHIVE_OK) { - lafe_warnc(archive_errno(disk), - "%s", archive_error_string(disk)); - if (r == ARCHIVE_FATAL || r == ARCHIVE_FAILED) { - bsdtar->return_value = 1; - archive_entry_free(entry); - archive_read_close(disk); - return; - } else if (r < ARCHIVE_WARN) - continue; - } - - if (bsdtar->uid >= 0) { - archive_entry_set_uid(entry, bsdtar->uid); - if (!bsdtar->uname) - archive_entry_set_uname(entry, - archive_read_disk_uname(bsdtar->diskreader, - bsdtar->uid)); - } - if (bsdtar->gid >= 0) { - archive_entry_set_gid(entry, bsdtar->gid); - if (!bsdtar->gname) - archive_entry_set_gname(entry, - archive_read_disk_gname(bsdtar->diskreader, - bsdtar->gid)); - } - if (bsdtar->uname) - archive_entry_set_uname(entry, bsdtar->uname); - if (bsdtar->gname) - archive_entry_set_gname(entry, bsdtar->gname); - - /* - * Rewrite the pathname to be archived. If rewrite - * fails, skip the entry. - */ - if (edit_pathname(bsdtar, entry)) - continue; - - /* Display entry as we process it. */ - if (bsdtar->verbose > 1) { - safe_fprintf(stderr, "a "); - list_item_verbose(bsdtar, stderr, entry); - } else if (bsdtar->verbose > 0) { - /* This format is required by SUSv2. */ - safe_fprintf(stderr, "a %s", - archive_entry_pathname(entry)); - } - - /* Non-regular files get archived with zero size. */ - if (archive_entry_filetype(entry) != AE_IFREG) - archive_entry_set_size(entry, 0); - - archive_entry_linkify(bsdtar->resolver, &entry, &spare_entry); - - while (entry != NULL) { - write_file(bsdtar, a, entry); - archive_entry_free(entry); - entry = spare_entry; - spare_entry = NULL; - } - - if (bsdtar->verbose) - fprintf(stderr, "\n"); - } - archive_entry_free(entry); - archive_read_close(disk); -} - -/* - * Write a single file (or directory or other filesystem object) to - * the archive. - */ -static void -write_file(struct bsdtar *bsdtar, struct archive *a, - struct archive_entry *entry) -{ - write_entry(bsdtar, a, entry); -} - -/* - * Write a single entry to the archive. - */ -static void -write_entry(struct bsdtar *bsdtar, struct archive *a, - struct archive_entry *entry) -{ - int e; - - e = archive_write_header(a, entry); - if (e != ARCHIVE_OK) { - if (bsdtar->verbose > 1) { - safe_fprintf(stderr, "a "); - list_item_verbose(bsdtar, stderr, entry); - lafe_warnc(0, ": %s", archive_error_string(a)); - } else if (bsdtar->verbose > 0) { - lafe_warnc(0, "%s: %s", - archive_entry_pathname(entry), - archive_error_string(a)); - } else - fprintf(stderr, ": %s", archive_error_string(a)); - } - - if (e == ARCHIVE_FATAL) - exit(1); - - /* - * If we opened a file earlier, write it out now. Note that - * the format handler might have reset the size field to zero - * to inform us that the archive body won't get stored. In - * that case, just skip the write. - */ - if (e >= ARCHIVE_WARN && archive_entry_size(entry) > 0) { - if (copy_file_data_block(bsdtar, a, bsdtar->diskreader, entry)) - exit(1); - } -} - -static void -report_write(struct bsdtar *bsdtar, struct archive *a, - struct archive_entry *entry, int64_t progress) -{ - uint64_t comp, uncomp; - int compression; - - if (bsdtar->verbose) - fprintf(stderr, "\n"); - comp = archive_filter_bytes(a, -1); - uncomp = archive_filter_bytes(a, 0); - fprintf(stderr, "In: %d files, %s bytes;", - archive_file_count(a), tar_i64toa(uncomp)); - if (comp >= uncomp) - compression = 0; - else - compression = (int)((uncomp - comp) * 100 / uncomp); - fprintf(stderr, - " Out: %s bytes, compression %d%%\n", - tar_i64toa(comp), compression); - /* Can't have two calls to tar_i64toa() pending, so split the output. */ - safe_fprintf(stderr, "Current: %s (%s", - archive_entry_pathname(entry), - tar_i64toa(progress)); - fprintf(stderr, "/%s bytes)\n", - tar_i64toa(archive_entry_size(entry))); -} - -static void -test_for_append(struct bsdtar *bsdtar) -{ - struct stat s; - - if (*bsdtar->argv == NULL && bsdtar->names_from_file == NULL) - lafe_errc(1, 0, "no files or directories specified"); - if (bsdtar->filename == NULL) - lafe_errc(1, 0, "Cannot append to stdout."); - - if (stat(bsdtar->filename, &s) != 0) - return; - - if (!S_ISREG(s.st_mode) && !S_ISBLK(s.st_mode)) - lafe_errc(1, 0, - "Cannot append to %s: not a regular file.", - bsdtar->filename); - -/* Is this an appropriate check here on Windows? */ -/* - if (GetFileType(handle) != FILE_TYPE_DISK) - lafe_errc(1, 0, "Cannot append"); -*/ - -} diff --git a/thirdparty/libarchive/test_utils/test_common.h b/thirdparty/libarchive/test_utils/test_common.h deleted file mode 100644 index 6250235c6..000000000 --- a/thirdparty/libarchive/test_utils/test_common.h +++ /dev/null @@ -1,476 +0,0 @@ -/* - * Copyright (c) 2003-2017 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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$ - */ - -#ifndef TEST_COMMON_H -#define TEST_COMMON_H - -/* - * The goal of this file (and the matching test.c) is to - * simplify the very repetitive test-*.c test programs. - */ -#if defined(HAVE_CONFIG_H) -/* Most POSIX platforms use the 'configure' script to build config.h */ -#include "config.h" -#elif defined(__FreeBSD__) -/* Building as part of FreeBSD system requires a pre-built config.h. */ -#include "config_freebsd.h" -#elif defined(__NetBSD__) -/* Building as part of NetBSD system requires a pre-built config.h. */ -#include "config_netbsd.h" -#elif defined(_WIN32) && !defined(__CYGWIN__) -/* Win32 can't run the 'configure' script. */ -#include "config_windows.h" -#else -/* Warn if the library hasn't been (automatically or manually) configured. */ -#error Oops: No config.h and no pre-built configuration in test.h. -#endif - -#include /* Windows requires this before sys/stat.h */ -#include - -#if HAVE_DIRENT_H -#include -#endif -#ifdef HAVE_DIRECT_H -#include -#define dirent direct -#endif -#include -#include -#ifdef HAVE_IO_H -#include -#endif -#ifdef HAVE_STDINT_H -#include -#endif -#include -#include -#include -#include -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#include -#ifdef HAVE_ACL_LIBACL_H -#include -#endif -#ifdef HAVE_SYS_ACL_H -#include -#endif -#ifdef HAVE_SYS_RICHACL_H -#include -#endif -#ifdef HAVE_WINDOWS_H -#define NOCRYPT -#include -#include -#endif - -/* - * System-specific tweaks. We really want to minimize these - * as much as possible, since they make it harder to understand - * the mainline code. - */ - -/* Windows (including Visual Studio and MinGW but not Cygwin) */ -#if defined(_WIN32) && !defined(__CYGWIN__) -#if !defined(__BORLANDC__) -#undef chdir -#define chdir _chdir -#define strdup _strdup -#endif -#endif - -/* Visual Studio */ -#if defined(_MSC_VER) && _MSC_VER < 1900 -#define snprintf sprintf_s -#endif - -#if defined(__BORLANDC__) -#pragma warn -8068 /* Constant out of range in comparison. */ -#endif - - -#if defined(__GNUC__) && (__GNUC__ > 2 || \ - (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)) -# ifdef __MINGW_PRINTF_FORMAT -# define __LA_PRINTF_FORMAT __MINGW_PRINTF_FORMAT -# else -# define __LA_PRINTF_FORMAT __printf__ -# endif -# define __LA_PRINTFLIKE(f,a) __attribute__((__format__(__LA_PRINTF_FORMAT, f, a))) -#else -# define __LA_PRINTFLIKE(f,a) -#endif - -/* Haiku OS and QNX */ -#if defined(__HAIKU__) || defined(__QNXNTO__) -/* Haiku and QNX have typedefs in stdint.h (needed for int64_t) */ -#include -#endif - -/* Get a real definition for __FBSDID if we can */ -#if HAVE_SYS_CDEFS_H -#include -#endif - -/* If not, define it so as to avoid dangling semicolons. */ -#ifndef __FBSDID -#define __FBSDID(a) struct _undefined_hack -#endif - -#ifndef O_BINARY -#define O_BINARY 0 -#endif - -#ifndef __LIBARCHIVE_TEST_COMMON -#define __LIBARCHIVE_TEST_COMMON -#endif - -#include "archive_platform_acl.h" -#define ARCHIVE_TEST_ACL_TYPE_POSIX1E 1 -#define ARCHIVE_TEST_ACL_TYPE_NFS4 2 - -#include "archive_platform_xattr.h" - -/* - * Redefine DEFINE_TEST for use in defining the test functions. - */ -#undef DEFINE_TEST -#define DEFINE_TEST(name) void name(void); void name(void) - -/* An implementation of the standard assert() macro */ -#define assert(e) assertion_assert(__FILE__, __LINE__, (e), #e, NULL) -/* chdir() and error if it fails */ -#define assertChdir(path) \ - assertion_chdir(__FILE__, __LINE__, path) -/* change file/directory permissions and errors if it fails */ -#define assertChmod(pathname, mode) \ - assertion_chmod(__FILE__, __LINE__, pathname, mode) -/* Assert two files have the same file flags */ -#define assertEqualFflags(patha, pathb) \ - assertion_compare_fflags(__FILE__, __LINE__, patha, pathb, 0) -/* Assert two integers are the same. Reports value of each one if not. */ -#define assertEqualInt(v1,v2) \ - assertion_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL) -/* Assert two strings are the same. Reports value of each one if not. */ -#define assertEqualString(v1,v2) \ - assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 0) -#define assertEqualUTF8String(v1,v2) \ - assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL, 1) -/* As above, but v1 and v2 are wchar_t * */ -#define assertEqualWString(v1,v2) \ - assertion_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL) -/* As above, but raw blocks of bytes. */ -#define assertEqualMem(v1, v2, l) \ - assertion_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL) -/* Assert that memory is full of a specified byte */ -#define assertMemoryFilledWith(v1, l, b) \ - assertion_memory_filled_with(__FILE__, __LINE__, (v1), #v1, (l), #l, (b), #b, NULL) -/* Assert two files are the same. */ -#define assertEqualFile(f1, f2) \ - assertion_equal_file(__FILE__, __LINE__, (f1), (f2)) -/* Assert that a file is empty. */ -#define assertEmptyFile(pathname) \ - assertion_empty_file(__FILE__, __LINE__, (pathname)) -/* Assert that a file is not empty. */ -#define assertNonEmptyFile(pathname) \ - assertion_non_empty_file(__FILE__, __LINE__, (pathname)) -#define assertFileAtime(pathname, sec, nsec) \ - assertion_file_atime(__FILE__, __LINE__, pathname, sec, nsec) -#define assertFileAtimeRecent(pathname) \ - assertion_file_atime_recent(__FILE__, __LINE__, pathname) -#define assertFileBirthtime(pathname, sec, nsec) \ - assertion_file_birthtime(__FILE__, __LINE__, pathname, sec, nsec) -#define assertFileBirthtimeRecent(pathname) \ - assertion_file_birthtime_recent(__FILE__, __LINE__, pathname) -/* Assert that a file exists; supports printf-style arguments. */ -#define assertFileExists(pathname) \ - assertion_file_exists(__FILE__, __LINE__, pathname) -/* Assert that a file exists. */ -#define assertFileNotExists(pathname) \ - assertion_file_not_exists(__FILE__, __LINE__, pathname) -/* Assert that file contents match a string. */ -#define assertFileContents(data, data_size, pathname) \ - assertion_file_contents(__FILE__, __LINE__, data, data_size, pathname) -/* Verify that a file does not contain invalid strings */ -#define assertFileContainsNoInvalidStrings(pathname, strings) \ - assertion_file_contains_no_invalid_strings(__FILE__, __LINE__, pathname, strings) -#define assertFileMtime(pathname, sec, nsec) \ - assertion_file_mtime(__FILE__, __LINE__, pathname, sec, nsec) -#define assertFileMtimeRecent(pathname) \ - assertion_file_mtime_recent(__FILE__, __LINE__, pathname) -#define assertFileNLinks(pathname, nlinks) \ - assertion_file_nlinks(__FILE__, __LINE__, pathname, nlinks) -#define assertFileSize(pathname, size) \ - assertion_file_size(__FILE__, __LINE__, pathname, size) -#define assertFileMode(pathname, mode) \ - assertion_file_mode(__FILE__, __LINE__, pathname, mode) -#define assertTextFileContents(text, pathname) \ - assertion_text_file_contents(__FILE__, __LINE__, text, pathname) -#define assertFileContainsLinesAnyOrder(pathname, lines) \ - assertion_file_contains_lines_any_order(__FILE__, __LINE__, pathname, lines) -#define assertIsDir(pathname, mode) \ - assertion_is_dir(__FILE__, __LINE__, pathname, mode) -#define assertIsHardlink(path1, path2) \ - assertion_is_hardlink(__FILE__, __LINE__, path1, path2) -#define assertIsNotHardlink(path1, path2) \ - assertion_is_not_hardlink(__FILE__, __LINE__, path1, path2) -#define assertIsReg(pathname, mode) \ - assertion_is_reg(__FILE__, __LINE__, pathname, mode) -#define assertIsSymlink(pathname, contents, isdir) \ - assertion_is_symlink(__FILE__, __LINE__, pathname, contents, isdir) -/* Create a directory, report error if it fails. */ -#define assertMakeDir(dirname, mode) \ - assertion_make_dir(__FILE__, __LINE__, dirname, mode) -#define assertMakeFile(path, mode, contents) \ - assertion_make_file(__FILE__, __LINE__, path, mode, -1, contents) -#define assertMakeBinFile(path, mode, csize, contents) \ - assertion_make_file(__FILE__, __LINE__, path, mode, csize, contents) -#define assertMakeHardlink(newfile, oldfile) \ - assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile) -#define assertMakeSymlink(newfile, linkto, targetIsDir) \ - assertion_make_symlink(__FILE__, __LINE__, newfile, linkto, targetIsDir) -#define assertSetNodump(path) \ - assertion_set_nodump(__FILE__, __LINE__, path) -#define assertUmask(mask) \ - assertion_umask(__FILE__, __LINE__, mask) -/* Assert that two files have unequal file flags */ -#define assertUnequalFflags(patha, pathb) \ - assertion_compare_fflags(__FILE__, __LINE__, patha, pathb, 1) -#define assertUtimes(pathname, atime, atime_nsec, mtime, mtime_nsec) \ - assertion_utimes(__FILE__, __LINE__, pathname, atime, atime_nsec, mtime, mtime_nsec) -#ifndef PROGRAM -#define assertEntrySetAcls(entry, acls, count) \ - assertion_entry_set_acls(__FILE__, __LINE__, entry, acls, count) -#define assertEntryCompareAcls(entry, acls, count, type, mode) \ - assertion_entry_compare_acls(__FILE__, __LINE__, entry, acls, count, type, mode) -#endif - -/* - * This would be simple with C99 variadic macros, but I don't want to - * require that. Instead, I insert a function call before each - * skipping() call to pass the file and line information down. Crude, - * but effective. - */ -#define skipping \ - skipping_setup(__FILE__, __LINE__);test_skipping - -/* Function declarations. These are defined in test_utility.c. */ -void failure(const char *fmt, ...) __LA_PRINTFLIKE(1, 2); -int assertion_assert(const char *, int, int, const char *, void *); -int assertion_chdir(const char *, int, const char *); -int assertion_chmod(const char *, int, const char *, int); -int assertion_compare_fflags(const char *, int, const char *, const char *, - int); -int assertion_empty_file(const char *, int, const char *); -int assertion_equal_file(const char *, int, const char *, const char *); -int assertion_equal_int(const char *, int, long long, const char *, long long, const char *, void *); -int assertion_equal_mem(const char *, int, const void *, const char *, const void *, const char *, size_t, const char *, void *); -int assertion_memory_filled_with(const char *, int, const void *, const char *, size_t, const char *, char, const char *, void *); -int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *, int); -int assertion_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *); -int assertion_file_atime(const char *, int, const char *, long, long); -int assertion_file_atime_recent(const char *, int, const char *); -int assertion_file_birthtime(const char *, int, const char *, long, long); -int assertion_file_birthtime_recent(const char *, int, const char *); -int assertion_file_contains_lines_any_order(const char *, int, const char *, const char **); -int assertion_file_contains_no_invalid_strings(const char *, int, const char *, const char **); -int assertion_file_contents(const char *, int, const void *, int, const char *); -int assertion_file_exists(const char *, int, const char *); -int assertion_file_mode(const char *, int, const char *, int); -int assertion_file_mtime(const char *, int, const char *, long, long); -int assertion_file_mtime_recent(const char *, int, const char *); -int assertion_file_nlinks(const char *, int, const char *, int); -int assertion_file_not_exists(const char *, int, const char *); -int assertion_file_size(const char *, int, const char *, long); -int assertion_is_dir(const char *, int, const char *, int); -int assertion_is_hardlink(const char *, int, const char *, const char *); -int assertion_is_not_hardlink(const char *, int, const char *, const char *); -int assertion_is_reg(const char *, int, const char *, int); -int assertion_is_symlink(const char *, int, const char *, const char *, int); -int assertion_make_dir(const char *, int, const char *, int); -int assertion_make_file(const char *, int, const char *, int, int, const void *); -int assertion_make_hardlink(const char *, int, const char *newpath, const char *); -int assertion_make_symlink(const char *, int, const char *newpath, const char *, int); -int assertion_non_empty_file(const char *, int, const char *); -int assertion_set_nodump(const char *, int, const char *); -int assertion_text_file_contents(const char *, int, const char *buff, const char *f); -int assertion_umask(const char *, int, int); -int assertion_utimes(const char *, int, const char *, long, long, long, long ); -int assertion_version(const char*, int, const char *, const char *); - -void skipping_setup(const char *, int); -void test_skipping(const char *fmt, ...) __LA_PRINTFLIKE(1, 2); - -/* Like sprintf, then system() */ -int systemf(const char *fmt, ...) __LA_PRINTFLIKE(1, 2); - -/* Delay until time() returns a value after this. */ -void sleepUntilAfter(time_t); - -/* Return true if this platform can create symlinks. */ -int canSymlink(void); - -/* Return true if this platform can run the "bzip2" program. */ -int canBzip2(void); - -/* Return true if this platform can run the "grzip" program. */ -int canGrzip(void); - -/* Return true if this platform can run the "gzip" program. */ -int canGzip(void); - -/* Return true if this platform can run the specified command. */ -int canRunCommand(const char *); - -/* Return true if this platform can run the "lrzip" program. */ -int canLrzip(void); - -/* Return true if this platform can run the "lz4" program. */ -int canLz4(void); - -/* Return true if this platform can run the "zstd" program. */ -int canZstd(void); - -/* Return true if this platform can run the "lzip" program. */ -int canLzip(void); - -/* Return true if this platform can run the "lzma" program. */ -int canLzma(void); - -/* Return true if this platform can run the "lzop" program. */ -int canLzop(void); - -/* Return true if this platform can run the "xz" program. */ -int canXz(void); - -/* Return true if this filesystem can handle nodump flags. */ -int canNodump(void); - -/* Set test ACLs */ -int setTestAcl(const char *path); - -/* Get extended attribute */ -void *getXattr(const char *, const char *, size_t *); - -/* Set extended attribute */ -int setXattr(const char *, const char *, const void *, size_t); - -/* Return true if the file has large i-node number(>0xffffffff). */ -int is_LargeInode(const char *); - -#if ARCHIVE_ACL_SUNOS -/* Fetch ACLs on Solaris using acl() or facl() */ -void *sunacl_get(int cmd, int *aclcnt, int fd, const char *path); -#endif - -/* Suck file into string allocated via malloc(). Call free() when done. */ -/* Supports printf-style args: slurpfile(NULL, "%s/myfile", refdir); */ -char *slurpfile(size_t *, const char *fmt, ...) __LA_PRINTFLIKE(2, 3); - -/* Dump block of bytes to a file. */ -void dumpfile(const char *filename, void *, size_t); - -/* Extracts named reference file to the current directory. */ -void extract_reference_file(const char *); -/* Copies named reference file to the current directory. */ -void copy_reference_file(const char *); - -/* Extracts a list of files to the current directory. - * List must be NULL terminated. - */ -void extract_reference_files(const char **); - -/* Subtract umask from mode */ -mode_t umasked(mode_t expected_mode); - -/* Path to working directory for current test */ -extern const char *testworkdir; - -#ifndef PROGRAM -/* - * Special interfaces for libarchive test harness. - */ - -#include "archive.h" -#include "archive_entry.h" - -/* ACL structure */ -struct archive_test_acl_t { - int type; /* Type of ACL */ - int permset; /* Permissions for this class of users. */ - int tag; /* Owner, User, Owning group, group, other, etc. */ - int qual; /* GID or UID of user/group, depending on tag. */ - const char *name; /* Name of user/group, depending on tag. */ -}; - -/* Set ACLs */ -int assertion_entry_set_acls(const char *, int, struct archive_entry *, - struct archive_test_acl_t *, int); - -/* Compare ACLs */ -int assertion_entry_compare_acls(const char *, int, struct archive_entry *, - struct archive_test_acl_t *, int, int, int); - -/* Special customized read-from-memory interface. */ -int read_open_memory(struct archive *, const void *, size_t, size_t); -/* _minimal version exercises a slightly different set of libarchive APIs. */ -int read_open_memory_minimal(struct archive *, const void *, size_t, size_t); -/* _seek version produces a seekable file. */ -int read_open_memory_seek(struct archive *, const void *, size_t, size_t); - -/* Versions of above that accept an archive argument for additional info. */ -#define assertA(e) assertion_assert(__FILE__, __LINE__, (e), #e, (a)) -#define assertEqualIntA(a,v1,v2) \ - assertion_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (a)) -#define assertEqualStringA(a,v1,v2) \ - assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (a), 0) - -#else /* defined(PROGRAM) */ -/* - * Special interfaces for program test harness. - */ - -/* Pathname of exe to be tested. */ -extern const char *testprogfile; -/* Name of exe to use in printf-formatted command strings. */ -/* On Windows, this includes leading/trailing quotes. */ -extern const char *testprog; - -void assertVersion(const char *prog, const char *base); - -#endif /* defined(PROGRAM) */ - -#ifdef USE_DMALLOC -#include -#endif - -#include "test_utils.h" - -#endif /* TEST_COMMON_H */ diff --git a/thirdparty/libarchive/test_utils/test_main.c b/thirdparty/libarchive/test_utils/test_main.c deleted file mode 100644 index e4b884ee3..000000000 --- a/thirdparty/libarchive/test_utils/test_main.c +++ /dev/null @@ -1,4236 +0,0 @@ -/* - * Copyright (c) 2003-2009 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test.h" -#include "test_utils.h" -#ifdef HAVE_SYS_IOCTL_H -#include -#endif -#ifdef HAVE_SYS_TIME_H -#include -#endif -#include -#ifdef HAVE_ICONV_H -#include -#endif -/* - * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h. - * As the include guards don't agree, the order of include is important. - */ -#ifdef HAVE_LINUX_EXT2_FS_H -#include /* for Linux file flags */ -#endif -#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__) -#include /* Linux file flags, broken on Cygwin */ -#endif -#ifdef HAVE_LINUX_FS_H -#include -#endif -#include -#include -#ifdef HAVE_SIGNAL_H -#include -#endif -#include -#include - -#ifdef HAVE_SIGNAL_H -#endif -#ifdef HAVE_ACL_LIBACL_H -#include -#endif -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_ACL_H -#include -#endif -#ifdef HAVE_SYS_EA_H -#include -#endif -#ifdef HAVE_SYS_EXTATTR_H -#include -#endif -#if HAVE_SYS_XATTR_H -#include -#elif HAVE_ATTR_XATTR_H -#include -#endif -#ifdef HAVE_SYS_RICHACL_H -#include -#endif -#if HAVE_MEMBERSHIP_H -#include -#endif - -/* - * - * Windows support routines - * - * Note: Configuration is a tricky issue. Using HAVE_* feature macros - * in the test harness is dangerous because they cover up - * configuration errors. The classic example of this is omitting a - * configure check. If libarchive and libarchive_test both look for - * the same feature macro, such errors are hard to detect. Platform - * macros (e.g., _WIN32 or __GNUC__) are a little better, but can - * easily lead to very messy code. It's best to limit yourself - * to only the most generic programming techniques in the test harness - * and thus avoid conditionals altogether. Where that's not possible, - * try to minimize conditionals by grouping platform-specific tests in - * one place (e.g., test_acl_freebsd) or by adding new assert() - * functions (e.g., assertMakeHardlink()) to cover up platform - * differences. Platform-specific coding in libarchive_test is often - * a symptom that some capability is missing from libarchive itself. - */ -#if defined(_WIN32) && !defined(__CYGWIN__) -#include -#include -#include -#ifndef F_OK -#define F_OK (0) -#endif -#ifndef S_ISDIR -#define S_ISDIR(m) ((m) & _S_IFDIR) -#endif -#ifndef S_ISREG -#define S_ISREG(m) ((m) & _S_IFREG) -#endif -#if !defined(__BORLANDC__) -#define access _access -#undef chdir -#define chdir _chdir -#endif -#ifndef fileno -#define fileno _fileno -#endif -/*#define fstat _fstat64*/ -#if !defined(__BORLANDC__) -#define getcwd _getcwd -#endif -#define lstat stat -/*#define lstat _stat64*/ -/*#define stat _stat64*/ -#define rmdir _rmdir -#if !defined(__BORLANDC__) -#define strdup _strdup -#define umask _umask -#endif -#define int64_t __int64 -#endif - -#if defined(HAVE__CrtSetReportMode) -# include -#endif - -mode_t umasked(mode_t expected_mode) -{ - mode_t mode = umask(0); - umask(mode); - return expected_mode & ~mode; -} - -/* Path to working directory for current test */ -const char *testworkdir; -#ifdef PROGRAM -/* Pathname of exe to be tested. */ -const char *testprogfile; -/* Name of exe to use in printf-formatted command strings. */ -/* On Windows, this includes leading/trailing quotes. */ -const char *testprog; -#endif - -#if defined(_WIN32) && !defined(__CYGWIN__) -static void *GetFunctionKernel32(const char *); -static int my_CreateSymbolicLinkA(const char *, const char *, int); -static int my_CreateHardLinkA(const char *, const char *); -static int my_GetFileInformationByName(const char *, - BY_HANDLE_FILE_INFORMATION *); - -typedef struct _REPARSE_DATA_BUFFER { - ULONG ReparseTag; - USHORT ReparseDataLength; - USHORT Reserved; - union { - struct { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - ULONG Flags; - WCHAR PathBuffer[1]; - } SymbolicLinkReparseBuffer; - struct { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - WCHAR PathBuffer[1]; - } MountPointReparseBuffer; - struct { - UCHAR DataBuffer[1]; - } GenericReparseBuffer; - } DUMMYUNIONNAME; -} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; - -static void * -GetFunctionKernel32(const char *name) -{ - static HINSTANCE lib; - static int set; - if (!set) { - set = 1; - lib = LoadLibrary("kernel32.dll"); - } - if (lib == NULL) { - fprintf(stderr, "Can't load kernel32.dll?!\n"); - exit(1); - } - return (void *)GetProcAddress(lib, name); -} - -static int -my_CreateSymbolicLinkA(const char *linkname, const char *target, - int targetIsDir) -{ - static BOOLEAN (WINAPI *f)(LPCSTR, LPCSTR, DWORD); - DWORD attrs; - static int set; - int ret, tmpflags, llen, tlen; - int flags = 0; - char *src, *tgt, *p; - if (!set) { - set = 1; - f = GetFunctionKernel32("CreateSymbolicLinkA"); - } - if (f == NULL) - return (0); - - tlen = strlen(target); - llen = strlen(linkname); - - if (tlen == 0 || llen == 0) - return (0); - - tgt = malloc((tlen + 1) * sizeof(char)); - if (tgt == NULL) - return (0); - src = malloc((llen + 1) * sizeof(char)); - if (src == NULL) { - free(tgt); - return (0); - } - - /* - * Translate slashes to backslashes - */ - p = src; - while(*linkname != '\0') { - if (*linkname == '/') - *p = '\\'; - else - *p = *linkname; - linkname++; - p++; - } - *p = '\0'; - - p = tgt; - while(*target != '\0') { - if (*target == '/') - *p = '\\'; - else - *p = *target; - target++; - p++; - } - *p = '\0'; - - /* - * Each test has to specify if a file or a directory symlink - * should be created. - */ - if (targetIsDir) { -#if defined(SYMBOLIC_LINK_FLAG_DIRECTORY) - flags |= SYMBOLIC_LINK_FLAG_DIRECTORY; -#else - flags |= 0x1; -#endif - } - -#if defined(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE) - tmpflags = flags | SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE; -#else - tmpflags = flags | 0x2; -#endif - /* - * Windows won't overwrite existing links - */ - attrs = GetFileAttributesA(linkname); - if (attrs != INVALID_FILE_ATTRIBUTES) { - if (attrs & FILE_ATTRIBUTE_DIRECTORY) - RemoveDirectoryA(linkname); - else - DeleteFileA(linkname); - } - - ret = (*f)(src, tgt, tmpflags); - /* - * Prior to Windows 10 the SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE - * is not understood - */ - if (!ret) - ret = (*f)(src, tgt, flags); - - free(src); - free(tgt); - return (ret); -} - -static int -my_CreateHardLinkA(const char *linkname, const char *target) -{ - static BOOLEAN (WINAPI *f)(LPCSTR, LPCSTR, LPSECURITY_ATTRIBUTES); - static int set; - if (!set) { - set = 1; - f = GetFunctionKernel32("CreateHardLinkA"); - } - return f == NULL ? 0 : (*f)(linkname, target, NULL); -} - -static int -my_GetFileInformationByName(const char *path, BY_HANDLE_FILE_INFORMATION *bhfi) -{ - HANDLE h; - int r; - - memset(bhfi, 0, sizeof(*bhfi)); - h = CreateFileA(path, FILE_READ_ATTRIBUTES, 0, NULL, - OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); - if (h == INVALID_HANDLE_VALUE) - return (0); - r = GetFileInformationByHandle(h, bhfi); - CloseHandle(h); - return (r); -} -#endif - -#if defined(HAVE__CrtSetReportMode) && !defined(__WATCOMC__) -static void -invalid_parameter_handler(const wchar_t * expression, - const wchar_t * function, const wchar_t * file, - unsigned int line, uintptr_t pReserved) -{ - /* nop */ - // Silence unused-parameter compiler warnings. - (void)expression; - (void)function; - (void)file; - (void)line; - (void)pReserved; -} -#endif - -/* - * - * OPTIONS FLAGS - * - */ - -/* Enable core dump on failure. */ -static int dump_on_failure = 0; -/* Default is to remove temp dirs and log data for successful tests. */ -static int keep_temp_files = 0; -/* Default is to run the specified tests once and report errors. */ -static int until_failure = 0; -/* Default is to just report pass/fail for each test. */ -static int verbosity = 0; -#define VERBOSITY_SUMMARY_ONLY -1 /* -q */ -#define VERBOSITY_PASSFAIL 0 /* Default */ -#define VERBOSITY_LIGHT_REPORT 1 /* -v */ -#define VERBOSITY_FULL 2 /* -vv */ -/* A few places generate even more output for verbosity > VERBOSITY_FULL, - * mostly for debugging the test harness itself. */ -/* Cumulative count of assertion failures. */ -static int failures = 0; -/* Cumulative count of reported skips. */ -static int skips = 0; -/* Cumulative count of assertions checked. */ -static int assertions = 0; - -/* Directory where uuencoded reference files can be found. */ -static const char *refdir; - -/* - * Report log information selectively to console and/or disk log. - */ -static int log_console = 0; -static FILE *logfile; -static void __LA_PRINTFLIKE(1, 0) -vlogprintf(const char *fmt, va_list ap) -{ -#ifdef va_copy - va_list lfap; - va_copy(lfap, ap); -#endif - if (log_console) - vfprintf(stdout, fmt, ap); - if (logfile != NULL) -#ifdef va_copy - vfprintf(logfile, fmt, lfap); - va_end(lfap); -#else - vfprintf(logfile, fmt, ap); -#endif -} - -static void __LA_PRINTFLIKE(1, 2) -logprintf(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vlogprintf(fmt, ap); - va_end(ap); -} - -/* Set up a message to display only if next assertion fails. */ -static char msgbuff[4096]; -static const char *msg, *nextmsg; -void -failure(const char *fmt, ...) -{ - va_list ap; - if (fmt == NULL) { - nextmsg = NULL; - } else { - va_start(ap, fmt); - vsnprintf(msgbuff, sizeof(msgbuff), fmt, ap); - va_end(ap); - nextmsg = msgbuff; - } -} - -/* - * Copy arguments into file-local variables. - * This was added to permit vararg assert() functions without needing - * variadic wrapper macros. Turns out that the vararg capability is almost - * never used, so almost all of the vararg assertions can be simplified - * by removing the vararg capability and reworking the wrapper macro to - * pass __FILE__, __LINE__ directly into the function instead of using - * this hook. I suspect this machinery is used so rarely that we - * would be better off just removing it entirely. That would simplify - * the code here noticeably. - */ -static const char *skipping_filename; -static int skipping_line; -void skipping_setup(const char *filename, int line) -{ - skipping_filename = filename; - skipping_line = line; -} - -/* Called at the beginning of each assert() function. */ -static void -assertion_count(const char *file, int line) -{ - (void)file; /* UNUSED */ - (void)line; /* UNUSED */ - ++assertions; - /* Proper handling of "failure()" message. */ - msg = nextmsg; - nextmsg = NULL; - /* Uncomment to print file:line after every assertion. - * Verbose, but occasionally useful in tracking down crashes. */ - /* printf("Checked %s:%d\n", file, line); */ -} - -/* - * For each test source file, we remember how many times each - * assertion was reported. Cleared before each new test, - * used by test_summarize(). - */ -static struct line { - int count; - int skip; -} failed_lines[10000]; -static const char *failed_filename; - -/* Count this failure, setup up log destination and handle initial report. */ -static void __LA_PRINTFLIKE(3, 4) -failure_start(const char *filename, int line, const char *fmt, ...) -{ - va_list ap; - - /* Record another failure for this line. */ - ++failures; - failed_filename = filename; - failed_lines[line].count++; - - /* Determine whether to log header to console. */ - switch (verbosity) { - case VERBOSITY_LIGHT_REPORT: - log_console = (failed_lines[line].count < 2); - break; - default: - log_console = (verbosity >= VERBOSITY_FULL); - } - - /* Log file:line header for this failure */ - va_start(ap, fmt); -#if _MSC_VER - logprintf("%s(%d): ", filename, line); -#else - logprintf("%s:%d: ", filename, line); -#endif - vlogprintf(fmt, ap); - va_end(ap); - logprintf("\n"); - - if (msg != NULL && msg[0] != '\0') { - logprintf(" Description: %s\n", msg); - msg = NULL; - } - - /* Determine whether to log details to console. */ - if (verbosity == VERBOSITY_LIGHT_REPORT) - log_console = 0; -} - -/* Complete reporting of failed tests. */ -/* - * The 'extra' hook here is used by libarchive to include libarchive - * error messages with assertion failures. It could also be used - * to add strerror() output, for example. Just define the EXTRA_DUMP() - * macro appropriately. - */ -static void -failure_finish(void *extra) -{ - (void)extra; /* UNUSED (maybe) */ -#ifdef EXTRA_DUMP - if (extra != NULL) { - logprintf(" errno: %d\n", EXTRA_ERRNO(extra)); - logprintf(" detail: %s\n", EXTRA_DUMP(extra)); - } -#endif - - if (dump_on_failure) { - fprintf(stderr, - " *** forcing core dump so failure can be debugged ***\n"); - abort(); - } -} - -/* Inform user that we're skipping some checks. */ -void -test_skipping(const char *fmt, ...) -{ - char buff[1024]; - va_list ap; - - va_start(ap, fmt); - vsnprintf(buff, sizeof(buff), fmt, ap); - va_end(ap); - /* Use failure() message if set. */ - msg = nextmsg; - nextmsg = NULL; - /* failure_start() isn't quite right, but is awfully convenient. */ - failure_start(skipping_filename, skipping_line, "SKIPPING: %s", buff); - --failures; /* Undo failures++ in failure_start() */ - /* Don't failure_finish() here. */ - /* Mark as skip, so doesn't count as failed test. */ - failed_lines[skipping_line].skip = 1; - ++skips; -} - -/* - * - * ASSERTIONS - * - */ - -/* Generic assert() just displays the failed condition. */ -int -assertion_assert(const char *file, int line, int value, - const char *condition, void *extra) -{ - assertion_count(file, line); - if (!value) { - failure_start(file, line, "Assertion failed: %s", condition); - failure_finish(extra); - } - return (value); -} - -/* chdir() and report any errors */ -int -assertion_chdir(const char *file, int line, const char *pathname) -{ - assertion_count(file, line); - if (chdir(pathname) == 0) - return (1); - failure_start(file, line, "chdir(\"%s\")", pathname); - failure_finish(NULL); - return (0); - -} - -/* change file/directory permissions and errors if it fails */ -int -assertion_chmod(const char *file, int line, const char *pathname, int mode) -{ - assertion_count(file, line); - if (chmod(pathname, mode) == 0) - return (1); - failure_start(file, line, "chmod(\"%s\", %4.o)", pathname, mode); - failure_finish(NULL); - return (0); - -} - -/* Verify two integers are equal. */ -int -assertion_equal_int(const char *file, int line, - long long v1, const char *e1, long long v2, const char *e2, void *extra) -{ - assertion_count(file, line); - if (v1 == v2) - return (1); - failure_start(file, line, "%s != %s", e1, e2); - logprintf(" %s=%lld (0x%llx, 0%llo)\n", e1, v1, v1, v1); - logprintf(" %s=%lld (0x%llx, 0%llo)\n", e2, v2, v2, v2); - failure_finish(extra); - return (0); -} - -/* - * Utility to convert a single UTF-8 sequence. - */ -static int -_utf8_to_unicode(uint32_t *pwc, const char *s, size_t n) -{ - static const char utf8_count[256] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 00 - 0F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 10 - 1F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 20 - 2F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 30 - 3F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40 - 4F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 50 - 5F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 60 - 6F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 70 - 7F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 80 - 8F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 90 - 9F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* A0 - AF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* B0 - BF */ - 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,/* C0 - CF */ - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,/* D0 - DF */ - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,/* E0 - EF */ - 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* F0 - FF */ - }; - int ch; - int cnt; - uint32_t wc; - - *pwc = 0; - - /* Sanity check. */ - if (n == 0) - return (0); - /* - * Decode 1-4 bytes depending on the value of the first byte. - */ - ch = (unsigned char)*s; - if (ch == 0) - return (0); /* Standard: return 0 for end-of-string. */ - cnt = utf8_count[ch]; - - /* Invalid sequence or there are not plenty bytes. */ - if (n < (size_t)cnt) - return (-1); - - /* Make a Unicode code point from a single UTF-8 sequence. */ - switch (cnt) { - case 1: /* 1 byte sequence. */ - *pwc = ch & 0x7f; - return (cnt); - case 2: /* 2 bytes sequence. */ - if ((s[1] & 0xc0) != 0x80) return (-1); - *pwc = ((ch & 0x1f) << 6) | (s[1] & 0x3f); - return (cnt); - case 3: /* 3 bytes sequence. */ - if ((s[1] & 0xc0) != 0x80) return (-1); - if ((s[2] & 0xc0) != 0x80) return (-1); - wc = ((ch & 0x0f) << 12) - | ((s[1] & 0x3f) << 6) - | (s[2] & 0x3f); - if (wc < 0x800) - return (-1);/* Overlong sequence. */ - break; - case 4: /* 4 bytes sequence. */ - if (n < 4) - return (-1); - if ((s[1] & 0xc0) != 0x80) return (-1); - if ((s[2] & 0xc0) != 0x80) return (-1); - if ((s[3] & 0xc0) != 0x80) return (-1); - wc = ((ch & 0x07) << 18) - | ((s[1] & 0x3f) << 12) - | ((s[2] & 0x3f) << 6) - | (s[3] & 0x3f); - if (wc < 0x10000) - return (-1);/* Overlong sequence. */ - break; - default: - return (-1); - } - - /* The code point larger than 0x10FFFF is not legal - * Unicode values. */ - if (wc > 0x10FFFF) - return (-1); - /* Correctly gets a Unicode, returns used bytes. */ - *pwc = wc; - return (cnt); -} - -static void strdump(const char *e, const char *p, int ewidth, int utf8) -{ - const char *q = p; - - logprintf(" %*s = ", ewidth, e); - if (p == NULL) { - logprintf("NULL\n"); - return; - } - logprintf("\""); - while (*p != '\0') { - unsigned int c = 0xff & *p++; - switch (c) { - case '\a': logprintf("\\a"); break; - case '\b': logprintf("\\b"); break; - case '\n': logprintf("\\n"); break; - case '\r': logprintf("\\r"); break; - default: - if (c >= 32 && c < 127) - logprintf("%c", c); - else - logprintf("\\x%02X", c); - } - } - logprintf("\""); - logprintf(" (length %d)", q == NULL ? -1 : (int)strlen(q)); - - /* - * If the current string is UTF-8, dump its code points. - */ - if (utf8) { - size_t len; - uint32_t uc; - int n; - int cnt = 0; - - p = q; - len = strlen(p); - logprintf(" ["); - while ((n = _utf8_to_unicode(&uc, p, len)) > 0) { - if (p != q) - logprintf(" "); - logprintf("%04X", uc); - p += n; - len -= n; - cnt++; - } - logprintf("]"); - logprintf(" (count %d", cnt); - if (n < 0) { - logprintf(",unknown %zu bytes", len); - } - logprintf(")"); - - } - logprintf("\n"); -} - -/* Verify two strings are equal, dump them if not. */ -int -assertion_equal_string(const char *file, int line, - const char *v1, const char *e1, - const char *v2, const char *e2, - void *extra, int utf8) -{ - int l1, l2; - - assertion_count(file, line); - if (v1 == v2 || (v1 != NULL && v2 != NULL && strcmp(v1, v2) == 0)) - return (1); - failure_start(file, line, "%s != %s", e1, e2); - l1 = (int)strlen(e1); - l2 = (int)strlen(e2); - if (l1 < l2) - l1 = l2; - strdump(e1, v1, l1, utf8); - strdump(e2, v2, l1, utf8); - failure_finish(extra); - return (0); -} - -static void -wcsdump(const char *e, const wchar_t *w) -{ - logprintf(" %s = ", e); - if (w == NULL) { - logprintf("(null)"); - return; - } - logprintf("\""); - while (*w != L'\0') { - unsigned int c = *w++; - if (c >= 32 && c < 127) - logprintf("%c", c); - else if (c < 256) - logprintf("\\x%02X", c); - else if (c < 0x10000) - logprintf("\\u%04X", c); - else - logprintf("\\U%08X", c); - } - logprintf("\"\n"); -} - -#ifndef HAVE_WCSCMP -static int -wcscmp(const wchar_t *s1, const wchar_t *s2) -{ - - while (*s1 == *s2++) { - if (*s1++ == L'\0') - return 0; - } - if (*s1 > *--s2) - return 1; - else - return -1; -} -#endif - -/* Verify that two wide strings are equal, dump them if not. */ -int -assertion_equal_wstring(const char *file, int line, - const wchar_t *v1, const char *e1, - const wchar_t *v2, const char *e2, - void *extra) -{ - assertion_count(file, line); - if (v1 == v2) - return (1); - if (v1 != NULL && v2 != NULL && wcscmp(v1, v2) == 0) - return (1); - failure_start(file, line, "%s != %s", e1, e2); - wcsdump(e1, v1); - wcsdump(e2, v2); - failure_finish(extra); - return (0); -} - -/* - * Pretty standard hexdump routine. As a bonus, if ref != NULL, then - * any bytes in p that differ from ref will be highlighted with '_' - * before and after the hex value. - */ -static void -hexdump(const char *p, const char *ref, size_t l, size_t offset) -{ - size_t i, j; - char sep; - - if (p == NULL) { - logprintf("(null)\n"); - return; - } - for(i=0; i < l; i+=16) { - logprintf("%04x", (unsigned)(i + offset)); - sep = ' '; - for (j = 0; j < 16 && i + j < l; j++) { - if (ref != NULL && p[i + j] != ref[i + j]) - sep = '_'; - logprintf("%c%02x", sep, 0xff & (int)p[i+j]); - if (ref != NULL && p[i + j] == ref[i + j]) - sep = ' '; - } - for (; j < 16; j++) { - logprintf("%c ", sep); - sep = ' '; - } - logprintf("%c", sep); - for (j=0; j < 16 && i + j < l; j++) { - int c = p[i + j]; - if (c >= ' ' && c <= 126) - logprintf("%c", c); - else - logprintf("."); - } - logprintf("\n"); - } -} - -/* Verify that two blocks of memory are the same, display the first - * block of differences if they're not. */ -int -assertion_equal_mem(const char *file, int line, - const void *_v1, const char *e1, - const void *_v2, const char *e2, - size_t l, const char *ld, void *extra) -{ - const char *v1 = (const char *)_v1; - const char *v2 = (const char *)_v2; - size_t offset; - - assertion_count(file, line); - if (v1 == v2 || (v1 != NULL && v2 != NULL && memcmp(v1, v2, l) == 0)) - return (1); - if (v1 == NULL || v2 == NULL) - return (0); - - failure_start(file, line, "%s != %s", e1, e2); - logprintf(" size %s = %d\n", ld, (int)l); - /* Dump 48 bytes (3 lines) so that the first difference is - * in the second line. */ - offset = 0; - while (l > 64 && memcmp(v1, v2, 32) == 0) { - /* Two lines agree, so step forward one line. */ - v1 += 16; - v2 += 16; - l -= 16; - offset += 16; - } - logprintf(" Dump of %s\n", e1); - hexdump(v1, v2, l < 128 ? l : 128, offset); - logprintf(" Dump of %s\n", e2); - hexdump(v2, v1, l < 128 ? l : 128, offset); - logprintf("\n"); - failure_finish(extra); - return (0); -} - -/* Verify that a block of memory is filled with the specified byte. */ -int -assertion_memory_filled_with(const char *file, int line, - const void *_v1, const char *vd, - size_t l, const char *ld, - char b, const char *bd, void *extra) -{ - const char *v1 = (const char *)_v1; - size_t c = 0; - size_t i; - (void)ld; /* UNUSED */ - - assertion_count(file, line); - - for (i = 0; i < l; ++i) { - if (v1[i] == b) { - ++c; - } - } - if (c == l) - return (1); - - failure_start(file, line, "%s (size %d) not filled with %s", vd, (int)l, bd); - logprintf(" Only %d bytes were correct\n", (int)c); - failure_finish(extra); - return (0); -} - -/* Verify that the named file exists and is empty. */ -int -assertion_empty_file(const char *filename, int line, const char *f1) -{ - char buff[1024]; - struct stat st; - ssize_t s; - FILE *f; - - assertion_count(filename, line); - - if (stat(f1, &st) != 0) { - failure_start(filename, line, "Stat failed: %s", f1); - failure_finish(NULL); - return (0); - } - if (st.st_size == 0) - return (1); - - failure_start(filename, line, "File should be empty: %s", f1); - logprintf(" File size: %d\n", (int)st.st_size); - logprintf(" Contents:\n"); - f = fopen(f1, "rb"); - if (f == NULL) { - logprintf(" Unable to open %s\n", f1); - } else { - s = ((off_t)sizeof(buff) < st.st_size) ? - (ssize_t)sizeof(buff) : (ssize_t)st.st_size; - s = fread(buff, 1, s, f); - hexdump(buff, NULL, s, 0); - fclose(f); - } - failure_finish(NULL); - return (0); -} - -/* Verify that the named file exists and is not empty. */ -int -assertion_non_empty_file(const char *filename, int line, const char *f1) -{ - struct stat st; - - assertion_count(filename, line); - - if (stat(f1, &st) != 0) { - failure_start(filename, line, "Stat failed: %s", f1); - failure_finish(NULL); - return (0); - } - if (st.st_size == 0) { - failure_start(filename, line, "File empty: %s", f1); - failure_finish(NULL); - return (0); - } - return (1); -} - -/* Verify that two files have the same contents. */ -/* TODO: hexdump the first bytes that actually differ. */ -int -assertion_equal_file(const char *filename, int line, const char *fn1, const char *fn2) -{ - char buff1[1024]; - char buff2[1024]; - FILE *f1, *f2; - int n1, n2; - - assertion_count(filename, line); - - f1 = fopen(fn1, "rb"); - f2 = fopen(fn2, "rb"); - if (f1 == NULL || f2 == NULL) { - if (f1) fclose(f1); - if (f2) fclose(f2); - return (0); - } - for (;;) { - n1 = (int)fread(buff1, 1, sizeof(buff1), f1); - n2 = (int)fread(buff2, 1, sizeof(buff2), f2); - if (n1 != n2) - break; - if (n1 == 0 && n2 == 0) { - fclose(f1); - fclose(f2); - return (1); - } - if (memcmp(buff1, buff2, n1) != 0) - break; - } - fclose(f1); - fclose(f2); - failure_start(filename, line, "Files not identical"); - logprintf(" file1=\"%s\"\n", fn1); - logprintf(" file2=\"%s\"\n", fn2); - failure_finish(NULL); - return (0); -} - -/* Verify that the named file does exist. */ -int -assertion_file_exists(const char *filename, int line, const char *f) -{ - assertion_count(filename, line); - -#if defined(_WIN32) && !defined(__CYGWIN__) - if (!_access(f, 0)) - return (1); -#else - if (!access(f, F_OK)) - return (1); -#endif - failure_start(filename, line, "File should exist: %s", f); - failure_finish(NULL); - return (0); -} - -/* Verify that the named file doesn't exist. */ -int -assertion_file_not_exists(const char *filename, int line, const char *f) -{ - assertion_count(filename, line); - -#if defined(_WIN32) && !defined(__CYGWIN__) - if (_access(f, 0)) - return (1); -#else - if (access(f, F_OK)) - return (1); -#endif - failure_start(filename, line, "File should not exist: %s", f); - failure_finish(NULL); - return (0); -} - -/* Compare the contents of a file to a block of memory. */ -int -assertion_file_contents(const char *filename, int line, const void *buff, int s, const char *fn) -{ - char *contents; - FILE *f; - int n; - - assertion_count(filename, line); - - f = fopen(fn, "rb"); - if (f == NULL) { - failure_start(filename, line, - "File should exist: %s", fn); - failure_finish(NULL); - return (0); - } - contents = malloc(s * 2); - n = (int)fread(contents, 1, s * 2, f); - fclose(f); - if (n == s && memcmp(buff, contents, s) == 0) { - free(contents); - return (1); - } - failure_start(filename, line, "File contents don't match"); - logprintf(" file=\"%s\"\n", fn); - if (n > 0) - hexdump(contents, buff, n > 512 ? 512 : n, 0); - else { - logprintf(" File empty, contents should be:\n"); - hexdump(buff, NULL, s > 512 ? 512 : s, 0); - } - failure_finish(NULL); - free(contents); - return (0); -} - -/* Check the contents of a text file, being tolerant of line endings. */ -int -assertion_text_file_contents(const char *filename, int line, const char *buff, const char *fn) -{ - char *contents; - const char *btxt, *ftxt; - FILE *f; - int n, s; - - assertion_count(filename, line); - f = fopen(fn, "r"); - if (f == NULL) { - failure_start(filename, line, - "File doesn't exist: %s", fn); - failure_finish(NULL); - return (0); - } - s = (int)strlen(buff); - contents = malloc(s * 2 + 128); - n = (int)fread(contents, 1, s * 2 + 128 - 1, f); - if (n >= 0) - contents[n] = '\0'; - fclose(f); - /* Compare texts. */ - btxt = buff; - ftxt = (const char *)contents; - while (*btxt != '\0' && *ftxt != '\0') { - if (*btxt == *ftxt) { - ++btxt; - ++ftxt; - continue; - } - if (btxt[0] == '\n' && ftxt[0] == '\r' && ftxt[1] == '\n') { - /* Pass over different new line characters. */ - ++btxt; - ftxt += 2; - continue; - } - break; - } - if (*btxt == '\0' && *ftxt == '\0') { - free(contents); - return (1); - } - failure_start(filename, line, "Contents don't match"); - logprintf(" file=\"%s\"\n", fn); - if (n > 0) { - hexdump(contents, buff, n, 0); - logprintf(" expected\n"); - hexdump(buff, contents, s, 0); - } else { - logprintf(" File empty, contents should be:\n"); - hexdump(buff, NULL, s, 0); - } - failure_finish(NULL); - free(contents); - return (0); -} - -/* Verify that a text file contains the specified lines, regardless of order */ -/* This could be more efficient if we sorted both sets of lines, etc, but - * since this is used only for testing and only ever deals with a dozen or so - * lines at a time, this relatively crude approach is just fine. */ -int -assertion_file_contains_lines_any_order(const char *file, int line, - const char *pathname, const char *lines[]) -{ - char *buff; - size_t buff_size; - size_t expected_count, actual_count, i, j; - char **expected = NULL; - char *p, **actual = NULL; - char c; - int expected_failure = 0, actual_failure = 0; - - assertion_count(file, line); - - buff = slurpfile(&buff_size, "%s", pathname); - if (buff == NULL) { - failure_start(pathname, line, "Can't read file: %s", pathname); - failure_finish(NULL); - return (0); - } - - /* Make a copy of the provided lines and count up the expected - * file size. */ - for (i = 0; lines[i] != NULL; ++i) { - } - expected_count = i; - if (expected_count) { - expected = malloc(sizeof(char *) * expected_count); - if (expected == NULL) { - failure_start(pathname, line, "Can't allocate memory"); - failure_finish(NULL); - free(expected); - free(buff); - return (0); - } - for (i = 0; lines[i] != NULL; ++i) { - expected[i] = strdup(lines[i]); - } - } - - /* Break the file into lines */ - actual_count = 0; - for (c = '\0', p = buff; p < buff + buff_size; ++p) { - if (*p == '\x0d' || *p == '\x0a') - *p = '\0'; - if (c == '\0' && *p != '\0') - ++actual_count; - c = *p; - } - if (actual_count) { - actual = calloc(sizeof(char *), actual_count); - if (actual == NULL) { - failure_start(pathname, line, "Can't allocate memory"); - failure_finish(NULL); - free(expected); - free(buff); - return (0); - } - for (j = 0, p = buff; p < buff + buff_size; - p += 1 + strlen(p)) { - if (*p != '\0') { - actual[j] = p; - ++j; - } - } - } - - /* Erase matching lines from both lists */ - for (i = 0; i < expected_count; ++i) { - if (expected[i] == NULL) - continue; - for (j = 0; j < actual_count; ++j) { - if (actual[j] == NULL) - continue; - if (strcmp(expected[i], actual[j]) == 0) { - free(expected[i]); - expected[i] = NULL; - actual[j] = NULL; - break; - } - } - } - - /* If there's anything left, it's a failure */ - for (i = 0; i < expected_count; ++i) { - if (expected[i] != NULL) - ++expected_failure; - } - for (j = 0; j < actual_count; ++j) { - if (actual[j] != NULL) - ++actual_failure; - } - if (expected_failure == 0 && actual_failure == 0) { - free(buff); - free(expected); - free(actual); - return (1); - } - failure_start(file, line, "File doesn't match: %s", pathname); - for (i = 0; i < expected_count; ++i) { - if (expected[i] != NULL) { - logprintf(" Expected but not present: %s\n", expected[i]); - free(expected[i]); - } - } - for (j = 0; j < actual_count; ++j) { - if (actual[j] != NULL) - logprintf(" Present but not expected: %s\n", actual[j]); - } - failure_finish(NULL); - free(buff); - free(expected); - free(actual); - return (0); -} - -/* Verify that a text file does not contains the specified strings */ -int -assertion_file_contains_no_invalid_strings(const char *file, int line, - const char *pathname, const char *strings[]) -{ - char *buff; - int i; - - buff = slurpfile(NULL, "%s", pathname); - if (buff == NULL) { - failure_start(file, line, "Can't read file: %s", pathname); - failure_finish(NULL); - return (0); - } - - for (i = 0; strings[i] != NULL; ++i) { - if (strstr(buff, strings[i]) != NULL) { - failure_start(file, line, "Invalid string in %s: %s", pathname, - strings[i]); - failure_finish(NULL); - free(buff); - return(0); - } - } - - free(buff); - return (0); -} - -/* Test that two paths point to the same file. */ -/* As a side-effect, asserts that both files exist. */ -static int -is_hardlink(const char *file, int line, - const char *path1, const char *path2) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - BY_HANDLE_FILE_INFORMATION bhfi1, bhfi2; - int r; - - assertion_count(file, line); - r = my_GetFileInformationByName(path1, &bhfi1); - if (r == 0) { - failure_start(file, line, "File %s can't be inspected?", path1); - failure_finish(NULL); - return (0); - } - r = my_GetFileInformationByName(path2, &bhfi2); - if (r == 0) { - failure_start(file, line, "File %s can't be inspected?", path2); - failure_finish(NULL); - return (0); - } - return (bhfi1.dwVolumeSerialNumber == bhfi2.dwVolumeSerialNumber - && bhfi1.nFileIndexHigh == bhfi2.nFileIndexHigh - && bhfi1.nFileIndexLow == bhfi2.nFileIndexLow); -#else - struct stat st1, st2; - int r; - - assertion_count(file, line); - r = lstat(path1, &st1); - if (r != 0) { - failure_start(file, line, "File should exist: %s", path1); - failure_finish(NULL); - return (0); - } - r = lstat(path2, &st2); - if (r != 0) { - failure_start(file, line, "File should exist: %s", path2); - failure_finish(NULL); - return (0); - } - return (st1.st_ino == st2.st_ino && st1.st_dev == st2.st_dev); -#endif -} - -int -assertion_is_hardlink(const char *file, int line, - const char *path1, const char *path2) -{ - if (is_hardlink(file, line, path1, path2)) - return (1); - failure_start(file, line, - "Files %s and %s are not hardlinked", path1, path2); - failure_finish(NULL); - return (0); -} - -int -assertion_is_not_hardlink(const char *file, int line, - const char *path1, const char *path2) -{ - if (!is_hardlink(file, line, path1, path2)) - return (1); - failure_start(file, line, - "Files %s and %s should not be hardlinked", path1, path2); - failure_finish(NULL); - return (0); -} - -/* Verify a/b/mtime of 'pathname'. */ -/* If 'recent', verify that it's within last 10 seconds. */ -static int -assertion_file_time(const char *file, int line, - const char *pathname, long t, long nsec, char type, int recent) -{ - long long filet, filet_nsec; - int r; - -#if defined(_WIN32) && !defined(__CYGWIN__) -#define EPOC_TIME (116444736000000000ULL) - FILETIME fxtime, fbirthtime, fatime, fmtime; - ULARGE_INTEGER wintm; - HANDLE h; - fxtime.dwLowDateTime = 0; - fxtime.dwHighDateTime = 0; - - assertion_count(file, line); - /* Note: FILE_FLAG_BACKUP_SEMANTICS applies to open - * a directory file. If not, CreateFile() will fail when - * the pathname is a directory. */ - h = CreateFileA(pathname, FILE_READ_ATTRIBUTES, 0, NULL, - OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); - if (h == INVALID_HANDLE_VALUE) { - failure_start(file, line, "Can't access %s\n", pathname); - failure_finish(NULL); - return (0); - } - r = GetFileTime(h, &fbirthtime, &fatime, &fmtime); - switch (type) { - case 'a': fxtime = fatime; break; - case 'b': fxtime = fbirthtime; break; - case 'm': fxtime = fmtime; break; - } - CloseHandle(h); - if (r == 0) { - failure_start(file, line, "Can't GetFileTime %s\n", pathname); - failure_finish(NULL); - return (0); - } - wintm.LowPart = fxtime.dwLowDateTime; - wintm.HighPart = fxtime.dwHighDateTime; - filet = (wintm.QuadPart - EPOC_TIME) / 10000000; - filet_nsec = ((wintm.QuadPart - EPOC_TIME) % 10000000) * 100; - nsec = (nsec / 100) * 100; /* Round the request */ -#else - struct stat st; - - assertion_count(file, line); - r = lstat(pathname, &st); - if (r != 0) { - failure_start(file, line, "Can't stat %s\n", pathname); - failure_finish(NULL); - return (0); - } - switch (type) { - case 'a': filet = st.st_atime; break; - case 'm': filet = st.st_mtime; break; - case 'b': filet = 0; break; - default: fprintf(stderr, "INTERNAL: Bad type %c for file time", type); - exit(1); - } -#if defined(__FreeBSD__) - switch (type) { - case 'a': filet_nsec = st.st_atimespec.tv_nsec; break; - case 'b': filet = st.st_birthtime; - /* FreeBSD filesystems that don't support birthtime - * (e.g., UFS1) always return -1 here. */ - if (filet == -1) { - return (1); - } - filet_nsec = st.st_birthtimespec.tv_nsec; break; - case 'm': filet_nsec = st.st_mtimespec.tv_nsec; break; - default: fprintf(stderr, "INTERNAL: Bad type %c for file time", type); - exit(1); - } - /* FreeBSD generally only stores to microsecond res, so round. */ - filet_nsec = (filet_nsec / 1000) * 1000; - nsec = (nsec / 1000) * 1000; -#else - filet_nsec = nsec = 0; /* Generic POSIX only has whole seconds. */ - if (type == 'b') return (1); /* Generic POSIX doesn't have birthtime */ -#if defined(__HAIKU__) - if (type == 'a') return (1); /* Haiku doesn't have atime. */ -#endif -#endif -#endif - if (recent) { - /* Check that requested time is up-to-date. */ - time_t now = time(NULL); - if (filet < now - 10 || filet > now + 1) { - failure_start(file, line, - "File %s has %ctime %lld, %lld seconds ago\n", - pathname, type, filet, now - filet); - failure_finish(NULL); - return (0); - } - } else if (filet != t || filet_nsec != nsec) { - failure_start(file, line, - "File %s has %ctime %lld.%09lld, expected %ld.%09ld", - pathname, type, filet, filet_nsec, t, nsec); - failure_finish(NULL); - return (0); - } - return (1); -} - -/* Verify atime of 'pathname'. */ -int -assertion_file_atime(const char *file, int line, - const char *pathname, long t, long nsec) -{ - return assertion_file_time(file, line, pathname, t, nsec, 'a', 0); -} - -/* Verify atime of 'pathname' is up-to-date. */ -int -assertion_file_atime_recent(const char *file, int line, const char *pathname) -{ - return assertion_file_time(file, line, pathname, 0, 0, 'a', 1); -} - -/* Verify birthtime of 'pathname'. */ -int -assertion_file_birthtime(const char *file, int line, - const char *pathname, long t, long nsec) -{ - return assertion_file_time(file, line, pathname, t, nsec, 'b', 0); -} - -/* Verify birthtime of 'pathname' is up-to-date. */ -int -assertion_file_birthtime_recent(const char *file, int line, - const char *pathname) -{ - return assertion_file_time(file, line, pathname, 0, 0, 'b', 1); -} - -/* Verify mode of 'pathname'. */ -int -assertion_file_mode(const char *file, int line, const char *pathname, int expected_mode) -{ - int mode; - int r; - - assertion_count(file, line); -#if defined(_WIN32) && !defined(__CYGWIN__) - failure_start(file, line, "assertFileMode not yet implemented for Windows"); - (void)mode; /* UNUSED */ - (void)r; /* UNUSED */ - (void)pathname; /* UNUSED */ - (void)expected_mode; /* UNUSED */ -#else - { - struct stat st; - r = lstat(pathname, &st); - mode = (int)(st.st_mode & 0777); - } - if (r == 0 && mode == expected_mode) - return (1); - failure_start(file, line, "File %s has mode %o, expected %o", - pathname, mode, expected_mode); -#endif - failure_finish(NULL); - return (0); -} - -/* Verify mtime of 'pathname'. */ -int -assertion_file_mtime(const char *file, int line, - const char *pathname, long t, long nsec) -{ - return assertion_file_time(file, line, pathname, t, nsec, 'm', 0); -} - -/* Verify mtime of 'pathname' is up-to-date. */ -int -assertion_file_mtime_recent(const char *file, int line, const char *pathname) -{ - return assertion_file_time(file, line, pathname, 0, 0, 'm', 1); -} - -/* Verify number of links to 'pathname'. */ -int -assertion_file_nlinks(const char *file, int line, - const char *pathname, int nlinks) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - BY_HANDLE_FILE_INFORMATION bhfi; - int r; - - assertion_count(file, line); - r = my_GetFileInformationByName(pathname, &bhfi); - if (r != 0 && bhfi.nNumberOfLinks == (DWORD)nlinks) - return (1); - failure_start(file, line, "File %s has %jd links, expected %d", - pathname, (intmax_t)bhfi.nNumberOfLinks, nlinks); - failure_finish(NULL); - return (0); -#else - struct stat st; - int r; - - assertion_count(file, line); - r = lstat(pathname, &st); - if (r == 0 && (int)st.st_nlink == nlinks) - return (1); - failure_start(file, line, "File %s has %jd links, expected %d", - pathname, (intmax_t)st.st_nlink, nlinks); - failure_finish(NULL); - return (0); -#endif -} - -/* Verify size of 'pathname'. */ -int -assertion_file_size(const char *file, int line, const char *pathname, long size) -{ - int64_t filesize; - int r; - - assertion_count(file, line); -#if defined(_WIN32) && !defined(__CYGWIN__) - { - BY_HANDLE_FILE_INFORMATION bhfi; - r = !my_GetFileInformationByName(pathname, &bhfi); - filesize = ((int64_t)bhfi.nFileSizeHigh << 32) + bhfi.nFileSizeLow; - } -#else - { - struct stat st; - r = lstat(pathname, &st); - filesize = st.st_size; - } -#endif - if (r == 0 && filesize == size) - return (1); - failure_start(file, line, "File %s has size %ld, expected %ld", - pathname, (long)filesize, (long)size); - failure_finish(NULL); - return (0); -} - -/* Assert that 'pathname' is a dir. If mode >= 0, verify that too. */ -int -assertion_is_dir(const char *file, int line, const char *pathname, int mode) -{ - struct stat st; - int r; - -#if defined(_WIN32) && !defined(__CYGWIN__) - (void)mode; /* UNUSED */ -#endif - assertion_count(file, line); - r = lstat(pathname, &st); - if (r != 0) { - failure_start(file, line, "Dir should exist: %s", pathname); - failure_finish(NULL); - return (0); - } - if (!S_ISDIR(st.st_mode)) { - failure_start(file, line, "%s is not a dir", pathname); - failure_finish(NULL); - return (0); - } -#if !defined(_WIN32) || defined(__CYGWIN__) - /* Windows doesn't handle permissions the same way as POSIX, - * so just ignore the mode tests. */ - /* TODO: Can we do better here? */ - if (mode >= 0 && (mode_t)mode != (st.st_mode & 07777)) { - failure_start(file, line, "Dir %s has wrong mode", pathname); - logprintf(" Expected: 0%3o\n", mode); - logprintf(" Found: 0%3o\n", st.st_mode & 07777); - failure_finish(NULL); - return (0); - } -#endif - return (1); -} - -/* Verify that 'pathname' is a regular file. If 'mode' is >= 0, - * verify that too. */ -int -assertion_is_reg(const char *file, int line, const char *pathname, int mode) -{ - struct stat st; - int r; - -#if defined(_WIN32) && !defined(__CYGWIN__) - (void)mode; /* UNUSED */ -#endif - assertion_count(file, line); - r = lstat(pathname, &st); - if (r != 0 || !S_ISREG(st.st_mode)) { - failure_start(file, line, "File should exist: %s", pathname); - failure_finish(NULL); - return (0); - } -#if !defined(_WIN32) || defined(__CYGWIN__) - /* Windows doesn't handle permissions the same way as POSIX, - * so just ignore the mode tests. */ - /* TODO: Can we do better here? */ - if (mode >= 0 && (mode_t)mode != (st.st_mode & 07777)) { - failure_start(file, line, "File %s has wrong mode", pathname); - logprintf(" Expected: 0%3o\n", mode); - logprintf(" Found: 0%3o\n", st.st_mode & 07777); - failure_finish(NULL); - return (0); - } -#endif - return (1); -} - -/* - * Check whether 'pathname' is a symbolic link. If 'contents' is - * non-NULL, verify that the symlink has those contents. - * - * On platforms with directory symlinks, set isdir to 0 to test for a file - * symlink and to 1 to test for a directory symlink. On other platforms - * the variable is ignored. - */ -static int -is_symlink(const char *file, int line, - const char *pathname, const char *contents, int isdir) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - HANDLE h; - DWORD inbytes; - REPARSE_DATA_BUFFER *buf; - BY_HANDLE_FILE_INFORMATION st; - size_t len, len2; - wchar_t *linknamew, *contentsw; - const char *p; - char *s, *pn; - int ret = 0; - BYTE *indata; - const DWORD flag = FILE_FLAG_BACKUP_SEMANTICS | - FILE_FLAG_OPEN_REPARSE_POINT; - - /* Replace slashes with backslashes in pathname */ - pn = malloc((strlen(pathname) + 1) * sizeof(char)); - p = pathname; - s = pn; - while(*p != '\0') { - if(*p == '/') - *s = '\\'; - else - *s = *p; - p++; - s++; - } - *s = '\0'; - - h = CreateFileA(pn, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, - flag, NULL); - free(pn); - if (h == INVALID_HANDLE_VALUE) { - failure_start(file, line, "Can't access %s\n", pathname); - failure_finish(NULL); - return (0); - } - ret = GetFileInformationByHandle(h, &st); - if (ret == 0) { - failure_start(file, line, - "Can't stat: %s", pathname); - failure_finish(NULL); - } else if ((st.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) == 0) { - failure_start(file, line, - "Not a symlink: %s", pathname); - failure_finish(NULL); - ret = 0; - } - if (isdir && ((st.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)) { - failure_start(file, line, - "Not a directory symlink: %s", pathname); - failure_finish(NULL); - ret = 0; - } - if (!isdir && - ((st.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)) { - failure_start(file, line, - "Not a file symlink: %s", pathname); - failure_finish(NULL); - ret = 0; - } - if (ret == 0) { - CloseHandle(h); - return (0); - } - - indata = malloc(MAXIMUM_REPARSE_DATA_BUFFER_SIZE); - ret = DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, NULL, 0, indata, - 1024, &inbytes, NULL); - CloseHandle(h); - if (ret == 0) { - free(indata); - failure_start(file, line, - "Could not retrieve symlink target: %s", pathname); - failure_finish(NULL); - return (0); - } - - buf = (REPARSE_DATA_BUFFER *) indata; - if (buf->ReparseTag != IO_REPARSE_TAG_SYMLINK) { - free(indata); - /* File is not a symbolic link */ - failure_start(file, line, - "Not a symlink: %s", pathname); - failure_finish(NULL); - return (0); - } - - if (contents == NULL) { - free(indata); - return (1); - } - - len = buf->SymbolicLinkReparseBuffer.SubstituteNameLength; - - linknamew = malloc(len + sizeof(wchar_t)); - if (linknamew == NULL) { - free(indata); - return (0); - } - - memcpy(linknamew, &((BYTE *)buf->SymbolicLinkReparseBuffer.PathBuffer) - [buf->SymbolicLinkReparseBuffer.SubstituteNameOffset], len); - free(indata); - - linknamew[len / sizeof(wchar_t)] = L'\0'; - - contentsw = malloc(len + sizeof(wchar_t)); - if (contentsw == NULL) { - free(linknamew); - return (0); - } - - len2 = mbsrtowcs(contentsw, &contents, (len + sizeof(wchar_t) - / sizeof(wchar_t)), NULL); - - if (len2 > 0 && wcscmp(linknamew, contentsw) != 0) - ret = 1; - - free(linknamew); - free(contentsw); - return (ret); -#else - char buff[300]; - struct stat st; - ssize_t linklen; - int r; - - (void)isdir; /* UNUSED */ - assertion_count(file, line); - r = lstat(pathname, &st); - if (r != 0) { - failure_start(file, line, - "Symlink should exist: %s", pathname); - failure_finish(NULL); - return (0); - } - if (!S_ISLNK(st.st_mode)) - return (0); - if (contents == NULL) - return (1); - linklen = readlink(pathname, buff, sizeof(buff) - 1); - if (linklen < 0) { - failure_start(file, line, "Can't read symlink %s", pathname); - failure_finish(NULL); - return (0); - } - buff[linklen] = '\0'; - if (strcmp(buff, contents) != 0) - return (0); - return (1); -#endif -} - -/* Assert that path is a symlink that (optionally) contains contents. */ -int -assertion_is_symlink(const char *file, int line, - const char *path, const char *contents, int isdir) -{ - if (is_symlink(file, line, path, contents, isdir)) - return (1); - if (contents) - failure_start(file, line, "File %s is not a symlink to %s", - path, contents); - else - failure_start(file, line, "File %s is not a symlink", path); - failure_finish(NULL); - return (0); -} - - -/* Create a directory and report any errors. */ -int -assertion_make_dir(const char *file, int line, const char *dirname, int mode) -{ - assertion_count(file, line); -#if defined(_WIN32) && !defined(__CYGWIN__) - (void)mode; /* UNUSED */ - if (0 == _mkdir(dirname)) - return (1); -#else - if (0 == mkdir(dirname, mode)) { - if (0 == chmod(dirname, mode)) { - assertion_file_mode(file, line, dirname, mode); - return (1); - } - } -#endif - failure_start(file, line, "Could not create directory %s", dirname); - failure_finish(NULL); - return(0); -} - -/* Create a file with the specified contents and report any failures. */ -int -assertion_make_file(const char *file, int line, - const char *path, int mode, int csize, const void *contents) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - /* TODO: Rework this to set file mode as well. */ - FILE *f; - (void)mode; /* UNUSED */ - assertion_count(file, line); - f = fopen(path, "wb"); - if (f == NULL) { - failure_start(file, line, "Could not create file %s", path); - failure_finish(NULL); - return (0); - } - if (contents != NULL) { - size_t wsize; - - if (csize < 0) - wsize = strlen(contents); - else - wsize = (size_t)csize; - if (wsize != fwrite(contents, 1, wsize, f)) { - fclose(f); - failure_start(file, line, - "Could not write file %s", path); - failure_finish(NULL); - return (0); - } - } - fclose(f); - return (1); -#else - int fd; - assertion_count(file, line); - fd = open(path, O_CREAT | O_WRONLY, mode >= 0 ? mode : 0644); - if (fd < 0) { - failure_start(file, line, "Could not create %s", path); - failure_finish(NULL); - return (0); - } -#ifdef HAVE_FCHMOD - if (0 != fchmod(fd, mode)) -#else - if (0 != chmod(path, mode)) -#endif - { - failure_start(file, line, "Could not chmod %s", path); - failure_finish(NULL); - close(fd); - return (0); - } - if (contents != NULL) { - ssize_t wsize; - - if (csize < 0) - wsize = (ssize_t)strlen(contents); - else - wsize = (ssize_t)csize; - if (wsize != write(fd, contents, wsize)) { - close(fd); - failure_start(file, line, - "Could not write to %s", path); - failure_finish(NULL); - close(fd); - return (0); - } - } - close(fd); - assertion_file_mode(file, line, path, mode); - return (1); -#endif -} - -/* Create a hardlink and report any failures. */ -int -assertion_make_hardlink(const char *file, int line, - const char *newpath, const char *linkto) -{ - int succeeded; - - assertion_count(file, line); -#if defined(_WIN32) && !defined(__CYGWIN__) - succeeded = my_CreateHardLinkA(newpath, linkto); -#elif HAVE_LINK - succeeded = !link(linkto, newpath); -#else - succeeded = 0; -#endif - if (succeeded) - return (1); - failure_start(file, line, "Could not create hardlink"); - logprintf(" New link: %s\n", newpath); - logprintf(" Old name: %s\n", linkto); - failure_finish(NULL); - return(0); -} - -/* - * Create a symlink and report any failures. - * - * Windows symlinks need to know if the target is a directory. - */ -int -assertion_make_symlink(const char *file, int line, - const char *newpath, const char *linkto, int targetIsDir) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - assertion_count(file, line); - if (my_CreateSymbolicLinkA(newpath, linkto, targetIsDir)) - return (1); -#elif HAVE_SYMLINK - (void)targetIsDir; /* UNUSED */ - assertion_count(file, line); - if (0 == symlink(linkto, newpath)) - return (1); -#else - (void)targetIsDir; /* UNUSED */ -#endif - failure_start(file, line, "Could not create symlink"); - logprintf(" New link: %s\n", newpath); - logprintf(" Old name: %s\n", linkto); - failure_finish(NULL); - return(0); -} - -/* Set umask, report failures. */ -int -assertion_umask(const char *file, int line, int mask) -{ - assertion_count(file, line); - (void)file; /* UNUSED */ - (void)line; /* UNUSED */ - umask(mask); - return (1); -} - -/* Set times, report failures. */ -int -assertion_utimes(const char *file, int line, - const char *pathname, long at, long at_nsec, long mt, long mt_nsec) -{ - int r; - -#if defined(_WIN32) && !defined(__CYGWIN__) -#define WINTIME(sec, nsec) ((Int32x32To64(sec, 10000000) + EPOC_TIME)\ - + (((nsec)/1000)*10)) - HANDLE h; - ULARGE_INTEGER wintm; - FILETIME fatime, fmtime; - FILETIME *pat, *pmt; - - assertion_count(file, line); - h = CreateFileA(pathname,GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, NULL); - if (h == INVALID_HANDLE_VALUE) { - failure_start(file, line, "Can't access %s\n", pathname); - failure_finish(NULL); - return (0); - } - - if (at > 0 || at_nsec > 0) { - wintm.QuadPart = WINTIME(at, at_nsec); - fatime.dwLowDateTime = wintm.LowPart; - fatime.dwHighDateTime = wintm.HighPart; - pat = &fatime; - } else - pat = NULL; - if (mt > 0 || mt_nsec > 0) { - wintm.QuadPart = WINTIME(mt, mt_nsec); - fmtime.dwLowDateTime = wintm.LowPart; - fmtime.dwHighDateTime = wintm.HighPart; - pmt = &fmtime; - } else - pmt = NULL; - if (pat != NULL || pmt != NULL) - r = SetFileTime(h, NULL, pat, pmt); - else - r = 1; - CloseHandle(h); - if (r == 0) { - failure_start(file, line, "Can't SetFileTime %s\n", pathname); - failure_finish(NULL); - return (0); - } - return (1); -#else /* defined(_WIN32) && !defined(__CYGWIN__) */ - struct stat st; - struct timeval times[2]; - -#if !defined(__FreeBSD__) - mt_nsec = at_nsec = 0; /* Generic POSIX only has whole seconds. */ -#endif - if (mt == 0 && mt_nsec == 0 && at == 0 && at_nsec == 0) - return (1); - - r = lstat(pathname, &st); - if (r < 0) { - failure_start(file, line, "Can't stat %s\n", pathname); - failure_finish(NULL); - return (0); - } - - if (mt == 0 && mt_nsec == 0) { - mt = st.st_mtime; -#if defined(__FreeBSD__) - mt_nsec = st.st_mtimespec.tv_nsec; - /* FreeBSD generally only stores to microsecond res, so round. */ - mt_nsec = (mt_nsec / 1000) * 1000; -#endif - } - if (at == 0 && at_nsec == 0) { - at = st.st_atime; -#if defined(__FreeBSD__) - at_nsec = st.st_atimespec.tv_nsec; - /* FreeBSD generally only stores to microsecond res, so round. */ - at_nsec = (at_nsec / 1000) * 1000; -#endif - } - - times[1].tv_sec = mt; - times[1].tv_usec = mt_nsec / 1000; - - times[0].tv_sec = at; - times[0].tv_usec = at_nsec / 1000; - -#ifdef HAVE_LUTIMES - r = lutimes(pathname, times); -#else - r = utimes(pathname, times); -#endif - if (r < 0) { - failure_start(file, line, "Can't utimes %s\n", pathname); - failure_finish(NULL); - return (0); - } - return (1); -#endif /* defined(_WIN32) && !defined(__CYGWIN__) */ -} - -/* Compare file flags */ -int -assertion_compare_fflags(const char *file, int line, const char *patha, - const char *pathb, int nomatch) -{ -#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP) - struct stat sa, sb; - - assertion_count(file, line); - - if (stat(patha, &sa) < 0) - return (0); - if (stat(pathb, &sb) < 0) - return (0); - if (!nomatch && sa.st_flags != sb.st_flags) { - failure_start(file, line, "File flags should be identical: " - "%s=%#010x %s=%#010x", patha, sa.st_flags, pathb, - sb.st_flags); - failure_finish(NULL); - return (0); - } - if (nomatch && sa.st_flags == sb.st_flags) { - failure_start(file, line, "File flags should be different: " - "%s=%#010x %s=%#010x", patha, sa.st_flags, pathb, - sb.st_flags); - failure_finish(NULL); - return (0); - } -#elif (defined(FS_IOC_GETFLAGS) && defined(HAVE_WORKING_FS_IOC_GETFLAGS) && \ - defined(FS_NODUMP_FL)) || \ - (defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS) \ - && defined(EXT2_NODUMP_FL)) - int fd, r, flagsa, flagsb; - - assertion_count(file, line); - fd = open(patha, O_RDONLY | O_NONBLOCK); - if (fd < 0) { - failure_start(file, line, "Can't open %s\n", patha); - failure_finish(NULL); - return (0); - } - r = ioctl(fd, -#ifdef FS_IOC_GETFLAGS - FS_IOC_GETFLAGS, -#else - EXT2_IOC_GETFLAGS, -#endif - &flagsa); - close(fd); - if (r < 0) { - failure_start(file, line, "Can't get flags %s\n", patha); - failure_finish(NULL); - return (0); - } - fd = open(pathb, O_RDONLY | O_NONBLOCK); - if (fd < 0) { - failure_start(file, line, "Can't open %s\n", pathb); - failure_finish(NULL); - return (0); - } - r = ioctl(fd, -#ifdef FS_IOC_GETFLAGS - FS_IOC_GETFLAGS, -#else - EXT2_IOC_GETFLAGS, -#endif - &flagsb); - close(fd); - if (r < 0) { - failure_start(file, line, "Can't get flags %s\n", pathb); - failure_finish(NULL); - return (0); - } - if (!nomatch && flagsa != flagsb) { - failure_start(file, line, "File flags should be identical: " - "%s=%#010x %s=%#010x", patha, flagsa, pathb, flagsb); - failure_finish(NULL); - return (0); - } - if (nomatch && flagsa == flagsb) { - failure_start(file, line, "File flags should be different: " - "%s=%#010x %s=%#010x", patha, flagsa, pathb, flagsb); - failure_finish(NULL); - return (0); - } -#else - (void)patha; /* UNUSED */ - (void)pathb; /* UNUSED */ - (void)nomatch; /* UNUSED */ - assertion_count(file, line); -#endif - return (1); -} - -/* Set nodump, report failures. */ -int -assertion_set_nodump(const char *file, int line, const char *pathname) -{ -#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP) - int r; - - assertion_count(file, line); - r = chflags(pathname, UF_NODUMP); - if (r < 0) { - failure_start(file, line, "Can't set nodump %s\n", pathname); - failure_finish(NULL); - return (0); - } -#elif (defined(FS_IOC_GETFLAGS) && defined(HAVE_WORKING_FS_IOC_GETFLAGS) && \ - defined(FS_NODUMP_FL)) || \ - (defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS) \ - && defined(EXT2_NODUMP_FL)) - int fd, r, flags; - - assertion_count(file, line); - fd = open(pathname, O_RDONLY | O_NONBLOCK); - if (fd < 0) { - failure_start(file, line, "Can't open %s\n", pathname); - failure_finish(NULL); - return (0); - } - r = ioctl(fd, -#ifdef FS_IOC_GETFLAGS - FS_IOC_GETFLAGS, -#else - EXT2_IOC_GETFLAGS, -#endif - &flags); - if (r < 0) { - failure_start(file, line, "Can't get flags %s\n", pathname); - failure_finish(NULL); - return (0); - } -#ifdef FS_NODUMP_FL - flags |= FS_NODUMP_FL; -#else - flags |= EXT2_NODUMP_FL; -#endif - - r = ioctl(fd, -#ifdef FS_IOC_SETFLAGS - FS_IOC_SETFLAGS, -#else - EXT2_IOC_SETFLAGS, -#endif - &flags); - if (r < 0) { - failure_start(file, line, "Can't set nodump %s\n", pathname); - failure_finish(NULL); - return (0); - } - close(fd); -#else - (void)pathname; /* UNUSED */ - assertion_count(file, line); -#endif - return (1); -} - -#ifdef PROGRAM -static void assert_version_id(char **qq, size_t *ss) -{ - char *q = *qq; - size_t s = *ss; - - /* Version number is a series of digits and periods. */ - while (s > 0 && (*q == '.' || (*q >= '0' && *q <= '9'))) { - ++q; - --s; - } - - if (q[0] == 'd' && q[1] == 'e' && q[2] == 'v') { - q += 3; - s -= 3; - } - - /* Skip a single trailing a,b,c, or d. */ - if (*q == 'a' || *q == 'b' || *q == 'c' || *q == 'd') - ++q; - - /* Version number terminated by space. */ - failure("No space after version: ``%s''", q); - assert(s > 1); - failure("No space after version: ``%s''", q); - assert(*q == ' '); - - ++q; --s; - - *qq = q; - *ss = s; -} - - -/* - * Check program version - */ -void assertVersion(const char *prog, const char *base) -{ - int r; - char *p, *q; - size_t s; - size_t prog_len = strlen(base); - - r = systemf("%s --version >version.stdout 2>version.stderr", prog); - if (r != 0) - r = systemf("%s -W version >version.stdout 2>version.stderr", - prog); - - failure("Unable to run either %s --version or %s -W version", - prog, prog); - if (!assert(r == 0)) - return; - - /* --version should generate nothing to stdout. */ - assertEmptyFile("version.stderr"); - - /* Verify format of version message. */ - q = p = slurpfile(&s, "version.stdout"); - - /* Version message should start with name of program, then space. */ - assert(s > prog_len + 1); - - failure("Version must start with '%s': ``%s''", base, p); - if (!assertEqualMem(q, base, prog_len)) { - free(p); - return; - } - - q += prog_len; s -= prog_len; - - assert(*q == ' '); - q++; s--; - - assert_version_id(&q, &s); - - /* Separator. */ - failure("No `-' between program name and versions: ``%s''", p); - assertEqualMem(q, "- ", 2); - q += 2; s -= 2; - - failure("Not long enough for libarchive version: ``%s''", p); - assert(s > 11); - - failure("Libarchive version must start with `libarchive': ``%s''", p); - assertEqualMem(q, "libarchive ", 11); - - q += 11; s -= 11; - - assert_version_id(&q, &s); - - /* Skip arbitrary third-party version numbers. */ - while (s > 0 && (*q == ' ' || *q == '-' || *q == '/' || *q == '.' || - isalnum((unsigned char)*q))) { - ++q; - --s; - } - - /* All terminated by end-of-line. */ - assert(s >= 1); - - /* Skip an optional CR character (e.g., Windows) */ - failure("Version output must end with \\n or \\r\\n"); - - if (*q == '\r') { ++q; --s; } - assertEqualMem(q, "\n", 1); - - free(p); -} -#endif /* PROGRAM */ - -/* - * - * UTILITIES for use by tests. - * - */ - -/* - * Check whether platform supports symlinks. This is intended - * for tests to use in deciding whether to bother testing symlink - * support; if the platform doesn't support symlinks, there's no point - * in checking whether the program being tested can create them. - * - * Note that the first time this test is called, we actually go out to - * disk to create and verify a symlink. This is necessary because - * symlink support is actually a property of a particular filesystem - * and can thus vary between directories on a single system. After - * the first call, this returns the cached result from memory, so it's - * safe to call it as often as you wish. - */ -int -canSymlink(void) -{ - /* Remember the test result */ - static int value = 0, tested = 0; - if (tested) - return (value); - - ++tested; - assertion_make_file(__FILE__, __LINE__, "canSymlink.0", 0644, 1, "a"); - /* Note: Cygwin has its own symlink() emulation that does not - * use the Win32 CreateSymbolicLink() function. */ -#if defined(_WIN32) && !defined(__CYGWIN__) - value = my_CreateSymbolicLinkA("canSymlink.1", "canSymlink.0", 0) - && is_symlink(__FILE__, __LINE__, "canSymlink.1", "canSymlink.0", - 0); -#elif HAVE_SYMLINK - value = (0 == symlink("canSymlink.0", "canSymlink.1")) - && is_symlink(__FILE__, __LINE__, "canSymlink.1","canSymlink.0", - 0); -#endif - return (value); -} - -/* Platform-dependent options for hiding the output of a subcommand. */ -#if defined(_WIN32) && !defined(__CYGWIN__) -static const char *redirectArgs = ">NUL 2>NUL"; /* Win32 cmd.exe */ -#else -static const char *redirectArgs = ">/dev/null 2>/dev/null"; /* POSIX 'sh' */ -#endif -/* - * Can this platform run the bzip2 program? - */ -int -canBzip2(void) -{ - static int tested = 0, value = 0; - if (!tested) { - tested = 1; - if (systemf("bzip2 --help %s", redirectArgs) == 0) - value = 1; - } - return (value); -} - -/* - * Can this platform run the grzip program? - */ -int -canGrzip(void) -{ - static int tested = 0, value = 0; - if (!tested) { - tested = 1; - if (systemf("grzip -V %s", redirectArgs) == 0) - value = 1; - } - return (value); -} - -/* - * Can this platform run the gzip program? - */ -int -canGzip(void) -{ - static int tested = 0, value = 0; - if (!tested) { - tested = 1; - if (systemf("gzip --help %s", redirectArgs) == 0) - value = 1; - } - return (value); -} - -/* - * Can this platform run the lrzip program? - */ -int -canRunCommand(const char *cmd) -{ - static int tested = 0, value = 0; - if (!tested) { - tested = 1; - if (systemf("%s %s", cmd, redirectArgs) == 0) - value = 1; - } - return (value); -} - -int -canLrzip(void) -{ - static int tested = 0, value = 0; - if (!tested) { - tested = 1; - if (systemf("lrzip -V %s", redirectArgs) == 0) - value = 1; - } - return (value); -} - -/* - * Can this platform run the lz4 program? - */ -int -canLz4(void) -{ - static int tested = 0, value = 0; - if (!tested) { - tested = 1; - if (systemf("lz4 --help %s", redirectArgs) == 0) - value = 1; - } - return (value); -} - -/* - * Can this platform run the zstd program? - */ -int -canZstd(void) -{ - static int tested = 0, value = 0; - if (!tested) { - tested = 1; - if (systemf("zstd --help %s", redirectArgs) == 0) - value = 1; - } - return (value); -} - -/* - * Can this platform run the lzip program? - */ -int -canLzip(void) -{ - static int tested = 0, value = 0; - if (!tested) { - tested = 1; - if (systemf("lzip --help %s", redirectArgs) == 0) - value = 1; - } - return (value); -} - -/* - * Can this platform run the lzma program? - */ -int -canLzma(void) -{ - static int tested = 0, value = 0; - if (!tested) { - tested = 1; - if (systemf("lzma --help %s", redirectArgs) == 0) - value = 1; - } - return (value); -} - -/* - * Can this platform run the lzop program? - */ -int -canLzop(void) -{ - static int tested = 0, value = 0; - if (!tested) { - tested = 1; - if (systemf("lzop --help %s", redirectArgs) == 0) - value = 1; - } - return (value); -} - -/* - * Can this platform run the xz program? - */ -int -canXz(void) -{ - static int tested = 0, value = 0; - if (!tested) { - tested = 1; - if (systemf("xz --help %s", redirectArgs) == 0) - value = 1; - } - return (value); -} - -/* - * Can this filesystem handle nodump flags. - */ -int -canNodump(void) -{ -#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP) - const char *path = "cannodumptest"; - struct stat sb; - - assertion_make_file(__FILE__, __LINE__, path, 0644, 0, NULL); - if (chflags(path, UF_NODUMP) < 0) - return (0); - if (stat(path, &sb) < 0) - return (0); - if (sb.st_flags & UF_NODUMP) - return (1); -#elif (defined(FS_IOC_GETFLAGS) && defined(HAVE_WORKING_FS_IOC_GETFLAGS) \ - && defined(FS_NODUMP_FL)) || \ - (defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS) \ - && defined(EXT2_NODUMP_FL)) - const char *path = "cannodumptest"; - int fd, r, flags; - - assertion_make_file(__FILE__, __LINE__, path, 0644, 0, NULL); - fd = open(path, O_RDONLY | O_NONBLOCK); - if (fd < 0) - return (0); - r = ioctl(fd, -#ifdef FS_IOC_GETFLAGS - FS_IOC_GETFLAGS, -#else - EXT2_IOC_GETFLAGS, -#endif - &flags); - if (r < 0) - return (0); -#ifdef FS_NODUMP_FL - flags |= FS_NODUMP_FL; -#else - flags |= EXT2_NODUMP_FL; -#endif - r = ioctl(fd, -#ifdef FS_IOC_SETFLAGS - FS_IOC_SETFLAGS, -#else - EXT2_IOC_SETFLAGS, -#endif - &flags); - if (r < 0) - return (0); - close(fd); - fd = open(path, O_RDONLY | O_NONBLOCK); - if (fd < 0) - return (0); - r = ioctl(fd, -#ifdef FS_IOC_GETFLAGS - FS_IOC_GETFLAGS, -#else - EXT2_IOC_GETFLAGS, -#endif - &flags); - if (r < 0) - return (0); - close(fd); -#ifdef FS_NODUMP_FL - if (flags & FS_NODUMP_FL) -#else - if (flags & EXT2_NODUMP_FL) -#endif - return (1); -#endif - return (0); -} - -/* Get extended attribute value from a path */ -void * -getXattr(const char *path, const char *name, size_t *sizep) -{ - void *value = NULL; -#if ARCHIVE_XATTR_SUPPORT - ssize_t size; -#if ARCHIVE_XATTR_LINUX - size = lgetxattr(path, name, NULL, 0); -#elif ARCHIVE_XATTR_DARWIN - size = getxattr(path, name, NULL, 0, 0, XATTR_NOFOLLOW); -#elif ARCHIVE_XATTR_AIX - size = lgetea(path, name, NULL, 0); -#elif ARCHIVE_XATTR_FREEBSD - size = extattr_get_link(path, EXTATTR_NAMESPACE_USER, name + 5, - NULL, 0); -#endif - - if (size >= 0) { - value = malloc(size); -#if ARCHIVE_XATTR_LINUX - size = lgetxattr(path, name, value, size); -#elif ARCHIVE_XATTR_DARWIN - size = getxattr(path, name, value, size, 0, XATTR_NOFOLLOW); -#elif ARCHIVE_XATTR_AIX - size = lgetea(path, name, value, size); -#elif ARCHIVE_XATTR_FREEBSD - size = extattr_get_link(path, EXTATTR_NAMESPACE_USER, name + 5, - value, size); -#endif - if (size < 0) { - free(value); - value = NULL; - } - } - if (size < 0) - *sizep = 0; - else - *sizep = (size_t)size; -#else /* !ARCHIVE_XATTR_SUPPORT */ - (void)path; /* UNUSED */ - (void)name; /* UNUSED */ - *sizep = 0; -#endif /* !ARCHIVE_XATTR_SUPPORT */ - return (value); -} - -/* - * Set extended attribute on a path - * Returns 0 on error, 1 on success - */ -int -setXattr(const char *path, const char *name, const void *value, size_t size) -{ -#if ARCHIVE_XATTR_SUPPORT -#if ARCHIVE_XATTR_LINUX - if (lsetxattr(path, name, value, size, 0) == 0) -#elif ARCHIVE_XATTR_DARWIN - if (setxattr(path, name, value, size, 0, XATTR_NOFOLLOW) == 0) -#elif ARCHIVE_XATTR_AIX - if (lsetea(path, name, value, size, 0) == 0) -#elif ARCHIVE_XATTR_FREEBSD - if (extattr_set_link(path, EXTATTR_NAMESPACE_USER, name + 5, value, - size) > -1) -#else - if (0) -#endif - return (1); -#else /* !ARCHIVE_XATTR_SUPPORT */ - (void)path; /* UNUSED */ - (void)name; /* UNUSED */ - (void)value; /* UNUSED */ - (void)size; /* UNUSED */ -#endif /* !ARCHIVE_XATTR_SUPPORT */ - return (0); -} - -#if ARCHIVE_ACL_SUNOS -/* Fetch ACLs on Solaris using acl() or facl() */ -void * -sunacl_get(int cmd, int *aclcnt, int fd, const char *path) -{ - int cnt, cntcmd; - size_t size; - void *aclp; - - if (cmd == GETACL) { - cntcmd = GETACLCNT; - size = sizeof(aclent_t); - } -#if ARCHIVE_ACL_SUNOS_NFS4 - else if (cmd == ACE_GETACL) { - cntcmd = ACE_GETACLCNT; - size = sizeof(ace_t); - } -#endif - else { - errno = EINVAL; - *aclcnt = -1; - return (NULL); - } - - aclp = NULL; - cnt = -2; - while (cnt == -2 || (cnt == -1 && errno == ENOSPC)) { - if (path != NULL) - cnt = acl(path, cntcmd, 0, NULL); - else - cnt = facl(fd, cntcmd, 0, NULL); - - if (cnt > 0) { - if (aclp == NULL) - aclp = malloc(cnt * size); - else - aclp = realloc(NULL, cnt * size); - if (aclp != NULL) { - if (path != NULL) - cnt = acl(path, cmd, cnt, aclp); - else - cnt = facl(fd, cmd, cnt, aclp); - } - } else { - free(aclp); - aclp = NULL; - break; - } - } - - *aclcnt = cnt; - return (aclp); -} -#endif /* ARCHIVE_ACL_SUNOS */ - -/* - * Set test ACLs on a path - * Return values: - * 0: error setting ACLs - * ARCHIVE_TEST_ACL_TYPE_POSIX1E: POSIX.1E ACLs have been set - * ARCHIVE_TEST_ACL_TYPE_NFS4: NFSv4 or extended ACLs have been set - */ -int -setTestAcl(const char *path) -{ -#if ARCHIVE_ACL_SUPPORT - int r = 1; -#if ARCHIVE_ACL_LIBACL || ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_DARWIN - acl_t acl; -#endif -#if ARCHIVE_ACL_LIBRICHACL - struct richacl *richacl; -#endif -#if ARCHIVE_ACL_LIBACL || ARCHIVE_ACL_FREEBSD - const char *acltext_posix1e = "user:1:rw-," - "group:15:r-x," - "user::rwx," - "group::rwx," - "other::r-x," - "mask::rwx"; -#elif ARCHIVE_ACL_SUNOS /* Solaris POSIX.1e */ - aclent_t aclp_posix1e[] = { - { USER_OBJ, -1, 4 | 2 | 1 }, - { USER, 1, 4 | 2 }, - { GROUP_OBJ, -1, 4 | 2 | 1 }, - { GROUP, 15, 4 | 1 }, - { CLASS_OBJ, -1, 4 | 2 | 1 }, - { OTHER_OBJ, -1, 4 | 2 | 1 } - }; -#endif -#if ARCHIVE_ACL_FREEBSD /* FreeBSD NFS4 */ - const char *acltext_nfs4 = "user:1:rwpaRcs::allow:1," - "group:15:rxaRcs::allow:15," - "owner@:rwpxaARWcCos::allow," - "group@:rwpxaRcs::allow," - "everyone@:rxaRcs::allow"; -#elif ARCHIVE_ACL_LIBRICHACL - const char *acltext_nfs4 = "owner:rwpxaARWcCoS::mask," - "group:rwpxaRcS::mask," - "other:rxaRcS::mask," - "user:1:rwpaRcS::allow," - "group:15:rxaRcS::allow," - "owner@:rwpxaARWcCoS::allow," - "group@:rwpxaRcS::allow," - "everyone@:rxaRcS::allow"; -#elif ARCHIVE_ACL_SUNOS_NFS4 /* Solaris NFS4 */ - ace_t aclp_nfs4[] = { - { 1, ACE_READ_DATA | ACE_WRITE_DATA | ACE_APPEND_DATA | - ACE_READ_ATTRIBUTES | ACE_READ_NAMED_ATTRS | ACE_READ_ACL | - ACE_SYNCHRONIZE, 0, ACE_ACCESS_ALLOWED_ACE_TYPE }, - { 15, ACE_READ_DATA | ACE_EXECUTE | ACE_READ_ATTRIBUTES | - ACE_READ_NAMED_ATTRS | ACE_READ_ACL | ACE_SYNCHRONIZE, - ACE_IDENTIFIER_GROUP, ACE_ACCESS_ALLOWED_ACE_TYPE }, - { -1, ACE_READ_DATA | ACE_WRITE_DATA | ACE_APPEND_DATA | - ACE_EXECUTE | ACE_READ_ATTRIBUTES | ACE_WRITE_ATTRIBUTES | - ACE_READ_NAMED_ATTRS | ACE_WRITE_NAMED_ATTRS | - ACE_READ_ACL | ACE_WRITE_ACL | ACE_WRITE_OWNER | ACE_SYNCHRONIZE, - ACE_OWNER, ACE_ACCESS_ALLOWED_ACE_TYPE }, - { -1, ACE_READ_DATA | ACE_WRITE_DATA | ACE_APPEND_DATA | - ACE_EXECUTE | ACE_READ_ATTRIBUTES | ACE_READ_NAMED_ATTRS | - ACE_READ_ACL | ACE_SYNCHRONIZE, ACE_GROUP | ACE_IDENTIFIER_GROUP, - ACE_ACCESS_ALLOWED_ACE_TYPE }, - { -1, ACE_READ_DATA | ACE_EXECUTE | ACE_READ_ATTRIBUTES | - ACE_READ_NAMED_ATTRS | ACE_READ_ACL | ACE_SYNCHRONIZE, - ACE_EVERYONE, ACE_ACCESS_ALLOWED_ACE_TYPE } - }; -#elif ARCHIVE_ACL_DARWIN /* Mac OS X */ - acl_entry_t aclent; - acl_permset_t permset; - const uid_t uid = 1; - uuid_t uuid; - int i; - const acl_perm_t acl_perms[] = { - ACL_READ_DATA, - ACL_WRITE_DATA, - ACL_APPEND_DATA, - ACL_EXECUTE, - ACL_READ_ATTRIBUTES, - ACL_READ_EXTATTRIBUTES, - ACL_READ_SECURITY, -#if HAVE_DECL_ACL_SYNCHRONIZE - ACL_SYNCHRONIZE -#endif - }; -#endif /* ARCHIVE_ACL_DARWIN */ - -#if ARCHIVE_ACL_FREEBSD - acl = acl_from_text(acltext_nfs4); - failure("acl_from_text() error: %s", strerror(errno)); - if (assert(acl != NULL) == 0) - return (0); -#elif ARCHIVE_ACL_LIBRICHACL - richacl = richacl_from_text(acltext_nfs4, NULL, NULL); - failure("richacl_from_text() error: %s", strerror(errno)); - if (assert(richacl != NULL) == 0) - return (0); -#elif ARCHIVE_ACL_DARWIN - acl = acl_init(1); - failure("acl_init() error: %s", strerror(errno)); - if (assert(acl != NULL) == 0) - return (0); - r = acl_create_entry(&acl, &aclent); - failure("acl_create_entry() error: %s", strerror(errno)); - if (assertEqualInt(r, 0) == 0) - goto testacl_free; - r = acl_set_tag_type(aclent, ACL_EXTENDED_ALLOW); - failure("acl_set_tag_type() error: %s", strerror(errno)); - if (assertEqualInt(r, 0) == 0) - goto testacl_free; - r = acl_get_permset(aclent, &permset); - failure("acl_get_permset() error: %s", strerror(errno)); - if (assertEqualInt(r, 0) == 0) - goto testacl_free; - for (i = 0; i < (int)(sizeof(acl_perms) / sizeof(acl_perms[0])); i++) { - r = acl_add_perm(permset, acl_perms[i]); - failure("acl_add_perm() error: %s", strerror(errno)); - if (assertEqualInt(r, 0) == 0) - goto testacl_free; - } - r = acl_set_permset(aclent, permset); - failure("acl_set_permset() error: %s", strerror(errno)); - if (assertEqualInt(r, 0) == 0) - goto testacl_free; - r = mbr_uid_to_uuid(uid, uuid); - failure("mbr_uid_to_uuid() error: %s", strerror(errno)); - if (assertEqualInt(r, 0) == 0) - goto testacl_free; - r = acl_set_qualifier(aclent, uuid); - failure("acl_set_qualifier() error: %s", strerror(errno)); - if (assertEqualInt(r, 0) == 0) - goto testacl_free; -#endif /* ARCHIVE_ACL_DARWIN */ - -#if ARCHIVE_ACL_NFS4 -#if ARCHIVE_ACL_FREEBSD - r = acl_set_file(path, ACL_TYPE_NFS4, acl); - acl_free(acl); -#elif ARCHIVE_ACL_LIBRICHACL - r = richacl_set_file(path, richacl); - richacl_free(richacl); -#elif ARCHIVE_ACL_SUNOS_NFS4 - r = acl(path, ACE_SETACL, - (int)(sizeof(aclp_nfs4)/sizeof(aclp_nfs4[0])), aclp_nfs4); -#elif ARCHIVE_ACL_DARWIN - r = acl_set_file(path, ACL_TYPE_EXTENDED, acl); - acl_free(acl); -#endif - if (r == 0) - return (ARCHIVE_TEST_ACL_TYPE_NFS4); -#endif /* ARCHIVE_ACL_NFS4 */ - -#if ARCHIVE_ACL_POSIX1E -#if ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_LIBACL - acl = acl_from_text(acltext_posix1e); - failure("acl_from_text() error: %s", strerror(errno)); - if (assert(acl != NULL) == 0) - return (0); - - r = acl_set_file(path, ACL_TYPE_ACCESS, acl); - acl_free(acl); -#elif ARCHIVE_ACL_SUNOS - r = acl(path, SETACL, - (int)(sizeof(aclp_posix1e)/sizeof(aclp_posix1e[0])), aclp_posix1e); -#endif - if (r == 0) - return (ARCHIVE_TEST_ACL_TYPE_POSIX1E); - else - return (0); -#endif /* ARCHIVE_ACL_POSIX1E */ -#if ARCHIVE_ACL_DARWIN -testacl_free: - acl_free(acl); -#endif -#endif /* ARCHIVE_ACL_SUPPORT */ - (void)path; /* UNUSED */ - return (0); -} - -/* - * Sleep as needed; useful for verifying disk timestamp changes by - * ensuring that the wall-clock time has actually changed before we - * go back to re-read something from disk. - */ -void -sleepUntilAfter(time_t t) -{ - while (t >= time(NULL)) -#if defined(_WIN32) && !defined(__CYGWIN__) - Sleep(500); -#else - sleep(1); -#endif -} - -/* - * Call standard system() call, but build up the command line using - * sprintf() conventions. - */ -int -systemf(const char *fmt, ...) -{ - char buff[8192]; - va_list ap; - int r; - - va_start(ap, fmt); - vsnprintf(buff, sizeof(buff), fmt, ap); - if (verbosity > VERBOSITY_FULL) - logprintf("Cmd: %s\n", buff); - r = system(buff); - va_end(ap); - return (r); -} - -/* - * Slurp a file into memory for ease of comparison and testing. - * Returns size of file in 'sizep' if non-NULL, null-terminates - * data in memory for ease of use. - */ -char * -slurpfile(size_t * sizep, const char *fmt, ...) -{ - char filename[8192]; - struct stat st; - va_list ap; - char *p; - ssize_t bytes_read; - FILE *f; - int r; - - va_start(ap, fmt); - vsnprintf(filename, sizeof(filename), fmt, ap); - va_end(ap); - - f = fopen(filename, "rb"); - if (f == NULL) { - /* Note: No error; non-existent file is okay here. */ - return (NULL); - } - r = fstat(fileno(f), &st); - if (r != 0) { - logprintf("Can't stat file %s\n", filename); - fclose(f); - return (NULL); - } - p = malloc((size_t)st.st_size + 1); - if (p == NULL) { - logprintf("Can't allocate %ld bytes of memory to read file %s\n", - (long int)st.st_size, filename); - fclose(f); - return (NULL); - } - bytes_read = fread(p, 1, (size_t)st.st_size, f); - if (bytes_read < st.st_size) { - logprintf("Can't read file %s\n", filename); - fclose(f); - free(p); - return (NULL); - } - p[st.st_size] = '\0'; - if (sizep != NULL) - *sizep = (size_t)st.st_size; - fclose(f); - return (p); -} - -/* - * Slurp a file into memory for ease of comparison and testing. - * Returns size of file in 'sizep' if non-NULL, null-terminates - * data in memory for ease of use. - */ -void -dumpfile(const char *filename, void *data, size_t len) -{ - ssize_t bytes_written; - FILE *f; - - f = fopen(filename, "wb"); - if (f == NULL) { - logprintf("Can't open file %s for writing\n", filename); - return; - } - bytes_written = fwrite(data, 1, len, f); - if (bytes_written < (ssize_t)len) - logprintf("Can't write file %s\n", filename); - fclose(f); -} - -/* Read a uuencoded file from the reference directory, decode, and - * write the result into the current directory. */ -#define VALID_UUDECODE(c) (c >= 32 && c <= 96) -#define UUDECODE(c) (((c) - 0x20) & 0x3f) -void -extract_reference_file(const char *name) -{ - char buff[1024]; - FILE *in, *out; - - snprintf(buff, sizeof(buff), "%s/%s.uu", refdir, name); - in = fopen(buff, "r"); - failure("Couldn't open reference file %s", buff); - assert(in != NULL); - if (in == NULL) - return; - /* Read up to and including the 'begin' line. */ - for (;;) { - if (fgets(buff, sizeof(buff), in) == NULL) { - /* TODO: This is a failure. */ - return; - } - if (memcmp(buff, "begin ", 6) == 0) - break; - } - /* Now, decode the rest and write it. */ - out = fopen(name, "wb"); - while (fgets(buff, sizeof(buff), in) != NULL) { - char *p = buff; - int bytes; - - if (memcmp(buff, "end", 3) == 0) - break; - - bytes = UUDECODE(*p++); - while (bytes > 0) { - int n = 0; - /* Write out 1-3 bytes from that. */ - assert(VALID_UUDECODE(p[0])); - assert(VALID_UUDECODE(p[1])); - n = UUDECODE(*p++) << 18; - n |= UUDECODE(*p++) << 12; - fputc(n >> 16, out); - --bytes; - if (bytes > 0) { - assert(VALID_UUDECODE(p[0])); - n |= UUDECODE(*p++) << 6; - fputc((n >> 8) & 0xFF, out); - --bytes; - } - if (bytes > 0) { - assert(VALID_UUDECODE(p[0])); - n |= UUDECODE(*p++); - fputc(n & 0xFF, out); - --bytes; - } - } - } - fclose(out); - fclose(in); -} - -void -copy_reference_file(const char *name) -{ - char buff[1024]; - FILE *in, *out; - size_t rbytes; - - snprintf(buff, sizeof(buff), "%s/%s", refdir, name); - in = fopen(buff, "rb"); - failure("Couldn't open reference file %s", buff); - assert(in != NULL); - if (in == NULL) - return; - /* Now, decode the rest and write it. */ - /* Not a lot of error checking here; the input better be right. */ - out = fopen(name, "wb"); - while ((rbytes = fread(buff, 1, sizeof(buff), in)) > 0) { - if (fwrite(buff, 1, rbytes, out) != rbytes) { - logprintf("Error: fwrite\n"); - break; - } - } - fclose(out); - fclose(in); -} - -int -is_LargeInode(const char *file) -{ -#if defined(_WIN32) && !defined(__CYGWIN__) - BY_HANDLE_FILE_INFORMATION bhfi; - int r; - - r = my_GetFileInformationByName(file, &bhfi); - if (r != 0) - return (0); - return (bhfi.nFileIndexHigh & 0x0000FFFFUL); -#else - struct stat st; - int64_t ino; - - if (stat(file, &st) < 0) - return (0); - ino = (int64_t)st.st_ino; - return (ino > 0xffffffff); -#endif -} - -void -extract_reference_files(const char **names) -{ - while (names && *names) - extract_reference_file(*names++); -} - -#ifndef PROGRAM -/* Set ACLs */ -int -assertion_entry_set_acls(const char *file, int line, struct archive_entry *ae, - struct archive_test_acl_t *acls, int n) -{ - int i, r, ret; - - assertion_count(file, line); - - ret = 0; - archive_entry_acl_clear(ae); - for (i = 0; i < n; i++) { - r = archive_entry_acl_add_entry(ae, - acls[i].type, acls[i].permset, acls[i].tag, - acls[i].qual, acls[i].name); - if (r != 0) { - ret = 1; - failure_start(file, line, "type=%#010x, " - "permset=%#010x, tag=%d, qual=%d name=%s", - acls[i].type, acls[i].permset, acls[i].tag, - acls[i].qual, acls[i].name); - failure_finish(NULL); - } - } - - return (ret); -} - -static int -archive_test_acl_match(struct archive_test_acl_t *acl, int type, int permset, - int tag, int qual, const char *name) -{ - if (type != acl->type) - return (0); - if (permset != acl->permset) - return (0); - if (tag != acl->tag) - return (0); - if (tag == ARCHIVE_ENTRY_ACL_USER_OBJ) - return (1); - if (tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ) - return (1); - if (tag == ARCHIVE_ENTRY_ACL_EVERYONE) - return (1); - if (tag == ARCHIVE_ENTRY_ACL_OTHER) - return (1); - if (qual != acl->qual) - return (0); - if (name == NULL) { - if (acl->name == NULL || acl->name[0] == '\0') - return (1); - return (0); - } - if (acl->name == NULL) { - if (name[0] == '\0') - return (1); - return (0); - } - return (0 == strcmp(name, acl->name)); -} - -/* Compare ACLs */ -int -assertion_entry_compare_acls(const char *file, int line, - struct archive_entry *ae, struct archive_test_acl_t *acls, int cnt, - int want_type, int mode) -{ - int *marker; - int i, r, n, ret; - int type, permset, tag, qual; - int matched; - const char *name; - - assertion_count(file, line); - - ret = 0; - n = 0; - marker = malloc(sizeof(marker[0]) * cnt); - - for (i = 0; i < cnt; i++) { - if ((acls[i].type & want_type) != 0) { - marker[n] = i; - n++; - } - } - - if (n == 0) { - failure_start(file, line, "No ACL's to compare, type mask: %d", - want_type); - return (1); - } - - while (0 == (r = archive_entry_acl_next(ae, want_type, - &type, &permset, &tag, &qual, &name))) { - for (i = 0, matched = 0; i < n && !matched; i++) { - if (archive_test_acl_match(&acls[marker[i]], type, - permset, tag, qual, name)) { - /* We found a match; remove it. */ - marker[i] = marker[n - 1]; - n--; - matched = 1; - } - } - if (type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS - && tag == ARCHIVE_ENTRY_ACL_USER_OBJ) { - if (!matched) { - failure_start(file, line, "No match for " - "user_obj perm"); - failure_finish(NULL); - ret = 1; - } - if ((permset << 6) != (mode & 0700)) { - failure_start(file, line, "USER_OBJ permset " - "(%02o) != user mode (%02o)", permset, - 07 & (mode >> 6)); - failure_finish(NULL); - ret = 1; - } - } else if (type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS - && tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ) { - if (!matched) { - failure_start(file, line, "No match for " - "group_obj perm"); - failure_finish(NULL); - ret = 1; - } - if ((permset << 3) != (mode & 0070)) { - failure_start(file, line, "GROUP_OBJ permset " - "(%02o) != group mode (%02o)", permset, - 07 & (mode >> 3)); - failure_finish(NULL); - ret = 1; - } - } else if (type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS - && tag == ARCHIVE_ENTRY_ACL_OTHER) { - if (!matched) { - failure_start(file, line, "No match for " - "other perm"); - failure_finish(NULL); - ret = 1; - } - if ((permset << 0) != (mode & 0007)) { - failure_start(file, line, "OTHER permset " - "(%02o) != other mode (%02o)", permset, - mode & 07); - failure_finish(NULL); - ret = 1; - } - } else if (matched != 1) { - failure_start(file, line, "Could not find match for " - "ACL (type=%#010x,permset=%#010x,tag=%d,qual=%d," - "name=``%s'')", type, permset, tag, qual, name); - failure_finish(NULL); - ret = 1; - } - } - if (r != ARCHIVE_EOF) { - failure_start(file, line, "Should not exit before EOF"); - failure_finish(NULL); - ret = 1; - } - if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0 && - (mode_t)(mode & 0777) != (archive_entry_mode(ae) & 0777)) { - failure_start(file, line, "Mode (%02o) and entry mode (%02o) " - "mismatch", mode, archive_entry_mode(ae)); - failure_finish(NULL); - ret = 1; - } - if (n != 0) { - failure_start(file, line, "Could not find match for ACL " - "(type=%#010x,permset=%#010x,tag=%d,qual=%d,name=``%s'')", - acls[marker[0]].type, acls[marker[0]].permset, - acls[marker[0]].tag, acls[marker[0]].qual, - acls[marker[0]].name); - failure_finish(NULL); - ret = 1; - /* Number of ACLs not matched should == 0 */ - } - free(marker); - return (ret); -} -#endif /* !defined(PROGRAM) */ - -/* - * - * TEST management - * - */ - -/* - * "list.h" is simply created by "grep DEFINE_TEST test_*.c"; it has - * a line like - * DEFINE_TEST(test_function) - * for each test. - */ -struct test_list_t -{ - void (*func)(void); - const char *name; - int failures; -}; - -/* Use "list.h" to declare all of the test functions. */ -#undef DEFINE_TEST -#define DEFINE_TEST(name) void name(void); -#include "list.h" - -/* Use "list.h" to create a list of all tests (functions and names). */ -#undef DEFINE_TEST -#define DEFINE_TEST(n) { n, #n, 0 }, -static struct test_list_t tests[] = { - #include "list.h" -}; - -/* - * Summarize repeated failures in the just-completed test. - */ -static void -test_summarize(int failed, int skips_num) -{ - unsigned int i; - - switch (verbosity) { - case VERBOSITY_SUMMARY_ONLY: - printf(failed ? "E" : "."); - fflush(stdout); - break; - case VERBOSITY_PASSFAIL: - printf(failed ? "FAIL\n" : skips_num ? "ok (S)\n" : "ok\n"); - break; - } - - log_console = (verbosity == VERBOSITY_LIGHT_REPORT); - - for (i = 0; i < sizeof(failed_lines)/sizeof(failed_lines[0]); i++) { - if (failed_lines[i].count > 1 && !failed_lines[i].skip) - logprintf("%s:%d: Summary: Failed %d times\n", - failed_filename, i, failed_lines[i].count); - } - /* Clear the failure history for the next file. */ - failed_filename = NULL; - memset(failed_lines, 0, sizeof(failed_lines)); -} - -/* - * Actually run a single test, with appropriate setup and cleanup. - */ -static int -test_run(int i, const char *tmpdir) -{ -#ifdef PATH_MAX - char workdir[PATH_MAX * 2]; -#else - char workdir[1024 * 2]; -#endif - char logfilename[64]; - int failures_before = failures; - int skips_before = skips; - int oldumask; - - switch (verbosity) { - case VERBOSITY_SUMMARY_ONLY: /* No per-test reports at all */ - break; - case VERBOSITY_PASSFAIL: /* rest of line will include ok/FAIL marker */ - printf("%3d: %-64s", i, tests[i].name); - fflush(stdout); - break; - default: /* Title of test, details will follow */ - printf("%3d: %s\n", i, tests[i].name); - } - - /* Chdir to the top-level work directory. */ - if (!assertChdir(tmpdir)) { - fprintf(stderr, - "ERROR: Can't chdir to top work dir %s\n", tmpdir); - exit(1); - } - /* Create a log file for this test. */ - snprintf(logfilename, sizeof(logfilename), "%s.log", tests[i].name); - logfile = fopen(logfilename, "w"); - fprintf(logfile, "%s\n\n", tests[i].name); - /* Chdir() to a work dir for this specific test. */ - snprintf(workdir, sizeof(workdir), "%s/%s", tmpdir, tests[i].name); - testworkdir = workdir; - if (!assertMakeDir(testworkdir, 0755) - || !assertChdir(testworkdir)) { - fprintf(stderr, - "ERROR: Can't chdir to work dir %s\n", testworkdir); - exit(1); - } - /* Explicitly reset the locale before each test. */ - setlocale(LC_ALL, "C"); - /* Record the umask before we run the test. */ - umask(oldumask = umask(0)); - /* - * Run the actual test. - */ - (*tests[i].func)(); - /* - * Clean up and report afterwards. - */ - testworkdir = NULL; - /* Restore umask */ - umask(oldumask); - /* Reset locale. */ - setlocale(LC_ALL, "C"); - /* Reset directory. */ - if (!assertChdir(tmpdir)) { - fprintf(stderr, "ERROR: Couldn't chdir to temp dir %s\n", - tmpdir); - exit(1); - } - /* Report per-test summaries. */ - tests[i].failures = failures - failures_before; - test_summarize(tests[i].failures, skips - skips_before); - /* Close the per-test log file. */ - fclose(logfile); - logfile = NULL; - /* If there were no failures, we can remove the work dir and logfile. */ - if (tests[i].failures == 0) { - if (!keep_temp_files && assertChdir(tmpdir)) { -#if defined(_WIN32) && !defined(__CYGWIN__) - /* Make sure not to leave empty directories. - * Sometimes a processing of closing files used by tests - * is not done, then rmdir will be failed and it will - * leave a empty test directory. So we should wait a few - * seconds and retry rmdir. */ - int r, t; - for (t = 0; t < 10; t++) { - if (t > 0) - Sleep(1000); - r = systemf("rmdir /S /Q %s", tests[i].name); - if (r == 0) - break; - } - systemf("del %s", logfilename); -#else - systemf("rm -rf %s", tests[i].name); - systemf("rm %s", logfilename); -#endif - } - } - /* Return appropriate status. */ - return (tests[i].failures); -} - -/* - * - * - * MAIN and support routines. - * - * - */ - -static void -usage(const char *program) -{ - static const int limit = sizeof(tests) / sizeof(tests[0]); - int i; - - printf("Usage: %s [options] ...\n", program); - printf("Default is to run all tests.\n"); - printf("Otherwise, specify the numbers of the tests you wish to run.\n"); - printf("Options:\n"); - printf(" -d Dump core after any failure, for debugging.\n"); - printf(" -k Keep all temp files.\n"); - printf(" Default: temp files for successful tests deleted.\n"); -#ifdef PROGRAM - printf(" -p Path to executable to be tested.\n"); - printf(" Default: path taken from " ENVBASE " environment variable.\n"); -#endif - printf(" -q Quiet.\n"); - printf(" -r Path to dir containing reference files.\n"); - printf(" Default: Current directory.\n"); - printf(" -u Keep running specifies tests until one fails.\n"); - printf(" -v Verbose.\n"); - printf("Available tests:\n"); - for (i = 0; i < limit; i++) - printf(" %d: %s\n", i, tests[i].name); - exit(1); -} - -static char * -get_refdir(const char *d) -{ - size_t tried_size, buff_size; - char *buff, *tried, *pwd = NULL, *p = NULL; - -#ifdef PATH_MAX - buff_size = PATH_MAX; -#else - buff_size = 8192; -#endif - buff = calloc(buff_size, 1); - if (buff == NULL) { - fprintf(stderr, "Unable to allocate memory\n"); - exit(1); - } - - /* Allocate a buffer to hold the various directories we checked. */ - tried_size = buff_size * 2; - tried = calloc(tried_size, 1); - if (tried == NULL) { - fprintf(stderr, "Unable to allocate memory\n"); - exit(1); - } - - /* If a dir was specified, try that */ - if (d != NULL) { - pwd = NULL; - snprintf(buff, buff_size, "%s", d); - p = slurpfile(NULL, "%s/%s", buff, KNOWNREF); - if (p != NULL) goto success; - strncat(tried, buff, tried_size - strlen(tried) - 1); - strncat(tried, "\n", tried_size - strlen(tried) - 1); - goto failure; - } - - /* Get the current dir. */ -#if defined(PATH_MAX) && !defined(__GLIBC__) - pwd = getcwd(NULL, PATH_MAX);/* Solaris getcwd needs the size. */ -#else - pwd = getcwd(NULL, 0); -#endif - while (pwd[strlen(pwd) - 1] == '\n') - pwd[strlen(pwd) - 1] = '\0'; - - /* Look for a known file. */ - snprintf(buff, buff_size, "%s", pwd); - p = slurpfile(NULL, "%s/%s", buff, KNOWNREF); - if (p != NULL) goto success; - strncat(tried, buff, tried_size - strlen(tried) - 1); - strncat(tried, "\n", tried_size - strlen(tried) - 1); - - snprintf(buff, buff_size, "%s/test", pwd); - p = slurpfile(NULL, "%s/%s", buff, KNOWNREF); - if (p != NULL) goto success; - strncat(tried, buff, tried_size - strlen(tried) - 1); - strncat(tried, "\n", tried_size - strlen(tried) - 1); - -#if defined(LIBRARY) - snprintf(buff, buff_size, "%s/%s/test", pwd, LIBRARY); -#else - snprintf(buff, buff_size, "%s/%s/test", pwd, PROGRAM); -#endif - p = slurpfile(NULL, "%s/%s", buff, KNOWNREF); - if (p != NULL) goto success; - strncat(tried, buff, tried_size - strlen(tried) - 1); - strncat(tried, "\n", tried_size - strlen(tried) - 1); - -#if defined(PROGRAM_ALIAS) - snprintf(buff, buff_size, "%s/%s/test", pwd, PROGRAM_ALIAS); - p = slurpfile(NULL, "%s/%s", buff, KNOWNREF); - if (p != NULL) goto success; - strncat(tried, buff, tried_size - strlen(tried) - 1); - strncat(tried, "\n", tried_size - strlen(tried) - 1); -#endif - - if (memcmp(pwd, "/usr/obj", 8) == 0) { - snprintf(buff, buff_size, "%s", pwd + 8); - p = slurpfile(NULL, "%s/%s", buff, KNOWNREF); - if (p != NULL) goto success; - strncat(tried, buff, tried_size - strlen(tried) - 1); - strncat(tried, "\n", tried_size - strlen(tried) - 1); - - snprintf(buff, buff_size, "%s/test", pwd + 8); - p = slurpfile(NULL, "%s/%s", buff, KNOWNREF); - if (p != NULL) goto success; - strncat(tried, buff, tried_size - strlen(tried) - 1); - strncat(tried, "\n", tried_size - strlen(tried) - 1); - } - -failure: - printf("Unable to locate known reference file %s\n", KNOWNREF); - printf(" Checked following directories:\n%s\n", tried); - printf("Use -r option to specify full path to reference directory\n"); -#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG) - DebugBreak(); -#endif - exit(1); - -success: - free(p); - free(pwd); - free(tried); - - /* Copy result into a fresh buffer to reduce memory usage. */ - p = strdup(buff); - free(buff); - return p; -} - -/* Filter tests against a glob pattern. Returns non-zero if test matches - * pattern, zero otherwise. A '^' at the beginning of the pattern negates - * the return values (i.e. returns zero for a match, non-zero otherwise. - */ -static int -test_filter(const char *pattern, const char *test) -{ - int retval = 0; - int negate = 0; - const char *p = pattern; - const char *t = test; - - if (p[0] == '^') - { - negate = 1; - p++; - } - - while (1) - { - if (p[0] == '\\') - p++; - else if (p[0] == '*') - { - while (p[0] == '*') - p++; - if (p[0] == '\\') - p++; - if ((t = strchr(t, p[0])) == 0) - break; - } - if (p[0] != t[0]) - break; - if (p[0] == '\0') { - retval = 1; - break; - } - p++; - t++; - } - - return (negate) ? !retval : retval; -} - -static int -get_test_set(int *test_set, int limit, const char *test) -{ - int start, end; - int idx = 0; - - if (test == NULL) { - /* Default: Run all tests. */ - for (;idx < limit; idx++) - test_set[idx] = idx; - return (limit); - } - if (*test >= '0' && *test <= '9') { - const char *vp = test; - start = 0; - while (*vp >= '0' && *vp <= '9') { - start *= 10; - start += *vp - '0'; - ++vp; - } - if (*vp == '\0') { - end = start; - } else if (*vp == '-') { - ++vp; - if (*vp == '\0') { - end = limit - 1; - } else { - end = 0; - while (*vp >= '0' && *vp <= '9') { - end *= 10; - end += *vp - '0'; - ++vp; - } - } - } else - return (-1); - if (start < 0 || end >= limit || start > end) - return (-1); - while (start <= end) - test_set[idx++] = start++; - } else { - for (start = 0; start < limit; ++start) { - const char *name = tests[start].name; - if (test_filter(test, name)) - test_set[idx++] = start; - } - } - return ((idx == 0)?-1:idx); -} - -int -main(int argc, char **argv) -{ - static const int limit = sizeof(tests) / sizeof(tests[0]); - int test_set[sizeof(tests) / sizeof(tests[0])]; - int i = 0, j = 0, tests_run = 0, tests_failed = 0, option; - int testprogdir_len; -#ifdef PROGRAM - int tmp2_len; -#endif - time_t now; - struct tm *tmptr; -#if defined(HAVE_LOCALTIME_R) || defined(HAVE_LOCALTIME_S) - struct tm tmbuf; -#endif - char *refdir_alloc = NULL; - const char *progname; - char **saved_argv; - const char *tmp, *option_arg, *p; -#ifdef PATH_MAX - char tmpdir[PATH_MAX]; -#else - char tmpdir[256]; -#endif - char *pwd, *testprogdir, *tmp2 = NULL, *vlevel = NULL; - char tmpdir_timestamp[32]; - - (void)argc; /* UNUSED */ - - /* Get the current dir. */ -#if defined(PATH_MAX) && !defined(__GLIBC__) - pwd = getcwd(NULL, PATH_MAX);/* Solaris getcwd needs the size. */ -#else - pwd = getcwd(NULL, 0); -#endif - while (pwd[strlen(pwd) - 1] == '\n') - pwd[strlen(pwd) - 1] = '\0'; - -#if defined(HAVE__CrtSetReportMode) && !defined(__WATCOMC__) - /* To stop to run the default invalid parameter handler. */ - _set_invalid_parameter_handler(invalid_parameter_handler); - /* Disable annoying assertion message box. */ - _CrtSetReportMode(_CRT_ASSERT, 0); -#endif - - /* - * Name of this program, used to build root of our temp directory - * tree. - */ - progname = p = argv[0]; - testprogdir_len = strlen(progname) + 1; - if ((testprogdir = (char *)malloc(testprogdir_len)) == NULL) - { - fprintf(stderr, "ERROR: Out of memory."); - exit(1); - } - strncpy(testprogdir, progname, testprogdir_len); - while (*p != '\0') { - /* Support \ or / dir separators for Windows compat. */ - if (*p == '/' || *p == '\\') - { - progname = p + 1; - i = j; - } - ++p; - j++; - } - testprogdir[i] = '\0'; -#if defined(_WIN32) && !defined(__CYGWIN__) - if (testprogdir[0] != '/' && testprogdir[0] != '\\' && - !(((testprogdir[0] >= 'a' && testprogdir[0] <= 'z') || - (testprogdir[0] >= 'A' && testprogdir[0] <= 'Z')) && - testprogdir[1] == ':' && - (testprogdir[2] == '/' || testprogdir[2] == '\\'))) -#else - if (testprogdir[0] != '/') -#endif - { - /* Fixup path for relative directories. */ - if ((testprogdir = (char *)realloc(testprogdir, - strlen(pwd) + 1 + strlen(testprogdir) + 1)) == NULL) - { - fprintf(stderr, "ERROR: Out of memory."); - exit(1); - } - memmove(testprogdir + strlen(pwd) + 1, testprogdir, - strlen(testprogdir) + 1); - memcpy(testprogdir, pwd, strlen(pwd)); - testprogdir[strlen(pwd)] = '/'; - } - -#ifdef PROGRAM - /* Get the target program from environment, if available. */ - testprogfile = getenv(ENVBASE); -#endif - - if (getenv("TMPDIR") != NULL) - tmp = getenv("TMPDIR"); - else if (getenv("TMP") != NULL) - tmp = getenv("TMP"); - else if (getenv("TEMP") != NULL) - tmp = getenv("TEMP"); - else if (getenv("TEMPDIR") != NULL) - tmp = getenv("TEMPDIR"); - else - tmp = "/tmp"; - - /* Allow -d to be controlled through the environment. */ - if (getenv(ENVBASE "_DEBUG") != NULL) - dump_on_failure = 1; - - /* Allow -v to be controlled through the environment. */ - if (getenv("_VERBOSITY_LEVEL") != NULL) - { - vlevel = getenv("_VERBOSITY_LEVEL"); - verbosity = atoi(vlevel); - if (verbosity < VERBOSITY_SUMMARY_ONLY || verbosity > VERBOSITY_FULL) - { - /* Unsupported verbosity levels are silently ignored */ - vlevel = NULL; - verbosity = VERBOSITY_PASSFAIL; - } - } - - /* Get the directory holding test files from environment. */ - refdir = getenv(ENVBASE "_TEST_FILES"); - - /* - * Parse options, without using getopt(), which isn't available - * on all platforms. - */ - ++argv; /* Skip program name */ - while (*argv != NULL) { - if (**argv != '-') - break; - p = *argv++; - ++p; /* Skip '-' */ - while (*p != '\0') { - option = *p++; - option_arg = NULL; - /* If 'opt' takes an argument, parse that. */ - if (option == 'p' || option == 'r') { - if (*p != '\0') - option_arg = p; - else if (*argv == NULL) { - fprintf(stderr, - "Option -%c requires argument.\n", - option); - usage(progname); - } else - option_arg = *argv++; - p = ""; /* End of this option word. */ - } - - /* Now, handle the option. */ - switch (option) { - case 'd': - dump_on_failure = 1; - break; - case 'k': - keep_temp_files = 1; - break; - case 'p': -#ifdef PROGRAM - testprogfile = option_arg; -#else - fprintf(stderr, "-p option not permitted\n"); - usage(progname); -#endif - break; - case 'q': - if (!vlevel) - verbosity--; - break; - case 'r': - refdir = option_arg; - break; - case 'u': - until_failure++; - break; - case 'v': - if (!vlevel) - verbosity++; - break; - default: - fprintf(stderr, "Unrecognized option '%c'\n", - option); - usage(progname); - } - } - } - - /* - * Sanity-check that our options make sense. - */ -#ifdef PROGRAM - if (testprogfile == NULL) - { - tmp2_len = strlen(testprogdir) + 1 + strlen(PROGRAM) + 1; - if ((tmp2 = (char *)malloc(tmp2_len)) == NULL) - { - fprintf(stderr, "ERROR: Out of memory."); - exit(1); - } - strncpy(tmp2, testprogdir, tmp2_len); - strncat(tmp2, "/", tmp2_len); - strncat(tmp2, PROGRAM, tmp2_len); - testprogfile = tmp2; - } - - { - char *testprg; - int testprg_len; -#if defined(_WIN32) && !defined(__CYGWIN__) - /* Command.com sometimes rejects '/' separators. */ - testprg = strdup(testprogfile); - for (i = 0; testprg[i] != '\0'; i++) { - if (testprg[i] == '/') - testprg[i] = '\\'; - } - testprogfile = testprg; -#endif - /* Quote the name that gets put into shell command lines. */ - testprg_len = strlen(testprogfile) + 3; - testprg = malloc(testprg_len); - strncpy(testprg, "\"", testprg_len); - strncat(testprg, testprogfile, testprg_len); - strncat(testprg, "\"", testprg_len); - testprog = testprg; - } -#endif - -#if !defined(_WIN32) && defined(SIGPIPE) - { /* Ignore SIGPIPE signals */ - struct sigaction sa; - sa.sa_handler = SIG_IGN; - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sigaction(SIGPIPE, &sa, NULL); - } -#endif - - /* - * Create a temp directory for the following tests. - * Include the time the tests started as part of the name, - * to make it easier to track the results of multiple tests. - */ - now = time(NULL); - for (i = 0; ; i++) { -#if defined(HAVE_LOCALTIME_S) - tmptr = localtime_s(&tmbuf, &now) ? NULL : &tmbuf; -#elif defined(HAVE_LOCALTIME_R) - tmptr = localtime_r(&now, &tmbuf); -#else - tmptr = localtime(&now); -#endif - strftime(tmpdir_timestamp, sizeof(tmpdir_timestamp), - "%Y-%m-%dT%H.%M.%S", tmptr); - if ((strlen(tmp) + 1 + strlen(progname) + 1 + - strlen(tmpdir_timestamp) + 1 + 3) > - (sizeof(tmpdir) / sizeof(char))) { - fprintf(stderr, - "ERROR: Temp directory pathname too long\n"); - exit(1); - } - snprintf(tmpdir, sizeof(tmpdir), "%s/%s.%s-%03d", tmp, - progname, tmpdir_timestamp, i); - if (assertMakeDir(tmpdir,0755)) - break; - if (i >= 999) { - fprintf(stderr, - "ERROR: Unable to create temp directory %s\n", - tmpdir); - exit(1); - } - } - - /* - * If the user didn't specify a directory for locating - * reference files, try to find the reference files in - * the "usual places." - */ - refdir = refdir_alloc = get_refdir(refdir); - - /* - * Banner with basic information. - */ - printf("\n"); - printf("If tests fail or crash, details will be in:\n"); - printf(" %s\n", tmpdir); - printf("\n"); - if (verbosity > VERBOSITY_SUMMARY_ONLY) { - printf("Reference files will be read from: %s\n", refdir); -#ifdef PROGRAM - printf("Running tests on: %s\n", testprog); -#endif - printf("Exercising: "); - fflush(stdout); - printf("%s\n", EXTRA_VERSION); - } else { - printf("Running "); - fflush(stdout); - } - - /* - * Run some or all of the individual tests. - */ - saved_argv = argv; - do { - argv = saved_argv; - do { - int test_num; - - test_num = get_test_set(test_set, limit, *argv); - if (test_num < 0) { - printf("*** INVALID Test %s\n", *argv); - free(refdir_alloc); - free(testprogdir); - usage(progname); - return (1); - } - for (i = 0; i < test_num; i++) { - tests_run++; - if (test_run(test_set[i], tmpdir)) { - tests_failed++; - if (until_failure) - goto finish; - } - } - if (*argv != NULL) - argv++; - } while (*argv != NULL); - } while (until_failure); - -finish: - /* Must be freed after all tests run */ - free(tmp2); - free(testprogdir); - free(pwd); - - /* - * Report summary statistics. - */ - if (verbosity > VERBOSITY_SUMMARY_ONLY) { - printf("\n"); - printf("Totals:\n"); - printf(" Tests run: %8d\n", tests_run); - printf(" Tests failed: %8d\n", tests_failed); - printf(" Assertions checked:%8d\n", assertions); - printf(" Assertions failed: %8d\n", failures); - printf(" Skips reported: %8d\n", skips); - } - if (failures) { - printf("\n"); - printf("Failing tests:\n"); - for (i = 0; i < limit; ++i) { - if (tests[i].failures) - printf(" %d: %s (%d failures)\n", i, - tests[i].name, tests[i].failures); - } - printf("\n"); - printf("Details for failing tests: %s\n", tmpdir); - printf("\n"); - } else { - if (verbosity == VERBOSITY_SUMMARY_ONLY) - printf("\n"); - printf("%d tests passed, no failures\n", tests_run); - } - - free(refdir_alloc); - - /* If the final tmpdir is empty, we can remove it. */ - /* This should be the usual case when all tests succeed. */ - assertChdir(".."); - rmdir(tmpdir); - - return (tests_failed ? 1 : 0); -} diff --git a/thirdparty/libarchive/test_utils/test_utils.c b/thirdparty/libarchive/test_utils/test_utils.c deleted file mode 100644 index b79667610..000000000 --- a/thirdparty/libarchive/test_utils/test_utils.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2003-2012 Tim Kientzle - * Copyright (c) 2012 Andres Mejia - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#include "test_utils.h" - -#include -#include -#include -#include -#include - -static inline uint64_t -xorshift64(uint64_t *state) -{ - uint64_t x = *state; - x ^= x << 13; - x ^= x >> 7; - x ^= x << 17; - *state = x; - return (x); -} - -/* - * Fill a buffer with reproducible pseudo-random data using a simple xorshift - * algorithm. Originally, most tests filled buffers with a loop that calls - * rand() once for each byte. However, this initialization can be extremely - * slow when running on emulated platforms such as QEMU where 16M calls to - * rand() take a long time: Before the test_write_format_7zip_large_copy test - * took ~22 seconds, whereas using a xorshift random number generator (that can - * be inlined) reduces it to ~17 seconds on QEMU RISC-V. - */ -static void -fill_with_pseudorandom_data_seed(uint64_t seed, void *buffer, size_t size) -{ - uint64_t *aligned_buffer; - size_t num_values; - size_t i; - size_t unaligned_suffix; - size_t unaligned_prefix = 0; - /* - * To avoid unaligned stores we only fill the aligned part of the buffer - * with pseudo-random data and fill the unaligned prefix with 0xab and - * the suffix with 0xcd. - */ - if ((uintptr_t)buffer % sizeof(uint64_t)) { - unaligned_prefix = - sizeof(uint64_t) - (uintptr_t)buffer % sizeof(uint64_t); - aligned_buffer = - (uint64_t *)((char *)buffer + unaligned_prefix); - memset(buffer, 0xab, unaligned_prefix); - } else { - aligned_buffer = (uint64_t *)buffer; - } - assert((uintptr_t)aligned_buffer % sizeof(uint64_t) == 0); - num_values = (size - unaligned_prefix) / sizeof(uint64_t); - unaligned_suffix = - size - unaligned_prefix - num_values * sizeof(uint64_t); - for (i = 0; i < num_values; i++) { - aligned_buffer[i] = xorshift64(&seed); - } - if (unaligned_suffix) { - memset((char *)buffer + size - unaligned_suffix, 0xcd, - unaligned_suffix); - } -} - -void -fill_with_pseudorandom_data(void *buffer, size_t size) -{ - uint64_t seed; - const char* seed_str; - /* - * Check if a seed has been specified in the environment, otherwise fall - * back to using rand() as a seed. - */ - if ((seed_str = getenv("TEST_RANDOM_SEED")) != NULL) { - errno = 0; - seed = strtoull(seed_str, NULL, 10); - if (errno != 0) { - fprintf(stderr, "strtoull(%s) failed: %s", seed_str, - strerror(errno)); - seed = rand(); - } - } else { - seed = rand(); - } - fill_with_pseudorandom_data_seed(seed, buffer, size); -} diff --git a/thirdparty/libarchive/test_utils/test_utils.h b/thirdparty/libarchive/test_utils/test_utils.h deleted file mode 100644 index 41457890f..000000000 --- a/thirdparty/libarchive/test_utils/test_utils.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2003-2012 Tim Kientzle - * Copyright (c) 2012 Andres Mejia - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#ifndef TEST_UTILS_H -#define TEST_UTILS_H - -#include -#include - -/* Fill a buffer with pseudorandom data */ -void fill_with_pseudorandom_data(void* buffer, size_t size); - -#endif /* TEST_UTILS_H */ diff --git a/thirdparty/libarchive/unzip/CMakeLists.txt b/thirdparty/libarchive/unzip/CMakeLists.txt deleted file mode 100644 index 150eb2c6b..000000000 --- a/thirdparty/libarchive/unzip/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -############################################ -# -# How to build bsdunzip -# -############################################ -IF(ENABLE_UNZIP) - - SET(bsdunzip_SOURCES - bsdunzip.c - bsdunzip.h - bsdunzip_platform.h - cmdline.c - la_getline.c - la_queue.h - ../libarchive_fe/err.c - ../libarchive_fe/err.h - ../libarchive_fe/lafe_platform.h - ../libarchive_fe/passphrase.c - ../libarchive_fe/passphrase.h - ) - INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libarchive_fe) - - # bsdunzip documentation - SET(bsdunzip_MANS bsdunzip.1) - - # How to build bsdunzip - ADD_EXECUTABLE(bsdunzip ${bsdunzip_SOURCES}) - IF(ENABLE_UNZIP_SHARED) - TARGET_LINK_LIBRARIES(bsdunzip archive ${ADDITIONAL_LIBS}) - ELSE(ENABLE_UNZIP_SHARED) - TARGET_LINK_LIBRARIES(bsdunzip archive_static ${ADDITIONAL_LIBS}) - SET_TARGET_PROPERTIES(bsdunzip PROPERTIES COMPILE_DEFINITIONS - LIBARCHIVE_STATIC) - ENDIF(ENABLE_UNZIP_SHARED) - - # Installation rules - INSTALL(TARGETS bsdunzip RUNTIME DESTINATION bin) - INSTALL_MAN(${bsdunzip_MANS}) -ENDIF(ENABLE_UNZIP) - -add_subdirectory(test) diff --git a/thirdparty/libarchive/unzip/bsdunzip.1 b/thirdparty/libarchive/unzip/bsdunzip.1 deleted file mode 100644 index dda01e7b8..000000000 --- a/thirdparty/libarchive/unzip/bsdunzip.1 +++ /dev/null @@ -1,220 +0,0 @@ -.\"- -.\" Copyright (c) 2007-2008 Dag-Erling Smø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. -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ -.\" -.Dd June 27, 2023 -.Dt BSDUNZIP 1 -.Os -.Sh NAME -.Nm bsdunzip -.Nd extract files from a ZIP archive -.Sh SYNOPSIS -.Nm -.Op Fl aCcfjLlnopqtuvy -.Op { Fl O | Fl I No } Ar encoding -.Op Fl d Ar dir -.Op Fl x Ar pattern -.Op Fl P Ar password -.Ar zipfile -.Op Ar member ... -.Sh DESCRIPTION -.\" ... -The following options are available: -.Bl -tag -width Fl -.It Fl a -When extracting a text file, convert DOS-style line endings to -Unix-style line endings. -.It Fl C -Match file names case-insensitively. -.It Fl c -Extract to stdout/screen. -When extracting files from the zipfile, they are written to stdout. -This is similar to -.Fl p , -but does not suppress normal output. -.It Fl d Ar dir -Extract files into the specified directory rather than the current -directory. -.It Fl f -Update existing. -Extract only files from the zipfile if a file with the same name -already exists on disk and is older than the former. -Otherwise, the file is silently skipped. -.It Fl I Ar encoding -.It Fl O Ar encoding -Convert filenames from the specified encoding. -.It Fl j -Ignore directories stored in the zipfile; instead, extract all files -directly into the extraction directory. -.It Fl L -Convert the names of the extracted files and directories to lowercase. -.It Fl l -List, rather than extract, the contents of the zipfile. -.It Fl n -No overwrite. -When extracting a file from the zipfile, if a file with the same name -already exists on disk, the file is silently skipped. -.It Fl o -Overwrite. -When extracting a file from the zipfile, if a file with the same name -already exists on disk, the existing file is replaced with the file -from the zipfile. -.It Fl p -Extract to stdout. -When extracting files from the zipfile, they are written to stdout. -The normal output is suppressed as if -.Fl q -was specified. -.It Fl P Ar password -Extract encrypted files using a password. -Putting a password on the command line using this option can be -insecure. -.It Fl q -Quiet: print less information while extracting. -.It Fl t -Test: do not extract anything, but verify the checksum of every file -in the archive. -.It Fl u -Update. -When extracting a file from the zipfile, if a file with the same name -already exists on disk, the existing file is replaced with the file -from the zipfile if and only if the latter is newer than the former. -Otherwise, the file is silently skipped. -.It Fl v -List verbosely, rather than extract, the contents of the zipfile. -This differs from -.Fl l -by using the long listing. -Note that most of the data is currently fake and does not reflect the -content of the archive. -.It Fl x Ar pattern -Exclude files matching the pattern -.Ar pattern . -.It Fl y -Print four digit years in listings instead of two. -.It Fl Z Ar mode -Emulate -.Xr zipinfo 1L -mode. -Enabling -.Xr zipinfo 1L -mode changes the way in which additional arguments are parsed. -Currently only -.Xr zipinfo 1L -mode 1 is supported, which lists the file names one per line. -.It Ar [member ...] -Optional list of members to extract from the zipfile. -Can include patterns, e.g., -.Ar 'memberdir/*' -will extract all files and dirs below memberdir. -.El -.Pp -Note that only one of -.Fl n , -.Fl o , -and -.Fl u -may be specified. -If specified filename is -.Qq - , -then data is read from -.Va stdin . -.Sh ENVIRONMENT -If the -.Ev UNZIP_DEBUG -environment variable is defined, the -.Fl q -command-line option has no effect, and additional debugging -information will be printed to -.Va stderr . -.Sh COMPATIBILITY -The -.Nm -utility aims to be sufficiently compatible with other implementations -to serve as a drop-in replacement in the context of the -.Xr ports 7 -system. -No attempt has been made to replicate functionality which is not -required for that purpose. -.Pp -For compatibility reasons, command-line options will be recognized if -they are listed not only before but also after the name of the -zipfile. -.Pp -Normally, the -.Fl a -option should only affect files which are marked as text files in the -zipfile's central directory. -Since the -.Xr archive 3 -library does not provide access to that information, it is not available -to the -.Nm -utility. -Instead, the -.Nm -utility will assume that a file is a text file if no non-ASCII -characters are present within the first block of data decompressed for -that file. -If non-ASCII characters appear in subsequent blocks of data, a warning -will be issued. -.Pp -The -.Nm -utility is only able to process ZIP archives handled by -.Xr libarchive 3 . -Depending on the installed version of -.Xr libarchive 3 , -this may or may not include self-extracting or ZIPX archives. -.Sh SEE ALSO -.Xr libarchive 3 -.Sh HISTORY -The -.Nm -utility appeared in -.Fx 8.0 . -.Sh AUTHORS -The -.Nm -utility and this manual page were written by -.An Dag-Erling Sm\(/orgrav Aq Mt des@FreeBSD.org . -It uses the -.Xr archive 3 -library developed by -.An Tim Kientzle Aq Mt kientzle@FreeBSD.org . -.Sh CAVEATS -The -.Nm -utility performs two scans of the command-line for arguments before -and after the archive name, so as to maintain compatibility with -Info-ZIP unzip. -As a result, the POSIX -.Ql -- -double-dash string used to separate options from arguments will need to -be repeated. -For example, to extract a "-a.jpg" from "-b.zip" with overwrite, one -would need to invoke -.Dl bsdunzip -o -- -a.jpg -- -b.zip diff --git a/thirdparty/libarchive/unzip/bsdunzip.c b/thirdparty/libarchive/unzip/bsdunzip.c deleted file mode 100644 index 29c3a1670..000000000 --- a/thirdparty/libarchive/unzip/bsdunzip.c +++ /dev/null @@ -1,1283 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause - * - * Copyright (c) 2009, 2010 Joerg Sonnenberger - * Copyright (c) 2007-2008 Dag-Erling Smø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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$ - * - * This file would be much shorter if we didn't care about command-line - * compatibility with Info-ZIP's UnZip, which requires us to duplicate - * parts of libarchive in order to gain more detailed control of its - * behaviour for the purpose of implementing the -n, -o, -L and -a - * options. - */ - -#include "bsdunzip_platform.h" - -#ifdef HAVE_SYS_QUEUE_H -#include -#else -#include "la_queue.h" -#endif -#ifdef HAVE_SYS_STAT_H -#include -#endif - -#ifdef HAVE_CTYPE_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif -#ifdef HAVE_FNMATCH_H -#include -#endif -#ifdef HAVE_STDARG_H -#include -#endif -#include -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#if ((!defined(HAVE_UTIMENSAT) && defined(HAVE_LUTIMES)) || \ - (!defined(HAVE_FUTIMENS) && defined(HAVE_FUTIMES))) -#ifdef HAVE_SYS_TIME_H -#include -#endif -#endif - -#include "bsdunzip.h" -#include "passphrase.h" -#include "err.h" - -/* command-line options */ -static int a_opt; /* convert EOL */ -static int C_opt; /* match case-insensitively */ -static int c_opt; /* extract to stdout */ -static const char *d_arg; /* directory */ -static int f_opt; /* update existing files only */ -static const char *O_arg; /* encoding */ -static int j_opt; /* junk directories */ -static int L_opt; /* lowercase names */ -static int n_opt; /* never overwrite */ -static int o_opt; /* always overwrite */ -static int p_opt; /* extract to stdout, quiet */ -static const char *P_arg; /* passphrase */ -static int q_opt; /* quiet */ -static int t_opt; /* test */ -static int u_opt; /* update */ -static int v_opt; /* verbose/list */ -static const char *y_str = ""; /* 4 digit year */ -static int Z1_opt; /* zipinfo mode list files only */ -static int version_opt; /* version string */ - -/* debug flag */ -static int unzip_debug; - -/* zipinfo mode */ -static int zipinfo_mode; - -/* running on tty? */ -static int tty; - -/* processing exclude list */ -static int unzip_exclude_mode = 0; - -int bsdunzip_optind; - -/* convenience macro */ -/* XXX should differentiate between ARCHIVE_{WARN,FAIL,RETRY} */ -#define ac(call) \ - do { \ - int acret = (call); \ - if (acret != ARCHIVE_OK) \ - errorx("%s", archive_error_string(a)); \ - } while (0) - -/* - * Indicates that last info() did not end with EOL. This helps error() et - * al. avoid printing an error message on the same line as an incomplete - * informational message. - */ -static int noeol; - -/* for an interactive passphrase input */ -static char *passphrase_buf; - -/* fatal error message + errno */ -static void -error(const char *fmt, ...) -{ - va_list ap; - - if (noeol) - fprintf(stdout, "\n"); - fflush(stdout); - fprintf(stderr, "unzip: "); - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - fprintf(stderr, ": %s\n", strerror(errno)); - exit(EXIT_FAILURE); -} - -/* fatal error message, no errno */ -static void -errorx(const char *fmt, ...) -{ - va_list ap; - - if (noeol) - fprintf(stdout, "\n"); - fflush(stdout); - fprintf(stderr, "unzip: "); - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - fprintf(stderr, "\n"); - exit(EXIT_FAILURE); -} - -/* non-fatal error message + errno */ -static void -warning(const char *fmt, ...) -{ - va_list ap; - - if (noeol) - fprintf(stdout, "\n"); - fflush(stdout); - fprintf(stderr, "unzip: "); - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - fprintf(stderr, ": %s\n", strerror(errno)); -} - -/* non-fatal error message, no errno */ -static void -warningx(const char *fmt, ...) -{ - va_list ap; - - if (noeol) - fprintf(stdout, "\n"); - fflush(stdout); - fprintf(stderr, "unzip: "); - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - fprintf(stderr, "\n"); -} - -/* informational message (if not -q) */ -static void -info(const char *fmt, ...) -{ - va_list ap; - - if (q_opt && !unzip_debug) - return; - va_start(ap, fmt); - vfprintf(stdout, fmt, ap); - va_end(ap); - fflush(stdout); - - if (*fmt == '\0') - noeol = 1; - else - noeol = fmt[strlen(fmt) - 1] != '\n'; -} - -/* debug message (if unzip_debug) */ -static void -debug(const char *fmt, ...) -{ - va_list ap; - - if (!unzip_debug) - return; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - fflush(stderr); - - if (*fmt == '\0') - noeol = 1; - else - noeol = fmt[strlen(fmt) - 1] != '\n'; -} - -/* duplicate a path name, possibly converting to lower case */ -static char * -pathdup(const char *path) -{ - char *str; - size_t i, len; - - if (path == NULL || path[0] == '\0') - return (NULL); - - len = strlen(path); - while (len && path[len - 1] == '/') - len--; - if ((str = malloc(len + 1)) == NULL) { - errno = ENOMEM; - error("malloc()"); - } - if (L_opt) { - for (i = 0; i < len; ++i) - str[i] = tolower((unsigned char)path[i]); - } else { - memcpy(str, path, len); - } - str[len] = '\0'; - - return (str); -} - -/* concatenate two path names */ -static char * -pathcat(const char *prefix, const char *path) -{ - char *str; - size_t prelen, len; - - prelen = prefix ? strlen(prefix) + 1 : 0; - len = strlen(path) + 1; - if ((str = malloc(prelen + len)) == NULL) { - errno = ENOMEM; - error("malloc()"); - } - if (prefix) { - memcpy(str, prefix, prelen); /* includes zero */ - str[prelen - 1] = '/'; /* splat zero */ - } - memcpy(str + prelen, path, len); /* includes zero */ - - return (str); -} - -/* - * Pattern lists for include / exclude processing - */ -struct pattern { - STAILQ_ENTRY(pattern) link; - char pattern[]; -}; - -STAILQ_HEAD(pattern_list, pattern); -static struct pattern_list include = STAILQ_HEAD_INITIALIZER(include); -static struct pattern_list exclude = STAILQ_HEAD_INITIALIZER(exclude); - -/* - * Add an entry to a pattern list - */ -static void -add_pattern(struct pattern_list *list, const char *pattern) -{ - struct pattern *entry; - size_t len; - - debug("adding pattern '%s'\n", pattern); - len = strlen(pattern); - if ((entry = malloc(sizeof *entry + len + 1)) == NULL) { - errno = ENOMEM; - error("malloc()"); - } - memcpy(entry->pattern, pattern, len + 1); - STAILQ_INSERT_TAIL(list, entry, link); -} - -/* - * Match a string against a list of patterns - */ -static int -match_pattern(struct pattern_list *list, const char *str) -{ - struct pattern *entry; - - STAILQ_FOREACH(entry, list, link) { -#ifdef HAVE_FNMATCH - if (fnmatch(entry->pattern, str, C_opt ? FNM_CASEFOLD : 0) == 0) - return (1); -#else -#error "Unsupported platform: fnmatch() is required" -#endif - } - return (0); -} - -/* - * Verify that a given pathname is in the include list and not in the - * exclude list. - */ -static int -accept_pathname(const char *pathname) -{ - - if (!STAILQ_EMPTY(&include) && !match_pattern(&include, pathname)) - return (0); - if (!STAILQ_EMPTY(&exclude) && match_pattern(&exclude, pathname)) - return (0); - return (1); -} - -/* - * Create the specified directory with the specified mode, taking certain - * precautions on they way. - */ -static void -make_dir(const char *path, int mode) -{ - struct stat sb; - - if (lstat(path, &sb) == 0) { - if (S_ISDIR(sb.st_mode)) - return; - /* - * Normally, we should either ask the user about removing - * the non-directory of the same name as a directory we - * wish to create, or respect the -n or -o command-line - * options. However, this may lead to a later failure or - * even compromise (if this non-directory happens to be a - * symlink to somewhere unsafe), so we don't. - */ - - /* - * Don't check unlink() result; failure will cause mkdir() - * to fail later, which we will catch. - */ - (void)unlink(path); - } - if (mkdir(path, mode) != 0 && errno != EEXIST) - error("mkdir('%s')", path); -} - -/* - * Ensure that all directories leading up to (but not including) the - * specified path exist. - * - * XXX inefficient + modifies the file in-place - */ -static void -make_parent(char *path) -{ - struct stat sb; - char *sep; - - sep = strrchr(path, '/'); - if (sep == NULL || sep == path) - return; - *sep = '\0'; - if (lstat(path, &sb) == 0) { - if (S_ISDIR(sb.st_mode)) { - *sep = '/'; - return; - } - unlink(path); - } - make_parent(path); - mkdir(path, 0755); - *sep = '/'; - -#if 0 - for (sep = path; (sep = strchr(sep, '/')) != NULL; sep++) { - /* root in case of absolute d_arg */ - if (sep == path) - continue; - *sep = '\0'; - make_dir(path, 0755); - *sep = '/'; - } -#endif -} - -/* - * Extract a directory. - */ -static void -extract_dir(struct archive *a, struct archive_entry *e, const char *path) -{ - int mode; - - /* - * Dropbox likes to create '/' directory entries, just ignore - * such junk. - */ - if (*path == '\0') - return; - - mode = archive_entry_mode(e) & 0777; - if (mode == 0) - mode = 0755; - - /* - * Some zipfiles contain directories with weird permissions such - * as 0644 or 0444. This can cause strange issues such as being - * unable to extract files into the directory we just created, or - * the user being unable to remove the directory later without - * first manually changing its permissions. Therefore, we whack - * the permissions into shape, assuming that the user wants full - * access and that anyone who gets read access also gets execute - * access. - */ - mode |= 0700; - if (mode & 0040) - mode |= 0010; - if (mode & 0004) - mode |= 0001; - - info(" creating: %s/\n", path); - make_dir(path, mode); - ac(archive_read_data_skip(a)); -} - -static unsigned char buffer[8192]; -static char spinner[] = { '|', '/', '-', '\\' }; - -static int -handle_existing_file(char **path) -{ - size_t alen; - ssize_t len; - char buf[4]; - - for (;;) { - fprintf(stderr, - "replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ", - *path); - if (fgets(buf, sizeof(buf), stdin) == NULL) { - clearerr(stdin); - printf("NULL\n(EOF or read error, " - "treating as \"[N]one\"...)\n"); - n_opt = 1; - return -1; - } - switch (*buf) { - case 'A': - o_opt = 1; - /* FALLTHROUGH */ - case 'y': - case 'Y': - (void)unlink(*path); - return 1; - case 'N': - n_opt = 1; - /* FALLTHROUGH */ - case 'n': - return -1; - case 'r': - case 'R': - printf("New name: "); - fflush(stdout); - free(*path); - *path = NULL; - alen = 0; - len = getline(path, &alen, stdin); - if ((*path)[len - 1] == '\n') - (*path)[len - 1] = '\0'; - return 0; - default: - break; - } - } -} - -/* - * Detect binary files by a combination of character white list and - * black list. NUL bytes and other control codes without use in text files - * result directly in switching the file to binary mode. Otherwise, at least - * one white-listed byte has to be found. - * - * Black-listed: 0..6, 14..25, 28..31 - * 0xf3ffc07f = 11110011111111111100000001111111b - * White-listed: 9..10, 13, >= 32 - * 0x00002600 = 00000000000000000010011000000000b - * - * See the proginfo/txtvsbin.txt in the zip sources for a detailed discussion. - */ -#define BYTE_IS_BINARY(x) ((x) < 32 && (0xf3ffc07fU & (1U << (x)))) -#define BYTE_IS_TEXT(x) ((x) >= 32 || (0x00002600U & (1U << (x)))) - -static int -check_binary(const unsigned char *buf, size_t len) -{ - int rv; - for (rv = 1; len--; ++buf) { - if (BYTE_IS_BINARY(*buf)) - return 1; - if (BYTE_IS_TEXT(*buf)) - rv = 0; - } - - return rv; -} - -/* - * Extract to a file descriptor - */ -static int -extract2fd(struct archive *a, char *pathname, int fd) -{ - int cr, text, warn; - ssize_t len; - unsigned char *p, *q, *end; - - text = a_opt; - warn = 0; - cr = 0; - - /* loop over file contents and write to fd */ - for (int n = 0; ; n++) { - if (fd != STDOUT_FILENO) - if (tty && (n % 4) == 0) - info(" %c\b\b", spinner[(n / 4) % sizeof spinner]); - - len = archive_read_data(a, buffer, sizeof buffer); - - if (len < 0) - ac(len); - - /* left over CR from previous buffer */ - if (a_opt && cr) { - if (len == 0 || buffer[0] != '\n') - if (write(fd, "\r", 1) != 1) - error("write('%s')", pathname); - cr = 0; - } - - /* EOF */ - if (len == 0) - break; - end = buffer + len; - - /* - * Detect whether this is a text file. The correct way to - * do this is to check the least significant bit of the - * "internal file attributes" field of the corresponding - * file header in the central directory, but libarchive - * does not provide access to this field, so we have to - * guess by looking for non-ASCII characters in the - * buffer. Hopefully we won't guess wrong. If we do - * guess wrong, we print a warning message later. - */ - if (a_opt && n == 0) { - if (check_binary(buffer, len)) - text = 0; - } - - /* simple case */ - if (!a_opt || !text) { - if (write(fd, buffer, len) != len) - error("write('%s')", pathname); - continue; - } - - /* hard case: convert \r\n to \n (sigh...) */ - for (p = buffer; p < end; p = q + 1) { - for (q = p; q < end; q++) { - if (!warn && BYTE_IS_BINARY(*q)) { - warningx("%s may be corrupted due" - " to weak text file detection" - " heuristic", pathname); - warn = 1; - } - if (q[0] != '\r') - continue; - if (&q[1] == end) { - cr = 1; - break; - } - if (q[1] == '\n') - break; - } - if (write(fd, p, q - p) != q - p) - error("write('%s')", pathname); - } - } - - return text; -} - -/* - * Extract a regular file. - */ -static void -extract_file(struct archive *a, struct archive_entry *e, char **path) -{ - int mode; - struct timespec mtime; - struct stat sb; - int fd, check, text; - const char *linkname; -#if defined(HAVE_UTIMENSAT) || defined(HAVE_FUTIMENS) - struct timespec ts[2]; -#endif -#if ((!defined(HAVE_UTIMENSAT) && defined(HAVE_LUTIMES)) || \ - (!defined(HAVE_FUTIMENS) && defined(HAVE_FUTIMES))) - struct timeval times[2]; -#endif - - mode = archive_entry_mode(e) & 0777; - if (mode == 0) - mode = 0644; - mtime.tv_sec = archive_entry_mtime(e); - mtime.tv_nsec = archive_entry_mtime_nsec(e); - - /* look for existing file of same name */ -recheck: - if (lstat(*path, &sb) == 0) { - if (u_opt || f_opt) { - /* check if up-to-date */ - if (S_ISREG(sb.st_mode) && ( -#if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC - sb.st_mtimespec.tv_sec > mtime.tv_sec || - (sb.st_mtimespec.tv_sec == mtime.tv_sec && - sb.st_mtimespec.tv_nsec >= mtime.tv_nsec) -#elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC - sb.st_mtim.tv_sec > mtime.tv_sec || - (sb.st_mtim.tv_sec == mtime.tv_sec && - sb.st_mtim.tv_nsec >= mtime.tv_nsec) -#elif HAVE_STRUCT_STAT_ST_MTIME_N - sb.st_mtime > mtime.tv_sec || - (sb.st_mtime == mtime.tv_sec && - sb.st_mtime_n => mtime.tv_nsec) -#elif HAVE_STRUCT_STAT_ST_MTIME_USEC - sb.st_mtime > mtime.tv_sec || - (sb.st_mtime == mtime.tv_sec && - sb.st_mtime_usec => mtime.tv_nsec / 1000) -#else - sb.st_mtime > mtime.tv_sec -#endif - )) - return; - (void)unlink(*path); - } else if (o_opt) { - /* overwrite */ - (void)unlink(*path); - } else if (n_opt) { - /* do not overwrite */ - return; - } else { - check = handle_existing_file(path); - if (check == 0) - goto recheck; - if (check == -1) - return; /* do not overwrite */ - } - } else { - if (f_opt) - return; - } - -#if defined(HAVE_UTIMENSAT) || defined(HAVE_FUTIMENS) - ts[0].tv_sec = 0; - ts[0].tv_nsec = UTIME_NOW; - ts[1] = mtime; -#endif -#if ((!defined(HAVE_UTIMENSAT) && defined(HAVE_LUTIMES)) || \ - (!defined(HAVE_FUTIMENS) && defined(HAVE_FUTIMES))) - times[0].tv_sec = 0; - times[0].tv_usec = -1; - times[1].tv_sec = mtime.tv_sec; - times[1].tv_usec = mtime.tv_nsec / 1000; -#endif - - /* process symlinks */ - linkname = archive_entry_symlink(e); - if (linkname != NULL) { - if (symlink(linkname, *path) != 0) - error("symlink('%s')", *path); - info(" extracting: %s -> %s\n", *path, linkname); -#ifdef HAVE_LCHMOD - if (lchmod(*path, mode) != 0) - warning("Cannot set mode for '%s'", *path); -#endif - /* set access and modification time */ -#if defined(HAVE_UTIMENSAT) - if (utimensat(AT_FDCWD, *path, ts, AT_SYMLINK_NOFOLLOW) != 0) - warning("utimensat('%s')", *path); -#elif defined(HAVE_LUTIMES) - gettimeofday(×[0], NULL); - if (lutimes(*path, times) != 0) - warning("lutimes('%s')", *path); -#endif - return; - } - - if ((fd = open(*path, O_RDWR|O_CREAT|O_TRUNC, mode)) < 0) - error("open('%s')", *path); - - info(" extracting: %s", *path); - - text = extract2fd(a, *path, fd); - - if (tty) - info(" \b\b"); - if (text) - info(" (text)"); - info("\n"); - - /* set access and modification time */ -#if defined(HAVE_FUTIMENS) - if (futimens(fd, ts) != 0) - error("futimens('%s')", *path); -#elif defined(HAVE_FUTIMES) - gettimeofday(×[0], NULL); - if (futimes(fd, times) != 0) - error("futimes('%s')", *path); -#endif - if (close(fd) != 0) - error("close('%s')", *path); -} - -/* - * Extract a zipfile entry: first perform some sanity checks to ensure - * that it is either a directory or a regular file and that the path is - * not absolute and does not try to break out of the current directory; - * then call either extract_dir() or extract_file() as appropriate. - * - * This is complicated a bit by the various ways in which we need to - * manipulate the path name. Case conversion (if requested by the -L - * option) happens first, but the include / exclude patterns are applied - * to the full converted path name, before the directory part of the path - * is removed in accordance with the -j option. Sanity checks are - * intentionally done earlier than they need to be, so the user will get a - * warning about insecure paths even for files or directories which - * wouldn't be extracted anyway. - */ -static void -extract(struct archive *a, struct archive_entry *e) -{ - char *pathname, *realpathname; - mode_t filetype; - char *p, *q; - - if ((pathname = pathdup(archive_entry_pathname(e))) == NULL) { - warningx("skipping empty or unreadable filename entry"); - ac(archive_read_data_skip(a)); - return; - } - filetype = archive_entry_filetype(e); - - /* sanity checks */ - if (pathname[0] == '/' || - strncmp(pathname, "../", 3) == 0 || - strstr(pathname, "/../") != NULL) { - warningx("skipping insecure entry '%s'", pathname); - ac(archive_read_data_skip(a)); - free(pathname); - return; - } - - /* I don't think this can happen in a zipfile.. */ - if (!S_ISDIR(filetype) && !S_ISREG(filetype) && !S_ISLNK(filetype)) { - warningx("skipping non-regular entry '%s'", pathname); - ac(archive_read_data_skip(a)); - free(pathname); - return; - } - - /* skip directories in -j case */ - if (S_ISDIR(filetype) && j_opt) { - ac(archive_read_data_skip(a)); - free(pathname); - return; - } - - /* apply include / exclude patterns */ - if (!accept_pathname(pathname)) { - ac(archive_read_data_skip(a)); - free(pathname); - return; - } - - /* apply -j and -d */ - if (j_opt) { - for (p = q = pathname; *p; ++p) - if (*p == '/') - q = p + 1; - realpathname = pathcat(d_arg, q); - } else { - realpathname = pathcat(d_arg, pathname); - } - - /* ensure that parent directory exists */ - make_parent(realpathname); - - if (S_ISDIR(filetype)) - extract_dir(a, e, realpathname); - else - extract_file(a, e, &realpathname); - - free(realpathname); - free(pathname); -} - -static void -extract_stdout(struct archive *a, struct archive_entry *e) -{ - char *pathname; - mode_t filetype; - - if ((pathname = pathdup(archive_entry_pathname(e))) == NULL) { - warningx("skipping empty or unreadable filename entry"); - ac(archive_read_data_skip(a)); - return; - } - filetype = archive_entry_filetype(e); - - /* I don't think this can happen in a zipfile.. */ - if (!S_ISDIR(filetype) && !S_ISREG(filetype) && !S_ISLNK(filetype)) { - warningx("skipping non-regular entry '%s'", pathname); - ac(archive_read_data_skip(a)); - free(pathname); - return; - } - - /* skip directories in -j case */ - if (S_ISDIR(filetype)) { - ac(archive_read_data_skip(a)); - free(pathname); - return; - } - - /* apply include / exclude patterns */ - if (!accept_pathname(pathname)) { - ac(archive_read_data_skip(a)); - free(pathname); - return; - } - - if (c_opt) - info("x %s\n", pathname); - - (void)extract2fd(a, pathname, STDOUT_FILENO); - - free(pathname); -} - -/* - * Print the name of an entry to stdout. - */ -static void -list(struct archive *a, struct archive_entry *e) -{ - char buf[20]; - time_t mtime; - struct tm *tm; - - mtime = archive_entry_mtime(e); - tm = localtime(&mtime); - if (*y_str) - strftime(buf, sizeof(buf), "%m-%d-%G %R", tm); - else - strftime(buf, sizeof(buf), "%m-%d-%g %R", tm); - - if (!zipinfo_mode) { - if (v_opt == 1) { - printf(" %8ju %s %s\n", - (uintmax_t)archive_entry_size(e), - buf, archive_entry_pathname(e)); - } else if (v_opt == 2) { - printf("%8ju Stored %7ju 0%% %s %08x %s\n", - (uintmax_t)archive_entry_size(e), - (uintmax_t)archive_entry_size(e), - buf, - 0U, - archive_entry_pathname(e)); - } - } else { - if (Z1_opt) - printf("%s\n",archive_entry_pathname(e)); - } - ac(archive_read_data_skip(a)); -} - -/* - * Extract to memory to check CRC - */ -static int -test(struct archive *a, struct archive_entry *e) -{ - ssize_t len; - int error_count; - - error_count = 0; - if (S_ISDIR(archive_entry_filetype(e))) - return 0; - - info(" testing: %s\t", archive_entry_pathname(e)); - while ((len = archive_read_data(a, buffer, sizeof buffer)) > 0) - /* nothing */; - if (len < 0) { - info(" %s\n", archive_error_string(a)); - ++error_count; - } else { - info(" OK\n"); - } - - /* shouldn't be necessary, but it doesn't hurt */ - ac(archive_read_data_skip(a)); - - return error_count; -} - -/* - * Callback function for reading passphrase. - * Originally from cpio.c and passphrase.c, libarchive. - */ -#define PPBUFF_SIZE 1024 -static const char * -passphrase_callback(struct archive *a, void *_client_data) -{ - char *p; - - (void)a; /* UNUSED */ - (void)_client_data; /* UNUSED */ - - if (passphrase_buf == NULL) { - passphrase_buf = malloc(PPBUFF_SIZE); - if (passphrase_buf == NULL) { - errno = ENOMEM; - error("malloc()"); - } - } - - p = lafe_readpassphrase("\nEnter password: ", passphrase_buf, - PPBUFF_SIZE); - - if (p == NULL && errno != EINTR) - error("Error reading password"); - - return p; -} - -/* - * Main loop: open the zipfile, iterate over its contents and decide what - * to do with each entry. - */ -static void -unzip(const char *fn) -{ - struct archive *a; - struct archive_entry *e; - int ret; - uintmax_t total_size, file_count, error_count; - - if ((a = archive_read_new()) == NULL) - error("archive_read_new failed"); - - ac(archive_read_support_format_zip(a)); - - if (O_arg) - ac(archive_read_set_format_option(a, "zip", "hdrcharset", O_arg)); - - if (P_arg) - archive_read_add_passphrase(a, P_arg); - else - archive_read_set_passphrase_callback(a, NULL, - &passphrase_callback); - - ac(archive_read_open_filename(a, fn, 8192)); - - if (!zipinfo_mode) { - if (!p_opt && !q_opt) - printf("Archive: %s\n", fn); - if (v_opt == 1) { - printf(" Length %sDate Time Name\n", y_str); - printf(" -------- %s---- ---- ----\n", y_str); - } else if (v_opt == 2) { - printf(" Length Method Size Ratio %sDate Time CRC-32 Name\n", y_str); - printf("-------- ------ ------- ----- %s---- ---- ------ ----\n", y_str); - } - } - - total_size = 0; - file_count = 0; - error_count = 0; - for (;;) { - ret = archive_read_next_header(a, &e); - if (ret == ARCHIVE_EOF) - break; - ac(ret); - if (!zipinfo_mode) { - if (t_opt) - error_count += test(a, e); - else if (v_opt) - list(a, e); - else if (p_opt || c_opt) - extract_stdout(a, e); - else - extract(a, e); - } else { - if (Z1_opt) - list(a, e); - } - - total_size += archive_entry_size(e); - ++file_count; - } - - if (zipinfo_mode) { - if (v_opt == 1) { - printf(" -------- %s-------\n", y_str); - printf(" %8ju %s%ju file%s\n", - total_size, y_str, file_count, file_count != 1 ? "s" : ""); - } else if (v_opt == 2) { - printf("-------- ------- --- %s-------\n", y_str); - printf("%8ju %7ju 0%% %s%ju file%s\n", - total_size, total_size, y_str, file_count, - file_count != 1 ? "s" : ""); - } - } - - ac(archive_read_free(a)); - - if (passphrase_buf != NULL) { - memset(passphrase_buf, 0, PPBUFF_SIZE); - free(passphrase_buf); - } - - if (t_opt) { - if (error_count > 0) { - errorx("%ju checksum error(s) found.", error_count); - } - else { - printf("No errors detected in compressed data of %s.\n", - fn); - } - } -} - -static void -usage(void) -{ - - fprintf(stderr, -"Usage: unzip [-aCcfjLlnopqtuvyZ1] [{-O|-I} encoding] [-d dir] [-x pattern] [-P password] zipfile\n" -" [member ...]\n"); - exit(EXIT_FAILURE); -} - -static void -version(void) -{ - printf("bsdunzip %s - %s \n", - BSDUNZIP_VERSION_STRING, - archive_version_details()); - exit(0); -} - -static int -getopts(int argc, char *argv[]) -{ - struct bsdunzip *bsdunzip, bsdunzip_storage; - int opt; - bsdunzip_optind = 1; - - bsdunzip = &bsdunzip_storage; - memset(bsdunzip, 0, sizeof(*bsdunzip)); - - bsdunzip->argv = argv; - bsdunzip->argc = argc; - - while ((opt = bsdunzip_getopt(bsdunzip)) != -1) { - unzip_exclude_mode = 0; - switch (opt) { - case 'a': - a_opt = 1; - break; - case 'C': - C_opt = 1; - break; - case 'c': - c_opt = 1; - break; - case 'd': - d_arg = bsdunzip->argument; - break; - case 'f': - f_opt = 1; - break; - case 'I': - case 'O': - O_arg = bsdunzip->argument; - break; - case 'j': - j_opt = 1; - break; - case 'L': - L_opt = 1; - break; - case 'l': - if (v_opt == 0) - v_opt = 1; - break; - case 'n': - n_opt = 1; - break; - case 'o': - o_opt = 1; - q_opt = 1; - break; - case 'p': - p_opt = 1; - break; - case 'P': - P_arg = bsdunzip->argument; - break; - case 'q': - q_opt = 1; - break; - case 't': - t_opt = 1; - break; - case 'u': - u_opt = 1; - break; - case 'v': - v_opt = 2; - break; - case 'x': - add_pattern(&exclude, bsdunzip->argument); - unzip_exclude_mode = 1; - break; - case 'y': - y_str = " "; - break; - case 'Z': - zipinfo_mode = 1; - if (bsdunzip->argument != NULL && - strcmp(bsdunzip->argument, "1") == 0) { - Z1_opt = 1; - } - break; - case OPTION_VERSION: - version_opt = 1; - break; - case OPTION_NONE: - break; - default: - usage(); - } - if (opt == OPTION_NONE) - break; - } - return (bsdunzip_optind); -} - -int -main(int argc, char *argv[]) -{ - const char *zipfile; - int nopts; - - lafe_setprogname(*argv, "bsdunzip"); - - if (isatty(STDOUT_FILENO)) - tty = 1; - - if (getenv("UNZIP_DEBUG") != NULL) - unzip_debug = 1; - for (int i = 0; i < argc; ++i) - debug("%s%c", argv[i], (i < argc - 1) ? ' ' : '\n'); - -#ifdef __GLIBC__ - /* Prevent GNU getopt(3) from rearranging options. */ - setenv("POSIXLY_CORRECT", "", 1); -#endif - /* - * Info-ZIP's unzip(1) expects certain options to come before the - * zipfile name, and others to come after - though it does not - * enforce this. For simplicity, we accept *all* options both - * before and after the zipfile name. - */ - nopts = getopts(argc, argv); - - if (version_opt == 1) { - version(); - exit(EXIT_SUCCESS); - } - - /* - * When more of the zipinfo mode options are implemented, this - * will need to change. - */ - if (zipinfo_mode && !Z1_opt) { - printf("Zipinfo mode needs additional options\n"); - exit(EXIT_FAILURE); - } - - if (argc <= nopts) - usage(); - zipfile = argv[nopts++]; - - if (strcmp(zipfile, "-") == 0) - zipfile = NULL; /* STDIN */ - - unzip_exclude_mode = 0; - - while (nopts < argc && *argv[nopts] != '-') - add_pattern(&include, argv[nopts++]); - - nopts--; /* fake argv[0] */ - nopts += getopts(argc - nopts, argv + nopts); - - /* - * For compatibility with Info-ZIP's unzip(1) we need to treat - * non-option arguments following an -x after the zipfile as - * exclude list members. - */ - if (unzip_exclude_mode) { - while (nopts < argc && *argv[nopts] != '-') - add_pattern(&exclude, argv[nopts++]); - nopts--; /* fake argv[0] */ - nopts += getopts(argc - nopts, argv + nopts); - } - - /* There may be residual arguments if we encountered -- */ - while (nopts < argc) - add_pattern(&include, argv[nopts++]); - - if (n_opt + o_opt + u_opt > 1) - errorx("-n, -o and -u are contradictory"); - - unzip(zipfile); - - exit(EXIT_SUCCESS); -} diff --git a/thirdparty/libarchive/unzip/bsdunzip.h b/thirdparty/libarchive/unzip/bsdunzip.h deleted file mode 100644 index ab81e3930..000000000 --- a/thirdparty/libarchive/unzip/bsdunzip.h +++ /dev/null @@ -1,60 +0,0 @@ -/*- - * Copyright (c) 2023, Martin Matuska - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -#ifndef BSDUNZIP_H_INCLUDED -#define BSDUNZIP_H_INCLUDED - -#if defined(PLATFORM_CONFIG_H) -/* Use hand-built config.h in environments that need it. */ -#include PLATFORM_CONFIG_H -#else -/* Not having a config.h of some sort is a serious problem. */ -#include "config.h" -#endif - -#include -#include - -struct bsdunzip { - /* Option parser state */ - int getopt_state; - char *getopt_word; - - /* Miscellaneous state information */ - int argc; - char **argv; - const char *argument; -}; - -enum { - OPTION_NONE, - OPTION_VERSION -}; - -int bsdunzip_getopt(struct bsdunzip *); - -extern int bsdunzip_optind; - -#endif diff --git a/thirdparty/libarchive/unzip/bsdunzip_platform.h b/thirdparty/libarchive/unzip/bsdunzip_platform.h deleted file mode 100644 index 76eca4f90..000000000 --- a/thirdparty/libarchive/unzip/bsdunzip_platform.h +++ /dev/null @@ -1,75 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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/usr.bin/tar/bsdtar_platform.h,v 1.26 2008/12/06 07:37:14 kientzle Exp $ - */ - -/* - * This header is the first thing included in any of the bsdtar - * source files. As far as possible, platform-specific issues should - * be dealt with here and not within individual source files. - */ - -#ifndef BSDUNZIP_PLATFORM_H_INCLUDED -#define BSDUNZIP_PLATFORM_H_INCLUDED - -#if defined(PLATFORM_CONFIG_H) -/* Use hand-built config.h in environments that need it. */ -#include PLATFORM_CONFIG_H -#else -/* Not having a config.h of some sort is a serious problem. */ -#include "config.h" -#endif - -/* Get a real definition for __FBSDID if we can */ -#if HAVE_SYS_CDEFS_H -#include -#endif - -/* If not, define it so as to avoid dangling semicolons. */ -#ifndef __FBSDID -#define __FBSDID(a) struct _undefined_hack -#endif - -#ifdef HAVE_LIBARCHIVE -/* If we're using the platform libarchive, include system headers. */ -#include -#include -#else -/* Otherwise, include user headers. */ -#include "archive.h" -#include "archive_entry.h" -#endif - -/* How to mark functions that don't return. */ -/* This facilitates use of some newer static code analysis tools. */ -#undef __LA_DEAD -#if defined(__GNUC__) && (__GNUC__ > 2 || \ - (__GNUC__ == 2 && __GNUC_MINOR__ >= 5)) -#define __LA_DEAD __attribute__((__noreturn__)) -#else -#define __LA_DEAD -#endif - -#endif /* !BSDUNZIP_PLATFORM_H_INCLUDED */ diff --git a/thirdparty/libarchive/unzip/cmdline.c b/thirdparty/libarchive/unzip/cmdline.c deleted file mode 100644 index 76eb423de..000000000 --- a/thirdparty/libarchive/unzip/cmdline.c +++ /dev/null @@ -1,248 +0,0 @@ -/*- - * Copyright (c) 2003-2008 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ - -/* - * Command line parser for bsdunzip. - */ - -#include "bsdunzip_platform.h" -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#include "bsdunzip.h" -#include "err.h" - -/* - * Short options for bsdunzip. Please keep this sorted. - */ -static const char *short_options - = "aCcd:fI:jLlnO:opP:qtuvx:yZ:"; - -/* - * Long options for bsdunzip. Please keep this list sorted. - * - * The symbolic names for options that lack a short equivalent are - * defined in bsdunzip.h. Also note that so far I've found no need - * to support optional arguments to long options. That would be - * a small change to the code below. - */ - -static const struct bsdunzip_option { - const char *name; - int required; /* 1 if this option requires an argument. */ - int equivalent; /* Equivalent short option. */ -} bsdunzip_longopts[] = { - { "version", 0, OPTION_VERSION }, - { NULL, 0, 0 } -}; - -/* - * This getopt implementation has two key features that common - * getopt_long() implementations lack. Apart from those, it's a - * straightforward option parser, considerably simplified by not - * needing to support the wealth of exotic getopt_long() features. It - * has, of course, been shamelessly tailored for bsdunzip. (If you're - * looking for a generic getopt_long() implementation for your - * project, I recommend Gregory Pietsch's public domain getopt_long() - * implementation.) The two additional features are: - */ - -int -bsdunzip_getopt(struct bsdunzip *bsdunzip) -{ - enum { state_start = 0, state_next_word, state_short, state_long }; - - const struct bsdunzip_option *popt, *match = NULL, *match2 = NULL; - const char *p, *long_prefix = "--"; - size_t optlength; - int opt = OPTION_NONE; - int required = 0; - - bsdunzip->argument = NULL; - - /* First time through, initialize everything. */ - if (bsdunzip->getopt_state == state_start) { - /* Skip program name. */ - ++bsdunzip->argv; - --bsdunzip->argc; - if (*bsdunzip->argv == NULL) - return (-1); - bsdunzip->getopt_state = state_next_word; - } - - /* - * We're ready to look at the next word in argv. - */ - if (bsdunzip->getopt_state == state_next_word) { - /* No more arguments, so no more options. */ - if (bsdunzip->argv[0] == NULL) - return (-1); - /* Doesn't start with '-', so no more options. */ - if (bsdunzip->argv[0][0] != '-') - return (-1); - /* "--" marks end of options; consume it and return. */ - if (strcmp(bsdunzip->argv[0], "--") == 0) { - ++bsdunzip->argv; - --bsdunzip->argc; - return (-1); - } - /* Get next word for parsing. */ - bsdunzip->getopt_word = *bsdunzip->argv++; - --bsdunzip->argc; - bsdunzip_optind++; - if (bsdunzip->getopt_word[1] == '-') { - /* Set up long option parser. */ - bsdunzip->getopt_state = state_long; - bsdunzip->getopt_word += 2; /* Skip leading '--' */ - } else { - /* Set up short option parser. */ - bsdunzip->getopt_state = state_short; - ++bsdunzip->getopt_word; /* Skip leading '-' */ - } - } - - /* - * We're parsing a group of POSIX-style single-character options. - */ - if (bsdunzip->getopt_state == state_short) { - /* Peel next option off of a group of short options. */ - opt = *bsdunzip->getopt_word++; - if (opt == '\0') { - /* End of this group; recurse to get next option. */ - bsdunzip->getopt_state = state_next_word; - return bsdunzip_getopt(bsdunzip); - } - - /* Does this option take an argument? */ - p = strchr(short_options, opt); - if (p == NULL) - return ('?'); - if (p[1] == ':') - required = 1; - - /* If it takes an argument, parse that. */ - if (required) { - /* If arg is run-in, bsdunzip->getopt_word already points to it. */ - if (bsdunzip->getopt_word[0] == '\0') { - /* Otherwise, pick up the next word. */ - bsdunzip->getopt_word = *bsdunzip->argv; - if (bsdunzip->getopt_word == NULL) { - lafe_warnc(0, - "Option -%c requires an argument", - opt); - return ('?'); - } - ++bsdunzip->argv; - --bsdunzip->argc; - bsdunzip_optind++; - } - bsdunzip->getopt_state = state_next_word; - bsdunzip->argument = bsdunzip->getopt_word; - } - } - - /* We're reading a long option */ - if (bsdunzip->getopt_state == state_long) { - /* After this long option, we'll be starting a new word. */ - bsdunzip->getopt_state = state_next_word; - - /* Option name ends at '=' if there is one. */ - p = strchr(bsdunzip->getopt_word, '='); - if (p != NULL) { - optlength = (size_t)(p - bsdunzip->getopt_word); - bsdunzip->argument = (char *)(uintptr_t)(p + 1); - } else { - optlength = strlen(bsdunzip->getopt_word); - } - - /* Search the table for an unambiguous match. */ - for (popt = bsdunzip_longopts; popt->name != NULL; popt++) { - /* Short-circuit if first chars don't match. */ - if (popt->name[0] != bsdunzip->getopt_word[0]) - continue; - /* If option is a prefix of name in table, record it.*/ - if (strncmp(bsdunzip->getopt_word, popt->name, optlength) == 0) { - match2 = match; /* Record up to two matches. */ - match = popt; - /* If it's an exact match, we're done. */ - if (strlen(popt->name) == optlength) { - match2 = NULL; /* Forget the others. */ - break; - } - } - } - - /* Fail if there wasn't a unique match. */ - if (match == NULL) { - lafe_warnc(0, - "Option %s%s is not supported", - long_prefix, bsdunzip->getopt_word); - return ('?'); - } - if (match2 != NULL) { - lafe_warnc(0, - "Ambiguous option %s%s (matches --%s and --%s)", - long_prefix, bsdunzip->getopt_word, match->name, match2->name); - return ('?'); - } - - /* We've found a unique match; does it need an argument? */ - if (match->required) { - /* Argument required: get next word if necessary. */ - if (bsdunzip->argument == NULL) { - bsdunzip->argument = *bsdunzip->argv; - if (bsdunzip->argument == NULL) { - lafe_warnc(0, - "Option %s%s requires an argument", - long_prefix, match->name); - return ('?'); - } - ++bsdunzip->argv; - --bsdunzip->argc; - bsdunzip_optind++; - } - } else { - /* Argument forbidden: fail if there is one. */ - if (bsdunzip->argument != NULL) { - lafe_warnc(0, - "Option %s%s does not allow an argument", - long_prefix, match->name); - return ('?'); - } - } - return (match->equivalent); - } - - return (opt); -} diff --git a/thirdparty/libarchive/unzip/la_getline.c b/thirdparty/libarchive/unzip/la_getline.c deleted file mode 100644 index 79a6bc010..000000000 --- a/thirdparty/libarchive/unzip/la_getline.c +++ /dev/null @@ -1,99 +0,0 @@ -/* $NetBSD: getline.c,v 1.2 2014/09/16 17:23:50 christos Exp $ */ - -/*- - * Copyright (c) 2011 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Christos Zoulas. - * - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``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 FOUNDATION OR CONTRIBUTORS - * 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. - */ - -#include "bsdunzip_platform.h" -#ifndef HAVE_GETLINE - -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_STDIO_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -static ssize_t -la_getdelim(char **buf, size_t *bufsiz, int delimiter, FILE *fp) -{ - char *ptr, *eptr; - - - if (*buf == NULL || *bufsiz == 0) { - *bufsiz = BUFSIZ; - if ((*buf = malloc(*bufsiz)) == NULL) - return -1; - } - - for (ptr = *buf, eptr = *buf + *bufsiz;;) { - int c = fgetc(fp); - if (c == -1) { - if (feof(fp)) { - ssize_t diff = (ssize_t)(ptr - *buf); - if (diff != 0) { - *ptr = '\0'; - return diff; - } - } - return -1; - } - *ptr++ = c; - if (c == delimiter) { - *ptr = '\0'; - return ptr - *buf; - } - if (ptr + 2 >= eptr) { - char *nbuf; - size_t nbufsiz = *bufsiz * 2; - ssize_t d = ptr - *buf; - if ((nbuf = realloc(*buf, nbufsiz)) == NULL) - return -1; - *buf = nbuf; - *bufsiz = nbufsiz; - eptr = nbuf + nbufsiz; - ptr = nbuf + d; - } - } -} - -ssize_t -getline(char **buf, size_t *bufsiz, FILE *fp) -{ - return la_getdelim(buf, bufsiz, '\n', fp); -} -#endif diff --git a/thirdparty/libarchive/unzip/la_queue.h b/thirdparty/libarchive/unzip/la_queue.h deleted file mode 100644 index 917526531..000000000 --- a/thirdparty/libarchive/unzip/la_queue.h +++ /dev/null @@ -1,840 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - */ - -#ifndef _SYS_QUEUE_H_ -#define _SYS_QUEUE_H_ - -/* - * This file defines four types of data structures: singly-linked lists, - * singly-linked tail queues, lists and tail queues. - * - * A singly-linked list is headed by a single forward pointer. The elements - * are singly linked for minimum space and pointer manipulation overhead at - * the expense of O(n) removal for arbitrary elements. New elements can be - * added to the list after an existing element or at the head of the list. - * Elements being removed from the head of the list should use the explicit - * macro for this purpose for optimum efficiency. A singly-linked list may - * only be traversed in the forward direction. Singly-linked lists are ideal - * for applications with large datasets and few or no removals or for - * implementing a LIFO queue. - * - * A singly-linked tail queue is headed by a pair of pointers, one to the - * head of the list and the other to the tail of the list. The elements are - * singly linked for minimum space and pointer manipulation overhead at the - * expense of O(n) removal for arbitrary elements. New elements can be added - * to the list after an existing element, at the head of the list, or at the - * end of the list. Elements being removed from the head of the tail queue - * should use the explicit macro for this purpose for optimum efficiency. - * A singly-linked tail queue may only be traversed in the forward direction. - * Singly-linked tail queues are ideal for applications with large datasets - * and few or no removals or for implementing a FIFO queue. - * - * A list is headed by a single forward pointer (or an array of forward - * pointers for a hash table header). The elements are doubly linked - * so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before - * or after an existing element or at the head of the list. A list - * may be traversed in either direction. - * - * A tail queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or - * after an existing element, at the head of the list, or at the end of - * the list. A tail queue may be traversed in either direction. - * - * For details on the use of these macros, see the queue(3) manual page. - * - * Below is a summary of implemented functions where: - * + means the macro is available - * - means the macro is not available - * s means the macro is available but is slow (runs in O(n) time) - * - * SLIST LIST STAILQ TAILQ - * _HEAD + + + + - * _CLASS_HEAD + + + + - * _HEAD_INITIALIZER + + + + - * _ENTRY + + + + - * _CLASS_ENTRY + + + + - * _INIT + + + + - * _EMPTY + + + + - * _FIRST + + + + - * _NEXT + + + + - * _PREV - + - + - * _LAST - - + + - * _LAST_FAST - - - + - * _FOREACH + + + + - * _FOREACH_FROM + + + + - * _FOREACH_SAFE + + + + - * _FOREACH_FROM_SAFE + + + + - * _FOREACH_REVERSE - - - + - * _FOREACH_REVERSE_FROM - - - + - * _FOREACH_REVERSE_SAFE - - - + - * _FOREACH_REVERSE_FROM_SAFE - - - + - * _INSERT_HEAD + + + + - * _INSERT_BEFORE - + - + - * _INSERT_AFTER + + + + - * _INSERT_TAIL - - + + - * _CONCAT s s + + - * _REMOVE_AFTER + - + - - * _REMOVE_HEAD + - + - - * _REMOVE s + s + - * _SWAP + + + + - */ -#ifdef QUEUE_MACRO_DEBUG -#warn Use QUEUE_MACRO_DEBUG_TRACE and/or QUEUE_MACRO_DEBUG_TRASH -#define QUEUE_MACRO_DEBUG_TRACE -#define QUEUE_MACRO_DEBUG_TRASH -#endif - -#ifdef QUEUE_MACRO_DEBUG_TRACE -/* Store the last 2 places the queue element or head was altered */ -struct qm_trace { - unsigned long lastline; - unsigned long prevline; - const char *lastfile; - const char *prevfile; -}; - -#define TRACEBUF struct qm_trace trace; -#define TRACEBUF_INITIALIZER { __LINE__, 0, __FILE__, NULL } , - -#define QMD_TRACE_HEAD(head) do { \ - (head)->trace.prevline = (head)->trace.lastline; \ - (head)->trace.prevfile = (head)->trace.lastfile; \ - (head)->trace.lastline = __LINE__; \ - (head)->trace.lastfile = __FILE__; \ -} while (0) - -#define QMD_TRACE_ELEM(elem) do { \ - (elem)->trace.prevline = (elem)->trace.lastline; \ - (elem)->trace.prevfile = (elem)->trace.lastfile; \ - (elem)->trace.lastline = __LINE__; \ - (elem)->trace.lastfile = __FILE__; \ -} while (0) - -#else /* !QUEUE_MACRO_DEBUG_TRACE */ -#define QMD_TRACE_ELEM(elem) -#define QMD_TRACE_HEAD(head) -#define TRACEBUF -#define TRACEBUF_INITIALIZER -#endif /* QUEUE_MACRO_DEBUG_TRACE */ - -#ifdef QUEUE_MACRO_DEBUG_TRASH -#define QMD_SAVELINK(name, link) void **name = (void *)&(link) -#define TRASHIT(x) do {(x) = (void *)-1;} while (0) -#define QMD_IS_TRASHED(x) ((x) == (void *)(intptr_t)-1) -#else /* !QUEUE_MACRO_DEBUG_TRASH */ -#define QMD_SAVELINK(name, link) -#define TRASHIT(x) -#define QMD_IS_TRASHED(x) 0 -#endif /* QUEUE_MACRO_DEBUG_TRASH */ - -#ifdef __cplusplus -/* - * In C++ there can be structure lists and class lists: - */ -#define QUEUE_TYPEOF(type) type -#else -#define QUEUE_TYPEOF(type) struct type -#endif - -/* - * Singly-linked List declarations. - */ -#define SLIST_HEAD(name, type) \ -struct name { \ - struct type *slh_first; /* first element */ \ -} - -#define SLIST_CLASS_HEAD(name, type) \ -struct name { \ - class type *slh_first; /* first element */ \ -} - -#define SLIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define SLIST_ENTRY(type) \ -struct { \ - struct type *sle_next; /* next element */ \ -} - -#define SLIST_CLASS_ENTRY(type) \ -struct { \ - class type *sle_next; /* next element */ \ -} - -/* - * Singly-linked List functions. - */ -#if (defined(_KERNEL) && defined(INVARIANTS)) -#define QMD_SLIST_CHECK_PREVPTR(prevp, elm) do { \ - if (*(prevp) != (elm)) \ - panic("Bad prevptr *(%p) == %p != %p", \ - (prevp), *(prevp), (elm)); \ -} while (0) -#else -#define QMD_SLIST_CHECK_PREVPTR(prevp, elm) -#endif - -#define SLIST_CONCAT(head1, head2, type, field) do { \ - QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head1); \ - if (curelm == NULL) { \ - if ((SLIST_FIRST(head1) = SLIST_FIRST(head2)) != NULL) \ - SLIST_INIT(head2); \ - } else if (SLIST_FIRST(head2) != NULL) { \ - while (SLIST_NEXT(curelm, field) != NULL) \ - curelm = SLIST_NEXT(curelm, field); \ - SLIST_NEXT(curelm, field) = SLIST_FIRST(head2); \ - SLIST_INIT(head2); \ - } \ -} while (0) - -#define SLIST_EMPTY(head) ((head)->slh_first == NULL) - -#define SLIST_FIRST(head) ((head)->slh_first) - -#define SLIST_FOREACH(var, head, field) \ - for ((var) = SLIST_FIRST((head)); \ - (var); \ - (var) = SLIST_NEXT((var), field)) - -#define SLIST_FOREACH_FROM(var, head, field) \ - for ((var) = ((var) ? (var) : SLIST_FIRST((head))); \ - (var); \ - (var) = SLIST_NEXT((var), field)) - -#define SLIST_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = SLIST_FIRST((head)); \ - (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define SLIST_FOREACH_FROM_SAFE(var, head, field, tvar) \ - for ((var) = ((var) ? (var) : SLIST_FIRST((head))); \ - (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \ - for ((varp) = &SLIST_FIRST((head)); \ - ((var) = *(varp)) != NULL; \ - (varp) = &SLIST_NEXT((var), field)) - -#define SLIST_INIT(head) do { \ - SLIST_FIRST((head)) = NULL; \ -} while (0) - -#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ - SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ - SLIST_NEXT((slistelm), field) = (elm); \ -} while (0) - -#define SLIST_INSERT_HEAD(head, elm, field) do { \ - SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ - SLIST_FIRST((head)) = (elm); \ -} while (0) - -#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) - -#define SLIST_REMOVE(head, elm, type, field) do { \ - QMD_SAVELINK(oldnext, (elm)->field.sle_next); \ - if (SLIST_FIRST((head)) == (elm)) { \ - SLIST_REMOVE_HEAD((head), field); \ - } \ - else { \ - QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head); \ - while (SLIST_NEXT(curelm, field) != (elm)) \ - curelm = SLIST_NEXT(curelm, field); \ - SLIST_REMOVE_AFTER(curelm, field); \ - } \ - TRASHIT(*oldnext); \ -} while (0) - -#define SLIST_REMOVE_AFTER(elm, field) do { \ - SLIST_NEXT(elm, field) = \ - SLIST_NEXT(SLIST_NEXT(elm, field), field); \ -} while (0) - -#define SLIST_REMOVE_HEAD(head, field) do { \ - SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ -} while (0) - -#define SLIST_REMOVE_PREVPTR(prevp, elm, field) do { \ - QMD_SLIST_CHECK_PREVPTR(prevp, elm); \ - *(prevp) = SLIST_NEXT(elm, field); \ - TRASHIT((elm)->field.sle_next); \ -} while (0) - -#define SLIST_SWAP(head1, head2, type) do { \ - QUEUE_TYPEOF(type) *swap_first = SLIST_FIRST(head1); \ - SLIST_FIRST(head1) = SLIST_FIRST(head2); \ - SLIST_FIRST(head2) = swap_first; \ -} while (0) - -/* - * Singly-linked Tail queue declarations. - */ -#define STAILQ_HEAD(name, type) \ -struct name { \ - struct type *stqh_first;/* first element */ \ - struct type **stqh_last;/* addr of last next element */ \ -} - -#define STAILQ_CLASS_HEAD(name, type) \ -struct name { \ - class type *stqh_first; /* first element */ \ - class type **stqh_last; /* addr of last next element */ \ -} - -#define STAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).stqh_first } - -#define STAILQ_ENTRY(type) \ -struct { \ - struct type *stqe_next; /* next element */ \ -} - -#define STAILQ_CLASS_ENTRY(type) \ -struct { \ - class type *stqe_next; /* next element */ \ -} - -/* - * Singly-linked Tail queue functions. - */ -#define STAILQ_CONCAT(head1, head2) do { \ - if (!STAILQ_EMPTY((head2))) { \ - *(head1)->stqh_last = (head2)->stqh_first; \ - (head1)->stqh_last = (head2)->stqh_last; \ - STAILQ_INIT((head2)); \ - } \ -} while (0) - -#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) - -#define STAILQ_FIRST(head) ((head)->stqh_first) - -#define STAILQ_FOREACH(var, head, field) \ - for((var) = STAILQ_FIRST((head)); \ - (var); \ - (var) = STAILQ_NEXT((var), field)) - -#define STAILQ_FOREACH_FROM(var, head, field) \ - for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); \ - (var); \ - (var) = STAILQ_NEXT((var), field)) - -#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = STAILQ_FIRST((head)); \ - (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define STAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \ - for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); \ - (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define STAILQ_INIT(head) do { \ - STAILQ_FIRST((head)) = NULL; \ - (head)->stqh_last = &STAILQ_FIRST((head)); \ -} while (0) - -#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ - if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ - STAILQ_NEXT((tqelm), field) = (elm); \ -} while (0) - -#define STAILQ_INSERT_HEAD(head, elm, field) do { \ - if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ - STAILQ_FIRST((head)) = (elm); \ -} while (0) - -#define STAILQ_INSERT_TAIL(head, elm, field) do { \ - STAILQ_NEXT((elm), field) = NULL; \ - *(head)->stqh_last = (elm); \ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ -} while (0) - -#define STAILQ_LAST(head, type, field) \ - (STAILQ_EMPTY((head)) ? NULL : \ - __containerof((head)->stqh_last, \ - QUEUE_TYPEOF(type), field.stqe_next)) - -#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) - -#define STAILQ_REMOVE(head, elm, type, field) do { \ - QMD_SAVELINK(oldnext, (elm)->field.stqe_next); \ - if (STAILQ_FIRST((head)) == (elm)) { \ - STAILQ_REMOVE_HEAD((head), field); \ - } \ - else { \ - QUEUE_TYPEOF(type) *curelm = STAILQ_FIRST(head); \ - while (STAILQ_NEXT(curelm, field) != (elm)) \ - curelm = STAILQ_NEXT(curelm, field); \ - STAILQ_REMOVE_AFTER(head, curelm, field); \ - } \ - TRASHIT(*oldnext); \ -} while (0) - -#define STAILQ_REMOVE_AFTER(head, elm, field) do { \ - if ((STAILQ_NEXT(elm, field) = \ - STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ -} while (0) - -#define STAILQ_REMOVE_HEAD(head, field) do { \ - if ((STAILQ_FIRST((head)) = \ - STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \ - (head)->stqh_last = &STAILQ_FIRST((head)); \ -} while (0) - -#define STAILQ_SWAP(head1, head2, type) do { \ - QUEUE_TYPEOF(type) *swap_first = STAILQ_FIRST(head1); \ - QUEUE_TYPEOF(type) **swap_last = (head1)->stqh_last; \ - STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \ - (head1)->stqh_last = (head2)->stqh_last; \ - STAILQ_FIRST(head2) = swap_first; \ - (head2)->stqh_last = swap_last; \ - if (STAILQ_EMPTY(head1)) \ - (head1)->stqh_last = &STAILQ_FIRST(head1); \ - if (STAILQ_EMPTY(head2)) \ - (head2)->stqh_last = &STAILQ_FIRST(head2); \ -} while (0) - - -/* - * List declarations. - */ -#define LIST_HEAD(name, type) \ -struct name { \ - struct type *lh_first; /* first element */ \ -} - -#define LIST_CLASS_HEAD(name, type) \ -struct name { \ - class type *lh_first; /* first element */ \ -} - -#define LIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define LIST_ENTRY(type) \ -struct { \ - struct type *le_next; /* next element */ \ - struct type **le_prev; /* address of previous next element */ \ -} - -#define LIST_CLASS_ENTRY(type) \ -struct { \ - class type *le_next; /* next element */ \ - class type **le_prev; /* address of previous next element */ \ -} - -/* - * List functions. - */ - -#if (defined(_KERNEL) && defined(INVARIANTS)) -/* - * QMD_LIST_CHECK_HEAD(LIST_HEAD *head, LIST_ENTRY NAME) - * - * If the list is non-empty, validates that the first element of the list - * points back at 'head.' - */ -#define QMD_LIST_CHECK_HEAD(head, field) do { \ - if (LIST_FIRST((head)) != NULL && \ - LIST_FIRST((head))->field.le_prev != \ - &LIST_FIRST((head))) \ - panic("Bad list head %p first->prev != head", (head)); \ -} while (0) - -/* - * QMD_LIST_CHECK_NEXT(TYPE *elm, LIST_ENTRY NAME) - * - * If an element follows 'elm' in the list, validates that the next element - * points back at 'elm.' - */ -#define QMD_LIST_CHECK_NEXT(elm, field) do { \ - if (LIST_NEXT((elm), field) != NULL && \ - LIST_NEXT((elm), field)->field.le_prev != \ - &((elm)->field.le_next)) \ - panic("Bad link elm %p next->prev != elm", (elm)); \ -} while (0) - -/* - * QMD_LIST_CHECK_PREV(TYPE *elm, LIST_ENTRY NAME) - * - * Validates that the previous element (or head of the list) points to 'elm.' - */ -#define QMD_LIST_CHECK_PREV(elm, field) do { \ - if (*(elm)->field.le_prev != (elm)) \ - panic("Bad link elm %p prev->next != elm", (elm)); \ -} while (0) -#else -#define QMD_LIST_CHECK_HEAD(head, field) -#define QMD_LIST_CHECK_NEXT(elm, field) -#define QMD_LIST_CHECK_PREV(elm, field) -#endif /* (_KERNEL && INVARIANTS) */ - -#define LIST_CONCAT(head1, head2, type, field) do { \ - QUEUE_TYPEOF(type) *curelm = LIST_FIRST(head1); \ - if (curelm == NULL) { \ - if ((LIST_FIRST(head1) = LIST_FIRST(head2)) != NULL) { \ - LIST_FIRST(head2)->field.le_prev = \ - &LIST_FIRST((head1)); \ - LIST_INIT(head2); \ - } \ - } else if (LIST_FIRST(head2) != NULL) { \ - while (LIST_NEXT(curelm, field) != NULL) \ - curelm = LIST_NEXT(curelm, field); \ - LIST_NEXT(curelm, field) = LIST_FIRST(head2); \ - LIST_FIRST(head2)->field.le_prev = &LIST_NEXT(curelm, field); \ - LIST_INIT(head2); \ - } \ -} while (0) - -#define LIST_EMPTY(head) ((head)->lh_first == NULL) - -#define LIST_FIRST(head) ((head)->lh_first) - -#define LIST_FOREACH(var, head, field) \ - for ((var) = LIST_FIRST((head)); \ - (var); \ - (var) = LIST_NEXT((var), field)) - -#define LIST_FOREACH_FROM(var, head, field) \ - for ((var) = ((var) ? (var) : LIST_FIRST((head))); \ - (var); \ - (var) = LIST_NEXT((var), field)) - -#define LIST_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = LIST_FIRST((head)); \ - (var) && ((tvar) = LIST_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define LIST_FOREACH_FROM_SAFE(var, head, field, tvar) \ - for ((var) = ((var) ? (var) : LIST_FIRST((head))); \ - (var) && ((tvar) = LIST_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define LIST_INIT(head) do { \ - LIST_FIRST((head)) = NULL; \ -} while (0) - -#define LIST_INSERT_AFTER(listelm, elm, field) do { \ - QMD_LIST_CHECK_NEXT(listelm, field); \ - if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\ - LIST_NEXT((listelm), field)->field.le_prev = \ - &LIST_NEXT((elm), field); \ - LIST_NEXT((listelm), field) = (elm); \ - (elm)->field.le_prev = &LIST_NEXT((listelm), field); \ -} while (0) - -#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ - QMD_LIST_CHECK_PREV(listelm, field); \ - (elm)->field.le_prev = (listelm)->field.le_prev; \ - LIST_NEXT((elm), field) = (listelm); \ - *(listelm)->field.le_prev = (elm); \ - (listelm)->field.le_prev = &LIST_NEXT((elm), field); \ -} while (0) - -#define LIST_INSERT_HEAD(head, elm, field) do { \ - QMD_LIST_CHECK_HEAD((head), field); \ - if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ - LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\ - LIST_FIRST((head)) = (elm); \ - (elm)->field.le_prev = &LIST_FIRST((head)); \ -} while (0) - -#define LIST_NEXT(elm, field) ((elm)->field.le_next) - -#define LIST_PREV(elm, head, type, field) \ - ((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL : \ - __containerof((elm)->field.le_prev, \ - QUEUE_TYPEOF(type), field.le_next)) - -#define LIST_REMOVE(elm, field) do { \ - QMD_SAVELINK(oldnext, (elm)->field.le_next); \ - QMD_SAVELINK(oldprev, (elm)->field.le_prev); \ - QMD_LIST_CHECK_NEXT(elm, field); \ - QMD_LIST_CHECK_PREV(elm, field); \ - if (LIST_NEXT((elm), field) != NULL) \ - LIST_NEXT((elm), field)->field.le_prev = \ - (elm)->field.le_prev; \ - *(elm)->field.le_prev = LIST_NEXT((elm), field); \ - TRASHIT(*oldnext); \ - TRASHIT(*oldprev); \ -} while (0) - -#define LIST_SWAP(head1, head2, type, field) do { \ - QUEUE_TYPEOF(type) *swap_tmp = LIST_FIRST(head1); \ - LIST_FIRST((head1)) = LIST_FIRST((head2)); \ - LIST_FIRST((head2)) = swap_tmp; \ - if ((swap_tmp = LIST_FIRST((head1))) != NULL) \ - swap_tmp->field.le_prev = &LIST_FIRST((head1)); \ - if ((swap_tmp = LIST_FIRST((head2))) != NULL) \ - swap_tmp->field.le_prev = &LIST_FIRST((head2)); \ -} while (0) - -/* - * Tail queue declarations. - */ -#define TAILQ_HEAD(name, type) \ -struct name { \ - struct type *tqh_first; /* first element */ \ - struct type **tqh_last; /* addr of last next element */ \ - TRACEBUF \ -} - -#define TAILQ_CLASS_HEAD(name, type) \ -struct name { \ - class type *tqh_first; /* first element */ \ - class type **tqh_last; /* addr of last next element */ \ - TRACEBUF \ -} - -#define TAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).tqh_first, TRACEBUF_INITIALIZER } - -#define TAILQ_ENTRY(type) \ -struct { \ - struct type *tqe_next; /* next element */ \ - struct type **tqe_prev; /* address of previous next element */ \ - TRACEBUF \ -} - -#define TAILQ_CLASS_ENTRY(type) \ -struct { \ - class type *tqe_next; /* next element */ \ - class type **tqe_prev; /* address of previous next element */ \ - TRACEBUF \ -} - -/* - * Tail queue functions. - */ -#if (defined(_KERNEL) && defined(INVARIANTS)) -/* - * QMD_TAILQ_CHECK_HEAD(TAILQ_HEAD *head, TAILQ_ENTRY NAME) - * - * If the tailq is non-empty, validates that the first element of the tailq - * points back at 'head.' - */ -#define QMD_TAILQ_CHECK_HEAD(head, field) do { \ - if (!TAILQ_EMPTY(head) && \ - TAILQ_FIRST((head))->field.tqe_prev != \ - &TAILQ_FIRST((head))) \ - panic("Bad tailq head %p first->prev != head", (head)); \ -} while (0) - -/* - * QMD_TAILQ_CHECK_TAIL(TAILQ_HEAD *head, TAILQ_ENTRY NAME) - * - * Validates that the tail of the tailq is a pointer to pointer to NULL. - */ -#define QMD_TAILQ_CHECK_TAIL(head, field) do { \ - if (*(head)->tqh_last != NULL) \ - panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head)); \ -} while (0) - -/* - * QMD_TAILQ_CHECK_NEXT(TYPE *elm, TAILQ_ENTRY NAME) - * - * If an element follows 'elm' in the tailq, validates that the next element - * points back at 'elm.' - */ -#define QMD_TAILQ_CHECK_NEXT(elm, field) do { \ - if (TAILQ_NEXT((elm), field) != NULL && \ - TAILQ_NEXT((elm), field)->field.tqe_prev != \ - &((elm)->field.tqe_next)) \ - panic("Bad link elm %p next->prev != elm", (elm)); \ -} while (0) - -/* - * QMD_TAILQ_CHECK_PREV(TYPE *elm, TAILQ_ENTRY NAME) - * - * Validates that the previous element (or head of the tailq) points to 'elm.' - */ -#define QMD_TAILQ_CHECK_PREV(elm, field) do { \ - if (*(elm)->field.tqe_prev != (elm)) \ - panic("Bad link elm %p prev->next != elm", (elm)); \ -} while (0) -#else -#define QMD_TAILQ_CHECK_HEAD(head, field) -#define QMD_TAILQ_CHECK_TAIL(head, headname) -#define QMD_TAILQ_CHECK_NEXT(elm, field) -#define QMD_TAILQ_CHECK_PREV(elm, field) -#endif /* (_KERNEL && INVARIANTS) */ - -#define TAILQ_CONCAT(head1, head2, field) do { \ - if (!TAILQ_EMPTY(head2)) { \ - *(head1)->tqh_last = (head2)->tqh_first; \ - (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \ - (head1)->tqh_last = (head2)->tqh_last; \ - TAILQ_INIT((head2)); \ - QMD_TRACE_HEAD(head1); \ - QMD_TRACE_HEAD(head2); \ - } \ -} while (0) - -#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) - -#define TAILQ_FIRST(head) ((head)->tqh_first) - -#define TAILQ_FOREACH(var, head, field) \ - for ((var) = TAILQ_FIRST((head)); \ - (var); \ - (var) = TAILQ_NEXT((var), field)) - -#define TAILQ_FOREACH_FROM(var, head, field) \ - for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \ - (var); \ - (var) = TAILQ_NEXT((var), field)) - -#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = TAILQ_FIRST((head)); \ - (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define TAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \ - for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \ - (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ - for ((var) = TAILQ_LAST((head), headname); \ - (var); \ - (var) = TAILQ_PREV((var), headname, field)) - -#define TAILQ_FOREACH_REVERSE_FROM(var, head, headname, field) \ - for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \ - (var); \ - (var) = TAILQ_PREV((var), headname, field)) - -#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ - for ((var) = TAILQ_LAST((head), headname); \ - (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \ - (var) = (tvar)) - -#define TAILQ_FOREACH_REVERSE_FROM_SAFE(var, head, headname, field, tvar) \ - for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \ - (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \ - (var) = (tvar)) - -#define TAILQ_INIT(head) do { \ - TAILQ_FIRST((head)) = NULL; \ - (head)->tqh_last = &TAILQ_FIRST((head)); \ - QMD_TRACE_HEAD(head); \ -} while (0) - -#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ - QMD_TAILQ_CHECK_NEXT(listelm, field); \ - if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\ - TAILQ_NEXT((elm), field)->field.tqe_prev = \ - &TAILQ_NEXT((elm), field); \ - else { \ - (head)->tqh_last = &TAILQ_NEXT((elm), field); \ - QMD_TRACE_HEAD(head); \ - } \ - TAILQ_NEXT((listelm), field) = (elm); \ - (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \ - QMD_TRACE_ELEM(&(elm)->field); \ - QMD_TRACE_ELEM(&(listelm)->field); \ -} while (0) - -#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ - QMD_TAILQ_CHECK_PREV(listelm, field); \ - (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ - TAILQ_NEXT((elm), field) = (listelm); \ - *(listelm)->field.tqe_prev = (elm); \ - (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \ - QMD_TRACE_ELEM(&(elm)->field); \ - QMD_TRACE_ELEM(&(listelm)->field); \ -} while (0) - -#define TAILQ_INSERT_HEAD(head, elm, field) do { \ - QMD_TAILQ_CHECK_HEAD(head, field); \ - if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ - TAILQ_FIRST((head))->field.tqe_prev = \ - &TAILQ_NEXT((elm), field); \ - else \ - (head)->tqh_last = &TAILQ_NEXT((elm), field); \ - TAILQ_FIRST((head)) = (elm); \ - (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \ - QMD_TRACE_HEAD(head); \ - QMD_TRACE_ELEM(&(elm)->field); \ -} while (0) - -#define TAILQ_INSERT_TAIL(head, elm, field) do { \ - QMD_TAILQ_CHECK_TAIL(head, field); \ - TAILQ_NEXT((elm), field) = NULL; \ - (elm)->field.tqe_prev = (head)->tqh_last; \ - *(head)->tqh_last = (elm); \ - (head)->tqh_last = &TAILQ_NEXT((elm), field); \ - QMD_TRACE_HEAD(head); \ - QMD_TRACE_ELEM(&(elm)->field); \ -} while (0) - -#define TAILQ_LAST(head, headname) \ - (*(((struct headname *)((head)->tqh_last))->tqh_last)) - -/* - * The FAST function is fast in that it causes no data access other - * then the access to the head. The standard LAST function above - * will cause a data access of both the element you want and - * the previous element. FAST is very useful for instances when - * you may want to prefetch the last data element. - */ -#define TAILQ_LAST_FAST(head, type, field) \ - (TAILQ_EMPTY(head) ? NULL : __containerof((head)->tqh_last, QUEUE_TYPEOF(type), field.tqe_next)) - -#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) - -#define TAILQ_PREV(elm, headname, field) \ - (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) - -#define TAILQ_PREV_FAST(elm, head, type, field) \ - ((elm)->field.tqe_prev == &(head)->tqh_first ? NULL : \ - __containerof((elm)->field.tqe_prev, QUEUE_TYPEOF(type), field.tqe_next)) - -#define TAILQ_REMOVE(head, elm, field) do { \ - QMD_SAVELINK(oldnext, (elm)->field.tqe_next); \ - QMD_SAVELINK(oldprev, (elm)->field.tqe_prev); \ - QMD_TAILQ_CHECK_NEXT(elm, field); \ - QMD_TAILQ_CHECK_PREV(elm, field); \ - if ((TAILQ_NEXT((elm), field)) != NULL) \ - TAILQ_NEXT((elm), field)->field.tqe_prev = \ - (elm)->field.tqe_prev; \ - else { \ - (head)->tqh_last = (elm)->field.tqe_prev; \ - QMD_TRACE_HEAD(head); \ - } \ - *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ - TRASHIT(*oldnext); \ - TRASHIT(*oldprev); \ - QMD_TRACE_ELEM(&(elm)->field); \ -} while (0) - -#define TAILQ_SWAP(head1, head2, type, field) do { \ - QUEUE_TYPEOF(type) *swap_first = (head1)->tqh_first; \ - QUEUE_TYPEOF(type) **swap_last = (head1)->tqh_last; \ - (head1)->tqh_first = (head2)->tqh_first; \ - (head1)->tqh_last = (head2)->tqh_last; \ - (head2)->tqh_first = swap_first; \ - (head2)->tqh_last = swap_last; \ - if ((swap_first = (head1)->tqh_first) != NULL) \ - swap_first->field.tqe_prev = &(head1)->tqh_first; \ - else \ - (head1)->tqh_last = &(head1)->tqh_first; \ - if ((swap_first = (head2)->tqh_first) != NULL) \ - swap_first->field.tqe_prev = &(head2)->tqh_first; \ - else \ - (head2)->tqh_last = &(head2)->tqh_first; \ -} while (0) - -#endif /* !_SYS_QUEUE_H_ */ diff --git a/thirdparty/libarchive/unzip/test/CMakeLists.txt b/thirdparty/libarchive/unzip/test/CMakeLists.txt deleted file mode 100644 index 20e730a9c..000000000 --- a/thirdparty/libarchive/unzip/test/CMakeLists.txt +++ /dev/null @@ -1,81 +0,0 @@ -############################################ -# -# How to build bsdunzip_test -# -############################################ -IF(ENABLE_UNZIP AND ENABLE_TEST) - SET(bsdunzip_test_SOURCES - ../../libarchive_fe/err.c - ../../test_utils/test_utils.c - ../../test_utils/test_main.c - test.h - test_0.c - test_basic.c - test_glob.c - test_singlefile.c - test_C.c - test_p.c - test_d.c - test_j.c - test_L.c - test_n.c - test_o.c - test_q.c - test_t.c - test_t_bad.c - test_version.c - test_x.c - test_Z1.c - test_P_encryption.c - ) - - # - # Register target - # - ADD_EXECUTABLE(bsdunzip_test ${bsdunzip_test_SOURCES}) - IF(ENABLE_ACL) - SET(TEST_ACL_LIBS "") - IF(HAVE_LIBACL) - LIST(APPEND TEST_ACL_LIBS ${ACL_LIBRARY}) - ENDIF(HAVE_LIBACL) - IF(HAVE_LIBRICHACL) - LIST(APPEND TEST_ACL_LIBS ${RICHACL_LIBRARY}) - ENDIF(HAVE_LIBRICHACL) - TARGET_LINK_LIBRARIES(bsdunzip_test ${TEST_ACL_LIBS}) - ENDIF(ENABLE_ACL) - SET_PROPERTY(TARGET bsdunzip_test PROPERTY COMPILE_DEFINITIONS LIST_H) - - # - # Generate list.h by grepping DEFINE_TEST() lines out of the C sources. - # - GENERATE_LIST_H(${CMAKE_CURRENT_BINARY_DIR}/list.h - ${CMAKE_CURRENT_LIST_FILE} ${bsdunzip_test_SOURCES}) - SET_PROPERTY(DIRECTORY APPEND PROPERTY INCLUDE_DIRECTORIES - ${CMAKE_CURRENT_BINARY_DIR}) - - # list.h has a line DEFINE_TEST(testname) for every - # test. We can use that to define the tests for cmake by - # defining a DEFINE_TEST macro and reading list.h in. - MACRO (DEFINE_TEST _testname) - ADD_TEST( - NAME bsdunzip_${_testname} - COMMAND bsdunzip_test -vv - -p $ - -r ${CMAKE_CURRENT_SOURCE_DIR} - ${_testname}) - ENDMACRO (DEFINE_TEST _testname) - - INCLUDE(${CMAKE_CURRENT_BINARY_DIR}/list.h) - INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) - INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/test_utils) - INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/unzip/test) - - # Experimental new test handling - ADD_CUSTOM_TARGET(run_bsdunzip_test - COMMAND bsdunzip_test -p $ - -r ${CMAKE_CURRENT_SOURCE_DIR} - -vv) - ADD_DEPENDENCIES(run_bsdunzip_test bsdunzip) - ADD_DEPENDENCIES(run_all_tests run_bsdunzip_test) -ENDIF(ENABLE_UNZIP AND ENABLE_TEST) - diff --git a/thirdparty/libarchive/unzip/test/list.h b/thirdparty/libarchive/unzip/test/list.h deleted file mode 100644 index e606eefc8..000000000 --- a/thirdparty/libarchive/unzip/test/list.h +++ /dev/null @@ -1,22 +0,0 @@ -DEFINE_TEST(test_0) -DEFINE_TEST(test_basic) -DEFINE_TEST(test_C) -DEFINE_TEST(test_d_before_zipfile) -DEFINE_TEST(test_d_after_zipfile) -DEFINE_TEST(test_glob) -DEFINE_TEST(test_j) -DEFINE_TEST(test_L) -DEFINE_TEST(test_n) -DEFINE_TEST(test_not_exist) -DEFINE_TEST(test_o) -DEFINE_TEST(test_p) -DEFINE_TEST(test_P) -DEFINE_TEST(test_q) -DEFINE_TEST(test_singlefile) -DEFINE_TEST(test_t_bad) -DEFINE_TEST(test_t) -DEFINE_TEST(test_version) -DEFINE_TEST(test_x_single) -DEFINE_TEST(test_x_multiple) -DEFINE_TEST(test_x_multiple_with_d) -DEFINE_TEST(test_Z1) diff --git a/thirdparty/libarchive/unzip/test/test.h b/thirdparty/libarchive/unzip/test/test.h deleted file mode 100644 index ba876afd8..000000000 --- a/thirdparty/libarchive/unzip/test/test.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2003-2017 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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$ - */ - -/* Every test program should #include "test.h" as the first thing. */ - -#define KNOWNREF "test_basic.zip.uu" -#define ENVBASE "BSDUNZIP" /* Prefix for environment variables. */ -#define PROGRAM "bsdunzip" /* Name of program being tested. */ -#define PROGRAM_ALIAS "unzip" /* Generic alias for program */ -#undef LIBRARY /* Not testing a library. */ -#undef EXTRA_DUMP /* How to dump extra data */ -#undef EXTRA_ERRNO /* How to dump errno */ -/* How to generate extra version info. */ -#define EXTRA_VERSION (systemf("%s --version", testprog) ? "" : "") - -#include "test_common.h" diff --git a/thirdparty/libarchive/unzip/test/test_0.c b/thirdparty/libarchive/unzip/test/test_0.c deleted file mode 100644 index 41279d388..000000000 --- a/thirdparty/libarchive/unzip/test/test_0.c +++ /dev/null @@ -1,58 +0,0 @@ -/*- - * Copyright (c) 2003-2007 Tim Kientzle - * 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. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -/* - * This first test does basic sanity checks on the environment. For - * most of these, we just exit on failure. - */ -#if !defined(_WIN32) || defined(__CYGWIN__) -#define DEV_NULL "/dev/null" -#else -#define DEV_NULL "NUL" -#endif - -DEFINE_TEST(test_0) -{ - struct stat st; - - failure("File %s does not exist?!", testprog); - if (!assertEqualInt(0, stat(testprogfile, &st))) { - fprintf(stderr, - "\nFile %s does not exist; aborting test.\n\n", - testprog); - exit(1); - } - - failure("%s is not executable?!", testprog); - if (!assert((st.st_mode & 0111) != 0)) { - fprintf(stderr, - "\nFile %s not executable; aborting test.\n\n", - testprog); - exit(1); - } - - /* TODO: Ensure that our reference files are available. */ -} diff --git a/thirdparty/libarchive/unzip/test/test_C.c b/thirdparty/libarchive/unzip/test/test_C.c deleted file mode 100644 index fc11b970c..000000000 --- a/thirdparty/libarchive/unzip/test/test_C.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2023 Adrian Vovk - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -/* Test C arg - match case-insensitive */ -DEFINE_TEST(test_C) -{ - const char *reffile = "test_basic.zip"; - int r; - - extract_reference_file(reffile); - r = systemf("%s -C %s test_basic/caps >test.out 2>test.err", testprog, reffile); - assertEqualInt(0, r); - assertNonEmptyFile("test.out"); - assertEmptyFile("test.err"); - - assertTextFileContents("contents CAPS\n", "test_basic/CAPS"); -} diff --git a/thirdparty/libarchive/unzip/test/test_L.c b/thirdparty/libarchive/unzip/test/test_L.c deleted file mode 100644 index 4815cb2b1..000000000 --- a/thirdparty/libarchive/unzip/test/test_L.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2023 Adrian Vovk - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -/* Test L arg - make names lowercase */ -DEFINE_TEST(test_L) -{ - const char *reffile = "test_basic.zip"; - int r; - - extract_reference_file(reffile); - r = systemf("%s -L %s >test.out 2>test.err", testprog, reffile); - assertEqualInt(0, r); - assertNonEmptyFile("test.out"); - assertEmptyFile("test.err"); - - assertTextFileContents("contents a\n", "test_basic/a"); - assertTextFileContents("contents b\n", "test_basic/b"); - assertTextFileContents("contents c\n", "test_basic/c"); - assertTextFileContents("contents CAPS\n", "test_basic/caps"); -} diff --git a/thirdparty/libarchive/unzip/test/test_P_encryption.c b/thirdparty/libarchive/unzip/test/test_P_encryption.c deleted file mode 100644 index beabbaa64..000000000 --- a/thirdparty/libarchive/unzip/test/test_P_encryption.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2023 Adrian Vovk - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -/* Test P arg - password protected */ -DEFINE_TEST(test_P) -{ - const char *reffile = "test_encrypted.zip"; - int r; - - extract_reference_file(reffile); - r = systemf("%s -P password %s >test.out 2>test.err", testprog, reffile); - assertEqualInt(0, r); - assertNonEmptyFile("test.out"); - assertEmptyFile("test.err"); - - assertTextFileContents("plaintext\n", "encrypted/file.txt"); -} diff --git a/thirdparty/libarchive/unzip/test/test_Z1.c b/thirdparty/libarchive/unzip/test/test_Z1.c deleted file mode 100644 index 58dc75003..000000000 --- a/thirdparty/libarchive/unzip/test/test_Z1.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2023 Adrian Vovk - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -/* Test -Z1 arg - List filenames */ -DEFINE_TEST(test_Z1) -{ - const char *reffile = "test_basic.zip"; - int r; - - extract_reference_file(reffile); - r = systemf("%s -Z1 %s >test.out 2>test.err", testprog, reffile); - assertEqualInt(0, r); - assertNonEmptyFile("test.out"); - assertTextFileContents("test_basic/\ntest_basic/a\ntest_basic/b\ntest_basic/c\ntest_basic/CAPS\n", "test.out"); - assertEmptyFile("test.err"); -} diff --git a/thirdparty/libarchive/unzip/test/test_basic.c b/thirdparty/libarchive/unzip/test/test_basic.c deleted file mode 100644 index e997755e7..000000000 --- a/thirdparty/libarchive/unzip/test/test_basic.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2023 Adrian Vovk - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -/* This test just does a basic zip decompression */ -DEFINE_TEST(test_basic) -{ - const char *reffile = "test_basic.zip"; - int r; - - extract_reference_file(reffile); - r = systemf("%s %s >test.out 2>test.err", testprog, reffile); - assertEqualInt(0, r); - assertNonEmptyFile("test.out"); - assertEmptyFile("test.err"); - - assertTextFileContents("contents a\n", "test_basic/a"); - assertTextFileContents("contents b\n", "test_basic/b"); - assertTextFileContents("contents c\n", "test_basic/c"); - assertTextFileContents("contents CAPS\n", "test_basic/CAPS"); -} diff --git a/thirdparty/libarchive/unzip/test/test_basic.zip.uu b/thirdparty/libarchive/unzip/test/test_basic.zip.uu deleted file mode 100644 index b55aca950..000000000 --- a/thirdparty/libarchive/unzip/test/test_basic.zip.uu +++ /dev/null @@ -1,25 +0,0 @@ -begin 644 test_basic.zip -M4$L#!!0``````,J0MU8````````````````+`"``=&5S=%]B87-I8R]55`T` -M!]PX;63U.6UDW#AM9'5X"P`!!.@#```$Z`,``%!+`P04``@`"``)C;=6```` -M```````+````#``@`'1E`L``03H`P``!.@#``!+SL\K2test.out 2>test.err", testprog, reffile); - assertEqualInt(0, r); - assertNonEmptyFile("test.out"); - assertEmptyFile("test.err"); - - assertTextFileContents("contents a\n", "foobar/test_basic/a"); - assertTextFileContents("contents b\n", "foobar/test_basic/b"); - assertTextFileContents("contents c\n", "foobar/test_basic/c"); - assertTextFileContents("contents CAPS\n", "foobar/test_basic/CAPS"); -} - -/* Test d arg - extract to target dir - after zipfile argument */ -DEFINE_TEST(test_d_after_zipfile) -{ - const char *reffile = "test_basic.zip"; - int r; - - extract_reference_file(reffile); - r = systemf("%s %s -d foobar >test.out 2>test.err", testprog, reffile); - assertEqualInt(0, r); - assertNonEmptyFile("test.out"); - assertEmptyFile("test.err"); - - assertTextFileContents("contents a\n", "foobar/test_basic/a"); - assertTextFileContents("contents b\n", "foobar/test_basic/b"); - assertTextFileContents("contents c\n", "foobar/test_basic/c"); - assertTextFileContents("contents CAPS\n", "foobar/test_basic/CAPS"); -} diff --git a/thirdparty/libarchive/unzip/test/test_encrypted.zip.uu b/thirdparty/libarchive/unzip/test/test_encrypted.zip.uu deleted file mode 100644 index 6aabeb9f5..000000000 --- a/thirdparty/libarchive/unzip/test/test_encrypted.zip.uu +++ /dev/null @@ -1,13 +0,0 @@ -begin 644 test_encrypted.zip -M4$L#!!0``````'*1MU8````````````````*`"``96YC`L``03H`P``!.@#```!F0<``@!!10,(`*_-)-RYPDYFJ$Q9+L< -M'#C?XVBR9/=H?7U\LC!A^8<6[&CO#PM02P<(`````"@````*````4$L!`A0# -M%```````7!T -M960O9FEL92YT>'155`T`!Q@Z;608.FUD&#IM9'5X"P`!!.@#```$Z`,```&9 -?!P`"`$%%`P@`4$L%!@`````"``(`PP```-L````````` -` -end diff --git a/thirdparty/libarchive/unzip/test/test_glob.c b/thirdparty/libarchive/unzip/test/test_glob.c deleted file mode 100644 index b334ce4bd..000000000 --- a/thirdparty/libarchive/unzip/test/test_glob.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2023 Adrian Vovk - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -/* Test that the glob works */ -DEFINE_TEST(test_glob) -{ - const char *reffile = "test_basic.zip"; - int r; - - extract_reference_file(reffile); - r = systemf("%s %s test_*/[ab] >test.out 2>test.err", testprog, reffile); - assertEqualInt(0, r); - assertNonEmptyFile("test.out"); - assertEmptyFile("test.err"); - - assertTextFileContents("contents a\n", "test_basic/a"); - assertTextFileContents("contents b\n", "test_basic/b"); - assertFileNotExists("test_basic/c"); - assertFileNotExists("test_basic/CAPS"); -} diff --git a/thirdparty/libarchive/unzip/test/test_j.c b/thirdparty/libarchive/unzip/test/test_j.c deleted file mode 100644 index a449e0264..000000000 --- a/thirdparty/libarchive/unzip/test/test_j.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2023 Adrian Vovk - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -/* Test j arg - don't make directories */ -DEFINE_TEST(test_j) -{ - const char *reffile = "test_basic.zip"; - int r; - - extract_reference_file(reffile); - r = systemf("%s -j %s >test.out 2>test.err", testprog, reffile); - assertEqualInt(0, r); - assertNonEmptyFile("test.out"); - assertEmptyFile("test.err"); - - assertTextFileContents("contents a\n", "a"); - assertTextFileContents("contents b\n", "b"); - assertTextFileContents("contents c\n", "c"); - assertTextFileContents("contents CAPS\n", "CAPS"); -} diff --git a/thirdparty/libarchive/unzip/test/test_n.c b/thirdparty/libarchive/unzip/test/test_n.c deleted file mode 100644 index 4e893f04b..000000000 --- a/thirdparty/libarchive/unzip/test/test_n.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2023 Adrian Vovk - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -/* Test n arg - don't overrite existing files */ -DEFINE_TEST(test_n) -{ - const char *reffile = "test_basic.zip"; - int r; - - assertMakeDir("test_basic", 0755); - assertMakeFile("test_basic/a", 0644, "orig a\n"); - assertMakeFile("test_basic/b", 0644, "orig b\n"); - - extract_reference_file(reffile); - r = systemf("%s -n %s >test.out 2>test.err", testprog, reffile); - assertEqualInt(0, r); - assertNonEmptyFile("test.out"); - assertEmptyFile("test.err"); - - assertTextFileContents("orig a\n", "test_basic/a"); - assertTextFileContents("orig b\n", "test_basic/b"); - assertTextFileContents("contents c\n", "test_basic/c"); - assertTextFileContents("contents CAPS\n", "test_basic/CAPS"); -} diff --git a/thirdparty/libarchive/unzip/test/test_not_exist.c b/thirdparty/libarchive/unzip/test/test_not_exist.c deleted file mode 100644 index aa660dc64..000000000 --- a/thirdparty/libarchive/unzip/test/test_not_exist.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2023 Adrian Vovk - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -/* Test non existant file */ -DEFINE_TEST(test_not_exist) -{ - int r; - r = systemf("%s nonexist.zip >test.out 2>test.err", testprog); - assert(r != 0); - assertEmptyFile("test.out"); - assertNonEmptyFile("test.err"); -} diff --git a/thirdparty/libarchive/unzip/test/test_o.c b/thirdparty/libarchive/unzip/test/test_o.c deleted file mode 100644 index af0c41286..000000000 --- a/thirdparty/libarchive/unzip/test/test_o.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2023 Adrian Vovk - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -/* Test o arg - overrite existing files */ -DEFINE_TEST(test_o) -{ - const char *reffile = "test_basic.zip"; - int r; - - assertMakeDir("test_basic", 0755); - assertMakeFile("test_basic/a", 0644, "orig a\n"); - assertMakeFile("test_basic/b", 0644, "orig b\n"); - - extract_reference_file(reffile); - r = systemf("%s -o %s >test.out 2>test.err", testprog, reffile); - assertEqualInt(0, r); - assertEmptyFile("test.err"); - - assertTextFileContents("contents a\n", "test_basic/a"); - assertTextFileContents("contents b\n", "test_basic/b"); - assertTextFileContents("contents c\n", "test_basic/c"); - assertTextFileContents("contents CAPS\n", "test_basic/CAPS"); -} diff --git a/thirdparty/libarchive/unzip/test/test_p.c b/thirdparty/libarchive/unzip/test/test_p.c deleted file mode 100644 index f34a5eae8..000000000 --- a/thirdparty/libarchive/unzip/test/test_p.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2023 Adrian Vovk - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -/* Test p arg - Print to stdout */ -DEFINE_TEST(test_p) -{ - const char *reffile = "test_basic.zip"; - int r; - - extract_reference_file(reffile); - r = systemf("%s -p %s >test.out 2>test.err", testprog, reffile); - assertEqualInt(0, r); - assertTextFileContents("contents a\ncontents b\ncontents c\ncontents CAPS\n", "test.out"); - assertEmptyFile("test.err"); -} diff --git a/thirdparty/libarchive/unzip/test/test_q.c b/thirdparty/libarchive/unzip/test/test_q.c deleted file mode 100644 index 9a532c888..000000000 --- a/thirdparty/libarchive/unzip/test/test_q.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2023 Adrian Vovk - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -/* Test q arg - Quiet */ -DEFINE_TEST(test_q) -{ - const char *reffile = "test_basic.zip"; - int r; - - extract_reference_file(reffile); - r = systemf("%s -q %s >test.out 2>test.err", testprog, reffile); - assertEqualInt(0, r); - assertEmptyFile("test.out"); - assertEmptyFile("test.err"); - - assertTextFileContents("contents a\n", "test_basic/a"); - assertTextFileContents("contents b\n", "test_basic/b"); - assertTextFileContents("contents c\n", "test_basic/c"); - assertTextFileContents("contents CAPS\n", "test_basic/CAPS"); -} diff --git a/thirdparty/libarchive/unzip/test/test_singlefile.c b/thirdparty/libarchive/unzip/test/test_singlefile.c deleted file mode 100644 index 70c376eb3..000000000 --- a/thirdparty/libarchive/unzip/test/test_singlefile.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2023 Adrian Vovk - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -/* Ensure single-file zips work */ -DEFINE_TEST(test_singlefile) -{ - const char *reffile = "test_singlefile.zip"; - int r; - - extract_reference_file(reffile); - r = systemf("%s %s >test.out 2>test.err", testprog, reffile); - assertEqualInt(0, r); - assertNonEmptyFile("test.out"); - assertEmptyFile("test.err"); - - assertTextFileContents("hello\n", "file.txt"); -} diff --git a/thirdparty/libarchive/unzip/test/test_singlefile.zip.uu b/thirdparty/libarchive/unzip/test/test_singlefile.zip.uu deleted file mode 100644 index 589e08f12..000000000 --- a/thirdparty/libarchive/unzip/test/test_singlefile.zip.uu +++ /dev/null @@ -1,8 +0,0 @@ -begin 644 test_singlefile.zip -M4$L#!!0`"``(`&"6MU8```````````8````(`"``9FEL92YT>'155`T`!U1# -M;6140VUD5$-M9'5X"P`!!.@#```$Z`,``,M(Stest.out 2>test.err", testprog, reffile); - assertEqualInt(0, r); - assertNonEmptyFile("test.out"); - assertEmptyFile("test.err"); -} diff --git a/thirdparty/libarchive/unzip/test/test_t_bad.c b/thirdparty/libarchive/unzip/test/test_t_bad.c deleted file mode 100644 index f9afbb40d..000000000 --- a/thirdparty/libarchive/unzip/test/test_t_bad.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2023 Adrian Vovk - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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. - */ -#include "test.h" - -/* Test t arg - Test zip contents, but fail! */ -DEFINE_TEST(test_t_bad) -{ - const char *reffile = "test_t_bad.zip"; - int r; - - extract_reference_file(reffile); - r = systemf("%s -t %s >test.out 2>test.err", testprog, reffile); - assert(r != 0); - assertNonEmptyFile("test.out"); - assertNonEmptyFile("test.err"); -} diff --git a/thirdparty/libarchive/unzip/test/test_t_bad.zip.uu b/thirdparty/libarchive/unzip/test/test_t_bad.zip.uu deleted file mode 100644 index ae6ad0792..000000000 --- a/thirdparty/libarchive/unzip/test/test_t_bad.zip.uu +++ /dev/null @@ -1,25 +0,0 @@ -begin 644 test_t_bad.zip -M4$L#!!0``````,J0MU8````````````````+`"``=&5S=%]B87-I8R]55`T` -M!]PX;63U.6UDW#AM9'5X"P`!!.@#```$Z`,``%!+`P04``@`"``)C;=6```` -M```````+````#``@`'1E`L``03H`P``!.@#``!+SL\K2test.out 2>test.err", testprog, reffile); - assertEqualInt(0, r); - assertNonEmptyFile("test.out"); - assertEmptyFile("test.err"); - - assertTextFileContents("contents a\n", "test_basic/a"); - assertTextFileContents("contents b\n", "test_basic/b"); - assertFileNotExists("test_basic/c"); - assertTextFileContents("contents CAPS\n", "test_basic/CAPS"); -} - -/* Test x arg with multiple exclude paths */ -DEFINE_TEST(test_x_multiple) -{ - const char *reffile = "test_basic.zip"; - int r; - - extract_reference_file(reffile); - r = systemf("%s %s -x test_basic/c test_basic/b >test.out 2>test.err", testprog, reffile); - assertEqualInt(0, r); - assertNonEmptyFile("test.out"); - assertEmptyFile("test.err"); - - assertTextFileContents("contents a\n", "test_basic/a"); - assertFileNotExists("test_basic/b"); - assertFileNotExists("test_basic/c"); - assertTextFileContents("contents CAPS\n", "test_basic/CAPS"); -} - -/* Test x arg with multiple exclude paths and a d arg afterwards */ -DEFINE_TEST(test_x_multiple_with_d) -{ - const char *reffile = "test_basic.zip"; - int r; - - extract_reference_file(reffile); - r = systemf("%s %s -x test_basic/c test_basic/b -d foobar >test.out 2>test.err", testprog, reffile); - assertEqualInt(0, r); - assertNonEmptyFile("test.out"); - assertEmptyFile("test.err"); - - assertTextFileContents("contents a\n", "foobar/test_basic/a"); - assertFileNotExists("foobar/test_basic/b"); - assertFileNotExists("foobar/test_basic/c"); - assertTextFileContents("contents CAPS\n", "foobar/test_basic/CAPS"); -} diff --git a/thirdparty/lsqlite3/lsqlite3.c b/thirdparty/lsqlite3/lsqlite3.c new file mode 100644 index 000000000..e3d0657d9 --- /dev/null +++ b/thirdparty/lsqlite3/lsqlite3.c @@ -0,0 +1,2459 @@ +/************************************************************************ +* lsqlite3 * +* Copyright (C) 2002-2016 Tiago Dionizio, Doug Currie * +* All rights reserved. * +* Author : Tiago Dionizio * +* Author : Doug Currie * +* Library : lsqlite3 - an SQLite 3 database binding for Lua 5 * +* * +* Permission is hereby granted, free of charge, to any person obtaining * +* a copy of this software and associated documentation files (the * +* "Software"), to deal in the Software without restriction, including * +* without limitation the rights to use, copy, modify, merge, publish, * +* distribute, sublicense, and/or sell copies of the Software, and to * +* permit persons to whom the Software is furnished to do so, subject to * +* the following conditions: * +* * +* The above copyright notice and this permission notice shall be * +* included in all copies or substantial portions of the Software. * +* * +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.* +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * +************************************************************************/ + +#include +#include +#include + +#define LUA_LIB +#include "lua.h" +#include "lauxlib.h" + +#if LUA_VERSION_NUM > 501 +/* +** Lua 5.2 +*/ +#ifndef lua_strlen +#define lua_strlen lua_rawlen +#endif +/* luaL_typerror always used with arg at ndx == NULL */ +#define luaL_typerror(L,ndx,str) luaL_error(L,"bad argument %d (%s expected, got nil)",ndx,str) +/* luaL_register used once, so below expansion is OK for this case */ +#define luaL_register(L,name,reg) lua_newtable(L);luaL_setfuncs(L,reg,0) +/* luaL_openlib always used with name == NULL */ +#define luaL_openlib(L,name,reg,nup) luaL_setfuncs(L,reg,nup) + +#if LUA_VERSION_NUM > 502 +/* +** Lua 5.3 +*/ +#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) +#endif +#endif + +#include "sqlite3.h" + +/* compile time features */ +#if !defined(SQLITE_OMIT_PROGRESS_CALLBACK) + #define SQLITE_OMIT_PROGRESS_CALLBACK 0 +#endif +#if !defined(LSQLITE_OMIT_UPDATE_HOOK) + #define LSQLITE_OMIT_UPDATE_HOOK 0 +#endif +#if defined(LSQLITE_OMIT_OPEN_V2) + #define SQLITE3_OPEN(L,filename,flags) sqlite3_open(L,filename) +#else + #define SQLITE3_OPEN(L,filename,flags) sqlite3_open_v2(L,filename,flags,NULL) +#endif + +typedef struct sdb sdb; +typedef struct sdb_vm sdb_vm; +typedef struct sdb_bu sdb_bu; +typedef struct sdb_func sdb_func; + +/* to use as C user data so i know what function sqlite is calling */ +struct sdb_func { + /* references to associated lua values */ + int fn_step; + int fn_finalize; + int udata; + + sdb *db; + char aggregate; + + sdb_func *next; +}; + +/* information about database */ +struct sdb { + /* associated lua state */ + lua_State *L; + /* sqlite database handle */ + sqlite3 *db; + + /* sql functions stack usage */ + sdb_func *func; /* top SQL function being called */ + + /* references */ + int busy_cb; /* busy callback */ + int busy_udata; + + int progress_cb; /* progress handler */ + int progress_udata; + + int trace_cb; /* trace callback */ + int trace_udata; + +#if !defined(LSQLITE_OMIT_UPDATE_HOOK) || !LSQLITE_OMIT_UPDATE_HOOK + + int update_hook_cb; /* update_hook callback */ + int update_hook_udata; + + int commit_hook_cb; /* commit_hook callback */ + int commit_hook_udata; + + int rollback_hook_cb; /* rollback_hook callback */ + int rollback_hook_udata; + +#endif +}; + +static const char *sqlite_meta = ":sqlite3"; +static const char *sqlite_vm_meta = ":sqlite3:vm"; +static const char *sqlite_bu_meta = ":sqlite3:bu"; +static const char *sqlite_ctx_meta = ":sqlite3:ctx"; +static int sqlite_ctx_meta_ref; + +/* Lua 5.3 introduced an integer type, but depending on the implementation, it could be 32 +** or 64 bits (or something else?). This helper macro tries to do "the right thing." +*/ + +#if LUA_VERSION_NUM > 502 +#define PUSH_INT64(L,i64in,fallback) \ + do { \ + sqlite_int64 i64 = i64in; \ + lua_Integer i = (lua_Integer )i64; \ + if (i == i64) lua_pushinteger(L, i);\ + else { \ + lua_Number n = (lua_Number)i64; \ + if (n == i64) lua_pushnumber(L, n); \ + else fallback; \ + } \ + } while (0) +#else +#define PUSH_INT64(L,i64in,fallback) \ + do { \ + sqlite_int64 i64 = i64in; \ + lua_Number n = (lua_Number)i64; \ + if (n == i64) lua_pushnumber(L, n); \ + else fallback; \ + } while (0) +#endif + +/* +** ======================================================= +** Database Virtual Machine Operations +** ======================================================= +*/ + +static void vm_push_column(lua_State *L, sqlite3_stmt *vm, int idx) { + switch (sqlite3_column_type(vm, idx)) { + case SQLITE_INTEGER: + PUSH_INT64(L, sqlite3_column_int64(vm, idx) + , lua_pushlstring(L, (const char*)sqlite3_column_text(vm, idx) + , sqlite3_column_bytes(vm, idx))); + break; + case SQLITE_FLOAT: + lua_pushnumber(L, sqlite3_column_double(vm, idx)); + break; + case SQLITE_TEXT: + lua_pushlstring(L, (const char*)sqlite3_column_text(vm, idx), sqlite3_column_bytes(vm, idx)); + break; + case SQLITE_BLOB: + lua_pushlstring(L, sqlite3_column_blob(vm, idx), sqlite3_column_bytes(vm, idx)); + break; + case SQLITE_NULL: + lua_pushnil(L); + break; + default: + lua_pushnil(L); + break; + } +} + +/* virtual machine information */ +struct sdb_vm { + sdb *db; /* associated database handle */ + sqlite3_stmt *vm; /* virtual machine */ + + /* sqlite3_step info */ + int columns; /* number of columns in result */ + char has_values; /* true when step succeeds */ + + char temp; /* temporary vm used in db:rows */ +}; + +/* called with db,sql text on the lua stack */ +static sdb_vm *newvm(lua_State *L, sdb *db) { + sdb_vm *svm = (sdb_vm*)lua_newuserdata(L, sizeof(sdb_vm)); /* db sql svm_ud -- */ + + luaL_getmetatable(L, sqlite_vm_meta); + lua_setmetatable(L, -2); /* set metatable */ + + svm->db = db; + svm->columns = 0; + svm->has_values = 0; + svm->vm = NULL; + svm->temp = 0; + + /* add an entry on the database table: svm -> db to keep db live while svm is live */ + lua_pushlightuserdata(L, db); /* db sql svm_ud db_lud -- */ + lua_rawget(L, LUA_REGISTRYINDEX); /* db sql svm_ud reg[db_lud] -- */ + lua_pushlightuserdata(L, svm); /* db sql svm_ud reg[db_lud] svm_lud -- */ + lua_pushvalue(L, -5); /* db sql svm_ud reg[db_lud] svm_lud db -- */ + lua_rawset(L, -3); /* (reg[db_lud])[svm_lud] = db ; set the db for this vm */ + lua_pop(L, 1); /* db sql svm_ud -- */ + + return svm; +} + +static int cleanupvm(lua_State *L, sdb_vm *svm) { + + /* remove entry in database table - no harm if not present in the table */ + lua_pushlightuserdata(L, svm->db); + lua_rawget(L, LUA_REGISTRYINDEX); + lua_pushlightuserdata(L, svm); + lua_pushnil(L); + lua_rawset(L, -3); + lua_pop(L, 1); + + svm->columns = 0; + svm->has_values = 0; + + if (!svm->vm) return 0; + + lua_pushinteger(L, sqlite3_finalize(svm->vm)); + svm->vm = NULL; + return 1; +} + +static int stepvm(lua_State *L, sdb_vm *svm) { + (void)L; + return sqlite3_step(svm->vm); +} + +static sdb_vm *lsqlite_getvm(lua_State *L, int index) { + sdb_vm *svm = (sdb_vm*)luaL_checkudata(L, index, sqlite_vm_meta); + if (svm == NULL) luaL_argerror(L, index, "bad sqlite virtual machine"); + return svm; +} + +static sdb_vm *lsqlite_checkvm(lua_State *L, int index) { + sdb_vm *svm = lsqlite_getvm(L, index); + if (svm->vm == NULL) luaL_argerror(L, index, "attempt to use closed sqlite virtual machine"); + return svm; +} + +static int dbvm_isopen(lua_State *L) { + sdb_vm *svm = lsqlite_getvm(L, 1); + lua_pushboolean(L, svm->vm != NULL ? 1 : 0); + return 1; +} + +static int dbvm_tostring(lua_State *L) { + char buff[39]; + sdb_vm *svm = lsqlite_getvm(L, 1); + if (svm->vm == NULL) + strcpy(buff, "closed"); + else + sprintf(buff, "%p", svm); + lua_pushfstring(L, "sqlite virtual machine (%s)", buff); + return 1; +} + +static int dbvm_gc(lua_State *L) { + sdb_vm *svm = lsqlite_getvm(L, 1); + if (svm->vm != NULL) /* ignore closed vms */ + cleanupvm(L, svm); + return 0; +} + +static int dbvm_step(lua_State *L) { + int result; + sdb_vm *svm = lsqlite_checkvm(L, 1); + + result = stepvm(L, svm); + svm->has_values = result == SQLITE_ROW ? 1 : 0; + svm->columns = sqlite3_data_count(svm->vm); + + lua_pushinteger(L, result); + return 1; +} + +static int dbvm_finalize(lua_State *L) { + sdb_vm *svm = lsqlite_checkvm(L, 1); + return cleanupvm(L, svm); +} + +static int dbvm_reset(lua_State *L) { + sdb_vm *svm = lsqlite_checkvm(L, 1); + sqlite3_reset(svm->vm); + lua_pushinteger(L, sqlite3_errcode(svm->db->db)); + return 1; +} + +static void dbvm_check_contents(lua_State *L, sdb_vm *svm) { + if (!svm->has_values) { + luaL_error(L, "misuse of function"); + } +} + +static void dbvm_check_index(lua_State *L, sdb_vm *svm, int index) { + if (index < 0 || index >= svm->columns) { + luaL_error(L, "index out of range [0..%d]", svm->columns - 1); + } +} + +static void dbvm_check_bind_index(lua_State *L, sdb_vm *svm, int index) { + if (index < 1 || index > sqlite3_bind_parameter_count(svm->vm)) { + luaL_error(L, "bind index out of range [1..%d]", sqlite3_bind_parameter_count(svm->vm)); + } +} + +static int dbvm_last_insert_rowid(lua_State *L) { + sdb_vm *svm = lsqlite_checkvm(L, 1); + /* conversion warning: int64 -> luaNumber */ + sqlite_int64 rowid = sqlite3_last_insert_rowid(svm->db->db); + PUSH_INT64(L, rowid, lua_pushfstring(L, "%ll", rowid)); + return 1; +} + +/* +** ======================================================= +** Virtual Machine - generic info +** ======================================================= +*/ +static int dbvm_columns(lua_State *L) { + sdb_vm *svm = lsqlite_checkvm(L, 1); + lua_pushinteger(L, sqlite3_column_count(svm->vm)); + return 1; +} + +/* +** ======================================================= +** Virtual Machine - getters +** ======================================================= +*/ + +static int dbvm_get_value(lua_State *L) { + sdb_vm *svm = lsqlite_checkvm(L, 1); + int index = luaL_checkint(L, 2); + dbvm_check_contents(L, svm); + dbvm_check_index(L, svm, index); + vm_push_column(L, svm->vm, index); + return 1; +} + +static int dbvm_get_name(lua_State *L) { + sdb_vm *svm = lsqlite_checkvm(L, 1); + int index = luaL_checknumber(L, 2); + dbvm_check_index(L, svm, index); + lua_pushstring(L, sqlite3_column_name(svm->vm, index)); + return 1; +} + +static int dbvm_get_type(lua_State *L) { + sdb_vm *svm = lsqlite_checkvm(L, 1); + int index = luaL_checknumber(L, 2); + dbvm_check_index(L, svm, index); + lua_pushstring(L, sqlite3_column_decltype(svm->vm, index)); + return 1; +} + +static int dbvm_get_values(lua_State *L) { + sdb_vm *svm = lsqlite_checkvm(L, 1); + sqlite3_stmt *vm = svm->vm; + int columns = svm->columns; + int n; + dbvm_check_contents(L, svm); + + lua_createtable(L, columns, 0); + for (n = 0; n < columns;) { + vm_push_column(L, vm, n++); + lua_rawseti(L, -2, n); + } + return 1; +} + +static int dbvm_get_names(lua_State *L) { + sdb_vm *svm = lsqlite_checkvm(L, 1); + sqlite3_stmt *vm = svm->vm; + int columns = sqlite3_column_count(vm); /* valid as soon as statement prepared */ + int n; + + lua_createtable(L, columns, 0); + for (n = 0; n < columns;) { + lua_pushstring(L, sqlite3_column_name(vm, n++)); + lua_rawseti(L, -2, n); + } + return 1; +} + +static int dbvm_get_types(lua_State *L) { + sdb_vm *svm = lsqlite_checkvm(L, 1); + sqlite3_stmt *vm = svm->vm; + int columns = sqlite3_column_count(vm); /* valid as soon as statement prepared */ + int n; + + lua_createtable(L, columns, 0); + for (n = 0; n < columns;) { + lua_pushstring(L, sqlite3_column_decltype(vm, n++)); + lua_rawseti(L, -2, n); + } + return 1; +} + +static int dbvm_get_uvalues(lua_State *L) { + sdb_vm *svm = lsqlite_checkvm(L, 1); + sqlite3_stmt *vm = svm->vm; + int columns = svm->columns; + int n; + dbvm_check_contents(L, svm); + + lua_checkstack(L, columns); + for (n = 0; n < columns; ++n) + vm_push_column(L, vm, n); + return columns; +} + +static int dbvm_get_unames(lua_State *L) { + sdb_vm *svm = lsqlite_checkvm(L, 1); + sqlite3_stmt *vm = svm->vm; + int columns = sqlite3_column_count(vm); /* valid as soon as statement prepared */ + int n; + + lua_checkstack(L, columns); + for (n = 0; n < columns; ++n) + lua_pushstring(L, sqlite3_column_name(vm, n)); + return columns; +} + +static int dbvm_get_utypes(lua_State *L) { + sdb_vm *svm = lsqlite_checkvm(L, 1); + sqlite3_stmt *vm = svm->vm; + int columns = sqlite3_column_count(vm); /* valid as soon as statement prepared */ + int n; + + lua_checkstack(L, columns); + for (n = 0; n < columns; ++n) + lua_pushstring(L, sqlite3_column_decltype(vm, n)); + return columns; +} + +static int dbvm_get_named_values(lua_State *L) { + sdb_vm *svm = lsqlite_checkvm(L, 1); + sqlite3_stmt *vm = svm->vm; + int columns = svm->columns; + int n; + dbvm_check_contents(L, svm); + + lua_createtable(L, 0, columns); + for (n = 0; n < columns; ++n) { + lua_pushstring(L, sqlite3_column_name(vm, n)); + vm_push_column(L, vm, n); + lua_rawset(L, -3); + } + return 1; +} + +static int dbvm_get_named_types(lua_State *L) { + sdb_vm *svm = lsqlite_checkvm(L, 1); + sqlite3_stmt *vm = svm->vm; + int columns = sqlite3_column_count(vm); + int n; + + lua_createtable(L, 0, columns); + for (n = 0; n < columns; ++n) { + lua_pushstring(L, sqlite3_column_name(vm, n)); + lua_pushstring(L, sqlite3_column_decltype(vm, n)); + lua_rawset(L, -3); + } + return 1; +} + +/* +** ======================================================= +** Virtual Machine - Bind +** ======================================================= +*/ + +static int dbvm_bind_index(lua_State *L, sqlite3_stmt *vm, int index, int lindex) { + switch (lua_type(L, lindex)) { + case LUA_TSTRING: + return sqlite3_bind_text(vm, index, lua_tostring(L, lindex), lua_strlen(L, lindex), SQLITE_TRANSIENT); + case LUA_TNUMBER: +#if LUA_VERSION_NUM > 502 + if (lua_isinteger(L, lindex)) + return sqlite3_bind_int64(vm, index, lua_tointeger(L, lindex)); +#endif + return sqlite3_bind_double(vm, index, lua_tonumber(L, lindex)); + case LUA_TBOOLEAN: + return sqlite3_bind_int(vm, index, lua_toboolean(L, lindex) ? 1 : 0); + case LUA_TNONE: + case LUA_TNIL: + return sqlite3_bind_null(vm, index); + default: + luaL_error(L, "index (%d) - invalid data type for bind (%s)", index, lua_typename(L, lua_type(L, lindex))); + return SQLITE_MISUSE; /*!*/ + } +} + + +static int dbvm_bind_parameter_count(lua_State *L) { + sdb_vm *svm = lsqlite_checkvm(L, 1); + lua_pushinteger(L, sqlite3_bind_parameter_count(svm->vm)); + return 1; +} + +static int dbvm_bind_parameter_name(lua_State *L) { + sdb_vm *svm = lsqlite_checkvm(L, 1); + int index = luaL_checknumber(L, 2); + dbvm_check_bind_index(L, svm, index); + lua_pushstring(L, sqlite3_bind_parameter_name(svm->vm, index)); + return 1; +} + +static int dbvm_bind(lua_State *L) { + sdb_vm *svm = lsqlite_checkvm(L, 1); + sqlite3_stmt *vm = svm->vm; + int index = luaL_checkint(L, 2); + int result; + + dbvm_check_bind_index(L, svm, index); + result = dbvm_bind_index(L, vm, index, 3); + + lua_pushinteger(L, result); + return 1; +} + +static int dbvm_bind_blob(lua_State *L) { + sdb_vm *svm = lsqlite_checkvm(L, 1); + int index = luaL_checkint(L, 2); + const char *value = luaL_checkstring(L, 3); + int len = lua_strlen(L, 3); + + lua_pushinteger(L, sqlite3_bind_blob(svm->vm, index, value, len, SQLITE_TRANSIENT)); + return 1; +} + +static int dbvm_bind_values(lua_State *L) { + sdb_vm *svm = lsqlite_checkvm(L, 1); + sqlite3_stmt *vm = svm->vm; + int top = lua_gettop(L); + int result, n; + + if (top - 1 != sqlite3_bind_parameter_count(vm)) + luaL_error(L, + "incorrect number of parameters to bind (%d given, %d to bind)", + top - 1, + sqlite3_bind_parameter_count(vm) + ); + + for (n = 2; n <= top; ++n) { + if ((result = dbvm_bind_index(L, vm, n - 1, n)) != SQLITE_OK) { + lua_pushinteger(L, result); + return 1; + } + } + + lua_pushinteger(L, SQLITE_OK); + return 1; +} + +static int dbvm_bind_table_fields (lua_State *L, int idx, int n, sqlite3_stmt *vm) { + const char *name; + int result, i; + + for ( i = 1; i <= n; ++i ) { + name = sqlite3_bind_parameter_name(vm, i ); + if (name && (name[0] == ':' || name[0] == '$')) { + lua_pushstring(L, ++name); + lua_gettable(L, idx); + result = dbvm_bind_index(L, vm, i, -1); + lua_pop(L, 1); + } + else { + lua_pushinteger(L, i ); + lua_gettable(L, idx); + result = dbvm_bind_index(L, vm, i, -1); + lua_pop(L, 1); + } + + if (result != SQLITE_OK) { + return result; + } + } + return SQLITE_OK; +} + +static int dbvm_bind_names(lua_State *L) { + sdb_vm *svm = lsqlite_checkvm(L, 1); + sqlite3_stmt *vm = svm->vm; + int count = sqlite3_bind_parameter_count(vm); + int result; + luaL_checktype(L, 2, LUA_TTABLE); + + result = dbvm_bind_table_fields (L, 2, count, vm); + lua_pushinteger(L, result); + return 1; +} + +/* +** ======================================================= +** Database (internal management) +** ======================================================= +*/ + +/* +** When creating database handles, always creates a `closed' database handle +** before opening the actual database; so, if there is a memory error, the +** database is not left opened. +** +** Creates a new 'table' and leaves it in the stack +*/ +static sdb *newdb (lua_State *L) { + sdb *db = (sdb*)lua_newuserdata(L, sizeof(sdb)); + db->L = L; + db->db = NULL; /* database handle is currently `closed' */ + db->func = NULL; + + db->busy_cb = + db->busy_udata = + db->progress_cb = + db->progress_udata = + db->trace_cb = + db->trace_udata = +#if !defined(LSQLITE_OMIT_UPDATE_HOOK) || !LSQLITE_OMIT_UPDATE_HOOK + db->update_hook_cb = + db->update_hook_udata = + db->commit_hook_cb = + db->commit_hook_udata = + db->rollback_hook_cb = + db->rollback_hook_udata = +#endif + LUA_NOREF; + + luaL_getmetatable(L, sqlite_meta); + lua_setmetatable(L, -2); /* set metatable */ + + /* to keep track of 'open' virtual machines */ + lua_pushlightuserdata(L, db); + lua_newtable(L); + lua_rawset(L, LUA_REGISTRYINDEX); + + return db; +} + +static int cleanupdb(lua_State *L, sdb *db) { + sdb_func *func; + sdb_func *func_next; + int top; + int result; + + /* free associated virtual machines */ + lua_pushlightuserdata(L, db); + lua_rawget(L, LUA_REGISTRYINDEX); + + /* close all used handles */ + top = lua_gettop(L); + lua_pushnil(L); + while (lua_next(L, -2)) { + sdb_vm *svm = lua_touserdata(L, -2); /* key: vm; val: sql text */ + cleanupvm(L, svm); + + lua_settop(L, top); + lua_pushnil(L); + } + + lua_pop(L, 1); /* pop vm table */ + + /* remove entry in lua registry table */ + lua_pushlightuserdata(L, db); + lua_pushnil(L); + lua_rawset(L, LUA_REGISTRYINDEX); + + /* 'free' all references */ + luaL_unref(L, LUA_REGISTRYINDEX, db->busy_cb); + luaL_unref(L, LUA_REGISTRYINDEX, db->busy_udata); + luaL_unref(L, LUA_REGISTRYINDEX, db->progress_cb); + luaL_unref(L, LUA_REGISTRYINDEX, db->progress_udata); + luaL_unref(L, LUA_REGISTRYINDEX, db->trace_cb); + luaL_unref(L, LUA_REGISTRYINDEX, db->trace_udata); +#if !defined(LSQLITE_OMIT_UPDATE_HOOK) || !LSQLITE_OMIT_UPDATE_HOOK + luaL_unref(L, LUA_REGISTRYINDEX, db->update_hook_cb); + luaL_unref(L, LUA_REGISTRYINDEX, db->update_hook_udata); + luaL_unref(L, LUA_REGISTRYINDEX, db->commit_hook_cb); + luaL_unref(L, LUA_REGISTRYINDEX, db->commit_hook_udata); + luaL_unref(L, LUA_REGISTRYINDEX, db->rollback_hook_cb); + luaL_unref(L, LUA_REGISTRYINDEX, db->rollback_hook_udata); +#endif + + /* close database */ + result = sqlite3_close(db->db); + db->db = NULL; + + /* free associated memory with created functions */ + func = db->func; + while (func) { + func_next = func->next; + luaL_unref(L, LUA_REGISTRYINDEX, func->fn_step); + luaL_unref(L, LUA_REGISTRYINDEX, func->fn_finalize); + luaL_unref(L, LUA_REGISTRYINDEX, func->udata); + free(func); + func = func_next; + } + db->func = NULL; + return result; +} + +static sdb *lsqlite_getdb(lua_State *L, int index) { + sdb *db = (sdb*)luaL_checkudata(L, index, sqlite_meta); + if (db == NULL) luaL_typerror(L, index, "sqlite database"); + return db; +} + +static sdb *lsqlite_checkdb(lua_State *L, int index) { + sdb *db = lsqlite_getdb(L, index); + if (db->db == NULL) luaL_argerror(L, index, "attempt to use closed sqlite database"); + return db; +} + + +/* +** ======================================================= +** User Defined Functions - Context Methods +** ======================================================= +*/ +typedef struct { + sqlite3_context *ctx; + int ud; +} lcontext; + +static lcontext *lsqlite_make_context(lua_State *L) { + lcontext *ctx = (lcontext*)lua_newuserdata(L, sizeof(lcontext)); + lua_rawgeti(L, LUA_REGISTRYINDEX, sqlite_ctx_meta_ref); + lua_setmetatable(L, -2); + ctx->ctx = NULL; + ctx->ud = LUA_NOREF; + return ctx; +} + +static lcontext *lsqlite_getcontext(lua_State *L, int index) { + lcontext *ctx = (lcontext*)luaL_checkudata(L, index, sqlite_ctx_meta); + if (ctx == NULL) luaL_typerror(L, index, "sqlite context"); + return ctx; +} + +static lcontext *lsqlite_checkcontext(lua_State *L, int index) { + lcontext *ctx = lsqlite_getcontext(L, index); + if (ctx->ctx == NULL) luaL_argerror(L, index, "invalid sqlite context"); + return ctx; +} + +static int lcontext_tostring(lua_State *L) { + char buff[39]; + lcontext *ctx = lsqlite_getcontext(L, 1); + if (ctx->ctx == NULL) + strcpy(buff, "closed"); + else + sprintf(buff, "%p", ctx->ctx); + lua_pushfstring(L, "sqlite function context (%s)", buff); + return 1; +} + +static void lcontext_check_aggregate(lua_State *L, lcontext *ctx) { + sdb_func *func = (sdb_func*)sqlite3_user_data(ctx->ctx); + if (!func->aggregate) { + luaL_error(L, "attempt to call aggregate method from scalar function"); + } +} + +static int lcontext_user_data(lua_State *L) { + lcontext *ctx = lsqlite_checkcontext(L, 1); + sdb_func *func = (sdb_func*)sqlite3_user_data(ctx->ctx); + lua_rawgeti(L, LUA_REGISTRYINDEX, func->udata); + return 1; +} + +static int lcontext_get_aggregate_context(lua_State *L) { + lcontext *ctx = lsqlite_checkcontext(L, 1); + lcontext_check_aggregate(L, ctx); + lua_rawgeti(L, LUA_REGISTRYINDEX, ctx->ud); + return 1; +} + +static int lcontext_set_aggregate_context(lua_State *L) { + lcontext *ctx = lsqlite_checkcontext(L, 1); + lcontext_check_aggregate(L, ctx); + lua_settop(L, 2); + luaL_unref(L, LUA_REGISTRYINDEX, ctx->ud); + ctx->ud = luaL_ref(L, LUA_REGISTRYINDEX); + return 0; +} + +static int lcontext_aggregate_count(lua_State *L) { + lcontext *ctx = lsqlite_checkcontext(L, 1); + lcontext_check_aggregate(L, ctx); + lua_pushinteger(L, sqlite3_aggregate_count(ctx->ctx)); + return 1; +} + +#if 0 +void *sqlite3_get_auxdata(sqlite3_context*, int); +void sqlite3_set_auxdata(sqlite3_context*, int, void*, void (*)(void*)); +#endif + +static int lcontext_result(lua_State *L) { + lcontext *ctx = lsqlite_checkcontext(L, 1); + switch (lua_type(L, 2)) { + case LUA_TNUMBER: +#if LUA_VERSION_NUM > 502 + if (lua_isinteger(L, 2)) + sqlite3_result_int64(ctx->ctx, luaL_checkinteger(L, 2)); + else +#endif + sqlite3_result_double(ctx->ctx, luaL_checknumber(L, 2)); + break; + case LUA_TSTRING: + sqlite3_result_text(ctx->ctx, luaL_checkstring(L, 2), lua_strlen(L, 2), SQLITE_TRANSIENT); + break; + case LUA_TNIL: + case LUA_TNONE: + sqlite3_result_null(ctx->ctx); + break; + default: + luaL_error(L, "invalid result type %s", lua_typename(L, 2)); + break; + } + + return 0; +} + +static int lcontext_result_blob(lua_State *L) { + lcontext *ctx = lsqlite_checkcontext(L, 1); + const char *blob = luaL_checkstring(L, 2); + int size = lua_strlen(L, 2); + sqlite3_result_blob(ctx->ctx, (const void*)blob, size, SQLITE_TRANSIENT); + return 0; +} + +static int lcontext_result_double(lua_State *L) { + lcontext *ctx = lsqlite_checkcontext(L, 1); + double d = luaL_checknumber(L, 2); + sqlite3_result_double(ctx->ctx, d); + return 0; +} + +static int lcontext_result_error(lua_State *L) { + lcontext *ctx = lsqlite_checkcontext(L, 1); + const char *err = luaL_checkstring(L, 2); + int size = lua_strlen(L, 2); + sqlite3_result_error(ctx->ctx, err, size); + return 0; +} + +static int lcontext_result_int(lua_State *L) { + lcontext *ctx = lsqlite_checkcontext(L, 1); + int i = luaL_checkint(L, 2); + sqlite3_result_int(ctx->ctx, i); + return 0; +} + +static int lcontext_result_null(lua_State *L) { + lcontext *ctx = lsqlite_checkcontext(L, 1); + sqlite3_result_null(ctx->ctx); + return 0; +} + +static int lcontext_result_text(lua_State *L) { + lcontext *ctx = lsqlite_checkcontext(L, 1); + const char *text = luaL_checkstring(L, 2); + int size = lua_strlen(L, 2); + sqlite3_result_text(ctx->ctx, text, size, SQLITE_TRANSIENT); + return 0; +} + +/* +** ======================================================= +** Database Methods +** ======================================================= +*/ + +static int db_isopen(lua_State *L) { + sdb *db = lsqlite_getdb(L, 1); + lua_pushboolean(L, db->db != NULL ? 1 : 0); + return 1; +} + +static int db_last_insert_rowid(lua_State *L) { + sdb *db = lsqlite_checkdb(L, 1); + /* conversion warning: int64 -> luaNumber */ + sqlite_int64 rowid = sqlite3_last_insert_rowid(db->db); + PUSH_INT64(L, rowid, lua_pushfstring(L, "%ll", rowid)); + return 1; +} + +static int db_changes(lua_State *L) { + sdb *db = lsqlite_checkdb(L, 1); + lua_pushinteger(L, sqlite3_changes(db->db)); + return 1; +} + +static int db_total_changes(lua_State *L) { + sdb *db = lsqlite_checkdb(L, 1); + lua_pushinteger(L, sqlite3_total_changes(db->db)); + return 1; +} + +static int db_errcode(lua_State *L) { + sdb *db = lsqlite_checkdb(L, 1); + lua_pushinteger(L, sqlite3_errcode(db->db)); + return 1; +} + +static int db_errmsg(lua_State *L) { + sdb *db = lsqlite_checkdb(L, 1); + lua_pushstring(L, sqlite3_errmsg(db->db)); + return 1; +} + +static int db_interrupt(lua_State *L) { + sdb *db = lsqlite_checkdb(L, 1); + sqlite3_interrupt(db->db); + return 0; +} + +static int db_db_filename(lua_State *L) { + sdb *db = lsqlite_checkdb(L, 1); + const char *db_name = luaL_checkstring(L, 2); + /* sqlite3_db_filename may return NULL, in that case Lua pushes nil... */ + lua_pushstring(L, sqlite3_db_filename(db->db, db_name)); + return 1; +} + +/* +** Registering SQL functions: +*/ + +static void db_push_value(lua_State *L, sqlite3_value *value) { + switch (sqlite3_value_type(value)) { + case SQLITE_TEXT: + lua_pushlstring(L, (const char*)sqlite3_value_text(value), sqlite3_value_bytes(value)); + break; + + case SQLITE_INTEGER: + PUSH_INT64(L, sqlite3_value_int64(value) + , lua_pushlstring(L, (const char*)sqlite3_value_text(value) + , sqlite3_value_bytes(value))); + break; + + case SQLITE_FLOAT: + lua_pushnumber(L, sqlite3_value_double(value)); + break; + + case SQLITE_BLOB: + lua_pushlstring(L, sqlite3_value_blob(value), sqlite3_value_bytes(value)); + break; + + case SQLITE_NULL: + lua_pushnil(L); + break; + + default: + /* things done properly (SQLite + Lua SQLite) + ** this should never happen */ + lua_pushnil(L); + break; + } +} + +/* +** callback functions used when calling registered sql functions +*/ + +/* scalar function to be called +** callback params: context, values... */ +static void db_sql_normal_function(sqlite3_context *context, int argc, sqlite3_value **argv) { + sdb_func *func = (sdb_func*)sqlite3_user_data(context); + lua_State *L = func->db->L; + int n; + lcontext *ctx; + + int top = lua_gettop(L); + + /* ensure there is enough space in the stack */ + lua_checkstack(L, argc + 3); + + lua_rawgeti(L, LUA_REGISTRYINDEX, func->fn_step); /* function to call */ + + if (!func->aggregate) { + ctx = lsqlite_make_context(L); /* push context - used to set results */ + } + else { + /* reuse context userdata value */ + void *p = sqlite3_aggregate_context(context, 1); + /* i think it is OK to use assume that using a light user data + ** as an entry on LUA REGISTRY table will be unique */ + lua_pushlightuserdata(L, p); + lua_rawget(L, LUA_REGISTRYINDEX); /* context table */ + + if (lua_isnil(L, -1)) { /* not yet created? */ + lua_pop(L, 1); + ctx = lsqlite_make_context(L); + lua_pushlightuserdata(L, p); + lua_pushvalue(L, -2); + lua_rawset(L, LUA_REGISTRYINDEX); + } + else + ctx = lsqlite_getcontext(L, -1); + } + + /* push params */ + for (n = 0; n < argc; ++n) { + db_push_value(L, argv[n]); + } + + /* set context */ + ctx->ctx = context; + + if (lua_pcall(L, argc + 1, 0, 0)) { + const char *errmsg = lua_tostring(L, -1); + int size = lua_strlen(L, -1); + sqlite3_result_error(context, errmsg, size); + } + + /* invalidate context */ + ctx->ctx = NULL; + + if (!func->aggregate) { + luaL_unref(L, LUA_REGISTRYINDEX, ctx->ud); + } + + lua_settop(L, top); +} + +static void db_sql_finalize_function(sqlite3_context *context) { + sdb_func *func = (sdb_func*)sqlite3_user_data(context); + lua_State *L = func->db->L; + void *p = sqlite3_aggregate_context(context, 1); /* minimal mem usage */ + lcontext *ctx; + int top = lua_gettop(L); + + lua_rawgeti(L, LUA_REGISTRYINDEX, func->fn_finalize); /* function to call */ + + /* i think it is OK to use assume that using a light user data + ** as an entry on LUA REGISTRY table will be unique */ + lua_pushlightuserdata(L, p); + lua_rawget(L, LUA_REGISTRYINDEX); /* context table */ + + if (lua_isnil(L, -1)) { /* not yet created? - shouldn't happen in finalize function */ + lua_pop(L, 1); + ctx = lsqlite_make_context(L); + lua_pushlightuserdata(L, p); + lua_pushvalue(L, -2); + lua_rawset(L, LUA_REGISTRYINDEX); + } + else + ctx = lsqlite_getcontext(L, -1); + + /* set context */ + ctx->ctx = context; + + if (lua_pcall(L, 1, 0, 0)) { + sqlite3_result_error(context, lua_tostring(L, -1), -1); + } + + /* invalidate context */ + ctx->ctx = NULL; + + /* cleanup context */ + luaL_unref(L, LUA_REGISTRYINDEX, ctx->ud); + /* remove it from registry */ + lua_pushlightuserdata(L, p); + lua_pushnil(L); + lua_rawset(L, LUA_REGISTRYINDEX); + + lua_settop(L, top); +} + +/* +** Register a normal function +** Params: db, function name, number arguments, [ callback | step, finalize], user data +** Returns: true on sucess +** +** Normal function: +** Params: context, params +** +** Aggregate function: +** Params of step: context, params +** Params of finalize: context +*/ +static int db_register_function(lua_State *L, int aggregate) { + sdb *db = lsqlite_checkdb(L, 1); + const char *name; + int args; + int result; + sdb_func *func; + + /* safety measure */ + if (aggregate) aggregate = 1; + + name = luaL_checkstring(L, 2); + args = luaL_checkint(L, 3); + luaL_checktype(L, 4, LUA_TFUNCTION); + if (aggregate) luaL_checktype(L, 5, LUA_TFUNCTION); + + /* maybe an alternative way to allocate memory should be used/avoided */ + func = (sdb_func*)malloc(sizeof(sdb_func)); + if (func == NULL) { + luaL_error(L, "out of memory"); + } + + result = sqlite3_create_function( + db->db, name, args, SQLITE_UTF8, func, + aggregate ? NULL : db_sql_normal_function, + aggregate ? db_sql_normal_function : NULL, + aggregate ? db_sql_finalize_function : NULL + ); + + if (result == SQLITE_OK) { + /* safety measures for userdata field to be present in the stack */ + lua_settop(L, 5 + aggregate); + + /* save registered function in db function list */ + func->db = db; + func->aggregate = aggregate; + func->next = db->func; + db->func = func; + + /* save the setp/normal function callback */ + lua_pushvalue(L, 4); + func->fn_step = luaL_ref(L, LUA_REGISTRYINDEX); + /* save user data */ + lua_pushvalue(L, 5+aggregate); + func->udata = luaL_ref(L, LUA_REGISTRYINDEX); + + if (aggregate) { + lua_pushvalue(L, 5); + func->fn_finalize = luaL_ref(L, LUA_REGISTRYINDEX); + } + else + func->fn_finalize = LUA_NOREF; + } + else { + /* free allocated memory */ + free(func); + } + + lua_pushboolean(L, result == SQLITE_OK ? 1 : 0); + return 1; +} + +static int db_create_function(lua_State *L) { + return db_register_function(L, 0); +} + +static int db_create_aggregate(lua_State *L) { + return db_register_function(L, 1); +} + +/* create_collation; contributed by Thomas Lauer +*/ + +typedef struct { + lua_State *L; + int ref; +} scc; + +static int collwrapper(scc *co,int l1,const void *p1, + int l2,const void *p2) { + int res=0; + lua_State *L=co->L; + lua_rawgeti(L,LUA_REGISTRYINDEX,co->ref); + lua_pushlstring(L,p1,l1); + lua_pushlstring(L,p2,l2); + if (lua_pcall(L,2,1,0)==0) res=(int)lua_tonumber(L,-1); + lua_pop(L,1); + return res; +} + +static void collfree(scc *co) { + if (co) { + luaL_unref(co->L,LUA_REGISTRYINDEX,co->ref); + free(co); + } +} + +static int db_create_collation(lua_State *L) { + sdb *db=lsqlite_checkdb(L,1); + const char *collname=luaL_checkstring(L,2); + scc *co=NULL; + int (*collfunc)(scc *,int,const void *,int,const void *)=NULL; + lua_settop(L,3); /* default args to nil, and exclude extras */ + if (lua_isfunction(L,3)) collfunc=collwrapper; + else if (!lua_isnil(L,3)) + luaL_error(L,"create_collation: function or nil expected"); + if (collfunc != NULL) { + co=(scc *)malloc(sizeof(scc)); /* userdata is a no-no as it + will be garbage-collected */ + if (co) { + co->L=L; + /* lua_settop(L,3) above means we don't need: lua_pushvalue(L,3); */ + co->ref=luaL_ref(L,LUA_REGISTRYINDEX); + } + else luaL_error(L,"create_collation: could not allocate callback"); + } + sqlite3_create_collation_v2(db->db, collname, SQLITE_UTF8, + (void *)co, + (int(*)(void*,int,const void*,int,const void*))collfunc, + (void(*)(void*))collfree); + return 0; +} + +/* Thanks to Wolfgang Oertl... +*/ +static int db_load_extension(lua_State *L) { + sdb *db=lsqlite_checkdb(L,1); + const char *extname=luaL_optstring(L,2,NULL); + const char *entrypoint=luaL_optstring(L,3,NULL); + int result; + char *errmsg = NULL; + + if (extname == NULL) { + result = sqlite3_enable_load_extension(db->db,0); /* disable extension loading */ + } + else { + sqlite3_enable_load_extension(db->db,1); /* enable extension loading */ + result = sqlite3_load_extension(db->db,extname,entrypoint,&errmsg); + } + + if (result == SQLITE_OK) { + lua_pushboolean(L,1); + return 1; + } + + lua_pushboolean(L,0); /* so, assert(load_extension(...)) works */ + lua_pushstring(L,errmsg); + sqlite3_free(errmsg); + return 2; +} + +/* +** trace callback: +** Params: database, callback function, userdata +** +** callback function: +** Params: userdata, sql +*/ +static void db_trace_callback(void *user, const char *sql) { + sdb *db = (sdb*)user; + lua_State *L = db->L; + int top = lua_gettop(L); + + /* setup lua callback call */ + lua_rawgeti(L, LUA_REGISTRYINDEX, db->trace_cb); /* get callback */ + lua_rawgeti(L, LUA_REGISTRYINDEX, db->trace_udata); /* get callback user data */ + lua_pushstring(L, sql); /* traced sql statement */ + + /* call lua function */ + lua_pcall(L, 2, 0, 0); + /* ignore any error generated by this function */ + + lua_settop(L, top); +} + +static int db_trace(lua_State *L) { + sdb *db = lsqlite_checkdb(L, 1); + + if (lua_gettop(L) < 2 || lua_isnil(L, 2)) { + luaL_unref(L, LUA_REGISTRYINDEX, db->trace_cb); + luaL_unref(L, LUA_REGISTRYINDEX, db->trace_udata); + + db->trace_cb = + db->trace_udata = LUA_NOREF; + + /* clear trace handler */ + sqlite3_trace(db->db, NULL, NULL); + } + else { + luaL_checktype(L, 2, LUA_TFUNCTION); + + /* make sure we have an userdata field (even if nil) */ + lua_settop(L, 3); + + luaL_unref(L, LUA_REGISTRYINDEX, db->trace_cb); + luaL_unref(L, LUA_REGISTRYINDEX, db->trace_udata); + + db->trace_udata = luaL_ref(L, LUA_REGISTRYINDEX); + db->trace_cb = luaL_ref(L, LUA_REGISTRYINDEX); + + /* set trace handler */ + sqlite3_trace(db->db, db_trace_callback, db); + } + + return 0; +} + +#if !defined(LSQLITE_OMIT_UPDATE_HOOK) || !LSQLITE_OMIT_UPDATE_HOOK + +/* +** update_hook callback: +** Params: database, callback function, userdata +** +** callback function: +** Params: userdata, {one of SQLITE_INSERT, SQLITE_DELETE, or SQLITE_UPDATE}, +** database name, table name (containing the affected row), rowid of the row +*/ +static void db_update_hook_callback(void *user, int op, char const *dbname, char const *tblname, sqlite3_int64 rowid) { + sdb *db = (sdb*)user; + lua_State *L = db->L; + int top = lua_gettop(L); + + /* setup lua callback call */ + lua_rawgeti(L, LUA_REGISTRYINDEX, db->update_hook_cb); /* get callback */ + lua_rawgeti(L, LUA_REGISTRYINDEX, db->update_hook_udata); /* get callback user data */ + lua_pushinteger(L, op); + lua_pushstring(L, dbname); /* update_hook database name */ + lua_pushstring(L, tblname); /* update_hook database name */ + + PUSH_INT64(L, rowid, lua_pushfstring(L, "%ll", rowid)); + + /* call lua function */ + lua_pcall(L, 5, 0, 0); + /* ignore any error generated by this function */ + + lua_settop(L, top); +} + +static int db_update_hook(lua_State *L) { + sdb *db = lsqlite_checkdb(L, 1); + + if (lua_gettop(L) < 2 || lua_isnil(L, 2)) { + luaL_unref(L, LUA_REGISTRYINDEX, db->update_hook_cb); + luaL_unref(L, LUA_REGISTRYINDEX, db->update_hook_udata); + + db->update_hook_cb = + db->update_hook_udata = LUA_NOREF; + + /* clear update_hook handler */ + sqlite3_update_hook(db->db, NULL, NULL); + } + else { + luaL_checktype(L, 2, LUA_TFUNCTION); + + /* make sure we have an userdata field (even if nil) */ + lua_settop(L, 3); + + luaL_unref(L, LUA_REGISTRYINDEX, db->update_hook_cb); + luaL_unref(L, LUA_REGISTRYINDEX, db->update_hook_udata); + + db->update_hook_udata = luaL_ref(L, LUA_REGISTRYINDEX); + db->update_hook_cb = luaL_ref(L, LUA_REGISTRYINDEX); + + /* set update_hook handler */ + sqlite3_update_hook(db->db, db_update_hook_callback, db); + } + + return 0; +} + +/* +** commit_hook callback: +** Params: database, callback function, userdata +** +** callback function: +** Params: userdata +** Returned value: Return false or nil to continue the COMMIT operation normally. +** return true (non false, non nil), then the COMMIT is converted into a ROLLBACK. +*/ +static int db_commit_hook_callback(void *user) { + sdb *db = (sdb*)user; + lua_State *L = db->L; + int top = lua_gettop(L); + int rollback = 0; + + /* setup lua callback call */ + lua_rawgeti(L, LUA_REGISTRYINDEX, db->commit_hook_cb); /* get callback */ + lua_rawgeti(L, LUA_REGISTRYINDEX, db->commit_hook_udata); /* get callback user data */ + + /* call lua function */ + if (!lua_pcall(L, 1, 1, 0)) + rollback = lua_toboolean(L, -1); /* use result if there was no error */ + + lua_settop(L, top); + return rollback; +} + +static int db_commit_hook(lua_State *L) { + sdb *db = lsqlite_checkdb(L, 1); + + if (lua_gettop(L) < 2 || lua_isnil(L, 2)) { + luaL_unref(L, LUA_REGISTRYINDEX, db->commit_hook_cb); + luaL_unref(L, LUA_REGISTRYINDEX, db->commit_hook_udata); + + db->commit_hook_cb = + db->commit_hook_udata = LUA_NOREF; + + /* clear commit_hook handler */ + sqlite3_commit_hook(db->db, NULL, NULL); + } + else { + luaL_checktype(L, 2, LUA_TFUNCTION); + + /* make sure we have an userdata field (even if nil) */ + lua_settop(L, 3); + + luaL_unref(L, LUA_REGISTRYINDEX, db->commit_hook_cb); + luaL_unref(L, LUA_REGISTRYINDEX, db->commit_hook_udata); + + db->commit_hook_udata = luaL_ref(L, LUA_REGISTRYINDEX); + db->commit_hook_cb = luaL_ref(L, LUA_REGISTRYINDEX); + + /* set commit_hook handler */ + sqlite3_commit_hook(db->db, db_commit_hook_callback, db); + } + + return 0; +} + +/* +** rollback hook callback: +** Params: database, callback function, userdata +** +** callback function: +** Params: userdata +*/ +static void db_rollback_hook_callback(void *user) { + sdb *db = (sdb*)user; + lua_State *L = db->L; + int top = lua_gettop(L); + + /* setup lua callback call */ + lua_rawgeti(L, LUA_REGISTRYINDEX, db->rollback_hook_cb); /* get callback */ + lua_rawgeti(L, LUA_REGISTRYINDEX, db->rollback_hook_udata); /* get callback user data */ + + /* call lua function */ + lua_pcall(L, 1, 0, 0); + /* ignore any error generated by this function */ + + lua_settop(L, top); +} + +static int db_rollback_hook(lua_State *L) { + sdb *db = lsqlite_checkdb(L, 1); + + if (lua_gettop(L) < 2 || lua_isnil(L, 2)) { + luaL_unref(L, LUA_REGISTRYINDEX, db->rollback_hook_cb); + luaL_unref(L, LUA_REGISTRYINDEX, db->rollback_hook_udata); + + db->rollback_hook_cb = + db->rollback_hook_udata = LUA_NOREF; + + /* clear rollback_hook handler */ + sqlite3_rollback_hook(db->db, NULL, NULL); + } + else { + luaL_checktype(L, 2, LUA_TFUNCTION); + + /* make sure we have an userdata field (even if nil) */ + lua_settop(L, 3); + + luaL_unref(L, LUA_REGISTRYINDEX, db->rollback_hook_cb); + luaL_unref(L, LUA_REGISTRYINDEX, db->rollback_hook_udata); + + db->rollback_hook_udata = luaL_ref(L, LUA_REGISTRYINDEX); + db->rollback_hook_cb = luaL_ref(L, LUA_REGISTRYINDEX); + + /* set rollback_hook handler */ + sqlite3_rollback_hook(db->db, db_rollback_hook_callback, db); + } + + return 0; +} + +#endif /* #if !defined(LSQLITE_OMIT_UPDATE_HOOK) || !LSQLITE_OMIT_UPDATE_HOOK */ + +#if !defined(SQLITE_OMIT_PROGRESS_CALLBACK) || !SQLITE_OMIT_PROGRESS_CALLBACK + +/* +** progress handler: +** Params: database, number of opcodes, callback function, userdata +** +** callback function: +** Params: userdata +** returns: 0 to return immediatly and return SQLITE_ABORT, non-zero to continue +*/ +static int db_progress_callback(void *user) { + int result = 1; /* abort by default */ + sdb *db = (sdb*)user; + lua_State *L = db->L; + int top = lua_gettop(L); + + lua_rawgeti(L, LUA_REGISTRYINDEX, db->progress_cb); + lua_rawgeti(L, LUA_REGISTRYINDEX, db->progress_udata); + + /* call lua function */ + if (!lua_pcall(L, 1, 1, 0)) + result = lua_toboolean(L, -1); + + lua_settop(L, top); + return result; +} + +static int db_progress_handler(lua_State *L) { + sdb *db = lsqlite_checkdb(L, 1); + + if (lua_gettop(L) < 2 || lua_isnil(L, 2)) { + luaL_unref(L, LUA_REGISTRYINDEX, db->progress_cb); + luaL_unref(L, LUA_REGISTRYINDEX, db->progress_udata); + + db->progress_cb = + db->progress_udata = LUA_NOREF; + + /* clear busy handler */ + sqlite3_progress_handler(db->db, 0, NULL, NULL); + } + else { + int nop = luaL_checkint(L, 2); /* number of opcodes */ + luaL_checktype(L, 3, LUA_TFUNCTION); + + /* make sure we have an userdata field (even if nil) */ + lua_settop(L, 4); + + luaL_unref(L, LUA_REGISTRYINDEX, db->progress_cb); + luaL_unref(L, LUA_REGISTRYINDEX, db->progress_udata); + + db->progress_udata = luaL_ref(L, LUA_REGISTRYINDEX); + db->progress_cb = luaL_ref(L, LUA_REGISTRYINDEX); + + /* set progress callback */ + sqlite3_progress_handler(db->db, nop, db_progress_callback, db); + } + + return 0; +} + +#else /* #if !defined(SQLITE_OMIT_PROGRESS_CALLBACK) || !SQLITE_OMIT_PROGRESS_CALLBACK */ + +static int db_progress_handler(lua_State *L) { + lua_pushliteral(L, "progress callback support disabled at compile time"); + lua_error(L); + return 0; +} + +#endif /* #if !defined(SQLITE_OMIT_PROGRESS_CALLBACK) || !SQLITE_OMIT_PROGRESS_CALLBACK */ + +/* Online Backup API */ +#if 0 +sqlite3_backup *sqlite3_backup_init( + sqlite3 *pDest, /* Destination database handle */ + const char *zDestName, /* Destination database name */ + sqlite3 *pSource, /* Source database handle */ + const char *zSourceName /* Source database name */ +); +int sqlite3_backup_step(sqlite3_backup *p, int nPage); +int sqlite3_backup_finish(sqlite3_backup *p); +int sqlite3_backup_remaining(sqlite3_backup *p); +int sqlite3_backup_pagecount(sqlite3_backup *p); +#endif + +struct sdb_bu { + sqlite3_backup *bu; /* backup structure */ +}; + +static int cleanupbu(lua_State *L, sdb_bu *sbu) { + + if (!sbu->bu) return 0; /* already finished */ + + /* remove table from registry */ + lua_pushlightuserdata(L, sbu->bu); + lua_pushnil(L); + lua_rawset(L, LUA_REGISTRYINDEX); + + lua_pushinteger(L, sqlite3_backup_finish(sbu->bu)); + sbu->bu = NULL; + + return 1; +} + +static int lsqlite_backup_init(lua_State *L) { + + sdb *target_db = lsqlite_checkdb(L, 1); + const char *target_nm = luaL_checkstring(L, 2); + sdb *source_db = lsqlite_checkdb(L, 3); + const char *source_nm = luaL_checkstring(L, 4); + + sqlite3_backup *bu = sqlite3_backup_init(target_db->db, target_nm, source_db->db, source_nm); + + if (NULL != bu) { + sdb_bu *sbu = (sdb_bu*)lua_newuserdata(L, sizeof(sdb_bu)); + + luaL_getmetatable(L, sqlite_bu_meta); + lua_setmetatable(L, -2); /* set metatable */ + sbu->bu = bu; + + /* create table from registry */ + /* to prevent referenced databases from being garbage collected while bu is live */ + lua_pushlightuserdata(L, bu); + lua_createtable(L, 2, 0); + /* add source and target dbs to table at indices 1 and 2 */ + lua_pushvalue(L, 1); /* target db */ + lua_rawseti(L, -2, 1); + lua_pushvalue(L, 3); /* source db */ + lua_rawseti(L, -2, 2); + /* put table in registry with key lightuserdata bu */ + lua_rawset(L, LUA_REGISTRYINDEX); + + return 1; + } + else { + return 0; + } +} + +static sdb_bu *lsqlite_getbu(lua_State *L, int index) { + sdb_bu *sbu = (sdb_bu*)luaL_checkudata(L, index, sqlite_bu_meta); + if (sbu == NULL) luaL_typerror(L, index, "sqlite database backup"); + return sbu; +} + +static sdb_bu *lsqlite_checkbu(lua_State *L, int index) { + sdb_bu *sbu = lsqlite_getbu(L, index); + if (sbu->bu == NULL) luaL_argerror(L, index, "attempt to use closed sqlite database backup"); + return sbu; +} + +static int dbbu_gc(lua_State *L) { + sdb_bu *sbu = lsqlite_getbu(L, 1); + if (sbu->bu != NULL) { + cleanupbu(L, sbu); + lua_pop(L, 1); + } + /* else ignore if already finished */ + return 0; +} + +static int dbbu_step(lua_State *L) { + sdb_bu *sbu = lsqlite_checkbu(L, 1); + int nPage = luaL_checkint(L, 2); + lua_pushinteger(L, sqlite3_backup_step(sbu->bu, nPage)); + return 1; +} + +static int dbbu_remaining(lua_State *L) { + sdb_bu *sbu = lsqlite_checkbu(L, 1); + lua_pushinteger(L, sqlite3_backup_remaining(sbu->bu)); + return 1; +} + +static int dbbu_pagecount(lua_State *L) { + sdb_bu *sbu = lsqlite_checkbu(L, 1); + lua_pushinteger(L, sqlite3_backup_pagecount(sbu->bu)); + return 1; +} + +static int dbbu_finish(lua_State *L) { + sdb_bu *sbu = lsqlite_checkbu(L, 1); + return cleanupbu(L, sbu); +} + +/* end of Online Backup API */ + +/* +** busy handler: +** Params: database, callback function, userdata +** +** callback function: +** Params: userdata, number of tries +** returns: 0 to return immediatly and return SQLITE_BUSY, non-zero to try again +*/ +static int db_busy_callback(void *user, int tries) { + int retry = 0; /* abort by default */ + sdb *db = (sdb*)user; + lua_State *L = db->L; + int top = lua_gettop(L); + + lua_rawgeti(L, LUA_REGISTRYINDEX, db->busy_cb); + lua_rawgeti(L, LUA_REGISTRYINDEX, db->busy_udata); + lua_pushinteger(L, tries); + + /* call lua function */ + if (!lua_pcall(L, 2, 1, 0)) + retry = lua_toboolean(L, -1); + + lua_settop(L, top); + return retry; +} + +static int db_busy_handler(lua_State *L) { + sdb *db = lsqlite_checkdb(L, 1); + + if (lua_gettop(L) < 2 || lua_isnil(L, 2)) { + luaL_unref(L, LUA_REGISTRYINDEX, db->busy_cb); + luaL_unref(L, LUA_REGISTRYINDEX, db->busy_udata); + + db->busy_cb = + db->busy_udata = LUA_NOREF; + + /* clear busy handler */ + sqlite3_busy_handler(db->db, NULL, NULL); + } + else { + luaL_checktype(L, 2, LUA_TFUNCTION); + /* make sure we have an userdata field (even if nil) */ + lua_settop(L, 3); + + luaL_unref(L, LUA_REGISTRYINDEX, db->busy_cb); + luaL_unref(L, LUA_REGISTRYINDEX, db->busy_udata); + + db->busy_udata = luaL_ref(L, LUA_REGISTRYINDEX); + db->busy_cb = luaL_ref(L, LUA_REGISTRYINDEX); + + /* set busy handler */ + sqlite3_busy_handler(db->db, db_busy_callback, db); + } + + return 0; +} + +static int db_busy_timeout(lua_State *L) { + sdb *db = lsqlite_checkdb(L, 1); + int timeout = luaL_checkint(L, 2); + sqlite3_busy_timeout(db->db, timeout); + + /* if there was a timeout callback registered, it is now + ** invalid/useless. free any references we may have */ + luaL_unref(L, LUA_REGISTRYINDEX, db->busy_cb); + luaL_unref(L, LUA_REGISTRYINDEX, db->busy_udata); + db->busy_cb = + db->busy_udata = LUA_NOREF; + + return 0; +} + +/* +** Params: db, sql, callback, user +** returns: code [, errmsg] +** +** Callback: +** Params: user, number of columns, values, names +** Returns: 0 to continue, other value will cause abort +*/ +static int db_exec_callback(void* user, int columns, char **data, char **names) { + int result = SQLITE_ABORT; /* abort by default */ + lua_State *L = (lua_State*)user; + int n; + + int top = lua_gettop(L); + + lua_pushvalue(L, 3); /* function to call */ + lua_pushvalue(L, 4); /* user data */ + lua_pushinteger(L, columns); /* total number of rows in result */ + + /* column values */ + lua_pushvalue(L, 6); + for (n = 0; n < columns;) { + lua_pushstring(L, data[n++]); + lua_rawseti(L, -2, n); + } + + /* columns names */ + lua_pushvalue(L, 5); + if (lua_isnil(L, -1)) { + lua_pop(L, 1); + lua_createtable(L, columns, 0); + lua_pushvalue(L, -1); + lua_replace(L, 5); + for (n = 0; n < columns;) { + lua_pushstring(L, names[n++]); + lua_rawseti(L, -2, n); + } + } + + /* call lua function */ + if (!lua_pcall(L, 4, 1, 0)) { + +#if LUA_VERSION_NUM > 502 + if (lua_isinteger(L, -1)) + result = lua_tointeger(L, -1); + else +#endif + if (lua_isnumber(L, -1)) + result = lua_tonumber(L, -1); + } + + lua_settop(L, top); + return result; +} + +static int db_exec(lua_State *L) { + sdb *db = lsqlite_checkdb(L, 1); + const char *sql = luaL_checkstring(L, 2); + int result; + + if (!lua_isnoneornil(L, 3)) { + /* stack: + ** 3: callback function + ** 4: userdata + ** 5: column names + ** 6: reusable column values + */ + luaL_checktype(L, 3, LUA_TFUNCTION); + lua_settop(L, 4); /* 'trap' userdata - nil extra parameters */ + lua_pushnil(L); /* column names not known at this point */ + lua_newtable(L); /* column values table */ + + result = sqlite3_exec(db->db, sql, db_exec_callback, L, NULL); + } + else { + /* no callbacks */ + result = sqlite3_exec(db->db, sql, NULL, NULL, NULL); + } + + lua_pushinteger(L, result); + return 1; +} + +/* +** Params: db, sql +** returns: code, compiled length or error message +*/ +static int db_prepare(lua_State *L) { + sdb *db = lsqlite_checkdb(L, 1); + const char *sql = luaL_checkstring(L, 2); + int sql_len = lua_strlen(L, 2); + const char *sqltail; + sdb_vm *svm; + lua_settop(L,2); /* db,sql is on top of stack for call to newvm */ + svm = newvm(L, db); + + if (sqlite3_prepare_v2(db->db, sql, sql_len, &svm->vm, &sqltail) != SQLITE_OK) { + lua_pushnil(L); + lua_pushinteger(L, sqlite3_errcode(db->db)); + if (cleanupvm(L, svm) == 1) + lua_pop(L, 1); /* this should not happen since sqlite3_prepare_v2 will not set ->vm on error */ + return 2; + } + + /* vm already in the stack */ + lua_pushstring(L, sqltail); + return 2; +} + +static int db_do_next_row(lua_State *L, int packed) { + int result; + sdb_vm *svm = lsqlite_checkvm(L, 1); + sqlite3_stmt *vm; + int columns; + int i; + + result = stepvm(L, svm); + vm = svm->vm; /* stepvm may change svm->vm if re-prepare is needed */ + svm->has_values = result == SQLITE_ROW ? 1 : 0; + svm->columns = columns = sqlite3_data_count(vm); + + if (result == SQLITE_ROW) { + if (packed) { + if (packed == 1) { + lua_createtable(L, columns, 0); + for (i = 0; i < columns;) { + vm_push_column(L, vm, i); + lua_rawseti(L, -2, ++i); + } + } + else { + lua_createtable(L, 0, columns); + for (i = 0; i < columns; ++i) { + lua_pushstring(L, sqlite3_column_name(vm, i)); + vm_push_column(L, vm, i); + lua_rawset(L, -3); + } + } + return 1; + } + else { + lua_checkstack(L, columns); + for (i = 0; i < columns; ++i) + vm_push_column(L, vm, i); + return svm->columns; + } + } + + if (svm->temp) { + /* finalize and check for errors */ + result = sqlite3_finalize(vm); + svm->vm = NULL; + cleanupvm(L, svm); + } + else if (result == SQLITE_DONE) { + result = sqlite3_reset(vm); + } + + if (result != SQLITE_OK) { + lua_pushstring(L, sqlite3_errmsg(svm->db->db)); + lua_error(L); + } + return 0; +} + +static int db_next_row(lua_State *L) { + return db_do_next_row(L, 0); +} + +static int db_next_packed_row(lua_State *L) { + return db_do_next_row(L, 1); +} + +static int db_next_named_row(lua_State *L) { + return db_do_next_row(L, 2); +} + +static int dbvm_do_rows(lua_State *L, int(*f)(lua_State *)) { + /* sdb_vm *svm = */ + lsqlite_checkvm(L, 1); + lua_pushvalue(L,1); + lua_pushcfunction(L, f); + lua_insert(L, -2); + return 2; +} + +static int dbvm_rows(lua_State *L) { + return dbvm_do_rows(L, db_next_packed_row); +} + +static int dbvm_nrows(lua_State *L) { + return dbvm_do_rows(L, db_next_named_row); +} + +static int dbvm_urows(lua_State *L) { + return dbvm_do_rows(L, db_next_row); +} + +static int db_do_rows(lua_State *L, int(*f)(lua_State *)) { + sdb *db = lsqlite_checkdb(L, 1); + const char *sql = luaL_checkstring(L, 2); + sdb_vm *svm; + + int nargs = lua_gettop(L) - 2; + if (nargs > 0) { + lua_pushvalue(L, 1); + lua_pushvalue(L, 2); /* copy db,sql on top of the stack for newvm */ + } + + svm = newvm(L, db); + svm->temp = 1; + + if (sqlite3_prepare_v2(db->db, sql, -1, &svm->vm, NULL) != SQLITE_OK) { + lua_pushstring(L, sqlite3_errmsg(svm->db->db)); + if (cleanupvm(L, svm) == 1) + lua_pop(L, 1); /* this should not happen since sqlite3_prepare_v2 will not set ->vm on error */ + lua_error(L); + } + + if (nargs > 0) { + lua_replace(L, 1); + lua_remove(L, 2); /* stack: vm, args.. */ + + if (nargs == 1 && lua_istable(L, 2)) { + int result; + if ((result = dbvm_bind_table_fields (L, 2, nargs, svm->vm)) != SQLITE_OK) { + lua_pushstring(L, sqlite3_errstr(result)); + cleanupvm(L, svm); + lua_error(L); + } + } else if (nargs == sqlite3_bind_parameter_count(svm->vm)) { + int result, i; + for (i = 1; i <= nargs; i++) { + if ((result = dbvm_bind_index(L, svm->vm, i, i + 1)) != SQLITE_OK) { + lua_pushstring(L, sqlite3_errstr(result)); + cleanupvm(L, svm); + lua_error(L); + } + } + } else { + luaL_error(L, "Required either %d parameters or a single table, got %d.", + sqlite3_bind_parameter_count(svm->vm), nargs); + } + lua_pop(L, nargs); + lua_pushvalue(L, 1); + } + + lua_pushcfunction(L, f); + lua_insert(L, -2); + return 2; +} + +static int db_rows(lua_State *L) { + return db_do_rows(L, db_next_packed_row); +} + +static int db_nrows(lua_State *L) { + return db_do_rows(L, db_next_named_row); +} + +/* unpacked version of db:rows */ +static int db_urows(lua_State *L) { + return db_do_rows(L, db_next_row); +} + +static int db_tostring(lua_State *L) { + char buff[32]; + sdb *db = lsqlite_getdb(L, 1); + if (db->db == NULL) + strcpy(buff, "closed"); + else + sprintf(buff, "%p", lua_touserdata(L, 1)); + lua_pushfstring(L, "sqlite database (%s)", buff); + return 1; +} + +static int db_close(lua_State *L) { + sdb *db = lsqlite_checkdb(L, 1); + lua_pushinteger(L, cleanupdb(L, db)); + return 1; +} + +static int db_close_vm(lua_State *L) { + sdb *db = lsqlite_checkdb(L, 1); + /* cleanup temporary only tables? */ + int temp = lua_toboolean(L, 2); + + /* free associated virtual machines */ + lua_pushlightuserdata(L, db); + lua_rawget(L, LUA_REGISTRYINDEX); + + /* close all used handles */ + lua_pushnil(L); + while (lua_next(L, -2)) { + sdb_vm *svm = lua_touserdata(L, -2); /* key: vm; val: sql text */ + + if ((!temp || svm->temp) && svm->vm) + { + sqlite3_finalize(svm->vm); + svm->vm = NULL; + } + + /* leave key in the stack */ + lua_pop(L, 1); + } + return 0; +} + +/* From: Wolfgang Oertl +When using lsqlite3 in a multithreaded environment, each thread has a separate Lua +environment, but full userdata structures can't be passed from one thread to another. +This is possible with lightuserdata, however. See: lsqlite_open_ptr(). +*/ +static int db_get_ptr(lua_State *L) { + sdb *db = lsqlite_checkdb(L, 1); + lua_pushlightuserdata(L, db->db); + return 1; +} + +static int db_gc(lua_State *L) { + sdb *db = lsqlite_getdb(L, 1); + if (db->db != NULL) /* ignore closed databases */ + cleanupdb(L, db); + return 0; +} + +/* +** ======================================================= +** General library functions +** ======================================================= +*/ + +static int lsqlite_version(lua_State *L) { + lua_pushstring(L, sqlite3_libversion()); + return 1; +} + +static int lsqlite_complete(lua_State *L) { + const char *sql = luaL_checkstring(L, 1); + lua_pushboolean(L, sqlite3_complete(sql)); + return 1; +} + +#ifndef _WIN32 +static int lsqlite_temp_directory(lua_State *L) { + const char *oldtemp = sqlite3_temp_directory; + + if (!lua_isnone(L, 1)) { + const char *temp = luaL_optstring(L, 1, NULL); + if (sqlite3_temp_directory) { + sqlite3_free((char*)sqlite3_temp_directory); + } + if (temp) { + sqlite3_temp_directory = sqlite3_mprintf("%s", temp); + } + else { + sqlite3_temp_directory = NULL; + } + } + lua_pushstring(L, oldtemp); + return 1; +} +#endif + +#if defined(SQLITE_ENABLE_CEROD) +static int lsqlite_activate_cerod(lua_State *L) { + const char *s = luaL_checkstring(L, 1); + sqlite3_activate_cerod(s); + lua_pushnil(L); + return 0; +} +#endif + +static int lsqlite_do_open(lua_State *L, const char *filename, int flags) { + sdb *db = newdb(L); /* create and leave in stack */ + + if (SQLITE3_OPEN(filename, &db->db, flags) == SQLITE_OK) { + /* database handle already in the stack - return it */ + return 1; + } + + /* failed to open database */ + lua_pushnil(L); /* push nil */ + lua_pushinteger(L, sqlite3_errcode(db->db)); + lua_pushstring(L, sqlite3_errmsg(db->db)); /* push error message */ + + /* clean things up */ + cleanupdb(L, db); + + /* return */ + return 3; +} + +static int lsqlite_open(lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + int flags = luaL_optinteger(L, 2, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE); + return lsqlite_do_open(L, filename, flags); +} + +static int lsqlite_open_memory(lua_State *L) { + return lsqlite_do_open(L, ":memory:", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE); +} + +/* From: Wolfgang Oertl +When using lsqlite3 in a multithreaded environment, each thread has a separate Lua +environment, but full userdata structures can't be passed from one thread to another. +This is possible with lightuserdata, however. See: db_get_ptr(). +*/ +static int lsqlite_open_ptr(lua_State *L) { + sqlite3 *db_ptr; + sdb *db; + int rc; + + luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); + db_ptr = lua_touserdata(L, 1); + /* This is the only API function that runs sqlite3SafetyCheck regardless of + * SQLITE_ENABLE_API_ARMOR and does almost nothing (without an SQL + * statement) */ + rc = sqlite3_exec(db_ptr, NULL, NULL, NULL, NULL); + if (rc != SQLITE_OK) + luaL_argerror(L, 1, "not a valid SQLite3 pointer"); + + db = newdb(L); /* create and leave in stack */ + db->db = db_ptr; + return 1; +} + +static int lsqlite_newindex(lua_State *L) { + lua_pushliteral(L, "attempt to change readonly table"); + lua_error(L); + return 0; +} + +#ifndef LSQLITE_VERSION +/* should be defined in rockspec, but just in case... */ +#define LSQLITE_VERSION "unknown" +#endif + +/* Version number of this library +*/ +static int lsqlite_lversion(lua_State *L) { + lua_pushstring(L, LSQLITE_VERSION); + return 1; +} + +/* +** ======================================================= +** Register functions +** ======================================================= +*/ + +#define SC(s) { #s, SQLITE_ ## s }, +#define LSC(s) { #s, LSQLITE_ ## s }, + +static const struct { + const char* name; + int value; +} sqlite_constants[] = { + /* error codes */ + SC(OK) SC(ERROR) SC(INTERNAL) SC(PERM) + SC(ABORT) SC(BUSY) SC(LOCKED) SC(NOMEM) + SC(READONLY) SC(INTERRUPT) SC(IOERR) SC(CORRUPT) + SC(NOTFOUND) SC(FULL) SC(CANTOPEN) SC(PROTOCOL) + SC(EMPTY) SC(SCHEMA) SC(TOOBIG) SC(CONSTRAINT) + SC(MISMATCH) SC(MISUSE) SC(NOLFS) + SC(FORMAT) SC(NOTADB) + + /* sqlite_step specific return values */ + SC(RANGE) SC(ROW) SC(DONE) + + /* column types */ + SC(INTEGER) SC(FLOAT) SC(TEXT) SC(BLOB) + SC(NULL) + + /* Authorizer Action Codes */ + SC(CREATE_INDEX ) + SC(CREATE_TABLE ) + SC(CREATE_TEMP_INDEX ) + SC(CREATE_TEMP_TABLE ) + SC(CREATE_TEMP_TRIGGER) + SC(CREATE_TEMP_VIEW ) + SC(CREATE_TRIGGER ) + SC(CREATE_VIEW ) + SC(DELETE ) + SC(DROP_INDEX ) + SC(DROP_TABLE ) + SC(DROP_TEMP_INDEX ) + SC(DROP_TEMP_TABLE ) + SC(DROP_TEMP_TRIGGER ) + SC(DROP_TEMP_VIEW ) + SC(DROP_TRIGGER ) + SC(DROP_VIEW ) + SC(INSERT ) + SC(PRAGMA ) + SC(READ ) + SC(SELECT ) + SC(TRANSACTION ) + SC(UPDATE ) + SC(ATTACH ) + SC(DETACH ) + SC(ALTER_TABLE ) + SC(REINDEX ) + SC(ANALYZE ) + SC(CREATE_VTABLE ) + SC(DROP_VTABLE ) + SC(FUNCTION ) + SC(SAVEPOINT ) + + /* file open flags */ + SC(OPEN_READONLY) + SC(OPEN_READWRITE) + SC(OPEN_CREATE) + SC(OPEN_URI) + SC(OPEN_MEMORY) + SC(OPEN_NOMUTEX) + SC(OPEN_FULLMUTEX) + SC(OPEN_SHAREDCACHE) + SC(OPEN_PRIVATECACHE) + + /* terminator */ + { NULL, 0 } +}; + +/* ======================================================= */ + +static const luaL_Reg dblib[] = { + {"isopen", db_isopen }, + {"last_insert_rowid", db_last_insert_rowid }, + {"changes", db_changes }, + {"total_changes", db_total_changes }, + {"errcode", db_errcode }, + {"error_code", db_errcode }, + {"errmsg", db_errmsg }, + {"error_message", db_errmsg }, + {"interrupt", db_interrupt }, + {"db_filename", db_db_filename }, + + {"create_function", db_create_function }, + {"create_aggregate", db_create_aggregate }, + {"create_collation", db_create_collation }, + {"load_extension", db_load_extension }, + + {"trace", db_trace }, + {"progress_handler", db_progress_handler }, + {"busy_timeout", db_busy_timeout }, + {"busy_handler", db_busy_handler }, +#if !defined(LSQLITE_OMIT_UPDATE_HOOK) || !LSQLITE_OMIT_UPDATE_HOOK + {"update_hook", db_update_hook }, + {"commit_hook", db_commit_hook }, + {"rollback_hook", db_rollback_hook }, +#endif + + {"prepare", db_prepare }, + {"rows", db_rows }, + {"urows", db_urows }, + {"nrows", db_nrows }, + + {"exec", db_exec }, + {"execute", db_exec }, + {"close", db_close }, + {"close_vm", db_close_vm }, + {"get_ptr", db_get_ptr }, + + {"__tostring", db_tostring }, + {"__gc", db_gc }, + + {NULL, NULL} +}; + +static const luaL_Reg vmlib[] = { + {"isopen", dbvm_isopen }, + + {"step", dbvm_step }, + {"reset", dbvm_reset }, + {"finalize", dbvm_finalize }, + + {"columns", dbvm_columns }, + + {"bind", dbvm_bind }, + {"bind_values", dbvm_bind_values }, + {"bind_names", dbvm_bind_names }, + {"bind_blob", dbvm_bind_blob }, + {"bind_parameter_count",dbvm_bind_parameter_count}, + {"bind_parameter_name", dbvm_bind_parameter_name}, + + {"get_value", dbvm_get_value }, + {"get_values", dbvm_get_values }, + {"get_name", dbvm_get_name }, + {"get_names", dbvm_get_names }, + {"get_type", dbvm_get_type }, + {"get_types", dbvm_get_types }, + {"get_uvalues", dbvm_get_uvalues }, + {"get_unames", dbvm_get_unames }, + {"get_utypes", dbvm_get_utypes }, + + {"get_named_values", dbvm_get_named_values }, + {"get_named_types", dbvm_get_named_types }, + + {"rows", dbvm_rows }, + {"urows", dbvm_urows }, + {"nrows", dbvm_nrows }, + + {"last_insert_rowid", dbvm_last_insert_rowid }, + + /* compatibility names (added by request) */ + {"idata", dbvm_get_values }, + {"inames", dbvm_get_names }, + {"itypes", dbvm_get_types }, + {"data", dbvm_get_named_values }, + {"type", dbvm_get_named_types }, + + {"__tostring", dbvm_tostring }, + {"__gc", dbvm_gc }, + + { NULL, NULL } +}; + +static const luaL_Reg ctxlib[] = { + {"user_data", lcontext_user_data }, + + {"get_aggregate_data", lcontext_get_aggregate_context }, + {"set_aggregate_data", lcontext_set_aggregate_context }, + {"aggregate_count", lcontext_aggregate_count }, + + {"result", lcontext_result }, + {"result_null", lcontext_result_null }, + {"result_number", lcontext_result_double }, + {"result_double", lcontext_result_double }, + {"result_int", lcontext_result_int }, + {"result_text", lcontext_result_text }, + {"result_blob", lcontext_result_blob }, + {"result_error", lcontext_result_error }, + + {"__tostring", lcontext_tostring }, + {NULL, NULL} +}; + +static const luaL_Reg dbbulib[] = { + + {"step", dbbu_step }, + {"remaining", dbbu_remaining }, + {"pagecount", dbbu_pagecount }, + {"finish", dbbu_finish }, + +/* {"__tostring", dbbu_tostring }, */ + {"__gc", dbbu_gc }, + {NULL, NULL} +}; + +static const luaL_Reg sqlitelib[] = { + {"lversion", lsqlite_lversion }, + {"version", lsqlite_version }, + {"complete", lsqlite_complete }, +#ifndef _WIN32 + {"temp_directory", lsqlite_temp_directory }, +#endif +#if defined(SQLITE_ENABLE_CEROD) + {"activate_cerod", lsqlite_activate_cerod }, +#endif + {"open", lsqlite_open }, + {"open_memory", lsqlite_open_memory }, + {"open_ptr", lsqlite_open_ptr }, + + {"backup_init", lsqlite_backup_init }, + + {"__newindex", lsqlite_newindex }, + {NULL, NULL} +}; + +static void create_meta(lua_State *L, const char *name, const luaL_Reg *lib) { + luaL_newmetatable(L, name); + lua_pushstring(L, "__index"); + lua_pushvalue(L, -2); /* push metatable */ + lua_rawset(L, -3); /* metatable.__index = metatable */ + + /* register metatable functions */ + luaL_openlib(L, NULL, lib, 0); + + /* remove metatable from stack */ + lua_pop(L, 1); +} + +LUALIB_API int luaopen_lsqlite3(lua_State *L) { + create_meta(L, sqlite_meta, dblib); + create_meta(L, sqlite_vm_meta, vmlib); + create_meta(L, sqlite_bu_meta, dbbulib); + create_meta(L, sqlite_ctx_meta, ctxlib); + + luaL_getmetatable(L, sqlite_ctx_meta); + sqlite_ctx_meta_ref = luaL_ref(L, LUA_REGISTRYINDEX); + + /* register (local) sqlite metatable */ + luaL_register(L, "sqlite3", sqlitelib); + + { + int i = 0; + /* add constants to global table */ + while (sqlite_constants[i].name) { + lua_pushstring(L, sqlite_constants[i].name); + lua_pushinteger(L, sqlite_constants[i].value); + lua_rawset(L, -3); + ++i; + } + } + + /* set sqlite's metatable to itself - set as readonly (__newindex) */ + lua_pushvalue(L, -1); + lua_setmetatable(L, -2); + + return 1; +} diff --git a/thirdparty/sqlite/sqlite3.c b/thirdparty/sqlite/sqlite3.c new file mode 100644 index 000000000..0644a39f8 --- /dev/null +++ b/thirdparty/sqlite/sqlite3.c @@ -0,0 +1,269649 @@ +/****************************************************************************** +** This file is an amalgamation of many separate C source files from SQLite +** version 3.53.4. By combining all the individual C code files into this +** single large file, the entire code can be compiled as a single translation +** unit. This allows many compilers to do optimizations that would not be +** possible if the files were compiled separately. Performance improvements +** of 5% or more are commonly seen when SQLite is compiled as a single +** translation unit. +** +** This file is all you need to compile SQLite. To use SQLite in other +** programs, you need this file and the "sqlite3.h" header file that defines +** the programming interface to the SQLite library. (If you do not have +** the "sqlite3.h" header file at hand, you will find a copy embedded within +** the text of this file. Search for "Begin file sqlite3.h" to find the start +** of the embedded sqlite3.h header file.) Additional code files may be needed +** if you want a wrapper to interface SQLite with your choice of programming +** language. The code for the "sqlite3" command-line shell is also in a +** separate file. This file contains only code for the core SQLite library. +** +** The content in this amalgamation comes from Fossil check-in +** bf7c7f30031888f4e796e429ab3978879485 with changes in files: +** +** +*/ +#ifndef SQLITE_AMALGAMATION +#define SQLITE_CORE 1 +#define SQLITE_AMALGAMATION 1 +#ifndef SQLITE_PRIVATE +# define SQLITE_PRIVATE static +#endif +/************** Begin file sqliteInt.h ***************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** Internal interface definitions for SQLite. +** +*/ +#ifndef SQLITEINT_H +#define SQLITEINT_H + +/* Special Comments: +** +** Some comments have special meaning to the tools that measure test +** coverage: +** +** NO_TEST - The branches on this line are not +** measured by branch coverage. This is +** used on lines of code that actually +** implement parts of coverage testing. +** +** OPTIMIZATION-IF-TRUE - This branch is allowed to always be false +** and the correct answer is still obtained, +** though perhaps more slowly. +** +** OPTIMIZATION-IF-FALSE - This branch is allowed to always be true +** and the correct answer is still obtained, +** though perhaps more slowly. +** +** PREVENTS-HARMLESS-OVERREAD - This branch prevents a buffer overread +** that would be harmless and undetectable +** if it did occur. +** +** In all cases, the special comment must be enclosed in the usual +** slash-asterisk...asterisk-slash comment marks, with no spaces between the +** asterisks and the comment text. +*/ + +/* +** Make sure the Tcl calling convention macro is defined. This macro is +** only used by test code and Tcl integration code. +*/ +#ifndef SQLITE_TCLAPI +# define SQLITE_TCLAPI +#endif + +/* +** Include the header file used to customize the compiler options for MSVC. +** This should be done first so that it can successfully prevent spurious +** compiler warnings due to subsequent content in this file and other files +** that are included by this file. +*/ +/************** Include msvc.h in the middle of sqliteInt.h ******************/ +/************** Begin file msvc.h ********************************************/ +/* +** 2015 January 12 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains code that is specific to MSVC. +*/ +#ifndef SQLITE_MSVC_H +#define SQLITE_MSVC_H + +#if defined(_MSC_VER) +#pragma warning(disable : 4054) +#pragma warning(disable : 4055) +#pragma warning(disable : 4100) +#pragma warning(disable : 4127) +#pragma warning(disable : 4130) +#pragma warning(disable : 4152) +#pragma warning(disable : 4189) +#pragma warning(disable : 4206) +#pragma warning(disable : 4210) +#pragma warning(disable : 4232) +#pragma warning(disable : 4244) +#pragma warning(disable : 4305) +#pragma warning(disable : 4306) +#pragma warning(disable : 4702) +#pragma warning(disable : 4706) +#endif /* defined(_MSC_VER) */ + +#if defined(_MSC_VER) && !defined(_WIN64) +#undef SQLITE_4_BYTE_ALIGNED_MALLOC +#define SQLITE_4_BYTE_ALIGNED_MALLOC +#endif /* defined(_MSC_VER) && !defined(_WIN64) */ + +#if !defined(HAVE_LOG2) && defined(_MSC_VER) && _MSC_VER<1800 +#define HAVE_LOG2 0 +#endif /* !defined(HAVE_LOG2) && defined(_MSC_VER) && _MSC_VER<1800 */ + +#endif /* SQLITE_MSVC_H */ + +/************** End of msvc.h ************************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ + +/* +** Special setup for VxWorks +*/ +/************** Include vxworks.h in the middle of sqliteInt.h ***************/ +/************** Begin file vxworks.h *****************************************/ +/* +** 2015-03-02 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains code that is specific to Wind River's VxWorks +*/ +#if defined(__RTP__) || defined(_WRS_KERNEL) +/* This is VxWorks. Set up things specially for that OS +*/ +#include +#include /* amalgamator: dontcache */ +#define OS_VXWORKS 1 +#define SQLITE_OS_OTHER 0 +#define SQLITE_HOMEGROWN_RECURSIVE_MUTEX 1 +#define SQLITE_OMIT_LOAD_EXTENSION 1 +#define SQLITE_ENABLE_LOCKING_STYLE 0 +#define HAVE_UTIME 1 +#else +/* This is not VxWorks. */ +#ifndef OS_VXWORKS +# define OS_VXWORKS 0 +#endif +#define HAVE_FCHOWN 1 +#define HAVE_READLINK 1 +#define HAVE_LSTAT 1 +#endif /* defined(_WRS_KERNEL) */ + +/************** End of vxworks.h *********************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ + +/* +** These #defines should enable >2GB file support on POSIX if the +** underlying operating system supports it. If the OS lacks +** large file support, or if the OS is windows, these should be no-ops. +** +** Ticket #2739: The _LARGEFILE_SOURCE macro must appear before any +** system #includes. Hence, this block of code must be the very first +** code in all source files. +** +** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch +** on the compiler command line. This is necessary if you are compiling +** on a recent machine (ex: Red Hat 7.2) but you want your code to work +** on an older machine (ex: Red Hat 6.0). If you compile on Red Hat 7.2 +** without this option, LFS is enable. But LFS does not exist in the kernel +** in Red Hat 6.0, so the code won't work. Hence, for maximum binary +** portability you should omit LFS. +** +** The previous paragraph was written in 2005. (This paragraph is written +** on 2008-11-28.) These days, all Linux kernels support large files, so +** you should probably leave LFS enabled. But some embedded platforms might +** lack LFS in which case the SQLITE_DISABLE_LFS macro might still be useful. +** +** Similar is true for Mac OS X. LFS is only supported on Mac OS X 9 and later. +*/ +#ifndef SQLITE_DISABLE_LFS +# define _LARGE_FILE 1 +# ifndef _FILE_OFFSET_BITS +# define _FILE_OFFSET_BITS 64 +# endif +# define _LARGEFILE_SOURCE 1 +#endif + +/* The GCC_VERSION and MSVC_VERSION macros are used to +** conditionally include optimizations for each of these compilers. A +** value of 0 means that compiler is not being used. The +** SQLITE_DISABLE_INTRINSIC macro means do not use any compiler-specific +** optimizations, and hence set all compiler macros to 0 +** +** There was once also a CLANG_VERSION macro. However, we learn that the +** version numbers in clang are for "marketing" only and are inconsistent +** and unreliable. Fortunately, all versions of clang also recognize the +** gcc version numbers and have reasonable settings for gcc version numbers, +** so the GCC_VERSION macro will be set to a correct non-zero value even +** when compiling with clang. +*/ +#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC) +# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__) +#else +# define GCC_VERSION 0 +#endif +#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC) +# define MSVC_VERSION _MSC_VER +#else +# define MSVC_VERSION 0 +#endif + +/* +** Some C99 functions in "math.h" are only present for MSVC when its version +** is associated with Visual Studio 2013 or higher. +*/ +#ifndef SQLITE_HAVE_C99_MATH_FUNCS +# if MSVC_VERSION==0 || MSVC_VERSION>=1800 +# define SQLITE_HAVE_C99_MATH_FUNCS (1) +# else +# define SQLITE_HAVE_C99_MATH_FUNCS (0) +# endif +#endif + +/* Needed for various definitions... */ +#if defined(__GNUC__) && !defined(_GNU_SOURCE) +# define _GNU_SOURCE +#endif + +#if defined(__OpenBSD__) && !defined(_BSD_SOURCE) +# define _BSD_SOURCE +#endif + +/* +** Macro to disable warnings about missing "break" at the end of a "case". +*/ +#if defined(__has_attribute) +# if __has_attribute(fallthrough) +# define deliberate_fall_through __attribute__((fallthrough)); +# endif +#endif +#if !defined(deliberate_fall_through) +# define deliberate_fall_through +#endif + +/* +** For MinGW, check to see if we can include the header file containing its +** version information, among other things. Normally, this internal MinGW +** header file would [only] be included automatically by other MinGW header +** files; however, the contained version information is now required by this +** header file to work around binary compatibility issues (see below) and +** this is the only known way to reliably obtain it. This entire #if block +** would be completely unnecessary if there was any other way of detecting +** MinGW via their preprocessor (e.g. if they customized their GCC to define +** some MinGW-specific macros). When compiling for MinGW, either the +** _HAVE_MINGW_H or _HAVE__MINGW_H (note the extra underscore) macro must be +** defined; otherwise, detection of conditions specific to MinGW will be +** disabled. +*/ +#if defined(_HAVE_MINGW_H) +# include "mingw.h" +#elif defined(_HAVE__MINGW_H) +# include "_mingw.h" +#endif + +/* +** For MinGW version 4.x (and higher), check to see if the _USE_32BIT_TIME_T +** define is required to maintain binary compatibility with the MSVC runtime +** library in use (e.g. for Windows XP). +*/ +#if !defined(_USE_32BIT_TIME_T) && !defined(_USE_64BIT_TIME_T) && \ + defined(_WIN32) && !defined(_WIN64) && \ + defined(__MINGW_MAJOR_VERSION) && __MINGW_MAJOR_VERSION >= 4 && \ + defined(__MSVCRT__) +# define _USE_32BIT_TIME_T +#endif + +/* Optionally #include a user-defined header, whereby compilation options +** may be set prior to where they take effect, but after platform setup. +** If SQLITE_CUSTOM_INCLUDE=? is defined, its value names the #include +** file. +*/ +#ifdef SQLITE_CUSTOM_INCLUDE +# define INC_STRINGIFY_(f) #f +# define INC_STRINGIFY(f) INC_STRINGIFY_(f) +# include INC_STRINGIFY(SQLITE_CUSTOM_INCLUDE) +#endif + +/* The public SQLite interface. The _FILE_OFFSET_BITS macro must appear +** first in QNX. Also, the _USE_32BIT_TIME_T macro must appear first for +** MinGW. +*/ +/************** Include sqlite3.h in the middle of sqliteInt.h ***************/ +/************** Begin file sqlite3.h *****************************************/ +/* +** 2001-09-15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This header file defines the interface that the SQLite library +** presents to client programs. If a C-function, structure, datatype, +** or constant definition does not appear in this file, then it is +** not a published API of SQLite, is subject to change without +** notice, and should not be referenced by programs that use SQLite. +** +** Some of the definitions that are in this file are marked as +** "experimental". Experimental interfaces are normally new +** features recently added to SQLite. We do not anticipate changes +** to experimental interfaces but reserve the right to make minor changes +** if experience from use "in the wild" suggest such changes are prudent. +** +** The official C-language API documentation for SQLite is derived +** from comments in this file. This file is the authoritative source +** on how SQLite interfaces are supposed to operate. +** +** The name of this file under configuration management is "sqlite.h.in". +** The makefile makes some minor changes to this file (such as inserting +** the version number) and changes its name to "sqlite3.h" as +** part of the build process. +*/ +#ifndef SQLITE3_H +#define SQLITE3_H +#include /* Needed for the definition of va_list */ + +/* +** Make sure we can call this stuff from C++. +*/ +#if 0 +extern "C" { +#endif + + +/* +** Facilitate override of interface linkage and calling conventions. +** Be aware that these macros may not be used within this particular +** translation of the amalgamation and its associated header file. +** +** The SQLITE_EXTERN and SQLITE_API macros are used to instruct the +** compiler that the target identifier should have external linkage. +** +** The SQLITE_CDECL macro is used to set the calling convention for +** public functions that accept a variable number of arguments. +** +** The SQLITE_APICALL macro is used to set the calling convention for +** public functions that accept a fixed number of arguments. +** +** The SQLITE_STDCALL macro is no longer used and is now deprecated. +** +** The SQLITE_CALLBACK macro is used to set the calling convention for +** function pointers. +** +** The SQLITE_SYSAPI macro is used to set the calling convention for +** functions provided by the operating system. +** +** Currently, the SQLITE_CDECL, SQLITE_APICALL, SQLITE_CALLBACK, and +** SQLITE_SYSAPI macros are used only when building for environments +** that require non-default calling conventions. +*/ +#ifndef SQLITE_EXTERN +# define SQLITE_EXTERN extern +#endif +#ifndef SQLITE_API +# define SQLITE_API +#endif +#ifndef SQLITE_CDECL +# define SQLITE_CDECL +#endif +#ifndef SQLITE_APICALL +# define SQLITE_APICALL +#endif +#ifndef SQLITE_STDCALL +# define SQLITE_STDCALL SQLITE_APICALL +#endif +#ifndef SQLITE_CALLBACK +# define SQLITE_CALLBACK +#endif +#ifndef SQLITE_SYSAPI +# define SQLITE_SYSAPI +#endif + +/* +** These no-op macros are used in front of interfaces to mark those +** interfaces as either deprecated or experimental. New applications +** should not use deprecated interfaces - they are supported for backwards +** compatibility only. Application writers should be aware that +** experimental interfaces are subject to change in point releases. +** +** These macros used to resolve to various kinds of compiler magic that +** would generate warning messages when they were used. But that +** compiler magic ended up generating such a flurry of bug reports +** that we have taken it all out and gone back to using simple +** noop macros. +*/ +#define SQLITE_DEPRECATED +#define SQLITE_EXPERIMENTAL + +/* +** Ensure these symbols were not defined by some previous header file. +*/ +#ifdef SQLITE_VERSION +# undef SQLITE_VERSION +#endif +#ifdef SQLITE_VERSION_NUMBER +# undef SQLITE_VERSION_NUMBER +#endif + +/* +** CAPI3REF: Compile-Time Library Version Numbers +** +** ^(The [SQLITE_VERSION] C preprocessor macro in the sqlite3.h header +** evaluates to a string literal that is the SQLite version in the +** format "X.Y.Z" where X is the major version number (always 3 for +** SQLite3) and Y is the minor version number and Z is the release number.)^ +** ^(The [SQLITE_VERSION_NUMBER] C preprocessor macro resolves to an integer +** with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z are the same +** numbers used in [SQLITE_VERSION].)^ +** The SQLITE_VERSION_NUMBER for any given release of SQLite will also +** be larger than the release from which it is derived. Either Y will +** be held constant and Z will be incremented or else Y will be incremented +** and Z will be reset to zero. +** +** Since [version 3.6.18] ([dateof:3.6.18]), +** SQLite source code has been stored in the +** Fossil configuration management +** system. ^The SQLITE_SOURCE_ID macro evaluates to +** a string which identifies a particular check-in of SQLite +** within its configuration management system. ^The SQLITE_SOURCE_ID +** string contains the date and time of the check-in (UTC) and a SHA1 +** or SHA3-256 hash of the entire source tree. If the source code has +** been edited in any way since it was last checked in, then the last +** four hexadecimal digits of the hash may be modified. +** +** See also: [sqlite3_libversion()], +** [sqlite3_libversion_number()], [sqlite3_sourceid()], +** [sqlite_version()] and [sqlite_source_id()]. +*/ +#define SQLITE_VERSION "3.53.4" +#define SQLITE_VERSION_NUMBER 3053004 +#define SQLITE_SOURCE_ID "2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bcc" +#define SQLITE_SCM_BRANCH "branch-3.53" +#define SQLITE_SCM_TAGS "release version-3.53.4" +#define SQLITE_SCM_DATETIME "2026-07-24T19:02:57.525Z" + +/* +** CAPI3REF: Run-Time Library Version Numbers +** KEYWORDS: sqlite3_version sqlite3_sourceid +** +** These interfaces provide the same information as the [SQLITE_VERSION], +** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros +** but are associated with the library instead of the header file. ^(Cautious +** programmers might include assert() statements in their application to +** verify that values returned by these interfaces match the macros in +** the header, and thus ensure that the application is +** compiled with matching library and header files. +** +**
    +** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
    +** assert( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,80)==0 );
    +** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 );
    +** 
    )^ +** +** ^The sqlite3_version[] string constant contains the text of the +** [SQLITE_VERSION] macro. ^The sqlite3_libversion() function returns a +** pointer to the sqlite3_version[] string constant. The sqlite3_libversion() +** function is provided for use in DLLs since DLL users usually do not have +** direct access to string constants within the DLL. ^The +** sqlite3_libversion_number() function returns an integer equal to +** [SQLITE_VERSION_NUMBER]. ^(The sqlite3_sourceid() function returns +** a pointer to a string constant whose value is the same as the +** [SQLITE_SOURCE_ID] C preprocessor macro. Except if SQLite is built +** using an edited copy of [the amalgamation], then the last four characters +** of the hash might be different from [SQLITE_SOURCE_ID].)^ +** +** See also: [sqlite_version()] and [sqlite_source_id()]. +*/ +SQLITE_API const char sqlite3_version[] = SQLITE_VERSION; +SQLITE_API const char *sqlite3_libversion(void); +SQLITE_API const char *sqlite3_sourceid(void); +SQLITE_API int sqlite3_libversion_number(void); + +/* +** CAPI3REF: Run-Time Library Compilation Options Diagnostics +** +** ^The sqlite3_compileoption_used() function returns 0 or 1 +** indicating whether the specified option was defined at +** compile time. ^The SQLITE_ prefix may be omitted from the +** option name passed to sqlite3_compileoption_used(). +** +** ^The sqlite3_compileoption_get() function allows iterating +** over the list of options that were defined at compile time by +** returning the N-th compile time option string. ^If N is out of range, +** sqlite3_compileoption_get() returns a NULL pointer. ^The SQLITE_ +** prefix is omitted from any strings returned by +** sqlite3_compileoption_get(). +** +** ^Support for the diagnostic functions sqlite3_compileoption_used() +** and sqlite3_compileoption_get() may be omitted by specifying the +** [SQLITE_OMIT_COMPILEOPTION_DIAGS] option at compile time. +** +** See also: SQL functions [sqlite_compileoption_used()] and +** [sqlite_compileoption_get()] and the [compile_options pragma]. +*/ +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS +SQLITE_API int sqlite3_compileoption_used(const char *zOptName); +SQLITE_API const char *sqlite3_compileoption_get(int N); +#else +# define sqlite3_compileoption_used(X) 0 +# define sqlite3_compileoption_get(X) ((void*)0) +#endif + +/* +** CAPI3REF: Test To See If The Library Is Threadsafe +** +** ^The sqlite3_threadsafe() function returns zero if and only if +** SQLite was compiled with mutexing code omitted due to the +** [SQLITE_THREADSAFE] compile-time option being set to 0. +** +** SQLite can be compiled with or without mutexes. When +** the [SQLITE_THREADSAFE] C preprocessor macro is 1 or 2, mutexes +** are enabled and SQLite is threadsafe. When the +** [SQLITE_THREADSAFE] macro is 0, +** the mutexes are omitted. Without the mutexes, it is not safe +** to use SQLite concurrently from more than one thread. +** +** Enabling mutexes incurs a measurable performance penalty. +** So if speed is of utmost importance, it makes sense to disable +** the mutexes. But for maximum safety, mutexes should be enabled. +** ^The default behavior is for mutexes to be enabled. +** +** This interface can be used by an application to make sure that the +** version of SQLite that it is linking against was compiled with +** the desired setting of the [SQLITE_THREADSAFE] macro. +** +** This interface only reports on the compile-time mutex setting +** of the [SQLITE_THREADSAFE] flag. If SQLite is compiled with +** SQLITE_THREADSAFE=1 or =2 then mutexes are enabled by default but +** can be fully or partially disabled using a call to [sqlite3_config()] +** with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD], +** or [SQLITE_CONFIG_SERIALIZED]. ^(The return value of the +** sqlite3_threadsafe() function shows only the compile-time setting of +** thread safety, not any run-time changes to that setting made by +** sqlite3_config(). In other words, the return value from sqlite3_threadsafe() +** is unchanged by calls to sqlite3_config().)^ +** +** See the [threading mode] documentation for additional information. +*/ +SQLITE_API int sqlite3_threadsafe(void); + +/* +** CAPI3REF: Database Connection Handle +** KEYWORDS: {database connection} {database connections} +** +** Each open SQLite database is represented by a pointer to an instance of +** the opaque structure named "sqlite3". It is useful to think of an sqlite3 +** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and +** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()] +** and [sqlite3_close_v2()] are its destructors. There are many other +** interfaces (such as +** [sqlite3_prepare_v2()], [sqlite3_create_function()], and +** [sqlite3_busy_timeout()] to name but three) that are methods on an +** sqlite3 object. +*/ +typedef struct sqlite3 sqlite3; + +/* +** CAPI3REF: 64-Bit Integer Types +** KEYWORDS: sqlite_int64 sqlite_uint64 +** +** Because there is no cross-platform way to specify 64-bit integer types +** SQLite includes typedefs for 64-bit signed and unsigned integers. +** +** The sqlite3_int64 and sqlite3_uint64 are the preferred type definitions. +** The sqlite_int64 and sqlite_uint64 types are supported for backwards +** compatibility only. +** +** ^The sqlite3_int64 and sqlite_int64 types can store integer values +** between -9223372036854775808 and +9223372036854775807 inclusive. ^The +** sqlite3_uint64 and sqlite_uint64 types can store integer values +** between 0 and +18446744073709551615 inclusive. +*/ +#ifdef SQLITE_INT64_TYPE + typedef SQLITE_INT64_TYPE sqlite_int64; +# ifdef SQLITE_UINT64_TYPE + typedef SQLITE_UINT64_TYPE sqlite_uint64; +# else + typedef unsigned SQLITE_INT64_TYPE sqlite_uint64; +# endif +#elif defined(_MSC_VER) || defined(__BORLANDC__) + typedef __int64 sqlite_int64; + typedef unsigned __int64 sqlite_uint64; +#else + typedef long long int sqlite_int64; + typedef unsigned long long int sqlite_uint64; +#endif +typedef sqlite_int64 sqlite3_int64; +typedef sqlite_uint64 sqlite3_uint64; + +/* +** If compiling for a processor that lacks floating point support, +** substitute integer for floating-point. +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# define double sqlite3_int64 +#endif + +/* +** CAPI3REF: Closing A Database Connection +** DESTRUCTOR: sqlite3 +** +** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors +** for the [sqlite3] object. +** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if +** the [sqlite3] object is successfully destroyed and all associated +** resources are deallocated. +** +** Ideally, applications should [sqlite3_finalize | finalize] all +** [prepared statements], [sqlite3_blob_close | close] all [BLOB handles], and +** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated +** with the [sqlite3] object prior to attempting to close the object. +** ^If the database connection is associated with unfinalized prepared +** statements, BLOB handlers, and/or unfinished sqlite3_backup objects then +** sqlite3_close() will leave the database connection open and return +** [SQLITE_BUSY]. ^If sqlite3_close_v2() is called with unfinalized prepared +** statements, unclosed BLOB handlers, and/or unfinished sqlite3_backups, +** it returns [SQLITE_OK] regardless, but instead of deallocating the database +** connection immediately, it marks the database connection as an unusable +** "zombie" and makes arrangements to automatically deallocate the database +** connection after all prepared statements are finalized, all BLOB handles +** are closed, and all backups have finished. The sqlite3_close_v2() interface +** is intended for use with host languages that are garbage collected, and +** where the order in which destructors are called is arbitrary. +** +** ^If an [sqlite3] object is destroyed while a transaction is open, +** the transaction is automatically rolled back. +** +** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)] +** must be either a NULL +** pointer or an [sqlite3] object pointer obtained +** from [sqlite3_open()], [sqlite3_open16()], or +** [sqlite3_open_v2()], and not previously closed. +** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer +** argument is a harmless no-op. +*/ +SQLITE_API int sqlite3_close(sqlite3*); +SQLITE_API int sqlite3_close_v2(sqlite3*); + +/* +** The type for a callback function. +** This is legacy and deprecated. It is included for historical +** compatibility and is not documented. +*/ +typedef int (*sqlite3_callback)(void*,int,char**, char**); + +/* +** CAPI3REF: One-Step Query Execution Interface +** METHOD: sqlite3 +** +** The sqlite3_exec() interface is a convenience wrapper around +** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()], +** that allows an application to run multiple statements of SQL +** without having to use a lot of C code. +** +** ^The sqlite3_exec() interface runs zero or more UTF-8 encoded, +** semicolon-separated SQL statements passed into its 2nd argument, +** in the context of the [database connection] passed in as its 1st +** argument. ^If the callback function of the 3rd argument to +** sqlite3_exec() is not NULL, then it is invoked for each result row +** coming out of the evaluated SQL statements. ^The 4th argument to +** sqlite3_exec() is relayed through to the 1st argument of each +** callback invocation. ^If the callback pointer to sqlite3_exec() +** is NULL, then no callback is ever invoked and result rows are +** ignored. +** +** ^If an error occurs while evaluating the SQL statements passed into +** sqlite3_exec(), then execution of the current statement stops and +** subsequent statements are skipped. ^If the 5th parameter to sqlite3_exec() +** is not NULL then any error message is written into memory obtained +** from [sqlite3_malloc()] and passed back through the 5th parameter. +** To avoid memory leaks, the application should invoke [sqlite3_free()] +** on error message strings returned through the 5th parameter of +** sqlite3_exec() after the error message string is no longer needed. +** ^If the 5th parameter to sqlite3_exec() is not NULL and no errors +** occur, then sqlite3_exec() sets the pointer in its 5th parameter to +** NULL before returning. +** +** ^If an sqlite3_exec() callback returns non-zero, the sqlite3_exec() +** routine returns SQLITE_ABORT without invoking the callback again and +** without running any subsequent SQL statements. +** +** ^The 2nd argument to the sqlite3_exec() callback function is the +** number of columns in the result. ^The 3rd argument to the sqlite3_exec() +** callback is an array of pointers to strings obtained as if from +** [sqlite3_column_text()], one for each column. ^If an element of a +** result row is NULL then the corresponding string pointer for the +** sqlite3_exec() callback is a NULL pointer. ^The 4th argument to the +** sqlite3_exec() callback is an array of pointers to strings where each +** entry represents the name of a corresponding result column as obtained +** from [sqlite3_column_name()]. +** +** ^If the 2nd parameter to sqlite3_exec() is a NULL pointer, a pointer +** to an empty string, or a pointer that contains only whitespace and/or +** SQL comments, then no SQL statements are evaluated and the database +** is not changed. +** +** Restrictions: +** +**
      +**
    • The application must ensure that the 1st parameter to sqlite3_exec() +** is a valid and open [database connection]. +**
    • The application must not close the [database connection] specified by +** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running. +**
    • The application must not modify the SQL statement text passed into +** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running. +**
    • The application must not dereference the arrays or string pointers +** passed as the 3rd and 4th callback parameters after it returns. +**
    +*/ +SQLITE_API int sqlite3_exec( + sqlite3*, /* An open database */ + const char *sql, /* SQL to be evaluated */ + int (*callback)(void*,int,char**,char**), /* Callback function */ + void *, /* 1st argument to callback */ + char **errmsg /* Error msg written here */ +); + +/* +** CAPI3REF: Result Codes +** KEYWORDS: {result code definitions} +** +** Many SQLite functions return an integer result code from the set shown +** here in order to indicate success or failure. +** +** New error codes may be added in future versions of SQLite. +** +** See also: [extended result code definitions] +*/ +#define SQLITE_OK 0 /* Successful result */ +/* beginning-of-error-codes */ +#define SQLITE_ERROR 1 /* Generic error */ +#define SQLITE_INTERNAL 2 /* Internal logic error in SQLite */ +#define SQLITE_PERM 3 /* Access permission denied */ +#define SQLITE_ABORT 4 /* Callback routine requested an abort */ +#define SQLITE_BUSY 5 /* The database file is locked */ +#define SQLITE_LOCKED 6 /* A table in the database is locked */ +#define SQLITE_NOMEM 7 /* A malloc() failed */ +#define SQLITE_READONLY 8 /* Attempt to write a readonly database */ +#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/ +#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ +#define SQLITE_CORRUPT 11 /* The database disk image is malformed */ +#define SQLITE_NOTFOUND 12 /* Unknown opcode in sqlite3_file_control() */ +#define SQLITE_FULL 13 /* Insertion failed because database is full */ +#define SQLITE_CANTOPEN 14 /* Unable to open the database file */ +#define SQLITE_PROTOCOL 15 /* Database lock protocol error */ +#define SQLITE_EMPTY 16 /* Internal use only */ +#define SQLITE_SCHEMA 17 /* The database schema changed */ +#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ +#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ +#define SQLITE_MISMATCH 20 /* Data type mismatch */ +#define SQLITE_MISUSE 21 /* Library used incorrectly */ +#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ +#define SQLITE_AUTH 23 /* Authorization denied */ +#define SQLITE_FORMAT 24 /* Not used */ +#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */ +#define SQLITE_NOTADB 26 /* File opened that is not a database file */ +#define SQLITE_NOTICE 27 /* Notifications from sqlite3_log() */ +#define SQLITE_WARNING 28 /* Warnings from sqlite3_log() */ +#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */ +#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */ +/* end-of-error-codes */ + +/* +** CAPI3REF: Extended Result Codes +** KEYWORDS: {extended result code definitions} +** +** In its default configuration, SQLite API routines return one of 30 integer +** [result codes]. However, experience has shown that many of +** these result codes are too coarse-grained. They do not provide as +** much information about problems as programmers might like. In an effort to +** address this, newer versions of SQLite (version 3.3.8 [dateof:3.3.8] +** and later) include +** support for additional result codes that provide more detailed information +** about errors. These [extended result codes] are enabled or disabled +** on a per database connection basis using the +** [sqlite3_extended_result_codes()] API. Or, the extended code for +** the most recent error can be obtained using +** [sqlite3_extended_errcode()]. +*/ +#define SQLITE_ERROR_MISSING_COLLSEQ (SQLITE_ERROR | (1<<8)) +#define SQLITE_ERROR_RETRY (SQLITE_ERROR | (2<<8)) +#define SQLITE_ERROR_SNAPSHOT (SQLITE_ERROR | (3<<8)) +#define SQLITE_ERROR_RESERVESIZE (SQLITE_ERROR | (4<<8)) +#define SQLITE_ERROR_KEY (SQLITE_ERROR | (5<<8)) +#define SQLITE_ERROR_UNABLE (SQLITE_ERROR | (6<<8)) +#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) +#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) +#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) +#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8)) +#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8)) +#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8)) +#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8)) +#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8)) +#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8)) +#define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10<<8)) +#define SQLITE_IOERR_BLOCKED (SQLITE_IOERR | (11<<8)) +#define SQLITE_IOERR_NOMEM (SQLITE_IOERR | (12<<8)) +#define SQLITE_IOERR_ACCESS (SQLITE_IOERR | (13<<8)) +#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8)) +#define SQLITE_IOERR_LOCK (SQLITE_IOERR | (15<<8)) +#define SQLITE_IOERR_CLOSE (SQLITE_IOERR | (16<<8)) +#define SQLITE_IOERR_DIR_CLOSE (SQLITE_IOERR | (17<<8)) +#define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18<<8)) +#define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) +#define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) +#define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) +#define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) +#define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8)) +#define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8)) +#define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8)) +#define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8)) +#define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8)) +#define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8)) +#define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8)) +#define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8)) +#define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8)) +#define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8)) +#define SQLITE_IOERR_CORRUPTFS (SQLITE_IOERR | (33<<8)) +#define SQLITE_IOERR_IN_PAGE (SQLITE_IOERR | (34<<8)) +#define SQLITE_IOERR_BADKEY (SQLITE_IOERR | (35<<8)) +#define SQLITE_IOERR_CODEC (SQLITE_IOERR | (36<<8)) +#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) +#define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8)) +#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) +#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) +#define SQLITE_BUSY_TIMEOUT (SQLITE_BUSY | (3<<8)) +#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) +#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) +#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) +#define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8)) +#define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) /* Not Used */ +#define SQLITE_CANTOPEN_SYMLINK (SQLITE_CANTOPEN | (6<<8)) +#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) +#define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8)) +#define SQLITE_CORRUPT_INDEX (SQLITE_CORRUPT | (3<<8)) +#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) +#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) +#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8)) +#define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8)) +#define SQLITE_READONLY_CANTINIT (SQLITE_READONLY | (5<<8)) +#define SQLITE_READONLY_DIRECTORY (SQLITE_READONLY | (6<<8)) +#define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) +#define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8)) +#define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8)) +#define SQLITE_CONSTRAINT_FOREIGNKEY (SQLITE_CONSTRAINT | (3<<8)) +#define SQLITE_CONSTRAINT_FUNCTION (SQLITE_CONSTRAINT | (4<<8)) +#define SQLITE_CONSTRAINT_NOTNULL (SQLITE_CONSTRAINT | (5<<8)) +#define SQLITE_CONSTRAINT_PRIMARYKEY (SQLITE_CONSTRAINT | (6<<8)) +#define SQLITE_CONSTRAINT_TRIGGER (SQLITE_CONSTRAINT | (7<<8)) +#define SQLITE_CONSTRAINT_UNIQUE (SQLITE_CONSTRAINT | (8<<8)) +#define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8)) +#define SQLITE_CONSTRAINT_ROWID (SQLITE_CONSTRAINT |(10<<8)) +#define SQLITE_CONSTRAINT_PINNED (SQLITE_CONSTRAINT |(11<<8)) +#define SQLITE_CONSTRAINT_DATATYPE (SQLITE_CONSTRAINT |(12<<8)) +#define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8)) +#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8)) +#define SQLITE_NOTICE_RBU (SQLITE_NOTICE | (3<<8)) +#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8)) +#define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8)) +#define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8)) +#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal only */ + +/* +** CAPI3REF: Flags For File Open Operations +** +** These bit values are intended for use in the +** 3rd parameter to the [sqlite3_open_v2()] interface and +** in the 4th parameter to the [sqlite3_vfs.xOpen] method. +** +** Only those flags marked as "Ok for sqlite3_open_v2()" may be +** used as the third argument to the [sqlite3_open_v2()] interface. +** The other flags have historically been ignored by sqlite3_open_v2(), +** though future versions of SQLite might change so that an error is +** raised if any of the disallowed bits are passed into sqlite3_open_v2(). +** Applications should not depend on the historical behavior. +** +** Note in particular that passing the SQLITE_OPEN_EXCLUSIVE flag into +** [sqlite3_open_v2()] does *not* cause the underlying database file +** to be opened using O_EXCL. Passing SQLITE_OPEN_EXCLUSIVE into +** [sqlite3_open_v2()] has historically been a no-op and might become an +** error in future versions of SQLite. +*/ +#define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */ +#define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */ +#define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */ +#define SQLITE_OPEN_URI 0x00000040 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_MEMORY 0x00000080 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */ +#define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */ +#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */ +#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */ +#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */ +#define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */ +#define SQLITE_OPEN_SUPER_JOURNAL 0x00004000 /* VFS only */ +#define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_WAL 0x00080000 /* VFS only */ +#define SQLITE_OPEN_NOFOLLOW 0x01000000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_EXRESCODE 0x02000000 /* Extended result codes */ + +/* Reserved: 0x00F00000 */ +/* Legacy compatibility: */ +#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */ + + +/* +** CAPI3REF: Device Characteristics +** +** The xDeviceCharacteristics method of the [sqlite3_io_methods] +** object returns an integer which is a vector of these +** bit values expressing I/O characteristics of the mass storage +** device that holds the file that the [sqlite3_io_methods] +** refers to. +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). The SQLITE_IOCAP_POWERSAFE_OVERWRITE property means that +** after reboot following a crash or power loss, the only bytes in a +** file that were written at the application level might have changed +** and that adjacent bytes, even bytes within the same sector are +** guaranteed to be unchanged. The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN +** flag indicates that a file cannot be deleted when open. The +** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on +** read-only media and cannot be changed even by processes with +** elevated privileges. +** +** The SQLITE_IOCAP_BATCH_ATOMIC property means that the underlying +** filesystem supports doing multiple write operations atomically when those +** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and +** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]. +** +** The SQLITE_IOCAP_SUBPAGE_READ property means that it is ok to read +** from the database file in amounts that are not a multiple of the +** page size and that do not begin at a page boundary. Without this +** property, SQLite is careful to only do full-page reads and write +** on aligned pages, with the one exception that it will do a sub-page +** read of the first page to access the database header. +*/ +#define SQLITE_IOCAP_ATOMIC 0x00000001 +#define SQLITE_IOCAP_ATOMIC512 0x00000002 +#define SQLITE_IOCAP_ATOMIC1K 0x00000004 +#define SQLITE_IOCAP_ATOMIC2K 0x00000008 +#define SQLITE_IOCAP_ATOMIC4K 0x00000010 +#define SQLITE_IOCAP_ATOMIC8K 0x00000020 +#define SQLITE_IOCAP_ATOMIC16K 0x00000040 +#define SQLITE_IOCAP_ATOMIC32K 0x00000080 +#define SQLITE_IOCAP_ATOMIC64K 0x00000100 +#define SQLITE_IOCAP_SAFE_APPEND 0x00000200 +#define SQLITE_IOCAP_SEQUENTIAL 0x00000400 +#define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800 +#define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000 +#define SQLITE_IOCAP_IMMUTABLE 0x00002000 +#define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000 +#define SQLITE_IOCAP_SUBPAGE_READ 0x00008000 + +/* +** CAPI3REF: File Locking Levels +** +** SQLite uses one of these integer values as the second +** argument to calls it makes to the xLock() and xUnlock() methods +** of an [sqlite3_io_methods] object. These values are ordered from +** least restrictive to most restrictive. +** +** The argument to xLock() is always SHARED or higher. The argument to +** xUnlock is either SHARED or NONE. +*/ +#define SQLITE_LOCK_NONE 0 /* xUnlock() only */ +#define SQLITE_LOCK_SHARED 1 /* xLock() or xUnlock() */ +#define SQLITE_LOCK_RESERVED 2 /* xLock() only */ +#define SQLITE_LOCK_PENDING 3 /* xLock() only */ +#define SQLITE_LOCK_EXCLUSIVE 4 /* xLock() only */ + +/* +** CAPI3REF: Synchronization Type Flags +** +** When SQLite invokes the xSync() method of an +** [sqlite3_io_methods] object it uses a combination of +** these integer values as the second argument. +** +** When the SQLITE_SYNC_DATAONLY flag is used, it means that the +** sync operation only needs to flush data to mass storage. Inode +** information need not be flushed. If the lower four bits of the flag +** equal SQLITE_SYNC_NORMAL, that means to use normal fsync() semantics. +** If the lower four bits equal SQLITE_SYNC_FULL, that means +** to use Mac OS X style fullsync instead of fsync(). +** +** Do not confuse the SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL flags +** with the [PRAGMA synchronous]=NORMAL and [PRAGMA synchronous]=FULL +** settings. The [synchronous pragma] determines when calls to the +** xSync VFS method occur and applies uniformly across all platforms. +** The SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL flags determine how +** energetic or rigorous or forceful the sync operations are and +** only make a difference on Mac OSX for the default SQLite code. +** (Third-party VFS implementations might also make the distinction +** between SQLITE_SYNC_NORMAL and SQLITE_SYNC_FULL, but among the +** operating systems natively supported by SQLite, only Mac OSX +** cares about the difference.) +*/ +#define SQLITE_SYNC_NORMAL 0x00002 +#define SQLITE_SYNC_FULL 0x00003 +#define SQLITE_SYNC_DATAONLY 0x00010 + +/* +** CAPI3REF: OS Interface Open File Handle +** +** An [sqlite3_file] object represents an open file in the +** [sqlite3_vfs | OS interface layer]. Individual OS interface +** implementations will +** want to subclass this object by appending additional fields +** for their own use. The pMethods entry is a pointer to an +** [sqlite3_io_methods] object that defines methods for performing +** I/O operations on the open file. +*/ +typedef struct sqlite3_file sqlite3_file; +struct sqlite3_file { + const struct sqlite3_io_methods *pMethods; /* Methods for an open file */ +}; + +/* +** CAPI3REF: OS Interface File Virtual Methods Object +** +** Every file opened by the [sqlite3_vfs.xOpen] method populates an +** [sqlite3_file] object (or, more commonly, a subclass of the +** [sqlite3_file] object) with a pointer to an instance of this object. +** This object defines the methods used to perform various operations +** against the open file represented by the [sqlite3_file] object. +** +** If the [sqlite3_vfs.xOpen] method sets the sqlite3_file.pMethods element +** to a non-NULL pointer, then the sqlite3_io_methods.xClose method +** may be invoked even if the [sqlite3_vfs.xOpen] reported that it failed. The +** only way to prevent a call to xClose following a failed [sqlite3_vfs.xOpen] +** is for the [sqlite3_vfs.xOpen] to set the sqlite3_file.pMethods element +** to NULL. +** +** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or +** [SQLITE_SYNC_FULL]. The first choice is the normal fsync(). +** The second choice is a Mac OS X style fullsync. The [SQLITE_SYNC_DATAONLY] +** flag may be ORed in to indicate that only the data of the file +** and not its inode needs to be synced. +** +** The integer values to xLock() and xUnlock() are one of +**
      +**
    • [SQLITE_LOCK_NONE], +**
    • [SQLITE_LOCK_SHARED], +**
    • [SQLITE_LOCK_RESERVED], +**
    • [SQLITE_LOCK_PENDING], or +**
    • [SQLITE_LOCK_EXCLUSIVE]. +**
    +** xLock() upgrades the database file lock. In other words, xLock() moves the +** database file lock in the direction NONE toward EXCLUSIVE. The argument to +** xLock() is always one of SHARED, RESERVED, PENDING, or EXCLUSIVE, never +** SQLITE_LOCK_NONE. If the database file lock is already at or above the +** requested lock, then the call to xLock() is a no-op. +** xUnlock() downgrades the database file lock to either SHARED or NONE. +** If the lock is already at or below the requested lock state, then the call +** to xUnlock() is a no-op. +** The xCheckReservedLock() method checks whether any database connection, +** either in this process or in some other process, is holding a RESERVED, +** PENDING, or EXCLUSIVE lock on the file. It returns, via its output +** pointer parameter, true if such a lock exists and false otherwise. +** +** The xFileControl() method is a generic interface that allows custom +** VFS implementations to directly control an open file using the +** [sqlite3_file_control()] interface. The second "op" argument is an +** integer opcode. The third argument is a generic pointer intended to +** point to a structure that may contain arguments or space in which to +** write return values. Potential uses for xFileControl() might be +** functions to enable blocking locks with timeouts, to change the +** locking strategy (for example to use dot-file locks), to inquire +** about the status of a lock, or to break stale locks. The SQLite +** core reserves all opcodes less than 100 for its own use. +** A [file control opcodes | list of opcodes] less than 100 is available. +** Applications that define a custom xFileControl method should use opcodes +** greater than 100 to avoid conflicts. VFS implementations should +** return [SQLITE_NOTFOUND] for file control opcodes that they do not +** recognize. +** +** The xSectorSize() method returns the sector size of the +** device that underlies the file. The sector size is the +** minimum write that can be performed without disturbing +** other bytes in the file. The xDeviceCharacteristics() +** method returns a bit vector describing behaviors of the +** underlying device: +** +**
      +**
    • [SQLITE_IOCAP_ATOMIC] +**
    • [SQLITE_IOCAP_ATOMIC512] +**
    • [SQLITE_IOCAP_ATOMIC1K] +**
    • [SQLITE_IOCAP_ATOMIC2K] +**
    • [SQLITE_IOCAP_ATOMIC4K] +**
    • [SQLITE_IOCAP_ATOMIC8K] +**
    • [SQLITE_IOCAP_ATOMIC16K] +**
    • [SQLITE_IOCAP_ATOMIC32K] +**
    • [SQLITE_IOCAP_ATOMIC64K] +**
    • [SQLITE_IOCAP_SAFE_APPEND] +**
    • [SQLITE_IOCAP_SEQUENTIAL] +**
    • [SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN] +**
    • [SQLITE_IOCAP_POWERSAFE_OVERWRITE] +**
    • [SQLITE_IOCAP_IMMUTABLE] +**
    • [SQLITE_IOCAP_BATCH_ATOMIC] +**
    • [SQLITE_IOCAP_SUBPAGE_READ] +**
    +** +** The SQLITE_IOCAP_ATOMIC property means that all writes of +** any size are atomic. The SQLITE_IOCAP_ATOMICnnn values +** mean that writes of blocks that are nnn bytes in size and +** are aligned to an address which is an integer multiple of +** nnn are atomic. The SQLITE_IOCAP_SAFE_APPEND value means +** that when data is appended to a file, the data is appended +** first then the size of the file is extended, never the other +** way around. The SQLITE_IOCAP_SEQUENTIAL property means that +** information is written to disk in the same order as calls +** to xWrite(). +** +** If xRead() returns SQLITE_IOERR_SHORT_READ it must also fill +** in the unread portions of the buffer with zeros. A VFS that +** fails to zero-fill short reads might seem to work. However, +** failure to zero-fill short reads will eventually lead to +** database corruption. +*/ +typedef struct sqlite3_io_methods sqlite3_io_methods; +struct sqlite3_io_methods { + int iVersion; + int (*xClose)(sqlite3_file*); + int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); + int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst); + int (*xTruncate)(sqlite3_file*, sqlite3_int64 size); + int (*xSync)(sqlite3_file*, int flags); + int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize); + int (*xLock)(sqlite3_file*, int); + int (*xUnlock)(sqlite3_file*, int); + int (*xCheckReservedLock)(sqlite3_file*, int *pResOut); + int (*xFileControl)(sqlite3_file*, int op, void *pArg); + int (*xSectorSize)(sqlite3_file*); + int (*xDeviceCharacteristics)(sqlite3_file*); + /* Methods above are valid for version 1 */ + int (*xShmMap)(sqlite3_file*, int iPg, int pgsz, int, void volatile**); + int (*xShmLock)(sqlite3_file*, int offset, int n, int flags); + void (*xShmBarrier)(sqlite3_file*); + int (*xShmUnmap)(sqlite3_file*, int deleteFlag); + /* Methods above are valid for version 2 */ + int (*xFetch)(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp); + int (*xUnfetch)(sqlite3_file*, sqlite3_int64 iOfst, void *p); + /* Methods above are valid for version 3 */ + /* Additional methods may be added in future releases */ +}; + +/* +** CAPI3REF: Standard File Control Opcodes +** KEYWORDS: {file control opcodes} {file control opcode} +** +** These integer constants are opcodes for the xFileControl method +** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()] +** interface. +** +**
      +**
    • [[SQLITE_FCNTL_LOCKSTATE]] +** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging. This +** opcode causes the xFileControl method to write the current state of +** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED], +** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE]) +** into an integer that the pArg argument points to. +** This capability is only available if SQLite is compiled with [SQLITE_DEBUG]. +** +**
    • [[SQLITE_FCNTL_SIZE_HINT]] +** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS +** layer a hint of how large the database file will grow to be during the +** current transaction. This hint is not guaranteed to be accurate but it +** is often close. The underlying VFS might choose to preallocate database +** file space based on this hint in order to help writes to the database +** file run faster. +** +**
    • [[SQLITE_FCNTL_SIZE_LIMIT]] +** The [SQLITE_FCNTL_SIZE_LIMIT] opcode is used by in-memory VFS that +** implements [sqlite3_deserialize()] to set an upper bound on the size +** of the in-memory database. The argument is a pointer to a [sqlite3_int64]. +** If the integer pointed to is negative, then it is filled in with the +** current limit. Otherwise the limit is set to the larger of the value +** of the integer pointed to and the current database size. The integer +** pointed to is set to the new limit. +** +**
    • [[SQLITE_FCNTL_CHUNK_SIZE]] +** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS +** extends and truncates the database file in chunks of a size specified +** by the user. The fourth argument to [sqlite3_file_control()] should +** point to an integer (type int) containing the new chunk-size to use +** for the nominated database. Allocating database file space in large +** chunks (say 1MB at a time), may reduce file-system fragmentation and +** improve performance on some systems. +** +**
    • [[SQLITE_FCNTL_FILE_POINTER]] +** The [SQLITE_FCNTL_FILE_POINTER] opcode is used to obtain a pointer +** to the [sqlite3_file] object associated with a particular database +** connection. See also [SQLITE_FCNTL_JOURNAL_POINTER]. +** +**
    • [[SQLITE_FCNTL_JOURNAL_POINTER]] +** The [SQLITE_FCNTL_JOURNAL_POINTER] opcode is used to obtain a pointer +** to the [sqlite3_file] object associated with the journal file (either +** the [rollback journal] or the [write-ahead log]) for a particular database +** connection. See also [SQLITE_FCNTL_FILE_POINTER]. +** +**
    • [[SQLITE_FCNTL_SYNC_OMITTED]] +** The SQLITE_FCNTL_SYNC_OMITTED file-control is no longer used. +** +**
    • [[SQLITE_FCNTL_SYNC]] +** The [SQLITE_FCNTL_SYNC] opcode is generated internally by SQLite and +** sent to the VFS immediately before the xSync method is invoked on a +** database file descriptor. Or, if the xSync method is not invoked +** because the user has configured SQLite with +** [PRAGMA synchronous | PRAGMA synchronous=OFF] it is invoked in place +** of the xSync method. In most cases, the pointer argument passed with +** this file-control is NULL. However, if the database file is being synced +** as part of a multi-database commit, the argument points to a nul-terminated +** string containing the transactions super-journal file name. VFSes that +** do not need this signal should silently ignore this opcode. Applications +** should not call [sqlite3_file_control()] with this opcode as doing so may +** disrupt the operation of the specialized VFSes that do require it. +** +**
    • [[SQLITE_FCNTL_COMMIT_PHASETWO]] +** The [SQLITE_FCNTL_COMMIT_PHASETWO] opcode is generated internally by SQLite +** and sent to the VFS after a transaction has been committed immediately +** but before the database is unlocked. VFSes that do not need this signal +** should silently ignore this opcode. Applications should not call +** [sqlite3_file_control()] with this opcode as doing so may disrupt the +** operation of the specialized VFSes that do require it. +** +**
    • [[SQLITE_FCNTL_WIN32_AV_RETRY]] +** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic +** retry counts and intervals for certain disk I/O operations for the +** windows [VFS] in order to provide robustness in the presence of +** anti-virus programs. By default, the windows VFS will retry file read, +** file write, and file delete operations up to 10 times, with a delay +** of 25 milliseconds before the first retry and with the delay increasing +** by an additional 25 milliseconds with each subsequent retry. This +** opcode allows these two values (10 retries and 25 milliseconds of delay) +** to be adjusted. The values are changed for all database connections +** within the same process. The argument is a pointer to an array of two +** integers where the first integer is the new retry count and the second +** integer is the delay. If either integer is negative, then the setting +** is not changed but instead the prior value of that setting is written +** into the array entry, allowing the current retry settings to be +** interrogated. The zDbName parameter is ignored. +** +**
    • [[SQLITE_FCNTL_PERSIST_WAL]] +** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the +** persistent [WAL | Write Ahead Log] setting. By default, the auxiliary +** write ahead log ([WAL file]) and shared memory +** files used for transaction control +** are automatically deleted when the latest connection to the database +** closes. Setting persistent WAL mode causes those files to persist after +** close. Persisting the files is useful when other processes that do not +** have write permission on the directory containing the database file want +** to read the database file, as the WAL and shared memory files must exist +** in order for the database to be readable. The fourth parameter to +** [sqlite3_file_control()] for this opcode should be a pointer to an integer. +** That integer is 0 to disable persistent WAL mode or 1 to enable persistent +** WAL mode. If the integer is -1, then it is overwritten with the current +** WAL persistence setting. +** +**
    • [[SQLITE_FCNTL_POWERSAFE_OVERWRITE]] +** ^The [SQLITE_FCNTL_POWERSAFE_OVERWRITE] opcode is used to set or query the +** persistent "powersafe-overwrite" or "PSOW" setting. The PSOW setting +** determines the [SQLITE_IOCAP_POWERSAFE_OVERWRITE] bit of the +** xDeviceCharacteristics methods. The fourth parameter to +** [sqlite3_file_control()] for this opcode should be a pointer to an integer. +** That integer is 0 to disable zero-damage mode or 1 to enable zero-damage +** mode. If the integer is -1, then it is overwritten with the current +** zero-damage mode setting. +** +**
    • [[SQLITE_FCNTL_OVERWRITE]] +** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening +** a write transaction to indicate that, unless it is rolled back for some +** reason, the entire database file will be overwritten by the current +** transaction. This is used by VACUUM operations. +** +**
    • [[SQLITE_FCNTL_VFSNAME]] +** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of +** all [VFSes] in the VFS stack. The names of all VFS shims and the +** final bottom-level VFS are written into memory obtained from +** [sqlite3_malloc()] and the result is stored in the char* variable +** that the fourth parameter of [sqlite3_file_control()] points to. +** The caller is responsible for freeing the memory when done. As with +** all file-control actions, there is no guarantee that this will actually +** do anything. Callers should initialize the char* variable to a NULL +** pointer in case this file-control is not implemented. This file-control +** is intended for diagnostic use only. +** +**
    • [[SQLITE_FCNTL_VFS_POINTER]] +** ^The [SQLITE_FCNTL_VFS_POINTER] opcode finds a pointer to the top-level +** [VFSes] currently in use. ^(The argument X in +** sqlite3_file_control(db,SQLITE_FCNTL_VFS_POINTER,X) must be +** of type "[sqlite3_vfs] **". This opcode will set *X +** to a pointer to the top-level VFS.)^ +** ^When there are multiple VFS shims in the stack, this opcode finds the +** upper-most shim only. +** +**
    • [[SQLITE_FCNTL_PRAGMA]] +** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA] +** file control is sent to the open [sqlite3_file] object corresponding +** to the database file to which the pragma statement refers. ^The argument +** to the [SQLITE_FCNTL_PRAGMA] file control is an array of +** pointers to strings (char**) in which the second element of the array +** is the name of the pragma and the third element is the argument to the +** pragma or NULL if the pragma has no argument. ^The handler for an +** [SQLITE_FCNTL_PRAGMA] file control can optionally make the first element +** of the char** argument point to a string obtained from [sqlite3_mprintf()] +** or the equivalent and that string will become the result of the pragma or +** the error message if the pragma fails. ^If the +** [SQLITE_FCNTL_PRAGMA] file control returns [SQLITE_NOTFOUND], then normal +** [PRAGMA] processing continues. ^If the [SQLITE_FCNTL_PRAGMA] +** file control returns [SQLITE_OK], then the parser assumes that the +** VFS has handled the PRAGMA itself and the parser generates a no-op +** prepared statement if result string is NULL, or that returns a copy +** of the result string if the string is non-NULL. +** ^If the [SQLITE_FCNTL_PRAGMA] file control returns +** any result code other than [SQLITE_OK] or [SQLITE_NOTFOUND], that means +** that the VFS encountered an error while handling the [PRAGMA] and the +** compilation of the PRAGMA fails with an error. ^The [SQLITE_FCNTL_PRAGMA] +** file control occurs at the beginning of pragma statement analysis and so +** it is able to override built-in [PRAGMA] statements. +** +**
    • [[SQLITE_FCNTL_BUSYHANDLER]] +** ^The [SQLITE_FCNTL_BUSYHANDLER] +** file-control may be invoked by SQLite on the database file handle +** shortly after it is opened in order to provide a custom VFS with access +** to the connection's busy-handler callback. The argument is of type (void**) +** - an array of two (void *) values. The first (void *) actually points +** to a function of type (int (*)(void *)). In order to invoke the connection's +** busy-handler, this function should be invoked with the second (void *) in +** the array as the only argument. If it returns non-zero, then the operation +** should be retried. If it returns zero, the custom VFS should abandon the +** current operation. +** +**
    • [[SQLITE_FCNTL_TEMPFILENAME]] +** ^Applications can invoke the [SQLITE_FCNTL_TEMPFILENAME] file-control +** to have SQLite generate a +** temporary filename using the same algorithm that is followed to generate +** temporary filenames for TEMP tables and other internal uses. The +** argument should be a char** which will be filled with the filename +** written into memory obtained from [sqlite3_malloc()]. The caller should +** invoke [sqlite3_free()] on the result to avoid a memory leak. +** +**
    • [[SQLITE_FCNTL_MMAP_SIZE]] +** The [SQLITE_FCNTL_MMAP_SIZE] file control is used to query or set the +** maximum number of bytes that will be used for memory-mapped I/O. +** The argument is a pointer to a value of type sqlite3_int64 that +** is an advisory maximum number of bytes in the file to memory map. The +** pointer is overwritten with the old value. The limit is not changed if +** the value originally pointed to is negative, and so the current limit +** can be queried by passing in a pointer to a negative number. This +** file-control is used internally to implement [PRAGMA mmap_size]. +** +**
    • [[SQLITE_FCNTL_TRACE]] +** The [SQLITE_FCNTL_TRACE] file control provides advisory information +** to the VFS about what the higher layers of the SQLite stack are doing. +** This file control is used by some VFS activity tracing [shims]. +** The argument is a zero-terminated string. Higher layers in the +** SQLite stack may generate instances of this file control if +** the [SQLITE_USE_FCNTL_TRACE] compile-time option is enabled. +** +**
    • [[SQLITE_FCNTL_HAS_MOVED]] +** The [SQLITE_FCNTL_HAS_MOVED] file control interprets its argument as a +** pointer to an integer and it writes a boolean into that integer depending +** on whether or not the file has been renamed, moved, or deleted since it +** was first opened. +** +**
    • [[SQLITE_FCNTL_WIN32_GET_HANDLE]] +** The [SQLITE_FCNTL_WIN32_GET_HANDLE] opcode can be used to obtain the +** underlying native file handle associated with a file handle. This file +** control interprets its argument as a pointer to a native file handle and +** writes the resulting value there. +** +**
    • [[SQLITE_FCNTL_WIN32_SET_HANDLE]] +** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This +** opcode causes the xFileControl method to swap the file handle with the one +** pointed to by the pArg argument. This capability is used during testing +** and only needs to be supported when SQLITE_TEST is defined. +** +**
    • [[SQLITE_FCNTL_NULL_IO]] +** The [SQLITE_FCNTL_NULL_IO] opcode sets the low-level file descriptor +** or file handle for the [sqlite3_file] object such that it will no longer +** read or write to the database file. +** +**
    • [[SQLITE_FCNTL_WAL_BLOCK]] +** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might +** be advantageous to block on the next WAL lock if the lock is not immediately +** available. The WAL subsystem issues this signal during rare +** circumstances in order to fix a problem with priority inversion. +** Applications should not use this file-control. +** +**
    • [[SQLITE_FCNTL_ZIPVFS]] +** The [SQLITE_FCNTL_ZIPVFS] opcode is implemented by zipvfs only. All other +** VFS should return SQLITE_NOTFOUND for this opcode. +** +**
    • [[SQLITE_FCNTL_RBU]] +** The [SQLITE_FCNTL_RBU] opcode is implemented by the special VFS used by +** the RBU extension only. All other VFS should return SQLITE_NOTFOUND for +** this opcode. +** +**
    • [[SQLITE_FCNTL_BEGIN_ATOMIC_WRITE]] +** If the [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] opcode returns SQLITE_OK, then +** the file descriptor is placed in "batch write mode", which +** means all subsequent write operations will be deferred and done +** atomically at the next [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]. Systems +** that do not support batch atomic writes will return SQLITE_NOTFOUND. +** ^Following a successful SQLITE_FCNTL_BEGIN_ATOMIC_WRITE and prior to +** the closing [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] or +** [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE], SQLite will make +** no VFS interface calls on the same [sqlite3_file] file descriptor +** except for calls to the xWrite method and the xFileControl method +** with [SQLITE_FCNTL_SIZE_HINT]. +** +**
    • [[SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]] +** The [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] opcode causes all write +** operations since the previous successful call to +** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be performed atomically. +** This file control returns [SQLITE_OK] if and only if the writes were +** all performed successfully and have been committed to persistent storage. +** ^Regardless of whether or not it is successful, this file control takes +** the file descriptor out of batch write mode so that all subsequent +** write operations are independent. +** ^SQLite will never invoke SQLITE_FCNTL_COMMIT_ATOMIC_WRITE without +** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE]. +** +**
    • [[SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE]] +** The [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE] opcode causes all write +** operations since the previous successful call to +** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be rolled back. +** ^This file control takes the file descriptor out of batch write mode +** so that all subsequent write operations are independent. +** ^SQLite will never invoke SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE without +** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE]. +** +**
    • [[SQLITE_FCNTL_LOCK_TIMEOUT]] +** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode is used to configure a VFS +** to block for up to M milliseconds before failing when attempting to +** obtain a file lock using the xLock or xShmLock methods of the VFS. +** The parameter is a pointer to a 32-bit signed integer that contains +** the value that M is to be set to. Before returning, the 32-bit signed +** integer is overwritten with the previous value of M. +** +**
    • [[SQLITE_FCNTL_BLOCK_ON_CONNECT]] +** The [SQLITE_FCNTL_BLOCK_ON_CONNECT] opcode is used to configure the +** VFS to block when taking a SHARED lock to connect to a wal mode database. +** This is used to implement the functionality associated with +** SQLITE_SETLK_BLOCK_ON_CONNECT. +** +**
    • [[SQLITE_FCNTL_DATA_VERSION]] +** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to +** a database file. The argument is a pointer to a 32-bit unsigned integer. +** The "data version" for the pager is written into the pointer. The +** "data version" changes whenever any change occurs to the corresponding +** database file, either through SQL statements on the same database +** connection or through transactions committed by separate database +** connections possibly in other processes. The [sqlite3_total_changes()] +** interface can be used to find if any database on the connection has changed, +** but that interface responds to changes on TEMP as well as MAIN and does +** not provide a mechanism to detect changes to MAIN only. Also, the +** [sqlite3_total_changes()] interface responds to internal changes only and +** omits changes made by other database connections. The +** [PRAGMA data_version] command provides a mechanism to detect changes to +** a single attached database that occur due to other database connections, +** but omits changes implemented by the database connection on which it is +** called. This file control is the only mechanism to detect changes that +** happen either internally or externally and that are associated with +** a particular attached database. +** +**
    • [[SQLITE_FCNTL_CKPT_START]] +** The [SQLITE_FCNTL_CKPT_START] opcode is invoked from within a checkpoint +** in wal mode before the client starts to copy pages from the wal +** file to the database file. +** +**
    • [[SQLITE_FCNTL_CKPT_DONE]] +** The [SQLITE_FCNTL_CKPT_DONE] opcode is invoked from within a checkpoint +** in wal mode after the client has finished copying pages from the wal +** file to the database file, but before the *-shm file is updated to +** record the fact that the pages have been checkpointed. +** +**
    • [[SQLITE_FCNTL_EXTERNAL_READER]] +** The EXPERIMENTAL [SQLITE_FCNTL_EXTERNAL_READER] opcode is used to detect +** whether or not there is a database client in another process with a wal-mode +** transaction open on the database or not. It is only available on unix. The +** (void*) argument passed with this file-control should be a pointer to a +** value of type (int). The integer value is set to 1 if the database is a wal +** mode database and there exists at least one client in another process that +** currently has an SQL transaction open on the database. It is set to 0 if +** the database is not a wal-mode db, or if there is no such connection in any +** other process. This opcode cannot be used to detect transactions opened +** by clients within the current process, only within other processes. +** +**
    • [[SQLITE_FCNTL_CKSM_FILE]] +** The [SQLITE_FCNTL_CKSM_FILE] opcode is for use internally by the +** [checksum VFS shim] only. +** +**
    • [[SQLITE_FCNTL_RESET_CACHE]] +** If there is currently no transaction open on the database, and the +** database is not a temp db, then the [SQLITE_FCNTL_RESET_CACHE] file-control +** purges the contents of the in-memory page cache. If there is an open +** transaction, or if the db is a temp-db, this opcode is a no-op, not an error. +** +**
    • [[SQLITE_FCNTL_FILESTAT]] +** The [SQLITE_FCNTL_FILESTAT] opcode returns low-level diagnostic information +** about the [sqlite3_file] objects used access the database and journal files +** for the given schema. The fourth parameter to [sqlite3_file_control()] +** should be an initialized [sqlite3_str] pointer. JSON text describing +** various aspects of the sqlite3_file object is appended to the sqlite3_str. +** The SQLITE_FCNTL_FILESTAT opcode is usually a no-op, unless compile-time +** options are used to enable it. +**
    +*/ +#define SQLITE_FCNTL_LOCKSTATE 1 +#define SQLITE_FCNTL_GET_LOCKPROXYFILE 2 +#define SQLITE_FCNTL_SET_LOCKPROXYFILE 3 +#define SQLITE_FCNTL_LAST_ERRNO 4 +#define SQLITE_FCNTL_SIZE_HINT 5 +#define SQLITE_FCNTL_CHUNK_SIZE 6 +#define SQLITE_FCNTL_FILE_POINTER 7 +#define SQLITE_FCNTL_SYNC_OMITTED 8 +#define SQLITE_FCNTL_WIN32_AV_RETRY 9 +#define SQLITE_FCNTL_PERSIST_WAL 10 +#define SQLITE_FCNTL_OVERWRITE 11 +#define SQLITE_FCNTL_VFSNAME 12 +#define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13 +#define SQLITE_FCNTL_PRAGMA 14 +#define SQLITE_FCNTL_BUSYHANDLER 15 +#define SQLITE_FCNTL_TEMPFILENAME 16 +#define SQLITE_FCNTL_MMAP_SIZE 18 +#define SQLITE_FCNTL_TRACE 19 +#define SQLITE_FCNTL_HAS_MOVED 20 +#define SQLITE_FCNTL_SYNC 21 +#define SQLITE_FCNTL_COMMIT_PHASETWO 22 +#define SQLITE_FCNTL_WIN32_SET_HANDLE 23 +#define SQLITE_FCNTL_WAL_BLOCK 24 +#define SQLITE_FCNTL_ZIPVFS 25 +#define SQLITE_FCNTL_RBU 26 +#define SQLITE_FCNTL_VFS_POINTER 27 +#define SQLITE_FCNTL_JOURNAL_POINTER 28 +#define SQLITE_FCNTL_WIN32_GET_HANDLE 29 +#define SQLITE_FCNTL_PDB 30 +#define SQLITE_FCNTL_BEGIN_ATOMIC_WRITE 31 +#define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32 +#define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33 +#define SQLITE_FCNTL_LOCK_TIMEOUT 34 +#define SQLITE_FCNTL_DATA_VERSION 35 +#define SQLITE_FCNTL_SIZE_LIMIT 36 +#define SQLITE_FCNTL_CKPT_DONE 37 +#define SQLITE_FCNTL_RESERVE_BYTES 38 +#define SQLITE_FCNTL_CKPT_START 39 +#define SQLITE_FCNTL_EXTERNAL_READER 40 +#define SQLITE_FCNTL_CKSM_FILE 41 +#define SQLITE_FCNTL_RESET_CACHE 42 +#define SQLITE_FCNTL_NULL_IO 43 +#define SQLITE_FCNTL_BLOCK_ON_CONNECT 44 +#define SQLITE_FCNTL_FILESTAT 45 + +/* deprecated names */ +#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE +#define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE +#define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO + +/* reserved file-control numbers: +** 101 +** 102 +** 103 +*/ + + +/* +** CAPI3REF: Mutex Handle +** +** The mutex module within SQLite defines [sqlite3_mutex] to be an +** abstract type for a mutex object. The SQLite core never looks +** at the internal representation of an [sqlite3_mutex]. It only +** deals with pointers to the [sqlite3_mutex] object. +** +** Mutexes are created using [sqlite3_mutex_alloc()]. +*/ +typedef struct sqlite3_mutex sqlite3_mutex; + +/* +** CAPI3REF: Loadable Extension Thunk +** +** A pointer to the opaque sqlite3_api_routines structure is passed as +** the third parameter to entry points of [loadable extensions]. This +** structure must be typedefed in order to work around compiler warnings +** on some platforms. +*/ +typedef struct sqlite3_api_routines sqlite3_api_routines; + +/* +** CAPI3REF: File Name +** +** Type [sqlite3_filename] is used by SQLite to pass filenames to the +** xOpen method of a [VFS]. It may be cast to (const char*) and treated +** as a normal, nul-terminated, UTF-8 buffer containing the filename, but +** may also be passed to special APIs such as: +** +**
      +**
    • sqlite3_filename_database() +**
    • sqlite3_filename_journal() +**
    • sqlite3_filename_wal() +**
    • sqlite3_uri_parameter() +**
    • sqlite3_uri_boolean() +**
    • sqlite3_uri_int64() +**
    • sqlite3_uri_key() +**
    +*/ +typedef const char *sqlite3_filename; + +/* +** CAPI3REF: OS Interface Object +** +** An instance of the sqlite3_vfs object defines the interface between +** the SQLite core and the underlying operating system. The "vfs" +** in the name of the object stands for "virtual file system". See +** the [VFS | VFS documentation] for further information. +** +** The VFS interface is sometimes extended by adding new methods onto +** the end. Each time such an extension occurs, the iVersion field +** is incremented. The iVersion value started out as 1 in +** SQLite [version 3.5.0] on [dateof:3.5.0], then increased to 2 +** with SQLite [version 3.7.0] on [dateof:3.7.0], and then increased +** to 3 with SQLite [version 3.7.6] on [dateof:3.7.6]. Additional fields +** may be appended to the sqlite3_vfs object and the iVersion value +** may increase again in future versions of SQLite. +** Note that due to an oversight, the structure +** of the sqlite3_vfs object changed in the transition from +** SQLite [version 3.5.9] to [version 3.6.0] on [dateof:3.6.0] +** and yet the iVersion field was not increased. +** +** The szOsFile field is the size of the subclassed [sqlite3_file] +** structure used by this VFS. mxPathname is the maximum length of +** a pathname in this VFS. +** +** Registered sqlite3_vfs objects are kept on a linked list formed by +** the pNext pointer. The [sqlite3_vfs_register()] +** and [sqlite3_vfs_unregister()] interfaces manage this list +** in a thread-safe way. The [sqlite3_vfs_find()] interface +** searches the list. Neither the application code nor the VFS +** implementation should use the pNext pointer. +** +** The pNext field is the only field in the sqlite3_vfs +** structure that SQLite will ever modify. SQLite will only access +** or modify this field while holding a particular static mutex. +** The application should never modify anything within the sqlite3_vfs +** object once the object has been registered. +** +** The zName field holds the name of the VFS module. The name must +** be unique across all VFS modules. +** +** [[sqlite3_vfs.xOpen]] +** ^SQLite guarantees that the zFilename parameter to xOpen +** is either a NULL pointer or string obtained +** from xFullPathname() with an optional suffix added. +** ^If a suffix is added to the zFilename parameter, it will +** consist of a single "-" character followed by no more than +** 11 alphanumeric and/or "-" characters. +** ^SQLite further guarantees that +** the string will be valid and unchanged until xClose() is +** called. Because of the previous sentence, +** the [sqlite3_file] can safely store a pointer to the +** filename if it needs to remember the filename for some reason. +** If the zFilename parameter to xOpen is a NULL pointer then xOpen +** must invent its own temporary name for the file. ^Whenever the +** xFilename parameter is NULL it will also be the case that the +** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE]. +** +** The flags argument to xOpen() includes all bits set in +** the flags argument to [sqlite3_open_v2()]. Or if [sqlite3_open()] +** or [sqlite3_open16()] is used, then flags includes at least +** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. +** If xOpen() opens a file read-only then it sets *pOutFlags to +** include [SQLITE_OPEN_READONLY]. Other bits in *pOutFlags may be set. +** +** ^(SQLite will also add one of the following flags to the xOpen() +** call, depending on the object being opened: +** +**
      +**
    • [SQLITE_OPEN_MAIN_DB] +**
    • [SQLITE_OPEN_MAIN_JOURNAL] +**
    • [SQLITE_OPEN_TEMP_DB] +**
    • [SQLITE_OPEN_TEMP_JOURNAL] +**
    • [SQLITE_OPEN_TRANSIENT_DB] +**
    • [SQLITE_OPEN_SUBJOURNAL] +**
    • [SQLITE_OPEN_SUPER_JOURNAL] +**
    • [SQLITE_OPEN_WAL] +**
    )^ +** +** The file I/O implementation can use the object type flags to +** change the way it deals with files. For example, an application +** that does not care about crash recovery or rollback might make +** the open of a journal file a no-op. Writes to this journal would +** also be no-ops, and any attempt to read the journal would return +** SQLITE_IOERR. Or the implementation might recognize that a database +** file will be doing page-aligned sector reads and writes in a random +** order and set up its I/O subsystem accordingly. +** +** SQLite might also add one of the following flags to the xOpen method: +** +**
      +**
    • [SQLITE_OPEN_DELETEONCLOSE] +**
    • [SQLITE_OPEN_EXCLUSIVE] +**
    +** +** The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be +** deleted when it is closed. ^The [SQLITE_OPEN_DELETEONCLOSE] +** will be set for TEMP databases and their journals, transient +** databases, and subjournals. +** +** ^The [SQLITE_OPEN_EXCLUSIVE] flag is always used in conjunction +** with the [SQLITE_OPEN_CREATE] flag, which are both directly +** analogous to the O_EXCL and O_CREAT flags of the POSIX open() +** API. The SQLITE_OPEN_EXCLUSIVE flag, when paired with the +** SQLITE_OPEN_CREATE, is used to indicate that file should always +** be created, and that it is an error if it already exists. +** It is not used to indicate the file should be opened +** for exclusive access. +** +** ^At least szOsFile bytes of memory are allocated by SQLite +** to hold the [sqlite3_file] structure passed as the third +** argument to xOpen. The xOpen method does not have to +** allocate the structure; it should just fill it in. Note that +** the xOpen method must set the sqlite3_file.pMethods to either +** a valid [sqlite3_io_methods] object or to NULL. xOpen must do +** this even if the open fails. SQLite expects that the sqlite3_file.pMethods +** element will be valid after xOpen returns regardless of the success +** or failure of the xOpen call. +** +** [[sqlite3_vfs.xAccess]] +** ^The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS] +** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to +** test whether a file is readable and writable, or [SQLITE_ACCESS_READ] +** to test whether a file is at least readable. The SQLITE_ACCESS_READ +** flag is never actually used and is not implemented in the built-in +** VFSes of SQLite. The file is named by the second argument and can be a +** directory. The xAccess method returns [SQLITE_OK] on success or some +** non-zero error code if there is an I/O error or if the name of +** the file given in the second argument is illegal. If SQLITE_OK +** is returned, then non-zero or zero is written into *pResOut to indicate +** whether or not the file is accessible. +** +** ^SQLite will always allocate at least mxPathname+1 bytes for the +** output buffer xFullPathname. The exact size of the output buffer +** is also passed as a parameter to both methods. If the output buffer +** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is +** handled as a fatal error by SQLite, vfs implementations should endeavor +** to prevent this by setting mxPathname to a sufficiently large value. +** +** The xRandomness(), xSleep(), xCurrentTime(), and xCurrentTimeInt64() +** interfaces are not strictly a part of the filesystem, but they are +** included in the VFS structure for completeness. +** The xRandomness() function attempts to return nBytes bytes +** of good-quality randomness into zOut. The return value is +** the actual number of bytes of randomness obtained. +** The xSleep() method causes the calling thread to sleep for at +** least the number of microseconds given. ^The xCurrentTime() +** method returns a Julian Day Number for the current date and time as +** a floating point value. +** ^The xCurrentTimeInt64() method returns, as an integer, the Julian +** Day Number multiplied by 86400000 (the number of milliseconds in +** a 24-hour day). +** ^SQLite will use the xCurrentTimeInt64() method to get the current +** date and time if that method is available (if iVersion is 2 or +** greater and the function pointer is not NULL) and will fall back +** to xCurrentTime() if xCurrentTimeInt64() is unavailable. +** +** ^The xSetSystemCall(), xGetSystemCall(), and xNextSystemCall() interfaces +** are not used by the SQLite core. These optional interfaces are provided +** by some VFSes to facilitate testing of the VFS code. By overriding +** system calls with functions under its control, a test program can +** simulate faults and error conditions that would otherwise be difficult +** or impossible to induce. The set of system calls that can be overridden +** varies from one VFS to another, and from one version of the same VFS to the +** next. Applications that use these interfaces must be prepared for any +** or all of these interfaces to be NULL or for their behavior to change +** from one release to the next. Applications must not attempt to access +** any of these methods if the iVersion of the VFS is less than 3. +*/ +typedef struct sqlite3_vfs sqlite3_vfs; +typedef void (*sqlite3_syscall_ptr)(void); +struct sqlite3_vfs { + int iVersion; /* Structure version number (currently 3) */ + int szOsFile; /* Size of subclassed sqlite3_file */ + int mxPathname; /* Maximum file pathname length */ + sqlite3_vfs *pNext; /* Next registered VFS */ + const char *zName; /* Name of this virtual file system */ + void *pAppData; /* Pointer to application-specific data */ + int (*xOpen)(sqlite3_vfs*, sqlite3_filename zName, sqlite3_file*, + int flags, int *pOutFlags); + int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); + int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut); + int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); + void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); + void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); + void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void); + void (*xDlClose)(sqlite3_vfs*, void*); + int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut); + int (*xSleep)(sqlite3_vfs*, int microseconds); + int (*xCurrentTime)(sqlite3_vfs*, double*); + int (*xGetLastError)(sqlite3_vfs*, int, char *); + /* + ** The methods above are in version 1 of the sqlite_vfs object + ** definition. Those that follow are added in version 2 or later + */ + int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*); + /* + ** The methods above are in versions 1 and 2 of the sqlite_vfs object. + ** Those below are for version 3 and greater. + */ + int (*xSetSystemCall)(sqlite3_vfs*, const char *zName, sqlite3_syscall_ptr); + sqlite3_syscall_ptr (*xGetSystemCall)(sqlite3_vfs*, const char *zName); + const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName); + /* + ** The methods above are in versions 1 through 3 of the sqlite_vfs object. + ** New fields may be appended in future versions. The iVersion + ** value will increment whenever this happens. + */ +}; + +/* +** CAPI3REF: Flags for the xAccess VFS method +** +** These integer constants can be used as the third parameter to +** the xAccess method of an [sqlite3_vfs] object. They determine +** what kind of permissions the xAccess method is looking for. +** With SQLITE_ACCESS_EXISTS, the xAccess method +** simply checks whether the file exists. +** With SQLITE_ACCESS_READWRITE, the xAccess method +** checks whether the named directory is both readable and writable +** (in other words, if files can be added, removed, and renamed within +** the directory). +** The SQLITE_ACCESS_READWRITE constant is currently used only by the +** [temp_store_directory pragma], though this could change in a future +** release of SQLite. +** With SQLITE_ACCESS_READ, the xAccess method +** checks whether the file is readable. The SQLITE_ACCESS_READ constant is +** currently unused, though it might be used in a future release of +** SQLite. +*/ +#define SQLITE_ACCESS_EXISTS 0 +#define SQLITE_ACCESS_READWRITE 1 /* Used by PRAGMA temp_store_directory */ +#define SQLITE_ACCESS_READ 2 /* Unused */ + +/* +** CAPI3REF: Flags for the xShmLock VFS method +** +** These integer constants define the various locking operations +** allowed by the xShmLock method of [sqlite3_io_methods]. The +** following are the only legal combinations of flags to the +** xShmLock method: +** +**
      +**
    • SQLITE_SHM_LOCK | SQLITE_SHM_SHARED +**
    • SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE +**
    • SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED +**
    • SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE +**
    +** +** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as +** was given on the corresponding lock. +** +** The xShmLock method can transition between unlocked and SHARED or +** between unlocked and EXCLUSIVE. It cannot transition between SHARED +** and EXCLUSIVE. +*/ +#define SQLITE_SHM_UNLOCK 1 +#define SQLITE_SHM_LOCK 2 +#define SQLITE_SHM_SHARED 4 +#define SQLITE_SHM_EXCLUSIVE 8 + +/* +** CAPI3REF: Maximum xShmLock index +** +** The xShmLock method on [sqlite3_io_methods] may use values +** between 0 and this upper bound as its "offset" argument. +** The SQLite core will never attempt to acquire or release a +** lock outside of this range +*/ +#define SQLITE_SHM_NLOCK 8 + + +/* +** CAPI3REF: Initialize The SQLite Library +** +** ^The sqlite3_initialize() routine initializes the +** SQLite library. ^The sqlite3_shutdown() routine +** deallocates any resources that were allocated by sqlite3_initialize(). +** These routines are designed to aid in process initialization and +** shutdown on embedded systems. Workstation applications using +** SQLite normally do not need to invoke either of these routines. +** +** A call to sqlite3_initialize() is an "effective" call if it is +** the first time sqlite3_initialize() is invoked during the lifetime of +** the process, or if it is the first time sqlite3_initialize() is invoked +** following a call to sqlite3_shutdown(). ^(Only an effective call +** of sqlite3_initialize() does any initialization. All other calls +** are harmless no-ops.)^ +** +** A call to sqlite3_shutdown() is an "effective" call if it is the first +** call to sqlite3_shutdown() since the last sqlite3_initialize(). ^(Only +** an effective call to sqlite3_shutdown() does any deinitialization. +** All other valid calls to sqlite3_shutdown() are harmless no-ops.)^ +** +** The sqlite3_initialize() interface is threadsafe, but sqlite3_shutdown() +** is not. The sqlite3_shutdown() interface must only be called from a +** single thread. All open [database connections] must be closed and all +** other SQLite resources must be deallocated prior to invoking +** sqlite3_shutdown(). +** +** Among other things, ^sqlite3_initialize() will invoke +** sqlite3_os_init(). Similarly, ^sqlite3_shutdown() +** will invoke sqlite3_os_end(). +** +** ^The sqlite3_initialize() routine returns [SQLITE_OK] on success. +** ^If for some reason, sqlite3_initialize() is unable to initialize +** the library (perhaps it is unable to allocate a needed resource such +** as a mutex) it returns an [error code] other than [SQLITE_OK]. +** +** ^The sqlite3_initialize() routine is called internally by many other +** SQLite interfaces so that an application usually does not need to +** invoke sqlite3_initialize() directly. For example, [sqlite3_open()] +** calls sqlite3_initialize() so the SQLite library will be automatically +** initialized when [sqlite3_open()] is called if it has not been initialized +** already. ^However, if SQLite is compiled with the [SQLITE_OMIT_AUTOINIT] +** compile-time option, then the automatic calls to sqlite3_initialize() +** are omitted and the application must call sqlite3_initialize() directly +** prior to using any other SQLite interface. For maximum portability, +** it is recommended that applications always invoke sqlite3_initialize() +** directly prior to using any other SQLite interface. Future releases +** of SQLite may require this. In other words, the behavior exhibited +** when SQLite is compiled with [SQLITE_OMIT_AUTOINIT] might become the +** default behavior in some future release of SQLite. +** +** The sqlite3_os_init() routine does operating-system specific +** initialization of the SQLite library. The sqlite3_os_end() +** routine undoes the effect of sqlite3_os_init(). Typical tasks +** performed by these routines include allocation or deallocation +** of static resources, initialization of global variables, +** setting up a default [sqlite3_vfs] module, or setting up +** a default configuration using [sqlite3_config()]. +** +** The application should never invoke either sqlite3_os_init() +** or sqlite3_os_end() directly. The application should only invoke +** sqlite3_initialize() and sqlite3_shutdown(). The sqlite3_os_init() +** interface is called automatically by sqlite3_initialize() and +** sqlite3_os_end() is called by sqlite3_shutdown(). Appropriate +** implementations for sqlite3_os_init() and sqlite3_os_end() +** are built into SQLite when it is compiled for Unix, Windows, or OS/2. +** When [custom builds | built for other platforms] +** (using the [SQLITE_OS_OTHER=1] compile-time +** option) the application must supply a suitable implementation for +** sqlite3_os_init() and sqlite3_os_end(). An application-supplied +** implementation of sqlite3_os_init() or sqlite3_os_end() +** must return [SQLITE_OK] on success and some other [error code] upon +** failure. +*/ +SQLITE_API int sqlite3_initialize(void); +SQLITE_API int sqlite3_shutdown(void); +SQLITE_API int sqlite3_os_init(void); +SQLITE_API int sqlite3_os_end(void); + +/* +** CAPI3REF: Configuring The SQLite Library +** +** The sqlite3_config() interface is used to make global configuration +** changes to SQLite in order to tune SQLite to the specific needs of +** the application. The default configuration is recommended for most +** applications and so this routine is usually not necessary. It is +** provided to support rare applications with unusual needs. +** +** The sqlite3_config() interface is not threadsafe. The application +** must ensure that no other SQLite interfaces are invoked by other +** threads while sqlite3_config() is running. +** +** The first argument to sqlite3_config() is an integer +** [configuration option] that determines +** what property of SQLite is to be configured. Subsequent arguments +** vary depending on the [configuration option] +** in the first argument. +** +** For most configuration options, the sqlite3_config() interface +** may only be invoked prior to library initialization using +** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()]. +** The exceptional configuration options that may be invoked at any time +** are called "anytime configuration options". +** ^If sqlite3_config() is called after [sqlite3_initialize()] and before +** [sqlite3_shutdown()] with a first argument that is not an anytime +** configuration option, then the sqlite3_config() call will +** return SQLITE_MISUSE. +** Note, however, that ^sqlite3_config() can be called as part of the +** implementation of an application-defined [sqlite3_os_init()]. +** +** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK]. +** ^If the option is unknown or SQLite is unable to set the option +** then this routine returns a non-zero [error code]. +*/ +SQLITE_API int sqlite3_config(int, ...); + +/* +** CAPI3REF: Configure database connections +** METHOD: sqlite3 +** +** The sqlite3_db_config() interface is used to make configuration +** changes to a [database connection]. The interface is similar to +** [sqlite3_config()] except that the changes apply to a single +** [database connection] (specified in the first argument). +** +** The second argument to sqlite3_db_config(D,V,...) is the +** [SQLITE_DBCONFIG_LOOKASIDE | configuration verb] - an integer code +** that indicates what aspect of the [database connection] is being configured. +** Subsequent arguments vary depending on the configuration verb. +** +** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if +** the call is considered successful. +*/ +SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...); + +/* +** CAPI3REF: Memory Allocation Routines +** +** An instance of this object defines the interface between SQLite +** and low-level memory allocation routines. +** +** This object is used in only one place in the SQLite interface. +** A pointer to an instance of this object is the argument to +** [sqlite3_config()] when the configuration option is +** [SQLITE_CONFIG_MALLOC] or [SQLITE_CONFIG_GETMALLOC]. +** By creating an instance of this object +** and passing it to [sqlite3_config]([SQLITE_CONFIG_MALLOC]) +** during configuration, an application can specify an alternative +** memory allocation subsystem for SQLite to use for all of its +** dynamic memory needs. +** +** Note that SQLite comes with several [built-in memory allocators] +** that are perfectly adequate for the overwhelming majority of applications +** and that this object is only useful to a tiny minority of applications +** with specialized memory allocation requirements. This object is +** also used during testing of SQLite in order to specify an alternative +** memory allocator that simulates memory out-of-memory conditions in +** order to verify that SQLite recovers gracefully from such +** conditions. +** +** The xMalloc, xRealloc, and xFree methods must work like the +** malloc(), realloc() and free() functions from the standard C library. +** ^SQLite guarantees that the second argument to +** xRealloc is always a value returned by a prior call to xRoundup. +** +** xSize should return the allocated size of a memory allocation +** previously obtained from xMalloc or xRealloc. The allocated size +** is always at least as big as the requested size but may be larger. +** +** The xRoundup method returns what would be the allocated size of +** a memory allocation given a particular requested size. Most memory +** allocators round up memory allocations at least to the next multiple +** of 8. Some allocators round up to a larger multiple or to a power of 2. +** Every memory allocation request coming in through [sqlite3_malloc()] +** or [sqlite3_realloc()] first calls xRoundup. If xRoundup returns 0, +** that causes the corresponding memory allocation to fail. +** +** The xInit method initializes the memory allocator. For example, +** it might allocate any required mutexes or initialize internal data +** structures. The xShutdown method is invoked (indirectly) by +** [sqlite3_shutdown()] and should deallocate any resources acquired +** by xInit. The pAppData pointer is used as the only parameter to +** xInit and xShutdown. +** +** SQLite holds the [SQLITE_MUTEX_STATIC_MAIN] mutex when it invokes +** the xInit method, so the xInit method need not be threadsafe. The +** xShutdown method is only called from [sqlite3_shutdown()] so it does +** not need to be threadsafe either. For all other methods, SQLite +** holds the [SQLITE_MUTEX_STATIC_MEM] mutex as long as the +** [SQLITE_CONFIG_MEMSTATUS] configuration option is turned on (which +** it is by default) and so the methods are automatically serialized. +** However, if [SQLITE_CONFIG_MEMSTATUS] is disabled, then the other +** methods must be threadsafe or else make their own arrangements for +** serialization. +** +** SQLite will never invoke xInit() more than once without an intervening +** call to xShutdown(). +*/ +typedef struct sqlite3_mem_methods sqlite3_mem_methods; +struct sqlite3_mem_methods { + void *(*xMalloc)(int); /* Memory allocation function */ + void (*xFree)(void*); /* Free a prior allocation */ + void *(*xRealloc)(void*,int); /* Resize an allocation */ + int (*xSize)(void*); /* Return the size of an allocation */ + int (*xRoundup)(int); /* Round up request size to allocation size */ + int (*xInit)(void*); /* Initialize the memory allocator */ + void (*xShutdown)(void*); /* Deinitialize the memory allocator */ + void *pAppData; /* Argument to xInit() and xShutdown() */ +}; + +/* +** CAPI3REF: Configuration Options +** KEYWORDS: {configuration option} +** +** These constants are the available integer configuration options that +** can be passed as the first argument to the [sqlite3_config()] interface. +** +** Most of the configuration options for sqlite3_config() +** will only work if invoked prior to [sqlite3_initialize()] or after +** [sqlite3_shutdown()]. The few exceptions to this rule are called +** "anytime configuration options". +** ^Calling [sqlite3_config()] with a first argument that is not an +** anytime configuration option in between calls to [sqlite3_initialize()] and +** [sqlite3_shutdown()] is a no-op that returns SQLITE_MISUSE. +** +** The set of anytime configuration options can change (by insertions +** and/or deletions) from one release of SQLite to the next. +** As of SQLite version 3.42.0, the complete set of anytime configuration +** options is: +**
      +**
    • SQLITE_CONFIG_LOG +**
    • SQLITE_CONFIG_PCACHE_HDRSZ +**
    +** +** New configuration options may be added in future releases of SQLite. +** Existing configuration options might be discontinued. Applications +** should check the return code from [sqlite3_config()] to make sure that +** the call worked. The [sqlite3_config()] interface will return a +** non-zero [error code] if a discontinued or unsupported configuration option +** is invoked. +** +**
    +** [[SQLITE_CONFIG_SINGLETHREAD]]
    SQLITE_CONFIG_SINGLETHREAD
    +**
    There are no arguments to this option. ^This option sets the +** [threading mode] to Single-thread. In other words, it disables +** all mutexing and puts SQLite into a mode where it can only be used +** by a single thread. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** it is not possible to change the [threading mode] from its default +** value of Single-thread and so [sqlite3_config()] will return +** [SQLITE_ERROR] if called with the SQLITE_CONFIG_SINGLETHREAD +** configuration option.
    +** +** [[SQLITE_CONFIG_MULTITHREAD]]
    SQLITE_CONFIG_MULTITHREAD
    +**
    There are no arguments to this option. ^This option sets the +** [threading mode] to Multi-thread. In other words, it disables +** mutexing on [database connection] and [prepared statement] objects. +** The application is responsible for serializing access to +** [database connections] and [prepared statements]. But other mutexes +** are enabled so that SQLite will be safe to use in a multi-threaded +** environment as long as no two threads attempt to use the same +** [database connection] at the same time. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** it is not possible to set the Multi-thread [threading mode] and +** [sqlite3_config()] will return [SQLITE_ERROR] if called with the +** SQLITE_CONFIG_MULTITHREAD configuration option.
    +** +** [[SQLITE_CONFIG_SERIALIZED]]
    SQLITE_CONFIG_SERIALIZED
    +**
    There are no arguments to this option. ^This option sets the +** [threading mode] to Serialized. In other words, this option enables +** all mutexes including the recursive +** mutexes on [database connection] and [prepared statement] objects. +** In this mode (which is the default when SQLite is compiled with +** [SQLITE_THREADSAFE=1]) the SQLite library will itself serialize access +** to [database connections] and [prepared statements] so that the +** application is free to use the same [database connection] or the +** same [prepared statement] in different threads at the same time. +** ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** it is not possible to set the Serialized [threading mode] and +** [sqlite3_config()] will return [SQLITE_ERROR] if called with the +** SQLITE_CONFIG_SERIALIZED configuration option.
    +** +** [[SQLITE_CONFIG_MALLOC]]
    SQLITE_CONFIG_MALLOC
    +**
    ^(The SQLITE_CONFIG_MALLOC option takes a single argument which is +** a pointer to an instance of the [sqlite3_mem_methods] structure. +** The argument specifies +** alternative low-level memory allocation routines to be used in place of +** the memory allocation routines built into SQLite.)^ ^SQLite makes +** its own private copy of the content of the [sqlite3_mem_methods] structure +** before the [sqlite3_config()] call returns.
    +** +** [[SQLITE_CONFIG_GETMALLOC]]
    SQLITE_CONFIG_GETMALLOC
    +**
    ^(The SQLITE_CONFIG_GETMALLOC option takes a single argument which +** is a pointer to an instance of the [sqlite3_mem_methods] structure. +** The [sqlite3_mem_methods] +** structure is filled with the currently defined memory allocation routines.)^ +** This option can be used to overload the default memory allocation +** routines with a wrapper that simulates memory allocation failure or +** tracks memory usage, for example.
    +** +** [[SQLITE_CONFIG_SMALL_MALLOC]]
    SQLITE_CONFIG_SMALL_MALLOC
    +**
    ^The SQLITE_CONFIG_SMALL_MALLOC option takes a single argument of +** type int, interpreted as a boolean, which if true provides a hint to +** SQLite that it should avoid large memory allocations if possible. +** SQLite will run faster if it is free to make large memory allocations, +** but some applications might prefer to run slower in exchange for +** guarantees about memory fragmentation that are possible if large +** allocations are avoided. This hint is normally off. +**
    +** +** [[SQLITE_CONFIG_MEMSTATUS]]
    SQLITE_CONFIG_MEMSTATUS
    +**
    ^The SQLITE_CONFIG_MEMSTATUS option takes a single argument of type int, +** interpreted as a boolean, which enables or disables the collection of +** memory allocation statistics. ^(When memory allocation statistics are +** disabled, the following SQLite interfaces become non-operational: +**
      +**
    • [sqlite3_hard_heap_limit64()] +**
    • [sqlite3_memory_used()] +**
    • [sqlite3_memory_highwater()] +**
    • [sqlite3_soft_heap_limit64()] +**
    • [sqlite3_status64()] +**
    )^ +** ^Memory allocation statistics are enabled by default unless SQLite is +** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory +** allocation statistics are disabled by default. +**
    +** +** [[SQLITE_CONFIG_SCRATCH]]
    SQLITE_CONFIG_SCRATCH
    +**
    The SQLITE_CONFIG_SCRATCH option is no longer used. +**
    +** +** [[SQLITE_CONFIG_PAGECACHE]]
    SQLITE_CONFIG_PAGECACHE
    +**
    ^The SQLITE_CONFIG_PAGECACHE option specifies a memory pool +** that SQLite can use for the database page cache with the default page +** cache implementation. +** This configuration option is a no-op if an application-defined page +** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2]. +** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to +** 8-byte aligned memory (pMem), the size of each page cache line (sz), +** and the number of cache lines (N). +** The sz argument should be the size of the largest database page +** (a power of two between 512 and 65536) plus some extra bytes for each +** page header. ^The number of extra bytes needed by the page header +** can be determined using [SQLITE_CONFIG_PCACHE_HDRSZ]. +** ^It is harmless, apart from the wasted memory, +** for the sz parameter to be larger than necessary. The pMem +** argument must be either a NULL pointer or a pointer to an 8-byte +** aligned block of memory of at least sz*N bytes, otherwise +** subsequent behavior is undefined. +** ^When pMem is not NULL, SQLite will strive to use the memory provided +** to satisfy page cache needs, falling back to [sqlite3_malloc()] if +** a page cache line is larger than sz bytes or if all of the pMem buffer +** is exhausted. +** ^If pMem is NULL and N is non-zero, then each database connection +** does an initial bulk allocation for page cache memory +** from [sqlite3_malloc()] sufficient for N cache lines if N is positive or +** of -1024*N bytes if N is negative. ^If additional +** page cache memory is needed beyond what is provided by the initial +** allocation, then SQLite goes to [sqlite3_malloc()] separately for each +** additional cache line.
    +** +** [[SQLITE_CONFIG_HEAP]]
    SQLITE_CONFIG_HEAP
    +**
    ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer +** that SQLite will use for all of its dynamic memory allocation needs +** beyond those provided for by [SQLITE_CONFIG_PAGECACHE]. +** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled +** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns +** [SQLITE_ERROR] if invoked otherwise. +** ^There are three arguments to SQLITE_CONFIG_HEAP: +** An 8-byte aligned pointer to the memory, +** the number of bytes in the memory buffer, and the minimum allocation size. +** ^If the first pointer (the memory pointer) is NULL, then SQLite reverts +** to using its default memory allocator (the system malloc() implementation), +** undoing any prior invocation of [SQLITE_CONFIG_MALLOC]. ^If the +** memory pointer is not NULL then the alternative memory +** allocator is engaged to handle all of SQLites memory allocation needs. +** The first pointer (the memory pointer) must be aligned to an 8-byte +** boundary or subsequent behavior of SQLite will be undefined. +** The minimum allocation size is capped at 2**12. Reasonable values +** for the minimum allocation size are 2**5 through 2**8.
    +** +** [[SQLITE_CONFIG_MUTEX]]
    SQLITE_CONFIG_MUTEX
    +**
    ^(The SQLITE_CONFIG_MUTEX option takes a single argument which is a +** pointer to an instance of the [sqlite3_mutex_methods] structure. +** The argument specifies alternative low-level mutex routines to be used +** in place of the mutex routines built into SQLite.)^ ^SQLite makes a copy of +** the content of the [sqlite3_mutex_methods] structure before the call to +** [sqlite3_config()] returns. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** the entire mutexing subsystem is omitted from the build and hence calls to +** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will +** return [SQLITE_ERROR].
    +** +** [[SQLITE_CONFIG_GETMUTEX]]
    SQLITE_CONFIG_GETMUTEX
    +**
    ^(The SQLITE_CONFIG_GETMUTEX option takes a single argument which +** is a pointer to an instance of the [sqlite3_mutex_methods] structure. The +** [sqlite3_mutex_methods] +** structure is filled with the currently defined mutex routines.)^ +** This option can be used to overload the default mutex allocation +** routines with a wrapper used to track mutex usage for performance +** profiling or testing, for example. ^If SQLite is compiled with +** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then +** the entire mutexing subsystem is omitted from the build and hence calls to +** [sqlite3_config()] with the SQLITE_CONFIG_GETMUTEX configuration option will +** return [SQLITE_ERROR].
    +** +** [[SQLITE_CONFIG_LOOKASIDE]]
    SQLITE_CONFIG_LOOKASIDE
    +**
    ^(The SQLITE_CONFIG_LOOKASIDE option takes two arguments that determine +** the default size of [lookaside memory] on each [database connection]. +** The first argument is the +** size of each lookaside buffer slot ("sz") and the second is the number of +** slots allocated to each database connection ("cnt").)^ +** ^(SQLITE_CONFIG_LOOKASIDE sets the default lookaside size. +** The [SQLITE_DBCONFIG_LOOKASIDE] option to [sqlite3_db_config()] can +** be used to change the lookaside configuration on individual connections.)^ +** The [-DSQLITE_DEFAULT_LOOKASIDE] option can be used to change the +** default lookaside configuration at compile-time. +**
    +** +** [[SQLITE_CONFIG_PCACHE2]]
    SQLITE_CONFIG_PCACHE2
    +**
    ^(The SQLITE_CONFIG_PCACHE2 option takes a single argument which is +** a pointer to an [sqlite3_pcache_methods2] object. This object specifies +** the interface to a custom page cache implementation.)^ +** ^SQLite makes a copy of the [sqlite3_pcache_methods2] object.
    +** +** [[SQLITE_CONFIG_GETPCACHE2]]
    SQLITE_CONFIG_GETPCACHE2
    +**
    ^(The SQLITE_CONFIG_GETPCACHE2 option takes a single argument which +** is a pointer to an [sqlite3_pcache_methods2] object. SQLite copies off +** the current page cache implementation into that object.)^
    +** +** [[SQLITE_CONFIG_LOG]]
    SQLITE_CONFIG_LOG
    +**
    The SQLITE_CONFIG_LOG option is used to configure the SQLite +** global [error log]. +** (^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a +** function with a call signature of void(*)(void*,int,const char*), +** and a pointer to void. ^If the function pointer is not NULL, it is +** invoked by [sqlite3_log()] to process each logging event. ^If the +** function pointer is NULL, the [sqlite3_log()] interface becomes a no-op. +** ^The void pointer that is the second argument to SQLITE_CONFIG_LOG is +** passed through as the first parameter to the application-defined logger +** function whenever that function is invoked. ^The second parameter to +** the logger function is a copy of the first parameter to the corresponding +** [sqlite3_log()] call and is intended to be a [result code] or an +** [extended result code]. ^The third parameter passed to the logger is +** a log message after formatting via [sqlite3_snprintf()]. +** The SQLite logging interface is not reentrant; the logger function +** supplied by the application must not invoke any SQLite interface. +** In a multi-threaded application, the application-defined logger +** function must be threadsafe.
    +** +** [[SQLITE_CONFIG_URI]]
    SQLITE_CONFIG_URI +**
    ^(The SQLITE_CONFIG_URI option takes a single argument of type int. +** If non-zero, then URI handling is globally enabled. If the parameter is zero, +** then URI handling is globally disabled.)^ ^If URI handling is globally +** enabled, all filenames passed to [sqlite3_open()], [sqlite3_open_v2()], +** [sqlite3_open16()] or +** specified as part of [ATTACH] commands are interpreted as URIs, regardless +** of whether or not the [SQLITE_OPEN_URI] flag is set when the database +** connection is opened. ^If it is globally disabled, filenames are +** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the +** database connection is opened. ^(By default, URI handling is globally +** disabled. The default value may be changed by compiling with the +** [SQLITE_USE_URI] symbol defined.)^ +** +** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]]
    SQLITE_CONFIG_COVERING_INDEX_SCAN +**
    ^The SQLITE_CONFIG_COVERING_INDEX_SCAN option takes a single integer +** argument which is interpreted as a boolean in order to enable or disable +** the use of covering indices for full table scans in the query optimizer. +** ^The default setting is determined +** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on" +** if that compile-time option is omitted. +** The ability to disable the use of covering indices for full table scans +** is because some incorrectly coded legacy applications might malfunction +** when the optimization is enabled. Providing the ability to +** disable the optimization allows the older, buggy application code to work +** without change even with newer versions of SQLite. +** +** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]] +**
    SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE +**
    These options are obsolete and should not be used by new code. +** They are retained for backwards compatibility but are now no-ops. +**
    +** +** [[SQLITE_CONFIG_SQLLOG]] +**
    SQLITE_CONFIG_SQLLOG +**
    This option is only available if sqlite is compiled with the +** [SQLITE_ENABLE_SQLLOG] pre-processor macro defined. The first argument should +** be a pointer to a function of type void(*)(void*,sqlite3*,const char*, int). +** The second should be of type (void*). The callback is invoked by the library +** in three separate circumstances, identified by the value passed as the +** fourth parameter. If the fourth parameter is 0, then the database connection +** passed as the second argument has just been opened. The third argument +** points to a buffer containing the name of the main database file. If the +** fourth parameter is 1, then the SQL statement that the third parameter +** points to has just been executed. Or, if the fourth parameter is 2, then +** the connection being passed as the second parameter is being closed. The +** third parameter is passed NULL In this case. An example of using this +** configuration option can be seen in the "test_sqllog.c" source file in +** the canonical SQLite source tree.
    +** +** [[SQLITE_CONFIG_MMAP_SIZE]] +**
    SQLITE_CONFIG_MMAP_SIZE +**
    ^SQLITE_CONFIG_MMAP_SIZE takes two 64-bit integer (sqlite3_int64) values +** that are the default mmap size limit (the default setting for +** [PRAGMA mmap_size]) and the maximum allowed mmap size limit. +** ^The default setting can be overridden by each database connection using +** either the [PRAGMA mmap_size] command, or by using the +** [SQLITE_FCNTL_MMAP_SIZE] file control. ^(The maximum allowed mmap size +** will be silently truncated if necessary so that it does not exceed the +** compile-time maximum mmap size set by the +** [SQLITE_MAX_MMAP_SIZE] compile-time option.)^ +** ^If either argument to this option is negative, then that argument is +** changed to its compile-time default. +** +** [[SQLITE_CONFIG_WIN32_HEAPSIZE]] +**
    SQLITE_CONFIG_WIN32_HEAPSIZE +**
    ^The SQLITE_CONFIG_WIN32_HEAPSIZE option is only available if SQLite is +** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro +** defined. ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value +** that specifies the maximum size of the created heap. +** +** [[SQLITE_CONFIG_PCACHE_HDRSZ]] +**
    SQLITE_CONFIG_PCACHE_HDRSZ +**
    ^The SQLITE_CONFIG_PCACHE_HDRSZ option takes a single parameter which +** is a pointer to an integer and writes into that integer the number of extra +** bytes per page required for each page in [SQLITE_CONFIG_PAGECACHE]. +** The amount of extra space required can change depending on the compiler, +** target platform, and SQLite version. +** +** [[SQLITE_CONFIG_PMASZ]] +**
    SQLITE_CONFIG_PMASZ +**
    ^The SQLITE_CONFIG_PMASZ option takes a single parameter which +** is an unsigned integer and sets the "Minimum PMA Size" for the multithreaded +** sorter to that integer. The default minimum PMA Size is set by the +** [SQLITE_SORTER_PMASZ] compile-time option. New threads are launched +** to help with sort operations when multithreaded sorting +** is enabled (using the [PRAGMA threads] command) and the amount of content +** to be sorted exceeds the page size times the minimum of the +** [PRAGMA cache_size] setting and this value. +** +** [[SQLITE_CONFIG_STMTJRNL_SPILL]] +**
    SQLITE_CONFIG_STMTJRNL_SPILL +**
    ^The SQLITE_CONFIG_STMTJRNL_SPILL option takes a single parameter which +** becomes the [statement journal] spill-to-disk threshold. +** [Statement journals] are held in memory until their size (in bytes) +** exceeds this threshold, at which point they are written to disk. +** Or if the threshold is -1, statement journals are always held +** exclusively in memory. +** Since many statement journals never become large, setting the spill +** threshold to a value such as 64KiB can greatly reduce the amount of +** I/O required to support statement rollback. +** The default value for this setting is controlled by the +** [SQLITE_STMTJRNL_SPILL] compile-time option. +** +** [[SQLITE_CONFIG_SORTERREF_SIZE]] +**
    SQLITE_CONFIG_SORTERREF_SIZE +**
    The SQLITE_CONFIG_SORTERREF_SIZE option accepts a single parameter +** of type (int) - the new value of the sorter-reference size threshold. +** Usually, when SQLite uses an external sort to order records according +** to an ORDER BY clause, all fields required by the caller are present in the +** sorted records. However, if SQLite determines based on the declared type +** of a table column that its values are likely to be very large - larger +** than the configured sorter-reference size threshold - then a reference +** is stored in each sorted record and the required column values loaded +** from the database as records are returned in sorted order. The default +** value for this option is to never use this optimization. Specifying a +** negative value for this option restores the default behavior. +** This option is only available if SQLite is compiled with the +** [SQLITE_ENABLE_SORTER_REFERENCES] compile-time option. +** +** [[SQLITE_CONFIG_MEMDB_MAXSIZE]] +**
    SQLITE_CONFIG_MEMDB_MAXSIZE +**
    The SQLITE_CONFIG_MEMDB_MAXSIZE option accepts a single parameter +** [sqlite3_int64] parameter which is the default maximum size for an in-memory +** database created using [sqlite3_deserialize()]. This default maximum +** size can be adjusted up or down for individual databases using the +** [SQLITE_FCNTL_SIZE_LIMIT] [sqlite3_file_control|file-control]. If this +** configuration setting is never used, then the default maximum is determined +** by the [SQLITE_MEMDB_DEFAULT_MAXSIZE] compile-time option. If that +** compile-time option is not set, then the default maximum is 1073741824. +** +** [[SQLITE_CONFIG_ROWID_IN_VIEW]] +**
    SQLITE_CONFIG_ROWID_IN_VIEW +**
    The SQLITE_CONFIG_ROWID_IN_VIEW option enables or disables the ability +** for VIEWs to have a ROWID. The capability can only be enabled if SQLite is +** compiled with -DSQLITE_ALLOW_ROWID_IN_VIEW, in which case the capability +** defaults to on. This configuration option queries the current setting or +** changes the setting to off or on. The argument is a pointer to an integer. +** If that integer initially holds a value of 1, then the ability for VIEWs to +** have ROWIDs is activated. If the integer initially holds zero, then the +** ability is deactivated. Any other initial value for the integer leaves the +** setting unchanged. After changes, if any, the integer is written with +** a 1 or 0, if the ability for VIEWs to have ROWIDs is on or off. If SQLite +** is compiled without -DSQLITE_ALLOW_ROWID_IN_VIEW (which is the usual and +** recommended case) then the integer is always filled with zero, regardless +** if its initial value. +**
    +*/ +#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ +#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ +#define SQLITE_CONFIG_SERIALIZED 3 /* nil */ +#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ +#define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */ +#define SQLITE_CONFIG_SCRATCH 6 /* No longer used */ +#define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */ +#define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */ +#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ +#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */ +#define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */ +/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ +#define SQLITE_CONFIG_LOOKASIDE 13 /* int int */ +#define SQLITE_CONFIG_PCACHE 14 /* no-op */ +#define SQLITE_CONFIG_GETPCACHE 15 /* no-op */ +#define SQLITE_CONFIG_LOG 16 /* xFunc, void* */ +#define SQLITE_CONFIG_URI 17 /* int */ +#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */ +#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */ +#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */ +#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */ +#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */ +#define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */ +#define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */ +#define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */ +#define SQLITE_CONFIG_STMTJRNL_SPILL 26 /* int nByte */ +#define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */ +#define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */ +#define SQLITE_CONFIG_MEMDB_MAXSIZE 29 /* sqlite3_int64 */ +#define SQLITE_CONFIG_ROWID_IN_VIEW 30 /* int* */ + +/* +** CAPI3REF: Database Connection Configuration Options +** +** These constants are the available integer configuration options that +** can be passed as the second parameter to the [sqlite3_db_config()] interface. +** +** The [sqlite3_db_config()] interface is a var-args function. It takes a +** variable number of parameters, though always at least two. The number of +** parameters passed into sqlite3_db_config() depends on which of these +** constants is given as the second parameter. This documentation page +** refers to parameters beyond the second as "arguments". Thus, when this +** page says "the N-th argument" it means "the N-th parameter past the +** configuration option" or "the (N+2)-th parameter to sqlite3_db_config()". +** +** New configuration options may be added in future releases of SQLite. +** Existing configuration options might be discontinued. Applications +** should check the return code from [sqlite3_db_config()] to make sure that +** the call worked. ^The [sqlite3_db_config()] interface will return a +** non-zero [error code] if a discontinued or unsupported configuration option +** is invoked. +** +**
    +** [[SQLITE_DBCONFIG_LOOKASIDE]] +**
    SQLITE_DBCONFIG_LOOKASIDE
    +**
    The SQLITE_DBCONFIG_LOOKASIDE option is used to adjust the +** configuration of the [lookaside memory allocator] within a database +** connection. +** The arguments to the SQLITE_DBCONFIG_LOOKASIDE option are not +** in the [DBCONFIG arguments|usual format]. +** The SQLITE_DBCONFIG_LOOKASIDE option takes three arguments, not two, +** so that a call to [sqlite3_db_config()] that uses SQLITE_DBCONFIG_LOOKASIDE +** should have a total of five parameters. +**
      +**
    1. The first argument ("buf") is a +** pointer to a memory buffer to use for lookaside memory. +** The first argument may be NULL in which case SQLite will allocate the +** lookaside buffer itself using [sqlite3_malloc()]. +**

    2. The second argument ("sz") is the +** size of each lookaside buffer slot. Lookaside is disabled if "sz" +** is less than 8. The "sz" argument should be a multiple of 8 less than +** 65536. If "sz" does not meet this constraint, it is reduced in size until +** it does. +**

    3. The third argument ("cnt") is the number of slots. +** Lookaside is disabled if "cnt"is less than 1. +* The "cnt" value will be reduced, if necessary, so +** that the product of "sz" and "cnt" does not exceed 2,147,418,112. The "cnt" +** parameter is usually chosen so that the product of "sz" and "cnt" is less +** than 1,000,000. +**

    +**

    If the "buf" argument is not NULL, then it must +** point to a memory buffer with a size that is greater than +** or equal to the product of "sz" and "cnt". +** The buffer must be aligned to an 8-byte boundary. +** The lookaside memory +** configuration for a database connection can only be changed when that +** connection is not currently using lookaside memory, or in other words +** when the value returned by [SQLITE_DBSTATUS_LOOKASIDE_USED] is zero. +** Any attempt to change the lookaside memory configuration when lookaside +** memory is in use leaves the configuration unchanged and returns +** [SQLITE_BUSY]. +** If the "buf" argument is NULL and an attempt +** to allocate memory based on "sz" and "cnt" fails, then +** lookaside is silently disabled. +**

    +** The [SQLITE_CONFIG_LOOKASIDE] configuration option can be used to set the +** default lookaside configuration at initialization. The +** [-DSQLITE_DEFAULT_LOOKASIDE] option can be used to set the default lookaside +** configuration at compile-time. Typical values for lookaside are 1200 for +** "sz" and 40 to 100 for "cnt". +**

    +** +** [[SQLITE_DBCONFIG_ENABLE_FKEY]] +**
    SQLITE_DBCONFIG_ENABLE_FKEY
    +**
    ^This option is used to enable or disable the enforcement of +** [foreign key constraints]. This is the same setting that is +** enabled or disabled by the [PRAGMA foreign_keys] statement. +** The first argument is an integer which is 0 to disable FK enforcement, +** positive to enable FK enforcement or negative to leave FK enforcement +** unchanged. The second parameter is a pointer to an integer into which +** is written 0 or 1 to indicate whether FK enforcement is off or on +** following this call. The second parameter may be a NULL pointer, in +** which case the FK enforcement setting is not reported back.
    +** +** [[SQLITE_DBCONFIG_ENABLE_TRIGGER]] +**
    SQLITE_DBCONFIG_ENABLE_TRIGGER
    +**
    ^This option is used to enable or disable [CREATE TRIGGER | triggers]. +** There should be two additional arguments. +** The first argument is an integer which is 0 to disable triggers, +** positive to enable triggers or negative to leave the setting unchanged. +** The second parameter is a pointer to an integer into which +** is written 0 or 1 to indicate whether triggers are disabled or enabled +** following this call. The second parameter may be a NULL pointer, in +** which case the trigger setting is not reported back. +** +**

    Originally this option disabled all triggers. ^(However, since +** SQLite version 3.35.0, TEMP triggers are still allowed even if +** this option is off. So, in other words, this option now only disables +** triggers in the main database schema or in the schemas of [ATTACH]-ed +** databases.)^

    +** +** [[SQLITE_DBCONFIG_ENABLE_VIEW]] +**
    SQLITE_DBCONFIG_ENABLE_VIEW
    +**
    ^This option is used to enable or disable [CREATE VIEW | views]. +** There must be two additional arguments. +** The first argument is an integer which is 0 to disable views, +** positive to enable views or negative to leave the setting unchanged. +** The second parameter is a pointer to an integer into which +** is written 0 or 1 to indicate whether views are disabled or enabled +** following this call. The second parameter may be a NULL pointer, in +** which case the view setting is not reported back. +** +**

    Originally this option disabled all views. ^(However, since +** SQLite version 3.35.0, TEMP views are still allowed even if +** this option is off. So, in other words, this option now only disables +** views in the main database schema or in the schemas of ATTACH-ed +** databases.)^

    +** +** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]] +**
    SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER
    +**
    ^This option is used to enable or disable using the +** [fts3_tokenizer()] function - part of the [FTS3] full-text search engine +** extension - without using bound parameters as the parameters. Doing so +** is disabled by default. There must be two additional arguments. The first +** argument is an integer. If it is passed 0, then using fts3_tokenizer() +** without bound parameters is disabled. If it is passed a positive value, +** then calling fts3_tokenizer without bound parameters is enabled. If it +** is passed a negative value, this setting is not modified - this can be +** used to query for the current setting. The second parameter is a pointer +** to an integer into which is written 0 or 1 to indicate the current value +** of this setting (after it is modified, if applicable). The second +** parameter may be a NULL pointer, in which case the value of the setting +** is not reported back. Refer to [FTS3] documentation for further details. +**
    +** +** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]] +**
    SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION
    +**
    ^This option is used to enable or disable the [sqlite3_load_extension()] +** interface independently of the [load_extension()] SQL function. +** The [sqlite3_enable_load_extension()] API enables or disables both the +** C-API [sqlite3_load_extension()] and the SQL function [load_extension()]. +** There must be two additional arguments. +** When the first argument to this interface is 1, then only the C-API is +** enabled and the SQL function remains disabled. If the first argument to +** this interface is 0, then both the C-API and the SQL function are disabled. +** If the first argument is -1, then no changes are made to the state of either +** the C-API or the SQL function. +** The second parameter is a pointer to an integer into which +** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface +** is disabled or enabled following this call. The second parameter may +** be a NULL pointer, in which case the new setting is not reported back. +**
    +** +** [[SQLITE_DBCONFIG_MAINDBNAME]]
    SQLITE_DBCONFIG_MAINDBNAME
    +**
    ^This option is used to change the name of the "main" database +** schema. This option does not follow the +** [DBCONFIG arguments|usual SQLITE_DBCONFIG argument format]. +** This option takes exactly one additional argument so that the +** [sqlite3_db_config()] call has a total of three parameters. The +** extra argument must be a pointer to a constant UTF8 string which +** will become the new schema name in place of "main". ^SQLite does +** not make a copy of the new main schema name string, so the application +** must ensure that the argument passed into SQLITE_DBCONFIG MAINDBNAME +** is unchanged until after the database connection closes. +**
    +** +** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]] +**
    SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE
    +**
    Usually, when a database in [WAL mode] is closed or detached from a +** database handle, SQLite checks if if there are other connections to the +** same database, and if there are no other database connection (if the +** connection being closed is the last open connection to the database), +** then SQLite performs a [checkpoint] before closing the connection and +** deletes the WAL file. The SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE option can +** be used to override that behavior. The first argument passed to this +** operation (the third parameter to [sqlite3_db_config()]) is an integer +** which is positive to disable checkpoints-on-close, or zero (the default) +** to enable them, and negative to leave the setting unchanged. +** The second argument (the fourth parameter) is a pointer to an integer +** into which is written 0 or 1 to indicate whether checkpoints-on-close +** have been disabled - 0 if they are not disabled, 1 if they are. +**
    +** +** [[SQLITE_DBCONFIG_ENABLE_QPSG]]
    SQLITE_DBCONFIG_ENABLE_QPSG
    +**
    ^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates +** the [query planner stability guarantee] (QPSG). When the QPSG is active, +** a single SQL query statement will always use the same algorithm regardless +** of values of [bound parameters].)^ The QPSG disables some query optimizations +** that look at the values of bound parameters, which can make some queries +** slower. But the QPSG has the advantage of more predictable behavior. With +** the QPSG active, SQLite will always use the same query plan in the field as +** was used during testing in the lab. +** The first argument to this setting is an integer which is 0 to disable +** the QPSG, positive to enable QPSG, or negative to leave the setting +** unchanged. The second parameter is a pointer to an integer into which +** is written 0 or 1 to indicate whether the QPSG is disabled or enabled +** following this call. +**
    +** +** [[SQLITE_DBCONFIG_TRIGGER_EQP]]
    SQLITE_DBCONFIG_TRIGGER_EQP
    +**
    By default, the output of EXPLAIN QUERY PLAN commands does not +** include output for any operations performed by trigger programs. This +** option is used to set or clear (the default) a flag that governs this +** behavior. The first parameter passed to this operation is an integer - +** positive to enable output for trigger programs, or zero to disable it, +** or negative to leave the setting unchanged. +** The second parameter is a pointer to an integer into which is written +** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if +** it is not disabled, 1 if it is. +**
    +** +** [[SQLITE_DBCONFIG_RESET_DATABASE]]
    SQLITE_DBCONFIG_RESET_DATABASE
    +**
    Set the SQLITE_DBCONFIG_RESET_DATABASE flag and then run +** [VACUUM] in order to reset a database back to an empty database +** with no schema and no content. The following process works even for +** a badly corrupted database file: +**
      +**
    1. If the database connection is newly opened, make sure it has read the +** database schema by preparing then discarding some query against the +** database, or calling sqlite3_table_column_metadata(), ignoring any +** errors. This step is only necessary if the application desires to keep +** the database in WAL mode after the reset if it was in WAL mode before +** the reset. +**
    2. sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0); +**
    3. [sqlite3_exec](db, "[VACUUM]", 0, 0, 0); +**
    4. sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0); +**
    +** Because resetting a database is destructive and irreversible, the +** process requires the use of this obscure API and multiple steps to +** help ensure that it does not happen by accident. Because this +** feature must be capable of resetting corrupt databases, and +** shutting down virtual tables may require access to that corrupt +** storage, the library must abandon any installed virtual tables +** without calling their xDestroy() methods. +** +** [[SQLITE_DBCONFIG_DEFENSIVE]]
    SQLITE_DBCONFIG_DEFENSIVE
    +**
    The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the +** "defensive" flag for a database connection. When the defensive +** flag is enabled, language features that allow ordinary SQL to +** deliberately corrupt the database file are disabled. The disabled +** features include but are not limited to the following: +**
      +**
    • The [PRAGMA writable_schema=ON] statement. +**
    • The [PRAGMA journal_mode=OFF] statement. +**
    • The [PRAGMA schema_version=N] statement. +**
    • Writes to the [sqlite_dbpage] virtual table. +**
    • Direct writes to [shadow tables]. +**
    +**
    +** +** [[SQLITE_DBCONFIG_WRITABLE_SCHEMA]]
    SQLITE_DBCONFIG_WRITABLE_SCHEMA
    +**
    The SQLITE_DBCONFIG_WRITABLE_SCHEMA option activates or deactivates the +** "writable_schema" flag. This has the same effect and is logically equivalent +** to setting [PRAGMA writable_schema=ON] or [PRAGMA writable_schema=OFF]. +** The first argument to this setting is an integer which is 0 to disable +** the writable_schema, positive to enable writable_schema, or negative to +** leave the setting unchanged. The second parameter is a pointer to an +** integer into which is written 0 or 1 to indicate whether the writable_schema +** is enabled or disabled following this call. +**
    +** +** [[SQLITE_DBCONFIG_LEGACY_ALTER_TABLE]] +**
    SQLITE_DBCONFIG_LEGACY_ALTER_TABLE
    +**
    The SQLITE_DBCONFIG_LEGACY_ALTER_TABLE option activates or deactivates +** the legacy behavior of the [ALTER TABLE RENAME] command such that it +** behaves as it did prior to [version 3.24.0] (2018-06-04). See the +** "Compatibility Notice" on the [ALTER TABLE RENAME documentation] for +** additional information. This feature can also be turned on and off +** using the [PRAGMA legacy_alter_table] statement. +**
    +** +** [[SQLITE_DBCONFIG_DQS_DML]] +**
    SQLITE_DBCONFIG_DQS_DML
    +**
    The SQLITE_DBCONFIG_DQS_DML option activates or deactivates +** the legacy [double-quoted string literal] misfeature for DML statements +** only, that is DELETE, INSERT, SELECT, and UPDATE statements. The +** default value of this setting is determined by the [-DSQLITE_DQS] +** compile-time option. +**
    +** +** [[SQLITE_DBCONFIG_DQS_DDL]] +**
    SQLITE_DBCONFIG_DQS_DDL
    +**
    The SQLITE_DBCONFIG_DQS option activates or deactivates +** the legacy [double-quoted string literal] misfeature for DDL statements, +** such as CREATE TABLE and CREATE INDEX. The +** default value of this setting is determined by the [-DSQLITE_DQS] +** compile-time option. +**
    +** +** [[SQLITE_DBCONFIG_TRUSTED_SCHEMA]] +**
    SQLITE_DBCONFIG_TRUSTED_SCHEMA
    +**
    The SQLITE_DBCONFIG_TRUSTED_SCHEMA option tells SQLite to +** assume that database schemas are untainted by malicious content. +** When the SQLITE_DBCONFIG_TRUSTED_SCHEMA option is disabled, SQLite +** takes additional defensive steps to protect the application from harm +** including: +**
      +**
    • Prohibit the use of SQL functions inside triggers, views, +** CHECK constraints, DEFAULT clauses, expression indexes, +** partial indexes, or generated columns +** unless those functions are tagged with [SQLITE_INNOCUOUS]. +**
    • Prohibit the use of virtual tables inside of triggers or views +** unless those virtual tables are tagged with [SQLITE_VTAB_INNOCUOUS]. +**
    +** This setting defaults to "on" for legacy compatibility, however +** all applications are advised to turn it off if possible. This setting +** can also be controlled using the [PRAGMA trusted_schema] statement. +**
    +** +** [[SQLITE_DBCONFIG_LEGACY_FILE_FORMAT]] +**
    SQLITE_DBCONFIG_LEGACY_FILE_FORMAT
    +**
    The SQLITE_DBCONFIG_LEGACY_FILE_FORMAT option activates or deactivates +** the legacy file format flag. When activated, this flag causes all newly +** created database files to have a schema format version number (the 4-byte +** integer found at offset 44 into the database header) of 1. This in turn +** means that the resulting database file will be readable and writable by +** any SQLite version back to 3.0.0 ([dateof:3.0.0]). Without this setting, +** newly created databases are generally not understandable by SQLite versions +** prior to 3.3.0 ([dateof:3.3.0]). As these words are written, there +** is now scarcely any need to generate database files that are compatible +** all the way back to version 3.0.0, and so this setting is of little +** practical use, but is provided so that SQLite can continue to claim the +** ability to generate new database files that are compatible with version +** 3.0.0. +**

    Note that when the SQLITE_DBCONFIG_LEGACY_FILE_FORMAT setting is on, +** the [VACUUM] command will fail with an obscure error when attempting to +** process a table with generated columns and a descending index. This is +** not considered a bug since SQLite versions 3.3.0 and earlier do not support +** either generated columns or descending indexes. +**

    +** +** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]] +**
    SQLITE_DBCONFIG_STMT_SCANSTATUS
    +**
    The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in +** [SQLITE_ENABLE_STMT_SCANSTATUS] builds. In this case, it sets or clears +** a flag that enables collection of run-time performance statistics +** used by [sqlite3_stmt_scanstatus_v2()] and the [nexec and ncycle] +** columns of the [bytecode virtual table]. +** For statistics to be collected, the flag must be set on +** the database handle both when the SQL statement is +** [sqlite3_prepare|prepared] and when it is [sqlite3_step|stepped]. +** The flag is set (collection of statistics is enabled) by default. +**

    This option takes two arguments: an integer and a pointer to +** an integer. The first argument is 1, 0, or -1 to enable, disable, or +** leave unchanged the statement scanstatus option. If the second argument +** is not NULL, then the value of the statement scanstatus setting after +** processing the first argument is written into the integer that the second +** argument points to. +**

    +** +** [[SQLITE_DBCONFIG_REVERSE_SCANORDER]] +**
    SQLITE_DBCONFIG_REVERSE_SCANORDER
    +**
    The SQLITE_DBCONFIG_REVERSE_SCANORDER option changes the default order +** in which tables and indexes are scanned so that the scans start at the end +** and work toward the beginning rather than starting at the beginning and +** working toward the end. Setting SQLITE_DBCONFIG_REVERSE_SCANORDER is the +** same as setting [PRAGMA reverse_unordered_selects].

    This option takes +** two arguments which are an integer and a pointer to an integer. The first +** argument is 1, 0, or -1 to enable, disable, or leave unchanged the +** reverse scan order flag, respectively. If the second argument is not NULL, +** then 0 or 1 is written into the integer that the second argument points to +** depending on if the reverse scan order flag is set after processing the +** first argument. +**

    +** +** [[SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE]] +**
    SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE
    +**
    The SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE option enables or disables +** the ability of the [ATTACH DATABASE] SQL command to create a new database +** file if the database filed named in the ATTACH command does not already +** exist. This ability of ATTACH to create a new database is enabled by +** default. Applications can disable or reenable the ability for ATTACH to +** create new database files using this DBCONFIG option.

    +** This option takes two arguments which are an integer and a pointer +** to an integer. The first argument is 1, 0, or -1 to enable, disable, or +** leave unchanged the attach-create flag, respectively. If the second +** argument is not NULL, then 0 or 1 is written into the integer that the +** second argument points to depending on if the attach-create flag is set +** after processing the first argument. +**

    +** +** [[SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE]] +**
    SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE
    +**
    The SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE option enables or disables the +** ability of the [ATTACH DATABASE] SQL command to open a database for writing. +** This capability is enabled by default. Applications can disable or +** reenable this capability using the current DBCONFIG option. If +** this capability is disabled, the [ATTACH] command will still work, +** but the database will be opened read-only. If this option is disabled, +** then the ability to create a new database using [ATTACH] is also disabled, +** regardless of the value of the [SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE] +** option.

    +** This option takes two arguments which are an integer and a pointer +** to an integer. The first argument is 1, 0, or -1 to enable, disable, or +** leave unchanged the ability to ATTACH another database for writing, +** respectively. If the second argument is not NULL, then 0 or 1 is written +** into the integer to which the second argument points, depending on whether +** the ability to ATTACH a read/write database is enabled or disabled +** after processing the first argument. +**

    +** +** [[SQLITE_DBCONFIG_ENABLE_COMMENTS]] +**
    SQLITE_DBCONFIG_ENABLE_COMMENTS
    +**
    The SQLITE_DBCONFIG_ENABLE_COMMENTS option enables or disables the +** ability to include comments in SQL text. Comments are enabled by default. +** An application can disable or reenable comments in SQL text using this +** DBCONFIG option.

    +** This option takes two arguments which are an integer and a pointer +** to an integer. The first argument is 1, 0, or -1 to enable, disable, or +** leave unchanged the ability to use comments in SQL text, +** respectively. If the second argument is not NULL, then 0 or 1 is written +** into the integer that the second argument points to depending on if +** comments are allowed in SQL text after processing the first argument. +**

    +** +** [[SQLITE_DBCONFIG_FP_DIGITS]] +**
    SQLITE_DBCONFIG_FP_DIGITS
    +**
    The SQLITE_DBCONFIG_FP_DIGITS setting is a small integer that determines +** the number of significant digits that SQLite will attempt to preserve when +** converting floating point numbers (IEEE 754 "doubles") into text. The +** default value 17, as of SQLite version 3.52.0. The value was 15 in all +** prior versions.

    +** This option takes two arguments which are an integer and a pointer +** to an integer. The first argument is a small integer, between 3 and 23, or +** zero. The FP_DIGITS setting is changed to that small integer, or left +** unaltered if the first argument is zero or out of range. The second argument +** is a pointer to an integer. If the pointer is not NULL, then the value of +** the FP_DIGITS setting, after possibly being modified by the first +** arguments, is written into the integer to which the second argument points. +**

    +** +**
    +** +** [[DBCONFIG arguments]]

    Arguments To SQLITE_DBCONFIG Options

    +** +**

    Most of the SQLITE_DBCONFIG options take two arguments, so that the +** overall call to [sqlite3_db_config()] has a total of four parameters. +** The first argument (the third parameter to sqlite3_db_config()) is +** an integer. +** The second argument is a pointer to an integer. If the first argument is 1, +** then the option becomes enabled. If the first integer argument is 0, +** then the option is disabled. +** If the first argument is -1, then the option setting +** is unchanged. The second argument, the pointer to an integer, may be NULL. +** If the second argument is not NULL, then a value of 0 or 1 is written into +** the integer to which the second argument points, depending on whether the +** setting is disabled or enabled after applying any changes specified by +** the first argument. +** +**

    While most SQLITE_DBCONFIG options use the argument format +** described in the previous paragraph, the [SQLITE_DBCONFIG_MAINDBNAME], +** [SQLITE_DBCONFIG_LOOKASIDE], and [SQLITE_DBCONFIG_FP_DIGITS] options +** are different. See the documentation of those exceptional options for +** details. +*/ +#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ +#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ +#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ +#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ +#define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */ +#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */ +#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */ +#define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */ +#define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */ +#define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */ +#define SQLITE_DBCONFIG_DEFENSIVE 1010 /* int int* */ +#define SQLITE_DBCONFIG_WRITABLE_SCHEMA 1011 /* int int* */ +#define SQLITE_DBCONFIG_LEGACY_ALTER_TABLE 1012 /* int int* */ +#define SQLITE_DBCONFIG_DQS_DML 1013 /* int int* */ +#define SQLITE_DBCONFIG_DQS_DDL 1014 /* int int* */ +#define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */ +#define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT 1016 /* int int* */ +#define SQLITE_DBCONFIG_TRUSTED_SCHEMA 1017 /* int int* */ +#define SQLITE_DBCONFIG_STMT_SCANSTATUS 1018 /* int int* */ +#define SQLITE_DBCONFIG_REVERSE_SCANORDER 1019 /* int int* */ +#define SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE 1020 /* int int* */ +#define SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE 1021 /* int int* */ +#define SQLITE_DBCONFIG_ENABLE_COMMENTS 1022 /* int int* */ +#define SQLITE_DBCONFIG_FP_DIGITS 1023 /* int int* */ +#define SQLITE_DBCONFIG_MAX 1023 /* Largest DBCONFIG */ + +/* +** CAPI3REF: Enable Or Disable Extended Result Codes +** METHOD: sqlite3 +** +** ^The sqlite3_extended_result_codes() routine enables or disables the +** [extended result codes] feature of SQLite. ^The extended result +** codes are disabled by default for historical compatibility. +*/ +SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff); + +/* +** CAPI3REF: Last Insert Rowid +** METHOD: sqlite3 +** +** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables) +** has a unique 64-bit signed +** integer key called the [ROWID | "rowid"]. ^The rowid is always available +** as an undeclared column named ROWID, OID, or _ROWID_ as long as those +** names are not also used by explicitly declared columns. ^If +** the table has a column of type [INTEGER PRIMARY KEY] then that column +** is another alias for the rowid. +** +** ^The sqlite3_last_insert_rowid(D) interface usually returns the [rowid] of +** the most recent successful [INSERT] into a rowid table or [virtual table] +** on database connection D. ^Inserts into [WITHOUT ROWID] tables are not +** recorded. ^If no successful [INSERT]s into rowid tables have ever occurred +** on the database connection D, then sqlite3_last_insert_rowid(D) returns +** zero. +** +** As well as being set automatically as rows are inserted into database +** tables, the value returned by this function may be set explicitly by +** [sqlite3_set_last_insert_rowid()] +** +** Some virtual table implementations may INSERT rows into rowid tables as +** part of committing a transaction (e.g. to flush data accumulated in memory +** to disk). In this case subsequent calls to this function return the rowid +** associated with these internal INSERT operations, which leads to +** unintuitive results. Virtual table implementations that do write to rowid +** tables in this way can avoid this problem by restoring the original +** rowid value using [sqlite3_set_last_insert_rowid()] before returning +** control to the user. +** +** ^(If an [INSERT] occurs within a trigger then this routine will +** return the [rowid] of the inserted row as long as the trigger is +** running. Once the trigger program ends, the value returned +** by this routine reverts to what it was before the trigger was fired.)^ +** +** ^An [INSERT] that fails due to a constraint violation is not a +** successful [INSERT] and does not change the value returned by this +** routine. ^Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK, +** and INSERT OR ABORT make no changes to the return value of this +** routine when their insertion fails. ^(When INSERT OR REPLACE +** encounters a constraint violation, it does not fail. The +** INSERT continues to completion after deleting rows that caused +** the constraint problem so INSERT OR REPLACE will always change +** the return value of this interface.)^ +** +** ^For the purposes of this routine, an [INSERT] is considered to +** be successful even if it is subsequently rolled back. +** +** This function is accessible to SQL statements via the +** [last_insert_rowid() SQL function]. +** +** If a separate thread performs a new [INSERT] on the same +** database connection while the [sqlite3_last_insert_rowid()] +** function is running and thus changes the last insert [rowid], +** then the value returned by [sqlite3_last_insert_rowid()] is +** unpredictable and might not equal either the old or the new +** last insert [rowid]. +*/ +SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); + +/* +** CAPI3REF: Set the Last Insert Rowid value. +** METHOD: sqlite3 +** +** The sqlite3_set_last_insert_rowid(D, R) method allows the application to +** set the value returned by calling sqlite3_last_insert_rowid(D) to R +** without inserting a row into the database. +*/ +SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64); + +/* +** CAPI3REF: Count The Number Of Rows Modified +** METHOD: sqlite3 +** +** ^These functions return the number of rows modified, inserted or +** deleted by the most recently completed INSERT, UPDATE or DELETE +** statement on the database connection specified by the only parameter. +** The two functions are identical except for the type of the return value +** and that if the number of rows modified by the most recent INSERT, UPDATE, +** or DELETE is greater than the maximum value supported by type "int", then +** the return value of sqlite3_changes() is undefined. ^Executing any other +** type of SQL statement does not modify the value returned by these functions. +** For the purposes of this interface, a CREATE TABLE AS SELECT statement +** does not count as an INSERT, UPDATE or DELETE statement and hence the rows +** added to the new table by the CREATE TABLE AS SELECT statement are not +** counted. +** +** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are +** considered - auxiliary changes caused by [CREATE TRIGGER | triggers], +** [foreign key actions] or [REPLACE] constraint resolution are not counted. +** +** Changes to a view that are intercepted by +** [INSTEAD OF trigger | INSTEAD OF triggers] are not counted. ^The value +** returned by sqlite3_changes() immediately after an INSERT, UPDATE or +** DELETE statement run on a view is always zero. Only changes made to real +** tables are counted. +** +** Things are more complicated if the sqlite3_changes() function is +** executed while a trigger program is running. This may happen if the +** program uses the [changes() SQL function], or if some other callback +** function invokes sqlite3_changes() directly. Essentially: +** +**

      +**
    • ^(Before entering a trigger program the value returned by +** sqlite3_changes() function is saved. After the trigger program +** has finished, the original value is restored.)^ +** +**
    • ^(Within a trigger program each INSERT, UPDATE and DELETE +** statement sets the value returned by sqlite3_changes() +** upon completion as normal. Of course, this value will not include +** any changes performed by sub-triggers, as the sqlite3_changes() +** value will be saved and restored after each sub-trigger has run.)^ +**
    +** +** ^This means that if the changes() SQL function (or similar) is used +** by the first INSERT, UPDATE or DELETE statement within a trigger, it +** returns the value as set when the calling statement began executing. +** ^If it is used by the second or subsequent such statement within a trigger +** program, the value returned reflects the number of rows modified by the +** previous INSERT, UPDATE or DELETE statement within the same trigger. +** +** If a separate thread makes changes on the same database connection +** while [sqlite3_changes()] is running then the value returned +** is unpredictable and not meaningful. +** +** See also: +**
      +**
    • the [sqlite3_total_changes()] interface +**
    • the [count_changes pragma] +**
    • the [changes() SQL function] +**
    • the [data_version pragma] +**
    +*/ +SQLITE_API int sqlite3_changes(sqlite3*); +SQLITE_API sqlite3_int64 sqlite3_changes64(sqlite3*); + +/* +** CAPI3REF: Total Number Of Rows Modified +** METHOD: sqlite3 +** +** ^These functions return the total number of rows inserted, modified or +** deleted by all [INSERT], [UPDATE] or [DELETE] statements completed +** since the database connection was opened, including those executed as +** part of trigger programs. The two functions are identical except for the +** type of the return value and that if the number of rows modified by the +** connection exceeds the maximum value supported by type "int", then +** the return value of sqlite3_total_changes() is undefined. ^Executing +** any other type of SQL statement does not affect the value returned by +** sqlite3_total_changes(). +** +** ^Changes made as part of [foreign key actions] are included in the +** count, but those made as part of REPLACE constraint resolution are +** not. ^Changes to a view that are intercepted by INSTEAD OF triggers +** are not counted. +** +** The [sqlite3_total_changes(D)] interface only reports the number +** of rows that changed due to SQL statement run against database +** connection D. Any changes by other database connections are ignored. +** To detect changes against a database file from other database +** connections use the [PRAGMA data_version] command or the +** [SQLITE_FCNTL_DATA_VERSION] [file control]. +** +** If a separate thread makes changes on the same database connection +** while [sqlite3_total_changes()] is running then the value +** returned is unpredictable and not meaningful. +** +** See also: +**
      +**
    • the [sqlite3_changes()] interface +**
    • the [count_changes pragma] +**
    • the [changes() SQL function] +**
    • the [data_version pragma] +**
    • the [SQLITE_FCNTL_DATA_VERSION] [file control] +**
    +*/ +SQLITE_API int sqlite3_total_changes(sqlite3*); +SQLITE_API sqlite3_int64 sqlite3_total_changes64(sqlite3*); + +/* +** CAPI3REF: Interrupt A Long-Running Query +** METHOD: sqlite3 +** +** ^This function causes any pending database operation to abort and +** return at its earliest opportunity. This routine is typically +** called in response to a user action such as pressing "Cancel" +** or Ctrl-C where the user wants a long query operation to halt +** immediately. +** +** ^It is safe to call this routine from a thread different from the +** thread that is currently running the database operation. But it +** is not safe to call this routine with a [database connection] that +** is closed or might close before sqlite3_interrupt() returns. +** +** ^If an SQL operation is very nearly finished at the time when +** sqlite3_interrupt() is called, then it might not have an opportunity +** to be interrupted and might continue to completion. +** +** ^An SQL operation that is interrupted will return [SQLITE_INTERRUPT]. +** ^If the interrupted SQL operation is an INSERT, UPDATE, or DELETE +** that is inside an explicit transaction, then the entire transaction +** will be rolled back automatically. +** +** ^The sqlite3_interrupt(D) call is in effect until all currently running +** SQL statements on [database connection] D complete. ^Any new SQL statements +** that are started after the sqlite3_interrupt() call and before the +** running statement count reaches zero are interrupted as if they had been +** running prior to the sqlite3_interrupt() call. ^New SQL statements +** that are started after the running statement count reaches zero are +** not effected by the sqlite3_interrupt(). +** ^A call to sqlite3_interrupt(D) that occurs when there are no running +** SQL statements is a no-op and has no effect on SQL statements +** that are started after the sqlite3_interrupt() call returns. +** +** ^The [sqlite3_is_interrupted(D)] interface can be used to determine whether +** or not an interrupt is currently in effect for [database connection] D. +** It returns 1 if an interrupt is currently in effect, or 0 otherwise. +*/ +SQLITE_API void sqlite3_interrupt(sqlite3*); +SQLITE_API int sqlite3_is_interrupted(sqlite3*); + +/* +** CAPI3REF: Determine If An SQL Statement Is Complete +** +** These routines are useful during command-line input to determine if the +** currently entered text seems to form a complete SQL statement or +** if additional input is needed before sending the text into +** SQLite for parsing. ^These routines return 1 if the input string +** appears to be a complete SQL statement. ^A statement is judged to be +** complete if it ends with a semicolon token and is not a prefix of a +** well-formed CREATE TRIGGER statement. ^Semicolons that are embedded within +** string literals or quoted identifier names or comments are not +** independent tokens (they are part of the token in which they are +** embedded) and thus do not count as a statement terminator. ^Whitespace +** and comments that follow the final semicolon are ignored. +** +** ^These routines return 0 if the statement is incomplete. ^If a +** memory allocation fails, then SQLITE_NOMEM is returned. +** +** ^These routines do not parse the SQL statements and thus +** will not detect syntactically incorrect SQL. +** +** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior +** to invoking sqlite3_complete16() then sqlite3_initialize() is invoked +** automatically by sqlite3_complete16(). If that initialization fails, +** then the return value from sqlite3_complete16() will be non-zero +** regardless of whether or not the input SQL is complete.)^ +** +** The input to [sqlite3_complete()] must be a zero-terminated +** UTF-8 string. +** +** The input to [sqlite3_complete16()] must be a zero-terminated +** UTF-16 string in native byte order. +*/ +SQLITE_API int sqlite3_complete(const char *sql); +SQLITE_API int sqlite3_complete16(const void *sql); + +/* +** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors +** KEYWORDS: {busy-handler callback} {busy handler} +** METHOD: sqlite3 +** +** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X +** that might be invoked with argument P whenever +** an attempt is made to access a database table associated with +** [database connection] D when another thread +** or process has the table locked. +** The sqlite3_busy_handler() interface is used to implement +** [sqlite3_busy_timeout()] and [PRAGMA busy_timeout]. +** +** ^If the busy callback is NULL, then [SQLITE_BUSY] +** is returned immediately upon encountering the lock. ^If the busy callback +** is not NULL, then the callback might be invoked with two arguments. +** +** ^The first argument to the busy handler is a copy of the void* pointer which +** is the third argument to sqlite3_busy_handler(). ^The second argument to +** the busy handler callback is the number of times that the busy handler has +** been invoked previously for the same locking event. ^If the +** busy callback returns 0, then no additional attempts are made to +** access the database and [SQLITE_BUSY] is returned +** to the application. +** ^If the callback returns non-zero, then another attempt +** is made to access the database and the cycle repeats. +** +** The presence of a busy handler does not guarantee that it will be invoked +** when there is lock contention. ^If SQLite determines that invoking the busy +** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY] +** to the application instead of invoking the +** busy handler. +** Consider a scenario where one process is holding a read lock that +** it is trying to promote to a reserved lock and +** a second process is holding a reserved lock that it is trying +** to promote to an exclusive lock. The first process cannot proceed +** because it is blocked by the second and the second process cannot +** proceed because it is blocked by the first. If both processes +** invoke the busy handlers, neither will make any progress. Therefore, +** SQLite returns [SQLITE_BUSY] for the first process, hoping that this +** will induce the first process to release its read lock and allow +** the second process to proceed. +** +** ^The default busy callback is NULL. +** +** ^(There can only be a single busy handler defined for each +** [database connection]. Setting a new busy handler clears any +** previously set handler.)^ ^Note that calling [sqlite3_busy_timeout()] +** or evaluating [PRAGMA busy_timeout=N] will change the +** busy handler and thus clear any previously set busy handler. +** +** The busy callback should not take any actions which modify the +** database connection that invoked the busy handler. In other words, +** the busy handler is not reentrant. Any such actions +** result in undefined behavior. +** +** A busy handler must not close the database connection +** or [prepared statement] that invoked the busy handler. +*/ +SQLITE_API int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*); + +/* +** CAPI3REF: Set A Busy Timeout +** METHOD: sqlite3 +** +** ^This routine sets a [sqlite3_busy_handler | busy handler] that sleeps +** for a specified amount of time when a table is locked. ^The handler +** will sleep multiple times until at least "ms" milliseconds of sleeping +** have accumulated. ^After at least "ms" milliseconds of sleeping, +** the handler returns 0 which causes [sqlite3_step()] to return +** [SQLITE_BUSY]. +** +** ^Calling this routine with an argument less than or equal to zero +** turns off all busy handlers. +** +** ^(There can only be a single busy handler for a particular +** [database connection] at any given moment. If another busy handler +** was defined (using [sqlite3_busy_handler()]) prior to calling +** this routine, that other busy handler is cleared.)^ +** +** See also: [PRAGMA busy_timeout] +*/ +SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); + +/* +** CAPI3REF: Set the Setlk Timeout +** METHOD: sqlite3 +** +** This routine is only useful in SQLITE_ENABLE_SETLK_TIMEOUT builds. If +** the VFS supports blocking locks, it sets the timeout in ms used by +** eligible locks taken on wal mode databases by the specified database +** handle. In non-SQLITE_ENABLE_SETLK_TIMEOUT builds, or if the VFS does +** not support blocking locks, this function is a no-op. +** +** Passing 0 to this function disables blocking locks altogether. Passing +** -1 to this function requests that the VFS blocks for a long time - +** indefinitely if possible. The results of passing any other negative value +** are undefined. +** +** Internally, each SQLite database handle stores two timeout values - the +** busy-timeout (used for rollback mode databases, or if the VFS does not +** support blocking locks) and the setlk-timeout (used for blocking locks +** on wal-mode databases). The sqlite3_busy_timeout() method sets both +** values, this function sets only the setlk-timeout value. Therefore, +** to configure separate busy-timeout and setlk-timeout values for a single +** database handle, call sqlite3_busy_timeout() followed by this function. +** +** Whenever the number of connections to a wal mode database falls from +** 1 to 0, the last connection takes an exclusive lock on the database, +** then checkpoints and deletes the wal file. While it is doing this, any +** new connection that tries to read from the database fails with an +** SQLITE_BUSY error. Or, if the SQLITE_SETLK_BLOCK_ON_CONNECT flag is +** passed to this API, the new connection blocks until the exclusive lock +** has been released. +*/ +SQLITE_API int sqlite3_setlk_timeout(sqlite3*, int ms, int flags); + +/* +** CAPI3REF: Flags for sqlite3_setlk_timeout() +*/ +#define SQLITE_SETLK_BLOCK_ON_CONNECT 0x01 + +/* +** CAPI3REF: Convenience Routines For Running Queries +** METHOD: sqlite3 +** +** This is a legacy interface that is preserved for backwards compatibility. +** Use of this interface is not recommended. +** +** Definition: A result table is a memory data structure created by the +** [sqlite3_get_table()] interface. A result table records the +** complete query results from one or more queries. +** +** The table conceptually has a number of rows and columns. But +** these numbers are not part of the result table itself. These +** numbers are obtained separately. Let N be the number of rows +** and M be the number of columns. +** +** A result table is an array of pointers to zero-terminated UTF-8 strings. +** There are (N+1)*M elements in the array. The first M pointers point +** to zero-terminated strings that contain the names of the columns. +** The remaining entries all point to query results. NULL values result +** in NULL pointers. All other values are in their UTF-8 zero-terminated +** string representation as returned by [sqlite3_column_text()]. +** +** A result table might consist of one or more memory allocations. +** It is not safe to pass a result table directly to [sqlite3_free()]. +** A result table should be deallocated using [sqlite3_free_table()]. +** +** ^(As an example of the result table format, suppose a query result +** is as follows: +** +**
    +**        Name        | Age
    +**        -----------------------
    +**        Alice       | 43
    +**        Bob         | 28
    +**        Cindy       | 21
    +** 
    +** +** There are two columns (M==2) and three rows (N==3). Thus the +** result table has 8 entries. Suppose the result table is stored +** in an array named azResult. Then azResult holds this content: +** +**
    +**        azResult[0] = "Name";
    +**        azResult[1] = "Age";
    +**        azResult[2] = "Alice";
    +**        azResult[3] = "43";
    +**        azResult[4] = "Bob";
    +**        azResult[5] = "28";
    +**        azResult[6] = "Cindy";
    +**        azResult[7] = "21";
    +** 
    )^ +** +** ^The sqlite3_get_table() function evaluates one or more +** semicolon-separated SQL statements in the zero-terminated UTF-8 +** string of its 2nd parameter and returns a result table to the +** pointer given in its 3rd parameter. +** +** After the application has finished with the result from sqlite3_get_table(), +** it must pass the result table pointer to sqlite3_free_table() in order to +** release the memory that was malloced. Because of the way the +** [sqlite3_malloc()] happens within sqlite3_get_table(), the calling +** function must not try to call [sqlite3_free()] directly. Only +** [sqlite3_free_table()] is able to release the memory properly and safely. +** +** The sqlite3_get_table() interface is implemented as a wrapper around +** [sqlite3_exec()]. The sqlite3_get_table() routine does not have access +** to any internal data structures of SQLite. It uses only the public +** interface defined here. As a consequence, errors that occur in the +** wrapper layer outside of the internal [sqlite3_exec()] call are not +** reflected in subsequent calls to [sqlite3_errcode()] or +** [sqlite3_errmsg()]. +*/ +SQLITE_API int sqlite3_get_table( + sqlite3 *db, /* An open database */ + const char *zSql, /* SQL to be evaluated */ + char ***pazResult, /* Results of the query */ + int *pnRow, /* Number of result rows written here */ + int *pnColumn, /* Number of result columns written here */ + char **pzErrmsg /* Error msg written here */ +); +SQLITE_API void sqlite3_free_table(char **result); + +/* +** CAPI3REF: Formatted String Printing Functions +** +** These routines are work-alikes of the "printf()" family of functions +** from the standard C library. +** These routines understand most of the common formatting options from +** the standard library printf() +** plus some additional non-standard formats ([%q], [%Q], [%w], and [%z]). +** See the [built-in printf()] documentation for details. +** +** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their +** results into memory obtained from [sqlite3_malloc64()]. +** The strings returned by these two routines should be +** released by [sqlite3_free()]. ^Both routines return a +** NULL pointer if [sqlite3_malloc64()] is unable to allocate enough +** memory to hold the resulting string. +** +** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from +** the standard C library. The result is written into the +** buffer supplied as the second parameter whose size is given by +** the first parameter. Note that the order of the +** first two parameters is reversed from snprintf().)^ This is an +** historical accident that cannot be fixed without breaking +** backwards compatibility. ^(Note also that sqlite3_snprintf() +** returns a pointer to its buffer instead of the number of +** characters actually written into the buffer.)^ We admit that +** the number of characters written would be a more useful return +** value but we cannot change the implementation of sqlite3_snprintf() +** now without breaking compatibility. +** +** ^As long as the buffer size is greater than zero, sqlite3_snprintf() +** guarantees that the buffer is always zero-terminated. ^The first +** parameter "n" is the total size of the buffer, including space for +** the zero terminator. So the longest string that can be completely +** written will be n-1 characters. +** +** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf(). +** +** See also: [built-in printf()], [printf() SQL function] +*/ +SQLITE_API char *sqlite3_mprintf(const char*,...); +SQLITE_API char *sqlite3_vmprintf(const char*, va_list); +SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...); +SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list); + +/* +** CAPI3REF: Memory Allocation Subsystem +** +** The SQLite core uses these three routines for all of its own +** internal memory allocation needs. "Core" in the previous sentence +** does not include operating-system specific [VFS] implementation. The +** Windows VFS uses native malloc() and free() for some operations. +** +** ^The sqlite3_malloc() routine returns a pointer to a block +** of memory at least N bytes in length, where N is the parameter. +** ^If sqlite3_malloc() is unable to obtain sufficient free +** memory, it returns a NULL pointer. ^If the parameter N to +** sqlite3_malloc() is zero or negative then sqlite3_malloc() returns +** a NULL pointer. +** +** ^The sqlite3_malloc64(N) routine works just like +** sqlite3_malloc(N) except that N is an unsigned 64-bit integer instead +** of a signed 32-bit integer. +** +** ^Calling sqlite3_free() with a pointer previously returned +** by sqlite3_malloc() or sqlite3_realloc() releases that memory so +** that it might be reused. ^The sqlite3_free() routine is +** a no-op if it is called with a NULL pointer. Passing a NULL pointer +** to sqlite3_free() is harmless. After being freed, memory +** should neither be read nor written. Even reading previously freed +** memory might result in a segmentation fault or other severe error. +** Memory corruption, a segmentation fault, or other severe error +** might result if sqlite3_free() is called with a non-NULL pointer that +** was not obtained from sqlite3_malloc() or sqlite3_realloc(). +** +** ^The sqlite3_realloc(X,N) interface attempts to resize a +** prior memory allocation X to be at least N bytes. +** ^If the X parameter to sqlite3_realloc(X,N) +** is a NULL pointer then its behavior is identical to calling +** sqlite3_malloc(N). +** ^If the N parameter to sqlite3_realloc(X,N) is zero or +** negative then the behavior is exactly the same as calling +** sqlite3_free(X). +** ^sqlite3_realloc(X,N) returns a pointer to a memory allocation +** of at least N bytes in size or NULL if insufficient memory is available. +** ^If M is the size of the prior allocation, then min(N,M) bytes of the +** prior allocation are copied into the beginning of the buffer returned +** by sqlite3_realloc(X,N) and the prior allocation is freed. +** ^If sqlite3_realloc(X,N) returns NULL and N is positive, then the +** prior allocation is not freed. +** +** ^The sqlite3_realloc64(X,N) interface works the same as +** sqlite3_realloc(X,N) except that N is a 64-bit unsigned integer instead +** of a 32-bit signed integer. +** +** ^If X is a memory allocation previously obtained from sqlite3_malloc(), +** sqlite3_malloc64(), sqlite3_realloc(), or sqlite3_realloc64(), then +** sqlite3_msize(X) returns the size of that memory allocation in bytes. +** ^The value returned by sqlite3_msize(X) might be larger than the number +** of bytes requested when X was allocated. ^If X is a NULL pointer then +** sqlite3_msize(X) returns zero. If X points to something that is not +** the beginning of memory allocation, or if it points to a formerly +** valid memory allocation that has now been freed, then the behavior +** of sqlite3_msize(X) is undefined and possibly harmful. +** +** ^The memory returned by sqlite3_malloc(), sqlite3_realloc(), +** sqlite3_malloc64(), and sqlite3_realloc64() +** is always aligned to at least an 8 byte boundary, or to a +** 4 byte boundary if the [SQLITE_4_BYTE_ALIGNED_MALLOC] compile-time +** option is used. +** +** The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()] +** must be either NULL or else pointers obtained from a prior +** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have +** not yet been released. +** +** The application must not read or write any part of +** a block of memory after it has been released using +** [sqlite3_free()] or [sqlite3_realloc()]. +*/ +SQLITE_API void *sqlite3_malloc(int); +SQLITE_API void *sqlite3_malloc64(sqlite3_uint64); +SQLITE_API void *sqlite3_realloc(void*, int); +SQLITE_API void *sqlite3_realloc64(void*, sqlite3_uint64); +SQLITE_API void sqlite3_free(void*); +SQLITE_API sqlite3_uint64 sqlite3_msize(void*); + +/* +** CAPI3REF: Memory Allocator Statistics +** +** SQLite provides these two interfaces for reporting on the status +** of the [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()] +** routines, which form the built-in memory allocation subsystem. +** +** ^The [sqlite3_memory_used()] routine returns the number of bytes +** of memory currently outstanding (malloced but not freed). +** ^The [sqlite3_memory_highwater()] routine returns the maximum +** value of [sqlite3_memory_used()] since the high-water mark +** was last reset. ^The values returned by [sqlite3_memory_used()] and +** [sqlite3_memory_highwater()] include any overhead +** added by SQLite in its implementation of [sqlite3_malloc()], +** but not overhead added by any underlying system library +** routines that [sqlite3_malloc()] may call. +** +** ^The memory high-water mark is reset to the current value of +** [sqlite3_memory_used()] if and only if the parameter to +** [sqlite3_memory_highwater()] is true. ^The value returned +** by [sqlite3_memory_highwater(1)] is the high-water mark +** prior to the reset. +*/ +SQLITE_API sqlite3_int64 sqlite3_memory_used(void); +SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag); + +/* +** CAPI3REF: Pseudo-Random Number Generator +** +** SQLite contains a high-quality pseudo-random number generator (PRNG) used to +** select random [ROWID | ROWIDs] when inserting new records into a table that +** already uses the largest possible [ROWID]. The PRNG is also used for +** the built-in random() and randomblob() SQL functions. This interface allows +** applications to access the same PRNG for other purposes. +** +** ^A call to this routine stores N bytes of randomness into buffer P. +** ^The P parameter can be a NULL pointer. +** +** ^If this routine has not been previously called or if the previous +** call had N less than one or a NULL pointer for P, then the PRNG is +** seeded using randomness obtained from the xRandomness method of +** the default [sqlite3_vfs] object. +** ^If the previous call to this routine had an N of 1 or more and a +** non-NULL P then the pseudo-randomness is generated +** internally and without recourse to the [sqlite3_vfs] xRandomness +** method. +*/ +SQLITE_API void sqlite3_randomness(int N, void *P); + +/* +** CAPI3REF: Compile-Time Authorization Callbacks +** METHOD: sqlite3 +** KEYWORDS: {authorizer callback} +** +** ^This routine registers an authorizer callback with a particular +** [database connection], supplied in the first argument. +** ^The authorizer callback is invoked as SQL statements are being compiled +** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], +** [sqlite3_prepare_v3()], [sqlite3_prepare16()], [sqlite3_prepare16_v2()], +** and [sqlite3_prepare16_v3()]. ^At various +** points during the compilation process, as logic is being created +** to perform various actions, the authorizer callback is invoked to +** see if those actions are allowed. ^The authorizer callback should +** return [SQLITE_OK] to allow the action, [SQLITE_IGNORE] to disallow the +** specific action but allow the SQL statement to continue to be +** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be +** rejected with an error. ^If the authorizer callback returns +** any value other than [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY] +** then the [sqlite3_prepare_v2()] or equivalent call that triggered +** the authorizer will fail with an error message. +** +** When the callback returns [SQLITE_OK], that means the operation +** requested is ok. ^When the callback returns [SQLITE_DENY], the +** [sqlite3_prepare_v2()] or equivalent call that triggered the +** authorizer will fail with an error message explaining that +** access is denied. +** +** ^The first parameter to the authorizer callback is a copy of the third +** parameter to the sqlite3_set_authorizer() interface. ^The second parameter +** to the callback is an integer [SQLITE_COPY | action code] that specifies +** the particular action to be authorized. ^The third through sixth parameters +** to the callback are either NULL pointers or zero-terminated strings +** that contain additional details about the action to be authorized. +** Applications must always be prepared to encounter a NULL pointer in any +** of the third through the sixth parameters of the authorization callback. +** +** ^If the action code is [SQLITE_READ] +** and the callback returns [SQLITE_IGNORE] then the +** [prepared statement] statement is constructed to substitute +** a NULL value in place of the table column that would have +** been read if [SQLITE_OK] had been returned. The [SQLITE_IGNORE] +** return can be used to deny an untrusted user access to individual +** columns of a table. +** ^When a table is referenced by a [SELECT] but no column values are +** extracted from that table (for example in a query like +** "SELECT count(*) FROM tab") then the [SQLITE_READ] authorizer callback +** is invoked once for that table with a column name that is an empty string. +** ^If the action code is [SQLITE_DELETE] and the callback returns +** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the +** [truncate optimization] is disabled and all rows are deleted individually. +** +** An authorizer is used when [sqlite3_prepare | preparing] +** SQL statements from an untrusted source, to ensure that the SQL statements +** do not try to access data they are not allowed to see, or that they do not +** try to execute malicious statements that damage the database. For +** example, an application may allow a user to enter arbitrary +** SQL queries for evaluation by a database. But the application does +** not want the user to be able to make arbitrary changes to the +** database. An authorizer could then be put in place while the +** user-entered SQL is being [sqlite3_prepare | prepared] that +** disallows everything except [SELECT] statements. +** +** Applications that need to process SQL from untrusted sources +** might also consider lowering resource limits using [sqlite3_limit()] +** and limiting database size using the [max_page_count] [PRAGMA] +** in addition to using an authorizer. +** +** ^(Only a single authorizer can be in place on a database connection +** at a time. Each call to sqlite3_set_authorizer overrides the +** previous call.)^ ^Disable the authorizer by installing a NULL callback. +** The authorizer is disabled by default. +** +** The authorizer callback must not do anything that will modify +** the database connection that invoked the authorizer callback. +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their +** database connections for the meaning of "modify" in this paragraph. +** +** ^When [sqlite3_prepare_v2()] is used to prepare a statement, the +** statement might be re-prepared during [sqlite3_step()] due to a +** schema change. Hence, the application should ensure that the +** correct authorizer callback remains in place during the [sqlite3_step()]. +** +** ^Note that the authorizer callback is invoked only during +** [sqlite3_prepare()] or its variants. Authorization is not +** performed during statement evaluation in [sqlite3_step()], unless +** as stated in the previous paragraph, sqlite3_step() invokes +** sqlite3_prepare_v2() to reprepare a statement after a schema change. +*/ +SQLITE_API int sqlite3_set_authorizer( + sqlite3*, + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), + void *pUserData +); + +/* +** CAPI3REF: Authorizer Return Codes +** +** The [sqlite3_set_authorizer | authorizer callback function] must +** return either [SQLITE_OK] or one of these two constants in order +** to signal SQLite whether or not the action is permitted. See the +** [sqlite3_set_authorizer | authorizer documentation] for additional +** information. +** +** Note that SQLITE_IGNORE is also used as a [conflict resolution mode] +** returned from the [sqlite3_vtab_on_conflict()] interface. +*/ +#define SQLITE_DENY 1 /* Abort the SQL statement with an error */ +#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */ + +/* +** CAPI3REF: Authorizer Action Codes +** +** The [sqlite3_set_authorizer()] interface registers a callback function +** that is invoked to authorize certain SQL statement actions. The +** second parameter to the callback is an integer code that specifies +** what action is being authorized. These are the integer action codes that +** the authorizer callback may be passed. +** +** These action code values signify what kind of operation is to be +** authorized. The 3rd and 4th parameters to the authorization +** callback function will be parameters or NULL depending on which of these +** codes is used as the second parameter. ^(The 5th parameter to the +** authorizer callback is the name of the database ("main", "temp", +** etc.) if applicable.)^ ^The 6th parameter to the authorizer callback +** is the name of the inner-most trigger or view that is responsible for +** the access attempt or NULL if this access attempt is directly from +** top-level SQL code. +*/ +/******************************************* 3rd ************ 4th ***********/ +#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */ +#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */ +#define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */ +#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */ +#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */ +#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */ +#define SQLITE_CREATE_VIEW 8 /* View Name NULL */ +#define SQLITE_DELETE 9 /* Table Name NULL */ +#define SQLITE_DROP_INDEX 10 /* Index Name Table Name */ +#define SQLITE_DROP_TABLE 11 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */ +#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */ +#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */ +#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */ +#define SQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */ +#define SQLITE_DROP_VIEW 17 /* View Name NULL */ +#define SQLITE_INSERT 18 /* Table Name NULL */ +#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */ +#define SQLITE_READ 20 /* Table Name Column Name */ +#define SQLITE_SELECT 21 /* NULL NULL */ +#define SQLITE_TRANSACTION 22 /* Operation NULL */ +#define SQLITE_UPDATE 23 /* Table Name Column Name */ +#define SQLITE_ATTACH 24 /* Filename NULL */ +#define SQLITE_DETACH 25 /* Database Name NULL */ +#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */ +#define SQLITE_REINDEX 27 /* Index Name NULL */ +#define SQLITE_ANALYZE 28 /* Table Name NULL */ +#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */ +#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */ +#define SQLITE_FUNCTION 31 /* NULL Function Name */ +#define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */ +#define SQLITE_COPY 0 /* No longer used */ +#define SQLITE_RECURSIVE 33 /* NULL NULL */ + +/* +** CAPI3REF: Deprecated Tracing And Profiling Functions +** DEPRECATED +** +** These routines are deprecated. Use the [sqlite3_trace_v2()] interface +** instead of the routines described here. +** +** These routines register callback functions that can be used for +** tracing and profiling the execution of SQL statements. +** +** ^The callback function registered by sqlite3_trace() is invoked at +** various times when an SQL statement is being run by [sqlite3_step()]. +** ^The sqlite3_trace() callback is invoked with a UTF-8 rendering of the +** SQL statement text as the statement first begins executing. +** ^(Additional sqlite3_trace() callbacks might occur +** as each triggered subprogram is entered. The callbacks for triggers +** contain a UTF-8 SQL comment that identifies the trigger.)^ +** +** The [SQLITE_TRACE_SIZE_LIMIT] compile-time option can be used to limit +** the length of [bound parameter] expansion in the output of sqlite3_trace(). +** +** ^The callback function registered by sqlite3_profile() is invoked +** as each SQL statement finishes. ^The profile callback contains +** the original statement text and an estimate of wall-clock time +** of how long that statement took to run. ^The profile callback +** time is in units of nanoseconds, however the current implementation +** is only capable of millisecond resolution so the six least significant +** digits in the time are meaningless. Future versions of SQLite +** might provide greater resolution on the profiler callback. Invoking +** either [sqlite3_trace()] or [sqlite3_trace_v2()] will cancel the +** profile callback. +*/ +SQLITE_API SQLITE_DEPRECATED void *sqlite3_trace(sqlite3*, + void(*xTrace)(void*,const char*), void*); +SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, + void(*xProfile)(void*,const char*,sqlite3_uint64), void*); + +/* +** CAPI3REF: SQL Trace Event Codes +** KEYWORDS: SQLITE_TRACE +** +** These constants identify classes of events that can be monitored +** using the [sqlite3_trace_v2()] tracing logic. The M argument +** to [sqlite3_trace_v2(D,M,X,P)] is an OR-ed combination of one or more of +** the following constants. ^The first argument to the trace callback +** is one of the following constants. +** +** New tracing constants may be added in future releases. +** +** ^A trace callback has four arguments: xCallback(T,C,P,X). +** ^The T argument is one of the integer type codes above. +** ^The C argument is a copy of the context pointer passed in as the +** fourth argument to [sqlite3_trace_v2()]. +** The P and X arguments are pointers whose meanings depend on T. +** +**
    +** [[SQLITE_TRACE_STMT]]
    SQLITE_TRACE_STMT
    +**
    ^An SQLITE_TRACE_STMT callback is invoked when a prepared statement +** first begins running and possibly at other times during the +** execution of the prepared statement, such as at the start of each +** trigger subprogram. ^The P argument is a pointer to the +** [prepared statement]. ^The X argument is a pointer to a string which +** is the unexpanded SQL text of the prepared statement or an SQL comment +** that indicates the invocation of a trigger. ^The callback can compute +** the same text that would have been returned by the legacy [sqlite3_trace()] +** interface by using the X argument when X begins with "--" and invoking +** [sqlite3_expanded_sql(P)] otherwise. +** +** [[SQLITE_TRACE_PROFILE]]
    SQLITE_TRACE_PROFILE
    +**
    ^An SQLITE_TRACE_PROFILE callback provides approximately the same +** information as is provided by the [sqlite3_profile()] callback. +** ^The P argument is a pointer to the [prepared statement] and the +** X argument points to a 64-bit integer which is approximately +** the number of nanoseconds that the prepared statement took to run. +** ^The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes. +** +** [[SQLITE_TRACE_ROW]]
    SQLITE_TRACE_ROW
    +**
    ^An SQLITE_TRACE_ROW callback is invoked whenever a prepared +** statement generates a single row of result. +** ^The P argument is a pointer to the [prepared statement] and the +** X argument is unused. +** +** [[SQLITE_TRACE_CLOSE]]
    SQLITE_TRACE_CLOSE
    +**
    ^An SQLITE_TRACE_CLOSE callback is invoked when a database +** connection closes. +** ^The P argument is a pointer to the [database connection] object +** and the X argument is unused. +**
    +*/ +#define SQLITE_TRACE_STMT 0x01 +#define SQLITE_TRACE_PROFILE 0x02 +#define SQLITE_TRACE_ROW 0x04 +#define SQLITE_TRACE_CLOSE 0x08 + +/* +** CAPI3REF: SQL Trace Hook +** METHOD: sqlite3 +** +** ^The sqlite3_trace_v2(D,M,X,P) interface registers a trace callback +** function X against [database connection] D, using property mask M +** and context pointer P. ^If the X callback is +** NULL or if the M mask is zero, then tracing is disabled. The +** M argument should be the bitwise OR-ed combination of +** zero or more [SQLITE_TRACE] constants. +** +** ^Each call to either sqlite3_trace(D,X,P) or sqlite3_trace_v2(D,M,X,P) +** overrides (cancels) all prior calls to sqlite3_trace(D,X,P) or +** sqlite3_trace_v2(D,M,X,P) for the [database connection] D. Each +** database connection may have at most one trace callback. +** +** ^The X callback is invoked whenever any of the events identified by +** mask M occur. ^The integer return value from the callback is currently +** ignored, though this may change in future releases. Callback +** implementations should return zero to ensure future compatibility. +** +** ^A trace callback is invoked with four arguments: callback(T,C,P,X). +** ^The T argument is one of the [SQLITE_TRACE] +** constants to indicate why the callback was invoked. +** ^The C argument is a copy of the context pointer. +** The P and X arguments are pointers whose meanings depend on T. +** +** The sqlite3_trace_v2() interface is intended to replace the legacy +** interfaces [sqlite3_trace()] and [sqlite3_profile()], both of which +** are deprecated. +*/ +SQLITE_API int sqlite3_trace_v2( + sqlite3*, + unsigned uMask, + int(*xCallback)(unsigned,void*,void*,void*), + void *pCtx +); + +/* +** CAPI3REF: Query Progress Callbacks +** METHOD: sqlite3 +** +** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback +** function X to be invoked periodically during long running calls to +** [sqlite3_step()] and [sqlite3_prepare()] and similar for +** database connection D. An example use for this +** interface is to keep a GUI updated during a large query. +** +** ^The parameter P is passed through as the only parameter to the +** callback function X. ^The parameter N is the approximate number of +** [virtual machine instructions] that are evaluated between successive +** invocations of the callback X. ^If N is less than one then the progress +** handler is disabled. +** +** ^Only a single progress handler may be defined at one time per +** [database connection]; setting a new progress handler cancels the +** old one. ^Setting parameter X to NULL disables the progress handler. +** ^The progress handler is also disabled by setting N to a value less +** than 1. +** +** ^If the progress callback returns non-zero, the operation is +** interrupted. This feature can be used to implement a +** "Cancel" button on a GUI progress dialog box. +** +** The progress handler callback must not do anything that will modify +** the database connection that invoked the progress handler. +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their +** database connections for the meaning of "modify" in this paragraph. +** +** The progress handler callback would originally only be invoked from the +** bytecode engine. It still might be invoked during [sqlite3_prepare()] +** and similar because those routines might force a reparse of the schema +** which involves running the bytecode engine. However, beginning with +** SQLite version 3.41.0, the progress handler callback might also be +** invoked directly from [sqlite3_prepare()] while analyzing and generating +** code for complex queries. +*/ +SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); + +/* +** CAPI3REF: Opening A New Database Connection +** CONSTRUCTOR: sqlite3 +** +** ^These routines open an SQLite database file as specified by the +** filename argument. ^The filename argument is interpreted as UTF-8 for +** sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte +** order for sqlite3_open16(). ^(A [database connection] handle is usually +** returned in *ppDb, even if an error occurs. The only exception is that +** if SQLite is unable to allocate memory to hold the [sqlite3] object, +** a NULL will be written into *ppDb instead of a pointer to the [sqlite3] +** object.)^ ^(If the database is opened (and/or created) successfully, then +** [SQLITE_OK] is returned. Otherwise an [error code] is returned.)^ ^The +** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain +** an English language description of the error following a failure of any +** of the sqlite3_open() routines. +** +** ^The default encoding will be UTF-8 for databases created using +** sqlite3_open() or sqlite3_open_v2(). ^The default encoding for databases +** created using sqlite3_open16() will be UTF-16 in the native byte order. +** +** Whether or not an error occurs when it is opened, resources +** associated with the [database connection] handle should be released by +** passing it to [sqlite3_close()] when it is no longer required. +** +** The sqlite3_open_v2() interface works like sqlite3_open() +** except that it accepts two additional parameters for additional control +** over the new database connection. ^(The flags parameter to +** sqlite3_open_v2() must include, at a minimum, one of the following +** three flag combinations:)^ +** +**
    +** ^(
    [SQLITE_OPEN_READONLY]
    +**
    The database is opened in read-only mode. If the database does +** not already exist, an error is returned.
    )^ +** +** ^(
    [SQLITE_OPEN_READWRITE]
    +**
    The database is opened for reading and writing if possible, or +** reading only if the file is write protected by the operating +** system. In either case the database must already exist, otherwise +** an error is returned. For historical reasons, if opening in +** read-write mode fails due to OS-level permissions, an attempt is +** made to open it in read-only mode. [sqlite3_db_readonly()] can be +** used to determine whether the database is actually +** read-write.
    )^ +** +** ^(
    [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]
    +**
    The database is opened for reading and writing, and is created if +** it does not already exist. This is the behavior that is always used for +** sqlite3_open() and sqlite3_open16().
    )^ +**
    +** +** In addition to the required flags, the following optional flags are +** also supported: +** +**
    +** ^(
    [SQLITE_OPEN_URI]
    +**
    The filename can be interpreted as a URI if this flag is set.
    )^ +** +** ^(
    [SQLITE_OPEN_MEMORY]
    +**
    The database will be opened as an in-memory database. The database +** is named by the "filename" argument for the purposes of cache-sharing, +** if shared cache mode is enabled, but the "filename" is otherwise ignored. +**
    )^ +** +** ^(
    [SQLITE_OPEN_NOMUTEX]
    +**
    The new database connection will use the "multi-thread" +** [threading mode].)^ This means that separate threads are allowed +** to use SQLite at the same time, as long as each thread is using +** a different [database connection]. +** +** ^(
    [SQLITE_OPEN_FULLMUTEX]
    +**
    The new database connection will use the "serialized" +** [threading mode].)^ This means the multiple threads can safely +** attempt to use the same database connection at the same time. +** (Mutexes will block any actual concurrency, but in this mode +** there is no harm in trying.) +** +** ^(
    [SQLITE_OPEN_SHAREDCACHE]
    +**
    The database is opened with [shared cache] enabled, overriding +** the default shared cache setting provided by +** [sqlite3_enable_shared_cache()].)^ +** The [use of shared cache mode is discouraged] and hence shared cache +** capabilities may be omitted from many builds of SQLite. In such cases, +** this option is a no-op. +** +** ^(
    [SQLITE_OPEN_PRIVATECACHE]
    +**
    The database is opened with [shared cache] disabled, overriding +** the default shared cache setting provided by +** [sqlite3_enable_shared_cache()].)^ +** +** [[OPEN_EXRESCODE]] ^(
    [SQLITE_OPEN_EXRESCODE]
    +**
    The database connection comes up in "extended result code mode". +** In other words, the database behaves as if +** [sqlite3_extended_result_codes(db,1)] were called on the database +** connection as soon as the connection is created. In addition to setting +** the extended result code mode, this flag also causes [sqlite3_open_v2()] +** to return an extended result code.
    +** +** [[OPEN_NOFOLLOW]] ^(
    [SQLITE_OPEN_NOFOLLOW]
    +**
    The database filename is not allowed to contain a symbolic link
    +**
    )^ +** +** If the 3rd parameter to sqlite3_open_v2() is not one of the +** required combinations shown above optionally combined with other +** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits] +** then the behavior is undefined. Historic versions of SQLite +** have silently ignored surplus bits in the flags parameter to +** sqlite3_open_v2(), however that behavior might not be carried through +** into future versions of SQLite and so applications should not rely +** upon it. Note in particular that the SQLITE_OPEN_EXCLUSIVE flag is a no-op +** for sqlite3_open_v2(). The SQLITE_OPEN_EXCLUSIVE does *not* cause +** the open to fail if the database already exists. The SQLITE_OPEN_EXCLUSIVE +** flag is intended for use by the [sqlite3_vfs|VFS interface] only, and not +** by sqlite3_open_v2(). +** +** ^The fourth parameter to sqlite3_open_v2() is the name of the +** [sqlite3_vfs] object that defines the operating system interface that +** the new database connection should use. ^If the fourth parameter is +** a NULL pointer then the default [sqlite3_vfs] object is used. +** +** ^If the filename is ":memory:", then a private, temporary in-memory database +** is created for the connection. ^This in-memory database will vanish when +** the database connection is closed. Future versions of SQLite might +** make use of additional special filenames that begin with the ":" character. +** It is recommended that when a database filename actually does begin with +** a ":" character you should prefix the filename with a pathname such as +** "./" to avoid ambiguity. +** +** ^If the filename is an empty string, then a private, temporary +** on-disk database will be created. ^This private database will be +** automatically deleted as soon as the database connection is closed. +** +** [[URI filenames in sqlite3_open()]]

    URI Filenames

    +** +** ^If [URI filename] interpretation is enabled, and the filename argument +** begins with "file:", then the filename is interpreted as a URI. ^URI +** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is +** set in the third argument to sqlite3_open_v2(), or if it has +** been enabled globally using the [SQLITE_CONFIG_URI] option with the +** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option. +** URI filename interpretation is turned off +** by default, but future releases of SQLite might enable URI filename +** interpretation by default. See "[URI filenames]" for additional +** information. +** +** URI filenames are parsed according to RFC 3986. ^If the URI contains an +** authority, then it must be either an empty string or the string +** "localhost". ^If the authority is not an empty string or "localhost", an +** error is returned to the caller. ^The fragment component of a URI, if +** present, is ignored. +** +** ^SQLite uses the path component of the URI as the name of the disk file +** which contains the database. ^If the path begins with a '/' character, +** then it is interpreted as an absolute path. ^If the path does not begin +** with a '/' (meaning that the authority section is omitted from the URI) +** then the path is interpreted as a relative path. +** ^(On windows, the first component of an absolute path +** is a drive specification (e.g. "C:").)^ +** +** [[core URI query parameters]] +** The query component of a URI may contain parameters that are interpreted +** either by SQLite itself, or by a [VFS | custom VFS implementation]. +** SQLite and its built-in [VFSes] interpret the +** following query parameters: +** +**
      +**
    • vfs: ^The "vfs" parameter may be used to specify the name of +** a VFS object that provides the operating system interface that should +** be used to access the database file on disk. ^If this option is set to +** an empty string the default VFS object is used. ^Specifying an unknown +** VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is +** present, then the VFS specified by the option takes precedence over +** the value passed as the fourth parameter to sqlite3_open_v2(). +** +**
    • mode: ^(The mode parameter may be set to either "ro", "rw", +** "rwc", or "memory". Attempting to set it to any other value is +** an error)^. +** ^If "ro" is specified, then the database is opened for read-only +** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the +** third argument to sqlite3_open_v2(). ^If the mode option is set to +** "rw", then the database is opened for read-write (but not create) +** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had +** been set. ^Value "rwc" is equivalent to setting both +** SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If the mode option is +** set to "memory" then a pure [in-memory database] that never reads +** or writes from disk is used. ^It is an error to specify a value for +** the mode parameter that is less restrictive than that specified by +** the flags passed in the third parameter to sqlite3_open_v2(). +** +**
    • cache: ^The cache parameter may be set to either "shared" or +** "private". ^Setting it to "shared" is equivalent to setting the +** SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to +** sqlite3_open_v2(). ^Setting the cache parameter to "private" is +** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit. +** ^If sqlite3_open_v2() is used and the "cache" parameter is present in +** a URI filename, its value overrides any behavior requested by setting +** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag. +** +**
    • psow: ^The psow parameter indicates whether or not the +** [powersafe overwrite] property does or does not apply to the +** storage media on which the database file resides. +** +**
    • nolock: ^The nolock parameter is a boolean query parameter +** which if set disables file locking in rollback journal modes. This +** is useful for accessing a database on a filesystem that does not +** support locking. Caution: Database corruption might result if two +** or more processes write to the same database and any one of those +** processes uses nolock=1. +** +**
    • immutable: ^The immutable parameter is a boolean query +** parameter that indicates that the database file is stored on +** read-only media. ^When immutable is set, SQLite assumes that the +** database file cannot be changed, even by a process with higher +** privilege, and so the database is opened read-only and all locking +** and change detection is disabled. Caution: Setting the immutable +** property on a database file that does in fact change can result +** in incorrect query results and/or [SQLITE_CORRUPT] errors. +** See also: [SQLITE_IOCAP_IMMUTABLE]. +** +**
    +** +** ^Specifying an unknown parameter in the query component of a URI is not an +** error. Future versions of SQLite might understand additional query +** parameters. See "[query parameters with special meaning to SQLite]" for +** additional information. +** +** [[URI filename examples]]

    URI filename examples

    +** +** +**
    URI filenames Results +**
    file:data.db +** Open the file "data.db" in the current directory. +**
    file:/home/fred/data.db
    +** file:///home/fred/data.db
    +** file://localhost/home/fred/data.db
    +** Open the database file "/home/fred/data.db". +**
    file://darkstar/home/fred/data.db +** An error. "darkstar" is not a recognized authority. +**
    +** file:///C:/Documents%20and%20Settings/fred/Desktop/data.db +** Windows only: Open the file "data.db" on fred's desktop on drive +** C:. Note that the %20 escaping in this example is not strictly +** necessary - space characters can be used literally +** in URI filenames. +**
    file:data.db?mode=ro&cache=private +** Open file "data.db" in the current directory for read-only access. +** Regardless of whether or not shared-cache mode is enabled by +** default, use a private cache. +**
    file:/home/fred/data.db?vfs=unix-dotfile +** Open file "/home/fred/data.db". Use the special VFS "unix-dotfile" +** that uses dot-files in place of posix advisory locking. +**
    file:data.db?mode=readonly +** An error. "readonly" is not a valid option for the "mode" parameter. +** Use "ro" instead: "file:data.db?mode=ro". +**
    +** +** ^URI hexadecimal escape sequences (%HH) are supported within the path and +** query components of a URI. A hexadecimal escape sequence consists of a +** percent sign - "%" - followed by exactly two hexadecimal digits +** specifying an octet value. ^Before the path or query components of a +** URI filename are interpreted, they are encoded using UTF-8 and all +** hexadecimal escape sequences replaced by a single byte containing the +** corresponding octet. If this process generates an invalid UTF-8 encoding, +** the results are undefined. +** +** Note to Windows users: The encoding used for the filename argument +** of sqlite3_open() and sqlite3_open_v2() must be UTF-8, not whatever +** codepage is currently defined. Filenames containing international +** characters must be converted to UTF-8 prior to passing them into +** sqlite3_open() or sqlite3_open_v2(). +** +** Note to Windows Runtime users: The temporary directory must be set +** prior to calling sqlite3_open() or sqlite3_open_v2(). Otherwise, various +** features that require the use of temporary files may fail. +** +** See also: [sqlite3_temp_directory] +*/ +SQLITE_API int sqlite3_open( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +SQLITE_API int sqlite3_open16( + const void *filename, /* Database filename (UTF-16) */ + sqlite3 **ppDb /* OUT: SQLite db handle */ +); +SQLITE_API int sqlite3_open_v2( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs /* Name of VFS module to use */ +); + +/* +** CAPI3REF: Obtain Values For URI Parameters +** +** These are utility routines, useful to [VFS|custom VFS implementations], +** that check if a database file was a URI that contained a specific query +** parameter, and if so obtains the value of that query parameter. +** +** The first parameter to these interfaces (hereafter referred to +** as F) must be one of: +**
      +**
    • A database filename pointer created by the SQLite core and +** passed into the xOpen() method of a VFS implementation, or +**
    • A filename obtained from [sqlite3_db_filename()], or +**
    • A new filename constructed using [sqlite3_create_filename()]. +**
    +** If the F parameter is not one of the above, then the behavior is +** undefined and probably undesirable. Older versions of SQLite were +** more tolerant of invalid F parameters than newer versions. +** +** If F is a suitable filename (as described in the previous paragraph) +** and if P is the name of the query parameter, then +** sqlite3_uri_parameter(F,P) returns the value of the P +** parameter if it exists or a NULL pointer if P does not appear as a +** query parameter on F. If P is a query parameter of F and it +** has no explicit value, then sqlite3_uri_parameter(F,P) returns +** a pointer to an empty string. +** +** The sqlite3_uri_boolean(F,P,B) routine assumes that P is a boolean +** parameter and returns true (1) or false (0) according to the value +** of P. The sqlite3_uri_boolean(F,P,B) routine returns true (1) if the +** value of query parameter P is one of "yes", "true", or "on" in any +** case or if the value begins with a non-zero number. The +** sqlite3_uri_boolean(F,P,B) routines returns false (0) if the value of +** query parameter P is one of "no", "false", or "off" in any case or +** if the value begins with a numeric zero. If P is not a query +** parameter on F or if the value of P does not match any of the +** above, then sqlite3_uri_boolean(F,P,B) returns (B!=0). +** +** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a +** 64-bit signed integer and returns that integer, or D if P does not +** exist. If the value of P is something other than an integer, then +** zero is returned. +** +** The sqlite3_uri_key(F,N) returns a pointer to the name (not +** the value) of the N-th query parameter for filename F, or a NULL +** pointer if N is less than zero or greater than the number of query +** parameters minus 1. The N value is zero-based so N should be 0 to obtain +** the name of the first query parameter, 1 for the second parameter, and +** so forth. +** +** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and +** sqlite3_uri_boolean(F,P,B) returns B. If F is not a NULL pointer and +** is not a database file pathname pointer that the SQLite core passed +** into the xOpen VFS method, then the behavior of this routine is undefined +** and probably undesirable. +** +** Beginning with SQLite [version 3.31.0] ([dateof:3.31.0]) the input F +** parameter can also be the name of a rollback journal file or WAL file +** in addition to the main database file. Prior to version 3.31.0, these +** routines would only work if F was the name of the main database file. +** When the F parameter is the name of the rollback journal or WAL file, +** it has access to all the same query parameters as were found on the +** main database file. +** +** See the [URI filename] documentation for additional information. +*/ +SQLITE_API const char *sqlite3_uri_parameter(sqlite3_filename z, const char *zParam); +SQLITE_API int sqlite3_uri_boolean(sqlite3_filename z, const char *zParam, int bDefault); +SQLITE_API sqlite3_int64 sqlite3_uri_int64(sqlite3_filename, const char*, sqlite3_int64); +SQLITE_API const char *sqlite3_uri_key(sqlite3_filename z, int N); + +/* +** CAPI3REF: Translate filenames +** +** These routines are available to [VFS|custom VFS implementations] for +** translating filenames between the main database file, the journal file, +** and the WAL file. +** +** If F is the name of an sqlite database file, journal file, or WAL file +** passed by the SQLite core into the VFS, then sqlite3_filename_database(F) +** returns the name of the corresponding database file. +** +** If F is the name of an sqlite database file, journal file, or WAL file +** passed by the SQLite core into the VFS, or if F is a database filename +** obtained from [sqlite3_db_filename()], then sqlite3_filename_journal(F) +** returns the name of the corresponding rollback journal file. +** +** If F is the name of an sqlite database file, journal file, or WAL file +** that was passed by the SQLite core into the VFS, or if F is a database +** filename obtained from [sqlite3_db_filename()], then +** sqlite3_filename_wal(F) returns the name of the corresponding +** WAL file. +** +** In all of the above, if F is not the name of a database, journal or WAL +** filename passed into the VFS from the SQLite core and F is not the +** return value from [sqlite3_db_filename()], then the result is +** undefined and is likely a memory access violation. +*/ +SQLITE_API const char *sqlite3_filename_database(sqlite3_filename); +SQLITE_API const char *sqlite3_filename_journal(sqlite3_filename); +SQLITE_API const char *sqlite3_filename_wal(sqlite3_filename); + +/* +** CAPI3REF: Database File Corresponding To A Journal +** +** ^If X is the name of a rollback or WAL-mode journal file that is +** passed into the xOpen method of [sqlite3_vfs], then +** sqlite3_database_file_object(X) returns a pointer to the [sqlite3_file] +** object that represents the main database file. +** +** This routine is intended for use in custom [VFS] implementations +** only. It is not a general-purpose interface. +** The argument sqlite3_file_object(X) must be a filename pointer that +** has been passed into [sqlite3_vfs].xOpen method where the +** flags parameter to xOpen contains one of the bits +** [SQLITE_OPEN_MAIN_JOURNAL] or [SQLITE_OPEN_WAL]. Any other use +** of this routine results in undefined and probably undesirable +** behavior. +*/ +SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*); + +/* +** CAPI3REF: Create and Destroy VFS Filenames +** +** These interfaces are provided for use by [VFS shim] implementations and +** are not useful outside of that context. +** +** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of +** database filename D with corresponding journal file J and WAL file W and +** an array P of N URI Key/Value pairs. The result from +** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that +** is safe to pass to routines like: +**
      +**
    • [sqlite3_uri_parameter()], +**
    • [sqlite3_uri_boolean()], +**
    • [sqlite3_uri_int64()], +**
    • [sqlite3_uri_key()], +**
    • [sqlite3_filename_database()], +**
    • [sqlite3_filename_journal()], or +**
    • [sqlite3_filename_wal()]. +**
    +** If a memory allocation error occurs, sqlite3_create_filename() might +** return a NULL pointer. The memory obtained from sqlite3_create_filename(X) +** must be released by a corresponding call to sqlite3_free_filename(Y). +** +** The P parameter in sqlite3_create_filename(D,J,W,N,P) should be an array +** of 2*N pointers to strings. Each pair of pointers in this array corresponds +** to a key and value for a query parameter. The P parameter may be a NULL +** pointer if N is zero. None of the 2*N pointers in the P array may be +** NULL pointers and key pointers should not be empty strings. +** None of the D, J, or W parameters to sqlite3_create_filename(D,J,W,N,P) may +** be NULL pointers, though they can be empty strings. +** +** The sqlite3_free_filename(Y) routine releases a memory allocation +** previously obtained from sqlite3_create_filename(). Invoking +** sqlite3_free_filename(Y) where Y is a NULL pointer is a harmless no-op. +** +** If the Y parameter to sqlite3_free_filename(Y) is anything other +** than a NULL pointer or a pointer previously acquired from +** sqlite3_create_filename(), then bad things such as heap +** corruption or segfaults may occur. The value Y should not be +** used again after sqlite3_free_filename(Y) has been called. This means +** that if the [sqlite3_vfs.xOpen()] method of a VFS has been called using Y, +** then the corresponding [sqlite3_module.xClose() method should also be +** invoked prior to calling sqlite3_free_filename(Y). +*/ +SQLITE_API sqlite3_filename sqlite3_create_filename( + const char *zDatabase, + const char *zJournal, + const char *zWal, + int nParam, + const char **azParam +); +SQLITE_API void sqlite3_free_filename(sqlite3_filename); + +/* +** CAPI3REF: Error Codes And Messages +** METHOD: sqlite3 +** +** ^If the most recent sqlite3_* API call associated with +** [database connection] D failed, then the sqlite3_errcode(D) interface +** returns the numeric [result code] or [extended result code] for that +** API call. +** ^The sqlite3_extended_errcode() +** interface is the same except that it always returns the +** [extended result code] even when extended result codes are +** disabled. +** +** The values returned by sqlite3_errcode() and/or +** sqlite3_extended_errcode() might change with each API call. +** Except, there are some interfaces that are guaranteed to never +** change the value of the error code. The error-code preserving +** interfaces include the following: +** +**
      +**
    • sqlite3_errcode() +**
    • sqlite3_extended_errcode() +**
    • sqlite3_errmsg() +**
    • sqlite3_errmsg16() +**
    • sqlite3_error_offset() +**
    • sqlite3_db_handle() +**
    +** +** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language +** text that describes the error, as either UTF-8 or UTF-16 respectively, +** or NULL if no error message is available. +** (See how SQLite handles [invalid UTF] for exceptions to this rule.) +** ^(Memory to hold the error message string is managed internally. +** The application does not need to worry about freeing the result. +** However, the error string might be overwritten or deallocated by +** subsequent calls to other SQLite interface functions.)^ +** +** ^The sqlite3_errstr(E) interface returns the English-language text +** that describes the [result code] E, as UTF-8, or NULL if E is not a +** result code for which a text error message is available. +** ^(Memory to hold the error message string is managed internally +** and must not be freed by the application)^. +** +** ^If the most recent error references a specific token in the input +** SQL, the sqlite3_error_offset() interface returns the byte offset +** of the start of that token. ^The byte offset returned by +** sqlite3_error_offset() assumes that the input SQL is UTF-8. +** ^If the most recent error does not reference a specific token in the input +** SQL, then the sqlite3_error_offset() function returns -1. +** +** When the serialized [threading mode] is in use, it might be the +** case that a second error occurs on a separate thread in between +** the time of the first error and the call to these interfaces. +** When that happens, the second error will be reported since these +** interfaces always report the most recent result. To avoid +** this, each thread can obtain exclusive use of the [database connection] D +** by invoking [sqlite3_mutex_enter]([sqlite3_db_mutex](D)) before beginning +** to use D and invoking [sqlite3_mutex_leave]([sqlite3_db_mutex](D)) after +** all calls to the interfaces listed here are completed. +** +** If an interface fails with SQLITE_MISUSE, that means the interface +** was invoked incorrectly by the application. In that case, the +** error code and message may or may not be set. +*/ +SQLITE_API int sqlite3_errcode(sqlite3 *db); +SQLITE_API int sqlite3_extended_errcode(sqlite3 *db); +SQLITE_API const char *sqlite3_errmsg(sqlite3*); +SQLITE_API const void *sqlite3_errmsg16(sqlite3*); +SQLITE_API const char *sqlite3_errstr(int); +SQLITE_API int sqlite3_error_offset(sqlite3 *db); + +/* +** CAPI3REF: Set Error Code And Message +** METHOD: sqlite3 +** +** Set the error code of the database handle passed as the first argument +** to errcode, and the error message to a copy of nul-terminated string +** zErrMsg. If zErrMsg is passed NULL, then the error message is set to +** the default message associated with the supplied error code. Subsequent +** calls to [sqlite3_errcode()] and [sqlite3_errmsg()] and similar will +** return the values set by this routine in place of what was previously +** set by SQLite itself. +** +** This function returns SQLITE_OK if the error code and error message are +** successfully set, SQLITE_NOMEM if an OOM occurs, and SQLITE_MISUSE if +** the database handle is NULL or invalid. +** +** The error code and message set by this routine remains in effect until +** they are changed, either by another call to this routine or until they are +** changed to by SQLite itself to reflect the result of some subsquent +** API call. +** +** This function is intended for use by SQLite extensions or wrappers. The +** idea is that an extension or wrapper can use this routine to set error +** messages and error codes and thus behave more like a core SQLite +** feature from the point of view of an application. +*/ +SQLITE_API int sqlite3_set_errmsg(sqlite3 *db, int errcode, const char *zErrMsg); + +/* +** CAPI3REF: Prepared Statement Object +** KEYWORDS: {prepared statement} {prepared statements} +** +** An instance of this object represents a single SQL statement that +** has been compiled into binary form and is ready to be evaluated. +** +** Think of each SQL statement as a separate computer program. The +** original SQL text is source code. A prepared statement object +** is the compiled object code. All SQL must be converted into a +** prepared statement before it can be run. +** +** The life-cycle of a prepared statement object usually goes like this: +** +**
      +**
    1. Create the prepared statement object using [sqlite3_prepare_v2()]. +**
    2. Bind values to [parameters] using the sqlite3_bind_*() +** interfaces. +**
    3. Run the SQL by calling [sqlite3_step()] one or more times. +**
    4. Reset the prepared statement using [sqlite3_reset()] then go back +** to step 2. Do this zero or more times. +**
    5. Destroy the object using [sqlite3_finalize()]. +**
    +*/ +typedef struct sqlite3_stmt sqlite3_stmt; + +/* +** CAPI3REF: Run-time Limits +** METHOD: sqlite3 +** +** ^(This interface allows the size of various constructs to be limited +** on a connection by connection basis. The first parameter is the +** [database connection] whose limit is to be set or queried. The +** second parameter is one of the [limit categories] that define a +** class of constructs to be size limited. The third parameter is the +** new limit for that construct.)^ +** +** ^If the new limit is a negative number, the limit is unchanged. +** ^(For each limit category SQLITE_LIMIT_NAME there is a +** [limits | hard upper bound] +** set at compile-time by a C preprocessor macro called +** [limits | SQLITE_MAX_NAME]. +** (The "_LIMIT_" in the name is changed to "_MAX_".))^ +** ^Attempts to increase a limit above its hard upper bound are +** silently truncated to the hard upper bound. +** +** ^Regardless of whether or not the limit was changed, the +** [sqlite3_limit()] interface returns the prior value of the limit. +** ^Hence, to find the current value of a limit without changing it, +** simply invoke this interface with the third parameter set to -1. +** +** Run-time limits are intended for use in applications that manage +** both their own internal database and also databases that are controlled +** by untrusted external sources. An example application might be a +** web browser that has its own databases for storing history and +** separate databases controlled by JavaScript applications downloaded +** off the Internet. The internal databases can be given the +** large, default limits. Databases managed by external sources can +** be given much smaller limits designed to prevent a denial of service +** attack. Developers might also want to use the [sqlite3_set_authorizer()] +** interface to further control untrusted SQL. The size of the database +** created by an untrusted script can be contained using the +** [max_page_count] [PRAGMA]. +** +** New run-time limit categories may be added in future releases. +*/ +SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); + +/* +** CAPI3REF: Run-Time Limit Categories +** KEYWORDS: {limit category} {*limit categories} +** +** These constants define various performance limits +** that can be lowered at run-time using [sqlite3_limit()]. +** A concise description of these limits follows, and additional information +** is available at [limits | Limits in SQLite]. +** +**
    +** [[SQLITE_LIMIT_LENGTH]] ^(
    SQLITE_LIMIT_LENGTH
    +**
    The maximum size of any string or BLOB or table row, in bytes.
    )^ +** +** [[SQLITE_LIMIT_SQL_LENGTH]] ^(
    SQLITE_LIMIT_SQL_LENGTH
    +**
    The maximum length of an SQL statement, in bytes.
    )^ +** +** [[SQLITE_LIMIT_COLUMN]] ^(
    SQLITE_LIMIT_COLUMN
    +**
    The maximum number of columns in a table definition or in the +** result set of a [SELECT] or the maximum number of columns in an index +** or in an ORDER BY or GROUP BY clause.
    )^ +** +** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(
    SQLITE_LIMIT_EXPR_DEPTH
    +**
    The maximum depth of the parse tree on any expression and +** the maximum nesting depth for subqueries and VIEWs
    )^ +** +** [[SQLITE_LIMIT_PARSER_DEPTH]] ^(
    SQLITE_LIMIT_PARSER_DEPTH
    +**
    The maximum depth of the LALR(1) parser stack used to analyze +** input SQL statements.
    )^ +** +** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(
    SQLITE_LIMIT_COMPOUND_SELECT
    +**
    The maximum number of terms in a compound SELECT statement.
    )^ +** +** [[SQLITE_LIMIT_VDBE_OP]] ^(
    SQLITE_LIMIT_VDBE_OP
    +**
    The maximum number of instructions in a virtual machine program +** used to implement an SQL statement. If [sqlite3_prepare_v2()] or +** the equivalent tries to allocate space for more than this many opcodes +** in a single prepared statement, an SQLITE_NOMEM error is returned.
    )^ +** +** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(
    SQLITE_LIMIT_FUNCTION_ARG
    +**
    The maximum number of arguments on a function.
    )^ +** +** [[SQLITE_LIMIT_ATTACHED]] ^(
    SQLITE_LIMIT_ATTACHED
    +**
    The maximum number of [ATTACH | attached databases].)^
    +** +** [[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]] +** ^(
    SQLITE_LIMIT_LIKE_PATTERN_LENGTH
    +**
    The maximum length of the pattern argument to the [LIKE] or +** [GLOB] operators.
    )^ +** +** [[SQLITE_LIMIT_VARIABLE_NUMBER]] +** ^(
    SQLITE_LIMIT_VARIABLE_NUMBER
    +**
    The maximum index number of any [parameter] in an SQL statement.)^ +** +** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(
    SQLITE_LIMIT_TRIGGER_DEPTH
    +**
    The maximum depth of recursion for triggers, and the maximum +** nesting depth for separate triggers.
    )^ +** +** [[SQLITE_LIMIT_WORKER_THREADS]] ^(
    SQLITE_LIMIT_WORKER_THREADS
    +**
    The maximum number of auxiliary worker threads that a single +** [prepared statement] may start.
    )^ +**
    +*/ +#define SQLITE_LIMIT_LENGTH 0 +#define SQLITE_LIMIT_SQL_LENGTH 1 +#define SQLITE_LIMIT_COLUMN 2 +#define SQLITE_LIMIT_EXPR_DEPTH 3 +#define SQLITE_LIMIT_COMPOUND_SELECT 4 +#define SQLITE_LIMIT_VDBE_OP 5 +#define SQLITE_LIMIT_FUNCTION_ARG 6 +#define SQLITE_LIMIT_ATTACHED 7 +#define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8 +#define SQLITE_LIMIT_VARIABLE_NUMBER 9 +#define SQLITE_LIMIT_TRIGGER_DEPTH 10 +#define SQLITE_LIMIT_WORKER_THREADS 11 +#define SQLITE_LIMIT_PARSER_DEPTH 12 + +/* +** CAPI3REF: Prepare Flags +** +** These constants define various flags that can be passed into the +** "prepFlags" parameter of the [sqlite3_prepare_v3()] and +** [sqlite3_prepare16_v3()] interfaces. +** +** New flags may be added in future releases of SQLite. +** +**
    +** [[SQLITE_PREPARE_PERSISTENT]] ^(
    SQLITE_PREPARE_PERSISTENT
    +**
    The SQLITE_PREPARE_PERSISTENT flag is a hint to the query planner +** that the prepared statement will be retained for a long time and +** probably reused many times.)^ ^Without this flag, [sqlite3_prepare_v3()] +** and [sqlite3_prepare16_v3()] assume that the prepared statement will +** be used just once or at most a few times and then destroyed using +** [sqlite3_finalize()] relatively soon. The current implementation acts +** on this hint by avoiding the use of [lookaside memory] so as not to +** deplete the limited store of lookaside memory. Future versions of +** SQLite may act on this hint differently. +** +** [[SQLITE_PREPARE_NORMALIZE]]
    SQLITE_PREPARE_NORMALIZE
    +**
    The SQLITE_PREPARE_NORMALIZE flag is a no-op. This flag used +** to be required for any prepared statement that wanted to use the +** [sqlite3_normalized_sql()] interface. However, the +** [sqlite3_normalized_sql()] interface is now available to all +** prepared statements, regardless of whether or not they use this +** flag. +** +** [[SQLITE_PREPARE_NO_VTAB]]
    SQLITE_PREPARE_NO_VTAB
    +**
    The SQLITE_PREPARE_NO_VTAB flag causes the SQL compiler +** to return an error (error code SQLITE_ERROR) if the statement uses +** any virtual tables. +** +** [[SQLITE_PREPARE_DONT_LOG]]
    SQLITE_PREPARE_DONT_LOG
    +**
    The SQLITE_PREPARE_DONT_LOG flag prevents SQL compiler +** errors from being sent to the error log defined by +** [SQLITE_CONFIG_LOG]. This can be used, for example, to do test +** compiles to see if some SQL syntax is well-formed, without generating +** messages on the global error log when it is not. If the test compile +** fails, the sqlite3_prepare_v3() call returns the same error indications +** with or without this flag; it just omits the call to [sqlite3_log()] that +** logs the error. +** +** [[SQLITE_PREPARE_FROM_DDL]]
    SQLITE_PREPARE_FROM_DDL
    +**
    The SQLITE_PREPARE_FROM_DDL flag causes the SQL compiler to enforce +** security constraints that would otherwise only be enforced when parsing +** the database schema. In other words, the SQLITE_PREPARE_FROM_DDL flag +** causes the SQL compiler to treat the SQL statement being prepared as if +** it had come from an attacker. When SQLITE_PREPARE_FROM_DDL is used and +** [SQLITE_DBCONFIG_TRUSTED_SCHEMA] is off, SQL functions may only be called +** if they are tagged with [SQLITE_INNOCUOUS] and virtual tables may only +** be used if they are tagged with [SQLITE_VTAB_INNOCUOUS]. Best practice +** is to use the SQLITE_PREPARE_FROM_DDL option when preparing any SQL that +** is derived from parts of the database schema. In particular, virtual +** table implementations that run SQL statements that are derived from +** arguments to their CREATE VIRTUAL TABLE statement should always use +** [sqlite3_prepare_v3()] and set the SQLITE_PREPARE_FROM_DDL flag to +** prevent bypass of the [SQLITE_DBCONFIG_TRUSTED_SCHEMA] security checks. +**
    +*/ +#define SQLITE_PREPARE_PERSISTENT 0x01 +#define SQLITE_PREPARE_NORMALIZE 0x02 +#define SQLITE_PREPARE_NO_VTAB 0x04 +#define SQLITE_PREPARE_DONT_LOG 0x10 +#define SQLITE_PREPARE_FROM_DDL 0x20 + +/* +** CAPI3REF: Compiling An SQL Statement +** KEYWORDS: {SQL statement compiler} +** METHOD: sqlite3 +** CONSTRUCTOR: sqlite3_stmt +** +** To execute an SQL statement, it must first be compiled into a byte-code +** program using one of these routines. Or, in other words, these routines +** are constructors for the [prepared statement] object. +** +** The preferred routine to use is [sqlite3_prepare_v2()]. The +** [sqlite3_prepare()] interface is legacy and should be avoided. +** [sqlite3_prepare_v3()] has an extra +** [SQLITE_PREPARE_FROM_DDL|"prepFlags" option] that is sometimes +** needed for special purpose or to pass along security restrictions. +** +** The use of the UTF-8 interfaces is preferred, as SQLite currently +** does all parsing using UTF-8. The UTF-16 interfaces are provided +** as a convenience. The UTF-16 interfaces work by converting the +** input text into UTF-8, then invoking the corresponding UTF-8 interface. +** +** The first argument, "db", is a [database connection] obtained from a +** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or +** [sqlite3_open16()]. The database connection must not have been closed. +** +** The second argument, "zSql", is the statement to be compiled, encoded +** as either UTF-8 or UTF-16. The sqlite3_prepare(), sqlite3_prepare_v2(), +** and sqlite3_prepare_v3() +** interfaces use UTF-8, and sqlite3_prepare16(), sqlite3_prepare16_v2(), +** and sqlite3_prepare16_v3() use UTF-16. +** +** ^If the nByte argument is negative, then zSql is read up to the +** first zero terminator. ^If nByte is positive, then it is the maximum +** number of bytes read from zSql. When nByte is positive, zSql is read +** up to the first zero terminator or until the nByte bytes have been read, +** whichever comes first. ^If nByte is zero, then no prepared +** statement is generated. +** If the caller knows that the supplied string is nul-terminated, then +** there is a small performance advantage to passing an nByte parameter that +** is the number of bytes in the input string including +** the nul-terminator. +** Note that nByte measures the length of the input in bytes, not +** characters, even for the UTF-16 interfaces. +** +** ^If pzTail is not NULL then *pzTail is made to point to the first byte +** past the end of the first SQL statement in zSql. These routines only +** compile the first statement in zSql, so *pzTail is left pointing to +** what remains uncompiled. +** +** ^*ppStmt is left pointing to a compiled [prepared statement] that can be +** executed using [sqlite3_step()]. ^If there is an error, *ppStmt is set +** to NULL. ^If the input text contains no SQL (if the input is an empty +** string or a comment) then *ppStmt is set to NULL. +** The calling procedure is responsible for deleting the compiled +** SQL statement using [sqlite3_finalize()] after it has finished with it. +** ppStmt may not be NULL. +** +** ^On success, the sqlite3_prepare() family of routines return [SQLITE_OK]; +** otherwise an [error code] is returned. +** +** The sqlite3_prepare_v2(), sqlite3_prepare_v3(), sqlite3_prepare16_v2(), +** and sqlite3_prepare16_v3() interfaces are recommended for all new programs. +** The older interfaces (sqlite3_prepare() and sqlite3_prepare16()) +** are retained for backwards compatibility, but their use is discouraged. +** ^In the "vX" interfaces, the prepared statement +** that is returned (the [sqlite3_stmt] object) contains a copy of the +** original SQL text. This causes the [sqlite3_step()] interface to +** behave differently in three ways: +** +**
      +**
    1. +** ^If the database schema changes, instead of returning [SQLITE_SCHEMA] as it +** always used to do, [sqlite3_step()] will automatically recompile the SQL +** statement and try to run it again. As many as [SQLITE_MAX_SCHEMA_RETRY] +** retries will occur before sqlite3_step() gives up and returns an error. +**
    2. +** +**
    3. +** ^When an error occurs, [sqlite3_step()] will return one of the detailed +** [error codes] or [extended error codes]. ^The legacy behavior was that +** [sqlite3_step()] would only return a generic [SQLITE_ERROR] result code +** and the application would have to make a second call to [sqlite3_reset()] +** in order to find the underlying cause of the problem. With the "v2" prepare +** interfaces, the underlying reason for the error is returned immediately. +**
    4. +** +**
    5. +** ^If the specific value bound to a [parameter | host parameter] in the +** WHERE clause might influence the choice of query plan for a statement, +** then the statement will be automatically recompiled, as if there had been +** a schema change, on the first [sqlite3_step()] call following any change +** to the [sqlite3_bind_text | bindings] of that [parameter]. +** ^The specific value of a WHERE-clause [parameter] might influence the +** choice of query plan if the parameter is the left-hand side of a [LIKE] +** or [GLOB] operator or if the parameter is compared to an indexed column +** and the [SQLITE_ENABLE_STAT4] compile-time option is enabled. +**
    6. +**
    +** +**

    ^sqlite3_prepare_v3() differs from sqlite3_prepare_v2() only in having +** the extra prepFlags parameter, which is a bit array consisting of zero or +** more of the [SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_*] flags. ^The +** sqlite3_prepare_v2() interface works exactly the same as +** sqlite3_prepare_v3() with a zero prepFlags parameter. +*/ +SQLITE_API int sqlite3_prepare( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +SQLITE_API int sqlite3_prepare_v2( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +SQLITE_API int sqlite3_prepare_v3( + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_ flags */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ +); +SQLITE_API int sqlite3_prepare16( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); +SQLITE_API int sqlite3_prepare16_v2( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); +SQLITE_API int sqlite3_prepare16_v3( + sqlite3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_ flags */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ +); + +/* +** CAPI3REF: Retrieving Statement SQL +** METHOD: sqlite3_stmt +** +** ^The sqlite3_sql(P) interface returns a pointer to a copy of the UTF-8 +** SQL text used to create [prepared statement] P if P was +** created by [sqlite3_prepare_v2()], [sqlite3_prepare_v3()], +** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()]. +** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8 +** string containing the SQL text of prepared statement P with +** [bound parameters] expanded. +** ^The sqlite3_normalized_sql(P) interface returns a pointer to a UTF-8 +** string containing the normalized SQL text of prepared statement P. The +** semantics used to normalize a SQL statement are unspecified and subject +** to change. At a minimum, literal values will be replaced with suitable +** placeholders. +** +** ^(For example, if a prepared statement is created using the SQL +** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345 +** and parameter :xyz is unbound, then sqlite3_sql() will return +** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql() +** will return "SELECT 2345,NULL".)^ +** +** ^The sqlite3_expanded_sql() interface returns NULL if insufficient memory +** is available to hold the result, or if the result would exceed the +** maximum string length determined by the [SQLITE_LIMIT_LENGTH]. +** +** ^The [SQLITE_TRACE_SIZE_LIMIT] compile-time option limits the size of +** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time +** option causes sqlite3_expanded_sql() to always return NULL. +** +** ^The strings returned by sqlite3_sql(P) and sqlite3_normalized_sql(P) +** are managed by SQLite and are automatically freed when the prepared +** statement is finalized. +** ^The string returned by sqlite3_expanded_sql(P), on the other hand, +** is obtained from [sqlite3_malloc()] and must be freed by the application +** by passing it to [sqlite3_free()]. +** +** ^The sqlite3_normalized_sql() interface is only available if +** the [SQLITE_ENABLE_NORMALIZE] compile-time option is defined. +*/ +SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt); +SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt); +#ifdef SQLITE_ENABLE_NORMALIZE +SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt); +#endif + +/* +** CAPI3REF: Determine If An SQL Statement Writes The Database +** METHOD: sqlite3_stmt +** +** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if +** and only if the [prepared statement] X makes no direct changes to +** the content of the database file. +** +** Note that [application-defined SQL functions] or +** [virtual tables] might change the database indirectly as a side effect. +** ^(For example, if an application defines a function "eval()" that +** calls [sqlite3_exec()], then the following SQL statement would +** change the database file through side-effects: +** +**

    +**    SELECT eval('DELETE FROM t1') FROM t2;
    +** 
    +** +** But because the [SELECT] statement does not change the database file +** directly, sqlite3_stmt_readonly() would still return true.)^ +** +** ^Transaction control statements such as [BEGIN], [COMMIT], [ROLLBACK], +** [SAVEPOINT], and [RELEASE] cause sqlite3_stmt_readonly() to return true, +** since the statements themselves do not actually modify the database but +** rather they control the timing of when other statements modify the +** database. ^The [ATTACH] and [DETACH] statements also cause +** sqlite3_stmt_readonly() to return true since, while those statements +** change the configuration of a database connection, they do not make +** changes to the content of the database files on disk. +** ^The sqlite3_stmt_readonly() interface returns true for [BEGIN] since +** [BEGIN] merely sets internal flags, but the [BEGIN|BEGIN IMMEDIATE] and +** [BEGIN|BEGIN EXCLUSIVE] commands do touch the database and so +** sqlite3_stmt_readonly() returns false for those commands. +** +** ^This routine returns false if there is any possibility that the +** statement might change the database file. ^A false return does +** not guarantee that the statement will change the database file. +** ^For example, an UPDATE statement might have a WHERE clause that +** makes it a no-op, but the sqlite3_stmt_readonly() result would still +** be false. ^Similarly, a CREATE TABLE IF NOT EXISTS statement is a +** read-only no-op if the table already exists, but +** sqlite3_stmt_readonly() still returns false for such a statement. +** +** ^If prepared statement X is an [EXPLAIN] or [EXPLAIN QUERY PLAN] +** statement, then sqlite3_stmt_readonly(X) returns the same value as +** if the EXPLAIN or EXPLAIN QUERY PLAN prefix were omitted. +*/ +SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Query The EXPLAIN Setting For A Prepared Statement +** METHOD: sqlite3_stmt +** +** ^The sqlite3_stmt_isexplain(S) interface returns 1 if the +** prepared statement S is an EXPLAIN statement, or 2 if the +** statement S is an EXPLAIN QUERY PLAN. +** ^The sqlite3_stmt_isexplain(S) interface returns 0 if S is +** an ordinary statement or a NULL pointer. +*/ +SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Change The EXPLAIN Setting For A Prepared Statement +** METHOD: sqlite3_stmt +** +** The sqlite3_stmt_explain(S,E) interface changes the EXPLAIN +** setting for [prepared statement] S. If E is zero, then S becomes +** a normal prepared statement. If E is 1, then S behaves as if +** its SQL text began with "[EXPLAIN]". If E is 2, then S behaves as if +** its SQL text began with "[EXPLAIN QUERY PLAN]". +** +** Calling sqlite3_stmt_explain(S,E) might cause S to be reprepared. +** SQLite tries to avoid a reprepare, but a reprepare might be necessary +** on the first transition into EXPLAIN or EXPLAIN QUERY PLAN mode. +** +** Because of the potential need to reprepare, a call to +** sqlite3_stmt_explain(S,E) will fail with SQLITE_ERROR if S cannot be +** reprepared because it was created using [sqlite3_prepare()] instead of +** the newer [sqlite3_prepare_v2()] or [sqlite3_prepare_v3()] interfaces and +** hence has no saved SQL text with which to reprepare. +** +** Changing the explain setting for a prepared statement does not change +** the original SQL text for the statement. Hence, if the SQL text originally +** began with EXPLAIN or EXPLAIN QUERY PLAN, but sqlite3_stmt_explain(S,0) +** is called to convert the statement into an ordinary statement, the EXPLAIN +** or EXPLAIN QUERY PLAN keywords will still appear in the sqlite3_sql(S) +** output, even though the statement now acts like a normal SQL statement. +** +** This routine returns SQLITE_OK if the explain mode is successfully +** changed, or an error code if the explain mode could not be changed. +** The explain mode cannot be changed while a statement is active. +** Hence, it is good practice to call [sqlite3_reset(S)] +** immediately prior to calling sqlite3_stmt_explain(S,E). +*/ +SQLITE_API int sqlite3_stmt_explain(sqlite3_stmt *pStmt, int eMode); + +/* +** CAPI3REF: Determine If A Prepared Statement Has Been Reset +** METHOD: sqlite3_stmt +** +** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the +** [prepared statement] S has been stepped at least once using +** [sqlite3_step(S)] but has neither run to completion (returned +** [SQLITE_DONE] from [sqlite3_step(S)]) nor +** been reset using [sqlite3_reset(S)]. ^The sqlite3_stmt_busy(S) +** interface returns false if S is a NULL pointer. If S is not a +** NULL pointer and is not a pointer to a valid [prepared statement] +** object, then the behavior is undefined and probably undesirable. +** +** This interface can be used in combination [sqlite3_next_stmt()] +** to locate all prepared statements associated with a database +** connection that are in need of being reset. This can be used, +** for example, in diagnostic routines to search for prepared +** statements that are holding a transaction open. +*/ +SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*); + +/* +** CAPI3REF: Dynamically Typed Value Object +** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value} +** +** SQLite uses the sqlite3_value object to represent all values +** that can be stored in a database table. SQLite uses dynamic typing +** for the values it stores. ^Values stored in sqlite3_value objects +** can be integers, floating point values, strings, BLOBs, or NULL. +** +** An sqlite3_value object may be either "protected" or "unprotected". +** Some interfaces require a protected sqlite3_value. Other interfaces +** will accept either a protected or an unprotected sqlite3_value. +** Every interface that accepts sqlite3_value arguments specifies +** whether or not it requires a protected sqlite3_value. The +** [sqlite3_value_dup()] interface can be used to construct a new +** protected sqlite3_value from an unprotected sqlite3_value. +** +** The terms "protected" and "unprotected" refer to whether or not +** a mutex is held. An internal mutex is held for a protected +** sqlite3_value object but no mutex is held for an unprotected +** sqlite3_value object. If SQLite is compiled to be single-threaded +** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0) +** or if SQLite is run in one of reduced mutex modes +** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD] +** then there is no distinction between protected and unprotected +** sqlite3_value objects and they can be used interchangeably. However, +** for maximum code portability it is recommended that applications +** still make the distinction between protected and unprotected +** sqlite3_value objects even when not strictly required. +** +** ^The sqlite3_value objects that are passed as parameters into the +** implementation of [application-defined SQL functions] are protected. +** ^The sqlite3_value objects returned by [sqlite3_vtab_rhs_value()] +** are protected. +** ^The sqlite3_value object returned by +** [sqlite3_column_value()] is unprotected. +** Unprotected sqlite3_value objects may only be used as arguments +** to [sqlite3_result_value()], [sqlite3_bind_value()], and +** [sqlite3_value_dup()]. +** The [sqlite3_value_blob | sqlite3_value_type()] family of +** interfaces require protected sqlite3_value objects. +*/ +typedef struct sqlite3_value sqlite3_value; + +/* +** CAPI3REF: SQL Function Context Object +** +** The context in which an SQL function executes is stored in an +** sqlite3_context object. ^A pointer to an sqlite3_context object +** is always the first parameter to [application-defined SQL functions]. +** The application-defined SQL function implementation will pass this +** pointer through into calls to [sqlite3_result_int | sqlite3_result()], +** [sqlite3_aggregate_context()], [sqlite3_user_data()], +** [sqlite3_context_db_handle()], [sqlite3_get_auxdata()], +** and/or [sqlite3_set_auxdata()]. +*/ +typedef struct sqlite3_context sqlite3_context; + +/* +** CAPI3REF: Binding Values To Prepared Statements +** KEYWORDS: {host parameter} {host parameters} {host parameter name} +** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding} +** METHOD: sqlite3_stmt +** +** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, +** literals may be replaced by a [parameter] that matches one of the following +** templates: +** +**
      +**
    • ? +**
    • ?NNN +**
    • :VVV +**
    • @VVV +**
    • $VVV +**
    +** +** In the templates above, NNN represents an integer literal, +** and VVV represents an alphanumeric identifier.)^ ^The values of these +** parameters (also called "host parameter names" or "SQL parameters") +** can be set using the sqlite3_bind_*() routines defined here. +** +** ^The first argument to the sqlite3_bind_*() routines is always +** a pointer to the [sqlite3_stmt] object returned from +** [sqlite3_prepare_v2()] or its variants. +** +** ^The second argument is the index of the SQL parameter to be set. +** ^The leftmost SQL parameter has an index of 1. ^When the same named +** SQL parameter is used more than once, second and subsequent +** occurrences have the same index as the first occurrence. +** ^The index for named parameters can be looked up using the +** [sqlite3_bind_parameter_index()] API if desired. ^The index +** for "?NNN" parameters is the value of NNN. +** ^The NNN value must be between 1 and the [sqlite3_limit()] +** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 32766). +** +** ^The third argument is the value to bind to the parameter. +** ^If the third parameter to sqlite3_bind_text() or sqlite3_bind_text16() +** or sqlite3_bind_blob() is a NULL pointer then the fourth parameter +** is ignored and the end result is the same as sqlite3_bind_null(). +** ^If the third parameter to sqlite3_bind_text() is not NULL, then +** it should be a pointer to well-formed UTF8 text. +** ^If the third parameter to sqlite3_bind_text16() is not NULL, then +** it should be a pointer to well-formed UTF16 text. +** ^If the third parameter to sqlite3_bind_text64() is not NULL, then +** it should be a pointer to a well-formed unicode string that is +** either UTF8 if the sixth parameter is SQLITE_UTF8 or SQLITE_UTF8_ZT, +** or UTF16 otherwise. +** +** [[byte-order determination rules]] ^The byte-order of +** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF) +** found in the first character, which is removed, or in the absence of a BOM +** the byte order is the native byte order of the host +** machine for sqlite3_bind_text16() or the byte order specified in +** the 6th parameter for sqlite3_bind_text64().)^ +** ^If UTF16 input text contains invalid unicode +** characters, then SQLite might change those invalid characters +** into the unicode replacement character: U+FFFD. +** +** ^(In those routines that have a fourth argument, its value is the +** number of bytes in the parameter. To be clear: the value is the +** number of bytes in the value, not the number of characters.)^ +** ^If the fourth parameter to sqlite3_bind_text() or sqlite3_bind_text16() +** is negative, then the length of the string is +** the number of bytes up to the first zero terminator. +** If the fourth parameter to sqlite3_bind_blob() is negative, then +** the behavior is undefined. +** If a non-negative fourth parameter is provided to sqlite3_bind_text() +** or sqlite3_bind_text16() or sqlite3_bind_text64() then +** that parameter must be the byte offset +** where the NUL terminator would occur assuming the string were NUL +** terminated. If any NUL characters occur at byte offsets less than +** the value of the fourth parameter then the resulting string value will +** contain embedded NULs. The result of expressions involving strings +** with embedded NULs is undefined. +** +** ^The fifth argument to the BLOB and string binding interfaces controls +** or indicates the lifetime of the object referenced by the third parameter. +** These three options exist: +** ^ (1) A destructor to dispose of the BLOB or string after SQLite has finished +** with it may be passed. ^It is called to dispose of the BLOB or string even +** if the call to the bind API fails, except the destructor is not called if +** the third parameter is a NULL pointer or the fourth parameter is negative. +** ^ (2) The special constant, [SQLITE_STATIC], may be passed to indicate that +** the application remains responsible for disposing of the object. ^In this +** case, the object and the provided pointer to it must remain valid until +** either the prepared statement is finalized or the same SQL parameter is +** bound to something else, whichever occurs sooner. +** ^ (3) The constant, [SQLITE_TRANSIENT], may be passed to indicate that the +** object is to be copied prior to the return from sqlite3_bind_*(). ^The +** object and pointer to it must remain valid until then. ^SQLite will then +** manage the lifetime of its private copy. +** +** ^The sixth argument (the E argument) +** to sqlite3_bind_text64(S,K,Z,N,D,E) must be one of +** [SQLITE_UTF8], [SQLITE_UTF8_ZT], [SQLITE_UTF16], [SQLITE_UTF16BE], +** or [SQLITE_UTF16LE] to specify the encoding of the text in the +** third parameter, Z. The special value [SQLITE_UTF8_ZT] means that the +** string argument is both UTF-8 encoded and is zero-terminated. In other +** words, SQLITE_UTF8_ZT means that the Z array is allocated to hold at +** least N+1 bytes and that the Z[N] byte is zero. If +** the E argument to sqlite3_bind_text64(S,K,Z,N,D,E) is not one of the +** allowed values shown above, or if the text encoding is different +** from the encoding specified by the sixth parameter, then the behavior +** is undefined. +** +** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that +** is filled with zeroes. ^A zeroblob uses a fixed amount of memory +** (just an integer to hold its size) while it is being processed. +** Zeroblobs are intended to serve as placeholders for BLOBs whose +** content is later written using +** [sqlite3_blob_open | incremental BLOB I/O] routines. +** ^A negative value for the zeroblob results in a zero-length BLOB. +** +** ^The sqlite3_bind_pointer(S,I,P,T,D) routine causes the I-th parameter in +** [prepared statement] S to have an SQL value of NULL, but to also be +** associated with the pointer P of type T. ^D is either a NULL pointer or +** a pointer to a destructor function for P. ^SQLite will invoke the +** destructor D with a single argument of P when it is finished using +** P, even if the call to sqlite3_bind_pointer() fails. Due to a +** historical design quirk, results are undefined if D is +** SQLITE_TRANSIENT. The T parameter should be a static string, +** preferably a string literal. The sqlite3_bind_pointer() routine is +** part of the [pointer passing interface] added for SQLite 3.20.0. +** +** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer +** for the [prepared statement] or with a prepared statement for which +** [sqlite3_step()] has been called more recently than [sqlite3_reset()], +** then the call will return [SQLITE_MISUSE]. If any sqlite3_bind_() +** routine is passed a [prepared statement] that has been finalized, the +** result is undefined and probably harmful. +** +** ^Bindings are not cleared by the [sqlite3_reset()] routine. +** ^Unbound parameters are interpreted as NULL. +** +** ^The sqlite3_bind_* routines return [SQLITE_OK] on success or an +** [error code] if anything goes wrong. +** ^[SQLITE_TOOBIG] might be returned if the size of a string or BLOB +** exceeds limits imposed by [sqlite3_limit]([SQLITE_LIMIT_LENGTH]) or +** [SQLITE_MAX_LENGTH]. +** ^[SQLITE_RANGE] is returned if the parameter +** index is out of range. ^[SQLITE_NOMEM] is returned if malloc() fails. +** +** See also: [sqlite3_bind_parameter_count()], +** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); +SQLITE_API int sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64, + void(*)(void*)); +SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double); +SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int); +SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); +SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int); +SQLITE_API int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*)); +SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); +SQLITE_API int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64, + void(*)(void*), unsigned char encoding); +SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); +SQLITE_API int sqlite3_bind_pointer(sqlite3_stmt*, int, void*, const char*,void(*)(void*)); +SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); +SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64); + +/* +** CAPI3REF: Number Of SQL Parameters +** METHOD: sqlite3_stmt +** +** ^This routine can be used to find the number of [SQL parameters] +** in a [prepared statement]. SQL parameters are tokens of the +** form "?", "?NNN", ":AAA", "$AAA", or "@AAA" that serve as +** placeholders for values that are [sqlite3_bind_blob | bound] +** to the parameters at a later time. +** +** ^(This routine actually returns the index of the largest (rightmost) +** parameter. For all forms except ?NNN, this will correspond to the +** number of unique parameters. If parameters of the ?NNN form are used, +** there may be gaps in the list.)^ +** +** See also: [sqlite3_bind_blob|sqlite3_bind()], +** [sqlite3_bind_parameter_name()], and +** [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*); + +/* +** CAPI3REF: Name Of A Host Parameter +** METHOD: sqlite3_stmt +** +** ^The sqlite3_bind_parameter_name(P,N) interface returns +** the name of the N-th [SQL parameter] in the [prepared statement] P. +** ^(SQL parameters of the form "?NNN" or ":AAA" or "@AAA" or "$AAA" +** have a name which is the string "?NNN" or ":AAA" or "@AAA" or "$AAA" +** respectively. +** In other words, the initial ":" or "$" or "@" or "?" +** is included as part of the name.)^ +** ^Parameters of the form "?" without a following integer have no name +** and are referred to as "nameless" or "anonymous parameters". +** +** ^The first host parameter has an index of 1, not 0. +** +** ^If the value N is out of range or if the N-th parameter is +** nameless, then NULL is returned. ^The returned string is +** always in UTF-8 encoding even if the named parameter was +** originally specified as UTF-16 in [sqlite3_prepare16()], +** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()]. +** +** See also: [sqlite3_bind_blob|sqlite3_bind()], +** [sqlite3_bind_parameter_count()], and +** [sqlite3_bind_parameter_index()]. +*/ +SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); + +/* +** CAPI3REF: Index Of A Parameter With A Given Name +** METHOD: sqlite3_stmt +** +** ^Return the index of an SQL parameter given its name. ^The +** index value returned is suitable for use as the second +** parameter to [sqlite3_bind_blob|sqlite3_bind()]. ^A zero +** is returned if no matching parameter is found. ^The parameter +** name must be given in UTF-8 even if the original statement +** was prepared from UTF-16 text using [sqlite3_prepare16_v2()] or +** [sqlite3_prepare16_v3()]. +** +** See also: [sqlite3_bind_blob|sqlite3_bind()], +** [sqlite3_bind_parameter_count()], and +** [sqlite3_bind_parameter_name()]. +*/ +SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); + +/* +** CAPI3REF: Reset All Bindings On A Prepared Statement +** METHOD: sqlite3_stmt +** +** ^Contrary to the intuition of many, [sqlite3_reset()] does not reset +** the [sqlite3_bind_blob | bindings] on a [prepared statement]. +** ^Use this routine to reset all host parameters to NULL. +*/ +SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*); + +/* +** CAPI3REF: Number Of Columns In A Result Set +** METHOD: sqlite3_stmt +** +** ^Return the number of columns in the result set returned by the +** [prepared statement]. ^If this routine returns 0, that means the +** [prepared statement] returns no data (for example an [UPDATE]). +** ^However, just because this routine returns a positive number does not +** mean that one or more rows of data will be returned. ^A SELECT statement +** will always have a positive sqlite3_column_count() but depending on the +** WHERE clause constraints and the table content, it might return no rows. +** +** See also: [sqlite3_data_count()] +*/ +SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Column Names In A Result Set +** METHOD: sqlite3_stmt +** +** ^These routines return the name assigned to a particular column +** in the result set of a [SELECT] statement. ^The sqlite3_column_name() +** interface returns a pointer to a zero-terminated UTF-8 string +** and sqlite3_column_name16() returns a pointer to a zero-terminated +** UTF-16 string. ^The first parameter is the [prepared statement] +** that implements the [SELECT] statement. ^The second parameter is the +** column number. ^The leftmost column is number 0. +** +** ^The returned string pointer is valid until either the [prepared statement] +** is destroyed by [sqlite3_finalize()] or until the statement is automatically +** reprepared by the first call to [sqlite3_step()] for a particular run +** or until the next call to +** sqlite3_column_name() or sqlite3_column_name16() on the same column. +** +** ^If sqlite3_malloc() fails during the processing of either routine +** (for example during a conversion from UTF-8 to UTF-16) then a +** NULL pointer is returned. +** +** ^The name of a result column is the value of the "AS" clause for +** that column, if there is an AS clause. If there is no AS clause +** then the name of the column is unspecified and may change from +** one release of SQLite to the next. +*/ +SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N); +SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N); + +/* +** CAPI3REF: Source Of Data In A Query Result +** METHOD: sqlite3_stmt +** +** ^These routines provide a means to determine the database, table, and +** table column that is the origin of a particular result column in a +** [SELECT] statement. +** ^The name of the database or table or column can be returned as +** either a UTF-8 or UTF-16 string. ^The _database_ routines return +** the database name, the _table_ routines return the table name, and +** the origin_ routines return the column name. +** ^The returned string is valid until the [prepared statement] is destroyed +** using [sqlite3_finalize()] or until the statement is automatically +** reprepared by the first call to [sqlite3_step()] for a particular run +** or until the same information is requested +** again in a different encoding. +** +** ^The names returned are the original un-aliased names of the +** database, table, and column. +** +** ^The first argument to these interfaces is a [prepared statement]. +** ^These functions return information about the Nth result column returned by +** the statement, where N is the second function argument. +** ^The left-most column is column 0 for these routines. +** +** ^If the Nth column returned by the statement is an expression or +** subquery and is not a column value, then all of these functions return +** NULL. ^These routines might also return NULL if a memory allocation error +** occurs. ^Otherwise, they return the name of the attached database, table, +** or column that query result column was extracted from. +** +** ^As with all other SQLite APIs, those whose names end with "16" return +** UTF-16 encoded strings and the other functions return UTF-8. +** +** ^These APIs are only available if the library was compiled with the +** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol. +** +** If two or more threads call one or more +** [sqlite3_column_database_name | column metadata interfaces] +** for the same [prepared statement] and result column +** at the same time then the results are undefined. +*/ +SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int); +SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int); +SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Declared Datatype Of A Query Result +** METHOD: sqlite3_stmt +** +** ^(The first parameter is a [prepared statement]. +** If this statement is a [SELECT] statement and the Nth column of the +** returned result set of that [SELECT] is a table column (not an +** expression or subquery) then the declared type of the table +** column is returned.)^ ^If the Nth column of the result set is an +** expression or subquery, then a NULL pointer is returned. +** ^The returned string is always UTF-8 encoded. +** +** ^(For example, given the database schema: +** +** CREATE TABLE t1(c1 VARIANT); +** +** and the following statement to be compiled: +** +** SELECT c1 + 1, c1 FROM t1; +** +** this routine would return the string "VARIANT" for the second result +** column (i==1), and a NULL pointer for the first result column (i==0).)^ +** +** ^SQLite uses dynamic run-time typing. ^So just because a column +** is declared to contain a particular type does not mean that the +** data stored in that column is of the declared type. SQLite is +** strongly typed, but the typing is dynamic not static. ^Type +** is associated with individual values, not with the containers +** used to hold those values. +*/ +SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); + +/* +** CAPI3REF: Evaluate An SQL Statement +** METHOD: sqlite3_stmt +** +** After a [prepared statement] has been prepared using any of +** [sqlite3_prepare_v2()], [sqlite3_prepare_v3()], [sqlite3_prepare16_v2()], +** or [sqlite3_prepare16_v3()] or one of the legacy +** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function +** must be called one or more times to evaluate the statement. +** +** The details of the behavior of the sqlite3_step() interface depend +** on whether the statement was prepared using the newer "vX" interfaces +** [sqlite3_prepare_v3()], [sqlite3_prepare_v2()], [sqlite3_prepare16_v3()], +** [sqlite3_prepare16_v2()] or the older legacy +** interfaces [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the +** new "vX" interface is recommended for new applications but the legacy +** interface will continue to be supported. +** +** ^In the legacy interface, the return value will be either [SQLITE_BUSY], +** [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE]. +** ^With the "v2" interface, any of the other [result codes] or +** [extended result codes] might be returned as well. +** +** ^[SQLITE_BUSY] means that the database engine was unable to acquire the +** database locks it needs to do its job. ^If the statement is a [COMMIT] +** or occurs outside of an explicit transaction, then you can retry the +** statement. If the statement is not a [COMMIT] and occurs within an +** explicit transaction then you should rollback the transaction before +** continuing. +** +** ^[SQLITE_DONE] means that the statement has finished executing +** successfully. sqlite3_step() should not be called again on this virtual +** machine without first calling [sqlite3_reset()] to reset the virtual +** machine back to its initial state. +** +** ^If the SQL statement being executed returns any data, then [SQLITE_ROW] +** is returned each time a new row of data is ready for processing by the +** caller. The values may be accessed using the [column access functions]. +** sqlite3_step() is called again to retrieve the next row of data. +** +** ^[SQLITE_ERROR] means that a run-time error (such as a constraint +** violation) has occurred. sqlite3_step() should not be called again on +** the VM. More information may be found by calling [sqlite3_errmsg()]. +** ^With the legacy interface, a more specific error code (for example, +** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth) +** can be obtained by calling [sqlite3_reset()] on the +** [prepared statement]. ^In the "v2" interface, +** the more specific error code is returned directly by sqlite3_step(). +** +** [SQLITE_MISUSE] means that the this routine was called inappropriately. +** Perhaps it was called on a [prepared statement] that has +** already been [sqlite3_finalize | finalized] or on one that had +** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could +** be the case that the same database connection is being used by two or +** more threads at the same moment in time. +** +** For all versions of SQLite up to and including 3.6.23.1, a call to +** [sqlite3_reset()] was required after sqlite3_step() returned anything +** other than [SQLITE_ROW] before any subsequent invocation of +** sqlite3_step(). Failure to reset the prepared statement using +** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from +** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1]), +** sqlite3_step() began +** calling [sqlite3_reset()] automatically in this circumstance rather +** than returning [SQLITE_MISUSE]. This is not considered a compatibility +** break because any application that ever receives an SQLITE_MISUSE error +** is broken by definition. The [SQLITE_OMIT_AUTORESET] compile-time option +** can be used to restore the legacy behavior. +** +** Goofy Interface Alert: In the legacy interface, the sqlite3_step() +** API always returns a generic error code, [SQLITE_ERROR], following any +** error other than [SQLITE_BUSY] and [SQLITE_MISUSE]. You must call +** [sqlite3_reset()] or [sqlite3_finalize()] in order to find one of the +** specific [error codes] that better describes the error. +** We admit that this is a goofy design. The problem has been fixed +** with the "v2" interface. If you prepare all of your SQL statements +** using [sqlite3_prepare_v3()] or [sqlite3_prepare_v2()] +** or [sqlite3_prepare16_v2()] or [sqlite3_prepare16_v3()] instead +** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces, +** then the more specific [error codes] are returned directly +** by sqlite3_step(). The use of the "vX" interfaces is recommended. +*/ +SQLITE_API int sqlite3_step(sqlite3_stmt*); + +/* +** CAPI3REF: Number of columns in a result set +** METHOD: sqlite3_stmt +** +** ^The sqlite3_data_count(P) interface returns the number of columns in the +** current row of the result set of [prepared statement] P. +** ^If prepared statement P does not have results ready to return +** (via calls to the [sqlite3_column_int | sqlite3_column()] family of +** interfaces) then sqlite3_data_count(P) returns 0. +** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer. +** ^The sqlite3_data_count(P) routine returns 0 if the previous call to +** [sqlite3_step](P) returned [SQLITE_DONE]. ^The sqlite3_data_count(P) +** will return non-zero if previous call to [sqlite3_step](P) returned +** [SQLITE_ROW], except in the case of the [PRAGMA incremental_vacuum] +** where it always returns zero since each step of that multi-step +** pragma returns 0 columns of data. +** +** See also: [sqlite3_column_count()] +*/ +SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Fundamental Datatypes +** KEYWORDS: SQLITE_TEXT +** +** ^(Every value in SQLite has one of five fundamental datatypes: +** +**
      +**
    • 64-bit signed integer +**
    • 64-bit IEEE floating point number +**
    • string +**
    • BLOB +**
    • NULL +**
    )^ +** +** These constants are codes for each of those types. +** +** Note that the SQLITE_TEXT constant was also used in SQLite version 2 +** for a completely different meaning. Software that links against both +** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT, not +** SQLITE_TEXT. +*/ +#define SQLITE_INTEGER 1 +#define SQLITE_FLOAT 2 +#define SQLITE_BLOB 4 +#define SQLITE_NULL 5 +#ifdef SQLITE_TEXT +# undef SQLITE_TEXT +#else +# define SQLITE_TEXT 3 +#endif +#define SQLITE3_TEXT 3 + +/* +** CAPI3REF: Result Values From A Query +** KEYWORDS: {column access functions} +** METHOD: sqlite3_stmt +** +** Summary: +**
    +**
    sqlite3_column_blobBLOB result +**
    sqlite3_column_doubleREAL result +**
    sqlite3_column_int32-bit INTEGER result +**
    sqlite3_column_int6464-bit INTEGER result +**
    sqlite3_column_textUTF-8 TEXT result +**
    sqlite3_column_text16UTF-16 TEXT result +**
    sqlite3_column_valueThe result as an +** [sqlite3_value|unprotected sqlite3_value] object. +**
        +**
    sqlite3_column_bytesSize of a BLOB +** or a UTF-8 TEXT result in bytes +**
    sqlite3_column_bytes16   +** →  Size of UTF-16 +** TEXT in bytes +**
    sqlite3_column_typeDefault +** datatype of the result +**
    +** +** Details: +** +** ^These routines return information about a single column of the current +** result row of a query. ^In every case the first argument is a pointer +** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*] +** that was returned from [sqlite3_prepare_v2()] or one of its variants) +** and the second argument is the index of the column for which information +** should be returned. ^The leftmost column of the result set has the index 0. +** ^The number of columns in the result can be determined using +** [sqlite3_column_count()]. +** +** If the SQL statement does not currently point to a valid row, or if the +** column index is out of range, the result is undefined. +** These routines may only be called when the most recent call to +** [sqlite3_step()] has returned [SQLITE_ROW] and neither +** [sqlite3_reset()] nor [sqlite3_finalize()] have been called subsequently. +** If any of these routines are called after [sqlite3_reset()] or +** [sqlite3_finalize()] or after [sqlite3_step()] has returned +** something other than [SQLITE_ROW], the results are undefined. +** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()] +** are called from a different thread while any of these routines +** are pending, then the results are undefined. +** +** The first six interfaces (_blob, _double, _int, _int64, _text, and _text16) +** each return the value of a result column in a specific data format. If +** the result column is not initially in the requested format (for example, +** if the query returns an integer but the sqlite3_column_text() interface +** is used to extract the value) then an automatic type conversion is performed. +** +** ^The sqlite3_column_type() routine returns the +** [SQLITE_INTEGER | datatype code] for the initial data type +** of the result column. ^The returned value is one of [SQLITE_INTEGER], +** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. +** The return value of sqlite3_column_type() can be used to decide which +** of the first six interface should be used to extract the column value. +** The value returned by sqlite3_column_type() is only meaningful if no +** automatic type conversions have occurred for the value in question. +** After a type conversion, the result of calling sqlite3_column_type() +** is undefined, though harmless. Future +** versions of SQLite may change the behavior of sqlite3_column_type() +** following a type conversion. +** +** If the result is a BLOB or a TEXT string, then the sqlite3_column_bytes() +** or sqlite3_column_bytes16() interfaces can be used to determine the size +** of that BLOB or string. +** +** ^If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes() +** routine returns the number of bytes in that BLOB or string. +** ^If the result is a UTF-16 string, then sqlite3_column_bytes() converts +** the string to UTF-8 and then returns the number of bytes. +** ^If the result is a numeric value then sqlite3_column_bytes() uses +** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns +** the number of bytes in that string. +** ^If the result is NULL, then sqlite3_column_bytes() returns zero. +** +** ^If the result is a BLOB or UTF-16 string then the sqlite3_column_bytes16() +** routine returns the number of bytes in that BLOB or string. +** ^If the result is a UTF-8 string, then sqlite3_column_bytes16() converts +** the string to UTF-16 and then returns the number of bytes. +** ^If the result is a numeric value then sqlite3_column_bytes16() uses +** [sqlite3_snprintf()] to convert that value to a UTF-16 string and returns +** the number of bytes in that string. +** ^If the result is NULL, then sqlite3_column_bytes16() returns zero. +** +** ^The values returned by [sqlite3_column_bytes()] and +** [sqlite3_column_bytes16()] do not include the zero terminators at the end +** of the string. ^For clarity: the values returned by +** [sqlite3_column_bytes()] and [sqlite3_column_bytes16()] are the number of +** bytes in the string, not the number of characters. +** +** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(), +** even empty strings, are always zero-terminated. ^The return +** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer. +** +** ^Strings returned by sqlite3_column_text16() always have the endianness +** which is native to the platform, regardless of the text encoding set +** for the database. +** +** Warning: ^The object returned by [sqlite3_column_value()] is an +** [unprotected sqlite3_value] object. In a multithreaded environment, +** an unprotected sqlite3_value object may only be used safely with +** [sqlite3_bind_value()] and [sqlite3_result_value()]. +** If the [unprotected sqlite3_value] object returned by +** [sqlite3_column_value()] is used in any other way, including calls +** to routines like [sqlite3_value_int()], [sqlite3_value_text()], +** or [sqlite3_value_bytes()], the behavior is not threadsafe. +** Hence, the sqlite3_column_value() interface +** is normally only useful within the implementation of +** [application-defined SQL functions] or [virtual tables], not within +** top-level application code. +** +** These routines may attempt to convert the datatype of the result. +** ^For example, if the internal representation is FLOAT and a text result +** is requested, [sqlite3_snprintf()] is used internally to perform the +** conversion automatically. ^(The following table details the conversions +** that are applied: +** +**
    +** +**
    Internal
    Type
    Requested
    Type
    Conversion +** +**
    NULL INTEGER Result is 0 +**
    NULL FLOAT Result is 0.0 +**
    NULL TEXT Result is a NULL pointer +**
    NULL BLOB Result is a NULL pointer +**
    INTEGER FLOAT Convert from integer to float +**
    INTEGER TEXT ASCII rendering of the integer +**
    INTEGER BLOB Same as INTEGER->TEXT +**
    FLOAT INTEGER [CAST] to INTEGER +**
    FLOAT TEXT ASCII rendering of the float +**
    FLOAT BLOB [CAST] to BLOB +**
    TEXT INTEGER [CAST] to INTEGER +**
    TEXT FLOAT [CAST] to REAL +**
    TEXT BLOB No change +**
    BLOB INTEGER [CAST] to INTEGER +**
    BLOB FLOAT [CAST] to REAL +**
    BLOB TEXT [CAST] to TEXT, ensure zero terminator +**
    +**
    )^ +** +** Note that when type conversions occur, pointers returned by prior +** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or +** sqlite3_column_text16() may be invalidated. +** Type conversions and pointer invalidations might occur +** in the following cases: +** +**
      +**
    • The initial content is a BLOB and sqlite3_column_text() or +** sqlite3_column_text16() is called. A zero-terminator might +** need to be added to the string.
    • +**
    • The initial content is UTF-8 text and sqlite3_column_bytes16() or +** sqlite3_column_text16() is called. The content must be converted +** to UTF-16.
    • +**
    • The initial content is UTF-16 text and sqlite3_column_bytes() or +** sqlite3_column_text() is called. The content must be converted +** to UTF-8.
    • +**
    +** +** ^Conversions between UTF-16be and UTF-16le are always done in place and do +** not invalidate a prior pointer, though of course the content of the buffer +** that the prior pointer references will have been modified. Other kinds +** of conversion are done in place when it is possible, but sometimes they +** are not possible and in those cases prior pointers are invalidated. +** +** The safest policy is to invoke these routines +** in one of the following ways: +** +**
      +**
    • sqlite3_column_text() followed by sqlite3_column_bytes()
    • +**
    • sqlite3_column_blob() followed by sqlite3_column_bytes()
    • +**
    • sqlite3_column_text16() followed by sqlite3_column_bytes16()
    • +**
    +** +** In other words, you should call sqlite3_column_text(), +** sqlite3_column_blob(), or sqlite3_column_text16() first to force the result +** into the desired format, then invoke sqlite3_column_bytes() or +** sqlite3_column_bytes16() to find the size of the result. Do not mix calls +** to sqlite3_column_text() or sqlite3_column_blob() with calls to +** sqlite3_column_bytes16(), and do not mix calls to sqlite3_column_text16() +** with calls to sqlite3_column_bytes(). +** +** ^The pointers returned are valid until a type conversion occurs as +** described above, or until [sqlite3_step()] or [sqlite3_reset()] or +** [sqlite3_finalize()] is called. ^The memory space used to hold strings +** and BLOBs is freed automatically. Do not pass the pointers returned +** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into +** [sqlite3_free()]. +** +** As long as the input parameters are correct, these routines will only +** fail if an out-of-memory error occurs during a format conversion. +** Only the following subset of interfaces are subject to out-of-memory +** errors: +** +**
      +**
    • sqlite3_column_blob() +**
    • sqlite3_column_text() +**
    • sqlite3_column_text16() +**
    • sqlite3_column_bytes() +**
    • sqlite3_column_bytes16() +**
    +** +** If an out-of-memory error occurs, then the return value from these +** routines is the same as if the column had contained an SQL NULL value. +** Valid SQL NULL returns can be distinguished from out-of-memory errors +** by invoking the [sqlite3_errcode()] immediately after the suspect +** return value is obtained and before any +** other SQLite interface is called on the same [database connection]. +*/ +SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); +SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol); +SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); +SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); +SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); +SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol); + +/* +** CAPI3REF: Destroy A Prepared Statement Object +** DESTRUCTOR: sqlite3_stmt +** +** ^The sqlite3_finalize() function is called to delete a [prepared statement]. +** ^If the most recent evaluation of the statement encountered no errors +** or if the statement has never been evaluated, then sqlite3_finalize() returns +** SQLITE_OK. ^If the most recent evaluation of statement S failed, then +** sqlite3_finalize(S) returns the appropriate [error code] or +** [extended error code]. +** +** ^The sqlite3_finalize(S) routine can be called at any point during +** the life cycle of [prepared statement] S: +** before statement S is ever evaluated, after +** one or more calls to [sqlite3_reset()], or after any call +** to [sqlite3_step()] regardless of whether or not the statement has +** completed execution. +** +** ^Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op. +** +** The application must finalize every [prepared statement] in order to avoid +** resource leaks. It is a grievous error for the application to try to use +** a prepared statement after it has been finalized. Any use of a prepared +** statement after it has been finalized can result in undefined and +** undesirable behavior such as segfaults and heap corruption. +*/ +SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Reset A Prepared Statement Object +** METHOD: sqlite3_stmt +** +** The sqlite3_reset() function is called to reset a [prepared statement] +** object back to its initial state, ready to be re-executed. +** ^Any SQL statement variables that had values bound to them using +** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values. +** Use [sqlite3_clear_bindings()] to reset the bindings. +** +** ^The [sqlite3_reset(S)] interface resets the [prepared statement] S +** back to the beginning of its program. +** +** ^The return code from [sqlite3_reset(S)] indicates whether or not +** the previous evaluation of prepared statement S completed successfully. +** ^If [sqlite3_step(S)] has never before been called on S or if +** [sqlite3_step(S)] has not been called since the previous call +** to [sqlite3_reset(S)], then [sqlite3_reset(S)] will return +** [SQLITE_OK]. +** +** ^If the most recent call to [sqlite3_step(S)] for the +** [prepared statement] S indicated an error, then +** [sqlite3_reset(S)] returns an appropriate [error code]. +** ^The [sqlite3_reset(S)] interface might also return an [error code] +** if there were no prior errors but the process of resetting +** the prepared statement caused a new error. ^For example, if an +** [INSERT] statement with a [RETURNING] clause is only stepped one time, +** that one call to [sqlite3_step(S)] might return SQLITE_ROW but +** the overall statement might still fail and the [sqlite3_reset(S)] call +** might return SQLITE_BUSY if locking constraints prevent the +** database change from committing. Therefore, it is important that +** applications check the return code from [sqlite3_reset(S)] even if +** no prior call to [sqlite3_step(S)] indicated a problem. +** +** ^The [sqlite3_reset(S)] interface does not change the values +** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S. +*/ +SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); + + +/* +** CAPI3REF: Create Or Redefine SQL Functions +** KEYWORDS: {function creation routines} +** METHOD: sqlite3 +** +** ^These functions (collectively known as "function creation routines") +** are used to add SQL functions or aggregates or to redefine the behavior +** of existing SQL functions or aggregates. The only differences between +** the three "sqlite3_create_function*" routines are the text encoding +** expected for the second parameter (the name of the function being +** created) and the presence or absence of a destructor callback for +** the application data pointer. Function sqlite3_create_window_function() +** is similar, but allows the user to supply the extra callback functions +** needed by [aggregate window functions]. +** +** ^The first parameter is the [database connection] to which the SQL +** function is to be added. ^If an application uses more than one database +** connection then application-defined SQL functions must be added +** to each database connection separately. +** +** ^The second parameter is the name of the SQL function to be created or +** redefined. ^The length of the name is limited to 255 bytes in a UTF-8 +** representation, exclusive of the zero-terminator. ^Note that the name +** length limit is in UTF-8 bytes, not characters nor UTF-16 bytes. +** ^Any attempt to create a function with a longer name +** will result in [SQLITE_MISUSE] being returned. +** +** ^The third parameter (nArg) +** is the number of arguments that the SQL function or +** aggregate takes. ^If this parameter is -1, then the SQL function or +** aggregate may take any number of arguments between 0 and the limit +** set by [sqlite3_limit]([SQLITE_LIMIT_FUNCTION_ARG]). If the third +** parameter is less than -1 or greater than 127 then the behavior is +** undefined. +** +** ^The fourth parameter, eTextRep, specifies what +** [SQLITE_UTF8 | text encoding] this SQL function prefers for +** its parameters. The application should set this parameter to +** [SQLITE_UTF16LE] if the function implementation invokes +** [sqlite3_value_text16le()] on an input, or [SQLITE_UTF16BE] if the +** implementation invokes [sqlite3_value_text16be()] on an input, or +** [SQLITE_UTF16] if [sqlite3_value_text16()] is used, or [SQLITE_UTF8] +** otherwise. ^The same SQL function may be registered multiple times using +** different preferred text encodings, with different implementations for +** each encoding. +** ^When multiple implementations of the same function are available, SQLite +** will pick the one that involves the least amount of data conversion. +** +** ^The fourth parameter may optionally be ORed with [SQLITE_DETERMINISTIC] +** to signal that the function will always return the same result given +** the same inputs within a single SQL statement. Most SQL functions are +** deterministic. The built-in [random()] SQL function is an example of a +** function that is not deterministic. The SQLite query planner is able to +** perform additional optimizations on deterministic functions, so use +** of the [SQLITE_DETERMINISTIC] flag is recommended where possible. +** +** ^The fourth parameter may also optionally include the [SQLITE_DIRECTONLY] +** flag, which if present prevents the function from being invoked from +** within VIEWs, TRIGGERs, CHECK constraints, generated column expressions, +** index expressions, or the WHERE clause of partial indexes. +** +** For best security, the [SQLITE_DIRECTONLY] flag is recommended for +** all application-defined SQL functions that do not need to be +** used inside of triggers, views, CHECK constraints, or other elements of +** the database schema. This flag is especially recommended for SQL +** functions that have side effects or reveal internal application state. +** Without this flag, an attacker might be able to modify the schema of +** a database file to include invocations of the function with parameters +** chosen by the attacker, which the application will then execute when +** the database file is opened and read. +** +** ^(The fifth parameter is an arbitrary pointer. The implementation of the +** function can gain access to this pointer using [sqlite3_user_data()].)^ +** +** ^The sixth, seventh and eighth parameters passed to the three +** "sqlite3_create_function*" functions, xFunc, xStep and xFinal, are +** pointers to C-language functions that implement the SQL function or +** aggregate. ^A scalar SQL function requires an implementation of the xFunc +** callback only; NULL pointers must be passed as the xStep and xFinal +** parameters. ^An aggregate SQL function requires an implementation of xStep +** and xFinal and NULL pointer must be passed for xFunc. ^To delete an existing +** SQL function or aggregate, pass NULL pointers for all three function +** callbacks. +** +** ^The sixth, seventh, eighth and ninth parameters (xStep, xFinal, xValue +** and xInverse) passed to sqlite3_create_window_function are pointers to +** C-language callbacks that implement the new function. xStep and xFinal +** must both be non-NULL. xValue and xInverse may either both be NULL, in +** which case a regular aggregate function is created, or must both be +** non-NULL, in which case the new function may be used as either an aggregate +** or aggregate window function. More details regarding the implementation +** of aggregate window functions are +** [user-defined window functions|available here]. +** +** ^(If the final parameter to sqlite3_create_function_v2() or +** sqlite3_create_window_function() is not NULL, then it is the destructor for +** the application data pointer. The destructor is invoked when the function +** is deleted, either by being overloaded or when the database connection +** closes.)^ ^The destructor is also invoked if the call to +** sqlite3_create_function_v2() fails. ^When the destructor callback is +** invoked, it is passed a single argument which is a copy of the application +** data pointer which was the fifth parameter to sqlite3_create_function_v2(). +** +** ^It is permitted to register multiple implementations of the same +** functions with the same name but with either differing numbers of +** arguments or differing preferred text encodings. ^SQLite will use +** the implementation that most closely matches the way in which the +** SQL function is used. ^A function implementation with a non-negative +** nArg parameter is a better match than a function implementation with +** a negative nArg. ^A function where the preferred text encoding +** matches the database encoding is a better +** match than a function where the encoding is different. +** ^A function where the encoding difference is between UTF16le and UTF16be +** is a closer match than a function where the encoding difference is +** between UTF8 and UTF16. +** +** ^Built-in functions may be overloaded by new application-defined functions. +** +** ^An application-defined function is permitted to call other +** SQLite interfaces. However, such calls must not +** close the database connection nor finalize or reset the prepared +** statement in which the function is running. +*/ +SQLITE_API int sqlite3_create_function( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); +SQLITE_API int sqlite3_create_function16( + sqlite3 *db, + const void *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); +SQLITE_API int sqlite3_create_function_v2( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void(*xDestroy)(void*) +); +SQLITE_API int sqlite3_create_window_function( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void (*xValue)(sqlite3_context*), + void (*xInverse)(sqlite3_context*,int,sqlite3_value**), + void(*xDestroy)(void*) +); + +/* +** CAPI3REF: Text Encodings +** +** These constants define integer codes that represent the various +** text encodings supported by SQLite. +** +**
    +** [[SQLITE_UTF8]]
    SQLITE_UTF8
    Text is encoding as UTF-8
    +** +** [[SQLITE_UTF16LE]]
    SQLITE_UTF16LE
    Text is encoding as UTF-16 +** with each code point being expressed "little endian" - the least significant +** byte first. This is the usual encoding, for example on Windows.
    +** +** [[SQLITE_UTF16BE]]
    SQLITE_UTF16BE
    Text is encoding as UTF-16 +** with each code point being expressed "big endian" - the most significant +** byte first. This encoding is less common, but is still sometimes seen, +** specially on older systems. +** +** [[SQLITE_UTF16]]
    SQLITE_UTF16
    Text is encoding as UTF-16 +** with each code point being expressed either little endian or as big +** endian, according to the native endianness of the host computer. +** +** [[SQLITE_ANY]]
    SQLITE_ANY
    This encoding value may only be used +** to declare the preferred text for [application-defined SQL functions] +** created using [sqlite3_create_function()] and similar. If the preferred +** encoding (the 4th parameter to sqlite3_create_function() - the eTextRep +** parameter) is SQLITE_ANY, that indicates that the function does not have +** a preference regarding the text encoding of its parameters and can take +** any text encoding that the SQLite core find convenient to supply. This +** option is deprecated. Please do not use it in new applications. +** +** [[SQLITE_UTF16_ALIGNED]]
    SQLITE_UTF16_ALIGNED
    This encoding +** value may be used as the 3rd parameter (the eTextRep parameter) to +** [sqlite3_create_collation()] and similar. This encoding value means +** that the application-defined collating sequence created expects its +** input strings to be in UTF16 in native byte order, and that the start +** of the strings must be aligned to a 2-byte boundary. +** +** [[SQLITE_UTF8_ZT]]
    SQLITE_UTF8_ZT
    This option can only be +** used to specify the text encoding to strings input to +** [sqlite3_result_text64()] and [sqlite3_bind_text64()]. +** The SQLITE_UTF8_ZT encoding means that the input string (call it "z") +** is UTF-8 encoded and that it is zero-terminated. If the length parameter +** (call it "n") is non-negative, this encoding option means that the caller +** guarantees that z array contains at least n+1 bytes and that the z[n] +** byte has a value of zero. +** This option gives the same output as SQLITE_UTF8, but can be more efficient +** by avoiding the need to make a copy of the input string, in some cases. +** However, if z is allocated to hold fewer than n+1 bytes or if the +** z[n] byte is not zero, undefined behavior may result. +**
    +*/ +#define SQLITE_UTF8 1 /* IMP: R-37514-35566 */ +#define SQLITE_UTF16LE 2 /* IMP: R-03371-37637 */ +#define SQLITE_UTF16BE 3 /* IMP: R-51971-34154 */ +#define SQLITE_UTF16 4 /* Use native byte order */ +#define SQLITE_ANY 5 /* Deprecated */ +#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ +#define SQLITE_UTF8_ZT 16 /* Zero-terminated UTF8 */ + +/* +** CAPI3REF: Function Flags +** +** These constants may be ORed together with the +** [SQLITE_UTF8 | preferred text encoding] as the fourth argument +** to [sqlite3_create_function()], [sqlite3_create_function16()], or +** [sqlite3_create_function_v2()]. +** +**
    +** [[SQLITE_DETERMINISTIC]]
    SQLITE_DETERMINISTIC
    +** The SQLITE_DETERMINISTIC flag means that the new function always gives +** the same output when the input parameters are the same. +** The [abs|abs() function] is deterministic, for example, but +** [randomblob|randomblob()] is not. Functions must +** be deterministic in order to be used in certain contexts such as +** with the WHERE clause of [partial indexes] or in [generated columns]. +** SQLite might also optimize deterministic functions by factoring them +** out of inner loops. +**
    +** +** [[SQLITE_DIRECTONLY]]
    SQLITE_DIRECTONLY
    +** The SQLITE_DIRECTONLY flag means that the function may only be invoked +** from top-level SQL, and cannot be used in VIEWs or TRIGGERs nor in +** schema structures such as [CHECK constraints], [DEFAULT clauses], +** [expression indexes], [partial indexes], or [generated columns]. +**

    +** The SQLITE_DIRECTONLY flag is recommended for any +** [application-defined SQL function] +** that has side-effects or that could potentially leak sensitive information. +** This will prevent attacks in which an application is tricked +** into using a database file that has had its schema surreptitiously +** modified to invoke the application-defined function in ways that are +** harmful. +**

    +** Some people say it is good practice to set SQLITE_DIRECTONLY on all +** [application-defined SQL functions], regardless of whether or not they +** are security sensitive, as doing so prevents those functions from being used +** inside of the database schema, and thus ensures that the database +** can be inspected and modified using generic tools (such as the [CLI]) +** that do not have access to the application-defined functions. +**

    +** +** [[SQLITE_INNOCUOUS]]
    SQLITE_INNOCUOUS
    +** The SQLITE_INNOCUOUS flag means that the function is unlikely +** to cause problems even if misused. An innocuous function should have +** no side effects and should not depend on any values other than its +** input parameters. The [abs|abs() function] is an example of an +** innocuous function. +** The [load_extension() SQL function] is not innocuous because of its +** side effects. +**

    SQLITE_INNOCUOUS is similar to SQLITE_DETERMINISTIC, but is not +** exactly the same. The [random|random() function] is an example of a +** function that is innocuous but not deterministic. +**

    Some heightened security settings +** ([SQLITE_DBCONFIG_TRUSTED_SCHEMA] and [PRAGMA trusted_schema=OFF]) +** disable the use of SQL functions inside views and triggers and in +** schema structures such as [CHECK constraints], [DEFAULT clauses], +** [expression indexes], [partial indexes], and [generated columns] unless +** the function is tagged with SQLITE_INNOCUOUS. Most built-in functions +** are innocuous. Developers are advised to avoid using the +** SQLITE_INNOCUOUS flag for application-defined functions unless the +** function has been carefully audited and found to be free of potentially +** security-adverse side-effects and information-leaks. +**

    +** +** [[SQLITE_SUBTYPE]]
    SQLITE_SUBTYPE
    +** The SQLITE_SUBTYPE flag indicates to SQLite that a function might call +** [sqlite3_value_subtype()] to inspect the sub-types of its arguments. +** This flag instructs SQLite to omit some corner-case optimizations that +** might disrupt the operation of the [sqlite3_value_subtype()] function, +** causing it to return zero rather than the correct subtype(). +** All SQL functions that invoke [sqlite3_value_subtype()] should have this +** property. If the SQLITE_SUBTYPE property is omitted, then the return +** value from [sqlite3_value_subtype()] might sometimes be zero even though +** a non-zero subtype was specified by the function argument expression. +** +** [[SQLITE_RESULT_SUBTYPE]]
    SQLITE_RESULT_SUBTYPE
    +** The SQLITE_RESULT_SUBTYPE flag indicates to SQLite that a function might call +** [sqlite3_result_subtype()] to cause a sub-type to be associated with its +** result. +** Every function that invokes [sqlite3_result_subtype()] should have this +** property. If it does not, then the call to [sqlite3_result_subtype()] +** might become a no-op if the function is used as a term in an +** [expression index]. On the other hand, SQL functions that never invoke +** [sqlite3_result_subtype()] should avoid setting this property, as the +** purpose of this property is to disable certain optimizations that are +** incompatible with subtypes. +** +** [[SQLITE_SELFORDER1]]
    SQLITE_SELFORDER1
    +** The SQLITE_SELFORDER1 flag indicates that the function is an aggregate +** that internally orders the values provided to the first argument. The +** ordered-set aggregate SQL notation with a single ORDER BY term can be +** used to invoke this function. If the ordered-set aggregate notation is +** used on a function that lacks this flag, then an error is raised. Note +** that the ordered-set aggregate syntax is only available if SQLite is +** built using the -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES compile-time option. +**
    +**
    +*/ +#define SQLITE_DETERMINISTIC 0x000000800 +#define SQLITE_DIRECTONLY 0x000080000 +#define SQLITE_SUBTYPE 0x000100000 +#define SQLITE_INNOCUOUS 0x000200000 +#define SQLITE_RESULT_SUBTYPE 0x001000000 +#define SQLITE_SELFORDER1 0x002000000 + +/* +** CAPI3REF: Deprecated Functions +** DEPRECATED +** +** These functions are [deprecated]. In order to maintain +** backwards compatibility with older code, these functions continue +** to be supported. However, new applications should avoid +** the use of these functions. To encourage programmers to avoid +** these functions, we will not explain what they do. +*/ +#ifndef SQLITE_OMIT_DEPRECATED +SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*); +SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*); +SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); +SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void); +SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void); +SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int), + void*,sqlite3_int64); +#endif + +/* +** CAPI3REF: Obtaining SQL Values +** METHOD: sqlite3_value +** +** Summary: +**
    +**
    sqlite3_value_blobBLOB value +**
    sqlite3_value_doubleREAL value +**
    sqlite3_value_int32-bit INTEGER value +**
    sqlite3_value_int6464-bit INTEGER value +**
    sqlite3_value_pointerPointer value +**
    sqlite3_value_textUTF-8 TEXT value +**
    sqlite3_value_text16UTF-16 TEXT value in +** the native byteorder +**
    sqlite3_value_text16beUTF-16be TEXT value +**
    sqlite3_value_text16leUTF-16le TEXT value +**
        +**
    sqlite3_value_bytesSize of a BLOB +** or a UTF-8 TEXT in bytes +**
    sqlite3_value_bytes16   +** →  Size of UTF-16 +** TEXT in bytes +**
    sqlite3_value_typeDefault +** datatype of the value +**
    sqlite3_value_numeric_type   +** →  Best numeric datatype of the value +**
    sqlite3_value_nochange   +** →  True if the column is unchanged in an UPDATE +** against a virtual table. +**
    sqlite3_value_frombind   +** →  True if value originated from a [bound parameter] +**
    +** +** Details: +** +** These routines extract type, size, and content information from +** [protected sqlite3_value] objects. Protected sqlite3_value objects +** are used to pass parameter information into the functions that +** implement [application-defined SQL functions] and [virtual tables]. +** +** These routines work only with [protected sqlite3_value] objects. +** Any attempt to use these routines on an [unprotected sqlite3_value] +** is not threadsafe. +** +** ^These routines work just like the corresponding [column access functions] +** except that these routines take a single [protected sqlite3_value] object +** pointer instead of a [sqlite3_stmt*] pointer and an integer column number. +** +** ^The sqlite3_value_text16() interface extracts a UTF-16 string +** in the native byte-order of the host machine. ^The +** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces +** extract UTF-16 strings as big-endian and little-endian respectively. +** +** ^If [sqlite3_value] object V was initialized +** using [sqlite3_bind_pointer(S,I,P,X,D)] or [sqlite3_result_pointer(C,P,X,D)] +** and if X and Y are strings that compare equal according to strcmp(X,Y), +** then sqlite3_value_pointer(V,Y) will return the pointer P. ^Otherwise, +** sqlite3_value_pointer(V,Y) returns a NULL. The sqlite3_bind_pointer() +** routine is part of the [pointer passing interface] added for SQLite 3.20.0. +** +** ^(The sqlite3_value_type(V) interface returns the +** [SQLITE_INTEGER | datatype code] for the initial datatype of the +** [sqlite3_value] object V. The returned value is one of [SQLITE_INTEGER], +** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].)^ +** Other interfaces might change the datatype for an sqlite3_value object. +** For example, if the datatype is initially SQLITE_INTEGER and +** sqlite3_value_text(V) is called to extract a text value for that +** integer, then subsequent calls to sqlite3_value_type(V) might return +** SQLITE_TEXT. Whether or not a persistent internal datatype conversion +** occurs is undefined and may change from one release of SQLite to the next. +** +** ^(The sqlite3_value_numeric_type() interface attempts to apply +** numeric affinity to the value. This means that an attempt is +** made to convert the value to an integer or floating point. If +** such a conversion is possible without loss of information (in other +** words, if the value is a string that looks like a number) +** then the conversion is performed. Otherwise no conversion occurs. +** The [SQLITE_INTEGER | datatype] after conversion is returned.)^ +** +** ^Within the [xUpdate] method of a [virtual table], the +** sqlite3_value_nochange(X) interface returns true if and only if +** the column corresponding to X is unchanged by the UPDATE operation +** that the xUpdate method call was invoked to implement and if +** the prior [xColumn] method call that was invoked to extract +** the value for that column returned without setting a result (probably +** because it queried [sqlite3_vtab_nochange()] and found that the column +** was unchanging). ^Within an [xUpdate] method, any value for which +** sqlite3_value_nochange(X) is true will in all other respects appear +** to be a NULL value. If sqlite3_value_nochange(X) is invoked anywhere other +** than within an [xUpdate] method call for an UPDATE statement, then +** the return value is arbitrary and meaningless. +** +** ^The sqlite3_value_frombind(X) interface returns non-zero if the +** value X originated from one of the [sqlite3_bind_int|sqlite3_bind()] +** interfaces. ^If X comes from an SQL literal value, or a table column, +** or an expression, then sqlite3_value_frombind(X) returns zero. +** +** Please pay particular attention to the fact that the pointer returned +** from [sqlite3_value_blob()], [sqlite3_value_text()], or +** [sqlite3_value_text16()] can be invalidated by a subsequent call to +** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()], +** or [sqlite3_value_text16()]. +** +** These routines must be called from the same thread as +** the SQL function that supplied the [sqlite3_value*] parameters. +** +** As long as the input parameter is correct, these routines can only +** fail if an out-of-memory error occurs while trying to do a +** UTF8→UTF16 or UTF16→UTF8 conversion. +** If an out-of-memory error occurs, then the return value from these +** routines is the same as if the column had contained an SQL NULL value. +** If the input sqlite3_value was not obtained from [sqlite3_value_dup()], +** then valid SQL NULL returns can also be distinguished from +** out-of-memory errors after extracting the value +** by invoking the [sqlite3_errcode()] immediately after the suspicious +** return value is obtained and before any +** other SQLite interface is called on the same [database connection]. +** If the input sqlite3_value was obtained from sqlite3_value_dup() then +** it is disconnected from the database connection and so sqlite3_errcode() +** will not work. +** In that case, the only way to distinguish an out-of-memory +** condition from a true SQL NULL is to invoke sqlite3_value_type() on the +** input to see if it is NULL prior to trying to extract the value. +*/ +SQLITE_API const void *sqlite3_value_blob(sqlite3_value*); +SQLITE_API double sqlite3_value_double(sqlite3_value*); +SQLITE_API int sqlite3_value_int(sqlite3_value*); +SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*); +SQLITE_API void *sqlite3_value_pointer(sqlite3_value*, const char*); +SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*); +SQLITE_API const void *sqlite3_value_text16(sqlite3_value*); +SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*); +SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*); +SQLITE_API int sqlite3_value_bytes(sqlite3_value*); +SQLITE_API int sqlite3_value_bytes16(sqlite3_value*); +SQLITE_API int sqlite3_value_type(sqlite3_value*); +SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); +SQLITE_API int sqlite3_value_nochange(sqlite3_value*); +SQLITE_API int sqlite3_value_frombind(sqlite3_value*); + +/* +** CAPI3REF: Report the internal text encoding state of an sqlite3_value object +** METHOD: sqlite3_value +** +** ^(The sqlite3_value_encoding(X) interface returns one of [SQLITE_UTF8], +** [SQLITE_UTF16BE], or [SQLITE_UTF16LE] according to the current text encoding +** of the value X, assuming that X has type TEXT.)^ If sqlite3_value_type(X) +** returns something other than SQLITE_TEXT, then the return value from +** sqlite3_value_encoding(X) is meaningless. ^Calls to +** [sqlite3_value_text(X)], [sqlite3_value_text16(X)], +** [sqlite3_value_text16be(X)], +** [sqlite3_value_text16le(X)], [sqlite3_value_bytes(X)], or +** [sqlite3_value_bytes16(X)] might change the encoding of the value X and +** thus change the return from subsequent calls to sqlite3_value_encoding(X). +** +** This routine is intended for used by applications that test and validate +** the SQLite implementation. This routine is inquiring about the opaque +** internal state of an [sqlite3_value] object. Ordinary applications should +** not need to know what the internal state of an sqlite3_value object is and +** hence should not need to use this interface. +*/ +SQLITE_API int sqlite3_value_encoding(sqlite3_value*); + +/* +** CAPI3REF: Finding The Subtype Of SQL Values +** METHOD: sqlite3_value +** +** The sqlite3_value_subtype(V) function returns the subtype for +** an [application-defined SQL function] argument V. The subtype +** information can be used to pass a limited amount of context from +** one SQL function to another. Use the [sqlite3_result_subtype()] +** routine to set the subtype for the return value of an SQL function. +** +** Every [application-defined SQL function] that invokes this interface +** should include the [SQLITE_SUBTYPE] property in the text +** encoding argument when the function is [sqlite3_create_function|registered]. +** If the [SQLITE_SUBTYPE] property is omitted, then sqlite3_value_subtype() +** might return zero instead of the upstream subtype in some corner cases. +*/ +SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); + +/* +** CAPI3REF: Copy And Free SQL Values +** METHOD: sqlite3_value +** +** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value] +** object V and returns a pointer to that copy. ^The [sqlite3_value] returned +** is a [protected sqlite3_value] object even if the input is not. +** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a +** memory allocation fails. ^If V is a [pointer value], then the result +** of sqlite3_value_dup(V) is a NULL value. +** +** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object +** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer +** then sqlite3_value_free(V) is a harmless no-op. +*/ +SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value*); +SQLITE_API void sqlite3_value_free(sqlite3_value*); + +/* +** CAPI3REF: Obtain Aggregate Function Context +** METHOD: sqlite3_context +** +** Implementations of aggregate SQL functions use this +** routine to allocate memory for storing their state. +** +** ^The first time the sqlite3_aggregate_context(C,N) routine is called +** for a particular aggregate function, SQLite allocates +** N bytes of memory, zeroes out that memory, and returns a pointer +** to the new memory. ^On second and subsequent calls to +** sqlite3_aggregate_context() for the same aggregate function instance, +** the same buffer is returned. Sqlite3_aggregate_context() is normally +** called once for each invocation of the xStep callback and then one +** last time when the xFinal callback is invoked. ^(When no rows match +** an aggregate query, the xStep() callback of the aggregate function +** implementation is never called and xFinal() is called exactly once. +** In those cases, sqlite3_aggregate_context() might be called for the +** first time from within xFinal().)^ +** +** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer +** when first called if N is less than or equal to zero or if a memory +** allocation error occurs. +** +** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is +** determined by the N parameter on the first successful call. Changing the +** value of N in any subsequent call to sqlite3_aggregate_context() within +** the same aggregate function instance will not resize the memory +** allocation.)^ Within the xFinal callback, it is customary to set +** N=0 in calls to sqlite3_aggregate_context(C,N) so that no +** pointless memory allocations occur. +** +** ^SQLite automatically frees the memory allocated by +** sqlite3_aggregate_context() when the aggregate query concludes. +** +** The first parameter must be a copy of the +** [sqlite3_context | SQL function context] that is the first parameter +** to the xStep or xFinal callback routine that implements the aggregate +** function. +** +** This routine must be called from the same thread in which +** the aggregate SQL function is running. +*/ +SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); + +/* +** CAPI3REF: User Data For Functions +** METHOD: sqlite3_context +** +** ^The sqlite3_user_data() interface returns a copy of +** the pointer that was the pUserData parameter (the 5th parameter) +** of the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines that originally +** registered the application defined function. +** +** This routine must be called from the same thread in which +** the application-defined function is running. +*/ +SQLITE_API void *sqlite3_user_data(sqlite3_context*); + +/* +** CAPI3REF: Database Connection For Functions +** METHOD: sqlite3_context +** +** ^The sqlite3_context_db_handle() interface returns a copy of +** the pointer to the [database connection] (the 1st parameter) +** of the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines that originally +** registered the application defined function. +*/ +SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); + +/* +** CAPI3REF: Function Auxiliary Data +** METHOD: sqlite3_context +** +** These functions may be used by (non-aggregate) SQL functions to +** associate auxiliary data with argument values. If the same argument +** value is passed to multiple invocations of the same SQL function during +** query execution, under some circumstances the associated auxiliary data +** might be preserved. An example of where this might be useful is in a +** regular-expression matching function. The compiled version of the regular +** expression can be stored as auxiliary data associated with the pattern +** string. Then as long as the pattern string remains the same, +** the compiled regular expression can be reused on multiple +** invocations of the same function. +** +** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the auxiliary +** data associated by the sqlite3_set_auxdata(C,N,P,X) function with the +** Nth argument value to the application-defined function. ^N is zero +** for the left-most function argument. ^If there is no auxiliary data +** associated with the function argument, the sqlite3_get_auxdata(C,N) +** interface returns a NULL pointer. +** +** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as auxiliary data for the +** N-th argument of the application-defined function. ^Subsequent +** calls to sqlite3_get_auxdata(C,N) return P from the most recent +** sqlite3_set_auxdata(C,N,P,X) call if the auxiliary data is still valid or +** NULL if the auxiliary data has been discarded. +** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL, +** SQLite will invoke the destructor function X with parameter P exactly +** once, when the auxiliary data is discarded. +** SQLite is free to discard the auxiliary data at any time, including:
      +**
    • ^(when the corresponding function parameter changes)^, or +**
    • ^(when [sqlite3_reset()] or [sqlite3_finalize()] is called for the +** SQL statement)^, or +**
    • ^(when sqlite3_set_auxdata() is invoked again on the same +** parameter)^, or +**
    • ^(during the original sqlite3_set_auxdata() call when a memory +** allocation error occurs.)^ +**
    • ^(during the original sqlite3_set_auxdata() call if the function +** is evaluated during query planning instead of during query execution, +** as sometimes happens with [SQLITE_ENABLE_STAT4].)^
    +** +** Note the last two bullets in particular. The destructor X in +** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the +** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata() +** should be called near the end of the function implementation and the +** function implementation should not make any use of P after +** sqlite3_set_auxdata() has been called. Furthermore, a call to +** sqlite3_get_auxdata() that occurs immediately after a corresponding call +** to sqlite3_set_auxdata() might still return NULL if an out-of-memory +** condition occurred during the sqlite3_set_auxdata() call or if the +** function is being evaluated during query planning rather than during +** query execution. +** +** ^(In practice, auxiliary data is preserved between function calls for +** function parameters that are compile-time constants, including literal +** values and [parameters] and expressions composed from the same.)^ +** +** The value of the N parameter to these interfaces should be non-negative. +** Future enhancements may make use of negative N values to define new +** kinds of function caching behavior. +** +** These routines must be called from the same thread in which +** the SQL function is running. +** +** See also: [sqlite3_get_clientdata()] and [sqlite3_set_clientdata()]. +*/ +SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N); +SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); + +/* +** CAPI3REF: Database Connection Client Data +** METHOD: sqlite3 +** +** These functions are used to associate one or more named pointers +** with a [database connection]. +** A call to sqlite3_set_clientdata(D,N,P,X) causes the pointer P +** to be attached to [database connection] D using name N. Subsequent +** calls to sqlite3_get_clientdata(D,N) will return a copy of pointer P +** or a NULL pointer if there were no prior calls to +** sqlite3_set_clientdata() with the same values of D and N. +** Names are compared using strcmp() and are thus case sensitive. +** It returns 0 on success and SQLITE_NOMEM on allocation failure. +** +** If P and X are both non-NULL, then the destructor X is invoked with +** argument P on the first of the following occurrences: +**
      +**
    • An out-of-memory error occurs during the call to +** sqlite3_set_clientdata() which attempts to register pointer P. +**
    • A subsequent call to sqlite3_set_clientdata(D,N,P,X) is made +** with the same D and N parameters. +**
    • The database connection closes. SQLite does not make any guarantees +** about the order in which destructors are called, only that all +** destructors will be called exactly once at some point during the +** database connection closing process. +**
    +** +** SQLite does not do anything with client data other than invoke +** destructors on the client data at the appropriate time. The intended +** use for client data is to provide a mechanism for wrapper libraries +** to store additional information about an SQLite database connection. +** +** There is no limit (other than available memory) on the number of different +** client data pointers (with different names) that can be attached to a +** single database connection. However, the current implementation stores +** the content on a linked list. Insert and retrieval performance will +** be proportional to the number of entries. The design use case, and +** the use case for which the implementation is optimized, is +** that an application will store only small number of client data names, +** typically just one or two. This interface is not intended to be a +** generalized key/value store for thousands or millions of keys. It +** will work for that, but performance might be disappointing. +** +** There is no way to enumerate the client data pointers +** associated with a database connection. The N parameter can be thought +** of as a secret key such that only code that knows the secret key is able +** to access the associated data. +** +** Security Warning: These interfaces should not be exposed in scripting +** languages or in other circumstances where it might be possible for an +** attacker to invoke them. Any agent that can invoke these interfaces +** can probably also take control of the process. +** +** Database connection client data is only available for SQLite +** version 3.44.0 ([dateof:3.44.0]) and later. +** +** See also: [sqlite3_set_auxdata()] and [sqlite3_get_auxdata()]. +*/ +SQLITE_API void *sqlite3_get_clientdata(sqlite3*,const char*); +SQLITE_API int sqlite3_set_clientdata(sqlite3*, const char*, void*, void(*)(void*)); + +/* +** CAPI3REF: Constants Defining Special Destructor Behavior +** +** These are special values for the destructor that is passed in as the +** final argument to routines like [sqlite3_result_blob()]. ^If the destructor +** argument is SQLITE_STATIC, it means that the content pointer is constant +** and will never change. It does not need to be destroyed. ^The +** SQLITE_TRANSIENT value means that the content will likely change in +** the near future and that SQLite should make its own private copy of +** the content before returning. +** +** The typedef is necessary to work around problems in certain +** C++ compilers. +*/ +typedef void (*sqlite3_destructor_type)(void*); +#define SQLITE_STATIC ((sqlite3_destructor_type)0) +#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) + +/* +** CAPI3REF: Setting The Result Of An SQL Function +** METHOD: sqlite3_context +** +** These routines are used by the xFunc or xFinal callbacks that +** implement SQL functions and aggregates. See +** [sqlite3_create_function()] and [sqlite3_create_function16()] +** for additional information. +** +** These functions work very much like the [parameter binding] family of +** functions used to bind values to host parameters in prepared statements. +** Refer to the [SQL parameter] documentation for additional information. +** +** ^The sqlite3_result_blob() interface sets the result from +** an application-defined function to be the BLOB whose content is pointed +** to by the second parameter and which is N bytes long where N is the +** third parameter. +** +** ^The sqlite3_result_zeroblob(C,N) and sqlite3_result_zeroblob64(C,N) +** interfaces set the result of the application-defined function to be +** a BLOB containing all zero bytes and N bytes in size. +** +** ^The sqlite3_result_double() interface sets the result from +** an application-defined function to be a floating point value specified +** by its 2nd argument. +** +** ^The sqlite3_result_error() and sqlite3_result_error16() functions +** cause the implemented SQL function to throw an exception. +** ^SQLite uses the string pointed to by the +** 2nd parameter of sqlite3_result_error() or sqlite3_result_error16() +** as the text of an error message. ^SQLite interprets the error +** message string from sqlite3_result_error() as UTF-8. ^SQLite +** interprets the string from sqlite3_result_error16() as UTF-16 using +** the same [byte-order determination rules] as [sqlite3_bind_text16()]. +** ^If the third parameter to sqlite3_result_error() +** or sqlite3_result_error16() is negative then SQLite takes as the error +** message all text up through the first zero character. +** ^If the third parameter to sqlite3_result_error() or +** sqlite3_result_error16() is non-negative then SQLite takes that many +** bytes (not characters) from the 2nd parameter as the error message. +** ^The sqlite3_result_error() and sqlite3_result_error16() +** routines make a private copy of the error message text before +** they return. Hence, the calling function can deallocate or +** modify the text after they return without harm. +** ^The sqlite3_result_error_code() function changes the error code +** returned by SQLite as a result of an error in a function. ^By default, +** the error code is SQLITE_ERROR. ^A subsequent call to sqlite3_result_error() +** or sqlite3_result_error16() resets the error code to SQLITE_ERROR. +** +** ^The sqlite3_result_error_toobig() interface causes SQLite to throw an +** error indicating that a string or BLOB is too long to represent. +** +** ^The sqlite3_result_error_nomem() interface causes SQLite to throw an +** error indicating that a memory allocation failed. +** +** ^The sqlite3_result_int() interface sets the return value +** of the application-defined function to be the 32-bit signed integer +** value given in the 2nd argument. +** ^The sqlite3_result_int64() interface sets the return value +** of the application-defined function to be the 64-bit signed integer +** value given in the 2nd argument. +** +** ^The sqlite3_result_null() interface sets the return value +** of the application-defined function to be NULL. +** +** ^The sqlite3_result_text(), sqlite3_result_text16(), +** sqlite3_result_text16le(), and sqlite3_result_text16be() interfaces +** set the return value of the application-defined function to be +** a text string which is represented as UTF-8, UTF-16 native byte order, +** UTF-16 little endian, or UTF-16 big endian, respectively. +** ^The sqlite3_result_text64(C,Z,N,D,E) interface sets the return value of an +** application-defined function to be a text string in an encoding +** specified the E parameter, which must be one +** of [SQLITE_UTF8], [SQLITE_UTF8_ZT], [SQLITE_UTF16], [SQLITE_UTF16BE], +** or [SQLITE_UTF16LE]. ^The special value [SQLITE_UTF8_ZT] means that +** the result text is both UTF-8 and zero-terminated. In other words, +** SQLITE_UTF8_ZT means that the Z array holds at least N+1 bytes and that +** the Z[N] is zero. +** ^SQLite takes the text result from the application from +** the 2nd parameter of the sqlite3_result_text* interfaces. +** ^If the 3rd parameter to any of the sqlite3_result_text* interfaces +** other than sqlite3_result_text64() is negative, then SQLite computes +** the string length itself by searching the 2nd parameter for the first +** zero character. +** ^If the 3rd parameter to the sqlite3_result_text* interfaces +** is non-negative, then as many bytes (not characters) of the text +** pointed to by the 2nd parameter are taken as the application-defined +** function result. If the 3rd parameter is non-negative, then it +** must be the byte offset into the string where the NUL terminator would +** appear if the string were NUL terminated. If any NUL characters occur +** in the string at a byte offset that is less than the value of the 3rd +** parameter, then the resulting string will contain embedded NULs and the +** result of expressions operating on strings with embedded NULs is undefined. +** ^If the 4th parameter to the sqlite3_result_text* interfaces +** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that +** function as the destructor on the text or BLOB result when it has +** finished using that result. +** ^If the 4th parameter to the sqlite3_result_text* interfaces or to +** sqlite3_result_blob is the special constant SQLITE_STATIC, then SQLite +** assumes that the text or BLOB result is in constant space and does not +** copy the content of the parameter nor call a destructor on the content +** when it has finished using that result. +** ^If the 4th parameter to the sqlite3_result_text* interfaces +** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT +** then SQLite makes a copy of the result into space obtained +** from [sqlite3_malloc()] before it returns. +** +** ^For the sqlite3_result_text16(), sqlite3_result_text16le(), and +** sqlite3_result_text16be() routines, and for sqlite3_result_text64() +** when the encoding is not UTF8, if the input UTF16 begins with a +** byte-order mark (BOM, U+FEFF) then the BOM is removed from the +** string and the rest of the string is interpreted according to the +** byte-order specified by the BOM. ^The byte-order specified by +** the BOM at the beginning of the text overrides the byte-order +** specified by the interface procedure. ^So, for example, if +** sqlite3_result_text16le() is invoked with text that begins +** with bytes 0xfe, 0xff (a big-endian byte-order mark) then the +** first two bytes of input are skipped and the remaining input +** is interpreted as UTF16BE text. +** +** ^For UTF16 input text to the sqlite3_result_text16(), +** sqlite3_result_text16be(), sqlite3_result_text16le(), and +** sqlite3_result_text64() routines, if the text contains invalid +** UTF16 characters, the invalid characters might be converted +** into the unicode replacement character, U+FFFD. +** +** ^The sqlite3_result_value() interface sets the result of +** the application-defined function to be a copy of the +** [unprotected sqlite3_value] object specified by the 2nd parameter. ^The +** sqlite3_result_value() interface makes a copy of the [sqlite3_value] +** so that the [sqlite3_value] specified in the parameter may change or +** be deallocated after sqlite3_result_value() returns without harm. +** ^A [protected sqlite3_value] object may always be used where an +** [unprotected sqlite3_value] object is required, so either +** kind of [sqlite3_value] object can be used with this interface. +** +** ^The sqlite3_result_pointer(C,P,T,D) interface sets the result to an +** SQL NULL value, just like [sqlite3_result_null(C)], except that it +** also associates the host-language pointer P or type T with that +** NULL value such that the pointer can be retrieved within an +** [application-defined SQL function] using [sqlite3_value_pointer()]. +** ^If the D parameter is not NULL, then it is a pointer to a destructor +** for the P parameter. ^SQLite invokes D with P as its only argument +** when SQLite is finished with P. The T parameter should be a static +** string and preferably a string literal. The sqlite3_result_pointer() +** routine is part of the [pointer passing interface] added for SQLite 3.20.0. +** +** If these routines are called from within a different thread +** than the one containing the application-defined function that received +** the [sqlite3_context] pointer, the results are undefined. +*/ +SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); +SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*, + sqlite3_uint64,void(*)(void*)); +SQLITE_API void sqlite3_result_double(sqlite3_context*, double); +SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int); +SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int); +SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*); +SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*); +SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int); +SQLITE_API void sqlite3_result_int(sqlite3_context*, int); +SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); +SQLITE_API void sqlite3_result_null(sqlite3_context*); +SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); +SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char *z, sqlite3_uint64 n, + void(*)(void*), unsigned char encoding); +SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); +SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); +SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); +SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*); +SQLITE_API void sqlite3_result_pointer(sqlite3_context*, void*,const char*,void(*)(void*)); +SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n); +SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n); + + +/* +** CAPI3REF: Setting The Subtype Of An SQL Function +** METHOD: sqlite3_context +** +** The sqlite3_result_subtype(C,T) function causes the subtype of +** the result from the [application-defined SQL function] with +** [sqlite3_context] C to be the value T. Only the lower 8 bits +** of the subtype T are preserved in current versions of SQLite; +** higher order bits are discarded. +** The number of subtype bytes preserved by SQLite might increase +** in future releases of SQLite. +** +** Every [application-defined SQL function] that invokes this interface +** should include the [SQLITE_RESULT_SUBTYPE] property in its +** text encoding argument when the SQL function is +** [sqlite3_create_function|registered]. If the [SQLITE_RESULT_SUBTYPE] +** property is omitted from the function that invokes sqlite3_result_subtype(), +** then in some cases the sqlite3_result_subtype() might fail to set +** the result subtype. +** +** If SQLite is compiled with -DSQLITE_STRICT_SUBTYPE=1, then any +** SQL function that invokes the sqlite3_result_subtype() interface +** and that does not have the SQLITE_RESULT_SUBTYPE property will raise +** an error. Future versions of SQLite might enable -DSQLITE_STRICT_SUBTYPE=1 +** by default. +*/ +SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int); + +/* +** CAPI3REF: Define New Collating Sequences +** METHOD: sqlite3 +** +** ^These functions add, remove, or modify a [collation] associated +** with the [database connection] specified as the first argument. +** +** ^The name of the collation is a UTF-8 string +** for sqlite3_create_collation() and sqlite3_create_collation_v2() +** and a UTF-16 string in native byte order for sqlite3_create_collation16(). +** ^Collation names that compare equal according to [sqlite3_strnicmp()] are +** considered to be the same name. +** +** ^(The third argument (eTextRep) must be one of the constants: +**
      +**
    • [SQLITE_UTF8], +**
    • [SQLITE_UTF16LE], +**
    • [SQLITE_UTF16BE], +**
    • [SQLITE_UTF16], or +**
    • [SQLITE_UTF16_ALIGNED]. +**
    )^ +** ^The eTextRep argument determines the encoding of strings passed +** to the collating function callback, xCompare. +** ^The [SQLITE_UTF16] and [SQLITE_UTF16_ALIGNED] values for eTextRep +** force strings to be UTF16 with native byte order. +** ^The [SQLITE_UTF16_ALIGNED] value for eTextRep forces strings to begin +** on an even byte address. +** +** ^The fourth argument, pArg, is an application data pointer that is passed +** through as the first argument to the collating function callback. +** +** ^The fifth argument, xCompare, is a pointer to the collating function. +** ^Multiple collating functions can be registered using the same name but +** with different eTextRep parameters and SQLite will use whichever +** function requires the least amount of data transformation. +** ^If the xCompare argument is NULL then the collating function is +** deleted. ^When all collating functions having the same name are deleted, +** that collation is no longer usable. +** +** ^The collating function callback is invoked with a copy of the pArg +** application data pointer and with two strings in the encoding specified +** by the eTextRep argument. The two integer parameters to the collating +** function callback are the length of the two strings, in bytes. The collating +** function must return an integer that is negative, zero, or positive +** if the first string is less than, equal to, or greater than the second, +** respectively. A collating function must always return the same answer +** given the same inputs. If two or more collating functions are registered +** to the same collation name (using different eTextRep values) then all +** must give an equivalent answer when invoked with equivalent strings. +** The collating function must obey the following properties for all +** strings A, B, and C: +** +**
      +**
    1. If A==B then B==A. +**
    2. If A==B and B==C then A==C. +**
    3. If A<B THEN B>A. +**
    4. If A<B and B<C then A<C. +**
    +** +** If a collating function fails any of the above constraints and that +** collating function is registered and used, then the behavior of SQLite +** is undefined. +** +** ^The sqlite3_create_collation_v2() works like sqlite3_create_collation() +** with the addition that the xDestroy callback is invoked on pArg when +** the collating function is deleted. +** ^Collating functions are deleted when they are overridden by later +** calls to the collation creation functions or when the +** [database connection] is closed using [sqlite3_close()]. +** +** ^The xDestroy callback is not called if the +** sqlite3_create_collation_v2() function fails. Applications that invoke +** sqlite3_create_collation_v2() with a non-NULL xDestroy argument should +** check the return code and dispose of the application data pointer +** themselves rather than expecting SQLite to deal with it for them. +** This is different from every other SQLite interface. The inconsistency +** is unfortunate but cannot be changed without breaking backwards +** compatibility. +** +** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()]. +*/ +SQLITE_API int sqlite3_create_collation( + sqlite3*, + const char *zName, + int eTextRep, + void *pArg, + int(*xCompare)(void*,int,const void*,int,const void*) +); +SQLITE_API int sqlite3_create_collation_v2( + sqlite3*, + const char *zName, + int eTextRep, + void *pArg, + int(*xCompare)(void*,int,const void*,int,const void*), + void(*xDestroy)(void*) +); +SQLITE_API int sqlite3_create_collation16( + sqlite3*, + const void *zName, + int eTextRep, + void *pArg, + int(*xCompare)(void*,int,const void*,int,const void*) +); + +/* +** CAPI3REF: Collation Needed Callbacks +** METHOD: sqlite3 +** +** ^To avoid having to register all collation sequences before a database +** can be used, a single callback function may be registered with the +** [database connection] to be invoked whenever an undefined collation +** sequence is required. +** +** ^If the function is registered using the sqlite3_collation_needed() API, +** then it is passed the names of undefined collation sequences as strings +** encoded in UTF-8. ^If sqlite3_collation_needed16() is used, +** the names are passed as UTF-16 in machine native byte order. +** ^A call to either function replaces the existing collation-needed callback. +** +** ^(When the callback is invoked, the first argument passed is a copy +** of the second argument to sqlite3_collation_needed() or +** sqlite3_collation_needed16(). The second argument is the database +** connection. The third argument is one of [SQLITE_UTF8], [SQLITE_UTF16BE], +** or [SQLITE_UTF16LE], indicating the most desirable form of the collation +** sequence function required. The fourth parameter is the name of the +** required collation sequence.)^ +** +** The callback function should register the desired collation using +** [sqlite3_create_collation()], [sqlite3_create_collation16()], or +** [sqlite3_create_collation_v2()]. +*/ +SQLITE_API int sqlite3_collation_needed( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const char*) +); +SQLITE_API int sqlite3_collation_needed16( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const void*) +); + +#ifdef SQLITE_ENABLE_CEROD +/* +** Specify the activation key for a CEROD database. Unless +** activated, none of the CEROD routines will work. +*/ +SQLITE_API void sqlite3_activate_cerod( + const char *zPassPhrase /* Activation phrase */ +); +#endif + +/* +** CAPI3REF: Suspend Execution For A Short Time +** +** The sqlite3_sleep() function causes the current thread to suspend execution +** for at least a number of milliseconds specified in its parameter. +** +** If the operating system does not support sleep requests with +** millisecond time resolution, then the time will be rounded up to +** the nearest second. The number of milliseconds of sleep actually +** requested from the operating system is returned. +** +** ^SQLite implements this interface by calling the xSleep() +** method of the default [sqlite3_vfs] object. If the xSleep() method +** of the default VFS is not implemented correctly, or not implemented at +** all, then the behavior of sqlite3_sleep() may deviate from the description +** in the previous paragraphs. +** +** If a negative argument is passed to sqlite3_sleep() the results vary by +** VFS and operating system. Some system treat a negative argument as an +** instruction to sleep forever. Others understand it to mean do not sleep +** at all. ^In SQLite version 3.42.0 and later, a negative +** argument passed into sqlite3_sleep() is changed to zero before it is relayed +** down into the xSleep method of the VFS. +*/ +SQLITE_API int sqlite3_sleep(int); + +/* +** CAPI3REF: Name Of The Folder Holding Temporary Files +** +** ^(If this global variable is made to point to a string which is +** the name of a folder (a.k.a. directory), then all temporary files +** created by SQLite when using a built-in [sqlite3_vfs | VFS] +** will be placed in that directory.)^ ^If this variable +** is a NULL pointer, then SQLite performs a search for an appropriate +** temporary file directory. +** +** Applications are strongly discouraged from using this global variable. +** It is required to set a temporary folder on Windows Runtime (WinRT). +** But for all other platforms, it is highly recommended that applications +** neither read nor write this variable. This global variable is a relic +** that exists for backwards compatibility of legacy applications and should +** be avoided in new projects. +** +** It is not safe to read or modify this variable in more than one +** thread at a time. It is not safe to read or modify this variable +** if a [database connection] is being used at the same time in a separate +** thread. +** It is intended that this variable be set once +** as part of process initialization and before any SQLite interface +** routines have been called and that this variable remain unchanged +** thereafter. +** +** ^The [temp_store_directory pragma] may modify this variable and cause +** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore, +** the [temp_store_directory pragma] always assumes that any string +** that this variable points to is held in memory obtained from +** [sqlite3_malloc] and the pragma may attempt to free that memory +** using [sqlite3_free]. +** Hence, if this variable is modified directly, either it should be +** made NULL or made to point to memory obtained from [sqlite3_malloc] +** or else the use of the [temp_store_directory pragma] should be avoided. +** Except when requested by the [temp_store_directory pragma], SQLite +** does not free the memory that sqlite3_temp_directory points to. If +** the application wants that memory to be freed, it must do +** so itself, taking care to only do so after all [database connection] +** objects have been destroyed. +** +** Note to Windows Runtime users: The temporary directory must be set +** prior to calling [sqlite3_open] or [sqlite3_open_v2]. Otherwise, various +** features that require the use of temporary files may fail. Here is an +** example of how to do this using C++ with the Windows Runtime: +** +**
    +** LPCWSTR zPath = Windows::Storage::ApplicationData::Current->
    +**       TemporaryFolder->Path->Data();
    +** char zPathBuf[MAX_PATH + 1];
    +** memset(zPathBuf, 0, sizeof(zPathBuf));
    +** WideCharToMultiByte(CP_UTF8, 0, zPath, -1, zPathBuf, sizeof(zPathBuf),
    +**       NULL, NULL);
    +** sqlite3_temp_directory = sqlite3_mprintf("%s", zPathBuf);
    +** 
    +*/ +SQLITE_API char *sqlite3_temp_directory; + +/* +** CAPI3REF: Name Of The Folder Holding Database Files +** +** ^(If this global variable is made to point to a string which is +** the name of a folder (a.k.a. directory), then all database files +** specified with a relative pathname and created or accessed by +** SQLite when using a built-in windows [sqlite3_vfs | VFS] will be assumed +** to be relative to that directory.)^ ^If this variable is a NULL +** pointer, then SQLite assumes that all database files specified +** with a relative pathname are relative to the current directory +** for the process. Only the windows VFS makes use of this global +** variable; it is ignored by the unix VFS. +** +** Changing the value of this variable while a database connection is +** open can result in a corrupt database. +** +** It is not safe to read or modify this variable in more than one +** thread at a time. It is not safe to read or modify this variable +** if a [database connection] is being used at the same time in a separate +** thread. +** It is intended that this variable be set once +** as part of process initialization and before any SQLite interface +** routines have been called and that this variable remain unchanged +** thereafter. +** +** ^The [data_store_directory pragma] may modify this variable and cause +** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore, +** the [data_store_directory pragma] always assumes that any string +** that this variable points to is held in memory obtained from +** [sqlite3_malloc] and the pragma may attempt to free that memory +** using [sqlite3_free]. +** Hence, if this variable is modified directly, either it should be +** made NULL or made to point to memory obtained from [sqlite3_malloc] +** or else the use of the [data_store_directory pragma] should be avoided. +*/ +SQLITE_API char *sqlite3_data_directory; + +/* +** CAPI3REF: Win32 Specific Interface +** +** These interfaces are available only on Windows. The +** [sqlite3_win32_set_directory] interface is used to set the value associated +** with the [sqlite3_temp_directory] or [sqlite3_data_directory] variable, to +** zValue, depending on the value of the type parameter. The zValue parameter +** should be NULL to cause the previous value to be freed via [sqlite3_free]; +** a non-NULL value will be copied into memory obtained from [sqlite3_malloc] +** prior to being used. The [sqlite3_win32_set_directory] interface returns +** [SQLITE_OK] to indicate success, [SQLITE_ERROR] if the type is unsupported, +** or [SQLITE_NOMEM] if memory could not be allocated. The value of the +** [sqlite3_data_directory] variable is intended to act as a replacement for +** the current directory on the sub-platforms of Win32 where that concept is +** not present, e.g. WinRT and UWP. The [sqlite3_win32_set_directory8] and +** [sqlite3_win32_set_directory16] interfaces behave exactly the same as the +** sqlite3_win32_set_directory interface except the string parameter must be +** UTF-8 or UTF-16, respectively. +*/ +SQLITE_API int sqlite3_win32_set_directory( + unsigned long type, /* Identifier for directory being set or reset */ + void *zValue /* New value for directory being set or reset */ +); +SQLITE_API int sqlite3_win32_set_directory8(unsigned long type, const char *zValue); +SQLITE_API int sqlite3_win32_set_directory16(unsigned long type, const void *zValue); + +/* +** CAPI3REF: Win32 Directory Types +** +** These macros are only available on Windows. They define the allowed values +** for the type argument to the [sqlite3_win32_set_directory] interface. +*/ +#define SQLITE_WIN32_DATA_DIRECTORY_TYPE 1 +#define SQLITE_WIN32_TEMP_DIRECTORY_TYPE 2 + +/* +** CAPI3REF: Test For Auto-Commit Mode +** KEYWORDS: {autocommit mode} +** METHOD: sqlite3 +** +** ^The sqlite3_get_autocommit() interface returns non-zero or +** zero if the given database connection is or is not in autocommit mode, +** respectively. ^Autocommit mode is on by default. +** ^Autocommit mode is disabled by a [BEGIN] statement. +** ^Autocommit mode is re-enabled by a [COMMIT] or [ROLLBACK]. +** +** If certain kinds of errors occur on a statement within a multi-statement +** transaction (errors including [SQLITE_FULL], [SQLITE_IOERR], +** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the +** transaction might be rolled back automatically. The only way to +** find out whether SQLite automatically rolled back the transaction after +** an error is to use this function. +** +** If another thread changes the autocommit status of the database +** connection while this routine is running, then the return value +** is undefined. +*/ +SQLITE_API int sqlite3_get_autocommit(sqlite3*); + +/* +** CAPI3REF: Find The Database Handle Of A Prepared Statement +** METHOD: sqlite3_stmt +** +** ^The sqlite3_db_handle interface returns the [database connection] handle +** to which a [prepared statement] belongs. ^The [database connection] +** returned by sqlite3_db_handle is the same [database connection] +** that was the first argument +** to the [sqlite3_prepare_v2()] call (or its variants) that was used to +** create the statement in the first place. +*/ +SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); + +/* +** CAPI3REF: Return The Schema Name For A Database Connection +** METHOD: sqlite3 +** +** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name +** for the N-th database on database connection D, or a NULL pointer if N is +** out of range. An N value of 0 means the main database file. An N of 1 is +** the "temp" schema. Larger values of N correspond to various ATTACH-ed +** databases. +** +** Space to hold the string that is returned by sqlite3_db_name() is managed +** by SQLite itself. The string might be deallocated by any operation that +** changes the schema, including [ATTACH] or [DETACH] or calls to +** [sqlite3_serialize()] or [sqlite3_deserialize()], even operations that +** occur on a different thread. Applications that need to +** remember the string long-term should make their own copy. Applications that +** are accessing the same database connection simultaneously on multiple +** threads should mutex-protect calls to this API and should make their own +** private copy of the result prior to releasing the mutex. +*/ +SQLITE_API const char *sqlite3_db_name(sqlite3 *db, int N); + +/* +** CAPI3REF: Return The Filename For A Database Connection +** METHOD: sqlite3 +** +** ^The sqlite3_db_filename(D,N) interface returns a pointer to the filename +** associated with database N of connection D. +** ^If there is no attached database N on the database +** connection D, or if database N is a temporary or in-memory database, then +** this function will return either a NULL pointer or an empty string. +** +** ^The string value returned by this routine is owned and managed by +** the database connection. ^The value will be valid until the database N +** is [DETACH]-ed or until the database connection closes. +** +** ^The filename returned by this function is the output of the +** xFullPathname method of the [VFS]. ^In other words, the filename +** will be an absolute pathname, even if the filename used +** to open the database originally was a URI or relative pathname. +** +** If the filename pointer returned by this routine is not NULL, then it +** can be used as the filename input parameter to these routines: +**
      +**
    • [sqlite3_uri_parameter()] +**
    • [sqlite3_uri_boolean()] +**
    • [sqlite3_uri_int64()] +**
    • [sqlite3_filename_database()] +**
    • [sqlite3_filename_journal()] +**
    • [sqlite3_filename_wal()] +**
    +*/ +SQLITE_API sqlite3_filename sqlite3_db_filename(sqlite3 *db, const char *zDbName); + +/* +** CAPI3REF: Determine if a database is read-only +** METHOD: sqlite3 +** +** ^The sqlite3_db_readonly(D,N) interface returns 1 if the database N +** of connection D is read-only, 0 if it is read/write, or -1 if N is not +** the name of a database on connection D. +*/ +SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName); + +/* +** CAPI3REF: Determine the transaction state of a database +** METHOD: sqlite3 +** +** ^The sqlite3_txn_state(D,S) interface returns the current +** [transaction state] of schema S in database connection D. ^If S is NULL, +** then the highest transaction state of any schema on database connection D +** is returned. Transaction states are (in order of lowest to highest): +**
      +**
    1. SQLITE_TXN_NONE +**
    2. SQLITE_TXN_READ +**
    3. SQLITE_TXN_WRITE +**
    +** ^If the S argument to sqlite3_txn_state(D,S) is not the name of +** a valid schema, then -1 is returned. +*/ +SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema); + +/* +** CAPI3REF: Allowed return values from sqlite3_txn_state() +** KEYWORDS: {transaction state} +** +** These constants define the current transaction state of a database file. +** ^The [sqlite3_txn_state(D,S)] interface returns one of these +** constants in order to describe the transaction state of schema S +** in [database connection] D. +** +**
    +** [[SQLITE_TXN_NONE]]
    SQLITE_TXN_NONE
    +**
    The SQLITE_TXN_NONE state means that no transaction is currently +** pending.
    +** +** [[SQLITE_TXN_READ]]
    SQLITE_TXN_READ
    +**
    The SQLITE_TXN_READ state means that the database is currently +** in a read transaction. Content has been read from the database file +** but nothing in the database file has changed. The transaction state +** will be advanced to SQLITE_TXN_WRITE if any changes occur and there are +** no other conflicting concurrent write transactions. The transaction +** state will revert to SQLITE_TXN_NONE following a [ROLLBACK] or +** [COMMIT].
    +** +** [[SQLITE_TXN_WRITE]]
    SQLITE_TXN_WRITE
    +**
    The SQLITE_TXN_WRITE state means that the database is currently +** in a write transaction. Content has been written to the database file +** but has not yet committed. The transaction state will change to +** SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT].
    +*/ +#define SQLITE_TXN_NONE 0 +#define SQLITE_TXN_READ 1 +#define SQLITE_TXN_WRITE 2 + +/* +** CAPI3REF: Find the next prepared statement +** METHOD: sqlite3 +** +** ^This interface returns a pointer to the next [prepared statement] after +** pStmt associated with the [database connection] pDb. ^If pStmt is NULL +** then this interface returns a pointer to the first prepared statement +** associated with the database connection pDb. ^If no prepared statement +** satisfies the conditions of this routine, it returns NULL. +** +** The [database connection] pointer D in a call to +** [sqlite3_next_stmt(D,S)] must refer to an open database +** connection and in particular must not be a NULL pointer. +*/ +SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); + +/* +** CAPI3REF: Commit And Rollback Notification Callbacks +** METHOD: sqlite3 +** +** ^The sqlite3_commit_hook() interface registers a callback +** function to be invoked whenever a transaction is [COMMIT | committed]. +** ^Any callback set by a previous call to sqlite3_commit_hook() +** for the same database connection is overridden. +** ^The sqlite3_rollback_hook() interface registers a callback +** function to be invoked whenever a transaction is [ROLLBACK | rolled back]. +** ^Any callback set by a previous call to sqlite3_rollback_hook() +** for the same database connection is overridden. +** ^The pArg argument is passed through to the callback. +** ^If the callback on a commit hook function returns non-zero, +** then the commit is converted into a rollback. +** +** ^The sqlite3_commit_hook(D,C,P) and sqlite3_rollback_hook(D,C,P) functions +** return the P argument from the previous call of the same function +** on the same [database connection] D, or NULL for +** the first call for each function on D. +** +** The commit and rollback hook callbacks are not reentrant. +** The callback implementation must not do anything that will modify +** the database connection that invoked the callback. Any actions +** to modify the database connection must be deferred until after the +** completion of the [sqlite3_step()] call that triggered the commit +** or rollback hook in the first place. +** Note that running any other SQL statements, including SELECT statements, +** or merely calling [sqlite3_prepare_v2()] and [sqlite3_step()] will modify +** the database connections for the meaning of "modify" in this paragraph. +** +** ^Registering a NULL function disables the callback. +** +** ^When the commit hook callback routine returns zero, the [COMMIT] +** operation is allowed to continue normally. ^If the commit hook +** returns non-zero, then the [COMMIT] is converted into a [ROLLBACK]. +** ^The rollback hook is invoked on a rollback that results from a commit +** hook returning non-zero, just as it would be with any other rollback. +** +** ^For the purposes of this API, a transaction is said to have been +** rolled back if an explicit "ROLLBACK" statement is executed, or +** an error or constraint causes an implicit rollback to occur. +** ^The rollback callback is not invoked if a transaction is +** automatically rolled back because the database connection is closed. +** +** See also the [sqlite3_update_hook()] interface. +*/ +SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); +SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); + +/* +** CAPI3REF: Autovacuum Compaction Amount Callback +** METHOD: sqlite3 +** +** ^The sqlite3_autovacuum_pages(D,C,P,X) interface registers a callback +** function C that is invoked prior to each autovacuum of the database +** file. ^The callback is passed a copy of the generic data pointer (P), +** the schema-name of the attached database that is being autovacuumed, +** the size of the database file in pages, the number of free pages, +** and the number of bytes per page, respectively. The callback should +** return the number of free pages that should be removed by the +** autovacuum. ^If the callback returns zero, then no autovacuum happens. +** ^If the value returned is greater than or equal to the number of +** free pages, then a complete autovacuum happens. +** +**

    ^If there are multiple ATTACH-ed database files that are being +** modified as part of a transaction commit, then the autovacuum pages +** callback is invoked separately for each file. +** +**

    The callback is not reentrant. The callback function should +** not attempt to invoke any other SQLite interface. If it does, bad +** things may happen, including segmentation faults and corrupt database +** files. The callback function should be a simple function that +** does some arithmetic on its input parameters and returns a result. +** +** ^The X parameter to sqlite3_autovacuum_pages(D,C,P,X) is an optional +** destructor for the P parameter. ^If X is not NULL, then X(P) is +** invoked whenever the database connection closes or when the callback +** is overwritten by another invocation of sqlite3_autovacuum_pages(). +** +**

    ^There is only one autovacuum pages callback per database connection. +** ^Each call to the sqlite3_autovacuum_pages() interface overrides all +** previous invocations for that database connection. ^If the callback +** argument (C) to sqlite3_autovacuum_pages(D,C,P,X) is a NULL pointer, +** then the autovacuum steps callback is canceled. The return value +** from sqlite3_autovacuum_pages() is normally SQLITE_OK, but might +** be some other error code if something goes wrong. The current +** implementation will only return SQLITE_OK or SQLITE_MISUSE, but other +** return codes might be added in future releases. +** +**

    If no autovacuum pages callback is specified (the usual case) or +** a NULL pointer is provided for the callback, +** then the default behavior is to vacuum all free pages. So, in other +** words, the default behavior is the same as if the callback function +** were something like this: +** +**

    +**     unsigned int demonstration_autovac_pages_callback(
    +**       void *pClientData,
    +**       const char *zSchema,
    +**       unsigned int nDbPage,
    +**       unsigned int nFreePage,
    +**       unsigned int nBytePerPage
    +**     ){
    +**       return nFreePage;
    +**     }
    +** 
    +*/ +SQLITE_API int sqlite3_autovacuum_pages( + sqlite3 *db, + unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int), + void*, + void(*)(void*) +); + + +/* +** CAPI3REF: Data Change Notification Callbacks +** METHOD: sqlite3 +** +** ^The sqlite3_update_hook() interface registers a callback function +** with the [database connection] identified by the first argument +** to be invoked whenever a row is updated, inserted or deleted in +** a [rowid table]. +** ^Any callback set by a previous call to this function +** for the same database connection is overridden. +** +** ^The second argument is a pointer to the function to invoke when a +** row is updated, inserted or deleted in a rowid table. +** ^The update hook is disabled by invoking sqlite3_update_hook() +** with a NULL pointer as the second parameter. +** ^The first argument to the callback is a copy of the third argument +** to sqlite3_update_hook(). +** ^The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE], +** or [SQLITE_UPDATE], depending on the operation that caused the callback +** to be invoked. +** ^The third and fourth arguments to the callback contain pointers to the +** database and table name containing the affected row. +** ^The final callback parameter is the [rowid] of the row. +** ^In the case of an update, this is the [rowid] after the update takes place. +** +** ^(The update hook is not invoked when internal system tables are +** modified (i.e. sqlite_sequence).)^ +** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified. +** +** ^In the current implementation, the update hook +** is not invoked when conflicting rows are deleted because of an +** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook +** invoked when rows are deleted using the [truncate optimization]. +** The exceptions defined in this paragraph might change in a future +** release of SQLite. +** +** Whether the update hook is invoked before or after the +** corresponding change is currently unspecified and may differ +** depending on the type of change. Do not rely on the order of the +** hook call with regards to the final result of the operation which +** triggers the hook. +** +** The update hook implementation must not do anything that will modify +** the database connection that invoked the update hook. Any actions +** to modify the database connection must be deferred until after the +** completion of the [sqlite3_step()] call that triggered the update hook. +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their +** database connections for the meaning of "modify" in this paragraph. +** +** ^The sqlite3_update_hook(D,C,P) function +** returns the P argument from the previous call +** on the same [database connection] D, or NULL for +** the first call on D. +** +** See also the [sqlite3_commit_hook()], [sqlite3_rollback_hook()], +** and [sqlite3_preupdate_hook()] interfaces. +*/ +SQLITE_API void *sqlite3_update_hook( + sqlite3*, + void(*)(void *,int ,char const *,char const *,sqlite3_int64), + void* +); + +/* +** CAPI3REF: Enable Or Disable Shared Pager Cache +** +** ^(This routine enables or disables the sharing of the database cache +** and schema data structures between [database connection | connections] +** to the same database. Sharing is enabled if the argument is true +** and disabled if the argument is false.)^ +** +** This interface is omitted if SQLite is compiled with +** [-DSQLITE_OMIT_SHARED_CACHE]. The [-DSQLITE_OMIT_SHARED_CACHE] +** compile-time option is recommended because the +** [use of shared cache mode is discouraged]. +** +** ^Cache sharing is enabled and disabled for an entire process. +** This is a change as of SQLite [version 3.5.0] ([dateof:3.5.0]). +** In prior versions of SQLite, +** sharing was enabled or disabled for each thread separately. +** +** ^(The cache sharing mode set by this interface effects all subsequent +** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()]. +** Existing database connections continue to use the sharing mode +** that was in effect at the time they were opened.)^ +** +** ^(This routine returns [SQLITE_OK] if shared cache was enabled or disabled +** successfully. An [error code] is returned otherwise.)^ +** +** ^Shared cache is disabled by default. It is recommended that it stay +** that way. In other words, do not use this routine. This interface +** continues to be provided for historical compatibility, but its use is +** discouraged. Any use of shared cache is discouraged. If shared cache +** must be used, it is recommended that shared cache only be enabled for +** individual database connections using the [sqlite3_open_v2()] interface +** with the [SQLITE_OPEN_SHAREDCACHE] flag. +** +** Note: This method is disabled on MacOS X 10.7 and iOS version 5.0 +** and will always return SQLITE_MISUSE. On those systems, +** shared cache mode should be enabled per-database connection via +** [sqlite3_open_v2()] with [SQLITE_OPEN_SHAREDCACHE]. +** +** This interface is threadsafe on processors where writing a +** 32-bit integer is atomic. +** +** See Also: [SQLite Shared-Cache Mode] +*/ +SQLITE_API int sqlite3_enable_shared_cache(int); + +/* +** CAPI3REF: Attempt To Free Heap Memory +** +** ^The sqlite3_release_memory() interface attempts to free N bytes +** of heap memory by deallocating non-essential memory allocations +** held by the database library. Memory used to cache database +** pages to improve performance is an example of non-essential memory. +** ^sqlite3_release_memory() returns the number of bytes actually freed, +** which might be more or less than the amount requested. +** ^The sqlite3_release_memory() routine is a no-op returning zero +** if SQLite is not compiled with [SQLITE_ENABLE_MEMORY_MANAGEMENT]. +** +** See also: [sqlite3_db_release_memory()] +*/ +SQLITE_API int sqlite3_release_memory(int); + +/* +** CAPI3REF: Free Memory Used By A Database Connection +** METHOD: sqlite3 +** +** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap +** memory as possible from database connection D. Unlike the +** [sqlite3_release_memory()] interface, this interface is in effect even +** when the [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is +** omitted. +** +** See also: [sqlite3_release_memory()] +*/ +SQLITE_API int sqlite3_db_release_memory(sqlite3*); + +/* +** CAPI3REF: Impose A Limit On Heap Size +** +** These interfaces impose limits on the amount of heap memory that will be +** used by all database connections within a single process. +** +** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the +** soft limit on the amount of heap memory that may be allocated by SQLite. +** ^SQLite strives to keep heap memory utilization below the soft heap +** limit by reducing the number of pages held in the page cache +** as heap memory usages approaches the limit. +** ^The soft heap limit is "soft" because even though SQLite strives to stay +** below the limit, it will exceed the limit rather than generate +** an [SQLITE_NOMEM] error. In other words, the soft heap limit +** is advisory only. +** +** ^The sqlite3_hard_heap_limit64(N) interface sets a hard upper bound of +** N bytes on the amount of memory that will be allocated. ^The +** sqlite3_hard_heap_limit64(N) interface is similar to +** sqlite3_soft_heap_limit64(N) except that memory allocations will fail +** when the hard heap limit is reached. +** +** ^The return value from both sqlite3_soft_heap_limit64() and +** sqlite3_hard_heap_limit64() is the size of +** the heap limit prior to the call, or negative in the case of an +** error. ^If the argument N is negative +** then no change is made to the heap limit. Hence, the current +** size of heap limits can be determined by invoking +** sqlite3_soft_heap_limit64(-1) or sqlite3_hard_heap_limit(-1). +** +** ^Setting the heap limits to zero disables the heap limiter mechanism. +** +** ^The soft heap limit may not be greater than the hard heap limit. +** ^If the hard heap limit is enabled and if sqlite3_soft_heap_limit(N) +** is invoked with a value of N that is greater than the hard heap limit, +** the soft heap limit is set to the value of the hard heap limit. +** ^The soft heap limit is automatically enabled whenever the hard heap +** limit is enabled. ^When sqlite3_hard_heap_limit64(N) is invoked and +** the soft heap limit is outside the range of 1..N, then the soft heap +** limit is set to N. ^Invoking sqlite3_soft_heap_limit64(0) when the +** hard heap limit is enabled makes the soft heap limit equal to the +** hard heap limit. +** +** The memory allocation limits can also be adjusted using +** [PRAGMA soft_heap_limit] and [PRAGMA hard_heap_limit]. +** +** ^(The heap limits are not enforced in the current implementation +** if one or more of following conditions are true: +** +**
      +**
    • The limit value is set to zero. +**
    • Memory accounting is disabled using a combination of the +** [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and +** the [SQLITE_DEFAULT_MEMSTATUS] compile-time option. +**
    • An alternative page cache implementation is specified using +** [sqlite3_config]([SQLITE_CONFIG_PCACHE2],...). +**
    • The page cache allocates from its own memory pool supplied +** by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than +** from the heap. +**
    )^ +** +** The circumstances under which SQLite will enforce the heap limits may +** change in future releases of SQLite. +*/ +SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N); +SQLITE_API sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 N); + +/* +** CAPI3REF: Deprecated Soft Heap Limit Interface +** DEPRECATED +** +** This is a deprecated version of the [sqlite3_soft_heap_limit64()] +** interface. This routine is provided for historical compatibility +** only. All new applications should use the +** [sqlite3_soft_heap_limit64()] interface rather than this one. +*/ +SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N); + + +/* +** CAPI3REF: Extract Metadata About A Column Of A Table +** METHOD: sqlite3 +** +** ^(The sqlite3_table_column_metadata(X,D,T,C,....) routine returns +** information about column C of table T in database D +** on [database connection] X.)^ ^The sqlite3_table_column_metadata() +** interface returns SQLITE_OK and fills in the non-NULL pointers in +** the final five arguments with appropriate values if the specified +** column exists. ^The sqlite3_table_column_metadata() interface returns +** SQLITE_ERROR if the specified column does not exist. +** ^If the column-name parameter to sqlite3_table_column_metadata() is a +** NULL pointer, then this routine simply checks for the existence of the +** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it +** does not. If the table name parameter T in a call to +** sqlite3_table_column_metadata(X,D,T,C,...) is NULL then the result is +** undefined behavior. +** +** ^The column is identified by the second, third and fourth parameters to +** this function. ^(The second parameter is either the name of the database +** (i.e. "main", "temp", or an attached database) containing the specified +** table or NULL.)^ ^If it is NULL, then all attached databases are searched +** for the table using the same algorithm used by the database engine to +** resolve unqualified table references. +** +** ^The third and fourth parameters to this function are the table and column +** name of the desired column, respectively. +** +** ^Metadata is returned by writing to the memory locations passed as the 5th +** and subsequent parameters to this function. ^Any of these arguments may be +** NULL, in which case the corresponding element of metadata is omitted. +** +** ^(
    +** +**
    Parameter Output
    Type
    Description +** +**
    5th const char* Data type +**
    6th const char* Name of default collation sequence +**
    7th int True if column has a NOT NULL constraint +**
    8th int True if column is part of the PRIMARY KEY +**
    9th int True if column is [AUTOINCREMENT] +**
    +**
    )^ +** +** ^The memory pointed to by the character pointers returned for the +** declaration type and collation sequence is valid until the next +** call to any SQLite API function. +** +** ^If the specified table is actually a view, an [error code] is returned. +** +** ^If the specified column is "rowid", "oid" or "_rowid_" and the table +** is not a [WITHOUT ROWID] table and an +** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output +** parameters are set for the explicitly declared column. ^(If there is no +** [INTEGER PRIMARY KEY] column, then the outputs +** for the [rowid] are set as follows: +** +**
    +**     data type: "INTEGER"
    +**     collation sequence: "BINARY"
    +**     not null: 0
    +**     primary key: 1
    +**     auto increment: 0
    +** 
    )^ +** +** ^This function causes all database schemas to be read from disk and +** parsed, if that has not already been done, and returns an error if +** any errors are encountered while loading the schema. +*/ +SQLITE_API int sqlite3_table_column_metadata( + sqlite3 *db, /* Connection handle */ + const char *zDbName, /* Database name or NULL */ + const char *zTableName, /* Table name */ + const char *zColumnName, /* Column name */ + char const **pzDataType, /* OUTPUT: Declared data type */ + char const **pzCollSeq, /* OUTPUT: Collation sequence name */ + int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ + int *pPrimaryKey, /* OUTPUT: True if column part of PK */ + int *pAutoinc /* OUTPUT: True if column is auto-increment */ +); + +/* +** CAPI3REF: Load An Extension +** METHOD: sqlite3 +** +** ^This interface loads an SQLite extension library from the named file. +** +** ^The sqlite3_load_extension() interface attempts to load an +** [SQLite extension] library contained in the file zFile. If +** the file cannot be loaded directly, attempts are made to load +** with various operating-system specific filename extensions added. +** So for example, if "samplelib" cannot be loaded, then names like +** "samplelib.so" or "samplelib.dylib" or "samplelib.dll" might +** be tried also. +** +** ^The entry point is zProc. +** ^(zProc may be 0, in which case SQLite will try to come up with an +** entry point name on its own. It first tries "sqlite3_extension_init". +** If that does not work, it tries names of the form "sqlite3_X_init" +** where X consists of the lower-case equivalent of all ASCII alphabetic +** characters or all ASCII alphanumeric characters in the filename from +** the last "/" to the first following "." and omitting any initial "lib".)^ +** ^The sqlite3_load_extension() interface returns +** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong. +** ^If an error occurs and pzErrMsg is not 0, then the +** [sqlite3_load_extension()] interface shall attempt to +** fill *pzErrMsg with error message text stored in memory +** obtained from [sqlite3_malloc()]. The calling function +** should free this memory by calling [sqlite3_free()]. +** +** ^Extension loading must be enabled using +** [sqlite3_enable_load_extension()] or +** [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],1,NULL) +** prior to calling this API, +** otherwise an error will be returned. +** +** Security warning: It is recommended that the +** [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method be used to enable only this +** interface. The use of the [sqlite3_enable_load_extension()] interface +** should be avoided. This will keep the SQL function [load_extension()] +** disabled and prevent SQL injections from giving attackers +** access to extension loading capabilities. +** +** See also the [load_extension() SQL function]. +*/ +SQLITE_API int sqlite3_load_extension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Derived from zFile if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +); + +/* +** CAPI3REF: Enable Or Disable Extension Loading +** METHOD: sqlite3 +** +** ^So as not to open security holes in older applications that are +** unprepared to deal with [extension loading], and as a means of disabling +** [extension loading] while evaluating user-entered SQL, the following API +** is provided to turn the [sqlite3_load_extension()] mechanism on and off. +** +** ^Extension loading is off by default. +** ^Call the sqlite3_enable_load_extension() routine with onoff==1 +** to turn extension loading on and call it with onoff==0 to turn +** it back off again. +** +** ^This interface enables or disables both the C-API +** [sqlite3_load_extension()] and the SQL function [load_extension()]. +** ^(Use [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],..) +** to enable or disable only the C-API.)^ +** +** Security warning: It is recommended that extension loading +** be enabled using the [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method +** rather than this interface, so the [load_extension()] SQL function +** remains disabled. This will prevent SQL injections from giving attackers +** access to extension loading capabilities. +*/ +SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff); + +/* +** CAPI3REF: Automatically Load Statically Linked Extensions +** +** ^This interface causes the xEntryPoint() function to be invoked for +** each new [database connection] that is created. The idea here is that +** xEntryPoint() is the entry point for a statically linked [SQLite extension] +** that is to be automatically loaded into all new database connections. +** +** ^(Even though the function prototype shows that xEntryPoint() takes +** no arguments and returns void, SQLite invokes xEntryPoint() with three +** arguments and expects an integer result as if the signature of the +** entry point were as follows: +** +**
    +**    int xEntryPoint(
    +**      sqlite3 *db,
    +**      char **pzErrMsg,
    +**      const struct sqlite3_api_routines *pThunk
    +**    );
    +** 
    )^ +** +** If the xEntryPoint routine encounters an error, it should make *pzErrMsg +** point to an appropriate error message (obtained from [sqlite3_mprintf()]) +** and return an appropriate [error code]. ^SQLite ensures that *pzErrMsg +** is NULL before calling the xEntryPoint(). ^SQLite will invoke +** [sqlite3_free()] on *pzErrMsg after xEntryPoint() returns. ^If any +** xEntryPoint() returns an error, the [sqlite3_open()], [sqlite3_open16()], +** or [sqlite3_open_v2()] call that provoked the xEntryPoint() will fail. +** +** ^Calling sqlite3_auto_extension(X) with an entry point X that is already +** on the list of automatic extensions is a harmless no-op. ^No entry point +** will be called more than once for each database connection that is opened. +** +** See also: [sqlite3_reset_auto_extension()] +** and [sqlite3_cancel_auto_extension()] +*/ +SQLITE_API int sqlite3_auto_extension(void(*xEntryPoint)(void)); + +/* +** CAPI3REF: Cancel Automatic Extension Loading +** +** ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the +** initialization routine X that was registered using a prior call to +** [sqlite3_auto_extension(X)]. ^The [sqlite3_cancel_auto_extension(X)] +** routine returns 1 if initialization routine X was successfully +** unregistered and it returns 0 if X was not on the list of initialization +** routines. +*/ +SQLITE_API int sqlite3_cancel_auto_extension(void(*xEntryPoint)(void)); + +/* +** CAPI3REF: Reset Automatic Extension Loading +** +** ^This interface disables all automatic extensions previously +** registered using [sqlite3_auto_extension()]. +*/ +SQLITE_API void sqlite3_reset_auto_extension(void); + +/* +** Structures used by the virtual table interface +*/ +typedef struct sqlite3_vtab sqlite3_vtab; +typedef struct sqlite3_index_info sqlite3_index_info; +typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; +typedef struct sqlite3_module sqlite3_module; + +/* +** CAPI3REF: Virtual Table Object +** KEYWORDS: sqlite3_module {virtual table module} +** +** This structure, sometimes called a "virtual table module", +** defines the implementation of a [virtual table]. +** This structure consists mostly of methods for the module. +** +** ^A virtual table module is created by filling in a persistent +** instance of this structure and passing a pointer to that instance +** to [sqlite3_create_module()] or [sqlite3_create_module_v2()]. +** ^The registration remains valid until it is replaced by a different +** module or until the [database connection] closes. The content +** of this structure must not change while it is registered with +** any database connection. +*/ +struct sqlite3_module { + int iVersion; + int (*xCreate)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xConnect)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); + int (*xDisconnect)(sqlite3_vtab *pVTab); + int (*xDestroy)(sqlite3_vtab *pVTab); + int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); + int (*xClose)(sqlite3_vtab_cursor*); + int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, + int argc, sqlite3_value **argv); + int (*xNext)(sqlite3_vtab_cursor*); + int (*xEof)(sqlite3_vtab_cursor*); + int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); + int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid); + int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *); + int (*xBegin)(sqlite3_vtab *pVTab); + int (*xSync)(sqlite3_vtab *pVTab); + int (*xCommit)(sqlite3_vtab *pVTab); + int (*xRollback)(sqlite3_vtab *pVTab); + int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), + void **ppArg); + int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); + /* The methods above are in version 1 of the sqlite_module object. Those + ** below are for version 2 and greater. */ + int (*xSavepoint)(sqlite3_vtab *pVTab, int); + int (*xRelease)(sqlite3_vtab *pVTab, int); + int (*xRollbackTo)(sqlite3_vtab *pVTab, int); + /* The methods above are in versions 1 and 2 of the sqlite_module object. + ** Those below are for version 3 and greater. */ + int (*xShadowName)(const char*); + /* The methods above are in versions 1 through 3 of the sqlite_module object. + ** Those below are for version 4 and greater. */ + int (*xIntegrity)(sqlite3_vtab *pVTab, const char *zSchema, + const char *zTabName, int mFlags, char **pzErr); +}; + +/* +** CAPI3REF: Virtual Table Indexing Information +** KEYWORDS: sqlite3_index_info +** +** The sqlite3_index_info structure and its substructures is used as part +** of the [virtual table] interface to +** pass information into and receive the reply from the [xBestIndex] +** method of a [virtual table module]. The fields under **Inputs** are the +** inputs to xBestIndex and are read-only. xBestIndex inserts its +** results into the **Outputs** fields. +** +** ^(The aConstraint[] array records WHERE clause constraints of the form: +** +**
    column OP expr
    +** +** where OP is =, <, <=, >, or >=.)^ ^(The particular operator is +** stored in aConstraint[].op using one of the +** [SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_ values].)^ +** ^(The index of the column is stored in +** aConstraint[].iColumn.)^ ^(aConstraint[].usable is TRUE if the +** expr on the right-hand side can be evaluated (and thus the constraint +** is usable) and false if it cannot.)^ +** +** ^The optimizer automatically inverts terms of the form "expr OP column" +** and makes other simplifications to the WHERE clause in an attempt to +** get as many WHERE clause terms into the form shown above as possible. +** ^The aConstraint[] array only reports WHERE clause terms that are +** relevant to the particular virtual table being queried. +** +** ^Information about the ORDER BY clause is stored in aOrderBy[]. +** ^Each term of aOrderBy records a column of the ORDER BY clause. +** +** The colUsed field indicates which columns of the virtual table may be +** required by the current scan. Virtual table columns are numbered from +** zero in the order in which they appear within the CREATE TABLE statement +** passed to sqlite3_declare_vtab(). For the first 63 columns (columns 0-62), +** the corresponding bit is set within the colUsed mask if the column may be +** required by SQLite. If the table has at least 64 columns and any column +** to the right of the first 63 is required, then bit 63 of colUsed is also +** set. In other words, column iCol may be required if the expression +** (colUsed & ((sqlite3_uint64)1 << (iCol>=63 ? 63 : iCol))) evaluates to +** non-zero. +** +** The [xBestIndex] method must fill aConstraintUsage[] with information +** about what parameters to pass to xFilter. ^If argvIndex>0 then +** the right-hand side of the corresponding aConstraint[] is evaluated +** and becomes the argvIndex-th entry in argv. ^(If aConstraintUsage[].omit +** is true, then the constraint is assumed to be fully handled by the +** virtual table and might not be checked again by the byte code.)^ ^(The +** aConstraintUsage[].omit flag is an optimization hint. When the omit flag +** is left in its default setting of false, the constraint will always be +** checked separately in byte code. If the omit flag is changed to true, then +** the constraint may or may not be checked in byte code. In other words, +** when the omit flag is true there is no guarantee that the constraint will +** not be checked again using byte code.)^ +** +** ^The idxNum and idxStr values are recorded and passed into the +** [xFilter] method. +** ^[sqlite3_free()] is used to free idxStr if and only if +** needToFreeIdxStr is true. +** +** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in +** the correct order to satisfy the ORDER BY clause so that no separate +** sorting step is required. +** +** ^The estimatedCost value is an estimate of the cost of a particular +** strategy. A cost of N indicates that the cost of the strategy is similar +** to a linear scan of an SQLite table with N rows. A cost of log(N) +** indicates that the expense of the operation is similar to that of a +** binary search on a unique indexed field of an SQLite table with N rows. +** +** ^The estimatedRows value is an estimate of the number of rows that +** will be returned by the strategy. +** +** The xBestIndex method may optionally populate the idxFlags field with a +** mask of SQLITE_INDEX_SCAN_* flags. One such flag is +** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN] +** output to show the idxNum as hex instead of as decimal. Another flag is +** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will +** return at most one row. +** +** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then +** SQLite also assumes that if a call to the xUpdate() method is made as +** part of the same statement to delete or update a virtual table row and the +** implementation returns SQLITE_CONSTRAINT, then there is no need to rollback +** any database changes. In other words, if the xUpdate() returns +** SQLITE_CONSTRAINT, the database contents must be exactly as they were +** before xUpdate was called. By contrast, if SQLITE_INDEX_SCAN_UNIQUE is not +** set and xUpdate returns SQLITE_CONSTRAINT, any database changes made by +** the xUpdate method are automatically rolled back by SQLite. +** +** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info +** structure for SQLite [version 3.8.2] ([dateof:3.8.2]). +** If a virtual table extension is +** used with an SQLite version earlier than 3.8.2, the results of attempting +** to read or write the estimatedRows field are undefined (but are likely +** to include crashing the application). The estimatedRows field should +** therefore only be used if [sqlite3_libversion_number()] returns a +** value greater than or equal to 3008002. Similarly, the idxFlags field +** was added for [version 3.9.0] ([dateof:3.9.0]). +** It may therefore only be used if +** sqlite3_libversion_number() returns a value greater than or equal to +** 3009000. +*/ +struct sqlite3_index_info { + /* Inputs */ + int nConstraint; /* Number of entries in aConstraint */ + struct sqlite3_index_constraint { + int iColumn; /* Column constrained. -1 for ROWID */ + unsigned char op; /* Constraint operator */ + unsigned char usable; /* True if this constraint is usable */ + int iTermOffset; /* Used internally - xBestIndex should ignore */ + } *aConstraint; /* Table of WHERE clause constraints */ + int nOrderBy; /* Number of terms in the ORDER BY clause */ + struct sqlite3_index_orderby { + int iColumn; /* Column number */ + unsigned char desc; /* True for DESC. False for ASC. */ + } *aOrderBy; /* The ORDER BY clause */ + /* Outputs */ + struct sqlite3_index_constraint_usage { + int argvIndex; /* if >0, constraint is part of argv to xFilter */ + unsigned char omit; /* Do not code a test for this constraint */ + } *aConstraintUsage; + int idxNum; /* Number used to identify the index */ + char *idxStr; /* String, possibly obtained from sqlite3_malloc */ + int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ + int orderByConsumed; /* True if output is already ordered */ + double estimatedCost; /* Estimated cost of using this index */ + /* Fields below are only available in SQLite 3.8.2 and later */ + sqlite3_int64 estimatedRows; /* Estimated number of rows returned */ + /* Fields below are only available in SQLite 3.9.0 and later */ + int idxFlags; /* Mask of SQLITE_INDEX_SCAN_* flags */ + /* Fields below are only available in SQLite 3.10.0 and later */ + sqlite3_uint64 colUsed; /* Input: Mask of columns used by statement */ +}; + +/* +** CAPI3REF: Virtual Table Scan Flags +** +** Virtual table implementations are allowed to set the +** [sqlite3_index_info].idxFlags field to some combination of +** these bits. +*/ +#define SQLITE_INDEX_SCAN_UNIQUE 0x00000001 /* Scan visits at most 1 row */ +#define SQLITE_INDEX_SCAN_HEX 0x00000002 /* Display idxNum as hex */ + /* in EXPLAIN QUERY PLAN */ + +/* +** CAPI3REF: Virtual Table Constraint Operator Codes +** +** These macros define the allowed values for the +** [sqlite3_index_info].aConstraint[].op field. Each value represents +** an operator that is part of a constraint term in the WHERE clause of +** a query that uses a [virtual table]. +** +** ^The left-hand operand of the operator is given by the corresponding +** aConstraint[].iColumn field. ^An iColumn of -1 indicates the left-hand +** operand is the rowid. +** The SQLITE_INDEX_CONSTRAINT_LIMIT and SQLITE_INDEX_CONSTRAINT_OFFSET +** operators have no left-hand operand, and so for those operators the +** corresponding aConstraint[].iColumn is meaningless and should not be +** used. +** +** All operator values from SQLITE_INDEX_CONSTRAINT_FUNCTION through +** value 255 are reserved to represent functions that are overloaded +** by the [xFindFunction|xFindFunction method] of the virtual table +** implementation. +** +** The right-hand operands for each constraint might be accessible using +** the [sqlite3_vtab_rhs_value()] interface. Usually the right-hand +** operand is only available if it appears as a single constant literal +** in the input SQL. If the right-hand operand is another column or an +** expression (even a constant expression) or a parameter, then the +** sqlite3_vtab_rhs_value() probably will not be able to extract it. +** ^The SQLITE_INDEX_CONSTRAINT_ISNULL and +** SQLITE_INDEX_CONSTRAINT_ISNOTNULL operators have no right-hand operand +** and hence calls to sqlite3_vtab_rhs_value() for those operators will +** always return SQLITE_NOTFOUND. +** +** The collating sequence to be used for comparison can be found using +** the [sqlite3_vtab_collation()] interface. For most real-world virtual +** tables, the collating sequence of constraints does not matter (for example +** because the constraints are numeric) and so the sqlite3_vtab_collation() +** interface is not commonly needed. +*/ +#define SQLITE_INDEX_CONSTRAINT_EQ 2 +#define SQLITE_INDEX_CONSTRAINT_GT 4 +#define SQLITE_INDEX_CONSTRAINT_LE 8 +#define SQLITE_INDEX_CONSTRAINT_LT 16 +#define SQLITE_INDEX_CONSTRAINT_GE 32 +#define SQLITE_INDEX_CONSTRAINT_MATCH 64 +#define SQLITE_INDEX_CONSTRAINT_LIKE 65 +#define SQLITE_INDEX_CONSTRAINT_GLOB 66 +#define SQLITE_INDEX_CONSTRAINT_REGEXP 67 +#define SQLITE_INDEX_CONSTRAINT_NE 68 +#define SQLITE_INDEX_CONSTRAINT_ISNOT 69 +#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70 +#define SQLITE_INDEX_CONSTRAINT_ISNULL 71 +#define SQLITE_INDEX_CONSTRAINT_IS 72 +#define SQLITE_INDEX_CONSTRAINT_LIMIT 73 +#define SQLITE_INDEX_CONSTRAINT_OFFSET 74 +#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150 + +/* +** CAPI3REF: Register A Virtual Table Implementation +** METHOD: sqlite3 +** +** ^These routines are used to register a new [virtual table module] name. +** ^Module names must be registered before +** creating a new [virtual table] using the module and before using a +** preexisting [virtual table] for the module. +** +** ^The module name is registered on the [database connection] specified +** by the first parameter. ^The name of the module is given by the +** second parameter. ^The third parameter is a pointer to +** the implementation of the [virtual table module]. ^The fourth +** parameter is an arbitrary client data pointer that is passed through +** into the [xCreate] and [xConnect] methods of the virtual table module +** when a new virtual table is being created or reinitialized. +** +** ^The sqlite3_create_module_v2() interface has a fifth parameter which +** is a pointer to a destructor for the pClientData. ^SQLite will +** invoke the destructor function (if it is not NULL) when SQLite +** no longer needs the pClientData pointer. ^The destructor will also +** be invoked if the call to sqlite3_create_module_v2() fails. +** ^The sqlite3_create_module() +** interface is equivalent to sqlite3_create_module_v2() with a NULL +** destructor. +** +** ^If the third parameter (the pointer to the sqlite3_module object) is +** NULL then no new module is created and any existing modules with the +** same name are dropped. +** +** See also: [sqlite3_drop_modules()] +*/ +SQLITE_API int sqlite3_create_module( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *p, /* Methods for the module */ + void *pClientData /* Client data for xCreate/xConnect */ +); +SQLITE_API int sqlite3_create_module_v2( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *p, /* Methods for the module */ + void *pClientData, /* Client data for xCreate/xConnect */ + void(*xDestroy)(void*) /* Module destructor function */ +); + +/* +** CAPI3REF: Remove Unnecessary Virtual Table Implementations +** METHOD: sqlite3 +** +** ^The sqlite3_drop_modules(D,L) interface removes all virtual +** table modules from database connection D except those named on list L. +** The L parameter must be either NULL or a pointer to an array of pointers +** to strings where the array is terminated by a single NULL pointer. +** ^If the L parameter is NULL, then all virtual table modules are removed. +** +** See also: [sqlite3_create_module()] +*/ +SQLITE_API int sqlite3_drop_modules( + sqlite3 *db, /* Remove modules from this connection */ + const char **azKeep /* Except, do not remove the ones named here */ +); + +/* +** CAPI3REF: Virtual Table Instance Object +** KEYWORDS: sqlite3_vtab +** +** Every [virtual table module] implementation uses a subclass +** of this object to describe a particular instance +** of the [virtual table]. Each subclass will +** be tailored to the specific needs of the module implementation. +** The purpose of this superclass is to define certain fields that are +** common to all module implementations. +** +** ^Virtual tables methods can set an error message by assigning a +** string obtained from [sqlite3_mprintf()] to zErrMsg. The method should +** take care that any prior string is freed by a call to [sqlite3_free()] +** prior to assigning a new string to zErrMsg. ^After the error message +** is delivered up to the client application, the string will be automatically +** freed by sqlite3_free() and the zErrMsg field will be zeroed. +*/ +struct sqlite3_vtab { + const sqlite3_module *pModule; /* The module for this virtual table */ + int nRef; /* Number of open cursors */ + char *zErrMsg; /* Error message from sqlite3_mprintf() */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* +** CAPI3REF: Virtual Table Cursor Object +** KEYWORDS: sqlite3_vtab_cursor {virtual table cursor} +** +** Every [virtual table module] implementation uses a subclass of the +** following structure to describe cursors that point into the +** [virtual table] and are used +** to loop through the virtual table. Cursors are created using the +** [sqlite3_module.xOpen | xOpen] method of the module and are destroyed +** by the [sqlite3_module.xClose | xClose] method. Cursors are used +** by the [xFilter], [xNext], [xEof], [xColumn], and [xRowid] methods +** of the module. Each module implementation will define +** the content of a cursor structure to suit its own needs. +** +** This superclass exists in order to define fields of the cursor that +** are common to all implementations. +*/ +struct sqlite3_vtab_cursor { + sqlite3_vtab *pVtab; /* Virtual table of this cursor */ + /* Virtual table implementations will typically add additional fields */ +}; + +/* +** CAPI3REF: Declare The Schema Of A Virtual Table +** +** ^The [xCreate] and [xConnect] methods of a +** [virtual table module] call this interface +** to declare the format (the names and datatypes of the columns) of +** the virtual tables they implement. +*/ +SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL); + +/* +** CAPI3REF: Overload A Function For A Virtual Table +** METHOD: sqlite3 +** +** ^(Virtual tables can provide alternative implementations of functions +** using the [xFindFunction] method of the [virtual table module]. +** But global versions of those functions +** must exist in order to be overloaded.)^ +** +** ^(This API makes sure a global version of a function with a particular +** name and number of parameters exists. If no such function exists +** before this API is called, a new function is created.)^ ^The implementation +** of the new function always causes an exception to be thrown. So +** the new function is not good for anything by itself. Its only +** purpose is to be a placeholder function that can be overloaded +** by a [virtual table]. +*/ +SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); + +/* +** CAPI3REF: A Handle To An Open BLOB +** KEYWORDS: {BLOB handle} {BLOB handles} +** +** An instance of this object represents an open BLOB on which +** [sqlite3_blob_open | incremental BLOB I/O] can be performed. +** ^Objects of this type are created by [sqlite3_blob_open()] +** and destroyed by [sqlite3_blob_close()]. +** ^The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces +** can be used to read or write small subsections of the BLOB. +** ^The [sqlite3_blob_bytes()] interface returns the size of the BLOB in bytes. +*/ +typedef struct sqlite3_blob sqlite3_blob; + +/* +** CAPI3REF: Open A BLOB For Incremental I/O +** METHOD: sqlite3 +** CONSTRUCTOR: sqlite3_blob +** +** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located +** in row iRow, column zColumn, table zTable in database zDb; +** in other words, the same BLOB that would be selected by: +** +**
    +**     SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
    +** 
    )^ +** +** ^(Parameter zDb is not the filename that contains the database, but +** rather the symbolic name of the database. For attached databases, this is +** the name that appears after the AS keyword in the [ATTACH] statement. +** For the main database file, the database name is "main". For TEMP +** tables, the database name is "temp".)^ +** +** ^If the flags parameter is non-zero, then the BLOB is opened for read +** and write access. ^If the flags parameter is zero, the BLOB is opened for +** read-only access. +** +** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored +** in *ppBlob. Otherwise an [error code] is returned and, unless the error +** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided +** the API is not misused, it is always safe to call [sqlite3_blob_close()] +** on *ppBlob after this function returns. +** +** This function fails with SQLITE_ERROR if any of the following are true: +**
      +**
    • ^(Database zDb does not exist)^, +**
    • ^(Table zTable does not exist within database zDb)^, +**
    • ^(Table zTable is a WITHOUT ROWID table)^, +**
    • ^(Column zColumn does not exist)^, +**
    • ^(Row iRow is not present in the table)^, +**
    • ^(The specified column of row iRow contains a value that is not +** a TEXT or BLOB value)^, +**
    • ^(Column zColumn is part of an index, PRIMARY KEY or UNIQUE +** constraint and the blob is being opened for read/write access)^, +**
    • ^([foreign key constraints | Foreign key constraints] are enabled, +** column zColumn is part of a [child key] definition and the blob is +** being opened for read/write access)^. +**
    +** +** ^Unless it returns SQLITE_MISUSE, this function sets the +** [database connection] error code and message accessible via +** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. +** +** A BLOB referenced by sqlite3_blob_open() may be read using the +** [sqlite3_blob_read()] interface and modified by using +** [sqlite3_blob_write()]. The [BLOB handle] can be moved to a +** different row of the same table using the [sqlite3_blob_reopen()] +** interface. However, the column, table, or database of a [BLOB handle] +** cannot be changed after the [BLOB handle] is opened. +** +** ^(If the row that a BLOB handle points to is modified by an +** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects +** then the BLOB handle is marked as "expired". +** This is true if any column of the row is changed, even a column +** other than the one the BLOB handle is open on.)^ +** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for +** an expired BLOB handle fail with a return code of [SQLITE_ABORT]. +** ^(Changes written into a BLOB prior to the BLOB expiring are not +** rolled back by the expiration of the BLOB. Such changes will eventually +** commit if the transaction continues to completion.)^ +** +** ^Use the [sqlite3_blob_bytes()] interface to determine the size of +** the opened blob. ^The size of a blob may not be changed by this +** interface. Use the [UPDATE] SQL command to change the size of a +** blob. +** +** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces +** and the built-in [zeroblob] SQL function may be used to create a +** zero-filled blob to read or write using the incremental-blob interface. +** +** To avoid a resource leak, every open [BLOB handle] should eventually +** be released by a call to [sqlite3_blob_close()]. +** +** See also: [sqlite3_blob_close()], +** [sqlite3_blob_reopen()], [sqlite3_blob_read()], +** [sqlite3_blob_bytes()], [sqlite3_blob_write()]. +*/ +SQLITE_API int sqlite3_blob_open( + sqlite3*, + const char *zDb, + const char *zTable, + const char *zColumn, + sqlite3_int64 iRow, + int flags, + sqlite3_blob **ppBlob +); + +/* +** CAPI3REF: Move a BLOB Handle to a New Row +** METHOD: sqlite3_blob +** +** ^This function is used to move an existing [BLOB handle] so that it points +** to a different row of the same database table. ^The new row is identified +** by the rowid value passed as the second argument. Only the row can be +** changed. ^The database, table and column on which the blob handle is open +** remain the same. Moving an existing [BLOB handle] to a new row is +** faster than closing the existing handle and opening a new one. +** +** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] - +** it must exist and there must be either a blob or text value stored in +** the nominated column.)^ ^If the new row is not present in the table, or if +** it does not contain a blob or text value, or if another error occurs, an +** SQLite error code is returned and the blob handle is considered aborted. +** ^All subsequent calls to [sqlite3_blob_read()], [sqlite3_blob_write()] or +** [sqlite3_blob_reopen()] on an aborted blob handle immediately return +** SQLITE_ABORT. ^Calling [sqlite3_blob_bytes()] on an aborted blob handle +** always returns zero. +** +** ^This function sets the database handle error code and message. +*/ +SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64); + +/* +** CAPI3REF: Close A BLOB Handle +** DESTRUCTOR: sqlite3_blob +** +** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed +** unconditionally. Even if this routine returns an error code, the +** handle is still closed.)^ +** +** ^If the blob handle being closed was opened for read-write access, and if +** the database is in auto-commit mode and there are no other open read-write +** blob handles or active write statements, the current transaction is +** committed. ^If an error occurs while committing the transaction, an error +** code is returned and the transaction rolled back. +** +** Calling this function with an argument that is not a NULL pointer or an +** open blob handle results in undefined behavior. ^Calling this routine +** with a null pointer (such as would be returned by a failed call to +** [sqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function +** is passed a valid open blob handle, the values returned by the +** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning. +*/ +SQLITE_API int sqlite3_blob_close(sqlite3_blob *); + +/* +** CAPI3REF: Return The Size Of An Open BLOB +** METHOD: sqlite3_blob +** +** ^Returns the size in bytes of the BLOB accessible via the +** successfully opened [BLOB handle] in its only argument. ^The +** incremental blob I/O routines can only read or overwrite existing +** blob content; they cannot change the size of a blob. +** +** This routine only works on a [BLOB handle] which has been created +** by a prior successful call to [sqlite3_blob_open()] and which has not +** been closed by [sqlite3_blob_close()]. Passing any other pointer in +** to this routine results in undefined and probably undesirable behavior. +*/ +SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *); + +/* +** CAPI3REF: Read Data From A BLOB Incrementally +** METHOD: sqlite3_blob +** +** ^(This function is used to read data from an open [BLOB handle] into a +** caller-supplied buffer. N bytes of data are copied into buffer Z +** from the open BLOB, starting at offset iOffset.)^ +** +** ^If offset iOffset is less than N bytes from the end of the BLOB, +** [SQLITE_ERROR] is returned and no data is read. ^If N or iOffset is +** less than zero, [SQLITE_ERROR] is returned and no data is read. +** ^The size of the blob (and hence the maximum value of N+iOffset) +** can be determined using the [sqlite3_blob_bytes()] interface. +** +** ^An attempt to read from an expired [BLOB handle] fails with an +** error code of [SQLITE_ABORT]. +** +** ^(On success, sqlite3_blob_read() returns SQLITE_OK. +** Otherwise, an [error code] or an [extended error code] is returned.)^ +** +** This routine only works on a [BLOB handle] which has been created +** by a prior successful call to [sqlite3_blob_open()] and which has not +** been closed by [sqlite3_blob_close()]. Passing any other pointer in +** to this routine results in undefined and probably undesirable behavior. +** +** See also: [sqlite3_blob_write()]. +*/ +SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset); + +/* +** CAPI3REF: Write Data Into A BLOB Incrementally +** METHOD: sqlite3_blob +** +** ^(This function is used to write data into an open [BLOB handle] from a +** caller-supplied buffer. N bytes of data are copied from the buffer Z +** into the open BLOB, starting at offset iOffset.)^ +** +** ^(On success, sqlite3_blob_write() returns SQLITE_OK. +** Otherwise, an [error code] or an [extended error code] is returned.)^ +** ^Unless SQLITE_MISUSE is returned, this function sets the +** [database connection] error code and message accessible via +** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. +** +** ^If the [BLOB handle] passed as the first argument was not opened for +** writing (the flags parameter to [sqlite3_blob_open()] was zero), +** this function returns [SQLITE_READONLY]. +** +** This function may only modify the contents of the BLOB; it is +** not possible to increase the size of a BLOB using this API. +** ^If offset iOffset is less than N bytes from the end of the BLOB, +** [SQLITE_ERROR] is returned and no data is written. The size of the +** BLOB (and hence the maximum value of N+iOffset) can be determined +** using the [sqlite3_blob_bytes()] interface. ^If N or iOffset are less +** than zero [SQLITE_ERROR] is returned and no data is written. +** +** ^An attempt to write to an expired [BLOB handle] fails with an +** error code of [SQLITE_ABORT]. ^Writes to the BLOB that occurred +** before the [BLOB handle] expired are not rolled back by the +** expiration of the handle, though of course those changes might +** have been overwritten by the statement that expired the BLOB handle +** or by other independent statements. +** +** This routine only works on a [BLOB handle] which has been created +** by a prior successful call to [sqlite3_blob_open()] and which has not +** been closed by [sqlite3_blob_close()]. Passing any other pointer in +** to this routine results in undefined and probably undesirable behavior. +** +** See also: [sqlite3_blob_read()]. +*/ +SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); + +/* +** CAPI3REF: Virtual File System Objects +** +** A virtual filesystem (VFS) is an [sqlite3_vfs] object +** that SQLite uses to interact +** with the underlying operating system. Most SQLite builds come with a +** single default VFS that is appropriate for the host computer. +** New VFSes can be registered and existing VFSes can be unregistered. +** The following interfaces are provided. +** +** ^The sqlite3_vfs_find() interface returns a pointer to a VFS given its name. +** ^Names are case sensitive. +** ^Names are zero-terminated UTF-8 strings. +** ^If there is no match, a NULL pointer is returned. +** ^If zVfsName is NULL then the default VFS is returned. +** +** ^New VFSes are registered with sqlite3_vfs_register(). +** ^Each new VFS becomes the default VFS if the makeDflt flag is set. +** ^The same VFS can be registered multiple times without injury. +** ^To make an existing VFS into the default VFS, register it again +** with the makeDflt flag set. If two different VFSes with the +** same name are registered, the behavior is undefined. If a +** VFS is registered with a name that is NULL or an empty string, +** then the behavior is undefined. +** +** ^Unregister a VFS with the sqlite3_vfs_unregister() interface. +** ^(If the default VFS is unregistered, another VFS is chosen as +** the default. The choice for the new VFS is arbitrary.)^ +*/ +SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); +SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); +SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); + +/* +** CAPI3REF: Mutexes +** +** The SQLite core uses these routines for thread +** synchronization. Though they are intended for internal +** use by SQLite, code that links against SQLite is +** permitted to use any of these routines. +** +** The SQLite source code contains multiple implementations +** of these mutex routines. An appropriate implementation +** is selected automatically at compile-time. The following +** implementations are available in the SQLite core: +** +**
      +**
    • SQLITE_MUTEX_PTHREADS +**
    • SQLITE_MUTEX_W32 +**
    • SQLITE_MUTEX_NOOP +**
    +** +** The SQLITE_MUTEX_NOOP implementation is a set of routines +** that does no real locking and is appropriate for use in +** a single-threaded application. The SQLITE_MUTEX_PTHREADS and +** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix +** and Windows. +** +** +** ^The sqlite3_mutex_alloc() routine allocates a new +** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc() +** routine returns NULL if it is unable to allocate the requested +** mutex. The argument to sqlite3_mutex_alloc() must be one of these +** integer constants: +** +**
      +**
    • SQLITE_MUTEX_FAST +**
    • SQLITE_MUTEX_RECURSIVE +**
    • SQLITE_MUTEX_STATIC_MAIN +**
    • SQLITE_MUTEX_STATIC_MEM +**
    • SQLITE_MUTEX_STATIC_OPEN +**
    • SQLITE_MUTEX_STATIC_PRNG +**
    • SQLITE_MUTEX_STATIC_LRU +**
    • SQLITE_MUTEX_STATIC_PMEM +**
    • SQLITE_MUTEX_STATIC_APP1 +**
    • SQLITE_MUTEX_STATIC_APP2 +**
    • SQLITE_MUTEX_STATIC_APP3 +**
    • SQLITE_MUTEX_STATIC_VFS1 +**
    • SQLITE_MUTEX_STATIC_VFS2 +**
    • SQLITE_MUTEX_STATIC_VFS3 +**
    +** +** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) +** cause sqlite3_mutex_alloc() to create +** a new mutex. ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE +** is used but not necessarily so when SQLITE_MUTEX_FAST is used. +** The mutex implementation does not need to make a distinction +** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does +** not want to. SQLite will only request a recursive mutex in +** cases where it really needs one. If a faster non-recursive mutex +** implementation is available on the host platform, the mutex subsystem +** might return such a mutex in response to SQLITE_MUTEX_FAST. +** +** ^The other allowed parameters to sqlite3_mutex_alloc() (anything other +** than SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) each return +** a pointer to a static preexisting mutex. ^Nine static mutexes are +** used by the current version of SQLite. Future versions of SQLite +** may add additional static mutexes. Static mutexes are for internal +** use by SQLite only. Applications that use SQLite mutexes should +** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or +** SQLITE_MUTEX_RECURSIVE. +** +** ^Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() +** returns a different mutex on every call. ^For the static +** mutex types, the same mutex is returned on every call that has +** the same type number. +** +** ^The sqlite3_mutex_free() routine deallocates a previously +** allocated dynamic mutex. Attempting to deallocate a static +** mutex results in undefined behavior. +** +** ^The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. ^If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. ^The sqlite3_mutex_try() interface returns [SQLITE_OK] +** upon successful entry. ^(Mutexes created using +** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread. +** In such cases, the +** mutex must be exited an equal number of times before another thread +** can enter.)^ If the same thread tries to enter any mutex other +** than an SQLITE_MUTEX_RECURSIVE more than once, the behavior is undefined. +** +** ^(Some systems (for example, Windows 95) do not support the operation +** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() +** will always return SQLITE_BUSY. In most cases the SQLite core only uses +** sqlite3_mutex_try() as an optimization, so this is acceptable +** behavior. The exceptions are unix builds that set the +** SQLITE_ENABLE_SETLK_TIMEOUT build option. In that case a working +** sqlite3_mutex_try() is required.)^ +** +** ^The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. The behavior +** is undefined if the mutex is not currently entered by the +** calling thread or is not currently allocated. +** +** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), +** sqlite3_mutex_leave(), or sqlite3_mutex_free() is a NULL pointer, +** then any of the four routines behaves as a no-op. +** +** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. +*/ +SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int); +SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*); +SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*); +SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*); +SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*); + +/* +** CAPI3REF: Mutex Methods Object +** +** An instance of this structure defines the low-level routines +** used to allocate and use mutexes. +** +** Usually, the default mutex implementations provided by SQLite are +** sufficient, however the application has the option of substituting a custom +** implementation for specialized deployments or systems for which SQLite +** does not provide a suitable implementation. In this case, the application +** creates and populates an instance of this structure to pass +** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option. +** Additionally, an instance of this structure can be used as an +** output variable when querying the system for the current mutex +** implementation, using the [SQLITE_CONFIG_GETMUTEX] option. +** +** ^The xMutexInit method defined by this structure is invoked as +** part of system initialization by the sqlite3_initialize() function. +** ^The xMutexInit routine is called by SQLite exactly once for each +** effective call to [sqlite3_initialize()]. +** +** ^The xMutexEnd method defined by this structure is invoked as +** part of system shutdown by the sqlite3_shutdown() function. The +** implementation of this method is expected to release all outstanding +** resources obtained by the mutex methods implementation, especially +** those obtained by the xMutexInit method. ^The xMutexEnd() +** interface is invoked exactly once for each call to [sqlite3_shutdown()]. +** +** ^(The remaining seven methods defined by this structure (xMutexAlloc, +** xMutexFree, xMutexEnter, xMutexTry, xMutexLeave, xMutexHeld and +** xMutexNotheld) implement the following interfaces (respectively): +** +**
      +**
    • [sqlite3_mutex_alloc()]
    • +**
    • [sqlite3_mutex_free()]
    • +**
    • [sqlite3_mutex_enter()]
    • +**
    • [sqlite3_mutex_try()]
    • +**
    • [sqlite3_mutex_leave()]
    • +**
    • [sqlite3_mutex_held()]
    • +**
    • [sqlite3_mutex_notheld()]
    • +**
    )^ +** +** The only difference is that the public sqlite3_XXX functions enumerated +** above silently ignore any invocations that pass a NULL pointer instead +** of a valid mutex handle. The implementations of the methods defined +** by this structure are not required to handle this case. The results +** of passing a NULL pointer instead of a valid mutex handle are undefined +** (i.e. it is acceptable to provide an implementation that segfaults if +** it is passed a NULL pointer). +** +** The xMutexInit() method must be threadsafe. It must be harmless to +** invoke xMutexInit() multiple times within the same process and without +** intervening calls to xMutexEnd(). Second and subsequent calls to +** xMutexInit() must be no-ops. +** +** xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()] +** and its associates). Similarly, xMutexAlloc() must not use SQLite memory +** allocation for a static mutex. ^However xMutexAlloc() may use SQLite +** memory allocation for a fast or recursive mutex. +** +** ^SQLite will invoke the xMutexEnd() method when [sqlite3_shutdown()] is +** called, but only if the prior call to xMutexInit returned SQLITE_OK. +** If xMutexInit fails in any way, it is expected to clean up after itself +** prior to returning. +*/ +typedef struct sqlite3_mutex_methods sqlite3_mutex_methods; +struct sqlite3_mutex_methods { + int (*xMutexInit)(void); + int (*xMutexEnd)(void); + sqlite3_mutex *(*xMutexAlloc)(int); + void (*xMutexFree)(sqlite3_mutex *); + void (*xMutexEnter)(sqlite3_mutex *); + int (*xMutexTry)(sqlite3_mutex *); + void (*xMutexLeave)(sqlite3_mutex *); + int (*xMutexHeld)(sqlite3_mutex *); + int (*xMutexNotheld)(sqlite3_mutex *); +}; + +/* +** CAPI3REF: Mutex Verification Routines +** +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines +** are intended for use inside assert() statements. The SQLite core +** never uses these routines except inside an assert() and applications +** are advised to follow the lead of the core. The SQLite core only +** provides implementations for these routines when it is compiled +** with the SQLITE_DEBUG flag. External mutex implementations +** are only required to provide these routines if SQLITE_DEBUG is +** defined and if NDEBUG is not defined. +** +** These routines should return true if the mutex in their argument +** is held or not held, respectively, by the calling thread. +** +** The implementation is not required to provide versions of these +** routines that actually work. If the implementation does not provide working +** versions of these routines, it should at least provide stubs that always +** return true so that one does not get spurious assertion failures. +** +** If the argument to sqlite3_mutex_held() is a NULL pointer then +** the routine should return 1. This seems counter-intuitive since +** clearly the mutex cannot be held if it does not exist. But +** the reason the mutex does not exist is because the build is not +** using mutexes. And we do not want the assert() containing the +** call to sqlite3_mutex_held() to fail, so a non-zero return is +** the appropriate thing to do. The sqlite3_mutex_notheld() +** interface should also return 1 when given a NULL pointer. +*/ +#ifndef NDEBUG +SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*); +SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*); +#endif + +/* +** CAPI3REF: Mutex Types +** +** The [sqlite3_mutex_alloc()] interface takes a single argument +** which is one of these integer constants. +** +** The set of static mutexes may change from one SQLite release to the +** next. Applications that override the built-in mutex logic must be +** prepared to accommodate additional static mutexes. +*/ +#define SQLITE_MUTEX_FAST 0 +#define SQLITE_MUTEX_RECURSIVE 1 +#define SQLITE_MUTEX_STATIC_MAIN 2 +#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */ +#define SQLITE_MUTEX_STATIC_MEM2 4 /* NOT USED */ +#define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */ +#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_randomness() */ +#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ +#define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */ +#define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */ +#define SQLITE_MUTEX_STATIC_APP1 8 /* For use by application */ +#define SQLITE_MUTEX_STATIC_APP2 9 /* For use by application */ +#define SQLITE_MUTEX_STATIC_APP3 10 /* For use by application */ +#define SQLITE_MUTEX_STATIC_VFS1 11 /* For use by built-in VFS */ +#define SQLITE_MUTEX_STATIC_VFS2 12 /* For use by extension VFS */ +#define SQLITE_MUTEX_STATIC_VFS3 13 /* For use by application VFS */ + +/* Legacy compatibility: */ +#define SQLITE_MUTEX_STATIC_MASTER 2 + + +/* +** CAPI3REF: Retrieve the mutex for a database connection +** METHOD: sqlite3 +** +** ^This interface returns a pointer to the [sqlite3_mutex] object that +** serializes access to the [database connection] given in the argument +** when the [threading mode] is Serialized. +** ^If the [threading mode] is Single-thread or Multi-thread then this +** routine returns a NULL pointer. +*/ +SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*); + +/* +** CAPI3REF: Low-Level Control Of Database Files +** METHOD: sqlite3 +** KEYWORDS: {file control} +** +** ^The [sqlite3_file_control()] interface makes a direct call to the +** xFileControl method for the [sqlite3_io_methods] object associated +** with a particular database identified by the second argument. ^The +** name of the database is "main" for the main database or "temp" for the +** TEMP database, or the name that appears after the AS keyword for +** databases that are added using the [ATTACH] SQL command. +** ^A NULL pointer can be used in place of "main" to refer to the +** main database file. +** ^The third and fourth parameters to this routine +** are passed directly through to the second and third parameters of +** the xFileControl method. ^The return value of the xFileControl +** method becomes the return value of this routine. +** +** A few opcodes for [sqlite3_file_control()] are handled directly +** by the SQLite core and never invoke the +** sqlite3_io_methods.xFileControl method. +** ^The [SQLITE_FCNTL_FILE_POINTER] value for the op parameter causes +** a pointer to the underlying [sqlite3_file] object to be written into +** the space pointed to by the 4th parameter. The +** [SQLITE_FCNTL_JOURNAL_POINTER] works similarly except that it returns +** the [sqlite3_file] object associated with the journal file instead of +** the main database. The [SQLITE_FCNTL_VFS_POINTER] opcode returns +** a pointer to the underlying [sqlite3_vfs] object for the file. +** The [SQLITE_FCNTL_DATA_VERSION] returns the data version counter +** from the pager. +** +** ^If the second parameter (zDbName) does not match the name of any +** open database file, then SQLITE_ERROR is returned. ^This error +** code is not remembered and will not be recalled by [sqlite3_errcode()] +** or [sqlite3_errmsg()]. The underlying xFileControl method might +** also return SQLITE_ERROR. There is no way to distinguish between +** an incorrect zDbName and an SQLITE_ERROR return from the underlying +** xFileControl method. +** +** See also: [file control opcodes] +*/ +SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); + +/* +** CAPI3REF: Testing Interface +** +** ^The sqlite3_test_control() interface is used to read out internal +** state of SQLite and to inject faults into SQLite for testing +** purposes. ^The first parameter is an operation code that determines +** the number, meaning, and operation of all subsequent parameters. +** +** This interface is not for use by applications. It exists solely +** for verifying the correct operation of the SQLite library. Depending +** on how the SQLite library is compiled, this interface might not exist. +** +** The details of the operation codes, their meanings, the parameters +** they take, and what they do are all subject to change without notice. +** Unlike most of the SQLite API, this function is not guaranteed to +** operate consistently from one release to the next. +*/ +SQLITE_API int sqlite3_test_control(int op, ...); + +/* +** CAPI3REF: Testing Interface Operation Codes +** +** These constants are the valid operation code parameters used +** as the first argument to [sqlite3_test_control()]. +** +** These parameters and their meanings are subject to change +** without notice. These values are for testing purposes only. +** Applications should not use any of these parameters or the +** [sqlite3_test_control()] interface. +*/ +#define SQLITE_TESTCTRL_FIRST 5 +#define SQLITE_TESTCTRL_PRNG_SAVE 5 +#define SQLITE_TESTCTRL_PRNG_RESTORE 6 +#define SQLITE_TESTCTRL_PRNG_RESET 7 /* NOT USED */ +#define SQLITE_TESTCTRL_FK_NO_ACTION 7 +#define SQLITE_TESTCTRL_BITVEC_TEST 8 +#define SQLITE_TESTCTRL_FAULT_INSTALL 9 +#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10 +#define SQLITE_TESTCTRL_PENDING_BYTE 11 +#define SQLITE_TESTCTRL_ASSERT 12 +#define SQLITE_TESTCTRL_ALWAYS 13 +#define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */ +#define SQLITE_TESTCTRL_JSON_SELFCHECK 14 +#define SQLITE_TESTCTRL_OPTIMIZATIONS 15 +#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ +#define SQLITE_TESTCTRL_GETOPT 16 +#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ +#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17 +#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 +#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */ +#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19 +#define SQLITE_TESTCTRL_NEVER_CORRUPT 20 +#define SQLITE_TESTCTRL_VDBE_COVERAGE 21 +#define SQLITE_TESTCTRL_BYTEORDER 22 +#define SQLITE_TESTCTRL_ISINIT 23 +#define SQLITE_TESTCTRL_SORTER_MMAP 24 +#define SQLITE_TESTCTRL_IMPOSTER 25 +#define SQLITE_TESTCTRL_PARSER_COVERAGE 26 +#define SQLITE_TESTCTRL_RESULT_INTREAL 27 +#define SQLITE_TESTCTRL_PRNG_SEED 28 +#define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29 +#define SQLITE_TESTCTRL_SEEK_COUNT 30 +#define SQLITE_TESTCTRL_TRACEFLAGS 31 +#define SQLITE_TESTCTRL_TUNE 32 +#define SQLITE_TESTCTRL_LOGEST 33 +#define SQLITE_TESTCTRL_USELONGDOUBLE 34 /* NOT USED */ +#define SQLITE_TESTCTRL_ATOF 34 +#define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */ + +/* +** CAPI3REF: SQL Keyword Checking +** +** These routines provide access to the set of SQL language keywords +** recognized by SQLite. Applications can use these routines to determine +** whether or not a specific identifier needs to be escaped (for example, +** by enclosing in double-quotes) so as not to confuse the parser. +** +** The sqlite3_keyword_count() interface returns the number of distinct +** keywords understood by SQLite. +** +** The sqlite3_keyword_name(N,Z,L) interface finds the 0-based N-th keyword and +** makes *Z point to that keyword expressed as UTF8 and writes the number +** of bytes in the keyword into *L. The string that *Z points to is not +** zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns +** SQLITE_OK if N is within bounds and SQLITE_ERROR if not. If either Z +** or L are NULL or invalid pointers then calls to +** sqlite3_keyword_name(N,Z,L) result in undefined behavior. +** +** The sqlite3_keyword_check(Z,L) interface checks to see whether or not +** the L-byte UTF8 identifier that Z points to is a keyword, returning non-zero +** if it is and zero if not. +** +** The parser used by SQLite is forgiving. It is often possible to use +** a keyword as an identifier as long as such use does not result in a +** parsing ambiguity. For example, the statement +** "CREATE TABLE BEGIN(REPLACE,PRAGMA,END);" is accepted by SQLite, and +** creates a new table named "BEGIN" with three columns named +** "REPLACE", "PRAGMA", and "END". Nevertheless, best practice is to avoid +** using keywords as identifiers. Common techniques used to avoid keyword +** name collisions include: +**
      +**
    • Put all identifier names inside double-quotes. This is the official +** SQL way to escape identifier names. +**
    • Put identifier names inside [...]. This is not standard SQL, +** but it is what SQL Server does and so lots of programmers use this +** technique. +**
    • Begin every identifier with the letter "Z" as no SQL keywords start +** with "Z". +**
    • Include a digit somewhere in every identifier name. +**
    +** +** Note that the number of keywords understood by SQLite can depend on +** compile-time options. For example, "VACUUM" is not a keyword if +** SQLite is compiled with the [-DSQLITE_OMIT_VACUUM] option. Also, +** new keywords may be added to future releases of SQLite. +*/ +SQLITE_API int sqlite3_keyword_count(void); +SQLITE_API int sqlite3_keyword_name(int,const char**,int*); +SQLITE_API int sqlite3_keyword_check(const char*,int); + +/* +** CAPI3REF: Dynamic String Object +** KEYWORDS: {dynamic string} +** +** An instance of the sqlite3_str object contains a dynamically-sized +** string under construction. +** +** The lifecycle of an sqlite3_str object is as follows: +**
      +**
    1. ^The sqlite3_str object is created using [sqlite3_str_new()]. +**
    2. ^Text is appended to the sqlite3_str object using various +** methods, such as [sqlite3_str_appendf()]. +**
    3. ^The sqlite3_str object is destroyed and the string it created +** is returned using the [sqlite3_str_finish()] interface. +**
    +*/ +typedef struct sqlite3_str sqlite3_str; + +/* +** CAPI3REF: Create A New Dynamic String Object +** CONSTRUCTOR: sqlite3_str +** +** ^The [sqlite3_str_new(D)] interface allocates and initializes +** a new [sqlite3_str] object. To avoid memory leaks, the object returned by +** [sqlite3_str_new()] must be freed by a subsequent call to +** [sqlite3_str_finish(X)]. +** +** ^The [sqlite3_str_new(D)] interface always returns a pointer to a +** valid [sqlite3_str] object, though in the event of an out-of-memory +** error the returned object might be a special singleton that will +** silently reject new text, always return SQLITE_NOMEM from +** [sqlite3_str_errcode()], always return 0 for +** [sqlite3_str_length()], and always return NULL from +** [sqlite3_str_finish(X)]. It is always safe to use the value +** returned by [sqlite3_str_new(D)] as the sqlite3_str parameter +** to any of the other [sqlite3_str] methods. +** +** The D parameter to [sqlite3_str_new(D)] may be NULL. If the +** D parameter in [sqlite3_str_new(D)] is not NULL, then the maximum +** length of the string contained in the [sqlite3_str] object will be +** the value set for [sqlite3_limit](D,[SQLITE_LIMIT_LENGTH]) instead +** of [SQLITE_MAX_LENGTH]. +*/ +SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3*); + +/* +** CAPI3REF: Finalize A Dynamic String +** DESTRUCTOR: sqlite3_str +** +** ^The [sqlite3_str_finish(X)] interface destroys the sqlite3_str object X +** and returns a pointer to a memory buffer obtained from [sqlite3_malloc64()] +** that contains the constructed string. The calling application should +** pass the returned value to [sqlite3_free()] to avoid a memory leak. +** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any +** errors were encountered during construction of the string. ^The +** [sqlite3_str_finish(X)] interface might also return a NULL pointer if the +** string in [sqlite3_str] object X is zero bytes long. +** +** ^The [sqlite3_str_free(X)] interface destroys both the sqlite3_str object +** X and the string content it contains. Calling sqlite3_str_free(X) is +** the equivalent of calling [sqlite3_free](sqlite3_str_finish(X)). +*/ +SQLITE_API char *sqlite3_str_finish(sqlite3_str*); +SQLITE_API void sqlite3_str_free(sqlite3_str*); + +/* +** CAPI3REF: Add Content To A Dynamic String +** METHOD: sqlite3_str +** +** These interfaces add or remove content to an sqlite3_str object +** previously obtained from [sqlite3_str_new()]. +** +** ^The [sqlite3_str_appendf(X,F,...)] and +** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf] +** functionality of SQLite to append formatted text onto the end of +** [sqlite3_str] object X. +** +** ^The [sqlite3_str_append(X,S,N)] method appends exactly N bytes from string S +** onto the end of the [sqlite3_str] object X. N must be non-negative. +** S must contain at least N non-zero bytes of content. To append a +** zero-terminated string in its entirety, use the [sqlite3_str_appendall()] +** method instead. +** +** ^The [sqlite3_str_appendall(X,S)] method appends the complete content of +** zero-terminated string S onto the end of [sqlite3_str] object X. +** +** ^The [sqlite3_str_appendchar(X,N,C)] method appends N copies of the +** single-byte character C onto the end of [sqlite3_str] object X. +** ^This method can be used, for example, to add whitespace indentation. +** +** ^The [sqlite3_str_reset(X)] method resets the string under construction +** inside [sqlite3_str] object X back to zero bytes in length. +** +** ^The [sqlite3_str_truncate(X,N)] method changes the length of the string +** under construction to be N bytes or less. This routine is a no-op if +** N is negative or if the string is already N bytes or smaller in size. +** +** These methods do not return a result code. ^If an error occurs, that fact +** is recorded in the [sqlite3_str] object and can be recovered by a +** subsequent call to [sqlite3_str_errcode(X)]. +*/ +SQLITE_API void sqlite3_str_appendf(sqlite3_str*, const char *zFormat, ...); +SQLITE_API void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list); +SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N); +SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn); +SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C); +SQLITE_API void sqlite3_str_reset(sqlite3_str*); +SQLITE_API void sqlite3_str_truncate(sqlite3_str*,int N); + +/* +** CAPI3REF: Status Of A Dynamic String +** METHOD: sqlite3_str +** +** These interfaces return the current status of an [sqlite3_str] object. +** +** ^If any prior errors have occurred while constructing the dynamic string +** in sqlite3_str X, then the [sqlite3_str_errcode(X)] method will return +** an appropriate error code. ^The [sqlite3_str_errcode(X)] method returns +** [SQLITE_NOMEM] following any out-of-memory error, or +** [SQLITE_TOOBIG] if the size of the dynamic string exceeds +** [SQLITE_MAX_LENGTH], or [SQLITE_OK] if there have been no errors. +** +** ^The [sqlite3_str_length(X)] method returns the current length, in bytes, +** of the dynamic string under construction in [sqlite3_str] object X. +** ^The length returned by [sqlite3_str_length(X)] does not include the +** zero-termination byte. +** +** ^The [sqlite3_str_value(X)] method returns a pointer to the current +** content of the dynamic string under construction in X. The value +** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X +** and might be freed or altered by any subsequent method on the same +** [sqlite3_str] object. Applications must not use the pointer returned by +** [sqlite3_str_value(X)] after any subsequent method call on the same +** object. ^Applications may change the content of the string returned +** by [sqlite3_str_value(X)] as long as they do not write into any bytes +** outside the range of 0 to [sqlite3_str_length(X)] and do not read or +** write any byte after any subsequent sqlite3_str method call. +*/ +SQLITE_API int sqlite3_str_errcode(sqlite3_str*); +SQLITE_API int sqlite3_str_length(sqlite3_str*); +SQLITE_API char *sqlite3_str_value(sqlite3_str*); + +/* +** CAPI3REF: SQLite Runtime Status +** +** ^These interfaces are used to retrieve runtime status information +** about the performance of SQLite, and optionally to reset various +** highwater marks. ^The first argument is an integer code for +** the specific parameter to measure. ^(Recognized integer codes +** are of the form [status parameters | SQLITE_STATUS_...].)^ +** ^The current value of the parameter is returned into *pCurrent. +** ^The highest recorded value is returned in *pHighwater. ^If the +** resetFlag is true, then the highest record value is reset after +** *pHighwater is written. ^(Some parameters do not record the highest +** value. For those parameters +** nothing is written into *pHighwater and the resetFlag is ignored.)^ +** ^(Other parameters record only the highwater mark and not the current +** value. For these latter parameters nothing is written into *pCurrent.)^ +** +** ^The sqlite3_status() and sqlite3_status64() routines return +** SQLITE_OK on success and a non-zero [error code] on failure. +** +** If either the current value or the highwater mark is too large to +** be represented by a 32-bit integer, then the values returned by +** sqlite3_status() are undefined. +** +** See also: [sqlite3_db_status()] +*/ +SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag); +SQLITE_API int sqlite3_status64( + int op, + sqlite3_int64 *pCurrent, + sqlite3_int64 *pHighwater, + int resetFlag +); + + +/* +** CAPI3REF: Status Parameters +** KEYWORDS: {status parameters} +** +** These integer constants designate various run-time status parameters +** that can be returned by [sqlite3_status()]. +** +**
    +** [[SQLITE_STATUS_MEMORY_USED]] ^(
    SQLITE_STATUS_MEMORY_USED
    +**
    This parameter is the current amount of memory checked out +** using [sqlite3_malloc()], either directly or indirectly. The +** figure includes calls made to [sqlite3_malloc()] by the application +** and internal memory usage by the SQLite library. Auxiliary page-cache +** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in +** this parameter. The amount returned is the sum of the allocation +** sizes as reported by the xSize method in [sqlite3_mem_methods].
    )^ +** +** [[SQLITE_STATUS_MALLOC_SIZE]] ^(
    SQLITE_STATUS_MALLOC_SIZE
    +**
    This parameter records the largest memory allocation request +** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their +** internal equivalents). Only the value returned in the +** *pHighwater parameter to [sqlite3_status()] is of interest. +** The value written into the *pCurrent parameter is undefined.
    )^ +** +** [[SQLITE_STATUS_MALLOC_COUNT]] ^(
    SQLITE_STATUS_MALLOC_COUNT
    +**
    This parameter records the number of separate memory allocations +** currently checked out.
    )^ +** +** [[SQLITE_STATUS_PAGECACHE_USED]] ^(
    SQLITE_STATUS_PAGECACHE_USED
    +**
    This parameter returns the number of pages used out of the +** [pagecache memory allocator] that was configured using +** [SQLITE_CONFIG_PAGECACHE]. The +** value returned is in pages, not in bytes.
    )^ +** +** [[SQLITE_STATUS_PAGECACHE_OVERFLOW]] +** ^(
    SQLITE_STATUS_PAGECACHE_OVERFLOW
    +**
    This parameter returns the number of bytes of page cache +** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE] +** buffer and where forced to overflow to [sqlite3_malloc()]. The +** returned value includes allocations that overflowed because they +** were too large (they were larger than the "sz" parameter to +** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because +** no space was left in the page cache.
    )^ +** +** [[SQLITE_STATUS_PAGECACHE_SIZE]] ^(
    SQLITE_STATUS_PAGECACHE_SIZE
    +**
    This parameter records the largest memory allocation request +** handed to the [pagecache memory allocator]. Only the value returned in the +** *pHighwater parameter to [sqlite3_status()] is of interest. +** The value written into the *pCurrent parameter is undefined.
    )^ +** +** [[SQLITE_STATUS_SCRATCH_USED]]
    SQLITE_STATUS_SCRATCH_USED
    +**
    No longer used.
    +** +** [[SQLITE_STATUS_SCRATCH_OVERFLOW]] ^(
    SQLITE_STATUS_SCRATCH_OVERFLOW
    +**
    No longer used.
    +** +** [[SQLITE_STATUS_SCRATCH_SIZE]]
    SQLITE_STATUS_SCRATCH_SIZE
    +**
    No longer used.
    +** +** [[SQLITE_STATUS_PARSER_STACK]] ^(
    SQLITE_STATUS_PARSER_STACK
    +**
    The *pHighwater parameter records the deepest parser stack. +** The *pCurrent value is undefined. The *pHighwater value is only +** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].
    )^ +**
    +** +** New status parameters may be added from time to time. +*/ +#define SQLITE_STATUS_MEMORY_USED 0 +#define SQLITE_STATUS_PAGECACHE_USED 1 +#define SQLITE_STATUS_PAGECACHE_OVERFLOW 2 +#define SQLITE_STATUS_SCRATCH_USED 3 /* NOT USED */ +#define SQLITE_STATUS_SCRATCH_OVERFLOW 4 /* NOT USED */ +#define SQLITE_STATUS_MALLOC_SIZE 5 +#define SQLITE_STATUS_PARSER_STACK 6 +#define SQLITE_STATUS_PAGECACHE_SIZE 7 +#define SQLITE_STATUS_SCRATCH_SIZE 8 /* NOT USED */ +#define SQLITE_STATUS_MALLOC_COUNT 9 + +/* +** CAPI3REF: Database Connection Status +** METHOD: sqlite3 +** +** ^This interface is used to retrieve runtime status information +** about a single [database connection]. ^The first argument is the +** database connection object to be interrogated. ^The second argument +** is an integer constant, taken from the set of +** [SQLITE_DBSTATUS options], that +** determines the parameter to interrogate. The set of +** [SQLITE_DBSTATUS options] is likely +** to grow in future releases of SQLite. +** +** ^The current value of the requested parameter is written into *pCur +** and the highest instantaneous value is written into *pHiwtr. ^If +** the resetFlg is true, then the highest instantaneous value is +** reset back down to the current value. +** +** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a +** non-zero [error code] on failure. +** +** ^The sqlite3_db_status64(D,O,C,H,R) routine works exactly the same +** way as sqlite3_db_status(D,O,C,H,R) routine except that the C and H +** parameters are pointer to 64-bit integers (type: sqlite3_int64) instead +** of pointers to 32-bit integers, which allows larger status values +** to be returned. If a status value exceeds 2,147,483,647 then +** sqlite3_db_status() will truncate the value whereas sqlite3_db_status64() +** will return the full value. +** +** See also: [sqlite3_status()] and [sqlite3_stmt_status()]. +*/ +SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); +SQLITE_API int sqlite3_db_status64(sqlite3*,int,sqlite3_int64*,sqlite3_int64*,int); + +/* +** CAPI3REF: Status Parameters for database connections +** KEYWORDS: {SQLITE_DBSTATUS options} +** +** These constants are the available integer "verbs" that can be passed as +** the second argument to the [sqlite3_db_status()] interface. +** +** New verbs may be added in future releases of SQLite. Existing verbs +** might be discontinued. Applications should check the return code from +** [sqlite3_db_status()] to make sure that the call worked. +** The [sqlite3_db_status()] interface will return a non-zero error code +** if a discontinued or unsupported verb is invoked. +** +**
    +** [[SQLITE_DBSTATUS_LOOKASIDE_USED]] ^(
    SQLITE_DBSTATUS_LOOKASIDE_USED
    +**
    This parameter returns the number of lookaside memory slots currently +** checked out.
    )^ +** +** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(
    SQLITE_DBSTATUS_LOOKASIDE_HIT
    +**
    This parameter returns the number of malloc attempts that were +** satisfied using lookaside memory. Only the high-water value is meaningful; +** the current value is always zero.
    )^ +** +** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE]] +** ^(
    SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE
    +**
    This parameter returns the number of malloc attempts that might have +** been satisfied using lookaside memory but failed due to the amount of +** memory requested being larger than the lookaside slot size. +** Only the high-water value is meaningful; +** the current value is always zero.
    )^ +** +** [[SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL]] +** ^(
    SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL
    +**
    This parameter returns the number of malloc attempts that might have +** been satisfied using lookaside memory but failed due to all lookaside +** memory already being in use. +** Only the high-water value is meaningful; +** the current value is always zero.
    )^ +** +** [[SQLITE_DBSTATUS_CACHE_USED]] ^(
    SQLITE_DBSTATUS_CACHE_USED
    +**
    This parameter returns the approximate number of bytes of heap +** memory used by all pager caches associated with the database connection.)^ +** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0. +**
    +** +** [[SQLITE_DBSTATUS_CACHE_USED_SHARED]] +** ^(
    SQLITE_DBSTATUS_CACHE_USED_SHARED
    +**
    This parameter is similar to DBSTATUS_CACHE_USED, except that if a +** pager cache is shared between two or more connections the bytes of heap +** memory used by that pager cache is divided evenly between the attached +** connections.)^ In other words, if none of the pager caches associated +** with the database connection are shared, this request returns the same +** value as DBSTATUS_CACHE_USED. Or, if one or more of the pager caches are +** shared, the value returned by this call will be smaller than that returned +** by DBSTATUS_CACHE_USED. ^The highwater mark associated with +** SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0.
    +** +** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(
    SQLITE_DBSTATUS_SCHEMA_USED
    +**
    This parameter returns the approximate number of bytes of heap +** memory used to store the schema for all databases associated +** with the connection - main, temp, and any [ATTACH]-ed databases.)^ +** ^The full amount of memory used by the schemas is reported, even if the +** schema memory is shared with other database connections due to +** [shared cache mode] being enabled. +** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0. +**
    +** +** [[SQLITE_DBSTATUS_STMT_USED]] ^(
    SQLITE_DBSTATUS_STMT_USED
    +**
    This parameter returns the approximate number of bytes of heap +** and lookaside memory used by all prepared statements associated with +** the database connection.)^ +** ^The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0. +**
    +** +** [[SQLITE_DBSTATUS_CACHE_HIT]] ^(
    SQLITE_DBSTATUS_CACHE_HIT
    +**
    This parameter returns the number of pager cache hits that have +** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT +** is always 0. +**
    +** +** [[SQLITE_DBSTATUS_CACHE_MISS]] ^(
    SQLITE_DBSTATUS_CACHE_MISS
    +**
    This parameter returns the number of pager cache misses that have +** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS +** is always 0. +**
    +** +** [[SQLITE_DBSTATUS_CACHE_WRITE]] ^(
    SQLITE_DBSTATUS_CACHE_WRITE
    +**
    This parameter returns the number of dirty cache entries that have +** been written to disk. Specifically, the number of pages written to the +** wal file in wal mode databases, or the number of pages written to the +** database file in rollback mode databases. Any pages written as part of +** transaction rollback or database recovery operations are not included. +** If an IO or other error occurs while writing a page to disk, the effect +** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The +** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. +**

    +** ^(There is overlap between the quantities measured by this parameter +** (SQLITE_DBSTATUS_CACHE_WRITE) and SQLITE_DBSTATUS_TEMPBUF_SPILL. +** Resetting one will reduce the other.)^ +**

    +** +** [[SQLITE_DBSTATUS_CACHE_SPILL]] ^(
    SQLITE_DBSTATUS_CACHE_SPILL
    +**
    This parameter returns the number of dirty cache entries that have +** been written to disk in the middle of a transaction due to the page +** cache overflowing. Transactions are more efficient if they are written +** to disk all at once. When pages spill mid-transaction, that introduces +** additional overhead. This parameter can be used to help identify +** inefficiencies that can be resolved by increasing the cache size. +**
    +** +** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(
    SQLITE_DBSTATUS_DEFERRED_FKS
    +**
    This parameter returns zero for the current value if and only if +** all foreign key constraints (deferred or immediate) have been +** resolved.)^ ^The highwater mark is always 0. +** +** [[SQLITE_DBSTATUS_TEMPBUF_SPILL] ^(
    SQLITE_DBSTATUS_TEMPBUF_SPILL
    +**
    ^(This parameter returns the number of bytes written to temporary +** files on disk that could have been kept in memory had sufficient memory +** been available. This value includes writes to intermediate tables that +** are part of complex queries, external sorts that spill to disk, and +** writes to TEMP tables.)^ +** ^The highwater mark is always 0. +**

    +** ^(There is overlap between the quantities measured by this parameter +** (SQLITE_DBSTATUS_TEMPBUF_SPILL) and SQLITE_DBSTATUS_CACHE_WRITE. +** Resetting one will reduce the other.)^ +**

    +**
    +*/ +#define SQLITE_DBSTATUS_LOOKASIDE_USED 0 +#define SQLITE_DBSTATUS_CACHE_USED 1 +#define SQLITE_DBSTATUS_SCHEMA_USED 2 +#define SQLITE_DBSTATUS_STMT_USED 3 +#define SQLITE_DBSTATUS_LOOKASIDE_HIT 4 +#define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5 +#define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6 +#define SQLITE_DBSTATUS_CACHE_HIT 7 +#define SQLITE_DBSTATUS_CACHE_MISS 8 +#define SQLITE_DBSTATUS_CACHE_WRITE 9 +#define SQLITE_DBSTATUS_DEFERRED_FKS 10 +#define SQLITE_DBSTATUS_CACHE_USED_SHARED 11 +#define SQLITE_DBSTATUS_CACHE_SPILL 12 +#define SQLITE_DBSTATUS_TEMPBUF_SPILL 13 +#define SQLITE_DBSTATUS_MAX 13 /* Largest defined DBSTATUS */ + + +/* +** CAPI3REF: Prepared Statement Status +** METHOD: sqlite3_stmt +** +** ^(Each prepared statement maintains various +** [SQLITE_STMTSTATUS counters] that measure the number +** of times it has performed specific operations.)^ These counters can +** be used to monitor the performance characteristics of the prepared +** statements. For example, if the number of table steps greatly exceeds +** the number of table searches or result rows, that would tend to indicate +** that the prepared statement is using a full table scan rather than +** an index. +** +** ^(This interface is used to retrieve and reset counter values from +** a [prepared statement]. The first argument is the prepared statement +** object to be interrogated. The second argument +** is an integer code for a specific [SQLITE_STMTSTATUS counter] +** to be interrogated.)^ +** ^The current value of the requested counter is returned. +** ^If the resetFlg is true, then the counter is reset to zero after this +** interface call returns. +** +** See also: [sqlite3_status()] and [sqlite3_db_status()]. +*/ +SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); + +/* +** CAPI3REF: Status Parameters for prepared statements +** KEYWORDS: {SQLITE_STMTSTATUS counter} {SQLITE_STMTSTATUS counters} +** +** These preprocessor macros define integer codes that name counter +** values associated with the [sqlite3_stmt_status()] interface. +** The meanings of the various counters are as follows: +** +**
    +** [[SQLITE_STMTSTATUS_FULLSCAN_STEP]]
    SQLITE_STMTSTATUS_FULLSCAN_STEP
    +**
    ^This is the number of times that SQLite has stepped forward in +** a table as part of a full table scan. Large numbers for this counter +** may indicate opportunities for performance improvement through +** careful use of indices.
    +** +** [[SQLITE_STMTSTATUS_SORT]]
    SQLITE_STMTSTATUS_SORT
    +**
    ^This is the number of sort operations that have occurred. +** A non-zero value in this counter may indicate an opportunity to +** improve performance through careful use of indices.
    +** +** [[SQLITE_STMTSTATUS_AUTOINDEX]]
    SQLITE_STMTSTATUS_AUTOINDEX
    +**
    ^This is the number of rows inserted into transient indices that +** were created automatically in order to help joins run faster. +** A non-zero value in this counter may indicate an opportunity to +** improve performance by adding permanent indices that do not +** need to be reinitialized each time the statement is run.
    +** +** [[SQLITE_STMTSTATUS_VM_STEP]]
    SQLITE_STMTSTATUS_VM_STEP
    +**
    ^This is the number of virtual machine operations executed +** by the prepared statement if that number is less than or equal +** to 2147483647. The number of virtual machine operations can be +** used as a proxy for the total work done by the prepared statement. +** If the number of virtual machine operations exceeds 2147483647 +** then the value returned by this statement status code is undefined.
    +** +** [[SQLITE_STMTSTATUS_REPREPARE]]
    SQLITE_STMTSTATUS_REPREPARE
    +**
    ^This is the number of times that the prepare statement has been +** automatically regenerated due to schema changes or changes to +** [bound parameters] that might affect the query plan.
    +** +** [[SQLITE_STMTSTATUS_RUN]]
    SQLITE_STMTSTATUS_RUN
    +**
    ^This is the number of times that the prepared statement has +** been run. A single "run" for the purposes of this counter is one +** or more calls to [sqlite3_step()] followed by a call to [sqlite3_reset()]. +** The counter is incremented on the first [sqlite3_step()] call of each +** cycle.
    +** +** [[SQLITE_STMTSTATUS_FILTER_MISS]] +** [[SQLITE_STMTSTATUS_FILTER HIT]] +**
    SQLITE_STMTSTATUS_FILTER_HIT
    +** SQLITE_STMTSTATUS_FILTER_MISS
    +**
    ^SQLITE_STMTSTATUS_FILTER_HIT is the number of times that a join +** step was bypassed because a Bloom filter returned not-found. The +** corresponding SQLITE_STMTSTATUS_FILTER_MISS value is the number of +** times that the Bloom filter returned a find, and thus the join step +** had to be processed as normal.
    +** +** [[SQLITE_STMTSTATUS_MEMUSED]]
    SQLITE_STMTSTATUS_MEMUSED
    +**
    ^This is the approximate number of bytes of heap memory +** used to store the prepared statement. ^This value is not actually +** a counter, and so the resetFlg parameter to sqlite3_stmt_status() +** is ignored when the opcode is SQLITE_STMTSTATUS_MEMUSED. +**
    +**
    +*/ +#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1 +#define SQLITE_STMTSTATUS_SORT 2 +#define SQLITE_STMTSTATUS_AUTOINDEX 3 +#define SQLITE_STMTSTATUS_VM_STEP 4 +#define SQLITE_STMTSTATUS_REPREPARE 5 +#define SQLITE_STMTSTATUS_RUN 6 +#define SQLITE_STMTSTATUS_FILTER_MISS 7 +#define SQLITE_STMTSTATUS_FILTER_HIT 8 +#define SQLITE_STMTSTATUS_MEMUSED 99 + +/* +** CAPI3REF: Custom Page Cache Object +** +** The sqlite3_pcache type is opaque. It is implemented by +** the pluggable module. The SQLite core has no knowledge of +** its size or internal structure and never deals with the +** sqlite3_pcache object except by holding and passing pointers +** to the object. +** +** See [sqlite3_pcache_methods2] for additional information. +*/ +typedef struct sqlite3_pcache sqlite3_pcache; + +/* +** CAPI3REF: Custom Page Cache Object +** +** The sqlite3_pcache_page object represents a single page in the +** page cache. The page cache will allocate instances of this +** object. Various methods of the page cache use pointers to instances +** of this object as parameters or as their return value. +** +** See [sqlite3_pcache_methods2] for additional information. +*/ +typedef struct sqlite3_pcache_page sqlite3_pcache_page; +struct sqlite3_pcache_page { + void *pBuf; /* The content of the page */ + void *pExtra; /* Extra information associated with the page */ +}; + +/* +** CAPI3REF: Application Defined Page Cache. +** KEYWORDS: {page cache} +** +** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE2], ...) interface can +** register an alternative page cache implementation by passing in an +** instance of the sqlite3_pcache_methods2 structure.)^ +** In many applications, most of the heap memory allocated by +** SQLite is used for the page cache. +** By implementing a +** custom page cache using this API, an application can better control +** the amount of memory consumed by SQLite, the way in which +** that memory is allocated and released, and the policies used to +** determine exactly which parts of a database file are cached and for +** how long. +** +** The alternative page cache mechanism is an +** extreme measure that is only needed by the most demanding applications. +** The built-in page cache is recommended for most uses. +** +** ^(The contents of the sqlite3_pcache_methods2 structure are copied to an +** internal buffer by SQLite within the call to [sqlite3_config]. Hence +** the application may discard the parameter after the call to +** [sqlite3_config()] returns.)^ +** +** [[the xInit() page cache method]] +** ^(The xInit() method is called once for each effective +** call to [sqlite3_initialize()])^ +** (usually only once during the lifetime of the process). ^(The xInit() +** method is passed a copy of the sqlite3_pcache_methods2.pArg value.)^ +** The intent of the xInit() method is to set up global data structures +** required by the custom page cache implementation. +** ^(If the xInit() method is NULL, then the +** built-in default page cache is used instead of the application defined +** page cache.)^ +** +** [[the xShutdown() page cache method]] +** ^The xShutdown() method is called by [sqlite3_shutdown()]. +** It can be used to clean up +** any outstanding resources before process shutdown, if required. +** ^The xShutdown() method may be NULL. +** +** ^SQLite automatically serializes calls to the xInit method, +** so the xInit method need not be threadsafe. ^The +** xShutdown method is only called from [sqlite3_shutdown()] so it does +** not need to be threadsafe either. All other methods must be threadsafe +** in multithreaded applications. +** +** ^SQLite will never invoke xInit() more than once without an intervening +** call to xShutdown(). +** +** [[the xCreate() page cache methods]] +** ^SQLite invokes the xCreate() method to construct a new cache instance. +** SQLite will typically create one cache instance for each open database file, +** though this is not guaranteed. ^The +** first parameter, szPage, is the size in bytes of the pages that must +** be allocated by the cache. ^szPage will always be a power of two. ^The +** second parameter szExtra is a number of bytes of extra storage +** associated with each page cache entry. ^The szExtra parameter will be +** a number less than 250. SQLite will use the +** extra szExtra bytes on each page to store metadata about the underlying +** database page on disk. The value passed into szExtra depends +** on the SQLite version, the target platform, and how SQLite was compiled. +** ^The third argument to xCreate(), bPurgeable, is true if the cache being +** created will be used to cache database pages of a file stored on disk, or +** false if it is used for an in-memory database. The cache implementation +** does not have to do anything special based upon the value of bPurgeable; +** it is purely advisory. ^On a cache where bPurgeable is false, SQLite will +** never invoke xUnpin() except to deliberately delete a page. +** ^In other words, calls to xUnpin() on a cache with bPurgeable set to +** false will always have the "discard" flag set to true. +** ^Hence, a cache created with bPurgeable set to false will +** never contain any unpinned pages. +** +** [[the xCachesize() page cache method]] +** ^(The xCachesize() method may be called at any time by SQLite to set the +** suggested maximum cache-size (number of pages stored) for the cache +** instance passed as the first argument. This is the value configured using +** the SQLite "[PRAGMA cache_size]" command.)^ As with the bPurgeable +** parameter, the implementation is not required to do anything with this +** value; it is advisory only. +** +** [[the xPagecount() page cache methods]] +** The xPagecount() method must return the number of pages currently +** stored in the cache, both pinned and unpinned. +** +** [[the xFetch() page cache methods]] +** The xFetch() method locates a page in the cache and returns a pointer to +** an sqlite3_pcache_page object associated with that page, or a NULL pointer. +** The pBuf element of the returned sqlite3_pcache_page object will be a +** pointer to a buffer of szPage bytes used to store the content of a +** single database page. The pExtra element of sqlite3_pcache_page will be +** a pointer to the szExtra bytes of extra storage that SQLite has requested +** for each entry in the page cache. +** +** The page to be fetched is determined by the key. ^The minimum key value +** is 1. After it has been retrieved using xFetch, the page is considered +** to be "pinned". +** +** If the requested page is already in the page cache, then the page cache +** implementation must return a pointer to the page buffer with its content +** intact. If the requested page is not already in the cache, then the +** cache implementation should use the value of the createFlag +** parameter to help it determine what action to take: +** +** +**
    createFlag Behavior when page is not already in cache +**
    0 Do not allocate a new page. Return NULL. +**
    1 Allocate a new page if it is easy and convenient to do so. +** Otherwise return NULL. +**
    2 Make every effort to allocate a new page. Only return +** NULL if allocating a new page is effectively impossible. +**
    +** +** ^(SQLite will normally invoke xFetch() with a createFlag of 0 or 1. SQLite +** will only use a createFlag of 2 after a prior call with a createFlag of 1 +** failed.)^ In between the xFetch() calls, SQLite may +** attempt to unpin one or more cache pages by spilling the content of +** pinned pages to disk and synching the operating system disk cache. +** +** [[the xUnpin() page cache method]] +** ^xUnpin() is called by SQLite with a pointer to a currently pinned page +** as its second argument. If the third parameter, discard, is non-zero, +** then the page must be evicted from the cache. +** ^If the discard parameter is +** zero, then the page may be discarded or retained at the discretion of the +** page cache implementation. ^The page cache implementation +** may choose to evict unpinned pages at any time. +** +** The cache must not perform any reference counting. A single +** call to xUnpin() unpins the page regardless of the number of prior calls +** to xFetch(). +** +** [[the xRekey() page cache methods]] +** The xRekey() method is used to change the key value associated with the +** page passed as the second argument. If the cache +** previously contains an entry associated with newKey, it must be +** discarded. ^Any prior cache entry associated with newKey is guaranteed not +** to be pinned. +** +** When SQLite calls the xTruncate() method, the cache must discard all +** existing cache entries with page numbers (keys) greater than or equal +** to the value of the iLimit parameter passed to xTruncate(). If any +** of these pages are pinned, they become implicitly unpinned, meaning that +** they can be safely discarded. +** +** [[the xDestroy() page cache method]] +** ^The xDestroy() method is used to delete a cache allocated by xCreate(). +** All resources associated with the specified cache should be freed. ^After +** calling the xDestroy() method, SQLite considers the [sqlite3_pcache*] +** handle invalid, and will not use it with any other sqlite3_pcache_methods2 +** functions. +** +** [[the xShrink() page cache method]] +** ^SQLite invokes the xShrink() method when it wants the page cache to +** free up as much of heap memory as possible. The page cache implementation +** is not obligated to free any memory, but well-behaved implementations should +** do their best. +*/ +typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2; +struct sqlite3_pcache_methods2 { + int iVersion; + void *pArg; + int (*xInit)(void*); + void (*xShutdown)(void*); + sqlite3_pcache *(*xCreate)(int szPage, int szExtra, int bPurgeable); + void (*xCachesize)(sqlite3_pcache*, int nCachesize); + int (*xPagecount)(sqlite3_pcache*); + sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); + void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard); + void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*, + unsigned oldKey, unsigned newKey); + void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); + void (*xDestroy)(sqlite3_pcache*); + void (*xShrink)(sqlite3_pcache*); +}; + +/* +** This is the obsolete pcache_methods object that has now been replaced +** by sqlite3_pcache_methods2. This object is not used by SQLite. It is +** retained in the header file for backwards compatibility only. +*/ +typedef struct sqlite3_pcache_methods sqlite3_pcache_methods; +struct sqlite3_pcache_methods { + void *pArg; + int (*xInit)(void*); + void (*xShutdown)(void*); + sqlite3_pcache *(*xCreate)(int szPage, int bPurgeable); + void (*xCachesize)(sqlite3_pcache*, int nCachesize); + int (*xPagecount)(sqlite3_pcache*); + void *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); + void (*xUnpin)(sqlite3_pcache*, void*, int discard); + void (*xRekey)(sqlite3_pcache*, void*, unsigned oldKey, unsigned newKey); + void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); + void (*xDestroy)(sqlite3_pcache*); +}; + + +/* +** CAPI3REF: Online Backup Object +** +** The sqlite3_backup object records state information about an ongoing +** online backup operation. ^The sqlite3_backup object is created by +** a call to [sqlite3_backup_init()] and is destroyed by a call to +** [sqlite3_backup_finish()]. +** +** See Also: [Using the SQLite Online Backup API] +*/ +typedef struct sqlite3_backup sqlite3_backup; + +/* +** CAPI3REF: Online Backup API. +** +** The backup API copies the content of one database into another. +** It is useful either for creating backups of databases or +** for copying in-memory databases to or from persistent files. +** +** See Also: [Using the SQLite Online Backup API] +** +** ^SQLite holds a write transaction open on the destination database file +** for the duration of the backup operation. +** ^The source database is read-locked only while it is being read; +** it is not locked continuously for the entire backup operation. +** ^Thus, the backup may be performed on a live source database without +** preventing other database connections from +** reading or writing to the source database while the backup is underway. +** +** ^(To perform a backup operation: +**
      +**
    1. sqlite3_backup_init() is called once to initialize the +** backup, +**
    2. sqlite3_backup_step() is called one or more times to transfer +** the data between the two databases, and finally +**
    3. sqlite3_backup_finish() is called to release all resources +** associated with the backup operation. +**
    )^ +** There should be exactly one call to sqlite3_backup_finish() for each +** successful call to sqlite3_backup_init(). +** +** [[sqlite3_backup_init()]] sqlite3_backup_init() +** +** ^The D and N arguments to sqlite3_backup_init(D,N,S,M) are the +** [database connection] associated with the destination database +** and the database name, respectively. +** ^The database name is "main" for the main database, "temp" for the +** temporary database, or the name specified after the AS keyword in +** an [ATTACH] statement for an attached database. +** ^The S and M arguments passed to +** sqlite3_backup_init(D,N,S,M) identify the [database connection] +** and database name of the source database, respectively. +** ^The source and destination [database connections] (parameters S and D) +** must be different or else sqlite3_backup_init(D,N,S,M) will fail with +** an error. +** +** ^A call to sqlite3_backup_init() will fail, returning NULL, if +** there is already a read or read-write transaction open on the +** destination database. +** +** ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is +** returned and an error code and error message are stored in the +** destination [database connection] D. +** ^The error code and message for the failed call to sqlite3_backup_init() +** can be retrieved using the [sqlite3_errcode()], [sqlite3_errmsg()], and/or +** [sqlite3_errmsg16()] functions. +** ^A successful call to sqlite3_backup_init() returns a pointer to an +** [sqlite3_backup] object. +** ^The [sqlite3_backup] object may be used with the sqlite3_backup_step() and +** sqlite3_backup_finish() functions to perform the specified backup +** operation. +** +** [[sqlite3_backup_step()]] sqlite3_backup_step() +** +** ^Function sqlite3_backup_step(B,N) will copy up to N pages between +** the source and destination databases specified by [sqlite3_backup] object B. +** ^If N is negative, all remaining source pages are copied. +** ^If sqlite3_backup_step(B,N) successfully copies N pages and there +** are still more pages to be copied, then the function returns [SQLITE_OK]. +** ^If sqlite3_backup_step(B,N) successfully finishes copying all pages +** from source to destination, then it returns [SQLITE_DONE]. +** ^If an error occurs while running sqlite3_backup_step(B,N), +** then an [error code] is returned. ^As well as [SQLITE_OK] and +** [SQLITE_DONE], a call to sqlite3_backup_step() may return [SQLITE_READONLY], +** [SQLITE_NOMEM], [SQLITE_BUSY], [SQLITE_LOCKED], or an +** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] extended error code. +** +** ^(The sqlite3_backup_step() might return [SQLITE_READONLY] if +**
      +**
    1. the destination database was opened read-only, or +**
    2. the destination database is using write-ahead-log journaling +** and the destination and source page sizes differ, or +**
    3. the destination database is an in-memory database and the +** destination and source page sizes differ. +**
    )^ +** +** ^If sqlite3_backup_step() cannot obtain a required file-system lock, then +** the [sqlite3_busy_handler | busy-handler function] +** is invoked (if one is specified). ^If the +** busy-handler returns non-zero before the lock is available, then +** [SQLITE_BUSY] is returned to the caller. ^In this case the call to +** sqlite3_backup_step() can be retried later. ^If the source +** [database connection] +** is being used to write to the source database when sqlite3_backup_step() +** is called, then [SQLITE_LOCKED] is returned immediately. ^Again, in this +** case the call to sqlite3_backup_step() can be retried later on. ^(If +** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX], [SQLITE_NOMEM], or +** [SQLITE_READONLY] is returned, then +** there is no point in retrying the call to sqlite3_backup_step(). These +** errors are considered fatal.)^ The application must accept +** that the backup operation has failed and pass the backup operation handle +** to the sqlite3_backup_finish() to release associated resources. +** +** ^The first call to sqlite3_backup_step() obtains an exclusive lock +** on the destination file. ^The exclusive lock is not released until either +** sqlite3_backup_finish() is called or the backup operation is complete +** and sqlite3_backup_step() returns [SQLITE_DONE]. ^Every call to +** sqlite3_backup_step() obtains a [shared lock] on the source database that +** lasts for the duration of the sqlite3_backup_step() call. +** ^Because the source database is not locked between calls to +** sqlite3_backup_step(), the source database may be modified mid-way +** through the backup process. ^If the source database is modified by an +** external process or via a database connection other than the one being +** used by the backup operation, then the backup will be automatically +** restarted by the next call to sqlite3_backup_step(). ^If the source +** database is modified by using the same database connection as is used +** by the backup operation, then the backup database is automatically +** updated at the same time. +** +** [[sqlite3_backup_finish()]] sqlite3_backup_finish() +** +** When sqlite3_backup_step() has returned [SQLITE_DONE], or when the +** application wishes to abandon the backup operation, the application +** should destroy the [sqlite3_backup] by passing it to sqlite3_backup_finish(). +** ^The sqlite3_backup_finish() interfaces releases all +** resources associated with the [sqlite3_backup] object. +** ^If sqlite3_backup_step() has not yet returned [SQLITE_DONE], then any +** active write-transaction on the destination database is rolled back. +** The [sqlite3_backup] object is invalid +** and may not be used following a call to sqlite3_backup_finish(). +** +** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no +** sqlite3_backup_step() errors occurred, regardless of whether or not +** sqlite3_backup_step() completed. +** ^If an out-of-memory condition or IO error occurred during any prior +** sqlite3_backup_step() call on the same [sqlite3_backup] object, then +** sqlite3_backup_finish() returns the corresponding [error code]. +** +** ^A return of [SQLITE_BUSY] or [SQLITE_LOCKED] from sqlite3_backup_step() +** is not a permanent error and does not affect the return value of +** sqlite3_backup_finish(). +** +** [[sqlite3_backup_remaining()]] [[sqlite3_backup_pagecount()]] +** sqlite3_backup_remaining() and sqlite3_backup_pagecount() +** +** ^The sqlite3_backup_remaining() routine returns the number of pages still +** to be backed up at the conclusion of the most recent sqlite3_backup_step(). +** ^The sqlite3_backup_pagecount() routine returns the total number of pages +** in the source database at the conclusion of the most recent +** sqlite3_backup_step(). +** ^(The values returned by these functions are only updated by +** sqlite3_backup_step(). If the source database is modified in a way that +** changes the size of the source database or the number of pages remaining, +** those changes are not reflected in the output of sqlite3_backup_pagecount() +** and sqlite3_backup_remaining() until after the next +** sqlite3_backup_step().)^ +** +** Concurrent Usage of Database Handles +** +** ^The source [database connection] may be used by the application for other +** purposes while a backup operation is underway or being initialized. +** ^If SQLite is compiled and configured to support threadsafe database +** connections, then the source database connection may be used concurrently +** from within other threads. +** +** However, the application must guarantee that the destination +** [database connection] is not passed to any other API (by any thread) after +** sqlite3_backup_init() is called and before the corresponding call to +** sqlite3_backup_finish(). SQLite does not currently check to see +** if the application incorrectly accesses the destination [database connection] +** and so no error code is reported, but the operations may malfunction +** nevertheless. Use of the destination database connection while a +** backup is in progress might also cause a mutex deadlock. +** +** If running in [shared cache mode], the application must +** guarantee that the shared cache used by the destination database +** is not accessed while the backup is running. In practice this means +** that the application must guarantee that the disk file being +** backed up to is not accessed by any connection within the process, +** not just the specific connection that was passed to sqlite3_backup_init(). +** +** The [sqlite3_backup] object itself is partially threadsafe. Multiple +** threads may safely make multiple concurrent calls to sqlite3_backup_step(). +** However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount() +** APIs are not strictly speaking threadsafe. If they are invoked at the +** same time as another thread is invoking sqlite3_backup_step() it is +** possible that they return invalid values. +** +** Alternatives To Using The Backup API +** +** Other techniques for safely creating a consistent backup of an SQLite +** database include: +** +**
      +**
    • The [VACUUM INTO] command. +**
    • The [sqlite3_rsync] utility program. +**
    +*/ +SQLITE_API sqlite3_backup *sqlite3_backup_init( + sqlite3 *pDest, /* Destination database handle */ + const char *zDestName, /* Destination database name */ + sqlite3 *pSource, /* Source database handle */ + const char *zSourceName /* Source database name */ +); +SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage); +SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p); +SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p); +SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); + +/* +** CAPI3REF: Unlock Notification +** METHOD: sqlite3 +** +** ^When running in shared-cache mode, a database operation may fail with +** an [SQLITE_LOCKED] error if the required locks on the shared-cache or +** individual tables within the shared-cache cannot be obtained. See +** [SQLite Shared-Cache Mode] for a description of shared-cache locking. +** ^This API may be used to register a callback that SQLite will invoke +** when the connection currently holding the required lock relinquishes it. +** ^This API is only available if the library was compiled with the +** [SQLITE_ENABLE_UNLOCK_NOTIFY] C-preprocessor symbol defined. +** +** See Also: [Using the SQLite Unlock Notification Feature]. +** +** ^Shared-cache locks are released when a database connection concludes +** its current transaction, either by committing it or rolling it back. +** +** ^When a connection (known as the blocked connection) fails to obtain a +** shared-cache lock and SQLITE_LOCKED is returned to the caller, the +** identity of the database connection (the blocking connection) that +** has locked the required resource is stored internally. ^After an +** application receives an SQLITE_LOCKED error, it may call the +** sqlite3_unlock_notify() method with the blocked connection handle as +** the first argument to register for a callback that will be invoked +** when the blocking connection's current transaction is concluded. ^The +** callback is invoked from within the [sqlite3_step] or [sqlite3_close] +** call that concludes the blocking connection's transaction. +** +** ^(If sqlite3_unlock_notify() is called in a multi-threaded application, +** there is a chance that the blocking connection will have already +** concluded its transaction by the time sqlite3_unlock_notify() is invoked. +** If this happens, then the specified callback is invoked immediately, +** from within the call to sqlite3_unlock_notify().)^ +** +** ^If the blocked connection is attempting to obtain a write-lock on a +** shared-cache table, and more than one other connection currently holds +** a read-lock on the same table, then SQLite arbitrarily selects one of +** the other connections to use as the blocking connection. +** +** ^(There may be at most one unlock-notify callback registered by a +** blocked connection. If sqlite3_unlock_notify() is called when the +** blocked connection already has a registered unlock-notify callback, +** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is +** called with a NULL pointer as its second argument, then any existing +** unlock-notify callback is canceled. ^The blocked connection's +** unlock-notify callback may also be canceled by closing the blocked +** connection using [sqlite3_close()]. +** +** The unlock-notify callback is not reentrant. If an application invokes +** any sqlite3_xxx API functions from within an unlock-notify callback, a +** crash or deadlock may be the result. +** +** ^Unless deadlock is detected (see below), sqlite3_unlock_notify() always +** returns SQLITE_OK. +** +** Callback Invocation Details +** +** When an unlock-notify callback is registered, the application provides a +** single void* pointer that is passed to the callback when it is invoked. +** However, the signature of the callback function allows SQLite to pass +** it an array of void* context pointers. The first argument passed to +** an unlock-notify callback is a pointer to an array of void* pointers, +** and the second is the number of entries in the array. +** +** When a blocking connection's transaction is concluded, there may be +** more than one blocked connection that has registered for an unlock-notify +** callback. ^If two or more such blocked connections have specified the +** same callback function, then instead of invoking the callback function +** multiple times, it is invoked once with the set of void* context pointers +** specified by the blocked connections bundled together into an array. +** This gives the application an opportunity to prioritize any actions +** related to the set of unblocked database connections. +** +** Deadlock Detection +** +** Assuming that after registering for an unlock-notify callback a +** database waits for the callback to be issued before taking any further +** action (a reasonable assumption), then using this API may cause the +** application to deadlock. For example, if connection X is waiting for +** connection Y's transaction to be concluded, and similarly connection +** Y is waiting on connection X's transaction, then neither connection +** will proceed and the system may remain deadlocked indefinitely. +** +** To avoid this scenario, the sqlite3_unlock_notify() performs deadlock +** detection. ^If a given call to sqlite3_unlock_notify() would put the +** system in a deadlocked state, then SQLITE_LOCKED is returned and no +** unlock-notify callback is registered. The system is said to be in +** a deadlocked state if connection A has registered for an unlock-notify +** callback on the conclusion of connection B's transaction, and connection +** B has itself registered for an unlock-notify callback when connection +** A's transaction is concluded. ^Indirect deadlock is also detected, so +** the system is also considered to be deadlocked if connection B has +** registered for an unlock-notify callback on the conclusion of connection +** C's transaction, where connection C is waiting on connection A. ^Any +** number of levels of indirection are allowed. +** +** The "DROP TABLE" Exception +** +** When a call to [sqlite3_step()] returns SQLITE_LOCKED, it is almost +** always appropriate to call sqlite3_unlock_notify(). There is however, +** one exception. When executing a "DROP TABLE" or "DROP INDEX" statement, +** SQLite checks if there are any currently executing SELECT statements +** that belong to the same connection. If there are, SQLITE_LOCKED is +** returned. In this case there is no "blocking connection", so invoking +** sqlite3_unlock_notify() results in the unlock-notify callback being +** invoked immediately. If the application then re-attempts the "DROP TABLE" +** or "DROP INDEX" query, an infinite loop might be the result. +** +** One way around this problem is to check the extended error code returned +** by an sqlite3_step() call. ^(If there is a blocking connection, then the +** extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in +** the special "DROP TABLE/INDEX" case, the extended error code is just +** SQLITE_LOCKED.)^ +*/ +SQLITE_API int sqlite3_unlock_notify( + sqlite3 *pBlocked, /* Waiting connection */ + void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */ + void *pNotifyArg /* Argument to pass to xNotify */ +); + + +/* +** CAPI3REF: String Comparison +** +** ^The [sqlite3_stricmp()] and [sqlite3_strnicmp()] APIs allow applications +** and extensions to compare the contents of two buffers containing UTF-8 +** strings in a case-independent fashion, using the same definition of "case +** independence" that SQLite uses internally when comparing identifiers. +*/ +SQLITE_API int sqlite3_stricmp(const char *, const char *); +SQLITE_API int sqlite3_strnicmp(const char *, const char *, int); + +/* +** CAPI3REF: String Globbing +* +** ^The [sqlite3_strglob(P,X)] interface returns zero if and only if +** string X matches the [GLOB] pattern P. +** ^The definition of [GLOB] pattern matching used in +** [sqlite3_strglob(P,X)] is the same as for the "X GLOB P" operator in the +** SQL dialect understood by SQLite. ^The [sqlite3_strglob(P,X)] function +** is case sensitive. +** +** Note that this routine returns zero on a match and non-zero if the strings +** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()]. +** +** See also: [sqlite3_strlike()]. +*/ +SQLITE_API int sqlite3_strglob(const char *zGlob, const char *zStr); + +/* +** CAPI3REF: String LIKE Matching +* +** ^The [sqlite3_strlike(P,X,E)] interface returns zero if and only if +** string X matches the [LIKE] pattern P with escape character E. +** ^The definition of [LIKE] pattern matching used in +** [sqlite3_strlike(P,X,E)] is the same as for the "X LIKE P ESCAPE E" +** operator in the SQL dialect understood by SQLite. ^For "X LIKE P" without +** the ESCAPE clause, set the E parameter of [sqlite3_strlike(P,X,E)] to 0. +** ^As with the LIKE operator, the [sqlite3_strlike(P,X,E)] function is case +** insensitive - equivalent upper and lower case ASCII characters match +** one another. +** +** ^The [sqlite3_strlike(P,X,E)] function matches Unicode characters, though +** only ASCII characters are case folded. +** +** Note that this routine returns zero on a match and non-zero if the strings +** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()]. +** +** See also: [sqlite3_strglob()]. +*/ +SQLITE_API int sqlite3_strlike(const char *zGlob, const char *zStr, unsigned int cEsc); + +/* +** CAPI3REF: Error Logging Interface +** +** ^The [sqlite3_log()] interface writes a message into the [error log] +** established by the [SQLITE_CONFIG_LOG] option to [sqlite3_config()]. +** ^If logging is enabled, the zFormat string and subsequent arguments are +** used with [sqlite3_snprintf()] to generate the final output string. +** +** The sqlite3_log() interface is intended for use by extensions such as +** virtual tables, collating functions, and SQL functions. While there is +** nothing to prevent an application from calling sqlite3_log(), doing so +** is considered bad form. +** +** The zFormat string must not be NULL. +** +** To avoid deadlocks and other threading problems, the sqlite3_log() routine +** will not use dynamically allocated memory. The log message is stored in +** a fixed-length buffer on the stack. If the log message is longer than +** a few hundred characters, it will be truncated to the length of the +** buffer. +*/ +SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...); + +/* +** CAPI3REF: Write-Ahead Log Commit Hook +** METHOD: sqlite3 +** +** ^The [sqlite3_wal_hook()] function is used to register a callback that +** is invoked each time data is committed to a database in wal mode. +** +** ^(The callback is invoked by SQLite after the commit has taken place and +** the associated write-lock on the database released)^, so the implementation +** may read, write or [checkpoint] the database as required. +** +** ^The first parameter passed to the callback function when it is invoked +** is a copy of the third parameter passed to sqlite3_wal_hook() when +** registering the callback. ^The second is a copy of the database handle. +** ^The third parameter is the name of the database that was written to - +** either "main" or the name of an [ATTACH]-ed database. ^The fourth parameter +** is the number of pages currently in the write-ahead log file, +** including those that were just committed. +** +** ^The callback function should normally return [SQLITE_OK]. ^If an error +** code is returned, that error will propagate back up through the +** SQLite code base to cause the statement that provoked the callback +** to report an error, though the commit will have still occurred. If the +** callback returns [SQLITE_ROW] or [SQLITE_DONE], or if it returns a value +** that does not correspond to any valid SQLite error code, the results +** are undefined. +** +** ^A single database handle may have at most a single write-ahead log +** callback registered at one time. ^Calling [sqlite3_wal_hook()] +** replaces the default behavior or previously registered write-ahead +** log callback. +** +** ^The return value is a copy of the third parameter from the +** previous call, if any, or 0. +** +** ^The [sqlite3_wal_autocheckpoint()] interface and the +** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and +** will overwrite any prior [sqlite3_wal_hook()] settings. +** +** ^If a write-ahead log callback is set using this function then +** [sqlite3_wal_checkpoint_v2()] or [PRAGMA wal_checkpoint] +** should be invoked periodically to keep the write-ahead log file +** from growing without bound. +** +** ^Passing a NULL pointer for the callback disables automatic +** checkpointing entirely. To re-enable the default behavior, call +** sqlite3_wal_autocheckpoint(db,1000) or use [PRAGMA wal_checkpoint]. +*/ +SQLITE_API void *sqlite3_wal_hook( + sqlite3*, + int(*)(void *,sqlite3*,const char*,int), + void* +); + +/* +** CAPI3REF: Configure an auto-checkpoint +** METHOD: sqlite3 +** +** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around +** [sqlite3_wal_hook()] that causes any database on [database connection] D +** to automatically [checkpoint] +** after committing a transaction if there are N or +** more frames in the [write-ahead log] file. ^Passing zero or +** a negative value as the N parameter disables automatic +** checkpoints entirely. +** +** ^The callback registered by this function replaces any existing callback +** registered using [sqlite3_wal_hook()]. ^Likewise, registering a callback +** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism +** configured by this function. +** +** ^The [wal_autocheckpoint pragma] can be used to invoke this interface +** from SQL. +** +** ^Checkpoints initiated by this mechanism are +** [sqlite3_wal_checkpoint_v2|PASSIVE]. +** +** ^Every new [database connection] defaults to having the auto-checkpoint +** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT] +** pages. +** +** ^The use of this interface is only necessary if the default setting +** is found to be suboptimal for a particular application. +*/ +SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N); + +/* +** CAPI3REF: Checkpoint a database +** METHOD: sqlite3 +** +** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to +** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^ +** +** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the +** [write-ahead log] for database X on [database connection] D to be +** transferred into the database file and for the write-ahead log to +** be reset. See the [checkpointing] documentation for addition +** information. +** +** This interface used to be the only way to cause a checkpoint to +** occur. But then the newer and more powerful [sqlite3_wal_checkpoint_v2()] +** interface was added. This interface is retained for backwards +** compatibility and as a convenience for applications that need to manually +** start a callback but which do not need the full power (and corresponding +** complication) of [sqlite3_wal_checkpoint_v2()]. +*/ +SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); + +/* +** CAPI3REF: Checkpoint a database +** METHOD: sqlite3 +** +** ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint +** operation on database X of [database connection] D in mode M. Status +** information is written back into integers pointed to by L and C.)^ +** ^(The M parameter must be a valid [checkpoint mode]:)^ +** +**
    +**
    SQLITE_CHECKPOINT_PASSIVE
    +** ^Checkpoint as many frames as possible without waiting for any database +** readers or writers to finish, then sync the database file if all frames +** in the log were checkpointed. ^The [busy-handler callback] +** is never invoked in the SQLITE_CHECKPOINT_PASSIVE mode. +** ^On the other hand, passive mode might leave the checkpoint unfinished +** if there are concurrent readers or writers. +** +**
    SQLITE_CHECKPOINT_FULL
    +** ^This mode blocks (it invokes the +** [sqlite3_busy_handler|busy-handler callback]) until there is no +** database writer and all readers are reading from the most recent database +** snapshot. ^It then checkpoints all frames in the log file and syncs the +** database file. ^This mode blocks new database writers while it is pending, +** but new database readers are allowed to continue unimpeded. +** +**
    SQLITE_CHECKPOINT_RESTART
    +** ^This mode works the same way as SQLITE_CHECKPOINT_FULL with the addition +** that after checkpointing the log file it blocks (calls the +** [busy-handler callback]) +** until all readers are reading from the database file only. ^This ensures +** that the next writer will restart the log file from the beginning. +** ^Like SQLITE_CHECKPOINT_FULL, this mode blocks new +** database writer attempts while it is pending, but does not impede readers. +** +**
    SQLITE_CHECKPOINT_TRUNCATE
    +** ^This mode works the same way as SQLITE_CHECKPOINT_RESTART with the +** addition that it also truncates the log file to zero bytes just prior +** to a successful return. +** +**
    SQLITE_CHECKPOINT_NOOP
    +** ^This mode always checkpoints zero frames. The only reason to invoke +** a NOOP checkpoint is to access the values returned by +** sqlite3_wal_checkpoint_v2() via output parameters *pnLog and *pnCkpt. +**
    +** +** ^If pnLog is not NULL, then *pnLog is set to the total number of frames in +** the log file or to -1 if the checkpoint could not run because +** of an error or because the database is not in [WAL mode]. ^If pnCkpt is not +** NULL,then *pnCkpt is set to the total number of checkpointed frames in the +** log file (including any that were already checkpointed before the function +** was called) or to -1 if the checkpoint could not run due to an error or +** because the database is not in WAL mode. ^Note that upon successful +** completion of an SQLITE_CHECKPOINT_TRUNCATE, the log file will have been +** truncated to zero bytes and so both *pnLog and *pnCkpt will be set to zero. +** +** ^All calls obtain an exclusive "checkpoint" lock on the database file. ^If +** any other process is running a checkpoint operation at the same time, the +** lock cannot be obtained and SQLITE_BUSY is returned. ^Even if there is a +** busy-handler configured, it will not be invoked in this case. +** +** ^The SQLITE_CHECKPOINT_FULL, RESTART and TRUNCATE modes also obtain the +** exclusive "writer" lock on the database file. ^If the writer lock cannot be +** obtained immediately, and a busy-handler is configured, it is invoked and +** the writer lock retried until either the busy-handler returns 0 or the lock +** is successfully obtained. ^The busy-handler is also invoked while waiting for +** database readers as described above. ^If the busy-handler returns 0 before +** the writer lock is obtained or while waiting for database readers, the +** checkpoint operation proceeds from that point in the same way as +** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible +** without blocking any further. ^SQLITE_BUSY is returned in this case. +** +** ^If parameter zDb is NULL or points to a zero length string, then the +** specified operation is attempted on all WAL databases [attached] to +** [database connection] db. In this case the +** values written to output parameters *pnLog and *pnCkpt are undefined. ^If +** an SQLITE_BUSY error is encountered when processing one or more of the +** attached WAL databases, the operation is still attempted on any remaining +** attached databases and SQLITE_BUSY is returned at the end. ^If any other +** error occurs while processing an attached database, processing is abandoned +** and the error code is returned to the caller immediately. ^If no error +** (SQLITE_BUSY or otherwise) is encountered while processing the attached +** databases, SQLITE_OK is returned. +** +** ^If database zDb is the name of an attached database that is not in WAL +** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. ^If +** zDb is not NULL (or a zero length string) and is not the name of any +** attached database, SQLITE_ERROR is returned to the caller. +** +** ^Unless it returns SQLITE_MISUSE, +** the sqlite3_wal_checkpoint_v2() interface +** sets the error information that is queried by +** [sqlite3_errcode()] and [sqlite3_errmsg()]. +** +** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface +** from SQL. +*/ +SQLITE_API int sqlite3_wal_checkpoint_v2( + sqlite3 *db, /* Database handle */ + const char *zDb, /* Name of attached database (or NULL) */ + int eMode, /* SQLITE_CHECKPOINT_* value */ + int *pnLog, /* OUT: Size of WAL log in frames */ + int *pnCkpt /* OUT: Total number of frames checkpointed */ +); + +/* +** CAPI3REF: Checkpoint Mode Values +** KEYWORDS: {checkpoint mode} +** +** These constants define all valid values for the "checkpoint mode" passed +** as the third parameter to the [sqlite3_wal_checkpoint_v2()] interface. +** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the +** meaning of each of these checkpoint modes. +*/ +#define SQLITE_CHECKPOINT_NOOP -1 /* Do no work at all */ +#define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */ +#define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */ +#define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for readers */ +#define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */ + +/* +** CAPI3REF: Virtual Table Interface Configuration +** +** This function may be called by either the [xConnect] or [xCreate] method +** of a [virtual table] implementation to configure +** various facets of the virtual table interface. +** +** If this interface is invoked outside the context of an xConnect or +** xCreate virtual table method then the behavior is undefined. +** +** In the call sqlite3_vtab_config(D,C,...) the D parameter is the +** [database connection] in which the virtual table is being created and +** which is passed in as the first argument to the [xConnect] or [xCreate] +** method that is invoking sqlite3_vtab_config(). The C parameter is one +** of the [virtual table configuration options]. The presence and meaning +** of parameters after C depend on which [virtual table configuration option] +** is used. +*/ +SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); + +/* +** CAPI3REF: Virtual Table Configuration Options +** KEYWORDS: {virtual table configuration options} +** KEYWORDS: {virtual table configuration option} +** +** These macros define the various options to the +** [sqlite3_vtab_config()] interface that [virtual table] implementations +** can use to customize and optimize their behavior. +** +**
    +** [[SQLITE_VTAB_CONSTRAINT_SUPPORT]] +**
    SQLITE_VTAB_CONSTRAINT_SUPPORT
    +**
    Calls of the form +** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported, +** where X is an integer. If X is zero, then the [virtual table] whose +** [xCreate] or [xConnect] method invoked [sqlite3_vtab_config()] does not +** support constraints. In this configuration (which is the default) if +** a call to the [xUpdate] method returns [SQLITE_CONSTRAINT], then the entire +** statement is rolled back as if [ON CONFLICT | OR ABORT] had been +** specified as part of the user's SQL statement, regardless of the actual +** ON CONFLICT mode specified. +** +** If X is non-zero, then the virtual table implementation guarantees +** that if [xUpdate] returns [SQLITE_CONSTRAINT], it will do so before +** any modifications to internal or persistent data structures have been made. +** If the [ON CONFLICT] mode is ABORT, FAIL, IGNORE or ROLLBACK, SQLite +** is able to roll back a statement or database transaction, and abandon +** or continue processing the current SQL statement as appropriate. +** If the ON CONFLICT mode is REPLACE and the [xUpdate] method returns +** [SQLITE_CONSTRAINT], SQLite handles this as if the ON CONFLICT mode +** had been ABORT. +** +** Virtual table implementations that are required to handle OR REPLACE +** must do so within the [xUpdate] method. If a call to the +** [sqlite3_vtab_on_conflict()] function indicates that the current ON +** CONFLICT policy is REPLACE, the virtual table implementation should +** silently replace the appropriate rows within the xUpdate callback and +** return SQLITE_OK. Or, if this is not possible, it may return +** SQLITE_CONSTRAINT, in which case SQLite falls back to OR ABORT +** constraint handling. +**
    +** +** [[SQLITE_VTAB_DIRECTONLY]]
    SQLITE_VTAB_DIRECTONLY
    +**
    Calls of the form +** [sqlite3_vtab_config](db,SQLITE_VTAB_DIRECTONLY) from within the +** the [xConnect] or [xCreate] methods of a [virtual table] implementation +** prohibits that virtual table from being used from within triggers and +** views. +**
    +** +** [[SQLITE_VTAB_INNOCUOUS]]
    SQLITE_VTAB_INNOCUOUS
    +**
    Calls of the form +** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the +** [xConnect] or [xCreate] methods of a [virtual table] implementation +** identify that virtual table as being safe to use from within triggers +** and views. Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the +** virtual table can do no serious harm even if it is controlled by a +** malicious hacker. Developers should avoid setting the SQLITE_VTAB_INNOCUOUS +** flag unless absolutely necessary. +**
    +** +** [[SQLITE_VTAB_USES_ALL_SCHEMAS]]
    SQLITE_VTAB_USES_ALL_SCHEMAS
    +**
    Calls of the form +** [sqlite3_vtab_config](db,SQLITE_VTAB_USES_ALL_SCHEMA) from within the +** the [xConnect] or [xCreate] methods of a [virtual table] implementation +** instruct the query planner to begin at least a read transaction on +** all schemas ("main", "temp", and any ATTACH-ed databases) whenever the +** virtual table is used. +**
    +**
    +*/ +#define SQLITE_VTAB_CONSTRAINT_SUPPORT 1 +#define SQLITE_VTAB_INNOCUOUS 2 +#define SQLITE_VTAB_DIRECTONLY 3 +#define SQLITE_VTAB_USES_ALL_SCHEMAS 4 + +/* +** CAPI3REF: Determine The Virtual Table Conflict Policy +** +** This function may only be called from within a call to the [xUpdate] method +** of a [virtual table] implementation for an INSERT or UPDATE operation. ^The +** value returned is one of [SQLITE_ROLLBACK], [SQLITE_IGNORE], [SQLITE_FAIL], +** [SQLITE_ABORT], or [SQLITE_REPLACE], according to the [ON CONFLICT] mode +** of the SQL statement that triggered the call to the [xUpdate] method of the +** [virtual table]. +*/ +SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *); + +/* +** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE +** +** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn] +** method of a [virtual table], then it might return true if the +** column is being fetched as part of an UPDATE operation during which the +** column value will not change. The virtual table implementation can use +** this hint as permission to substitute a return value that is less +** expensive to compute and that the corresponding +** [xUpdate] method understands as a "no-change" value. +** +** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that +** the column is not changed by the UPDATE statement, then the xColumn +** method can optionally return without setting a result, without calling +** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces]. +** In that case, [sqlite3_value_nochange(X)] will return true for the +** same column in the [xUpdate] method. +** +** The sqlite3_vtab_nochange() routine is an optimization. Virtual table +** implementations should continue to give a correct answer even if the +** sqlite3_vtab_nochange() interface were to always return false. In the +** current implementation, the sqlite3_vtab_nochange() interface does always +** returns false for the enhanced [UPDATE FROM] statement. +*/ +SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*); + +/* +** CAPI3REF: Determine The Collation For a Virtual Table Constraint +** METHOD: sqlite3_index_info +** +** This function may only be called from within a call to the [xBestIndex] +** method of a [virtual table]. This function returns a pointer to a string +** that is the name of the appropriate collation sequence to use for text +** comparisons on the constraint identified by its arguments. +** +** The first argument must be the pointer to the [sqlite3_index_info] object +** that is the first parameter to the xBestIndex() method. The second argument +** must be an index into the aConstraint[] array belonging to the +** sqlite3_index_info structure passed to xBestIndex. +** +** Important: +** The first parameter must be the same pointer that is passed into the +** xBestMethod() method. The first parameter may not be a pointer to a +** different [sqlite3_index_info] object, even an exact copy. +** +** The return value is computed as follows: +** +**
      +**
    1. If the constraint comes from a WHERE clause expression that contains +** a [COLLATE operator], then the name of the collation specified by +** that COLLATE operator is returned. +**

    2. If there is no COLLATE operator, but the column that is the subject +** of the constraint specifies an alternative collating sequence via +** a [COLLATE clause] on the column definition within the CREATE TABLE +** statement that was passed into [sqlite3_declare_vtab()], then the +** name of that alternative collating sequence is returned. +**

    3. Otherwise, "BINARY" is returned. +**

    +*/ +SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int); + +/* +** CAPI3REF: Determine if a virtual table query is DISTINCT +** METHOD: sqlite3_index_info +** +** This API may only be used from within an [xBestIndex|xBestIndex method] +** of a [virtual table] implementation. The result of calling this +** interface from outside of xBestIndex() is undefined and probably harmful. +** +** ^The sqlite3_vtab_distinct() interface returns an integer between 0 and +** 3. The integer returned by sqlite3_vtab_distinct() +** gives the virtual table additional information about how the query +** planner wants the output to be ordered. As long as the virtual table +** can meet the ordering requirements of the query planner, it may set +** the "orderByConsumed" flag. +** +**
    1. +** ^If the sqlite3_vtab_distinct() interface returns 0, that means +** that the query planner needs the virtual table to return all rows in the +** sort order defined by the "nOrderBy" and "aOrderBy" fields of the +** [sqlite3_index_info] object. This is the default expectation. If the +** virtual table outputs all rows in sorted order, then it is always safe for +** the xBestIndex method to set the "orderByConsumed" flag, regardless of +** the return value from sqlite3_vtab_distinct(). +**

    2. +** ^(If the sqlite3_vtab_distinct() interface returns 1, that means +** that the query planner does not need the rows to be returned in sorted order +** as long as all rows with the same values in all columns identified by the +** "aOrderBy" field are adjacent.)^ This mode is used when the query planner +** is doing a GROUP BY. +**

    3. +** ^(If the sqlite3_vtab_distinct() interface returns 2, that means +** that the query planner does not need the rows returned in any particular +** order, as long as rows with the same values in all columns identified +** by "aOrderBy" are adjacent.)^ ^(Furthermore, when two or more rows +** contain the same values for all columns identified by "colUsed", all but +** one such row may optionally be omitted from the result.)^ +** The virtual table is not required to omit rows that are duplicates +** over the "colUsed" columns, but if the virtual table can do that without +** too much extra effort, it could potentially help the query to run faster. +** This mode is used for a DISTINCT query. +**

    4. +** ^(If the sqlite3_vtab_distinct() interface returns 3, that means the +** virtual table must return rows in the order defined by "aOrderBy" as +** if the sqlite3_vtab_distinct() interface had returned 0. However if +** two or more rows in the result have the same values for all columns +** identified by "colUsed", then all but one such row may optionally be +** omitted.)^ Like when the return value is 2, the virtual table +** is not required to omit rows that are duplicates over the "colUsed" +** columns, but if the virtual table can do that without +** too much extra effort, it could potentially help the query to run faster. +** This mode is used for queries +** that have both DISTINCT and ORDER BY clauses. +**

    +** +**

    The following table summarizes the conditions under which the +** virtual table is allowed to set the "orderByConsumed" flag based on +** the value returned by sqlite3_vtab_distinct(). This table is a +** restatement of the previous four paragraphs: +** +** +** +**
    sqlite3_vtab_distinct() return value +** Rows are returned in aOrderBy order +** Rows with the same value in all aOrderBy columns are +** adjacent +** Duplicates over all colUsed columns may be omitted +**
    0yesyesno +**
    1noyesno +**
    2noyesyes +**
    3yesyesyes +**
    +** +** ^For the purposes of comparing virtual table output values to see if the +** values are the same value for sorting purposes, two NULL values are +** considered to be the same. In other words, the comparison operator is "IS" +** (or "IS NOT DISTINCT FROM") and not "==". +** +** If a virtual table implementation is unable to meet the requirements +** specified above, then it must not set the "orderByConsumed" flag in the +** [sqlite3_index_info] object or an incorrect answer may result. +** +** ^A virtual table implementation is always free to return rows in any order +** it wants, as long as the "orderByConsumed" flag is not set. ^When the +** "orderByConsumed" flag is unset, the query planner will add extra +** [bytecode] to ensure that the final results returned by the SQL query are +** ordered correctly. The use of the "orderByConsumed" flag and the +** sqlite3_vtab_distinct() interface is merely an optimization. ^Careful +** use of the sqlite3_vtab_distinct() interface and the "orderByConsumed" +** flag might help queries against a virtual table to run faster. Being +** overly aggressive and setting the "orderByConsumed" flag when it is not +** valid to do so, on the other hand, might cause SQLite to return incorrect +** results. +*/ +SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info*); + +/* +** CAPI3REF: Identify and handle IN constraints in xBestIndex +** +** This interface may only be used from within an +** [xBestIndex|xBestIndex() method] of a [virtual table] implementation. +** The result of invoking this interface from any other context is +** undefined and probably harmful. +** +** ^(A constraint on a virtual table of the form +** "[IN operator|column IN (...)]" is +** communicated to the xBestIndex method as a +** [SQLITE_INDEX_CONSTRAINT_EQ] constraint.)^ If xBestIndex wants to use +** this constraint, it must set the corresponding +** aConstraintUsage[].argvIndex to a positive integer. ^(Then, under +** the usual mode of handling IN operators, SQLite generates [bytecode] +** that invokes the [xFilter|xFilter() method] once for each value +** on the right-hand side of the IN operator.)^ Thus the virtual table +** only sees a single value from the right-hand side of the IN operator +** at a time. +** +** In some cases, however, it would be advantageous for the virtual +** table to see all values on the right-hand of the IN operator all at +** once. The sqlite3_vtab_in() interfaces facilitates this in two ways: +** +**

      +**
    1. +** ^A call to sqlite3_vtab_in(P,N,-1) will return true (non-zero) +** if and only if the [sqlite3_index_info|P->aConstraint][N] constraint +** is an [IN operator] that can be processed all at once. ^In other words, +** sqlite3_vtab_in() with -1 in the third argument is a mechanism +** by which the virtual table can ask SQLite if all-at-once processing +** of the IN operator is even possible. +** +**

    2. +** ^A call to sqlite3_vtab_in(P,N,F) with F==1 or F==0 indicates +** to SQLite that the virtual table does or does not want to process +** the IN operator all-at-once, respectively. ^Thus when the third +** parameter (F) is non-negative, this interface is the mechanism by +** which the virtual table tells SQLite how it wants to process the +** IN operator. +**

    +** +** ^The sqlite3_vtab_in(P,N,F) interface can be invoked multiple times +** within the same xBestIndex method call. ^For any given P,N pair, +** the return value from sqlite3_vtab_in(P,N,F) will always be the same +** within the same xBestIndex call. ^If the interface returns true +** (non-zero), that means that the constraint is an IN operator +** that can be processed all-at-once. ^If the constraint is not an IN +** operator or cannot be processed all-at-once, then the interface returns +** false. +** +** ^(All-at-once processing of the IN operator is selected if both of the +** following conditions are met: +** +**
      +**
    1. The P->aConstraintUsage[N].argvIndex value is set to a positive +** integer. This is how the virtual table tells SQLite that it wants to +** use the N-th constraint. +** +**

    2. The last call to sqlite3_vtab_in(P,N,F) for which F was +** non-negative had F>=1. +**

    )^ +** +** ^If either or both of the conditions above are false, then SQLite uses +** the traditional one-at-a-time processing strategy for the IN constraint. +** ^If both conditions are true, then the argvIndex-th parameter to the +** xFilter method will be an [sqlite3_value] that appears to be NULL, +** but which can be passed to [sqlite3_vtab_in_first()] and +** [sqlite3_vtab_in_next()] to find all values on the right-hand side +** of the IN constraint. +*/ +SQLITE_API int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle); + +/* +** CAPI3REF: Find all elements on the right-hand side of an IN constraint. +** +** These interfaces are only useful from within the +** [xFilter|xFilter() method] of a [virtual table] implementation. +** The result of invoking these interfaces from any other context +** is undefined and probably harmful. +** +** The X parameter in a call to sqlite3_vtab_in_first(X,P) or +** sqlite3_vtab_in_next(X,P) should be one of the parameters to the +** xFilter method which invokes these routines, and specifically +** a parameter that was previously selected for all-at-once IN constraint +** processing using the [sqlite3_vtab_in()] interface in the +** [xBestIndex|xBestIndex method]. ^(If the X parameter is not +** an xFilter argument that was selected for all-at-once IN constraint +** processing, then these routines return [SQLITE_ERROR].)^ +** +** ^(Use these routines to access all values on the right-hand side +** of the IN constraint using code like the following: +** +**
    +**    for(rc=sqlite3_vtab_in_first(pList, &pVal);
    +**        rc==SQLITE_OK && pVal;
    +**        rc=sqlite3_vtab_in_next(pList, &pVal)
    +**    ){
    +**      // do something with pVal
    +**    }
    +**    if( rc!=SQLITE_DONE ){
    +**      // an error has occurred
    +**    }
    +** 
    )^ +** +** ^On success, the sqlite3_vtab_in_first(X,P) and sqlite3_vtab_in_next(X,P) +** routines return SQLITE_OK and set *P to point to the first or next value +** on the RHS of the IN constraint. ^If there are no more values on the +** right hand side of the IN constraint, then *P is set to NULL and these +** routines return [SQLITE_DONE]. ^The return value might be +** some other value, such as SQLITE_NOMEM, in the event of a malfunction. +** +** The *ppOut values returned by these routines are only valid until the +** next call to either of these routines or until the end of the xFilter +** method from which these routines were called. If the virtual table +** implementation needs to retain the *ppOut values for longer, it must make +** copies. The *ppOut values are [protected sqlite3_value|protected]. +*/ +SQLITE_API int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut); +SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut); + +/* +** CAPI3REF: Constraint values in xBestIndex() +** METHOD: sqlite3_index_info +** +** This API may only be used from within the [xBestIndex|xBestIndex method] +** of a [virtual table] implementation. The result of calling this interface +** from outside of an xBestIndex method are undefined and probably harmful. +** +** ^When the sqlite3_vtab_rhs_value(P,J,V) interface is invoked from within +** the [xBestIndex] method of a [virtual table] implementation, with P being +** a copy of the [sqlite3_index_info] object pointer passed into xBestIndex and +** J being a 0-based index into P->aConstraint[], then this routine +** attempts to set *V to the value of the right-hand operand of +** that constraint if the right-hand operand is known. ^If the +** right-hand operand is not known, then *V is set to a NULL pointer. +** ^The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if +** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V) +** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th +** constraint is not available. ^The sqlite3_vtab_rhs_value() interface +** can return a result code other than SQLITE_OK or SQLITE_NOTFOUND if +** something goes wrong. +** +** The sqlite3_vtab_rhs_value() interface is usually only successful if +** the right-hand operand of a constraint is a literal value in the original +** SQL statement. If the right-hand operand is an expression or a reference +** to some other column or a [host parameter], then sqlite3_vtab_rhs_value() +** will probably return [SQLITE_NOTFOUND]. +** +** ^(Some constraints, such as [SQLITE_INDEX_CONSTRAINT_ISNULL] and +** [SQLITE_INDEX_CONSTRAINT_ISNOTNULL], have no right-hand operand. For such +** constraints, sqlite3_vtab_rhs_value() always returns SQLITE_NOTFOUND.)^ +** +** ^The [sqlite3_value] object returned in *V is a protected sqlite3_value +** and remains valid for the duration of the xBestIndex method call. +** ^When xBestIndex returns, the sqlite3_value object returned by +** sqlite3_vtab_rhs_value() is automatically deallocated. +** +** The "_rhs_" in the name of this routine is an abbreviation for +** "Right-Hand Side". +*/ +SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal); + +/* +** CAPI3REF: Conflict resolution modes +** KEYWORDS: {conflict resolution mode} +** +** These constants are returned by [sqlite3_vtab_on_conflict()] to +** inform a [virtual table] implementation of the [ON CONFLICT] mode +** for the SQL statement being evaluated. +** +** Note that the [SQLITE_IGNORE] constant is also used as a potential +** return value from the [sqlite3_set_authorizer()] callback and that +** [SQLITE_ABORT] is also a [result code]. +*/ +#define SQLITE_ROLLBACK 1 +/* #define SQLITE_IGNORE 2 // Also used by sqlite3_authorizer() callback */ +#define SQLITE_FAIL 3 +/* #define SQLITE_ABORT 4 // Also an error code */ +#define SQLITE_REPLACE 5 + +/* +** CAPI3REF: Prepared Statement Scan Status Opcodes +** KEYWORDS: {scanstatus options} +** +** The following constants can be used for the T parameter to the +** [sqlite3_stmt_scanstatus(S,X,T,V)] interface. Each constant designates a +** different metric for sqlite3_stmt_scanstatus() to return. +** +** When the value returned to V is a string, space to hold that string is +** managed by the prepared statement S and will be automatically freed when +** S is finalized. +** +** Not all values are available for all query elements. When a value is +** not available, the output variable is set to -1 if the value is numeric, +** or to NULL if it is a string (SQLITE_SCANSTAT_NAME). +** +**
    +** [[SQLITE_SCANSTAT_NLOOP]]
    SQLITE_SCANSTAT_NLOOP
    +**
    ^The [sqlite3_int64] variable pointed to by the V parameter will be +** set to the total number of times that the X-th loop has run.
    +** +** [[SQLITE_SCANSTAT_NVISIT]]
    SQLITE_SCANSTAT_NVISIT
    +**
    ^The [sqlite3_int64] variable pointed to by the V parameter will be set +** to the total number of rows examined by all iterations of the X-th loop.
    +** +** [[SQLITE_SCANSTAT_EST]]
    SQLITE_SCANSTAT_EST
    +**
    ^The "double" variable pointed to by the V parameter will be set to the +** query planner's estimate for the average number of rows output from each +** iteration of the X-th loop. If the query planner's estimate was accurate, +** then this value will approximate the quotient NVISIT/NLOOP and the +** product of this value for all prior loops with the same SELECTID will +** be the NLOOP value for the current loop.
    +** +** [[SQLITE_SCANSTAT_NAME]]
    SQLITE_SCANSTAT_NAME
    +**
    ^The "const char *" variable pointed to by the V parameter will be set +** to a zero-terminated UTF-8 string containing the name of the index or table +** used for the X-th loop.
    +** +** [[SQLITE_SCANSTAT_EXPLAIN]]
    SQLITE_SCANSTAT_EXPLAIN
    +**
    ^The "const char *" variable pointed to by the V parameter will be set +** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] +** description for the X-th loop.
    +** +** [[SQLITE_SCANSTAT_SELECTID]]
    SQLITE_SCANSTAT_SELECTID
    +**
    ^The "int" variable pointed to by the V parameter will be set to the +** id for the X-th query plan element. The id value is unique within the +** statement. The select-id is the same value as is output in the first +** column of an [EXPLAIN QUERY PLAN] query.
    +** +** [[SQLITE_SCANSTAT_PARENTID]]
    SQLITE_SCANSTAT_PARENTID
    +**
    The "int" variable pointed to by the V parameter will be set to the +** id of the parent of the current query element, if applicable, or +** to zero if the query element has no parent. This is the same value as +** returned in the second column of an [EXPLAIN QUERY PLAN] query.
    +** +** [[SQLITE_SCANSTAT_NCYCLE]]
    SQLITE_SCANSTAT_NCYCLE
    +**
    The sqlite3_int64 output value is set to the number of cycles, +** according to the processor time-stamp counter, that elapsed while the +** query element was being processed. This value is not available for +** all query elements - if it is unavailable the output variable is +** set to -1.
    +**
    +*/ +#define SQLITE_SCANSTAT_NLOOP 0 +#define SQLITE_SCANSTAT_NVISIT 1 +#define SQLITE_SCANSTAT_EST 2 +#define SQLITE_SCANSTAT_NAME 3 +#define SQLITE_SCANSTAT_EXPLAIN 4 +#define SQLITE_SCANSTAT_SELECTID 5 +#define SQLITE_SCANSTAT_PARENTID 6 +#define SQLITE_SCANSTAT_NCYCLE 7 + +/* +** CAPI3REF: Prepared Statement Scan Status +** METHOD: sqlite3_stmt +** +** These interfaces return information about the predicted and measured +** performance for pStmt. Advanced applications can use this +** interface to compare the predicted and the measured performance and +** issue warnings and/or rerun [ANALYZE] if discrepancies are found. +** +** Since this interface is expected to be rarely used, it is only +** available if SQLite is compiled using the [SQLITE_ENABLE_STMT_SCANSTATUS] +** compile-time option. +** +** The "iScanStatusOp" parameter determines which status information to return. +** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior +** of this interface is undefined. ^The requested measurement is written into +** a variable pointed to by the "pOut" parameter. +** +** The "flags" parameter must be passed a mask of flags. At present only +** one flag is defined - [SQLITE_SCANSTAT_COMPLEX]. If SQLITE_SCANSTAT_COMPLEX +** is specified, then status information is available for all elements +** of a query plan that are reported by "[EXPLAIN QUERY PLAN]" output. If +** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements +** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of +** the EXPLAIN QUERY PLAN output) are available. Invoking API +** sqlite3_stmt_scanstatus() is equivalent to calling +** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter. +** +** Parameter "idx" identifies the specific query element to retrieve statistics +** for. Query elements are numbered starting from zero. A value of -1 may +** retrieve statistics for the entire query. ^If idx is out of range +** - less than -1 or greater than or equal to the total number of query +** elements used to implement the statement - a non-zero value is returned and +** the variable that pOut points to is unchanged. +** +** See also: [sqlite3_stmt_scanstatus_reset()] and the +** [nexec and ncycle] columns of the [bytecode virtual table]. +*/ +SQLITE_API int sqlite3_stmt_scanstatus( + sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ + int idx, /* Index of loop to report on */ + int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ + void *pOut /* Result written here */ +); +SQLITE_API int sqlite3_stmt_scanstatus_v2( + sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ + int idx, /* Index of loop to report on */ + int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ + int flags, /* Mask of flags defined below */ + void *pOut /* Result written here */ +); + +/* +** CAPI3REF: Prepared Statement Scan Status +** KEYWORDS: {scan status flags} +*/ +#define SQLITE_SCANSTAT_COMPLEX 0x0001 + +/* +** CAPI3REF: Zero Scan-Status Counters +** METHOD: sqlite3_stmt +** +** ^Zero all [sqlite3_stmt_scanstatus()] related event counters. +** +** This API is only available if the library is built with pre-processor +** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined. +*/ +SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); + +/* +** CAPI3REF: Flush caches to disk mid-transaction +** METHOD: sqlite3 +** +** ^If a write-transaction is open on [database connection] D when the +** [sqlite3_db_cacheflush(D)] interface is invoked, any dirty +** pages in the pager-cache that are not currently in use are written out +** to disk. A dirty page may be in use if a database cursor created by an +** active SQL statement is reading from it, or if it is page 1 of a database +** file (page 1 is always "in use"). ^The [sqlite3_db_cacheflush(D)] +** interface flushes caches for all schemas - "main", "temp", and +** any [attached] databases. +** +** ^If this function needs to obtain extra database locks before dirty pages +** can be flushed to disk, it does so. ^If those locks cannot be obtained +** immediately and there is a busy-handler callback configured, it is invoked +** in the usual manner. ^If the required lock still cannot be obtained, then +** the database is skipped and an attempt made to flush any dirty pages +** belonging to the next (if any) database. ^If any databases are skipped +** because locks cannot be obtained, but no other error occurs, this +** function returns SQLITE_BUSY. +** +** ^If any other error occurs while flushing dirty pages to disk (for +** example an IO error or out-of-memory condition), then processing is +** abandoned and an SQLite [error code] is returned to the caller immediately. +** +** ^Otherwise, if no error occurs, [sqlite3_db_cacheflush()] returns SQLITE_OK. +** +** ^This function does not set the database handle error code or message +** returned by the [sqlite3_errcode()] and [sqlite3_errmsg()] functions. +*/ +SQLITE_API int sqlite3_db_cacheflush(sqlite3*); + +/* +** CAPI3REF: The pre-update hook. +** METHOD: sqlite3 +** +** ^These interfaces are only available if SQLite is compiled using the +** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option. +** +** ^The [sqlite3_preupdate_hook()] interface registers a callback function +** that is invoked prior to each [INSERT], [UPDATE], and [DELETE] operation +** on a database table. +** ^At most one preupdate hook may be registered at a time on a single +** [database connection]; each call to [sqlite3_preupdate_hook()] overrides +** the previous setting. +** ^The preupdate hook is disabled by invoking [sqlite3_preupdate_hook()] +** with a NULL pointer as the second parameter. +** ^The third parameter to [sqlite3_preupdate_hook()] is passed through as +** the first parameter to callbacks. +** +** ^The preupdate hook only fires for changes to real database tables; the +** preupdate hook is not invoked for changes to [virtual tables] or to +** system tables like sqlite_sequence or sqlite_stat1. +** +** ^The second parameter to the preupdate callback is a pointer to +** the [database connection] that registered the preupdate hook. +** ^The third parameter to the preupdate callback is one of the constants +** [SQLITE_INSERT], [SQLITE_DELETE], or [SQLITE_UPDATE] to identify the +** kind of update operation that is about to occur. +** ^(The fourth parameter to the preupdate callback is the name of the +** database within the database connection that is being modified. This +** will be "main" for the main database or "temp" for TEMP tables or +** the name given after the AS keyword in the [ATTACH] statement for attached +** databases.)^ +** ^The fifth parameter to the preupdate callback is the name of the +** table that is being modified. +** +** For an UPDATE or DELETE operation on a [rowid table], the sixth +** parameter passed to the preupdate callback is the initial [rowid] of the +** row being modified or deleted. For an INSERT operation on a rowid table, +** or any operation on a WITHOUT ROWID table, the value of the sixth +** parameter is undefined. For an INSERT or UPDATE on a rowid table the +** seventh parameter is the final rowid value of the row being inserted +** or updated. The value of the seventh parameter passed to the callback +** function is not defined for operations on WITHOUT ROWID tables, or for +** DELETE operations on rowid tables. +** +** ^The sqlite3_preupdate_hook(D,C,P) function returns the P argument from +** the previous call on the same [database connection] D, or NULL for +** the first call on D. +** +** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()], +** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces +** provide additional information about a preupdate event. These routines +** may only be called from within a preupdate callback. Invoking any of +** these routines from outside of a preupdate callback or with a +** [database connection] pointer that is different from the one supplied +** to the preupdate callback results in undefined and probably undesirable +** behavior. +** +** ^The [sqlite3_preupdate_count(D)] interface returns the number of columns +** in the row that is being inserted, updated, or deleted. +** +** ^The [sqlite3_preupdate_old(D,N,P)] interface writes into P a pointer to +** a [protected sqlite3_value] that contains the value of the Nth column of +** the table row before it is updated. The N parameter must be between 0 +** and one less than the number of columns or the behavior will be +** undefined. This must only be used within SQLITE_UPDATE and SQLITE_DELETE +** preupdate callbacks; if it is used by an SQLITE_INSERT callback then the +** behavior is undefined. The [sqlite3_value] that P points to +** will be destroyed when the preupdate callback returns. +** +** ^The [sqlite3_preupdate_new(D,N,P)] interface writes into P a pointer to +** a [protected sqlite3_value] that contains the value of the Nth column of +** the table row after it is updated. The N parameter must be between 0 +** and one less than the number of columns or the behavior will be +** undefined. This must only be used within SQLITE_INSERT and SQLITE_UPDATE +** preupdate callbacks; if it is used by an SQLITE_DELETE callback then the +** behavior is undefined. The [sqlite3_value] that P points to +** will be destroyed when the preupdate callback returns. +** +** ^The [sqlite3_preupdate_depth(D)] interface returns 0 if the preupdate +** callback was invoked as a result of a direct insert, update, or delete +** operation; or 1 for inserts, updates, or deletes invoked by top-level +** triggers; or 2 for changes resulting from triggers called by top-level +** triggers; and so forth. +** +** When the [sqlite3_blob_write()] API is used to update a blob column, +** the pre-update hook is invoked with SQLITE_DELETE, because +** the new values are not yet available. In this case, when a +** callback made with op==SQLITE_DELETE is actually a write using the +** sqlite3_blob_write() API, the [sqlite3_preupdate_blobwrite()] returns +** the index of the column being written. In other cases, where the +** pre-update hook is being invoked for some other reason, including a +** regular DELETE, sqlite3_preupdate_blobwrite() returns -1. +** +** See also: [sqlite3_update_hook()] +*/ +#if defined(SQLITE_ENABLE_PREUPDATE_HOOK) +SQLITE_API void *sqlite3_preupdate_hook( + sqlite3 *db, + void(*xPreUpdate)( + void *pCtx, /* Copy of third arg to preupdate_hook() */ + sqlite3 *db, /* Database handle */ + int op, /* SQLITE_UPDATE, DELETE or INSERT */ + char const *zDb, /* Database name */ + char const *zName, /* Table name */ + sqlite3_int64 iKey1, /* Rowid of row about to be deleted/updated */ + sqlite3_int64 iKey2 /* New rowid value (for a rowid UPDATE) */ + ), + void* +); +SQLITE_API int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **); +SQLITE_API int sqlite3_preupdate_count(sqlite3 *); +SQLITE_API int sqlite3_preupdate_depth(sqlite3 *); +SQLITE_API int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **); +SQLITE_API int sqlite3_preupdate_blobwrite(sqlite3 *); +#endif + +/* +** CAPI3REF: Low-level system error code +** METHOD: sqlite3 +** +** ^Attempt to return the underlying operating system error code or error +** number that caused the most recent I/O error or failure to open a file. +** The return value is OS-dependent. For example, on unix systems, after +** [sqlite3_open_v2()] returns [SQLITE_CANTOPEN], this interface could be +** called to get back the underlying "errno" that caused the problem, such +** as ENOSPC, EAUTH, EISDIR, and so forth. +*/ +SQLITE_API int sqlite3_system_errno(sqlite3*); + +/* +** CAPI3REF: Database Snapshot +** KEYWORDS: {snapshot} {sqlite3_snapshot} +** +** An instance of the snapshot object records the state of a [WAL mode] +** database for some specific point in history. +** +** In [WAL mode], multiple [database connections] that are open on the +** same database file can each be reading a different historical version +** of the database file. When a [database connection] begins a read +** transaction, that connection sees an unchanging copy of the database +** as it existed for the point in time when the transaction first started. +** Subsequent changes to the database from other connections are not seen +** by the reader until a new read transaction is started. +** +** The sqlite3_snapshot object records state information about an historical +** version of the database file so that it is possible to later open a new read +** transaction that sees that historical version of the database rather than +** the most recent version. +*/ +typedef struct sqlite3_snapshot { + unsigned char hidden[48]; +} sqlite3_snapshot; + +/* +** CAPI3REF: Record A Database Snapshot +** CONSTRUCTOR: sqlite3_snapshot +** +** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a +** new [sqlite3_snapshot] object that records the current state of +** schema S in database connection D. ^On success, the +** [sqlite3_snapshot_get(D,S,P)] interface writes a pointer to the newly +** created [sqlite3_snapshot] object into *P and returns SQLITE_OK. +** If there is not already a read-transaction open on schema S when +** this function is called, one is opened automatically. +** +** If a read-transaction is opened by this function, then it is guaranteed +** that the returned snapshot object may not be invalidated by a database +** writer or checkpointer until after the read-transaction is closed. This +** is not guaranteed if a read-transaction is already open when this +** function is called. In that case, any subsequent write or checkpoint +** operation on the database may invalidate the returned snapshot handle, +** even while the read-transaction remains open. +** +** The following must be true for this function to succeed. If any of +** the following statements are false when sqlite3_snapshot_get() is +** called, SQLITE_ERROR is returned. The final value of *P is undefined +** in this case. +** +**
      +**
    • The database handle must not be in [autocommit mode]. +** +**
    • Schema S of [database connection] D must be a [WAL mode] database. +** +**
    • There must not be a write transaction open on schema S of database +** connection D. +** +**
    • One or more transactions must have been written to the current wal +** file since it was created on disk (by any connection). This means +** that a snapshot cannot be taken on a wal mode database with no wal +** file immediately after it is first opened. At least one transaction +** must be written to it first. +**
    +** +** This function may also return SQLITE_NOMEM. If it is called with the +** database handle in autocommit mode but fails for some other reason, +** whether or not a read transaction is opened on schema S is undefined. +** +** The [sqlite3_snapshot] object returned from a successful call to +** [sqlite3_snapshot_get()] must be freed using [sqlite3_snapshot_free()] +** to avoid a memory leak. +** +** The [sqlite3_snapshot_get()] interface is only available when the +** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used. +*/ +SQLITE_API int sqlite3_snapshot_get( + sqlite3 *db, + const char *zSchema, + sqlite3_snapshot **ppSnapshot +); + +/* +** CAPI3REF: Start a read transaction on an historical snapshot +** METHOD: sqlite3_snapshot +** +** ^The [sqlite3_snapshot_open(D,S,P)] interface either starts a new read +** transaction or upgrades an existing one for schema S of +** [database connection] D such that the read transaction refers to +** historical [snapshot] P, rather than the most recent change to the +** database. ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK +** on success or an appropriate [error code] if it fails. +** +** ^In order to succeed, the database connection must not be in +** [autocommit mode] when [sqlite3_snapshot_open(D,S,P)] is called. If there +** is already a read transaction open on schema S, then the database handle +** must have no active statements (SELECT statements that have been passed +** to sqlite3_step() but not sqlite3_reset() or sqlite3_finalize()). +** SQLITE_ERROR is returned if either of these conditions is violated, or +** if schema S does not exist, or if the snapshot object is invalid. +** +** ^A call to sqlite3_snapshot_open() will fail to open if the specified +** snapshot has been overwritten by a [checkpoint]. In this case +** SQLITE_ERROR_SNAPSHOT is returned. +** +** If there is already a read transaction open when this function is +** invoked, then the same read transaction remains open (on the same +** database snapshot) if SQLITE_ERROR, SQLITE_BUSY or SQLITE_ERROR_SNAPSHOT +** is returned. If another error code - for example SQLITE_PROTOCOL or an +** SQLITE_IOERR error code - is returned, then the final state of the +** read transaction is undefined. If SQLITE_OK is returned, then the +** read transaction is now open on database snapshot P. +** +** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the +** database connection D does not know that the database file for +** schema S is in [WAL mode]. A database connection might not know +** that the database file is in [WAL mode] if there has been no prior +** I/O on that database connection, or if the database entered [WAL mode] +** after the most recent I/O on the database connection.)^ +** (Hint: Run "[PRAGMA application_id]" against a newly opened +** database connection in order to make it ready to use snapshots.) +** +** The [sqlite3_snapshot_open()] interface is only available when the +** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used. +*/ +SQLITE_API int sqlite3_snapshot_open( + sqlite3 *db, + const char *zSchema, + sqlite3_snapshot *pSnapshot +); + +/* +** CAPI3REF: Destroy a snapshot +** DESTRUCTOR: sqlite3_snapshot +** +** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P. +** The application must eventually free every [sqlite3_snapshot] object +** using this routine to avoid a memory leak. +** +** The [sqlite3_snapshot_free()] interface is only available when the +** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used. +*/ +SQLITE_API void sqlite3_snapshot_free(sqlite3_snapshot*); + +/* +** CAPI3REF: Compare the ages of two snapshot handles. +** METHOD: sqlite3_snapshot +** +** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages +** of two valid snapshot handles. +** +** If the two snapshot handles are not associated with the same database +** file, the result of the comparison is undefined. +** +** Additionally, the result of the comparison is only valid if both of the +** snapshot handles were obtained by calling sqlite3_snapshot_get() since the +** last time the wal file was deleted. The wal file is deleted when the +** database is changed back to rollback mode or when the number of database +** clients drops to zero. If either snapshot handle was obtained before the +** wal file was last deleted, the value returned by this function +** is undefined. +** +** Otherwise, this API returns a negative value if P1 refers to an older +** snapshot than P2, zero if the two handles refer to the same database +** snapshot, and a positive value if P1 is a newer snapshot than P2. +** +** This interface is only available if SQLite is compiled with the +** [SQLITE_ENABLE_SNAPSHOT] option. +*/ +SQLITE_API int sqlite3_snapshot_cmp( + sqlite3_snapshot *p1, + sqlite3_snapshot *p2 +); + +/* +** CAPI3REF: Recover snapshots from a wal file +** METHOD: sqlite3_snapshot +** +** If a [WAL file] remains on disk after all database connections close +** (either through the use of the [SQLITE_FCNTL_PERSIST_WAL] [file control] +** or because the last process to have the database opened exited without +** calling [sqlite3_close()]) and a new connection is subsequently opened +** on that database and [WAL file], the [sqlite3_snapshot_open()] interface +** will only be able to open the last transaction added to the WAL file +** even though the WAL file contains other valid transactions. +** +** This function attempts to scan the WAL file associated with database zDb +** of database handle db and make all valid snapshots available to +** sqlite3_snapshot_open(). It is an error if there is already a read +** transaction open on the database, or if the database is not a WAL mode +** database. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +** +** This interface is only available if SQLite is compiled with the +** [SQLITE_ENABLE_SNAPSHOT] option. +*/ +SQLITE_API int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb); + +/* +** CAPI3REF: Serialize a database +** +** The sqlite3_serialize(D,S,P,F) interface returns a pointer to +** memory that is a serialization of the S database on +** [database connection] D. If S is a NULL pointer, the main database is used. +** If P is not a NULL pointer, then the size of the database in bytes +** is written into *P. +** +** For an ordinary on-disk database file, the serialization is just a +** copy of the disk file. For an in-memory database or a "TEMP" database, +** the serialization is the same sequence of bytes which would be written +** to disk if that database were backed up to disk. +** +** The usual case is that sqlite3_serialize() copies the serialization of +** the database into memory obtained from [sqlite3_malloc64()] and returns +** a pointer to that memory. The caller is responsible for freeing the +** returned value to avoid a memory leak. However, if the F argument +** contains the SQLITE_SERIALIZE_NOCOPY bit, then no memory allocations +** are made, and the sqlite3_serialize() function will return a pointer +** to the contiguous memory representation of the database that SQLite +** is currently using for that database, or NULL if no such contiguous +** memory representation of the database exists. A contiguous memory +** representation of the database will usually only exist if there has +** been a prior call to [sqlite3_deserialize(D,S,...)] with the same +** values of D and S. +** The size of the database is written into *P even if the +** SQLITE_SERIALIZE_NOCOPY bit is set but no contiguous copy +** of the database exists. +** +** After the call, if the SQLITE_SERIALIZE_NOCOPY bit had been set, +** the returned buffer content will remain accessible and unchanged +** until either the next write operation on the connection or when +** the connection is closed, and applications must not modify the +** buffer. If the bit had been clear, the returned buffer will not +** be accessed by SQLite after the call. +** +** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the +** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory +** allocation error occurs. +** +** This interface is omitted if SQLite is compiled with the +** [SQLITE_OMIT_DESERIALIZE] option. +*/ +SQLITE_API unsigned char *sqlite3_serialize( + sqlite3 *db, /* The database connection */ + const char *zSchema, /* Which DB to serialize. ex: "main", "temp", ... */ + sqlite3_int64 *piSize, /* Write size of the DB here, if not NULL */ + unsigned int mFlags /* Zero or more SQLITE_SERIALIZE_* flags */ +); + +/* +** CAPI3REF: Flags for sqlite3_serialize +** +** Zero or more of the following constants can be OR-ed together for +** the F argument to [sqlite3_serialize(D,S,P,F)]. +** +** SQLITE_SERIALIZE_NOCOPY means that [sqlite3_serialize()] will return +** a pointer to contiguous in-memory database that it is currently using, +** without making a copy of the database. If SQLite is not currently using +** a contiguous in-memory database, then this option causes +** [sqlite3_serialize()] to return a NULL pointer. SQLite will only be +** using a contiguous in-memory database if it has been initialized by a +** prior call to [sqlite3_deserialize()]. +*/ +#define SQLITE_SERIALIZE_NOCOPY 0x001 /* Do no memory allocations */ + +/* +** CAPI3REF: Deserialize a database +** +** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the +** [database connection] D to disconnect from database S and then +** reopen S as an in-memory database based on the serialization +** contained in P. If S is a NULL pointer, the main database is +** used. The serialized database P is N bytes in size. M is the size +** of the buffer P, which might be larger than N. If M is larger than +** N, and the SQLITE_DESERIALIZE_READONLY bit is not set in F, then +** SQLite is permitted to add content to the in-memory database as +** long as the total size does not exceed M bytes. +** +** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will +** invoke sqlite3_free() on the serialization buffer when the database +** connection closes. If the SQLITE_DESERIALIZE_RESIZEABLE bit is set, then +** SQLite will try to increase the buffer size using sqlite3_realloc64() +** if writes on the database cause it to grow larger than M bytes. +** +** Applications must not modify the buffer P or invalidate it before +** the database connection D is closed. +** +** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the +** database is currently in a read transaction or is involved in a backup +** operation. +** +** It is not possible to deserialize into the TEMP database. If the +** S argument to sqlite3_deserialize(D,S,P,N,M,F) is "temp" then the +** function returns SQLITE_ERROR. +** +** The deserialized database should not be in [WAL mode]. If the database +** is in WAL mode, then any attempt to use the database file will result +** in an [SQLITE_CANTOPEN] error. The application can set the +** [file format version numbers] (bytes 18 and 19) of the input database P +** to 0x01 prior to invoking sqlite3_deserialize(D,S,P,N,M,F) to force the +** database file into rollback mode and work around this limitation. +** +** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the +** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then +** [sqlite3_free()] is invoked on argument P prior to returning. +** +** This interface is omitted if SQLite is compiled with the +** [SQLITE_OMIT_DESERIALIZE] option. +*/ +SQLITE_API int sqlite3_deserialize( + sqlite3 *db, /* The database connection */ + const char *zSchema, /* Which DB to reopen with the deserialization */ + unsigned char *pData, /* The serialized database content */ + sqlite3_int64 szDb, /* Number of bytes in the deserialization */ + sqlite3_int64 szBuf, /* Total size of buffer pData[] */ + unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */ +); + +/* +** CAPI3REF: Flags for sqlite3_deserialize() +** +** The following are allowed values for the 6th argument (the F argument) to +** the [sqlite3_deserialize(D,S,P,N,M,F)] interface. +** +** The SQLITE_DESERIALIZE_FREEONCLOSE means that the database serialization +** in the P argument is held in memory obtained from [sqlite3_malloc64()] +** and that SQLite should take ownership of this memory and automatically +** free it when it has finished using it. Without this flag, the caller +** is responsible for freeing any dynamically allocated memory. +** +** The SQLITE_DESERIALIZE_RESIZEABLE flag means that SQLite is allowed to +** grow the size of the database using calls to [sqlite3_realloc64()]. This +** flag should only be used if SQLITE_DESERIALIZE_FREEONCLOSE is also used. +** Without this flag, the deserialized database cannot increase in size beyond +** the number of bytes specified by the M parameter. +** +** The SQLITE_DESERIALIZE_READONLY flag means that the deserialized database +** should be treated as read-only. +*/ +#define SQLITE_DESERIALIZE_FREEONCLOSE 1 /* Call sqlite3_free() on close */ +#define SQLITE_DESERIALIZE_RESIZEABLE 2 /* Resize using sqlite3_realloc64() */ +#define SQLITE_DESERIALIZE_READONLY 4 /* Database is read-only */ + +/* +** CAPI3REF: Bind array values to the CARRAY table-valued function +** +** The sqlite3_carray_bind_v2(S,I,P,N,F,X,D) interface binds an array value to +** parameter that is the first argument of the [carray() table-valued function]. +** The S parameter is a pointer to the [prepared statement] that uses the +** carray() functions. I is the parameter index to be bound. I must be the +** index of the parameter that is the first argument to the carray() +** table-valued function. P is a pointer to the array to be bound, and N +** is the number of elements in the array. The F argument is one of +** constants [SQLITE_CARRAY_INT32], [SQLITE_CARRAY_INT64], +** [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT], +** or [SQLITE_CARRAY_BLOB] to indicate the datatype of the array P. +** +** If the X argument is not a NULL pointer or one of the special +** values [SQLITE_STATIC] or [SQLITE_TRANSIENT], then SQLite will invoke +** the function X with argument D when it is finished using the data in P. +** The call to X(D) is a destructor for the array P. The destructor X(D) +** is invoked even if the call to sqlite3_carray_bind_v2() fails. If the X +** parameter is the special-case value [SQLITE_STATIC], then SQLite assumes +** that the data static and the destructor is never invoked. If the X +** parameter is the special-case value [SQLITE_TRANSIENT], then +** sqlite3_carray_bind_v2() makes its own private copy of the data prior +** to returning and never invokes the destructor X. +** +** The sqlite3_carray_bind() function works the same as sqlite3_carray_bind_v2() +** with a D parameter set to P. In other words, +** sqlite3_carray_bind(S,I,P,N,F,X) is same as +** sqlite3_carray_bind_v2(S,I,P,N,F,X,P). +*/ +SQLITE_API int sqlite3_carray_bind_v2( + sqlite3_stmt *pStmt, /* Statement to be bound */ + int i, /* Parameter index */ + void *aData, /* Pointer to array data */ + int nData, /* Number of data elements */ + int mFlags, /* CARRAY flags */ + void (*xDel)(void*), /* Destructor for aData */ + void *pDel /* Optional argument to xDel() */ +); +SQLITE_API int sqlite3_carray_bind( + sqlite3_stmt *pStmt, /* Statement to be bound */ + int i, /* Parameter index */ + void *aData, /* Pointer to array data */ + int nData, /* Number of data elements */ + int mFlags, /* CARRAY flags */ + void (*xDel)(void*) /* Destructor for aData */ +); + +/* +** CAPI3REF: Datatypes for the CARRAY table-valued function +** +** The fifth argument to the [sqlite3_carray_bind()] interface musts be +** one of the following constants, to specify the datatype of the array +** that is being bound into the [carray table-valued function]. +*/ +#define SQLITE_CARRAY_INT32 0 /* Data is 32-bit signed integers */ +#define SQLITE_CARRAY_INT64 1 /* Data is 64-bit signed integers */ +#define SQLITE_CARRAY_DOUBLE 2 /* Data is doubles */ +#define SQLITE_CARRAY_TEXT 3 /* Data is char* */ +#define SQLITE_CARRAY_BLOB 4 /* Data is struct iovec */ + +/* +** Versions of the above #defines that omit the initial SQLITE_, for +** legacy compatibility. +*/ +#define CARRAY_INT32 0 /* Data is 32-bit signed integers */ +#define CARRAY_INT64 1 /* Data is 64-bit signed integers */ +#define CARRAY_DOUBLE 2 /* Data is doubles */ +#define CARRAY_TEXT 3 /* Data is char* */ +#define CARRAY_BLOB 4 /* Data is struct iovec */ + +/* +** Undo the hack that converts floating point types to integer for +** builds on processors without floating point support. +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# undef double +#endif + +#if defined(__wasi__) +# undef SQLITE_WASI +# define SQLITE_WASI 1 +# ifndef SQLITE_OMIT_LOAD_EXTENSION +# define SQLITE_OMIT_LOAD_EXTENSION +# endif +# ifndef SQLITE_THREADSAFE +# define SQLITE_THREADSAFE 0 +# endif +#endif + +#if 0 +} /* End of the 'extern "C"' block */ +#endif +/* #endif for SQLITE3_H will be added by mksqlite3.tcl */ + +/******** Begin file sqlite3rtree.h *********/ +/* +** 2010 August 30 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +*/ + +#ifndef _SQLITE3RTREE_H_ +#define _SQLITE3RTREE_H_ + + +#if 0 +extern "C" { +#endif + +typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry; +typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info; + +/* The double-precision datatype used by RTree depends on the +** SQLITE_RTREE_INT_ONLY compile-time option. +*/ +#ifdef SQLITE_RTREE_INT_ONLY + typedef sqlite3_int64 sqlite3_rtree_dbl; +#else + typedef double sqlite3_rtree_dbl; +#endif + +/* +** Register a geometry callback named zGeom that can be used as part of an +** R-Tree geometry query as follows: +** +** SELECT ... FROM WHERE MATCH $zGeom(... params ...) +*/ +SQLITE_API int sqlite3_rtree_geometry_callback( + sqlite3 *db, + const char *zGeom, + int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*), + void *pContext +); + + +/* +** A pointer to a structure of the following type is passed as the first +** argument to callbacks registered using rtree_geometry_callback(). +*/ +struct sqlite3_rtree_geometry { + void *pContext; /* Copy of pContext passed to s_r_g_c() */ + int nParam; /* Size of array aParam[] */ + sqlite3_rtree_dbl *aParam; /* Parameters passed to SQL geom function */ + void *pUser; /* Callback implementation user data */ + void (*xDelUser)(void *); /* Called by SQLite to clean up pUser */ +}; + +/* +** Register a 2nd-generation geometry callback named zScore that can be +** used as part of an R-Tree geometry query as follows: +** +** SELECT ... FROM WHERE MATCH $zQueryFunc(... params ...) +*/ +SQLITE_API int sqlite3_rtree_query_callback( + sqlite3 *db, + const char *zQueryFunc, + int (*xQueryFunc)(sqlite3_rtree_query_info*), + void *pContext, + void (*xDestructor)(void*) +); + + +/* +** A pointer to a structure of the following type is passed as the +** argument to scored geometry callback registered using +** sqlite3_rtree_query_callback(). +** +** Note that the first 5 fields of this structure are identical to +** sqlite3_rtree_geometry. This structure is a subclass of +** sqlite3_rtree_geometry. +*/ +struct sqlite3_rtree_query_info { + void *pContext; /* pContext from when function registered */ + int nParam; /* Number of function parameters */ + sqlite3_rtree_dbl *aParam; /* value of function parameters */ + void *pUser; /* callback can use this, if desired */ + void (*xDelUser)(void*); /* function to free pUser */ + sqlite3_rtree_dbl *aCoord; /* Coordinates of node or entry to check */ + unsigned int *anQueue; /* Number of pending entries in the queue */ + int nCoord; /* Number of coordinates */ + int iLevel; /* Level of current node or entry */ + int mxLevel; /* The largest iLevel value in the tree */ + sqlite3_int64 iRowid; /* Rowid for current entry */ + sqlite3_rtree_dbl rParentScore; /* Score of parent node */ + int eParentWithin; /* Visibility of parent node */ + int eWithin; /* OUT: Visibility */ + sqlite3_rtree_dbl rScore; /* OUT: Write the score here */ + /* The following fields are only available in 3.8.11 and later */ + sqlite3_value **apSqlParam; /* Original SQL values of parameters */ +}; + +/* +** Allowed values for sqlite3_rtree_query.eWithin and .eParentWithin. +*/ +#define NOT_WITHIN 0 /* Object completely outside of query region */ +#define PARTLY_WITHIN 1 /* Object partially overlaps query region */ +#define FULLY_WITHIN 2 /* Object fully contained within query region */ + + +#if 0 +} /* end of the 'extern "C"' block */ +#endif + +#endif /* ifndef _SQLITE3RTREE_H_ */ + +/******** End of sqlite3rtree.h *********/ +/******** Begin file sqlite3session.h *********/ + +#if !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION) +#define __SQLITESESSION_H_ 1 + +/* +** Make sure we can call this stuff from C++. +*/ +#if 0 +extern "C" { +#endif + + +/* +** CAPI3REF: Session Object Handle +** +** An instance of this object is a [session] that can be used to +** record changes to a database. +*/ +typedef struct sqlite3_session sqlite3_session; + +/* +** CAPI3REF: Changeset Iterator Handle +** +** An instance of this object acts as a cursor for iterating +** over the elements of a [changeset] or [patchset]. +*/ +typedef struct sqlite3_changeset_iter sqlite3_changeset_iter; + +/* +** CAPI3REF: Create A New Session Object +** CONSTRUCTOR: sqlite3_session +** +** Create a new session object attached to database handle db. If successful, +** a pointer to the new object is written to *ppSession and SQLITE_OK is +** returned. If an error occurs, *ppSession is set to NULL and an SQLite +** error code (e.g. SQLITE_NOMEM) is returned. +** +** It is possible to create multiple session objects attached to a single +** database handle. +** +** Session objects created using this function should be deleted using the +** [sqlite3session_delete()] function before the database handle that they +** are attached to is itself closed. If the database handle is closed before +** the session object is deleted, then the results of calling any session +** module function, including [sqlite3session_delete()] on the session object +** are undefined. +** +** Because the session module uses the [sqlite3_preupdate_hook()] API, it +** is not possible for an application to register a pre-update hook on a +** database handle that has one or more session objects attached. Nor is +** it possible to create a session object attached to a database handle for +** which a pre-update hook is already defined. The results of attempting +** either of these things are undefined. +** +** The session object will be used to create changesets for tables in +** database zDb, where zDb is either "main", or "temp", or the name of an +** attached database. It is not an error if database zDb is not attached +** to the database when the session object is created. +*/ +SQLITE_API int sqlite3session_create( + sqlite3 *db, /* Database handle */ + const char *zDb, /* Name of db (e.g. "main") */ + sqlite3_session **ppSession /* OUT: New session object */ +); + +/* +** CAPI3REF: Delete A Session Object +** DESTRUCTOR: sqlite3_session +** +** Delete a session object previously allocated using +** [sqlite3session_create()]. Once a session object has been deleted, the +** results of attempting to use pSession with any other session module +** function are undefined. +** +** Session objects must be deleted before the database handle to which they +** are attached is closed. Refer to the documentation for +** [sqlite3session_create()] for details. +*/ +SQLITE_API void sqlite3session_delete(sqlite3_session *pSession); + +/* +** CAPI3REF: Configure a Session Object +** METHOD: sqlite3_session +** +** This method is used to configure a session object after it has been +** created. At present the only valid values for the second parameter are +** [SQLITE_SESSION_OBJCONFIG_SIZE] and [SQLITE_SESSION_OBJCONFIG_ROWID]. +** +*/ +SQLITE_API int sqlite3session_object_config(sqlite3_session*, int op, void *pArg); + +/* +** CAPI3REF: Options for sqlite3session_object_config +** +** The following values may passed as the the 2nd parameter to +** sqlite3session_object_config(). +** +**
    SQLITE_SESSION_OBJCONFIG_SIZE
    +** This option is used to set, clear or query the flag that enables +** the [sqlite3session_changeset_size()] API. Because it imposes some +** computational overhead, this API is disabled by default. Argument +** pArg must point to a value of type (int). If the value is initially +** 0, then the sqlite3session_changeset_size() API is disabled. If it +** is greater than 0, then the same API is enabled. Or, if the initial +** value is less than zero, no change is made. In all cases the (int) +** variable is set to 1 if the sqlite3session_changeset_size() API is +** enabled following the current call, or 0 otherwise. +** +** It is an error (SQLITE_MISUSE) to attempt to modify this setting after +** the first table has been attached to the session object. +** +**
    SQLITE_SESSION_OBJCONFIG_ROWID
    +** This option is used to set, clear or query the flag that enables +** collection of data for tables with no explicit PRIMARY KEY. +** +** Normally, tables with no explicit PRIMARY KEY are simply ignored +** by the sessions module. However, if this flag is set, it behaves +** as if such tables have a column "_rowid_ INTEGER PRIMARY KEY" inserted +** as their leftmost columns. +** +** It is an error (SQLITE_MISUSE) to attempt to modify this setting after +** the first table has been attached to the session object. +*/ +#define SQLITE_SESSION_OBJCONFIG_SIZE 1 +#define SQLITE_SESSION_OBJCONFIG_ROWID 2 + +/* +** CAPI3REF: Enable Or Disable A Session Object +** METHOD: sqlite3_session +** +** Enable or disable the recording of changes by a session object. When +** enabled, a session object records changes made to the database. When +** disabled - it does not. A newly created session object is enabled. +** Refer to the documentation for [sqlite3session_changeset()] for further +** details regarding how enabling and disabling a session object affects +** the eventual changesets. +** +** Passing zero to this function disables the session. Passing a value +** greater than zero enables it. Passing a value less than zero is a +** no-op, and may be used to query the current state of the session. +** +** The return value indicates the final state of the session object: 0 if +** the session is disabled, or 1 if it is enabled. +*/ +SQLITE_API int sqlite3session_enable(sqlite3_session *pSession, int bEnable); + +/* +** CAPI3REF: Set Or Clear the Indirect Change Flag +** METHOD: sqlite3_session +** +** Each change recorded by a session object is marked as either direct or +** indirect. A change is marked as indirect if either: +** +**
      +**
    • The session object "indirect" flag is set when the change is +** made, or +**
    • The change is made by an SQL trigger or foreign key action +** instead of directly as a result of a users SQL statement. +**
    +** +** If a single row is affected by more than one operation within a session, +** then the change is considered indirect if all operations meet the criteria +** for an indirect change above, or direct otherwise. +** +** This function is used to set, clear or query the session object indirect +** flag. If the second argument passed to this function is zero, then the +** indirect flag is cleared. If it is greater than zero, the indirect flag +** is set. Passing a value less than zero does not modify the current value +** of the indirect flag, and may be used to query the current state of the +** indirect flag for the specified session object. +** +** The return value indicates the final state of the indirect flag: 0 if +** it is clear, or 1 if it is set. +*/ +SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect); + +/* +** CAPI3REF: Attach A Table To A Session Object +** METHOD: sqlite3_session +** +** If argument zTab is not NULL, then it is the name of a table to attach +** to the session object passed as the first argument. All subsequent changes +** made to the table while the session object is enabled will be recorded. See +** documentation for [sqlite3session_changeset()] for further details. +** +** Or, if argument zTab is NULL, then changes are recorded for all tables +** in the database. If additional tables are added to the database (by +** executing "CREATE TABLE" statements) after this call is made, changes for +** the new tables are also recorded. +** +** Changes can only be recorded for tables that have a PRIMARY KEY explicitly +** defined as part of their CREATE TABLE statement. It does not matter if the +** PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias) or not. The PRIMARY +** KEY may consist of a single column, or may be a composite key. +** +** It is not an error if the named table does not exist in the database. Nor +** is it an error if the named table does not have a PRIMARY KEY. However, +** no changes will be recorded in either of these scenarios. +** +** Changes are not recorded for individual rows that have NULL values stored +** in one or more of their PRIMARY KEY columns. +** +** SQLITE_OK is returned if the call completes without error. Or, if an error +** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned. +** +**

    Special sqlite_stat1 Handling

    +** +** As of SQLite version 3.22.0, the "sqlite_stat1" table is an exception to +** some of the rules above. In SQLite, the schema of sqlite_stat1 is: +**
    +**        CREATE TABLE sqlite_stat1(tbl,idx,stat)
    +**  
    +** +** Even though sqlite_stat1 does not have a PRIMARY KEY, changes are +** recorded for it as if the PRIMARY KEY is (tbl,idx). Additionally, changes +** are recorded for rows for which (idx IS NULL) is true. However, for such +** rows a zero-length blob (SQL value X'') is stored in the changeset or +** patchset instead of a NULL value. This allows such changesets to be +** manipulated by legacy implementations of sqlite3changeset_invert(), +** concat() and similar. +** +** The sqlite3changeset_apply() function automatically converts the +** zero-length blob back to a NULL value when updating the sqlite_stat1 +** table. However, if the application calls sqlite3changeset_new(), +** sqlite3changeset_old() or sqlite3changeset_conflict on a changeset +** iterator directly (including on a changeset iterator passed to a +** conflict-handler callback) then the X'' value is returned. The application +** must translate X'' to NULL itself if required. +** +** Legacy (older than 3.22.0) versions of the sessions module cannot capture +** changes made to the sqlite_stat1 table. Legacy versions of the +** sqlite3changeset_apply() function silently ignore any modifications to the +** sqlite_stat1 table that are part of a changeset or patchset. +*/ +SQLITE_API int sqlite3session_attach( + sqlite3_session *pSession, /* Session object */ + const char *zTab /* Table name */ +); + +/* +** CAPI3REF: Set a table filter on a Session Object. +** METHOD: sqlite3_session +** +** The second argument (xFilter) is the "filter callback". For changes to rows +** in tables that are not attached to the Session object, the filter is called +** to determine whether changes to the table's rows should be tracked or not. +** If xFilter returns 0, changes are not tracked. Note that once a table is +** attached, xFilter will not be called again. +*/ +SQLITE_API void sqlite3session_table_filter( + sqlite3_session *pSession, /* Session object */ + int(*xFilter)( + void *pCtx, /* Copy of third arg to _filter_table() */ + const char *zTab /* Table name */ + ), + void *pCtx /* First argument passed to xFilter */ +); + +/* +** CAPI3REF: Generate A Changeset From A Session Object +** METHOD: sqlite3_session +** +** Obtain a changeset containing changes to the tables attached to the +** session object passed as the first argument. If successful, +** set *ppChangeset to point to a buffer containing the changeset +** and *pnChangeset to the size of the changeset in bytes before returning +** SQLITE_OK. If an error occurs, set both *ppChangeset and *pnChangeset to +** zero and return an SQLite error code. +** +** A changeset consists of zero or more INSERT, UPDATE and/or DELETE changes, +** each representing a change to a single row of an attached table. An INSERT +** change contains the values of each field of a new database row. A DELETE +** contains the original values of each field of a deleted database row. An +** UPDATE change contains the original values of each field of an updated +** database row along with the updated values for each updated non-primary-key +** column. It is not possible for an UPDATE change to represent a change that +** modifies the values of primary key columns. If such a change is made, it +** is represented in a changeset as a DELETE followed by an INSERT. +** +** Changes are not recorded for rows that have NULL values stored in one or +** more of their PRIMARY KEY columns. If such a row is inserted or deleted, +** no corresponding change is present in the changesets returned by this +** function. If an existing row with one or more NULL values stored in +** PRIMARY KEY columns is updated so that all PRIMARY KEY columns are non-NULL, +** only an INSERT is appears in the changeset. Similarly, if an existing row +** with non-NULL PRIMARY KEY values is updated so that one or more of its +** PRIMARY KEY columns are set to NULL, the resulting changeset contains a +** DELETE change only. +** +** The contents of a changeset may be traversed using an iterator created +** using the [sqlite3changeset_start()] API. A changeset may be applied to +** a database with a compatible schema using the [sqlite3changeset_apply()] +** API. +** +** Within a changeset generated by this function, all changes related to a +** single table are grouped together. In other words, when iterating through +** a changeset or when applying a changeset to a database, all changes related +** to a single table are processed before moving on to the next table. Tables +** are sorted in the same order in which they were attached (or auto-attached) +** to the sqlite3_session object. The order in which the changes related to +** a single table are stored is undefined. +** +** Following a successful call to this function, it is the responsibility of +** the caller to eventually free the buffer that *ppChangeset points to using +** [sqlite3_free()]. +** +**

    Changeset Generation

    +** +** Once a table has been attached to a session object, the session object +** records the primary key values of all new rows inserted into the table. +** It also records the original primary key and other column values of any +** deleted or updated rows. For each unique primary key value, data is only +** recorded once - the first time a row with said primary key is inserted, +** updated or deleted in the lifetime of the session. +** +** There is one exception to the previous paragraph: when a row is inserted, +** updated or deleted, if one or more of its primary key columns contain a +** NULL value, no record of the change is made. +** +** The session object therefore accumulates two types of records - those +** that consist of primary key values only (created when the user inserts +** a new record) and those that consist of the primary key values and the +** original values of other table columns (created when the users deletes +** or updates a record). +** +** When this function is called, the requested changeset is created using +** both the accumulated records and the current contents of the database +** file. Specifically: +** +**
      +**
    • For each record generated by an insert, the database is queried +** for a row with a matching primary key. If one is found, an INSERT +** change is added to the changeset. If no such row is found, no change +** is added to the changeset. +** +**
    • For each record generated by an update or delete, the database is +** queried for a row with a matching primary key. If such a row is +** found and one or more of the non-primary key fields have been +** modified from their original values, an UPDATE change is added to +** the changeset. Or, if no such row is found in the table, a DELETE +** change is added to the changeset. If there is a row with a matching +** primary key in the database, but all fields contain their original +** values, no change is added to the changeset. +**
    +** +** This means, amongst other things, that if a row is inserted and then later +** deleted while a session object is active, neither the insert nor the delete +** will be present in the changeset. Or if a row is deleted and then later a +** row with the same primary key values inserted while a session object is +** active, the resulting changeset will contain an UPDATE change instead of +** a DELETE and an INSERT. +** +** When a session object is disabled (see the [sqlite3session_enable()] API), +** it does not accumulate records when rows are inserted, updated or deleted. +** This may appear to have some counter-intuitive effects if a single row +** is written to more than once during a session. For example, if a row +** is inserted while a session object is enabled, then later deleted while +** the same session object is disabled, no INSERT record will appear in the +** changeset, even though the delete took place while the session was disabled. +** Or, if one field of a row is updated while a session is enabled, and +** then another field of the same row is updated while the session is disabled, +** the resulting changeset will contain an UPDATE change that updates both +** fields. +*/ +SQLITE_API int sqlite3session_changeset( + sqlite3_session *pSession, /* Session object */ + int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */ + void **ppChangeset /* OUT: Buffer containing changeset */ +); + +/* +** CAPI3REF: Return An Upper-limit For The Size Of The Changeset +** METHOD: sqlite3_session +** +** By default, this function always returns 0. For it to return +** a useful result, the sqlite3_session object must have been configured +** to enable this API using sqlite3session_object_config() with the +** SQLITE_SESSION_OBJCONFIG_SIZE verb. +** +** When enabled, this function returns an upper limit, in bytes, for the size +** of the changeset that might be produced if sqlite3session_changeset() were +** called. The final changeset size might be equal to or smaller than the +** size in bytes returned by this function. +*/ +SQLITE_API sqlite3_int64 sqlite3session_changeset_size(sqlite3_session *pSession); + +/* +** CAPI3REF: Load The Difference Between Tables Into A Session +** METHOD: sqlite3_session +** +** If it is not already attached to the session object passed as the first +** argument, this function attaches table zTbl in the same manner as the +** [sqlite3session_attach()] function. If zTbl does not exist, or if it +** does not have a primary key, this function is a no-op (but does not return +** an error). +** +** Argument zFromDb must be the name of a database ("main", "temp" etc.) +** attached to the same database handle as the session object that contains +** a table compatible with the table attached to the session by this function. +** A table is considered compatible if it: +** +**
      +**
    • Has the same name, +**
    • Has the same set of columns declared in the same order, and +**
    • Has the same PRIMARY KEY definition. +**
    +** +** If the tables are not compatible, SQLITE_SCHEMA is returned. If the tables +** are compatible but do not have any PRIMARY KEY columns, it is not an error +** but no changes are added to the session object. As with other session +** APIs, tables without PRIMARY KEYs are simply ignored. +** +** This function adds a set of changes to the session object that could be +** used to update the table in database zFrom (call this the "from-table") +** so that its content is the same as the table attached to the session +** object (call this the "to-table"). Specifically: +** +**
      +**
    • For each row (primary key) that exists in the to-table but not in +** the from-table, an INSERT record is added to the session object. +** +**
    • For each row (primary key) that exists in the to-table but not in +** the from-table, a DELETE record is added to the session object. +** +**
    • For each row (primary key) that exists in both tables, but features +** different non-PK values in each, an UPDATE record is added to the +** session. +**
    +** +** To clarify, if this function is called and then a changeset constructed +** using [sqlite3session_changeset()], then after applying that changeset to +** database zFrom the contents of the two compatible tables would be +** identical. +** +** Unless the call to this function is a no-op as described above, it is an +** error if database zFrom does not exist or does not contain the required +** compatible table. +** +** If the operation is successful, SQLITE_OK is returned. Otherwise, an SQLite +** error code. In this case, if argument pzErrMsg is not NULL, *pzErrMsg +** may be set to point to a buffer containing an English language error +** message. It is the responsibility of the caller to free this buffer using +** sqlite3_free(). +*/ +SQLITE_API int sqlite3session_diff( + sqlite3_session *pSession, + const char *zFromDb, + const char *zTbl, + char **pzErrMsg +); + + +/* +** CAPI3REF: Generate A Patchset From A Session Object +** METHOD: sqlite3_session +** +** The differences between a patchset and a changeset are that: +** +**
      +**
    • DELETE records consist of the primary key fields only. The +** original values of other fields are omitted. +**
    • The original values of any modified fields are omitted from +** UPDATE records. +**
    +** +** A patchset blob may be used with up to date versions of all +** sqlite3changeset_xxx API functions except for sqlite3changeset_invert(), +** which returns SQLITE_CORRUPT if it is passed a patchset. Similarly, +** attempting to use a patchset blob with old versions of the +** sqlite3changeset_xxx APIs also provokes an SQLITE_CORRUPT error. +** +** Because the non-primary key "old.*" fields are omitted, no +** SQLITE_CHANGESET_DATA conflicts can be detected or reported if a patchset +** is passed to the sqlite3changeset_apply() API. Other conflict types work +** in the same way as for changesets. +** +** Changes within a patchset are ordered in the same way as for changesets +** generated by the sqlite3session_changeset() function (i.e. all changes for +** a single table are grouped together, tables appear in the order in which +** they were attached to the session object). +*/ +SQLITE_API int sqlite3session_patchset( + sqlite3_session *pSession, /* Session object */ + int *pnPatchset, /* OUT: Size of buffer at *ppPatchset */ + void **ppPatchset /* OUT: Buffer containing patchset */ +); + +/* +** CAPI3REF: Test if a changeset has recorded any changes. +** +** Return non-zero if no changes to attached tables have been recorded by +** the session object passed as the first argument. Otherwise, if one or +** more changes have been recorded, return zero. +** +** Even if this function returns zero, it is possible that calling +** [sqlite3session_changeset()] on the session handle may still return a +** changeset that contains no changes. This can happen when a row in +** an attached table is modified and then later on the original values +** are restored. However, if this function returns non-zero, then it is +** guaranteed that a call to sqlite3session_changeset() will return a +** changeset containing zero changes. +*/ +SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession); + +/* +** CAPI3REF: Query for the amount of heap memory used by a session object. +** +** This API returns the total amount of heap memory in bytes currently +** used by the session object passed as the only argument. +*/ +SQLITE_API sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession); + +/* +** CAPI3REF: Create An Iterator To Traverse A Changeset +** CONSTRUCTOR: sqlite3_changeset_iter +** +** Create an iterator used to iterate through the contents of a changeset. +** If successful, *pp is set to point to the iterator handle and SQLITE_OK +** is returned. Otherwise, if an error occurs, *pp is set to zero and an +** SQLite error code is returned. +** +** The following functions can be used to advance and query a changeset +** iterator created by this function: +** +**
      +**
    • [sqlite3changeset_next()] +**
    • [sqlite3changeset_op()] +**
    • [sqlite3changeset_new()] +**
    • [sqlite3changeset_old()] +**
    +** +** It is the responsibility of the caller to eventually destroy the iterator +** by passing it to [sqlite3changeset_finalize()]. The buffer containing the +** changeset (pChangeset) must remain valid until after the iterator is +** destroyed. +** +** Assuming the changeset blob was created by one of the +** [sqlite3session_changeset()], [sqlite3changeset_concat()] or +** [sqlite3changeset_invert()] functions, all changes within the changeset +** that apply to a single table are grouped together. This means that when +** an application iterates through a changeset using an iterator created by +** this function, all changes that relate to a single table are visited +** consecutively. There is no chance that the iterator will visit a change +** the applies to table X, then one for table Y, and then later on visit +** another change for table X. +** +** The behavior of sqlite3changeset_start_v2() and its streaming equivalent +** may be modified by passing a combination of +** [SQLITE_CHANGESETSTART_INVERT | supported flags] as the 4th parameter. +** +** Note that the sqlite3changeset_start_v2() API is still experimental +** and therefore subject to change. +*/ +SQLITE_API int sqlite3changeset_start( + sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */ + int nChangeset, /* Size of changeset blob in bytes */ + void *pChangeset /* Pointer to blob containing changeset */ +); +SQLITE_API int sqlite3changeset_start_v2( + sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */ + int nChangeset, /* Size of changeset blob in bytes */ + void *pChangeset, /* Pointer to blob containing changeset */ + int flags /* SESSION_CHANGESETSTART_* flags */ +); + +/* +** CAPI3REF: Flags for sqlite3changeset_start_v2 +** +** The following flags may passed via the 4th parameter to +** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]: +** +**
    SQLITE_CHANGESETSTART_INVERT
    +** Invert the changeset while iterating through it. This is equivalent to +** inverting a changeset using sqlite3changeset_invert() before applying it. +** It is an error to specify this flag with a patchset. +*/ +#define SQLITE_CHANGESETSTART_INVERT 0x0002 + + +/* +** CAPI3REF: Advance A Changeset Iterator +** METHOD: sqlite3_changeset_iter +** +** This function may only be used with iterators created by the function +** [sqlite3changeset_start()]. If it is called on an iterator passed to +** a conflict-handler callback by [sqlite3changeset_apply()], SQLITE_MISUSE +** is returned and the call has no effect. +** +** Immediately after an iterator is created by sqlite3changeset_start(), it +** does not point to any change in the changeset. Assuming the changeset +** is not empty, the first call to this function advances the iterator to +** point to the first change in the changeset. Each subsequent call advances +** the iterator to point to the next change in the changeset (if any). If +** no error occurs and the iterator points to a valid change after a call +** to sqlite3changeset_next() has advanced it, SQLITE_ROW is returned. +** Otherwise, if all changes in the changeset have already been visited, +** SQLITE_DONE is returned. +** +** If an error occurs, an SQLite error code is returned. Possible error +** codes include SQLITE_CORRUPT (if the changeset buffer is corrupt) or +** SQLITE_NOMEM. +*/ +SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter); + +/* +** CAPI3REF: Obtain The Current Operation From A Changeset Iterator +** METHOD: sqlite3_changeset_iter +** +** The pIter argument passed to this function may either be an iterator +** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator +** created by [sqlite3changeset_start()]. In the latter case, the most recent +** call to [sqlite3changeset_next()] must have returned [SQLITE_ROW]. If this +** is not the case, this function returns [SQLITE_MISUSE]. +** +** Arguments pOp, pnCol and pzTab may not be NULL. Upon return, three +** outputs are set through these pointers: +** +** *pOp is set to one of [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE], +** depending on the type of change that the iterator currently points to; +** +** *pnCol is set to the number of columns in the table affected by the change; and +** +** *pzTab is set to point to a nul-terminated utf-8 encoded string containing +** the name of the table affected by the current change. The buffer remains +** valid until either sqlite3changeset_next() is called on the iterator +** or until the conflict-handler function returns. +** +** If pbIndirect is not NULL, then *pbIndirect is set to true (1) if the change +** is an indirect change, or false (0) otherwise. See the documentation for +** [sqlite3session_indirect()] for a description of direct and indirect +** changes. +** +** If no error occurs, SQLITE_OK is returned. If an error does occur, an +** SQLite error code is returned. The values of the output variables may not +** be trusted in this case. +*/ +SQLITE_API int sqlite3changeset_op( + sqlite3_changeset_iter *pIter, /* Iterator object */ + const char **pzTab, /* OUT: Pointer to table name */ + int *pnCol, /* OUT: Number of columns in table */ + int *pOp, /* OUT: SQLITE_INSERT, DELETE or UPDATE */ + int *pbIndirect /* OUT: True for an 'indirect' change */ +); + +/* +** CAPI3REF: Obtain The Primary Key Definition Of A Table +** METHOD: sqlite3_changeset_iter +** +** For each modified table, a changeset includes the following: +** +**
      +**
    • The number of columns in the table, and +**
    • Which of those columns make up the tables PRIMARY KEY. +**
    +** +** This function is used to find which columns comprise the PRIMARY KEY of +** the table modified by the change that iterator pIter currently points to. +** If successful, *pabPK is set to point to an array of nCol entries, where +** nCol is the number of columns in the table. Elements of *pabPK are set to +** 0x01 if the corresponding column is part of the tables primary key, or +** 0x00 if it is not. +** +** If argument pnCol is not NULL, then *pnCol is set to the number of columns +** in the table. +** +** If this function is called when the iterator does not point to a valid +** entry, SQLITE_MISUSE is returned and the output variables zeroed. Otherwise, +** SQLITE_OK is returned and the output variables populated as described +** above. +*/ +SQLITE_API int sqlite3changeset_pk( + sqlite3_changeset_iter *pIter, /* Iterator object */ + unsigned char **pabPK, /* OUT: Array of boolean - true for PK cols */ + int *pnCol /* OUT: Number of entries in output array */ +); + +/* +** CAPI3REF: Obtain old.* Values From A Changeset Iterator +** METHOD: sqlite3_changeset_iter +** +** The pIter argument passed to this function may either be an iterator +** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator +** created by [sqlite3changeset_start()]. In the latter case, the most recent +** call to [sqlite3changeset_next()] must have returned SQLITE_ROW. +** Furthermore, it may only be called if the type of change that the iterator +** currently points to is either [SQLITE_DELETE] or [SQLITE_UPDATE]. Otherwise, +** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL. +** +** Argument iVal must be greater than or equal to 0, and less than the number +** of columns in the table affected by the current change. Otherwise, +** [SQLITE_RANGE] is returned and *ppValue is set to NULL. +** +** If successful, this function sets *ppValue to point to a protected +** sqlite3_value object containing the iVal'th value from the vector of +** original row values stored as part of the UPDATE or DELETE change and +** returns SQLITE_OK. The name of the function comes from the fact that this +** is similar to the "old.*" columns available to update or delete triggers. +** +** If some other error occurs (e.g. an OOM condition), an SQLite error code +** is returned and *ppValue is set to NULL. +*/ +SQLITE_API int sqlite3changeset_old( + sqlite3_changeset_iter *pIter, /* Changeset iterator */ + int iVal, /* Column number */ + sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */ +); + +/* +** CAPI3REF: Obtain new.* Values From A Changeset Iterator +** METHOD: sqlite3_changeset_iter +** +** The pIter argument passed to this function may either be an iterator +** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator +** created by [sqlite3changeset_start()]. In the latter case, the most recent +** call to [sqlite3changeset_next()] must have returned SQLITE_ROW. +** Furthermore, it may only be called if the type of change that the iterator +** currently points to is either [SQLITE_UPDATE] or [SQLITE_INSERT]. Otherwise, +** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL. +** +** Argument iVal must be greater than or equal to 0, and less than the number +** of columns in the table affected by the current change. Otherwise, +** [SQLITE_RANGE] is returned and *ppValue is set to NULL. +** +** If successful, this function sets *ppValue to point to a protected +** sqlite3_value object containing the iVal'th value from the vector of +** new row values stored as part of the UPDATE or INSERT change and +** returns SQLITE_OK. If the change is an UPDATE and does not include +** a new value for the requested column, *ppValue is set to NULL and +** SQLITE_OK returned. The name of the function comes from the fact that +** this is similar to the "new.*" columns available to update or delete +** triggers. +** +** If some other error occurs (e.g. an OOM condition), an SQLite error code +** is returned and *ppValue is set to NULL. +*/ +SQLITE_API int sqlite3changeset_new( + sqlite3_changeset_iter *pIter, /* Changeset iterator */ + int iVal, /* Column number */ + sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */ +); + +/* +** CAPI3REF: Obtain Conflicting Row Values From A Changeset Iterator +** METHOD: sqlite3_changeset_iter +** +** This function should only be used with iterator objects passed to a +** conflict-handler callback by [sqlite3changeset_apply()] with either +** [SQLITE_CHANGESET_DATA] or [SQLITE_CHANGESET_CONFLICT]. If this function +** is called on any other iterator, [SQLITE_MISUSE] is returned and *ppValue +** is set to NULL. +** +** Argument iVal must be greater than or equal to 0, and less than the number +** of columns in the table affected by the current change. Otherwise, +** [SQLITE_RANGE] is returned and *ppValue is set to NULL. +** +** If successful, this function sets *ppValue to point to a protected +** sqlite3_value object containing the iVal'th value from the +** "conflicting row" associated with the current conflict-handler callback +** and returns SQLITE_OK. +** +** If some other error occurs (e.g. an OOM condition), an SQLite error code +** is returned and *ppValue is set to NULL. +*/ +SQLITE_API int sqlite3changeset_conflict( + sqlite3_changeset_iter *pIter, /* Changeset iterator */ + int iVal, /* Column number */ + sqlite3_value **ppValue /* OUT: Value from conflicting row */ +); + +/* +** CAPI3REF: Determine The Number Of Foreign Key Constraint Violations +** METHOD: sqlite3_changeset_iter +** +** This function may only be called with an iterator passed to an +** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case +** it sets the output variable to the total number of known foreign key +** violations in the destination database and returns SQLITE_OK. +** +** In all other cases this function returns SQLITE_MISUSE. +*/ +SQLITE_API int sqlite3changeset_fk_conflicts( + sqlite3_changeset_iter *pIter, /* Changeset iterator */ + int *pnOut /* OUT: Number of FK violations */ +); + + +/* +** CAPI3REF: Finalize A Changeset Iterator +** METHOD: sqlite3_changeset_iter +** +** This function is used to finalize an iterator allocated with +** [sqlite3changeset_start()]. +** +** This function should only be called on iterators created using the +** [sqlite3changeset_start()] function. If an application calls this +** function with an iterator passed to a conflict-handler by +** [sqlite3changeset_apply()], [SQLITE_MISUSE] is immediately returned and the +** call has no effect. +** +** If an error was encountered within a call to an sqlite3changeset_xxx() +** function (for example an [SQLITE_CORRUPT] in [sqlite3changeset_next()] or an +** [SQLITE_NOMEM] in [sqlite3changeset_new()]) then an error code corresponding +** to that error is returned by this function. Otherwise, SQLITE_OK is +** returned. This is to allow the following pattern (pseudo-code): +** +**
    +**   sqlite3changeset_start();
    +**   while( SQLITE_ROW==sqlite3changeset_next() ){
    +**     // Do something with change.
    +**   }
    +**   rc = sqlite3changeset_finalize();
    +**   if( rc!=SQLITE_OK ){
    +**     // An error has occurred
    +**   }
    +** 
    +*/ +SQLITE_API int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter); + +/* +** CAPI3REF: Invert A Changeset +** +** This function is used to "invert" a changeset object. Applying an inverted +** changeset to a database reverses the effects of applying the uninverted +** changeset. Specifically: +** +**
      +**
    • Each DELETE change is changed to an INSERT, and +**
    • Each INSERT change is changed to a DELETE, and +**
    • For each UPDATE change, the old.* and new.* values are exchanged. +**
    +** +** This function does not change the order in which changes appear within +** the changeset. It merely reverses the sense of each individual change. +** +** If successful, a pointer to a buffer containing the inverted changeset +** is stored in *ppOut, the size of the same buffer is stored in *pnOut, and +** SQLITE_OK is returned. If an error occurs, both *pnOut and *ppOut are +** zeroed and an SQLite error code returned. +** +** It is the responsibility of the caller to eventually call sqlite3_free() +** on the *ppOut pointer to free the buffer allocation following a successful +** call to this function. +** +** WARNING/TODO: This function currently assumes that the input is a valid +** changeset. If it is not, the results are undefined. +*/ +SQLITE_API int sqlite3changeset_invert( + int nIn, const void *pIn, /* Input changeset */ + int *pnOut, void **ppOut /* OUT: Inverse of input */ +); + +/* +** CAPI3REF: Concatenate Two Changeset Objects +** +** This function is used to concatenate two changesets, A and B, into a +** single changeset. The result is a changeset equivalent to applying +** changeset A followed by changeset B. +** +** This function combines the two input changesets using an +** sqlite3_changegroup object. Calling it produces similar results as the +** following code fragment: +** +**
    +**   sqlite3_changegroup *pGrp;
    +**   rc = sqlite3_changegroup_new(&pGrp);
    +**   if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nA, pA);
    +**   if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nB, pB);
    +**   if( rc==SQLITE_OK ){
    +**     rc = sqlite3changegroup_output(pGrp, pnOut, ppOut);
    +**   }else{
    +**     *ppOut = 0;
    +**     *pnOut = 0;
    +**   }
    +** 
    +** +** Refer to the sqlite3_changegroup documentation below for details. +*/ +SQLITE_API int sqlite3changeset_concat( + int nA, /* Number of bytes in buffer pA */ + void *pA, /* Pointer to buffer containing changeset A */ + int nB, /* Number of bytes in buffer pB */ + void *pB, /* Pointer to buffer containing changeset B */ + int *pnOut, /* OUT: Number of bytes in output changeset */ + void **ppOut /* OUT: Buffer containing output changeset */ +); + +/* +** CAPI3REF: Changegroup Handle +** +** A changegroup is an object used to combine two or more +** [changesets] or [patchsets] +*/ +typedef struct sqlite3_changegroup sqlite3_changegroup; + +/* +** CAPI3REF: Create A New Changegroup Object +** CONSTRUCTOR: sqlite3_changegroup +** +** An sqlite3_changegroup object is used to combine two or more changesets +** (or patchsets) into a single changeset (or patchset). A single changegroup +** object may combine changesets or patchsets, but not both. The output is +** always in the same format as the input. +** +** If successful, this function returns SQLITE_OK and populates (*pp) with +** a pointer to a new sqlite3_changegroup object before returning. The caller +** should eventually free the returned object using a call to +** sqlite3changegroup_delete(). If an error occurs, an SQLite error code +** (i.e. SQLITE_NOMEM) is returned and *pp is set to NULL. +** +** The usual usage pattern for an sqlite3_changegroup object is as follows: +** +**
      +**
    • It is created using a call to sqlite3changegroup_new(). +** +**
    • Zero or more changesets (or patchsets) are added to the object +** by calling sqlite3changegroup_add(). +** +**
    • The result of combining all input changesets together is obtained +** by the application via a call to sqlite3changegroup_output(). +** +**
    • The object is deleted using a call to sqlite3changegroup_delete(). +**
    +** +** Any number of calls to add() and output() may be made between the calls to +** new() and delete(), and in any order. +** +** As well as the regular sqlite3changegroup_add() and +** sqlite3changegroup_output() functions, also available are the streaming +** versions sqlite3changegroup_add_strm() and sqlite3changegroup_output_strm(). +*/ +SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp); + +/* +** CAPI3REF: Add a Schema to a Changegroup +** METHOD: sqlite3_changegroup_schema +** +** This method may be used to optionally enforce the rule that the changesets +** added to the changegroup handle must match the schema of database zDb +** ("main", "temp", or the name of an attached database). If +** sqlite3changegroup_add() is called to add a changeset that is not compatible +** with the configured schema, SQLITE_SCHEMA is returned and the changegroup +** object is left in an undefined state. +** +** A changeset schema is considered compatible with the database schema in +** the same way as for sqlite3changeset_apply(). Specifically, for each +** table in the changeset, there exists a database table with: +** +**
      +**
    • The name identified by the changeset, and +**
    • at least as many columns as recorded in the changeset, and +**
    • the primary key columns in the same position as recorded in +** the changeset. +**
    +** +** The output of the changegroup object always has the same schema as the +** database nominated using this function. In cases where changesets passed +** to sqlite3changegroup_add() have fewer columns than the corresponding table +** in the database schema, these are filled in using the default column +** values from the database schema. This makes it possible to combined +** changesets that have different numbers of columns for a single table +** within a changegroup, provided that they are otherwise compatible. +*/ +SQLITE_API int sqlite3changegroup_schema(sqlite3_changegroup*, sqlite3*, const char *zDb); + +/* +** CAPI3REF: Add A Changeset To A Changegroup +** METHOD: sqlite3_changegroup +** +** Add all changes within the changeset (or patchset) in buffer pData (size +** nData bytes) to the changegroup. +** +** If the buffer contains a patchset, then all prior calls to this function +** on the same changegroup object must also have specified patchsets. Or, if +** the buffer contains a changeset, so must have the earlier calls to this +** function. Otherwise, SQLITE_ERROR is returned and no changes are added +** to the changegroup. +** +** Rows within the changeset and changegroup are identified by the values in +** their PRIMARY KEY columns. A change in the changeset is considered to +** apply to the same row as a change already present in the changegroup if +** the two rows have the same primary key. +** +** Changes to rows that do not already appear in the changegroup are +** simply copied into it. Or, if both the new changeset and the changegroup +** contain changes that apply to a single row, the final contents of the +** changegroup depends on the type of each change, as follows: +** +** +** +** +**
    Existing Change New Change Output Change +**
    INSERT INSERT +** The new change is ignored. This case does not occur if the new +** changeset was recorded immediately after the changesets already +** added to the changegroup. +**
    INSERT UPDATE +** The INSERT change remains in the changegroup. The values in the +** INSERT change are modified as if the row was inserted by the +** existing change and then updated according to the new change. +**
    INSERT DELETE +** The existing INSERT is removed from the changegroup. The DELETE is +** not added. +**
    UPDATE INSERT +** The new change is ignored. This case does not occur if the new +** changeset was recorded immediately after the changesets already +** added to the changegroup. +**
    UPDATE UPDATE +** The existing UPDATE remains within the changegroup. It is amended +** so that the accompanying values are as if the row was updated once +** by the existing change and then again by the new change. +**
    UPDATE DELETE +** The existing UPDATE is replaced by the new DELETE within the +** changegroup. +**
    DELETE INSERT +** If one or more of the column values in the row inserted by the +** new change differ from those in the row deleted by the existing +** change, the existing DELETE is replaced by an UPDATE within the +** changegroup. Otherwise, if the inserted row is exactly the same +** as the deleted row, the existing DELETE is simply discarded. +**
    DELETE UPDATE +** The new change is ignored. This case does not occur if the new +** changeset was recorded immediately after the changesets already +** added to the changegroup. +**
    DELETE DELETE +** The new change is ignored. This case does not occur if the new +** changeset was recorded immediately after the changesets already +** added to the changegroup. +**
    +** +** If the new changeset contains changes to a table that is already present +** in the changegroup, then the number of columns and the position of the +** primary key columns for the table must be consistent. If this is not the +** case, this function fails with SQLITE_SCHEMA. Except, if the changegroup +** object has been configured with a database schema using the +** sqlite3changegroup_schema() API, then it is possible to combine changesets +** with different numbers of columns for a single table, provided that +** they are otherwise compatible. +** +** If the input changeset appears to be corrupt and the corruption is +** detected, SQLITE_CORRUPT is returned. Or, if an out-of-memory condition +** occurs during processing, this function returns SQLITE_NOMEM. +** +** In all cases, if an error occurs the state of the final contents of the +** changegroup is undefined. If no error occurs, SQLITE_OK is returned. +*/ +SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); + +/* +** CAPI3REF: Add A Single Change To A Changegroup +** METHOD: sqlite3_changegroup +** +** This function adds the single change currently indicated by the iterator +** passed as the second argument to the changegroup object. The rules for +** adding the change are just as described for [sqlite3changegroup_add()]. +** +** If the change is successfully added to the changegroup, SQLITE_OK is +** returned. Otherwise, an SQLite error code is returned. +** +** The iterator must point to a valid entry when this function is called. +** If it does not, SQLITE_ERROR is returned and no change is added to the +** changegroup. Additionally, the iterator must not have been opened with +** the SQLITE_CHANGESETAPPLY_INVERT flag. In this case SQLITE_ERROR is also +** returned. +*/ +SQLITE_API int sqlite3changegroup_add_change( + sqlite3_changegroup*, + sqlite3_changeset_iter* +); + + + +/* +** CAPI3REF: Obtain A Composite Changeset From A Changegroup +** METHOD: sqlite3_changegroup +** +** Obtain a buffer containing a changeset (or patchset) representing the +** current contents of the changegroup. If the inputs to the changegroup +** were themselves changesets, the output is a changeset. Or, if the +** inputs were patchsets, the output is also a patchset. +** +** As with the output of the sqlite3session_changeset() and +** sqlite3session_patchset() functions, all changes related to a single +** table are grouped together in the output of this function. Tables appear +** in the same order as for the very first changeset added to the changegroup. +** If the second or subsequent changesets added to the changegroup contain +** changes for tables that do not appear in the first changeset, they are +** appended onto the end of the output changeset, again in the order in +** which they are first encountered. +** +** If an error occurs, an SQLite error code is returned and the output +** variables (*pnData) and (*ppData) are set to 0. Otherwise, SQLITE_OK +** is returned and the output variables are set to the size of and a +** pointer to the output buffer, respectively. In this case it is the +** responsibility of the caller to eventually free the buffer using a +** call to sqlite3_free(). +*/ +SQLITE_API int sqlite3changegroup_output( + sqlite3_changegroup*, + int *pnData, /* OUT: Size of output buffer in bytes */ + void **ppData /* OUT: Pointer to output buffer */ +); + +/* +** CAPI3REF: Delete A Changegroup Object +** DESTRUCTOR: sqlite3_changegroup +*/ +SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*); + +/* +** CAPI3REF: Apply A Changeset To A Database +** +** Apply a changeset or patchset to a database. These functions attempt to +** update the "main" database attached to handle db with the changes found in +** the changeset passed via the second and third arguments. +** +** All changes made by these functions are enclosed in a savepoint transaction. +** If any other error (aside from a constraint failure when attempting to +** write to the target database) occurs, then the savepoint transaction is +** rolled back, restoring the target database to its original state, and an +** SQLite error code returned. Additionally, starting with version 3.51.0, +** an error code and error message that may be accessed using the +** [sqlite3_errcode()] and [sqlite3_errmsg()] APIs are left in the database +** handle. +** +** The fourth argument (xFilter) passed to these functions is the "filter +** callback". This may be passed NULL, in which case all changes in the +** changeset are applied to the database. For sqlite3changeset_apply() and +** sqlite3_changeset_apply_v2(), if it is not NULL, then it is invoked once +** for each table affected by at least one change in the changeset. In this +** case the table name is passed as the second argument, and a copy of +** the context pointer passed as the sixth argument to apply() or apply_v2() +** as the first. If the "filter callback" returns zero, then no attempt is +** made to apply any changes to the table. Otherwise, if the return value is +** non-zero, all changes related to the table are attempted. +** +** For sqlite3_changeset_apply_v3(), the xFilter callback is invoked once +** per change. The second argument in this case is an sqlite3_changeset_iter +** that may be queried using the usual APIs for the details of the current +** change. If the "filter callback" returns zero in this case, then no attempt +** is made to apply the current change. If it returns non-zero, the change +** is applied. +** +** For each table that is not excluded by the filter callback, this function +** tests that the target database contains a compatible table. A table is +** considered compatible if all of the following are true: +** +**
      +**
    • The table has the same name as the name recorded in the +** changeset, and +**
    • The table has at least as many columns as recorded in the +** changeset, and +**
    • The table has primary key columns in the same position as +** recorded in the changeset. +**
    +** +** If there is no compatible table, it is not an error, but none of the +** changes associated with the table are applied. A warning message is issued +** via the sqlite3_log() mechanism with the error code SQLITE_SCHEMA. At most +** one such warning is issued for each table in the changeset. +** +** For each change for which there is a compatible table, an attempt is made +** to modify the table contents according to each UPDATE, INSERT or DELETE +** change that is not excluded by a filter callback. If a change cannot be +** applied cleanly, the conflict handler function passed as the fifth argument +** to sqlite3changeset_apply() may be invoked. A description of exactly when +** the conflict handler is invoked for each type of change is below. +** +** Unlike the xFilter argument, xConflict may not be passed NULL. The results +** of passing anything other than a valid function pointer as the xConflict +** argument are undefined. +** +** Each time the conflict handler function is invoked, it must return one +** of [SQLITE_CHANGESET_OMIT], [SQLITE_CHANGESET_ABORT] or +** [SQLITE_CHANGESET_REPLACE]. SQLITE_CHANGESET_REPLACE may only be returned +** if the second argument passed to the conflict handler is either +** SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If the conflict-handler +** returns an illegal value, any changes already made are rolled back and +** the call to sqlite3changeset_apply() returns SQLITE_MISUSE. Different +** actions are taken by sqlite3changeset_apply() depending on the value +** returned by each invocation of the conflict-handler function. Refer to +** the documentation for the three +** [SQLITE_CHANGESET_OMIT|available return values] for details. +** +**
    +**
    DELETE Changes
    +** For each DELETE change, the function checks if the target database +** contains a row with the same primary key value (or values) as the +** original row values stored in the changeset. If it does, and the values +** stored in all non-primary key columns also match the values stored in +** the changeset the row is deleted from the target database. +** +** If a row with matching primary key values is found, but one or more of +** the non-primary key fields contains a value different from the original +** row value stored in the changeset, the conflict-handler function is +** invoked with [SQLITE_CHANGESET_DATA] as the second argument. If the +** database table has more columns than are recorded in the changeset, +** only the values of those non-primary key fields are compared against +** the current database contents - any trailing database table columns +** are ignored. +** +** If no row with matching primary key values is found in the database, +** the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND] +** passed as the second argument. +** +** If the DELETE operation is attempted, but SQLite returns SQLITE_CONSTRAINT +** (which can only happen if a foreign key constraint is violated), the +** conflict-handler function is invoked with [SQLITE_CHANGESET_CONSTRAINT] +** passed as the second argument. This includes the case where the DELETE +** operation is attempted because an earlier call to the conflict handler +** function returned [SQLITE_CHANGESET_REPLACE]. +** +**
    INSERT Changes
    +** For each INSERT change, an attempt is made to insert the new row into +** the database. If the changeset row contains fewer fields than the +** database table, the trailing fields are populated with their default +** values. +** +** If the attempt to insert the row fails because the database already +** contains a row with the same primary key values, the conflict handler +** function is invoked with the second argument set to +** [SQLITE_CHANGESET_CONFLICT]. +** +** If the attempt to insert the row fails because of some other constraint +** violation (e.g. NOT NULL or UNIQUE), the conflict handler function is +** invoked with the second argument set to [SQLITE_CHANGESET_CONSTRAINT]. +** This includes the case where the INSERT operation is re-attempted because +** an earlier call to the conflict handler function returned +** [SQLITE_CHANGESET_REPLACE]. +** +**
    UPDATE Changes
    +** For each UPDATE change, the function checks if the target database +** contains a row with the same primary key value (or values) as the +** original row values stored in the changeset. If it does, and the values +** stored in all modified non-primary key columns also match the values +** stored in the changeset the row is updated within the target database. +** +** If a row with matching primary key values is found, but one or more of +** the modified non-primary key fields contains a value different from an +** original row value stored in the changeset, the conflict-handler function +** is invoked with [SQLITE_CHANGESET_DATA] as the second argument. Since +** UPDATE changes only contain values for non-primary key fields that are +** to be modified, only those fields need to match the original values to +** avoid the SQLITE_CHANGESET_DATA conflict-handler callback. +** +** If no row with matching primary key values is found in the database, +** the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND] +** passed as the second argument. +** +** If the UPDATE operation is attempted, but SQLite returns +** SQLITE_CONSTRAINT, the conflict-handler function is invoked with +** [SQLITE_CHANGESET_CONSTRAINT] passed as the second argument. +** This includes the case where the UPDATE operation is attempted after +** an earlier call to the conflict handler function returned +** [SQLITE_CHANGESET_REPLACE]. +**
    +** +** It is safe to execute SQL statements, including those that write to the +** table that the callback related to, from within the xConflict callback. +** This can be used to further customize the application's conflict +** resolution strategy. +** +** If the output parameters (ppRebase) and (pnRebase) are non-NULL and +** the input is a changeset (not a patchset), then sqlite3changeset_apply_v2() +** may set (*ppRebase) to point to a "rebase" that may be used with the +** sqlite3_rebaser APIs buffer before returning. In this case (*pnRebase) +** is set to the size of the buffer in bytes. It is the responsibility of the +** caller to eventually free any such buffer using sqlite3_free(). The buffer +** is only allocated and populated if one or more conflicts were encountered +** while applying the patchset. See comments surrounding the sqlite3_rebaser +** APIs for further details. +** +** The behavior of sqlite3changeset_apply_v2() and its streaming equivalent +** may be modified by passing a combination of +** [SQLITE_CHANGESETAPPLY_NOSAVEPOINT | supported flags] as the 9th parameter. +** +** Note that the sqlite3changeset_apply_v2() API is still experimental +** and therefore subject to change. +*/ +SQLITE_API int sqlite3changeset_apply( + sqlite3 *db, /* Apply change to "main" db of this handle */ + int nChangeset, /* Size of changeset in bytes */ + void *pChangeset, /* Changeset blob */ + int(*xFilter)( + void *pCtx, /* Copy of sixth arg to _apply() */ + const char *zTab /* Table name */ + ), + int(*xConflict)( + void *pCtx, /* Copy of sixth arg to _apply() */ + int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ + ), + void *pCtx /* First argument passed to xConflict */ +); +SQLITE_API int sqlite3changeset_apply_v2( + sqlite3 *db, /* Apply change to "main" db of this handle */ + int nChangeset, /* Size of changeset in bytes */ + void *pChangeset, /* Changeset blob */ + int(*xFilter)( + void *pCtx, /* Copy of sixth arg to _apply() */ + const char *zTab /* Table name */ + ), + int(*xConflict)( + void *pCtx, /* Copy of sixth arg to _apply() */ + int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ + ), + void *pCtx, /* First argument passed to xConflict */ + void **ppRebase, int *pnRebase, /* OUT: Rebase data */ + int flags /* SESSION_CHANGESETAPPLY_* flags */ +); +SQLITE_API int sqlite3changeset_apply_v3( + sqlite3 *db, /* Apply change to "main" db of this handle */ + int nChangeset, /* Size of changeset in bytes */ + void *pChangeset, /* Changeset blob */ + int(*xFilter)( + void *pCtx, /* Copy of sixth arg to _apply() */ + sqlite3_changeset_iter *p /* Handle describing change */ + ), + int(*xConflict)( + void *pCtx, /* Copy of sixth arg to _apply() */ + int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ + ), + void *pCtx, /* First argument passed to xConflict */ + void **ppRebase, int *pnRebase, /* OUT: Rebase data */ + int flags /* SESSION_CHANGESETAPPLY_* flags */ +); + +/* +** CAPI3REF: Flags for sqlite3changeset_apply_v2 +** +** The following flags may passed via the 9th parameter to +** [sqlite3changeset_apply_v2] and [sqlite3changeset_apply_v2_strm]: +** +**
    +**
    SQLITE_CHANGESETAPPLY_NOSAVEPOINT
    +** Usually, the sessions module encloses all operations performed by +** a single call to apply_v2() or apply_v2_strm() in a [SAVEPOINT]. The +** SAVEPOINT is committed if the changeset or patchset is successfully +** applied, or rolled back if an error occurs. Specifying this flag +** causes the sessions module to omit this savepoint. In this case, if the +** caller has an open transaction or savepoint when apply_v2() is called, +** it may revert the partially applied changeset by rolling it back. +** +**
    SQLITE_CHANGESETAPPLY_INVERT
    +** Invert the changeset before applying it. This is equivalent to inverting +** a changeset using sqlite3changeset_invert() before applying it. It is +** an error to specify this flag with a patchset. +** +**
    SQLITE_CHANGESETAPPLY_IGNORENOOP
    +** Do not invoke the conflict handler callback for any changes that +** would not actually modify the database even if they were applied. +** Specifically, this means that the conflict handler is not invoked +** for: +**
      +**
    • a delete change if the row being deleted cannot be found, +**
    • an update change if the modified fields are already set to +** their new values in the conflicting row, or +**
    • an insert change if all fields of the conflicting row match +** the row being inserted. +**
    +** +**
    SQLITE_CHANGESETAPPLY_FKNOACTION
    +** If this flag it set, then all foreign key constraints in the target +** database behave as if they were declared with "ON UPDATE NO ACTION ON +** DELETE NO ACTION", even if they are actually CASCADE, RESTRICT, SET NULL +** or SET DEFAULT. +** +**
    SQLITE_CHANGESETAPPLY_NOUPDATELOOP
    +** Sometimes, a changeset contains two or more update statements such that +** although after applying all updates the database will contain no +** constraint violations, no single update can be applied before the others. +** The simplest example of this is a pair of UPDATEs that have "swapped" +** two column values with a UNIQUE constraint. +**

    +** Usually, sqlite3changeset_apply() and similar functions work hard to try +** to find a way to apply such a changeset. However, if this flag is set, +** then all such updates are considered CONSTRAINT conflicts. +*/ +#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001 +#define SQLITE_CHANGESETAPPLY_INVERT 0x0002 +#define SQLITE_CHANGESETAPPLY_IGNORENOOP 0x0004 +#define SQLITE_CHANGESETAPPLY_FKNOACTION 0x0008 +#define SQLITE_CHANGESETAPPLY_NOUPDATELOOP 0x0010 + +/* +** CAPI3REF: Constants Passed To The Conflict Handler +** +** Values that may be passed as the second argument to a conflict-handler. +** +**

    +**
    SQLITE_CHANGESET_DATA
    +** The conflict handler is invoked with CHANGESET_DATA as the second argument +** when processing a DELETE or UPDATE change if a row with the required +** PRIMARY KEY fields is present in the database, but one or more other +** (non primary-key) fields modified by the update do not contain the +** expected "before" values. +** +** The conflicting row, in this case, is the database row with the matching +** primary key. +** +**
    SQLITE_CHANGESET_NOTFOUND
    +** The conflict handler is invoked with CHANGESET_NOTFOUND as the second +** argument when processing a DELETE or UPDATE change if a row with the +** required PRIMARY KEY fields is not present in the database. +** +** There is no conflicting row in this case. The results of invoking the +** sqlite3changeset_conflict() API are undefined. +** +**
    SQLITE_CHANGESET_CONFLICT
    +** CHANGESET_CONFLICT is passed as the second argument to the conflict +** handler while processing an INSERT change if the operation would result +** in duplicate primary key values. +** +** The conflicting row in this case is the database row with the matching +** primary key. +** +**
    SQLITE_CHANGESET_FOREIGN_KEY
    +** If foreign key handling is enabled, and applying a changeset leaves the +** database in a state containing foreign key violations, the conflict +** handler is invoked with CHANGESET_FOREIGN_KEY as the second argument +** exactly once before the changeset is committed. If the conflict handler +** returns CHANGESET_OMIT, the changes, including those that caused the +** foreign key constraint violation, are committed. Or, if it returns +** CHANGESET_ABORT, the changeset is rolled back. +** +** No current or conflicting row information is provided. The only function +** it is possible to call on the supplied sqlite3_changeset_iter handle +** is sqlite3changeset_fk_conflicts(). +** +**
    SQLITE_CHANGESET_CONSTRAINT
    +** If any other constraint violation occurs while applying a change (i.e. +** a UNIQUE, CHECK or NOT NULL constraint), the conflict handler is +** invoked with CHANGESET_CONSTRAINT as the second argument. +** +** There is no conflicting row in this case. The results of invoking the +** sqlite3changeset_conflict() API are undefined. +** +**
    +*/ +#define SQLITE_CHANGESET_DATA 1 +#define SQLITE_CHANGESET_NOTFOUND 2 +#define SQLITE_CHANGESET_CONFLICT 3 +#define SQLITE_CHANGESET_CONSTRAINT 4 +#define SQLITE_CHANGESET_FOREIGN_KEY 5 + +/* +** CAPI3REF: Constants Returned By The Conflict Handler +** +** A conflict handler callback must return one of the following three values. +** +**
    +**
    SQLITE_CHANGESET_OMIT
    +** If a conflict handler returns this value no special action is taken. The +** change that caused the conflict is not applied. The session module +** continues to the next change in the changeset. +** +**
    SQLITE_CHANGESET_REPLACE
    +** This value may only be returned if the second argument to the conflict +** handler was SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If this +** is not the case, any changes applied so far are rolled back and the +** call to sqlite3changeset_apply() returns SQLITE_MISUSE. +** +** If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_DATA conflict +** handler, then the conflicting row is either updated or deleted, depending +** on the type of change. +** +** If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_CONFLICT conflict +** handler, then the conflicting row is removed from the database and a +** second attempt to apply the change is made. If this second attempt fails, +** the original row is restored to the database before continuing. +** +**
    SQLITE_CHANGESET_ABORT
    +** If this value is returned, any changes applied so far are rolled back +** and the call to sqlite3changeset_apply() returns SQLITE_ABORT. +**
    +*/ +#define SQLITE_CHANGESET_OMIT 0 +#define SQLITE_CHANGESET_REPLACE 1 +#define SQLITE_CHANGESET_ABORT 2 + +/* +** CAPI3REF: Rebasing changesets +** EXPERIMENTAL +** +** Suppose there is a site hosting a database in state S0. And that +** modifications are made that move that database to state S1 and a +** changeset recorded (the "local" changeset). Then, a changeset based +** on S0 is received from another site (the "remote" changeset) and +** applied to the database. The database is then in state +** (S1+"remote"), where the exact state depends on any conflict +** resolution decisions (OMIT or REPLACE) made while applying "remote". +** Rebasing a changeset is to update it to take those conflict +** resolution decisions into account, so that the same conflicts +** do not have to be resolved elsewhere in the network. +** +** For example, if both the local and remote changesets contain an +** INSERT of the same key on "CREATE TABLE t1(a PRIMARY KEY, b)": +** +** local: INSERT INTO t1 VALUES(1, 'v1'); +** remote: INSERT INTO t1 VALUES(1, 'v2'); +** +** and the conflict resolution is REPLACE, then the INSERT change is +** removed from the local changeset (it was overridden). Or, if the +** conflict resolution was "OMIT", then the local changeset is modified +** to instead contain: +** +** UPDATE t1 SET b = 'v2' WHERE a=1; +** +** Changes within the local changeset are rebased as follows: +** +**
    +**
    Local INSERT
    +** This may only conflict with a remote INSERT. If the conflict +** resolution was OMIT, then add an UPDATE change to the rebased +** changeset. Or, if the conflict resolution was REPLACE, add +** nothing to the rebased changeset. +** +**
    Local DELETE
    +** This may conflict with a remote UPDATE or DELETE. In both cases the +** only possible resolution is OMIT. If the remote operation was a +** DELETE, then add no change to the rebased changeset. If the remote +** operation was an UPDATE, then the old.* fields of change are updated +** to reflect the new.* values in the UPDATE. +** +**
    Local UPDATE
    +** This may conflict with a remote UPDATE or DELETE. If it conflicts +** with a DELETE, and the conflict resolution was OMIT, then the update +** is changed into an INSERT. Any undefined values in the new.* record +** from the update change are filled in using the old.* values from +** the conflicting DELETE. Or, if the conflict resolution was REPLACE, +** the UPDATE change is simply omitted from the rebased changeset. +** +** If conflict is with a remote UPDATE and the resolution is OMIT, then +** the old.* values are rebased using the new.* values in the remote +** change. Or, if the resolution is REPLACE, then the change is copied +** into the rebased changeset with updates to columns also updated by +** the conflicting remote UPDATE removed. If this means no columns would +** be updated, the change is omitted. +**
    +** +** A local change may be rebased against multiple remote changes +** simultaneously. If a single key is modified by multiple remote +** changesets, they are combined as follows before the local changeset +** is rebased: +** +**
      +**
    • If there has been one or more REPLACE resolutions on a +** key, it is rebased according to a REPLACE. +** +**
    • If there have been no REPLACE resolutions on a key, then +** the local changeset is rebased according to the most recent +** of the OMIT resolutions. +**
    +** +** Note that conflict resolutions from multiple remote changesets are +** combined on a per-field basis, not per-row. This means that in the +** case of multiple remote UPDATE operations, some fields of a single +** local change may be rebased for REPLACE while others are rebased for +** OMIT. +** +** In order to rebase a local changeset, the remote changeset must first +** be applied to the local database using sqlite3changeset_apply_v2() and +** the buffer of rebase information captured. Then: +** +**
      +**
    1. An sqlite3_rebaser object is created by calling +** sqlite3rebaser_create(). +**
    2. The new object is configured with the rebase buffer obtained from +** sqlite3changeset_apply_v2() by calling sqlite3rebaser_configure(). +** If the local changeset is to be rebased against multiple remote +** changesets, then sqlite3rebaser_configure() should be called +** multiple times, in the same order that the multiple +** sqlite3changeset_apply_v2() calls were made. +**
    3. Each local changeset is rebased by calling sqlite3rebaser_rebase(). +**
    4. The sqlite3_rebaser object is deleted by calling +** sqlite3rebaser_delete(). +**
    +*/ +typedef struct sqlite3_rebaser sqlite3_rebaser; + +/* +** CAPI3REF: Create a changeset rebaser object. +** EXPERIMENTAL +** +** Allocate a new changeset rebaser object. If successful, set (*ppNew) to +** point to the new object and return SQLITE_OK. Otherwise, if an error +** occurs, return an SQLite error code (e.g. SQLITE_NOMEM) and set (*ppNew) +** to NULL. +*/ +SQLITE_API int sqlite3rebaser_create(sqlite3_rebaser **ppNew); + +/* +** CAPI3REF: Configure a changeset rebaser object. +** EXPERIMENTAL +** +** Configure the changeset rebaser object to rebase changesets according +** to the conflict resolutions described by buffer pRebase (size nRebase +** bytes), which must have been obtained from a previous call to +** sqlite3changeset_apply_v2(). +*/ +SQLITE_API int sqlite3rebaser_configure( + sqlite3_rebaser*, + int nRebase, const void *pRebase +); + +/* +** CAPI3REF: Rebase a changeset +** EXPERIMENTAL +** +** Argument pIn must point to a buffer containing a changeset nIn bytes +** in size. This function allocates and populates a buffer with a copy +** of the changeset rebased according to the configuration of the +** rebaser object passed as the first argument. If successful, (*ppOut) +** is set to point to the new buffer containing the rebased changeset and +** (*pnOut) to its size in bytes and SQLITE_OK returned. It is the +** responsibility of the caller to eventually free the new buffer using +** sqlite3_free(). Otherwise, if an error occurs, (*ppOut) and (*pnOut) +** are set to zero and an SQLite error code returned. +*/ +SQLITE_API int sqlite3rebaser_rebase( + sqlite3_rebaser*, + int nIn, const void *pIn, + int *pnOut, void **ppOut +); + +/* +** CAPI3REF: Delete a changeset rebaser object. +** EXPERIMENTAL +** +** Delete the changeset rebaser object and all associated resources. There +** should be one call to this function for each successful invocation +** of sqlite3rebaser_create(). +*/ +SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p); + +/* +** CAPI3REF: Streaming Versions of API functions. +** +** The six streaming API xxx_strm() functions serve similar purposes to the +** corresponding non-streaming API functions: +** +** +** +**
    Streaming functionNon-streaming equivalent
    sqlite3changeset_apply_strm[sqlite3changeset_apply] +**
    sqlite3changeset_apply_strm_v2[sqlite3changeset_apply_v2] +**
    sqlite3changeset_concat_strm[sqlite3changeset_concat] +**
    sqlite3changeset_invert_strm[sqlite3changeset_invert] +**
    sqlite3changeset_start_strm[sqlite3changeset_start] +**
    sqlite3session_changeset_strm[sqlite3session_changeset] +**
    sqlite3session_patchset_strm[sqlite3session_patchset] +**
    +** +** Non-streaming functions that accept changesets (or patchsets) as input +** require that the entire changeset be stored in a single buffer in memory. +** Similarly, those that return a changeset or patchset do so by returning +** a pointer to a single large buffer allocated using sqlite3_malloc(). +** Normally this is convenient. However, if an application running in a +** low-memory environment is required to handle very large changesets, the +** large contiguous memory allocations required can become onerous. +** +** In order to avoid this problem, instead of a single large buffer, input +** is passed to a streaming API functions by way of a callback function that +** the sessions module invokes to incrementally request input data as it is +** required. In all cases, a pair of API function parameters such as +** +**
    +**        int nChangeset,
    +**        void *pChangeset,
    +**  
    +** +** Is replaced by: +** +**
    +**        int (*xInput)(void *pIn, void *pData, int *pnData),
    +**        void *pIn,
    +**  
    +** +** Each time the xInput callback is invoked by the sessions module, the first +** argument passed is a copy of the supplied pIn context pointer. The second +** argument, pData, points to a buffer (*pnData) bytes in size. Assuming no +** error occurs the xInput method should copy up to (*pnData) bytes of data +** into the buffer and set (*pnData) to the actual number of bytes copied +** before returning SQLITE_OK. If the input is completely exhausted, (*pnData) +** should be set to zero to indicate this. Or, if an error occurs, an SQLite +** error code should be returned. In all cases, if an xInput callback returns +** an error, all processing is abandoned and the streaming API function +** returns a copy of the error code to the caller. +** +** In the case of sqlite3changeset_start_strm(), the xInput callback may be +** invoked by the sessions module at any point during the lifetime of the +** iterator. If such an xInput callback returns an error, the iterator enters +** an error state, whereby all subsequent calls to iterator functions +** immediately fail with the same error code as returned by xInput. +** +** Similarly, streaming API functions that return changesets (or patchsets) +** return them in chunks by way of a callback function instead of via a +** pointer to a single large buffer. In this case, a pair of parameters such +** as: +** +**
    +**        int *pnChangeset,
    +**        void **ppChangeset,
    +**  
    +** +** Is replaced by: +** +**
    +**        int (*xOutput)(void *pOut, const void *pData, int nData),
    +**        void *pOut
    +**  
    +** +** The xOutput callback is invoked zero or more times to return data to +** the application. The first parameter passed to each call is a copy of the +** pOut pointer supplied by the application. The second parameter, pData, +** points to a buffer nData bytes in size containing the chunk of output +** data being returned. If the xOutput callback successfully processes the +** supplied data, it should return SQLITE_OK to indicate success. Otherwise, +** it should return some other SQLite error code. In this case processing +** is immediately abandoned and the streaming API function returns a copy +** of the xOutput error code to the application. +** +** The sessions module never invokes an xOutput callback with the third +** parameter set to a value less than or equal to zero. Other than this, +** no guarantees are made as to the size of the chunks of data returned. +*/ +SQLITE_API int sqlite3changeset_apply_strm( + sqlite3 *db, /* Apply change to "main" db of this handle */ + int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */ + void *pIn, /* First arg for xInput */ + int(*xFilter)( + void *pCtx, /* Copy of sixth arg to _apply() */ + const char *zTab /* Table name */ + ), + int(*xConflict)( + void *pCtx, /* Copy of sixth arg to _apply() */ + int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ + ), + void *pCtx /* First argument passed to xConflict */ +); +SQLITE_API int sqlite3changeset_apply_v2_strm( + sqlite3 *db, /* Apply change to "main" db of this handle */ + int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */ + void *pIn, /* First arg for xInput */ + int(*xFilter)( + void *pCtx, /* Copy of sixth arg to _apply() */ + const char *zTab /* Table name */ + ), + int(*xConflict)( + void *pCtx, /* Copy of sixth arg to _apply() */ + int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ + ), + void *pCtx, /* First argument passed to xConflict */ + void **ppRebase, int *pnRebase, + int flags +); +SQLITE_API int sqlite3changeset_apply_v3_strm( + sqlite3 *db, /* Apply change to "main" db of this handle */ + int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */ + void *pIn, /* First arg for xInput */ + int(*xFilter)( + void *pCtx, /* Copy of sixth arg to _apply() */ + sqlite3_changeset_iter *p + ), + int(*xConflict)( + void *pCtx, /* Copy of sixth arg to _apply() */ + int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ + ), + void *pCtx, /* First argument passed to xConflict */ + void **ppRebase, int *pnRebase, + int flags +); +SQLITE_API int sqlite3changeset_concat_strm( + int (*xInputA)(void *pIn, void *pData, int *pnData), + void *pInA, + int (*xInputB)(void *pIn, void *pData, int *pnData), + void *pInB, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut +); +SQLITE_API int sqlite3changeset_invert_strm( + int (*xInput)(void *pIn, void *pData, int *pnData), + void *pIn, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut +); +SQLITE_API int sqlite3changeset_start_strm( + sqlite3_changeset_iter **pp, + int (*xInput)(void *pIn, void *pData, int *pnData), + void *pIn +); +SQLITE_API int sqlite3changeset_start_v2_strm( + sqlite3_changeset_iter **pp, + int (*xInput)(void *pIn, void *pData, int *pnData), + void *pIn, + int flags +); +SQLITE_API int sqlite3session_changeset_strm( + sqlite3_session *pSession, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut +); +SQLITE_API int sqlite3session_patchset_strm( + sqlite3_session *pSession, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut +); +SQLITE_API int sqlite3changegroup_add_strm(sqlite3_changegroup*, + int (*xInput)(void *pIn, void *pData, int *pnData), + void *pIn +); +SQLITE_API int sqlite3changegroup_output_strm(sqlite3_changegroup*, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut +); +SQLITE_API int sqlite3rebaser_rebase_strm( + sqlite3_rebaser *pRebaser, + int (*xInput)(void *pIn, void *pData, int *pnData), + void *pIn, + int (*xOutput)(void *pOut, const void *pData, int nData), + void *pOut +); + +/* +** CAPI3REF: Configure global parameters +** +** The sqlite3session_config() interface is used to make global configuration +** changes to the sessions module in order to tune it to the specific needs +** of the application. +** +** The sqlite3session_config() interface is not threadsafe. If it is invoked +** while any other thread is inside any other sessions method then the +** results are undefined. Furthermore, if it is invoked after any sessions +** related objects have been created, the results are also undefined. +** +** The first argument to the sqlite3session_config() function must be one +** of the SQLITE_SESSION_CONFIG_XXX constants defined below. The +** interpretation of the (void*) value passed as the second parameter and +** the effect of calling this function depends on the value of the first +** parameter. +** +**
    +**
    SQLITE_SESSION_CONFIG_STRMSIZE
    +** By default, the sessions module streaming interfaces attempt to input +** and output data in approximately 1 KiB chunks. This operand may be used +** to set and query the value of this configuration setting. The pointer +** passed as the second argument must point to a value of type (int). +** If this value is greater than 0, it is used as the new streaming data +** chunk size for both input and output. Before returning, the (int) value +** pointed to by pArg is set to the final value of the streaming interface +** chunk size. +**
    +** +** This function returns SQLITE_OK if successful, or an SQLite error code +** otherwise. +*/ +SQLITE_API int sqlite3session_config(int op, void *pArg); + +/* +** CAPI3REF: Values for sqlite3session_config(). +*/ +#define SQLITE_SESSION_CONFIG_STRMSIZE 1 + +/* +** CAPI3REF: Configure a changegroup object +** +** Configure the changegroup object passed as the first argument. +** At present the only valid value for the second parameter is +** [SQLITE_CHANGEGROUP_CONFIG_PATCHSET]. +*/ +SQLITE_API int sqlite3changegroup_config(sqlite3_changegroup*, int, void *pArg); + +/* +** CAPI3REF: Options for sqlite3changegroup_config(). +** +** The following values may be passed as the 2nd parameter to +** sqlite3changegroup_config(). +** +**
    SQLITE_CHANGEGROUP_CONFIG_PATCHSET
    +** A changegroup object generates either a changeset or patchset. Usually, +** this is determined by whether the first call to sqlite3changegroup_add() +** is passed a changeset or a patchset. Or, if the first changes are added +** to the changegroup object using the sqlite3changegroup_change_xxx() +** APIs, then this option may be used to configure whether the changegroup +** object generates a changeset or patchset. +** +** When this option is invoked, parameter pArg must point to a value of +** type int. If the changegroup currently contains zero changes, and the +** value of the int variable is zero or greater than zero, then the +** changegroup is configured to generate a changeset or patchset, +** respectively. It is a no-op, not an error, if the changegroup is not +** configured because it has already started accumulating changes. +** +** Before returning, the int variable is set to 0 if the changegroup is +** configured to generate a changeset, or 1 if it is configured to generate +** a patchset. +*/ +#define SQLITE_CHANGEGROUP_CONFIG_PATCHSET 1 + + +/* +** CAPI3REF: Begin adding a change to a changegroup +** +** This API is used, in concert with other sqlite3changegroup_change_xxx() +** APIs, to add changes to a changegroup object one at a time. To add a +** single change, the caller must: +** +** 1. Invoke sqlite3changegroup_change_begin() to indicate the type of +** change (INSERT, UPDATE or DELETE), the affected table and whether +** or not the change should be marked as indirect. +** +** 2. Invoke sqlite3changegroup_change_int64() or one of the other four +** value functions - _null(), _double(), _text() or _blob() - one or +** more times to specify old.* and new.* values for the change being +** constructed. +** +** 3. Invoke sqlite3changegroup_change_finish() to either finish adding +** the change to the group, or to discard the change altogether. +** +** The first argument to this function must be a pointer to the existing +** changegroup object that the change will be added to. The second argument +** must be SQLITE_INSERT, SQLITE_UPDATE or SQLITE_DELETE. The third is the +** name of the table that the change affects, and the fourth is a boolean +** flag specifying whether the change should be marked as "indirect" (if +** bIndirect is non-zero) or not indirect (if bIndirect is zero). +** +** Following a successful call to this function, this function may not be +** called again on the same changegroup object until after +** sqlite3changegroup_change_finish() has been called. Doing so is an +** SQLITE_MISUSE error. +** +** The changegroup object passed as the first argument must be already +** configured with schema data for the specified table. It may be configured +** either by calling sqlite3changegroup_schema() with a database that contains +** the table, or sqlite3changegroup_add() with a changeset that contains the +** table. If the changegroup object has not been configured with a schema for +** the specified table when this function is called, SQLITE_ERROR is returned. +** +** If successful, SQLITE_OK is returned. Otherwise, if an error occurs, an +** SQLite error code is returned. In this case, if argument pzErr is non-NULL, +** then (*pzErr) may be set to point to a buffer containing a utf-8 formated, +** nul-terminated, English language error message. It is the responsibility +** of the caller to eventually free this buffer using sqlite3_free(). +*/ +SQLITE_API int sqlite3changegroup_change_begin( + sqlite3_changegroup*, + int eOp, + const char *zTab, + int bIndirect, + char **pzErr +); + +/* +** CAPI3REF: Add a 64-bit integer to a changegroup +** +** This function may only be called between a successful call to +** sqlite3changegroup_change_begin() and its matching +** sqlite3changegroup_change_finish() call. If it is called at any +** other time, it is an SQLITE_MISUSE error. Calling this function +** specifies a 64-bit integer value to be used in the change currently being +** added to the changegroup object passed as the first argument. +** +** The second parameter, bNew, specifies whether the value is to be part of +** the new.* (if bNew is non-zero) or old.* (if bNew is zero) record of +** the change under construction. If this does not match the type of change +** specified by the preceding call to sqlite3changegroup_change_begin() (i.e. +** an old.* value for an SQLITE_INSERT change, or a new.* value for an +** SQLITE_DELETE), then SQLITE_ERROR is returned. +** +** The third parameter specifies the column of the old.* or new.* record that +** the value will be a part of. If the specified table has an explicit primary +** key, then this is the index of the table column, numbered from 0 in the order +** specified within the CREATE TABLE statement. Or, if the table uses an +** implicit rowid key, then the column 0 is the rowid and the explicit columns +** are numbered starting from 1. If the iCol parameter is less than 0 or greater +** than the index of the last column in the table, SQLITE_RANGE is returned. +** +** The fourth parameter is the integer value to use as part of the old.* or +** new.* record. +** +** If this call is successful, SQLITE_OK is returned. Otherwise, if an +** error occurs, an SQLite error code is returned. +*/ +SQLITE_API int sqlite3changegroup_change_int64( + sqlite3_changegroup*, + int bNew, + int iCol, + sqlite3_int64 iVal +); + +/* +** CAPI3REF: Add a NULL to a changegroup +** +** This function is similar to sqlite3changegroup_change_int64(). Except that +** it configures the change currently under construction with a NULL value +** instead of a 64-bit integer. +*/ +SQLITE_API int sqlite3changegroup_change_null(sqlite3_changegroup*, int, int); + +/* +** CAPI3REF: Add an double to a changegroup +** +** This function is similar to sqlite3changegroup_change_int64(). Except that +** it configures the change currently being constructed with a real value +** instead of a 64-bit integer. +*/ +SQLITE_API int sqlite3changegroup_change_double(sqlite3_changegroup*, int, int, double); + +/* +** CAPI3REF: Add a text value to a changegroup +** +** This function is similar to sqlite3changegroup_change_int64(). It configures +** the currently accumulated change with a text value instead of a 64-bit +** integer. Parameter pVal points to a buffer containing the text encoded using +** utf-8. Parameter nVal may either be the size of the text value in bytes, or +** else a negative value, in which case the buffer pVal points to is assumed to +** be nul-terminated. +*/ +SQLITE_API int sqlite3changegroup_change_text( + sqlite3_changegroup*, int, int, const char *pVal, int nVal +); + +/* +** CAPI3REF: Add a blob to a changegroup +** +** This function is similar to sqlite3changegroup_change_int64(). It configures +** the currently accumulated change with a blob value instead of a 64-bit +** integer. Parameter pVal points to a buffer containing the blob. Parameter +** nVal is the size of the blob in bytes. +*/ +SQLITE_API int sqlite3changegroup_change_blob( + sqlite3_changegroup*, int, int, const void *pVal, int nVal +); + +/* +** CAPI3REF: Finish adding one-at-at-time changes to a changegroup +** +** This function may only be called following a successful call to +** sqlite3changegroup_change_begin(). Otherwise, it is an SQLITE_MISUSE error. +** +** If parameter bDiscard is non-zero, then the current change is simply +** discarded. In this case this function is always successful and SQLITE_OK +** returned. +** +** If parameter bDiscard is zero, then an attempt is made to add the current +** change to the changegroup. Assuming the changegroup is configured to +** produce a changeset (not a patchset), this requires that: +** +** * If the change is an INSERT or DELETE, then a value must be specified +** for all columns of the new.* or old.* record, respectively. +** +** * If the change is an UPDATE record, then values must be provided for +** the PRIMARY KEY columns of the old.* record, but must not be provided +** for PRIMARY KEY columns of the new.* record. +** +** * If the change is an UPDATE record, then for each non-PRIMARY KEY +** column in the old.* record for which a value has been provided, a +** value must also be provided for the same column in the new.* record. +** Similarly, for each non-PK column in the old.* record for which +** a value is not provided, a value must not be provided for the same +** column in the new.* record. +** +** * All values specified for PRIMARY KEY columns must be non-NULL. +** +** Otherwise, it is an error. +** +** If the changegroup already contains a change for the same row (identified +** by PRIMARY KEY columns), then the current change is combined with the +** existing change in the same way as for sqlite3changegroup_add(). +** +** For a patchset, all of the above rules apply except that it doesn't matter +** whether or not values are provided for the non-PK old.* record columns +** for an UPDATE or DELETE change. This means that code used to produce +** a changeset using the sqlite3changegroup_change_xxx() APIs may also +** be used to produce patchsets. +** +** If the call is successful, SQLITE_OK is returned. Otherwise, if an error +** occurs, an SQLite error code is returned. If an error is returned and +** parameter pzErr is not NULL, then (*pzErr) may be set to point to a buffer +** containing a nul-terminated, utf-8 encoded, English language error message. +** It is the responsibility of the caller to eventually free any such error +** message buffer using sqlite3_free(). +*/ +SQLITE_API int sqlite3changegroup_change_finish( + sqlite3_changegroup*, + int bDiscard, + char **pzErr +); + +/* +** Make sure we can call this stuff from C++. +*/ +#if 0 +} +#endif + +#endif /* !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION) */ + +/******** End of sqlite3session.h *********/ +/******** Begin file fts5.h *********/ +/* +** 2014 May 31 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** Interfaces to extend FTS5. Using the interfaces defined in this file, +** FTS5 may be extended with: +** +** * custom tokenizers, and +** * custom auxiliary functions. +*/ + + +#ifndef _FTS5_H +#define _FTS5_H + + +#if 0 +extern "C" { +#endif + +/************************************************************************* +** CUSTOM AUXILIARY FUNCTIONS +** +** Virtual table implementations may overload SQL functions by implementing +** the sqlite3_module.xFindFunction() method. +*/ + +typedef struct Fts5ExtensionApi Fts5ExtensionApi; +typedef struct Fts5Context Fts5Context; +typedef struct Fts5PhraseIter Fts5PhraseIter; + +typedef void (*fts5_extension_function)( + const Fts5ExtensionApi *pApi, /* API offered by current FTS version */ + Fts5Context *pFts, /* First arg to pass to pApi functions */ + sqlite3_context *pCtx, /* Context for returning result/error */ + int nVal, /* Number of values in apVal[] array */ + sqlite3_value **apVal /* Array of trailing arguments */ +); + +struct Fts5PhraseIter { + const unsigned char *a; + const unsigned char *b; +}; + +/* +** EXTENSION API FUNCTIONS +** +** xUserData(pFts): +** Return a copy of the pUserData pointer passed to the xCreateFunction() +** API when the extension function was registered. +** +** xColumnTotalSize(pFts, iCol, pnToken): +** If parameter iCol is less than zero, set output variable *pnToken +** to the total number of tokens in the FTS5 table. Or, if iCol is +** non-negative but less than the number of columns in the table, return +** the total number of tokens in column iCol, considering all rows in +** the FTS5 table. +** +** If parameter iCol is greater than or equal to the number of columns +** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g. +** an OOM condition or IO error), an appropriate SQLite error code is +** returned. +** +** xColumnCount(pFts): +** Return the number of columns in the table. +** +** xColumnSize(pFts, iCol, pnToken): +** If parameter iCol is less than zero, set output variable *pnToken +** to the total number of tokens in the current row. Or, if iCol is +** non-negative but less than the number of columns in the table, set +** *pnToken to the number of tokens in column iCol of the current row. +** +** If parameter iCol is greater than or equal to the number of columns +** in the table, SQLITE_RANGE is returned. Or, if an error occurs (e.g. +** an OOM condition or IO error), an appropriate SQLite error code is +** returned. +** +** This function may be quite inefficient if used with an FTS5 table +** created with the "columnsize=0" option. +** +** xColumnText: +** If parameter iCol is less than zero, or greater than or equal to the +** number of columns in the table, SQLITE_RANGE is returned. +** +** Otherwise, this function attempts to retrieve the text of column iCol of +** the current document. If successful, (*pz) is set to point to a buffer +** containing the text in utf-8 encoding, (*pn) is set to the size in bytes +** (not characters) of the buffer and SQLITE_OK is returned. Otherwise, +** if an error occurs, an SQLite error code is returned and the final values +** of (*pz) and (*pn) are undefined. +** +** xPhraseCount: +** Returns the number of phrases in the current query expression. +** +** xPhraseSize: +** If parameter iCol is less than zero, or greater than or equal to the +** number of phrases in the current query, as returned by xPhraseCount, +** 0 is returned. Otherwise, this function returns the number of tokens in +** phrase iPhrase of the query. Phrases are numbered starting from zero. +** +** xInstCount: +** Set *pnInst to the total number of occurrences of all phrases within +** the query within the current row. Return SQLITE_OK if successful, or +** an error code (i.e. SQLITE_NOMEM) if an error occurs. +** +** This API can be quite slow if used with an FTS5 table created with the +** "detail=none" or "detail=column" option. If the FTS5 table is created +** with either "detail=none" or "detail=column" and "content=" option +** (i.e. if it is a contentless table), then this API always returns 0. +** +** xInst: +** Query for the details of phrase match iIdx within the current row. +** Phrase matches are numbered starting from zero, so the iIdx argument +** should be greater than or equal to zero and smaller than the value +** output by xInstCount(). If iIdx is less than zero or greater than +** or equal to the value returned by xInstCount(), SQLITE_RANGE is returned. +** +** Otherwise, output parameter *piPhrase is set to the phrase number, *piCol +** to the column in which it occurs and *piOff the token offset of the +** first token of the phrase. SQLITE_OK is returned if successful, or an +** error code (i.e. SQLITE_NOMEM) if an error occurs. +** +** This API can be quite slow if used with an FTS5 table created with the +** "detail=none" or "detail=column" option. +** +** xRowid: +** Returns the rowid of the current row. +** +** xTokenize: +** Tokenize text using the tokenizer belonging to the FTS5 table. +** +** xQueryPhrase(pFts5, iPhrase, pUserData, xCallback): +** This API function is used to query the FTS table for phrase iPhrase +** of the current query. Specifically, a query equivalent to: +** +** ... FROM ftstable WHERE ftstable MATCH $p ORDER BY rowid +** +** with $p set to a phrase equivalent to the phrase iPhrase of the +** current query is executed. Any column filter that applies to +** phrase iPhrase of the current query is included in $p. For each +** row visited, the callback function passed as the fourth argument +** is invoked. The context and API objects passed to the callback +** function may be used to access the properties of each matched row. +** Invoking Api.xUserData() returns a copy of the pointer passed as +** the third argument to pUserData. +** +** If parameter iPhrase is less than zero, or greater than or equal to +** the number of phrases in the query, as returned by xPhraseCount(), +** this function returns SQLITE_RANGE. +** +** If the callback function returns any value other than SQLITE_OK, the +** query is abandoned and the xQueryPhrase function returns immediately. +** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK. +** Otherwise, the error code is propagated upwards. +** +** If the query runs to completion without incident, SQLITE_OK is returned. +** Or, if some error occurs before the query completes or is aborted by +** the callback, an SQLite error code is returned. +** +** +** xSetAuxdata(pFts5, pAux, xDelete) +** +** Save the pointer passed as the second argument as the extension function's +** "auxiliary data". The pointer may then be retrieved by the current or any +** future invocation of the same fts5 extension function made as part of +** the same MATCH query using the xGetAuxdata() API. +** +** Each extension function is allocated a single auxiliary data slot for +** each FTS query (MATCH expression). If the extension function is invoked +** more than once for a single FTS query, then all invocations share a +** single auxiliary data context. +** +** If there is already an auxiliary data pointer when this function is +** invoked, then it is replaced by the new pointer. If an xDelete callback +** was specified along with the original pointer, it is invoked at this +** point. +** +** The xDelete callback, if one is specified, is also invoked on the +** auxiliary data pointer after the FTS5 query has finished. +** +** If an error (e.g. an OOM condition) occurs within this function, +** the auxiliary data is set to NULL and an error code returned. If the +** xDelete parameter was not NULL, it is invoked on the auxiliary data +** pointer before returning. +** +** +** xGetAuxdata(pFts5, bClear) +** +** Returns the current auxiliary data pointer for the fts5 extension +** function. See the xSetAuxdata() method for details. +** +** If the bClear argument is non-zero, then the auxiliary data is cleared +** (set to NULL) before this function returns. In this case the xDelete, +** if any, is not invoked. +** +** +** xRowCount(pFts5, pnRow) +** +** This function is used to retrieve the total number of rows in the table. +** In other words, the same value that would be returned by: +** +** SELECT count(*) FROM ftstable; +** +** xPhraseFirst() +** This function is used, along with type Fts5PhraseIter and the xPhraseNext +** method, to iterate through all instances of a single query phrase within +** the current row. This is the same information as is accessible via the +** xInstCount/xInst APIs. While the xInstCount/xInst APIs are more convenient +** to use, this API may be faster under some circumstances. To iterate +** through instances of phrase iPhrase, use the following code: +** +** Fts5PhraseIter iter; +** int iCol, iOff; +** for(pApi->xPhraseFirst(pFts, iPhrase, &iter, &iCol, &iOff); +** iCol>=0; +** pApi->xPhraseNext(pFts, &iter, &iCol, &iOff) +** ){ +** // An instance of phrase iPhrase at offset iOff of column iCol +** } +** +** The Fts5PhraseIter structure is defined above. Applications should not +** modify this structure directly - it should only be used as shown above +** with the xPhraseFirst() and xPhraseNext() API methods (and by +** xPhraseFirstColumn() and xPhraseNextColumn() as illustrated below). +** +** This API can be quite slow if used with an FTS5 table created with the +** "detail=none" or "detail=column" option. If the FTS5 table is created +** with either "detail=none" or "detail=column" and "content=" option +** (i.e. if it is a contentless table), then this API always iterates +** through an empty set (all calls to xPhraseFirst() set iCol to -1). +** +** In all cases, matches are visited in (column ASC, offset ASC) order. +** i.e. all those in column 0, sorted by offset, followed by those in +** column 1, etc. +** +** xPhraseNext() +** See xPhraseFirst above. +** +** xPhraseFirstColumn() +** This function and xPhraseNextColumn() are similar to the xPhraseFirst() +** and xPhraseNext() APIs described above. The difference is that instead +** of iterating through all instances of a phrase in the current row, these +** APIs are used to iterate through the set of columns in the current row +** that contain one or more instances of a specified phrase. For example: +** +** Fts5PhraseIter iter; +** int iCol; +** for(pApi->xPhraseFirstColumn(pFts, iPhrase, &iter, &iCol); +** iCol>=0; +** pApi->xPhraseNextColumn(pFts, &iter, &iCol) +** ){ +** // Column iCol contains at least one instance of phrase iPhrase +** } +** +** This API can be quite slow if used with an FTS5 table created with the +** "detail=none" option. If the FTS5 table is created with either +** "detail=none" "content=" option (i.e. if it is a contentless table), +** then this API always iterates through an empty set (all calls to +** xPhraseFirstColumn() set iCol to -1). +** +** The information accessed using this API and its companion +** xPhraseFirstColumn() may also be obtained using xPhraseFirst/xPhraseNext +** (or xInst/xInstCount). The chief advantage of this API is that it is +** significantly more efficient than those alternatives when used with +** "detail=column" tables. +** +** xPhraseNextColumn() +** See xPhraseFirstColumn above. +** +** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken) +** This is used to access token iToken of phrase iPhrase of the current +** query. Before returning, output parameter *ppToken is set to point +** to a buffer containing the requested token, and *pnToken to the +** size of this buffer in bytes. +** +** If iPhrase or iToken are less than zero, or if iPhrase is greater than +** or equal to the number of phrases in the query as reported by +** xPhraseCount(), or if iToken is equal to or greater than the number of +** tokens in the phrase, SQLITE_RANGE is returned and *ppToken and *pnToken + are both zeroed. +** +** The output text is not a copy of the query text that specified the +** token. It is the output of the tokenizer module. For tokendata=1 +** tables, this includes any embedded 0x00 and trailing data. +** +** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken) +** This is used to access token iToken of phrase hit iIdx within the +** current row. If iIdx is less than zero or greater than or equal to the +** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise, +** output variable (*ppToken) is set to point to a buffer containing the +** matching document token, and (*pnToken) to the size of that buffer in +** bytes. +** +** The output text is not a copy of the document text that was tokenized. +** It is the output of the tokenizer module. For tokendata=1 tables, this +** includes any embedded 0x00 and trailing data. +** +** This API may be slow in some cases if the token identified by parameters +** iIdx and iToken matched a prefix token in the query. In most cases, the +** first call to this API for each prefix token in the query is forced +** to scan the portion of the full-text index that matches the prefix +** token to collect the extra data required by this API. If the prefix +** token matches a large number of token instances in the document set, +** this may be a performance problem. +** +** If the user knows in advance that a query may use this API for a +** prefix token, FTS5 may be configured to collect all required data as part +** of the initial querying of the full-text index, avoiding the second scan +** entirely. This also causes prefix queries that do not use this API to +** run more slowly and use more memory. FTS5 may be configured in this way +** either on a per-table basis using the [FTS5 insttoken | 'insttoken'] +** option, or on a per-query basis using the +** [fts5_insttoken | fts5_insttoken()] user function. +** +** This API can be quite slow if used with an FTS5 table created with the +** "detail=none" or "detail=column" option. +** +** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale) +** If parameter iCol is less than zero, or greater than or equal to the +** number of columns in the table, SQLITE_RANGE is returned. +** +** Otherwise, this function attempts to retrieve the locale associated +** with column iCol of the current row. Usually, there is no associated +** locale, and output parameters (*pzLocale) and (*pnLocale) are set +** to NULL and 0, respectively. However, if the fts5_locale() function +** was used to associate a locale with the value when it was inserted +** into the fts5 table, then (*pzLocale) is set to point to a nul-terminated +** buffer containing the name of the locale in utf-8 encoding. (*pnLocale) +** is set to the size in bytes of the buffer, not including the +** nul-terminator. +** +** If successful, SQLITE_OK is returned. Or, if an error occurs, an +** SQLite error code is returned. The final value of the output parameters +** is undefined in this case. +** +** xTokenize_v2: +** Tokenize text using the tokenizer belonging to the FTS5 table. This +** API is the same as the xTokenize() API, except that it allows a tokenizer +** locale to be specified. +*/ +struct Fts5ExtensionApi { + int iVersion; /* Currently always set to 4 */ + + void *(*xUserData)(Fts5Context*); + + int (*xColumnCount)(Fts5Context*); + int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow); + int (*xColumnTotalSize)(Fts5Context*, int iCol, sqlite3_int64 *pnToken); + + int (*xTokenize)(Fts5Context*, + const char *pText, int nText, /* Text to tokenize */ + void *pCtx, /* Context passed to xToken() */ + int (*xToken)(void*, int, const char*, int, int, int) /* Callback */ + ); + + int (*xPhraseCount)(Fts5Context*); + int (*xPhraseSize)(Fts5Context*, int iPhrase); + + int (*xInstCount)(Fts5Context*, int *pnInst); + int (*xInst)(Fts5Context*, int iIdx, int *piPhrase, int *piCol, int *piOff); + + sqlite3_int64 (*xRowid)(Fts5Context*); + int (*xColumnText)(Fts5Context*, int iCol, const char **pz, int *pn); + int (*xColumnSize)(Fts5Context*, int iCol, int *pnToken); + + int (*xQueryPhrase)(Fts5Context*, int iPhrase, void *pUserData, + int(*)(const Fts5ExtensionApi*,Fts5Context*,void*) + ); + int (*xSetAuxdata)(Fts5Context*, void *pAux, void(*xDelete)(void*)); + void *(*xGetAuxdata)(Fts5Context*, int bClear); + + int (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*); + void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff); + + int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*); + void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol); + + /* Below this point are iVersion>=3 only */ + int (*xQueryToken)(Fts5Context*, + int iPhrase, int iToken, + const char **ppToken, int *pnToken + ); + int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); + + /* Below this point are iVersion>=4 only */ + int (*xColumnLocale)(Fts5Context*, int iCol, const char **pz, int *pn); + int (*xTokenize_v2)(Fts5Context*, + const char *pText, int nText, /* Text to tokenize */ + const char *pLocale, int nLocale, /* Locale to pass to tokenizer */ + void *pCtx, /* Context passed to xToken() */ + int (*xToken)(void*, int, const char*, int, int, int) /* Callback */ + ); +}; + +/* +** CUSTOM AUXILIARY FUNCTIONS +*************************************************************************/ + +/************************************************************************* +** CUSTOM TOKENIZERS +** +** Applications may also register custom tokenizer types. A tokenizer +** is registered by providing fts5 with a populated instance of the +** following structure. All structure methods must be defined, setting +** any member of the fts5_tokenizer struct to NULL leads to undefined +** behaviour. The structure methods are expected to function as follows: +** +** xCreate: +** This function is used to allocate and initialize a tokenizer instance. +** A tokenizer instance is required to actually tokenize text. +** +** The first argument passed to this function is a copy of the (void*) +** pointer provided by the application when the fts5_tokenizer_v2 object +** was registered with FTS5 (the third argument to xCreateTokenizer()). +** The second and third arguments are an array of nul-terminated strings +** containing the tokenizer arguments, if any, specified following the +** tokenizer name as part of the CREATE VIRTUAL TABLE statement used +** to create the FTS5 table. +** +** The final argument is an output variable. If successful, (*ppOut) +** should be set to point to the new tokenizer handle and SQLITE_OK +** returned. If an error occurs, some value other than SQLITE_OK should +** be returned. In this case, fts5 assumes that the final value of *ppOut +** is undefined. +** +** xDelete: +** This function is invoked to delete a tokenizer handle previously +** allocated using xCreate(). Fts5 guarantees that this function will +** be invoked exactly once for each successful call to xCreate(). +** +** xTokenize: +** This function is expected to tokenize the nText byte string indicated +** by argument pText. pText may or may not be nul-terminated. The first +** argument passed to this function is a pointer to an Fts5Tokenizer object +** returned by an earlier call to xCreate(). +** +** The third argument indicates the reason that FTS5 is requesting +** tokenization of the supplied text. This is always one of the following +** four values: +** +**
    • FTS5_TOKENIZE_DOCUMENT - A document is being inserted into +** or removed from the FTS table. The tokenizer is being invoked to +** determine the set of tokens to add to (or delete from) the +** FTS index. +** +**
    • FTS5_TOKENIZE_QUERY - A MATCH query is being executed +** against the FTS index. The tokenizer is being called to tokenize +** a bareword or quoted string specified as part of the query. +** +**
    • (FTS5_TOKENIZE_QUERY | FTS5_TOKENIZE_PREFIX) - Same as +** FTS5_TOKENIZE_QUERY, except that the bareword or quoted string is +** followed by a "*" character, indicating that the last token +** returned by the tokenizer will be treated as a token prefix. +** +**
    • FTS5_TOKENIZE_AUX - The tokenizer is being invoked to +** satisfy an fts5_api.xTokenize() request made by an auxiliary +** function. Or an fts5_api.xColumnSize() request made by the same +** on a columnsize=0 database. +**
    +** +** The sixth and seventh arguments passed to xTokenize() - pLocale and +** nLocale - are a pointer to a buffer containing the locale to use for +** tokenization (e.g. "en_US") and its size in bytes, respectively. The +** pLocale buffer is not nul-terminated. pLocale may be passed NULL (in +** which case nLocale is always 0) to indicate that the tokenizer should +** use its default locale. +** +** For each token in the input string, the supplied callback xToken() must +** be invoked. The first argument to it should be a copy of the pointer +** passed as the second argument to xTokenize(). The third and fourth +** arguments are a pointer to a buffer containing the token text, and the +** size of the token in bytes. The 4th and 5th arguments are the byte offsets +** of the first byte of and first byte immediately following the text from +** which the token is derived within the input. +** +** The second argument passed to the xToken() callback ("tflags") should +** normally be set to 0. The exception is if the tokenizer supports +** synonyms. In this case see the discussion below for details. +** +** FTS5 assumes the xToken() callback is invoked for each token in the +** order that they occur within the input text. +** +** If an xToken() callback returns any value other than SQLITE_OK, then +** the tokenization should be abandoned and the xTokenize() method should +** immediately return a copy of the xToken() return value. Or, if the +** input buffer is exhausted, xTokenize() should return SQLITE_OK. Finally, +** if an error occurs with the xTokenize() implementation itself, it +** may abandon the tokenization and return any error code other than +** SQLITE_OK or SQLITE_DONE. +** +** If the tokenizer is registered using an fts5_tokenizer_v2 object, +** then the xTokenize() method has two additional arguments - pLocale +** and nLocale. These specify the locale that the tokenizer should use +** for the current request. If pLocale and nLocale are both 0, then the +** tokenizer should use its default locale. Otherwise, pLocale points to +** an nLocale byte buffer containing the name of the locale to use as utf-8 +** text. pLocale is not nul-terminated. +** +** FTS5_TOKENIZER +** +** There is also an fts5_tokenizer object. This is an older, deprecated, +** version of fts5_tokenizer_v2. It is similar except that: +** +**
      +**
    • There is no "iVersion" field, and +**
    • The xTokenize() method does not take a locale argument. +**
    +** +** Legacy fts5_tokenizer tokenizers must be registered using the +** legacy xCreateTokenizer() function, instead of xCreateTokenizer_v2(). +** +** Tokenizer implementations registered using either API may be retrieved +** using both xFindTokenizer() and xFindTokenizer_v2(). +** +** SYNONYM SUPPORT +** +** Custom tokenizers may also support synonyms. Consider a case in which a +** user wishes to query for a phrase such as "first place". Using the +** built-in tokenizers, the FTS5 query 'first + place' will match instances +** of "first place" within the document set, but not alternative forms +** such as "1st place". In some applications, it would be better to match +** all instances of "first place" or "1st place" regardless of which form +** the user specified in the MATCH query text. +** +** There are several ways to approach this in FTS5: +** +**
    1. By mapping all synonyms to a single token. In this case, using +** the above example, this means that the tokenizer returns the +** same token for inputs "first" and "1st". Say that token is in +** fact "first", so that when the user inserts the document "I won +** 1st place" entries are added to the index for tokens "i", "won", +** "first" and "place". If the user then queries for '1st + place', +** the tokenizer substitutes "first" for "1st" and the query works +** as expected. +** +**
    2. By querying the index for all synonyms of each query term +** separately. In this case, when tokenizing query text, the +** tokenizer may provide multiple synonyms for a single term +** within the document. FTS5 then queries the index for each +** synonym individually. For example, faced with the query: +** +** +** ... MATCH 'first place' +** +** the tokenizer offers both "1st" and "first" as synonyms for the +** first token in the MATCH query and FTS5 effectively runs a query +** similar to: +** +** +** ... MATCH '(first OR 1st) place' +** +** except that, for the purposes of auxiliary functions, the query +** still appears to contain just two phrases - "(first OR 1st)" +** being treated as a single phrase. +** +**
    3. By adding multiple synonyms for a single term to the FTS index. +** Using this method, when tokenizing document text, the tokenizer +** provides multiple synonyms for each token. So that when a +** document such as "I won first place" is tokenized, entries are +** added to the FTS index for "i", "won", "first", "1st" and +** "place". +** +** This way, even if the tokenizer does not provide synonyms +** when tokenizing query text (it should not - to do so would be +** inefficient), it doesn't matter if the user queries for +** 'first + place' or '1st + place', as there are entries in the +** FTS index corresponding to both forms of the first token. +**
    +** +** Whether it is parsing document or query text, any call to xToken that +** specifies a tflags argument with the FTS5_TOKEN_COLOCATED bit +** is considered to supply a synonym for the previous token. For example, +** when parsing the document "I won first place", a tokenizer that supports +** synonyms would call xToken() 5 times, as follows: +** +** +** xToken(pCtx, 0, "i", 1, 0, 1); +** xToken(pCtx, 0, "won", 3, 2, 5); +** xToken(pCtx, 0, "first", 5, 6, 11); +** xToken(pCtx, FTS5_TOKEN_COLOCATED, "1st", 3, 6, 11); +** xToken(pCtx, 0, "place", 5, 12, 17); +** +** +** It is an error to specify the FTS5_TOKEN_COLOCATED flag the first time +** xToken() is called. Multiple synonyms may be specified for a single token +** by making multiple calls to xToken(FTS5_TOKEN_COLOCATED) in sequence. +** There is no limit to the number of synonyms that may be provided for a +** single token. +** +** In many cases, method (1) above is the best approach. It does not add +** extra data to the FTS index or require FTS5 to query for multiple terms, +** so it is efficient in terms of disk space and query speed. However, it +** does not support prefix queries very well. If, as suggested above, the +** token "first" is substituted for "1st" by the tokenizer, then the query: +** +** +** ... MATCH '1s*' +** +** will not match documents that contain the token "1st" (as the tokenizer +** will probably not map "1s" to any prefix of "first"). +** +** For full prefix support, method (3) may be preferred. In this case, +** because the index contains entries for both "first" and "1st", prefix +** queries such as 'fi*' or '1s*' will match correctly. However, because +** extra entries are added to the FTS index, this method uses more space +** within the database. +** +** Method (2) offers a midpoint between (1) and (3). Using this method, +** a query such as '1s*' will match documents that contain the literal +** token "1st", but not "first" (assuming the tokenizer is not able to +** provide synonyms for prefixes). However, a non-prefix query like '1st' +** will match against "1st" and "first". This method does not require +** extra disk space, as no extra entries are added to the FTS index. +** On the other hand, it may require more CPU cycles to run MATCH queries, +** as separate queries of the FTS index are required for each synonym. +** +** When using methods (2) or (3), it is important that the tokenizer only +** provide synonyms when tokenizing document text (method (3)) or query +** text (method (2)), not both. Doing so will not cause any errors, but is +** inefficient. +*/ +typedef struct Fts5Tokenizer Fts5Tokenizer; +typedef struct fts5_tokenizer_v2 fts5_tokenizer_v2; +struct fts5_tokenizer_v2 { + int iVersion; /* Currently always 2 */ + + int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); + void (*xDelete)(Fts5Tokenizer*); + int (*xTokenize)(Fts5Tokenizer*, + void *pCtx, + int flags, /* Mask of FTS5_TOKENIZE_* flags */ + const char *pText, int nText, + const char *pLocale, int nLocale, + int (*xToken)( + void *pCtx, /* Copy of 2nd argument to xTokenize() */ + int tflags, /* Mask of FTS5_TOKEN_* flags */ + const char *pToken, /* Pointer to buffer containing token */ + int nToken, /* Size of token in bytes */ + int iStart, /* Byte offset of token within input text */ + int iEnd /* Byte offset of end of token within input text */ + ) + ); +}; + +/* +** New code should use the fts5_tokenizer_v2 type to define tokenizer +** implementations. The following type is included for legacy applications +** that still use it. +*/ +typedef struct fts5_tokenizer fts5_tokenizer; +struct fts5_tokenizer { + int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); + void (*xDelete)(Fts5Tokenizer*); + int (*xTokenize)(Fts5Tokenizer*, + void *pCtx, + int flags, /* Mask of FTS5_TOKENIZE_* flags */ + const char *pText, int nText, + int (*xToken)( + void *pCtx, /* Copy of 2nd argument to xTokenize() */ + int tflags, /* Mask of FTS5_TOKEN_* flags */ + const char *pToken, /* Pointer to buffer containing token */ + int nToken, /* Size of token in bytes */ + int iStart, /* Byte offset of token within input text */ + int iEnd /* Byte offset of end of token within input text */ + ) + ); +}; + + +/* Flags that may be passed as the third argument to xTokenize() */ +#define FTS5_TOKENIZE_QUERY 0x0001 +#define FTS5_TOKENIZE_PREFIX 0x0002 +#define FTS5_TOKENIZE_DOCUMENT 0x0004 +#define FTS5_TOKENIZE_AUX 0x0008 + +/* Flags that may be passed by the tokenizer implementation back to FTS5 +** as the third argument to the supplied xToken callback. */ +#define FTS5_TOKEN_COLOCATED 0x0001 /* Same position as prev. token */ + +/* +** END OF CUSTOM TOKENIZERS +*************************************************************************/ + +/************************************************************************* +** FTS5 EXTENSION REGISTRATION API +*/ +typedef struct fts5_api fts5_api; +struct fts5_api { + int iVersion; /* Currently always set to 3 */ + + /* Create a new tokenizer */ + int (*xCreateTokenizer)( + fts5_api *pApi, + const char *zName, + void *pUserData, + fts5_tokenizer *pTokenizer, + void (*xDestroy)(void*) + ); + + /* Find an existing tokenizer */ + int (*xFindTokenizer)( + fts5_api *pApi, + const char *zName, + void **ppUserData, + fts5_tokenizer *pTokenizer + ); + + /* Create a new auxiliary function */ + int (*xCreateFunction)( + fts5_api *pApi, + const char *zName, + void *pUserData, + fts5_extension_function xFunction, + void (*xDestroy)(void*) + ); + + /* APIs below this point are only available if iVersion>=3 */ + + /* Create a new tokenizer */ + int (*xCreateTokenizer_v2)( + fts5_api *pApi, + const char *zName, + void *pUserData, + fts5_tokenizer_v2 *pTokenizer, + void (*xDestroy)(void*) + ); + + /* Find an existing tokenizer */ + int (*xFindTokenizer_v2)( + fts5_api *pApi, + const char *zName, + void **ppUserData, + fts5_tokenizer_v2 **ppTokenizer + ); +}; + +/* +** END OF REGISTRATION API +*************************************************************************/ + +#if 0 +} /* end of the 'extern "C"' block */ +#endif + +#endif /* _FTS5_H */ + +/******** End of fts5.h *********/ +#endif /* SQLITE3_H */ + +/************** End of sqlite3.h *********************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ + +/* +** Reuse the STATIC_LRU for mutex access to sqlite3_temp_directory. +*/ +#define SQLITE_MUTEX_STATIC_TEMPDIR SQLITE_MUTEX_STATIC_VFS1 + +/* +** Include the configuration header output by 'configure' if we're using the +** autoconf-based build +*/ +#if defined(_HAVE_SQLITE_CONFIG_H) && !defined(SQLITECONFIG_H) +#include "sqlite_cfg.h" +#define SQLITECONFIG_H 1 +#endif + +/************** Include sqliteLimit.h in the middle of sqliteInt.h ***********/ +/************** Begin file sqliteLimit.h *************************************/ +/* +** 2007 May 7 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file defines various limits of what SQLite can process. +*/ + +/* +** The maximum length of a TEXT or BLOB in bytes. This also +** limits the size of a row in a table or index. +** +** The hard limit is the ability of a 32-bit signed integer +** to count the size: 2^31-1 or 2147483647. +*/ +#ifndef SQLITE_MAX_LENGTH +# define SQLITE_MAX_LENGTH 1000000000 +#endif +#define SQLITE_MIN_LENGTH 30 /* Minimum value for the length limit */ + +/* +** Maximum size of any single memory allocation. +** +** This is not a limit on the total amount of memory used. This is +** a limit on the size parameter to sqlite3_malloc() and sqlite3_realloc(). +** +** The upper bound is slightly less than 2GiB: 0x7ffffeff == 2,147,483,391 +** This provides a 256-byte safety margin for defense against 32-bit +** signed integer overflow bugs when computing memory allocation sizes. +** Paranoid applications might want to reduce the maximum allocation size +** further for an even larger safety margin. 0x3fffffff or 0x0fffffff +** or even smaller would be reasonable upper bounds on the size of a memory +** allocations for most applications. +*/ +#ifndef SQLITE_MAX_ALLOCATION_SIZE +# define SQLITE_MAX_ALLOCATION_SIZE 2147483391 +#endif +#if SQLITE_MAX_ALLOCATION_SIZE>2147483391 +# error Maximum size for SQLITE_MAX_ALLOCATION_SIZE is 2147483391 +#endif + +/* +** This is the maximum number of +** +** * Columns in a table +** * Columns in an index +** * Columns in a view +** * Terms in the SET clause of an UPDATE statement +** * Terms in the result set of a SELECT statement +** * Terms in the GROUP BY or ORDER BY clauses of a SELECT statement. +** * Terms in the VALUES clause of an INSERT statement +** +** The hard upper limit here is 32767. Most database people will +** tell you that in a well-normalized database, you usually should +** not have more than a dozen or so columns in any table. And if +** that is the case, there is no point in having more than a few +** dozen values in any of the other situations described above. +** +** An index can only have SQLITE_MAX_COLUMN columns from the user +** point of view, but the underlying b-tree that implements the index +** might have up to twice as many columns in a WITHOUT ROWID table, +** since must also store the primary key at the end. Hence the +** column count for Index is u16 instead of i16. +*/ +#if !defined(SQLITE_MAX_COLUMN) +# define SQLITE_MAX_COLUMN 2000 +#elif SQLITE_MAX_COLUMN>32767 +# error SQLITE_MAX_COLUMN may not exceed 32767 +#endif + +/* +** The maximum length of a single SQL statement in bytes. +** +** It used to be the case that setting this value to zero would +** turn the limit off. That is no longer true. It is not possible +** to turn this limit off. +** +** The hard limit is the largest possible 32-bit signed integer less +** 1024, or 2147482624. +*/ +#ifndef SQLITE_MAX_SQL_LENGTH +# define SQLITE_MAX_SQL_LENGTH 1000000000 +#endif + +/* +** The maximum depth of an expression tree. The expression tree depth +** is also limited indirectly by SQLITE_MAX_SQL_LENGTH and by +** SQLITE_MAX_PARSER_DEPTH. Reducing the maximum complexity of +** expressions can help prevent excess memory usage by hostile SQL. +** +** A value of 0 for this compile-time option causes all expression +** depth limiting code to be omitted. +*/ +#ifndef SQLITE_MAX_EXPR_DEPTH +# define SQLITE_MAX_EXPR_DEPTH 1000 +#endif + +/* +** The maximum depth of the LALR(1) stack used in the parser that +** interprets SQL inputs. The parser stack depth can also be limited +** indirectly by SQLITE_MAX_SQL_LENGTH. Limiting the parser stack +** depth can help prevent excess memory usage and excess CPU stack +** usage when processing hostile SQL. +** +** Prior to version 3.45.0 (2024-01-15), the parser stack was +** hard-coded to 100 entries, and that worked fine for almost all +** applications. So the upper bound on this limit need not be large. +*/ +#ifndef SQLITE_MAX_PARSER_DEPTH +# define SQLITE_MAX_PARSER_DEPTH 2500 +#endif + +/* +** The maximum number of terms in a compound SELECT statement. +** The code generator for compound SELECT statements does one +** level of recursion for each term. A stack overflow can result +** if the number of terms is too large. In practice, most SQL +** never has more than 3 or 4 terms. Use a value of 0 to disable +** any limit on the number of terms in a compound SELECT. +*/ +#ifndef SQLITE_MAX_COMPOUND_SELECT +# define SQLITE_MAX_COMPOUND_SELECT 500 +#endif + +/* +** The maximum number of opcodes in a VDBE program. +** Not currently enforced. +*/ +#ifndef SQLITE_MAX_VDBE_OP +# define SQLITE_MAX_VDBE_OP 250000000 +#endif + +/* +** The maximum number of arguments to an SQL function. +** +** This value has a hard upper limit of 32767 due to storage +** constraints (it needs to fit inside a i16). We keep it +** lower than that to prevent abuse. +*/ +#ifndef SQLITE_MAX_FUNCTION_ARG +# define SQLITE_MAX_FUNCTION_ARG 1000 +#endif + +/* +** The suggested maximum number of in-memory pages to use for +** the main database table and for temporary tables. +** +** IMPLEMENTATION-OF: R-30185-15359 The default suggested cache size is -2000, +** which means the cache size is limited to 2048000 bytes of memory. +** IMPLEMENTATION-OF: R-48205-43578 The default suggested cache size can be +** altered using the SQLITE_DEFAULT_CACHE_SIZE compile-time options. +*/ +#ifndef SQLITE_DEFAULT_CACHE_SIZE +# define SQLITE_DEFAULT_CACHE_SIZE -2000 +#endif + +/* +** The default number of frames to accumulate in the log file before +** checkpointing the database in WAL mode. +*/ +#ifndef SQLITE_DEFAULT_WAL_AUTOCHECKPOINT +# define SQLITE_DEFAULT_WAL_AUTOCHECKPOINT 1000 +#endif + +/* +** The maximum number of attached databases. This must be between 0 +** and 125. The upper bound of 125 is because the attached databases are +** counted using a signed 8-bit integer which has a maximum value of 127 +** and we have to allow 2 extra counts for the "main" and "temp" databases. +*/ +#ifndef SQLITE_MAX_ATTACHED +# define SQLITE_MAX_ATTACHED 10 +#endif + + +/* +** The maximum value of a ?nnn wildcard that the parser will accept. +** If the value exceeds 32767 then extra space is required for the Expr +** structure. But otherwise, we believe that the number can be as large +** as a signed 32-bit integer can hold. +*/ +#ifndef SQLITE_MAX_VARIABLE_NUMBER +# define SQLITE_MAX_VARIABLE_NUMBER 32766 +#endif + +/* Maximum page size. The upper bound on this value is 65536. This a limit +** imposed by the use of 16-bit offsets within each page. +** +** Earlier versions of SQLite allowed the user to change this value at +** compile time. This is no longer permitted, on the grounds that it creates +** a library that is technically incompatible with an SQLite library +** compiled with a different limit. If a process operating on a database +** with a page-size of 65536 bytes crashes, then an instance of SQLite +** compiled with the default page-size limit will not be able to rollback +** the aborted transaction. This could lead to database corruption. +*/ +#ifdef SQLITE_MAX_PAGE_SIZE +# undef SQLITE_MAX_PAGE_SIZE +#endif +#define SQLITE_MAX_PAGE_SIZE 65536 + + +/* +** The default size of a database page. +*/ +#ifndef SQLITE_DEFAULT_PAGE_SIZE +# define SQLITE_DEFAULT_PAGE_SIZE 4096 +#endif +#if SQLITE_DEFAULT_PAGE_SIZE>SQLITE_MAX_PAGE_SIZE +# undef SQLITE_DEFAULT_PAGE_SIZE +# define SQLITE_DEFAULT_PAGE_SIZE SQLITE_MAX_PAGE_SIZE +#endif + +/* +** Ordinarily, if no value is explicitly provided, SQLite creates databases +** with page size SQLITE_DEFAULT_PAGE_SIZE. However, based on certain +** device characteristics (sector-size and atomic write() support), +** SQLite may choose a larger value. This constant is the maximum value +** SQLite will choose on its own. +*/ +#ifndef SQLITE_MAX_DEFAULT_PAGE_SIZE +# define SQLITE_MAX_DEFAULT_PAGE_SIZE 8192 +#endif +#if SQLITE_MAX_DEFAULT_PAGE_SIZE>SQLITE_MAX_PAGE_SIZE +# undef SQLITE_MAX_DEFAULT_PAGE_SIZE +# define SQLITE_MAX_DEFAULT_PAGE_SIZE SQLITE_MAX_PAGE_SIZE +#endif +#if SQLITE_MAX_DEFAULT_PAGE_SIZE=4007000 || __has_extension(c_atomic) +# define SQLITE_ATOMIC_INTRINSICS 1 +# define AtomicLoad(PTR) __atomic_load_n((PTR),__ATOMIC_RELAXED) +# define AtomicStore(PTR,VAL) __atomic_store_n((PTR),(VAL),__ATOMIC_RELAXED) +#else +# define SQLITE_ATOMIC_INTRINSICS 0 +# define AtomicLoad(PTR) (*(PTR)) +# define AtomicStore(PTR,VAL) (*(PTR) = (VAL)) +#endif + +/* +** Include standard header files as necessary +*/ +#include +#ifdef HAVE_INTTYPES_H +#include +#endif + +/* +** The following macros are used to cast pointers to integers and +** integers to pointers. The way you do this varies from one compiler +** to the next, so we have developed the following set of #if statements +** to generate appropriate macros for a wide range of compilers. +** +** The correct "ANSI" way to do this is to use the intptr_t type. +** Unfortunately, that typedef is not available on all compilers, or +** if it is available, it requires an #include of specific headers +** that vary from one machine to the next. +** +** Ticket #3860: The llvm-gcc-4.2 compiler from Apple chokes on +** the ((void*)&((char*)0)[X]) construct. But MSVC chokes on ((void*)(X)). +** So we have to define the macros in different ways depending on the +** compiler. +*/ +#if defined(HAVE_STDINT_H) /* Use this case if we have ANSI headers */ +# define SQLITE_INT_TO_PTR(X) ((void*)(intptr_t)(X)) +# define SQLITE_PTR_TO_INT(X) ((int)(intptr_t)(X)) +#elif defined(__PTRDIFF_TYPE__) /* This case should work for GCC */ +# define SQLITE_INT_TO_PTR(X) ((void*)(__PTRDIFF_TYPE__)(X)) +# define SQLITE_PTR_TO_INT(X) ((int)(__PTRDIFF_TYPE__)(X)) +#elif !defined(__GNUC__) /* Works for compilers other than LLVM */ +# define SQLITE_INT_TO_PTR(X) ((void*)&((char*)0)[X]) +# define SQLITE_PTR_TO_INT(X) ((int)(((char*)X)-(char*)0)) +#else /* Generates a warning - but it always works */ +# define SQLITE_INT_TO_PTR(X) ((void*)(X)) +# define SQLITE_PTR_TO_INT(X) ((int)(X)) +#endif + +/* +** Macros to hint to the compiler that a function should or should not be +** inlined. +*/ +#if defined(__GNUC__) +# define SQLITE_NOINLINE __attribute__((noinline)) +# define SQLITE_INLINE __attribute__((always_inline)) inline +#elif defined(_MSC_VER) && _MSC_VER>=1310 +# define SQLITE_NOINLINE __declspec(noinline) +# define SQLITE_INLINE __forceinline +#else +# define SQLITE_NOINLINE +# define SQLITE_INLINE +#endif +#if defined(SQLITE_COVERAGE_TEST) || defined(__STRICT_ANSI__) +# undef SQLITE_INLINE +# define SQLITE_INLINE +#endif + +/* +** Make sure that the compiler intrinsics we desire are enabled when +** compiling with an appropriate version of MSVC unless prevented by +** the SQLITE_DISABLE_INTRINSIC define. +*/ +#if !defined(SQLITE_DISABLE_INTRINSIC) +# if defined(_MSC_VER) && _MSC_VER>=1400 +# if !defined(_WIN32_WCE) +# include +# pragma intrinsic(_byteswap_ushort) +# pragma intrinsic(_byteswap_ulong) +# pragma intrinsic(_byteswap_uint64) +# pragma intrinsic(_ReadWriteBarrier) +# else +# include +# endif +# endif +#endif + +/* +** Enable SQLITE_USE_SEH by default on MSVC builds. Only omit +** SEH support if the -DSQLITE_OMIT_SEH option is given. +*/ +#if defined(_MSC_VER) && !defined(SQLITE_OMIT_SEH) +# define SQLITE_USE_SEH 1 +#else +# undef SQLITE_USE_SEH +#endif + +/* +** Enable SQLITE_DIRECT_OVERFLOW_READ, unless the build explicitly +** disables it using -DSQLITE_DIRECT_OVERFLOW_READ=0 +*/ +#if defined(SQLITE_DIRECT_OVERFLOW_READ) && SQLITE_DIRECT_OVERFLOW_READ+1==1 + /* Disable if -DSQLITE_DIRECT_OVERFLOW_READ=0 */ +# undef SQLITE_DIRECT_OVERFLOW_READ +#else + /* In all other cases, enable */ +# define SQLITE_DIRECT_OVERFLOW_READ 1 +#endif + + +/* +** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2. +** 0 means mutexes are permanently disable and the library is never +** threadsafe. 1 means the library is serialized which is the highest +** level of threadsafety. 2 means the library is multithreaded - multiple +** threads can use SQLite as long as no two threads try to use the same +** database connection at the same time. +** +** Older versions of SQLite used an optional THREADSAFE macro. +** We support that for legacy. +** +** To ensure that the correct value of "THREADSAFE" is reported when querying +** for compile-time options at runtime (e.g. "PRAGMA compile_options"), this +** logic is partially replicated in ctime.c. If it is updated here, it should +** also be updated there. +*/ +#if !defined(SQLITE_THREADSAFE) +# if defined(THREADSAFE) +# define SQLITE_THREADSAFE THREADSAFE +# else +# define SQLITE_THREADSAFE 1 /* IMP: R-07272-22309 */ +# endif +#endif + +/* +** Powersafe overwrite is on by default. But can be turned off using +** the -DSQLITE_POWERSAFE_OVERWRITE=0 command-line option. +*/ +#ifndef SQLITE_POWERSAFE_OVERWRITE +# define SQLITE_POWERSAFE_OVERWRITE 1 +#endif + +/* +** EVIDENCE-OF: R-25715-37072 Memory allocation statistics are enabled by +** default unless SQLite is compiled with SQLITE_DEFAULT_MEMSTATUS=0 in +** which case memory allocation statistics are disabled by default. +*/ +#if !defined(SQLITE_DEFAULT_MEMSTATUS) +# define SQLITE_DEFAULT_MEMSTATUS 1 +#endif + +/* +** Exactly one of the following macros must be defined in order to +** specify which memory allocation subsystem to use. +** +** SQLITE_SYSTEM_MALLOC // Use normal system malloc() +** SQLITE_WIN32_MALLOC // Use Win32 native heap API +** SQLITE_ZERO_MALLOC // Use a stub allocator that always fails +** SQLITE_MEMDEBUG // Debugging version of system malloc() +** +** On Windows, if the SQLITE_WIN32_MALLOC_VALIDATE macro is defined and the +** assert() macro is enabled, each call into the Win32 native heap subsystem +** will cause HeapValidate to be called. If heap validation should fail, an +** assertion will be triggered. +** +** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as +** the default. +*/ +#if defined(SQLITE_SYSTEM_MALLOC) \ + + defined(SQLITE_WIN32_MALLOC) \ + + defined(SQLITE_ZERO_MALLOC) \ + + defined(SQLITE_MEMDEBUG)>1 +# error "Two or more of the following compile-time configuration options\ + are defined but at most one is allowed:\ + SQLITE_SYSTEM_MALLOC, SQLITE_WIN32_MALLOC, SQLITE_MEMDEBUG,\ + SQLITE_ZERO_MALLOC" +#endif +#if defined(SQLITE_SYSTEM_MALLOC) \ + + defined(SQLITE_WIN32_MALLOC) \ + + defined(SQLITE_ZERO_MALLOC) \ + + defined(SQLITE_MEMDEBUG)==0 +# define SQLITE_SYSTEM_MALLOC 1 +#endif + +/* +** If SQLITE_MALLOC_SOFT_LIMIT is not zero, then try to keep the +** sizes of memory allocations below this value where possible. +*/ +#if !defined(SQLITE_MALLOC_SOFT_LIMIT) +# define SQLITE_MALLOC_SOFT_LIMIT 1024 +#endif + +/* +** We need to define _XOPEN_SOURCE as follows in order to enable +** recursive mutexes on most Unix systems and fchmod() on OpenBSD. +** But _XOPEN_SOURCE define causes problems for Mac OS X, so omit +** it. +*/ +#if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__) +# define _XOPEN_SOURCE 600 +#endif + +/* +** NDEBUG and SQLITE_DEBUG are opposites. It should always be true that +** defined(NDEBUG)==!defined(SQLITE_DEBUG). If this is not currently true, +** make it true by defining or undefining NDEBUG. +** +** Setting NDEBUG makes the code smaller and faster by disabling the +** assert() statements in the code. So we want the default action +** to be for NDEBUG to be set and NDEBUG to be undefined only if SQLITE_DEBUG +** is set. Thus NDEBUG becomes an opt-in rather than an opt-out +** feature. +*/ +#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) +# define NDEBUG 1 +#endif +#if defined(NDEBUG) && defined(SQLITE_DEBUG) +# undef NDEBUG +#endif + +/* +** Enable SQLITE_ENABLE_EXPLAIN_COMMENTS if SQLITE_DEBUG is turned on. +*/ +#if !defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) && defined(SQLITE_DEBUG) +# define SQLITE_ENABLE_EXPLAIN_COMMENTS 1 +#endif + +/* +** The testcase() macro is used to aid in coverage testing. When +** doing coverage testing, the condition inside the argument to +** testcase() must be evaluated both true and false in order to +** get full branch coverage. The testcase() macro is inserted +** to help ensure adequate test coverage in places where simple +** condition/decision coverage is inadequate. For example, testcase() +** can be used to make sure boundary values are tested. For +** bitmask tests, testcase() can be used to make sure each bit +** is significant and used at least once. On switch statements +** where multiple cases go to the same block of code, testcase() +** can insure that all cases are evaluated. +*/ +#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG) +# ifndef SQLITE_AMALGAMATION + extern unsigned int sqlite3CoverageCounter; +# endif +# define testcase(X) if( X ){ sqlite3CoverageCounter += (unsigned)__LINE__; } +#else +# define testcase(X) +#endif + +/* +** The TESTONLY macro is used to enclose variable declarations or +** other bits of code that are needed to support the arguments +** within testcase() and assert() macros. +*/ +#if !defined(NDEBUG) || defined(SQLITE_COVERAGE_TEST) +# define TESTONLY(X) X +#else +# define TESTONLY(X) +#endif + +/* +** Sometimes we need a small amount of code such as a variable initialization +** to setup for a later assert() statement. We do not want this code to +** appear when assert() is disabled. The following macro is therefore +** used to contain that setup code. The "VVA" acronym stands for +** "Verification, Validation, and Accreditation". In other words, the +** code within VVA_ONLY() will only run during verification processes. +*/ +#ifndef NDEBUG +# define VVA_ONLY(X) X +#else +# define VVA_ONLY(X) +#endif + +/* +** Disable ALWAYS() and NEVER() (make them pass-throughs) for coverage +** and mutation testing +*/ +#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST) +# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1 +#endif + +/* +** The ALWAYS and NEVER macros surround boolean expressions which +** are intended to always be true or false, respectively. Such +** expressions could be omitted from the code completely. But they +** are included in a few cases in order to enhance the resilience +** of SQLite to unexpected behavior - to make the code "self-healing" +** or "ductile" rather than being "brittle" and crashing at the first +** hint of unplanned behavior. +** +** In other words, ALWAYS and NEVER are added for defensive code. +** +** When doing coverage testing ALWAYS and NEVER are hard-coded to +** be true and false so that the unreachable code they specify will +** not be counted as untested code. +*/ +#if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS) +# define ALWAYS(X) (1) +# define NEVER(X) (0) +#elif !defined(NDEBUG) +# define ALWAYS(X) ((X)?1:(assert(0),0)) +# define NEVER(X) ((X)?(assert(0),1):0) +#else +# define ALWAYS(X) (X) +# define NEVER(X) (X) +#endif + +/* +** Some conditionals are optimizations only. In other words, if the +** conditionals are replaced with a constant 1 (true) or 0 (false) then +** the correct answer is still obtained, though perhaps not as quickly. +** +** The following macros mark these optimizations conditionals. +*/ +#if defined(SQLITE_MUTATION_TEST) +# define OK_IF_ALWAYS_TRUE(X) (1) +# define OK_IF_ALWAYS_FALSE(X) (0) +#else +# define OK_IF_ALWAYS_TRUE(X) (X) +# define OK_IF_ALWAYS_FALSE(X) (X) +#endif + +/* +** Some malloc failures are only possible if SQLITE_TEST_REALLOC_STRESS is +** defined. We need to defend against those failures when testing with +** SQLITE_TEST_REALLOC_STRESS, but we don't want the unreachable branches +** during a normal build. The following macro can be used to disable tests +** that are always false except when SQLITE_TEST_REALLOC_STRESS is set. +*/ +#if defined(SQLITE_TEST_REALLOC_STRESS) +# define ONLY_IF_REALLOC_STRESS(X) (X) +#elif !defined(NDEBUG) +# define ONLY_IF_REALLOC_STRESS(X) ((X)?(assert(0),1):0) +#else +# define ONLY_IF_REALLOC_STRESS(X) (0) +#endif + +/* +** Declarations used for tracing the operating system interfaces. +*/ +#if defined(SQLITE_FORCE_OS_TRACE) || defined(SQLITE_TEST) || \ + (defined(SQLITE_DEBUG) && SQLITE_OS_WIN) + extern int sqlite3OSTrace; +# define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X +# define SQLITE_HAVE_OS_TRACE +#else +# define OSTRACE(X) +# undef SQLITE_HAVE_OS_TRACE +#endif + +/* +** Is the sqlite3ErrName() function needed in the build? Currently, +** it is needed by "mutex_w32.c" (when debugging), "os_win.c" (when +** OSTRACE is enabled), and by several "test*.c" files (which are +** compiled using SQLITE_TEST). +*/ +#if defined(SQLITE_HAVE_OS_TRACE) || defined(SQLITE_TEST) || \ + (defined(SQLITE_DEBUG) && SQLITE_OS_WIN) +# define SQLITE_NEED_ERR_NAME +#else +# undef SQLITE_NEED_ERR_NAME +#endif + +/* +** SQLITE_ENABLE_EXPLAIN_COMMENTS is incompatible with SQLITE_OMIT_EXPLAIN +*/ +#ifdef SQLITE_OMIT_EXPLAIN +# undef SQLITE_ENABLE_EXPLAIN_COMMENTS +#endif + +/* +** SQLITE_OMIT_VIRTUALTABLE implies SQLITE_OMIT_ALTERTABLE +*/ +#if defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_ALTERTABLE) +# define SQLITE_OMIT_ALTERTABLE +#endif + +#define SQLITE_DIGIT_SEPARATOR '_' + +/* +** Return true (non-zero) if the input is an integer that is too large +** to fit in 32-bits. This macro is used inside of various testcase() +** macros to verify that we have tested SQLite for large-file support. +*/ +#define IS_BIG_INT(X) (((X)&~(i64)0xffffffff)!=0) + +/* +** The macro unlikely() is a hint that surrounds a boolean +** expression that is usually false. Macro likely() surrounds +** a boolean expression that is usually true. These hints could, +** in theory, be used by the compiler to generate better code, but +** currently they are just comments for human readers. +*/ +#define likely(X) (X) +#define unlikely(X) (X) + +/************** Include hash.h in the middle of sqliteInt.h ******************/ +/************** Begin file hash.h ********************************************/ +/* +** 2001 September 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This is the header file for the generic hash-table implementation +** used in SQLite. +*/ +#ifndef SQLITE_HASH_H +#define SQLITE_HASH_H + +/* Forward declarations of structures. */ +typedef struct Hash Hash; +typedef struct HashElem HashElem; + +/* A complete hash table is an instance of the following structure. +** The internals of this structure are intended to be opaque -- client +** code should not attempt to access or modify the fields of this structure +** directly. Change this structure only by using the routines below. +** However, some of the "procedures" and "functions" for modifying and +** accessing this structure are really macros, so we can't really make +** this structure opaque. +** +** All elements of the hash table are on a single doubly-linked list. +** Hash.first points to the head of this list. +** +** There are Hash.htsize buckets. Each bucket points to a spot in +** the global doubly-linked list. The contents of the bucket are the +** element pointed to plus the next _ht.count-1 elements in the list. +** +** Hash.htsize and Hash.ht may be zero. In that case lookup is done +** by a linear search of the global list. For small tables, the +** Hash.ht table is never allocated because if there are few elements +** in the table, it is faster to do a linear search than to manage +** the hash table. +*/ +struct Hash { + unsigned int htsize; /* Number of buckets in the hash table */ + unsigned int count; /* Number of entries in this table */ + HashElem *first; /* The first element of the array */ + struct _ht { /* the hash table */ + unsigned int count; /* Number of entries with this hash */ + HashElem *chain; /* Pointer to first entry with this hash */ + } *ht; +}; + +/* Each element in the hash table is an instance of the following +** structure. All elements are stored on a single doubly-linked list. +** +** Again, this structure is intended to be opaque, but it can't really +** be opaque because it is used by macros. +*/ +struct HashElem { + HashElem *next, *prev; /* Next and previous elements in the table */ + void *data; /* Data associated with this element */ + const char *pKey; /* Key associated with this element */ + unsigned int h; /* hash for pKey */ +}; + +/* +** Access routines. To delete, insert a NULL pointer. +*/ +SQLITE_PRIVATE void sqlite3HashInit(Hash*); +SQLITE_PRIVATE void *sqlite3HashInsert(Hash*, const char *pKey, void *pData); +SQLITE_PRIVATE void *sqlite3HashFind(const Hash*, const char *pKey); +SQLITE_PRIVATE void sqlite3HashClear(Hash*); + +/* +** Macros for looping over all elements of a hash table. The idiom is +** like this: +** +** Hash h; +** HashElem *p; +** ... +** for(p=sqliteHashFirst(&h); p; p=sqliteHashNext(p)){ +** SomeStructure *pData = sqliteHashData(p); +** // do something with pData +** } +*/ +#define sqliteHashFirst(H) ((H)->first) +#define sqliteHashNext(E) ((E)->next) +#define sqliteHashData(E) ((E)->data) +/* #define sqliteHashKey(E) ((E)->pKey) // NOT USED */ +/* #define sqliteHashKeysize(E) ((E)->nKey) // NOT USED */ + +/* +** Number of entries in a hash table +*/ +#define sqliteHashCount(H) ((H)->count) + +#endif /* SQLITE_HASH_H */ + +/************** End of hash.h ************************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ +/************** Include parse.h in the middle of sqliteInt.h *****************/ +/************** Begin file parse.h *******************************************/ +#define TK_SEMI 1 +#define TK_EXPLAIN 2 +#define TK_QUERY 3 +#define TK_PLAN 4 +#define TK_BEGIN 5 +#define TK_TRANSACTION 6 +#define TK_DEFERRED 7 +#define TK_IMMEDIATE 8 +#define TK_EXCLUSIVE 9 +#define TK_COMMIT 10 +#define TK_END 11 +#define TK_ROLLBACK 12 +#define TK_SAVEPOINT 13 +#define TK_RELEASE 14 +#define TK_TO 15 +#define TK_TABLE 16 +#define TK_CREATE 17 +#define TK_IF 18 +#define TK_NOT 19 +#define TK_EXISTS 20 +#define TK_TEMP 21 +#define TK_LP 22 +#define TK_RP 23 +#define TK_AS 24 +#define TK_COMMA 25 +#define TK_WITHOUT 26 +#define TK_ABORT 27 +#define TK_ACTION 28 +#define TK_AFTER 29 +#define TK_ANALYZE 30 +#define TK_ASC 31 +#define TK_ATTACH 32 +#define TK_BEFORE 33 +#define TK_BY 34 +#define TK_CASCADE 35 +#define TK_CAST 36 +#define TK_CONFLICT 37 +#define TK_DATABASE 38 +#define TK_DESC 39 +#define TK_DETACH 40 +#define TK_EACH 41 +#define TK_FAIL 42 +#define TK_OR 43 +#define TK_AND 44 +#define TK_IS 45 +#define TK_ISNOT 46 +#define TK_MATCH 47 +#define TK_LIKE_KW 48 +#define TK_BETWEEN 49 +#define TK_IN 50 +#define TK_ISNULL 51 +#define TK_NOTNULL 52 +#define TK_NE 53 +#define TK_EQ 54 +#define TK_GT 55 +#define TK_LE 56 +#define TK_LT 57 +#define TK_GE 58 +#define TK_ESCAPE 59 +#define TK_ID 60 +#define TK_COLUMNKW 61 +#define TK_DO 62 +#define TK_FOR 63 +#define TK_IGNORE 64 +#define TK_INITIALLY 65 +#define TK_INSTEAD 66 +#define TK_NO 67 +#define TK_KEY 68 +#define TK_OF 69 +#define TK_OFFSET 70 +#define TK_PRAGMA 71 +#define TK_RAISE 72 +#define TK_RECURSIVE 73 +#define TK_REPLACE 74 +#define TK_RESTRICT 75 +#define TK_ROW 76 +#define TK_ROWS 77 +#define TK_TRIGGER 78 +#define TK_VACUUM 79 +#define TK_VIEW 80 +#define TK_VIRTUAL 81 +#define TK_WITH 82 +#define TK_NULLS 83 +#define TK_FIRST 84 +#define TK_LAST 85 +#define TK_CURRENT 86 +#define TK_FOLLOWING 87 +#define TK_PARTITION 88 +#define TK_PRECEDING 89 +#define TK_RANGE 90 +#define TK_UNBOUNDED 91 +#define TK_EXCLUDE 92 +#define TK_GROUPS 93 +#define TK_OTHERS 94 +#define TK_TIES 95 +#define TK_GENERATED 96 +#define TK_ALWAYS 97 +#define TK_MATERIALIZED 98 +#define TK_REINDEX 99 +#define TK_RENAME 100 +#define TK_CTIME_KW 101 +#define TK_ANY 102 +#define TK_BITAND 103 +#define TK_BITOR 104 +#define TK_LSHIFT 105 +#define TK_RSHIFT 106 +#define TK_PLUS 107 +#define TK_MINUS 108 +#define TK_STAR 109 +#define TK_SLASH 110 +#define TK_REM 111 +#define TK_CONCAT 112 +#define TK_PTR 113 +#define TK_COLLATE 114 +#define TK_BITNOT 115 +#define TK_ON 116 +#define TK_INDEXED 117 +#define TK_STRING 118 +#define TK_JOIN_KW 119 +#define TK_CONSTRAINT 120 +#define TK_DEFAULT 121 +#define TK_NULL 122 +#define TK_PRIMARY 123 +#define TK_UNIQUE 124 +#define TK_CHECK 125 +#define TK_REFERENCES 126 +#define TK_AUTOINCR 127 +#define TK_INSERT 128 +#define TK_DELETE 129 +#define TK_UPDATE 130 +#define TK_SET 131 +#define TK_DEFERRABLE 132 +#define TK_FOREIGN 133 +#define TK_DROP 134 +#define TK_UNION 135 +#define TK_ALL 136 +#define TK_EXCEPT 137 +#define TK_INTERSECT 138 +#define TK_SELECT 139 +#define TK_VALUES 140 +#define TK_DISTINCT 141 +#define TK_DOT 142 +#define TK_FROM 143 +#define TK_JOIN 144 +#define TK_USING 145 +#define TK_ORDER 146 +#define TK_GROUP 147 +#define TK_HAVING 148 +#define TK_LIMIT 149 +#define TK_WHERE 150 +#define TK_RETURNING 151 +#define TK_INTO 152 +#define TK_NOTHING 153 +#define TK_FLOAT 154 +#define TK_BLOB 155 +#define TK_INTEGER 156 +#define TK_VARIABLE 157 +#define TK_CASE 158 +#define TK_WHEN 159 +#define TK_THEN 160 +#define TK_ELSE 161 +#define TK_INDEX 162 +#define TK_ALTER 163 +#define TK_ADD 164 +#define TK_WINDOW 165 +#define TK_OVER 166 +#define TK_FILTER 167 +#define TK_COLUMN 168 +#define TK_AGG_FUNCTION 169 +#define TK_AGG_COLUMN 170 +#define TK_TRUEFALSE 171 +#define TK_FUNCTION 172 +#define TK_UPLUS 173 +#define TK_UMINUS 174 +#define TK_TRUTH 175 +#define TK_REGISTER 176 +#define TK_VECTOR 177 +#define TK_SELECT_COLUMN 178 +#define TK_IF_NULL_ROW 179 +#define TK_ASTERISK 180 +#define TK_SPAN 181 +#define TK_ERROR 182 +#define TK_QNUMBER 183 +#define TK_SPACE 184 +#define TK_COMMENT 185 +#define TK_ILLEGAL 186 + +/************** End of parse.h ***********************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ +#include +#include +#include +#include +#include +#include + +/* +** Use a macro to replace memcpy() if compiled with SQLITE_INLINE_MEMCPY. +** This allows better measurements of where memcpy() is used when running +** cachegrind. But this macro version of memcpy() is very slow so it +** should not be used in production. This is a performance measurement +** hack only. +*/ +#ifdef SQLITE_INLINE_MEMCPY +# define memcpy(D,S,N) {char*xxd=(char*)(D);const char*xxs=(const char*)(S);\ + int xxn=(N);while(xxn-->0)*(xxd++)=*(xxs++);} +#endif + +/* +** If compiling for a processor that lacks floating point support, +** substitute integer for floating-point +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# define double sqlite_int64 +# define float sqlite_int64 +# define fabs(X) ((X)<0?-(X):(X)) +# define sqlite3IsOverflow(X) 0 +# define INFINITY (9223372036854775807LL) +# ifndef SQLITE_BIG_DBL +# define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50) +# endif +# define SQLITE_OMIT_DATETIME_FUNCS 1 +# define SQLITE_OMIT_TRACE 1 +# undef SQLITE_MIXED_ENDIAN_64BIT_FLOAT +# undef SQLITE_HAVE_ISNAN +#endif +#ifndef SQLITE_BIG_DBL +# define SQLITE_BIG_DBL (1e99) +#endif + +/* +** OMIT_TEMPDB is set to 1 if SQLITE_OMIT_TEMPDB is defined, or 0 +** afterward. Having this macro allows us to cause the C compiler +** to omit code used by TEMP tables without messy #ifndef statements. +*/ +#ifdef SQLITE_OMIT_TEMPDB +#define OMIT_TEMPDB 1 +#else +#define OMIT_TEMPDB 0 +#endif + +/* +** The "file format" number is an integer that is incremented whenever +** the VDBE-level file format changes. The following macros define the +** the default file format for new databases and the maximum file format +** that the library can read. +*/ +#define SQLITE_MAX_FILE_FORMAT 4 +#ifndef SQLITE_DEFAULT_FILE_FORMAT +# define SQLITE_DEFAULT_FILE_FORMAT 4 +#endif + +/* +** Determine whether triggers are recursive by default. This can be +** changed at run-time using a pragma. +*/ +#ifndef SQLITE_DEFAULT_RECURSIVE_TRIGGERS +# define SQLITE_DEFAULT_RECURSIVE_TRIGGERS 0 +#endif + +/* +** Provide a default value for SQLITE_TEMP_STORE in case it is not specified +** on the command-line +*/ +#ifndef SQLITE_TEMP_STORE +# define SQLITE_TEMP_STORE 1 +#endif + +/* +** If no value has been provided for SQLITE_MAX_WORKER_THREADS, or if +** SQLITE_TEMP_STORE is set to 3 (never use temporary files), set it +** to zero. +*/ +#if SQLITE_TEMP_STORE==3 || SQLITE_THREADSAFE==0 +# undef SQLITE_MAX_WORKER_THREADS +# define SQLITE_MAX_WORKER_THREADS 0 +#endif +#ifndef SQLITE_MAX_WORKER_THREADS +# define SQLITE_MAX_WORKER_THREADS 8 +#endif +#ifndef SQLITE_DEFAULT_WORKER_THREADS +# define SQLITE_DEFAULT_WORKER_THREADS 0 +#endif +#if SQLITE_DEFAULT_WORKER_THREADS>SQLITE_MAX_WORKER_THREADS +# undef SQLITE_MAX_WORKER_THREADS +# define SQLITE_MAX_WORKER_THREADS SQLITE_DEFAULT_WORKER_THREADS +#endif + +/* +** The default initial allocation for the pagecache when using separate +** pagecaches for each database connection. A positive number is the +** number of pages. A negative number N translations means that a buffer +** of -1024*N bytes is allocated and used for as many pages as it will hold. +** +** The default value of "20" was chosen to minimize the run-time of the +** speedtest1 test program with options: --shrink-memory --reprepare +*/ +#ifndef SQLITE_DEFAULT_PCACHE_INITSZ +# define SQLITE_DEFAULT_PCACHE_INITSZ 20 +#endif + +/* +** Default value for the SQLITE_CONFIG_SORTERREF_SIZE option. +*/ +#ifndef SQLITE_DEFAULT_SORTERREF_SIZE +# define SQLITE_DEFAULT_SORTERREF_SIZE 0x7fffffff +#endif + +/* +** The compile-time options SQLITE_MMAP_READWRITE and +** SQLITE_ENABLE_BATCH_ATOMIC_WRITE are not compatible with one another. +** You must choose one or the other (or neither) but not both. +*/ +#if defined(SQLITE_MMAP_READWRITE) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) +#error Cannot use both SQLITE_MMAP_READWRITE and SQLITE_ENABLE_BATCH_ATOMIC_WRITE +#endif + +/* +** GCC does not define the offsetof() macro so we'll have to do it +** ourselves. +*/ +#ifndef offsetof +# define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) +#endif + +/* +** sizeof64() is like sizeof(), but always returns a 64-bit value, even +** on 32-bit builds. This can help to avoid overflow by ensuring 64-bit +** arithmetic is used consistently in both 32-bit and 64-bit builds. +*/ +#define sizeof64(X) ((sqlite3_int64)sizeof(X)) + +/* +** Work around C99 "flex-array" syntax for pre-C99 compilers, so as +** to avoid complaints from -fsanitize=strict-bounds. +*/ +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define FLEXARRAY +#else +# define FLEXARRAY 1 +#endif + +/* +** Macros to compute minimum and maximum of two numbers. +*/ +#ifndef MIN +# define MIN(A,B) ((A)<(B)?(A):(B)) +#endif +#ifndef MAX +# define MAX(A,B) ((A)>(B)?(A):(B)) +#endif + +/* +** Swap two objects of type TYPE. +*/ +#define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;} + +/* +** Check to see if this machine uses EBCDIC. (Yes, believe it or +** not, there are still machines out there that use EBCDIC.) +*/ +#if 'A' == '\301' +# define SQLITE_EBCDIC 1 +#else +# define SQLITE_ASCII 1 +#endif + +/* +** Integers of known sizes. These typedefs might change for architectures +** where the sizes very. Preprocessor macros are available so that the +** types can be conveniently redefined at compile-type. Like this: +** +** cc '-DUINTPTR_TYPE=long long int' ... +*/ +#ifndef UINT32_TYPE +# ifdef HAVE_UINT32_T +# define UINT32_TYPE uint32_t +# else +# define UINT32_TYPE unsigned int +# endif +#endif +#ifndef UINT16_TYPE +# ifdef HAVE_UINT16_T +# define UINT16_TYPE uint16_t +# else +# define UINT16_TYPE unsigned short int +# endif +#endif +#ifndef INT16_TYPE +# ifdef HAVE_INT16_T +# define INT16_TYPE int16_t +# else +# define INT16_TYPE short int +# endif +#endif +#ifndef UINT8_TYPE +# ifdef HAVE_UINT8_T +# define UINT8_TYPE uint8_t +# else +# define UINT8_TYPE unsigned char +# endif +#endif +#ifndef INT8_TYPE +# ifdef HAVE_INT8_T +# define INT8_TYPE int8_t +# else +# define INT8_TYPE signed char +# endif +#endif +typedef sqlite_int64 i64; /* 8-byte signed integer */ +typedef sqlite_uint64 u64; /* 8-byte unsigned integer */ +typedef UINT32_TYPE u32; /* 4-byte unsigned integer */ +typedef UINT16_TYPE u16; /* 2-byte unsigned integer */ +typedef INT16_TYPE i16; /* 2-byte signed integer */ +typedef UINT8_TYPE u8; /* 1-byte unsigned integer */ +typedef INT8_TYPE i8; /* 1-byte signed integer */ + +/* A bitfield type for use inside of structures. Always follow with :N where +** N is the number of bits. +*/ +typedef unsigned bft; /* Bit Field Type */ + +/* +** SQLITE_MAX_U32 is a u64 constant that is the maximum u64 value +** that can be stored in a u32 without loss of data. The value +** is 0x00000000ffffffff. But because of quirks of some compilers, we +** have to specify the value in the less intuitive manner shown: +*/ +#define SQLITE_MAX_U32 ((((u64)1)<<32)-1) + +/* +** The datatype used to store estimates of the number of rows in a +** table or index. +*/ +typedef u64 tRowcnt; + +/* +** Estimated quantities used for query planning are stored as 16-bit +** logarithms. For quantity X, the value stored is 10*log2(X). This +** gives a possible range of values of approximately 1.0e986 to 1e-986. +** But the allowed values are "grainy". Not every value is representable. +** For example, quantities 16 and 17 are both represented by a LogEst +** of 40. However, since LogEst quantities are suppose to be estimates, +** not exact values, this imprecision is not a problem. +** +** "LogEst" is short for "Logarithmic Estimate". +** +** Examples: +** 1 -> 0 20 -> 43 10000 -> 132 +** 2 -> 10 25 -> 46 25000 -> 146 +** 3 -> 16 100 -> 66 1000000 -> 199 +** 4 -> 20 1000 -> 99 1048576 -> 200 +** 10 -> 33 1024 -> 100 4294967296 -> 320 +** +** The LogEst can be negative to indicate fractional values. +** Examples: +** +** 0.5 -> -10 0.1 -> -33 0.0625 -> -40 +*/ +typedef INT16_TYPE LogEst; +#define LOGEST_MIN (-32768) +#define LOGEST_MAX (32767) + +/* +** Set the SQLITE_PTRSIZE macro to the number of bytes in a pointer +*/ +#ifndef SQLITE_PTRSIZE +# if defined(__SIZEOF_POINTER__) +# define SQLITE_PTRSIZE __SIZEOF_POINTER__ +# elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(_M_ARM) || defined(__arm__) || defined(__x86) || \ + (defined(__APPLE__) && defined(__ppc__)) || \ + (defined(__TOS_AIX__) && !defined(__64BIT__)) +# define SQLITE_PTRSIZE 4 +# else +# define SQLITE_PTRSIZE 8 +# endif +#endif + +/* The uptr type is an unsigned integer large enough to hold a pointer +*/ +#if defined(HAVE_STDINT_H) + typedef uintptr_t uptr; +#elif SQLITE_PTRSIZE==4 + typedef u32 uptr; +#else + typedef u64 uptr; +#endif + +/* +** The SQLITE_WITHIN(P,S,E) macro checks to see if pointer P points to +** something between S (inclusive) and E (exclusive). +** +** In other words, S is a buffer and E is a pointer to the first byte after +** the end of buffer S. This macro returns true if P points to something +** contained within the buffer S. +*/ +#define SQLITE_WITHIN(P,S,E) (((uptr)(P)>=(uptr)(S))&&((uptr)(P)<(uptr)(E))) + +/* +** P is one byte past the end of a large buffer. Return true if a span of bytes +** between S..E crosses the end of that buffer. In other words, return true +** if the sub-buffer S..E-1 overflows the buffer whose last byte is P-1. +** +** S is the start of the span. E is one byte past the end of end of span. +** +** P +** |-----------------| FALSE +** |-------| +** S E +** +** P +** |-----------------| +** |-------| TRUE +** S E +** +** P +** |-----------------| +** |-------| FALSE +** S E +*/ +#define SQLITE_OVERFLOW(P,S,E) (((uptr)(S)<(uptr)(P))&&((uptr)(E)>(uptr)(P))) + +/* +** Macros to determine whether the machine is big or little endian, +** and whether or not that determination is run-time or compile-time. +** +** For best performance, an attempt is made to guess at the byte-order +** using C-preprocessor macros. If that is unsuccessful, or if +** -DSQLITE_BYTEORDER=0 is set, then byte-order is determined +** at run-time. +** +** If you are building SQLite on some obscure platform for which the +** following ifdef magic does not work, you can always include either: +** +** -DSQLITE_BYTEORDER=1234 +** +** or +** +** -DSQLITE_BYTEORDER=4321 +** +** to cause the build to work for little-endian or big-endian processors, +** respectively. +*/ +#ifndef SQLITE_BYTEORDER /* Replicate changes at tag-20230904a */ +# if defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__ +# define SQLITE_BYTEORDER 4321 +# elif defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ +# define SQLITE_BYTEORDER 1234 +# elif defined(__BIG_ENDIAN__) && __BIG_ENDIAN__==1 +# define SQLITE_BYTEORDER 4321 +# elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ + defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ + defined(__ARMEL__) || defined(__AARCH64EL__) || defined(_M_ARM64) +# define SQLITE_BYTEORDER 1234 +# elif defined(sparc) || defined(__ARMEB__) || defined(__AARCH64EB__) +# define SQLITE_BYTEORDER 4321 +# else +# define SQLITE_BYTEORDER 0 +# endif +#endif +#if SQLITE_BYTEORDER==4321 +# define SQLITE_BIGENDIAN 1 +# define SQLITE_LITTLEENDIAN 0 +# define SQLITE_UTF16NATIVE SQLITE_UTF16BE +#elif SQLITE_BYTEORDER==1234 +# define SQLITE_BIGENDIAN 0 +# define SQLITE_LITTLEENDIAN 1 +# define SQLITE_UTF16NATIVE SQLITE_UTF16LE +#else +# ifdef SQLITE_AMALGAMATION + const int sqlite3one = 1; +# else + extern const int sqlite3one; +# endif +# define SQLITE_BIGENDIAN (*(char *)(&sqlite3one)==0) +# define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1) +# define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE) +#endif + +/* +** Constants for the largest and smallest possible 64-bit signed integers. +** These macros are designed to work correctly on both 32-bit and 64-bit +** compilers. +*/ +#define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) +#define LARGEST_UINT64 (0xffffffff|(((u64)0xffffffff)<<32)) +#define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) + +/* +** Macro SMXV(n) return the maximum value that can be held in variable n, +** assuming n is a signed integer type. UMXV(n) is similar for unsigned +** integer types. +*/ +#define SMXV(n) ((((i64)1)<<(sizeof(n)*8-1))-1) +#define UMXV(n) ((((i64)1)<<(sizeof(n)*8))-1) + +/* +** Round up a number to the next larger multiple of 8. This is used +** to force 8-byte alignment on 64-bit architectures. +** +** ROUND8() always does the rounding, for any argument. +** +** ROUND8P() assumes that the argument is already an integer number of +** pointers in size, and so it is a no-op on systems where the pointer +** size is 8. +*/ +#define ROUND8(x) (((x)+7)&~7) +#if SQLITE_PTRSIZE==8 +# define ROUND8P(x) (x) +#else +# define ROUND8P(x) (((x)+7)&~7) +#endif + +/* +** Round down to the nearest multiple of 8 +*/ +#define ROUNDDOWN8(x) ((x)&~7) + +/* +** Assert that the pointer X is aligned to an 8-byte boundary. This +** macro is used only within assert() to verify that the code gets +** all alignment restrictions correct. +** +** Except, if SQLITE_4_BYTE_ALIGNED_MALLOC is defined, then the +** underlying malloc() implementation might return us 4-byte aligned +** pointers. In that case, only verify 4-byte alignment. +*/ +#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC +# define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&3)==0) +#else +# define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&7)==0) +#endif +#define TWO_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&1)==0) + +/* +** Disable MMAP on platforms where it is known to not work +*/ +#if defined(__OpenBSD__) || defined(__QNXNTO__) +# undef SQLITE_MAX_MMAP_SIZE +# define SQLITE_MAX_MMAP_SIZE 0 +#endif + +/* +** Default maximum size of memory used by memory-mapped I/O in the VFS +*/ +#ifdef __APPLE__ +# include +#endif +#ifndef SQLITE_MAX_MMAP_SIZE +# if defined(__linux__) \ + || defined(_WIN32) \ + || (defined(__APPLE__) && defined(__MACH__)) \ + || defined(__sun) \ + || defined(__FreeBSD__) \ + || defined(__DragonFly__) +# define SQLITE_MAX_MMAP_SIZE 0x7fff0000 /* 2147418112 */ +# else +# define SQLITE_MAX_MMAP_SIZE 0 +# endif +#endif + +/* +** The default MMAP_SIZE is zero on all platforms. Or, even if a larger +** default MMAP_SIZE is specified at compile-time, make sure that it does +** not exceed the maximum mmap size. +*/ +#ifndef SQLITE_DEFAULT_MMAP_SIZE +# define SQLITE_DEFAULT_MMAP_SIZE 0 +#endif +#if SQLITE_DEFAULT_MMAP_SIZE>SQLITE_MAX_MMAP_SIZE +# undef SQLITE_DEFAULT_MMAP_SIZE +# define SQLITE_DEFAULT_MMAP_SIZE SQLITE_MAX_MMAP_SIZE +#endif + +/* +** TREETRACE_ENABLED will be either 1 or 0 depending on whether or not +** the Abstract Syntax Tree tracing logic is turned on. +*/ +#if !defined(SQLITE_AMALGAMATION) +SQLITE_PRIVATE u32 sqlite3TreeTrace; +#endif +#if defined(SQLITE_DEBUG) \ + && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_SELECTTRACE) \ + || defined(SQLITE_ENABLE_TREETRACE)) +# define TREETRACE_ENABLED 1 +# define TREETRACE(K,P,S,X) \ + if(sqlite3TreeTrace&(K)) \ + sqlite3DebugPrintf("%u/%d/%p: ",(S)->selId,(P)->addrExplain,(S)),\ + sqlite3DebugPrintf X +#else +# define TREETRACE(K,P,S,X) +# define TREETRACE_ENABLED 0 +#endif + +/* TREETRACE flag meanings: +** +** 0x00000001 Beginning and end of SELECT processing +** 0x00000002 WHERE clause processing +** 0x00000004 Query flattener +** 0x00000008 Result-set wildcard expansion +** 0x00000010 Query name resolution +** 0x00000020 Aggregate analysis +** 0x00000040 Window functions +** 0x00000080 Generated column names +** 0x00000100 Move HAVING terms into WHERE +** 0x00000200 Count-of-view optimization +** 0x00000400 Compound SELECT processing +** 0x00000800 Drop superfluous ORDER BY +** 0x00001000 LEFT JOIN simplifies to JOIN +** 0x00002000 Constant propagation +** 0x00004000 Push-down optimization +** 0x00008000 After all FROM-clause analysis +** 0x00010000 Beginning of DELETE/INSERT/UPDATE processing +** 0x00020000 Transform DISTINCT into GROUP BY +** 0x00040000 SELECT tree dump after all code has been generated +** 0x00080000 NOT NULL strength reduction +** 0x00100000 Pointers are all shown as zero +** 0x00200000 EXISTS-to-JOIN optimization +*/ + +/* +** Macros for "wheretrace" +*/ +SQLITE_PRIVATE u32 sqlite3WhereTrace; +#if defined(SQLITE_DEBUG) \ + && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE)) +# define WHERETRACE(K,X) if(sqlite3WhereTrace&(K)) sqlite3DebugPrintf X +# define WHERETRACE_ENABLED 1 +#else +# define WHERETRACE(K,X) +#endif + +/* +** Bits for the sqlite3WhereTrace mask: +** +** (---any--) Top-level block structure +** 0x-------F High-level debug messages +** 0x----FFF- More detail +** 0xFFFF---- Low-level debug messages +** +** 0x00000001 Code generation +** 0x00000002 Solver (Use 0x40000 for less detail) +** 0x00000004 Solver costs +** 0x00000008 WhereLoop inserts +** +** 0x00000010 Display sqlite3_index_info xBestIndex calls +** 0x00000020 Range an equality scan metrics +** 0x00000040 IN operator decisions +** 0x00000080 WhereLoop cost adjustments +** 0x00000100 +** 0x00000200 Covering index decisions +** 0x00000400 OR optimization +** 0x00000800 Index scanner +** 0x00001000 More details associated with code generation +** 0x00002000 +** 0x00004000 Show all WHERE terms at key points +** 0x00008000 Show the full SELECT statement at key places +** +** 0x00010000 Show more detail when printing WHERE terms +** 0x00020000 Show WHERE terms returned from whereScanNext() +** 0x00040000 Solver overview messages +** 0x00080000 Star-query heuristic +** 0x00100000 Pointers are all shown as zero +*/ + + +/* +** An instance of the following structure is used to store the busy-handler +** callback for a given sqlite handle. +** +** The sqlite.busyHandler member of the sqlite struct contains the busy +** callback for the database handle. Each pager opened via the sqlite +** handle is passed a pointer to sqlite.busyHandler. The busy-handler +** callback is currently invoked only from within pager.c. +*/ +typedef struct BusyHandler BusyHandler; +struct BusyHandler { + int (*xBusyHandler)(void *,int); /* The busy callback */ + void *pBusyArg; /* First arg to busy callback */ + int nBusy; /* Incremented with each busy call */ +}; + +/* +** Name of table that holds the database schema. +** +** The PREFERRED names are used wherever possible. But LEGACY is also +** used for backwards compatibility. +** +** 1. Queries can use either the PREFERRED or the LEGACY names +** 2. The sqlite3_set_authorizer() callback uses the LEGACY name +** 3. The PRAGMA table_list statement uses the PREFERRED name +** +** The LEGACY names are stored in the internal symbol hash table +** in support of (2). Names are translated using sqlite3PreferredTableName() +** for (3). The sqlite3FindTable() function takes care of translating +** names for (1). +** +** Note that "sqlite_temp_schema" can also be called "temp.sqlite_schema". +*/ +#define LEGACY_SCHEMA_TABLE "sqlite_master" +#define LEGACY_TEMP_SCHEMA_TABLE "sqlite_temp_master" +#define PREFERRED_SCHEMA_TABLE "sqlite_schema" +#define PREFERRED_TEMP_SCHEMA_TABLE "sqlite_temp_schema" + + +/* +** The root-page of the schema table. +*/ +#define SCHEMA_ROOT 1 + +/* +** The name of the schema table. The name is different for TEMP. +*/ +#define SCHEMA_TABLE(x) \ + ((!OMIT_TEMPDB)&&(x==1)?LEGACY_TEMP_SCHEMA_TABLE:LEGACY_SCHEMA_TABLE) + +/* +** A convenience macro that returns the number of elements in +** an array. +*/ +#define ArraySize(X) ((int)(sizeof(X)/sizeof(X[0]))) + +/* +** Determine if the argument is a power of two +*/ +#define IsPowerOfTwo(X) (((X)&((X)-1))==0) + +/* +** The following value as a destructor means to use sqlite3DbFree(). +** The sqlite3DbFree() routine requires two parameters instead of the +** one parameter that destructors normally want. So we have to introduce +** this magic value that the code knows to handle differently. Any +** pointer will work here as long as it is distinct from SQLITE_STATIC +** and SQLITE_TRANSIENT. +*/ +#define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3RowSetClear) + +/* +** When SQLITE_OMIT_WSD is defined, it means that the target platform does +** not support Writable Static Data (WSD) such as global and static variables. +** All variables must either be on the stack or dynamically allocated from +** the heap. When WSD is unsupported, the variable declarations scattered +** throughout the SQLite code must become constants instead. The SQLITE_WSD +** macro is used for this purpose. And instead of referencing the variable +** directly, we use its constant as a key to lookup the run-time allocated +** buffer that holds real variable. The constant is also the initializer +** for the run-time allocated buffer. +** +** In the usual case where WSD is supported, the SQLITE_WSD and GLOBAL +** macros become no-ops and have zero performance impact. +*/ +#ifdef SQLITE_OMIT_WSD + #define SQLITE_WSD const + #define GLOBAL(t,v) (*(t*)sqlite3_wsd_find((void*)&(v), sizeof(v))) + #define sqlite3GlobalConfig GLOBAL(struct Sqlite3Config, sqlite3Config) +SQLITE_API int sqlite3_wsd_init(int N, int J); +SQLITE_API void *sqlite3_wsd_find(void *K, int L); +#else + #define SQLITE_WSD + #define GLOBAL(t,v) v + #define sqlite3GlobalConfig sqlite3Config +#endif + +/* +** The following macros are used to suppress compiler warnings and to +** make it clear to human readers when a function parameter is deliberately +** left unused within the body of a function. This usually happens when +** a function is called via a function pointer. For example the +** implementation of an SQL aggregate step callback may not use the +** parameter indicating the number of arguments passed to the aggregate, +** if it knows that this is enforced elsewhere. +** +** When a function parameter is not used at all within the body of a function, +** it is generally named "NotUsed" or "NotUsed2" to make things even clearer. +** However, these macros may also be used to suppress warnings related to +** parameters that may or may not be used depending on compilation options. +** For example those parameters only used in assert() statements. In these +** cases the parameters are named as per the usual conventions. +*/ +#define UNUSED_PARAMETER(x) (void)(x) +#define UNUSED_PARAMETER2(x,y) UNUSED_PARAMETER(x),UNUSED_PARAMETER(y) + +/* +** Forward references to structures +*/ +typedef struct AggInfo AggInfo; +typedef struct AuthContext AuthContext; +typedef struct AutoincInfo AutoincInfo; +typedef struct Bitvec Bitvec; +typedef struct CollSeq CollSeq; +typedef struct Column Column; +typedef struct Cte Cte; +typedef struct CteUse CteUse; +typedef struct Db Db; +typedef struct DbClientData DbClientData; +typedef struct DbFixer DbFixer; +typedef struct Schema Schema; +typedef struct Expr Expr; +typedef struct ExprList ExprList; +typedef struct FKey FKey; +typedef struct FpDecode FpDecode; +typedef struct FuncDestructor FuncDestructor; +typedef struct FuncDef FuncDef; +typedef struct FuncDefHash FuncDefHash; +typedef struct IdList IdList; +typedef struct Index Index; +typedef struct IndexedExpr IndexedExpr; +typedef struct IndexSample IndexSample; +typedef struct KeyClass KeyClass; +typedef struct KeyInfo KeyInfo; +typedef struct Lookaside Lookaside; +typedef struct LookasideSlot LookasideSlot; +typedef struct Module Module; +typedef struct NameContext NameContext; +typedef struct OnOrUsing OnOrUsing; +typedef struct Parse Parse; +typedef struct ParseCleanup ParseCleanup; +typedef struct PreUpdate PreUpdate; +typedef struct PrintfArguments PrintfArguments; +typedef struct RCStr RCStr; +typedef struct RenameToken RenameToken; +typedef struct Returning Returning; +typedef struct RowSet RowSet; +typedef struct Savepoint Savepoint; +typedef struct Select Select; +typedef struct SQLiteThread SQLiteThread; +typedef struct SelectDest SelectDest; +typedef struct Subquery Subquery; +typedef struct SrcItem SrcItem; +typedef struct SrcList SrcList; +typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */ +typedef struct Table Table; +typedef struct TableLock TableLock; +typedef struct Token Token; +typedef struct TreeView TreeView; +typedef struct Trigger Trigger; +typedef struct TriggerPrg TriggerPrg; +typedef struct TriggerStep TriggerStep; +typedef struct UnpackedRecord UnpackedRecord; +typedef struct Upsert Upsert; +typedef struct VTable VTable; +typedef struct VtabCtx VtabCtx; +typedef struct Walker Walker; +typedef struct WhereInfo WhereInfo; +typedef struct Window Window; +typedef struct With With; + + +/* +** The bitmask datatype defined below is used for various optimizations. +** +** Changing this from a 64-bit to a 32-bit type limits the number of +** tables in a join to 32 instead of 64. But it also reduces the size +** of the library by 738 bytes on ix86. +*/ +#ifdef SQLITE_BITMASK_TYPE + typedef SQLITE_BITMASK_TYPE Bitmask; +#else + typedef u64 Bitmask; +#endif + +/* +** The number of bits in a Bitmask. "BMS" means "BitMask Size". +*/ +#define BMS ((int)(sizeof(Bitmask)*8)) + +/* +** A bit in a Bitmask +*/ +#define MASKBIT(n) (((Bitmask)1)<<(n)) +#define MASKBIT64(n) (((u64)1)<<(n)) +#define MASKBIT32(n) (((unsigned int)1)<<(n)) +#define SMASKBIT32(n) ((n)<=31?((unsigned int)1)<<(n):0) +#define ALLBITS ((Bitmask)-1) +#define TOPBIT (((Bitmask)1)<<(BMS-1)) + +/* A VList object records a mapping between parameters/variables/wildcards +** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer +** variable number associated with that parameter. See the format description +** on the sqlite3VListAdd() routine for more information. A VList is really +** just an array of integers. +*/ +typedef int VList; + +/* +** Defer sourcing vdbe.h and btree.h until after the "u8" and +** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque +** pointer types (i.e. FuncDef) defined above. +*/ +/************** Include os.h in the middle of sqliteInt.h ********************/ +/************** Begin file os.h **********************************************/ +/* +** 2001 September 16 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This header file (together with is companion C source-code file +** "os.c") attempt to abstract the underlying operating system so that +** the SQLite library will work on both POSIX and windows systems. +** +** This header file is #include-ed by sqliteInt.h and thus ends up +** being included by every source file. +*/ +#ifndef _SQLITE_OS_H_ +#define _SQLITE_OS_H_ + +/* +** Attempt to automatically detect the operating system and setup the +** necessary pre-processor macros for it. +*/ +/************** Include os_setup.h in the middle of os.h *********************/ +/************** Begin file os_setup.h ****************************************/ +/* +** 2013 November 25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains pre-processor directives related to operating system +** detection and/or setup. +*/ +#ifndef SQLITE_OS_SETUP_H +#define SQLITE_OS_SETUP_H + +/* +** Figure out if we are dealing with Unix, Windows, or some other operating +** system. +** +** After the following block of preprocess macros, all of +** +** SQLITE_OS_KV +** SQLITE_OS_OTHER +** SQLITE_OS_UNIX +** SQLITE_OS_WIN +** +** will defined to either 1 or 0. One of them will be 1. The others will be 0. +** If none of the macros are initially defined, then select either +** SQLITE_OS_UNIX or SQLITE_OS_WIN depending on the target platform. +** +** If SQLITE_OS_OTHER=1 is specified at compile-time, then the application +** must provide its own VFS implementation together with sqlite3_os_init() +** and sqlite3_os_end() routines. +*/ +#if SQLITE_OS_KV+1<=1 && SQLITE_OS_OTHER+1<=1 && \ + SQLITE_OS_WIN+1<=1 && SQLITE_OS_UNIX+1<=1 +# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || \ + defined(__MINGW32__) || defined(__BORLANDC__) +# define SQLITE_OS_WIN 1 +# define SQLITE_OS_UNIX 0 +# else +# define SQLITE_OS_WIN 0 +# define SQLITE_OS_UNIX 1 +# endif +#endif +#if SQLITE_OS_OTHER+1>1 +# undef SQLITE_OS_KV +# define SQLITE_OS_KV 0 +# undef SQLITE_OS_UNIX +# define SQLITE_OS_UNIX 0 +# undef SQLITE_OS_WIN +# define SQLITE_OS_WIN 0 +#endif +#if SQLITE_OS_KV+1>1 +# undef SQLITE_OS_OTHER +# define SQLITE_OS_OTHER 0 +# undef SQLITE_OS_UNIX +# define SQLITE_OS_UNIX 0 +# undef SQLITE_OS_WIN +# define SQLITE_OS_WIN 0 +# define SQLITE_OMIT_LOAD_EXTENSION 1 +# define SQLITE_OMIT_WAL 1 +# define SQLITE_OMIT_DEPRECATED 1 +# undef SQLITE_TEMP_STORE +# define SQLITE_TEMP_STORE 3 /* Always use memory for temporary storage */ +# define SQLITE_DQS 0 +# define SQLITE_OMIT_SHARED_CACHE 1 +# define SQLITE_OMIT_AUTOINIT 1 +#endif +#if SQLITE_OS_UNIX+1>1 +# undef SQLITE_OS_KV +# define SQLITE_OS_KV 0 +# undef SQLITE_OS_OTHER +# define SQLITE_OS_OTHER 0 +# undef SQLITE_OS_WIN +# define SQLITE_OS_WIN 0 +#endif +#if SQLITE_OS_WIN+1>1 +# undef SQLITE_OS_KV +# define SQLITE_OS_KV 0 +# undef SQLITE_OS_OTHER +# define SQLITE_OS_OTHER 0 +# undef SQLITE_OS_UNIX +# define SQLITE_OS_UNIX 0 +#endif + + +#endif /* SQLITE_OS_SETUP_H */ + +/************** End of os_setup.h ********************************************/ +/************** Continuing where we left off in os.h *************************/ + +/* If the SET_FULLSYNC macro is not defined above, then make it +** a no-op +*/ +#ifndef SET_FULLSYNC +# define SET_FULLSYNC(x,y) +#endif + +/* Maximum pathname length. Note: FILENAME_MAX defined by stdio.h +*/ +#ifndef SQLITE_MAX_PATHLEN +# define SQLITE_MAX_PATHLEN FILENAME_MAX +#endif + +/* Maximum number of symlinks that will be resolved while trying to +** expand a filename in xFullPathname() in the VFS. +*/ +#ifndef SQLITE_MAX_SYMLINK +# define SQLITE_MAX_SYMLINK 200 +#endif + +/* +** The default size of a disk sector +*/ +#ifndef SQLITE_DEFAULT_SECTOR_SIZE +# define SQLITE_DEFAULT_SECTOR_SIZE 4096 +#endif + +/* +** Temporary files are named starting with this prefix followed by 16 random +** alphanumeric characters, and no file extension. They are stored in the +** OS's standard temporary file directory, and are deleted prior to exit. +** If sqlite is being embedded in another program, you may wish to change the +** prefix to reflect your program's name, so that if your program exits +** prematurely, old temporary files can be easily identified. This can be done +** using -DSQLITE_TEMP_FILE_PREFIX=myprefix_ on the compiler command line. +** +** 2006-10-31: The default prefix used to be "sqlite_". But then +** Mcafee started using SQLite in their anti-virus product and it +** started putting files with the "sqlite" name in the c:/temp folder. +** This annoyed many windows users. Those users would then do a +** Google search for "sqlite", find the telephone numbers of the +** developers and call to wake them up at night and complain. +** For this reason, the default name prefix is changed to be "sqlite" +** spelled backwards. So the temp files are still identified, but +** anybody smart enough to figure out the code is also likely smart +** enough to know that calling the developer will not help get rid +** of the file. +*/ +#ifndef SQLITE_TEMP_FILE_PREFIX +# define SQLITE_TEMP_FILE_PREFIX "etilqs_" +#endif + +/* +** The following values may be passed as the second argument to +** sqlite3OsLock(). The various locks exhibit the following semantics: +** +** SHARED: Any number of processes may hold a SHARED lock simultaneously. +** RESERVED: A single process may hold a RESERVED lock on a file at +** any time. Other processes may hold and obtain new SHARED locks. +** PENDING: A single process may hold a PENDING lock on a file at +** any one time. Existing SHARED locks may persist, but no new +** SHARED locks may be obtained by other processes. +** EXCLUSIVE: An EXCLUSIVE lock precludes all other locks. +** +** PENDING_LOCK may not be passed directly to sqlite3OsLock(). Instead, a +** process that requests an EXCLUSIVE lock may actually obtain a PENDING +** lock. This can be upgraded to an EXCLUSIVE lock by a subsequent call to +** sqlite3OsLock(). +*/ +#define NO_LOCK 0 +#define SHARED_LOCK 1 +#define RESERVED_LOCK 2 +#define PENDING_LOCK 3 +#define EXCLUSIVE_LOCK 4 + +/* +** File Locking Notes: (Mostly about windows but also some info for Unix) +** +** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because +** those functions are not available. So we use only LockFile() and +** UnlockFile(). +** +** LockFile() prevents not just writing but also reading by other processes. +** A SHARED_LOCK is obtained by locking a single randomly-chosen +** byte out of a specific range of bytes. The lock byte is obtained at +** random so two separate readers can probably access the file at the +** same time, unless they are unlucky and choose the same lock byte. +** An EXCLUSIVE_LOCK is obtained by locking all bytes in the range. +** There can only be one writer. A RESERVED_LOCK is obtained by locking +** a single byte of the file that is designated as the reserved lock byte. +** A PENDING_LOCK is obtained by locking a designated byte different from +** the RESERVED_LOCK byte. +** +** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available, +** which means we can use reader/writer locks. When reader/writer locks +** are used, the lock is placed on the same range of bytes that is used +** for probabilistic locking in Win95/98/ME. Hence, the locking scheme +** will support two or more Win95 readers or two or more WinNT readers. +** But a single Win95 reader will lock out all WinNT readers and a single +** WinNT reader will lock out all other Win95 readers. +** +** The following #defines specify the range of bytes used for locking. +** SHARED_SIZE is the number of bytes available in the pool from which +** a random byte is selected for a shared lock. The pool of bytes for +** shared locks begins at SHARED_FIRST. +** +** The same locking strategy and +** byte ranges are used for Unix. This leaves open the possibility of having +** clients on win95, winNT, and unix all talking to the same shared file +** and all locking correctly. To do so would require that samba (or whatever +** tool is being used for file sharing) implements locks correctly between +** windows and unix. I'm guessing that isn't likely to happen, but by +** using the same locking range we are at least open to the possibility. +** +** Locking in windows is manditory. For this reason, we cannot store +** actual data in the bytes used for locking. The pager never allocates +** the pages involved in locking therefore. SHARED_SIZE is selected so +** that all locks will fit on a single page even at the minimum page size. +** PENDING_BYTE defines the beginning of the locks. By default PENDING_BYTE +** is set high so that we don't have to allocate an unused page except +** for very large databases. But one should test the page skipping logic +** by setting PENDING_BYTE low and running the entire regression suite. +** +** Changing the value of PENDING_BYTE results in a subtly incompatible +** file format. Depending on how it is changed, you might not notice +** the incompatibility right away, even running a full regression test. +** The default location of PENDING_BYTE is the first byte past the +** 1GB boundary. +** +*/ +#ifdef SQLITE_OMIT_WSD +# define PENDING_BYTE (0x40000000) +#else +# define PENDING_BYTE sqlite3PendingByte +#endif +#define RESERVED_BYTE (PENDING_BYTE+1) +#define SHARED_FIRST (PENDING_BYTE+2) +#define SHARED_SIZE 510 + +/* +** Wrapper around OS specific sqlite3_os_init() function. +*/ +SQLITE_PRIVATE int sqlite3OsInit(void); + +/* +** Functions for accessing sqlite3_file methods +*/ +SQLITE_PRIVATE void sqlite3OsClose(sqlite3_file*); +SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset); +SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset); +SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file*, i64 size); +SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file*, int); +SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file*, i64 *pSize); +SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file*, int); +SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file*, int); +SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut); +SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file*,int,void*); +SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file*,int,void*); +#define SQLITE_FCNTL_DB_UNCHANGED 0xca093fa0 +SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id); +SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id); +#ifndef SQLITE_OMIT_WAL +SQLITE_PRIVATE int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **); +SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int, int, int); +SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id); +SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int); +#endif /* SQLITE_OMIT_WAL */ +SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64, int, void **); +SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *, i64, void *); + + +/* +** Functions for accessing sqlite3_vfs methods +*/ +SQLITE_PRIVATE int sqlite3OsOpen(sqlite3_vfs *, const char *, sqlite3_file*, int, int *); +SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *, const char *, int); +SQLITE_PRIVATE int sqlite3OsAccess(sqlite3_vfs *, const char *, int, int *pResOut); +SQLITE_PRIVATE int sqlite3OsFullPathname(sqlite3_vfs *, const char *, int, char *); +#ifndef SQLITE_OMIT_LOAD_EXTENSION +SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *, const char *); +SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *, int, char *); +SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *, void *, const char *))(void); +SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *, void *); +#endif /* SQLITE_OMIT_LOAD_EXTENSION */ +SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *, int, char *); +SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *, int); +SQLITE_PRIVATE int sqlite3OsGetLastError(sqlite3_vfs*); +SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*); + +/* +** Convenience functions for opening and closing files using +** sqlite3_malloc() to obtain space for the file-handle structure. +*/ +SQLITE_PRIVATE int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int,int*); +SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *); + +#endif /* _SQLITE_OS_H_ */ + +/************** End of os.h **************************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ +/************** Include pager.h in the middle of sqliteInt.h *****************/ +/************** Begin file pager.h *******************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This header file defines the interface that the sqlite page cache +** subsystem. The page cache subsystem reads and writes a file a page +** at a time and provides a journal for rollback. +*/ + +#ifndef SQLITE_PAGER_H +#define SQLITE_PAGER_H + +/* +** Default maximum size for persistent journal files. A negative +** value means no limit. This value may be overridden using the +** sqlite3PagerJournalSizeLimit() API. See also "PRAGMA journal_size_limit". +*/ +#ifndef SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT + #define SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT -1 +#endif + +/* +** The type used to represent a page number. The first page in a file +** is called page 1. 0 is used to represent "not a page". +*/ +typedef u32 Pgno; + +/* +** Each open file is managed by a separate instance of the "Pager" structure. +*/ +typedef struct Pager Pager; + +/* +** Handle type for pages. +*/ +typedef struct PgHdr DbPage; + +/* +** Page number PAGER_SJ_PGNO is never used in an SQLite database (it is +** reserved for working around a windows/posix incompatibility). It is +** used in the journal to signify that the remainder of the journal file +** is devoted to storing a super-journal name - there are no more pages to +** roll back. See comments for function writeSuperJournal() in pager.c +** for details. +*/ +#define PAGER_SJ_PGNO_COMPUTED(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1)) +#define PAGER_SJ_PGNO(x) ((x)->lckPgno) + +/* +** Allowed values for the flags parameter to sqlite3PagerOpen(). +** +** NOTE: These values must match the corresponding BTREE_ values in btree.h. +*/ +#define PAGER_OMIT_JOURNAL 0x0001 /* Do not use a rollback journal */ +#define PAGER_MEMORY 0x0002 /* In-memory database */ + +/* +** Valid values for the second argument to sqlite3PagerLockingMode(). +*/ +#define PAGER_LOCKINGMODE_QUERY -1 +#define PAGER_LOCKINGMODE_NORMAL 0 +#define PAGER_LOCKINGMODE_EXCLUSIVE 1 + +/* +** Numeric constants that encode the journalmode. +** +** The numeric values encoded here (other than PAGER_JOURNALMODE_QUERY) +** are exposed in the API via the "PRAGMA journal_mode" command and +** therefore cannot be changed without a compatibility break. +*/ +#define PAGER_JOURNALMODE_QUERY (-1) /* Query the value of journalmode */ +#define PAGER_JOURNALMODE_DELETE 0 /* Commit by deleting journal file */ +#define PAGER_JOURNALMODE_PERSIST 1 /* Commit by zeroing journal header */ +#define PAGER_JOURNALMODE_OFF 2 /* Journal omitted. */ +#define PAGER_JOURNALMODE_TRUNCATE 3 /* Commit by truncating journal */ +#define PAGER_JOURNALMODE_MEMORY 4 /* In-memory journal file */ +#define PAGER_JOURNALMODE_WAL 5 /* Use write-ahead logging */ + +#define isWalMode(x) ((x)==PAGER_JOURNALMODE_WAL) + +/* +** The argument to this macro is a file descriptor (type sqlite3_file*). +** Return 0 if it is not open, or non-zero (but not 1) if it is. +** +** This is so that expressions can be written as: +** +** if( isOpen(pPager->jfd) ){ ... +** +** instead of +** +** if( pPager->jfd->pMethods ){ ... +*/ +#define isOpen(pFd) ((pFd)->pMethods!=0) + +/* +** Flags that make up the mask passed to sqlite3PagerGet(). +*/ +#define PAGER_GET_NOCONTENT 0x01 /* Do not load data from disk */ +#define PAGER_GET_READONLY 0x02 /* Read-only page is acceptable */ + +/* +** Flags for sqlite3PagerSetFlags() +** +** Value constraints (enforced via assert()): +** PAGER_FULLFSYNC == SQLITE_FullFSync +** PAGER_CKPT_FULLFSYNC == SQLITE_CkptFullFSync +** PAGER_CACHE_SPILL == SQLITE_CacheSpill +*/ +#define PAGER_SYNCHRONOUS_OFF 0x01 /* PRAGMA synchronous=OFF */ +#define PAGER_SYNCHRONOUS_NORMAL 0x02 /* PRAGMA synchronous=NORMAL */ +#define PAGER_SYNCHRONOUS_FULL 0x03 /* PRAGMA synchronous=FULL */ +#define PAGER_SYNCHRONOUS_EXTRA 0x04 /* PRAGMA synchronous=EXTRA */ +#define PAGER_SYNCHRONOUS_MASK 0x07 /* Mask for four values above */ +#define PAGER_FULLFSYNC 0x08 /* PRAGMA fullfsync=ON */ +#define PAGER_CKPT_FULLFSYNC 0x10 /* PRAGMA checkpoint_fullfsync=ON */ +#define PAGER_CACHESPILL 0x20 /* PRAGMA cache_spill=ON */ +#define PAGER_FLAGS_MASK 0x38 /* All above except SYNCHRONOUS */ + +/* +** The remainder of this file contains the declarations of the functions +** that make up the Pager sub-system API. See source code comments for +** a detailed description of each routine. +*/ + +/* Open and close a Pager connection. */ +SQLITE_PRIVATE int sqlite3PagerOpen( + sqlite3_vfs*, + Pager **ppPager, + const char*, + int, + int, + int, + void(*)(DbPage*) +); +SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3*); +SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager*, int, unsigned char*); + +/* Functions used to configure a Pager object. */ +SQLITE_PRIVATE void sqlite3PagerSetBusyHandler(Pager*, int(*)(void *), void *); +SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u32*, int); +SQLITE_PRIVATE Pgno sqlite3PagerMaxPageCount(Pager*, Pgno); +SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager*, int); +SQLITE_PRIVATE int sqlite3PagerSetSpillsize(Pager*, int); +SQLITE_PRIVATE void sqlite3PagerSetMmapLimit(Pager *, sqlite3_int64); +SQLITE_PRIVATE void sqlite3PagerShrink(Pager*); +SQLITE_PRIVATE void sqlite3PagerSetFlags(Pager*,unsigned); +SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *, int); +SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *, int); +SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager*); +SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager*); +SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *, i64); +SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager*); +SQLITE_PRIVATE int sqlite3PagerFlush(Pager*); + +/* Functions used to obtain and release page references. */ +SQLITE_PRIVATE int sqlite3PagerGet(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag); +SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno); +SQLITE_PRIVATE void sqlite3PagerRef(DbPage*); +SQLITE_PRIVATE void sqlite3PagerUnref(DbPage*); +SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage*); +SQLITE_PRIVATE void sqlite3PagerUnrefPageOne(DbPage*); + +/* Operations on page references. */ +SQLITE_PRIVATE int sqlite3PagerWrite(DbPage*); +SQLITE_PRIVATE void sqlite3PagerDontWrite(DbPage*); +SQLITE_PRIVATE int sqlite3PagerMovepage(Pager*,DbPage*,Pgno,int); +SQLITE_PRIVATE int sqlite3PagerPageRefcount(DbPage*); +SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *); +SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *); + +/* Functions used to manage pager transactions and savepoints. */ +SQLITE_PRIVATE void sqlite3PagerPagecount(Pager*, int*); +SQLITE_PRIVATE int sqlite3PagerBegin(Pager*, int exFlag, int); +SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(Pager*,const char *zSuper, int); +SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager*); +SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager, const char *zSuper); +SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager*); +SQLITE_PRIVATE int sqlite3PagerRollback(Pager*); +SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int n); +SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint); +SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager); + +#ifndef SQLITE_OMIT_WAL +SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, sqlite3*, int, int*, int*); +SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager); +SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager); +SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen); +SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3*); +# ifdef SQLITE_ENABLE_SNAPSHOT +SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager*, sqlite3_snapshot **ppSnapshot); +SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager*, sqlite3_snapshot *pSnapshot); +SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager); +SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot); +SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager); +# endif +#endif + +#if !defined(SQLITE_OMIT_WAL) && defined(SQLITE_ENABLE_SETLK_TIMEOUT) +SQLITE_PRIVATE int sqlite3PagerWalWriteLock(Pager*, int); +SQLITE_PRIVATE void sqlite3PagerWalDb(Pager*, sqlite3*); +#else +# define sqlite3PagerWalWriteLock(y,z) SQLITE_OK +# define sqlite3PagerWalDb(x,y) +#endif + +#ifdef SQLITE_DIRECT_OVERFLOW_READ +SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno); +#endif + +#ifdef SQLITE_ENABLE_ZIPVFS +SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager); +#endif + +/* Functions used to query pager state and configuration. */ +SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager*); +SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager*); +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*); +#endif +SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager*); +SQLITE_PRIVATE const char *sqlite3PagerFilename(const Pager*, int); +SQLITE_PRIVATE sqlite3_vfs *sqlite3PagerVfs(Pager*); +SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*); +SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager*); +SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*); +SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*); +SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*); +SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, u64*); +SQLITE_PRIVATE void sqlite3PagerClearCache(Pager*); +SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *); + +/* Functions used to truncate the database file. */ +SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno); + +SQLITE_PRIVATE void sqlite3PagerRekey(DbPage*, Pgno, u16); + +/* Functions to support testing and debugging. */ +#if !defined(NDEBUG) || defined(SQLITE_TEST) +SQLITE_PRIVATE Pgno sqlite3PagerPagenumber(DbPage*); +SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage*); +#endif +#ifdef SQLITE_TEST +SQLITE_PRIVATE int *sqlite3PagerStats(Pager*); +SQLITE_PRIVATE void sqlite3PagerRefdump(Pager*); + void disable_simulated_io_errors(void); + void enable_simulated_io_errors(void); +#else +# define disable_simulated_io_errors() +# define enable_simulated_io_errors() +#endif + +#if defined(SQLITE_USE_SEH) && !defined(SQLITE_OMIT_WAL) +SQLITE_PRIVATE int sqlite3PagerWalSystemErrno(Pager*); +#endif + +#endif /* SQLITE_PAGER_H */ + +/************** End of pager.h ***********************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ +/************** Include btree.h in the middle of sqliteInt.h *****************/ +/************** Begin file btree.h *******************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This header file defines the interface that the sqlite B-Tree file +** subsystem. See comments in the source code for a detailed description +** of what each interface routine does. +*/ +#ifndef SQLITE_BTREE_H +#define SQLITE_BTREE_H + +/* TODO: This definition is just included so other modules compile. It +** needs to be revisited. +*/ +#define SQLITE_N_BTREE_META 16 + +/* +** If defined as non-zero, auto-vacuum is enabled by default. Otherwise +** it must be turned on for each database using "PRAGMA auto_vacuum = 1". +*/ +#ifndef SQLITE_DEFAULT_AUTOVACUUM + #define SQLITE_DEFAULT_AUTOVACUUM 0 +#endif + +#define BTREE_AUTOVACUUM_NONE 0 /* Do not do auto-vacuum */ +#define BTREE_AUTOVACUUM_FULL 1 /* Do full auto-vacuum */ +#define BTREE_AUTOVACUUM_INCR 2 /* Incremental vacuum */ + +/* +** Forward declarations of structure +*/ +typedef struct Btree Btree; +typedef struct BtCursor BtCursor; +typedef struct BtShared BtShared; +typedef struct BtreePayload BtreePayload; + + +SQLITE_PRIVATE int sqlite3BtreeOpen( + sqlite3_vfs *pVfs, /* VFS to use with this b-tree */ + const char *zFilename, /* Name of database file to open */ + sqlite3 *db, /* Associated database connection */ + Btree **ppBtree, /* Return open Btree* here */ + int flags, /* Flags */ + int vfsFlags /* Flags passed through to VFS open */ +); + +/* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the +** following values. +** +** NOTE: These values must match the corresponding PAGER_ values in +** pager.h. +*/ +#define BTREE_OMIT_JOURNAL 1 /* Do not create or use a rollback journal */ +#define BTREE_MEMORY 2 /* This is an in-memory DB */ +#define BTREE_SINGLE 4 /* The file contains at most 1 b-tree */ +#define BTREE_UNORDERED 8 /* Use of a hash implementation is OK */ + +SQLITE_PRIVATE int sqlite3BtreeClose(Btree*); +SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int); +SQLITE_PRIVATE int sqlite3BtreeSetSpillSize(Btree*,int); +#if SQLITE_MAX_MMAP_SIZE>0 +SQLITE_PRIVATE int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64); +#endif +SQLITE_PRIVATE int sqlite3BtreeSetPagerFlags(Btree*,unsigned); +SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix); +SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*); +SQLITE_PRIVATE Pgno sqlite3BtreeMaxPageCount(Btree*,Pgno); +SQLITE_PRIVATE Pgno sqlite3BtreeLastPage(Btree*); +SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree*,int); +SQLITE_PRIVATE int sqlite3BtreeGetRequestedReserve(Btree*); +SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p); +SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *, int); +SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *); +SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int,int*); +SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree*, const char*); +SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree*, int); +SQLITE_PRIVATE int sqlite3BtreeCommit(Btree*); +SQLITE_PRIVATE int sqlite3BtreeRollback(Btree*,int,int); +SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree*,int); +SQLITE_PRIVATE int sqlite3BtreeCreateTable(Btree*, Pgno*, int flags); +SQLITE_PRIVATE int sqlite3BtreeTxnState(Btree*); +SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree*); + +SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *, int, void(*)(void *)); +SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *pBtree); +#ifndef SQLITE_OMIT_SHARED_CACHE +SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock); +#endif + +/* Savepoints are named, nestable SQL transactions mostly implemented */ +/* in vdbe.c and pager.c See https://sqlite.org/lang_savepoint.html */ +SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *, int, int); + +/* "Checkpoint" only refers to WAL. See https://sqlite.org/wal.html#ckpt */ +#ifndef SQLITE_OMIT_WAL +SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree*, int, int *, int *); +#endif + +SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *); +SQLITE_PRIVATE const char *sqlite3BtreeGetJournalname(Btree *); +SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree*, Btree*); + +SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *); + +/* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR +** of the flags shown below. +** +** Every SQLite table must have either BTREE_INTKEY or BTREE_BLOBKEY set. +** With BTREE_INTKEY, the table key is a 64-bit integer and arbitrary data +** is stored in the leaves. (BTREE_INTKEY is used for SQL tables.) With +** BTREE_BLOBKEY, the key is an arbitrary BLOB and no content is stored +** anywhere - the key is the content. (BTREE_BLOBKEY is used for SQL +** indices.) +*/ +#define BTREE_INTKEY 1 /* Table has only 64-bit signed integer keys */ +#define BTREE_BLOBKEY 2 /* Table has keys only - no data */ + +SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree*, int, int*); +SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree*, int, i64*); +SQLITE_PRIVATE int sqlite3BtreeClearTableOfCursor(BtCursor*); +SQLITE_PRIVATE int sqlite3BtreeTripAllCursors(Btree*, int, int); + +SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue); +SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value); + +SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p); + +/* +** The second parameter to sqlite3BtreeGetMeta or sqlite3BtreeUpdateMeta +** should be one of the following values. The integer values are assigned +** to constants so that the offset of the corresponding field in an +** SQLite database header may be found using the following formula: +** +** offset = 36 + (idx * 4) +** +** For example, the free-page-count field is located at byte offset 36 of +** the database file header. The incr-vacuum-flag field is located at +** byte offset 64 (== 36+4*7). +** +** The BTREE_DATA_VERSION value is not really a value stored in the header. +** It is a read-only number computed by the pager. But we merge it with +** the header value access routines since its access pattern is the same. +** Call it a "virtual meta value". +*/ +#define BTREE_FREE_PAGE_COUNT 0 +#define BTREE_SCHEMA_VERSION 1 +#define BTREE_FILE_FORMAT 2 +#define BTREE_DEFAULT_CACHE_SIZE 3 +#define BTREE_LARGEST_ROOT_PAGE 4 +#define BTREE_TEXT_ENCODING 5 +#define BTREE_USER_VERSION 6 +#define BTREE_INCR_VACUUM 7 +#define BTREE_APPLICATION_ID 8 +#define BTREE_DATA_VERSION 15 /* A virtual meta-value */ + +/* +** Kinds of hints that can be passed into the sqlite3BtreeCursorHint() +** interface. +** +** BTREE_HINT_RANGE (arguments: Expr*, Mem*) +** +** The first argument is an Expr* (which is guaranteed to be constant for +** the lifetime of the cursor) that defines constraints on which rows +** might be fetched with this cursor. The Expr* tree may contain +** TK_REGISTER nodes that refer to values stored in the array of registers +** passed as the second parameter. In other words, if Expr.op==TK_REGISTER +** then the value of the node is the value in Mem[pExpr.iTable]. Any +** TK_COLUMN node in the expression tree refers to the Expr.iColumn-th +** column of the b-tree of the cursor. The Expr tree will not contain +** any function calls nor subqueries nor references to b-trees other than +** the cursor being hinted. +** +** The design of the _RANGE hint is aid b-tree implementations that try +** to prefetch content from remote machines - to provide those +** implementations with limits on what needs to be prefetched and thereby +** reduce network bandwidth. +** +** Note that BTREE_HINT_FLAGS with BTREE_BULKLOAD is the only hint used by +** standard SQLite. The other hints are provided for extensions that use +** the SQLite parser and code generator but substitute their own storage +** engine. +*/ +#define BTREE_HINT_RANGE 0 /* Range constraints on queries */ + +/* +** Values that may be OR'd together to form the argument to the +** BTREE_HINT_FLAGS hint for sqlite3BtreeCursorHint(): +** +** The BTREE_BULKLOAD flag is set on index cursors when the index is going +** to be filled with content that is already in sorted order. +** +** The BTREE_SEEK_EQ flag is set on cursors that will get OP_SeekGE or +** OP_SeekLE opcodes for a range search, but where the range of entries +** selected will all have the same key. In other words, the cursor will +** be used only for equality key searches. +** +*/ +#define BTREE_BULKLOAD 0x00000001 /* Used to full index in sorted order */ +#define BTREE_SEEK_EQ 0x00000002 /* EQ seeks only - no range seeks */ + +/* +** Flags passed as the third argument to sqlite3BtreeCursor(). +** +** For read-only cursors the wrFlag argument is always zero. For read-write +** cursors it may be set to either (BTREE_WRCSR|BTREE_FORDELETE) or just +** (BTREE_WRCSR). If the BTREE_FORDELETE bit is set, then the cursor will +** only be used by SQLite for the following: +** +** * to seek to and then delete specific entries, and/or +** +** * to read values that will be used to create keys that other +** BTREE_FORDELETE cursors will seek to and delete. +** +** The BTREE_FORDELETE flag is an optimization hint. It is not used by +** by this, the native b-tree engine of SQLite, but it is available to +** alternative storage engines that might be substituted in place of this +** b-tree system. For alternative storage engines in which a delete of +** the main table row automatically deletes corresponding index rows, +** the FORDELETE flag hint allows those alternative storage engines to +** skip a lot of work. Namely: FORDELETE cursors may treat all SEEK +** and DELETE operations as no-ops, and any READ operation against a +** FORDELETE cursor may return a null row: 0x01 0x00. +*/ +#define BTREE_WRCSR 0x00000004 /* read-write cursor */ +#define BTREE_FORDELETE 0x00000008 /* Cursor is for seek/delete only */ + +SQLITE_PRIVATE int sqlite3BtreeCursor( + Btree*, /* BTree containing table to open */ + Pgno iTable, /* Index of root page */ + int wrFlag, /* 1 for writing. 0 for read-only */ + struct KeyInfo*, /* First argument to compare function */ + BtCursor *pCursor /* Space to write cursor structure */ +); +SQLITE_PRIVATE BtCursor *sqlite3BtreeFakeValidCursor(void); +SQLITE_PRIVATE int sqlite3BtreeCursorSize(void); +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3BtreeClosesWithCursor(Btree*,BtCursor*); +#endif +SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor*); +SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned); +#ifdef SQLITE_ENABLE_CURSOR_HINTS +SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor*, int, ...); +#endif + +SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor*); +SQLITE_PRIVATE int sqlite3BtreeTableMoveto( + BtCursor*, + i64 intKey, + int bias, + int *pRes +); +SQLITE_PRIVATE int sqlite3BtreeIndexMoveto( + BtCursor*, + UnpackedRecord *pUnKey, + int *pRes +); +SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor*); +SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor*, int*); +SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*, u8 flags); + +/* Allowed flags for sqlite3BtreeDelete() and sqlite3BtreeInsert() */ +#define BTREE_SAVEPOSITION 0x02 /* Leave cursor pointing at NEXT or PREV */ +#define BTREE_AUXDELETE 0x04 /* not the primary delete operation */ +#define BTREE_APPEND 0x08 /* Insert is likely an append */ +#define BTREE_PREFORMAT 0x80 /* Inserted data is a preformated cell */ + +/* An instance of the BtreePayload object describes the content of a single +** entry in either an index or table btree. +** +** Index btrees (used for indexes and also WITHOUT ROWID tables) contain +** an arbitrary key and no data. These btrees have pKey,nKey set to the +** key and the pData,nData,nZero fields are uninitialized. The aMem,nMem +** fields give an array of Mem objects that are a decomposition of the key. +** The nMem field might be zero, indicating that no decomposition is available. +** +** Table btrees (used for rowid tables) contain an integer rowid used as +** the key and passed in the nKey field. The pKey field is zero. +** pData,nData hold the content of the new entry. nZero extra zero bytes +** are appended to the end of the content when constructing the entry. +** The aMem,nMem fields are uninitialized for table btrees. +** +** Field usage summary: +** +** Table BTrees Index Btrees +** +** pKey always NULL encoded key +** nKey the ROWID length of pKey +** pData data not used +** aMem not used decomposed key value +** nMem not used entries in aMem +** nData length of pData not used +** nZero extra zeros after pData not used +** +** This object is used to pass information into sqlite3BtreeInsert(). The +** same information used to be passed as five separate parameters. But placing +** the information into this object helps to keep the interface more +** organized and understandable, and it also helps the resulting code to +** run a little faster by using fewer registers for parameter passing. +*/ +struct BtreePayload { + const void *pKey; /* Key content for indexes. NULL for tables */ + sqlite3_int64 nKey; /* Size of pKey for indexes. PRIMARY KEY for tabs */ + const void *pData; /* Data for tables. */ + sqlite3_value *aMem; /* First of nMem value in the unpacked pKey */ + u16 nMem; /* Number of aMem[] value. Might be zero */ + int nData; /* Size of pData. 0 if none. */ + int nZero; /* Extra zero data appended after pData,nData */ +}; + +SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload, + int flags, int seekResult); +SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor*, int *pRes); +SQLITE_PRIVATE int sqlite3BtreeIsEmpty(BtCursor *pCur, int *pRes); +SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor*, int *pRes); +SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int flags); +SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*); +SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int flags); +SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor*); +SQLITE_PRIVATE void sqlite3BtreeCursorPin(BtCursor*); +SQLITE_PRIVATE void sqlite3BtreeCursorUnpin(BtCursor*); +SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor*); +SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*); +SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt); +SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor*); +SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor*); + +SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( + sqlite3 *db, /* Database connection that is running the check */ + Btree *p, /* The btree to be checked */ + Pgno *aRoot, /* An array of root pages numbers for individual trees */ + sqlite3_value *aCnt, /* OUT: entry counts for each btree in aRoot[] */ + int nRoot, /* Number of entries in aRoot[] */ + int mxErr, /* Stop reporting errors after this many */ + int *pnErr, /* OUT: Write number of errors seen to this variable */ + char **pzOut /* OUT: Write the error message string here */ +); +SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*); +SQLITE_PRIVATE i64 sqlite3BtreeRowCountEst(BtCursor*); + +#ifndef SQLITE_OMIT_INCRBLOB +SQLITE_PRIVATE int sqlite3BtreePayloadChecked(BtCursor*, u32 offset, u32 amt, void*); +SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*); +SQLITE_PRIVATE void sqlite3BtreeIncrblobCursor(BtCursor *); +#endif +SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *); +SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion); +SQLITE_PRIVATE int sqlite3BtreeCursorHasHint(BtCursor*, unsigned int mask); +SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *pBt); +SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void); + +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE sqlite3_uint64 sqlite3BtreeSeekCount(Btree*); +#else +# define sqlite3BtreeSeekCount(X) 0 +#endif + +#ifndef NDEBUG +SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*); +#endif +SQLITE_PRIVATE int sqlite3BtreeCursorIsValidNN(BtCursor*); + +SQLITE_PRIVATE int sqlite3BtreeCount(sqlite3*, BtCursor*, i64*); + +#ifdef SQLITE_TEST +SQLITE_PRIVATE int sqlite3BtreeCursorInfo(BtCursor*, int*, int); +SQLITE_PRIVATE void sqlite3BtreeCursorList(Btree*); +#endif + +#ifndef SQLITE_OMIT_WAL +SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree*, int, int *, int *); +#endif + +SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor*, BtCursor*, i64); + +SQLITE_PRIVATE void sqlite3BtreeClearCache(Btree*); + +/* +** If we are not using shared cache, then there is no need to +** use mutexes to access the BtShared structures. So make the +** Enter and Leave procedures no-ops. +*/ +#ifndef SQLITE_OMIT_SHARED_CACHE +SQLITE_PRIVATE void sqlite3BtreeEnter(Btree*); +SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3*); +SQLITE_PRIVATE int sqlite3BtreeSharable(Btree*); +SQLITE_PRIVATE void sqlite3BtreeEnterCursor(BtCursor*); +SQLITE_PRIVATE int sqlite3BtreeConnectionCount(Btree*); +#else +# define sqlite3BtreeEnter(X) +# define sqlite3BtreeEnterAll(X) +# define sqlite3BtreeSharable(X) 0 +# define sqlite3BtreeEnterCursor(X) +# define sqlite3BtreeConnectionCount(X) 1 +#endif + +#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE +SQLITE_PRIVATE void sqlite3BtreeLeave(Btree*); +SQLITE_PRIVATE void sqlite3BtreeLeaveCursor(BtCursor*); +SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3*); +#ifndef NDEBUG + /* These routines are used inside assert() statements only. */ +SQLITE_PRIVATE int sqlite3BtreeHoldsMutex(Btree*); +SQLITE_PRIVATE int sqlite3BtreeHoldsAllMutexes(sqlite3*); +SQLITE_PRIVATE int sqlite3SchemaMutexHeld(sqlite3*,int,Schema*); +#endif +#else + +# define sqlite3BtreeLeave(X) +# define sqlite3BtreeLeaveCursor(X) +# define sqlite3BtreeLeaveAll(X) + +# define sqlite3BtreeHoldsMutex(X) 1 +# define sqlite3BtreeHoldsAllMutexes(X) 1 +# define sqlite3SchemaMutexHeld(X,Y,Z) 1 +#endif + + +#endif /* SQLITE_BTREE_H */ + +/************** End of btree.h ***********************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ +/************** Include vdbe.h in the middle of sqliteInt.h ******************/ +/************** Begin file vdbe.h ********************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** Header file for the Virtual DataBase Engine (VDBE) +** +** This header defines the interface to the virtual database engine +** or VDBE. The VDBE implements an abstract machine that runs a +** simple program to access and modify the underlying database. +*/ +#ifndef SQLITE_VDBE_H +#define SQLITE_VDBE_H +/* #include */ + +/* +** A single VDBE is an opaque structure named "Vdbe". Only routines +** in the source file sqliteVdbe.c are allowed to see the insides +** of this structure. +*/ +typedef struct Vdbe Vdbe; + +/* +** The names of the following types declared in vdbeInt.h are required +** for the VdbeOp definition. +*/ +typedef struct sqlite3_value Mem; +typedef struct SubProgram SubProgram; +typedef struct SubrtnSig SubrtnSig; + +/* +** A signature for a reusable subroutine that materializes the RHS of +** an IN operator. +*/ +struct SubrtnSig { + int selId; /* SELECT-id for the SELECT statement on the RHS */ + u8 bComplete; /* True if fully coded and available for reusable */ + char *zAff; /* Affinity of the overall IN expression */ + int iTable; /* Ephemeral table generated by the subroutine */ + int iAddr; /* Subroutine entry address */ + int regReturn; /* Register used to hold return address */ +}; + +/* +** A single instruction of the virtual machine has an opcode +** and as many as three operands. The instruction is recorded +** as an instance of the following structure: +*/ +struct VdbeOp { + u8 opcode; /* What operation to perform */ + signed char p4type; /* One of the P4_xxx constants for p4 */ + u16 p5; /* Fifth parameter is an unsigned 16-bit integer */ + int p1; /* First operand */ + int p2; /* Second parameter (often the jump destination) */ + int p3; /* The third parameter */ + union p4union { /* fourth parameter */ + int i; /* Integer value if p4type==P4_INT32 */ + void *p; /* Generic pointer */ + char *z; /* Pointer to data for string (char array) types */ + i64 *pI64; /* Used when p4type is P4_INT64 */ + double *pReal; /* Used when p4type is P4_REAL */ + FuncDef *pFunc; /* Used when p4type is P4_FUNCDEF */ + sqlite3_context *pCtx; /* Used when p4type is P4_FUNCCTX */ + CollSeq *pColl; /* Used when p4type is P4_COLLSEQ */ + Mem *pMem; /* Used when p4type is P4_MEM */ + VTable *pVtab; /* Used when p4type is P4_VTAB */ + KeyInfo *pKeyInfo; /* Used when p4type is P4_KEYINFO */ + u32 *ai; /* Used when p4type is P4_INTARRAY */ + SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */ + Table *pTab; /* Used when p4type is P4_TABLE */ + SubrtnSig *pSubrtnSig; /* Used when p4type is P4_SUBRTNSIG */ + Index *pIdx; /* Used when p4type is P4_INDEX */ +#ifdef SQLITE_ENABLE_CURSOR_HINTS + Expr *pExpr; /* Used when p4type is P4_EXPR */ +#endif + } p4; +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + char *zComment; /* Comment to improve readability */ +#endif +#ifdef SQLITE_VDBE_COVERAGE + u32 iSrcLine; /* Source-code line that generated this opcode + ** with flags in the upper 8 bits */ +#endif +#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) + u64 nExec; + u64 nCycle; +#endif +}; +typedef struct VdbeOp VdbeOp; + + +/* +** A sub-routine used to implement a trigger program. +*/ +struct SubProgram { + VdbeOp *aOp; /* Array of opcodes for sub-program */ + int nOp; /* Elements in aOp[] */ + int nMem; /* Number of memory cells required */ + int nCsr; /* Number of cursors required */ + u8 *aOnce; /* Array of OP_Once flags */ + void *token; /* id that may be used to recursive triggers */ + SubProgram *pNext; /* Next sub-program already visited */ +}; + +/* +** A smaller version of VdbeOp used for the VdbeAddOpList() function because +** it takes up less space. +*/ +struct VdbeOpList { + u8 opcode; /* What operation to perform */ + signed char p1; /* First operand */ + signed char p2; /* Second parameter (often the jump destination) */ + signed char p3; /* Third parameter */ +}; +typedef struct VdbeOpList VdbeOpList; + +/* +** Allowed values of VdbeOp.p4type +*/ +#define P4_NOTUSED 0 /* The P4 parameter is not used */ +#define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */ +#define P4_STATIC (-1) /* Pointer to a static string */ +#define P4_COLLSEQ (-2) /* P4 is a pointer to a CollSeq structure */ +#define P4_INT32 (-3) /* P4 is a 32-bit signed integer */ +#define P4_SUBPROGRAM (-4) /* P4 is a pointer to a SubProgram structure */ +#define P4_TABLE (-5) /* P4 is a pointer to a Table structure */ +#define P4_INDEX (-6) /* P4 is a pointer to an Index structure */ +/* Above do not own any resources. Must free those below */ +#define P4_FREE_IF_LE (-7) +#define P4_DYNAMIC (-7) /* Pointer to memory from sqliteMalloc() */ +#define P4_FUNCDEF (-8) /* P4 is a pointer to a FuncDef structure */ +#define P4_KEYINFO (-9) /* P4 is a pointer to a KeyInfo structure */ +#define P4_EXPR (-10) /* P4 is a pointer to an Expr tree */ +#define P4_MEM (-11) /* P4 is a pointer to a Mem* structure */ +#define P4_VTAB (-12) /* P4 is a pointer to an sqlite3_vtab structure */ +#define P4_REAL (-13) /* P4 is a 64-bit floating point value */ +#define P4_INT64 (-14) /* P4 is a 64-bit signed integer */ +#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */ +#define P4_FUNCCTX (-16) /* P4 is a pointer to an sqlite3_context object */ +#define P4_TABLEREF (-17) /* Like P4_TABLE, but reference counted */ +#define P4_SUBRTNSIG (-18) /* P4 is a SubrtnSig pointer */ + +/* Error message codes for OP_Halt */ +#define P5_ConstraintNotNull 1 +#define P5_ConstraintUnique 2 +#define P5_ConstraintCheck 3 +#define P5_ConstraintFK 4 + +/* +** The Vdbe.aColName array contains 5n Mem structures, where n is the +** number of columns of data returned by the statement. +*/ +#define COLNAME_NAME 0 +#define COLNAME_DECLTYPE 1 +#define COLNAME_DATABASE 2 +#define COLNAME_TABLE 3 +#define COLNAME_COLUMN 4 +#ifdef SQLITE_ENABLE_COLUMN_METADATA +# define COLNAME_N 5 /* Number of COLNAME_xxx symbols */ +#else +# ifdef SQLITE_OMIT_DECLTYPE +# define COLNAME_N 1 /* Store only the name */ +# else +# define COLNAME_N 2 /* Store the name and decltype */ +# endif +#endif + +/* +** The following macro converts a label returned by sqlite3VdbeMakeLabel() +** into an index into the Parse.aLabel[] array that contains the resolved +** address of that label. +*/ +#define ADDR(X) (~(X)) + +/* +** The makefile scans the vdbe.c source file and creates the "opcodes.h" +** header file that defines a number for each opcode used by the VDBE. +*/ +/************** Include opcodes.h in the middle of vdbe.h ********************/ +/************** Begin file opcodes.h *****************************************/ +/* Automatically generated. Do not edit */ +/* See the tool/mkopcodeh.tcl script for details */ +#define OP_Savepoint 0 +#define OP_AutoCommit 1 +#define OP_Transaction 2 +#define OP_Checkpoint 3 +#define OP_JournalMode 4 +#define OP_Vacuum 5 +#define OP_VFilter 6 /* jump, synopsis: iplan=r[P3] zplan='P4' */ +#define OP_VUpdate 7 /* synopsis: data=r[P3@P2] */ +#define OP_Init 8 /* jump0, synopsis: Start at P2 */ +#define OP_Goto 9 /* jump */ +#define OP_Gosub 10 /* jump */ +#define OP_InitCoroutine 11 /* jump0 */ +#define OP_Yield 12 /* jump0 */ +#define OP_MustBeInt 13 /* jump0 */ +#define OP_Jump 14 /* jump */ +#define OP_Once 15 /* jump */ +#define OP_If 16 /* jump */ +#define OP_IfNot 17 /* jump */ +#define OP_IsType 18 /* jump, synopsis: if typeof(P1.P3) in P5 goto P2 */ +#define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */ +#define OP_IfNullRow 20 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */ +#define OP_SeekLT 21 /* jump0, synopsis: key=r[P3@P4] */ +#define OP_SeekLE 22 /* jump0, synopsis: key=r[P3@P4] */ +#define OP_SeekGE 23 /* jump0, synopsis: key=r[P3@P4] */ +#define OP_SeekGT 24 /* jump0, synopsis: key=r[P3@P4] */ +#define OP_IfNotOpen 25 /* jump, synopsis: if( !csr[P1] ) goto P2 */ +#define OP_IfNoHope 26 /* jump, synopsis: key=r[P3@P4] */ +#define OP_NoConflict 27 /* jump, synopsis: key=r[P3@P4] */ +#define OP_NotFound 28 /* jump, synopsis: key=r[P3@P4] */ +#define OP_Found 29 /* jump, synopsis: key=r[P3@P4] */ +#define OP_SeekRowid 30 /* jump0, synopsis: intkey=r[P3] */ +#define OP_NotExists 31 /* jump, synopsis: intkey=r[P3] */ +#define OP_Last 32 /* jump0 */ +#define OP_IfSizeBetween 33 /* jump */ +#define OP_SorterSort 34 /* jump */ +#define OP_Sort 35 /* jump */ +#define OP_Rewind 36 /* jump0 */ +#define OP_IfEmpty 37 /* jump, synopsis: if( empty(P1) ) goto P2 */ +#define OP_SorterNext 38 /* jump */ +#define OP_Prev 39 /* jump */ +#define OP_Next 40 /* jump */ +#define OP_IdxLE 41 /* jump, synopsis: key=r[P3@P4] */ +#define OP_IdxGT 42 /* jump, synopsis: key=r[P3@P4] */ +#define OP_Or 43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ +#define OP_And 44 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ +#define OP_IdxLT 45 /* jump, synopsis: key=r[P3@P4] */ +#define OP_IdxGE 46 /* jump, synopsis: key=r[P3@P4] */ +#define OP_IFindKey 47 /* jump */ +#define OP_RowSetRead 48 /* jump, synopsis: r[P3]=rowset(P1) */ +#define OP_RowSetTest 49 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ +#define OP_Program 50 /* jump0 */ +#define OP_IsNull 51 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ +#define OP_NotNull 52 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ +#define OP_Ne 53 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */ +#define OP_Eq 54 /* jump, same as TK_EQ, synopsis: IF r[P3]==r[P1] */ +#define OP_Gt 55 /* jump, same as TK_GT, synopsis: IF r[P3]>r[P1] */ +#define OP_Le 56 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */ +#define OP_Lt 57 /* jump, same as TK_LT, synopsis: IF r[P3]=r[P1] */ +#define OP_ElseEq 59 /* jump, same as TK_ESCAPE */ +#define OP_FkIfZero 60 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ +#define OP_IfPos 61 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ +#define OP_IfNotZero 62 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ +#define OP_DecrJumpZero 63 /* jump, synopsis: if (--r[P1])==0 goto P2 */ +#define OP_IncrVacuum 64 /* jump */ +#define OP_VNext 65 /* jump */ +#define OP_Filter 66 /* jump, synopsis: if key(P3@P4) not in filter(P1) goto P2 */ +#define OP_PureFunc 67 /* synopsis: r[P3]=func(r[P2@NP]) */ +#define OP_Function 68 /* synopsis: r[P3]=func(r[P2@NP]) */ +#define OP_Return 69 +#define OP_EndCoroutine 70 +#define OP_HaltIfNull 71 /* synopsis: if r[P3]=null halt */ +#define OP_Halt 72 +#define OP_Integer 73 /* synopsis: r[P2]=P1 */ +#define OP_Int64 74 /* synopsis: r[P2]=P4 */ +#define OP_String 75 /* synopsis: r[P2]='P4' (len=P1) */ +#define OP_BeginSubrtn 76 /* synopsis: r[P2]=NULL */ +#define OP_Null 77 /* synopsis: r[P2..P3]=NULL */ +#define OP_SoftNull 78 /* synopsis: r[P1]=NULL */ +#define OP_Blob 79 /* synopsis: r[P2]=P4 (len=P1) */ +#define OP_Variable 80 /* synopsis: r[P2]=parameter(P1) */ +#define OP_Move 81 /* synopsis: r[P2@P3]=r[P1@P3] */ +#define OP_Copy 82 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ +#define OP_SCopy 83 /* synopsis: r[P2]=r[P1] */ +#define OP_IntCopy 84 /* synopsis: r[P2]=r[P1] */ +#define OP_FkCheck 85 +#define OP_ResultRow 86 /* synopsis: output=r[P1@P2] */ +#define OP_CollSeq 87 +#define OP_AddImm 88 /* synopsis: r[P1]=r[P1]+P2 */ +#define OP_RealAffinity 89 +#define OP_Cast 90 /* synopsis: affinity(r[P1]) */ +#define OP_Permutation 91 +#define OP_Compare 92 /* synopsis: r[P1@P3] <-> r[P2@P3] */ +#define OP_IsTrue 93 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */ +#define OP_ZeroOrNull 94 /* synopsis: r[P2] = 0 OR NULL */ +#define OP_Offset 95 /* synopsis: r[P3] = sqlite_offset(P1) */ +#define OP_Column 96 /* synopsis: r[P3]=PX cursor P1 column P2 */ +#define OP_TypeCheck 97 /* synopsis: typecheck(r[P1@P2]) */ +#define OP_Affinity 98 /* synopsis: affinity(r[P1@P2]) */ +#define OP_MakeRecord 99 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ +#define OP_Count 100 /* synopsis: r[P2]=count() */ +#define OP_ReadCookie 101 +#define OP_SetCookie 102 +#define OP_BitAnd 103 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ +#define OP_BitOr 104 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ +#define OP_ShiftLeft 105 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */ +#define OP_Add 107 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ +#define OP_Subtract 108 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ +#define OP_Multiply 109 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ +#define OP_Divide 110 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ +#define OP_Remainder 111 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ +#define OP_Concat 112 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ +#define OP_ReopenIdx 113 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenRead 114 /* synopsis: root=P2 iDb=P3 */ +#define OP_BitNot 115 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */ +#define OP_OpenWrite 116 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenDup 117 +#define OP_String8 118 /* same as TK_STRING, synopsis: r[P2]='P4' */ +#define OP_OpenAutoindex 119 /* synopsis: nColumn=P2 */ +#define OP_OpenEphemeral 120 /* synopsis: nColumn=P2 */ +#define OP_SorterOpen 121 +#define OP_SequenceTest 122 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ +#define OP_OpenPseudo 123 /* synopsis: P3 columns in r[P2] */ +#define OP_Close 124 +#define OP_ColumnsUsed 125 +#define OP_SeekScan 126 /* synopsis: Scan-ahead up to P1 rows */ +#define OP_SeekHit 127 /* synopsis: set P2<=seekHit<=P3 */ +#define OP_Sequence 128 /* synopsis: r[P2]=cursor[P1].ctr++ */ +#define OP_NewRowid 129 /* synopsis: r[P2]=rowid */ +#define OP_Insert 130 /* synopsis: intkey=r[P3] data=r[P2] */ +#define OP_RowCell 131 +#define OP_Delete 132 +#define OP_ResetCount 133 +#define OP_SorterCompare 134 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ +#define OP_SorterData 135 /* synopsis: r[P2]=data */ +#define OP_RowData 136 /* synopsis: r[P2]=data */ +#define OP_Rowid 137 /* synopsis: r[P2]=PX rowid of P1 */ +#define OP_NullRow 138 +#define OP_SeekEnd 139 +#define OP_IdxInsert 140 /* synopsis: key=r[P2] */ +#define OP_SorterInsert 141 /* synopsis: key=r[P2] */ +#define OP_IdxDelete 142 /* synopsis: key=r[P2@P3] */ +#define OP_DeferredSeek 143 /* synopsis: Move P3 to P1.rowid if needed */ +#define OP_IdxRowid 144 /* synopsis: r[P2]=rowid */ +#define OP_FinishSeek 145 +#define OP_Destroy 146 +#define OP_Clear 147 +#define OP_ResetSorter 148 +#define OP_CreateBtree 149 /* synopsis: r[P2]=root iDb=P1 flags=P3 */ +#define OP_SqlExec 150 +#define OP_ParseSchema 151 +#define OP_LoadAnalysis 152 +#define OP_DropTable 153 +#define OP_Real 154 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ +#define OP_DropIndex 155 +#define OP_DropTrigger 156 +#define OP_IntegrityCk 157 +#define OP_RowSetAdd 158 /* synopsis: rowset(P1)=r[P2] */ +#define OP_Param 159 +#define OP_FkCounter 160 /* synopsis: fkctr[P1]+=P2 */ +#define OP_MemMax 161 /* synopsis: r[P1]=max(r[P1],r[P2]) */ +#define OP_OffsetLimit 162 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ +#define OP_AggInverse 163 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */ +#define OP_AggStep 164 /* synopsis: accum=r[P3] step(r[P2@P5]) */ +#define OP_AggStep1 165 /* synopsis: accum=r[P3] step(r[P2@P5]) */ +#define OP_AggValue 166 /* synopsis: r[P3]=value N=P2 */ +#define OP_AggFinal 167 /* synopsis: accum=r[P1] N=P2 */ +#define OP_Expire 168 +#define OP_CursorLock 169 +#define OP_CursorUnlock 170 +#define OP_TableLock 171 /* synopsis: iDb=P1 root=P2 write=P3 */ +#define OP_VBegin 172 +#define OP_VCreate 173 +#define OP_VDestroy 174 +#define OP_VOpen 175 +#define OP_VCheck 176 +#define OP_VInitIn 177 /* synopsis: r[P2]=ValueList(P1,P3) */ +#define OP_VColumn 178 /* synopsis: r[P3]=vcolumn(P2) */ +#define OP_VRename 179 +#define OP_Pagecount 180 +#define OP_MaxPgcnt 181 +#define OP_ClrSubtype 182 /* synopsis: r[P1].subtype = 0 */ +#define OP_GetSubtype 183 /* synopsis: r[P2] = r[P1].subtype */ +#define OP_SetSubtype 184 /* synopsis: r[P2].subtype = r[P1] */ +#define OP_FilterAdd 185 /* synopsis: filter(P1) += key(P3@P4) */ +#define OP_Trace 186 +#define OP_CursorHint 187 +#define OP_ReleaseReg 188 /* synopsis: release r[P1@P2] mask P3 */ +#define OP_Noop 189 +#define OP_Explain 190 +#define OP_Abortable 191 + +/* Properties such as "out2" or "jump" that are specified in +** comments following the "case" for each opcode in the vdbe.c +** are encoded into bitvectors as follows: +*/ +#define OPFLG_JUMP 0x01 /* jump: P2 holds jmp target */ +#define OPFLG_IN1 0x02 /* in1: P1 is an input */ +#define OPFLG_IN2 0x04 /* in2: P2 is an input */ +#define OPFLG_IN3 0x08 /* in3: P3 is an input */ +#define OPFLG_OUT2 0x10 /* out2: P2 is an output */ +#define OPFLG_OUT3 0x20 /* out3: P3 is an output */ +#define OPFLG_NCYCLE 0x40 /* ncycle:Cycles count against P1 */ +#define OPFLG_JUMP0 0x80 /* jump0: P2 might be zero */ +#define OPFLG_INITIALIZER {\ +/* 0 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x41, 0x00,\ +/* 8 */ 0x81, 0x01, 0x01, 0x81, 0x83, 0x83, 0x01, 0x01,\ +/* 16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0xc9, 0xc9, 0xc9,\ +/* 24 */ 0xc9, 0x01, 0x49, 0x49, 0x49, 0x49, 0xc9, 0x49,\ +/* 32 */ 0xc1, 0x01, 0x41, 0x41, 0xc1, 0x01, 0x01, 0x41,\ +/* 40 */ 0x41, 0x41, 0x41, 0x26, 0x26, 0x41, 0x41, 0x09,\ +/* 48 */ 0x23, 0x0b, 0x81, 0x03, 0x03, 0x0b, 0x0b, 0x0b,\ +/* 56 */ 0x0b, 0x0b, 0x0b, 0x01, 0x01, 0x03, 0x03, 0x03,\ +/* 64 */ 0x01, 0x41, 0x01, 0x00, 0x00, 0x02, 0x02, 0x08,\ +/* 72 */ 0x00, 0x10, 0x10, 0x10, 0x00, 0x10, 0x00, 0x10,\ +/* 80 */ 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00,\ +/* 88 */ 0x02, 0x02, 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20,\ +/* 96 */ 0x40, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x26,\ +/* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\ +/* 112 */ 0x26, 0x40, 0x40, 0x12, 0x00, 0x40, 0x10, 0x40,\ +/* 120 */ 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x40,\ +/* 128 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,\ +/* 136 */ 0x00, 0x50, 0x00, 0x40, 0x04, 0x04, 0x00, 0x40,\ +/* 144 */ 0x50, 0x40, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00,\ +/* 152 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x10,\ +/* 160 */ 0x00, 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,\ +/* 176 */ 0x10, 0x50, 0x40, 0x00, 0x10, 0x10, 0x02, 0x12,\ +/* 184 */ 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +} + +/* The resolve3P2Values() routine is able to run faster if it knows +** the value of the largest JUMP opcode. The smaller the maximum +** JUMP opcode the better, so the mkopcodeh.tcl script that +** generated this include file strives to group all JUMP opcodes +** together near the beginning of the list. +*/ +#define SQLITE_MX_JUMP_OPCODE 66 /* Maximum JUMP opcode */ + +/************** End of opcodes.h *********************************************/ +/************** Continuing where we left off in vdbe.h ***********************/ + +/* +** Additional non-public SQLITE_PREPARE_* flags +*/ +#define SQLITE_PREPARE_SAVESQL 0x80 /* Preserve SQL text */ +#define SQLITE_PREPARE_MASK 0x3f /* Mask of public flags */ + +/* +** Prototypes for the VDBE interface. See comments on the implementation +** for a description of what each of these routines does. +*/ +SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse*); +SQLITE_PRIVATE Parse *sqlite3VdbeParser(Vdbe*); +SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe*,int); +SQLITE_PRIVATE int sqlite3VdbeAddOp1(Vdbe*,int,int); +SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe*,int,int,int); +SQLITE_PRIVATE int sqlite3VdbeGoto(Vdbe*,int); +SQLITE_PRIVATE int sqlite3VdbeLoadString(Vdbe*,int,const char*); +SQLITE_PRIVATE void sqlite3VdbeMultiLoad(Vdbe*,int,const char*,...); +SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int); +SQLITE_PRIVATE int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int); +SQLITE_PRIVATE int sqlite3VdbeAddOp4Dup8(Vdbe*,int,int,int,int,const u8*,int); +SQLITE_PRIVATE int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int); +SQLITE_PRIVATE int sqlite3VdbeAddFunctionCall(Parse*,int,int,int,int,const FuncDef*,int); +SQLITE_PRIVATE void sqlite3VdbeEndCoroutine(Vdbe*,int); +#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS) +SQLITE_PRIVATE void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N); +SQLITE_PRIVATE void sqlite3VdbeVerifyNoResultRow(Vdbe *p); +#else +# define sqlite3VdbeVerifyNoMallocRequired(A,B) +# define sqlite3VdbeVerifyNoResultRow(A) +#endif +#if defined(SQLITE_DEBUG) +SQLITE_PRIVATE void sqlite3VdbeVerifyAbortable(Vdbe *p, int); +SQLITE_PRIVATE void sqlite3VdbeNoJumpsOutsideSubrtn(Vdbe*,int,int,int); +#else +# define sqlite3VdbeVerifyAbortable(A,B) +# define sqlite3VdbeNoJumpsOutsideSubrtn(A,B,C,D) +#endif +SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp,int iLineno); +#ifndef SQLITE_OMIT_EXPLAIN +SQLITE_PRIVATE int sqlite3VdbeExplain(Parse*,u8,const char*,...); +SQLITE_PRIVATE void sqlite3VdbeExplainPop(Parse*); +SQLITE_PRIVATE int sqlite3VdbeExplainParent(Parse*); +# define ExplainQueryPlan(P) sqlite3VdbeExplain P +# ifdef SQLITE_ENABLE_STMT_SCANSTATUS +# define ExplainQueryPlan2(V,P) (V = sqlite3VdbeExplain P) +# else +# define ExplainQueryPlan2(V,P) ExplainQueryPlan(P) +# endif +# define ExplainQueryPlanPop(P) sqlite3VdbeExplainPop(P) +# define ExplainQueryPlanParent(P) sqlite3VdbeExplainParent(P) +#else +# define ExplainQueryPlan(P) +# define ExplainQueryPlan2(V,P) +# define ExplainQueryPlanPop(P) +# define ExplainQueryPlanParent(P) 0 +# define sqlite3ExplainBreakpoint(A,B) /*no-op*/ +#endif +#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_EXPLAIN) +SQLITE_PRIVATE void sqlite3ExplainBreakpoint(const char*,const char*); +#else +# define sqlite3ExplainBreakpoint(A,B) /*no-op*/ +#endif +SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe*, int, char*, u16); +SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe*, int addr, u8); +SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1); +SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2); +SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe*, int addr, int P3); +SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u16 P5); +SQLITE_PRIVATE void sqlite3VdbeTypeofColumn(Vdbe*, int); +SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe*, int addr); +SQLITE_PRIVATE void sqlite3VdbeJumpHereOrPopInst(Vdbe*, int addr); +SQLITE_PRIVATE int sqlite3VdbeChangeToNoop(Vdbe*, int addr); +SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op); +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE void sqlite3VdbeReleaseRegisters(Parse*,int addr, int n, u32 mask, int); +#else +# define sqlite3VdbeReleaseRegisters(P,A,N,M,F) +#endif +SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N); +SQLITE_PRIVATE void sqlite3VdbeAppendP4(Vdbe*, void *pP4, int p4type); +SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse*, Index*); +SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int); +SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); +SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetLastOp(Vdbe*); +SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Parse*); +SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,Parse*); +SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int); +SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*); +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *, int); +#endif +SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe*); +SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe*,int); +SQLITE_PRIVATE int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*)); +SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*); +SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*); +SQLITE_PRIVATE u8 sqlite3VdbePrepareFlags(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, u8); +#ifdef SQLITE_ENABLE_NORMALIZE +SQLITE_PRIVATE void sqlite3VdbeAddDblquoteStr(sqlite3*,Vdbe*,const char*); +SQLITE_PRIVATE int sqlite3VdbeUsesDoubleQuotedString(Vdbe*,const char*); +#endif +SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*); +SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*); +SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8); +SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int); +#ifndef SQLITE_OMIT_TRACE +SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); +#endif +SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); +SQLITE_PRIVATE int sqlite3BlobCompare(const Mem*, const Mem*); +#ifdef SQLITE_ENABLE_PERCENTILE +SQLITE_PRIVATE const char *sqlite3VdbeFuncName(const sqlite3_context*); +#endif + +SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(int,const void*,UnpackedRecord*); +SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); +SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int); +SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo*); + +typedef int (*RecordCompare)(int,const void*,UnpackedRecord*); +SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*); + +SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *); +SQLITE_PRIVATE int sqlite3VdbeHasSubProgram(Vdbe*); + +SQLITE_PRIVATE void sqlite3MemSetArrayInt64(sqlite3_value *aMem, int iIdx, i64 val); + +#ifndef SQLITE_OMIT_DATETIME_FUNCS +SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context*); +#endif +#ifdef SQLITE_ENABLE_BYTECODE_VTAB +SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3*); +#endif + +/* Use SQLITE_ENABLE_EXPLAIN_COMMENTS to enable generation of extra +** comments on each VDBE opcode. +** +** Use the SQLITE_ENABLE_MODULE_COMMENTS macro to see some extra no-op +** comments in VDBE programs that show key decision points in the code +** generator. +*/ +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS +SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe*, const char*, ...); +# define VdbeComment(X) sqlite3VdbeComment X +SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe*, const char*, ...); +# define VdbeNoopComment(X) sqlite3VdbeNoopComment X +# ifdef SQLITE_ENABLE_MODULE_COMMENTS +# define VdbeModuleComment(X) sqlite3VdbeNoopComment X +# else +# define VdbeModuleComment(X) +# endif +#else +# define VdbeComment(X) +# define VdbeNoopComment(X) +# define VdbeModuleComment(X) +#endif + +/* +** The VdbeCoverage macros are used to set a coverage testing point +** for VDBE branch instructions. The coverage testing points are line +** numbers in the sqlite3.c source file. VDBE branch coverage testing +** only works with an amalgamation build. That's ok since a VDBE branch +** coverage build designed for testing the test suite only. No application +** should ever ship with VDBE branch coverage measuring turned on. +** +** VdbeCoverage(v) // Mark the previously coded instruction +** // as a branch +** +** VdbeCoverageIf(v, conditional) // Mark previous if conditional true +** +** VdbeCoverageAlwaysTaken(v) // Previous branch is always taken +** +** VdbeCoverageNeverTaken(v) // Previous branch is never taken +** +** VdbeCoverageNeverNull(v) // Previous three-way branch is only +** // taken on the first two ways. The +** // NULL option is not possible +** +** VdbeCoverageEqNe(v) // Previous OP_Jump is only interested +** // in distinguishing equal and not-equal. +** +** Every VDBE branch operation must be tagged with one of the macros above. +** If not, then when "make test" is run with -DSQLITE_VDBE_COVERAGE and +** -DSQLITE_DEBUG then an ALWAYS() will fail in the vdbeTakeBranch() +** routine in vdbe.c, alerting the developer to the missed tag. +** +** During testing, the test application will invoke +** sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE,...) to set a callback +** routine that is invoked as each bytecode branch is taken. The callback +** contains the sqlite3.c source line number of the VdbeCoverage macro and +** flags to indicate whether or not the branch was taken. The test application +** is responsible for keeping track of this and reporting byte-code branches +** that are never taken. +** +** See the VdbeBranchTaken() macro and vdbeTakeBranch() function in the +** vdbe.c source file for additional information. +*/ +#ifdef SQLITE_VDBE_COVERAGE +SQLITE_PRIVATE void sqlite3VdbeSetLineNumber(Vdbe*,int); +# define VdbeCoverage(v) sqlite3VdbeSetLineNumber(v,__LINE__) +# define VdbeCoverageIf(v,x) if(x)sqlite3VdbeSetLineNumber(v,__LINE__) +# define VdbeCoverageAlwaysTaken(v) \ + sqlite3VdbeSetLineNumber(v,__LINE__|0x5000000); +# define VdbeCoverageNeverTaken(v) \ + sqlite3VdbeSetLineNumber(v,__LINE__|0x6000000); +# define VdbeCoverageNeverNull(v) \ + sqlite3VdbeSetLineNumber(v,__LINE__|0x4000000); +# define VdbeCoverageNeverNullIf(v,x) \ + if(x)sqlite3VdbeSetLineNumber(v,__LINE__|0x4000000); +# define VdbeCoverageEqNe(v) \ + sqlite3VdbeSetLineNumber(v,__LINE__|0x8000000); +# define VDBE_OFFSET_LINENO(x) (__LINE__+x) +#else +# define VdbeCoverage(v) +# define VdbeCoverageIf(v,x) +# define VdbeCoverageAlwaysTaken(v) +# define VdbeCoverageNeverTaken(v) +# define VdbeCoverageNeverNull(v) +# define VdbeCoverageNeverNullIf(v,x) +# define VdbeCoverageEqNe(v) +# define VDBE_OFFSET_LINENO(x) 0 +#endif + +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS +SQLITE_PRIVATE void sqlite3VdbeScanStatus(Vdbe*, int, int, int, LogEst, const char*); +SQLITE_PRIVATE void sqlite3VdbeScanStatusRange(Vdbe*, int, int, int); +SQLITE_PRIVATE void sqlite3VdbeScanStatusCounters(Vdbe*, int, int, int); +#else +# define sqlite3VdbeScanStatus(a,b,c,d,e,f) +# define sqlite3VdbeScanStatusRange(a,b,c,d) +# define sqlite3VdbeScanStatusCounters(a,b,c,d) +#endif + +#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) +SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, VdbeOp*); +#endif + +#if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG) +SQLITE_PRIVATE int sqlite3CursorRangeHintExprCheck(Walker *pWalker, Expr *pExpr); +#endif + +#endif /* SQLITE_VDBE_H */ + +/************** End of vdbe.h ************************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ +/************** Include pcache.h in the middle of sqliteInt.h ****************/ +/************** Begin file pcache.h ******************************************/ +/* +** 2008 August 05 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This header file defines the interface that the sqlite page cache +** subsystem. +*/ + +#ifndef _PCACHE_H_ + +typedef struct PgHdr PgHdr; +typedef struct PCache PCache; + +/* +** Every page in the cache is controlled by an instance of the following +** structure. +*/ +struct PgHdr { + sqlite3_pcache_page *pPage; /* Pcache object page handle */ + void *pData; /* Page data */ + void *pExtra; /* Extra content */ + PCache *pCache; /* PRIVATE: Cache that owns this page */ + PgHdr *pDirty; /* Transient list of dirty sorted by pgno */ + Pager *pPager; /* The pager this page is part of */ +#ifdef SQLITE_CHECK_PAGES + u64 pageHash; /* Hash of page content */ +#endif + Pgno pgno; /* Page number for this page */ + u16 flags; /* PGHDR flags defined below */ + + /********************************************************************** + ** Elements above, except pCache, are public. All that follow are + ** private to pcache.c and should not be accessed by other modules. + ** pCache is grouped with the public elements for efficiency. + */ + i64 nRef; /* Number of users of this page */ + PgHdr *pDirtyNext; /* Next element in list of dirty pages */ + PgHdr *pDirtyPrev; /* Previous element in list of dirty pages */ + /* NB: pDirtyNext and pDirtyPrev are undefined if the + ** PgHdr object is not dirty */ +}; + +/* Bit values for PgHdr.flags */ +#define PGHDR_CLEAN 0x001 /* Page not on the PCache.pDirty list */ +#define PGHDR_DIRTY 0x002 /* Page is on the PCache.pDirty list */ +#define PGHDR_WRITEABLE 0x004 /* Journaled and ready to modify */ +#define PGHDR_NEED_SYNC 0x008 /* Fsync the rollback journal before + ** writing this page to the database */ +#define PGHDR_DONT_WRITE 0x010 /* Do not write content to disk */ +#define PGHDR_MMAP 0x020 /* This is an mmap page object */ + +#define PGHDR_WAL_APPEND 0x040 /* Appended to wal file */ + +/* Initialize and shutdown the page cache subsystem */ +SQLITE_PRIVATE int sqlite3PcacheInitialize(void); +SQLITE_PRIVATE void sqlite3PcacheShutdown(void); + +/* Page cache buffer management: +** These routines implement SQLITE_CONFIG_PAGECACHE. +*/ +SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *, int sz, int n); + +/* Create a new pager cache. +** Under memory stress, invoke xStress to try to make pages clean. +** Only clean and unpinned pages can be reclaimed. +*/ +SQLITE_PRIVATE int sqlite3PcacheOpen( + int szPage, /* Size of every page */ + int szExtra, /* Extra space associated with each page */ + int bPurgeable, /* True if pages are on backing store */ + int (*xStress)(void*, PgHdr*), /* Call to try to make pages clean */ + void *pStress, /* Argument to xStress */ + PCache *pToInit /* Preallocated space for the PCache */ +); + +/* Modify the page-size after the cache has been created. */ +SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *, int); + +/* Return the size in bytes of a PCache object. Used to preallocate +** storage space. +*/ +SQLITE_PRIVATE int sqlite3PcacheSize(void); + +/* One release per successful fetch. Page is pinned until released. +** Reference counted. +*/ +SQLITE_PRIVATE sqlite3_pcache_page *sqlite3PcacheFetch(PCache*, Pgno, int createFlag); +SQLITE_PRIVATE int sqlite3PcacheFetchStress(PCache*, Pgno, sqlite3_pcache_page**); +SQLITE_PRIVATE PgHdr *sqlite3PcacheFetchFinish(PCache*, Pgno, sqlite3_pcache_page *pPage); +SQLITE_PRIVATE void sqlite3PcacheRelease(PgHdr*); + +SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr*); /* Remove page from cache */ +SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr*); /* Make sure page is marked dirty */ +SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr*); /* Mark a single page as clean */ +SQLITE_PRIVATE void sqlite3PcacheCleanAll(PCache*); /* Mark all dirty list pages as clean */ +SQLITE_PRIVATE void sqlite3PcacheClearWritable(PCache*); + +/* Change a page number. Used by incr-vacuum. */ +SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr*, Pgno); + +/* Remove all pages with pgno>x. Reset the cache if x==0 */ +SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache*, Pgno x); + +/* Get a list of all dirty pages in the cache, sorted by page number */ +SQLITE_PRIVATE PgHdr *sqlite3PcacheDirtyList(PCache*); + +/* Reset and close the cache object */ +SQLITE_PRIVATE void sqlite3PcacheClose(PCache*); + +/* Clear flags from pages of the page cache */ +SQLITE_PRIVATE void sqlite3PcacheClearSyncFlags(PCache *); + +/* Discard the contents of the cache */ +SQLITE_PRIVATE void sqlite3PcacheClear(PCache*); + +/* Return the total number of outstanding page references */ +SQLITE_PRIVATE i64 sqlite3PcacheRefCount(PCache*); + +/* Increment the reference count of an existing page */ +SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr*); + +SQLITE_PRIVATE i64 sqlite3PcachePageRefcount(PgHdr*); + +/* Return the total number of pages stored in the cache */ +SQLITE_PRIVATE int sqlite3PcachePagecount(PCache*); + +#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG) +/* Iterate through all dirty pages currently stored in the cache. This +** interface is only available if SQLITE_CHECK_PAGES is defined when the +** library is built. +*/ +SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)); +#endif + +#if defined(SQLITE_DEBUG) +/* Check invariants on a PgHdr object */ +SQLITE_PRIVATE int sqlite3PcachePageSanity(PgHdr*); +#endif + +/* Set and get the suggested cache-size for the specified pager-cache. +** +** If no global maximum is configured, then the system attempts to limit +** the total number of pages cached by purgeable pager-caches to the sum +** of the suggested cache-sizes. +*/ +SQLITE_PRIVATE void sqlite3PcacheSetCachesize(PCache *, int); +#ifdef SQLITE_TEST +SQLITE_PRIVATE int sqlite3PcacheGetCachesize(PCache *); +#endif + +/* Set or get the suggested spill-size for the specified pager-cache. +** +** The spill-size is the minimum number of pages in cache before the cache +** will attempt to spill dirty pages by calling xStress. +*/ +SQLITE_PRIVATE int sqlite3PcacheSetSpillsize(PCache *, int); + +/* Free up as much memory as possible from the page cache */ +SQLITE_PRIVATE void sqlite3PcacheShrink(PCache*); + +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT +/* Try to return memory used by the pcache module to the main memory heap */ +SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int); +#endif + +#ifdef SQLITE_TEST +SQLITE_PRIVATE void sqlite3PcacheStats(int*,int*,int*,int*); +#endif + +SQLITE_PRIVATE void sqlite3PCacheSetDefault(void); + +/* Return the header size */ +SQLITE_PRIVATE int sqlite3HeaderSizePcache(void); +SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void); + +/* Number of dirty pages as a percentage of the configured cache size */ +SQLITE_PRIVATE int sqlite3PCachePercentDirty(PCache*); + +#ifdef SQLITE_DIRECT_OVERFLOW_READ +SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache); +#endif + +#endif /* _PCACHE_H_ */ + +/************** End of pcache.h **********************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ +/************** Include mutex.h in the middle of sqliteInt.h *****************/ +/************** Begin file mutex.h *******************************************/ +/* +** 2007 August 28 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains the common header for all mutex implementations. +** The sqliteInt.h header #includes this file so that it is available +** to all source files. We break it out in an effort to keep the code +** better organized. +** +** NOTE: source files should *not* #include this header file directly. +** Source files should #include the sqliteInt.h file and let that file +** include this one indirectly. +*/ + + +/* +** Figure out what version of the code to use. The choices are +** +** SQLITE_MUTEX_OMIT No mutex logic. Not even stubs. The +** mutexes implementation cannot be overridden +** at start-time. +** +** SQLITE_MUTEX_NOOP For single-threaded applications. No +** mutual exclusion is provided. But this +** implementation can be overridden at +** start-time. +** +** SQLITE_MUTEX_PTHREADS For multi-threaded applications on Unix. +** +** SQLITE_MUTEX_W32 For multi-threaded applications on Win32. +*/ +#if !SQLITE_THREADSAFE +# define SQLITE_MUTEX_OMIT +#endif +#if SQLITE_THREADSAFE && !defined(SQLITE_MUTEX_NOOP) +# if SQLITE_OS_UNIX +# define SQLITE_MUTEX_PTHREADS +# elif SQLITE_OS_WIN +# define SQLITE_MUTEX_W32 +# else +# define SQLITE_MUTEX_NOOP +# endif +#endif + +#ifdef SQLITE_MUTEX_OMIT +/* +** If this is a no-op implementation, implement everything as macros. +*/ +#define sqlite3_mutex_alloc(X) ((sqlite3_mutex*)8) +#define sqlite3_mutex_free(X) +#define sqlite3_mutex_enter(X) +#define sqlite3_mutex_try(X) SQLITE_OK +#define sqlite3_mutex_leave(X) +#define sqlite3_mutex_held(X) ((void)(X),1) +#define sqlite3_mutex_notheld(X) ((void)(X),1) +#define sqlite3MutexAlloc(X) ((sqlite3_mutex*)8) +#define sqlite3MutexInit() SQLITE_OK +#define sqlite3MutexEnd() +#define MUTEX_LOGIC(X) +#else +#define MUTEX_LOGIC(X) X +SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*); +#endif /* defined(SQLITE_MUTEX_OMIT) */ + +/************** End of mutex.h ***********************************************/ +/************** Continuing where we left off in sqliteInt.h ******************/ + +/* The SQLITE_EXTRA_DURABLE compile-time option used to set the default +** synchronous setting to EXTRA. It is no longer supported. +*/ +#ifdef SQLITE_EXTRA_DURABLE +# warning Use SQLITE_DEFAULT_SYNCHRONOUS=3 instead of SQLITE_EXTRA_DURABLE +# define SQLITE_DEFAULT_SYNCHRONOUS 3 +#endif + +/* +** Default synchronous levels. +** +** Note that (for historical reasons) the PAGER_SYNCHRONOUS_* macros differ +** from the SQLITE_DEFAULT_SYNCHRONOUS value by 1. +** +** PAGER_SYNCHRONOUS DEFAULT_SYNCHRONOUS +** OFF 1 0 +** NORMAL 2 1 +** FULL 3 2 +** EXTRA 4 3 +** +** The "PRAGMA synchronous" statement also uses the zero-based numbers. +** In other words, the zero-based numbers are used for all external interfaces +** and the one-based values are used internally. +*/ +#ifndef SQLITE_DEFAULT_SYNCHRONOUS +# define SQLITE_DEFAULT_SYNCHRONOUS 2 +#endif +#ifndef SQLITE_DEFAULT_WAL_SYNCHRONOUS +# define SQLITE_DEFAULT_WAL_SYNCHRONOUS SQLITE_DEFAULT_SYNCHRONOUS +#endif + +/* +** Each database file to be accessed by the system is an instance +** of the following structure. There are normally two of these structures +** in the sqlite.aDb[] array. aDb[0] is the main database file and +** aDb[1] is the database file used to hold temporary tables. Additional +** databases may be attached. +*/ +struct Db { + char *zDbSName; /* Name of this database. (schema name, not filename) */ + Btree *pBt; /* The B*Tree structure for this database file */ + u8 safety_level; /* How aggressive at syncing data to disk */ + u8 bSyncSet; /* True if "PRAGMA synchronous=N" has been run */ + Schema *pSchema; /* Pointer to database schema (possibly shared) */ +}; + +/* +** An instance of the following structure stores a database schema. +** +** Most Schema objects are associated with a Btree. The exception is +** the Schema for the TEMP database (sqlite3.aDb[1]) which is free-standing. +** In shared cache mode, a single Schema object can be shared by multiple +** Btrees that refer to the same underlying BtShared object. +** +** Schema objects are automatically deallocated when the last Btree that +** references them is destroyed. The TEMP Schema is manually freed by +** sqlite3_close(). +* +** A thread must be holding a mutex on the corresponding Btree in order +** to access Schema content. This implies that the thread must also be +** holding a mutex on the sqlite3 connection pointer that owns the Btree. +** For a TEMP Schema, only the connection mutex is required. +*/ +struct Schema { + int schema_cookie; /* Database schema version number for this file */ + int iGeneration; /* Generation counter. Incremented with each change */ + Hash tblHash; /* All tables indexed by name */ + Hash idxHash; /* All (named) indices indexed by name */ + Hash trigHash; /* All triggers indexed by name */ + Hash fkeyHash; /* All foreign keys by referenced table name */ + Table *pSeqTab; /* The sqlite_sequence table used by AUTOINCREMENT */ + u8 file_format; /* Schema format version for this file */ + u8 enc; /* Text encoding used by this database */ + u16 schemaFlags; /* Flags associated with this schema */ + int cache_size; /* Number of pages to use in the cache */ +}; + +/* +** These macros can be used to test, set, or clear bits in the +** Db.pSchema->flags field. +*/ +#define DbHasProperty(D,I,P) (((D)->aDb[I].pSchema->schemaFlags&(P))==(P)) +#define DbHasAnyProperty(D,I,P) (((D)->aDb[I].pSchema->schemaFlags&(P))!=0) +#define DbSetProperty(D,I,P) (D)->aDb[I].pSchema->schemaFlags|=(P) +#define DbClearProperty(D,I,P) (D)->aDb[I].pSchema->schemaFlags&=~(P) + +/* +** Allowed values for the DB.pSchema->flags field. +** +** The DB_SchemaLoaded flag is set after the database schema has been +** read into internal hash tables. +** +** DB_UnresetViews means that one or more views have column names that +** have been filled out. If the schema changes, these column names might +** changes and so the view will need to be reset. +*/ +#define DB_SchemaLoaded 0x0001 /* The schema has been loaded */ +#define DB_UnresetViews 0x0002 /* Some views have defined column names */ +#define DB_ResetWanted 0x0008 /* Reset the schema when nSchemaLock==0 */ + +/* +** The number of different kinds of things that can be limited +** using the sqlite3_limit() interface. +*/ +#define SQLITE_N_LIMIT (SQLITE_LIMIT_PARSER_DEPTH+1) + +/* +** Lookaside malloc is a set of fixed-size buffers that can be used +** to satisfy small transient memory allocation requests for objects +** associated with a particular database connection. The use of +** lookaside malloc provides a significant performance enhancement +** (approx 10%) by avoiding numerous malloc/free requests while parsing +** SQL statements. +** +** The Lookaside structure holds configuration information about the +** lookaside malloc subsystem. Each available memory allocation in +** the lookaside subsystem is stored on a linked list of LookasideSlot +** objects. +** +** Lookaside allocations are only allowed for objects that are associated +** with a particular database connection. Hence, schema information cannot +** be stored in lookaside because in shared cache mode the schema information +** is shared by multiple database connections. Therefore, while parsing +** schema information, the Lookaside.bEnabled flag is cleared so that +** lookaside allocations are not used to construct the schema objects. +** +** New lookaside allocations are only allowed if bDisable==0. When +** bDisable is greater than zero, sz is set to zero which effectively +** disables lookaside without adding a new test for the bDisable flag +** in a performance-critical path. sz should be set by to szTrue whenever +** bDisable changes back to zero. +** +** Lookaside buffers are initially held on the pInit list. As they are +** used and freed, they are added back to the pFree list. New allocations +** come off of pFree first, then pInit as a fallback. This dual-list +** allows use to compute a high-water mark - the maximum number of allocations +** outstanding at any point in the past - by subtracting the number of +** allocations on the pInit list from the total number of allocations. +** +** Enhancement on 2019-12-12: Two-size-lookaside +** The default lookaside configuration is 100 slots of 1200 bytes each. +** The larger slot sizes are important for performance, but they waste +** a lot of space, as most lookaside allocations are less than 128 bytes. +** The two-size-lookaside enhancement breaks up the lookaside allocation +** into two pools: One of 128-byte slots and the other of the default size +** (1200-byte) slots. Allocations are filled from the small-pool first, +** failing over to the full-size pool if that does not work. Thus more +** lookaside slots are available while also using less memory. +** This enhancement can be omitted by compiling with +** SQLITE_OMIT_TWOSIZE_LOOKASIDE. +*/ +struct Lookaside { + u32 bDisable; /* Only operate the lookaside when zero */ + u16 sz; /* Size of each buffer in bytes */ + u16 szTrue; /* True value of sz, even if disabled */ + u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */ + u32 nSlot; /* Number of lookaside slots allocated */ + u32 anStat[3]; /* 0: hits. 1: size misses. 2: full misses */ + LookasideSlot *pInit; /* List of buffers not previously used */ + LookasideSlot *pFree; /* List of available buffers */ +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + LookasideSlot *pSmallInit; /* List of small buffers not previously used */ + LookasideSlot *pSmallFree; /* List of available small buffers */ + void *pMiddle; /* First byte past end of full-size buffers and + ** the first byte of LOOKASIDE_SMALL buffers */ +#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ + void *pStart; /* First byte of available memory space */ + void *pEnd; /* First byte past end of available space */ + void *pTrueEnd; /* True value of pEnd, when db->pnBytesFreed!=0 */ +}; +struct LookasideSlot { + LookasideSlot *pNext; /* Next buffer in the list of free buffers */ +}; + +#define DisableLookaside db->lookaside.bDisable++;db->lookaside.sz=0 +#define EnableLookaside db->lookaside.bDisable--;\ + db->lookaside.sz=db->lookaside.bDisable?0:db->lookaside.szTrue + +/* Size of the smaller allocations in two-size lookaside */ +#ifdef SQLITE_OMIT_TWOSIZE_LOOKASIDE +# define LOOKASIDE_SMALL 0 +#else +# define LOOKASIDE_SMALL 128 +#endif + +/* +** A hash table for built-in function definitions. (Application-defined +** functions use a regular table table from hash.h.) +** +** Hash each FuncDef structure into one of the FuncDefHash.a[] slots. +** Collisions are on the FuncDef.u.pHash chain. Use the SQLITE_FUNC_HASH() +** macro to compute a hash on the function name. +*/ +#define SQLITE_FUNC_HASH_SZ 23 +struct FuncDefHash { + FuncDef *a[SQLITE_FUNC_HASH_SZ]; /* Hash table for functions */ +}; +#define SQLITE_FUNC_HASH(C,L) (((C)+(L))%SQLITE_FUNC_HASH_SZ) + +/* +** typedef for the authorization callback function. +*/ +typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*, + const char*); + +#ifndef SQLITE_OMIT_DEPRECATED +/* This is an extra SQLITE_TRACE macro that indicates "legacy" tracing +** in the style of sqlite3_trace() +*/ +#define SQLITE_TRACE_LEGACY 0x40 /* Use the legacy xTrace */ +#define SQLITE_TRACE_XPROFILE 0x80 /* Use the legacy xProfile */ +#else +#define SQLITE_TRACE_LEGACY 0 +#define SQLITE_TRACE_XPROFILE 0 +#endif /* SQLITE_OMIT_DEPRECATED */ +#define SQLITE_TRACE_NONLEGACY_MASK 0x0f /* Normal flags */ + +/* +** Maximum number of sqlite3.aDb[] entries. This is the number of attached +** databases plus 2 for "main" and "temp". +*/ +#define SQLITE_MAX_DB (SQLITE_MAX_ATTACHED+2) + +/* +** Each database connection is an instance of the following structure. +*/ +struct sqlite3 { + sqlite3_vfs *pVfs; /* OS Interface */ + struct Vdbe *pVdbe; /* List of active virtual machines */ + CollSeq *pDfltColl; /* BINARY collseq for the database encoding */ + sqlite3_mutex *mutex; /* Connection mutex */ + Db *aDb; /* All backends */ + int nDb; /* Number of backends currently in use */ + u32 mDbFlags; /* flags recording internal state */ + u64 flags; /* flags settable by pragmas. See below */ + i64 lastRowid; /* ROWID of most recent insert (see above) */ + i64 szMmap; /* Default mmap_size setting */ + u32 nSchemaLock; /* Do not reset the schema when non-zero */ + unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ + int errCode; /* Most recent error code (SQLITE_*) */ + int errByteOffset; /* Byte offset of error in SQL statement */ + int errMask; /* & result codes with this before returning */ + int iSysErrno; /* Errno value from last system error */ + u32 dbOptFlags; /* Flags to enable/disable optimizations */ + u8 enc; /* Text encoding */ + u8 autoCommit; /* The auto-commit flag. */ + u8 temp_store; /* 1: file 2: memory 0: default */ + u8 mallocFailed; /* True if we have seen a malloc failure */ + u8 bBenignMalloc; /* Do not require OOMs if true */ + u8 dfltLockMode; /* Default locking-mode for attached dbs */ + signed char nextAutovac; /* Autovac setting after VACUUM if >=0 */ + u8 suppressErr; /* Do not issue error messages if true */ + u8 vtabOnConflict; /* Value to return for s3_vtab_on_conflict() */ + u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */ + u8 mTrace; /* zero or more SQLITE_TRACE flags */ + u8 noSharedCache; /* True if no shared-cache backends */ + u8 nSqlExec; /* Number of pending OP_SqlExec opcodes */ + u8 eOpenState; /* Current condition of the connection */ + u8 nFpDigit; /* Significant digits to keep on double->text */ + int nextPagesize; /* Pagesize after VACUUM if >0 */ + i64 nChange; /* Value returned by sqlite3_changes() */ + i64 nTotalChange; /* Value returned by sqlite3_total_changes() */ + int aLimit[SQLITE_N_LIMIT]; /* Limits */ + int nMaxSorterMmap; /* Maximum size of regions mapped by sorter */ + struct sqlite3InitInfo { /* Information used during initialization */ + Pgno newTnum; /* Rootpage of table being initialized */ + u8 iDb; /* Which db file is being initialized */ + u8 busy; /* TRUE if currently initializing */ + unsigned orphanTrigger : 1; /* Last statement is orphaned TEMP trigger */ + unsigned imposterTable : 2; /* Building an imposter table */ + unsigned reopenMemdb : 1; /* ATTACH is really a reopen using MemDB */ + const char **azInit; /* "type", "name", and "tbl_name" columns */ + } init; + int nVdbeActive; /* Number of VDBEs currently running */ + int nVdbeRead; /* Number of active VDBEs that read or write */ + int nVdbeWrite; /* Number of active VDBEs that read and write */ + int nVdbeExec; /* Number of nested calls to VdbeExec() */ + int nVDestroy; /* Number of active OP_VDestroy operations */ + int nExtension; /* Number of loaded extensions */ + void **aExtension; /* Array of shared library handles */ + union { + void (*xLegacy)(void*,const char*); /* mTrace==SQLITE_TRACE_LEGACY */ + int (*xV2)(u32,void*,void*,void*); /* All other mTrace values */ + } trace; + void *pTraceArg; /* Argument to the trace function */ +#ifndef SQLITE_OMIT_DEPRECATED + void (*xProfile)(void*,const char*,u64); /* Profiling function */ + void *pProfileArg; /* Argument to profile function */ +#endif + void *pCommitArg; /* Argument to xCommitCallback() */ + int (*xCommitCallback)(void*); /* Invoked at every commit. */ + void *pRollbackArg; /* Argument to xRollbackCallback() */ + void (*xRollbackCallback)(void*); /* Invoked at every commit. */ + void *pUpdateArg; + void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64); + void *pAutovacPagesArg; /* Client argument to autovac_pages */ + void (*xAutovacDestr)(void*); /* Destructor for pAutovacPAgesArg */ + unsigned int (*xAutovacPages)(void*,const char*,u32,u32,u32); + Parse *pParse; /* Current parse */ +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + void *pPreUpdateArg; /* First argument to xPreUpdateCallback */ + void (*xPreUpdateCallback)( /* Registered using sqlite3_preupdate_hook() */ + void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64 + ); + PreUpdate *pPreUpdate; /* Context for active pre-update callback */ +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ +#ifndef SQLITE_OMIT_WAL + int (*xWalCallback)(void *, sqlite3 *, const char *, int); + void *pWalArg; +#endif + void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*); + void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*); + void *pCollNeededArg; + sqlite3_value *pErr; /* Most recent error message */ + union { + volatile int isInterrupted; /* True if sqlite3_interrupt has been called */ + double notUsed1; /* Spacer */ + } u1; + Lookaside lookaside; /* Lookaside malloc configuration */ +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth; /* Access authorization function */ + void *pAuthArg; /* 1st argument to the access auth function */ +#endif +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + int (*xProgress)(void *); /* The progress callback */ + void *pProgressArg; /* Argument to the progress callback */ + unsigned nProgressOps; /* Number of opcodes for progress callback */ +#endif +#ifndef SQLITE_OMIT_VIRTUALTABLE + int nVTrans; /* Allocated size of aVTrans */ + Hash aModule; /* populated by sqlite3_create_module() */ + VtabCtx *pVtabCtx; /* Context for active vtab connect/create */ + VTable **aVTrans; /* Virtual tables with open transactions */ + VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */ +#endif + Hash aFunc; /* Hash table of connection functions */ + Hash aCollSeq; /* All collating sequences */ + BusyHandler busyHandler; /* Busy callback */ + Db aDbStatic[2]; /* Static space for the 2 default backends */ + Savepoint *pSavepoint; /* List of active savepoints */ + int nAnalysisLimit; /* Number of index rows to ANALYZE */ + int busyTimeout; /* Busy handler timeout, in msec */ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + int setlkTimeout; /* Blocking lock timeout, in msec. -1 -> inf. */ + int setlkFlags; /* Flags passed to setlk_timeout() */ +#endif + int nSavepoint; /* Number of non-transaction savepoints */ + int nStatement; /* Number of nested statement-transactions */ + i64 nDeferredCons; /* Net deferred constraints this transaction. */ + i64 nDeferredImmCons; /* Net deferred immediate constraints */ + int *pnBytesFreed; /* If not NULL, increment this in DbFree() */ + DbClientData *pDbData; /* sqlite3_set_clientdata() content */ + u64 nSpill; /* TEMP content spilled to disk */ +#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY + /* The following variables are all protected by the STATIC_MAIN + ** mutex, not by sqlite3.mutex. They are used by code in notify.c. + ** + ** When X.pUnlockConnection==Y, that means that X is waiting for Y to + ** unlock so that it can proceed. + ** + ** When X.pBlockingConnection==Y, that means that something that X tried + ** tried to do recently failed with an SQLITE_LOCKED error due to locks + ** held by Y. + */ + sqlite3 *pBlockingConnection; /* Connection that caused SQLITE_LOCKED */ + sqlite3 *pUnlockConnection; /* Connection to watch for unlock */ + void *pUnlockArg; /* Argument to xUnlockNotify */ + void (*xUnlockNotify)(void **, int); /* Unlock notify callback */ + sqlite3 *pNextBlocked; /* Next in list of all blocked connections */ +#endif +}; + +/* +** A macro to discover the encoding of a database. +*/ +#define SCHEMA_ENC(db) ((db)->aDb[0].pSchema->enc) +#define ENC(db) ((db)->enc) + +/* +** A u64 constant where the lower 32 bits are all zeros. Only the +** upper 32 bits are included in the argument. Necessary because some +** C-compilers still do not accept LL integer literals. +*/ +#define HI(X) ((u64)(X)<<32) + +/* +** Possible values for the sqlite3.flags. +** +** Value constraints (enforced via assert()): +** SQLITE_FullFSync == PAGER_FULLFSYNC +** SQLITE_CkptFullFSync == PAGER_CKPT_FULLFSYNC +** SQLITE_CacheSpill == PAGER_CACHE_SPILL +*/ +#define SQLITE_WriteSchema 0x00000001 /* OK to update SQLITE_SCHEMA */ +#define SQLITE_LegacyFileFmt 0x00000002 /* Create new databases in format 1 */ +#define SQLITE_FullColNames 0x00000004 /* Show full column names on SELECT */ +#define SQLITE_FullFSync 0x00000008 /* Use full fsync on the backend */ +#define SQLITE_CkptFullFSync 0x00000010 /* Use full fsync for checkpoint */ +#define SQLITE_CacheSpill 0x00000020 /* OK to spill pager cache */ +#define SQLITE_ShortColNames 0x00000040 /* Show short columns names */ +#define SQLITE_TrustedSchema 0x00000080 /* Allow unsafe functions and + ** vtabs in the schema definition */ +#define SQLITE_NullCallback 0x00000100 /* Invoke the callback once if the */ + /* result set is empty */ +#define SQLITE_IgnoreChecks 0x00000200 /* Do not enforce check constraints */ +#define SQLITE_StmtScanStatus 0x00000400 /* Enable stmt_scanstats() counters */ +#define SQLITE_NoCkptOnClose 0x00000800 /* No checkpoint on close()/DETACH */ +#define SQLITE_ReverseOrder 0x00001000 /* Reverse unordered SELECTs */ +#define SQLITE_RecTriggers 0x00002000 /* Enable recursive triggers */ +#define SQLITE_ForeignKeys 0x00004000 /* Enforce foreign key constraints */ +#define SQLITE_AutoIndex 0x00008000 /* Enable automatic indexes */ +#define SQLITE_LoadExtension 0x00010000 /* Enable load_extension */ +#define SQLITE_LoadExtFunc 0x00020000 /* Enable load_extension() SQL func */ +#define SQLITE_EnableTrigger 0x00040000 /* True to enable triggers */ +#define SQLITE_DeferFKs 0x00080000 /* Defer all FK constraints */ +#define SQLITE_QueryOnly 0x00100000 /* Disable database changes */ +#define SQLITE_CellSizeCk 0x00200000 /* Check btree cell sizes on load */ +#define SQLITE_Fts3Tokenizer 0x00400000 /* Enable fts3_tokenizer(2) */ +#define SQLITE_EnableQPSG 0x00800000 /* Query Planner Stability Guarantee*/ +#define SQLITE_TriggerEQP 0x01000000 /* Show trigger EXPLAIN QUERY PLAN */ +#define SQLITE_ResetDatabase 0x02000000 /* Reset the database */ +#define SQLITE_LegacyAlter 0x04000000 /* Legacy ALTER TABLE behaviour */ +#define SQLITE_NoSchemaError 0x08000000 /* Do not report schema parse errors*/ +#define SQLITE_Defensive 0x10000000 /* Input SQL is likely hostile */ +#define SQLITE_DqsDDL 0x20000000 /* dbl-quoted strings allowed in DDL*/ +#define SQLITE_DqsDML 0x40000000 /* dbl-quoted strings allowed in DML*/ +#define SQLITE_EnableView 0x80000000 /* Enable the use of views */ +#define SQLITE_CountRows HI(0x00001) /* Count rows changed by INSERT, */ + /* DELETE, or UPDATE and return */ + /* the count using a callback. */ +#define SQLITE_CorruptRdOnly HI(0x00002) /* Prohibit writes due to error */ +#define SQLITE_ReadUncommit HI(0x00004) /* READ UNCOMMITTED in shared-cache */ +#define SQLITE_FkNoAction HI(0x00008) /* Treat all FK as NO ACTION */ +#define SQLITE_AttachCreate HI(0x00010) /* ATTACH allowed to create new dbs */ +#define SQLITE_AttachWrite HI(0x00020) /* ATTACH allowed to open for write */ +#define SQLITE_Comments HI(0x00040) /* Enable SQL comments */ + +/* Flags used only if debugging */ +#ifdef SQLITE_DEBUG +#define SQLITE_SqlTrace HI(0x0100000) /* Debug print SQL as it executes */ +#define SQLITE_VdbeListing HI(0x0200000) /* Debug listings of VDBE progs */ +#define SQLITE_VdbeTrace HI(0x0400000) /* True to trace VDBE execution */ +#define SQLITE_VdbeAddopTrace HI(0x0800000) /* Trace sqlite3VdbeAddOp() calls */ +#define SQLITE_VdbeEQP HI(0x1000000) /* Debug EXPLAIN QUERY PLAN */ +#define SQLITE_ParserTrace HI(0x2000000) /* PRAGMA parser_trace=ON */ +#endif + +/* +** Allowed values for sqlite3.mDbFlags +*/ +#define DBFLAG_SchemaChange 0x0001 /* Uncommitted Hash table changes */ +#define DBFLAG_PreferBuiltin 0x0002 /* Preference to built-in funcs */ +#define DBFLAG_Vacuum 0x0004 /* Currently in a VACUUM */ +#define DBFLAG_VacuumInto 0x0008 /* Currently running VACUUM INTO */ +#define DBFLAG_SchemaKnownOk 0x0010 /* Schema is known to be valid */ +#define DBFLAG_InternalFunc 0x0020 /* Allow use of internal functions */ +#define DBFLAG_EncodingFixed 0x0040 /* No longer possible to change enc. */ + +/* +** Bits of the sqlite3.dbOptFlags field that are used by the +** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to +** selectively disable various optimizations. +*/ +#define SQLITE_QueryFlattener 0x00000001 /* Query flattening */ +#define SQLITE_WindowFunc 0x00000002 /* Use xInverse for window functions */ +#define SQLITE_GroupByOrder 0x00000004 /* GROUPBY cover of ORDERBY */ +#define SQLITE_FactorOutConst 0x00000008 /* Constant factoring */ +#define SQLITE_DistinctOpt 0x00000010 /* DISTINCT using indexes */ +#define SQLITE_CoverIdxScan 0x00000020 /* Covering index scans */ +#define SQLITE_OrderByIdxJoin 0x00000040 /* ORDER BY of joins via index */ +#define SQLITE_Transitive 0x00000080 /* Transitive constraints */ +#define SQLITE_OmitNoopJoin 0x00000100 /* Omit unused tables in joins */ +#define SQLITE_CountOfView 0x00000200 /* The count-of-view optimization */ +#define SQLITE_CursorHints 0x00000400 /* Add OP_CursorHint opcodes */ +#define SQLITE_Stat4 0x00000800 /* Use STAT4 data */ + /* TH3 expects this value ^^^^^^^^^^ to be 0x0000800. Don't change it */ +#define SQLITE_PushDown 0x00001000 /* WHERE-clause push-down opt */ +#define SQLITE_SimplifyJoin 0x00002000 /* Convert LEFT JOIN to JOIN */ +#define SQLITE_SkipScan 0x00004000 /* Skip-scans */ +#define SQLITE_PropagateConst 0x00008000 /* The constant propagation opt */ +#define SQLITE_MinMaxOpt 0x00010000 /* The min/max optimization */ +#define SQLITE_SeekScan 0x00020000 /* The OP_SeekScan optimization */ +#define SQLITE_OmitOrderBy 0x00040000 /* Omit pointless ORDER BY */ + /* TH3 expects this value ^^^^^^^^^^ to be 0x40000. Coordinate any change */ +#define SQLITE_BloomFilter 0x00080000 /* Use a Bloom filter on searches */ +#define SQLITE_BloomPulldown 0x00100000 /* Run Bloom filters early */ +#define SQLITE_BalancedMerge 0x00200000 /* Balance multi-way merges */ +#define SQLITE_ReleaseReg 0x00400000 /* Use OP_ReleaseReg for testing */ +#define SQLITE_FlttnUnionAll 0x00800000 /* Disable the UNION ALL flattener */ + /* TH3 expects this value ^^^^^^^^^^ See flatten04.test */ +#define SQLITE_IndexedExpr 0x01000000 /* Pull exprs from index when able */ +#define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */ +#define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */ +#define SQLITE_OnePass 0x08000000 /* Single-pass DELETE and UPDATE */ +#define SQLITE_OrderBySubq 0x10000000 /* ORDER BY in subquery helps outer */ +#define SQLITE_StarQuery 0x20000000 /* Heurists for star queries */ +#define SQLITE_ExistsToJoin 0x40000000 /* The EXISTS-to-JOIN optimization */ +#define SQLITE_AllOpts 0xffffffff /* All optimizations */ + +/* +** Macros for testing whether or not optimizations are enabled or disabled. +*/ +#define OptimizationDisabled(db, mask) (((db)->dbOptFlags&(mask))!=0) +#define OptimizationEnabled(db, mask) (((db)->dbOptFlags&(mask))==0) + +/* +** Return true if it OK to factor constant expressions into the initialization +** code. The argument is a Parse object for the code generator. +*/ +#define ConstFactorOk(P) ((P)->okConstFactor) + +/* Possible values for the sqlite3.eOpenState field. +** The numbers are randomly selected such that a minimum of three bits must +** change to convert any number to another or to zero +*/ +#define SQLITE_STATE_OPEN 0x76 /* Database is open */ +#define SQLITE_STATE_CLOSED 0xce /* Database is closed */ +#define SQLITE_STATE_SICK 0xba /* Error and awaiting close */ +#define SQLITE_STATE_BUSY 0x6d /* Database currently in use */ +#define SQLITE_STATE_ERROR 0xd5 /* An SQLITE_MISUSE error occurred */ +#define SQLITE_STATE_ZOMBIE 0xa7 /* Close with last statement close */ + +/* +** Each SQL function is defined by an instance of the following +** structure. For global built-in functions (ex: substr(), max(), count()) +** a pointer to this structure is held in the sqlite3BuiltinFunctions object. +** For per-connection application-defined functions, a pointer to this +** structure is held in the db->aHash hash table. +** +** The u.pHash field is used by the global built-ins. The u.pDestructor +** field is used by per-connection app-def functions. +*/ +struct FuncDef { + i16 nArg; /* Number of arguments. -1 means unlimited */ + u32 funcFlags; /* Some combination of SQLITE_FUNC_* */ + void *pUserData; /* User data parameter */ + FuncDef *pNext; /* Next function with same name */ + void (*xSFunc)(sqlite3_context*,int,sqlite3_value**); /* func or agg-step */ + void (*xFinalize)(sqlite3_context*); /* Agg finalizer */ + void (*xValue)(sqlite3_context*); /* Current agg value */ + void (*xInverse)(sqlite3_context*,int,sqlite3_value**); /* inverse agg-step */ + const char *zName; /* SQL name of the function. */ + union { + FuncDef *pHash; /* Next with a different name but the same hash */ + FuncDestructor *pDestructor; /* Reference counted destructor function */ + } u; /* pHash if SQLITE_FUNC_BUILTIN, pDestructor otherwise */ +}; + +/* +** This structure encapsulates a user-function destructor callback (as +** configured using create_function_v2()) and a reference counter. When +** create_function_v2() is called to create a function with a destructor, +** a single object of this type is allocated. FuncDestructor.nRef is set to +** the number of FuncDef objects created (either 1 or 3, depending on whether +** or not the specified encoding is SQLITE_ANY). The FuncDef.pDestructor +** member of each of the new FuncDef objects is set to point to the allocated +** FuncDestructor. +** +** Thereafter, when one of the FuncDef objects is deleted, the reference +** count on this object is decremented. When it reaches 0, the destructor +** is invoked and the FuncDestructor structure freed. +*/ +struct FuncDestructor { + int nRef; + void (*xDestroy)(void *); + void *pUserData; +}; + +/* +** Possible values for FuncDef.flags. Note that the _LENGTH and _TYPEOF +** values must correspond to OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG. And +** SQLITE_FUNC_CONSTANT must be the same as SQLITE_DETERMINISTIC. There +** are assert() statements in the code to verify this. +** +** Value constraints (enforced via assert()): +** SQLITE_FUNC_MINMAX == NC_MinMaxAgg == SF_MinMaxAgg +** SQLITE_FUNC_ANYORDER == NC_OrderAgg == SF_OrderByReqd +** SQLITE_FUNC_LENGTH == OPFLAG_LENGTHARG +** SQLITE_FUNC_TYPEOF == OPFLAG_TYPEOFARG +** SQLITE_FUNC_BYTELEN == OPFLAG_BYTELENARG +** SQLITE_FUNC_CONSTANT == SQLITE_DETERMINISTIC from the API +** SQLITE_FUNC_DIRECT == SQLITE_DIRECTONLY from the API +** SQLITE_FUNC_UNSAFE == SQLITE_INNOCUOUS -- opposite meanings!!! +** SQLITE_FUNC_ENCMASK depends on SQLITE_UTF* macros in the API +** +** Note that even though SQLITE_FUNC_UNSAFE and SQLITE_INNOCUOUS have the +** same bit value, their meanings are inverted. SQLITE_FUNC_UNSAFE is +** used internally and if set means that the function has side effects. +** SQLITE_INNOCUOUS is used by application code and means "not unsafe". +** See multiple instances of tag-20230109-1. +*/ +#define SQLITE_FUNC_ENCMASK 0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */ +#define SQLITE_FUNC_LIKE 0x0004 /* Candidate for the LIKE optimization */ +#define SQLITE_FUNC_CASE 0x0008 /* Case-sensitive LIKE-type function */ +#define SQLITE_FUNC_EPHEM 0x0010 /* Ephemeral. Delete with VDBE */ +#define SQLITE_FUNC_NEEDCOLL 0x0020 /* sqlite3GetFuncCollSeq() might be called*/ +#define SQLITE_FUNC_LENGTH 0x0040 /* Built-in length() function */ +#define SQLITE_FUNC_TYPEOF 0x0080 /* Built-in typeof() function */ +#define SQLITE_FUNC_BYTELEN 0x00c0 /* Built-in octet_length() function */ +#define SQLITE_FUNC_COUNT 0x0100 /* Built-in count(*) aggregate */ +/* 0x0200 -- available for reuse */ +#define SQLITE_FUNC_UNLIKELY 0x0400 /* Built-in unlikely() function */ +#define SQLITE_FUNC_CONSTANT 0x0800 /* Constant inputs give a constant output */ +#define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */ +#define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a + ** single query - might change over time */ +#define SQLITE_FUNC_TEST 0x4000 /* Built-in testing functions */ +#define SQLITE_FUNC_RUNONLY 0x8000 /* Cannot be used by valueFromFunction */ +#define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */ +#define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */ +#define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */ +/* SQLITE_SUBTYPE 0x00100000 // Consumer of subtypes */ +#define SQLITE_FUNC_UNSAFE 0x00200000 /* Function has side effects */ +#define SQLITE_FUNC_INLINE 0x00400000 /* Functions implemented in-line */ +#define SQLITE_FUNC_BUILTIN 0x00800000 /* This is a built-in function */ +/* SQLITE_RESULT_SUBTYPE 0x01000000 // Generator of subtypes */ +#define SQLITE_FUNC_ANYORDER 0x08000000 /* count/min/max aggregate */ + +/* Identifier numbers for each in-line function */ +#define INLINEFUNC_coalesce 0 +#define INLINEFUNC_implies_nonnull_row 1 +#define INLINEFUNC_expr_implies_expr 2 +#define INLINEFUNC_expr_compare 3 +#define INLINEFUNC_affinity 4 +#define INLINEFUNC_iif 5 +#define INLINEFUNC_sqlite_offset 6 +#define INLINEFUNC_unlikely 99 /* Default case */ + +/* +** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are +** used to create the initializers for the FuncDef structures. +** +** FUNCTION(zName, nArg, iArg, bNC, xFunc) +** Used to create a scalar function definition of a function zName +** implemented by C function xFunc that accepts nArg arguments. The +** value passed as iArg is cast to a (void*) and made available +** as the user-data (sqlite3_user_data()) for the function. If +** argument bNC is true, then the SQLITE_FUNC_NEEDCOLL flag is set. +** +** VFUNCTION(zName, nArg, iArg, bNC, xFunc) +** Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag. +** +** SFUNCTION(zName, nArg, iArg, bNC, xFunc) +** Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag and +** adds the SQLITE_DIRECTONLY flag. +** +** INLINE_FUNC(zName, nArg, iFuncId, mFlags) +** zName is the name of a function that is implemented by in-line +** byte code rather than by the usual callbacks. The iFuncId +** parameter determines the function id. The mFlags parameter is +** optional SQLITE_FUNC_ flags for this function. +** +** TEST_FUNC(zName, nArg, iFuncId, mFlags) +** zName is the name of a test-only function implemented by in-line +** byte code rather than by the usual callbacks. The iFuncId +** parameter determines the function id. The mFlags parameter is +** optional SQLITE_FUNC_ flags for this function. +** +** DFUNCTION(zName, nArg, iArg, bNC, xFunc) +** Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag and +** adds the SQLITE_FUNC_SLOCHNG flag. Used for date & time functions +** and functions like sqlite_version() that can change, but not during +** a single query. The iArg is ignored. The user-data is always set +** to a NULL pointer. The bNC parameter is not used. +** +** MFUNCTION(zName, nArg, xPtr, xFunc) +** For math-library functions. xPtr is an arbitrary pointer. +** +** PURE_DATE(zName, nArg, iArg, bNC, xFunc) +** Used for "pure" date/time functions, this macro is like DFUNCTION +** except that it does set the SQLITE_FUNC_CONSTANT flags. iArg is +** ignored and the user-data for these functions is set to an +** arbitrary non-NULL pointer. The bNC parameter is not used. +** +** AGGREGATE(zName, nArg, iArg, bNC, xStep, xFinal) +** Used to create an aggregate function definition implemented by +** the C functions xStep and xFinal. The first four parameters +** are interpreted in the same way as the first 4 parameters to +** FUNCTION(). +** +** WAGGREGATE(zName, nArg, iArg, xStep, xFinal, xValue, xInverse) +** Used to create an aggregate function definition implemented by +** the C functions xStep and xFinal. The first four parameters +** are interpreted in the same way as the first 4 parameters to +** FUNCTION(). +** +** LIKEFUNC(zName, nArg, pArg, flags) +** Used to create a scalar function definition of a function zName +** that accepts nArg arguments and is implemented by a call to C +** function likeFunc. Argument pArg is cast to a (void *) and made +** available as the function user-data (sqlite3_user_data()). The +** FuncDef.flags variable is set to the value passed as the flags +** parameter. +*/ +#define FUNCTION(zName, nArg, iArg, bNC, xFunc) \ + {nArg, SQLITE_FUNC_BUILTIN|\ + SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ + SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } +#define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \ + {nArg, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ + SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } +#define SFUNCTION(zName, nArg, iArg, bNC, xFunc) \ + {nArg, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_DIRECTONLY|SQLITE_FUNC_UNSAFE, \ + SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } +#define MFUNCTION(zName, nArg, xPtr, xFunc) \ + {nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ + xPtr, 0, xFunc, 0, 0, 0, #zName, {0} } +#define JFUNCTION(zName, nArg, bUseCache, bWS, bRS, bJsonB, iArg, xFunc) \ + {nArg, SQLITE_FUNC_BUILTIN|SQLITE_DETERMINISTIC|SQLITE_FUNC_CONSTANT|\ + SQLITE_UTF8|((bUseCache)*SQLITE_FUNC_RUNONLY)|\ + ((bRS)*SQLITE_SUBTYPE)|((bWS)*SQLITE_RESULT_SUBTYPE), \ + SQLITE_INT_TO_PTR(iArg|((bJsonB)*JSON_BLOB)),0,xFunc,0, 0, 0, #zName, {0} } +#define INLINE_FUNC(zName, nArg, iArg, mFlags) \ + {nArg, SQLITE_FUNC_BUILTIN|\ + SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \ + SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} } +#define TEST_FUNC(zName, nArg, iArg, mFlags) \ + {nArg, SQLITE_FUNC_BUILTIN|\ + SQLITE_UTF8|SQLITE_FUNC_INTERNAL|SQLITE_FUNC_TEST| \ + SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \ + SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} } +#define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \ + {nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_SLOCHNG|SQLITE_UTF8, \ + 0, 0, xFunc, 0, 0, 0, #zName, {0} } +#define PURE_DATE(zName, nArg, iArg, bNC, xFunc) \ + {nArg, SQLITE_FUNC_BUILTIN|\ + SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \ + (void*)&sqlite3Config, 0, xFunc, 0, 0, 0, #zName, {0} } +#define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \ + {nArg, SQLITE_FUNC_BUILTIN|\ + SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\ + SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } +#define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \ + {nArg, SQLITE_FUNC_BUILTIN|\ + SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ + pArg, 0, xFunc, 0, 0, 0, #zName, {0} } +#define LIKEFUNC(zName, nArg, arg, flags) \ + {nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \ + (void *)arg, 0, likeFunc, 0, 0, 0, #zName, {0} } +#define WAGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue, xInverse, f) \ + {nArg, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|f, \ + SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,xInverse,#zName, {0}} +#define INTERNAL_FUNCTION(zName, nArg, xFunc) \ + {nArg, SQLITE_FUNC_BUILTIN|\ + SQLITE_FUNC_INTERNAL|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \ + 0, 0, xFunc, 0, 0, 0, #zName, {0} } + + +/* +** All current savepoints are stored in a linked list starting at +** sqlite3.pSavepoint. The first element in the list is the most recently +** opened savepoint. Savepoints are added to the list by the vdbe +** OP_Savepoint instruction. +*/ +struct Savepoint { + char *zName; /* Savepoint name (nul-terminated) */ + i64 nDeferredCons; /* Number of deferred fk violations */ + i64 nDeferredImmCons; /* Number of deferred imm fk. */ + Savepoint *pNext; /* Parent savepoint (if any) */ +}; + +/* +** The following are used as the second parameter to sqlite3Savepoint(), +** and as the P1 argument to the OP_Savepoint instruction. +*/ +#define SAVEPOINT_BEGIN 0 +#define SAVEPOINT_RELEASE 1 +#define SAVEPOINT_ROLLBACK 2 + + +/* +** Each SQLite module (virtual table definition) is defined by an +** instance of the following structure, stored in the sqlite3.aModule +** hash table. +*/ +struct Module { + const sqlite3_module *pModule; /* Callback pointers */ + const char *zName; /* Name passed to create_module() */ + int nRefModule; /* Number of pointers to this object */ + void *pAux; /* pAux passed to create_module() */ + void (*xDestroy)(void *); /* Module destructor function */ + Table *pEpoTab; /* Eponymous table for this module */ +}; + +/* +** Information about each column of an SQL table is held in an instance +** of the Column structure, in the Table.aCol[] array. +** +** Definitions: +** +** "table column index" This is the index of the column in the +** Table.aCol[] array, and also the index of +** the column in the original CREATE TABLE stmt. +** +** "storage column index" This is the index of the column in the +** record BLOB generated by the OP_MakeRecord +** opcode. The storage column index is less than +** or equal to the table column index. It is +** equal if and only if there are no VIRTUAL +** columns to the left. +** +** Notes on zCnName: +** The zCnName field stores the name of the column, the datatype of the +** column, and the collating sequence for the column, in that order, all in +** a single allocation. Each string is 0x00 terminated. The datatype +** is only included if the COLFLAG_HASTYPE bit of colFlags is set and the +** collating sequence name is only included if the COLFLAG_HASCOLL bit is +** set. +*/ +struct Column { + char *zCnName; /* Name of this column */ + unsigned notNull :4; /* An OE_ code for handling a NOT NULL constraint */ + unsigned eCType :4; /* One of the standard types */ + char affinity; /* One of the SQLITE_AFF_... values */ + u8 szEst; /* Est size of value in this column. sizeof(INT)==1 */ + u8 hName; /* Column name hash for faster lookup */ + u16 iDflt; /* 1-based index of DEFAULT. 0 means "none" */ + u16 colFlags; /* Boolean properties. See COLFLAG_ defines below */ +}; + +/* Allowed values for Column.eCType. +** +** Values must match entries in the global constant arrays +** sqlite3StdTypeLen[] and sqlite3StdType[]. Each value is one more +** than the offset into these arrays for the corresponding name. +** Adjust the SQLITE_N_STDTYPE value if adding or removing entries. +*/ +#define COLTYPE_CUSTOM 0 /* Type appended to zName */ +#define COLTYPE_ANY 1 +#define COLTYPE_BLOB 2 +#define COLTYPE_INT 3 +#define COLTYPE_INTEGER 4 +#define COLTYPE_REAL 5 +#define COLTYPE_TEXT 6 +#define SQLITE_N_STDTYPE 6 /* Number of standard types */ + +/* Allowed values for Column.colFlags. +** +** Constraints: +** TF_HasVirtual == COLFLAG_VIRTUAL +** TF_HasStored == COLFLAG_STORED +** TF_HasHidden == COLFLAG_HIDDEN +*/ +#define COLFLAG_PRIMKEY 0x0001 /* Column is part of the primary key */ +#define COLFLAG_HIDDEN 0x0002 /* A hidden column in a virtual table */ +#define COLFLAG_HASTYPE 0x0004 /* Type name follows column name */ +#define COLFLAG_UNIQUE 0x0008 /* Column def contains "UNIQUE" or "PK" */ +#define COLFLAG_SORTERREF 0x0010 /* Use sorter-refs with this column */ +#define COLFLAG_VIRTUAL 0x0020 /* GENERATED ALWAYS AS ... VIRTUAL */ +#define COLFLAG_STORED 0x0040 /* GENERATED ALWAYS AS ... STORED */ +#define COLFLAG_NOTAVAIL 0x0080 /* STORED column not yet calculated */ +#define COLFLAG_BUSY 0x0100 /* Blocks recursion on GENERATED columns */ +#define COLFLAG_HASCOLL 0x0200 /* Has collating sequence name in zCnName */ +#define COLFLAG_NOEXPAND 0x0400 /* Omit this column when expanding "*" */ +#define COLFLAG_GENERATED 0x0060 /* Combo: _STORED, _VIRTUAL */ +#define COLFLAG_NOINSERT 0x0062 /* Combo: _HIDDEN, _STORED, _VIRTUAL */ + +/* +** A "Collating Sequence" is defined by an instance of the following +** structure. Conceptually, a collating sequence consists of a name and +** a comparison routine that defines the order of that sequence. +** +** If CollSeq.xCmp is NULL, it means that the +** collating sequence is undefined. Indices built on an undefined +** collating sequence may not be read or written. +*/ +struct CollSeq { + char *zName; /* Name of the collating sequence, UTF-8 encoded */ + u8 enc; /* Text encoding handled by xCmp() */ + void *pUser; /* First argument to xCmp() */ + int (*xCmp)(void*,int, const void*, int, const void*); + void (*xDel)(void*); /* Destructor for pUser */ +}; + +/* +** A sort order can be either ASC or DESC. +*/ +#define SQLITE_SO_ASC 0 /* Sort in ascending order */ +#define SQLITE_SO_DESC 1 /* Sort in ascending order */ +#define SQLITE_SO_UNDEFINED -1 /* No sort order specified */ + +/* +** Column affinity types. +** +** These used to have mnemonic name like 'i' for SQLITE_AFF_INTEGER and +** 't' for SQLITE_AFF_TEXT. But we can save a little space and improve +** the speed a little by numbering the values consecutively. +** +** But rather than start with 0 or 1, we begin with 'A'. That way, +** when multiple affinity types are concatenated into a string and +** used as the P4 operand, they will be more readable. +** +** Note also that the numeric types are grouped together so that testing +** for a numeric type is a single comparison. And the BLOB type is first. +*/ +#define SQLITE_AFF_NONE 0x40 /* '@' */ +#define SQLITE_AFF_BLOB 0x41 /* 'A' */ +#define SQLITE_AFF_TEXT 0x42 /* 'B' */ +#define SQLITE_AFF_NUMERIC 0x43 /* 'C' */ +#define SQLITE_AFF_INTEGER 0x44 /* 'D' */ +#define SQLITE_AFF_REAL 0x45 /* 'E' */ +#define SQLITE_AFF_FLEXNUM 0x46 /* 'F' */ +#define SQLITE_AFF_DEFER 0x58 /* 'X' - defer computation until later */ + +#define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC) + +/* +** The SQLITE_AFF_MASK values masks off the significant bits of an +** affinity value. +*/ +#define SQLITE_AFF_MASK 0x47 + +/* +** Additional bit values that can be ORed with an affinity without +** changing the affinity. +** +** The SQLITE_NOTNULL flag is a combination of NULLEQ and JUMPIFNULL. +** It causes an assert() to fire if either operand to a comparison +** operator is NULL. It is added to certain comparison operators to +** prove that the operands are always NOT NULL. +*/ +#define SQLITE_JUMPIFNULL 0x10 /* jumps if either operand is NULL */ +#define SQLITE_NULLEQ 0x80 /* NULL=NULL */ +#define SQLITE_NOTNULL 0x90 /* Assert that operands are never NULL */ + +/* +** An object of this type is created for each virtual table present in +** the database schema. +** +** If the database schema is shared, then there is one instance of this +** structure for each database connection (sqlite3*) that uses the shared +** schema. This is because each database connection requires its own unique +** instance of the sqlite3_vtab* handle used to access the virtual table +** implementation. sqlite3_vtab* handles can not be shared between +** database connections, even when the rest of the in-memory database +** schema is shared, as the implementation often stores the database +** connection handle passed to it via the xConnect() or xCreate() method +** during initialization internally. This database connection handle may +** then be used by the virtual table implementation to access real tables +** within the database. So that they appear as part of the callers +** transaction, these accesses need to be made via the same database +** connection as that used to execute SQL operations on the virtual table. +** +** All VTable objects that correspond to a single table in a shared +** database schema are initially stored in a linked-list pointed to by +** the Table.pVTable member variable of the corresponding Table object. +** When an sqlite3_prepare() operation is required to access the virtual +** table, it searches the list for the VTable that corresponds to the +** database connection doing the preparing so as to use the correct +** sqlite3_vtab* handle in the compiled query. +** +** When an in-memory Table object is deleted (for example when the +** schema is being reloaded for some reason), the VTable objects are not +** deleted and the sqlite3_vtab* handles are not xDisconnect()ed +** immediately. Instead, they are moved from the Table.pVTable list to +** another linked list headed by the sqlite3.pDisconnect member of the +** corresponding sqlite3 structure. They are then deleted/xDisconnected +** next time a statement is prepared using said sqlite3*. This is done +** to avoid deadlock issues involving multiple sqlite3.mutex mutexes. +** Refer to comments above function sqlite3VtabUnlockList() for an +** explanation as to why it is safe to add an entry to an sqlite3.pDisconnect +** list without holding the corresponding sqlite3.mutex mutex. +** +** The memory for objects of this type is always allocated by +** sqlite3DbMalloc(), using the connection handle stored in VTable.db as +** the first argument. +*/ +struct VTable { + sqlite3 *db; /* Database connection associated with this table */ + Module *pMod; /* Pointer to module implementation */ + sqlite3_vtab *pVtab; /* Pointer to vtab instance */ + int nRef; /* Number of pointers to this structure */ + u8 bConstraint; /* True if constraints are supported */ + u8 bAllSchemas; /* True if might use any attached schema */ + u8 eVtabRisk; /* Riskiness of allowing hacker access */ + int iSavepoint; /* Depth of the SAVEPOINT stack */ + VTable *pNext; /* Next in linked list (see above) */ +}; + +/* Allowed values for VTable.eVtabRisk +*/ +#define SQLITE_VTABRISK_Low 0 +#define SQLITE_VTABRISK_Normal 1 +#define SQLITE_VTABRISK_High 2 + +/* +** The schema for each SQL table, virtual table, and view is represented +** in memory by an instance of the following structure. +*/ +struct Table { + char *zName; /* Name of the table or view */ + Column *aCol; /* Information about each column */ + Index *pIndex; /* List of SQL indexes on this table. */ + char *zColAff; /* String defining the affinity of each column */ + ExprList *pCheck; /* All CHECK constraints */ + /* ... also used as column name list in a VIEW */ + Pgno tnum; /* Root BTree page for this table */ + u32 nTabRef; /* Number of pointers to this Table */ + u32 tabFlags; /* Mask of TF_* values */ + i16 iPKey; /* If not negative, use aCol[iPKey] as the rowid */ + i16 nCol; /* Number of columns in this table */ + i16 nNVCol; /* Number of columns that are not VIRTUAL */ + LogEst nRowLogEst; /* Estimated rows in table - from sqlite_stat1 table */ + LogEst szTabRow; /* Estimated size of each table row in bytes */ +#ifdef SQLITE_ENABLE_COSTMULT + LogEst costMult; /* Cost multiplier for using this table */ +#endif + u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */ + u8 eTabType; /* 0: normal, 1: virtual, 2: view */ + union { + struct { /* Used by ordinary tables: */ + int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */ + FKey *pFKey; /* Linked list of all foreign keys in this table */ + ExprList *pDfltList; /* DEFAULT clauses on various columns. + ** Or the AS clause for generated columns. */ + } tab; + struct { /* Used by views: */ + Select *pSelect; /* View definition */ + } view; + struct { /* Used by virtual tables only: */ + int nArg; /* Number of arguments to the module */ + char **azArg; /* 0: module 1: schema 2: vtab name 3...: args */ + VTable *p; /* List of VTable objects. */ + } vtab; + } u; + Trigger *pTrigger; /* List of triggers on this object */ + Schema *pSchema; /* Schema that contains this table */ + u8 aHx[16]; /* Column aHt[K%sizeof(aHt)] might have hash K */ +}; + +/* +** Allowed values for Table.tabFlags. +** +** TF_OOOHidden applies to tables or view that have hidden columns that are +** followed by non-hidden columns. Example: "CREATE VIRTUAL TABLE x USING +** vtab1(a HIDDEN, b);". Since "b" is a non-hidden column but "a" is hidden, +** the TF_OOOHidden attribute would apply in this case. Such tables require +** special handling during INSERT processing. The "OOO" means "Out Of Order". +** +** Constraints: +** +** TF_HasVirtual == COLFLAG_VIRTUAL +** TF_HasStored == COLFLAG_STORED +** TF_HasHidden == COLFLAG_HIDDEN +*/ +#define TF_Readonly 0x00000001 /* Read-only system table */ +#define TF_HasHidden 0x00000002 /* Has one or more hidden columns */ +#define TF_HasPrimaryKey 0x00000004 /* Table has a primary key */ +#define TF_Autoincrement 0x00000008 /* Integer primary key is autoincrement */ +#define TF_HasStat1 0x00000010 /* nRowLogEst set from sqlite_stat1 */ +#define TF_HasVirtual 0x00000020 /* Has one or more VIRTUAL columns */ +#define TF_HasStored 0x00000040 /* Has one or more STORED columns */ +#define TF_HasGenerated 0x00000060 /* Combo: HasVirtual + HasStored */ +#define TF_WithoutRowid 0x00000080 /* No rowid. PRIMARY KEY is the key */ +#define TF_MaybeReanalyze 0x00000100 /* Maybe run ANALYZE on this table */ +#define TF_NoVisibleRowid 0x00000200 /* No user-visible "rowid" column */ +#define TF_OOOHidden 0x00000400 /* Out-of-Order hidden columns */ +#define TF_HasNotNull 0x00000800 /* Contains NOT NULL constraints */ +#define TF_Shadow 0x00001000 /* True for a shadow table */ +#define TF_HasStat4 0x00002000 /* STAT4 info available for this table */ +#define TF_Ephemeral 0x00004000 /* An ephemeral table */ +#define TF_Eponymous 0x00008000 /* An eponymous virtual table */ +#define TF_Strict 0x00010000 /* STRICT mode */ +#define TF_Imposter 0x00020000 /* An imposter table */ + +/* +** Allowed values for Table.eTabType +*/ +#define TABTYP_NORM 0 /* Ordinary table */ +#define TABTYP_VTAB 1 /* Virtual table */ +#define TABTYP_VIEW 2 /* A view */ + +#define IsView(X) ((X)->eTabType==TABTYP_VIEW) +#define IsOrdinaryTable(X) ((X)->eTabType==TABTYP_NORM) + +/* +** Test to see whether or not a table is a virtual table. This is +** done as a macro so that it will be optimized out when virtual +** table support is omitted from the build. +*/ +#ifndef SQLITE_OMIT_VIRTUALTABLE +# define IsVirtual(X) ((X)->eTabType==TABTYP_VTAB) +# define ExprIsVtab(X) \ + ((X)->op==TK_COLUMN && (X)->y.pTab->eTabType==TABTYP_VTAB) +#else +# define IsVirtual(X) 0 +# define ExprIsVtab(X) 0 +#endif + +/* +** Macros to determine if a column is hidden. IsOrdinaryHiddenColumn() +** only works for non-virtual tables (ordinary tables and views) and is +** always false unless SQLITE_ENABLE_HIDDEN_COLUMNS is defined. The +** IsHiddenColumn() macro is general purpose. +*/ +#if defined(SQLITE_ENABLE_HIDDEN_COLUMNS) +# define IsHiddenColumn(X) (((X)->colFlags & COLFLAG_HIDDEN)!=0) +# define IsOrdinaryHiddenColumn(X) (((X)->colFlags & COLFLAG_HIDDEN)!=0) +#elif !defined(SQLITE_OMIT_VIRTUALTABLE) +# define IsHiddenColumn(X) (((X)->colFlags & COLFLAG_HIDDEN)!=0) +# define IsOrdinaryHiddenColumn(X) 0 +#else +# define IsHiddenColumn(X) 0 +# define IsOrdinaryHiddenColumn(X) 0 +#endif + + +/* Does the table have a rowid */ +#define HasRowid(X) (((X)->tabFlags & TF_WithoutRowid)==0) +#define VisibleRowid(X) (((X)->tabFlags & TF_NoVisibleRowid)==0) + +/* Macro is true if the SQLITE_ALLOW_ROWID_IN_VIEW (mis-)feature is +** available. By default, this macro is false +*/ +#ifndef SQLITE_ALLOW_ROWID_IN_VIEW +# define ViewCanHaveRowid 0 +#else +# define ViewCanHaveRowid (sqlite3Config.mNoVisibleRowid==0) +#endif + +/* +** Each foreign key constraint is an instance of the following structure. +** +** A foreign key is associated with two tables. The "from" table is +** the table that contains the REFERENCES clause that creates the foreign +** key. The "to" table is the table that is named in the REFERENCES clause. +** Consider this example: +** +** CREATE TABLE ex1( +** a INTEGER PRIMARY KEY, +** b INTEGER CONSTRAINT fk1 REFERENCES ex2(x) +** ); +** +** For foreign key "fk1", the from-table is "ex1" and the to-table is "ex2". +** Equivalent names: +** +** from-table == child-table +** to-table == parent-table +** +** Each REFERENCES clause generates an instance of the following structure +** which is attached to the from-table. The to-table need not exist when +** the from-table is created. The existence of the to-table is not checked. +** +** The list of all parents for child Table X is held at X.pFKey. +** +** A list of all children for a table named Z (which might not even exist) +** is held in Schema.fkeyHash with a hash key of Z. +*/ +struct FKey { + Table *pFrom; /* Table containing the REFERENCES clause (aka: Child) */ + FKey *pNextFrom; /* Next FKey with the same in pFrom. Next parent of pFrom */ + char *zTo; /* Name of table that the key points to (aka: Parent) */ + FKey *pNextTo; /* Next with the same zTo. Next child of zTo. */ + FKey *pPrevTo; /* Previous with the same zTo */ + int nCol; /* Number of columns in this key */ + /* EV: R-30323-21917 */ + u8 isDeferred; /* True if constraint checking is deferred till COMMIT */ + u8 aAction[2]; /* ON DELETE and ON UPDATE actions, respectively */ + Trigger *apTrigger[2];/* Triggers for aAction[] actions */ + struct sColMap { /* Mapping of columns in pFrom to columns in zTo */ + int iFrom; /* Index of column in pFrom */ + char *zCol; /* Name of column in zTo. If NULL use PRIMARY KEY */ + } aCol[FLEXARRAY]; /* One entry for each of nCol columns */ +}; + +/* The size (in bytes) of an FKey object holding N columns. The answer +** does NOT include space to hold the zTo name. */ +#define SZ_FKEY(N) (offsetof(FKey,aCol)+(N)*sizeof(struct sColMap)) + +/* +** SQLite supports many different ways to resolve a constraint +** error. ROLLBACK processing means that a constraint violation +** causes the operation in process to fail and for the current transaction +** to be rolled back. ABORT processing means the operation in process +** fails and any prior changes from that one operation are backed out, +** but the transaction is not rolled back. FAIL processing means that +** the operation in progress stops and returns an error code. But prior +** changes due to the same operation are not backed out and no rollback +** occurs. IGNORE means that the particular row that caused the constraint +** error is not inserted or updated. Processing continues and no error +** is returned. REPLACE means that preexisting database rows that caused +** a UNIQUE constraint violation are removed so that the new insert or +** update can proceed. Processing continues and no error is reported. +** UPDATE applies to insert operations only and means that the insert +** is omitted and the DO UPDATE clause of an upsert is run instead. +** +** RESTRICT, SETNULL, SETDFLT, and CASCADE actions apply only to foreign keys. +** RESTRICT is the same as ABORT for IMMEDIATE foreign keys and the +** same as ROLLBACK for DEFERRED keys. SETNULL means that the foreign +** key is set to NULL. SETDFLT means that the foreign key is set +** to its default value. CASCADE means that a DELETE or UPDATE of the +** referenced table row is propagated into the row that holds the +** foreign key. +** +** The OE_Default value is a place holder that means to use whatever +** conflict resolution algorithm is required from context. +** +** The following symbolic values are used to record which type +** of conflict resolution action to take. +*/ +#define OE_None 0 /* There is no constraint to check */ +#define OE_Rollback 1 /* Fail the operation and rollback the transaction */ +#define OE_Abort 2 /* Back out changes but do no rollback transaction */ +#define OE_Fail 3 /* Stop the operation but leave all prior changes */ +#define OE_Ignore 4 /* Ignore the error. Do not do the INSERT or UPDATE */ +#define OE_Replace 5 /* Delete existing record, then do INSERT or UPDATE */ +#define OE_Update 6 /* Process as a DO UPDATE in an upsert */ +#define OE_Restrict 7 /* OE_Abort for IMMEDIATE, OE_Rollback for DEFERRED */ +#define OE_SetNull 8 /* Set the foreign key value to NULL */ +#define OE_SetDflt 9 /* Set the foreign key value to its default */ +#define OE_Cascade 10 /* Cascade the changes */ +#define OE_Default 11 /* Do whatever the default action is */ + + +/* +** An instance of the following structure is passed as the first +** argument to sqlite3VdbeKeyCompare and is used to control the +** comparison of the two index keys. +** +** The aSortOrder[] and aColl[] arrays have nAllField slots each. There +** are nKeyField slots for the columns of an index then extra slots +** for the rowid or key at the end. The aSortOrder array is located after +** the aColl[] array. +** +** If SQLITE_ENABLE_PREUPDATE_HOOK is defined, then aSortFlags might be NULL +** to indicate that this object is for use by a preupdate hook. When aSortFlags +** is NULL, then nAllField is uninitialized and no space is allocated for +** aColl[], so those fields may not be used. +*/ +struct KeyInfo { + u32 nRef; /* Number of references to this KeyInfo object */ + u8 enc; /* Text encoding - one of the SQLITE_UTF* values */ + u16 nKeyField; /* Number of key columns in the index */ + u16 nAllField; /* Total columns, including key plus others */ + sqlite3 *db; /* The database connection */ + u8 *aSortFlags; /* Sort order for each column. */ + CollSeq *aColl[FLEXARRAY]; /* Collating sequence for each term of the key */ +}; + +/* The size (in bytes) of a KeyInfo object with up to N fields. This includes +** the main body of the KeyInfo object and the aColl[] array of N elements, +** but does not count the memory used to hold aSortFlags[]. */ +#define SZ_KEYINFO(N) (offsetof(KeyInfo,aColl) + (N)*sizeof(CollSeq*)) + +/* The size of a bare KeyInfo with no aColl[] entries */ +#if FLEXARRAY+1 > 1 +# define SZ_KEYINFO_0 offsetof(KeyInfo,aColl) +#else +# define SZ_KEYINFO_0 sizeof(KeyInfo) +#endif + +/* +** Allowed bit values for entries in the KeyInfo.aSortFlags[] array. +*/ +#define KEYINFO_ORDER_DESC 0x01 /* DESC sort order */ +#define KEYINFO_ORDER_BIGNULL 0x02 /* NULL is larger than any other value */ + +/* +** This object holds a record which has been parsed out into individual +** fields, for the purposes of doing a comparison. +** +** A record is an object that contains one or more fields of data. +** Records are used to store the content of a table row and to store +** the key of an index. A blob encoding of a record is created by +** the OP_MakeRecord opcode of the VDBE and is disassembled by the +** OP_Column opcode. +** +** An instance of this object serves as a "key" for doing a search on +** an index b+tree. The goal of the search is to find the entry that +** is closest to the key described by this object. This object might hold +** just a prefix of the key. The number of fields is given by nField. +** +** The r1 and r2 fields are the values to return if this key is less than +** or greater than a key in the btree, respectively. These are normally +** -1 and +1 respectively, but might be inverted to +1 and -1 if the b-tree +** is in DESC order. +** +** The key comparison functions actually return default_rc when they find +** an equals comparison. default_rc can be -1, 0, or +1. If there are +** multiple entries in the b-tree with the same key (when only looking +** at the first nField elements) then default_rc can be set to -1 to +** cause the search to find the last match, or +1 to cause the search to +** find the first match. +** +** The key comparison functions will set eqSeen to true if they ever +** get and equal results when comparing this structure to a b-tree record. +** When default_rc!=0, the search might end up on the record immediately +** before the first match or immediately after the last match. The +** eqSeen field will indicate whether or not an exact match exists in the +** b-tree. +*/ +struct UnpackedRecord { + KeyInfo *pKeyInfo; /* Comparison info for the index that is unpacked */ + Mem *aMem; /* Values for columns of the index */ + union { + char *z; /* Cache of aMem[0].z for vdbeRecordCompareString() */ + i64 i; /* Cache of aMem[0].u.i for vdbeRecordCompareInt() */ + } u; + int n; /* Cache of aMem[0].n used by vdbeRecordCompareString() */ + u16 nField; /* Number of entries in apMem[] */ + i8 default_rc; /* Comparison result if keys are equal */ + u8 errCode; /* Error detected by xRecordCompare (CORRUPT or NOMEM) */ + i8 r1; /* Value to return if (lhs < rhs) */ + i8 r2; /* Value to return if (lhs > rhs) */ + u8 eqSeen; /* True if an equality comparison has been seen */ +}; + + +/* +** Each SQL index is represented in memory by an +** instance of the following structure. +** +** The columns of the table that are to be indexed are described +** by the aiColumn[] field of this structure. For example, suppose +** we have the following table and index: +** +** CREATE TABLE Ex1(c1 int, c2 int, c3 text); +** CREATE INDEX Ex2 ON Ex1(c3,c1); +** +** In the Table structure describing Ex1, nCol==3 because there are +** three columns in the table. In the Index structure describing +** Ex2, nColumn==2 since 2 of the 3 columns of Ex1 are indexed. +** The value of aiColumn is {2, 0}. aiColumn[0]==2 because the +** first column to be indexed (c3) has an index of 2 in Ex1.aCol[]. +** The second column to be indexed (c1) has an index of 0 in +** Ex1.aCol[], hence Ex2.aiColumn[1]==0. +** +** The Index.onError field determines whether or not the indexed columns +** must be unique and what to do if they are not. When Index.onError=OE_None, +** it means this is not a unique index. Otherwise it is a unique index +** and the value of Index.onError indicates which conflict resolution +** algorithm to employ when an attempt is made to insert a non-unique +** element. +** +** The colNotIdxed bitmask is used in combination with SrcItem.colUsed +** for a fast test to see if an index can serve as a covering index. +** colNotIdxed has a 1 bit for every column of the original table that +** is *not* available in the index. Thus the expression +** "colUsed & colNotIdxed" will be non-zero if the index is not a +** covering index. The most significant bit of of colNotIdxed will always +** be true (note-20221022-a). If a column beyond the 63rd column of the +** table is used, the "colUsed & colNotIdxed" test will always be non-zero +** and we have to assume either that the index is not covering, or use +** an alternative (slower) algorithm to determine whether or not +** the index is covering. +** +** While parsing a CREATE TABLE or CREATE INDEX statement in order to +** generate VDBE code (as opposed to parsing one read from an sqlite_schema +** table as part of parsing an existing database schema), transient instances +** of this structure may be created. In this case the Index.tnum variable is +** used to store the address of a VDBE instruction, not a database page +** number (it cannot - the database page is not allocated until the VDBE +** program is executed). See convertToWithoutRowidTable() for details. +*/ +struct Index { + char *zName; /* Name of this index */ + i16 *aiColumn; /* Which columns are used by this index. 1st is 0 */ + LogEst *aiRowLogEst; /* From ANALYZE: Est. rows selected by each column */ + Table *pTable; /* The SQL table being indexed */ + char *zColAff; /* String defining the affinity of each column */ + Index *pNext; /* The next index associated with the same table */ + Schema *pSchema; /* Schema containing this index */ + u8 *aSortOrder; /* for each column: True==DESC, False==ASC */ + const char **azColl; /* Array of collation sequence names for index */ + Expr *pPartIdxWhere; /* WHERE clause for partial indices */ + ExprList *aColExpr; /* Column expressions */ + Pgno tnum; /* DB Page containing root of this index */ + LogEst szIdxRow; /* Estimated average row size in bytes */ + u16 nKeyCol; /* Number of columns forming the key */ + u16 nColumn; /* Nr columns in btree. Can be 2*Table.nCol */ + u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ + unsigned idxType:2; /* 0:Normal 1:UNIQUE, 2:PRIMARY KEY, 3:IPK */ + unsigned bUnordered:1; /* Use this index for == or IN queries only */ + unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */ + unsigned isResized:1; /* True if resizeIndexObject() has been called */ + unsigned isCovering:1; /* True if this is a covering index */ + unsigned noSkipScan:1; /* Do not try to use skip-scan if true */ + unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */ + unsigned bNoQuery:1; /* Do not use this index to optimize queries */ + unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */ + unsigned bHasVCol:1; /* Index references one or more VIRTUAL columns */ + unsigned bHasExpr:1; /* Index contains an expression, either a literal + ** expression, or a reference to a VIRTUAL column */ +#ifdef SQLITE_ENABLE_STAT4 + int nSample; /* Number of elements in aSample[] */ + int mxSample; /* Number of slots allocated to aSample[] */ + int nSampleCol; /* Size of IndexSample.anEq[] and so on */ + tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */ + IndexSample *aSample; /* Samples of the left-most key */ + tRowcnt *aiRowEst; /* Non-logarithmic stat1 data for this index */ + tRowcnt nRowEst0; /* Non-logarithmic number of rows in the index */ +#endif + Bitmask colNotIdxed; /* Unindexed columns in pTab */ +}; + +/* +** Allowed values for Index.idxType +*/ +#define SQLITE_IDXTYPE_APPDEF 0 /* Created using CREATE INDEX */ +#define SQLITE_IDXTYPE_UNIQUE 1 /* Implements a UNIQUE constraint */ +#define SQLITE_IDXTYPE_PRIMARYKEY 2 /* Is the PRIMARY KEY for the table */ +#define SQLITE_IDXTYPE_IPK 3 /* INTEGER PRIMARY KEY index */ + +/* Return true if index X is a PRIMARY KEY index */ +#define IsPrimaryKeyIndex(X) ((X)->idxType==SQLITE_IDXTYPE_PRIMARYKEY) + +/* Return true if index X is a UNIQUE index */ +#define IsUniqueIndex(X) ((X)->onError!=OE_None) + +/* The Index.aiColumn[] values are normally positive integer. But +** there are some negative values that have special meaning: +*/ +#define XN_ROWID (-1) /* Indexed column is the rowid */ +#define XN_EXPR (-2) /* Indexed column is an expression */ + +/* +** Each sample stored in the sqlite_stat4 table is represented in memory +** using a structure of this type. See documentation at the top of the +** analyze.c source file for additional information. +*/ +struct IndexSample { + void *p; /* Pointer to sampled record */ + int n; /* Size of record in bytes */ + tRowcnt *anEq; /* Est. number of rows where the key equals this sample */ + tRowcnt *anLt; /* Est. number of rows where key is less than this sample */ + tRowcnt *anDLt; /* Est. number of distinct keys less than this sample */ +}; + +/* +** Possible values to use within the flags argument to sqlite3GetToken(). +*/ +#define SQLITE_TOKEN_QUOTED 0x1 /* Token is a quoted identifier. */ +#define SQLITE_TOKEN_KEYWORD 0x2 /* Token is a keyword. */ + +/* +** Each token coming out of the lexer is an instance of +** this structure. Tokens are also used as part of an expression. +** +** The memory that "z" points to is owned by other objects. Take care +** that the owner of the "z" string does not deallocate the string before +** the Token goes out of scope! Very often, the "z" points to some place +** in the middle of the Parse.zSql text. But it might also point to a +** static string. +*/ +struct Token { + const char *z; /* Text of the token. Not NULL-terminated! */ + unsigned int n; /* Number of characters in this token */ +}; + +/* +** An instance of this structure contains information needed to generate +** code for a SELECT that contains aggregate functions. +** +** If Expr.op==TK_AGG_COLUMN or TK_AGG_FUNCTION then Expr.pAggInfo is a +** pointer to this structure. The Expr.iAgg field is the index in +** AggInfo.aCol[] or AggInfo.aFunc[] of information needed to generate +** code for that node. +** +** AggInfo.pGroupBy and AggInfo.aFunc.pExpr point to fields within the +** original Select structure that describes the SELECT statement. These +** fields do not need to be freed when deallocating the AggInfo structure. +*/ +struct AggInfo { + u8 directMode; /* Direct rendering mode means take data directly + ** from source tables rather than from accumulators */ + u8 useSortingIdx; /* In direct mode, reference the sorting index rather + ** than the source table */ + u32 nSortingColumn; /* Number of columns in the sorting index */ + int sortingIdx; /* Cursor number of the sorting index */ + int sortingIdxPTab; /* Cursor number of pseudo-table */ + int iFirstReg; /* First register in range for aCol[] and aFunc[] */ + ExprList *pGroupBy; /* The group by clause */ + struct AggInfo_col { /* For each column used in source tables */ + Table *pTab; /* Source table */ + Expr *pCExpr; /* The original expression */ + int iTable; /* Cursor number of the source table */ + int iColumn; /* Column number within the source table */ + int iSorterColumn; /* Column number in the sorting index */ + } *aCol; + int nColumn; /* Number of used entries in aCol[] */ + int nAccumulator; /* Number of columns that show through to the output. + ** Additional columns are used only as parameters to + ** aggregate functions */ + struct AggInfo_func { /* For each aggregate function */ + Expr *pFExpr; /* Expression encoding the function */ + FuncDef *pFunc; /* The aggregate function implementation */ + int iDistinct; /* Ephemeral table used to enforce DISTINCT */ + int iDistAddr; /* Address of OP_OpenEphemeral */ + int iOBTab; /* Ephemeral table to implement ORDER BY */ + u8 bOBPayload; /* iOBTab has payload columns separate from key */ + u8 bOBUnique; /* Enforce uniqueness on iOBTab keys */ + u8 bUseSubtype; /* Transfer subtype info through sorter */ + } *aFunc; + int nFunc; /* Number of entries in aFunc[] */ + u32 selId; /* Select to which this AggInfo belongs */ +#ifdef SQLITE_DEBUG + Select *pSelect; /* SELECT statement that this AggInfo supports */ +#endif +}; + +/* +** Macros to compute aCol[] and aFunc[] register numbers. +** +** These macros should not be used prior to the call to +** assignAggregateRegisters() that computes the value of pAggInfo->iFirstReg. +** The assert()s that are part of this macro verify that constraint. +*/ +#ifndef NDEBUG +#define AggInfoColumnReg(A,I) (assert((A)->iFirstReg),(A)->iFirstReg+(I)) +#define AggInfoFuncReg(A,I) \ + (assert((A)->iFirstReg),(A)->iFirstReg+(A)->nColumn+(I)) +#else +#define AggInfoColumnReg(A,I) ((A)->iFirstReg+(I)) +#define AggInfoFuncReg(A,I) \ + ((A)->iFirstReg+(A)->nColumn+(I)) +#endif + +/* +** The datatype ynVar is a signed integer, either 16-bit or 32-bit. +** Usually it is 16-bits. But if SQLITE_MAX_VARIABLE_NUMBER is greater +** than 32767 we have to make it 32-bit. 16-bit is preferred because +** it uses less memory in the Expr object, which is a big memory user +** in systems with lots of prepared statements. And few applications +** need more than about 10 or 20 variables. But some extreme users want +** to have prepared statements with over 32766 variables, and for them +** the option is available (at compile-time). +*/ +#if SQLITE_MAX_VARIABLE_NUMBER<32767 +typedef i16 ynVar; +#else +typedef int ynVar; +#endif + +/* +** Each node of an expression in the parse tree is an instance +** of this structure. +** +** Expr.op is the opcode. The integer parser token codes are reused +** as opcodes here. For example, the parser defines TK_GE to be an integer +** code representing the ">=" operator. This same integer code is reused +** to represent the greater-than-or-equal-to operator in the expression +** tree. +** +** If the expression is an SQL literal (TK_INTEGER, TK_FLOAT, TK_BLOB, +** or TK_STRING), then Expr.u.zToken contains the text of the SQL literal. If +** the expression is a variable (TK_VARIABLE), then Expr.u.zToken contains the +** variable name. Finally, if the expression is an SQL function (TK_FUNCTION), +** then Expr.u.zToken contains the name of the function. +** +** Expr.pRight and Expr.pLeft are the left and right subexpressions of a +** binary operator. Either or both may be NULL. +** +** Expr.x.pList is a list of arguments if the expression is an SQL function, +** a CASE expression or an IN expression of the form " IN (, ...)". +** Expr.x.pSelect is used if the expression is a sub-select or an expression of +** the form " IN (SELECT ...)". If the EP_xIsSelect bit is set in the +** Expr.flags mask, then Expr.x.pSelect is valid. Otherwise, Expr.x.pList is +** valid. +** +** An expression of the form ID or ID.ID refers to a column in a table. +** For such expressions, Expr.op is set to TK_COLUMN and Expr.iTable is +** the integer cursor number of a VDBE cursor pointing to that table and +** Expr.iColumn is the column number for the specific column. If the +** expression is used as a result in an aggregate SELECT, then the +** value is also stored in the Expr.iAgg column in the aggregate so that +** it can be accessed after all aggregates are computed. +** +** If the expression is an unbound variable marker (a question mark +** character '?' in the original SQL) then the Expr.iTable holds the index +** number for that variable. +** +** If the expression is a subquery then Expr.iColumn holds an integer +** register number containing the result of the subquery. If the +** subquery gives a constant result, then iTable is -1. If the subquery +** gives a different answer at different times during statement processing +** then iTable is the address of a subroutine that computes the subquery. +** +** If the Expr is of type OP_Column, and the table it is selecting from +** is a disk table or the "old.*" pseudo-table, then pTab points to the +** corresponding table definition. +** +** ALLOCATION NOTES: +** +** Expr objects can use a lot of memory space in database schema. To +** help reduce memory requirements, sometimes an Expr object will be +** truncated. And to reduce the number of memory allocations, sometimes +** two or more Expr objects will be stored in a single memory allocation, +** together with Expr.u.zToken strings. +** +** If the EP_Reduced and EP_TokenOnly flags are set when +** an Expr object is truncated. When EP_Reduced is set, then all +** the child Expr objects in the Expr.pLeft and Expr.pRight subtrees +** are contained within the same memory allocation. Note, however, that +** the subtrees in Expr.x.pList or Expr.x.pSelect are always separately +** allocated, regardless of whether or not EP_Reduced is set. +*/ +struct Expr { + u8 op; /* Operation performed by this node */ + char affExpr; /* affinity, or RAISE type */ + u8 op2; /* TK_REGISTER/TK_TRUTH: original value of Expr.op + ** TK_COLUMN: the value of p5 for OP_Column + ** TK_AGG_FUNCTION: nesting depth + ** TK_FUNCTION: NC_SelfRef flag if needs OP_PureFunc */ +#ifdef SQLITE_DEBUG + u8 vvaFlags; /* Verification flags. */ +#endif + u32 flags; /* Various flags. EP_* See below */ + union { + char *zToken; /* Token value. Zero terminated and dequoted */ + int iValue; /* Non-negative integer value if EP_IntValue */ + } u; + + /* If the EP_TokenOnly flag is set in the Expr.flags mask, then no + ** space is allocated for the fields below this point. An attempt to + ** access them will result in a segfault or malfunction. + *********************************************************************/ + + Expr *pLeft; /* Left subnode */ + Expr *pRight; /* Right subnode */ + union { + ExprList *pList; /* op = IN, EXISTS, SELECT, CASE, FUNCTION, BETWEEN */ + Select *pSelect; /* EP_xIsSelect and op = IN, EXISTS, SELECT */ + } x; + + /* If the EP_Reduced flag is set in the Expr.flags mask, then no + ** space is allocated for the fields below this point. An attempt to + ** access them will result in a segfault or malfunction. + *********************************************************************/ + +#if SQLITE_MAX_EXPR_DEPTH>0 + int nHeight; /* Height of the tree headed by this node */ +#endif + int iTable; /* TK_COLUMN: cursor number of table holding column + ** TK_REGISTER: register number + ** TK_TRIGGER: 1 -> new, 0 -> old + ** EP_Unlikely: 134217728 times likelihood + ** TK_IN: ephemeral table holding RHS + ** TK_SELECT_COLUMN: Number of columns on the LHS + ** TK_SELECT: 1st register of result vector */ + ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid. + ** TK_VARIABLE: variable number (always >= 1). + ** TK_SELECT_COLUMN: column of the result vector */ + i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */ + union { + int iJoin; /* If EP_OuterON or EP_InnerON, the right table */ + int iOfst; /* else: start of token from start of statement */ + } w; + AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ + union { + Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL + ** for a column of an index on an expression */ + Window *pWin; /* EP_WinFunc: Window/Filter defn for a function */ + int nReg; /* TK_NULLS: Number of registers to NULL out */ + struct { /* TK_IN, TK_SELECT, and TK_EXISTS */ + int iAddr; /* Subroutine entry address */ + int regReturn; /* Register used to hold return address */ + } sub; + } y; +}; + +/* The following are the meanings of bits in the Expr.flags field. +** Value restrictions: +** +** EP_Agg == NC_HasAgg == SF_HasAgg +** EP_Win == NC_HasWin +*/ +#define EP_OuterON 0x000001 /* Originates in ON/USING clause of outer join */ +#define EP_InnerON 0x000002 /* Originates in ON/USING of an inner join */ +#define EP_Distinct 0x000004 /* Aggregate function with DISTINCT keyword */ +#define EP_HasFunc 0x000008 /* Contains one or more functions of any kind */ +#define EP_Agg 0x000010 /* Contains one or more aggregate functions */ +#define EP_FixedCol 0x000020 /* TK_Column with a known fixed value */ +#define EP_VarSelect 0x000040 /* pSelect is correlated, not constant */ +#define EP_DblQuoted 0x000080 /* token.z was originally in "..." */ +#define EP_InfixFunc 0x000100 /* True for an infix function: LIKE, GLOB, etc */ +#define EP_Collate 0x000200 /* Tree contains a TK_COLLATE operator */ +#define EP_Commuted 0x000400 /* Comparison operator has been commuted */ +#define EP_IntValue 0x000800 /* Integer value contained in u.iValue */ +#define EP_xIsSelect 0x001000 /* x.pSelect is valid (otherwise x.pList is) */ +#define EP_Skip 0x002000 /* Operator does not contribute to affinity */ +#define EP_Reduced 0x004000 /* Expr struct EXPR_REDUCEDSIZE bytes only */ +#define EP_Win 0x008000 /* Contains window functions */ +#define EP_TokenOnly 0x010000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */ +#define EP_FullSize 0x020000 /* Expr structure must remain full sized */ +#define EP_IfNullRow 0x040000 /* The TK_IF_NULL_ROW opcode */ +#define EP_Unlikely 0x080000 /* unlikely() or likelihood() function */ +#define EP_ConstFunc 0x100000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */ +#define EP_CanBeNull 0x200000 /* Can be null despite NOT NULL constraint */ +#define EP_Subquery 0x400000 /* Tree contains a TK_SELECT operator */ +#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */ +#define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */ +#define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */ +#define EP_Quoted 0x4000000 /* TK_ID was originally quoted */ +#define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */ +#define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */ +#define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */ +#define EP_FromDDL 0x40000000 /* Originates from sqlite_schema */ +#define EP_SubtArg 0x80000000 /* Is argument to SQLITE_SUBTYPE function */ + +/* The EP_Propagate mask is a set of properties that automatically propagate +** upwards into parent nodes. +*/ +#define EP_Propagate (EP_Collate|EP_Subquery|EP_HasFunc) + +/* Macros can be used to test, set, or clear bits in the +** Expr.flags field. +*/ +#define ExprHasProperty(E,P) (((E)->flags&(u32)(P))!=0) +#define ExprHasAllProperty(E,P) (((E)->flags&(u32)(P))==(u32)(P)) +#define ExprSetProperty(E,P) (E)->flags|=(u32)(P) +#define ExprClearProperty(E,P) (E)->flags&=~(u32)(P) +#define ExprAlwaysTrue(E) (((E)->flags&(EP_OuterON|EP_IsTrue))==EP_IsTrue) +#define ExprAlwaysFalse(E) (((E)->flags&(EP_OuterON|EP_IsFalse))==EP_IsFalse) +#define ExprIsFullSize(E) (((E)->flags&(EP_Reduced|EP_TokenOnly))==0) + +/* Macros used to ensure that the correct members of unions are accessed +** in Expr. +*/ +#define ExprUseUToken(E) (((E)->flags&EP_IntValue)==0) +#define ExprUseUValue(E) (((E)->flags&EP_IntValue)!=0) +#define ExprUseWOfst(E) (((E)->flags&(EP_InnerON|EP_OuterON))==0) +#define ExprUseWJoin(E) (((E)->flags&(EP_InnerON|EP_OuterON))!=0) +#define ExprUseXList(E) (((E)->flags&EP_xIsSelect)==0) +#define ExprUseXSelect(E) (((E)->flags&EP_xIsSelect)!=0) +#define ExprUseYTab(E) (((E)->flags&(EP_WinFunc|EP_Subrtn))==0) +#define ExprUseYWin(E) (((E)->flags&EP_WinFunc)!=0) +#define ExprUseYSub(E) (((E)->flags&EP_Subrtn)!=0) + +/* Flags for use with Expr.vvaFlags +*/ +#define EP_NoReduce 0x01 /* Cannot EXPRDUP_REDUCE this Expr */ +#define EP_Immutable 0x02 /* Do not change this Expr node */ + +/* The ExprSetVVAProperty() macro is used for Verification, Validation, +** and Accreditation only. It works like ExprSetProperty() during VVA +** processes but is a no-op for delivery. +*/ +#ifdef SQLITE_DEBUG +# define ExprSetVVAProperty(E,P) (E)->vvaFlags|=(P) +# define ExprHasVVAProperty(E,P) (((E)->vvaFlags&(P))!=0) +# define ExprClearVVAProperties(E) (E)->vvaFlags = 0 +#else +# define ExprSetVVAProperty(E,P) +# define ExprHasVVAProperty(E,P) 0 +# define ExprClearVVAProperties(E) +#endif + +/* +** Macros to determine the number of bytes required by a normal Expr +** struct, an Expr struct with the EP_Reduced flag set in Expr.flags +** and an Expr struct with the EP_TokenOnly flag set. +*/ +#define EXPR_FULLSIZE sizeof(Expr) /* Full size */ +#define EXPR_REDUCEDSIZE offsetof(Expr,iTable) /* Common features */ +#define EXPR_TOKENONLYSIZE offsetof(Expr,pLeft) /* Fewer features */ + +/* +** Flags passed to the sqlite3ExprDup() function. See the header comment +** above sqlite3ExprDup() for details. +*/ +#define EXPRDUP_REDUCE 0x0001 /* Used reduced-size Expr nodes */ + +/* +** True if the expression passed as an argument was a function with +** an OVER() clause (a window function). +*/ +#ifdef SQLITE_OMIT_WINDOWFUNC +# define IsWindowFunc(p) 0 +#else +# define IsWindowFunc(p) ( \ + ExprHasProperty((p), EP_WinFunc) && p->y.pWin->eFrmType!=TK_FILTER \ + ) +#endif + +/* +** A list of expressions. Each expression may optionally have a +** name. An expr/name combination can be used in several ways, such +** as the list of "expr AS ID" fields following a "SELECT" or in the +** list of "ID = expr" items in an UPDATE. A list of expressions can +** also be used as the argument to a function, in which case the a.zName +** field is not used. +** +** In order to try to keep memory usage down, the Expr.a.zEName field +** is used for multiple purposes: +** +** eEName Usage +** ---------- ------------------------- +** ENAME_NAME (1) the AS of result set column +** (2) COLUMN= of an UPDATE +** +** ENAME_TAB DB.TABLE.NAME used to resolve names +** of subqueries +** +** ENAME_SPAN Text of the original result set +** expression. +*/ +struct ExprList { + int nExpr; /* Number of expressions on the list */ + int nAlloc; /* Number of a[] slots allocated */ + struct ExprList_item { /* For each expression in the list */ + Expr *pExpr; /* The parse tree for this expression */ + char *zEName; /* Token associated with this expression */ + struct { + u8 sortFlags; /* Mask of KEYINFO_ORDER_* flags */ + unsigned eEName :2; /* Meaning of zEName */ + unsigned done :1; /* Indicates when processing is finished */ + unsigned reusable :1; /* Constant expression is reusable */ + unsigned bSorterRef :1; /* Defer evaluation until after sorting */ + unsigned bNulls :1; /* True if explicit "NULLS FIRST/LAST" */ + unsigned bUsed :1; /* This column used in a SF_NestedFrom subquery */ + unsigned bUsingTerm:1; /* Term from the USING clause of a NestedFrom */ + unsigned bNoExpand: 1; /* Term is an auxiliary in NestedFrom and should + ** not be expanded by "*" in parent queries */ + } fg; + union { + struct { /* Used by any ExprList other than Parse.pConsExpr */ + u16 iOrderByCol; /* For ORDER BY, column number in result set */ + u16 iAlias; /* Index into Parse.aAlias[] for zName */ + } x; + int iConstExprReg; /* Register in which Expr value is cached. Used only + ** by Parse.pConstExpr */ + } u; + } a[FLEXARRAY]; /* One slot for each expression in the list */ +}; + +/* The size (in bytes) of an ExprList object that is big enough to hold +** as many as N expressions. */ +#define SZ_EXPRLIST(N) \ + (offsetof(ExprList,a) + (N)*sizeof(struct ExprList_item)) + +/* +** Allowed values for Expr.a.eEName +*/ +#define ENAME_NAME 0 /* The AS clause of a result set */ +#define ENAME_SPAN 1 /* Complete text of the result set expression */ +#define ENAME_TAB 2 /* "DB.TABLE.NAME" for the result set */ +#define ENAME_ROWID 3 /* "DB.TABLE._rowid_" for * expansion of rowid */ + +/* +** An instance of this structure can hold a simple list of identifiers, +** such as the list "a,b,c" in the following statements: +** +** INSERT INTO t(a,b,c) VALUES ...; +** CREATE INDEX idx ON t(a,b,c); +** CREATE TRIGGER trig BEFORE UPDATE ON t(a,b,c) ...; +** +** The IdList.a.idx field is used when the IdList represents the list of +** column names after a table name in an INSERT statement. In the statement +** +** INSERT INTO t(a,b,c) ... +** +** If "a" is the k-th column of table "t", then IdList.a[0].idx==k. +*/ +struct IdList { + int nId; /* Number of identifiers on the list */ + struct IdList_item { + char *zName; /* Name of the identifier */ + } a[FLEXARRAY]; +}; + +/* The size (in bytes) of an IdList object that can hold up to N IDs. */ +#define SZ_IDLIST(N) (offsetof(IdList,a)+(N)*sizeof(struct IdList_item)) + +/* +** Allowed values for IdList.eType, which determines which value of the a.u4 +** is valid. +*/ +#define EU4_NONE 0 /* Does not use IdList.a.u4 */ +#define EU4_IDX 1 /* Uses IdList.a.u4.idx */ +#define EU4_EXPR 2 /* Uses IdList.a.u4.pExpr -- NOT CURRENTLY USED */ + +/* +** Details of the implementation of a subquery. +*/ +struct Subquery { + Select *pSelect; /* A SELECT statement used in place of a table name */ + int addrFillSub; /* Address of subroutine to initialize a subquery */ + int regReturn; /* Register holding return address of addrFillSub */ + int regResult; /* Registers holding results of a co-routine */ +}; + +/* +** The SrcItem object represents a single term in the FROM clause of a query. +** The SrcList object is mostly an array of SrcItems. +** +** The jointype starts out showing the join type between the current table +** and the next table on the list. The parser builds the list this way. +** But sqlite3SrcListShiftJoinType() later shifts the jointypes so that each +** jointype expresses the join between the table and the previous table. +** +** In the colUsed field, the high-order bit (bit 63) is set if the table +** contains more than 63 columns and the 64-th or later column is used. +** +** Aggressive use of "union" helps keep the size of the object small. This +** has been shown to boost performance, in addition to saving memory. +** Access to union elements is gated by the following rules which should +** always be checked, either by an if-statement or by an assert(). +** +** Field Only access if this is true +** --------------- ----------------------------------- +** u1.zIndexedBy fg.isIndexedBy +** u1.pFuncArg fg.isTabFunc +** u1.nRow !fg.isTabFunc && !fg.isIndexedBy +** +** u2.pIBIndex fg.isIndexedBy +** u2.pCteUse fg.isCte +** +** u3.pOn !fg.isUsing +** u3.pUsing fg.isUsing +** +** u4.zDatabase !fg.fixedSchema && !fg.isSubquery +** u4.pSchema fg.fixedSchema +** u4.pSubq fg.isSubquery +** +** See also the sqlite3SrcListDelete() routine for assert() statements that +** check invariants on the fields of this object, especially the flags +** inside the fg struct. +*/ +struct SrcItem { + char *zName; /* Name of the table */ + char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */ + Table *pSTab; /* Table object for zName. Mnemonic: Srcitem-TABle */ + struct { + u8 jointype; /* Type of join between this table and the previous */ + unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */ + unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */ + unsigned isSubquery :1; /* True if this term is a subquery */ + unsigned isTabFunc :1; /* True if table-valued-function syntax */ + unsigned isCorrelated :1; /* True if sub-query is correlated */ + unsigned isMaterialized:1; /* This is a materialized view */ + unsigned viaCoroutine :1; /* Implemented as a co-routine */ + unsigned isRecursive :1; /* True for recursive reference in WITH */ + unsigned fromDDL :1; /* Comes from sqlite_schema */ + unsigned isCte :1; /* This is a CTE */ + unsigned notCte :1; /* This item may not match a CTE */ + unsigned isUsing :1; /* u3.pUsing is valid */ + unsigned isOn :1; /* u3.pOn was once valid and non-NULL */ + unsigned isSynthUsing :1; /* u3.pUsing is synthesized from NATURAL */ + unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */ + unsigned rowidUsed :1; /* The ROWID of this table is referenced */ + unsigned fixedSchema :1; /* Uses u4.pSchema, not u4.zDatabase */ + unsigned hadSchema :1; /* Had u4.zDatabase before u4.pSchema */ + unsigned fromExists :1; /* Comes from WHERE EXISTS(...) */ + } fg; + int iCursor; /* The VDBE cursor number used to access this table */ + Bitmask colUsed; /* Bit N set if column N used. Details above for N>62 */ + union { + char *zIndexedBy; /* Identifier from "INDEXED BY " clause */ + ExprList *pFuncArg; /* Arguments to table-valued-function */ + u32 nRow; /* Number of rows in a VALUES clause */ + } u1; + union { + Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */ + CteUse *pCteUse; /* CTE Usage info when fg.isCte is true */ + } u2; + union { + Expr *pOn; /* fg.isUsing==0 => The ON clause of a join */ + IdList *pUsing; /* fg.isUsing==1 => The USING clause of a join */ + } u3; + union { + Schema *pSchema; /* Schema to which this item is fixed */ + char *zDatabase; /* Name of database holding this table */ + Subquery *pSubq; /* Description of a subquery */ + } u4; +}; + +/* +** The OnOrUsing object represents either an ON clause or a USING clause. +** It can never be both at the same time, but it can be neither. +*/ +struct OnOrUsing { + Expr *pOn; /* The ON clause of a join */ + IdList *pUsing; /* The USING clause of a join */ +}; + +/* +** This object represents one or more tables that are the source of +** content for an SQL statement. For example, a single SrcList object +** is used to hold the FROM clause of a SELECT statement. SrcList also +** represents the target tables for DELETE, INSERT, and UPDATE statements. +** +*/ +struct SrcList { + int nSrc; /* Number of tables or subqueries in the FROM clause */ + u32 nAlloc; /* Number of entries allocated in a[] below */ + SrcItem a[FLEXARRAY]; /* One entry for each identifier on the list */ +}; + +/* Size (in bytes) of a SrcList object that can hold as many as N +** SrcItem objects. */ +#define SZ_SRCLIST(N) (offsetof(SrcList,a)+(N)*sizeof(SrcItem)) + +/* Size (in bytes( of a SrcList object that holds 1 SrcItem. This is a +** special case of SZ_SRCITEM(1) that comes up often. */ +#define SZ_SRCLIST_1 (offsetof(SrcList,a)+sizeof(SrcItem)) + +/* +** Permitted values of the SrcList.a.jointype field +*/ +#define JT_INNER 0x01 /* Any kind of inner or cross join */ +#define JT_CROSS 0x02 /* Explicit use of the CROSS keyword */ +#define JT_NATURAL 0x04 /* True for a "natural" join */ +#define JT_LEFT 0x08 /* Left outer join */ +#define JT_RIGHT 0x10 /* Right outer join */ +#define JT_OUTER 0x20 /* The "OUTER" keyword is present */ +#define JT_LTORJ 0x40 /* One of the LEFT operands of a RIGHT JOIN + ** Mnemonic: Left Table Of Right Join */ +#define JT_ERROR 0x80 /* unknown or unsupported join type */ + +/* +** Flags appropriate for the wctrlFlags parameter of sqlite3WhereBegin() +** and the WhereInfo.wctrlFlags member. +** +** Value constraints (enforced via assert()): +** WHERE_USE_LIMIT == SF_FixedLimit +*/ +#define WHERE_ORDERBY_NORMAL 0x0000 /* No-op */ +#define WHERE_ORDERBY_MIN 0x0001 /* ORDER BY processing for min() func */ +#define WHERE_ORDERBY_MAX 0x0002 /* ORDER BY processing for max() func */ +#define WHERE_ONEPASS_DESIRED 0x0004 /* Want to do one-pass UPDATE/DELETE */ +#define WHERE_ONEPASS_MULTIROW 0x0008 /* ONEPASS is ok with multiple rows */ +#define WHERE_DUPLICATES_OK 0x0010 /* Ok to return a row more than once */ +#define WHERE_OR_SUBCLAUSE 0x0020 /* Processing a sub-WHERE as part of + ** the OR optimization */ +#define WHERE_GROUPBY 0x0040 /* pOrderBy is really a GROUP BY */ +#define WHERE_DISTINCTBY 0x0080 /* pOrderby is really a DISTINCT clause */ +#define WHERE_WANT_DISTINCT 0x0100 /* All output needs to be distinct */ +#define WHERE_SORTBYGROUP 0x0200 /* Support sqlite3WhereIsSorted() */ +#define WHERE_AGG_DISTINCT 0x0400 /* Query is "SELECT agg(DISTINCT ...)" */ +#define WHERE_ORDERBY_LIMIT 0x0800 /* ORDERBY+LIMIT on the inner loop */ +#define WHERE_RIGHT_JOIN 0x1000 /* Processing a RIGHT JOIN */ +#define WHERE_KEEP_ALL_JOINS 0x2000 /* Do not do the omit-noop-join opt */ +#define WHERE_USE_LIMIT 0x4000 /* Use the LIMIT in cost estimates */ + /* 0x8000 not currently used */ + +/* Allowed return values from sqlite3WhereIsDistinct() +*/ +#define WHERE_DISTINCT_NOOP 0 /* DISTINCT keyword not used */ +#define WHERE_DISTINCT_UNIQUE 1 /* No duplicates */ +#define WHERE_DISTINCT_ORDERED 2 /* All duplicates are adjacent */ +#define WHERE_DISTINCT_UNORDERED 3 /* Duplicates are scattered */ + +/* +** A NameContext defines a context in which to resolve table and column +** names. The context consists of a list of tables (the pSrcList) field and +** a list of named expression (pEList). The named expression list may +** be NULL. The pSrc corresponds to the FROM clause of a SELECT or +** to the table being operated on by INSERT, UPDATE, or DELETE. The +** pEList corresponds to the result set of a SELECT and is NULL for +** other statements. +** +** NameContexts can be nested. When resolving names, the inner-most +** context is searched first. If no match is found, the next outer +** context is checked. If there is still no match, the next context +** is checked. This process continues until either a match is found +** or all contexts are check. When a match is found, the nRef member of +** the context containing the match is incremented. +** +** Each subquery gets a new NameContext. The pNext field points to the +** NameContext in the parent query. Thus the process of scanning the +** NameContext list corresponds to searching through successively outer +** subqueries looking for a match. +*/ +struct NameContext { + Parse *pParse; /* The parser */ + SrcList *pSrcList; /* One or more tables used to resolve names */ + union { + ExprList *pEList; /* Optional list of result-set columns */ + AggInfo *pAggInfo; /* Information about aggregates at this level */ + Upsert *pUpsert; /* ON CONFLICT clause information from an upsert */ + int iBaseReg; /* For TK_REGISTER when parsing RETURNING */ + } uNC; + NameContext *pNext; /* Next outer name context. NULL for outermost */ + int nRef; /* Number of names resolved by this context */ + int nNcErr; /* Number of errors encountered while resolving names */ + int ncFlags; /* Zero or more NC_* flags defined below */ + u32 nNestedSelect; /* Number of nested selects using this NC */ + Select *pWinSelect; /* SELECT statement for any window functions */ +}; + +/* +** Allowed values for the NameContext, ncFlags field. +** +** Value constraints (all checked via assert()): +** NC_HasAgg == SF_HasAgg == EP_Agg +** NC_MinMaxAgg == SF_MinMaxAgg == SQLITE_FUNC_MINMAX +** NC_OrderAgg == SF_OrderByReqd == SQLITE_FUNC_ANYORDER +** NC_HasWin == EP_Win +** +*/ +#define NC_AllowAgg 0x000001 /* Aggregate functions are allowed here */ +#define NC_PartIdx 0x000002 /* True if resolving a partial index WHERE */ +#define NC_IsCheck 0x000004 /* True if resolving a CHECK constraint */ +#define NC_GenCol 0x000008 /* True for a GENERATED ALWAYS AS clause */ +#define NC_HasAgg 0x000010 /* One or more aggregate functions seen */ +#define NC_IdxExpr 0x000020 /* True if resolving columns of CREATE INDEX */ +#define NC_SelfRef 0x00002e /* Combo: PartIdx, isCheck, GenCol, and IdxExpr */ +#define NC_Subquery 0x000040 /* A subquery has been seen */ +#define NC_UEList 0x000080 /* True if uNC.pEList is used */ +#define NC_UAggInfo 0x000100 /* True if uNC.pAggInfo is used */ +#define NC_UUpsert 0x000200 /* True if uNC.pUpsert is used */ +#define NC_UBaseReg 0x000400 /* True if uNC.iBaseReg is used */ +#define NC_MinMaxAgg 0x001000 /* min/max aggregates seen. See note above */ +/* 0x002000 // available for reuse */ +#define NC_AllowWin 0x004000 /* Window functions are allowed here */ +#define NC_HasWin 0x008000 /* One or more window functions seen */ +#define NC_IsDDL 0x010000 /* Resolving names in a CREATE statement */ +#define NC_InAggFunc 0x020000 /* True if analyzing arguments to an agg func */ +#define NC_FromDDL 0x040000 /* SQL text comes from sqlite_schema */ +#define NC_NoSelect 0x080000 /* Do not descend into sub-selects */ +#define NC_Where 0x100000 /* Processing WHERE clause of a SELECT */ +#define NC_OrderAgg 0x8000000 /* Has an aggregate other than count/min/max */ + +/* +** An instance of the following object describes a single ON CONFLICT +** clause in an upsert. +** +** The pUpsertTarget field is only set if the ON CONFLICT clause includes +** conflict-target clause. (In "ON CONFLICT(a,b)" the "(a,b)" is the +** conflict-target clause.) The pUpsertTargetWhere is the optional +** WHERE clause used to identify partial unique indexes. +** +** pUpsertSet is the list of column=expr terms of the UPDATE statement. +** The pUpsertSet field is NULL for a ON CONFLICT DO NOTHING. The +** pUpsertWhere is the WHERE clause for the UPDATE and is NULL if the +** WHERE clause is omitted. +*/ +struct Upsert { + ExprList *pUpsertTarget; /* Optional description of conflict target */ + Expr *pUpsertTargetWhere; /* WHERE clause for partial index targets */ + ExprList *pUpsertSet; /* The SET clause from an ON CONFLICT UPDATE */ + Expr *pUpsertWhere; /* WHERE clause for the ON CONFLICT UPDATE */ + Upsert *pNextUpsert; /* Next ON CONFLICT clause in the list */ + u8 isDoUpdate; /* True for DO UPDATE. False for DO NOTHING */ + u8 isDup; /* True if 2nd or later with same pUpsertIdx */ + /* Above this point is the parse tree for the ON CONFLICT clauses. + ** The next group of fields stores intermediate data. */ + void *pToFree; /* Free memory when deleting the Upsert object */ + /* All fields above are owned by the Upsert object and must be freed + ** when the Upsert is destroyed. The fields below are used to transfer + ** information from the INSERT processing down into the UPDATE processing + ** while generating code. The fields below are owned by the INSERT + ** statement and will be freed by INSERT processing. */ + Index *pUpsertIdx; /* UNIQUE constraint specified by pUpsertTarget */ + SrcList *pUpsertSrc; /* Table to be updated */ + int regData; /* First register holding array of VALUES */ + int iDataCur; /* Index of the data cursor */ + int iIdxCur; /* Index of the first index cursor */ +}; + +/* +** An instance of the following structure contains all information +** needed to generate code for a single SELECT statement. +*/ +struct Select { + u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */ + LogEst nSelectRow; /* Estimated number of result rows */ + u32 selFlags; /* Various SF_* values */ + int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */ + u32 selId; /* Unique identifier number for this SELECT */ + ExprList *pEList; /* The fields of the result */ + SrcList *pSrc; /* The FROM clause */ + Expr *pWhere; /* The WHERE clause */ + ExprList *pGroupBy; /* The GROUP BY clause */ + Expr *pHaving; /* The HAVING clause */ + ExprList *pOrderBy; /* The ORDER BY clause */ + Select *pPrior; /* Prior select in a compound select statement */ + Select *pNext; /* Next select to the left in a compound */ + Expr *pLimit; /* LIMIT expression. NULL means not used. */ + With *pWith; /* WITH clause attached to this select. Or NULL. */ +#ifndef SQLITE_OMIT_WINDOWFUNC + Window *pWin; /* List of window functions */ + Window *pWinDefn; /* List of named window definitions */ +#endif +}; + +/* +** Allowed values for Select.selFlags. The "SF" prefix stands for +** "Select Flag". +** +** Value constraints (all checked via assert()) +** SF_HasAgg == NC_HasAgg +** SF_MinMaxAgg == NC_MinMaxAgg == SQLITE_FUNC_MINMAX +** SF_OrderByReqd == NC_OrderAgg == SQLITE_FUNC_ANYORDER +** SF_FixedLimit == WHERE_USE_LIMIT +*/ +#define SF_Distinct 0x0000001 /* Output should be DISTINCT */ +#define SF_All 0x0000002 /* Includes the ALL keyword */ +#define SF_Resolved 0x0000004 /* Identifiers have been resolved */ +#define SF_Aggregate 0x0000008 /* Contains agg functions or a GROUP BY */ +#define SF_HasAgg 0x0000010 /* Contains aggregate functions */ +#define SF_ClonedRhsIn 0x0000020 /* Cloned RHS of an IN operator */ +#define SF_Expanded 0x0000040 /* sqlite3SelectExpand() called on this */ +#define SF_HasTypeInfo 0x0000080 /* FROM subqueries have Table metadata */ +#define SF_Compound 0x0000100 /* Part of a compound query */ +#define SF_Values 0x0000200 /* Synthesized from VALUES clause */ +#define SF_MultiValue 0x0000400 /* Single VALUES term with multiple rows */ +#define SF_NestedFrom 0x0000800 /* Part of a parenthesized FROM clause */ +#define SF_MinMaxAgg 0x0001000 /* Aggregate containing min() or max() */ +#define SF_Recursive 0x0002000 /* The recursive part of a recursive CTE */ +#define SF_FixedLimit 0x0004000 /* nSelectRow set by a constant LIMIT */ +/* 0x0008000 // available for reuse */ +#define SF_Converted 0x0010000 /* By convertCompoundSelectToSubquery() */ +#define SF_IncludeHidden 0x0020000 /* Include hidden columns in output */ +#define SF_ComplexResult 0x0040000 /* Result contains subquery or function */ +#define SF_WhereBegin 0x0080000 /* Really a WhereBegin() call. Debug Only */ +#define SF_WinRewrite 0x0100000 /* Window function rewrite accomplished */ +#define SF_View 0x0200000 /* SELECT statement is a view */ +/* 0x0400000 // available for reuse */ +#define SF_UFSrcCheck 0x0800000 /* Check pSrc as required by UPDATE...FROM */ +#define SF_PushDown 0x1000000 /* Modified by WHERE-clause push-down opt */ +#define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */ +#define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */ +#define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */ +#define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */ +#define SF_Correlated 0x20000000 /* True if references the outer context */ +#define SF_OnToWhere 0x40000000 /* One or more ON clauses moved to WHERE */ + +/* True if SrcItem X is a subquery that has SF_NestedFrom */ +#define IsNestedFrom(X) \ + ((X)->fg.isSubquery && \ + ((X)->u4.pSubq->pSelect->selFlags&SF_NestedFrom)!=0) + +/* +** The results of a SELECT can be distributed in several ways, as defined +** by one of the following macros. The "SRT" prefix means "SELECT Result +** Type". +** +** SRT_Exists Store a 1 in memory cell pDest->iSDParm if the result +** set is not empty. +** +** SRT_Discard Throw the results away. This is used by SELECT +** statements within triggers whose only purpose is +** the side-effects of functions. +** +** SRT_Output Generate a row of output (using the OP_ResultRow +** opcode) for each row in the result set. +** +** SRT_Mem Only valid if the result is a single column. +** Store the first column of the first result row +** in register pDest->iSDParm then abandon the rest +** of the query. This destination implies "LIMIT 1". +** +** SRT_Set The result must be a single column. Store each +** row of result as the key in table pDest->iSDParm. +** Apply the affinity pDest->affSdst before storing +** results. if pDest->iSDParm2 is positive, then it is +** a register holding a Bloom filter for the IN operator +** that should be populated in addition to the +** pDest->iSDParm table. This SRT is used to +** implement "IN (SELECT ...)". +** +** SRT_EphemTab Create an temporary table pDest->iSDParm and store +** the result there. The cursor is left open after +** returning. This is like SRT_Table except that +** this destination uses OP_OpenEphemeral to create +** the table first. +** +** SRT_Coroutine Generate a co-routine that returns a new row of +** results each time it is invoked. The entry point +** of the co-routine is stored in register pDest->iSDParm +** and the result row is stored in pDest->nDest registers +** starting with pDest->iSdst. +** +** SRT_Table Store results in temporary table pDest->iSDParm. +** SRT_Fifo This is like SRT_EphemTab except that the table +** is assumed to already be open. SRT_Fifo has +** the additional property of being able to ignore +** the ORDER BY clause. +** +** SRT_DistFifo Store results in a temporary table pDest->iSDParm. +** But also use temporary table pDest->iSDParm+1 as +** a record of all prior results and ignore any duplicate +** rows. Name means: "Distinct Fifo". +** +** SRT_Queue Store results in priority queue pDest->iSDParm (really +** an index). Append a sequence number so that all entries +** are distinct. +** +** SRT_DistQueue Store results in priority queue pDest->iSDParm only if +** the same record has never been stored before. The +** index at pDest->iSDParm+1 hold all prior stores. +** +** SRT_Upfrom Store results in the temporary table already opened by +** pDest->iSDParm. If (pDest->iSDParm<0), then the temp +** table is an intkey table - in this case the first +** column returned by the SELECT is used as the integer +** key. If (pDest->iSDParm>0), then the table is an index +** table. (pDest->iSDParm) is the number of key columns in +** each index record in this case. +*/ +#define SRT_Exists 1 /* Store 1 if the result is not empty */ +#define SRT_Discard 2 /* Do not save the results anywhere */ +#define SRT_DistFifo 3 /* Like SRT_Fifo, but unique results only */ +#define SRT_DistQueue 4 /* Like SRT_Queue, but unique results only */ + +/* The DISTINCT clause is ignored for all of the above. Not that +** IgnorableDistinct() implies IgnorableOrderby() */ +#define IgnorableDistinct(X) ((X->eDest)<=SRT_DistQueue) + +#define SRT_Queue 5 /* Store result in an queue */ +#define SRT_Fifo 6 /* Store result as data with an automatic rowid */ + +/* The ORDER BY clause is ignored for all of the above */ +#define IgnorableOrderby(X) ((X->eDest)<=SRT_Fifo) + +#define SRT_Output 7 /* Output each row of result */ +#define SRT_Mem 8 /* Store result in a memory cell */ +#define SRT_Set 9 /* Store results as keys in an index */ +#define SRT_EphemTab 10 /* Create transient tab and store like SRT_Table */ +#define SRT_Coroutine 11 /* Generate a single row of result */ +#define SRT_Table 12 /* Store result as data with an automatic rowid */ +#define SRT_Upfrom 13 /* Store result as data with rowid */ + +/* +** An instance of this object describes where to put of the results of +** a SELECT statement. +*/ +struct SelectDest { + u8 eDest; /* How to dispose of the results. One of SRT_* above. */ + int iSDParm; /* A parameter used by the eDest disposal method */ + int iSDParm2; /* A second parameter for the eDest disposal method */ + int iSdst; /* Base register where results are written */ + int nSdst; /* Number of registers allocated */ + char *zAffSdst; /* Affinity used for SRT_Set */ + ExprList *pOrderBy; /* Key columns for SRT_Queue and SRT_DistQueue */ +}; + +/* +** During code generation of statements that do inserts into AUTOINCREMENT +** tables, the following information is attached to the Table.u.autoInc.p +** pointer of each autoincrement table to record some side information that +** the code generator needs. We have to keep per-table autoincrement +** information in case inserts are done within triggers. Triggers do not +** normally coordinate their activities, but we do need to coordinate the +** loading and saving of autoincrement information. +*/ +struct AutoincInfo { + AutoincInfo *pNext; /* Next info block in a list of them all */ + Table *pTab; /* Table this info block refers to */ + int iDb; /* Index in sqlite3.aDb[] of database holding pTab */ + int regCtr; /* Memory register holding the rowid counter */ +}; + +/* +** At least one instance of the following structure is created for each +** trigger that may be fired while parsing an INSERT, UPDATE or DELETE +** statement. All such objects are stored in the linked list headed at +** Parse.pTriggerPrg and deleted once statement compilation has been +** completed. +** +** A Vdbe sub-program that implements the body and WHEN clause of trigger +** TriggerPrg.pTrigger, assuming a default ON CONFLICT clause of +** TriggerPrg.orconf, is stored in the TriggerPrg.pProgram variable. +** The Parse.pTriggerPrg list never contains two entries with the same +** values for both pTrigger and orconf. +** +** The TriggerPrg.aColmask[0] variable is set to a mask of old.* columns +** accessed (or set to 0 for triggers fired as a result of INSERT +** statements). Similarly, the TriggerPrg.aColmask[1] variable is set to +** a mask of new.* columns used by the program. +*/ +struct TriggerPrg { + Trigger *pTrigger; /* Trigger this program was coded from */ + TriggerPrg *pNext; /* Next entry in Parse.pTriggerPrg list */ + SubProgram *pProgram; /* Program implementing pTrigger/orconf */ + int orconf; /* Default ON CONFLICT policy */ + u32 aColmask[2]; /* Masks of old.*, new.* columns accessed */ +}; + +/* +** The yDbMask datatype for the bitmask of all attached databases. +*/ +#if SQLITE_MAX_ATTACHED>30 + typedef unsigned char yDbMask[(SQLITE_MAX_ATTACHED+9)/8]; +# define DbMaskTest(M,I) (((M)[(I)/8]&(1<<((I)&7)))!=0) +# define DbMaskZero(M) memset((M),0,sizeof(M)) +# define DbMaskSet(M,I) (M)[(I)/8]|=(1<<((I)&7)) +# define DbMaskAllZero(M) sqlite3DbMaskAllZero(M) +# define DbMaskNonZero(M) (sqlite3DbMaskAllZero(M)==0) +#else + typedef unsigned int yDbMask; +# define DbMaskTest(M,I) (((M)&(((yDbMask)1)<<(I)))!=0) +# define DbMaskZero(M) ((M)=0) +# define DbMaskSet(M,I) ((M)|=(((yDbMask)1)<<(I))) +# define DbMaskAllZero(M) ((M)==0) +# define DbMaskNonZero(M) ((M)!=0) +#endif + +/* +** For each index X that has as one of its arguments either an expression +** or the name of a virtual generated column, and if X is in scope such that +** the value of the expression can simply be read from the index, then +** there is an instance of this object on the Parse.pIdxExpr list. +** +** During code generation, while generating code to evaluate expressions, +** this list is consulted and if a matching expression is found, the value +** is read from the index rather than being recomputed. +*/ +struct IndexedExpr { + Expr *pExpr; /* The expression contained in the index */ + int iDataCur; /* The data cursor associated with the index */ + int iIdxCur; /* The index cursor */ + int iIdxCol; /* The index column that contains value of pExpr */ + u8 bMaybeNullRow; /* True if we need an OP_IfNullRow check */ + u8 aff; /* Affinity of the pExpr expression */ + IndexedExpr *pIENext; /* Next in a list of all indexed expressions */ +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + const char *zIdxName; /* Name of index, used only for bytecode comments */ +#endif +}; + +/* +** An instance of the ParseCleanup object specifies an operation that +** should be performed after parsing to deallocation resources obtained +** during the parse and which are no longer needed. +*/ +struct ParseCleanup { + ParseCleanup *pNext; /* Next cleanup task */ + void *pPtr; /* Pointer to object to deallocate */ + void (*xCleanup)(sqlite3*,void*); /* Deallocation routine */ +}; + +/* +** An SQL parser context. A copy of this structure is passed through +** the parser and down into all the parser action routine in order to +** carry around information that is global to the entire parse. +** +** The structure is divided into two parts. When the parser and code +** generate call themselves recursively, the first part of the structure +** is constant but the second part is reset at the beginning and end of +** each recursion. +** +** The nTableLock and aTableLock variables are only used if the shared-cache +** feature is enabled (if sqlite3Tsd()->useSharedData is true). They are +** used to store the set of table-locks required by the statement being +** compiled. Function sqlite3TableLock() is used to add entries to the +** list. +*/ +struct Parse { + sqlite3 *db; /* The main database structure */ + char *zErrMsg; /* An error message */ + Vdbe *pVdbe; /* An engine for executing database bytecode */ + int rc; /* Return code from execution */ + LogEst nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */ + u8 nested; /* Number of nested calls to the parser/code generator */ + u8 nTempReg; /* Number of temporary registers in aTempReg[] */ + u8 isMultiWrite; /* True if statement may modify/insert multiple rows */ + u8 disableLookaside; /* Number of times lookaside has been disabled */ + u8 prepFlags; /* SQLITE_PREPARE_* flags */ + u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */ + u8 mSubrtnSig; /* mini Bloom filter on available SubrtnSig.selId */ + u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */ + u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ +#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) + u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */ +#endif +#ifdef SQLITE_DEBUG + u8 ifNotExists; /* Might be true if IF NOT EXISTS. Assert()s only */ + u8 isCreate; /* CREATE TABLE, INDEX, or VIEW (but not TRIGGER) + ** and ALTER TABLE ADD COLUMN. */ +#endif + bft disableTriggers:1; /* True to disable triggers */ + bft mayAbort :1; /* True if statement may throw an ABORT exception */ + bft hasCompound :1; /* Need to invoke convertCompoundSelectToSubquery() */ + bft bReturning :1; /* Coding a RETURNING trigger */ + bft bHasExists :1; /* Has a correlated "EXISTS (SELECT ....)" expression */ + bft colNamesSet :1; /* TRUE after OP_ColumnName has been issued to pVdbe */ + bft bHasWith :1; /* True if statement contains WITH */ + bft okConstFactor:1; /* OK to factor out constants */ + bft checkSchema :1; /* Causes schema cookie check after an error */ + int nRangeReg; /* Size of the temporary register block */ + int iRangeReg; /* First register in temporary register block */ + int nErr; /* Number of errors seen */ + int nTab; /* Number of previously allocated VDBE cursors */ + int nMem; /* Number of memory cells used so far */ + int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */ + int iSelfTab; /* Table associated with an index on expr, or negative + ** of the base register during check-constraint eval */ + int nNestSel; /* Number of nested SELECT statements and/or VIEWs */ + int nLabel; /* The *negative* of the number of labels used */ + int nLabelAlloc; /* Number of slots in aLabel */ + int *aLabel; /* Space to hold the labels */ + ExprList *pConstExpr;/* Constant expressions */ + IndexedExpr *pIdxEpr;/* List of expressions used by active indexes */ + IndexedExpr *pIdxPartExpr; /* Exprs constrained by index WHERE clauses */ + yDbMask writeMask; /* Start a write transaction on these databases */ + yDbMask cookieMask; /* Bitmask of schema verified databases */ + int nMaxArg; /* Max args to xUpdate and xFilter vtab methods */ + int nSelect; /* Number of SELECT stmts. Counter for Select.selId */ +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + u32 nProgressSteps; /* xProgress steps taken during sqlite3_prepare() */ +#endif +#ifndef SQLITE_OMIT_SHARED_CACHE + int nTableLock; /* Number of locks in aTableLock */ + TableLock *aTableLock; /* Required table locks for shared-cache mode */ +#endif + AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */ + Parse *pToplevel; /* Parse structure for main program (or NULL) */ + Table *pTriggerTab; /* Table triggers are being coded for */ + TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */ + ParseCleanup *pCleanup; /* List of cleanup operations to run after parse */ + + /************************************************************************** + ** Fields above must be initialized to zero. The fields that follow, + ** down to the beginning of the recursive section, do not need to be + ** initialized as they will be set before being used. The boundary is + ** determined by offsetof(Parse,aTempReg). + **************************************************************************/ + + int aTempReg[8]; /* Holding area for temporary registers */ + Parse *pOuterParse; /* Outer Parse object when nested */ + Token sNameToken; /* Token with unqualified schema object name */ + u32 oldmask; /* Mask of old.* columns referenced */ + u32 newmask; /* Mask of new.* columns referenced */ + union { + struct { /* These fields available when isCreate is true */ + int addrCrTab; /* Address of OP_CreateBtree on CREATE TABLE */ + int regRowid; /* Register holding rowid of CREATE TABLE entry */ + int regRoot; /* Register holding root page for new objects */ + Token constraintName; /* Name of the constraint currently being parsed */ + } cr; + struct { /* These fields available to all other statements */ + Returning *pReturning; /* The RETURNING clause */ + } d; + } u1; + + /************************************************************************ + ** Above is constant between recursions. Below is reset before and after + ** each recursion. The boundary between these two regions is determined + ** using offsetof(Parse,sLastToken) so the sLastToken field must be the + ** first field in the recursive region. + ************************************************************************/ + + Token sLastToken; /* The last token parsed */ + ynVar nVar; /* Number of '?' variables seen in the SQL so far */ + u8 iPkSortOrder; /* ASC or DESC for INTEGER PRIMARY KEY */ + u8 explain; /* True if the EXPLAIN flag is found on the query */ + u8 eParseMode; /* PARSE_MODE_XXX constant */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + int nVtabLock; /* Number of virtual tables to lock */ +#endif + int nHeight; /* Expression tree height of current sub-select */ + int addrExplain; /* Address of current OP_Explain opcode */ + VList *pVList; /* Mapping between variable names and numbers */ + Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */ + const char *zTail; /* All SQL text past the last semicolon parsed */ + Table *pNewTable; /* A table being constructed by CREATE TABLE */ + Index *pNewIndex; /* An index being constructed by CREATE INDEX. + ** Also used to hold redundant UNIQUE constraints + ** during a RENAME COLUMN */ + Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */ + const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + Token sArg; /* Complete text of a module argument */ + Table **apVtabLock; /* Pointer to virtual tables needing locking */ +#endif + With *pWith; /* Current WITH clause, or NULL */ +#ifndef SQLITE_OMIT_ALTERTABLE + RenameToken *pRename; /* Tokens subject to renaming by ALTER TABLE */ +#endif +}; + +/* Allowed values for Parse.eParseMode +*/ +#define PARSE_MODE_NORMAL 0 +#define PARSE_MODE_DECLARE_VTAB 1 +#define PARSE_MODE_RENAME 2 +#define PARSE_MODE_UNMAP 3 + +/* +** Sizes and pointers of various parts of the Parse object. +*/ +#define PARSE_HDR(X) (((char*)(X))+offsetof(Parse,zErrMsg)) +#define PARSE_HDR_SZ (offsetof(Parse,aTempReg)-offsetof(Parse,zErrMsg)) /* Recursive part w/o aColCache*/ +#define PARSE_RECURSE_SZ offsetof(Parse,sLastToken) /* Recursive part */ +#define PARSE_TAIL_SZ (sizeof(Parse)-PARSE_RECURSE_SZ) /* Non-recursive part */ +#define PARSE_TAIL(X) (((char*)(X))+PARSE_RECURSE_SZ) /* Pointer to tail */ + +/* +** Return true if currently inside an sqlite3_declare_vtab() call. +*/ +#ifdef SQLITE_OMIT_VIRTUALTABLE + #define IN_DECLARE_VTAB 0 +#else + #define IN_DECLARE_VTAB (pParse->eParseMode==PARSE_MODE_DECLARE_VTAB) +#endif + +#if defined(SQLITE_OMIT_ALTERTABLE) + #define IN_RENAME_OBJECT 0 +#else + #define IN_RENAME_OBJECT (pParse->eParseMode>=PARSE_MODE_RENAME) +#endif + +#if defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_OMIT_ALTERTABLE) + #define IN_SPECIAL_PARSE 0 +#else + #define IN_SPECIAL_PARSE (pParse->eParseMode!=PARSE_MODE_NORMAL) +#endif + +/* +** An instance of the following structure can be declared on a stack and used +** to save the Parse.zAuthContext value so that it can be restored later. +*/ +struct AuthContext { + const char *zAuthContext; /* Put saved Parse.zAuthContext here */ + Parse *pParse; /* The Parse structure */ +}; + +/* +** Bitfield flags for P5 value in various opcodes. +** +** Value constraints (enforced via assert()): +** OPFLAG_LENGTHARG == SQLITE_FUNC_LENGTH +** OPFLAG_TYPEOFARG == SQLITE_FUNC_TYPEOF +** OPFLAG_BULKCSR == BTREE_BULKLOAD +** OPFLAG_SEEKEQ == BTREE_SEEK_EQ +** OPFLAG_FORDELETE == BTREE_FORDELETE +** OPFLAG_SAVEPOSITION == BTREE_SAVEPOSITION +** OPFLAG_AUXDELETE == BTREE_AUXDELETE +*/ +#define OPFLAG_NCHANGE 0x01 /* OP_Insert: Set to update db->nChange */ + /* Also used in P2 (not P5) of OP_Delete */ +#define OPFLAG_NOCHNG 0x01 /* OP_VColumn nochange for UPDATE */ +#define OPFLAG_EPHEM 0x01 /* OP_Column: Ephemeral output is ok */ +#define OPFLAG_LASTROWID 0x20 /* Set to update db->lastRowid */ +#define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */ +#define OPFLAG_APPEND 0x08 /* This is likely to be an append */ +#define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */ +#define OPFLAG_ISNOOP 0x40 /* OP_Delete does pre-update-hook only */ +#define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */ +#define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */ +#define OPFLAG_BYTELENARG 0xc0 /* OP_Column only for octet_length() */ +#define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */ +#define OPFLAG_SEEKEQ 0x02 /* OP_Open** cursor uses EQ seek only */ +#define OPFLAG_FORDELETE 0x08 /* OP_Open should use BTREE_FORDELETE */ +#define OPFLAG_P2ISREG 0x10 /* P2 to OP_Open** is a register number */ +#define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */ +#define OPFLAG_SAVEPOSITION 0x02 /* OP_Delete/Insert: save cursor pos */ +#define OPFLAG_AUXDELETE 0x04 /* OP_Delete: index in a DELETE op */ +#define OPFLAG_NOCHNG_MAGIC 0x6d /* OP_MakeRecord: serialtype 10 is ok */ +#define OPFLAG_PREFORMAT 0x80 /* OP_Insert uses preformatted cell */ + +/* +** Each trigger present in the database schema is stored as an instance of +** struct Trigger. +** +** Pointers to instances of struct Trigger are stored in two ways. +** 1. In the "trigHash" hash table (part of the sqlite3* that represents the +** database). This allows Trigger structures to be retrieved by name. +** 2. All triggers associated with a single table form a linked list, using the +** pNext member of struct Trigger. A pointer to the first element of the +** linked list is stored as the "pTrigger" member of the associated +** struct Table. +** +** The "step_list" member points to the first element of a linked list +** containing the SQL statements specified as the trigger program. +*/ +struct Trigger { + char *zName; /* The name of the trigger */ + char *table; /* The table or view to which the trigger applies */ + u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT */ + u8 tr_tm; /* One of TRIGGER_BEFORE, TRIGGER_AFTER */ + u8 bReturning; /* This trigger implements a RETURNING clause */ + Expr *pWhen; /* The WHEN clause of the expression (may be NULL) */ + IdList *pColumns; /* If this is an UPDATE OF trigger, + the is stored here */ + Schema *pSchema; /* Schema containing the trigger */ + Schema *pTabSchema; /* Schema containing the table */ + TriggerStep *step_list; /* Link list of trigger program steps */ + Trigger *pNext; /* Next trigger associated with the table */ +}; + +/* +** A trigger is either a BEFORE or an AFTER trigger. The following constants +** determine which. +** +** If there are multiple triggers, you might of some BEFORE and some AFTER. +** In that cases, the constants below can be ORed together. +*/ +#define TRIGGER_BEFORE 1 +#define TRIGGER_AFTER 2 + +/* +** An instance of struct TriggerStep is used to store a single SQL statement +** that is a part of a trigger-program. +** +** Instances of struct TriggerStep are stored in a singly linked list (linked +** using the "pNext" member) referenced by the "step_list" member of the +** associated struct Trigger instance. The first element of the linked list is +** the first step of the trigger-program. +** +** The "op" member indicates whether this is a "DELETE", "INSERT", "UPDATE" or +** "SELECT" statement. The meanings of the other members is determined by the +** value of "op" as follows: +** +** (op == TK_INSERT) +** orconf -> stores the ON CONFLICT algorithm +** pSelect -> The content to be inserted - either a SELECT statement or +** a VALUES clause. +** pSrc -> Table to insert into. +** pIdList -> If this is an INSERT INTO ... () VALUES ... +** statement, then this stores the column-names to be +** inserted into. +** pUpsert -> The ON CONFLICT clauses for an Upsert +** +** (op == TK_DELETE) +** pSrc -> Table to delete from +** pWhere -> The WHERE clause of the DELETE statement if one is specified. +** Otherwise NULL. +** +** (op == TK_UPDATE) +** pSrc -> Table to update, followed by any FROM clause tables. +** pWhere -> The WHERE clause of the UPDATE statement if one is specified. +** Otherwise NULL. +** pExprList -> A list of the columns to update and the expressions to update +** them to. See sqlite3Update() documentation of "pChanges" +** argument. +** +** (op == TK_SELECT) +** pSelect -> The SELECT statement +** +** (op == TK_RETURNING) +** pExprList -> The list of expressions that follow the RETURNING keyword. +** +*/ +struct TriggerStep { + u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT, + ** or TK_RETURNING */ + u8 orconf; /* OE_Rollback etc. */ + Trigger *pTrig; /* The trigger that this step is a part of */ + Select *pSelect; /* SELECT statement or RHS of INSERT INTO SELECT ... */ + SrcList *pSrc; /* Table to insert/update/delete */ + Expr *pWhere; /* The WHERE clause for DELETE or UPDATE steps */ + ExprList *pExprList; /* SET clause for UPDATE, or RETURNING clause */ + IdList *pIdList; /* Column names for INSERT */ + Upsert *pUpsert; /* Upsert clauses on an INSERT */ + char *zSpan; /* Original SQL text of this command */ + TriggerStep *pNext; /* Next in the link-list */ + TriggerStep *pLast; /* Last element in link-list. Valid for 1st elem only */ +}; + +/* +** Information about a RETURNING clause +*/ +struct Returning { + Parse *pParse; /* The parse that includes the RETURNING clause */ + ExprList *pReturnEL; /* List of expressions to return */ + Trigger retTrig; /* The transient trigger that implements RETURNING */ + TriggerStep retTStep; /* The trigger step */ + int iRetCur; /* Transient table holding RETURNING results */ + int nRetCol; /* Number of in pReturnEL after expansion */ + int iRetReg; /* Register array for holding a row of RETURNING */ + char zName[40]; /* Name of trigger: "sqlite_returning_%p" */ +}; + +/* +** An object used to accumulate the text of a string where we +** do not necessarily know how big the string will be in the end. +*/ +struct sqlite3_str { + sqlite3 *db; /* Optional database for lookaside. Can be NULL */ + char *zText; /* The string collected so far */ + u32 nAlloc; /* Amount of space allocated in zText */ + u32 mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */ + u32 nChar; /* Length of the string so far */ + u8 accError; /* SQLITE_NOMEM or SQLITE_TOOBIG */ + u8 printfFlags; /* SQLITE_PRINTF flags below */ +}; +#define SQLITE_PRINTF_INTERNAL 0x01 /* Internal-use-only converters allowed */ +#define SQLITE_PRINTF_SQLFUNC 0x02 /* SQL function arguments to VXPrintf */ +#define SQLITE_PRINTF_MALLOCED 0x04 /* True if zText is allocated space */ + +#define isMalloced(X) (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0) + +/* +** The following object is the header for an "RCStr" or "reference-counted +** string". An RCStr is passed around and used like any other char* +** that has been dynamically allocated. The important interface +** differences: +** +** 1. RCStr strings are reference counted. They are deallocated +** when the reference count reaches zero. +** +** 2. Use sqlite3RCStrUnref() to free an RCStr string rather than +** sqlite3_free() +** +** 3. Make a (read-only) copy of a read-only RCStr string using +** sqlite3RCStrRef(). +** +** "String" is in the name, but an RCStr object can also be used to hold +** binary data. +*/ +struct RCStr { + u64 nRCRef; /* Number of references */ + /* Total structure size should be a multiple of 8 bytes for alignment */ +}; + +/* +** A pointer to this structure is used to communicate information +** from sqlite3Init and OP_ParseSchema into the sqlite3InitCallback. +*/ +typedef struct { + sqlite3 *db; /* The database being initialized */ + char **pzErrMsg; /* Error message stored here */ + int iDb; /* 0 for main database. 1 for TEMP, 2.. for ATTACHed */ + int rc; /* Result code stored here */ + u32 mInitFlags; /* Flags controlling error messages */ + u32 nInitRow; /* Number of rows processed */ + Pgno mxPage; /* Maximum page number. 0 for no limit. */ +} InitData; + +/* +** Allowed values for mInitFlags +*/ +#define INITFLAG_AlterMask 0x0007 /* Types of ALTER */ +#define INITFLAG_AlterRename 0x0001 /* Reparse after a RENAME */ +#define INITFLAG_AlterDrop 0x0002 /* Reparse after a DROP COLUMN */ +#define INITFLAG_AlterAdd 0x0003 /* Reparse after an ADD COLUMN */ +#define INITFLAG_AlterDropCons 0x0004 /* Reparse after an ADD COLUMN */ + +/* Tuning parameters are set using SQLITE_TESTCTRL_TUNE and are controlled +** on debug-builds of the CLI using ".testctrl tune ID VALUE". Tuning +** parameters are for temporary use during development, to help find +** optimal values for parameters in the query planner. The should not +** be used on trunk check-ins. They are a temporary mechanism available +** for transient development builds only. +** +** Tuning parameters are numbered starting with 1. +*/ +#define SQLITE_NTUNE 6 /* Should be zero for all trunk check-ins */ +#ifdef SQLITE_DEBUG +# define Tuning(X) (sqlite3Config.aTune[(X)-1]) +#else +# define Tuning(X) 0 +#endif + +/* +** Structure containing global configuration data for the SQLite library. +** +** This structure also contains some state information. +*/ +struct Sqlite3Config { + int bMemstat; /* True to enable memory status */ + u8 bCoreMutex; /* True to enable core mutexing */ + u8 bFullMutex; /* True to enable full mutexing */ + u8 bOpenUri; /* True to interpret filenames as URIs */ + u8 bUseCis; /* Use covering indices for full-scans */ + u8 bSmallMalloc; /* Avoid large memory allocations if true */ + u8 bExtraSchemaChecks; /* Verify type,name,tbl_name in schema */ +#ifdef SQLITE_DEBUG + u8 bJsonSelfcheck; /* Double-check JSON parsing */ +#endif + int mxStrlen; /* Maximum string length */ + int neverCorrupt; /* Database is always well-formed */ + int szLookaside; /* Default lookaside buffer size */ + int nLookaside; /* Default lookaside buffer count */ + int nStmtSpill; /* Stmt-journal spill-to-disk threshold */ + sqlite3_mem_methods m; /* Low-level memory allocation interface */ + sqlite3_mutex_methods mutex; /* Low-level mutex interface */ + sqlite3_pcache_methods2 pcache2; /* Low-level page-cache interface */ + void *pHeap; /* Heap storage space */ + int nHeap; /* Size of pHeap[] */ + int mnReq, mxReq; /* Min and max heap requests sizes */ + sqlite3_int64 szMmap; /* mmap() space per open file */ + sqlite3_int64 mxMmap; /* Maximum value for szMmap */ + void *pPage; /* Page cache memory */ + int szPage; /* Size of each page in pPage[] */ + int nPage; /* Number of pages in pPage[] */ + int mxParserStack; /* maximum depth of the parser stack */ + int sharedCacheEnabled; /* true if shared-cache mode enabled */ + u32 szPma; /* Maximum Sorter PMA size */ + /* The above might be initialized to non-zero. The following need to always + ** initially be zero, however. */ + int isInit; /* True after initialization has finished */ + int inProgress; /* True while initialization in progress */ + int isMutexInit; /* True after mutexes are initialized */ + int isMallocInit; /* True after malloc is initialized */ + int isPCacheInit; /* True after malloc is initialized */ + int nRefInitMutex; /* Number of users of pInitMutex */ + sqlite3_mutex *pInitMutex; /* Mutex used by sqlite3_initialize() */ + void (*xLog)(void*,int,const char*); /* Function for logging */ + void *pLogArg; /* First argument to xLog() */ +#ifdef SQLITE_ENABLE_SQLLOG + void(*xSqllog)(void*,sqlite3*,const char*, int); + void *pSqllogArg; +#endif +#ifdef SQLITE_VDBE_COVERAGE + /* The following callback (if not NULL) is invoked on every VDBE branch + ** operation. Set the callback using SQLITE_TESTCTRL_VDBE_COVERAGE. + */ + void (*xVdbeBranch)(void*,unsigned iSrcLine,u8 eThis,u8 eMx); /* Callback */ + void *pVdbeBranchArg; /* 1st argument */ +#endif +#ifndef SQLITE_OMIT_DESERIALIZE + sqlite3_int64 mxMemdbSize; /* Default max memdb size */ +#endif +#ifndef SQLITE_UNTESTABLE + int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */ +#endif +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + u32 mNoVisibleRowid; /* TF_NoVisibleRowid if the ROWID_IN_VIEW + ** feature is disabled. 0 if rowids can + ** occur in views. */ +#endif + int bLocaltimeFault; /* True to fail localtime() calls */ + int (*xAltLocaltime)(const void*,void*); /* Alternative localtime() routine */ + int iOnceResetThreshold; /* When to reset OP_Once counters */ + u32 szSorterRef; /* Min size in bytes to use sorter-refs */ + unsigned int iPrngSeed; /* Alternative fixed seed for the PRNG */ + /* vvvv--- must be last ---vvv */ +#ifdef SQLITE_DEBUG + sqlite3_int64 aTune[SQLITE_NTUNE]; /* Tuning parameters */ +#endif +}; + +/* +** This macro is used inside of assert() statements to indicate that +** the assert is only valid on a well-formed database. Instead of: +** +** assert( X ); +** +** One writes: +** +** assert( X || CORRUPT_DB ); +** +** CORRUPT_DB is true during normal operation. CORRUPT_DB does not indicate +** that the database is definitely corrupt, only that it might be corrupt. +** For most test cases, CORRUPT_DB is set to false using a special +** sqlite3_test_control(). This enables assert() statements to prove +** things that are always true for well-formed databases. +*/ +#define CORRUPT_DB (sqlite3Config.neverCorrupt==0) + +/* +** Context pointer passed down through the tree-walk. +*/ +struct Walker { + Parse *pParse; /* Parser context. */ + int (*xExprCallback)(Walker*, Expr*); /* Callback for expressions */ + int (*xSelectCallback)(Walker*,Select*); /* Callback for SELECTs */ + void (*xSelectCallback2)(Walker*,Select*);/* Second callback for SELECTs */ + int walkerDepth; /* Number of subqueries */ + u16 eCode; /* A small processing code */ + u16 mWFlags; /* Use-dependent flags */ + union { /* Extra data for callback */ + NameContext *pNC; /* Naming context */ + int n; /* A counter */ + int iCur; /* A cursor number */ + int sz; /* String literal length */ + SrcList *pSrcList; /* FROM clause */ + struct CCurHint *pCCurHint; /* Used by codeCursorHint() */ + struct RefSrcList *pRefSrcList; /* sqlite3ReferencesSrcList() */ + int *aiCol; /* array of column indexes */ + struct IdxCover *pIdxCover; /* Check for index coverage */ + ExprList *pGroupBy; /* GROUP BY clause */ + Select *pSelect; /* HAVING to WHERE clause ctx */ + struct WindowRewrite *pRewrite; /* Window rewrite context */ + struct WhereConst *pConst; /* WHERE clause constants */ + struct RenameCtx *pRename; /* RENAME COLUMN context */ + struct Table *pTab; /* Table of generated column */ + struct CoveringIndexCheck *pCovIdxCk; /* Check for covering index */ + SrcItem *pSrcItem; /* A single FROM clause item */ + DbFixer *pFix; /* See sqlite3FixSelect() */ + Mem *aMem; /* See sqlite3BtreeCursorHint() */ + struct CheckOnCtx *pCheckOnCtx; /* See selectCheckOnClauses() */ + } u; +}; + +/* +** The following structure contains information used by the sqliteFix... +** routines as they walk the parse tree to make database references +** explicit. +*/ +struct DbFixer { + Parse *pParse; /* The parsing context. Error messages written here */ + Walker w; /* Walker object */ + Schema *pSchema; /* Fix items to this schema */ + u8 bTemp; /* True for TEMP schema entries */ + const char *zDb; /* Make sure all objects are contained in this database */ + const char *zType; /* Type of the container - used for error messages */ + const Token *pName; /* Name of the container - used for error messages */ +}; + +/* Forward declarations */ +SQLITE_PRIVATE int sqlite3WalkExpr(Walker*, Expr*); +SQLITE_PRIVATE int sqlite3WalkExprNN(Walker*, Expr*); +SQLITE_PRIVATE int sqlite3WalkExprList(Walker*, ExprList*); +SQLITE_PRIVATE int sqlite3WalkSelect(Walker*, Select*); +SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker*, Select*); +SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker*, Select*); +SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker*, Expr*); +SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker*, Select*); +SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker*, Select*); +SQLITE_PRIVATE int sqlite3WalkerDepthIncrease(Walker*,Select*); +SQLITE_PRIVATE void sqlite3WalkerDepthDecrease(Walker*,Select*); +SQLITE_PRIVATE void sqlite3WalkWinDefnDummyCallback(Walker*,Select*); + +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE void sqlite3SelectWalkAssert2(Walker*, Select*); +#endif + +#ifndef SQLITE_OMIT_CTE +SQLITE_PRIVATE void sqlite3SelectPopWith(Walker*, Select*); +#else +# define sqlite3SelectPopWith 0 +#endif + +/* +** Return code from the parse-tree walking primitives and their +** callbacks. +*/ +#define WRC_Continue 0 /* Continue down into children */ +#define WRC_Prune 1 /* Omit children but continue walking siblings */ +#define WRC_Abort 2 /* Abandon the tree walk */ + +/* +** A single common table expression +*/ +struct Cte { + char *zName; /* Name of this CTE */ + ExprList *pCols; /* List of explicit column names, or NULL */ + Select *pSelect; /* The definition of this CTE */ + const char *zCteErr; /* Error message for circular references */ + CteUse *pUse; /* Usage information for this CTE */ + u8 eM10d; /* The MATERIALIZED flag */ +}; + +/* +** Allowed values for the materialized flag (eM10d): +*/ +#define M10d_Yes 0 /* AS MATERIALIZED */ +#define M10d_Any 1 /* Not specified. Query planner's choice */ +#define M10d_No 2 /* AS NOT MATERIALIZED */ + +/* +** An instance of the With object represents a WITH clause containing +** one or more CTEs (common table expressions). +*/ +struct With { + int nCte; /* Number of CTEs in the WITH clause */ + int bView; /* Belongs to the outermost Select of a view */ + With *pOuter; /* Containing WITH clause, or NULL */ + Cte a[FLEXARRAY]; /* For each CTE in the WITH clause.... */ +}; + +/* The size (in bytes) of a With object that can hold as many +** as N different CTEs. */ +#define SZ_WITH(N) (offsetof(With,a) + (N)*sizeof(Cte)) + +/* +** The Cte object is not guaranteed to persist for the entire duration +** of code generation. (The query flattener or other parser tree +** edits might delete it.) The following object records information +** about each Common Table Expression that must be preserved for the +** duration of the parse. +** +** The CteUse objects are freed using sqlite3ParserAddCleanup() rather +** than sqlite3SelectDelete(), which is what enables them to persist +** until the end of code generation. +*/ +struct CteUse { + int nUse; /* Number of users of this CTE */ + int addrM9e; /* Start of subroutine to compute materialization */ + int regRtn; /* Return address register for addrM9e subroutine */ + int iCur; /* Ephemeral table holding the materialization */ + LogEst nRowEst; /* Estimated number of rows in the table */ + u8 eM10d; /* The MATERIALIZED flag */ +}; + + +/* Client data associated with sqlite3_set_clientdata() and +** sqlite3_get_clientdata(). +*/ +struct DbClientData { + DbClientData *pNext; /* Next in a linked list */ + void *pData; /* The data */ + void (*xDestructor)(void*); /* Destructor. Might be NULL */ + char zName[FLEXARRAY]; /* Name of this client data. MUST BE LAST */ +}; + +/* The size (in bytes) of a DbClientData object that can has a name +** that is N bytes long, including the zero-terminator. */ +#define SZ_DBCLIENTDATA(N) (offsetof(DbClientData,zName)+(N)) + +#ifdef SQLITE_DEBUG +/* +** An instance of the TreeView object is used for printing the content of +** data structures on sqlite3DebugPrintf() using a tree-like view. +*/ +struct TreeView { + int iLevel; /* Which level of the tree we are on */ + u8 bLine[100]; /* Draw vertical in column i if bLine[i] is true */ +}; +#endif /* SQLITE_DEBUG */ + +/* +** This object is used in various ways, most (but not all) related to window +** functions. +** +** (1) A single instance of this structure is attached to the +** the Expr.y.pWin field for each window function in an expression tree. +** This object holds the information contained in the OVER clause, +** plus additional fields used during code generation. +** +** (2) All window functions in a single SELECT form a linked-list +** attached to Select.pWin. The Window.pFunc and Window.pExpr +** fields point back to the expression that is the window function. +** +** (3) The terms of the WINDOW clause of a SELECT are instances of this +** object on a linked list attached to Select.pWinDefn. +** +** (4) For an aggregate function with a FILTER clause, an instance +** of this object is stored in Expr.y.pWin with eFrmType set to +** TK_FILTER. In this case the only field used is Window.pFilter. +** +** The uses (1) and (2) are really the same Window object that just happens +** to be accessible in two different ways. Use case (3) are separate objects. +*/ +struct Window { + char *zName; /* Name of window (may be NULL) */ + char *zBase; /* Name of base window for chaining (may be NULL) */ + ExprList *pPartition; /* PARTITION BY clause */ + ExprList *pOrderBy; /* ORDER BY clause */ + u8 eFrmType; /* TK_RANGE, TK_GROUPS, TK_ROWS, or 0 */ + u8 eStart; /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */ + u8 eEnd; /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */ + u8 bImplicitFrame; /* True if frame was implicitly specified */ + u8 eExclude; /* TK_NO, TK_CURRENT, TK_TIES, TK_GROUP, or 0 */ + Expr *pStart; /* Expression for " PRECEDING" */ + Expr *pEnd; /* Expression for " FOLLOWING" */ + Window **ppThis; /* Pointer to this object in Select.pWin list */ + Window *pNextWin; /* Next window function belonging to this SELECT */ + Expr *pFilter; /* The FILTER expression */ + FuncDef *pWFunc; /* The function */ + int iEphCsr; /* Partition buffer or Peer buffer */ + int regAccum; /* Accumulator */ + int regResult; /* Interim result */ + int csrApp; /* Function cursor (used by min/max) */ + int regApp; /* Function register (also used by min/max) */ + int regPart; /* Array of registers for PARTITION BY values */ + Expr *pOwner; /* Expression object this window is attached to */ + int nBufferCol; /* Number of columns in buffer table */ + int iArgCol; /* Offset of first argument for this function */ + int regOne; /* Register containing constant value 1 */ + int regStartRowid; + int regEndRowid; + u8 bExprArgs; /* Defer evaluation of window function arguments + ** due to the SQLITE_SUBTYPE flag */ +}; + +SQLITE_PRIVATE Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList *pRow); +SQLITE_PRIVATE void sqlite3MultiValuesEnd(Parse *pParse, Select *pVal); + +#ifndef SQLITE_OMIT_WINDOWFUNC +SQLITE_PRIVATE void sqlite3WindowDelete(sqlite3*, Window*); +SQLITE_PRIVATE void sqlite3WindowUnlinkFromSelect(Window*); +SQLITE_PRIVATE void sqlite3WindowListDelete(sqlite3 *db, Window *p); +SQLITE_PRIVATE Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*, u8); +SQLITE_PRIVATE void sqlite3WindowAttach(Parse*, Expr*, Window*); +SQLITE_PRIVATE void sqlite3WindowLink(Select *pSel, Window *pWin); +SQLITE_PRIVATE int sqlite3WindowCompare(const Parse*, const Window*, const Window*, int); +SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse*, Select*); +SQLITE_PRIVATE void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int); +SQLITE_PRIVATE int sqlite3WindowRewrite(Parse*, Select*); +SQLITE_PRIVATE void sqlite3WindowUpdate(Parse*, Window*, Window*, FuncDef*); +SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p); +SQLITE_PRIVATE Window *sqlite3WindowListDup(sqlite3 *db, Window *p); +SQLITE_PRIVATE void sqlite3WindowFunctions(void); +SQLITE_PRIVATE void sqlite3WindowChain(Parse*, Window*, Window*); +SQLITE_PRIVATE Window *sqlite3WindowAssemble(Parse*, Window*, ExprList*, ExprList*, Token*); +#else +# define sqlite3WindowDelete(a,b) +# define sqlite3WindowFunctions() +# define sqlite3WindowAttach(a,b,c) +#endif + +/* +** Assuming zIn points to the first byte of a UTF-8 character, +** advance zIn to point to the first byte of the next UTF-8 character. +*/ +#define SQLITE_SKIP_UTF8(zIn) { \ + if( (*(zIn++))>=0xc0 ){ \ + while( (*zIn & 0xc0)==0x80 ){ zIn++; } \ + } \ +} + +/* +** The SQLITE_*_BKPT macros are substitutes for the error codes with +** the same name but without the _BKPT suffix. These macros invoke +** routines that report the line-number on which the error originated +** using sqlite3_log(). The routines also provide a convenient place +** to set a debugger breakpoint. +*/ +SQLITE_PRIVATE int sqlite3ReportError(int iErr, int lineno, const char *zType); +SQLITE_PRIVATE int sqlite3CorruptError(int); +SQLITE_PRIVATE int sqlite3MisuseError(int); +SQLITE_PRIVATE int sqlite3CantopenError(int); +#define SQLITE_CORRUPT_BKPT sqlite3CorruptError(__LINE__) +#define SQLITE_MISUSE_BKPT sqlite3MisuseError(__LINE__) +#define SQLITE_CANTOPEN_BKPT sqlite3CantopenError(__LINE__) +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3NomemError(int); +SQLITE_PRIVATE int sqlite3IoerrnomemError(int); +# define SQLITE_NOMEM_BKPT sqlite3NomemError(__LINE__) +# define SQLITE_IOERR_NOMEM_BKPT sqlite3IoerrnomemError(__LINE__) +#else +# define SQLITE_NOMEM_BKPT SQLITE_NOMEM +# define SQLITE_IOERR_NOMEM_BKPT SQLITE_IOERR_NOMEM +#endif +#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_CORRUPT_PGNO) +SQLITE_PRIVATE int sqlite3CorruptPgnoError(int,Pgno); +# define SQLITE_CORRUPT_PGNO(P) sqlite3CorruptPgnoError(__LINE__,(P)) +#else +# define SQLITE_CORRUPT_PGNO(P) sqlite3CorruptError(__LINE__) +#endif + +/* +** FTS3 and FTS4 both require virtual table support +*/ +#if defined(SQLITE_OMIT_VIRTUALTABLE) +# undef SQLITE_ENABLE_FTS3 +# undef SQLITE_ENABLE_FTS4 +#endif + +/* +** FTS4 is really an extension for FTS3. It is enabled using the +** SQLITE_ENABLE_FTS3 macro. But to avoid confusion we also call +** the SQLITE_ENABLE_FTS4 macro to serve as an alias for SQLITE_ENABLE_FTS3. +*/ +#if defined(SQLITE_ENABLE_FTS4) && !defined(SQLITE_ENABLE_FTS3) +# define SQLITE_ENABLE_FTS3 1 +#endif + +/* +** The following macros mimic the standard library functions toupper(), +** isspace(), isalnum(), isdigit() and isxdigit(), respectively. The +** sqlite versions only work for ASCII characters, regardless of locale. +*/ +#ifdef SQLITE_ASCII +# define sqlite3Toupper(x) ((x)&~(sqlite3CtypeMap[(unsigned char)(x)]&0x20)) +# define sqlite3Isspace(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x01) +# define sqlite3Isalnum(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x06) +# define sqlite3Isalpha(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x02) +# define sqlite3Isdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x04) +# define sqlite3Isxdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x08) +# define sqlite3Tolower(x) (sqlite3UpperToLower[(unsigned char)(x)]) +# define sqlite3Isquote(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x80) +# define sqlite3JsonId1(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x42) +# define sqlite3JsonId2(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x46) +#else +# define sqlite3Toupper(x) toupper((unsigned char)(x)) +# define sqlite3Isspace(x) isspace((unsigned char)(x)) +# define sqlite3Isalnum(x) isalnum((unsigned char)(x)) +# define sqlite3Isalpha(x) isalpha((unsigned char)(x)) +# define sqlite3Isdigit(x) isdigit((unsigned char)(x)) +# define sqlite3Isxdigit(x) isxdigit((unsigned char)(x)) +# define sqlite3Tolower(x) tolower((unsigned char)(x)) +# define sqlite3Isquote(x) ((x)=='"'||(x)=='\''||(x)=='['||(x)=='`') +# define sqlite3JsonId1(x) (sqlite3IsIdChar(x)&&(x)<'0') +# define sqlite3JsonId2(x) sqlite3IsIdChar(x) +#endif +SQLITE_PRIVATE int sqlite3IsIdChar(u8); + +/* +** Internal function prototypes +*/ +SQLITE_PRIVATE int sqlite3StrICmp(const char*,const char*); +SQLITE_PRIVATE int sqlite3Strlen30(const char*); +#define sqlite3Strlen30NN(C) (strlen(C)&0x3fffffff) +SQLITE_PRIVATE char *sqlite3ColumnType(Column*,char*); +#define sqlite3StrNICmp sqlite3_strnicmp + +SQLITE_PRIVATE int sqlite3MallocInit(void); +SQLITE_PRIVATE void sqlite3MallocEnd(void); +SQLITE_PRIVATE void *sqlite3Malloc(u64); +SQLITE_PRIVATE void *sqlite3MallocZero(u64); +SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3*, u64); +SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3*, u64); +SQLITE_PRIVATE void *sqlite3DbMallocRawNN(sqlite3*, u64); +SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3*,const char*); +SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3*,const char*, u64); +SQLITE_PRIVATE char *sqlite3DbSpanDup(sqlite3*,const char*,const char*); +SQLITE_PRIVATE void *sqlite3Realloc(void*, u64); +SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64); +SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, u64); +SQLITE_PRIVATE void sqlite3DbFree(sqlite3*, void*); +SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3*, void*); +SQLITE_PRIVATE void sqlite3DbNNFreeNN(sqlite3*, void*); +SQLITE_PRIVATE int sqlite3MallocSize(const void*); +SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3*, const void*); +SQLITE_PRIVATE void *sqlite3PageMalloc(int); +SQLITE_PRIVATE void sqlite3PageFree(void*); +SQLITE_PRIVATE void sqlite3MemSetDefault(void); +#ifndef SQLITE_UNTESTABLE +SQLITE_PRIVATE void sqlite3BenignMallocHooks(void (*)(void), void (*)(void)); +#endif +SQLITE_PRIVATE int sqlite3HeapNearlyFull(void); + +/* +** On systems with ample stack space and that support alloca(), make +** use of alloca() to obtain space for large automatic objects. By default, +** obtain space from malloc(). +** +** The alloca() routine never returns NULL. This will cause code paths +** that deal with sqlite3StackAlloc() failures to be unreachable. +*/ +#ifdef SQLITE_USE_ALLOCA +# define sqlite3StackAllocRaw(D,N) alloca(N) +# define sqlite3StackAllocRawNN(D,N) alloca(N) +# define sqlite3StackFree(D,P) +# define sqlite3StackFreeNN(D,P) +#else +# define sqlite3StackAllocRaw(D,N) sqlite3DbMallocRaw(D,N) +# define sqlite3StackAllocRawNN(D,N) sqlite3DbMallocRawNN(D,N) +# define sqlite3StackFree(D,P) sqlite3DbFree(D,P) +# define sqlite3StackFreeNN(D,P) sqlite3DbFreeNN(D,P) +#endif + +/* Do not allow both MEMSYS5 and MEMSYS3 to be defined together. If they +** are, disable MEMSYS3 +*/ +#ifdef SQLITE_ENABLE_MEMSYS5 +SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys5(void); +#undef SQLITE_ENABLE_MEMSYS3 +#endif +#ifdef SQLITE_ENABLE_MEMSYS3 +SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void); +#endif + + +#ifndef SQLITE_MUTEX_OMIT +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void); +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void); +SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int); +SQLITE_PRIVATE int sqlite3MutexInit(void); +SQLITE_PRIVATE int sqlite3MutexEnd(void); +#endif +#if !defined(SQLITE_MUTEX_OMIT) && !defined(SQLITE_MUTEX_NOOP) +SQLITE_PRIVATE void sqlite3MemoryBarrier(void); +#else +# define sqlite3MemoryBarrier() +#endif + +SQLITE_PRIVATE sqlite3_int64 sqlite3StatusValue(int); +SQLITE_PRIVATE void sqlite3StatusUp(int, int); +SQLITE_PRIVATE void sqlite3StatusDown(int, int); +SQLITE_PRIVATE void sqlite3StatusHighwater(int, int); +SQLITE_PRIVATE int sqlite3LookasideUsed(sqlite3*,int*); + +/* Access to mutexes used by sqlite3_status() */ +SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void); +SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void); + + +/* The SQLITE_THREAD_MISUSE_WARNINGS compile-time option used to be called +** SQLITE_ENABLE_MULTITHREADED_CHECKS. Keep that older macro for backwards +** compatibility, at least for a while... */ +#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS +# define SQLITE_THREAD_MISUSE_WARNINGS 1 +#endif + +/* SQLITE_THREAD_MISUSE_ABORT implies SQLITE_THREAD_MISUSE_WARNINGS */ +#ifdef SQLITE_THREAD_MISUSE_ABORT +# define SQLITE_THREAD_MISUSE_WARNINGS 1 +#endif + +#if defined(SQLITE_THREAD_MISUSE_WARNINGS) && !defined(SQLITE_MUTEX_OMIT) +SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex*); +#else +# define sqlite3MutexWarnOnContention(x) +#endif + +#ifndef SQLITE_OMIT_FLOATING_POINT +# define EXP754 (((u64)0x7ff)<<52) +# define MAN754 ((((u64)1)<<52)-1) +# define IsNaN(X) (((X)&EXP754)==EXP754 && ((X)&MAN754)!=0) +# define IsOvfl(X) (((X)&EXP754)==EXP754) +SQLITE_PRIVATE int sqlite3IsNaN(double); +SQLITE_PRIVATE int sqlite3IsOverflow(double); +#else +# define IsNaN(X) 0 +# define sqlite3IsNaN(X) 0 +# define sqlite3IsOVerflow(X) 0 +#endif + +/* +** An instance of the following structure holds information about SQL +** functions arguments that are the parameters to the printf() function. +*/ +struct PrintfArguments { + int nArg; /* Total number of arguments */ + int nUsed; /* Number of arguments used so far */ + sqlite3_value **apArg; /* The argument values */ +}; + +/* +** Maxium number of base-10 digits in an unsigned 64-bit integer +*/ +#define SQLITE_U64_DIGITS 20 + +/* +** An instance of this object receives the decoding of a floating point +** value into an approximate decimal representation. +*/ +struct FpDecode { + int n; /* Significant digits in the decode */ + int iDP; /* Location of the decimal point */ + char *z; /* Start of significant digits */ + char zBuf[SQLITE_U64_DIGITS+1]; /* Storage for significant digits */ + char sign; /* '+' or '-' */ + char isSpecial; /* 1: Infinity 2: NaN */ +}; + +SQLITE_PRIVATE void sqlite3FpDecode(FpDecode*,double,int,int); +SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...); +SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list); +#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) +SQLITE_PRIVATE void sqlite3DebugPrintf(const char*, ...); +#endif +#if defined(SQLITE_TEST) +SQLITE_PRIVATE void *sqlite3TestTextToPtr(const char*); +#endif + +#if defined(SQLITE_DEBUG) +SQLITE_PRIVATE void sqlite3TreeViewLine(TreeView*, const char *zFormat, ...); +SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView*, const Expr*, u8); +SQLITE_PRIVATE void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*); +SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*); +SQLITE_PRIVATE void sqlite3TreeViewBareIdList(TreeView*, const IdList*, const char*); +SQLITE_PRIVATE void sqlite3TreeViewIdList(TreeView*, const IdList*, u8, const char*); +SQLITE_PRIVATE void sqlite3TreeViewColumnList(TreeView*, const Column*, int, u8); +SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView*, const SrcList*); +SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8); +SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView*, const With*, u8); +SQLITE_PRIVATE void sqlite3TreeViewUpsert(TreeView*, const Upsert*, u8); +#if TREETRACE_ENABLED +SQLITE_PRIVATE void sqlite3TreeViewDelete(const With*, const SrcList*, const Expr*, + const ExprList*,const Expr*, const Trigger*); +SQLITE_PRIVATE void sqlite3TreeViewInsert(const With*, const SrcList*, + const IdList*, const Select*, const ExprList*, + int, const Upsert*, const Trigger*); +SQLITE_PRIVATE void sqlite3TreeViewUpdate(const With*, const SrcList*, const ExprList*, + const Expr*, int, const ExprList*, const Expr*, + const Upsert*, const Trigger*); +#endif +#ifndef SQLITE_OMIT_TRIGGER +SQLITE_PRIVATE void sqlite3TreeViewTriggerStep(TreeView*, const TriggerStep*, u8, u8); +SQLITE_PRIVATE void sqlite3TreeViewTrigger(TreeView*, const Trigger*, u8, u8); +#endif +#ifndef SQLITE_OMIT_WINDOWFUNC +SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView*, const Window*, u8); +SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8); +#endif +SQLITE_PRIVATE void sqlite3ShowExpr(const Expr*); +SQLITE_PRIVATE void sqlite3ShowExprList(const ExprList*); +SQLITE_PRIVATE void sqlite3ShowIdList(const IdList*); +SQLITE_PRIVATE void sqlite3ShowSrcList(const SrcList*); +SQLITE_PRIVATE void sqlite3ShowSelect(const Select*); +SQLITE_PRIVATE void sqlite3ShowWith(const With*); +SQLITE_PRIVATE void sqlite3ShowUpsert(const Upsert*); +#ifndef SQLITE_OMIT_TRIGGER +SQLITE_PRIVATE void sqlite3ShowTriggerStep(const TriggerStep*); +SQLITE_PRIVATE void sqlite3ShowTriggerStepList(const TriggerStep*); +SQLITE_PRIVATE void sqlite3ShowTrigger(const Trigger*); +SQLITE_PRIVATE void sqlite3ShowTriggerList(const Trigger*); +#endif +#ifndef SQLITE_OMIT_WINDOWFUNC +SQLITE_PRIVATE void sqlite3ShowWindow(const Window*); +SQLITE_PRIVATE void sqlite3ShowWinFunc(const Window*); +#endif +SQLITE_PRIVATE void sqlite3ShowBitvec(Bitvec*); +#endif + +SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*); +SQLITE_PRIVATE void sqlite3ProgressCheck(Parse*); +SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...); +SQLITE_PRIVATE int sqlite3ErrorToParser(sqlite3*,int); +SQLITE_PRIVATE void sqlite3Dequote(char*); +SQLITE_PRIVATE void sqlite3DequoteExpr(Expr*); +SQLITE_PRIVATE void sqlite3DequoteToken(Token*); +SQLITE_PRIVATE void sqlite3DequoteNumber(Parse*, Expr*); +SQLITE_PRIVATE void sqlite3TokenInit(Token*,char*); +SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int); +SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*); +SQLITE_PRIVATE void sqlite3FinishCoding(Parse*); +SQLITE_PRIVATE int sqlite3GetTempReg(Parse*); +SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse*,int); +SQLITE_PRIVATE int sqlite3GetTempRange(Parse*,int); +SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse*,int,int); +SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse*); +SQLITE_PRIVATE void sqlite3TouchRegister(Parse*,int); +#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_DEBUG) +SQLITE_PRIVATE int sqlite3FirstAvailableRegister(Parse*,int); +#endif +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse*,int,int); +#endif +SQLITE_PRIVATE Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int); +SQLITE_PRIVATE Expr *sqlite3Expr(sqlite3*,int,const char*); +SQLITE_PRIVATE Expr *sqlite3ExprInt32(sqlite3*,int); +SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*); +SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*); +SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*); +SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse*,Expr*, Expr*); +SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr*); +SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, const Token*, int); +SQLITE_PRIVATE void sqlite3ExprAddFunctionOrderBy(Parse*,Expr*,ExprList*); +SQLITE_PRIVATE void sqlite3ExprOrderByAggregateError(Parse*,Expr*); +SQLITE_PRIVATE void sqlite3ExprFunctionUsable(Parse*,const Expr*,const FuncDef*); +SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); +SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*); +SQLITE_PRIVATE void sqlite3ExprDeleteGeneric(sqlite3*,void*); +SQLITE_PRIVATE int sqlite3ExprDeferredDelete(Parse*, Expr*); +SQLITE_PRIVATE void sqlite3ExprUnmapAndDelete(Parse*, Expr*); +SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); +SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*); +SQLITE_PRIVATE Select *sqlite3ExprListToValues(Parse*, int, ExprList*); +SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList*,int,int); +SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,const Token*,int); +SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*); +SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*); +SQLITE_PRIVATE void sqlite3ExprListDeleteGeneric(sqlite3*,void*); +SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*); +SQLITE_PRIVATE int sqlite3IndexHasDuplicateRootPage(Index*); +SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**); +SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**); +SQLITE_PRIVATE int sqlite3InitOne(sqlite3*, int, char**, u32); +SQLITE_PRIVATE void sqlite3Pragma(Parse*,Token*,Token*,Token*,int); +#ifndef SQLITE_OMIT_VIRTUALTABLE +SQLITE_PRIVATE Module *sqlite3PragmaVtabRegister(sqlite3*,const char *zName); +#endif +SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3*); +SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3*,int); +SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3*); +SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3*); +SQLITE_PRIVATE void sqlite3ColumnSetExpr(Parse*,Table*,Column*,Expr*); +SQLITE_PRIVATE Expr *sqlite3ColumnExpr(Table*,Column*); +SQLITE_PRIVATE void sqlite3ColumnSetColl(sqlite3*,Column*,const char*zColl); +SQLITE_PRIVATE const char *sqlite3ColumnColl(Column*); +SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3*,Table*); +SQLITE_PRIVATE void sqlite3GenerateColumnNames(Parse *pParse, Select *pSelect); +SQLITE_PRIVATE int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**); +SQLITE_PRIVATE void sqlite3SubqueryColumnTypes(Parse*,Table*,Select*,char); +SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse*,Select*,char); +SQLITE_PRIVATE void sqlite3OpenSchemaTable(Parse *, int); +SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table*); +SQLITE_PRIVATE int sqlite3TableColumnToIndex(Index*, int); +#ifdef SQLITE_OMIT_GENERATED_COLUMNS +# define sqlite3TableColumnToStorage(T,X) (X) /* No-op pass-through */ +# define sqlite3StorageColumnToTable(T,X) (X) /* No-op pass-through */ +#else +SQLITE_PRIVATE i16 sqlite3TableColumnToStorage(Table*, i16); +SQLITE_PRIVATE i16 sqlite3StorageColumnToTable(Table*, i16); +#endif +SQLITE_PRIVATE void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int); +#if SQLITE_ENABLE_HIDDEN_COLUMNS +SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table*, Column*); +#else +# define sqlite3ColumnPropertiesFromName(T,C) /* no-op */ +#endif +SQLITE_PRIVATE void sqlite3AddColumn(Parse*,Token,Token); +SQLITE_PRIVATE void sqlite3AddNotNull(Parse*, int); +SQLITE_PRIVATE void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int); +SQLITE_PRIVATE void sqlite3AddCheckConstraint(Parse*, Expr*, const char*, const char*); +SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,Expr*,const char*,const char*); +SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*); +SQLITE_PRIVATE void sqlite3AddGenerated(Parse*,Expr*,Token*); +SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u32,Select*); +SQLITE_PRIVATE void sqlite3AddReturning(Parse*,ExprList*); +SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*, + sqlite3_vfs**,char**,char **); +#define sqlite3CodecQueryParameters(A,B,C) 0 +SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3*,const char*); + +#ifdef SQLITE_UNTESTABLE +# define sqlite3FaultSim(X) SQLITE_OK +#else +SQLITE_PRIVATE int sqlite3FaultSim(int); +#endif + +SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32); +SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec*, u32); +SQLITE_PRIVATE int sqlite3BitvecTestNotNull(Bitvec*, u32); +SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec*, u32); +SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec*, u32, void*); +SQLITE_PRIVATE void sqlite3BitvecDestroy(Bitvec*); +SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec*); +#ifndef SQLITE_UNTESTABLE +SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int,int*); +#endif + +SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3*); +SQLITE_PRIVATE void sqlite3RowSetDelete(void*); +SQLITE_PRIVATE void sqlite3RowSetClear(void*); +SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet*, i64); +SQLITE_PRIVATE int sqlite3RowSetTest(RowSet*, int iBatch, i64); +SQLITE_PRIVATE int sqlite3RowSetNext(RowSet*, i64*); + +SQLITE_PRIVATE void sqlite3CreateView(Parse*,Token*,Token*,Token*,ExprList*,Select*,int,int); + +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) +SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse*,Table*); +#else +# define sqlite3ViewGetColumnNames(A,B) 0 +#endif + +#if SQLITE_MAX_ATTACHED>30 +SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask); +#endif +SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int); +SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int); +SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*); +SQLITE_PRIVATE void sqlite3DeleteTableGeneric(sqlite3*, void*); +SQLITE_PRIVATE void sqlite3FreeIndex(sqlite3*, Index*); +#ifndef SQLITE_OMIT_AUTOINCREMENT +SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse); +SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse); +#else +# define sqlite3AutoincrementBegin(X) +# define sqlite3AutoincrementEnd(X) +#endif +SQLITE_PRIVATE void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int, Upsert*); +#ifndef SQLITE_OMIT_GENERATED_COLUMNS +SQLITE_PRIVATE void sqlite3ComputeGeneratedColumns(Parse*, int, Table*); +#endif +SQLITE_PRIVATE void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*); +SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse*, IdList*, Token*); +SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*); +SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(Parse*, SrcList*, int, int); +SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2); +SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*); +SQLITE_PRIVATE void sqlite3SubqueryDelete(sqlite3*,Subquery*); +SQLITE_PRIVATE Select *sqlite3SubqueryDetach(sqlite3*,SrcItem*); +SQLITE_PRIVATE int sqlite3SrcItemAttachSubquery(Parse*, SrcItem*, Select*, int); +SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*, + Token*, Select*, OnOrUsing*); +SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *); +SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*); +SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, SrcItem *); +SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(Parse*,SrcList*); +SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*); +SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*); +SQLITE_PRIVATE void sqlite3ClearOnOrUsing(sqlite3*, OnOrUsing*); +SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*); +SQLITE_PRIVATE Index *sqlite3AllocateIndexObject(sqlite3*,int,int,char**); +SQLITE_PRIVATE void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, + Expr*, int, int, u8); +SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int); +SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*); +SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*, + Expr*,ExprList*,u32,Expr*); +SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*); +SQLITE_PRIVATE void sqlite3SelectDeleteGeneric(sqlite3*,void*); +SQLITE_PRIVATE void sqlite3SelectCheckOnClauses(Parse *pParse, Select *pSelect); +SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*); +SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, Trigger*); +SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); +#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) +SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*); +#endif +SQLITE_PRIVATE void sqlite3CodeChangeCount(Vdbe*,int,const char*); +SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*); +SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*, + Upsert*); +SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*, + ExprList*,Select*,u16,int); +SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*); +SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo*); +SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*); +SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*); +SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo*); +SQLITE_PRIVATE void sqlite3WhereMinMaxOptEarlyOut(Vdbe*,WhereInfo*); +SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo*); +SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo*); +SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo*); +SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo*, int*); +#define ONEPASS_OFF 0 /* Use of ONEPASS not allowed */ +#define ONEPASS_SINGLE 1 /* ONEPASS valid for a single row update */ +#define ONEPASS_MULTI 2 /* ONEPASS is valid for multiple rows */ +SQLITE_PRIVATE int sqlite3WhereUsesDeferredSeek(WhereInfo*); +SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int); +SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); +SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); +SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int); +SQLITE_PRIVATE void sqlite3ExprToRegister(Expr *pExpr, int iReg); +SQLITE_PRIVATE void sqlite3ExprCode(Parse*, Expr*, int); +#ifndef SQLITE_OMIT_GENERATED_COLUMNS +SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn(Parse*, Table*, Column*, int); +#endif +SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, Expr*, int); +SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse*, Expr*, int); +SQLITE_PRIVATE int sqlite3ExprCodeRunJustOnce(Parse*, Expr*, int); +SQLITE_PRIVATE void sqlite3ExprNullRegisterRange(Parse*, int, int); +SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse*, Expr*, int*); +SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse*, Expr*, int); +SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int, u8); +#define SQLITE_ECEL_DUP 0x01 /* Deep, not shallow copies */ +#define SQLITE_ECEL_FACTOR 0x02 /* Factor out constant terms */ +#define SQLITE_ECEL_REF 0x04 /* Use ExprList.u.x.iOrderByCol */ +#define SQLITE_ECEL_OMITREF 0x08 /* Omit if ExprList.u.x.iOrderByCol */ +SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse*, Expr*, int, int); +SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse*, Expr*, int, int); +SQLITE_PRIVATE void sqlite3ExprIfFalseDup(Parse*, Expr*, int, int); +SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3*,const char*, const char*); +#define LOCATE_VIEW 0x01 +#define LOCATE_NOERR 0x02 +SQLITE_PRIVATE Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*); +SQLITE_PRIVATE const char *sqlite3PreferredTableName(const char*); +SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,u32 flags,SrcItem *); +SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*); +SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*); +SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); +SQLITE_PRIVATE void sqlite3Vacuum(Parse*,Token*,Expr*); +SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*, int, sqlite3_value*); +SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, const Token*); +SQLITE_PRIVATE int sqlite3ExprCompare(const Parse*,const Expr*,const Expr*, int); +SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr*,Expr*,int); +SQLITE_PRIVATE int sqlite3ExprListCompare(const ExprList*,const ExprList*, int); +SQLITE_PRIVATE int sqlite3ExprImpliesExpr(const Parse*,const Expr*,const Expr*, int); +SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr*,int,int); +SQLITE_PRIVATE void sqlite3AggInfoPersistWalkerInit(Walker*,Parse*); +SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); +SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); +SQLITE_PRIVATE int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx); +SQLITE_PRIVATE int sqlite3ReferencesSrcList(Parse*, Expr*, SrcList*); +SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*); +#ifndef SQLITE_UNTESTABLE +SQLITE_PRIVATE void sqlite3PrngSaveState(void); +SQLITE_PRIVATE void sqlite3PrngRestoreState(void); +#endif +SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3*,int); +SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse*, int); +SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb); +SQLITE_PRIVATE void sqlite3BeginTransaction(Parse*, int); +SQLITE_PRIVATE void sqlite3EndTransaction(Parse*,int); +SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*); +SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *); +SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*); +SQLITE_PRIVATE u32 sqlite3IsTrueOrFalse(const char*); +SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr*); +SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr*); +SQLITE_PRIVATE int sqlite3ExprIsConstant(Parse*,Expr*); +SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8); +SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*); +SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int,int); +#ifdef SQLITE_ENABLE_CURSOR_HINTS +SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*); +#endif +SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr*, int*, Parse*); +SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*); +SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); +SQLITE_PRIVATE int sqlite3ExprIsLikeOperator(const Expr*); +SQLITE_PRIVATE int sqlite3IsRowid(const char*); +SQLITE_PRIVATE const char *sqlite3RowidAlias(Table *pTab); +SQLITE_PRIVATE void sqlite3GenerateRowDelete( + Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int); +SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int); +SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int); +SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse*,int); +SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn(Expr*,int*,int); +SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int, + u8,u8,int,int*,int*,Upsert*); +#ifdef SQLITE_ENABLE_NULL_TRIM +SQLITE_PRIVATE void sqlite3SetMakeRecordP5(Vdbe*,Table*); +#else +# define sqlite3SetMakeRecordP5(A,B) +#endif +SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int); +SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, u8, int, u8*, int*, int*); +SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int); +SQLITE_PRIVATE void sqlite3MultiWrite(Parse*); +SQLITE_PRIVATE void sqlite3MayAbort(Parse*); +SQLITE_PRIVATE void sqlite3HaltConstraint(Parse*, int, int, char*, i8, u8); +SQLITE_PRIVATE void sqlite3UniqueConstraint(Parse*, int, Index*); +SQLITE_PRIVATE void sqlite3RowidConstraint(Parse*, int, Table*); +SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,const Expr*,int); +SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,const ExprList*,int); +SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,const SrcList*,int); +SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,const IdList*); +SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,const Select*,int); +SQLITE_PRIVATE FuncDef *sqlite3FunctionSearch(int,const char*); +SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(FuncDef*,int); +SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8); +SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum*,sqlite3_value*,int); +SQLITE_PRIVATE int sqlite3AppendOneUtf8Character(char*, u32); +SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void); +SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void); +SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void); +SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*); +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON) +SQLITE_PRIVATE Module *sqlite3JsonVtabRegister(sqlite3*,const char*); +#endif +SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*); +SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*); +SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int); +SQLITE_PRIVATE With *sqlite3WithDup(sqlite3 *db, With *p); + +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_CARRAY) +SQLITE_PRIVATE Module *sqlite3CarrayRegister(sqlite3*); +#endif + +#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) +SQLITE_PRIVATE void sqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,int); +#endif + +#ifndef SQLITE_OMIT_TRIGGER +SQLITE_PRIVATE void sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*, + Expr*,int, int); +SQLITE_PRIVATE void sqlite3FinishTrigger(Parse*, TriggerStep*, Token*); +SQLITE_PRIVATE void sqlite3DropTrigger(Parse*, SrcList*, int); +SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse*, Trigger*); +SQLITE_PRIVATE Trigger *sqlite3TriggersExist(Parse *, Table*, int, ExprList*, int *pMask); +SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *, Table *); +SQLITE_PRIVATE void sqlite3CodeRowTrigger(Parse*, Trigger *, int, ExprList*, int, Table *, + int, int, int); +SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect(Parse *, Trigger *, Table *, int, int, int); + void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*); +SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*); +SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*, + const char*,const char*); +SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(Parse*,SrcList*, IdList*, + Select*,u8,Upsert*, + const char*,const char*); +SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(Parse*,SrcList*,SrcList*,ExprList*, + Expr*, u8, const char*,const char*); +SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(Parse*,SrcList*, Expr*, + const char*,const char*); +SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3*, Trigger*); +SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*); +SQLITE_PRIVATE u32 sqlite3TriggerColmask(Parse*,Trigger*,ExprList*,int,int,Table*,int); +# define sqlite3ParseToplevel(p) ((p)->pToplevel ? (p)->pToplevel : (p)) +# define sqlite3IsToplevel(p) ((p)->pToplevel==0) +#else +# define sqlite3TriggersExist(B,C,D,E,F) 0 +# define sqlite3DeleteTrigger(A,B) +# define sqlite3DropTriggerPtr(A,B) +# define sqlite3UnlinkAndDeleteTrigger(A,B,C) +# define sqlite3CodeRowTrigger(A,B,C,D,E,F,G,H,I) +# define sqlite3CodeRowTriggerDirect(A,B,C,D,E,F) +# define sqlite3TriggerList(X, Y) 0 +# define sqlite3ParseToplevel(p) p +# define sqlite3IsToplevel(p) 1 +# define sqlite3TriggerColmask(A,B,C,D,E,F,G) 0 +#endif + +SQLITE_PRIVATE int sqlite3JoinType(Parse*, Token*, Token*, Token*); +SQLITE_PRIVATE int sqlite3ColumnIndex(Table *pTab, const char *zCol); +SQLITE_PRIVATE void sqlite3SrcItemColumnUsed(SrcItem*,int); +SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr*,int,u32); +SQLITE_PRIVATE void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int); +SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse*, int); +#ifndef SQLITE_OMIT_AUTHORIZATION +SQLITE_PRIVATE void sqlite3AuthRead(Parse*,Expr*,Schema*,SrcList*); +SQLITE_PRIVATE int sqlite3AuthCheck(Parse*,int, const char*, const char*, const char*); +SQLITE_PRIVATE void sqlite3AuthContextPush(Parse*, AuthContext*, const char*); +SQLITE_PRIVATE void sqlite3AuthContextPop(AuthContext*); +SQLITE_PRIVATE int sqlite3AuthReadCol(Parse*, const char *, const char *, int); +#else +# define sqlite3AuthRead(a,b,c,d) +# define sqlite3AuthCheck(a,b,c,d,e) SQLITE_OK +# define sqlite3AuthContextPush(a,b,c) +# define sqlite3AuthContextPop(a) ((void)(a)) +#endif +SQLITE_PRIVATE int sqlite3DbIsNamed(sqlite3 *db, int iDb, const char *zName); +SQLITE_PRIVATE void sqlite3Attach(Parse*, Expr*, Expr*, Expr*); +SQLITE_PRIVATE void sqlite3Detach(Parse*, Expr*); +SQLITE_PRIVATE void sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*); +SQLITE_PRIVATE int sqlite3FixSrcList(DbFixer*, SrcList*); +SQLITE_PRIVATE int sqlite3FixSelect(DbFixer*, Select*); +SQLITE_PRIVATE int sqlite3FixExpr(DbFixer*, Expr*); +SQLITE_PRIVATE int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); + +SQLITE_PRIVATE int sqlite3RealSameAsInt(double,sqlite3_int64); +SQLITE_PRIVATE i64 sqlite3RealToI64(double); +SQLITE_PRIVATE int sqlite3Int64ToText(i64,char*); +SQLITE_PRIVATE int sqlite3AtoF(const char *z, double*); +SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*); +SQLITE_PRIVATE int sqlite3GetUInt32(const char*, u32*); +SQLITE_PRIVATE int sqlite3Atoi(const char*); +#ifndef SQLITE_OMIT_UTF16 +SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nByte, int nChar); +#endif +SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte); +SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**); +SQLITE_PRIVATE int sqlite3Utf8ReadLimited(const u8*, int, u32*); +SQLITE_PRIVATE LogEst sqlite3LogEst(u64); +SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst,LogEst); +SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double); +SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst); +SQLITE_PRIVATE VList *sqlite3VListAdd(sqlite3*,VList*,const char*,int,int); +SQLITE_PRIVATE const char *sqlite3VListNumToName(VList*,int); +SQLITE_PRIVATE int sqlite3VListNameToNum(VList*,const char*,int); + +/* +** Routines to read and write variable-length integers. These used to +** be defined locally, but now we use the varint routines in the util.c +** file. +*/ +SQLITE_PRIVATE int sqlite3PutVarint(unsigned char*, u64); +SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *, u64 *); +SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *, u32 *); +SQLITE_PRIVATE int sqlite3VarintLen(u64 v); + +/* +** The common case is for a varint to be a single byte. They following +** macros handle the common case without a procedure call, but then call +** the procedure for larger varints. +*/ +#define getVarint32(A,B) \ + (u8)((*(A)<(u8)0x80)?((B)=(u32)*(A)),1:sqlite3GetVarint32((A),(u32 *)&(B))) +#define getVarint32NR(A,B) \ + B=(u32)*(A);if(B>=0x80)sqlite3GetVarint32((A),(u32*)&(B)) +#define putVarint32(A,B) \ + (u8)(((u32)(B)<(u32)0x80)?(*(A)=(unsigned char)(B)),1:\ + sqlite3PutVarint((A),(B))) +#define getVarint sqlite3GetVarint +#define putVarint sqlite3PutVarint + + +SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3*, Index*); +SQLITE_PRIVATE char *sqlite3TableAffinityStr(sqlite3*,const Table*); +SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe*, Table*, int); +SQLITE_PRIVATE char sqlite3CompareAffinity(const Expr *pExpr, char aff2); +SQLITE_PRIVATE int sqlite3IndexAffinityOk(const Expr *pExpr, char idx_affinity); +SQLITE_PRIVATE char sqlite3TableColumnAffinity(const Table*,int); +SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr); +SQLITE_PRIVATE int sqlite3ExprDataType(const Expr *pExpr); +SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8); +SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*); +SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...); +SQLITE_PRIVATE void sqlite3Error(sqlite3*,int); +SQLITE_PRIVATE void sqlite3ErrorClear(sqlite3*); +SQLITE_PRIVATE void sqlite3SystemError(sqlite3*,int); +#if !defined(SQLITE_OMIT_BLOB_LITERAL) +SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n); +#endif +SQLITE_PRIVATE u8 sqlite3HexToInt(int h); +SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); + +#if defined(SQLITE_NEED_ERR_NAME) +SQLITE_PRIVATE const char *sqlite3ErrName(int); +#endif + +#ifndef SQLITE_OMIT_DESERIALIZE +SQLITE_PRIVATE int sqlite3MemdbInit(void); +SQLITE_PRIVATE int sqlite3IsMemdb(const sqlite3_vfs*); +#else +# define sqlite3IsMemdb(X) 0 +#endif + +SQLITE_PRIVATE const char *sqlite3ErrStr(int); +SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse); +SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); +SQLITE_PRIVATE int sqlite3IsBinary(const CollSeq*); +SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); +SQLITE_PRIVATE void sqlite3SetTextEncoding(sqlite3 *db, u8); +SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr); +SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, const Expr *pExpr); +SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse*,const Expr*,const Expr*); +SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(const Parse *pParse, Expr*, const Token*, int); +SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(const Parse*,Expr*,const char*); +SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*); +SQLITE_PRIVATE Expr *sqlite3ExprSkipCollateAndLikely(Expr*); +SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *); +SQLITE_PRIVATE int sqlite3WritableSchema(sqlite3*); +SQLITE_PRIVATE int sqlite3CheckObjectName(Parse*, const char*,const char*,const char*); +SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, i64); +SQLITE_PRIVATE int sqlite3AddInt64(i64*,i64); +SQLITE_PRIVATE int sqlite3SubInt64(i64*,i64); +SQLITE_PRIVATE int sqlite3MulInt64(i64*,i64); +SQLITE_PRIVATE int sqlite3AbsInt32(int); +#ifdef SQLITE_ENABLE_8_3_NAMES +SQLITE_PRIVATE void sqlite3FileSuffix3(const char*, char*); +#else +# define sqlite3FileSuffix3(X,Y) +#endif +SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z,u8); + +SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8); +SQLITE_PRIVATE int sqlite3ValueIsOfClass(const sqlite3_value*, void(*)(void*)); +SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8); +SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, + void(*)(void*)); +SQLITE_PRIVATE void sqlite3ValueSetNull(sqlite3_value*); +SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*); +#ifndef SQLITE_UNTESTABLE +SQLITE_PRIVATE void sqlite3ResultIntReal(sqlite3_context*); +#endif +SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *); +#ifndef SQLITE_OMIT_UTF16 +SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8); +#endif +SQLITE_PRIVATE int sqlite3ValueFromExpr(sqlite3 *, const Expr *, u8, u8, sqlite3_value **); +SQLITE_PRIVATE void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8); +#ifndef SQLITE_AMALGAMATION +SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[]; +SQLITE_PRIVATE const char sqlite3StrBINARY[]; +SQLITE_PRIVATE const unsigned char sqlite3StdTypeLen[]; +SQLITE_PRIVATE const char sqlite3StdTypeAffinity[]; +SQLITE_PRIVATE const char *sqlite3StdType[]; +SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[]; +SQLITE_PRIVATE const unsigned char *sqlite3aLTb; +SQLITE_PRIVATE const unsigned char *sqlite3aEQb; +SQLITE_PRIVATE const unsigned char *sqlite3aGTb; +SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[]; +SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config; +SQLITE_PRIVATE FuncDefHash sqlite3BuiltinFunctions; +#ifndef SQLITE_OMIT_WSD +SQLITE_PRIVATE int sqlite3PendingByte; +#endif +#endif /* SQLITE_AMALGAMATION */ +#ifdef VDBE_PROFILE +SQLITE_PRIVATE sqlite3_uint64 sqlite3NProfileCnt; +#endif +SQLITE_PRIVATE void sqlite3RootPageMoved(sqlite3*, int, Pgno, Pgno); +SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*); +SQLITE_PRIVATE void sqlite3AlterFunctions(void); +SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*); +SQLITE_PRIVATE void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*); +SQLITE_PRIVATE void sqlite3AlterDropConstraint(Parse*,SrcList*,Token*,Token*); +SQLITE_PRIVATE void sqlite3AlterAddConstraint( + Parse *pParse, /* Parse context */ + SrcList *pSrc, /* Table to add constraint to */ + Token *pFirst, /* First token of new constraint */ + Token *pName, /* Name of new constraint. NULL if name omitted. */ + const char *zExpr, /* Text of CHECK expression */ + int nExpr, /* Size of pExpr in bytes */ + Expr *pExpr /* The parsed CHECK expression */ +); +SQLITE_PRIVATE void sqlite3AlterSetNotNull(Parse*, SrcList*, Token*, Token*); +SQLITE_PRIVATE i64 sqlite3GetToken(const unsigned char *, int *); +SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...); +SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*, int); +SQLITE_PRIVATE void sqlite3CodeRhsOfIN(Parse*, Expr*, int, int); +SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr*); +SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*); +SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse*, SrcItem*); +SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p); +SQLITE_PRIVATE int sqlite3MatchEName( + const struct ExprList_item*, + const char*, + const char*, + const char*, + int* +); +SQLITE_PRIVATE Bitmask sqlite3ExprColUsed(Expr*); +SQLITE_PRIVATE u8 sqlite3StrIHash(const char*); +SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*); +SQLITE_PRIVATE int sqlite3ResolveExprListNames(NameContext*, ExprList*); +SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*); +SQLITE_PRIVATE int sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*); +SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*); +SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int); +SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *); +SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *); +SQLITE_PRIVATE void sqlite3AlterDropColumn(Parse*, SrcList*, const Token*); +SQLITE_PRIVATE const void *sqlite3RenameTokenMap(Parse*, const void*, const Token*); +SQLITE_PRIVATE void sqlite3RenameTokenRemap(Parse*, const void *pTo, const void *pFrom); +SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse*, Expr*); +SQLITE_PRIVATE void sqlite3RenameExprlistUnmap(Parse*, ExprList*); +SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*); +SQLITE_PRIVATE char sqlite3AffinityType(const char*, Column*); +SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*); +SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*); +SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*); +SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *, const char *); +SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3*,int iDB); +SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3*,Index*); +SQLITE_PRIVATE void sqlite3DefaultRowEst(Index*); +SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3*, int); +SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*); +SQLITE_PRIVATE void sqlite3SchemaClear(void *); +SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *, Btree *); +SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *); +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int,int); +SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo*); +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoRef(KeyInfo*); +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*); +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoFromExprList(Parse*, ExprList*, int, int); +SQLITE_PRIVATE const char *sqlite3SelectOpName(int); +SQLITE_PRIVATE int sqlite3HasExplicitNulls(Parse*, ExprList*); + +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo*); +#endif +SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, + void (*)(sqlite3_context*,int,sqlite3_value **), + void (*)(sqlite3_context*,int,sqlite3_value **), + void (*)(sqlite3_context*), + void (*)(sqlite3_context*), + void (*)(sqlite3_context*,int,sqlite3_value **), + FuncDestructor *pDestructor +); +SQLITE_PRIVATE void sqlite3NoopDestructor(void*); +SQLITE_PRIVATE void *sqlite3OomFault(sqlite3*); +SQLITE_PRIVATE void sqlite3OomClear(sqlite3*); +SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int); +SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *); + +SQLITE_PRIVATE char *sqlite3RCStrRef(char*); +SQLITE_PRIVATE void sqlite3RCStrUnref(void*); +SQLITE_PRIVATE char *sqlite3RCStrNew(u64); +SQLITE_PRIVATE char *sqlite3RCStrResize(char*,u64); + +SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int); +SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum*, i64); +SQLITE_PRIVATE int sqlite3StrAccumEnlargeIfNeeded(StrAccum*, i64); +SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*); +SQLITE_PRIVATE void sqlite3StrAccumSetError(StrAccum*, u8); +SQLITE_PRIVATE void sqlite3ResultStrAccum(sqlite3_context*,StrAccum*); +SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int); +SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int); +SQLITE_PRIVATE void sqlite3RecordErrorByteOffset(sqlite3*,const char*); +SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3*,const Expr*); + +SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *); +SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *); + +#ifndef SQLITE_OMIT_SUBQUERY +SQLITE_PRIVATE int sqlite3ExprCheckIN(Parse*, Expr*); +#else +# define sqlite3ExprCheckIN(x,y) SQLITE_OK +#endif + +#ifdef SQLITE_ENABLE_STAT4 +SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue( + Parse*,Index*,UnpackedRecord**,Expr*,int,int,int*); +SQLITE_PRIVATE int sqlite3Stat4ValueFromExpr(Parse*, Expr*, u8, sqlite3_value**); +SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord*); +SQLITE_PRIVATE int sqlite3Stat4Column(sqlite3*, const void*, int, int, sqlite3_value**); +SQLITE_PRIVATE char sqlite3IndexColumnAffinity(sqlite3*, Index*, int); +#endif + +/* +** The interface to the LEMON-generated parser +*/ +#ifndef SQLITE_AMALGAMATION +SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(u64), Parse*); +SQLITE_PRIVATE void sqlite3ParserFree(void*, void(*)(void*)); +#endif +SQLITE_PRIVATE void sqlite3Parser(void*, int, Token); +SQLITE_PRIVATE int sqlite3ParserFallback(int); +#ifdef YYTRACKMAXSTACKDEPTH +SQLITE_PRIVATE int sqlite3ParserStackPeak(void*); +#endif + +SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3*); +#ifndef SQLITE_OMIT_LOAD_EXTENSION +SQLITE_PRIVATE void sqlite3CloseExtensions(sqlite3*); +#else +# define sqlite3CloseExtensions(X) +#endif + +#ifndef SQLITE_OMIT_SHARED_CACHE +SQLITE_PRIVATE void sqlite3TableLock(Parse *, int, Pgno, u8, const char *); +#else + #define sqlite3TableLock(v,w,x,y,z) +#endif + +#ifdef SQLITE_TEST +SQLITE_PRIVATE int sqlite3Utf8To8(unsigned char*); +#endif + +#ifdef SQLITE_OMIT_VIRTUALTABLE +# define sqlite3VtabClear(D,T) +# define sqlite3VtabSync(X,Y) SQLITE_OK +# define sqlite3VtabRollback(X) +# define sqlite3VtabCommit(X) +# define sqlite3VtabInSync(db) 0 +# define sqlite3VtabLock(X) +# define sqlite3VtabUnlock(X) +# define sqlite3VtabModuleUnref(D,X) +# define sqlite3VtabUnlockList(X) +# define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK +# define sqlite3GetVTable(X,Y) ((VTable*)0) +#else +SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table*); +SQLITE_PRIVATE void sqlite3VtabDisconnect(sqlite3 *db, Table *p); +SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, Vdbe*); +SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db); +SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db); +SQLITE_PRIVATE void sqlite3VtabLock(VTable *); +SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *); +SQLITE_PRIVATE void sqlite3VtabModuleUnref(sqlite3*,Module*); +SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3*); +SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *, int, int); +SQLITE_PRIVATE void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*); +SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3*, Table*); +SQLITE_PRIVATE Module *sqlite3VtabCreateModule( + sqlite3*, + const char*, + const sqlite3_module*, + void*, + void(*)(void*) + ); +# define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0) +#endif +SQLITE_PRIVATE int sqlite3ReadOnlyShadowTables(sqlite3 *db); +#ifndef SQLITE_OMIT_VIRTUALTABLE +SQLITE_PRIVATE int sqlite3ShadowTableName(sqlite3 *db, const char *zName); +SQLITE_PRIVATE int sqlite3IsShadowTableOf(sqlite3*,Table*,const char*); +SQLITE_PRIVATE void sqlite3MarkAllShadowTablesOf(sqlite3*, Table*); +#else +# define sqlite3ShadowTableName(A,B) 0 +# define sqlite3IsShadowTableOf(A,B,C) 0 +# define sqlite3MarkAllShadowTablesOf(A,B) +#endif +SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse*,Module*); +SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3*,Module*); +SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*); +SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int); +SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse*, Token*); +SQLITE_PRIVATE void sqlite3VtabArgInit(Parse*); +SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse*, Token*); +SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **); +SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse*, Table*); +SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *); +SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *); + +SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*); +SQLITE_PRIVATE void sqlite3VtabUsesAllSchemas(Parse*); +SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*); +SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int); +SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); +SQLITE_PRIVATE void sqlite3ParseObjectInit(Parse*,sqlite3*); +SQLITE_PRIVATE void sqlite3ParseObjectReset(Parse*); +SQLITE_PRIVATE void *sqlite3ParserAddCleanup(Parse*,void(*)(sqlite3*,void*),void*); +#ifdef SQLITE_ENABLE_NORMALIZE +SQLITE_PRIVATE char *sqlite3Normalize(Vdbe*, const char*); +#endif +SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*); +SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*); +SQLITE_PRIVATE CollSeq *sqlite3ExprCompareCollSeq(Parse*,const Expr*); +SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, const Expr*, const Expr*); +SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3*); +SQLITE_PRIVATE const char *sqlite3JournalModename(int); +#ifndef SQLITE_OMIT_WAL +SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3*, int, int, int*, int*); +SQLITE_PRIVATE int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int); +#endif +#ifndef SQLITE_OMIT_CTE +SQLITE_PRIVATE Cte *sqlite3CteNew(Parse*,Token*,ExprList*,Select*,u8); +SQLITE_PRIVATE void sqlite3CteDelete(sqlite3*,Cte*); +SQLITE_PRIVATE With *sqlite3WithAdd(Parse*,With*,Cte*); +SQLITE_PRIVATE void sqlite3WithDelete(sqlite3*,With*); +SQLITE_PRIVATE void sqlite3WithDeleteGeneric(sqlite3*,void*); +SQLITE_PRIVATE With *sqlite3WithPush(Parse*, With*, u8); +#else +# define sqlite3CteNew(P,T,E,S) ((void*)0) +# define sqlite3CteDelete(D,C) +# define sqlite3CteWithAdd(P,W,C) ((void*)0) +# define sqlite3WithDelete(x,y) +# define sqlite3WithPush(x,y,z) ((void*)0) +#endif +#ifndef SQLITE_OMIT_UPSERT +SQLITE_PRIVATE Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*,Upsert*); +SQLITE_PRIVATE void sqlite3UpsertDelete(sqlite3*,Upsert*); +SQLITE_PRIVATE Upsert *sqlite3UpsertDup(sqlite3*,Upsert*); +SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*,Upsert*); +SQLITE_PRIVATE void sqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int); +SQLITE_PRIVATE Upsert *sqlite3UpsertOfIndex(Upsert*,Index*); +SQLITE_PRIVATE int sqlite3UpsertNextIsIPK(Upsert*); +#else +#define sqlite3UpsertNew(u,v,w,x,y,z) ((Upsert*)0) +#define sqlite3UpsertDelete(x,y) +#define sqlite3UpsertDup(x,y) ((Upsert*)0) +#define sqlite3UpsertOfIndex(x,y) ((Upsert*)0) +#define sqlite3UpsertNextIsIPK(x) 0 +#endif + + +/* Declarations for functions in fkey.c. All of these are replaced by +** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign +** key functionality is available. If OMIT_TRIGGER is defined but +** OMIT_FOREIGN_KEY is not, only some of the functions are no-oped. In +** this case foreign keys are parsed, but no other functionality is +** provided (enforcement of FK constraints requires the triggers sub-system). +*/ +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) +SQLITE_PRIVATE void sqlite3FkCheck(Parse*, Table*, int, int, int*, int); +SQLITE_PRIVATE void sqlite3FkDropTable(Parse*, SrcList *, Table*); +SQLITE_PRIVATE void sqlite3FkActions(Parse*, Table*, ExprList*, int, int*, int); +SQLITE_PRIVATE int sqlite3FkRequired(Parse*, Table*, int*, int); +SQLITE_PRIVATE u32 sqlite3FkOldmask(Parse*, Table*); +SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *); +SQLITE_PRIVATE void sqlite3FkClearTriggerCache(sqlite3*,int); +#else + #define sqlite3FkActions(a,b,c,d,e,f) + #define sqlite3FkCheck(a,b,c,d,e,f) + #define sqlite3FkDropTable(a,b,c) + #define sqlite3FkOldmask(a,b) 0 + #define sqlite3FkRequired(a,b,c,d) 0 + #define sqlite3FkReferences(a) 0 + #define sqlite3FkClearTriggerCache(a,b) +#endif +#ifndef SQLITE_OMIT_FOREIGN_KEY +SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *, Table*); +SQLITE_PRIVATE int sqlite3FkLocateIndex(Parse*,Table*,FKey*,Index**,int**); +#else + #define sqlite3FkDelete(a,b) + #define sqlite3FkLocateIndex(a,b,c,d,e) +#endif + + +/* +** Available fault injectors. Should be numbered beginning with 0. +*/ +#define SQLITE_FAULTINJECTOR_MALLOC 0 +#define SQLITE_FAULTINJECTOR_COUNT 1 + +/* +** The interface to the code in fault.c used for identifying "benign" +** malloc failures. This is only present if SQLITE_UNTESTABLE +** is not defined. +*/ +#ifndef SQLITE_UNTESTABLE +SQLITE_PRIVATE void sqlite3BeginBenignMalloc(void); +SQLITE_PRIVATE void sqlite3EndBenignMalloc(void); +#else + #define sqlite3BeginBenignMalloc() + #define sqlite3EndBenignMalloc() +#endif + +/* +** Allowed return values from sqlite3FindInIndex() +*/ +#define IN_INDEX_ROWID 1 /* Search the rowid of the table */ +#define IN_INDEX_EPH 2 /* Search an ephemeral b-tree */ +#define IN_INDEX_INDEX_ASC 3 /* Existing index ASCENDING */ +#define IN_INDEX_INDEX_DESC 4 /* Existing index DESCENDING */ +#define IN_INDEX_NOOP 5 /* No table available. Use comparisons */ +/* +** Allowed flags for the 3rd parameter to sqlite3FindInIndex(). +*/ +#define IN_INDEX_NOOP_OK 0x0001 /* OK to return IN_INDEX_NOOP */ +#define IN_INDEX_MEMBERSHIP 0x0002 /* IN operator used for membership test */ +#define IN_INDEX_LOOP 0x0004 /* IN operator used as a loop */ +SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*, int*, int*); + +SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int); +SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *); +#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \ + || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) +SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *); +#endif + +SQLITE_PRIVATE int sqlite3JournalIsInMemory(sqlite3_file *p); +SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *); + +SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p); +#if SQLITE_MAX_EXPR_DEPTH>0 +SQLITE_PRIVATE int sqlite3SelectExprHeight(const Select *); +SQLITE_PRIVATE int sqlite3ExprCheckHeight(Parse*, int); +#else + #define sqlite3SelectExprHeight(x) 0 + #define sqlite3ExprCheckHeight(x,y) +#endif +SQLITE_PRIVATE void sqlite3ExprSetErrorOffset(Expr*,int); + +SQLITE_PRIVATE u32 sqlite3Get4byte(const u8*); +SQLITE_PRIVATE void sqlite3Put4byte(u8*, u32); + +#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY +SQLITE_PRIVATE void sqlite3ConnectionBlocked(sqlite3 *, sqlite3 *); +SQLITE_PRIVATE void sqlite3ConnectionUnlocked(sqlite3 *db); +SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db); +#else + #define sqlite3ConnectionBlocked(x,y) + #define sqlite3ConnectionUnlocked(x) + #define sqlite3ConnectionClosed(x) +#endif + +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE void sqlite3ParserTrace(FILE*, char *); +#endif +#if defined(YYCOVERAGE) +SQLITE_PRIVATE int sqlite3ParserCoverage(FILE*); +#endif + +/* +** If the SQLITE_ENABLE IOTRACE exists then the global variable +** sqlite3IoTrace is a pointer to a printf-like routine used to +** print I/O tracing messages. +*/ +#ifdef SQLITE_ENABLE_IOTRACE +# define IOTRACE(A) if( sqlite3IoTrace ){ sqlite3IoTrace A; } +SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe*); +SQLITE_API SQLITE_EXTERN void (SQLITE_CDECL *sqlite3IoTrace)(const char*,...); +#else +# define IOTRACE(A) +# define sqlite3VdbeIOTraceSql(X) +#endif + +/* +** These routines are available for the mem2.c debugging memory allocator +** only. They are used to verify that different "types" of memory +** allocations are properly tracked by the system. +** +** sqlite3MemdebugSetType() sets the "type" of an allocation to one of +** the MEMTYPE_* macros defined below. The type must be a bitmask with +** a single bit set. +** +** sqlite3MemdebugHasType() returns true if any of the bits in its second +** argument match the type set by the previous sqlite3MemdebugSetType(). +** sqlite3MemdebugHasType() is intended for use inside assert() statements. +** +** sqlite3MemdebugNoType() returns true if none of the bits in its second +** argument match the type set by the previous sqlite3MemdebugSetType(). +** +** Perhaps the most important point is the difference between MEMTYPE_HEAP +** and MEMTYPE_LOOKASIDE. If an allocation is MEMTYPE_LOOKASIDE, that means +** it might have been allocated by lookaside, except the allocation was +** too large or lookaside was already full. It is important to verify +** that allocations that might have been satisfied by lookaside are not +** passed back to non-lookaside free() routines. Asserts such as the +** example above are placed on the non-lookaside free() routines to verify +** this constraint. +** +** All of this is no-op for a production build. It only comes into +** play when the SQLITE_MEMDEBUG compile-time option is used. +*/ +#ifdef SQLITE_MEMDEBUG +SQLITE_PRIVATE void sqlite3MemdebugSetType(void*,u8); +SQLITE_PRIVATE int sqlite3MemdebugHasType(const void*,u8); +SQLITE_PRIVATE int sqlite3MemdebugNoType(const void*,u8); +#else +# define sqlite3MemdebugSetType(X,Y) /* no-op */ +# define sqlite3MemdebugHasType(X,Y) 1 +# define sqlite3MemdebugNoType(X,Y) 1 +#endif +#define MEMTYPE_HEAP 0x01 /* General heap allocations */ +#define MEMTYPE_LOOKASIDE 0x02 /* Heap that might have been lookaside */ +#define MEMTYPE_PCACHE 0x04 /* Page cache allocations */ + +/* +** Threading interface +*/ +#if SQLITE_MAX_WORKER_THREADS>0 +SQLITE_PRIVATE int sqlite3ThreadCreate(SQLiteThread**,void*(*)(void*),void*); +SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread*, void**); +#endif + +#if defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST) +SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3*); +#endif +#if defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST) +SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3*); +#endif + +SQLITE_PRIVATE int sqlite3ExprVectorSize(const Expr *pExpr); +SQLITE_PRIVATE int sqlite3ExprIsVector(const Expr *pExpr); +SQLITE_PRIVATE Expr *sqlite3VectorFieldSubexpr(Expr*, int); +SQLITE_PRIVATE Expr *sqlite3ExprForVectorField(Parse*,Expr*,int,int); +SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse*, Expr*); + +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS +SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt); +#endif + +#if SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL) +SQLITE_PRIVATE int sqlite3KvvfsInit(void); +#endif + +#if defined(VDBE_PROFILE) \ + || defined(SQLITE_PERFORMANCE_TRACE) \ + || defined(SQLITE_ENABLE_STMT_SCANSTATUS) +SQLITE_PRIVATE sqlite3_uint64 sqlite3Hwtime(void); +#endif + +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS +# define IS_STMT_SCANSTATUS(db) (db->flags & SQLITE_StmtScanStatus) +#else +# define IS_STMT_SCANSTATUS(db) 0 +#endif + +#endif /* SQLITEINT_H */ + +/************** End of sqliteInt.h *******************************************/ +/************** Begin file os_common.h ***************************************/ +/* +** 2004 May 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains macros and a little bit of code that is common to +** all of the platform-specific files (os_*.c) and is #included into those +** files. +** +** This file should be #included by the os_*.c files only. It is not a +** general purpose header file. +*/ +#ifndef _OS_COMMON_H_ +#define _OS_COMMON_H_ + +/* +** At least two bugs have slipped in because we changed the MEMORY_DEBUG +** macro to SQLITE_DEBUG and some older makefiles have not yet made the +** switch. The following code should catch this problem at compile-time. +*/ +#ifdef MEMORY_DEBUG +# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." +#endif + +/* +** Macros for performance tracing. Normally turned off. Only works +** on i486 hardware. +*/ +#ifdef SQLITE_PERFORMANCE_TRACE + +static sqlite_uint64 g_start; +static sqlite_uint64 g_elapsed; +#define TIMER_START g_start=sqlite3Hwtime() +#define TIMER_END g_elapsed=sqlite3Hwtime()-g_start +#define TIMER_ELAPSED g_elapsed +#else +#define TIMER_START +#define TIMER_END +#define TIMER_ELAPSED ((sqlite_uint64)0) +#endif + +/* +** If we compile with the SQLITE_TEST macro set, then the following block +** of code will give us the ability to simulate a disk I/O error. This +** is used for testing the I/O recovery logic. +*/ +#if defined(SQLITE_TEST) +SQLITE_API extern int sqlite3_io_error_hit; +SQLITE_API extern int sqlite3_io_error_hardhit; +SQLITE_API extern int sqlite3_io_error_pending; +SQLITE_API extern int sqlite3_io_error_persist; +SQLITE_API extern int sqlite3_io_error_benign; +SQLITE_API extern int sqlite3_diskfull_pending; +SQLITE_API extern int sqlite3_diskfull; +#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X) +#define SimulateIOError(CODE) \ + if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \ + || sqlite3_io_error_pending-- == 1 ) \ + { local_ioerr(); CODE; } +static void local_ioerr(){ + IOTRACE(("IOERR\n")); + sqlite3_io_error_hit++; + if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++; +} +#define SimulateDiskfullError(CODE) \ + if( sqlite3_diskfull_pending ){ \ + if( sqlite3_diskfull_pending == 1 ){ \ + local_ioerr(); \ + sqlite3_diskfull = 1; \ + sqlite3_io_error_hit = 1; \ + CODE; \ + }else{ \ + sqlite3_diskfull_pending--; \ + } \ + } +#else +#define SimulateIOErrorBenign(X) +#define SimulateIOError(A) +#define SimulateDiskfullError(A) +#endif /* defined(SQLITE_TEST) */ + +/* +** When testing, keep a count of the number of open files. +*/ +#if defined(SQLITE_TEST) +SQLITE_API extern int sqlite3_open_file_count; +#define OpenCounter(X) sqlite3_open_file_count+=(X) +#else +#define OpenCounter(X) +#endif /* defined(SQLITE_TEST) */ + +#endif /* !defined(_OS_COMMON_H_) */ + +/************** End of os_common.h *******************************************/ +/************** Begin file ctime.c *******************************************/ +/* DO NOT EDIT! +** This file is automatically generated by the script in the canonical +** SQLite source tree at tool/mkctimec.tcl. +** +** To modify this header, edit any of the various lists in that script +** which specify categories of generated conditionals in this file. +*/ + +/* +** 2010 February 23 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file implements routines used to report what compile-time options +** SQLite was built with. +*/ +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS /* IMP: R-16824-07538 */ + +/* +** Include the configuration header output by 'configure' if we're using the +** autoconf-based build +*/ +#if defined(_HAVE_SQLITE_CONFIG_H) && !defined(SQLITECONFIG_H) +/* #include "sqlite_cfg.h" */ +#define SQLITECONFIG_H 1 +#endif + +/* These macros are provided to "stringify" the value of the define +** for those options in which the value is meaningful. */ +#define CTIMEOPT_VAL_(opt) #opt +#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt) + +/* Like CTIMEOPT_VAL, but especially for SQLITE_DEFAULT_LOOKASIDE. This +** option requires a separate macro because legal values contain a single +** comma. e.g. (-DSQLITE_DEFAULT_LOOKASIDE="100,100") */ +#define CTIMEOPT_VAL2_(opt1,opt2) #opt1 "," #opt2 +#define CTIMEOPT_VAL2(opt) CTIMEOPT_VAL2_(opt) +/* #include "sqliteInt.h" */ + +/* +** An array of names of all compile-time options. This array should +** be sorted A-Z. +** +** This array looks large, but in a typical installation actually uses +** only a handful of compile-time options, so most times this array is usually +** rather short and uses little memory space. +*/ +static const char * const sqlite3azCompileOpt[] = { + +#ifdef SQLITE_32BIT_ROWID + "32BIT_ROWID", +#endif +#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC + "4_BYTE_ALIGNED_MALLOC", +#endif +#ifdef SQLITE_ALLOW_COVERING_INDEX_SCAN +# if SQLITE_ALLOW_COVERING_INDEX_SCAN != 1 + "ALLOW_COVERING_INDEX_SCAN=" CTIMEOPT_VAL(SQLITE_ALLOW_COVERING_INDEX_SCAN), +# endif +#endif +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + "ALLOW_ROWID_IN_VIEW", +#endif +#ifdef SQLITE_ALLOW_URI_AUTHORITY + "ALLOW_URI_AUTHORITY", +#endif +#ifdef SQLITE_ATOMIC_INTRINSICS + "ATOMIC_INTRINSICS=" CTIMEOPT_VAL(SQLITE_ATOMIC_INTRINSICS), +#endif +#ifdef SQLITE_BITMASK_TYPE + "BITMASK_TYPE=" CTIMEOPT_VAL(SQLITE_BITMASK_TYPE), +#endif +#ifdef SQLITE_BUG_COMPATIBLE_20160819 + "BUG_COMPATIBLE_20160819", +#endif +#ifdef SQLITE_BUG_COMPATIBLE_20250510 + "BUG_COMPATIBLE_20250510", +#endif +#ifdef SQLITE_CASE_SENSITIVE_LIKE + "CASE_SENSITIVE_LIKE", +#endif +#ifdef SQLITE_CHECK_PAGES + "CHECK_PAGES", +#endif +#if defined(__clang__) && defined(__clang_major__) + "COMPILER=clang-" CTIMEOPT_VAL(__clang_major__) "." + CTIMEOPT_VAL(__clang_minor__) "." + CTIMEOPT_VAL(__clang_patchlevel__), +#elif defined(_MSC_VER) + "COMPILER=msvc-" CTIMEOPT_VAL(_MSC_VER), +#elif defined(__GNUC__) && defined(__VERSION__) + "COMPILER=gcc-" __VERSION__, +#endif +#ifdef SQLITE_COVERAGE_TEST + "COVERAGE_TEST", +#endif +#ifdef SQLITE_DEBUG + "DEBUG", +#endif +#ifdef SQLITE_DEFAULT_AUTOMATIC_INDEX + "DEFAULT_AUTOMATIC_INDEX", +#endif +#ifdef SQLITE_DEFAULT_AUTOVACUUM + "DEFAULT_AUTOVACUUM", +#endif +#ifdef SQLITE_DEFAULT_CACHE_SIZE + "DEFAULT_CACHE_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_CACHE_SIZE), +#endif +#ifdef SQLITE_DEFAULT_CKPTFULLFSYNC + "DEFAULT_CKPTFULLFSYNC", +#endif +#ifdef SQLITE_DEFAULT_FILE_FORMAT + "DEFAULT_FILE_FORMAT=" CTIMEOPT_VAL(SQLITE_DEFAULT_FILE_FORMAT), +#endif +#ifdef SQLITE_DEFAULT_FILE_PERMISSIONS + "DEFAULT_FILE_PERMISSIONS=" CTIMEOPT_VAL(SQLITE_DEFAULT_FILE_PERMISSIONS), +#endif +#ifdef SQLITE_DEFAULT_FOREIGN_KEYS + "DEFAULT_FOREIGN_KEYS", +#endif +#ifdef SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT + "DEFAULT_JOURNAL_SIZE_LIMIT=" CTIMEOPT_VAL(SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT), +#endif +#ifdef SQLITE_DEFAULT_LOCKING_MODE + "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE), +#endif +#ifdef SQLITE_DEFAULT_LOOKASIDE + "DEFAULT_LOOKASIDE=" CTIMEOPT_VAL2(SQLITE_DEFAULT_LOOKASIDE), +#endif +#ifdef SQLITE_DEFAULT_MEMSTATUS +# if SQLITE_DEFAULT_MEMSTATUS != 1 + "DEFAULT_MEMSTATUS=" CTIMEOPT_VAL(SQLITE_DEFAULT_MEMSTATUS), +# endif +#endif +#ifdef SQLITE_DEFAULT_MMAP_SIZE + "DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE), +#endif +#ifdef SQLITE_DEFAULT_PAGE_SIZE + "DEFAULT_PAGE_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_PAGE_SIZE), +#endif +#ifdef SQLITE_DEFAULT_PCACHE_INITSZ + "DEFAULT_PCACHE_INITSZ=" CTIMEOPT_VAL(SQLITE_DEFAULT_PCACHE_INITSZ), +#endif +#ifdef SQLITE_DEFAULT_PROXYDIR_PERMISSIONS + "DEFAULT_PROXYDIR_PERMISSIONS=" CTIMEOPT_VAL(SQLITE_DEFAULT_PROXYDIR_PERMISSIONS), +#endif +#ifdef SQLITE_DEFAULT_RECURSIVE_TRIGGERS + "DEFAULT_RECURSIVE_TRIGGERS", +#endif +#ifdef SQLITE_DEFAULT_ROWEST + "DEFAULT_ROWEST=" CTIMEOPT_VAL(SQLITE_DEFAULT_ROWEST), +#endif +#ifdef SQLITE_DEFAULT_SECTOR_SIZE + "DEFAULT_SECTOR_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_SECTOR_SIZE), +#endif +#ifdef SQLITE_DEFAULT_SYNCHRONOUS + "DEFAULT_SYNCHRONOUS=" CTIMEOPT_VAL(SQLITE_DEFAULT_SYNCHRONOUS), +#endif +#ifdef SQLITE_DEFAULT_WAL_AUTOCHECKPOINT + "DEFAULT_WAL_AUTOCHECKPOINT=" CTIMEOPT_VAL(SQLITE_DEFAULT_WAL_AUTOCHECKPOINT), +#endif +#ifdef SQLITE_DEFAULT_WAL_SYNCHRONOUS + "DEFAULT_WAL_SYNCHRONOUS=" CTIMEOPT_VAL(SQLITE_DEFAULT_WAL_SYNCHRONOUS), +#endif +#ifdef SQLITE_DEFAULT_WORKER_THREADS + "DEFAULT_WORKER_THREADS=" CTIMEOPT_VAL(SQLITE_DEFAULT_WORKER_THREADS), +#endif +#ifdef SQLITE_DIRECT_OVERFLOW_READ + "DIRECT_OVERFLOW_READ", +#endif +#ifdef SQLITE_DISABLE_DIRSYNC + "DISABLE_DIRSYNC", +#endif +#ifdef SQLITE_DISABLE_FTS3_UNICODE + "DISABLE_FTS3_UNICODE", +#endif +#ifdef SQLITE_DISABLE_FTS4_DEFERRED + "DISABLE_FTS4_DEFERRED", +#endif +#ifdef SQLITE_DISABLE_INTRINSIC + "DISABLE_INTRINSIC", +#endif +#ifdef SQLITE_DISABLE_LFS + "DISABLE_LFS", +#endif +#ifdef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS + "DISABLE_PAGECACHE_OVERFLOW_STATS", +#endif +#ifdef SQLITE_DISABLE_SKIPAHEAD_DISTINCT + "DISABLE_SKIPAHEAD_DISTINCT", +#endif +#ifdef SQLITE_DQS + "DQS=" CTIMEOPT_VAL(SQLITE_DQS), +#endif +#ifdef SQLITE_ENABLE_8_3_NAMES + "ENABLE_8_3_NAMES=" CTIMEOPT_VAL(SQLITE_ENABLE_8_3_NAMES), +#endif +#ifdef SQLITE_ENABLE_API_ARMOR + "ENABLE_API_ARMOR", +#endif +#ifdef SQLITE_ENABLE_ATOMIC_WRITE + "ENABLE_ATOMIC_WRITE", +#endif +#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE + "ENABLE_BATCH_ATOMIC_WRITE", +#endif +#ifdef SQLITE_ENABLE_BYTECODE_VTAB + "ENABLE_BYTECODE_VTAB", +#endif +#ifdef SQLITE_ENABLE_CARRAY + "ENABLE_CARRAY", +#endif +#ifdef SQLITE_ENABLE_CEROD + "ENABLE_CEROD=" CTIMEOPT_VAL(SQLITE_ENABLE_CEROD), +#endif +#ifdef SQLITE_ENABLE_COLUMN_METADATA + "ENABLE_COLUMN_METADATA", +#endif +#ifdef SQLITE_ENABLE_COLUMN_USED_MASK + "ENABLE_COLUMN_USED_MASK", +#endif +#ifdef SQLITE_ENABLE_COSTMULT + "ENABLE_COSTMULT", +#endif +#ifdef SQLITE_ENABLE_CURSOR_HINTS + "ENABLE_CURSOR_HINTS", +#endif +#ifdef SQLITE_ENABLE_DBPAGE_VTAB + "ENABLE_DBPAGE_VTAB", +#endif +#ifdef SQLITE_ENABLE_DBSTAT_VTAB + "ENABLE_DBSTAT_VTAB", +#endif +#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT + "ENABLE_EXPENSIVE_ASSERT", +#endif +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + "ENABLE_EXPLAIN_COMMENTS", +#endif +#ifdef SQLITE_ENABLE_FTS3 + "ENABLE_FTS3", +#endif +#ifdef SQLITE_ENABLE_FTS3_PARENTHESIS + "ENABLE_FTS3_PARENTHESIS", +#endif +#ifdef SQLITE_ENABLE_FTS3_TOKENIZER + "ENABLE_FTS3_TOKENIZER", +#endif +#ifdef SQLITE_ENABLE_FTS4 + "ENABLE_FTS4", +#endif +#ifdef SQLITE_ENABLE_FTS5 + "ENABLE_FTS5", +#endif +#ifdef SQLITE_ENABLE_GEOPOLY + "ENABLE_GEOPOLY", +#endif +#ifdef SQLITE_ENABLE_HIDDEN_COLUMNS + "ENABLE_HIDDEN_COLUMNS", +#endif +#ifdef SQLITE_ENABLE_ICU + "ENABLE_ICU", +#endif +#ifdef SQLITE_ENABLE_IOTRACE + "ENABLE_IOTRACE", +#endif +#ifdef SQLITE_ENABLE_LOAD_EXTENSION + "ENABLE_LOAD_EXTENSION", +#endif +#ifdef SQLITE_ENABLE_LOCKING_STYLE + "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE), +#endif +#ifdef SQLITE_ENABLE_MATH_FUNCTIONS + "ENABLE_MATH_FUNCTIONS", +#endif +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT + "ENABLE_MEMORY_MANAGEMENT", +#endif +#ifdef SQLITE_ENABLE_MEMSYS3 + "ENABLE_MEMSYS3", +#endif +#ifdef SQLITE_ENABLE_MEMSYS5 + "ENABLE_MEMSYS5", +#endif +#ifdef SQLITE_ENABLE_MULTIPLEX + "ENABLE_MULTIPLEX", +#endif +#ifdef SQLITE_ENABLE_NORMALIZE + "ENABLE_NORMALIZE", +#endif +#ifdef SQLITE_ENABLE_NULL_TRIM + "ENABLE_NULL_TRIM", +#endif +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC + "ENABLE_OFFSET_SQL_FUNC", +#endif +#ifdef SQLITE_ENABLE_ORDERED_SET_AGGREGATES + "ENABLE_ORDERED_SET_AGGREGATES", +#endif +#ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK + "ENABLE_OVERSIZE_CELL_CHECK", +#endif +#ifdef SQLITE_ENABLE_PERCENTILE + "ENABLE_PERCENTILE", +#endif +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + "ENABLE_PREUPDATE_HOOK", +#endif +#ifdef SQLITE_ENABLE_QPSG + "ENABLE_QPSG", +#endif +#ifdef SQLITE_ENABLE_RBU + "ENABLE_RBU", +#endif +#ifdef SQLITE_ENABLE_RTREE + "ENABLE_RTREE", +#endif +#ifdef SQLITE_ENABLE_SESSION + "ENABLE_SESSION", +#endif +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + "ENABLE_SETLK_TIMEOUT", +#endif +#ifdef SQLITE_ENABLE_SNAPSHOT + "ENABLE_SNAPSHOT", +#endif +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + "ENABLE_SORTER_REFERENCES", +#endif +#ifdef SQLITE_ENABLE_SQLLOG + "ENABLE_SQLLOG", +#endif +#ifdef SQLITE_ENABLE_STAT4 + "ENABLE_STAT4", +#endif +#ifdef SQLITE_ENABLE_STMTVTAB + "ENABLE_STMTVTAB", +#endif +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + "ENABLE_STMT_SCANSTATUS", +#endif +#ifdef SQLITE_ENABLE_TREETRACE + "ENABLE_TREETRACE", +#endif +#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION + "ENABLE_UNKNOWN_SQL_FUNCTION", +#endif +#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY + "ENABLE_UNLOCK_NOTIFY", +#endif +#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT + "ENABLE_UPDATE_DELETE_LIMIT", +#endif +#ifdef SQLITE_ENABLE_URI_00_ERROR + "ENABLE_URI_00_ERROR", +#endif +#ifdef SQLITE_ENABLE_VFSTRACE + "ENABLE_VFSTRACE", +#endif +#ifdef SQLITE_ENABLE_WHERETRACE + "ENABLE_WHERETRACE", +#endif +#ifdef SQLITE_ENABLE_ZIPVFS + "ENABLE_ZIPVFS", +#endif +#ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS + "EXPLAIN_ESTIMATED_ROWS", +#endif +#ifdef SQLITE_EXTRA_AUTOEXT + "EXTRA_AUTOEXT=" CTIMEOPT_VAL(SQLITE_EXTRA_AUTOEXT), +#endif +#ifdef SQLITE_EXTRA_IFNULLROW + "EXTRA_IFNULLROW", +#endif +#ifdef SQLITE_EXTRA_INIT + "EXTRA_INIT=" CTIMEOPT_VAL(SQLITE_EXTRA_INIT), +#endif +#ifdef SQLITE_EXTRA_INIT_MUTEXED + "EXTRA_INIT_MUTEXED=" CTIMEOPT_VAL(SQLITE_EXTRA_INIT_MUTEXED), +#endif +#ifdef SQLITE_EXTRA_SHUTDOWN + "EXTRA_SHUTDOWN=" CTIMEOPT_VAL(SQLITE_EXTRA_SHUTDOWN), +#endif +#ifdef SQLITE_FTS3_MAX_EXPR_DEPTH + "FTS3_MAX_EXPR_DEPTH=" CTIMEOPT_VAL(SQLITE_FTS3_MAX_EXPR_DEPTH), +#endif +#ifdef SQLITE_FTS5_ENABLE_TEST_MI + "FTS5_ENABLE_TEST_MI", +#endif +#ifdef SQLITE_FTS5_NO_WITHOUT_ROWID + "FTS5_NO_WITHOUT_ROWID", +#endif +#if HAVE_ISNAN || SQLITE_HAVE_ISNAN + "HAVE_ISNAN", +#endif +#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX +# if SQLITE_HOMEGROWN_RECURSIVE_MUTEX != 1 + "HOMEGROWN_RECURSIVE_MUTEX=" CTIMEOPT_VAL(SQLITE_HOMEGROWN_RECURSIVE_MUTEX), +# endif +#endif +#ifdef SQLITE_IGNORE_AFP_LOCK_ERRORS + "IGNORE_AFP_LOCK_ERRORS", +#endif +#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS + "IGNORE_FLOCK_LOCK_ERRORS", +#endif +#ifdef SQLITE_INLINE_MEMCPY + "INLINE_MEMCPY", +#endif +#ifdef SQLITE_INT64_TYPE + "INT64_TYPE", +#endif +#ifdef SQLITE_INTEGRITY_CHECK_ERROR_MAX + "INTEGRITY_CHECK_ERROR_MAX=" CTIMEOPT_VAL(SQLITE_INTEGRITY_CHECK_ERROR_MAX), +#endif +#ifdef SQLITE_LEGACY_JSON_VALID + "LEGACY_JSON_VALID", +#endif +#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS + "LIKE_DOESNT_MATCH_BLOBS", +#endif +#ifdef SQLITE_LOCK_TRACE + "LOCK_TRACE", +#endif +#ifdef SQLITE_LOG_CACHE_SPILL + "LOG_CACHE_SPILL", +#endif +#ifdef SQLITE_MALLOC_SOFT_LIMIT + "MALLOC_SOFT_LIMIT=" CTIMEOPT_VAL(SQLITE_MALLOC_SOFT_LIMIT), +#endif +#ifdef SQLITE_MAX_ATTACHED + "MAX_ATTACHED=" CTIMEOPT_VAL(SQLITE_MAX_ATTACHED), +#endif +#ifdef SQLITE_MAX_COLUMN + "MAX_COLUMN=" CTIMEOPT_VAL(SQLITE_MAX_COLUMN), +#endif +#ifdef SQLITE_MAX_COMPOUND_SELECT + "MAX_COMPOUND_SELECT=" CTIMEOPT_VAL(SQLITE_MAX_COMPOUND_SELECT), +#endif +#ifdef SQLITE_MAX_DEFAULT_PAGE_SIZE + "MAX_DEFAULT_PAGE_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_DEFAULT_PAGE_SIZE), +#endif +#ifdef SQLITE_MAX_EXPR_DEPTH + "MAX_EXPR_DEPTH=" CTIMEOPT_VAL(SQLITE_MAX_EXPR_DEPTH), +#endif +#ifdef SQLITE_MAX_FUNCTION_ARG + "MAX_FUNCTION_ARG=" CTIMEOPT_VAL(SQLITE_MAX_FUNCTION_ARG), +#endif +#ifdef SQLITE_MAX_LENGTH + "MAX_LENGTH=" CTIMEOPT_VAL(SQLITE_MAX_LENGTH), +#endif +#ifdef SQLITE_MAX_LIKE_PATTERN_LENGTH + "MAX_LIKE_PATTERN_LENGTH=" CTIMEOPT_VAL(SQLITE_MAX_LIKE_PATTERN_LENGTH), +#endif +#ifdef SQLITE_MAX_MEMORY + "MAX_MEMORY=" CTIMEOPT_VAL(SQLITE_MAX_MEMORY), +#endif +#ifdef SQLITE_MAX_MMAP_SIZE + "MAX_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_MMAP_SIZE), +#endif +#ifdef SQLITE_MAX_MMAP_SIZE_ + "MAX_MMAP_SIZE_=" CTIMEOPT_VAL(SQLITE_MAX_MMAP_SIZE_), +#endif +#ifdef SQLITE_MAX_PAGE_COUNT + "MAX_PAGE_COUNT=" CTIMEOPT_VAL(SQLITE_MAX_PAGE_COUNT), +#endif +#ifdef SQLITE_MAX_PAGE_SIZE + "MAX_PAGE_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_PAGE_SIZE), +#endif +#ifdef SQLITE_MAX_SCHEMA_RETRY + "MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY), +#endif +#ifdef SQLITE_MAX_SQL_LENGTH + "MAX_SQL_LENGTH=" CTIMEOPT_VAL(SQLITE_MAX_SQL_LENGTH), +#endif +#ifdef SQLITE_MAX_TRIGGER_DEPTH + "MAX_TRIGGER_DEPTH=" CTIMEOPT_VAL(SQLITE_MAX_TRIGGER_DEPTH), +#endif +#ifdef SQLITE_MAX_VARIABLE_NUMBER + "MAX_VARIABLE_NUMBER=" CTIMEOPT_VAL(SQLITE_MAX_VARIABLE_NUMBER), +#endif +#ifdef SQLITE_MAX_VDBE_OP + "MAX_VDBE_OP=" CTIMEOPT_VAL(SQLITE_MAX_VDBE_OP), +#endif +#ifdef SQLITE_MAX_WORKER_THREADS + "MAX_WORKER_THREADS=" CTIMEOPT_VAL(SQLITE_MAX_WORKER_THREADS), +#endif +#ifdef SQLITE_MEMDEBUG + "MEMDEBUG", +#endif +#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT + "MIXED_ENDIAN_64BIT_FLOAT", +#endif +#ifdef SQLITE_MMAP_READWRITE + "MMAP_READWRITE", +#endif +#ifdef SQLITE_MUTEX_NOOP + "MUTEX_NOOP", +#endif +#ifdef SQLITE_MUTEX_OMIT + "MUTEX_OMIT", +#endif +#ifdef SQLITE_MUTEX_PTHREADS + "MUTEX_PTHREADS", +#endif +#ifdef SQLITE_MUTEX_W32 + "MUTEX_W32", +#endif +#ifdef SQLITE_NEED_ERR_NAME + "NEED_ERR_NAME", +#endif +#ifdef SQLITE_NO_SYNC + "NO_SYNC", +#endif +#ifdef SQLITE_OMIT_ALTERTABLE + "OMIT_ALTERTABLE", +#endif +#ifdef SQLITE_OMIT_ANALYZE + "OMIT_ANALYZE", +#endif +#ifdef SQLITE_OMIT_ATTACH + "OMIT_ATTACH", +#endif +#ifdef SQLITE_OMIT_AUTHORIZATION + "OMIT_AUTHORIZATION", +#endif +#ifdef SQLITE_OMIT_AUTOINCREMENT + "OMIT_AUTOINCREMENT", +#endif +#ifdef SQLITE_OMIT_AUTOINIT + "OMIT_AUTOINIT", +#endif +#ifdef SQLITE_OMIT_AUTOMATIC_INDEX + "OMIT_AUTOMATIC_INDEX", +#endif +#ifdef SQLITE_OMIT_AUTORESET + "OMIT_AUTORESET", +#endif +#ifdef SQLITE_OMIT_AUTOVACUUM + "OMIT_AUTOVACUUM", +#endif +#ifdef SQLITE_OMIT_BETWEEN_OPTIMIZATION + "OMIT_BETWEEN_OPTIMIZATION", +#endif +#ifdef SQLITE_OMIT_BLOB_LITERAL + "OMIT_BLOB_LITERAL", +#endif +#ifdef SQLITE_OMIT_CAST + "OMIT_CAST", +#endif +#ifdef SQLITE_OMIT_CHECK + "OMIT_CHECK", +#endif +#ifdef SQLITE_OMIT_COMPLETE + "OMIT_COMPLETE", +#endif +#ifdef SQLITE_OMIT_COMPOUND_SELECT + "OMIT_COMPOUND_SELECT", +#endif +#ifdef SQLITE_OMIT_CONFLICT_CLAUSE + "OMIT_CONFLICT_CLAUSE", +#endif +#ifdef SQLITE_OMIT_CTE + "OMIT_CTE", +#endif +#if defined(SQLITE_OMIT_DATETIME_FUNCS) || defined(SQLITE_OMIT_FLOATING_POINT) + "OMIT_DATETIME_FUNCS", +#endif +#ifdef SQLITE_OMIT_DECLTYPE + "OMIT_DECLTYPE", +#endif +#ifdef SQLITE_OMIT_DEPRECATED + "OMIT_DEPRECATED", +#endif +#ifdef SQLITE_OMIT_DESERIALIZE + "OMIT_DESERIALIZE", +#endif +#ifdef SQLITE_OMIT_DISKIO + "OMIT_DISKIO", +#endif +#ifdef SQLITE_OMIT_EXPLAIN + "OMIT_EXPLAIN", +#endif +#ifdef SQLITE_OMIT_FLAG_PRAGMAS + "OMIT_FLAG_PRAGMAS", +#endif +#ifdef SQLITE_OMIT_FLOATING_POINT + "OMIT_FLOATING_POINT", +#endif +#ifdef SQLITE_OMIT_FOREIGN_KEY + "OMIT_FOREIGN_KEY", +#endif +#ifdef SQLITE_OMIT_GET_TABLE + "OMIT_GET_TABLE", +#endif +#ifdef SQLITE_OMIT_HEX_INTEGER + "OMIT_HEX_INTEGER", +#endif +#ifdef SQLITE_OMIT_INCRBLOB + "OMIT_INCRBLOB", +#endif +#ifdef SQLITE_OMIT_INTEGRITY_CHECK + "OMIT_INTEGRITY_CHECK", +#endif +#ifdef SQLITE_OMIT_INTROSPECTION_PRAGMAS + "OMIT_INTROSPECTION_PRAGMAS", +#endif +#ifdef SQLITE_OMIT_JSON + "OMIT_JSON", +#endif +#ifdef SQLITE_OMIT_LIKE_OPTIMIZATION + "OMIT_LIKE_OPTIMIZATION", +#endif +#ifdef SQLITE_OMIT_LOAD_EXTENSION + "OMIT_LOAD_EXTENSION", +#endif +#ifdef SQLITE_OMIT_LOCALTIME + "OMIT_LOCALTIME", +#endif +#ifdef SQLITE_OMIT_LOOKASIDE + "OMIT_LOOKASIDE", +#endif +#ifdef SQLITE_OMIT_MEMORYDB + "OMIT_MEMORYDB", +#endif +#ifdef SQLITE_OMIT_OR_OPTIMIZATION + "OMIT_OR_OPTIMIZATION", +#endif +#ifdef SQLITE_OMIT_PAGER_PRAGMAS + "OMIT_PAGER_PRAGMAS", +#endif +#ifdef SQLITE_OMIT_PARSER_TRACE + "OMIT_PARSER_TRACE", +#endif +#ifdef SQLITE_OMIT_POPEN + "OMIT_POPEN", +#endif +#ifdef SQLITE_OMIT_PRAGMA + "OMIT_PRAGMA", +#endif +#ifdef SQLITE_OMIT_PROGRESS_CALLBACK + "OMIT_PROGRESS_CALLBACK", +#endif +#ifdef SQLITE_OMIT_QUICKBALANCE + "OMIT_QUICKBALANCE", +#endif +#ifdef SQLITE_OMIT_REINDEX + "OMIT_REINDEX", +#endif +#ifdef SQLITE_OMIT_SCHEMA_PRAGMAS + "OMIT_SCHEMA_PRAGMAS", +#endif +#ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS + "OMIT_SCHEMA_VERSION_PRAGMAS", +#endif +#ifdef SQLITE_OMIT_SEH + "OMIT_SEH", +#endif +#ifdef SQLITE_OMIT_SHARED_CACHE + "OMIT_SHARED_CACHE", +#endif +#ifdef SQLITE_OMIT_SHUTDOWN_DIRECTORIES + "OMIT_SHUTDOWN_DIRECTORIES", +#endif +#ifdef SQLITE_OMIT_SUBQUERY + "OMIT_SUBQUERY", +#endif +#ifdef SQLITE_OMIT_TCL_VARIABLE + "OMIT_TCL_VARIABLE", +#endif +#ifdef SQLITE_OMIT_TEMPDB + "OMIT_TEMPDB", +#endif +#ifdef SQLITE_OMIT_TEST_CONTROL + "OMIT_TEST_CONTROL", +#endif +#ifdef SQLITE_OMIT_TRACE +# if SQLITE_OMIT_TRACE != 1 + "OMIT_TRACE=" CTIMEOPT_VAL(SQLITE_OMIT_TRACE), +# endif +#endif +#ifdef SQLITE_OMIT_TRIGGER + "OMIT_TRIGGER", +#endif +#ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION + "OMIT_TRUNCATE_OPTIMIZATION", +#endif +#ifdef SQLITE_OMIT_UTF16 + "OMIT_UTF16", +#endif +#ifdef SQLITE_OMIT_VACUUM + "OMIT_VACUUM", +#endif +#ifdef SQLITE_OMIT_VIEW + "OMIT_VIEW", +#endif +#ifdef SQLITE_OMIT_VIRTUALTABLE + "OMIT_VIRTUALTABLE", +#endif +#ifdef SQLITE_OMIT_WAL + "OMIT_WAL", +#endif +#ifdef SQLITE_OMIT_WSD + "OMIT_WSD", +#endif +#ifdef SQLITE_OMIT_XFER_OPT + "OMIT_XFER_OPT", +#endif +#ifdef SQLITE_PERFORMANCE_TRACE + "PERFORMANCE_TRACE", +#endif +#ifdef SQLITE_POWERSAFE_OVERWRITE +# if SQLITE_POWERSAFE_OVERWRITE != 1 + "POWERSAFE_OVERWRITE=" CTIMEOPT_VAL(SQLITE_POWERSAFE_OVERWRITE), +# endif +#endif +#ifdef SQLITE_PREFER_PROXY_LOCKING + "PREFER_PROXY_LOCKING", +#endif +#ifdef SQLITE_PROXY_DEBUG + "PROXY_DEBUG", +#endif +#ifdef SQLITE_REVERSE_UNORDERED_SELECTS + "REVERSE_UNORDERED_SELECTS", +#endif +#ifdef SQLITE_RTREE_INT_ONLY + "RTREE_INT_ONLY", +#endif +#ifdef SQLITE_SECURE_DELETE + "SECURE_DELETE", +#endif +#ifdef SQLITE_SMALL_STACK + "SMALL_STACK", +#endif +#ifdef SQLITE_SORTER_PMASZ + "SORTER_PMASZ=" CTIMEOPT_VAL(SQLITE_SORTER_PMASZ), +#endif +#ifdef SQLITE_SOUNDEX + "SOUNDEX", +#endif +#ifdef SQLITE_STAT4_SAMPLES + "STAT4_SAMPLES=" CTIMEOPT_VAL(SQLITE_STAT4_SAMPLES), +#endif +#ifdef SQLITE_STMTJRNL_SPILL + "STMTJRNL_SPILL=" CTIMEOPT_VAL(SQLITE_STMTJRNL_SPILL), +#endif +#ifdef SQLITE_STRICT_SUBTYPE + "STRICT_SUBTYPE", +#endif +#ifdef SQLITE_SUBSTR_COMPATIBILITY + "SUBSTR_COMPATIBILITY", +#endif +#if (!defined(SQLITE_WIN32_MALLOC) \ + && !defined(SQLITE_ZERO_MALLOC) \ + && !defined(SQLITE_MEMDEBUG) \ + ) || defined(SQLITE_SYSTEM_MALLOC) + "SYSTEM_MALLOC", +#endif +#ifdef SQLITE_TCL + "TCL", +#endif +#ifdef SQLITE_TEMP_STORE + "TEMP_STORE=" CTIMEOPT_VAL(SQLITE_TEMP_STORE), +#endif +#ifdef SQLITE_TEST + "TEST", +#endif +#if defined(SQLITE_THREADSAFE) + "THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE), +#elif defined(THREADSAFE) + "THREADSAFE=" CTIMEOPT_VAL(THREADSAFE), +#else + "THREADSAFE=1", +#endif +#ifdef SQLITE_UNLINK_AFTER_CLOSE + "UNLINK_AFTER_CLOSE", +#endif +#ifdef SQLITE_UNTESTABLE + "UNTESTABLE", +#endif +#ifdef SQLITE_USE_ALLOCA + "USE_ALLOCA", +#endif +#ifdef SQLITE_USE_FCNTL_TRACE + "USE_FCNTL_TRACE", +#endif +#ifdef SQLITE_USE_URI + "USE_URI", +#endif +#ifdef SQLITE_VDBE_COVERAGE + "VDBE_COVERAGE", +#endif +#ifdef SQLITE_WIN32_MALLOC + "WIN32_MALLOC", +#endif +#ifdef SQLITE_ZERO_MALLOC + "ZERO_MALLOC", +#endif + +} ; + +SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt){ + *pnOpt = sizeof(sqlite3azCompileOpt) / sizeof(sqlite3azCompileOpt[0]); + return (const char**)sqlite3azCompileOpt; +} + +#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ + +/************** End of ctime.c ***********************************************/ +/************** Begin file global.c ******************************************/ +/* +** 2008 June 13 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains definitions of global variables and constants. +*/ +/* #include "sqliteInt.h" */ + +/* An array to map all upper-case characters into their corresponding +** lower-case character. +** +** SQLite only considers US-ASCII (or EBCDIC) characters. We do not +** handle case conversions for the UTF character set since the tables +** involved are nearly as big or bigger than SQLite itself. +*/ +SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[] = { +#ifdef SQLITE_ASCII + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103, + 104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121, + 122, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,106,107, + 108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125, + 126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, + 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161, + 162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179, + 180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197, + 198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215, + 216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233, + 234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251, + 252,253,254,255, +#endif +#ifdef SQLITE_EBCDIC + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 0x */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 1x */ + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 2x */ + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 3x */ + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 4x */ + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 5x */ + 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, /* 6x */ + 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, /* 7x */ + 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, /* 8x */ + 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, /* 9x */ + 160,161,162,163,164,165,166,167,168,169,170,171,140,141,142,175, /* Ax */ + 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, /* Bx */ + 192,129,130,131,132,133,134,135,136,137,202,203,204,205,206,207, /* Cx */ + 208,145,146,147,148,149,150,151,152,153,218,219,220,221,222,223, /* Dx */ + 224,225,162,163,164,165,166,167,168,169,234,235,236,237,238,239, /* Ex */ + 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, /* Fx */ +#endif +/* All of the upper-to-lower conversion data is above. The following +** 18 integers are completely unrelated. They are appended to the +** sqlite3UpperToLower[] array to avoid UBSAN warnings. Here's what is +** going on: +** +** The SQL comparison operators (<>, =, >, <=, <, and >=) are implemented +** by invoking sqlite3MemCompare(A,B) which compares values A and B and +** returns negative, zero, or positive if A is less then, equal to, or +** greater than B, respectively. Then the true false results is found by +** consulting sqlite3aLTb[opcode], sqlite3aEQb[opcode], or +** sqlite3aGTb[opcode] depending on whether the result of compare(A,B) +** is negative, zero, or positive, where opcode is the specific opcode. +** The only works because the comparison opcodes are consecutive and in +** this order: NE EQ GT LE LT GE. Various assert()s throughout the code +** ensure that is the case. +** +** These elements must be appended to another array. Otherwise the +** index (here shown as [256-OP_Ne]) would be out-of-bounds and thus +** be undefined behavior. That's goofy, but the C-standards people thought +** it was a good idea, so here we are. +*/ +/* NE EQ GT LE LT GE */ + 1, 0, 0, 1, 1, 0, /* aLTb[]: Use when compare(A,B) less than zero */ + 0, 1, 0, 1, 0, 1, /* aEQb[]: Use when compare(A,B) equals zero */ + 1, 0, 1, 0, 0, 1 /* aGTb[]: Use when compare(A,B) greater than zero*/ +}; +SQLITE_PRIVATE const unsigned char *sqlite3aLTb = &sqlite3UpperToLower[256-OP_Ne]; +SQLITE_PRIVATE const unsigned char *sqlite3aEQb = &sqlite3UpperToLower[256+6-OP_Ne]; +SQLITE_PRIVATE const unsigned char *sqlite3aGTb = &sqlite3UpperToLower[256+12-OP_Ne]; + +/* +** The following 256 byte lookup table is used to support SQLites built-in +** equivalents to the following standard library functions: +** +** isspace() 0x01 +** isalpha() 0x02 +** isdigit() 0x04 +** isalnum() 0x06 +** isxdigit() 0x08 +** toupper() 0x20 +** SQLite identifier character 0x40 $, _, or non-ascii +** Quote character 0x80 +** +** Bit 0x20 is set if the mapped character requires translation to upper +** case. i.e. if the character is a lower-case ASCII character. +** If x is a lower-case ASCII character, then its upper-case equivalent +** is (x - 0x20). Therefore toupper() can be implemented as: +** +** (x & ~(map[x]&0x20)) +** +** The equivalent of tolower() is implemented using the sqlite3UpperToLower[] +** array. tolower() is used more often than toupper() by SQLite. +** +** Bit 0x40 is set if the character is non-alphanumeric and can be used in an +** SQLite identifier. Identifiers are alphanumerics, "_", "$", and any +** non-ASCII UTF character. Hence the test for whether or not a character is +** part of an identifier is 0x46. +*/ +SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00..07 ........ */ + 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, /* 08..0f ........ */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 10..17 ........ */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 18..1f ........ */ + 0x01, 0x00, 0x80, 0x00, 0x40, 0x00, 0x00, 0x80, /* 20..27 !"#$%&' */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 28..2f ()*+,-./ */ + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, /* 30..37 01234567 */ + 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 38..3f 89:;<=>? */ + + 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x02, /* 40..47 @ABCDEFG */ + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 48..4f HIJKLMNO */ + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* 50..57 PQRSTUVW */ + 0x02, 0x02, 0x02, 0x80, 0x00, 0x00, 0x00, 0x40, /* 58..5f XYZ[\]^_ */ + 0x80, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x22, /* 60..67 `abcdefg */ + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 68..6f hijklmno */ + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* 70..77 pqrstuvw */ + 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, /* 78..7f xyz{|}~. */ + + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 80..87 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 88..8f ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 90..97 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* 98..9f ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* a0..a7 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* a8..af ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* b0..b7 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* b8..bf ........ */ + + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* c0..c7 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* c8..cf ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* d0..d7 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* d8..df ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* e0..e7 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* e8..ef ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* f0..f7 ........ */ + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 /* f8..ff ........ */ +}; + +/* EVIDENCE-OF: R-02982-34736 In order to maintain full backwards +** compatibility for legacy applications, the URI filename capability is +** disabled by default. +** +** EVIDENCE-OF: R-38799-08373 URI filenames can be enabled or disabled +** using the SQLITE_USE_URI=1 or SQLITE_USE_URI=0 compile-time options. +** +** EVIDENCE-OF: R-43642-56306 By default, URI handling is globally +** disabled. The default value may be changed by compiling with the +** SQLITE_USE_URI symbol defined. +*/ +#ifndef SQLITE_USE_URI +# define SQLITE_USE_URI 0 +#endif + +/* EVIDENCE-OF: R-38720-18127 The default setting is determined by the +** SQLITE_ALLOW_COVERING_INDEX_SCAN compile-time option, or is "on" if +** that compile-time option is omitted. +*/ +#if !defined(SQLITE_ALLOW_COVERING_INDEX_SCAN) +# define SQLITE_ALLOW_COVERING_INDEX_SCAN 1 +#else +# if !SQLITE_ALLOW_COVERING_INDEX_SCAN +# error "Compile-time disabling of covering index scan using the\ + -DSQLITE_ALLOW_COVERING_INDEX_SCAN=0 option is deprecated.\ + Contact SQLite developers if this is a problem for you, and\ + delete this #error macro to continue with your build." +# endif +#endif + +/* The minimum PMA size is set to this value multiplied by the database +** page size in bytes. +*/ +#ifndef SQLITE_SORTER_PMASZ +# define SQLITE_SORTER_PMASZ 250 +#endif + +/* Statement journals spill to disk when their size exceeds the following +** threshold (in bytes). 0 means that statement journals are created and +** written to disk immediately (the default behavior for SQLite versions +** before 3.12.0). -1 means always keep the entire statement journal in +** memory. (The statement journal is also always held entirely in memory +** if journal_mode=MEMORY or if temp_store=MEMORY, regardless of this +** setting.) +*/ +#ifndef SQLITE_STMTJRNL_SPILL +# define SQLITE_STMTJRNL_SPILL (64*1024) +#endif + +/* +** The default lookaside-configuration, the format "SZ,N". SZ is the +** number of bytes in each lookaside slot (should be a multiple of 8) +** and N is the number of slots. The lookaside-configuration can be +** changed as start-time using sqlite3_config(SQLITE_CONFIG_LOOKASIDE) +** or at run-time for an individual database connection using +** sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE); +** +** With the two-size-lookaside enhancement, less lookaside is required. +** The default configuration of 1200,40 actually provides 30 1200-byte slots +** and 93 128-byte slots, which is more lookaside than is available +** using the older 1200,100 configuration without two-size-lookaside. +*/ +#ifndef SQLITE_DEFAULT_LOOKASIDE +# ifdef SQLITE_OMIT_TWOSIZE_LOOKASIDE +# define SQLITE_DEFAULT_LOOKASIDE 1200,100 /* 120KB of memory */ +# else +# define SQLITE_DEFAULT_LOOKASIDE 1200,40 /* 48KB of memory */ +# endif +#endif + + +/* The default maximum size of an in-memory database created using +** sqlite3_deserialize() +*/ +#ifndef SQLITE_MEMDB_DEFAULT_MAXSIZE +# define SQLITE_MEMDB_DEFAULT_MAXSIZE 1073741824 +#endif + +/* +** The following singleton contains the global configuration for +** the SQLite library. +*/ +SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { + SQLITE_DEFAULT_MEMSTATUS, /* bMemstat */ + 1, /* bCoreMutex */ + SQLITE_THREADSAFE==1, /* bFullMutex */ + SQLITE_USE_URI, /* bOpenUri */ + SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */ + 0, /* bSmallMalloc */ + 1, /* bExtraSchemaChecks */ +#ifdef SQLITE_DEBUG + 0, /* bJsonSelfcheck */ +#endif + 0x7ffffffe, /* mxStrlen */ + 0, /* neverCorrupt */ + SQLITE_DEFAULT_LOOKASIDE, /* szLookaside, nLookaside */ + SQLITE_STMTJRNL_SPILL, /* nStmtSpill */ + {0,0,0,0,0,0,0,0}, /* m */ + {0,0,0,0,0,0,0,0,0}, /* mutex */ + {0,0,0,0,0,0,0,0,0,0,0,0,0},/* pcache2 */ + (void*)0, /* pHeap */ + 0, /* nHeap */ + 0, 0, /* mnHeap, mxHeap */ + SQLITE_DEFAULT_MMAP_SIZE, /* szMmap */ + SQLITE_MAX_MMAP_SIZE, /* mxMmap */ + (void*)0, /* pPage */ + 0, /* szPage */ + SQLITE_DEFAULT_PCACHE_INITSZ, /* nPage */ + 0, /* mxParserStack */ + 0, /* sharedCacheEnabled */ + SQLITE_SORTER_PMASZ, /* szPma */ + /* All the rest should always be initialized to zero */ + 0, /* isInit */ + 0, /* inProgress */ + 0, /* isMutexInit */ + 0, /* isMallocInit */ + 0, /* isPCacheInit */ + 0, /* nRefInitMutex */ + 0, /* pInitMutex */ + 0, /* xLog */ + 0, /* pLogArg */ +#ifdef SQLITE_ENABLE_SQLLOG + 0, /* xSqllog */ + 0, /* pSqllogArg */ +#endif +#ifdef SQLITE_VDBE_COVERAGE + 0, /* xVdbeBranch */ + 0, /* pVbeBranchArg */ +#endif +#ifndef SQLITE_OMIT_DESERIALIZE + SQLITE_MEMDB_DEFAULT_MAXSIZE, /* mxMemdbSize */ +#endif +#ifndef SQLITE_UNTESTABLE + 0, /* xTestCallback */ +#endif +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + 0, /* mNoVisibleRowid. 0 == allow rowid-in-view */ +#endif + 0, /* bLocaltimeFault */ + 0, /* xAltLocaltime */ + 0x7ffffffe, /* iOnceResetThreshold */ + SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */ + 0, /* iPrngSeed */ +#ifdef SQLITE_DEBUG + {0,0,0,0,0,0}, /* aTune */ +#endif +}; + +/* +** Hash table for global functions - functions common to all +** database connections. After initialization, this table is +** read-only. +*/ +SQLITE_PRIVATE FuncDefHash sqlite3BuiltinFunctions; + +#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG) +/* +** Counter used for coverage testing. Does not come into play for +** release builds. +** +** Access to this global variable is not mutex protected. This might +** result in TSAN warnings. But as the variable does not exist in +** release builds, that should not be a concern. +*/ +SQLITE_PRIVATE unsigned int sqlite3CoverageCounter; +#endif /* SQLITE_COVERAGE_TEST || SQLITE_DEBUG */ + +#ifdef VDBE_PROFILE +/* +** The following performance counter can be used in place of +** sqlite3Hwtime() for profiling. This is a no-op on standard builds. +*/ +SQLITE_PRIVATE sqlite3_uint64 sqlite3NProfileCnt = 0; +#endif + +/* +** The value of the "pending" byte must be 0x40000000 (1 byte past the +** 1-gibabyte boundary) in a compatible database. SQLite never uses +** the database page that contains the pending byte. It never attempts +** to read or write that page. The pending byte page is set aside +** for use by the VFS layers as space for managing file locks. +** +** During testing, it is often desirable to move the pending byte to +** a different position in the file. This allows code that has to +** deal with the pending byte to run on files that are much smaller +** than 1 GiB. The sqlite3_test_control() interface can be used to +** move the pending byte. +** +** IMPORTANT: Changing the pending byte to any value other than +** 0x40000000 results in an incompatible database file format! +** Changing the pending byte during operation will result in undefined +** and incorrect behavior. +*/ +#ifndef SQLITE_OMIT_WSD +SQLITE_PRIVATE int sqlite3PendingByte = 0x40000000; +#endif + +/* +** Tracing flags set by SQLITE_TESTCTRL_TRACEFLAGS. +*/ +SQLITE_PRIVATE u32 sqlite3TreeTrace = 0; +SQLITE_PRIVATE u32 sqlite3WhereTrace = 0; + +/* #include "opcodes.h" */ +/* +** Properties of opcodes. The OPFLG_INITIALIZER macro is +** created by mkopcodeh.awk during compilation. Data is obtained +** from the comments following the "case OP_xxxx:" statements in +** the vdbe.c file. +*/ +SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[] = OPFLG_INITIALIZER; + +/* +** Name of the default collating sequence +*/ +SQLITE_PRIVATE const char sqlite3StrBINARY[] = "BINARY"; + +/* +** Standard typenames. These names must match the COLTYPE_* definitions. +** Adjust the SQLITE_N_STDTYPE value if adding or removing entries. +** +** sqlite3StdType[] The actual names of the datatypes. +** +** sqlite3StdTypeLen[] The length (in bytes) of each entry +** in sqlite3StdType[]. +** +** sqlite3StdTypeAffinity[] The affinity associated with each entry +** in sqlite3StdType[]. +*/ +SQLITE_PRIVATE const unsigned char sqlite3StdTypeLen[] = { 3, 4, 3, 7, 4, 4 }; +SQLITE_PRIVATE const char sqlite3StdTypeAffinity[] = { + SQLITE_AFF_NUMERIC, + SQLITE_AFF_BLOB, + SQLITE_AFF_INTEGER, + SQLITE_AFF_INTEGER, + SQLITE_AFF_REAL, + SQLITE_AFF_TEXT +}; +SQLITE_PRIVATE const char *sqlite3StdType[] = { + "ANY", + "BLOB", + "INT", + "INTEGER", + "REAL", + "TEXT" +}; + +/************** End of global.c **********************************************/ +/************** Begin file status.c ******************************************/ +/* +** 2008 June 18 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This module implements the sqlite3_status() interface and related +** functionality. +*/ +/* #include "sqliteInt.h" */ +/************** Include vdbeInt.h in the middle of status.c ******************/ +/************** Begin file vdbeInt.h *****************************************/ +/* +** 2003 September 6 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This is the header file for information that is private to the +** VDBE. This information used to all be at the top of the single +** source code file "vdbe.c". When that file became too big (over +** 6000 lines long) it was split up into several smaller files and +** this header information was factored out. +*/ +#ifndef SQLITE_VDBEINT_H +#define SQLITE_VDBEINT_H + +/* +** The maximum number of times that a statement will try to reparse +** itself before giving up and returning SQLITE_SCHEMA. +*/ +#ifndef SQLITE_MAX_SCHEMA_RETRY +# define SQLITE_MAX_SCHEMA_RETRY 50 +#endif + +/* +** VDBE_DISPLAY_P4 is true or false depending on whether or not the +** "explain" P4 display logic is enabled. +*/ +#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \ + || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) \ + || defined(SQLITE_ENABLE_BYTECODE_VTAB) +# define VDBE_DISPLAY_P4 1 +#else +# define VDBE_DISPLAY_P4 0 +#endif + +/* +** SQL is translated into a sequence of instructions to be +** executed by a virtual machine. Each instruction is an instance +** of the following structure. +*/ +typedef struct VdbeOp Op; + +/* +** Boolean values +*/ +typedef unsigned Bool; + +/* Opaque type used by code in vdbesort.c */ +typedef struct VdbeSorter VdbeSorter; + +/* Elements of the linked list at Vdbe.pAuxData */ +typedef struct AuxData AuxData; + +/* A cache of large TEXT or BLOB values in a VdbeCursor */ +typedef struct VdbeTxtBlbCache VdbeTxtBlbCache; + +/* Types of VDBE cursors */ +#define CURTYPE_BTREE 0 +#define CURTYPE_SORTER 1 +#define CURTYPE_VTAB 2 +#define CURTYPE_PSEUDO 3 + +/* +** A VdbeCursor is an superclass (a wrapper) for various cursor objects: +** +** * A b-tree cursor +** - In the main database or in an ephemeral database +** - On either an index or a table +** * A sorter +** * A virtual table +** * A one-row "pseudotable" stored in a single register +*/ +typedef struct VdbeCursor VdbeCursor; +struct VdbeCursor { + u8 eCurType; /* One of the CURTYPE_* values above */ + i8 iDb; /* Index of cursor database in db->aDb[] */ + u8 nullRow; /* True if pointing to a row with no data */ + u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ + u8 isTable; /* True for rowid tables. False for indexes */ +#ifdef SQLITE_DEBUG + u8 seekOp; /* Most recent seek operation on this cursor */ + u8 wrFlag; /* The wrFlag argument to sqlite3BtreeCursor() */ +#endif + Bool isEphemeral:1; /* True for an ephemeral table */ + Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */ + Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */ + Bool noReuse:1; /* OpenEphemeral may not reuse this cursor */ + Bool colCache:1; /* pCache pointer is initialized and non-NULL */ + u16 seekHit; /* See the OP_SeekHit and OP_IfNoHope opcodes */ + union { /* pBtx for isEphermeral. pAltMap otherwise */ + Btree *pBtx; /* Separate file holding temporary table */ + u32 *aAltMap; /* Mapping from table to index column numbers */ + } ub; + i64 seqCount; /* Sequence counter */ + + /* Cached OP_Column parse information is only valid if cacheStatus matches + ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of + ** CACHE_STALE (0) and so setting cacheStatus=CACHE_STALE guarantees that + ** the cache is out of date. */ + u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ + int seekResult; /* Result of previous sqlite3BtreeMoveto() or 0 + ** if there have been no prior seeks on the cursor. */ + /* seekResult does not distinguish between "no seeks have ever occurred + ** on this cursor" and "the most recent seek was an exact match". + ** For CURTYPE_PSEUDO, seekResult is the register holding the record */ + + /* When a new VdbeCursor is allocated, only the fields above are zeroed. + ** The fields that follow are uninitialized, and must be individually + ** initialized prior to first use. */ + VdbeCursor *pAltCursor; /* Associated index cursor from which to read */ + union { + BtCursor *pCursor; /* CURTYPE_BTREE or _PSEUDO. Btree cursor */ + sqlite3_vtab_cursor *pVCur; /* CURTYPE_VTAB. Vtab cursor */ + VdbeSorter *pSorter; /* CURTYPE_SORTER. Sorter object */ + } uc; + KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ + u32 iHdrOffset; /* Offset to next unparsed byte of the header */ + Pgno pgnoRoot; /* Root page of the open btree cursor */ + i16 nField; /* Number of fields in the header */ + u16 nHdrParsed; /* Number of header fields parsed so far */ + i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ + u32 *aOffset; /* Pointer to aType[nField] */ + const u8 *aRow; /* Data for the current row, if all on one page */ + u32 payloadSize; /* Total number of bytes in the record */ + u32 szRow; /* Byte available in aRow */ +#ifdef SQLITE_ENABLE_COLUMN_USED_MASK + u64 maskUsed; /* Mask of columns used by this cursor */ +#endif + VdbeTxtBlbCache *pCache; /* Cache of large TEXT or BLOB values */ + + /* Space is allocated for aType to hold at least 2*nField+1 entries: + ** nField slots for aType[] and nField+1 array slots for aOffset[] */ + u32 aType[FLEXARRAY]; /* Type values record decode. MUST BE LAST */ +}; + +/* +** The size (in bytes) of a VdbeCursor object that has an nField value of N +** or less. The value of SZ_VDBECURSOR(n) is guaranteed to be a multiple +** of 8. +*/ +#define SZ_VDBECURSOR(N) \ + (ROUND8(offsetof(VdbeCursor,aType)) + ((N)+1)*sizeof(u64)) + +/* Return true if P is a null-only cursor +*/ +#define IsNullCursor(P) \ + ((P)->eCurType==CURTYPE_PSEUDO && (P)->nullRow && (P)->seekResult==0) + +/* +** A value for VdbeCursor.cacheStatus that means the cache is always invalid. +*/ +#define CACHE_STALE 0 + +/* +** Large TEXT or BLOB values can be slow to load, so we want to avoid +** loading them more than once. For that reason, large TEXT and BLOB values +** can be stored in a cache defined by this object, and attached to the +** VdbeCursor using the pCache field. +*/ +struct VdbeTxtBlbCache { + char *pCValue; /* A RCStr buffer to hold the value */ + i64 iOffset; /* File offset of the row being cached */ + int iCol; /* Column for which the cache is valid */ + u32 cacheStatus; /* Vdbe.cacheCtr value */ + u32 colCacheCtr; /* Column cache counter */ +}; + +/* +** When a sub-program is executed (OP_Program), a structure of this type +** is allocated to store the current value of the program counter, as +** well as the current memory cell array and various other frame specific +** values stored in the Vdbe struct. When the sub-program is finished, +** these values are copied back to the Vdbe from the VdbeFrame structure, +** restoring the state of the VM to as it was before the sub-program +** began executing. +** +** The memory for a VdbeFrame object is allocated and managed by a memory +** cell in the parent (calling) frame. When the memory cell is deleted or +** overwritten, the VdbeFrame object is not freed immediately. Instead, it +** is linked into the Vdbe.pDelFrame list. The contents of the Vdbe.pDelFrame +** list is deleted when the VM is reset in VdbeHalt(). The reason for doing +** this instead of deleting the VdbeFrame immediately is to avoid recursive +** calls to sqlite3VdbeMemRelease() when the memory cells belonging to the +** child frame are released. +** +** The currently executing frame is stored in Vdbe.pFrame. Vdbe.pFrame is +** set to NULL if the currently executing frame is the main program. +*/ +typedef struct VdbeFrame VdbeFrame; +struct VdbeFrame { + Vdbe *v; /* VM this frame belongs to */ + VdbeFrame *pParent; /* Parent of this frame, or NULL if parent is main */ + Op *aOp; /* Program instructions for parent frame */ + Mem *aMem; /* Array of memory cells for parent frame */ + VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */ + u8 *aOnce; /* Bitmask used by OP_Once */ + void *token; /* Copy of SubProgram.token */ + i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */ + AuxData *pAuxData; /* Linked list of auxdata allocations */ +#if SQLITE_DEBUG + u32 iFrameMagic; /* magic number for sanity checking */ +#endif + int nCursor; /* Number of entries in apCsr */ + int pc; /* Program Counter in parent (calling) frame */ + int nOp; /* Size of aOp array */ + int nMem; /* Number of entries in aMem */ + int nChildMem; /* Number of memory cells for child frame */ + int nChildCsr; /* Number of cursors for child frame */ + i64 nChange; /* Statement changes (Vdbe.nChange) */ + i64 nDbChange; /* Value of db->nChange */ +}; + +/* Magic number for sanity checking on VdbeFrame objects */ +#define SQLITE_FRAME_MAGIC 0x879fb71e + +/* +** Return a pointer to the array of registers allocated for use +** by a VdbeFrame. +*/ +#define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))]) + +/* +** Internally, the vdbe manipulates nearly all SQL values as Mem +** structures. Each Mem struct may cache multiple representations (string, +** integer etc.) of the same value. +*/ +struct sqlite3_value { + union MemValue { + double r; /* Real value used when MEM_Real is set in flags */ + i64 i; /* Integer value used when MEM_Int is set in flags */ + int nZero; /* Extra zero bytes when MEM_Zero and MEM_Blob set */ + const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */ + FuncDef *pDef; /* Used only when flags==MEM_Agg */ + } u; + char *z; /* String or BLOB value */ + int n; /* Number of characters in string value, excluding '\0' */ + u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */ + u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */ + u8 eSubtype; /* Subtype for this value */ + /* ShallowCopy only needs to copy the information above */ + sqlite3 *db; /* The associated database connection */ + int szMalloc; /* Size of the zMalloc allocation */ + u32 uTemp; /* Transient storage for serial_type in OP_MakeRecord */ + char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */ + void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */ +#ifdef SQLITE_DEBUG + Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */ + u16 mScopyFlags; /* flags value immediately after the shallow copy */ + u8 bScopy; /* The pScopyFrom of some other Mem *might* point here */ +#endif +}; + +/* +** Size of struct Mem not including the Mem.zMalloc member or anything that +** follows. +*/ +#define MEMCELLSIZE offsetof(Mem,db) + +/* One or more of the following flags are set to indicate the +** representations of the value stored in the Mem struct. +** +** * MEM_Null An SQL NULL value +** +** * MEM_Null|MEM_Zero An SQL NULL with the virtual table +** UPDATE no-change flag set +** +** * MEM_Null|MEM_Term| An SQL NULL, but also contains a +** MEM_Subtype pointer accessible using +** sqlite3_value_pointer(). +** +** * MEM_Null|MEM_Cleared Special SQL NULL that compares non-equal +** to other NULLs even using the IS operator. +** +** * MEM_Str A string, stored in Mem.z with +** length Mem.n. Zero-terminated if +** MEM_Term is set. This flag is +** incompatible with MEM_Blob and +** MEM_Null, but can appear with MEM_Int, +** MEM_Real, and MEM_IntReal. +** +** * MEM_Blob A blob, stored in Mem.z length Mem.n. +** Incompatible with MEM_Str, MEM_Null, +** MEM_Int, MEM_Real, and MEM_IntReal. +** +** * MEM_Blob|MEM_Zero A blob in Mem.z of length Mem.n plus +** Mem.u.nZero extra 0x00 bytes at the end. +** +** * MEM_Int Integer stored in Mem.u.i. +** +** * MEM_Real Real stored in Mem.u.r. +** +** * MEM_IntReal Real stored as an integer in Mem.u.i. +** +** If the MEM_Null flag is set, then the value is an SQL NULL value. +** For a pointer type created using sqlite3_bind_pointer() or +** sqlite3_result_pointer() the MEM_Term and MEM_Subtype flags are also set. +** +** If the MEM_Str flag is set then Mem.z points at a string representation. +** Usually this is encoded in the same unicode encoding as the main +** database (see below for exceptions). If the MEM_Term flag is also +** set, then the string is nul terminated. The MEM_Int and MEM_Real +** flags may coexist with the MEM_Str flag. +*/ +#define MEM_Undefined 0x0000 /* Value is undefined */ +#define MEM_Null 0x0001 /* Value is NULL (or a pointer) */ +#define MEM_Str 0x0002 /* Value is a string */ +#define MEM_Int 0x0004 /* Value is an integer */ +#define MEM_Real 0x0008 /* Value is a real number */ +#define MEM_Blob 0x0010 /* Value is a BLOB */ +#define MEM_IntReal 0x0020 /* MEM_Int that stringifies like MEM_Real */ +#define MEM_AffMask 0x003f /* Mask of affinity bits */ + +/* Extra bits that modify the meanings of the core datatypes above +*/ +#define MEM_FromBind 0x0040 /* Value originates from sqlite3_bind() */ + /* 0x0080 // Available */ +#define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */ +#define MEM_Term 0x0200 /* String in Mem.z is zero terminated */ +#define MEM_Zero 0x0400 /* Mem.i contains count of 0s appended to blob */ +#define MEM_Subtype 0x0800 /* Mem.eSubtype is valid */ +#define MEM_TypeMask 0x0dbf /* Mask of type bits */ + +/* Bits that determine the storage for Mem.z for a string or blob or +** aggregate accumulator. +*/ +#define MEM_Dyn 0x1000 /* Need to call Mem.xDel() on Mem.z */ +#define MEM_Static 0x2000 /* Mem.z points to a static string */ +#define MEM_Ephem 0x4000 /* Mem.z points to an ephemeral string */ +#define MEM_Agg 0x8000 /* Mem.z points to an agg function context */ + +/* Return TRUE if Mem X contains dynamically allocated content - anything +** that needs to be deallocated to avoid a leak. +*/ +#define VdbeMemDynamic(X) \ + (((X)->flags&(MEM_Agg|MEM_Dyn))!=0) + +/* +** Clear any existing type flags from a Mem and replace them with f +*/ +#define MemSetTypeFlag(p, f) \ + ((p)->flags = ((p)->flags&~(MEM_TypeMask|MEM_Zero))|f) + +/* +** True if Mem X is a NULL-nochng type. +*/ +#define MemNullNochng(X) \ + (((X)->flags&MEM_TypeMask)==(MEM_Null|MEM_Zero) \ + && (X)->n==0 && (X)->u.nZero==0) + +/* +** Return true if a memory cell has been initialized and is valid. +** is for use inside assert() statements only. +** +** A Memory cell is initialized if at least one of the +** MEM_Null, MEM_Str, MEM_Int, MEM_Real, MEM_Blob, or MEM_IntReal bits +** is set. It is "undefined" if all those bits are zero. +*/ +#ifdef SQLITE_DEBUG +#define memIsValid(M) ((M)->flags & MEM_AffMask)!=0 +#endif + +/* +** Each auxiliary data pointer stored by a user defined function +** implementation calling sqlite3_set_auxdata() is stored in an instance +** of this structure. All such structures associated with a single VM +** are stored in a linked list headed at Vdbe.pAuxData. All are destroyed +** when the VM is halted (if not before). +*/ +struct AuxData { + int iAuxOp; /* Instruction number of OP_Function opcode */ + int iAuxArg; /* Index of function argument. */ + void *pAux; /* Aux data pointer */ + void (*xDeleteAux)(void*); /* Destructor for the aux data */ + AuxData *pNextAux; /* Next element in list */ +}; + +/* +** The "context" argument for an installable function. A pointer to an +** instance of this structure is the first argument to the routines used +** implement the SQL functions. +** +** There is a typedef for this structure in sqlite.h. So all routines, +** even the public interface to SQLite, can use a pointer to this structure. +** But this file is the only place where the internal details of this +** structure are known. +** +** This structure is defined inside of vdbeInt.h because it uses substructures +** (Mem) which are only defined there. +*/ +struct sqlite3_context { + Mem *pOut; /* The return value is stored here */ + FuncDef *pFunc; /* Pointer to function information */ + Mem *pMem; /* Memory cell used to store aggregate context */ + Vdbe *pVdbe; /* The VM that owns this context */ + int iOp; /* Instruction number of OP_Function */ + int isError; /* Error code returned by the function. */ + u8 enc; /* Encoding to use for results */ + u8 skipFlag; /* Skip accumulator loading if true */ + u16 argc; /* Number of arguments */ + sqlite3_value *argv[FLEXARRAY]; /* Argument set */ +}; + +/* +** The size (in bytes) of an sqlite3_context object that holds N +** argv[] arguments. +*/ +#define SZ_CONTEXT(N) \ + (offsetof(sqlite3_context,argv)+(N)*sizeof(sqlite3_value*)) + + +/* The ScanStatus object holds a single value for the +** sqlite3_stmt_scanstatus() interface. +** +** aAddrRange[]: +** This array is used by ScanStatus elements associated with EQP +** notes that make an SQLITE_SCANSTAT_NCYCLE value available. It is +** an array of up to 3 ranges of VM addresses for which the Vdbe.anCycle[] +** values should be summed to calculate the NCYCLE value. Each pair of +** integer addresses is a start and end address (both inclusive) for a range +** instructions. A start value of 0 indicates an empty range. +*/ +typedef struct ScanStatus ScanStatus; +struct ScanStatus { + int addrExplain; /* OP_Explain for loop */ + int aAddrRange[6]; + int addrLoop; /* Address of "loops" counter */ + int addrVisit; /* Address of "rows visited" counter */ + int iSelectID; /* The "Select-ID" for this loop */ + LogEst nEst; /* Estimated output rows per loop */ + char *zName; /* Name of table or index */ +}; + +/* The DblquoteStr object holds the text of a double-quoted +** string for a prepared statement. A linked list of these objects +** is constructed during statement parsing and is held on Vdbe.pDblStr. +** When computing a normalized SQL statement for an SQL statement, that +** list is consulted for each double-quoted identifier to see if the +** identifier should really be a string literal. +*/ +typedef struct DblquoteStr DblquoteStr; +struct DblquoteStr { + DblquoteStr *pNextStr; /* Next string literal in the list */ + char z[8]; /* Dequoted value for the string */ +}; + +/* +** An instance of the virtual machine. This structure contains the complete +** state of the virtual machine. +** +** The "sqlite3_stmt" structure pointer that is returned by sqlite3_prepare() +** is really a pointer to an instance of this structure. +*/ +struct Vdbe { + sqlite3 *db; /* The database connection that owns this statement */ + Vdbe **ppVPrev,*pVNext; /* Linked list of VDBEs with the same Vdbe.db */ + Parse *pParse; /* Parsing context used to create this Vdbe */ + ynVar nVar; /* Number of entries in aVar[] */ + int nMem; /* Number of memory locations currently allocated */ + int nCursor; /* Number of slots in apCsr[] */ + u32 cacheCtr; /* VdbeCursor row cache generation counter */ + int pc; /* The program counter */ + int rc; /* Value to return */ + i64 nChange; /* Number of db changes made since last reset */ + int iStatement; /* Statement number (or 0 if has no opened stmt) */ + i64 iCurrentTime; /* Value of julianday('now') for this statement */ + i64 nFkConstraint; /* Number of imm. FK constraints this VM */ + i64 nStmtDefCons; /* Number of def. constraints when stmt started */ + i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */ + Mem *aMem; /* The memory locations */ + Mem **apArg; /* Arguments xUpdate and xFilter vtab methods */ + VdbeCursor **apCsr; /* One element of this array for each open cursor */ + Mem *aVar; /* Values for the OP_Variable opcode. */ + + /* When allocating a new Vdbe object, all of the fields below should be + ** initialized to zero or NULL */ + + Op *aOp; /* Space to hold the virtual machine's program */ + int nOp; /* Number of instructions in the program */ + int nOpAlloc; /* Slots allocated for aOp[] */ + Mem *aColName; /* Column names to return */ + Mem *pResultRow; /* Current output row */ + char *zErrMsg; /* Error message written here */ + VList *pVList; /* Name of variables */ +#ifndef SQLITE_OMIT_TRACE + i64 startTime; /* Time when query started - used for profiling */ +#endif +#ifdef SQLITE_DEBUG + int rcApp; /* errcode set by sqlite3_result_error_code() */ + u32 nWrite; /* Number of write operations that have occurred */ + int napArg; /* Size of the apArg[] array */ +#endif + u16 nResColumn; /* Number of columns in one row of the result set */ + u16 nResAlloc; /* Column slots allocated to aColName[] */ + u8 errorAction; /* Recovery action to do in case of an error */ + u8 minWriteFileFormat; /* Minimum file format for writable database files */ + u8 prepFlags; /* SQLITE_PREPARE_* flags */ + u8 eVdbeState; /* On of the VDBE_*_STATE values */ + bft expired:2; /* 1: recompile VM immediately 2: when convenient */ + bft explain:2; /* 0: normal, 1: EXPLAIN, 2: EXPLAIN QUERY PLAN */ + bft changeCntOn:1; /* True to update the change-counter */ + bft usesStmtJournal:1; /* True if uses a statement journal */ + bft readOnly:1; /* True for statements that do not write */ + bft bIsReader:1; /* True for statements that read */ + bft haveEqpOps:1; /* Bytecode supports EXPLAIN QUERY PLAN */ + yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */ + yDbMask lockMask; /* Subset of btreeMask that requires a lock */ + u32 aCounter[9]; /* Counters used by sqlite3_stmt_status() */ + char *zSql; /* Text of the SQL statement that generated this */ +#ifdef SQLITE_ENABLE_NORMALIZE + char *zNormSql; /* Normalization of the associated SQL statement */ + DblquoteStr *pDblStr; /* List of double-quoted string literals */ +#endif + void *pFree; /* Free this when deleting the vdbe */ + VdbeFrame *pFrame; /* Parent frame */ + VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */ + int nFrame; /* Number of frames in pFrame list */ + u32 expmask; /* Binding to these vars invalidates VM */ + SubProgram *pProgram; /* Linked list of all sub-programs used by VM */ + AuxData *pAuxData; /* Linked list of auxdata allocations */ +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + int nScan; /* Entries in aScan[] */ + ScanStatus *aScan; /* Scan definitions for sqlite3_stmt_scanstatus() */ +#endif +}; + +/* +** The following are allowed values for Vdbe.eVdbeState +*/ +#define VDBE_INIT_STATE 0 /* Prepared statement under construction */ +#define VDBE_READY_STATE 1 /* Ready to run but not yet started */ +#define VDBE_RUN_STATE 2 /* Run in progress */ +#define VDBE_HALT_STATE 3 /* Finished. Need reset() or finalize() */ + +/* +** Structure used to store the context required by the +** sqlite3_preupdate_*() API functions. +*/ +struct PreUpdate { + Vdbe *v; + VdbeCursor *pCsr; /* Cursor to read old values from */ + int op; /* One of SQLITE_INSERT, UPDATE, DELETE */ + u8 *aRecord; /* old.* database record */ + KeyInfo *pKeyinfo; /* Key information */ + UnpackedRecord *pUnpacked; /* Unpacked version of aRecord[] */ + UnpackedRecord *pNewUnpacked; /* Unpacked version of new.* record */ + int iNewReg; /* Register for new.* values */ + int iBlobWrite; /* Value returned by preupdate_blobwrite() */ + i64 iKey1; /* First key value passed to hook */ + i64 iKey2; /* Second key value passed to hook */ + Mem oldipk; /* Memory cell holding "old" IPK value */ + Mem *aNew; /* Array of new.* values */ + Table *pTab; /* Schema object being updated */ + Index *pPk; /* PK index if pTab is WITHOUT ROWID */ + sqlite3_value **apDflt; /* Array of default values, if required */ + struct { + u8 keyinfoSpace[SZ_KEYINFO_0]; /* Space to hold pKeyinfo[0] content */ + } uKey; +}; + +/* +** An instance of this object is used to pass an vector of values into +** OP_VFilter, the xFilter method of a virtual table. The vector is the +** set of values on the right-hand side of an IN constraint. +** +** The value as passed into xFilter is an sqlite3_value with a "pointer" +** type, such as is generated by sqlite3_result_pointer() and read by +** sqlite3_value_pointer. Such values have MEM_Term|MEM_Subtype|MEM_Null +** and a subtype of 'p'. The sqlite3_vtab_in_first() and _next() interfaces +** know how to use this object to step through all the values in the +** right operand of the IN constraint. +*/ +typedef struct ValueList ValueList; +struct ValueList { + BtCursor *pCsr; /* An ephemeral table holding all values */ + sqlite3_value *pOut; /* Register to hold each decoded output value */ +}; + +/* Size of content associated with serial types that fit into a +** single-byte varint. +*/ +#ifndef SQLITE_AMALGAMATION +SQLITE_PRIVATE const u8 sqlite3SmallTypeSizes[]; +#endif + +/* +** Function prototypes +*/ +SQLITE_PRIVATE void sqlite3VdbeError(Vdbe*, const char *, ...); +SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*); +SQLITE_PRIVATE void sqlite3VdbeFreeCursorNN(Vdbe*,VdbeCursor*); +void sqliteVdbePopStack(Vdbe*,int); +SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeHandleMovedCursor(VdbeCursor *p); +SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor*); +SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*); +SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32); +SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8); +#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT +SQLITE_PRIVATE u64 sqlite3FloatSwap(u64 in); +# define swapMixedEndianFloat(X) X = sqlite3FloatSwap(X) +#else +# define swapMixedEndianFloat(X) +#endif +SQLITE_PRIVATE void sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); +SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3*, AuxData**, int, int); + +int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); +SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*); +SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*); +SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*); +#if !defined(SQLITE_OMIT_EXPLAIN) || defined(SQLITE_ENABLE_BYTECODE_VTAB) +SQLITE_PRIVATE int sqlite3VdbeNextOpcode(Vdbe*,Mem*,int,int*,int*,Op**); +SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3*,Op*); +#endif +#if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) +SQLITE_PRIVATE char *sqlite3VdbeDisplayComment(sqlite3*,const Op*,const char*); +#endif +#if !defined(SQLITE_OMIT_EXPLAIN) +SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*); +#endif +SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*); +SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int); +SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem*, const Mem*); +SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int); +SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem*, Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemSetStr(Mem*, const char*, i64, u8, void(*)(void*)); +SQLITE_PRIVATE int sqlite3VdbeMemSetText(Mem*, const char*, i64, void(*)(void*)); +SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem*, i64); +#ifdef SQLITE_OMIT_FLOATING_POINT +# define sqlite3VdbeMemSetDouble sqlite3VdbeMemSetInt64 +#else +SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem*, double); +#endif +SQLITE_PRIVATE void sqlite3VdbeMemSetPointer(Mem*, void*, const char*, void(*)(void*)); +SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16); +SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*); +#ifndef SQLITE_OMIT_INCRBLOB +SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int); +#else +SQLITE_PRIVATE int sqlite3VdbeMemSetZeroBlob(Mem*,int); +#endif +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem*); +#endif +SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemZeroTerminateIfAble(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8); +SQLITE_PRIVATE int sqlite3IntFloatCompare(i64,double); +SQLITE_PRIVATE i64 sqlite3VdbeIntValue(const Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*); +SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*); +SQLITE_PRIVATE int sqlite3MemRealValueRC(Mem*, double*); +SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem*, int ifNull); +SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemCast(Mem*,u8,u8); +SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemFromBtreeZeroOffset(BtCursor*,u32,Mem*); +SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p); +SQLITE_PRIVATE void sqlite3VdbeMemReleaseMalloc(Mem*p); +SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*); +#ifndef SQLITE_OMIT_WINDOWFUNC +SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*); +#endif +#if !defined(SQLITE_OMIT_EXPLAIN) || defined(SQLITE_ENABLE_BYTECODE_VTAB) +SQLITE_PRIVATE const char *sqlite3OpcodeName(int); +#endif +SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); +SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n); +SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int); +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3VdbeFrameIsValid(VdbeFrame*); +#endif +SQLITE_PRIVATE void sqlite3VdbeFrameMemDel(void*); /* Destructor on Mem */ +SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*); /* Actually deletes the Frame */ +SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *); +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( + Vdbe*,VdbeCursor*,int,const char*,Table*,i64,int,int); +#endif +SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p); +SQLITE_PRIVATE int sqlite3VdbeFindIndexKey(BtCursor*, Index*, UnpackedRecord*, int*, int); + +SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, int, VdbeCursor *); +SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *, VdbeSorter *); +SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *); +SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *); +SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *); +SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *, int *); +SQLITE_PRIVATE int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *); +SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *); + +SQLITE_PRIVATE void sqlite3VdbeValueListFree(void*); + +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE void sqlite3VdbeIncrWriteCounter(Vdbe*, VdbeCursor*); +SQLITE_PRIVATE void sqlite3VdbeAssertAbortable(Vdbe*); +#else +# define sqlite3VdbeIncrWriteCounter(V,C) +# define sqlite3VdbeAssertAbortable(V) +#endif + +#if !defined(SQLITE_OMIT_SHARED_CACHE) +SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe*); +#else +# define sqlite3VdbeEnter(X) +#endif + +#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 +SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe*); +#else +# define sqlite3VdbeLeave(X) +#endif + +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe*,Mem*); +SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem*); +#endif + +#ifndef SQLITE_OMIT_FOREIGN_KEY +SQLITE_PRIVATE int sqlite3VdbeCheckFkImmediate(Vdbe*); +SQLITE_PRIVATE int sqlite3VdbeCheckFkDeferred(Vdbe*); +#else +# define sqlite3VdbeCheckFkImmediate(p) 0 +# define sqlite3VdbeCheckFkDeferred(p) 0 +#endif + +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE void sqlite3VdbePrintSql(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, StrAccum *pStr); +#endif +#ifndef SQLITE_OMIT_UTF16 +SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem*, u8); +SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem); +#endif + +#ifndef SQLITE_OMIT_INCRBLOB +SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *); + #define ExpandBlob(P) (((P)->flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(P):0) +#else + #define sqlite3VdbeMemExpandBlob(x) SQLITE_OK + #define ExpandBlob(P) SQLITE_OK +#endif + +#endif /* !defined(SQLITE_VDBEINT_H) */ + +/************** End of vdbeInt.h *********************************************/ +/************** Continuing where we left off in status.c *********************/ + +/* +** Variables in which to record status information. +*/ +#if SQLITE_PTRSIZE>4 +typedef sqlite3_int64 sqlite3StatValueType; +#else +typedef u32 sqlite3StatValueType; +#endif +typedef struct sqlite3StatType sqlite3StatType; +static SQLITE_WSD struct sqlite3StatType { + sqlite3StatValueType nowValue[10]; /* Current value */ + sqlite3StatValueType mxValue[10]; /* Maximum value */ +} sqlite3Stat = { {0,}, {0,} }; + +/* +** Elements of sqlite3Stat[] are protected by either the memory allocator +** mutex, or by the pcache1 mutex. The following array determines which. +*/ +static const char statMutex[] = { + 0, /* SQLITE_STATUS_MEMORY_USED */ + 1, /* SQLITE_STATUS_PAGECACHE_USED */ + 1, /* SQLITE_STATUS_PAGECACHE_OVERFLOW */ + 0, /* SQLITE_STATUS_SCRATCH_USED */ + 0, /* SQLITE_STATUS_SCRATCH_OVERFLOW */ + 0, /* SQLITE_STATUS_MALLOC_SIZE */ + 0, /* SQLITE_STATUS_PARSER_STACK */ + 1, /* SQLITE_STATUS_PAGECACHE_SIZE */ + 0, /* SQLITE_STATUS_SCRATCH_SIZE */ + 0, /* SQLITE_STATUS_MALLOC_COUNT */ +}; + + +/* The "wsdStat" macro will resolve to the status information +** state vector. If writable static data is unsupported on the target, +** we have to locate the state vector at run-time. In the more common +** case where writable static data is supported, wsdStat can refer directly +** to the "sqlite3Stat" state vector declared above. +*/ +#ifdef SQLITE_OMIT_WSD +# define wsdStatInit sqlite3StatType *x = &GLOBAL(sqlite3StatType,sqlite3Stat) +# define wsdStat x[0] +#else +# define wsdStatInit +# define wsdStat sqlite3Stat +#endif + +/* +** Return the current value of a status parameter. The caller must +** be holding the appropriate mutex. +*/ +SQLITE_PRIVATE sqlite3_int64 sqlite3StatusValue(int op){ + wsdStatInit; + assert( op>=0 && op=0 && op=0 && op=0 && opwsdStat.mxValue[op] ){ + wsdStat.mxValue[op] = wsdStat.nowValue[op]; + } +} +SQLITE_PRIVATE void sqlite3StatusDown(int op, int N){ + wsdStatInit; + assert( N>=0 ); + assert( op>=0 && op=0 && op=0 ); + newValue = (sqlite3StatValueType)X; + assert( op>=0 && op=0 && opwsdStat.mxValue[op] ){ + wsdStat.mxValue[op] = newValue; + } +} + +/* +** Query status information. +*/ +SQLITE_API int sqlite3_status64( + int op, + sqlite3_int64 *pCurrent, + sqlite3_int64 *pHighwater, + int resetFlag +){ + sqlite3_mutex *pMutex; + wsdStatInit; + if( op<0 || op>=ArraySize(wsdStat.nowValue) ){ + return SQLITE_MISUSE_BKPT; + } +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT; +#endif + pMutex = statMutex[op] ? sqlite3Pcache1Mutex() : sqlite3MallocMutex(); + sqlite3_mutex_enter(pMutex); + *pCurrent = wsdStat.nowValue[op]; + *pHighwater = wsdStat.mxValue[op]; + if( resetFlag ){ + wsdStat.mxValue[op] = wsdStat.nowValue[op]; + } + sqlite3_mutex_leave(pMutex); + (void)pMutex; /* Prevent warning when SQLITE_THREADSAFE=0 */ + return SQLITE_OK; +} +SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){ + sqlite3_int64 iCur = 0, iHwtr = 0; + int rc; +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT; +#endif + rc = sqlite3_status64(op, &iCur, &iHwtr, resetFlag); + if( rc==0 ){ + *pCurrent = (int)iCur; + *pHighwater = (int)iHwtr; + } + return rc; +} + +/* +** Return the number of LookasideSlot elements on the linked list +*/ +static u32 countLookasideSlots(LookasideSlot *p){ + u32 cnt = 0; + while( p ){ + p = p->pNext; + cnt++; + } + return cnt; +} + +/* +** Count the number of slots of lookaside memory that are outstanding +*/ +SQLITE_PRIVATE int sqlite3LookasideUsed(sqlite3 *db, int *pHighwater){ + u32 nInit = countLookasideSlots(db->lookaside.pInit); + u32 nFree = countLookasideSlots(db->lookaside.pFree); +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + nInit += countLookasideSlots(db->lookaside.pSmallInit); + nFree += countLookasideSlots(db->lookaside.pSmallFree); +#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ + assert( db->lookaside.nSlot >= nInit+nFree ); + if( pHighwater ) *pHighwater = (int)(db->lookaside.nSlot - nInit); + return (int)(db->lookaside.nSlot - (nInit+nFree)); +} + +/* +** Query status information for a single database connection +*/ +SQLITE_API int sqlite3_db_status64( + sqlite3 *db, /* The database connection whose status is desired */ + int op, /* Status verb */ + sqlite3_int64 *pCurrent, /* Write current value here */ + sqlite3_int64 *pHighwtr, /* Write high-water mark here */ + int resetFlag /* Reset high-water mark if true */ +){ + int rc = SQLITE_OK; /* Return code */ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || pCurrent==0|| pHighwtr==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + sqlite3_mutex_enter(db->mutex); + switch( op ){ + case SQLITE_DBSTATUS_LOOKASIDE_USED: { + int H = 0; + *pCurrent = sqlite3LookasideUsed(db, &H); + *pHighwtr = H; + if( resetFlag ){ + LookasideSlot *p = db->lookaside.pFree; + if( p ){ + while( p->pNext ) p = p->pNext; + p->pNext = db->lookaside.pInit; + db->lookaside.pInit = db->lookaside.pFree; + db->lookaside.pFree = 0; + } +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + p = db->lookaside.pSmallFree; + if( p ){ + while( p->pNext ) p = p->pNext; + p->pNext = db->lookaside.pSmallInit; + db->lookaside.pSmallInit = db->lookaside.pSmallFree; + db->lookaside.pSmallFree = 0; + } +#endif + } + break; + } + + case SQLITE_DBSTATUS_LOOKASIDE_HIT: + case SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE: + case SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL: { + testcase( op==SQLITE_DBSTATUS_LOOKASIDE_HIT ); + testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE ); + testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL ); + assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)>=0 ); + assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)<3 ); + *pCurrent = 0; + *pHighwtr = db->lookaside.anStat[op-SQLITE_DBSTATUS_LOOKASIDE_HIT]; + if( resetFlag ){ + db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT] = 0; + } + break; + } + + /* + ** Return an approximation for the amount of memory currently used + ** by all pagers associated with the given database connection. The + ** highwater mark is meaningless and is returned as zero. + */ + case SQLITE_DBSTATUS_CACHE_USED_SHARED: + case SQLITE_DBSTATUS_CACHE_USED: { + sqlite3_int64 totalUsed = 0; + int i; + sqlite3BtreeEnterAll(db); + for(i=0; inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + Pager *pPager = sqlite3BtreePager(pBt); + int nByte = sqlite3PagerMemUsed(pPager); + if( op==SQLITE_DBSTATUS_CACHE_USED_SHARED ){ + nByte = nByte / sqlite3BtreeConnectionCount(pBt); + } + totalUsed += nByte; + } + } + sqlite3BtreeLeaveAll(db); + *pCurrent = totalUsed; + *pHighwtr = 0; + break; + } + + /* + ** *pCurrent gets an accurate estimate of the amount of memory used + ** to store the schema for all databases (main, temp, and any ATTACHed + ** databases. *pHighwtr is set to zero. + */ + case SQLITE_DBSTATUS_SCHEMA_USED: { + int i; /* Used to iterate through schemas */ + int nByte = 0; /* Used to accumulate return value */ + + sqlite3BtreeEnterAll(db); + db->pnBytesFreed = &nByte; + assert( db->lookaside.pEnd==db->lookaside.pTrueEnd ); + db->lookaside.pEnd = db->lookaside.pStart; + for(i=0; inDb; i++){ + Schema *pSchema = db->aDb[i].pSchema; + if( ALWAYS(pSchema!=0) ){ + HashElem *p; + + nByte += sqlite3GlobalConfig.m.xRoundup(sizeof(HashElem)) * ( + pSchema->tblHash.count + + pSchema->trigHash.count + + pSchema->idxHash.count + + pSchema->fkeyHash.count + ); + nByte += sqlite3_msize(pSchema->tblHash.ht); + nByte += sqlite3_msize(pSchema->trigHash.ht); + nByte += sqlite3_msize(pSchema->idxHash.ht); + nByte += sqlite3_msize(pSchema->fkeyHash.ht); + + for(p=sqliteHashFirst(&pSchema->trigHash); p; p=sqliteHashNext(p)){ + sqlite3DeleteTrigger(db, (Trigger*)sqliteHashData(p)); + } + for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){ + sqlite3DeleteTable(db, (Table *)sqliteHashData(p)); + } + } + } + db->pnBytesFreed = 0; + db->lookaside.pEnd = db->lookaside.pTrueEnd; + sqlite3BtreeLeaveAll(db); + + *pHighwtr = 0; + *pCurrent = nByte; + break; + } + + /* + ** *pCurrent gets an accurate estimate of the amount of memory used + ** to store all prepared statements. + ** *pHighwtr is set to zero. + */ + case SQLITE_DBSTATUS_STMT_USED: { + struct Vdbe *pVdbe; /* Used to iterate through VMs */ + int nByte = 0; /* Used to accumulate return value */ + + db->pnBytesFreed = &nByte; + assert( db->lookaside.pEnd==db->lookaside.pTrueEnd ); + db->lookaside.pEnd = db->lookaside.pStart; + for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pVNext){ + sqlite3VdbeDelete(pVdbe); + } + db->lookaside.pEnd = db->lookaside.pTrueEnd; + db->pnBytesFreed = 0; + + *pHighwtr = 0; /* IMP: R-64479-57858 */ + *pCurrent = nByte; + + break; + } + + /* + ** Set *pCurrent to the total cache hits or misses encountered by all + ** pagers the database handle is connected to. *pHighwtr is always set + ** to zero. + */ + case SQLITE_DBSTATUS_CACHE_SPILL: + op = SQLITE_DBSTATUS_CACHE_WRITE+1; + /* no break */ deliberate_fall_through + case SQLITE_DBSTATUS_CACHE_HIT: + case SQLITE_DBSTATUS_CACHE_MISS: + case SQLITE_DBSTATUS_CACHE_WRITE:{ + int i; + u64 nRet = 0; + assert( SQLITE_DBSTATUS_CACHE_MISS==SQLITE_DBSTATUS_CACHE_HIT+1 ); + assert( SQLITE_DBSTATUS_CACHE_WRITE==SQLITE_DBSTATUS_CACHE_HIT+2 ); + + for(i=0; inDb; i++){ + if( db->aDb[i].pBt ){ + Pager *pPager = sqlite3BtreePager(db->aDb[i].pBt); + sqlite3PagerCacheStat(pPager, op, resetFlag, &nRet); + } + } + *pHighwtr = 0; /* IMP: R-42420-56072 */ + /* IMP: R-54100-20147 */ + /* IMP: R-29431-39229 */ + *pCurrent = nRet; + break; + } + + /* Set *pCurrent to the number of bytes that the db database connection + ** has spilled to the filesystem in temporary files that could have been + ** stored in memory, had sufficient memory been available. + ** The *pHighwater is always set to zero. + */ + case SQLITE_DBSTATUS_TEMPBUF_SPILL: { + u64 nRet = 0; + if( db->aDb[1].pBt ){ + Pager *pPager = sqlite3BtreePager(db->aDb[1].pBt); + sqlite3PagerCacheStat(pPager, SQLITE_DBSTATUS_CACHE_WRITE, + resetFlag, &nRet); + nRet *= sqlite3BtreeGetPageSize(db->aDb[1].pBt); + } + nRet += db->nSpill; + if( resetFlag ) db->nSpill = 0; + *pHighwtr = 0; + *pCurrent = nRet; + break; + } + + /* Set *pCurrent to non-zero if there are unresolved deferred foreign + ** key constraints. Set *pCurrent to zero if all foreign key constraints + ** have been satisfied. The *pHighwtr is always set to zero. + */ + case SQLITE_DBSTATUS_DEFERRED_FKS: { + *pHighwtr = 0; /* IMP: R-11967-56545 */ + *pCurrent = db->nDeferredImmCons>0 || db->nDeferredCons>0; + break; + } + + default: { + rc = SQLITE_ERROR; + } + } + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** 32-bit variant of sqlite3_db_status64() +*/ +SQLITE_API int sqlite3_db_status( + sqlite3 *db, /* The database connection whose status is desired */ + int op, /* Status verb */ + int *pCurrent, /* Write current value here */ + int *pHighwtr, /* Write high-water mark here */ + int resetFlag /* Reset high-water mark if true */ +){ + sqlite3_int64 C = 0, H = 0; + int rc; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || pCurrent==0|| pHighwtr==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + rc = sqlite3_db_status64(db, op, &C, &H, resetFlag); + if( rc==0 ){ + *pCurrent = C & 0x7fffffff; + *pHighwtr = H & 0x7fffffff; + } + return rc; +} + +/************** End of status.c **********************************************/ +/************** Begin file date.c ********************************************/ +/* +** 2003 October 31 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains the C functions that implement date and time +** functions for SQLite. +** +** There is only one exported symbol in this file - the function +** sqlite3RegisterDateTimeFunctions() found at the bottom of the file. +** All other code has file scope. +** +** SQLite processes all times and dates as julian day numbers. The +** dates and times are stored as the number of days since noon +** in Greenwich on November 24, 4714 B.C. according to the Gregorian +** calendar system. +** +** 1970-01-01 00:00:00 is JD 2440587.5 +** 2000-01-01 00:00:00 is JD 2451544.5 +** +** This implementation requires years to be expressed as a 4-digit number +** which means that only dates between 0000-01-01 and 9999-12-31 can +** be represented, even though julian day numbers allow a much wider +** range of dates. +** +** The Gregorian calendar system is used for all dates and times, +** even those that predate the Gregorian calendar. Historians usually +** use the julian calendar for dates prior to 1582-10-15 and for some +** dates afterwards, depending on locale. Beware of this difference. +** +** The conversion algorithms are implemented based on descriptions +** in the following text: +** +** Jean Meeus +** Astronomical Algorithms, 2nd Edition, 1998 +** ISBN 0-943396-61-1 +** Willmann-Bell, Inc +** Richmond, Virginia (USA) +*/ +/* #include "sqliteInt.h" */ +/* #include */ +/* #include */ +#include + +#ifndef SQLITE_OMIT_DATETIME_FUNCS + +/* +** The MSVC CRT on Windows CE may not have a localtime() function. +** So declare a substitute. The substitute function itself is +** defined in "os_win.c". +*/ +#if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \ + (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API) +struct tm *__cdecl localtime(const time_t *); +#endif + +/* +** A structure for holding a single date and time. +*/ +typedef struct DateTime DateTime; +struct DateTime { + sqlite3_int64 iJD; /* The julian day number times 86400000 */ + int Y, M, D; /* Year, month, and day */ + int h, m; /* Hour and minutes */ + int tz; /* Timezone offset in minutes */ + double s; /* Seconds */ + char validJD; /* True (1) if iJD is valid */ + char validYMD; /* True (1) if Y,M,D are valid */ + char validHMS; /* True (1) if h,m,s are valid */ + char nFloor; /* Days to implement "floor" */ + unsigned rawS : 1; /* Raw numeric value stored in s */ + unsigned isError : 1; /* An overflow has occurred */ + unsigned useSubsec : 1; /* Display subsecond precision */ + unsigned isUtc : 1; /* Time is known to be UTC */ + unsigned isLocal : 1; /* Time is known to be localtime */ +}; + + +/* +** Convert zDate into one or more integers according to the conversion +** specifier zFormat. +** +** zFormat[] contains 4 characters for each integer converted, except for +** the last integer which is specified by three characters. The meaning +** of a four-character format specifiers ABCD is: +** +** A: number of digits to convert. Always "2" or "4". +** B: minimum value. Always "0" or "1". +** C: maximum value, decoded as: +** a: 12 +** b: 14 +** c: 24 +** d: 31 +** e: 59 +** f: 9999 +** D: the separator character, or \000 to indicate this is the +** last number to convert. +** +** Example: To translate an ISO-8601 date YYYY-MM-DD, the format would +** be "40f-21a-20c". The "40f-" indicates the 4-digit year followed by "-". +** The "21a-" indicates the 2-digit month followed by "-". The "20c" indicates +** the 2-digit day which is the last integer in the set. +** +** The function returns the number of successful conversions. +*/ +static int getDigits(const char *zDate, const char *zFormat, ...){ + /* The aMx[] array translates the 3rd character of each format + ** spec into a max size: a b c d e f */ + static const u16 aMx[] = { 12, 14, 24, 31, 59, 14712 }; + va_list ap; + int cnt = 0; + char nextC; + va_start(ap, zFormat); + do{ + char N = zFormat[0] - '0'; + char min = zFormat[1] - '0'; + int val = 0; + u16 max; + + assert( zFormat[2]>='a' && zFormat[2]<='f' ); + max = aMx[zFormat[2] - 'a']; + nextC = zFormat[3]; + val = 0; + while( N-- ){ + if( !sqlite3Isdigit(*zDate) ){ + goto end_getDigits; + } + val = val*10 + *zDate - '0'; + zDate++; + } + if( val<(int)min || val>(int)max || (nextC!=0 && nextC!=*zDate) ){ + goto end_getDigits; + } + *va_arg(ap,int*) = val; + zDate++; + cnt++; + zFormat += 4; + }while( nextC ); +end_getDigits: + va_end(ap); + return cnt; +} + +/* +** Parse a timezone extension on the end of a date-time. +** The extension is of the form: +** +** (+/-)HH:MM +** +** Or the "zulu" notation: +** +** Z +** +** If the parse is successful, write the number of minutes +** of change in p->tz and return 0. If a parser error occurs, +** return non-zero. +** +** A missing specifier is not considered an error. +*/ +static int parseTimezone(const char *zDate, DateTime *p){ + int sgn = 0; + int nHr, nMn; + int c; + while( sqlite3Isspace(*zDate) ){ zDate++; } + p->tz = 0; + c = *zDate; + if( c=='-' ){ + sgn = -1; + }else if( c=='+' ){ + sgn = +1; + }else if( c=='Z' || c=='z' ){ + zDate++; + p->isLocal = 0; + p->isUtc = 1; + goto zulu_time; + }else{ + return c!=0; + } + zDate++; + if( getDigits(zDate, "20b:20e", &nHr, &nMn)!=2 ){ + return 1; + } + zDate += 5; + p->tz = sgn*(nMn + nHr*60); + if( p->tz==0 ){ /* Forum post 2025-09-17T10:12:14z */ + p->isLocal = 0; + p->isUtc = 1; + } +zulu_time: + while( sqlite3Isspace(*zDate) ){ zDate++; } + return *zDate!=0; +} + +/* +** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF. +** The HH, MM, and SS must each be exactly 2 digits. The +** fractional seconds FFFF can be one or more digits. +** +** Return 1 if there is a parsing error and 0 on success. +*/ +static int parseHhMmSs(const char *zDate, DateTime *p){ + int h, m, s; + double ms = 0.0; + if( getDigits(zDate, "20c:20e", &h, &m)!=2 ){ + return 1; + } + zDate += 5; + if( *zDate==':' ){ + zDate++; + if( getDigits(zDate, "20e", &s)!=1 ){ + return 1; + } + zDate += 2; + if( *zDate=='.' && sqlite3Isdigit(zDate[1]) ){ + double rScale = 1.0; + zDate++; + while( sqlite3Isdigit(*zDate) ){ + ms = ms*10.0 + *zDate - '0'; + rScale *= 10.0; + zDate++; + } + ms /= rScale; + /* Truncate to avoid problems with sub-milliseconds + ** rounding. https://sqlite.org/forum/forumpost/766a2c9231 */ + if( ms>0.999 ) ms = 0.999; + } + }else{ + s = 0; + } + p->validJD = 0; + p->rawS = 0; + p->validHMS = 1; + p->h = h; + p->m = m; + p->s = s + ms; + if( parseTimezone(zDate, p) ) return 1; + return 0; +} + +/* +** Put the DateTime object into its error state. +*/ +static void datetimeError(DateTime *p){ + memset(p, 0, sizeof(*p)); + p->isError = 1; +} + +/* +** Convert from YYYY-MM-DD HH:MM:SS to julian day. We always assume +** that the YYYY-MM-DD is according to the Gregorian calendar. +** +** Reference: Meeus page 61 +*/ +static void computeJD(DateTime *p){ + int Y, M, D, A, B, X1, X2; + + if( p->validJD ) return; + if( p->validYMD ){ + Y = p->Y; + M = p->M; + D = p->D; + }else{ + Y = 2000; /* If no YMD specified, assume 2000-Jan-01 */ + M = 1; + D = 1; + } + if( Y<-4713 || Y>9999 || p->rawS ){ + datetimeError(p); + return; + } + if( M<=2 ){ + Y--; + M += 12; + } + A = (Y+4800)/100; + B = 38 - A + (A/4); + X1 = 36525*(Y+4716)/100; + X2 = 306001*(M+1)/10000; + p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000); + p->validJD = 1; + if( p->validHMS ){ + p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000 + 0.5); + if( p->tz ){ + p->iJD -= p->tz*60000; + p->validYMD = 0; + p->validHMS = 0; + p->tz = 0; + p->isUtc = 1; + p->isLocal = 0; + } + } +} + +/* +** Given the YYYY-MM-DD information current in p, determine if there +** is day-of-month overflow and set nFloor to the number of days that +** would need to be subtracted from the date in order to bring the +** date back to the end of the month. +*/ +static void computeFloor(DateTime *p){ + assert( p->validYMD || p->isError ); + assert( p->D>=0 && p->D<=31 ); + assert( p->M>=0 && p->M<=12 ); + if( p->D<=28 ){ + p->nFloor = 0; + }else if( (1<M) & 0x15aa ){ + p->nFloor = 0; + }else if( p->M!=2 ){ + p->nFloor = (p->D==31); + }else if( p->Y%4!=0 || (p->Y%100==0 && p->Y%400!=0) ){ + p->nFloor = p->D - 28; + }else{ + p->nFloor = p->D - 29; + } +} + +/* +** Parse dates of the form +** +** YYYY-MM-DD HH:MM:SS.FFF +** YYYY-MM-DD HH:MM:SS +** YYYY-MM-DD HH:MM +** YYYY-MM-DD +** +** Write the result into the DateTime structure and return 0 +** on success and 1 if the input string is not a well-formed +** date. +*/ +static int parseYyyyMmDd(const char *zDate, DateTime *p){ + int Y, M, D, neg; + + if( zDate[0]=='-' ){ + zDate++; + neg = 1; + }else{ + neg = 0; + } + if( getDigits(zDate, "40f-21a-21d", &Y, &M, &D)!=3 ){ + return 1; + } + zDate += 10; + while( sqlite3Isspace(*zDate) || 'T'==*(u8*)zDate ){ zDate++; } + if( parseHhMmSs(zDate, p)==0 ){ + /* We got the time */ + }else if( *zDate==0 ){ + p->validHMS = 0; + }else{ + return 1; + } + p->validJD = 0; + p->validYMD = 1; + p->Y = neg ? -Y : Y; + p->M = M; + p->D = D; + computeFloor(p); + if( p->tz ){ + computeJD(p); + } + return 0; +} + + +static void clearYMD_HMS_TZ(DateTime *p); /* Forward declaration */ + +/* +** Set the time to the current time reported by the VFS. +** +** Return the number of errors. +*/ +static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){ + p->iJD = sqlite3StmtCurrentTime(context); + if( p->iJD>0 ){ + p->validJD = 1; + p->isUtc = 1; + p->isLocal = 0; + clearYMD_HMS_TZ(p); + return 0; + }else{ + return 1; + } +} + +/* +** Input "r" is a numeric quantity which might be a julian day number, +** or the number of seconds since 1970. If the value if r is within +** range of a julian day number, install it as such and set validJD. +** If the value is a valid unix timestamp, put it in p->s and set p->rawS. +*/ +static void setRawDateNumber(DateTime *p, double r){ + p->s = r; + p->rawS = 1; + if( r>=0.0 && r<5373484.5 ){ + p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5); + p->validJD = 1; + } +} + +/* +** Attempt to parse the given string into a julian day number. Return +** the number of errors. +** +** The following are acceptable forms for the input string: +** +** YYYY-MM-DD HH:MM:SS.FFF +/-HH:MM +** DDDD.DD +** now +** +** In the first form, the +/-HH:MM is always optional. The fractional +** seconds extension (the ".FFF") is optional. The seconds portion +** (":SS.FFF") is option. The year and date can be omitted as long +** as there is a time string. The time string can be omitted as long +** as there is a year and date. +*/ +static int parseDateOrTime( + sqlite3_context *context, + const char *zDate, + DateTime *p +){ + double r; + if( parseYyyyMmDd(zDate,p)==0 ){ + return 0; + }else if( parseHhMmSs(zDate, p)==0 ){ + return 0; + }else if( sqlite3StrICmp(zDate,"now")==0 && sqlite3NotPureFunc(context) ){ + return setDateTimeToCurrent(context, p); + }else if( sqlite3AtoF(zDate, &r)>0 ){ + setRawDateNumber(p, r); + return 0; + }else if( (sqlite3StrICmp(zDate,"subsec")==0 + || sqlite3StrICmp(zDate,"subsecond")==0) + && sqlite3NotPureFunc(context) ){ + p->useSubsec = 1; + return setDateTimeToCurrent(context, p); + } + return 1; +} + +/* The julian day number for 9999-12-31 23:59:59.999 is 5373484.4999999. +** Multiplying this by 86400000 gives 464269060799999 as the maximum value +** for DateTime.iJD. +** +** But some older compilers (ex: gcc 4.2.1 on older Macs) cannot deal with +** such a large integer literal, so we have to encode it. +*/ +#define INT_464269060799999 ((((i64)0x1a640)<<32)|0x1072fdff) + +/* +** Return TRUE if the given julian day number is within range. +** +** The input is the JulianDay times 86400000. +*/ +static int validJulianDay(sqlite3_int64 iJD){ + return iJD>=0 && iJD<=INT_464269060799999; +} + +/* +** Compute the Year, Month, and Day from the julian day number. +*/ +static void computeYMD(DateTime *p){ + int Z, alpha, A, B, C, D, E, X1; + if( p->validYMD ) return; + if( !p->validJD ){ + p->Y = 2000; + p->M = 1; + p->D = 1; + }else if( !validJulianDay(p->iJD) ){ + datetimeError(p); + return; + }else{ + Z = (int)((p->iJD + 43200000)/86400000); + alpha = (int)((Z + 32044.75)/36524.25) - 52; + A = Z + 1 + alpha - ((alpha+100)/4) + 25; + B = A + 1524; + C = (int)((B - 122.1)/365.25); + D = (36525*(C&32767))/100; + E = (int)((B-D)/30.6001); + X1 = (int)(30.6001*E); + p->D = B - D - X1; + p->M = E<14 ? E-1 : E-13; + p->Y = p->M>2 ? C - 4716 : C - 4715; + } + p->validYMD = 1; +} + +/* +** Compute the Hour, Minute, and Seconds from the julian day number. +*/ +static void computeHMS(DateTime *p){ + int day_ms, day_min; /* milliseconds, minutes into the day */ + if( p->validHMS ) return; + computeJD(p); + day_ms = (int)((p->iJD + 43200000) % 86400000); + p->s = (day_ms % 60000)/1000.0; + day_min = day_ms/60000; + p->m = day_min % 60; + p->h = day_min / 60; + p->rawS = 0; + p->validHMS = 1; +} + +/* +** Compute both YMD and HMS +*/ +static void computeYMD_HMS(DateTime *p){ + computeYMD(p); + computeHMS(p); +} + +/* +** Clear the YMD and HMS and the TZ +*/ +static void clearYMD_HMS_TZ(DateTime *p){ + p->validYMD = 0; + p->validHMS = 0; + p->tz = 0; +} + +#ifndef SQLITE_OMIT_LOCALTIME +/* +** On recent Windows platforms, the localtime_s() function is available +** as part of the "Secure CRT". It is essentially equivalent to +** localtime_r() available under most POSIX platforms, except that the +** order of the parameters is reversed. +** +** See http://msdn.microsoft.com/en-us/library/a442x3ye(VS.80).aspx. +** +** If the user has not indicated to use localtime_r() or localtime_s() +** already, check for an MSVC build environment that provides +** localtime_s(). +*/ +#if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S \ + && defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE) +#undef HAVE_LOCALTIME_S +#define HAVE_LOCALTIME_S 1 +#endif + +/* +** The following routine implements the rough equivalent of localtime_r() +** using whatever operating-system specific localtime facility that +** is available. This routine returns 0 on success and +** non-zero on any kind of error. +** +** If the sqlite3GlobalConfig.bLocaltimeFault variable is non-zero then this +** routine will always fail. If bLocaltimeFault is nonzero and +** sqlite3GlobalConfig.xAltLocaltime is not NULL, then xAltLocaltime() is +** invoked in place of the OS-defined localtime() function. +** +** EVIDENCE-OF: R-62172-00036 In this implementation, the standard C +** library function localtime_r() is used to assist in the calculation of +** local time. +*/ +static int osLocaltime(time_t *t, struct tm *pTm){ + int rc; +#if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S + struct tm *pX; +#if SQLITE_THREADSAFE>0 + sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); +#endif + sqlite3_mutex_enter(mutex); + pX = localtime(t); +#ifndef SQLITE_UNTESTABLE + if( sqlite3GlobalConfig.bLocaltimeFault ){ + if( sqlite3GlobalConfig.xAltLocaltime!=0 + && 0==sqlite3GlobalConfig.xAltLocaltime((const void*)t,(void*)pTm) + ){ + pX = pTm; + }else{ + pX = 0; + } + } +#endif + if( pX ) *pTm = *pX; +#if SQLITE_THREADSAFE>0 + sqlite3_mutex_leave(mutex); +#endif + rc = pX==0; +#else +#ifndef SQLITE_UNTESTABLE + if( sqlite3GlobalConfig.bLocaltimeFault ){ + if( sqlite3GlobalConfig.xAltLocaltime!=0 ){ + return sqlite3GlobalConfig.xAltLocaltime((const void*)t,(void*)pTm); + }else{ + return 1; + } + } +#endif +#if HAVE_LOCALTIME_R + rc = localtime_r(t, pTm)==0; +#else + rc = localtime_s(pTm, t); +#endif /* HAVE_LOCALTIME_R */ +#endif /* HAVE_LOCALTIME_R || HAVE_LOCALTIME_S */ + return rc; +} +#endif /* SQLITE_OMIT_LOCALTIME */ + + +#ifndef SQLITE_OMIT_LOCALTIME +/* +** Assuming the input DateTime is UTC, move it to its localtime equivalent. +*/ +static int toLocaltime( + DateTime *p, /* Date at which to calculate offset */ + sqlite3_context *pCtx /* Write error here if one occurs */ +){ + time_t t; + struct tm sLocal; + int iYearDiff; + + /* Initialize the contents of sLocal to avoid a compiler warning. */ + memset(&sLocal, 0, sizeof(sLocal)); + + computeJD(p); + if( p->iJD<2108667600*(i64)100000 /* 1970-01-01 */ + || p->iJD>2130141456*(i64)100000 /* 2038-01-18 */ + ){ + /* EVIDENCE-OF: R-55269-29598 The localtime_r() C function normally only + ** works for years between 1970 and 2037. For dates outside this range, + ** SQLite attempts to map the year into an equivalent year within this + ** range, do the calculation, then map the year back. + */ + DateTime x = *p; + computeYMD_HMS(&x); + iYearDiff = (2000 + x.Y%4) - x.Y; + x.Y += iYearDiff; + x.validJD = 0; + computeJD(&x); + t = (time_t)(x.iJD/1000 - 21086676*(i64)10000); + }else{ + iYearDiff = 0; + t = (time_t)(p->iJD/1000 - 21086676*(i64)10000); + } + if( osLocaltime(&t, &sLocal) ){ + sqlite3_result_error(pCtx, "local time unavailable", -1); + return SQLITE_ERROR; + } + p->Y = sLocal.tm_year + 1900 - iYearDiff; + p->M = sLocal.tm_mon + 1; + p->D = sLocal.tm_mday; + p->h = sLocal.tm_hour; + p->m = sLocal.tm_min; + p->s = sLocal.tm_sec + (p->iJD%1000)*0.001; + p->validYMD = 1; + p->validHMS = 1; + p->validJD = 0; + p->rawS = 0; + p->tz = 0; + p->isError = 0; + return SQLITE_OK; +} +#endif /* SQLITE_OMIT_LOCALTIME */ + +/* +** The following table defines various date transformations of the form +** +** 'NNN days' +** +** Where NNN is an arbitrary floating-point number and "days" can be one +** of several units of time. +*/ +static const struct { + u8 nName; /* Length of the name */ + char zName[7]; /* Name of the transformation */ + float rLimit; /* Maximum NNN value for this transform */ + float rXform; /* Constant used for this transform */ +} aXformType[] = { + /* 0 */ { 6, "second", 4.6427e+14, 1.0 }, + /* 1 */ { 6, "minute", 7.7379e+12, 60.0 }, + /* 2 */ { 4, "hour", 1.2897e+11, 3600.0 }, + /* 3 */ { 3, "day", 5373485.0, 86400.0 }, + /* 4 */ { 5, "month", 176546.0, 2592000.0 }, + /* 5 */ { 4, "year", 14713.0, 31536000.0 }, +}; + +/* +** If the DateTime p is raw number, try to figure out if it is +** a julian day number of a unix timestamp. Set the p value +** appropriately. +*/ +static void autoAdjustDate(DateTime *p){ + if( !p->rawS || p->validJD ){ + p->rawS = 0; + }else if( p->s>=-21086676*(i64)10000 /* -4713-11-24 12:00:00 */ + && p->s<=(25340230*(i64)10000)+799 /* 9999-12-31 23:59:59 */ + ){ + double r = p->s*1000.0 + 210866760000000.0; + clearYMD_HMS_TZ(p); + p->iJD = (sqlite3_int64)(r + 0.5); + p->validJD = 1; + p->rawS = 0; + } +} + +/* +** Process a modifier to a date-time stamp. The modifiers are +** as follows: +** +** NNN days +** NNN hours +** NNN minutes +** NNN.NNNN seconds +** NNN months +** NNN years +** +/-YYYY-MM-DD HH:MM:SS.SSS +** ceiling +** floor +** start of month +** start of year +** start of week +** start of day +** weekday N +** unixepoch +** auto +** localtime +** utc +** subsec +** subsecond +** +** Return 0 on success and 1 if there is any kind of error. If the error +** is in a system call (i.e. localtime()), then an error message is written +** to context pCtx. If the error is an unrecognized modifier, no error is +** written to pCtx. +*/ +static int parseModifier( + sqlite3_context *pCtx, /* Function context */ + const char *z, /* The text of the modifier */ + int n, /* Length of zMod in bytes */ + DateTime *p, /* The date/time value to be modified */ + int idx /* Parameter index of the modifier */ +){ + int rc = 1; + double r; + switch(sqlite3UpperToLower[(u8)z[0]] ){ + case 'a': { + /* + ** auto + ** + ** If rawS is available, then interpret as a julian day number, or + ** a unix timestamp, depending on its magnitude. + */ + if( sqlite3_stricmp(z, "auto")==0 ){ + if( idx>1 ) return 1; /* IMP: R-33611-57934 */ + autoAdjustDate(p); + rc = 0; + } + break; + } + case 'c': { + /* + ** ceiling + ** + ** Resolve day-of-month overflow by rolling forward into the next + ** month. As this is the default action, this modifier is really + ** a no-op that is only included for symmetry. See "floor". + */ + if( sqlite3_stricmp(z, "ceiling")==0 ){ + computeJD(p); + clearYMD_HMS_TZ(p); + rc = 0; + p->nFloor = 0; + } + break; + } + case 'f': { + /* + ** floor + ** + ** Resolve day-of-month overflow by rolling back to the end of the + ** previous month. + */ + if( sqlite3_stricmp(z, "floor")==0 ){ + computeJD(p); + p->iJD -= p->nFloor*86400000; + clearYMD_HMS_TZ(p); + rc = 0; + } + break; + } + case 'j': { + /* + ** julianday + ** + ** Always interpret the prior number as a julian-day value. If this + ** is not the first modifier, or if the prior argument is not a numeric + ** value in the allowed range of julian day numbers understood by + ** SQLite (0..5373484.5) then the result will be NULL. + */ + if( sqlite3_stricmp(z, "julianday")==0 ){ + if( idx>1 ) return 1; /* IMP: R-31176-64601 */ + if( p->validJD && p->rawS ){ + rc = 0; + p->rawS = 0; + } + } + break; + } +#ifndef SQLITE_OMIT_LOCALTIME + case 'l': { + /* localtime + ** + ** Assuming the current time value is UTC (a.k.a. GMT), shift it to + ** show local time. + */ + if( sqlite3_stricmp(z, "localtime")==0 && sqlite3NotPureFunc(pCtx) ){ + rc = p->isLocal ? SQLITE_OK : toLocaltime(p, pCtx); + p->isUtc = 0; + p->isLocal = 1; + } + break; + } +#endif + case 'u': { + /* + ** unixepoch + ** + ** Treat the current value of p->s as the number of + ** seconds since 1970. Convert to a real julian day number. + */ + if( sqlite3_stricmp(z, "unixepoch")==0 && p->rawS ){ + if( idx>1 ) return 1; /* IMP: R-49255-55373 */ + r = p->s*1000.0 + 210866760000000.0; + if( r>=0.0 && r<464269060800000.0 ){ + clearYMD_HMS_TZ(p); + p->iJD = (sqlite3_int64)(r + 0.5); + p->validJD = 1; + p->rawS = 0; + rc = 0; + } + } +#ifndef SQLITE_OMIT_LOCALTIME + else if( sqlite3_stricmp(z, "utc")==0 && sqlite3NotPureFunc(pCtx) ){ + if( p->isUtc==0 ){ + i64 iOrigJD; /* Original localtime */ + i64 iGuess; /* Guess at the corresponding utc time */ + int cnt = 0; /* Safety to prevent infinite loop */ + i64 iErr; /* Guess is off by this much */ + + computeJD(p); + iGuess = iOrigJD = p->iJD; + iErr = 0; + do{ + DateTime new; + memset(&new, 0, sizeof(new)); + iGuess -= iErr; + new.iJD = iGuess; + new.validJD = 1; + rc = toLocaltime(&new, pCtx); + if( rc ) return rc; + computeJD(&new); + iErr = new.iJD - iOrigJD; + }while( iErr && cnt++<3 ); + memset(p, 0, sizeof(*p)); + p->iJD = iGuess; + p->validJD = 1; + p->isUtc = 1; + p->isLocal = 0; + } + rc = SQLITE_OK; + } +#endif + break; + } + case 'w': { + /* + ** weekday N + ** + ** Move the date to the same time on the next occurrence of + ** weekday N where 0==Sunday, 1==Monday, and so forth. If the + ** date is already on the appropriate weekday, this is a no-op. + */ + if( sqlite3_strnicmp(z, "weekday ", 8)==0 + && sqlite3AtoF(&z[8], &r)>0 + && r>=0.0 && r<7.0 && (n=(int)r)==r ){ + sqlite3_int64 Z; + computeYMD_HMS(p); + p->tz = 0; + p->validJD = 0; + computeJD(p); + Z = ((p->iJD + 129600000)/86400000) % 7; + if( Z>n ) Z -= 7; + p->iJD += (n - Z)*86400000; + clearYMD_HMS_TZ(p); + rc = 0; + } + break; + } + case 's': { + /* + ** start of TTTTT + ** + ** Move the date backwards to the beginning of the current day, + ** or month or year. + ** + ** subsecond + ** subsec + ** + ** Show subsecond precision in the output of datetime() and + ** unixepoch() and strftime('%s'). + */ + if( sqlite3_strnicmp(z, "start of ", 9)!=0 ){ + if( sqlite3_stricmp(z, "subsec")==0 + || sqlite3_stricmp(z, "subsecond")==0 + ){ + p->useSubsec = 1; + rc = 0; + } + break; + } + if( !p->validJD && !p->validYMD && !p->validHMS ) break; + z += 9; + computeYMD(p); + p->validHMS = 1; + p->h = p->m = 0; + p->s = 0.0; + p->rawS = 0; + p->tz = 0; + p->validJD = 0; + if( sqlite3_stricmp(z,"month")==0 ){ + p->D = 1; + rc = 0; + }else if( sqlite3_stricmp(z,"year")==0 ){ + p->M = 1; + p->D = 1; + rc = 0; + }else if( sqlite3_stricmp(z,"day")==0 ){ + rc = 0; + } + break; + } + case '+': + case '-': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': { + double rRounder; + int i, rx; + int Y,M,D,h,m,x; + const char *z2 = z; + char *zCopy; + sqlite3 *db = sqlite3_context_db_handle(pCtx); + char z0 = z[0]; + for(n=1; z[n]; n++){ + if( z[n]==':' ) break; + if( sqlite3Isspace(z[n]) ) break; + if( z[n]=='-' ){ + if( n==5 && getDigits(&z[1], "40f", &Y)==1 ) break; + if( n==6 && getDigits(&z[1], "50f", &Y)==1 ) break; + } + } + zCopy = sqlite3DbStrNDup(db, z, n); + if( zCopy==0 ) break; + rx = sqlite3AtoF(zCopy, &r)<=0; + sqlite3DbFree(db, zCopy); + if( rx ){ + assert( rc==1 ); + break; + } + if( z[n]=='-' ){ + /* A modifier of the form (+|-)YYYY-MM-DD adds or subtracts the + ** specified number of years, months, and days. MM is limited to + ** the range 0-11 and DD is limited to 0-30. + */ + if( z0!='+' && z0!='-' ) break; /* Must start with +/- */ + if( n==5 ){ + if( getDigits(&z[1], "40f-20a-20d", &Y, &M, &D)!=3 ) break; + }else{ + assert( n==6 ); + if( getDigits(&z[1], "50f-20a-20d", &Y, &M, &D)!=3 ) break; + z++; + } + if( M>=12 ) break; /* M range 0..11 */ + if( D>=31 ) break; /* D range 0..30 */ + computeYMD_HMS(p); + p->validJD = 0; + if( z0=='-' ){ + p->Y -= Y; + p->M -= M; + D = -D; + }else{ + p->Y += Y; + p->M += M; + } + x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12; + p->Y += x; + p->M -= x*12; + computeFloor(p); + computeJD(p); + p->validHMS = 0; + p->validYMD = 0; + p->iJD += (i64)D*86400000; + if( z[11]==0 ){ + rc = 0; + break; + } + if( sqlite3Isspace(z[11]) + && getDigits(&z[12], "20c:20e", &h, &m)==2 + ){ + z2 = &z[12]; + n = 2; + }else{ + break; + } + } + if( z2[n]==':' ){ + /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the + ** specified number of hours, minutes, seconds, and fractional seconds + ** to the time. The ".FFF" may be omitted. The ":SS.FFF" may be + ** omitted. + */ + + DateTime tx; + sqlite3_int64 day; + if( !sqlite3Isdigit(*z2) ) z2++; + memset(&tx, 0, sizeof(tx)); + if( parseHhMmSs(z2, &tx) ) break; + computeJD(&tx); + tx.iJD -= 43200000; + day = tx.iJD/86400000; + tx.iJD -= day*86400000; + if( z0=='-' ) tx.iJD = -tx.iJD; + computeJD(p); + clearYMD_HMS_TZ(p); + p->iJD += tx.iJD; + rc = 0; + break; + } + + /* If control reaches this point, it means the transformation is + ** one of the forms like "+NNN days". */ + z += n; + while( sqlite3Isspace(*z) ) z++; + n = sqlite3Strlen30(z); + if( n<3 || n>10 ) break; + if( sqlite3UpperToLower[(u8)z[n-1]]=='s' ) n--; + computeJD(p); + assert( rc==1 ); + rRounder = r<0 ? -0.5 : +0.5; + p->nFloor = 0; + for(i=0; i-aXformType[i].rLimit && rM += (int)r; + x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12; + p->Y += x; + p->M -= x*12; + computeFloor(p); + p->validJD = 0; + r -= (int)r; + break; + } + case 5: { /* Special processing to add years */ + int y = (int)r; + assert( strcmp(aXformType[5].zName,"year")==0 ); + computeYMD_HMS(p); + assert( p->M>=0 && p->M<=12 ); + p->Y += y; + computeFloor(p); + p->validJD = 0; + r -= (int)r; + break; + } + } + computeJD(p); + p->iJD += (sqlite3_int64)(r*1000.0*aXformType[i].rXform + rRounder); + rc = 0; + break; + } + } + clearYMD_HMS_TZ(p); + break; + } + default: { + break; + } + } + return rc; +} + +/* +** Process time function arguments. argv[0] is a date-time stamp. +** argv[1] and following are modifiers. Parse them all and write +** the resulting time into the DateTime structure p. Return 0 +** on success and 1 if there are any errors. +** +** If there are zero parameters (if even argv[0] is undefined) +** then assume a default value of "now" for argv[0]. +*/ +static int isDate( + sqlite3_context *context, + int argc, + sqlite3_value **argv, + DateTime *p +){ + int i, n; + const unsigned char *z; + int eType; + memset(p, 0, sizeof(*p)); + if( argc==0 ){ + if( !sqlite3NotPureFunc(context) ) return 1; + return setDateTimeToCurrent(context, p); + } + if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT + || eType==SQLITE_INTEGER ){ + setRawDateNumber(p, sqlite3_value_double(argv[0])); + }else{ + z = sqlite3_value_text(argv[0]); + if( !z || parseDateOrTime(context, (char*)z, p) ){ + return 1; + } + } + for(i=1; iisError || !validJulianDay(p->iJD) ) return 1; + if( argc==1 && p->validYMD && p->D>28 ){ + /* Make sure a YYYY-MM-DD is normalized. + ** Example: 2023-02-31 -> 2023-03-03 */ + assert( p->validJD ); + p->validYMD = 0; + } + return 0; +} + + +/* +** The following routines implement the various date and time functions +** of SQLite. +*/ + +/* +** julianday( TIMESTRING, MOD, MOD, ...) +** +** Return the julian day number of the date specified in the arguments +*/ +static void juliandayFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + DateTime x; + if( isDate(context, argc, argv, &x)==0 ){ + computeJD(&x); + sqlite3_result_double(context, x.iJD/86400000.0); + } +} + +/* +** unixepoch( TIMESTRING, MOD, MOD, ...) +** +** Return the number of seconds (including fractional seconds) since +** the unix epoch of 1970-01-01 00:00:00 GMT. +*/ +static void unixepochFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + DateTime x; + if( isDate(context, argc, argv, &x)==0 ){ + computeJD(&x); + if( x.useSubsec ){ + sqlite3_result_double(context, (x.iJD - 21086676*(i64)10000000)/1000.0); + }else{ + sqlite3_result_int64(context, x.iJD/1000 - 21086676*(i64)10000); + } + } +} + +/* +** datetime( TIMESTRING, MOD, MOD, ...) +** +** Return YYYY-MM-DD HH:MM:SS +*/ +static void datetimeFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + DateTime x; + if( isDate(context, argc, argv, &x)==0 ){ + int Y, s, n; + char zBuf[32]; + computeYMD_HMS(&x); + Y = x.Y; + if( Y<0 ) Y = -Y; + zBuf[1] = '0' + (Y/1000)%10; + zBuf[2] = '0' + (Y/100)%10; + zBuf[3] = '0' + (Y/10)%10; + zBuf[4] = '0' + (Y)%10; + zBuf[5] = '-'; + zBuf[6] = '0' + (x.M/10)%10; + zBuf[7] = '0' + (x.M)%10; + zBuf[8] = '-'; + zBuf[9] = '0' + (x.D/10)%10; + zBuf[10] = '0' + (x.D)%10; + zBuf[11] = ' '; + zBuf[12] = '0' + (x.h/10)%10; + zBuf[13] = '0' + (x.h)%10; + zBuf[14] = ':'; + zBuf[15] = '0' + (x.m/10)%10; + zBuf[16] = '0' + (x.m)%10; + zBuf[17] = ':'; + if( x.useSubsec ){ + s = (int)(1000.0*x.s + 0.5); + zBuf[18] = '0' + (s/10000)%10; + zBuf[19] = '0' + (s/1000)%10; + zBuf[20] = '.'; + zBuf[21] = '0' + (s/100)%10; + zBuf[22] = '0' + (s/10)%10; + zBuf[23] = '0' + (s)%10; + zBuf[24] = 0; + n = 24; + }else{ + s = (int)x.s; + zBuf[18] = '0' + (s/10)%10; + zBuf[19] = '0' + (s)%10; + zBuf[20] = 0; + n = 20; + } + if( x.Y<0 ){ + zBuf[0] = '-'; + sqlite3_result_text(context, zBuf, n, SQLITE_TRANSIENT); + }else{ + sqlite3_result_text(context, &zBuf[1], n-1, SQLITE_TRANSIENT); + } + } +} + +/* +** time( TIMESTRING, MOD, MOD, ...) +** +** Return HH:MM:SS +*/ +static void timeFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + DateTime x; + if( isDate(context, argc, argv, &x)==0 ){ + int s, n; + char zBuf[16]; + computeHMS(&x); + zBuf[0] = '0' + (x.h/10)%10; + zBuf[1] = '0' + (x.h)%10; + zBuf[2] = ':'; + zBuf[3] = '0' + (x.m/10)%10; + zBuf[4] = '0' + (x.m)%10; + zBuf[5] = ':'; + if( x.useSubsec ){ + s = (int)(1000.0*x.s + 0.5); + zBuf[6] = '0' + (s/10000)%10; + zBuf[7] = '0' + (s/1000)%10; + zBuf[8] = '.'; + zBuf[9] = '0' + (s/100)%10; + zBuf[10] = '0' + (s/10)%10; + zBuf[11] = '0' + (s)%10; + zBuf[12] = 0; + n = 12; + }else{ + s = (int)x.s; + zBuf[6] = '0' + (s/10)%10; + zBuf[7] = '0' + (s)%10; + zBuf[8] = 0; + n = 8; + } + sqlite3_result_text(context, zBuf, n, SQLITE_TRANSIENT); + } +} + +/* +** date( TIMESTRING, MOD, MOD, ...) +** +** Return YYYY-MM-DD +*/ +static void dateFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + DateTime x; + if( isDate(context, argc, argv, &x)==0 ){ + int Y; + char zBuf[16]; + computeYMD(&x); + Y = x.Y; + if( Y<0 ) Y = -Y; + zBuf[1] = '0' + (Y/1000)%10; + zBuf[2] = '0' + (Y/100)%10; + zBuf[3] = '0' + (Y/10)%10; + zBuf[4] = '0' + (Y)%10; + zBuf[5] = '-'; + zBuf[6] = '0' + (x.M/10)%10; + zBuf[7] = '0' + (x.M)%10; + zBuf[8] = '-'; + zBuf[9] = '0' + (x.D/10)%10; + zBuf[10] = '0' + (x.D)%10; + zBuf[11] = 0; + if( x.Y<0 ){ + zBuf[0] = '-'; + sqlite3_result_text(context, zBuf, 11, SQLITE_TRANSIENT); + }else{ + sqlite3_result_text(context, &zBuf[1], 10, SQLITE_TRANSIENT); + } + } +} + +/* +** Compute the number of days after the most recent January 1. +** +** In other words, compute the zero-based day number for the +** current year: +** +** Jan01 = 0, Jan02 = 1, ..., Jan31 = 30, Feb01 = 31, ... +** Dec31 = 364 or 365. +*/ +static int daysAfterJan01(DateTime *pDate){ + DateTime jan01 = *pDate; + assert( jan01.validYMD ); + assert( jan01.validHMS ); + assert( pDate->validJD ); + jan01.validJD = 0; + jan01.M = 1; + jan01.D = 1; + computeJD(&jan01); + return (int)((pDate->iJD-jan01.iJD+43200000)/86400000); +} + +/* +** Return the number of days after the most recent Monday. +** +** In other words, return the day of the week according +** to this code: +** +** 0=Monday, 1=Tuesday, 2=Wednesday, ..., 6=Sunday. +*/ +static int daysAfterMonday(DateTime *pDate){ + assert( pDate->validJD ); + return (int)((pDate->iJD+43200000)/86400000) % 7; +} + +/* +** Return the number of days after the most recent Sunday. +** +** In other words, return the day of the week according +** to this code: +** +** 0=Sunday, 1=Monday, 2=Tuesday, ..., 6=Saturday +*/ +static int daysAfterSunday(DateTime *pDate){ + assert( pDate->validJD ); + return (int)((pDate->iJD+129600000)/86400000) % 7; +} + +/* +** strftime( FORMAT, TIMESTRING, MOD, MOD, ...) +** +** Return a string described by FORMAT. Conversions as follows: +** +** %d day of month 01-31 +** %e day of month 1-31 +** %f ** fractional seconds SS.SSS +** %F ISO date. YYYY-MM-DD +** %G ISO year corresponding to %V 0000-9999. +** %g 2-digit ISO year corresponding to %V 00-99 +** %H hour 00-24 +** %k hour 0-24 (leading zero converted to space) +** %I hour 01-12 +** %j day of year 001-366 +** %J ** julian day number +** %l hour 1-12 (leading zero converted to space) +** %m month 01-12 +** %M minute 00-59 +** %p "AM" or "PM" +** %P "am" or "pm" +** %R time as HH:MM +** %s seconds since 1970-01-01 +** %S seconds 00-59 +** %T time as HH:MM:SS +** %u day of week 1-7 Monday==1, Sunday==7 +** %w day of week 0-6 Sunday==0, Monday==1 +** %U week of year 00-53 (First Sunday is start of week 01) +** %V week of year 01-53 (First week containing Thursday is week 01) +** %W week of year 00-53 (First Monday is start of week 01) +** %Y year 0000-9999 +** %% % +*/ +static void strftimeFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + DateTime x; + size_t i,j; + sqlite3 *db; + const char *zFmt; + sqlite3_str sRes; + + + if( argc==0 ) return; + zFmt = (const char*)sqlite3_value_text(argv[0]); + if( zFmt==0 || isDate(context, argc-1, argv+1, &x) ) return; + db = sqlite3_context_db_handle(context); + sqlite3StrAccumInit(&sRes, 0, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); + + computeJD(&x); + computeYMD_HMS(&x); + for(i=j=0; zFmt[i]; i++){ + char cf; + if( zFmt[i]!='%' ) continue; + if( j59.999) ) s = 59.999; + sqlite3_str_appendf(&sRes, "%06.3f", s); + break; + } + case 'F': { + sqlite3_str_appendf(&sRes, "%04d-%02d-%02d", x.Y, x.M, x.D); + break; + } + case 'G': /* Fall thru */ + case 'g': { + DateTime y = x; + assert( y.validJD ); + /* Move y so that it is the Thursday in the same week as x */ + y.iJD += (3 - daysAfterMonday(&x))*86400000; + y.validYMD = 0; + computeYMD(&y); + if( cf=='g' ){ + sqlite3_str_appendf(&sRes, "%02d", y.Y%100); + }else{ + sqlite3_str_appendf(&sRes, "%04d", y.Y); + } + break; + } + case 'H': + case 'k': { + sqlite3_str_appendf(&sRes, cf=='H' ? "%02d" : "%2d", x.h); + break; + } + case 'I': /* Fall thru */ + case 'l': { + int h = x.h; + if( h>12 ) h -= 12; + if( h==0 ) h = 12; + sqlite3_str_appendf(&sRes, cf=='I' ? "%02d" : "%2d", h); + break; + } + case 'j': { /* Day of year. Jan01==1, Jan02==2, and so forth */ + sqlite3_str_appendf(&sRes,"%03d",daysAfterJan01(&x)+1); + break; + } + case 'J': { /* Julian day number. (Non-standard) */ + sqlite3_str_appendf(&sRes,"%.16g",x.iJD/86400000.0); + break; + } + case 'm': { + sqlite3_str_appendf(&sRes,"%02d",x.M); + break; + } + case 'M': { + sqlite3_str_appendf(&sRes,"%02d",x.m); + break; + } + case 'p': /* Fall thru */ + case 'P': { + if( x.h>=12 ){ + sqlite3_str_append(&sRes, cf=='p' ? "PM" : "pm", 2); + }else{ + sqlite3_str_append(&sRes, cf=='p' ? "AM" : "am", 2); + } + break; + } + case 'R': { + sqlite3_str_appendf(&sRes, "%02d:%02d", x.h, x.m); + break; + } + case 's': { + if( x.useSubsec ){ + sqlite3_str_appendf(&sRes,"%.3f", + (x.iJD - 21086676*(i64)10000000)/1000.0); + }else{ + i64 iS = (i64)(x.iJD/1000 - 21086676*(i64)10000); + sqlite3_str_appendf(&sRes,"%lld",iS); + } + break; + } + case 'S': { + sqlite3_str_appendf(&sRes,"%02d",(int)x.s); + break; + } + case 'T': { + sqlite3_str_appendf(&sRes,"%02d:%02d:%02d", x.h, x.m, (int)x.s); + break; + } + case 'u': /* Day of week. 1 to 7. Monday==1, Sunday==7 */ + case 'w': { /* Day of week. 0 to 6. Sunday==0, Monday==1 */ + char c = (char)daysAfterSunday(&x) + '0'; + if( c=='0' && cf=='u' ) c = '7'; + sqlite3_str_appendchar(&sRes, 1, c); + break; + } + case 'U': { /* Week num. 00-53. First Sun of the year is week 01 */ + sqlite3_str_appendf(&sRes,"%02d", + (daysAfterJan01(&x)-daysAfterSunday(&x)+7)/7); + break; + } + case 'V': { /* Week num. 01-53. First week with a Thur is week 01 */ + DateTime y = x; + /* Adjust y so that is the Thursday in the same week as x */ + assert( y.validJD ); + y.iJD += (3 - daysAfterMonday(&x))*86400000; + y.validYMD = 0; + computeYMD(&y); + sqlite3_str_appendf(&sRes,"%02d", daysAfterJan01(&y)/7+1); + break; + } + case 'W': { /* Week num. 00-53. First Mon of the year is week 01 */ + sqlite3_str_appendf(&sRes,"%02d", + (daysAfterJan01(&x)-daysAfterMonday(&x)+7)/7); + break; + } + case 'Y': { + sqlite3_str_appendf(&sRes,"%04d",x.Y); + break; + } + case '%': { + sqlite3_str_appendchar(&sRes, 1, '%'); + break; + } + default: { + sqlite3_str_reset(&sRes); + return; + } + } + } + if( j=d2.iJD ){ + sign = '+'; + Y = d1.Y - d2.Y; + if( Y ){ + d2.Y = d1.Y; + d2.validJD = 0; + computeJD(&d2); + } + M = d1.M - d2.M; + if( M<0 ){ + Y--; + M += 12; + } + if( M!=0 ){ + d2.M = d1.M; + d2.validJD = 0; + computeJD(&d2); + } + while( d1.iJDd2.iJD ){ + M--; + if( M<0 ){ + M = 11; + Y--; + } + d2.M++; + if( d2.M>12 ){ + d2.M = 1; + d2.Y++; + } + d2.validJD = 0; + computeJD(&d2); + } + d1.iJD = d2.iJD - d1.iJD; + d1.iJD += (u64)1486995408 * (u64)100000; + } + clearYMD_HMS_TZ(&d1); + computeYMD_HMS(&d1); + sqlite3StrAccumInit(&sRes, 0, 0, 0, 100); + sqlite3_str_appendf(&sRes, "%c%04d-%02d-%02d %02d:%02d:%06.3f", + sign, Y, M, d1.D-1, d1.h, d1.m, d1.s); + sqlite3ResultStrAccum(context, &sRes); +} + + +/* +** current_timestamp() +** +** This function returns the same value as datetime('now'). +*/ +static void ctimestampFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **NotUsed2 +){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + datetimeFunc(context, 0, 0); +} +#endif /* !defined(SQLITE_OMIT_DATETIME_FUNCS) */ + +#ifdef SQLITE_OMIT_DATETIME_FUNCS +/* +** If the library is compiled to omit the full-scale date and time +** handling (to get a smaller binary), the following minimal version +** of the functions current_time(), current_date() and current_timestamp() +** are included instead. This is to support column declarations that +** include "DEFAULT CURRENT_TIME" etc. +** +** This function uses the C-library functions time(), gmtime() +** and strftime(). The format string to pass to strftime() is supplied +** as the user-data for the function. +*/ +static void currentTimeFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + time_t t; + char *zFormat = (char *)sqlite3_user_data(context); + sqlite3_int64 iT; + struct tm *pTm; + struct tm sNow; + char zBuf[20]; + + UNUSED_PARAMETER(argc); + UNUSED_PARAMETER(argv); + + iT = sqlite3StmtCurrentTime(context); + if( iT<=0 ) return; + t = iT/1000 - 10000*(sqlite3_int64)21086676; +#if HAVE_GMTIME_R + pTm = gmtime_r(&t, &sNow); +#else + sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN)); + pTm = gmtime(&t); + if( pTm ) memcpy(&sNow, pTm, sizeof(sNow)); + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN)); +#endif + if( pTm ){ + strftime(zBuf, 20, zFormat, &sNow); + sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); + } +} +#endif + +#if !defined(SQLITE_OMIT_DATETIME_FUNCS) && defined(SQLITE_DEBUG) +/* +** datedebug(...) +** +** This routine returns JSON that describes the internal DateTime object. +** Used for debugging and testing only. Subject to change. +*/ +static void datedebugFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + DateTime x; + if( isDate(context, argc, argv, &x)==0 ){ + char *zJson; + zJson = sqlite3_mprintf( + "{iJD:%lld,Y:%d,M:%d,D:%d,h:%d,m:%d,tz:%d," + "s:%.3f,validJD:%d,validYMD:%d,validHMS:%d," + "nFloor:%d,rawS:%d,isError:%d,useSubsec:%d," + "isUtc:%d,isLocal:%d}", + x.iJD, x.Y, x.M, x.D, x.h, x.m, x.tz, + x.s, x.validJD, x.validYMD, x.validHMS, + x.nFloor, x.rawS, x.isError, x.useSubsec, + x.isUtc, x.isLocal); + sqlite3_result_text(context, zJson, -1, sqlite3_free); + } +} +#endif /* !SQLITE_OMIT_DATETIME_FUNCS && SQLITE_DEBUG */ + + +/* +** This function registered all of the above C functions as SQL +** functions. This should be the only routine in this file with +** external linkage. +*/ +SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){ + static FuncDef aDateTimeFuncs[] = { +#ifndef SQLITE_OMIT_DATETIME_FUNCS + PURE_DATE(julianday, -1, 0, 0, juliandayFunc ), + PURE_DATE(unixepoch, -1, 0, 0, unixepochFunc ), + PURE_DATE(date, -1, 0, 0, dateFunc ), + PURE_DATE(time, -1, 0, 0, timeFunc ), + PURE_DATE(datetime, -1, 0, 0, datetimeFunc ), + PURE_DATE(strftime, -1, 0, 0, strftimeFunc ), + PURE_DATE(timediff, 2, 0, 0, timediffFunc ), +#ifdef SQLITE_DEBUG + PURE_DATE(datedebug, -1, 0, 0, datedebugFunc ), +#endif + DFUNCTION(current_time, 0, 0, 0, ctimeFunc ), + DFUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc), + DFUNCTION(current_date, 0, 0, 0, cdateFunc ), +#else + STR_FUNCTION(current_time, 0, "%H:%M:%S", 0, currentTimeFunc), + STR_FUNCTION(current_date, 0, "%Y-%m-%d", 0, currentTimeFunc), + STR_FUNCTION(current_timestamp, 0, "%Y-%m-%d %H:%M:%S", 0, currentTimeFunc), +#endif + }; + sqlite3InsertBuiltinFuncs(aDateTimeFuncs, ArraySize(aDateTimeFuncs)); +} + +/************** End of date.c ************************************************/ +/************** Begin file os.c **********************************************/ +/* +** 2005 November 29 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains OS interface code that is common to all +** architectures. +*/ +/* #include "sqliteInt.h" */ + +/* +** If we compile with the SQLITE_TEST macro set, then the following block +** of code will give us the ability to simulate a disk I/O error. This +** is used for testing the I/O recovery logic. +*/ +#if defined(SQLITE_TEST) +SQLITE_API int sqlite3_io_error_hit = 0; /* Total number of I/O Errors */ +SQLITE_API int sqlite3_io_error_hardhit = 0; /* Number of non-benign errors */ +SQLITE_API int sqlite3_io_error_pending = 0; /* Count down to first I/O error */ +SQLITE_API int sqlite3_io_error_persist = 0; /* True if I/O errors persist */ +SQLITE_API int sqlite3_io_error_benign = 0; /* True if errors are benign */ +SQLITE_API int sqlite3_diskfull_pending = 0; +SQLITE_API int sqlite3_diskfull = 0; +#endif /* defined(SQLITE_TEST) */ + +/* +** When testing, also keep a count of the number of open files. +*/ +#if defined(SQLITE_TEST) +SQLITE_API int sqlite3_open_file_count = 0; +#endif /* defined(SQLITE_TEST) */ + +/* +** The default SQLite sqlite3_vfs implementations do not allocate +** memory (actually, os_unix.c allocates a small amount of memory +** from within OsOpen()), but some third-party implementations may. +** So we test the effects of a malloc() failing and the sqlite3OsXXX() +** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro. +** +** The following functions are instrumented for malloc() failure +** testing: +** +** sqlite3OsRead() +** sqlite3OsWrite() +** sqlite3OsSync() +** sqlite3OsFileSize() +** sqlite3OsLock() +** sqlite3OsCheckReservedLock() +** sqlite3OsFileControl() +** sqlite3OsShmMap() +** sqlite3OsOpen() +** sqlite3OsDelete() +** sqlite3OsAccess() +** sqlite3OsFullPathname() +** +*/ +#if defined(SQLITE_TEST) +SQLITE_API int sqlite3_memdebug_vfs_oom_test = 1; + #define DO_OS_MALLOC_TEST(x) \ + if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3JournalIsInMemory(x))) { \ + void *pTstAlloc = sqlite3Malloc(10); \ + if (!pTstAlloc) return SQLITE_IOERR_NOMEM_BKPT; \ + sqlite3_free(pTstAlloc); \ + } +#else + #define DO_OS_MALLOC_TEST(x) +#endif + +/* +** The following routines are convenience wrappers around methods +** of the sqlite3_file object. This is mostly just syntactic sugar. All +** of this would be completely automatic if SQLite were coded using +** C++ instead of plain old C. +*/ +SQLITE_PRIVATE void sqlite3OsClose(sqlite3_file *pId){ + if( pId->pMethods ){ + pId->pMethods->xClose(pId); + pId->pMethods = 0; + } +} +SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){ + DO_OS_MALLOC_TEST(id); + return id->pMethods->xRead(id, pBuf, amt, offset); +} +SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){ + DO_OS_MALLOC_TEST(id); + return id->pMethods->xWrite(id, pBuf, amt, offset); +} +SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file *id, i64 size){ + return id->pMethods->xTruncate(id, size); +} +SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file *id, int flags){ + DO_OS_MALLOC_TEST(id); + return flags ? id->pMethods->xSync(id, flags) : SQLITE_OK; +} +SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){ + DO_OS_MALLOC_TEST(id); + return id->pMethods->xFileSize(id, pSize); +} +SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file *id, int lockType){ + DO_OS_MALLOC_TEST(id); + assert( lockType>=SQLITE_LOCK_SHARED && lockType<=SQLITE_LOCK_EXCLUSIVE ); + return id->pMethods->xLock(id, lockType); +} +SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file *id, int lockType){ + assert( lockType==SQLITE_LOCK_NONE || lockType==SQLITE_LOCK_SHARED ); + return id->pMethods->xUnlock(id, lockType); +} +SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){ + DO_OS_MALLOC_TEST(id); + return id->pMethods->xCheckReservedLock(id, pResOut); +} + +/* +** Use sqlite3OsFileControl() when we are doing something that might fail +** and we need to know about the failures. Use sqlite3OsFileControlHint() +** when simply tossing information over the wall to the VFS and we do not +** really care if the VFS receives and understands the information since it +** is only a hint and can be safely ignored. The sqlite3OsFileControlHint() +** routine has no return value since the return value would be meaningless. +*/ +SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ + if( id->pMethods==0 ) return SQLITE_NOTFOUND; +#ifdef SQLITE_TEST + if( op!=SQLITE_FCNTL_COMMIT_PHASETWO + && op!=SQLITE_FCNTL_LOCK_TIMEOUT + && op!=SQLITE_FCNTL_CKPT_DONE + && op!=SQLITE_FCNTL_CKPT_START + ){ + /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite + ** is using a regular VFS, it is called after the corresponding + ** transaction has been committed. Injecting a fault at this point + ** confuses the test scripts - the COMMIT command returns SQLITE_NOMEM + ** but the transaction is committed anyway. + ** + ** The core must call OsFileControl() though, not OsFileControlHint(), + ** as if a custom VFS (e.g. zipvfs) returns an error here, it probably + ** means the commit really has failed and an error should be returned + ** to the user. + ** + ** The CKPT_DONE and CKPT_START file-controls are write-only signals + ** to the cksumvfs. Their return code is meaningless and is ignored + ** by the SQLite core, so there is no point in simulating OOMs for them. + */ + DO_OS_MALLOC_TEST(id); + } +#endif + return id->pMethods->xFileControl(id, op, pArg); +} +SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){ + if( id->pMethods ) (void)id->pMethods->xFileControl(id, op, pArg); +} + +SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id){ + int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize; + return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE); +} +SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id){ + if( NEVER(id->pMethods==0) ) return 0; + return id->pMethods->xDeviceCharacteristics(id); +} +#ifndef SQLITE_OMIT_WAL +SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){ + return id->pMethods->xShmLock(id, offset, n, flags); +} +SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id){ + id->pMethods->xShmBarrier(id); +} +SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int deleteFlag){ + return id->pMethods->xShmUnmap(id, deleteFlag); +} +SQLITE_PRIVATE int sqlite3OsShmMap( + sqlite3_file *id, /* Database file handle */ + int iPage, + int pgsz, + int bExtend, /* True to extend file if necessary */ + void volatile **pp /* OUT: Pointer to mapping */ +){ + DO_OS_MALLOC_TEST(id); + return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp); +} +#endif /* SQLITE_OMIT_WAL */ + +#if SQLITE_MAX_MMAP_SIZE>0 +/* The real implementation of xFetch and xUnfetch */ +SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){ + DO_OS_MALLOC_TEST(id); + return id->pMethods->xFetch(id, iOff, iAmt, pp); +} +SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){ + return id->pMethods->xUnfetch(id, iOff, p); +} +#else +/* No-op stubs to use when memory-mapped I/O is disabled */ +SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){ + *pp = 0; + return SQLITE_OK; +} +SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){ + return SQLITE_OK; +} +#endif + +/* +** The next group of routines are convenience wrappers around the +** VFS methods. +*/ +SQLITE_PRIVATE int sqlite3OsOpen( + sqlite3_vfs *pVfs, + const char *zPath, + sqlite3_file *pFile, + int flags, + int *pFlagsOut +){ + int rc; + DO_OS_MALLOC_TEST(0); + /* 0x87f7f is a mask of SQLITE_OPEN_ flags that are valid to be passed + ** down into the VFS layer. Some SQLITE_OPEN_ flags (for example, + ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before + ** reaching the VFS. */ + assert( zPath || (flags & SQLITE_OPEN_EXCLUSIVE) ); + rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x1087f7f, pFlagsOut); + assert( rc==SQLITE_OK || pFile->pMethods==0 ); + return rc; +} +SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ + DO_OS_MALLOC_TEST(0); + assert( dirSync==0 || dirSync==1 ); + return pVfs->xDelete!=0 ? pVfs->xDelete(pVfs, zPath, dirSync) : SQLITE_OK; +} +SQLITE_PRIVATE int sqlite3OsAccess( + sqlite3_vfs *pVfs, + const char *zPath, + int flags, + int *pResOut +){ + DO_OS_MALLOC_TEST(0); + return pVfs->xAccess(pVfs, zPath, flags, pResOut); +} +SQLITE_PRIVATE int sqlite3OsFullPathname( + sqlite3_vfs *pVfs, + const char *zPath, + int nPathOut, + char *zPathOut +){ + DO_OS_MALLOC_TEST(0); + zPathOut[0] = 0; + return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut); +} +#ifndef SQLITE_OMIT_LOAD_EXTENSION +SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){ + assert( zPath!=0 ); + assert( strlen(zPath)<=SQLITE_MAX_PATHLEN ); /* tag-20210611-1 */ + return pVfs->xDlOpen(pVfs, zPath); +} +SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ + pVfs->xDlError(pVfs, nByte, zBufOut); +} +SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHdle, const char *zSym))(void){ + return pVfs->xDlSym(pVfs, pHdle, zSym); +} +SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){ + pVfs->xDlClose(pVfs, pHandle); +} +#endif /* SQLITE_OMIT_LOAD_EXTENSION */ +SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ + if( sqlite3Config.iPrngSeed ){ + memset(zBufOut, 0, nByte); + if( ALWAYS(nByte>(signed)sizeof(unsigned)) ) nByte = sizeof(unsigned int); + memcpy(zBufOut, &sqlite3Config.iPrngSeed, nByte); + return SQLITE_OK; + }else{ + return pVfs->xRandomness(pVfs, nByte, zBufOut); + } + +} +SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){ + return pVfs->xSleep(pVfs, nMicro); +} +SQLITE_PRIVATE int sqlite3OsGetLastError(sqlite3_vfs *pVfs){ + return pVfs->xGetLastError ? pVfs->xGetLastError(pVfs, 0, 0) : 0; +} +SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){ + int rc; + /* IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64() + ** method to get the current date and time if that method is available + ** (if iVersion is 2 or greater and the function pointer is not NULL) and + ** will fall back to xCurrentTime() if xCurrentTimeInt64() is + ** unavailable. + */ + if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){ + rc = pVfs->xCurrentTimeInt64(pVfs, pTimeOut); + }else{ + double r; + rc = pVfs->xCurrentTime(pVfs, &r); + *pTimeOut = sqlite3RealToI64(r*86400000.0); + } + return rc; +} + +SQLITE_PRIVATE int sqlite3OsOpenMalloc( + sqlite3_vfs *pVfs, + const char *zFile, + sqlite3_file **ppFile, + int flags, + int *pOutFlags +){ + int rc; + sqlite3_file *pFile; + pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile); + if( pFile ){ + rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags); + if( rc!=SQLITE_OK ){ + sqlite3_free(pFile); + *ppFile = 0; + }else{ + *ppFile = pFile; + } + }else{ + *ppFile = 0; + rc = SQLITE_NOMEM_BKPT; + } + assert( *ppFile!=0 || rc!=SQLITE_OK ); + return rc; +} +SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *pFile){ + assert( pFile ); + sqlite3OsClose(pFile); + sqlite3_free(pFile); +} + +/* +** This function is a wrapper around the OS specific implementation of +** sqlite3_os_init(). The purpose of the wrapper is to provide the +** ability to simulate a malloc failure, so that the handling of an +** error in sqlite3_os_init() by the upper layers can be tested. +*/ +SQLITE_PRIVATE int sqlite3OsInit(void){ + void *p = sqlite3_malloc(10); + if( p==0 ) return SQLITE_NOMEM_BKPT; + sqlite3_free(p); + return sqlite3_os_init(); +} + +/* +** The list of all registered VFS implementations. +*/ +static sqlite3_vfs * SQLITE_WSD vfsList = 0; +#define vfsList GLOBAL(sqlite3_vfs *, vfsList) + +/* +** Locate a VFS by name. If no name is given, simply return the +** first VFS on the list. +*/ +SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){ + sqlite3_vfs *pVfs = 0; +#if SQLITE_THREADSAFE + sqlite3_mutex *mutex; +#endif +#ifndef SQLITE_OMIT_AUTOINIT + int rc = sqlite3_initialize(); + if( rc ) return 0; +#endif +#if SQLITE_THREADSAFE + mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); +#endif + sqlite3_mutex_enter(mutex); + for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){ + if( zVfs==0 ) break; + if( strcmp(zVfs, pVfs->zName)==0 ) break; + } + sqlite3_mutex_leave(mutex); + return pVfs; +} + +/* +** Unlink a VFS from the linked list +*/ +static void vfsUnlink(sqlite3_vfs *pVfs){ + assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN)) ); + if( pVfs==0 ){ + /* No-op */ + }else if( vfsList==pVfs ){ + vfsList = pVfs->pNext; + }else if( vfsList ){ + sqlite3_vfs *p = vfsList; + while( p->pNext && p->pNext!=pVfs ){ + p = p->pNext; + } + if( p->pNext==pVfs ){ + p->pNext = pVfs->pNext; + } + } +} + +/* +** Register a VFS with the system. It is harmless to register the same +** VFS multiple times. The new VFS becomes the default if makeDflt is +** true. +*/ +SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){ + MUTEX_LOGIC(sqlite3_mutex *mutex;) +#ifndef SQLITE_OMIT_AUTOINIT + int rc = sqlite3_initialize(); + if( rc ) return rc; +#endif +#ifdef SQLITE_ENABLE_API_ARMOR + if( pVfs==0 ) return SQLITE_MISUSE_BKPT; +#endif + + MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); ) + sqlite3_mutex_enter(mutex); + vfsUnlink(pVfs); + if( makeDflt || vfsList==0 ){ + pVfs->pNext = vfsList; + vfsList = pVfs; + }else{ + pVfs->pNext = vfsList->pNext; + vfsList->pNext = pVfs; + } + assert(vfsList); + sqlite3_mutex_leave(mutex); + return SQLITE_OK; +} + +/* +** Unregister a VFS so that it is no longer accessible. +*/ +SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){ + MUTEX_LOGIC(sqlite3_mutex *mutex;) +#ifndef SQLITE_OMIT_AUTOINIT + int rc = sqlite3_initialize(); + if( rc ) return rc; +#endif + MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); ) + sqlite3_mutex_enter(mutex); + vfsUnlink(pVfs); + sqlite3_mutex_leave(mutex); + return SQLITE_OK; +} + +/************** End of os.c **************************************************/ +/************** Begin file fault.c *******************************************/ +/* +** 2008 Jan 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains code to support the concept of "benign" +** malloc failures (when the xMalloc() or xRealloc() method of the +** sqlite3_mem_methods structure fails to allocate a block of memory +** and returns 0). +** +** Most malloc failures are non-benign. After they occur, SQLite +** abandons the current operation and returns an error code (usually +** SQLITE_NOMEM) to the user. However, sometimes a fault is not necessarily +** fatal. For example, if a malloc fails while resizing a hash table, this +** is completely recoverable simply by not carrying out the resize. The +** hash table will continue to function normally. So a malloc failure +** during a hash table resize is a benign fault. +*/ + +/* #include "sqliteInt.h" */ + +#ifndef SQLITE_UNTESTABLE + +/* +** Global variables. +*/ +typedef struct BenignMallocHooks BenignMallocHooks; +static SQLITE_WSD struct BenignMallocHooks { + void (*xBenignBegin)(void); + void (*xBenignEnd)(void); +} sqlite3Hooks = { 0, 0 }; + +/* The "wsdHooks" macro will resolve to the appropriate BenignMallocHooks +** structure. If writable static data is unsupported on the target, +** we have to locate the state vector at run-time. In the more common +** case where writable static data is supported, wsdHooks can refer directly +** to the "sqlite3Hooks" state vector declared above. +*/ +#ifdef SQLITE_OMIT_WSD +# define wsdHooksInit \ + BenignMallocHooks *x = &GLOBAL(BenignMallocHooks,sqlite3Hooks) +# define wsdHooks x[0] +#else +# define wsdHooksInit +# define wsdHooks sqlite3Hooks +#endif + + +/* +** Register hooks to call when sqlite3BeginBenignMalloc() and +** sqlite3EndBenignMalloc() are called, respectively. +*/ +SQLITE_PRIVATE void sqlite3BenignMallocHooks( + void (*xBenignBegin)(void), + void (*xBenignEnd)(void) +){ + wsdHooksInit; + wsdHooks.xBenignBegin = xBenignBegin; + wsdHooks.xBenignEnd = xBenignEnd; +} + +/* +** This (sqlite3EndBenignMalloc()) is called by SQLite code to indicate that +** subsequent malloc failures are benign. A call to sqlite3EndBenignMalloc() +** indicates that subsequent malloc failures are non-benign. +*/ +SQLITE_PRIVATE void sqlite3BeginBenignMalloc(void){ + wsdHooksInit; + if( wsdHooks.xBenignBegin ){ + wsdHooks.xBenignBegin(); + } +} +SQLITE_PRIVATE void sqlite3EndBenignMalloc(void){ + wsdHooksInit; + if( wsdHooks.xBenignEnd ){ + wsdHooks.xBenignEnd(); + } +} + +#endif /* #ifndef SQLITE_UNTESTABLE */ + +/************** End of fault.c ***********************************************/ +/************** Begin file mem0.c ********************************************/ +/* +** 2008 October 28 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains a no-op memory allocation drivers for use when +** SQLITE_ZERO_MALLOC is defined. The allocation drivers implemented +** here always fail. SQLite will not operate with these drivers. These +** are merely placeholders. Real drivers must be substituted using +** sqlite3_config() before SQLite will operate. +*/ +/* #include "sqliteInt.h" */ + +/* +** This version of the memory allocator is the default. It is +** used when no other memory allocator is specified using compile-time +** macros. +*/ +#ifdef SQLITE_ZERO_MALLOC + +/* +** No-op versions of all memory allocation routines +*/ +static void *sqlite3MemMalloc(int nByte){ return 0; } +static void sqlite3MemFree(void *pPrior){ return; } +static void *sqlite3MemRealloc(void *pPrior, int nByte){ return 0; } +static int sqlite3MemSize(void *pPrior){ return 0; } +static int sqlite3MemRoundup(int n){ return n; } +static int sqlite3MemInit(void *NotUsed){ return SQLITE_OK; } +static void sqlite3MemShutdown(void *NotUsed){ return; } + +/* +** This routine is the only routine in this file with external linkage. +** +** Populate the low-level memory allocation function pointers in +** sqlite3GlobalConfig.m with pointers to the routines in this file. +*/ +SQLITE_PRIVATE void sqlite3MemSetDefault(void){ + static const sqlite3_mem_methods defaultMethods = { + sqlite3MemMalloc, + sqlite3MemFree, + sqlite3MemRealloc, + sqlite3MemSize, + sqlite3MemRoundup, + sqlite3MemInit, + sqlite3MemShutdown, + 0 + }; + sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods); +} + +#endif /* SQLITE_ZERO_MALLOC */ + +/************** End of mem0.c ************************************************/ +/************** Begin file mem1.c ********************************************/ +/* +** 2007 August 14 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains low-level memory allocation drivers for when +** SQLite will use the standard C-library malloc/realloc/free interface +** to obtain the memory it needs. +** +** This file contains implementations of the low-level memory allocation +** routines specified in the sqlite3_mem_methods object. The content of +** this file is only used if SQLITE_SYSTEM_MALLOC is defined. The +** SQLITE_SYSTEM_MALLOC macro is defined automatically if neither the +** SQLITE_MEMDEBUG nor the SQLITE_WIN32_MALLOC macros are defined. The +** default configuration is to use memory allocation routines in this +** file. +** +** C-preprocessor macro summary: +** +** HAVE_MALLOC_USABLE_SIZE The configure script sets this symbol if +** the malloc_usable_size() interface exists +** on the target platform. Or, this symbol +** can be set manually, if desired. +** If an equivalent interface exists by +** a different name, using a separate -D +** option to rename it. +** +** SQLITE_WITHOUT_ZONEMALLOC Some older macs lack support for the zone +** memory allocator. Set this symbol to enable +** building on older macs. +** +** SQLITE_WITHOUT_MSIZE Set this symbol to disable the use of +** _msize() on windows systems. This might +** be necessary when compiling for Delphi, +** for example. +*/ +/* #include "sqliteInt.h" */ + +/* +** This version of the memory allocator is the default. It is +** used when no other memory allocator is specified using compile-time +** macros. +*/ +#ifdef SQLITE_SYSTEM_MALLOC +#if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC) + +/* +** Use the zone allocator available on apple products unless the +** SQLITE_WITHOUT_ZONEMALLOC symbol is defined. +*/ +#include +#include +#ifdef SQLITE_MIGHT_BE_SINGLE_CORE +#include +#endif /* SQLITE_MIGHT_BE_SINGLE_CORE */ +static malloc_zone_t* _sqliteZone_; +#define SQLITE_MALLOC(x) malloc_zone_malloc(_sqliteZone_, (x)) +#define SQLITE_FREE(x) malloc_zone_free(_sqliteZone_, (x)); +#define SQLITE_REALLOC(x,y) malloc_zone_realloc(_sqliteZone_, (x), (y)) +#define SQLITE_MALLOCSIZE(x) \ + (_sqliteZone_ ? _sqliteZone_->size(_sqliteZone_,x) : malloc_size(x)) + +#else /* if not __APPLE__ */ + +/* +** Use standard C library malloc and free on non-Apple systems. +** Also used by Apple systems if SQLITE_WITHOUT_ZONEMALLOC is defined. +*/ +#define SQLITE_MALLOC(x) malloc(x) +#define SQLITE_FREE(x) free(x) +#define SQLITE_REALLOC(x,y) realloc((x),(y)) + +/* +** The malloc.h header file is needed for malloc_usable_size() function +** on some systems (e.g. Linux). +*/ +#if HAVE_MALLOC_H && HAVE_MALLOC_USABLE_SIZE +# define SQLITE_USE_MALLOC_H 1 +# define SQLITE_USE_MALLOC_USABLE_SIZE 1 +/* +** The MSVCRT has malloc_usable_size(), but it is called _msize(). The +** use of _msize() is automatic, but can be disabled by compiling with +** -DSQLITE_WITHOUT_MSIZE. Using the _msize() function also requires +** the malloc.h header file. +*/ +#elif defined(_MSC_VER) && !defined(SQLITE_WITHOUT_MSIZE) +# define SQLITE_USE_MALLOC_H +# define SQLITE_USE_MSIZE +#endif + +/* +** Include the malloc.h header file, if necessary. Also set define macro +** SQLITE_MALLOCSIZE to the appropriate function name, which is _msize() +** for MSVC and malloc_usable_size() for most other systems (e.g. Linux). +** The memory size function can always be overridden manually by defining +** the macro SQLITE_MALLOCSIZE to the desired function name. +*/ +#if defined(SQLITE_USE_MALLOC_H) +# include +# if defined(SQLITE_USE_MALLOC_USABLE_SIZE) +# if !defined(SQLITE_MALLOCSIZE) +# define SQLITE_MALLOCSIZE(x) malloc_usable_size(x) +# endif +# elif defined(SQLITE_USE_MSIZE) +# if !defined(SQLITE_MALLOCSIZE) +# define SQLITE_MALLOCSIZE _msize +# endif +# endif +#endif /* defined(SQLITE_USE_MALLOC_H) */ + +#endif /* __APPLE__ or not __APPLE__ */ + +/* +** Like malloc(), but remember the size of the allocation +** so that we can find it later using sqlite3MemSize(). +** +** For this low-level routine, we are guaranteed that nByte>0 because +** cases of nByte<=0 will be intercepted and dealt with by higher level +** routines. +*/ +static void *sqlite3MemMalloc(int nByte){ +#ifdef SQLITE_MALLOCSIZE + void *p; + testcase( ROUND8(nByte)==nByte ); + p = SQLITE_MALLOC( nByte ); + if( p==0 ){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte); + } + return p; +#else + sqlite3_int64 *p; + assert( nByte>0 ); + testcase( ROUND8(nByte)!=nByte ); + p = SQLITE_MALLOC( nByte+8 ); + if( p ){ + p[0] = nByte; + p++; + }else{ + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte); + } + return (void *)p; +#endif +} + +/* +** Like free() but works for allocations obtained from sqlite3MemMalloc() +** or sqlite3MemRealloc(). +** +** For this low-level routine, we already know that pPrior!=0 since +** cases where pPrior==0 will have been intercepted and dealt with +** by higher-level routines. +*/ +static void sqlite3MemFree(void *pPrior){ +#ifdef SQLITE_MALLOCSIZE + SQLITE_FREE(pPrior); +#else + sqlite3_int64 *p = (sqlite3_int64*)pPrior; + assert( pPrior!=0 ); + p--; + SQLITE_FREE(p); +#endif +} + +/* +** Report the allocated size of a prior return from xMalloc() +** or xRealloc(). +*/ +static int sqlite3MemSize(void *pPrior){ +#ifdef SQLITE_MALLOCSIZE + assert( pPrior!=0 ); + return (int)SQLITE_MALLOCSIZE(pPrior); +#else + sqlite3_int64 *p; + assert( pPrior!=0 ); + p = (sqlite3_int64*)pPrior; + p--; + return (int)p[0]; +#endif +} + +/* +** Like realloc(). Resize an allocation previously obtained from +** sqlite3MemMalloc(). +** +** For this low-level interface, we know that pPrior!=0. Cases where +** pPrior==0 while have been intercepted by higher-level routine and +** redirected to xMalloc. Similarly, we know that nByte>0 because +** cases where nByte<=0 will have been intercepted by higher-level +** routines and redirected to xFree. +*/ +static void *sqlite3MemRealloc(void *pPrior, int nByte){ +#ifdef SQLITE_MALLOCSIZE + void *p = SQLITE_REALLOC(pPrior, nByte); + if( p==0 ){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_NOMEM, + "failed memory resize %u to %u bytes", + SQLITE_MALLOCSIZE(pPrior), nByte); + } + return p; +#else + sqlite3_int64 *p = (sqlite3_int64*)pPrior; + assert( pPrior!=0 && nByte>0 ); + assert( nByte==ROUND8(nByte) ); /* EV: R-46199-30249 */ + p--; + p = SQLITE_REALLOC(p, nByte+8 ); + if( p ){ + p[0] = nByte; + p++; + }else{ + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_NOMEM, + "failed memory resize %u to %u bytes", + sqlite3MemSize(pPrior), nByte); + } + return (void*)p; +#endif +} + +/* +** Round up a request size to the next valid allocation size. +*/ +static int sqlite3MemRoundup(int n){ + return ROUND8(n); +} + +/* +** Initialize this module. +*/ +static int sqlite3MemInit(void *NotUsed){ +#if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC) + int cpuCount; + size_t len; + if( _sqliteZone_ ){ + return SQLITE_OK; + } + len = sizeof(cpuCount); + /* One usually wants to use hw.activecpu for MT decisions, but not here */ + sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0); + if( cpuCount>1 ){ + /* defer MT decisions to system malloc */ + _sqliteZone_ = malloc_default_zone(); + }else{ + /* only 1 core, use our own zone to contention over global locks, + ** e.g. we have our own dedicated locks */ + _sqliteZone_ = malloc_create_zone(4096, 0); + malloc_set_zone_name(_sqliteZone_, "Sqlite_Heap"); + } +#endif /* defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC) */ + UNUSED_PARAMETER(NotUsed); + return SQLITE_OK; +} + +/* +** Deinitialize this module. +*/ +static void sqlite3MemShutdown(void *NotUsed){ + UNUSED_PARAMETER(NotUsed); + return; +} + +/* +** This routine is the only routine in this file with external linkage. +** +** Populate the low-level memory allocation function pointers in +** sqlite3GlobalConfig.m with pointers to the routines in this file. +*/ +SQLITE_PRIVATE void sqlite3MemSetDefault(void){ + static const sqlite3_mem_methods defaultMethods = { + sqlite3MemMalloc, + sqlite3MemFree, + sqlite3MemRealloc, + sqlite3MemSize, + sqlite3MemRoundup, + sqlite3MemInit, + sqlite3MemShutdown, + 0 + }; + sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods); +} + +#endif /* SQLITE_SYSTEM_MALLOC */ + +/************** End of mem1.c ************************************************/ +/************** Begin file mem2.c ********************************************/ +/* +** 2007 August 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains low-level memory allocation drivers for when +** SQLite will use the standard C-library malloc/realloc/free interface +** to obtain the memory it needs while adding lots of additional debugging +** information to each allocation in order to help detect and fix memory +** leaks and memory usage errors. +** +** This file contains implementations of the low-level memory allocation +** routines specified in the sqlite3_mem_methods object. +*/ +/* #include "sqliteInt.h" */ + +/* +** This version of the memory allocator is used only if the +** SQLITE_MEMDEBUG macro is defined +*/ +#ifdef SQLITE_MEMDEBUG + +/* +** The backtrace functionality is only available with GLIBC +*/ +#ifdef __GLIBC__ + extern int backtrace(void**,int); + extern void backtrace_symbols_fd(void*const*,int,int); +#else +# define backtrace(A,B) 1 +# define backtrace_symbols_fd(A,B,C) +#endif +/* #include */ + +/* +** Each memory allocation looks like this: +** +** ------------------------------------------------------------------------ +** | Title | backtrace pointers | MemBlockHdr | allocation | EndGuard | +** ------------------------------------------------------------------------ +** +** The application code sees only a pointer to the allocation. We have +** to back up from the allocation pointer to find the MemBlockHdr. The +** MemBlockHdr tells us the size of the allocation and the number of +** backtrace pointers. There is also a guard word at the end of the +** MemBlockHdr. +*/ +struct MemBlockHdr { + i64 iSize; /* Size of this allocation */ + struct MemBlockHdr *pNext, *pPrev; /* Linked list of all unfreed memory */ + char nBacktrace; /* Number of backtraces on this alloc */ + char nBacktraceSlots; /* Available backtrace slots */ + u8 nTitle; /* Bytes of title; includes '\0' */ + u8 eType; /* Allocation type code */ + int iForeGuard; /* Guard word for sanity */ +}; + +/* +** Guard words +*/ +#define FOREGUARD 0x80F5E153 +#define REARGUARD 0xE4676B53 + +/* +** Number of malloc size increments to track. +*/ +#define NCSIZE 1000 + +/* +** All of the static variables used by this module are collected +** into a single structure named "mem". This is to keep the +** static variables organized and to reduce namespace pollution +** when this module is combined with other in the amalgamation. +*/ +static struct { + + /* + ** Mutex to control access to the memory allocation subsystem. + */ + sqlite3_mutex *mutex; + + /* + ** Head and tail of a linked list of all outstanding allocations + */ + struct MemBlockHdr *pFirst; + struct MemBlockHdr *pLast; + + /* + ** The number of levels of backtrace to save in new allocations. + */ + int nBacktrace; + void (*xBacktrace)(int, int, void **); + + /* + ** Title text to insert in front of each block + */ + int nTitle; /* Bytes of zTitle to save. Includes '\0' and padding */ + char zTitle[100]; /* The title text */ + + /* + ** sqlite3MallocDisallow() increments the following counter. + ** sqlite3MallocAllow() decrements it. + */ + int disallow; /* Do not allow memory allocation */ + + /* + ** Gather statistics on the sizes of memory allocations. + ** nAlloc[i] is the number of allocation attempts of i*8 + ** bytes. i==NCSIZE is the number of allocation attempts for + ** sizes more than NCSIZE*8 bytes. + */ + int nAlloc[NCSIZE]; /* Total number of allocations */ + int nCurrent[NCSIZE]; /* Current number of allocations */ + int mxCurrent[NCSIZE]; /* Highwater mark for nCurrent */ + +} mem; + + +/* +** Adjust memory usage statistics +*/ +static void adjustStats(int iSize, int increment){ + int i = ROUND8(iSize)/8; + if( i>NCSIZE-1 ){ + i = NCSIZE - 1; + } + if( increment>0 ){ + mem.nAlloc[i]++; + mem.nCurrent[i]++; + if( mem.nCurrent[i]>mem.mxCurrent[i] ){ + mem.mxCurrent[i] = mem.nCurrent[i]; + } + }else{ + mem.nCurrent[i]--; + assert( mem.nCurrent[i]>=0 ); + } +} + +/* +** Given an allocation, find the MemBlockHdr for that allocation. +** +** This routine checks the guards at either end of the allocation and +** if they are incorrect it asserts. +*/ +static struct MemBlockHdr *sqlite3MemsysGetHeader(const void *pAllocation){ + struct MemBlockHdr *p; + int *pInt; + u8 *pU8; + int nReserve; + + p = (struct MemBlockHdr*)pAllocation; + p--; + assert( p->iForeGuard==(int)FOREGUARD ); + nReserve = ROUND8(p->iSize); + pInt = (int*)pAllocation; + pU8 = (u8*)pAllocation; + assert( pInt[nReserve/sizeof(int)]==(int)REARGUARD ); + /* This checks any of the "extra" bytes allocated due + ** to rounding up to an 8 byte boundary to ensure + ** they haven't been overwritten. + */ + while( nReserve-- > p->iSize ) assert( pU8[nReserve]==0x65 ); + return p; +} + +/* +** Return the number of bytes currently allocated at address p. +*/ +static int sqlite3MemSize(void *p){ + struct MemBlockHdr *pHdr; + if( !p ){ + return 0; + } + pHdr = sqlite3MemsysGetHeader(p); + return (int)pHdr->iSize; +} + +/* +** Initialize the memory allocation subsystem. +*/ +static int sqlite3MemInit(void *NotUsed){ + UNUSED_PARAMETER(NotUsed); + assert( (sizeof(struct MemBlockHdr)&7) == 0 ); + if( !sqlite3GlobalConfig.bMemstat ){ + /* If memory status is enabled, then the malloc.c wrapper will already + ** hold the STATIC_MEM mutex when the routines here are invoked. */ + mem.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); + } + return SQLITE_OK; +} + +/* +** Deinitialize the memory allocation subsystem. +*/ +static void sqlite3MemShutdown(void *NotUsed){ + UNUSED_PARAMETER(NotUsed); + mem.mutex = 0; +} + +/* +** Round up a request size to the next valid allocation size. +*/ +static int sqlite3MemRoundup(int n){ + return ROUND8(n); +} + +/* +** Fill a buffer with pseudo-random bytes. This is used to preset +** the content of a new memory allocation to unpredictable values and +** to clear the content of a freed allocation to unpredictable values. +*/ +static void randomFill(char *pBuf, int nByte){ + unsigned int x, y, r; + x = SQLITE_PTR_TO_INT(pBuf); + y = nByte | 1; + while( nByte >= 4 ){ + x = (x>>1) ^ (-(int)(x&1) & 0xd0000001); + y = y*1103515245 + 12345; + r = x ^ y; + *(int*)pBuf = r; + pBuf += 4; + nByte -= 4; + } + while( nByte-- > 0 ){ + x = (x>>1) ^ (-(int)(x&1) & 0xd0000001); + y = y*1103515245 + 12345; + r = x ^ y; + *(pBuf++) = r & 0xff; + } +} + +/* +** Allocate nByte bytes of memory. +*/ +static void *sqlite3MemMalloc(int nByte){ + struct MemBlockHdr *pHdr; + void **pBt; + char *z; + int *pInt; + void *p = 0; + int totalSize; + int nReserve; + sqlite3_mutex_enter(mem.mutex); + assert( mem.disallow==0 ); + nReserve = ROUND8(nByte); + totalSize = nReserve + sizeof(*pHdr) + sizeof(int) + + mem.nBacktrace*sizeof(void*) + mem.nTitle; + p = malloc(totalSize); + if( p ){ + z = p; + pBt = (void**)&z[mem.nTitle]; + pHdr = (struct MemBlockHdr*)&pBt[mem.nBacktrace]; + pHdr->pNext = 0; + pHdr->pPrev = mem.pLast; + if( mem.pLast ){ + mem.pLast->pNext = pHdr; + }else{ + mem.pFirst = pHdr; + } + mem.pLast = pHdr; + pHdr->iForeGuard = FOREGUARD; + pHdr->eType = MEMTYPE_HEAP; + pHdr->nBacktraceSlots = mem.nBacktrace; + pHdr->nTitle = mem.nTitle; + if( mem.nBacktrace ){ + void *aAddr[40]; + pHdr->nBacktrace = backtrace(aAddr, mem.nBacktrace+1)-1; + memcpy(pBt, &aAddr[1], pHdr->nBacktrace*sizeof(void*)); + assert(pBt[0]); + if( mem.xBacktrace ){ + mem.xBacktrace(nByte, pHdr->nBacktrace-1, &aAddr[1]); + } + }else{ + pHdr->nBacktrace = 0; + } + if( mem.nTitle ){ + memcpy(z, mem.zTitle, mem.nTitle); + } + pHdr->iSize = nByte; + adjustStats(nByte, +1); + pInt = (int*)&pHdr[1]; + pInt[nReserve/sizeof(int)] = REARGUARD; + randomFill((char*)pInt, nByte); + memset(((char*)pInt)+nByte, 0x65, nReserve-nByte); + p = (void*)pInt; + } + sqlite3_mutex_leave(mem.mutex); + return p; +} + +/* +** Free memory. +*/ +static void sqlite3MemFree(void *pPrior){ + struct MemBlockHdr *pHdr; + void **pBt; + char *z; + assert( sqlite3GlobalConfig.bMemstat || sqlite3GlobalConfig.bCoreMutex==0 + || mem.mutex!=0 ); + pHdr = sqlite3MemsysGetHeader(pPrior); + pBt = (void**)pHdr; + pBt -= pHdr->nBacktraceSlots; + sqlite3_mutex_enter(mem.mutex); + if( pHdr->pPrev ){ + assert( pHdr->pPrev->pNext==pHdr ); + pHdr->pPrev->pNext = pHdr->pNext; + }else{ + assert( mem.pFirst==pHdr ); + mem.pFirst = pHdr->pNext; + } + if( pHdr->pNext ){ + assert( pHdr->pNext->pPrev==pHdr ); + pHdr->pNext->pPrev = pHdr->pPrev; + }else{ + assert( mem.pLast==pHdr ); + mem.pLast = pHdr->pPrev; + } + z = (char*)pBt; + z -= pHdr->nTitle; + adjustStats((int)pHdr->iSize, -1); + randomFill(z, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) + + (int)pHdr->iSize + sizeof(int) + pHdr->nTitle); + free(z); + sqlite3_mutex_leave(mem.mutex); +} + +/* +** Change the size of an existing memory allocation. +** +** For this debugging implementation, we *always* make a copy of the +** allocation into a new place in memory. In this way, if the +** higher level code is using pointer to the old allocation, it is +** much more likely to break and we are much more liking to find +** the error. +*/ +static void *sqlite3MemRealloc(void *pPrior, int nByte){ + struct MemBlockHdr *pOldHdr; + void *pNew; + assert( mem.disallow==0 ); + assert( (nByte & 7)==0 ); /* EV: R-46199-30249 */ + pOldHdr = sqlite3MemsysGetHeader(pPrior); + pNew = sqlite3MemMalloc(nByte); + if( pNew ){ + memcpy(pNew, pPrior, (int)(nByteiSize ? nByte : pOldHdr->iSize)); + if( nByte>pOldHdr->iSize ){ + randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - (int)pOldHdr->iSize); + } + sqlite3MemFree(pPrior); + } + return pNew; +} + +/* +** Populate the low-level memory allocation function pointers in +** sqlite3GlobalConfig.m with pointers to the routines in this file. +*/ +SQLITE_PRIVATE void sqlite3MemSetDefault(void){ + static const sqlite3_mem_methods defaultMethods = { + sqlite3MemMalloc, + sqlite3MemFree, + sqlite3MemRealloc, + sqlite3MemSize, + sqlite3MemRoundup, + sqlite3MemInit, + sqlite3MemShutdown, + 0 + }; + sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods); +} + +/* +** Set the "type" of an allocation. +*/ +SQLITE_PRIVATE void sqlite3MemdebugSetType(void *p, u8 eType){ + if( p && sqlite3GlobalConfig.m.xFree==sqlite3MemFree ){ + struct MemBlockHdr *pHdr; + pHdr = sqlite3MemsysGetHeader(p); + assert( pHdr->iForeGuard==FOREGUARD ); + pHdr->eType = eType; + } +} + +/* +** Return TRUE if the mask of type in eType matches the type of the +** allocation p. Also return true if p==NULL. +** +** This routine is designed for use within an assert() statement, to +** verify the type of an allocation. For example: +** +** assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); +*/ +SQLITE_PRIVATE int sqlite3MemdebugHasType(const void *p, u8 eType){ + int rc = 1; + if( p && sqlite3GlobalConfig.m.xFree==sqlite3MemFree ){ + struct MemBlockHdr *pHdr; + pHdr = sqlite3MemsysGetHeader(p); + assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */ + if( (pHdr->eType&eType)==0 ){ + rc = 0; + } + } + return rc; +} + +/* +** Return TRUE if the mask of type in eType matches no bits of the type of the +** allocation p. Also return true if p==NULL. +** +** This routine is designed for use within an assert() statement, to +** verify the type of an allocation. For example: +** +** assert( sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); +*/ +SQLITE_PRIVATE int sqlite3MemdebugNoType(const void *p, u8 eType){ + int rc = 1; + if( p && sqlite3GlobalConfig.m.xFree==sqlite3MemFree ){ + struct MemBlockHdr *pHdr; + pHdr = sqlite3MemsysGetHeader(p); + assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */ + if( (pHdr->eType&eType)!=0 ){ + rc = 0; + } + } + return rc; +} + +/* +** Set the number of backtrace levels kept for each allocation. +** A value of zero turns off backtracing. The number is always rounded +** up to a multiple of 2. +*/ +SQLITE_PRIVATE void sqlite3MemdebugBacktrace(int depth){ + if( depth<0 ){ depth = 0; } + if( depth>20 ){ depth = 20; } + depth = (depth+1)&0xfe; + mem.nBacktrace = depth; +} + +SQLITE_PRIVATE void sqlite3MemdebugBacktraceCallback(void (*xBacktrace)(int, int, void **)){ + mem.xBacktrace = xBacktrace; +} + +/* +** Set the title string for subsequent allocations. +*/ +SQLITE_PRIVATE void sqlite3MemdebugSettitle(const char *zTitle){ + unsigned int n = sqlite3Strlen30(zTitle) + 1; + sqlite3_mutex_enter(mem.mutex); + if( n>=sizeof(mem.zTitle) ) n = sizeof(mem.zTitle)-1; + memcpy(mem.zTitle, zTitle, n); + mem.zTitle[n] = 0; + mem.nTitle = ROUND8(n); + sqlite3_mutex_leave(mem.mutex); +} + +SQLITE_PRIVATE void sqlite3MemdebugSync(){ + struct MemBlockHdr *pHdr; + for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){ + void **pBt = (void**)pHdr; + pBt -= pHdr->nBacktraceSlots; + mem.xBacktrace((int)pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]); + } +} + +/* +** Open the file indicated and write a log of all unfreed memory +** allocations into that log. +*/ +SQLITE_PRIVATE void sqlite3MemdebugDump(const char *zFilename){ + FILE *out; + struct MemBlockHdr *pHdr; + void **pBt; + int i; + out = fopen(zFilename, "w"); + if( out==0 ){ + fprintf(stderr, "** Unable to output memory debug output log: %s **\n", + zFilename); + return; + } + for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){ + char *z = (char*)pHdr; + z -= pHdr->nBacktraceSlots*sizeof(void*) + pHdr->nTitle; + fprintf(out, "**** %lld bytes at %p from %s ****\n", + pHdr->iSize, &pHdr[1], pHdr->nTitle ? z : "???"); + if( pHdr->nBacktrace ){ + fflush(out); + pBt = (void**)pHdr; + pBt -= pHdr->nBacktraceSlots; + backtrace_symbols_fd(pBt, pHdr->nBacktrace, fileno(out)); + fprintf(out, "\n"); + } + } + fprintf(out, "COUNTS:\n"); + for(i=0; i=1 ); + size = mem3.aPool[i-1].u.hdr.size4x/4; + assert( size==mem3.aPool[i+size-1].u.hdr.prevSize ); + assert( size>=2 ); + if( size <= MX_SMALL ){ + memsys3UnlinkFromList(i, &mem3.aiSmall[size-2]); + }else{ + hash = size % N_HASH; + memsys3UnlinkFromList(i, &mem3.aiHash[hash]); + } +} + +/* +** Link the chunk at mem3.aPool[i] so that is on the list rooted +** at *pRoot. +*/ +static void memsys3LinkIntoList(u32 i, u32 *pRoot){ + assert( sqlite3_mutex_held(mem3.mutex) ); + mem3.aPool[i].u.list.next = *pRoot; + mem3.aPool[i].u.list.prev = 0; + if( *pRoot ){ + mem3.aPool[*pRoot].u.list.prev = i; + } + *pRoot = i; +} + +/* +** Link the chunk at index i into either the appropriate +** small chunk list, or into the large chunk hash table. +*/ +static void memsys3Link(u32 i){ + u32 size, hash; + assert( sqlite3_mutex_held(mem3.mutex) ); + assert( i>=1 ); + assert( (mem3.aPool[i-1].u.hdr.size4x & 1)==0 ); + size = mem3.aPool[i-1].u.hdr.size4x/4; + assert( size==mem3.aPool[i+size-1].u.hdr.prevSize ); + assert( size>=2 ); + if( size <= MX_SMALL ){ + memsys3LinkIntoList(i, &mem3.aiSmall[size-2]); + }else{ + hash = size % N_HASH; + memsys3LinkIntoList(i, &mem3.aiHash[hash]); + } +} + +/* +** If the STATIC_MEM mutex is not already held, obtain it now. The mutex +** will already be held (obtained by code in malloc.c) if +** sqlite3GlobalConfig.bMemStat is true. +*/ +static void memsys3Enter(void){ + if( sqlite3GlobalConfig.bMemstat==0 && mem3.mutex==0 ){ + mem3.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); + } + sqlite3_mutex_enter(mem3.mutex); +} +static void memsys3Leave(void){ + sqlite3_mutex_leave(mem3.mutex); +} + +/* +** Called when we are unable to satisfy an allocation of nBytes. +*/ +static void memsys3OutOfMemory(int nByte){ + if( !mem3.alarmBusy ){ + mem3.alarmBusy = 1; + assert( sqlite3_mutex_held(mem3.mutex) ); + sqlite3_mutex_leave(mem3.mutex); + sqlite3_release_memory(nByte); + sqlite3_mutex_enter(mem3.mutex); + mem3.alarmBusy = 0; + } +} + + +/* +** Chunk i is a free chunk that has been unlinked. Adjust its +** size parameters for check-out and return a pointer to the +** user portion of the chunk. +*/ +static void *memsys3Checkout(u32 i, u32 nBlock){ + u32 x; + assert( sqlite3_mutex_held(mem3.mutex) ); + assert( i>=1 ); + assert( mem3.aPool[i-1].u.hdr.size4x/4==nBlock ); + assert( mem3.aPool[i+nBlock-1].u.hdr.prevSize==nBlock ); + x = mem3.aPool[i-1].u.hdr.size4x; + mem3.aPool[i-1].u.hdr.size4x = nBlock*4 | 1 | (x&2); + mem3.aPool[i+nBlock-1].u.hdr.prevSize = nBlock; + mem3.aPool[i+nBlock-1].u.hdr.size4x |= 2; + return &mem3.aPool[i]; +} + +/* +** Carve a piece off of the end of the mem3.iKeyBlk free chunk. +** Return a pointer to the new allocation. Or, if the key chunk +** is not large enough, return 0. +*/ +static void *memsys3FromKeyBlk(u32 nBlock){ + assert( sqlite3_mutex_held(mem3.mutex) ); + assert( mem3.szKeyBlk>=nBlock ); + if( nBlock>=mem3.szKeyBlk-1 ){ + /* Use the entire key chunk */ + void *p = memsys3Checkout(mem3.iKeyBlk, mem3.szKeyBlk); + mem3.iKeyBlk = 0; + mem3.szKeyBlk = 0; + mem3.mnKeyBlk = 0; + return p; + }else{ + /* Split the key block. Return the tail. */ + u32 newi, x; + newi = mem3.iKeyBlk + mem3.szKeyBlk - nBlock; + assert( newi > mem3.iKeyBlk+1 ); + mem3.aPool[mem3.iKeyBlk+mem3.szKeyBlk-1].u.hdr.prevSize = nBlock; + mem3.aPool[mem3.iKeyBlk+mem3.szKeyBlk-1].u.hdr.size4x |= 2; + mem3.aPool[newi-1].u.hdr.size4x = nBlock*4 + 1; + mem3.szKeyBlk -= nBlock; + mem3.aPool[newi-1].u.hdr.prevSize = mem3.szKeyBlk; + x = mem3.aPool[mem3.iKeyBlk-1].u.hdr.size4x & 2; + mem3.aPool[mem3.iKeyBlk-1].u.hdr.size4x = mem3.szKeyBlk*4 | x; + if( mem3.szKeyBlk < mem3.mnKeyBlk ){ + mem3.mnKeyBlk = mem3.szKeyBlk; + } + return (void*)&mem3.aPool[newi]; + } +} + +/* +** *pRoot is the head of a list of free chunks of the same size +** or same size hash. In other words, *pRoot is an entry in either +** mem3.aiSmall[] or mem3.aiHash[]. +** +** This routine examines all entries on the given list and tries +** to coalesce each entries with adjacent free chunks. +** +** If it sees a chunk that is larger than mem3.iKeyBlk, it replaces +** the current mem3.iKeyBlk with the new larger chunk. In order for +** this mem3.iKeyBlk replacement to work, the key chunk must be +** linked into the hash tables. That is not the normal state of +** affairs, of course. The calling routine must link the key +** chunk before invoking this routine, then must unlink the (possibly +** changed) key chunk once this routine has finished. +*/ +static void memsys3Merge(u32 *pRoot){ + u32 iNext, prev, size, i, x; + + assert( sqlite3_mutex_held(mem3.mutex) ); + for(i=*pRoot; i>0; i=iNext){ + iNext = mem3.aPool[i].u.list.next; + size = mem3.aPool[i-1].u.hdr.size4x; + assert( (size&1)==0 ); + if( (size&2)==0 ){ + memsys3UnlinkFromList(i, pRoot); + assert( i > mem3.aPool[i-1].u.hdr.prevSize ); + prev = i - mem3.aPool[i-1].u.hdr.prevSize; + if( prev==iNext ){ + iNext = mem3.aPool[prev].u.list.next; + } + memsys3Unlink(prev); + size = i + size/4 - prev; + x = mem3.aPool[prev-1].u.hdr.size4x & 2; + mem3.aPool[prev-1].u.hdr.size4x = size*4 | x; + mem3.aPool[prev+size-1].u.hdr.prevSize = size; + memsys3Link(prev); + i = prev; + }else{ + size /= 4; + } + if( size>mem3.szKeyBlk ){ + mem3.iKeyBlk = i; + mem3.szKeyBlk = size; + } + } +} + +/* +** Return a block of memory of at least nBytes in size. +** Return NULL if unable. +** +** This function assumes that the necessary mutexes, if any, are +** already held by the caller. Hence "Unsafe". +*/ +static void *memsys3MallocUnsafe(int nByte){ + u32 i; + u32 nBlock; + u32 toFree; + + assert( sqlite3_mutex_held(mem3.mutex) ); + assert( sizeof(Mem3Block)==8 ); + if( nByte<=12 ){ + nBlock = 2; + }else{ + nBlock = (nByte + 11)/8; + } + assert( nBlock>=2 ); + + /* STEP 1: + ** Look for an entry of the correct size in either the small + ** chunk table or in the large chunk hash table. This is + ** successful most of the time (about 9 times out of 10). + */ + if( nBlock <= MX_SMALL ){ + i = mem3.aiSmall[nBlock-2]; + if( i>0 ){ + memsys3UnlinkFromList(i, &mem3.aiSmall[nBlock-2]); + return memsys3Checkout(i, nBlock); + } + }else{ + int hash = nBlock % N_HASH; + for(i=mem3.aiHash[hash]; i>0; i=mem3.aPool[i].u.list.next){ + if( mem3.aPool[i-1].u.hdr.size4x/4==nBlock ){ + memsys3UnlinkFromList(i, &mem3.aiHash[hash]); + return memsys3Checkout(i, nBlock); + } + } + } + + /* STEP 2: + ** Try to satisfy the allocation by carving a piece off of the end + ** of the key chunk. This step usually works if step 1 fails. + */ + if( mem3.szKeyBlk>=nBlock ){ + return memsys3FromKeyBlk(nBlock); + } + + + /* STEP 3: + ** Loop through the entire memory pool. Coalesce adjacent free + ** chunks. Recompute the key chunk as the largest free chunk. + ** Then try again to satisfy the allocation by carving a piece off + ** of the end of the key chunk. This step happens very + ** rarely (we hope!) + */ + for(toFree=nBlock*16; toFree<(mem3.nPool*16); toFree *= 2){ + memsys3OutOfMemory(toFree); + if( mem3.iKeyBlk ){ + memsys3Link(mem3.iKeyBlk); + mem3.iKeyBlk = 0; + mem3.szKeyBlk = 0; + } + for(i=0; i=nBlock ){ + return memsys3FromKeyBlk(nBlock); + } + } + } + + /* If none of the above worked, then we fail. */ + return 0; +} + +/* +** Free an outstanding memory allocation. +** +** This function assumes that the necessary mutexes, if any, are +** already held by the caller. Hence "Unsafe". +*/ +static void memsys3FreeUnsafe(void *pOld){ + Mem3Block *p = (Mem3Block*)pOld; + int i; + u32 size, x; + assert( sqlite3_mutex_held(mem3.mutex) ); + assert( p>mem3.aPool && p<&mem3.aPool[mem3.nPool] ); + i = p - mem3.aPool; + assert( (mem3.aPool[i-1].u.hdr.size4x&1)==1 ); + size = mem3.aPool[i-1].u.hdr.size4x/4; + assert( i+size<=mem3.nPool+1 ); + mem3.aPool[i-1].u.hdr.size4x &= ~1; + mem3.aPool[i+size-1].u.hdr.prevSize = size; + mem3.aPool[i+size-1].u.hdr.size4x &= ~2; + memsys3Link(i); + + /* Try to expand the key using the newly freed chunk */ + if( mem3.iKeyBlk ){ + while( (mem3.aPool[mem3.iKeyBlk-1].u.hdr.size4x&2)==0 ){ + size = mem3.aPool[mem3.iKeyBlk-1].u.hdr.prevSize; + mem3.iKeyBlk -= size; + mem3.szKeyBlk += size; + memsys3Unlink(mem3.iKeyBlk); + x = mem3.aPool[mem3.iKeyBlk-1].u.hdr.size4x & 2; + mem3.aPool[mem3.iKeyBlk-1].u.hdr.size4x = mem3.szKeyBlk*4 | x; + mem3.aPool[mem3.iKeyBlk+mem3.szKeyBlk-1].u.hdr.prevSize = mem3.szKeyBlk; + } + x = mem3.aPool[mem3.iKeyBlk-1].u.hdr.size4x & 2; + while( (mem3.aPool[mem3.iKeyBlk+mem3.szKeyBlk-1].u.hdr.size4x&1)==0 ){ + memsys3Unlink(mem3.iKeyBlk+mem3.szKeyBlk); + mem3.szKeyBlk += mem3.aPool[mem3.iKeyBlk+mem3.szKeyBlk-1].u.hdr.size4x/4; + mem3.aPool[mem3.iKeyBlk-1].u.hdr.size4x = mem3.szKeyBlk*4 | x; + mem3.aPool[mem3.iKeyBlk+mem3.szKeyBlk-1].u.hdr.prevSize = mem3.szKeyBlk; + } + } +} + +/* +** Return the size of an outstanding allocation, in bytes. The +** size returned omits the 8-byte header overhead. This only +** works for chunks that are currently checked out. +*/ +static int memsys3Size(void *p){ + Mem3Block *pBlock; + assert( p!=0 ); + pBlock = (Mem3Block*)p; + assert( (pBlock[-1].u.hdr.size4x&1)!=0 ); + return (pBlock[-1].u.hdr.size4x&~3)*2 - 4; +} + +/* +** Round up a request size to the next valid allocation size. +*/ +static int memsys3Roundup(int n){ + if( n<=12 ){ + return 12; + }else{ + return ((n+11)&~7) - 4; + } +} + +/* +** Allocate nBytes of memory. +*/ +static void *memsys3Malloc(int nBytes){ + sqlite3_int64 *p; + assert( nBytes>0 ); /* malloc.c filters out 0 byte requests */ + memsys3Enter(); + p = memsys3MallocUnsafe(nBytes); + memsys3Leave(); + return (void*)p; +} + +/* +** Free memory. +*/ +static void memsys3Free(void *pPrior){ + assert( pPrior ); + memsys3Enter(); + memsys3FreeUnsafe(pPrior); + memsys3Leave(); +} + +/* +** Change the size of an existing memory allocation +*/ +static void *memsys3Realloc(void *pPrior, int nBytes){ + int nOld; + void *p; + if( pPrior==0 ){ + return sqlite3_malloc(nBytes); + } + if( nBytes<=0 ){ + sqlite3_free(pPrior); + return 0; + } + nOld = memsys3Size(pPrior); + if( nBytes<=nOld && nBytes>=nOld-128 ){ + return pPrior; + } + memsys3Enter(); + p = memsys3MallocUnsafe(nBytes); + if( p ){ + if( nOld>1)!=(size&1) ){ + fprintf(out, "%p tail checkout bit is incorrect\n", &mem3.aPool[i]); + assert( 0 ); + break; + } + if( size&1 ){ + fprintf(out, "%p %6d bytes checked out\n", &mem3.aPool[i], (size/4)*8-8); + }else{ + fprintf(out, "%p %6d bytes free%s\n", &mem3.aPool[i], (size/4)*8-8, + i==mem3.iKeyBlk ? " **key**" : ""); + } + } + for(i=0; i0; j=mem3.aPool[j].u.list.next){ + fprintf(out, " %p(%d)", &mem3.aPool[j], + (mem3.aPool[j-1].u.hdr.size4x/4)*8-8); + } + fprintf(out, "\n"); + } + for(i=0; i0; j=mem3.aPool[j].u.list.next){ + fprintf(out, " %p(%d)", &mem3.aPool[j], + (mem3.aPool[j-1].u.hdr.size4x/4)*8-8); + } + fprintf(out, "\n"); + } + fprintf(out, "key=%d\n", mem3.iKeyBlk); + fprintf(out, "nowUsed=%d\n", mem3.nPool*8 - mem3.szKeyBlk*8); + fprintf(out, "mxUsed=%d\n", mem3.nPool*8 - mem3.mnKeyBlk*8); + sqlite3_mutex_leave(mem3.mutex); + if( out==stdout ){ + fflush(stdout); + }else{ + fclose(out); + } +#else + UNUSED_PARAMETER(zFilename); +#endif +} + +/* +** This routine is the only routine in this file with external +** linkage. +** +** Populate the low-level memory allocation function pointers in +** sqlite3GlobalConfig.m with pointers to the routines in this file. The +** arguments specify the block of memory to manage. +** +** This routine is only called by sqlite3_config(), and therefore +** is not required to be threadsafe (it is not). +*/ +SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void){ + static const sqlite3_mem_methods mempoolMethods = { + memsys3Malloc, + memsys3Free, + memsys3Realloc, + memsys3Size, + memsys3Roundup, + memsys3Init, + memsys3Shutdown, + 0 + }; + return &mempoolMethods; +} + +#endif /* SQLITE_ENABLE_MEMSYS3 */ + +/************** End of mem3.c ************************************************/ +/************** Begin file mem5.c ********************************************/ +/* +** 2007 October 14 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains the C functions that implement a memory +** allocation subsystem for use by SQLite. +** +** This version of the memory allocation subsystem omits all +** use of malloc(). The application gives SQLite a block of memory +** before calling sqlite3_initialize() from which allocations +** are made and returned by the xMalloc() and xRealloc() +** implementations. Once sqlite3_initialize() has been called, +** the amount of memory available to SQLite is fixed and cannot +** be changed. +** +** This version of the memory allocation subsystem is included +** in the build only if SQLITE_ENABLE_MEMSYS5 is defined. +** +** This memory allocator uses the following algorithm: +** +** 1. All memory allocation sizes are rounded up to a power of 2. +** +** 2. If two adjacent free blocks are the halves of a larger block, +** then the two blocks are coalesced into the single larger block. +** +** 3. New memory is allocated from the first available free block. +** +** This algorithm is described in: J. M. Robson. "Bounds for Some Functions +** Concerning Dynamic Storage Allocation". Journal of the Association for +** Computing Machinery, Volume 21, Number 8, July 1974, pages 491-499. +** +** Let n be the size of the largest allocation divided by the minimum +** allocation size (after rounding all sizes up to a power of 2.) Let M +** be the maximum amount of memory ever outstanding at one time. Let +** N be the total amount of memory available for allocation. Robson +** proved that this memory allocator will never breakdown due to +** fragmentation as long as the following constraint holds: +** +** N >= M*(1 + log2(n)/2) - n + 1 +** +** The sqlite3_status() logic tracks the maximum values of n and M so +** that an application can, at any time, verify this constraint. +*/ +/* #include "sqliteInt.h" */ + +/* +** This version of the memory allocator is used only when +** SQLITE_ENABLE_MEMSYS5 is defined. +*/ +#ifdef SQLITE_ENABLE_MEMSYS5 + +/* +** A minimum allocation is an instance of the following structure. +** Larger allocations are an array of these structures where the +** size of the array is a power of 2. +** +** The size of this object must be a power of two. That fact is +** verified in memsys5Init(). +*/ +typedef struct Mem5Link Mem5Link; +struct Mem5Link { + int next; /* Index of next free chunk */ + int prev; /* Index of previous free chunk */ +}; + +/* +** Maximum size of any allocation is ((1<=0 && i=0 && iLogsize<=LOGMAX ); + assert( (mem5.aCtrl[i] & CTRL_LOGSIZE)==iLogsize ); + + next = MEM5LINK(i)->next; + prev = MEM5LINK(i)->prev; + if( prev<0 ){ + mem5.aiFreelist[iLogsize] = next; + }else{ + MEM5LINK(prev)->next = next; + } + if( next>=0 ){ + MEM5LINK(next)->prev = prev; + } +} + +/* +** Link the chunk at mem5.aPool[i] so that is on the iLogsize +** free list. +*/ +static void memsys5Link(int i, int iLogsize){ + int x; + assert( sqlite3_mutex_held(mem5.mutex) ); + assert( i>=0 && i=0 && iLogsize<=LOGMAX ); + assert( (mem5.aCtrl[i] & CTRL_LOGSIZE)==iLogsize ); + + x = MEM5LINK(i)->next = mem5.aiFreelist[iLogsize]; + MEM5LINK(i)->prev = -1; + if( x>=0 ){ + assert( xprev = i; + } + mem5.aiFreelist[iLogsize] = i; +} + +/* +** Obtain or release the mutex needed to access global data structures. +*/ +static void memsys5Enter(void){ + sqlite3_mutex_enter(mem5.mutex); +} +static void memsys5Leave(void){ + sqlite3_mutex_leave(mem5.mutex); +} + +/* +** Return the size of an outstanding allocation, in bytes. +** This only works for chunks that are currently checked out. +*/ +static int memsys5Size(void *p){ + int iSize, i; + assert( p!=0 ); + i = (int)(((u8 *)p-mem5.zPool)/mem5.szAtom); + assert( i>=0 && i0 ); + + /* No more than 1GiB per allocation */ + if( nByte > 0x40000000 ) return 0; + +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + /* Keep track of the maximum allocation request. Even unfulfilled + ** requests are counted */ + if( (u32)nByte>mem5.maxRequest ){ + mem5.maxRequest = nByte; + } +#endif + + + /* Round nByte up to the next valid power of two */ + for(iFullSz=mem5.szAtom,iLogsize=0; iFullSzLOGMAX ){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes", nByte); + return 0; + } + i = mem5.aiFreelist[iBin]; + memsys5Unlink(i, iBin); + while( iBin>iLogsize ){ + int newSize; + + iBin--; + newSize = 1 << iBin; + mem5.aCtrl[i+newSize] = CTRL_FREE | iBin; + memsys5Link(i+newSize, iBin); + } + mem5.aCtrl[i] = iLogsize; + +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + /* Update allocator performance statistics. */ + mem5.nAlloc++; + mem5.totalAlloc += iFullSz; + mem5.totalExcess += iFullSz - nByte; + mem5.currentCount++; + mem5.currentOut += iFullSz; + if( mem5.maxCount=0 && iBlock0 ); + assert( mem5.currentOut>=(size*mem5.szAtom) ); + mem5.currentCount--; + mem5.currentOut -= size*mem5.szAtom; + assert( mem5.currentOut>0 || mem5.currentCount==0 ); + assert( mem5.currentCount>0 || mem5.currentOut==0 ); +#endif + + mem5.aCtrl[iBlock] = CTRL_FREE | iLogsize; + while( ALWAYS(iLogsize>iLogsize) & 1 ){ + iBuddy = iBlock - size; + assert( iBuddy>=0 ); + }else{ + iBuddy = iBlock + size; + if( iBuddy>=mem5.nBlock ) break; + } + if( mem5.aCtrl[iBuddy]!=(CTRL_FREE | iLogsize) ) break; + memsys5Unlink(iBuddy, iLogsize); + iLogsize++; + if( iBuddy0 ){ + memsys5Enter(); + p = memsys5MallocUnsafe(nBytes); + memsys5Leave(); + } + return (void*)p; +} + +/* +** Free memory. +** +** The outer layer memory allocator prevents this routine from +** being called with pPrior==0. +*/ +static void memsys5Free(void *pPrior){ + assert( pPrior!=0 ); + memsys5Enter(); + memsys5FreeUnsafe(pPrior); + memsys5Leave(); +} + +/* +** Change the size of an existing memory allocation. +** +** The outer layer memory allocator prevents this routine from +** being called with pPrior==0. +** +** nBytes is always a value obtained from a prior call to +** memsys5Round(). Hence nBytes is always a non-negative power +** of two. If nBytes==0 that means that an oversize allocation +** (an allocation larger than 0x40000000) was requested and this +** routine should return 0 without freeing pPrior. +*/ +static void *memsys5Realloc(void *pPrior, int nBytes){ + int nOld; + void *p; + assert( pPrior!=0 ); + assert( (nBytes&(nBytes-1))==0 ); /* EV: R-46199-30249 */ + assert( nBytes>=0 ); + if( nBytes==0 ){ + return 0; + } + nOld = memsys5Size(pPrior); + if( nBytes<=nOld ){ + return pPrior; + } + p = memsys5Malloc(nBytes); + if( p ){ + memcpy(p, pPrior, nOld); + memsys5Free(pPrior); + } + return p; +} + +/* +** Round up a request size to the next valid allocation size. If +** the allocation is too large to be handled by this allocation system, +** return 0. +** +** All allocations must be a power of two and must be expressed by a +** 32-bit signed integer. Hence the largest allocation is 0x40000000 +** or 1073741824 bytes. +*/ +static int memsys5Roundup(int n){ + int iFullSz; + if( n<=mem5.szAtom*2 ){ + if( n<=mem5.szAtom ) return mem5.szAtom; + return mem5.szAtom*2; + } + if( n>0x10000000 ){ + if( n>0x40000000 ) return 0; + if( n>0x20000000 ) return 0x40000000; + return 0x20000000; + } + for(iFullSz=mem5.szAtom*8; iFullSz=(i64)n ) return iFullSz/2; + return iFullSz; +} + +/* +** Return the ceiling of the logarithm base 2 of iValue. +** +** Examples: memsys5Log(1) -> 0 +** memsys5Log(2) -> 1 +** memsys5Log(4) -> 2 +** memsys5Log(5) -> 3 +** memsys5Log(8) -> 3 +** memsys5Log(9) -> 4 +*/ +static int memsys5Log(int iValue){ + int iLog; + for(iLog=0; (iLog<(int)((sizeof(int)*8)-1)) && (1<mem5.szAtom ){ + mem5.szAtom = mem5.szAtom << 1; + } + + mem5.nBlock = (nByte / (mem5.szAtom+sizeof(u8))); + mem5.zPool = zByte; + mem5.aCtrl = (u8 *)&mem5.zPool[mem5.nBlock*mem5.szAtom]; + + for(ii=0; ii<=LOGMAX; ii++){ + mem5.aiFreelist[ii] = -1; + } + + iOffset = 0; + for(ii=LOGMAX; ii>=0; ii--){ + int nAlloc = (1<mem5.nBlock); + } + + /* If a mutex is required for normal operation, allocate one */ + if( sqlite3GlobalConfig.bMemstat==0 ){ + mem5.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); + } + + return SQLITE_OK; +} + +/* +** Deinitialize this module. +*/ +static void memsys5Shutdown(void *NotUsed){ + UNUSED_PARAMETER(NotUsed); + mem5.mutex = 0; + return; +} + +#ifdef SQLITE_TEST +/* +** Open the file indicated and write a log of all unfreed memory +** allocations into that log. +*/ +SQLITE_PRIVATE void sqlite3Memsys5Dump(const char *zFilename){ + FILE *out; + int i, j, n; + int nMinLog; + + if( zFilename==0 || zFilename[0]==0 ){ + out = stdout; + }else{ + out = fopen(zFilename, "w"); + if( out==0 ){ + fprintf(stderr, "** Unable to output memory debug output log: %s **\n", + zFilename); + return; + } + } + memsys5Enter(); + nMinLog = memsys5Log(mem5.szAtom); + for(i=0; i<=LOGMAX && i+nMinLog<32; i++){ + for(n=0, j=mem5.aiFreelist[i]; j>=0; j = MEM5LINK(j)->next, n++){} + fprintf(out, "freelist items of size %d: %d\n", mem5.szAtom << i, n); + } + fprintf(out, "mem5.nAlloc = %llu\n", mem5.nAlloc); + fprintf(out, "mem5.totalAlloc = %llu\n", mem5.totalAlloc); + fprintf(out, "mem5.totalExcess = %llu\n", mem5.totalExcess); + fprintf(out, "mem5.currentOut = %u\n", mem5.currentOut); + fprintf(out, "mem5.currentCount = %u\n", mem5.currentCount); + fprintf(out, "mem5.maxOut = %u\n", mem5.maxOut); + fprintf(out, "mem5.maxCount = %u\n", mem5.maxCount); + fprintf(out, "mem5.maxRequest = %u\n", mem5.maxRequest); + memsys5Leave(); + if( out==stdout ){ + fflush(stdout); + }else{ + fclose(out); + } +} +#endif + +/* +** This routine is the only routine in this file with external +** linkage. It returns a pointer to a static sqlite3_mem_methods +** struct populated with the memsys5 methods. +*/ +SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys5(void){ + static const sqlite3_mem_methods memsys5Methods = { + memsys5Malloc, + memsys5Free, + memsys5Realloc, + memsys5Size, + memsys5Roundup, + memsys5Init, + memsys5Shutdown, + 0 + }; + return &memsys5Methods; +} + +#endif /* SQLITE_ENABLE_MEMSYS5 */ + +/************** End of mem5.c ************************************************/ +/************** Begin file mutex.c *******************************************/ +/* +** 2007 August 14 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains the C functions that implement mutexes. +** +** This file contains code that is common across all mutex implementations. +*/ +/* #include "sqliteInt.h" */ + +#if defined(SQLITE_DEBUG) && !defined(SQLITE_MUTEX_OMIT) +/* +** For debugging purposes, record when the mutex subsystem is initialized +** and uninitialized so that we can assert() if there is an attempt to +** allocate a mutex while the system is uninitialized. +*/ +static SQLITE_WSD int mutexIsInit = 0; +#endif /* SQLITE_DEBUG && !defined(SQLITE_MUTEX_OMIT) */ + + +#ifndef SQLITE_MUTEX_OMIT + +#ifdef SQLITE_THREAD_MISUSE_WARNINGS +/* +** This block (enclosed by SQLITE_THREAD_MISUSE_WARNINGS) contains +** the implementation of a wrapper around the system default mutex +** implementation (sqlite3DefaultMutex()). +** +** Most calls are passed directly through to the underlying default +** mutex implementation. Except, if a mutex is configured by calling +** sqlite3MutexWarnOnContention() on it, then if contention is ever +** encountered within xMutexEnter() then a warning is emitted via +** sqlite3_log(). Furthermore, if SQLITE_THREAD_MISUSE_ABORT is +** defined then abort() is called after the sqlite3_log() warning. +** +** This type of mutex is used on the database handle mutex when testing +** apps that usually use SQLITE_CONFIG_MULTITHREAD mode. A failure +** indicates that the app ought to be using SQLITE_OPEN_FULLMUTEX or +** similar because it is trying to use the same database handle from +** two different connections at the same time. +*/ + +/* +** Type for all mutexes used when SQLITE_THREAD_MISUSE_WARNINGS +** is defined. Variable CheckMutex.mutex is a pointer to the real mutex +** allocated by the system mutex implementation. Variable iType is usually set +** to the type of mutex requested - SQLITE_MUTEX_RECURSIVE, SQLITE_MUTEX_FAST +** or one of the static mutex identifiers. Or, if this is a recursive mutex +** that has been configured using sqlite3MutexWarnOnContention(), it is +** set to SQLITE_MUTEX_WARNONCONTENTION. +*/ +typedef struct CheckMutex CheckMutex; +struct CheckMutex { + int iType; + sqlite3_mutex *mutex; +}; + +#define SQLITE_MUTEX_WARNONCONTENTION (-1) + +/* +** Pointer to real mutex methods object used by the CheckMutex +** implementation. Set by checkMutexInit(). +*/ +static SQLITE_WSD const sqlite3_mutex_methods *pGlobalMutexMethods; + +#ifdef SQLITE_DEBUG +static int checkMutexHeld(sqlite3_mutex *p){ + return pGlobalMutexMethods->xMutexHeld(((CheckMutex*)p)->mutex); +} +static int checkMutexNotheld(sqlite3_mutex *p){ + return pGlobalMutexMethods->xMutexNotheld(((CheckMutex*)p)->mutex); +} +#endif + +/* +** Initialize and deinitialize the mutex subsystem. +*/ +static int checkMutexInit(void){ + pGlobalMutexMethods = sqlite3DefaultMutex(); + return pGlobalMutexMethods->xMutexInit(); +} +static int checkMutexEnd(void){ + int rc = pGlobalMutexMethods->xMutexEnd(); + pGlobalMutexMethods = 0; + return rc; +} + +/* +** Allocate a mutex. +*/ +static sqlite3_mutex *checkMutexAlloc(int iType){ + static CheckMutex staticMutexes[] = { + {2, 0}, {3, 0}, {4, 0}, {5, 0}, + {6, 0}, {7, 0}, {8, 0}, {9, 0}, + {10, 0}, {11, 0}, {12, 0}, {13, 0} + }; + CheckMutex *p = 0; + + assert( SQLITE_MUTEX_RECURSIVE==1 && SQLITE_MUTEX_FAST==0 ); + if( iType<2 ){ + p = sqlite3MallocZero(sizeof(CheckMutex)); + if( p==0 ) return 0; + p->iType = iType; + }else{ +#ifdef SQLITE_ENABLE_API_ARMOR + if( iType-2>=ArraySize(staticMutexes) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + p = &staticMutexes[iType-2]; + } + + if( p->mutex==0 ){ + p->mutex = pGlobalMutexMethods->xMutexAlloc(iType); + if( p->mutex==0 ){ + if( iType<2 ){ + sqlite3_free(p); + } + p = 0; + } + } + + return (sqlite3_mutex*)p; +} + +/* +** Free a mutex. +*/ +static void checkMutexFree(sqlite3_mutex *p){ + assert( SQLITE_MUTEX_RECURSIVE<2 ); + assert( SQLITE_MUTEX_FAST<2 ); + assert( SQLITE_MUTEX_WARNONCONTENTION<2 ); + +#ifdef SQLITE_ENABLE_API_ARMOR + if( ((CheckMutex*)p)->iType<2 ) +#endif + { + CheckMutex *pCheck = (CheckMutex*)p; + pGlobalMutexMethods->xMutexFree(pCheck->mutex); + sqlite3_free(pCheck); + } +#ifdef SQLITE_ENABLE_API_ARMOR + else{ + (void)SQLITE_MISUSE_BKPT; + } +#endif +} + +/* +** Enter the mutex. +*/ +static void checkMutexEnter(sqlite3_mutex *p){ + CheckMutex *pCheck = (CheckMutex*)p; + if( pCheck->iType==SQLITE_MUTEX_WARNONCONTENTION ){ + if( SQLITE_OK==pGlobalMutexMethods->xMutexTry(pCheck->mutex) ){ + return; + } + sqlite3_log(SQLITE_MISUSE, + "illegal multi-threaded access to database connection" + ); +#if SQLITE_THREAD_MISUSE_ABORT + abort(); +#endif + } + pGlobalMutexMethods->xMutexEnter(pCheck->mutex); +} + +/* +** Enter the mutex (do not block). +*/ +static int checkMutexTry(sqlite3_mutex *p){ + CheckMutex *pCheck = (CheckMutex*)p; + return pGlobalMutexMethods->xMutexTry(pCheck->mutex); +} + +/* +** Leave the mutex. +*/ +static void checkMutexLeave(sqlite3_mutex *p){ + CheckMutex *pCheck = (CheckMutex*)p; + pGlobalMutexMethods->xMutexLeave(pCheck->mutex); +} + +sqlite3_mutex_methods const *multiThreadedCheckMutex(void){ + static const sqlite3_mutex_methods sMutex = { + checkMutexInit, + checkMutexEnd, + checkMutexAlloc, + checkMutexFree, + checkMutexEnter, + checkMutexTry, + checkMutexLeave, +#ifdef SQLITE_DEBUG + checkMutexHeld, + checkMutexNotheld +#else + 0, + 0 +#endif + }; + return &sMutex; +} + +/* +** Mark the SQLITE_MUTEX_RECURSIVE mutex passed as the only argument as +** one on which there should be no contention. +*/ +SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex *p){ + if( sqlite3GlobalConfig.mutex.xMutexAlloc==checkMutexAlloc ){ + CheckMutex *pCheck = (CheckMutex*)p; + assert( pCheck->iType==SQLITE_MUTEX_RECURSIVE ); + pCheck->iType = SQLITE_MUTEX_WARNONCONTENTION; + } +} +#endif /* ifdef SQLITE_THREAD_MISUSE_WARNINGS */ + +/* +** Initialize the mutex system. +*/ +SQLITE_PRIVATE int sqlite3MutexInit(void){ + int rc = SQLITE_OK; + if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){ + /* If the xMutexAlloc method has not been set, then the user did not + ** install a mutex implementation via sqlite3_config() prior to + ** sqlite3_initialize() being called. This block copies pointers to + ** the default implementation into the sqlite3GlobalConfig structure. + */ + sqlite3_mutex_methods const *pFrom; + sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex; + + if( sqlite3GlobalConfig.bCoreMutex ){ +#ifdef SQLITE_THREAD_MISUSE_WARNINGS + pFrom = multiThreadedCheckMutex(); +#else + pFrom = sqlite3DefaultMutex(); +#endif + }else{ + pFrom = sqlite3NoopMutex(); + } + pTo->xMutexInit = pFrom->xMutexInit; + pTo->xMutexEnd = pFrom->xMutexEnd; + pTo->xMutexFree = pFrom->xMutexFree; + pTo->xMutexEnter = pFrom->xMutexEnter; + pTo->xMutexTry = pFrom->xMutexTry; + pTo->xMutexLeave = pFrom->xMutexLeave; + pTo->xMutexHeld = pFrom->xMutexHeld; + pTo->xMutexNotheld = pFrom->xMutexNotheld; + sqlite3MemoryBarrier(); + pTo->xMutexAlloc = pFrom->xMutexAlloc; + } + assert( sqlite3GlobalConfig.mutex.xMutexInit ); + rc = sqlite3GlobalConfig.mutex.xMutexInit(); + +#ifdef SQLITE_DEBUG + GLOBAL(int, mutexIsInit) = 1; +#endif + + sqlite3MemoryBarrier(); + return rc; +} + +/* +** Shutdown the mutex system. This call frees resources allocated by +** sqlite3MutexInit(). +*/ +SQLITE_PRIVATE int sqlite3MutexEnd(void){ + int rc = SQLITE_OK; + if( sqlite3GlobalConfig.mutex.xMutexEnd ){ + rc = sqlite3GlobalConfig.mutex.xMutexEnd(); + } + +#ifdef SQLITE_DEBUG + GLOBAL(int, mutexIsInit) = 0; +#endif + + return rc; +} + +/* +** Retrieve a pointer to a static mutex or allocate a new dynamic one. +*/ +SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int id){ +#ifndef SQLITE_OMIT_AUTOINIT + if( id<=SQLITE_MUTEX_RECURSIVE && sqlite3_initialize() ) return 0; + if( id>SQLITE_MUTEX_RECURSIVE && sqlite3MutexInit() ) return 0; +#endif + assert( sqlite3GlobalConfig.mutex.xMutexAlloc ); + return sqlite3GlobalConfig.mutex.xMutexAlloc(id); +} + +SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){ + if( !sqlite3GlobalConfig.bCoreMutex ){ + return 0; + } + assert( GLOBAL(int, mutexIsInit) ); + assert( sqlite3GlobalConfig.mutex.xMutexAlloc ); + return sqlite3GlobalConfig.mutex.xMutexAlloc(id); +} + +/* +** Free a dynamic mutex. +*/ +SQLITE_API void sqlite3_mutex_free(sqlite3_mutex *p){ + if( p ){ + assert( sqlite3GlobalConfig.mutex.xMutexFree ); + sqlite3GlobalConfig.mutex.xMutexFree(p); + } +} + +/* +** Obtain the mutex p. If some other thread already has the mutex, block +** until it can be obtained. +*/ +SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex *p){ + if( p ){ + assert( sqlite3GlobalConfig.mutex.xMutexEnter ); + sqlite3GlobalConfig.mutex.xMutexEnter(p); + } +} + +/* +** Obtain the mutex p. If successful, return SQLITE_OK. Otherwise, if another +** thread holds the mutex and it cannot be obtained, return SQLITE_BUSY. +*/ +SQLITE_API int sqlite3_mutex_try(sqlite3_mutex *p){ + int rc = SQLITE_OK; + if( p ){ + assert( sqlite3GlobalConfig.mutex.xMutexTry ); + return sqlite3GlobalConfig.mutex.xMutexTry(p); + } + return rc; +} + +/* +** The sqlite3_mutex_leave() routine exits a mutex that was previously +** entered by the same thread. The behavior is undefined if the mutex +** is not currently entered. If a NULL pointer is passed as an argument +** this function is a no-op. +*/ +SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){ + if( p ){ + assert( sqlite3GlobalConfig.mutex.xMutexLeave ); + sqlite3GlobalConfig.mutex.xMutexLeave(p); + } +} + +#ifndef NDEBUG +/* +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are +** intended for use inside assert() statements. +** +** Because these routines raise false-positive alerts in TSAN, disable +** them (make them always return 1) when compiling with TSAN. +*/ +SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){ +# if defined(__has_feature) +# if __has_feature(thread_sanitizer) + p = 0; +# endif +# endif + assert( p==0 || sqlite3GlobalConfig.mutex.xMutexHeld ); + return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p); +} +SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){ +# if defined(__has_feature) +# if __has_feature(thread_sanitizer) + p = 0; +# endif +# endif + assert( p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld ); + return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p); +} +#endif /* NDEBUG */ + +#endif /* !defined(SQLITE_MUTEX_OMIT) */ + +/************** End of mutex.c ***********************************************/ +/************** Begin file mutex_noop.c **************************************/ +/* +** 2008 October 07 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains the C functions that implement mutexes. +** +** This implementation in this file does not provide any mutual +** exclusion and is thus suitable for use only in applications +** that use SQLite in a single thread. The routines defined +** here are place-holders. Applications can substitute working +** mutex routines at start-time using the +** +** sqlite3_config(SQLITE_CONFIG_MUTEX,...) +** +** interface. +** +** If compiled with SQLITE_DEBUG, then additional logic is inserted +** that does error checking on mutexes to make sure they are being +** called correctly. +*/ +/* #include "sqliteInt.h" */ + +#ifndef SQLITE_MUTEX_OMIT + +#ifndef SQLITE_DEBUG +/* +** Stub routines for all mutex methods. +** +** This routines provide no mutual exclusion or error checking. +*/ +static int noopMutexInit(void){ return SQLITE_OK; } +static int noopMutexEnd(void){ return SQLITE_OK; } +static sqlite3_mutex *noopMutexAlloc(int id){ + UNUSED_PARAMETER(id); + return (sqlite3_mutex*)8; +} +static void noopMutexFree(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } +static void noopMutexEnter(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } +static int noopMutexTry(sqlite3_mutex *p){ + UNUSED_PARAMETER(p); + return SQLITE_OK; +} +static void noopMutexLeave(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } + +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void){ + static const sqlite3_mutex_methods sMutex = { + noopMutexInit, + noopMutexEnd, + noopMutexAlloc, + noopMutexFree, + noopMutexEnter, + noopMutexTry, + noopMutexLeave, + + 0, + 0, + }; + + return &sMutex; +} +#endif /* !SQLITE_DEBUG */ + +#ifdef SQLITE_DEBUG +/* +** In this implementation, error checking is provided for testing +** and debugging purposes. The mutexes still do not provide any +** mutual exclusion. +*/ + +/* +** The mutex object +*/ +typedef struct sqlite3_debug_mutex { + int id; /* The mutex type */ + int cnt; /* Number of entries without a matching leave */ +} sqlite3_debug_mutex; + +/* +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are +** intended for use inside assert() statements. +*/ +static int debugMutexHeld(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; + return p==0 || p->cnt>0; +} +static int debugMutexNotheld(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; + return p==0 || p->cnt==0; +} + +/* +** Initialize and deinitialize the mutex subsystem. +*/ +static int debugMutexInit(void){ return SQLITE_OK; } +static int debugMutexEnd(void){ return SQLITE_OK; } + +/* +** The sqlite3_mutex_alloc() routine allocates a new +** mutex and returns a pointer to it. If it returns NULL +** that means that a mutex could not be allocated. +*/ +static sqlite3_mutex *debugMutexAlloc(int id){ + static sqlite3_debug_mutex aStatic[SQLITE_MUTEX_STATIC_VFS3 - 1]; + sqlite3_debug_mutex *pNew = 0; + switch( id ){ + case SQLITE_MUTEX_FAST: + case SQLITE_MUTEX_RECURSIVE: { + pNew = sqlite3Malloc(sizeof(*pNew)); + if( pNew ){ + pNew->id = id; + pNew->cnt = 0; + } + break; + } + default: { +#ifdef SQLITE_ENABLE_API_ARMOR + if( id-2<0 || id-2>=ArraySize(aStatic) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + pNew = &aStatic[id-2]; + pNew->id = id; + break; + } + } + return (sqlite3_mutex*)pNew; +} + +/* +** This routine deallocates a previously allocated mutex. +*/ +static void debugMutexFree(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; + assert( p->cnt==0 ); + if( p->id==SQLITE_MUTEX_RECURSIVE || p->id==SQLITE_MUTEX_FAST ){ + sqlite3_free(p); + }else{ +#ifdef SQLITE_ENABLE_API_ARMOR + (void)SQLITE_MISUSE_BKPT; +#endif + } +} + +/* +** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK +** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can +** be entered multiple times by the same thread. In such cases the, +** mutex must be exited an equal number of times before another thread +** can enter. If the same thread tries to enter any other kind of mutex +** more than once, the behavior is undefined. +*/ +static void debugMutexEnter(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; + assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); + p->cnt++; +} +static int debugMutexTry(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; + assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); + p->cnt++; + return SQLITE_OK; +} + +/* +** The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. The behavior +** is undefined if the mutex is not currently entered or +** is not currently allocated. SQLite will never do either. +*/ +static void debugMutexLeave(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; + assert( debugMutexHeld(pX) ); + p->cnt--; + assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); +} + +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void){ + static const sqlite3_mutex_methods sMutex = { + debugMutexInit, + debugMutexEnd, + debugMutexAlloc, + debugMutexFree, + debugMutexEnter, + debugMutexTry, + debugMutexLeave, + + debugMutexHeld, + debugMutexNotheld + }; + + return &sMutex; +} +#endif /* SQLITE_DEBUG */ + +/* +** If compiled with SQLITE_MUTEX_NOOP, then the no-op mutex implementation +** is used regardless of the run-time threadsafety setting. +*/ +#ifdef SQLITE_MUTEX_NOOP +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ + return sqlite3NoopMutex(); +} +#endif /* defined(SQLITE_MUTEX_NOOP) */ +#endif /* !defined(SQLITE_MUTEX_OMIT) */ + +/************** End of mutex_noop.c ******************************************/ +/************** Begin file mutex_unix.c **************************************/ +/* +** 2007 August 28 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains the C functions that implement mutexes for pthreads +*/ +/* #include "sqliteInt.h" */ + +/* +** The code in this file is only used if we are compiling threadsafe +** under unix with pthreads. +** +** Note that this implementation requires a version of pthreads that +** supports recursive mutexes. +*/ +#ifdef SQLITE_MUTEX_PTHREADS + +#include + +/* +** The sqlite3_mutex.id, sqlite3_mutex.nRef, and sqlite3_mutex.owner fields +** are necessary under two conditions: (1) Debug builds and (2) using +** home-grown mutexes. Encapsulate these conditions into a single #define. +*/ +#if defined(SQLITE_DEBUG) || defined(SQLITE_HOMEGROWN_RECURSIVE_MUTEX) +# define SQLITE_MUTEX_NREF 1 +#else +# define SQLITE_MUTEX_NREF 0 +#endif + +/* +** Each recursive mutex is an instance of the following structure. +*/ +struct sqlite3_mutex { + pthread_mutex_t mutex; /* Mutex controlling the lock */ +#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR) + int id; /* Mutex type */ +#endif +#if SQLITE_MUTEX_NREF + volatile int nRef; /* Number of entrances */ + volatile pthread_t owner; /* Thread that is within this mutex */ + int trace; /* True to trace changes */ +#endif +}; +#if SQLITE_MUTEX_NREF +# define SQLITE3_MUTEX_INITIALIZER(id) \ + {PTHREAD_MUTEX_INITIALIZER,id,0,(pthread_t)0,0} +#elif defined(SQLITE_ENABLE_API_ARMOR) +# define SQLITE3_MUTEX_INITIALIZER(id) { PTHREAD_MUTEX_INITIALIZER, id } +#else +#define SQLITE3_MUTEX_INITIALIZER(id) { PTHREAD_MUTEX_INITIALIZER } +#endif + +/* +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are +** intended for use only inside assert() statements. On some platforms, +** there might be race conditions that can cause these routines to +** deliver incorrect results. In particular, if pthread_equal() is +** not an atomic operation, then these routines might delivery +** incorrect results. On most platforms, pthread_equal() is a +** comparison of two integers and is therefore atomic. But we are +** told that HPUX is not such a platform. If so, then these routines +** will not always work correctly on HPUX. +** +** On those platforms where pthread_equal() is not atomic, SQLite +** should be compiled without -DSQLITE_DEBUG and with -DNDEBUG to +** make sure no assert() statements are evaluated and hence these +** routines are never called. +*/ +#if !defined(NDEBUG) || defined(SQLITE_DEBUG) +static int pthreadMutexHeld(sqlite3_mutex *p){ + return (p->nRef!=0 && pthread_equal(p->owner, pthread_self())); +} +static int pthreadMutexNotheld(sqlite3_mutex *p){ + return p->nRef==0 || pthread_equal(p->owner, pthread_self())==0; +} +#endif + +/* +** Try to provide a memory barrier operation, needed for initialization +** and also for the implementation of xShmBarrier in the VFS in cases +** where SQLite is compiled without mutexes. +*/ +SQLITE_PRIVATE void sqlite3MemoryBarrier(void){ +#if defined(SQLITE_MEMORY_BARRIER) + SQLITE_MEMORY_BARRIER; +#elif defined(__GNUC__) && GCC_VERSION>=4001000 + __sync_synchronize(); +#endif +} + +/* +** Initialize and deinitialize the mutex subsystem. +*/ +static int pthreadMutexInit(void){ return SQLITE_OK; } +static int pthreadMutexEnd(void){ return SQLITE_OK; } + +/* +** The sqlite3_mutex_alloc() routine allocates a new +** mutex and returns a pointer to it. If it returns NULL +** that means that a mutex could not be allocated. SQLite +** will unwind its stack and return an error. The argument +** to sqlite3_mutex_alloc() is one of these integer constants: +** +**
      +**
    • SQLITE_MUTEX_FAST +**
    • SQLITE_MUTEX_RECURSIVE +**
    • SQLITE_MUTEX_STATIC_MAIN +**
    • SQLITE_MUTEX_STATIC_MEM +**
    • SQLITE_MUTEX_STATIC_OPEN +**
    • SQLITE_MUTEX_STATIC_PRNG +**
    • SQLITE_MUTEX_STATIC_LRU +**
    • SQLITE_MUTEX_STATIC_PMEM +**
    • SQLITE_MUTEX_STATIC_APP1 +**
    • SQLITE_MUTEX_STATIC_APP2 +**
    • SQLITE_MUTEX_STATIC_APP3 +**
    • SQLITE_MUTEX_STATIC_VFS1 +**
    • SQLITE_MUTEX_STATIC_VFS2 +**
    • SQLITE_MUTEX_STATIC_VFS3 +**
    +** +** The first two constants cause sqlite3_mutex_alloc() to create +** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE +** is used but not necessarily so when SQLITE_MUTEX_FAST is used. +** The mutex implementation does not need to make a distinction +** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does +** not want to. But SQLite will only request a recursive mutex in +** cases where it really needs one. If a faster non-recursive mutex +** implementation is available on the host platform, the mutex subsystem +** might return such a mutex in response to SQLITE_MUTEX_FAST. +** +** The other allowed parameters to sqlite3_mutex_alloc() each return +** a pointer to a static preexisting mutex. Six static mutexes are +** used by the current version of SQLite. Future versions of SQLite +** may add additional static mutexes. Static mutexes are for internal +** use by SQLite only. Applications that use SQLite mutexes should +** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or +** SQLITE_MUTEX_RECURSIVE. +** +** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() +** returns a different mutex on every call. But for the static +** mutex types, the same mutex is returned on every call that has +** the same type number. +*/ +static sqlite3_mutex *pthreadMutexAlloc(int iType){ + static sqlite3_mutex staticMutexes[] = { + SQLITE3_MUTEX_INITIALIZER(2), + SQLITE3_MUTEX_INITIALIZER(3), + SQLITE3_MUTEX_INITIALIZER(4), + SQLITE3_MUTEX_INITIALIZER(5), + SQLITE3_MUTEX_INITIALIZER(6), + SQLITE3_MUTEX_INITIALIZER(7), + SQLITE3_MUTEX_INITIALIZER(8), + SQLITE3_MUTEX_INITIALIZER(9), + SQLITE3_MUTEX_INITIALIZER(10), + SQLITE3_MUTEX_INITIALIZER(11), + SQLITE3_MUTEX_INITIALIZER(12), + SQLITE3_MUTEX_INITIALIZER(13) + }; + sqlite3_mutex *p; + switch( iType ){ + case SQLITE_MUTEX_RECURSIVE: { + p = sqlite3MallocZero( sizeof(*p) ); + if( p ){ +#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX + /* If recursive mutexes are not available, we will have to + ** build our own. See below. */ + pthread_mutex_init(&p->mutex, 0); +#else + /* Use a recursive mutex if it is available */ + pthread_mutexattr_t recursiveAttr; + pthread_mutexattr_init(&recursiveAttr); + pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&p->mutex, &recursiveAttr); + pthread_mutexattr_destroy(&recursiveAttr); +#endif +#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR) + p->id = SQLITE_MUTEX_RECURSIVE; +#endif + } + break; + } + case SQLITE_MUTEX_FAST: { + p = sqlite3MallocZero( sizeof(*p) ); + if( p ){ + pthread_mutex_init(&p->mutex, 0); +#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR) + p->id = SQLITE_MUTEX_FAST; +#endif + } + break; + } + default: { +#ifdef SQLITE_ENABLE_API_ARMOR + if( iType-2<0 || iType-2>=ArraySize(staticMutexes) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + p = &staticMutexes[iType-2]; + break; + } + } +#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR) + assert( p==0 || p->id==iType ); +#endif + return p; +} + + +/* +** This routine deallocates a previously +** allocated mutex. SQLite is careful to deallocate every +** mutex that it allocates. +*/ +static void pthreadMutexFree(sqlite3_mutex *p){ + assert( p->nRef==0 ); +#ifdef SQLITE_ENABLE_API_ARMOR + if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ) +#endif + { + pthread_mutex_destroy(&p->mutex); + sqlite3_free(p); + } +#ifdef SQLITE_ENABLE_API_ARMOR + else{ + (void)SQLITE_MISUSE_BKPT; + } +#endif +} + +/* +** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK +** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can +** be entered multiple times by the same thread. In such cases the, +** mutex must be exited an equal number of times before another thread +** can enter. If the same thread tries to enter any other kind of mutex +** more than once, the behavior is undefined. +*/ +static void pthreadMutexEnter(sqlite3_mutex *p){ + assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) ); + +#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX + /* If recursive mutexes are not available, then we have to grow + ** our own. This implementation assumes that pthread_equal() + ** is atomic - that it cannot be deceived into thinking self + ** and p->owner are equal if p->owner changes between two values + ** that are not equal to self while the comparison is taking place. + ** This implementation also assumes a coherent cache - that + ** separate processes cannot read different values from the same + ** address at the same time. If either of these two conditions + ** are not met, then the mutexes will fail and problems will result. + */ + { + pthread_t self = pthread_self(); + if( p->nRef>0 && pthread_equal(p->owner, self) ){ + p->nRef++; + }else{ + pthread_mutex_lock(&p->mutex); + assert( p->nRef==0 ); + p->owner = self; + p->nRef = 1; + } + } +#else + /* Use the built-in recursive mutexes if they are available. + */ + pthread_mutex_lock(&p->mutex); +#if SQLITE_MUTEX_NREF + assert( p->nRef>0 || p->owner==0 ); + p->owner = pthread_self(); + p->nRef++; +#endif +#endif + +#ifdef SQLITE_DEBUG + if( p->trace ){ + printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); + } +#endif +} +static int pthreadMutexTry(sqlite3_mutex *p){ + int rc; + assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) ); + +#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX + /* If recursive mutexes are not available, then we have to grow + ** our own. This implementation assumes that pthread_equal() + ** is atomic - that it cannot be deceived into thinking self + ** and p->owner are equal if p->owner changes between two values + ** that are not equal to self while the comparison is taking place. + ** This implementation also assumes a coherent cache - that + ** separate processes cannot read different values from the same + ** address at the same time. If either of these two conditions + ** are not met, then the mutexes will fail and problems will result. + */ + { + pthread_t self = pthread_self(); + if( p->nRef>0 && pthread_equal(p->owner, self) ){ + p->nRef++; + rc = SQLITE_OK; + }else if( pthread_mutex_trylock(&p->mutex)==0 ){ + assert( p->nRef==0 ); + p->owner = self; + p->nRef = 1; + rc = SQLITE_OK; + }else{ + rc = SQLITE_BUSY; + } + } +#else + /* Use the built-in recursive mutexes if they are available. + */ + if( pthread_mutex_trylock(&p->mutex)==0 ){ +#if SQLITE_MUTEX_NREF + p->owner = pthread_self(); + p->nRef++; +#endif + rc = SQLITE_OK; + }else{ + rc = SQLITE_BUSY; + } +#endif + +#ifdef SQLITE_DEBUG + if( rc==SQLITE_OK && p->trace ){ + printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); + } +#endif + return rc; +} + +/* +** The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. The behavior +** is undefined if the mutex is not currently entered or +** is not currently allocated. SQLite will never do either. +*/ +static void pthreadMutexLeave(sqlite3_mutex *p){ + assert( pthreadMutexHeld(p) ); +#if SQLITE_MUTEX_NREF + p->nRef--; + if( p->nRef==0 ) p->owner = 0; +#endif + assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); + +#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX + if( p->nRef==0 ){ + pthread_mutex_unlock(&p->mutex); + } +#else + pthread_mutex_unlock(&p->mutex); +#endif + +#ifdef SQLITE_DEBUG + if( p->trace ){ + printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); + } +#endif +} + +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ + static const sqlite3_mutex_methods sMutex = { + pthreadMutexInit, + pthreadMutexEnd, + pthreadMutexAlloc, + pthreadMutexFree, + pthreadMutexEnter, + pthreadMutexTry, + pthreadMutexLeave, +#ifdef SQLITE_DEBUG + pthreadMutexHeld, + pthreadMutexNotheld +#else + 0, + 0 +#endif + }; + + return &sMutex; +} + +#endif /* SQLITE_MUTEX_PTHREADS */ + +/************** End of mutex_unix.c ******************************************/ +/************** Begin file mutex_w32.c ***************************************/ +/* +** 2007 August 14 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains the C functions that implement mutexes for Win32. +*/ +/* #include "sqliteInt.h" */ + +#if SQLITE_OS_WIN +/* +** Include code that is common to all os_*.c files +*/ +/* #include "os_common.h" */ + +/* +** Include the header file for the Windows VFS. +*/ +/************** Include os_win.h in the middle of mutex_w32.c ****************/ +/************** Begin file os_win.h ******************************************/ +/* +** 2013 November 25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains code that is specific to Windows. +*/ +#ifndef SQLITE_OS_WIN_H +#define SQLITE_OS_WIN_H + +/* +** Include the primary Windows SDK header file. +*/ +#include "windows.h" + +#ifdef __CYGWIN__ +# include +# include /* amalgamator: dontcache */ +# include /* amalgamator: dontcache */ +# include /* amalgamator: dontcache */ +#endif + +/* +** Determine if we are dealing with Windows NT. +** +** We ought to be able to determine if we are compiling for Windows 9x or +** Windows NT using the _WIN32_WINNT macro as follows: +** +** #if defined(_WIN32_WINNT) +** # define SQLITE_OS_WINNT 1 +** #else +** # define SQLITE_OS_WINNT 0 +** #endif +** +** However, Visual Studio 2005 does not set _WIN32_WINNT by default, as +** it ought to, so the above test does not work. We'll just assume that +** everything is Windows NT unless the programmer explicitly says otherwise +** by setting SQLITE_OS_WINNT to 0. +*/ +#if SQLITE_OS_WIN && !defined(SQLITE_OS_WINNT) +# define SQLITE_OS_WINNT 1 +#endif + +/* +** Determine if we are dealing with Windows CE - which has a much reduced +** API. +*/ +#if defined(_WIN32_WCE) +# define SQLITE_OS_WINCE 1 +#else +# define SQLITE_OS_WINCE 0 +#endif + +/* +** For WinCE, some API function parameters do not appear to be declared as +** volatile. +*/ +#if SQLITE_OS_WINCE +# define SQLITE_WIN32_VOLATILE +#else +# define SQLITE_WIN32_VOLATILE volatile +#endif + +/* +** For some Windows sub-platforms, the _beginthreadex() / _endthreadex() +** functions are not available (e.g. those not using MSVC, Cygwin, etc). +*/ +#if SQLITE_OS_WIN && !SQLITE_OS_WINCE && \ + SQLITE_THREADSAFE>0 && !defined(__CYGWIN__) +# define SQLITE_OS_WIN_THREADS 1 +#else +# define SQLITE_OS_WIN_THREADS 0 +#endif + +#endif /* SQLITE_OS_WIN_H */ + +/************** End of os_win.h **********************************************/ +/************** Continuing where we left off in mutex_w32.c ******************/ +#endif + +/* +** The code in this file is only used if we are compiling multithreaded +** on a Win32 system. +*/ +#ifdef SQLITE_MUTEX_W32 + +/* +** Each recursive mutex is an instance of the following structure. +*/ +struct sqlite3_mutex { + CRITICAL_SECTION mutex; /* Mutex controlling the lock */ + int id; /* Mutex type */ +#ifdef SQLITE_DEBUG + volatile int nRef; /* Number of entrances */ + volatile DWORD owner; /* Thread holding this mutex */ + volatile LONG trace; /* True to trace changes */ +#endif +}; + +/* +** These are the initializer values used when declaring a "static" mutex +** on Win32. It should be noted that all mutexes require initialization +** on the Win32 platform. +*/ +#define SQLITE_W32_MUTEX_INITIALIZER { 0 } + +#ifdef SQLITE_DEBUG +#define SQLITE3_MUTEX_INITIALIZER(id) { SQLITE_W32_MUTEX_INITIALIZER, id, \ + 0L, (DWORD)0, 0 } +#else +#define SQLITE3_MUTEX_INITIALIZER(id) { SQLITE_W32_MUTEX_INITIALIZER, id } +#endif + +#ifdef SQLITE_DEBUG +/* +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are +** intended for use only inside assert() statements. +*/ +static int winMutexHeld(sqlite3_mutex *p){ + return p->nRef!=0 && p->owner==GetCurrentThreadId(); +} + +static int winMutexNotheld2(sqlite3_mutex *p, DWORD tid){ + return p->nRef==0 || p->owner!=tid; +} + +static int winMutexNotheld(sqlite3_mutex *p){ + DWORD tid = GetCurrentThreadId(); + return winMutexNotheld2(p, tid); +} +#endif + +/* +** Try to provide a memory barrier operation, needed for initialization +** and also for the xShmBarrier method of the VFS in cases when SQLite is +** compiled without mutexes (SQLITE_THREADSAFE=0). +*/ +SQLITE_PRIVATE void sqlite3MemoryBarrier(void){ +#if defined(SQLITE_MEMORY_BARRIER) + SQLITE_MEMORY_BARRIER; +#elif defined(__GNUC__) + __sync_synchronize(); +#elif MSVC_VERSION>=1400 + _ReadWriteBarrier(); +#elif defined(MemoryBarrier) + MemoryBarrier(); +#endif +} + +/* +** Initialize and deinitialize the mutex subsystem. +*/ +static sqlite3_mutex winMutex_staticMutexes[] = { + SQLITE3_MUTEX_INITIALIZER(2), + SQLITE3_MUTEX_INITIALIZER(3), + SQLITE3_MUTEX_INITIALIZER(4), + SQLITE3_MUTEX_INITIALIZER(5), + SQLITE3_MUTEX_INITIALIZER(6), + SQLITE3_MUTEX_INITIALIZER(7), + SQLITE3_MUTEX_INITIALIZER(8), + SQLITE3_MUTEX_INITIALIZER(9), + SQLITE3_MUTEX_INITIALIZER(10), + SQLITE3_MUTEX_INITIALIZER(11), + SQLITE3_MUTEX_INITIALIZER(12), + SQLITE3_MUTEX_INITIALIZER(13) +}; + +static int winMutex_isInit = 0; +static int winMutex_isNt = -1; /* <0 means "need to query" */ + +/* As the winMutexInit() and winMutexEnd() functions are called as part +** of the sqlite3_initialize() and sqlite3_shutdown() processing, the +** "interlocked" magic used here is probably not strictly necessary. +*/ +static LONG SQLITE_WIN32_VOLATILE winMutex_lock = 0; + +SQLITE_API int sqlite3_win32_is_nt(void); /* os_win.c */ +SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */ + +static int winMutexInit(void){ + /* The first to increment to 1 does actual initialization */ + if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){ + int i; + for(i=0; i +**
  • SQLITE_MUTEX_FAST +**
  • SQLITE_MUTEX_RECURSIVE +**
  • SQLITE_MUTEX_STATIC_MAIN +**
  • SQLITE_MUTEX_STATIC_MEM +**
  • SQLITE_MUTEX_STATIC_OPEN +**
  • SQLITE_MUTEX_STATIC_PRNG +**
  • SQLITE_MUTEX_STATIC_LRU +**
  • SQLITE_MUTEX_STATIC_PMEM +**
  • SQLITE_MUTEX_STATIC_APP1 +**
  • SQLITE_MUTEX_STATIC_APP2 +**
  • SQLITE_MUTEX_STATIC_APP3 +**
  • SQLITE_MUTEX_STATIC_VFS1 +**
  • SQLITE_MUTEX_STATIC_VFS2 +**
  • SQLITE_MUTEX_STATIC_VFS3 +** +** +** The first two constants cause sqlite3_mutex_alloc() to create +** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE +** is used but not necessarily so when SQLITE_MUTEX_FAST is used. +** The mutex implementation does not need to make a distinction +** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does +** not want to. But SQLite will only request a recursive mutex in +** cases where it really needs one. If a faster non-recursive mutex +** implementation is available on the host platform, the mutex subsystem +** might return such a mutex in response to SQLITE_MUTEX_FAST. +** +** The other allowed parameters to sqlite3_mutex_alloc() each return +** a pointer to a static preexisting mutex. Six static mutexes are +** used by the current version of SQLite. Future versions of SQLite +** may add additional static mutexes. Static mutexes are for internal +** use by SQLite only. Applications that use SQLite mutexes should +** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or +** SQLITE_MUTEX_RECURSIVE. +** +** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() +** returns a different mutex on every call. But for the static +** mutex types, the same mutex is returned on every call that has +** the same type number. +*/ +static sqlite3_mutex *winMutexAlloc(int iType){ + sqlite3_mutex *p; + + switch( iType ){ + case SQLITE_MUTEX_FAST: + case SQLITE_MUTEX_RECURSIVE: { + p = sqlite3MallocZero( sizeof(*p) ); + if( p ){ + p->id = iType; +#ifdef SQLITE_DEBUG +#ifdef SQLITE_WIN32_MUTEX_TRACE_DYNAMIC + p->trace = 1; +#endif +#endif + InitializeCriticalSection(&p->mutex); + } + break; + } + default: { +#ifdef SQLITE_ENABLE_API_ARMOR + if( iType-2<0 || iType-2>=ArraySize(winMutex_staticMutexes) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + p = &winMutex_staticMutexes[iType-2]; +#ifdef SQLITE_DEBUG +#ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC + InterlockedCompareExchange(&p->trace, 1, 0); +#endif +#endif + break; + } + } + assert( p==0 || p->id==iType ); + return p; +} + + +/* +** This routine deallocates a previously +** allocated mutex. SQLite is careful to deallocate every +** mutex that it allocates. +*/ +static void winMutexFree(sqlite3_mutex *p){ + assert( p ); + assert( p->nRef==0 && p->owner==0 ); + if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ){ + DeleteCriticalSection(&p->mutex); + sqlite3_free(p); + }else{ +#ifdef SQLITE_ENABLE_API_ARMOR + (void)SQLITE_MISUSE_BKPT; +#endif + } +} + +/* +** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt +** to enter a mutex. If another thread is already within the mutex, +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK +** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can +** be entered multiple times by the same thread. In such cases the, +** mutex must be exited an equal number of times before another thread +** can enter. If the same thread tries to enter any other kind of mutex +** more than once, the behavior is undefined. +*/ +static void winMutexEnter(sqlite3_mutex *p){ +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + DWORD tid = GetCurrentThreadId(); +#endif +#ifdef SQLITE_DEBUG + assert( p ); + assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); +#else + assert( p ); +#endif + assert( winMutex_isInit==1 ); + EnterCriticalSection(&p->mutex); +#ifdef SQLITE_DEBUG + assert( p->nRef>0 || p->owner==0 ); + p->owner = tid; + p->nRef++; + if( p->trace ){ + OSTRACE(("ENTER-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n", + tid, p->id, p, p->trace, p->nRef)); + } +#endif +} + +static int winMutexTry(sqlite3_mutex *p){ +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + DWORD tid = GetCurrentThreadId(); +#endif + int rc = SQLITE_BUSY; + assert( p ); + assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); + /* + ** The sqlite3_mutex_try() routine is very rarely used, and when it + ** is used it is merely an optimization. So it is OK for it to always + ** fail. + ** + ** The TryEnterCriticalSection() interface is only available on WinNT. + ** And some windows compilers complain if you try to use it without + ** first doing some #defines that prevent SQLite from building on Win98. + ** For that reason, we will omit this optimization for now. See + ** ticket #2685. + */ +#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0400 + assert( winMutex_isInit==1 ); + assert( winMutex_isNt>=-1 && winMutex_isNt<=1 ); + if( winMutex_isNt<0 ){ + winMutex_isNt = sqlite3_win32_is_nt(); + } + assert( winMutex_isNt==0 || winMutex_isNt==1 ); + if( winMutex_isNt && TryEnterCriticalSection(&p->mutex) ){ +#ifdef SQLITE_DEBUG + p->owner = tid; + p->nRef++; +#endif + rc = SQLITE_OK; + } +#else + UNUSED_PARAMETER(p); +#endif +#ifdef SQLITE_DEBUG + if( p->trace ){ + OSTRACE(("TRY-MUTEX tid=%lu, mutex(%d)=%p (%d), owner=%lu, nRef=%d, rc=%s\n", + tid, p->id, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc))); + } +#endif + return rc; +} + +/* +** The sqlite3_mutex_leave() routine exits a mutex that was +** previously entered by the same thread. The behavior +** is undefined if the mutex is not currently entered or +** is not currently allocated. SQLite will never do either. +*/ +static void winMutexLeave(sqlite3_mutex *p){ +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + DWORD tid = GetCurrentThreadId(); +#endif + assert( p ); +#ifdef SQLITE_DEBUG + assert( p->nRef>0 ); + assert( p->owner==tid ); + p->nRef--; + if( p->nRef==0 ) p->owner = 0; + assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); +#endif + assert( winMutex_isInit==1 ); + LeaveCriticalSection(&p->mutex); +#ifdef SQLITE_DEBUG + if( p->trace ){ + OSTRACE(("LEAVE-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n", + tid, p->id, p, p->trace, p->nRef)); + } +#endif +} + +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ + static const sqlite3_mutex_methods sMutex = { + winMutexInit, + winMutexEnd, + winMutexAlloc, + winMutexFree, + winMutexEnter, + winMutexTry, + winMutexLeave, +#ifdef SQLITE_DEBUG + winMutexHeld, + winMutexNotheld +#else + 0, + 0 +#endif + }; + return &sMutex; +} + +#endif /* SQLITE_MUTEX_W32 */ + +/************** End of mutex_w32.c *******************************************/ +/************** Begin file malloc.c ******************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** Memory allocation functions used throughout sqlite. +*/ +/* #include "sqliteInt.h" */ +/* #include */ + +/* +** Attempt to release up to n bytes of non-essential memory currently +** held by SQLite. An example of non-essential memory is memory used to +** cache database pages that are not currently in use. +*/ +SQLITE_API int sqlite3_release_memory(int n){ +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT + return sqlite3PcacheReleaseMemory(n); +#else + /* IMPLEMENTATION-OF: R-34391-24921 The sqlite3_release_memory() routine + ** is a no-op returning zero if SQLite is not compiled with + ** SQLITE_ENABLE_MEMORY_MANAGEMENT. */ + UNUSED_PARAMETER(n); + return 0; +#endif +} + +/* +** Default value of the hard heap limit. 0 means "no limit". +*/ +#ifndef SQLITE_MAX_MEMORY +# define SQLITE_MAX_MEMORY 0 +#endif + +/* +** State information local to the memory allocation subsystem. +*/ +static SQLITE_WSD struct Mem0Global { + sqlite3_mutex *mutex; /* Mutex to serialize access */ + sqlite3_int64 alarmThreshold; /* The soft heap limit */ + sqlite3_int64 hardLimit; /* The hard upper bound on memory */ + + /* + ** True if heap is nearly "full" where "full" is defined by the + ** sqlite3_soft_heap_limit() setting. + */ + int nearlyFull; +} mem0 = { 0, SQLITE_MAX_MEMORY, SQLITE_MAX_MEMORY, 0 }; + +#define mem0 GLOBAL(struct Mem0Global, mem0) + +/* +** Return the memory allocator mutex. sqlite3_status() needs it. +*/ +SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void){ + return mem0.mutex; +} + +#ifndef SQLITE_OMIT_DEPRECATED +/* +** Deprecated external interface. It used to set an alarm callback +** that was invoked when memory usage grew too large. Now it is a +** no-op. +*/ +SQLITE_API int sqlite3_memory_alarm( + void(*xCallback)(void *pArg, sqlite3_int64 used,int N), + void *pArg, + sqlite3_int64 iThreshold +){ + (void)xCallback; + (void)pArg; + (void)iThreshold; + return SQLITE_OK; +} +#endif + +/* +** Set the soft heap-size limit for the library. An argument of +** zero disables the limit. A negative argument is a no-op used to +** obtain the return value. +** +** The return value is the value of the heap limit just before this +** interface was called. +** +** If the hard heap limit is enabled, then the soft heap limit cannot +** be disabled nor raised above the hard heap limit. +*/ +SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){ + sqlite3_int64 priorLimit; + sqlite3_int64 excess; + sqlite3_int64 nUsed; +#ifndef SQLITE_OMIT_AUTOINIT + int rc = sqlite3_initialize(); + if( rc ) return -1; +#endif + sqlite3_mutex_enter(mem0.mutex); + priorLimit = mem0.alarmThreshold; + if( n<0 ){ + sqlite3_mutex_leave(mem0.mutex); + return priorLimit; + } + if( mem0.hardLimit>0 && (n>mem0.hardLimit || n==0) ){ + n = mem0.hardLimit; + } + mem0.alarmThreshold = n; + nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); + AtomicStore(&mem0.nearlyFull, n>0 && n<=nUsed); + sqlite3_mutex_leave(mem0.mutex); + excess = sqlite3_memory_used() - n; + if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff)); + return priorLimit; +} +SQLITE_API void sqlite3_soft_heap_limit(int n){ + if( n<0 ) n = 0; + sqlite3_soft_heap_limit64(n); +} + +/* +** Set the hard heap-size limit for the library. An argument of zero +** disables the hard heap limit. A negative argument is a no-op used +** to obtain the return value without affecting the hard heap limit. +** +** The return value is the value of the hard heap limit just prior to +** calling this interface. +** +** Setting the hard heap limit will also activate the soft heap limit +** and constrain the soft heap limit to be no more than the hard heap +** limit. +*/ +SQLITE_API sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 n){ + sqlite3_int64 priorLimit; +#ifndef SQLITE_OMIT_AUTOINIT + int rc = sqlite3_initialize(); + if( rc ) return -1; +#endif + sqlite3_mutex_enter(mem0.mutex); + priorLimit = mem0.hardLimit; + if( n>=0 ){ + mem0.hardLimit = n; + if( n>32) < 0xffffffff ); +} +#else +# define test_oom_breakpoint(X) /* No-op for production builds */ +#endif + +/* +** Do a memory allocation with statistics and alarms. Assume the +** lock is already held. +*/ +static void mallocWithAlarm(int n, void **pp){ + void *p; + int nFull; + assert( sqlite3_mutex_held(mem0.mutex) ); + assert( n>0 ); + + /* In Firefox (circa 2017-02-08), xRoundup() is remapped to an internal + ** implementation of malloc_good_size(), which must be called in debug + ** mode and specifically when the DMD "Dark Matter Detector" is enabled + ** or else a crash results. Hence, do not attempt to optimize out the + ** following xRoundup() call. */ + nFull = sqlite3GlobalConfig.m.xRoundup(n); + + sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n); + if( mem0.alarmThreshold>0 ){ + sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); + if( nUsed >= mem0.alarmThreshold - nFull ){ + AtomicStore(&mem0.nearlyFull, 1); + sqlite3MallocAlarm(nFull); + if( mem0.hardLimit ){ + nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); + if( nUsed >= mem0.hardLimit - nFull ){ + test_oom_breakpoint(1); + *pp = 0; + return; + } + } + }else{ + AtomicStore(&mem0.nearlyFull, 0); + } + } + p = sqlite3GlobalConfig.m.xMalloc(nFull); +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT + if( p==0 && mem0.alarmThreshold>0 ){ + sqlite3MallocAlarm(nFull); + p = sqlite3GlobalConfig.m.xMalloc(nFull); + } +#endif + if( p ){ + nFull = sqlite3MallocSize(p); + sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nFull); + sqlite3StatusUp(SQLITE_STATUS_MALLOC_COUNT, 1); + } + *pp = p; +} + +/* +** Allocate memory. This routine is like sqlite3_malloc() except that it +** assumes the memory subsystem has already been initialized. +*/ +SQLITE_PRIVATE void *sqlite3Malloc(u64 n){ + void *p; + if( n==0 || n>SQLITE_MAX_ALLOCATION_SIZE ){ + p = 0; + }else if( sqlite3GlobalConfig.bMemstat ){ + sqlite3_mutex_enter(mem0.mutex); + mallocWithAlarm((int)n, &p); + sqlite3_mutex_leave(mem0.mutex); + }else{ + p = sqlite3GlobalConfig.m.xMalloc((int)n); + } + assert( EIGHT_BYTE_ALIGNMENT(p) ); /* IMP: R-11148-40995 */ + return p; +} + +/* +** This version of the memory allocation is for use by the application. +** First make sure the memory subsystem is initialized, then do the +** allocation. +*/ +SQLITE_API void *sqlite3_malloc(int n){ +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return n<=0 ? 0 : sqlite3Malloc(n); +} +SQLITE_API void *sqlite3_malloc64(sqlite3_uint64 n){ +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return sqlite3Malloc(n); +} + +/* +** TRUE if p is a lookaside memory allocation from db +*/ +#ifndef SQLITE_OMIT_LOOKASIDE +static int isLookaside(sqlite3 *db, const void *p){ + return SQLITE_WITHIN(p, db->lookaside.pStart, db->lookaside.pTrueEnd); +} +#else +#define isLookaside(A,B) 0 +#endif + +/* +** Return the size of a memory allocation previously obtained from +** sqlite3Malloc() or sqlite3_malloc(). +*/ +SQLITE_PRIVATE int sqlite3MallocSize(const void *p){ + assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); + return sqlite3GlobalConfig.m.xSize((void*)p); +} +static int lookasideMallocSize(sqlite3 *db, const void *p){ +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + return plookaside.pMiddle ? db->lookaside.szTrue : LOOKASIDE_SMALL; +#else + return db->lookaside.szTrue; +#endif +} +SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, const void *p){ + assert( p!=0 ); +#ifdef SQLITE_DEBUG + if( db==0 ){ + assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); + assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); + }else if( !isLookaside(db,p) ){ + assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + } +#endif + if( db ){ + if( ((uptr)p)<(uptr)(db->lookaside.pTrueEnd) ){ +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + if( ((uptr)p)>=(uptr)(db->lookaside.pMiddle) ){ + assert( sqlite3_mutex_held(db->mutex) ); + return LOOKASIDE_SMALL; + } +#endif + if( ((uptr)p)>=(uptr)(db->lookaside.pStart) ){ + assert( sqlite3_mutex_held(db->mutex) ); + return db->lookaside.szTrue; + } + } + } + return sqlite3GlobalConfig.m.xSize((void*)p); +} +SQLITE_API sqlite3_uint64 sqlite3_msize(void *p){ + assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); + assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); + return p ? sqlite3GlobalConfig.m.xSize(p) : 0; +} + +/* +** Free memory previously obtained from sqlite3Malloc(). +*/ +SQLITE_API void sqlite3_free(void *p){ + if( p==0 ) return; /* IMP: R-49053-54554 */ + assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); + assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); + if( sqlite3GlobalConfig.bMemstat ){ + sqlite3_mutex_enter(mem0.mutex); + sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, sqlite3MallocSize(p)); + sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1); + sqlite3GlobalConfig.m.xFree(p); + sqlite3_mutex_leave(mem0.mutex); + }else{ + sqlite3GlobalConfig.m.xFree(p); + } +} + +/* +** Add the size of memory allocation "p" to the count in +** *db->pnBytesFreed. +*/ +static SQLITE_NOINLINE void measureAllocationSize(sqlite3 *db, void *p){ + *db->pnBytesFreed += sqlite3DbMallocSize(db,p); +} + +/* +** Free memory that might be associated with a particular database +** connection. Calling sqlite3DbFree(D,X) for X==0 is a harmless no-op. +** The sqlite3DbFreeNN(D,X) version requires that X be non-NULL. +*/ +SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3 *db, void *p){ + assert( db==0 || sqlite3_mutex_held(db->mutex) ); + assert( p!=0 ); + if( db ){ + if( ((uptr)p)<(uptr)(db->lookaside.pEnd) ){ +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + if( ((uptr)p)>=(uptr)(db->lookaside.pMiddle) ){ + LookasideSlot *pBuf = (LookasideSlot*)p; + assert( db->pnBytesFreed==0 ); +#ifdef SQLITE_DEBUG + memset(p, 0xaa, LOOKASIDE_SMALL); /* Trash freed content */ +#endif + pBuf->pNext = db->lookaside.pSmallFree; + db->lookaside.pSmallFree = pBuf; + return; + } +#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ + if( ((uptr)p)>=(uptr)(db->lookaside.pStart) ){ + LookasideSlot *pBuf = (LookasideSlot*)p; + assert( db->pnBytesFreed==0 ); +#ifdef SQLITE_DEBUG + memset(p, 0xaa, db->lookaside.szTrue); /* Trash freed content */ +#endif + pBuf->pNext = db->lookaside.pFree; + db->lookaside.pFree = pBuf; + return; + } + } + if( db->pnBytesFreed ){ + measureAllocationSize(db, p); + return; + } + } + assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); + sqlite3MemdebugSetType(p, MEMTYPE_HEAP); + sqlite3_free(p); +} +SQLITE_PRIVATE void sqlite3DbNNFreeNN(sqlite3 *db, void *p){ + assert( db!=0 ); + assert( sqlite3_mutex_held(db->mutex) ); + assert( p!=0 ); + if( ((uptr)p)<(uptr)(db->lookaside.pEnd) ){ +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + if( ((uptr)p)>=(uptr)(db->lookaside.pMiddle) ){ + LookasideSlot *pBuf = (LookasideSlot*)p; + assert( db->pnBytesFreed==0 ); +#ifdef SQLITE_DEBUG + memset(p, 0xaa, LOOKASIDE_SMALL); /* Trash freed content */ +#endif + pBuf->pNext = db->lookaside.pSmallFree; + db->lookaside.pSmallFree = pBuf; + return; + } +#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ + if( ((uptr)p)>=(uptr)(db->lookaside.pStart) ){ + LookasideSlot *pBuf = (LookasideSlot*)p; + assert( db->pnBytesFreed==0 ); +#ifdef SQLITE_DEBUG + memset(p, 0xaa, db->lookaside.szTrue); /* Trash freed content */ +#endif + pBuf->pNext = db->lookaside.pFree; + db->lookaside.pFree = pBuf; + return; + } + } + if( db->pnBytesFreed ){ + measureAllocationSize(db, p); + return; + } + assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + sqlite3MemdebugSetType(p, MEMTYPE_HEAP); + sqlite3_free(p); +} +SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){ + assert( db==0 || sqlite3_mutex_held(db->mutex) ); + if( p ) sqlite3DbFreeNN(db, p); +} + +/* +** Change the size of an existing memory allocation +*/ +SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){ + int nOld, nNew, nDiff; + void *pNew; + assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) ); + assert( sqlite3MemdebugNoType(pOld, (u8)~MEMTYPE_HEAP) ); + if( pOld==0 ){ + return sqlite3Malloc(nBytes); /* IMP: R-04300-56712 */ + } + if( nBytes==0 ){ + sqlite3_free(pOld); /* IMP: R-26507-47431 */ + return 0; + } + if( nBytes>SQLITE_MAX_ALLOCATION_SIZE ){ + return 0; + } + nOld = sqlite3MallocSize(pOld); + /* IMPLEMENTATION-OF: R-46199-30249 SQLite guarantees that the second + ** argument to xRealloc is always a value returned by a prior call to + ** xRoundup. */ + nNew = sqlite3GlobalConfig.m.xRoundup((int)nBytes); + if( nOld==nNew ){ + pNew = pOld; + }else if( sqlite3GlobalConfig.bMemstat ){ + sqlite3_int64 nUsed; + sqlite3_mutex_enter(mem0.mutex); + sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes); + nDiff = nNew - nOld; + if( nDiff>0 && (nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)) >= + mem0.alarmThreshold-nDiff ){ + sqlite3MallocAlarm(nDiff); + if( mem0.hardLimit>0 && nUsed >= mem0.hardLimit - nDiff ){ + sqlite3_mutex_leave(mem0.mutex); + test_oom_breakpoint(1); + return 0; + } + } + pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT + if( pNew==0 && mem0.alarmThreshold>0 ){ + sqlite3MallocAlarm((int)nBytes); + pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); + } +#endif + if( pNew ){ + nNew = sqlite3MallocSize(pNew); + sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nNew-nOld); + } + sqlite3_mutex_leave(mem0.mutex); + }else{ + pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); + } + assert( EIGHT_BYTE_ALIGNMENT(pNew) ); /* IMP: R-11148-40995 */ + return pNew; +} + +/* +** The public interface to sqlite3Realloc. Make sure that the memory +** subsystem is initialized prior to invoking sqliteRealloc. +*/ +SQLITE_API void *sqlite3_realloc(void *pOld, int n){ +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + if( n<0 ) n = 0; /* IMP: R-26507-47431 */ + return sqlite3Realloc(pOld, n); +} +SQLITE_API void *sqlite3_realloc64(void *pOld, sqlite3_uint64 n){ +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return sqlite3Realloc(pOld, n); +} + + +/* +** Allocate and zero memory. +*/ +SQLITE_PRIVATE void *sqlite3MallocZero(u64 n){ + void *p = sqlite3Malloc(n); + if( p ){ + memset(p, 0, (size_t)n); + } + return p; +} + +/* +** Allocate and zero memory. If the allocation fails, make +** the mallocFailed flag in the connection pointer. +*/ +SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3 *db, u64 n){ + void *p; + testcase( db==0 ); + p = sqlite3DbMallocRaw(db, n); + if( p ) memset(p, 0, (size_t)n); + return p; +} + + +/* Finish the work of sqlite3DbMallocRawNN for the unusual and +** slower case when the allocation cannot be fulfilled using lookaside. +*/ +static SQLITE_NOINLINE void *dbMallocRawFinish(sqlite3 *db, u64 n){ + void *p; + assert( db!=0 ); + p = sqlite3Malloc(n); + if( !p ) sqlite3OomFault(db); + sqlite3MemdebugSetType(p, + (db->lookaside.bDisable==0) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP); + return p; +} + +/* +** Allocate memory, either lookaside (if possible) or heap. +** If the allocation fails, set the mallocFailed flag in +** the connection pointer. +** +** If db!=0 and db->mallocFailed is true (indicating a prior malloc +** failure on the same database connection) then always return 0. +** Hence for a particular database connection, once malloc starts +** failing, it fails consistently until mallocFailed is reset. +** This is an important assumption. There are many places in the +** code that do things like this: +** +** int *a = (int*)sqlite3DbMallocRaw(db, 100); +** int *b = (int*)sqlite3DbMallocRaw(db, 200); +** if( b ) a[10] = 9; +** +** In other words, if a subsequent malloc (ex: "b") worked, it is assumed +** that all prior mallocs (ex: "a") worked too. +** +** The sqlite3MallocRawNN() variant guarantees that the "db" parameter is +** not a NULL pointer. +*/ +SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3 *db, u64 n){ + void *p; + if( db ) return sqlite3DbMallocRawNN(db, n); + p = sqlite3Malloc(n); + sqlite3MemdebugSetType(p, MEMTYPE_HEAP); + return p; +} +SQLITE_PRIVATE void *sqlite3DbMallocRawNN(sqlite3 *db, u64 n){ +#ifndef SQLITE_OMIT_LOOKASIDE + LookasideSlot *pBuf; + assert( db!=0 ); + assert( sqlite3_mutex_held(db->mutex) ); + assert( db->pnBytesFreed==0 ); + if( n>db->lookaside.sz ){ + if( !db->lookaside.bDisable ){ + db->lookaside.anStat[1]++; + }else if( db->mallocFailed ){ + return 0; + } + return dbMallocRawFinish(db, n); + } +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + if( n<=LOOKASIDE_SMALL ){ + if( (pBuf = db->lookaside.pSmallFree)!=0 ){ + db->lookaside.pSmallFree = pBuf->pNext; + db->lookaside.anStat[0]++; + return (void*)pBuf; + }else if( (pBuf = db->lookaside.pSmallInit)!=0 ){ + db->lookaside.pSmallInit = pBuf->pNext; + db->lookaside.anStat[0]++; + return (void*)pBuf; + } + } +#endif + if( (pBuf = db->lookaside.pFree)!=0 ){ + db->lookaside.pFree = pBuf->pNext; + db->lookaside.anStat[0]++; + return (void*)pBuf; + }else if( (pBuf = db->lookaside.pInit)!=0 ){ + db->lookaside.pInit = pBuf->pNext; + db->lookaside.anStat[0]++; + return (void*)pBuf; + }else{ + db->lookaside.anStat[2]++; + } +#else + assert( db!=0 ); + assert( sqlite3_mutex_held(db->mutex) ); + assert( db->pnBytesFreed==0 ); + if( db->mallocFailed ){ + return 0; + } +#endif + return dbMallocRawFinish(db, n); +} + +/* Forward declaration */ +static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n); + +/* +** Resize the block of memory pointed to by p to n bytes. If the +** resize fails, set the mallocFailed flag in the connection object. +*/ +SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){ + assert( db!=0 ); + if( p==0 ) return sqlite3DbMallocRawNN(db, n); + assert( sqlite3_mutex_held(db->mutex) ); + if( ((uptr)p)<(uptr)db->lookaside.pEnd ){ +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + if( ((uptr)p)>=(uptr)db->lookaside.pMiddle ){ + if( n<=LOOKASIDE_SMALL ) return p; + }else +#endif + if( ((uptr)p)>=(uptr)db->lookaside.pStart ){ + if( n<=db->lookaside.szTrue ) return p; + } + } + return dbReallocFinish(db, p, n); +} +static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n){ + void *pNew = 0; + assert( db!=0 ); + assert( p!=0 ); + if( db->mallocFailed==0 ){ + if( isLookaside(db, p) ){ + pNew = sqlite3DbMallocRawNN(db, n); + if( pNew ){ + memcpy(pNew, p, lookasideMallocSize(db, p)); + sqlite3DbFree(db, p); + } + }else{ + assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + sqlite3MemdebugSetType(p, MEMTYPE_HEAP); + pNew = sqlite3Realloc(p, n); + if( !pNew ){ + sqlite3OomFault(db); + } + sqlite3MemdebugSetType(pNew, + (db->lookaside.bDisable==0 ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP)); + } + } + return pNew; +} + +/* +** Attempt to reallocate p. If the reallocation fails, then free p +** and set the mallocFailed flag in the database connection. +*/ +SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *db, void *p, u64 n){ + void *pNew; + pNew = sqlite3DbRealloc(db, p, n); + if( !pNew ){ + sqlite3DbFree(db, p); + } + return pNew; +} + +/* +** Make a copy of a string in memory obtained from sqliteMalloc(). These +** functions call sqlite3MallocRaw() directly instead of sqliteMalloc(). This +** is because when memory debugging is turned on, these two functions are +** called via macros that record the current file and line number in the +** ThreadData structure. +*/ +SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3 *db, const char *z){ + char *zNew; + size_t n; + if( z==0 ){ + return 0; + } + n = strlen(z) + 1; + zNew = sqlite3DbMallocRaw(db, n); + if( zNew ){ + memcpy(zNew, z, n); + } + return zNew; +} +SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3 *db, const char *z, u64 n){ + char *zNew; + assert( db!=0 ); + assert( z!=0 || n==0 ); + assert( (n&0x7fffffff)==n ); + zNew = z ? sqlite3DbMallocRawNN(db, n+1) : 0; + if( zNew ){ + memcpy(zNew, z, (size_t)n); + zNew[n] = 0; + } + return zNew; +} + +/* +** The text between zStart and zEnd represents a phrase within a larger +** SQL statement. Make a copy of this phrase in space obtained form +** sqlite3DbMalloc(). Omit leading and trailing whitespace. +*/ +SQLITE_PRIVATE char *sqlite3DbSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){ + int n; +#ifdef SQLITE_DEBUG + /* Because of the way the parser works, the span is guaranteed to contain + ** at least one non-space character */ + for(n=0; sqlite3Isspace(zStart[n]); n++){ assert( &zStart[n]mallocFailed, and also +** temporarily disable the lookaside memory allocator and interrupt +** any running VDBEs. +** +** Always return a NULL pointer so that this routine can be invoked using +** +** return sqlite3OomFault(db); +** +** and thereby avoid unnecessary stack frame allocations for the overwhelmingly +** common case where no OOM occurs. +*/ +SQLITE_PRIVATE void *sqlite3OomFault(sqlite3 *db){ + if( db->mallocFailed==0 && db->bBenignMalloc==0 ){ + db->mallocFailed = 1; + if( db->nVdbeExec>0 ){ + AtomicStore(&db->u1.isInterrupted, 1); + } + DisableLookaside; + if( db->pParse ){ + Parse *pParse; + sqlite3ErrorMsg(db->pParse, "out of memory"); + db->pParse->rc = SQLITE_NOMEM_BKPT; + for(pParse=db->pParse->pOuterParse; pParse; pParse = pParse->pOuterParse){ + pParse->nErr++; + pParse->rc = SQLITE_NOMEM; + } + } + } + return 0; +} + +/* +** This routine reactivates the memory allocator and clears the +** db->mallocFailed flag as necessary. +** +** The memory allocator is not restarted if there are running +** VDBEs. +*/ +SQLITE_PRIVATE void sqlite3OomClear(sqlite3 *db){ + if( db->mallocFailed && db->nVdbeExec==0 ){ + db->mallocFailed = 0; + AtomicStore(&db->u1.isInterrupted, 0); + assert( db->lookaside.bDisable>0 ); + EnableLookaside; + } +} + +/* +** Take actions at the end of an API call to deal with error codes. +*/ +static SQLITE_NOINLINE int apiHandleError(sqlite3 *db, int rc){ + if( db->mallocFailed || rc==SQLITE_IOERR_NOMEM ){ + sqlite3OomClear(db); + sqlite3Error(db, SQLITE_NOMEM); + return SQLITE_NOMEM_BKPT; + } + return rc & db->errMask; +} + +/* +** This function must be called before exiting any API function (i.e. +** returning control to the user) that has called sqlite3_malloc or +** sqlite3_realloc. +** +** The returned value is normally a copy of the second argument to this +** function. However, if a malloc() failure has occurred since the previous +** invocation SQLITE_NOMEM is returned instead. +** +** If an OOM as occurred, then the connection error-code (the value +** returned by sqlite3_errcode()) is set to SQLITE_NOMEM. +*/ +SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){ + /* If the db handle must hold the connection handle mutex here. + ** Otherwise the read (and possible write) of db->mallocFailed + ** is unsafe, as is the call to sqlite3Error(). + */ + assert( db!=0 ); + assert( sqlite3_mutex_held(db->mutex) ); + if( db->mallocFailed || rc ){ + return apiHandleError(db, rc); + } + return 0; +} + +/************** End of malloc.c **********************************************/ +/************** Begin file printf.c ******************************************/ +/* +** The "printf" code that follows dates from the 1980's. It is in +** the public domain. +** +************************************************************************** +** +** This file contains code for a set of "printf"-like routines. These +** routines format strings much like the printf() from the standard C +** library, though the implementation here has enhancements to support +** SQLite. +*/ +/* #include "sqliteInt.h" */ + +/* +** Conversion types fall into various categories as defined by the +** following enumeration. +*/ +#define etRADIX 0 /* non-decimal integer types. %x %o */ +#define etFLOAT 1 /* Floating point. %f */ +#define etEXP 2 /* Exponentional notation. %e and %E */ +#define etGENERIC 3 /* Floating or exponential, depending on exponent. %g */ +#define etSIZE 4 /* Return number of characters processed so far. %n */ +#define etSTRING 5 /* Strings. %s */ +#define etDYNSTRING 6 /* Dynamically allocated strings. %z */ +#define etPERCENT 7 /* Percent symbol. %% */ +#define etCHARX 8 /* Characters. %c */ +/* The rest are extensions, not normally found in printf() */ +#define etESCAPE_q 9 /* Strings with '\'' doubled. %q */ +#define etESCAPE_Q 10 /* Strings with '\'' doubled and enclosed in '', + NULL pointers replaced by SQL NULL. %Q */ +#define etTOKEN 11 /* a pointer to a Token structure */ +#define etSRCITEM 12 /* a pointer to a SrcItem */ +#define etPOINTER 13 /* The %p conversion */ +#define etESCAPE_w 14 /* %w -> Strings with '\"' doubled */ +#define etORDINAL 15 /* %r -> 1st, 2nd, 3rd, 4th, etc. English only */ +#define etDECIMAL 16 /* %d or %u, but not %x, %o */ + +#define etINVALID 17 /* Any unrecognized conversion type */ + + +/* +** An "etByte" is an 8-bit unsigned value. +*/ +typedef unsigned char etByte; + +/* +** Each builtin conversion character (ex: the 'd' in "%d") is described +** by an instance of the following structure +*/ +typedef struct et_info { /* Information about each format field */ + char fmttype; /* The format field code letter */ + etByte base; /* The base for radix conversion */ + etByte flags; /* One or more of FLAG_ constants below */ + etByte type; /* Conversion paradigm */ + etByte charset; /* Offset into aDigits[] of the digits string */ + etByte prefix; /* Offset into aPrefix[] of the prefix string */ + char iNxt; /* Next with same hash, or 0 for end of chain */ +} et_info; + +/* +** Allowed values for et_info.flags +*/ +#define FLAG_SIGNED 1 /* True if the value to convert is signed */ +#define FLAG_STRING 4 /* Allow infinite precision */ + +/* +** The table is searched by hash. In the case of %C where C is the character +** and that character has ASCII value j, then the hash is j%23. +** +** The order of the entries in fmtinfo[] and the hash chain was entered +** manually, but based on the output of the following TCL script: +*/ +#if 0 /***** Beginning of script ******/ +foreach c {d s g z q Q w c o u x X f e E G i n % p T S r} { + scan $c %c x + set n($c) $x +} +set mx [llength [array names n]] +puts "count: $mx" + +set mx 27 +puts "*********** mx=$mx ************" +for {set r 0} {$r<$mx} {incr r} { + puts -nonewline [format %2d: $r] + foreach c [array names n] { + if {($n($c))%$mx==$r} {puts -nonewline " $c"} + } + puts "" +} +#endif /***** End of script ********/ + +static const char aDigits[] = "0123456789ABCDEF0123456789abcdef"; +static const char aPrefix[] = "-x0\000X0"; +static const et_info fmtinfo[23] = { + /* 0 */ { 's', 0, 4, etSTRING, 0, 0, 1 }, + /* 1 */ { 'E', 0, 1, etEXP, 14, 0, 0 }, /* Hash: 0 */ + /* 2 */ { 'u', 10, 0, etDECIMAL, 0, 0, 3 }, + /* 3 */ { 'G', 0, 1, etGENERIC, 14, 0, 0 }, /* Hash: 2 */ + /* 4 */ { 'w', 0, 4, etESCAPE_w, 0, 0, 0 }, + /* 5 */ { 'x', 16, 0, etRADIX, 16, 1, 0 }, + /* 6 */ { 'c', 0, 0, etCHARX, 0, 0, 0 }, /* Hash: 7 */ + /* 7 */ { 'z', 0, 4, etDYNSTRING, 0, 0, 6 }, + /* 8 */ { 'd', 10, 1, etDECIMAL, 0, 0, 0 }, + /* 9 */ { 'e', 0, 1, etEXP, 30, 0, 0 }, + /* 10 */ { 'f', 0, 1, etFLOAT, 0, 0, 0 }, + /* 11 */ { 'g', 0, 1, etGENERIC, 30, 0, 0 }, + /* 12 */ { 'Q', 0, 4, etESCAPE_Q, 0, 0, 0 }, + /* 13 */ { 'i', 10, 1, etDECIMAL, 0, 0, 0 }, + /* 14 */ { '%', 0, 0, etPERCENT, 0, 0, 16 }, + /* 15 */ { 'T', 0, 0, etTOKEN, 0, 0, 0 }, + /* 16 */ { 'S', 0, 0, etSRCITEM, 0, 0, 0 }, /* Hash: 14 */ + /* 17 */ { 'X', 16, 0, etRADIX, 0, 4, 0 }, /* Hash: 19 */ + /* 18 */ { 'n', 0, 0, etSIZE, 0, 0, 0 }, + /* 19 */ { 'o', 8, 0, etRADIX, 0, 2, 17 }, + /* 20 */ { 'p', 16, 0, etPOINTER, 0, 1, 0 }, + /* 21 */ { 'q', 0, 4, etESCAPE_q, 0, 0, 0 }, + /* 22 */ { 'r', 10, 1, etORDINAL, 0, 0, 0 } +}; + +/* Additional Notes: +** +** %S Takes a pointer to SrcItem. Shows name or database.name +** %!S Like %S but prefer the zName over the zAlias +*/ + +/* +** Set the StrAccum object to an error mode. +*/ +SQLITE_PRIVATE void sqlite3StrAccumSetError(StrAccum *p, u8 eError){ + assert( eError==SQLITE_NOMEM || eError==SQLITE_TOOBIG ); + p->accError = eError; + if( p->mxAlloc ) sqlite3_str_reset(p); + if( eError==SQLITE_TOOBIG ) sqlite3ErrorToParser(p->db, eError); +} + +/* +** Extra argument values from a PrintfArguments object +*/ +static sqlite3_int64 getIntArg(PrintfArguments *p){ + if( p->nArg<=p->nUsed ) return 0; + return sqlite3_value_int64(p->apArg[p->nUsed++]); +} +static double getDoubleArg(PrintfArguments *p){ + if( p->nArg<=p->nUsed ) return 0.0; + return sqlite3_value_double(p->apArg[p->nUsed++]); +} +static char *getTextArg(PrintfArguments *p){ + if( p->nArg<=p->nUsed ) return 0; + return (char*)sqlite3_value_text(p->apArg[p->nUsed++]); +} + +/* +** Allocate memory for a temporary buffer needed for printf rendering. +** +** If the requested size of the temp buffer is larger than the size +** of the output buffer in pAccum, then cause an SQLITE_TOOBIG error. +** Do the size check before the memory allocation to prevent rogue +** SQL from requesting large allocations using the precision or width +** field of the printf() function. +*/ +static char *printfTempBuf(sqlite3_str *pAccum, sqlite3_int64 n){ + char *z; + if( pAccum->accError ) return 0; + if( n>pAccum->nAlloc && n>pAccum->mxAlloc ){ + sqlite3StrAccumSetError(pAccum, SQLITE_TOOBIG); + return 0; + } + z = sqlite3_malloc(n); + if( z==0 ){ + sqlite3StrAccumSetError(pAccum, SQLITE_NOMEM); + } + return z; +} + +/* +** On machines with a small stack size, you can redefine the +** SQLITE_PRINT_BUF_SIZE to be something smaller, if desired. +*/ +#ifndef SQLITE_PRINT_BUF_SIZE +# define SQLITE_PRINT_BUF_SIZE 70 +#endif +#define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */ + +/* +** Hard limit on the precision of floating-point conversions. +*/ +#ifndef SQLITE_PRINTF_PRECISION_LIMIT +# define SQLITE_FP_PRECISION_LIMIT 100000000 +#endif + +/* +** Render a string given by "fmt" into the StrAccum object. +*/ +SQLITE_API void sqlite3_str_vappendf( + sqlite3_str *pAccum, /* Accumulate results here */ + const char *fmt, /* Format string */ + va_list ap /* arguments */ +){ + int c; /* Next character in the format string */ + char *bufpt; /* Pointer to the conversion buffer */ + int precision; /* Precision of the current field */ + int length; /* Length of the field */ + int idx; /* A general purpose loop counter */ + int width; /* Width of the current field */ + etByte flag_leftjustify; /* True if "-" flag is present */ + etByte flag_prefix; /* '+' or ' ' or 0 for prefix */ + etByte flag_alternateform; /* True if "#" flag is present */ + etByte flag_altform2; /* True if "!" flag is present */ + etByte flag_zeropad; /* True if field width constant starts with zero */ + etByte flag_long; /* 1 for the "l" flag, 2 for "ll", 0 by default */ + etByte done; /* Loop termination flag */ + etByte cThousand; /* Thousands separator for %d and %u */ + etByte xtype = etINVALID; /* Conversion paradigm */ + u8 bArgList; /* True for SQLITE_PRINTF_SQLFUNC */ + char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */ + sqlite_uint64 longvalue; /* Value for integer types */ + double realvalue; /* Value for real types */ + const et_info *infop; /* Pointer to the appropriate info structure */ + char *zOut; /* Rendering buffer */ + int nOut; /* Size of the rendering buffer */ + char *zExtra = 0; /* Malloced memory used by some conversion */ + int exp, e2; /* exponent of real numbers */ + etByte flag_dp; /* True if decimal point should be shown */ + etByte flag_rtz; /* True if trailing zeros should be removed */ + + PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */ + char buf[etBUFSIZE]; /* Conversion buffer */ + + /* pAccum never starts out with an empty buffer that was obtained from + ** malloc(). This precondition is required by the mprintf("%z...") + ** optimization. */ + assert( pAccum->nChar>0 || (pAccum->printfFlags&SQLITE_PRINTF_MALLOCED)==0 ); + + bufpt = 0; + if( (pAccum->printfFlags & SQLITE_PRINTF_SQLFUNC)!=0 ){ + pArgList = va_arg(ap, PrintfArguments*); + bArgList = 1; + }else{ + bArgList = 0; + } + for(; (c=(*fmt))!=0; ++fmt){ + if( c!='%' ){ + bufpt = (char *)fmt; +#if HAVE_STRCHRNUL + fmt = strchrnul(fmt, '%'); +#else + fmt = strchr(fmt, '%'); + if( fmt==0 ){ + fmt = bufpt + strlen(bufpt); + } +#endif + sqlite3_str_append(pAccum, bufpt, (int)(fmt - bufpt)); + if( *fmt==0 ) break; + } + if( (c=(*++fmt))==0 ){ + sqlite3_str_append(pAccum, "%", 1); + break; + } + /* Find out what flags are present */ + flag_leftjustify = flag_prefix = cThousand = + flag_alternateform = flag_altform2 = flag_zeropad = 0; + done = 0; + width = 0; + flag_long = 0; + precision = -1; + do{ + switch( c ){ + case '-': flag_leftjustify = 1; break; + case '+': flag_prefix = '+'; break; + case ' ': flag_prefix = ' '; break; + case '#': flag_alternateform = 1; break; + case '!': flag_altform2 = 1; break; + case '0': flag_zeropad = 1; break; + case ',': cThousand = ','; break; + default: done = 1; break; + case 'l': { + flag_long = 1; + c = *++fmt; + if( c=='l' ){ + c = *++fmt; + flag_long = 2; + } + done = 1; + break; + } + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': { + unsigned wx = c - '0'; + while( (c = *++fmt)>='0' && c<='9' ){ + wx = wx*10 + c - '0'; + } + testcase( wx>0x7fffffff ); + width = wx & 0x7fffffff; +#ifdef SQLITE_PRINTF_PRECISION_LIMIT + if( width>SQLITE_PRINTF_PRECISION_LIMIT ){ + width = SQLITE_PRINTF_PRECISION_LIMIT; + } +#endif + if( c!='.' && c!='l' ){ + done = 1; + }else{ + fmt--; + } + break; + } + case '*': { + if( bArgList ){ + width = (int)getIntArg(pArgList); + }else{ + width = va_arg(ap,int); + } + if( width<0 ){ + flag_leftjustify = 1; + width = width >= -2147483647 ? -width : 0; + } +#ifdef SQLITE_PRINTF_PRECISION_LIMIT + if( width>SQLITE_PRINTF_PRECISION_LIMIT ){ + width = SQLITE_PRINTF_PRECISION_LIMIT; + } +#endif + if( (c = fmt[1])!='.' && c!='l' ){ + c = *++fmt; + done = 1; + } + break; + } + case '.': { + c = *++fmt; + if( c=='*' ){ + if( bArgList ){ + precision = (int)getIntArg(pArgList); + }else{ + precision = va_arg(ap,int); + } + if( precision<0 ){ + precision = precision >= -2147483647 ? -precision : -1; + } + c = *++fmt; + }else{ + unsigned px = 0; + while( c>='0' && c<='9' ){ + px = px*10 + c - '0'; + c = *++fmt; + } + testcase( px>0x7fffffff ); + precision = px & 0x7fffffff; + } +#ifdef SQLITE_PRINTF_PRECISION_LIMIT + if( precision>SQLITE_PRINTF_PRECISION_LIMIT ){ + precision = SQLITE_PRINTF_PRECISION_LIMIT; + } +#endif + if( c=='l' ){ + --fmt; + }else{ + done = 1; + } + break; + } + } + }while( !done && (c=(*++fmt))!=0 ); + + /* Fetch the info entry for the field */ +#ifdef SQLITE_EBCDIC + /* The hash table only works for ASCII. For EBCDIC, we need to do + ** a linear search of the table */ + infop = &fmtinfo[0]; + xtype = etINVALID; + for(idx=0; idxtype; + break; + } + } +#else + /* Fast hash-table lookup */ + assert( ArraySize(fmtinfo)==23 ); + idx = ((unsigned)c) % 23; + if( fmtinfo[idx].fmttype==c + || fmtinfo[idx = fmtinfo[idx].iNxt].fmttype==c + ){ + infop = &fmtinfo[idx]; + xtype = infop->type; + }else{ + infop = &fmtinfo[0]; + xtype = etINVALID; + } +#endif + + /* + ** At this point, variables are initialized as follows: + ** + ** flag_alternateform TRUE if a '#' is present. + ** flag_altform2 TRUE if a '!' is present. + ** flag_prefix '+' or ' ' or zero + ** flag_leftjustify TRUE if a '-' is present or if the + ** field width was negative. + ** flag_zeropad TRUE if the width began with 0. + ** flag_long 1 for "l", 2 for "ll" + ** width The specified field width. This is + ** always non-negative. Zero is the default. + ** precision The specified precision. The default + ** is -1. + ** xtype The class of the conversion. + ** infop Pointer to the appropriate info struct. + */ + assert( width>=0 ); + assert( precision>=(-1) ); + switch( xtype ){ + case etPOINTER: + flag_long = sizeof(char*)==sizeof(i64) ? 2 : + sizeof(char*)==sizeof(long int) ? 1 : 0; + /* no break */ deliberate_fall_through + case etORDINAL: + case etRADIX: + cThousand = 0; + /* no break */ deliberate_fall_through + case etDECIMAL: + if( infop->flags & FLAG_SIGNED ){ + i64 v; + if( bArgList ){ + v = getIntArg(pArgList); + }else if( flag_long ){ + if( flag_long==2 ){ + v = va_arg(ap,i64) ; + }else{ + v = va_arg(ap,long int); + } + }else{ + v = va_arg(ap,int); + } + if( v<0 ){ + testcase( v==SMALLEST_INT64 ); + testcase( v==(-1) ); + longvalue = ~v; + longvalue++; + prefix = '-'; + }else{ + longvalue = v; + prefix = flag_prefix; + } + }else{ + if( bArgList ){ + longvalue = (u64)getIntArg(pArgList); + }else if( flag_long ){ + if( flag_long==2 ){ + longvalue = va_arg(ap,u64); + }else{ + longvalue = va_arg(ap,unsigned long int); + } + }else{ + longvalue = va_arg(ap,unsigned int); + } + prefix = 0; + } + +#if WHERETRACE_ENABLED + if( xtype==etPOINTER && sqlite3WhereTrace & 0x100000 ) longvalue = 0; +#endif +#if TREETRACE_ENABLED + if( xtype==etPOINTER && sqlite3TreeTrace & 0x100000 ) longvalue = 0; +#endif + + if( longvalue==0 ) flag_alternateform = 0; + if( flag_zeropad && precision=4 || (longvalue/10)%10==1 ){ + x = 0; + } + *(--bufpt) = zOrd[x*2+1]; + *(--bufpt) = zOrd[x*2]; + } + { + const char *cset = &aDigits[infop->charset]; + u8 base = infop->base; + do{ /* Convert to ascii */ + *(--bufpt) = cset[longvalue%base]; + longvalue = longvalue/base; + }while( longvalue>0 ); + } + length = (int)(&zOut[nOut-1]-bufpt); + if( precision>length ){ /* zero pad */ + int nn = precision-length; + bufpt -= nn; + memset(bufpt,'0',nn); + length = precision; + } + if( cThousand ){ + int nn = (length - 1)/3; /* Number of "," to insert */ + int ix = (length - 1)%3 + 1; + bufpt -= nn; + for(idx=0; nn>0; idx++){ + bufpt[idx] = bufpt[idx+nn]; + ix--; + if( ix==0 ){ + bufpt[++idx] = cThousand; + nn--; + ix = 3; + } + } + } + if( prefix ) *(--bufpt) = prefix; /* Add sign */ + if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */ + const char *pre; + char x; + pre = &aPrefix[infop->prefix]; + for(; (x=(*pre))!=0; pre++) *(--bufpt) = x; + } + length = (int)(&zOut[nOut-1]-bufpt); + break; + case etFLOAT: + case etEXP: + case etGENERIC: { + FpDecode s; + int iRound; + int j; + i64 szBufNeeded; /* Size needed to hold the output */ + + if( bArgList ){ + realvalue = getDoubleArg(pArgList); + }else{ + realvalue = va_arg(ap,double); + } + if( precision<0 ) precision = 6; /* Set default precision */ +#ifdef SQLITE_FP_PRECISION_LIMIT + if( precision>SQLITE_FP_PRECISION_LIMIT ){ + precision = SQLITE_FP_PRECISION_LIMIT; + } +#endif + if( xtype==etFLOAT ){ + iRound = -precision; + }else if( xtype==etGENERIC ){ + if( precision==0 ) precision = 1; + iRound = precision; + }else{ + iRound = precision+1; + } + sqlite3FpDecode(&s, realvalue, iRound, flag_altform2 ? 20 : 16); + if( s.isSpecial ){ + if( s.isSpecial==2 ){ + bufpt = flag_zeropad ? "null" : "NaN"; + length = sqlite3Strlen30(bufpt); + break; + }else if( flag_zeropad ){ + s.z[0] = '9'; + s.iDP = 1000; + s.n = 1; + }else{ + memcpy(buf, "-Inf", 5); + bufpt = buf; + if( s.sign=='-' ){ + /* no-op */ + }else if( flag_prefix ){ + buf[0] = flag_prefix; + }else{ + bufpt++; + } + length = sqlite3Strlen30(bufpt); + break; + } + } + if( s.sign=='-' ){ + if( flag_alternateform + && !flag_prefix + && xtype==etFLOAT + && s.iDP<=iRound + ){ + /* Suppress the minus sign if all of the following are true: + ** * The value displayed is zero + ** * The '#' flag is used + ** * The '+' flag is not used, and + ** * The format is %f + */ + prefix = 0; + }else{ + prefix = '-'; + } + }else{ + prefix = flag_prefix; + } + + exp = s.iDP-1; + + /* + ** If the field type is etGENERIC, then convert to either etEXP + ** or etFLOAT, as appropriate. + */ + if( xtype==etGENERIC ){ + assert( precision>0 ); + precision--; + flag_rtz = !flag_alternateform; + if( exp<-4 || exp>precision ){ + xtype = etEXP; + }else{ + precision = precision - exp; + xtype = etFLOAT; + } + }else{ + flag_rtz = flag_altform2; + } + if( xtype==etEXP ){ + e2 = 0; + }else{ + e2 = s.iDP - 1; + } + + szBufNeeded = MAX(e2,0)+(i64)precision+(i64)width+10; + if( cThousand && e2>0 ) szBufNeeded += (e2+2)/3; + if( szBufNeeded + pAccum->nChar >= pAccum->nAlloc ){ + if( pAccum->mxAlloc==0 && pAccum->accError==0 ){ + /* Unable to allocate space in pAccum, perhaps because it + ** is coming from sqlite3_snprintf() or similar. We'll have + ** to render into temporary space and the memcpy() it over. */ + bufpt = sqlite3_malloc(szBufNeeded); + if( bufpt==0 ){ + sqlite3StrAccumSetError(pAccum, SQLITE_NOMEM); + return; + } + zExtra = bufpt; + }else if( sqlite3StrAccumEnlarge(pAccum, szBufNeeded)zText + pAccum->nChar; + } + }else{ + bufpt = pAccum->zText + pAccum->nChar; + } + zOut = bufpt; + + flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2; + /* The sign in front of the number */ + if( prefix ){ + *(bufpt++) = prefix; + } + /* Digits prior to the decimal point */ + j = 0; + assert( s.n>0 ); + if( e2<0 ){ + *(bufpt++) = '0'; + }else if( cThousand ){ + for(; e2>=0; e2--){ + *(bufpt++) = j1 ) *(bufpt++) = ','; + } + }else{ + j = e2+1; + if( j>s.n ) j = s.n; + memcpy(bufpt, s.z, j); + bufpt += j; + e2 -= j; + if( e2>=0 ){ + memset(bufpt, '0', e2+1); + bufpt += e2+1; + e2 = -1; + } + } + /* The decimal point */ + if( flag_dp ){ + *(bufpt++) = '.'; + } + /* "0" digits after the decimal point but before the first + ** significant digit of the number */ + if( e2<(-1) && precision>0 ){ + int nn = -1-e2; + if( nn>precision ) nn = precision; + memset(bufpt, '0', nn); + bufpt += nn; + precision -= nn; + } + /* Significant digits after the decimal point */ + if( precision>0 ){ + int nn = s.n - j; + if( NEVER(nn>precision) ) nn = precision; + if( nn>0 ){ + memcpy(bufpt, s.z+j, nn); + bufpt += nn; + precision -= nn; + } + if( precision>0 && !flag_rtz ){ + memset(bufpt, '0', precision); + bufpt += precision; + } + } + /* Remove trailing zeros and the "." if no digits follow the "." */ + if( flag_rtz && flag_dp ){ + while( bufpt[-1]=='0' ) *(--bufpt) = 0; + assert( bufpt>zOut ); + if( bufpt[-1]=='.' ){ + if( flag_altform2 ){ + *(bufpt++) = '0'; + }else{ + *(--bufpt) = 0; + } + } + } + /* Add the "eNNN" suffix */ + if( xtype==etEXP ){ + exp = s.iDP - 1; + *(bufpt++) = aDigits[infop->charset]; + if( exp<0 ){ + *(bufpt++) = '-'; exp = -exp; + }else{ + *(bufpt++) = '+'; + } + if( exp>=100 ){ + *(bufpt++) = (char)((exp/100)+'0'); /* 100's digit */ + exp %= 100; + } + *(bufpt++) = (char)(exp/10+'0'); /* 10's digit */ + *(bufpt++) = (char)(exp%10+'0'); /* 1's digit */ + } + + length = (int)(bufpt-zOut); + assert( length <= szBufNeeded ); + if( lengthnChar += length; + zOut[length] = 0; + continue; + }else{ + /* We were unable to render directly into pAccum because we + ** couldn't allocate sufficient memory. We need to memcpy() + ** the rendering (or some prefix thereof) into the output + ** buffer. */ + bufpt[0] = 0; + bufpt = zExtra; + break; + } + } + case etSIZE: + if( !bArgList ){ + *(va_arg(ap,int*)) = pAccum->nChar; + } + length = width = 0; + break; + case etPERCENT: + buf[0] = '%'; + bufpt = buf; + length = 1; + break; + case etCHARX: + if( bArgList ){ + bufpt = getTextArg(pArgList); + length = 1; + if( bufpt ){ + buf[0] = c = *(bufpt++); + if( (c&0xc0)==0xc0 ){ + while( length<4 && (bufpt[0]&0xc0)==0x80 ){ + buf[length++] = *(bufpt++); + } + } + }else{ + buf[0] = 0; + } + }else{ + unsigned int ch = va_arg(ap,unsigned int); + length = sqlite3AppendOneUtf8Character(buf, ch); + } + if( precision>1 ){ + i64 nPrior = 1; + width -= precision-1; + if( width>1 && !flag_leftjustify ){ + sqlite3_str_appendchar(pAccum, width-1, ' '); + width = 0; + } + sqlite3_str_append(pAccum, buf, length); + precision--; + while( precision > 1 ){ + i64 nCopyBytes; + if( nPrior > precision-1 ) nPrior = precision - 1; + nCopyBytes = length*nPrior; + if( sqlite3StrAccumEnlargeIfNeeded(pAccum, nCopyBytes) ){ + break; + } + sqlite3_str_append(pAccum, + &pAccum->zText[pAccum->nChar-nCopyBytes], nCopyBytes); + precision -= nPrior; + nPrior *= 2; + } + } + bufpt = buf; + flag_altform2 = 1; + goto adjust_width_for_utf8; + case etSTRING: + case etDYNSTRING: + if( bArgList ){ + bufpt = getTextArg(pArgList); + xtype = etSTRING; + }else{ + bufpt = va_arg(ap,char*); + } + if( bufpt==0 ){ + bufpt = ""; + }else if( xtype==etDYNSTRING ){ + if( pAccum->nChar==0 + && pAccum->mxAlloc + && width==0 + && precision<0 + && pAccum->accError==0 + ){ + /* Special optimization for sqlite3_mprintf("%z..."): + ** Extend an existing memory allocation rather than creating + ** a new one. */ + assert( (pAccum->printfFlags&SQLITE_PRINTF_MALLOCED)==0 ); + pAccum->zText = bufpt; + pAccum->nAlloc = sqlite3DbMallocSize(pAccum->db, bufpt); + pAccum->nChar = 0x7fffffff & (int)strlen(bufpt); + pAccum->printfFlags |= SQLITE_PRINTF_MALLOCED; + length = 0; + break; + } + zExtra = bufpt; + } + if( precision>=0 ){ + if( flag_altform2 ){ + /* Set length to the number of bytes needed in order to display + ** precision characters */ + unsigned char *z = (unsigned char*)bufpt; + while( precision-- > 0 && z[0] ){ + SQLITE_SKIP_UTF8(z); + } + length = (int)(z - (unsigned char*)bufpt); + }else{ + for(length=0; length0 ){ + /* Adjust width to account for extra bytes in UTF-8 characters */ + int ii = length - 1; + while( ii>=0 ) if( (bufpt[ii--] & 0xc0)==0x80 ) width++; + } + break; + case etESCAPE_q: /* %q: Escape ' characters */ + case etESCAPE_Q: /* %Q: Escape ' and enclose in '...' */ + case etESCAPE_w: { /* %w: Escape " characters */ + i64 i, j, k, n; + int needQuote = 0; + char ch; + char *escarg; + char q; + + if( bArgList ){ + escarg = getTextArg(pArgList); + }else{ + escarg = va_arg(ap,char*); + } + if( escarg==0 ){ + escarg = (xtype==etESCAPE_Q ? "NULL" : "(NULL)"); + }else if( xtype==etESCAPE_Q ){ + needQuote = 1; + } + if( xtype==etESCAPE_w ){ + q = '"'; + flag_alternateform = 0; + }else{ + q = '\''; + } + /* For %q, %Q, and %w, the precision is the number of bytes (or + ** characters if the ! flags is present) to use from the input. + ** Because of the extra quoting characters inserted, the number + ** of output characters may be larger than the precision. + */ + k = precision; + for(i=n=0; k!=0 && (ch=escarg[i])!=0; i++, k--){ + if( ch==q ) n++; + if( flag_altform2 && (ch&0xc0)==0xc0 ){ + while( (escarg[i+1]&0xc0)==0x80 ){ i++; } + } + } + if( flag_alternateform ){ + /* For %#q, do unistr()-style backslash escapes for + ** all control characters, and for backslash itself. + ** For %#Q, do the same but only if there is at least + ** one control character. */ + i64 nBack = 0; + i64 nCtrl = 0; + for(k=0; ketBUFSIZE ){ + bufpt = zExtra = printfTempBuf(pAccum, n); + if( bufpt==0 ) return; + }else{ + bufpt = buf; + } + j = 0; + if( needQuote ){ + if( needQuote==2 ){ + memcpy(&bufpt[j], "unistr('", 8); + j += 8; + }else{ + bufpt[j++] = '\''; + } + } + k = i; + if( flag_alternateform ){ + for(i=0; i=0x10 ? '1' : '0'; + bufpt[j++] = "0123456789abcdef"[ch&0xf]; + } + } + }else{ + for(i=0; iprintfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return; + if( flag_alternateform ){ + /* %#T means an Expr pointer that uses Expr.u.zToken */ + Expr *pExpr = va_arg(ap,Expr*); + if( ALWAYS(pExpr) && ALWAYS(!ExprHasProperty(pExpr,EP_IntValue)) ){ + sqlite3_str_appendall(pAccum, (const char*)pExpr->u.zToken); + sqlite3RecordErrorOffsetOfExpr(pAccum->db, pExpr); + } + }else{ + /* %T means a Token pointer */ + Token *pToken = va_arg(ap, Token*); + assert( bArgList==0 ); + if( pToken && pToken->n ){ + sqlite3_str_append(pAccum, (const char*)pToken->z, pToken->n); + sqlite3RecordErrorByteOffset(pAccum->db, pToken->z); + } + } + length = width = 0; + break; + } + case etSRCITEM: { + SrcItem *pItem; + if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return; + pItem = va_arg(ap, SrcItem*); + assert( bArgList==0 ); + if( pItem->zAlias && !flag_altform2 ){ + sqlite3_str_appendall(pAccum, pItem->zAlias); + }else if( pItem->zName ){ + if( pItem->fg.fixedSchema==0 + && pItem->fg.isSubquery==0 + && pItem->u4.zDatabase!=0 + ){ + sqlite3_str_appendall(pAccum, pItem->u4.zDatabase); + sqlite3_str_append(pAccum, ".", 1); + } + sqlite3_str_appendall(pAccum, pItem->zName); + }else if( pItem->zAlias ){ + sqlite3_str_appendall(pAccum, pItem->zAlias); + }else if( ALWAYS(pItem->fg.isSubquery) ){/* Because of tag-20240424-1 */ + Select *pSel = pItem->u4.pSubq->pSelect; + assert( pSel!=0 ); + if( pSel->selFlags & SF_NestedFrom ){ + sqlite3_str_appendf(pAccum, "(join-%u)", pSel->selId); + }else if( pSel->selFlags & SF_MultiValue ){ + assert( !pItem->fg.isTabFunc && !pItem->fg.isIndexedBy ); + sqlite3_str_appendf(pAccum, "%u-ROW VALUES CLAUSE", + pItem->u1.nRow); + }else{ + sqlite3_str_appendf(pAccum, "(subquery-%u)", pSel->selId); + } + } + length = width = 0; + break; + } + default: { + assert( xtype==etINVALID ); + return; + } + }/* End switch over the format type */ + /* + ** The text of the conversion is pointed to by "bufpt" and is + ** "length" characters long. The field width is "width". Do + ** the output. Both length and width are in bytes, not characters, + ** at this point. If the "!" flag was present on string conversions + ** indicating that width and precision should be expressed in characters, + ** then the values have been translated prior to reaching this point. + */ + width -= length; + if( width>0 ){ + if( !flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' '); + sqlite3_str_append(pAccum, bufpt, length); + if( flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' '); + }else{ + sqlite3_str_append(pAccum, bufpt, length); + } + + if( zExtra ){ + sqlite3DbFree(pAccum->db, zExtra); + zExtra = 0; + } + }/* End for loop over the format string */ +} /* End of function */ + + +/* +** The z string points to the first character of a token that is +** associated with an error. If db does not already have an error +** byte offset recorded, try to compute the error byte offset for +** z and set the error byte offset in db. +*/ +SQLITE_PRIVATE void sqlite3RecordErrorByteOffset(sqlite3 *db, const char *z){ + const Parse *pParse; + const char *zText; + const char *zEnd; + assert( z!=0 ); + if( NEVER(db==0) ) return; + if( db->errByteOffset!=(-2) ) return; + pParse = db->pParse; + if( NEVER(pParse==0) ) return; + zText =pParse->zTail; + if( NEVER(zText==0) ) return; + zEnd = &zText[strlen(zText)]; + if( SQLITE_WITHIN(z,zText,zEnd) ){ + db->errByteOffset = (int)(z-zText); + } +} + +/* +** If pExpr has a byte offset for the start of a token, record that as +** as the error offset. +*/ +SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3 *db, const Expr *pExpr){ + while( pExpr + && (ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) || pExpr->w.iOfst<=0) + ){ + pExpr = pExpr->pLeft; + } + if( pExpr==0 ) return; + if( ExprHasProperty(pExpr, EP_FromDDL) ) return; + db->errByteOffset = pExpr->w.iOfst; +} + +/* +** Enlarge the memory allocation on a StrAccum object so that it is +** able to accept at least N more bytes of text. +** +** Return the number of bytes of text that StrAccum is able to accept +** after the attempted enlargement. The value returned might be zero. +*/ +SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum *p, i64 N){ + char *zNew; + assert( p->nChar+N >= p->nAlloc ); /* Only called if really needed */ + if( p->accError ){ + testcase(p->accError==SQLITE_TOOBIG); + testcase(p->accError==SQLITE_NOMEM); + return 0; + } + if( p->mxAlloc==0 ){ + sqlite3StrAccumSetError(p, SQLITE_TOOBIG); + return p->nAlloc - p->nChar - 1; + }else{ + char *zOld = isMalloced(p) ? p->zText : 0; + i64 szNew = p->nChar + N + 1; + if( szNew+p->nChar<=p->mxAlloc ){ + /* Force exponential buffer size growth as long as it does not overflow, + ** to avoid having to call this routine too often */ + szNew += p->nChar; + } + if( szNew > p->mxAlloc ){ + sqlite3_str_reset(p); + sqlite3StrAccumSetError(p, SQLITE_TOOBIG); + return 0; + }else{ + p->nAlloc = (int)szNew; + } + if( p->db ){ + zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc); + }else{ + zNew = sqlite3Realloc(zOld, p->nAlloc); + } + if( zNew ){ + assert( p->zText!=0 || p->nChar==0 ); + if( !isMalloced(p) && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar); + p->zText = zNew; + p->nAlloc = sqlite3DbMallocSize(p->db, zNew); + p->printfFlags |= SQLITE_PRINTF_MALLOCED; + }else{ + sqlite3_str_reset(p); + sqlite3StrAccumSetError(p, SQLITE_NOMEM); + return 0; + } + } + assert( N>=0 && N<=0x7fffffff ); + return (int)N; +} + +SQLITE_PRIVATE int sqlite3StrAccumEnlargeIfNeeded(StrAccum *p, i64 N){ + if( N + p->nChar >= p->nAlloc ){ + sqlite3StrAccumEnlarge(p, N); + } + return p->accError; +} + +/* +** Append N copies of character c to the given string buffer. +*/ +SQLITE_API void sqlite3_str_appendchar(sqlite3_str *p, int N, char c){ + testcase( p->nChar + (i64)N > 0x7fffffff ); + if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){ + return; + } + while( (N--)>0 ) p->zText[p->nChar++] = c; +} + +/* +** The StrAccum "p" is not large enough to accept N new bytes of z[]. +** So enlarge if first, then do the append. +** +** This is a helper routine to sqlite3_str_append() that does special-case +** work (enlarging the buffer) using tail recursion, so that the +** sqlite3_str_append() routine can use fast calling semantics. +*/ +static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){ + N = sqlite3StrAccumEnlarge(p, N); + if( N>0 ){ + memcpy(&p->zText[p->nChar], z, N); + p->nChar += N; + } +} + +/* +** Append N bytes of text from z to the StrAccum object. Increase the +** size of the memory allocation for StrAccum if necessary. +*/ +SQLITE_API void sqlite3_str_append(sqlite3_str *p, const char *z, int N){ + assert( z!=0 || N==0 ); + assert( p->zText!=0 || p->nChar==0 || p->accError ); + assert( N>=0 ); + assert( p->accError==0 || p->nAlloc==0 || p->mxAlloc==0 ); + if( p->nChar+N >= p->nAlloc ){ + enlargeAndAppend(p,z,N); + }else if( N ){ + assert( p->zText ); + p->nChar += N; + memcpy(&p->zText[p->nChar-N], z, N); + } +} + +/* +** Append the complete text of zero-terminated string z[] to the p string. +*/ +SQLITE_API void sqlite3_str_appendall(sqlite3_str *p, const char *z){ + sqlite3_str_append(p, z, sqlite3Strlen30(z)); +} + + +/* +** Finish off a string by making sure it is zero-terminated. +** Return a pointer to the resulting string. Return a NULL +** pointer if any kind of error was encountered. +*/ +static SQLITE_NOINLINE char *strAccumFinishRealloc(StrAccum *p){ + char *zText; + assert( p->mxAlloc>0 && !isMalloced(p) ); + zText = sqlite3DbMallocRaw(p->db, 1+(u64)p->nChar ); + if( zText ){ + memcpy(zText, p->zText, p->nChar+1); + p->printfFlags |= SQLITE_PRINTF_MALLOCED; + }else{ + sqlite3StrAccumSetError(p, SQLITE_NOMEM); + } + p->zText = zText; + return zText; +} +SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){ + if( p->zText ){ + p->zText[p->nChar] = 0; + if( p->mxAlloc>0 && !isMalloced(p) ){ + return strAccumFinishRealloc(p); + } + } + return p->zText; +} + +/* +** Use the content of the StrAccum passed as the second argument +** as the result of an SQL function. +*/ +SQLITE_PRIVATE void sqlite3ResultStrAccum(sqlite3_context *pCtx, StrAccum *p){ + if( p->accError ){ + sqlite3_result_error_code(pCtx, p->accError); + sqlite3_str_reset(p); + }else if( isMalloced(p) ){ + sqlite3_result_text(pCtx, p->zText, p->nChar, SQLITE_DYNAMIC); + }else{ + sqlite3_result_text(pCtx, "", 0, SQLITE_STATIC); + sqlite3_str_reset(p); + } +} + +/* +** This singleton is an sqlite3_str object that is returned if +** sqlite3_malloc() fails to provide space for a real one. This +** sqlite3_str object accepts no new text and always returns +** an SQLITE_NOMEM error. +*/ +static sqlite3_str sqlite3OomStr = { + 0, 0, 0, 0, 0, SQLITE_NOMEM, 0 +}; + +/* Finalize a string created using sqlite3_str_new(). +*/ +SQLITE_API char *sqlite3_str_finish(sqlite3_str *p){ + char *z; + if( p!=0 && p!=&sqlite3OomStr ){ + z = sqlite3StrAccumFinish(p); + sqlite3_free(p); + }else{ + z = 0; + } + return z; +} + +/* Return any error code associated with p */ +SQLITE_API int sqlite3_str_errcode(sqlite3_str *p){ + return p ? p->accError : SQLITE_NOMEM; +} + +/* Return the current length of p in bytes */ +SQLITE_API int sqlite3_str_length(sqlite3_str *p){ + return p ? p->nChar : 0; +} + +/* Truncate the text of the string to be no more than N bytes. */ +SQLITE_API void sqlite3_str_truncate(sqlite3_str *p, int N){ + if( p!=0 && N>=0 && (u32)NnChar ){ + p->nChar = N; + p->zText[p->nChar] = 0; + } +} + +/* Return the current value for p */ +SQLITE_API char *sqlite3_str_value(sqlite3_str *p){ + if( p==0 || p->nChar==0 ) return 0; + p->zText[p->nChar] = 0; + return p->zText; +} + +/* +** Reset an StrAccum string. Reclaim all malloced memory. +*/ +SQLITE_API void sqlite3_str_reset(StrAccum *p){ + if( isMalloced(p) ){ + sqlite3DbFree(p->db, p->zText); + p->printfFlags &= ~SQLITE_PRINTF_MALLOCED; + } + p->nAlloc = 0; + p->nChar = 0; + p->zText = 0; +} + +/* +** Destroy a dynamically allocate sqlite3_str object and all +** of its content, all in one call. +*/ +SQLITE_API void sqlite3_str_free(sqlite3_str *p){ + if( p!=0 && p!=&sqlite3OomStr ){ + sqlite3_str_reset(p); + sqlite3_free(p); + } +} + +/* +** Initialize a string accumulator. +** +** p: The accumulator to be initialized. +** db: Pointer to a database connection. May be NULL. Lookaside +** memory is used if not NULL. db->mallocFailed is set appropriately +** when not NULL. +** zBase: An initial buffer. May be NULL in which case the initial buffer +** is malloced. +** n: Size of zBase in bytes. If total space requirements never exceed +** n then no memory allocations ever occur. +** mx: Maximum number of bytes to accumulate. If mx==0 then no memory +** allocations will ever occur. +*/ +SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){ + p->zText = zBase; + p->db = db; + p->nAlloc = n; + p->mxAlloc = mx; + p->nChar = 0; + p->accError = 0; + p->printfFlags = 0; +} + +/* Allocate and initialize a new dynamic string object */ +SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3 *db){ + sqlite3_str *p = sqlite3_malloc64(sizeof(*p)); + if( p ){ + sqlite3StrAccumInit(p, 0, 0, 0, + db ? db->aLimit[SQLITE_LIMIT_LENGTH] : SQLITE_MAX_LENGTH); + }else{ + p = &sqlite3OomStr; + } + return p; +} + +/* +** Print into memory obtained from sqliteMalloc(). Use the internal +** %-conversion extensions. +*/ +SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){ + char *z; + char zBase[SQLITE_PRINT_BUF_SIZE]; + StrAccum acc; + assert( db!=0 ); + sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase), + db->aLimit[SQLITE_LIMIT_LENGTH]); + acc.printfFlags = SQLITE_PRINTF_INTERNAL; + sqlite3_str_vappendf(&acc, zFormat, ap); + z = sqlite3StrAccumFinish(&acc); + if( acc.accError==SQLITE_NOMEM ){ + sqlite3OomFault(db); + } + return z; +} + +/* +** Print into memory obtained from sqliteMalloc(). Use the internal +** %-conversion extensions. +*/ +SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3 *db, const char *zFormat, ...){ + va_list ap; + char *z; + va_start(ap, zFormat); + z = sqlite3VMPrintf(db, zFormat, ap); + va_end(ap); + return z; +} + +/* +** Print into memory obtained from sqlite3_malloc(). Omit the internal +** %-conversion extensions. +*/ +SQLITE_API char *sqlite3_vmprintf(const char *zFormat, va_list ap){ + char *z; + char zBase[SQLITE_PRINT_BUF_SIZE]; + StrAccum acc; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( zFormat==0 ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH); + sqlite3_str_vappendf(&acc, zFormat, ap); + z = sqlite3StrAccumFinish(&acc); + return z; +} + +/* +** Print into memory obtained from sqlite3_malloc()(). Omit the internal +** %-conversion extensions. +*/ +SQLITE_API char *sqlite3_mprintf(const char *zFormat, ...){ + va_list ap; + char *z; +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + va_start(ap, zFormat); + z = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + return z; +} + +/* +** sqlite3_snprintf() works like snprintf() except that it ignores the +** current locale settings. This is important for SQLite because we +** are not able to use a "," as the decimal point in place of "." as +** specified by some locales. +** +** Oops: The first two arguments of sqlite3_snprintf() are backwards +** from the snprintf() standard. Unfortunately, it is too late to change +** this without breaking compatibility, so we just have to live with the +** mistake. +** +** sqlite3_vsnprintf() is the varargs version. +*/ +SQLITE_API char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){ + StrAccum acc; + if( n<=0 ) return zBuf; +#ifdef SQLITE_ENABLE_API_ARMOR + if( zBuf==0 || zFormat==0 ) { + (void)SQLITE_MISUSE_BKPT; + if( zBuf ) zBuf[0] = 0; + return zBuf; + } +#endif + sqlite3StrAccumInit(&acc, 0, zBuf, n, 0); + sqlite3_str_vappendf(&acc, zFormat, ap); + zBuf[acc.nChar] = 0; + return zBuf; +} +SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ + StrAccum acc; + va_list ap; + if( n<=0 ) return zBuf; +#ifdef SQLITE_ENABLE_API_ARMOR + if( zBuf==0 || zFormat==0 ) { + (void)SQLITE_MISUSE_BKPT; + if( zBuf ) zBuf[0] = 0; + return zBuf; + } +#endif + sqlite3StrAccumInit(&acc, 0, zBuf, n, 0); + va_start(ap,zFormat); + sqlite3_str_vappendf(&acc, zFormat, ap); + va_end(ap); + zBuf[acc.nChar] = 0; + return zBuf; +} + +/* Maximum size of an sqlite3_log() message. */ +#if defined(SQLITE_MAX_LOG_MESSAGE) + /* Leave the definition as supplied */ +#elif SQLITE_PRINT_BUF_SIZE*10>10000 +# define SQLITE_MAX_LOG_MESSAGE 10000 +#else +# define SQLITE_MAX_LOG_MESSAGE (SQLITE_PRINT_BUF_SIZE*10) +#endif + +/* +** This is the routine that actually formats the sqlite3_log() message. +** We house it in a separate routine from sqlite3_log() to avoid using +** stack space on small-stack systems when logging is disabled. +** +** sqlite3_log() must render into a static buffer. It cannot dynamically +** allocate memory because it might be called while the memory allocator +** mutex is held. +** +** sqlite3_str_vappendf() might ask for *temporary* memory allocations for +** certain format characters (%q) or for very large precisions or widths. +** Care must be taken that any sqlite3_log() calls that occur while the +** memory mutex is held do not use these mechanisms. +*/ +static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){ + StrAccum acc; /* String accumulator */ + char zMsg[SQLITE_MAX_LOG_MESSAGE]; /* Complete log message */ + + sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0); + sqlite3_str_vappendf(&acc, zFormat, ap); + sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode, + sqlite3StrAccumFinish(&acc)); +} + +/* +** Format and write a message to the log if logging is enabled. +*/ +SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...){ + va_list ap; /* Vararg list */ + if( sqlite3GlobalConfig.xLog ){ + va_start(ap, zFormat); + renderLogMsg(iErrCode, zFormat, ap); + va_end(ap); + } +} + +#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) +/* +** A version of printf() that understands %lld. Used for debugging. +** The printf() built into some versions of windows does not understand %lld +** and segfaults if you give it a long long int. +*/ +SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){ + va_list ap; + StrAccum acc; + char zBuf[SQLITE_PRINT_BUF_SIZE*10]; + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); + va_start(ap,zFormat); + sqlite3_str_vappendf(&acc, zFormat, ap); + va_end(ap); + sqlite3StrAccumFinish(&acc); +#ifdef SQLITE_OS_TRACE_PROC + { + extern void SQLITE_OS_TRACE_PROC(const char *zBuf, int nBuf); + SQLITE_OS_TRACE_PROC(zBuf, sizeof(zBuf)); + } +#else + fprintf(stdout,"%s", zBuf); + fflush(stdout); +#endif +} +#endif + + +/* +** variable-argument wrapper around sqlite3_str_vappendf(). The bFlags argument +** can contain the bit SQLITE_PRINTF_INTERNAL enable internal formats. +*/ +SQLITE_API void sqlite3_str_appendf(StrAccum *p, const char *zFormat, ...){ + va_list ap; + va_start(ap,zFormat); + sqlite3_str_vappendf(p, zFormat, ap); + va_end(ap); +} + + +/***************************************************************************** +** Reference counted string/blob storage +*****************************************************************************/ + +/* +** Increase the reference count of the string by one. +** +** The input parameter is returned. +*/ +SQLITE_PRIVATE char *sqlite3RCStrRef(char *z){ + RCStr *p = (RCStr*)z; + assert( p!=0 ); + p--; + p->nRCRef++; + return z; +} + +/* +** Decrease the reference count by one. Free the string when the +** reference count reaches zero. +*/ +SQLITE_PRIVATE void sqlite3RCStrUnref(void *z){ + RCStr *p = (RCStr*)z; + assert( p!=0 ); + p--; + assert( p->nRCRef>0 ); + if( p->nRCRef>=2 ){ + p->nRCRef--; + }else{ + sqlite3_free(p); + } +} + +/* +** Create a new string that is capable of holding N bytes of text, not counting +** the zero byte at the end. The string is uninitialized. +** +** The reference count is initially 1. Call sqlite3RCStrUnref() to free the +** newly allocated string. +** +** This routine returns 0 on an OOM. +*/ +SQLITE_PRIVATE char *sqlite3RCStrNew(u64 N){ + RCStr *p = sqlite3_malloc64( N + sizeof(*p) + 1 ); + if( p==0 ) return 0; + p->nRCRef = 1; + return (char*)&p[1]; +} + +/* +** Change the size of the string so that it is able to hold N bytes. +** The string might be reallocated, so return the new allocation. +*/ +SQLITE_PRIVATE char *sqlite3RCStrResize(char *z, u64 N){ + RCStr *p = (RCStr*)z; + RCStr *pNew; + assert( p!=0 ); + p--; + assert( p->nRCRef==1 ); + pNew = sqlite3_realloc64(p, N+sizeof(RCStr)+1); + if( pNew==0 ){ + sqlite3_free(p); + return 0; + }else{ + return (char*)&pNew[1]; + } +} + +/************** End of printf.c **********************************************/ +/************** Begin file treeview.c ****************************************/ +/* +** 2015-06-08 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains C code to implement the TreeView debugging routines. +** These routines print a parse tree to standard output for debugging and +** analysis. +** +** The interfaces in this file is only available when compiling +** with SQLITE_DEBUG. +*/ +/* #include "sqliteInt.h" */ +#ifdef SQLITE_DEBUG + +/* +** Add a new subitem to the tree. The moreToFollow flag indicates that this +** is not the last item in the tree. +*/ +static void sqlite3TreeViewPush(TreeView **pp, u8 moreToFollow){ + TreeView *p = *pp; + if( p==0 ){ + *pp = p = sqlite3_malloc64( sizeof(*p) ); + if( p==0 ) return; + memset(p, 0, sizeof(*p)); + }else{ + p->iLevel++; + } + assert( moreToFollow==0 || moreToFollow==1 ); + if( p->iLevel<(int)sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow; +} + +/* +** Finished with one layer of the tree +*/ +static void sqlite3TreeViewPop(TreeView **pp){ + TreeView *p = *pp; + if( p==0 ) return; + p->iLevel--; + if( p->iLevel<0 ){ + sqlite3_free(p); + *pp = 0; + } +} + +/* +** Generate a single line of output for the tree, with a prefix that contains +** all the appropriate tree lines +*/ +SQLITE_PRIVATE void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){ + va_list ap; + int i; + StrAccum acc; + char zBuf[1000]; + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); + if( p ){ + for(i=0; iiLevel && i<(int)sizeof(p->bLine)-1; i++){ + sqlite3_str_append(&acc, p->bLine[i] ? "| " : " ", 4); + } + sqlite3_str_append(&acc, p->bLine[i] ? "|-- " : "'-- ", 4); + } + if( zFormat!=0 ){ + va_start(ap, zFormat); + sqlite3_str_vappendf(&acc, zFormat, ap); + va_end(ap); + assert( acc.nChar>0 || acc.accError ); + sqlite3_str_append(&acc, "\n", 1); + } + sqlite3StrAccumFinish(&acc); + fprintf(stdout,"%s", zBuf); + fflush(stdout); +} + +/* +** Shorthand for starting a new tree item that consists of a single label +*/ +static void sqlite3TreeViewItem(TreeView *p, const char *zLabel,u8 moreFollows){ + sqlite3TreeViewPush(&p, moreFollows); + sqlite3TreeViewLine(p, "%s", zLabel); +} + +/* +** Show a list of Column objects in tree format. +*/ +SQLITE_PRIVATE void sqlite3TreeViewColumnList( + TreeView *pView, + const Column *aCol, + int nCol, + u8 moreToFollow +){ + int i; + sqlite3TreeViewPush(&pView, moreToFollow); + sqlite3TreeViewLine(pView, "COLUMNS"); + for(i=0; inCte==0 ) return; + if( pWith->pOuter ){ + sqlite3TreeViewLine(pView, "WITH (0x%p, pOuter=0x%p)",pWith,pWith->pOuter); + }else{ + sqlite3TreeViewLine(pView, "WITH (0x%p)", pWith); + } + if( pWith->nCte>0 ){ + sqlite3TreeViewPush(&pView, moreToFollow); + for(i=0; inCte; i++){ + StrAccum x; + char zLine[1000]; + const struct Cte *pCte = &pWith->a[i]; + sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); + sqlite3_str_appendf(&x, "%s", pCte->zName); + if( pCte->pCols && pCte->pCols->nExpr>0 ){ + char cSep = '('; + int j; + for(j=0; jpCols->nExpr; j++){ + sqlite3_str_appendf(&x, "%c%s", cSep, pCte->pCols->a[j].zEName); + cSep = ','; + } + sqlite3_str_appendf(&x, ")"); + } + if( pCte->eM10d!=M10d_Any ){ + sqlite3_str_appendf(&x, " %sMATERIALIZED", + pCte->eM10d==M10d_No ? "NOT " : ""); + } + if( pCte->pUse ){ + sqlite3_str_appendf(&x, " (pUse=0x%p, nUse=%d)", pCte->pUse, + pCte->pUse->nUse); + } + sqlite3StrAccumFinish(&x); + sqlite3TreeViewItem(pView, zLine, inCte-1); + sqlite3TreeViewSelect(pView, pCte->pSelect, 0); + sqlite3TreeViewPop(&pView); + } + sqlite3TreeViewPop(&pView); + } +} + +/* +** Generate a human-readable description of a SrcList object. +*/ +SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ + int i; + if( pSrc==0 ) return; + for(i=0; inSrc; i++){ + const SrcItem *pItem = &pSrc->a[i]; + StrAccum x; + int n = 0; + char zLine[1000]; + sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); + x.printfFlags |= SQLITE_PRINTF_INTERNAL; + sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem); + if( pItem->pSTab ){ + sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx%s", + pItem->pSTab->zName, pItem->pSTab->nCol, pItem->pSTab, + pItem->colUsed, + pItem->fg.rowidUsed ? "+rowid" : ""); + } + if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==(JT_LEFT|JT_RIGHT) ){ + sqlite3_str_appendf(&x, " FULL-OUTER-JOIN"); + }else if( pItem->fg.jointype & JT_LEFT ){ + sqlite3_str_appendf(&x, " LEFT-JOIN"); + }else if( pItem->fg.jointype & JT_RIGHT ){ + sqlite3_str_appendf(&x, " RIGHT-JOIN"); + }else if( pItem->fg.jointype & JT_CROSS ){ + sqlite3_str_appendf(&x, " CROSS-JOIN"); + } + if( pItem->fg.jointype & JT_LTORJ ){ + sqlite3_str_appendf(&x, " LTORJ"); + } + if( pItem->fg.fromDDL ){ + sqlite3_str_appendf(&x, " DDL"); + } + if( pItem->fg.isCte ){ + static const char *aMat[] = {",MAT", "", ",NO-MAT"}; + sqlite3_str_appendf(&x, " CteUse=%d%s", + pItem->u2.pCteUse->nUse, + aMat[pItem->u2.pCteUse->eM10d]); + } + if( pItem->fg.isOn || (pItem->fg.isUsing==0 && pItem->u3.pOn!=0) ){ + sqlite3_str_appendf(&x, " isOn"); + } + if( pItem->fg.isTabFunc ) sqlite3_str_appendf(&x, " isTabFunc"); + if( pItem->fg.isCorrelated ) sqlite3_str_appendf(&x, " isCorrelated"); + if( pItem->fg.isMaterialized ) sqlite3_str_appendf(&x, " isMaterialized"); + if( pItem->fg.viaCoroutine ) sqlite3_str_appendf(&x, " viaCoroutine"); + if( pItem->fg.notCte ) sqlite3_str_appendf(&x, " notCte"); + if( pItem->fg.isNestedFrom ) sqlite3_str_appendf(&x, " isNestedFrom"); + if( pItem->fg.fixedSchema ) sqlite3_str_appendf(&x, " fixedSchema"); + if( pItem->fg.hadSchema ) sqlite3_str_appendf(&x, " hadSchema"); + if( pItem->fg.isSubquery ) sqlite3_str_appendf(&x, " isSubquery"); + + sqlite3StrAccumFinish(&x); + sqlite3TreeViewItem(pView, zLine, inSrc-1); + n = 0; + if( pItem->fg.isSubquery ) n++; + if( pItem->fg.isTabFunc ) n++; + if( pItem->fg.isUsing || pItem->u3.pOn!=0 ) n++; + if( pItem->fg.isUsing ){ + sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING"); + }else if( pItem->u3.pOn!=0 ){ + sqlite3TreeViewItem(pView, "ON", (--n)>0); + sqlite3TreeViewExpr(pView, pItem->u3.pOn, 0); + sqlite3TreeViewPop(&pView); + } + if( pItem->fg.isSubquery ){ + assert( n==1 ); + if( pItem->pSTab ){ + Table *pTab = pItem->pSTab; + sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1); + } + assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem) ); + sqlite3TreeViewSelect(pView, pItem->u4.pSubq->pSelect, 0); + } + if( pItem->fg.isTabFunc ){ + sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); + } + sqlite3TreeViewPop(&pView); + } +} + +/* +** Generate a human-readable description of a Select object. +*/ +SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ + int n = 0; + int cnt = 0; + if( p==0 ){ + sqlite3TreeViewLine(pView, "nil-SELECT"); + return; + } + sqlite3TreeViewPush(&pView, moreToFollow); + if( p->pWith ){ + sqlite3TreeViewWith(pView, p->pWith, 1); + cnt = 1; + sqlite3TreeViewPush(&pView, 1); + } + do{ + if( p->selFlags & SF_WhereBegin ){ + sqlite3TreeViewLine(pView, "sqlite3WhereBegin()"); + }else{ + sqlite3TreeViewLine(pView, + "SELECT%s%s (%u/%p) selFlags=0x%x nSelectRow=%d", + ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""), + ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), + p->selId, p, p->selFlags, + (int)p->nSelectRow + ); + } + if( cnt++ ) sqlite3TreeViewPop(&pView); + if( p->pPrior ){ + n = 1000; + }else{ + n = 0; + if( p->pSrc && p->pSrc->nSrc && p->pSrc->nAlloc ) n++; + if( p->pWhere ) n++; + if( p->pGroupBy ) n++; + if( p->pHaving ) n++; + if( p->pOrderBy ) n++; + if( p->pLimit ) n++; +#ifndef SQLITE_OMIT_WINDOWFUNC + if( p->pWin ) n++; + if( p->pWinDefn ) n++; +#endif + } + if( p->pEList ){ + sqlite3TreeViewExprList(pView, p->pEList, n>0, "result-set"); + } + n--; +#ifndef SQLITE_OMIT_WINDOWFUNC + if( p->pWin ){ + Window *pX; + sqlite3TreeViewPush(&pView, (n--)>0); + sqlite3TreeViewLine(pView, "window-functions"); + for(pX=p->pWin; pX; pX=pX->pNextWin){ + sqlite3TreeViewWinFunc(pView, pX, pX->pNextWin!=0); + } + sqlite3TreeViewPop(&pView); + } +#endif + if( p->pSrc && p->pSrc->nSrc && p->pSrc->nAlloc ){ + sqlite3TreeViewPush(&pView, (n--)>0); + sqlite3TreeViewLine(pView, "FROM"); + sqlite3TreeViewSrcList(pView, p->pSrc); + sqlite3TreeViewPop(&pView); + } + if( p->pWhere ){ + sqlite3TreeViewItem(pView, "WHERE", (n--)>0); + sqlite3TreeViewExpr(pView, p->pWhere, 0); + sqlite3TreeViewPop(&pView); + } + if( p->pGroupBy ){ + sqlite3TreeViewExprList(pView, p->pGroupBy, (n--)>0, "GROUPBY"); + } + if( p->pHaving ){ + sqlite3TreeViewItem(pView, "HAVING", (n--)>0); + sqlite3TreeViewExpr(pView, p->pHaving, 0); + sqlite3TreeViewPop(&pView); + } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( p->pWinDefn ){ + Window *pX; + sqlite3TreeViewItem(pView, "WINDOW", (n--)>0); + for(pX=p->pWinDefn; pX; pX=pX->pNextWin){ + sqlite3TreeViewWindow(pView, pX, pX->pNextWin!=0); + } + sqlite3TreeViewPop(&pView); + } +#endif + if( p->pOrderBy ){ + sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY"); + } + if( p->pLimit ){ + sqlite3TreeViewItem(pView, "LIMIT", (n--)>0); + sqlite3TreeViewExpr(pView, p->pLimit->pLeft, p->pLimit->pRight!=0); + if( p->pLimit->pRight ){ + sqlite3TreeViewItem(pView, "OFFSET", 0); + sqlite3TreeViewExpr(pView, p->pLimit->pRight, 0); + sqlite3TreeViewPop(&pView); + } + sqlite3TreeViewPop(&pView); + } + if( p->pPrior ){ + const char *zOp = "UNION"; + switch( p->op ){ + case TK_ALL: zOp = "UNION ALL"; break; + case TK_INTERSECT: zOp = "INTERSECT"; break; + case TK_EXCEPT: zOp = "EXCEPT"; break; + } + sqlite3TreeViewItem(pView, zOp, 1); + } + p = p->pPrior; + }while( p!=0 ); + sqlite3TreeViewPop(&pView); +} + +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** Generate a description of starting or stopping bounds +*/ +SQLITE_PRIVATE void sqlite3TreeViewBound( + TreeView *pView, /* View context */ + u8 eBound, /* UNBOUNDED, CURRENT, PRECEDING, FOLLOWING */ + Expr *pExpr, /* Value for PRECEDING or FOLLOWING */ + u8 moreToFollow /* True if more to follow */ +){ + switch( eBound ){ + case TK_UNBOUNDED: { + sqlite3TreeViewItem(pView, "UNBOUNDED", moreToFollow); + sqlite3TreeViewPop(&pView); + break; + } + case TK_CURRENT: { + sqlite3TreeViewItem(pView, "CURRENT", moreToFollow); + sqlite3TreeViewPop(&pView); + break; + } + case TK_PRECEDING: { + sqlite3TreeViewItem(pView, "PRECEDING", moreToFollow); + sqlite3TreeViewExpr(pView, pExpr, 0); + sqlite3TreeViewPop(&pView); + break; + } + case TK_FOLLOWING: { + sqlite3TreeViewItem(pView, "FOLLOWING", moreToFollow); + sqlite3TreeViewExpr(pView, pExpr, 0); + sqlite3TreeViewPop(&pView); + break; + } + } +} +#endif /* SQLITE_OMIT_WINDOWFUNC */ + +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** Generate a human-readable explanation for a Window object +*/ +SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){ + int nElement = 0; + if( pWin==0 ) return; + if( pWin->pFilter ){ + sqlite3TreeViewItem(pView, "FILTER", 1); + sqlite3TreeViewExpr(pView, pWin->pFilter, 0); + sqlite3TreeViewPop(&pView); + if( pWin->eFrmType==TK_FILTER ) return; + } + sqlite3TreeViewPush(&pView, more); + if( pWin->zName ){ + sqlite3TreeViewLine(pView, "OVER %s (%p)", pWin->zName, pWin); + }else{ + sqlite3TreeViewLine(pView, "OVER (%p)", pWin); + } + if( pWin->zBase ) nElement++; + if( pWin->pOrderBy ) nElement++; + if( pWin->eFrmType!=0 && pWin->eFrmType!=TK_FILTER ) nElement++; + if( pWin->eExclude ) nElement++; + if( pWin->zBase ){ + sqlite3TreeViewPush(&pView, (--nElement)>0); + sqlite3TreeViewLine(pView, "window: %s", pWin->zBase); + sqlite3TreeViewPop(&pView); + } + if( pWin->pPartition ){ + sqlite3TreeViewExprList(pView, pWin->pPartition, nElement>0,"PARTITION-BY"); + } + if( pWin->pOrderBy ){ + sqlite3TreeViewExprList(pView, pWin->pOrderBy, (--nElement)>0, "ORDER-BY"); + } + if( pWin->eFrmType!=0 && pWin->eFrmType!=TK_FILTER ){ + char zBuf[30]; + const char *zFrmType = "ROWS"; + if( pWin->eFrmType==TK_RANGE ) zFrmType = "RANGE"; + if( pWin->eFrmType==TK_GROUPS ) zFrmType = "GROUPS"; + sqlite3_snprintf(sizeof(zBuf),zBuf,"%s%s",zFrmType, + pWin->bImplicitFrame ? " (implied)" : ""); + sqlite3TreeViewItem(pView, zBuf, (--nElement)>0); + sqlite3TreeViewBound(pView, pWin->eStart, pWin->pStart, 1); + sqlite3TreeViewBound(pView, pWin->eEnd, pWin->pEnd, 0); + sqlite3TreeViewPop(&pView); + } + if( pWin->eExclude ){ + char zBuf[30]; + const char *zExclude; + switch( pWin->eExclude ){ + case TK_NO: zExclude = "NO OTHERS"; break; + case TK_CURRENT: zExclude = "CURRENT ROW"; break; + case TK_GROUP: zExclude = "GROUP"; break; + case TK_TIES: zExclude = "TIES"; break; + default: + sqlite3_snprintf(sizeof(zBuf),zBuf,"invalid(%d)", pWin->eExclude); + zExclude = zBuf; + break; + } + sqlite3TreeViewPush(&pView, 0); + sqlite3TreeViewLine(pView, "EXCLUDE %s", zExclude); + sqlite3TreeViewPop(&pView); + } + sqlite3TreeViewPop(&pView); +} +#endif /* SQLITE_OMIT_WINDOWFUNC */ + +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** Generate a human-readable explanation for a Window Function object +*/ +SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){ + if( pWin==0 ) return; + sqlite3TreeViewPush(&pView, more); + sqlite3TreeViewLine(pView, "WINFUNC %s(%d)", + pWin->pWFunc->zName, pWin->pWFunc->nArg); + sqlite3TreeViewWindow(pView, pWin, 0); + sqlite3TreeViewPop(&pView); +} +#endif /* SQLITE_OMIT_WINDOWFUNC */ + +/* +** Generate a human-readable explanation of an expression tree. +*/ +SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ + const char *zBinOp = 0; /* Binary operator */ + const char *zUniOp = 0; /* Unary operator */ + char zFlgs[200]; + sqlite3TreeViewPush(&pView, moreToFollow); + if( pExpr==0 ){ + sqlite3TreeViewLine(pView, "nil"); + sqlite3TreeViewPop(&pView); + return; + } + if( pExpr->flags || pExpr->affExpr || pExpr->vvaFlags || pExpr->pAggInfo ){ + StrAccum x; + sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0); + sqlite3_str_appendf(&x, " fg.af=%x.%c", + pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n'); + if( ExprHasProperty(pExpr, EP_OuterON) ){ + sqlite3_str_appendf(&x, " outer.iJoin=%d", pExpr->w.iJoin); + } + if( ExprHasProperty(pExpr, EP_InnerON) ){ + sqlite3_str_appendf(&x, " inner.iJoin=%d", pExpr->w.iJoin); + } + if( ExprHasProperty(pExpr, EP_FromDDL) ){ + sqlite3_str_appendf(&x, " DDL"); + } + if( ExprHasVVAProperty(pExpr, EP_Immutable) ){ + sqlite3_str_appendf(&x, " IMMUTABLE"); + } + if( pExpr->pAggInfo!=0 ){ + sqlite3_str_appendf(&x, " agg-column[%d]", pExpr->iAgg); + } + sqlite3StrAccumFinish(&x); + }else{ + zFlgs[0] = 0; + } + switch( pExpr->op ){ + case TK_AGG_COLUMN: { + sqlite3TreeViewLine(pView, "AGG{%d:%d}%s", + pExpr->iTable, pExpr->iColumn, zFlgs); + break; + } + case TK_COLUMN: { + if( pExpr->iTable<0 ){ + /* This only happens when coding check constraints */ + char zOp2[16]; + if( pExpr->op2 ){ + sqlite3_snprintf(sizeof(zOp2),zOp2," op2=0x%02x",pExpr->op2); + }else{ + zOp2[0] = 0; + } + sqlite3TreeViewLine(pView, "COLUMN(%d)%s%s", + pExpr->iColumn, zFlgs, zOp2); + }else{ + assert( ExprUseYTab(pExpr) ); + sqlite3TreeViewLine(pView, "{%d:%d} pTab=%p%s", + pExpr->iTable, pExpr->iColumn, + pExpr->y.pTab, zFlgs); + } + if( ExprHasProperty(pExpr, EP_FixedCol) ){ + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); + } + break; + } + case TK_INTEGER: { + if( pExpr->flags & EP_IntValue ){ + sqlite3TreeViewLine(pView, "%d", pExpr->u.iValue); + }else{ + sqlite3TreeViewLine(pView, "%s", pExpr->u.zToken); + } + break; + } +#ifndef SQLITE_OMIT_FLOATING_POINT + case TK_FLOAT: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken); + break; + } +#endif + case TK_STRING: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3TreeViewLine(pView,"%Q", pExpr->u.zToken); + break; + } + case TK_NULL: { + sqlite3TreeViewLine(pView,"NULL"); + break; + } + case TK_TRUEFALSE: { + sqlite3TreeViewLine(pView,"%s%s", + sqlite3ExprTruthValue(pExpr) ? "TRUE" : "FALSE", zFlgs); + break; + } +#ifndef SQLITE_OMIT_BLOB_LITERAL + case TK_BLOB: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken); + break; + } +#endif + case TK_VARIABLE: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3TreeViewLine(pView,"VARIABLE(%s,%d)", + pExpr->u.zToken, pExpr->iColumn); + break; + } + case TK_REGISTER: { + sqlite3TreeViewLine(pView,"REGISTER(%d)", pExpr->iTable); + break; + } + case TK_ID: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3TreeViewLine(pView,"ID \"%w\"", pExpr->u.zToken); + break; + } +#ifndef SQLITE_OMIT_CAST + case TK_CAST: { + /* Expressions of the form: CAST(pLeft AS token) */ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3TreeViewLine(pView,"CAST %Q", pExpr->u.zToken); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); + break; + } +#endif /* SQLITE_OMIT_CAST */ + case TK_LT: zBinOp = "LT"; break; + case TK_LE: zBinOp = "LE"; break; + case TK_GT: zBinOp = "GT"; break; + case TK_GE: zBinOp = "GE"; break; + case TK_NE: zBinOp = "NE"; break; + case TK_EQ: zBinOp = "EQ"; break; + case TK_IS: zBinOp = "IS"; break; + case TK_ISNOT: zBinOp = "ISNOT"; break; + case TK_AND: zBinOp = "AND"; break; + case TK_OR: zBinOp = "OR"; break; + case TK_PLUS: zBinOp = "ADD"; break; + case TK_STAR: zBinOp = "MUL"; break; + case TK_MINUS: zBinOp = "SUB"; break; + case TK_REM: zBinOp = "REM"; break; + case TK_BITAND: zBinOp = "BITAND"; break; + case TK_BITOR: zBinOp = "BITOR"; break; + case TK_SLASH: zBinOp = "DIV"; break; + case TK_LSHIFT: zBinOp = "LSHIFT"; break; + case TK_RSHIFT: zBinOp = "RSHIFT"; break; + case TK_CONCAT: zBinOp = "CONCAT"; break; + case TK_DOT: zBinOp = "DOT"; break; + case TK_LIMIT: zBinOp = "LIMIT"; break; + + case TK_UMINUS: zUniOp = "UMINUS"; break; + case TK_UPLUS: zUniOp = "UPLUS"; break; + case TK_BITNOT: zUniOp = "BITNOT"; break; + case TK_NOT: zUniOp = "NOT"; break; + case TK_ISNULL: zUniOp = "ISNULL"; break; + case TK_NOTNULL: zUniOp = "NOTNULL"; break; + + case TK_TRUTH: { + int x; + const char *azOp[] = { + "IS-FALSE", "IS-TRUE", "IS-NOT-FALSE", "IS-NOT-TRUE" + }; + assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT ); + assert( pExpr->pRight ); + assert( sqlite3ExprSkipCollateAndLikely(pExpr->pRight)->op + == TK_TRUEFALSE ); + x = (pExpr->op2==TK_ISNOT)*2 + sqlite3ExprTruthValue(pExpr->pRight); + zUniOp = azOp[x]; + break; + } + + case TK_SPAN: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3TreeViewLine(pView, "SPAN %Q", pExpr->u.zToken); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); + break; + } + + case TK_COLLATE: { + /* COLLATE operators without the EP_Collate flag are intended to + ** emulate collation associated with a table column. These show + ** up in the treeview output as "SOFT-COLLATE". Explicit COLLATE + ** operators that appear in the original SQL always have the + ** EP_Collate bit set and appear in treeview output as just "COLLATE" */ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3TreeViewLine(pView, "%sCOLLATE %Q%s", + !ExprHasProperty(pExpr, EP_Collate) ? "SOFT-" : "", + pExpr->u.zToken, zFlgs); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); + break; + } + + case TK_AGG_FUNCTION: + case TK_FUNCTION: { + ExprList *pFarg; /* List of function arguments */ + Window *pWin; + if( ExprHasProperty(pExpr, EP_TokenOnly) ){ + pFarg = 0; + pWin = 0; + }else{ + assert( ExprUseXList(pExpr) ); + pFarg = pExpr->x.pList; +#ifndef SQLITE_OMIT_WINDOWFUNC + pWin = IsWindowFunc(pExpr) ? pExpr->y.pWin : 0; +#else + pWin = 0; +#endif + } + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + if( pExpr->op==TK_AGG_FUNCTION ){ + sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q%s agg=%d[%d]/%p", + pExpr->op2, pExpr->u.zToken, zFlgs, + pExpr->pAggInfo ? pExpr->pAggInfo->selId : 0, + pExpr->iAgg, pExpr->pAggInfo); + }else if( pExpr->op2!=0 ){ + const char *zOp2; + char zBuf[8]; + sqlite3_snprintf(sizeof(zBuf),zBuf,"0x%02x",pExpr->op2); + zOp2 = zBuf; + if( pExpr->op2==NC_IsCheck ) zOp2 = "NC_IsCheck"; + if( pExpr->op2==NC_IdxExpr ) zOp2 = "NC_IdxExpr"; + if( pExpr->op2==NC_PartIdx ) zOp2 = "NC_PartIdx"; + if( pExpr->op2==NC_GenCol ) zOp2 = "NC_GenCol"; + sqlite3TreeViewLine(pView, "FUNCTION %Q%s op2=%s", + pExpr->u.zToken, zFlgs, zOp2); + }else{ + sqlite3TreeViewLine(pView, "FUNCTION %Q%s", pExpr->u.zToken, zFlgs); + } + if( pFarg ){ + sqlite3TreeViewExprList(pView, pFarg, pWin!=0 || pExpr->pLeft, 0); + if( pExpr->pLeft ){ + Expr *pOB = pExpr->pLeft; + assert( pOB->op==TK_ORDER ); + assert( ExprUseXList(pOB) ); + sqlite3TreeViewExprList(pView, pOB->x.pList, pWin!=0, "ORDERBY"); + } + } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pWin ){ + sqlite3TreeViewWindow(pView, pWin, 0); + } +#endif + break; + } + case TK_ORDER: { + sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, "ORDERBY"); + break; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_EXISTS: { + assert( ExprUseXSelect(pExpr) ); + sqlite3TreeViewLine(pView, "EXISTS-expr flags=0x%x", pExpr->flags); + sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); + break; + } + case TK_SELECT: { + assert( ExprUseXSelect(pExpr) ); + sqlite3TreeViewLine(pView, "subquery-expr flags=0x%x", pExpr->flags); + sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); + break; + } + case TK_IN: { + sqlite3_str *pStr = sqlite3_str_new(0); + char *z; + sqlite3_str_appendf(pStr, "IN flags=0x%x", pExpr->flags); + if( pExpr->iTable ) sqlite3_str_appendf(pStr, " iTable=%d",pExpr->iTable); + if( ExprHasProperty(pExpr, EP_Subrtn) ){ + sqlite3_str_appendf(pStr, " subrtn(%d,%d)", + pExpr->y.sub.regReturn, pExpr->y.sub.iAddr); + } + z = sqlite3_str_finish(pStr); + sqlite3TreeViewLine(pView, z); + sqlite3_free(z); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); + if( ExprUseXSelect(pExpr) ){ + sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); + }else{ + sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0); + } + break; + } +#endif /* SQLITE_OMIT_SUBQUERY */ + + /* + ** x BETWEEN y AND z + ** + ** This is equivalent to + ** + ** x>=y AND x<=z + ** + ** X is stored in pExpr->pLeft. + ** Y is stored in pExpr->pList->a[0].pExpr. + ** Z is stored in pExpr->pList->a[1].pExpr. + */ + case TK_BETWEEN: { + const Expr *pX, *pY, *pZ; + pX = pExpr->pLeft; + assert( ExprUseXList(pExpr) ); + assert( pExpr->x.pList->nExpr==2 ); + pY = pExpr->x.pList->a[0].pExpr; + pZ = pExpr->x.pList->a[1].pExpr; + sqlite3TreeViewLine(pView, "BETWEEN%s", zFlgs); + sqlite3TreeViewExpr(pView, pX, 1); + sqlite3TreeViewExpr(pView, pY, 1); + sqlite3TreeViewExpr(pView, pZ, 0); + break; + } + case TK_TRIGGER: { + /* If the opcode is TK_TRIGGER, then the expression is a reference + ** to a column in the new.* or old.* pseudo-tables available to + ** trigger programs. In this case Expr.iTable is set to 1 for the + ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn + ** is set to the column of the pseudo-table to read, or to -1 to + ** read the rowid field. + */ + sqlite3TreeViewLine(pView, "%s(%d)", + pExpr->iTable ? "NEW" : "OLD", pExpr->iColumn); + break; + } + case TK_CASE: { + sqlite3TreeViewLine(pView, "CASE"); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); + assert( ExprUseXList(pExpr) ); + sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0); + break; + } +#ifndef SQLITE_OMIT_TRIGGER + case TK_RAISE: { + const char *zType = "unk"; + switch( pExpr->affExpr ){ + case OE_Rollback: zType = "rollback"; break; + case OE_Abort: zType = "abort"; break; + case OE_Fail: zType = "fail"; break; + case OE_Ignore: zType = "ignore"; break; + } + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3TreeViewLine(pView, "RAISE %s", zType); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); + break; + } +#endif + case TK_MATCH: { + sqlite3TreeViewLine(pView, "MATCH {%d:%d}%s", + pExpr->iTable, pExpr->iColumn, zFlgs); + sqlite3TreeViewExpr(pView, pExpr->pRight, 0); + break; + } + case TK_VECTOR: { + char *z = sqlite3_mprintf("VECTOR%s",zFlgs); + assert( ExprUseXList(pExpr) ); + sqlite3TreeViewBareExprList(pView, pExpr->x.pList, z); + sqlite3_free(z); + break; + } + case TK_SELECT_COLUMN: { + sqlite3TreeViewLine(pView, "SELECT-COLUMN %d of [0..%d]%s", + pExpr->iColumn, pExpr->iTable-1, + pExpr->pRight==pExpr->pLeft ? " (SELECT-owner)" : ""); + assert( ExprUseXSelect(pExpr->pLeft) ); + sqlite3TreeViewSelect(pView, pExpr->pLeft->x.pSelect, 0); + break; + } + case TK_IF_NULL_ROW: { + sqlite3TreeViewLine(pView, "IF-NULL-ROW %d", pExpr->iTable); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); + break; + } + case TK_ERROR: { + Expr tmp; + sqlite3TreeViewLine(pView, "ERROR"); + tmp = *pExpr; + tmp.op = pExpr->op2; + sqlite3TreeViewExpr(pView, &tmp, 0); + break; + } + case TK_ROW: { + if( pExpr->iColumn<=0 ){ + sqlite3TreeViewLine(pView, "First FROM table rowid"); + }else{ + sqlite3TreeViewLine(pView, "First FROM table column %d", + pExpr->iColumn-1); + } + break; + } + default: { + sqlite3TreeViewLine(pView, "op=%d", pExpr->op); + break; + } + } + if( zBinOp ){ + sqlite3TreeViewLine(pView, "%s%s", zBinOp, zFlgs); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); + sqlite3TreeViewExpr(pView, pExpr->pRight, 0); + }else if( zUniOp ){ + sqlite3TreeViewLine(pView, "%s%s", zUniOp, zFlgs); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); + } + sqlite3TreeViewPop(&pView); +} + + +/* +** Generate a human-readable explanation of an expression list. +*/ +SQLITE_PRIVATE void sqlite3TreeViewBareExprList( + TreeView *pView, + const ExprList *pList, + const char *zLabel +){ + if( zLabel==0 || zLabel[0]==0 ) zLabel = "LIST"; + if( pList==0 ){ + sqlite3TreeViewLine(pView, "%s (empty)", zLabel); + }else{ + int i; + sqlite3TreeViewLine(pView, "%s", zLabel); + for(i=0; inExpr; i++){ + int j = pList->a[i].u.x.iOrderByCol; + u8 sortFlags = pList->a[i].fg.sortFlags; + char *zName = pList->a[i].zEName; + int moreToFollow = inExpr - 1; + if( j || zName || sortFlags ){ + sqlite3TreeViewPush(&pView, moreToFollow); + moreToFollow = 0; + sqlite3TreeViewLine(pView, 0); + if( zName ){ + switch( pList->a[i].fg.eEName ){ + default: + fprintf(stdout, "AS %s ", zName); + break; + case ENAME_TAB: + fprintf(stdout, "TABLE-ALIAS-NAME(\"%s\") ", zName); + if( pList->a[i].fg.bUsed ) fprintf(stdout, "(used) "); + if( pList->a[i].fg.bUsingTerm ) fprintf(stdout, "(USING-term) "); + if( pList->a[i].fg.bNoExpand ) fprintf(stdout, "(NoExpand) "); + break; + case ENAME_SPAN: + fprintf(stdout, "SPAN(\"%s\") ", zName); + break; + } + } + if( j ){ + fprintf(stdout, "iOrderByCol=%d ", j); + } + if( sortFlags & KEYINFO_ORDER_DESC ){ + fprintf(stdout, "DESC "); + }else if( sortFlags & KEYINFO_ORDER_BIGNULL ){ + fprintf(stdout, "NULLS-LAST"); + } + fprintf(stdout, "\n"); + fflush(stdout); + } + sqlite3TreeViewExpr(pView, pList->a[i].pExpr, moreToFollow); + if( j || zName || sortFlags ){ + sqlite3TreeViewPop(&pView); + } + } + } +} +SQLITE_PRIVATE void sqlite3TreeViewExprList( + TreeView *pView, + const ExprList *pList, + u8 moreToFollow, + const char *zLabel +){ + sqlite3TreeViewPush(&pView, moreToFollow); + sqlite3TreeViewBareExprList(pView, pList, zLabel); + sqlite3TreeViewPop(&pView); +} + +/* +** Generate a human-readable explanation of an id-list. +*/ +SQLITE_PRIVATE void sqlite3TreeViewBareIdList( + TreeView *pView, + const IdList *pList, + const char *zLabel +){ + if( zLabel==0 || zLabel[0]==0 ) zLabel = "LIST"; + if( pList==0 ){ + sqlite3TreeViewLine(pView, "%s (empty)", zLabel); + }else{ + int i; + sqlite3TreeViewLine(pView, "%s", zLabel); + for(i=0; inId; i++){ + char *zName = pList->a[i].zName; + int moreToFollow = inId - 1; + if( zName==0 ) zName = "(null)"; + sqlite3TreeViewPush(&pView, moreToFollow); + sqlite3TreeViewLine(pView, 0); + fprintf(stdout, "%s\n", zName); + sqlite3TreeViewPop(&pView); + } + } +} +SQLITE_PRIVATE void sqlite3TreeViewIdList( + TreeView *pView, + const IdList *pList, + u8 moreToFollow, + const char *zLabel +){ + sqlite3TreeViewPush(&pView, moreToFollow); + sqlite3TreeViewBareIdList(pView, pList, zLabel); + sqlite3TreeViewPop(&pView); +} + +/* +** Generate a human-readable explanation of a list of Upsert objects +*/ +SQLITE_PRIVATE void sqlite3TreeViewUpsert( + TreeView *pView, + const Upsert *pUpsert, + u8 moreToFollow +){ + if( pUpsert==0 ) return; + sqlite3TreeViewPush(&pView, moreToFollow); + while( pUpsert ){ + int n; + sqlite3TreeViewPush(&pView, pUpsert->pNextUpsert!=0 || moreToFollow); + sqlite3TreeViewLine(pView, "ON CONFLICT DO %s", + pUpsert->isDoUpdate ? "UPDATE" : "NOTHING"); + n = (pUpsert->pUpsertSet!=0) + (pUpsert->pUpsertWhere!=0); + sqlite3TreeViewExprList(pView, pUpsert->pUpsertTarget, (n--)>0, "TARGET"); + sqlite3TreeViewExprList(pView, pUpsert->pUpsertSet, (n--)>0, "SET"); + if( pUpsert->pUpsertWhere ){ + sqlite3TreeViewItem(pView, "WHERE", (n--)>0); + sqlite3TreeViewExpr(pView, pUpsert->pUpsertWhere, 0); + sqlite3TreeViewPop(&pView); + } + sqlite3TreeViewPop(&pView); + pUpsert = pUpsert->pNextUpsert; + } + sqlite3TreeViewPop(&pView); +} + +#if TREETRACE_ENABLED +/* +** Generate a human-readable diagram of the data structure that go +** into generating an DELETE statement. +*/ +SQLITE_PRIVATE void sqlite3TreeViewDelete( + const With *pWith, + const SrcList *pTabList, + const Expr *pWhere, + const ExprList *pOrderBy, + const Expr *pLimit, + const Trigger *pTrigger +){ + int n = 0; + TreeView *pView = 0; + sqlite3TreeViewPush(&pView, 0); + sqlite3TreeViewLine(pView, "DELETE"); + if( pWith ) n++; + if( pTabList ) n++; + if( pWhere ) n++; + if( pOrderBy ) n++; + if( pLimit ) n++; + if( pTrigger ) n++; + if( pWith ){ + sqlite3TreeViewPush(&pView, (--n)>0); + sqlite3TreeViewWith(pView, pWith, 0); + sqlite3TreeViewPop(&pView); + } + if( pTabList ){ + sqlite3TreeViewPush(&pView, (--n)>0); + sqlite3TreeViewLine(pView, "FROM"); + sqlite3TreeViewSrcList(pView, pTabList); + sqlite3TreeViewPop(&pView); + } + if( pWhere ){ + sqlite3TreeViewPush(&pView, (--n)>0); + sqlite3TreeViewLine(pView, "WHERE"); + sqlite3TreeViewExpr(pView, pWhere, 0); + sqlite3TreeViewPop(&pView); + } + if( pOrderBy ){ + sqlite3TreeViewExprList(pView, pOrderBy, (--n)>0, "ORDER-BY"); + } + if( pLimit ){ + sqlite3TreeViewPush(&pView, (--n)>0); + sqlite3TreeViewLine(pView, "LIMIT"); + sqlite3TreeViewExpr(pView, pLimit, 0); + sqlite3TreeViewPop(&pView); + } + if( pTrigger ){ + sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1); + } + sqlite3TreeViewPop(&pView); +} +#endif /* TREETRACE_ENABLED */ + +#if TREETRACE_ENABLED +/* +** Generate a human-readable diagram of the data structure that go +** into generating an INSERT statement. +*/ +SQLITE_PRIVATE void sqlite3TreeViewInsert( + const With *pWith, + const SrcList *pTabList, + const IdList *pColumnList, + const Select *pSelect, + const ExprList *pExprList, + int onError, + const Upsert *pUpsert, + const Trigger *pTrigger +){ + TreeView *pView = 0; + int n = 0; + const char *zLabel = "INSERT"; + switch( onError ){ + case OE_Replace: zLabel = "REPLACE"; break; + case OE_Ignore: zLabel = "INSERT OR IGNORE"; break; + case OE_Rollback: zLabel = "INSERT OR ROLLBACK"; break; + case OE_Abort: zLabel = "INSERT OR ABORT"; break; + case OE_Fail: zLabel = "INSERT OR FAIL"; break; + } + sqlite3TreeViewPush(&pView, 0); + sqlite3TreeViewLine(pView, zLabel); + if( pWith ) n++; + if( pTabList ) n++; + if( pColumnList ) n++; + if( pSelect ) n++; + if( pExprList ) n++; + if( pUpsert ) n++; + if( pTrigger ) n++; + if( pWith ){ + sqlite3TreeViewPush(&pView, (--n)>0); + sqlite3TreeViewWith(pView, pWith, 0); + sqlite3TreeViewPop(&pView); + } + if( pTabList ){ + sqlite3TreeViewPush(&pView, (--n)>0); + sqlite3TreeViewLine(pView, "INTO"); + sqlite3TreeViewSrcList(pView, pTabList); + sqlite3TreeViewPop(&pView); + } + if( pColumnList ){ + sqlite3TreeViewIdList(pView, pColumnList, (--n)>0, "COLUMNS"); + } + if( pSelect ){ + sqlite3TreeViewPush(&pView, (--n)>0); + sqlite3TreeViewLine(pView, "DATA-SOURCE"); + sqlite3TreeViewSelect(pView, pSelect, 0); + sqlite3TreeViewPop(&pView); + } + if( pExprList ){ + sqlite3TreeViewExprList(pView, pExprList, (--n)>0, "VALUES"); + } + if( pUpsert ){ + sqlite3TreeViewPush(&pView, (--n)>0); + sqlite3TreeViewLine(pView, "UPSERT"); + sqlite3TreeViewUpsert(pView, pUpsert, 0); + sqlite3TreeViewPop(&pView); + } + if( pTrigger ){ + sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1); + } + sqlite3TreeViewPop(&pView); +} +#endif /* TREETRACE_ENABLED */ + +#if TREETRACE_ENABLED +/* +** Generate a human-readable diagram of the data structure that go +** into generating an UPDATE statement. +*/ +SQLITE_PRIVATE void sqlite3TreeViewUpdate( + const With *pWith, + const SrcList *pTabList, + const ExprList *pChanges, + const Expr *pWhere, + int onError, + const ExprList *pOrderBy, + const Expr *pLimit, + const Upsert *pUpsert, + const Trigger *pTrigger +){ + int n = 0; + TreeView *pView = 0; + const char *zLabel = "UPDATE"; + switch( onError ){ + case OE_Replace: zLabel = "UPDATE OR REPLACE"; break; + case OE_Ignore: zLabel = "UPDATE OR IGNORE"; break; + case OE_Rollback: zLabel = "UPDATE OR ROLLBACK"; break; + case OE_Abort: zLabel = "UPDATE OR ABORT"; break; + case OE_Fail: zLabel = "UPDATE OR FAIL"; break; + } + sqlite3TreeViewPush(&pView, 0); + sqlite3TreeViewLine(pView, zLabel); + if( pWith ) n++; + if( pTabList ) n++; + if( pChanges ) n++; + if( pWhere ) n++; + if( pOrderBy ) n++; + if( pLimit ) n++; + if( pUpsert ) n++; + if( pTrigger ) n++; + if( pWith ){ + sqlite3TreeViewPush(&pView, (--n)>0); + sqlite3TreeViewWith(pView, pWith, 0); + sqlite3TreeViewPop(&pView); + } + if( pTabList ){ + sqlite3TreeViewPush(&pView, (--n)>0); + sqlite3TreeViewLine(pView, "FROM"); + sqlite3TreeViewSrcList(pView, pTabList); + sqlite3TreeViewPop(&pView); + } + if( pChanges ){ + sqlite3TreeViewExprList(pView, pChanges, (--n)>0, "SET"); + } + if( pWhere ){ + sqlite3TreeViewPush(&pView, (--n)>0); + sqlite3TreeViewLine(pView, "WHERE"); + sqlite3TreeViewExpr(pView, pWhere, 0); + sqlite3TreeViewPop(&pView); + } + if( pOrderBy ){ + sqlite3TreeViewExprList(pView, pOrderBy, (--n)>0, "ORDER-BY"); + } + if( pLimit ){ + sqlite3TreeViewPush(&pView, (--n)>0); + sqlite3TreeViewLine(pView, "LIMIT"); + sqlite3TreeViewExpr(pView, pLimit, 0); + sqlite3TreeViewPop(&pView); + } + if( pUpsert ){ + sqlite3TreeViewPush(&pView, (--n)>0); + sqlite3TreeViewLine(pView, "UPSERT"); + sqlite3TreeViewUpsert(pView, pUpsert, 0); + sqlite3TreeViewPop(&pView); + } + if( pTrigger ){ + sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1); + } + sqlite3TreeViewPop(&pView); +} +#endif /* TREETRACE_ENABLED */ + +#ifndef SQLITE_OMIT_TRIGGER +/* +** Show a human-readable graph of a TriggerStep +*/ +SQLITE_PRIVATE void sqlite3TreeViewTriggerStep( + TreeView *pView, + const TriggerStep *pStep, + u8 moreToFollow, + u8 showFullList +){ + int cnt = 0; + if( pStep==0 ) return; + sqlite3TreeViewPush(&pView, + moreToFollow || (showFullList && pStep->pNext!=0)); + do{ + if( cnt++ && pStep->pNext==0 ){ + sqlite3TreeViewPop(&pView); + sqlite3TreeViewPush(&pView, 0); + } + sqlite3TreeViewLine(pView, "%s", pStep->zSpan ? pStep->zSpan : "RETURNING"); + }while( showFullList && (pStep = pStep->pNext)!=0 ); + sqlite3TreeViewPop(&pView); +} + +/* +** Show a human-readable graph of a Trigger +*/ +SQLITE_PRIVATE void sqlite3TreeViewTrigger( + TreeView *pView, + const Trigger *pTrigger, + u8 moreToFollow, + u8 showFullList +){ + int cnt = 0; + if( pTrigger==0 ) return; + sqlite3TreeViewPush(&pView, + moreToFollow || (showFullList && pTrigger->pNext!=0)); + do{ + if( cnt++ && pTrigger->pNext==0 ){ + sqlite3TreeViewPop(&pView); + sqlite3TreeViewPush(&pView, 0); + } + sqlite3TreeViewLine(pView, "TRIGGER %s", pTrigger->zName); + sqlite3TreeViewPush(&pView, 0); + sqlite3TreeViewTriggerStep(pView, pTrigger->step_list, 0, 1); + sqlite3TreeViewPop(&pView); + }while( showFullList && (pTrigger = pTrigger->pNext)!=0 ); + sqlite3TreeViewPop(&pView); +} +#endif /* SQLITE_OMIT_TRIGGER */ + + +/* +** These simplified versions of the tree-view routines omit unnecessary +** parameters. These variants are intended to be used from a symbolic +** debugger, such as "gdb", during interactive debugging sessions. +** +** This routines are given external linkage so that they will always be +** accessible to the debugging, and to avoid warnings about unused +** functions. But these routines only exist in debugging builds, so they +** do not contaminate the interface. +** +** See Also: +** +** sqlite3ShowWhereTerm() in where.c +*/ +SQLITE_PRIVATE void sqlite3ShowExpr(const Expr *p){ sqlite3TreeViewExpr(0,p,0); } +SQLITE_PRIVATE void sqlite3ShowExprList(const ExprList *p){ sqlite3TreeViewExprList(0,p,0,0);} +SQLITE_PRIVATE void sqlite3ShowIdList(const IdList *p){ sqlite3TreeViewIdList(0,p,0,0); } +SQLITE_PRIVATE void sqlite3ShowSrcList(const SrcList *p){ + TreeView *pView = 0; + sqlite3TreeViewPush(&pView, 0); + sqlite3TreeViewLine(pView, "SRCLIST"); + sqlite3TreeViewSrcList(pView,p); + sqlite3TreeViewPop(&pView); +} +SQLITE_PRIVATE void sqlite3ShowSelect(const Select *p){ sqlite3TreeViewSelect(0,p,0); } +SQLITE_PRIVATE void sqlite3ShowWith(const With *p){ sqlite3TreeViewWith(0,p,0); } +SQLITE_PRIVATE void sqlite3ShowUpsert(const Upsert *p){ sqlite3TreeViewUpsert(0,p,0); } +#ifndef SQLITE_OMIT_TRIGGER +SQLITE_PRIVATE void sqlite3ShowTriggerStep(const TriggerStep *p){ + sqlite3TreeViewTriggerStep(0,p,0,0); +} +SQLITE_PRIVATE void sqlite3ShowTriggerStepList(const TriggerStep *p){ + sqlite3TreeViewTriggerStep(0,p,0,1); +} +SQLITE_PRIVATE void sqlite3ShowTrigger(const Trigger *p){ sqlite3TreeViewTrigger(0,p,0,0); } +SQLITE_PRIVATE void sqlite3ShowTriggerList(const Trigger *p){ sqlite3TreeViewTrigger(0,p,0,1);} +#endif +#ifndef SQLITE_OMIT_WINDOWFUNC +SQLITE_PRIVATE void sqlite3ShowWindow(const Window *p){ sqlite3TreeViewWindow(0,p,0); } +SQLITE_PRIVATE void sqlite3ShowWinFunc(const Window *p){ sqlite3TreeViewWinFunc(0,p,0); } +#endif + +#endif /* SQLITE_DEBUG */ + +/************** End of treeview.c ********************************************/ +/************** Begin file random.c ******************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code to implement a pseudo-random number +** generator (PRNG) for SQLite. +** +** Random numbers are used by some of the database backends in order +** to generate random integer keys for tables or random filenames. +*/ +/* #include "sqliteInt.h" */ + + +/* All threads share a single random number generator. +** This structure is the current state of the generator. +*/ +static SQLITE_WSD struct sqlite3PrngType { + u32 s[16]; /* 64 bytes of chacha20 state */ + u8 out[64]; /* Output bytes */ + u8 n; /* Output bytes remaining */ +} sqlite3Prng; + + +/* The RFC-7539 ChaCha20 block function +*/ +#define ROTL(a,b) (((a) << (b)) | ((a) >> (32 - (b)))) +#define QR(a, b, c, d) ( \ + a += b, d ^= a, d = ROTL(d,16), \ + c += d, b ^= c, b = ROTL(b,12), \ + a += b, d ^= a, d = ROTL(d, 8), \ + c += d, b ^= c, b = ROTL(b, 7)) +static void chacha_block(u32 *out, const u32 *in){ + int i; + u32 x[16]; + memcpy(x, in, 64); + for(i=0; i<10; i++){ + QR(x[0], x[4], x[ 8], x[12]); + QR(x[1], x[5], x[ 9], x[13]); + QR(x[2], x[6], x[10], x[14]); + QR(x[3], x[7], x[11], x[15]); + QR(x[0], x[5], x[10], x[15]); + QR(x[1], x[6], x[11], x[12]); + QR(x[2], x[7], x[ 8], x[13]); + QR(x[3], x[4], x[ 9], x[14]); + } + for(i=0; i<16; i++) out[i] = x[i]+in[i]; +} + +/* +** Return N random bytes. +*/ +SQLITE_API void sqlite3_randomness(int N, void *pBuf){ + unsigned char *zBuf = pBuf; + + /* The "wsdPrng" macro will resolve to the pseudo-random number generator + ** state vector. If writable static data is unsupported on the target, + ** we have to locate the state vector at run-time. In the more common + ** case where writable static data is supported, wsdPrng can refer directly + ** to the "sqlite3Prng" state vector declared above. + */ +#ifdef SQLITE_OMIT_WSD + struct sqlite3PrngType *p = &GLOBAL(struct sqlite3PrngType, sqlite3Prng); +# define wsdPrng p[0] +#else +# define wsdPrng sqlite3Prng +#endif + +#if SQLITE_THREADSAFE + sqlite3_mutex *mutex; +#endif + +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return; +#endif + +#if SQLITE_THREADSAFE + mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG); +#endif + + sqlite3_mutex_enter(mutex); + if( N<=0 || pBuf==0 ){ + wsdPrng.s[0] = 0; + sqlite3_mutex_leave(mutex); + return; + } + + /* Initialize the state of the random number generator once, + ** the first time this routine is called. + */ + if( wsdPrng.s[0]==0 ){ + sqlite3_vfs *pVfs = sqlite3_vfs_find(0); + static const u32 chacha20_init[] = { + 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 + }; + memcpy(&wsdPrng.s[0], chacha20_init, 16); + if( NEVER(pVfs==0) ){ + memset(&wsdPrng.s[4], 0, 44); + }else{ + sqlite3OsRandomness(pVfs, 44, (char*)&wsdPrng.s[4]); + } + wsdPrng.s[15] = wsdPrng.s[12]; + wsdPrng.s[12] = 0; + wsdPrng.n = 0; + } + + assert( N>0 ); + while( 1 /* exit by break */ ){ + if( N<=wsdPrng.n ){ + memcpy(zBuf, &wsdPrng.out[wsdPrng.n-N], N); + wsdPrng.n -= N; + break; + } + if( wsdPrng.n>0 ){ + memcpy(zBuf, wsdPrng.out, wsdPrng.n); + N -= wsdPrng.n; + zBuf += wsdPrng.n; + } + wsdPrng.s[12]++; + chacha_block((u32*)wsdPrng.out, wsdPrng.s); + wsdPrng.n = 64; + } + sqlite3_mutex_leave(mutex); +} + +#ifndef SQLITE_UNTESTABLE +/* +** For testing purposes, we sometimes want to preserve the state of +** PRNG and restore the PRNG to its saved state at a later time, or +** to reset the PRNG to its initial state. These routines accomplish +** those tasks. +** +** The sqlite3_test_control() interface calls these routines to +** control the PRNG. +*/ +static SQLITE_WSD struct sqlite3PrngType sqlite3SavedPrng; +SQLITE_PRIVATE void sqlite3PrngSaveState(void){ + memcpy( + &GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng), + &GLOBAL(struct sqlite3PrngType, sqlite3Prng), + sizeof(sqlite3Prng) + ); +} +SQLITE_PRIVATE void sqlite3PrngRestoreState(void){ + memcpy( + &GLOBAL(struct sqlite3PrngType, sqlite3Prng), + &GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng), + sizeof(sqlite3Prng) + ); +} +#endif /* SQLITE_UNTESTABLE */ + +/************** End of random.c **********************************************/ +/************** Begin file threads.c *****************************************/ +/* +** 2012 July 21 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file presents a simple cross-platform threading interface for +** use internally by SQLite. +** +** A "thread" can be created using sqlite3ThreadCreate(). This thread +** runs independently of its creator until it is joined using +** sqlite3ThreadJoin(), at which point it terminates. +** +** Threads do not have to be real. It could be that the work of the +** "thread" is done by the main thread at either the sqlite3ThreadCreate() +** or sqlite3ThreadJoin() call. This is, in fact, what happens in +** single threaded systems. Nothing in SQLite requires multiple threads. +** This interface exists so that applications that want to take advantage +** of multiple cores can do so, while also allowing applications to stay +** single-threaded if desired. +*/ +/* #include "sqliteInt.h" */ +#if SQLITE_OS_WIN +/* # include "os_win.h" */ +#endif + +#if SQLITE_MAX_WORKER_THREADS>0 + +/********************************* Unix Pthreads ****************************/ +#if SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) && SQLITE_THREADSAFE>0 + +#define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */ +/* #include */ + +/* A running thread */ +struct SQLiteThread { + pthread_t tid; /* Thread ID */ + int done; /* Set to true when thread finishes */ + void *pOut; /* Result returned by the thread */ + void *(*xTask)(void*); /* The thread routine */ + void *pIn; /* Argument to the thread */ +}; + +/* Create a new thread */ +SQLITE_PRIVATE int sqlite3ThreadCreate( + SQLiteThread **ppThread, /* OUT: Write the thread object here */ + void *(*xTask)(void*), /* Routine to run in a separate thread */ + void *pIn /* Argument passed into xTask() */ +){ + SQLiteThread *p; + int rc; + + assert( ppThread!=0 ); + assert( xTask!=0 ); + /* This routine is never used in single-threaded mode */ + assert( sqlite3GlobalConfig.bCoreMutex!=0 ); + + *ppThread = 0; + p = sqlite3Malloc(sizeof(*p)); + if( p==0 ) return SQLITE_NOMEM_BKPT; + memset(p, 0, sizeof(*p)); + p->xTask = xTask; + p->pIn = pIn; + /* If the SQLITE_TESTCTRL_FAULT_INSTALL callback is registered to a + ** function that returns SQLITE_ERROR when passed the argument 200, that + ** forces worker threads to run sequentially and deterministically + ** for testing purposes. */ + if( sqlite3FaultSim(200) ){ + rc = 1; + }else{ + rc = pthread_create(&p->tid, 0, xTask, pIn); + } + if( rc ){ + p->done = 1; + p->pOut = xTask(pIn); + } + *ppThread = p; + return SQLITE_OK; +} + +/* Get the results of the thread */ +SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ + int rc; + + assert( ppOut!=0 ); + if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT; + if( p->done ){ + *ppOut = p->pOut; + rc = SQLITE_OK; + }else{ + rc = pthread_join(p->tid, ppOut) ? SQLITE_ERROR : SQLITE_OK; + } + sqlite3_free(p); + return rc; +} + +#endif /* SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) */ +/******************************** End Unix Pthreads *************************/ + + +/********************************* Win32 Threads ****************************/ +#if SQLITE_OS_WIN_THREADS + +#define SQLITE_THREADS_IMPLEMENTED 1 /* Prevent the single-thread code below */ +#include + +/* A running thread */ +struct SQLiteThread { + void *tid; /* The thread handle */ + unsigned id; /* The thread identifier */ + void *(*xTask)(void*); /* The routine to run as a thread */ + void *pIn; /* Argument to xTask */ + void *pResult; /* Result of xTask */ +}; + +/* Thread procedure Win32 compatibility shim */ +static unsigned __stdcall sqlite3ThreadProc( + void *pArg /* IN: Pointer to the SQLiteThread structure */ +){ + SQLiteThread *p = (SQLiteThread *)pArg; + + assert( p!=0 ); +#if 0 + /* + ** This assert appears to trigger spuriously on certain + ** versions of Windows, possibly due to _beginthreadex() + ** and/or CreateThread() not fully setting their thread + ** ID parameter before starting the thread. + */ + assert( p->id==GetCurrentThreadId() ); +#endif + assert( p->xTask!=0 ); + p->pResult = p->xTask(p->pIn); + + _endthreadex(0); + return 0; /* NOT REACHED */ +} + +/* Create a new thread */ +SQLITE_PRIVATE int sqlite3ThreadCreate( + SQLiteThread **ppThread, /* OUT: Write the thread object here */ + void *(*xTask)(void*), /* Routine to run in a separate thread */ + void *pIn /* Argument passed into xTask() */ +){ + SQLiteThread *p; + + assert( ppThread!=0 ); + assert( xTask!=0 ); + *ppThread = 0; + p = sqlite3Malloc(sizeof(*p)); + if( p==0 ) return SQLITE_NOMEM_BKPT; + /* If the SQLITE_TESTCTRL_FAULT_INSTALL callback is registered to a + ** function that returns SQLITE_ERROR when passed the argument 200, that + ** forces worker threads to run sequentially and deterministically + ** (via the sqlite3FaultSim() term of the conditional) for testing + ** purposes. */ + if( sqlite3GlobalConfig.bCoreMutex==0 || sqlite3FaultSim(200) ){ + memset(p, 0, sizeof(*p)); + }else{ + p->xTask = xTask; + p->pIn = pIn; + p->tid = (void*)_beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id); + if( p->tid==0 ){ + memset(p, 0, sizeof(*p)); + } + } + if( p->xTask==0 ){ + p->id = GetCurrentThreadId(); + p->pResult = xTask(pIn); + } + *ppThread = p; + return SQLITE_OK; +} + +SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject); /* os_win.c */ + +/* Get the results of the thread */ +SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ + DWORD rc; + BOOL bRc; + + assert( ppOut!=0 ); + if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT; + if( p->xTask==0 ){ + /* assert( p->id==GetCurrentThreadId() ); */ + rc = WAIT_OBJECT_0; + assert( p->tid==0 ); + }else{ + assert( p->id!=0 && p->id!=GetCurrentThreadId() ); + rc = sqlite3Win32Wait((HANDLE)p->tid); + assert( rc!=WAIT_IO_COMPLETION ); + bRc = CloseHandle((HANDLE)p->tid); + (void)bRc; /* Prevent warning when assert() is a no-op */ + assert( bRc ); + } + if( rc==WAIT_OBJECT_0 ) *ppOut = p->pResult; + sqlite3_free(p); + return (rc==WAIT_OBJECT_0) ? SQLITE_OK : SQLITE_ERROR; +} + +#endif /* SQLITE_OS_WIN_THREADS */ +/******************************** End Win32 Threads *************************/ + + +/********************************* Single-Threaded **************************/ +#ifndef SQLITE_THREADS_IMPLEMENTED +/* +** This implementation does not actually create a new thread. It does the +** work of the thread in the main thread, when either the thread is created +** or when it is joined +*/ + +/* A running thread */ +struct SQLiteThread { + void *(*xTask)(void*); /* The routine to run as a thread */ + void *pIn; /* Argument to xTask */ + void *pResult; /* Result of xTask */ +}; + +/* Create a new thread */ +SQLITE_PRIVATE int sqlite3ThreadCreate( + SQLiteThread **ppThread, /* OUT: Write the thread object here */ + void *(*xTask)(void*), /* Routine to run in a separate thread */ + void *pIn /* Argument passed into xTask() */ +){ + SQLiteThread *p; + + assert( ppThread!=0 ); + assert( xTask!=0 ); + *ppThread = 0; + p = sqlite3Malloc(sizeof(*p)); + if( p==0 ) return SQLITE_NOMEM_BKPT; + if( (SQLITE_PTR_TO_INT(p)/17)&1 ){ + p->xTask = xTask; + p->pIn = pIn; + }else{ + p->xTask = 0; + p->pResult = xTask(pIn); + } + *ppThread = p; + return SQLITE_OK; +} + +/* Get the results of the thread */ +SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ + + assert( ppOut!=0 ); + if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT; + if( p->xTask ){ + *ppOut = p->xTask(p->pIn); + }else{ + *ppOut = p->pResult; + } + sqlite3_free(p); + +#if defined(SQLITE_TEST) + { + void *pTstAlloc = sqlite3Malloc(10); + if (!pTstAlloc) return SQLITE_NOMEM_BKPT; + sqlite3_free(pTstAlloc); + } +#endif + + return SQLITE_OK; +} + +#endif /* !defined(SQLITE_THREADS_IMPLEMENTED) */ +/****************************** End Single-Threaded *************************/ +#endif /* SQLITE_MAX_WORKER_THREADS>0 */ + +/************** End of threads.c *********************************************/ +/************** Begin file utf.c *********************************************/ +/* +** 2004 April 13 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains routines used to translate between UTF-8, +** UTF-16, UTF-16BE, and UTF-16LE. +** +** Notes on UTF-8: +** +** Byte-0 Byte-1 Byte-2 Byte-3 Value +** 0xxxxxxx 00000000 00000000 0xxxxxxx +** 110yyyyy 10xxxxxx 00000000 00000yyy yyxxxxxx +** 1110zzzz 10yyyyyy 10xxxxxx 00000000 zzzzyyyy yyxxxxxx +** 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx 000uuuuu zzzzyyyy yyxxxxxx +** +** +** Notes on UTF-16: (with wwww+1==uuuuu) +** +** Word-0 Word-1 Value +** 110110ww wwzzzzyy 110111yy yyxxxxxx 000uuuuu zzzzyyyy yyxxxxxx +** zzzzyyyy yyxxxxxx 00000000 zzzzyyyy yyxxxxxx +** +** +** BOM or Byte Order Mark: +** 0xff 0xfe little-endian utf-16 follows +** 0xfe 0xff big-endian utf-16 follows +** +*/ +/* #include "sqliteInt.h" */ +/* #include */ +/* #include "vdbeInt.h" */ + +#if !defined(SQLITE_AMALGAMATION) && SQLITE_BYTEORDER==0 +/* +** The following constant value is used by the SQLITE_BIGENDIAN and +** SQLITE_LITTLEENDIAN macros. +*/ +SQLITE_PRIVATE const int sqlite3one = 1; +#endif /* SQLITE_AMALGAMATION && SQLITE_BYTEORDER==0 */ + +/* +** This lookup table is used to help decode the first byte of +** a multi-byte UTF8 character. +*/ +static const unsigned char sqlite3Utf8Trans1[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00, +}; + + +#define WRITE_UTF8(zOut, c) { \ + if( c<0x00080 ){ \ + *zOut++ = (u8)(c&0xFF); \ + } \ + else if( c<0x00800 ){ \ + *zOut++ = 0xC0 + (u8)((c>>6)&0x1F); \ + *zOut++ = 0x80 + (u8)(c & 0x3F); \ + } \ + else if( c<0x10000 ){ \ + *zOut++ = 0xE0 + (u8)((c>>12)&0x0F); \ + *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \ + *zOut++ = 0x80 + (u8)(c & 0x3F); \ + }else{ \ + *zOut++ = 0xF0 + (u8)((c>>18) & 0x07); \ + *zOut++ = 0x80 + (u8)((c>>12) & 0x3F); \ + *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \ + *zOut++ = 0x80 + (u8)(c & 0x3F); \ + } \ +} + +#define WRITE_UTF16LE(zOut, c) { \ + if( c<=0xFFFF ){ \ + *zOut++ = (u8)(c&0x00FF); \ + *zOut++ = (u8)((c>>8)&0x00FF); \ + }else{ \ + *zOut++ = (u8)(((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0)); \ + *zOut++ = (u8)(0x00D8 + (((c-0x10000)>>18)&0x03)); \ + *zOut++ = (u8)(c&0x00FF); \ + *zOut++ = (u8)(0x00DC + ((c>>8)&0x03)); \ + } \ +} + +#define WRITE_UTF16BE(zOut, c) { \ + if( c<=0xFFFF ){ \ + *zOut++ = (u8)((c>>8)&0x00FF); \ + *zOut++ = (u8)(c&0x00FF); \ + }else{ \ + *zOut++ = (u8)(0x00D8 + (((c-0x10000)>>18)&0x03)); \ + *zOut++ = (u8)(((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0)); \ + *zOut++ = (u8)(0x00DC + ((c>>8)&0x03)); \ + *zOut++ = (u8)(c&0x00FF); \ + } \ +} + +/* +** Write a single UTF8 character whose value is v into the +** buffer starting at zOut. zOut must be sized to hold at +** least four bytes. Return the number of bytes needed +** to encode the new character. +*/ +SQLITE_PRIVATE int sqlite3AppendOneUtf8Character(char *zOut, u32 v){ + if( v<0x00080 ){ + zOut[0] = (u8)(v & 0xff); + return 1; + } + if( v<0x00800 ){ + zOut[0] = 0xc0 + (u8)((v>>6) & 0x1f); + zOut[1] = 0x80 + (u8)(v & 0x3f); + return 2; + } + if( v<0x10000 ){ + zOut[0] = 0xe0 + (u8)((v>>12) & 0x0f); + zOut[1] = 0x80 + (u8)((v>>6) & 0x3f); + zOut[2] = 0x80 + (u8)(v & 0x3f); + return 3; + } + zOut[0] = 0xf0 + (u8)((v>>18) & 0x07); + zOut[1] = 0x80 + (u8)((v>>12) & 0x3f); + zOut[2] = 0x80 + (u8)((v>>6) & 0x3f); + zOut[3] = 0x80 + (u8)(v & 0x3f); + return 4; +} + +/* +** Translate a single UTF-8 character. Return the unicode value. +** +** During translation, assume that the byte that zTerm points +** is a 0x00. +** +** Write a pointer to the next unread byte back into *pzNext. +** +** Notes On Invalid UTF-8: +** +** * This routine never allows a 7-bit character (0x00 through 0x7f) to +** be encoded as a multi-byte character. Any multi-byte character that +** attempts to encode a value between 0x00 and 0x7f is rendered as 0xfffd. +** +** * This routine never allows a UTF16 surrogate value to be encoded. +** If a multi-byte character attempts to encode a value between +** 0xd800 and 0xe000 then it is rendered as 0xfffd. +** +** * Bytes in the range of 0x80 through 0xbf which occur as the first +** byte of a character are interpreted as single-byte characters +** and rendered as themselves even though they are technically +** invalid characters. +** +** * This routine accepts over-length UTF8 encodings +** for unicode values 0x80 and greater. It does not change over-length +** encodings to 0xfffd as some systems recommend. +*/ +#define READ_UTF8(zIn, zTerm, c) \ + c = *(zIn++); \ + if( c>=0xc0 ){ \ + c = sqlite3Utf8Trans1[c-0xc0]; \ + while( zIn=0xc0 ){ + c = sqlite3Utf8Trans1[c-0xc0]; + while( (*(*pz) & 0xc0)==0x80 ){ + c = (c<<6) + (0x3f & *((*pz)++)); + } + if( c<0x80 + || (c&0xFFFFF800)==0xD800 + || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } + } + return c; +} + +/* +** Read a single UTF8 character out of buffer z[], but reading no +** more than n characters from the buffer. z[] is not zero-terminated. +** +** Return the number of bytes used to construct the character. +** +** Invalid UTF8 might generate a strange result. No effort is made +** to detect invalid UTF8. +** +** At most 4 bytes will be read out of z[]. The return value will always +** be between 1 and 4. +*/ +SQLITE_PRIVATE int sqlite3Utf8ReadLimited( + const u8 *z, + int n, + u32 *piOut +){ + u32 c; + int i = 1; + assert( n>0 ); + c = z[0]; + if( c>=0xc0 ){ + c = sqlite3Utf8Trans1[c-0xc0]; + if( n>4 ) n = 4; + while( idb==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( pMem->flags&MEM_Str ); + assert( pMem->enc!=desiredEnc ); + assert( pMem->enc!=0 ); + assert( pMem->n>=0 ); + +#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG) + { + StrAccum acc; + char zBuf[1000]; + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); + sqlite3VdbeMemPrettyPrint(pMem, &acc); + fprintf(stderr, "INPUT: %s\n", sqlite3StrAccumFinish(&acc)); + } +#endif + + /* If the translation is between UTF-16 little and big endian, then + ** all that is required is to swap the byte order. This case is handled + ** differently from the others. + */ + if( pMem->enc!=SQLITE_UTF8 && desiredEnc!=SQLITE_UTF8 ){ + u8 temp; + int rc; + rc = sqlite3VdbeMemMakeWriteable(pMem); + if( rc!=SQLITE_OK ){ + assert( rc==SQLITE_NOMEM ); + return SQLITE_NOMEM_BKPT; + } + zIn = (u8*)pMem->z; + zTerm = &zIn[pMem->n&~1]; + while( zInenc = desiredEnc; + goto translate_out; + } + + /* Set len to the maximum number of bytes required in the output buffer. */ + if( desiredEnc==SQLITE_UTF8 ){ + /* When converting from UTF-16, the maximum growth results from + ** translating a 2-byte character to a 4-byte UTF-8 character. + ** A single byte is required for the output string + ** nul-terminator. + */ + pMem->n &= ~1; + len = 2 * (sqlite3_int64)pMem->n + 1; + }else{ + /* When converting from UTF-8 to UTF-16 the maximum growth is caused + ** when a 1-byte UTF-8 character is translated into a 2-byte UTF-16 + ** character. Two bytes are required in the output buffer for the + ** nul-terminator. + */ + len = 2 * (sqlite3_int64)pMem->n + 2; + } + + /* Set zIn to point at the start of the input buffer and zTerm to point 1 + ** byte past the end. + ** + ** Variable zOut is set to point at the output buffer, space obtained + ** from sqlite3_malloc(). + */ + zIn = (u8*)pMem->z; + zTerm = &zIn[pMem->n]; + zOut = sqlite3DbMallocRaw(pMem->db, len); + if( !zOut ){ + return SQLITE_NOMEM_BKPT; + } + z = zOut; + + if( pMem->enc==SQLITE_UTF8 ){ + if( desiredEnc==SQLITE_UTF16LE ){ + /* UTF-8 -> UTF-16 Little-endian */ + while( zIn UTF-16 Big-endian */ + while( zInn = (int)(z - zOut); + *z++ = 0; + }else{ + assert( desiredEnc==SQLITE_UTF8 ); + if( pMem->enc==SQLITE_UTF16LE ){ + /* UTF-16 Little-endian -> UTF-8 */ + while( zIn=0xd800 && c<0xe000 ){ +#ifdef SQLITE_REPLACE_INVALID_UTF + if( c>=0xdc00 || zIn>=zTerm ){ + c = 0xfffd; + }else{ + int c2 = *(zIn++); + c2 += (*(zIn++))<<8; + if( c2<0xdc00 || c2>=0xe000 ){ + zIn -= 2; + c = 0xfffd; + }else{ + c = ((c&0x3ff)<<10) + (c2&0x3ff) + 0x10000; + } + } +#else + if( zIn UTF-8 */ + while( zIn=0xd800 && c<0xe000 ){ +#ifdef SQLITE_REPLACE_INVALID_UTF + if( c>=0xdc00 || zIn>=zTerm ){ + c = 0xfffd; + }else{ + int c2 = (*(zIn++))<<8; + c2 += *(zIn++); + if( c2<0xdc00 || c2>=0xe000 ){ + zIn -= 2; + c = 0xfffd; + }else{ + c = ((c&0x3ff)<<10) + (c2&0x3ff) + 0x10000; + } + } +#else + if( zInn = (int)(z - zOut); + } + *z = 0; + assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len ); + + c = MEM_Str|MEM_Term|(pMem->flags&(MEM_AffMask|MEM_Subtype)); + sqlite3VdbeMemRelease(pMem); + pMem->flags = c; + pMem->enc = desiredEnc; + pMem->z = (char*)zOut; + pMem->zMalloc = pMem->z; + pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->z); + +translate_out: +#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG) + { + StrAccum acc; + char zBuf[1000]; + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); + sqlite3VdbeMemPrettyPrint(pMem, &acc); + fprintf(stderr, "OUTPUT: %s\n", sqlite3StrAccumFinish(&acc)); + } +#endif + return SQLITE_OK; +} +#endif /* SQLITE_OMIT_UTF16 */ + +#ifndef SQLITE_OMIT_UTF16 +/* +** This routine checks for a byte-order mark at the beginning of the +** UTF-16 string stored in *pMem. If one is present, it is removed and +** the encoding of the Mem adjusted. This routine does not do any +** byte-swapping, it just sets Mem.enc appropriately. +** +** The allocation (static, dynamic etc.) and encoding of the Mem may be +** changed by this function. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem){ + int rc = SQLITE_OK; + u8 bom = 0; + + assert( pMem->n>=0 ); + if( pMem->n>1 ){ + u8 b1 = *(u8 *)pMem->z; + u8 b2 = *(((u8 *)pMem->z) + 1); + if( b1==0xFE && b2==0xFF ){ + bom = SQLITE_UTF16BE; + } + if( b1==0xFF && b2==0xFE ){ + bom = SQLITE_UTF16LE; + } + } + + if( bom ){ + rc = sqlite3VdbeMemMakeWriteable(pMem); + if( rc==SQLITE_OK ){ + pMem->n -= 2; + memmove(pMem->z, &pMem->z[2], pMem->n); + pMem->z[pMem->n] = '\0'; + pMem->z[pMem->n+1] = '\0'; + pMem->flags |= MEM_Term; + pMem->enc = bom; + } + } + return rc; +} +#endif /* SQLITE_OMIT_UTF16 */ + +/* +** pZ is a UTF-8 encoded unicode string. If nByte is less than zero, +** return the number of unicode characters in pZ up to (but not including) +** the first 0x00 byte. If nByte is not less than zero, return the +** number of unicode characters in the first nByte of pZ (or up to +** the first 0x00, whichever comes first). +*/ +SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *zIn, int nByte){ + int r = 0; + const u8 *z = (const u8*)zIn; + const u8 *zTerm; + if( nByte>=0 ){ + zTerm = &z[nByte]; + }else{ + zTerm = (const u8*)(-1); + } + assert( z<=zTerm ); + while( *z!=0 && zmallocFailed ){ + sqlite3VdbeMemRelease(&m); + m.z = 0; + } + assert( (m.flags & MEM_Term)!=0 || db->mallocFailed ); + assert( (m.flags & MEM_Str)!=0 || db->mallocFailed ); + assert( m.z || db->mallocFailed ); + return m.z; +} + +/* +** zIn is a UTF-16 encoded unicode string at least nByte bytes long. +** Return the number of bytes in the first nChar unicode characters +** in pZ. nChar must be non-negative. Surrogate pairs count as a single +** character. +*/ +SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *zIn, int nByte, int nChar){ + int c; + unsigned char const *z = zIn; + unsigned char const *zEnd = &z[nByte-1]; + int n = 0; + + if( SQLITE_UTF16NATIVE==SQLITE_UTF16LE ) z++; + while( n=0xd8 && c<0xdc && z<=zEnd && z[0]>=0xdc && z[0]<0xe0 ) z += 2; + n++; + } + return (int)(z-(unsigned char const *)zIn) + - (SQLITE_UTF16NATIVE==SQLITE_UTF16LE); +} + +#if defined(SQLITE_TEST) +/* +** This routine is called from the TCL test function "translate_selftest". +** It checks that the primitives for serializing and deserializing +** characters in each encoding are inverses of each other. +*/ +SQLITE_PRIVATE void sqlite3UtfSelfTest(void){ + unsigned int i, t; + unsigned char zBuf[20]; + unsigned char *z; + int n; + unsigned int c; + + for(i=0; i<0x00110000; i++){ + z = zBuf; + WRITE_UTF8(z, i); + n = (int)(z-zBuf); + assert( n>0 && n<=4 ); + z[0] = 0; + z = zBuf; + c = sqlite3Utf8Read((const u8**)&z); + t = i; + if( i>=0xD800 && i<=0xDFFF ) t = 0xFFFD; + if( (i&0xFFFFFFFE)==0xFFFE ) t = 0xFFFD; + assert( c==t ); + assert( (z-zBuf)==n ); + } +} +#endif /* SQLITE_TEST */ +#endif /* SQLITE_OMIT_UTF16 */ + +/************** End of utf.c *************************************************/ +/************** Begin file util.c ********************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** Utility functions used throughout sqlite. +** +** This file contains functions for allocating memory, comparing +** strings, and stuff like that. +** +*/ +/* #include "sqliteInt.h" */ +/* #include */ +#ifndef SQLITE_OMIT_FLOATING_POINT +#include +#endif + +/* +** Calls to sqlite3FaultSim() are used to simulate a failure during testing, +** or to bypass normal error detection during testing in order to let +** execute proceed further downstream. +** +** In deployment, sqlite3FaultSim() *always* return SQLITE_OK (0). The +** sqlite3FaultSim() function only returns non-zero during testing. +** +** During testing, if the test harness has set a fault-sim callback using +** a call to sqlite3_test_control(SQLITE_TESTCTRL_FAULT_INSTALL), then +** each call to sqlite3FaultSim() is relayed to that application-supplied +** callback and the integer return value form the application-supplied +** callback is returned by sqlite3FaultSim(). +** +** The integer argument to sqlite3FaultSim() is a code to identify which +** sqlite3FaultSim() instance is being invoked. Each call to sqlite3FaultSim() +** should have a unique code. To prevent legacy testing applications from +** breaking, the codes should not be changed or reused. +*/ +#ifndef SQLITE_UNTESTABLE +SQLITE_PRIVATE int sqlite3FaultSim(int iTest){ + int (*xCallback)(int) = sqlite3GlobalConfig.xTestCallback; + return xCallback ? xCallback(iTest) : SQLITE_OK; +} +#endif + +#ifndef SQLITE_OMIT_FLOATING_POINT +/* +** Return true if the floating point value is Not a Number (NaN). +** +** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN. +** Otherwise, we have our own implementation that works on most systems. +*/ +SQLITE_PRIVATE int sqlite3IsNaN(double x){ + int rc; /* The value return */ +#if !SQLITE_HAVE_ISNAN && !HAVE_ISNAN + u64 y; + memcpy(&y,&x,sizeof(y)); + rc = IsNaN(y); +#else + rc = isnan(x); +#endif /* HAVE_ISNAN */ + testcase( rc ); + return rc; +} +#endif /* SQLITE_OMIT_FLOATING_POINT */ + +#ifndef SQLITE_OMIT_FLOATING_POINT +/* +** Return true if the floating point value is NaN or +Inf or -Inf. +*/ +SQLITE_PRIVATE int sqlite3IsOverflow(double x){ + int rc; /* The value return */ + u64 y; + memcpy(&y,&x,sizeof(y)); + rc = IsOvfl(y); + return rc; +} +#endif /* SQLITE_OMIT_FLOATING_POINT */ + +/* +** Compute a string length that is limited to what can be stored in +** lower 30 bits of a 32-bit signed integer. +** +** The value returned will never be negative. Nor will it ever be greater +** than the actual length of the string. For very long strings (greater +** than 1GiB) the value returned might be less than the true string length. +*/ +SQLITE_PRIVATE int sqlite3Strlen30(const char *z){ + if( z==0 ) return 0; + return 0x3fffffff & (int)strlen(z); +} + +/* +** Return the declared type of a column. Or return zDflt if the column +** has no declared type. +** +** The column type is an extra string stored after the zero-terminator on +** the column name if and only if the COLFLAG_HASTYPE flag is set. +*/ +SQLITE_PRIVATE char *sqlite3ColumnType(Column *pCol, char *zDflt){ + if( pCol->colFlags & COLFLAG_HASTYPE ){ + return pCol->zCnName + strlen(pCol->zCnName) + 1; + }else if( pCol->eCType ){ + assert( pCol->eCType<=SQLITE_N_STDTYPE ); + return (char*)sqlite3StdType[pCol->eCType-1]; + }else{ + return zDflt; + } +} + +/* +** Helper function for sqlite3Error() - called rarely. Broken out into +** a separate routine to avoid unnecessary register saves on entry to +** sqlite3Error(). +*/ +static SQLITE_NOINLINE void sqlite3ErrorFinish(sqlite3 *db, int err_code){ + if( db->pErr ) sqlite3ValueSetNull(db->pErr); + sqlite3SystemError(db, err_code); +} + +/* +** Set the current error code to err_code and clear any prior error message. +** Also set iSysErrno (by calling sqlite3System) if the err_code indicates +** that would be appropriate. +*/ +SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code){ + assert( db!=0 ); + db->errCode = err_code; + if( err_code || db->pErr ){ + sqlite3ErrorFinish(db, err_code); + }else{ + db->errByteOffset = -1; + } +} + +/* +** The equivalent of sqlite3Error(db, SQLITE_OK). Clear the error state +** and error message. +*/ +SQLITE_PRIVATE void sqlite3ErrorClear(sqlite3 *db){ + assert( db!=0 ); + db->errCode = SQLITE_OK; + db->errByteOffset = -1; + if( db->pErr ) sqlite3ValueSetNull(db->pErr); +} + +/* +** Load the sqlite3.iSysErrno field if that is an appropriate thing +** to do based on the SQLite error code in rc. +*/ +SQLITE_PRIVATE void sqlite3SystemError(sqlite3 *db, int rc){ + if( rc==SQLITE_IOERR_NOMEM ) return; +#if defined(SQLITE_USE_SEH) && !defined(SQLITE_OMIT_WAL) + if( rc==SQLITE_IOERR_IN_PAGE ){ + int ii; + int iErr; + sqlite3BtreeEnterAll(db); + for(ii=0; iinDb; ii++){ + if( db->aDb[ii].pBt ){ + iErr = sqlite3PagerWalSystemErrno(sqlite3BtreePager(db->aDb[ii].pBt)); + if( iErr ){ + db->iSysErrno = iErr; + } + } + } + sqlite3BtreeLeaveAll(db); + return; + } +#endif + rc &= 0xff; + if( rc==SQLITE_CANTOPEN || rc==SQLITE_IOERR ){ + db->iSysErrno = sqlite3OsGetLastError(db->pVfs); + } +} + +/* +** Set the most recent error code and error string for the sqlite +** handle "db". The error code is set to "err_code". +** +** If it is not NULL, string zFormat specifies the format of the +** error string. zFormat and any string tokens that follow it are +** assumed to be encoded in UTF-8. +** +** To clear the most recent error for sqlite handle "db", sqlite3Error +** should be called with err_code set to SQLITE_OK and zFormat set +** to NULL. +*/ +SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3 *db, int err_code, const char *zFormat, ...){ + assert( db!=0 ); + db->errCode = err_code; + sqlite3SystemError(db, err_code); + if( zFormat==0 ){ + sqlite3Error(db, err_code); + }else if( db->pErr || (db->pErr = sqlite3ValueNew(db))!=0 ){ + char *z; + va_list ap; + va_start(ap, zFormat); + z = sqlite3VMPrintf(db, zFormat, ap); + va_end(ap); + sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, SQLITE_DYNAMIC); + } +} + +/* +** Check for interrupts and invoke progress callback. +*/ +SQLITE_PRIVATE void sqlite3ProgressCheck(Parse *p){ + sqlite3 *db = p->db; + if( AtomicLoad(&db->u1.isInterrupted) ){ + p->nErr++; + p->rc = SQLITE_INTERRUPT; + } +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + if( db->xProgress ){ + if( p->rc==SQLITE_INTERRUPT ){ + p->nProgressSteps = 0; + }else if( (++p->nProgressSteps)>=db->nProgressOps ){ + if( db->xProgress(db->pProgressArg) ){ + p->nErr++; + p->rc = SQLITE_INTERRUPT; + } + p->nProgressSteps = 0; + } + } +#endif +} + +/* +** Add an error message to pParse->zErrMsg and increment pParse->nErr. +** +** This function should be used to report any error that occurs while +** compiling an SQL statement (i.e. within sqlite3_prepare()). The +** last thing the sqlite3_prepare() function does is copy the error +** stored by this function into the database handle using sqlite3Error(). +** Functions sqlite3Error() or sqlite3ErrorWithMsg() should be used +** during statement execution (sqlite3_step() etc.). +*/ +SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){ + char *zMsg; + va_list ap; + sqlite3 *db = pParse->db; + assert( db!=0 ); + assert( db->pParse==pParse || db->pParse->pToplevel==pParse ); + db->errByteOffset = -2; + va_start(ap, zFormat); + zMsg = sqlite3VMPrintf(db, zFormat, ap); + va_end(ap); + if( db->errByteOffset<-1 ) db->errByteOffset = -1; + if( db->suppressErr ){ + sqlite3DbFree(db, zMsg); + if( db->mallocFailed ){ + pParse->nErr++; + pParse->rc = SQLITE_NOMEM; + } + }else{ + pParse->nErr++; + sqlite3DbFree(db, pParse->zErrMsg); + pParse->zErrMsg = zMsg; + pParse->rc = SQLITE_ERROR; + pParse->pWith = 0; + } +} + +/* +** If database connection db is currently parsing SQL, then transfer +** error code errCode to that parser if the parser has not already +** encountered some other kind of error. +*/ +SQLITE_PRIVATE int sqlite3ErrorToParser(sqlite3 *db, int errCode){ + Parse *pParse; + if( db==0 || (pParse = db->pParse)==0 ) return errCode; + pParse->rc = errCode; + pParse->nErr++; + return errCode; +} + +/* +** Convert an SQL-style quoted string into a normal string by removing +** the quote characters. The conversion is done in-place. If the +** input does not begin with a quote character, then this routine +** is a no-op. +** +** The input string must be zero-terminated. A new zero-terminator +** is added to the dequoted string. +** +** The return value is -1 if no dequoting occurs or the length of the +** dequoted string, exclusive of the zero terminator, if dequoting does +** occur. +** +** 2002-02-14: This routine is extended to remove MS-Access style +** brackets from around identifiers. For example: "[a-b-c]" becomes +** "a-b-c". +*/ +SQLITE_PRIVATE void sqlite3Dequote(char *z){ + char quote; + int i, j; + if( z==0 ) return; + quote = z[0]; + if( !sqlite3Isquote(quote) ) return; + if( quote=='[' ) quote = ']'; + for(i=1, j=0;; i++){ + assert( z[i] ); + if( z[i]==quote ){ + if( z[i+1]==quote ){ + z[j++] = quote; + i++; + }else{ + break; + } + }else{ + z[j++] = z[i]; + } + } + z[j] = 0; +} +SQLITE_PRIVATE void sqlite3DequoteExpr(Expr *p){ + assert( !ExprHasProperty(p, EP_IntValue) ); + assert( sqlite3Isquote(p->u.zToken[0]) ); + p->flags |= p->u.zToken[0]=='"' ? EP_Quoted|EP_DblQuoted : EP_Quoted; + sqlite3Dequote(p->u.zToken); +} + +/* +** Expression p is a QNUMBER (quoted number). Dequote the value in p->u.zToken +** and set the type to INTEGER or FLOAT. "Quoted" integers or floats are those +** that contain '_' characters that must be removed before further processing. +*/ +SQLITE_PRIVATE void sqlite3DequoteNumber(Parse *pParse, Expr *p){ + assert( p!=0 || pParse->db->mallocFailed ); + if( p ){ + const char *pIn = p->u.zToken; + char *pOut = p->u.zToken; + int bHex = (pIn[0]=='0' && (pIn[1]=='x' || pIn[1]=='X')); + int iValue; + assert( p->op==TK_QNUMBER ); + p->op = TK_INTEGER; + do { + if( *pIn!=SQLITE_DIGIT_SEPARATOR ){ + *pOut++ = *pIn; + if( *pIn=='e' || *pIn=='E' || *pIn=='.' ) p->op = TK_FLOAT; + }else{ + if( (bHex==0 && (!sqlite3Isdigit(pIn[-1]) || !sqlite3Isdigit(pIn[1]))) + || (bHex==1 && (!sqlite3Isxdigit(pIn[-1]) || !sqlite3Isxdigit(pIn[1]))) + ){ + sqlite3ErrorMsg(pParse, "unrecognized token: \"%s\"", p->u.zToken); + } + } + }while( *pIn++ ); + if( bHex ) p->op = TK_INTEGER; + + /* tag-20240227-a: If after dequoting, the number is an integer that + ** fits in 32 bits, then it must be converted into EP_IntValue. Other + ** parts of the code expect this. See also tag-20240227-b. */ + if( p->op==TK_INTEGER && sqlite3GetInt32(p->u.zToken, &iValue) ){ + p->u.iValue = iValue; + p->flags |= EP_IntValue; + } + } +} + +/* +** If the input token p is quoted, try to adjust the token to remove +** the quotes. This is not always possible: +** +** "abc" -> abc +** "ab""cd" -> (not possible because of the interior "") +** +** Remove the quotes if possible. This is a optimization. The overall +** system should still return the correct answer even if this routine +** is always a no-op. +*/ +SQLITE_PRIVATE void sqlite3DequoteToken(Token *p){ + unsigned int i; + if( p->n<2 ) return; + if( !sqlite3Isquote(p->z[0]) ) return; + for(i=1; in-1; i++){ + if( sqlite3Isquote(p->z[i]) ) return; + } + p->n -= 2; + p->z++; +} + +/* +** Generate a Token object from a string +*/ +SQLITE_PRIVATE void sqlite3TokenInit(Token *p, char *z){ + p->z = z; + p->n = sqlite3Strlen30(z); +} + +/* Convenient short-hand */ +#define UpperToLower sqlite3UpperToLower + +/* +** Some systems have stricmp(). Others have strcasecmp(). Because +** there is no consistency, we will define our own. +** +** IMPLEMENTATION-OF: R-30243-02494 The sqlite3_stricmp() and +** sqlite3_strnicmp() APIs allow applications and extensions to compare +** the contents of two buffers containing UTF-8 strings in a +** case-independent fashion, using the same definition of "case +** independence" that SQLite uses internally when comparing identifiers. +*/ +SQLITE_API int sqlite3_stricmp(const char *zLeft, const char *zRight){ + if( zLeft==0 ){ + return zRight ? -1 : 0; + }else if( zRight==0 ){ + return 1; + } + return sqlite3StrICmp(zLeft, zRight); +} +SQLITE_PRIVATE int sqlite3StrICmp(const char *zLeft, const char *zRight){ + unsigned char *a, *b; + int c, x; + a = (unsigned char *)zLeft; + b = (unsigned char *)zRight; + for(;;){ + c = *a; + x = *b; + if( c==x ){ + if( c==0 ) break; + }else{ + c = (int)UpperToLower[c] - (int)UpperToLower[x]; + if( c ) break; + } + a++; + b++; + } + return c; +} +SQLITE_API int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){ + register unsigned char *a, *b; + if( zLeft==0 ){ + return zRight ? -1 : 0; + }else if( zRight==0 ){ + return 1; + } + a = (unsigned char *)zLeft; + b = (unsigned char *)zRight; + while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; } + return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b]; +} + +/* +** Compute an 8-bit hash on a string that is insensitive to case differences +*/ +SQLITE_PRIVATE u8 sqlite3StrIHash(const char *z){ + u8 h = 0; + if( z==0 ) return 0; + while( z[0] ){ + h += UpperToLower[(unsigned char)z[0]]; + z++; + } + return h; +} + +#if !defined(SQLITE_DISABLE_INTRINSIC) \ + && (defined(__GNUC__) || defined(__clang__)) \ + && (defined(__x86_64__) || defined(__aarch64__) || \ + (defined(__riscv) && defined(__riscv_xlen) && (__riscv_xlen>32))) +#define SQLITE_USE_UINT128 +#endif + +/* +** Two inputs are multiplied to get a 128-bit result. Write the +** lower 64-bits of the result into *pLo, and return the high-order +** 64 bits. +*/ +static u64 sqlite3Multiply128(u64 a, u64 b, u64 *pLo){ +#if defined(SQLITE_USE_UINT128) + __uint128_t r = (__uint128_t)a * b; + *pLo = (u64)r; + return (u64)(r>>64); +#elif defined(_WIN64) && !defined(SQLITE_DISABLE_INTRINSIC) + *pLo = a*b; + return __umulh(a, b); +#else + u64 a0 = (u32)a; + u64 a1 = a >> 32; + u64 b0 = (u32)b; + u64 b1 = b >> 32; + u64 a0b0 = a0 * b0; + u64 a1b1 = a1 * b1; + u64 a0b1 = a0 * b1; + u64 a1b0 = a1 * b0; + u64 t = (a0b0 >> 32) + (u32)a0b1 + (u32)a1b0; + *pLo = (a0b0 & UINT64_C(0xffffffff)) | (t << 32); + return a1b1 + (a0b1>>32) + (a1b0>>32) + (t>>32); +#endif +} + +/* +** A is an unsigned 96-bit integer formed by (a<<32)+aLo. +** B is an unsigned 64-bit integer. +** +** Compute the upper 96 bits of 160-bit result of A*B. +** +** Write ((A*B)>>64 & 0xffffffff) (the middle 32 bits of A*B) +** into *pLo. Return the upper 64 bits of A*B. +** +** The lower 64 bits of A*B are discarded. +*/ +static u64 sqlite3Multiply160(u64 a, u32 aLo, u64 b, u32 *pLo){ +#if defined(SQLITE_USE_UINT128) + __uint128_t r = (__uint128_t)a * b; + r += ((__uint128_t)aLo * b) >> 32; + *pLo = (r>>32)&0xffffffff; + return r>>64; +#elif defined(_WIN64) && !defined(SQLITE_DISABLE_INTRINSIC) + u64 r1_hi = __umulh(a,b); + u64 r1_lo = a*b; + u64 r2 = (__umulh((u64)aLo,b)<<32) + ((aLo*b)>>32); + u64 t = r1_lo + r2; + if( t>32; + return r1_hi; +#else + u64 x2 = a>>32; + u64 x1 = a&0xffffffff; + u64 x0 = aLo; + u64 y1 = b>>32; + u64 y0 = b&0xffffffff; + u64 x2y1 = x2*y1; + u64 r4 = x2y1>>32; + u64 x2y0 = x2*y0; + u64 x1y1 = x1*y1; + u64 r3 = (x2y1 & 0xffffffff) + (x2y0 >>32) + (x1y1 >>32); + u64 x1y0 = x1*y0; + u64 x0y1 = x0*y1; + u64 r2 = (x2y0 & 0xffffffff) + (x1y1 & 0xffffffff) + + (x1y0 >>32) + (x0y1>>32); + u64 x0y0 = x0*y0; + u64 r1 = (x1y0 & 0xffffffff) + (x0y1 & 0xffffffff) + + (x0y0 >>32); + r2 += r1>>32; + r3 += r2>>32; + *pLo = r2&0xffffffff; + return (r4<<32) + r3; +#endif +} + +#undef SQLITE_USE_UINT128 + +/* +** Return a u64 with the N-th bit set. +*/ +#define U64_BIT(N) (((u64)1)<<(N)) + +/* +** Range of powers of 10 that we need to deal with when converting +** IEEE754 doubles to and from decimal. +*/ +#define POWERSOF10_FIRST (-348) +#define POWERSOF10_LAST (+347) + +/* +** For any p between -348 and +347, return the integer part of +** +** pow(10,p) * pow(2,63-pow10to2(p)) +** +** Or, in other words, for any p in range, return the most significant +** 64 bits of pow(10,p). The pow(10,p) value is shifted left or right, +** as appropriate so the most significant 64 bits fit exactly into a +** 64-bit unsigned integer. +** +** Write into *pLo the next 32 significant bits of the answer after +** the first 64. +** +** Algorithm: +** +** (1) For p between 0 and 26, return the value directly from the aBase[] +** lookup table. +** +** (2) For p outside the range 0 to 26, use aScale[] for the initial value +** then refine that result (if necessary) by a single multiplication +** against aBase[]. +** +** The constant tables aBase[], aScale[], and aScaleLo[] are generated +** by the C program at ../tool/mkfptab.c run with the --round option. +*/ +static u64 powerOfTen(int p, u32 *pLo){ + static const u64 aBase[] = { + UINT64_C(0x8000000000000000), /* 0: 1.0e+0 << 63 */ + UINT64_C(0xa000000000000000), /* 1: 1.0e+1 << 60 */ + UINT64_C(0xc800000000000000), /* 2: 1.0e+2 << 57 */ + UINT64_C(0xfa00000000000000), /* 3: 1.0e+3 << 54 */ + UINT64_C(0x9c40000000000000), /* 4: 1.0e+4 << 50 */ + UINT64_C(0xc350000000000000), /* 5: 1.0e+5 << 47 */ + UINT64_C(0xf424000000000000), /* 6: 1.0e+6 << 44 */ + UINT64_C(0x9896800000000000), /* 7: 1.0e+7 << 40 */ + UINT64_C(0xbebc200000000000), /* 8: 1.0e+8 << 37 */ + UINT64_C(0xee6b280000000000), /* 9: 1.0e+9 << 34 */ + UINT64_C(0x9502f90000000000), /* 10: 1.0e+10 << 30 */ + UINT64_C(0xba43b74000000000), /* 11: 1.0e+11 << 27 */ + UINT64_C(0xe8d4a51000000000), /* 12: 1.0e+12 << 24 */ + UINT64_C(0x9184e72a00000000), /* 13: 1.0e+13 << 20 */ + UINT64_C(0xb5e620f480000000), /* 14: 1.0e+14 << 17 */ + UINT64_C(0xe35fa931a0000000), /* 15: 1.0e+15 << 14 */ + UINT64_C(0x8e1bc9bf04000000), /* 16: 1.0e+16 << 10 */ + UINT64_C(0xb1a2bc2ec5000000), /* 17: 1.0e+17 << 7 */ + UINT64_C(0xde0b6b3a76400000), /* 18: 1.0e+18 << 4 */ + UINT64_C(0x8ac7230489e80000), /* 19: 1.0e+19 >> 0 */ + UINT64_C(0xad78ebc5ac620000), /* 20: 1.0e+20 >> 3 */ + UINT64_C(0xd8d726b7177a8000), /* 21: 1.0e+21 >> 6 */ + UINT64_C(0x878678326eac9000), /* 22: 1.0e+22 >> 10 */ + UINT64_C(0xa968163f0a57b400), /* 23: 1.0e+23 >> 13 */ + UINT64_C(0xd3c21bcecceda100), /* 24: 1.0e+24 >> 16 */ + UINT64_C(0x84595161401484a0), /* 25: 1.0e+25 >> 20 */ + UINT64_C(0xa56fa5b99019a5c8), /* 26: 1.0e+26 >> 23 */ + }; + static const u64 aScale[] = { + UINT64_C(0x8049a4ac0c5811ae), /* 0: 1.0e-351 << 1229 */ + UINT64_C(0xcf42894a5dce35ea), /* 1: 1.0e-324 << 1140 */ + UINT64_C(0xa76c582338ed2621), /* 2: 1.0e-297 << 1050 */ + UINT64_C(0x873e4f75e2224e68), /* 3: 1.0e-270 << 960 */ + UINT64_C(0xda7f5bf590966848), /* 4: 1.0e-243 << 871 */ + UINT64_C(0xb080392cc4349dec), /* 5: 1.0e-216 << 781 */ + UINT64_C(0x8e938662882af53e), /* 6: 1.0e-189 << 691 */ + UINT64_C(0xe65829b3046b0afa), /* 7: 1.0e-162 << 602 */ + UINT64_C(0xba121a4650e4ddeb), /* 8: 1.0e-135 << 512 */ + UINT64_C(0x964e858c91ba2655), /* 9: 1.0e-108 << 422 */ + UINT64_C(0xf2d56790ab41c2a2), /* 10: 1.0e-81 << 333 */ + UINT64_C(0xc428d05aa4751e4c), /* 11: 1.0e-54 << 243 */ + UINT64_C(0x9e74d1b791e07e48), /* 12: 1.0e-27 << 153 */ + UINT64_C(0xcccccccccccccccc), /* 13: 1.0e-1 << 67 (special case) */ + UINT64_C(0xcecb8f27f4200f3a), /* 14: 1.0e+27 >> 26 */ + UINT64_C(0xa70c3c40a64e6c51), /* 15: 1.0e+54 >> 116 */ + UINT64_C(0x86f0ac99b4e8dafd), /* 16: 1.0e+81 >> 206 */ + UINT64_C(0xda01ee641a708de9), /* 17: 1.0e+108 >> 295 */ + UINT64_C(0xb01ae745b101e9e4), /* 18: 1.0e+135 >> 385 */ + UINT64_C(0x8e41ade9fbebc27d), /* 19: 1.0e+162 >> 475 */ + UINT64_C(0xe5d3ef282a242e81), /* 20: 1.0e+189 >> 564 */ + UINT64_C(0xb9a74a0637ce2ee1), /* 21: 1.0e+216 >> 654 */ + UINT64_C(0x95f83d0a1fb69cd9), /* 22: 1.0e+243 >> 744 */ + UINT64_C(0xf24a01a73cf2dccf), /* 23: 1.0e+270 >> 833 */ + UINT64_C(0xc3b8358109e84f07), /* 24: 1.0e+297 >> 923 */ + UINT64_C(0x9e19db92b4e31ba9), /* 25: 1.0e+324 >> 1013 */ + }; + static const unsigned int aScaleLo[] = { + 0x205b896d, /* 0: 1.0e-351 << 1229 */ + 0x52064cad, /* 1: 1.0e-324 << 1140 */ + 0xaf2af2b8, /* 2: 1.0e-297 << 1050 */ + 0x5a7744a7, /* 3: 1.0e-270 << 960 */ + 0xaf39a475, /* 4: 1.0e-243 << 871 */ + 0xbd8d794e, /* 5: 1.0e-216 << 781 */ + 0x547eb47b, /* 6: 1.0e-189 << 691 */ + 0x0cb4a5a3, /* 7: 1.0e-162 << 602 */ + 0x92f34d62, /* 8: 1.0e-135 << 512 */ + 0x3a6a07f9, /* 9: 1.0e-108 << 422 */ + 0xfae27299, /* 10: 1.0e-81 << 333 */ + 0xaa97e14c, /* 11: 1.0e-54 << 243 */ + 0x775ea265, /* 12: 1.0e-27 << 153 */ + 0xcccccccc, /* 13: 1.0e-1 << 67 (special case) */ + 0x00000000, /* 14: 1.0e+27 >> 26 */ + 0x999090b6, /* 15: 1.0e+54 >> 116 */ + 0x69a028bb, /* 16: 1.0e+81 >> 206 */ + 0xe80e6f48, /* 17: 1.0e+108 >> 295 */ + 0x5ec05dd0, /* 18: 1.0e+135 >> 385 */ + 0x14588f14, /* 19: 1.0e+162 >> 475 */ + 0x8f1668c9, /* 20: 1.0e+189 >> 564 */ + 0x6d953e2c, /* 21: 1.0e+216 >> 654 */ + 0x4abdaf10, /* 22: 1.0e+243 >> 744 */ + 0xbc633b39, /* 23: 1.0e+270 >> 833 */ + 0x0a862f81, /* 24: 1.0e+297 >> 923 */ + 0x6c07a2c2, /* 25: 1.0e+324 >> 1013 */ + }; + int g, n; + u64 s, x; + u32 lo; + + assert( p>=POWERSOF10_FIRST && p<=POWERSOF10_LAST ); + if( p<0 ){ + if( p==(-1) ){ + *pLo = aScaleLo[13]; + return aScale[13]; + } + g = p/27; + n = p%27; + if( n ){ + g--; + n += 27; + } + }else if( p<27 ){ + *pLo = 0; + return aBase[p]; + }else{ + g = p/27; + n = p%27; + } + s = aScale[g+13]; + if( n==0 ){ + *pLo = aScaleLo[g+13]; + return s; + } + x = sqlite3Multiply160(s,aScaleLo[g+13],aBase[n],&lo); + if( (U64_BIT(63) & x)==0 ){ + x = x<<1 | ((lo>>31)&1); + lo = (lo<<1) | 1; + } + *pLo = lo; + return x; +} + +/* +** pow10to2(x) computes floor(log2(pow(10,x))). +** pow2to10(y) computes floor(log10(pow(2,y))). +** +** Conceptually, pow10to2(p) converts a base-10 exponent p into +** a corresponding base-2 exponent, and pow2to10(e) converts a base-2 +** exponent into a base-10 exponent. +** +** The conversions are based on the observation that: +** +** ln(10.0)/ln(2.0) == 108853/32768 (approximately) +** ln(2.0)/ln(10.0) == 78913/262144 (approximately) +** +** These ratios are approximate, but they are accurate to 5 digits, +** which is close enough for the usage here. Right-shift is used +** for division so that rounding of negative numbers happens in the +** right direction. +*/ +static int pwr10to2(int p){ return (p*108853) >> 15; } +static int pwr2to10(int p){ return (p*78913) >> 18; } + +/* +** Count leading zeros for a 64-bit unsigned integer. +*/ +static int countLeadingZeros(u64 m){ +#if (defined(__GNUC__) || defined(__clang__)) \ + && !defined(SQLITE_DISABLE_INTRINSIC) + return __builtin_clzll(m); +#else + int n = 0; + if( m <= 0x00000000ffffffffULL) { n += 32; m <<= 32; } + if( m <= 0x0000ffffffffffffULL) { n += 16; m <<= 16; } + if( m <= 0x00ffffffffffffffULL) { n += 8; m <<= 8; } + if( m <= 0x0fffffffffffffffULL) { n += 4; m <<= 4; } + if( m <= 0x3fffffffffffffffULL) { n += 2; m <<= 2; } + if( m <= 0x7fffffffffffffffULL) { n += 1; } + return n; +#endif +} + +/* +** Given m and e, which represent a quantity r == m*pow(2,e), +** return values *pD and *pP such that r == (*pD)*pow(10,*pP), +** approximately. *pD should contain at least n significant digits. +** +** The input m is required to have its highest bit set. In other words, +** m should be left-shifted, and e decremented, to maximize the value of m. +*/ +static void sqlite3Fp2Convert10(u64 m, int e, int n, u64 *pD, int *pP){ + int p; + u64 h, d1; + u32 d2; + assert( n>=1 && n<=18 ); + p = n - 1 - pwr2to10(e+63); + h = sqlite3Multiply128(m, powerOfTen(p,&d2), &d1); + assert( -(e + pwr10to2(p) + 2) >= 0 ); + assert( -(e + pwr10to2(p) + 1) <= 63 ); + if( n==18 ){ + h >>= -(e + pwr10to2(p) + 2); + *pD = (h + ((h<<1)&2))>>1; + }else{ + *pD = h >> -(e + pwr10to2(p) + 1); + } + *pP = -p; +} + +/* +** Return an IEEE754 floating point value that approximates d*pow(10,p). +** +** The (current) algorithm is adapted from the work of Ross Cox at +** https://github.com/rsc/fpfmt +*/ +static double sqlite3Fp10Convert2(u64 d, int p){ + int b, lp, e, adj, s; + u32 pwr10l, mid1; + u64 pwr10h, x, hi, lo, sticky, u, m; + double r; + if( pPOWERSOF10_LAST ) return INFINITY; + b = 64 - countLeadingZeros(d); + lp = pwr10to2(p); + e = 53 - b - lp; + if( e > 1074 ){ + if( e>=1130 ) return 0.0; + e = 1074; + } + s = -(e-(64-b) + lp + 3); + pwr10h = powerOfTen(p, &pwr10l); + if( pwr10l!=0 ){ + pwr10h++; + pwr10l = ~pwr10l; + } + x = d<<(64-b); + hi = sqlite3Multiply128(x,pwr10h,&lo); + mid1 = lo>>32; + sticky = 1; + if( (hi & (U64_BIT(s)-1))==0 ) { + u32 mid2 = sqlite3Multiply128(x,((u64)pwr10l)<<32,&lo)>>32; + sticky = (mid1-mid2 > 1); + hi -= mid1 < mid2; + } + u = (hi>>s) | sticky; + adj = (u >= U64_BIT(55)-2); + if( adj ){ + u = (u>>adj) | (u&1); + e -= adj; + } + m = (u + 1 + ((u>>2)&1)) >> 2; + if( e<=(-972) ) return INFINITY; + if((m & U64_BIT(52)) != 0){ + m = (m & ~U64_BIT(52)) | ((u64)(1075-e)<<52); + } + memcpy(&r,&m,8); + return r; +} + +/* +** The string z[] is an text representation of a real number. +** Convert this string to a double and write it into *pResult. +** +** z[] must be UTF-8 and zero-terminated. +** +** Return positive if the result is a valid real number (or integer) and +** zero or negative if the string is empty or contains extraneous text. +** Lower bits of the return value contain addition information about the +** parse: +** +** bit 0 => Set if any prefix of the input is valid. Clear if +** there is no prefix of the input that can be seen as +** a valid floating point number. +** bit 1 => Set if the input contains a decimal point or eNNN +** clause. Zero if the input is an integer. +** bit 2 => The input is exactly 0.0, not an underflow from +** some value near zero. +** bit 3 => Set if there are more than about 19 significant +** digits in the input. +** +** If the input contains a syntax error but begins with text that might +** be a valid number of some kind, then the result is negative. The +** result is only zero if no prefix of the input could be interpreted as +** a number. +** +** Leading and trailing whitespace is ignored. Valid numbers are in +** one of the formats below: +** +** [+-]digits[E[+-]digits] +** [+-]digits.[digits][E[+-]digits] +** [+-].digits[E[+-]digits] +** +** Algorithm sketch: Compute an unsigned 64-bit integer s and a base-10 +** exponent d such that the value encoding by the input is s*pow(10,d). +** Then invoke sqlite3Fp10Convert2() to calculated the closest possible +** IEEE754 double. The sign is added back afterwards, if the input string +** starts with a "-". The use of an unsigned 64-bit s mantissa means that +** only about the first 19 significant digits of the input can contribute +** to the result. This can result in suboptimal rounding decisions when +** correct rounding requires more than 19 input digits. For example, +** this routine renders "3500000000000000.2500001" as +** 3500000000000000.0 instead of 3500000000000000.5 because the decision +** to round up instead of using banker's rounding to round down is determined +** by the 23rd significant digit, which this routine ignores. It is not +** possible to do better without some kind of BigNum. +*/ +SQLITE_PRIVATE int sqlite3AtoF(const char *zIn, double *pResult){ +#ifndef SQLITE_OMIT_FLOATING_POINT + const unsigned char *z = (const unsigned char*)zIn; + int neg = 0; /* True for a negative value */ + u64 s = 0; /* mantissa */ + int d = 0; /* Value is s * pow(10,d) */ + int mState = 0; /* 1: digit seen 2: fp 4: hard-zero */ + unsigned v; /* Value of a single digit */ + + start_of_text: + if( (v = (unsigned)z[0] - '0')<10 ){ + parse_integer_part: + mState = 1; + s = v; + z++; + while( (v = (unsigned)z[0] - '0')<10 ){ + s = s*10 + v; + z++; + if( s>=(LARGEST_UINT64-9)/10 ){ + mState = 9; + while( sqlite3Isdigit(z[0]) ){ z++; d++; } + break; + } + } + }else if( z[0]=='-' ){ + neg = 1; + z++; + if( (v = (unsigned)z[0] - '0')<10 ) goto parse_integer_part; + }else if( z[0]=='+' ){ + z++; + if( (v = (unsigned)z[0] - '0')<10 ) goto parse_integer_part; + }else if( sqlite3Isspace(z[0]) ){ + do{ z++; }while( sqlite3Isspace(z[0]) ); + goto start_of_text; + }else{ + s = 0; + } + + /* if decimal point is present */ + if( *z=='.' ){ + z++; + if( sqlite3Isdigit(z[0]) ){ + mState |= 1; + do{ + if( s<(LARGEST_UINT64-9)/10 ){ + s = s*10 + z[0] - '0'; + d--; + }else{ + mState = 11; + } + }while( sqlite3Isdigit(*++z) ); + }else if( mState==0 ){ + *pResult = 0.0; + return 0; + } + mState |= 2; + }else if( mState==0 ){ + *pResult = 0.0; + return 0; + } + + /* if exponent is present */ + if( *z=='e' || *z=='E' ){ + int esign; + z++; + + /* get sign of exponent */ + if( *z=='-' ){ + esign = -1; + z++; + }else{ + esign = +1; + if( *z=='+' ){ + z++; + } + } + /* copy digits to exponent */ + if( (v = (unsigned)z[0] - '0')<10 ){ + int exp = v; + z++; + mState |= 2; + while( (v = (unsigned)z[0] - '0')<10 ){ + exp = exp<10000 ? (exp*10 + v) : 10000; + z++; + } + d += esign*exp; + }else{ + z--; /* Leave z[0] at 'e' or '+' or '-', + ** so that the return is 0 or -1 */ + } + } + + /* Convert s*pow(10,d) into real */ + if( s==0 ){ + *pResult = 0.0; + mState |= 4; + }else{ + *pResult = sqlite3Fp10Convert2(s,d); + } + if( neg ) *pResult = -*pResult; + assert( !sqlite3IsNaN(*pResult) ); + + /* return true if number and no extra non-whitespace characters after */ + if( z[0]==0 ){ + return mState; + } + if( sqlite3Isspace(z[0]) ){ + do{ z++; }while( sqlite3Isspace(*z) ); + if( z[0]==0 ){ + return mState; + } + } + return 0xfffffff0 | mState; +#else + return sqlite3Atoi64(z, pResult, strlen(z), SQLITE_UTF8)==0; +#endif /* SQLITE_OMIT_FLOATING_POINT */ +} + +/* +** Digit pairs used to convert a U64 or I64 into text, two digits +** at a time. +*/ +static const union { + char a[201]; + short int forceAlignment; +} sqlite3DigitPairs = { + "00010203040506070809" + "10111213141516171819" + "20212223242526272829" + "30313233343536373839" + "40414243444546474849" + "50515253545556575859" + "60616263646566676869" + "70717273747576777879" + "80818283848586878889" + "90919293949596979899" +}; + +/* +** ARMv6, ARMv7, PPC32 are known to not support hardware u64 division. +*/ +#if (defined(__arm__) && !defined(__aarch64__)) || \ + (defined(__ppc__) && !defined(__ppc64__)) +# define SQLITE_AVOID_U64_DIVIDE 1 +#endif + +#ifdef SQLITE_AVOID_U64_DIVIDE +/* +** Render an unsigned 64-bit integer as text onto the end of a 2-byte +** aligned buffer that is SQLITE_U64_DIGIT+1 bytes long. The last byte +** of the buffer will be filled with a \000 byte. +** +** Return the index into the buffer of the first byte. +** +** This routine is used on platforms where u64-division is slow because +** it is not available in hardware and has to be emulated in software. +** It seeks to minimize the number of u64 divisions and use u32 divisions +** instead. It is slower on platforms that have hardware u64 division, +** but much faster on platforms that do not. +*/ +static int sqlite3UInt64ToText(u64 v, char *zOut){ + u32 x32, kk; + int i; + zOut[SQLITE_U64_DIGITS] = 0; + i = SQLITE_U64_DIGITS; + assert( TWO_BYTE_ALIGNMENT(&sqlite3DigitPairs.a[0]) ); + assert( TWO_BYTE_ALIGNMENT(zOut) ); + while( (v>>32)!=0 ){ + u32 y, x0, x1, y0, y1; + x32 = v % 100000000; + v = v / 100000000; + y = x32 % 10000; + x32 /= 10000; + x1 = x32 / 100; + x0 = x32 % 100; + y1 = y / 100; + y0 = y % 100; + assert( i>=8 ); + i -= 8; + *(u16*)(&zOut[i]) = *(u16*)&sqlite3DigitPairs.a[x1*2]; + *(u16*)(&zOut[i+2]) = *(u16*)&sqlite3DigitPairs.a[x0*2]; + *(u16*)(&zOut[i+4]) = *(u16*)&sqlite3DigitPairs.a[y1*2]; + *(u16*)(&zOut[i+6]) = *(u16*)&sqlite3DigitPairs.a[y0*2]; + } + x32 = v; + while( x32>=10 ){ + kk = x32 % 100; + x32 = x32 / 100; + assert( TWO_BYTE_ALIGNMENT(&sqlite3DigitPairs.a[kk*2]) ); + assert( i>=2 ); + i -= 2; + assert( TWO_BYTE_ALIGNMENT(&zOut[i]) ); + *(u16*)(&zOut[i]) = *(u16*)&sqlite3DigitPairs.a[kk*2]; + } + if( x32 ){ + assert( i>0 ); + zOut[--i] = x32 + '0'; + } + return i; +} +#endif /* defined(SQLITE_AVOID_U64_DIVIDE) */ + +/* +** Render an signed 64-bit integer as text. Store the result in zOut[] and +** return the length of the string that was stored, in bytes. The value +** returned does not include the zero terminator at the end of the output +** string. +** +** The caller must ensure that zOut[] is at least 21 bytes in size. +*/ +SQLITE_PRIVATE int sqlite3Int64ToText(i64 v, char *zOut){ + int i; + u64 x; + union { + char a[SQLITE_U64_DIGITS+1]; + u16 forceAlignment; + } u; + if( v>0 ){ + x = v; + }else if( v==0 ){ + zOut[0] = '0'; + zOut[1] = 0; + return 1; + }else{ + x = (v==SMALLEST_INT64) ? ((u64)1)<<63 : (u64)-v; + } +#ifdef SQLITE_AVOID_U64_DIVIDE + i = sqlite3UInt64ToText(x, u.a); +#else + i = sizeof(u.a)-1; + u.a[i] = 0; + while( x>=10 ){ + int kk = (x%100)*2; + assert( TWO_BYTE_ALIGNMENT(&sqlite3DigitPairs.a[kk]) ); + assert( TWO_BYTE_ALIGNMENT(&u.a[i-2]) ); + *(u16*)(&u.a[i-2]) = *(u16*)&sqlite3DigitPairs.a[kk]; + i -= 2; + x /= 100; + } + if( x ){ + u.a[--i] = x + '0'; + } +#endif /* SQLITE_AVOID_U64_DIVIDE */ + if( v<0 ) u.a[--i] = '-'; + memcpy(zOut, &u.a[i], sizeof(u.a)-i); + return sizeof(u.a)-1-i; +} + +/* +** Compare the 19-character string zNum against the text representation +** value 2^63: 9223372036854775808. Return negative, zero, or positive +** if zNum is less than, equal to, or greater than the string. +** Note that zNum must contain exactly 19 characters. +** +** Unlike memcmp() this routine is guaranteed to return the difference +** in the values of the last digit if the only difference is in the +** last digit. So, for example, +** +** compare2pow63("9223372036854775800", 1) +** +** will return -8. +*/ +static int compare2pow63(const char *zNum, int incr){ + int c = 0; + int i; + /* 012345678901234567 */ + const char *pow63 = "922337203685477580"; + for(i=0; c==0 && i<18; i++){ + c = (zNum[i*incr]-pow63[i])*10; + } + if( c==0 ){ + c = zNum[18*incr] - '8'; + testcase( c==(-1) ); + testcase( c==0 ); + testcase( c==(+1) ); + } + return c; +} + +/* +** Convert zNum to a 64-bit signed integer. zNum must be decimal. This +** routine does *not* accept hexadecimal notation. +** +** Returns: +** +** -1 Not even a prefix of the input text looks like an integer +** 0 Successful transformation. Fits in a 64-bit signed integer. +** 1 Excess non-space text after the integer value +** 2 Integer too large for a 64-bit signed integer or is malformed +** 3 Special case of 9223372036854775808 +** +** length is the number of bytes in the string (bytes, not characters). +** The string is not necessarily zero-terminated. The encoding is +** given by enc. +*/ +SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ + int incr; + u64 u = 0; + int neg = 0; /* assume positive */ + int i, j; + unsigned int c = 0; + int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */ + int rc; /* Baseline return code */ + const char *zStart; + const char *zEnd = zNum + length; + assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); + if( enc==SQLITE_UTF8 ){ + incr = 1; + }else{ + incr = 2; + length &= ~1; + assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); + for(i=3-enc; iLARGEST_INT64 ){ + /* This test and assignment is needed only to suppress UB warnings + ** from clang and -fsanitize=undefined. This test and assignment make + ** the code a little larger and slower, and no harm comes from omitting + ** them, but we must appease the undefined-behavior pharisees. */ + *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64; + }else if( neg ){ + *pNum = -(i64)u; + }else{ + *pNum = (i64)u; + } + rc = 0; + if( i==0 && zStart==zNum ){ /* No digits */ + rc = -1; + }else if( nonNum ){ /* UTF16 with high-order bytes non-zero */ + rc = 1; + }else if( &zNum[i]19*incr ? 1 : compare2pow63(zNum, incr); + if( j<0 ){ + /* zNum is less than 9223372036854775808 so it fits */ + assert( u<=LARGEST_INT64 ); + return rc; + }else{ + *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64; + if( j>0 ){ + /* zNum is greater than 9223372036854775808 so it overflows */ + return 2; + }else{ + /* zNum is exactly 9223372036854775808. Fits if negative. The + ** special case 2 overflow if positive */ + assert( u-1==LARGEST_INT64 ); + return neg ? rc : 3; + } + } + } +} + +/* +** Transform a UTF-8 integer literal, in either decimal or hexadecimal, +** into a 64-bit signed integer. This routine accepts hexadecimal literals, +** whereas sqlite3Atoi64() does not. +** +** Returns: +** +** 0 Successful transformation. Fits in a 64-bit signed integer. +** 1 Excess text after the integer value +** 2 Integer too large for a 64-bit signed integer or is malformed +** 3 Special case of 9223372036854775808 +*/ +SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char *z, i64 *pOut){ +#ifndef SQLITE_OMIT_HEX_INTEGER + if( z[0]=='0' + && (z[1]=='x' || z[1]=='X') + ){ + u64 u = 0; + int i, k; + for(i=2; z[i]=='0'; i++){} + for(k=i; sqlite3Isxdigit(z[k]); k++){ + u = u*16 + sqlite3HexToInt(z[k]); + } + memcpy(pOut, &u, 8); + if( k-i>16 ) return 2; + if( z[k]!=0 ) return 1; + return 0; + }else +#endif /* SQLITE_OMIT_HEX_INTEGER */ + { + int n = (int)(0x3fffffff&strspn(z,"+- \n\t0123456789")); + if( z[n] ) n++; + return sqlite3Atoi64(z, pOut, n, SQLITE_UTF8); + } +} + +/* +** If zNum represents an integer that will fit in 32-bits, then set +** *pValue to that integer and return true. Otherwise return false. +** +** This routine accepts both decimal and hexadecimal notation for integers. +** +** Any non-numeric characters that following zNum are ignored. +** This is different from sqlite3Atoi64() which requires the +** input number to be zero-terminated. +*/ +SQLITE_PRIVATE int sqlite3GetInt32(const char *zNum, int *pValue){ + sqlite_int64 v = 0; + int i, c; + int neg = 0; + if( zNum[0]=='-' ){ + neg = 1; + zNum++; + }else if( zNum[0]=='+' ){ + zNum++; + } +#ifndef SQLITE_OMIT_HEX_INTEGER + else if( zNum[0]=='0' + && (zNum[1]=='x' || zNum[1]=='X') + && sqlite3Isxdigit(zNum[2]) + ){ + u32 u = 0; + zNum += 2; + while( zNum[0]=='0' ) zNum++; + for(i=0; i<8 && sqlite3Isxdigit(zNum[i]); i++){ + u = u*16 + sqlite3HexToInt(zNum[i]); + } + if( (u&0x80000000)==0 && sqlite3Isxdigit(zNum[i])==0 ){ + memcpy(pValue, &u, 4); + return 1; + }else{ + return 0; + } + } +#endif + if( !sqlite3Isdigit(zNum[0]) ) return 0; + while( zNum[0]=='0' ) zNum++; + for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){ + v = v*10 + c; + } + + /* The longest decimal representation of a 32 bit integer is 10 digits: + ** + ** 1234567890 + ** 2^31 -> 2147483648 + */ + testcase( i==10 ); + if( i>10 ){ + return 0; + } + testcase( v-neg==2147483647 ); + if( v-neg>2147483647 ){ + return 0; + } + if( neg ){ + v = -v; + } + *pValue = (int)v; + return 1; +} + +/* +** Return a 32-bit integer value extracted from a string. If the +** string is not an integer, just return 0. +*/ +SQLITE_PRIVATE int sqlite3Atoi(const char *z){ + int x = 0; + sqlite3GetInt32(z, &x); + return x; +} + +/* +** Decode a floating-point value into an approximate decimal +** representation. +** +** If iRound<=0 then round to -iRound significant digits to the +** the right of the decimal point, or to a maximum of mxRound total +** significant digits. +** +** If iRound>0 round to min(iRound,mxRound) significant digits total. +** +** mxRound must be positive. +** +** The significant digits of the decimal representation are +** stored in p->z[] which is a often (but not always) a pointer +** into the middle of p->zBuf[]. There are p->n significant digits. +** The p->z[] array is *not* zero-terminated. +*/ +SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRound){ + int i; /* Index into zBuf[] where to put next character */ + int n; /* Number of digits */ + u64 v; /* mantissa */ + int e, exp = 0; /* Base-2 and base-10 exponent */ + char *zBuf; /* Local alias for p->zBuf */ + char *z; /* Local alias for p->z */ + + p->isSpecial = 0; + assert( mxRound>0 ); + + /* Convert negative numbers to positive. Deal with Infinity, 0.0, and + ** NaN. */ + if( r<0.0 ){ + p->sign = '-'; + r = -r; + }else if( r==0.0 ){ + p->sign = '+'; + p->n = 1; + p->iDP = 1; + p->z = "0"; + return; + }else{ + p->sign = '+'; + } + memcpy(&v,&r,8); + e = (v>>52)&0x7ff; + if( e==0x7ff ){ + p->isSpecial = 1 + (v!=0x7ff0000000000000LL); + p->n = 0; + p->iDP = 0; + p->z = p->zBuf; + return; + } + v &= 0x000fffffffffffffULL; + if( e==0 ){ + int nn = countLeadingZeros(v); + v <<= nn; + e = -1074 - nn; + }else{ + v = (v<<11) | U64_BIT(63); + e -= 1086; + } + sqlite3Fp2Convert10(v, e, (iRound<=0||iRound>=18)?18:iRound+1, &v, &exp); + + /* Extract significant digits, start at the right-most slot in p->zBuf + ** and working back to the right. "i" keeps track of the next slot in + ** which to store a digit. */ + assert( sizeof(p->zBuf)==SQLITE_U64_DIGITS+1 ); + assert( v>0 ); + zBuf = p->zBuf; +#ifdef SQLITE_AVOID_U64_DIVIDE + i = sqlite3UInt64ToText(v, zBuf); +#else + i = SQLITE_U64_DIGITS; + while( v>=10 ){ + int kk = (v%100)*2; + assert( TWO_BYTE_ALIGNMENT(&sqlite3DigitPairs.a[kk]) ); + assert( TWO_BYTE_ALIGNMENT(&zBuf[i]) ); + assert( i-2>=0 ); + *(u16*)(&zBuf[i-2]) = *(u16*)&sqlite3DigitPairs.a[kk]; + i -= 2; + v /= 100; + } + if( v ){ + assert( v<10 ); + assert( i>0 ); + zBuf[--i] = v + '0'; + } +#endif /* SQLITE_AVOID_U64_DIVIDE */ + assert( i>=0 && i0 ); + assert( n<=SQLITE_U64_DIGITS ); + p->iDP = n + exp; + if( iRound<=0 ){ + iRound = p->iDP - iRound; + if( iRound==0 && zBuf[i]>='5' ){ + iRound = 1; + zBuf[--i] = '0'; + n++; + p->iDP++; + } + } + z = &zBuf[i]; /* z points to the first digit */ + if( iRound>0 && (iRoundmxRound) ){ + if( iRound>mxRound ) iRound = mxRound; + if( iRound==17 ){ + /* If the precision is exactly 17, which only happens with the "!" + ** flag (ex: "%!.17g") then try to reduce the precision if that + ** yields text that will round-trip to the original floating-point. + ** value. Thus, for exaple, 49.47 will render as 49.47, rather than + ** as 49.469999999999999. */ + if( z[15]=='9' && z[14]=='9' ){ + int jj, kk; + u64 v2; + for(jj=14; jj>0 && z[jj-1]=='9'; jj--){} + if( jj==0 ){ + v2 = 1; + }else{ + v2 = z[0] - '0'; + for(kk=1; kkiDP>=n || (z[15]=='0' && z[14]=='0' && z[13]=='0') ){ + int jj, kk; + u64 v2; + assert( z[0]!='0' ); + for(jj=13; z[jj-1]=='0'; jj--){} + v2 = z[0] - '0'; + for(kk=1; kk='5' ){ + int j = iRound-1; + while( 1 /*exit-by-break*/ ){ + z[j]++; + if( z[j]<='9' ) break; + z[j] = '0'; + if( j==0 ){ + z--; + z[0] = '1'; + n++; + p->iDP++; + break; + }else{ + j--; + } + } + } + } + assert( n>0 ); + while( z[n-1]=='0' ){ + n--; + assert( n>0 ); + } + p->n = n; + p->z = z; +} + +/* +** Try to convert z into an unsigned 32-bit integer. Return true on +** success and false if there is an error. +** +** Only decimal notation is accepted. +*/ +SQLITE_PRIVATE int sqlite3GetUInt32(const char *z, u32 *pI){ + u64 v = 0; + int i; + for(i=0; sqlite3Isdigit(z[i]); i++){ + v = v*10 + z[i] - '0'; + if( v>4294967296LL ){ *pI = 0; return 0; } + } + if( i==0 || z[i]!=0 ){ *pI = 0; return 0; } + *pI = (u32)v; + return 1; +} + +/* +** The variable-length integer encoding is as follows: +** +** KEY: +** A = 0xxxxxxx 7 bits of data and one flag bit +** B = 1xxxxxxx 7 bits of data and one flag bit +** C = xxxxxxxx 8 bits of data +** +** 7 bits - A +** 14 bits - BA +** 21 bits - BBA +** 28 bits - BBBA +** 35 bits - BBBBA +** 42 bits - BBBBBA +** 49 bits - BBBBBBA +** 56 bits - BBBBBBBA +** 64 bits - BBBBBBBBC +*/ + +/* +** Write a 64-bit variable-length integer to memory starting at p[0]. +** The length of data write will be between 1 and 9 bytes. The number +** of bytes written is returned. +** +** A variable-length integer consists of the lower 7 bits of each byte +** for all bytes that have the 8th bit set and one byte with the 8th +** bit clear. Except, if we get to the 9th byte, it stores the full +** 8 bits and is the last byte. +*/ +static int SQLITE_NOINLINE putVarint64(unsigned char *p, u64 v){ + int i, j, n; + u8 buf[10]; + if( v & (((u64)0xff000000)<<32) ){ + p[8] = (u8)v; + v >>= 8; + for(i=7; i>=0; i--){ + p[i] = (u8)((v & 0x7f) | 0x80); + v >>= 7; + } + return 9; + } + n = 0; + do{ + buf[n++] = (u8)((v & 0x7f) | 0x80); + v >>= 7; + }while( v!=0 ); + buf[0] &= 0x7f; + assert( n<=9 ); + for(i=0, j=n-1; j>=0; j--, i++){ + p[i] = buf[j]; + } + return n; +} +SQLITE_PRIVATE int sqlite3PutVarint(unsigned char *p, u64 v){ + if( v<=0x7f ){ + p[0] = v&0x7f; + return 1; + } + if( v<=0x3fff ){ + p[0] = ((v>>7)&0x7f)|0x80; + p[1] = v&0x7f; + return 2; + } + return putVarint64(p,v); +} + +/* +** Bitmasks used by sqlite3GetVarint(). These precomputed constants +** are defined here rather than simply putting the constant expressions +** inline in order to work around bugs in the RVT compiler. +** +** SLOT_2_0 A mask for (0x7f<<14) | 0x7f +** +** SLOT_4_2_0 A mask for (0x7f<<28) | SLOT_2_0 +*/ +#define SLOT_2_0 0x001fc07f +#define SLOT_4_2_0 0xf01fc07f + + +/* +** Read a 64-bit variable-length integer from memory starting at p[0]. +** Return the number of bytes read. The value is stored in *v. +*/ +SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *p, u64 *v){ + u32 a,b,s; + + if( ((signed char*)p)[0]>=0 ){ + *v = *p; + return 1; + } + if( ((signed char*)p)[1]>=0 ){ + *v = ((u32)(p[0]&0x7f)<<7) | p[1]; + return 2; + } + + /* Verify that constants are precomputed correctly */ + assert( SLOT_2_0 == ((0x7f<<14) | (0x7f)) ); + assert( SLOT_4_2_0 == ((0xfU<<28) | (0x7f<<14) | (0x7f)) ); + + a = ((u32)p[0])<<14; + b = p[1]; + p += 2; + a |= *p; + /* a: p0<<14 | p2 (unmasked) */ + if (!(a&0x80)) + { + a &= SLOT_2_0; + b &= 0x7f; + b = b<<7; + a |= b; + *v = a; + return 3; + } + + /* CSE1 from below */ + a &= SLOT_2_0; + p++; + b = b<<14; + b |= *p; + /* b: p1<<14 | p3 (unmasked) */ + if (!(b&0x80)) + { + b &= SLOT_2_0; + /* moved CSE1 up */ + /* a &= (0x7f<<14)|(0x7f); */ + a = a<<7; + a |= b; + *v = a; + return 4; + } + + /* a: p0<<14 | p2 (masked) */ + /* b: p1<<14 | p3 (unmasked) */ + /* 1:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ + /* moved CSE1 up */ + /* a &= (0x7f<<14)|(0x7f); */ + b &= SLOT_2_0; + s = a; + /* s: p0<<14 | p2 (masked) */ + + p++; + a = a<<14; + a |= *p; + /* a: p0<<28 | p2<<14 | p4 (unmasked) */ + if (!(a&0x80)) + { + /* we can skip these cause they were (effectively) done above + ** while calculating s */ + /* a &= (0x7f<<28)|(0x7f<<14)|(0x7f); */ + /* b &= (0x7f<<14)|(0x7f); */ + b = b<<7; + a |= b; + s = s>>18; + *v = ((u64)s)<<32 | a; + return 5; + } + + /* 2:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ + s = s<<7; + s |= b; + /* s: p0<<21 | p1<<14 | p2<<7 | p3 (masked) */ + + p++; + b = b<<14; + b |= *p; + /* b: p1<<28 | p3<<14 | p5 (unmasked) */ + if (!(b&0x80)) + { + /* we can skip this cause it was (effectively) done above in calc'ing s */ + /* b &= (0x7f<<28)|(0x7f<<14)|(0x7f); */ + a &= SLOT_2_0; + a = a<<7; + a |= b; + s = s>>18; + *v = ((u64)s)<<32 | a; + return 6; + } + + p++; + a = a<<14; + a |= *p; + /* a: p2<<28 | p4<<14 | p6 (unmasked) */ + if (!(a&0x80)) + { + a &= SLOT_4_2_0; + b &= SLOT_2_0; + b = b<<7; + a |= b; + s = s>>11; + *v = ((u64)s)<<32 | a; + return 7; + } + + /* CSE2 from below */ + a &= SLOT_2_0; + p++; + b = b<<14; + b |= *p; + /* b: p3<<28 | p5<<14 | p7 (unmasked) */ + if (!(b&0x80)) + { + b &= SLOT_4_2_0; + /* moved CSE2 up */ + /* a &= (0x7f<<14)|(0x7f); */ + a = a<<7; + a |= b; + s = s>>4; + *v = ((u64)s)<<32 | a; + return 8; + } + + p++; + a = a<<15; + a |= *p; + /* a: p4<<29 | p6<<15 | p8 (unmasked) */ + + /* moved CSE2 up */ + /* a &= (0x7f<<29)|(0x7f<<15)|(0xff); */ + b &= SLOT_2_0; + b = b<<8; + a |= b; + + s = s<<4; + b = p[-4]; + b &= 0x7f; + b = b>>3; + s |= b; + + *v = ((u64)s)<<32 | a; + + return 9; +} + +/* +** Read a 32-bit variable-length integer from memory starting at p[0]. +** Return the number of bytes read. The value is stored in *v. +** +** If the varint stored in p[0] is larger than can fit in a 32-bit unsigned +** integer, then set *v to 0xffffffff. +** +** A MACRO version, getVarint32, is provided which inlines the +** single-byte case. All code should use the MACRO version as +** this function assumes the single-byte case has already been handled. +*/ +SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *p, u32 *v){ + u64 v64; + u8 n; + + /* Assume that the single-byte case has already been handled by + ** the getVarint32() macro */ + assert( (p[0] & 0x80)!=0 ); + + if( (p[1] & 0x80)==0 ){ + /* This is the two-byte case */ + *v = ((p[0]&0x7f)<<7) | p[1]; + return 2; + } + if( (p[2] & 0x80)==0 ){ + /* This is the three-byte case */ + *v = ((p[0]&0x7f)<<14) | ((p[1]&0x7f)<<7) | p[2]; + return 3; + } + /* four or more bytes */ + n = sqlite3GetVarint(p, &v64); + assert( n>3 && n<=9 ); + if( (v64 & SQLITE_MAX_U32)!=v64 ){ + *v = 0xffffffff; + }else{ + *v = (u32)v64; + } + return n; +} + +/* +** Return the number of bytes that will be needed to store the given +** 64-bit integer. +*/ +SQLITE_PRIVATE int sqlite3VarintLen(u64 v){ + int i; + for(i=1; (v >>= 7)!=0; i++){ assert( i<10 ); } + return i; +} + + +/* +** Read or write a four-byte big-endian integer value. +*/ +SQLITE_PRIVATE u32 sqlite3Get4byte(const u8 *p){ +#if SQLITE_BYTEORDER==4321 + u32 x; + memcpy(&x,p,4); + return x; +#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 + u32 x; + memcpy(&x,p,4); + return __builtin_bswap32(x); +#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 + u32 x; + memcpy(&x,p,4); + return _byteswap_ulong(x); +#else + testcase( p[0]&0x80 ); + return ((unsigned)p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3]; +#endif +} +SQLITE_PRIVATE void sqlite3Put4byte(unsigned char *p, u32 v){ +#if SQLITE_BYTEORDER==4321 + memcpy(p,&v,4); +#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 + u32 x = __builtin_bswap32(v); + memcpy(p,&x,4); +#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 + u32 x = _byteswap_ulong(v); + memcpy(p,&x,4); +#else + p[0] = (u8)(v>>24); + p[1] = (u8)(v>>16); + p[2] = (u8)(v>>8); + p[3] = (u8)v; +#endif +} + + + +/* +** Translate a single byte of Hex into an integer. +** This routine only works if h really is a valid hexadecimal +** character: 0..9a..fA..F +*/ +SQLITE_PRIVATE u8 sqlite3HexToInt(int h){ + assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') ); +#ifdef SQLITE_ASCII + h += 9*(1&(h>>6)); +#endif +#ifdef SQLITE_EBCDIC + h += 9*(1&~(h>>4)); +#endif + return (u8)(h & 0xf); +} + +#if !defined(SQLITE_OMIT_BLOB_LITERAL) +/* +** Convert a BLOB literal of the form "x'hhhhhh'" into its binary +** value. Return a pointer to its binary value. Space to hold the +** binary value has been obtained from malloc and must be freed by +** the calling routine. +*/ +SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){ + char *zBlob; + int i; + + zBlob = (char *)sqlite3DbMallocRawNN(db, n/2 + 1); + n--; + if( zBlob ){ + for(i=0; ieOpenState; + if( eOpenState!=SQLITE_STATE_OPEN ){ + if( sqlite3SafetyCheckSickOrOk(db) ){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + logBadConnection("unopened"); + } + return 0; + }else{ + return 1; + } +} +SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3 *db){ + u8 eOpenState; + eOpenState = db->eOpenState; + if( eOpenState!=SQLITE_STATE_SICK && + eOpenState!=SQLITE_STATE_OPEN && + eOpenState!=SQLITE_STATE_BUSY ){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + logBadConnection("invalid"); + return 0; + }else{ + return 1; + } +} + +/* +** Attempt to add, subtract, or multiply the 64-bit signed value iB against +** the other 64-bit signed integer at *pA and store the result in *pA. +** Return 0 on success. Or if the operation would have resulted in an +** overflow, leave *pA unchanged and return 1. +*/ +SQLITE_PRIVATE int sqlite3AddInt64(i64 *pA, i64 iB){ +#if GCC_VERSION>=5004000 && !defined(__INTEL_COMPILER) + return __builtin_add_overflow(*pA, iB, pA); +#else + i64 iA = *pA; + testcase( iA==0 ); testcase( iA==1 ); + testcase( iB==-1 ); testcase( iB==0 ); + if( iB>=0 ){ + testcase( iA>0 && LARGEST_INT64 - iA == iB ); + testcase( iA>0 && LARGEST_INT64 - iA == iB - 1 ); + if( iA>0 && LARGEST_INT64 - iA < iB ) return 1; + }else{ + testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 1 ); + testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 2 ); + if( iA<0 && -(iA + LARGEST_INT64) > iB + 1 ) return 1; + } + *pA += iB; + return 0; +#endif +} +SQLITE_PRIVATE int sqlite3SubInt64(i64 *pA, i64 iB){ +#if GCC_VERSION>=5004000 && !defined(__INTEL_COMPILER) + return __builtin_sub_overflow(*pA, iB, pA); +#else + testcase( iB==SMALLEST_INT64+1 ); + if( iB==SMALLEST_INT64 ){ + testcase( (*pA)==(-1) ); testcase( (*pA)==0 ); + if( (*pA)>=0 ) return 1; + *pA -= iB; + return 0; + }else{ + return sqlite3AddInt64(pA, -iB); + } +#endif +} +SQLITE_PRIVATE int sqlite3MulInt64(i64 *pA, i64 iB){ +#if GCC_VERSION>=5004000 && !defined(__INTEL_COMPILER) + return __builtin_mul_overflow(*pA, iB, pA); +#else + i64 iA = *pA; + if( iB>0 ){ + if( iA>LARGEST_INT64/iB ) return 1; + if( iA0 ){ + if( iBLARGEST_INT64/-iB ) return 1; + } + } + *pA = iA*iB; + return 0; +#endif +} + +/* +** Compute the absolute value of a 32-bit signed integer, if possible. Or +** if the integer has a value of -2147483648, return +2147483647 +*/ +SQLITE_PRIVATE int sqlite3AbsInt32(int x){ + if( x>=0 ) return x; + if( x==(int)0x80000000 ) return 0x7fffffff; + return -x; +} + +#ifdef SQLITE_ENABLE_8_3_NAMES +/* +** If SQLITE_ENABLE_8_3_NAMES is set at compile-time and if the database +** filename in zBaseFilename is a URI with the "8_3_names=1" parameter and +** if filename in z[] has a suffix (a.k.a. "extension") that is longer than +** three characters, then shorten the suffix on z[] to be the last three +** characters of the original suffix. +** +** If SQLITE_ENABLE_8_3_NAMES is set to 2 at compile-time, then always +** do the suffix shortening regardless of URI parameter. +** +** Examples: +** +** test.db-journal => test.nal +** test.db-wal => test.wal +** test.db-shm => test.shm +** test.db-mj7f3319fa => test.9fa +*/ +SQLITE_PRIVATE void sqlite3FileSuffix3(const char *zBaseFilename, char *z){ +#if SQLITE_ENABLE_8_3_NAMES<2 + if( sqlite3_uri_boolean(zBaseFilename, "8_3_names", 0) ) +#endif + { + int i, sz; + sz = sqlite3Strlen30(z); + for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){} + if( z[i]=='.' && ALWAYS(sz>i+4) ) memmove(&z[i+1], &z[sz-3], 4); + } +} +#endif + +/* +** Find (an approximate) sum of two LogEst values. This computation is +** not a simple "+" operator because LogEst is stored as a logarithmic +** value. +** +*/ +SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst a, LogEst b){ + static const unsigned char x[] = { + 10, 10, /* 0,1 */ + 9, 9, /* 2,3 */ + 8, 8, /* 4,5 */ + 7, 7, 7, /* 6,7,8 */ + 6, 6, 6, /* 9,10,11 */ + 5, 5, 5, /* 12-14 */ + 4, 4, 4, 4, /* 15-18 */ + 3, 3, 3, 3, 3, 3, /* 19-24 */ + 2, 2, 2, 2, 2, 2, 2, /* 25-31 */ + }; + if( a>=b ){ + if( a>b+49 ) return a; + if( a>b+31 ) return a+1; + return a+x[a-b]; + }else{ + if( b>a+49 ) return b; + if( b>a+31 ) return b+1; + return b+x[b-a]; + } +} + +/* +** Convert an integer into a LogEst. In other words, compute an +** approximation for 10*log2(x). +*/ +SQLITE_PRIVATE LogEst sqlite3LogEst(u64 x){ + static LogEst a[] = { 0, 2, 3, 5, 6, 7, 8, 9 }; + LogEst y = 40; + if( x<8 ){ + if( x<2 ) return 0; + while( x<8 ){ y -= 10; x <<= 1; } + }else{ +#if GCC_VERSION>=5004000 + int i = 60 - __builtin_clzll(x); + y += i*10; + x >>= i; +#else + while( x>255 ){ y += 40; x >>= 4; } /*OPTIMIZATION-IF-TRUE*/ + while( x>15 ){ y += 10; x >>= 1; } +#endif + } + return a[x&7] + y - 10; +} + +/* +** Convert a double into a LogEst +** In other words, compute an approximation for 10*log2(x). +*/ +SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double x){ + u64 a; + LogEst e; + assert( sizeof(x)==8 && sizeof(a)==8 ); + if( x<=1 ) return 0; + if( x<=2000000000 ) return sqlite3LogEst((u64)x); + memcpy(&a, &x, 8); + e = (a>>52) - 1022; + return e*10; +} + +/* +** Convert a LogEst into an integer. +*/ +SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst x){ + u64 n; + n = x%10; + x /= 10; + if( n>=5 ) n -= 2; + else if( n>=1 ) n -= 1; + if( x>60 ) return (u64)LARGEST_INT64; + return x>=3 ? (n+8)<<(x-3) : (n+8)>>(3-x); +} + +/* +** Add a new name/number pair to a VList. This might require that the +** VList object be reallocated, so return the new VList. If an OOM +** error occurs, the original VList returned and the +** db->mallocFailed flag is set. +** +** A VList is really just an array of integers. To destroy a VList, +** simply pass it to sqlite3DbFree(). +** +** The first integer is the number of integers allocated for the whole +** VList. The second integer is the number of integers actually used. +** Each name/number pair is encoded by subsequent groups of 3 or more +** integers. +** +** Each name/number pair starts with two integers which are the numeric +** value for the pair and the size of the name/number pair, respectively. +** The text name overlays one or more following integers. The text name +** is always zero-terminated. +** +** Conceptually: +** +** struct VList { +** int nAlloc; // Number of allocated slots +** int nUsed; // Number of used slots +** struct VListEntry { +** int iValue; // Value for this entry +** int nSlot; // Slots used by this entry +** // ... variable name goes here +** } a[0]; +** } +** +** During code generation, pointers to the variable names within the +** VList are taken. When that happens, nAlloc is set to zero as an +** indication that the VList may never again be enlarged, since the +** accompanying realloc() would invalidate the pointers. +*/ +SQLITE_PRIVATE VList *sqlite3VListAdd( + sqlite3 *db, /* The database connection used for malloc() */ + VList *pIn, /* The input VList. Might be NULL */ + const char *zName, /* Name of symbol to add */ + int nName, /* Bytes of text in zName */ + int iVal /* Value to associate with zName */ +){ + int nInt; /* number of sizeof(int) objects needed for zName */ + char *z; /* Pointer to where zName will be stored */ + int i; /* Index in pIn[] where zName is stored */ + + nInt = nName/4 + 3; + assert( pIn==0 || pIn[0]>=3 ); /* Verify ok to add new elements */ + if( pIn==0 || pIn[1]+nInt > pIn[0] ){ + /* Enlarge the allocation */ + sqlite3_int64 nAlloc = (pIn ? 2*(sqlite3_int64)pIn[0] : 10) + nInt; + VList *pOut = sqlite3DbRealloc(db, pIn, nAlloc*sizeof(int)); + if( pOut==0 ) return pIn; + if( pIn==0 ) pOut[1] = 2; + pIn = pOut; + pIn[0] = nAlloc; + } + i = pIn[1]; + pIn[i] = iVal; + pIn[i+1] = nInt; + z = (char*)&pIn[i+2]; + pIn[1] = i+nInt; + assert( pIn[1]<=pIn[0] ); + memcpy(z, zName, nName); + z[nName] = 0; + return pIn; +} + +/* +** Return a pointer to the name of a variable in the given VList that +** has the value iVal. Or return a NULL if there is no such variable in +** the list +*/ +SQLITE_PRIVATE const char *sqlite3VListNumToName(VList *pIn, int iVal){ + int i, mx; + if( pIn==0 ) return 0; + mx = pIn[1]; + i = 2; + do{ + if( pIn[i]==iVal ) return (char*)&pIn[i+2]; + i += pIn[i+1]; + }while( i */ + +/* Turn bulk memory into a hash table object by initializing the +** fields of the Hash structure. +** +** "pNew" is a pointer to the hash table that is to be initialized. +*/ +SQLITE_PRIVATE void sqlite3HashInit(Hash *pNew){ + assert( pNew!=0 ); + pNew->first = 0; + pNew->count = 0; + pNew->htsize = 0; + pNew->ht = 0; +} + +/* Remove all entries from a hash table. Reclaim all memory. +** Call this routine to delete a hash table or to reset a hash table +** to the empty state. +*/ +SQLITE_PRIVATE void sqlite3HashClear(Hash *pH){ + HashElem *elem; /* For looping over all elements of the table */ + + assert( pH!=0 ); + elem = pH->first; + pH->first = 0; + sqlite3_free(pH->ht); + pH->ht = 0; + pH->htsize = 0; + while( elem ){ + HashElem *next_elem = elem->next; + sqlite3_free(elem); + elem = next_elem; + } + pH->count = 0; +} + +/* +** The hashing function. +*/ +static unsigned int strHash(const char *z){ + unsigned int h = 0; + while( z[0] ){ /*OPTIMIZATION-IF-TRUE*/ + /* Knuth multiplicative hashing. (Sorting & Searching, p. 510). + ** 0x9e3779b1 is 2654435761 which is the closest prime number to + ** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. + ** + ** Only bits 0xdf for ASCII and bits 0xbf for EBCDIC each octet are + ** hashed since the omitted bits determine the upper/lower case difference. + */ +#ifdef SQLITE_EBCDIC + h += 0xbf & (unsigned char)*(z++); +#else + h += 0xdf & (unsigned char)*(z++); +#endif + h *= 0x9e3779b1; + } + return h; +} + + +/* Link pNew element into the hash table pH. If pEntry!=0 then also +** insert pNew into the pEntry hash bucket. +*/ +static void insertElement( + Hash *pH, /* The complete hash table */ + struct _ht *pEntry, /* The entry into which pNew is inserted */ + HashElem *pNew /* The element to be inserted */ +){ + HashElem *pHead; /* First element already in pEntry */ + if( pEntry ){ + pHead = pEntry->count ? pEntry->chain : 0; + pEntry->count++; + pEntry->chain = pNew; + }else{ + pHead = 0; + } + if( pHead ){ + pNew->next = pHead; + pNew->prev = pHead->prev; + if( pHead->prev ){ pHead->prev->next = pNew; } + else { pH->first = pNew; } + pHead->prev = pNew; + }else{ + pNew->next = pH->first; + if( pH->first ){ pH->first->prev = pNew; } + pNew->prev = 0; + pH->first = pNew; + } +} + + +/* Resize the hash table so that it contains "new_size" buckets. +** +** The hash table might fail to resize if sqlite3_malloc() fails or +** if the new size is the same as the prior size. +** Return TRUE if the resize occurs and false if not. +*/ +static int rehash(Hash *pH, unsigned int new_size){ + struct _ht *new_ht; /* The new hash table */ + HashElem *elem, *next_elem; /* For looping over existing elements */ + +#if SQLITE_MALLOC_SOFT_LIMIT>0 + if( new_size*sizeof(struct _ht)>SQLITE_MALLOC_SOFT_LIMIT ){ + new_size = SQLITE_MALLOC_SOFT_LIMIT/sizeof(struct _ht); + } + if( new_size==pH->htsize ) return 0; +#endif + + /* The inability to allocates space for a larger hash table is + ** a performance hit but it is not a fatal error. So mark the + ** allocation as a benign. Use sqlite3Malloc()/memset(0) instead of + ** sqlite3MallocZero() to make the allocation, as sqlite3MallocZero() + ** only zeroes the requested number of bytes whereas this module will + ** use the actual amount of space allocated for the hash table (which + ** may be larger than the requested amount). + */ + sqlite3BeginBenignMalloc(); + new_ht = (struct _ht *)sqlite3Malloc( new_size*sizeof(struct _ht) ); + sqlite3EndBenignMalloc(); + + if( new_ht==0 ) return 0; + sqlite3_free(pH->ht); + pH->ht = new_ht; + pH->htsize = new_size = sqlite3MallocSize(new_ht)/sizeof(struct _ht); + memset(new_ht, 0, new_size*sizeof(struct _ht)); + for(elem=pH->first, pH->first=0; elem; elem = next_elem){ + next_elem = elem->next; + insertElement(pH, &new_ht[elem->h % new_size], elem); + } + return 1; +} + +/* This function (for internal use only) locates an element in an +** hash table that matches the given key. If no element is found, +** a pointer to a static null element with HashElem.data==0 is returned. +** If pH is not NULL, then the hash for this key is written to *pH. +*/ +static HashElem *findElementWithHash( + const Hash *pH, /* The pH to be searched */ + const char *pKey, /* The key we are searching for */ + unsigned int *pHash /* Write the hash value here */ +){ + HashElem *elem; /* Used to loop thru the element list */ + unsigned int count; /* Number of elements left to test */ + unsigned int h; /* The computed hash */ + static HashElem nullElement = { 0, 0, 0, 0, 0 }; + + h = strHash(pKey); + if( pH->ht ){ /*OPTIMIZATION-IF-TRUE*/ + struct _ht *pEntry; + pEntry = &pH->ht[h % pH->htsize]; + elem = pEntry->chain; + count = pEntry->count; + }else{ + elem = pH->first; + count = pH->count; + } + if( pHash ) *pHash = h; + while( count ){ + assert( elem!=0 ); + if( h==elem->h && sqlite3StrICmp(elem->pKey,pKey)==0 ){ + return elem; + } + elem = elem->next; + count--; + } + return &nullElement; +} + +/* Remove a single entry from the hash table given a pointer to that +** element and a hash on the element's key. +*/ +static void removeElement( + Hash *pH, /* The pH containing "elem" */ + HashElem *elem /* The element to be removed from the pH */ +){ + struct _ht *pEntry; + if( elem->prev ){ + elem->prev->next = elem->next; + }else{ + pH->first = elem->next; + } + if( elem->next ){ + elem->next->prev = elem->prev; + } + if( pH->ht ){ + pEntry = &pH->ht[elem->h % pH->htsize]; + if( pEntry->chain==elem ){ + pEntry->chain = elem->next; + } + assert( pEntry->count>0 ); + pEntry->count--; + } + sqlite3_free( elem ); + pH->count--; + if( pH->count==0 ){ + assert( pH->first==0 ); + assert( pH->count==0 ); + sqlite3HashClear(pH); + } +} + +/* Attempt to locate an element of the hash table pH with a key +** that matches pKey. Return the data for this element if it is +** found, or NULL if there is no match. +*/ +SQLITE_PRIVATE void *sqlite3HashFind(const Hash *pH, const char *pKey){ + assert( pH!=0 ); + assert( pKey!=0 ); + return findElementWithHash(pH, pKey, 0)->data; +} + +/* Insert an element into the hash table pH. The key is pKey +** and the data is "data". +** +** If no element exists with a matching key, then a new +** element is created and NULL is returned. +** +** If another element already exists with the same key, then the +** new data replaces the old data and the old data is returned. +** The key is not copied in this instance. If a malloc fails, then +** the new data is returned and the hash table is unchanged. +** +** If the "data" parameter to this function is NULL, then the +** element corresponding to "key" is removed from the hash table. +*/ +SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, void *data){ + unsigned int h; /* the hash of the key modulo hash table size */ + HashElem *elem; /* Used to loop thru the element list */ + HashElem *new_elem; /* New element added to the pH */ + + assert( pH!=0 ); + assert( pKey!=0 ); + elem = findElementWithHash(pH,pKey,&h); + if( elem->data ){ + void *old_data = elem->data; + if( data==0 ){ + removeElement(pH,elem); + }else{ + elem->data = data; + elem->pKey = pKey; + } + return old_data; + } + if( data==0 ) return 0; + new_elem = (HashElem*)sqlite3Malloc( sizeof(HashElem) ); + if( new_elem==0 ) return data; + new_elem->pKey = pKey; + new_elem->h = h; + new_elem->data = data; + pH->count++; + if( pH->count>=5 && pH->count > 2*pH->htsize ){ + rehash(pH, pH->count*3); + } + insertElement(pH, pH->ht ? &pH->ht[new_elem->h % pH->htsize] : 0, new_elem); + return 0; +} + + +/************** End of hash.c ************************************************/ +/************** Begin file opcodes.c *****************************************/ +/* Automatically generated. Do not edit */ +/* See the tool/mkopcodec.tcl script for details. */ +#if !defined(SQLITE_OMIT_EXPLAIN) \ + || defined(VDBE_PROFILE) \ + || defined(SQLITE_DEBUG) +#if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) || defined(SQLITE_DEBUG) +# define OpHelp(X) "\0" X +#else +# define OpHelp(X) +#endif +SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ + static const char *const azName[] = { + /* 0 */ "Savepoint" OpHelp(""), + /* 1 */ "AutoCommit" OpHelp(""), + /* 2 */ "Transaction" OpHelp(""), + /* 3 */ "Checkpoint" OpHelp(""), + /* 4 */ "JournalMode" OpHelp(""), + /* 5 */ "Vacuum" OpHelp(""), + /* 6 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"), + /* 7 */ "VUpdate" OpHelp("data=r[P3@P2]"), + /* 8 */ "Init" OpHelp("Start at P2"), + /* 9 */ "Goto" OpHelp(""), + /* 10 */ "Gosub" OpHelp(""), + /* 11 */ "InitCoroutine" OpHelp(""), + /* 12 */ "Yield" OpHelp(""), + /* 13 */ "MustBeInt" OpHelp(""), + /* 14 */ "Jump" OpHelp(""), + /* 15 */ "Once" OpHelp(""), + /* 16 */ "If" OpHelp(""), + /* 17 */ "IfNot" OpHelp(""), + /* 18 */ "IsType" OpHelp("if typeof(P1.P3) in P5 goto P2"), + /* 19 */ "Not" OpHelp("r[P2]= !r[P1]"), + /* 20 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"), + /* 21 */ "SeekLT" OpHelp("key=r[P3@P4]"), + /* 22 */ "SeekLE" OpHelp("key=r[P3@P4]"), + /* 23 */ "SeekGE" OpHelp("key=r[P3@P4]"), + /* 24 */ "SeekGT" OpHelp("key=r[P3@P4]"), + /* 25 */ "IfNotOpen" OpHelp("if( !csr[P1] ) goto P2"), + /* 26 */ "IfNoHope" OpHelp("key=r[P3@P4]"), + /* 27 */ "NoConflict" OpHelp("key=r[P3@P4]"), + /* 28 */ "NotFound" OpHelp("key=r[P3@P4]"), + /* 29 */ "Found" OpHelp("key=r[P3@P4]"), + /* 30 */ "SeekRowid" OpHelp("intkey=r[P3]"), + /* 31 */ "NotExists" OpHelp("intkey=r[P3]"), + /* 32 */ "Last" OpHelp(""), + /* 33 */ "IfSizeBetween" OpHelp(""), + /* 34 */ "SorterSort" OpHelp(""), + /* 35 */ "Sort" OpHelp(""), + /* 36 */ "Rewind" OpHelp(""), + /* 37 */ "IfEmpty" OpHelp("if( empty(P1) ) goto P2"), + /* 38 */ "SorterNext" OpHelp(""), + /* 39 */ "Prev" OpHelp(""), + /* 40 */ "Next" OpHelp(""), + /* 41 */ "IdxLE" OpHelp("key=r[P3@P4]"), + /* 42 */ "IdxGT" OpHelp("key=r[P3@P4]"), + /* 43 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), + /* 44 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), + /* 45 */ "IdxLT" OpHelp("key=r[P3@P4]"), + /* 46 */ "IdxGE" OpHelp("key=r[P3@P4]"), + /* 47 */ "IFindKey" OpHelp(""), + /* 48 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), + /* 49 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), + /* 50 */ "Program" OpHelp(""), + /* 51 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), + /* 52 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), + /* 53 */ "Ne" OpHelp("IF r[P3]!=r[P1]"), + /* 54 */ "Eq" OpHelp("IF r[P3]==r[P1]"), + /* 55 */ "Gt" OpHelp("IF r[P3]>r[P1]"), + /* 56 */ "Le" OpHelp("IF r[P3]<=r[P1]"), + /* 57 */ "Lt" OpHelp("IF r[P3]=r[P1]"), + /* 59 */ "ElseEq" OpHelp(""), + /* 60 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), + /* 61 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), + /* 62 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), + /* 63 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), + /* 64 */ "IncrVacuum" OpHelp(""), + /* 65 */ "VNext" OpHelp(""), + /* 66 */ "Filter" OpHelp("if key(P3@P4) not in filter(P1) goto P2"), + /* 67 */ "PureFunc" OpHelp("r[P3]=func(r[P2@NP])"), + /* 68 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"), + /* 69 */ "Return" OpHelp(""), + /* 70 */ "EndCoroutine" OpHelp(""), + /* 71 */ "HaltIfNull" OpHelp("if r[P3]=null halt"), + /* 72 */ "Halt" OpHelp(""), + /* 73 */ "Integer" OpHelp("r[P2]=P1"), + /* 74 */ "Int64" OpHelp("r[P2]=P4"), + /* 75 */ "String" OpHelp("r[P2]='P4' (len=P1)"), + /* 76 */ "BeginSubrtn" OpHelp("r[P2]=NULL"), + /* 77 */ "Null" OpHelp("r[P2..P3]=NULL"), + /* 78 */ "SoftNull" OpHelp("r[P1]=NULL"), + /* 79 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), + /* 80 */ "Variable" OpHelp("r[P2]=parameter(P1)"), + /* 81 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), + /* 82 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), + /* 83 */ "SCopy" OpHelp("r[P2]=r[P1]"), + /* 84 */ "IntCopy" OpHelp("r[P2]=r[P1]"), + /* 85 */ "FkCheck" OpHelp(""), + /* 86 */ "ResultRow" OpHelp("output=r[P1@P2]"), + /* 87 */ "CollSeq" OpHelp(""), + /* 88 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), + /* 89 */ "RealAffinity" OpHelp(""), + /* 90 */ "Cast" OpHelp("affinity(r[P1])"), + /* 91 */ "Permutation" OpHelp(""), + /* 92 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), + /* 93 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"), + /* 94 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"), + /* 95 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"), + /* 96 */ "Column" OpHelp("r[P3]=PX cursor P1 column P2"), + /* 97 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"), + /* 98 */ "Affinity" OpHelp("affinity(r[P1@P2])"), + /* 99 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), + /* 100 */ "Count" OpHelp("r[P2]=count()"), + /* 101 */ "ReadCookie" OpHelp(""), + /* 102 */ "SetCookie" OpHelp(""), + /* 103 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), + /* 104 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), + /* 105 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"), + /* 107 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), + /* 108 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), + /* 109 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), + /* 110 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), + /* 111 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), + /* 112 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), + /* 113 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), + /* 114 */ "OpenRead" OpHelp("root=P2 iDb=P3"), + /* 115 */ "BitNot" OpHelp("r[P2]= ~r[P1]"), + /* 116 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), + /* 117 */ "OpenDup" OpHelp(""), + /* 118 */ "String8" OpHelp("r[P2]='P4'"), + /* 119 */ "OpenAutoindex" OpHelp("nColumn=P2"), + /* 120 */ "OpenEphemeral" OpHelp("nColumn=P2"), + /* 121 */ "SorterOpen" OpHelp(""), + /* 122 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), + /* 123 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), + /* 124 */ "Close" OpHelp(""), + /* 125 */ "ColumnsUsed" OpHelp(""), + /* 126 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"), + /* 127 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"), + /* 128 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), + /* 129 */ "NewRowid" OpHelp("r[P2]=rowid"), + /* 130 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), + /* 131 */ "RowCell" OpHelp(""), + /* 132 */ "Delete" OpHelp(""), + /* 133 */ "ResetCount" OpHelp(""), + /* 134 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), + /* 135 */ "SorterData" OpHelp("r[P2]=data"), + /* 136 */ "RowData" OpHelp("r[P2]=data"), + /* 137 */ "Rowid" OpHelp("r[P2]=PX rowid of P1"), + /* 138 */ "NullRow" OpHelp(""), + /* 139 */ "SeekEnd" OpHelp(""), + /* 140 */ "IdxInsert" OpHelp("key=r[P2]"), + /* 141 */ "SorterInsert" OpHelp("key=r[P2]"), + /* 142 */ "IdxDelete" OpHelp("key=r[P2@P3]"), + /* 143 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"), + /* 144 */ "IdxRowid" OpHelp("r[P2]=rowid"), + /* 145 */ "FinishSeek" OpHelp(""), + /* 146 */ "Destroy" OpHelp(""), + /* 147 */ "Clear" OpHelp(""), + /* 148 */ "ResetSorter" OpHelp(""), + /* 149 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"), + /* 150 */ "SqlExec" OpHelp(""), + /* 151 */ "ParseSchema" OpHelp(""), + /* 152 */ "LoadAnalysis" OpHelp(""), + /* 153 */ "DropTable" OpHelp(""), + /* 154 */ "Real" OpHelp("r[P2]=P4"), + /* 155 */ "DropIndex" OpHelp(""), + /* 156 */ "DropTrigger" OpHelp(""), + /* 157 */ "IntegrityCk" OpHelp(""), + /* 158 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), + /* 159 */ "Param" OpHelp(""), + /* 160 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), + /* 161 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), + /* 162 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), + /* 163 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"), + /* 164 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), + /* 165 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"), + /* 166 */ "AggValue" OpHelp("r[P3]=value N=P2"), + /* 167 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), + /* 168 */ "Expire" OpHelp(""), + /* 169 */ "CursorLock" OpHelp(""), + /* 170 */ "CursorUnlock" OpHelp(""), + /* 171 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), + /* 172 */ "VBegin" OpHelp(""), + /* 173 */ "VCreate" OpHelp(""), + /* 174 */ "VDestroy" OpHelp(""), + /* 175 */ "VOpen" OpHelp(""), + /* 176 */ "VCheck" OpHelp(""), + /* 177 */ "VInitIn" OpHelp("r[P2]=ValueList(P1,P3)"), + /* 178 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), + /* 179 */ "VRename" OpHelp(""), + /* 180 */ "Pagecount" OpHelp(""), + /* 181 */ "MaxPgcnt" OpHelp(""), + /* 182 */ "ClrSubtype" OpHelp("r[P1].subtype = 0"), + /* 183 */ "GetSubtype" OpHelp("r[P2] = r[P1].subtype"), + /* 184 */ "SetSubtype" OpHelp("r[P2].subtype = r[P1]"), + /* 185 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"), + /* 186 */ "Trace" OpHelp(""), + /* 187 */ "CursorHint" OpHelp(""), + /* 188 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), + /* 189 */ "Noop" OpHelp(""), + /* 190 */ "Explain" OpHelp(""), + /* 191 */ "Abortable" OpHelp(""), + }; + return azName[i]; +} +#endif + +/************** End of opcodes.c *********************************************/ +/************** Begin file os_kv.c *******************************************/ +/* +** 2022-09-06 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains an experimental VFS layer that operates on a +** Key/Value storage engine where both keys and values must be pure +** text. +*/ +/* #include */ +#if SQLITE_OS_KV || (SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL)) + +/***************************************************************************** +** Debugging logic +*/ + +/* SQLITE_KV_TRACE() is used for tracing calls to kvrecord routines. */ +#if 0 +#define SQLITE_KV_TRACE(X) printf X +#else +#define SQLITE_KV_TRACE(X) +#endif + +/* SQLITE_KV_LOG() is used for tracing calls to the VFS interface */ +#if 0 +#define SQLITE_KV_LOG(X) printf X +#else +#define SQLITE_KV_LOG(X) +#endif + +/* +** Forward declaration of objects used by this VFS implementation +*/ +typedef struct KVVfsFile KVVfsFile; + +/* A single open file. There are only two files represented by this +** VFS - the database and the rollback journal. +** +** Maintenance reminder: if this struct changes in any way, the JSON +** rendering of its structure must be updated in +** sqlite3-wasm.c:sqlite3__wasm_enum_json(). There are no binary +** compatibility concerns, so it does not need an iVersion member. +*/ +struct KVVfsFile { + sqlite3_file base; /* IO methods */ + const char *zClass; /* Storage class */ + int isJournal; /* True if this is a journal file */ + unsigned int nJrnl; /* Space allocated for aJrnl[] */ + char *aJrnl; /* Journal content */ + int szPage; /* Last known page size */ + sqlite3_int64 szDb; /* Database file size. -1 means unknown */ + char *aData; /* Buffer to hold page data */ +}; +#define SQLITE_KVOS_SZ 133073 + +/* +** Methods for KVVfsFile +*/ +static int kvvfsClose(sqlite3_file*); +static int kvvfsReadDb(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); +static int kvvfsReadJrnl(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); +static int kvvfsWriteDb(sqlite3_file*,const void*,int iAmt, sqlite3_int64); +static int kvvfsWriteJrnl(sqlite3_file*,const void*,int iAmt, sqlite3_int64); +static int kvvfsTruncateDb(sqlite3_file*, sqlite3_int64 size); +static int kvvfsTruncateJrnl(sqlite3_file*, sqlite3_int64 size); +static int kvvfsSyncDb(sqlite3_file*, int flags); +static int kvvfsSyncJrnl(sqlite3_file*, int flags); +static int kvvfsFileSizeDb(sqlite3_file*, sqlite3_int64 *pSize); +static int kvvfsFileSizeJrnl(sqlite3_file*, sqlite3_int64 *pSize); +static int kvvfsLock(sqlite3_file*, int); +static int kvvfsUnlock(sqlite3_file*, int); +static int kvvfsCheckReservedLock(sqlite3_file*, int *pResOut); +static int kvvfsFileControlDb(sqlite3_file*, int op, void *pArg); +static int kvvfsFileControlJrnl(sqlite3_file*, int op, void *pArg); +static int kvvfsSectorSize(sqlite3_file*); +static int kvvfsDeviceCharacteristics(sqlite3_file*); + +/* +** Methods for sqlite3_vfs +*/ +static int kvvfsOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *); +static int kvvfsDelete(sqlite3_vfs*, const char *zName, int syncDir); +static int kvvfsAccess(sqlite3_vfs*, const char *zName, int flags, int *); +static int kvvfsFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut); +static void *kvvfsDlOpen(sqlite3_vfs*, const char *zFilename); +static int kvvfsRandomness(sqlite3_vfs*, int nByte, char *zOut); +static int kvvfsSleep(sqlite3_vfs*, int microseconds); +static int kvvfsCurrentTime(sqlite3_vfs*, double*); +static int kvvfsCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*); + +static sqlite3_vfs sqlite3OsKvvfsObject = { + 2, /* iVersion */ + sizeof(KVVfsFile), /* szOsFile */ + 1024, /* mxPathname */ + 0, /* pNext */ + "kvvfs", /* zName */ + 0, /* pAppData */ + kvvfsOpen, /* xOpen */ + kvvfsDelete, /* xDelete */ + kvvfsAccess, /* xAccess */ + kvvfsFullPathname, /* xFullPathname */ + kvvfsDlOpen, /* xDlOpen */ + 0, /* xDlError */ + 0, /* xDlSym */ + 0, /* xDlClose */ + kvvfsRandomness, /* xRandomness */ + kvvfsSleep, /* xSleep */ + kvvfsCurrentTime, /* xCurrentTime */ + 0, /* xGetLastError */ + kvvfsCurrentTimeInt64 /* xCurrentTimeInt64 */ +}; + +/* Methods for sqlite3_file objects referencing a database file +*/ +static sqlite3_io_methods kvvfs_db_io_methods = { + 1, /* iVersion */ + kvvfsClose, /* xClose */ + kvvfsReadDb, /* xRead */ + kvvfsWriteDb, /* xWrite */ + kvvfsTruncateDb, /* xTruncate */ + kvvfsSyncDb, /* xSync */ + kvvfsFileSizeDb, /* xFileSize */ + kvvfsLock, /* xLock */ + kvvfsUnlock, /* xUnlock */ + kvvfsCheckReservedLock, /* xCheckReservedLock */ + kvvfsFileControlDb, /* xFileControl */ + kvvfsSectorSize, /* xSectorSize */ + kvvfsDeviceCharacteristics, /* xDeviceCharacteristics */ + 0, /* xShmMap */ + 0, /* xShmLock */ + 0, /* xShmBarrier */ + 0, /* xShmUnmap */ + 0, /* xFetch */ + 0 /* xUnfetch */ +}; + +/* Methods for sqlite3_file objects referencing a rollback journal +*/ +static sqlite3_io_methods kvvfs_jrnl_io_methods = { + 1, /* iVersion */ + kvvfsClose, /* xClose */ + kvvfsReadJrnl, /* xRead */ + kvvfsWriteJrnl, /* xWrite */ + kvvfsTruncateJrnl, /* xTruncate */ + kvvfsSyncJrnl, /* xSync */ + kvvfsFileSizeJrnl, /* xFileSize */ + kvvfsLock, /* xLock */ + kvvfsUnlock, /* xUnlock */ + kvvfsCheckReservedLock, /* xCheckReservedLock */ + kvvfsFileControlJrnl, /* xFileControl */ + kvvfsSectorSize, /* xSectorSize */ + kvvfsDeviceCharacteristics, /* xDeviceCharacteristics */ + 0, /* xShmMap */ + 0, /* xShmLock */ + 0, /* xShmBarrier */ + 0, /* xShmUnmap */ + 0, /* xFetch */ + 0 /* xUnfetch */ +}; + +/****** Storage subsystem **************************************************/ +#include +#include +#include + +/* Forward declarations for the low-level storage engine +*/ +#ifndef SQLITE_WASM +/* In WASM builds these are implemented in JS. */ +static int kvrecordWrite(const char*, const char *zKey, const char *zData); +static int kvrecordDelete(const char*, const char *zKey); +static int kvrecordRead(const char*, const char *zKey, char *zBuf, int nBuf); +#endif +#ifndef KVRECORD_KEY_SZ +#define KVRECORD_KEY_SZ 32 +#endif + +/* Expand the key name with an appropriate prefix and put the result +** in zKeyOut[]. The zKeyOut[] buffer is assumed to hold at least +** KVRECORD_KEY_SZ bytes. +*/ +static void kvrecordMakeKey( + const char *zClass, + const char *zKeyIn, + char *zKeyOut +){ + assert( zKeyIn ); + assert( zKeyOut ); + assert( zClass ); + sqlite3_snprintf(KVRECORD_KEY_SZ, zKeyOut, "kvvfs-%s-%s", + zClass, zKeyIn); +} + +#ifndef SQLITE_WASM +/* In WASM builds do not define APIs which use fopen(), fwrite(), +** and the like because those APIs are a portability issue for +** WASM. +*/ +/* Write content into a key. zClass is the particular namespace of the +** underlying key/value store to use - either "local" or "session". +** +** Both zKey and zData are zero-terminated pure text strings. +** +** Return the number of errors. +*/ +static int kvrecordWrite( + const char *zClass, + const char *zKey, + const char *zData +){ + FILE *fd; + char zXKey[KVRECORD_KEY_SZ]; + kvrecordMakeKey(zClass, zKey, zXKey); + fd = fopen(zXKey, "wb"); + if( fd ){ + SQLITE_KV_TRACE(("KVVFS-WRITE %-15s (%d) %.50s%s\n", zXKey, + (int)strlen(zData), zData, + strlen(zData)>50 ? "..." : "")); + fputs(zData, fd); + fclose(fd); + return 0; + }else{ + return 1; + } +} + +/* Delete a key (with its corresponding data) from the key/value +** namespace given by zClass. If the key does not previously exist, +** this routine is a no-op. +*/ +static int kvrecordDelete(const char *zClass, const char *zKey){ + char zXKey[KVRECORD_KEY_SZ]; + kvrecordMakeKey(zClass, zKey, zXKey); + unlink(zXKey); + SQLITE_KV_TRACE(("KVVFS-DELETE %-15s\n", zXKey)); + return 0; +} + +/* Read the value associated with a zKey from the key/value namespace given +** by zClass and put the text data associated with that key in the first +** nBuf bytes of zBuf[]. The value might be truncated if zBuf is not large +** enough to hold it all. The value put into zBuf must always be zero +** terminated, even if it gets truncated because nBuf is not large enough. +** +** Return the total number of bytes in the data, without truncation, and +** not counting the final zero terminator. Return -1 if the key does +** not exist or its key cannot be read. +** +** If nBuf<=0 then this routine simply returns the size of the data +** without actually reading it. Similarly, if nBuf==1 then it +** zero-terminates zBuf at zBuf[0] and returns the size of the data +** without reading it. +*/ +static int kvrecordRead( + const char *zClass, + const char *zKey, + char *zBuf, + int nBuf +){ + FILE *fd; + struct stat buf; + char zXKey[KVRECORD_KEY_SZ]; + kvrecordMakeKey(zClass, zKey, zXKey); + if( access(zXKey, R_OK)!=0 + || stat(zXKey, &buf)!=0 + || !S_ISREG(buf.st_mode) + ){ + SQLITE_KV_TRACE(("KVVFS-READ %-15s (-1)\n", zXKey)); + return -1; + } + if( nBuf<=0 ){ + return (int)buf.st_size; + }else if( nBuf==1 ){ + zBuf[0] = 0; + SQLITE_KV_TRACE(("KVVFS-READ %-15s (%d)\n", zXKey, + (int)buf.st_size)); + return (int)buf.st_size; + } + if( nBuf > buf.st_size + 1 ){ + nBuf = buf.st_size + 1; + } + fd = fopen(zXKey, "rb"); + if( fd==0 ){ + SQLITE_KV_TRACE(("KVVFS-READ %-15s (-1)\n", zXKey)); + return -1; + }else{ + sqlite3_int64 n = fread(zBuf, 1, nBuf-1, fd); + fclose(fd); + zBuf[n] = 0; + SQLITE_KV_TRACE(("KVVFS-READ %-15s (%lld) %.50s%s\n", zXKey, + n, zBuf, n>50 ? "..." : "")); + return (int)n; + } +} +#endif /* #ifndef SQLITE_WASM */ + + +/* +** An internal level of indirection which enables us to replace the +** kvvfs i/o methods with JavaScript implementations in WASM builds. +** Maintenance reminder: if this struct changes in any way, the JSON +** rendering of its structure must be updated in +** sqlite3-wasm.c:sqlite3__wasm_enum_json(). There are no binary +** compatibility concerns, so it does not need an iVersion member. +*/ +typedef struct sqlite3_kvvfs_methods sqlite3_kvvfs_methods; +struct sqlite3_kvvfs_methods { + int (*xRcrdRead)(const char*, const char *zKey, char *zBuf, int nBuf); + int (*xRcrdWrite)(const char*, const char *zKey, const char *zData); + int (*xRcrdDelete)(const char*, const char *zKey); + const int nKeySize; + const int nBufferSize; +#ifndef SQLITE_WASM +# define MAYBE_CONST const +#else +# define MAYBE_CONST +#endif + MAYBE_CONST sqlite3_vfs * pVfs; + MAYBE_CONST sqlite3_io_methods *pIoDb; + MAYBE_CONST sqlite3_io_methods *pIoJrnl; +#undef MAYBE_CONST +}; + + +/* +** This object holds the kvvfs I/O methods which may be swapped out +** for JavaScript-side implementations in WASM builds. In such builds +** it cannot be const, but in native builds it should be so that +** the compiler can hopefully optimize this level of indirection out. +** That said, kvvfs is intended primarily for use in WASM builds. +** +** This is not explicitly flagged as static because the amalgamation +** build will tag it with SQLITE_PRIVATE. +*/ +#ifndef SQLITE_WASM +const +#endif +SQLITE_PRIVATE sqlite3_kvvfs_methods sqlite3KvvfsMethods = { +#ifndef SQLITE_WASM + .xRcrdRead = kvrecordRead, + .xRcrdWrite = kvrecordWrite, + .xRcrdDelete = kvrecordDelete, +#else + .xRcrdRead = 0, + .xRcrdWrite = 0, + .xRcrdDelete = 0, +#endif + .nKeySize = KVRECORD_KEY_SZ, + .nBufferSize = SQLITE_KVOS_SZ, + .pVfs = &sqlite3OsKvvfsObject, + .pIoDb = &kvvfs_db_io_methods, + .pIoJrnl = &kvvfs_jrnl_io_methods +}; + +/****** Utility subroutines ************************************************/ + +/* +** Encode binary into the text encoded used to persist on disk. +** The output text is stored in aOut[], which must be at least +** nData+1 bytes in length. +** +** Return the actual length of the encoded text, not counting the +** zero terminator at the end. +** +** Encoding format +** --------------- +** +** * Non-zero bytes are encoded as upper-case hexadecimal +** +** * A sequence of one or more zero-bytes that are not at the +** beginning of the buffer are encoded as a little-endian +** base-26 number using a..z. "a" means 0. "b" means 1, +** "z" means 25. "ab" means 26. "ac" means 52. And so forth. +** +** * Because there is no overlap between the encoding characters +** of hexadecimal and base-26 numbers, it is always clear where +** one stops and the next begins. +*/ +#ifndef SQLITE_WASM +static +#endif +int kvvfsEncode(const char *aData, int nData, char *aOut){ + int i, j; + const unsigned char *a = (const unsigned char*)aData; + for(i=j=0; i>4]; + aOut[j++] = "0123456789ABCDEF"[c&0xf]; + }else{ + /* A sequence of 1 or more zeros is stored as a little-endian + ** base-26 number using a..z as the digits. So one zero is "b". + ** Two zeros is "c". 25 zeros is "z", 26 zeros is "ab", 27 is "bb", + ** and so forth. + */ + int k; + for(k=1; i+k0 ){ + aOut[j++] = 'a'+(k%26); + k /= 26; + } + } + } + aOut[j] = 0; + return j; +} + +static const signed char kvvfsHexValue[256] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +}; + +/* +** Decode the text encoding back to binary. The binary content is +** written into pOut, which must be at least nOut bytes in length. +** +** The return value is the number of bytes actually written into aOut[], or +** -1 for malformed inputs. +*/ +#ifndef SQLITE_WASM +static +#endif +int kvvfsDecode(const char *a, char *aOut, int nOut){ + int i, j; + int c; + const unsigned char *aIn = (const unsigned char*)a; + i = 0; + j = 0; + while( 1 ){ + c = kvvfsHexValue[aIn[i]]; + if( c<0 ){ + sqlite3_int64 n = 0; + sqlite3_int64 mult = 1; + c = aIn[i]; + if( c==0 ) break; + while( c>='a' && c<='z' ){ + n += (c - 'a')*mult; + if( n>nOut ) return -1 /* oversized/malformed input */; + mult *= 26; + c = aIn[++i]; + } + if( j+n>nOut ) return -1 /* oversized/malformed input */; + memset(&aOut[j], 0, n); + j += n; + if( c==0 || mult==1 ) break; /* progress stalled if mult==1 */ + }else{ + aOut[j] = c<<4; + c = kvvfsHexValue[aIn[++i]]; + if( c<0 ) return -1 /* hex bytes are always in pairs */; + aOut[j++] += c; + i++; + } + } + return j; +} + +/* +** Decode a complete journal file. Allocate space in pFile->aJrnl +** and store the decoding there. Or leave pFile->aJrnl set to NULL +** if an error is encountered. +** +** The first few characters of the text encoding will be a little-endian +** base-26 number (digits a..z) that is the total number of bytes +** in the decoded journal file image. This base-26 number is followed +** by a single space, then the encoding of the journal. The space +** separator is required to act as a terminator for the base-26 number. +*/ +static void kvvfsDecodeJournal( + KVVfsFile *pFile, /* Store decoding in pFile->aJrnl */ + const char *zTxt, /* Text encoding. Zero-terminated */ + int nTxt /* Bytes in zTxt, excluding zero terminator */ +){ + unsigned int n = 0; + int c, i, mult; + i = 0; + mult = 1; + while( (c = zTxt[i++])>='a' && c<='z' ){ + n += (c - 'a')*mult; + mult *= 26; + } + sqlite3_free(pFile->aJrnl); + pFile->aJrnl = sqlite3_malloc64( n ); + if( pFile->aJrnl==0 ){ + pFile->nJrnl = 0; + return; + } + pFile->nJrnl = n; + n = kvvfsDecode(zTxt+i, pFile->aJrnl, pFile->nJrnl); + if( nnJrnl ){ + sqlite3_free(pFile->aJrnl); + pFile->aJrnl = 0; + pFile->nJrnl = 0; + } +} + +/* +** Read or write the "sz" element, containing the database file size. +*/ +static sqlite3_int64 kvvfsReadFileSize(KVVfsFile *pFile){ + char zData[50]; + zData[0] = 0; + sqlite3KvvfsMethods.xRcrdRead(pFile->zClass, "sz", zData, + sizeof(zData)-1); + return strtoll(zData, 0, 0); +} +static int kvvfsWriteFileSize(KVVfsFile *pFile, sqlite3_int64 sz){ + char zData[50]; + sqlite3_snprintf(sizeof(zData), zData, "%lld", sz); + return sqlite3KvvfsMethods.xRcrdWrite(pFile->zClass, "sz", zData); +} + +/****** sqlite3_io_methods methods ******************************************/ + +/* +** Close an kvvfs-file. +*/ +static int kvvfsClose(sqlite3_file *pProtoFile){ + KVVfsFile *pFile = (KVVfsFile *)pProtoFile; + + SQLITE_KV_LOG(("xClose %s %s\n", pFile->zClass, + pFile->isJournal ? "journal" : "db")); + sqlite3_free(pFile->aJrnl); + sqlite3_free(pFile->aData); + memset(pFile, 0, sizeof(*pFile)); + return SQLITE_OK; +} + +/* +** Read from the -journal file. +*/ +static int kvvfsReadJrnl( + sqlite3_file *pProtoFile, + void *zBuf, + int iAmt, + sqlite_int64 iOfst +){ + KVVfsFile *pFile = (KVVfsFile*)pProtoFile; + assert( pFile->isJournal ); + SQLITE_KV_LOG(("xRead('%s-journal',%d,%lld)\n", pFile->zClass, iAmt, iOfst)); + if( pFile->aJrnl==0 ){ + int rc; + int szTxt = sqlite3KvvfsMethods.xRcrdRead(pFile->zClass, "jrnl", + 0, 0); + char *aTxt; + if( szTxt<=4 ){ + return SQLITE_IOERR; + } + aTxt = sqlite3_malloc64( szTxt+1 ); + if( aTxt==0 ) return SQLITE_NOMEM; + rc = sqlite3KvvfsMethods.xRcrdRead(pFile->zClass, "jrnl", + aTxt, szTxt+1); + if( rc>=0 ){ + kvvfsDecodeJournal(pFile, aTxt, szTxt); + rc = 0; + } + sqlite3_free(aTxt); + if( rc ) return rc; + if( pFile->aJrnl==0 ) return SQLITE_IOERR; + } + if( iOfst+iAmt>pFile->nJrnl ){ + return SQLITE_IOERR_SHORT_READ; + } + memcpy(zBuf, pFile->aJrnl+iOfst, iAmt); + return SQLITE_OK; +} + +/* +** Read from the database file. +*/ +static int kvvfsReadDb( + sqlite3_file *pProtoFile, + void *zBuf, + int iAmt, + sqlite_int64 iOfst +){ + KVVfsFile *pFile = (KVVfsFile*)pProtoFile; + unsigned int pgno; + int got, n; + char zKey[30]; + char *aData = pFile->aData; + assert( iOfst>=0 ); + assert( iAmt>=0 ); + SQLITE_KV_LOG(("xRead('%s-db',%d,%lld)\n", pFile->zClass, iAmt, iOfst)); + if( iOfst+iAmt>=512 ){ + if( (iOfst % iAmt)!=0 ){ + return SQLITE_IOERR_READ; + } + if( (iAmt & (iAmt-1))!=0 || iAmt<512 || iAmt>65536 ){ + return SQLITE_IOERR_READ; + } + pFile->szPage = iAmt; + pgno = 1 + iOfst/iAmt; + }else{ + pgno = 1; + } + sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno); + got = sqlite3KvvfsMethods.xRcrdRead(pFile->zClass, zKey, + aData, SQLITE_KVOS_SZ-1); + if( got<0 ){ + n = 0; + }else{ + aData[got] = 0; + if( iOfst+iAmt<512 ){ + int k = iOfst+iAmt; + aData[k*2] = 0; + n = kvvfsDecode(aData, &aData[2000], SQLITE_KVOS_SZ-2000); + if( n>=iOfst+iAmt ){ + memcpy(zBuf, &aData[2000+iOfst], iAmt); + n = iAmt; + }else{ + n = 0; + } + }else{ + n = kvvfsDecode(aData, zBuf, iAmt); + } + } + if( nzClass, iAmt, iOfst)); + if( iEnd>=0x10000000 ) return SQLITE_FULL; + if( pFile->aJrnl==0 || pFile->nJrnlaJrnl, iEnd); + if( aNew==0 ){ + return SQLITE_IOERR_NOMEM; + } + pFile->aJrnl = aNew; + if( pFile->nJrnlaJrnl+pFile->nJrnl, 0, iOfst-pFile->nJrnl); + } + pFile->nJrnl = iEnd; + } + memcpy(pFile->aJrnl+iOfst, zBuf, iAmt); + return SQLITE_OK; +} + +/* +** Write into the database file. +*/ +static int kvvfsWriteDb( + sqlite3_file *pProtoFile, + const void *zBuf, + int iAmt, + sqlite_int64 iOfst +){ + KVVfsFile *pFile = (KVVfsFile*)pProtoFile; + unsigned int pgno; + char zKey[30]; + char *aData = pFile->aData; + int rc; + SQLITE_KV_LOG(("xWrite('%s-db',%d,%lld)\n", pFile->zClass, iAmt, iOfst)); + assert( iAmt>=512 && iAmt<=65536 ); + assert( (iAmt & (iAmt-1))==0 ); + assert( pFile->szPage<0 || pFile->szPage==iAmt ); + pFile->szPage = iAmt; + pgno = 1 + iOfst/iAmt; + sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno); + kvvfsEncode(zBuf, iAmt, aData); + rc = sqlite3KvvfsMethods.xRcrdWrite(pFile->zClass, zKey, aData); + if( 0==rc ){ + if( iOfst+iAmt > pFile->szDb ){ + pFile->szDb = iOfst + iAmt; + } + } + return rc; +} + +/* +** Truncate an kvvfs-file. +*/ +static int kvvfsTruncateJrnl(sqlite3_file *pProtoFile, sqlite_int64 size){ + KVVfsFile *pFile = (KVVfsFile *)pProtoFile; + SQLITE_KV_LOG(("xTruncate('%s-journal',%lld)\n", pFile->zClass, size)); + assert( size==0 ); + sqlite3KvvfsMethods.xRcrdDelete(pFile->zClass, "jrnl"); + sqlite3_free(pFile->aJrnl); + pFile->aJrnl = 0; + pFile->nJrnl = 0; + return SQLITE_OK; +} +static int kvvfsTruncateDb(sqlite3_file *pProtoFile, sqlite_int64 size){ + KVVfsFile *pFile = (KVVfsFile *)pProtoFile; + if( pFile->szDb>size + && pFile->szPage>0 + && (size % pFile->szPage)==0 + ){ + char zKey[50]; + unsigned int pgno, pgnoMax; + SQLITE_KV_LOG(("xTruncate('%s-db',%lld)\n", pFile->zClass, size)); + pgno = 1 + size/pFile->szPage; + pgnoMax = 2 + pFile->szDb/pFile->szPage; + while( pgno<=pgnoMax ){ + sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno); + sqlite3KvvfsMethods.xRcrdDelete(pFile->zClass, zKey); + pgno++; + } + pFile->szDb = size; + return kvvfsWriteFileSize(pFile, size) ? SQLITE_IOERR : SQLITE_OK; + } + return SQLITE_IOERR; +} + +/* +** Sync an kvvfs-file. +*/ +static int kvvfsSyncJrnl(sqlite3_file *pProtoFile, int flags){ + int i, n; + KVVfsFile *pFile = (KVVfsFile *)pProtoFile; + char *zOut; + SQLITE_KV_LOG(("xSync('%s-journal')\n", pFile->zClass)); + if( pFile->nJrnl<=0 ){ + return kvvfsTruncateJrnl(pProtoFile, 0); + } + zOut = sqlite3_malloc64( pFile->nJrnl*2 + 50 ); + if( zOut==0 ){ + return SQLITE_IOERR_NOMEM; + } + n = pFile->nJrnl; + i = 0; + do{ + zOut[i++] = 'a' + (n%26); + n /= 26; + }while( n>0 ); + zOut[i++] = ' '; + kvvfsEncode(pFile->aJrnl, pFile->nJrnl, &zOut[i]); + i = sqlite3KvvfsMethods.xRcrdWrite(pFile->zClass, "jrnl", zOut); + sqlite3_free(zOut); + return i ? SQLITE_IOERR : SQLITE_OK; +} +static int kvvfsSyncDb(sqlite3_file *pProtoFile, int flags){ + return SQLITE_OK; +} + +/* +** Return the current file-size of an kvvfs-file. +*/ +static int kvvfsFileSizeJrnl(sqlite3_file *pProtoFile, sqlite_int64 *pSize){ + KVVfsFile *pFile = (KVVfsFile *)pProtoFile; + SQLITE_KV_LOG(("xFileSize('%s-journal')\n", pFile->zClass)); + *pSize = pFile->nJrnl; + return SQLITE_OK; +} +static int kvvfsFileSizeDb(sqlite3_file *pProtoFile, sqlite_int64 *pSize){ + KVVfsFile *pFile = (KVVfsFile *)pProtoFile; + SQLITE_KV_LOG(("xFileSize('%s-db')\n", pFile->zClass)); + if( pFile->szDb>=0 ){ + *pSize = pFile->szDb; + }else{ + *pSize = kvvfsReadFileSize(pFile); + } + return SQLITE_OK; +} + +/* +** Lock an kvvfs-file. +*/ +static int kvvfsLock(sqlite3_file *pProtoFile, int eLock){ + KVVfsFile *pFile = (KVVfsFile *)pProtoFile; + assert( !pFile->isJournal ); + SQLITE_KV_LOG(("xLock(%s,%d)\n", pFile->zClass, eLock)); + + if( eLock!=SQLITE_LOCK_NONE ){ + pFile->szDb = kvvfsReadFileSize(pFile); + } + return SQLITE_OK; +} + +/* +** Unlock an kvvfs-file. +*/ +static int kvvfsUnlock(sqlite3_file *pProtoFile, int eLock){ + KVVfsFile *pFile = (KVVfsFile *)pProtoFile; + assert( !pFile->isJournal ); + SQLITE_KV_LOG(("xUnlock(%s,%d)\n", pFile->zClass, eLock)); + if( eLock==SQLITE_LOCK_NONE ){ + pFile->szDb = -1; + } + return SQLITE_OK; +} + +/* +** Check if another file-handle holds a RESERVED lock on an kvvfs-file. +*/ +static int kvvfsCheckReservedLock(sqlite3_file *pProtoFile, int *pResOut){ + SQLITE_KV_LOG(("xCheckReservedLock\n")); + *pResOut = 0; + return SQLITE_OK; +} + +/* +** File control method. For custom operations on an kvvfs-file. +*/ +static int kvvfsFileControlJrnl(sqlite3_file *pProtoFile, int op, void *pArg){ + SQLITE_KV_LOG(("xFileControl(%d) on journal\n", op)); + return SQLITE_NOTFOUND; +} +static int kvvfsFileControlDb(sqlite3_file *pProtoFile, int op, void *pArg){ + SQLITE_KV_LOG(("xFileControl(%d) on database\n", op)); + if( op==SQLITE_FCNTL_SYNC ){ + KVVfsFile *pFile = (KVVfsFile *)pProtoFile; + int rc = SQLITE_OK; + SQLITE_KV_LOG(("xSync('%s-db')\n", pFile->zClass)); + if( pFile->szDb>0 && 0!=kvvfsWriteFileSize(pFile, pFile->szDb) ){ + rc = SQLITE_IOERR; + } + return rc; + } + return SQLITE_NOTFOUND; +} + +/* +** Return the sector-size in bytes for an kvvfs-file. +*/ +static int kvvfsSectorSize(sqlite3_file *pFile){ + return 512; +} + +/* +** Return the device characteristic flags supported by an kvvfs-file. +*/ +static int kvvfsDeviceCharacteristics(sqlite3_file *pProtoFile){ + return 0; +} + +/****** sqlite3_vfs methods *************************************************/ + +/* +** Open an kvvfs file handle. +*/ +static int kvvfsOpen( + sqlite3_vfs *pProtoVfs, + const char *zName, + sqlite3_file *pProtoFile, + int flags, + int *pOutFlags +){ + KVVfsFile *pFile = (KVVfsFile*)pProtoFile; + if( zName==0 ) zName = ""; + SQLITE_KV_LOG(("xOpen(\"%s\")\n", zName)); + assert(!pFile->zClass); + assert(!pFile->aData); + assert(!pFile->aJrnl); + assert(!pFile->nJrnl); + assert(!pFile->base.pMethods); + pFile->szPage = -1; + pFile->szDb = -1; + if( 0==sqlite3_strglob("*-journal", zName) ){ + pFile->isJournal = 1; + pFile->base.pMethods = &kvvfs_jrnl_io_methods; + if( 0==strcmp("session-journal",zName) ){ + pFile->zClass = "session"; + }else if( 0==strcmp("local-journal",zName) ){ + pFile->zClass = "local"; + } + }else{ + pFile->isJournal = 0; + pFile->base.pMethods = &kvvfs_db_io_methods; + } + if( !pFile->zClass ){ + pFile->zClass = zName; + } + pFile->aData = sqlite3_malloc64(SQLITE_KVOS_SZ); + if( pFile->aData==0 ){ + return SQLITE_NOMEM; + } + return SQLITE_OK; +} + +/* +** Delete the file located at zPath. If the dirSync argument is true, +** ensure the file-system modifications are synced to disk before +** returning. +*/ +static int kvvfsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ + int rc /* The JS impl can fail with OOM in argument conversion */; + if( strcmp(zPath, "local-journal")==0 ){ + rc = sqlite3KvvfsMethods.xRcrdDelete("local", "jrnl"); + }else + if( strcmp(zPath, "session-journal")==0 ){ + rc = sqlite3KvvfsMethods.xRcrdDelete("session", "jrnl"); + } + else{ + rc = 0; + } + return rc; +} + +/* +** Test for access permissions. Return true if the requested permission +** is available, or false otherwise. +*/ +static int kvvfsAccess( + sqlite3_vfs *pProtoVfs, + const char *zPath, + int flags, + int *pResOut +){ + SQLITE_KV_LOG(("xAccess(\"%s\")\n", zPath)); +#if 0 && defined(SQLITE_WASM) + /* + ** This is not having the desired effect in the JS bindings. + ** It's ostensibly the same logic as the #else block, but + ** it's not behaving that way. + ** + ** In JS we map all zPaths to Storage objects, and -journal files + ** are mapped to the storage for the main db (which is is exactly + ** what the mapping of "local-journal" -> "local" is doing). + */ + const char *zKey = (0==sqlite3_strglob("*-journal", zPath)) + ? "jrnl" : "sz"; + *pResOut = + sqlite3KvvfsMethods.xRcrdRead(zPath, zKey, 0, 0)>0; +#else + if( strcmp(zPath, "local-journal")==0 ){ + *pResOut = + sqlite3KvvfsMethods.xRcrdRead("local", "jrnl", 0, 0)>0; + }else + if( strcmp(zPath, "session-journal")==0 ){ + *pResOut = + sqlite3KvvfsMethods.xRcrdRead("session", "jrnl", 0, 0)>0; + }else + if( strcmp(zPath, "local")==0 ){ + *pResOut = + sqlite3KvvfsMethods.xRcrdRead("local", "sz", 0, 0)>0; + }else + if( strcmp(zPath, "session")==0 ){ + *pResOut = + sqlite3KvvfsMethods.xRcrdRead("session", "sz", 0, 0)>0; + }else + { + *pResOut = 0; + } + /*all current JS tests avoid triggering: assert( *pResOut == 0 ); */ +#endif + SQLITE_KV_LOG(("xAccess returns %d\n",*pResOut)); + return SQLITE_OK; +} + +/* +** Populate buffer zOut with the full canonical pathname corresponding +** to the pathname in zPath. zOut is guaranteed to point to a buffer +** of at least (INST_MAX_PATHNAME+1) bytes. +*/ +static int kvvfsFullPathname( + sqlite3_vfs *pVfs, + const char *zPath, + int nOut, + char *zOut +){ + size_t nPath; +#ifdef SQLITE_OS_KV_ALWAYS_LOCAL + zPath = "local"; +#endif + nPath = strlen(zPath); + SQLITE_KV_LOG(("xFullPathname(\"%s\")\n", zPath)); + if( nOut +static int kvvfsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){ + static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000; + struct timeval sNow; + (void)gettimeofday(&sNow, 0); /* Cannot fail given valid arguments */ + *pTimeOut = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000; + return SQLITE_OK; +} +#endif /* SQLITE_OS_KV || SQLITE_OS_UNIX */ + +#if SQLITE_OS_KV +/* +** This routine is called initialize the KV-vfs as the default VFS. +*/ +SQLITE_API int sqlite3_os_init(void){ + return sqlite3_vfs_register(&sqlite3OsKvvfsObject, 1); +} +SQLITE_API int sqlite3_os_end(void){ + return SQLITE_OK; +} +#endif /* SQLITE_OS_KV */ + +#if SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL) +SQLITE_PRIVATE int sqlite3KvvfsInit(void){ + return sqlite3_vfs_register(&sqlite3OsKvvfsObject, 0); +} +#endif + +/************** End of os_kv.c ***********************************************/ +/************** Begin file os_unix.c *****************************************/ +/* +** 2004 May 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains the VFS implementation for unix-like operating systems +** include Linux, MacOSX, *BSD, QNX, VxWorks, AIX, HPUX, and others. +** +** There are actually several different VFS implementations in this file. +** The differences are in the way that file locking is done. The default +** implementation uses Posix Advisory Locks. Alternative implementations +** use flock(), dot-files, various proprietary locking schemas, or simply +** skip locking all together. +** +** This source file is organized into divisions where the logic for various +** subfunctions is contained within the appropriate division. PLEASE +** KEEP THE STRUCTURE OF THIS FILE INTACT. New code should be placed +** in the correct division and should be clearly labelled. +** +** The layout of divisions is as follows: +** +** * General-purpose declarations and utility functions. +** * Unique file ID logic used by VxWorks. +** * Various locking primitive implementations (all except proxy locking): +** + for Posix Advisory Locks +** + for no-op locks +** + for dot-file locks +** + for flock() locking +** + for named semaphore locks (VxWorks only) +** + for AFP filesystem locks (MacOSX only) +** * sqlite3_file methods not associated with locking. +** * Definitions of sqlite3_io_methods objects for all locking +** methods plus "finder" functions for each locking method. +** * sqlite3_vfs method implementations. +** * Locking primitives for the proxy uber-locking-method. (MacOSX only) +** * Definitions of sqlite3_vfs objects for all locking methods +** plus implementations of sqlite3_os_init() and sqlite3_os_end(). +*/ +/* #include "sqliteInt.h" */ +#if SQLITE_OS_UNIX /* This file is used on unix only */ + +/* +** There are various methods for file locking used for concurrency +** control: +** +** 1. POSIX locking (the default), +** 2. No locking, +** 3. Dot-file locking, +** 4. flock() locking, +** 5. AFP locking (OSX only), +** 6. Named POSIX semaphores (VXWorks only), +** 7. proxy locking. (OSX only) +** +** Styles 4, 5, and 7 are only available of SQLITE_ENABLE_LOCKING_STYLE +** is defined to 1. The SQLITE_ENABLE_LOCKING_STYLE also enables automatic +** selection of the appropriate locking style based on the filesystem +** where the database is located. +*/ +#if !defined(SQLITE_ENABLE_LOCKING_STYLE) +# if defined(__APPLE__) +# define SQLITE_ENABLE_LOCKING_STYLE 1 +# else +# define SQLITE_ENABLE_LOCKING_STYLE 0 +# endif +#endif + +/* Use pread() and pwrite() if they are available */ +#if defined(__APPLE__) || defined(__linux__) +# define HAVE_PREAD 1 +# define HAVE_PWRITE 1 +#endif +#if defined(HAVE_PREAD64) && defined(HAVE_PWRITE64) +# undef USE_PREAD +# define USE_PREAD64 1 +#elif defined(HAVE_PREAD) && defined(HAVE_PWRITE) +# undef USE_PREAD64 +# define USE_PREAD 1 +#endif + +/* +** standard include files. +*/ +#include /* amalgamator: keep */ +#include /* amalgamator: keep */ +#include +#include +#include /* amalgamator: keep */ +/* #include */ +#include /* amalgamator: keep */ +#include +#if (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) \ + && !defined(SQLITE_WASI) +# include +#endif + +#if SQLITE_ENABLE_LOCKING_STYLE +/* # include */ +# include +# include +#endif /* SQLITE_ENABLE_LOCKING_STYLE */ + +/* +** Try to determine if gethostuuid() is available based on standard +** macros. This might sometimes compute the wrong value for some +** obscure platforms. For those cases, simply compile with one of +** the following: +** +** -DHAVE_GETHOSTUUID=0 +** -DHAVE_GETHOSTUUID=1 +** +** None if this matters except when building on Apple products with +** -DSQLITE_ENABLE_LOCKING_STYLE. +*/ +#ifndef HAVE_GETHOSTUUID +# define HAVE_GETHOSTUUID 0 +# if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \ + (__IPHONE_OS_VERSION_MIN_REQUIRED > 2000)) +# if (!defined(TARGET_OS_EMBEDDED) || (TARGET_OS_EMBEDDED==0)) \ + && (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0))\ + && (!defined(TARGET_OS_MACCATALYST) || (TARGET_OS_MACCATALYST==0)) +# undef HAVE_GETHOSTUUID +# define HAVE_GETHOSTUUID 1 +# else +# warning "gethostuuid() is disabled." +# endif +# endif +#endif + + +#if OS_VXWORKS +/* # include */ +# include +# include +#endif /* OS_VXWORKS */ + +#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE +# include +#endif + +#ifdef HAVE_UTIME +# include +#endif + +/* +** Allowed values of unixFile.fsFlags +*/ +#define SQLITE_FSFLAGS_IS_MSDOS 0x1 + +/* +** If we are to be thread-safe, include the pthreads header. +*/ +#if SQLITE_THREADSAFE +/* # include */ +#endif + +/* +** Default permissions when creating a new file +*/ +#ifndef SQLITE_DEFAULT_FILE_PERMISSIONS +# define SQLITE_DEFAULT_FILE_PERMISSIONS 0644 +#endif + +/* +** Default permissions when creating auto proxy dir +*/ +#ifndef SQLITE_DEFAULT_PROXYDIR_PERMISSIONS +# define SQLITE_DEFAULT_PROXYDIR_PERMISSIONS 0755 +#endif + +/* +** Maximum supported path-length. +*/ +#define MAX_PATHNAME 512 + +/* +** Maximum supported symbolic links +*/ +#define SQLITE_MAX_SYMLINKS 100 + +/* +** Remove and stub certain info for WASI (WebAssembly System +** Interface) builds. +*/ +#ifdef SQLITE_WASI +# undef HAVE_FCHMOD +# undef HAVE_FCHOWN +# undef HAVE_MREMAP +# define HAVE_MREMAP 0 +# ifndef SQLITE_DEFAULT_UNIX_VFS +# define SQLITE_DEFAULT_UNIX_VFS "unix-dotfile" + /* ^^^ should SQLITE_DEFAULT_UNIX_VFS be "unix-none"? */ +# endif +# ifndef F_RDLCK +# define F_RDLCK 0 +# define F_WRLCK 1 +# define F_UNLCK 2 +# if __LONG_MAX == 0x7fffffffL +# define F_GETLK 12 +# define F_SETLK 13 +# define F_SETLKW 14 +# else +# define F_GETLK 5 +# define F_SETLK 6 +# define F_SETLKW 7 +# endif +# endif +#else /* !SQLITE_WASI */ +# ifndef HAVE_FCHMOD +# define HAVE_FCHMOD 1 +# endif +#endif /* SQLITE_WASI */ + +#ifdef SQLITE_WASI +# define osGetpid(X) (pid_t)1 +#else +/* Always cast the getpid() return type for compatibility with +** kernel modules in VxWorks. */ +# define osGetpid(X) (pid_t)getpid() +#endif + +/* +** Only set the lastErrno if the error code is a real error and not +** a normal expected return code of SQLITE_BUSY or SQLITE_OK +*/ +#define IS_LOCK_ERROR(x) ((x != SQLITE_OK) && (x != SQLITE_BUSY)) + +/* Forward references */ +typedef struct unixShm unixShm; /* Connection shared memory */ +typedef struct unixShmNode unixShmNode; /* Shared memory instance */ +typedef struct unixInodeInfo unixInodeInfo; /* An i-node */ +typedef struct UnixUnusedFd UnixUnusedFd; /* An unused file descriptor */ + +/* +** Sometimes, after a file handle is closed by SQLite, the file descriptor +** cannot be closed immediately. In these cases, instances of the following +** structure are used to store the file descriptor while waiting for an +** opportunity to either close or reuse it. +*/ +struct UnixUnusedFd { + int fd; /* File descriptor to close */ + int flags; /* Flags this file descriptor was opened with */ + UnixUnusedFd *pNext; /* Next unused file descriptor on same file */ +}; + +/* +** The unixFile structure is subclass of sqlite3_file specific to the unix +** VFS implementations. +*/ +typedef struct unixFile unixFile; +struct unixFile { + sqlite3_io_methods const *pMethod; /* Always the first entry */ + sqlite3_vfs *pVfs; /* The VFS that created this unixFile */ + unixInodeInfo *pInode; /* Info about locks on this inode */ + int h; /* The file descriptor */ + unsigned char eFileLock; /* The type of lock held on this fd */ + unsigned short int ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */ + int lastErrno; /* The unix errno from last I/O error */ + void *lockingContext; /* Locking style specific state */ + UnixUnusedFd *pPreallocatedUnused; /* Pre-allocated UnixUnusedFd */ + const char *zPath; /* Name of the file */ + unixShm *pShm; /* Shared memory segment information */ + int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ +#if SQLITE_MAX_MMAP_SIZE>0 + int nFetchOut; /* Number of outstanding xFetch refs */ + sqlite3_int64 mmapSize; /* Usable size of mapping at pMapRegion */ + sqlite3_int64 mmapSizeActual; /* Actual size of mapping at pMapRegion */ + sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */ + void *pMapRegion; /* Memory mapped region */ +#endif + int sectorSize; /* Device sector size */ + int deviceCharacteristics; /* Precomputed device characteristics */ +#if SQLITE_ENABLE_LOCKING_STYLE + int openFlags; /* The flags specified at open() */ +#endif +#if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__) + unsigned fsFlags; /* cached details from statfs() */ +#endif +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + unsigned iBusyTimeout; /* Wait this many millisec on locks */ + int bBlockOnConnect; /* True to block for SHARED locks */ +#endif +#if OS_VXWORKS + struct vxworksFileId *pId; /* Unique file ID */ +#endif +#ifdef SQLITE_DEBUG + /* The next group of variables are used to track whether or not the + ** transaction counter in bytes 24-27 of database files are updated + ** whenever any part of the database changes. An assertion fault will + ** occur if a file is updated without also updating the transaction + ** counter. This test is made to avoid new problems similar to the + ** one described by ticket #3584. + */ + unsigned char transCntrChng; /* True if the transaction counter changed */ + unsigned char dbUpdate; /* True if any part of database file changed */ + unsigned char inNormalWrite; /* True if in a normal write operation */ + +#endif + +#ifdef SQLITE_TEST + /* In test mode, increase the size of this structure a bit so that + ** it is larger than the struct CrashFile defined in test6.c. + */ + char aPadding[32]; +#endif +}; + +/* This variable holds the process id (pid) from when the xRandomness() +** method was called. If xOpen() is called from a different process id, +** indicating that a fork() has occurred, the PRNG will be reset. +*/ +static pid_t randomnessPid = 0; + +/* +** Allowed values for the unixFile.ctrlFlags bitmask: +*/ +#define UNIXFILE_EXCL 0x01 /* Connections from one process only */ +#define UNIXFILE_RDONLY 0x02 /* Connection is read only */ +#define UNIXFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ +#if !defined(SQLITE_DISABLE_DIRSYNC) && !defined(_AIX) +# define UNIXFILE_DIRSYNC 0x08 /* Directory sync needed */ +#else +# define UNIXFILE_DIRSYNC 0x00 +#endif +#define UNIXFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ +#define UNIXFILE_DELETE 0x20 /* Delete on close */ +#define UNIXFILE_URI 0x40 /* Filename might have query parameters */ +#define UNIXFILE_NOLOCK 0x80 /* Do no file locking */ + +/* +** Include code that is common to all os_*.c files +*/ +/* #include "os_common.h" */ + +/* +** Define various macros that are missing from some systems. +*/ +#ifndef O_LARGEFILE +# define O_LARGEFILE 0 +#endif +#ifdef SQLITE_DISABLE_LFS +# undef O_LARGEFILE +# define O_LARGEFILE 0 +#endif +#ifndef O_NOFOLLOW +# define O_NOFOLLOW 0 +#endif +#ifndef O_BINARY +# define O_BINARY 0 +#endif + +/* +** The threadid macro resolves to the thread-id or to 0. Used for +** testing and debugging only. +*/ +#if SQLITE_THREADSAFE +#define threadid pthread_self() +#else +#define threadid 0 +#endif + +/* +** HAVE_MREMAP defaults to true on Linux and false everywhere else. +*/ +#if !defined(HAVE_MREMAP) +# if defined(__linux__) && defined(_GNU_SOURCE) +# define HAVE_MREMAP 1 +# else +# define HAVE_MREMAP 0 +# endif +#endif + +/* +** Explicitly call the 64-bit version of lseek() on Android. Otherwise, lseek() +** is the 32-bit version, even if _FILE_OFFSET_BITS=64 is defined. +*/ +#ifdef __ANDROID__ +# define lseek lseek64 +#endif + +#ifdef __linux__ +/* +** Linux-specific IOCTL magic numbers used for controlling F2FS +*/ +#define F2FS_IOCTL_MAGIC 0xf5 +#define F2FS_IOC_START_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 1) +#define F2FS_IOC_COMMIT_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 2) +#define F2FS_IOC_START_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 3) +#define F2FS_IOC_ABORT_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 5) +#define F2FS_IOC_GET_FEATURES _IOR(F2FS_IOCTL_MAGIC, 12, u32) +#define F2FS_FEATURE_ATOMIC_WRITE 0x0004 +#endif /* __linux__ */ + + +/* +** Different Unix systems declare open() in different ways. Same use +** open(const char*,int,mode_t). Others use open(const char*,int,...). +** The difference is important when using a pointer to the function. +** +** The safest way to deal with the problem is to always use this wrapper +** which always has the same well-defined interface. +*/ +static int posixOpen(const char *zFile, int flags, int mode){ + return open(zFile, flags, mode); +} + +/* Forward reference */ +static int openDirectory(const char*, int*); +static int unixGetpagesize(void); + +/* +** Many system calls are accessed through pointer-to-functions so that +** they may be overridden at runtime to facilitate fault injection during +** testing and sandboxing. The following array holds the names and pointers +** to all overrideable system calls. +*/ +static struct unix_syscall { + const char *zName; /* Name of the system call */ + sqlite3_syscall_ptr pCurrent; /* Current value of the system call */ + sqlite3_syscall_ptr pDefault; /* Default value */ +} aSyscall[] = { + { "open", (sqlite3_syscall_ptr)posixOpen, 0 }, +#define osOpen ((int(*)(const char*,int,int))aSyscall[0].pCurrent) + + { "close", (sqlite3_syscall_ptr)close, 0 }, +#define osClose ((int(*)(int))aSyscall[1].pCurrent) + + { "access", (sqlite3_syscall_ptr)access, 0 }, +#define osAccess ((int(*)(const char*,int))aSyscall[2].pCurrent) + + { "getcwd", (sqlite3_syscall_ptr)getcwd, 0 }, +#define osGetcwd ((char*(*)(char*,size_t))aSyscall[3].pCurrent) + + { "stat", (sqlite3_syscall_ptr)stat, 0 }, +#define osStat ((int(*)(const char*,struct stat*))aSyscall[4].pCurrent) + +/* +** The DJGPP compiler environment looks mostly like Unix, but it +** lacks the fcntl() system call. So redefine fcntl() to be something +** that always succeeds. This means that locking does not occur under +** DJGPP. But it is DOS - what did you expect? +*/ +#ifdef __DJGPP__ + { "fstat", 0, 0 }, +#define osFstat(a,b,c) 0 +#else + { "fstat", (sqlite3_syscall_ptr)fstat, 0 }, +#define osFstat ((int(*)(int,struct stat*))aSyscall[5].pCurrent) +#endif + + { "ftruncate", (sqlite3_syscall_ptr)ftruncate, 0 }, +#define osFtruncate ((int(*)(int,off_t))aSyscall[6].pCurrent) + + { "fcntl", (sqlite3_syscall_ptr)fcntl, 0 }, +#define osFcntl ((int(*)(int,int,...))aSyscall[7].pCurrent) + + { "read", (sqlite3_syscall_ptr)read, 0 }, +#define osRead ((ssize_t(*)(int,void*,size_t))aSyscall[8].pCurrent) + +#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE + { "pread", (sqlite3_syscall_ptr)pread, 0 }, +#else + { "pread", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osPread ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[9].pCurrent) + +#if defined(USE_PREAD64) + { "pread64", (sqlite3_syscall_ptr)pread64, 0 }, +#else + { "pread64", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osPread64 ((ssize_t(*)(int,void*,size_t,off64_t))aSyscall[10].pCurrent) + + { "write", (sqlite3_syscall_ptr)write, 0 }, +#define osWrite ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent) + +#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE + { "pwrite", (sqlite3_syscall_ptr)pwrite, 0 }, +#else + { "pwrite", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osPwrite ((ssize_t(*)(int,const void*,size_t,off_t))\ + aSyscall[12].pCurrent) + +#if defined(USE_PREAD64) + { "pwrite64", (sqlite3_syscall_ptr)pwrite64, 0 }, +#else + { "pwrite64", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off64_t))\ + aSyscall[13].pCurrent) + +#if defined(HAVE_FCHMOD) + { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 }, +#define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent) +#else + { "fchmod", (sqlite3_syscall_ptr)0, 0 }, +#define osFchmod(FID,MODE) 0 +#endif + +#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE + { "fallocate", (sqlite3_syscall_ptr)posix_fallocate, 0 }, +#else + { "fallocate", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osFallocate ((int(*)(int,off_t,off_t))aSyscall[15].pCurrent) + + { "unlink", (sqlite3_syscall_ptr)unlink, 0 }, +#define osUnlink ((int(*)(const char*))aSyscall[16].pCurrent) + + { "openDirectory", (sqlite3_syscall_ptr)openDirectory, 0 }, +#define osOpenDirectory ((int(*)(const char*,int*))aSyscall[17].pCurrent) + + { "mkdir", (sqlite3_syscall_ptr)mkdir, 0 }, +#define osMkdir ((int(*)(const char*,mode_t))aSyscall[18].pCurrent) + + { "rmdir", (sqlite3_syscall_ptr)rmdir, 0 }, +#define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent) + +#if defined(HAVE_FCHOWN) + { "fchown", (sqlite3_syscall_ptr)fchown, 0 }, +#else + { "fchown", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent) + +#if defined(HAVE_FCHOWN) + { "geteuid", (sqlite3_syscall_ptr)geteuid, 0 }, +#else + { "geteuid", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osGeteuid ((uid_t(*)(void))aSyscall[21].pCurrent) + +#if (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) \ + && !defined(SQLITE_WASI) + { "mmap", (sqlite3_syscall_ptr)mmap, 0 }, +#else + { "mmap", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[22].pCurrent) + +#if (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) \ + && !defined(SQLITE_WASI) + { "munmap", (sqlite3_syscall_ptr)munmap, 0 }, +#else + { "munmap", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osMunmap ((int(*)(void*,size_t))aSyscall[23].pCurrent) + +#if HAVE_MREMAP && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) + { "mremap", (sqlite3_syscall_ptr)mremap, 0 }, +#else + { "mremap", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[24].pCurrent) + +#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 + { "getpagesize", (sqlite3_syscall_ptr)unixGetpagesize, 0 }, +#else + { "getpagesize", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osGetpagesize ((int(*)(void))aSyscall[25].pCurrent) + +#if defined(HAVE_READLINK) + { "readlink", (sqlite3_syscall_ptr)readlink, 0 }, +#else + { "readlink", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[26].pCurrent) + +#if defined(HAVE_LSTAT) + { "lstat", (sqlite3_syscall_ptr)lstat, 0 }, +#else + { "lstat", (sqlite3_syscall_ptr)0, 0 }, +#endif +#define osLstat ((int(*)(const char*,struct stat*))aSyscall[27].pCurrent) + +#if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) +# ifdef __ANDROID__ + { "ioctl", (sqlite3_syscall_ptr)(int(*)(int, int, ...))ioctl, 0 }, +#define osIoctl ((int(*)(int,int,...))aSyscall[28].pCurrent) +# else + { "ioctl", (sqlite3_syscall_ptr)ioctl, 0 }, +#define osIoctl ((int(*)(int,unsigned long,...))aSyscall[28].pCurrent) +# endif +#else + { "ioctl", (sqlite3_syscall_ptr)0, 0 }, +#endif + +}; /* End of the overrideable system calls */ + + +#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT) +/* +** Extract Posix Advisory Locking information about file description fd +** from the /proc/PID/fdinfo/FD pseudo-file. Fill the string buffer a[16] +** with characters to indicate which SQLite-relevant locks are held. +** a[16] will be a 15-character zero-terminated string with the following +** schema: +** +** AAA/B.DDD.DDDDD +** +** Each of character A-D will be "w" or "r" or "-" to indicate either a +** write-lock, a read-lock, or no-lock, respectively. The "." and "/" +** characters are delimiters intended to make the string more easily +** readable by humans. Here are the meaning of the specific letters: +** +** AAA -> The main database locks. PENDING_BYTE, RESERVED_BYTE, +** and SHARED_FIRST, respectively. +** +** B -> The deadman switch lock. Offset 128 of the -shm file. +** +** CCC -> WAL locks: WRITE, CKPT, RECOVER +** +** DDDDD -> WAL read-locks 0 through 5 +** +** Note that elements before the "/" apply to the main database file and +** elements after the "/" apply to the -shm file in WAL mode. +** +** Here is another way of thinking about the meaning of the result string: +** +** AAA/B.CCC.DDDDD +** ||| | ||| \___/ +** PENDING--'|| | ||| `----- READ 0-5 +** RESERVED--'| | ||`---- RECOVER +** SHARED ----' | |`----- CKPT +** DMS ------' `------ WRITE +** +** Return SQLITE_OK on success and SQLITE_ERROR_UNABLE if the /proc +** pseudo-filesystem is unavailable. +*/ +static int unixPosixAdvisoryLocks( + int fd, /* The file descriptor to analyze */ + char a[16] /* Write a text description of PALs here */ +){ + int in; + ssize_t n; + char *p, *pNext, *x; + char z[2000]; + + /* 1 */ + /* 012 4 678 01234 */ + memcpy(a, "---/-.---.-----", 16); + sqlite3_snprintf(sizeof(z), z, "/proc/%d/fdinfo/%d", getpid(), fd); + in = osOpen(z, O_RDONLY, 0); + if( in<0 ){ + return SQLITE_ERROR_UNABLE; + } + n = osRead(in, z, sizeof(z)-1); + osClose(in); + if( n<=0 ) return SQLITE_ERROR_UNABLE; + z[n] = 0; + + /* We are looking for lines that begin with "lock:\t". Examples: + ** + ** lock: 1: POSIX ADVISORY READ 494716 08:02:5277597 1073741826 1073742335 + ** lock: 1: POSIX ADVISORY WRITE 494716 08:02:5282282 120 120 + ** lock: 2: POSIX ADVISORY READ 494716 08:02:5282282 123 123 + ** lock: 3: POSIX ADVISORY READ 494716 08:02:5282282 128 128 + */ + pNext = strstr(z, "lock:\t"); + while( pNext ){ + char cType = 0; + sqlite3_int64 iFirst, iLast; + p = pNext+6; + pNext = strstr(p, "lock:\t"); + if( pNext ) pNext[-1] = 0; + if( (x = strstr(p, " READ "))!=0 ){ + cType = 'r'; + x += 6; + }else if( (x = strstr(p, " WRITE "))!=0 ){ + cType = 'w'; + x += 7; + }else{ + continue; + } + x = strrchr(x, ' '); + if( x==0 ) continue; + iLast = strtoll(x+1, 0, 10); + *x = 0; + x = strrchr(p, ' '); + if( x==0 ) continue; + iFirst = strtoll(x+1, 0, 10); + if( iLast>=PENDING_BYTE ){ + if( iFirst<=PENDING_BYTE && iLast>=PENDING_BYTE ) a[0] = cType; + if( iFirst<=PENDING_BYTE+1 && iLast>=PENDING_BYTE+1 ) a[1] = cType; + if( iFirst<=PENDING_BYTE+2 && iLast>=PENDING_BYTE+510 ) a[2] = cType; + }else if( iLast<=128 ){ + if( iFirst<=128 && iLast>=128 ) a[4] = cType; + if( iFirst<=120 && iLast>=120 ) a[6] = cType; + if( iFirst<=121 && iLast>=121 ) a[7] = cType; + if( iFirst<=122 && iLast>=122 ) a[8] = cType; + if( iFirst<=123 && iLast>=123 ) a[10] = cType; + if( iFirst<=124 && iLast>=124 ) a[11] = cType; + if( iFirst<=125 && iLast>=125 ) a[12] = cType; + if( iFirst<=126 && iLast>=126 ) a[13] = cType; + if( iFirst<=127 && iLast>=127 ) a[14] = cType; + } + } + return SQLITE_OK; +} +#else +# define unixPosixAdvisoryLocks(A,B) SQLITE_ERROR_UNABLE +#endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */ + +/* +** On some systems, calls to fchown() will trigger a message in a security +** log if they come from non-root processes. So avoid calling fchown() if +** we are not running as root. +*/ +static int robustFchown(int fd, uid_t uid, gid_t gid){ +#if defined(HAVE_FCHOWN) + return osGeteuid() ? 0 : osFchown(fd,uid,gid); +#else + return 0; +#endif +} + +/* +** This is the xSetSystemCall() method of sqlite3_vfs for all of the +** "unix" VFSes. Return SQLITE_OK upon successfully updating the +** system call pointer, or SQLITE_NOTFOUND if there is no configurable +** system call named zName. +*/ +static int unixSetSystemCall( + sqlite3_vfs *pNotUsed, /* The VFS pointer. Not used */ + const char *zName, /* Name of system call to override */ + sqlite3_syscall_ptr pNewFunc /* Pointer to new system call value */ +){ + unsigned int i; + int rc = SQLITE_NOTFOUND; + + UNUSED_PARAMETER(pNotUsed); + if( zName==0 ){ + /* If no zName is given, restore all system calls to their default + ** settings and return NULL + */ + rc = SQLITE_OK; + for(i=0; i=SQLITE_MINIMUM_FILE_DESCRIPTOR ) break; + if( (f & (O_EXCL|O_CREAT))==(O_EXCL|O_CREAT) ){ + (void)osUnlink(z); + } + osClose(fd); + sqlite3_log(SQLITE_WARNING, + "attempt to open \"%s\" as file descriptor %d", z, fd); + fd = -1; + if( osOpen("/dev/null", O_RDONLY, m)<0 ) break; + } + if( fd>=0 ){ + if( m!=0 ){ + struct stat statbuf; + if( osFstat(fd, &statbuf)==0 + && statbuf.st_size==0 + && (statbuf.st_mode&0777)!=m + ){ + osFchmod(fd, m); + } + } +#if defined(FD_CLOEXEC) && (!defined(O_CLOEXEC) || O_CLOEXEC==0) + osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC); +#endif + } + return fd; +} + +/* +** Helper functions to obtain and relinquish the global mutex. The +** global mutex is used to protect the unixInodeInfo objects used by +** this file, all of which may be shared by multiple threads. +** +** Function unixMutexHeld() is used to assert() that the global mutex +** is held when required. This function is only used as part of assert() +** statements. e.g. +** +** unixEnterMutex() +** assert( unixMutexHeld() ); +** unixEnterLeave() +** +** To prevent deadlock, the global unixBigLock must must be acquired +** before the unixInodeInfo.pLockMutex mutex, if both are held. It is +** OK to get the pLockMutex without holding unixBigLock first, but if +** that happens, the unixBigLock mutex must not be acquired until after +** pLockMutex is released. +** +** OK: enter(unixBigLock), enter(pLockInfo) +** OK: enter(unixBigLock) +** OK: enter(pLockInfo) +** ERROR: enter(pLockInfo), enter(unixBigLock) +*/ +static sqlite3_mutex *unixBigLock = 0; +static void unixEnterMutex(void){ + assert( sqlite3_mutex_notheld(unixBigLock) ); /* Not a recursive mutex */ + sqlite3_mutex_enter(unixBigLock); +} +static void unixLeaveMutex(void){ + assert( sqlite3_mutex_held(unixBigLock) ); + sqlite3_mutex_leave(unixBigLock); +} +#ifdef SQLITE_DEBUG +static int unixMutexHeld(void) { + return sqlite3_mutex_held(unixBigLock); +} +#endif + + +#ifdef SQLITE_HAVE_OS_TRACE +/* +** Helper function for printing out trace information from debugging +** binaries. This returns the string representation of the supplied +** integer lock-type. +*/ +static const char *azFileLock(int eFileLock){ + switch( eFileLock ){ + case NO_LOCK: return "NONE"; + case SHARED_LOCK: return "SHARED"; + case RESERVED_LOCK: return "RESERVED"; + case PENDING_LOCK: return "PENDING"; + case EXCLUSIVE_LOCK: return "EXCLUSIVE"; + } + return "ERROR"; +} +#endif + +#ifdef SQLITE_LOCK_TRACE +/* +** Print out information about all locking operations. +** +** This routine is used for troubleshooting locks on multithreaded +** platforms. Enable by compiling with the -DSQLITE_LOCK_TRACE +** command-line option on the compiler. This code is normally +** turned off. +*/ +static int lockTrace(int fd, int op, struct flock *p){ + char *zOpName, *zType; + int s; + int savedErrno; + if( op==F_GETLK ){ + zOpName = "GETLK"; + }else if( op==F_SETLK ){ + zOpName = "SETLK"; + }else{ + s = osFcntl(fd, op, p); + sqlite3DebugPrintf("fcntl unknown %d %d %d\n", fd, op, s); + return s; + } + if( p->l_type==F_RDLCK ){ + zType = "RDLCK"; + }else if( p->l_type==F_WRLCK ){ + zType = "WRLCK"; + }else if( p->l_type==F_UNLCK ){ + zType = "UNLCK"; + }else{ + assert( 0 ); + } + assert( p->l_whence==SEEK_SET ); + s = osFcntl(fd, op, p); + savedErrno = errno; + sqlite3DebugPrintf("fcntl %d %d %s %s %d %d %d %d\n", + threadid, fd, zOpName, zType, (int)p->l_start, (int)p->l_len, + (int)p->l_pid, s); + if( s==(-1) && op==F_SETLK && (p->l_type==F_RDLCK || p->l_type==F_WRLCK) ){ + struct flock l2; + l2 = *p; + osFcntl(fd, F_GETLK, &l2); + if( l2.l_type==F_RDLCK ){ + zType = "RDLCK"; + }else if( l2.l_type==F_WRLCK ){ + zType = "WRLCK"; + }else if( l2.l_type==F_UNLCK ){ + zType = "UNLCK"; + }else{ + assert( 0 ); + } + sqlite3DebugPrintf("fcntl-failure-reason: %s %d %d %d\n", + zType, (int)l2.l_start, (int)l2.l_len, (int)l2.l_pid); + } + errno = savedErrno; + return s; +} +#undef osFcntl +#define osFcntl lockTrace +#endif /* SQLITE_LOCK_TRACE */ + +/* +** Retry ftruncate() calls that fail due to EINTR +** +** All calls to ftruncate() within this file should be made through +** this wrapper. On the Android platform, bypassing the logic below +** could lead to a corrupt database. +*/ +static int robust_ftruncate(int h, sqlite3_int64 sz){ + int rc; +#ifdef __ANDROID__ + /* On Android, ftruncate() always uses 32-bit offsets, even if + ** _FILE_OFFSET_BITS=64 is defined. This means it is unsafe to attempt to + ** truncate a file to any size larger than 2GiB. Silently ignore any + ** such attempts. */ + if( sz>(sqlite3_int64)0x7FFFFFFF ){ + rc = SQLITE_OK; + }else +#endif + do{ rc = osFtruncate(h,sz); }while( rc<0 && errno==EINTR ); + return rc; +} + +/* +** This routine translates a standard POSIX errno code into something +** useful to the clients of the sqlite3 functions. Specifically, it is +** intended to translate a variety of "try again" errors into SQLITE_BUSY +** and a variety of "please close the file descriptor NOW" errors into +** SQLITE_IOERR +** +** Errors during initialization of locks, or file system support for locks, +** should handle ENOLCK, ENOTSUP, EOPNOTSUPP separately. +*/ +static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) { + assert( (sqliteIOErr == SQLITE_IOERR_LOCK) || + (sqliteIOErr == SQLITE_IOERR_UNLOCK) || + (sqliteIOErr == SQLITE_IOERR_RDLOCK) || + (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ); + switch (posixError) { + case EACCES: + case EAGAIN: + case ETIMEDOUT: + case EBUSY: + case EINTR: + case ENOLCK: + /* random NFS retry error, unless during file system support + * introspection, in which it actually means what it says */ + return SQLITE_BUSY; + + case EPERM: + return SQLITE_PERM; + + default: + return sqliteIOErr; + } +} + + +/****************************************************************************** +****************** Begin Unique File ID Utility Used By VxWorks *************** +** +** On most versions of unix, we can get a unique ID for a file by concatenating +** the device number and the inode number. But this does not work on VxWorks. +** On VxWorks, a unique file id must be based on the canonical filename. +** +** A pointer to an instance of the following structure can be used as a +** unique file ID in VxWorks. Each instance of this structure contains +** a copy of the canonical filename. There is also a reference count. +** The structure is reclaimed when the number of pointers to it drops to +** zero. +** +** There are never very many files open at one time and lookups are not +** a performance-critical path, so it is sufficient to put these +** structures on a linked list. +*/ +struct vxworksFileId { + struct vxworksFileId *pNext; /* Next in a list of them all */ + int nRef; /* Number of references to this one */ + int nName; /* Length of the zCanonicalName[] string */ + char *zCanonicalName; /* Canonical filename */ +}; + +#if OS_VXWORKS +/* +** All unique filenames are held on a linked list headed by this +** variable: +*/ +static struct vxworksFileId *vxworksFileList = 0; +static sqlite3_mutex *vxworksMutex = 0; + +/* +** Simplify a filename into its canonical form +** by making the following changes: +** +** * removing any trailing and duplicate / +** * convert /./ into just / +** * convert /A/../ where A is any simple name into just / +** +** Changes are made in-place. Return the new name length. +** +** The original filename is in z[0..n-1]. Return the number of +** characters in the simplified name. +*/ +static int vxworksSimplifyName(char *z, int n){ + int i, j; + while( n>1 && z[n-1]=='/' ){ n--; } + for(i=j=0; i0 && z[j-1]!='/' ){ j--; } + if( j>0 ){ j--; } + i += 2; + continue; + } + } + z[j++] = z[i]; + } + z[j] = 0; + return j; +} + +/* +** Find a unique file ID for the given absolute pathname. Return +** a pointer to the vxworksFileId object. This pointer is the unique +** file ID. +** +** The nRef field of the vxworksFileId object is incremented before +** the object is returned. A new vxworksFileId object is created +** and added to the global list if necessary. +** +** If a memory allocation error occurs, return NULL. +*/ +static struct vxworksFileId *vxworksFindFileId(const char *zAbsoluteName){ + struct vxworksFileId *pNew; /* search key and new file ID */ + struct vxworksFileId *pCandidate; /* For looping over existing file IDs */ + int n; /* Length of zAbsoluteName string */ + + assert( zAbsoluteName[0]=='/' ); + n = (int)strlen(zAbsoluteName); + pNew = sqlite3_malloc64( sizeof(*pNew) + (n+1) ); + if( pNew==0 ) return 0; + pNew->zCanonicalName = (char*)&pNew[1]; + memcpy(pNew->zCanonicalName, zAbsoluteName, n+1); + n = vxworksSimplifyName(pNew->zCanonicalName, n); + + /* Search for an existing entry that matching the canonical name. + ** If found, increment the reference count and return a pointer to + ** the existing file ID. + */ + sqlite3_mutex_enter(vxworksMutex); + for(pCandidate=vxworksFileList; pCandidate; pCandidate=pCandidate->pNext){ + if( pCandidate->nName==n + && memcmp(pCandidate->zCanonicalName, pNew->zCanonicalName, n)==0 + ){ + sqlite3_free(pNew); + pCandidate->nRef++; + sqlite3_mutex_leave(vxworksMutex); + return pCandidate; + } + } + + /* No match was found. We will make a new file ID */ + pNew->nRef = 1; + pNew->nName = n; + pNew->pNext = vxworksFileList; + vxworksFileList = pNew; + sqlite3_mutex_leave(vxworksMutex); + return pNew; +} + +/* +** Decrement the reference count on a vxworksFileId object. Free +** the object when the reference count reaches zero. +*/ +static void vxworksReleaseFileId(struct vxworksFileId *pId){ + sqlite3_mutex_enter(vxworksMutex); + assert( pId->nRef>0 ); + pId->nRef--; + if( pId->nRef==0 ){ + struct vxworksFileId **pp; + for(pp=&vxworksFileList; *pp && *pp!=pId; pp = &((*pp)->pNext)){} + assert( *pp==pId ); + *pp = pId->pNext; + sqlite3_free(pId); + } + sqlite3_mutex_leave(vxworksMutex); +} +#endif /* OS_VXWORKS */ +/*************** End of Unique File ID Utility Used By VxWorks **************** +******************************************************************************/ + + +/****************************************************************************** +*************************** Posix Advisory Locking **************************** +** +** POSIX advisory locks are broken by design. ANSI STD 1003.1 (1996) +** section 6.5.2.2 lines 483 through 490 specify that when a process +** sets or clears a lock, that operation overrides any prior locks set +** by the same process. It does not explicitly say so, but this implies +** that it overrides locks set by the same process using a different +** file descriptor. Consider this test case: +** +** int fd1 = open("./file1", O_RDWR|O_CREAT, 0644); +** int fd2 = open("./file2", O_RDWR|O_CREAT, 0644); +** +** Suppose ./file1 and ./file2 are really the same file (because +** one is a hard or symbolic link to the other) then if you set +** an exclusive lock on fd1, then try to get an exclusive lock +** on fd2, it works. I would have expected the second lock to +** fail since there was already a lock on the file due to fd1. +** But not so. Since both locks came from the same process, the +** second overrides the first, even though they were on different +** file descriptors opened on different file names. +** +** This means that we cannot use POSIX locks to synchronize file access +** among competing threads of the same process. POSIX locks will work fine +** to synchronize access for threads in separate processes, but not +** threads within the same process. +** +** To work around the problem, SQLite has to manage file locks internally +** on its own. Whenever a new database is opened, we have to find the +** specific inode of the database file (the inode is determined by the +** st_dev and st_ino fields of the stat structure that fstat() fills in) +** and check for locks already existing on that inode. When locks are +** created or removed, we have to look at our own internal record of the +** locks to see if another thread has previously set a lock on that same +** inode. +** +** (Aside: The use of inode numbers as unique IDs does not work on VxWorks. +** For VxWorks, we have to use the alternative unique ID system based on +** canonical filename and implemented in the previous division.) +** +** The sqlite3_file structure for POSIX is no longer just an integer file +** descriptor. It is now a structure that holds the integer file +** descriptor and a pointer to a structure that describes the internal +** locks on the corresponding inode. There is one locking structure +** per inode, so if the same inode is opened twice, both unixFile structures +** point to the same locking structure. The locking structure keeps +** a reference count (so we will know when to delete it) and a "cnt" +** field that tells us its internal lock status. cnt==0 means the +** file is unlocked. cnt==-1 means the file has an exclusive lock. +** cnt>0 means there are cnt shared locks on the file. +** +** Any attempt to lock or unlock a file first checks the locking +** structure. The fcntl() system call is only invoked to set a +** POSIX lock if the internal lock structure transitions between +** a locked and an unlocked state. +** +** But wait: there are yet more problems with POSIX advisory locks. +** +** If you close a file descriptor that points to a file that has locks, +** all locks on that file that are owned by the current process are +** released. To work around this problem, each unixInodeInfo object +** maintains a count of the number of pending locks on the inode. +** When an attempt is made to close an unixFile, if there are +** other unixFile open on the same inode that are holding locks, the call +** to close() the file descriptor is deferred until all of the locks clear. +** The unixInodeInfo structure keeps a list of file descriptors that need to +** be closed and that list is walked (and cleared) when the last lock +** clears. +** +** Yet another problem: LinuxThreads do not play well with posix locks. +** +** Many older versions of linux use the LinuxThreads library which is +** not posix compliant. Under LinuxThreads, a lock created by thread +** A cannot be modified or overridden by a different thread B. +** Only thread A can modify the lock. Locking behavior is correct +** if the application uses the newer Native Posix Thread Library (NPTL) +** on linux - with NPTL a lock created by thread A can override locks +** in thread B. But there is no way to know at compile-time which +** threading library is being used. So there is no way to know at +** compile-time whether or not thread A can override locks on thread B. +** One has to do a run-time check to discover the behavior of the +** current process. +** +** SQLite used to support LinuxThreads. But support for LinuxThreads +** was dropped beginning with version 3.7.0. SQLite will still work with +** LinuxThreads provided that (1) there is no more than one connection +** per database file in the same process and (2) database connections +** do not move across threads. +*/ + +/* +** An instance of the following structure serves as the key used +** to locate a particular unixInodeInfo object. +*/ +struct unixFileId { + dev_t dev; /* Device number */ +#if OS_VXWORKS + struct vxworksFileId *pId; /* Unique file ID for vxworks. */ +#else + /* We are told that some versions of Android contain a bug that + ** sizes ino_t at only 32-bits instead of 64-bits. (See + ** https://android-review.googlesource.com/#/c/115351/3/dist/sqlite3.c) + ** To work around this, always allocate 64-bits for the inode number. + ** On small machines that only have 32-bit inodes, this wastes 4 bytes, + ** but that should not be a big deal. */ + /* WAS: ino_t ino; */ + u64 ino; /* Inode number */ +#endif +}; + +/* +** An instance of the following structure is allocated for each open +** inode. +** +** A single inode can have multiple file descriptors, so each unixFile +** structure contains a pointer to an instance of this object and this +** object keeps a count of the number of unixFile pointing to it. +** +** Mutex rules: +** +** (1) Only the pLockMutex mutex must be held in order to read or write +** any of the locking fields: +** nShared, nLock, eFileLock, bProcessLock, pUnused +** +** (2) When nRef>0, then the following fields are unchanging and can +** be read (but not written) without holding any mutex: +** fileId, pLockMutex +** +** (3) With the exceptions above, all the fields may only be read +** or written while holding the global unixBigLock mutex. +** +** Deadlock prevention: The global unixBigLock mutex may not +** be acquired while holding the pLockMutex mutex. If both unixBigLock +** and pLockMutex are needed, then unixBigLock must be acquired first. +*/ +struct unixInodeInfo { + struct unixFileId fileId; /* The lookup key */ + sqlite3_mutex *pLockMutex; /* Hold this mutex for... */ + int nShared; /* Number of SHARED locks held */ + int nLock; /* Number of outstanding file locks */ + unsigned char eFileLock; /* One of SHARED_LOCK, RESERVED_LOCK etc. */ + unsigned char bProcessLock; /* An exclusive process lock is held */ + UnixUnusedFd *pUnused; /* Unused file descriptors to close */ + int nRef; /* Number of pointers to this structure */ + unixShmNode *pShmNode; /* Shared memory associated with this inode */ + unixInodeInfo *pNext; /* List of all unixInodeInfo objects */ + unixInodeInfo *pPrev; /* .... doubly linked */ +#if SQLITE_ENABLE_LOCKING_STYLE + unsigned long long sharedByte; /* for AFP simulated shared lock */ +#endif +#if OS_VXWORKS + sem_t *pSem; /* Named POSIX semaphore */ + char aSemName[MAX_PATHNAME+2]; /* Name of that semaphore */ +#endif +}; + +/* +** A lists of all unixInodeInfo objects. +** +** Must hold unixBigLock in order to read or write this variable. +*/ +static unixInodeInfo *inodeList = 0; /* All unixInodeInfo objects */ + +#ifdef SQLITE_DEBUG +/* +** True if the inode mutex (on the unixFile.pFileMutex field) is held, or not. +** This routine is used only within assert() to help verify correct mutex +** usage. +*/ +int unixFileMutexHeld(unixFile *pFile){ + assert( pFile->pInode ); + return sqlite3_mutex_held(pFile->pInode->pLockMutex); +} +int unixFileMutexNotheld(unixFile *pFile){ + assert( pFile->pInode ); + return sqlite3_mutex_notheld(pFile->pInode->pLockMutex); +} +#endif + +/* +** +** This function - unixLogErrorAtLine(), is only ever called via the macro +** unixLogError(). +** +** It is invoked after an error occurs in an OS function and errno has been +** set. It logs a message using sqlite3_log() containing the current value of +** errno and, if possible, the human-readable equivalent from strerror() or +** strerror_r(). +** +** The first argument passed to the macro should be the error code that +** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN). +** The two subsequent arguments should be the name of the OS function that +** failed (e.g. "unlink", "open") and the associated file-system path, +** if any. +*/ +#define unixLogError(a,b,c) unixLogErrorAtLine(a,b,c,__LINE__) +static int unixLogErrorAtLine( + int errcode, /* SQLite error code */ + const char *zFunc, /* Name of OS function that failed */ + const char *zPath, /* File path associated with error */ + int iLine /* Source line number where error occurred */ +){ + char *zErr; /* Message from strerror() or equivalent */ + int iErrno = errno; /* Saved syscall error number */ + + /* If this is not a threadsafe build (SQLITE_THREADSAFE==0), then use + ** the strerror() function to obtain the human-readable error message + ** equivalent to errno. Otherwise, use strerror_r(). + */ +#if SQLITE_THREADSAFE && defined(HAVE_STRERROR_R) + char aErr[80]; + memset(aErr, 0, sizeof(aErr)); + zErr = aErr; + + /* If STRERROR_R_CHAR_P (set by autoconf scripts) or __USE_GNU is defined, + ** assume that the system provides the GNU version of strerror_r() that + ** returns a pointer to a buffer containing the error message. That pointer + ** may point to aErr[], or it may point to some static storage somewhere. + ** Otherwise, assume that the system provides the POSIX version of + ** strerror_r(), which always writes an error message into aErr[]. + ** + ** If the code incorrectly assumes that it is the POSIX version that is + ** available, the error message will often be an empty string. Not a + ** huge problem. Incorrectly concluding that the GNU version is available + ** could lead to a segfault though. + ** + ** Forum post 3f13857fa4062301 reports that the Android SDK may use + ** int-type return, depending on its version. + */ +#if (defined(STRERROR_R_CHAR_P) || defined(__USE_GNU)) \ + && !defined(ANDROID) && !defined(__ANDROID__) + zErr = +# endif + strerror_r(iErrno, aErr, sizeof(aErr)-1); + +#elif SQLITE_THREADSAFE + /* This is a threadsafe build, but strerror_r() is not available. */ + zErr = ""; +#else + /* Non-threadsafe build, use strerror(). */ + zErr = strerror(iErrno); +#endif + + if( zPath==0 ) zPath = ""; + sqlite3_log(errcode, + "os_unix.c:%d: (%d) %s(%s) - %s", + iLine, iErrno, zFunc, zPath, zErr + ); + + return errcode; +} + +/* +** Close a file descriptor. +** +** We assume that close() almost always works, since it is only in a +** very sick application or on a very sick platform that it might fail. +** If it does fail, simply leak the file descriptor, but do log the +** error. +** +** Note that it is not safe to retry close() after EINTR since the +** file descriptor might have already been reused by another thread. +** So we don't even try to recover from an EINTR. Just log the error +** and move on. +*/ +static void robust_close(unixFile *pFile, int h, int lineno){ + if( osClose(h) ){ + unixLogErrorAtLine(SQLITE_IOERR_CLOSE, "close", + pFile ? pFile->zPath : 0, lineno); + } +} + +/* +** Set the pFile->lastErrno. Do this in a subroutine as that provides +** a convenient place to set a breakpoint. +*/ +static void storeLastErrno(unixFile *pFile, int error){ + pFile->lastErrno = error; +} + +/* +** Close all file descriptors accumulated in the unixInodeInfo->pUnused list. +*/ +static void closePendingFds(unixFile *pFile){ + unixInodeInfo *pInode = pFile->pInode; + UnixUnusedFd *p; + UnixUnusedFd *pNext; + assert( unixFileMutexHeld(pFile) ); + for(p=pInode->pUnused; p; p=pNext){ + pNext = p->pNext; + robust_close(pFile, p->fd, __LINE__); + sqlite3_free(p); + } + pInode->pUnused = 0; +} + +/* +** Release a unixInodeInfo structure previously allocated by findInodeInfo(). +** +** The global mutex must be held when this routine is called, but the mutex +** on the inode being deleted must NOT be held. +*/ +static void releaseInodeInfo(unixFile *pFile){ + unixInodeInfo *pInode = pFile->pInode; + assert( unixMutexHeld() ); + assert( unixFileMutexNotheld(pFile) ); + if( ALWAYS(pInode) ){ + pInode->nRef--; + if( pInode->nRef==0 ){ + assert( pInode->pShmNode==0 ); + sqlite3_mutex_enter(pInode->pLockMutex); + closePendingFds(pFile); + sqlite3_mutex_leave(pInode->pLockMutex); + if( pInode->pPrev ){ + assert( pInode->pPrev->pNext==pInode ); + pInode->pPrev->pNext = pInode->pNext; + }else{ + assert( inodeList==pInode ); + inodeList = pInode->pNext; + } + if( pInode->pNext ){ + assert( pInode->pNext->pPrev==pInode ); + pInode->pNext->pPrev = pInode->pPrev; + } + sqlite3_mutex_free(pInode->pLockMutex); + sqlite3_free(pInode); + } + } +} + +/* +** Given a file descriptor, locate the unixInodeInfo object that +** describes that file descriptor. Create a new one if necessary. The +** return value might be uninitialized if an error occurs. +** +** The global mutex must held when calling this routine. +** +** Return an appropriate error code. +*/ +static int findInodeInfo( + unixFile *pFile, /* Unix file with file desc used in the key */ + unixInodeInfo **ppInode /* Return the unixInodeInfo object here */ +){ + int rc; /* System call return code */ + int fd; /* The file descriptor for pFile */ + struct unixFileId fileId; /* Lookup key for the unixInodeInfo */ + struct stat statbuf; /* Low-level file information */ + unixInodeInfo *pInode = 0; /* Candidate unixInodeInfo object */ + + assert( unixMutexHeld() ); + + /* Get low-level information about the file that we can used to + ** create a unique name for the file. + */ + fd = pFile->h; + rc = osFstat(fd, &statbuf); + if( rc!=0 ){ + storeLastErrno(pFile, errno); +#if defined(EOVERFLOW) && defined(SQLITE_DISABLE_LFS) + if( pFile->lastErrno==EOVERFLOW ) return SQLITE_NOLFS; +#endif + return SQLITE_IOERR; + } + +#ifdef __APPLE__ + /* On OS X on an msdos filesystem, the inode number is reported + ** incorrectly for zero-size files. See ticket #3260. To work + ** around this problem (we consider it a bug in OS X, not SQLite) + ** we always increase the file size to 1 by writing a single byte + ** prior to accessing the inode number. The one byte written is + ** an ASCII 'S' character which also happens to be the first byte + ** in the header of every SQLite database. In this way, if there + ** is a race condition such that another thread has already populated + ** the first page of the database, no damage is done. + */ + if( statbuf.st_size==0 && (pFile->fsFlags & SQLITE_FSFLAGS_IS_MSDOS)!=0 ){ + do{ rc = osWrite(fd, "S", 1); }while( rc<0 && errno==EINTR ); + if( rc!=1 ){ + storeLastErrno(pFile, errno); + return SQLITE_IOERR; + } + if( fsync(fd) ){ + storeLastErrno(pFile, errno); + return SQLITE_IOERR_FSYNC; + } + rc = osFstat(fd, &statbuf); + if( rc!=0 ){ + storeLastErrno(pFile, errno); + return SQLITE_IOERR; + } + } +#endif + + memset(&fileId, 0, sizeof(fileId)); + fileId.dev = statbuf.st_dev; +#if OS_VXWORKS + fileId.pId = pFile->pId; +#else + fileId.ino = (u64)statbuf.st_ino; +#endif + assert( unixMutexHeld() ); + pInode = inodeList; + while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){ + pInode = pInode->pNext; + } + if( pInode==0 ){ + pInode = sqlite3_malloc64( sizeof(*pInode) ); + if( pInode==0 ){ + return SQLITE_NOMEM_BKPT; + } + memset(pInode, 0, sizeof(*pInode)); + memcpy(&pInode->fileId, &fileId, sizeof(fileId)); + if( sqlite3GlobalConfig.bCoreMutex ){ + pInode->pLockMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( pInode->pLockMutex==0 ){ + sqlite3_free(pInode); + return SQLITE_NOMEM_BKPT; + } + } + pInode->nRef = 1; + assert( unixMutexHeld() ); + pInode->pNext = inodeList; + pInode->pPrev = 0; + if( inodeList ) inodeList->pPrev = pInode; + inodeList = pInode; + }else{ + pInode->nRef++; + } + *ppInode = pInode; + return SQLITE_OK; +} + +/* +** Return TRUE if pFile has been renamed or unlinked since it was first opened. +*/ +static int fileHasMoved(unixFile *pFile){ +#if OS_VXWORKS + return pFile->pInode!=0 && pFile->pId!=pFile->pInode->fileId.pId; +#else + struct stat buf; + return pFile->pInode!=0 && + (osStat(pFile->zPath, &buf)!=0 + || (u64)buf.st_ino!=pFile->pInode->fileId.ino); +#endif +} + + +/* +** Check a unixFile that is a database. Verify the following: +** +** (1) There is exactly one hard link on the file +** (2) The file is not a symbolic link +** (3) The file has not been renamed or unlinked +** +** Issue sqlite3_log(SQLITE_WARNING,...) messages if anything is not right. +*/ +static void verifyDbFile(unixFile *pFile){ + struct stat buf; + int rc; + + /* These verifications occurs for the main database only */ + if( pFile->ctrlFlags & UNIXFILE_NOLOCK ) return; + + rc = osFstat(pFile->h, &buf); + if( rc!=0 ){ + sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath); + return; + } + if( buf.st_nlink==0 ){ + sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath); + return; + } + if( buf.st_nlink>1 ){ + sqlite3_log(SQLITE_WARNING, "multiple links to file: %s", pFile->zPath); + return; + } + if( fileHasMoved(pFile) ){ + sqlite3_log(SQLITE_WARNING, "file renamed while open: %s", pFile->zPath); + return; + } +} + + +/* +** This routine checks if there is a RESERVED lock held on the specified +** file by this or any other process. If such a lock is held, set *pResOut +** to a non-zero value otherwise *pResOut is set to zero. The return value +** is set to SQLITE_OK unless an I/O error occurs during lock checking. +*/ +static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ + int rc = SQLITE_OK; + int reserved = 0; + unixFile *pFile = (unixFile*)id; + + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); + + assert( pFile ); + assert( pFile->eFileLock<=SHARED_LOCK ); + sqlite3_mutex_enter(pFile->pInode->pLockMutex); + + /* Check if a thread in this process holds such a lock */ + if( pFile->pInode->eFileLock>SHARED_LOCK ){ + reserved = 1; + } + + /* Otherwise see if some other process holds it. + */ +#ifndef __DJGPP__ + if( !reserved && !pFile->pInode->bProcessLock ){ + struct flock lock; + lock.l_whence = SEEK_SET; + lock.l_start = RESERVED_BYTE; + lock.l_len = 1; + lock.l_type = F_WRLCK; + if( osFcntl(pFile->h, F_GETLK, &lock) ){ + rc = SQLITE_IOERR_CHECKRESERVEDLOCK; + storeLastErrno(pFile, errno); + } else if( lock.l_type!=F_UNLCK ){ + reserved = 1; + } + } +#endif + + sqlite3_mutex_leave(pFile->pInode->pLockMutex); + OSTRACE(("TEST WR-LOCK %d %d %d (unix)\n", pFile->h, rc, reserved)); + + *pResOut = reserved; + return rc; +} + +/* Forward declaration*/ +static int unixSleep(sqlite3_vfs*,int); + +/* +** Set a posix-advisory-lock. +** +** There are two versions of this routine. If compiled with +** SQLITE_ENABLE_SETLK_TIMEOUT then the routine has an extra parameter +** which is a pointer to a unixFile. If the unixFile->iBusyTimeout +** value is set, then it is the number of milliseconds to wait before +** failing the lock. The iBusyTimeout value is always reset back to +** zero on each call. +** +** If SQLITE_ENABLE_SETLK_TIMEOUT is not defined, then do a non-blocking +** attempt to set the lock. +*/ +#ifndef SQLITE_ENABLE_SETLK_TIMEOUT +# define osSetPosixAdvisoryLock(h,x,t) osFcntl(h,F_SETLK,x) +#else +static int osSetPosixAdvisoryLock( + int h, /* The file descriptor on which to take the lock */ + struct flock *pLock, /* The description of the lock */ + unixFile *pFile /* Structure holding timeout value */ +){ + int rc = 0; + + if( pFile->iBusyTimeout==0 ){ + /* unixFile->iBusyTimeout is set to 0. In this case, attempt a + ** non-blocking lock. */ + rc = osFcntl(h,F_SETLK,pLock); + }else{ + /* unixFile->iBusyTimeout is set to greater than zero. In this case, + ** attempt a blocking-lock with a unixFile->iBusyTimeout ms timeout. + ** + ** On systems that support some kind of blocking file lock operation, + ** this block should be replaced by code to attempt a blocking lock + ** with a timeout of unixFile->iBusyTimeout ms. The code below is + ** placeholder code. If SQLITE_TEST is defined, the placeholder code + ** retries the lock once every 1ms until it succeeds or the timeout + ** is reached. Or, if SQLITE_TEST is not defined, the placeholder + ** code attempts a non-blocking lock and sets unixFile->iBusyTimeout + ** to 0. This causes the caller to return SQLITE_BUSY, instead of + ** SQLITE_BUSY_TIMEOUT to SQLite - as required by a VFS that does not + ** support blocking locks. + */ +#ifdef SQLITE_TEST + int tm = pFile->iBusyTimeout; + while( tm>0 ){ + rc = osFcntl(h,F_SETLK,pLock); + if( rc==0 ) break; + unixSleep(0,1000); + tm--; + } +#else + rc = osFcntl(h,F_SETLK,pLock); + pFile->iBusyTimeout = 0; +#endif + /* End of code to replace with real blocking-locks code. */ + } + + return rc; +} +#endif /* SQLITE_ENABLE_SETLK_TIMEOUT */ + + +/* +** Attempt to set a system-lock on the file pFile. The lock is +** described by pLock. +** +** If the pFile was opened read/write from unix-excl, then the only lock +** ever obtained is an exclusive lock, and it is obtained exactly once +** the first time any lock is attempted. All subsequent system locking +** operations become no-ops. Locking operations still happen internally, +** in order to coordinate access between separate database connections +** within this process, but all of that is handled in memory and the +** operating system does not participate. +** +** This function is a pass-through to fcntl(F_SETLK) if pFile is using +** any VFS other than "unix-excl" or if pFile is opened on "unix-excl" +** and is read-only. +** +** Zero is returned if the call completes successfully, or -1 if a call +** to fcntl() fails. In this case, errno is set appropriately (by fcntl()). +*/ +static int unixFileLock(unixFile *pFile, struct flock *pLock){ + int rc; + unixInodeInfo *pInode = pFile->pInode; + assert( pInode!=0 ); + assert( sqlite3_mutex_held(pInode->pLockMutex) ); + if( (pFile->ctrlFlags & (UNIXFILE_EXCL|UNIXFILE_RDONLY))==UNIXFILE_EXCL ){ + if( pInode->bProcessLock==0 ){ + struct flock lock; + /* assert( pInode->nLock==0 ); <-- Not true if unix-excl READONLY used */ + lock.l_whence = SEEK_SET; + lock.l_start = SHARED_FIRST; + lock.l_len = SHARED_SIZE; + lock.l_type = F_WRLCK; + rc = osSetPosixAdvisoryLock(pFile->h, &lock, pFile); + if( rc<0 ) return rc; + pInode->bProcessLock = 1; + pInode->nLock++; + }else{ + rc = 0; + } + }else{ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + if( pFile->bBlockOnConnect && pLock->l_type==F_RDLCK + && pLock->l_start==SHARED_FIRST && pLock->l_len==SHARED_SIZE + ){ + rc = osFcntl(pFile->h, F_SETLKW, pLock); + }else +#endif + rc = osSetPosixAdvisoryLock(pFile->h, pLock, pFile); + } + return rc; +} + +#if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL) +/* Forward reference */ +static int unixIsSharingShmNode(unixFile*); +#else +#define unixIsSharingShmNode(pFile) (0) +#endif + +/* +** Lock the file with the lock specified by parameter eFileLock - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** This routine will only increase a lock. Use the sqlite3OsUnlock() +** routine to lower a locking level. +*/ +static int unixLock(sqlite3_file *id, int eFileLock){ + /* The following describes the implementation of the various locks and + ** lock transitions in terms of the POSIX advisory shared and exclusive + ** lock primitives (called read-locks and write-locks below, to avoid + ** confusion with SQLite lock names). The algorithms are complicated + ** slightly in order to be compatible with Windows95 systems simultaneously + ** accessing the same database file, in case that is ever required. + ** + ** Symbols defined in os.h identify the 'pending byte' and the 'reserved + ** byte', each single bytes at well known offsets, and the 'shared byte + ** range', a range of 510 bytes at a well known offset. + ** + ** To obtain a SHARED lock, a read-lock is obtained on the 'pending + ** byte'. If this is successful, 'shared byte range' is read-locked + ** and the lock on the 'pending byte' released. (Legacy note: When + ** SQLite was first developed, Windows95 systems were still very common, + ** and Windows95 lacks a shared-lock capability. So on Windows95, a + ** single randomly selected by from the 'shared byte range' is locked. + ** Windows95 is now pretty much extinct, but this work-around for the + ** lack of shared-locks on Windows95 lives on, for backwards + ** compatibility.) + ** + ** A process may only obtain a RESERVED lock after it has a SHARED lock. + ** A RESERVED lock is implemented by grabbing a write-lock on the + ** 'reserved byte'. + ** + ** An EXCLUSIVE lock may only be requested after either a SHARED or + ** RESERVED lock is held. An EXCLUSIVE lock is implemented by obtaining + ** a write-lock on the entire 'shared byte range'. Since all other locks + ** require a read-lock on one of the bytes within this range, this ensures + ** that no other locks are held on the database. + ** + ** If a process that holds a RESERVED lock requests an EXCLUSIVE, then + ** a PENDING lock is obtained first. A PENDING lock is implemented by + ** obtaining a write-lock on the 'pending byte'. This ensures that no new + ** SHARED locks can be obtained, but existing SHARED locks are allowed to + ** persist. If the call to this function fails to obtain the EXCLUSIVE + ** lock in this case, it holds the PENDING lock instead. The client may + ** then re-attempt the EXCLUSIVE lock later on, after existing SHARED + ** locks have cleared. + */ + int rc = SQLITE_OK; + unixFile *pFile = (unixFile*)id; + unixInodeInfo *pInode; + struct flock lock; + int tErrno = 0; + + assert( pFile ); + OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (unix)\n", pFile->h, + azFileLock(eFileLock), azFileLock(pFile->eFileLock), + azFileLock(pFile->pInode->eFileLock), pFile->pInode->nShared, + osGetpid(0))); + + /* If there is already a lock of this type or more restrictive on the + ** unixFile, do nothing. Don't use the end_lock: exit path, as + ** unixEnterMutex() hasn't been called yet. + */ + if( pFile->eFileLock>=eFileLock ){ + OSTRACE(("LOCK %d %s ok (already held) (unix)\n", pFile->h, + azFileLock(eFileLock))); + return SQLITE_OK; + } + + /* Make sure the locking sequence is correct. + ** (1) We never move from unlocked to anything higher than shared lock. + ** (2) SQLite never explicitly requests a pending lock. + ** (3) A shared lock is always held when a reserve lock is requested. + */ + assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK ); + assert( eFileLock!=PENDING_LOCK ); + assert( eFileLock!=RESERVED_LOCK || pFile->eFileLock==SHARED_LOCK ); + + /* This mutex is needed because pFile->pInode is shared across threads + */ + pInode = pFile->pInode; + sqlite3_mutex_enter(pInode->pLockMutex); + + /* If some thread using this PID has a lock via a different unixFile* + ** handle that precludes the requested lock, return BUSY. + */ + if( (pFile->eFileLock!=pInode->eFileLock && + (pInode->eFileLock>=PENDING_LOCK || eFileLock>SHARED_LOCK)) + ){ + rc = SQLITE_BUSY; + goto end_lock; + } + + /* If a SHARED lock is requested, and some thread using this PID already + ** has a SHARED or RESERVED lock, then increment reference counts and + ** return SQLITE_OK. + */ + if( eFileLock==SHARED_LOCK && + (pInode->eFileLock==SHARED_LOCK || pInode->eFileLock==RESERVED_LOCK) ){ + assert( eFileLock==SHARED_LOCK ); + assert( pFile->eFileLock==0 ); + assert( pInode->nShared>0 ); + pFile->eFileLock = SHARED_LOCK; + pInode->nShared++; + pInode->nLock++; + goto end_lock; + } + + + /* A PENDING lock is needed before acquiring a SHARED lock and before + ** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will + ** be released. + */ + lock.l_len = 1L; + lock.l_whence = SEEK_SET; + if( eFileLock==SHARED_LOCK + || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLock==RESERVED_LOCK) + ){ + lock.l_type = (eFileLock==SHARED_LOCK?F_RDLCK:F_WRLCK); + lock.l_start = PENDING_BYTE; + if( unixFileLock(pFile, &lock) ){ + tErrno = errno; + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); + if( rc!=SQLITE_BUSY ){ + storeLastErrno(pFile, tErrno); + } + goto end_lock; + }else if( eFileLock==EXCLUSIVE_LOCK ){ + pFile->eFileLock = PENDING_LOCK; + pInode->eFileLock = PENDING_LOCK; + } + } + + + /* If control gets to this point, then actually go ahead and make + ** operating system calls for the specified lock. + */ + if( eFileLock==SHARED_LOCK ){ + assert( pInode->nShared==0 ); + assert( pInode->eFileLock==0 ); + assert( rc==SQLITE_OK ); + + /* Now get the read-lock */ + lock.l_start = SHARED_FIRST; + lock.l_len = SHARED_SIZE; + if( unixFileLock(pFile, &lock) ){ + tErrno = errno; + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); + } + + /* Drop the temporary PENDING lock */ + lock.l_start = PENDING_BYTE; + lock.l_len = 1L; + lock.l_type = F_UNLCK; + if( unixFileLock(pFile, &lock) && rc==SQLITE_OK ){ + /* This could happen with a network mount */ + tErrno = errno; + rc = SQLITE_IOERR_UNLOCK; + } + + if( rc ){ + if( rc!=SQLITE_BUSY ){ + storeLastErrno(pFile, tErrno); + } + goto end_lock; + }else{ + pFile->eFileLock = SHARED_LOCK; + pInode->nLock++; + pInode->nShared = 1; + } + }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1 ){ + /* We are trying for an exclusive lock but another thread in this + ** same process is still holding a shared lock. */ + rc = SQLITE_BUSY; + }else if( unixIsSharingShmNode(pFile) ){ + /* We are in WAL mode and attempting to delete the SHM and WAL + ** files due to closing the connection or changing out of WAL mode, + ** but another process still holds locks on the SHM file, thus + ** indicating that database locks have been broken, perhaps due + ** to a rogue close(open(dbFile)) or similar. + */ + rc = SQLITE_BUSY; + }else{ + /* The request was for a RESERVED or EXCLUSIVE lock. It is + ** assumed that there is a SHARED or greater lock on the file + ** already. + */ + assert( 0!=pFile->eFileLock ); + lock.l_type = F_WRLCK; + + assert( eFileLock==RESERVED_LOCK || eFileLock==EXCLUSIVE_LOCK ); + if( eFileLock==RESERVED_LOCK ){ + lock.l_start = RESERVED_BYTE; + lock.l_len = 1L; + }else{ + lock.l_start = SHARED_FIRST; + lock.l_len = SHARED_SIZE; + } + + if( unixFileLock(pFile, &lock) ){ + tErrno = errno; + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); + if( rc!=SQLITE_BUSY ){ + storeLastErrno(pFile, tErrno); + } + } + } + + +#ifdef SQLITE_DEBUG + /* Set up the transaction-counter change checking flags when + ** transitioning from a SHARED to a RESERVED lock. The change + ** from SHARED to RESERVED marks the beginning of a normal + ** write operation (not a hot journal rollback). + */ + if( rc==SQLITE_OK + && pFile->eFileLock<=SHARED_LOCK + && eFileLock==RESERVED_LOCK + ){ + pFile->transCntrChng = 0; + pFile->dbUpdate = 0; + pFile->inNormalWrite = 1; + } +#endif + + if( rc==SQLITE_OK ){ + pFile->eFileLock = eFileLock; + pInode->eFileLock = eFileLock; + } + +end_lock: + sqlite3_mutex_leave(pInode->pLockMutex); + OSTRACE(("LOCK %d %s %s (unix)\n", pFile->h, azFileLock(eFileLock), + rc==SQLITE_OK ? "ok" : "failed")); + return rc; +} + +/* +** Add the file descriptor used by file handle pFile to the corresponding +** pUnused list. +*/ +static void setPendingFd(unixFile *pFile){ + unixInodeInfo *pInode = pFile->pInode; + UnixUnusedFd *p = pFile->pPreallocatedUnused; + assert( unixFileMutexHeld(pFile) ); + p->pNext = pInode->pUnused; + pInode->pUnused = p; + pFile->h = -1; + pFile->pPreallocatedUnused = 0; +} + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +** +** If handleNFSUnlock is true, then on downgrading an EXCLUSIVE_LOCK to SHARED +** the byte range is divided into 2 parts and the first part is unlocked then +** set to a read lock, then the other part is simply unlocked. This works +** around a bug in BSD NFS lockd (also seen on MacOSX 10.3+) that fails to +** remove the write lock on a region when a read lock is set. +*/ +static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ + unixFile *pFile = (unixFile*)id; + unixInodeInfo *pInode; + struct flock lock; + int rc = SQLITE_OK; + + assert( pFile ); + OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (unix)\n", pFile->h, eFileLock, + pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared, + osGetpid(0))); + + assert( eFileLock<=SHARED_LOCK ); + if( pFile->eFileLock<=eFileLock ){ + return SQLITE_OK; + } + pInode = pFile->pInode; + sqlite3_mutex_enter(pInode->pLockMutex); + assert( pInode->nShared!=0 ); + if( pFile->eFileLock>SHARED_LOCK ){ + assert( pInode->eFileLock==pFile->eFileLock ); + +#ifdef SQLITE_DEBUG + /* When reducing a lock such that other processes can start + ** reading the database file again, make sure that the + ** transaction counter was updated if any part of the database + ** file changed. If the transaction counter is not updated, + ** other connections to the same file might not realize that + ** the file has changed and hence might not know to flush their + ** cache. The use of a stale cache can lead to database corruption. + */ + pFile->inNormalWrite = 0; +#endif + + /* downgrading to a shared lock on NFS involves clearing the write lock + ** before establishing the readlock - to avoid a race condition we downgrade + ** the lock in 2 blocks, so that part of the range will be covered by a + ** write lock until the rest is covered by a read lock: + ** 1: [WWWWW] + ** 2: [....W] + ** 3: [RRRRW] + ** 4: [RRRR.] + */ + if( eFileLock==SHARED_LOCK ){ +#if !defined(__APPLE__) || !SQLITE_ENABLE_LOCKING_STYLE + (void)handleNFSUnlock; + assert( handleNFSUnlock==0 ); +#endif +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE + if( handleNFSUnlock ){ + int tErrno; /* Error code from system call errors */ + off_t divSize = SHARED_SIZE - 1; + + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + lock.l_start = SHARED_FIRST; + lock.l_len = divSize; + if( unixFileLock(pFile, &lock)==(-1) ){ + tErrno = errno; + rc = SQLITE_IOERR_UNLOCK; + storeLastErrno(pFile, tErrno); + goto end_unlock; + } + lock.l_type = F_RDLCK; + lock.l_whence = SEEK_SET; + lock.l_start = SHARED_FIRST; + lock.l_len = divSize; + if( unixFileLock(pFile, &lock)==(-1) ){ + tErrno = errno; + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK); + if( IS_LOCK_ERROR(rc) ){ + storeLastErrno(pFile, tErrno); + } + goto end_unlock; + } + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + lock.l_start = SHARED_FIRST+divSize; + lock.l_len = SHARED_SIZE-divSize; + if( unixFileLock(pFile, &lock)==(-1) ){ + tErrno = errno; + rc = SQLITE_IOERR_UNLOCK; + storeLastErrno(pFile, tErrno); + goto end_unlock; + } + }else +#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ + { + lock.l_type = F_RDLCK; + lock.l_whence = SEEK_SET; + lock.l_start = SHARED_FIRST; + lock.l_len = SHARED_SIZE; + if( unixFileLock(pFile, &lock) ){ + /* In theory, the call to unixFileLock() cannot fail because another + ** process is holding an incompatible lock. If it does, this + ** indicates that the other process is not following the locking + ** protocol. If this happens, return SQLITE_IOERR_RDLOCK. Returning + ** SQLITE_BUSY would confuse the upper layer (in practice it causes + ** an assert to fail). */ + rc = SQLITE_IOERR_RDLOCK; + storeLastErrno(pFile, errno); + goto end_unlock; + } + } + } + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + lock.l_start = PENDING_BYTE; + lock.l_len = 2L; assert( PENDING_BYTE+1==RESERVED_BYTE ); + if( unixFileLock(pFile, &lock)==0 ){ + pInode->eFileLock = SHARED_LOCK; + }else{ + rc = SQLITE_IOERR_UNLOCK; + storeLastErrno(pFile, errno); + goto end_unlock; + } + } + if( eFileLock==NO_LOCK ){ + /* Decrement the shared lock counter. Release the lock using an + ** OS call only when all threads in this same process have released + ** the lock. + */ + pInode->nShared--; + if( pInode->nShared==0 ){ + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + lock.l_start = lock.l_len = 0L; + if( unixFileLock(pFile, &lock)==0 ){ + pInode->eFileLock = NO_LOCK; + }else{ + rc = SQLITE_IOERR_UNLOCK; + storeLastErrno(pFile, errno); + pInode->eFileLock = NO_LOCK; + pFile->eFileLock = NO_LOCK; + } + } + + /* Decrement the count of locks against this same file. When the + ** count reaches zero, close any other file descriptors whose close + ** was deferred because of outstanding locks. + */ + pInode->nLock--; + assert( pInode->nLock>=0 ); + if( pInode->nLock==0 ) closePendingFds(pFile); + } + +end_unlock: + sqlite3_mutex_leave(pInode->pLockMutex); + if( rc==SQLITE_OK ){ + pFile->eFileLock = eFileLock; + } + return rc; +} + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +*/ +static int unixUnlock(sqlite3_file *id, int eFileLock){ +#if SQLITE_MAX_MMAP_SIZE>0 + assert( eFileLock==SHARED_LOCK || ((unixFile *)id)->nFetchOut==0 ); +#endif + return posixUnlock(id, eFileLock, 0); +} + +#if SQLITE_MAX_MMAP_SIZE>0 +static int unixMapfile(unixFile *pFd, i64 nByte); +static void unixUnmapfile(unixFile *pFd); +#endif + +/* +** This function performs the parts of the "close file" operation +** common to all locking schemes. It closes the directory and file +** handles, if they are valid, and sets all fields of the unixFile +** structure to 0. +** +** It is *not* necessary to hold the mutex when this routine is called, +** even on VxWorks. A mutex will be acquired on VxWorks by the +** vxworksReleaseFileId() routine. +*/ +static int closeUnixFile(sqlite3_file *id){ + unixFile *pFile = (unixFile*)id; +#if SQLITE_MAX_MMAP_SIZE>0 + unixUnmapfile(pFile); +#endif + if( pFile->h>=0 ){ + robust_close(pFile, pFile->h, __LINE__); + pFile->h = -1; + } +#if OS_VXWORKS + if( pFile->pId ){ + if( pFile->ctrlFlags & UNIXFILE_DELETE ){ + osUnlink(pFile->pId->zCanonicalName); + } + vxworksReleaseFileId(pFile->pId); + pFile->pId = 0; + } +#endif +#ifdef SQLITE_UNLINK_AFTER_CLOSE + if( pFile->ctrlFlags & UNIXFILE_DELETE ){ + osUnlink(pFile->zPath); + sqlite3_free(*(char**)&pFile->zPath); + pFile->zPath = 0; + } +#endif + OSTRACE(("CLOSE %-3d\n", pFile->h)); + OpenCounter(-1); + sqlite3_free(pFile->pPreallocatedUnused); + memset(pFile, 0, sizeof(unixFile)); + return SQLITE_OK; +} + +/* +** Close a file. +*/ +static int unixClose(sqlite3_file *id){ + int rc = SQLITE_OK; + unixFile *pFile = (unixFile *)id; + unixInodeInfo *pInode = pFile->pInode; + + assert( pInode!=0 ); + verifyDbFile(pFile); + unixUnlock(id, NO_LOCK); + assert( unixFileMutexNotheld(pFile) ); + unixEnterMutex(); + + /* unixFile.pInode is always valid here. Otherwise, a different close + ** routine (e.g. nolockClose()) would be called instead. + */ + assert( pFile->pInode->nLock>0 || pFile->pInode->bProcessLock==0 ); + sqlite3_mutex_enter(pInode->pLockMutex); + if( pInode->nLock ){ + /* If there are outstanding locks, do not actually close the file just + ** yet because that would clear those locks. Instead, add the file + ** descriptor to pInode->pUnused list. It will be automatically closed + ** when the last lock is cleared. + */ + setPendingFd(pFile); + } + sqlite3_mutex_leave(pInode->pLockMutex); + releaseInodeInfo(pFile); + assert( pFile->pShm==0 ); + rc = closeUnixFile(id); + unixLeaveMutex(); + return rc; +} + +/************** End of the posix advisory lock implementation ***************** +******************************************************************************/ + +/****************************************************************************** +****************************** No-op Locking ********************************** +** +** Of the various locking implementations available, this is by far the +** simplest: locking is ignored. No attempt is made to lock the database +** file for reading or writing. +** +** This locking mode is appropriate for use on read-only databases +** (ex: databases that are burned into CD-ROM, for example.) It can +** also be used if the application employs some external mechanism to +** prevent simultaneous access of the same database by two or more +** database connections. But there is a serious risk of database +** corruption if this locking mode is used in situations where multiple +** database connections are accessing the same database file at the same +** time and one or more of those connections are writing. +*/ + +static int nolockCheckReservedLock(sqlite3_file *NotUsed, int *pResOut){ + UNUSED_PARAMETER(NotUsed); + *pResOut = 0; + return SQLITE_OK; +} +static int nolockLock(sqlite3_file *NotUsed, int NotUsed2){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + return SQLITE_OK; +} +static int nolockUnlock(sqlite3_file *NotUsed, int NotUsed2){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + return SQLITE_OK; +} + +/* +** Close the file. +*/ +static int nolockClose(sqlite3_file *id) { + return closeUnixFile(id); +} + +/******************* End of the no-op lock implementation ********************* +******************************************************************************/ + +/****************************************************************************** +************************* Begin dot-file Locking ****************************** +** +** The dotfile locking implementation uses the existence of separate lock +** files (really a directory) to control access to the database. This works +** on just about every filesystem imaginable. But there are serious downsides: +** +** (1) There is zero concurrency. A single reader blocks all other +** connections from reading or writing the database. +** +** (2) An application crash or power loss can leave stale lock files +** sitting around that need to be cleared manually. +** +** Nevertheless, a dotlock is an appropriate locking mode for use if no +** other locking strategy is available. +** +** Dotfile locking works by creating a subdirectory in the same directory as +** the database and with the same name but with a ".lock" extension added. +** The existence of a lock directory implies an EXCLUSIVE lock. All other +** lock types (SHARED, RESERVED, PENDING) are mapped into EXCLUSIVE. +*/ + +/* +** The file suffix added to the data base filename in order to create the +** lock directory. +*/ +#define DOTLOCK_SUFFIX ".lock" + +/* +** This routine checks if there is a RESERVED lock held on the specified +** file by this or any other process. If the caller holds a SHARED +** or greater lock when it is called, then it is assumed that no other +** client may hold RESERVED. Or, if the caller holds no lock, then it +** is assumed another client holds RESERVED if the lock-file exists. +*/ +static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) { + unixFile *pFile = (unixFile*)id; + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); + + if( pFile->eFileLock>=SHARED_LOCK ){ + *pResOut = 0; + }else{ + *pResOut = osAccess((const char*)pFile->lockingContext, 0)==0; + } + OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, 0, *pResOut)); + return SQLITE_OK; +} + +/* +** Lock the file with the lock specified by parameter eFileLock - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> (PENDING) -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** This routine will only increase a lock. Use the sqlite3OsUnlock() +** routine to lower a locking level. +** +** With dotfile locking, we really only support state (4): EXCLUSIVE. +** But we track the other locking levels internally. +*/ +static int dotlockLock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + char *zLockFile = (char *)pFile->lockingContext; + int rc = SQLITE_OK; + + + /* If we have any lock, then the lock file already exists. All we have + ** to do is adjust our internal record of the lock level. + */ + if( pFile->eFileLock > NO_LOCK ){ + pFile->eFileLock = eFileLock; + /* Always update the timestamp on the old file */ +#ifdef HAVE_UTIME + utime(zLockFile, NULL); +#else + utimes(zLockFile, NULL); +#endif + return SQLITE_OK; + } + + /* grab an exclusive lock */ + rc = osMkdir(zLockFile, 0777); + if( rc<0 ){ + /* failed to open/create the lock directory */ + int tErrno = errno; + if( EEXIST == tErrno ){ + rc = SQLITE_BUSY; + } else { + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); + if( rc!=SQLITE_BUSY ){ + storeLastErrno(pFile, tErrno); + } + } + return rc; + } + + /* got it, set the type and return ok */ + pFile->eFileLock = eFileLock; + return rc; +} + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +** +** When the locking level reaches NO_LOCK, delete the lock file. +*/ +static int dotlockUnlock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + char *zLockFile = (char *)pFile->lockingContext; + int rc; + + assert( pFile ); + OSTRACE(("UNLOCK %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock, + pFile->eFileLock, osGetpid(0))); + assert( eFileLock<=SHARED_LOCK ); + + /* no-op if possible */ + if( pFile->eFileLock==eFileLock ){ + return SQLITE_OK; + } + + /* To downgrade to shared, simply update our internal notion of the + ** lock state. No need to mess with the file on disk. + */ + if( eFileLock==SHARED_LOCK ){ + pFile->eFileLock = SHARED_LOCK; + return SQLITE_OK; + } + + /* To fully unlock the database, delete the lock file */ + assert( eFileLock==NO_LOCK ); + rc = osRmdir(zLockFile); + if( rc<0 ){ + int tErrno = errno; + if( tErrno==ENOENT ){ + rc = SQLITE_OK; + }else{ + rc = SQLITE_IOERR_UNLOCK; + storeLastErrno(pFile, tErrno); + } + return rc; + } + pFile->eFileLock = NO_LOCK; + return SQLITE_OK; +} + +/* +** Close a file. Make sure the lock has been released before closing. +*/ +static int dotlockClose(sqlite3_file *id) { + unixFile *pFile = (unixFile*)id; + assert( id!=0 ); + dotlockUnlock(id, NO_LOCK); + sqlite3_free(pFile->lockingContext); + return closeUnixFile(id); +} +/****************** End of the dot-file lock implementation ******************* +******************************************************************************/ + +/****************************************************************************** +************************** Begin flock Locking ******************************** +** +** Use the flock() system call to do file locking. +** +** flock() locking is like dot-file locking in that the various +** fine-grain locking levels supported by SQLite are collapsed into +** a single exclusive lock. In other words, SHARED, RESERVED, and +** PENDING locks are the same thing as an EXCLUSIVE lock. SQLite +** still works when you do this, but concurrency is reduced since +** only a single process can be reading the database at a time. +** +** Omit this section if SQLITE_ENABLE_LOCKING_STYLE is turned off +*/ +#if SQLITE_ENABLE_LOCKING_STYLE + +/* +** Retry flock() calls that fail with EINTR +*/ +#ifdef EINTR +static int robust_flock(int fd, int op){ + int rc; + do{ rc = flock(fd,op); }while( rc<0 && errno==EINTR ); + return rc; +} +#else +# define robust_flock(a,b) flock(a,b) +#endif + + +/* +** This routine checks if there is a RESERVED lock held on the specified +** file by this or any other process. If such a lock is held, set *pResOut +** to a non-zero value otherwise *pResOut is set to zero. The return value +** is set to SQLITE_OK unless an I/O error occurs during lock checking. +*/ +static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){ +#ifdef SQLITE_DEBUG + unixFile *pFile = (unixFile*)id; +#else + UNUSED_PARAMETER(id); +#endif + + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); + + assert( pFile ); + assert( pFile->eFileLock<=SHARED_LOCK ); + + /* The flock VFS only ever takes exclusive locks (see function flockLock). + ** Therefore, if this connection is holding any lock at all, no other + ** connection may be holding a RESERVED lock. So set *pResOut to 0 + ** in this case. + ** + ** Or, this connection may be holding no lock. In that case, set *pResOut to + ** 0 as well. The caller will then attempt to take an EXCLUSIVE lock on the + ** db in order to roll the hot journal back. If there is another connection + ** holding a lock, that attempt will fail and an SQLITE_BUSY returned to + ** the user. With other VFS, we try to avoid this, in order to allow a reader + ** to proceed while a writer is preparing its transaction. But that won't + ** work with the flock VFS - as it always takes EXCLUSIVE locks - so it is + ** not a problem in this case. */ + *pResOut = 0; + + return SQLITE_OK; +} + +/* +** Lock the file with the lock specified by parameter eFileLock - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> (PENDING) -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** flock() only really support EXCLUSIVE locks. We track intermediate +** lock states in the sqlite3_file structure, but all locks SHARED or +** above are really EXCLUSIVE locks and exclude all other processes from +** access the file. +** +** This routine will only increase a lock. Use the sqlite3OsUnlock() +** routine to lower a locking level. +*/ +static int flockLock(sqlite3_file *id, int eFileLock) { + int rc = SQLITE_OK; + unixFile *pFile = (unixFile*)id; + + assert( pFile ); + + /* if we already have a lock, it is exclusive. + ** Just adjust level and punt on outta here. */ + if (pFile->eFileLock > NO_LOCK) { + pFile->eFileLock = eFileLock; + return SQLITE_OK; + } + + /* grab an exclusive lock */ + + if (robust_flock(pFile->h, LOCK_EX | LOCK_NB)) { + int tErrno = errno; + /* didn't get, must be busy */ + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); + if( IS_LOCK_ERROR(rc) ){ + storeLastErrno(pFile, tErrno); + } + } else { + /* got it, set the type and return ok */ + pFile->eFileLock = eFileLock; + } + OSTRACE(("LOCK %d %s %s (flock)\n", pFile->h, azFileLock(eFileLock), + rc==SQLITE_OK ? "ok" : "failed")); +#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS + if( (rc & 0xff) == SQLITE_IOERR ){ + rc = SQLITE_BUSY; + } +#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ + return rc; +} + + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +*/ +static int flockUnlock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + + assert( pFile ); + OSTRACE(("UNLOCK %d %d was %d pid=%d (flock)\n", pFile->h, eFileLock, + pFile->eFileLock, osGetpid(0))); + assert( eFileLock<=SHARED_LOCK ); + + /* no-op if possible */ + if( pFile->eFileLock==eFileLock ){ + return SQLITE_OK; + } + + /* shared can just be set because we always have an exclusive */ + if (eFileLock==SHARED_LOCK) { + pFile->eFileLock = eFileLock; + return SQLITE_OK; + } + + /* no, really, unlock. */ + if( robust_flock(pFile->h, LOCK_UN) ){ +#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS + return SQLITE_OK; +#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ + return SQLITE_IOERR_UNLOCK; + }else{ + pFile->eFileLock = NO_LOCK; + return SQLITE_OK; + } +} + +/* +** Close a file. +*/ +static int flockClose(sqlite3_file *id) { + assert( id!=0 ); + flockUnlock(id, NO_LOCK); + return closeUnixFile(id); +} + +#endif /* SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORK */ + +/******************* End of the flock lock implementation ********************* +******************************************************************************/ + +/****************************************************************************** +************************ Begin Named Semaphore Locking ************************ +** +** Named semaphore locking is only supported on VxWorks. +** +** Semaphore locking is like dot-lock and flock in that it really only +** supports EXCLUSIVE locking. Only a single process can read or write +** the database file at a time. This reduces potential concurrency, but +** makes the lock implementation much easier. +*/ +#if OS_VXWORKS + +/* +** This routine checks if there is a RESERVED lock held on the specified +** file by this or any other process. If such a lock is held, set *pResOut +** to a non-zero value otherwise *pResOut is set to zero. The return value +** is set to SQLITE_OK unless an I/O error occurs during lock checking. +*/ +static int semXCheckReservedLock(sqlite3_file *id, int *pResOut) { + int rc = SQLITE_OK; + int reserved = 0; + unixFile *pFile = (unixFile*)id; + + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); + + assert( pFile ); + + /* Check if a thread in this process holds such a lock */ + if( pFile->eFileLock>SHARED_LOCK ){ + reserved = 1; + } + + /* Otherwise see if some other process holds it. */ + if( !reserved ){ + sem_t *pSem = pFile->pInode->pSem; + + if( sem_trywait(pSem)==-1 ){ + int tErrno = errno; + if( EAGAIN != tErrno ){ + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK); + storeLastErrno(pFile, tErrno); + } else { + /* someone else has the lock when we are in NO_LOCK */ + reserved = (pFile->eFileLock < SHARED_LOCK); + } + }else{ + /* we could have it if we want it */ + sem_post(pSem); + } + } + OSTRACE(("TEST WR-LOCK %d %d %d (sem)\n", pFile->h, rc, reserved)); + + *pResOut = reserved; + return rc; +} + +/* +** Lock the file with the lock specified by parameter eFileLock - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> (PENDING) -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** Semaphore locks only really support EXCLUSIVE locks. We track intermediate +** lock states in the sqlite3_file structure, but all locks SHARED or +** above are really EXCLUSIVE locks and exclude all other processes from +** access the file. +** +** This routine will only increase a lock. Use the sqlite3OsUnlock() +** routine to lower a locking level. +*/ +static int semXLock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + sem_t *pSem = pFile->pInode->pSem; + int rc = SQLITE_OK; + + /* if we already have a lock, it is exclusive. + ** Just adjust level and punt on outta here. */ + if (pFile->eFileLock > NO_LOCK) { + pFile->eFileLock = eFileLock; + rc = SQLITE_OK; + goto sem_end_lock; + } + + /* lock semaphore now but bail out when already locked. */ + if( sem_trywait(pSem)==-1 ){ + rc = SQLITE_BUSY; + goto sem_end_lock; + } + + /* got it, set the type and return ok */ + pFile->eFileLock = eFileLock; + + sem_end_lock: + return rc; +} + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +*/ +static int semXUnlock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + sem_t *pSem = pFile->pInode->pSem; + + assert( pFile ); + assert( pSem ); + OSTRACE(("UNLOCK %d %d was %d pid=%d (sem)\n", pFile->h, eFileLock, + pFile->eFileLock, osGetpid(0))); + assert( eFileLock<=SHARED_LOCK ); + + /* no-op if possible */ + if( pFile->eFileLock==eFileLock ){ + return SQLITE_OK; + } + + /* shared can just be set because we always have an exclusive */ + if (eFileLock==SHARED_LOCK) { + pFile->eFileLock = eFileLock; + return SQLITE_OK; + } + + /* no, really unlock. */ + if ( sem_post(pSem)==-1 ) { + int rc, tErrno = errno; + rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); + if( IS_LOCK_ERROR(rc) ){ + storeLastErrno(pFile, tErrno); + } + return rc; + } + pFile->eFileLock = NO_LOCK; + return SQLITE_OK; +} + +/* + ** Close a file. + */ +static int semXClose(sqlite3_file *id) { + if( id ){ + unixFile *pFile = (unixFile*)id; + semXUnlock(id, NO_LOCK); + assert( pFile ); + assert( unixFileMutexNotheld(pFile) ); + unixEnterMutex(); + releaseInodeInfo(pFile); + unixLeaveMutex(); + closeUnixFile(id); + } + return SQLITE_OK; +} + +#endif /* OS_VXWORKS */ +/* +** Named semaphore locking is only available on VxWorks. +** +*************** End of the named semaphore lock implementation **************** +******************************************************************************/ + + +/****************************************************************************** +*************************** Begin AFP Locking ********************************* +** +** AFP is the Apple Filing Protocol. AFP is a network filesystem found +** on Apple Macintosh computers - both OS9 and OSX. +** +** Third-party implementations of AFP are available. But this code here +** only works on OSX. +*/ + +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE +/* +** The afpLockingContext structure contains all afp lock specific state +*/ +typedef struct afpLockingContext afpLockingContext; +struct afpLockingContext { + int reserved; + const char *dbPath; /* Name of the open file */ +}; + +struct ByteRangeLockPB2 +{ + unsigned long long offset; /* offset to first byte to lock */ + unsigned long long length; /* nbr of bytes to lock */ + unsigned long long retRangeStart; /* nbr of 1st byte locked if successful */ + unsigned char unLockFlag; /* 1 = unlock, 0 = lock */ + unsigned char startEndFlag; /* 1=rel to end of fork, 0=rel to start */ + int fd; /* file desc to assoc this lock with */ +}; + +#define afpfsByteRangeLock2FSCTL _IOWR('z', 23, struct ByteRangeLockPB2) + +/* +** This is a utility for setting or clearing a bit-range lock on an +** AFP filesystem. +** +** Return SQLITE_OK on success, SQLITE_BUSY on failure. +*/ +static int afpSetLock( + const char *path, /* Name of the file to be locked or unlocked */ + unixFile *pFile, /* Open file descriptor on path */ + unsigned long long offset, /* First byte to be locked */ + unsigned long long length, /* Number of bytes to lock */ + int setLockFlag /* True to set lock. False to clear lock */ +){ + struct ByteRangeLockPB2 pb; + int err; + + pb.unLockFlag = setLockFlag ? 0 : 1; + pb.startEndFlag = 0; + pb.offset = offset; + pb.length = length; + pb.fd = pFile->h; + + OSTRACE(("AFPSETLOCK [%s] for %d%s in range %llx:%llx\n", + (setLockFlag?"ON":"OFF"), pFile->h, (pb.fd==-1?"[testval-1]":""), + offset, length)); + err = fsctl(path, afpfsByteRangeLock2FSCTL, &pb, 0); + if ( err==-1 ) { + int rc; + int tErrno = errno; + OSTRACE(("AFPSETLOCK failed to fsctl() '%s' %d %s\n", + path, tErrno, strerror(tErrno))); +#ifdef SQLITE_IGNORE_AFP_LOCK_ERRORS + rc = SQLITE_BUSY; +#else + rc = sqliteErrorFromPosixError(tErrno, + setLockFlag ? SQLITE_IOERR_LOCK : SQLITE_IOERR_UNLOCK); +#endif /* SQLITE_IGNORE_AFP_LOCK_ERRORS */ + if( IS_LOCK_ERROR(rc) ){ + storeLastErrno(pFile, tErrno); + } + return rc; + } else { + return SQLITE_OK; + } +} + +/* +** This routine checks if there is a RESERVED lock held on the specified +** file by this or any other process. If such a lock is held, set *pResOut +** to a non-zero value otherwise *pResOut is set to zero. The return value +** is set to SQLITE_OK unless an I/O error occurs during lock checking. +*/ +static int afpCheckReservedLock(sqlite3_file *id, int *pResOut){ + int rc = SQLITE_OK; + int reserved = 0; + unixFile *pFile = (unixFile*)id; + afpLockingContext *context; + + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); + + assert( pFile ); + context = (afpLockingContext *) pFile->lockingContext; + if( context->reserved ){ + *pResOut = 1; + return SQLITE_OK; + } + sqlite3_mutex_enter(pFile->pInode->pLockMutex); + /* Check if a thread in this process holds such a lock */ + if( pFile->pInode->eFileLock>SHARED_LOCK ){ + reserved = 1; + } + + /* Otherwise see if some other process holds it. + */ + if( !reserved ){ + /* lock the RESERVED byte */ + int lrc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1,1); + if( SQLITE_OK==lrc ){ + /* if we succeeded in taking the reserved lock, unlock it to restore + ** the original state */ + lrc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1, 0); + } else { + /* if we failed to get the lock then someone else must have it */ + reserved = 1; + } + if( IS_LOCK_ERROR(lrc) ){ + rc=lrc; + } + } + + sqlite3_mutex_leave(pFile->pInode->pLockMutex); + OSTRACE(("TEST WR-LOCK %d %d %d (afp)\n", pFile->h, rc, reserved)); + + *pResOut = reserved; + return rc; +} + +/* +** Lock the file with the lock specified by parameter eFileLock - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> (PENDING) -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** This routine will only increase a lock. Use the sqlite3OsUnlock() +** routine to lower a locking level. +*/ +static int afpLock(sqlite3_file *id, int eFileLock){ + int rc = SQLITE_OK; + unixFile *pFile = (unixFile*)id; + unixInodeInfo *pInode = pFile->pInode; + afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; + + assert( pFile ); + OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (afp)\n", pFile->h, + azFileLock(eFileLock), azFileLock(pFile->eFileLock), + azFileLock(pInode->eFileLock), pInode->nShared , osGetpid(0))); + + /* If there is already a lock of this type or more restrictive on the + ** unixFile, do nothing. Don't use the afp_end_lock: exit path, as + ** unixEnterMutex() hasn't been called yet. + */ + if( pFile->eFileLock>=eFileLock ){ + OSTRACE(("LOCK %d %s ok (already held) (afp)\n", pFile->h, + azFileLock(eFileLock))); + return SQLITE_OK; + } + + /* Make sure the locking sequence is correct + ** (1) We never move from unlocked to anything higher than shared lock. + ** (2) SQLite never explicitly requests a pending lock. + ** (3) A shared lock is always held when a reserve lock is requested. + */ + assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK ); + assert( eFileLock!=PENDING_LOCK ); + assert( eFileLock!=RESERVED_LOCK || pFile->eFileLock==SHARED_LOCK ); + + /* This mutex is needed because pFile->pInode is shared across threads + */ + pInode = pFile->pInode; + sqlite3_mutex_enter(pInode->pLockMutex); + + /* If some thread using this PID has a lock via a different unixFile* + ** handle that precludes the requested lock, return BUSY. + */ + if( (pFile->eFileLock!=pInode->eFileLock && + (pInode->eFileLock>=PENDING_LOCK || eFileLock>SHARED_LOCK)) + ){ + rc = SQLITE_BUSY; + goto afp_end_lock; + } + + /* If a SHARED lock is requested, and some thread using this PID already + ** has a SHARED or RESERVED lock, then increment reference counts and + ** return SQLITE_OK. + */ + if( eFileLock==SHARED_LOCK && + (pInode->eFileLock==SHARED_LOCK || pInode->eFileLock==RESERVED_LOCK) ){ + assert( eFileLock==SHARED_LOCK ); + assert( pFile->eFileLock==0 ); + assert( pInode->nShared>0 ); + pFile->eFileLock = SHARED_LOCK; + pInode->nShared++; + pInode->nLock++; + goto afp_end_lock; + } + + /* A PENDING lock is needed before acquiring a SHARED lock and before + ** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will + ** be released. + */ + if( eFileLock==SHARED_LOCK + || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLockdbPath, pFile, PENDING_BYTE, 1, 1); + if (failed) { + rc = failed; + goto afp_end_lock; + } + } + + /* If control gets to this point, then actually go ahead and make + ** operating system calls for the specified lock. + */ + if( eFileLock==SHARED_LOCK ){ + int lrc1, lrc2, lrc1Errno = 0; + long lk, mask; + + assert( pInode->nShared==0 ); + assert( pInode->eFileLock==0 ); + + mask = (sizeof(long)==8) ? LARGEST_INT64 : 0x7fffffff; + /* Now get the read-lock SHARED_LOCK */ + /* note that the quality of the randomness doesn't matter that much */ + lk = random(); + pInode->sharedByte = (lk & mask)%(SHARED_SIZE - 1); + lrc1 = afpSetLock(context->dbPath, pFile, + SHARED_FIRST+pInode->sharedByte, 1, 1); + if( IS_LOCK_ERROR(lrc1) ){ + lrc1Errno = pFile->lastErrno; + } + /* Drop the temporary PENDING lock */ + lrc2 = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0); + + if( IS_LOCK_ERROR(lrc1) ) { + storeLastErrno(pFile, lrc1Errno); + rc = lrc1; + goto afp_end_lock; + } else if( IS_LOCK_ERROR(lrc2) ){ + rc = lrc2; + goto afp_end_lock; + } else if( lrc1 != SQLITE_OK ) { + rc = lrc1; + } else { + pFile->eFileLock = SHARED_LOCK; + pInode->nLock++; + pInode->nShared = 1; + } + }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1 ){ + /* We are trying for an exclusive lock but another thread in this + ** same process is still holding a shared lock. */ + rc = SQLITE_BUSY; + }else{ + /* The request was for a RESERVED or EXCLUSIVE lock. It is + ** assumed that there is a SHARED or greater lock on the file + ** already. + */ + int failed = 0; + assert( 0!=pFile->eFileLock ); + if (eFileLock >= RESERVED_LOCK && pFile->eFileLock < RESERVED_LOCK) { + /* Acquire a RESERVED lock */ + failed = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1,1); + if( !failed ){ + context->reserved = 1; + } + } + if (!failed && eFileLock == EXCLUSIVE_LOCK) { + /* Acquire an EXCLUSIVE lock */ + + /* Remove the shared lock before trying the range. we'll need to + ** reestablish the shared lock if we can't get the afpUnlock + */ + if( !(failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST + + pInode->sharedByte, 1, 0)) ){ + int failed2 = SQLITE_OK; + /* now attempt to get the exclusive lock range */ + failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST, + SHARED_SIZE, 1); + if( failed && (failed2 = afpSetLock(context->dbPath, pFile, + SHARED_FIRST + pInode->sharedByte, 1, 1)) ){ + /* Can't reestablish the shared lock. Sqlite can't deal, this is + ** a critical I/O error + */ + rc = ((failed & 0xff) == SQLITE_IOERR) ? failed2 : + SQLITE_IOERR_LOCK; + goto afp_end_lock; + } + }else{ + rc = failed; + } + } + if( failed ){ + rc = failed; + } + } + + if( rc==SQLITE_OK ){ + pFile->eFileLock = eFileLock; + pInode->eFileLock = eFileLock; + }else if( eFileLock==EXCLUSIVE_LOCK ){ + pFile->eFileLock = PENDING_LOCK; + pInode->eFileLock = PENDING_LOCK; + } + +afp_end_lock: + sqlite3_mutex_leave(pInode->pLockMutex); + OSTRACE(("LOCK %d %s %s (afp)\n", pFile->h, azFileLock(eFileLock), + rc==SQLITE_OK ? "ok" : "failed")); + return rc; +} + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +*/ +static int afpUnlock(sqlite3_file *id, int eFileLock) { + int rc = SQLITE_OK; + unixFile *pFile = (unixFile*)id; + unixInodeInfo *pInode; + afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; + int skipShared = 0; + + assert( pFile ); + OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (afp)\n", pFile->h, eFileLock, + pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared, + osGetpid(0))); + + assert( eFileLock<=SHARED_LOCK ); + if( pFile->eFileLock<=eFileLock ){ + return SQLITE_OK; + } + pInode = pFile->pInode; + sqlite3_mutex_enter(pInode->pLockMutex); + assert( pInode->nShared!=0 ); + if( pFile->eFileLock>SHARED_LOCK ){ + assert( pInode->eFileLock==pFile->eFileLock ); + +#ifdef SQLITE_DEBUG + /* When reducing a lock such that other processes can start + ** reading the database file again, make sure that the + ** transaction counter was updated if any part of the database + ** file changed. If the transaction counter is not updated, + ** other connections to the same file might not realize that + ** the file has changed and hence might not know to flush their + ** cache. The use of a stale cache can lead to database corruption. + */ + assert( pFile->inNormalWrite==0 + || pFile->dbUpdate==0 + || pFile->transCntrChng==1 ); + pFile->inNormalWrite = 0; +#endif + + if( pFile->eFileLock==EXCLUSIVE_LOCK ){ + rc = afpSetLock(context->dbPath, pFile, SHARED_FIRST, SHARED_SIZE, 0); + if( rc==SQLITE_OK && (eFileLock==SHARED_LOCK || pInode->nShared>1) ){ + /* only re-establish the shared lock if necessary */ + int sharedLockByte = SHARED_FIRST+pInode->sharedByte; + rc = afpSetLock(context->dbPath, pFile, sharedLockByte, 1, 1); + } else { + skipShared = 1; + } + } + if( rc==SQLITE_OK && pFile->eFileLock>=PENDING_LOCK ){ + rc = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0); + } + if( rc==SQLITE_OK && pFile->eFileLock>=RESERVED_LOCK && context->reserved ){ + rc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1, 0); + if( !rc ){ + context->reserved = 0; + } + } + if( rc==SQLITE_OK && (eFileLock==SHARED_LOCK || pInode->nShared>1)){ + pInode->eFileLock = SHARED_LOCK; + } + } + if( rc==SQLITE_OK && eFileLock==NO_LOCK ){ + + /* Decrement the shared lock counter. Release the lock using an + ** OS call only when all threads in this same process have released + ** the lock. + */ + unsigned long long sharedLockByte = SHARED_FIRST+pInode->sharedByte; + pInode->nShared--; + if( pInode->nShared==0 ){ + if( !skipShared ){ + rc = afpSetLock(context->dbPath, pFile, sharedLockByte, 1, 0); + } + if( !rc ){ + pInode->eFileLock = NO_LOCK; + pFile->eFileLock = NO_LOCK; + } + } + if( rc==SQLITE_OK ){ + pInode->nLock--; + assert( pInode->nLock>=0 ); + if( pInode->nLock==0 ) closePendingFds(pFile); + } + } + + sqlite3_mutex_leave(pInode->pLockMutex); + if( rc==SQLITE_OK ){ + pFile->eFileLock = eFileLock; + } + return rc; +} + +/* +** Close a file & cleanup AFP specific locking context +*/ +static int afpClose(sqlite3_file *id) { + int rc = SQLITE_OK; + unixFile *pFile = (unixFile*)id; + assert( id!=0 ); + afpUnlock(id, NO_LOCK); + assert( unixFileMutexNotheld(pFile) ); + unixEnterMutex(); + if( pFile->pInode ){ + unixInodeInfo *pInode = pFile->pInode; + sqlite3_mutex_enter(pInode->pLockMutex); + if( pInode->nLock ){ + /* If there are outstanding locks, do not actually close the file just + ** yet because that would clear those locks. Instead, add the file + ** descriptor to pInode->aPending. It will be automatically closed when + ** the last lock is cleared. + */ + setPendingFd(pFile); + } + sqlite3_mutex_leave(pInode->pLockMutex); + } + releaseInodeInfo(pFile); + sqlite3_free(pFile->lockingContext); + rc = closeUnixFile(id); + unixLeaveMutex(); + return rc; +} + +#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ +/* +** The code above is the AFP lock implementation. The code is specific +** to MacOSX and does not work on other unix platforms. No alternative +** is available. If you don't compile for a mac, then the "unix-afp" +** VFS is not available. +** +********************* End of the AFP lock implementation ********************** +******************************************************************************/ + +/****************************************************************************** +*************************** Begin NFS Locking ********************************/ + +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE +/* + ** Lower the locking level on file descriptor pFile to eFileLock. eFileLock + ** must be either NO_LOCK or SHARED_LOCK. + ** + ** If the locking level of the file descriptor is already at or below + ** the requested locking level, this routine is a no-op. + */ +static int nfsUnlock(sqlite3_file *id, int eFileLock){ + return posixUnlock(id, eFileLock, 1); +} + +#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ +/* +** The code above is the NFS lock implementation. The code is specific +** to MacOSX and does not work on other unix platforms. No alternative +** is available. +** +********************* End of the NFS lock implementation ********************** +******************************************************************************/ + +/****************************************************************************** +**************** Non-locking sqlite3_file methods ***************************** +** +** The next division contains implementations for all methods of the +** sqlite3_file object other than the locking methods. The locking +** methods were defined in divisions above (one locking method per +** division). Those methods that are common to all locking modes +** are gather together into this division. +*/ + +/* +** Seek to the offset passed as the second argument, then read cnt +** bytes into pBuf. Return the number of bytes actually read. +** +** To avoid stomping the errno value on a failed read the lastErrno value +** is set before returning. +*/ +static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){ + int got; + int prior = 0; +#if (!defined(USE_PREAD) && !defined(USE_PREAD64)) + i64 newOffset; +#endif + TIMER_START; + assert( cnt==(cnt&0x1ffff) ); + assert( id->h>2 ); + do{ +#if defined(USE_PREAD) + got = osPread(id->h, pBuf, cnt, offset); + SimulateIOError( got = -1 ); +#elif defined(USE_PREAD64) + got = osPread64(id->h, pBuf, cnt, offset); + SimulateIOError( got = -1 ); +#else + newOffset = lseek(id->h, offset, SEEK_SET); + SimulateIOError( newOffset = -1 ); + if( newOffset<0 ){ + storeLastErrno((unixFile*)id, errno); + return -1; + } + got = osRead(id->h, pBuf, cnt); +#endif + if( got==cnt ) break; + if( got<0 ){ + if( errno==EINTR ){ got = 1; continue; } + prior = 0; + storeLastErrno((unixFile*)id, errno); + break; + }else if( got>0 ){ + cnt -= got; + offset += got; + prior += got; + pBuf = (void*)(got + (char*)pBuf); + } + }while( got>0 ); + TIMER_END; + OSTRACE(("READ %-3d %5d %7lld %llu\n", + id->h, got+prior, offset-prior, TIMER_ELAPSED)); + return got+prior; +} + +/* +** Read data from a file into a buffer. Return SQLITE_OK if all +** bytes were read successfully and SQLITE_IOERR if anything goes +** wrong. +*/ +static int unixRead( + sqlite3_file *id, + void *pBuf, + int amt, + sqlite3_int64 offset +){ + unixFile *pFile = (unixFile *)id; + int got; + assert( id ); + assert( offset>=0 ); + assert( amt>0 ); + + /* If this is a database file (not a journal, super-journal or temp + ** file), the bytes in the locking range should never be read or written. */ +#if 0 + assert( pFile->pPreallocatedUnused==0 + || offset>=PENDING_BYTE+512 + || offset+amt<=PENDING_BYTE + ); +#endif + +#if SQLITE_MAX_MMAP_SIZE>0 + /* Deal with as much of this read request as possible by transferring + ** data from the memory mapping using memcpy(). */ + if( offsetmmapSize ){ + if( offset+amt <= pFile->mmapSize ){ + memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt); + return SQLITE_OK; + }else{ + int nCopy = pFile->mmapSize - offset; + memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy); + pBuf = &((u8 *)pBuf)[nCopy]; + amt -= nCopy; + offset += nCopy; + } + } +#endif + + got = seekAndRead(pFile, offset, pBuf, amt); + if( got==amt ){ + return SQLITE_OK; + }else if( got<0 ){ + /* pFile->lastErrno has been set by seekAndRead(). + ** Usually we return SQLITE_IOERR_READ here, though for some + ** kinds of errors we return SQLITE_IOERR_CORRUPTFS. The + ** SQLITE_IOERR_CORRUPTFS will be converted into SQLITE_CORRUPT + ** prior to returning to the application by the sqlite3ApiExit() + ** routine. + */ + switch( pFile->lastErrno ){ + case ERANGE: + case EIO: +#ifdef ENXIO + case ENXIO: +#endif +#ifdef EDEVERR + case EDEVERR: +#endif + return SQLITE_IOERR_CORRUPTFS; + } + return SQLITE_IOERR_READ; + }else{ + storeLastErrno(pFile, 0); /* not a system error */ + /* Unread parts of the buffer must be zero-filled */ + memset(&((char*)pBuf)[got], 0, amt-got); + return SQLITE_IOERR_SHORT_READ; + } +} + +/* +** Attempt to seek the file-descriptor passed as the first argument to +** absolute offset iOff, then attempt to write nBuf bytes of data from +** pBuf to it. If an error occurs, return -1 and set *piErrno. Otherwise, +** return the actual number of bytes written (which may be less than +** nBuf). +*/ +static int seekAndWriteFd( + int fd, /* File descriptor to write to */ + i64 iOff, /* File offset to begin writing at */ + const void *pBuf, /* Copy data from this buffer to the file */ + int nBuf, /* Size of buffer pBuf in bytes */ + int *piErrno /* OUT: Error number if error occurs */ +){ + int rc = 0; /* Value returned by system call */ + + assert( nBuf==(nBuf&0x1ffff) ); + assert( fd>2 ); + assert( piErrno!=0 ); + nBuf &= 0x1ffff; + TIMER_START; + +#if defined(USE_PREAD) + do{ rc = (int)osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR ); +#elif defined(USE_PREAD64) + do{ rc = (int)osPwrite64(fd, pBuf, nBuf, iOff);}while( rc<0 && errno==EINTR); +#else + do{ + i64 iSeek = lseek(fd, iOff, SEEK_SET); + SimulateIOError( iSeek = -1 ); + if( iSeek<0 ){ + rc = -1; + break; + } + rc = osWrite(fd, pBuf, nBuf); + }while( rc<0 && errno==EINTR ); +#endif + + TIMER_END; + OSTRACE(("WRITE %-3d %5d %7lld %llu\n", fd, rc, iOff, TIMER_ELAPSED)); + + if( rc<0 ) *piErrno = errno; + return rc; +} + + +/* +** Seek to the offset in id->offset then read cnt bytes into pBuf. +** Return the number of bytes actually read. Update the offset. +** +** To avoid stomping the errno value on a failed write the lastErrno value +** is set before returning. +*/ +static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){ + return seekAndWriteFd(id->h, offset, pBuf, cnt, &id->lastErrno); +} + + +/* +** Write data from a buffer into a file. Return SQLITE_OK on success +** or some other error code on failure. +*/ +static int unixWrite( + sqlite3_file *id, + const void *pBuf, + int amt, + sqlite3_int64 offset +){ + unixFile *pFile = (unixFile*)id; + int wrote = 0; + assert( id ); + assert( amt>0 ); + + /* If this is a database file (not a journal, super-journal or temp + ** file), the bytes in the locking range should never be read or written. */ +#if 0 + assert( pFile->pPreallocatedUnused==0 + || offset>=PENDING_BYTE+512 + || offset+amt<=PENDING_BYTE + ); +#endif + +#ifdef SQLITE_DEBUG + /* If we are doing a normal write to a database file (as opposed to + ** doing a hot-journal rollback or a write to some file other than a + ** normal database file) then record the fact that the database + ** has changed. If the transaction counter is modified, record that + ** fact too. + */ + if( pFile->inNormalWrite ){ + pFile->dbUpdate = 1; /* The database has been modified */ + if( offset<=24 && offset+amt>=27 ){ + int rc; + char oldCntr[4]; + SimulateIOErrorBenign(1); + rc = seekAndRead(pFile, 24, oldCntr, 4); + SimulateIOErrorBenign(0); + if( rc!=4 || memcmp(oldCntr, &((char*)pBuf)[24-offset], 4)!=0 ){ + pFile->transCntrChng = 1; /* The transaction counter has changed */ + } + } + } +#endif + +#if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0 + /* Deal with as much of this write request as possible by transferring + ** data from the memory mapping using memcpy(). */ + if( offsetmmapSize ){ + if( offset+amt <= pFile->mmapSize ){ + memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt); + return SQLITE_OK; + }else{ + int nCopy = pFile->mmapSize - offset; + memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy); + pBuf = &((u8 *)pBuf)[nCopy]; + amt -= nCopy; + offset += nCopy; + } + } +#endif + + while( (wrote = seekAndWrite(pFile, offset, pBuf, amt))0 ){ + amt -= wrote; + offset += wrote; + pBuf = &((char*)pBuf)[wrote]; + } + SimulateIOError(( wrote=(-1), amt=1 )); + SimulateDiskfullError(( wrote=0, amt=1 )); + + if( amt>wrote ){ + if( wrote<0 && pFile->lastErrno!=ENOSPC ){ + /* lastErrno set by seekAndWrite */ + return SQLITE_IOERR_WRITE; + }else{ + storeLastErrno(pFile, 0); /* not a system error */ + return SQLITE_FULL; + } + } + + return SQLITE_OK; +} + +#ifdef SQLITE_TEST +/* +** Count the number of fullsyncs and normal syncs. This is used to test +** that syncs and fullsyncs are occurring at the right times. +*/ +SQLITE_API int sqlite3_sync_count = 0; +SQLITE_API int sqlite3_fullsync_count = 0; +#endif + +/* +** We do not trust systems to provide a working fdatasync(). Some do. +** Others do no. To be safe, we will stick with the (slightly slower) +** fsync(). If you know that your system does support fdatasync() correctly, +** then simply compile with -Dfdatasync=fdatasync or -DHAVE_FDATASYNC +*/ +#if !defined(fdatasync) && !HAVE_FDATASYNC +# define fdatasync fsync +#endif + +/* +** Define HAVE_FULLFSYNC to 0 or 1 depending on whether or not +** the F_FULLFSYNC macro is defined. F_FULLFSYNC is currently +** only available on Mac OS X. But that could change. +*/ +#ifdef F_FULLFSYNC +# define HAVE_FULLFSYNC 1 +#else +# define HAVE_FULLFSYNC 0 +#endif + + +/* +** The fsync() system call does not work as advertised on many +** unix systems. The following procedure is an attempt to make +** it work better. +** +** The SQLITE_NO_SYNC macro disables all fsync()s. This is useful +** for testing when we want to run through the test suite quickly. +** You are strongly advised *not* to deploy with SQLITE_NO_SYNC +** enabled, however, since with SQLITE_NO_SYNC enabled, an OS crash +** or power failure will likely corrupt the database file. +** +** SQLite sets the dataOnly flag if the size of the file is unchanged. +** The idea behind dataOnly is that it should only write the file content +** to disk, not the inode. We only set dataOnly if the file size is +** unchanged since the file size is part of the inode. However, +** Ted Ts'o tells us that fdatasync() will also write the inode if the +** file size has changed. The only real difference between fdatasync() +** and fsync(), Ted tells us, is that fdatasync() will not flush the +** inode if the mtime or owner or other inode attributes have changed. +** We only care about the file size, not the other file attributes, so +** as far as SQLite is concerned, an fdatasync() is always adequate. +** So, we always use fdatasync() if it is available, regardless of +** the value of the dataOnly flag. +*/ +static int full_fsync(int fd, int fullSync, int dataOnly){ + int rc; + + /* The following "ifdef/elif/else/" block has the same structure as + ** the one below. It is replicated here solely to avoid cluttering + ** up the real code with the UNUSED_PARAMETER() macros. + */ +#ifdef SQLITE_NO_SYNC + UNUSED_PARAMETER(fd); + UNUSED_PARAMETER(fullSync); + UNUSED_PARAMETER(dataOnly); +#elif HAVE_FULLFSYNC + UNUSED_PARAMETER(dataOnly); +#else + UNUSED_PARAMETER(fullSync); + UNUSED_PARAMETER(dataOnly); +#endif + + /* Record the number of times that we do a normal fsync() and + ** FULLSYNC. This is used during testing to verify that this procedure + ** gets called with the correct arguments. + */ +#ifdef SQLITE_TEST + if( fullSync ) sqlite3_fullsync_count++; + sqlite3_sync_count++; +#endif + + /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a + ** no-op. But go ahead and call fstat() to validate the file + ** descriptor as we need a method to provoke a failure during + ** coverage testing. + */ +#ifdef SQLITE_NO_SYNC + { + struct stat buf; + rc = osFstat(fd, &buf); + } +#elif HAVE_FULLFSYNC + if( fullSync ){ + rc = osFcntl(fd, F_FULLFSYNC, 0); + }else{ + rc = 1; + } + /* If the FULLFSYNC failed, fall back to attempting an fsync(). + ** It shouldn't be possible for fullfsync to fail on the local + ** file system (on OSX), so failure indicates that FULLFSYNC + ** isn't supported for this file system. So, attempt an fsync + ** and (for now) ignore the overhead of a superfluous fcntl call. + ** It'd be better to detect fullfsync support once and avoid + ** the fcntl call every time sync is called. + */ + if( rc ) rc = fsync(fd); + +#elif defined(__APPLE__) + /* fdatasync() on HFS+ doesn't yet flush the file size if it changed correctly + ** so currently we default to the macro that redefines fdatasync to fsync + */ + rc = fsync(fd); +#else + rc = fdatasync(fd); +#if OS_VXWORKS + if( rc==-1 && errno==ENOTSUP ){ + rc = fsync(fd); + } +#endif /* OS_VXWORKS */ +#endif /* ifdef SQLITE_NO_SYNC elif HAVE_FULLFSYNC */ + + if( OS_VXWORKS && rc!= -1 ){ + rc = 0; + } + return rc; +} + +/* +** Open a file descriptor to the directory containing file zFilename. +** If successful, *pFd is set to the opened file descriptor and +** SQLITE_OK is returned. If an error occurs, either SQLITE_NOMEM +** or SQLITE_CANTOPEN is returned and *pFd is set to an undefined +** value. +** +** The directory file descriptor is used for only one thing - to +** fsync() a directory to make sure file creation and deletion events +** are flushed to disk. Such fsyncs are not needed on newer +** journaling filesystems, but are required on older filesystems. +** +** This routine can be overridden using the xSetSysCall interface. +** The ability to override this routine was added in support of the +** chromium sandbox. Opening a directory is a security risk (we are +** told) so making it overrideable allows the chromium sandbox to +** replace this routine with a harmless no-op. To make this routine +** a no-op, replace it with a stub that returns SQLITE_OK but leaves +** *pFd set to a negative number. +** +** If SQLITE_OK is returned, the caller is responsible for closing +** the file descriptor *pFd using close(). +*/ +static int openDirectory(const char *zFilename, int *pFd){ + int ii; + int fd = -1; + char zDirname[MAX_PATHNAME+1]; + + sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename); + for(ii=(int)strlen(zDirname); ii>0 && zDirname[ii]!='/'; ii--); + if( ii>0 ){ + zDirname[ii] = '\0'; + }else{ + if( zDirname[0]!='/' ) zDirname[0] = '.'; + zDirname[1] = 0; + } + fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0); + if( fd>=0 ){ + OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname)); + } + *pFd = fd; + if( fd>=0 ) return SQLITE_OK; + return unixLogError(SQLITE_CANTOPEN_BKPT, "openDirectory", zDirname); +} + +/* +** Make sure all writes to a particular file are committed to disk. +** +** If dataOnly==0 then both the file itself and its metadata (file +** size, access time, etc) are synced. If dataOnly!=0 then only the +** file data is synced. +** +** Under Unix, also make sure that the directory entry for the file +** has been created by fsync-ing the directory that contains the file. +** If we do not do this and we encounter a power failure, the directory +** entry for the journal might not exist after we reboot. The next +** SQLite to access the file will not know that the journal exists (because +** the directory entry for the journal was never created) and the transaction +** will not roll back - possibly leading to database corruption. +*/ +static int unixSync(sqlite3_file *id, int flags){ + int rc; + unixFile *pFile = (unixFile*)id; + + int isDataOnly = (flags&SQLITE_SYNC_DATAONLY); + int isFullsync = (flags&0x0F)==SQLITE_SYNC_FULL; + + /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */ + assert((flags&0x0F)==SQLITE_SYNC_NORMAL + || (flags&0x0F)==SQLITE_SYNC_FULL + ); + + /* Unix cannot, but some systems may return SQLITE_FULL from here. This + ** line is to test that doing so does not cause any problems. + */ + SimulateDiskfullError( return SQLITE_FULL ); + + assert( pFile ); + OSTRACE(("SYNC %-3d\n", pFile->h)); + rc = full_fsync(pFile->h, isFullsync, isDataOnly); + SimulateIOError( rc=1 ); + if( rc ){ + storeLastErrno(pFile, errno); + return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath); + } + + /* Also fsync the directory containing the file if the DIRSYNC flag + ** is set. This is a one-time occurrence. Many systems (examples: AIX) + ** are unable to fsync a directory, so ignore errors on the fsync. + */ + if( pFile->ctrlFlags & UNIXFILE_DIRSYNC ){ + int dirfd; + OSTRACE(("DIRSYNC %s (have_fullfsync=%d fullsync=%d)\n", pFile->zPath, + HAVE_FULLFSYNC, isFullsync)); + rc = osOpenDirectory(pFile->zPath, &dirfd); + if( rc==SQLITE_OK ){ + full_fsync(dirfd, 0, 0); + robust_close(pFile, dirfd, __LINE__); + }else{ + assert( rc==SQLITE_CANTOPEN ); + rc = SQLITE_OK; + } + pFile->ctrlFlags &= ~UNIXFILE_DIRSYNC; + } + return rc; +} + +/* +** Truncate an open file to a specified size +*/ +static int unixTruncate(sqlite3_file *id, i64 nByte){ + unixFile *pFile = (unixFile *)id; + int rc; + assert( pFile ); + SimulateIOError( return SQLITE_IOERR_TRUNCATE ); + + /* If the user has configured a chunk-size for this file, truncate the + ** file so that it consists of an integer number of chunks (i.e. the + ** actual file size after the operation may be larger than the requested + ** size). + */ + if( pFile->szChunk>0 ){ + nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; + } + + rc = robust_ftruncate(pFile->h, nByte); + if( rc ){ + storeLastErrno(pFile, errno); + return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); + }else{ +#ifdef SQLITE_DEBUG + /* If we are doing a normal write to a database file (as opposed to + ** doing a hot-journal rollback or a write to some file other than a + ** normal database file) and we truncate the file to zero length, + ** that effectively updates the change counter. This might happen + ** when restoring a database using the backup API from a zero-length + ** source. + */ + if( pFile->inNormalWrite && nByte==0 ){ + pFile->transCntrChng = 1; + } +#endif + +#if SQLITE_MAX_MMAP_SIZE>0 + /* If the file was just truncated to a size smaller than the currently + ** mapped region, reduce the effective mapping size as well. SQLite will + ** use read() and write() to access data beyond this point from now on. + */ + if( nBytemmapSize ){ + pFile->mmapSize = nByte; + } +#endif + + return SQLITE_OK; + } +} + +/* +** Determine the current size of a file in bytes +*/ +static int unixFileSize(sqlite3_file *id, i64 *pSize){ + int rc; + struct stat buf; + assert( id ); + rc = osFstat(((unixFile*)id)->h, &buf); + SimulateIOError( rc=1 ); + if( rc!=0 ){ + storeLastErrno((unixFile*)id, errno); + return SQLITE_IOERR_FSTAT; + } + *pSize = buf.st_size; + + /* When opening a zero-size database, the findInodeInfo() procedure + ** writes a single byte into that file in order to work around a bug + ** in the OS-X msdos filesystem. In order to avoid problems with upper + ** layers, we need to report this file size as zero even though it is + ** really 1. Ticket #3260. + */ + if( *pSize==1 ) *pSize = 0; + + + return SQLITE_OK; +} + +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) +/* +** Handler for proxy-locking file-control verbs. Defined below in the +** proxying locking division. +*/ +static int proxyFileControl(sqlite3_file*,int,void*); +#endif + +/* +** This function is called to handle the SQLITE_FCNTL_SIZE_HINT +** file-control operation. Enlarge the database to nBytes in size +** (rounded up to the next chunk-size). If the database is already +** nBytes or larger, this routine is a no-op. +*/ +static int fcntlSizeHint(unixFile *pFile, i64 nByte){ + if( pFile->szChunk>0 ){ + i64 nSize; /* Required file size */ + struct stat buf; /* Used to hold return values of fstat() */ + + if( osFstat(pFile->h, &buf) ){ + return SQLITE_IOERR_FSTAT; + } + + nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk; + if( nSize>(i64)buf.st_size ){ + +#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE + /* The code below is handling the return value of osFallocate() + ** correctly. posix_fallocate() is defined to "returns zero on success, + ** or an error number on failure". See the manpage for details. */ + int err; + do{ + err = osFallocate(pFile->h, buf.st_size, nSize-buf.st_size); + }while( err==EINTR ); + if( err && err!=EINVAL ) return SQLITE_IOERR_WRITE; +#else + /* If the OS does not have posix_fallocate(), fake it. Write a + ** single byte to the last byte in each block that falls entirely + ** within the extended region. Then, if required, a single byte + ** at offset (nSize-1), to set the size of the file correctly. + ** This is a similar technique to that used by glibc on systems + ** that do not have a real fallocate() call. + */ + int nBlk = buf.st_blksize; /* File-system block size */ + int nWrite = 0; /* Number of bytes written by seekAndWrite */ + i64 iWrite; /* Next offset to write to */ + + iWrite = (buf.st_size/nBlk)*nBlk + nBlk - 1; + assert( iWrite>=buf.st_size ); + assert( ((iWrite+1)%nBlk)==0 ); + for(/*no-op*/; iWrite=nSize ) iWrite = nSize - 1; + nWrite = seekAndWrite(pFile, iWrite, "", 1); + if( nWrite!=1 ) return SQLITE_IOERR_WRITE; + } +#endif + } + } + +#if SQLITE_MAX_MMAP_SIZE>0 + if( pFile->mmapSizeMax>0 && nByte>pFile->mmapSize ){ + int rc; + if( pFile->szChunk<=0 ){ + if( robust_ftruncate(pFile->h, nByte) ){ + storeLastErrno(pFile, errno); + return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); + } + } + + rc = unixMapfile(pFile, nByte); + return rc; + } +#endif + + return SQLITE_OK; +} + +/* +** If *pArg is initially negative then this is a query. Set *pArg to +** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set. +** +** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags. +*/ +static void unixModeBit(unixFile *pFile, unsigned char mask, int *pArg){ + if( *pArg<0 ){ + *pArg = (pFile->ctrlFlags & mask)!=0; + }else if( (*pArg)==0 ){ + pFile->ctrlFlags &= ~mask; + }else{ + pFile->ctrlFlags |= mask; + } +} + +/* Forward declaration */ +static int unixGetTempname(int nBuf, char *zBuf); +#if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL) + static int unixFcntlExternalReader(unixFile*, int*); +#endif +#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT) + static void unixDescribeShm(sqlite3_str*,unixShm*); +#endif + + +/* +** Information and control of an open file handle. +*/ +static int unixFileControl(sqlite3_file *id, int op, void *pArg){ + unixFile *pFile = (unixFile*)id; + switch( op ){ +#if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) + case SQLITE_FCNTL_BEGIN_ATOMIC_WRITE: { + int rc = osIoctl(pFile->h, F2FS_IOC_START_ATOMIC_WRITE); + return rc ? SQLITE_IOERR_BEGIN_ATOMIC : SQLITE_OK; + } + case SQLITE_FCNTL_COMMIT_ATOMIC_WRITE: { + int rc = osIoctl(pFile->h, F2FS_IOC_COMMIT_ATOMIC_WRITE); + return rc ? SQLITE_IOERR_COMMIT_ATOMIC : SQLITE_OK; + } + case SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE: { + int rc = osIoctl(pFile->h, F2FS_IOC_ABORT_VOLATILE_WRITE); + return rc ? SQLITE_IOERR_ROLLBACK_ATOMIC : SQLITE_OK; + } +#endif /* __linux__ && SQLITE_ENABLE_BATCH_ATOMIC_WRITE */ + + case SQLITE_FCNTL_NULL_IO: { + osClose(pFile->h); + pFile->h = -1; + return SQLITE_OK; + } + case SQLITE_FCNTL_LOCKSTATE: { + *(int*)pArg = pFile->eFileLock; + return SQLITE_OK; + } + case SQLITE_FCNTL_LAST_ERRNO: { + *(int*)pArg = pFile->lastErrno; + return SQLITE_OK; + } + case SQLITE_FCNTL_CHUNK_SIZE: { + pFile->szChunk = *(int *)pArg; + return SQLITE_OK; + } + case SQLITE_FCNTL_SIZE_HINT: { + int rc; + SimulateIOErrorBenign(1); + rc = fcntlSizeHint(pFile, *(i64 *)pArg); + SimulateIOErrorBenign(0); + return rc; + } + case SQLITE_FCNTL_PERSIST_WAL: { + unixModeBit(pFile, UNIXFILE_PERSIST_WAL, (int*)pArg); + return SQLITE_OK; + } + case SQLITE_FCNTL_POWERSAFE_OVERWRITE: { + unixModeBit(pFile, UNIXFILE_PSOW, (int*)pArg); + return SQLITE_OK; + } + case SQLITE_FCNTL_VFSNAME: { + *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName); + return SQLITE_OK; + } + case SQLITE_FCNTL_TEMPFILENAME: { + char *zTFile = sqlite3_malloc64( pFile->pVfs->mxPathname ); + if( zTFile ){ + unixGetTempname(pFile->pVfs->mxPathname, zTFile); + *(char**)pArg = zTFile; + } + return SQLITE_OK; + } + case SQLITE_FCNTL_HAS_MOVED: { + *(int*)pArg = fileHasMoved(pFile); + return SQLITE_OK; + } +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + case SQLITE_FCNTL_LOCK_TIMEOUT: { + int iOld = pFile->iBusyTimeout; + int iNew = *(int*)pArg; +#if SQLITE_ENABLE_SETLK_TIMEOUT==1 + pFile->iBusyTimeout = iNew<0 ? 0x7FFFFFFF : (unsigned)iNew; +#elif SQLITE_ENABLE_SETLK_TIMEOUT==2 + pFile->iBusyTimeout = !!(*(int*)pArg); +#else +# error "SQLITE_ENABLE_SETLK_TIMEOUT must be set to 1 or 2" +#endif + *(int*)pArg = iOld; + return SQLITE_OK; + } + case SQLITE_FCNTL_BLOCK_ON_CONNECT: { + int iNew = *(int*)pArg; + pFile->bBlockOnConnect = iNew; + return SQLITE_OK; + } +#endif /* SQLITE_ENABLE_SETLK_TIMEOUT */ +#if SQLITE_MAX_MMAP_SIZE>0 + case SQLITE_FCNTL_MMAP_SIZE: { + i64 newLimit = *(i64*)pArg; + int rc = SQLITE_OK; + if( newLimit>sqlite3GlobalConfig.mxMmap ){ + newLimit = sqlite3GlobalConfig.mxMmap; + } + + /* The value of newLimit may be eventually cast to (size_t) and passed + ** to mmap(). Restrict its value to 2GB if (size_t) is not at least a + ** 64-bit type. */ + if( newLimit>0 && sizeof(size_t)<8 ){ + newLimit = (newLimit & 0x7FFFFFFF); + } + + *(i64*)pArg = pFile->mmapSizeMax; + if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){ + pFile->mmapSizeMax = newLimit; + if( pFile->mmapSize>0 ){ + unixUnmapfile(pFile); + rc = unixMapfile(pFile, -1); + } + } + return rc; + } +#endif +#ifdef SQLITE_DEBUG + /* The pager calls this method to signal that it has done + ** a rollback and that the database is therefore unchanged and + ** it hence it is OK for the transaction change counter to be + ** unchanged. + */ + case SQLITE_FCNTL_DB_UNCHANGED: { + ((unixFile*)id)->dbUpdate = 0; + return SQLITE_OK; + } +#endif +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) + case SQLITE_FCNTL_SET_LOCKPROXYFILE: + case SQLITE_FCNTL_GET_LOCKPROXYFILE: { + return proxyFileControl(id,op,pArg); + } +#endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */ + + case SQLITE_FCNTL_EXTERNAL_READER: { +#if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL) + return unixFcntlExternalReader((unixFile*)id, (int*)pArg); +#else + *(int*)pArg = 0; + return SQLITE_OK; +#endif + } + +#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT) + case SQLITE_FCNTL_FILESTAT: { + sqlite3_str *pStr = (sqlite3_str*)pArg; + char aLck[16]; + unixInodeInfo *pInode; + static const char *azLock[] = { "SHARED", "RESERVED", + "PENDING", "EXCLUSIVE" }; + sqlite3_str_appendf(pStr, "{\"h\":%d", pFile->h); + sqlite3_str_appendf(pStr, ",\"vfs\":\"%s\"", pFile->pVfs->zName); + if( pFile->eFileLock ){ + sqlite3_str_appendf(pStr, ",\"eFileLock\":\"%s\"", + azLock[pFile->eFileLock-1]); + if( unixPosixAdvisoryLocks(pFile->h, aLck)==SQLITE_OK ){ + sqlite3_str_appendf(pStr, ",\"pal\":\"%s\"", aLck); + } + } + unixEnterMutex(); + if( pFile->pShm ){ + sqlite3_str_appendall(pStr, ",\"shm\":"); + unixDescribeShm(pStr, pFile->pShm); + } +#if SQLITE_MAX_MMAP_SIZE>0 + if( pFile->mmapSize ){ + sqlite3_str_appendf(pStr, ",\"mmapSize\":%lld", pFile->mmapSize); + sqlite3_str_appendf(pStr, ",\"nFetchOut\":%d", pFile->nFetchOut); + } +#endif + if( (pInode = pFile->pInode)!=0 ){ + sqlite3_str_appendf(pStr, ",\"inode\":{\"nRef\":%d",pInode->nRef); + sqlite3_mutex_enter(pInode->pLockMutex); + sqlite3_str_appendf(pStr, ",\"nShared\":%d", pInode->nShared); + if( pInode->eFileLock ){ + sqlite3_str_appendf(pStr, ",\"eFileLock\":\"%s\"", + azLock[pInode->eFileLock-1]); + } + if( pInode->pUnused ){ + char cSep = '['; + UnixUnusedFd *pUFd = pFile->pInode->pUnused; + sqlite3_str_appendall(pStr, ",\"unusedFd\":"); + while( pUFd ){ + sqlite3_str_appendf(pStr, "%c{\"fd\":%d,\"flags\":%d", + cSep, pUFd->fd, pUFd->flags); + cSep = ','; + if( unixPosixAdvisoryLocks(pUFd->fd, aLck)==SQLITE_OK ){ + sqlite3_str_appendf(pStr, ",\"pal\":\"%s\"", aLck); + } + sqlite3_str_append(pStr, "}", 1); + pUFd = pUFd->pNext; + } + sqlite3_str_append(pStr, "]", 1); + } + sqlite3_mutex_leave(pInode->pLockMutex); + sqlite3_str_append(pStr, "}", 1); + } + unixLeaveMutex(); + sqlite3_str_append(pStr, "}", 1); + return SQLITE_OK; + } +#endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */ + } + return SQLITE_NOTFOUND; +} + +/* +** If pFd->sectorSize is non-zero when this function is called, it is a +** no-op. Otherwise, the values of pFd->sectorSize and +** pFd->deviceCharacteristics are set according to the file-system +** characteristics. +** +** There are two versions of this function. One for QNX and one for all +** other systems. +*/ +#ifndef __QNXNTO__ +static void setDeviceCharacteristics(unixFile *pFd){ + assert( pFd->deviceCharacteristics==0 || pFd->sectorSize!=0 ); + if( pFd->sectorSize==0 ){ +#if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) + int res; + u32 f = 0; + + /* Check for support for F2FS atomic batch writes. */ + res = osIoctl(pFd->h, F2FS_IOC_GET_FEATURES, &f); + if( res==0 && (f & F2FS_FEATURE_ATOMIC_WRITE) ){ + pFd->deviceCharacteristics = SQLITE_IOCAP_BATCH_ATOMIC; + } +#endif /* __linux__ && SQLITE_ENABLE_BATCH_ATOMIC_WRITE */ + + /* Set the POWERSAFE_OVERWRITE flag if requested. */ + if( pFd->ctrlFlags & UNIXFILE_PSOW ){ + pFd->deviceCharacteristics |= SQLITE_IOCAP_POWERSAFE_OVERWRITE; + } + pFd->deviceCharacteristics |= SQLITE_IOCAP_SUBPAGE_READ; + + pFd->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; + } +} +#else +#include +#include +static void setDeviceCharacteristics(unixFile *pFile){ + if( pFile->sectorSize == 0 ){ + struct statvfs fsInfo; + + /* Set defaults for non-supported filesystems */ + pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; + pFile->deviceCharacteristics = 0; + if( fstatvfs(pFile->h, &fsInfo) == -1 ) { + return; + } + + if( !strcmp(fsInfo.f_basetype, "tmp") ) { + pFile->sectorSize = fsInfo.f_bsize; + pFile->deviceCharacteristics = + SQLITE_IOCAP_ATOMIC4K | /* All ram filesystem writes are atomic */ + SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until + ** the write succeeds */ + SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind + ** so it is ordered */ + 0; + }else if( strstr(fsInfo.f_basetype, "etfs") ){ + pFile->sectorSize = fsInfo.f_bsize; + pFile->deviceCharacteristics = + /* etfs cluster size writes are atomic */ + (pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) | + SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until + ** the write succeeds */ + SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind + ** so it is ordered */ + 0; + }else if( !strcmp(fsInfo.f_basetype, "qnx6") ){ + pFile->sectorSize = fsInfo.f_bsize; + pFile->deviceCharacteristics = + SQLITE_IOCAP_ATOMIC | /* All filesystem writes are atomic */ + SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until + ** the write succeeds */ + SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind + ** so it is ordered */ + 0; + }else if( !strcmp(fsInfo.f_basetype, "qnx4") ){ + pFile->sectorSize = fsInfo.f_bsize; + pFile->deviceCharacteristics = + /* full bitset of atomics from max sector size and smaller */ + (((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2) | + SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind + ** so it is ordered */ + 0; + }else if( strstr(fsInfo.f_basetype, "dos") ){ + pFile->sectorSize = fsInfo.f_bsize; + pFile->deviceCharacteristics = + /* full bitset of atomics from max sector size and smaller */ + (((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2) | + SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind + ** so it is ordered */ + 0; + }else{ + pFile->deviceCharacteristics = + SQLITE_IOCAP_ATOMIC512 | /* blocks are atomic */ + SQLITE_IOCAP_SAFE_APPEND | /* growing the file does not occur until + ** the write succeeds */ + 0; + } + } + /* Last chance verification. If the sector size isn't a multiple of 512 + ** then it isn't valid.*/ + if( pFile->sectorSize % 512 != 0 ){ + pFile->deviceCharacteristics = 0; + pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; + } +} +#endif + +/* +** Return the sector size in bytes of the underlying block device for +** the specified file. This is almost always 512 bytes, but may be +** larger for some devices. +** +** SQLite code assumes this function cannot fail. It also assumes that +** if two files are created in the same file-system directory (i.e. +** a database and its journal file) that the sector size will be the +** same for both. +*/ +static int unixSectorSize(sqlite3_file *id){ + unixFile *pFd = (unixFile*)id; + setDeviceCharacteristics(pFd); + return pFd->sectorSize; +} + +/* +** Return the device characteristics for the file. +** +** This VFS is set up to return SQLITE_IOCAP_POWERSAFE_OVERWRITE by default. +** However, that choice is controversial since technically the underlying +** file system does not always provide powersafe overwrites. (In other +** words, after a power-loss event, parts of the file that were never +** written might end up being altered.) However, non-PSOW behavior is very, +** very rare. And asserting PSOW makes a large reduction in the amount +** of required I/O for journaling, since a lot of padding is eliminated. +** Hence, while POWERSAFE_OVERWRITE is on by default, there is a file-control +** available to turn it off and URI query parameter available to turn it off. +*/ +static int unixDeviceCharacteristics(sqlite3_file *id){ + unixFile *pFd = (unixFile*)id; + setDeviceCharacteristics(pFd); + return pFd->deviceCharacteristics; +} + +#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 + +/* +** Return the system page size. +** +** This function should not be called directly by other code in this file. +** Instead, it should be called via macro osGetpagesize(). +*/ +static int unixGetpagesize(void){ +#if OS_VXWORKS + return 1024; +#elif defined(_BSD_SOURCE) + return getpagesize(); +#else + return (int)sysconf(_SC_PAGESIZE); +#endif +} + +#endif /* !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 */ + +#if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL) + +/* +** Object used to represent an shared memory buffer. +** +** When multiple threads all reference the same wal-index, each thread +** has its own unixShm object, but they all point to a single instance +** of this unixShmNode object. In other words, each wal-index is opened +** only once per process. +** +** Each unixShmNode object is connected to a single unixInodeInfo object. +** We could coalesce this object into unixInodeInfo, but that would mean +** every open file that does not use shared memory (in other words, most +** open files) would have to carry around this extra information. So +** the unixInodeInfo object contains a pointer to this unixShmNode object +** and the unixShmNode object is created only when needed. +** +** unixMutexHeld() must be true when creating or destroying +** this object or while reading or writing the following fields: +** +** nRef +** +** The following fields are read-only after the object is created: +** +** hShm +** zFilename +** +** Either unixShmNode.pShmMutex must be held or unixShmNode.nRef==0 and +** unixMutexHeld() is true when reading or writing any other field +** in this structure. +** +** aLock[SQLITE_SHM_NLOCK]: +** This array records the various locks held by clients on each of the +** SQLITE_SHM_NLOCK slots. If the aLock[] entry is set to 0, then no +** locks are held by the process on this slot. If it is set to -1, then +** some client holds an EXCLUSIVE lock on the locking slot. If the aLock[] +** value is set to a positive value, then it is the number of shared +** locks currently held on the slot. +** +** aMutex[SQLITE_SHM_NLOCK]: +** Normally, when SQLITE_ENABLE_SETLK_TIMEOUT is not defined, mutex +** pShmMutex is used to protect the aLock[] array and the right to +** call fcntl() on unixShmNode.hShm to obtain or release locks. +** +** If SQLITE_ENABLE_SETLK_TIMEOUT is defined though, we use an array +** of mutexes - one for each locking slot. To read or write locking +** slot aLock[iSlot], the caller must hold the corresponding mutex +** aMutex[iSlot]. Similarly, to call fcntl() to obtain or release a +** lock corresponding to slot iSlot, mutex aMutex[iSlot] must be held. +*/ +struct unixShmNode { + unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */ + sqlite3_mutex *pShmMutex; /* Mutex to access this object */ + char *zFilename; /* Name of the mmapped file */ + int hShm; /* Open file descriptor */ + int szRegion; /* Size of shared-memory regions */ + u16 nRegion; /* Size of array apRegion */ + u8 isReadonly; /* True if read-only */ + u8 isUnlocked; /* True if no DMS lock held */ + char **apRegion; /* Array of mapped shared-memory regions */ + int nRef; /* Number of unixShm objects pointing to this */ + unixShm *pFirst; /* All unixShm objects pointing to this */ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + sqlite3_mutex *aMutex[SQLITE_SHM_NLOCK]; +#endif + int aLock[SQLITE_SHM_NLOCK]; /* # shared locks on slot, -1==excl lock */ +#ifdef SQLITE_DEBUG + u8 nextShmId; /* Next available unixShm.id value */ +#endif +}; + +/* +** Structure used internally by this VFS to record the state of an +** open shared memory connection. +** +** The following fields are initialized when this object is created and +** are read-only thereafter: +** +** unixShm.pShmNode +** unixShm.id +** +** All other fields are read/write. The unixShm.pShmNode->pShmMutex must +** be held while accessing any read/write fields. +*/ +struct unixShm { + unixShmNode *pShmNode; /* The underlying unixShmNode object */ + unixShm *pNext; /* Next unixShm with the same unixShmNode */ + u8 hasMutex; /* True if holding the unixShmNode->pShmMutex */ + u8 id; /* Id of this connection within its unixShmNode */ + u16 sharedMask; /* Mask of shared locks held */ + u16 exclMask; /* Mask of exclusive locks held */ +}; + +/* +** Constants used for locking +*/ +#define UNIX_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ +#define UNIX_SHM_DMS (UNIX_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ + +#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT) +/* +** Describe the pShm object using JSON. Used for diagnostics only. +*/ +static void unixDescribeShm(sqlite3_str *pStr, unixShm *pShm){ + unixShmNode *pNode = pShm->pShmNode; + char aLck[16]; + sqlite3_str_appendf(pStr, "{\"h\":%d", pNode->hShm); + assert( unixMutexHeld() ); + sqlite3_str_appendf(pStr, ",\"nRef\":%d", pNode->nRef); + sqlite3_str_appendf(pStr, ",\"id\":%d", pShm->id); + sqlite3_str_appendf(pStr, ",\"sharedMask\":%d", pShm->sharedMask); + sqlite3_str_appendf(pStr, ",\"exclMask\":%d", pShm->exclMask); + if( unixPosixAdvisoryLocks(pNode->hShm, aLck)==SQLITE_OK ){ + sqlite3_str_appendf(pStr, ",\"pal\":\"%s\"", aLck); + } + sqlite3_str_append(pStr, "}", 1); +} +#endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */ + +/* +** Use F_GETLK to check whether or not there are any readers with open +** wal-mode transactions in other processes on database file pFile. If +** no error occurs, return SQLITE_OK and set (*piOut) to 1 if there are +** such transactions, or 0 otherwise. If an error occurs, return an +** SQLite error code. The final value of *piOut is undefined in this +** case. +*/ +static int unixFcntlExternalReader(unixFile *pFile, int *piOut){ + int rc = SQLITE_OK; + *piOut = 0; + if( pFile->pShm){ + unixShmNode *pShmNode = pFile->pShm->pShmNode; + struct flock f; + + memset(&f, 0, sizeof(f)); + f.l_type = F_WRLCK; + f.l_whence = SEEK_SET; + f.l_start = UNIX_SHM_BASE + 3; + f.l_len = SQLITE_SHM_NLOCK - 3; + + sqlite3_mutex_enter(pShmNode->pShmMutex); + if( osFcntl(pShmNode->hShm, F_GETLK, &f)<0 ){ + rc = SQLITE_IOERR_LOCK; + }else{ + *piOut = (f.l_type!=F_UNLCK); + } + sqlite3_mutex_leave(pShmNode->pShmMutex); + } + + return rc; +} + +/* +** If pFile has a -shm file open and it is sharing that file with some +** other connection, either in the same process or in a separate process, +** then return true. Return false if either pFile does not have a -shm +** file open or if it is the only connection to that -shm file across the +** entire system. +** +** This routine is not required for correct operation. It can always return +** false and SQLite will continue to operate according to spec. However, +** when this routine does its job, it adds extra robustness in cases +** where database file locks have been erroneously deleted in a WAL-mode +** database by doing close(open(DATABASE_PATHNAME)) or similar. +** +** With false negatives, SQLite still operates to spec, though with less +** robustness. With false positives, the last database connection on a +** WAL-mode database will fail to unlink the -wal and -shm files, which +** is annoying but harmless. False positives will also prevent a database +** connection from running "PRAGMA journal_mode=DELETE" in order to take +** the database out of WAL mode, which is perhaps more serious, but is +** still not a disaster. +*/ +static int unixIsSharingShmNode(unixFile *pFile){ + unixShmNode *pShmNode; + struct flock lock; + if( pFile->pShm==0 ) return 0; + if( pFile->ctrlFlags & UNIXFILE_EXCL ) return 0; + pShmNode = pFile->pShm->pShmNode; +#if SQLITE_ATOMIC_INTRINSICS + assert( AtomicLoad(&pShmNode->nRef)==1 ); +#endif + memset(&lock, 0, sizeof(lock)); + lock.l_whence = SEEK_SET; + lock.l_start = UNIX_SHM_DMS; + lock.l_len = 1; + lock.l_type = F_WRLCK; + osFcntl(pShmNode->hShm, F_GETLK, &lock); + return (lock.l_type!=F_UNLCK); +} + +/* +** Apply posix advisory locks for all bytes from ofst through ofst+n-1. +** +** Locks block if the mask is exactly UNIX_SHM_C and are non-blocking +** otherwise. +*/ +static int unixShmSystemLock( + unixFile *pFile, /* Open connection to the WAL file */ + int lockType, /* F_UNLCK, F_RDLCK, or F_WRLCK */ + int ofst, /* First byte of the locking range */ + int n /* Number of bytes to lock */ +){ + unixShmNode *pShmNode; /* Apply locks to this open shared-memory segment */ + struct flock f; /* The posix advisory locking structure */ + int rc = SQLITE_OK; /* Result code form fcntl() */ + + pShmNode = pFile->pInode->pShmNode; + + /* Assert that the parameters are within expected range and that the + ** correct mutex or mutexes are held. */ + assert( pShmNode->nRef>=0 ); + assert( (ofst==UNIX_SHM_DMS && n==1) + || (ofst>=UNIX_SHM_BASE && ofst+n<=(UNIX_SHM_BASE+SQLITE_SHM_NLOCK)) + ); + if( ofst==UNIX_SHM_DMS ){ + assert( pShmNode->nRef>0 || unixMutexHeld() ); + assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) ); + }else{ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + int ii; + for(ii=ofst-UNIX_SHM_BASE; iiaMutex[ii]) ); + } +#else + assert( sqlite3_mutex_held(pShmNode->pShmMutex) ); + assert( pShmNode->nRef>0 ); +#endif + } + + /* Shared locks never span more than one byte */ + assert( n==1 || lockType!=F_RDLCK ); + + /* Locks are within range */ + assert( n>=1 && n<=SQLITE_SHM_NLOCK ); + assert( ofst>=UNIX_SHM_BASE && ofst<=UNIX_SHM_DMS ); + assert( ofst+n-1<=UNIX_SHM_DMS ); + + if( pShmNode->hShm>=0 ){ + int res; + /* Initialize the locking parameters */ + f.l_type = lockType; + f.l_whence = SEEK_SET; + f.l_start = ofst; + f.l_len = n; + res = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile); + if( res==-1 ){ +#if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && SQLITE_ENABLE_SETLK_TIMEOUT==1 + rc = (pFile->iBusyTimeout ? SQLITE_BUSY_TIMEOUT : SQLITE_BUSY); +#else + rc = SQLITE_BUSY; +#endif + } + } + + /* Do debug tracing */ +#ifdef SQLITE_DEBUG + OSTRACE(("SHM-LOCK ")); + if( rc==SQLITE_OK ){ + if( lockType==F_UNLCK ){ + OSTRACE(("unlock %d..%d ok\n", ofst, ofst+n-1)); + }else if( lockType==F_RDLCK ){ + OSTRACE(("read-lock %d..%d ok\n", ofst, ofst+n-1)); + }else{ + assert( lockType==F_WRLCK ); + OSTRACE(("write-lock %d..%d ok\n", ofst, ofst+n-1)); + } + }else{ + if( lockType==F_UNLCK ){ + OSTRACE(("unlock %d..%d failed\n", ofst, ofst+n-1)); + }else if( lockType==F_RDLCK ){ + OSTRACE(("read-lock %d..%d failed\n", ofst, ofst+n-1)); + }else{ + assert( lockType==F_WRLCK ); + OSTRACE(("write-lock %d..%d failed\n", ofst, ofst+n-1)); + } + } +#endif + + return rc; +} + +/* +** Return the minimum number of 32KB shm regions that should be mapped at +** a time, assuming that each mapping must be an integer multiple of the +** current system page-size. +** +** Usually, this is 1. The exception seems to be systems that are configured +** to use 64KB pages - in this case each mapping must cover at least two +** shm regions. +*/ +static int unixShmRegionPerMap(void){ + int shmsz = 32*1024; /* SHM region size */ + int pgsz = osGetpagesize(); /* System page size */ + assert( ((pgsz-1)&pgsz)==0 ); /* Page size must be a power of 2 */ + if( pgszpInode->pShmNode; + assert( unixMutexHeld() ); + if( p && ALWAYS(p->nRef==0) ){ + int nShmPerMap = unixShmRegionPerMap(); + int i; + assert( p->pInode==pFd->pInode ); + sqlite3_mutex_free(p->pShmMutex); +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + for(i=0; iaMutex[i]); + } +#endif + for(i=0; inRegion; i+=nShmPerMap){ + if( p->hShm>=0 ){ + osMunmap(p->apRegion[i], p->szRegion); + }else{ + sqlite3_free(p->apRegion[i]); + } + } + sqlite3_free(p->apRegion); + if( p->hShm>=0 ){ + robust_close(pFd, p->hShm, __LINE__); + p->hShm = -1; + } + p->pInode->pShmNode = 0; + sqlite3_free(p); + } +} + +/* +** The DMS lock has not yet been taken on shm file pShmNode. Attempt to +** take it now. Return SQLITE_OK if successful, or an SQLite error +** code otherwise. +** +** If the DMS cannot be locked because this is a readonly_shm=1 +** connection and no other process already holds a lock, return +** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1. +*/ +static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){ + struct flock lock; + int rc = SQLITE_OK; + + /* Use F_GETLK to determine the locks other processes are holding + ** on the DMS byte. If it indicates that another process is holding + ** a SHARED lock, then this process may also take a SHARED lock + ** and proceed with opening the *-shm file. + ** + ** Or, if no other process is holding any lock, then this process + ** is the first to open it. In this case take an EXCLUSIVE lock on the + ** DMS byte and truncate the *-shm file to zero bytes in size. Then + ** downgrade to a SHARED lock on the DMS byte. + ** + ** If another process is holding an EXCLUSIVE lock on the DMS byte, + ** return SQLITE_BUSY to the caller (it will try again). An earlier + ** version of this code attempted the SHARED lock at this point. But + ** this introduced a subtle race condition: if the process holding + ** EXCLUSIVE failed just before truncating the *-shm file, then this + ** process might open and use the *-shm file without truncating it. + ** And if the *-shm file has been corrupted by a power failure or + ** system crash, the database itself may also become corrupt. */ + lock.l_whence = SEEK_SET; + lock.l_start = UNIX_SHM_DMS; + lock.l_len = 1; + lock.l_type = F_WRLCK; + if( osFcntl(pShmNode->hShm, F_GETLK, &lock)!=0 ) { + rc = SQLITE_IOERR_LOCK; + }else if( lock.l_type==F_UNLCK ){ + if( pShmNode->isReadonly ){ + pShmNode->isUnlocked = 1; + rc = SQLITE_READONLY_CANTINIT; + }else{ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + /* Do not use a blocking lock here. If the lock cannot be obtained + ** immediately, it means some other connection is truncating the + ** *-shm file. And after it has done so, it will not release its + ** lock, but only downgrade it to a shared lock. So no point in + ** blocking here. The call below to obtain the shared DMS lock may + ** use a blocking lock. */ + int iSaveTimeout = pDbFd->iBusyTimeout; + pDbFd->iBusyTimeout = 0; +#endif + rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1); +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + pDbFd->iBusyTimeout = iSaveTimeout; +#endif + /* The first connection to attach must truncate the -shm file. We + ** truncate to 3 bytes (an arbitrary small number, less than the + ** -shm header size) rather than 0 as a system debugging aid, to + ** help detect if a -shm file truncation is legitimate or is the work + ** or a rogue process. */ + if( rc==SQLITE_OK && robust_ftruncate(pShmNode->hShm, 3) ){ + rc = unixLogError(SQLITE_IOERR_SHMOPEN,"ftruncate",pShmNode->zFilename); + } + } + }else if( lock.l_type==F_WRLCK ){ + rc = SQLITE_BUSY; + } + + if( rc==SQLITE_OK ){ + assert( lock.l_type==F_UNLCK || lock.l_type==F_RDLCK ); + rc = unixShmSystemLock(pDbFd, F_RDLCK, UNIX_SHM_DMS, 1); + } + return rc; +} + +/* +** Open a shared-memory area associated with open database file pDbFd. +** This particular implementation uses mmapped files. +** +** The file used to implement shared-memory is in the same directory +** as the open database file and has the same name as the open database +** file with the "-shm" suffix added. For example, if the database file +** is "/home/user1/config.db" then the file that is created and mmapped +** for shared memory will be called "/home/user1/config.db-shm". +** +** Another approach to is to use files in /dev/shm or /dev/tmp or an +** some other tmpfs mount. But if a file in a different directory +** from the database file is used, then differing access permissions +** or a chroot() might cause two different processes on the same +** database to end up using different files for shared memory - +** meaning that their memory would not really be shared - resulting +** in database corruption. Nevertheless, this tmpfs file usage +** can be enabled at compile-time using -DSQLITE_SHM_DIRECTORY="/dev/shm" +** or the equivalent. The use of the SQLITE_SHM_DIRECTORY compile-time +** option results in an incompatible build of SQLite; builds of SQLite +** that with differing SQLITE_SHM_DIRECTORY settings attempt to use the +** same database file at the same time, database corruption will likely +** result. The SQLITE_SHM_DIRECTORY compile-time option is considered +** "unsupported" and may go away in a future SQLite release. +** +** When opening a new shared-memory file, if no other instances of that +** file are currently open, in this process or in other processes, then +** the file must be truncated to zero length or have its header cleared. +** +** If the original database file (pDbFd) is using the "unix-excl" VFS +** that means that an exclusive lock is held on the database file and +** that no other processes are able to read or write the database. In +** that case, we do not really need shared memory. No shared memory +** file is created. The shared memory will be simulated with heap memory. +*/ +static int unixOpenSharedMemory(unixFile *pDbFd){ + struct unixShm *p = 0; /* The connection to be opened */ + struct unixShmNode *pShmNode; /* The underlying mmapped file */ + int rc = SQLITE_OK; /* Result code */ + unixInodeInfo *pInode; /* The inode of fd */ + char *zShm; /* Name of the file used for SHM */ + int nShmFilename; /* Size of the SHM filename in bytes */ + + /* Allocate space for the new unixShm object. */ + p = sqlite3_malloc64( sizeof(*p) ); + if( p==0 ) return SQLITE_NOMEM_BKPT; + memset(p, 0, sizeof(*p)); + assert( pDbFd->pShm==0 ); + + /* Check to see if a unixShmNode object already exists. Reuse an existing + ** one if present. Create a new one if necessary. + */ + assert( unixFileMutexNotheld(pDbFd) ); + unixEnterMutex(); + pInode = pDbFd->pInode; + pShmNode = pInode->pShmNode; + if( pShmNode==0 ){ + struct stat sStat; /* fstat() info for database file */ +#ifndef SQLITE_SHM_DIRECTORY + const char *zBasePath = pDbFd->zPath; +#endif + + /* Call fstat() to figure out the permissions on the database file. If + ** a new *-shm file is created, an attempt will be made to create it + ** with the same permissions. + */ + if( osFstat(pDbFd->h, &sStat) ){ + rc = SQLITE_IOERR_FSTAT; + goto shm_open_err; + } + +#ifdef SQLITE_SHM_DIRECTORY + nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 31; +#else + nShmFilename = 6 + (int)strlen(zBasePath); +#endif + pShmNode = sqlite3_malloc64( sizeof(*pShmNode) + nShmFilename ); + if( pShmNode==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto shm_open_err; + } + memset(pShmNode, 0, sizeof(*pShmNode)+nShmFilename); + zShm = pShmNode->zFilename = (char*)&pShmNode[1]; +#ifdef SQLITE_SHM_DIRECTORY + sqlite3_snprintf(nShmFilename, zShm, + SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x", + (u32)sStat.st_ino, (u32)sStat.st_dev); +#else + sqlite3_snprintf(nShmFilename, zShm, "%s-shm", zBasePath); + sqlite3FileSuffix3(pDbFd->zPath, zShm); +#endif + pShmNode->hShm = -1; + pDbFd->pInode->pShmNode = pShmNode; + pShmNode->pInode = pDbFd->pInode; + if( sqlite3GlobalConfig.bCoreMutex ){ + pShmNode->pShmMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( pShmNode->pShmMutex==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto shm_open_err; + } +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + { + int ii; + for(ii=0; iiaMutex[ii] = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( pShmNode->aMutex[ii]==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto shm_open_err; + } + } + } +#endif + } + + if( pInode->bProcessLock==0 ){ + if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ + pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT|O_NOFOLLOW, + (sStat.st_mode&0777)); + } + if( pShmNode->hShm<0 ){ + pShmNode->hShm = robust_open(zShm, O_RDONLY|O_NOFOLLOW, + (sStat.st_mode&0777)); + if( pShmNode->hShm<0 ){ + rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShm); + goto shm_open_err; + } + pShmNode->isReadonly = 1; + } + + /* If this process is running as root, make sure that the SHM file + ** is owned by the same user that owns the original database. Otherwise, + ** the original owner will not be able to connect. + */ + robustFchown(pShmNode->hShm, sStat.st_uid, sStat.st_gid); + + rc = unixLockSharedMemory(pDbFd, pShmNode); + if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err; + } + } + + /* Make the new connection a child of the unixShmNode */ + p->pShmNode = pShmNode; +#ifdef SQLITE_DEBUG + p->id = pShmNode->nextShmId++; +#endif + pShmNode->nRef++; + pDbFd->pShm = p; + unixLeaveMutex(); + + /* The reference count on pShmNode has already been incremented under + ** the cover of the unixEnterMutex() mutex and the pointer from the + ** new (struct unixShm) object to the pShmNode has been set. All that is + ** left to do is to link the new object into the linked list starting + ** at pShmNode->pFirst. This must be done while holding the + ** pShmNode->pShmMutex. + */ + sqlite3_mutex_enter(pShmNode->pShmMutex); + p->pNext = pShmNode->pFirst; + pShmNode->pFirst = p; + sqlite3_mutex_leave(pShmNode->pShmMutex); + return rc; + + /* Jump here on any error */ +shm_open_err: + unixShmPurge(pDbFd); /* This call frees pShmNode if required */ + sqlite3_free(p); + unixLeaveMutex(); + return rc; +} + +/* +** This function is called to obtain a pointer to region iRegion of the +** shared-memory associated with the database file fd. Shared-memory regions +** are numbered starting from zero. Each shared-memory region is szRegion +** bytes in size. +** +** If an error occurs, an error code is returned and *pp is set to NULL. +** +** Otherwise, if the bExtend parameter is 0 and the requested shared-memory +** region has not been allocated (by any client, including one running in a +** separate process), then *pp is set to NULL and SQLITE_OK returned. If +** bExtend is non-zero and the requested shared-memory region has not yet +** been allocated, it is allocated by this function. +** +** If the shared-memory region has already been allocated or is allocated by +** this call as described above, then it is mapped into this processes +** address space (if it is not already), *pp is set to point to the mapped +** memory and SQLITE_OK returned. +*/ +static int unixShmMap( + sqlite3_file *fd, /* Handle open on database file */ + int iRegion, /* Region to retrieve */ + int szRegion, /* Size of regions */ + int bExtend, /* True to extend file if necessary */ + void volatile **pp /* OUT: Mapped memory */ +){ + unixFile *pDbFd = (unixFile*)fd; + unixShm *p; + unixShmNode *pShmNode; + int rc = SQLITE_OK; + int nShmPerMap = unixShmRegionPerMap(); + int nReqRegion; + + /* If the shared-memory file has not yet been opened, open it now. */ + if( pDbFd->pShm==0 ){ + rc = unixOpenSharedMemory(pDbFd); + if( rc!=SQLITE_OK ) return rc; + } + + p = pDbFd->pShm; + pShmNode = p->pShmNode; + sqlite3_mutex_enter(pShmNode->pShmMutex); + if( pShmNode->isUnlocked ){ + rc = unixLockSharedMemory(pDbFd, pShmNode); + if( rc!=SQLITE_OK ) goto shmpage_out; + pShmNode->isUnlocked = 0; + } + assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); + assert( pShmNode->pInode==pDbFd->pInode ); + assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 ); + assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 ); + + /* Minimum number of regions required to be mapped. */ + nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap; + + if( pShmNode->nRegionszRegion = szRegion; + + if( pShmNode->hShm>=0 ){ + /* The requested region is not mapped into this processes address space. + ** Check to see if it has been allocated (i.e. if the wal-index file is + ** large enough to contain the requested region). + */ + if( osFstat(pShmNode->hShm, &sStat) ){ + rc = SQLITE_IOERR_SHMSIZE; + goto shmpage_out; + } + + if( sStat.st_sizehShm, iPg*pgsz + pgsz-1,"",1,&x)!=1 ){ + const char *zFile = pShmNode->zFilename; + rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile); + goto shmpage_out; + } + } + } + } + } + + /* Map the requested memory region into this processes address space. */ + apNew = (char **)sqlite3_realloc64( + pShmNode->apRegion, nReqRegion*sizeof(char *) + ); + if( !apNew ){ + rc = SQLITE_IOERR_NOMEM_BKPT; + goto shmpage_out; + } + pShmNode->apRegion = apNew; + while( pShmNode->nRegionhShm>=0 ){ + pMem = osMmap(0, nMap, + pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, + MAP_SHARED, pShmNode->hShm, szRegion*(i64)pShmNode->nRegion + ); + if( pMem==MAP_FAILED ){ + rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename); + goto shmpage_out; + } + }else{ + pMem = sqlite3_malloc64(nMap); + if( pMem==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto shmpage_out; + } + memset(pMem, 0, nMap); + } + + for(i=0; iapRegion[pShmNode->nRegion+i] = &((char*)pMem)[szRegion*i]; + } + pShmNode->nRegion += nShmPerMap; + } + } + +shmpage_out: + if( pShmNode->nRegion>iRegion ){ + *pp = pShmNode->apRegion[iRegion]; + }else{ + *pp = 0; + } + if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY; + sqlite3_mutex_leave(pShmNode->pShmMutex); + return rc; +} + +/* +** Check that the pShmNode->aLock[] array comports with the locking bitmasks +** held by each client. Return true if it does, or false otherwise. This +** is to be used in an assert(). e.g. +** +** assert( assertLockingArrayOk(pShmNode) ); +*/ +#ifdef SQLITE_DEBUG +static int assertLockingArrayOk(unixShmNode *pShmNode){ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + return 1; +#else + unixShm *pX; + int aLock[SQLITE_SHM_NLOCK]; + + memset(aLock, 0, sizeof(aLock)); + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + int i; + for(i=0; iexclMask & (1<sharedMask & (1<=0 ); + aLock[i]++; + } + } + } + + assert( 0==memcmp(pShmNode->aLock, aLock, sizeof(aLock)) ); + return (memcmp(pShmNode->aLock, aLock, sizeof(aLock))==0); +#endif +} +#endif /* !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL) */ + +/* +** Change the lock state for a shared-memory segment. +** +** Note that the relationship between SHARED and EXCLUSIVE locks is a little +** different here than in posix. In xShmLock(), one can go from unlocked +** to shared and back or from unlocked to exclusive and back. But one may +** not go from shared to exclusive or from exclusive to shared. +*/ +static int unixShmLock( + sqlite3_file *fd, /* Database file holding the shared memory */ + int ofst, /* First lock to acquire or release */ + int n, /* Number of locks to acquire or release */ + int flags /* What to do with the lock */ +){ + unixFile *pDbFd = (unixFile*)fd; /* Connection holding shared memory */ + unixShm *p; /* The shared memory being locked */ + unixShmNode *pShmNode; /* The underlying file iNode */ + int rc = SQLITE_OK; /* Result code */ + u16 mask = (1<<(ofst+n)) - (1<pShm; + if( p==0 ) return SQLITE_IOERR_SHMLOCK; + pShmNode = p->pShmNode; + if( NEVER(pShmNode==0) ) return SQLITE_IOERR_SHMLOCK; + aLock = pShmNode->aLock; + + assert( pShmNode==pDbFd->pInode->pShmNode ); + assert( pShmNode->pInode==pDbFd->pInode ); + assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK ); + assert( n>=1 ); + assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED) + || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE) + || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED) + || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); + assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); + assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 ); + assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 ); + + /* Check that, if this to be a blocking lock, no locks that occur later + ** in the following list than the lock being obtained are already held: + ** + ** 1. Recovery lock (ofst==2). + ** 2. Checkpointer lock (ofst==1). + ** 3. Write lock (ofst==0). + ** 4. Read locks (ofst>=3 && ofstexclMask|p->sharedMask); + assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( + (ofst!=2 || lockMask==0) + && (ofst!=1 || lockMask==0 || lockMask==2) + && (ofst!=0 || lockMask<3) + && (ofst<3 || lockMask<(1<exclMask & mask) + ); + if( ((flags & SQLITE_SHM_UNLOCK) && ((p->exclMask|p->sharedMask) & mask)) + || (flags==(SQLITE_SHM_SHARED|SQLITE_SHM_LOCK) && 0==(p->sharedMask & mask)) + || (flags==(SQLITE_SHM_EXCLUSIVE|SQLITE_SHM_LOCK)) + ){ + + /* Take the required mutexes. In SETLK_TIMEOUT mode (blocking locks), if + ** this is an attempt on an exclusive lock use sqlite3_mutex_try(). If any + ** other thread is holding this mutex, then it is either holding or about + ** to hold a lock exclusive to the one being requested, and we may + ** therefore return SQLITE_BUSY to the caller. + ** + ** Doing this prevents some deadlock scenarios. For example, thread 1 may + ** be a checkpointer blocked waiting on the WRITER lock. And thread 2 + ** may be a normal SQL client upgrading to a write transaction. In this + ** case thread 2 does a non-blocking request for the WRITER lock. But - + ** if it were to use sqlite3_mutex_enter() then it would effectively + ** become a (doomed) blocking request, as thread 2 would block until thread + ** 1 obtained WRITER and released the mutex. Since thread 2 already holds + ** a lock on a read-locking slot at this point, this breaks the + ** anti-deadlock rules (see above). */ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + int iMutex; + for(iMutex=ofst; iMutexaMutex[iMutex]); + if( rc!=SQLITE_OK ) goto leave_shmnode_mutexes; + }else{ + sqlite3_mutex_enter(pShmNode->aMutex[iMutex]); + } + } +#else + sqlite3_mutex_enter(pShmNode->pShmMutex); +#endif + + if( ALWAYS(rc==SQLITE_OK) ){ + if( flags & SQLITE_SHM_UNLOCK ){ + /* Case (a) - unlock. */ + int bUnlock = 1; + assert( (p->exclMask & p->sharedMask)==0 ); + assert( !(flags & SQLITE_SHM_EXCLUSIVE) || (p->exclMask & mask)==mask ); + assert( !(flags & SQLITE_SHM_SHARED) || (p->sharedMask & mask)==mask ); + + /* If this is a SHARED lock being unlocked, it is possible that other + ** clients within this process are holding the same SHARED lock. In + ** this case, set bUnlock to 0 so that the posix lock is not removed + ** from the file-descriptor below. */ + if( flags & SQLITE_SHM_SHARED ){ + assert( n==1 ); + assert( aLock[ofst]>=1 ); + if( aLock[ofst]>1 ){ + bUnlock = 0; + aLock[ofst]--; + p->sharedMask &= ~mask; + } + } + + if( bUnlock ){ + rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n); + if( rc==SQLITE_OK ){ + memset(&aLock[ofst], 0, sizeof(int)*n); + p->sharedMask &= ~mask; + p->exclMask &= ~mask; + } + } + }else if( flags & SQLITE_SHM_SHARED ){ + /* Case (b) - a shared lock. */ + + if( aLock[ofst]<0 ){ + /* An exclusive lock is held by some other connection. BUSY. */ + rc = SQLITE_BUSY; + }else if( aLock[ofst]==0 ){ + rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n); + } + + /* Get the local shared locks */ + if( rc==SQLITE_OK ){ + p->sharedMask |= mask; + aLock[ofst]++; + } + }else{ + /* Case (c) - an exclusive lock. */ + int ii; + + assert( flags==(SQLITE_SHM_LOCK|SQLITE_SHM_EXCLUSIVE) ); + assert( (p->sharedMask & mask)==0 ); + assert( (p->exclMask & mask)==0 ); + + /* Make sure no sibling connections hold locks that will block this + ** lock. If any do, return SQLITE_BUSY right away. */ + for(ii=ofst; iiexclMask |= mask; + for(ii=ofst; ii=ofst; iMutex--){ + sqlite3_mutex_leave(pShmNode->aMutex[iMutex]); + } +#else + sqlite3_mutex_leave(pShmNode->pShmMutex); +#endif + } + + OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n", + p->id, osGetpid(0), p->sharedMask, p->exclMask)); + return rc; +} + +/* +** Implement a memory barrier or memory fence on shared memory. +** +** All loads and stores begun before the barrier must complete before +** any load or store begun after the barrier. +*/ +static void unixShmBarrier( + sqlite3_file *fd /* Database file holding the shared memory */ +){ + UNUSED_PARAMETER(fd); + sqlite3MemoryBarrier(); /* compiler-defined memory barrier */ + assert( fd->pMethods->xLock==nolockLock + || unixFileMutexNotheld((unixFile*)fd) + ); + unixEnterMutex(); /* Also mutex, for redundancy */ + unixLeaveMutex(); +} + +/* +** Close a connection to shared-memory. Delete the underlying +** storage if deleteFlag is true. +** +** If there is no shared memory associated with the connection then this +** routine is a harmless no-op. +*/ +static int unixShmUnmap( + sqlite3_file *fd, /* The underlying database file */ + int deleteFlag /* Delete shared-memory if true */ +){ + unixShm *p; /* The connection to be closed */ + unixShmNode *pShmNode; /* The underlying shared-memory file */ + unixShm **pp; /* For looping over sibling connections */ + unixFile *pDbFd; /* The underlying database file */ + + pDbFd = (unixFile*)fd; + p = pDbFd->pShm; + if( p==0 ) return SQLITE_OK; + pShmNode = p->pShmNode; + + assert( pShmNode==pDbFd->pInode->pShmNode ); + assert( pShmNode->pInode==pDbFd->pInode ); + + /* Remove connection p from the set of connections associated + ** with pShmNode */ + sqlite3_mutex_enter(pShmNode->pShmMutex); + for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){} + *pp = p->pNext; + + /* Free the connection p */ + sqlite3_free(p); + pDbFd->pShm = 0; + sqlite3_mutex_leave(pShmNode->pShmMutex); + + /* If pShmNode->nRef has reached 0, then close the underlying + ** shared-memory file, too */ + assert( unixFileMutexNotheld(pDbFd) ); + unixEnterMutex(); + assert( pShmNode->nRef>0 ); + pShmNode->nRef--; + if( pShmNode->nRef==0 ){ + if( deleteFlag && pShmNode->hShm>=0 ){ + osUnlink(pShmNode->zFilename); + } + unixShmPurge(pDbFd); + } + unixLeaveMutex(); + + return SQLITE_OK; +} + + +#else +# define unixShmMap 0 +# define unixShmLock 0 +# define unixShmBarrier 0 +# define unixShmUnmap 0 +#endif /* #ifndef SQLITE_OMIT_WAL */ + +#if SQLITE_MAX_MMAP_SIZE>0 +/* +** If it is currently memory mapped, unmap file pFd. +*/ +static void unixUnmapfile(unixFile *pFd){ + assert( pFd->nFetchOut==0 ); + if( pFd->pMapRegion ){ + osMunmap(pFd->pMapRegion, pFd->mmapSizeActual); + pFd->pMapRegion = 0; + pFd->mmapSize = 0; + pFd->mmapSizeActual = 0; + } +} + +/* +** Attempt to set the size of the memory mapping maintained by file +** descriptor pFd to nNew bytes. Any existing mapping is discarded. +** +** If successful, this function sets the following variables: +** +** unixFile.pMapRegion +** unixFile.mmapSize +** unixFile.mmapSizeActual +** +** If unsuccessful, an error message is logged via sqlite3_log() and +** the three variables above are zeroed. In this case SQLite should +** continue accessing the database using the xRead() and xWrite() +** methods. +*/ +static void unixRemapfile( + unixFile *pFd, /* File descriptor object */ + i64 nNew /* Required mapping size */ +){ + const char *zErr = "mmap"; + int h = pFd->h; /* File descriptor open on db file */ + u8 *pOrig = (u8 *)pFd->pMapRegion; /* Pointer to current file mapping */ + i64 nOrig = pFd->mmapSizeActual; /* Size of pOrig region in bytes */ + u8 *pNew = 0; /* Location of new mapping */ + int flags = PROT_READ; /* Flags to pass to mmap() */ + + assert( pFd->nFetchOut==0 ); + assert( nNew>pFd->mmapSize ); + assert( nNew<=pFd->mmapSizeMax ); + assert( nNew>0 ); + assert( pFd->mmapSizeActual>=pFd->mmapSize ); + assert( MAP_FAILED!=0 ); + +#ifdef SQLITE_MMAP_READWRITE + if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE; +#endif + + if( pOrig ){ +#if HAVE_MREMAP + i64 nReuse = pFd->mmapSize; +#else + const int szSyspage = osGetpagesize(); + i64 nReuse = (pFd->mmapSize & ~(szSyspage-1)); +#endif + u8 *pReq = &pOrig[nReuse]; + + /* Unmap any pages of the existing mapping that cannot be reused. */ + if( nReuse!=nOrig ){ + osMunmap(pReq, nOrig-nReuse); + } + +#if HAVE_MREMAP + pNew = osMremap(pOrig, nReuse, nNew, MREMAP_MAYMOVE); + zErr = "mremap"; +#else + pNew = osMmap(pReq, nNew-nReuse, flags, MAP_SHARED, h, nReuse); + if( pNew!=MAP_FAILED ){ + if( pNew!=pReq ){ + osMunmap(pNew, nNew - nReuse); + pNew = 0; + }else{ + pNew = pOrig; + } + } +#endif + + /* The attempt to extend the existing mapping failed. Free it. */ + if( pNew==MAP_FAILED || pNew==0 ){ + osMunmap(pOrig, nReuse); + } + } + + /* If pNew is still NULL, try to create an entirely new mapping. */ + if( pNew==0 ){ + pNew = osMmap(0, nNew, flags, MAP_SHARED, h, 0); + } + + if( pNew==MAP_FAILED ){ + pNew = 0; + nNew = 0; + unixLogError(SQLITE_OK, zErr, pFd->zPath); + + /* If the mmap() above failed, assume that all subsequent mmap() calls + ** will probably fail too. Fall back to using xRead/xWrite exclusively + ** in this case. */ + pFd->mmapSizeMax = 0; + } + pFd->pMapRegion = (void *)pNew; + pFd->mmapSize = pFd->mmapSizeActual = nNew; +} + +/* +** Memory map or remap the file opened by file-descriptor pFd (if the file +** is already mapped, the existing mapping is replaced by the new). Or, if +** there already exists a mapping for this file, and there are still +** outstanding xFetch() references to it, this function is a no-op. +** +** If parameter nByte is non-negative, then it is the requested size of +** the mapping to create. Otherwise, if nByte is less than zero, then the +** requested size is the size of the file on disk. The actual size of the +** created mapping is either the requested size or the value configured +** using SQLITE_FCNTL_MMAP_LIMIT, whichever is smaller. +** +** SQLITE_OK is returned if no error occurs (even if the mapping is not +** recreated as a result of outstanding references) or an SQLite error +** code otherwise. +*/ +static int unixMapfile(unixFile *pFd, i64 nMap){ + assert( nMap>=0 || pFd->nFetchOut==0 ); + assert( nMap>0 || (pFd->mmapSize==0 && pFd->pMapRegion==0) ); + if( pFd->nFetchOut>0 ) return SQLITE_OK; + + if( nMap<0 ){ + struct stat statbuf; /* Low-level file information */ + if( osFstat(pFd->h, &statbuf) ){ + return SQLITE_IOERR_FSTAT; + } + nMap = statbuf.st_size; + } + if( nMap>pFd->mmapSizeMax ){ + nMap = pFd->mmapSizeMax; + } + + assert( nMap>0 || (pFd->mmapSize==0 && pFd->pMapRegion==0) ); + if( nMap!=pFd->mmapSize ){ + unixRemapfile(pFd, nMap); + } + + return SQLITE_OK; +} +#endif /* SQLITE_MAX_MMAP_SIZE>0 */ + +/* +** If possible, return a pointer to a mapping of file fd starting at offset +** iOff. The mapping must be valid for at least nAmt bytes. +** +** If such a pointer can be obtained, store it in *pp and return SQLITE_OK. +** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK. +** Finally, if an error does occur, return an SQLite error code. The final +** value of *pp is undefined in this case. +** +** If this function does return a pointer, the caller must eventually +** release the reference by calling unixUnfetch(). +*/ +static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ +#if SQLITE_MAX_MMAP_SIZE>0 + unixFile *pFd = (unixFile *)fd; /* The underlying database file */ +#endif + *pp = 0; + +#if SQLITE_MAX_MMAP_SIZE>0 + if( pFd->mmapSizeMax>0 ){ + /* Ensure that there is always at least a 256 byte buffer of addressable + ** memory following the returned page. If the database is corrupt, + ** SQLite may overread the page slightly (in practice only a few bytes, + ** but 256 is safe, round, number). */ + const int nEofBuffer = 256; + if( pFd->pMapRegion==0 ){ + int rc = unixMapfile(pFd, -1); + if( rc!=SQLITE_OK ) return rc; + } + if( pFd->mmapSize >= (iOff+nAmt+nEofBuffer) ){ + *pp = &((u8 *)pFd->pMapRegion)[iOff]; + pFd->nFetchOut++; + } + } +#endif + return SQLITE_OK; +} + +/* +** If the third argument is non-NULL, then this function releases a +** reference obtained by an earlier call to unixFetch(). The second +** argument passed to this function must be the same as the corresponding +** argument that was passed to the unixFetch() invocation. +** +** Or, if the third argument is NULL, then this function is being called +** to inform the VFS layer that, according to POSIX, any existing mapping +** may now be invalid and should be unmapped. +*/ +static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){ +#if SQLITE_MAX_MMAP_SIZE>0 + unixFile *pFd = (unixFile *)fd; /* The underlying database file */ + UNUSED_PARAMETER(iOff); + + /* If p==0 (unmap the entire file) then there must be no outstanding + ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference), + ** then there must be at least one outstanding. */ + assert( (p==0)==(pFd->nFetchOut==0) ); + + /* If p!=0, it must match the iOff value. */ + assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] ); + + if( p ){ + pFd->nFetchOut--; + }else{ + unixUnmapfile(pFd); + } + + assert( pFd->nFetchOut>=0 ); +#else + UNUSED_PARAMETER(fd); + UNUSED_PARAMETER(p); + UNUSED_PARAMETER(iOff); +#endif + return SQLITE_OK; +} + +/* +** Here ends the implementation of all sqlite3_file methods. +** +********************** End sqlite3_file Methods ******************************* +******************************************************************************/ + +/* +** This division contains definitions of sqlite3_io_methods objects that +** implement various file locking strategies. It also contains definitions +** of "finder" functions. A finder-function is used to locate the appropriate +** sqlite3_io_methods object for a particular database file. The pAppData +** field of the sqlite3_vfs VFS objects are initialized to be pointers to +** the correct finder-function for that VFS. +** +** Most finder functions return a pointer to a fixed sqlite3_io_methods +** object. The only interesting finder-function is autolockIoFinder, which +** looks at the filesystem type and tries to guess the best locking +** strategy from that. +** +** For finder-function F, two objects are created: +** +** (1) The real finder-function named "FImpt()". +** +** (2) A constant pointer to this function named just "F". +** +** +** A pointer to the F pointer is used as the pAppData value for VFS +** objects. We have to do this instead of letting pAppData point +** directly at the finder-function since C90 rules prevent a void* +** from be cast into a function pointer. +** +** +** Each instance of this macro generates two objects: +** +** * A constant sqlite3_io_methods object call METHOD that has locking +** methods CLOSE, LOCK, UNLOCK, CKRESLOCK. +** +** * An I/O method finder function called FINDER that returns a pointer +** to the METHOD object in the previous bullet. +*/ +#define IOMETHODS(FINDER,METHOD,VERSION,CLOSE,LOCK,UNLOCK,CKLOCK,SHMMAP) \ +static const sqlite3_io_methods METHOD = { \ + VERSION, /* iVersion */ \ + CLOSE, /* xClose */ \ + unixRead, /* xRead */ \ + unixWrite, /* xWrite */ \ + unixTruncate, /* xTruncate */ \ + unixSync, /* xSync */ \ + unixFileSize, /* xFileSize */ \ + LOCK, /* xLock */ \ + UNLOCK, /* xUnlock */ \ + CKLOCK, /* xCheckReservedLock */ \ + unixFileControl, /* xFileControl */ \ + unixSectorSize, /* xSectorSize */ \ + unixDeviceCharacteristics, /* xDeviceCapabilities */ \ + SHMMAP, /* xShmMap */ \ + unixShmLock, /* xShmLock */ \ + unixShmBarrier, /* xShmBarrier */ \ + unixShmUnmap, /* xShmUnmap */ \ + unixFetch, /* xFetch */ \ + unixUnfetch, /* xUnfetch */ \ +}; \ +static const sqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){ \ + UNUSED_PARAMETER(z); UNUSED_PARAMETER(p); \ + return &METHOD; \ +} \ +static const sqlite3_io_methods *(*const FINDER)(const char*,unixFile *p) \ + = FINDER##Impl; + +/* +** Here are all of the sqlite3_io_methods objects for each of the +** locking strategies. Functions that return pointers to these methods +** are also created. +*/ +IOMETHODS( + posixIoFinder, /* Finder function name */ + posixIoMethods, /* sqlite3_io_methods object name */ + 3, /* shared memory and mmap are enabled */ + unixClose, /* xClose method */ + unixLock, /* xLock method */ + unixUnlock, /* xUnlock method */ + unixCheckReservedLock, /* xCheckReservedLock method */ + unixShmMap /* xShmMap method */ +) +IOMETHODS( + nolockIoFinder, /* Finder function name */ + nolockIoMethods, /* sqlite3_io_methods object name */ + 3, /* shared memory and mmap are enabled */ + nolockClose, /* xClose method */ + nolockLock, /* xLock method */ + nolockUnlock, /* xUnlock method */ + nolockCheckReservedLock, /* xCheckReservedLock method */ + 0 /* xShmMap method */ +) +IOMETHODS( + dotlockIoFinder, /* Finder function name */ + dotlockIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ + dotlockClose, /* xClose method */ + dotlockLock, /* xLock method */ + dotlockUnlock, /* xUnlock method */ + dotlockCheckReservedLock, /* xCheckReservedLock method */ + 0 /* xShmMap method */ +) + +#if SQLITE_ENABLE_LOCKING_STYLE +IOMETHODS( + flockIoFinder, /* Finder function name */ + flockIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ + flockClose, /* xClose method */ + flockLock, /* xLock method */ + flockUnlock, /* xUnlock method */ + flockCheckReservedLock, /* xCheckReservedLock method */ + 0 /* xShmMap method */ +) +#endif + +#if OS_VXWORKS +IOMETHODS( + semIoFinder, /* Finder function name */ + semIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ + semXClose, /* xClose method */ + semXLock, /* xLock method */ + semXUnlock, /* xUnlock method */ + semXCheckReservedLock, /* xCheckReservedLock method */ + 0 /* xShmMap method */ +) +#endif + +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE +IOMETHODS( + afpIoFinder, /* Finder function name */ + afpIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ + afpClose, /* xClose method */ + afpLock, /* xLock method */ + afpUnlock, /* xUnlock method */ + afpCheckReservedLock, /* xCheckReservedLock method */ + 0 /* xShmMap method */ +) +#endif + +/* +** The proxy locking method is a "super-method" in the sense that it +** opens secondary file descriptors for the conch and lock files and +** it uses proxy, dot-file, AFP, and flock() locking methods on those +** secondary files. For this reason, the division that implements +** proxy locking is located much further down in the file. But we need +** to go ahead and define the sqlite3_io_methods and finder function +** for proxy locking here. So we forward declare the I/O methods. +*/ +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE +static int proxyClose(sqlite3_file*); +static int proxyLock(sqlite3_file*, int); +static int proxyUnlock(sqlite3_file*, int); +static int proxyCheckReservedLock(sqlite3_file*, int*); +IOMETHODS( + proxyIoFinder, /* Finder function name */ + proxyIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ + proxyClose, /* xClose method */ + proxyLock, /* xLock method */ + proxyUnlock, /* xUnlock method */ + proxyCheckReservedLock, /* xCheckReservedLock method */ + 0 /* xShmMap method */ +) +#endif + +/* nfs lockd on OSX 10.3+ doesn't clear write locks when a read lock is set */ +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE +IOMETHODS( + nfsIoFinder, /* Finder function name */ + nfsIoMethods, /* sqlite3_io_methods object name */ + 1, /* shared memory is disabled */ + unixClose, /* xClose method */ + unixLock, /* xLock method */ + nfsUnlock, /* xUnlock method */ + unixCheckReservedLock, /* xCheckReservedLock method */ + 0 /* xShmMap method */ +) +#endif + +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE +/* +** This "finder" function attempts to determine the best locking strategy +** for the database file "filePath". It then returns the sqlite3_io_methods +** object that implements that strategy. +** +** This is for MacOSX only. +*/ +static const sqlite3_io_methods *autolockIoFinderImpl( + const char *filePath, /* name of the database file */ + unixFile *pNew /* open file object for the database file */ +){ + static const struct Mapping { + const char *zFilesystem; /* Filesystem type name */ + const sqlite3_io_methods *pMethods; /* Appropriate locking method */ + } aMap[] = { + { "hfs", &posixIoMethods }, + { "ufs", &posixIoMethods }, + { "afpfs", &afpIoMethods }, + { "smbfs", &afpIoMethods }, + { "webdav", &nolockIoMethods }, + { 0, 0 } + }; + int i; + struct statfs fsInfo; + struct flock lockInfo; + + if( !filePath ){ + /* If filePath==NULL that means we are dealing with a transient file + ** that does not need to be locked. */ + return &nolockIoMethods; + } + if( statfs(filePath, &fsInfo) != -1 ){ + if( fsInfo.f_flags & MNT_RDONLY ){ + return &nolockIoMethods; + } + for(i=0; aMap[i].zFilesystem; i++){ + if( strcmp(fsInfo.f_fstypename, aMap[i].zFilesystem)==0 ){ + return aMap[i].pMethods; + } + } + } + + /* Default case. Handles, amongst others, "nfs". + ** Test byte-range lock using fcntl(). If the call succeeds, + ** assume that the file-system supports POSIX style locks. + */ + lockInfo.l_len = 1; + lockInfo.l_start = 0; + lockInfo.l_whence = SEEK_SET; + lockInfo.l_type = F_RDLCK; + if( osFcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { + if( strcmp(fsInfo.f_fstypename, "nfs")==0 ){ + return &nfsIoMethods; + } else { + return &posixIoMethods; + } + }else{ + return &dotlockIoMethods; + } +} +static const sqlite3_io_methods + *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl; + +#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ + +#if OS_VXWORKS +/* +** This "finder" function for VxWorks checks to see if posix advisory +** locking works. If it does, then that is what is used. If it does not +** work, then fallback to named semaphore locking. +*/ +static const sqlite3_io_methods *vxworksIoFinderImpl( + const char *filePath, /* name of the database file */ + unixFile *pNew /* the open file object */ +){ + struct flock lockInfo; + + if( !filePath ){ + /* If filePath==NULL that means we are dealing with a transient file + ** that does not need to be locked. */ + return &nolockIoMethods; + } + + /* Test if fcntl() is supported and use POSIX style locks. + ** Otherwise fall back to the named semaphore method. + */ + lockInfo.l_len = 1; + lockInfo.l_start = 0; + lockInfo.l_whence = SEEK_SET; + lockInfo.l_type = F_RDLCK; + if( osFcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { + return &posixIoMethods; + }else{ + return &semIoMethods; + } +} +static const sqlite3_io_methods + *(*const vxworksIoFinder)(const char*,unixFile*) = vxworksIoFinderImpl; + +#endif /* OS_VXWORKS */ + +/* +** An abstract type for a pointer to an IO method finder function: +*/ +typedef const sqlite3_io_methods *(*finder_type)(const char*,unixFile*); + + +/**************************************************************************** +**************************** sqlite3_vfs methods **************************** +** +** This division contains the implementation of methods on the +** sqlite3_vfs object. +*/ + +/* +** Initialize the contents of the unixFile structure pointed to by pId. +*/ +static int fillInUnixFile( + sqlite3_vfs *pVfs, /* Pointer to vfs object */ + int h, /* Open file descriptor of file being opened */ + sqlite3_file *pId, /* Write to the unixFile structure here */ + const char *zFilename, /* Name of the file being opened */ + int ctrlFlags /* Zero or more UNIXFILE_* values */ +){ + const sqlite3_io_methods *pLockingStyle; + unixFile *pNew = (unixFile *)pId; + int rc = SQLITE_OK; + + assert( pNew->pInode==NULL ); + + /* No locking occurs in temporary files */ + assert( zFilename!=0 || (ctrlFlags & UNIXFILE_NOLOCK)!=0 ); + + OSTRACE(("OPEN %-3d %s\n", h, zFilename)); + pNew->h = h; + pNew->pVfs = pVfs; + pNew->zPath = zFilename; + pNew->ctrlFlags = (u8)ctrlFlags; +#if SQLITE_MAX_MMAP_SIZE>0 + pNew->mmapSizeMax = sqlite3GlobalConfig.szMmap; +#endif + if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0), + "psow", SQLITE_POWERSAFE_OVERWRITE) ){ + pNew->ctrlFlags |= UNIXFILE_PSOW; + } + if( strcmp(pVfs->zName,"unix-excl")==0 ){ + pNew->ctrlFlags |= UNIXFILE_EXCL; + } + +#if OS_VXWORKS + pNew->pId = vxworksFindFileId(zFilename); + if( pNew->pId==0 ){ + ctrlFlags |= UNIXFILE_NOLOCK; + rc = SQLITE_NOMEM_BKPT; + } +#endif + + if( ctrlFlags & UNIXFILE_NOLOCK ){ + pLockingStyle = &nolockIoMethods; + }else{ + pLockingStyle = (**(finder_type*)pVfs->pAppData)(zFilename, pNew); +#if SQLITE_ENABLE_LOCKING_STYLE + /* Cache zFilename in the locking context (AFP and dotlock override) for + ** proxyLock activation is possible (remote proxy is based on db name) + ** zFilename remains valid until file is closed, to support */ + pNew->lockingContext = (void*)zFilename; +#endif + } + + if( pLockingStyle == &posixIoMethods +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE + || pLockingStyle == &nfsIoMethods +#endif + ){ + unixEnterMutex(); + rc = findInodeInfo(pNew, &pNew->pInode); + if( rc!=SQLITE_OK ){ + /* If an error occurred in findInodeInfo(), close the file descriptor + ** immediately, before releasing the mutex. findInodeInfo() may fail + ** in two scenarios: + ** + ** (a) A call to fstat() failed. + ** (b) A malloc failed. + ** + ** Scenario (b) may only occur if the process is holding no other + ** file descriptors open on the same file. If there were other file + ** descriptors on this file, then no malloc would be required by + ** findInodeInfo(). If this is the case, it is quite safe to close + ** handle h - as it is guaranteed that no posix locks will be released + ** by doing so. + ** + ** If scenario (a) caused the error then things are not so safe. The + ** implicit assumption here is that if fstat() fails, things are in + ** such bad shape that dropping a lock or two doesn't matter much. + */ + robust_close(pNew, h, __LINE__); + h = -1; + } + unixLeaveMutex(); + } + +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) + else if( pLockingStyle == &afpIoMethods ){ + /* AFP locking uses the file path so it needs to be included in + ** the afpLockingContext. + */ + afpLockingContext *pCtx; + pNew->lockingContext = pCtx = sqlite3_malloc64( sizeof(*pCtx) ); + if( pCtx==0 ){ + rc = SQLITE_NOMEM_BKPT; + }else{ + /* NB: zFilename exists and remains valid until the file is closed + ** according to requirement F11141. So we do not need to make a + ** copy of the filename. */ + pCtx->dbPath = zFilename; + pCtx->reserved = 0; + srandomdev(); + unixEnterMutex(); + rc = findInodeInfo(pNew, &pNew->pInode); + if( rc!=SQLITE_OK ){ + sqlite3_free(pNew->lockingContext); + robust_close(pNew, h, __LINE__); + h = -1; + } + unixLeaveMutex(); + } + } +#endif + + else if( pLockingStyle == &dotlockIoMethods ){ + /* Dotfile locking uses the file path so it needs to be included in + ** the dotlockLockingContext + */ + char *zLockFile; + int nFilename; + assert( zFilename!=0 ); + nFilename = (int)strlen(zFilename) + 6; + zLockFile = (char *)sqlite3_malloc64(nFilename); + if( zLockFile==0 ){ + rc = SQLITE_NOMEM_BKPT; + }else{ + sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename); + } + pNew->lockingContext = zLockFile; + } + +#if OS_VXWORKS + else if( pLockingStyle == &semIoMethods ){ + /* Named semaphore locking uses the file path so it needs to be + ** included in the semLockingContext + */ + unixEnterMutex(); + rc = findInodeInfo(pNew, &pNew->pInode); + if( (rc==SQLITE_OK) && (pNew->pInode->pSem==NULL) ){ + char *zSemName = pNew->pInode->aSemName; + int n; + sqlite3_snprintf(MAX_PATHNAME, zSemName, "/%s.sem", + pNew->pId->zCanonicalName); + for( n=1; zSemName[n]; n++ ) + if( zSemName[n]=='/' ) zSemName[n] = '_'; + pNew->pInode->pSem = sem_open(zSemName, O_CREAT, 0666, 1); + if( pNew->pInode->pSem == SEM_FAILED ){ + rc = SQLITE_NOMEM_BKPT; + pNew->pInode->aSemName[0] = '\0'; + } + } + unixLeaveMutex(); + } +#endif + + storeLastErrno(pNew, 0); +#if OS_VXWORKS + if( rc!=SQLITE_OK ){ + if( h>=0 ){ + robust_close(pNew, h, __LINE__); + h = -1; + } + if( pNew->ctrlFlags & UNIXFILE_DELETE ){ + osUnlink(zFilename); + } + if( pNew->pId ){ + vxworksReleaseFileId(pNew->pId); + pNew->pId = 0; + } + } +#endif + if( rc!=SQLITE_OK ){ + if( h>=0 ) robust_close(pNew, h, __LINE__); + }else{ + pId->pMethods = pLockingStyle; + OpenCounter(+1); + verifyDbFile(pNew); + } + return rc; +} + +/* +** Directories to consider for temp files. +*/ +static const char *azTempDirs[] = { + 0, + 0, + "/var/tmp", + "/usr/tmp", + "/tmp", + "." +}; + +/* +** Initialize first two members of azTempDirs[] array. +*/ +static void unixTempFileInit(void){ + azTempDirs[0] = getenv("SQLITE_TMPDIR"); + azTempDirs[1] = getenv("TMPDIR"); +} + +/* +** Return the name of a directory in which to put temporary files. +** If no suitable temporary file directory can be found, return NULL. +*/ +static const char *unixTempFileDir(void){ + unsigned int i = 0; + struct stat buf; + const char *zDir = sqlite3_temp_directory; + + while(1){ + if( zDir!=0 +#if OS_VXWORKS + && zDir[0]=='/' +#endif + && osStat(zDir, &buf)==0 + && S_ISDIR(buf.st_mode) + && osAccess(zDir, 03)==0 + ){ + return zDir; + } + if( i>=sizeof(azTempDirs)/sizeof(azTempDirs[0]) ) break; + zDir = azTempDirs[i++]; + } + return 0; +} + +/* +** Create a temporary file name in zBuf. zBuf must be allocated +** by the calling process and must be big enough to hold at least +** pVfs->mxPathname bytes. +*/ +static int unixGetTempname(int nBuf, char *zBuf){ + const char *zDir; + int iLimit = 0; + int rc = SQLITE_OK; + + /* It's odd to simulate an io-error here, but really this is just + ** using the io-error infrastructure to test that SQLite handles this + ** function failing. + */ + zBuf[0] = 0; + SimulateIOError( return SQLITE_IOERR ); + + sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); + zDir = unixTempFileDir(); + if( zDir==0 ){ + rc = SQLITE_IOERR_GETTEMPPATH; + }else{ + do{ + u64 r; + sqlite3_randomness(sizeof(r), &r); + assert( nBuf>2 ); + zBuf[nBuf-2] = 0; + sqlite3_snprintf(nBuf, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX"%llx%c", + zDir, r, 0); + if( zBuf[nBuf-2]!=0 || (iLimit++)>10 ){ + rc = SQLITE_ERROR; + break; + } + }while( osAccess(zBuf,0)==0 ); + } + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); + return rc; +} + +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) +/* +** Routine to transform a unixFile into a proxy-locking unixFile. +** Implementation in the proxy-lock division, but used by unixOpen() +** if SQLITE_PREFER_PROXY_LOCKING is defined. +*/ +static int proxyTransformUnixFile(unixFile*, const char*); +#endif + +/* +** Search for an unused file descriptor that was opened on the database +** file (not a journal or super-journal file) identified by pathname +** zPath with SQLITE_OPEN_XXX flags matching those passed as the second +** argument to this function. +** +** Such a file descriptor may exist if a database connection was closed +** but the associated file descriptor could not be closed because some +** other file descriptor open on the same file is holding a file-lock. +** Refer to comments in the unixClose() function and the lengthy comment +** describing "Posix Advisory Locking" at the start of this file for +** further details. Also, ticket #4018. +** +** If a suitable file descriptor is found, then it is returned. If no +** such file descriptor is located, -1 is returned. +*/ +static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ + UnixUnusedFd *pUnused = 0; + + /* Do not search for an unused file descriptor on vxworks. Not because + ** vxworks would not benefit from the change (it might, we're not sure), + ** but because no way to test it is currently available. It is better + ** not to risk breaking vxworks support for the sake of such an obscure + ** feature. */ +#if !OS_VXWORKS + struct stat sStat; /* Results of stat() call */ + + unixEnterMutex(); + + /* A stat() call may fail for various reasons. If this happens, it is + ** almost certain that an open() call on the same path will also fail. + ** For this reason, if an error occurs in the stat() call here, it is + ** ignored and -1 is returned. The caller will try to open a new file + ** descriptor on the same path, fail, and return an error to SQLite. + ** + ** Even if a subsequent open() call does succeed, the consequences of + ** not searching for a reusable file descriptor are not dire. */ + if( inodeList!=0 && 0==osStat(zPath, &sStat) ){ + unixInodeInfo *pInode; + + pInode = inodeList; + while( pInode && (pInode->fileId.dev!=sStat.st_dev + || pInode->fileId.ino!=(u64)sStat.st_ino) ){ + pInode = pInode->pNext; + } + if( pInode ){ + UnixUnusedFd **pp; + assert( sqlite3_mutex_notheld(pInode->pLockMutex) ); + sqlite3_mutex_enter(pInode->pLockMutex); + flags &= (SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE); + for(pp=&pInode->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext)); + pUnused = *pp; + if( pUnused ){ + *pp = pUnused->pNext; + } + sqlite3_mutex_leave(pInode->pLockMutex); + } + } + unixLeaveMutex(); +#endif /* if !OS_VXWORKS */ + return pUnused; +} + +/* +** Find the mode, uid and gid of file zFile. +*/ +static int getFileMode( + const char *zFile, /* File name */ + mode_t *pMode, /* OUT: Permissions of zFile */ + uid_t *pUid, /* OUT: uid of zFile. */ + gid_t *pGid /* OUT: gid of zFile. */ +){ + struct stat sStat; /* Output of stat() on database file */ + int rc = SQLITE_OK; + if( 0==osStat(zFile, &sStat) ){ + *pMode = sStat.st_mode & 0777; + *pUid = sStat.st_uid; + *pGid = sStat.st_gid; + }else{ + rc = SQLITE_IOERR_FSTAT; + } + return rc; +} + +/* +** This function is called by unixOpen() to determine the unix permissions +** to create new files with. If no error occurs, then SQLITE_OK is returned +** and a value suitable for passing as the third argument to open(2) is +** written to *pMode. If an IO error occurs, an SQLite error code is +** returned and the value of *pMode is not modified. +** +** In most cases, this routine sets *pMode to 0, which will become +** an indication to robust_open() to create the file using +** SQLITE_DEFAULT_FILE_PERMISSIONS adjusted by the umask. +** But if the file being opened is a WAL or regular journal file, then +** this function queries the file-system for the permissions on the +** corresponding database file and sets *pMode to this value. Whenever +** possible, WAL and journal files are created using the same permissions +** as the associated database file. +** +** If the SQLITE_ENABLE_8_3_NAMES option is enabled, then the +** original filename is unavailable. But 8_3_NAMES is only used for +** FAT filesystems and permissions do not matter there, so just use +** the default permissions. In 8_3_NAMES mode, leave *pMode set to zero. +*/ +static int findCreateFileMode( + const char *zPath, /* Path of file (possibly) being created */ + int flags, /* Flags passed as 4th argument to xOpen() */ + mode_t *pMode, /* OUT: Permissions to open file with */ + uid_t *pUid, /* OUT: uid to set on the file */ + gid_t *pGid /* OUT: gid to set on the file */ +){ + int rc = SQLITE_OK; /* Return Code */ + *pMode = 0; + *pUid = 0; + *pGid = 0; + if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){ + char zDb[MAX_PATHNAME+1]; /* Database file path */ + int nDb; /* Number of valid bytes in zDb */ + + /* zPath is a path to a WAL or journal file. The following block derives + ** the path to the associated database file from zPath. This block handles + ** the following naming conventions: + ** + ** "-journal" + ** "-wal" + ** "-journalNN" + ** "-walNN" + ** + ** where NN is a decimal number. The NN naming schemes are + ** used by the test_multiplex.c module. + ** + ** In normal operation, the journal file name will always contain + ** a '-' character. However in 8+3 filename mode, or if a corrupt + ** rollback journal specifies a super-journal with a goofy name, then + ** the '-' might be missing or the '-' might be the first character in + ** the filename. In that case, just return SQLITE_OK with *pMode==0. + */ + nDb = sqlite3Strlen30(zPath) - 1; + while( nDb>0 && zPath[nDb]!='.' ){ + if( zPath[nDb]=='-' ){ + memcpy(zDb, zPath, nDb); + zDb[nDb] = '\0'; + rc = getFileMode(zDb, pMode, pUid, pGid); + break; + } + nDb--; + } + }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){ + *pMode = 0600; + }else if( flags & SQLITE_OPEN_URI ){ + /* If this is a main database file and the file was opened using a URI + ** filename, check for the "modeof" parameter. If present, interpret + ** its value as a filename and try to copy the mode, uid and gid from + ** that file. */ + const char *z = sqlite3_uri_parameter(zPath, "modeof"); + if( z ){ + rc = getFileMode(z, pMode, pUid, pGid); + } + } + return rc; +} + +/* +** Open the file zPath. +** +** Previously, the SQLite OS layer used three functions in place of this +** one: +** +** sqlite3OsOpenReadWrite(); +** sqlite3OsOpenReadOnly(); +** sqlite3OsOpenExclusive(); +** +** These calls correspond to the following combinations of flags: +** +** ReadWrite() -> (READWRITE | CREATE) +** ReadOnly() -> (READONLY) +** OpenExclusive() -> (READWRITE | CREATE | EXCLUSIVE) +** +** The old OpenExclusive() accepted a boolean argument - "delFlag". If +** true, the file was configured to be automatically deleted when the +** file handle closed. To achieve the same effect using this new +** interface, add the DELETEONCLOSE flag to those specified above for +** OpenExclusive(). +*/ +static int unixOpen( + sqlite3_vfs *pVfs, /* The VFS for which this is the xOpen method */ + const char *zPath, /* Pathname of file to be opened */ + sqlite3_file *pFile, /* The file descriptor to be filled in */ + int flags, /* Input flags to control the opening */ + int *pOutFlags /* Output flags returned to SQLite core */ +){ + unixFile *p = (unixFile *)pFile; + int fd = -1; /* File descriptor returned by open() */ + int openFlags = 0; /* Flags to pass to open() */ + int eType = flags&0x0FFF00; /* Type of file to open */ + int noLock; /* True to omit locking primitives */ + int rc = SQLITE_OK; /* Function Return Code */ + int ctrlFlags = 0; /* UNIXFILE_* flags */ + + int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); + int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); + int isCreate = (flags & SQLITE_OPEN_CREATE); + int isReadonly = (flags & SQLITE_OPEN_READONLY); + int isReadWrite = (flags & SQLITE_OPEN_READWRITE); +#if SQLITE_ENABLE_LOCKING_STYLE + int isAutoProxy = (flags & SQLITE_OPEN_AUTOPROXY); +#endif +#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE + struct statfs fsInfo; +#endif + + /* If creating a super- or main-file journal, this function will open + ** a file-descriptor on the directory too. The first time unixSync() + ** is called the directory file descriptor will be fsync()ed and close()d. + */ + int isNewJrnl = (isCreate && ( + eType==SQLITE_OPEN_SUPER_JOURNAL + || eType==SQLITE_OPEN_MAIN_JOURNAL + || eType==SQLITE_OPEN_WAL + )); + + /* If argument zPath is a NULL pointer, this function is required to open + ** a temporary file. Use this buffer to store the file name in. + */ + char zTmpname[MAX_PATHNAME+2]; + const char *zName = zPath; + + /* Check the following statements are true: + ** + ** (a) Exactly one of the READWRITE and READONLY flags must be set, and + ** (b) if CREATE is set, then READWRITE must also be set, and + ** (c) if EXCLUSIVE is set, then CREATE must also be set. + ** (d) if DELETEONCLOSE is set, then CREATE must also be set. + */ + assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly)); + assert(isCreate==0 || isReadWrite); + assert(isExclusive==0 || isCreate); + assert(isDelete==0 || isCreate); + + /* The main DB, main journal, WAL file and super-journal are never + ** automatically deleted. Nor are they ever temporary files. */ + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_SUPER_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL ); + + /* Assert that the upper layer has set one of the "file-type" flags. */ + assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB + || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL + || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_SUPER_JOURNAL + || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL + ); + +#if OS_VXWORKS + /* The file-ID mechanism used in Vxworks requires that all pathnames + ** provided to unixOpen must be absolute pathnames. */ + if( zPath!=0 && zPath[0]!='/' ){ return SQLITE_CANTOPEN; } +#endif + + /* Detect a pid change and reset the PRNG. There is a race condition + ** here such that two or more threads all trying to open databases at + ** the same instant might all reset the PRNG. But multiple resets + ** are harmless. + */ + if( randomnessPid!=osGetpid(0) ){ + randomnessPid = osGetpid(0); + sqlite3_randomness(0,0); + } + memset(p, 0, sizeof(unixFile)); + +#ifdef SQLITE_ASSERT_NO_FILES + /* Applications that never read or write a persistent disk files */ + assert( zName==0 ); +#endif + + if( eType==SQLITE_OPEN_MAIN_DB ){ + UnixUnusedFd *pUnused; + pUnused = findReusableFd(zName, flags); + if( pUnused ){ + fd = pUnused->fd; + }else{ + pUnused = sqlite3_malloc64(sizeof(*pUnused)); + if( !pUnused ){ + return SQLITE_NOMEM_BKPT; + } + } + p->pPreallocatedUnused = pUnused; + + /* Database filenames are double-zero terminated if they are not + ** URIs with parameters. Hence, they can always be passed into + ** sqlite3_uri_parameter(). */ + assert( (flags & SQLITE_OPEN_URI) || zName[strlen(zName)+1]==0 ); + + }else if( !zName ){ + /* If zName is NULL, the upper layer is requesting a temp file. */ + assert(isDelete && !isNewJrnl); + rc = unixGetTempname(pVfs->mxPathname, zTmpname); + if( rc!=SQLITE_OK ){ + return rc; + } + zName = zTmpname; + + /* Generated temporary filenames are always double-zero terminated + ** for use by sqlite3_uri_parameter(). */ + assert( zName[strlen(zName)+1]==0 ); + } + + /* Determine the value of the flags parameter passed to POSIX function + ** open(). These must be calculated even if open() is not called, as + ** they may be stored as part of the file handle and used by the + ** 'conch file' locking functions later on. */ + if( isReadonly ) openFlags |= O_RDONLY; + if( isReadWrite ) openFlags |= O_RDWR; + if( isCreate ) openFlags |= O_CREAT; + if( isExclusive ) openFlags |= (O_EXCL|O_NOFOLLOW); + openFlags |= (O_LARGEFILE|O_BINARY|O_NOFOLLOW); + + if( fd<0 ){ + mode_t openMode; /* Permissions to create file with */ + uid_t uid; /* Userid for the file */ + gid_t gid; /* Groupid for the file */ + rc = findCreateFileMode(zName, flags, &openMode, &uid, &gid); + if( rc!=SQLITE_OK ){ + assert( !p->pPreallocatedUnused ); + assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL ); + return rc; + } + fd = robust_open(zName, openFlags, openMode); + OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags)); + assert( !isExclusive || (openFlags & O_CREAT)!=0 ); + if( fd<0 ){ + if( isNewJrnl && errno==EACCES && osAccess(zName, F_OK) ){ + /* If unable to create a journal because the directory is not + ** writable, change the error code to indicate that. */ + rc = SQLITE_READONLY_DIRECTORY; + }else if( errno!=EISDIR && isReadWrite ){ + /* Failed to open the file for read/write access. Try read-only. */ + UnixUnusedFd *pReadonly = 0; + flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); + openFlags &= ~(O_RDWR|O_CREAT); + flags |= SQLITE_OPEN_READONLY; + openFlags |= O_RDONLY; + isReadonly = 1; + pReadonly = findReusableFd(zName, flags); + if( pReadonly ){ + fd = pReadonly->fd; + sqlite3_free(pReadonly); + }else{ + fd = robust_open(zName, openFlags, openMode); + } + } + } + if( fd<0 ){ + int rc2 = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName); + if( rc==SQLITE_OK ) rc = rc2; + goto open_finished; + } + + /* The owner of the rollback journal or WAL file should always be the + ** same as the owner of the database file. Try to ensure that this is + ** the case. The chown() system call will be a no-op if the current + ** process lacks root privileges, be we should at least try. Without + ** this step, if a root process opens a database file, it can leave + ** behinds a journal/WAL that is owned by root and hence make the + ** database inaccessible to unprivileged processes. + ** + ** If openMode==0, then that means uid and gid are not set correctly + ** (probably because SQLite is configured to use 8+3 filename mode) and + ** in that case we do not want to attempt the chown(). + */ + if( openMode && (flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL))!=0 ){ + robustFchown(fd, uid, gid); + } + } + assert( fd>=0 ); + if( pOutFlags ){ + *pOutFlags = flags; + } + + if( p->pPreallocatedUnused ){ + p->pPreallocatedUnused->fd = fd; + p->pPreallocatedUnused->flags = + flags & (SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE); + } + + if( isDelete ){ +#if OS_VXWORKS + zPath = zName; +#elif defined(SQLITE_UNLINK_AFTER_CLOSE) + zPath = sqlite3_mprintf("%s", zName); + if( zPath==0 ){ + robust_close(p, fd, __LINE__); + return SQLITE_NOMEM_BKPT; + } +#else + osUnlink(zName); +#endif + } +#if SQLITE_ENABLE_LOCKING_STYLE + else{ + p->openFlags = openFlags; + } +#endif + +#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE + if( fstatfs(fd, &fsInfo) == -1 ){ + storeLastErrno(p, errno); + robust_close(p, fd, __LINE__); + return SQLITE_IOERR_ACCESS; + } + if (0 == strncmp("msdos", fsInfo.f_fstypename, 5)) { + ((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS; + } + if (0 == strncmp("exfat", fsInfo.f_fstypename, 5)) { + ((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS; + } +#endif + + /* Set up appropriate ctrlFlags */ + if( isDelete ) ctrlFlags |= UNIXFILE_DELETE; + if( isReadonly ) ctrlFlags |= UNIXFILE_RDONLY; + noLock = eType!=SQLITE_OPEN_MAIN_DB; + if( noLock ) ctrlFlags |= UNIXFILE_NOLOCK; + if( isNewJrnl ) ctrlFlags |= UNIXFILE_DIRSYNC; + if( flags & SQLITE_OPEN_URI ) ctrlFlags |= UNIXFILE_URI; + +#if SQLITE_ENABLE_LOCKING_STYLE +#if SQLITE_PREFER_PROXY_LOCKING + isAutoProxy = 1; +#endif + if( isAutoProxy && (zPath!=NULL) && (!noLock) && pVfs->xOpen ){ + char *envforce = getenv("SQLITE_FORCE_PROXY_LOCKING"); + int useProxy = 0; + + /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, 0 means + ** never use proxy, NULL means use proxy for non-local files only. */ + if( envforce!=NULL ){ + useProxy = atoi(envforce)>0; + }else{ + useProxy = !(fsInfo.f_flags&MNT_LOCAL); + } + if( useProxy ){ + rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags); + if( rc==SQLITE_OK ){ + rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:"); + if( rc!=SQLITE_OK ){ + /* Use unixClose to clean up the resources added in fillInUnixFile + ** and clear all the structure's references. Specifically, + ** pFile->pMethods will be NULL so sqlite3OsClose will be a no-op + */ + unixClose(pFile); + return rc; + } + } + goto open_finished; + } + } +#endif + + assert( zPath==0 + || zPath[0]=='/' + || eType==SQLITE_OPEN_SUPER_JOURNAL + || eType==SQLITE_OPEN_MAIN_JOURNAL + || eType==SQLITE_OPEN_TEMP_JOURNAL + ); + rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags); + +open_finished: + if( rc!=SQLITE_OK ){ + sqlite3_free(p->pPreallocatedUnused); + } + return rc; +} + + +/* +** Delete the file at zPath. If the dirSync argument is true, fsync() +** the directory after deleting the file. +*/ +static int unixDelete( + sqlite3_vfs *NotUsed, /* VFS containing this as the xDelete method */ + const char *zPath, /* Name of file to be deleted */ + int dirSync /* If true, fsync() directory after deleting file */ +){ + int rc = SQLITE_OK; + UNUSED_PARAMETER(NotUsed); + SimulateIOError(return SQLITE_IOERR_DELETE); + if( osUnlink(zPath)==(-1) ){ + if( errno==ENOENT +#if OS_VXWORKS + || osAccess(zPath,0)!=0 +#endif + ){ + rc = SQLITE_IOERR_DELETE_NOENT; + }else{ + rc = unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath); + } + return rc; + } +#ifndef SQLITE_DISABLE_DIRSYNC + if( (dirSync & 1)!=0 ){ + int fd; + rc = osOpenDirectory(zPath, &fd); + if( rc==SQLITE_OK ){ + if( full_fsync(fd,0,0) ){ + rc = unixLogError(SQLITE_IOERR_DIR_FSYNC, "fsync", zPath); + } + robust_close(0, fd, __LINE__); + }else{ + assert( rc==SQLITE_CANTOPEN ); + rc = SQLITE_OK; + } + } +#endif + return rc; +} + +/* +** Test the existence of or access permissions of file zPath. The +** test performed depends on the value of flags: +** +** SQLITE_ACCESS_EXISTS: Return 1 if the file exists +** SQLITE_ACCESS_READWRITE: Return 1 if the file is read and writable. +** SQLITE_ACCESS_READONLY: Return 1 if the file is readable. +** +** Otherwise return 0. +*/ +static int unixAccess( + sqlite3_vfs *NotUsed, /* The VFS containing this xAccess method */ + const char *zPath, /* Path of the file to examine */ + int flags, /* What do we want to learn about the zPath file? */ + int *pResOut /* Write result boolean here */ +){ + UNUSED_PARAMETER(NotUsed); + SimulateIOError( return SQLITE_IOERR_ACCESS; ); + assert( pResOut!=0 ); + + /* The spec says there are three possible values for flags. But only + ** two of them are actually used */ + assert( flags==SQLITE_ACCESS_EXISTS || flags==SQLITE_ACCESS_READWRITE ); + + if( flags==SQLITE_ACCESS_EXISTS ){ + struct stat buf; + *pResOut = 0==osStat(zPath, &buf) && + (!S_ISREG(buf.st_mode) || buf.st_size>0); + }else{ + *pResOut = osAccess(zPath, W_OK|R_OK)==0; + } + return SQLITE_OK; +} + +/* +** A pathname under construction +*/ +typedef struct DbPath DbPath; +struct DbPath { + int rc; /* Non-zero following any error */ + int nSymlink; /* Number of symlinks resolved */ + char *zOut; /* Write the pathname here */ + int nOut; /* Bytes of space available to zOut[] */ + int nUsed; /* Bytes of zOut[] currently being used */ +}; + +/* Forward reference */ +static void appendAllPathElements(DbPath*,const char*); + +/* +** Append a single path element to the DbPath under construction +*/ +static void appendOnePathElement( + DbPath *pPath, /* Path under construction, to which to append zName */ + const char *zName, /* Name to append to pPath. Not zero-terminated */ + int nName /* Number of significant bytes in zName */ +){ + assert( nName>0 ); + assert( zName!=0 ); + if( zName[0]=='.' ){ + if( nName==1 ) return; + if( zName[1]=='.' && nName==2 ){ + if( pPath->nUsed>1 ){ + assert( pPath->zOut[0]=='/' ); + while( pPath->zOut[--pPath->nUsed]!='/' ){} + } + return; + } + } + if( pPath->nUsed + nName + 2 >= pPath->nOut ){ + pPath->rc = SQLITE_ERROR; + return; + } + pPath->zOut[pPath->nUsed++] = '/'; + memcpy(&pPath->zOut[pPath->nUsed], zName, nName); + pPath->nUsed += nName; +#if defined(HAVE_READLINK) && defined(HAVE_LSTAT) + if( pPath->rc==SQLITE_OK ){ + const char *zIn; + struct stat buf; + pPath->zOut[pPath->nUsed] = 0; + zIn = pPath->zOut; + if( osLstat(zIn, &buf)!=0 ){ + if( errno!=ENOENT ){ + pPath->rc = unixLogError(SQLITE_CANTOPEN_BKPT, "lstat", zIn); + } + }else if( S_ISLNK(buf.st_mode) ){ + ssize_t got; + char zLnk[SQLITE_MAX_PATHLEN+2]; + if( pPath->nSymlink++ > SQLITE_MAX_SYMLINK ){ + pPath->rc = SQLITE_CANTOPEN_BKPT; + return; + } + got = osReadlink(zIn, zLnk, sizeof(zLnk)-2); + if( got<=0 || got>=(ssize_t)sizeof(zLnk)-2 ){ + pPath->rc = unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zIn); + return; + } + zLnk[got] = 0; + if( zLnk[0]=='/' ){ + pPath->nUsed = 0; + }else{ + pPath->nUsed -= nName + 1; + } + appendAllPathElements(pPath, zLnk); + } + } +#endif +} + +/* +** Append all path elements in zPath to the DbPath under construction. +*/ +static void appendAllPathElements( + DbPath *pPath, /* Path under construction, to which to append zName */ + const char *zPath /* Path to append to pPath. Is zero-terminated */ +){ + int i = 0; + int j = 0; + do{ + while( zPath[i] && zPath[i]!='/' ){ i++; } + if( i>j ){ + appendOnePathElement(pPath, &zPath[j], i-j); + } + j = i+1; + }while( zPath[i++] ); +} + +/* +** Turn a relative pathname into a full pathname. The relative path +** is stored as a nul-terminated string in the buffer pointed to by +** zPath. +** +** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes +** (in this case, MAX_PATHNAME bytes). The full-path is written to +** this buffer before returning. +*/ +static int unixFullPathname( + sqlite3_vfs *pVfs, /* Pointer to vfs object */ + const char *zPath, /* Possibly relative input path */ + int nOut, /* Size of output buffer in bytes */ + char *zOut /* Output buffer */ +){ + DbPath path; + UNUSED_PARAMETER(pVfs); + path.rc = 0; + path.nUsed = 0; + path.nSymlink = 0; + path.nOut = nOut; + path.zOut = zOut; + if( zPath[0]!='/' ){ + char zPwd[SQLITE_MAX_PATHLEN+2]; + if( osGetcwd(zPwd, sizeof(zPwd)-2)==0 ){ + return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath); + } + appendAllPathElements(&path, zPwd); + } + appendAllPathElements(&path, zPath); + zOut[path.nUsed] = 0; + if( path.rc || path.nUsed<2 ) return SQLITE_CANTOPEN_BKPT; + if( path.nSymlink ) return SQLITE_OK_SYMLINK; + return SQLITE_OK; +} + +#ifndef SQLITE_OMIT_LOAD_EXTENSION +/* +** Interfaces for opening a shared library, finding entry points +** within the shared library, and closing the shared library. +*/ +#include +static void *unixDlOpen(sqlite3_vfs *NotUsed, const char *zFilename){ + UNUSED_PARAMETER(NotUsed); + return dlopen(zFilename, RTLD_NOW | RTLD_GLOBAL); +} + +/* +** SQLite calls this function immediately after a call to unixDlSym() or +** unixDlOpen() fails (returns a null pointer). If a more detailed error +** message is available, it is written to zBufOut. If no error message +** is available, zBufOut is left unmodified and SQLite uses a default +** error message. +*/ +static void unixDlError(sqlite3_vfs *NotUsed, int nBuf, char *zBufOut){ + const char *zErr; + UNUSED_PARAMETER(NotUsed); + unixEnterMutex(); + zErr = dlerror(); + if( zErr ){ + sqlite3_snprintf(nBuf, zBufOut, "%s", zErr); + } + unixLeaveMutex(); +} +static void (*unixDlSym(sqlite3_vfs *NotUsed, void *p, const char*zSym))(void){ + /* + ** GCC with -pedantic-errors says that C90 does not allow a void* to be + ** cast into a pointer to a function. And yet the library dlsym() routine + ** returns a void* which is really a pointer to a function. So how do we + ** use dlsym() with -pedantic-errors? + ** + ** Variable x below is defined to be a pointer to a function taking + ** parameters void* and const char* and returning a pointer to a function. + ** We initialize x by assigning it a pointer to the dlsym() function. + ** (That assignment requires a cast.) Then we call the function that + ** x points to. + ** + ** This work-around is unlikely to work correctly on any system where + ** you really cannot cast a function pointer into void*. But then, on the + ** other hand, dlsym() will not work on such a system either, so we have + ** not really lost anything. + */ + void (*(*x)(void*,const char*))(void); + UNUSED_PARAMETER(NotUsed); + x = (void(*(*)(void*,const char*))(void))dlsym; + return (*x)(p, zSym); +} +static void unixDlClose(sqlite3_vfs *NotUsed, void *pHandle){ + UNUSED_PARAMETER(NotUsed); + dlclose(pHandle); +} +#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ + #define unixDlOpen 0 + #define unixDlError 0 + #define unixDlSym 0 + #define unixDlClose 0 +#endif + +/* +** Write nBuf bytes of random data to the supplied buffer zBuf. +*/ +static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){ + UNUSED_PARAMETER(NotUsed); + assert((size_t)nBuf>=(sizeof(time_t)+sizeof(int))); + + /* We have to initialize zBuf to prevent valgrind from reporting + ** errors. The reports issued by valgrind are incorrect - we would + ** prefer that the randomness be increased by making use of the + ** uninitialized space in zBuf - but valgrind errors tend to worry + ** some users. Rather than argue, it seems easier just to initialize + ** the whole array and silence valgrind, even if that means less randomness + ** in the random seed. + ** + ** When testing, initializing zBuf[] to zero is all we do. That means + ** that we always use the same random number sequence. This makes the + ** tests repeatable. + */ + memset(zBuf, 0, nBuf); + randomnessPid = osGetpid(0); +#if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) + { + int fd, got; + fd = robust_open("/dev/urandom", O_RDONLY, 0); + if( fd<0 ){ + time_t t; + time(&t); + memcpy(zBuf, &t, sizeof(t)); + memcpy(&zBuf[sizeof(t)], &randomnessPid, sizeof(randomnessPid)); + assert( sizeof(t)+sizeof(randomnessPid)<=(size_t)nBuf ); + nBuf = sizeof(t) + sizeof(randomnessPid); + }else{ + do{ got = osRead(fd, zBuf, nBuf); }while( got<0 && errno==EINTR ); + robust_close(0, fd, __LINE__); + } + } +#endif + return nBuf; +} + + +/* +** Sleep for a little while. Return the amount of time slept. +** The argument is the number of microseconds we want to sleep. +** The return value is the number of microseconds of sleep actually +** requested from the underlying operating system, a number which +** might be greater than or equal to the argument, but not less +** than the argument. +*/ +static int unixSleep(sqlite3_vfs *NotUsed, int microseconds){ +#if !defined(HAVE_NANOSLEEP) || HAVE_NANOSLEEP+0 + struct timespec sp; + sp.tv_sec = microseconds / 1000000; + sp.tv_nsec = (microseconds % 1000000) * 1000; + + /* Almost all modern unix systems support nanosleep(). But if you are + ** compiling for one of the rare exceptions, you can use + ** -DHAVE_NANOSLEEP=0 (perhaps in conjunction with -DHAVE_USLEEP if + ** usleep() is available) in order to bypass the use of nanosleep() */ + nanosleep(&sp, NULL); + + UNUSED_PARAMETER(NotUsed); + return microseconds; +#elif defined(HAVE_USLEEP) && HAVE_USLEEP + if( microseconds>=1000000 ) sleep(microseconds/1000000); + if( microseconds%1000000 ) usleep(microseconds%1000000); + UNUSED_PARAMETER(NotUsed); + return microseconds; +#else + int seconds = (microseconds+999999)/1000000; + sleep(seconds); + UNUSED_PARAMETER(NotUsed); + return seconds*1000000; +#endif +} + +/* +** The following variable, if set to a non-zero value, is interpreted as +** the number of seconds since 1970 and is used to set the result of +** sqlite3OsCurrentTime() during testing. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_current_time = 0; /* Fake system time in seconds since 1970. */ +#endif + +/* +** Find the current time (in Universal Coordinated Time). Write into *piNow +** the current time and date as a Julian Day number times 86_400_000. In +** other words, write into *piNow the number of milliseconds since the Julian +** epoch of noon in Greenwich on November 24, 4714 B.C according to the +** proleptic Gregorian calendar. +** +** On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date +** cannot be found. +*/ +static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){ + static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000; + int rc = SQLITE_OK; +#if defined(NO_GETTOD) + time_t t; + time(&t); + *piNow = ((sqlite3_int64)t)*1000 + unixEpoch; +#elif OS_VXWORKS + struct timespec sNow; + clock_gettime(CLOCK_REALTIME, &sNow); + *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_nsec/1000000; +#else + struct timeval sNow; + (void)gettimeofday(&sNow, 0); /* Cannot fail given valid arguments */ + *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000; +#endif + +#ifdef SQLITE_TEST + if( sqlite3_current_time ){ + *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch; + } +#endif + UNUSED_PARAMETER(NotUsed); + return rc; +} + +#ifndef SQLITE_OMIT_DEPRECATED +/* +** Find the current time (in Universal Coordinated Time). Write the +** current time and date as a Julian Day number into *prNow and +** return 0. Return 1 if the time and date cannot be found. +*/ +static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){ + sqlite3_int64 i = 0; + int rc; + UNUSED_PARAMETER(NotUsed); + rc = unixCurrentTimeInt64(0, &i); + *prNow = i/86400000.0; + return rc; +} +#else +# define unixCurrentTime 0 +#endif + +/* +** The xGetLastError() method is designed to return a better +** low-level error message when operating-system problems come up +** during SQLite operation. Only the integer return code is currently +** used. +*/ +static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){ + UNUSED_PARAMETER(NotUsed); + UNUSED_PARAMETER(NotUsed2); + UNUSED_PARAMETER(NotUsed3); + return errno; +} + + +/* +************************ End of sqlite3_vfs methods *************************** +******************************************************************************/ + +/****************************************************************************** +************************** Begin Proxy Locking ******************************** +** +** Proxy locking is a "uber-locking-method" in this sense: It uses the +** other locking methods on secondary lock files. Proxy locking is a +** meta-layer over top of the primitive locking implemented above. For +** this reason, the division that implements of proxy locking is deferred +** until late in the file (here) after all of the other I/O methods have +** been defined - so that the primitive locking methods are available +** as services to help with the implementation of proxy locking. +** +**** +** +** The default locking schemes in SQLite use byte-range locks on the +** database file to coordinate safe, concurrent access by multiple readers +** and writers [http://sqlite.org/lockingv3.html]. The five file locking +** states (UNLOCKED, PENDING, SHARED, RESERVED, EXCLUSIVE) are implemented +** as POSIX read & write locks over fixed set of locations (via fsctl), +** on AFP and SMB only exclusive byte-range locks are available via fsctl +** with _IOWR('z', 23, struct ByteRangeLockPB2) to track the same 5 states. +** To simulate a F_RDLCK on the shared range, on AFP a randomly selected +** address in the shared range is taken for a SHARED lock, the entire +** shared range is taken for an EXCLUSIVE lock): +** +** PENDING_BYTE 0x40000000 +** RESERVED_BYTE 0x40000001 +** SHARED_RANGE 0x40000002 -> 0x40000200 +** +** This works well on the local file system, but shows a nearly 100x +** slowdown in read performance on AFP because the AFP client disables +** the read cache when byte-range locks are present. Enabling the read +** cache exposes a cache coherency problem that is present on all OS X +** supported network file systems. NFS and AFP both observe the +** close-to-open semantics for ensuring cache coherency +** [http://nfs.sourceforge.net/#faq_a8], which does not effectively +** address the requirements for concurrent database access by multiple +** readers and writers +** [http://www.nabble.com/SQLite-on-NFS-cache-coherency-td15655701.html]. +** +** To address the performance and cache coherency issues, proxy file locking +** changes the way database access is controlled by limiting access to a +** single host at a time and moving file locks off of the database file +** and onto a proxy file on the local file system. +** +** +** Using proxy locks +** ----------------- +** +** C APIs +** +** sqlite3_file_control(db, dbname, SQLITE_FCNTL_SET_LOCKPROXYFILE, +** | ":auto:"); +** sqlite3_file_control(db, dbname, SQLITE_FCNTL_GET_LOCKPROXYFILE, +** &); +** +** +** SQL pragmas +** +** PRAGMA [database.]lock_proxy_file= | :auto: +** PRAGMA [database.]lock_proxy_file +** +** Specifying ":auto:" means that if there is a conch file with a matching +** host ID in it, the proxy path in the conch file will be used, otherwise +** a proxy path based on the user's temp dir +** (via confstr(_CS_DARWIN_USER_TEMP_DIR,...)) will be used and the +** actual proxy file name is generated from the name and path of the +** database file. For example: +** +** For database path "/Users/me/foo.db" +** The lock path will be "/sqliteplocks/_Users_me_foo.db:auto:") +** +** Once a lock proxy is configured for a database connection, it can not +** be removed, however it may be switched to a different proxy path via +** the above APIs (assuming the conch file is not being held by another +** connection or process). +** +** +** How proxy locking works +** ----------------------- +** +** Proxy file locking relies primarily on two new supporting files: +** +** * conch file to limit access to the database file to a single host +** at a time +** +** * proxy file to act as a proxy for the advisory locks normally +** taken on the database +** +** The conch file - to use a proxy file, sqlite must first "hold the conch" +** by taking an sqlite-style shared lock on the conch file, reading the +** contents and comparing the host's unique host ID (see below) and lock +** proxy path against the values stored in the conch. The conch file is +** stored in the same directory as the database file and the file name +** is patterned after the database file name as ".-conch". +** If the conch file does not exist, or its contents do not match the +** host ID and/or proxy path, then the lock is escalated to an exclusive +** lock and the conch file contents is updated with the host ID and proxy +** path and the lock is downgraded to a shared lock again. If the conch +** is held by another process (with a shared lock), the exclusive lock +** will fail and SQLITE_BUSY is returned. +** +** The proxy file - a single-byte file used for all advisory file locks +** normally taken on the database file. This allows for safe sharing +** of the database file for multiple readers and writers on the same +** host (the conch ensures that they all use the same local lock file). +** +** Requesting the lock proxy does not immediately take the conch, it is +** only taken when the first request to lock database file is made. +** This matches the semantics of the traditional locking behavior, where +** opening a connection to a database file does not take a lock on it. +** The shared lock and an open file descriptor are maintained until +** the connection to the database is closed. +** +** The proxy file and the lock file are never deleted so they only need +** to be created the first time they are used. +** +** Configuration options +** --------------------- +** +** SQLITE_PREFER_PROXY_LOCKING +** +** Database files accessed on non-local file systems are +** automatically configured for proxy locking, lock files are +** named automatically using the same logic as +** PRAGMA lock_proxy_file=":auto:" +** +** SQLITE_PROXY_DEBUG +** +** Enables the logging of error messages during host id file +** retrieval and creation +** +** LOCKPROXYDIR +** +** Overrides the default directory used for lock proxy files that +** are named automatically via the ":auto:" setting +** +** SQLITE_DEFAULT_PROXYDIR_PERMISSIONS +** +** Permissions to use when creating a directory for storing the +** lock proxy files, only used when LOCKPROXYDIR is not set. +** +** +** As mentioned above, when compiled with SQLITE_PREFER_PROXY_LOCKING, +** setting the environment variable SQLITE_FORCE_PROXY_LOCKING to 1 will +** force proxy locking to be used for every database file opened, and 0 +** will force automatic proxy locking to be disabled for all database +** files (explicitly calling the SQLITE_FCNTL_SET_LOCKPROXYFILE pragma or +** sqlite_file_control API is not affected by SQLITE_FORCE_PROXY_LOCKING). +*/ + +/* +** Proxy locking is only available on MacOSX +*/ +#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE + +/* +** The proxyLockingContext has the path and file structures for the remote +** and local proxy files in it +*/ +typedef struct proxyLockingContext proxyLockingContext; +struct proxyLockingContext { + unixFile *conchFile; /* Open conch file */ + char *conchFilePath; /* Name of the conch file */ + unixFile *lockProxy; /* Open proxy lock file */ + char *lockProxyPath; /* Name of the proxy lock file */ + char *dbPath; /* Name of the open file */ + int conchHeld; /* 1 if the conch is held, -1 if lockless */ + int nFails; /* Number of conch taking failures */ + void *oldLockingContext; /* Original lockingcontext to restore on close */ + sqlite3_io_methods const *pOldMethod; /* Original I/O methods for close */ +}; + +/* +** The proxy lock file path for the database at dbPath is written into lPath, +** which must point to valid, writable memory large enough for a maxLen length +** file path. +*/ +static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){ + int len; + int dbLen; + int i; + +#ifdef LOCKPROXYDIR + len = strlcpy(lPath, LOCKPROXYDIR, maxLen); +#else +# ifdef _CS_DARWIN_USER_TEMP_DIR + { + if( !confstr(_CS_DARWIN_USER_TEMP_DIR, lPath, maxLen) ){ + OSTRACE(("GETLOCKPATH failed %s errno=%d pid=%d\n", + lPath, errno, osGetpid(0))); + return SQLITE_IOERR_LOCK; + } + len = strlcat(lPath, "sqliteplocks", maxLen); + } +# else + len = strlcpy(lPath, "/tmp/", maxLen); +# endif +#endif + + if( lPath[len-1]!='/' ){ + len = strlcat(lPath, "/", maxLen); + } + + /* transform the db path to a unique cache name */ + dbLen = (int)strlen(dbPath); + for( i=0; i 0) ){ + /* only mkdir if leaf dir != "." or "/" or ".." */ + if( i-start>2 || (i-start==1 && buf[start] != '.' && buf[start] != '/') + || (i-start==2 && buf[start] != '.' && buf[start+1] != '.') ){ + buf[i]='\0'; + if( osMkdir(buf, SQLITE_DEFAULT_PROXYDIR_PERMISSIONS) ){ + int err=errno; + if( err!=EEXIST ) { + OSTRACE(("CREATELOCKPATH FAILED creating %s, " + "'%s' proxy lock path=%s pid=%d\n", + buf, strerror(err), lockPath, osGetpid(0))); + return err; + } + } + } + start=i+1; + } + buf[i] = lockPath[i]; + } + OSTRACE(("CREATELOCKPATH proxy lock path=%s pid=%d\n",lockPath,osGetpid(0))); + return 0; +} + +/* +** Create a new VFS file descriptor (stored in memory obtained from +** sqlite3_malloc) and open the file named "path" in the file descriptor. +** +** The caller is responsible not only for closing the file descriptor +** but also for freeing the memory associated with the file descriptor. +*/ +static int proxyCreateUnixFile( + const char *path, /* path for the new unixFile */ + unixFile **ppFile, /* unixFile created and returned by ref */ + int islockfile /* if non zero missing dirs will be created */ +) { + int fd = -1; + unixFile *pNew; + int rc = SQLITE_OK; + int openFlags = O_RDWR | O_CREAT | O_NOFOLLOW; + sqlite3_vfs dummyVfs; + int terrno = 0; + UnixUnusedFd *pUnused = NULL; + + /* 1. first try to open/create the file + ** 2. if that fails, and this is a lock file (not-conch), try creating + ** the parent directories and then try again. + ** 3. if that fails, try to open the file read-only + ** otherwise return BUSY (if lock file) or CANTOPEN for the conch file + */ + pUnused = findReusableFd(path, openFlags); + if( pUnused ){ + fd = pUnused->fd; + }else{ + pUnused = sqlite3_malloc64(sizeof(*pUnused)); + if( !pUnused ){ + return SQLITE_NOMEM_BKPT; + } + } + if( fd<0 ){ + fd = robust_open(path, openFlags, 0); + terrno = errno; + if( fd<0 && errno==ENOENT && islockfile ){ + if( proxyCreateLockPath(path) == SQLITE_OK ){ + fd = robust_open(path, openFlags, 0); + } + } + } + if( fd<0 ){ + openFlags = O_RDONLY | O_NOFOLLOW; + fd = robust_open(path, openFlags, 0); + terrno = errno; + } + if( fd<0 ){ + if( islockfile ){ + return SQLITE_BUSY; + } + switch (terrno) { + case EACCES: + return SQLITE_PERM; + case EIO: + return SQLITE_IOERR_LOCK; /* even though it is the conch */ + default: + return SQLITE_CANTOPEN_BKPT; + } + } + + pNew = (unixFile *)sqlite3_malloc64(sizeof(*pNew)); + if( pNew==NULL ){ + rc = SQLITE_NOMEM_BKPT; + goto end_create_proxy; + } + memset(pNew, 0, sizeof(unixFile)); + pNew->openFlags = openFlags; + memset(&dummyVfs, 0, sizeof(dummyVfs)); + dummyVfs.pAppData = (void*)&autolockIoFinder; + dummyVfs.zName = "dummy"; + pUnused->fd = fd; + pUnused->flags = openFlags; + pNew->pPreallocatedUnused = pUnused; + + rc = fillInUnixFile(&dummyVfs, fd, (sqlite3_file*)pNew, path, 0); + if( rc==SQLITE_OK ){ + *ppFile = pNew; + return SQLITE_OK; + } +end_create_proxy: + robust_close(pNew, fd, __LINE__); + sqlite3_free(pNew); + sqlite3_free(pUnused); + return rc; +} + +#ifdef SQLITE_TEST +/* simulate multiple hosts by creating unique hostid file paths */ +SQLITE_API int sqlite3_hostid_num = 0; +#endif + +#define PROXY_HOSTIDLEN 16 /* conch file host id length */ + +#if HAVE_GETHOSTUUID +/* Not always defined in the headers as it ought to be */ +extern int gethostuuid(uuid_t id, const struct timespec *wait); +#endif + +/* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN +** bytes of writable memory. +*/ +static int proxyGetHostID(unsigned char *pHostID, int *pError){ + assert(PROXY_HOSTIDLEN == sizeof(uuid_t)); + memset(pHostID, 0, PROXY_HOSTIDLEN); +#if HAVE_GETHOSTUUID + { + struct timespec timeout = {1, 0}; /* 1 sec timeout */ + if( gethostuuid(pHostID, &timeout) ){ + int err = errno; + if( pError ){ + *pError = err; + } + return SQLITE_IOERR; + } + } +#else + UNUSED_PARAMETER(pError); +#endif +#ifdef SQLITE_TEST + /* simulate multiple hosts by creating unique hostid file paths */ + if( sqlite3_hostid_num != 0){ + pHostID[0] = (char)(pHostID[0] + (char)(sqlite3_hostid_num & 0xFF)); + } +#endif + + return SQLITE_OK; +} + +/* The conch file contains the header, host id and lock file path + */ +#define PROXY_CONCHVERSION 2 /* 1-byte header, 16-byte host id, path */ +#define PROXY_HEADERLEN 1 /* conch file header length */ +#define PROXY_PATHINDEX (PROXY_HEADERLEN+PROXY_HOSTIDLEN) +#define PROXY_MAXCONCHLEN (PROXY_HEADERLEN+PROXY_HOSTIDLEN+MAXPATHLEN) + +/* +** Takes an open conch file, copies the contents to a new path and then moves +** it back. The newly created file's file descriptor is assigned to the +** conch file structure and finally the original conch file descriptor is +** closed. Returns zero if successful. +*/ +static int proxyBreakConchLock(unixFile *pFile, uuid_t myHostID){ + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + unixFile *conchFile = pCtx->conchFile; + char tPath[MAXPATHLEN]; + char buf[PROXY_MAXCONCHLEN]; + char *cPath = pCtx->conchFilePath; + size_t readLen = 0; + size_t pathLen = 0; + char errmsg[64] = ""; + int fd = -1; + int rc = -1; + UNUSED_PARAMETER(myHostID); + + /* create a new path by replace the trailing '-conch' with '-break' */ + pathLen = strlcpy(tPath, cPath, MAXPATHLEN); + if( pathLen>MAXPATHLEN || pathLen<6 || + (strlcpy(&tPath[pathLen-5], "break", 6) != 5) ){ + sqlite3_snprintf(sizeof(errmsg),errmsg,"path error (len %d)",(int)pathLen); + goto end_breaklock; + } + /* read the conch content */ + readLen = osPread(conchFile->h, buf, PROXY_MAXCONCHLEN, 0); + if( readLenh, __LINE__); + conchFile->h = fd; + conchFile->openFlags = O_RDWR | O_CREAT; + +end_breaklock: + if( rc ){ + if( fd>=0 ){ + osUnlink(tPath); + robust_close(pFile, fd, __LINE__); + } + fprintf(stderr, "failed to break stale lock on %s, %s\n", cPath, errmsg); + } + return rc; +} + +/* Take the requested lock on the conch file and break a stale lock if the +** host id matches. +*/ +static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){ + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + unixFile *conchFile = pCtx->conchFile; + int rc = SQLITE_OK; + int nTries = 0; + struct timespec conchModTime; + + memset(&conchModTime, 0, sizeof(conchModTime)); + do { + rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType); + nTries ++; + if( rc==SQLITE_BUSY ){ + /* If the lock failed (busy): + * 1st try: get the mod time of the conch, wait 0.5s and try again. + * 2nd try: fail if the mod time changed or host id is different, wait + * 10 sec and try again + * 3rd try: break the lock unless the mod time has changed. + */ + struct stat buf; + if( osFstat(conchFile->h, &buf) ){ + storeLastErrno(pFile, errno); + return SQLITE_IOERR_LOCK; + } + + if( nTries==1 ){ + conchModTime = buf.st_mtimespec; + unixSleep(0,500000); /* wait 0.5 sec and try the lock again*/ + continue; + } + + assert( nTries>1 ); + if( conchModTime.tv_sec != buf.st_mtimespec.tv_sec || + conchModTime.tv_nsec != buf.st_mtimespec.tv_nsec ){ + return SQLITE_BUSY; + } + + if( nTries==2 ){ + char tBuf[PROXY_MAXCONCHLEN]; + int len = osPread(conchFile->h, tBuf, PROXY_MAXCONCHLEN, 0); + if( len<0 ){ + storeLastErrno(pFile, errno); + return SQLITE_IOERR_LOCK; + } + if( len>PROXY_PATHINDEX && tBuf[0]==(char)PROXY_CONCHVERSION){ + /* don't break the lock if the host id doesn't match */ + if( 0!=memcmp(&tBuf[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN) ){ + return SQLITE_BUSY; + } + }else{ + /* don't break the lock on short read or a version mismatch */ + return SQLITE_BUSY; + } + unixSleep(0,10000000); /* wait 10 sec and try the lock again */ + continue; + } + + assert( nTries==3 ); + if( 0==proxyBreakConchLock(pFile, myHostID) ){ + rc = SQLITE_OK; + if( lockType==EXCLUSIVE_LOCK ){ + rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK); + } + if( !rc ){ + rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType); + } + } + } + } while( rc==SQLITE_BUSY && nTries<3 ); + + return rc; +} + +/* Takes the conch by taking a shared lock and read the contents conch, if +** lockPath is non-NULL, the host ID and lock file path must match. A NULL +** lockPath means that the lockPath in the conch file will be used if the +** host IDs match, or a new lock path will be generated automatically +** and written to the conch file. +*/ +static int proxyTakeConch(unixFile *pFile){ + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + + if( pCtx->conchHeld!=0 ){ + return SQLITE_OK; + }else{ + unixFile *conchFile = pCtx->conchFile; + uuid_t myHostID; + int pError = 0; + char readBuf[PROXY_MAXCONCHLEN]; + char lockPath[MAXPATHLEN]; + char *tempLockPath = NULL; + int rc = SQLITE_OK; + int createConch = 0; + int hostIdMatch = 0; + int readLen = 0; + int tryOldLockPath = 0; + int forceNewLockPath = 0; + + OSTRACE(("TAKECONCH %d for %s pid=%d\n", conchFile->h, + (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), + osGetpid(0))); + + rc = proxyGetHostID(myHostID, &pError); + if( (rc&0xff)==SQLITE_IOERR ){ + storeLastErrno(pFile, pError); + goto end_takeconch; + } + rc = proxyConchLock(pFile, myHostID, SHARED_LOCK); + if( rc!=SQLITE_OK ){ + goto end_takeconch; + } + /* read the existing conch file */ + readLen = seekAndRead((unixFile*)conchFile, 0, readBuf, PROXY_MAXCONCHLEN); + if( readLen<0 ){ + /* I/O error: lastErrno set by seekAndRead */ + storeLastErrno(pFile, conchFile->lastErrno); + rc = SQLITE_IOERR_READ; + goto end_takeconch; + }else if( readLen<=(PROXY_HEADERLEN+PROXY_HOSTIDLEN) || + readBuf[0]!=(char)PROXY_CONCHVERSION ){ + /* a short read or version format mismatch means we need to create a new + ** conch file. + */ + createConch = 1; + } + /* if the host id matches and the lock path already exists in the conch + ** we'll try to use the path there, if we can't open that path, we'll + ** retry with a new auto-generated path + */ + do { /* in case we need to try again for an :auto: named lock file */ + + if( !createConch && !forceNewLockPath ){ + hostIdMatch = !memcmp(&readBuf[PROXY_HEADERLEN], myHostID, + PROXY_HOSTIDLEN); + /* if the conch has data compare the contents */ + if( !pCtx->lockProxyPath ){ + /* for auto-named local lock file, just check the host ID and we'll + ** use the local lock file path that's already in there + */ + if( hostIdMatch ){ + size_t pathLen = (readLen - PROXY_PATHINDEX); + + if( pathLen>=MAXPATHLEN ){ + pathLen=MAXPATHLEN-1; + } + memcpy(lockPath, &readBuf[PROXY_PATHINDEX], pathLen); + lockPath[pathLen] = 0; + tempLockPath = lockPath; + tryOldLockPath = 1; + /* create a copy of the lock path if the conch is taken */ + goto end_takeconch; + } + }else if( hostIdMatch + && !strncmp(pCtx->lockProxyPath, &readBuf[PROXY_PATHINDEX], + readLen-PROXY_PATHINDEX) + ){ + /* conch host and lock path match */ + goto end_takeconch; + } + } + + /* if the conch isn't writable and doesn't match, we can't take it */ + if( (conchFile->openFlags&O_RDWR) == 0 ){ + rc = SQLITE_BUSY; + goto end_takeconch; + } + + /* either the conch didn't match or we need to create a new one */ + if( !pCtx->lockProxyPath ){ + proxyGetLockPath(pCtx->dbPath, lockPath, MAXPATHLEN); + tempLockPath = lockPath; + /* create a copy of the lock path _only_ if the conch is taken */ + } + + /* update conch with host and path (this will fail if other process + ** has a shared lock already), if the host id matches, use the big + ** stick. + */ + futimes(conchFile->h, NULL); + if( hostIdMatch && !createConch ){ + if( conchFile->pInode && conchFile->pInode->nShared>1 ){ + /* We are trying for an exclusive lock but another thread in this + ** same process is still holding a shared lock. */ + rc = SQLITE_BUSY; + } else { + rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK); + } + }else{ + rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK); + } + if( rc==SQLITE_OK ){ + char writeBuffer[PROXY_MAXCONCHLEN]; + int writeSize = 0; + + writeBuffer[0] = (char)PROXY_CONCHVERSION; + memcpy(&writeBuffer[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN); + if( pCtx->lockProxyPath!=NULL ){ + strlcpy(&writeBuffer[PROXY_PATHINDEX], pCtx->lockProxyPath, + MAXPATHLEN); + }else{ + strlcpy(&writeBuffer[PROXY_PATHINDEX], tempLockPath, MAXPATHLEN); + } + writeSize = PROXY_PATHINDEX + strlen(&writeBuffer[PROXY_PATHINDEX]); + robust_ftruncate(conchFile->h, writeSize); + rc = unixWrite((sqlite3_file *)conchFile, writeBuffer, writeSize, 0); + full_fsync(conchFile->h,0,0); + /* If we created a new conch file (not just updated the contents of a + ** valid conch file), try to match the permissions of the database + */ + if( rc==SQLITE_OK && createConch ){ + struct stat buf; + int err = osFstat(pFile->h, &buf); + if( err==0 ){ + mode_t cmode = buf.st_mode&(S_IRUSR|S_IWUSR | S_IRGRP|S_IWGRP | + S_IROTH|S_IWOTH); + /* try to match the database file R/W permissions, ignore failure */ +#ifndef SQLITE_PROXY_DEBUG + osFchmod(conchFile->h, cmode); +#else + do{ + rc = osFchmod(conchFile->h, cmode); + }while( rc==(-1) && errno==EINTR ); + if( rc!=0 ){ + int code = errno; + fprintf(stderr, "fchmod %o FAILED with %d %s\n", + cmode, code, strerror(code)); + } else { + fprintf(stderr, "fchmod %o SUCCEDED\n",cmode); + } + }else{ + int code = errno; + fprintf(stderr, "STAT FAILED[%d] with %d %s\n", + err, code, strerror(code)); +#endif + } + } + } + conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, SHARED_LOCK); + + end_takeconch: + OSTRACE(("TRANSPROXY: CLOSE %d\n", pFile->h)); + if( rc==SQLITE_OK && pFile->openFlags ){ + int fd; + if( pFile->h>=0 ){ + robust_close(pFile, pFile->h, __LINE__); + } + pFile->h = -1; + fd = robust_open(pCtx->dbPath, pFile->openFlags, 0); + OSTRACE(("TRANSPROXY: OPEN %d\n", fd)); + if( fd>=0 ){ + pFile->h = fd; + }else{ + rc=SQLITE_CANTOPEN_BKPT; /* SQLITE_BUSY? proxyTakeConch called + during locking */ + } + } + if( rc==SQLITE_OK && !pCtx->lockProxy ){ + char *path = tempLockPath ? tempLockPath : pCtx->lockProxyPath; + rc = proxyCreateUnixFile(path, &pCtx->lockProxy, 1); + if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM && tryOldLockPath ){ + /* we couldn't create the proxy lock file with the old lock file path + ** so try again via auto-naming + */ + forceNewLockPath = 1; + tryOldLockPath = 0; + continue; /* go back to the do {} while start point, try again */ + } + } + if( rc==SQLITE_OK ){ + /* Need to make a copy of path if we extracted the value + ** from the conch file or the path was allocated on the stack + */ + if( tempLockPath ){ + pCtx->lockProxyPath = sqlite3DbStrDup(0, tempLockPath); + if( !pCtx->lockProxyPath ){ + rc = SQLITE_NOMEM_BKPT; + } + } + } + if( rc==SQLITE_OK ){ + pCtx->conchHeld = 1; + + if( pCtx->lockProxy->pMethod == &afpIoMethods ){ + afpLockingContext *afpCtx; + afpCtx = (afpLockingContext *)pCtx->lockProxy->lockingContext; + afpCtx->dbPath = pCtx->lockProxyPath; + } + } else { + conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK); + } + OSTRACE(("TAKECONCH %d %s\n", conchFile->h, + rc==SQLITE_OK?"ok":"failed")); + return rc; + } while (1); /* in case we need to retry the :auto: lock file - + ** we should never get here except via the 'continue' call. */ + } +} + +/* +** If pFile holds a lock on a conch file, then release that lock. +*/ +static int proxyReleaseConch(unixFile *pFile){ + int rc = SQLITE_OK; /* Subroutine return code */ + proxyLockingContext *pCtx; /* The locking context for the proxy lock */ + unixFile *conchFile; /* Name of the conch file */ + + pCtx = (proxyLockingContext *)pFile->lockingContext; + conchFile = pCtx->conchFile; + OSTRACE(("RELEASECONCH %d for %s pid=%d\n", conchFile->h, + (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), + osGetpid(0))); + if( pCtx->conchHeld>0 ){ + rc = conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK); + } + pCtx->conchHeld = 0; + OSTRACE(("RELEASECONCH %d %s\n", conchFile->h, + (rc==SQLITE_OK ? "ok" : "failed"))); + return rc; +} + +/* +** Given the name of a database file, compute the name of its conch file. +** Store the conch filename in memory obtained from sqlite3_malloc64(). +** Make *pConchPath point to the new name. Return SQLITE_OK on success +** or SQLITE_NOMEM if unable to obtain memory. +** +** The caller is responsible for ensuring that the allocated memory +** space is eventually freed. +** +** *pConchPath is set to NULL if a memory allocation error occurs. +*/ +static int proxyCreateConchPathname(char *dbPath, char **pConchPath){ + int i; /* Loop counter */ + int len = (int)strlen(dbPath); /* Length of database filename - dbPath */ + char *conchPath; /* buffer in which to construct conch name */ + + /* Allocate space for the conch filename and initialize the name to + ** the name of the original database file. */ + *pConchPath = conchPath = (char *)sqlite3_malloc64(len + 8); + if( conchPath==0 ){ + return SQLITE_NOMEM_BKPT; + } + memcpy(conchPath, dbPath, len+1); + + /* now insert a "." before the last / character */ + for( i=(len-1); i>=0; i-- ){ + if( conchPath[i]=='/' ){ + i++; + break; + } + } + conchPath[i]='.'; + while ( ilockingContext; + char *oldPath = pCtx->lockProxyPath; + int rc = SQLITE_OK; + + if( pFile->eFileLock!=NO_LOCK ){ + return SQLITE_BUSY; + } + + /* nothing to do if the path is NULL, :auto: or matches the existing path */ + if( !path || path[0]=='\0' || !strcmp(path, ":auto:") || + (oldPath && !strncmp(oldPath, path, MAXPATHLEN)) ){ + return SQLITE_OK; + }else{ + unixFile *lockProxy = pCtx->lockProxy; + pCtx->lockProxy=NULL; + pCtx->conchHeld = 0; + if( lockProxy!=NULL ){ + rc=lockProxy->pMethod->xClose((sqlite3_file *)lockProxy); + if( rc ) return rc; + sqlite3_free(lockProxy); + } + sqlite3_free(oldPath); + pCtx->lockProxyPath = sqlite3DbStrDup(0, path); + } + + return rc; +} + +/* +** pFile is a file that has been opened by a prior xOpen call. dbPath +** is a string buffer at least MAXPATHLEN+1 characters in size. +** +** This routine find the filename associated with pFile and writes it +** int dbPath. +*/ +static int proxyGetDbPathForUnixFile(unixFile *pFile, char *dbPath){ +#if defined(__APPLE__) + if( pFile->pMethod == &afpIoMethods ){ + /* afp style keeps a reference to the db path in the filePath field + ** of the struct */ + assert( (int)strlen((char*)pFile->lockingContext)<=MAXPATHLEN ); + strlcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath, + MAXPATHLEN); + } else +#endif + if( pFile->pMethod == &dotlockIoMethods ){ + /* dot lock style uses the locking context to store the dot lock + ** file path */ + int len = strlen((char *)pFile->lockingContext) - strlen(DOTLOCK_SUFFIX); + memcpy(dbPath, (char *)pFile->lockingContext, len + 1); + }else{ + /* all other styles use the locking context to store the db file path */ + assert( strlen((char*)pFile->lockingContext)<=MAXPATHLEN ); + strlcpy(dbPath, (char *)pFile->lockingContext, MAXPATHLEN); + } + return SQLITE_OK; +} + +/* +** Takes an already filled in unix file and alters it so all file locking +** will be performed on the local proxy lock file. The following fields +** are preserved in the locking context so that they can be restored and +** the unix structure properly cleaned up at close time: +** ->lockingContext +** ->pMethod +*/ +static int proxyTransformUnixFile(unixFile *pFile, const char *path) { + proxyLockingContext *pCtx; + char dbPath[MAXPATHLEN+1]; /* Name of the database file */ + char *lockPath=NULL; + int rc = SQLITE_OK; + + if( pFile->eFileLock!=NO_LOCK ){ + return SQLITE_BUSY; + } + proxyGetDbPathForUnixFile(pFile, dbPath); + if( !path || path[0]=='\0' || !strcmp(path, ":auto:") ){ + lockPath=NULL; + }else{ + lockPath=(char *)path; + } + + OSTRACE(("TRANSPROXY %d for %s pid=%d\n", pFile->h, + (lockPath ? lockPath : ":auto:"), osGetpid(0))); + + pCtx = sqlite3_malloc64( sizeof(*pCtx) ); + if( pCtx==0 ){ + return SQLITE_NOMEM_BKPT; + } + memset(pCtx, 0, sizeof(*pCtx)); + + rc = proxyCreateConchPathname(dbPath, &pCtx->conchFilePath); + if( rc==SQLITE_OK ){ + rc = proxyCreateUnixFile(pCtx->conchFilePath, &pCtx->conchFile, 0); + if( rc==SQLITE_CANTOPEN && ((pFile->openFlags&O_RDWR) == 0) ){ + /* if (a) the open flags are not O_RDWR, (b) the conch isn't there, and + ** (c) the file system is read-only, then enable no-locking access. + ** Ugh, since O_RDONLY==0x0000 we test for !O_RDWR since unixOpen asserts + ** that openFlags will have only one of O_RDONLY or O_RDWR. + */ + struct statfs fsInfo; + struct stat conchInfo; + int goLockless = 0; + + if( osStat(pCtx->conchFilePath, &conchInfo) == -1 ) { + int err = errno; + if( (err==ENOENT) && (statfs(dbPath, &fsInfo) != -1) ){ + goLockless = (fsInfo.f_flags&MNT_RDONLY) == MNT_RDONLY; + } + } + if( goLockless ){ + pCtx->conchHeld = -1; /* read only FS/ lockless */ + rc = SQLITE_OK; + } + } + } + if( rc==SQLITE_OK && lockPath ){ + pCtx->lockProxyPath = sqlite3DbStrDup(0, lockPath); + } + + if( rc==SQLITE_OK ){ + pCtx->dbPath = sqlite3DbStrDup(0, dbPath); + if( pCtx->dbPath==NULL ){ + rc = SQLITE_NOMEM_BKPT; + } + } + if( rc==SQLITE_OK ){ + /* all memory is allocated, proxys are created and assigned, + ** switch the locking context and pMethod then return. + */ + pCtx->oldLockingContext = pFile->lockingContext; + pFile->lockingContext = pCtx; + pCtx->pOldMethod = pFile->pMethod; + pFile->pMethod = &proxyIoMethods; + }else{ + if( pCtx->conchFile ){ + pCtx->conchFile->pMethod->xClose((sqlite3_file *)pCtx->conchFile); + sqlite3_free(pCtx->conchFile); + } + sqlite3DbFree(0, pCtx->lockProxyPath); + sqlite3_free(pCtx->conchFilePath); + sqlite3_free(pCtx); + } + OSTRACE(("TRANSPROXY %d %s\n", pFile->h, + (rc==SQLITE_OK ? "ok" : "failed"))); + return rc; +} + + +/* +** This routine handles sqlite3_file_control() calls that are specific +** to proxy locking. +*/ +static int proxyFileControl(sqlite3_file *id, int op, void *pArg){ + switch( op ){ + case SQLITE_FCNTL_GET_LOCKPROXYFILE: { + unixFile *pFile = (unixFile*)id; + if( pFile->pMethod == &proxyIoMethods ){ + proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext; + proxyTakeConch(pFile); + if( pCtx->lockProxyPath ){ + *(const char **)pArg = pCtx->lockProxyPath; + }else{ + *(const char **)pArg = ":auto: (not held)"; + } + } else { + *(const char **)pArg = NULL; + } + return SQLITE_OK; + } + case SQLITE_FCNTL_SET_LOCKPROXYFILE: { + unixFile *pFile = (unixFile*)id; + int rc = SQLITE_OK; + int isProxyStyle = (pFile->pMethod == &proxyIoMethods); + if( pArg==NULL || (const char *)pArg==0 ){ + if( isProxyStyle ){ + /* turn off proxy locking - not supported. If support is added for + ** switching proxy locking mode off then it will need to fail if + ** the journal mode is WAL mode. + */ + rc = SQLITE_ERROR /*SQLITE_PROTOCOL? SQLITE_MISUSE?*/; + }else{ + /* turn off proxy locking - already off - NOOP */ + rc = SQLITE_OK; + } + }else{ + const char *proxyPath = (const char *)pArg; + if( isProxyStyle ){ + proxyLockingContext *pCtx = + (proxyLockingContext*)pFile->lockingContext; + if( !strcmp(pArg, ":auto:") + || (pCtx->lockProxyPath && + !strncmp(pCtx->lockProxyPath, proxyPath, MAXPATHLEN)) + ){ + rc = SQLITE_OK; + }else{ + rc = switchLockProxyPath(pFile, proxyPath); + } + }else{ + /* turn on proxy file locking */ + rc = proxyTransformUnixFile(pFile, proxyPath); + } + } + return rc; + } + default: { + assert( 0 ); /* The call assures that only valid opcodes are sent */ + } + } + /*NOTREACHED*/ assert(0); + return SQLITE_ERROR; +} + +/* +** Within this division (the proxying locking implementation) the procedures +** above this point are all utilities. The lock-related methods of the +** proxy-locking sqlite3_io_method object follow. +*/ + + +/* +** This routine checks if there is a RESERVED lock held on the specified +** file by this or any other process. If such a lock is held, set *pResOut +** to a non-zero value otherwise *pResOut is set to zero. The return value +** is set to SQLITE_OK unless an I/O error occurs during lock checking. +*/ +static int proxyCheckReservedLock(sqlite3_file *id, int *pResOut) { + unixFile *pFile = (unixFile*)id; + int rc = proxyTakeConch(pFile); + if( rc==SQLITE_OK ){ + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + if( pCtx->conchHeld>0 ){ + unixFile *proxy = pCtx->lockProxy; + return proxy->pMethod->xCheckReservedLock((sqlite3_file*)proxy, pResOut); + }else{ /* conchHeld < 0 is lockless */ + pResOut=0; + } + } + return rc; +} + +/* +** Lock the file with the lock specified by parameter eFileLock - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> (PENDING) -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** This routine will only increase a lock. Use the sqlite3OsUnlock() +** routine to lower a locking level. +*/ +static int proxyLock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + int rc = proxyTakeConch(pFile); + if( rc==SQLITE_OK ){ + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + if( pCtx->conchHeld>0 ){ + unixFile *proxy = pCtx->lockProxy; + rc = proxy->pMethod->xLock((sqlite3_file*)proxy, eFileLock); + pFile->eFileLock = proxy->eFileLock; + }else{ + /* conchHeld < 0 is lockless */ + } + } + return rc; +} + + +/* +** Lower the locking level on file descriptor pFile to eFileLock. eFileLock +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +*/ +static int proxyUnlock(sqlite3_file *id, int eFileLock) { + unixFile *pFile = (unixFile*)id; + int rc = proxyTakeConch(pFile); + if( rc==SQLITE_OK ){ + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + if( pCtx->conchHeld>0 ){ + unixFile *proxy = pCtx->lockProxy; + rc = proxy->pMethod->xUnlock((sqlite3_file*)proxy, eFileLock); + pFile->eFileLock = proxy->eFileLock; + }else{ + /* conchHeld < 0 is lockless */ + } + } + return rc; +} + +/* +** Close a file that uses proxy locks. +*/ +static int proxyClose(sqlite3_file *id) { + if( ALWAYS(id) ){ + unixFile *pFile = (unixFile*)id; + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + unixFile *lockProxy = pCtx->lockProxy; + unixFile *conchFile = pCtx->conchFile; + int rc = SQLITE_OK; + + if( lockProxy ){ + rc = lockProxy->pMethod->xUnlock((sqlite3_file*)lockProxy, NO_LOCK); + if( rc ) return rc; + rc = lockProxy->pMethod->xClose((sqlite3_file*)lockProxy); + if( rc ) return rc; + sqlite3_free(lockProxy); + pCtx->lockProxy = 0; + } + if( conchFile ){ + if( pCtx->conchHeld ){ + rc = proxyReleaseConch(pFile); + if( rc ) return rc; + } + rc = conchFile->pMethod->xClose((sqlite3_file*)conchFile); + if( rc ) return rc; + sqlite3_free(conchFile); + } + sqlite3DbFree(0, pCtx->lockProxyPath); + sqlite3_free(pCtx->conchFilePath); + sqlite3DbFree(0, pCtx->dbPath); + /* restore the original locking context and pMethod then close it */ + pFile->lockingContext = pCtx->oldLockingContext; + pFile->pMethod = pCtx->pOldMethod; + sqlite3_free(pCtx); + return pFile->pMethod->xClose(id); + } + return SQLITE_OK; +} + + + +#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ +/* +** The proxy locking style is intended for use with AFP filesystems. +** And since AFP is only supported on MacOSX, the proxy locking is also +** restricted to MacOSX. +** +** +******************* End of the proxy lock implementation ********************** +******************************************************************************/ + +/* +** Initialize the operating system interface. +** +** This routine registers all VFS implementations for unix-like operating +** systems. This routine, and the sqlite3_os_end() routine that follows, +** should be the only routines in this file that are visible from other +** files. +** +** This routine is called once during SQLite initialization and by a +** single thread. The memory allocation and mutex subsystems have not +** necessarily been initialized when this routine is called, and so they +** should not be used. +*/ +SQLITE_API int sqlite3_os_init(void){ + /* + ** The following macro defines an initializer for an sqlite3_vfs object. + ** The name of the VFS is NAME. The pAppData is a pointer to a pointer + ** to the "finder" function. (pAppData is a pointer to a pointer because + ** silly C90 rules prohibit a void* from being cast to a function pointer + ** and so we have to go through the intermediate pointer to avoid problems + ** when compiling with -pedantic-errors on GCC.) + ** + ** The FINDER parameter to this macro is the name of the pointer to the + ** finder-function. The finder-function returns a pointer to the + ** sqlite_io_methods object that implements the desired locking + ** behaviors. See the division above that contains the IOMETHODS + ** macro for addition information on finder-functions. + ** + ** Most finders simply return a pointer to a fixed sqlite3_io_methods + ** object. But the "autolockIoFinder" available on MacOSX does a little + ** more than that; it looks at the filesystem type that hosts the + ** database file and tries to choose an locking method appropriate for + ** that filesystem time. + */ + #define UNIXVFS(VFSNAME, FINDER) { \ + 3, /* iVersion */ \ + sizeof(unixFile), /* szOsFile */ \ + MAX_PATHNAME, /* mxPathname */ \ + 0, /* pNext */ \ + VFSNAME, /* zName */ \ + (void*)&FINDER, /* pAppData */ \ + unixOpen, /* xOpen */ \ + unixDelete, /* xDelete */ \ + unixAccess, /* xAccess */ \ + unixFullPathname, /* xFullPathname */ \ + unixDlOpen, /* xDlOpen */ \ + unixDlError, /* xDlError */ \ + unixDlSym, /* xDlSym */ \ + unixDlClose, /* xDlClose */ \ + unixRandomness, /* xRandomness */ \ + unixSleep, /* xSleep */ \ + unixCurrentTime, /* xCurrentTime */ \ + unixGetLastError, /* xGetLastError */ \ + unixCurrentTimeInt64, /* xCurrentTimeInt64 */ \ + unixSetSystemCall, /* xSetSystemCall */ \ + unixGetSystemCall, /* xGetSystemCall */ \ + unixNextSystemCall, /* xNextSystemCall */ \ + } + + /* + ** All default VFSes for unix are contained in the following array. + ** + ** Note that the sqlite3_vfs.pNext field of the VFS object is modified + ** by the SQLite core when the VFS is registered. So the following + ** array cannot be const. + */ + static sqlite3_vfs aVfs[] = { +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) + UNIXVFS("unix", autolockIoFinder ), +#elif OS_VXWORKS + UNIXVFS("unix", vxworksIoFinder ), +#else + UNIXVFS("unix", posixIoFinder ), +#endif + UNIXVFS("unix-none", nolockIoFinder ), + UNIXVFS("unix-dotfile", dotlockIoFinder ), + UNIXVFS("unix-excl", posixIoFinder ), +#if OS_VXWORKS + UNIXVFS("unix-namedsem", semIoFinder ), +#endif +#if SQLITE_ENABLE_LOCKING_STYLE || OS_VXWORKS + UNIXVFS("unix-posix", posixIoFinder ), +#endif +#if SQLITE_ENABLE_LOCKING_STYLE + UNIXVFS("unix-flock", flockIoFinder ), +#endif +#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) + UNIXVFS("unix-afp", afpIoFinder ), + UNIXVFS("unix-nfs", nfsIoFinder ), + UNIXVFS("unix-proxy", proxyIoFinder ), +#endif + }; + unsigned int i; /* Loop counter */ + + /* Double-check that the aSyscall[] array has been constructed + ** correctly. See ticket [bb3a86e890c8e96ab] */ + assert( ArraySize(aSyscall)==29 ); + + /* Register all VFSes defined in the aVfs[] array */ + for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ +#ifdef SQLITE_DEFAULT_UNIX_VFS + sqlite3_vfs_register(&aVfs[i], + 0==strcmp(aVfs[i].zName,SQLITE_DEFAULT_UNIX_VFS)); +#else + sqlite3_vfs_register(&aVfs[i], i==0); +#endif + } +#ifdef SQLITE_OS_KV_OPTIONAL + sqlite3KvvfsInit(); +#endif + unixBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); +#if OS_VXWORKS + vxworksMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS2); +#endif + +#ifndef SQLITE_OMIT_WAL + /* Validate lock assumptions */ + assert( SQLITE_SHM_NLOCK==8 ); /* Number of available locks */ + assert( UNIX_SHM_BASE==120 ); /* Start of locking area */ + /* Locks: + ** WRITE UNIX_SHM_BASE 120 + ** CKPT UNIX_SHM_BASE+1 121 + ** RECOVER UNIX_SHM_BASE+2 122 + ** READ-0 UNIX_SHM_BASE+3 123 + ** READ-1 UNIX_SHM_BASE+4 124 + ** READ-2 UNIX_SHM_BASE+5 125 + ** READ-3 UNIX_SHM_BASE+6 126 + ** READ-4 UNIX_SHM_BASE+7 127 + ** DMS UNIX_SHM_BASE+8 128 + */ + assert( UNIX_SHM_DMS==128 ); /* Byte offset of the deadman-switch */ +#endif + + /* Initialize temp file dir array. */ + unixTempFileInit(); + + return SQLITE_OK; +} + +/* +** Shutdown the operating system interface. +** +** Some operating systems might need to do some cleanup in this routine, +** to release dynamically allocated objects. But not on unix. +** This routine is a no-op for unix. +*/ +SQLITE_API int sqlite3_os_end(void){ + unixBigLock = 0; +#if OS_VXWORKS + vxworksMutex = 0; +#endif + return SQLITE_OK; +} + +#endif /* SQLITE_OS_UNIX */ + +/************** End of os_unix.c *********************************************/ +/************** Begin file os_win.c ******************************************/ +/* +** 2004 May 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains code that is specific to Windows. +*/ +/* #include "sqliteInt.h" */ +#if SQLITE_OS_WIN /* This file is used for Windows only */ + +/* +** Include code that is common to all os_*.c files +*/ +/* #include "os_common.h" */ + +/* +** Include the header file for the Windows VFS. +*/ +/* #include "os_win.h" */ + +/* +** Compiling and using WAL mode requires several APIs that are only +** available in Windows platforms based on the NT kernel. +*/ +#if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL) +# error "WAL mode requires support from the Windows NT kernel, compile\ + with SQLITE_OMIT_WAL." +#endif + +#if !SQLITE_OS_WINNT && SQLITE_MAX_MMAP_SIZE>0 +# error "Memory mapped files require support from the Windows NT kernel,\ + compile with SQLITE_MAX_MMAP_SIZE=0." +#endif + +/* +** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions +** based on the sub-platform)? +*/ +#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_ANSI) +# define SQLITE_WIN32_HAS_ANSI +#endif + +/* +** Are most of the Win32 Unicode APIs available (i.e. with certain exceptions +** based on the sub-platform)? +*/ +#if (SQLITE_OS_WINCE || SQLITE_OS_WINNT) && \ + !defined(SQLITE_WIN32_NO_WIDE) +# define SQLITE_WIN32_HAS_WIDE +#endif + +/* +** Make sure at least one set of Win32 APIs is available. +*/ +#if !defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_WIN32_HAS_WIDE) +# error "At least one of SQLITE_WIN32_HAS_ANSI and SQLITE_WIN32_HAS_WIDE\ + must be defined." +#endif + +/* +** Define the required Windows SDK version constants if they are not +** already available. +*/ +#ifndef NTDDI_WIN8 +# define NTDDI_WIN8 0x06020000 +#endif + +#ifndef NTDDI_WINBLUE +# define NTDDI_WINBLUE 0x06030000 +#endif + +#ifndef NTDDI_WINTHRESHOLD +# define NTDDI_WINTHRESHOLD 0x06040000 +#endif + +/* +** Check to see if the GetVersionEx[AW] functions are deprecated on the +** target system. GetVersionEx was first deprecated in Win8.1. +*/ +#ifndef SQLITE_WIN32_GETVERSIONEX +# if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINBLUE +# define SQLITE_WIN32_GETVERSIONEX 0 /* GetVersionEx() is deprecated */ +# else +# define SQLITE_WIN32_GETVERSIONEX 1 /* GetVersionEx() is current */ +# endif +#endif + +/* +** Check to see if the CreateFileMappingA function is supported on the +** target system. It is unavailable when using "mincore.lib" on Win10. +** When compiling for Windows 10, always assume "mincore.lib" is in use. +*/ +#ifndef SQLITE_WIN32_CREATEFILEMAPPINGA +# if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINTHRESHOLD +# define SQLITE_WIN32_CREATEFILEMAPPINGA 0 +# else +# define SQLITE_WIN32_CREATEFILEMAPPINGA 1 +# endif +#endif + +/* +** This constant should already be defined (in the "WinDef.h" SDK file). +*/ +#ifndef MAX_PATH +# define MAX_PATH (260) +#endif + +/* +** Maximum pathname length (in chars) for Win32. This should normally be +** MAX_PATH. +*/ +#ifndef SQLITE_WIN32_MAX_PATH_CHARS +# define SQLITE_WIN32_MAX_PATH_CHARS (MAX_PATH) +#endif + +/* +** This constant should already be defined (in the "WinNT.h" SDK file). +*/ +#ifndef UNICODE_STRING_MAX_CHARS +# define UNICODE_STRING_MAX_CHARS (32767) +#endif + +/* +** Maximum pathname length (in chars) for WinNT. This should normally be +** UNICODE_STRING_MAX_CHARS. +*/ +#ifndef SQLITE_WINNT_MAX_PATH_CHARS +# define SQLITE_WINNT_MAX_PATH_CHARS (UNICODE_STRING_MAX_CHARS) +#endif + +/* +** Maximum pathname length (in bytes) for Win32. The MAX_PATH macro is in +** characters, so we allocate 4 bytes per character assuming worst-case of +** 4-bytes-per-character for UTF8. +*/ +#ifndef SQLITE_WIN32_MAX_PATH_BYTES +# define SQLITE_WIN32_MAX_PATH_BYTES (SQLITE_WIN32_MAX_PATH_CHARS*4) +#endif + +/* +** Maximum pathname length (in bytes) for WinNT. This should normally be +** UNICODE_STRING_MAX_CHARS * sizeof(WCHAR). +*/ +#ifndef SQLITE_WINNT_MAX_PATH_BYTES +# define SQLITE_WINNT_MAX_PATH_BYTES \ + (sizeof(WCHAR) * SQLITE_WINNT_MAX_PATH_CHARS) +#endif + +/* +** Maximum error message length (in chars) for WinRT. +*/ +#ifndef SQLITE_WIN32_MAX_ERRMSG_CHARS +# define SQLITE_WIN32_MAX_ERRMSG_CHARS (1024) +#endif + +/* +** Returns non-zero if the character should be treated as a directory +** separator. +*/ +#ifndef winIsDirSep +# define winIsDirSep(a) (((a) == '/') || ((a) == '\\')) +#endif + +/* +** This macro is used when a local variable is set to a value that is +** [sometimes] not used by the code (e.g. via conditional compilation). +*/ +#ifndef UNUSED_VARIABLE_VALUE +# define UNUSED_VARIABLE_VALUE(x) (void)(x) +#endif + +/* +** Returns the character that should be used as the directory separator. +*/ +#ifndef winGetDirSep +# define winGetDirSep() '\\' +#endif + +/* +** Do we need to manually define the Win32 file mapping APIs for use with WAL +** mode or memory mapped files (e.g. these APIs are available in the Windows +** CE SDK; however, they are not present in the header file)? +*/ +#if SQLITE_WIN32_FILEMAPPING_API && \ + (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) + +#if defined(SQLITE_WIN32_HAS_ANSI) +WINBASEAPI HANDLE WINAPI CreateFileMappingA(HANDLE, LPSECURITY_ATTRIBUTES, \ + DWORD, DWORD, DWORD, LPCSTR); +#endif /* defined(SQLITE_WIN32_HAS_ANSI) */ + +#if defined(SQLITE_WIN32_HAS_WIDE) +WINBASEAPI HANDLE WINAPI CreateFileMappingW(HANDLE, LPSECURITY_ATTRIBUTES, \ + DWORD, DWORD, DWORD, LPCWSTR); +#endif /* defined(SQLITE_WIN32_HAS_WIDE) */ + +WINBASEAPI LPVOID WINAPI MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, SIZE_T); + +/* +** These file mapping APIs are common to both Win32 and WinRT. +*/ + +WINBASEAPI BOOL WINAPI FlushViewOfFile(LPCVOID, SIZE_T); +WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID); +#endif /* SQLITE_WIN32_FILEMAPPING_API */ + +/* +** Some Microsoft compilers lack this definition. +*/ +#ifndef INVALID_FILE_ATTRIBUTES +# define INVALID_FILE_ATTRIBUTES ((DWORD)-1) +#endif + +#ifndef FILE_FLAG_MASK +# define FILE_FLAG_MASK (0xFF3C0000) +#endif + +#ifndef FILE_ATTRIBUTE_MASK +# define FILE_ATTRIBUTE_MASK (0x0003FFF7) +#endif + +#ifndef SQLITE_OMIT_WAL +/* Forward references to structures used for WAL */ +typedef struct winShm winShm; /* A connection to shared-memory */ +typedef struct winShmNode winShmNode; /* A region of shared-memory */ +#endif + +/* +** WinCE lacks native support for file locking so we have to fake it +** with some code of our own. +*/ +#if SQLITE_OS_WINCE +typedef struct winceLock { + int nReaders; /* Number of reader locks obtained */ + BOOL bPending; /* Indicates a pending lock has been obtained */ + BOOL bReserved; /* Indicates a reserved lock has been obtained */ + BOOL bExclusive; /* Indicates an exclusive lock has been obtained */ +} winceLock; +#endif + +/* +** The winFile structure is a subclass of sqlite3_file* specific to the win32 +** portability layer. +*/ +typedef struct winFile winFile; +struct winFile { + const sqlite3_io_methods *pMethod; /*** Must be first ***/ + sqlite3_vfs *pVfs; /* The VFS used to open this file */ + HANDLE h; /* Handle for accessing the file */ + u8 locktype; /* Type of lock currently held on this file */ + short sharedLockByte; /* Randomly chosen byte used as a shared lock */ + u8 ctrlFlags; /* Flags. See WINFILE_* below */ + DWORD lastErrno; /* The Windows errno from the last I/O error */ +#ifndef SQLITE_OMIT_WAL + winShm *pShm; /* Instance of shared memory on this file */ +#endif + const char *zPath; /* Full pathname of this file */ + int szChunk; /* Chunk size configured by FCNTL_CHUNK_SIZE */ +#if SQLITE_OS_WINCE + LPWSTR zDeleteOnClose; /* Name of file to delete when closing */ + HANDLE hMutex; /* Mutex used to control access to shared lock */ + HANDLE hShared; /* Shared memory segment used for locking */ + winceLock local; /* Locks obtained by this instance of winFile */ + winceLock *shared; /* Global shared lock memory for the file */ +#endif +#if SQLITE_MAX_MMAP_SIZE>0 + int nFetchOut; /* Number of outstanding xFetch references */ + HANDLE hMap; /* Handle for accessing memory mapping */ + void *pMapRegion; /* Area memory mapped */ + sqlite3_int64 mmapSize; /* Size of mapped region */ + sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */ +#endif +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + DWORD iBusyTimeout; /* Wait this many millisec on locks */ + int bBlockOnConnect; +#endif +}; + +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT +# define winFileBusyTimeout(pDbFd) pDbFd->iBusyTimeout +#else +# define winFileBusyTimeout(pDbFd) 0 +#endif + +/* +** The winVfsAppData structure is used for the pAppData member for all of the +** Win32 VFS variants. +*/ +typedef struct winVfsAppData winVfsAppData; +struct winVfsAppData { + const sqlite3_io_methods *pMethod; /* The file I/O methods to use. */ + void *pAppData; /* The extra pAppData, if any. */ + BOOL bNoLock; /* Non-zero if locking is disabled. */ +}; + +/* +** Allowed values for winFile.ctrlFlags +*/ +#define WINFILE_RDONLY 0x02 /* Connection is read only */ +#define WINFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ +#define WINFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ + +/* + * The size of the buffer used by sqlite3_win32_write_debug(). + */ +#ifndef SQLITE_WIN32_DBG_BUF_SIZE +# define SQLITE_WIN32_DBG_BUF_SIZE ((int)(4096-sizeof(DWORD))) +#endif + +/* + * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the + * various Win32 API heap functions instead of our own. + */ +#ifdef SQLITE_WIN32_MALLOC + +/* + * If this is non-zero, an isolated heap will be created by the native Win32 + * allocator subsystem; otherwise, the default process heap will be used. This + * setting has no effect when compiling for WinRT. By default, this is enabled + * and an isolated heap will be created to store all allocated data. + * + ****************************************************************************** + * WARNING: It is important to note that when this setting is non-zero and the + * winMemShutdown function is called (e.g. by the sqlite3_shutdown + * function), all data that was allocated using the isolated heap will + * be freed immediately and any attempt to access any of that freed + * data will almost certainly result in an immediate access violation. + ****************************************************************************** + */ +#ifndef SQLITE_WIN32_HEAP_CREATE +# define SQLITE_WIN32_HEAP_CREATE (TRUE) +#endif + +/* + * This is the maximum possible initial size of the Win32-specific heap, in + * bytes. + */ +#ifndef SQLITE_WIN32_HEAP_MAX_INIT_SIZE +# define SQLITE_WIN32_HEAP_MAX_INIT_SIZE (4294967295U) +#endif + +/* + * This is the extra space for the initial size of the Win32-specific heap, + * in bytes. This value may be zero. + */ +#ifndef SQLITE_WIN32_HEAP_INIT_EXTRA +# define SQLITE_WIN32_HEAP_INIT_EXTRA (4194304) +#endif + +/* + * Calculate the maximum legal cache size, in pages, based on the maximum + * possible initial heap size and the default page size, setting aside the + * needed extra space. + */ +#ifndef SQLITE_WIN32_MAX_CACHE_SIZE +# define SQLITE_WIN32_MAX_CACHE_SIZE (((SQLITE_WIN32_HEAP_MAX_INIT_SIZE) - \ + (SQLITE_WIN32_HEAP_INIT_EXTRA)) / \ + (SQLITE_DEFAULT_PAGE_SIZE)) +#endif + +/* + * This is cache size used in the calculation of the initial size of the + * Win32-specific heap. It cannot be negative. + */ +#ifndef SQLITE_WIN32_CACHE_SIZE +# if SQLITE_DEFAULT_CACHE_SIZE>=0 +# define SQLITE_WIN32_CACHE_SIZE (SQLITE_DEFAULT_CACHE_SIZE) +# else +# define SQLITE_WIN32_CACHE_SIZE (-(SQLITE_DEFAULT_CACHE_SIZE)) +# endif +#endif + +/* + * Make sure that the calculated cache size, in pages, cannot cause the + * initial size of the Win32-specific heap to exceed the maximum amount + * of memory that can be specified in the call to HeapCreate. + */ +#if SQLITE_WIN32_CACHE_SIZE>SQLITE_WIN32_MAX_CACHE_SIZE +# undef SQLITE_WIN32_CACHE_SIZE +# define SQLITE_WIN32_CACHE_SIZE (2000) +#endif + +/* + * The initial size of the Win32-specific heap. This value may be zero. + */ +#ifndef SQLITE_WIN32_HEAP_INIT_SIZE +# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_WIN32_CACHE_SIZE) * \ + (SQLITE_DEFAULT_PAGE_SIZE) + \ + (SQLITE_WIN32_HEAP_INIT_EXTRA)) +#endif + +/* + * The maximum size of the Win32-specific heap. This value may be zero. + */ +#ifndef SQLITE_WIN32_HEAP_MAX_SIZE +# define SQLITE_WIN32_HEAP_MAX_SIZE (0) +#endif + +/* + * The extra flags to use in calls to the Win32 heap APIs. This value may be + * zero for the default behavior. + */ +#ifndef SQLITE_WIN32_HEAP_FLAGS +# define SQLITE_WIN32_HEAP_FLAGS (0) +#endif + + +/* +** The winMemData structure stores information required by the Win32-specific +** sqlite3_mem_methods implementation. +*/ +typedef struct winMemData winMemData; +struct winMemData { +#ifndef NDEBUG + u32 magic1; /* Magic number to detect structure corruption. */ +#endif + HANDLE hHeap; /* The handle to our heap. */ + BOOL bOwned; /* Do we own the heap (i.e. destroy it on shutdown)? */ +#ifndef NDEBUG + u32 magic2; /* Magic number to detect structure corruption. */ +#endif +}; + +#ifndef NDEBUG +#define WINMEM_MAGIC1 0x42b2830b +#define WINMEM_MAGIC2 0xbd4d7cf4 +#endif + +static struct winMemData win_mem_data = { +#ifndef NDEBUG + WINMEM_MAGIC1, +#endif + NULL, FALSE +#ifndef NDEBUG + ,WINMEM_MAGIC2 +#endif +}; + +#ifndef NDEBUG +#define winMemAssertMagic1() assert( win_mem_data.magic1==WINMEM_MAGIC1 ) +#define winMemAssertMagic2() assert( win_mem_data.magic2==WINMEM_MAGIC2 ) +#define winMemAssertMagic() winMemAssertMagic1(); winMemAssertMagic2(); +#else +#define winMemAssertMagic() +#endif + +#define winMemGetDataPtr() &win_mem_data +#define winMemGetHeap() win_mem_data.hHeap +#define winMemGetOwned() win_mem_data.bOwned + +static void *winMemMalloc(int nBytes); +static void winMemFree(void *pPrior); +static void *winMemRealloc(void *pPrior, int nBytes); +static int winMemSize(void *p); +static int winMemRoundup(int n); +static int winMemInit(void *pAppData); +static void winMemShutdown(void *pAppData); + +SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetWin32(void); +#endif /* SQLITE_WIN32_MALLOC */ + +/* +** The following variable is (normally) set once and never changes +** thereafter. It records whether the operating system is Win9x +** or WinNT. +** +** 0: Operating system unknown. +** 1: Operating system is Win9x. +** 2: Operating system is WinNT. +** +** In order to facilitate testing on a WinNT system, the test fixture +** can manually set this value to 1 to emulate Win98 behavior. +*/ +#ifdef SQLITE_TEST +SQLITE_API LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0; +#else +static LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0; +#endif + +#ifndef SYSCALL +# define SYSCALL sqlite3_syscall_ptr +#endif + +/* +** This function is not available on Windows CE or WinRT. + */ + +#if SQLITE_OS_WINCE +# define osAreFileApisANSI() 1 +#endif + +/* +** Many system calls are accessed through pointer-to-functions so that +** they may be overridden at runtime to facilitate fault injection during +** testing and sandboxing. The following array holds the names and pointers +** to all overrideable system calls. +*/ +static struct win_syscall { + const char *zName; /* Name of the system call */ + sqlite3_syscall_ptr pCurrent; /* Current value of the system call */ + sqlite3_syscall_ptr pDefault; /* Default value */ +} aSyscall[] = { +#if !SQLITE_OS_WINCE + { "AreFileApisANSI", (SYSCALL)AreFileApisANSI, 0 }, +#else + { "AreFileApisANSI", (SYSCALL)0, 0 }, +#endif + +#ifndef osAreFileApisANSI +#define osAreFileApisANSI ((BOOL(WINAPI*)(VOID))aSyscall[0].pCurrent) +#endif + +#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) + { "CharLowerW", (SYSCALL)CharLowerW, 0 }, +#else + { "CharLowerW", (SYSCALL)0, 0 }, +#endif + +#define osCharLowerW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[1].pCurrent) + +#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) + { "CharUpperW", (SYSCALL)CharUpperW, 0 }, +#else + { "CharUpperW", (SYSCALL)0, 0 }, +#endif + +#define osCharUpperW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[2].pCurrent) + + { "CloseHandle", (SYSCALL)CloseHandle, 0 }, + +#define osCloseHandle ((BOOL(WINAPI*)(HANDLE))aSyscall[3].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "CreateFileA", (SYSCALL)CreateFileA, 0 }, +#else + { "CreateFileA", (SYSCALL)0, 0 }, +#endif + +#define osCreateFileA ((HANDLE(WINAPI*)(LPCSTR,DWORD,DWORD, \ + LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[4].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "CreateFileW", (SYSCALL)CreateFileW, 0 }, +#else + { "CreateFileW", (SYSCALL)0, 0 }, +#endif + +#define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \ + LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) && \ + (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) && \ + SQLITE_WIN32_CREATEFILEMAPPINGA + { "CreateFileMappingA", (SYSCALL)CreateFileMappingA, 0 }, +#else + { "CreateFileMappingA", (SYSCALL)0, 0 }, +#endif + +#define osCreateFileMappingA ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \ + DWORD,DWORD,DWORD,LPCSTR))aSyscall[6].pCurrent) + +#if (SQLITE_OS_WINCE || defined(SQLITE_WIN32_HAS_WIDE)) && \ + (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) + { "CreateFileMappingW", (SYSCALL)CreateFileMappingW, 0 }, +#else + { "CreateFileMappingW", (SYSCALL)0, 0 }, +#endif + +#define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \ + DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "CreateMutexW", (SYSCALL)CreateMutexW, 0 }, +#else + { "CreateMutexW", (SYSCALL)0, 0 }, +#endif + +#define osCreateMutexW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,BOOL, \ + LPCWSTR))aSyscall[8].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "DeleteFileA", (SYSCALL)DeleteFileA, 0 }, +#else + { "DeleteFileA", (SYSCALL)0, 0 }, +#endif + +#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[9].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "DeleteFileW", (SYSCALL)DeleteFileW, 0 }, +#else + { "DeleteFileW", (SYSCALL)0, 0 }, +#endif + +#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[10].pCurrent) + +#if SQLITE_OS_WINCE + { "FileTimeToLocalFileTime", (SYSCALL)FileTimeToLocalFileTime, 0 }, +#else + { "FileTimeToLocalFileTime", (SYSCALL)0, 0 }, +#endif + +#define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(const FILETIME*, \ + LPFILETIME))aSyscall[11].pCurrent) + +#if SQLITE_OS_WINCE + { "FileTimeToSystemTime", (SYSCALL)FileTimeToSystemTime, 0 }, +#else + { "FileTimeToSystemTime", (SYSCALL)0, 0 }, +#endif + +#define osFileTimeToSystemTime ((BOOL(WINAPI*)(const FILETIME*, \ + LPSYSTEMTIME))aSyscall[12].pCurrent) + + { "FlushFileBuffers", (SYSCALL)FlushFileBuffers, 0 }, + +#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[13].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "FormatMessageA", (SYSCALL)FormatMessageA, 0 }, +#else + { "FormatMessageA", (SYSCALL)0, 0 }, +#endif + +#define osFormatMessageA ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPSTR, \ + DWORD,va_list*))aSyscall[14].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "FormatMessageW", (SYSCALL)FormatMessageW, 0 }, +#else + { "FormatMessageW", (SYSCALL)0, 0 }, +#endif + +#define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \ + DWORD,va_list*))aSyscall[15].pCurrent) + +#if !defined(SQLITE_OMIT_LOAD_EXTENSION) + { "FreeLibrary", (SYSCALL)FreeLibrary, 0 }, +#else + { "FreeLibrary", (SYSCALL)0, 0 }, +#endif + +#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[16].pCurrent) + + { "GetCurrentProcessId", (SYSCALL)GetCurrentProcessId, 0 }, + +#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[17].pCurrent) + +#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI) + { "GetDiskFreeSpaceA", (SYSCALL)GetDiskFreeSpaceA, 0 }, +#else + { "GetDiskFreeSpaceA", (SYSCALL)0, 0 }, +#endif + +#define osGetDiskFreeSpaceA ((BOOL(WINAPI*)(LPCSTR,LPDWORD,LPDWORD,LPDWORD, \ + LPDWORD))aSyscall[18].pCurrent) + +#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) + { "GetDiskFreeSpaceW", (SYSCALL)GetDiskFreeSpaceW, 0 }, +#else + { "GetDiskFreeSpaceW", (SYSCALL)0, 0 }, +#endif + +#define osGetDiskFreeSpaceW ((BOOL(WINAPI*)(LPCWSTR,LPDWORD,LPDWORD,LPDWORD, \ + LPDWORD))aSyscall[19].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "GetFileAttributesA", (SYSCALL)GetFileAttributesA, 0 }, +#else + { "GetFileAttributesA", (SYSCALL)0, 0 }, +#endif + +#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[20].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "GetFileAttributesW", (SYSCALL)GetFileAttributesW, 0 }, +#else + { "GetFileAttributesW", (SYSCALL)0, 0 }, +#endif + +#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[21].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "GetFileAttributesExW", (SYSCALL)GetFileAttributesExW, 0 }, +#else + { "GetFileAttributesExW", (SYSCALL)0, 0 }, +#endif + +#define osGetFileAttributesExW ((BOOL(WINAPI*)(LPCWSTR,GET_FILEEX_INFO_LEVELS, \ + LPVOID))aSyscall[22].pCurrent) + + { "GetFileSize", (SYSCALL)GetFileSize, 0 }, + +#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[23].pCurrent) + +#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI) + { "GetFullPathNameA", (SYSCALL)GetFullPathNameA, 0 }, +#else + { "GetFullPathNameA", (SYSCALL)0, 0 }, +#endif + +#define osGetFullPathNameA ((DWORD(WINAPI*)(LPCSTR,DWORD,LPSTR, \ + LPSTR*))aSyscall[24].pCurrent) + +#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE) + { "GetFullPathNameW", (SYSCALL)GetFullPathNameW, 0 }, +#else + { "GetFullPathNameW", (SYSCALL)0, 0 }, +#endif + +#define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \ + LPWSTR*))aSyscall[25].pCurrent) + +/* +** For GetLastError(), MSDN says: +** +** Minimum supported client: Windows XP [desktop apps | UWP apps] +** Minimum supported server: Windows Server 2003 [desktop apps | UWP apps] +*/ + { "GetLastError", (SYSCALL)GetLastError, 0 }, + +#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent) + +#if !defined(SQLITE_OMIT_LOAD_EXTENSION) +#if SQLITE_OS_WINCE + /* The GetProcAddressA() routine is only available on Windows CE. */ + { "GetProcAddressA", (SYSCALL)GetProcAddressA, 0 }, +#else + /* All other Windows platforms expect GetProcAddress() to take + ** an ANSI string regardless of the _UNICODE setting */ + { "GetProcAddressA", (SYSCALL)GetProcAddress, 0 }, +#endif +#else + { "GetProcAddressA", (SYSCALL)0, 0 }, +#endif + +#define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \ + LPCSTR))aSyscall[27].pCurrent) + + { "GetSystemInfo", (SYSCALL)GetSystemInfo, 0 }, +#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[28].pCurrent) + + { "GetSystemTime", (SYSCALL)GetSystemTime, 0 }, +#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[29].pCurrent) + +#if !SQLITE_OS_WINCE + { "GetSystemTimeAsFileTime", (SYSCALL)GetSystemTimeAsFileTime, 0 }, +#else + { "GetSystemTimeAsFileTime", (SYSCALL)0, 0 }, +#endif + +#define osGetSystemTimeAsFileTime ((VOID(WINAPI*)( \ + LPFILETIME))aSyscall[30].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "GetTempPathA", (SYSCALL)GetTempPathA, 0 }, +#else + { "GetTempPathA", (SYSCALL)0, 0 }, +#endif + +#define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[31].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "GetTempPathW", (SYSCALL)GetTempPathW, 0 }, +#else + { "GetTempPathW", (SYSCALL)0, 0 }, +#endif + +#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[32].pCurrent) + + { "GetTickCount", (SYSCALL)GetTickCount, 0 }, + +#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_GETVERSIONEX + { "GetVersionExA", (SYSCALL)GetVersionExA, 0 }, +#else + { "GetVersionExA", (SYSCALL)0, 0 }, +#endif + +#define osGetVersionExA ((BOOL(WINAPI*)( \ + LPOSVERSIONINFOA))aSyscall[34].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) && \ + SQLITE_WIN32_GETVERSIONEX + { "GetVersionExW", (SYSCALL)GetVersionExW, 0 }, +#else + { "GetVersionExW", (SYSCALL)0, 0 }, +#endif + +#define osGetVersionExW ((BOOL(WINAPI*)( \ + LPOSVERSIONINFOW))aSyscall[35].pCurrent) + + { "HeapAlloc", (SYSCALL)HeapAlloc, 0 }, + +#define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \ + SIZE_T))aSyscall[36].pCurrent) + + { "HeapCreate", (SYSCALL)HeapCreate, 0 }, + +#define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \ + SIZE_T))aSyscall[37].pCurrent) + + { "HeapDestroy", (SYSCALL)HeapDestroy, 0 }, + +#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[38].pCurrent) + + { "HeapFree", (SYSCALL)HeapFree, 0 }, + +#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[39].pCurrent) + + { "HeapReAlloc", (SYSCALL)HeapReAlloc, 0 }, + +#define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \ + SIZE_T))aSyscall[40].pCurrent) + + { "HeapSize", (SYSCALL)HeapSize, 0 }, + +#define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \ + LPCVOID))aSyscall[41].pCurrent) + + { "HeapValidate", (SYSCALL)HeapValidate, 0 }, + +#define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \ + LPCVOID))aSyscall[42].pCurrent) + +#if !SQLITE_OS_WINCE + { "HeapCompact", (SYSCALL)HeapCompact, 0 }, +#else + { "HeapCompact", (SYSCALL)0, 0 }, +#endif + +#define osHeapCompact ((UINT(WINAPI*)(HANDLE,DWORD))aSyscall[43].pCurrent) + +#if defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_OMIT_LOAD_EXTENSION) + { "LoadLibraryA", (SYSCALL)LoadLibraryA, 0 }, +#else + { "LoadLibraryA", (SYSCALL)0, 0 }, +#endif + +#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[44].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) && \ + !defined(SQLITE_OMIT_LOAD_EXTENSION) + { "LoadLibraryW", (SYSCALL)LoadLibraryW, 0 }, +#else + { "LoadLibraryW", (SYSCALL)0, 0 }, +#endif + +#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[45].pCurrent) + + { "LocalFree", (SYSCALL)LocalFree, 0 }, + +#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[46].pCurrent) + +#if !SQLITE_OS_WINCE + { "LockFile", (SYSCALL)LockFile, 0 }, +#else + { "LockFile", (SYSCALL)0, 0 }, +#endif + +#if !defined(osLockFile) && defined(SQLITE_WIN32_HAS_ANSI) +#define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ + DWORD))aSyscall[47].pCurrent) +#endif + +#if !SQLITE_OS_WINCE + { "LockFileEx", (SYSCALL)LockFileEx, 0 }, +#else + { "LockFileEx", (SYSCALL)0, 0 }, +#endif + +#ifndef osLockFileEx +#define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \ + LPOVERLAPPED))aSyscall[48].pCurrent) +#endif + +#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 + { "MapViewOfFile", (SYSCALL)MapViewOfFile, 0 }, +#else + { "MapViewOfFile", (SYSCALL)0, 0 }, +#endif + +#define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ + SIZE_T))aSyscall[49].pCurrent) + + { "MultiByteToWideChar", (SYSCALL)MultiByteToWideChar, 0 }, + +#define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \ + int))aSyscall[50].pCurrent) + + { "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 }, + +#define osQueryPerformanceCounter ((BOOL(WINAPI*)( \ + LARGE_INTEGER*))aSyscall[51].pCurrent) + + { "ReadFile", (SYSCALL)ReadFile, 0 }, + +#define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \ + LPOVERLAPPED))aSyscall[52].pCurrent) + + { "SetEndOfFile", (SYSCALL)SetEndOfFile, 0 }, + +#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[53].pCurrent) + + { "SetFilePointer", (SYSCALL)SetFilePointer, 0 }, + +#define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \ + DWORD))aSyscall[54].pCurrent) + + { "Sleep", (SYSCALL)Sleep, 0 }, + +#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[55].pCurrent) + + { "SystemTimeToFileTime", (SYSCALL)SystemTimeToFileTime, 0 }, + +#define osSystemTimeToFileTime ((BOOL(WINAPI*)(const SYSTEMTIME*, \ + LPFILETIME))aSyscall[56].pCurrent) + +#if !SQLITE_OS_WINCE + { "UnlockFile", (SYSCALL)UnlockFile, 0 }, +#else + { "UnlockFile", (SYSCALL)0, 0 }, +#endif + +#if !defined(osUnlockFile) && defined(SQLITE_WIN32_HAS_ANSI) +#define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ + DWORD))aSyscall[57].pCurrent) +#endif + +#if !SQLITE_OS_WINCE + { "UnlockFileEx", (SYSCALL)UnlockFileEx, 0 }, +#else + { "UnlockFileEx", (SYSCALL)0, 0 }, +#endif + +#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ + LPOVERLAPPED))aSyscall[58].pCurrent) + +#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 + { "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 }, +#else + { "UnmapViewOfFile", (SYSCALL)0, 0 }, +#endif + +#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[59].pCurrent) + + { "WideCharToMultiByte", (SYSCALL)WideCharToMultiByte, 0 }, + +#define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \ + LPCSTR,LPBOOL))aSyscall[60].pCurrent) + + { "WriteFile", (SYSCALL)WriteFile, 0 }, + +#define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \ + LPOVERLAPPED))aSyscall[61].pCurrent) + +/* +** For WaitForSingleObject(), MSDN says: +** +** Minimum supported client: Windows XP [desktop apps | UWP apps] +** Minimum supported server: Windows Server 2003 [desktop apps | UWP apps] +*/ + { "WaitForSingleObject", (SYSCALL)WaitForSingleObject, 0 }, + +#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \ + DWORD))aSyscall[62].pCurrent) + +#if !SQLITE_OS_WINCE + { "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 }, +#else + { "WaitForSingleObjectEx", (SYSCALL)0, 0 }, +#endif + +#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \ + BOOL))aSyscall[63].pCurrent) + + { "GetNativeSystemInfo", (SYSCALL)0, 0 }, + /* ^^^^^^^^^^^^^^^^^^^----------------^------- placeholder only */ + +#if defined(SQLITE_WIN32_HAS_ANSI) + { "OutputDebugStringA", (SYSCALL)OutputDebugStringA, 0 }, +#else + { "OutputDebugStringA", (SYSCALL)0, 0 }, +#endif + +#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[65].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) + { "OutputDebugStringW", (SYSCALL)OutputDebugStringW, 0 }, +#else + { "OutputDebugStringW", (SYSCALL)0, 0 }, +#endif + +#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[66].pCurrent) + + { "GetProcessHeap", (SYSCALL)GetProcessHeap, 0 }, + +#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[67].pCurrent) + +/* +** NOTE: On some sub-platforms, the InterlockedCompareExchange "function" +** is really just a macro that uses a compiler intrinsic (e.g. x64). +** So do not try to make this is into a redefinable interface. +*/ +#if defined(InterlockedCompareExchange) + { "InterlockedCompareExchange", (SYSCALL)0, 0 }, + +#define osInterlockedCompareExchange InterlockedCompareExchange +#else + { "InterlockedCompareExchange", (SYSCALL)InterlockedCompareExchange, 0 }, + +#define osInterlockedCompareExchange ((LONG(WINAPI*)(LONG \ + SQLITE_WIN32_VOLATILE*, LONG,LONG))aSyscall[68].pCurrent) +#endif /* defined(InterlockedCompareExchange) */ + +#if !SQLITE_OS_WINCE && SQLITE_WIN32_USE_UUID + { "UuidCreate", (SYSCALL)UuidCreate, 0 }, +#else + { "UuidCreate", (SYSCALL)0, 0 }, +#endif + +#define osUuidCreate ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[69].pCurrent) + +#if !SQLITE_OS_WINCE && SQLITE_WIN32_USE_UUID + { "UuidCreateSequential", (SYSCALL)UuidCreateSequential, 0 }, +#else + { "UuidCreateSequential", (SYSCALL)0, 0 }, +#endif + +#define osUuidCreateSequential \ + ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[70].pCurrent) + +#if !defined(SQLITE_NO_SYNC) && SQLITE_MAX_MMAP_SIZE>0 + { "FlushViewOfFile", (SYSCALL)FlushViewOfFile, 0 }, +#else + { "FlushViewOfFile", (SYSCALL)0, 0 }, +#endif + +#define osFlushViewOfFile \ + ((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[71].pCurrent) + +/* +** If SQLITE_ENABLE_SETLK_TIMEOUT is defined, we require CreateEvent() +** to implement blocking locks with timeouts. MSDN says: +** +** Minimum supported client: Windows XP [desktop apps | UWP apps] +** Minimum supported server: Windows Server 2003 [desktop apps | UWP apps] +*/ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + { "CreateEvent", (SYSCALL)CreateEvent, 0 }, +#else + { "CreateEvent", (SYSCALL)0, 0 }, +#endif + +#define osCreateEvent ( \ + (HANDLE(WINAPI*) (LPSECURITY_ATTRIBUTES,BOOL,BOOL,LPCSTR)) \ + aSyscall[72].pCurrent \ +) + +/* +** If SQLITE_ENABLE_SETLK_TIMEOUT is defined, we require CancelIo() +** for the case where a timeout expires and a lock request must be +** cancelled. +** +** Minimum supported client: Windows XP [desktop apps | UWP apps] +** Minimum supported server: Windows Server 2003 [desktop apps | UWP apps] +*/ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + { "CancelIo", (SYSCALL)CancelIo, 0 }, +#else + { "CancelIo", (SYSCALL)0, 0 }, +#endif + +#define osCancelIo ((BOOL(WINAPI*)(HANDLE))aSyscall[73].pCurrent) + +#if defined(SQLITE_WIN32_HAS_WIDE) && defined(_WIN32) + { "GetModuleHandleW", (SYSCALL)GetModuleHandleW, 0 }, +#else + { "GetModuleHandleW", (SYSCALL)0, 0 }, +#endif + +#define osGetModuleHandleW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[74].pCurrent) + +#ifndef _WIN32 + { "getenv", (SYSCALL)getenv, 0 }, +#else + { "getenv", (SYSCALL)0, 0 }, +#endif + +#define osGetenv ((const char *(*)(const char *))aSyscall[75].pCurrent) + +#ifndef _WIN32 + { "getcwd", (SYSCALL)getcwd, 0 }, +#else + { "getcwd", (SYSCALL)0, 0 }, +#endif + +#define osGetcwd ((char*(*)(char*,size_t))aSyscall[76].pCurrent) + +#ifndef _WIN32 + { "readlink", (SYSCALL)readlink, 0 }, +#else + { "readlink", (SYSCALL)0, 0 }, +#endif + +#define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[77].pCurrent) + +#ifndef _WIN32 + { "lstat", (SYSCALL)lstat, 0 }, +#else + { "lstat", (SYSCALL)0, 0 }, +#endif + +#define osLstat ((int(*)(const char*,struct stat*))aSyscall[78].pCurrent) + +#ifndef _WIN32 + { "__errno", (SYSCALL)__errno, 0 }, +#else + { "__errno", (SYSCALL)0, 0 }, +#endif + +#define osErrno (*((int*(*)(void))aSyscall[79].pCurrent)()) + +#ifndef _WIN32 + { "cygwin_conv_path", (SYSCALL)cygwin_conv_path, 0 }, +#else + { "cygwin_conv_path", (SYSCALL)0, 0 }, +#endif + +#define osCygwin_conv_path ((size_t(*)(unsigned int, \ + const void *, void *, size_t))aSyscall[80].pCurrent) + +}; /* End of the overrideable system calls */ + +/* +** This is the xSetSystemCall() method of sqlite3_vfs for all of the +** "win32" VFSes. Return SQLITE_OK upon successfully updating the +** system call pointer, or SQLITE_NOTFOUND if there is no configurable +** system call named zName. +*/ +static int winSetSystemCall( + sqlite3_vfs *pNotUsed, /* The VFS pointer. Not used */ + const char *zName, /* Name of system call to override */ + sqlite3_syscall_ptr pNewFunc /* Pointer to new system call value */ +){ + unsigned int i; + int rc = SQLITE_NOTFOUND; + + UNUSED_PARAMETER(pNotUsed); + if( zName==0 ){ + /* If no zName is given, restore all system calls to their default + ** settings and return NULL + */ + rc = SQLITE_OK; + for(i=0; i0 ){ + memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE); + memcpy(zDbgBuf, zBuf, nMin); + osOutputDebugStringA(zDbgBuf); + }else{ + osOutputDebugStringA(zBuf); + } +#elif defined(SQLITE_WIN32_HAS_WIDE) + memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE); + if ( osMultiByteToWideChar( + osAreFileApisANSI() ? CP_ACP : CP_OEMCP, 0, zBuf, + nMin, (LPWSTR)zDbgBuf, SQLITE_WIN32_DBG_BUF_SIZE/sizeof(WCHAR))<=0 ){ + return; + } + osOutputDebugStringW((LPCWSTR)zDbgBuf); +#else + if( nMin>0 ){ + memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE); + memcpy(zDbgBuf, zBuf, nMin); + fprintf(stderr, "%s", zDbgBuf); + }else{ + fprintf(stderr, "%s", zBuf); + } +#endif +} +#endif /* _WIN32 */ + +SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds){ + osSleep(milliseconds); +} + +#if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINCE && \ + SQLITE_THREADSAFE>0 +SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){ + DWORD rc; + while( (rc = osWaitForSingleObjectEx(hObject, INFINITE, + TRUE))==WAIT_IO_COMPLETION ){} + return rc; +} +#endif + +/* +** Return true (non-zero) if we are running under WinNT, Win2K, WinXP, +** or WinCE. Return false (zero) for Win95, Win98, or WinME. +** +** Here is an interesting observation: Win95, Win98, and WinME lack +** the LockFileEx() API. But we can still statically link against that +** API as long as we don't call it when running Win95/98/ME. A call to +** this routine is used to determine if the host is Win95/98/ME or +** WinNT/2K/XP so that we will know whether or not we can safely call +** the LockFileEx() API. +*/ + +#if !SQLITE_WIN32_GETVERSIONEX +# define osIsNT() (1) +#elif SQLITE_OS_WINCE || !defined(SQLITE_WIN32_HAS_ANSI) +# define osIsNT() (1) +#elif !defined(SQLITE_WIN32_HAS_WIDE) +# define osIsNT() (0) +#else +# define osIsNT() ((sqlite3_os_type==2) || sqlite3_win32_is_nt()) +#endif + +/* +** This function determines if the machine is running a version of Windows +** based on the NT kernel. +*/ +SQLITE_API int sqlite3_win32_is_nt(void){ +#if SQLITE_WIN32_GETVERSIONEX + if( osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ){ +#if defined(SQLITE_WIN32_HAS_ANSI) + OSVERSIONINFOA sInfo; + sInfo.dwOSVersionInfoSize = sizeof(sInfo); + osGetVersionExA(&sInfo); + osInterlockedCompareExchange(&sqlite3_os_type, + (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0); +#elif defined(SQLITE_WIN32_HAS_WIDE) + OSVERSIONINFOW sInfo; + sInfo.dwOSVersionInfoSize = sizeof(sInfo); + osGetVersionExW(&sInfo); + osInterlockedCompareExchange(&sqlite3_os_type, + (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0); +#endif + } + return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2; +#elif SQLITE_TEST + return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2 + || osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 + ; +#else + /* + ** NOTE: All sub-platforms where the GetVersionEx[AW] functions are + ** deprecated are always assumed to be based on the NT kernel. + */ + return 1; +#endif +} + +#ifdef SQLITE_WIN32_MALLOC +/* +** Allocate nBytes of memory. +*/ +static void *winMemMalloc(int nBytes){ + HANDLE hHeap; + void *p; + + winMemAssertMagic(); + hHeap = winMemGetHeap(); + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +#if defined(SQLITE_WIN32_MALLOC_VALIDATE) + assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); +#endif + assert( nBytes>=0 ); + p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes); + if( !p ){ + sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%lu), heap=%p", + nBytes, osGetLastError(), (void*)hHeap); + } + return p; +} + +/* +** Free memory. +*/ +static void winMemFree(void *pPrior){ + HANDLE hHeap; + + winMemAssertMagic(); + hHeap = winMemGetHeap(); + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +#if defined(SQLITE_WIN32_MALLOC_VALIDATE) + assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ); +#endif + if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */ + if( !osHeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){ + sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%lu), heap=%p", + pPrior, osGetLastError(), (void*)hHeap); + } +} + +/* +** Change the size of an existing memory allocation +*/ +static void *winMemRealloc(void *pPrior, int nBytes){ + HANDLE hHeap; + void *p; + + winMemAssertMagic(); + hHeap = winMemGetHeap(); + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +#if defined(SQLITE_WIN32_MALLOC_VALIDATE) + assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ); +#endif + assert( nBytes>=0 ); + if( !pPrior ){ + p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes); + }else{ + p = osHeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes); + } + if( !p ){ + sqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%lu), heap=%p", + pPrior ? "HeapReAlloc" : "HeapAlloc", nBytes, osGetLastError(), + (void*)hHeap); + } + return p; +} + +/* +** Return the size of an outstanding allocation, in bytes. +*/ +static int winMemSize(void *p){ + HANDLE hHeap; + SIZE_T n; + + winMemAssertMagic(); + hHeap = winMemGetHeap(); + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +#if defined(SQLITE_WIN32_MALLOC_VALIDATE) + assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, p) ); +#endif + if( !p ) return 0; + n = osHeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p); + if( n==(SIZE_T)-1 ){ + sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%lu), heap=%p", + p, osGetLastError(), (void*)hHeap); + return 0; + } + return (int)n; +} + +/* +** Round up a request size to the next valid allocation size. +*/ +static int winMemRoundup(int n){ + return n; +} + +/* +** Initialize this module. +*/ +static int winMemInit(void *pAppData){ + winMemData *pWinMemData = (winMemData *)pAppData; + + if( !pWinMemData ) return SQLITE_ERROR; + assert( pWinMemData->magic1==WINMEM_MAGIC1 ); + assert( pWinMemData->magic2==WINMEM_MAGIC2 ); + +#if SQLITE_WIN32_HEAP_CREATE + if( !pWinMemData->hHeap ){ + DWORD dwInitialSize = SQLITE_WIN32_HEAP_INIT_SIZE; + DWORD dwMaximumSize = (DWORD)sqlite3GlobalConfig.nHeap; + if( dwMaximumSize==0 ){ + dwMaximumSize = SQLITE_WIN32_HEAP_MAX_SIZE; + }else if( dwInitialSize>dwMaximumSize ){ + dwInitialSize = dwMaximumSize; + } + pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS, + dwInitialSize, dwMaximumSize); + if( !pWinMemData->hHeap ){ + sqlite3_log(SQLITE_NOMEM, + "failed to HeapCreate (%lu), flags=%u, initSize=%lu, maxSize=%lu", + osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, dwInitialSize, + dwMaximumSize); + return SQLITE_NOMEM_BKPT; + } + pWinMemData->bOwned = TRUE; + assert( pWinMemData->bOwned ); + } +#else + pWinMemData->hHeap = osGetProcessHeap(); + if( !pWinMemData->hHeap ){ + sqlite3_log(SQLITE_NOMEM, + "failed to GetProcessHeap (%lu)", osGetLastError()); + return SQLITE_NOMEM_BKPT; + } + pWinMemData->bOwned = FALSE; + assert( !pWinMemData->bOwned ); +#endif + assert( pWinMemData->hHeap!=0 ); + assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE ); +#if defined(SQLITE_WIN32_MALLOC_VALIDATE) + assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); +#endif + return SQLITE_OK; +} + +/* +** Deinitialize this module. +*/ +static void winMemShutdown(void *pAppData){ + winMemData *pWinMemData = (winMemData *)pAppData; + + if( !pWinMemData ) return; + assert( pWinMemData->magic1==WINMEM_MAGIC1 ); + assert( pWinMemData->magic2==WINMEM_MAGIC2 ); + + if( pWinMemData->hHeap ){ + assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE ); +#if defined(SQLITE_WIN32_MALLOC_VALIDATE) + assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) ); +#endif + if( pWinMemData->bOwned ){ + if( !osHeapDestroy(pWinMemData->hHeap) ){ + sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%lu), heap=%p", + osGetLastError(), (void*)pWinMemData->hHeap); + } + pWinMemData->bOwned = FALSE; + } + pWinMemData->hHeap = NULL; + } +} + +/* +** Populate the low-level memory allocation function pointers in +** sqlite3GlobalConfig.m with pointers to the routines in this file. The +** arguments specify the block of memory to manage. +** +** This routine is only called by sqlite3_config(), and therefore +** is not required to be threadsafe (it is not). +*/ +SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetWin32(void){ + static const sqlite3_mem_methods winMemMethods = { + winMemMalloc, + winMemFree, + winMemRealloc, + winMemSize, + winMemRoundup, + winMemInit, + winMemShutdown, + &win_mem_data + }; + return &winMemMethods; +} + +SQLITE_PRIVATE void sqlite3MemSetDefault(void){ + sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetWin32()); +} +#endif /* SQLITE_WIN32_MALLOC */ + +#ifdef _WIN32 +/* +** Convert a UTF-8 string to Microsoft Unicode. +** +** Space to hold the returned string is obtained from sqlite3_malloc(). +*/ +static LPWSTR winUtf8ToUnicode(const char *zText){ + int nChar; + LPWSTR zWideText; + + nChar = osMultiByteToWideChar(CP_UTF8, 0, zText, -1, NULL, 0); + if( nChar==0 ){ + return 0; + } + zWideText = sqlite3MallocZero( nChar*sizeof(WCHAR) ); + if( zWideText==0 ){ + return 0; + } + nChar = osMultiByteToWideChar(CP_UTF8, 0, zText, -1, zWideText, + nChar); + if( nChar==0 ){ + sqlite3_free(zWideText); + zWideText = 0; + } + return zWideText; +} +#endif /* _WIN32 */ + +/* +** Convert a Microsoft Unicode string to UTF-8. +** +** Space to hold the returned string is obtained from sqlite3_malloc(). +*/ +static char *winUnicodeToUtf8(LPCWSTR zWideText){ + int nByte; + char *zText; + + nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideText, -1, 0, 0, 0, 0); + if( nByte == 0 ){ + return 0; + } + zText = sqlite3MallocZero( nByte ); + if( zText==0 ){ + return 0; + } + nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideText, -1, zText, nByte, + 0, 0); + if( nByte == 0 ){ + sqlite3_free(zText); + zText = 0; + } + return zText; +} + +/* +** Convert an ANSI string to Microsoft Unicode, using the ANSI or OEM +** code page. +** +** Space to hold the returned string is obtained from sqlite3_malloc(). +*/ +static LPWSTR winMbcsToUnicode(const char *zText, int useAnsi){ + int nWideChar; + LPWSTR zMbcsText; + int codepage = useAnsi ? CP_ACP : CP_OEMCP; + + nWideChar = osMultiByteToWideChar(codepage, 0, zText, -1, NULL, + 0); + if( nWideChar==0 ){ + return 0; + } + zMbcsText = sqlite3MallocZero( nWideChar*sizeof(WCHAR) ); + if( zMbcsText==0 ){ + return 0; + } + nWideChar = osMultiByteToWideChar(codepage, 0, zText, -1, zMbcsText, + nWideChar); + if( nWideChar==0 ){ + sqlite3_free(zMbcsText); + zMbcsText = 0; + } + return zMbcsText; +} + +#ifdef _WIN32 +/* +** Convert a Microsoft Unicode string to a multi-byte character string, +** using the ANSI or OEM code page. +** +** Space to hold the returned string is obtained from sqlite3_malloc(). +*/ +static char *winUnicodeToMbcs(LPCWSTR zWideText, int useAnsi){ + int nByte; + char *zText; + int codepage = useAnsi ? CP_ACP : CP_OEMCP; + + nByte = osWideCharToMultiByte(codepage, 0, zWideText, -1, 0, 0, 0, 0); + if( nByte == 0 ){ + return 0; + } + zText = sqlite3MallocZero( nByte ); + if( zText==0 ){ + return 0; + } + nByte = osWideCharToMultiByte(codepage, 0, zWideText, -1, zText, + nByte, 0, 0); + if( nByte == 0 ){ + sqlite3_free(zText); + zText = 0; + } + return zText; +} +#endif /* _WIN32 */ + +/* +** Convert a multi-byte character string to UTF-8. +** +** Space to hold the returned string is obtained from sqlite3_malloc(). +*/ +static char *winMbcsToUtf8(const char *zText, int useAnsi){ + char *zTextUtf8; + LPWSTR zTmpWide; + + zTmpWide = winMbcsToUnicode(zText, useAnsi); + if( zTmpWide==0 ){ + return 0; + } + zTextUtf8 = winUnicodeToUtf8(zTmpWide); + sqlite3_free(zTmpWide); + return zTextUtf8; +} + +#ifdef _WIN32 +/* +** Convert a UTF-8 string to a multi-byte character string. +** +** Space to hold the returned string is obtained from sqlite3_malloc(). +*/ +static char *winUtf8ToMbcs(const char *zText, int useAnsi){ + char *zTextMbcs; + LPWSTR zTmpWide; + + zTmpWide = winUtf8ToUnicode(zText); + if( zTmpWide==0 ){ + return 0; + } + zTextMbcs = winUnicodeToMbcs(zTmpWide, useAnsi); + sqlite3_free(zTmpWide); + return zTextMbcs; +} + +/* +** This is a public wrapper for the winUtf8ToUnicode() function. +*/ +SQLITE_API LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !zText ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return winUtf8ToUnicode(zText); +} + +/* +** This is a public wrapper for the winUnicodeToUtf8() function. +*/ +SQLITE_API char *sqlite3_win32_unicode_to_utf8(LPCWSTR zWideText){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !zWideText ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return winUnicodeToUtf8(zWideText); +} +#endif /* _WIN32 */ + +/* +** This is a public wrapper for the winMbcsToUtf8() function. +*/ +SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zText){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !zText ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return winMbcsToUtf8(zText, osAreFileApisANSI()); +} + +#ifdef _WIN32 +/* +** This is a public wrapper for the winMbcsToUtf8() function. +*/ +SQLITE_API char *sqlite3_win32_mbcs_to_utf8_v2(const char *zText, int useAnsi){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !zText ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return winMbcsToUtf8(zText, useAnsi); +} + +/* +** This is a public wrapper for the winUtf8ToMbcs() function. +*/ +SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zText){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !zText ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return winUtf8ToMbcs(zText, osAreFileApisANSI()); +} + +/* +** This is a public wrapper for the winUtf8ToMbcs() function. +*/ +SQLITE_API char *sqlite3_win32_utf8_to_mbcs_v2(const char *zText, int useAnsi){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !zText ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return winUtf8ToMbcs(zText, useAnsi); +} + +/* +** This function is the same as sqlite3_win32_set_directory (below); however, +** it accepts a UTF-8 string. +*/ +SQLITE_API int sqlite3_win32_set_directory8( + unsigned long type, /* Identifier for directory being set or reset */ + const char *zValue /* New value for directory being set or reset */ +){ + char **ppDirectory = 0; + int rc; +#ifndef SQLITE_OMIT_AUTOINIT + rc = sqlite3_initialize(); + if( rc ) return rc; +#endif + sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); + if( type==SQLITE_WIN32_DATA_DIRECTORY_TYPE ){ + ppDirectory = &sqlite3_data_directory; + }else if( type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE ){ + ppDirectory = &sqlite3_temp_directory; + } + assert( !ppDirectory || type==SQLITE_WIN32_DATA_DIRECTORY_TYPE + || type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE + ); + assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) ); + if( ppDirectory ){ + char *zCopy = 0; + if( zValue && zValue[0] ){ + zCopy = sqlite3_mprintf("%s", zValue); + if ( zCopy==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto set_directory8_done; + } + } + sqlite3_free(*ppDirectory); + *ppDirectory = zCopy; + rc = SQLITE_OK; + }else{ + rc = SQLITE_ERROR; + } +set_directory8_done: + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); + return rc; +} + +/* +** This function is the same as sqlite3_win32_set_directory (below); however, +** it accepts a UTF-16 string. +*/ +SQLITE_API int sqlite3_win32_set_directory16( + unsigned long type, /* Identifier for directory being set or reset */ + const void *zValue /* New value for directory being set or reset */ +){ + int rc; + char *zUtf8 = 0; + if( zValue ){ + zUtf8 = sqlite3_win32_unicode_to_utf8(zValue); + if( zUtf8==0 ) return SQLITE_NOMEM_BKPT; + } + rc = sqlite3_win32_set_directory8(type, zUtf8); + if( zUtf8 ) sqlite3_free(zUtf8); + return rc; +} + +/* +** This function sets the data directory or the temporary directory based on +** the provided arguments. The type argument must be 1 in order to set the +** data directory or 2 in order to set the temporary directory. The zValue +** argument is the name of the directory to use. The return value will be +** SQLITE_OK if successful. +*/ +SQLITE_API int sqlite3_win32_set_directory( + unsigned long type, /* Identifier for directory being set or reset */ + void *zValue /* New value for directory being set or reset */ +){ + return sqlite3_win32_set_directory16(type, zValue); +} +#endif /* _WIN32 */ + +/* +** The return value of winGetLastErrorMsg +** is zero if the error message fits in the buffer, or non-zero +** otherwise (if the message was truncated). +*/ +static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ + /* FormatMessage returns 0 on failure. Otherwise it + ** returns the number of TCHARs written to the output + ** buffer, excluding the terminating null char. + */ + DWORD dwLen = 0; + char *zOut = 0; + + if( osIsNT() ){ + LPWSTR zTempWide = NULL; + dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + lastErrno, + 0, + (LPWSTR) &zTempWide, + 0, + 0); + if( dwLen > 0 ){ + /* allocate a buffer and convert to UTF8 */ + sqlite3BeginBenignMalloc(); + zOut = winUnicodeToUtf8(zTempWide); + sqlite3EndBenignMalloc(); + /* free the system buffer allocated by FormatMessage */ + osLocalFree(zTempWide); + } + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + char *zTemp = NULL; + dwLen = osFormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + lastErrno, + 0, + (LPSTR) &zTemp, + 0, + 0); + if( dwLen > 0 ){ + /* allocate a buffer and convert to UTF8 */ + sqlite3BeginBenignMalloc(); + zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI()); + sqlite3EndBenignMalloc(); + /* free the system buffer allocated by FormatMessage */ + osLocalFree(zTemp); + } + } +#endif + if( 0 == dwLen ){ + sqlite3_snprintf(nBuf, zBuf, "OsError 0x%lx (%lu)", lastErrno, lastErrno); + }else{ + /* copy a maximum of nBuf chars to output buffer */ + sqlite3_snprintf(nBuf, zBuf, "%s", zOut); + /* free the UTF8 buffer */ + sqlite3_free(zOut); + } + return 0; +} + +/* +** +** This function - winLogErrorAtLine() - is only ever called via the macro +** winLogError(). +** +** This routine is invoked after an error occurs in an OS function. +** It logs a message using sqlite3_log() containing the current value of +** error code and, if possible, the human-readable equivalent from +** FormatMessage. +** +** The first argument passed to the macro should be the error code that +** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN). +** The two subsequent arguments should be the name of the OS function that +** failed and the associated file-system path, if any. +*/ +#define winLogError(a,b,c,d) winLogErrorAtLine(a,b,c,d,__LINE__) +static int winLogErrorAtLine( + int errcode, /* SQLite error code */ + DWORD lastErrno, /* Win32 last error */ + const char *zFunc, /* Name of OS function that failed */ + const char *zPath, /* File path associated with error */ + int iLine /* Source line number where error occurred */ +){ + char zMsg[500]; /* Human readable error text */ + int i; /* Loop counter */ + + zMsg[0] = 0; + winGetLastErrorMsg(lastErrno, sizeof(zMsg), zMsg); + assert( errcode!=SQLITE_OK ); + if( zPath==0 ) zPath = ""; + for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){} + zMsg[i] = 0; + sqlite3_log(errcode, + "os_win.c:%d: (%lu) %s(%s) - %s", + iLine, lastErrno, zFunc, zPath, zMsg + ); + + return errcode; +} + +/* +** The number of times that a ReadFile(), WriteFile(), and DeleteFile() +** will be retried following a locking error - probably caused by +** antivirus software. Also the initial delay before the first retry. +** The delay increases linearly with each retry. +*/ +#ifndef SQLITE_WIN32_IOERR_RETRY +# define SQLITE_WIN32_IOERR_RETRY 10 +#endif +#ifndef SQLITE_WIN32_IOERR_RETRY_DELAY +# define SQLITE_WIN32_IOERR_RETRY_DELAY 25 +#endif +static int winIoerrRetry = SQLITE_WIN32_IOERR_RETRY; +static int winIoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY; + +/* +** The "winIoerrCanRetry1" macro is used to determine if a particular I/O +** error code obtained via GetLastError() is eligible to be retried. It +** must accept the error code DWORD as its only argument and should return +** non-zero if the error code is transient in nature and the operation +** responsible for generating the original error might succeed upon being +** retried. The argument to this macro should be a variable. +** +** Additionally, a macro named "winIoerrCanRetry2" may be defined. If it +** is defined, it will be consulted only when the macro "winIoerrCanRetry1" +** returns zero. The "winIoerrCanRetry2" macro is completely optional and +** may be used to include additional error codes in the set that should +** result in the failing I/O operation being retried by the caller. If +** defined, the "winIoerrCanRetry2" macro must exhibit external semantics +** identical to those of the "winIoerrCanRetry1" macro. +*/ +#if !defined(winIoerrCanRetry1) +#define winIoerrCanRetry1(a) (((a)==ERROR_ACCESS_DENIED) || \ + ((a)==ERROR_SHARING_VIOLATION) || \ + ((a)==ERROR_LOCK_VIOLATION) || \ + ((a)==ERROR_DEV_NOT_EXIST) || \ + ((a)==ERROR_NETNAME_DELETED) || \ + ((a)==ERROR_SEM_TIMEOUT) || \ + ((a)==ERROR_NETWORK_UNREACHABLE)) +#endif + +/* +** If a ReadFile() or WriteFile() error occurs, invoke this routine +** to see if it should be retried. Return TRUE to retry. Return FALSE +** to give up with an error. +*/ +static int winRetryIoerr(int *pnRetry, DWORD *pError){ + DWORD e = osGetLastError(); + if( *pnRetry>=winIoerrRetry ){ + if( pError ){ + *pError = e; + } + return 0; + } + if( winIoerrCanRetry1(e) ){ + sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry)); + ++*pnRetry; + return 1; + } +#if defined(winIoerrCanRetry2) + else if( winIoerrCanRetry2(e) ){ + sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry)); + ++*pnRetry; + return 1; + } +#endif + if( pError ){ + *pError = e; + } + return 0; +} + +/* +** Log a I/O error retry episode. +*/ +static void winLogIoerr(int nRetry, int lineno){ + if( nRetry ){ + sqlite3_log(SQLITE_NOTICE, + "delayed %dms for lock/sharing conflict at line %d", + winIoerrRetryDelay*nRetry*(nRetry+1)/2, lineno + ); + } +} + +/* +** This #if does not rely on the SQLITE_OS_WINCE define because the +** corresponding section in "date.c" cannot use it. +*/ +#if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \ + (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API) +/* +** The MSVC CRT on Windows CE may not have a localtime() function. +** So define a substitute. +*/ +/* # include */ +struct tm *__cdecl localtime(const time_t *t) +{ + static struct tm y; + FILETIME uTm, lTm; + SYSTEMTIME pTm; + sqlite3_int64 t64; + t64 = *t; + t64 = (t64 + 11644473600)*10000000; + uTm.dwLowDateTime = (DWORD)(t64 & 0xFFFFFFFF); + uTm.dwHighDateTime= (DWORD)(t64 >> 32); + osFileTimeToLocalFileTime(&uTm,&lTm); + osFileTimeToSystemTime(&lTm,&pTm); + y.tm_year = pTm.wYear - 1900; + y.tm_mon = pTm.wMonth - 1; + y.tm_wday = pTm.wDayOfWeek; + y.tm_mday = pTm.wDay; + y.tm_hour = pTm.wHour; + y.tm_min = pTm.wMinute; + y.tm_sec = pTm.wSecond; + return &y; +} +#endif + +#if SQLITE_OS_WINCE +/************************************************************************* +** This section contains code for WinCE only. +*/ +#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)] + +/* +** Acquire a lock on the handle h +*/ +static void winceMutexAcquire(HANDLE h){ + DWORD dwErr; + do { + dwErr = osWaitForSingleObject(h, INFINITE); + } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED); +} +/* +** Release a lock acquired by winceMutexAcquire() +*/ +#define winceMutexRelease(h) ReleaseMutex(h) + +/* +** Create the mutex and shared memory used for locking in the file +** descriptor pFile +*/ +static int winceCreateLock(const char *zFilename, winFile *pFile){ + LPWSTR zTok; + LPWSTR zName; + DWORD lastErrno; + BOOL bLogged = FALSE; + BOOL bInit = TRUE; + + zName = winUtf8ToUnicode(zFilename); + if( zName==0 ){ + /* out of memory */ + return SQLITE_IOERR_NOMEM_BKPT; + } + + /* Initialize the local lockdata */ + memset(&pFile->local, 0, sizeof(pFile->local)); + + /* Replace the backslashes from the filename and lowercase it + ** to derive a mutex name. */ + zTok = osCharLowerW(zName); + for (;*zTok;zTok++){ + if (*zTok == '\\') *zTok = '_'; + } + + /* Create/open the named mutex */ + pFile->hMutex = osCreateMutexW(NULL, FALSE, zName); + if (!pFile->hMutex){ + pFile->lastErrno = osGetLastError(); + sqlite3_free(zName); + return winLogError(SQLITE_IOERR, pFile->lastErrno, + "winceCreateLock1", zFilename); + } + + /* Acquire the mutex before continuing */ + winceMutexAcquire(pFile->hMutex); + + /* Since the names of named mutexes, semaphores, file mappings etc are + ** case-sensitive, take advantage of that by uppercasing the mutex name + ** and using that as the shared filemapping name. + */ + osCharUpperW(zName); + pFile->hShared = osCreateFileMappingW(INVALID_HANDLE_VALUE, NULL, + PAGE_READWRITE, 0, sizeof(winceLock), + zName); + + /* Set a flag that indicates we're the first to create the memory so it + ** must be zero-initialized */ + lastErrno = osGetLastError(); + if (lastErrno == ERROR_ALREADY_EXISTS){ + bInit = FALSE; + } + + sqlite3_free(zName); + + /* If we succeeded in making the shared memory handle, map it. */ + if( pFile->hShared ){ + pFile->shared = (winceLock*)osMapViewOfFile(pFile->hShared, + FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock)); + /* If mapping failed, close the shared memory handle and erase it */ + if( !pFile->shared ){ + pFile->lastErrno = osGetLastError(); + winLogError(SQLITE_IOERR, pFile->lastErrno, + "winceCreateLock2", zFilename); + bLogged = TRUE; + osCloseHandle(pFile->hShared); + pFile->hShared = NULL; + } + } + + /* If shared memory could not be created, then close the mutex and fail */ + if( pFile->hShared==NULL ){ + if( !bLogged ){ + pFile->lastErrno = lastErrno; + winLogError(SQLITE_IOERR, pFile->lastErrno, + "winceCreateLock3", zFilename); + bLogged = TRUE; + } + winceMutexRelease(pFile->hMutex); + osCloseHandle(pFile->hMutex); + pFile->hMutex = NULL; + return SQLITE_IOERR; + } + + /* Initialize the shared memory if we're supposed to */ + if( bInit ){ + memset(pFile->shared, 0, sizeof(winceLock)); + } + + winceMutexRelease(pFile->hMutex); + return SQLITE_OK; +} + +/* +** Destroy the part of winFile that deals with wince locks +*/ +static void winceDestroyLock(winFile *pFile){ + if (pFile->hMutex){ + /* Acquire the mutex */ + winceMutexAcquire(pFile->hMutex); + + /* The following blocks should probably assert in debug mode, but they + are to cleanup in case any locks remained open */ + if (pFile->local.nReaders){ + pFile->shared->nReaders --; + } + if (pFile->local.bReserved){ + pFile->shared->bReserved = FALSE; + } + if (pFile->local.bPending){ + pFile->shared->bPending = FALSE; + } + if (pFile->local.bExclusive){ + pFile->shared->bExclusive = FALSE; + } + + /* De-reference and close our copy of the shared memory handle */ + osUnmapViewOfFile(pFile->shared); + osCloseHandle(pFile->hShared); + + /* Done with the mutex */ + winceMutexRelease(pFile->hMutex); + osCloseHandle(pFile->hMutex); + pFile->hMutex = NULL; + } +} + +/* +** An implementation of the LockFile() API of Windows for CE +*/ +static BOOL winceLockFile( + LPHANDLE phFile, + DWORD dwFileOffsetLow, + DWORD dwFileOffsetHigh, + DWORD nNumberOfBytesToLockLow, + DWORD nNumberOfBytesToLockHigh +){ + winFile *pFile = HANDLE_TO_WINFILE(phFile); + BOOL bReturn = FALSE; + + UNUSED_PARAMETER(dwFileOffsetHigh); + UNUSED_PARAMETER(nNumberOfBytesToLockHigh); + + if (!pFile->hMutex) return TRUE; + winceMutexAcquire(pFile->hMutex); + + /* Wanting an exclusive lock? */ + if (dwFileOffsetLow == (DWORD)SHARED_FIRST + && nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){ + if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){ + pFile->shared->bExclusive = TRUE; + pFile->local.bExclusive = TRUE; + bReturn = TRUE; + } + } + + /* Want a read-only lock? */ + else if (dwFileOffsetLow == (DWORD)SHARED_FIRST && + nNumberOfBytesToLockLow == 1){ + if (pFile->shared->bExclusive == 0){ + pFile->local.nReaders ++; + if (pFile->local.nReaders == 1){ + pFile->shared->nReaders ++; + } + bReturn = TRUE; + } + } + + /* Want a pending lock? */ + else if (dwFileOffsetLow == (DWORD)PENDING_BYTE + && nNumberOfBytesToLockLow == 1){ + /* If no pending lock has been acquired, then acquire it */ + if (pFile->shared->bPending == 0) { + pFile->shared->bPending = TRUE; + pFile->local.bPending = TRUE; + bReturn = TRUE; + } + } + + /* Want a reserved lock? */ + else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE + && nNumberOfBytesToLockLow == 1){ + if (pFile->shared->bReserved == 0) { + pFile->shared->bReserved = TRUE; + pFile->local.bReserved = TRUE; + bReturn = TRUE; + } + } + + winceMutexRelease(pFile->hMutex); + return bReturn; +} + +/* +** An implementation of the UnlockFile API of Windows for CE +*/ +static BOOL winceUnlockFile( + LPHANDLE phFile, + DWORD dwFileOffsetLow, + DWORD dwFileOffsetHigh, + DWORD nNumberOfBytesToUnlockLow, + DWORD nNumberOfBytesToUnlockHigh +){ + winFile *pFile = HANDLE_TO_WINFILE(phFile); + BOOL bReturn = FALSE; + + UNUSED_PARAMETER(dwFileOffsetHigh); + UNUSED_PARAMETER(nNumberOfBytesToUnlockHigh); + + if (!pFile->hMutex) return TRUE; + winceMutexAcquire(pFile->hMutex); + + /* Releasing a reader lock or an exclusive lock */ + if (dwFileOffsetLow == (DWORD)SHARED_FIRST){ + /* Did we have an exclusive lock? */ + if (pFile->local.bExclusive){ + assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE); + pFile->local.bExclusive = FALSE; + pFile->shared->bExclusive = FALSE; + bReturn = TRUE; + } + + /* Did we just have a reader lock? */ + else if (pFile->local.nReaders){ + assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE + || nNumberOfBytesToUnlockLow == 1); + pFile->local.nReaders --; + if (pFile->local.nReaders == 0) + { + pFile->shared->nReaders --; + } + bReturn = TRUE; + } + } + + /* Releasing a pending lock */ + else if (dwFileOffsetLow == (DWORD)PENDING_BYTE + && nNumberOfBytesToUnlockLow == 1){ + if (pFile->local.bPending){ + pFile->local.bPending = FALSE; + pFile->shared->bPending = FALSE; + bReturn = TRUE; + } + } + /* Releasing a reserved lock */ + else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE + && nNumberOfBytesToUnlockLow == 1){ + if (pFile->local.bReserved) { + pFile->local.bReserved = FALSE; + pFile->shared->bReserved = FALSE; + bReturn = TRUE; + } + } + + winceMutexRelease(pFile->hMutex); + return bReturn; +} +/* +** End of the special code for wince +*****************************************************************************/ +#endif /* SQLITE_OS_WINCE */ + +/* +** Lock a file region. +*/ +static BOOL winLockFile( + LPHANDLE phFile, + DWORD flags, + DWORD offsetLow, + DWORD offsetHigh, + DWORD numBytesLow, + DWORD numBytesHigh +){ +#if SQLITE_OS_WINCE + /* + ** NOTE: Windows CE is handled differently here due its lack of the Win32 + ** API LockFile. + */ + return winceLockFile(phFile, offsetLow, offsetHigh, + numBytesLow, numBytesHigh); +#else + if( osIsNT() ){ + OVERLAPPED ovlp; + memset(&ovlp, 0, sizeof(OVERLAPPED)); + ovlp.Offset = offsetLow; + ovlp.OffsetHigh = offsetHigh; + return osLockFileEx(*phFile, flags, 0, numBytesLow, numBytesHigh, &ovlp); +#ifdef SQLITE_WIN32_HAS_ANSI + }else{ + return osLockFile(*phFile, offsetLow, offsetHigh, numBytesLow, + numBytesHigh); +#endif + } +#endif +} + +#ifndef SQLITE_OMIT_WAL +/* +** Lock a region of nByte bytes starting at offset offset of file hFile. +** Take an EXCLUSIVE lock if parameter bExclusive is true, or a SHARED lock +** otherwise. If nMs is greater than zero and the lock cannot be obtained +** immediately, block for that many ms before giving up. +** +** This function returns SQLITE_OK if the lock is obtained successfully. If +** some other process holds the lock, SQLITE_BUSY is returned if nMs==0, or +** SQLITE_BUSY_TIMEOUT otherwise. Or, if an error occurs, SQLITE_IOERR. +*/ +static int winHandleLockTimeout( + HANDLE hFile, + DWORD offset, + DWORD nByte, + int bExcl, + DWORD nMs +){ + DWORD flags = LOCKFILE_FAIL_IMMEDIATELY | (bExcl?LOCKFILE_EXCLUSIVE_LOCK:0); + int rc = SQLITE_OK; + BOOL ret; + + if( !osIsNT() ){ + ret = winLockFile(&hFile, flags, offset, 0, nByte, 0); + }else{ + OVERLAPPED ovlp; + memset(&ovlp, 0, sizeof(OVERLAPPED)); + ovlp.Offset = offset; + +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + if( nMs!=0 ){ + flags &= ~LOCKFILE_FAIL_IMMEDIATELY; + } + ovlp.hEvent = osCreateEvent(NULL, TRUE, FALSE, NULL); + if( ovlp.hEvent==NULL ){ + return SQLITE_IOERR_LOCK; + } +#endif + + ret = osLockFileEx(hFile, flags, 0, nByte, 0, &ovlp); + +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + /* If SQLITE_ENABLE_SETLK_TIMEOUT is defined, then the file-handle was + ** opened with FILE_FLAG_OVERHEAD specified. In this case, the call to + ** LockFileEx() may fail because the request is still pending. This can + ** happen even if LOCKFILE_FAIL_IMMEDIATELY was specified. + ** + ** If nMs is 0, then LOCKFILE_FAIL_IMMEDIATELY was set in the flags + ** passed to LockFileEx(). In this case, if the operation is pending, + ** block indefinitely until it is finished. + ** + ** Otherwise, wait for up to nMs ms for the operation to finish. nMs + ** may be set to INFINITE. + */ + if( !ret && GetLastError()==ERROR_IO_PENDING ){ + DWORD nDelay = (nMs==0 ? INFINITE : nMs); + DWORD res = osWaitForSingleObject(ovlp.hEvent, nDelay); + if( res==WAIT_OBJECT_0 ){ + ret = TRUE; + }else if( res==WAIT_TIMEOUT ){ +#if SQLITE_ENABLE_SETLK_TIMEOUT==1 + rc = SQLITE_BUSY_TIMEOUT; +#else + rc = SQLITE_BUSY; +#endif + }else{ + /* Some other error has occurred */ + rc = SQLITE_IOERR_LOCK; + } + + /* If it is still pending, cancel the LockFileEx() call. */ + osCancelIo(hFile); + } + + osCloseHandle(ovlp.hEvent); +#endif + } + + if( rc==SQLITE_OK && !ret ){ + rc = SQLITE_BUSY; + } + return rc; +} +#endif /* #ifndef SQLITE_OMIT_WAL */ + +/* +** Unlock a file region. + */ +static BOOL winUnlockFile( + LPHANDLE phFile, + DWORD offsetLow, + DWORD offsetHigh, + DWORD numBytesLow, + DWORD numBytesHigh +){ +#if SQLITE_OS_WINCE + /* + ** NOTE: Windows CE is handled differently here due its lack of the Win32 + ** API UnlockFile. + */ + return winceUnlockFile(phFile, offsetLow, offsetHigh, + numBytesLow, numBytesHigh); +#else + if( osIsNT() ){ + OVERLAPPED ovlp; + memset(&ovlp, 0, sizeof(OVERLAPPED)); + ovlp.Offset = offsetLow; + ovlp.OffsetHigh = offsetHigh; + return osUnlockFileEx(*phFile, 0, numBytesLow, numBytesHigh, &ovlp); +#ifdef SQLITE_WIN32_HAS_ANSI + }else{ + return osUnlockFile(*phFile, offsetLow, offsetHigh, numBytesLow, + numBytesHigh); +#endif + } +#endif +} + +#ifndef SQLITE_OMIT_WAL +/* +** Remove an nByte lock starting at offset iOff from HANDLE h. +*/ +static int winHandleUnlock(HANDLE h, int iOff, int nByte){ + BOOL ret = winUnlockFile(&h, iOff, 0, nByte, 0); + return (ret ? SQLITE_OK : SQLITE_IOERR_UNLOCK); +} +#endif + +/***************************************************************************** +** The next group of routines implement the I/O methods specified +** by the sqlite3_io_methods object. +******************************************************************************/ + +/* +** Some Microsoft compilers lack this definition. +*/ +#ifndef INVALID_SET_FILE_POINTER +# define INVALID_SET_FILE_POINTER ((DWORD)-1) +#endif + +/* +** Seek the file handle h to offset nByte of the file. +** +** If successful, return SQLITE_OK. Or, if an error occurs, return an SQLite +** error code. +*/ +static int winHandleSeek(HANDLE h, sqlite3_int64 iOffset){ + int rc = SQLITE_OK; /* Return value */ + + LONG upperBits; /* Most sig. 32 bits of new offset */ + LONG lowerBits; /* Least sig. 32 bits of new offset */ + DWORD dwRet; /* Value returned by SetFilePointer() */ + + upperBits = (LONG)((iOffset>>32) & 0x7fffffff); + lowerBits = (LONG)(iOffset & 0xffffffff); + + dwRet = osSetFilePointer(h, lowerBits, &upperBits, FILE_BEGIN); + + /* API oddity: If successful, SetFilePointer() returns a dword + ** containing the lower 32-bits of the new file-offset. Or, if it fails, + ** it returns INVALID_SET_FILE_POINTER. However according to MSDN, + ** INVALID_SET_FILE_POINTER may also be a valid new offset. So to determine + ** whether an error has actually occurred, it is also necessary to call + ** GetLastError(). */ + if( dwRet==INVALID_SET_FILE_POINTER ){ + DWORD lastErrno = osGetLastError(); + if( lastErrno!=NO_ERROR ){ + rc = SQLITE_IOERR_SEEK; + } + } + OSTRACE(("SEEK file=%p, offset=%lld rc=%s\n", h, iOffset,sqlite3ErrName(rc))); + return rc; +} + +/* +** Move the current position of the file handle passed as the first +** argument to offset iOffset within the file. If successful, return 0. +** Otherwise, set pFile->lastErrno and return non-zero. +*/ +static int winSeekFile(winFile *pFile, sqlite3_int64 iOffset){ + int rc; + + rc = winHandleSeek(pFile->h, iOffset); + if( rc!=SQLITE_OK ){ + pFile->lastErrno = osGetLastError(); + winLogError(rc, pFile->lastErrno, "winSeekFile", pFile->zPath); + } + return rc; +} + + +#if SQLITE_MAX_MMAP_SIZE>0 +/* Forward references to VFS helper methods used for memory mapped files */ +static int winMapfile(winFile*, sqlite3_int64); +static int winUnmapfile(winFile*); +#endif + +/* +** Close a file. +** +** It is reported that an attempt to close a handle might sometimes +** fail. This is a very unreasonable result, but Windows is notorious +** for being unreasonable so I do not doubt that it might happen. If +** the close fails, we pause for 100 milliseconds and try again. As +** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before +** giving up and returning an error. +*/ +#define MX_CLOSE_ATTEMPT 3 +static int winClose(sqlite3_file *id){ + int rc, cnt = 0; + winFile *pFile = (winFile*)id; + + assert( id!=0 ); +#ifndef SQLITE_OMIT_WAL + assert( pFile->pShm==0 ); +#endif + assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE ); + OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p\n", + osGetCurrentProcessId(), pFile, pFile->h)); + +#if SQLITE_MAX_MMAP_SIZE>0 + winUnmapfile(pFile); +#endif + + do{ + rc = osCloseHandle(pFile->h); + /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */ + }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) ); +#if SQLITE_OS_WINCE +#define WINCE_DELETION_ATTEMPTS 3 + { + winVfsAppData *pAppData = (winVfsAppData*)pFile->pVfs->pAppData; + if( pAppData==NULL || !pAppData->bNoLock ){ + winceDestroyLock(pFile); + } + } + if( pFile->zDeleteOnClose ){ + int cnt = 0; + while( + osDeleteFileW(pFile->zDeleteOnClose)==0 + && osGetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff + && cnt++ < WINCE_DELETION_ATTEMPTS + ){ + sqlite3_win32_sleep(100); /* Wait a little before trying again */ + } + sqlite3_free(pFile->zDeleteOnClose); + } +#endif + if( rc ){ + pFile->h = NULL; + } + OpenCounter(-1); + OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p, rc=%s\n", + osGetCurrentProcessId(), pFile, pFile->h, rc ? "ok" : "failed")); + return rc ? SQLITE_OK + : winLogError(SQLITE_IOERR_CLOSE, osGetLastError(), + "winClose", pFile->zPath); +} + +/* +** Read data from a file into a buffer. Return SQLITE_OK if all +** bytes were read successfully and SQLITE_IOERR if anything goes +** wrong. +*/ +static int winRead( + sqlite3_file *id, /* File to read from */ + void *pBuf, /* Write content into this buffer */ + int amt, /* Number of bytes to read */ + sqlite3_int64 offset /* Begin reading at this offset */ +){ +#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED) + OVERLAPPED overlapped; /* The offset for ReadFile. */ +#endif + winFile *pFile = (winFile*)id; /* file handle */ + DWORD nRead; /* Number of bytes actually read from file */ + int nRetry = 0; /* Number of retrys */ + + assert( id!=0 ); + assert( amt>0 ); + assert( offset>=0 ); + SimulateIOError(return SQLITE_IOERR_READ); + OSTRACE(("READ pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, " + "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile, + pFile->h, pBuf, amt, offset, pFile->locktype)); + +#if SQLITE_MAX_MMAP_SIZE>0 + /* Deal with as much of this read request as possible by transferring + ** data from the memory mapping using memcpy(). */ + if( offsetmmapSize ){ + if( offset+amt <= pFile->mmapSize ){ + memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt); + OSTRACE(("READ-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return SQLITE_OK; + }else{ + int nCopy = (int)(pFile->mmapSize - offset); + memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy); + pBuf = &((u8 *)pBuf)[nCopy]; + amt -= nCopy; + offset += nCopy; + } + } +#endif + +#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED) + if( winSeekFile(pFile, offset) ){ + OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return SQLITE_FULL; + } + while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ +#else + memset(&overlapped, 0, sizeof(OVERLAPPED)); + overlapped.Offset = (LONG)(offset & 0xffffffff); + overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff); + while( !osReadFile(pFile->h, pBuf, amt, &nRead, &overlapped) && + osGetLastError()!=ERROR_HANDLE_EOF ){ +#endif + DWORD lastErrno; + if( winRetryIoerr(&nRetry, &lastErrno) ) continue; + pFile->lastErrno = lastErrno; + OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_READ\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return winLogError(SQLITE_IOERR_READ, pFile->lastErrno, + "winRead", pFile->zPath); + } + winLogIoerr(nRetry, __LINE__); + if( nRead<(DWORD)amt ){ + /* Unread parts of the buffer must be zero-filled */ + memset(&((char*)pBuf)[nRead], 0, amt-nRead); + OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_SHORT_READ\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return SQLITE_IOERR_SHORT_READ; + } + + OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return SQLITE_OK; +} + +/* +** Write data from a buffer into a file. Return SQLITE_OK on success +** or some other error code on failure. +*/ +static int winWrite( + sqlite3_file *id, /* File to write into */ + const void *pBuf, /* The bytes to be written */ + int amt, /* Number of bytes to write */ + sqlite3_int64 offset /* Offset into the file to begin writing at */ +){ + int rc = 0; /* True if error has occurred, else false */ + winFile *pFile = (winFile*)id; /* File handle */ + int nRetry = 0; /* Number of retries */ + + assert( amt>0 ); + assert( pFile ); + SimulateIOError(return SQLITE_IOERR_WRITE); + SimulateDiskfullError(return SQLITE_FULL); + + OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, " + "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile, + pFile->h, pBuf, amt, offset, pFile->locktype)); + +#if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0 + /* Deal with as much of this write request as possible by transferring + ** data from the memory mapping using memcpy(). */ + if( offsetmmapSize ){ + if( offset+amt <= pFile->mmapSize ){ + memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt); + OSTRACE(("WRITE-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return SQLITE_OK; + }else{ + int nCopy = (int)(pFile->mmapSize - offset); + memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy); + pBuf = &((u8 *)pBuf)[nCopy]; + amt -= nCopy; + offset += nCopy; + } + } +#endif + +#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED) + rc = winSeekFile(pFile, offset); + if( rc==0 ){ +#else + { +#endif +#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED) + OVERLAPPED overlapped; /* The offset for WriteFile. */ +#endif + u8 *aRem = (u8 *)pBuf; /* Data yet to be written */ + int nRem = amt; /* Number of bytes yet to be written */ + DWORD nWrite; /* Bytes written by each WriteFile() call */ + DWORD lastErrno = NO_ERROR; /* Value returned by GetLastError() */ + +#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED) + memset(&overlapped, 0, sizeof(OVERLAPPED)); + overlapped.Offset = (LONG)(offset & 0xffffffff); + overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff); +#endif + + while( nRem>0 ){ +#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED) + if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){ +#else + if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){ +#endif + if( winRetryIoerr(&nRetry, &lastErrno) ) continue; + break; + } + assert( nWrite==0 || nWrite<=(DWORD)nRem ); + if( nWrite==0 || nWrite>(DWORD)nRem ){ + lastErrno = osGetLastError(); + break; + } +#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED) + offset += nWrite; + overlapped.Offset = (LONG)(offset & 0xffffffff); + overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff); +#endif + aRem += nWrite; + nRem -= nWrite; + } + if( nRem>0 ){ + pFile->lastErrno = lastErrno; + rc = 1; + } + } + + if( rc ){ + if( ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ) + || ( pFile->lastErrno==ERROR_DISK_FULL )){ + OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return winLogError(SQLITE_FULL, pFile->lastErrno, + "winWrite1", pFile->zPath); + } + OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_WRITE\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno, + "winWrite2", pFile->zPath); + }else{ + winLogIoerr(nRetry, __LINE__); + } + OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return SQLITE_OK; +} + +#ifndef SQLITE_OMIT_WAL +/* +** Truncate the file opened by handle h to nByte bytes in size. +*/ +static int winHandleTruncate(HANDLE h, sqlite3_int64 nByte){ + int rc = SQLITE_OK; /* Return code */ + rc = winHandleSeek(h, nByte); + if( rc==SQLITE_OK ){ + if( 0==osSetEndOfFile(h) ){ + rc = SQLITE_IOERR_TRUNCATE; + } + } + return rc; +} + +/* +** Determine the size in bytes of the file opened by the handle passed as +** the first argument. +*/ +static int winHandleSize(HANDLE h, sqlite3_int64 *pnByte){ + int rc = SQLITE_OK; + DWORD upperBits = 0; + DWORD lowerBits = 0; + + assert( pnByte ); + lowerBits = osGetFileSize(h, &upperBits); + *pnByte = (((sqlite3_int64)upperBits)<<32) + lowerBits; + if( lowerBits==INVALID_FILE_SIZE && osGetLastError()!=NO_ERROR ){ + rc = SQLITE_IOERR_FSTAT; + } + return rc; +} + +/* +** Close the handle passed as the only argument. +*/ +static void winHandleClose(HANDLE h){ + if( h!=INVALID_HANDLE_VALUE ){ + osCloseHandle(h); + } +} +#endif /* #ifndef SQLITE_OMIT_WAL */ + +/* +** Truncate an open file to a specified size +*/ +static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ + winFile *pFile = (winFile*)id; /* File handle object */ + int rc = SQLITE_OK; /* Return code for this function */ + DWORD lastErrno; +#if SQLITE_MAX_MMAP_SIZE>0 + sqlite3_int64 oldMmapSize; + if( pFile->nFetchOut>0 ){ + /* File truncation is a no-op if there are outstanding memory mapped + ** pages. This is because truncating the file means temporarily unmapping + ** the file, and that might delete memory out from under existing cursors. + ** + ** This can result in incremental vacuum not truncating the file, + ** if there is an active read cursor when the incremental vacuum occurs. + ** No real harm comes of this - the database file is not corrupted, + ** though some folks might complain that the file is bigger than it + ** needs to be. + ** + ** The only feasible work-around is to defer the truncation until after + ** all references to memory-mapped content are closed. That is doable, + ** but involves adding a few branches in the common write code path which + ** could slow down normal operations slightly. Hence, we have decided for + ** now to simply make transactions a no-op if there are pending reads. We + ** can maybe revisit this decision in the future. + */ + return SQLITE_OK; + } +#endif + + assert( pFile ); + SimulateIOError(return SQLITE_IOERR_TRUNCATE); + OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, size=%lld, lock=%d\n", + osGetCurrentProcessId(), pFile, pFile->h, nByte, pFile->locktype)); + + /* If the user has configured a chunk-size for this file, truncate the + ** file so that it consists of an integer number of chunks (i.e. the + ** actual file size after the operation may be larger than the requested + ** size). + */ + if( pFile->szChunk>0 ){ + nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; + } + +#if SQLITE_MAX_MMAP_SIZE>0 + if( pFile->pMapRegion ){ + oldMmapSize = pFile->mmapSize; + }else{ + oldMmapSize = 0; + } + winUnmapfile(pFile); +#endif + + /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */ + if( winSeekFile(pFile, nByte) ){ + rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, + "winTruncate1", pFile->zPath); + }else if( 0==osSetEndOfFile(pFile->h) && + ((lastErrno = osGetLastError())!=ERROR_USER_MAPPED_FILE) ){ + pFile->lastErrno = lastErrno; + rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, + "winTruncate2", pFile->zPath); + } + +#if SQLITE_MAX_MMAP_SIZE>0 + if( rc==SQLITE_OK && oldMmapSize>0 ){ + if( oldMmapSize>nByte ){ + winMapfile(pFile, -1); + }else{ + winMapfile(pFile, oldMmapSize); + } + } +#endif + + OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, rc=%s\n", + osGetCurrentProcessId(), pFile, pFile->h, sqlite3ErrName(rc))); + return rc; +} + +#ifdef SQLITE_TEST +/* +** Count the number of fullsyncs and normal syncs. This is used to test +** that syncs and fullsyncs are occurring at the right times. +*/ +SQLITE_API int sqlite3_sync_count = 0; +SQLITE_API int sqlite3_fullsync_count = 0; +#endif + +/* +** Make sure all writes to a particular file are committed to disk. +*/ +static int winSync(sqlite3_file *id, int flags){ +#ifndef SQLITE_NO_SYNC + /* + ** Used only when SQLITE_NO_SYNC is not defined. + */ + BOOL rc; +#endif +#if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || \ + defined(SQLITE_HAVE_OS_TRACE) + /* + ** Used when SQLITE_NO_SYNC is not defined and by the assert() and/or + ** OSTRACE() macros. + */ + winFile *pFile = (winFile*)id; +#else + UNUSED_PARAMETER(id); +#endif + + assert( pFile ); + /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */ + assert((flags&0x0F)==SQLITE_SYNC_NORMAL + || (flags&0x0F)==SQLITE_SYNC_FULL + ); + + /* Unix cannot, but some systems may return SQLITE_FULL from here. This + ** line is to test that doing so does not cause any problems. + */ + SimulateDiskfullError( return SQLITE_FULL ); + + OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, flags=%x, lock=%d\n", + osGetCurrentProcessId(), pFile, pFile->h, flags, + pFile->locktype)); + +#ifndef SQLITE_TEST + UNUSED_PARAMETER(flags); +#else + if( (flags&0x0F)==SQLITE_SYNC_FULL ){ + sqlite3_fullsync_count++; + } + sqlite3_sync_count++; +#endif + + /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a + ** no-op + */ +#ifdef SQLITE_NO_SYNC + OSTRACE(("SYNC-NOP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return SQLITE_OK; +#else +#if SQLITE_MAX_MMAP_SIZE>0 + if( pFile->pMapRegion ){ + if( osFlushViewOfFile(pFile->pMapRegion, 0) ){ + OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, " + "rc=SQLITE_OK\n", osGetCurrentProcessId(), + pFile, pFile->pMapRegion)); + }else{ + pFile->lastErrno = osGetLastError(); + OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, " + "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), + pFile, pFile->pMapRegion)); + return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, + "winSync1", pFile->zPath); + } + } +#endif + rc = osFlushFileBuffers(pFile->h); + SimulateIOError( rc=FALSE ); + if( rc ){ + OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return SQLITE_OK; + }else{ + pFile->lastErrno = osGetLastError(); + OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_FSYNC\n", + osGetCurrentProcessId(), pFile, pFile->h)); + return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno, + "winSync2", pFile->zPath); + } +#endif +} + +/* +** Determine the current size of a file in bytes +*/ +static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ + winFile *pFile = (winFile*)id; + int rc = SQLITE_OK; + + assert( id!=0 ); + assert( pSize!=0 ); + SimulateIOError(return SQLITE_IOERR_FSTAT); + OSTRACE(("SIZE file=%p, pSize=%p\n", pFile->h, pSize)); + { + DWORD upperBits; + DWORD lowerBits; + DWORD lastErrno; + + lowerBits = osGetFileSize(pFile->h, &upperBits); + *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits; + if( (lowerBits == INVALID_FILE_SIZE) + && ((lastErrno = osGetLastError())!=NO_ERROR) ){ + pFile->lastErrno = lastErrno; + rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, + "winFileSize", pFile->zPath); + } + } + OSTRACE(("SIZE file=%p, pSize=%p, *pSize=%lld, rc=%s\n", + pFile->h, pSize, *pSize, sqlite3ErrName(rc))); + return rc; +} + +/* +** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems. +*/ +#ifndef LOCKFILE_FAIL_IMMEDIATELY +# define LOCKFILE_FAIL_IMMEDIATELY 1 +#endif + +#ifndef LOCKFILE_EXCLUSIVE_LOCK +# define LOCKFILE_EXCLUSIVE_LOCK 2 +#endif + +/* +** Historically, SQLite has used both the LockFile and LockFileEx functions. +** When the LockFile function was used, it was always expected to fail +** immediately if the lock could not be obtained. Also, it always expected to +** obtain an exclusive lock. These flags are used with the LockFileEx function +** and reflect those expectations; therefore, they should not be changed. +*/ +#ifndef SQLITE_LOCKFILE_FLAGS +# define SQLITE_LOCKFILE_FLAGS (LOCKFILE_FAIL_IMMEDIATELY | \ + LOCKFILE_EXCLUSIVE_LOCK) +#endif + +/* +** Currently, SQLite never calls the LockFileEx function without wanting the +** call to fail immediately if the lock cannot be obtained. +*/ +#ifndef SQLITE_LOCKFILEEX_FLAGS +# define SQLITE_LOCKFILEEX_FLAGS (LOCKFILE_FAIL_IMMEDIATELY) +#endif + +/* +** Acquire a reader lock. +** Different API routines are called depending on whether or not this +** is Win9x or WinNT. +*/ +static int winGetReadLock(winFile *pFile, int bBlock){ + int res; + DWORD mask = ~(bBlock ? LOCKFILE_FAIL_IMMEDIATELY : 0); + OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); + if( osIsNT() ){ +#if SQLITE_OS_WINCE + /* + ** NOTE: Windows CE is handled differently here due its lack of the Win32 + ** API LockFileEx. + */ + res = winceLockFile(&pFile->h, SHARED_FIRST, 0, 1, 0); +#else + res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS&mask, SHARED_FIRST, 0, + SHARED_SIZE, 0); +#endif + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + int lk; + sqlite3_randomness(sizeof(lk), &lk); + pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1)); + res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS&mask, + SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); + } +#endif + if( res == 0 ){ + pFile->lastErrno = osGetLastError(); + /* No need to log a failure to lock */ + } + OSTRACE(("READ-LOCK file=%p, result=%d\n", pFile->h, res)); + return res; +} + +/* +** Undo a readlock +*/ +static int winUnlockReadLock(winFile *pFile){ + int res; + DWORD lastErrno; + OSTRACE(("READ-UNLOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); + if( osIsNT() ){ + res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + res = winUnlockFile(&pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); + } +#endif + if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){ + pFile->lastErrno = lastErrno; + winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno, + "winUnlockReadLock", pFile->zPath); + } + OSTRACE(("READ-UNLOCK file=%p, result=%d\n", pFile->h, res)); + return res; +} + +/* +** Lock the file with the lock specified by parameter locktype - one +** of the following: +** +** (1) SHARED_LOCK +** (2) RESERVED_LOCK +** (3) PENDING_LOCK +** (4) EXCLUSIVE_LOCK +** +** Sometimes when requesting one lock state, additional lock states +** are inserted in between. The locking might fail on one of the later +** transitions leaving the lock state different from what it started but +** still short of its goal. The following chart shows the allowed +** transitions and the inserted intermediate states: +** +** UNLOCKED -> SHARED +** SHARED -> RESERVED +** SHARED -> (PENDING) -> EXCLUSIVE +** RESERVED -> (PENDING) -> EXCLUSIVE +** PENDING -> EXCLUSIVE +** +** This routine will only increase a lock. The winUnlock() routine +** erases all locks at once and returns us immediately to locking level 0. +** It is not possible to lower the locking level one step at a time. You +** must go straight to locking level 0. +*/ +static int winLock(sqlite3_file *id, int locktype){ + int rc = SQLITE_OK; /* Return code from subroutines */ + int res = 1; /* Result of a Windows lock call */ + int newLocktype; /* Set pFile->locktype to this value before exiting */ + int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */ + winFile *pFile = (winFile*)id; + DWORD lastErrno = NO_ERROR; + + assert( id!=0 ); + OSTRACE(("LOCK file=%p, oldLock=%d(%d), newLock=%d\n", + pFile->h, pFile->locktype, pFile->sharedLockByte, locktype)); + + /* If there is already a lock of this type or more restrictive on the + ** OsFile, do nothing. Don't use the end_lock: exit path, as + ** sqlite3OsEnterMutex() hasn't been called yet. + */ + if( pFile->locktype>=locktype ){ + OSTRACE(("LOCK-HELD file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } + + /* Do not allow any kind of write-lock on a read-only database + */ + if( (pFile->ctrlFlags & WINFILE_RDONLY)!=0 && locktype>=RESERVED_LOCK ){ + return SQLITE_IOERR_LOCK; + } + + /* Make sure the locking sequence is correct + */ + assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK ); + assert( locktype!=PENDING_LOCK ); + assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK ); + + /* Lock the PENDING_LOCK byte if we need to acquire an EXCLUSIVE lock or + ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of + ** the PENDING_LOCK byte is temporary. + */ + newLocktype = pFile->locktype; + if( locktype==SHARED_LOCK + || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK) + ){ + int cnt = 3; + + /* Flags for the LockFileEx() call. This should be an exclusive lock if + ** this call is to obtain EXCLUSIVE, or a shared lock if this call is to + ** obtain SHARED. */ + int flags = LOCKFILE_FAIL_IMMEDIATELY; + if( locktype==EXCLUSIVE_LOCK ){ + flags |= LOCKFILE_EXCLUSIVE_LOCK; + } + while( cnt>0 ){ + /* Try 3 times to get the pending lock. This is needed to work + ** around problems caused by indexing and/or anti-virus software on + ** Windows systems. + ** + ** If you are using this code as a model for alternative VFSes, do not + ** copy this retry logic. It is a hack intended for Windows only. */ + res = winLockFile(&pFile->h, flags, PENDING_BYTE, 0, 1, 0); + if( res ) break; + + lastErrno = osGetLastError(); + OSTRACE(("LOCK-PENDING-FAIL file=%p, count=%d, result=%d\n", + pFile->h, cnt, res + )); + + if( lastErrno==ERROR_INVALID_HANDLE ){ + pFile->lastErrno = lastErrno; + rc = SQLITE_IOERR_LOCK; + OSTRACE(("LOCK-FAIL file=%p, count=%d, rc=%s\n", + pFile->h, cnt, sqlite3ErrName(rc) + )); + return rc; + } + + cnt--; + if( cnt>0 ) sqlite3_win32_sleep(1); + } + gotPendingLock = res; + } + + /* Acquire a shared lock + */ + if( locktype==SHARED_LOCK && res ){ + assert( pFile->locktype==NO_LOCK ); +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + res = winGetReadLock(pFile, pFile->bBlockOnConnect); +#else + res = winGetReadLock(pFile, 0); +#endif + if( res ){ + newLocktype = SHARED_LOCK; + }else{ + lastErrno = osGetLastError(); + } + } + + /* Acquire a RESERVED lock + */ + if( locktype==RESERVED_LOCK && res ){ + assert( pFile->locktype==SHARED_LOCK ); + res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0); + if( res ){ + newLocktype = RESERVED_LOCK; + }else{ + lastErrno = osGetLastError(); + } + } + + /* Acquire a PENDING lock + */ + if( locktype==EXCLUSIVE_LOCK && res ){ + newLocktype = PENDING_LOCK; + gotPendingLock = 0; + } + + /* Acquire an EXCLUSIVE lock + */ + if( locktype==EXCLUSIVE_LOCK && res ){ + assert( pFile->locktype>=SHARED_LOCK ); + (void)winUnlockReadLock(pFile); + res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0, + SHARED_SIZE, 0); + if( res ){ + newLocktype = EXCLUSIVE_LOCK; + }else{ + lastErrno = osGetLastError(); + winGetReadLock(pFile, 0); + } + } + + /* If we are holding a PENDING lock that ought to be released, then + ** release it now. + */ + if( gotPendingLock && locktype==SHARED_LOCK ){ + winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0); + } + + /* Update the state of the lock has held in the file descriptor then + ** return the appropriate result code. + */ + if( res ){ + rc = SQLITE_OK; + }else{ + pFile->lastErrno = lastErrno; + rc = SQLITE_BUSY; + OSTRACE(("LOCK-FAIL file=%p, wanted=%d, got=%d\n", + pFile->h, locktype, newLocktype)); + } + pFile->locktype = (u8)newLocktype; + OSTRACE(("LOCK file=%p, lock=%d, rc=%s\n", + pFile->h, pFile->locktype, sqlite3ErrName(rc))); + return rc; +} + +/* +** This routine checks if there is a RESERVED lock held on the specified +** file by this or any other process. If such a lock is held, return +** non-zero, otherwise zero. +*/ +static int winCheckReservedLock(sqlite3_file *id, int *pResOut){ + int res; + winFile *pFile = (winFile*)id; + + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); + OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p\n", pFile->h, pResOut)); + + assert( id!=0 ); + if( pFile->locktype>=RESERVED_LOCK ){ + res = 1; + OSTRACE(("TEST-WR-LOCK file=%p, result=%d (local)\n", pFile->h, res)); + }else{ + res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE,0,1,0); + if( res ){ + winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); + } + res = !res; + OSTRACE(("TEST-WR-LOCK file=%p, result=%d (remote)\n", pFile->h, res)); + } + *pResOut = res; + OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n", + pFile->h, pResOut, *pResOut)); + return SQLITE_OK; +} + +/* +** Lower the locking level on file descriptor id to locktype. locktype +** must be either NO_LOCK or SHARED_LOCK. +** +** If the locking level of the file descriptor is already at or below +** the requested locking level, this routine is a no-op. +** +** It is not possible for this routine to fail if the second argument +** is NO_LOCK. If the second argument is SHARED_LOCK then this routine +** might return SQLITE_IOERR; +*/ +static int winUnlock(sqlite3_file *id, int locktype){ + int type; + winFile *pFile = (winFile*)id; + int rc = SQLITE_OK; + assert( pFile!=0 ); + assert( locktype<=SHARED_LOCK ); + OSTRACE(("UNLOCK file=%p, oldLock=%d(%d), newLock=%d\n", + pFile->h, pFile->locktype, pFile->sharedLockByte, locktype)); + type = pFile->locktype; + if( type>=EXCLUSIVE_LOCK ){ + winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); + if( locktype==SHARED_LOCK && !winGetReadLock(pFile, 0) ){ + /* This should never happen. We should always be able to + ** reacquire the read lock */ + rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(), + "winUnlock", pFile->zPath); + } + } + if( type>=RESERVED_LOCK ){ + winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); + } + if( locktype==NO_LOCK && type>=SHARED_LOCK ){ + winUnlockReadLock(pFile); + } + if( type>=PENDING_LOCK ){ + winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0); + } + pFile->locktype = (u8)locktype; + OSTRACE(("UNLOCK file=%p, lock=%d, rc=%s\n", + pFile->h, pFile->locktype, sqlite3ErrName(rc))); + return rc; +} + +/****************************************************************************** +****************************** No-op Locking ********************************** +** +** Of the various locking implementations available, this is by far the +** simplest: locking is ignored. No attempt is made to lock the database +** file for reading or writing. +** +** This locking mode is appropriate for use on read-only databases +** (ex: databases that are burned into CD-ROM, for example.) It can +** also be used if the application employs some external mechanism to +** prevent simultaneous access of the same database by two or more +** database connections. But there is a serious risk of database +** corruption if this locking mode is used in situations where multiple +** database connections are accessing the same database file at the same +** time and one or more of those connections are writing. +*/ + +static int winNolockLock(sqlite3_file *id, int locktype){ + UNUSED_PARAMETER(id); + UNUSED_PARAMETER(locktype); + return SQLITE_OK; +} + +static int winNolockCheckReservedLock(sqlite3_file *id, int *pResOut){ + UNUSED_PARAMETER(id); + UNUSED_PARAMETER(pResOut); + return SQLITE_OK; +} + +static int winNolockUnlock(sqlite3_file *id, int locktype){ + UNUSED_PARAMETER(id); + UNUSED_PARAMETER(locktype); + return SQLITE_OK; +} + +/******************* End of the no-op lock implementation ********************* +******************************************************************************/ + +/* +** If *pArg is initially negative then this is a query. Set *pArg to +** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set. +** +** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags. +*/ +static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){ + if( *pArg<0 ){ + *pArg = (pFile->ctrlFlags & mask)!=0; + }else if( (*pArg)==0 ){ + pFile->ctrlFlags &= ~mask; + }else{ + pFile->ctrlFlags |= mask; + } +} + +/* Forward references to VFS helper methods used for temporary files */ +static int winGetTempname(sqlite3_vfs *, char **); +static int winIsDir(const void *); +static BOOL winIsLongPathPrefix(const char *); +static BOOL winIsDriveLetterAndColon(const char *); + +/* +** Control and query of the open file handle. +*/ +static int winFileControl(sqlite3_file *id, int op, void *pArg){ + winFile *pFile = (winFile*)id; + OSTRACE(("FCNTL file=%p, op=%d, pArg=%p\n", pFile->h, op, pArg)); + switch( op ){ + case SQLITE_FCNTL_LOCKSTATE: { + *(int*)pArg = pFile->locktype; + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } + case SQLITE_FCNTL_LAST_ERRNO: { + *(int*)pArg = (int)pFile->lastErrno; + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } + case SQLITE_FCNTL_CHUNK_SIZE: { + pFile->szChunk = *(int *)pArg; + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } + case SQLITE_FCNTL_SIZE_HINT: { + if( pFile->szChunk>0 ){ + sqlite3_int64 oldSz; + int rc = winFileSize(id, &oldSz); + if( rc==SQLITE_OK ){ + sqlite3_int64 newSz = *(sqlite3_int64*)pArg; + if( newSz>oldSz ){ + SimulateIOErrorBenign(1); + rc = winTruncate(id, newSz); + SimulateIOErrorBenign(0); + } + } + OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); + return rc; + } + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } + case SQLITE_FCNTL_PERSIST_WAL: { + winModeBit(pFile, WINFILE_PERSIST_WAL, (int*)pArg); + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } + case SQLITE_FCNTL_POWERSAFE_OVERWRITE: { + winModeBit(pFile, WINFILE_PSOW, (int*)pArg); + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } + case SQLITE_FCNTL_VFSNAME: { + *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName); + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } + case SQLITE_FCNTL_WIN32_AV_RETRY: { + int *a = (int*)pArg; + if( a[0]>0 ){ + winIoerrRetry = a[0]; + }else{ + a[0] = winIoerrRetry; + } + if( a[1]>0 ){ + winIoerrRetryDelay = a[1]; + }else{ + a[1] = winIoerrRetryDelay; + } + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } + case SQLITE_FCNTL_WIN32_GET_HANDLE: { + LPHANDLE phFile = (LPHANDLE)pArg; + *phFile = pFile->h; + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); + return SQLITE_OK; + } +#ifdef SQLITE_TEST + case SQLITE_FCNTL_WIN32_SET_HANDLE: { + LPHANDLE phFile = (LPHANDLE)pArg; + HANDLE hOldFile = pFile->h; + pFile->h = *phFile; + *phFile = hOldFile; + OSTRACE(("FCNTL oldFile=%p, newFile=%p, rc=SQLITE_OK\n", + hOldFile, pFile->h)); + return SQLITE_OK; + } +#endif + case SQLITE_FCNTL_NULL_IO: { + (void)osCloseHandle(pFile->h); + pFile->h = NULL; + return SQLITE_OK; + } + case SQLITE_FCNTL_TEMPFILENAME: { + char *zTFile = 0; + int rc = winGetTempname(pFile->pVfs, &zTFile); + if( rc==SQLITE_OK ){ + *(char**)pArg = zTFile; + } + OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); + return rc; + } +#if SQLITE_MAX_MMAP_SIZE>0 + case SQLITE_FCNTL_MMAP_SIZE: { + i64 newLimit = *(i64*)pArg; + int rc = SQLITE_OK; + if( newLimit>sqlite3GlobalConfig.mxMmap ){ + newLimit = sqlite3GlobalConfig.mxMmap; + } + + /* The value of newLimit may be eventually cast to (SIZE_T) and passed + ** to MapViewOfFile(). Restrict its value to 2GB if (SIZE_T) is not at + ** least a 64-bit type. */ + if( newLimit>0 && sizeof(SIZE_T)<8 ){ + newLimit = (newLimit & 0x7FFFFFFF); + } + + *(i64*)pArg = pFile->mmapSizeMax; + if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){ + pFile->mmapSizeMax = newLimit; + if( pFile->mmapSize>0 ){ + winUnmapfile(pFile); + rc = winMapfile(pFile, -1); + } + } + OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); + return rc; + } +#endif + +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + case SQLITE_FCNTL_LOCK_TIMEOUT: { + int iOld = pFile->iBusyTimeout; + int iNew = *(int*)pArg; +#if SQLITE_ENABLE_SETLK_TIMEOUT==1 + pFile->iBusyTimeout = (iNew < 0) ? INFINITE : (DWORD)iNew; +#elif SQLITE_ENABLE_SETLK_TIMEOUT==2 + pFile->iBusyTimeout = (DWORD)(!!iNew); +#else +# error "SQLITE_ENABLE_SETLK_TIMEOUT must be set to 1 or 2" +#endif + *(int*)pArg = iOld; + return SQLITE_OK; + } + case SQLITE_FCNTL_BLOCK_ON_CONNECT: { + int iNew = *(int*)pArg; + pFile->bBlockOnConnect = iNew; + return SQLITE_OK; + } +#endif /* SQLITE_ENABLE_SETLK_TIMEOUT */ + +#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT) + case SQLITE_FCNTL_FILESTAT: { + sqlite3_str *pStr = (sqlite3_str*)pArg; + sqlite3_str_appendf(pStr, "{\"h\":%llu", (sqlite3_uint64)pFile->h); + sqlite3_str_appendf(pStr, ",\"vfs\":\"%s\"", pFile->pVfs->zName); + if( pFile->locktype ){ + static const char *azLock[] = { "SHARED", "RESERVED", + "PENDING", "EXCLUSIVE" }; + sqlite3_str_appendf(pStr, ",\"locktype\":\"%s\"", + azLock[pFile->locktype-1]); + } +#if SQLITE_MAX_MMAP_SIZE>0 + if( pFile->mmapSize ){ + sqlite3_str_appendf(pStr, ",\"mmapSize\":%lld", pFile->mmapSize); + sqlite3_str_appendf(pStr, ",\"nFetchOut\":%d", pFile->nFetchOut); + } +#endif + sqlite3_str_append(pStr, "}", 1); + return SQLITE_OK; + } +#endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */ + + } + OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h)); + return SQLITE_NOTFOUND; +} + +/* +** Return the sector size in bytes of the underlying block device for +** the specified file. This is almost always 512 bytes, but may be +** larger for some devices. +** +** SQLite code assumes this function cannot fail. It also assumes that +** if two files are created in the same file-system directory (i.e. +** a database and its journal file) that the sector size will be the +** same for both. +*/ +static int winSectorSize(sqlite3_file *id){ + (void)id; + return SQLITE_DEFAULT_SECTOR_SIZE; +} + +/* +** Return a vector of device characteristics. +*/ +static int winDeviceCharacteristics(sqlite3_file *id){ + winFile *p = (winFile*)id; + return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | SQLITE_IOCAP_SUBPAGE_READ | + ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0); +} + +/* +** Windows will only let you create file view mappings +** on allocation size granularity boundaries. +** During sqlite3_os_init() we do a GetSystemInfo() +** to get the granularity size. +*/ +static SYSTEM_INFO winSysInfo; + +/* +** Convert a UTF-8 filename into whatever form the underlying +** operating system wants filenames in. Space to hold the result +** is obtained from malloc and must be freed by the calling +** function +** +** On Cygwin, 3 possible input forms are accepted: +** - If the filename starts with ":/" or ":\", +** it is converted to UTF-16 as-is. +** - If the filename contains '/', it is assumed to be a +** Cygwin absolute path, it is converted to a win32 +** absolute path in UTF-16. +** - Otherwise it must be a filename only, the win32 filename +** is returned in UTF-16. +** Note: If the function cygwin_conv_path() fails, only +** UTF-8 -> UTF-16 conversion will be done. This can only +** happen when the file path >32k, in which case winUtf8ToUnicode() +** will fail too. +*/ +static void *winConvertFromUtf8Filename(const char *zFilename){ + void *zConverted = 0; + if( osIsNT() ){ +#ifdef __CYGWIN__ + int nChar; + LPWSTR zWideFilename; + + if( osCygwin_conv_path && !(winIsDriveLetterAndColon(zFilename) + && winIsDirSep(zFilename[2])) ){ + i64 nByte; + int convertflag = CCP_POSIX_TO_WIN_W; + if( !strchr(zFilename, '/') ) convertflag |= CCP_RELATIVE; + nByte = (i64)osCygwin_conv_path(convertflag, + zFilename, 0, 0); + if( nByte>0 ){ + zConverted = sqlite3MallocZero(12+(u64)nByte); + if ( zConverted==0 ){ + return zConverted; + } + zWideFilename = zConverted; + /* Filenames should be prefixed, except when converted + * full path already starts with "\\?\". */ + if( osCygwin_conv_path(convertflag, zFilename, + zWideFilename+4, nByte)==0 ){ + if( (convertflag&CCP_RELATIVE) ){ + memmove(zWideFilename, zWideFilename+4, nByte); + }else if( memcmp(zWideFilename+4, L"\\\\", 4) ){ + memcpy(zWideFilename, L"\\\\?\\", 8); + }else if( zWideFilename[6]!='?' ){ + memmove(zWideFilename+6, zWideFilename+4, nByte); + memcpy(zWideFilename, L"\\\\?\\UNC", 14); + }else{ + memmove(zWideFilename, zWideFilename+4, nByte); + } + return zConverted; + } + sqlite3_free(zConverted); + } + } + nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); + if( nChar==0 ){ + return 0; + } + zWideFilename = sqlite3MallocZero( nChar*sizeof(WCHAR)+12 ); + if( zWideFilename==0 ){ + return 0; + } + nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, + zWideFilename, nChar); + if( nChar==0 ){ + sqlite3_free(zWideFilename); + zWideFilename = 0; + }else if( nChar>MAX_PATH + && winIsDriveLetterAndColon(zFilename) + && winIsDirSep(zFilename[2]) ){ + memmove(zWideFilename+4, zWideFilename, nChar*sizeof(WCHAR)); + zWideFilename[2] = '\\'; + memcpy(zWideFilename, L"\\\\?\\", 8); + }else if( nChar>MAX_PATH + && winIsDirSep(zFilename[0]) && winIsDirSep(zFilename[1]) + && zFilename[2] != '?' ){ + memmove(zWideFilename+6, zWideFilename, nChar*sizeof(WCHAR)); + memcpy(zWideFilename, L"\\\\?\\UNC", 14); + } + zConverted = zWideFilename; +#else + zConverted = winUtf8ToUnicode(zFilename); +#endif /* __CYGWIN__ */ + } +#if defined(SQLITE_WIN32_HAS_ANSI) && defined(_WIN32) + else{ + zConverted = winUtf8ToMbcs(zFilename, osAreFileApisANSI()); + } +#endif + /* caller will handle out of memory */ + return zConverted; +} + +#ifndef SQLITE_OMIT_WAL + +/* +** Helper functions to obtain and relinquish the global mutex. The +** global mutex is used to protect the winLockInfo objects used by +** this file, all of which may be shared by multiple threads. +** +** Function winShmMutexHeld() is used to assert() that the global mutex +** is held when required. This function is only used as part of assert() +** statements. e.g. +** +** winShmEnterMutex() +** assert( winShmMutexHeld() ); +** winShmLeaveMutex() +*/ +static sqlite3_mutex *winBigLock = 0; +static void winShmEnterMutex(void){ + sqlite3_mutex_enter(winBigLock); +} +static void winShmLeaveMutex(void){ + sqlite3_mutex_leave(winBigLock); +} +#ifndef NDEBUG +static int winShmMutexHeld(void) { + return sqlite3_mutex_held(winBigLock); +} +#endif + +/* +** Object used to represent a single file opened and mmapped to provide +** shared memory. When multiple threads all reference the same +** log-summary, each thread has its own winFile object, but they all +** point to a single instance of this object. In other words, each +** log-summary is opened only once per process. +** +** winShmMutexHeld() must be true when creating or destroying +** this object, or while editing the global linked list that starts +** at winShmNodeList. +** +** When reading or writing the linked list starting at winShmNode.pWinShmList, +** pShmNode->mutex must be held. +** +** The following fields are constant after the object is created: +** +** zFilename +** hSharedShm +** mutex +** bUseSharedLockHandle +** +** Either winShmNode.mutex must be held or winShmNode.pWinShmList==0 and +** winShmMutexHeld() is true when reading or writing any other field +** in this structure. +** +** File-handle hSharedShm is always used to (a) take the DMS lock, (b) +** truncate the *-shm file if the DMS-locking protocol demands it, and +** (c) map regions of the *-shm file into memory using MapViewOfFile() +** or similar. If bUseSharedLockHandle is true, then other locks are also +** taken on hSharedShm. Or, if bUseSharedLockHandle is false, then other +** locks are taken using each connection's winShm.hShm handles. +*/ +struct winShmNode { + sqlite3_mutex *mutex; /* Mutex to access this object */ + char *zFilename; /* Name of the file */ + HANDLE hSharedShm; /* File handle open on zFilename */ + int bUseSharedLockHandle; /* True to use hSharedShm for everything */ + + int isUnlocked; /* DMS lock has not yet been obtained */ + int isReadonly; /* True if read-only */ + int szRegion; /* Size of shared-memory regions */ + int nRegion; /* Size of array apRegion */ + + struct ShmRegion { + HANDLE hMap; /* File handle from CreateFileMapping */ + void *pMap; + } *aRegion; + DWORD lastErrno; /* The Windows errno from the last I/O error */ + + winShm *pWinShmList; /* List of winShm objects with ptrs to this */ + + winShmNode *pNext; /* Next in list of all winShmNode objects */ +#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) + u8 nextShmId; /* Next available winShm.id value */ +#endif +}; + +/* +** A global array of all winShmNode objects. +** +** The winShmMutexHeld() must be true while reading or writing this list. +*/ +static winShmNode *winShmNodeList = 0; + +/* +** Structure used internally by this VFS to record the state of an +** open shared memory connection. There is one such structure for each +** winFile open on a wal mode database. +*/ +struct winShm { + winShmNode *pShmNode; /* The underlying winShmNode object */ + u16 sharedMask; /* Mask of shared locks held */ + u16 exclMask; /* Mask of exclusive locks held */ + HANDLE hShm; /* File-handle on *-shm file. For locking. */ + int bReadonly; /* True if hShm is opened read-only */ +#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) + u8 id; /* Id of this connection with its winShmNode */ +#endif + winShm *pWinShmNext; /* Next winShm object on same winShmNode */ +}; + +/* +** Constants used for locking +*/ +#define WIN_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ +#define WIN_SHM_DMS (WIN_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ + +/* Forward references to VFS methods */ +static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*); +static int winDelete(sqlite3_vfs *,const char*,int); + +/* +** Purge the winShmNodeList list of all entries with winShmNode.pWinShmList==0. +** +** This is not a VFS shared-memory method; it is a utility function called +** by VFS shared-memory methods. +*/ +static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){ + winShmNode **pp; + winShmNode *p; + assert( winShmMutexHeld() ); + OSTRACE(("SHM-PURGE pid=%lu, deleteFlag=%d\n", + osGetCurrentProcessId(), deleteFlag)); + pp = &winShmNodeList; + while( (p = *pp)!=0 ){ + if( p->pWinShmList==0 ){ + int i; + if( p->mutex ){ sqlite3_mutex_free(p->mutex); } + for(i=0; inRegion; i++){ + BOOL bRc = osUnmapViewOfFile(p->aRegion[i].pMap); + OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n", + osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); + UNUSED_VARIABLE_VALUE(bRc); + bRc = osCloseHandle(p->aRegion[i].hMap); + OSTRACE(("SHM-PURGE-CLOSE pid=%lu, region=%d, rc=%s\n", + osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); + UNUSED_VARIABLE_VALUE(bRc); + } + winHandleClose(p->hSharedShm); + if( deleteFlag ){ + SimulateIOErrorBenign(1); + sqlite3BeginBenignMalloc(); + winDelete(pVfs, p->zFilename, 0); + sqlite3EndBenignMalloc(); + SimulateIOErrorBenign(0); + } + *pp = p->pNext; + sqlite3_free(p->aRegion); + sqlite3_free(p); + }else{ + pp = &p->pNext; + } + } +} + +/* +** The DMS lock has not yet been taken on the shm file associated with +** pShmNode. Take the lock. Truncate the *-shm file if required. +** Return SQLITE_OK if successful, or an SQLite error code otherwise. +*/ +static int winLockSharedMemory(winShmNode *pShmNode, DWORD nMs){ + HANDLE h = pShmNode->hSharedShm; + int rc = SQLITE_OK; + + assert( sqlite3_mutex_held(pShmNode->mutex) ); + rc = winHandleLockTimeout(h, WIN_SHM_DMS, 1, 1, 0); + if( rc==SQLITE_OK ){ + /* We have an EXCLUSIVE lock on the DMS byte. This means that this + ** is the first process to open the file. Truncate it to zero bytes + ** in this case. */ + if( pShmNode->isReadonly ){ + rc = SQLITE_READONLY_CANTINIT; + }else{ + rc = winHandleTruncate(h, 0); + } + + /* Release the EXCLUSIVE lock acquired above. */ + winUnlockFile(&h, WIN_SHM_DMS, 0, 1, 0); + }else if( (rc & 0xFF)==SQLITE_BUSY ){ + rc = SQLITE_OK; + } + + if( rc==SQLITE_OK ){ + /* Take a SHARED lock on the DMS byte. */ + rc = winHandleLockTimeout(h, WIN_SHM_DMS, 1, 0, nMs); + if( rc==SQLITE_OK ){ + pShmNode->isUnlocked = 0; + } + } + + return rc; +} + + +/* +** This function is used to open a handle on a *-shm file. +** +** If SQLITE_ENABLE_SETLK_TIMEOUT is defined at build time, then the file +** is opened with FILE_FLAG_OVERLAPPED specified. If not, it is not. +*/ +static int winHandleOpen( + const char *zUtf8, /* File to open */ + int *pbReadonly, /* IN/OUT: True for readonly handle */ + HANDLE *ph /* OUT: New HANDLE for file */ +){ + int rc = SQLITE_OK; + void *zConverted = 0; + int bReadonly = *pbReadonly; + HANDLE h = INVALID_HANDLE_VALUE; + +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + const DWORD flag_overlapped = FILE_FLAG_OVERLAPPED; +#else + const DWORD flag_overlapped = 0; +#endif + + /* Convert the filename to the system encoding. */ + zConverted = winConvertFromUtf8Filename(zUtf8); + if( zConverted==0 ){ + OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8)); + rc = SQLITE_IOERR_NOMEM_BKPT; + goto winopenfile_out; + } + + /* Ensure the file we are trying to open is not actually a directory. */ + if( winIsDir(zConverted) ){ + OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8)); + rc = SQLITE_CANTOPEN_ISDIR; + goto winopenfile_out; + } + + /* TODO: platforms. + ** TODO: retry-on-ioerr. + */ + if( osIsNT() ){ + h = osCreateFileW((LPCWSTR)zConverted, /* lpFileName */ + (GENERIC_READ | (bReadonly ? 0 : GENERIC_WRITE)), /* dwDesiredAccess */ + FILE_SHARE_READ | FILE_SHARE_WRITE, /* dwShareMode */ + NULL, /* lpSecurityAttributes */ + OPEN_ALWAYS, /* dwCreationDisposition */ + FILE_ATTRIBUTE_NORMAL|flag_overlapped, + NULL + ); + }else{ + /* Due to pre-processor directives earlier in this file, + ** SQLITE_WIN32_HAS_ANSI is always defined if osIsNT() is false. */ +#ifdef SQLITE_WIN32_HAS_ANSI + h = osCreateFileA((LPCSTR)zConverted, + (GENERIC_READ | (bReadonly ? 0 : GENERIC_WRITE)), /* dwDesiredAccess */ + FILE_SHARE_READ | FILE_SHARE_WRITE, /* dwShareMode */ + NULL, /* lpSecurityAttributes */ + OPEN_ALWAYS, /* dwCreationDisposition */ + FILE_ATTRIBUTE_NORMAL|flag_overlapped, + NULL + ); +#endif + } + + if( h==INVALID_HANDLE_VALUE ){ + if( bReadonly==0 ){ + bReadonly = 1; + rc = winHandleOpen(zUtf8, &bReadonly, &h); + }else{ + rc = SQLITE_CANTOPEN_BKPT; + } + } + + winopenfile_out: + sqlite3_free(zConverted); + *pbReadonly = bReadonly; + *ph = h; + return rc; +} + +/* +** Close pDbFd's connection to shared-memory. Delete the underlying +** *-shm file if deleteFlag is true. +*/ +static int winCloseSharedMemory(winFile *pDbFd, int deleteFlag){ + winShm *p; /* The connection to be closed */ + winShm **pp; /* Iterator for pShmNode->pWinShmList */ + winShmNode *pShmNode; /* The underlying shared-memory file */ + + p = pDbFd->pShm; + if( p==0 ) return SQLITE_OK; + if( p->hShm!=INVALID_HANDLE_VALUE ){ + osCloseHandle(p->hShm); + } + + winShmEnterMutex(); + pShmNode = p->pShmNode; + + /* Remove this connection from the winShmNode.pWinShmList list */ + sqlite3_mutex_enter(pShmNode->mutex); + for(pp=&pShmNode->pWinShmList; *pp!=p; pp=&(*pp)->pWinShmNext){} + *pp = p->pWinShmNext; + sqlite3_mutex_leave(pShmNode->mutex); + + winShmPurge(pDbFd->pVfs, deleteFlag); + winShmLeaveMutex(); + + /* Free the connection p */ + sqlite3_free(p); + pDbFd->pShm = 0; + return SQLITE_OK; +} + +/* +** testfixture builds may set this global variable to true via a +** Tcl interface. This forces the VFS to use the locking normally +** only used for UNC paths for all files. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_win_test_unc_locking = 0; +#else +# define sqlite3_win_test_unc_locking 0 +#endif + +/* +** Return true if the string passed as the only argument is likely +** to be a UNC path. Return false if note. +** +** Return true if: +** +** (1) The name begins with "\\" +** (2) But does not begin with "\\?\C:\" where C can be any alphabetic +** character. +** +** For testing, also return true in all cases if the global variable +** sqlite3_win_test_unc_locking is true. +*/ +static int winIsUNCPath(const char *zFile){ + if( zFile[0]=='\\' && zFile[1]=='\\' ){ + if( zFile[2]=='?' + && zFile[3]=='\\' + && sqlite3Isalpha(zFile[4]) + && zFile[5]==':' + && winIsDirSep(zFile[6]) + ){ + return sqlite3_win_test_unc_locking; + }else{ + return 1; + } + } + return sqlite3_win_test_unc_locking; +} + +/* +** Open the shared-memory area associated with database file pDbFd. +*/ +static int winOpenSharedMemory(winFile *pDbFd){ + struct winShm *p; /* The connection to be opened */ + winShmNode *pShmNode = 0; /* The underlying mmapped file */ + int rc = SQLITE_OK; /* Result code */ + winShmNode *pNew; /* Newly allocated winShmNode */ + int nName; /* Size of zName in bytes */ + + assert( pDbFd->pShm==0 ); /* Not previously opened */ + + /* Allocate space for the new sqlite3_shm object. Also speculatively + ** allocate space for a new winShmNode and filename. */ + p = sqlite3MallocZero( sizeof(*p) ); + if( p==0 ) return SQLITE_IOERR_NOMEM_BKPT; + nName = sqlite3Strlen30(pDbFd->zPath); + pNew = sqlite3MallocZero( sizeof(*pShmNode) + (i64)nName + 17 ); + if( pNew==0 ){ + sqlite3_free(p); + return SQLITE_IOERR_NOMEM_BKPT; + } + pNew->zFilename = (char*)&pNew[1]; + pNew->hSharedShm = INVALID_HANDLE_VALUE; + pNew->isUnlocked = 1; + pNew->bUseSharedLockHandle = winIsUNCPath(pDbFd->zPath); + sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath); + sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename); + + /* Look to see if there is an existing winShmNode that can be used. + ** If no matching winShmNode currently exists, then create a new one. */ + winShmEnterMutex(); + for(pShmNode = winShmNodeList; pShmNode; pShmNode=pShmNode->pNext){ + /* TBD need to come up with better match here. Perhaps + ** use FILE_ID_BOTH_DIR_INFO Structure. */ + if( sqlite3StrICmp(pShmNode->zFilename, pNew->zFilename)==0 ) break; + } + if( pShmNode==0 ){ + pShmNode = pNew; + + /* Allocate a mutex for this winShmNode object, if one is required. */ + if( sqlite3GlobalConfig.bCoreMutex ){ + pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( pShmNode->mutex==0 ) rc = SQLITE_IOERR_NOMEM_BKPT; + } + + /* Open a file-handle to use for mappings, and for the DMS lock. */ + if( rc==SQLITE_OK ){ + HANDLE h = INVALID_HANDLE_VALUE; + pShmNode->isReadonly = sqlite3_uri_boolean(pDbFd->zPath,"readonly_shm",0); + rc = winHandleOpen(pNew->zFilename, &pShmNode->isReadonly, &h); + pShmNode->hSharedShm = h; + } + + /* If successful, link the new winShmNode into the global list. If an + ** error occurred, free the object. */ + if( rc==SQLITE_OK ){ + pShmNode->pNext = winShmNodeList; + winShmNodeList = pShmNode; + pNew = 0; + }else{ + sqlite3_mutex_free(pShmNode->mutex); + if( pShmNode->hSharedShm!=INVALID_HANDLE_VALUE ){ + osCloseHandle(pShmNode->hSharedShm); + } + } + } + + /* If no error has occurred, link the winShm object to the winShmNode and + ** the winShm to pDbFd. */ + if( rc==SQLITE_OK ){ + sqlite3_mutex_enter(pShmNode->mutex); + p->pShmNode = pShmNode; + p->pWinShmNext = pShmNode->pWinShmList; + pShmNode->pWinShmList = p; +#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) + p->id = pShmNode->nextShmId++; +#endif + pDbFd->pShm = p; + sqlite3_mutex_leave(pShmNode->mutex); + }else if( p ){ + sqlite3_free(p); + } + + assert( rc!=SQLITE_OK || pShmNode->isUnlocked==0 || pShmNode->nRegion==0 ); + winShmLeaveMutex(); + sqlite3_free(pNew); + + /* Open a file-handle on the *-shm file for this connection. This file-handle + ** is only used for locking. The mapping of the *-shm file is created using + ** the shared file handle in winShmNode.hSharedShm. */ + if( rc==SQLITE_OK && pShmNode->bUseSharedLockHandle==0 ){ + p->bReadonly = sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0); + rc = winHandleOpen(pShmNode->zFilename, &p->bReadonly, &p->hShm); + if( rc!=SQLITE_OK ){ + assert( p->hShm==INVALID_HANDLE_VALUE ); + winCloseSharedMemory(pDbFd, 0); + } + } + + return rc; +} + +/* +** Close a connection to shared-memory. Delete the underlying +** storage if deleteFlag is true. +*/ +static int winShmUnmap( + sqlite3_file *fd, /* Database holding shared memory */ + int deleteFlag /* Delete after closing if true */ +){ + return winCloseSharedMemory((winFile*)fd, deleteFlag); +} + +/* +** Change the lock state for a shared-memory segment. +*/ +static int winShmLock( + sqlite3_file *fd, /* Database file holding the shared memory */ + int ofst, /* First lock to acquire or release */ + int n, /* Number of locks to acquire or release */ + int flags /* What to do with the lock */ +){ + winFile *pDbFd = (winFile*)fd; /* Connection holding shared memory */ + winShm *p = pDbFd->pShm; /* The shared memory being locked */ + winShmNode *pShmNode; + int rc = SQLITE_OK; /* Result code */ + u16 mask = (u16)((1U<<(ofst+n)) - (1U<pShmNode; + if( NEVER(pShmNode==0) ) return SQLITE_IOERR_SHMLOCK; + + assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK ); + assert( n>=1 ); + assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED) + || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE) + || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED) + || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); + assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); + + /* Check that, if this to be a blocking lock, no locks that occur later + ** in the following list than the lock being obtained are already held: + ** + ** 1. Recovery lock (ofst==2). + ** 2. Checkpointer lock (ofst==1). + ** 3. Write lock (ofst==0). + ** 4. Read locks (ofst>=3 && ofstexclMask|p->sharedMask); + assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( + (ofst!=2 || lockMask==0) + && (ofst!=1 || lockMask==0 || lockMask==2) + && (ofst!=0 || lockMask<3) + && (ofst<3 || lockMask<(1<exclMask & mask) + ); + if( ((flags & SQLITE_SHM_UNLOCK) && ((p->exclMask|p->sharedMask) & mask)) + || (flags==(SQLITE_SHM_SHARED|SQLITE_SHM_LOCK) && 0==(p->sharedMask & mask)) + || (flags==(SQLITE_SHM_EXCLUSIVE|SQLITE_SHM_LOCK)) + ){ + HANDLE h = p->hShm; + + if( flags & SQLITE_SHM_UNLOCK ){ + /* Case (a) - unlock. */ + + assert( (p->exclMask & p->sharedMask)==0 ); + assert( !(flags & SQLITE_SHM_EXCLUSIVE) || (p->exclMask & mask)==mask ); + assert( !(flags & SQLITE_SHM_SHARED) || (p->sharedMask & mask)==mask ); + + assert( !(flags & SQLITE_SHM_SHARED) || n==1 ); + if( pShmNode->bUseSharedLockHandle ){ + h = pShmNode->hSharedShm; + if( flags & SQLITE_SHM_SHARED ){ + winShm *pShm; + sqlite3_mutex_enter(pShmNode->mutex); + for(pShm=pShmNode->pWinShmList; pShm; pShm=pShm->pWinShmNext){ + if( pShm!=p && (pShm->sharedMask & mask) ){ + /* Another connection within this process is also holding this + ** SHARED lock. So do not actually release the OS lock. */ + h = INVALID_HANDLE_VALUE; + break; + } + } + sqlite3_mutex_leave(pShmNode->mutex); + } + } + + if( h!=INVALID_HANDLE_VALUE ){ + rc = winHandleUnlock(h, ofst+WIN_SHM_BASE, n); + } + + /* If successful, also clear the bits in sharedMask/exclMask */ + if( rc==SQLITE_OK ){ + p->exclMask = (p->exclMask & ~mask); + p->sharedMask = (p->sharedMask & ~mask); + } + }else{ + int bExcl = ((flags & SQLITE_SHM_EXCLUSIVE) ? 1 : 0); + DWORD nMs = winFileBusyTimeout(pDbFd); + + if( pShmNode->bUseSharedLockHandle ){ + winShm *pShm; + h = pShmNode->hSharedShm; + sqlite3_mutex_enter(pShmNode->mutex); + for(pShm=pShmNode->pWinShmList; pShm; pShm=pShm->pWinShmNext){ + if( bExcl ){ + if( (pShm->sharedMask|pShm->exclMask) & mask ){ + rc = SQLITE_BUSY; + h = INVALID_HANDLE_VALUE; + } + }else{ + if( pShm->sharedMask & mask ){ + h = INVALID_HANDLE_VALUE; + }else if( pShm->exclMask & mask ){ + rc = SQLITE_BUSY; + h = INVALID_HANDLE_VALUE; + } + } + } + sqlite3_mutex_leave(pShmNode->mutex); + } + + if( h!=INVALID_HANDLE_VALUE ){ + rc = winHandleLockTimeout(h, ofst+WIN_SHM_BASE, n, bExcl, nMs); + } + if( rc==SQLITE_OK ){ + if( bExcl ){ + p->exclMask = (p->exclMask | mask); + }else{ + p->sharedMask = (p->sharedMask | mask); + } + } + } + } + + OSTRACE(( + "SHM-LOCK(%d,%d,%d) pid=%lu, id=%d, sharedMask=%03x, exclMask=%03x," + " rc=%s\n", + ofst, n, flags, + osGetCurrentProcessId(), p->id, p->sharedMask, p->exclMask, + sqlite3ErrName(rc)) + ); + return rc; +} + +/* +** Implement a memory barrier or memory fence on shared memory. +** +** All loads and stores begun before the barrier must complete before +** any load or store begun after the barrier. +*/ +static void winShmBarrier( + sqlite3_file *fd /* Database holding the shared memory */ +){ + UNUSED_PARAMETER(fd); + sqlite3MemoryBarrier(); /* compiler-defined memory barrier */ + winShmEnterMutex(); /* Also mutex, for redundancy */ + winShmLeaveMutex(); +} + +/* +** This function is called to obtain a pointer to region iRegion of the +** shared-memory associated with the database file fd. Shared-memory regions +** are numbered starting from zero. Each shared-memory region is szRegion +** bytes in size. +** +** If an error occurs, an error code is returned and *pp is set to NULL. +** +** Otherwise, if the isWrite parameter is 0 and the requested shared-memory +** region has not been allocated (by any client, including one running in a +** separate process), then *pp is set to NULL and SQLITE_OK returned. If +** isWrite is non-zero and the requested shared-memory region has not yet +** been allocated, it is allocated by this function. +** +** If the shared-memory region has already been allocated or is allocated by +** this call as described above, then it is mapped into this processes +** address space (if it is not already), *pp is set to point to the mapped +** memory and SQLITE_OK returned. +*/ +static int winShmMap( + sqlite3_file *fd, /* Handle open on database file */ + int iRegion, /* Region to retrieve */ + int szRegion, /* Size of regions */ + int isWrite, /* True to extend file if necessary */ + void volatile **pp /* OUT: Mapped memory */ +){ + winFile *pDbFd = (winFile*)fd; + winShm *pShm = pDbFd->pShm; + winShmNode *pShmNode; + DWORD protect = PAGE_READWRITE; + DWORD flags = FILE_MAP_WRITE | FILE_MAP_READ; + int rc = SQLITE_OK; + + if( !pShm ){ + rc = winOpenSharedMemory(pDbFd); + if( rc!=SQLITE_OK ) return rc; + pShm = pDbFd->pShm; + assert( pShm!=0 ); + } + pShmNode = pShm->pShmNode; + + sqlite3_mutex_enter(pShmNode->mutex); + if( pShmNode->isUnlocked ){ + /* Take the DMS lock. */ + assert( pShmNode->nRegion==0 ); + rc = winLockSharedMemory(pShmNode, winFileBusyTimeout(pDbFd)); + if( rc!=SQLITE_OK ) goto shmpage_out; + } + + assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); + if( pShmNode->nRegion<=iRegion ){ + HANDLE hShared = pShmNode->hSharedShm; + struct ShmRegion *apNew; /* New aRegion[] array */ + i64 nByte = ((i64)iRegion+1)*(i64)szRegion; /* Minimum file size */ + sqlite3_int64 sz; /* Current size of wal-index file */ + + pShmNode->szRegion = szRegion; + + /* The requested region is not mapped into this processes address space. + ** Check to see if it has been allocated (i.e. if the wal-index file is + ** large enough to contain the requested region). + */ + rc = winHandleSize(hShared, &sz); + if( rc!=SQLITE_OK ){ + rc = winLogError(rc, osGetLastError(), "winShmMap1", pDbFd->zPath); + goto shmpage_out; + } + + if( szzPath); + goto shmpage_out; + } + } + + /* Map the requested memory region into this processes address space. */ + apNew = (struct ShmRegion*)sqlite3_realloc64( + pShmNode->aRegion, ((i64)iRegion+1)*sizeof(apNew[0]) + ); + if( !apNew ){ + rc = SQLITE_IOERR_NOMEM_BKPT; + goto shmpage_out; + } + pShmNode->aRegion = apNew; + + if( pShmNode->isReadonly ){ + protect = PAGE_READONLY; + flags = FILE_MAP_READ; + } + + while( pShmNode->nRegion<=iRegion ){ + HANDLE hMap = NULL; /* file-mapping handle */ + void *pMap = 0; /* Mapped memory region */ + +#if defined(SQLITE_WIN32_HAS_WIDE) + hMap = osCreateFileMappingW(hShared, NULL, protect, 0, nByte, NULL); +#elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA + hMap = osCreateFileMappingA(hShared, NULL, protect, 0, nByte, NULL); +#endif + OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%lld, rc=%s\n", + osGetCurrentProcessId(), pShmNode->nRegion, nByte, + hMap ? "ok" : "failed")); + if( hMap ){ + i64 iOffset = pShmNode->nRegion*szRegion; + int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; + pMap = osMapViewOfFile(hMap, flags, + 0, iOffset - iOffsetShift, (i64)szRegion + iOffsetShift + ); + OSTRACE(("SHM-MAP-MAP pid=%lu, region=%d, offset=%d, size=%d, rc=%s\n", + osGetCurrentProcessId(), pShmNode->nRegion, iOffset, + szRegion, pMap ? "ok" : "failed")); + } + if( !pMap ){ + pShmNode->lastErrno = osGetLastError(); + rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno, + "winShmMap3", pDbFd->zPath); + if( hMap ) osCloseHandle(hMap); + goto shmpage_out; + } + + pShmNode->aRegion[pShmNode->nRegion].pMap = pMap; + pShmNode->aRegion[pShmNode->nRegion].hMap = hMap; + pShmNode->nRegion++; + } + } + +shmpage_out: + if( pShmNode->nRegion>iRegion ){ + i64 iOffset = (i64)iRegion*(i64)szRegion; + int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; + char *p = (char *)pShmNode->aRegion[iRegion].pMap; + *pp = (void *)&p[iOffsetShift]; + }else{ + *pp = 0; + } + if( pShmNode->isReadonly && rc==SQLITE_OK ){ + rc = SQLITE_READONLY; + } + sqlite3_mutex_leave(pShmNode->mutex); + return rc; +} + +#else +# define winShmMap 0 +# define winShmLock 0 +# define winShmBarrier 0 +# define winShmUnmap 0 +#endif /* #ifndef SQLITE_OMIT_WAL */ + +/* +** Cleans up the mapped region of the specified file, if any. +*/ +#if SQLITE_MAX_MMAP_SIZE>0 +static int winUnmapfile(winFile *pFile){ + assert( pFile!=0 ); + OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, pMapRegion=%p, " + "mmapSize=%lld, mmapSizeMax=%lld\n", + osGetCurrentProcessId(), pFile, pFile->hMap, pFile->pMapRegion, + pFile->mmapSize, pFile->mmapSizeMax)); + if( pFile->pMapRegion ){ + if( !osUnmapViewOfFile(pFile->pMapRegion) ){ + pFile->lastErrno = osGetLastError(); + OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, pMapRegion=%p, " + "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile, + pFile->pMapRegion)); + return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, + "winUnmapfile1", pFile->zPath); + } + pFile->pMapRegion = 0; + pFile->mmapSize = 0; + } + if( pFile->hMap!=NULL ){ + if( !osCloseHandle(pFile->hMap) ){ + pFile->lastErrno = osGetLastError(); + OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n", + osGetCurrentProcessId(), pFile, pFile->hMap)); + return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, + "winUnmapfile2", pFile->zPath); + } + pFile->hMap = NULL; + } + OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFile)); + return SQLITE_OK; +} + +/* +** Memory map or remap the file opened by file-descriptor pFd (if the file +** is already mapped, the existing mapping is replaced by the new). Or, if +** there already exists a mapping for this file, and there are still +** outstanding xFetch() references to it, this function is a no-op. +** +** If parameter nByte is non-negative, then it is the requested size of +** the mapping to create. Otherwise, if nByte is less than zero, then the +** requested size is the size of the file on disk. The actual size of the +** created mapping is either the requested size or the value configured +** using SQLITE_FCNTL_MMAP_SIZE, whichever is smaller. +** +** SQLITE_OK is returned if no error occurs (even if the mapping is not +** recreated as a result of outstanding references) or an SQLite error +** code otherwise. +*/ +static int winMapfile(winFile *pFd, sqlite3_int64 nByte){ + sqlite3_int64 nMap = nByte; + int rc; + + assert( nMap>=0 || pFd->nFetchOut==0 ); + OSTRACE(("MAP-FILE pid=%lu, pFile=%p, size=%lld\n", + osGetCurrentProcessId(), pFd, nByte)); + + if( pFd->nFetchOut>0 ) return SQLITE_OK; + + if( nMap<0 ){ + rc = winFileSize((sqlite3_file*)pFd, &nMap); + if( rc ){ + OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_IOERR_FSTAT\n", + osGetCurrentProcessId(), pFd)); + return SQLITE_IOERR_FSTAT; + } + } + if( nMap>pFd->mmapSizeMax ){ + nMap = pFd->mmapSizeMax; + } + nMap &= ~(sqlite3_int64)(winSysInfo.dwPageSize - 1); + + if( nMap==0 && pFd->mmapSize>0 ){ + winUnmapfile(pFd); + } + if( nMap!=pFd->mmapSize ){ + void *pNew = 0; + DWORD protect = PAGE_READONLY; + DWORD flags = FILE_MAP_READ; + + winUnmapfile(pFd); +#ifdef SQLITE_MMAP_READWRITE + if( (pFd->ctrlFlags & WINFILE_RDONLY)==0 ){ + protect = PAGE_READWRITE; + flags |= FILE_MAP_WRITE; + } +#endif +#if defined(SQLITE_WIN32_HAS_WIDE) + pFd->hMap = osCreateFileMappingW(pFd->h, NULL, protect, + (DWORD)((nMap>>32) & 0xffffffff), + (DWORD)(nMap & 0xffffffff), NULL); +#elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA + pFd->hMap = osCreateFileMappingA(pFd->h, NULL, protect, + (DWORD)((nMap>>32) & 0xffffffff), + (DWORD)(nMap & 0xffffffff), NULL); +#endif + if( pFd->hMap==NULL ){ + pFd->lastErrno = osGetLastError(); + rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, + "winMapfile1", pFd->zPath); + /* Log the error, but continue normal operation using xRead/xWrite */ + OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=%s\n", + osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); + return SQLITE_OK; + } + assert( (nMap % winSysInfo.dwPageSize)==0 ); + assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff ); + pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap); + if( pNew==NULL ){ + osCloseHandle(pFd->hMap); + pFd->hMap = NULL; + pFd->lastErrno = osGetLastError(); + rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, + "winMapfile2", pFd->zPath); + /* Log the error, but continue normal operation using xRead/xWrite */ + OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=%s\n", + osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); + return SQLITE_OK; + } + pFd->pMapRegion = pNew; + pFd->mmapSize = nMap; + } + + OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), pFd)); + return SQLITE_OK; +} +#endif /* SQLITE_MAX_MMAP_SIZE>0 */ + +/* +** If possible, return a pointer to a mapping of file fd starting at offset +** iOff. The mapping must be valid for at least nAmt bytes. +** +** If such a pointer can be obtained, store it in *pp and return SQLITE_OK. +** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK. +** Finally, if an error does occur, return an SQLite error code. The final +** value of *pp is undefined in this case. +** +** If this function does return a pointer, the caller must eventually +** release the reference by calling winUnfetch(). +*/ +static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ +#if SQLITE_MAX_MMAP_SIZE>0 + winFile *pFd = (winFile*)fd; /* The underlying database file */ +#endif + *pp = 0; + + OSTRACE(("FETCH pid=%lu, pFile=%p, offset=%lld, amount=%d, pp=%p\n", + osGetCurrentProcessId(), fd, iOff, nAmt, pp)); + +#if SQLITE_MAX_MMAP_SIZE>0 + if( pFd->mmapSizeMax>0 ){ + /* Ensure that there is always at least a 256 byte buffer of addressable + ** memory following the returned page. If the database is corrupt, + ** SQLite may overread the page slightly (in practice only a few bytes, + ** but 256 is safe, round, number). */ + const int nEofBuffer = 256; + if( pFd->pMapRegion==0 ){ + int rc = winMapfile(pFd, -1); + if( rc!=SQLITE_OK ){ + OSTRACE(("FETCH pid=%lu, pFile=%p, rc=%s\n", + osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); + return rc; + } + } + if( pFd->mmapSize >= (iOff+nAmt+nEofBuffer) ){ + assert( pFd->pMapRegion!=0 ); + *pp = &((u8 *)pFd->pMapRegion)[iOff]; + pFd->nFetchOut++; + } + } +#endif + + OSTRACE(("FETCH pid=%lu, pFile=%p, pp=%p, *pp=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), fd, pp, *pp)); + return SQLITE_OK; +} + +/* +** If the third argument is non-NULL, then this function releases a +** reference obtained by an earlier call to winFetch(). The second +** argument passed to this function must be the same as the corresponding +** argument that was passed to the winFetch() invocation. +** +** Or, if the third argument is NULL, then this function is being called +** to inform the VFS layer that, according to POSIX, any existing mapping +** may now be invalid and should be unmapped. +*/ +static int winUnfetch(sqlite3_file *fd, i64 iOff, void *p){ +#if SQLITE_MAX_MMAP_SIZE>0 + winFile *pFd = (winFile*)fd; /* The underlying database file */ + + /* If p==0 (unmap the entire file) then there must be no outstanding + ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference), + ** then there must be at least one outstanding. */ + assert( (p==0)==(pFd->nFetchOut==0) ); + + /* If p!=0, it must match the iOff value. */ + assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] ); + + OSTRACE(("UNFETCH pid=%lu, pFile=%p, offset=%lld, p=%p\n", + osGetCurrentProcessId(), pFd, iOff, p)); + + if( p ){ + pFd->nFetchOut--; + }else{ + /* FIXME: If Windows truly always prevents truncating or deleting a + ** file while a mapping is held, then the following winUnmapfile() call + ** is unnecessary can be omitted - potentially improving + ** performance. */ + winUnmapfile(pFd); + } + + assert( pFd->nFetchOut>=0 ); +#endif + + OSTRACE(("UNFETCH pid=%lu, pFile=%p, rc=SQLITE_OK\n", + osGetCurrentProcessId(), fd)); + return SQLITE_OK; +} + +/* +** Here ends the implementation of all sqlite3_file methods. +** +********************** End sqlite3_file Methods ******************************* +******************************************************************************/ + +/* +** This vector defines all the methods that can operate on an +** sqlite3_file for win32. +*/ +static const sqlite3_io_methods winIoMethod = { + 3, /* iVersion */ + winClose, /* xClose */ + winRead, /* xRead */ + winWrite, /* xWrite */ + winTruncate, /* xTruncate */ + winSync, /* xSync */ + winFileSize, /* xFileSize */ + winLock, /* xLock */ + winUnlock, /* xUnlock */ + winCheckReservedLock, /* xCheckReservedLock */ + winFileControl, /* xFileControl */ + winSectorSize, /* xSectorSize */ + winDeviceCharacteristics, /* xDeviceCharacteristics */ + winShmMap, /* xShmMap */ + winShmLock, /* xShmLock */ + winShmBarrier, /* xShmBarrier */ + winShmUnmap, /* xShmUnmap */ + winFetch, /* xFetch */ + winUnfetch /* xUnfetch */ +}; + +/* +** This vector defines all the methods that can operate on an +** sqlite3_file for win32 without performing any locking. +*/ +static const sqlite3_io_methods winIoNolockMethod = { + 3, /* iVersion */ + winClose, /* xClose */ + winRead, /* xRead */ + winWrite, /* xWrite */ + winTruncate, /* xTruncate */ + winSync, /* xSync */ + winFileSize, /* xFileSize */ + winNolockLock, /* xLock */ + winNolockUnlock, /* xUnlock */ + winNolockCheckReservedLock, /* xCheckReservedLock */ + winFileControl, /* xFileControl */ + winSectorSize, /* xSectorSize */ + winDeviceCharacteristics, /* xDeviceCharacteristics */ + winShmMap, /* xShmMap */ + winShmLock, /* xShmLock */ + winShmBarrier, /* xShmBarrier */ + winShmUnmap, /* xShmUnmap */ + winFetch, /* xFetch */ + winUnfetch /* xUnfetch */ +}; + +static winVfsAppData winAppData = { + &winIoMethod, /* pMethod */ + 0, /* pAppData */ + 0 /* bNoLock */ +}; + +static winVfsAppData winNolockAppData = { + &winIoNolockMethod, /* pMethod */ + 0, /* pAppData */ + 1 /* bNoLock */ +}; + +/**************************************************************************** +**************************** sqlite3_vfs methods **************************** +** +** This division contains the implementation of methods on the +** sqlite3_vfs object. +*/ + +/* +** This function returns non-zero if the specified UTF-8 string buffer +** ends with a directory separator character or one was successfully +** added to it. +*/ +static int winMakeEndInDirSep(int nBuf, char *zBuf){ + if( zBuf ){ + int nLen = sqlite3Strlen30(zBuf); + if( nLen>0 ){ + if( winIsDirSep(zBuf[nLen-1]) ){ + return 1; + }else if( nLen+1mxPathname; + nBuf = 2 + (i64)nMax; + zBuf = sqlite3MallocZero( nBuf ); + if( !zBuf ){ + OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); + return SQLITE_IOERR_NOMEM_BKPT; + } + + /* Figure out the effective temporary directory. First, check if one + ** has been explicitly set by the application; otherwise, use the one + ** configured by the operating system. + */ + nDir = nMax - (nPre + 15); + assert( nDir>0 ); + if( winTempDirDefined() ){ + int nDirLen = sqlite3Strlen30(sqlite3_temp_directory); + if( nDirLen>0 ){ + if( !winIsDirSep(sqlite3_temp_directory[nDirLen-1]) ){ + nDirLen++; + } + if( nDirLen>nDir ){ + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); + sqlite3_free(zBuf); + OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); + return winLogError(SQLITE_ERROR, 0, "winGetTempname1", 0); + } + sqlite3_snprintf(nMax, zBuf, "%s", sqlite3_temp_directory); + } + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); + } + +#if defined(__CYGWIN__) + else if( osGetenv!=NULL ){ + static const char *azDirs[] = { + 0, /* getenv("SQLITE_TMPDIR") */ + 0, /* getenv("TMPDIR") */ + 0, /* getenv("TMP") */ + 0, /* getenv("TEMP") */ + 0, /* getenv("USERPROFILE") */ + "/var/tmp", + "/usr/tmp", + "/tmp", + ".", + 0 /* List terminator */ + }; + unsigned int i; + const char *zDir = 0; + + if( !azDirs[0] ) azDirs[0] = osGetenv("SQLITE_TMPDIR"); + if( !azDirs[1] ) azDirs[1] = osGetenv("TMPDIR"); + if( !azDirs[2] ) azDirs[2] = osGetenv("TMP"); + if( !azDirs[3] ) azDirs[3] = osGetenv("TEMP"); + if( !azDirs[4] ) azDirs[4] = osGetenv("USERPROFILE"); + for(i=0; i/etilqs_XXXXXXXXXXXXXXX\0\0" + ** + ** If not, return SQLITE_ERROR. The number 17 is used here in order to + ** account for the space used by the 15 character random suffix and the + ** two trailing NUL characters. The final directory separator character + ** has already added if it was not already present. + */ + nLen = sqlite3Strlen30(zBuf); + if( (nLen + nPre + 17) > nBuf ){ + sqlite3_free(zBuf); + OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); + return winLogError(SQLITE_ERROR, 0, "winGetTempname5", 0); + } + + sqlite3_snprintf(nBuf-16-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX); + + j = sqlite3Strlen30(zBuf); + sqlite3_randomness(15, &zBuf[j]); + pid = osGetCurrentProcessId(); + for(i=0; i<15; i++, j++){ + zBuf[j] += pid & 0xff; + pid >>= 8; + zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; + } + zBuf[j] = 0; + zBuf[j+1] = 0; + *pzBuf = zBuf; + + OSTRACE(("TEMP-FILENAME name=%s, rc=SQLITE_OK\n", zBuf)); + return SQLITE_OK; +} + +/* +** Return TRUE if the named file is really a directory. Return false if +** it is something other than a directory, or if there is any kind of memory +** allocation failure. +*/ +static int winIsDir(const void *zConverted){ + DWORD attr; + int rc = 0; + DWORD lastErrno; + + if( osIsNT() ){ + int cnt = 0; + WIN32_FILE_ATTRIBUTE_DATA sAttrData; + memset(&sAttrData, 0, sizeof(sAttrData)); + while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, + GetFileExInfoStandard, + &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){} + if( !rc ){ + return 0; /* Invalid name? */ + } + attr = sAttrData.dwFileAttributes; +#if SQLITE_OS_WINCE==0 && defined(SQLITE_WIN32_HAS_ANSI) + }else{ + attr = osGetFileAttributesA((char*)zConverted); +#endif + } + return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY); +} + +/* forward reference */ +static int winAccess( + sqlite3_vfs *pVfs, /* Not used on win32 */ + const char *zFilename, /* Name of file to check */ + int flags, /* Type of test to make on this file */ + int *pResOut /* OUT: Result */ +); + +/* +** The Windows version of xAccess() accepts an extra bit in the flags +** parameter that prevents an anti-virus retry loop. +*/ +#define NORETRY 0x4000 + +/* +** Open a file. +*/ +static int winOpen( + sqlite3_vfs *pVfs, /* Used to get maximum path length and AppData */ + const char *zName, /* Name of the file (UTF-8) */ + sqlite3_file *id, /* Write the SQLite file handle here */ + int flags, /* Open mode flags */ + int *pOutFlags /* Status return flags */ +){ + HANDLE h; + DWORD lastErrno = 0; + DWORD dwDesiredAccess; + DWORD dwShareMode; + DWORD dwCreationDisposition; + DWORD dwFlagsAndAttributes = 0; +#if SQLITE_OS_WINCE + int isTemp = 0; +#endif + winVfsAppData *pAppData; + winFile *pFile = (winFile*)id; + void *zConverted; /* Filename in OS encoding */ + const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */ + int cnt = 0; + int isRO = 0; /* file is known to be accessible readonly */ + + /* If argument zPath is a NULL pointer, this function is required to open + ** a temporary file. Use this buffer to store the file name in. + */ + char *zTmpname = 0; /* For temporary filename, if necessary. */ + + int rc = SQLITE_OK; /* Function Return Code */ +#if !defined(NDEBUG) || SQLITE_OS_WINCE + int eType = flags&0x0FFF00; /* Type of file to open */ +#endif + + int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); + int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); + int isCreate = (flags & SQLITE_OPEN_CREATE); + int isReadonly = (flags & SQLITE_OPEN_READONLY); + int isReadWrite = (flags & SQLITE_OPEN_READWRITE); + +#ifndef NDEBUG + int isOpenJournal = (isCreate && ( + eType==SQLITE_OPEN_SUPER_JOURNAL + || eType==SQLITE_OPEN_MAIN_JOURNAL + || eType==SQLITE_OPEN_WAL + )); +#endif + + OSTRACE(("OPEN name=%s, pFile=%p, flags=%x, pOutFlags=%p\n", + zUtf8Name, id, flags, pOutFlags)); + + /* Check the following statements are true: + ** + ** (a) Exactly one of the READWRITE and READONLY flags must be set, and + ** (b) if CREATE is set, then READWRITE must also be set, and + ** (c) if EXCLUSIVE is set, then CREATE must also be set. + ** (d) if DELETEONCLOSE is set, then CREATE must also be set. + */ + assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly)); + assert(isCreate==0 || isReadWrite); + assert(isExclusive==0 || isCreate); + assert(isDelete==0 || isCreate); + + /* The main DB, main journal, WAL file and super-journal are never + ** automatically deleted. Nor are they ever temporary files. */ + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_SUPER_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL ); + + /* Assert that the upper layer has set one of the "file-type" flags. */ + assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB + || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL + || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_SUPER_JOURNAL + || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL + ); + + assert( pFile!=0 ); + memset(pFile, 0, sizeof(winFile)); + pFile->h = INVALID_HANDLE_VALUE; + + /* If the second argument to this function is NULL, generate a + ** temporary file name to use + */ + if( !zUtf8Name ){ + assert( isDelete && !isOpenJournal ); + rc = winGetTempname(pVfs, &zTmpname); + if( rc!=SQLITE_OK ){ + OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc))); + return rc; + } + zUtf8Name = zTmpname; + } + + /* Database filenames are double-zero terminated if they are not + ** URIs with parameters. Hence, they can always be passed into + ** sqlite3_uri_parameter(). + */ + assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) || + zUtf8Name[sqlite3Strlen30(zUtf8Name)+1]==0 ); + + /* Convert the filename to the system encoding. */ + zConverted = winConvertFromUtf8Filename(zUtf8Name); + if( zConverted==0 ){ + sqlite3_free(zTmpname); + OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name)); + return SQLITE_IOERR_NOMEM_BKPT; + } + + if( winIsDir(zConverted) ){ + sqlite3_free(zConverted); + sqlite3_free(zTmpname); + OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8Name)); + return SQLITE_CANTOPEN_ISDIR; + } + + if( isReadWrite ){ + dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; + }else{ + dwDesiredAccess = GENERIC_READ; + } + + /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is + ** created. SQLite doesn't use it to indicate "exclusive access" + ** as it is usually understood. + */ + if( isExclusive ){ + /* Creates a new file, only if it does not already exist. */ + /* If the file exists, it fails. */ + dwCreationDisposition = CREATE_NEW; + }else if( isCreate ){ + /* Open existing file, or create if it doesn't exist */ + dwCreationDisposition = OPEN_ALWAYS; + }else{ + /* Opens a file, only if it exists. */ + dwCreationDisposition = OPEN_EXISTING; + } + + if( 0==sqlite3_uri_boolean(zName, "exclusive", 0) ){ + dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; + }else{ + dwShareMode = 0; + } + + if( isDelete ){ +#if SQLITE_OS_WINCE + dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN; + isTemp = 1; +#else + dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY + | FILE_ATTRIBUTE_HIDDEN + | FILE_FLAG_DELETE_ON_CLOSE; +#endif + }else{ + dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; + } + /* Reports from the internet are that performance is always + ** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */ +#if SQLITE_OS_WINCE + dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; +#endif + + if( osIsNT() ){ + do{ + h = osCreateFileW((LPCWSTR)zConverted, + dwDesiredAccess, + dwShareMode, NULL, + dwCreationDisposition, + dwFlagsAndAttributes, + NULL); + if( h!=INVALID_HANDLE_VALUE ) break; + if( isReadWrite ){ + int rc2; + sqlite3BeginBenignMalloc(); + rc2 = winAccess(pVfs, zUtf8Name, SQLITE_ACCESS_READ|NORETRY, &isRO); + sqlite3EndBenignMalloc(); + if( rc2==SQLITE_OK && isRO ) break; + } + }while( winRetryIoerr(&cnt, &lastErrno) ); + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + do{ + h = osCreateFileA((LPCSTR)zConverted, + dwDesiredAccess, + dwShareMode, NULL, + dwCreationDisposition, + dwFlagsAndAttributes, + NULL); + if( h!=INVALID_HANDLE_VALUE ) break; + if( isReadWrite ){ + int rc2; + sqlite3BeginBenignMalloc(); + rc2 = winAccess(pVfs, zUtf8Name, SQLITE_ACCESS_READ|NORETRY, &isRO); + sqlite3EndBenignMalloc(); + if( rc2==SQLITE_OK && isRO ) break; + } + }while( winRetryIoerr(&cnt, &lastErrno) ); + } +#endif + winLogIoerr(cnt, __LINE__); + + OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name, + dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); + + if( h==INVALID_HANDLE_VALUE ){ + sqlite3_free(zConverted); + sqlite3_free(zTmpname); + if( isReadWrite && isRO && !isExclusive ){ + return winOpen(pVfs, zName, id, + ((flags|SQLITE_OPEN_READONLY) & + ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), + pOutFlags); + }else{ + pFile->lastErrno = lastErrno; + winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name); + return SQLITE_CANTOPEN_BKPT; + } + } + + if( pOutFlags ){ + if( isReadWrite ){ + *pOutFlags = SQLITE_OPEN_READWRITE; + }else{ + *pOutFlags = SQLITE_OPEN_READONLY; + } + } + + OSTRACE(("OPEN file=%p, name=%s, access=%lx, pOutFlags=%p, *pOutFlags=%d, " + "rc=%s\n", h, zUtf8Name, dwDesiredAccess, pOutFlags, pOutFlags ? + *pOutFlags : 0, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); + + pAppData = (winVfsAppData*)pVfs->pAppData; + +#if SQLITE_OS_WINCE + { + if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB + && ((pAppData==NULL) || !pAppData->bNoLock) + && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK + ){ + osCloseHandle(h); + sqlite3_free(zConverted); + sqlite3_free(zTmpname); + OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc))); + return rc; + } + } + if( isTemp ){ + pFile->zDeleteOnClose = zConverted; + }else +#endif + { + sqlite3_free(zConverted); + } + + sqlite3_free(zTmpname); + id->pMethods = pAppData ? pAppData->pMethod : &winIoMethod; + pFile->pVfs = pVfs; + pFile->h = h; + if( isReadonly ){ + pFile->ctrlFlags |= WINFILE_RDONLY; + } + if( (flags & SQLITE_OPEN_MAIN_DB) + && sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) + ){ + pFile->ctrlFlags |= WINFILE_PSOW; + } + pFile->lastErrno = NO_ERROR; + pFile->zPath = zName; +#if SQLITE_MAX_MMAP_SIZE>0 + pFile->hMap = NULL; + pFile->pMapRegion = 0; + pFile->mmapSize = 0; + pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap; +#endif + + OpenCounter(+1); + return rc; +} + +/* +** Delete the named file. +** +** Note that Windows does not allow a file to be deleted if some other +** process has it open. Sometimes a virus scanner or indexing program +** will open a journal file shortly after it is created in order to do +** whatever it does. While this other process is holding the +** file open, we will be unable to delete it. To work around this +** problem, we delay 100 milliseconds and try to delete again. Up +** to MX_DELETION_ATTEMPTs deletion attempts are run before giving +** up and returning an error. +*/ +static int winDelete( + sqlite3_vfs *pVfs, /* Not used on win32 */ + const char *zFilename, /* Name of file to delete */ + int syncDir /* Not used on win32 */ +){ + int cnt = 0; + int rc; + DWORD attr; + DWORD lastErrno = 0; + void *zConverted; + UNUSED_PARAMETER(pVfs); + UNUSED_PARAMETER(syncDir); + + SimulateIOError(return SQLITE_IOERR_DELETE); + OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir)); + + zConverted = winConvertFromUtf8Filename(zFilename); + if( zConverted==0 ){ + OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); + return SQLITE_IOERR_NOMEM_BKPT; + } + if( osIsNT() ){ + do { + attr = osGetFileAttributesW(zConverted); + if ( attr==INVALID_FILE_ATTRIBUTES ){ + lastErrno = osGetLastError(); + if( lastErrno==ERROR_FILE_NOT_FOUND + || lastErrno==ERROR_PATH_NOT_FOUND ){ + rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */ + }else{ + rc = SQLITE_ERROR; + } + break; + } + if ( attr&FILE_ATTRIBUTE_DIRECTORY ){ + rc = SQLITE_ERROR; /* Files only. */ + break; + } + if ( osDeleteFileW(zConverted) ){ + rc = SQLITE_OK; /* Deleted OK. */ + break; + } + if ( !winRetryIoerr(&cnt, &lastErrno) ){ + rc = SQLITE_ERROR; /* No more retries. */ + break; + } + } while(1); + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + do { + attr = osGetFileAttributesA(zConverted); + if ( attr==INVALID_FILE_ATTRIBUTES ){ + lastErrno = osGetLastError(); + if( lastErrno==ERROR_FILE_NOT_FOUND + || lastErrno==ERROR_PATH_NOT_FOUND ){ + rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */ + }else{ + rc = SQLITE_ERROR; + } + break; + } + if ( attr&FILE_ATTRIBUTE_DIRECTORY ){ + rc = SQLITE_ERROR; /* Files only. */ + break; + } + if ( osDeleteFileA(zConverted) ){ + rc = SQLITE_OK; /* Deleted OK. */ + break; + } + if ( !winRetryIoerr(&cnt, &lastErrno) ){ + rc = SQLITE_ERROR; /* No more retries. */ + break; + } + } while(1); + } +#endif + if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){ + rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename); + }else{ + winLogIoerr(cnt, __LINE__); + } + sqlite3_free(zConverted); + OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc))); + return rc; +} + +/* +** Check the existence and status of a file. +*/ +static int winAccess( + sqlite3_vfs *pVfs, /* Not used on win32 */ + const char *zFilename, /* Name of file to check */ + int flags, /* Type of test to make on this file */ + int *pResOut /* OUT: Result */ +){ + DWORD attr; + int rc = 0; + DWORD lastErrno = 0; + void *zConverted; + int noRetry = 0; /* Do not use winRetryIoerr() */ + UNUSED_PARAMETER(pVfs); + + if( (flags & NORETRY)!=0 ){ + noRetry = 1; + flags &= ~NORETRY; + } + + SimulateIOError( return SQLITE_IOERR_ACCESS; ); + OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n", + zFilename, flags, pResOut)); + + if( zFilename==0 ){ + *pResOut = 0; + OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n", + zFilename, pResOut, *pResOut)); + return SQLITE_OK; + } + + zConverted = winConvertFromUtf8Filename(zFilename); + if( zConverted==0 ){ + OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); + return SQLITE_IOERR_NOMEM_BKPT; + } + if( osIsNT() ){ + int cnt = 0; + WIN32_FILE_ATTRIBUTE_DATA sAttrData; + memset(&sAttrData, 0, sizeof(sAttrData)); + while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, + GetFileExInfoStandard, + &sAttrData)) + && !noRetry + && winRetryIoerr(&cnt, &lastErrno) + ){ /* Loop until true */} + if( rc ){ + /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file + ** as if it does not exist. + */ + if( flags==SQLITE_ACCESS_EXISTS + && sAttrData.nFileSizeHigh==0 + && sAttrData.nFileSizeLow==0 ){ + attr = INVALID_FILE_ATTRIBUTES; + }else{ + attr = sAttrData.dwFileAttributes; + } + }else{ + if( noRetry ) lastErrno = osGetLastError(); + winLogIoerr(cnt, __LINE__); + if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){ + sqlite3_free(zConverted); + return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", + zFilename); + }else{ + attr = INVALID_FILE_ATTRIBUTES; + } + } + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + attr = osGetFileAttributesA((char*)zConverted); + } +#endif + sqlite3_free(zConverted); + switch( flags ){ + case SQLITE_ACCESS_READ: + case SQLITE_ACCESS_EXISTS: + rc = attr!=INVALID_FILE_ATTRIBUTES; + break; + case SQLITE_ACCESS_READWRITE: + rc = attr!=INVALID_FILE_ATTRIBUTES && + (attr & FILE_ATTRIBUTE_READONLY)==0; + break; + default: + assert(!"Invalid flags argument"); + } + *pResOut = rc; + OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n", + zFilename, pResOut, *pResOut)); + return SQLITE_OK; +} + +/* +** Returns non-zero if the specified path name starts with the "long path" +** prefix. +*/ +static BOOL winIsLongPathPrefix( + const char *zPathname +){ + return ( zPathname[0]=='\\' && zPathname[1]=='\\' + && zPathname[2]=='?' && zPathname[3]=='\\' ); +} + +/* +** Returns non-zero if the specified path name starts with a drive letter +** followed by a colon character. +*/ +static BOOL winIsDriveLetterAndColon( + const char *zPathname +){ + return ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ); +} + +#ifdef _WIN32 +/* +** Returns non-zero if the specified path name should be used verbatim. If +** non-zero is returned from this function, the calling function must simply +** use the provided path name verbatim -OR- resolve it into a full path name +** using the GetFullPathName Win32 API function (if available). +*/ +static BOOL winIsVerbatimPathname( + const char *zPathname +){ + /* + ** If the path name starts with a forward slash or a backslash, it is either + ** a legal UNC name, a volume relative path, or an absolute path name in the + ** "Unix" format on Windows. There is no easy way to differentiate between + ** the final two cases; therefore, we return the safer return value of TRUE + ** so that callers of this function will simply use it verbatim. + */ + if ( winIsDirSep(zPathname[0]) ){ + return TRUE; + } + + /* + ** If the path name starts with a letter and a colon it is either a volume + ** relative path or an absolute path. Callers of this function must not + ** attempt to treat it as a relative path name (i.e. they should simply use + ** it verbatim). + */ + if ( winIsDriveLetterAndColon(zPathname) ){ + return TRUE; + } + + /* + ** If we get to this point, the path name should almost certainly be a purely + ** relative one (i.e. not a UNC name, not absolute, and not volume relative). + */ + return FALSE; +} +#endif /* _WIN32 */ + +#ifdef __CYGWIN__ +/* +** Simplify a filename into its canonical form +** by making the following changes: +** +** * convert any '/' to '\' (win32) or reverse (Cygwin) +** * removing any trailing and duplicate / (except for UNC paths) +** * convert /./ into just / +** +** Changes are made in-place. Return the new name length. +** +** The original filename is in z[0..]. If the path is shortened, +** no-longer used bytes will be written by '\0'. +*/ +static void winSimplifyName(char *z){ + int i, j; + for(i=j=0; z[i]; ++i){ + if( winIsDirSep(z[i]) ){ +#if !defined(SQLITE_TEST) + /* Some test-cases assume that "./foo" and "foo" are different */ + if( z[i+1]=='.' && winIsDirSep(z[i+2]) ){ + ++i; + continue; + } +#endif + if( !z[i+1] || (winIsDirSep(z[i+1]) && (i!=0)) ){ + continue; + } + z[j++] = osGetenv?'/':'\\'; + }else{ + z[j++] = z[i]; + } + } + while(jnOut ){ + /* SQLite assumes that xFullPathname() nul-terminates the output buffer + ** even if it returns an error. */ + zOut[iOff] = '\0'; + return SQLITE_CANTOPEN_BKPT; + } + sqlite3_snprintf(nOut-iOff, &zOut[iOff], "%s", zPath); + return SQLITE_OK; +} +#endif /* __CYGWIN__ */ + +/* +** Turn a relative pathname into a full pathname. Write the full +** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname +** bytes in size. +*/ +static int winFullPathnameNoMutex( + sqlite3_vfs *pVfs, /* Pointer to vfs object */ + const char *zRelative, /* Possibly relative input path */ + int nFull, /* Size of output buffer in bytes */ + char *zFull /* Output buffer */ +){ +#if !SQLITE_OS_WINCE + int nByte; + void *zConverted; + char *zOut; +#endif + + /* If this path name begins with "/X:" or "\\?\", where "X" is any + ** alphabetic character, discard the initial "/" from the pathname. + */ + if( zRelative[0]=='/' && (winIsDriveLetterAndColon(zRelative+1) + || winIsLongPathPrefix(zRelative+1)) ){ + zRelative++; + } + + SimulateIOError( return SQLITE_ERROR ); + +#ifdef __CYGWIN__ + if( osGetcwd ){ + zFull[nFull-1] = '\0'; + if( !winIsDriveLetterAndColon(zRelative) || !winIsDirSep(zRelative[2]) ){ + int rc = SQLITE_OK; + int nLink = 1; /* Number of symbolic links followed so far */ + const char *zIn = zRelative; /* Input path for each iteration of loop */ + char *zDel = 0; + struct stat buf; + + UNUSED_PARAMETER(pVfs); + + do { + /* Call lstat() on path zIn. Set bLink to true if the path is a symbolic + ** link, or false otherwise. */ + int bLink = 0; + if( osLstat && osReadlink ) { + if( osLstat(zIn, &buf)!=0 ){ + int myErrno = osErrno; + if( myErrno!=ENOENT ){ + rc = winLogError(SQLITE_CANTOPEN_BKPT, (DWORD)myErrno, "lstat", zIn); + } + }else{ + bLink = ((buf.st_mode & 0170000) == 0120000); + } + + if( bLink ){ + if( zDel==0 ){ + zDel = sqlite3MallocZero(nFull); + if( zDel==0 ) rc = SQLITE_NOMEM; + }else if( ++nLink>SQLITE_MAX_SYMLINKS ){ + rc = SQLITE_CANTOPEN_BKPT; + } + + if( rc==SQLITE_OK ){ + nByte = osReadlink(zIn, zDel, nFull-1); + if( nByte ==(DWORD)-1 ){ + rc = winLogError(SQLITE_CANTOPEN_BKPT, (DWORD)osErrno, "readlink", zIn); + }else{ + if( zDel[0]!='/' ){ + int n; + for(n = sqlite3Strlen30(zIn); n>0 && zIn[n-1]!='/'; n--); + if( nByte+n+1>nFull ){ + rc = SQLITE_CANTOPEN_BKPT; + }else{ + memmove(&zDel[n], zDel, nByte+1); + memcpy(zDel, zIn, n); + nByte += n; + } + } + zDel[nByte] = '\0'; + } + } + + zIn = zDel; + } + } + + assert( rc!=SQLITE_OK || zIn!=zFull || zIn[0]=='/' ); + if( rc==SQLITE_OK && zIn!=zFull ){ + rc = mkFullPathname(zIn, zFull, nFull); + } + if( bLink==0 ) break; + zIn = zFull; + }while( rc==SQLITE_OK ); + + sqlite3_free(zDel); + winSimplifyName(zFull); + return rc; + } + } +#endif /* __CYGWIN__ */ + +#if SQLITE_OS_WINCE && defined(_WIN32) + SimulateIOError( return SQLITE_ERROR ); + /* WinCE has no concept of a relative pathname, or so I am told. */ + /* WinRT has no way to convert a relative path to an absolute one. */ + if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ + /* + ** NOTE: We are dealing with a relative path name and the data + ** directory has been set. Therefore, use it as the basis + ** for converting the relative path name to an absolute + ** one by prepending the data directory and a backslash. + */ + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", + sqlite3_data_directory, winGetDirSep(), zRelative); + }else{ + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative); + } + return SQLITE_OK; +#endif + +#if !SQLITE_OS_WINCE +#if defined(_WIN32) + /* It's odd to simulate an io-error here, but really this is just + ** using the io-error infrastructure to test that SQLite handles this + ** function failing. This function could fail if, for example, the + ** current working directory has been unlinked. + */ + SimulateIOError( return SQLITE_ERROR ); + if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ + /* + ** NOTE: We are dealing with a relative path name and the data + ** directory has been set. Therefore, use it as the basis + ** for converting the relative path name to an absolute + ** one by prepending the data directory and a backslash. + */ + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", + sqlite3_data_directory, winGetDirSep(), zRelative); + return SQLITE_OK; + } +#endif + zConverted = winConvertFromUtf8Filename(zRelative); + if( zConverted==0 ){ + return SQLITE_IOERR_NOMEM_BKPT; + } + if( osIsNT() ){ + LPWSTR zTemp; + nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0); + if( nByte==0 ){ + sqlite3_free(zConverted); + return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), + "winFullPathname1", zRelative); + } + nByte += 3; + zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); + if( zTemp==0 ){ + sqlite3_free(zConverted); + return SQLITE_IOERR_NOMEM_BKPT; + } + nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0); + if( nByte==0 ){ + sqlite3_free(zConverted); + sqlite3_free(zTemp); + return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), + "winFullPathname2", zRelative); + } + sqlite3_free(zConverted); + zOut = winUnicodeToUtf8(zTemp); + sqlite3_free(zTemp); + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + char *zTemp; + nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0); + if( nByte==0 ){ + sqlite3_free(zConverted); + return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), + "winFullPathname3", zRelative); + } + zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) + 3*sizeof(zTemp[0]) ); + if( zTemp==0 ){ + sqlite3_free(zConverted); + return SQLITE_IOERR_NOMEM_BKPT; + } + nByte = osGetFullPathNameA((char*)zConverted, nByte+3, zTemp, 0); + if( nByte==0 ){ + sqlite3_free(zConverted); + sqlite3_free(zTemp); + return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), + "winFullPathname4", zRelative); + } + sqlite3_free(zConverted); + zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI()); + sqlite3_free(zTemp); + } +#endif + if( zOut ){ +#ifdef __CYGWIN__ + if( memcmp(zOut, "\\\\?\\", 4) ){ + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut); + }else if( memcmp(zOut+4, "UNC\\", 4) ){ + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut+4); + }else{ + char *p = zOut+6; + *p = '\\'; + if( osGetcwd ){ + /* On Cygwin, UNC paths use forward slashes */ + while( *p ){ + if( *p=='\\' ) *p = '/'; + ++p; + } + } + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut+6); + } +#else + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut); +#endif /* __CYGWIN__ */ + sqlite3_free(zOut); + return SQLITE_OK; + }else{ + return SQLITE_IOERR_NOMEM_BKPT; + } +#endif +} +static int winFullPathname( + sqlite3_vfs *pVfs, /* Pointer to vfs object */ + const char *zRelative, /* Possibly relative input path */ + int nFull, /* Size of output buffer in bytes */ + char *zFull /* Output buffer */ +){ + int rc; + MUTEX_LOGIC( sqlite3_mutex *pMutex; ) + MUTEX_LOGIC( pMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR); ) + sqlite3_mutex_enter(pMutex); + rc = winFullPathnameNoMutex(pVfs, zRelative, nFull, zFull); + sqlite3_mutex_leave(pMutex); + return rc; +} + +#ifndef SQLITE_OMIT_LOAD_EXTENSION +/* +** Interfaces for opening a shared library, finding entry points +** within the shared library, and closing the shared library. +*/ +static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ + HANDLE h; + void *zConverted = winConvertFromUtf8Filename(zFilename); + UNUSED_PARAMETER(pVfs); + if( zConverted==0 ){ + OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); + return 0; + } + if( osIsNT() ){ + h = osLoadLibraryW((LPCWSTR)zConverted); + } +#ifdef SQLITE_WIN32_HAS_ANSI + else{ + h = osLoadLibraryA((char*)zConverted); + } +#endif + OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)h)); + sqlite3_free(zConverted); + return (void*)h; +} +static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ + UNUSED_PARAMETER(pVfs); + winGetLastErrorMsg(osGetLastError(), nBuf, zBufOut); +} +static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){ + FARPROC proc; + UNUSED_PARAMETER(pVfs); + proc = osGetProcAddressA((HANDLE)pH, zSym); + OSTRACE(("DLSYM handle=%p, symbol=%s, address=%p\n", + (void*)pH, zSym, (void*)proc)); + return (void(*)(void))proc; +} +static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){ + UNUSED_PARAMETER(pVfs); + osFreeLibrary((HANDLE)pHandle); + OSTRACE(("DLCLOSE handle=%p\n", (void*)pHandle)); +} +#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ + #define winDlOpen 0 + #define winDlError 0 + #define winDlSym 0 + #define winDlClose 0 +#endif + +/* State information for the randomness gatherer. */ +typedef struct EntropyGatherer EntropyGatherer; +struct EntropyGatherer { + unsigned char *a; /* Gather entropy into this buffer */ + int na; /* Size of a[] in bytes */ + int i; /* XOR next input into a[i] */ + int nXor; /* Number of XOR operations done */ +}; + +#if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) +/* Mix sz bytes of entropy into p. */ +static void xorMemory(EntropyGatherer *p, unsigned char *x, int sz){ + int j, k; + for(j=0, k=p->i; ja[k++] ^= x[j]; + if( k>=p->na ) k = 0; + } + p->i = k; + p->nXor += sz; +} +#endif /* !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) */ + +/* +** Write up to nBuf bytes of randomness into zBuf. +*/ +static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ +#if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS) + UNUSED_PARAMETER(pVfs); + memset(zBuf, 0, nBuf); + return nBuf; +#else + EntropyGatherer e; + UNUSED_PARAMETER(pVfs); + memset(zBuf, 0, nBuf); + e.a = (unsigned char*)zBuf; + e.na = nBuf; + e.nXor = 0; + e.i = 0; + { + SYSTEMTIME x; + osGetSystemTime(&x); + xorMemory(&e, (unsigned char*)&x, sizeof(SYSTEMTIME)); + } + { + DWORD pid = osGetCurrentProcessId(); + xorMemory(&e, (unsigned char*)&pid, sizeof(DWORD)); + } + { + DWORD cnt = osGetTickCount(); + xorMemory(&e, (unsigned char*)&cnt, sizeof(DWORD)); + } + { + LARGE_INTEGER i; + osQueryPerformanceCounter(&i); + xorMemory(&e, (unsigned char*)&i, sizeof(LARGE_INTEGER)); + } +#if !SQLITE_OS_WINCE && SQLITE_WIN32_USE_UUID + { + UUID id; + memset(&id, 0, sizeof(UUID)); + osUuidCreate(&id); + xorMemory(&e, (unsigned char*)&id, sizeof(UUID)); + memset(&id, 0, sizeof(UUID)); + osUuidCreateSequential(&id); + xorMemory(&e, (unsigned char*)&id, sizeof(UUID)); + } +#endif /* !SQLITE_OS_WINCE && SQLITE_WIN32_USE_UUID */ + return e.nXor>nBuf ? nBuf : e.nXor; +#endif /* defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS) */ +} + + +/* +** Sleep for a little while. Return the amount of time slept. +*/ +static int winSleep(sqlite3_vfs *pVfs, int microsec){ + sqlite3_win32_sleep((microsec+999)/1000); + UNUSED_PARAMETER(pVfs); + return ((microsec+999)/1000)*1000; +} + +/* +** The following variable, if set to a non-zero value, is interpreted as +** the number of seconds since 1970 and is used to set the result of +** sqlite3OsCurrentTime() during testing. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_current_time = 0; /* Fake system time in seconds since 1970. */ +#endif + +/* +** Find the current time (in Universal Coordinated Time). Write into *piNow +** the current time and date as a Julian Day number times 86_400_000. In +** other words, write into *piNow the number of milliseconds since the Julian +** epoch of noon in Greenwich on November 24, 4714 B.C according to the +** proleptic Gregorian calendar. +** +** On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date +** cannot be found. +*/ +static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){ + /* FILETIME structure is a 64-bit value representing the number of + 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). + */ + FILETIME ft; + static const sqlite3_int64 winFiletimeEpoch = 23058135*(sqlite3_int64)8640000; +#ifdef SQLITE_TEST + static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000; +#endif + /* 2^32 - to avoid use of LL and warnings in gcc */ + static const sqlite3_int64 max32BitValue = + (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 + + (sqlite3_int64)294967296; + +#if SQLITE_OS_WINCE + SYSTEMTIME time; + osGetSystemTime(&time); + /* if SystemTimeToFileTime() fails, it returns zero. */ + if (!osSystemTimeToFileTime(&time,&ft)){ + return SQLITE_ERROR; + } +#else + osGetSystemTimeAsFileTime( &ft ); +#endif + + *piNow = winFiletimeEpoch + + ((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) + + (sqlite3_int64)ft.dwLowDateTime)/(sqlite3_int64)10000; + +#ifdef SQLITE_TEST + if( sqlite3_current_time ){ + *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch; + } +#endif + UNUSED_PARAMETER(pVfs); + return SQLITE_OK; +} + +/* +** Find the current time (in Universal Coordinated Time). Write the +** current time and date as a Julian Day number into *prNow and +** return 0. Return 1 if the time and date cannot be found. +*/ +static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){ + int rc; + sqlite3_int64 i; + rc = winCurrentTimeInt64(pVfs, &i); + if( !rc ){ + *prNow = i/86400000.0; + } + return rc; +} + +/* +** The idea is that this function works like a combination of +** GetLastError() and FormatMessage() on Windows (or errno and +** strerror_r() on Unix). After an error is returned by an OS +** function, SQLite calls this function with zBuf pointing to +** a buffer of nBuf bytes. The OS layer should populate the +** buffer with a nul-terminated UTF-8 encoded error message +** describing the last IO error to have occurred within the calling +** thread. +** +** If the error message is too large for the supplied buffer, +** it should be truncated. The return value of xGetLastError +** is zero if the error message fits in the buffer, or non-zero +** otherwise (if the message was truncated). If non-zero is returned, +** then it is not necessary to include the nul-terminator character +** in the output buffer. +** +** Not supplying an error message will have no adverse effect +** on SQLite. It is fine to have an implementation that never +** returns an error message: +** +** int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ +** assert(zBuf[0]=='\0'); +** return 0; +** } +** +** However if an error message is supplied, it will be incorporated +** by sqlite into the error message available to the user using +** sqlite3_errmsg(), possibly making IO errors easier to debug. +*/ +static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ + DWORD e = osGetLastError(); + UNUSED_PARAMETER(pVfs); + if( nBuf>0 ) winGetLastErrorMsg(e, nBuf, zBuf); + return e; +} + +/* +** Initialize and deinitialize the operating system interface. +*/ +SQLITE_API int sqlite3_os_init(void){ + static sqlite3_vfs winVfs = { + 3, /* iVersion */ + sizeof(winFile), /* szOsFile */ + SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */ + 0, /* pNext */ + "win32", /* zName */ + &winAppData, /* pAppData */ + winOpen, /* xOpen */ + winDelete, /* xDelete */ + winAccess, /* xAccess */ + winFullPathname, /* xFullPathname */ + winDlOpen, /* xDlOpen */ + winDlError, /* xDlError */ + winDlSym, /* xDlSym */ + winDlClose, /* xDlClose */ + winRandomness, /* xRandomness */ + winSleep, /* xSleep */ + winCurrentTime, /* xCurrentTime */ + winGetLastError, /* xGetLastError */ + winCurrentTimeInt64, /* xCurrentTimeInt64 */ + winSetSystemCall, /* xSetSystemCall */ + winGetSystemCall, /* xGetSystemCall */ + winNextSystemCall, /* xNextSystemCall */ + }; +#if defined(SQLITE_WIN32_HAS_WIDE) + static sqlite3_vfs winLongPathVfs = { + 3, /* iVersion */ + sizeof(winFile), /* szOsFile */ + SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */ + 0, /* pNext */ + "win32-longpath", /* zName */ + &winAppData, /* pAppData */ + winOpen, /* xOpen */ + winDelete, /* xDelete */ + winAccess, /* xAccess */ + winFullPathname, /* xFullPathname */ + winDlOpen, /* xDlOpen */ + winDlError, /* xDlError */ + winDlSym, /* xDlSym */ + winDlClose, /* xDlClose */ + winRandomness, /* xRandomness */ + winSleep, /* xSleep */ + winCurrentTime, /* xCurrentTime */ + winGetLastError, /* xGetLastError */ + winCurrentTimeInt64, /* xCurrentTimeInt64 */ + winSetSystemCall, /* xSetSystemCall */ + winGetSystemCall, /* xGetSystemCall */ + winNextSystemCall, /* xNextSystemCall */ + }; +#endif + static sqlite3_vfs winNolockVfs = { + 3, /* iVersion */ + sizeof(winFile), /* szOsFile */ + SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */ + 0, /* pNext */ + "win32-none", /* zName */ + &winNolockAppData, /* pAppData */ + winOpen, /* xOpen */ + winDelete, /* xDelete */ + winAccess, /* xAccess */ + winFullPathname, /* xFullPathname */ + winDlOpen, /* xDlOpen */ + winDlError, /* xDlError */ + winDlSym, /* xDlSym */ + winDlClose, /* xDlClose */ + winRandomness, /* xRandomness */ + winSleep, /* xSleep */ + winCurrentTime, /* xCurrentTime */ + winGetLastError, /* xGetLastError */ + winCurrentTimeInt64, /* xCurrentTimeInt64 */ + winSetSystemCall, /* xSetSystemCall */ + winGetSystemCall, /* xGetSystemCall */ + winNextSystemCall, /* xNextSystemCall */ + }; +#if defined(SQLITE_WIN32_HAS_WIDE) + static sqlite3_vfs winLongPathNolockVfs = { + 3, /* iVersion */ + sizeof(winFile), /* szOsFile */ + SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */ + 0, /* pNext */ + "win32-longpath-none", /* zName */ + &winNolockAppData, /* pAppData */ + winOpen, /* xOpen */ + winDelete, /* xDelete */ + winAccess, /* xAccess */ + winFullPathname, /* xFullPathname */ + winDlOpen, /* xDlOpen */ + winDlError, /* xDlError */ + winDlSym, /* xDlSym */ + winDlClose, /* xDlClose */ + winRandomness, /* xRandomness */ + winSleep, /* xSleep */ + winCurrentTime, /* xCurrentTime */ + winGetLastError, /* xGetLastError */ + winCurrentTimeInt64, /* xCurrentTimeInt64 */ + winSetSystemCall, /* xSetSystemCall */ + winGetSystemCall, /* xGetSystemCall */ + winNextSystemCall, /* xNextSystemCall */ + }; +#endif + + /* Double-check that the aSyscall[] array has been constructed + ** correctly. See ticket [bb3a86e890c8e96ab] */ + assert( ArraySize(aSyscall)==81 ); + assert( strcmp(aSyscall[0].zName,"AreFileApisANSI")==0 ); + assert( strcmp(aSyscall[20].zName,"GetFileAttributesA")==0 ); + assert( strcmp(aSyscall[40].zName,"HeapReAlloc")==0 ); + assert( strcmp(aSyscall[60].zName,"WideCharToMultiByte")==0 ); + assert( strcmp(aSyscall[80].zName,"cygwin_conv_path")==0 ); + + /* get memory map allocation granularity */ + memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); + osGetSystemInfo(&winSysInfo); + assert( winSysInfo.dwAllocationGranularity>0 ); + assert( winSysInfo.dwPageSize>0 ); + + sqlite3_vfs_register(&winVfs, 1); + +#if defined(SQLITE_WIN32_HAS_WIDE) + sqlite3_vfs_register(&winLongPathVfs, 0); +#endif + + sqlite3_vfs_register(&winNolockVfs, 0); + +#if defined(SQLITE_WIN32_HAS_WIDE) + sqlite3_vfs_register(&winLongPathNolockVfs, 0); +#endif + +#ifndef SQLITE_OMIT_WAL + winBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); +#endif + + return SQLITE_OK; +} + +SQLITE_API int sqlite3_os_end(void){ +#ifndef SQLITE_OMIT_WAL + winBigLock = 0; +#endif + return SQLITE_OK; +} + +#endif /* SQLITE_OS_WIN */ + +/************** End of os_win.c **********************************************/ +/************** Begin file memdb.c *******************************************/ +/* +** 2016-09-07 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file implements an in-memory VFS. A database is held as a contiguous +** block of memory. +** +** This file also implements interface sqlite3_serialize() and +** sqlite3_deserialize(). +*/ +/* #include "sqliteInt.h" */ +#ifndef SQLITE_OMIT_DESERIALIZE + +/* +** Forward declaration of objects used by this utility +*/ +typedef struct sqlite3_vfs MemVfs; +typedef struct MemFile MemFile; +typedef struct MemStore MemStore; + +/* Access to a lower-level VFS that (might) implement dynamic loading, +** access to randomness, etc. +*/ +#define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData)) + +/* Storage for a memdb file. +** +** An memdb object can be shared or separate. Shared memdb objects can be +** used by more than one database connection. Mutexes are used by shared +** memdb objects to coordinate access. Separate memdb objects are only +** connected to a single database connection and do not require additional +** mutexes. +** +** Shared memdb objects have .zFName!=0 and .pMutex!=0. They are created +** using "file:/name?vfs=memdb". The first character of the name must be +** "/" or else the object will be a separate memdb object. All shared +** memdb objects are stored in memdb_g.apMemStore[] in an arbitrary order. +** +** Separate memdb objects are created using a name that does not begin +** with "/" or using sqlite3_deserialize(). +** +** Access rules for shared MemStore objects: +** +** * .zFName is initialized when the object is created and afterwards +** is unchanged until the object is destroyed. So it can be accessed +** at any time as long as we know the object is not being destroyed, +** which means while either the SQLITE_MUTEX_STATIC_VFS1 or +** .pMutex is held or the object is not part of memdb_g.apMemStore[]. +** +** * Can .pMutex can only be changed while holding the +** SQLITE_MUTEX_STATIC_VFS1 mutex or while the object is not part +** of memdb_g.apMemStore[]. +** +** * Other fields can only be changed while holding the .pMutex mutex +** or when the .nRef is less than zero and the object is not part of +** memdb_g.apMemStore[]. +** +** * The .aData pointer has the added requirement that it can can only +** be changed (for resizing) when nMmap is zero. +** +*/ +struct MemStore { + sqlite3_int64 sz; /* Size of the file */ + sqlite3_int64 szAlloc; /* Space allocated to aData */ + sqlite3_int64 szMax; /* Maximum allowed size of the file */ + unsigned char *aData; /* content of the file */ + sqlite3_mutex *pMutex; /* Used by shared stores only */ + int nMmap; /* Number of memory mapped pages */ + unsigned mFlags; /* Flags */ + int nRdLock; /* Number of readers */ + int nWrLock; /* Number of writers. (Always 0 or 1) */ + int nRef; /* Number of users of this MemStore */ + char *zFName; /* The filename for shared stores */ +}; + +/* An open file */ +struct MemFile { + sqlite3_file base; /* IO methods */ + MemStore *pStore; /* The storage */ + int eLock; /* Most recent lock against this file */ +}; + +/* +** File-scope variables for holding the memdb files that are accessible +** to multiple database connections in separate threads. +** +** Must hold SQLITE_MUTEX_STATIC_VFS1 to access any part of this object. +*/ +static struct MemFS { + int nMemStore; /* Number of shared MemStore objects */ + MemStore **apMemStore; /* Array of all shared MemStore objects */ +} memdb_g; + +/* +** Methods for MemFile +*/ +static int memdbClose(sqlite3_file*); +static int memdbRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); +static int memdbWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst); +static int memdbTruncate(sqlite3_file*, sqlite3_int64 size); +static int memdbSync(sqlite3_file*, int flags); +static int memdbFileSize(sqlite3_file*, sqlite3_int64 *pSize); +static int memdbLock(sqlite3_file*, int); +static int memdbUnlock(sqlite3_file*, int); +/* static int memdbCheckReservedLock(sqlite3_file*, int *pResOut);// not used */ +static int memdbFileControl(sqlite3_file*, int op, void *pArg); +/* static int memdbSectorSize(sqlite3_file*); // not used */ +static int memdbDeviceCharacteristics(sqlite3_file*); +static int memdbFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp); +static int memdbUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p); + +/* +** Methods for MemVfs +*/ +static int memdbOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *); +/* static int memdbDelete(sqlite3_vfs*, const char *zName, int syncDir); */ +static int memdbAccess(sqlite3_vfs*, const char *zName, int flags, int *); +static int memdbFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut); +static void *memdbDlOpen(sqlite3_vfs*, const char *zFilename); +static void memdbDlError(sqlite3_vfs*, int nByte, char *zErrMsg); +static void (*memdbDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void); +static void memdbDlClose(sqlite3_vfs*, void*); +static int memdbRandomness(sqlite3_vfs*, int nByte, char *zOut); +static int memdbSleep(sqlite3_vfs*, int microseconds); +/* static int memdbCurrentTime(sqlite3_vfs*, double*); */ +static int memdbGetLastError(sqlite3_vfs*, int, char *); +static int memdbCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*); + +static sqlite3_vfs memdb_vfs = { + 2, /* iVersion */ + 0, /* szOsFile (set when registered) */ + 1024, /* mxPathname */ + 0, /* pNext */ + "memdb", /* zName */ + 0, /* pAppData (set when registered) */ + memdbOpen, /* xOpen */ + 0, /* memdbDelete, */ /* xDelete */ + memdbAccess, /* xAccess */ + memdbFullPathname, /* xFullPathname */ + memdbDlOpen, /* xDlOpen */ + memdbDlError, /* xDlError */ + memdbDlSym, /* xDlSym */ + memdbDlClose, /* xDlClose */ + memdbRandomness, /* xRandomness */ + memdbSleep, /* xSleep */ + 0, /* memdbCurrentTime, */ /* xCurrentTime */ + memdbGetLastError, /* xGetLastError */ + memdbCurrentTimeInt64, /* xCurrentTimeInt64 */ + 0, /* xSetSystemCall */ + 0, /* xGetSystemCall */ + 0, /* xNextSystemCall */ +}; + +static const sqlite3_io_methods memdb_io_methods = { + 3, /* iVersion */ + memdbClose, /* xClose */ + memdbRead, /* xRead */ + memdbWrite, /* xWrite */ + memdbTruncate, /* xTruncate */ + memdbSync, /* xSync */ + memdbFileSize, /* xFileSize */ + memdbLock, /* xLock */ + memdbUnlock, /* xUnlock */ + 0, /* memdbCheckReservedLock, */ /* xCheckReservedLock */ + memdbFileControl, /* xFileControl */ + 0, /* memdbSectorSize,*/ /* xSectorSize */ + memdbDeviceCharacteristics, /* xDeviceCharacteristics */ + 0, /* xShmMap */ + 0, /* xShmLock */ + 0, /* xShmBarrier */ + 0, /* xShmUnmap */ + memdbFetch, /* xFetch */ + memdbUnfetch /* xUnfetch */ +}; + +/* +** Enter/leave the mutex on a MemStore +*/ +#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE==0 +static void memdbEnter(MemStore *p){ + UNUSED_PARAMETER(p); +} +static void memdbLeave(MemStore *p){ + UNUSED_PARAMETER(p); +} +#else +static void memdbEnter(MemStore *p){ + sqlite3_mutex_enter(p->pMutex); +} +static void memdbLeave(MemStore *p){ + sqlite3_mutex_leave(p->pMutex); +} +#endif + + + +/* +** Close an memdb-file. +** Free the underlying MemStore object when its refcount drops to zero +** or less. +*/ +static int memdbClose(sqlite3_file *pFile){ + MemStore *p = ((MemFile*)pFile)->pStore; + if( p->zFName ){ + int i; +#ifndef SQLITE_MUTEX_OMIT + sqlite3_mutex *pVfsMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); +#endif + sqlite3_mutex_enter(pVfsMutex); + for(i=0; ALWAYS(inRef==1 ){ + memdb_g.apMemStore[i] = memdb_g.apMemStore[--memdb_g.nMemStore]; + if( memdb_g.nMemStore==0 ){ + sqlite3_free(memdb_g.apMemStore); + memdb_g.apMemStore = 0; + } + } + break; + } + } + sqlite3_mutex_leave(pVfsMutex); + }else{ + memdbEnter(p); + } + p->nRef--; + if( p->nRef<=0 ){ + if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ){ + sqlite3_free(p->aData); + } + memdbLeave(p); + sqlite3_mutex_free(p->pMutex); + sqlite3_free(p); + }else{ + memdbLeave(p); + } + return SQLITE_OK; +} + +/* +** Read data from an memdb-file. +*/ +static int memdbRead( + sqlite3_file *pFile, + void *zBuf, + int iAmt, + sqlite_int64 iOfst +){ + MemStore *p = ((MemFile*)pFile)->pStore; + memdbEnter(p); + if( iOfst+iAmt>p->sz ){ + memset(zBuf, 0, iAmt); + if( iOfstsz ) memcpy(zBuf, p->aData+iOfst, p->sz - iOfst); + memdbLeave(p); + return SQLITE_IOERR_SHORT_READ; + } + memcpy(zBuf, p->aData+iOfst, iAmt); + memdbLeave(p); + return SQLITE_OK; +} + +/* +** Try to enlarge the memory allocation to hold at least sz bytes +*/ +static int memdbEnlarge(MemStore *p, sqlite3_int64 newSz){ + unsigned char *pNew; + if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || NEVER(p->nMmap>0) ){ + return SQLITE_FULL; + } + if( newSz>p->szMax ){ + return SQLITE_FULL; + } + newSz *= 2; + if( newSz>p->szMax ) newSz = p->szMax; + pNew = sqlite3Realloc(p->aData, newSz); + if( pNew==0 ) return SQLITE_IOERR_NOMEM; + p->aData = pNew; + p->szAlloc = newSz; + return SQLITE_OK; +} + +/* +** Write data to an memdb-file. +*/ +static int memdbWrite( + sqlite3_file *pFile, + const void *z, + int iAmt, + sqlite_int64 iOfst +){ + MemStore *p = ((MemFile*)pFile)->pStore; + memdbEnter(p); + if( NEVER(p->mFlags & SQLITE_DESERIALIZE_READONLY) ){ + /* Can't happen: memdbLock() will return SQLITE_READONLY before + ** reaching this point */ + memdbLeave(p); + return SQLITE_IOERR_WRITE; + } + if( iOfst+iAmt>p->sz ){ + int rc; + if( iOfst+iAmt>p->szAlloc + && (rc = memdbEnlarge(p, iOfst+iAmt))!=SQLITE_OK + ){ + memdbLeave(p); + return rc; + } + if( iOfst>p->sz ) memset(p->aData+p->sz, 0, iOfst-p->sz); + p->sz = iOfst+iAmt; + } + memcpy(p->aData+iOfst, z, iAmt); + memdbLeave(p); + return SQLITE_OK; +} + +/* +** Truncate an memdb-file. +** +** In rollback mode (which is always the case for memdb, as it does not +** support WAL mode) the truncate() method is only used to reduce +** the size of a file, never to increase the size. +*/ +static int memdbTruncate(sqlite3_file *pFile, sqlite_int64 size){ + MemStore *p = ((MemFile*)pFile)->pStore; + int rc = SQLITE_OK; + memdbEnter(p); + if( size>p->sz ){ + /* This can only happen with a corrupt wal mode db */ + rc = SQLITE_CORRUPT; + }else{ + p->sz = size; + } + memdbLeave(p); + return rc; +} + +/* +** Sync an memdb-file. +*/ +static int memdbSync(sqlite3_file *pFile, int flags){ + UNUSED_PARAMETER(pFile); + UNUSED_PARAMETER(flags); + return SQLITE_OK; +} + +/* +** Return the current file-size of an memdb-file. +*/ +static int memdbFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ + MemStore *p = ((MemFile*)pFile)->pStore; + memdbEnter(p); + *pSize = p->sz; + memdbLeave(p); + return SQLITE_OK; +} + +/* +** Lock an memdb-file. +*/ +static int memdbLock(sqlite3_file *pFile, int eLock){ + MemFile *pThis = (MemFile*)pFile; + MemStore *p = pThis->pStore; + int rc = SQLITE_OK; + if( eLock<=pThis->eLock ) return SQLITE_OK; + memdbEnter(p); + + assert( p->nWrLock==0 || p->nWrLock==1 ); + assert( pThis->eLock<=SQLITE_LOCK_SHARED || p->nWrLock==1 ); + assert( pThis->eLock==SQLITE_LOCK_NONE || p->nRdLock>=1 ); + + if( eLock>SQLITE_LOCK_SHARED && (p->mFlags & SQLITE_DESERIALIZE_READONLY) ){ + rc = SQLITE_READONLY; + }else{ + switch( eLock ){ + case SQLITE_LOCK_SHARED: { + assert( pThis->eLock==SQLITE_LOCK_NONE ); + if( p->nWrLock>0 ){ + rc = SQLITE_BUSY; + }else{ + p->nRdLock++; + } + break; + }; + + case SQLITE_LOCK_RESERVED: + case SQLITE_LOCK_PENDING: { + assert( pThis->eLock>=SQLITE_LOCK_SHARED ); + if( ALWAYS(pThis->eLock==SQLITE_LOCK_SHARED) ){ + if( p->nWrLock>0 ){ + rc = SQLITE_BUSY; + }else{ + p->nWrLock = 1; + } + } + break; + } + + default: { + assert( eLock==SQLITE_LOCK_EXCLUSIVE ); + assert( pThis->eLock>=SQLITE_LOCK_SHARED ); + if( p->nRdLock>1 ){ + rc = SQLITE_BUSY; + }else if( pThis->eLock==SQLITE_LOCK_SHARED ){ + p->nWrLock = 1; + } + break; + } + } + } + if( rc==SQLITE_OK ) pThis->eLock = eLock; + memdbLeave(p); + return rc; +} + +/* +** Unlock an memdb-file. +*/ +static int memdbUnlock(sqlite3_file *pFile, int eLock){ + MemFile *pThis = (MemFile*)pFile; + MemStore *p = pThis->pStore; + if( eLock>=pThis->eLock ) return SQLITE_OK; + memdbEnter(p); + + assert( eLock==SQLITE_LOCK_SHARED || eLock==SQLITE_LOCK_NONE ); + if( eLock==SQLITE_LOCK_SHARED ){ + if( ALWAYS(pThis->eLock>SQLITE_LOCK_SHARED) ){ + p->nWrLock--; + } + }else{ + if( pThis->eLock>SQLITE_LOCK_SHARED ){ + p->nWrLock--; + } + p->nRdLock--; + } + + pThis->eLock = eLock; + memdbLeave(p); + return SQLITE_OK; +} + +#if 0 +/* +** This interface is only used for crash recovery, which does not +** occur on an in-memory database. +*/ +static int memdbCheckReservedLock(sqlite3_file *pFile, int *pResOut){ + *pResOut = 0; + return SQLITE_OK; +} +#endif + + +/* +** File control method. For custom operations on an memdb-file. +*/ +static int memdbFileControl(sqlite3_file *pFile, int op, void *pArg){ + MemStore *p = ((MemFile*)pFile)->pStore; + int rc = SQLITE_NOTFOUND; + memdbEnter(p); + if( op==SQLITE_FCNTL_VFSNAME ){ + *(char**)pArg = sqlite3_mprintf("memdb(%p,%lld)", p->aData, p->sz); + rc = SQLITE_OK; + } + if( op==SQLITE_FCNTL_SIZE_LIMIT ){ + sqlite3_int64 iLimit = *(sqlite3_int64*)pArg; + if( iLimitsz ){ + if( iLimit<0 ){ + iLimit = p->szMax; + }else{ + iLimit = p->sz; + } + } + p->szMax = iLimit; + *(sqlite3_int64*)pArg = iLimit; + rc = SQLITE_OK; + } + memdbLeave(p); + return rc; +} + +#if 0 /* Not used because of SQLITE_IOCAP_POWERSAFE_OVERWRITE */ +/* +** Return the sector-size in bytes for an memdb-file. +*/ +static int memdbSectorSize(sqlite3_file *pFile){ + return 1024; +} +#endif + +/* +** Return the device characteristic flags supported by an memdb-file. +*/ +static int memdbDeviceCharacteristics(sqlite3_file *pFile){ + UNUSED_PARAMETER(pFile); + return SQLITE_IOCAP_ATOMIC | + SQLITE_IOCAP_POWERSAFE_OVERWRITE | + SQLITE_IOCAP_SAFE_APPEND | + SQLITE_IOCAP_SEQUENTIAL; +} + +/* Fetch a page of a memory-mapped file */ +static int memdbFetch( + sqlite3_file *pFile, + sqlite3_int64 iOfst, + int iAmt, + void **pp +){ + MemStore *p = ((MemFile*)pFile)->pStore; + memdbEnter(p); + if( iOfst+iAmt>p->sz || (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)!=0 ){ + *pp = 0; + }else{ + p->nMmap++; + *pp = (void*)(p->aData + iOfst); + } + memdbLeave(p); + return SQLITE_OK; +} + +/* Release a memory-mapped page */ +static int memdbUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){ + MemStore *p = ((MemFile*)pFile)->pStore; + UNUSED_PARAMETER(iOfst); + UNUSED_PARAMETER(pPage); + memdbEnter(p); + p->nMmap--; + memdbLeave(p); + return SQLITE_OK; +} + +/* +** Open an mem file handle. +*/ +static int memdbOpen( + sqlite3_vfs *pVfs, + const char *zName, + sqlite3_file *pFd, + int flags, + int *pOutFlags +){ + MemFile *pFile = (MemFile*)pFd; + MemStore *p = 0; + int szName; + UNUSED_PARAMETER(pVfs); + + memset(pFile, 0, sizeof(*pFile)); + szName = sqlite3Strlen30(zName); + if( szName>1 && (zName[0]=='/' || zName[0]=='\\') ){ + int i; +#ifndef SQLITE_MUTEX_OMIT + sqlite3_mutex *pVfsMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); +#endif + sqlite3_mutex_enter(pVfsMutex); + for(i=0; izFName,zName)==0 ){ + p = memdb_g.apMemStore[i]; + break; + } + } + if( p==0 ){ + MemStore **apNew; + p = sqlite3Malloc( sizeof(*p) + (i64)szName + 3 ); + if( p==0 ){ + sqlite3_mutex_leave(pVfsMutex); + return SQLITE_NOMEM; + } + apNew = sqlite3Realloc(memdb_g.apMemStore, + sizeof(apNew[0])*(1+(i64)memdb_g.nMemStore) ); + if( apNew==0 ){ + sqlite3_free(p); + sqlite3_mutex_leave(pVfsMutex); + return SQLITE_NOMEM; + } + apNew[memdb_g.nMemStore++] = p; + memdb_g.apMemStore = apNew; + memset(p, 0, sizeof(*p)); + p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE|SQLITE_DESERIALIZE_FREEONCLOSE; + p->szMax = sqlite3GlobalConfig.mxMemdbSize; + p->zFName = (char*)&p[1]; + memcpy(p->zFName, zName, szName+1); + p->pMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( p->pMutex==0 ){ + memdb_g.nMemStore--; + sqlite3_free(p); + sqlite3_mutex_leave(pVfsMutex); + return SQLITE_NOMEM; + } + p->nRef = 1; + memdbEnter(p); + }else{ + memdbEnter(p); + p->nRef++; + } + sqlite3_mutex_leave(pVfsMutex); + }else{ + p = sqlite3Malloc( sizeof(*p) ); + if( p==0 ){ + return SQLITE_NOMEM; + } + memset(p, 0, sizeof(*p)); + p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE; + p->szMax = sqlite3GlobalConfig.mxMemdbSize; + } + pFile->pStore = p; + if( pOutFlags!=0 ){ + *pOutFlags = flags | SQLITE_OPEN_MEMORY; + } + pFd->pMethods = &memdb_io_methods; + memdbLeave(p); + return SQLITE_OK; +} + +#if 0 /* Only used to delete rollback journals, super-journals, and WAL + ** files, none of which exist in memdb. So this routine is never used */ +/* +** Delete the file located at zPath. If the dirSync argument is true, +** ensure the file-system modifications are synced to disk before +** returning. +*/ +static int memdbDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ + return SQLITE_IOERR_DELETE; +} +#endif + +/* +** Test for access permissions. Return true if the requested permission +** is available, or false otherwise. +** +** With memdb, no files ever exist on disk. So always return false. +*/ +static int memdbAccess( + sqlite3_vfs *pVfs, + const char *zPath, + int flags, + int *pResOut +){ + UNUSED_PARAMETER(pVfs); + UNUSED_PARAMETER(zPath); + UNUSED_PARAMETER(flags); + *pResOut = 0; + return SQLITE_OK; +} + +/* +** Populate buffer zOut with the full canonical pathname corresponding +** to the pathname in zPath. zOut is guaranteed to point to a buffer +** of at least (INST_MAX_PATHNAME+1) bytes. +*/ +static int memdbFullPathname( + sqlite3_vfs *pVfs, + const char *zPath, + int nOut, + char *zOut +){ + UNUSED_PARAMETER(pVfs); + sqlite3_snprintf(nOut, zOut, "%s", zPath); + return SQLITE_OK; +} + +/* +** Open the dynamic library located at zPath and return a handle. +*/ +static void *memdbDlOpen(sqlite3_vfs *pVfs, const char *zPath){ + return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath); +} + +/* +** Populate the buffer zErrMsg (size nByte bytes) with a human readable +** utf-8 string describing the most recent error encountered associated +** with dynamic libraries. +*/ +static void memdbDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){ + ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg); +} + +/* +** Return a pointer to the symbol zSymbol in the dynamic library pHandle. +*/ +static void (*memdbDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){ + return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym); +} + +/* +** Close the dynamic library handle pHandle. +*/ +static void memdbDlClose(sqlite3_vfs *pVfs, void *pHandle){ + ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle); +} + +/* +** Populate the buffer pointed to by zBufOut with nByte bytes of +** random data. +*/ +static int memdbRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ + return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut); +} + +/* +** Sleep for nMicro microseconds. Return the number of microseconds +** actually slept. +*/ +static int memdbSleep(sqlite3_vfs *pVfs, int nMicro){ + return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro); +} + +#if 0 /* Never used. Modern cores only call xCurrentTimeInt64() */ +/* +** Return the current time as a Julian Day number in *pTimeOut. +*/ +static int memdbCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ + return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut); +} +#endif + +static int memdbGetLastError(sqlite3_vfs *pVfs, int a, char *b){ + return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b); +} +static int memdbCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){ + return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p); +} + +/* +** Translate a database connection pointer and schema name into a +** MemFile pointer. +*/ +static MemFile *memdbFromDbSchema(sqlite3 *db, const char *zSchema){ + MemFile *p = 0; + MemStore *pStore; + int rc = sqlite3_file_control(db, zSchema, SQLITE_FCNTL_FILE_POINTER, &p); + if( rc ) return 0; + if( p->base.pMethods!=&memdb_io_methods ) return 0; + pStore = p->pStore; + memdbEnter(pStore); + if( pStore->zFName!=0 ) p = 0; + memdbLeave(pStore); + return p; +} + +/* +** Return the serialization of a database +*/ +SQLITE_API unsigned char *sqlite3_serialize( + sqlite3 *db, /* The database connection */ + const char *zSchema, /* Which database within the connection */ + sqlite3_int64 *piSize, /* Write size here, if not NULL */ + unsigned int mFlags /* Maybe SQLITE_SERIALIZE_NOCOPY */ +){ + MemFile *p; + int iDb; + Btree *pBt; + sqlite3_int64 sz; + int szPage = 0; + sqlite3_stmt *pStmt = 0; + unsigned char *pOut = 0; + char *zSql; + int rc; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + + if( zSchema==0 ) zSchema = db->aDb[0].zDbSName; + p = memdbFromDbSchema(db, zSchema); + iDb = sqlite3FindDbName(db, zSchema); + if( piSize ) *piSize = -1; + if( iDb<0 ) goto serialize_out; + if( p ){ + MemStore *pStore = p->pStore; + assert( pStore->pMutex==0 ); + if( piSize ) *piSize = pStore->sz; + if( mFlags & SQLITE_SERIALIZE_NOCOPY ){ + pOut = pStore->aData; + }else{ + pOut = sqlite3_malloc64( pStore->sz ); + if( pOut ) memcpy(pOut, pStore->aData, pStore->sz); + } + goto serialize_out; + } + pBt = db->aDb[iDb].pBt; + if( pBt==0 ) goto serialize_out; + szPage = sqlite3BtreeGetPageSize(pBt); + zSql = sqlite3_mprintf("PRAGMA \"%w\".page_count", zSchema); + rc = zSql ? sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0) : SQLITE_NOMEM; + sqlite3_free(zSql); + if( rc ) goto serialize_out; + rc = sqlite3_step(pStmt); + if( rc==SQLITE_ROW ){ + sz = sqlite3_column_int64(pStmt, 0)*szPage; + if( sz==0 ){ + sqlite3_reset(pStmt); + sqlite3_exec(db, "BEGIN IMMEDIATE; COMMIT;", 0, 0, 0); + rc = sqlite3_step(pStmt); + if( rc==SQLITE_ROW ){ + sz = sqlite3_column_int64(pStmt, 0)*szPage; + } + } + if( piSize ) *piSize = sz; + if( mFlags & SQLITE_SERIALIZE_NOCOPY ){ + pOut = 0; + }else{ + pOut = sqlite3_malloc64( sz ); + if( pOut ){ + int nPage = sqlite3_column_int(pStmt, 0); + Pager *pPager = sqlite3BtreePager(pBt); + int pgno; + for(pgno=1; pgno<=nPage; pgno++){ + DbPage *pPage = 0; + unsigned char *pTo = pOut + szPage*(sqlite3_int64)(pgno-1); + rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pPage, 0); + if( rc==SQLITE_OK ){ + memcpy(pTo, sqlite3PagerGetData(pPage), szPage); + }else{ + memset(pTo, 0, szPage); + } + sqlite3PagerUnref(pPage); + } + } + } + } + sqlite3_finalize(pStmt); + + serialize_out: + sqlite3_mutex_leave(db->mutex); + return pOut; +} + +/* Convert zSchema to a MemDB and initialize its content. +*/ +SQLITE_API int sqlite3_deserialize( + sqlite3 *db, /* The database connection */ + const char *zSchema, /* Which DB to reopen with the deserialization */ + unsigned char *pData, /* The serialized database content */ + sqlite3_int64 szDb, /* Number bytes in the deserialization */ + sqlite3_int64 szBuf, /* Total size of buffer pData[] */ + unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */ +){ + MemFile *p; + char *zSql; + sqlite3_stmt *pStmt = 0; + int rc; + int iDb; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + return SQLITE_MISUSE_BKPT; + } + if( szDb<0 ) return SQLITE_MISUSE_BKPT; + if( szBuf<0 ) return SQLITE_MISUSE_BKPT; +#endif + + sqlite3_mutex_enter(db->mutex); + if( zSchema==0 ) zSchema = db->aDb[0].zDbSName; + iDb = sqlite3FindDbName(db, zSchema); + testcase( iDb==1 ); + if( iDb<2 && iDb!=0 ){ + rc = SQLITE_ERROR; + goto end_deserialize; + } + zSql = sqlite3_mprintf("ATTACH x AS %Q", zSchema); + if( zSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + } + if( rc ) goto end_deserialize; + db->init.iDb = (u8)iDb; + db->init.reopenMemdb = 1; + sqlite3_step(pStmt); + db->init.reopenMemdb = 0; + rc = sqlite3_finalize(pStmt); + if( rc!=SQLITE_OK ){ + goto end_deserialize; + } + p = memdbFromDbSchema(db, zSchema); + if( p==0 ){ + rc = SQLITE_ERROR; + }else{ + MemStore *pStore = p->pStore; + pStore->aData = pData; + pData = 0; + pStore->sz = szDb; + pStore->szAlloc = szBuf; + pStore->szMax = szBuf; + if( pStore->szMaxszMax = sqlite3GlobalConfig.mxMemdbSize; + } + pStore->mFlags = mFlags; + rc = SQLITE_OK; + } + +end_deserialize: + if( pData && (mFlags & SQLITE_DESERIALIZE_FREEONCLOSE)!=0 ){ + sqlite3_free(pData); + } + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Return true if the VFS is the memvfs. +*/ +SQLITE_PRIVATE int sqlite3IsMemdb(const sqlite3_vfs *pVfs){ + return pVfs==&memdb_vfs; +} + +/* +** This routine is called when the extension is loaded. +** Register the new VFS. +*/ +SQLITE_PRIVATE int sqlite3MemdbInit(void){ + sqlite3_vfs *pLower = sqlite3_vfs_find(0); + unsigned int sz; + if( NEVER(pLower==0) ) return SQLITE_ERROR; + sz = pLower->szOsFile; + memdb_vfs.pAppData = pLower; + /* The following conditional can only be true when compiled for + ** Windows x86 and SQLITE_MAX_MMAP_SIZE=0. We always leave + ** it in, to be safe, but it is marked as NO_TEST since there + ** is no way to reach it under most builds. */ + if( szBITVEC_NBIT and iDivisor==0 then Bitvec.u.aHash[] is +** a hash table that will hold up to BITVEC_MXHASH distinct values. +** +** Otherwise, the value i is redirected into one of BITVEC_NPTR +** sub-bitmaps pointed to by Bitvec.u.apSub[]. Each subbitmap +** handles up to iDivisor separate values of i. apSub[0] holds +** values between 1 and iDivisor. apSub[1] holds values between +** iDivisor+1 and 2*iDivisor. apSub[N] holds values between +** N*iDivisor+1 and (N+1)*iDivisor. Each subbitmap is normalized +** to hold deal with values between 1 and iDivisor. +*/ +struct Bitvec { + u32 iSize; /* Maximum bit index. Max iSize is 4,294,967,296. */ + u32 nSet; /* Number of bits that are set - only valid for aHash + ** element. Max is BITVEC_NINT. For BITVEC_SZ of 512, + ** this would be 125. */ + u32 iDivisor; /* Number of bits handled by each apSub[] entry. */ + /* Should >=0 for apSub element. */ + /* Max iDivisor is max(u32) / BITVEC_NPTR + 1. */ + /* For a BITVEC_SZ of 512, this would be 34,359,739. */ + union { + BITVEC_TELEM aBitmap[BITVEC_NELEM]; /* Bitmap representation */ + u32 aHash[BITVEC_NINT]; /* Hash table representation */ + Bitvec *apSub[BITVEC_NPTR]; /* Recursive representation */ + } u; +}; + + +/* +** Create a new bitmap object able to handle bits between 0 and iSize, +** inclusive. Return a pointer to the new object. Return NULL if +** malloc fails. +*/ +SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32 iSize){ + Bitvec *p; + assert( sizeof(*p)==BITVEC_SZ ); + p = sqlite3MallocZero( sizeof(*p) ); + if( p ){ + p->iSize = iSize; + } + return p; +} + +/* +** Check to see if the i-th bit is set. Return true or false. +** If p is NULL (if the bitmap has not been created) or if +** i is out of range, then return false. +*/ +SQLITE_PRIVATE int sqlite3BitvecTestNotNull(Bitvec *p, u32 i){ + assert( p!=0 ); + i--; + if( i>=p->iSize ) return 0; + while( p->iDivisor ){ + u32 bin = i/p->iDivisor; + i = i%p->iDivisor; + p = p->u.apSub[bin]; + if (!p) { + return 0; + } + } + if( p->iSize<=BITVEC_NBIT ){ + return (p->u.aBitmap[i/BITVEC_SZELEM] & (1<<(i&(BITVEC_SZELEM-1))))!=0; + } else{ + u32 h = BITVEC_HASH(i++); + while( p->u.aHash[h] ){ + if( p->u.aHash[h]==i ) return 1; + h = (h+1) % BITVEC_NINT; + } + return 0; + } +} +SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec *p, u32 i){ + return p!=0 && sqlite3BitvecTestNotNull(p,i); +} + +/* +** Set the i-th bit. Return 0 on success and an error code if +** anything goes wrong. +** +** This routine might cause sub-bitmaps to be allocated. Failing +** to get the memory needed to hold the sub-bitmap is the only +** that can go wrong with an insert, assuming p and i are valid. +** +** The calling function must ensure that p is a valid Bitvec object +** and that the value for "i" is within range of the Bitvec object. +** Otherwise the behavior is undefined. +*/ +SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec *p, u32 i){ + u32 h; + if( p==0 ) return SQLITE_OK; + assert( i>0 ); + assert( i<=p->iSize ); + i--; + while((p->iSize > BITVEC_NBIT) && p->iDivisor) { + u32 bin = i/p->iDivisor; + i = i%p->iDivisor; + if( p->u.apSub[bin]==0 ){ + p->u.apSub[bin] = sqlite3BitvecCreate( p->iDivisor ); + if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM_BKPT; + } + p = p->u.apSub[bin]; + } + if( p->iSize<=BITVEC_NBIT ){ + p->u.aBitmap[i/BITVEC_SZELEM] |= 1 << (i&(BITVEC_SZELEM-1)); + return SQLITE_OK; + } + h = BITVEC_HASH(i++); + /* if there wasn't a hash collision, and this doesn't */ + /* completely fill the hash, then just add it without */ + /* worrying about sub-dividing and re-hashing. */ + if( !p->u.aHash[h] ){ + if (p->nSet<(BITVEC_NINT-1)) { + goto bitvec_set_end; + } else { + goto bitvec_set_rehash; + } + } + /* there was a collision, check to see if it's already */ + /* in hash, if not, try to find a spot for it */ + do { + if( p->u.aHash[h]==i ) return SQLITE_OK; + h++; + if( h>=BITVEC_NINT ) h = 0; + } while( p->u.aHash[h] ); + /* we didn't find it in the hash. h points to the first */ + /* available free spot. check to see if this is going to */ + /* make our hash too "full". */ +bitvec_set_rehash: + if( p->nSet>=BITVEC_MXHASH ){ + unsigned int j; + int rc; + u32 *aiValues = sqlite3StackAllocRaw(0, sizeof(p->u.aHash)); + if( aiValues==0 ){ + return SQLITE_NOMEM_BKPT; + }else{ + memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash)); + memset(p->u.apSub, 0, sizeof(p->u.apSub)); + p->iDivisor = p->iSize/BITVEC_NPTR; + if( (p->iSize%BITVEC_NPTR)!=0 ) p->iDivisor++; + if( p->iDivisoriDivisor = BITVEC_NBIT; + rc = sqlite3BitvecSet(p, i); + for(j=0; jnSet++; + p->u.aHash[h] = i; + return SQLITE_OK; +} + +/* +** Clear the i-th bit. +** +** pBuf must be a pointer to at least BITVEC_SZ bytes of temporary storage +** that BitvecClear can use to rebuilt its hash table. +*/ +SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec *p, u32 i, void *pBuf){ + if( p==0 ) return; + assert( i>0 ); + i--; + while( p->iDivisor ){ + u32 bin = i/p->iDivisor; + i = i%p->iDivisor; + p = p->u.apSub[bin]; + if (!p) { + return; + } + } + if( p->iSize<=BITVEC_NBIT ){ + p->u.aBitmap[i/BITVEC_SZELEM] &= ~(BITVEC_TELEM)(1<<(i&(BITVEC_SZELEM-1))); + }else{ + unsigned int j; + u32 *aiValues = pBuf; + memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash)); + memset(p->u.aHash, 0, sizeof(p->u.aHash)); + p->nSet = 0; + for(j=0; jnSet++; + while( p->u.aHash[h] ){ + h++; + if( h>=BITVEC_NINT ) h = 0; + } + p->u.aHash[h] = aiValues[j]; + } + } + } +} + +/* +** Destroy a bitmap object. Reclaim all memory used. +*/ +SQLITE_PRIVATE void sqlite3BitvecDestroy(Bitvec *p){ + if( p==0 ) return; + if( p->iDivisor ){ + unsigned int i; + for(i=0; iu.apSub[i]); + } + } + sqlite3_free(p); +} + +/* +** Return the value of the iSize parameter specified when Bitvec *p +** was created. +*/ +SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec *p){ + return p->iSize; +} + +#ifdef SQLITE_DEBUG +/* +** Show the content of a Bitvec option and its children. Indent +** everything by n spaces. Add x to each bitvec value. +** +** From a debugger such as gdb, one can type: +** +** call sqlite3ShowBitvec(p) +** +** For some Bitvec p and see a recursive view of the Bitvec's content. +*/ +static void showBitvec(Bitvec *p, int n, unsigned x){ + int i; + if( p==0 ){ + printf("NULL\n"); + return; + } + printf("Bitvec 0x%p iSize=%u", p, p->iSize); + if( p->iSize<=BITVEC_NBIT ){ + printf(" bitmap\n"); + printf("%*s bits:", n, ""); + for(i=1; i<=BITVEC_NBIT; i++){ + if( sqlite3BitvecTest(p,i) ) printf(" %u", x+(unsigned)i); + } + printf("\n"); + }else if( p->iDivisor==0 ){ + printf(" hash with %u entries\n", p->nSet); + printf("%*s bits:", n, ""); + for(i=0; iu.aHash[i] ) printf(" %u", x+(unsigned)p->u.aHash[i]); + } + printf("\n"); + }else{ + printf(" sub-bitvec with iDivisor=%u\n", p->iDivisor); + for(i=0; iu.apSub[i]==0 ) continue; + printf("%*s apSub[%d]=", n, "", i); + showBitvec(p->u.apSub[i], n+4, i*p->iDivisor); + } + } +} +SQLITE_PRIVATE void sqlite3ShowBitvec(Bitvec *p){ + showBitvec(p, 0, 0); +} +#endif + +#ifndef SQLITE_UNTESTABLE +/* +** Let V[] be an array of unsigned characters sufficient to hold +** up to N bits. Let I be an integer between 0 and N. 0<=I>3] |= (1<<(I&7)) +#define CLEARBIT(V,I) V[I>>3] &= ~(BITVEC_TELEM)(1<<(I&7)) +#define TESTBIT(V,I) (V[I>>3]&(1<<(I&7)))!=0 + + +/* +** This routine runs an extensive test of the Bitvec code. +** +** The input is an array of integers that acts as a program +** to test the Bitvec. The integers are opcodes followed +** by 0, 1, or 3 operands, depending on the opcode. Another +** opcode follows immediately after the last operand. +** +** There are opcodes numbered starting with 0. 0 is the +** "halt" opcode and causes the test to end. +** +** 0 Halt and return the number of errors +** 1 N S X Set N bits beginning with S and incrementing by X +** 2 N S X Clear N bits beginning with S and incrementing by X +** 3 N Set N randomly chosen bits +** 4 N Clear N randomly chosen bits +** 5 N S X Set N bits from S increment X in array only, not in bitvec +** 6 Invoice sqlite3ShowBitvec() on the Bitvec object so far +** 7 X Show compile-time parameters and the hash of X +** +** The opcodes 1 through 4 perform set and clear operations are performed +** on both a Bitvec object and on a linear array of bits obtained from malloc. +** Opcode 5 works on the linear array only, not on the Bitvec. +** Opcode 5 is used to deliberately induce a fault in order to +** confirm that error detection works. Opcodes 6 and greater are +** state output opcodes. Opcodes 6 and greater are no-ops unless +** SQLite has been compiled with SQLITE_DEBUG. +** +** At the conclusion of the test the linear array is compared +** against the Bitvec object. If there are any differences, +** an error is returned. If they are the same, zero is returned. +** +** If a memory allocation error occurs, return -1. +** +** sz is the size of the Bitvec. Or if sz is negative, make the size +** 2*(unsigned)(-sz) and disabled the linear vector check. +*/ +SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){ + Bitvec *pBitvec = 0; + unsigned char *pV = 0; + int rc = -1; + int i, nx, pc, op; + void *pTmpSpace; + + /* Allocate the Bitvec to be tested and a linear array of + ** bits to act as the reference */ + if( sz<=0 ){ + pBitvec = sqlite3BitvecCreate( 2*(unsigned)(-sz) ); + pV = 0; + }else{ + pBitvec = sqlite3BitvecCreate( sz ); + pV = sqlite3MallocZero( (7+(i64)sz)/8 + 1 ); + } + pTmpSpace = sqlite3_malloc64(BITVEC_SZ); + if( pBitvec==0 || pTmpSpace==0 || (pV==0 && sz>0) ) goto bitvec_end; + + /* NULL pBitvec tests */ + sqlite3BitvecSet(0, 1); + sqlite3BitvecClear(0, 1, pTmpSpace); + + /* Run the program */ + pc = i = 0; + while( (op = aOp[pc])!=0 ){ + if( op>=6 ){ +#ifdef SQLITE_DEBUG + if( op==6 ){ + sqlite3ShowBitvec(pBitvec); + }else if( op==7 ){ + printf("BITVEC_SZ = %d (%d by sizeof)\n", + BITVEC_SZ, (int)sizeof(Bitvec)); + printf("BITVEC_USIZE = %d\n", (int)BITVEC_USIZE); + printf("BITVEC_NELEM = %d\n", (int)BITVEC_NELEM); + printf("BITVEC_NBIT = %d\n", (int)BITVEC_NBIT); + printf("BITVEC_NINT = %d\n", (int)BITVEC_NINT); + printf("BITVEC_MXHASH = %d\n", (int)BITVEC_MXHASH); + printf("BITVEC_NPTR = %d\n", (int)BITVEC_NPTR); + } +#endif + pc++; + continue; + } + switch( op ){ + case 1: + case 2: + case 5: { + nx = 4; + i = aOp[pc+2] - 1; + aOp[pc+2] += aOp[pc+3]; + break; + } + case 3: + case 4: + default: { + nx = 2; + sqlite3_randomness(sizeof(i), &i); + break; + } + } + if( (--aOp[pc+1]) > 0 ) nx = 0; + pc += nx; + i = (i & 0x7fffffff)%sz; + if( (op & 1)!=0 ){ + if( pV ) SETBIT(pV, (i+1)); + if( op!=5 ){ + if( sqlite3BitvecSet(pBitvec, i+1) ) goto bitvec_end; + } + }else{ + if( pV ) CLEARBIT(pV, (i+1)); + sqlite3BitvecClear(pBitvec, i+1, pTmpSpace); + } + } + + /* Test to make sure the linear array exactly matches the + ** Bitvec object. Start with the assumption that they do + ** match (rc==0). Change rc to non-zero if a discrepancy + ** is found. + */ + if( pV ){ + rc = sqlite3BitvecTest(0,0) + sqlite3BitvecTest(pBitvec, sz+1) + + sqlite3BitvecTest(pBitvec, 0) + + (sqlite3BitvecSize(pBitvec) - sz); + for(i=1; i<=sz; i++){ + if( (TESTBIT(pV,i))!=sqlite3BitvecTest(pBitvec,i) ){ + rc = i; + break; + } + } + }else{ + rc = 0; + } + + /* Free allocated structure */ +bitvec_end: + sqlite3_free(pTmpSpace); + sqlite3_free(pV); + sqlite3BitvecDestroy(pBitvec); + return rc; +} +#endif /* SQLITE_UNTESTABLE */ + +/************** End of bitvec.c **********************************************/ +/************** Begin file pcache.c ******************************************/ +/* +** 2008 August 05 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file implements that page cache. +*/ +/* #include "sqliteInt.h" */ + +/* +** A complete page cache is an instance of this structure. Every +** entry in the cache holds a single page of the database file. The +** btree layer only operates on the cached copy of the database pages. +** +** A page cache entry is "clean" if it exactly matches what is currently +** on disk. A page is "dirty" if it has been modified and needs to be +** persisted to disk. +** +** pDirty, pDirtyTail, pSynced: +** All dirty pages are linked into the doubly linked list using +** PgHdr.pDirtyNext and pDirtyPrev. The list is maintained in LRU order +** such that p was added to the list more recently than p->pDirtyNext. +** PCache.pDirty points to the first (newest) element in the list and +** pDirtyTail to the last (oldest). +** +** The PCache.pSynced variable is used to optimize searching for a dirty +** page to eject from the cache mid-transaction. It is better to eject +** a page that does not require a journal sync than one that does. +** Therefore, pSynced is maintained so that it *almost* always points +** to either the oldest page in the pDirty/pDirtyTail list that has a +** clear PGHDR_NEED_SYNC flag or to a page that is older than this one +** (so that the right page to eject can be found by following pDirtyPrev +** pointers). +*/ +struct PCache { + PgHdr *pDirty, *pDirtyTail; /* List of dirty pages in LRU order */ + PgHdr *pSynced; /* Last synced page in dirty page list */ + i64 nRefSum; /* Sum of ref counts over all pages */ + int szCache; /* Configured cache size */ + int szSpill; /* Size before spilling occurs */ + int szPage; /* Size of every page in this cache */ + int szExtra; /* Size of extra space for each page */ + u8 bPurgeable; /* True if pages are on backing store */ + u8 eCreate; /* eCreate value for for xFetch() */ + int (*xStress)(void*,PgHdr*); /* Call to try make a page clean */ + void *pStress; /* Argument to xStress */ + sqlite3_pcache *pCache; /* Pluggable cache module */ +}; + +/********************************** Test and Debug Logic **********************/ +/* +** Debug tracing macros. Enable by by changing the "0" to "1" and +** recompiling. +** +** When sqlite3PcacheTrace is 1, single line trace messages are issued. +** When sqlite3PcacheTrace is 2, a dump of the pcache showing all cache entries +** is displayed for many operations, resulting in a lot of output. +*/ +#if defined(SQLITE_DEBUG) && 0 + int sqlite3PcacheTrace = 2; /* 0: off 1: simple 2: cache dumps */ + int sqlite3PcacheMxDump = 9999; /* Max cache entries for pcacheDump() */ +# define pcacheTrace(X) if(sqlite3PcacheTrace){sqlite3DebugPrintf X;} + static void pcachePageTrace(int i, sqlite3_pcache_page *pLower){ + PgHdr *pPg; + unsigned char *a; + int j; + if( pLower==0 ){ + printf("%3d: NULL\n", i); + }else{ + pPg = (PgHdr*)pLower->pExtra; + printf("%3d: nRef %2lld flgs %02x data ", i, pPg->nRef, pPg->flags); + a = (unsigned char *)pLower->pBuf; + for(j=0; j<12; j++) printf("%02x", a[j]); + printf(" ptr %p\n", pPg); + } + } + static void pcacheDump(PCache *pCache){ + int N; + int i; + sqlite3_pcache_page *pLower; + + if( sqlite3PcacheTrace<2 ) return; + if( pCache->pCache==0 ) return; + N = sqlite3PcachePagecount(pCache); + if( N>sqlite3PcacheMxDump ) N = sqlite3PcacheMxDump; + for(i=1; i<=N; i++){ + pLower = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, i, 0); + pcachePageTrace(i, pLower); + if( pLower && ((PgHdr*)pLower)->pPage==0 ){ + sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, pLower, 0); + } + } + } +#else +# define pcacheTrace(X) +# define pcachePageTrace(PGNO, X) +# define pcacheDump(X) +#endif + +/* +** Return 1 if pPg is on the dirty list for pCache. Return 0 if not. +** This routine runs inside of assert() statements only. +*/ +#if defined(SQLITE_ENABLE_EXPENSIVE_ASSERT) +static int pageOnDirtyList(PCache *pCache, PgHdr *pPg){ + PgHdr *p; + for(p=pCache->pDirty; p; p=p->pDirtyNext){ + if( p==pPg ) return 1; + } + return 0; +} +static int pageNotOnDirtyList(PCache *pCache, PgHdr *pPg){ + PgHdr *p; + for(p=pCache->pDirty; p; p=p->pDirtyNext){ + if( p==pPg ) return 0; + } + return 1; +} +#else +# define pageOnDirtyList(A,B) 1 +# define pageNotOnDirtyList(A,B) 1 +#endif + +/* +** Check invariants on a PgHdr entry. Return true if everything is OK. +** Return false if any invariant is violated. +** +** This routine is for use inside of assert() statements only. For +** example: +** +** assert( sqlite3PcachePageSanity(pPg) ); +*/ +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3PcachePageSanity(PgHdr *pPg){ + PCache *pCache; + assert( pPg!=0 ); + assert( pPg->pgno>0 || pPg->pPager==0 ); /* Page number is 1 or more */ + pCache = pPg->pCache; + assert( pCache!=0 ); /* Every page has an associated PCache */ + if( pPg->flags & PGHDR_CLEAN ){ + assert( (pPg->flags & PGHDR_DIRTY)==0 );/* Cannot be both CLEAN and DIRTY */ + assert( pageNotOnDirtyList(pCache, pPg) );/* CLEAN pages not on dirtylist */ + }else{ + assert( (pPg->flags & PGHDR_DIRTY)!=0 );/* If not CLEAN must be DIRTY */ + assert( pPg->pDirtyNext==0 || pPg->pDirtyNext->pDirtyPrev==pPg ); + assert( pPg->pDirtyPrev==0 || pPg->pDirtyPrev->pDirtyNext==pPg ); + assert( pPg->pDirtyPrev!=0 || pCache->pDirty==pPg ); + assert( pageOnDirtyList(pCache, pPg) ); + } + /* WRITEABLE pages must also be DIRTY */ + if( pPg->flags & PGHDR_WRITEABLE ){ + assert( pPg->flags & PGHDR_DIRTY ); /* WRITEABLE implies DIRTY */ + } + /* NEED_SYNC can be set independently of WRITEABLE. This can happen, + ** for example, when using the sqlite3PagerDontWrite() optimization: + ** (1) Page X is journalled, and gets WRITEABLE and NEED_SEEK. + ** (2) Page X moved to freelist, WRITEABLE is cleared + ** (3) Page X reused, WRITEABLE is set again + ** If NEED_SYNC had been cleared in step 2, then it would not be reset + ** in step 3, and page might be written into the database without first + ** syncing the rollback journal, which might cause corruption on a power + ** loss. + ** + ** Another example is when the database page size is smaller than the + ** disk sector size. When any page of a sector is journalled, all pages + ** in that sector are marked NEED_SYNC even if they are still CLEAN, just + ** in case they are later modified, since all pages in the same sector + ** must be journalled and synced before any of those pages can be safely + ** written. + */ + return 1; +} +#endif /* SQLITE_DEBUG */ + + +/********************************** Linked List Management ********************/ + +/* Allowed values for second argument to pcacheManageDirtyList() */ +#define PCACHE_DIRTYLIST_REMOVE 1 /* Remove pPage from dirty list */ +#define PCACHE_DIRTYLIST_ADD 2 /* Add pPage to the dirty list */ +#define PCACHE_DIRTYLIST_FRONT 3 /* Move pPage to the front of the list */ + +/* +** Manage pPage's participation on the dirty list. Bits of the addRemove +** argument determines what operation to do. The 0x01 bit means first +** remove pPage from the dirty list. The 0x02 means add pPage back to +** the dirty list. Doing both moves pPage to the front of the dirty list. +*/ +static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){ + PCache *p = pPage->pCache; + + pcacheTrace(("%p.DIRTYLIST.%s %d\n", p, + addRemove==1 ? "REMOVE" : addRemove==2 ? "ADD" : "FRONT", + pPage->pgno)); + if( addRemove & PCACHE_DIRTYLIST_REMOVE ){ + assert( pPage->pDirtyNext || pPage==p->pDirtyTail ); + assert( pPage->pDirtyPrev || pPage==p->pDirty ); + + /* Update the PCache1.pSynced variable if necessary. */ + if( p->pSynced==pPage ){ + p->pSynced = pPage->pDirtyPrev; + } + + if( pPage->pDirtyNext ){ + pPage->pDirtyNext->pDirtyPrev = pPage->pDirtyPrev; + }else{ + assert( pPage==p->pDirtyTail ); + p->pDirtyTail = pPage->pDirtyPrev; + } + if( pPage->pDirtyPrev ){ + pPage->pDirtyPrev->pDirtyNext = pPage->pDirtyNext; + }else{ + /* If there are now no dirty pages in the cache, set eCreate to 2. + ** This is an optimization that allows sqlite3PcacheFetch() to skip + ** searching for a dirty page to eject from the cache when it might + ** otherwise have to. */ + assert( pPage==p->pDirty ); + p->pDirty = pPage->pDirtyNext; + assert( p->bPurgeable || p->eCreate==2 ); + if( p->pDirty==0 ){ /*OPTIMIZATION-IF-TRUE*/ + assert( p->bPurgeable==0 || p->eCreate==1 ); + p->eCreate = 2; + } + } + } + if( addRemove & PCACHE_DIRTYLIST_ADD ){ + pPage->pDirtyPrev = 0; + pPage->pDirtyNext = p->pDirty; + if( pPage->pDirtyNext ){ + assert( pPage->pDirtyNext->pDirtyPrev==0 ); + pPage->pDirtyNext->pDirtyPrev = pPage; + }else{ + p->pDirtyTail = pPage; + if( p->bPurgeable ){ + assert( p->eCreate==2 ); + p->eCreate = 1; + } + } + p->pDirty = pPage; + + /* If pSynced is NULL and this page has a clear NEED_SYNC flag, set + ** pSynced to point to it. Checking the NEED_SYNC flag is an + ** optimization, as if pSynced points to a page with the NEED_SYNC + ** flag set sqlite3PcacheFetchStress() searches through all newer + ** entries of the dirty-list for a page with NEED_SYNC clear anyway. */ + if( !p->pSynced + && 0==(pPage->flags&PGHDR_NEED_SYNC) /*OPTIMIZATION-IF-FALSE*/ + ){ + p->pSynced = pPage; + } + } + pcacheDump(p); +} + +/* +** Wrapper around the pluggable caches xUnpin method. If the cache is +** being used for an in-memory database, this function is a no-op. +*/ +static void pcacheUnpin(PgHdr *p){ + if( p->pCache->bPurgeable ){ + pcacheTrace(("%p.UNPIN %d\n", p->pCache, p->pgno)); + sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 0); + pcacheDump(p->pCache); + } +} + +/* +** Compute the number of pages of cache requested. p->szCache is the +** cache size requested by the "PRAGMA cache_size" statement. +*/ +static int numberOfCachePages(PCache *p){ + if( p->szCache>=0 ){ + /* IMPLEMENTATION-OF: R-42059-47211 If the argument N is positive then the + ** suggested cache size is set to N. */ + return p->szCache; + }else{ + i64 n; + /* IMPLEMENTATION-OF: R-59858-46238 If the argument N is negative, then the + ** number of cache pages is adjusted to be a number of pages that would + ** use approximately abs(N*1024) bytes of memory based on the current + ** page size. */ + n = ((-1024*(i64)p->szCache)/(p->szPage+p->szExtra)); + if( n>1000000000 ) n = 1000000000; + return (int)n; + } +} + +/*************************************************** General Interfaces ****** +** +** Initialize and shutdown the page cache subsystem. Neither of these +** functions are threadsafe. +*/ +SQLITE_PRIVATE int sqlite3PcacheInitialize(void){ + if( sqlite3GlobalConfig.pcache2.xInit==0 ){ + /* IMPLEMENTATION-OF: R-26801-64137 If the xInit() method is NULL, then the + ** built-in default page cache is used instead of the application defined + ** page cache. */ + sqlite3PCacheSetDefault(); + assert( sqlite3GlobalConfig.pcache2.xInit!=0 ); + } + return sqlite3GlobalConfig.pcache2.xInit(sqlite3GlobalConfig.pcache2.pArg); +} +SQLITE_PRIVATE void sqlite3PcacheShutdown(void){ + if( sqlite3GlobalConfig.pcache2.xShutdown ){ + /* IMPLEMENTATION-OF: R-26000-56589 The xShutdown() method may be NULL. */ + sqlite3GlobalConfig.pcache2.xShutdown(sqlite3GlobalConfig.pcache2.pArg); + } +} + +/* +** Return the size in bytes of a PCache object. +*/ +SQLITE_PRIVATE int sqlite3PcacheSize(void){ return sizeof(PCache); } + +/* +** Create a new PCache object. Storage space to hold the object +** has already been allocated and is passed in as the p pointer. +** The caller discovers how much space needs to be allocated by +** calling sqlite3PcacheSize(). +** +** szExtra is some extra space allocated for each page. The first +** 8 bytes of the extra space will be zeroed as the page is allocated, +** but remaining content will be uninitialized. Though it is opaque +** to this module, the extra space really ends up being the MemPage +** structure in the pager. +*/ +SQLITE_PRIVATE int sqlite3PcacheOpen( + int szPage, /* Size of every page */ + int szExtra, /* Extra space associated with each page */ + int bPurgeable, /* True if pages are on backing store */ + int (*xStress)(void*,PgHdr*),/* Call to try to make pages clean */ + void *pStress, /* Argument to xStress */ + PCache *p /* Preallocated space for the PCache */ +){ + memset(p, 0, sizeof(PCache)); + p->szPage = 1; + p->szExtra = szExtra; + assert( szExtra>=8 ); /* First 8 bytes will be zeroed */ + p->bPurgeable = bPurgeable; + p->eCreate = 2; + p->xStress = xStress; + p->pStress = pStress; + p->szCache = 100; + p->szSpill = 1; + pcacheTrace(("%p.OPEN szPage %d bPurgeable %d\n",p,szPage,bPurgeable)); + return sqlite3PcacheSetPageSize(p, szPage); +} + +/* +** Change the page size for PCache object. The caller must ensure that there +** are no outstanding page references when this function is called. +*/ +SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){ + assert( pCache->nRefSum==0 && pCache->pDirty==0 ); + if( pCache->szPage ){ + sqlite3_pcache *pNew; + pNew = sqlite3GlobalConfig.pcache2.xCreate( + szPage, pCache->szExtra + ROUND8(sizeof(PgHdr)), + pCache->bPurgeable + ); + if( pNew==0 ) return SQLITE_NOMEM_BKPT; + sqlite3GlobalConfig.pcache2.xCachesize(pNew, numberOfCachePages(pCache)); + if( pCache->pCache ){ + sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); + } + pCache->pCache = pNew; + pCache->szPage = szPage; + pcacheTrace(("%p.PAGESIZE %d\n",pCache,szPage)); + } + return SQLITE_OK; +} + +/* +** Try to obtain a page from the cache. +** +** This routine returns a pointer to an sqlite3_pcache_page object if +** such an object is already in cache, or if a new one is created. +** This routine returns a NULL pointer if the object was not in cache +** and could not be created. +** +** The createFlags should be 0 to check for existing pages and should +** be 3 (not 1, but 3) to try to create a new page. +** +** If the createFlag is 0, then NULL is always returned if the page +** is not already in the cache. If createFlag is 1, then a new page +** is created only if that can be done without spilling dirty pages +** and without exceeding the cache size limit. +** +** The caller needs to invoke sqlite3PcacheFetchFinish() to properly +** initialize the sqlite3_pcache_page object and convert it into a +** PgHdr object. The sqlite3PcacheFetch() and sqlite3PcacheFetchFinish() +** routines are split this way for performance reasons. When separated +** they can both (usually) operate without having to push values to +** the stack on entry and pop them back off on exit, which saves a +** lot of pushing and popping. +*/ +SQLITE_PRIVATE sqlite3_pcache_page *sqlite3PcacheFetch( + PCache *pCache, /* Obtain the page from this cache */ + Pgno pgno, /* Page number to obtain */ + int createFlag /* If true, create page if it does not exist already */ +){ + int eCreate; + sqlite3_pcache_page *pRes; + + assert( pCache!=0 ); + assert( pCache->pCache!=0 ); + assert( createFlag==3 || createFlag==0 ); + assert( pCache->eCreate==((pCache->bPurgeable && pCache->pDirty) ? 1 : 2) ); + + /* eCreate defines what to do if the page does not exist. + ** 0 Do not allocate a new page. (createFlag==0) + ** 1 Allocate a new page if doing so is inexpensive. + ** (createFlag==1 AND bPurgeable AND pDirty) + ** 2 Allocate a new page even it doing so is difficult. + ** (createFlag==1 AND !(bPurgeable AND pDirty) + */ + eCreate = createFlag & pCache->eCreate; + assert( eCreate==0 || eCreate==1 || eCreate==2 ); + assert( createFlag==0 || pCache->eCreate==eCreate ); + assert( createFlag==0 || eCreate==1+(!pCache->bPurgeable||!pCache->pDirty) ); + pRes = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate); + pcacheTrace(("%p.FETCH %d%s (result: %p) ",pCache,pgno, + createFlag?" create":"",pRes)); + pcachePageTrace(pgno, pRes); + return pRes; +} + +/* +** If the sqlite3PcacheFetch() routine is unable to allocate a new +** page because no clean pages are available for reuse and the cache +** size limit has been reached, then this routine can be invoked to +** try harder to allocate a page. This routine might invoke the stress +** callback to spill dirty pages to the journal. It will then try to +** allocate the new page and will only fail to allocate a new page on +** an OOM error. +** +** This routine should be invoked only after sqlite3PcacheFetch() fails. +*/ +SQLITE_PRIVATE int sqlite3PcacheFetchStress( + PCache *pCache, /* Obtain the page from this cache */ + Pgno pgno, /* Page number to obtain */ + sqlite3_pcache_page **ppPage /* Write result here */ +){ + PgHdr *pPg; + if( pCache->eCreate==2 ) return 0; + + if( sqlite3PcachePagecount(pCache)>pCache->szSpill ){ + /* Find a dirty page to write-out and recycle. First try to find a + ** page that does not require a journal-sync (one with PGHDR_NEED_SYNC + ** cleared), but if that is not possible settle for any other + ** unreferenced dirty page. + ** + ** If the LRU page in the dirty list that has a clear PGHDR_NEED_SYNC + ** flag is currently referenced, then the following may leave pSynced + ** set incorrectly (pointing to other than the LRU page with NEED_SYNC + ** cleared). This is Ok, as pSynced is just an optimization. */ + for(pPg=pCache->pSynced; + pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC)); + pPg=pPg->pDirtyPrev + ); + pCache->pSynced = pPg; + if( !pPg ){ + for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev); + } + if( pPg ){ + int rc; +#ifdef SQLITE_LOG_CACHE_SPILL + sqlite3_log(SQLITE_FULL, + "spill page %d making room for %d - cache used: %d/%d", + pPg->pgno, pgno, + sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache), + numberOfCachePages(pCache)); +#endif + pcacheTrace(("%p.SPILL %d\n",pCache,pPg->pgno)); + rc = pCache->xStress(pCache->pStress, pPg); + pcacheDump(pCache); + if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){ + return rc; + } + } + } + *ppPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2); + return *ppPage==0 ? SQLITE_NOMEM_BKPT : SQLITE_OK; +} + +/* +** This is a helper routine for sqlite3PcacheFetchFinish() +** +** In the uncommon case where the page being fetched has not been +** initialized, this routine is invoked to do the initialization. +** This routine is broken out into a separate function since it +** requires extra stack manipulation that can be avoided in the common +** case. +*/ +static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit( + PCache *pCache, /* Obtain the page from this cache */ + Pgno pgno, /* Page number obtained */ + sqlite3_pcache_page *pPage /* Page obtained by prior PcacheFetch() call */ +){ + PgHdr *pPgHdr; + assert( pPage!=0 ); + pPgHdr = (PgHdr*)pPage->pExtra; + assert( pPgHdr->pPage==0 ); + memset(&pPgHdr->pDirty, 0, sizeof(PgHdr) - offsetof(PgHdr,pDirty)); + pPgHdr->pPage = pPage; + pPgHdr->pData = pPage->pBuf; + pPgHdr->pExtra = (void *)&pPgHdr[1]; + memset(pPgHdr->pExtra, 0, 8); + assert( EIGHT_BYTE_ALIGNMENT( pPgHdr->pExtra ) ); + pPgHdr->pCache = pCache; + pPgHdr->pgno = pgno; + pPgHdr->flags = PGHDR_CLEAN; + return sqlite3PcacheFetchFinish(pCache,pgno,pPage); +} + +/* +** This routine converts the sqlite3_pcache_page object returned by +** sqlite3PcacheFetch() into an initialized PgHdr object. This routine +** must be called after sqlite3PcacheFetch() in order to get a usable +** result. +*/ +SQLITE_PRIVATE PgHdr *sqlite3PcacheFetchFinish( + PCache *pCache, /* Obtain the page from this cache */ + Pgno pgno, /* Page number obtained */ + sqlite3_pcache_page *pPage /* Page obtained by prior PcacheFetch() call */ +){ + PgHdr *pPgHdr; + + assert( pPage!=0 ); + pPgHdr = (PgHdr *)pPage->pExtra; + + if( !pPgHdr->pPage ){ + return pcacheFetchFinishWithInit(pCache, pgno, pPage); + } + pCache->nRefSum++; + pPgHdr->nRef++; + assert( sqlite3PcachePageSanity(pPgHdr) ); + return pPgHdr; +} + +/* +** Decrement the reference count on a page. If the page is clean and the +** reference count drops to 0, then it is made eligible for recycling. +*/ +SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){ + assert( p->nRef>0 ); + p->pCache->nRefSum--; + if( (--p->nRef)==0 ){ + if( p->flags&PGHDR_CLEAN ){ + pcacheUnpin(p); + }else{ + pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT); + assert( sqlite3PcachePageSanity(p) ); + } + } +} + +/* +** Increase the reference count of a supplied page by 1. +*/ +SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr *p){ + assert(p->nRef>0); + assert( sqlite3PcachePageSanity(p) ); + p->nRef++; + p->pCache->nRefSum++; +} + +/* +** Drop a page from the cache. There must be exactly one reference to the +** page. This function deletes that reference, so after it returns the +** page pointed to by p is invalid. +*/ +SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr *p){ + assert( p->nRef==1 ); + assert( sqlite3PcachePageSanity(p) ); + if( p->flags&PGHDR_DIRTY ){ + pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); + } + p->pCache->nRefSum--; + sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 1); +} + +/* +** Make sure the page is marked as dirty. If it isn't dirty already, +** make it so. +*/ +SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){ + assert( p->nRef>0 ); + assert( sqlite3PcachePageSanity(p) ); + if( p->flags & (PGHDR_CLEAN|PGHDR_DONT_WRITE) ){ /*OPTIMIZATION-IF-FALSE*/ + p->flags &= ~PGHDR_DONT_WRITE; + if( p->flags & PGHDR_CLEAN ){ + p->flags ^= (PGHDR_DIRTY|PGHDR_CLEAN); + pcacheTrace(("%p.DIRTY %d\n",p->pCache,p->pgno)); + assert( (p->flags & (PGHDR_DIRTY|PGHDR_CLEAN))==PGHDR_DIRTY ); + pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD); + assert( sqlite3PcachePageSanity(p) ); + } + assert( sqlite3PcachePageSanity(p) ); + } +} + +/* +** Make sure the page is marked as clean. If it isn't clean already, +** make it so. +*/ +SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr *p){ + assert( sqlite3PcachePageSanity(p) ); + assert( (p->flags & PGHDR_DIRTY)!=0 ); + assert( (p->flags & PGHDR_CLEAN)==0 ); + pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); + p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC|PGHDR_WRITEABLE); + p->flags |= PGHDR_CLEAN; + pcacheTrace(("%p.CLEAN %d\n",p->pCache,p->pgno)); + assert( sqlite3PcachePageSanity(p) ); + if( p->nRef==0 ){ + pcacheUnpin(p); + } +} + +/* +** Make every page in the cache clean. +*/ +SQLITE_PRIVATE void sqlite3PcacheCleanAll(PCache *pCache){ + PgHdr *p; + pcacheTrace(("%p.CLEAN-ALL\n",pCache)); + while( (p = pCache->pDirty)!=0 ){ + sqlite3PcacheMakeClean(p); + } +} + +/* +** Clear the PGHDR_NEED_SYNC and PGHDR_WRITEABLE flag from all dirty pages. +*/ +SQLITE_PRIVATE void sqlite3PcacheClearWritable(PCache *pCache){ + PgHdr *p; + pcacheTrace(("%p.CLEAR-WRITEABLE\n",pCache)); + for(p=pCache->pDirty; p; p=p->pDirtyNext){ + p->flags &= ~(PGHDR_NEED_SYNC|PGHDR_WRITEABLE); + } + pCache->pSynced = pCache->pDirtyTail; +} + +/* +** Clear the PGHDR_NEED_SYNC flag from all dirty pages. +*/ +SQLITE_PRIVATE void sqlite3PcacheClearSyncFlags(PCache *pCache){ + PgHdr *p; + for(p=pCache->pDirty; p; p=p->pDirtyNext){ + p->flags &= ~PGHDR_NEED_SYNC; + } + pCache->pSynced = pCache->pDirtyTail; +} + +/* +** Change the page number of page p to newPgno. +*/ +SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){ + PCache *pCache = p->pCache; + sqlite3_pcache_page *pOther; + assert( p->nRef>0 ); + assert( newPgno>0 ); + assert( sqlite3PcachePageSanity(p) ); + pcacheTrace(("%p.MOVE %d -> %d\n",pCache,p->pgno,newPgno)); + pOther = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, newPgno, 0); + if( pOther ){ + PgHdr *pXPage = (PgHdr*)pOther->pExtra; + assert( pXPage->nRef==0 ); + pXPage->nRef++; + pCache->nRefSum++; + sqlite3PcacheDrop(pXPage); + } + sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno); + p->pgno = newPgno; + if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){ + pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT); + assert( sqlite3PcachePageSanity(p) ); + } +} + +/* +** Drop every cache entry whose page number is greater than "pgno". The +** caller must ensure that there are no outstanding references to any pages +** other than page 1 with a page number greater than pgno. +** +** If there is a reference to page 1 and the pgno parameter passed to this +** function is 0, then the data area associated with page 1 is zeroed, but +** the page object is not dropped. +*/ +SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){ + if( pCache->pCache ){ + PgHdr *p; + PgHdr *pNext; + pcacheTrace(("%p.TRUNCATE %d\n",pCache,pgno)); + for(p=pCache->pDirty; p; p=pNext){ + pNext = p->pDirtyNext; + /* This routine never gets call with a positive pgno except right + ** after sqlite3PcacheCleanAll(). So if there are dirty pages, + ** it must be that pgno==0. + */ + assert( p->pgno>0 ); + if( p->pgno>pgno ){ + assert( p->flags&PGHDR_DIRTY ); + sqlite3PcacheMakeClean(p); + } + } + if( pgno==0 && pCache->nRefSum ){ + sqlite3_pcache_page *pPage1; + pPage1 = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache,1,0); + if( ALWAYS(pPage1) ){ /* Page 1 is always available in cache, because + ** pCache->nRefSum>0 */ + memset(pPage1->pBuf, 0, pCache->szPage); + pgno = 1; + } + } + sqlite3GlobalConfig.pcache2.xTruncate(pCache->pCache, pgno+1); + } +} + +/* +** Close a cache. +*/ +SQLITE_PRIVATE void sqlite3PcacheClose(PCache *pCache){ + assert( pCache->pCache!=0 ); + pcacheTrace(("%p.CLOSE\n",pCache)); + sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); +} + +/* +** Discard the contents of the cache. +*/ +SQLITE_PRIVATE void sqlite3PcacheClear(PCache *pCache){ + sqlite3PcacheTruncate(pCache, 0); +} + +/* +** Merge two lists of pages connected by pDirty and in pgno order. +** Do not bother fixing the pDirtyPrev pointers. +*/ +static PgHdr *pcacheMergeDirtyList(PgHdr *pA, PgHdr *pB){ + PgHdr result, *pTail; + pTail = &result; + assert( pA!=0 && pB!=0 ); + for(;;){ + if( pA->pgnopgno ){ + pTail->pDirty = pA; + pTail = pA; + pA = pA->pDirty; + if( pA==0 ){ + pTail->pDirty = pB; + break; + } + }else{ + pTail->pDirty = pB; + pTail = pB; + pB = pB->pDirty; + if( pB==0 ){ + pTail->pDirty = pA; + break; + } + } + } + return result.pDirty; +} + +/* +** Sort the list of pages in ascending order by pgno. Pages are +** connected by pDirty pointers. The pDirtyPrev pointers are +** corrupted by this sort. +** +** Since there cannot be more than 2^31 distinct pages in a database, +** there cannot be more than 31 buckets required by the merge sorter. +** One extra bucket is added to catch overflow in case something +** ever changes to make the previous sentence incorrect. +*/ +#define N_SORT_BUCKET 32 +static PgHdr *pcacheSortDirtyList(PgHdr *pIn){ + PgHdr *a[N_SORT_BUCKET], *p; + int i; + memset(a, 0, sizeof(a)); + while( pIn ){ + p = pIn; + pIn = p->pDirty; + p->pDirty = 0; + for(i=0; ALWAYS(ipDirty; p; p=p->pDirtyNext){ + p->pDirty = p->pDirtyNext; + } + return pcacheSortDirtyList(pCache->pDirty); +} + +/* +** Return the total number of references to all pages held by the cache. +** +** This is not the total number of pages referenced, but the sum of the +** reference count for all pages. +*/ +SQLITE_PRIVATE i64 sqlite3PcacheRefCount(PCache *pCache){ + return pCache->nRefSum; +} + +/* +** Return the number of references to the page supplied as an argument. +*/ +SQLITE_PRIVATE i64 sqlite3PcachePageRefcount(PgHdr *p){ + return p->nRef; +} + +/* +** Return the total number of pages in the cache. +*/ +SQLITE_PRIVATE int sqlite3PcachePagecount(PCache *pCache){ + assert( pCache->pCache!=0 ); + return sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache); +} + +#ifdef SQLITE_TEST +/* +** Get the suggested cache-size value. +*/ +SQLITE_PRIVATE int sqlite3PcacheGetCachesize(PCache *pCache){ + return numberOfCachePages(pCache); +} +#endif + +/* +** Set the suggested cache-size value. +*/ +SQLITE_PRIVATE void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){ + assert( pCache->pCache!=0 ); + pCache->szCache = mxPage; + sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache, + numberOfCachePages(pCache)); +} + +/* +** Set the suggested cache-spill value. Make no changes if if the +** argument is zero. Return the effective cache-spill size, which will +** be the larger of the szSpill and szCache. +*/ +SQLITE_PRIVATE int sqlite3PcacheSetSpillsize(PCache *p, int mxPage){ + int res; + assert( p->pCache!=0 ); + if( mxPage ){ + if( mxPage<0 ){ + mxPage = (int)((-1024*(i64)mxPage)/(p->szPage+p->szExtra)); + } + p->szSpill = mxPage; + } + res = numberOfCachePages(p); + if( resszSpill ) res = p->szSpill; + return res; +} + +/* +** Free up as much memory as possible from the page cache. +*/ +SQLITE_PRIVATE void sqlite3PcacheShrink(PCache *pCache){ + assert( pCache->pCache!=0 ); + sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache); +} + +/* +** Return the size of the header added by this middleware layer +** in the page-cache hierarchy. +*/ +SQLITE_PRIVATE int sqlite3HeaderSizePcache(void){ return ROUND8(sizeof(PgHdr)); } + +/* +** Return the number of dirty pages currently in the cache, as a percentage +** of the configured cache size. +*/ +SQLITE_PRIVATE int sqlite3PCachePercentDirty(PCache *pCache){ + PgHdr *pDirty; + int nDirty = 0; + int nCache = numberOfCachePages(pCache); + for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext) nDirty++; + return nCache ? (int)(((i64)nDirty * 100) / nCache) : 0; +} + +#ifdef SQLITE_DIRECT_OVERFLOW_READ +/* +** Return true if there are one or more dirty pages in the cache. Else false. +*/ +SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache){ + return (pCache->pDirty!=0); +} +#endif + +#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG) +/* +** For all dirty pages currently in the cache, invoke the specified +** callback. This is only used if the SQLITE_CHECK_PAGES macro is +** defined. +*/ +SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)){ + PgHdr *pDirty; + for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext){ + xIter(pDirty); + } +} +#endif + +/************** End of pcache.c **********************************************/ +/************** Begin file pcache1.c *****************************************/ +/* +** 2008 November 05 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file implements the default page cache implementation (the +** sqlite3_pcache interface). It also contains part of the implementation +** of the SQLITE_CONFIG_PAGECACHE and sqlite3_release_memory() features. +** If the default page cache implementation is overridden, then neither of +** these two features are available. +** +** A Page cache line looks like this: +** +** ------------------------------------------------------------- +** | database page content | PgHdr1 | MemPage | PgHdr | +** ------------------------------------------------------------- +** +** The database page content is up front (so that buffer overreads tend to +** flow harmlessly into the PgHdr1, MemPage, and PgHdr extensions). MemPage +** is the extension added by the btree.c module containing information such +** as the database page number and how that database page is used. PgHdr +** is added by the pcache.c layer and contains information used to keep track +** of which pages are "dirty". PgHdr1 is an extension added by this +** module (pcache1.c). The PgHdr1 header is a subclass of sqlite3_pcache_page. +** PgHdr1 contains information needed to look up a page by its page number. +** The superclass sqlite3_pcache_page.pBuf points to the start of the +** database page content and sqlite3_pcache_page.pExtra points to PgHdr. +** +** The size of the extension (MemPage+PgHdr+PgHdr1) can be determined at +** runtime using sqlite3_config(SQLITE_CONFIG_PCACHE_HDRSZ, &size). The +** sizes of the extensions sum to 272 bytes on x64 for 3.8.10, but this +** size can vary according to architecture, compile-time options, and +** SQLite library version number. +** +** Historical note: It used to be that if the SQLITE_PCACHE_SEPARATE_HEADER +** was defined, then the page content would be held in a separate memory +** allocation from the PgHdr1. This was intended to avoid clownshoe memory +** allocations. However, the btree layer needs a small (16-byte) overrun +** area after the page content buffer. The header serves as that overrun +** area. Therefore SQLITE_PCACHE_SEPARATE_HEADER was discontinued to avoid +** any possibility of a memory error. +** +** This module tracks pointers to PgHdr1 objects. Only pcache.c communicates +** with this module. Information is passed back and forth as PgHdr1 pointers. +** +** The pcache.c and pager.c modules deal pointers to PgHdr objects. +** The btree.c module deals with pointers to MemPage objects. +** +** SOURCE OF PAGE CACHE MEMORY: +** +** Memory for a page might come from any of three sources: +** +** (1) The general-purpose memory allocator - sqlite3Malloc() +** (2) Global page-cache memory provided using sqlite3_config() with +** SQLITE_CONFIG_PAGECACHE. +** (3) PCache-local bulk allocation. +** +** The third case is a chunk of heap memory (defaulting to 100 pages worth) +** that is allocated when the page cache is created. The size of the local +** bulk allocation can be adjusted using +** +** sqlite3_config(SQLITE_CONFIG_PAGECACHE, (void*)0, 0, N). +** +** If N is positive, then N pages worth of memory are allocated using a single +** sqlite3Malloc() call and that memory is used for the first N pages allocated. +** Or if N is negative, then -1024*N bytes of memory are allocated and used +** for as many pages as can be accommodated. +** +** Only one of (2) or (3) can be used. Once the memory available to (2) or +** (3) is exhausted, subsequent allocations fail over to the general-purpose +** memory allocator (1). +** +** Earlier versions of SQLite used only methods (1) and (2). But experiments +** show that method (3) with N==100 provides about a 5% performance boost for +** common workloads. +*/ +/* #include "sqliteInt.h" */ + +typedef struct PCache1 PCache1; +typedef struct PgHdr1 PgHdr1; +typedef struct PgFreeslot PgFreeslot; +typedef struct PGroup PGroup; + +/* +** Each cache entry is represented by an instance of the following +** structure. A buffer of PgHdr1.pCache->szPage bytes is allocated +** directly before this structure and is used to cache the page content. +** +** When reading a corrupt database file, it is possible that SQLite might +** read a few bytes (no more than 16 bytes) past the end of the page buffer. +** It will only read past the end of the page buffer, never write. This +** object is positioned immediately after the page buffer to serve as an +** overrun area, so that overreads are harmless. +** +** Variables isBulkLocal and isAnchor were once type "u8". That works, +** but causes a 2-byte gap in the structure for most architectures (since +** pointers must be either 4 or 8-byte aligned). As this structure is located +** in memory directly after the associated page data, if the database is +** corrupt, code at the b-tree layer may overread the page buffer and +** read part of this structure before the corruption is detected. This +** can cause a valgrind error if the uninitialized gap is accessed. Using u16 +** ensures there is no such gap, and therefore no bytes of uninitialized +** memory in the structure. +** +** The pLruNext and pLruPrev pointers form a double-linked circular list +** of all pages that are unpinned. The PGroup.lru element (which should be +** the only element on the list with PgHdr1.isAnchor set to 1) forms the +** beginning and the end of the list. +*/ +struct PgHdr1 { + sqlite3_pcache_page page; /* Base class. Must be first. pBuf & pExtra */ + unsigned int iKey; /* Key value (page number) */ + u16 isBulkLocal; /* This page from bulk local storage */ + u16 isAnchor; /* This is the PGroup.lru element */ + PgHdr1 *pNext; /* Next in hash table chain */ + PCache1 *pCache; /* Cache that currently owns this page */ + PgHdr1 *pLruNext; /* Next in circular LRU list of unpinned pages */ + PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */ + /* NB: pLruPrev is only valid if pLruNext!=0 */ +}; + +/* +** A page is pinned if it is not on the LRU list. To be "pinned" means +** that the page is in active use and must not be deallocated. +*/ +#define PAGE_IS_PINNED(p) ((p)->pLruNext==0) +#define PAGE_IS_UNPINNED(p) ((p)->pLruNext!=0) + +/* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set +** of one or more PCaches that are able to recycle each other's unpinned +** pages when they are under memory pressure. A PGroup is an instance of +** the following object. +** +** This page cache implementation works in one of two modes: +** +** (1) Every PCache is the sole member of its own PGroup. There is +** one PGroup per PCache. +** +** (2) There is a single global PGroup that all PCaches are a member +** of. +** +** Mode 1 uses more memory (since PCache instances are not able to rob +** unused pages from other PCaches) but it also operates without a mutex, +** and is therefore often faster. Mode 2 requires a mutex in order to be +** threadsafe, but recycles pages more efficiently. +** +** For mode (1), PGroup.mutex is NULL. For mode (2) there is only a single +** PGroup which is the pcache1.grp global variable and its mutex is +** SQLITE_MUTEX_STATIC_LRU. +*/ +struct PGroup { + sqlite3_mutex *mutex; /* MUTEX_STATIC_LRU or NULL */ + unsigned int nMaxPage; /* Sum of nMax for purgeable caches */ + unsigned int nMinPage; /* Sum of nMin for purgeable caches */ + unsigned int mxPinned; /* nMaxpage + 10 - nMinPage */ + unsigned int nPurgeable; /* Number of purgeable pages allocated */ + PgHdr1 lru; /* The beginning and end of the LRU list */ +}; + +/* Each page cache is an instance of the following object. Every +** open database file (including each in-memory database and each +** temporary or transient database) has a single page cache which +** is an instance of this object. +** +** Pointers to structures of this type are cast and returned as +** opaque sqlite3_pcache* handles. +*/ +struct PCache1 { + /* Cache configuration parameters. Page size (szPage) and the purgeable + ** flag (bPurgeable) and the pnPurgeable pointer are all set when the + ** cache is created and are never changed thereafter. nMax may be + ** modified at any time by a call to the pcache1Cachesize() method. + ** The PGroup mutex must be held when accessing nMax. + */ + PGroup *pGroup; /* PGroup this cache belongs to */ + unsigned int *pnPurgeable; /* Pointer to pGroup->nPurgeable */ + int szPage; /* Size of database content section */ + int szExtra; /* sizeof(MemPage)+sizeof(PgHdr) */ + int szAlloc; /* Total size of one pcache line */ + int bPurgeable; /* True if cache is purgeable */ + unsigned int nMin; /* Minimum number of pages reserved */ + unsigned int nMax; /* Configured "cache_size" value */ + unsigned int n90pct; /* nMax*9/10 */ + unsigned int iMaxKey; /* Largest key seen since xTruncate() */ + unsigned int nPurgeableDummy; /* pnPurgeable points here when not used*/ + + /* Hash table of all pages. The following variables may only be accessed + ** when the accessor is holding the PGroup mutex. + */ + unsigned int nRecyclable; /* Number of pages in the LRU list */ + unsigned int nPage; /* Total number of pages in apHash */ + unsigned int nHash; /* Number of slots in apHash[] */ + PgHdr1 **apHash; /* Hash table for fast lookup by key */ + PgHdr1 *pFree; /* List of unused pcache-local pages */ + void *pBulk; /* Bulk memory used by pcache-local */ +}; + +/* +** Free slots in the allocator used to divide up the global page cache +** buffer provided using the SQLITE_CONFIG_PAGECACHE mechanism. +*/ +struct PgFreeslot { + PgFreeslot *pNext; /* Next free slot */ +}; + +/* +** Global data used by this cache. +*/ +static SQLITE_WSD struct PCacheGlobal { + PGroup grp; /* The global PGroup for mode (2) */ + + /* Variables related to SQLITE_CONFIG_PAGECACHE settings. The + ** szSlot, nSlot, pStart, pEnd, nReserve, and isInit values are all + ** fixed at sqlite3_initialize() time and do not require mutex protection. + ** The nFreeSlot and pFree values do require mutex protection. + */ + int isInit; /* True if initialized */ + int separateCache; /* Use a new PGroup for each PCache */ + int nInitPage; /* Initial bulk allocation size */ + int szSlot; /* Size of each free slot */ + int nSlot; /* The number of pcache slots */ + int nReserve; /* Try to keep nFreeSlot above this */ + void *pStart, *pEnd; /* Bounds of global page cache memory */ + /* Above requires no mutex. Use mutex below for variable that follow. */ + sqlite3_mutex *mutex; /* Mutex for accessing the following: */ + PgFreeslot *pFree; /* Free page blocks */ + int nFreeSlot; /* Number of unused pcache slots */ + int bUnderPressure; /* True if low on PAGECACHE memory */ +} pcache1_g; + +/* +** All code in this file should access the global structure above via the +** alias "pcache1". This ensures that the WSD emulation is used when +** compiling for systems that do not support real WSD. +*/ +#define pcache1 (GLOBAL(struct PCacheGlobal, pcache1_g)) + +/* +** Macros to enter and leave the PCache LRU mutex. +*/ +#if !defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) || SQLITE_THREADSAFE==0 +# define pcache1EnterMutex(X) assert((X)->mutex==0) +# define pcache1LeaveMutex(X) assert((X)->mutex==0) +# define PCACHE1_MIGHT_USE_GROUP_MUTEX 0 +#else +# define pcache1EnterMutex(X) sqlite3_mutex_enter((X)->mutex) +# define pcache1LeaveMutex(X) sqlite3_mutex_leave((X)->mutex) +# define PCACHE1_MIGHT_USE_GROUP_MUTEX 1 +#endif + +/******************************************************************************/ +/******** Page Allocation/SQLITE_CONFIG_PCACHE Related Functions **************/ + + +/* +** This function is called during initialization if a static buffer is +** supplied to use for the page-cache by passing the SQLITE_CONFIG_PAGECACHE +** verb to sqlite3_config(). Parameter pBuf points to an allocation large +** enough to contain 'n' buffers of 'sz' bytes each. +** +** This routine is called from sqlite3_initialize() and so it is guaranteed +** to be serialized already. There is no need for further mutexing. +*/ +SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){ + if( pcache1.isInit ){ + PgFreeslot *p; + if( pBuf==0 ) sz = n = 0; + if( n==0 ) sz = 0; + sz = ROUNDDOWN8(sz); + pcache1.szSlot = sz; + pcache1.nSlot = pcache1.nFreeSlot = n; + pcache1.nReserve = n>90 ? 10 : (n/10 + 1); + pcache1.pStart = pBuf; + pcache1.pFree = 0; + AtomicStore(&pcache1.bUnderPressure,0); + while( n-- ){ + p = (PgFreeslot*)pBuf; + p->pNext = pcache1.pFree; + pcache1.pFree = p; + pBuf = (void*)&((char*)pBuf)[sz]; + } + pcache1.pEnd = pBuf; + } +} + +/* +** Try to initialize the pCache->pFree and pCache->pBulk fields. Return +** true if pCache->pFree ends up containing one or more free pages. +*/ +static int pcache1InitBulk(PCache1 *pCache){ + i64 szBulk; + char *zBulk; + if( pcache1.nInitPage==0 ) return 0; + /* Do not bother with a bulk allocation if the cache size very small */ + if( pCache->nMax<3 ) return 0; + sqlite3BeginBenignMalloc(); + if( pcache1.nInitPage>0 ){ + szBulk = pCache->szAlloc * (i64)pcache1.nInitPage; + }else{ + szBulk = -1024 * (i64)pcache1.nInitPage; + } + if( szBulk > pCache->szAlloc*(i64)pCache->nMax ){ + szBulk = pCache->szAlloc*(i64)pCache->nMax; + } + if( szBulk>=pCache->szAlloc ){ + zBulk = pCache->pBulk = sqlite3Malloc( szBulk ); + sqlite3EndBenignMalloc(); + if( zBulk ){ + int nBulk = sqlite3MallocSize(zBulk)/pCache->szAlloc; + do{ + PgHdr1 *pX = (PgHdr1*)&zBulk[pCache->szPage]; + pX->page.pBuf = zBulk; + pX->page.pExtra = (u8*)pX + ROUND8(sizeof(*pX)); + assert( EIGHT_BYTE_ALIGNMENT( pX->page.pExtra ) ); + pX->isBulkLocal = 1; + pX->isAnchor = 0; + pX->pNext = pCache->pFree; + pX->pLruPrev = 0; /* Initializing this saves a valgrind error */ + pCache->pFree = pX; + zBulk += pCache->szAlloc; + }while( --nBulk ); + } + } + return pCache->pFree!=0; +} + +/* +** Malloc function used within this file to allocate space from the buffer +** configured using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no +** such buffer exists or there is no space left in it, this function falls +** back to sqlite3Malloc(). +** +** Multiple threads can run this routine at the same time. Global variables +** in pcache1 need to be protected via mutex. +*/ +static void *pcache1Alloc(int nByte){ + void *p = 0; + assert( sqlite3_mutex_notheld(pcache1.grp.mutex) ); + if( nByte<=pcache1.szSlot ){ + sqlite3_mutex_enter(pcache1.mutex); + p = (PgHdr1 *)pcache1.pFree; + if( p ){ + pcache1.pFree = pcache1.pFree->pNext; + pcache1.nFreeSlot--; + AtomicStore(&pcache1.bUnderPressure,pcache1.nFreeSlot=0 ); + sqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte); + sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_USED, 1); + } + sqlite3_mutex_leave(pcache1.mutex); + } + if( p==0 ){ + /* Memory is not available in the SQLITE_CONFIG_PAGECACHE pool. Get + ** it from sqlite3Malloc instead. + */ + p = sqlite3Malloc(nByte); +#ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS + if( p ){ + int sz = sqlite3MallocSize(p); + sqlite3_mutex_enter(pcache1.mutex); + sqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte); + sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz); + sqlite3_mutex_leave(pcache1.mutex); + } +#endif + sqlite3MemdebugSetType(p, MEMTYPE_PCACHE); + } + return p; +} + +/* +** Free an allocated buffer obtained from pcache1Alloc(). +*/ +static void pcache1Free(void *p){ + if( p==0 ) return; + if( SQLITE_WITHIN(p, pcache1.pStart, pcache1.pEnd) ){ + PgFreeslot *pSlot; + sqlite3_mutex_enter(pcache1.mutex); + sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_USED, 1); + pSlot = (PgFreeslot*)p; + pSlot->pNext = pcache1.pFree; + pcache1.pFree = pSlot; + pcache1.nFreeSlot++; + AtomicStore(&pcache1.bUnderPressure,pcache1.nFreeSlot=pcache1.pStart && ppGroup->mutex) ); + if( pCache->pFree || (pCache->nPage==0 && pcache1InitBulk(pCache)) ){ + assert( pCache->pFree!=0 ); + p = pCache->pFree; + pCache->pFree = p->pNext; + p->pNext = 0; + }else{ +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT + /* The group mutex must be released before pcache1Alloc() is called. This + ** is because it might call sqlite3_release_memory(), which assumes that + ** this mutex is not held. */ + assert( pcache1.separateCache==0 ); + assert( pCache->pGroup==&pcache1.grp ); + pcache1LeaveMutex(pCache->pGroup); +#endif + if( benignMalloc ){ sqlite3BeginBenignMalloc(); } + pPg = pcache1Alloc(pCache->szAlloc); + if( benignMalloc ){ sqlite3EndBenignMalloc(); } +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT + pcache1EnterMutex(pCache->pGroup); +#endif + if( pPg==0 ) return 0; + p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage]; + p->page.pBuf = pPg; + p->page.pExtra = (u8*)p + ROUND8(sizeof(*p)); + assert( EIGHT_BYTE_ALIGNMENT( p->page.pExtra ) ); + p->isBulkLocal = 0; + p->isAnchor = 0; + p->pLruPrev = 0; /* Initializing this saves a valgrind error */ + } + (*pCache->pnPurgeable)++; + return p; +} + +/* +** Free a page object allocated by pcache1AllocPage(). +*/ +static void pcache1FreePage(PgHdr1 *p){ + PCache1 *pCache; + assert( p!=0 ); + pCache = p->pCache; + assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) ); + if( p->isBulkLocal ){ + p->pNext = pCache->pFree; + pCache->pFree = p; + }else{ + pcache1Free(p->page.pBuf); + } + (*pCache->pnPurgeable)--; +} + +/* +** Malloc function used by SQLite to obtain space from the buffer configured +** using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no such buffer +** exists, this function falls back to sqlite3Malloc(). +*/ +SQLITE_PRIVATE void *sqlite3PageMalloc(int sz){ + assert( sz<=65536+8 ); /* These allocations are never very large */ + return pcache1Alloc(sz); +} + +/* +** Free an allocated buffer obtained from sqlite3PageMalloc(). +*/ +SQLITE_PRIVATE void sqlite3PageFree(void *p){ + pcache1Free(p); +} + + +/* +** Return true if it desirable to avoid allocating a new page cache +** entry. +** +** If memory was allocated specifically to the page cache using +** SQLITE_CONFIG_PAGECACHE but that memory has all been used, then +** it is desirable to avoid allocating a new page cache entry because +** presumably SQLITE_CONFIG_PAGECACHE was suppose to be sufficient +** for all page cache needs and we should not need to spill the +** allocation onto the heap. +** +** Or, the heap is used for all page cache memory but the heap is +** under memory pressure, then again it is desirable to avoid +** allocating a new page cache entry in order to avoid stressing +** the heap even further. +*/ +static int pcache1UnderMemoryPressure(PCache1 *pCache){ + if( pcache1.nSlot && (pCache->szPage+pCache->szExtra)<=pcache1.szSlot ){ + return AtomicLoad(&pcache1.bUnderPressure); + }else{ + return sqlite3HeapNearlyFull(); + } +} + +/******************************************************************************/ +/******** General Implementation Functions ************************************/ + +/* +** This function is used to resize the hash table used by the cache passed +** as the first argument. +** +** The PCache mutex must be held when this function is called. +*/ +static void pcache1ResizeHash(PCache1 *p){ + PgHdr1 **apNew; + u64 nNew; + u32 i; + + assert( sqlite3_mutex_held(p->pGroup->mutex) ); + + nNew = 2*(u64)p->nHash; + if( nNew<256 ){ + nNew = 256; + } + + pcache1LeaveMutex(p->pGroup); + if( p->nHash ){ sqlite3BeginBenignMalloc(); } + apNew = (PgHdr1 **)sqlite3MallocZero(sizeof(PgHdr1 *)*nNew); + if( p->nHash ){ sqlite3EndBenignMalloc(); } + pcache1EnterMutex(p->pGroup); + if( apNew ){ + for(i=0; inHash; i++){ + PgHdr1 *pPage; + PgHdr1 *pNext = p->apHash[i]; + while( (pPage = pNext)!=0 ){ + unsigned int h = pPage->iKey % nNew; + pNext = pPage->pNext; + pPage->pNext = apNew[h]; + apNew[h] = pPage; + } + } + sqlite3_free(p->apHash); + p->apHash = apNew; + p->nHash = nNew; + } +} + +/* +** This function is used internally to remove the page pPage from the +** PGroup LRU list, if is part of it. If pPage is not part of the PGroup +** LRU list, then this function is a no-op. +** +** The PGroup mutex must be held when this function is called. +*/ +static PgHdr1 *pcache1PinPage(PgHdr1 *pPage){ + assert( pPage!=0 ); + assert( PAGE_IS_UNPINNED(pPage) ); + assert( pPage->pLruNext ); + assert( pPage->pLruPrev ); + assert( sqlite3_mutex_held(pPage->pCache->pGroup->mutex) ); + pPage->pLruPrev->pLruNext = pPage->pLruNext; + pPage->pLruNext->pLruPrev = pPage->pLruPrev; + pPage->pLruNext = 0; + /* pPage->pLruPrev = 0; + ** No need to clear pLruPrev as it is never accessed if pLruNext is 0 */ + assert( pPage->isAnchor==0 ); + assert( pPage->pCache->pGroup->lru.isAnchor==1 ); + pPage->pCache->nRecyclable--; + return pPage; +} + + +/* +** Remove the page supplied as an argument from the hash table +** (PCache1.apHash structure) that it is currently stored in. +** Also free the page if freePage is true. +** +** The PGroup mutex must be held when this function is called. +*/ +static void pcache1RemoveFromHash(PgHdr1 *pPage, int freeFlag){ + unsigned int h; + PCache1 *pCache = pPage->pCache; + PgHdr1 **pp; + + assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); + h = pPage->iKey % pCache->nHash; + for(pp=&pCache->apHash[h]; (*pp)!=pPage; pp=&(*pp)->pNext); + *pp = (*pp)->pNext; + + pCache->nPage--; + if( freeFlag ) pcache1FreePage(pPage); +} + +/* +** If there are currently more than nMaxPage pages allocated, try +** to recycle pages to reduce the number allocated to nMaxPage. +*/ +static void pcache1EnforceMaxPage(PCache1 *pCache){ + PGroup *pGroup = pCache->pGroup; + PgHdr1 *p; + assert( sqlite3_mutex_held(pGroup->mutex) ); + while( pGroup->nPurgeable>pGroup->nMaxPage + && (p=pGroup->lru.pLruPrev)->isAnchor==0 + ){ + assert( p->pCache->pGroup==pGroup ); + assert( PAGE_IS_UNPINNED(p) ); + pcache1PinPage(p); + pcache1RemoveFromHash(p, 1); + } + if( pCache->nPage==0 && pCache->pBulk ){ + sqlite3_free(pCache->pBulk); + pCache->pBulk = pCache->pFree = 0; + } +} + +/* +** Discard all pages from cache pCache with a page number (key value) +** greater than or equal to iLimit. Any pinned pages that meet this +** criteria are unpinned before they are discarded. +** +** The PCache mutex must be held when this function is called. +*/ +static void pcache1TruncateUnsafe( + PCache1 *pCache, /* The cache to truncate */ + unsigned int iLimit /* Drop pages with this pgno or larger */ +){ + TESTONLY( int nPage = 0; ) /* To assert pCache->nPage is correct */ + unsigned int h, iStop; + assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); + assert( pCache->iMaxKey >= iLimit ); + assert( pCache->nHash > 0 ); + if( pCache->iMaxKey - iLimit < pCache->nHash ){ + /* If we are just shaving the last few pages off the end of the + ** cache, then there is no point in scanning the entire hash table. + ** Only scan those hash slots that might contain pages that need to + ** be removed. */ + h = iLimit % pCache->nHash; + iStop = pCache->iMaxKey % pCache->nHash; + TESTONLY( nPage = -10; ) /* Disable the pCache->nPage validity check */ + }else{ + /* This is the general case where many pages are being removed. + ** It is necessary to scan the entire hash table */ + h = pCache->nHash/2; + iStop = h - 1; + } + for(;;){ + PgHdr1 **pp; + PgHdr1 *pPage; + assert( hnHash ); + pp = &pCache->apHash[h]; + while( (pPage = *pp)!=0 ){ + if( pPage->iKey>=iLimit ){ + pCache->nPage--; + *pp = pPage->pNext; + if( PAGE_IS_UNPINNED(pPage) ) pcache1PinPage(pPage); + pcache1FreePage(pPage); + }else{ + pp = &pPage->pNext; + TESTONLY( if( nPage>=0 ) nPage++; ) + } + } + if( h==iStop ) break; + h = (h+1) % pCache->nHash; + } + assert( nPage<0 || pCache->nPage==(unsigned)nPage ); +} + +/******************************************************************************/ +/******** sqlite3_pcache Methods **********************************************/ + +/* +** Implementation of the sqlite3_pcache.xInit method. +*/ +static int pcache1Init(void *NotUsed){ + UNUSED_PARAMETER(NotUsed); + assert( pcache1.isInit==0 ); + memset(&pcache1, 0, sizeof(pcache1)); + + + /* + ** The pcache1.separateCache variable is true if each PCache has its own + ** private PGroup (mode-1). pcache1.separateCache is false if the single + ** PGroup in pcache1.grp is used for all page caches (mode-2). + ** + ** * Always use a unified cache (mode-2) if ENABLE_MEMORY_MANAGEMENT + ** + ** * Use a unified cache in single-threaded applications that have + ** configured a start-time buffer for use as page-cache memory using + ** sqlite3_config(SQLITE_CONFIG_PAGECACHE, pBuf, sz, N) with non-NULL + ** pBuf argument. + ** + ** * Otherwise use separate caches (mode-1) + */ +#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) + pcache1.separateCache = 0; +#elif SQLITE_THREADSAFE + pcache1.separateCache = sqlite3GlobalConfig.pPage==0 + || sqlite3GlobalConfig.bCoreMutex>0; +#else + pcache1.separateCache = sqlite3GlobalConfig.pPage==0; +#endif + +#if SQLITE_THREADSAFE + if( sqlite3GlobalConfig.bCoreMutex ){ + pcache1.grp.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU); + pcache1.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PMEM); + } +#endif + if( pcache1.separateCache + && sqlite3GlobalConfig.nPage!=0 + && sqlite3GlobalConfig.pPage==0 + ){ + pcache1.nInitPage = sqlite3GlobalConfig.nPage; + }else{ + pcache1.nInitPage = 0; + } + pcache1.grp.mxPinned = 10; + pcache1.isInit = 1; + return SQLITE_OK; +} + +/* +** Implementation of the sqlite3_pcache.xShutdown method. +** Note that the static mutex allocated in xInit does +** not need to be freed. +*/ +static void pcache1Shutdown(void *NotUsed){ + UNUSED_PARAMETER(NotUsed); + assert( pcache1.isInit!=0 ); + memset(&pcache1, 0, sizeof(pcache1)); +} + +/* forward declaration */ +static void pcache1Destroy(sqlite3_pcache *p); + +/* +** Implementation of the sqlite3_pcache.xCreate method. +** +** Allocate a new cache. +*/ +static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){ + PCache1 *pCache; /* The newly created page cache */ + PGroup *pGroup; /* The group the new page cache will belong to */ + i64 sz; /* Bytes of memory required to allocate the new cache */ + + assert( (szPage & (szPage-1))==0 && szPage>=512 && szPage<=65536 ); + assert( szExtra < 300 ); + + sz = sizeof(PCache1) + sizeof(PGroup)*pcache1.separateCache; + pCache = (PCache1 *)sqlite3MallocZero(sz); + if( pCache ){ + if( pcache1.separateCache ){ + pGroup = (PGroup*)&pCache[1]; + pGroup->mxPinned = 10; + }else{ + pGroup = &pcache1.grp; + } + pcache1EnterMutex(pGroup); + if( pGroup->lru.isAnchor==0 ){ + pGroup->lru.isAnchor = 1; + pGroup->lru.pLruPrev = pGroup->lru.pLruNext = &pGroup->lru; + } + pCache->pGroup = pGroup; + pCache->szPage = szPage; + pCache->szExtra = szExtra; + pCache->szAlloc = szPage + szExtra + ROUND8(sizeof(PgHdr1)); + pCache->bPurgeable = (bPurgeable ? 1 : 0); + pcache1ResizeHash(pCache); + if( bPurgeable ){ + pCache->nMin = 10; + pGroup->nMinPage += pCache->nMin; + pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; + pCache->pnPurgeable = &pGroup->nPurgeable; + }else{ + pCache->pnPurgeable = &pCache->nPurgeableDummy; + } + pcache1LeaveMutex(pGroup); + if( pCache->nHash==0 ){ + pcache1Destroy((sqlite3_pcache*)pCache); + pCache = 0; + } + } + return (sqlite3_pcache *)pCache; +} + +/* +** Implementation of the sqlite3_pcache.xCachesize method. +** +** Configure the cache_size limit for a cache. +*/ +static void pcache1Cachesize(sqlite3_pcache *p, int nMax){ + PCache1 *pCache = (PCache1 *)p; + u32 n; + assert( nMax>=0 ); + if( pCache->bPurgeable ){ + PGroup *pGroup = pCache->pGroup; + pcache1EnterMutex(pGroup); + n = (u32)nMax; + if( n > 0x7fff0000 - pGroup->nMaxPage + pCache->nMax ){ + n = 0x7fff0000 - pGroup->nMaxPage + pCache->nMax; + } + pGroup->nMaxPage += (n - pCache->nMax); + pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; + pCache->nMax = n; + pCache->n90pct = pCache->nMax*9/10; + pcache1EnforceMaxPage(pCache); + pcache1LeaveMutex(pGroup); + } +} + +/* +** Implementation of the sqlite3_pcache.xShrink method. +** +** Free up as much memory as possible. +*/ +static void pcache1Shrink(sqlite3_pcache *p){ + PCache1 *pCache = (PCache1*)p; + if( pCache->bPurgeable ){ + PGroup *pGroup = pCache->pGroup; + unsigned int savedMaxPage; + pcache1EnterMutex(pGroup); + savedMaxPage = pGroup->nMaxPage; + pGroup->nMaxPage = 0; + pcache1EnforceMaxPage(pCache); + pGroup->nMaxPage = savedMaxPage; + pcache1LeaveMutex(pGroup); + } +} + +/* +** Implementation of the sqlite3_pcache.xPagecount method. +*/ +static int pcache1Pagecount(sqlite3_pcache *p){ + int n; + PCache1 *pCache = (PCache1*)p; + pcache1EnterMutex(pCache->pGroup); + n = pCache->nPage; + pcache1LeaveMutex(pCache->pGroup); + return n; +} + + +/* +** Implement steps 3, 4, and 5 of the pcache1Fetch() algorithm described +** in the header of the pcache1Fetch() procedure. +** +** This steps are broken out into a separate procedure because they are +** usually not needed, and by avoiding the stack initialization required +** for these steps, the main pcache1Fetch() procedure can run faster. +*/ +static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2( + PCache1 *pCache, + unsigned int iKey, + int createFlag +){ + unsigned int nPinned; + PGroup *pGroup = pCache->pGroup; + PgHdr1 *pPage = 0; + + /* Step 3: Abort if createFlag is 1 but the cache is nearly full */ + assert( pCache->nPage >= pCache->nRecyclable ); + nPinned = pCache->nPage - pCache->nRecyclable; + assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage ); + assert( pCache->n90pct == pCache->nMax*9/10 ); + if( createFlag==1 && ( + nPinned>=pGroup->mxPinned + || nPinned>=pCache->n90pct + || (pcache1UnderMemoryPressure(pCache) && pCache->nRecyclablenPage>=pCache->nHash ) pcache1ResizeHash(pCache); + assert( pCache->nHash>0 && pCache->apHash ); + + /* Step 4. Try to recycle a page. */ + if( pCache->bPurgeable + && !pGroup->lru.pLruPrev->isAnchor + && ((pCache->nPage+1>=pCache->nMax) || pcache1UnderMemoryPressure(pCache)) + ){ + PCache1 *pOther; + pPage = pGroup->lru.pLruPrev; + assert( PAGE_IS_UNPINNED(pPage) ); + pcache1RemoveFromHash(pPage, 0); + pcache1PinPage(pPage); + pOther = pPage->pCache; + if( pOther->szAlloc != pCache->szAlloc ){ + pcache1FreePage(pPage); + pPage = 0; + }else{ + pGroup->nPurgeable -= (pOther->bPurgeable - pCache->bPurgeable); + } + } + + /* Step 5. If a usable page buffer has still not been found, + ** attempt to allocate a new one. + */ + if( !pPage ){ + pPage = pcache1AllocPage(pCache, createFlag==1); + } + + if( pPage ){ + unsigned int h = iKey % pCache->nHash; + pCache->nPage++; + pPage->iKey = iKey; + pPage->pNext = pCache->apHash[h]; + pPage->pCache = pCache; + pPage->pLruNext = 0; + /* pPage->pLruPrev = 0; + ** No need to clear pLruPrev since it is not accessed when pLruNext==0 */ + *(void **)pPage->page.pExtra = 0; + pCache->apHash[h] = pPage; + if( iKey>pCache->iMaxKey ){ + pCache->iMaxKey = iKey; + } + } + return pPage; +} + +/* +** Implementation of the sqlite3_pcache.xFetch method. +** +** Fetch a page by key value. +** +** Whether or not a new page may be allocated by this function depends on +** the value of the createFlag argument. 0 means do not allocate a new +** page. 1 means allocate a new page if space is easily available. 2 +** means to try really hard to allocate a new page. +** +** For a non-purgeable cache (a cache used as the storage for an in-memory +** database) there is really no difference between createFlag 1 and 2. So +** the calling function (pcache.c) will never have a createFlag of 1 on +** a non-purgeable cache. +** +** There are three different approaches to obtaining space for a page, +** depending on the value of parameter createFlag (which may be 0, 1 or 2). +** +** 1. Regardless of the value of createFlag, the cache is searched for a +** copy of the requested page. If one is found, it is returned. +** +** 2. If createFlag==0 and the page is not already in the cache, NULL is +** returned. +** +** 3. If createFlag is 1, and the page is not already in the cache, then +** return NULL (do not allocate a new page) if any of the following +** conditions are true: +** +** (a) the number of pages pinned by the cache is greater than +** PCache1.nMax, or +** +** (b) the number of pages pinned by the cache is greater than +** the sum of nMax for all purgeable caches, less the sum of +** nMin for all other purgeable caches, or +** +** 4. If none of the first three conditions apply and the cache is marked +** as purgeable, and if one of the following is true: +** +** (a) The number of pages allocated for the cache is already +** PCache1.nMax, or +** +** (b) The number of pages allocated for all purgeable caches is +** already equal to or greater than the sum of nMax for all +** purgeable caches, +** +** (c) The system is under memory pressure and wants to avoid +** unnecessary pages cache entry allocations +** +** then attempt to recycle a page from the LRU list. If it is the right +** size, return the recycled buffer. Otherwise, free the buffer and +** proceed to step 5. +** +** 5. Otherwise, allocate and return a new page buffer. +** +** There are two versions of this routine. pcache1FetchWithMutex() is +** the general case. pcache1FetchNoMutex() is a faster implementation for +** the common case where pGroup->mutex is NULL. The pcache1Fetch() wrapper +** invokes the appropriate routine. +*/ +static PgHdr1 *pcache1FetchNoMutex( + sqlite3_pcache *p, + unsigned int iKey, + int createFlag +){ + PCache1 *pCache = (PCache1 *)p; + PgHdr1 *pPage = 0; + + /* Step 1: Search the hash table for an existing entry. */ + pPage = pCache->apHash[iKey % pCache->nHash]; + while( pPage && pPage->iKey!=iKey ){ pPage = pPage->pNext; } + + /* Step 2: If the page was found in the hash table, then return it. + ** If the page was not in the hash table and createFlag is 0, abort. + ** Otherwise (page not in hash and createFlag!=0) continue with + ** subsequent steps to try to create the page. */ + if( pPage ){ + if( PAGE_IS_UNPINNED(pPage) ){ + return pcache1PinPage(pPage); + }else{ + return pPage; + } + }else if( createFlag ){ + /* Steps 3, 4, and 5 implemented by this subroutine */ + return pcache1FetchStage2(pCache, iKey, createFlag); + }else{ + return 0; + } +} +#if PCACHE1_MIGHT_USE_GROUP_MUTEX +static PgHdr1 *pcache1FetchWithMutex( + sqlite3_pcache *p, + unsigned int iKey, + int createFlag +){ + PCache1 *pCache = (PCache1 *)p; + PgHdr1 *pPage; + + pcache1EnterMutex(pCache->pGroup); + pPage = pcache1FetchNoMutex(p, iKey, createFlag); + assert( pPage==0 || pCache->iMaxKey>=iKey ); + pcache1LeaveMutex(pCache->pGroup); + return pPage; +} +#endif +static sqlite3_pcache_page *pcache1Fetch( + sqlite3_pcache *p, + unsigned int iKey, + int createFlag +){ +#if PCACHE1_MIGHT_USE_GROUP_MUTEX || defined(SQLITE_DEBUG) + PCache1 *pCache = (PCache1 *)p; +#endif + + assert( offsetof(PgHdr1,page)==0 ); + assert( pCache->bPurgeable || createFlag!=1 ); + assert( pCache->bPurgeable || pCache->nMin==0 ); + assert( pCache->bPurgeable==0 || pCache->nMin==10 ); + assert( pCache->nMin==0 || pCache->bPurgeable ); + assert( pCache->nHash>0 ); +#if PCACHE1_MIGHT_USE_GROUP_MUTEX + if( pCache->pGroup->mutex ){ + return (sqlite3_pcache_page*)pcache1FetchWithMutex(p, iKey, createFlag); + }else +#endif + { + return (sqlite3_pcache_page*)pcache1FetchNoMutex(p, iKey, createFlag); + } +} + + +/* +** Implementation of the sqlite3_pcache.xUnpin method. +** +** Mark a page as unpinned (eligible for asynchronous recycling). +*/ +static void pcache1Unpin( + sqlite3_pcache *p, + sqlite3_pcache_page *pPg, + int reuseUnlikely +){ + PCache1 *pCache = (PCache1 *)p; + PgHdr1 *pPage = (PgHdr1 *)pPg; + PGroup *pGroup = pCache->pGroup; + + assert( pPage->pCache==pCache ); + pcache1EnterMutex(pGroup); + + /* It is an error to call this function if the page is already + ** part of the PGroup LRU list. + */ + assert( pPage->pLruNext==0 ); + assert( PAGE_IS_PINNED(pPage) ); + + if( reuseUnlikely || pGroup->nPurgeable>pGroup->nMaxPage ){ + pcache1RemoveFromHash(pPage, 1); + }else{ + /* Add the page to the PGroup LRU list. */ + PgHdr1 **ppFirst = &pGroup->lru.pLruNext; + pPage->pLruPrev = &pGroup->lru; + (pPage->pLruNext = *ppFirst)->pLruPrev = pPage; + *ppFirst = pPage; + pCache->nRecyclable++; + } + + pcache1LeaveMutex(pCache->pGroup); +} + +/* +** Implementation of the sqlite3_pcache.xRekey method. +*/ +static void pcache1Rekey( + sqlite3_pcache *p, + sqlite3_pcache_page *pPg, + unsigned int iOld, + unsigned int iNew +){ + PCache1 *pCache = (PCache1 *)p; + PgHdr1 *pPage = (PgHdr1 *)pPg; + PgHdr1 **pp; + unsigned int hOld, hNew; + assert( pPage->iKey==iOld ); + assert( pPage->pCache==pCache ); + assert( iOld!=iNew ); /* The page number really is changing */ + + pcache1EnterMutex(pCache->pGroup); + + assert( pcache1FetchNoMutex(p, iOld, 0)==pPage ); /* pPg really is iOld */ + hOld = iOld%pCache->nHash; + pp = &pCache->apHash[hOld]; + while( (*pp)!=pPage ){ + pp = &(*pp)->pNext; + } + *pp = pPage->pNext; + + assert( pcache1FetchNoMutex(p, iNew, 0)==0 ); /* iNew not in cache */ + hNew = iNew%pCache->nHash; + pPage->iKey = iNew; + pPage->pNext = pCache->apHash[hNew]; + pCache->apHash[hNew] = pPage; + if( iNew>pCache->iMaxKey ){ + pCache->iMaxKey = iNew; + } + + pcache1LeaveMutex(pCache->pGroup); +} + +/* +** Implementation of the sqlite3_pcache.xTruncate method. +** +** Discard all unpinned pages in the cache with a page number equal to +** or greater than parameter iLimit. Any pinned pages with a page number +** equal to or greater than iLimit are implicitly unpinned. +*/ +static void pcache1Truncate(sqlite3_pcache *p, unsigned int iLimit){ + PCache1 *pCache = (PCache1 *)p; + pcache1EnterMutex(pCache->pGroup); + if( iLimit<=pCache->iMaxKey ){ + pcache1TruncateUnsafe(pCache, iLimit); + pCache->iMaxKey = iLimit-1; + } + pcache1LeaveMutex(pCache->pGroup); +} + +/* +** Implementation of the sqlite3_pcache.xDestroy method. +** +** Destroy a cache allocated using pcache1Create(). +*/ +static void pcache1Destroy(sqlite3_pcache *p){ + PCache1 *pCache = (PCache1 *)p; + PGroup *pGroup = pCache->pGroup; + assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) ); + pcache1EnterMutex(pGroup); + if( pCache->nPage ) pcache1TruncateUnsafe(pCache, 0); + assert( pGroup->nMaxPage >= pCache->nMax ); + pGroup->nMaxPage -= pCache->nMax; + assert( pGroup->nMinPage >= pCache->nMin ); + pGroup->nMinPage -= pCache->nMin; + pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; + pcache1EnforceMaxPage(pCache); + pcache1LeaveMutex(pGroup); + sqlite3_free(pCache->pBulk); + sqlite3_free(pCache->apHash); + sqlite3_free(pCache); +} + +/* +** This function is called during initialization (sqlite3_initialize()) to +** install the default pluggable cache module, assuming the user has not +** already provided an alternative. +*/ +SQLITE_PRIVATE void sqlite3PCacheSetDefault(void){ + static const sqlite3_pcache_methods2 defaultMethods = { + 1, /* iVersion */ + 0, /* pArg */ + pcache1Init, /* xInit */ + pcache1Shutdown, /* xShutdown */ + pcache1Create, /* xCreate */ + pcache1Cachesize, /* xCachesize */ + pcache1Pagecount, /* xPagecount */ + pcache1Fetch, /* xFetch */ + pcache1Unpin, /* xUnpin */ + pcache1Rekey, /* xRekey */ + pcache1Truncate, /* xTruncate */ + pcache1Destroy, /* xDestroy */ + pcache1Shrink /* xShrink */ + }; + sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultMethods); +} + +/* +** Return the size of the header on each page of this PCACHE implementation. +*/ +SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void){ return ROUND8(sizeof(PgHdr1)); } + +/* +** Return the global mutex used by this PCACHE implementation. The +** sqlite3_status() routine needs access to this mutex. +*/ +SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void){ + return pcache1.mutex; +} + +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT +/* +** This function is called to free superfluous dynamically allocated memory +** held by the pager system. Memory in use by any SQLite pager allocated +** by the current thread may be sqlite3_free()ed. +** +** nReq is the number of bytes of memory required. Once this much has +** been released, the function returns. The return value is the total number +** of bytes of memory released. +*/ +SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int nReq){ + int nFree = 0; + assert( sqlite3_mutex_notheld(pcache1.grp.mutex) ); + assert( sqlite3_mutex_notheld(pcache1.mutex) ); + if( sqlite3GlobalConfig.pPage==0 ){ + PgHdr1 *p; + pcache1EnterMutex(&pcache1.grp); + while( (nReq<0 || nFreeisAnchor==0 + ){ + nFree += pcache1MemSize(p->page.pBuf); + assert( PAGE_IS_UNPINNED(p) ); + pcache1PinPage(p); + pcache1RemoveFromHash(p, 1); + } + pcache1LeaveMutex(&pcache1.grp); + } + return nFree; +} +#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */ + +#ifdef SQLITE_TEST +/* +** This function is used by test procedures to inspect the internal state +** of the global cache. +*/ +SQLITE_PRIVATE void sqlite3PcacheStats( + int *pnCurrent, /* OUT: Total number of pages cached */ + int *pnMax, /* OUT: Global maximum cache size */ + int *pnMin, /* OUT: Sum of PCache1.nMin for purgeable caches */ + int *pnRecyclable /* OUT: Total number of pages available for recycling */ +){ + PgHdr1 *p; + int nRecyclable = 0; + for(p=pcache1.grp.lru.pLruNext; p && !p->isAnchor; p=p->pLruNext){ + assert( PAGE_IS_UNPINNED(p) ); + nRecyclable++; + } + *pnCurrent = pcache1.grp.nPurgeable; + *pnMax = (int)pcache1.grp.nMaxPage; + *pnMin = (int)pcache1.grp.nMinPage; + *pnRecyclable = nRecyclable; +} +#endif + +/************** End of pcache1.c *********************************************/ +/************** Begin file rowset.c ******************************************/ +/* +** 2008 December 3 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This module implements an object we call a "RowSet". +** +** The RowSet object is a collection of rowids. Rowids +** are inserted into the RowSet in an arbitrary order. Inserts +** can be intermixed with tests to see if a given rowid has been +** previously inserted into the RowSet. +** +** After all inserts are finished, it is possible to extract the +** elements of the RowSet in sorted order. Once this extraction +** process has started, no new elements may be inserted. +** +** Hence, the primitive operations for a RowSet are: +** +** CREATE +** INSERT +** TEST +** SMALLEST +** DESTROY +** +** The CREATE and DESTROY primitives are the constructor and destructor, +** obviously. The INSERT primitive adds a new element to the RowSet. +** TEST checks to see if an element is already in the RowSet. SMALLEST +** extracts the least value from the RowSet. +** +** The INSERT primitive might allocate additional memory. Memory is +** allocated in chunks so most INSERTs do no allocation. There is an +** upper bound on the size of allocated memory. No memory is freed +** until DESTROY. +** +** The TEST primitive includes a "batch" number. The TEST primitive +** will only see elements that were inserted before the last change +** in the batch number. In other words, if an INSERT occurs between +** two TESTs where the TESTs have the same batch number, then the +** value added by the INSERT will not be visible to the second TEST. +** The initial batch number is zero, so if the very first TEST contains +** a non-zero batch number, it will see all prior INSERTs. +** +** No INSERTs may occurs after a SMALLEST. An assertion will fail if +** that is attempted. +** +** The cost of an INSERT is roughly constant. (Sometimes new memory +** has to be allocated on an INSERT.) The cost of a TEST with a new +** batch number is O(NlogN) where N is the number of elements in the RowSet. +** The cost of a TEST using the same batch number is O(logN). The cost +** of the first SMALLEST is O(NlogN). Second and subsequent SMALLEST +** primitives are constant time. The cost of DESTROY is O(N). +** +** TEST and SMALLEST may not be used by the same RowSet. This used to +** be possible, but the feature was not used, so it was removed in order +** to simplify the code. +*/ +/* #include "sqliteInt.h" */ + + +/* +** Target size for allocation chunks. +*/ +#define ROWSET_ALLOCATION_SIZE 1024 + +/* +** The number of rowset entries per allocation chunk. +*/ +#define ROWSET_ENTRY_PER_CHUNK \ + ((ROWSET_ALLOCATION_SIZE-8)/sizeof(struct RowSetEntry)) + +/* +** Each entry in a RowSet is an instance of the following object. +** +** This same object is reused to store a linked list of trees of RowSetEntry +** objects. In that alternative use, pRight points to the next entry +** in the list, pLeft points to the tree, and v is unused. The +** RowSet.pForest value points to the head of this forest list. +*/ +struct RowSetEntry { + i64 v; /* ROWID value for this entry */ + struct RowSetEntry *pRight; /* Right subtree (larger entries) or list */ + struct RowSetEntry *pLeft; /* Left subtree (smaller entries) */ +}; + +/* +** RowSetEntry objects are allocated in large chunks (instances of the +** following structure) to reduce memory allocation overhead. The +** chunks are kept on a linked list so that they can be deallocated +** when the RowSet is destroyed. +*/ +struct RowSetChunk { + struct RowSetChunk *pNextChunk; /* Next chunk on list of them all */ + struct RowSetEntry aEntry[ROWSET_ENTRY_PER_CHUNK]; /* Allocated entries */ +}; + +/* +** A RowSet in an instance of the following structure. +** +** A typedef of this structure if found in sqliteInt.h. +*/ +struct RowSet { + struct RowSetChunk *pChunk; /* List of all chunk allocations */ + sqlite3 *db; /* The database connection */ + struct RowSetEntry *pEntry; /* List of entries using pRight */ + struct RowSetEntry *pLast; /* Last entry on the pEntry list */ + struct RowSetEntry *pFresh; /* Source of new entry objects */ + struct RowSetEntry *pForest; /* List of binary trees of entries */ + u16 nFresh; /* Number of objects on pFresh */ + u16 rsFlags; /* Various flags */ + int iBatch; /* Current insert batch */ +}; + +/* +** Allowed values for RowSet.rsFlags +*/ +#define ROWSET_SORTED 0x01 /* True if RowSet.pEntry is sorted */ +#define ROWSET_NEXT 0x02 /* True if sqlite3RowSetNext() has been called */ + +/* +** Allocate a RowSet object. Return NULL if a memory allocation +** error occurs. +*/ +SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db){ + RowSet *p = sqlite3DbMallocRawNN(db, sizeof(*p)); + if( p ){ + int N = sqlite3DbMallocSize(db, p); + p->pChunk = 0; + p->db = db; + p->pEntry = 0; + p->pLast = 0; + p->pForest = 0; + p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p); + p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry)); + p->rsFlags = ROWSET_SORTED; + p->iBatch = 0; + } + return p; +} + +/* +** Deallocate all chunks from a RowSet. This frees all memory that +** the RowSet has allocated over its lifetime. This routine is +** the destructor for the RowSet. +*/ +SQLITE_PRIVATE void sqlite3RowSetClear(void *pArg){ + RowSet *p = (RowSet*)pArg; + struct RowSetChunk *pChunk, *pNextChunk; + for(pChunk=p->pChunk; pChunk; pChunk = pNextChunk){ + pNextChunk = pChunk->pNextChunk; + sqlite3DbFree(p->db, pChunk); + } + p->pChunk = 0; + p->nFresh = 0; + p->pEntry = 0; + p->pLast = 0; + p->pForest = 0; + p->rsFlags = ROWSET_SORTED; +} + +/* +** Deallocate all chunks from a RowSet. This frees all memory that +** the RowSet has allocated over its lifetime. This routine is +** the destructor for the RowSet. +*/ +SQLITE_PRIVATE void sqlite3RowSetDelete(void *pArg){ + sqlite3RowSetClear(pArg); + sqlite3DbFree(((RowSet*)pArg)->db, pArg); +} + +/* +** Allocate a new RowSetEntry object that is associated with the +** given RowSet. Return a pointer to the new and completely uninitialized +** object. +** +** In an OOM situation, the RowSet.db->mallocFailed flag is set and this +** routine returns NULL. +*/ +static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){ + assert( p!=0 ); + if( p->nFresh==0 ){ /*OPTIMIZATION-IF-FALSE*/ + /* We could allocate a fresh RowSetEntry each time one is needed, but it + ** is more efficient to pull a preallocated entry from the pool */ + struct RowSetChunk *pNew; + pNew = sqlite3DbMallocRawNN(p->db, sizeof(*pNew)); + if( pNew==0 ){ + return 0; + } + pNew->pNextChunk = p->pChunk; + p->pChunk = pNew; + p->pFresh = pNew->aEntry; + p->nFresh = ROWSET_ENTRY_PER_CHUNK; + } + p->nFresh--; + return p->pFresh++; +} + +/* +** Insert a new value into a RowSet. +** +** The mallocFailed flag of the database connection is set if a +** memory allocation fails. +*/ +SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet *p, i64 rowid){ + struct RowSetEntry *pEntry; /* The new entry */ + struct RowSetEntry *pLast; /* The last prior entry */ + + /* This routine is never called after sqlite3RowSetNext() */ + assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 ); + + pEntry = rowSetEntryAlloc(p); + if( pEntry==0 ) return; + pEntry->v = rowid; + pEntry->pRight = 0; + pLast = p->pLast; + if( pLast ){ + if( rowid<=pLast->v ){ /*OPTIMIZATION-IF-FALSE*/ + /* Avoid unnecessary sorts by preserving the ROWSET_SORTED flags + ** where possible */ + p->rsFlags &= ~ROWSET_SORTED; + } + pLast->pRight = pEntry; + }else{ + p->pEntry = pEntry; + } + p->pLast = pEntry; +} + +/* +** Merge two lists of RowSetEntry objects. Remove duplicates. +** +** The input lists are connected via pRight pointers and are +** assumed to each already be in sorted order. +*/ +static struct RowSetEntry *rowSetEntryMerge( + struct RowSetEntry *pA, /* First sorted list to be merged */ + struct RowSetEntry *pB /* Second sorted list to be merged */ +){ + struct RowSetEntry head; + struct RowSetEntry *pTail; + + pTail = &head; + assert( pA!=0 && pB!=0 ); + for(;;){ + assert( pA->pRight==0 || pA->v<=pA->pRight->v ); + assert( pB->pRight==0 || pB->v<=pB->pRight->v ); + if( pA->v<=pB->v ){ + if( pA->vv ) pTail = pTail->pRight = pA; + pA = pA->pRight; + if( pA==0 ){ + pTail->pRight = pB; + break; + } + }else{ + pTail = pTail->pRight = pB; + pB = pB->pRight; + if( pB==0 ){ + pTail->pRight = pA; + break; + } + } + } + return head.pRight; +} + +/* +** Sort all elements on the list of RowSetEntry objects into order of +** increasing v. +*/ +static struct RowSetEntry *rowSetEntrySort(struct RowSetEntry *pIn){ + unsigned int i; + struct RowSetEntry *pNext, *aBucket[40]; + + memset(aBucket, 0, sizeof(aBucket)); + while( pIn ){ + pNext = pIn->pRight; + pIn->pRight = 0; + for(i=0; aBucket[i]; i++){ + pIn = rowSetEntryMerge(aBucket[i], pIn); + aBucket[i] = 0; + } + aBucket[i] = pIn; + pIn = pNext; + } + pIn = aBucket[0]; + for(i=1; ipLeft ){ + struct RowSetEntry *p; + rowSetTreeToList(pIn->pLeft, ppFirst, &p); + p->pRight = pIn; + }else{ + *ppFirst = pIn; + } + if( pIn->pRight ){ + rowSetTreeToList(pIn->pRight, &pIn->pRight, ppLast); + }else{ + *ppLast = pIn; + } + assert( (*ppLast)->pRight==0 ); +} + + +/* +** Convert a sorted list of elements (connected by pRight) into a binary +** tree with depth of iDepth. A depth of 1 means the tree contains a single +** node taken from the head of *ppList. A depth of 2 means a tree with +** three nodes. And so forth. +** +** Use as many entries from the input list as required and update the +** *ppList to point to the unused elements of the list. If the input +** list contains too few elements, then construct an incomplete tree +** and leave *ppList set to NULL. +** +** Return a pointer to the root of the constructed binary tree. +*/ +static struct RowSetEntry *rowSetNDeepTree( + struct RowSetEntry **ppList, + int iDepth +){ + struct RowSetEntry *p; /* Root of the new tree */ + struct RowSetEntry *pLeft; /* Left subtree */ + if( *ppList==0 ){ /*OPTIMIZATION-IF-TRUE*/ + /* Prevent unnecessary deep recursion when we run out of entries */ + return 0; + } + if( iDepth>1 ){ /*OPTIMIZATION-IF-TRUE*/ + /* This branch causes a *balanced* tree to be generated. A valid tree + ** is still generated without this branch, but the tree is wildly + ** unbalanced and inefficient. */ + pLeft = rowSetNDeepTree(ppList, iDepth-1); + p = *ppList; + if( p==0 ){ /*OPTIMIZATION-IF-FALSE*/ + /* It is safe to always return here, but the resulting tree + ** would be unbalanced */ + return pLeft; + } + p->pLeft = pLeft; + *ppList = p->pRight; + p->pRight = rowSetNDeepTree(ppList, iDepth-1); + }else{ + p = *ppList; + *ppList = p->pRight; + p->pLeft = p->pRight = 0; + } + return p; +} + +/* +** Convert a sorted list of elements into a binary tree. Make the tree +** as deep as it needs to be in order to contain the entire list. +*/ +static struct RowSetEntry *rowSetListToTree(struct RowSetEntry *pList){ + int iDepth; /* Depth of the tree so far */ + struct RowSetEntry *p; /* Current tree root */ + struct RowSetEntry *pLeft; /* Left subtree */ + + assert( pList!=0 ); + p = pList; + pList = p->pRight; + p->pLeft = p->pRight = 0; + for(iDepth=1; pList; iDepth++){ + pLeft = p; + p = pList; + pList = p->pRight; + p->pLeft = pLeft; + p->pRight = rowSetNDeepTree(&pList, iDepth); + } + return p; +} + +/* +** Extract the smallest element from the RowSet. +** Write the element into *pRowid. Return 1 on success. Return +** 0 if the RowSet is already empty. +** +** After this routine has been called, the sqlite3RowSetInsert() +** routine may not be called again. +** +** This routine may not be called after sqlite3RowSetTest() has +** been used. Older versions of RowSet allowed that, but as the +** capability was not used by the code generator, it was removed +** for code economy. +*/ +SQLITE_PRIVATE int sqlite3RowSetNext(RowSet *p, i64 *pRowid){ + assert( p!=0 ); + assert( p->pForest==0 ); /* Cannot be used with sqlite3RowSetText() */ + + /* Merge the forest into a single sorted list on first call */ + if( (p->rsFlags & ROWSET_NEXT)==0 ){ /*OPTIMIZATION-IF-FALSE*/ + if( (p->rsFlags & ROWSET_SORTED)==0 ){ /*OPTIMIZATION-IF-FALSE*/ + p->pEntry = rowSetEntrySort(p->pEntry); + } + p->rsFlags |= ROWSET_SORTED|ROWSET_NEXT; + } + + /* Return the next entry on the list */ + if( p->pEntry ){ + *pRowid = p->pEntry->v; + p->pEntry = p->pEntry->pRight; + if( p->pEntry==0 ){ /*OPTIMIZATION-IF-TRUE*/ + /* Free memory immediately, rather than waiting on sqlite3_finalize() */ + sqlite3RowSetClear(p); + } + return 1; + }else{ + return 0; + } +} + +/* +** Check to see if element iRowid was inserted into the rowset as +** part of any insert batch prior to iBatch. Return 1 or 0. +** +** If this is the first test of a new batch and if there exist entries +** on pRowSet->pEntry, then sort those entries into the forest at +** pRowSet->pForest so that they can be tested. +*/ +SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64 iRowid){ + struct RowSetEntry *p, *pTree; + + /* This routine is never called after sqlite3RowSetNext() */ + assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 ); + + /* Sort entries into the forest on the first test of a new batch. + ** To save unnecessary work, only do this when the batch number changes. + */ + if( iBatch!=pRowSet->iBatch ){ /*OPTIMIZATION-IF-FALSE*/ + p = pRowSet->pEntry; + if( p ){ + struct RowSetEntry **ppPrevTree = &pRowSet->pForest; + if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){ /*OPTIMIZATION-IF-FALSE*/ + /* Only sort the current set of entries if they need it */ + p = rowSetEntrySort(p); + } + for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){ + ppPrevTree = &pTree->pRight; + if( pTree->pLeft==0 ){ + pTree->pLeft = rowSetListToTree(p); + break; + }else{ + struct RowSetEntry *pAux, *pTail; + rowSetTreeToList(pTree->pLeft, &pAux, &pTail); + pTree->pLeft = 0; + p = rowSetEntryMerge(pAux, p); + } + } + if( pTree==0 ){ + *ppPrevTree = pTree = rowSetEntryAlloc(pRowSet); + if( pTree ){ + pTree->v = 0; + pTree->pRight = 0; + pTree->pLeft = rowSetListToTree(p); + } + } + pRowSet->pEntry = 0; + pRowSet->pLast = 0; + pRowSet->rsFlags |= ROWSET_SORTED; + } + pRowSet->iBatch = iBatch; + } + + /* Test to see if the iRowid value appears anywhere in the forest. + ** Return 1 if it does and 0 if not. + */ + for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){ + p = pTree->pLeft; + while( p ){ + if( p->vpRight; + }else if( p->v>iRowid ){ + p = p->pLeft; + }else{ + return 1; + } + } + } + return 0; +} + +/************** End of rowset.c **********************************************/ +/************** Begin file pager.c *******************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This is the implementation of the page cache subsystem or "pager". +** +** The pager is used to access a database disk file. It implements +** atomic commit and rollback through the use of a journal file that +** is separate from the database file. The pager also implements file +** locking to prevent two processes from writing the same database +** file simultaneously, or one process from reading the database while +** another is writing. +*/ +#ifndef SQLITE_OMIT_DISKIO +/* #include "sqliteInt.h" */ +/************** Include wal.h in the middle of pager.c ***********************/ +/************** Begin file wal.h *********************************************/ +/* +** 2010 February 1 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This header file defines the interface to the write-ahead logging +** system. Refer to the comments below and the header comment attached to +** the implementation of each function in log.c for further details. +*/ + +#ifndef SQLITE_WAL_H +#define SQLITE_WAL_H + +/* #include "sqliteInt.h" */ + +/* Macros for extracting appropriate sync flags for either transaction +** commits (WAL_SYNC_FLAGS(X)) or for checkpoint ops (CKPT_SYNC_FLAGS(X)): +*/ +#define WAL_SYNC_FLAGS(X) ((X)&0x03) +#define CKPT_SYNC_FLAGS(X) (((X)>>2)&0x03) + +#ifdef SQLITE_OMIT_WAL +# define sqlite3WalOpen(x,y,z) 0 +# define sqlite3WalLimit(x,y) +# define sqlite3WalClose(v,w,x,y,z) 0 +# define sqlite3WalBeginReadTransaction(y,z) 0 +# define sqlite3WalEndReadTransaction(z) +# define sqlite3WalDbsize(y) 0 +# define sqlite3WalBeginWriteTransaction(y) 0 +# define sqlite3WalEndWriteTransaction(x) 0 +# define sqlite3WalUndo(x,y,z) 0 +# define sqlite3WalSavepoint(y,z) +# define sqlite3WalSavepointUndo(y,z) 0 +# define sqlite3WalFrames(u,v,w,x,y,z) 0 +# define sqlite3WalCheckpoint(q,r,s,t,u,v,w,x,y,z) 0 +# define sqlite3WalCallback(z) 0 +# define sqlite3WalExclusiveMode(y,z) 0 +# define sqlite3WalHeapMemory(z) 0 +# define sqlite3WalFramesize(z) 0 +# define sqlite3WalFindFrame(x,y,z) 0 +# define sqlite3WalFile(x) 0 +# undef SQLITE_USE_SEH +#else + +#define WAL_SAVEPOINT_NDATA 4 + +/* Connection to a write-ahead log (WAL) file. +** There is one object of this type for each pager. +*/ +typedef struct Wal Wal; + +/* Open and close a connection to a write-ahead log. */ +SQLITE_PRIVATE int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, Wal**); +SQLITE_PRIVATE int sqlite3WalClose(Wal *pWal, sqlite3*, int sync_flags, int, u8 *); + +/* Set the limiting size of a WAL file. */ +SQLITE_PRIVATE void sqlite3WalLimit(Wal*, i64); + +/* Used by readers to open (lock) and close (unlock) a snapshot. A +** snapshot is like a read-transaction. It is the state of the database +** at an instant in time. sqlite3WalOpenSnapshot gets a read lock and +** preserves the current state even if the other threads or processes +** write to or checkpoint the WAL. sqlite3WalCloseSnapshot() closes the +** transaction and releases the lock. +*/ +SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *); +SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal); + +/* Read a page from the write-ahead log, if it is present. */ +SQLITE_PRIVATE int sqlite3WalFindFrame(Wal *, Pgno, u32 *); +SQLITE_PRIVATE int sqlite3WalReadFrame(Wal *, u32, int, u8 *); + +/* If the WAL is not empty, return the size of the database. */ +SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal); + +/* Obtain or release the WRITER lock. */ +SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal); +SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal); + +/* Undo any frames written (but not committed) to the log */ +SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx); + +/* Return an integer that records the current (uncommitted) write +** position in the WAL */ +SQLITE_PRIVATE void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData); + +/* Move the write position of the WAL back to iFrame. Called in +** response to a ROLLBACK TO command. */ +SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData); + +/* Write a frame or frames to the log. */ +SQLITE_PRIVATE int sqlite3WalFrames(Wal *pWal, int, PgHdr *, Pgno, int, int); + +/* Copy pages from the log to the database file */ +SQLITE_PRIVATE int sqlite3WalCheckpoint( + Wal *pWal, /* Write-ahead log connection */ + sqlite3 *db, /* Check this handle's interrupt flag */ + int eMode, /* One of PASSIVE, FULL and RESTART */ + int (*xBusy)(void*), /* Function to call when busy */ + void *pBusyArg, /* Context argument for xBusyHandler */ + int sync_flags, /* Flags to sync db file with (or 0) */ + int nBuf, /* Size of buffer nBuf */ + u8 *zBuf, /* Temporary buffer to use */ + int *pnLog, /* OUT: Number of frames in WAL */ + int *pnCkpt /* OUT: Number of backfilled frames in WAL */ +); + +/* Return the value to pass to a sqlite3_wal_hook callback, the +** number of frames in the WAL at the point of the last commit since +** sqlite3WalCallback() was called. If no commits have occurred since +** the last call, then return 0. +*/ +SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal); + +/* Tell the wal layer that an EXCLUSIVE lock has been obtained (or released) +** by the pager layer on the database file. +*/ +SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op); + +/* Return true if the argument is non-NULL and the WAL module is using +** heap-memory for the wal-index. Otherwise, if the argument is NULL or the +** WAL module is using shared-memory, return false. +*/ +SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal); + +#ifdef SQLITE_ENABLE_SNAPSHOT +SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot); +SQLITE_PRIVATE void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot); +SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal); +SQLITE_PRIVATE int sqlite3WalSnapshotCheck(Wal *pWal, sqlite3_snapshot *pSnapshot); +SQLITE_PRIVATE void sqlite3WalSnapshotUnlock(Wal *pWal); +#endif + +#ifdef SQLITE_ENABLE_ZIPVFS +/* If the WAL file is not empty, return the number of bytes of content +** stored in each frame (i.e. the db page-size when the WAL was created). +*/ +SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal); +#endif + +/* Return the sqlite3_file object for the WAL file */ +SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal); + +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT +SQLITE_PRIVATE int sqlite3WalWriteLock(Wal *pWal, int bLock); +SQLITE_PRIVATE void sqlite3WalDb(Wal *pWal, sqlite3 *db); +#endif + +#ifdef SQLITE_USE_SEH +SQLITE_PRIVATE int sqlite3WalSystemErrno(Wal*); +#endif + +#endif /* ifndef SQLITE_OMIT_WAL */ +#endif /* SQLITE_WAL_H */ + +/************** End of wal.h *************************************************/ +/************** Continuing where we left off in pager.c **********************/ + + +/******************* NOTES ON THE DESIGN OF THE PAGER ************************ +** +** This comment block describes invariants that hold when using a rollback +** journal. These invariants do not apply for journal_mode=WAL, +** journal_mode=MEMORY, or journal_mode=OFF. +** +** Within this comment block, a page is deemed to have been synced +** automatically as soon as it is written when PRAGMA synchronous=OFF. +** Otherwise, the page is not synced until the xSync method of the VFS +** is called successfully on the file containing the page. +** +** Definition: A page of the database file is said to be "overwriteable" if +** one or more of the following are true about the page: +** +** (a) The original content of the page as it was at the beginning of +** the transaction has been written into the rollback journal and +** synced. +** +** (b) The page was a freelist leaf page at the start of the transaction. +** +** (c) The page number is greater than the largest page that existed in +** the database file at the start of the transaction. +** +** (1) A page of the database file is never overwritten unless one of the +** following are true: +** +** (a) The page and all other pages on the same sector are overwriteable. +** +** (b) The atomic page write optimization is enabled, and the entire +** transaction other than the update of the transaction sequence +** number consists of a single page change. +** +** (2) The content of a page written into the rollback journal exactly matches +** both the content in the database when the rollback journal was written +** and the content in the database at the beginning of the current +** transaction. +** +** (3) Writes to the database file are an integer multiple of the page size +** in length and are aligned on a page boundary. +** +** (4) Reads from the database file are either aligned on a page boundary and +** an integer multiple of the page size in length or are taken from the +** first 100 bytes of the database file. +** +** (5) All writes to the database file are synced prior to the rollback journal +** being deleted, truncated, or zeroed. +** +** (6) If a super-journal file is used, then all writes to the database file +** are synced prior to the super-journal being deleted. +** +** Definition: Two databases (or the same database at two points it time) +** are said to be "logically equivalent" if they give the same answer to +** all queries. Note in particular the content of freelist leaf +** pages can be changed arbitrarily without affecting the logical equivalence +** of the database. +** +** (7) At any time, if any subset, including the empty set and the total set, +** of the unsynced changes to a rollback journal are removed and the +** journal is rolled back, the resulting database file will be logically +** equivalent to the database file at the beginning of the transaction. +** +** (8) When a transaction is rolled back, the xTruncate method of the VFS +** is called to restore the database file to the same size it was at +** the beginning of the transaction. (In some VFSes, the xTruncate +** method is a no-op, but that does not change the fact the SQLite will +** invoke it.) +** +** (9) Whenever the database file is modified, at least one bit in the range +** of bytes from 24 through 39 inclusive will be changed prior to releasing +** the EXCLUSIVE lock, thus signaling other connections on the same +** database to flush their caches. +** +** (10) The pattern of bits in bytes 24 through 39 shall not repeat in less +** than one billion transactions. +** +** (11) A database file is well-formed at the beginning and at the conclusion +** of every transaction. +** +** (12) An EXCLUSIVE lock is held on the database file when writing to +** the database file. +** +** (13) A SHARED lock is held on the database file while reading any +** content out of the database file. +** +******************************************************************************/ + +/* +** Macros for troubleshooting. Normally turned off +*/ +#if 0 +int sqlite3PagerTrace=1; /* True to enable tracing */ +#define sqlite3DebugPrintf printf +#define PAGERTRACE(X) if( sqlite3PagerTrace ){ sqlite3DebugPrintf X; } +#else +#define PAGERTRACE(X) +#endif + +/* +** The following two macros are used within the PAGERTRACE() macros above +** to print out file-descriptors. +** +** PAGERID() takes a pointer to a Pager struct as its argument. The +** associated file-descriptor is returned. FILEHANDLEID() takes an sqlite3_file +** struct as its argument. +*/ +#define PAGERID(p) (SQLITE_PTR_TO_INT(p->fd)) +#define FILEHANDLEID(fd) (SQLITE_PTR_TO_INT(fd)) + +/* +** The Pager.eState variable stores the current 'state' of a pager. A +** pager may be in any one of the seven states shown in the following +** state diagram. +** +** OPEN <------+------+ +** | | | +** V | | +** +---------> READER-------+ | +** | | | +** | V | +** |<-------WRITER_LOCKED------> ERROR +** | | ^ +** | V | +** |<------WRITER_CACHEMOD-------->| +** | | | +** | V | +** |<-------WRITER_DBMOD---------->| +** | | | +** | V | +** +<------WRITER_FINISHED-------->+ +** +** +** List of state transitions and the C [function] that performs each: +** +** OPEN -> READER [sqlite3PagerSharedLock] +** READER -> OPEN [pager_unlock] +** +** READER -> WRITER_LOCKED [sqlite3PagerBegin] +** WRITER_LOCKED -> WRITER_CACHEMOD [pager_open_journal] +** WRITER_CACHEMOD -> WRITER_DBMOD [syncJournal] +** WRITER_DBMOD -> WRITER_FINISHED [sqlite3PagerCommitPhaseOne] +** WRITER_*** -> READER [pager_end_transaction] +** +** WRITER_*** -> ERROR [pager_error] +** ERROR -> OPEN [pager_unlock] +** +** +** OPEN: +** +** The pager starts up in this state. Nothing is guaranteed in this +** state - the file may or may not be locked and the database size is +** unknown. The database may not be read or written. +** +** * No read or write transaction is active. +** * Any lock, or no lock at all, may be held on the database file. +** * The dbSize, dbOrigSize and dbFileSize variables may not be trusted. +** +** READER: +** +** In this state all the requirements for reading the database in +** rollback (non-WAL) mode are met. Unless the pager is (or recently +** was) in exclusive-locking mode, a user-level read transaction is +** open. The database size is known in this state. +** +** A connection running with locking_mode=normal enters this state when +** it opens a read-transaction on the database and returns to state +** OPEN after the read-transaction is completed. However a connection +** running in locking_mode=exclusive (including temp databases) remains in +** this state even after the read-transaction is closed. The only way +** a locking_mode=exclusive connection can transition from READER to OPEN +** is via the ERROR state (see below). +** +** * A read transaction may be active (but a write-transaction cannot). +** * A SHARED or greater lock is held on the database file. +** * The dbSize variable may be trusted (even if a user-level read +** transaction is not active). The dbOrigSize and dbFileSize variables +** may not be trusted at this point. +** * If the database is a WAL database, then the WAL connection is open. +** * Even if a read-transaction is not open, it is guaranteed that +** there is no hot-journal in the file-system. +** +** WRITER_LOCKED: +** +** The pager moves to this state from READER when a write-transaction +** is first opened on the database. In WRITER_LOCKED state, all locks +** required to start a write-transaction are held, but no actual +** modifications to the cache or database have taken place. +** +** In rollback mode, a RESERVED or (if the transaction was opened with +** BEGIN EXCLUSIVE) EXCLUSIVE lock is obtained on the database file when +** moving to this state, but the journal file is not written to or opened +** to in this state. If the transaction is committed or rolled back while +** in WRITER_LOCKED state, all that is required is to unlock the database +** file. +** +** IN WAL mode, WalBeginWriteTransaction() is called to lock the log file. +** If the connection is running with locking_mode=exclusive, an attempt +** is made to obtain an EXCLUSIVE lock on the database file. +** +** * A write transaction is active. +** * If the connection is open in rollback-mode, a RESERVED or greater +** lock is held on the database file. +** * If the connection is open in WAL-mode, a WAL write transaction +** is open (i.e. sqlite3WalBeginWriteTransaction() has been successfully +** called). +** * The dbSize, dbOrigSize and dbFileSize variables are all valid. +** * The contents of the pager cache have not been modified. +** * The journal file may or may not be open. +** * Nothing (not even the first header) has been written to the journal. +** +** WRITER_CACHEMOD: +** +** A pager moves from WRITER_LOCKED state to this state when a page is +** first modified by the upper layer. In rollback mode the journal file +** is opened (if it is not already open) and a header written to the +** start of it. The database file on disk has not been modified. +** +** * A write transaction is active. +** * A RESERVED or greater lock is held on the database file. +** * The journal file is open and the first header has been written +** to it, but the header has not been synced to disk. +** * The contents of the page cache have been modified. +** +** WRITER_DBMOD: +** +** The pager transitions from WRITER_CACHEMOD into WRITER_DBMOD state +** when it modifies the contents of the database file. WAL connections +** never enter this state (since they do not modify the database file, +** just the log file). +** +** * A write transaction is active. +** * An EXCLUSIVE or greater lock is held on the database file. +** * The journal file is open and the first header has been written +** and synced to disk. +** * The contents of the page cache have been modified (and possibly +** written to disk). +** +** WRITER_FINISHED: +** +** It is not possible for a WAL connection to enter this state. +** +** A rollback-mode pager changes to WRITER_FINISHED state from WRITER_DBMOD +** state after the entire transaction has been successfully written into the +** database file. In this state the transaction may be committed simply +** by finalizing the journal file. Once in WRITER_FINISHED state, it is +** not possible to modify the database further. At this point, the upper +** layer must either commit or rollback the transaction. +** +** * A write transaction is active. +** * An EXCLUSIVE or greater lock is held on the database file. +** * All writing and syncing of journal and database data has finished. +** If no error occurred, all that remains is to finalize the journal to +** commit the transaction. If an error did occur, the caller will need +** to rollback the transaction. +** +** ERROR: +** +** The ERROR state is entered when an IO or disk-full error (including +** SQLITE_IOERR_NOMEM) occurs at a point in the code that makes it +** difficult to be sure that the in-memory pager state (cache contents, +** db size etc.) are consistent with the contents of the file-system. +** +** Temporary pager files may enter the ERROR state, but in-memory pagers +** cannot. +** +** For example, if an IO error occurs while performing a rollback, +** the contents of the page-cache may be left in an inconsistent state. +** At this point it would be dangerous to change back to READER state +** (as usually happens after a rollback). Any subsequent readers might +** report database corruption (due to the inconsistent cache), and if +** they upgrade to writers, they may inadvertently corrupt the database +** file. To avoid this hazard, the pager switches into the ERROR state +** instead of READER following such an error. +** +** Once it has entered the ERROR state, any attempt to use the pager +** to read or write data returns an error. Eventually, once all +** outstanding transactions have been abandoned, the pager is able to +** transition back to OPEN state, discarding the contents of the +** page-cache and any other in-memory state at the same time. Everything +** is reloaded from disk (and, if necessary, hot-journal rollback performed) +** when a read-transaction is next opened on the pager (transitioning +** the pager into READER state). At that point the system has recovered +** from the error. +** +** Specifically, the pager jumps into the ERROR state if: +** +** 1. An error occurs while attempting a rollback. This happens in +** function sqlite3PagerRollback(). +** +** 2. An error occurs while attempting to finalize a journal file +** following a commit in function sqlite3PagerCommitPhaseTwo(). +** +** 3. An error occurs while attempting to write to the journal or +** database file in function pagerStress() in order to free up +** memory. +** +** In other cases, the error is returned to the b-tree layer. The b-tree +** layer then attempts a rollback operation. If the error condition +** persists, the pager enters the ERROR state via condition (1) above. +** +** Condition (3) is necessary because it can be triggered by a read-only +** statement executed within a transaction. In this case, if the error +** code were simply returned to the user, the b-tree layer would not +** automatically attempt a rollback, as it assumes that an error in a +** read-only statement cannot leave the pager in an internally inconsistent +** state. +** +** * The Pager.errCode variable is set to something other than SQLITE_OK. +** * There are one or more outstanding references to pages (after the +** last reference is dropped the pager should move back to OPEN state). +** * The pager is not an in-memory pager. +** +** +** Notes: +** +** * A pager is never in WRITER_DBMOD or WRITER_FINISHED state if the +** connection is open in WAL mode. A WAL connection is always in one +** of the first four states. +** +** * Normally, a connection open in exclusive mode is never in PAGER_OPEN +** state. There are two exceptions: immediately after exclusive-mode has +** been turned on (and before any read or write transactions are +** executed), and when the pager is leaving the "error state". +** +** * See also: assert_pager_state(). +*/ +#define PAGER_OPEN 0 +#define PAGER_READER 1 +#define PAGER_WRITER_LOCKED 2 +#define PAGER_WRITER_CACHEMOD 3 +#define PAGER_WRITER_DBMOD 4 +#define PAGER_WRITER_FINISHED 5 +#define PAGER_ERROR 6 + +/* +** The Pager.eLock variable is almost always set to one of the +** following locking-states, according to the lock currently held on +** the database file: NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK. +** This variable is kept up to date as locks are taken and released by +** the pagerLockDb() and pagerUnlockDb() wrappers. +** +** If the VFS xLock() or xUnlock() returns an error other than SQLITE_BUSY +** (i.e. one of the SQLITE_IOERR subtypes), it is not clear whether or not +** the operation was successful. In these circumstances pagerLockDb() and +** pagerUnlockDb() take a conservative approach - eLock is always updated +** when unlocking the file, and only updated when locking the file if the +** VFS call is successful. This way, the Pager.eLock variable may be set +** to a less exclusive (lower) value than the lock that is actually held +** at the system level, but it is never set to a more exclusive value. +** +** This is usually safe. If an xUnlock fails or appears to fail, there may +** be a few redundant xLock() calls or a lock may be held for longer than +** required, but nothing really goes wrong. +** +** The exception is when the database file is unlocked as the pager moves +** from ERROR to OPEN state. At this point there may be a hot-journal file +** in the file-system that needs to be rolled back (as part of an OPEN->SHARED +** transition, by the same pager or any other). If the call to xUnlock() +** fails at this point and the pager is left holding an EXCLUSIVE lock, this +** can confuse the call to xCheckReservedLock() call made later as part +** of hot-journal detection. +** +** xCheckReservedLock() is defined as returning true "if there is a RESERVED +** lock held by this process or any others". So xCheckReservedLock may +** return true because the caller itself is holding an EXCLUSIVE lock (but +** doesn't know it because of a previous error in xUnlock). If this happens +** a hot-journal may be mistaken for a journal being created by an active +** transaction in another process, causing SQLite to read from the database +** without rolling it back. +** +** To work around this, if a call to xUnlock() fails when unlocking the +** database in the ERROR state, Pager.eLock is set to UNKNOWN_LOCK. It +** is only changed back to a real locking state after a successful call +** to xLock(EXCLUSIVE). Also, the code to do the OPEN->SHARED state transition +** omits the check for a hot-journal if Pager.eLock is set to UNKNOWN_LOCK +** lock. Instead, it assumes a hot-journal exists and obtains an EXCLUSIVE +** lock on the database file before attempting to roll it back. See function +** PagerSharedLock() for more detail. +** +** Pager.eLock may only be set to UNKNOWN_LOCK when the pager is in +** PAGER_OPEN state. +*/ +#define UNKNOWN_LOCK (EXCLUSIVE_LOCK+1) + +/* +** The maximum allowed sector size. 64KiB. If the xSectorsize() method +** returns a value larger than this, then MAX_SECTOR_SIZE is used instead. +** This could conceivably cause corruption following a power failure on +** such a system. This is currently an undocumented limit. +*/ +#define MAX_SECTOR_SIZE 0x10000 + + +/* +** An instance of the following structure is allocated for each active +** savepoint and statement transaction in the system. All such structures +** are stored in the Pager.aSavepoint[] array, which is allocated and +** resized using sqlite3Realloc(). +** +** When a savepoint is created, the PagerSavepoint.iHdrOffset field is +** set to 0. If a journal-header is written into the main journal while +** the savepoint is active, then iHdrOffset is set to the byte offset +** immediately following the last journal record written into the main +** journal before the journal-header. This is required during savepoint +** rollback (see pagerPlaybackSavepoint()). +*/ +typedef struct PagerSavepoint PagerSavepoint; +struct PagerSavepoint { + i64 iOffset; /* Starting offset in main journal */ + i64 iHdrOffset; /* See above */ + Bitvec *pInSavepoint; /* Set of pages in this savepoint */ + Pgno nOrig; /* Original number of pages in file */ + Pgno iSubRec; /* Index of first record in sub-journal */ + int bTruncateOnRelease; /* If stmt journal may be truncated on RELEASE */ +#ifndef SQLITE_OMIT_WAL + u32 aWalData[WAL_SAVEPOINT_NDATA]; /* WAL savepoint context */ +#endif +}; + +/* +** Bits of the Pager.doNotSpill flag. See further description below. +*/ +#define SPILLFLAG_OFF 0x01 /* Never spill cache. Set via pragma */ +#define SPILLFLAG_ROLLBACK 0x02 /* Current rolling back, so do not spill */ +#define SPILLFLAG_NOSYNC 0x04 /* Spill is ok, but do not sync */ + +/* +** An open page cache is an instance of struct Pager. A description of +** some of the more important member variables follows: +** +** eState +** +** The current 'state' of the pager object. See the comment and state +** diagram above for a description of the pager state. +** +** eLock +** +** For a real on-disk database, the current lock held on the database file - +** NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK. +** +** For a temporary or in-memory database (neither of which require any +** locks), this variable is always set to EXCLUSIVE_LOCK. Since such +** databases always have Pager.exclusiveMode==1, this tricks the pager +** logic into thinking that it already has all the locks it will ever +** need (and no reason to release them). +** +** In some (obscure) circumstances, this variable may also be set to +** UNKNOWN_LOCK. See the comment above the #define of UNKNOWN_LOCK for +** details. +** +** changeCountDone +** +** This boolean variable is used to make sure that the change-counter +** (the 4-byte header field at byte offset 24 of the database file) is +** not updated more often than necessary. +** +** It is set to true when the change-counter field is updated, which +** can only happen if an exclusive lock is held on the database file. +** It is cleared (set to false) whenever an exclusive lock is +** relinquished on the database file. Each time a transaction is committed, +** The changeCountDone flag is inspected. If it is true, the work of +** updating the change-counter is omitted for the current transaction. +** +** This mechanism means that when running in exclusive mode, a connection +** need only update the change-counter once, for the first transaction +** committed. +** +** setSuper +** +** When PagerCommitPhaseOne() is called to commit a transaction, it may +** (or may not) specify a super-journal name to be written into the +** journal file before it is synced to disk. +** +** Whether or not a journal file contains a super-journal pointer affects +** the way in which the journal file is finalized after the transaction is +** committed or rolled back when running in "journal_mode=PERSIST" mode. +** If a journal file does not contain a super-journal pointer, it is +** finalized by overwriting the first journal header with zeroes. If +** it does contain a super-journal pointer the journal file is finalized +** by truncating it to zero bytes, just as if the connection were +** running in "journal_mode=truncate" mode. +** +** Journal files that contain super-journal pointers cannot be finalized +** simply by overwriting the first journal-header with zeroes, as the +** super-journal pointer could interfere with hot-journal rollback of any +** subsequently interrupted transaction that reuses the journal file. +** +** The flag is cleared as soon as the journal file is finalized (either +** by PagerCommitPhaseTwo or PagerRollback). If an IO error prevents the +** journal file from being successfully finalized, the setSuper flag +** is cleared anyway (and the pager will move to ERROR state). +** +** doNotSpill +** +** This variables control the behavior of cache-spills (calls made by +** the pcache module to the pagerStress() routine to write cached data +** to the file-system in order to free up memory). +** +** When bits SPILLFLAG_OFF or SPILLFLAG_ROLLBACK of doNotSpill are set, +** writing to the database from pagerStress() is disabled altogether. +** The SPILLFLAG_ROLLBACK case is done in a very obscure case that +** comes up during savepoint rollback that requires the pcache module +** to allocate a new page to prevent the journal file from being written +** while it is being traversed by code in pager_playback(). The SPILLFLAG_OFF +** case is a user preference. +** +** If the SPILLFLAG_NOSYNC bit is set, writing to the database from +** pagerStress() is permitted, but syncing the journal file is not. +** This flag is set by sqlite3PagerWrite() when the file-system sector-size +** is larger than the database page-size in order to prevent a journal sync +** from happening in between the journalling of two pages on the same sector. +** +** subjInMemory +** +** This is a boolean variable. If true, then any required sub-journal +** is opened as an in-memory journal file. If false, then in-memory +** sub-journals are only used for in-memory pager files. +** +** This variable is updated by the upper layer each time a new +** write-transaction is opened. +** +** dbSize, dbOrigSize, dbFileSize +** +** Variable dbSize is set to the number of pages in the database file. +** It is valid in PAGER_READER and higher states (all states except for +** OPEN and ERROR). +** +** dbSize is set based on the size of the database file, which may be +** larger than the size of the database (the value stored at offset +** 28 of the database header by the btree). If the size of the file +** is not an integer multiple of the page-size, the value stored in +** dbSize is rounded down (i.e. a 5KB file with 2K page-size has dbSize==2). +** Except, any file that is greater than 0 bytes in size is considered +** to have at least one page. (i.e. a 1KB file with 2K page-size leads +** to dbSize==1). +** +** During a write-transaction, if pages with page-numbers greater than +** dbSize are modified in the cache, dbSize is updated accordingly. +** Similarly, if the database is truncated using PagerTruncateImage(), +** dbSize is updated. +** +** Variables dbOrigSize and dbFileSize are valid in states +** PAGER_WRITER_LOCKED and higher. dbOrigSize is a copy of the dbSize +** variable at the start of the transaction. It is used during rollback, +** and to determine whether or not pages need to be journalled before +** being modified. +** +** Throughout a write-transaction, dbFileSize contains the size of +** the file on disk in pages. It is set to a copy of dbSize when the +** write-transaction is first opened, and updated when VFS calls are made +** to write or truncate the database file on disk. +** +** The only reason the dbFileSize variable is required is to suppress +** unnecessary calls to xTruncate() after committing a transaction. If, +** when a transaction is committed, the dbFileSize variable indicates +** that the database file is larger than the database image (Pager.dbSize), +** pager_truncate() is called. The pager_truncate() call uses xFilesize() +** to measure the database file on disk, and then truncates it if required. +** dbFileSize is not used when rolling back a transaction. In this case +** pager_truncate() is called unconditionally (which means there may be +** a call to xFilesize() that is not strictly required). In either case, +** pager_truncate() may cause the file to become smaller or larger. +** +** dbHintSize +** +** The dbHintSize variable is used to limit the number of calls made to +** the VFS xFileControl(FCNTL_SIZE_HINT) method. +** +** dbHintSize is set to a copy of the dbSize variable when a +** write-transaction is opened (at the same time as dbFileSize and +** dbOrigSize). If the xFileControl(FCNTL_SIZE_HINT) method is called, +** dbHintSize is increased to the number of pages that correspond to the +** size-hint passed to the method call. See pager_write_pagelist() for +** details. +** +** errCode +** +** The Pager.errCode variable is only ever used in PAGER_ERROR state. It +** is set to zero in all other states. In PAGER_ERROR state, Pager.errCode +** is always set to SQLITE_FULL, SQLITE_IOERR or one of the SQLITE_IOERR_XXX +** sub-codes. +** +** syncFlags, walSyncFlags +** +** syncFlags is either SQLITE_SYNC_NORMAL (0x02) or SQLITE_SYNC_FULL (0x03). +** syncFlags is used for rollback mode. walSyncFlags is used for WAL mode +** and contains the flags used to sync the checkpoint operations in the +** lower two bits, and sync flags used for transaction commits in the WAL +** file in bits 0x04 and 0x08. In other words, to get the correct sync flags +** for checkpoint operations, use (walSyncFlags&0x03) and to get the correct +** sync flags for transaction commit, use ((walSyncFlags>>2)&0x03). Note +** that with synchronous=NORMAL in WAL mode, transaction commit is not synced +** meaning that the 0x04 and 0x08 bits are both zero. +*/ +struct Pager { + sqlite3_vfs *pVfs; /* OS functions to use for IO */ + u8 exclusiveMode; /* Boolean. True if locking_mode==EXCLUSIVE */ + u8 journalMode; /* One of the PAGER_JOURNALMODE_* values */ + u8 useJournal; /* Use a rollback journal on this file */ + u8 noSync; /* Do not sync the journal if true */ + u8 fullSync; /* Do extra syncs of the journal for robustness */ + u8 extraSync; /* sync directory after journal delete */ + u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ + u8 walSyncFlags; /* See description above */ + u8 tempFile; /* zFilename is a temporary or immutable file */ + u8 noLock; /* Do not lock (except in WAL mode) */ + u8 readOnly; /* True for a read-only database */ + u8 memDb; /* True to inhibit all file I/O */ + u8 memVfs; /* VFS-implemented memory database */ + + /************************************************************************** + ** The following block contains those class members that change during + ** routine operation. Class members not in this block are either fixed + ** when the pager is first created or else only change when there is a + ** significant mode change (such as changing the page_size, locking_mode, + ** or the journal_mode). From another view, these class members describe + ** the "state" of the pager, while other class members describe the + ** "configuration" of the pager. + */ + u8 eState; /* Pager state (OPEN, READER, WRITER_LOCKED..) */ + u8 eLock; /* Current lock held on database file */ + u8 changeCountDone; /* Set after incrementing the change-counter */ + u8 setSuper; /* Super-jrnl name is written into jrnl */ + u8 doNotSpill; /* Do not spill the cache when non-zero */ + u8 subjInMemory; /* True to use in-memory sub-journals */ + u8 bUseFetch; /* True to use xFetch() */ + u8 hasHeldSharedLock; /* True if a shared lock has ever been held */ + Pgno dbSize; /* Number of pages in the database */ + Pgno dbOrigSize; /* dbSize before the current transaction */ + Pgno dbFileSize; /* Number of pages in the database file */ + Pgno dbHintSize; /* Value passed to FCNTL_SIZE_HINT call */ + int errCode; /* One of several kinds of errors */ + int nRec; /* Pages journalled since last j-header written */ + u32 cksumInit; /* Quasi-random value added to every checksum */ + u32 nSubRec; /* Number of records written to sub-journal */ + Bitvec *pInJournal; /* One bit for each page in the database file */ + sqlite3_file *fd; /* File descriptor for database */ + sqlite3_file *jfd; /* File descriptor for main journal */ + sqlite3_file *sjfd; /* File descriptor for sub-journal */ + i64 journalOff; /* Current write offset in the journal file */ + i64 journalHdr; /* Byte offset to previous journal header */ + sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */ + PagerSavepoint *aSavepoint; /* Array of active savepoints */ + int nSavepoint; /* Number of elements in aSavepoint[] */ + u32 iDataVersion; /* Changes whenever database content changes */ + char dbFileVers[16]; /* Changes whenever database file changes */ + + int nMmapOut; /* Number of mmap pages currently outstanding */ + sqlite3_int64 szMmap; /* Desired maximum mmap size */ + PgHdr *pMmapFreelist; /* List of free mmap page headers (pDirty) */ + /* + ** End of the routinely-changing class members + ***************************************************************************/ + + u16 nExtra; /* Add this many bytes to each in-memory page */ + i16 nReserve; /* Number of unused bytes at end of each page */ + u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */ + u32 sectorSize; /* Assumed sector size during rollback */ + Pgno mxPgno; /* Maximum allowed size of the database */ + Pgno lckPgno; /* Page number for the locking page */ + i64 pageSize; /* Number of bytes in a page */ + i64 journalSizeLimit; /* Size limit for persistent journal files */ + char *zFilename; /* Name of the database file */ + char *zJournal; /* Name of the journal file */ + int (*xBusyHandler)(void*); /* Function to call when busy */ + void *pBusyHandlerArg; /* Context argument for xBusyHandler */ + u32 aStat[4]; /* Total cache hits, misses, writes, spills */ +#ifdef SQLITE_TEST + int nRead; /* Database pages read */ +#endif + void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */ + int (*xGet)(Pager*,Pgno,DbPage**,int); /* Routine to fetch a patch */ + char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ + PCache *pPCache; /* Pointer to page cache object */ +#ifndef SQLITE_OMIT_WAL + Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ + char *zWal; /* File name for write-ahead log */ +#endif +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + sqlite3 *dbWal; +#endif +}; + +/* +** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains +** the values accessed by passing SQLITE_DBSTATUS_CACHE_HIT, CACHE_MISS +** or CACHE_WRITE to sqlite3_db_status(). +*/ +#define PAGER_STAT_HIT 0 +#define PAGER_STAT_MISS 1 +#define PAGER_STAT_WRITE 2 +#define PAGER_STAT_SPILL 3 + +/* +** The following global variables hold counters used for +** testing purposes only. These variables do not exist in +** a non-testing build. These variables are not thread-safe. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_pager_readdb_count = 0; /* Number of full pages read from DB */ +SQLITE_API int sqlite3_pager_writedb_count = 0; /* Number of full pages written to DB */ +SQLITE_API int sqlite3_pager_writej_count = 0; /* Number of pages written to journal */ +# define PAGER_INCR(v) v++ +#else +# define PAGER_INCR(v) +#endif + + + +/* +** Journal files begin with the following magic string. The data +** was obtained from /dev/random. It is used only as a sanity check. +** +** Since version 2.8.0, the journal format contains additional sanity +** checking information. If the power fails while the journal is being +** written, semi-random garbage data might appear in the journal +** file after power is restored. If an attempt is then made +** to roll the journal back, the database could be corrupted. The additional +** sanity checking data is an attempt to discover the garbage in the +** journal and ignore it. +** +** The sanity checking information for the new journal format consists +** of a 32-bit checksum on each page of data. The checksum covers both +** the page number and the pPager->pageSize bytes of data for the page. +** This cksum is initialized to a 32-bit random value that appears in the +** journal file right after the header. The random initializer is important, +** because garbage data that appears at the end of a journal is likely +** data that was once in other files that have now been deleted. If the +** garbage data came from an obsolete journal file, the checksums might +** be correct. But by initializing the checksum to random value which +** is different for every journal, we minimize that risk. +*/ +static const unsigned char aJournalMagic[] = { + 0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd7, +}; + +/* +** The size of the of each page record in the journal is given by +** the following macro. +*/ +#define JOURNAL_PG_SZ(pPager) ((pPager->pageSize) + 8) + +/* +** The journal header size for this pager. This is usually the same +** size as a single disk sector. See also setSectorSize(). +*/ +#define JOURNAL_HDR_SZ(pPager) (pPager->sectorSize) + +/* +** The macro MEMDB is true if we are dealing with an in-memory database. +** We do this as a macro so that if the SQLITE_OMIT_MEMORYDB macro is set, +** the value of MEMDB will be a constant and the compiler will optimize +** out code that would never execute. +*/ +#ifdef SQLITE_OMIT_MEMORYDB +# define MEMDB 0 +#else +# define MEMDB pPager->memDb +#endif + +/* +** The macro USEFETCH is true if we are allowed to use the xFetch and xUnfetch +** interfaces to access the database using memory-mapped I/O. +*/ +#if SQLITE_MAX_MMAP_SIZE>0 +# define USEFETCH(x) ((x)->bUseFetch) +#else +# define USEFETCH(x) 0 +#endif + +#ifdef SQLITE_DIRECT_OVERFLOW_READ +/* +** Return true if page pgno can be read directly from the database file +** by the b-tree layer. This is the case if: +** +** (1) the database file is open +** (2) the VFS for the database is able to do unaligned sub-page reads +** (3) there are no dirty pages in the cache, and +** (4) the desired page is not currently in the wal file. +*/ +SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){ + assert( pPager!=0 ); + assert( pPager->fd!=0 ); + if( pPager->fd->pMethods==0 ) return 0; /* Case (1) */ + if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; /* Failed (3) */ +#ifndef SQLITE_OMIT_WAL + if( pPager->pWal ){ + u32 iRead = 0; + (void)sqlite3WalFindFrame(pPager->pWal, pgno, &iRead); + if( iRead ) return 0; /* Case (4) */ + } +#else + UNUSED_PARAMETER(pgno); +#endif + assert( pPager->fd->pMethods->xDeviceCharacteristics!=0 ); + if( (pPager->fd->pMethods->xDeviceCharacteristics(pPager->fd) + & SQLITE_IOCAP_SUBPAGE_READ)==0 ){ + return 0; /* Case (2) */ + } + return 1; +} +#endif + +#ifndef SQLITE_OMIT_WAL +# define pagerUseWal(x) ((x)->pWal!=0) +#else +# define pagerUseWal(x) 0 +# define pagerRollbackWal(x) 0 +# define pagerWalFrames(v,w,x,y) 0 +# define pagerOpenWalIfPresent(z) SQLITE_OK +# define pagerBeginReadTransaction(z) SQLITE_OK +#endif + +#ifndef NDEBUG +/* +** Usage: +** +** assert( assert_pager_state(pPager) ); +** +** This function runs many asserts to try to find inconsistencies in +** the internal state of the Pager object. +*/ +static int assert_pager_state(Pager *p){ + Pager *pPager = p; + + /* State must be valid. */ + assert( p->eState==PAGER_OPEN + || p->eState==PAGER_READER + || p->eState==PAGER_WRITER_LOCKED + || p->eState==PAGER_WRITER_CACHEMOD + || p->eState==PAGER_WRITER_DBMOD + || p->eState==PAGER_WRITER_FINISHED + || p->eState==PAGER_ERROR + ); + + /* Regardless of the current state, a temp-file connection always behaves + ** as if it has an exclusive lock on the database file. It never updates + ** the change-counter field, so the changeCountDone flag is always set. + */ + assert( p->tempFile==0 || p->eLock==EXCLUSIVE_LOCK ); + assert( p->tempFile==0 || pPager->changeCountDone ); + + /* If the useJournal flag is clear, the journal-mode must be "OFF". + ** And if the journal-mode is "OFF", the journal file must not be open. + */ + assert( p->journalMode==PAGER_JOURNALMODE_OFF || p->useJournal ); + assert( p->journalMode!=PAGER_JOURNALMODE_OFF || !isOpen(p->jfd) ); + + /* Check that MEMDB implies noSync. And an in-memory journal. Since + ** this means an in-memory pager performs no IO at all, it cannot encounter + ** either SQLITE_IOERR or SQLITE_FULL during rollback or while finalizing + ** a journal file. (although the in-memory journal implementation may + ** return SQLITE_IOERR_NOMEM while the journal file is being written). It + ** is therefore not possible for an in-memory pager to enter the ERROR + ** state. + */ + if( MEMDB ){ + assert( !isOpen(p->fd) ); + assert( p->noSync ); + assert( p->journalMode==PAGER_JOURNALMODE_OFF + || p->journalMode==PAGER_JOURNALMODE_MEMORY + ); + assert( p->eState!=PAGER_ERROR && p->eState!=PAGER_OPEN ); + assert( pagerUseWal(p)==0 ); + } + + /* If changeCountDone is set, a RESERVED lock or greater must be held + ** on the file. + */ + assert( pPager->changeCountDone==0 || pPager->eLock>=RESERVED_LOCK ); + assert( p->eLock!=PENDING_LOCK ); + + switch( p->eState ){ + case PAGER_OPEN: + assert( !MEMDB ); + assert( pPager->errCode==SQLITE_OK ); + assert( sqlite3PcacheRefCount(pPager->pPCache)==0 || pPager->tempFile ); + break; + + case PAGER_READER: + assert( pPager->errCode==SQLITE_OK ); + assert( p->eLock!=UNKNOWN_LOCK ); + assert( p->eLock>=SHARED_LOCK ); + break; + + case PAGER_WRITER_LOCKED: + assert( p->eLock!=UNKNOWN_LOCK ); + assert( pPager->errCode==SQLITE_OK ); + if( !pagerUseWal(pPager) ){ + assert( p->eLock>=RESERVED_LOCK ); + } + assert( pPager->dbSize==pPager->dbOrigSize ); + assert( pPager->dbOrigSize==pPager->dbFileSize ); + assert( pPager->dbOrigSize==pPager->dbHintSize ); + assert( pPager->setSuper==0 ); + break; + + case PAGER_WRITER_CACHEMOD: + assert( p->eLock!=UNKNOWN_LOCK ); + assert( pPager->errCode==SQLITE_OK ); + if( !pagerUseWal(pPager) ){ + /* It is possible that if journal_mode=wal here that neither the + ** journal file nor the WAL file are open. This happens during + ** a rollback transaction that switches from journal_mode=off + ** to journal_mode=wal. + */ + assert( p->eLock>=RESERVED_LOCK ); + assert( isOpen(p->jfd) + || p->journalMode==PAGER_JOURNALMODE_OFF + || p->journalMode==PAGER_JOURNALMODE_WAL + ); + } + assert( pPager->dbOrigSize==pPager->dbFileSize ); + assert( pPager->dbOrigSize==pPager->dbHintSize ); + break; + + case PAGER_WRITER_DBMOD: + assert( p->eLock==EXCLUSIVE_LOCK ); + assert( pPager->errCode==SQLITE_OK ); + assert( !pagerUseWal(pPager) ); + assert( p->eLock>=EXCLUSIVE_LOCK ); + assert( isOpen(p->jfd) + || p->journalMode==PAGER_JOURNALMODE_OFF + || p->journalMode==PAGER_JOURNALMODE_WAL + || (sqlite3OsDeviceCharacteristics(p->fd)&SQLITE_IOCAP_BATCH_ATOMIC) + ); + assert( pPager->dbOrigSize<=pPager->dbHintSize ); + break; + + case PAGER_WRITER_FINISHED: + assert( p->eLock==EXCLUSIVE_LOCK ); + assert( pPager->errCode==SQLITE_OK ); + assert( !pagerUseWal(pPager) ); + assert( isOpen(p->jfd) + || p->journalMode==PAGER_JOURNALMODE_OFF + || p->journalMode==PAGER_JOURNALMODE_WAL + || (sqlite3OsDeviceCharacteristics(p->fd)&SQLITE_IOCAP_BATCH_ATOMIC) + ); + break; + + case PAGER_ERROR: + /* There must be at least one outstanding reference to the pager if + ** in ERROR state. Otherwise the pager should have already dropped + ** back to OPEN state. + */ + assert( pPager->errCode!=SQLITE_OK ); + assert( sqlite3PcacheRefCount(pPager->pPCache)>0 || pPager->tempFile ); + break; + } + + return 1; +} +#endif /* ifndef NDEBUG */ + +#ifdef SQLITE_DEBUG +/* +** Return a pointer to a human readable string in a static buffer +** containing the state of the Pager object passed as an argument. This +** is intended to be used within debuggers. For example, as an alternative +** to "print *pPager" in gdb: +** +** (gdb) printf "%s", print_pager_state(pPager) +** +** This routine has external linkage in order to suppress compiler warnings +** about an unused function. It is enclosed within SQLITE_DEBUG and so does +** not appear in normal builds. +*/ +char *print_pager_state(Pager *p){ + static char zRet[1024]; + + sqlite3_snprintf(1024, zRet, + "Filename: %s\n" + "State: %s errCode=%d\n" + "Lock: %s\n" + "Locking mode: locking_mode=%s\n" + "Journal mode: journal_mode=%s\n" + "Backing store: tempFile=%d memDb=%d useJournal=%d\n" + "Journal: journalOff=%lld journalHdr=%lld\n" + "Size: dbsize=%d dbOrigSize=%d dbFileSize=%d\n" + , p->zFilename + , p->eState==PAGER_OPEN ? "OPEN" : + p->eState==PAGER_READER ? "READER" : + p->eState==PAGER_WRITER_LOCKED ? "WRITER_LOCKED" : + p->eState==PAGER_WRITER_CACHEMOD ? "WRITER_CACHEMOD" : + p->eState==PAGER_WRITER_DBMOD ? "WRITER_DBMOD" : + p->eState==PAGER_WRITER_FINISHED ? "WRITER_FINISHED" : + p->eState==PAGER_ERROR ? "ERROR" : "?error?" + , (int)p->errCode + , p->eLock==NO_LOCK ? "NO_LOCK" : + p->eLock==RESERVED_LOCK ? "RESERVED" : + p->eLock==EXCLUSIVE_LOCK ? "EXCLUSIVE" : + p->eLock==SHARED_LOCK ? "SHARED" : + p->eLock==UNKNOWN_LOCK ? "UNKNOWN" : "?error?" + , p->exclusiveMode ? "exclusive" : "normal" + , p->journalMode==PAGER_JOURNALMODE_MEMORY ? "memory" : + p->journalMode==PAGER_JOURNALMODE_OFF ? "off" : + p->journalMode==PAGER_JOURNALMODE_DELETE ? "delete" : + p->journalMode==PAGER_JOURNALMODE_PERSIST ? "persist" : + p->journalMode==PAGER_JOURNALMODE_TRUNCATE ? "truncate" : + p->journalMode==PAGER_JOURNALMODE_WAL ? "wal" : "?error?" + , (int)p->tempFile, (int)p->memDb, (int)p->useJournal + , p->journalOff, p->journalHdr + , (int)p->dbSize, (int)p->dbOrigSize, (int)p->dbFileSize + ); + + return zRet; +} +#endif + +/* Forward references to the various page getters */ +static int getPageNormal(Pager*,Pgno,DbPage**,int); +static int getPageError(Pager*,Pgno,DbPage**,int); +#if SQLITE_MAX_MMAP_SIZE>0 +static int getPageMMap(Pager*,Pgno,DbPage**,int); +#endif + +/* +** Set the Pager.xGet method for the appropriate routine used to fetch +** content from the pager. +*/ +static void setGetterMethod(Pager *pPager){ + if( pPager->errCode ){ + pPager->xGet = getPageError; +#if SQLITE_MAX_MMAP_SIZE>0 + }else if( USEFETCH(pPager) ){ + pPager->xGet = getPageMMap; +#endif /* SQLITE_MAX_MMAP_SIZE>0 */ + }else{ + pPager->xGet = getPageNormal; + } +} + +/* +** Return true if it is necessary to write page *pPg into the sub-journal. +** A page needs to be written into the sub-journal if there exists one +** or more open savepoints for which: +** +** * The page-number is less than or equal to PagerSavepoint.nOrig, and +** * The bit corresponding to the page-number is not set in +** PagerSavepoint.pInSavepoint. +*/ +static int subjRequiresPage(PgHdr *pPg){ + Pager *pPager = pPg->pPager; + PagerSavepoint *p; + Pgno pgno = pPg->pgno; + int i; + for(i=0; inSavepoint; i++){ + p = &pPager->aSavepoint[i]; + if( p->nOrig>=pgno && 0==sqlite3BitvecTestNotNull(p->pInSavepoint, pgno) ){ + for(i=i+1; inSavepoint; i++){ + pPager->aSavepoint[i].bTruncateOnRelease = 0; + } + return 1; + } + } + return 0; +} + +#ifdef SQLITE_DEBUG +/* +** Return true if the page is already in the journal file. +*/ +static int pageInJournal(Pager *pPager, PgHdr *pPg){ + return sqlite3BitvecTest(pPager->pInJournal, pPg->pgno); +} +#endif + +/* +** Read a 32-bit integer from the given file descriptor. Store the integer +** that is read in *pRes. Return SQLITE_OK if everything worked, or an +** error code is something goes wrong. +** +** All values are stored on disk as big-endian. +*/ +static int read32bits(sqlite3_file *fd, i64 offset, u32 *pRes){ + unsigned char ac[4]; + int rc = sqlite3OsRead(fd, ac, sizeof(ac), offset); + if( rc==SQLITE_OK ){ + *pRes = sqlite3Get4byte(ac); + } + return rc; +} + +/* +** Write a 32-bit integer into a string buffer in big-endian byte order. +*/ +#define put32bits(A,B) sqlite3Put4byte((u8*)A,B) + + +/* +** Write a 32-bit integer into the given file descriptor. Return SQLITE_OK +** on success or an error code is something goes wrong. +*/ +static int write32bits(sqlite3_file *fd, i64 offset, u32 val){ + char ac[4]; + put32bits(ac, val); + return sqlite3OsWrite(fd, ac, 4, offset); +} + +/* +** Unlock the database file to level eLock, which must be either NO_LOCK +** or SHARED_LOCK. Regardless of whether or not the call to xUnlock() +** succeeds, set the Pager.eLock variable to match the (attempted) new lock. +** +** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is +** called, do not modify it. See the comment above the #define of +** UNKNOWN_LOCK for an explanation of this. +*/ +static int pagerUnlockDb(Pager *pPager, int eLock){ + int rc = SQLITE_OK; + + assert( !pPager->exclusiveMode || pPager->eLock==eLock ); + assert( eLock==NO_LOCK || eLock==SHARED_LOCK ); + assert( eLock!=NO_LOCK || pagerUseWal(pPager)==0 ); + if( isOpen(pPager->fd) ){ + assert( pPager->eLock>=eLock ); + rc = pPager->noLock ? SQLITE_OK : sqlite3OsUnlock(pPager->fd, eLock); + if( pPager->eLock!=UNKNOWN_LOCK ){ + pPager->eLock = (u8)eLock; + } + IOTRACE(("UNLOCK %p %d\n", pPager, eLock)) + } + pPager->changeCountDone = pPager->tempFile; /* ticket fb3b3024ea238d5c */ + return rc; +} + +/* +** Lock the database file to level eLock, which must be either SHARED_LOCK, +** RESERVED_LOCK or EXCLUSIVE_LOCK. If the caller is successful, set the +** Pager.eLock variable to the new locking state. +** +** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is +** called, do not modify it unless the new locking state is EXCLUSIVE_LOCK. +** See the comment above the #define of UNKNOWN_LOCK for an explanation +** of this. +*/ +static int pagerLockDb(Pager *pPager, int eLock){ + int rc = SQLITE_OK; + + assert( eLock==SHARED_LOCK || eLock==RESERVED_LOCK || eLock==EXCLUSIVE_LOCK ); + if( pPager->eLockeLock==UNKNOWN_LOCK ){ + rc = pPager->noLock ? SQLITE_OK : sqlite3OsLock(pPager->fd, eLock); + if( rc==SQLITE_OK && (pPager->eLock!=UNKNOWN_LOCK||eLock==EXCLUSIVE_LOCK) ){ + pPager->eLock = (u8)eLock; + IOTRACE(("LOCK %p %d\n", pPager, eLock)) + } + } + return rc; +} + +/* +** This function determines whether or not the atomic-write or +** atomic-batch-write optimizations can be used with this pager. The +** atomic-write optimization can be used if: +** +** (a) the value returned by OsDeviceCharacteristics() indicates that +** a database page may be written atomically, and +** (b) the value returned by OsSectorSize() is less than or equal +** to the page size. +** +** If it can be used, then the value returned is the size of the journal +** file when it contains rollback data for exactly one page. +** +** The atomic-batch-write optimization can be used if OsDeviceCharacteristics() +** returns a value with the SQLITE_IOCAP_BATCH_ATOMIC bit set. -1 is +** returned in this case. +** +** If neither optimization can be used, 0 is returned. +*/ +static int jrnlBufferSize(Pager *pPager){ + assert( !MEMDB ); + +#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \ + || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) + int dc; /* Device characteristics */ + + assert( isOpen(pPager->fd) ); + dc = sqlite3OsDeviceCharacteristics(pPager->fd); +#else + UNUSED_PARAMETER(pPager); +#endif + +#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE + if( pPager->dbSize>0 && (dc&SQLITE_IOCAP_BATCH_ATOMIC) ){ + return -1; + } +#endif + +#ifdef SQLITE_ENABLE_ATOMIC_WRITE + { + int nSector = pPager->sectorSize; + int szPage = pPager->pageSize; + + assert(SQLITE_IOCAP_ATOMIC512==(512>>8)); + assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8)); + if( 0==(dc&(SQLITE_IOCAP_ATOMIC|(szPage>>8)) || nSector>szPage) ){ + return 0; + } + } + + return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager); +#endif + + return 0; +} + +/* +** If SQLITE_CHECK_PAGES is defined then we do some sanity checking +** on the cache using a hash function. This is used for testing +** and debugging only. +*/ +#ifdef SQLITE_CHECK_PAGES +/* +** Return a 64-bit hash of the page data for pPage. +*/ +static u64 pager_datahash(int nByte, unsigned char *pData){ + u64 hash = 0; + int i; + for(i=0; ipPager->pageSize, (unsigned char *)pPage->pData); +} +static void pager_set_pagehash(PgHdr *pPage){ + pPage->pageHash = pager_pagehash(pPage); +} + +/* +** The CHECK_PAGE macro takes a PgHdr* as an argument. If SQLITE_CHECK_PAGES +** is defined, and NDEBUG is not defined, an assert() statement checks +** that the page is either dirty or still matches the calculated page-hash. +*/ +#define CHECK_PAGE(x) checkPage(x) +static void checkPage(PgHdr *pPg){ + Pager *pPager = pPg->pPager; + assert( pPager->eState!=PAGER_ERROR ); + assert( (pPg->flags&PGHDR_DIRTY) || pPg->pageHash==pager_pagehash(pPg) ); +} + +#else +#define pager_datahash(X,Y) 0 +#define pager_pagehash(X) 0 +#define pager_set_pagehash(X) +#define CHECK_PAGE(x) +#endif /* SQLITE_CHECK_PAGES */ + +/* +** Free a buffer allocated by the readSuperJournal() function. +*/ +static void freeSuperJournal(char *zSuper){ + if( zSuper ){ + sqlite3_free(&zSuper[-4]); + } +} + +/* +** Parameter pJrnl is a file-handle open on a journal file. This function +** attempts to read a super-journal file name from the end of the journal +** file. If successful, it sets output parameter (*pzSuper) to point to a +** buffer containing the super-journal name as a nul-terminated string. +** The caller is responsible for freeing the buffer using freeSuperJournal(). +** +** Refer to comments above writeSuperJournal() for the format used to store +** a super-journal file name at the end of a journal file. +** +** Parameter nSuper is passed the maximum allowable size of the super journal +** name in bytes. If the super-journal name in the journal is longer than +** nSuper bytes (including a nul-terminator), then this is handled as if no +** super-journal name were present in the journal. +** +** If there is no super-journal name at the end of pJrnl, (*pzSuper) is +** set to 0 and SQLITE_OK is returned. Or, if an error occurs while reading +** the super-journal name, an SQLite error code is returned and (*pzSuper) +** is set to 0. +*/ +static int readSuperJournal(sqlite3_file *pJrnl, u64 nSuper, char **pzSuper){ + int rc; /* Return code */ + u32 len; /* Length in bytes of super-journal name */ + i64 szJ; /* Total size in bytes of journal file pJrnl */ + u32 cksum; /* MJ checksum value read from journal */ + unsigned char aMagic[8]; /* A buffer to hold the magic header */ + char *zOut = 0; + + *pzSuper = 0; + if( SQLITE_OK!=(rc = sqlite3OsFileSize(pJrnl, &szJ)) + || szJ<16 + || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len)) + || len>=nSuper + || len>szJ-16 + || len==0 + || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum)) + || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8)) + || memcmp(aMagic, aJournalMagic, 8) + ){ + return rc; + } + + zOut = (char*)sqlite3MallocZero(4 + len + 2); + if( !zOut ){ + rc = SQLITE_NOMEM_BKPT; + }else{ + zOut = &zOut[4]; + if( SQLITE_OK==(rc = sqlite3OsRead(pJrnl, zOut, len, szJ-16-len)) ){ + u32 u; /* Unsigned loop counter */ + /* See if the checksum matches the super-journal name */ + for(u=0; ujournalOff, assuming a sector +** size of pPager->sectorSize bytes. +** +** i.e for a sector size of 512: +** +** Pager.journalOff Return value +** --------------------------------------- +** 0 0 +** 512 512 +** 100 512 +** 2000 2048 +** +*/ +static i64 journalHdrOffset(Pager *pPager){ + i64 offset = 0; + i64 c = pPager->journalOff; + if( c ){ + offset = ((c-1)/JOURNAL_HDR_SZ(pPager) + 1) * JOURNAL_HDR_SZ(pPager); + } + assert( offset%JOURNAL_HDR_SZ(pPager)==0 ); + assert( offset>=c ); + assert( (offset-c)jfd) ); + assert( !sqlite3JournalIsInMemory(pPager->jfd) ); + if( pPager->journalOff ){ + const i64 iLimit = pPager->journalSizeLimit; /* Local cache of jsl */ + + IOTRACE(("JZEROHDR %p\n", pPager)) + if( doTruncate || iLimit==0 ){ + rc = sqlite3OsTruncate(pPager->jfd, 0); + }else{ + static const char zeroHdr[28] = {0}; + rc = sqlite3OsWrite(pPager->jfd, zeroHdr, sizeof(zeroHdr), 0); + } + if( rc==SQLITE_OK && !pPager->noSync ){ + rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_DATAONLY|pPager->syncFlags); + } + + /* At this point the transaction is committed but the write lock + ** is still held on the file. If there is a size limit configured for + ** the persistent journal and the journal file currently consumes more + ** space than that limit allows for, truncate it now. There is no need + ** to sync the file following this operation. + */ + if( rc==SQLITE_OK && iLimit>0 ){ + i64 sz; + rc = sqlite3OsFileSize(pPager->jfd, &sz); + if( rc==SQLITE_OK && sz>iLimit ){ + rc = sqlite3OsTruncate(pPager->jfd, iLimit); + } + } + } + return rc; +} + +/* +** The journal file must be open when this routine is called. A journal +** header (JOURNAL_HDR_SZ bytes) is written into the journal file at the +** current location. +** +** The format for the journal header is as follows: +** - 8 bytes: Magic identifying journal format. +** - 4 bytes: Number of records in journal, or -1 no-sync mode is on. +** - 4 bytes: Random number used for page hash. +** - 4 bytes: Initial database page count. +** - 4 bytes: Sector size used by the process that wrote this journal. +** - 4 bytes: Database page size. +** +** Followed by (JOURNAL_HDR_SZ - 28) bytes of unused space. +*/ +static int writeJournalHdr(Pager *pPager){ + int rc = SQLITE_OK; /* Return code */ + char *zHeader = pPager->pTmpSpace; /* Temporary space used to build header */ + u32 nHeader = (u32)pPager->pageSize;/* Size of buffer pointed to by zHeader */ + u32 nWrite; /* Bytes of header sector written */ + int ii; /* Loop counter */ + + assert( isOpen(pPager->jfd) ); /* Journal file must be open. */ + + if( nHeader>JOURNAL_HDR_SZ(pPager) ){ + nHeader = JOURNAL_HDR_SZ(pPager); + } + + /* If there are active savepoints and any of them were created + ** since the most recent journal header was written, update the + ** PagerSavepoint.iHdrOffset fields now. + */ + for(ii=0; iinSavepoint; ii++){ + if( pPager->aSavepoint[ii].iHdrOffset==0 ){ + pPager->aSavepoint[ii].iHdrOffset = pPager->journalOff; + } + } + + pPager->journalHdr = pPager->journalOff = journalHdrOffset(pPager); + + /* + ** Write the nRec Field - the number of page records that follow this + ** journal header. Normally, zero is written to this value at this time. + ** After the records are added to the journal (and the journal synced, + ** if in full-sync mode), the zero is overwritten with the true number + ** of records (see syncJournal()). + ** + ** A faster alternative is to write 0xFFFFFFFF to the nRec field. When + ** reading the journal this value tells SQLite to assume that the + ** rest of the journal file contains valid page records. This assumption + ** is dangerous, as if a failure occurred whilst writing to the journal + ** file it may contain some garbage data. There are two scenarios + ** where this risk can be ignored: + ** + ** * When the pager is in no-sync mode. Corruption can follow a + ** power failure in this case anyway. + ** + ** * When the SQLITE_IOCAP_SAFE_APPEND flag is set. This guarantees + ** that garbage data is never appended to the journal file. + */ + assert( isOpen(pPager->fd) || pPager->noSync ); + if( pPager->noSync || (pPager->journalMode==PAGER_JOURNALMODE_MEMORY) + || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) + ){ + memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic)); + put32bits(&zHeader[sizeof(aJournalMagic)], 0xffffffff); + }else{ + memset(zHeader, 0, sizeof(aJournalMagic)+4); + } + + + + /* The random check-hash initializer */ + if( pPager->journalMode!=PAGER_JOURNALMODE_MEMORY ){ + sqlite3_randomness(sizeof(pPager->cksumInit), &pPager->cksumInit); + } +#ifdef SQLITE_DEBUG + else{ + /* The Pager.cksumInit variable is usually randomized above to protect + ** against there being existing records in the journal file. This is + ** dangerous, as following a crash they may be mistaken for records + ** written by the current transaction and rolled back into the database + ** file, causing corruption. The following assert statements verify + ** that this is not required in "journal_mode=memory" mode, as in that + ** case the journal file is always 0 bytes in size at this point. + ** It is advantageous to avoid the sqlite3_randomness() call if possible + ** as it takes the global PRNG mutex. */ + i64 sz = 0; + sqlite3OsFileSize(pPager->jfd, &sz); + assert( sz==0 ); + assert( pPager->journalOff==journalHdrOffset(pPager) ); + assert( sqlite3JournalIsInMemory(pPager->jfd) ); + } +#endif + put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit); + + /* The initial database size */ + put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbOrigSize); + /* The assumed sector size for this process */ + put32bits(&zHeader[sizeof(aJournalMagic)+12], pPager->sectorSize); + + /* The page size */ + put32bits(&zHeader[sizeof(aJournalMagic)+16], pPager->pageSize); + + /* Initializing the tail of the buffer is not necessary. Everything + ** works find if the following memset() is omitted. But initializing + ** the memory prevents valgrind from complaining, so we are willing to + ** take the performance hit. + */ + memset(&zHeader[sizeof(aJournalMagic)+20], 0, + nHeader-(sizeof(aJournalMagic)+20)); + + /* In theory, it is only necessary to write the 28 bytes that the + ** journal header consumes to the journal file here. Then increment the + ** Pager.journalOff variable by JOURNAL_HDR_SZ so that the next + ** record is written to the following sector (leaving a gap in the file + ** that will be implicitly filled in by the OS). + ** + ** However it has been discovered that on some systems this pattern can + ** be significantly slower than contiguously writing data to the file, + ** even if that means explicitly writing data to the block of + ** (JOURNAL_HDR_SZ - 28) bytes that will not be used. So that is what + ** is done. + ** + ** The loop is required here in case the sector-size is larger than the + ** database page size. Since the zHeader buffer is only Pager.pageSize + ** bytes in size, more than one call to sqlite3OsWrite() may be required + ** to populate the entire journal header sector. + */ + for(nWrite=0; rc==SQLITE_OK&&nWritejournalHdr, nHeader)) + rc = sqlite3OsWrite(pPager->jfd, zHeader, nHeader, pPager->journalOff); + assert( pPager->journalHdr <= pPager->journalOff ); + pPager->journalOff += nHeader; + } + + return rc; +} + +/* +** The journal file must be open when this is called. A journal header file +** (JOURNAL_HDR_SZ bytes) is read from the current location in the journal +** file. The current location in the journal file is given by +** pPager->journalOff. See comments above function writeJournalHdr() for +** a description of the journal header format. +** +** If the header is read successfully, *pNRec is set to the number of +** page records following this header and *pDbSize is set to the size of the +** database before the transaction began, in pages. Also, pPager->cksumInit +** is set to the value read from the journal header. SQLITE_OK is returned +** in this case. +** +** If the journal header file appears to be corrupted, SQLITE_DONE is +** returned and *pNRec and *PDbSize are undefined. If JOURNAL_HDR_SZ bytes +** cannot be read from the journal file an error code is returned. +*/ +static int readJournalHdr( + Pager *pPager, /* Pager object */ + int isHot, + i64 journalSize, /* Size of the open journal file in bytes */ + u32 *pNRec, /* OUT: Value read from the nRec field */ + u32 *pDbSize /* OUT: Value of original database size field */ +){ + int rc; /* Return code */ + unsigned char aMagic[8]; /* A buffer to hold the magic header */ + i64 iHdrOff; /* Offset of journal header being read */ + + assert( isOpen(pPager->jfd) ); /* Journal file must be open. */ + + /* Advance Pager.journalOff to the start of the next sector. If the + ** journal file is too small for there to be a header stored at this + ** point, return SQLITE_DONE. + */ + pPager->journalOff = journalHdrOffset(pPager); + if( pPager->journalOff+JOURNAL_HDR_SZ(pPager) > journalSize ){ + return SQLITE_DONE; + } + iHdrOff = pPager->journalOff; + + /* Read in the first 8 bytes of the journal header. If they do not match + ** the magic string found at the start of each journal header, return + ** SQLITE_DONE. If an IO error occurs, return an error code. Otherwise, + ** proceed. + */ + if( isHot || iHdrOff!=pPager->journalHdr ){ + rc = sqlite3OsRead(pPager->jfd, aMagic, sizeof(aMagic), iHdrOff); + if( rc ){ + return rc; + } + if( memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){ + return SQLITE_DONE; + } + } + + /* Read the first three 32-bit fields of the journal header: The nRec + ** field, the checksum-initializer and the database size at the start + ** of the transaction. Return an error code if anything goes wrong. + */ + if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+8, pNRec)) + || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+12, &pPager->cksumInit)) + || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+16, pDbSize)) + ){ + return rc; + } + + if( pPager->journalOff==0 ){ + u32 iPageSize; /* Page-size field of journal header */ + u32 iSectorSize; /* Sector-size field of journal header */ + + /* Read the page-size and sector-size journal header fields. */ + if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+20, &iSectorSize)) + || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+24, &iPageSize)) + ){ + return rc; + } + + /* Versions of SQLite prior to 3.5.8 set the page-size field of the + ** journal header to zero. In this case, assume that the Pager.pageSize + ** variable is already set to the correct page size. + */ + if( iPageSize==0 ){ + iPageSize = pPager->pageSize; + } + + /* Check that the values read from the page-size and sector-size fields + ** are within range. To be 'in range', both values need to be a power + ** of two greater than or equal to 512 or 32, and not greater than their + ** respective compile time maximum limits. + */ + if( iPageSize<512 || iSectorSize<32 + || iPageSize>SQLITE_MAX_PAGE_SIZE || iSectorSize>MAX_SECTOR_SIZE + || ((iPageSize-1)&iPageSize)!=0 || ((iSectorSize-1)&iSectorSize)!=0 + ){ + /* If the either the page-size or sector-size in the journal-header is + ** invalid, then the process that wrote the journal-header must have + ** crashed before the header was synced. In this case stop reading + ** the journal file here. + */ + return SQLITE_DONE; + } + + /* Update the page-size to match the value read from the journal. + ** Use a testcase() macro to make sure that malloc failure within + ** PagerSetPagesize() is tested. + */ + rc = sqlite3PagerSetPagesize(pPager, &iPageSize, -1); + testcase( rc!=SQLITE_OK ); + + /* Update the assumed sector-size to match the value used by + ** the process that created this journal. If this journal was + ** created by a process other than this one, then this routine + ** is being called from within pager_playback(). The local value + ** of Pager.sectorSize is restored at the end of that routine. + */ + pPager->sectorSize = iSectorSize; + } + + pPager->journalOff += JOURNAL_HDR_SZ(pPager); + return rc; +} + + +/* +** Write the supplied super-journal name into the journal file for pager +** pPager at the current location. The super-journal name must be the last +** thing written to a journal file. If the pager is in full-sync mode, the +** journal file descriptor is advanced to the next sector boundary before +** anything is written. The format is: +** +** + 4 bytes: PAGER_SJ_PGNO. +** + N bytes: super-journal filename in utf-8. +** + 4 bytes: N (length of super-journal name in bytes, no nul-terminator). +** + 4 bytes: super-journal name checksum. +** + 8 bytes: aJournalMagic[]. +** +** The super-journal page checksum is the sum of the bytes in the super-journal +** name, where each byte is interpreted as a signed 8-bit integer. +** +** If zSuper is a NULL pointer (occurs for a single database transaction), +** this call is a no-op. +*/ +static int writeSuperJournal(Pager *pPager, const char *zSuper){ + int rc; /* Return code */ + int nSuper; /* Length of string zSuper */ + i64 iHdrOff; /* Offset of header in journal file */ + i64 jrnlSize; /* Size of journal file on disk */ + u32 cksum = 0; /* Checksum of string zSuper */ + + assert( pPager->setSuper==0 ); + assert( !pagerUseWal(pPager) ); + + if( !zSuper + || pPager->journalMode==PAGER_JOURNALMODE_MEMORY + || !isOpen(pPager->jfd) + ){ + return SQLITE_OK; + } + pPager->setSuper = 1; + assert( pPager->journalHdr <= pPager->journalOff ); + + /* Calculate the length in bytes and the checksum of zSuper */ + for(nSuper=0; zSuper[nSuper]; nSuper++){ + cksum += zSuper[nSuper]; + } + + /* If in full-sync mode, advance to the next disk sector before writing + ** the super-journal name. This is in case the previous page written to + ** the journal has already been synced. + */ + if( pPager->fullSync ){ + pPager->journalOff = journalHdrOffset(pPager); + } + iHdrOff = pPager->journalOff; + + /* Write the super-journal data to the end of the journal file. If + ** an error occurs, return the error code to the caller. + */ + if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_SJ_PGNO(pPager)))) + || (0 != (rc = sqlite3OsWrite(pPager->jfd, zSuper, nSuper, iHdrOff+4))) + || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nSuper, nSuper))) + || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nSuper+4, cksum))) + || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8, + iHdrOff+4+nSuper+8))) + ){ + return rc; + } + pPager->journalOff += (nSuper+20); + + /* If the pager is in persistent-journal mode, then the physical + ** journal-file may extend past the end of the super-journal name + ** and 8 bytes of magic data just written to the file. This is + ** dangerous because the code to rollback a hot-journal file + ** will not be able to find the super-journal name to determine + ** whether or not the journal is hot. + ** + ** Easiest thing to do in this scenario is to truncate the journal + ** file to the required size. + */ + if( SQLITE_OK==(rc = sqlite3OsFileSize(pPager->jfd, &jrnlSize)) + && jrnlSize>pPager->journalOff + ){ + rc = sqlite3OsTruncate(pPager->jfd, pPager->journalOff); + } + return rc; +} + +/* +** Discard the entire contents of the in-memory page-cache. +*/ +static void pager_reset(Pager *pPager){ + pPager->iDataVersion++; + sqlite3BackupRestart(pPager->pBackup); + sqlite3PcacheClear(pPager->pPCache); +} + +/* +** Return the pPager->iDataVersion value +*/ +SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager *pPager){ + return pPager->iDataVersion; +} + +/* +** Free all structures in the Pager.aSavepoint[] array and set both +** Pager.aSavepoint and Pager.nSavepoint to zero. Close the sub-journal +** if it is open and the pager is not in exclusive mode. +*/ +static void releaseAllSavepoints(Pager *pPager){ + int ii; /* Iterator for looping through Pager.aSavepoint */ + for(ii=0; iinSavepoint; ii++){ + sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint); + } + if( !pPager->exclusiveMode || sqlite3JournalIsInMemory(pPager->sjfd) ){ + sqlite3OsClose(pPager->sjfd); + } + sqlite3_free(pPager->aSavepoint); + pPager->aSavepoint = 0; + pPager->nSavepoint = 0; + pPager->nSubRec = 0; +} + +/* +** Set the bit number pgno in the PagerSavepoint.pInSavepoint +** bitvecs of all open savepoints. Return SQLITE_OK if successful +** or SQLITE_NOMEM if a malloc failure occurs. +*/ +static int addToSavepointBitvecs(Pager *pPager, Pgno pgno){ + int ii; /* Loop counter */ + int rc = SQLITE_OK; /* Result code */ + + for(ii=0; iinSavepoint; ii++){ + PagerSavepoint *p = &pPager->aSavepoint[ii]; + if( pgno<=p->nOrig ){ + rc |= sqlite3BitvecSet(p->pInSavepoint, pgno); + testcase( rc==SQLITE_NOMEM ); + assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); + } + } + return rc; +} + +/* +** This function is a no-op if the pager is in exclusive mode and not +** in the ERROR state. Otherwise, it switches the pager to PAGER_OPEN +** state. +** +** If the pager is not in exclusive-access mode, the database file is +** completely unlocked. If the file is unlocked and the file-system does +** not exhibit the UNDELETABLE_WHEN_OPEN property, the journal file is +** closed (if it is open). +** +** If the pager is in ERROR state when this function is called, the +** contents of the pager cache are discarded before switching back to +** the OPEN state. Regardless of whether the pager is in exclusive-mode +** or not, any journal file left in the file-system will be treated +** as a hot-journal and rolled back the next time a read-transaction +** is opened (by this or by any other connection). +*/ +static void pager_unlock(Pager *pPager){ + + assert( pPager->eState==PAGER_READER + || pPager->eState==PAGER_OPEN + || pPager->eState==PAGER_ERROR + ); + + sqlite3BitvecDestroy(pPager->pInJournal); + pPager->pInJournal = 0; + releaseAllSavepoints(pPager); + + if( pagerUseWal(pPager) ){ + assert( !isOpen(pPager->jfd) ); + if( pPager->eState==PAGER_ERROR ){ + /* If an IO error occurs in wal.c while attempting to wrap the wal file, + ** then the Wal object may be holding a write-lock but no read-lock. + ** This call ensures that the write-lock is dropped as well. We cannot + ** have sqlite3WalEndReadTransaction() drop the write-lock, as it once + ** did, because this would break "BEGIN EXCLUSIVE" handling for + ** SQLITE_ENABLE_SETLK_TIMEOUT builds. */ + (void)sqlite3WalEndWriteTransaction(pPager->pWal); + } + sqlite3WalEndReadTransaction(pPager->pWal); + pPager->eState = PAGER_OPEN; + }else if( !pPager->exclusiveMode ){ + int rc; /* Error code returned by pagerUnlockDb() */ + int iDc = isOpen(pPager->fd)?sqlite3OsDeviceCharacteristics(pPager->fd):0; + + /* If the operating system support deletion of open files, then + ** close the journal file when dropping the database lock. Otherwise + ** another connection with journal_mode=delete might delete the file + ** out from under us. + */ + assert( (PAGER_JOURNALMODE_MEMORY & 5)!=1 ); + assert( (PAGER_JOURNALMODE_OFF & 5)!=1 ); + assert( (PAGER_JOURNALMODE_WAL & 5)!=1 ); + assert( (PAGER_JOURNALMODE_DELETE & 5)!=1 ); + assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 ); + assert( (PAGER_JOURNALMODE_PERSIST & 5)==1 ); + if( 0==(iDc & SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN) + || 1!=(pPager->journalMode & 5) + ){ + sqlite3OsClose(pPager->jfd); + } + + /* If the pager is in the ERROR state and the call to unlock the database + ** file fails, set the current lock to UNKNOWN_LOCK. See the comment + ** above the #define for UNKNOWN_LOCK for an explanation of why this + ** is necessary. + */ + rc = pagerUnlockDb(pPager, NO_LOCK); + if( rc!=SQLITE_OK && pPager->eState==PAGER_ERROR ){ + pPager->eLock = UNKNOWN_LOCK; + } + + /* The pager state may be changed from PAGER_ERROR to PAGER_OPEN here + ** without clearing the error code. This is intentional - the error + ** code is cleared and the cache reset in the block below. + */ + assert( pPager->errCode || pPager->eState!=PAGER_ERROR ); + pPager->eState = PAGER_OPEN; + } + + /* If Pager.errCode is set, the contents of the pager cache cannot be + ** trusted. Now that there are no outstanding references to the pager, + ** it can safely move back to PAGER_OPEN state. This happens in both + ** normal and exclusive-locking mode. + */ + assert( pPager->errCode==SQLITE_OK || !MEMDB ); + if( pPager->errCode ){ + if( pPager->tempFile==0 ){ + pager_reset(pPager); + pPager->changeCountDone = 0; + pPager->eState = PAGER_OPEN; + }else{ + pPager->eState = (isOpen(pPager->jfd) ? PAGER_OPEN : PAGER_READER); + } + if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0); + pPager->errCode = SQLITE_OK; + setGetterMethod(pPager); + } + + pPager->journalOff = 0; + pPager->journalHdr = 0; + pPager->setSuper = 0; +} + +/* +** This function is called whenever an IOERR or FULL error that requires +** the pager to transition into the ERROR state may have occurred. +** The first argument is a pointer to the pager structure, the second +** the error-code about to be returned by a pager API function. The +** value returned is a copy of the second argument to this function. +** +** If the second argument is SQLITE_FULL, SQLITE_IOERR or one of the +** IOERR sub-codes, the pager enters the ERROR state and the error code +** is stored in Pager.errCode. While the pager remains in the ERROR state, +** all major API calls on the Pager will immediately return Pager.errCode. +** +** The ERROR state indicates that the contents of the pager-cache +** cannot be trusted. This state can be cleared by completely discarding +** the contents of the pager-cache. If a transaction was active when +** the persistent error occurred, then the rollback journal may need +** to be replayed to restore the contents of the database file (as if +** it were a hot-journal). +*/ +static int pager_error(Pager *pPager, int rc){ + int rc2 = rc & 0xff; + assert( rc==SQLITE_OK || !MEMDB ); + assert( + pPager->errCode==SQLITE_FULL || + pPager->errCode==SQLITE_OK || + (pPager->errCode & 0xff)==SQLITE_IOERR + ); + if( rc2==SQLITE_FULL || rc2==SQLITE_IOERR ){ + pPager->errCode = rc; + pPager->eState = PAGER_ERROR; + setGetterMethod(pPager); + } + return rc; +} + +static int pager_truncate(Pager *pPager, Pgno nPage); + +/* +** The write transaction open on pPager is being committed (bCommit==1) +** or rolled back (bCommit==0). +** +** Return TRUE if and only if all dirty pages should be flushed to disk. +** +** Rules: +** +** * For non-TEMP databases, always sync to disk. This is necessary +** for transactions to be durable. +** +** * Sync TEMP database only on a COMMIT (not a ROLLBACK) when the backing +** file has been created already (via a spill on pagerStress()) and +** when the number of dirty pages in memory exceeds 25% of the total +** cache size. +*/ +static int pagerFlushOnCommit(Pager *pPager, int bCommit){ + if( pPager->tempFile==0 ) return 1; + if( !bCommit ) return 0; + if( !isOpen(pPager->fd) ) return 0; + return (sqlite3PCachePercentDirty(pPager->pPCache)>=25); +} + +/* +** This routine ends a transaction. A transaction is usually ended by +** either a COMMIT or a ROLLBACK operation. This routine may be called +** after rollback of a hot-journal, or if an error occurs while opening +** the journal file or writing the very first journal-header of a +** database transaction. +** +** This routine is never called in PAGER_ERROR state. If it is called +** in PAGER_NONE or PAGER_SHARED state and the lock held is less +** exclusive than a RESERVED lock, it is a no-op. +** +** Otherwise, any active savepoints are released. +** +** If the journal file is open, then it is "finalized". Once a journal +** file has been finalized it is not possible to use it to roll back a +** transaction. Nor will it be considered to be a hot-journal by this +** or any other database connection. Exactly how a journal is finalized +** depends on whether or not the pager is running in exclusive mode and +** the current journal-mode (Pager.journalMode value), as follows: +** +** journalMode==MEMORY +** Journal file descriptor is simply closed. This destroys an +** in-memory journal. +** +** journalMode==TRUNCATE +** Journal file is truncated to zero bytes in size. +** +** journalMode==PERSIST +** The first 28 bytes of the journal file are zeroed. This invalidates +** the first journal header in the file, and hence the entire journal +** file. An invalid journal file cannot be rolled back. +** +** journalMode==DELETE +** The journal file is closed and deleted using sqlite3OsDelete(). +** +** If the pager is running in exclusive mode, this method of finalizing +** the journal file is never used. Instead, if the journalMode is +** DELETE and the pager is in exclusive mode, the method described under +** journalMode==PERSIST is used instead. +** +** After the journal is finalized, the pager moves to PAGER_READER state. +** If running in non-exclusive rollback mode, the lock on the file is +** downgraded to a SHARED_LOCK. +** +** SQLITE_OK is returned if no error occurs. If an error occurs during +** any of the IO operations to finalize the journal file or unlock the +** database then the IO error code is returned to the user. If the +** operation to finalize the journal file fails, then the code still +** tries to unlock the database file if not in exclusive mode. If the +** unlock operation fails as well, then the first error code related +** to the first error encountered (the journal finalization one) is +** returned. +*/ +static int pager_end_transaction(Pager *pPager, int hasSuper, int bCommit){ + int rc = SQLITE_OK; /* Error code from journal finalization operation */ + int rc2 = SQLITE_OK; /* Error code from db file unlock operation */ + + /* Do nothing if the pager does not have an open write transaction + ** or at least a RESERVED lock. This function may be called when there + ** is no write-transaction active but a RESERVED or greater lock is + ** held under two circumstances: + ** + ** 1. After a successful hot-journal rollback, it is called with + ** eState==PAGER_NONE and eLock==EXCLUSIVE_LOCK. + ** + ** 2. If a connection with locking_mode=exclusive holding an EXCLUSIVE + ** lock switches back to locking_mode=normal and then executes a + ** read-transaction, this function is called with eState==PAGER_READER + ** and eLock==EXCLUSIVE_LOCK when the read-transaction is closed. + */ + assert( assert_pager_state(pPager) ); + assert( pPager->eState!=PAGER_ERROR ); + if( pPager->eStateeLockjfd) || pPager->pInJournal==0 + || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_BATCH_ATOMIC) + ); + if( isOpen(pPager->jfd) ){ + assert( !pagerUseWal(pPager) ); + + /* Finalize the journal file. */ + if( sqlite3JournalIsInMemory(pPager->jfd) ){ + /* assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ); */ + sqlite3OsClose(pPager->jfd); + }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){ + if( pPager->journalOff==0 ){ + rc = SQLITE_OK; + }else{ + rc = sqlite3OsTruncate(pPager->jfd, 0); + if( rc==SQLITE_OK && pPager->fullSync ){ + /* Make sure the new file size is written into the inode right away. + ** Otherwise the journal might resurrect following a power loss and + ** cause the last transaction to roll back. See + ** https://bugzilla.mozilla.org/show_bug.cgi?id=1072773 + */ + rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags); + } + } + pPager->journalOff = 0; + }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST + || (pPager->exclusiveMode && pPager->journalModetempFile); + pPager->journalOff = 0; + }else{ + /* This branch may be executed with Pager.journalMode==MEMORY if + ** a hot-journal was just rolled back. In this case the journal + ** file should be closed and deleted. If this connection writes to + ** the database file, it will do so using an in-memory journal. + */ + int bDelete = !pPager->tempFile; + assert( sqlite3JournalIsInMemory(pPager->jfd)==0 ); + assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE + || pPager->journalMode==PAGER_JOURNALMODE_MEMORY + || pPager->journalMode==PAGER_JOURNALMODE_WAL + ); + sqlite3OsClose(pPager->jfd); + if( bDelete ){ + rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, pPager->extraSync); + } + } + } + +#ifdef SQLITE_CHECK_PAGES + sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash); + if( pPager->dbSize==0 && sqlite3PcacheRefCount(pPager->pPCache)>0 ){ + PgHdr *p = sqlite3PagerLookup(pPager, 1); + if( p ){ + p->pageHash = 0; + sqlite3PagerUnrefNotNull(p); + } + } +#endif + + sqlite3BitvecDestroy(pPager->pInJournal); + pPager->pInJournal = 0; + pPager->nRec = 0; + if( rc==SQLITE_OK ){ + if( MEMDB || pagerFlushOnCommit(pPager, bCommit) ){ + sqlite3PcacheCleanAll(pPager->pPCache); + }else{ + sqlite3PcacheClearWritable(pPager->pPCache); + } + sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize); + } + + if( pagerUseWal(pPager) ){ + /* Drop the WAL write-lock, if any. Also, if the connection was in + ** locking_mode=exclusive mode but is no longer, drop the EXCLUSIVE + ** lock held on the database file. + */ + rc2 = sqlite3WalEndWriteTransaction(pPager->pWal); + assert( rc2==SQLITE_OK ); + }else if( rc==SQLITE_OK && bCommit && pPager->dbFileSize>pPager->dbSize ){ + /* This branch is taken when committing a transaction in rollback-journal + ** mode if the database file on disk is larger than the database image. + ** At this point the journal has been finalized and the transaction + ** successfully committed, but the EXCLUSIVE lock is still held on the + ** file. So it is safe to truncate the database file to its minimum + ** required size. */ + assert( pPager->eLock==EXCLUSIVE_LOCK ); + rc = pager_truncate(pPager, pPager->dbSize); + } + + if( rc==SQLITE_OK && bCommit ){ + rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_COMMIT_PHASETWO, 0); + if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; + } + + if( !pPager->exclusiveMode + && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0)) + ){ + rc2 = pagerUnlockDb(pPager, SHARED_LOCK); + } + pPager->eState = PAGER_READER; + pPager->setSuper = 0; + + return (rc==SQLITE_OK?rc2:rc); +} + +/* Forward reference */ +static int pager_playback(Pager *pPager, int isHot); + +/* +** Execute a rollback if a transaction is active and unlock the +** database file. +** +** If the pager has already entered the ERROR state, do not attempt +** the rollback at this time. Instead, pager_unlock() is called. The +** call to pager_unlock() will discard all in-memory pages, unlock +** the database file and move the pager back to OPEN state. If this +** means that there is a hot-journal left in the file-system, the next +** connection to obtain a shared lock on the pager (which may be this one) +** will roll it back. +** +** If the pager has not already entered the ERROR state, but an IO or +** malloc error occurs during a rollback, then this will itself cause +** the pager to enter the ERROR state. Which will be cleared by the +** call to pager_unlock(), as described above. +*/ +static void pagerUnlockAndRollback(Pager *pPager){ + if( pPager->eState!=PAGER_ERROR && pPager->eState!=PAGER_OPEN ){ + assert( assert_pager_state(pPager) ); + if( pPager->eState>=PAGER_WRITER_LOCKED ){ + sqlite3BeginBenignMalloc(); + sqlite3PagerRollback(pPager); + sqlite3EndBenignMalloc(); + }else if( !pPager->exclusiveMode ){ + assert( pPager->eState==PAGER_READER ); + pager_end_transaction(pPager, 0, 0); + } + }else if( pPager->eState==PAGER_ERROR + && pPager->journalMode==PAGER_JOURNALMODE_MEMORY + && isOpen(pPager->jfd) + ){ + /* Special case for a ROLLBACK due to I/O error with an in-memory + ** journal: We have to rollback immediately, before the journal is + ** closed, because once it is closed, all content is forgotten. */ + int errCode = pPager->errCode; + u8 eLock = pPager->eLock; + pPager->eState = PAGER_OPEN; + pPager->errCode = SQLITE_OK; + pPager->eLock = EXCLUSIVE_LOCK; + pager_playback(pPager, 1); + pPager->errCode = errCode; + pPager->eLock = eLock; + } + pager_unlock(pPager); +} + +/* +** Parameter aData must point to a buffer of pPager->pageSize bytes +** of data. Compute and return a checksum based on the contents of the +** page of data and the current value of pPager->cksumInit. +** +** This is not a real checksum. It is really just the sum of the +** random initial value (pPager->cksumInit) and every 200th byte +** of the page data, starting with byte offset (pPager->pageSize%200). +** Each byte is interpreted as an 8-bit unsigned integer. +** +** Changing the formula used to compute this checksum results in an +** incompatible journal file format. +** +** If journal corruption occurs due to a power failure, the most likely +** scenario is that one end or the other of the record will be changed. +** It is much less likely that the two ends of the journal record will be +** correct and the middle be corrupt. Thus, this "checksum" scheme, +** though fast and simple, catches the mostly likely kind of corruption. +*/ +static u32 pager_cksum(Pager *pPager, const u8 *aData){ + u32 cksum = pPager->cksumInit; /* Checksum value to return */ + int i = pPager->pageSize-200; /* Loop counter */ + while( i>0 ){ + cksum += aData[i]; + i -= 200; + } + return cksum; +} + +/* +** Read a single page from either the journal file (if isMainJrnl==1) or +** from the sub-journal (if isMainJrnl==0) and playback that page. +** The page begins at offset *pOffset into the file. The *pOffset +** value is increased to the start of the next page in the journal. +** +** The main rollback journal uses checksums - the statement journal does +** not. +** +** If the page number of the page record read from the (sub-)journal file +** is greater than the current value of Pager.dbSize, then playback is +** skipped and SQLITE_OK is returned. +** +** If pDone is not NULL, then it is a record of pages that have already +** been played back. If the page at *pOffset has already been played back +** (if the corresponding pDone bit is set) then skip the playback. +** Make sure the pDone bit corresponding to the *pOffset page is set +** prior to returning. +** +** If the page record is successfully read from the (sub-)journal file +** and played back, then SQLITE_OK is returned. If an IO error occurs +** while reading the record from the (sub-)journal file or while writing +** to the database file, then the IO error code is returned. If data +** is successfully read from the (sub-)journal file but appears to be +** corrupted, SQLITE_DONE is returned. Data is considered corrupted in +** two circumstances: +** +** * If the record page-number is illegal (0 or PAGER_SJ_PGNO), or +** * If the record is being rolled back from the main journal file +** and the checksum field does not match the record content. +** +** Neither of these two scenarios are possible during a savepoint rollback. +** +** If this is a savepoint rollback, then memory may have to be dynamically +** allocated by this function. If this is the case and an allocation fails, +** SQLITE_NOMEM is returned. +*/ +static int pager_playback_one_page( + Pager *pPager, /* The pager being played back */ + i64 *pOffset, /* Offset of record to playback */ + Bitvec *pDone, /* Bitvec of pages already played back */ + int isMainJrnl, /* 1 -> main journal. 0 -> sub-journal. */ + int isSavepnt /* True for a savepoint rollback */ +){ + int rc; + PgHdr *pPg; /* An existing page in the cache */ + Pgno pgno; /* The page number of a page in journal */ + u32 cksum; /* Checksum used for sanity checking */ + char *aData; /* Temporary storage for the page */ + sqlite3_file *jfd; /* The file descriptor for the journal file */ + int isSynced; /* True if journal page is synced */ + + assert( (isMainJrnl&~1)==0 ); /* isMainJrnl is 0 or 1 */ + assert( (isSavepnt&~1)==0 ); /* isSavepnt is 0 or 1 */ + assert( isMainJrnl || pDone ); /* pDone always used on sub-journals */ + assert( isSavepnt || pDone==0 ); /* pDone never used on non-savepoint */ + + aData = pPager->pTmpSpace; + assert( aData ); /* Temp storage must have already been allocated */ + assert( pagerUseWal(pPager)==0 || (!isMainJrnl && isSavepnt) ); + + /* Either the state is greater than PAGER_WRITER_CACHEMOD (a transaction + ** or savepoint rollback done at the request of the caller) or this is + ** a hot-journal rollback. If it is a hot-journal rollback, the pager + ** is in state OPEN and holds an EXCLUSIVE lock. Hot-journal rollback + ** only reads from the main journal, not the sub-journal. + */ + assert( pPager->eState>=PAGER_WRITER_CACHEMOD + || (pPager->eState==PAGER_OPEN && pPager->eLock==EXCLUSIVE_LOCK) + ); + assert( pPager->eState>=PAGER_WRITER_CACHEMOD || isMainJrnl ); + + /* Read the page number and page data from the journal or sub-journal + ** file. Return an error code to the caller if an IO error occurs. + */ + jfd = isMainJrnl ? pPager->jfd : pPager->sjfd; + rc = read32bits(jfd, *pOffset, &pgno); + if( rc!=SQLITE_OK ) return rc; + rc = sqlite3OsRead(jfd, (u8*)aData, pPager->pageSize, (*pOffset)+4); + if( rc!=SQLITE_OK ) return rc; + *pOffset += pPager->pageSize + 4 + isMainJrnl*4; + + /* Sanity checking on the page. This is more important that I originally + ** thought. If a power failure occurs while the journal is being written, + ** it could cause invalid data to be written into the journal. We need to + ** detect this invalid data (with high probability) and ignore it. + */ + if( pgno==0 || pgno==PAGER_SJ_PGNO(pPager) ){ + assert( !isSavepnt ); + return SQLITE_DONE; + } + if( pgno>(Pgno)pPager->dbSize || sqlite3BitvecTest(pDone, pgno) ){ + return SQLITE_OK; + } + if( isMainJrnl ){ + rc = read32bits(jfd, (*pOffset)-4, &cksum); + if( rc ) return rc; + if( !isSavepnt && pager_cksum(pPager, (u8*)aData)!=cksum ){ + return SQLITE_DONE; + } + } + + /* If this page has already been played back before during the current + ** rollback, then don't bother to play it back again. + */ + if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){ + return rc; + } + + /* When playing back page 1, restore the nReserve setting + */ + if( pgno==1 && pPager->nReserve!=((u8*)aData)[20] ){ + pPager->nReserve = ((u8*)aData)[20]; + } + + /* If the pager is in CACHEMOD state, then there must be a copy of this + ** page in the pager cache. In this case just update the pager cache, + ** not the database file. The page is left marked dirty in this case. + ** + ** An exception to the above rule: If the database is in no-sync mode + ** and a page is moved during an incremental vacuum then the page may + ** not be in the pager cache. Later: if a malloc() or IO error occurs + ** during a Movepage() call, then the page may not be in the cache + ** either. So the condition described in the above paragraph is not + ** assert()able. + ** + ** If in WRITER_DBMOD, WRITER_FINISHED or OPEN state, then we update the + ** pager cache if it exists and the main file. The page is then marked + ** not dirty. Since this code is only executed in PAGER_OPEN state for + ** a hot-journal rollback, it is guaranteed that the page-cache is empty + ** if the pager is in OPEN state. + ** + ** Ticket #1171: The statement journal might contain page content that is + ** different from the page content at the start of the transaction. + ** This occurs when a page is changed prior to the start of a statement + ** then changed again within the statement. When rolling back such a + ** statement we must not write to the original database unless we know + ** for certain that original page contents are synced into the main rollback + ** journal. Otherwise, a power loss might leave modified data in the + ** database file without an entry in the rollback journal that can + ** restore the database to its original form. Two conditions must be + ** met before writing to the database files. (1) the database must be + ** locked. (2) we know that the original page content is fully synced + ** in the main journal either because the page is not in cache or else + ** the page is marked as needSync==0. + ** + ** 2008-04-14: When attempting to vacuum a corrupt database file, it + ** is possible to fail a statement on a database that does not yet exist. + ** Do not attempt to write if database file has never been opened. + */ + if( pagerUseWal(pPager) ){ + pPg = 0; + }else{ + pPg = sqlite3PagerLookup(pPager, pgno); + } + assert( pPg || !MEMDB ); + assert( pPager->eState!=PAGER_OPEN || pPg==0 || pPager->tempFile ); + PAGERTRACE(("PLAYBACK %d page %d hash(%08x) %s\n", + PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, (u8*)aData), + (isMainJrnl?"main-journal":"sub-journal") + )); + if( isMainJrnl ){ + isSynced = pPager->noSync || (*pOffset <= pPager->journalHdr); + }else{ + isSynced = (pPg==0 || 0==(pPg->flags & PGHDR_NEED_SYNC)); + } + if( isOpen(pPager->fd) + && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) + && isSynced + ){ + i64 ofst = (pgno-1)*(i64)pPager->pageSize; + testcase( !isSavepnt && pPg!=0 && (pPg->flags&PGHDR_NEED_SYNC)!=0 ); + assert( !pagerUseWal(pPager) ); + + /* Write the data read from the journal back into the database file. + ** This is usually safe even for an encrypted database - as the data + ** was encrypted before it was written to the journal file. The exception + ** is if the data was just read from an in-memory sub-journal. In that + ** case it must be encrypted here before it is copied into the database + ** file. */ + rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst); + + if( pgno>pPager->dbFileSize ){ + pPager->dbFileSize = pgno; + } + if( pPager->pBackup ){ + sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData); + } + }else if( !isMainJrnl && pPg==0 ){ + /* If this is a rollback of a savepoint and data was not written to + ** the database and the page is not in-memory, there is a potential + ** problem. When the page is next fetched by the b-tree layer, it + ** will be read from the database file, which may or may not be + ** current. + ** + ** There are a couple of different ways this can happen. All are quite + ** obscure. When running in synchronous mode, this can only happen + ** if the page is on the free-list at the start of the transaction, then + ** populated, then moved using sqlite3PagerMovepage(). + ** + ** The solution is to add an in-memory page to the cache containing + ** the data just read from the sub-journal. Mark the page as dirty + ** and if the pager requires a journal-sync, then mark the page as + ** requiring a journal-sync before it is written. + */ + assert( isSavepnt ); + assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)==0 ); + pPager->doNotSpill |= SPILLFLAG_ROLLBACK; + rc = sqlite3PagerGet(pPager, pgno, &pPg, 1); + assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)!=0 ); + pPager->doNotSpill &= ~SPILLFLAG_ROLLBACK; + if( rc!=SQLITE_OK ) return rc; + sqlite3PcacheMakeDirty(pPg); + } + if( pPg ){ + /* No page should ever be explicitly rolled back that is in use, except + ** for page 1 which is held in use in order to keep the lock on the + ** database active. However such a page may be rolled back as a result + ** of an internal error resulting in an automatic call to + ** sqlite3PagerRollback(). + */ + void *pData; + pData = pPg->pData; + memcpy(pData, (u8*)aData, pPager->pageSize); + pPager->xReiniter(pPg); + /* It used to be that sqlite3PcacheMakeClean(pPg) was called here. But + ** that call was dangerous and had no detectable benefit since the cache + ** is normally cleaned by sqlite3PcacheCleanAll() after rollback and so + ** has been removed. */ + pager_set_pagehash(pPg); + + /* If this was page 1, then restore the value of Pager.dbFileVers. + ** Do this before any decoding. */ + if( pgno==1 ){ + memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers)); + } + sqlite3PcacheRelease(pPg); + } + return rc; +} + +/* +** Check if zSuper is a valid super-journal name. There are two valid +** formats: +** +** + The 3rd and 4th last bytes of the filename are ".9", and the +** following 2 bytes are hex digits. This is a file created in 8.3 +** filenames mode. +** +** + The 3rd last byte of the filename is "9" and the filename +** contains the string "-mj" starting at the 12th last byte. +** All bytes following the "-mj" are hex digits. +** +** If the filename matches either of these patterns, return non-zero. +** Otherwise, return zero. +*/ +static int pagerIsSuperJrnlName(const char *zSuper){ + const int nSuper = sqlite3Strlen30(zSuper); + int ii; + + if( nSuper<4 ) return 0; + if( zSuper[nSuper-3]!='9' ) return 0; +#ifdef SQLITE_ENABLE_8_3_NAMES + if( sqlite3Isxdigit(zSuper[nSuper-2])==0 ) return 0; + if( sqlite3Isxdigit(zSuper[nSuper-1])==0 ) return 0; + if( zSuper[nSuper-4]=='.' ) return 1; +#endif + if( nSuper<12 ) return 0; + if( memcmp(&zSuper[nSuper-12], "-mj", 3) ) return 0; + for(ii=nSuper-9; iipVfs; + int rc; /* Return code */ + sqlite3_file *pSuper; /* Malloc'd super-journal file descriptor */ + sqlite3_file *pJournal; /* Malloc'd child-journal file descriptor */ + char *zSuperJournal = 0; /* Contents of super-journal file */ + i64 nSuperJournal; /* Size of super-journal file */ + char *zJournal; /* Pointer to one journal within MJ file */ + char *zFree = 0; /* Free this buffer */ + int bSeen = 0; /* If super-journal contains pPager->zJournal */ + + /* Check if this looks like a real super-journal name. If it does not, + ** return SQLITE_OK without attempting to delete it. This is to limit + ** the degree to which a crafted journal file can be used to cause + ** SQLite to delete arbitrary files. */ + if( pagerIsSuperJrnlName(zSuper)==0 ){ + return SQLITE_OK; + } + + /* Allocate space for both the pJournal and pSuper file descriptors. + ** If successful, open the super-journal file for reading. + */ + pSuper = (sqlite3_file *)sqlite3MallocZero(2 * (i64)pVfs->szOsFile); + if( !pSuper ){ + rc = SQLITE_NOMEM_BKPT; + pJournal = 0; + }else{ + const int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_SUPER_JOURNAL); + rc = sqlite3OsOpen(pVfs, zSuper, pSuper, flags, 0); + pJournal = (sqlite3_file *)(((u8 *)pSuper) + pVfs->szOsFile); + } + if( rc!=SQLITE_OK ) goto delsuper_out; + + /* Load the entire super-journal file into space obtained from + ** sqlite3_malloc() and pointed to by zSuperJournal. Also obtain + ** sufficient space (in zSuperPtr) to hold the names of super-journal + ** files extracted from regular rollback-journals. + */ + rc = sqlite3OsFileSize(pSuper, &nSuperJournal); + if( rc!=SQLITE_OK ) goto delsuper_out; + assert( nSuperJournal>=0 ); + zFree = sqlite3Malloc(4 + nSuperJournal + 2); + if( !zFree ){ + rc = SQLITE_NOMEM_BKPT; + goto delsuper_out; + }else{ + assert( nSuperJournal<=0x7fffffff ); + } + zFree[0] = zFree[1] = zFree[2] = zFree[3] = 0; + zSuperJournal = &zFree[4]; + rc = sqlite3OsRead(pSuper, zSuperJournal, (int)nSuperJournal, 0); + if( rc!=SQLITE_OK ) goto delsuper_out; + zSuperJournal[nSuperJournal] = 0; + zSuperJournal[nSuperJournal+1] = 0; + + zJournal = zSuperJournal; + while( (zJournal-zSuperJournal)zJournal)==0 ){ + bSeen = 1; + }else{ + int exists; + rc = sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS, &exists); + if( rc!=SQLITE_OK ){ + goto delsuper_out; + } + if( exists ){ + char *zSuperPtr = 0; + + /* One of the journals pointed to by the super-journal exists. + ** Open it and check if it points at the super-journal. If + ** so, return without deleting the super-journal file. + ** NB: zJournal is really a MAIN_JOURNAL. But call it a + ** SUPER_JOURNAL here so that the VFS will not send the zJournal + ** name into sqlite3_database_file_object(). + */ + int c; + int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_SUPER_JOURNAL); + rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0); + if( rc!=SQLITE_OK ){ + goto delsuper_out; + } + + rc = readSuperJournal(pJournal, 1+(u64)pVfs->mxPathname, &zSuperPtr); + sqlite3OsClose(pJournal); + if( rc!=SQLITE_OK ){ + assert( zSuperPtr==0 ); + goto delsuper_out; + } + + c = zSuperPtr!=0 && strcmp(zSuperPtr, zSuper)==0; + freeSuperJournal(zSuperPtr); + if( c ){ + /* We have a match. Do not delete the super-journal file. */ + goto delsuper_out; + } + } + } + zJournal += (sqlite3Strlen30(zJournal)+1); + } + + sqlite3OsClose(pSuper); + if( bSeen ){ + /* Only delete the super-journal if bSeen is true - indicating that + ** the super-journal contained a pointer to this database's journal + ** file. */ + rc = sqlite3OsDelete(pVfs, zSuper, 0); + } + +delsuper_out: + sqlite3_free(zFree); + if( pSuper ){ + sqlite3OsClose(pSuper); + assert( !isOpen(pJournal) ); + sqlite3_free(pSuper); + } + return rc; +} + + +/* +** This function is used to change the actual size of the database +** file in the file-system. This only happens when committing a transaction, +** or rolling back a transaction (including rolling back a hot-journal). +** +** If the main database file is not open, or the pager is not in either +** DBMOD or OPEN state, this function is a no-op. Otherwise, the size +** of the file is changed to nPage pages (nPage*pPager->pageSize bytes). +** If the file on disk is currently larger than nPage pages, then use the VFS +** xTruncate() method to truncate it. +** +** Or, it might be the case that the file on disk is smaller than +** nPage pages. Some operating system implementations can get confused if +** you try to truncate a file to some size that is larger than it +** currently is, so detect this case and write a single zero byte to +** the end of the new file instead. +** +** If successful, return SQLITE_OK. If an IO error occurs while modifying +** the database file, return the error code to the caller. +*/ +static int pager_truncate(Pager *pPager, Pgno nPage){ + int rc = SQLITE_OK; + assert( pPager->eState!=PAGER_ERROR ); + assert( pPager->eState!=PAGER_READER ); + PAGERTRACE(("Truncate %d npage %u\n", PAGERID(pPager), nPage)); + + + if( isOpen(pPager->fd) + && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) + ){ + i64 currentSize, newSize; + int szPage = pPager->pageSize; + assert( pPager->eLock==EXCLUSIVE_LOCK ); + /* TODO: Is it safe to use Pager.dbFileSize here? */ + rc = sqlite3OsFileSize(pPager->fd, ¤tSize); + newSize = szPage*(i64)nPage; + if( rc==SQLITE_OK && currentSize!=newSize ){ + if( currentSize>newSize ){ + rc = sqlite3OsTruncate(pPager->fd, newSize); + }else if( (currentSize+szPage)<=newSize ){ + char *pTmp = pPager->pTmpSpace; + memset(pTmp, 0, szPage); + testcase( (newSize-szPage) == currentSize ); + testcase( (newSize-szPage) > currentSize ); + sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &newSize); + rc = sqlite3OsWrite(pPager->fd, pTmp, szPage, newSize-szPage); + } + if( rc==SQLITE_OK ){ + pPager->dbFileSize = nPage; + } + } + } + return rc; +} + +/* +** Return a sanitized version of the sector-size of OS file pFile. The +** return value is guaranteed to lie between 32 and MAX_SECTOR_SIZE. +*/ +SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *pFile){ + int iRet = sqlite3OsSectorSize(pFile); + if( iRet<32 ){ + iRet = 512; + }else if( iRet>MAX_SECTOR_SIZE ){ + assert( MAX_SECTOR_SIZE>=512 ); + iRet = MAX_SECTOR_SIZE; + } + return iRet; +} + +/* +** Set the value of the Pager.sectorSize variable for the given +** pager based on the value returned by the xSectorSize method +** of the open database file. The sector size will be used +** to determine the size and alignment of journal header and +** super-journal pointers within created journal files. +** +** For temporary files the effective sector size is always 512 bytes. +** +** Otherwise, for non-temporary files, the effective sector size is +** the value returned by the xSectorSize() method rounded up to 32 if +** it is less than 32, or rounded down to MAX_SECTOR_SIZE if it +** is greater than MAX_SECTOR_SIZE. +** +** If the file has the SQLITE_IOCAP_POWERSAFE_OVERWRITE property, then set +** the effective sector size to its minimum value (512). The purpose of +** pPager->sectorSize is to define the "blast radius" of bytes that +** might change if a crash occurs while writing to a single byte in +** that range. But with POWERSAFE_OVERWRITE, the blast radius is zero +** (that is what POWERSAFE_OVERWRITE means), so we minimize the sector +** size. For backwards compatibility of the rollback journal file format, +** we cannot reduce the effective sector size below 512. +*/ +static void setSectorSize(Pager *pPager){ + assert( isOpen(pPager->fd) || pPager->tempFile ); + + if( pPager->tempFile + || (sqlite3OsDeviceCharacteristics(pPager->fd) & + SQLITE_IOCAP_POWERSAFE_OVERWRITE)!=0 + ){ + /* Sector size doesn't matter for temporary files. Also, the file + ** may not have been opened yet, in which case the OsSectorSize() + ** call will segfault. */ + pPager->sectorSize = 512; + }else{ + pPager->sectorSize = sqlite3SectorSize(pPager->fd); + } +} + +/* +** Playback the journal and thus restore the database file to +** the state it was in before we started making changes. +** +** The journal file format is as follows: +** +** (1) 8 byte prefix. A copy of aJournalMagic[]. +** (2) 4 byte big-endian integer which is the number of valid page records +** in the journal. If this value is 0xffffffff, then compute the +** number of page records from the journal size. +** (3) 4 byte big-endian integer which is the initial value for the +** sanity checksum. +** (4) 4 byte integer which is the number of pages to truncate the +** database to during a rollback. +** (5) 4 byte big-endian integer which is the sector size. The header +** is this many bytes in size. +** (6) 4 byte big-endian integer which is the page size. +** (7) zero padding out to the next sector size. +** (8) Zero or more pages instances, each as follows: +** + 4 byte page number. +** + pPager->pageSize bytes of data. +** + 4 byte checksum +** +** When we speak of the journal header, we mean the first 7 items above. +** Each entry in the journal is an instance of the 8th item. +** +** Call the value from the second bullet "nRec". nRec is the number of +** valid page entries in the journal. In most cases, you can compute the +** value of nRec from the size of the journal file. But if a power +** failure occurred while the journal was being written, it could be the +** case that the size of the journal file had already been increased but +** the extra entries had not yet made it safely to disk. In such a case, +** the value of nRec computed from the file size would be too large. For +** that reason, we always use the nRec value in the header. +** +** If the nRec value is 0xffffffff it means that nRec should be computed +** from the file size. This value is used when the user selects the +** no-sync option for the journal. A power failure could lead to corruption +** in this case. But for things like temporary table (which will be +** deleted when the power is restored) we don't care. +** +** If the file opened as the journal file is not a well-formed +** journal file then all pages up to the first corrupted page are rolled +** back (or no pages if the journal header is corrupted). The journal file +** is then deleted and SQLITE_OK returned, just as if no corruption had +** been encountered. +** +** If an I/O or malloc() error occurs, the journal-file is not deleted +** and an error code is returned. +** +** The isHot parameter indicates that we are trying to rollback a journal +** that might be a hot journal. Or, it could be that the journal is +** preserved because of JOURNALMODE_PERSIST or JOURNALMODE_TRUNCATE. +** If the journal really is hot, reset the pager cache prior rolling +** back any content. If the journal is merely persistent, no reset is +** needed. +*/ +static int pager_playback(Pager *pPager, int isHot){ + sqlite3_vfs *pVfs = pPager->pVfs; + i64 szJ; /* Size of the journal file in bytes */ + u32 nRec; /* Number of Records in the journal */ + u32 u; /* Unsigned loop counter */ + Pgno mxPg = 0; /* Size of the original file in pages */ + int rc; /* Result code of a subroutine */ + int res = 1; /* Value returned by sqlite3OsAccess() */ + char *zSuper = 0; /* Name of super-journal file if any */ + int needPagerReset; /* True to reset page prior to first page rollback */ + int nPlayback = 0; /* Total number of pages restored from journal */ + u32 savedPageSize = pPager->pageSize; + + /* Figure out how many records are in the journal. Abort early if + ** the journal is empty. + */ + assert( isOpen(pPager->jfd) ); + rc = sqlite3OsFileSize(pPager->jfd, &szJ); + if( rc!=SQLITE_OK ){ + goto end_playback; + } + + /* Read the super-journal name from the journal, if it is present. + ** If a super-journal file name is specified, but the file is not + ** present on disk, then the journal is not hot and does not need to be + ** played back. + */ + rc = readSuperJournal(pPager->jfd, 1+(i64)pPager->pVfs->mxPathname, &zSuper); + if( rc==SQLITE_OK && zSuper ){ + rc = sqlite3OsAccess(pVfs, zSuper, SQLITE_ACCESS_EXISTS, &res); + } + if( rc!=SQLITE_OK || !res ){ + goto end_playback; + } + pPager->journalOff = 0; + needPagerReset = isHot; + + /* This loop terminates either when a readJournalHdr() or + ** pager_playback_one_page() call returns SQLITE_DONE or an IO error + ** occurs. + */ + while( 1 ){ + /* Read the next journal header from the journal file. If there are + ** not enough bytes left in the journal file for a complete header, or + ** it is corrupted, then a process must have failed while writing it. + ** This indicates nothing more needs to be rolled back. + */ + rc = readJournalHdr(pPager, isHot, szJ, &nRec, &mxPg); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_DONE ){ + rc = SQLITE_OK; + } + goto end_playback; + } + + /* If nRec is 0xffffffff, then this journal was created by a process + ** working in no-sync mode. This means that the rest of the journal + ** file consists of pages, there are no more journal headers. Compute + ** the value of nRec based on this assumption. + */ + if( nRec==0xffffffff ){ + assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ); + nRec = (int)((szJ - JOURNAL_HDR_SZ(pPager))/JOURNAL_PG_SZ(pPager)); + } + + /* If nRec is 0 and this rollback is of a transaction created by this + ** process and if this is the final header in the journal, then it means + ** that this part of the journal was being filled but has not yet been + ** synced to disk. Compute the number of pages based on the remaining + ** size of the file. + ** + ** The third term of the test was added to fix ticket #2565. + ** When rolling back a hot journal, nRec==0 always means that the next + ** chunk of the journal contains zero pages to be rolled back. But + ** when doing a ROLLBACK and the nRec==0 chunk is the last chunk in + ** the journal, it means that the journal might contain additional + ** pages that need to be rolled back and that the number of pages + ** should be computed based on the journal file size. + */ + if( nRec==0 && !isHot && + pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff ){ + nRec = (int)((szJ - pPager->journalOff) / JOURNAL_PG_SZ(pPager)); + } + + /* If this is the first header read from the journal, truncate the + ** database file back to its original size. + */ + if( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){ + rc = pager_truncate(pPager, mxPg); + if( rc!=SQLITE_OK ){ + goto end_playback; + } + pPager->dbSize = mxPg; + if( pPager->mxPgnomxPgno = mxPg; + } + } + + /* Copy original pages out of the journal and back into the + ** database file and/or page cache. + */ + for(u=0; ujournalOff,0,1,0); + if( rc==SQLITE_OK ){ + nPlayback++; + }else{ + if( rc==SQLITE_DONE ){ + pPager->journalOff = szJ; + break; + }else if( rc==SQLITE_IOERR_SHORT_READ ){ + /* If the journal has been truncated, simply stop reading and + ** processing the journal. This might happen if the journal was + ** not completely written and synced prior to a crash. In that + ** case, the database should have never been written in the + ** first place so it is OK to simply abandon the rollback. */ + rc = SQLITE_OK; + goto end_playback; + }else{ + /* If we are unable to rollback, quit and return the error + ** code. This will cause the pager to enter the error state + ** so that no further harm will be done. Perhaps the next + ** process to come along will be able to rollback the database. + */ + goto end_playback; + } + } + } + } + /*NOTREACHED*/ + assert( 0 ); + +end_playback: + if( rc==SQLITE_OK ){ + rc = sqlite3PagerSetPagesize(pPager, &savedPageSize, -1); + } + /* Following a rollback, the database file should be back in its original + ** state prior to the start of the transaction, so invoke the + ** SQLITE_FCNTL_DB_UNCHANGED file-control method to disable the + ** assertion that the transaction counter was modified. + */ +#ifdef SQLITE_DEBUG + sqlite3OsFileControlHint(pPager->fd,SQLITE_FCNTL_DB_UNCHANGED,0); +#endif + + /* If this playback is happening automatically as a result of an IO or + ** malloc error that occurred after the change-counter was updated but + ** before the transaction was committed, then the change-counter + ** modification may just have been reverted. If this happens in exclusive + ** mode, then subsequent transactions performed by the connection will not + ** update the change-counter at all. This may lead to cache inconsistency + ** problems for other processes at some point in the future. So, just + ** in case this has happened, clear the changeCountDone flag now. + */ + pPager->changeCountDone = pPager->tempFile; + + if( rc==SQLITE_OK + && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) + ){ + rc = sqlite3PagerSync(pPager, 0); + } + if( rc==SQLITE_OK ){ + rc = pager_end_transaction(pPager, zSuper!=0, 0); + testcase( rc!=SQLITE_OK ); + } + if( rc==SQLITE_OK && zSuper && res ){ + /* If there was a super-journal and this routine will return success, + ** see if it is possible to delete the super-journal. + */ + assert( memcmp(&zSuper[-4], "\0\0\0\0", 4)==0 ); + rc = pager_delsuper(pPager, zSuper); + testcase( rc!=SQLITE_OK ); + } + if( isHot && nPlayback ){ + sqlite3_log(SQLITE_NOTICE_RECOVER_ROLLBACK, "recovered %d pages from %s", + nPlayback, pPager->zJournal); + } + + /* The Pager.sectorSize variable may have been updated while rolling + ** back a journal created by a process with a different sector size + ** value. Reset it to the correct value for this process. + */ + freeSuperJournal(zSuper); + setSectorSize(pPager); + return rc; +} + + +/* +** Read the content for page pPg out of the database file (or out of +** the WAL if that is where the most recent copy if found) into +** pPg->pData. A shared lock or greater must be held on the database +** file before this function is called. +** +** If page 1 is read, then the value of Pager.dbFileVers[] is set to +** the value read from the database file. +** +** If an IO error occurs, then the IO error is returned to the caller. +** Otherwise, SQLITE_OK is returned. +*/ +static int readDbPage(PgHdr *pPg){ + Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */ + int rc = SQLITE_OK; /* Return code */ + +#ifndef SQLITE_OMIT_WAL + u32 iFrame = 0; /* Frame of WAL containing pgno */ + + assert( pPager->eState>=PAGER_READER && !MEMDB ); + assert( isOpen(pPager->fd) ); + + if( pagerUseWal(pPager) ){ + rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame); + if( rc ) return rc; + } + if( iFrame ){ + rc = sqlite3WalReadFrame(pPager->pWal, iFrame,pPager->pageSize,pPg->pData); + }else +#endif + { + i64 iOffset = (pPg->pgno-1)*(i64)pPager->pageSize; + rc = sqlite3OsRead(pPager->fd, pPg->pData, pPager->pageSize, iOffset); + if( rc==SQLITE_IOERR_SHORT_READ ){ + rc = SQLITE_OK; + } + } + + if( pPg->pgno==1 ){ + if( rc ){ + /* If the read is unsuccessful, set the dbFileVers[] to something + ** that will never be a valid file version. dbFileVers[] is a copy + ** of bytes 24..39 of the database. Bytes 28..31 should always be + ** zero or the size of the database in page. Bytes 32..35 and 35..39 + ** should be page numbers which are never 0xffffffff. So filling + ** pPager->dbFileVers[] with all 0xff bytes should suffice. + ** + ** For an encrypted database, the situation is more complex: bytes + ** 24..39 of the database are white noise. But the probability of + ** white noise equaling 16 bytes of 0xff is vanishingly small so + ** we should still be ok. + */ + memset(pPager->dbFileVers, 0xff, sizeof(pPager->dbFileVers)); + }else{ + u8 *dbFileVers = &((u8*)pPg->pData)[24]; + memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers)); + } + } + PAGER_INCR(sqlite3_pager_readdb_count); + PAGER_INCR(pPager->nRead); + IOTRACE(("PGIN %p %d\n", pPager, pPg->pgno)); + PAGERTRACE(("FETCH %d page %d hash(%08x)\n", + PAGERID(pPager), pPg->pgno, pager_pagehash(pPg))); + + return rc; +} + +/* +** Update the value of the change-counter at offsets 24 and 92 in +** the header and the sqlite version number at offset 96. +** +** This is an unconditional update. See also the pager_incr_changecounter() +** routine which only updates the change-counter if the update is actually +** needed, as determined by the pPager->changeCountDone state variable. +*/ +static void pager_write_changecounter(PgHdr *pPg){ + u32 change_counter; + if( NEVER(pPg==0) ) return; + + /* Increment the value just read and write it back to byte 24. */ + change_counter = sqlite3Get4byte((u8*)pPg->pPager->dbFileVers)+1; + put32bits(((char*)pPg->pData)+24, change_counter); + + /* Also store the SQLite version number in bytes 96..99 and in + ** bytes 92..95 store the change counter for which the version number + ** is valid. */ + put32bits(((char*)pPg->pData)+92, change_counter); + put32bits(((char*)pPg->pData)+96, SQLITE_VERSION_NUMBER); +} + +#ifndef SQLITE_OMIT_WAL +/* +** This function is invoked once for each page that has already been +** written into the log file when a WAL transaction is rolled back. +** Parameter iPg is the page number of said page. The pCtx argument +** is actually a pointer to the Pager structure. +** +** If page iPg is present in the cache, and has no outstanding references, +** it is discarded. Otherwise, if there are one or more outstanding +** references, the page content is reloaded from the database. If the +** attempt to reload content from the database is required and fails, +** return an SQLite error code. Otherwise, SQLITE_OK. +*/ +static int pagerUndoCallback(void *pCtx, Pgno iPg){ + int rc = SQLITE_OK; + Pager *pPager = (Pager *)pCtx; + PgHdr *pPg; + + assert( pagerUseWal(pPager) ); + pPg = sqlite3PagerLookup(pPager, iPg); + if( pPg ){ + if( sqlite3PcachePageRefcount(pPg)==1 ){ + sqlite3PcacheDrop(pPg); + }else{ + rc = readDbPage(pPg); + if( rc==SQLITE_OK ){ + pPager->xReiniter(pPg); + } + sqlite3PagerUnrefNotNull(pPg); + } + } + + /* Normally, if a transaction is rolled back, any backup processes are + ** updated as data is copied out of the rollback journal and into the + ** database. This is not generally possible with a WAL database, as + ** rollback involves simply truncating the log file. Therefore, if one + ** or more frames have already been written to the log (and therefore + ** also copied into the backup databases) as part of this transaction, + ** the backups must be restarted. + */ + sqlite3BackupRestart(pPager->pBackup); + + return rc; +} + +/* +** This function is called to rollback a transaction on a WAL database. +*/ +static int pagerRollbackWal(Pager *pPager){ + int rc; /* Return Code */ + PgHdr *pList; /* List of dirty pages to revert */ + + /* For all pages in the cache that are currently dirty or have already + ** been written (but not committed) to the log file, do one of the + ** following: + ** + ** + Discard the cached page (if refcount==0), or + ** + Reload page content from the database (if refcount>0). + */ + pPager->dbSize = pPager->dbOrigSize; + rc = sqlite3WalUndo(pPager->pWal, pagerUndoCallback, (void *)pPager); + pList = sqlite3PcacheDirtyList(pPager->pPCache); + while( pList && rc==SQLITE_OK ){ + PgHdr *pNext = pList->pDirty; + rc = pagerUndoCallback((void *)pPager, pList->pgno); + pList = pNext; + } + + return rc; +} + +/* +** This function is a wrapper around sqlite3WalFrames(). As well as logging +** the contents of the list of pages headed by pList (connected by pDirty), +** this function notifies any active backup processes that the pages have +** changed. +** +** The list of pages passed into this routine is always sorted by page number. +** Hence, if page 1 appears anywhere on the list, it will be the first page. +*/ +static int pagerWalFrames( + Pager *pPager, /* Pager object */ + PgHdr *pList, /* List of frames to log */ + Pgno nTruncate, /* Database size after this commit */ + int isCommit /* True if this is a commit */ +){ + int rc; /* Return code */ + int nList; /* Number of pages in pList */ + PgHdr *p; /* For looping over pages */ + + assert( pPager->pWal ); + assert( pList ); +#ifdef SQLITE_DEBUG + /* Verify that the page list is in ascending order */ + for(p=pList; p && p->pDirty; p=p->pDirty){ + assert( p->pgno < p->pDirty->pgno ); + } +#endif + + assert( pList->pDirty==0 || isCommit ); + if( isCommit ){ + /* If a WAL transaction is being committed, there is no point in writing + ** any pages with page numbers greater than nTruncate into the WAL file. + ** They will never be read by any client. So remove them from the pDirty + ** list here. */ + PgHdr **ppNext = &pList; + nList = 0; + for(p=pList; (*ppNext = p)!=0; p=p->pDirty){ + if( p->pgno<=nTruncate ){ + ppNext = &p->pDirty; + nList++; + } + } + assert( pList ); + }else{ + nList = 1; + } + pPager->aStat[PAGER_STAT_WRITE] += nList; + + if( pList->pgno==1 ) pager_write_changecounter(pList); + rc = sqlite3WalFrames(pPager->pWal, + pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags + ); + if( rc==SQLITE_OK && pPager->pBackup ){ + for(p=pList; p; p=p->pDirty){ + sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData); + } + } + +#ifdef SQLITE_CHECK_PAGES + pList = sqlite3PcacheDirtyList(pPager->pPCache); + for(p=pList; p; p=p->pDirty){ + pager_set_pagehash(p); + } +#endif + + return rc; +} + +/* +** Begin a read transaction on the WAL. +** +** This routine used to be called "pagerOpenSnapshot()" because it essentially +** makes a snapshot of the database at the current point in time and preserves +** that snapshot for use by the reader in spite of concurrently changes by +** other writers or checkpointers. +*/ +static int pagerBeginReadTransaction(Pager *pPager){ + int rc; /* Return code */ + int changed = 0; /* True if cache must be reset */ + + assert( pagerUseWal(pPager) ); + assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER ); + + /* sqlite3WalEndReadTransaction() was not called for the previous + ** transaction in locking_mode=EXCLUSIVE. So call it now. If we + ** are in locking_mode=NORMAL and EndRead() was previously called, + ** the duplicate call is harmless. + */ + sqlite3WalEndReadTransaction(pPager->pWal); + + rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed); + if( rc!=SQLITE_OK || changed ){ + pager_reset(pPager); + if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0); + } + + return rc; +} +#endif + +/* +** This function is called as part of the transition from PAGER_OPEN +** to PAGER_READER state to determine the size of the database file +** in pages (assuming the page size currently stored in Pager.pageSize). +** +** If no error occurs, SQLITE_OK is returned and the size of the database +** in pages is stored in *pnPage. Otherwise, an error code (perhaps +** SQLITE_IOERR_FSTAT) is returned and *pnPage is left unmodified. +*/ +static int pagerPagecount(Pager *pPager, Pgno *pnPage){ + Pgno nPage; /* Value to return via *pnPage */ + + /* Query the WAL sub-system for the database size. The WalDbsize() + ** function returns zero if the WAL is not open (i.e. Pager.pWal==0), or + ** if the database size is not available. The database size is not + ** available from the WAL sub-system if the log file is empty or + ** contains no valid committed transactions. + */ + assert( pPager->eState==PAGER_OPEN ); + assert( pPager->eLock>=SHARED_LOCK ); + assert( isOpen(pPager->fd) ); + assert( pPager->tempFile==0 ); + nPage = sqlite3WalDbsize(pPager->pWal); + + /* If the number of pages in the database is not available from the + ** WAL sub-system, determine the page count based on the size of + ** the database file. If the size of the database file is not an + ** integer multiple of the page-size, round up the result. + */ + if( nPage==0 && ALWAYS(isOpen(pPager->fd)) ){ + i64 n = 0; /* Size of db file in bytes */ + int rc = sqlite3OsFileSize(pPager->fd, &n); + if( rc!=SQLITE_OK ){ + return rc; + } + nPage = (Pgno)((n+pPager->pageSize-1) / pPager->pageSize); + } + + /* If the current number of pages in the file is greater than the + ** configured maximum pager number, increase the allowed limit so + ** that the file can be read. + */ + if( nPage>pPager->mxPgno ){ + pPager->mxPgno = (Pgno)nPage; + } + + *pnPage = nPage; + return SQLITE_OK; +} + +#ifndef SQLITE_OMIT_WAL +/* +** Check if the *-wal file that corresponds to the database opened by pPager +** exists if the database is not empty, or verify that the *-wal file does +** not exist (by deleting it) if the database file is empty. +** +** If the database is not empty and the *-wal file exists, open the pager +** in WAL mode. If the database is empty or if no *-wal file exists and +** if no error occurs, make sure Pager.journalMode is not set to +** PAGER_JOURNALMODE_WAL. +** +** Return SQLITE_OK or an error code. +** +** The caller must hold a SHARED lock on the database file to call this +** function. Because an EXCLUSIVE lock on the db file is required to delete +** a WAL on a none-empty database, this ensures there is no race condition +** between the xAccess() below and an xDelete() being executed by some +** other connection. +*/ +static int pagerOpenWalIfPresent(Pager *pPager){ + int rc = SQLITE_OK; + assert( pPager->eState==PAGER_OPEN ); + assert( pPager->eLock>=SHARED_LOCK ); + + if( !pPager->tempFile ){ + int isWal; /* True if WAL file exists */ + rc = sqlite3OsAccess( + pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal + ); + if( rc==SQLITE_OK ){ + if( isWal ){ + Pgno nPage; /* Size of the database file */ + + rc = pagerPagecount(pPager, &nPage); + if( rc ) return rc; + if( nPage==0 ){ + rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0); + }else{ + testcase( sqlite3PcachePagecount(pPager->pPCache)==0 ); + rc = sqlite3PagerOpenWal(pPager, 0); + } + }else if( pPager->journalMode==PAGER_JOURNALMODE_WAL ){ + pPager->journalMode = PAGER_JOURNALMODE_DELETE; + } + } + } + return rc; +} +#endif + +/* +** Playback savepoint pSavepoint. Or, if pSavepoint==NULL, then playback +** the entire super-journal file. The case pSavepoint==NULL occurs when +** a ROLLBACK TO command is invoked on a SAVEPOINT that is a transaction +** savepoint. +** +** When pSavepoint is not NULL (meaning a non-transaction savepoint is +** being rolled back), then the rollback consists of up to three stages, +** performed in the order specified: +** +** * Pages are played back from the main journal starting at byte +** offset PagerSavepoint.iOffset and continuing to +** PagerSavepoint.iHdrOffset, or to the end of the main journal +** file if PagerSavepoint.iHdrOffset is zero. +** +** * If PagerSavepoint.iHdrOffset is not zero, then pages are played +** back starting from the journal header immediately following +** PagerSavepoint.iHdrOffset to the end of the main journal file. +** +** * Pages are then played back from the sub-journal file, starting +** with the PagerSavepoint.iSubRec and continuing to the end of +** the journal file. +** +** Throughout the rollback process, each time a page is rolled back, the +** corresponding bit is set in a bitvec structure (variable pDone in the +** implementation below). This is used to ensure that a page is only +** rolled back the first time it is encountered in either journal. +** +** If pSavepoint is NULL, then pages are only played back from the main +** journal file. There is no need for a bitvec in this case. +** +** In either case, before playback commences the Pager.dbSize variable +** is reset to the value that it held at the start of the savepoint +** (or transaction). No page with a page-number greater than this value +** is played back. If one is encountered it is simply skipped. +*/ +static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){ + i64 szJ; /* Effective size of the main journal */ + i64 iHdrOff; /* End of first segment of main-journal records */ + int rc = SQLITE_OK; /* Return code */ + Bitvec *pDone = 0; /* Bitvec to ensure pages played back only once */ + + assert( pPager->eState!=PAGER_ERROR ); + assert( pPager->eState>=PAGER_WRITER_LOCKED ); + + /* Allocate a bitvec to use to store the set of pages rolled back */ + if( pSavepoint ){ + pDone = sqlite3BitvecCreate(pSavepoint->nOrig); + if( !pDone ){ + return SQLITE_NOMEM_BKPT; + } + } + + /* Set the database size back to the value it was before the savepoint + ** being reverted was opened. + */ + pPager->dbSize = pSavepoint ? pSavepoint->nOrig : pPager->dbOrigSize; + pPager->changeCountDone = pPager->tempFile; + + if( !pSavepoint && pagerUseWal(pPager) ){ + return pagerRollbackWal(pPager); + } + + /* Use pPager->journalOff as the effective size of the main rollback + ** journal. The actual file might be larger than this in + ** PAGER_JOURNALMODE_TRUNCATE or PAGER_JOURNALMODE_PERSIST. But anything + ** past pPager->journalOff is off-limits to us. + */ + szJ = pPager->journalOff; + assert( pagerUseWal(pPager)==0 || szJ==0 ); + + /* Begin by rolling back records from the main journal starting at + ** PagerSavepoint.iOffset and continuing to the next journal header. + ** There might be records in the main journal that have a page number + ** greater than the current database size (pPager->dbSize) but those + ** will be skipped automatically. Pages are added to pDone as they + ** are played back. + */ + if( pSavepoint && !pagerUseWal(pPager) ){ + iHdrOff = pSavepoint->iHdrOffset ? pSavepoint->iHdrOffset : szJ; + pPager->journalOff = pSavepoint->iOffset; + while( rc==SQLITE_OK && pPager->journalOffjournalOff, pDone, 1, 1); + } + assert( rc!=SQLITE_DONE ); + }else{ + pPager->journalOff = 0; + } + + /* Continue rolling back records out of the main journal starting at + ** the first journal header seen and continuing until the effective end + ** of the main journal file. Continue to skip out-of-range pages and + ** continue adding pages rolled back to pDone. + */ + while( rc==SQLITE_OK && pPager->journalOffjournalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff" + ** test is related to ticket #2565. See the discussion in the + ** pager_playback() function for additional information. + */ + if( nJRec==0 + && pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff + ){ + nJRec = (u32)((szJ - pPager->journalOff)/JOURNAL_PG_SZ(pPager)); + } + for(ii=0; rc==SQLITE_OK && iijournalOffjournalOff, pDone, 1, 1); + } + assert( rc!=SQLITE_DONE ); + } + assert( rc!=SQLITE_OK || pPager->journalOff>=szJ ); + + /* Finally, rollback pages from the sub-journal. Page that were + ** previously rolled back out of the main journal (and are hence in pDone) + ** will be skipped. Out-of-range pages are also skipped. + */ + if( pSavepoint ){ + u32 ii; /* Loop counter */ + i64 offset = (i64)pSavepoint->iSubRec*(4+pPager->pageSize); + + if( pagerUseWal(pPager) ){ + rc = sqlite3WalSavepointUndo(pPager->pWal, pSavepoint->aWalData); + } + for(ii=pSavepoint->iSubRec; rc==SQLITE_OK && iinSubRec; ii++){ + assert( offset==(i64)ii*(4+pPager->pageSize) ); + rc = pager_playback_one_page(pPager, &offset, pDone, 0, 1); + } + assert( rc!=SQLITE_DONE ); + } + + sqlite3BitvecDestroy(pDone); + if( rc==SQLITE_OK ){ + pPager->journalOff = szJ; + } + + return rc; +} + +/* +** Change the maximum number of in-memory pages that are allowed +** before attempting to recycle clean and unused pages. +*/ +SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){ + sqlite3PcacheSetCachesize(pPager->pPCache, mxPage); +} + +/* +** Change the maximum number of in-memory pages that are allowed +** before attempting to spill pages to journal. +*/ +SQLITE_PRIVATE int sqlite3PagerSetSpillsize(Pager *pPager, int mxPage){ + return sqlite3PcacheSetSpillsize(pPager->pPCache, mxPage); +} + +/* +** Invoke SQLITE_FCNTL_MMAP_SIZE based on the current value of szMmap. +*/ +static void pagerFixMaplimit(Pager *pPager){ +#if SQLITE_MAX_MMAP_SIZE>0 + sqlite3_file *fd = pPager->fd; + if( isOpen(fd) && fd->pMethods->iVersion>=3 ){ + sqlite3_int64 sz; + sz = pPager->szMmap; + pPager->bUseFetch = (sz>0); + setGetterMethod(pPager); + sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz); + } +#endif +} + +/* +** Change the maximum size of any memory mapping made of the database file. +*/ +SQLITE_PRIVATE void sqlite3PagerSetMmapLimit(Pager *pPager, sqlite3_int64 szMmap){ + pPager->szMmap = szMmap; + pagerFixMaplimit(pPager); +} + +/* +** Free as much memory as possible from the pager. +*/ +SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){ + sqlite3PcacheShrink(pPager->pPCache); +} + +/* +** Adjust settings of the pager to those specified in the pgFlags parameter. +** +** The "level" in pgFlags & PAGER_SYNCHRONOUS_MASK sets the robustness +** of the database to damage due to OS crashes or power failures by +** changing the number of syncs()s when writing the journals. +** There are four levels: +** +** OFF sqlite3OsSync() is never called. This is the default +** for temporary and transient files. +** +** NORMAL The journal is synced once before writes begin on the +** database. This is normally adequate protection, but +** it is theoretically possible, though very unlikely, +** that an inopertune power failure could leave the journal +** in a state which would cause damage to the database +** when it is rolled back. +** +** FULL The journal is synced twice before writes begin on the +** database (with some additional information - the nRec field +** of the journal header - being written in between the two +** syncs). If we assume that writing a +** single disk sector is atomic, then this mode provides +** assurance that the journal will not be corrupted to the +** point of causing damage to the database during rollback. +** +** EXTRA This is like FULL except that is also syncs the directory +** that contains the rollback journal after the rollback +** journal is unlinked. +** +** The above is for a rollback-journal mode. For WAL mode, OFF continues +** to mean that no syncs ever occur. NORMAL means that the WAL is synced +** prior to the start of checkpoint and that the database file is synced +** at the conclusion of the checkpoint if the entire content of the WAL +** was written back into the database. But no sync operations occur for +** an ordinary commit in NORMAL mode with WAL. FULL means that the WAL +** file is synced following each commit operation, in addition to the +** syncs associated with NORMAL. There is no difference between FULL +** and EXTRA for WAL mode. +** +** Do not confuse synchronous=FULL with SQLITE_SYNC_FULL. The +** SQLITE_SYNC_FULL macro means to use the MacOSX-style full-fsync +** using fcntl(F_FULLFSYNC). SQLITE_SYNC_NORMAL means to do an +** ordinary fsync() call. There is no difference between SQLITE_SYNC_FULL +** and SQLITE_SYNC_NORMAL on platforms other than MacOSX. But the +** synchronous=FULL versus synchronous=NORMAL setting determines when +** the xSync primitive is called and is relevant to all platforms. +** +** Numeric values associated with these states are OFF==1, NORMAL=2, +** and FULL=3. +*/ +SQLITE_PRIVATE void sqlite3PagerSetFlags( + Pager *pPager, /* The pager to set safety level for */ + unsigned pgFlags /* Various flags */ +){ + unsigned level = pgFlags & PAGER_SYNCHRONOUS_MASK; + if( pPager->tempFile || level==PAGER_SYNCHRONOUS_OFF ){ + pPager->noSync = 1; + pPager->fullSync = 0; + pPager->extraSync = 0; + }else{ + pPager->noSync = 0; + pPager->fullSync = level>=PAGER_SYNCHRONOUS_FULL ?1:0; + + /* Set Pager.extraSync if "PRAGMA synchronous=EXTRA" is requested, or + ** if the file-system supports F2FS style atomic writes. If this flag + ** is set, SQLite syncs the directory to disk immediately after deleting + ** a journal file in "PRAGMA journal_mode=DELETE" mode. */ + if( level==PAGER_SYNCHRONOUS_EXTRA +#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE + || (sqlite3OsDeviceCharacteristics(pPager->fd) & SQLITE_IOCAP_BATCH_ATOMIC) +#endif + ){ + pPager->extraSync = 1; + }else{ + pPager->extraSync = 0; + } + } + if( pPager->noSync ){ + pPager->syncFlags = 0; + }else if( pgFlags & PAGER_FULLFSYNC ){ + pPager->syncFlags = SQLITE_SYNC_FULL; + }else{ + pPager->syncFlags = SQLITE_SYNC_NORMAL; + } + pPager->walSyncFlags = (pPager->syncFlags<<2); + if( pPager->fullSync ){ + pPager->walSyncFlags |= pPager->syncFlags; + } + if( (pgFlags & PAGER_CKPT_FULLFSYNC) && !pPager->noSync ){ + pPager->walSyncFlags |= (SQLITE_SYNC_FULL<<2); + } + if( pgFlags & PAGER_CACHESPILL ){ + pPager->doNotSpill &= ~SPILLFLAG_OFF; + }else{ + pPager->doNotSpill |= SPILLFLAG_OFF; + } +} + +/* +** The following global variable is incremented whenever the library +** attempts to open a temporary file. This information is used for +** testing and analysis only. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_opentemp_count = 0; +#endif + +/* +** Open a temporary file. +** +** Write the file descriptor into *pFile. Return SQLITE_OK on success +** or some other error code if we fail. The OS will automatically +** delete the temporary file when it is closed. +** +** The flags passed to the VFS layer xOpen() call are those specified +** by parameter vfsFlags ORed with the following: +** +** SQLITE_OPEN_READWRITE +** SQLITE_OPEN_CREATE +** SQLITE_OPEN_EXCLUSIVE +** SQLITE_OPEN_DELETEONCLOSE +*/ +static int pagerOpentemp( + Pager *pPager, /* The pager object */ + sqlite3_file *pFile, /* Write the file descriptor here */ + int vfsFlags /* Flags passed through to the VFS */ +){ + int rc; /* Return code */ + +#ifdef SQLITE_TEST + sqlite3_opentemp_count++; /* Used for testing and analysis only */ +#endif + + vfsFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | + SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE; + rc = sqlite3OsOpen(pPager->pVfs, 0, pFile, vfsFlags, 0); + assert( rc!=SQLITE_OK || isOpen(pFile) ); + return rc; +} + +/* +** Set the busy handler function. +** +** The pager invokes the busy-handler if sqlite3OsLock() returns +** SQLITE_BUSY when trying to upgrade from no-lock to a SHARED lock, +** or when trying to upgrade from a RESERVED lock to an EXCLUSIVE +** lock. It does *not* invoke the busy handler when upgrading from +** SHARED to RESERVED, or when upgrading from SHARED to EXCLUSIVE +** (which occurs during hot-journal rollback). Summary: +** +** Transition | Invokes xBusyHandler +** -------------------------------------------------------- +** NO_LOCK -> SHARED_LOCK | Yes +** SHARED_LOCK -> RESERVED_LOCK | No +** SHARED_LOCK -> EXCLUSIVE_LOCK | No +** RESERVED_LOCK -> EXCLUSIVE_LOCK | Yes +** +** If the busy-handler callback returns non-zero, the lock is +** retried. If it returns zero, then the SQLITE_BUSY error is +** returned to the caller of the pager API function. +*/ +SQLITE_PRIVATE void sqlite3PagerSetBusyHandler( + Pager *pPager, /* Pager object */ + int (*xBusyHandler)(void *), /* Pointer to busy-handler function */ + void *pBusyHandlerArg /* Argument to pass to xBusyHandler */ +){ + void **ap; + pPager->xBusyHandler = xBusyHandler; + pPager->pBusyHandlerArg = pBusyHandlerArg; + ap = (void **)&pPager->xBusyHandler; + assert( ((int(*)(void *))(ap[0]))==xBusyHandler ); + assert( ap[1]==pBusyHandlerArg ); + sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap); +} + +/* +** Change the page size used by the Pager object. The new page size +** is passed in *pPageSize. +** +** If the pager is in the error state when this function is called, it +** is a no-op. The value returned is the error state error code (i.e. +** one of SQLITE_IOERR, an SQLITE_IOERR_xxx sub-code or SQLITE_FULL). +** +** Otherwise, if all of the following are true: +** +** * the new page size (value of *pPageSize) is valid (a power +** of two between 512 and SQLITE_MAX_PAGE_SIZE, inclusive), and +** +** * there are no outstanding page references, and +** +** * the database is either not an in-memory database or it is +** an in-memory database that currently consists of zero pages. +** +** then the pager object page size is set to *pPageSize. +** +** If the page size is changed, then this function uses sqlite3PagerMalloc() +** to obtain a new Pager.pTmpSpace buffer. If this allocation attempt +** fails, SQLITE_NOMEM is returned and the page size remains unchanged. +** In all other cases, SQLITE_OK is returned. +** +** If the page size is not changed, either because one of the enumerated +** conditions above is not true, the pager was in error state when this +** function was called, or because the memory allocation attempt failed, +** then *pPageSize is set to the old, retained page size before returning. +*/ +SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){ + int rc = SQLITE_OK; + + /* It is not possible to do a full assert_pager_state() here, as this + ** function may be called from within PagerOpen(), before the state + ** of the Pager object is internally consistent. + ** + ** At one point this function returned an error if the pager was in + ** PAGER_ERROR state. But since PAGER_ERROR state guarantees that + ** there is at least one outstanding page reference, this function + ** is a no-op for that case anyhow. + */ + + u32 pageSize = *pPageSize; + assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) ); + if( (pPager->memDb==0 || pPager->dbSize==0) + && sqlite3PcacheRefCount(pPager->pPCache)==0 + && pageSize && pageSize!=(u32)pPager->pageSize + ){ + char *pNew = NULL; /* New temp space */ + i64 nByte = 0; + + if( pPager->eState>PAGER_OPEN && isOpen(pPager->fd) ){ + rc = sqlite3OsFileSize(pPager->fd, &nByte); + } + if( rc==SQLITE_OK ){ + /* 8 bytes of zeroed overrun space is sufficient so that the b-tree + * cell header parser will never run off the end of the allocation */ + pNew = (char *)sqlite3PageMalloc(pageSize+8); + if( !pNew ){ + rc = SQLITE_NOMEM_BKPT; + }else{ + memset(pNew+pageSize, 0, 8); + } + } + + if( rc==SQLITE_OK ){ + pager_reset(pPager); + rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize); + } + if( rc==SQLITE_OK ){ + sqlite3PageFree(pPager->pTmpSpace); + pPager->pTmpSpace = pNew; + pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize); + pPager->pageSize = pageSize; + pPager->lckPgno = (Pgno)(PENDING_BYTE/pageSize) + 1; + }else{ + sqlite3PageFree(pNew); + } + } + + *pPageSize = pPager->pageSize; + if( rc==SQLITE_OK ){ + if( nReserve<0 ) nReserve = pPager->nReserve; + assert( nReserve>=0 && nReserve<1000 ); + pPager->nReserve = (i16)nReserve; + pagerFixMaplimit(pPager); + } + return rc; +} + +/* +** Return a pointer to the "temporary page" buffer held internally +** by the pager. This is a buffer that is big enough to hold the +** entire content of a database page. This buffer is used internally +** during rollback and will be overwritten whenever a rollback +** occurs. But other modules are free to use it too, as long as +** no rollbacks are happening. +*/ +SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager *pPager){ + return pPager->pTmpSpace; +} + +/* +** Attempt to set the maximum database page count if mxPage is positive. +** Make no changes if mxPage is zero or negative. And never reduce the +** maximum page count below the current size of the database. +** +** Regardless of mxPage, return the current maximum page count. +*/ +SQLITE_PRIVATE Pgno sqlite3PagerMaxPageCount(Pager *pPager, Pgno mxPage){ + if( mxPage>0 ){ + pPager->mxPgno = mxPage; + } + assert( pPager->eState!=PAGER_OPEN ); /* Called only by OP_MaxPgcnt */ + /* assert( pPager->mxPgno>=pPager->dbSize ); */ + /* OP_MaxPgcnt ensures that the parameter passed to this function is not + ** less than the total number of valid pages in the database. But this + ** may be less than Pager.dbSize, and so the assert() above is not valid */ + return pPager->mxPgno; +} + +/* +** The following set of routines are used to disable the simulated +** I/O error mechanism. These routines are used to avoid simulated +** errors in places where we do not care about errors. +** +** Unless -DSQLITE_TEST=1 is used, these routines are all no-ops +** and generate no code. +*/ +#ifdef SQLITE_TEST +SQLITE_API extern int sqlite3_io_error_pending; +SQLITE_API extern int sqlite3_io_error_hit; +static int saved_cnt; +void disable_simulated_io_errors(void){ + saved_cnt = sqlite3_io_error_pending; + sqlite3_io_error_pending = -1; +} +void enable_simulated_io_errors(void){ + sqlite3_io_error_pending = saved_cnt; +} +#else +# define disable_simulated_io_errors() +# define enable_simulated_io_errors() +#endif + +/* +** Read the first N bytes from the beginning of the file into memory +** that pDest points to. +** +** If the pager was opened on a transient file (zFilename==""), or +** opened on a file less than N bytes in size, the output buffer is +** zeroed and SQLITE_OK returned. The rationale for this is that this +** function is used to read database headers, and a new transient or +** zero sized database has a header than consists entirely of zeroes. +** +** If any IO error apart from SQLITE_IOERR_SHORT_READ is encountered, +** the error code is returned to the caller and the contents of the +** output buffer undefined. +*/ +SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager *pPager, int N, unsigned char *pDest){ + int rc = SQLITE_OK; + memset(pDest, 0, N); + assert( isOpen(pPager->fd) || pPager->tempFile ); + + /* This routine is only called by btree immediately after creating + ** the Pager object. There has not been an opportunity to transition + ** to WAL mode yet. + */ + assert( !pagerUseWal(pPager) ); + + if( isOpen(pPager->fd) ){ + IOTRACE(("DBHDR %p 0 %d\n", pPager, N)) + rc = sqlite3OsRead(pPager->fd, pDest, N, 0); + if( rc==SQLITE_IOERR_SHORT_READ ){ + rc = SQLITE_OK; + } + } + return rc; +} + +/* +** This function may only be called when a read-transaction is open on +** the pager. It returns the total number of pages in the database. +** +** However, if the file is between 1 and bytes in size, then +** this is considered a 1 page file. +*/ +SQLITE_PRIVATE void sqlite3PagerPagecount(Pager *pPager, int *pnPage){ + assert( pPager->eState>=PAGER_READER ); + assert( pPager->eState!=PAGER_WRITER_FINISHED ); + *pnPage = (int)pPager->dbSize; +} + + +/* +** Try to obtain a lock of type locktype on the database file. If +** a similar or greater lock is already held, this function is a no-op +** (returning SQLITE_OK immediately). +** +** Otherwise, attempt to obtain the lock using sqlite3OsLock(). Invoke +** the busy callback if the lock is currently not available. Repeat +** until the busy callback returns false or until the attempt to +** obtain the lock succeeds. +** +** Return SQLITE_OK on success and an error code if we cannot obtain +** the lock. If the lock is obtained successfully, set the Pager.state +** variable to locktype before returning. +*/ +static int pager_wait_on_lock(Pager *pPager, int locktype){ + int rc; /* Return code */ + + /* Check that this is either a no-op (because the requested lock is + ** already held), or one of the transitions that the busy-handler + ** may be invoked during, according to the comment above + ** sqlite3PagerSetBusyhandler(). + */ + assert( (pPager->eLock>=locktype) + || (pPager->eLock==NO_LOCK && locktype==SHARED_LOCK) + || (pPager->eLock==RESERVED_LOCK && locktype==EXCLUSIVE_LOCK) + ); + + do { + rc = pagerLockDb(pPager, locktype); + }while( rc==SQLITE_BUSY && pPager->xBusyHandler(pPager->pBusyHandlerArg) ); + return rc; +} + +/* +** Function assertTruncateConstraint(pPager) checks that one of the +** following is true for all dirty pages currently in the page-cache: +** +** a) The page number is less than or equal to the size of the +** current database image, in pages, OR +** +** b) if the page content were written at this time, it would not +** be necessary to write the current content out to the sub-journal. +** +** If the condition asserted by this function were not true, and the +** dirty page were to be discarded from the cache via the pagerStress() +** routine, pagerStress() would not write the current page content to +** the database file. If a savepoint transaction were rolled back after +** this happened, the correct behavior would be to restore the current +** content of the page. However, since this content is not present in either +** the database file or the portion of the rollback journal and +** sub-journal rolled back the content could not be restored and the +** database image would become corrupt. It is therefore fortunate that +** this circumstance cannot arise. +*/ +#if defined(SQLITE_DEBUG) +static void assertTruncateConstraintCb(PgHdr *pPg){ + Pager *pPager = pPg->pPager; + assert( pPg->flags&PGHDR_DIRTY ); + if( pPg->pgno>pPager->dbSize ){ /* if (a) is false */ + Pgno pgno = pPg->pgno; + int i; + for(i=0; ipPager->nSavepoint; i++){ + PagerSavepoint *p = &pPager->aSavepoint[i]; + assert( p->nOrigpInSavepoint,pgno) ); + } + } +} +static void assertTruncateConstraint(Pager *pPager){ + sqlite3PcacheIterateDirty(pPager->pPCache, assertTruncateConstraintCb); +} +#else +# define assertTruncateConstraint(pPager) +#endif + +/* +** Truncate the in-memory database file image to nPage pages. This +** function does not actually modify the database file on disk. It +** just sets the internal state of the pager object so that the +** truncation will be done when the current transaction is committed. +** +** This function is only called right before committing a transaction. +** Once this function has been called, the transaction must either be +** rolled back or committed. It is not safe to call this function and +** then continue writing to the database. +*/ +SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){ + assert( pPager->dbSize>=nPage || CORRUPT_DB ); + assert( pPager->eState>=PAGER_WRITER_CACHEMOD ); + pPager->dbSize = nPage; + + /* At one point the code here called assertTruncateConstraint() to + ** ensure that all pages being truncated away by this operation are, + ** if one or more savepoints are open, present in the savepoint + ** journal so that they can be restored if the savepoint is rolled + ** back. This is no longer necessary as this function is now only + ** called right before committing a transaction. So although the + ** Pager object may still have open savepoints (Pager.nSavepoint!=0), + ** they cannot be rolled back. So the assertTruncateConstraint() call + ** is no longer correct. */ +} + + +/* +** This function is called before attempting a hot-journal rollback. It +** syncs the journal file to disk, then sets pPager->journalHdr to the +** size of the journal file so that the pager_playback() routine knows +** that the entire journal file has been synced. +** +** Syncing a hot-journal to disk before attempting to roll it back ensures +** that if a power-failure occurs during the rollback, the process that +** attempts rollback following system recovery sees the same journal +** content as this process. +** +** If everything goes as planned, SQLITE_OK is returned. Otherwise, +** an SQLite error code. +*/ +static int pagerSyncHotJournal(Pager *pPager){ + int rc = SQLITE_OK; + if( !pPager->noSync ){ + rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_NORMAL); + } + if( rc==SQLITE_OK ){ + rc = sqlite3OsFileSize(pPager->jfd, &pPager->journalHdr); + } + return rc; +} + +#if SQLITE_MAX_MMAP_SIZE>0 +/* +** Obtain a reference to a memory mapped page object for page number pgno. +** The new object will use the pointer pData, obtained from xFetch(). +** If successful, set *ppPage to point to the new page reference +** and return SQLITE_OK. Otherwise, return an SQLite error code and set +** *ppPage to zero. +** +** Page references obtained by calling this function should be released +** by calling pagerReleaseMapPage(). +*/ +static int pagerAcquireMapPage( + Pager *pPager, /* Pager object */ + Pgno pgno, /* Page number */ + void *pData, /* xFetch()'d data for this page */ + PgHdr **ppPage /* OUT: Acquired page object */ +){ + PgHdr *p; /* Memory mapped page to return */ + + if( pPager->pMmapFreelist ){ + *ppPage = p = pPager->pMmapFreelist; + pPager->pMmapFreelist = p->pDirty; + p->pDirty = 0; + assert( pPager->nExtra>=8 ); + memset(p->pExtra, 0, 8); + }else{ + *ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra); + if( p==0 ){ + sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pData); + return SQLITE_NOMEM_BKPT; + } + p->pExtra = (void *)&p[1]; + assert( EIGHT_BYTE_ALIGNMENT( p->pExtra ) ); + p->flags = PGHDR_MMAP; + p->nRef = 1; + p->pPager = pPager; + } + + assert( p->pExtra==(void *)&p[1] ); + assert( p->pPage==0 ); + assert( p->flags==PGHDR_MMAP ); + assert( p->pPager==pPager ); + assert( p->nRef==1 ); + + p->pgno = pgno; + p->pData = pData; + pPager->nMmapOut++; + + return SQLITE_OK; +} +#endif + +/* +** Release a reference to page pPg. pPg must have been returned by an +** earlier call to pagerAcquireMapPage(). +*/ +static void pagerReleaseMapPage(PgHdr *pPg){ + Pager *pPager = pPg->pPager; + pPager->nMmapOut--; + pPg->pDirty = pPager->pMmapFreelist; + pPager->pMmapFreelist = pPg; + + assert( pPager->fd->pMethods->iVersion>=3 ); + sqlite3OsUnfetch(pPager->fd, (i64)(pPg->pgno-1)*pPager->pageSize, pPg->pData); +} + +/* +** Free all PgHdr objects stored in the Pager.pMmapFreelist list. +*/ +static void pagerFreeMapHdrs(Pager *pPager){ + PgHdr *p; + PgHdr *pNext; + for(p=pPager->pMmapFreelist; p; p=pNext){ + pNext = p->pDirty; + sqlite3_free(p); + } +} + +/* Verify that the database file has not be deleted or renamed out from +** under the pager. Return SQLITE_OK if the database is still where it ought +** to be on disk. Return non-zero (SQLITE_READONLY_DBMOVED or some other error +** code from sqlite3OsAccess()) if the database has gone missing. +*/ +static int databaseIsUnmoved(Pager *pPager){ + int bHasMoved = 0; + int rc; + + if( pPager->tempFile ) return SQLITE_OK; + if( pPager->dbSize==0 ) return SQLITE_OK; + assert( pPager->zFilename && pPager->zFilename[0] ); + rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_HAS_MOVED, &bHasMoved); + if( rc==SQLITE_NOTFOUND ){ + /* If the HAS_MOVED file-control is unimplemented, assume that the file + ** has not been moved. That is the historical behavior of SQLite: prior to + ** version 3.8.3, it never checked */ + rc = SQLITE_OK; + }else if( rc==SQLITE_OK && bHasMoved ){ + rc = SQLITE_READONLY_DBMOVED; + } + return rc; +} + + +/* +** Shutdown the page cache. Free all memory and close all files. +** +** If a transaction was in progress when this routine is called, that +** transaction is rolled back. All outstanding pages are invalidated +** and their memory is freed. Any attempt to use a page associated +** with this page cache after this function returns will likely +** result in a coredump. +** +** This function always succeeds. If a transaction is active an attempt +** is made to roll it back. If an error occurs during the rollback +** a hot journal may be left in the filesystem but no error is returned +** to the caller. +*/ +SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3 *db){ + u8 *pTmp = (u8*)pPager->pTmpSpace; + assert( db || pagerUseWal(pPager)==0 ); + assert( assert_pager_state(pPager) ); + disable_simulated_io_errors(); + sqlite3BeginBenignMalloc(); + pagerFreeMapHdrs(pPager); + /* pPager->errCode = 0; */ + pPager->exclusiveMode = 0; +#ifndef SQLITE_OMIT_WAL + { + u8 *a = 0; + assert( db || pPager->pWal==0 ); + if( db && 0==(db->flags & SQLITE_NoCkptOnClose) + && SQLITE_OK==databaseIsUnmoved(pPager) + ){ + a = pTmp; + } + sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,a); + pPager->pWal = 0; + } +#else + UNUSED_PARAMETER(db); +#endif + pager_reset(pPager); + if( MEMDB ){ + pager_unlock(pPager); + }else{ + /* If it is open, sync the journal file before calling UnlockAndRollback. + ** If this is not done, then an unsynced portion of the open journal + ** file may be played back into the database. If a power failure occurs + ** while this is happening, the database could become corrupt. + ** + ** If an error occurs while trying to sync the journal, shift the pager + ** into the ERROR state. This causes UnlockAndRollback to unlock the + ** database and close the journal file without attempting to roll it + ** back or finalize it. The next database user will have to do hot-journal + ** rollback before accessing the database file. + */ + if( isOpen(pPager->jfd) ){ + pager_error(pPager, pagerSyncHotJournal(pPager)); + } + pagerUnlockAndRollback(pPager); + } + sqlite3EndBenignMalloc(); + enable_simulated_io_errors(); + PAGERTRACE(("CLOSE %d\n", PAGERID(pPager))); + IOTRACE(("CLOSE %p\n", pPager)) + sqlite3OsClose(pPager->jfd); + sqlite3OsClose(pPager->fd); + sqlite3PageFree(pTmp); + sqlite3PcacheClose(pPager->pPCache); + assert( !pPager->aSavepoint && !pPager->pInJournal ); + assert( !isOpen(pPager->jfd) && !isOpen(pPager->sjfd) ); + + sqlite3_free(pPager); + return SQLITE_OK; +} + +#if !defined(NDEBUG) || defined(SQLITE_TEST) +/* +** Return the page number for page pPg. +*/ +SQLITE_PRIVATE Pgno sqlite3PagerPagenumber(DbPage *pPg){ + return pPg->pgno; +} +#endif + +/* +** Increment the reference count for page pPg. +*/ +SQLITE_PRIVATE void sqlite3PagerRef(DbPage *pPg){ + sqlite3PcacheRef(pPg); +} + +/* +** Sync the journal. In other words, make sure all the pages that have +** been written to the journal have actually reached the surface of the +** disk and can be restored in the event of a hot-journal rollback. +** +** If the Pager.noSync flag is set, then this function is a no-op. +** Otherwise, the actions required depend on the journal-mode and the +** device characteristics of the file-system, as follows: +** +** * If the journal file is an in-memory journal file, no action need +** be taken. +** +** * Otherwise, if the device does not support the SAFE_APPEND property, +** then the nRec field of the most recently written journal header +** is updated to contain the number of journal records that have +** been written following it. If the pager is operating in full-sync +** mode, then the journal file is synced before this field is updated. +** +** * If the device does not support the SEQUENTIAL property, then +** journal file is synced. +** +** Or, in pseudo-code: +** +** if( NOT ){ +** if( NOT SAFE_APPEND ){ +** if( ) xSync(); +** +** } +** if( NOT SEQUENTIAL ) xSync(); +** } +** +** If successful, this routine clears the PGHDR_NEED_SYNC flag of every +** page currently held in memory before returning SQLITE_OK. If an IO +** error is encountered, then the IO error code is returned to the caller. +*/ +static int syncJournal(Pager *pPager, int newHdr){ + int rc; /* Return code */ + + assert( pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + ); + assert( assert_pager_state(pPager) ); + assert( !pagerUseWal(pPager) ); + + rc = sqlite3PagerExclusiveLock(pPager); + if( rc!=SQLITE_OK ) return rc; + + if( !pPager->noSync ){ + assert( !pPager->tempFile ); + if( isOpen(pPager->jfd) && pPager->journalMode!=PAGER_JOURNALMODE_MEMORY ){ + const int iDc = sqlite3OsDeviceCharacteristics(pPager->fd); + assert( isOpen(pPager->jfd) ); + + if( 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){ + /* This block deals with an obscure problem. If the last connection + ** that wrote to this database was operating in persistent-journal + ** mode, then the journal file may at this point actually be larger + ** than Pager.journalOff bytes. If the next thing in the journal + ** file happens to be a journal-header (written as part of the + ** previous connection's transaction), and a crash or power-failure + ** occurs after nRec is updated but before this connection writes + ** anything else to the journal file (or commits/rolls back its + ** transaction), then SQLite may become confused when doing the + ** hot-journal rollback following recovery. It may roll back all + ** of this connections data, then proceed to rolling back the old, + ** out-of-date data that follows it. Database corruption. + ** + ** To work around this, if the journal file does appear to contain + ** a valid header following Pager.journalOff, then write a 0x00 + ** byte to the start of it to prevent it from being recognized. + ** + ** Variable iNextHdrOffset is set to the offset at which this + ** problematic header will occur, if it exists. aMagic is used + ** as a temporary buffer to inspect the first couple of bytes of + ** the potential journal header. + */ + i64 iNextHdrOffset; + u8 aMagic[8]; + u8 zHeader[sizeof(aJournalMagic)+4]; + + memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic)); + put32bits(&zHeader[sizeof(aJournalMagic)], pPager->nRec); + + iNextHdrOffset = journalHdrOffset(pPager); + rc = sqlite3OsRead(pPager->jfd, aMagic, 8, iNextHdrOffset); + if( rc==SQLITE_OK && 0==memcmp(aMagic, aJournalMagic, 8) ){ + static const u8 zerobyte = 0; + rc = sqlite3OsWrite(pPager->jfd, &zerobyte, 1, iNextHdrOffset); + } + if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){ + return rc; + } + + /* Write the nRec value into the journal file header. If in + ** full-synchronous mode, sync the journal first. This ensures that + ** all data has really hit the disk before nRec is updated to mark + ** it as a candidate for rollback. + ** + ** This is not required if the persistent media supports the + ** SAFE_APPEND property. Because in this case it is not possible + ** for garbage data to be appended to the file, the nRec field + ** is populated with 0xFFFFFFFF when the journal header is written + ** and never needs to be updated. + */ + if( pPager->fullSync && 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){ + PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager))); + IOTRACE(("JSYNC %p\n", pPager)) + rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags); + if( rc!=SQLITE_OK ) return rc; + } + IOTRACE(("JHDR %p %lld\n", pPager, pPager->journalHdr)); + rc = sqlite3OsWrite( + pPager->jfd, zHeader, sizeof(zHeader), pPager->journalHdr + ); + if( rc!=SQLITE_OK ) return rc; + } + if( 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){ + PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager))); + IOTRACE(("JSYNC %p\n", pPager)) + rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags| + (pPager->syncFlags==SQLITE_SYNC_FULL?SQLITE_SYNC_DATAONLY:0) + ); + if( rc!=SQLITE_OK ) return rc; + } + + pPager->journalHdr = pPager->journalOff; + if( newHdr && 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){ + pPager->nRec = 0; + rc = writeJournalHdr(pPager); + if( rc!=SQLITE_OK ) return rc; + } + }else{ + pPager->journalHdr = pPager->journalOff; + } + } + + /* Unless the pager is in noSync mode, the journal file was just + ** successfully synced. Either way, clear the PGHDR_NEED_SYNC flag on + ** all pages. + */ + sqlite3PcacheClearSyncFlags(pPager->pPCache); + pPager->eState = PAGER_WRITER_DBMOD; + assert( assert_pager_state(pPager) ); + return SQLITE_OK; +} + +/* +** The argument is the first in a linked list of dirty pages connected +** by the PgHdr.pDirty pointer. This function writes each one of the +** in-memory pages in the list to the database file. The argument may +** be NULL, representing an empty list. In this case this function is +** a no-op. +** +** The pager must hold at least a RESERVED lock when this function +** is called. Before writing anything to the database file, this lock +** is upgraded to an EXCLUSIVE lock. If the lock cannot be obtained, +** SQLITE_BUSY is returned and no data is written to the database file. +** +** If the pager is a temp-file pager and the actual file-system file +** is not yet open, it is created and opened before any data is +** written out. +** +** Once the lock has been upgraded and, if necessary, the file opened, +** the pages are written out to the database file in list order. Writing +** a page is skipped if it meets either of the following criteria: +** +** * The page number is greater than Pager.dbSize, or +** * The PGHDR_DONT_WRITE flag is set on the page. +** +** If writing out a page causes the database file to grow, Pager.dbFileSize +** is updated accordingly. If page 1 is written out, then the value cached +** in Pager.dbFileVers[] is updated to match the new value stored in +** the database file. +** +** If everything is successful, SQLITE_OK is returned. If an IO error +** occurs, an IO error code is returned. Or, if the EXCLUSIVE lock cannot +** be obtained, SQLITE_BUSY is returned. +*/ +static int pager_write_pagelist(Pager *pPager, PgHdr *pList){ + int rc = SQLITE_OK; /* Return code */ + + /* This function is only called for rollback pagers in WRITER_DBMOD state. */ + assert( !pagerUseWal(pPager) ); + assert( pPager->tempFile || pPager->eState==PAGER_WRITER_DBMOD ); + assert( pPager->eLock==EXCLUSIVE_LOCK ); + assert( isOpen(pPager->fd) || pList->pDirty==0 ); + + /* If the file is a temp-file has not yet been opened, open it now. It + ** is not possible for rc to be other than SQLITE_OK if this branch + ** is taken, as pager_wait_on_lock() is a no-op for temp-files. + */ + if( !isOpen(pPager->fd) ){ + assert( pPager->tempFile && rc==SQLITE_OK ); + rc = pagerOpentemp(pPager, pPager->fd, pPager->vfsFlags); + } + + /* Before the first write, give the VFS a hint of what the final + ** file size will be. + */ + assert( rc!=SQLITE_OK || isOpen(pPager->fd) ); + if( rc==SQLITE_OK + && pPager->dbHintSizedbSize + && (pList->pDirty || pList->pgno>pPager->dbHintSize) + ){ + sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize; + sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile); + pPager->dbHintSize = pPager->dbSize; + } + + while( rc==SQLITE_OK && pList ){ + Pgno pgno = pList->pgno; + + /* If there are dirty pages in the page cache with page numbers greater + ** than Pager.dbSize, this means sqlite3PagerTruncateImage() was called to + ** make the file smaller (presumably by auto-vacuum code). Do not write + ** any such pages to the file. + ** + ** Also, do not write out any page that has the PGHDR_DONT_WRITE flag + ** set (set by sqlite3PagerDontWrite()). + */ + if( pgno<=pPager->dbSize && 0==(pList->flags&PGHDR_DONT_WRITE) ){ + i64 offset = (pgno-1)*(i64)pPager->pageSize; /* Offset to write */ + char *pData; /* Data to write */ + + assert( (pList->flags&PGHDR_NEED_SYNC)==0 ); + if( pList->pgno==1 ) pager_write_changecounter(pList); + + pData = pList->pData; + + /* Write out the page data. */ + rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset); + + /* If page 1 was just written, update Pager.dbFileVers to match + ** the value now stored in the database file. If writing this + ** page caused the database file to grow, update dbFileSize. + */ + if( pgno==1 ){ + memcpy(&pPager->dbFileVers, &pData[24], sizeof(pPager->dbFileVers)); + } + if( pgno>pPager->dbFileSize ){ + pPager->dbFileSize = pgno; + } + pPager->aStat[PAGER_STAT_WRITE]++; + + /* Update any backup objects copying the contents of this pager. */ + sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)pList->pData); + + PAGERTRACE(("STORE %d page %d hash(%08x)\n", + PAGERID(pPager), pgno, pager_pagehash(pList))); + IOTRACE(("PGOUT %p %d\n", pPager, pgno)); + PAGER_INCR(sqlite3_pager_writedb_count); + }else{ + PAGERTRACE(("NOSTORE %d page %d\n", PAGERID(pPager), pgno)); + } + pager_set_pagehash(pList); + pList = pList->pDirty; + } + + return rc; +} + +/* +** Ensure that the sub-journal file is open. If it is already open, this +** function is a no-op. +** +** SQLITE_OK is returned if everything goes according to plan. An +** SQLITE_IOERR_XXX error code is returned if a call to sqlite3OsOpen() +** fails. +*/ +static int openSubJournal(Pager *pPager){ + int rc = SQLITE_OK; + if( !isOpen(pPager->sjfd) ){ + const int flags = SQLITE_OPEN_SUBJOURNAL | SQLITE_OPEN_READWRITE + | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE + | SQLITE_OPEN_DELETEONCLOSE; + int nStmtSpill = sqlite3Config.nStmtSpill; + if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY || pPager->subjInMemory ){ + nStmtSpill = -1; + } + rc = sqlite3JournalOpen(pPager->pVfs, 0, pPager->sjfd, flags, nStmtSpill); + } + return rc; +} + +/* +** Append a record of the current state of page pPg to the sub-journal. +** +** If successful, set the bit corresponding to pPg->pgno in the bitvecs +** for all open savepoints before returning. +** +** This function returns SQLITE_OK if everything is successful, an IO +** error code if the attempt to write to the sub-journal fails, or +** SQLITE_NOMEM if a malloc fails while setting a bit in a savepoint +** bitvec. +*/ +static int subjournalPage(PgHdr *pPg){ + int rc = SQLITE_OK; + Pager *pPager = pPg->pPager; + if( pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ + + /* Open the sub-journal, if it has not already been opened */ + assert( pPager->useJournal ); + assert( isOpen(pPager->jfd) || pagerUseWal(pPager) ); + assert( isOpen(pPager->sjfd) || pPager->nSubRec==0 ); + assert( pagerUseWal(pPager) + || pageInJournal(pPager, pPg) + || pPg->pgno>pPager->dbOrigSize + ); + rc = openSubJournal(pPager); + + /* If the sub-journal was opened successfully (or was already open), + ** write the journal record into the file. */ + if( rc==SQLITE_OK ){ + void *pData = pPg->pData; + i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize); + char *pData2; + pData2 = pData; + PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno)); + rc = write32bits(pPager->sjfd, offset, pPg->pgno); + if( rc==SQLITE_OK ){ + rc = sqlite3OsWrite(pPager->sjfd, pData2, pPager->pageSize, offset+4); + } + } + } + if( rc==SQLITE_OK ){ + pPager->nSubRec++; + assert( pPager->nSavepoint>0 ); + rc = addToSavepointBitvecs(pPager, pPg->pgno); + } + return rc; +} +static int subjournalPageIfRequired(PgHdr *pPg){ + if( subjRequiresPage(pPg) ){ + return subjournalPage(pPg); + }else{ + return SQLITE_OK; + } +} + +/* +** This function is called by the pcache layer when it has reached some +** soft memory limit. The first argument is a pointer to a Pager object +** (cast as a void*). The pager is always 'purgeable' (not an in-memory +** database). The second argument is a reference to a page that is +** currently dirty but has no outstanding references. The page +** is always associated with the Pager object passed as the first +** argument. +** +** The job of this function is to make pPg clean by writing its contents +** out to the database file, if possible. This may involve syncing the +** journal file. +** +** If successful, sqlite3PcacheMakeClean() is called on the page and +** SQLITE_OK returned. If an IO error occurs while trying to make the +** page clean, the IO error code is returned. If the page cannot be +** made clean for some other reason, but no error occurs, then SQLITE_OK +** is returned by sqlite3PcacheMakeClean() is not called. +*/ +static int pagerStress(void *p, PgHdr *pPg){ + Pager *pPager = (Pager *)p; + int rc = SQLITE_OK; + + assert( pPg->pPager==pPager ); + assert( pPg->flags&PGHDR_DIRTY ); + + /* The doNotSpill NOSYNC bit is set during times when doing a sync of + ** journal (and adding a new header) is not allowed. This occurs + ** during calls to sqlite3PagerWrite() while trying to journal multiple + ** pages belonging to the same sector. + ** + ** The doNotSpill ROLLBACK and OFF bits inhibits all cache spilling + ** regardless of whether or not a sync is required. This is set during + ** a rollback or by user request, respectively. + ** + ** Spilling is also prohibited when in an error state since that could + ** lead to database corruption. In the current implementation it + ** is impossible for sqlite3PcacheFetch() to be called with createFlag==3 + ** while in the error state, hence it is impossible for this routine to + ** be called in the error state. Nevertheless, we include a NEVER() + ** test for the error state as a safeguard against future changes. + */ + if( NEVER(pPager->errCode) ) return SQLITE_OK; + testcase( pPager->doNotSpill & SPILLFLAG_ROLLBACK ); + testcase( pPager->doNotSpill & SPILLFLAG_OFF ); + testcase( pPager->doNotSpill & SPILLFLAG_NOSYNC ); + if( pPager->doNotSpill + && ((pPager->doNotSpill & (SPILLFLAG_ROLLBACK|SPILLFLAG_OFF))!=0 + || (pPg->flags & PGHDR_NEED_SYNC)!=0) + ){ + return SQLITE_OK; + } + + pPager->aStat[PAGER_STAT_SPILL]++; + pPg->pDirty = 0; + if( pagerUseWal(pPager) ){ + /* Write a single frame for this page to the log. */ + rc = subjournalPageIfRequired(pPg); + if( rc==SQLITE_OK ){ + rc = pagerWalFrames(pPager, pPg, 0, 0); + } + }else{ + +#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE + if( pPager->tempFile==0 ){ + rc = sqlite3JournalCreate(pPager->jfd); + if( rc!=SQLITE_OK ) return pager_error(pPager, rc); + } +#endif + + /* Sync the journal file if required. */ + if( pPg->flags&PGHDR_NEED_SYNC + || pPager->eState==PAGER_WRITER_CACHEMOD + ){ + rc = syncJournal(pPager, 1); + } + + /* Write the contents of the page out to the database file. */ + if( rc==SQLITE_OK ){ + assert( (pPg->flags&PGHDR_NEED_SYNC)==0 ); + rc = pager_write_pagelist(pPager, pPg); + } + } + + /* Mark the page as clean. */ + if( rc==SQLITE_OK ){ + PAGERTRACE(("STRESS %d page %d\n", PAGERID(pPager), pPg->pgno)); + sqlite3PcacheMakeClean(pPg); + } + + return pager_error(pPager, rc); +} + +/* +** Flush all unreferenced dirty pages to disk. +*/ +SQLITE_PRIVATE int sqlite3PagerFlush(Pager *pPager){ + int rc = pPager->errCode; + if( !MEMDB ){ + PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache); + assert( assert_pager_state(pPager) ); + while( rc==SQLITE_OK && pList ){ + PgHdr *pNext = pList->pDirty; + if( pList->nRef==0 ){ + rc = pagerStress((void*)pPager, pList); + } + pList = pNext; + } + } + + return rc; +} + +/* +** Allocate and initialize a new Pager object and put a pointer to it +** in *ppPager. The pager should eventually be freed by passing it +** to sqlite3PagerClose(). +** +** The zFilename argument is the path to the database file to open. +** If zFilename is NULL then a randomly-named temporary file is created +** and used as the file to be cached. Temporary files are be deleted +** automatically when they are closed. If zFilename is ":memory:" then +** all information is held in cache. It is never written to disk. +** This can be used to implement an in-memory database. +** +** The nExtra parameter specifies the number of bytes of space allocated +** along with each page reference. This space is available to the user +** via the sqlite3PagerGetExtra() API. When a new page is allocated, the +** first 8 bytes of this space are zeroed but the remainder is uninitialized. +** (The extra space is used by btree as the MemPage object.) +** +** The flags argument is used to specify properties that affect the +** operation of the pager. It should be passed some bitwise combination +** of the PAGER_* flags. +** +** The vfsFlags parameter is a bitmask to pass to the flags parameter +** of the xOpen() method of the supplied VFS when opening files. +** +** If the pager object is allocated and the specified file opened +** successfully, SQLITE_OK is returned and *ppPager set to point to +** the new pager object. If an error occurs, *ppPager is set to NULL +** and error code returned. This function may return SQLITE_NOMEM +** (sqlite3Malloc() is used to allocate memory), SQLITE_CANTOPEN or +** various SQLITE_IO_XXX errors. +*/ +SQLITE_PRIVATE int sqlite3PagerOpen( + sqlite3_vfs *pVfs, /* The virtual file system to use */ + Pager **ppPager, /* OUT: Return the Pager structure here */ + const char *zFilename, /* Name of the database file to open */ + int nExtra, /* Extra bytes append to each in-memory page */ + int flags, /* flags controlling this file */ + int vfsFlags, /* flags passed through to sqlite3_vfs.xOpen() */ + void (*xReinit)(DbPage*) /* Function to reinitialize pages */ +){ + u8 *pPtr; + Pager *pPager = 0; /* Pager object to allocate and return */ + int rc = SQLITE_OK; /* Return code */ + int tempFile = 0; /* True for temp files (incl. in-memory files) */ + int memDb = 0; /* True if this is an in-memory file */ + int memJM = 0; /* Memory journal mode */ + int readOnly = 0; /* True if this is a read-only file */ + int journalFileSize; /* Bytes to allocate for each journal fd */ + char *zPathname = 0; /* Full path to database file */ + int nPathname = 0; /* Number of bytes in zPathname */ + int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */ + int pcacheSize = sqlite3PcacheSize(); /* Bytes to allocate for PCache */ + u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */ + const char *zUri = 0; /* URI args to copy */ + int nUriByte = 1; /* Number of bytes of URI args at *zUri */ + + + /* Figure out how much space is required for each journal file-handle + ** (there are two of them, the main journal and the sub-journal). */ + journalFileSize = ROUND8(sqlite3JournalSize(pVfs)); + + /* Set the output variable to NULL in case an error occurs. */ + *ppPager = 0; + +#ifndef SQLITE_OMIT_MEMORYDB + if( flags & PAGER_MEMORY ){ + memDb = 1; + if( zFilename && zFilename[0] ){ + zPathname = sqlite3DbStrDup(0, zFilename); + if( zPathname==0 ) return SQLITE_NOMEM_BKPT; + nPathname = sqlite3Strlen30(zPathname); + zFilename = 0; + } + } +#endif + + /* Compute and store the full pathname in an allocated buffer pointed + ** to by zPathname, length nPathname. Or, if this is a temporary file, + ** leave both nPathname and zPathname set to 0. + */ + if( zFilename && zFilename[0] ){ + const char *z; + nPathname = pVfs->mxPathname + 1; + zPathname = sqlite3DbMallocRaw(0, 2*(i64)nPathname); + if( zPathname==0 ){ + return SQLITE_NOMEM_BKPT; + } + zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */ + rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_OK_SYMLINK ){ + if( vfsFlags & SQLITE_OPEN_NOFOLLOW ){ + rc = SQLITE_CANTOPEN_SYMLINK; + }else{ + rc = SQLITE_OK; + } + } + } + nPathname = sqlite3Strlen30(zPathname); + z = zUri = &zFilename[sqlite3Strlen30(zFilename)+1]; + while( *z ){ + z += strlen(z)+1; + z += strlen(z)+1; + } + nUriByte = (int)(&z[1] - zUri); + assert( nUriByte>=1 ); + if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){ + /* This branch is taken when the journal path required by + ** the database being opened will be more than pVfs->mxPathname + ** bytes in length. This means the database cannot be opened, + ** as it will not be possible to open the journal file or even + ** check for a hot-journal before reading. + */ + rc = SQLITE_CANTOPEN_BKPT; + } + if( rc!=SQLITE_OK ){ + sqlite3DbFree(0, zPathname); + return rc; + } + } + + /* Allocate memory for the Pager structure, PCache object, the + ** three file descriptors, the database file name and the journal + ** file name. The layout in memory is as follows: + ** + ** Pager object (sizeof(Pager) bytes) + ** PCache object (sqlite3PcacheSize() bytes) + ** Database file handle (pVfs->szOsFile bytes) + ** Sub-journal file handle (journalFileSize bytes) + ** Main journal file handle (journalFileSize bytes) + ** Ptr back to the Pager (sizeof(Pager*) bytes) + ** \0\0\0\0 database prefix (4 bytes) + ** Database file name (nPathname+1 bytes) + ** URI query parameters (nUriByte bytes) + ** Journal filename (nPathname+8+1 bytes) + ** WAL filename (nPathname+4+1 bytes) + ** \0\0\0 terminator (3 bytes) + ** + ** Some 3rd-party software, over which we have no control, depends on + ** the specific order of the filenames and the \0 separators between them + ** so that it can (for example) find the database filename given the WAL + ** filename without using the sqlite3_filename_database() API. This is a + ** misuse of SQLite and a bug in the 3rd-party software, but the 3rd-party + ** software is in widespread use, so we try to avoid changing the filename + ** order and formatting if possible. In particular, the details of the + ** filename format expected by 3rd-party software should be as follows: + ** + ** - Main Database Path + ** - \0 + ** - Multiple URI components consisting of: + ** - Key + ** - \0 + ** - Value + ** - \0 + ** - \0 + ** - Journal Path + ** - \0 + ** - WAL Path (zWALName) + ** - \0 + ** + ** The sqlite3_create_filename() interface and the databaseFilename() utility + ** that is used by sqlite3_filename_database() and kin also depend on the + ** specific formatting and order of the various filenames, so if the format + ** changes here, be sure to change it there as well. + */ + assert( SQLITE_PTRSIZE==sizeof(Pager*) ); + pPtr = (u8 *)sqlite3MallocZero( + ROUND8(sizeof(*pPager)) + /* Pager structure */ + ROUND8(pcacheSize) + /* PCache object */ + ROUND8(pVfs->szOsFile) + /* The main db file */ + (u64)journalFileSize * 2 + /* The two journal files */ + SQLITE_PTRSIZE + /* Space to hold a pointer */ + 4 + /* Database prefix */ + (u64)nPathname + 1 + /* database filename */ + (u64)nUriByte + /* query parameters */ + (u64)nPathname + 8 + 1 + /* Journal filename */ +#ifndef SQLITE_OMIT_WAL + (u64)nPathname + 4 + 1 + /* WAL filename */ +#endif + 3 /* Terminator */ + ); + assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) ); + if( !pPtr ){ + sqlite3DbFree(0, zPathname); + return SQLITE_NOMEM_BKPT; + } + pPager = (Pager*)pPtr; pPtr += ROUND8(sizeof(*pPager)); + pPager->pPCache = (PCache*)pPtr; pPtr += ROUND8(pcacheSize); + pPager->fd = (sqlite3_file*)pPtr; pPtr += ROUND8(pVfs->szOsFile); + pPager->sjfd = (sqlite3_file*)pPtr; pPtr += journalFileSize; + pPager->jfd = (sqlite3_file*)pPtr; pPtr += journalFileSize; + assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) ); + memcpy(pPtr, &pPager, SQLITE_PTRSIZE); pPtr += SQLITE_PTRSIZE; + + /* Fill in the Pager.zFilename and pPager.zQueryParam fields */ + pPtr += 4; /* Skip zero prefix */ + pPager->zFilename = (char*)pPtr; + if( nPathname>0 ){ + memcpy(pPtr, zPathname, nPathname); pPtr += nPathname + 1; + if( zUri ){ + memcpy(pPtr, zUri, nUriByte); pPtr += nUriByte; + }else{ + pPtr++; + } + } + + + /* Fill in Pager.zJournal */ + if( nPathname>0 ){ + pPager->zJournal = (char*)pPtr; + memcpy(pPtr, zPathname, nPathname); pPtr += nPathname; + memcpy(pPtr, "-journal",8); pPtr += 8 + 1; +#ifdef SQLITE_ENABLE_8_3_NAMES + sqlite3FileSuffix3(zFilename,pPager->zJournal); + pPtr = (u8*)(pPager->zJournal + sqlite3Strlen30(pPager->zJournal)+1); +#endif + }else{ + pPager->zJournal = 0; + } + +#ifndef SQLITE_OMIT_WAL + /* Fill in Pager.zWal */ + if( nPathname>0 ){ + pPager->zWal = (char*)pPtr; + memcpy(pPtr, zPathname, nPathname); pPtr += nPathname; + memcpy(pPtr, "-wal", 4); pPtr += 4 + 1; +#ifdef SQLITE_ENABLE_8_3_NAMES + sqlite3FileSuffix3(zFilename, pPager->zWal); + pPtr = (u8*)(pPager->zWal + sqlite3Strlen30(pPager->zWal)+1); +#endif + }else{ + pPager->zWal = 0; + } +#endif + (void)pPtr; /* Suppress warning about unused pPtr value */ + + if( nPathname ) sqlite3DbFree(0, zPathname); + pPager->pVfs = pVfs; + pPager->vfsFlags = vfsFlags; + + /* Open the pager file. + */ + if( zFilename && zFilename[0] ){ + int fout = 0; /* VFS flags returned by xOpen() */ + rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout); + assert( !memDb ); + pPager->memVfs = memJM = (fout&SQLITE_OPEN_MEMORY)!=0; + readOnly = (fout&SQLITE_OPEN_READONLY)!=0; + + /* If the file was successfully opened for read/write access, + ** choose a default page size in case we have to create the + ** database file. The default page size is the maximum of: + ** + ** + SQLITE_DEFAULT_PAGE_SIZE, + ** + The value returned by sqlite3OsSectorSize() + ** + The largest page size that can be written atomically. + */ + if( rc==SQLITE_OK ){ + int iDc = sqlite3OsDeviceCharacteristics(pPager->fd); + if( !readOnly ){ + setSectorSize(pPager); + assert(SQLITE_DEFAULT_PAGE_SIZE<=SQLITE_MAX_DEFAULT_PAGE_SIZE); + if( szPageDfltsectorSize ){ + if( pPager->sectorSize>SQLITE_MAX_DEFAULT_PAGE_SIZE ){ + szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE; + }else{ + szPageDflt = (u32)pPager->sectorSize; + } + } +#ifdef SQLITE_ENABLE_ATOMIC_WRITE + { + int ii; + assert(SQLITE_IOCAP_ATOMIC512==(512>>8)); + assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8)); + assert(SQLITE_MAX_DEFAULT_PAGE_SIZE<=65536); + for(ii=szPageDflt; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){ + if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ){ + szPageDflt = ii; + } + } + } +#endif + } + pPager->noLock = sqlite3_uri_boolean(pPager->zFilename, "nolock", 0); + if( (iDc & SQLITE_IOCAP_IMMUTABLE)!=0 + || sqlite3_uri_boolean(pPager->zFilename, "immutable", 0) ){ + vfsFlags |= SQLITE_OPEN_READONLY; + goto act_like_temp_file; + } + } + }else{ + /* If a temporary file is requested, it is not opened immediately. + ** In this case we accept the default page size and delay actually + ** opening the file until the first call to OsWrite(). + ** + ** This branch is also run for an in-memory database. An in-memory + ** database is the same as a temp-file that is never written out to + ** disk and uses an in-memory rollback journal. + ** + ** This branch also runs for files marked as immutable. + */ +act_like_temp_file: + tempFile = 1; + pPager->eState = PAGER_READER; /* Pretend we already have a lock */ + pPager->eLock = EXCLUSIVE_LOCK; /* Pretend we are in EXCLUSIVE mode */ + pPager->noLock = 1; /* Do no locking */ + readOnly = (vfsFlags&SQLITE_OPEN_READONLY); + } + + /* The following call to PagerSetPagesize() serves to set the value of + ** Pager.pageSize and to allocate the Pager.pTmpSpace buffer. + */ + if( rc==SQLITE_OK ){ + assert( pPager->memDb==0 ); + rc = sqlite3PagerSetPagesize(pPager, &szPageDflt, -1); + testcase( rc!=SQLITE_OK ); + } + + /* Initialize the PCache object. */ + if( rc==SQLITE_OK ){ + nExtra = ROUND8(nExtra); + assert( nExtra>=8 && nExtra<1000 ); + rc = sqlite3PcacheOpen(szPageDflt, nExtra, !memDb, + !memDb?pagerStress:0, (void *)pPager, pPager->pPCache); + } + + /* If an error occurred above, free the Pager structure and close the file. + */ + if( rc!=SQLITE_OK ){ + sqlite3OsClose(pPager->fd); + sqlite3PageFree(pPager->pTmpSpace); + sqlite3_free(pPager); + return rc; + } + + PAGERTRACE(("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename)); + IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename)) + + pPager->useJournal = (u8)useJournal; + /* pPager->stmtOpen = 0; */ + /* pPager->stmtInUse = 0; */ + /* pPager->nRef = 0; */ + /* pPager->stmtSize = 0; */ + /* pPager->stmtJSize = 0; */ + /* pPager->nPage = 0; */ + pPager->mxPgno = SQLITE_MAX_PAGE_COUNT; + /* pPager->state = PAGER_UNLOCK; */ + /* pPager->errMask = 0; */ + pPager->tempFile = (u8)tempFile; + assert( tempFile==PAGER_LOCKINGMODE_NORMAL + || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE ); + assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 ); + pPager->exclusiveMode = (u8)tempFile; + pPager->changeCountDone = pPager->tempFile; + pPager->memDb = (u8)memDb; + pPager->readOnly = (u8)readOnly; + assert( useJournal || pPager->tempFile ); + sqlite3PagerSetFlags(pPager, (SQLITE_DEFAULT_SYNCHRONOUS+1)|PAGER_CACHESPILL); + /* pPager->pFirst = 0; */ + /* pPager->pFirstSynced = 0; */ + /* pPager->pLast = 0; */ + pPager->nExtra = (u16)nExtra; + pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT; + assert( isOpen(pPager->fd) || tempFile ); + setSectorSize(pPager); + if( !useJournal ){ + pPager->journalMode = PAGER_JOURNALMODE_OFF; + }else if( memDb || memJM ){ + pPager->journalMode = PAGER_JOURNALMODE_MEMORY; + } + /* pPager->xBusyHandler = 0; */ + /* pPager->pBusyHandlerArg = 0; */ + pPager->xReiniter = xReinit; + setGetterMethod(pPager); + /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */ + /* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */ + + *ppPager = pPager; + return SQLITE_OK; +} + +/* +** Return the sqlite3_file for the main database given the name +** of the corresponding WAL or Journal name as passed into +** xOpen. +*/ +SQLITE_API sqlite3_file *sqlite3_database_file_object(const char *zName){ + Pager *pPager; + const char *p; + while( zName[-1]!=0 || zName[-2]!=0 || zName[-3]!=0 || zName[-4]!=0 ){ + zName--; + } + p = zName - 4 - sizeof(Pager*); + assert( EIGHT_BYTE_ALIGNMENT(p) ); + pPager = *(Pager**)p; + return pPager->fd; +} + + +/* +** This function is called after transitioning from PAGER_UNLOCK to +** PAGER_SHARED state. It tests if there is a hot journal present in +** the file-system for the given pager. A hot journal is one that +** needs to be played back. According to this function, a hot-journal +** file exists if the following criteria are met: +** +** * The journal file exists in the file system, and +** * No process holds a RESERVED or greater lock on the database file, and +** * The database file itself is greater than 0 bytes in size, and +** * The first byte of the journal file exists and is not 0x00. +** +** If the current size of the database file is 0 but a journal file +** exists, that is probably an old journal left over from a prior +** database with the same name. In this case the journal file is +** just deleted using OsDelete, *pExists is set to 0 and SQLITE_OK +** is returned. +** +** This routine does not check if there is a super-journal filename +** at the end of the file. If there is, and that super-journal file +** does not exist, then the journal file is not really hot. In this +** case this routine will return a false-positive. The pager_playback() +** routine will discover that the journal file is not really hot and +** will not roll it back. +** +** If a hot-journal file is found to exist, *pExists is set to 1 and +** SQLITE_OK returned. If no hot-journal file is present, *pExists is +** set to 0 and SQLITE_OK returned. If an IO error occurs while trying +** to determine whether or not a hot-journal file exists, the IO error +** code is returned and the value of *pExists is undefined. +*/ +static int hasHotJournal(Pager *pPager, int *pExists){ + sqlite3_vfs * const pVfs = pPager->pVfs; + int rc = SQLITE_OK; /* Return code */ + int exists = 1; /* True if a journal file is present */ + int jrnlOpen = !!isOpen(pPager->jfd); + + assert( pPager->useJournal ); + assert( isOpen(pPager->fd) ); + assert( pPager->eState==PAGER_OPEN ); + + assert( jrnlOpen==0 || ( sqlite3OsDeviceCharacteristics(pPager->jfd) & + SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN + )); + + *pExists = 0; + if( !jrnlOpen ){ + rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &exists); + } + if( rc==SQLITE_OK && exists ){ + int locked = 0; /* True if some process holds a RESERVED lock */ + + /* Race condition here: Another process might have been holding the + ** the RESERVED lock and have a journal open at the sqlite3OsAccess() + ** call above, but then delete the journal and drop the lock before + ** we get to the following sqlite3OsCheckReservedLock() call. If that + ** is the case, this routine might think there is a hot journal when + ** in fact there is none. This results in a false-positive which will + ** be dealt with by the playback routine. Ticket #3883. + */ + rc = sqlite3OsCheckReservedLock(pPager->fd, &locked); + if( rc==SQLITE_OK && !locked ){ + Pgno nPage; /* Number of pages in database file */ + + assert( pPager->tempFile==0 ); + rc = pagerPagecount(pPager, &nPage); + if( rc==SQLITE_OK ){ + /* If the database is zero pages in size, that means that either (1) the + ** journal is a remnant from a prior database with the same name where + ** the database file but not the journal was deleted, or (2) the initial + ** transaction that populates a new database is being rolled back. + ** In either case, the journal file can be deleted. However, take care + ** not to delete the journal file if it is already open due to + ** journal_mode=PERSIST. + */ + if( nPage==0 && !jrnlOpen ){ + sqlite3BeginBenignMalloc(); + if( pagerLockDb(pPager, RESERVED_LOCK)==SQLITE_OK ){ + sqlite3OsDelete(pVfs, pPager->zJournal, 0); + if( !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK); + } + sqlite3EndBenignMalloc(); + }else{ + /* The journal file exists and no other connection has a reserved + ** or greater lock on the database file. Now check that there is + ** at least one non-zero bytes at the start of the journal file. + ** If there is, then we consider this journal to be hot. If not, + ** it can be ignored. + */ + if( !jrnlOpen ){ + int f = SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL; + rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &f); + } + if( rc==SQLITE_OK ){ + u8 first = 0; + rc = sqlite3OsRead(pPager->jfd, (void *)&first, 1, 0); + if( rc==SQLITE_IOERR_SHORT_READ ){ + rc = SQLITE_OK; + } + if( !jrnlOpen ){ + sqlite3OsClose(pPager->jfd); + } + *pExists = (first!=0); + }else if( rc==SQLITE_CANTOPEN ){ + /* If we cannot open the rollback journal file in order to see if + ** it has a zero header, that might be due to an I/O error, or + ** it might be due to the race condition described above and in + ** ticket #3883. Either way, assume that the journal is hot. + ** This might be a false positive. But if it is, then the + ** automatic journal playback and recovery mechanism will deal + ** with it under an EXCLUSIVE lock where we do not need to + ** worry so much with race conditions. + */ + *pExists = 1; + rc = SQLITE_OK; + } + } + } + } + } + + return rc; +} + +/* +** This function is called to obtain a shared lock on the database file. +** It is illegal to call sqlite3PagerGet() until after this function +** has been successfully called. If a shared-lock is already held when +** this function is called, it is a no-op. +** +** The following operations are also performed by this function. +** +** 1) If the pager is currently in PAGER_OPEN state (no lock held +** on the database file), then an attempt is made to obtain a +** SHARED lock on the database file. Immediately after obtaining +** the SHARED lock, the file-system is checked for a hot-journal, +** which is played back if present. Following any hot-journal +** rollback, the contents of the cache are validated by checking +** the 'change-counter' field of the database file header and +** discarded if they are found to be invalid. +** +** 2) If the pager is running in exclusive-mode, and there are currently +** no outstanding references to any pages, and is in the error state, +** then an attempt is made to clear the error state by discarding +** the contents of the page cache and rolling back any open journal +** file. +** +** If everything is successful, SQLITE_OK is returned. If an IO error +** occurs while locking the database, checking for a hot-journal file or +** rolling back a journal file, the IO error code is returned. +*/ +SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){ + int rc = SQLITE_OK; /* Return code */ + + /* This routine is only called from b-tree and only when there are no + ** outstanding pages. This implies that the pager state should either + ** be OPEN or READER. READER is only possible if the pager is or was in + ** exclusive access mode. */ + assert( sqlite3PcacheRefCount(pPager->pPCache)==0 ); + assert( assert_pager_state(pPager) ); + assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER ); + assert( pPager->errCode==SQLITE_OK ); + + if( !pagerUseWal(pPager) && pPager->eState==PAGER_OPEN ){ + int bHotJournal = 1; /* True if there exists a hot journal-file */ + + assert( !MEMDB ); + assert( pPager->tempFile==0 || pPager->eLock==EXCLUSIVE_LOCK ); + + rc = pager_wait_on_lock(pPager, SHARED_LOCK); + if( rc!=SQLITE_OK ){ + assert( pPager->eLock==NO_LOCK || pPager->eLock==UNKNOWN_LOCK ); + goto failed; + } + + /* If a journal file exists, and there is no RESERVED lock on the + ** database file, then it either needs to be played back or deleted. + */ + if( pPager->eLock<=SHARED_LOCK ){ + rc = hasHotJournal(pPager, &bHotJournal); + } + if( rc!=SQLITE_OK ){ + goto failed; + } + if( bHotJournal ){ + if( pPager->readOnly ){ + rc = SQLITE_READONLY_ROLLBACK; + goto failed; + } + + /* Get an EXCLUSIVE lock on the database file. At this point it is + ** important that a RESERVED lock is not obtained on the way to the + ** EXCLUSIVE lock. If it were, another process might open the + ** database file, detect the RESERVED lock, and conclude that the + ** database is safe to read while this process is still rolling the + ** hot-journal back. + ** + ** Because the intermediate RESERVED lock is not requested, any + ** other process attempting to access the database file will get to + ** this point in the code and fail to obtain its own EXCLUSIVE lock + ** on the database file. + ** + ** Unless the pager is in locking_mode=exclusive mode, the lock is + ** downgraded to SHARED_LOCK before this function returns. + */ + rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); + if( rc!=SQLITE_OK ){ + goto failed; + } + + /* If it is not already open and the file exists on disk, open the + ** journal for read/write access. Write access is required because + ** in exclusive-access mode the file descriptor will be kept open + ** and possibly used for a transaction later on. Also, write-access + ** is usually required to finalize the journal in journal_mode=persist + ** mode (and also for journal_mode=truncate on some systems). + ** + ** If the journal does not exist, it usually means that some + ** other connection managed to get in and roll it back before + ** this connection obtained the exclusive lock above. Or, it + ** may mean that the pager was in the error-state when this + ** function was called and the journal file does not exist. + */ + if( !isOpen(pPager->jfd) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ + sqlite3_vfs * const pVfs = pPager->pVfs; + int bExists; /* True if journal file exists */ + rc = sqlite3OsAccess( + pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &bExists); + if( rc==SQLITE_OK && bExists ){ + int fout = 0; + int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL; + assert( !pPager->tempFile ); + rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout); + assert( rc!=SQLITE_OK || isOpen(pPager->jfd) ); + if( rc==SQLITE_OK && fout&SQLITE_OPEN_READONLY ){ + rc = SQLITE_CANTOPEN_BKPT; + sqlite3OsClose(pPager->jfd); + } + } + } + + /* Playback and delete the journal. Drop the database write + ** lock and reacquire the read lock. Purge the cache before + ** playing back the hot-journal so that we don't end up with + ** an inconsistent cache. Sync the hot journal before playing + ** it back since the process that crashed and left the hot journal + ** probably did not sync it and we are required to always sync + ** the journal before playing it back. + */ + if( isOpen(pPager->jfd) ){ + assert( rc==SQLITE_OK ); + rc = pagerSyncHotJournal(pPager); + if( rc==SQLITE_OK ){ + rc = pager_playback(pPager, !pPager->tempFile); + pPager->eState = PAGER_OPEN; + } + }else if( !pPager->exclusiveMode ){ + pagerUnlockDb(pPager, SHARED_LOCK); + } + + if( rc!=SQLITE_OK ){ + /* This branch is taken if an error occurs while trying to open + ** or roll back a hot-journal while holding an EXCLUSIVE lock. The + ** pager_unlock() routine will be called before returning to unlock + ** the file. If the unlock attempt fails, then Pager.eLock must be + ** set to UNKNOWN_LOCK (see the comment above the #define for + ** UNKNOWN_LOCK above for an explanation). + ** + ** In order to get pager_unlock() to do this, set Pager.eState to + ** PAGER_ERROR now. This is not actually counted as a transition + ** to ERROR state in the state diagram at the top of this file, + ** since we know that the same call to pager_unlock() will very + ** shortly transition the pager object to the OPEN state. Calling + ** assert_pager_state() would fail now, as it should not be possible + ** to be in ERROR state when there are zero outstanding page + ** references. + */ + pager_error(pPager, rc); + goto failed; + } + + assert( pPager->eState==PAGER_OPEN ); + assert( (pPager->eLock==SHARED_LOCK) + || (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK) + ); + } + + if( !pPager->tempFile && pPager->hasHeldSharedLock ){ + /* The shared-lock has just been acquired then check to + ** see if the database has been modified. If the database has changed, + ** flush the cache. The hasHeldSharedLock flag prevents this from + ** occurring on the very first access to a file, in order to save a + ** single unnecessary sqlite3OsRead() call at the start-up. + ** + ** Database changes are detected by looking at 15 bytes beginning + ** at offset 24 into the file. The first 4 of these 16 bytes are + ** a 32-bit counter that is incremented with each change. The + ** other bytes change randomly with each file change when + ** a codec is in use. + ** + ** There is a vanishingly small chance that a change will not be + ** detected. The chance of an undetected change is so small that + ** it can be neglected. + */ + char dbFileVers[sizeof(pPager->dbFileVers)]; + + IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers))); + rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24); + if( rc!=SQLITE_OK ){ + if( rc!=SQLITE_IOERR_SHORT_READ ){ + goto failed; + } + memset(dbFileVers, 0, sizeof(dbFileVers)); + } + + if( memcmp(pPager->dbFileVers, dbFileVers, sizeof(dbFileVers))!=0 ){ + pager_reset(pPager); + + /* Unmap the database file. It is possible that external processes + ** may have truncated the database file and then extended it back + ** to its original size while this process was not holding a lock. + ** In this case there may exist a Pager.pMap mapping that appears + ** to be the right size but is not actually valid. Avoid this + ** possibility by unmapping the db here. */ + if( USEFETCH(pPager) ){ + sqlite3OsUnfetch(pPager->fd, 0, 0); + } + } + } + + /* If there is a WAL file in the file-system, open this database in WAL + ** mode. Otherwise, the following function call is a no-op. + */ + rc = pagerOpenWalIfPresent(pPager); +#ifndef SQLITE_OMIT_WAL + assert( pPager->pWal==0 || rc==SQLITE_OK ); +#endif + } + + if( pagerUseWal(pPager) ){ + assert( rc==SQLITE_OK ); + rc = pagerBeginReadTransaction(pPager); + } + + if( pPager->tempFile==0 && pPager->eState==PAGER_OPEN && rc==SQLITE_OK ){ + rc = pagerPagecount(pPager, &pPager->dbSize); + } + + failed: + if( rc!=SQLITE_OK ){ + assert( !MEMDB ); + pager_unlock(pPager); + assert( pPager->eState==PAGER_OPEN ); + }else{ + pPager->eState = PAGER_READER; + pPager->hasHeldSharedLock = 1; + } + return rc; +} + +/* +** If the reference count has reached zero, rollback any active +** transaction and unlock the pager. +** +** Except, in locking_mode=EXCLUSIVE when there is nothing to in +** the rollback journal, the unlock is not performed and there is +** nothing to rollback, so this routine is a no-op. +*/ +static void pagerUnlockIfUnused(Pager *pPager){ + if( sqlite3PcacheRefCount(pPager->pPCache)==0 ){ + assert( pPager->nMmapOut==0 ); /* because page1 is never memory mapped */ + pagerUnlockAndRollback(pPager); + } +} + +/* +** The page getter methods each try to acquire a reference to a +** page with page number pgno. If the requested reference is +** successfully obtained, it is copied to *ppPage and SQLITE_OK returned. +** +** There are different implementations of the getter method depending +** on the current state of the pager. +** +** getPageNormal() -- The normal getter +** getPageError() -- Used if the pager is in an error state +** getPageMmap() -- Used if memory-mapped I/O is enabled +** +** If the requested page is already in the cache, it is returned. +** Otherwise, a new page object is allocated and populated with data +** read from the database file. In some cases, the pcache module may +** choose not to allocate a new page object and may reuse an existing +** object with no outstanding references. +** +** The extra data appended to a page is always initialized to zeros the +** first time a page is loaded into memory. If the page requested is +** already in the cache when this function is called, then the extra +** data is left as it was when the page object was last used. +** +** If the database image is smaller than the requested page or if +** the flags parameter contains the PAGER_GET_NOCONTENT bit and the +** requested page is not already stored in the cache, then no +** actual disk read occurs. In this case the memory image of the +** page is initialized to all zeros. +** +** If PAGER_GET_NOCONTENT is true, it means that we do not care about +** the contents of the page. This occurs in two scenarios: +** +** a) When reading a free-list leaf page from the database, and +** +** b) When a savepoint is being rolled back and we need to load +** a new page into the cache to be filled with the data read +** from the savepoint journal. +** +** If PAGER_GET_NOCONTENT is true, then the data returned is zeroed instead +** of being read from the database. Additionally, the bits corresponding +** to pgno in Pager.pInJournal (bitvec of pages already written to the +** journal file) and the PagerSavepoint.pInSavepoint bitvecs of any open +** savepoints are set. This means if the page is made writable at any +** point in the future, using a call to sqlite3PagerWrite(), its contents +** will not be journaled. This saves IO. +** +** The acquisition might fail for several reasons. In all cases, +** an appropriate error code is returned and *ppPage is set to NULL. +** +** See also sqlite3PagerLookup(). Both this routine and Lookup() attempt +** to find a page in the in-memory cache first. If the page is not already +** in memory, this routine goes to disk to read it in whereas Lookup() +** just returns 0. This routine acquires a read-lock the first time it +** has to go to disk, and could also playback an old journal if necessary. +** Since Lookup() never goes to disk, it never has to deal with locks +** or journal files. +*/ +static int getPageNormal( + Pager *pPager, /* The pager open on the database file */ + Pgno pgno, /* Page number to fetch */ + DbPage **ppPage, /* Write a pointer to the page here */ + int flags /* PAGER_GET_XXX flags */ +){ + int rc = SQLITE_OK; + PgHdr *pPg; + u8 noContent; /* True if PAGER_GET_NOCONTENT is set */ + sqlite3_pcache_page *pBase; + + assert( pPager->errCode==SQLITE_OK ); + assert( pPager->eState>=PAGER_READER ); + assert( assert_pager_state(pPager) ); + assert( pPager->hasHeldSharedLock==1 ); + + if( pgno==0 ) return SQLITE_CORRUPT_BKPT; + pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3); + if( pBase==0 ){ + pPg = 0; + rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase); + if( rc!=SQLITE_OK ) goto pager_acquire_err; + if( pBase==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto pager_acquire_err; + } + } + pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase); + assert( pPg==(*ppPage) ); + assert( pPg->pgno==pgno ); + assert( pPg->pPager==pPager || pPg->pPager==0 ); + + noContent = (flags & PAGER_GET_NOCONTENT)!=0; + if( pPg->pPager && !noContent ){ + /* In this case the pcache already contains an initialized copy of + ** the page. Return without further ado. */ + assert( pgno!=PAGER_SJ_PGNO(pPager) ); + pPager->aStat[PAGER_STAT_HIT]++; + return SQLITE_OK; + + }else{ + /* The pager cache has created a new page. Its content needs to + ** be initialized. But first some error checks: + ** + ** (*) obsolete. Was: maximum page number is 2^31 + ** (2) Never try to fetch the locking page + */ + if( pgno==PAGER_SJ_PGNO(pPager) ){ + rc = SQLITE_CORRUPT_BKPT; + goto pager_acquire_err; + } + + pPg->pPager = pPager; + + assert( !isOpen(pPager->fd) || !MEMDB ); + if( !isOpen(pPager->fd) || pPager->dbSizepPager->mxPgno ){ + rc = SQLITE_FULL; + if( pgno<=pPager->dbSize ){ + sqlite3PcacheRelease(pPg); + pPg = 0; + } + goto pager_acquire_err; + } + if( noContent ){ + /* Failure to set the bits in the InJournal bit-vectors is benign. + ** It merely means that we might do some extra work to journal a + ** page that does not need to be journaled. Nevertheless, be sure + ** to test the case where a malloc error occurs while trying to set + ** a bit in a bit vector. + */ + sqlite3BeginBenignMalloc(); + if( pgno<=pPager->dbOrigSize ){ + TESTONLY( rc = ) sqlite3BitvecSet(pPager->pInJournal, pgno); + testcase( rc==SQLITE_NOMEM ); + } + TESTONLY( rc = ) addToSavepointBitvecs(pPager, pgno); + testcase( rc==SQLITE_NOMEM ); + sqlite3EndBenignMalloc(); + } + memset(pPg->pData, 0, pPager->pageSize); + IOTRACE(("ZERO %p %d\n", pPager, pgno)); + }else{ + assert( pPg->pPager==pPager ); + pPager->aStat[PAGER_STAT_MISS]++; + rc = readDbPage(pPg); + if( rc!=SQLITE_OK ){ + goto pager_acquire_err; + } + } + pager_set_pagehash(pPg); + } + return SQLITE_OK; + +pager_acquire_err: + assert( rc!=SQLITE_OK ); + if( pPg ){ + sqlite3PcacheDrop(pPg); + } + pagerUnlockIfUnused(pPager); + *ppPage = 0; + return rc; +} + +#if SQLITE_MAX_MMAP_SIZE>0 +/* The page getter for when memory-mapped I/O is enabled */ +static int getPageMMap( + Pager *pPager, /* The pager open on the database file */ + Pgno pgno, /* Page number to fetch */ + DbPage **ppPage, /* Write a pointer to the page here */ + int flags /* PAGER_GET_XXX flags */ +){ + int rc = SQLITE_OK; + PgHdr *pPg = 0; + u32 iFrame = 0; /* Frame to read from WAL file */ + + /* It is acceptable to use a read-only (mmap) page for any page except + ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY + ** flag was specified by the caller. And so long as the db is not a + ** temporary or in-memory database. */ + const int bMmapOk = (pgno>1 + && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY)) + ); + + assert( USEFETCH(pPager) ); + + /* Optimization note: Adding the "pgno<=1" term before "pgno==0" here + ** allows the compiler optimizer to reuse the results of the "pgno>1" + ** test in the previous statement, and avoid testing pgno==0 in the + ** common case where pgno is large. */ + if( pgno<=1 && pgno==0 ){ + return SQLITE_CORRUPT_BKPT; + } + assert( pPager->eState>=PAGER_READER ); + assert( assert_pager_state(pPager) ); + assert( pPager->hasHeldSharedLock==1 ); + assert( pPager->errCode==SQLITE_OK ); + + if( bMmapOk && pagerUseWal(pPager) ){ + rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); + if( rc!=SQLITE_OK ){ + *ppPage = 0; + return rc; + } + } + if( bMmapOk && iFrame==0 ){ + void *pData = 0; + rc = sqlite3OsFetch(pPager->fd, + (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData + ); + if( rc==SQLITE_OK && pData ){ + if( pPager->eState>PAGER_READER || pPager->tempFile ){ + pPg = sqlite3PagerLookup(pPager, pgno); + } + if( pPg==0 ){ + rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg); + }else{ + sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData); + } + if( pPg ){ + assert( rc==SQLITE_OK ); + *ppPage = pPg; + return SQLITE_OK; + } + } + if( rc!=SQLITE_OK ){ + *ppPage = 0; + return rc; + } + } + return getPageNormal(pPager, pgno, ppPage, flags); +} +#endif /* SQLITE_MAX_MMAP_SIZE>0 */ + +/* The page getter method for when the pager is an error state */ +static int getPageError( + Pager *pPager, /* The pager open on the database file */ + Pgno pgno, /* Page number to fetch */ + DbPage **ppPage, /* Write a pointer to the page here */ + int flags /* PAGER_GET_XXX flags */ +){ + UNUSED_PARAMETER(pgno); + UNUSED_PARAMETER(flags); + assert( pPager->errCode!=SQLITE_OK ); + *ppPage = 0; + return pPager->errCode; +} + + +/* Dispatch all page fetch requests to the appropriate getter method. +*/ +SQLITE_PRIVATE int sqlite3PagerGet( + Pager *pPager, /* The pager open on the database file */ + Pgno pgno, /* Page number to fetch */ + DbPage **ppPage, /* Write a pointer to the page here */ + int flags /* PAGER_GET_XXX flags */ +){ +#if 0 /* Trace page fetch by setting to 1 */ + int rc; + printf("PAGE %u\n", pgno); + fflush(stdout); + rc = pPager->xGet(pPager, pgno, ppPage, flags); + if( rc ){ + printf("PAGE %u failed with 0x%02x\n", pgno, rc); + fflush(stdout); + } + return rc; +#else + /* Normal, high-speed version of sqlite3PagerGet() */ + return pPager->xGet(pPager, pgno, ppPage, flags); +#endif +} + +/* +** Acquire a page if it is already in the in-memory cache. Do +** not read the page from disk. Return a pointer to the page, +** or 0 if the page is not in cache. +** +** See also sqlite3PagerGet(). The difference between this routine +** and sqlite3PagerGet() is that _get() will go to the disk and read +** in the page if the page is not already in cache. This routine +** returns NULL if the page is not in cache or if a disk I/O error +** has ever happened. +*/ +SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){ + sqlite3_pcache_page *pPage; + assert( pPager!=0 ); + assert( pgno!=0 ); + assert( pPager->pPCache!=0 ); + pPage = sqlite3PcacheFetch(pPager->pPCache, pgno, 0); + assert( pPage==0 || pPager->hasHeldSharedLock ); + if( pPage==0 ) return 0; + return sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pPage); +} + +/* +** Release a page reference. +** +** The sqlite3PagerUnref() and sqlite3PagerUnrefNotNull() may only be used +** if we know that the page being released is not the last reference to page1. +** The btree layer always holds page1 open until the end, so these first +** two routines can be used to release any page other than BtShared.pPage1. +** The assert() at tag-20230419-2 proves that this constraint is always +** honored. +** +** Use sqlite3PagerUnrefPageOne() to release page1. This latter routine +** checks the total number of outstanding pages and if the number of +** pages reaches zero it drops the database lock. +*/ +SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage *pPg){ + TESTONLY( Pager *pPager = pPg->pPager; ) + assert( pPg!=0 ); + if( pPg->flags & PGHDR_MMAP ){ + assert( pPg->pgno!=1 ); /* Page1 is never memory mapped */ + pagerReleaseMapPage(pPg); + }else{ + sqlite3PcacheRelease(pPg); + } + /* Do not use this routine to release the last reference to page1 */ + assert( sqlite3PcacheRefCount(pPager->pPCache)>0 ); /* tag-20230419-2 */ +} +SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){ + if( pPg ) sqlite3PagerUnrefNotNull(pPg); +} +SQLITE_PRIVATE void sqlite3PagerUnrefPageOne(DbPage *pPg){ + Pager *pPager; + assert( pPg!=0 ); + assert( pPg->pgno==1 ); + assert( (pPg->flags & PGHDR_MMAP)==0 ); /* Page1 is never memory mapped */ + pPager = pPg->pPager; + sqlite3PcacheRelease(pPg); + pagerUnlockIfUnused(pPager); +} + +/* +** This function is called at the start of every write transaction. +** There must already be a RESERVED or EXCLUSIVE lock on the database +** file when this routine is called. +** +** Open the journal file for pager pPager and write a journal header +** to the start of it. If there are active savepoints, open the sub-journal +** as well. This function is only used when the journal file is being +** opened to write a rollback log for a transaction. It is not used +** when opening a hot journal file to roll it back. +** +** If the journal file is already open (as it may be in exclusive mode), +** then this function just writes a journal header to the start of the +** already open file. +** +** Whether or not the journal file is opened by this function, the +** Pager.pInJournal bitvec structure is allocated. +** +** Return SQLITE_OK if everything is successful. Otherwise, return +** SQLITE_NOMEM if the attempt to allocate Pager.pInJournal fails, or +** an IO error code if opening or writing the journal file fails. +*/ +static int pager_open_journal(Pager *pPager){ + int rc = SQLITE_OK; /* Return code */ + sqlite3_vfs * const pVfs = pPager->pVfs; /* Local cache of vfs pointer */ + + assert( pPager->eState==PAGER_WRITER_LOCKED ); + assert( assert_pager_state(pPager) ); + assert( pPager->pInJournal==0 ); + + /* If already in the error state, this function is a no-op. But on + ** the other hand, this routine is never called if we are already in + ** an error state. */ + if( NEVER(pPager->errCode) ) return pPager->errCode; + + if( !pagerUseWal(pPager) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ + pPager->pInJournal = sqlite3BitvecCreate(pPager->dbSize); + if( pPager->pInJournal==0 ){ + return SQLITE_NOMEM_BKPT; + } + + /* Open the journal file if it is not already open. */ + if( !isOpen(pPager->jfd) ){ + if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){ + sqlite3MemJournalOpen(pPager->jfd); + }else{ + int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE; + int nSpill; + + if( pPager->tempFile ){ + flags |= (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL); + flags |= SQLITE_OPEN_EXCLUSIVE; + nSpill = sqlite3Config.nStmtSpill; + }else{ + flags |= SQLITE_OPEN_MAIN_JOURNAL; + nSpill = jrnlBufferSize(pPager); + } + + /* Verify that the database still has the same name as it did when + ** it was originally opened. */ + rc = databaseIsUnmoved(pPager); + if( rc==SQLITE_OK ){ + rc = sqlite3JournalOpen ( + pVfs, pPager->zJournal, pPager->jfd, flags, nSpill + ); + } + } + assert( rc!=SQLITE_OK || isOpen(pPager->jfd) ); + } + + + /* Write the first journal header to the journal file and open + ** the sub-journal if necessary. + */ + if( rc==SQLITE_OK ){ + /* TODO: Check if all of these are really required. */ + pPager->nRec = 0; + pPager->journalOff = 0; + pPager->setSuper = 0; + pPager->journalHdr = 0; + rc = writeJournalHdr(pPager); + } + } + + if( rc!=SQLITE_OK ){ + sqlite3BitvecDestroy(pPager->pInJournal); + pPager->pInJournal = 0; + pPager->journalOff = 0; + }else{ + assert( pPager->eState==PAGER_WRITER_LOCKED ); + pPager->eState = PAGER_WRITER_CACHEMOD; + } + + return rc; +} + +/* +** Begin a write-transaction on the specified pager object. If a +** write-transaction has already been opened, this function is a no-op. +** +** If the exFlag argument is false, then acquire at least a RESERVED +** lock on the database file. If exFlag is true, then acquire at least +** an EXCLUSIVE lock. If such a lock is already held, no locking +** functions need be called. +** +** If the subjInMemory argument is non-zero, then any sub-journal opened +** within this transaction will be opened as an in-memory file. This +** has no effect if the sub-journal is already opened (as it may be when +** running in exclusive mode) or if the transaction does not require a +** sub-journal. If the subjInMemory argument is zero, then any required +** sub-journal is implemented in-memory if pPager is an in-memory database, +** or using a temporary file otherwise. +*/ +SQLITE_PRIVATE int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory){ + int rc = SQLITE_OK; + + if( pPager->errCode ) return pPager->errCode; + assert( pPager->eState>=PAGER_READER && pPager->eStatesubjInMemory = (u8)subjInMemory; + + if( pPager->eState==PAGER_READER ){ + assert( pPager->pInJournal==0 ); + + if( pagerUseWal(pPager) ){ + /* If the pager is configured to use locking_mode=exclusive, and an + ** exclusive lock on the database is not already held, obtain it now. + */ + if( pPager->exclusiveMode && sqlite3WalExclusiveMode(pPager->pWal, -1) ){ + rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); + if( rc!=SQLITE_OK ){ + return rc; + } + (void)sqlite3WalExclusiveMode(pPager->pWal, 1); + } + + /* Grab the write lock on the log file. If successful, upgrade to + ** PAGER_RESERVED state. Otherwise, return an error code to the caller. + ** The busy-handler is not invoked if another connection already + ** holds the write-lock. If possible, the upper layer will call it. + */ + rc = sqlite3WalBeginWriteTransaction(pPager->pWal); + }else{ + /* Obtain a RESERVED lock on the database file. If the exFlag parameter + ** is true, then immediately upgrade this to an EXCLUSIVE lock. The + ** busy-handler callback can be used when upgrading to the EXCLUSIVE + ** lock, but not when obtaining the RESERVED lock. + */ + rc = pagerLockDb(pPager, RESERVED_LOCK); + if( rc==SQLITE_OK && exFlag ){ + rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); + } + } + + if( rc==SQLITE_OK ){ + /* Change to WRITER_LOCKED state. + ** + ** WAL mode sets Pager.eState to PAGER_WRITER_LOCKED or CACHEMOD + ** when it has an open transaction, but never to DBMOD or FINISHED. + ** This is because in those states the code to roll back savepoint + ** transactions may copy data from the sub-journal into the database + ** file as well as into the page cache. Which would be incorrect in + ** WAL mode. + */ + pPager->eState = PAGER_WRITER_LOCKED; + pPager->dbHintSize = pPager->dbSize; + pPager->dbFileSize = pPager->dbSize; + pPager->dbOrigSize = pPager->dbSize; + pPager->journalOff = 0; + } + + assert( rc==SQLITE_OK || pPager->eState==PAGER_READER ); + assert( rc!=SQLITE_OK || pPager->eState==PAGER_WRITER_LOCKED ); + assert( assert_pager_state(pPager) ); + } + + PAGERTRACE(("TRANSACTION %d\n", PAGERID(pPager))); + return rc; +} + +/* +** Write page pPg onto the end of the rollback journal. +*/ +static SQLITE_NOINLINE int pagerAddPageToRollbackJournal(PgHdr *pPg){ + Pager *pPager = pPg->pPager; + int rc; + u32 cksum; + char *pData2; + i64 iOff = pPager->journalOff; + + /* We should never write to the journal file the page that + ** contains the database locks. The following assert verifies + ** that we do not. */ + assert( pPg->pgno!=PAGER_SJ_PGNO(pPager) ); + + assert( pPager->journalHdr<=pPager->journalOff ); + pData2 = pPg->pData; + cksum = pager_cksum(pPager, (u8*)pData2); + + /* Even if an IO or diskfull error occurs while journalling the + ** page in the block above, set the need-sync flag for the page. + ** Otherwise, when the transaction is rolled back, the logic in + ** playback_one_page() will think that the page needs to be restored + ** in the database file. And if an IO error occurs while doing so, + ** then corruption may follow. + */ + pPg->flags |= PGHDR_NEED_SYNC; + + rc = write32bits(pPager->jfd, iOff, pPg->pgno); + if( rc!=SQLITE_OK ) return rc; + rc = sqlite3OsWrite(pPager->jfd, pData2, pPager->pageSize, iOff+4); + if( rc!=SQLITE_OK ) return rc; + rc = write32bits(pPager->jfd, iOff+pPager->pageSize+4, cksum); + if( rc!=SQLITE_OK ) return rc; + + IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno, + pPager->journalOff, pPager->pageSize)); + PAGER_INCR(sqlite3_pager_writej_count); + PAGERTRACE(("JOURNAL %d page %d needSync=%d hash(%08x)\n", + PAGERID(pPager), pPg->pgno, + ((pPg->flags&PGHDR_NEED_SYNC)?1:0), pager_pagehash(pPg))); + + pPager->journalOff += 8 + pPager->pageSize; + pPager->nRec++; + assert( pPager->pInJournal!=0 ); + rc = sqlite3BitvecSet(pPager->pInJournal, pPg->pgno); + testcase( rc==SQLITE_NOMEM ); + assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); + rc |= addToSavepointBitvecs(pPager, pPg->pgno); + assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); + return rc; +} + +/* +** Mark a single data page as writeable. The page is written into the +** main journal or sub-journal as required. If the page is written into +** one of the journals, the corresponding bit is set in the +** Pager.pInJournal bitvec and the PagerSavepoint.pInSavepoint bitvecs +** of any open savepoints as appropriate. +*/ +static int pager_write(PgHdr *pPg){ + Pager *pPager = pPg->pPager; + int rc = SQLITE_OK; + + /* This routine is not called unless a write-transaction has already + ** been started. The journal file may or may not be open at this point. + ** It is never called in the ERROR state. + */ + assert( pPager->eState==PAGER_WRITER_LOCKED + || pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + ); + assert( assert_pager_state(pPager) ); + assert( pPager->errCode==0 ); + assert( pPager->readOnly==0 ); + CHECK_PAGE(pPg); + + /* The journal file needs to be opened. Higher level routines have already + ** obtained the necessary locks to begin the write-transaction, but the + ** rollback journal might not yet be open. Open it now if this is the case. + ** + ** This is done before calling sqlite3PcacheMakeDirty() on the page. + ** Otherwise, if it were done after calling sqlite3PcacheMakeDirty(), then + ** an error might occur and the pager would end up in WRITER_LOCKED state + ** with pages marked as dirty in the cache. + */ + if( pPager->eState==PAGER_WRITER_LOCKED ){ + rc = pager_open_journal(pPager); + if( rc!=SQLITE_OK ) return rc; + } + assert( pPager->eState>=PAGER_WRITER_CACHEMOD ); + assert( assert_pager_state(pPager) ); + + /* Mark the page that is about to be modified as dirty. */ + sqlite3PcacheMakeDirty(pPg); + + /* If a rollback journal is in use, them make sure the page that is about + ** to change is in the rollback journal, or if the page is a new page off + ** then end of the file, make sure it is marked as PGHDR_NEED_SYNC. + */ + assert( (pPager->pInJournal!=0) == isOpen(pPager->jfd) ); + if( pPager->pInJournal!=0 + && sqlite3BitvecTestNotNull(pPager->pInJournal, pPg->pgno)==0 + ){ + assert( pagerUseWal(pPager)==0 ); + if( pPg->pgno<=pPager->dbOrigSize ){ + rc = pagerAddPageToRollbackJournal(pPg); + if( rc!=SQLITE_OK ){ + return rc; + } + }else{ + if( pPager->eState!=PAGER_WRITER_DBMOD ){ + pPg->flags |= PGHDR_NEED_SYNC; + } + PAGERTRACE(("APPEND %d page %d needSync=%d\n", + PAGERID(pPager), pPg->pgno, + ((pPg->flags&PGHDR_NEED_SYNC)?1:0))); + } + } + + /* The PGHDR_DIRTY bit is set above when the page was added to the dirty-list + ** and before writing the page into the rollback journal. Wait until now, + ** after the page has been successfully journalled, before setting the + ** PGHDR_WRITEABLE bit that indicates that the page can be safely modified. + */ + pPg->flags |= PGHDR_WRITEABLE; + + /* If the statement journal is open and the page is not in it, + ** then write the page into the statement journal. + */ + if( pPager->nSavepoint>0 ){ + rc = subjournalPageIfRequired(pPg); + } + + /* Update the database size and return. */ + if( pPager->dbSizepgno ){ + pPager->dbSize = pPg->pgno; + } + return rc; +} + +/* +** This is a variant of sqlite3PagerWrite() that runs when the sector size +** is larger than the page size. SQLite makes the (reasonable) assumption that +** all bytes of a sector are written together by hardware. Hence, all bytes of +** a sector need to be journalled in case of a power loss in the middle of +** a write. +** +** Usually, the sector size is less than or equal to the page size, in which +** case pages can be individually written. This routine only runs in the +** exceptional case where the page size is smaller than the sector size. +*/ +static SQLITE_NOINLINE int pagerWriteLargeSector(PgHdr *pPg){ + int rc = SQLITE_OK; /* Return code */ + Pgno nPageCount; /* Total number of pages in database file */ + Pgno pg1; /* First page of the sector pPg is located on. */ + int nPage = 0; /* Number of pages starting at pg1 to journal */ + int ii; /* Loop counter */ + int needSync = 0; /* True if any page has PGHDR_NEED_SYNC */ + Pager *pPager = pPg->pPager; /* The pager that owns pPg */ + Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize); + + /* Set the doNotSpill NOSYNC bit to 1. This is because we cannot allow + ** a journal header to be written between the pages journaled by + ** this function. + */ + assert( !MEMDB ); + assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)==0 ); + pPager->doNotSpill |= SPILLFLAG_NOSYNC; + + /* This trick assumes that both the page-size and sector-size are + ** an integer power of 2. It sets variable pg1 to the identifier + ** of the first page of the sector pPg is located on. + */ + pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1; + + nPageCount = pPager->dbSize; + if( pPg->pgno>nPageCount ){ + nPage = (pPg->pgno - pg1)+1; + }else if( (pg1+nPagePerSector-1)>nPageCount ){ + nPage = nPageCount+1-pg1; + }else{ + nPage = nPagePerSector; + } + assert(nPage>0); + assert(pg1<=pPg->pgno); + assert((pg1+nPage)>pPg->pgno); + + for(ii=0; iipgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){ + if( pg!=PAGER_SJ_PGNO(pPager) ){ + rc = sqlite3PagerGet(pPager, pg, &pPage, 0); + if( rc==SQLITE_OK ){ + rc = pager_write(pPage); + if( pPage->flags&PGHDR_NEED_SYNC ){ + needSync = 1; + } + sqlite3PagerUnrefNotNull(pPage); + } + } + }else if( (pPage = sqlite3PagerLookup(pPager, pg))!=0 ){ + if( pPage->flags&PGHDR_NEED_SYNC ){ + needSync = 1; + } + sqlite3PagerUnrefNotNull(pPage); + } + } + + /* If the PGHDR_NEED_SYNC flag is set for any of the nPage pages + ** starting at pg1, then it needs to be set for all of them. Because + ** writing to any of these nPage pages may damage the others, the + ** journal file must contain sync()ed copies of all of them + ** before any of them can be written out to the database file. + */ + if( rc==SQLITE_OK && needSync ){ + assert( !MEMDB ); + for(ii=0; iiflags |= PGHDR_NEED_SYNC; + sqlite3PagerUnrefNotNull(pPage); + } + } + } + + assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)!=0 ); + pPager->doNotSpill &= ~SPILLFLAG_NOSYNC; + return rc; +} + +/* +** Mark a data page as writeable. This routine must be called before +** making changes to a page. The caller must check the return value +** of this function and be careful not to change any page data unless +** this routine returns SQLITE_OK. +** +** The difference between this function and pager_write() is that this +** function also deals with the special case where 2 or more pages +** fit on a single disk sector. In this case all co-resident pages +** must have been written to the journal file before returning. +** +** If an error occurs, SQLITE_NOMEM or an IO error code is returned +** as appropriate. Otherwise, SQLITE_OK. +*/ +SQLITE_PRIVATE int sqlite3PagerWrite(PgHdr *pPg){ + Pager *pPager = pPg->pPager; + assert( (pPg->flags & PGHDR_MMAP)==0 ); + assert( pPager->eState>=PAGER_WRITER_LOCKED ); + assert( assert_pager_state(pPager) ); + if( (pPg->flags & PGHDR_WRITEABLE)!=0 && pPager->dbSize>=pPg->pgno ){ + if( pPager->nSavepoint ) return subjournalPageIfRequired(pPg); + return SQLITE_OK; + }else if( pPager->errCode ){ + return pPager->errCode; + }else if( pPager->sectorSize > (u32)pPager->pageSize ){ + assert( pPager->tempFile==0 ); + return pagerWriteLargeSector(pPg); + }else{ + return pager_write(pPg); + } +} + +/* +** Return TRUE if the page given in the argument was previously passed +** to sqlite3PagerWrite(). In other words, return TRUE if it is ok +** to change the content of the page. +*/ +#ifndef NDEBUG +SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage *pPg){ + return pPg->flags & PGHDR_WRITEABLE; +} +#endif + +/* +** A call to this routine tells the pager that it is not necessary to +** write the information on page pPg back to the disk, even though +** that page might be marked as dirty. This happens, for example, when +** the page has been added as a leaf of the freelist and so its +** content no longer matters. +** +** The overlying software layer calls this routine when all of the data +** on the given page is unused. The pager marks the page as clean so +** that it does not get written to disk. +** +** Tests show that this optimization can quadruple the speed of large +** DELETE operations. +** +** This optimization cannot be used with a temp-file, as the page may +** have been dirty at the start of the transaction. In that case, if +** memory pressure forces page pPg out of the cache, the data does need +** to be written out to disk so that it may be read back in if the +** current transaction is rolled back. +*/ +SQLITE_PRIVATE void sqlite3PagerDontWrite(PgHdr *pPg){ + Pager *pPager = pPg->pPager; + if( !pPager->tempFile && (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){ + PAGERTRACE(("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager))); + IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno)) + pPg->flags |= PGHDR_DONT_WRITE; + pPg->flags &= ~PGHDR_WRITEABLE; + testcase( pPg->flags & PGHDR_NEED_SYNC ); + pager_set_pagehash(pPg); + } +} + +/* +** This routine is called to increment the value of the database file +** change-counter, stored as a 4-byte big-endian integer starting at +** byte offset 24 of the pager file. The secondary change counter at +** 92 is also updated, as is the SQLite version number at offset 96. +** +** But this only happens if the pPager->changeCountDone flag is false. +** To avoid excess churning of page 1, the update only happens once. +** See also the pager_write_changecounter() routine that does an +** unconditional update of the change counters. +** +** If the isDirectMode flag is zero, then this is done by calling +** sqlite3PagerWrite() on page 1, then modifying the contents of the +** page data. In this case the file will be updated when the current +** transaction is committed. +** +** The isDirectMode flag may only be non-zero if the library was compiled +** with the SQLITE_ENABLE_ATOMIC_WRITE macro defined. In this case, +** if isDirect is non-zero, then the database file is updated directly +** by writing an updated version of page 1 using a call to the +** sqlite3OsWrite() function. +*/ +static int pager_incr_changecounter(Pager *pPager, int isDirectMode){ + int rc = SQLITE_OK; + + assert( pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + ); + assert( assert_pager_state(pPager) ); + + /* Declare and initialize constant integer 'isDirect'. If the + ** atomic-write optimization is enabled in this build, then isDirect + ** is initialized to the value passed as the isDirectMode parameter + ** to this function. Otherwise, it is always set to zero. + ** + ** The idea is that if the atomic-write optimization is not + ** enabled at compile time, the compiler can omit the tests of + ** 'isDirect' below, as well as the block enclosed in the + ** "if( isDirect )" condition. + */ +#ifndef SQLITE_ENABLE_ATOMIC_WRITE +# define DIRECT_MODE 0 + assert( isDirectMode==0 ); + UNUSED_PARAMETER(isDirectMode); +#else +# define DIRECT_MODE isDirectMode +#endif + + if( !pPager->changeCountDone && pPager->dbSize>0 ){ + PgHdr *pPgHdr; /* Reference to page 1 */ + + assert( !pPager->tempFile && isOpen(pPager->fd) ); + + /* Open page 1 of the file for writing. */ + rc = sqlite3PagerGet(pPager, 1, &pPgHdr, 0); + assert( pPgHdr==0 || rc==SQLITE_OK ); + + /* If page one was fetched successfully, and this function is not + ** operating in direct-mode, make page 1 writable. When not in + ** direct mode, page 1 is always held in cache and hence the PagerGet() + ** above is always successful - hence the ALWAYS on rc==SQLITE_OK. + */ + if( !DIRECT_MODE && ALWAYS(rc==SQLITE_OK) ){ + rc = sqlite3PagerWrite(pPgHdr); + } + + if( rc==SQLITE_OK ){ + /* Actually do the update of the change counter */ + pager_write_changecounter(pPgHdr); + + /* If running in direct mode, write the contents of page 1 to the file. */ + if( DIRECT_MODE ){ + const void *zBuf; + assert( pPager->dbFileSize>0 ); + zBuf = pPgHdr->pData; + if( rc==SQLITE_OK ){ + rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0); + pPager->aStat[PAGER_STAT_WRITE]++; + } + if( rc==SQLITE_OK ){ + /* Update the pager's copy of the change-counter. Otherwise, the + ** next time a read transaction is opened the cache will be + ** flushed (as the change-counter values will not match). */ + const void *pCopy = (const void *)&((const char *)zBuf)[24]; + memcpy(&pPager->dbFileVers, pCopy, sizeof(pPager->dbFileVers)); + pPager->changeCountDone = 1; + } + }else{ + pPager->changeCountDone = 1; + } + } + + /* Release the page reference. */ + sqlite3PagerUnref(pPgHdr); + } + return rc; +} + +/* +** Sync the database file to disk. This is a no-op for in-memory databases +** or pages with the Pager.noSync flag set. +** +** If successful, or if called on a pager for which it is a no-op, this +** function returns SQLITE_OK. Otherwise, an IO error code is returned. +*/ +SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager, const char *zSuper){ + int rc = SQLITE_OK; + void *pArg = (void*)zSuper; + rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC, pArg); + if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; + if( rc==SQLITE_OK && !pPager->noSync ){ + assert( !MEMDB ); + rc = sqlite3OsSync(pPager->fd, pPager->syncFlags); + } + return rc; +} + +/* +** This function may only be called while a write-transaction is active in +** rollback. If the connection is in WAL mode, this call is a no-op. +** Otherwise, if the connection does not already have an EXCLUSIVE lock on +** the database file, an attempt is made to obtain one. +** +** If the EXCLUSIVE lock is already held or the attempt to obtain it is +** successful, or the connection is in WAL mode, SQLITE_OK is returned. +** Otherwise, either SQLITE_BUSY or an SQLITE_IOERR_XXX error code is +** returned. +*/ +SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager *pPager){ + int rc = pPager->errCode; + assert( assert_pager_state(pPager) ); + if( rc==SQLITE_OK ){ + assert( pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + || pPager->eState==PAGER_WRITER_LOCKED + ); + assert( assert_pager_state(pPager) ); + if( 0==pagerUseWal(pPager) ){ + rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); + } + } + return rc; +} + +/* +** Sync the database file for the pager pPager. zSuper points to the name +** of a super-journal file that should be written into the individual +** journal file. zSuper may be NULL, which is interpreted as no +** super-journal (a single database transaction). +** +** This routine ensures that: +** +** * The database file change-counter is updated, +** * the journal is synced (unless the atomic-write optimization is used), +** * all dirty pages are written to the database file, +** * the database file is truncated (if required), and +** * the database file synced. +** +** The only thing that remains to commit the transaction is to finalize +** (delete, truncate or zero the first part of) the journal file (or +** delete the super-journal file if specified). +** +** Note that if zSuper==NULL, this does not overwrite a previous value +** passed to an sqlite3PagerCommitPhaseOne() call. +** +** If the final parameter - noSync - is true, then the database file itself +** is not synced. The caller must call sqlite3PagerSync() directly to +** sync the database file before calling CommitPhaseTwo() to delete the +** journal file in this case. +*/ +SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne( + Pager *pPager, /* Pager object */ + const char *zSuper, /* If not NULL, the super-journal name */ + int noSync /* True to omit the xSync on the db file */ +){ + int rc = SQLITE_OK; /* Return code */ + + assert( pPager->eState==PAGER_WRITER_LOCKED + || pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + || pPager->eState==PAGER_ERROR + ); + assert( assert_pager_state(pPager) ); + + /* If a prior error occurred, report that error again. */ + if( NEVER(pPager->errCode) ) return pPager->errCode; + + /* Provide the ability to easily simulate an I/O error during testing */ + if( sqlite3FaultSim(400) ) return SQLITE_IOERR; + + PAGERTRACE(("DATABASE SYNC: File=%s zSuper=%s nSize=%d\n", + pPager->zFilename, zSuper, pPager->dbSize)); + + /* If no database changes have been made, return early. */ + if( pPager->eStatetempFile ); + assert( isOpen(pPager->fd) || pPager->tempFile ); + if( 0==pagerFlushOnCommit(pPager, 1) ){ + /* If this is an in-memory db, or no pages have been written to, or this + ** function has already been called, it is mostly a no-op. However, any + ** backup in progress needs to be restarted. */ + sqlite3BackupRestart(pPager->pBackup); + }else{ + PgHdr *pList; + if( pagerUseWal(pPager) ){ + PgHdr *pPageOne = 0; + pList = sqlite3PcacheDirtyList(pPager->pPCache); + if( pList==0 ){ + /* Must have at least one page for the WAL commit flag. + ** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */ + rc = sqlite3PagerGet(pPager, 1, &pPageOne, 0); + pList = pPageOne; + pList->pDirty = 0; + } + assert( rc==SQLITE_OK ); + if( ALWAYS(pList) ){ + rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1); + } + sqlite3PagerUnref(pPageOne); + if( rc==SQLITE_OK ){ + sqlite3PcacheCleanAll(pPager->pPCache); + } + }else{ + /* The bBatch boolean is true if the batch-atomic-write commit method + ** should be used. No rollback journal is created if batch-atomic-write + ** is enabled. + */ +#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE + sqlite3_file *fd = pPager->fd; + int bBatch = zSuper==0 /* An SQLITE_IOCAP_BATCH_ATOMIC commit */ + && (sqlite3OsDeviceCharacteristics(fd) & SQLITE_IOCAP_BATCH_ATOMIC) + && !pPager->noSync + && sqlite3JournalIsInMemory(pPager->jfd); +#else +# define bBatch 0 +#endif + +#ifdef SQLITE_ENABLE_ATOMIC_WRITE + /* The following block updates the change-counter. Exactly how it + ** does this depends on whether or not the atomic-update optimization + ** was enabled at compile time, and if this transaction meets the + ** runtime criteria to use the operation: + ** + ** * The file-system supports the atomic-write property for + ** blocks of size page-size, and + ** * This commit is not part of a multi-file transaction, and + ** * Exactly one page has been modified and store in the journal file. + ** + ** If the optimization was not enabled at compile time, then the + ** pager_incr_changecounter() function is called to update the change + ** counter in 'indirect-mode'. If the optimization is compiled in but + ** is not applicable to this transaction, call sqlite3JournalCreate() + ** to make sure the journal file has actually been created, then call + ** pager_incr_changecounter() to update the change-counter in indirect + ** mode. + ** + ** Otherwise, if the optimization is both enabled and applicable, + ** then call pager_incr_changecounter() to update the change-counter + ** in 'direct' mode. In this case the journal file will never be + ** created for this transaction. + */ + if( bBatch==0 ){ + PgHdr *pPg; + assert( isOpen(pPager->jfd) + || pPager->journalMode==PAGER_JOURNALMODE_OFF + || pPager->journalMode==PAGER_JOURNALMODE_WAL + ); + if( !zSuper && isOpen(pPager->jfd) + && pPager->journalOff==jrnlBufferSize(pPager) + && pPager->dbSize>=pPager->dbOrigSize + && (!(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty) + ){ + /* Update the db file change counter via the direct-write method. The + ** following call will modify the in-memory representation of page 1 + ** to include the updated change counter and then write page 1 + ** directly to the database file. Because of the atomic-write + ** property of the host file-system, this is safe. + */ + rc = pager_incr_changecounter(pPager, 1); + }else{ + rc = sqlite3JournalCreate(pPager->jfd); + if( rc==SQLITE_OK ){ + rc = pager_incr_changecounter(pPager, 0); + } + } + } +#else /* SQLITE_ENABLE_ATOMIC_WRITE */ +#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE + if( zSuper ){ + rc = sqlite3JournalCreate(pPager->jfd); + if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + assert( bBatch==0 ); + } +#endif + rc = pager_incr_changecounter(pPager, 0); +#endif /* !SQLITE_ENABLE_ATOMIC_WRITE */ + if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + + /* Write the super-journal name into the journal file. If a + ** super-journal file name has already been written to the journal file, + ** or if zSuper is NULL (no super-journal), then this call is a no-op. + */ + rc = writeSuperJournal(pPager, zSuper); + if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + + /* Sync the journal file and write all dirty pages to the database. + ** If the atomic-update optimization is being used, this sync will not + ** create the journal file or perform any real IO. + ** + ** Because the change-counter page was just modified, unless the + ** atomic-update optimization is used it is almost certain that the + ** journal requires a sync here. However, in locking_mode=exclusive + ** on a system under memory pressure it is just possible that this is + ** not the case. In this case it is likely enough that the redundant + ** xSync() call will be changed to a no-op by the OS anyhow. + */ + rc = syncJournal(pPager, 0); + if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + + pList = sqlite3PcacheDirtyList(pPager->pPCache); +#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE + if( bBatch ){ + rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_BEGIN_ATOMIC_WRITE, 0); + if( rc==SQLITE_OK ){ + rc = pager_write_pagelist(pPager, pList); + if( rc==SQLITE_OK && pPager->dbSize>pPager->dbFileSize ){ + char *pTmp = pPager->pTmpSpace; + int szPage = (int)pPager->pageSize; + memset(pTmp, 0, szPage); + rc = sqlite3OsWrite(pPager->fd, pTmp, szPage, + ((i64)pPager->dbSize*pPager->pageSize)-szPage); + } + if( rc==SQLITE_OK ){ + rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_COMMIT_ATOMIC_WRITE, 0); + } + if( rc!=SQLITE_OK ){ + sqlite3OsFileControlHint(fd, SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE, 0); + } + } + + if( (rc&0xFF)==SQLITE_IOERR && rc!=SQLITE_IOERR_NOMEM ){ + rc = sqlite3JournalCreate(pPager->jfd); + if( rc!=SQLITE_OK ){ + sqlite3OsClose(pPager->jfd); + goto commit_phase_one_exit; + } + bBatch = 0; + }else{ + sqlite3OsClose(pPager->jfd); + } + } +#endif /* SQLITE_ENABLE_BATCH_ATOMIC_WRITE */ + + if( bBatch==0 ){ + rc = pager_write_pagelist(pPager, pList); + } + if( rc!=SQLITE_OK ){ + assert( rc!=SQLITE_IOERR_BLOCKED ); + goto commit_phase_one_exit; + } + sqlite3PcacheCleanAll(pPager->pPCache); + + /* If the file on disk is smaller than the database image, use + ** pager_truncate to grow the file here. This can happen if the database + ** image was extended as part of the current transaction and then the + ** last page in the db image moved to the free-list. In this case the + ** last page is never written out to disk, leaving the database file + ** undersized. Fix this now if it is the case. */ + if( pPager->dbSize>pPager->dbFileSize ){ + Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_SJ_PGNO(pPager)); + assert( pPager->eState==PAGER_WRITER_DBMOD ); + rc = pager_truncate(pPager, nNew); + if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + } + + /* Finally, sync the database file. */ + if( !noSync ){ + rc = sqlite3PagerSync(pPager, zSuper); + } + IOTRACE(("DBSYNC %p\n", pPager)) + } + } + +commit_phase_one_exit: + if( rc==SQLITE_OK && !pagerUseWal(pPager) ){ + pPager->eState = PAGER_WRITER_FINISHED; + } + return rc; +} + + +/* +** When this function is called, the database file has been completely +** updated to reflect the changes made by the current transaction and +** synced to disk. The journal file still exists in the file-system +** though, and if a failure occurs at this point it will eventually +** be used as a hot-journal and the current transaction rolled back. +** +** This function finalizes the journal file, either by deleting, +** truncating or partially zeroing it, so that it cannot be used +** for hot-journal rollback. Once this is done the transaction is +** irrevocably committed. +** +** If an error occurs, an IO error code is returned and the pager +** moves into the error state. Otherwise, SQLITE_OK is returned. +*/ +SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager *pPager){ + int rc = SQLITE_OK; /* Return code */ + + /* This routine should not be called if a prior error has occurred. + ** But if (due to a coding error elsewhere in the system) it does get + ** called, just return the same error code without doing anything. */ + if( NEVER(pPager->errCode) ) return pPager->errCode; + pPager->iDataVersion++; + + assert( pPager->eState==PAGER_WRITER_LOCKED + || pPager->eState==PAGER_WRITER_FINISHED + || (pagerUseWal(pPager) && pPager->eState==PAGER_WRITER_CACHEMOD) + ); + assert( assert_pager_state(pPager) ); + + /* An optimization. If the database was not actually modified during + ** this transaction, the pager is running in exclusive-mode and is + ** using persistent journals, then this function is a no-op. + ** + ** The start of the journal file currently contains a single journal + ** header with the nRec field set to 0. If such a journal is used as + ** a hot-journal during hot-journal rollback, 0 changes will be made + ** to the database file. So there is no need to zero the journal + ** header. Since the pager is in exclusive mode, there is no need + ** to drop any locks either. + */ + if( pPager->eState==PAGER_WRITER_LOCKED + && pPager->exclusiveMode + && pPager->journalMode==PAGER_JOURNALMODE_PERSIST + ){ + assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) || !pPager->journalOff ); + pPager->eState = PAGER_READER; + return SQLITE_OK; + } + + PAGERTRACE(("COMMIT %d\n", PAGERID(pPager))); + rc = pager_end_transaction(pPager, pPager->setSuper, 1); + return pager_error(pPager, rc); +} + +/* +** If a write transaction is open, then all changes made within the +** transaction are reverted and the current write-transaction is closed. +** The pager falls back to PAGER_READER state if successful, or PAGER_ERROR +** state if an error occurs. +** +** If the pager is already in PAGER_ERROR state when this function is called, +** it returns Pager.errCode immediately. No work is performed in this case. +** +** Otherwise, in rollback mode, this function performs two functions: +** +** 1) It rolls back the journal file, restoring all database file and +** in-memory cache pages to the state they were in when the transaction +** was opened, and +** +** 2) It finalizes the journal file, so that it is not used for hot +** rollback at any point in the future. +** +** Finalization of the journal file (task 2) is only performed if the +** rollback is successful. +** +** In WAL mode, all cache-entries containing data modified within the +** current transaction are either expelled from the cache or reverted to +** their pre-transaction state by re-reading data from the database or +** WAL files. The WAL transaction is then closed. +*/ +SQLITE_PRIVATE int sqlite3PagerRollback(Pager *pPager){ + int rc = SQLITE_OK; /* Return code */ + PAGERTRACE(("ROLLBACK %d\n", PAGERID(pPager))); + + /* PagerRollback() is a no-op if called in READER or OPEN state. If + ** the pager is already in the ERROR state, the rollback is not + ** attempted here. Instead, the error code is returned to the caller. + */ + assert( assert_pager_state(pPager) ); + if( pPager->eState==PAGER_ERROR ) return pPager->errCode; + if( pPager->eState<=PAGER_READER ) return SQLITE_OK; + + if( pagerUseWal(pPager) ){ + int rc2; + rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, -1); + rc2 = pager_end_transaction(pPager, pPager->setSuper, 0); + if( rc==SQLITE_OK ) rc = rc2; + }else if( !isOpen(pPager->jfd) || pPager->eState==PAGER_WRITER_LOCKED ){ + int eState = pPager->eState; + rc = pager_end_transaction(pPager, 0, 0); + if( !MEMDB && eState>PAGER_WRITER_LOCKED ){ + /* This can happen using journal_mode=off. Move the pager to the error + ** state to indicate that the contents of the cache may not be trusted. + ** Any active readers will get SQLITE_ABORT. + */ + pPager->errCode = SQLITE_ABORT; + pPager->eState = PAGER_ERROR; + setGetterMethod(pPager); + return rc; + } + }else{ + rc = pager_playback(pPager, 0); + } + + assert( pPager->eState==PAGER_READER || rc!=SQLITE_OK ); + assert( rc==SQLITE_OK || rc==SQLITE_FULL || rc==SQLITE_CORRUPT + || rc==SQLITE_NOMEM || (rc&0xFF)==SQLITE_IOERR + || rc==SQLITE_CANTOPEN + ); + + /* If an error occurs during a ROLLBACK, we can no longer trust the pager + ** cache. So call pager_error() on the way out to make any error persistent. + */ + return pager_error(pPager, rc); +} + +/* +** Return TRUE if the database file is opened read-only. Return FALSE +** if the database is (in theory) writable. +*/ +SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager *pPager){ + return pPager->readOnly; +} + +#ifdef SQLITE_DEBUG +/* +** Return the sum of the reference counts for all pages held by pPager. +*/ +SQLITE_PRIVATE int sqlite3PagerRefcount(Pager *pPager){ + return sqlite3PcacheRefCount(pPager->pPCache); +} +#endif + +/* +** Return the approximate number of bytes of memory currently +** used by the pager and its associated cache. +*/ +SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager *pPager){ + int perPageSize = pPager->pageSize + pPager->nExtra + + (int)(sizeof(PgHdr) + 5*sizeof(void*)); + return perPageSize*sqlite3PcachePagecount(pPager->pPCache) + + sqlite3MallocSize(pPager) + + pPager->pageSize; +} + +/* +** Return the number of references to the specified page. +*/ +SQLITE_PRIVATE int sqlite3PagerPageRefcount(DbPage *pPage){ + return sqlite3PcachePageRefcount(pPage); +} + +#ifdef SQLITE_TEST +/* +** This routine is used for testing and analysis only. +*/ +SQLITE_PRIVATE int *sqlite3PagerStats(Pager *pPager){ + static int a[11]; + a[0] = sqlite3PcacheRefCount(pPager->pPCache); + a[1] = sqlite3PcachePagecount(pPager->pPCache); + a[2] = sqlite3PcacheGetCachesize(pPager->pPCache); + a[3] = pPager->eState==PAGER_OPEN ? -1 : (int) pPager->dbSize; + a[4] = pPager->eState; + a[5] = pPager->errCode; + a[6] = (int)pPager->aStat[PAGER_STAT_HIT] & 0x7fffffff; + a[7] = (int)pPager->aStat[PAGER_STAT_MISS] & 0x7fffffff; + a[8] = 0; /* Used to be pPager->nOvfl */ + a[9] = pPager->nRead; + a[10] = (int)pPager->aStat[PAGER_STAT_WRITE] & 0x7fffffff; + return a; +} +#endif + +/* +** Parameter eStat must be one of SQLITE_DBSTATUS_CACHE_HIT, _MISS, _WRITE, +** or _WRITE+1. The SQLITE_DBSTATUS_CACHE_WRITE+1 case is a translation +** of SQLITE_DBSTATUS_CACHE_SPILL. The _SPILL case is not contiguous because +** it was added later. +** +** Before returning, *pnVal is incremented by the +** current cache hit or miss count, according to the value of eStat. If the +** reset parameter is non-zero, the cache hit or miss count is zeroed before +** returning. +*/ +SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, u64 *pnVal){ + + assert( eStat==SQLITE_DBSTATUS_CACHE_HIT + || eStat==SQLITE_DBSTATUS_CACHE_MISS + || eStat==SQLITE_DBSTATUS_CACHE_WRITE + || eStat==SQLITE_DBSTATUS_CACHE_WRITE+1 + ); + + assert( SQLITE_DBSTATUS_CACHE_HIT+1==SQLITE_DBSTATUS_CACHE_MISS ); + assert( SQLITE_DBSTATUS_CACHE_HIT+2==SQLITE_DBSTATUS_CACHE_WRITE ); + assert( PAGER_STAT_HIT==0 && PAGER_STAT_MISS==1 + && PAGER_STAT_WRITE==2 && PAGER_STAT_SPILL==3 ); + + eStat -= SQLITE_DBSTATUS_CACHE_HIT; + *pnVal += pPager->aStat[eStat]; + if( reset ){ + pPager->aStat[eStat] = 0; + } +} + +/* +** Return true if this is an in-memory or temp-file backed pager. +*/ +SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){ + return pPager->tempFile || pPager->memVfs; +} + +/* +** Check that there are at least nSavepoint savepoints open. If there are +** currently less than nSavepoints open, then open one or more savepoints +** to make up the difference. If the number of savepoints is already +** equal to nSavepoint, then this function is a no-op. +** +** If a memory allocation fails, SQLITE_NOMEM is returned. If an error +** occurs while opening the sub-journal file, then an IO error code is +** returned. Otherwise, SQLITE_OK. +*/ +static SQLITE_NOINLINE int pagerOpenSavepoint(Pager *pPager, int nSavepoint){ + int rc = SQLITE_OK; /* Return code */ + int nCurrent = pPager->nSavepoint; /* Current number of savepoints */ + int ii; /* Iterator variable */ + PagerSavepoint *aNew; /* New Pager.aSavepoint array */ + + assert( pPager->eState>=PAGER_WRITER_LOCKED ); + assert( assert_pager_state(pPager) ); + assert( nSavepoint>nCurrent && pPager->useJournal ); + + /* Grow the Pager.aSavepoint array using realloc(). Return SQLITE_NOMEM + ** if the allocation fails. Otherwise, zero the new portion in case a + ** malloc failure occurs while populating it in the for(...) loop below. + */ + aNew = (PagerSavepoint *)sqlite3Realloc( + pPager->aSavepoint, sizeof(PagerSavepoint)*nSavepoint + ); + if( !aNew ){ + return SQLITE_NOMEM_BKPT; + } + memset(&aNew[nCurrent], 0, (nSavepoint-nCurrent) * sizeof(PagerSavepoint)); + pPager->aSavepoint = aNew; + + /* Populate the PagerSavepoint structures just allocated. */ + for(ii=nCurrent; iidbSize; + if( isOpen(pPager->jfd) && pPager->journalOff>0 ){ + aNew[ii].iOffset = pPager->journalOff; + }else{ + aNew[ii].iOffset = JOURNAL_HDR_SZ(pPager); + } + aNew[ii].iSubRec = pPager->nSubRec; + aNew[ii].pInSavepoint = sqlite3BitvecCreate(pPager->dbSize); + aNew[ii].bTruncateOnRelease = 1; + if( !aNew[ii].pInSavepoint ){ + return SQLITE_NOMEM_BKPT; + } + if( pagerUseWal(pPager) ){ + sqlite3WalSavepoint(pPager->pWal, aNew[ii].aWalData); + } + pPager->nSavepoint = ii+1; + } + assert( pPager->nSavepoint==nSavepoint ); + assertTruncateConstraint(pPager); + return rc; +} +SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){ + assert( pPager->eState>=PAGER_WRITER_LOCKED ); + assert( assert_pager_state(pPager) ); + + if( nSavepoint>pPager->nSavepoint && pPager->useJournal ){ + return pagerOpenSavepoint(pPager, nSavepoint); + }else{ + return SQLITE_OK; + } +} + + +/* +** This function is called to rollback or release (commit) a savepoint. +** The savepoint to release or rollback need not be the most recently +** created savepoint. +** +** Parameter op is always either SAVEPOINT_ROLLBACK or SAVEPOINT_RELEASE. +** If it is SAVEPOINT_RELEASE, then release and destroy the savepoint with +** index iSavepoint. If it is SAVEPOINT_ROLLBACK, then rollback all changes +** that have occurred since the specified savepoint was created. +** +** The savepoint to rollback or release is identified by parameter +** iSavepoint. A value of 0 means to operate on the outermost savepoint +** (the first created). A value of (Pager.nSavepoint-1) means operate +** on the most recently created savepoint. If iSavepoint is greater than +** (Pager.nSavepoint-1), then this function is a no-op. +** +** If a negative value is passed to this function, then the current +** transaction is rolled back. This is different to calling +** sqlite3PagerRollback() because this function does not terminate +** the transaction or unlock the database, it just restores the +** contents of the database to its original state. +** +** In any case, all savepoints with an index greater than iSavepoint +** are destroyed. If this is a release operation (op==SAVEPOINT_RELEASE), +** then savepoint iSavepoint is also destroyed. +** +** This function may return SQLITE_NOMEM if a memory allocation fails, +** or an IO error code if an IO error occurs while rolling back a +** savepoint. If no errors occur, SQLITE_OK is returned. +*/ +SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){ + int rc = pPager->errCode; + +#ifdef SQLITE_ENABLE_ZIPVFS + if( op==SAVEPOINT_RELEASE ) rc = SQLITE_OK; +#endif + + assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK ); + assert( iSavepoint>=0 || op==SAVEPOINT_ROLLBACK ); + + if( rc==SQLITE_OK && iSavepointnSavepoint ){ + int ii; /* Iterator variable */ + int nNew; /* Number of remaining savepoints after this op. */ + + /* Figure out how many savepoints will still be active after this + ** operation. Store this value in nNew. Then free resources associated + ** with any savepoints that are destroyed by this operation. + */ + nNew = iSavepoint + (( op==SAVEPOINT_RELEASE ) ? 0 : 1); + for(ii=nNew; iinSavepoint; ii++){ + sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint); + } + pPager->nSavepoint = nNew; + + /* Truncate the sub-journal so that it only includes the parts + ** that are still in use. */ + if( op==SAVEPOINT_RELEASE ){ + PagerSavepoint *pRel = &pPager->aSavepoint[nNew]; + if( pRel->bTruncateOnRelease && isOpen(pPager->sjfd) ){ + /* Only truncate if it is an in-memory sub-journal. */ + if( sqlite3JournalIsInMemory(pPager->sjfd) ){ + i64 sz = (pPager->pageSize+4)*(i64)pRel->iSubRec; + rc = sqlite3OsTruncate(pPager->sjfd, sz); + assert( rc==SQLITE_OK ); + } + pPager->nSubRec = pRel->iSubRec; + } + } + /* Else this is a rollback operation, playback the specified savepoint. + ** If this is a temp-file, it is possible that the journal file has + ** not yet been opened. In this case there have been no changes to + ** the database file, so the playback operation can be skipped. + */ + else if( pagerUseWal(pPager) || isOpen(pPager->jfd) ){ + PagerSavepoint *pSavepoint = (nNew==0)?0:&pPager->aSavepoint[nNew-1]; + rc = pagerPlaybackSavepoint(pPager, pSavepoint); + assert(rc!=SQLITE_DONE); + } + +#ifdef SQLITE_ENABLE_ZIPVFS + /* If the cache has been modified but the savepoint cannot be rolled + ** back journal_mode=off, put the pager in the error state. This way, + ** if the VFS used by this pager includes ZipVFS, the entire transaction + ** can be rolled back at the ZipVFS level. */ + else if( + pPager->journalMode==PAGER_JOURNALMODE_OFF + && pPager->eState>=PAGER_WRITER_CACHEMOD + ){ + pPager->errCode = SQLITE_ABORT; + pPager->eState = PAGER_ERROR; + setGetterMethod(pPager); + } +#endif + } + + return rc; +} + +/* +** Return the full pathname of the database file. +** +** Except, if the pager is in-memory only, then return an empty string if +** nullIfMemDb is true. This routine is called with nullIfMemDb==1 when +** used to report the filename to the user, for compatibility with legacy +** behavior. But when the Btree needs to know the filename for matching to +** shared cache, it uses nullIfMemDb==0 so that in-memory databases can +** participate in shared-cache. +** +** The return value to this routine is always safe to use with +** sqlite3_uri_parameter() and sqlite3_filename_database() and friends. +*/ +SQLITE_PRIVATE const char *sqlite3PagerFilename(const Pager *pPager, int nullIfMemDb){ + static const char zFake[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + if( nullIfMemDb && (pPager->memDb || sqlite3IsMemdb(pPager->pVfs)) ){ + return &zFake[4]; + }else{ + return pPager->zFilename; + } +} + +/* +** Return the VFS structure for the pager. +*/ +SQLITE_PRIVATE sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){ + return pPager->pVfs; +} + +/* +** Return the file handle for the database file associated +** with the pager. This might return NULL if the file has +** not yet been opened. +*/ +SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){ + return pPager->fd; +} + +/* +** Return the file handle for the journal file (if it exists). +** This will be either the rollback journal or the WAL file. +*/ +SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager *pPager){ +#ifdef SQLITE_OMIT_WAL + return pPager->jfd; +#else + return pPager->pWal ? sqlite3WalFile(pPager->pWal) : pPager->jfd; +#endif +} + +/* +** Return the full pathname of the journal file. +*/ +SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager *pPager){ + return pPager->zJournal; +} + +#ifndef SQLITE_OMIT_AUTOVACUUM +/* +** Move the page pPg to location pgno in the file. +** +** There must be no references to the page previously located at +** pgno (which we call pPgOld) though that page is allowed to be +** in cache. If the page previously located at pgno is not already +** in the rollback journal, it is not put there by by this routine. +** +** References to the page pPg remain valid. Updating any +** meta-data associated with pPg (i.e. data stored in the nExtra bytes +** allocated along with the page) is the responsibility of the caller. +** +** A transaction must be active when this routine is called. It used to be +** required that a statement transaction was not active, but this restriction +** has been removed (CREATE INDEX needs to move a page when a statement +** transaction is active). +** +** If the fourth argument, isCommit, is non-zero, then this page is being +** moved as part of a database reorganization just before the transaction +** is being committed. In this case, it is guaranteed that the database page +** pPg refers to will not be written to again within this transaction. +** +** This function may return SQLITE_NOMEM or an IO error code if an error +** occurs. Otherwise, it returns SQLITE_OK. +*/ +SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){ + PgHdr *pPgOld; /* The page being overwritten. */ + Pgno needSyncPgno = 0; /* Old value of pPg->pgno, if sync is required */ + int rc; /* Return code */ + Pgno origPgno; /* The original page number */ + + assert( pPg->nRef>0 ); + assert( pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + ); + assert( assert_pager_state(pPager) ); + + /* In order to be able to rollback, an in-memory database must journal + ** the page we are moving from. + */ + assert( pPager->tempFile || !MEMDB ); + if( pPager->tempFile ){ + rc = sqlite3PagerWrite(pPg); + if( rc ) return rc; + } + + /* If the page being moved is dirty and has not been saved by the latest + ** savepoint, then save the current contents of the page into the + ** sub-journal now. This is required to handle the following scenario: + ** + ** BEGIN; + ** + ** SAVEPOINT one; + ** + ** ROLLBACK TO one; + ** + ** If page X were not written to the sub-journal here, it would not + ** be possible to restore its contents when the "ROLLBACK TO one" + ** statement were is processed. + ** + ** subjournalPage() may need to allocate space to store pPg->pgno into + ** one or more savepoint bitvecs. This is the reason this function + ** may return SQLITE_NOMEM. + */ + if( (pPg->flags & PGHDR_DIRTY)!=0 + && SQLITE_OK!=(rc = subjournalPageIfRequired(pPg)) + ){ + return rc; + } + + PAGERTRACE(("MOVE %d page %d (needSync=%d) moves to %d\n", + PAGERID(pPager), pPg->pgno, (pPg->flags&PGHDR_NEED_SYNC)?1:0, pgno)); + IOTRACE(("MOVE %p %d %d\n", pPager, pPg->pgno, pgno)) + + /* If the journal needs to be sync()ed before page pPg->pgno can + ** be written to, store pPg->pgno in local variable needSyncPgno. + ** + ** If the isCommit flag is set, there is no need to remember that + ** the journal needs to be sync()ed before database page pPg->pgno + ** can be written to. The caller has already promised not to write to it. + */ + if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){ + needSyncPgno = pPg->pgno; + assert( pPager->journalMode==PAGER_JOURNALMODE_OFF || + pageInJournal(pPager, pPg) || pPg->pgno>pPager->dbOrigSize ); + assert( pPg->flags&PGHDR_DIRTY ); + } + + /* If the cache contains a page with page-number pgno, remove it + ** from its hash chain. Also, if the PGHDR_NEED_SYNC flag was set for + ** page pgno before the 'move' operation, it needs to be retained + ** for the page moved there. + */ + pPg->flags &= ~PGHDR_NEED_SYNC; + pPgOld = sqlite3PagerLookup(pPager, pgno); + assert( !pPgOld || pPgOld->nRef==1 || CORRUPT_DB ); + if( pPgOld ){ + if( NEVER(pPgOld->nRef>1) ){ + sqlite3PagerUnrefNotNull(pPgOld); + return SQLITE_CORRUPT_BKPT; + } + pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC); + if( pPager->tempFile ){ + /* Do not discard pages from an in-memory database since we might + ** need to rollback later. Just move the page out of the way. */ + sqlite3PcacheMove(pPgOld, pPager->dbSize+1); + }else{ + sqlite3PcacheDrop(pPgOld); + } + } + + origPgno = pPg->pgno; + sqlite3PcacheMove(pPg, pgno); + sqlite3PcacheMakeDirty(pPg); + + /* For an in-memory database, make sure the original page continues + ** to exist, in case the transaction needs to roll back. Use pPgOld + ** as the original page since it has already been allocated. + */ + if( pPager->tempFile && pPgOld ){ + sqlite3PcacheMove(pPgOld, origPgno); + sqlite3PagerUnrefNotNull(pPgOld); + } + + if( needSyncPgno ){ + /* If needSyncPgno is non-zero, then the journal file needs to be + ** sync()ed before any data is written to database file page needSyncPgno. + ** Currently, no such page exists in the page-cache and the + ** "is journaled" bitvec flag has been set. This needs to be remedied by + ** loading the page into the pager-cache and setting the PGHDR_NEED_SYNC + ** flag. + ** + ** If the attempt to load the page into the page-cache fails, (due + ** to a malloc() or IO failure), clear the bit in the pInJournal[] + ** array. Otherwise, if the page is loaded and written again in + ** this transaction, it may be written to the database file before + ** it is synced into the journal file. This way, it may end up in + ** the journal file twice, but that is not a problem. + */ + PgHdr *pPgHdr; + rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr, 0); + if( rc!=SQLITE_OK ){ + if( needSyncPgno<=pPager->dbOrigSize ){ + assert( pPager->pTmpSpace!=0 ); + sqlite3BitvecClear(pPager->pInJournal, needSyncPgno, pPager->pTmpSpace); + } + return rc; + } + pPgHdr->flags |= PGHDR_NEED_SYNC; + sqlite3PcacheMakeDirty(pPgHdr); + sqlite3PagerUnrefNotNull(pPgHdr); + } + + return SQLITE_OK; +} +#endif + +/* +** The page handle passed as the first argument refers to a dirty page +** with a page number other than iNew. This function changes the page's +** page number to iNew and sets the value of the PgHdr.flags field to +** the value passed as the third parameter. +*/ +SQLITE_PRIVATE void sqlite3PagerRekey(DbPage *pPg, Pgno iNew, u16 flags){ + assert( pPg->pgno!=iNew ); + pPg->flags = flags; + sqlite3PcacheMove(pPg, iNew); +} + +/* +** Return a pointer to the data for the specified page. +*/ +SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *pPg){ + assert( pPg->nRef>0 || pPg->pPager->memDb ); + return pPg->pData; +} + +/* +** Return a pointer to the Pager.nExtra bytes of "extra" space +** allocated along with the specified page. +*/ +SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *pPg){ + return pPg->pExtra; +} + +/* +** Get/set the locking-mode for this pager. Parameter eMode must be one +** of PAGER_LOCKINGMODE_QUERY, PAGER_LOCKINGMODE_NORMAL or +** PAGER_LOCKINGMODE_EXCLUSIVE. If the parameter is not _QUERY, then +** the locking-mode is set to the value specified. +** +** The returned value is either PAGER_LOCKINGMODE_NORMAL or +** PAGER_LOCKINGMODE_EXCLUSIVE, indicating the current (possibly updated) +** locking-mode. +*/ +SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *pPager, int eMode){ + assert( eMode==PAGER_LOCKINGMODE_QUERY + || eMode==PAGER_LOCKINGMODE_NORMAL + || eMode==PAGER_LOCKINGMODE_EXCLUSIVE ); + assert( PAGER_LOCKINGMODE_QUERY<0 ); + assert( PAGER_LOCKINGMODE_NORMAL>=0 && PAGER_LOCKINGMODE_EXCLUSIVE>=0 ); + assert( pPager->exclusiveMode || 0==sqlite3WalHeapMemory(pPager->pWal) ); + if( eMode>=0 && !pPager->tempFile && !sqlite3WalHeapMemory(pPager->pWal) ){ + pPager->exclusiveMode = (u8)eMode; + } + return (int)pPager->exclusiveMode; +} + +/* +** Set the journal-mode for this pager. Parameter eMode must be one of: +** +** PAGER_JOURNALMODE_DELETE +** PAGER_JOURNALMODE_TRUNCATE +** PAGER_JOURNALMODE_PERSIST +** PAGER_JOURNALMODE_OFF +** PAGER_JOURNALMODE_MEMORY +** PAGER_JOURNALMODE_WAL +** +** The journalmode is set to the value specified if the change is allowed. +** The change may be disallowed for the following reasons: +** +** * An in-memory database can only have its journal_mode set to _OFF +** or _MEMORY. +** +** * Temporary databases cannot have _WAL journalmode. +** +** The returned indicate the current (possibly updated) journal-mode. +*/ +SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){ + u8 eOld = pPager->journalMode; /* Prior journalmode */ + + /* The eMode parameter is always valid */ + assert( eMode==PAGER_JOURNALMODE_DELETE /* 0 */ + || eMode==PAGER_JOURNALMODE_PERSIST /* 1 */ + || eMode==PAGER_JOURNALMODE_OFF /* 2 */ + || eMode==PAGER_JOURNALMODE_TRUNCATE /* 3 */ + || eMode==PAGER_JOURNALMODE_MEMORY /* 4 */ + || eMode==PAGER_JOURNALMODE_WAL /* 5 */ ); + + /* This routine is only called from the OP_JournalMode opcode, and + ** the logic there will never allow a temporary file to be changed + ** to WAL mode. + */ + assert( pPager->tempFile==0 || eMode!=PAGER_JOURNALMODE_WAL ); + + /* Do allow the journalmode of an in-memory database to be set to + ** anything other than MEMORY or OFF + */ + if( MEMDB ){ + assert( eOld==PAGER_JOURNALMODE_MEMORY || eOld==PAGER_JOURNALMODE_OFF ); + if( eMode!=PAGER_JOURNALMODE_MEMORY && eMode!=PAGER_JOURNALMODE_OFF ){ + eMode = eOld; + } + } + + if( eMode!=eOld ){ + + /* Change the journal mode. */ + assert( pPager->eState!=PAGER_ERROR ); + pPager->journalMode = (u8)eMode; + + /* When transitioning from TRUNCATE or PERSIST to any other journal + ** mode except WAL, unless the pager is in locking_mode=exclusive mode, + ** delete the journal file. + */ + assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 ); + assert( (PAGER_JOURNALMODE_PERSIST & 5)==1 ); + assert( (PAGER_JOURNALMODE_DELETE & 5)==0 ); + assert( (PAGER_JOURNALMODE_MEMORY & 5)==4 ); + assert( (PAGER_JOURNALMODE_OFF & 5)==0 ); + assert( (PAGER_JOURNALMODE_WAL & 5)==5 ); + + assert( isOpen(pPager->fd) || pPager->exclusiveMode ); + if( !pPager->exclusiveMode && (eOld & 5)==1 && (eMode & 1)==0 ){ + /* In this case we would like to delete the journal file. If it is + ** not possible, then that is not a problem. Deleting the journal file + ** here is an optimization only. + ** + ** Before deleting the journal file, obtain a RESERVED lock on the + ** database file. This ensures that the journal file is not deleted + ** while it is in use by some other client. + */ + sqlite3OsClose(pPager->jfd); + if( pPager->eLock>=RESERVED_LOCK ){ + sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); + }else{ + int rc = SQLITE_OK; + int state = pPager->eState; + assert( state==PAGER_OPEN || state==PAGER_READER ); + if( state==PAGER_OPEN ){ + rc = sqlite3PagerSharedLock(pPager); + } + if( pPager->eState==PAGER_READER ){ + assert( rc==SQLITE_OK ); + rc = pagerLockDb(pPager, RESERVED_LOCK); + } + if( rc==SQLITE_OK ){ + sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); + } + if( rc==SQLITE_OK && state==PAGER_READER ){ + pagerUnlockDb(pPager, SHARED_LOCK); + }else if( state==PAGER_OPEN ){ + pager_unlock(pPager); + } + assert( state==pPager->eState ); + } + }else if( eMode==PAGER_JOURNALMODE_OFF || eMode==PAGER_JOURNALMODE_MEMORY ){ + sqlite3OsClose(pPager->jfd); + } + } + + /* Return the new journal mode */ + return (int)pPager->journalMode; +} + +/* +** Return the current journal mode. +*/ +SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager *pPager){ + return (int)pPager->journalMode; +} + +/* +** Return TRUE if the pager is in a state where it is OK to change the +** journalmode. Journalmode changes can only happen when the database +** is unmodified. +*/ +SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager *pPager){ + assert( assert_pager_state(pPager) ); + if( pPager->eState>=PAGER_WRITER_CACHEMOD ) return 0; + if( NEVER(isOpen(pPager->jfd) && pPager->journalOff>0) ) return 0; + return 1; +} + +/* +** Get/set the size-limit used for persistent journal files. +** +** Setting the size limit to -1 means no limit is enforced. +** An attempt to set a limit smaller than -1 is a no-op. +*/ +SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){ + if( iLimit>=-1 ){ + pPager->journalSizeLimit = iLimit; + sqlite3WalLimit(pPager->pWal, iLimit); + } + return pPager->journalSizeLimit; +} + +/* +** Return a pointer to the pPager->pBackup variable. The backup module +** in backup.c maintains the content of this variable. This module +** uses it opaquely as an argument to sqlite3BackupRestart() and +** sqlite3BackupUpdate() only. +*/ +SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){ + return &pPager->pBackup; +} + +#ifndef SQLITE_OMIT_VACUUM +/* +** Unless this is an in-memory or temporary database, clear the pager cache. +*/ +SQLITE_PRIVATE void sqlite3PagerClearCache(Pager *pPager){ + assert( MEMDB==0 || pPager->tempFile ); + if( pPager->tempFile==0 ) pager_reset(pPager); +} +#endif + + +#ifndef SQLITE_OMIT_WAL +/* +** This function is called when the user invokes "PRAGMA wal_checkpoint", +** "PRAGMA wal_blocking_checkpoint" or calls the sqlite3_wal_checkpoint() +** or wal_blocking_checkpoint() API functions. +** +** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART. +*/ +SQLITE_PRIVATE int sqlite3PagerCheckpoint( + Pager *pPager, /* Checkpoint on this pager */ + sqlite3 *db, /* Db handle used to check for interrupts */ + int eMode, /* Type of checkpoint */ + int *pnLog, /* OUT: Final number of frames in log */ + int *pnCkpt /* OUT: Final number of checkpointed frames */ +){ + int rc = SQLITE_OK; + if( pPager->pWal==0 && pPager->journalMode==PAGER_JOURNALMODE_WAL ){ + /* This only happens when a database file is zero bytes in size opened and + ** then "PRAGMA journal_mode=WAL" is run and then sqlite3_wal_checkpoint() + ** is invoked without any intervening transactions. We need to start + ** a transaction to initialize pWal. The PRAGMA table_list statement is + ** used for this since it starts transactions on every database file, + ** including all ATTACHed databases. This seems expensive for a single + ** sqlite3_wal_checkpoint() call, but it happens very rarely. + ** https://sqlite.org/forum/forumpost/fd0f19d229156939 + */ + sqlite3_exec(db, "PRAGMA table_list",0,0,0); + } + if( pPager->pWal ){ + rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode, + (eMode<=SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler), + pPager->pBusyHandlerArg, + pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace, + pnLog, pnCkpt + ); + } + return rc; +} + +SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager){ + return sqlite3WalCallback(pPager->pWal); +} + +/* +** Return true if the underlying VFS for the given pager supports the +** primitives necessary for write-ahead logging. +*/ +SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager){ + const sqlite3_io_methods *pMethods = pPager->fd->pMethods; + if( pPager->noLock ) return 0; + return pPager->exclusiveMode || (pMethods->iVersion>=2 && pMethods->xShmMap); +} + +/* +** Attempt to take an exclusive lock on the database file. If a PENDING lock +** is obtained instead, immediately release it. +*/ +static int pagerExclusiveLock(Pager *pPager){ + int rc; /* Return code */ + u8 eOrigLock; /* Original lock */ + + assert( pPager->eLock>=SHARED_LOCK ); + eOrigLock = pPager->eLock; + rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); + if( rc!=SQLITE_OK ){ + /* If the attempt to grab the exclusive lock failed, release the + ** pending lock that may have been obtained instead. */ + pagerUnlockDb(pPager, eOrigLock); + } + + return rc; +} + +/* +** Call sqlite3WalOpen() to open the WAL handle. If the pager is in +** exclusive-locking mode when this function is called, take an EXCLUSIVE +** lock on the database file and use heap-memory to store the wal-index +** in. Otherwise, use the normal shared-memory. +*/ +static int pagerOpenWal(Pager *pPager){ + int rc = SQLITE_OK; + + assert( pPager->pWal==0 && pPager->tempFile==0 ); + assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK ); + + /* If the pager is already in exclusive-mode, the WAL module will use + ** heap-memory for the wal-index instead of the VFS shared-memory + ** implementation. Take the exclusive lock now, before opening the WAL + ** file, to make sure this is safe. + */ + if( pPager->exclusiveMode ){ + rc = pagerExclusiveLock(pPager); + } + + /* Open the connection to the log file. If this operation fails, + ** (e.g. due to malloc() failure), return an error code. + */ + if( rc==SQLITE_OK ){ + rc = sqlite3WalOpen(pPager->pVfs, + pPager->fd, pPager->zWal, pPager->exclusiveMode, + pPager->journalSizeLimit, &pPager->pWal + ); +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + if( rc==SQLITE_OK ){ + sqlite3WalDb(pPager->pWal, pPager->dbWal); + } +#endif + } + pagerFixMaplimit(pPager); + + return rc; +} + + +/* +** The caller must be holding a SHARED lock on the database file to call +** this function. +** +** If the pager passed as the first argument is open on a real database +** file (not a temp file or an in-memory database), and the WAL file +** is not already open, make an attempt to open it now. If successful, +** return SQLITE_OK. If an error occurs or the VFS used by the pager does +** not support the xShmXXX() methods, return an error code. *pbOpen is +** not modified in either case. +** +** If the pager is open on a temp-file (or in-memory database), or if +** the WAL file is already open, set *pbOpen to 1 and return SQLITE_OK +** without doing anything. +*/ +SQLITE_PRIVATE int sqlite3PagerOpenWal( + Pager *pPager, /* Pager object */ + int *pbOpen /* OUT: Set to true if call is a no-op */ +){ + int rc = SQLITE_OK; /* Return code */ + + assert( assert_pager_state(pPager) ); + assert( pPager->eState==PAGER_OPEN || pbOpen ); + assert( pPager->eState==PAGER_READER || !pbOpen ); + assert( pbOpen==0 || *pbOpen==0 ); + assert( pbOpen!=0 || (!pPager->tempFile && !pPager->pWal) ); + + if( !pPager->tempFile && !pPager->pWal ){ + if( !sqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN; + + /* Close any rollback journal previously open */ + sqlite3OsClose(pPager->jfd); + + rc = pagerOpenWal(pPager); + if( rc==SQLITE_OK ){ + pPager->journalMode = PAGER_JOURNALMODE_WAL; + pPager->eState = PAGER_OPEN; + } + }else{ + *pbOpen = 1; + } + + return rc; +} + +/* +** This function is called to close the connection to the log file prior +** to switching from WAL to rollback mode. +** +** Before closing the log file, this function attempts to take an +** EXCLUSIVE lock on the database file. If this cannot be obtained, an +** error (SQLITE_BUSY) is returned and the log connection is not closed. +** If successful, the EXCLUSIVE lock is not released before returning. +*/ +SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3 *db){ + int rc = SQLITE_OK; + + assert( pPager->journalMode==PAGER_JOURNALMODE_WAL ); + + /* If the log file is not already open, but does exist in the file-system, + ** it may need to be checkpointed before the connection can switch to + ** rollback mode. Open it now so this can happen. + */ + if( !pPager->pWal ){ + int logexists = 0; + rc = pagerLockDb(pPager, SHARED_LOCK); + if( rc==SQLITE_OK ){ + rc = sqlite3OsAccess( + pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &logexists + ); + } + if( rc==SQLITE_OK && logexists ){ + rc = pagerOpenWal(pPager); + } + } + + /* Checkpoint and close the log. Because an EXCLUSIVE lock is held on + ** the database file, the log and log-summary files will be deleted. + */ + if( rc==SQLITE_OK && pPager->pWal ){ + rc = pagerExclusiveLock(pPager); + if( rc==SQLITE_OK ){ + rc = sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, + pPager->pageSize, (u8*)pPager->pTmpSpace); + pPager->pWal = 0; + pagerFixMaplimit(pPager); + if( rc && !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK); + } + } + return rc; +} + +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT +/* +** If pager pPager is a wal-mode database not in exclusive locking mode, +** invoke the sqlite3WalWriteLock() function on the associated Wal object +** with the same db and bLock parameters as were passed to this function. +** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise. +*/ +SQLITE_PRIVATE int sqlite3PagerWalWriteLock(Pager *pPager, int bLock){ + int rc = SQLITE_OK; + if( pagerUseWal(pPager) && pPager->exclusiveMode==0 ){ + rc = sqlite3WalWriteLock(pPager->pWal, bLock); + } + return rc; +} + +/* +** Set the database handle used by the wal layer to determine if +** blocking locks are required. +*/ +SQLITE_PRIVATE void sqlite3PagerWalDb(Pager *pPager, sqlite3 *db){ + pPager->dbWal = db; + if( pagerUseWal(pPager) ){ + sqlite3WalDb(pPager->pWal, db); + } +} +#endif + +#ifdef SQLITE_ENABLE_SNAPSHOT +/* +** If this is a WAL database, obtain a snapshot handle for the snapshot +** currently open. Otherwise, return an error. +*/ +SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot){ + int rc = SQLITE_ERROR; + if( pPager->pWal ){ + rc = sqlite3WalSnapshotGet(pPager->pWal, ppSnapshot); + } + return rc; +} + +/* +** If this is a WAL database, store a pointer to pSnapshot. Next time a +** read transaction is opened, attempt to read from the snapshot it +** identifies. If this is not a WAL database, return an error. +*/ +SQLITE_PRIVATE int sqlite3PagerSnapshotOpen( + Pager *pPager, + sqlite3_snapshot *pSnapshot +){ + int rc = SQLITE_OK; + if( pPager->pWal ){ + sqlite3WalSnapshotOpen(pPager->pWal, pSnapshot); + }else{ + rc = SQLITE_ERROR; + } + return rc; +} + +/* +** If this is a WAL database, call sqlite3WalSnapshotRecover(). If this +** is not a WAL database, return an error. +*/ +SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager){ + int rc; + if( pPager->pWal ){ + rc = sqlite3WalSnapshotRecover(pPager->pWal); + }else{ + rc = SQLITE_ERROR; + } + return rc; +} + +/* +** The caller currently has a read transaction open on the database. +** If this is not a WAL database, SQLITE_ERROR is returned. Otherwise, +** this function takes a SHARED lock on the CHECKPOINTER slot and then +** checks if the snapshot passed as the second argument is still +** available. If so, SQLITE_OK is returned. +** +** If the snapshot is not available, SQLITE_ERROR is returned. Or, if +** the CHECKPOINTER lock cannot be obtained, SQLITE_BUSY. If any error +** occurs (any value other than SQLITE_OK is returned), the CHECKPOINTER +** lock is released before returning. +*/ +SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot){ + int rc; + if( pPager->pWal ){ + rc = sqlite3WalSnapshotCheck(pPager->pWal, pSnapshot); + }else{ + rc = SQLITE_ERROR; + } + return rc; +} + +/* +** Release a lock obtained by an earlier successful call to +** sqlite3PagerSnapshotCheck(). +*/ +SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager){ + assert( pPager->pWal ); + sqlite3WalSnapshotUnlock(pPager->pWal); +} + +#endif /* SQLITE_ENABLE_SNAPSHOT */ +#endif /* !SQLITE_OMIT_WAL */ + +#ifdef SQLITE_ENABLE_ZIPVFS +/* +** A read-lock must be held on the pager when this function is called. If +** the pager is in WAL mode and the WAL file currently contains one or more +** frames, return the size in bytes of the page images stored within the +** WAL frames. Otherwise, if this is not a WAL database or the WAL file +** is empty, return 0. +*/ +SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){ + assert( pPager->eState>=PAGER_READER ); + return sqlite3WalFramesize(pPager->pWal); +} +#endif + +#if defined(SQLITE_USE_SEH) && !defined(SQLITE_OMIT_WAL) +SQLITE_PRIVATE int sqlite3PagerWalSystemErrno(Pager *pPager){ + return sqlite3WalSystemErrno(pPager->pWal); +} +#endif + +#endif /* SQLITE_OMIT_DISKIO */ + +/************** End of pager.c ***********************************************/ +/************** Begin file wal.c *********************************************/ +/* +** 2010 February 1 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains the implementation of a write-ahead log (WAL) used in +** "journal_mode=WAL" mode. +** +** WRITE-AHEAD LOG (WAL) FILE FORMAT +** +** A WAL file consists of a header followed by zero or more "frames". +** Each frame records the revised content of a single page from the +** database file. All changes to the database are recorded by writing +** frames into the WAL. Transactions commit when a frame is written that +** contains a commit marker. A single WAL can and usually does record +** multiple transactions. Periodically, the content of the WAL is +** transferred back into the database file in an operation called a +** "checkpoint". +** +** A single WAL file can be used multiple times. In other words, the +** WAL can fill up with frames and then be checkpointed and then new +** frames can overwrite the old ones. A WAL always grows from beginning +** toward the end. Checksums and counters attached to each frame are +** used to determine which frames within the WAL are valid and which +** are leftovers from prior checkpoints. +** +** The WAL header is 32 bytes in size and consists of the following eight +** big-endian 32-bit unsigned integer values: +** +** 0: Magic number. 0x377f0682 or 0x377f0683 +** 4: File format version. Currently 3007000 +** 8: Database page size. Example: 1024 +** 12: Checkpoint sequence number +** 16: Salt-1, random integer incremented with each checkpoint +** 20: Salt-2, a different random integer changing with each ckpt +** 24: Checksum-1 (first part of checksum for first 24 bytes of header). +** 28: Checksum-2 (second part of checksum for first 24 bytes of header). +** +** Immediately following the wal-header are zero or more frames. Each +** frame consists of a 24-byte frame-header followed by bytes +** of page data. The frame-header is six big-endian 32-bit unsigned +** integer values, as follows: +** +** 0: Page number. +** 4: For commit records, the size of the database image in pages +** after the commit. For all other records, zero. +** 8: Salt-1 (copied from the header) +** 12: Salt-2 (copied from the header) +** 16: Checksum-1. +** 20: Checksum-2. +** +** A frame is considered valid if and only if the following conditions are +** true: +** +** (1) The salt-1 and salt-2 values in the frame-header match +** salt values in the wal-header +** +** (2) The checksum values in the final 8 bytes of the frame-header +** exactly match the checksum computed consecutively on the +** WAL header and the first 8 bytes and the content of all frames +** up to and including the current frame. +** +** The checksum is computed using 32-bit big-endian integers if the +** magic number in the first 4 bytes of the WAL is 0x377f0683 and it +** is computed using little-endian if the magic number is 0x377f0682. +** The checksum values are always stored in the frame header in a +** big-endian format regardless of which byte order is used to compute +** the checksum. The checksum is computed by interpreting the input as +** an even number of unsigned 32-bit integers: x[0] through x[N]. The +** algorithm used for the checksum is as follows: +** +** for i from 0 to n-1 step 2: +** s0 += x[i] + s1; +** s1 += x[i+1] + s0; +** endfor +** +** Note that s0 and s1 are both weighted checksums using fibonacci weights +** in reverse order (the largest fibonacci weight occurs on the first element +** of the sequence being summed.) The s1 value spans all 32-bit +** terms of the sequence whereas s0 omits the final term. +** +** On a checkpoint, the WAL is first VFS.xSync-ed, then valid content of the +** WAL is transferred into the database, then the database is VFS.xSync-ed. +** The VFS.xSync operations serve as write barriers - all writes launched +** before the xSync must complete before any write that launches after the +** xSync begins. +** +** After each checkpoint, the salt-1 value is incremented and the salt-2 +** value is randomized. This prevents old and new frames in the WAL from +** being considered valid at the same time and being checkpointing together +** following a crash. +** +** READER ALGORITHM +** +** To read a page from the database (call it page number P), a reader +** first checks the WAL to see if it contains page P. If so, then the +** last valid instance of page P that is a followed by a commit frame +** or is a commit frame itself becomes the value read. If the WAL +** contains no copies of page P that are valid and which are a commit +** frame or are followed by a commit frame, then page P is read from +** the database file. +** +** To start a read transaction, the reader records the index of the last +** valid frame in the WAL. The reader uses this recorded "mxFrame" value +** for all subsequent read operations. New transactions can be appended +** to the WAL, but as long as the reader uses its original mxFrame value +** and ignores the newly appended content, it will see a consistent snapshot +** of the database from a single point in time. This technique allows +** multiple concurrent readers to view different versions of the database +** content simultaneously. +** +** The reader algorithm in the previous paragraphs works correctly, but +** because frames for page P can appear anywhere within the WAL, the +** reader has to scan the entire WAL looking for page P frames. If the +** WAL is large (multiple megabytes is typical) that scan can be slow, +** and read performance suffers. To overcome this problem, a separate +** data structure called the wal-index is maintained to expedite the +** search for frames of a particular page. +** +** WAL-INDEX FORMAT +** +** Conceptually, the wal-index is shared memory, though VFS implementations +** might choose to implement the wal-index using a mmapped file. Because +** the wal-index is shared memory, SQLite does not support journal_mode=WAL +** on a network filesystem. All users of the database must be able to +** share memory. +** +** In the default unix and windows implementation, the wal-index is a mmapped +** file whose name is the database name with a "-shm" suffix added. For that +** reason, the wal-index is sometimes called the "shm" file. +** +** The wal-index is transient. After a crash, the wal-index can (and should +** be) reconstructed from the original WAL file. In fact, the VFS is required +** to either truncate or zero the header of the wal-index when the last +** connection to it closes. Because the wal-index is transient, it can +** use an architecture-specific format; it does not have to be cross-platform. +** Hence, unlike the database and WAL file formats which store all values +** as big endian, the wal-index can store multi-byte values in the native +** byte order of the host computer. +** +** The purpose of the wal-index is to answer this question quickly: Given +** a page number P and a maximum frame index M, return the index of the +** last frame in the wal before frame M for page P in the WAL, or return +** NULL if there are no frames for page P in the WAL prior to M. +** +** The wal-index consists of a header region, followed by an one or +** more index blocks. +** +** The wal-index header contains the total number of frames within the WAL +** in the mxFrame field. +** +** Each index block except for the first contains information on +** HASHTABLE_NPAGE frames. The first index block contains information on +** HASHTABLE_NPAGE_ONE frames. The values of HASHTABLE_NPAGE_ONE and +** HASHTABLE_NPAGE are selected so that together the wal-index header and +** first index block are the same size as all other index blocks in the +** wal-index. The values are: +** +** HASHTABLE_NPAGE 4096 +** HASHTABLE_NPAGE_ONE 4062 +** +** Each index block contains two sections, a page-mapping that contains the +** database page number associated with each wal frame, and a hash-table +** that allows readers to query an index block for a specific page number. +** The page-mapping is an array of HASHTABLE_NPAGE (or HASHTABLE_NPAGE_ONE +** for the first index block) 32-bit page numbers. The first entry in the +** first index-block contains the database page number corresponding to the +** first frame in the WAL file. The first entry in the second index block +** in the WAL file corresponds to the (HASHTABLE_NPAGE_ONE+1)th frame in +** the log, and so on. +** +** The last index block in a wal-index usually contains less than the full +** complement of HASHTABLE_NPAGE (or HASHTABLE_NPAGE_ONE) page-numbers, +** depending on the contents of the WAL file. This does not change the +** allocated size of the page-mapping array - the page-mapping array merely +** contains unused entries. +** +** Even without using the hash table, the last frame for page P +** can be found by scanning the page-mapping sections of each index block +** starting with the last index block and moving toward the first, and +** within each index block, starting at the end and moving toward the +** beginning. The first entry that equals P corresponds to the frame +** holding the content for that page. +** +** The hash table consists of HASHTABLE_NSLOT 16-bit unsigned integers. +** HASHTABLE_NSLOT = 2*HASHTABLE_NPAGE, and there is one entry in the +** hash table for each page number in the mapping section, so the hash +** table is never more than half full. The expected number of collisions +** prior to finding a match is 1. Each entry of the hash table is an +** 1-based index of an entry in the mapping section of the same +** index block. Let K be the 1-based index of the largest entry in +** the mapping section. (For index blocks other than the last, K will +** always be exactly HASHTABLE_NPAGE (4096) and for the last index block +** K will be (mxFrame%HASHTABLE_NPAGE).) Unused slots of the hash table +** contain a value of 0. +** +** To look for page P in the hash table, first compute a hash iKey on +** P as follows: +** +** iKey = (P * 383) % HASHTABLE_NSLOT +** +** Then start scanning entries of the hash table, starting with iKey +** (wrapping around to the beginning when the end of the hash table is +** reached) until an unused hash slot is found. Let the first unused slot +** be at index iUnused. (iUnused might be less than iKey if there was +** wrap-around.) Because the hash table is never more than half full, +** the search is guaranteed to eventually hit an unused entry. Let +** iMax be the value between iKey and iUnused, closest to iUnused, +** where aHash[iMax]==P. If there is no iMax entry (if there exists +** no hash slot such that aHash[i]==p) then page P is not in the +** current index block. Otherwise the iMax-th mapping entry of the +** current index block corresponds to the last entry that references +** page P. +** +** A hash search begins with the last index block and moves toward the +** first index block, looking for entries corresponding to page P. On +** average, only two or three slots in each index block need to be +** examined in order to either find the last entry for page P, or to +** establish that no such entry exists in the block. Each index block +** holds over 4000 entries. So two or three index blocks are sufficient +** to cover a typical 10 megabyte WAL file, assuming 1K pages. 8 or 10 +** comparisons (on average) suffice to either locate a frame in the +** WAL or to establish that the frame does not exist in the WAL. This +** is much faster than scanning the entire 10MB WAL. +** +** Note that entries are added in order of increasing K. Hence, one +** reader might be using some value K0 and a second reader that started +** at a later time (after additional transactions were added to the WAL +** and to the wal-index) might be using a different value K1, where K1>K0. +** Both readers can use the same hash table and mapping section to get +** the correct result. There may be entries in the hash table with +** K>K0 but to the first reader, those entries will appear to be unused +** slots in the hash table and so the first reader will get an answer as +** if no values greater than K0 had ever been inserted into the hash table +** in the first place - which is what reader one wants. Meanwhile, the +** second reader using K1 will see additional values that were inserted +** later, which is exactly what reader two wants. +** +** When a rollback occurs, the value of K is decreased. Hash table entries +** that correspond to frames greater than the new K value are removed +** from the hash table at this point. +*/ +#ifndef SQLITE_OMIT_WAL + +/* #include "wal.h" */ + +/* +** Trace output macros +*/ +#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) +SQLITE_PRIVATE int sqlite3WalTrace = 0; +# define WALTRACE(X) if(sqlite3WalTrace) sqlite3DebugPrintf X +#else +# define WALTRACE(X) +#endif + +/* +** The maximum (and only) versions of the wal and wal-index formats +** that may be interpreted by this version of SQLite. +** +** If a client begins recovering a WAL file and finds that (a) the checksum +** values in the wal-header are correct and (b) the version field is not +** WAL_MAX_VERSION, recovery fails and SQLite returns SQLITE_CANTOPEN. +** +** Similarly, if a client successfully reads a wal-index header (i.e. the +** checksum test is successful) and finds that the version field is not +** WALINDEX_MAX_VERSION, then no read-transaction is opened and SQLite +** returns SQLITE_CANTOPEN. +*/ +#define WAL_MAX_VERSION 3007000 +#define WALINDEX_MAX_VERSION 3007000 + +/* +** Index numbers for various locking bytes. WAL_NREADER is the number +** of available reader locks and should be at least 3. The default +** is SQLITE_SHM_NLOCK==8 and WAL_NREADER==5. +** +** Technically, the various VFSes are free to implement these locks however +** they see fit. However, compatibility is encouraged so that VFSes can +** interoperate. The standard implementation used on both unix and windows +** is for the index number to indicate a byte offset into the +** WalCkptInfo.aLock[] array in the wal-index header. In other words, all +** locks are on the shm file. The WALINDEX_LOCK_OFFSET constant (which +** should be 120) is the location in the shm file for the first locking +** byte. +*/ +#define WAL_WRITE_LOCK 0 +#define WAL_ALL_BUT_WRITE 1 +#define WAL_CKPT_LOCK 1 +#define WAL_RECOVER_LOCK 2 +#define WAL_READ_LOCK(I) (3+(I)) +#define WAL_NREADER (SQLITE_SHM_NLOCK-3) + + +/* Object declarations */ +typedef struct WalIndexHdr WalIndexHdr; +typedef struct WalIterator WalIterator; +typedef struct WalCkptInfo WalCkptInfo; + + +/* +** The following object holds a copy of the wal-index header content. +** +** The actual header in the wal-index consists of two copies of this +** object followed by one instance of the WalCkptInfo object. +** For all versions of SQLite through 3.10.0 and probably beyond, +** the locking bytes (WalCkptInfo.aLock) start at offset 120 and +** the total header size is 136 bytes. +** +** The szPage value can be any power of 2 between 512 and 32768, inclusive. +** Or it can be 1 to represent a 65536-byte page. The latter case was +** added in 3.7.1 when support for 64K pages was added. +*/ +struct WalIndexHdr { + u32 iVersion; /* Wal-index version */ + u32 unused; /* Unused (padding) field */ + u32 iChange; /* Counter incremented each transaction */ + u8 isInit; /* 1 when initialized */ + u8 bigEndCksum; /* True if checksums in WAL are big-endian */ + u16 szPage; /* Database page size in bytes. 1==64K */ + u32 mxFrame; /* Index of last valid frame in the WAL */ + u32 nPage; /* Size of database in pages */ + u32 aFrameCksum[2]; /* Checksum of last frame in log */ + u32 aSalt[2]; /* Two salt values copied from WAL header */ + u32 aCksum[2]; /* Checksum over all prior fields */ +}; + +/* +** A copy of the following object occurs in the wal-index immediately +** following the second copy of the WalIndexHdr. This object stores +** information used by checkpoint. +** +** nBackfill is the number of frames in the WAL that have been written +** back into the database. (We call the act of moving content from WAL to +** database "backfilling".) The nBackfill number is never greater than +** WalIndexHdr.mxFrame. nBackfill can only be increased by threads +** holding the WAL_CKPT_LOCK lock (which includes a recovery thread). +** However, a WAL_WRITE_LOCK thread can move the value of nBackfill from +** mxFrame back to zero when the WAL is reset. +** +** nBackfillAttempted is the largest value of nBackfill that a checkpoint +** has attempted to achieve. Normally nBackfill==nBackfillAtempted, however +** the nBackfillAttempted is set before any backfilling is done and the +** nBackfill is only set after all backfilling completes. So if a checkpoint +** crashes, nBackfillAttempted might be larger than nBackfill. The +** WalIndexHdr.mxFrame must never be less than nBackfillAttempted. +** +** The aLock[] field is a set of bytes used for locking. These bytes should +** never be read or written. +** +** There is one entry in aReadMark[] for each reader lock. If a reader +** holds read-lock K, then the value in aReadMark[K] is no greater than +** the mxFrame for that reader. The value READMARK_NOT_USED (0xffffffff) +** for any aReadMark[] means that entry is unused. aReadMark[0] is +** a special case; its value is never used and it exists as a place-holder +** to avoid having to offset aReadMark[] indexes by one. Readers holding +** WAL_READ_LOCK(0) always ignore the entire WAL and read all content +** directly from the database. +** +** The value of aReadMark[K] may only be changed by a thread that +** is holding an exclusive lock on WAL_READ_LOCK(K). Thus, the value of +** aReadMark[K] cannot changed while there is a reader is using that mark +** since the reader will be holding a shared lock on WAL_READ_LOCK(K). +** +** The checkpointer may only transfer frames from WAL to database where +** the frame numbers are less than or equal to every aReadMark[] that is +** in use (that is, every aReadMark[j] for which there is a corresponding +** WAL_READ_LOCK(j)). New readers (usually) pick the aReadMark[] with the +** largest value and will increase an unused aReadMark[] to mxFrame if there +** is not already an aReadMark[] equal to mxFrame. The exception to the +** previous sentence is when nBackfill equals mxFrame (meaning that everything +** in the WAL has been backfilled into the database) then new readers +** will choose aReadMark[0] which has value 0 and hence such reader will +** get all their all content directly from the database file and ignore +** the WAL. +** +** Writers normally append new frames to the end of the WAL. However, +** if nBackfill equals mxFrame (meaning that all WAL content has been +** written back into the database) and if no readers are using the WAL +** (in other words, if there are no WAL_READ_LOCK(i) where i>0) then +** the writer will first "reset" the WAL back to the beginning and start +** writing new content beginning at frame 1. +** +** We assume that 32-bit loads are atomic and so no locks are needed in +** order to read from any aReadMark[] entries. +*/ +struct WalCkptInfo { + u32 nBackfill; /* Number of WAL frames backfilled into DB */ + u32 aReadMark[WAL_NREADER]; /* Reader marks */ + u8 aLock[SQLITE_SHM_NLOCK]; /* Reserved space for locks */ + u32 nBackfillAttempted; /* WAL frames perhaps written, or maybe not */ + u32 notUsed0; /* Available for future enhancements */ +}; +#define READMARK_NOT_USED 0xffffffff + +/* +** This is a schematic view of the complete 136-byte header of the +** wal-index file (also known as the -shm file): +** +** +-----------------------------+ +** 0: | iVersion | \ +** +-----------------------------+ | +** 4: | (unused padding) | | +** +-----------------------------+ | +** 8: | iChange | | +** +-------+-------+-------------+ | +** 12: | bInit | bBig | szPage | | +** +-------+-------+-------------+ | +** 16: | mxFrame | | First copy of the +** +-----------------------------+ | WalIndexHdr object +** 20: | nPage | | +** +-----------------------------+ | +** 24: | aFrameCksum | | +** | | | +** +-----------------------------+ | +** 32: | aSalt | | +** | | | +** +-----------------------------+ | +** 40: | aCksum | | +** | | / +** +-----------------------------+ +** 48: | iVersion | \ +** +-----------------------------+ | +** 52: | (unused padding) | | +** +-----------------------------+ | +** 56: | iChange | | +** +-------+-------+-------------+ | +** 60: | bInit | bBig | szPage | | +** +-------+-------+-------------+ | Second copy of the +** 64: | mxFrame | | WalIndexHdr +** +-----------------------------+ | +** 68: | nPage | | +** +-----------------------------+ | +** 72: | aFrameCksum | | +** | | | +** +-----------------------------+ | +** 80: | aSalt | | +** | | | +** +-----------------------------+ | +** 88: | aCksum | | +** | | / +** +-----------------------------+ +** 96: | nBackfill | +** +-----------------------------+ +** 100: | 5 read marks | +** | | +** | | +** | | +** | | +** +-------+-------+------+------+ +** 120: | Write | Ckpt | Rcvr | Rd0 | \ +** +-------+-------+------+------+ ) 8 lock bytes +** | Read1 | Read2 | Rd3 | Rd4 | / +** +-------+-------+------+------+ +** 128: | nBackfillAttempted | +** +-----------------------------+ +** 132: | (unused padding) | +** +-----------------------------+ +*/ + +/* A block of WALINDEX_LOCK_RESERVED bytes beginning at +** WALINDEX_LOCK_OFFSET is reserved for locks. Since some systems +** only support mandatory file-locks, we do not read or write data +** from the region of the file on which locks are applied. +*/ +#define WALINDEX_LOCK_OFFSET (sizeof(WalIndexHdr)*2+offsetof(WalCkptInfo,aLock)) +#define WALINDEX_HDR_SIZE (sizeof(WalIndexHdr)*2+sizeof(WalCkptInfo)) + +/* Size of header before each frame in wal */ +#define WAL_FRAME_HDRSIZE 24 + +/* Size of write ahead log header, including checksum. */ +#define WAL_HDRSIZE 32 + +/* WAL magic value. Either this value, or the same value with the least +** significant bit also set (WAL_MAGIC | 0x00000001) is stored in 32-bit +** big-endian format in the first 4 bytes of a WAL file. +** +** If the LSB is set, then the checksums for each frame within the WAL +** file are calculated by treating all data as an array of 32-bit +** big-endian words. Otherwise, they are calculated by interpreting +** all data as 32-bit little-endian words. +*/ +#define WAL_MAGIC 0x377f0682 + +/* +** Return the offset of frame iFrame in the write-ahead log file, +** assuming a database page size of szPage bytes. The offset returned +** is to the start of the write-ahead log frame-header. +*/ +#define walFrameOffset(iFrame, szPage) ( \ + WAL_HDRSIZE + ((iFrame)-1)*(i64)((szPage)+WAL_FRAME_HDRSIZE) \ +) + +/* +** An open write-ahead log file is represented by an instance of the +** following object. +** +** writeLock: +** This is usually set to 1 whenever the WRITER lock is held. However, +** if it is set to 2, then the WRITER lock is held but must be released +** by walHandleException() if a SEH exception is thrown. +*/ +struct Wal { + sqlite3_vfs *pVfs; /* The VFS used to create pDbFd */ + sqlite3_file *pDbFd; /* File handle for the database file */ + sqlite3_file *pWalFd; /* File handle for WAL file */ + u32 iCallback; /* Value to pass to log callback (or 0) */ + i64 mxWalSize; /* Truncate WAL to this size upon reset */ + int nWiData; /* Size of array apWiData */ + int szFirstBlock; /* Size of first block written to WAL file */ + volatile u32 **apWiData; /* Pointer to wal-index content in memory */ + u32 szPage; /* Database page size */ + i16 readLock; /* Which read lock is being held. -1 for none */ + u8 syncFlags; /* Flags to use to sync header writes */ + u8 exclusiveMode; /* Non-zero if connection is in exclusive mode */ + u8 writeLock; /* True if in a write transaction */ + u8 ckptLock; /* True if holding a checkpoint lock */ + u8 readOnly; /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */ + u8 truncateOnCommit; /* True to truncate WAL file on commit */ + u8 syncHeader; /* Fsync the WAL header if true */ + u8 padToSectorBoundary; /* Pad transactions out to the next sector */ + u8 bShmUnreliable; /* SHM content is read-only and unreliable */ + WalIndexHdr hdr; /* Wal-index header for current transaction */ + u32 minFrame; /* Ignore wal frames before this one */ + u32 iReCksum; /* On commit, recalculate checksums from here */ + const char *zWalName; /* Name of WAL file */ + u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ +#ifdef SQLITE_USE_SEH + u32 lockMask; /* Mask of locks held */ + void *pFree; /* Pointer to sqlite3_free() if exception thrown */ + u32 *pWiValue; /* Value to write into apWiData[iWiPg] */ + int iWiPg; /* Write pWiValue into apWiData[iWiPg] */ + int iSysErrno; /* System error code following exception */ +#endif +#ifdef SQLITE_DEBUG + int nSehTry; /* Number of nested SEH_TRY{} blocks */ + u8 lockError; /* True if a locking error has occurred */ +#endif +#ifdef SQLITE_ENABLE_SNAPSHOT + WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */ + int bGetSnapshot; /* Transaction opened for sqlite3_get_snapshot() */ +#endif +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + sqlite3 *db; +#endif +}; + +/* +** Candidate values for Wal.exclusiveMode. +*/ +#define WAL_NORMAL_MODE 0 +#define WAL_EXCLUSIVE_MODE 1 +#define WAL_HEAPMEMORY_MODE 2 + +/* +** Possible values for WAL.readOnly +*/ +#define WAL_RDWR 0 /* Normal read/write connection */ +#define WAL_RDONLY 1 /* The WAL file is readonly */ +#define WAL_SHM_RDONLY 2 /* The SHM file is readonly */ + +/* +** Each page of the wal-index mapping contains a hash-table made up of +** an array of HASHTABLE_NSLOT elements of the following type. +*/ +typedef u16 ht_slot; + +/* +** This structure is used to implement an iterator that loops through +** all frames in the WAL in database page order. Where two or more frames +** correspond to the same database page, the iterator visits only the +** frame most recently written to the WAL (in other words, the frame with +** the largest index). +** +** The internals of this structure are only accessed by: +** +** walIteratorInit() - Create a new iterator, +** walIteratorNext() - Step an iterator, +** walIteratorFree() - Free an iterator. +** +** This functionality is used by the checkpoint code (see walCheckpoint()). +*/ +struct WalIterator { + u32 iPrior; /* Last result returned from the iterator */ + int nSegment; /* Number of entries in aSegment[] */ + struct WalSegment { + int iNext; /* Next slot in aIndex[] not yet returned */ + ht_slot *aIndex; /* i0, i1, i2... such that aPgno[iN] ascend */ + u32 *aPgno; /* Array of page numbers. */ + int nEntry; /* Nr. of entries in aPgno[] and aIndex[] */ + int iZero; /* Frame number associated with aPgno[0] */ + } aSegment[FLEXARRAY]; /* One for every 32KB page in the wal-index */ +}; + +/* Size (in bytes) of a WalIterator object suitable for N or fewer segments */ +#define SZ_WALITERATOR(N) \ + (offsetof(WalIterator,aSegment)+(N)*sizeof(struct WalSegment)) + +/* +** Define the parameters of the hash tables in the wal-index file. There +** is a hash-table following every HASHTABLE_NPAGE page numbers in the +** wal-index. +** +** Changing any of these constants will alter the wal-index format and +** create incompatibilities. +*/ +#define HASHTABLE_NPAGE 4096 /* Must be power of 2 */ +#define HASHTABLE_HASH_1 383 /* Should be prime */ +#define HASHTABLE_NSLOT (HASHTABLE_NPAGE*2) /* Must be a power of 2 */ + +/* +** The block of page numbers associated with the first hash-table in a +** wal-index is smaller than usual. This is so that there is a complete +** hash-table on each aligned 32KB page of the wal-index. +*/ +#define HASHTABLE_NPAGE_ONE (HASHTABLE_NPAGE - (WALINDEX_HDR_SIZE/sizeof(u32))) + +/* The wal-index is divided into pages of WALINDEX_PGSZ bytes each. */ +#define WALINDEX_PGSZ ( \ + sizeof(ht_slot)*HASHTABLE_NSLOT + HASHTABLE_NPAGE*sizeof(u32) \ +) + +/* +** Structured Exception Handling (SEH) is a Windows-specific technique +** for catching exceptions raised while accessing memory-mapped files. +** +** The -DSQLITE_USE_SEH compile-time option means to use SEH to catch and +** deal with system-level errors that arise during WAL -shm file processing. +** Without this compile-time option, any system-level faults that appear +** while accessing the memory-mapped -shm file will cause a process-wide +** signal to be deliver, which will more than likely cause the entire +** process to exit. +*/ +#ifdef SQLITE_USE_SEH +#include + +/* Beginning of a block of code in which an exception might occur */ +# define SEH_TRY __try { \ + assert( walAssertLockmask(pWal) && pWal->nSehTry==0 ); \ + VVA_ONLY(pWal->nSehTry++); + +/* The end of a block of code in which an exception might occur */ +# define SEH_EXCEPT(X) \ + VVA_ONLY(pWal->nSehTry--); \ + assert( pWal->nSehTry==0 ); \ + } __except( sehExceptionFilter(pWal, GetExceptionCode(), GetExceptionInformation() ) ){ X } + +/* Simulate a memory-mapping fault in the -shm file for testing purposes */ +# define SEH_INJECT_FAULT sehInjectFault(pWal) + +/* +** The second argument is the return value of GetExceptionCode() for the +** current exception. Return EXCEPTION_EXECUTE_HANDLER if the exception code +** indicates that the exception may have been caused by accessing the *-shm +** file mapping. Or EXCEPTION_CONTINUE_SEARCH otherwise. +*/ +static int sehExceptionFilter(Wal *pWal, int eCode, EXCEPTION_POINTERS *p){ + VVA_ONLY(pWal->nSehTry--); + if( eCode==EXCEPTION_IN_PAGE_ERROR ){ + if( p && p->ExceptionRecord && p->ExceptionRecord->NumberParameters>=3 ){ + /* From MSDN: For this type of exception, the first element of the + ** ExceptionInformation[] array is a read-write flag - 0 if the exception + ** was thrown while reading, 1 if while writing. The second element is + ** the virtual address being accessed. The "third array element specifies + ** the underlying NTSTATUS code that resulted in the exception". */ + pWal->iSysErrno = (int)p->ExceptionRecord->ExceptionInformation[2]; + } + return EXCEPTION_EXECUTE_HANDLER; + } + return EXCEPTION_CONTINUE_SEARCH; +} + +/* +** If one is configured, invoke the xTestCallback callback with 650 as +** the argument. If it returns true, throw the same exception that is +** thrown by the system if the *-shm file mapping is accessed after it +** has been invalidated. +*/ +static void sehInjectFault(Wal *pWal){ + int res; + assert( pWal->nSehTry>0 ); + + res = sqlite3FaultSim(650); + if( res!=0 ){ + ULONG_PTR aArg[3]; + aArg[0] = 0; + aArg[1] = 0; + aArg[2] = (ULONG_PTR)res; + RaiseException(EXCEPTION_IN_PAGE_ERROR, 0, 3, (const ULONG_PTR*)aArg); + } +} + +/* +** There are two ways to use this macro. To set a pointer to be freed +** if an exception is thrown: +** +** SEH_FREE_ON_ERROR(0, pPtr); +** +** and to cancel the same: +** +** SEH_FREE_ON_ERROR(pPtr, 0); +** +** In the first case, there must not already be a pointer registered to +** be freed. In the second case, pPtr must be the registered pointer. +*/ +#define SEH_FREE_ON_ERROR(X,Y) \ + assert( (X==0 || Y==0) && pWal->pFree==X ); pWal->pFree = Y + +/* +** There are two ways to use this macro. To arrange for pWal->apWiData[iPg] +** to be set to pValue if an exception is thrown: +** +** SEH_SET_ON_ERROR(iPg, pValue); +** +** and to cancel the same: +** +** SEH_SET_ON_ERROR(0, 0); +*/ +#define SEH_SET_ON_ERROR(X,Y) pWal->iWiPg = X; pWal->pWiValue = Y + +#else +# define SEH_TRY VVA_ONLY(pWal->nSehTry++); +# define SEH_EXCEPT(X) VVA_ONLY(pWal->nSehTry--); assert( pWal->nSehTry==0 ); +# define SEH_INJECT_FAULT assert( pWal->nSehTry>0 ); +# define SEH_FREE_ON_ERROR(X,Y) +# define SEH_SET_ON_ERROR(X,Y) +#endif /* ifdef SQLITE_USE_SEH */ + + +/* +** Obtain a pointer to the iPage'th page of the wal-index. The wal-index +** is broken into pages of WALINDEX_PGSZ bytes. Wal-index pages are +** numbered from zero. +** +** If the wal-index is currently smaller the iPage pages then the size +** of the wal-index might be increased, but only if it is safe to do +** so. It is safe to enlarge the wal-index if pWal->writeLock is true +** or pWal->exclusiveMode==WAL_HEAPMEMORY_MODE. +** +** Three possible result scenarios: +** +** (1) rc==SQLITE_OK and *ppPage==Requested-Wal-Index-Page +** (2) rc>=SQLITE_ERROR and *ppPage==NULL +** (3) rc==SQLITE_OK and *ppPage==NULL // only if iPage==0 +** +** Scenario (3) can only occur when pWal->writeLock is false and iPage==0 +*/ +static SQLITE_NOINLINE int walIndexPageRealloc( + Wal *pWal, /* The WAL context */ + int iPage, /* The page we seek */ + volatile u32 **ppPage /* Write the page pointer here */ +){ + int rc = SQLITE_OK; + + /* Enlarge the pWal->apWiData[] array if required */ + if( pWal->nWiData<=iPage ){ + sqlite3_int64 nByte = sizeof(u32*)*(1+(i64)iPage); + volatile u32 **apNew; + apNew = (volatile u32 **)sqlite3Realloc((void *)pWal->apWiData, nByte); + if( !apNew ){ + *ppPage = 0; + return SQLITE_NOMEM_BKPT; + } + memset((void*)&apNew[pWal->nWiData], 0, + sizeof(u32*)*(iPage+1-pWal->nWiData)); + pWal->apWiData = apNew; + pWal->nWiData = iPage+1; + } + + /* Request a pointer to the required page from the VFS */ + assert( pWal->apWiData[iPage]==0 ); + if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){ + pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ); + if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT; + }else{ + rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, + pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] + ); + assert( pWal->apWiData[iPage]!=0 + || rc!=SQLITE_OK + || (pWal->writeLock==0 && iPage==0) ); + testcase( pWal->apWiData[iPage]==0 && rc==SQLITE_OK ); + if( rc==SQLITE_OK ){ + if( iPage>0 && sqlite3FaultSim(600) ) rc = SQLITE_NOMEM; + }else if( (rc&0xff)==SQLITE_READONLY ){ + pWal->readOnly |= WAL_SHM_RDONLY; + if( rc==SQLITE_READONLY ){ + rc = SQLITE_OK; + } + } + } + + *ppPage = pWal->apWiData[iPage]; + assert( iPage==0 || *ppPage || rc!=SQLITE_OK ); + return rc; +} +static int walIndexPage( + Wal *pWal, /* The WAL context */ + int iPage, /* The page we seek */ + volatile u32 **ppPage /* Write the page pointer here */ +){ + SEH_INJECT_FAULT; + if( pWal->nWiData<=iPage || (*ppPage = pWal->apWiData[iPage])==0 ){ + return walIndexPageRealloc(pWal, iPage, ppPage); + } + return SQLITE_OK; +} + +/* +** Return a pointer to the WalCkptInfo structure in the wal-index. +*/ +static volatile WalCkptInfo *walCkptInfo(Wal *pWal){ + assert( pWal->nWiData>0 && pWal->apWiData[0] ); + SEH_INJECT_FAULT; + return (volatile WalCkptInfo*)&(pWal->apWiData[0][sizeof(WalIndexHdr)/2]); +} + +/* +** Return a pointer to the WalIndexHdr structure in the wal-index. +*/ +static volatile WalIndexHdr *walIndexHdr(Wal *pWal){ + assert( pWal->nWiData>0 && pWal->apWiData[0] ); + SEH_INJECT_FAULT; + return (volatile WalIndexHdr*)pWal->apWiData[0]; +} + +/* +** The argument to this macro must be of type u32. On a little-endian +** architecture, it returns the u32 value that results from interpreting +** the 4 bytes as a big-endian value. On a big-endian architecture, it +** returns the value that would be produced by interpreting the 4 bytes +** of the input value as a little-endian integer. +*/ +#define BYTESWAP32(x) ( \ + (((x)&0x000000FF)<<24) + (((x)&0x0000FF00)<<8) \ + + (((x)&0x00FF0000)>>8) + (((x)&0xFF000000)>>24) \ +) + +/* +** Generate or extend an 8 byte checksum based on the data in +** array aByte[] and the initial values of aIn[0] and aIn[1] (or +** initial values of 0 and 0 if aIn==NULL). +** +** The checksum is written back into aOut[] before returning. +** +** nByte must be a positive multiple of 8. +*/ +static void walChecksumBytes( + int nativeCksum, /* True for native byte-order, false for non-native */ + u8 *a, /* Content to be checksummed */ + int nByte, /* Bytes of content in a[]. Must be a multiple of 8. */ + const u32 *aIn, /* Initial checksum value input */ + u32 *aOut /* OUT: Final checksum value output */ +){ + u32 s1, s2; + u32 *aData = (u32 *)a; + u32 *aEnd = (u32 *)&a[nByte]; + + if( aIn ){ + s1 = aIn[0]; + s2 = aIn[1]; + }else{ + s1 = s2 = 0; + } + + /* nByte is a multiple of 8 between 8 and 65536 */ + assert( nByte>=8 && (nByte&7)==0 && nByte<=65536 ); + + if( !nativeCksum ){ + do { + s1 += BYTESWAP32(aData[0]) + s2; + s2 += BYTESWAP32(aData[1]) + s1; + aData += 2; + }while( aDataexclusiveMode!=WAL_HEAPMEMORY_MODE ){ + sqlite3OsShmBarrier(pWal->pDbFd); + } +} + +/* +** Add the SQLITE_NO_TSAN as part of the return-type of a function +** definition as a hint that the function contains constructs that +** might give false-positive TSAN warnings. +** +** See tag-20200519-1. +*/ +#if defined(__clang__) && !defined(SQLITE_NO_TSAN) +# define SQLITE_NO_TSAN __attribute__((no_sanitize_thread)) +#else +# define SQLITE_NO_TSAN +#endif + +/* +** Write the header information in pWal->hdr into the wal-index. +** +** The checksum on pWal->hdr is updated before it is written. +*/ +static SQLITE_NO_TSAN void walIndexWriteHdr(Wal *pWal){ + volatile WalIndexHdr *aHdr = walIndexHdr(pWal); + const int nCksum = offsetof(WalIndexHdr, aCksum); + + assert( pWal->writeLock ); + pWal->hdr.isInit = 1; + pWal->hdr.iVersion = WALINDEX_MAX_VERSION; + walChecksumBytes(1, (u8*)&pWal->hdr, nCksum, 0, pWal->hdr.aCksum); + /* Possible TSAN false-positive. See tag-20200519-1 */ + memcpy((void*)&aHdr[1], (const void*)&pWal->hdr, sizeof(WalIndexHdr)); + walShmBarrier(pWal); + memcpy((void*)&aHdr[0], (const void*)&pWal->hdr, sizeof(WalIndexHdr)); +} + +/* +** This function encodes a single frame header and writes it to a buffer +** supplied by the caller. A frame-header is made up of a series of +** 4-byte big-endian integers, as follows: +** +** 0: Page number. +** 4: For commit records, the size of the database image in pages +** after the commit. For all other records, zero. +** 8: Salt-1 (copied from the wal-header) +** 12: Salt-2 (copied from the wal-header) +** 16: Checksum-1. +** 20: Checksum-2. +*/ +static void walEncodeFrame( + Wal *pWal, /* The write-ahead log */ + u32 iPage, /* Database page number for frame */ + u32 nTruncate, /* New db size (or 0 for non-commit frames) */ + u8 *aData, /* Pointer to page data */ + u8 *aFrame /* OUT: Write encoded frame here */ +){ + int nativeCksum; /* True for native byte-order checksums */ + u32 *aCksum = pWal->hdr.aFrameCksum; + assert( WAL_FRAME_HDRSIZE==24 ); + sqlite3Put4byte(&aFrame[0], iPage); + sqlite3Put4byte(&aFrame[4], nTruncate); + if( pWal->iReCksum==0 ){ + memcpy(&aFrame[8], pWal->hdr.aSalt, 8); + + nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN); + walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum); + walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum); + + sqlite3Put4byte(&aFrame[16], aCksum[0]); + sqlite3Put4byte(&aFrame[20], aCksum[1]); + }else{ + memset(&aFrame[8], 0, 16); + } +} + +/* +** Check to see if the frame with header in aFrame[] and content +** in aData[] is valid. If it is a valid frame, fill *piPage and +** *pnTruncate and return true. Return if the frame is not valid. +*/ +static int walDecodeFrame( + Wal *pWal, /* The write-ahead log */ + u32 *piPage, /* OUT: Database page number for frame */ + u32 *pnTruncate, /* OUT: New db size (or 0 if not commit) */ + u8 *aData, /* Pointer to page data (for checksum) */ + u8 *aFrame /* Frame data */ +){ + int nativeCksum; /* True for native byte-order checksums */ + u32 *aCksum = pWal->hdr.aFrameCksum; + u32 pgno; /* Page number of the frame */ + assert( WAL_FRAME_HDRSIZE==24 ); + + /* A frame is only valid if the salt values in the frame-header + ** match the salt values in the wal-header. + */ + if( memcmp(&pWal->hdr.aSalt, &aFrame[8], 8)!=0 ){ + return 0; + } + + /* A frame is only valid if the page number is greater than zero. + */ + pgno = sqlite3Get4byte(&aFrame[0]); + if( pgno==0 ){ + return 0; + } + + /* Need a valid page size + */ + if( !pWal->szPage ){ + return 0; + } + + /* A frame is only valid if a checksum of the WAL header, + ** all prior frames, the first 16 bytes of this frame-header, + ** and the frame-data matches the checksum in the last 8 + ** bytes of this frame-header. + */ + nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN); + walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum); + walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum); + if( aCksum[0]!=sqlite3Get4byte(&aFrame[16]) + || aCksum[1]!=sqlite3Get4byte(&aFrame[20]) + ){ + /* Checksum failed. */ + return 0; + } + + /* If we reach this point, the frame is valid. Return the page number + ** and the new database size. + */ + *piPage = pgno; + *pnTruncate = sqlite3Get4byte(&aFrame[4]); + return 1; +} + + +#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) +/* +** Names of locks. This routine is used to provide debugging output and is not +** a part of an ordinary build. +*/ +static const char *walLockName(int lockIdx){ + if( lockIdx==WAL_WRITE_LOCK ){ + return "WRITE-LOCK"; + }else if( lockIdx==WAL_CKPT_LOCK ){ + return "CKPT-LOCK"; + }else if( lockIdx==WAL_RECOVER_LOCK ){ + return "RECOVER-LOCK"; + }else{ + static char zName[15]; + sqlite3_snprintf(sizeof(zName), zName, "READ-LOCK[%d]", + lockIdx-WAL_READ_LOCK(0)); + return zName; + } +} +#endif /*defined(SQLITE_TEST) || defined(SQLITE_DEBUG) */ + + +/* +** Set or release locks on the WAL. Locks are either shared or exclusive. +** A lock cannot be moved directly between shared and exclusive - it must go +** through the unlocked state first. +** +** In locking_mode=EXCLUSIVE, all of these routines become no-ops. +*/ +static int walLockShared(Wal *pWal, int lockIdx){ + int rc; + if( pWal->exclusiveMode ) return SQLITE_OK; + rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, + SQLITE_SHM_LOCK | SQLITE_SHM_SHARED); + WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal, + walLockName(lockIdx), rc ? "failed" : "ok")); + VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && (rc&0xFF)!=SQLITE_BUSY); ) +#ifdef SQLITE_USE_SEH + if( rc==SQLITE_OK ) pWal->lockMask |= (1 << lockIdx); +#endif + return rc; +} +static void walUnlockShared(Wal *pWal, int lockIdx){ + if( pWal->exclusiveMode ) return; + (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, + SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED); +#ifdef SQLITE_USE_SEH + pWal->lockMask &= ~(1 << lockIdx); +#endif + WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx))); +} +static int walLockExclusive(Wal *pWal, int lockIdx, int n){ + int rc; + if( pWal->exclusiveMode ) return SQLITE_OK; + rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, + SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE); + WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal, + walLockName(lockIdx), n, rc ? "failed" : "ok")); + VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && (rc&0xFF)!=SQLITE_BUSY); ) +#ifdef SQLITE_USE_SEH + if( rc==SQLITE_OK ){ + pWal->lockMask |= (((1<exclusiveMode ) return; + (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, + SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE); +#ifdef SQLITE_USE_SEH + pWal->lockMask &= ~(((1<0 ); + assert( (HASHTABLE_NSLOT & (HASHTABLE_NSLOT-1))==0 ); + return (iPage*HASHTABLE_HASH_1) & (HASHTABLE_NSLOT-1); +} +static int walNextHash(int iPriorHash){ + return (iPriorHash+1)&(HASHTABLE_NSLOT-1); +} + +/* +** An instance of the WalHashLoc object is used to describe the location +** of a page hash table in the wal-index. This becomes the return value +** from walHashGet(). +*/ +typedef struct WalHashLoc WalHashLoc; +struct WalHashLoc { + volatile ht_slot *aHash; /* Start of the wal-index hash table */ + volatile u32 *aPgno; /* aPgno[1] is the page of first frame indexed */ + u32 iZero; /* One less than the frame number of first indexed*/ +}; + +/* +** Return pointers to the hash table and page number array stored on +** page iHash of the wal-index. The wal-index is broken into 32KB pages +** numbered starting from 0. +** +** Set output variable pLoc->aHash to point to the start of the hash table +** in the wal-index file. Set pLoc->iZero to one less than the frame +** number of the first frame indexed by this hash table. If a +** slot in the hash table is set to N, it refers to frame number +** (pLoc->iZero+N) in the log. +** +** Finally, set pLoc->aPgno so that pLoc->aPgno[0] is the page number of the +** first frame indexed by the hash table, frame (pLoc->iZero). +*/ +static int walHashGet( + Wal *pWal, /* WAL handle */ + int iHash, /* Find the iHash'th table */ + WalHashLoc *pLoc /* OUT: Hash table location */ +){ + int rc; /* Return code */ + + rc = walIndexPage(pWal, iHash, &pLoc->aPgno); + assert( rc==SQLITE_OK || iHash>0 ); + + if( pLoc->aPgno ){ + pLoc->aHash = (volatile ht_slot *)&pLoc->aPgno[HASHTABLE_NPAGE]; + if( iHash==0 ){ + pLoc->aPgno = &pLoc->aPgno[WALINDEX_HDR_SIZE/sizeof(u32)]; + pLoc->iZero = 0; + }else{ + pLoc->iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE; + } + }else if( NEVER(rc==SQLITE_OK) ){ + rc = SQLITE_ERROR; + } + return rc; +} + +/* +** Return the number of the wal-index page that contains the hash-table +** and page-number array that contain entries corresponding to WAL frame +** iFrame. The wal-index is broken up into 32KB pages. Wal-index pages +** are numbered starting from 0. +*/ +static int walFramePage(u32 iFrame){ + int iHash = (iFrame+HASHTABLE_NPAGE-HASHTABLE_NPAGE_ONE-1) / HASHTABLE_NPAGE; + assert( (iHash==0 || iFrame>HASHTABLE_NPAGE_ONE) + && (iHash>=1 || iFrame<=HASHTABLE_NPAGE_ONE) + && (iHash<=1 || iFrame>(HASHTABLE_NPAGE_ONE+HASHTABLE_NPAGE)) + && (iHash>=2 || iFrame<=HASHTABLE_NPAGE_ONE+HASHTABLE_NPAGE) + && (iHash<=2 || iFrame>(HASHTABLE_NPAGE_ONE+2*HASHTABLE_NPAGE)) + ); + assert( iHash>=0 ); + return iHash; +} + +/* +** Return the page number associated with frame iFrame in this WAL. +*/ +static u32 walFramePgno(Wal *pWal, u32 iFrame){ + int iHash = walFramePage(iFrame); + SEH_INJECT_FAULT; + if( iHash==0 ){ + return pWal->apWiData[0][WALINDEX_HDR_SIZE/sizeof(u32) + iFrame - 1]; + } + return pWal->apWiData[iHash][(iFrame-1-HASHTABLE_NPAGE_ONE)%HASHTABLE_NPAGE]; +} + +/* +** Remove entries from the hash table that point to WAL slots greater +** than pWal->hdr.mxFrame. +** +** This function is called whenever pWal->hdr.mxFrame is decreased due +** to a rollback or savepoint. +** +** At most only the hash table containing pWal->hdr.mxFrame needs to be +** updated. Any later hash tables will be automatically cleared when +** pWal->hdr.mxFrame advances to the point where those hash tables are +** actually needed. +*/ +static void walCleanupHash(Wal *pWal){ + WalHashLoc sLoc; /* Hash table location */ + int iLimit = 0; /* Zero values greater than this */ + int nByte; /* Number of bytes to zero in aPgno[] */ + int i; /* Used to iterate through aHash[] */ + + assert( pWal->writeLock ); + testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE-1 ); + testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE ); + testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE+1 ); + + if( pWal->hdr.mxFrame==0 ) return; + + /* Obtain pointers to the hash-table and page-number array containing + ** the entry that corresponds to frame pWal->hdr.mxFrame. It is guaranteed + ** that the page said hash-table and array reside on is already mapped.(1) + */ + assert( pWal->nWiData>walFramePage(pWal->hdr.mxFrame) ); + assert( pWal->apWiData[walFramePage(pWal->hdr.mxFrame)] ); + i = walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &sLoc); + if( NEVER(i) ) return; /* Defense-in-depth, in case (1) above is wrong */ + + /* Zero all hash-table entries that correspond to frame numbers greater + ** than pWal->hdr.mxFrame. + */ + iLimit = pWal->hdr.mxFrame - sLoc.iZero; + assert( iLimit>0 ); + for(i=0; iiLimit ){ + sLoc.aHash[i] = 0; + } + } + + /* Zero the entries in the aPgno array that correspond to frames with + ** frame numbers greater than pWal->hdr.mxFrame. + */ + nByte = (int)((char *)sLoc.aHash - (char *)&sLoc.aPgno[iLimit]); + assert( nByte>=0 ); + memset((void *)&sLoc.aPgno[iLimit], 0, nByte); + +#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT + /* Verify that the every entry in the mapping region is still reachable + ** via the hash table even after the cleanup. + */ + if( iLimit ){ + int j; /* Loop counter */ + int iKey; /* Hash key */ + for(j=0; j=0 ); + memset((void*)sLoc.aPgno, 0, nByte); + } + + /* If the entry in aPgno[] is already set, then the previous writer + ** must have exited unexpectedly in the middle of a transaction (after + ** writing one or more dirty pages to the WAL to free up memory). + ** Remove the remnants of that writers uncommitted transaction from + ** the hash-table before writing any new entries. + */ + if( sLoc.aPgno[idx-1] ){ + walCleanupHash(pWal); + assert( !sLoc.aPgno[idx-1] ); + } + + /* Write the aPgno[] array entry and the hash-table slot. */ + nCollide = idx; + for(iKey=walHash(iPage); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){ + if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT; + } + sLoc.aPgno[(idx-1)&(HASHTABLE_NPAGE-1)] = iPage; + AtomicStore(&sLoc.aHash[iKey], (ht_slot)idx); + +#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT + /* Verify that the number of entries in the hash table exactly equals + ** the number of entries in the mapping region. + */ + { + int i; /* Loop counter */ + int nEntry = 0; /* Number of entries in the hash table */ + for(i=0; ickptLock==1 || pWal->ckptLock==0 ); + assert( WAL_ALL_BUT_WRITE==WAL_WRITE_LOCK+1 ); + assert( WAL_CKPT_LOCK==WAL_ALL_BUT_WRITE ); + assert( pWal->writeLock ); + iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock; + rc = walLockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock); + if( rc ){ + return rc; + } + + WALTRACE(("WAL%p: recovery begin...\n", pWal)); + + memset(&pWal->hdr, 0, sizeof(WalIndexHdr)); + + rc = sqlite3OsFileSize(pWal->pWalFd, &nSize); + if( rc!=SQLITE_OK ){ + goto recovery_error; + } + + if( nSize>WAL_HDRSIZE ){ + u8 aBuf[WAL_HDRSIZE]; /* Buffer to load WAL header into */ + u32 *aPrivate = 0; /* Heap copy of *-shm hash being populated */ + u8 *aFrame = 0; /* Malloc'd buffer to load entire frame */ + int szFrame; /* Number of bytes in buffer aFrame[] */ + u8 *aData; /* Pointer to data part of aFrame buffer */ + int szPage; /* Page size according to the log */ + u32 magic; /* Magic value read from WAL header */ + u32 version; /* Magic value read from WAL header */ + int isValid; /* True if this frame is valid */ + u32 iPg; /* Current 32KB wal-index page */ + u32 iLastFrame; /* Last frame in wal, based on nSize alone */ + + /* Read in the WAL header. */ + rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0); + if( rc!=SQLITE_OK ){ + goto recovery_error; + } + + /* If the database page size is not a power of two, or is greater than + ** SQLITE_MAX_PAGE_SIZE, conclude that the WAL file contains no valid + ** data. Similarly, if the 'magic' value is invalid, ignore the whole + ** WAL file. + */ + magic = sqlite3Get4byte(&aBuf[0]); + szPage = sqlite3Get4byte(&aBuf[8]); + if( (magic&0xFFFFFFFE)!=WAL_MAGIC + || szPage&(szPage-1) + || szPage>SQLITE_MAX_PAGE_SIZE + || szPage<512 + ){ + goto finished; + } + pWal->hdr.bigEndCksum = (u8)(magic&0x00000001); + pWal->szPage = szPage; + pWal->nCkpt = sqlite3Get4byte(&aBuf[12]); + memcpy(&pWal->hdr.aSalt, &aBuf[16], 8); + + /* Verify that the WAL header checksum is correct */ + walChecksumBytes(pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN, + aBuf, WAL_HDRSIZE-2*4, 0, pWal->hdr.aFrameCksum + ); + if( pWal->hdr.aFrameCksum[0]!=sqlite3Get4byte(&aBuf[24]) + || pWal->hdr.aFrameCksum[1]!=sqlite3Get4byte(&aBuf[28]) + ){ + goto finished; + } + + /* Verify that the version number on the WAL format is one that + ** are able to understand */ + version = sqlite3Get4byte(&aBuf[4]); + if( version!=WAL_MAX_VERSION ){ + rc = SQLITE_CANTOPEN_BKPT; + goto finished; + } + + /* Malloc a buffer to read frames into. */ + szFrame = szPage + WAL_FRAME_HDRSIZE; + aFrame = (u8 *)sqlite3_malloc64(szFrame + WALINDEX_PGSZ); + SEH_FREE_ON_ERROR(0, aFrame); + if( !aFrame ){ + rc = SQLITE_NOMEM_BKPT; + goto recovery_error; + } + aData = &aFrame[WAL_FRAME_HDRSIZE]; + aPrivate = (u32*)&aData[szPage]; + + /* Read all frames from the log file. */ + iLastFrame = (nSize - WAL_HDRSIZE) / szFrame; + for(iPg=0; iPg<=(u32)walFramePage(iLastFrame); iPg++){ + u32 *aShare; + u32 iFrame; /* Index of last frame read */ + u32 iLast = MIN(iLastFrame, HASHTABLE_NPAGE_ONE+iPg*HASHTABLE_NPAGE); + u32 iFirst = 1 + (iPg==0?0:HASHTABLE_NPAGE_ONE+(iPg-1)*HASHTABLE_NPAGE); + u32 nHdr, nHdr32; + rc = walIndexPage(pWal, iPg, (volatile u32**)&aShare); + assert( aShare!=0 || rc!=SQLITE_OK ); + if( aShare==0 ) break; + SEH_SET_ON_ERROR(iPg, aShare); + pWal->apWiData[iPg] = aPrivate; + + for(iFrame=iFirst; iFrame<=iLast; iFrame++){ + i64 iOffset = walFrameOffset(iFrame, szPage); + u32 pgno; /* Database page number for frame */ + u32 nTruncate; /* dbsize field from frame header */ + + /* Read and decode the next log frame. */ + rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset); + if( rc!=SQLITE_OK ) break; + isValid = walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame); + if( !isValid ) break; + rc = walIndexAppend(pWal, iFrame, pgno); + if( NEVER(rc!=SQLITE_OK) ) break; + + /* If nTruncate is non-zero, this is a commit record. */ + if( nTruncate ){ + pWal->hdr.mxFrame = iFrame; + pWal->hdr.nPage = nTruncate; + pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16)); + testcase( szPage<=32768 ); + testcase( szPage>=65536 ); + aFrameCksum[0] = pWal->hdr.aFrameCksum[0]; + aFrameCksum[1] = pWal->hdr.aFrameCksum[1]; + } + } + pWal->apWiData[iPg] = aShare; + SEH_SET_ON_ERROR(0,0); + nHdr = (iPg==0 ? WALINDEX_HDR_SIZE : 0); + nHdr32 = nHdr / sizeof(u32); +#ifndef SQLITE_SAFER_WALINDEX_RECOVERY + /* Memcpy() should work fine here, on all reasonable implementations. + ** Technically, memcpy() might change the destination to some + ** intermediate value before setting to the final value, and that might + ** cause a concurrent reader to malfunction. Memcpy() is allowed to + ** do that, according to the spec, but no memcpy() implementation that + ** we know of actually does that, which is why we say that memcpy() + ** is safe for this. Memcpy() is certainly a lot faster. + */ + memcpy(&aShare[nHdr32], &aPrivate[nHdr32], WALINDEX_PGSZ-nHdr); +#else + /* In the event that some platform is found for which memcpy() + ** changes the destination to some intermediate value before + ** setting the final value, this alternative copy routine is + ** provided. + */ + { + int i; + for(i=nHdr32; ihdr.aFrameCksum[0] = aFrameCksum[0]; + pWal->hdr.aFrameCksum[1] = aFrameCksum[1]; + walIndexWriteHdr(pWal); + + /* Reset the checkpoint-header. This is safe because this thread is + ** currently holding locks that exclude all other writers and + ** checkpointers. Then set the values of read-mark slots 1 through N. + */ + pInfo = walCkptInfo(pWal); + pInfo->nBackfill = 0; + pInfo->nBackfillAttempted = pWal->hdr.mxFrame; + pInfo->aReadMark[0] = 0; + for(i=1; ihdr.mxFrame ){ + pInfo->aReadMark[i] = pWal->hdr.mxFrame; + }else{ + pInfo->aReadMark[i] = READMARK_NOT_USED; + } + SEH_INJECT_FAULT; + walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); + }else if( rc!=SQLITE_BUSY ){ + goto recovery_error; + } + } + + /* If more than one frame was recovered from the log file, report an + ** event via sqlite3_log(). This is to help with identifying performance + ** problems caused by applications routinely shutting down without + ** checkpointing the log file. + */ + if( pWal->hdr.nPage ){ + sqlite3_log(SQLITE_NOTICE_RECOVER_WAL, + "recovered %d frames from WAL file %s", + pWal->hdr.mxFrame, pWal->zWalName + ); + } + } + +recovery_error: + WALTRACE(("WAL%p: recovery %s\n", pWal, rc ? "failed" : "ok")); + walUnlockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock); + return rc; +} + +/* +** Close an open wal-index. +*/ +static void walIndexClose(Wal *pWal, int isDelete){ + if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE || pWal->bShmUnreliable ){ + int i; + for(i=0; inWiData; i++){ + sqlite3_free((void *)pWal->apWiData[i]); + pWal->apWiData[i] = 0; + } + } + if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){ + sqlite3OsShmUnmap(pWal->pDbFd, isDelete); + } +} + +/* +** Open a connection to the WAL file zWalName. The database file must +** already be opened on connection pDbFd. The buffer that zWalName points +** to must remain valid for the lifetime of the returned Wal* handle. +** +** A SHARED lock should be held on the database file when this function +** is called. The purpose of this SHARED lock is to prevent any other +** client from unlinking the WAL or wal-index file. If another process +** were to do this just after this client opened one of these files, the +** system would be badly broken. +** +** If the log file is successfully opened, SQLITE_OK is returned and +** *ppWal is set to point to a new WAL handle. If an error occurs, +** an SQLite error code is returned and *ppWal is left unmodified. +*/ +SQLITE_PRIVATE int sqlite3WalOpen( + sqlite3_vfs *pVfs, /* vfs module to open wal and wal-index */ + sqlite3_file *pDbFd, /* The open database file */ + const char *zWalName, /* Name of the WAL file */ + int bNoShm, /* True to run in heap-memory mode */ + i64 mxWalSize, /* Truncate WAL to this size on reset */ + Wal **ppWal /* OUT: Allocated Wal handle */ +){ + int rc; /* Return Code */ + Wal *pRet; /* Object to allocate and return */ + int flags; /* Flags passed to OsOpen() */ + + assert( zWalName && zWalName[0] ); + assert( pDbFd ); + + /* Verify the values of various constants. Any changes to the values + ** of these constants would result in an incompatible on-disk format + ** for the -shm file. Any change that causes one of these asserts to + ** fail is a backward compatibility problem, even if the change otherwise + ** works. + ** + ** This table also serves as a helpful cross-reference when trying to + ** interpret hex dumps of the -shm file. + */ + assert( 48 == sizeof(WalIndexHdr) ); + assert( 40 == sizeof(WalCkptInfo) ); + assert( 120 == WALINDEX_LOCK_OFFSET ); + assert( 136 == WALINDEX_HDR_SIZE ); + assert( 4096 == HASHTABLE_NPAGE ); + assert( 4062 == HASHTABLE_NPAGE_ONE ); + assert( 8192 == HASHTABLE_NSLOT ); + assert( 383 == HASHTABLE_HASH_1 ); + assert( 32768 == WALINDEX_PGSZ ); + assert( 8 == SQLITE_SHM_NLOCK ); + assert( 5 == WAL_NREADER ); + assert( 24 == WAL_FRAME_HDRSIZE ); + assert( 32 == WAL_HDRSIZE ); + assert( 120 == WALINDEX_LOCK_OFFSET + WAL_WRITE_LOCK ); + assert( 121 == WALINDEX_LOCK_OFFSET + WAL_CKPT_LOCK ); + assert( 122 == WALINDEX_LOCK_OFFSET + WAL_RECOVER_LOCK ); + assert( 123 == WALINDEX_LOCK_OFFSET + WAL_READ_LOCK(0) ); + assert( 124 == WALINDEX_LOCK_OFFSET + WAL_READ_LOCK(1) ); + assert( 125 == WALINDEX_LOCK_OFFSET + WAL_READ_LOCK(2) ); + assert( 126 == WALINDEX_LOCK_OFFSET + WAL_READ_LOCK(3) ); + assert( 127 == WALINDEX_LOCK_OFFSET + WAL_READ_LOCK(4) ); + + /* In the amalgamation, the os_unix.c and os_win.c source files come before + ** this source file. Verify that the #defines of the locking byte offsets + ** in os_unix.c and os_win.c agree with the WALINDEX_LOCK_OFFSET value. + ** For that matter, if the lock offset ever changes from its initial design + ** value of 120, we need to know that so there is an assert() to check it. + */ +#ifdef WIN_SHM_BASE + assert( WIN_SHM_BASE==WALINDEX_LOCK_OFFSET ); +#endif +#ifdef UNIX_SHM_BASE + assert( UNIX_SHM_BASE==WALINDEX_LOCK_OFFSET ); +#endif + + + /* Allocate an instance of struct Wal to return. */ + *ppWal = 0; + pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile); + if( !pRet ){ + return SQLITE_NOMEM_BKPT; + } + + pRet->pVfs = pVfs; + pRet->pWalFd = (sqlite3_file *)&pRet[1]; + pRet->pDbFd = pDbFd; + pRet->readLock = -1; + pRet->mxWalSize = mxWalSize; + pRet->zWalName = zWalName; + pRet->syncHeader = 1; + pRet->padToSectorBoundary = 1; + pRet->exclusiveMode = (bNoShm ? WAL_HEAPMEMORY_MODE: WAL_NORMAL_MODE); + + /* Open file handle on the write-ahead log file. */ + flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL); + rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags); + if( rc==SQLITE_OK && flags&SQLITE_OPEN_READONLY ){ + pRet->readOnly = WAL_RDONLY; + } + + if( rc!=SQLITE_OK ){ + walIndexClose(pRet, 0); + sqlite3OsClose(pRet->pWalFd); + sqlite3_free(pRet); + }else{ + int iDC = sqlite3OsDeviceCharacteristics(pDbFd); + if( iDC & SQLITE_IOCAP_SEQUENTIAL ){ pRet->syncHeader = 0; } + if( iDC & SQLITE_IOCAP_POWERSAFE_OVERWRITE ){ + pRet->padToSectorBoundary = 0; + } + *ppWal = pRet; + WALTRACE(("WAL%d: opened\n", pRet)); + } + return rc; +} + +/* +** Change the size to which the WAL file is truncated on each reset. +*/ +SQLITE_PRIVATE void sqlite3WalLimit(Wal *pWal, i64 iLimit){ + if( pWal ) pWal->mxWalSize = iLimit; +} + +/* +** Find the smallest page number out of all pages held in the WAL that +** has not been returned by any prior invocation of this method on the +** same WalIterator object. Write into *piFrame the frame index where +** that page was last written into the WAL. Write into *piPage the page +** number. +** +** Return 0 on success. If there are no pages in the WAL with a page +** number larger than *piPage, then return 1. +*/ +static int walIteratorNext( + WalIterator *p, /* Iterator */ + u32 *piPage, /* OUT: The page number of the next page */ + u32 *piFrame /* OUT: Wal frame index of next page */ +){ + u32 iMin; /* Result pgno must be greater than iMin */ + u32 iRet = 0xFFFFFFFF; /* 0xffffffff is never a valid page number */ + int i; /* For looping through segments */ + + iMin = p->iPrior; + assert( iMin<0xffffffff ); + for(i=p->nSegment-1; i>=0; i--){ + struct WalSegment *pSegment = &p->aSegment[i]; + while( pSegment->iNextnEntry ){ + u32 iPg = pSegment->aPgno[pSegment->aIndex[pSegment->iNext]]; + if( iPg>iMin ){ + if( iPgiZero + pSegment->aIndex[pSegment->iNext]; + } + break; + } + pSegment->iNext++; + } + } + + *piPage = p->iPrior = iRet; + return (iRet==0xFFFFFFFF); +} + +/* +** This function merges two sorted lists into a single sorted list. +** +** aLeft[] and aRight[] are arrays of indices. The sort key is +** aContent[aLeft[]] and aContent[aRight[]]. Upon entry, the following +** is guaranteed for all J0 && nRight>0 ); + while( iRight=nRight || aContent[aLeft[iLeft]]=nLeft || aContent[aLeft[iLeft]]>dbpage ); + assert( iRight>=nRight || aContent[aRight[iRight]]>dbpage ); + } + + *paRight = aLeft; + *pnRight = iOut; + memcpy(aLeft, aTmp, sizeof(aTmp[0])*iOut); +} + +/* +** Sort the elements in list aList using aContent[] as the sort key. +** Remove elements with duplicate keys, preferring to keep the +** larger aList[] values. +** +** The aList[] entries are indices into aContent[]. The values in +** aList[] are to be sorted so that for all J0 ); + assert( HASHTABLE_NPAGE==(1<<(ArraySize(aSub)-1)) ); + + for(iList=0; iListaList && p->nList<=(1<aList==&aList[iList&~((2<aList, p->nList, &aMerge, &nMerge, aBuffer); + } + aSub[iSub].aList = aMerge; + aSub[iSub].nList = nMerge; + } + + for(iSub++; iSubnList<=(1<aList==&aList[nList&~((2<aList, p->nList, &aMerge, &nMerge, aBuffer); + } + } + assert( aMerge==aList ); + *pnList = nMerge; + +#ifdef SQLITE_DEBUG + { + int i; + for(i=1; i<*pnList; i++){ + assert( aContent[aList[i]] > aContent[aList[i-1]] ); + } + } +#endif +} + +/* +** Free an iterator allocated by walIteratorInit(). +*/ +static void walIteratorFree(WalIterator *p){ + sqlite3_free(p); +} + +/* +** Construct a WalInterator object that can be used to loop over all +** pages in the WAL following frame nBackfill in ascending order. Frames +** nBackfill or earlier may be included - excluding them is an optimization +** only. The caller must hold the checkpoint lock. +** +** On success, make *pp point to the newly allocated WalInterator object +** return SQLITE_OK. Otherwise, return an error code. If this routine +** returns an error, the value of *pp is undefined. +** +** The calling routine should invoke walIteratorFree() to destroy the +** WalIterator object when it has finished with it. +*/ +static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){ + WalIterator *p; /* Return value */ + int nSegment; /* Number of segments to merge */ + u32 iLast; /* Last frame in log */ + sqlite3_int64 nByte; /* Number of bytes to allocate */ + int i; /* Iterator variable */ + ht_slot *aTmp; /* Temp space used by merge-sort */ + int rc = SQLITE_OK; /* Return Code */ + + /* This routine only runs while holding the checkpoint lock. And + ** it only runs if there is actually content in the log (mxFrame>0). + */ + assert( pWal->ckptLock && pWal->hdr.mxFrame>0 ); + iLast = pWal->hdr.mxFrame; + + /* Allocate space for the WalIterator object. */ + nSegment = walFramePage(iLast) + 1; + nByte = SZ_WALITERATOR(nSegment) + + iLast*sizeof(ht_slot); + p = (WalIterator *)sqlite3_malloc64(nByte + + sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast) + ); + if( !p ){ + return SQLITE_NOMEM_BKPT; + } + memset(p, 0, nByte); + p->nSegment = nSegment; + aTmp = (ht_slot*)&(((u8*)p)[nByte]); + SEH_FREE_ON_ERROR(0, p); + for(i=walFramePage(nBackfill+1); rc==SQLITE_OK && iaSegment[p->nSegment])[sLoc.iZero]; + sLoc.iZero++; + + for(j=0; jaSegment[i].iZero = sLoc.iZero; + p->aSegment[i].nEntry = nEntry; + p->aSegment[i].aIndex = aIndex; + p->aSegment[i].aPgno = (u32 *)sLoc.aPgno; + } + } + if( rc!=SQLITE_OK ){ + SEH_FREE_ON_ERROR(p, 0); + walIteratorFree(p); + p = 0; + } + *pp = p; + return rc; +} + +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + + +/* +** Attempt to enable blocking locks that block for nMs ms. Return 1 if +** blocking locks are successfully enabled, or 0 otherwise. +*/ +static int walEnableBlockingMs(Wal *pWal, int nMs){ + int rc = sqlite3OsFileControl( + pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&nMs + ); + return (rc==SQLITE_OK); +} + +/* +** Attempt to enable blocking locks. Blocking locks are enabled only if (a) +** they are supported by the VFS, and (b) the database handle is configured +** with a busy-timeout. Return 1 if blocking locks are successfully enabled, +** or 0 otherwise. +*/ +static int walEnableBlocking(Wal *pWal){ + int res = 0; + if( pWal->db ){ + int tmout = pWal->db->setlkTimeout; + if( tmout ){ + res = walEnableBlockingMs(pWal, tmout); + } + } + return res; +} + +/* +** Disable blocking locks. +*/ +static void walDisableBlocking(Wal *pWal){ + int tmout = 0; + sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout); +} + +/* +** If parameter bLock is true, attempt to enable blocking locks, take +** the WRITER lock, and then disable blocking locks. If blocking locks +** cannot be enabled, no attempt to obtain the WRITER lock is made. Return +** an SQLite error code if an error occurs, or SQLITE_OK otherwise. It is not +** an error if blocking locks can not be enabled. +** +** If the bLock parameter is false and the WRITER lock is held, release it. +*/ +SQLITE_PRIVATE int sqlite3WalWriteLock(Wal *pWal, int bLock){ + int rc = SQLITE_OK; + assert( pWal->readLock<0 || bLock==0 ); + if( bLock ){ + assert( pWal->db ); + if( walEnableBlocking(pWal) ){ + rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1); + if( rc==SQLITE_OK ){ + pWal->writeLock = 1; + } + walDisableBlocking(pWal); + } + }else if( pWal->writeLock ){ + walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); + pWal->writeLock = 0; + } + return rc; +} + +/* +** Set the database handle used to determine if blocking locks are required. +*/ +SQLITE_PRIVATE void sqlite3WalDb(Wal *pWal, sqlite3 *db){ + pWal->db = db; +} + +#else +# define walEnableBlocking(x) 0 +# define walDisableBlocking(x) +# define walEnableBlockingMs(pWal, ms) 0 +# define sqlite3WalDb(pWal, db) +#endif /* ifdef SQLITE_ENABLE_SETLK_TIMEOUT */ + + +/* +** Attempt to obtain the exclusive WAL lock defined by parameters lockIdx and +** n. If the attempt fails and parameter xBusy is not NULL, then it is a +** busy-handler function. Invoke it and retry the lock until either the +** lock is successfully obtained or the busy-handler returns 0. +*/ +static int walBusyLock( + Wal *pWal, /* WAL connection */ + int (*xBusy)(void*), /* Function to call when busy */ + void *pBusyArg, /* Context argument for xBusyHandler */ + int lockIdx, /* Offset of first byte to lock */ + int n /* Number of bytes to lock */ +){ + int rc; + do { + rc = walLockExclusive(pWal, lockIdx, n); + }while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) ); +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + if( rc==SQLITE_BUSY_TIMEOUT ){ + walDisableBlocking(pWal); + rc = SQLITE_BUSY; + } +#endif + return rc; +} + +/* +** The cache of the wal-index header must be valid to call this function. +** Return the page-size in bytes used by the database. +*/ +static int walPagesize(Wal *pWal){ + return (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16); +} + +/* +** The following is guaranteed when this function is called: +** +** a) the WRITER lock is held, +** b) the entire log file has been checkpointed, and +** c) any existing readers are reading exclusively from the database +** file - there are no readers that may attempt to read a frame from +** the log file. +** +** This function updates the shared-memory structures so that the next +** client to write to the database (which may be this one) does so by +** writing frames into the start of the log file. +** +** The value of parameter salt1 is used as the aSalt[1] value in the +** new wal-index header. It should be passed a pseudo-random value (i.e. +** one obtained from sqlite3_randomness()). +*/ +static void walRestartHdr(Wal *pWal, u32 salt1){ + volatile WalCkptInfo *pInfo = walCkptInfo(pWal); + int i; /* Loop counter */ + u32 *aSalt = pWal->hdr.aSalt; /* Big-endian salt values */ + pWal->nCkpt++; + pWal->hdr.mxFrame = 0; + sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0])); + memcpy(&pWal->hdr.aSalt[1], &salt1, 4); + walIndexWriteHdr(pWal); + AtomicStore(&pInfo->nBackfill, 0); + pInfo->nBackfillAttempted = 0; + pInfo->aReadMark[1] = 0; + for(i=2; iaReadMark[i] = READMARK_NOT_USED; + assert( pInfo->aReadMark[0]==0 ); +} + +/* +** Copy as much content as we can from the WAL back into the database file +** in response to an sqlite3_wal_checkpoint() request or the equivalent. +** +** The amount of information copies from WAL to database might be limited +** by active readers. This routine will never overwrite a database page +** that a concurrent reader might be using. +** +** All I/O barrier operations (a.k.a fsyncs) occur in this routine when +** SQLite is in WAL-mode in synchronous=NORMAL. That means that if +** checkpoints are always run by a background thread or background +** process, foreground threads will never block on a lengthy fsync call. +** +** Fsync is called on the WAL before writing content out of the WAL and +** into the database. This ensures that if the new content is persistent +** in the WAL and can be recovered following a power-loss or hard reset. +** +** Fsync is also called on the database file if (and only if) the entire +** WAL content is copied into the database file. This second fsync makes +** it safe to delete the WAL since the new content will persist in the +** database file. +** +** This routine uses and updates the nBackfill field of the wal-index header. +** This is the only routine that will increase the value of nBackfill. +** (A WAL reset or recovery will revert nBackfill to zero, but not increase +** its value.) +** +** The caller must be holding sufficient locks to ensure that no other +** checkpoint is running (in any other thread or process) at the same +** time. +*/ +static int walCheckpoint( + Wal *pWal, /* Wal connection */ + sqlite3 *db, /* Check for interrupts on this handle */ + int eMode, /* One of PASSIVE, FULL or RESTART */ + int (*xBusy)(void*), /* Function to call when busy */ + void *pBusyArg, /* Context argument for xBusyHandler */ + int sync_flags, /* Flags for OsSync() (or 0) */ + u8 *zBuf /* Temporary buffer to use */ +){ + int rc = SQLITE_OK; /* Return code */ + int szPage; /* Database page-size */ + WalIterator *pIter = 0; /* Wal iterator context */ + u32 iDbpage = 0; /* Next database page to write */ + u32 iFrame = 0; /* Wal frame containing data for iDbpage */ + u32 mxSafeFrame; /* Max frame that can be backfilled */ + u32 mxPage; /* Max database page to write */ + int i; /* Loop counter */ + volatile WalCkptInfo *pInfo; /* The checkpoint status information */ + + szPage = walPagesize(pWal); + testcase( szPage<=32768 ); + testcase( szPage>=65536 ); + pInfo = walCkptInfo(pWal); + if( pInfo->nBackfillhdr.mxFrame ){ + + /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked + ** in the SQLITE_CHECKPOINT_PASSIVE mode. */ + assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 ); + + /* Compute in mxSafeFrame the index of the last frame of the WAL that is + ** safe to write into the database. Frames beyond mxSafeFrame might + ** overwrite database pages that are in use by active readers and thus + ** cannot be backfilled from the WAL. + */ + mxSafeFrame = pWal->hdr.mxFrame; + mxPage = pWal->hdr.nPage; + for(i=1; iaReadMark+i); SEH_INJECT_FAULT; + if( mxSafeFrame>y ){ + assert( y<=pWal->hdr.mxFrame ); + rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1); + if( rc==SQLITE_OK ){ + u32 iMark = (i==1 ? mxSafeFrame : READMARK_NOT_USED); + AtomicStore(pInfo->aReadMark+i, iMark); SEH_INJECT_FAULT; + walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); + }else if( rc==SQLITE_BUSY ){ + mxSafeFrame = y; + xBusy = 0; + }else{ + goto walcheckpoint_out; + } + } + } + + /* Allocate the iterator */ + if( pInfo->nBackfillnBackfill, &pIter); + assert( rc==SQLITE_OK || pIter==0 ); + } + + if( pIter + && (rc = walBusyLock(pWal,xBusy,pBusyArg,WAL_READ_LOCK(0),1))==SQLITE_OK + ){ + u32 nBackfill = pInfo->nBackfill; + WalIndexHdr *pLive = (WalIndexHdr*)walIndexHdr(pWal); + + /* Now that read-lock slot 0 is locked, check that the wal has not been + ** wrapped since the header was read for this checkpoint. If it was, then + ** there was no work to do anyway. In this case the + ** (pInfo->nBackfillhdr.mxFrame) test above only passed because + ** pInfo->nBackfill had already been set to 0 by the writer that wrapped + ** the wal file. It would also be dangerous to proceed, as there may be + ** fewer than pWal->hdr.mxFrame valid frames in the wal file. */ + int bChg = memcmp(pLive->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt)); + if( 0==bChg ){ + pInfo->nBackfillAttempted = mxSafeFrame; SEH_INJECT_FAULT; + + /* Sync the WAL to disk */ + rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags)); + + /* If the database may grow as a result of this checkpoint, hint + ** about the eventual size of the db file to the VFS layer. + */ + if( rc==SQLITE_OK ){ + i64 nReq = ((i64)mxPage * szPage); + i64 nSize; /* Current size of database file */ + sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_START, 0); + rc = sqlite3OsFileSize(pWal->pDbFd, &nSize); + if( rc==SQLITE_OK && nSizehdr.mxFrame*szPage)pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq); + } + } + + } + + /* Iterate through the contents of the WAL, copying data to the + ** db file */ + while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){ + i64 iOffset; + assert( walFramePgno(pWal, iFrame)==iDbpage ); + SEH_INJECT_FAULT; + if( AtomicLoad(&db->u1.isInterrupted) ){ + rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT; + break; + } + if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){ + continue; + } + iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE; + /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */ + rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset); + if( rc!=SQLITE_OK ) break; + iOffset = (iDbpage-1)*(i64)szPage; + testcase( IS_BIG_INT(iOffset) ); + rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset); + if( rc!=SQLITE_OK ) break; + } + sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_DONE, 0); + + /* If work was actually accomplished... */ + if( rc==SQLITE_OK ){ + if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){ + i64 szDb = pWal->hdr.nPage*(i64)szPage; + testcase( IS_BIG_INT(szDb) ); + rc = sqlite3OsTruncate(pWal->pDbFd, szDb); + if( rc==SQLITE_OK ){ + rc = sqlite3OsSync(pWal->pDbFd, CKPT_SYNC_FLAGS(sync_flags)); + } + } + if( rc==SQLITE_OK ){ + AtomicStore(&pInfo->nBackfill, mxSafeFrame); SEH_INJECT_FAULT; + } + } + } + + /* Release the reader lock held while backfilling */ + walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1); + } + + if( rc==SQLITE_BUSY ){ + /* Reset the return code so as not to report a checkpoint failure + ** just because there are active readers. */ + rc = SQLITE_OK; + } + } + + /* If this is an SQLITE_CHECKPOINT_RESTART or TRUNCATE operation, and the + ** entire wal file has been copied into the database file, then block + ** until all readers have finished using the wal file. This ensures that + ** the next process to write to the database restarts the wal file. + */ + if( rc==SQLITE_OK && eMode!=SQLITE_CHECKPOINT_PASSIVE ){ + assert( pWal->writeLock ); + SEH_INJECT_FAULT; + if( pInfo->nBackfillhdr.mxFrame ){ + rc = SQLITE_BUSY; + }else if( eMode>=SQLITE_CHECKPOINT_RESTART ){ + u32 salt1; + sqlite3_randomness(4, &salt1); + assert( pInfo->nBackfill==pWal->hdr.mxFrame ); + rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(1), WAL_NREADER-1); + if( rc==SQLITE_OK ){ + if( eMode==SQLITE_CHECKPOINT_TRUNCATE ){ + /* IMPLEMENTATION-OF: R-44699-57140 This mode works the same way as + ** SQLITE_CHECKPOINT_RESTART with the addition that it also + ** truncates the log file to zero bytes just prior to a + ** successful return. + ** + ** In theory, it might be safe to do this without updating the + ** wal-index header in shared memory, as all subsequent reader or + ** writer clients should see that the entire log file has been + ** checkpointed and behave accordingly. This seems unsafe though, + ** as it would leave the system in a state where the contents of + ** the wal-index header do not match the contents of the + ** file-system. To avoid this, update the wal-index header to + ** indicate that the log file contains zero valid frames. */ + walRestartHdr(pWal, salt1); + rc = sqlite3OsTruncate(pWal->pWalFd, 0); + } + walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); + } + } + } + + walcheckpoint_out: + SEH_FREE_ON_ERROR(pIter, 0); + walIteratorFree(pIter); + return rc; +} + +/* +** If the WAL file is currently larger than nMax bytes in size, truncate +** it to exactly nMax bytes. If an error occurs while doing so, ignore it. +*/ +static void walLimitSize(Wal *pWal, i64 nMax){ + i64 sz; + int rx; + sqlite3BeginBenignMalloc(); + rx = sqlite3OsFileSize(pWal->pWalFd, &sz); + if( rx==SQLITE_OK && (sz > nMax ) ){ + rx = sqlite3OsTruncate(pWal->pWalFd, nMax); + } + sqlite3EndBenignMalloc(); + if( rx ){ + sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName); + } +} + +#ifdef SQLITE_USE_SEH +/* +** This is the "standard" exception handler used in a few places to handle +** an exception thrown by reading from the *-shm mapping after it has become +** invalid in SQLITE_USE_SEH builds. It is used as follows: +** +** SEH_TRY { ... } +** SEH_EXCEPT( rc = walHandleException(pWal); ) +** +** This function does three things: +** +** 1) Determines the locks that should be held, based on the contents of +** the Wal.readLock, Wal.writeLock and Wal.ckptLock variables. All other +** held locks are assumed to be transient locks that would have been +** released had the exception not been thrown and are dropped. +** +** 2) Frees the pointer at Wal.pFree, if any, using sqlite3_free(). +** +** 3) Set pWal->apWiData[pWal->iWiPg] to pWal->pWiValue if not NULL +** +** 4) Returns SQLITE_IOERR. +*/ +static int walHandleException(Wal *pWal){ + if( pWal->exclusiveMode==0 ){ + static const int S = 1; + static const int E = (1<writeLock==2 ) pWal->writeLock = 0; + mUnlock = pWal->lockMask & ~( + (pWal->readLock<0 ? 0 : (S << WAL_READ_LOCK(pWal->readLock))) + | (pWal->writeLock ? (E << WAL_WRITE_LOCK) : 0) + | (pWal->ckptLock ? (E << WAL_CKPT_LOCK) : 0) + ); + for(ii=0; iipFree); + pWal->pFree = 0; + if( pWal->pWiValue ){ + pWal->apWiData[pWal->iWiPg] = pWal->pWiValue; + pWal->pWiValue = 0; + } + return SQLITE_IOERR_IN_PAGE; +} + +/* +** Assert that the Wal.lockMask mask, which indicates the locks held +** by the connection, is consistent with the Wal.readLock, Wal.writeLock +** and Wal.ckptLock variables. To be used as: +** +** assert( walAssertLockmask(pWal) ); +*/ +static int walAssertLockmask(Wal *pWal){ + if( pWal->exclusiveMode==0 ){ + static const int S = 1; + static const int E = (1<readLock<0 ? 0 : (S << WAL_READ_LOCK(pWal->readLock))) + | (pWal->writeLock ? (E << WAL_WRITE_LOCK) : 0) + | (pWal->ckptLock ? (E << WAL_CKPT_LOCK) : 0) +#ifdef SQLITE_ENABLE_SNAPSHOT + | (pWal->pSnapshot ? (pWal->lockMask & (1 << WAL_CKPT_LOCK)) : 0) +#endif + ); + assert( mExpect==pWal->lockMask ); + } + return 1; +} + +/* +** Return and zero the "system error" field set when an +** EXCEPTION_IN_PAGE_ERROR exception is caught. +*/ +SQLITE_PRIVATE int sqlite3WalSystemErrno(Wal *pWal){ + int iRet = 0; + if( pWal ){ + iRet = pWal->iSysErrno; + pWal->iSysErrno = 0; + } + return iRet; +} + +#else +# define walAssertLockmask(x) 1 +#endif /* ifdef SQLITE_USE_SEH */ + +/* +** Close a connection to a log file. +*/ +SQLITE_PRIVATE int sqlite3WalClose( + Wal *pWal, /* Wal to close */ + sqlite3 *db, /* For interrupt flag */ + int sync_flags, /* Flags to pass to OsSync() (or 0) */ + int nBuf, + u8 *zBuf /* Buffer of at least nBuf bytes */ +){ + int rc = SQLITE_OK; + if( pWal ){ + int isDelete = 0; /* True to unlink wal and wal-index files */ + + assert( walAssertLockmask(pWal) ); + + /* If an EXCLUSIVE lock can be obtained on the database file (using the + ** ordinary, rollback-mode locking methods, this guarantees that the + ** connection associated with this log file is the only connection to + ** the database. In this case checkpoint the database and unlink both + ** the wal and wal-index files. + ** + ** The EXCLUSIVE lock is not released before returning. + */ + if( zBuf!=0 + && SQLITE_OK==(rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE)) + ){ + if( pWal->exclusiveMode==WAL_NORMAL_MODE ){ + pWal->exclusiveMode = WAL_EXCLUSIVE_MODE; + } + rc = sqlite3WalCheckpoint(pWal, db, + SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0 + ); + if( rc==SQLITE_OK ){ + int bPersist = -1; + sqlite3OsFileControlHint( + pWal->pDbFd, SQLITE_FCNTL_PERSIST_WAL, &bPersist + ); + if( bPersist!=1 ){ + /* Try to delete the WAL file if the checkpoint completed and + ** fsynced (rc==SQLITE_OK) and if we are not in persistent-wal + ** mode (!bPersist) */ + isDelete = 1; + }else if( pWal->mxWalSize>=0 ){ + /* Try to truncate the WAL file to zero bytes if the checkpoint + ** completed and fsynced (rc==SQLITE_OK) and we are in persistent + ** WAL mode (bPersist) and if the PRAGMA journal_size_limit is a + ** non-negative value (pWal->mxWalSize>=0). Note that we truncate + ** to zero bytes as truncating to the journal_size_limit might + ** leave a corrupt WAL file on disk. */ + walLimitSize(pWal, 0); + } + } + } + + walIndexClose(pWal, isDelete); + sqlite3OsClose(pWal->pWalFd); + if( isDelete ){ + sqlite3BeginBenignMalloc(); + sqlite3OsDelete(pWal->pVfs, pWal->zWalName, 0); + sqlite3EndBenignMalloc(); + } + WALTRACE(("WAL%p: closed\n", pWal)); + sqlite3_free((void *)pWal->apWiData); + sqlite3_free(pWal); + } + return rc; +} + +/* +** Try to read the wal-index header. Return 0 on success and 1 if +** there is a problem. +** +** The wal-index is in shared memory. Another thread or process might +** be writing the header at the same time this procedure is trying to +** read it, which might result in inconsistency. A dirty read is detected +** by verifying that both copies of the header are the same and also by +** a checksum on the header. +** +** If and only if the read is consistent and the header is different from +** pWal->hdr, then pWal->hdr is updated to the content of the new header +** and *pChanged is set to 1. +** +** If the checksum cannot be verified return non-zero. If the header +** is read successfully and the checksum verified, return zero. +*/ +static SQLITE_NO_TSAN int walIndexTryHdr(Wal *pWal, int *pChanged){ + u32 aCksum[2]; /* Checksum on the header content */ + WalIndexHdr h1, h2; /* Two copies of the header content */ + WalIndexHdr volatile *aHdr; /* Header in shared memory */ + + /* The first page of the wal-index must be mapped at this point. */ + assert( pWal->nWiData>0 && pWal->apWiData[0] ); + + /* Read the header. This might happen concurrently with a write to the + ** same area of shared memory on a different CPU in a SMP, + ** meaning it is possible that an inconsistent snapshot is read + ** from the file. If this happens, return non-zero. + ** + ** tag-20200519-1: + ** There are two copies of the header at the beginning of the wal-index. + ** When reading, read [0] first then [1]. Writes are in the reverse order. + ** Memory barriers are used to prevent the compiler or the hardware from + ** reordering the reads and writes. TSAN and similar tools can sometimes + ** give false-positive warnings about these accesses because the tools do not + ** account for the double-read and the memory barrier. The use of mutexes + ** here would be problematic as the memory being accessed is potentially + ** shared among multiple processes and not all mutex implementations work + ** reliably in that environment. + */ + aHdr = walIndexHdr(pWal); + memcpy(&h1, (void *)&aHdr[0], sizeof(h1)); /* Possible TSAN false-positive */ + walShmBarrier(pWal); + memcpy(&h2, (void *)&aHdr[1], sizeof(h2)); + + if( memcmp(&h1, &h2, sizeof(h1))!=0 ){ + return 1; /* Dirty read */ + } + if( h1.isInit==0 ){ + return 1; /* Malformed header - probably all zeros */ + } + walChecksumBytes(1, (u8*)&h1, sizeof(h1)-sizeof(h1.aCksum), 0, aCksum); + if( aCksum[0]!=h1.aCksum[0] || aCksum[1]!=h1.aCksum[1] ){ + return 1; /* Checksum does not match */ + } + + if( memcmp(&pWal->hdr, &h1, sizeof(WalIndexHdr)) ){ + *pChanged = 1; + memcpy(&pWal->hdr, &h1, sizeof(WalIndexHdr)); + pWal->szPage = (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16); + testcase( pWal->szPage<=32768 ); + testcase( pWal->szPage>=65536 ); + } + + /* The header was successfully read. Return zero. */ + return 0; +} + +/* +** This is the value that walTryBeginRead returns when it needs to +** be retried. +*/ +#define WAL_RETRY (-1) + +/* +** Read the wal-index header from the wal-index and into pWal->hdr. +** If the wal-header appears to be corrupt, try to reconstruct the +** wal-index from the WAL before returning. +** +** Set *pChanged to 1 if the wal-index header value in pWal->hdr is +** changed by this operation. If pWal->hdr is unchanged, set *pChanged +** to 0. +** +** If the wal-index header is successfully read, return SQLITE_OK. +** Otherwise an SQLite error code. +*/ +static int walIndexReadHdr(Wal *pWal, int *pChanged){ + int rc; /* Return code */ + int badHdr; /* True if a header read failed */ + volatile u32 *page0; /* Chunk of wal-index containing header */ + + /* Ensure that page 0 of the wal-index (the page that contains the + ** wal-index header) is mapped. Return early if an error occurs here. + */ + assert( pChanged ); + rc = walIndexPage(pWal, 0, &page0); + if( rc!=SQLITE_OK ){ + assert( rc!=SQLITE_READONLY ); /* READONLY changed to OK in walIndexPage */ + if( rc==SQLITE_READONLY_CANTINIT ){ + /* The SQLITE_READONLY_CANTINIT return means that the shared-memory + ** was openable but is not writable, and this thread is unable to + ** confirm that another write-capable connection has the shared-memory + ** open, and hence the content of the shared-memory is unreliable, + ** since the shared-memory might be inconsistent with the WAL file + ** and there is no writer on hand to fix it. */ + assert( page0==0 ); + assert( pWal->writeLock==0 ); + assert( pWal->readOnly & WAL_SHM_RDONLY ); + pWal->bShmUnreliable = 1; + pWal->exclusiveMode = WAL_HEAPMEMORY_MODE; + *pChanged = 1; + }else{ + return rc; /* Any other non-OK return is just an error */ + } + }else{ + /* page0 can be NULL if the SHM is zero bytes in size and pWal->writeLock + ** is zero, which prevents the SHM from growing */ + testcase( page0!=0 ); + } + assert( page0!=0 || pWal->writeLock==0 ); + + /* If the first page of the wal-index has been mapped, try to read the + ** wal-index header immediately, without holding any lock. This usually + ** works, but may fail if the wal-index header is corrupt or currently + ** being modified by another thread or process. + */ + badHdr = (page0 ? walIndexTryHdr(pWal, pChanged) : 1); + + /* If the first attempt failed, it might have been due to a race + ** with a writer. So get a WRITE lock and try again. + */ + if( badHdr ){ + if( pWal->bShmUnreliable==0 && (pWal->readOnly & WAL_SHM_RDONLY) ){ + if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){ + walUnlockShared(pWal, WAL_WRITE_LOCK); + rc = SQLITE_READONLY_RECOVERY; + } + }else{ + int bWriteLock = pWal->writeLock; + if( bWriteLock + || SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) + ){ + /* If the write-lock was just obtained, set writeLock to 2 instead of + ** the usual 1. This causes walIndexPage() to behave as if the + ** write-lock were held (so that it allocates new pages as required), + ** and walHandleException() to unlock the write-lock if a SEH exception + ** is thrown. */ + if( !bWriteLock ) pWal->writeLock = 2; + if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){ + badHdr = walIndexTryHdr(pWal, pChanged); + if( badHdr ){ + /* If the wal-index header is still malformed even while holding + ** a WRITE lock, it can only mean that the header is corrupted and + ** needs to be reconstructed. So run recovery to do exactly that. + ** Disable blocking locks first. */ + walDisableBlocking(pWal); + rc = walIndexRecover(pWal); + *pChanged = 1; + } + } + if( bWriteLock==0 ){ + pWal->writeLock = 0; + walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); + } + } + } + } + + /* If the header is read successfully, check the version number to make + ** sure the wal-index was not constructed with some future format that + ** this version of SQLite cannot understand. + */ + if( badHdr==0 && pWal->hdr.iVersion!=WALINDEX_MAX_VERSION ){ + rc = SQLITE_CANTOPEN_BKPT; + } + if( pWal->bShmUnreliable ){ + if( rc!=SQLITE_OK ){ + walIndexClose(pWal, 0); + pWal->bShmUnreliable = 0; + assert( pWal->nWiData>0 && pWal->apWiData[0]==0 ); + /* walIndexRecover() might have returned SHORT_READ if a concurrent + ** writer truncated the WAL out from under it. If that happens, it + ** indicates that a writer has fixed the SHM file for us, so retry */ + if( rc==SQLITE_IOERR_SHORT_READ ) rc = WAL_RETRY; + } + pWal->exclusiveMode = WAL_NORMAL_MODE; + } + + return rc; +} + +/* +** Open a transaction in a connection where the shared-memory is read-only +** and where we cannot verify that there is a separate write-capable connection +** on hand to keep the shared-memory up-to-date with the WAL file. +** +** This can happen, for example, when the shared-memory is implemented by +** memory-mapping a *-shm file, where a prior writer has shut down and +** left the *-shm file on disk, and now the present connection is trying +** to use that database but lacks write permission on the *-shm file. +** Other scenarios are also possible, depending on the VFS implementation. +** +** Precondition: +** +** The *-wal file has been read and an appropriate wal-index has been +** constructed in pWal->apWiData[] using heap memory instead of shared +** memory. +** +** If this function returns SQLITE_OK, then the read transaction has +** been successfully opened. In this case output variable (*pChanged) +** is set to true before returning if the caller should discard the +** contents of the page cache before proceeding. Or, if it returns +** WAL_RETRY, then the heap memory wal-index has been discarded and +** the caller should retry opening the read transaction from the +** beginning (including attempting to map the *-shm file). +** +** If an error occurs, an SQLite error code is returned. +*/ +static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ + i64 szWal; /* Size of wal file on disk in bytes */ + i64 iOffset; /* Current offset when reading wal file */ + u8 aBuf[WAL_HDRSIZE]; /* Buffer to load WAL header into */ + u8 *aFrame = 0; /* Malloc'd buffer to load entire frame */ + int szFrame; /* Number of bytes in buffer aFrame[] */ + u8 *aData; /* Pointer to data part of aFrame buffer */ + volatile void *pDummy; /* Dummy argument for xShmMap */ + int rc; /* Return code */ + u32 aSaveCksum[2]; /* Saved copy of pWal->hdr.aFrameCksum */ + + assert( pWal->bShmUnreliable ); + assert( pWal->readOnly & WAL_SHM_RDONLY ); + assert( pWal->nWiData>0 && pWal->apWiData[0] ); + + /* Take WAL_READ_LOCK(0). This has the effect of preventing any + ** writers from running a checkpoint, but does not stop them + ** from running recovery. */ + rc = walLockShared(pWal, WAL_READ_LOCK(0)); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_BUSY ) rc = WAL_RETRY; + goto begin_unreliable_shm_out; + } + pWal->readLock = 0; + + /* Check to see if a separate writer has attached to the shared-memory area, + ** thus making the shared-memory "reliable" again. Do this by invoking + ** the xShmMap() routine of the VFS and looking to see if the return + ** is SQLITE_READONLY instead of SQLITE_READONLY_CANTINIT. + ** + ** If the shared-memory is now "reliable" return WAL_RETRY, which will + ** cause the heap-memory WAL-index to be discarded and the actual + ** shared memory to be used in its place. + ** + ** This step is important because, even though this connection is holding + ** the WAL_READ_LOCK(0) which prevents a checkpoint, a writer might + ** have already checkpointed the WAL file and, while the current + ** is active, wrap the WAL and start overwriting frames that this + ** process wants to use. + ** + ** Once sqlite3OsShmMap() has been called for an sqlite3_file and has + ** returned any SQLITE_READONLY value, it must return only SQLITE_READONLY + ** or SQLITE_READONLY_CANTINIT or some error for all subsequent invocations, + ** even if some external agent does a "chmod" to make the shared-memory + ** writable by us, until sqlite3OsShmUnmap() has been called. + ** This is a requirement on the VFS implementation. + */ + rc = sqlite3OsShmMap(pWal->pDbFd, 0, WALINDEX_PGSZ, 0, &pDummy); + assert( rc!=SQLITE_OK ); /* SQLITE_OK not possible for read-only connection */ + if( rc!=SQLITE_READONLY_CANTINIT ){ + rc = (rc==SQLITE_READONLY ? WAL_RETRY : rc); + goto begin_unreliable_shm_out; + } + + /* We reach this point only if the real shared-memory is still unreliable. + ** Assume the in-memory WAL-index substitute is correct and load it + ** into pWal->hdr. + */ + memcpy(&pWal->hdr, (void*)walIndexHdr(pWal), sizeof(WalIndexHdr)); + + /* Make sure some writer hasn't come in and changed the WAL file out + ** from under us, then disconnected, while we were not looking. + */ + rc = sqlite3OsFileSize(pWal->pWalFd, &szWal); + if( rc!=SQLITE_OK ){ + goto begin_unreliable_shm_out; + } + if( szWalhdr.mxFrame==0 ? SQLITE_OK : WAL_RETRY); + goto begin_unreliable_shm_out; + } + + /* Check the salt keys at the start of the wal file still match. */ + rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0); + if( rc!=SQLITE_OK ){ + goto begin_unreliable_shm_out; + } + if( memcmp(&pWal->hdr.aSalt, &aBuf[16], 8) ){ + /* Some writer has wrapped the WAL file while we were not looking. + ** Return WAL_RETRY which will cause the in-memory WAL-index to be + ** rebuilt. */ + rc = WAL_RETRY; + goto begin_unreliable_shm_out; + } + + /* Allocate a buffer to read frames into */ + assert( (pWal->szPage & (pWal->szPage-1))==0 ); + assert( (pWal->szPage>=512 && pWal->szPage<=65536) || pWal->szPage==0 ); + szFrame = pWal->szPage + WAL_FRAME_HDRSIZE; + aFrame = (u8 *)sqlite3_malloc64(szFrame); + if( aFrame==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto begin_unreliable_shm_out; + } + aData = &aFrame[WAL_FRAME_HDRSIZE]; + + /* Check to see if a complete transaction has been appended to the + ** wal file since the heap-memory wal-index was created. If so, the + ** heap-memory wal-index is discarded and WAL_RETRY returned to + ** the caller. */ + aSaveCksum[0] = pWal->hdr.aFrameCksum[0]; + aSaveCksum[1] = pWal->hdr.aFrameCksum[1]; + for(iOffset=walFrameOffset(pWal->hdr.mxFrame+1, pWal->szPage); + iOffset+szFrame<=szWal; + iOffset+=szFrame + ){ + u32 pgno; /* Database page number for frame */ + u32 nTruncate; /* dbsize field from frame header */ + + /* Read and decode the next log frame. */ + rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset); + if( rc!=SQLITE_OK ) break; + if( !walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame) ) break; + + /* If nTruncate is non-zero, then a complete transaction has been + ** appended to this wal file. Set rc to WAL_RETRY and break out of + ** the loop. */ + if( nTruncate ){ + rc = WAL_RETRY; + break; + } + } + pWal->hdr.aFrameCksum[0] = aSaveCksum[0]; + pWal->hdr.aFrameCksum[1] = aSaveCksum[1]; + + begin_unreliable_shm_out: + sqlite3_free(aFrame); + if( rc!=SQLITE_OK ){ + int i; + for(i=0; inWiData; i++){ + sqlite3_free((void*)pWal->apWiData[i]); + pWal->apWiData[i] = 0; + } + pWal->bShmUnreliable = 0; + sqlite3WalEndReadTransaction(pWal); + *pChanged = 1; + } + return rc; +} + +/* +** The final argument passed to walTryBeginRead() is of type (int*). The +** caller should invoke walTryBeginRead as follows: +** +** int cnt = 0; +** do { +** rc = walTryBeginRead(..., &cnt); +** }while( rc==WAL_RETRY ); +** +** The final value of "cnt" is of no use to the caller. It is used by +** the implementation of walTryBeginRead() as follows: +** +** + Each time walTryBeginRead() is called, it is incremented. Once +** it reaches WAL_RETRY_PROTOCOL_LIMIT - indicating that walTryBeginRead() +** has many times been invoked and failed with WAL_RETRY - walTryBeginRead() +** returns SQLITE_PROTOCOL. +** +** + If SQLITE_ENABLE_SETLK_TIMEOUT is defined and walTryBeginRead() failed +** because a blocking lock timed out (SQLITE_BUSY_TIMEOUT from the OS +** layer), the WAL_RETRY_BLOCKED_MASK bit is set in "cnt". In this case +** the next invocation of walTryBeginRead() may omit an expected call to +** sqlite3OsSleep(). There has already been a delay when the previous call +** waited on a lock. +*/ +#define WAL_RETRY_PROTOCOL_LIMIT 100 +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT +# define WAL_RETRY_BLOCKED_MASK 0x10000000 +#else +# define WAL_RETRY_BLOCKED_MASK 0 +#endif + +/* +** Attempt to start a read transaction. This might fail due to a race or +** other transient condition. When that happens, it returns WAL_RETRY to +** indicate to the caller that it is safe to retry immediately. +** +** On success return SQLITE_OK. On a permanent failure (such an +** I/O error or an SQLITE_BUSY because another process is running +** recovery) return a positive error code. +** +** The useWal parameter is true to force the use of the WAL and disable +** the case where the WAL is bypassed because it has been completely +** checkpointed. If useWal==0 then this routine calls walIndexReadHdr() +** to make a copy of the wal-index header into pWal->hdr. If the +** wal-index header has changed, *pChanged is set to 1 (as an indication +** to the caller that the local page cache is obsolete and needs to be +** flushed.) When useWal==1, the wal-index header is assumed to already +** be loaded and the pChanged parameter is unused. +** +** The caller must set the cnt parameter to the number of prior calls to +** this routine during the current read attempt that returned WAL_RETRY. +** This routine will start taking more aggressive measures to clear the +** race conditions after multiple WAL_RETRY returns, and after an excessive +** number of errors will ultimately return SQLITE_PROTOCOL. The +** SQLITE_PROTOCOL return indicates that some other process has gone rogue +** and is not honoring the locking protocol. There is a vanishingly small +** chance that SQLITE_PROTOCOL could be returned because of a run of really +** bad luck when there is lots of contention for the wal-index, but that +** possibility is so small that it can be safely neglected, we believe. +** +** On success, this routine obtains a read lock on +** WAL_READ_LOCK(pWal->readLock). The pWal->readLock integer is +** in the range 0 <= pWal->readLock < WAL_NREADER. If pWal->readLock==(-1) +** that means the Wal does not hold any read lock. The reader must not +** access any database page that is modified by a WAL frame up to and +** including frame number aReadMark[pWal->readLock]. The reader will +** use WAL frames up to and including pWal->hdr.mxFrame if pWal->readLock>0 +** Or if pWal->readLock==0, then the reader will ignore the WAL +** completely and get all content directly from the database file. +** If the useWal parameter is 1 then the WAL will never be ignored and +** this routine will always set pWal->readLock>0 on success. +** When the read transaction is completed, the caller must release the +** lock on WAL_READ_LOCK(pWal->readLock) and set pWal->readLock to -1. +** +** This routine uses the nBackfill and aReadMark[] fields of the header +** to select a particular WAL_READ_LOCK() that strives to let the +** checkpoint process do as much work as possible. This routine might +** update values of the aReadMark[] array in the header, but if it does +** so it takes care to hold an exclusive lock on the corresponding +** WAL_READ_LOCK() while changing values. +*/ +static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ + volatile WalCkptInfo *pInfo; /* Checkpoint information in wal-index */ + int rc = SQLITE_OK; /* Return code */ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + int nBlockTmout = 0; +#endif + + assert( pWal->readLock<0 ); /* Not currently locked */ + + /* useWal may only be set for read/write connections */ + assert( (pWal->readOnly & WAL_SHM_RDONLY)==0 || useWal==0 ); + + /* Take steps to avoid spinning forever if there is a protocol error. + ** + ** Circumstances that cause a RETRY should only last for the briefest + ** instances of time. No I/O or other system calls are done while the + ** locks are held, so the locks should not be held for very long. But + ** if we are unlucky, another process that is holding a lock might get + ** paged out or take a page-fault that is time-consuming to resolve, + ** during the few nanoseconds that it is holding the lock. In that case, + ** it might take longer than normal for the lock to free. + ** + ** After 5 RETRYs, we begin calling sqlite3OsSleep(). The first few + ** calls to sqlite3OsSleep() have a delay of 1 microsecond. Really this + ** is more of a scheduler yield than an actual delay. But on the 10th + ** an subsequent retries, the delays start becoming longer and longer, + ** so that on the 100th (and last) RETRY we delay for 323 milliseconds. + ** The total delay time before giving up is less than 10 seconds. + */ + (*pCnt)++; + if( *pCnt>5 ){ + int nDelay = 1; /* Pause time in microseconds */ + int cnt = (*pCnt & ~WAL_RETRY_BLOCKED_MASK); + if( cnt>WAL_RETRY_PROTOCOL_LIMIT ){ + VVA_ONLY( pWal->lockError = 1; ) + return SQLITE_PROTOCOL; + } + if( *pCnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39; +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + /* In SQLITE_ENABLE_SETLK_TIMEOUT builds, configure the file-descriptor + ** to block for locks for approximately nDelay us. This affects three + ** locks: (a) the shared lock taken on the DMS slot in os_unix.c (if + ** using os_unix.c), (b) the WRITER lock taken in walIndexReadHdr() if the + ** first attempted read fails, and (c) the shared lock taken on the + ** read-mark. + ** + ** If the previous call failed due to an SQLITE_BUSY_TIMEOUT error, + ** then sleep for the minimum of 1us. The previous call already provided + ** an extra delay while it was blocking on the lock. + */ + nBlockTmout = (nDelay+998) / 1000; + if( !useWal && walEnableBlockingMs(pWal, nBlockTmout) ){ + if( *pCnt & WAL_RETRY_BLOCKED_MASK ) nDelay = 1; + } +#endif + sqlite3OsSleep(pWal->pVfs, nDelay); + *pCnt &= ~WAL_RETRY_BLOCKED_MASK; + } + + if( !useWal ){ + assert( rc==SQLITE_OK ); + if( pWal->bShmUnreliable==0 ){ + rc = walIndexReadHdr(pWal, pChanged); + } +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + if( rc==SQLITE_BUSY_TIMEOUT ){ + rc = SQLITE_BUSY; + *pCnt |= WAL_RETRY_BLOCKED_MASK; + } +#endif + if( rc==SQLITE_BUSY ){ + /* If there is not a recovery running in another thread or process + ** then convert BUSY errors to WAL_RETRY. If recovery is known to + ** be running, convert BUSY to BUSY_RECOVERY. There is a race here + ** which might cause WAL_RETRY to be returned even if BUSY_RECOVERY + ** would be technically correct. But the race is benign since with + ** WAL_RETRY this routine will be called again and will probably be + ** right on the second iteration. + */ + (void)walEnableBlocking(pWal); + if( pWal->apWiData[0]==0 ){ + /* This branch is taken when the xShmMap() method returns SQLITE_BUSY. + ** We assume this is a transient condition, so return WAL_RETRY. The + ** xShmMap() implementation used by the default unix and win32 VFS + ** modules may return SQLITE_BUSY due to a race condition in the + ** code that determines whether or not the shared-memory region + ** must be zeroed before the requested page is returned. + */ + rc = WAL_RETRY; + }else if( SQLITE_OK==(rc = walLockShared(pWal, WAL_RECOVER_LOCK)) ){ + walUnlockShared(pWal, WAL_RECOVER_LOCK); + rc = WAL_RETRY; + }else if( rc==SQLITE_BUSY ){ + rc = SQLITE_BUSY_RECOVERY; + } + } + walDisableBlocking(pWal); + if( rc!=SQLITE_OK ){ + return rc; + } + else if( pWal->bShmUnreliable ){ + return walBeginShmUnreliable(pWal, pChanged); + } + } + + assert( pWal->nWiData>0 ); + assert( pWal->apWiData[0]!=0 ); + pInfo = walCkptInfo(pWal); + SEH_INJECT_FAULT; + { + u32 mxReadMark; /* Largest aReadMark[] value */ + int mxI; /* Index of largest aReadMark[] value */ + int i; /* Loop counter */ + u32 mxFrame; /* Wal frame to lock to */ + if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame +#ifdef SQLITE_ENABLE_SNAPSHOT + && ((pWal->bGetSnapshot==0 && pWal->pSnapshot==0) || pWal->hdr.mxFrame==0) +#endif + ){ + /* The WAL has been completely backfilled (or it is empty). + ** and can be safely ignored. + */ + rc = walLockShared(pWal, WAL_READ_LOCK(0)); + walShmBarrier(pWal); + if( rc==SQLITE_OK ){ + if( memcmp((void *)walIndexHdr(pWal), &pWal->hdr,sizeof(WalIndexHdr)) ){ + /* It is not safe to allow the reader to continue here if frames + ** may have been appended to the log before READ_LOCK(0) was obtained. + ** When holding READ_LOCK(0), the reader ignores the entire log file, + ** which implies that the database file contains a trustworthy + ** snapshot. Since holding READ_LOCK(0) prevents a checkpoint from + ** happening, this is usually correct. + ** + ** However, if frames have been appended to the log (or if the log + ** is wrapped and written for that matter) before the READ_LOCK(0) + ** is obtained, that is not necessarily true. A checkpointer may + ** have started to backfill the appended frames but crashed before + ** it finished. Leaving a corrupt image in the database file. + */ + walUnlockShared(pWal, WAL_READ_LOCK(0)); + return WAL_RETRY; + } + pWal->readLock = 0; + return SQLITE_OK; + }else if( rc!=SQLITE_BUSY ){ + return rc; + } + } + + /* If we get this far, it means that the reader will want to use + ** the WAL to get at content from recent commits. The job now is + ** to select one of the aReadMark[] entries that is closest to + ** but not exceeding pWal->hdr.mxFrame and lock that entry. + */ + mxReadMark = 0; + mxI = 0; + mxFrame = pWal->hdr.mxFrame; +#ifdef SQLITE_ENABLE_SNAPSHOT + if( pWal->pSnapshot && pWal->pSnapshot->mxFramepSnapshot->mxFrame; + } +#endif + for(i=1; iaReadMark+i); SEH_INJECT_FAULT; + if( mxReadMark<=thisMark && thisMark<=mxFrame ){ + assert( thisMark!=READMARK_NOT_USED ); + mxReadMark = thisMark; + mxI = i; + } + } + if( (pWal->readOnly & WAL_SHM_RDONLY)==0 + && (mxReadMarkaReadMark+i,mxFrame); + mxReadMark = mxFrame; + mxI = i; + walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); + break; + }else if( rc!=SQLITE_BUSY ){ + return rc; + } + } + } + if( mxI==0 ){ + assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 ); + return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT; + } + + (void)walEnableBlockingMs(pWal, nBlockTmout); + rc = walLockShared(pWal, WAL_READ_LOCK(mxI)); + walDisableBlocking(pWal); + if( rc ){ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + if( rc==SQLITE_BUSY_TIMEOUT ){ + *pCnt |= WAL_RETRY_BLOCKED_MASK; + } +#else + assert( rc!=SQLITE_BUSY_TIMEOUT ); +#endif + assert((rc&0xFF)!=SQLITE_BUSY||rc==SQLITE_BUSY||rc==SQLITE_BUSY_TIMEOUT); + return (rc&0xFF)==SQLITE_BUSY ? WAL_RETRY : rc; + } + /* Now that the read-lock has been obtained, check that neither the + ** value in the aReadMark[] array or the contents of the wal-index + ** header have changed. + ** + ** It is necessary to check that the wal-index header did not change + ** between the time it was read and when the shared-lock was obtained + ** on WAL_READ_LOCK(mxI) was obtained to account for the possibility + ** that the log file may have been wrapped by a writer, or that frames + ** that occur later in the log than pWal->hdr.mxFrame may have been + ** copied into the database by a checkpointer. If either of these things + ** happened, then reading the database with the current value of + ** pWal->hdr.mxFrame risks reading a corrupted snapshot. So, retry + ** instead. + ** + ** Before checking that the live wal-index header has not changed + ** since it was read, set Wal.minFrame to the first frame in the wal + ** file that has not yet been checkpointed. This client will not need + ** to read any frames earlier than minFrame from the wal file - they + ** can be safely read directly from the database file. + ** + ** Because a ShmBarrier() call is made between taking the copy of + ** nBackfill and checking that the wal-header in shared-memory still + ** matches the one cached in pWal->hdr, it is guaranteed that the + ** checkpointer that set nBackfill was not working with a wal-index + ** header newer than that cached in pWal->hdr. If it were, that could + ** cause a problem. The checkpointer could omit to checkpoint + ** a version of page X that lies before pWal->minFrame (call that version + ** A) on the basis that there is a newer version (version B) of the same + ** page later in the wal file. But if version B happens to like past + ** frame pWal->hdr.mxFrame - then the client would incorrectly assume + ** that it can read version A from the database file. However, since + ** we can guarantee that the checkpointer that set nBackfill could not + ** see any pages past pWal->hdr.mxFrame, this problem does not come up. + */ + pWal->minFrame = AtomicLoad(&pInfo->nBackfill)+1; SEH_INJECT_FAULT; + walShmBarrier(pWal); + if( AtomicLoad(pInfo->aReadMark+mxI)!=mxReadMark + || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) + ){ + walUnlockShared(pWal, WAL_READ_LOCK(mxI)); + return WAL_RETRY; + }else{ + assert( mxReadMark<=pWal->hdr.mxFrame ); + pWal->readLock = (i16)mxI; + } + } + return rc; +} + +#ifdef SQLITE_ENABLE_SNAPSHOT +/* +** This function does the work of sqlite3WalSnapshotRecover(). +*/ +static int walSnapshotRecover( + Wal *pWal, /* WAL handle */ + void *pBuf1, /* Temp buffer pWal->szPage bytes in size */ + void *pBuf2 /* Temp buffer pWal->szPage bytes in size */ +){ + int szPage = (int)pWal->szPage; + int rc; + i64 szDb; /* Size of db file in bytes */ + + rc = sqlite3OsFileSize(pWal->pDbFd, &szDb); + if( rc==SQLITE_OK ){ + volatile WalCkptInfo *pInfo = walCkptInfo(pWal); + u32 i = pInfo->nBackfillAttempted; + for(i=pInfo->nBackfillAttempted; i>AtomicLoad(&pInfo->nBackfill); i--){ + WalHashLoc sLoc; /* Hash table location */ + u32 pgno; /* Page number in db file */ + i64 iDbOff; /* Offset of db file entry */ + i64 iWalOff; /* Offset of wal file entry */ + + rc = walHashGet(pWal, walFramePage(i), &sLoc); + if( rc!=SQLITE_OK ) break; + assert( i - sLoc.iZero - 1 >=0 ); + pgno = sLoc.aPgno[i-sLoc.iZero-1]; + iDbOff = (i64)(pgno-1) * szPage; + + if( iDbOff+szPage<=szDb ){ + iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE; + rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff); + + if( rc==SQLITE_OK ){ + rc = sqlite3OsRead(pWal->pDbFd, pBuf2, szPage, iDbOff); + } + + if( rc!=SQLITE_OK || 0==memcmp(pBuf1, pBuf2, szPage) ){ + break; + } + } + + pInfo->nBackfillAttempted = i-1; + } + } + + return rc; +} + +/* +** Attempt to reduce the value of the WalCkptInfo.nBackfillAttempted +** variable so that older snapshots can be accessed. To do this, loop +** through all wal frames from nBackfillAttempted to (nBackfill+1), +** comparing their content to the corresponding page with the database +** file, if any. Set nBackfillAttempted to the frame number of the +** first frame for which the wal file content matches the db file. +** +** This is only really safe if the file-system is such that any page +** writes made by earlier checkpointers were atomic operations, which +** is not always true. It is also possible that nBackfillAttempted +** may be left set to a value larger than expected, if a wal frame +** contains content that duplicate of an earlier version of the same +** page. +** +** SQLITE_OK is returned if successful, or an SQLite error code if an +** error occurs. It is not an error if nBackfillAttempted cannot be +** decreased at all. +*/ +SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal){ + int rc; + + assert( pWal->readLock>=0 ); + rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); + if( rc==SQLITE_OK ){ + void *pBuf1 = sqlite3_malloc(pWal->szPage); + void *pBuf2 = sqlite3_malloc(pWal->szPage); + if( pBuf1==0 || pBuf2==0 ){ + rc = SQLITE_NOMEM; + }else{ + pWal->ckptLock = 1; + SEH_TRY { + rc = walSnapshotRecover(pWal, pBuf1, pBuf2); + } + SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) + pWal->ckptLock = 0; + } + + sqlite3_free(pBuf1); + sqlite3_free(pBuf2); + walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1); + } + + return rc; +} +#endif /* SQLITE_ENABLE_SNAPSHOT */ + +/* +** This function does the work of sqlite3WalBeginReadTransaction() (see +** below). That function simply calls this one inside an SEH_TRY{...} block. +*/ +static int walBeginReadTransaction(Wal *pWal, int *pChanged){ + int rc; /* Return code */ + int cnt = 0; /* Number of TryBeginRead attempts */ +#ifdef SQLITE_ENABLE_SNAPSHOT + int ckptLock = 0; + int bChanged = 0; + WalIndexHdr *pSnapshot = pWal->pSnapshot; +#endif + + assert( pWal->ckptLock==0 ); + assert( pWal->nSehTry>0 ); + +#ifdef SQLITE_ENABLE_SNAPSHOT + if( pSnapshot ){ + if( memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){ + bChanged = 1; + } + + /* It is possible that there is a checkpointer thread running + ** concurrent with this code. If this is the case, it may be that the + ** checkpointer has already determined that it will checkpoint + ** snapshot X, where X is later in the wal file than pSnapshot, but + ** has not yet set the pInfo->nBackfillAttempted variable to indicate + ** its intent. To avoid the race condition this leads to, ensure that + ** there is no checkpointer process by taking a shared CKPT lock + ** before checking pInfo->nBackfillAttempted. */ + (void)walEnableBlocking(pWal); + rc = walLockShared(pWal, WAL_CKPT_LOCK); + walDisableBlocking(pWal); + + if( rc!=SQLITE_OK ){ + return rc; + } + ckptLock = 1; + } +#endif + + do{ + rc = walTryBeginRead(pWal, pChanged, 0, &cnt); + }while( rc==WAL_RETRY ); + testcase( (rc&0xff)==SQLITE_BUSY ); + testcase( (rc&0xff)==SQLITE_IOERR ); + testcase( rc==SQLITE_PROTOCOL ); + testcase( rc==SQLITE_OK ); + +#ifdef SQLITE_ENABLE_SNAPSHOT + if( rc==SQLITE_OK ){ + if( pSnapshot && memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){ + /* At this point the client has a lock on an aReadMark[] slot holding + ** a value equal to or smaller than pSnapshot->mxFrame, but pWal->hdr + ** is populated with the wal-index header corresponding to the head + ** of the wal file. Verify that pSnapshot is still valid before + ** continuing. Reasons why pSnapshot might no longer be valid: + ** + ** (1) The WAL file has been reset since the snapshot was taken. + ** In this case, the salt will have changed. + ** + ** (2) A checkpoint as been attempted that wrote frames past + ** pSnapshot->mxFrame into the database file. Note that the + ** checkpoint need not have completed for this to cause problems. + */ + volatile WalCkptInfo *pInfo = walCkptInfo(pWal); + + assert( pWal->readLock>0 || pWal->hdr.mxFrame==0 ); + assert( pInfo->aReadMark[pWal->readLock]<=pSnapshot->mxFrame ); + + /* Check that the wal file has not been wrapped. Assuming that it has + ** not, also check that no checkpointer has attempted to checkpoint any + ** frames beyond pSnapshot->mxFrame. If either of these conditions are + ** true, return SQLITE_ERROR_SNAPSHOT. Otherwise, overwrite pWal->hdr + ** with *pSnapshot and set *pChanged as appropriate for opening the + ** snapshot. */ + if( !memcmp(pSnapshot->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt)) + && pSnapshot->mxFrame>=pInfo->nBackfillAttempted + ){ + assert( pWal->readLock>0 ); + memcpy(&pWal->hdr, pSnapshot, sizeof(WalIndexHdr)); + *pChanged = bChanged; + }else{ + rc = SQLITE_ERROR_SNAPSHOT; + } + + /* A client using a non-current snapshot may not ignore any frames + ** from the start of the wal file. This is because, for a system + ** where (minFrame < iSnapshot < maxFrame), a checkpointer may + ** have omitted to checkpoint a frame earlier than minFrame in + ** the file because there exists a frame after iSnapshot that + ** is the same database page. */ + pWal->minFrame = 1; + + if( rc!=SQLITE_OK ){ + sqlite3WalEndReadTransaction(pWal); + } + } + } + + /* Release the shared CKPT lock obtained above. */ + if( ckptLock ){ + assert( pSnapshot ); + walUnlockShared(pWal, WAL_CKPT_LOCK); + } +#endif + return rc; +} + +/* +** Begin a read transaction on the database. +** +** This routine used to be called sqlite3OpenSnapshot() and with good reason: +** it takes a snapshot of the state of the WAL and wal-index for the current +** instant in time. The current thread will continue to use this snapshot. +** Other threads might append new content to the WAL and wal-index but +** that extra content is ignored by the current thread. +** +** If the database contents have changes since the previous read +** transaction, then *pChanged is set to 1 before returning. The +** Pager layer will use this to know that its cache is stale and +** needs to be flushed. +*/ +SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ + int rc; + SEH_TRY { + rc = walBeginReadTransaction(pWal, pChanged); + } + SEH_EXCEPT( rc = walHandleException(pWal); ) + return rc; +} + +/* +** Finish with a read transaction. All this does is release the +** read-lock. +*/ +SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal){ +#ifndef SQLITE_ENABLE_SETLK_TIMEOUT + assert( pWal->writeLock==0 || pWal->readLock<0 ); +#endif + if( pWal->readLock>=0 ){ + (void)sqlite3WalEndWriteTransaction(pWal); + walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock)); + pWal->readLock = -1; + } +} + +/* +** Search the wal file for page pgno. If found, set *piRead to the frame that +** contains the page. Otherwise, if pgno is not in the wal file, set *piRead +** to zero. +** +** Return SQLITE_OK if successful, or an error code if an error occurs. If an +** error does occur, the final value of *piRead is undefined. +*/ +static int walFindFrame( + Wal *pWal, /* WAL handle */ + Pgno pgno, /* Database page number to read data for */ + u32 *piRead /* OUT: Frame number (or zero) */ +){ + u32 iRead = 0; /* If !=0, WAL frame to return data from */ + u32 iLast = pWal->hdr.mxFrame; /* Last page in WAL for this reader */ + int iHash; /* Used to loop through N hash tables */ + int iMinHash; + + /* This routine is only be called from within a read transaction. */ + assert( pWal->readLock>=0 || pWal->lockError ); + + /* If the "last page" field of the wal-index header snapshot is 0, then + ** no data will be read from the wal under any circumstances. Return early + ** in this case as an optimization. Likewise, if pWal->readLock==0, + ** then the WAL is ignored by the reader so return early, as if the + ** WAL were empty. + */ + if( iLast==0 || (pWal->readLock==0 && pWal->bShmUnreliable==0) ){ + *piRead = 0; + return SQLITE_OK; + } + + /* Search the hash table or tables for an entry matching page number + ** pgno. Each iteration of the following for() loop searches one + ** hash table (each hash table indexes up to HASHTABLE_NPAGE frames). + ** + ** This code might run concurrently to the code in walIndexAppend() + ** that adds entries to the wal-index (and possibly to this hash + ** table). This means the value just read from the hash + ** slot (aHash[iKey]) may have been added before or after the + ** current read transaction was opened. Values added after the + ** read transaction was opened may have been written incorrectly - + ** i.e. these slots may contain garbage data. However, we assume + ** that any slots written before the current read transaction was + ** opened remain unmodified. + ** + ** For the reasons above, the if(...) condition featured in the inner + ** loop of the following block is more stringent that would be required + ** if we had exclusive access to the hash-table: + ** + ** (aPgno[iFrame]==pgno): + ** This condition filters out normal hash-table collisions. + ** + ** (iFrame<=iLast): + ** This condition filters out entries that were added to the hash + ** table after the current read-transaction had started. + */ + iMinHash = walFramePage(pWal->minFrame); + for(iHash=walFramePage(iLast); iHash>=iMinHash; iHash--){ + WalHashLoc sLoc; /* Hash table location */ + int iKey; /* Hash slot index */ + int nCollide; /* Number of hash collisions remaining */ + int rc; /* Error code */ + u32 iH; + + rc = walHashGet(pWal, iHash, &sLoc); + if( rc!=SQLITE_OK ){ + return rc; + } + nCollide = HASHTABLE_NSLOT; + iKey = walHash(pgno); + SEH_INJECT_FAULT; + while( (iH = AtomicLoad(&sLoc.aHash[iKey]))!=0 ){ + u32 iFrame = iH + sLoc.iZero; + if( iFrame<=iLast + && iFrame>=pWal->minFrame + && sLoc.aPgno[(iH-1)&(HASHTABLE_NPAGE-1)]==pgno + ){ + assert( iFrame>iRead || CORRUPT_DB ); + iRead = iFrame; + } + if( (nCollide--)==0 ){ + *piRead = 0; + return SQLITE_CORRUPT_BKPT; + } + iKey = walNextHash(iKey); + } + if( iRead ) break; + } + +#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT + /* If expensive assert() statements are available, do a linear search + ** of the wal-index file content. Make sure the results agree with the + ** result obtained using the hash indexes above. */ + { + u32 iRead2 = 0; + u32 iTest; + assert( pWal->bShmUnreliable || pWal->minFrame>0 ); + for(iTest=iLast; iTest>=pWal->minFrame && iTest>0; iTest--){ + if( walFramePgno(pWal, iTest)==pgno ){ + iRead2 = iTest; + break; + } + } + assert( iRead==iRead2 ); + } +#endif + + *piRead = iRead; + return SQLITE_OK; +} + +/* +** Search the wal file for page pgno. If found, set *piRead to the frame that +** contains the page. Otherwise, if pgno is not in the wal file, set *piRead +** to zero. +** +** Return SQLITE_OK if successful, or an error code if an error occurs. If an +** error does occur, the final value of *piRead is undefined. +** +** The difference between this function and walFindFrame() is that this +** function wraps walFindFrame() in an SEH_TRY{...} block. +*/ +SQLITE_PRIVATE int sqlite3WalFindFrame( + Wal *pWal, /* WAL handle */ + Pgno pgno, /* Database page number to read data for */ + u32 *piRead /* OUT: Frame number (or zero) */ +){ + int rc; + SEH_TRY { + rc = walFindFrame(pWal, pgno, piRead); + } + SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) + return rc; +} + +/* +** Read the contents of frame iRead from the wal file into buffer pOut +** (which is nOut bytes in size). Return SQLITE_OK if successful, or an +** error code otherwise. +*/ +SQLITE_PRIVATE int sqlite3WalReadFrame( + Wal *pWal, /* WAL handle */ + u32 iRead, /* Frame to read */ + int nOut, /* Size of buffer pOut in bytes */ + u8 *pOut /* Buffer to write page data to */ +){ + int sz; + i64 iOffset; + sz = pWal->hdr.szPage; + sz = (sz&0xfe00) + ((sz&0x0001)<<16); + testcase( sz<=32768 ); + testcase( sz>=65536 ); + iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE; + /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ + return sqlite3OsRead(pWal->pWalFd, pOut, (nOut>sz ? sz : nOut), iOffset); +} + +/* +** Return the size of the database in pages (or zero, if unknown). +*/ +SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal){ + if( pWal && ALWAYS(pWal->readLock>=0) ){ + return pWal->hdr.nPage; + } + return 0; +} + + +/* +** This function starts a write transaction on the WAL. +** +** A read transaction must have already been started by a prior call +** to sqlite3WalBeginReadTransaction(). +** +** If another thread or process has written into the database since +** the read transaction was started, then it is not possible for this +** thread to write as doing so would cause a fork. So this routine +** returns SQLITE_BUSY in that case and no write transaction is started. +** +** There can only be a single writer active at a time. +*/ +SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){ + int rc; + +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + /* If the write-lock is already held, then it was obtained before the + ** read-transaction was even opened, making this call a no-op. + ** Return early. */ + if( pWal->writeLock ){ + assert( !memcmp(&pWal->hdr,(void*)pWal->apWiData[0],sizeof(WalIndexHdr)) ); + return SQLITE_OK; + } +#endif + + /* Cannot start a write transaction without first holding a read + ** transaction. */ + assert( pWal->readLock>=0 ); + assert( pWal->writeLock==0 && pWal->iReCksum==0 ); + + if( pWal->readOnly ){ + return SQLITE_READONLY; + } + + /* Only one writer allowed at a time. Get the write lock. Return + ** SQLITE_BUSY if unable. + */ + rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1); + if( rc ){ + return rc; + } + pWal->writeLock = 1; + + /* If another connection has written to the database file since the + ** time the read transaction on this connection was started, then + ** the write is disallowed. + */ + SEH_TRY { + if( memcmp(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr))!=0 ){ + rc = SQLITE_BUSY_SNAPSHOT; + } + } + SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) + + if( rc!=SQLITE_OK ){ + walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); + pWal->writeLock = 0; + } + return rc; +} + +/* +** End a write transaction. The commit has already been done. This +** routine merely releases the lock. +*/ +SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal){ + if( pWal->writeLock ){ + walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); + pWal->writeLock = 0; + pWal->iReCksum = 0; + pWal->truncateOnCommit = 0; + } + return SQLITE_OK; +} + +/* +** If any data has been written (but not committed) to the log file, this +** function moves the write-pointer back to the start of the transaction. +** +** Additionally, the callback function is invoked for each frame written +** to the WAL since the start of the transaction. If the callback returns +** other than SQLITE_OK, it is not invoked again and the error code is +** returned to the caller. +** +** Otherwise, if the callback function does not return an error, this +** function returns SQLITE_OK. +*/ +SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx){ + int rc = SQLITE_OK; + if( ALWAYS(pWal->writeLock) ){ + Pgno iMax = pWal->hdr.mxFrame; + Pgno iFrame; + + SEH_TRY { + /* Restore the clients cache of the wal-index header to the state it + ** was in before the client began writing to the database. + */ + memcpy(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr)); + + for(iFrame=pWal->hdr.mxFrame+1; + ALWAYS(rc==SQLITE_OK) && iFrame<=iMax; + iFrame++ + ){ + /* This call cannot fail. Unless the page for which the page number + ** is passed as the second argument is (a) in the cache and + ** (b) has an outstanding reference, then xUndo is either a no-op + ** (if (a) is false) or simply expels the page from the cache (if (b) + ** is false). + ** + ** If the upper layer is doing a rollback, it is guaranteed that there + ** are no outstanding references to any page other than page 1. And + ** page 1 is never written to the log until the transaction is + ** committed. As a result, the call to xUndo may not fail. + */ + assert( walFramePgno(pWal, iFrame)!=1 ); + rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame)); + } + if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal); + } + SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) + pWal->iReCksum = 0; + } + return rc; +} + +/* +** Argument aWalData must point to an array of WAL_SAVEPOINT_NDATA u32 +** values. This function populates the array with values required to +** "rollback" the write position of the WAL handle back to the current +** point in the event of a savepoint rollback (via WalSavepointUndo()). +*/ +SQLITE_PRIVATE void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData){ + assert( pWal->writeLock ); + aWalData[0] = pWal->hdr.mxFrame; + aWalData[1] = pWal->hdr.aFrameCksum[0]; + aWalData[2] = pWal->hdr.aFrameCksum[1]; + aWalData[3] = pWal->nCkpt; +} + +/* +** Move the write position of the WAL back to the point identified by +** the values in the aWalData[] array. aWalData must point to an array +** of WAL_SAVEPOINT_NDATA u32 values that has been previously populated +** by a call to WalSavepoint(). +*/ +SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){ + int rc = SQLITE_OK; + + assert( pWal->writeLock ); + assert( aWalData[3]!=pWal->nCkpt || aWalData[0]<=pWal->hdr.mxFrame ); + + if( aWalData[3]!=pWal->nCkpt ){ + /* This savepoint was opened immediately after the write-transaction + ** was started. Right after that, the writer decided to wrap around + ** to the start of the log. Update the savepoint values to match. + */ + aWalData[0] = 0; + aWalData[3] = pWal->nCkpt; + } + + if( aWalData[0]hdr.mxFrame ){ + pWal->hdr.mxFrame = aWalData[0]; + pWal->hdr.aFrameCksum[0] = aWalData[1]; + pWal->hdr.aFrameCksum[1] = aWalData[2]; + SEH_TRY { + walCleanupHash(pWal); + } + SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) + if( pWal->iReCksum>pWal->hdr.mxFrame ){ + pWal->iReCksum = 0; + } + } + + return rc; +} + +/* +** This function is called just before writing a set of frames to the log +** file (see sqlite3WalFrames()). It checks to see if, instead of appending +** to the current log file, it is possible to overwrite the start of the +** existing log file with the new frames (i.e. "reset" the log). If so, +** it sets pWal->hdr.mxFrame to 0. Otherwise, pWal->hdr.mxFrame is left +** unchanged. +** +** SQLITE_OK is returned if no error is encountered (regardless of whether +** or not pWal->hdr.mxFrame is modified). An SQLite error code is returned +** if an error occurs. +*/ +static int walRestartLog(Wal *pWal){ + int rc = SQLITE_OK; + int cnt; + + if( pWal->readLock==0 ){ + volatile WalCkptInfo *pInfo = walCkptInfo(pWal); + assert( pInfo->nBackfill==pWal->hdr.mxFrame ); + if( pInfo->nBackfill>0 ){ + u32 salt1; + sqlite3_randomness(4, &salt1); + rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); + if( rc==SQLITE_OK ){ + /* If all readers are using WAL_READ_LOCK(0) (in other words if no + ** readers are currently using the WAL), then the transactions + ** frames will overwrite the start of the existing log. Update the + ** wal-index header to reflect this. + ** + ** In theory it would be Ok to update the cache of the header only + ** at this point. But updating the actual wal-index header is also + ** safe and means there is no special case for sqlite3WalUndo() + ** to handle if this transaction is rolled back. */ + walRestartHdr(pWal, salt1); + walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); + }else if( rc!=SQLITE_BUSY ){ + return rc; + } + } + walUnlockShared(pWal, WAL_READ_LOCK(0)); + pWal->readLock = -1; + cnt = 0; + do{ + int notUsed; + rc = walTryBeginRead(pWal, ¬Used, 1, &cnt); + }while( rc==WAL_RETRY ); + assert( (rc&0xff)!=SQLITE_BUSY ); /* BUSY not possible when useWal==1 */ + testcase( (rc&0xff)==SQLITE_IOERR ); + testcase( rc==SQLITE_PROTOCOL ); + testcase( rc==SQLITE_OK ); + } + return rc; +} + +/* +** Information about the current state of the WAL file and where +** the next fsync should occur - passed from sqlite3WalFrames() into +** walWriteToLog(). +*/ +typedef struct WalWriter { + Wal *pWal; /* The complete WAL information */ + sqlite3_file *pFd; /* The WAL file to which we write */ + sqlite3_int64 iSyncPoint; /* Fsync at this offset */ + int syncFlags; /* Flags for the fsync */ + int szPage; /* Size of one page */ +} WalWriter; + +/* +** Write iAmt bytes of content into the WAL file beginning at iOffset. +** Do a sync when crossing the p->iSyncPoint boundary. +** +** In other words, if iSyncPoint is in between iOffset and iOffset+iAmt, +** first write the part before iSyncPoint, then sync, then write the +** rest. +*/ +static int walWriteToLog( + WalWriter *p, /* WAL to write to */ + void *pContent, /* Content to be written */ + int iAmt, /* Number of bytes to write */ + sqlite3_int64 iOffset /* Start writing at this offset */ +){ + int rc; + if( iOffsetiSyncPoint && iOffset+iAmt>=p->iSyncPoint ){ + int iFirstAmt = (int)(p->iSyncPoint - iOffset); + rc = sqlite3OsWrite(p->pFd, pContent, iFirstAmt, iOffset); + if( rc ) return rc; + iOffset += iFirstAmt; + iAmt -= iFirstAmt; + pContent = (void*)(iFirstAmt + (char*)pContent); + assert( WAL_SYNC_FLAGS(p->syncFlags)!=0 ); + rc = sqlite3OsSync(p->pFd, WAL_SYNC_FLAGS(p->syncFlags)); + if( iAmt==0 || rc ) return rc; + } + rc = sqlite3OsWrite(p->pFd, pContent, iAmt, iOffset); + return rc; +} + +/* +** Write out a single frame of the WAL +*/ +static int walWriteOneFrame( + WalWriter *p, /* Where to write the frame */ + PgHdr *pPage, /* The page of the frame to be written */ + int nTruncate, /* The commit flag. Usually 0. >0 for commit */ + sqlite3_int64 iOffset /* Byte offset at which to write */ +){ + int rc; /* Result code from subfunctions */ + void *pData; /* Data actually written */ + u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-header in */ + pData = pPage->pData; + walEncodeFrame(p->pWal, pPage->pgno, nTruncate, pData, aFrame); + rc = walWriteToLog(p, aFrame, sizeof(aFrame), iOffset); + if( rc ) return rc; + /* Write the page data */ + rc = walWriteToLog(p, pData, p->szPage, iOffset+sizeof(aFrame)); + return rc; +} + +/* +** This function is called as part of committing a transaction within which +** one or more frames have been overwritten. It updates the checksums for +** all frames written to the wal file by the current transaction starting +** with the earliest to have been overwritten. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +*/ +static int walRewriteChecksums(Wal *pWal, u32 iLast){ + const int szPage = pWal->szPage;/* Database page size */ + int rc = SQLITE_OK; /* Return code */ + u8 *aBuf; /* Buffer to load data from wal file into */ + u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-headers in */ + u32 iRead; /* Next frame to read from wal file */ + i64 iCksumOff; + + aBuf = sqlite3_malloc(szPage + WAL_FRAME_HDRSIZE); + if( aBuf==0 ) return SQLITE_NOMEM_BKPT; + + /* Find the checksum values to use as input for the recalculating the + ** first checksum. If the first frame is frame 1 (implying that the current + ** transaction restarted the wal file), these values must be read from the + ** wal-file header. Otherwise, read them from the frame header of the + ** previous frame. */ + assert( pWal->iReCksum>0 ); + if( pWal->iReCksum==1 ){ + iCksumOff = 24; + }else{ + iCksumOff = walFrameOffset(pWal->iReCksum-1, szPage) + 16; + } + rc = sqlite3OsRead(pWal->pWalFd, aBuf, sizeof(u32)*2, iCksumOff); + pWal->hdr.aFrameCksum[0] = sqlite3Get4byte(aBuf); + pWal->hdr.aFrameCksum[1] = sqlite3Get4byte(&aBuf[sizeof(u32)]); + + iRead = pWal->iReCksum; + pWal->iReCksum = 0; + for(; rc==SQLITE_OK && iRead<=iLast; iRead++){ + i64 iOff = walFrameOffset(iRead, szPage); + rc = sqlite3OsRead(pWal->pWalFd, aBuf, szPage+WAL_FRAME_HDRSIZE, iOff); + if( rc==SQLITE_OK ){ + u32 iPgno, nDbSize; + iPgno = sqlite3Get4byte(aBuf); + nDbSize = sqlite3Get4byte(&aBuf[4]); + + walEncodeFrame(pWal, iPgno, nDbSize, &aBuf[WAL_FRAME_HDRSIZE], aFrame); + rc = sqlite3OsWrite(pWal->pWalFd, aFrame, sizeof(aFrame), iOff); + } + } + + sqlite3_free(aBuf); + return rc; +} + +/* +** Write a set of frames to the log. The caller must hold the write-lock +** on the log file (obtained using sqlite3WalBeginWriteTransaction()). +*/ +static int walFrames( + Wal *pWal, /* Wal handle to write to */ + int szPage, /* Database page-size in bytes */ + PgHdr *pList, /* List of dirty pages to write */ + Pgno nTruncate, /* Database size after this commit */ + int isCommit, /* True if this is a commit */ + int sync_flags /* Flags to pass to OsSync() (or 0) */ +){ + int rc; /* Used to catch return codes */ + u32 iFrame; /* Next frame address */ + PgHdr *p; /* Iterator to run through pList with. */ + PgHdr *pLast = 0; /* Last frame in list */ + int nExtra = 0; /* Number of extra copies of last page */ + int szFrame; /* The size of a single frame */ + i64 iOffset; /* Next byte to write in WAL file */ + WalWriter w; /* The writer */ + u32 iFirst = 0; /* First frame that may be overwritten */ + WalIndexHdr *pLive; /* Pointer to shared header */ + + assert( pList ); + assert( pWal->writeLock ); + + /* If this frame set completes a transaction, then nTruncate>0. If + ** nTruncate==0 then this frame set does not complete the transaction. */ + assert( (isCommit!=0)==(nTruncate!=0) ); + +#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) + { int cnt; for(cnt=0, p=pList; p; p=p->pDirty, cnt++){} + WALTRACE(("WAL%p: frame write begin. %d frames. mxFrame=%d. %s\n", + pWal, cnt, pWal->hdr.mxFrame, isCommit ? "Commit" : "Spill")); + } +#endif + + pLive = (WalIndexHdr*)walIndexHdr(pWal); + if( memcmp(&pWal->hdr, (void *)pLive, sizeof(WalIndexHdr))!=0 ){ + iFirst = pLive->mxFrame+1; + } + + /* See if it is possible to write these frames into the start of the + ** log file, instead of appending to it at pWal->hdr.mxFrame. + */ + if( SQLITE_OK!=(rc = walRestartLog(pWal)) ){ + return rc; + } + + /* If this is the first frame written into the log, write the WAL + ** header to the start of the WAL file. See comments at the top of + ** this source file for a description of the WAL header format. + */ + iFrame = pWal->hdr.mxFrame; + if( iFrame==0 ){ + u8 aWalHdr[WAL_HDRSIZE]; /* Buffer to assemble wal-header in */ + u32 aCksum[2]; /* Checksum for wal-header */ + + sqlite3Put4byte(&aWalHdr[0], (WAL_MAGIC | SQLITE_BIGENDIAN)); + sqlite3Put4byte(&aWalHdr[4], WAL_MAX_VERSION); + sqlite3Put4byte(&aWalHdr[8], szPage); + sqlite3Put4byte(&aWalHdr[12], pWal->nCkpt); + if( pWal->nCkpt==0 ) sqlite3_randomness(8, pWal->hdr.aSalt); + memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8); + walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum); + sqlite3Put4byte(&aWalHdr[24], aCksum[0]); + sqlite3Put4byte(&aWalHdr[28], aCksum[1]); + + pWal->szPage = szPage; + pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN; + pWal->hdr.aFrameCksum[0] = aCksum[0]; + pWal->hdr.aFrameCksum[1] = aCksum[1]; + pWal->truncateOnCommit = 1; + + rc = sqlite3OsWrite(pWal->pWalFd, aWalHdr, sizeof(aWalHdr), 0); + WALTRACE(("WAL%p: wal-header write %s\n", pWal, rc ? "failed" : "ok")); + if( rc!=SQLITE_OK ){ + return rc; + } + + /* Sync the header (unless SQLITE_IOCAP_SEQUENTIAL is true or unless + ** all syncing is turned off by PRAGMA synchronous=OFF). Otherwise + ** an out-of-order write following a WAL restart could result in + ** database corruption. See the ticket: + ** + ** https://sqlite.org/src/info/ff5be73dee + */ + if( pWal->syncHeader ){ + rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags)); + if( rc ) return rc; + } + } + if( (int)pWal->szPage!=szPage ){ + return SQLITE_CORRUPT_BKPT; /* TH3 test case: cov1/corrupt155.test */ + } + + /* Setup information needed to write frames into the WAL */ + w.pWal = pWal; + w.pFd = pWal->pWalFd; + w.iSyncPoint = 0; + w.syncFlags = sync_flags; + w.szPage = szPage; + iOffset = walFrameOffset(iFrame+1, szPage); + szFrame = szPage + WAL_FRAME_HDRSIZE; + + /* Write all frames into the log file exactly once */ + for(p=pList; p; p=p->pDirty){ + int nDbSize; /* 0 normally. Positive == commit flag */ + + /* Check if this page has already been written into the wal file by + ** the current transaction. If so, overwrite the existing frame and + ** set Wal.writeLock to WAL_WRITELOCK_RECKSUM - indicating that + ** checksums must be recomputed when the transaction is committed. */ + if( iFirst && (p->pDirty || isCommit==0) ){ + u32 iWrite = 0; + VVA_ONLY(rc =) walFindFrame(pWal, p->pgno, &iWrite); + assert( rc==SQLITE_OK || iWrite==0 ); + if( iWrite>=iFirst ){ + i64 iOff = walFrameOffset(iWrite, szPage) + WAL_FRAME_HDRSIZE; + void *pData; + if( pWal->iReCksum==0 || iWriteiReCksum ){ + pWal->iReCksum = iWrite; + } + pData = p->pData; + rc = sqlite3OsWrite(pWal->pWalFd, pData, szPage, iOff); + if( rc ) return rc; + p->flags &= ~PGHDR_WAL_APPEND; + continue; + } + } + + iFrame++; + assert( iOffset==walFrameOffset(iFrame, szPage) ); + nDbSize = (isCommit && p->pDirty==0) ? nTruncate : 0; + rc = walWriteOneFrame(&w, p, nDbSize, iOffset); + if( rc ) return rc; + pLast = p; + iOffset += szFrame; + p->flags |= PGHDR_WAL_APPEND; + } + + /* Recalculate checksums within the wal file if required. */ + if( isCommit && pWal->iReCksum ){ + rc = walRewriteChecksums(pWal, iFrame); + if( rc ) return rc; + } + + /* If this is the end of a transaction, then we might need to pad + ** the transaction and/or sync the WAL file. + ** + ** Padding and syncing only occur if this set of frames complete a + ** transaction and if PRAGMA synchronous=FULL. If synchronous==NORMAL + ** or synchronous==OFF, then no padding or syncing are needed. + ** + ** If SQLITE_IOCAP_POWERSAFE_OVERWRITE is defined, then padding is not + ** needed and only the sync is done. If padding is needed, then the + ** final frame is repeated (with its commit mark) until the next sector + ** boundary is crossed. Only the part of the WAL prior to the last + ** sector boundary is synced; the part of the last frame that extends + ** past the sector boundary is written after the sync. + */ + if( isCommit && WAL_SYNC_FLAGS(sync_flags)!=0 ){ + int bSync = 1; + if( pWal->padToSectorBoundary ){ + int sectorSize = sqlite3SectorSize(pWal->pWalFd); + w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize; + bSync = (w.iSyncPoint==iOffset); + testcase( bSync ); + while( iOffsettruncateOnCommit && pWal->mxWalSize>=0 ){ + i64 sz = pWal->mxWalSize; + if( walFrameOffset(iFrame+nExtra+1, szPage)>pWal->mxWalSize ){ + sz = walFrameOffset(iFrame+nExtra+1, szPage); + } + walLimitSize(pWal, sz); + pWal->truncateOnCommit = 0; + } + + /* Append data to the wal-index. It is not necessary to lock the + ** wal-index to do this as the SQLITE_SHM_WRITE lock held on the wal-index + ** guarantees that there are no other writers, and no data that may + ** be in use by existing readers is being overwritten. + */ + iFrame = pWal->hdr.mxFrame; + for(p=pList; p && rc==SQLITE_OK; p=p->pDirty){ + if( (p->flags & PGHDR_WAL_APPEND)==0 ) continue; + iFrame++; + rc = walIndexAppend(pWal, iFrame, p->pgno); + } + assert( pLast!=0 || nExtra==0 ); + while( rc==SQLITE_OK && nExtra>0 ){ + iFrame++; + nExtra--; + rc = walIndexAppend(pWal, iFrame, pLast->pgno); + } + + if( rc==SQLITE_OK ){ + /* Update the private copy of the header. */ + pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16)); + testcase( szPage<=32768 ); + testcase( szPage>=65536 ); + pWal->hdr.mxFrame = iFrame; + if( isCommit ){ + pWal->hdr.iChange++; + pWal->hdr.nPage = nTruncate; + } + /* If this is a commit, update the wal-index header too. */ + if( isCommit ){ + walIndexWriteHdr(pWal); + pWal->iCallback = iFrame; + } + } + + WALTRACE(("WAL%p: frame write %s\n", pWal, rc ? "failed" : "ok")); + return rc; +} + +/* +** Write a set of frames to the log. The caller must hold the write-lock +** on the log file (obtained using sqlite3WalBeginWriteTransaction()). +** +** The difference between this function and walFrames() is that this +** function wraps walFrames() in an SEH_TRY{...} block. +*/ +SQLITE_PRIVATE int sqlite3WalFrames( + Wal *pWal, /* Wal handle to write to */ + int szPage, /* Database page-size in bytes */ + PgHdr *pList, /* List of dirty pages to write */ + Pgno nTruncate, /* Database size after this commit */ + int isCommit, /* True if this is a commit */ + int sync_flags /* Flags to pass to OsSync() (or 0) */ +){ + int rc; + SEH_TRY { + rc = walFrames(pWal, szPage, pList, nTruncate, isCommit, sync_flags); + } + SEH_EXCEPT( rc = walHandleException(pWal); ) + return rc; +} + +/* +** This routine is called to implement sqlite3_wal_checkpoint() and +** related interfaces. +** +** Obtain a CHECKPOINT lock and then backfill as much information as +** we can from WAL into the database. +** +** If parameter xBusy is not NULL, it is a pointer to a busy-handler +** callback. In this case this function runs a blocking checkpoint. +*/ +SQLITE_PRIVATE int sqlite3WalCheckpoint( + Wal *pWal, /* Wal connection */ + sqlite3 *db, /* Check this handle's interrupt flag */ + int eMode, /* PASSIVE, FULL, RESTART, or TRUNCATE */ + int (*xBusy)(void*), /* Function to call when busy */ + void *pBusyArg, /* Context argument for xBusyHandler */ + int sync_flags, /* Flags to sync db file with (or 0) */ + int nBuf, /* Size of temporary buffer */ + u8 *zBuf, /* Temporary buffer to use */ + int *pnLog, /* OUT: Number of frames in WAL */ + int *pnCkpt /* OUT: Number of backfilled frames in WAL */ +){ + int rc; /* Return code */ + int isChanged = 0; /* True if a new wal-index header is loaded */ + int eMode2 = eMode; /* Mode to pass to walCheckpoint() */ + int (*xBusy2)(void*) = xBusy; /* Busy handler for eMode2 */ + + assert( pWal->ckptLock==0 ); + assert( pWal->writeLock==0 ); + + /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked + ** in the SQLITE_CHECKPOINT_PASSIVE mode. */ + assert( SQLITE_CHECKPOINT_NOOPSQLITE_CHECKPOINT_PASSIVE || xBusy==0 ); + + if( pWal->readOnly ) return SQLITE_READONLY; + WALTRACE(("WAL%p: checkpoint begins\n", pWal)); + + /* Enable blocking locks, if possible. */ + sqlite3WalDb(pWal, db); + if( xBusy2 ) (void)walEnableBlocking(pWal); + + /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive + ** "checkpoint" lock on the database file. + ** EVIDENCE-OF: R-10421-19736 If any other process is running a + ** checkpoint operation at the same time, the lock cannot be obtained and + ** SQLITE_BUSY is returned. + ** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured, + ** it will not be invoked in this case. + */ + if( eMode!=SQLITE_CHECKPOINT_NOOP ){ + rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); + testcase( rc==SQLITE_BUSY ); + testcase( rc!=SQLITE_OK && xBusy2!=0 ); + if( rc==SQLITE_OK ){ + pWal->ckptLock = 1; + + /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART + ** and TRUNCATE modes also obtain the exclusive "writer" lock on the + ** database file. + ** + ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained + ** immediately, and a busy-handler is configured, it is invoked and the + ** writer lock retried until either the busy-handler returns 0 or the + ** lock is successfully obtained. + */ + if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){ + rc = walBusyLock(pWal, xBusy2, pBusyArg, WAL_WRITE_LOCK, 1); + if( rc==SQLITE_OK ){ + pWal->writeLock = 1; + }else if( rc==SQLITE_BUSY ){ + eMode2 = SQLITE_CHECKPOINT_PASSIVE; + xBusy2 = 0; + rc = SQLITE_OK; + } + } + } + }else{ + rc = SQLITE_OK; + } + + + /* Read the wal-index header. */ + SEH_TRY { + if( rc==SQLITE_OK ){ + /* For a passive checkpoint, do not re-enable blocking locks after + ** reading the wal-index header. A passive checkpoint should not block + ** or invoke the busy handler. The only lock such a checkpoint may + ** attempt to obtain is a lock on a read-slot, and it should give up + ** immediately and do a partial checkpoint if it cannot obtain it. */ + walDisableBlocking(pWal); + rc = walIndexReadHdr(pWal, &isChanged); + if( eMode2>SQLITE_CHECKPOINT_PASSIVE ) (void)walEnableBlocking(pWal); + if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){ + sqlite3OsUnfetch(pWal->pDbFd, 0, 0); + } + } + + /* Copy data from the log to the database file. */ + if( rc==SQLITE_OK ){ + sqlite3FaultSim(660); + if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){ + rc = SQLITE_CORRUPT_BKPT; + }else if( eMode2!=SQLITE_CHECKPOINT_NOOP ){ + rc = walCheckpoint(pWal, db, eMode2, xBusy2, pBusyArg, sync_flags,zBuf); + } + + /* If no error occurred, set the output variables. */ + if( rc==SQLITE_OK || rc==SQLITE_BUSY ){ + if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame; + SEH_INJECT_FAULT; + if( pnCkpt ) *pnCkpt = (int)(walCkptInfo(pWal)->nBackfill); + } + } + } + SEH_EXCEPT( rc = walHandleException(pWal); ) + + if( isChanged ){ + /* If a new wal-index header was loaded before the checkpoint was + ** performed, then the pager-cache associated with pWal is now + ** out of date. So zero the cached wal-index header to ensure that + ** next time the pager opens a snapshot on this database it knows that + ** the cache needs to be reset. + */ + memset(&pWal->hdr, 0, sizeof(WalIndexHdr)); + } + + walDisableBlocking(pWal); + sqlite3WalDb(pWal, 0); + + /* Release the locks. */ + (void)sqlite3WalEndWriteTransaction(pWal); + if( pWal->ckptLock ){ + walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1); + pWal->ckptLock = 0; + } + WALTRACE(("WAL%p: checkpoint %s\n", pWal, rc ? "failed" : "ok")); +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY; +#endif + return (rc==SQLITE_OK && eMode!=eMode2 ? SQLITE_BUSY : rc); +} + +/* Return the value to pass to a sqlite3_wal_hook callback, the +** number of frames in the WAL at the point of the last commit since +** sqlite3WalCallback() was called. If no commits have occurred since +** the last call, then return 0. +*/ +SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal){ + u32 ret = 0; + if( pWal ){ + ret = pWal->iCallback; + pWal->iCallback = 0; + } + return (int)ret; +} + +/* +** This function is called to change the WAL subsystem into or out +** of locking_mode=EXCLUSIVE. +** +** If op is zero, then attempt to change from locking_mode=EXCLUSIVE +** into locking_mode=NORMAL. This means that we must acquire a lock +** on the pWal->readLock byte. If the WAL is already in locking_mode=NORMAL +** or if the acquisition of the lock fails, then return 0. If the +** transition out of exclusive-mode is successful, return 1. This +** operation must occur while the pager is still holding the exclusive +** lock on the main database file. +** +** If op is one, then change from locking_mode=NORMAL into +** locking_mode=EXCLUSIVE. This means that the pWal->readLock must +** be released. Return 1 if the transition is made and 0 if the +** WAL is already in exclusive-locking mode - meaning that this +** routine is a no-op. The pager must already hold the exclusive lock +** on the main database file before invoking this operation. +** +** If op is negative, then do a dry-run of the op==1 case but do +** not actually change anything. The pager uses this to see if it +** should acquire the database exclusive lock prior to invoking +** the op==1 case. +*/ +SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op){ + int rc; + assert( pWal->writeLock==0 ); + assert( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE || op==-1 ); + + /* pWal->readLock is usually set, but might be -1 if there was a + ** prior error while attempting to acquire are read-lock. This cannot + ** happen if the connection is actually in exclusive mode (as no xShmLock + ** locks are taken in this case). Nor should the pager attempt to + ** upgrade to exclusive-mode following such an error. + */ +#ifndef SQLITE_USE_SEH + assert( pWal->readLock>=0 || pWal->lockError ); +#endif + assert( pWal->readLock>=0 || (op<=0 && pWal->exclusiveMode==0) ); + + if( op==0 ){ + if( pWal->exclusiveMode!=WAL_NORMAL_MODE ){ + pWal->exclusiveMode = WAL_NORMAL_MODE; + if( walLockShared(pWal, WAL_READ_LOCK(pWal->readLock))!=SQLITE_OK ){ + pWal->exclusiveMode = WAL_EXCLUSIVE_MODE; + } + rc = pWal->exclusiveMode==WAL_NORMAL_MODE; + }else{ + /* Already in locking_mode=NORMAL */ + rc = 0; + } + }else if( op>0 ){ + assert( pWal->exclusiveMode==WAL_NORMAL_MODE ); + assert( pWal->readLock>=0 ); + walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock)); + pWal->exclusiveMode = WAL_EXCLUSIVE_MODE; + rc = 1; + }else{ + rc = pWal->exclusiveMode==WAL_NORMAL_MODE; + } + return rc; +} + +/* +** Return true if the argument is non-NULL and the WAL module is using +** heap-memory for the wal-index. Otherwise, if the argument is NULL or the +** WAL module is using shared-memory, return false. +*/ +SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal){ + return (pWal && pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ); +} + +#ifdef SQLITE_ENABLE_SNAPSHOT +/* Create a snapshot object. The content of a snapshot is opaque to +** every other subsystem, so the WAL module can put whatever it needs +** in the object. +*/ +SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot){ + int rc = SQLITE_OK; + WalIndexHdr *pRet; + static const u32 aZero[4] = { 0, 0, 0, 0 }; + + assert( pWal->readLock>=0 && pWal->writeLock==0 ); + + if( memcmp(&pWal->hdr.aFrameCksum[0],aZero,16)==0 ){ + *ppSnapshot = 0; + return SQLITE_ERROR; + } + pRet = (WalIndexHdr*)sqlite3_malloc(sizeof(WalIndexHdr)); + if( pRet==0 ){ + rc = SQLITE_NOMEM_BKPT; + }else{ + memcpy(pRet, &pWal->hdr, sizeof(WalIndexHdr)); + *ppSnapshot = (sqlite3_snapshot*)pRet; + } + + return rc; +} + +/* Try to open on pSnapshot when the next read-transaction starts +*/ +SQLITE_PRIVATE void sqlite3WalSnapshotOpen( + Wal *pWal, + sqlite3_snapshot *pSnapshot +){ + if( pSnapshot && ((WalIndexHdr*)pSnapshot)->iVersion==0 ){ + /* iVersion==0 means that this is a call to sqlite3_snapshot_get(). In + ** this case set the bGetSnapshot flag so that if the call to + ** sqlite3_snapshot_get() is about to read transaction on this wal + ** file, it does not take read-lock 0 if the wal file has been completely + ** checkpointed. Taking read-lock 0 would work, but then it would be + ** possible for a subsequent writer to destroy the snapshot even while + ** this connection is holding its read-transaction open. This is contrary + ** to user expectations, so we avoid it by not taking read-lock 0. */ + pWal->bGetSnapshot = 1; + }else{ + pWal->pSnapshot = (WalIndexHdr*)pSnapshot; + pWal->bGetSnapshot = 0; + } +} + +/* +** Return a +ve value if snapshot p1 is newer than p2. A -ve value if +** p1 is older than p2 and zero if p1 and p2 are the same snapshot. +*/ +SQLITE_API int sqlite3_snapshot_cmp(sqlite3_snapshot *p1, sqlite3_snapshot *p2){ + WalIndexHdr *pHdr1 = (WalIndexHdr*)p1; + WalIndexHdr *pHdr2 = (WalIndexHdr*)p2; + + /* aSalt[0] is a copy of the value stored in the wal file header. It + ** is incremented each time the wal file is restarted. */ + if( pHdr1->aSalt[0]aSalt[0] ) return -1; + if( pHdr1->aSalt[0]>pHdr2->aSalt[0] ) return +1; + if( pHdr1->mxFramemxFrame ) return -1; + if( pHdr1->mxFrame>pHdr2->mxFrame ) return +1; + return 0; +} + +/* +** The caller currently has a read transaction open on the database. +** This function takes a SHARED lock on the CHECKPOINTER slot and then +** checks if the snapshot passed as the second argument is still +** available. If so, SQLITE_OK is returned. +** +** If the snapshot is not available, SQLITE_ERROR is returned. Or, if +** the CHECKPOINTER lock cannot be obtained, SQLITE_BUSY. If any error +** occurs (any value other than SQLITE_OK is returned), the CHECKPOINTER +** lock is released before returning. +*/ +SQLITE_PRIVATE int sqlite3WalSnapshotCheck(Wal *pWal, sqlite3_snapshot *pSnapshot){ + int rc; + SEH_TRY { + rc = walLockShared(pWal, WAL_CKPT_LOCK); + if( rc==SQLITE_OK ){ + WalIndexHdr *pNew = (WalIndexHdr*)pSnapshot; + if( memcmp(pNew->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt)) + || pNew->mxFramenBackfillAttempted + ){ + rc = SQLITE_ERROR_SNAPSHOT; + walUnlockShared(pWal, WAL_CKPT_LOCK); + } + } + } + SEH_EXCEPT( rc = walHandleException(pWal); ) + return rc; +} + +/* +** Release a lock obtained by an earlier successful call to +** sqlite3WalSnapshotCheck(). +*/ +SQLITE_PRIVATE void sqlite3WalSnapshotUnlock(Wal *pWal){ + assert( pWal ); + walUnlockShared(pWal, WAL_CKPT_LOCK); +} + + +#endif /* SQLITE_ENABLE_SNAPSHOT */ + +#ifdef SQLITE_ENABLE_ZIPVFS +/* +** If the argument is not NULL, it points to a Wal object that holds a +** read-lock. This function returns the database page-size if it is known, +** or zero if it is not (or if pWal is NULL). +*/ +SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal){ + assert( pWal==0 || pWal->readLock>=0 ); + return (pWal ? pWal->szPage : 0); +} +#endif + +/* Return the sqlite3_file object for the WAL file +*/ +SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal){ + return pWal->pWalFd; +} + +#endif /* #ifndef SQLITE_OMIT_WAL */ + +/************** End of wal.c *************************************************/ +/************** Begin file btmutex.c *****************************************/ +/* +** 2007 August 27 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains code used to implement mutexes on Btree objects. +** This code really belongs in btree.c. But btree.c is getting too +** big and we want to break it down some. This packaged seemed like +** a good breakout. +*/ +/************** Include btreeInt.h in the middle of btmutex.c ****************/ +/************** Begin file btreeInt.h ****************************************/ +/* +** 2004 April 6 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file implements an external (disk-based) database using BTrees. +** For a detailed discussion of BTrees, refer to +** +** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3: +** "Sorting And Searching", pages 473-480. Addison-Wesley +** Publishing Company, Reading, Massachusetts. +** +** The basic idea is that each page of the file contains N database +** entries and N+1 pointers to subpages. +** +** ---------------------------------------------------------------- +** | Ptr(0) | Key(0) | Ptr(1) | Key(1) | ... | Key(N-1) | Ptr(N) | +** ---------------------------------------------------------------- +** +** All of the keys on the page that Ptr(0) points to have values less +** than Key(0). All of the keys on page Ptr(1) and its subpages have +** values greater than Key(0) and less than Key(1). All of the keys +** on Ptr(N) and its subpages have values greater than Key(N-1). And +** so forth. +** +** Finding a particular key requires reading O(log(M)) pages from the +** disk where M is the number of entries in the tree. +** +** In this implementation, a single file can hold one or more separate +** BTrees. Each BTree is identified by the index of its root page. The +** key and data for any entry are combined to form the "payload". A +** fixed amount of payload can be carried directly on the database +** page. If the payload is larger than the preset amount then surplus +** bytes are stored on overflow pages. The payload for an entry +** and the preceding pointer are combined to form a "Cell". Each +** page has a small header which contains the Ptr(N) pointer and other +** information such as the size of key and data. +** +** FORMAT DETAILS +** +** The file is divided into pages. The first page is called page 1, +** the second is page 2, and so forth. A page number of zero indicates +** "no such page". The page size can be any power of 2 between 512 and 65536. +** Each page can be either a btree page, a freelist page, an overflow +** page, or a pointer-map page. +** +** The first page is always a btree page. The first 100 bytes of the first +** page contain a special header (the "file header") that describes the file. +** The format of the file header is as follows: +** +** OFFSET SIZE DESCRIPTION +** 0 16 Header string: "SQLite format 3\000" +** 16 2 Page size in bytes. (1 means 65536) +** 18 1 File format write version +** 19 1 File format read version +** 20 1 Bytes of unused space at the end of each page +** 21 1 Max embedded payload fraction (must be 64) +** 22 1 Min embedded payload fraction (must be 32) +** 23 1 Min leaf payload fraction (must be 32) +** 24 4 File change counter +** 28 4 The size of the database in pages +** 32 4 First freelist page +** 36 4 Number of freelist pages in the file +** 40 60 15 4-byte meta values passed to higher layers +** +** 40 4 Schema cookie +** 44 4 File format of schema layer +** 48 4 Size of page cache +** 52 4 Largest root-page (auto/incr_vacuum) +** 56 4 1=UTF-8 2=UTF16le 3=UTF16be +** 60 4 User version +** 64 4 Incremental vacuum mode +** 68 4 Application-ID +** 72 20 unused +** 92 4 The version-valid-for number +** 96 4 SQLITE_VERSION_NUMBER +** +** All of the integer values are big-endian (most significant byte first). +** +** The file change counter is incremented when the database is changed +** This counter allows other processes to know when the file has changed +** and thus when they need to flush their cache. +** +** The max embedded payload fraction is the amount of the total usable +** space in a page that can be consumed by a single cell for standard +** B-tree (non-LEAFDATA) tables. A value of 255 means 100%. The default +** is to limit the maximum cell size so that at least 4 cells will fit +** on one page. Thus the default max embedded payload fraction is 64. +** +** If the payload for a cell is larger than the max payload, then extra +** payload is spilled to overflow pages. Once an overflow page is allocated, +** as many bytes as possible are moved into the overflow pages without letting +** the cell size drop below the min embedded payload fraction. +** +** The min leaf payload fraction is like the min embedded payload fraction +** except that it applies to leaf nodes in a LEAFDATA tree. The maximum +** payload fraction for a LEAFDATA tree is always 100% (or 255) and it +** not specified in the header. +** +** Each btree pages is divided into three sections: The header, the +** cell pointer array, and the cell content area. Page 1 also has a 100-byte +** file header that occurs before the page header. +** +** |----------------| +** | file header | 100 bytes. Page 1 only. +** |----------------| +** | page header | 8 bytes for leaves. 12 bytes for interior nodes +** |----------------| +** | cell pointer | | 2 bytes per cell. Sorted order. +** | array | | Grows downward +** | | v +** |----------------| +** | unallocated | +** | space | +** |----------------| ^ Grows upwards +** | cell content | | Arbitrary order interspersed with freeblocks. +** | area | | and free space fragments. +** |----------------| +** +** The page headers looks like this: +** +** OFFSET SIZE DESCRIPTION +** 0 1 Flags. 1: intkey, 2: zerodata, 4: leafdata, 8: leaf +** 1 2 byte offset to the first freeblock +** 3 2 number of cells on this page +** 5 2 first byte of the cell content area +** 7 1 number of fragmented free bytes +** 8 4 Right child (the Ptr(N) value). Omitted on leaves. +** +** The flags define the format of this btree page. The leaf flag means that +** this page has no children. The zerodata flag means that this page carries +** only keys and no data. The intkey flag means that the key is an integer +** which is stored in the key size entry of the cell header rather than in +** the payload area. +** +** The cell pointer array begins on the first byte after the page header. +** The cell pointer array contains zero or more 2-byte numbers which are +** offsets from the beginning of the page to the cell content in the cell +** content area. The cell pointers occur in sorted order. The system strives +** to keep free space after the last cell pointer so that new cells can +** be easily added without having to defragment the page. +** +** Cell content is stored at the very end of the page and grows toward the +** beginning of the page. +** +** Unused space within the cell content area is collected into a linked list of +** freeblocks. Each freeblock is at least 4 bytes in size. The byte offset +** to the first freeblock is given in the header. Freeblocks occur in +** increasing order. Because a freeblock must be at least 4 bytes in size, +** any group of 3 or fewer unused bytes in the cell content area cannot +** exist on the freeblock chain. A group of 3 or fewer free bytes is called +** a fragment. The total number of bytes in all fragments is recorded. +** in the page header at offset 7. +** +** SIZE DESCRIPTION +** 2 Byte offset of the next freeblock +** 2 Bytes in this freeblock +** +** Cells are of variable length. Cells are stored in the cell content area at +** the end of the page. Pointers to the cells are in the cell pointer array +** that immediately follows the page header. Cells is not necessarily +** contiguous or in order, but cell pointers are contiguous and in order. +** +** Cell content makes use of variable length integers. A variable +** length integer is 1 to 9 bytes where the lower 7 bits of each +** byte are used. The integer consists of all bytes that have bit 8 set and +** the first byte with bit 8 clear. The most significant byte of the integer +** appears first. A variable-length integer may not be more than 9 bytes long. +** As a special case, all 8 bits of the 9th byte are used as data. This +** allows a 64-bit integer to be encoded in 9 bytes. +** +** 0x00 becomes 0x00000000 +** 0x7f becomes 0x0000007f +** 0x81 0x00 becomes 0x00000080 +** 0x82 0x00 becomes 0x00000100 +** 0x80 0x7f becomes 0x0000007f +** 0x81 0x91 0xd1 0xac 0x78 becomes 0x12345678 +** 0x81 0x81 0x81 0x81 0x01 becomes 0x10204081 +** +** Variable length integers are used for rowids and to hold the number of +** bytes of key and data in a btree cell. +** +** The content of a cell looks like this: +** +** SIZE DESCRIPTION +** 4 Page number of the left child. Omitted if leaf flag is set. +** var Number of bytes of data. Omitted if the zerodata flag is set. +** var Number of bytes of key. Or the key itself if intkey flag is set. +** * Payload +** 4 First page of the overflow chain. Omitted if no overflow +** +** Overflow pages form a linked list. Each page except the last is completely +** filled with data (pagesize - 4 bytes). The last page can have as little +** as 1 byte of data. +** +** SIZE DESCRIPTION +** 4 Page number of next overflow page +** * Data +** +** Freelist pages come in two subtypes: trunk pages and leaf pages. The +** file header points to the first in a linked list of trunk page. Each trunk +** page points to multiple leaf pages. The content of a leaf page is +** unspecified. A trunk page looks like this: +** +** SIZE DESCRIPTION +** 4 Page number of next trunk page +** 4 Number of leaf pointers on this page +** * zero or more pages numbers of leaves +*/ +/* #include "sqliteInt.h" */ + + +/* The following value is the maximum cell size assuming a maximum page +** size give above. +*/ +#define MX_CELL_SIZE(pBt) ((int)(pBt->pageSize-8)) + +/* The maximum number of cells on a single page of the database. This +** assumes a minimum cell size of 6 bytes (4 bytes for the cell itself +** plus 2 bytes for the index to the cell in the page header). Such +** small cells will be rare, but they are possible. +*/ +#define MX_CELL(pBt) ((pBt->pageSize-8)/6) + +/* Forward declarations */ +typedef struct MemPage MemPage; +typedef struct BtLock BtLock; +typedef struct CellInfo CellInfo; + +/* +** This is a magic string that appears at the beginning of every +** SQLite database in order to identify the file as a real database. +** +** You can change this value at compile-time by specifying a +** -DSQLITE_FILE_HEADER="..." on the compiler command-line. The +** header must be exactly 16 bytes including the zero-terminator so +** the string itself should be 15 characters long. If you change +** the header, then your custom library will not be able to read +** databases generated by the standard tools and the standard tools +** will not be able to read databases created by your custom library. +*/ +#ifndef SQLITE_FILE_HEADER /* 123456789 123456 */ +# define SQLITE_FILE_HEADER "SQLite format 3" +#endif + +/* +** Page type flags. An ORed combination of these flags appear as the +** first byte of on-disk image of every BTree page. +*/ +#define PTF_INTKEY 0x01 +#define PTF_ZERODATA 0x02 +#define PTF_LEAFDATA 0x04 +#define PTF_LEAF 0x08 + +/* +** An instance of this object stores information about each a single database +** page that has been loaded into memory. The information in this object +** is derived from the raw on-disk page content. +** +** As each database page is loaded into memory, the pager allocates an +** instance of this object and zeros the first 8 bytes. (This is the +** "extra" information associated with each page of the pager.) +** +** Access to all fields of this structure is controlled by the mutex +** stored in MemPage.pBt->mutex. +*/ +struct MemPage { + u8 isInit; /* True if previously initialized. MUST BE FIRST! */ + u8 intKey; /* True if table b-trees. False for index b-trees */ + u8 intKeyLeaf; /* True if the leaf of an intKey table */ + Pgno pgno; /* Page number for this page */ + /* Only the first 8 bytes (above) are zeroed by pager.c when a new page + ** is allocated. All fields that follow must be initialized before use */ + u8 leaf; /* True if a leaf page */ + u8 hdrOffset; /* 100 for page 1. 0 otherwise */ + u8 childPtrSize; /* 0 if leaf==1. 4 if leaf==0 */ + u8 max1bytePayload; /* min(maxLocal,127) */ + u8 nOverflow; /* Number of overflow cell bodies in aCell[] */ + u16 maxLocal; /* Copy of BtShared.maxLocal or BtShared.maxLeaf */ + u16 minLocal; /* Copy of BtShared.minLocal or BtShared.minLeaf */ + u16 cellOffset; /* Index in aData of first cell pointer */ + int nFree; /* Number of free bytes on the page. -1 for unknown */ + u16 nCell; /* Number of cells on this page, local and ovfl */ + u16 maskPage; /* Mask for page offset */ + u16 aiOvfl[4]; /* Insert the i-th overflow cell before the aiOvfl-th + ** non-overflow cell */ + u8 *apOvfl[4]; /* Pointers to the body of overflow cells */ + BtShared *pBt; /* Pointer to BtShared that this page is part of */ + u8 *aData; /* Pointer to disk image of the page data */ + u8 *aDataEnd; /* One byte past the end of the entire page - not just + ** the usable space, the entire page. Used to prevent + ** corruption-induced buffer overflow. */ + u8 *aCellIdx; /* The cell index area */ + u8 *aDataOfst; /* Same as aData for leaves. aData+4 for interior */ + DbPage *pDbPage; /* Pager page handle */ + u16 (*xCellSize)(MemPage*,u8*); /* cellSizePtr method */ + void (*xParseCell)(MemPage*,u8*,CellInfo*); /* btreeParseCell method */ +}; + +/* +** A linked list of the following structures is stored at BtShared.pLock. +** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor +** is opened on the table with root page BtShared.iTable. Locks are removed +** from this list when a transaction is committed or rolled back, or when +** a btree handle is closed. +*/ +struct BtLock { + Btree *pBtree; /* Btree handle holding this lock */ + Pgno iTable; /* Root page of table */ + u8 eLock; /* READ_LOCK or WRITE_LOCK */ + BtLock *pNext; /* Next in BtShared.pLock list */ +}; + +/* Candidate values for BtLock.eLock */ +#define READ_LOCK 1 +#define WRITE_LOCK 2 + +/* A Btree handle +** +** A database connection contains a pointer to an instance of +** this object for every database file that it has open. This structure +** is opaque to the database connection. The database connection cannot +** see the internals of this structure and only deals with pointers to +** this structure. +** +** For some database files, the same underlying database cache might be +** shared between multiple connections. In that case, each connection +** has it own instance of this object. But each instance of this object +** points to the same BtShared object. The database cache and the +** schema associated with the database file are all contained within +** the BtShared object. +** +** All fields in this structure are accessed under sqlite3.mutex. +** The pBt pointer itself may not be changed while there exists cursors +** in the referenced BtShared that point back to this Btree since those +** cursors have to go through this Btree to find their BtShared and +** they often do so without holding sqlite3.mutex. +*/ +struct Btree { + sqlite3 *db; /* The database connection holding this btree */ + BtShared *pBt; /* Sharable content of this btree */ + u8 inTrans; /* TRANS_NONE, TRANS_READ or TRANS_WRITE */ + u8 sharable; /* True if we can share pBt with another db */ + u8 locked; /* True if db currently has pBt locked */ + u8 hasIncrblobCur; /* True if there are one or more Incrblob cursors */ + int wantToLock; /* Number of nested calls to sqlite3BtreeEnter() */ + int nBackup; /* Number of backup operations reading this btree */ + u32 iBDataVersion; /* Combines with pBt->pPager->iDataVersion */ + Btree *pNext; /* List of other sharable Btrees from the same db */ + Btree *pPrev; /* Back pointer of the same list */ +#ifdef SQLITE_DEBUG + u64 nSeek; /* Calls to sqlite3BtreeMovetoUnpacked() */ +#endif +#ifndef SQLITE_OMIT_SHARED_CACHE + BtLock lock; /* Object used to lock page 1 */ +#endif +}; + +/* +** Btree.inTrans may take one of the following values. +** +** If the shared-data extension is enabled, there may be multiple users +** of the Btree structure. At most one of these may open a write transaction, +** but any number may have active read transactions. +** +** These values must match SQLITE_TXN_NONE, SQLITE_TXN_READ, and +** SQLITE_TXN_WRITE +*/ +#define TRANS_NONE 0 +#define TRANS_READ 1 +#define TRANS_WRITE 2 + +#if TRANS_NONE!=SQLITE_TXN_NONE +# error wrong numeric code for no-transaction +#endif +#if TRANS_READ!=SQLITE_TXN_READ +# error wrong numeric code for read-transaction +#endif +#if TRANS_WRITE!=SQLITE_TXN_WRITE +# error wrong numeric code for write-transaction +#endif + + +/* +** An instance of this object represents a single database file. +** +** A single database file can be in use at the same time by two +** or more database connections. When two or more connections are +** sharing the same database file, each connection has it own +** private Btree object for the file and each of those Btrees points +** to this one BtShared object. BtShared.nRef is the number of +** connections currently sharing this database file. +** +** Fields in this structure are accessed under the BtShared.mutex +** mutex, except for nRef and pNext which are accessed under the +** global SQLITE_MUTEX_STATIC_MAIN mutex. The pPager field +** may not be modified once it is initially set as long as nRef>0. +** The pSchema field may be set once under BtShared.mutex and +** thereafter is unchanged as long as nRef>0. +** +** isPending: +** +** If a BtShared client fails to obtain a write-lock on a database +** table (because there exists one or more read-locks on the table), +** the shared-cache enters 'pending-lock' state and isPending is +** set to true. +** +** The shared-cache leaves the 'pending lock' state when either of +** the following occur: +** +** 1) The current writer (BtShared.pWriter) concludes its transaction, OR +** 2) The number of locks held by other connections drops to zero. +** +** while in the 'pending-lock' state, no connection may start a new +** transaction. +** +** This feature is included to help prevent writer-starvation. +*/ +struct BtShared { + Pager *pPager; /* The page cache */ + sqlite3 *db; /* Database connection currently using this Btree */ + BtCursor *pCursor; /* A list of all open cursors */ + MemPage *pPage1; /* First page of the database */ + u8 openFlags; /* Flags to sqlite3BtreeOpen() */ +#ifndef SQLITE_OMIT_AUTOVACUUM + u8 autoVacuum; /* True if auto-vacuum is enabled */ + u8 incrVacuum; /* True if incr-vacuum is enabled */ + u8 bDoTruncate; /* True to truncate db on commit */ +#endif + u8 inTransaction; /* Transaction state */ + u8 max1bytePayload; /* Maximum first byte of cell for a 1-byte payload */ + u8 nReserveWanted; /* Desired number of extra bytes per page */ + u16 btsFlags; /* Boolean parameters. See BTS_* macros below */ + u16 maxLocal; /* Maximum local payload in non-LEAFDATA tables */ + u16 minLocal; /* Minimum local payload in non-LEAFDATA tables */ + u16 maxLeaf; /* Maximum local payload in a LEAFDATA table */ + u16 minLeaf; /* Minimum local payload in a LEAFDATA table */ + u32 pageSize; /* Total number of bytes on a page */ + u32 usableSize; /* Number of usable bytes on each page */ + int nTransaction; /* Number of open transactions (read + write) */ + u32 nPage; /* Number of pages in the database */ + void *pSchema; /* Pointer to space allocated by sqlite3BtreeSchema() */ + void (*xFreeSchema)(void*); /* Destructor for BtShared.pSchema */ + sqlite3_mutex *mutex; /* Non-recursive mutex required to access this object */ + Bitvec *pHasContent; /* Set of pages moved to free-list this transaction */ +#ifndef SQLITE_OMIT_SHARED_CACHE + int nRef; /* Number of references to this structure */ + BtShared *pNext; /* Next on a list of sharable BtShared structs */ + BtLock *pLock; /* List of locks held on this shared-btree struct */ + Btree *pWriter; /* Btree with currently open write transaction */ +#endif + u8 *pTmpSpace; /* Temp space sufficient to hold a single cell */ + int nPreformatSize; /* Size of last cell written by TransferRow() */ +}; + +/* +** Allowed values for BtShared.btsFlags +*/ +#define BTS_READ_ONLY 0x0001 /* Underlying file is readonly */ +#define BTS_PAGESIZE_FIXED 0x0002 /* Page size can no longer be changed */ +#define BTS_SECURE_DELETE 0x0004 /* PRAGMA secure_delete is enabled */ +#define BTS_OVERWRITE 0x0008 /* Overwrite deleted content with zeros */ +#define BTS_FAST_SECURE 0x000c /* Combination of the previous two */ +#define BTS_INITIALLY_EMPTY 0x0010 /* Database was empty at trans start */ +#define BTS_NO_WAL 0x0020 /* Do not open write-ahead-log files */ +#define BTS_EXCLUSIVE 0x0040 /* pWriter has an exclusive lock */ +#define BTS_PENDING 0x0080 /* Waiting for read-locks to clear */ + +/* +** An instance of the following structure is used to hold information +** about a cell. The parseCellPtr() function fills in this structure +** based on information extract from the raw disk page. +*/ +struct CellInfo { + i64 nKey; /* The key for INTKEY tables, or nPayload otherwise */ + u8 *pPayload; /* Pointer to the start of payload */ + u32 nPayload; /* Bytes of payload */ + u16 nLocal; /* Amount of payload held locally, not on overflow */ + u16 nSize; /* Size of the cell content on the main b-tree page */ +}; + +/* +** Maximum depth of an SQLite B-Tree structure. Any B-Tree deeper than +** this will be declared corrupt. This value is calculated based on a +** maximum database size of 2^31 pages a minimum fanout of 2 for a +** root-node and 3 for all other internal nodes. +** +** If a tree that appears to be taller than this is encountered, it is +** assumed that the database is corrupt. +*/ +#define BTCURSOR_MAX_DEPTH 20 + +/* +** Maximum amount of storage local to a database page, regardless of +** page size. +*/ +#define BT_MAX_LOCAL 65501 /* 65536 - 35 */ + +/* +** A cursor is a pointer to a particular entry within a particular +** b-tree within a database file. +** +** The entry is identified by its MemPage and the index in +** MemPage.aCell[] of the entry. +** +** A single database file can be shared by two more database connections, +** but cursors cannot be shared. Each cursor is associated with a +** particular database connection identified BtCursor.pBtree.db. +** +** Fields in this structure are accessed under the BtShared.mutex +** found at self->pBt->mutex. +** +** skipNext meaning: +** The meaning of skipNext depends on the value of eState: +** +** eState Meaning of skipNext +** VALID skipNext is meaningless and is ignored +** INVALID skipNext is meaningless and is ignored +** SKIPNEXT sqlite3BtreeNext() is a no-op if skipNext>0 and +** sqlite3BtreePrevious() is no-op if skipNext<0. +** REQUIRESEEK restoreCursorPosition() restores the cursor to +** eState=SKIPNEXT if skipNext!=0 +** FAULT skipNext holds the cursor fault error code. +*/ +struct BtCursor { + u8 eState; /* One of the CURSOR_XXX constants (see below) */ + u8 curFlags; /* zero or more BTCF_* flags defined below */ + u8 curPagerFlags; /* Flags to send to sqlite3PagerGet() */ + u8 hints; /* As configured by CursorSetHints() */ + int skipNext; /* Prev() is noop if negative. Next() is noop if positive. + ** Error code if eState==CURSOR_FAULT */ + Btree *pBtree; /* The Btree to which this cursor belongs */ + Pgno *aOverflow; /* Cache of overflow page locations */ + void *pKey; /* Saved key that was cursor last known position */ + /* All fields above are zeroed when the cursor is allocated. See + ** sqlite3BtreeCursorZero(). Fields that follow must be manually + ** initialized. */ +#define BTCURSOR_FIRST_UNINIT pBt /* Name of first uninitialized field */ + BtShared *pBt; /* The BtShared this cursor points to */ + BtCursor *pNext; /* Forms a linked list of all cursors */ + CellInfo info; /* A parse of the cell we are pointing at */ + i64 nKey; /* Size of pKey, or last integer key */ + Pgno pgnoRoot; /* The root page of this tree */ + i8 iPage; /* Index of current page in apPage */ + u8 curIntKey; /* Value of apPage[0]->intKey */ + u16 ix; /* Current index for apPage[iPage] */ + u16 aiIdx[BTCURSOR_MAX_DEPTH-1]; /* Current index in apPage[i] */ + struct KeyInfo *pKeyInfo; /* Arg passed to comparison function */ + MemPage *pPage; /* Current page */ + MemPage *apPage[BTCURSOR_MAX_DEPTH-1]; /* Stack of parents of current page */ +}; + +/* +** Legal values for BtCursor.curFlags +*/ +#define BTCF_WriteFlag 0x01 /* True if a write cursor */ +#define BTCF_ValidNKey 0x02 /* True if info.nKey is valid */ +#define BTCF_ValidOvfl 0x04 /* True if aOverflow is valid */ +#define BTCF_AtLast 0x08 /* Cursor is pointing to the last entry */ +#define BTCF_Incrblob 0x10 /* True if an incremental I/O handle */ +#define BTCF_Multiple 0x20 /* Maybe another cursor on the same btree */ +#define BTCF_Pinned 0x40 /* Cursor is busy and cannot be moved */ + +/* +** Potential values for BtCursor.eState. +** +** CURSOR_INVALID: +** Cursor does not point to a valid entry. This can happen (for example) +** because the table is empty or because BtreeCursorFirst() has not been +** called. +** +** CURSOR_VALID: +** Cursor points to a valid entry. getPayload() etc. may be called. +** +** CURSOR_SKIPNEXT: +** Cursor is valid except that the Cursor.skipNext field is non-zero +** indicating that the next sqlite3BtreeNext() or sqlite3BtreePrevious() +** operation should be a no-op. +** +** CURSOR_REQUIRESEEK: +** The table that this cursor was opened on still exists, but has been +** modified since the cursor was last used. The cursor position is saved +** in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in +** this state, restoreCursorPosition() can be called to attempt to +** seek the cursor to the saved position. +** +** CURSOR_FAULT: +** An unrecoverable error (an I/O error or a malloc failure) has occurred +** on a different connection that shares the BtShared cache with this +** cursor. The error has left the cache in an inconsistent state. +** Do nothing else with this cursor. Any attempt to use the cursor +** should return the error code stored in BtCursor.skipNext +*/ +#define CURSOR_VALID 0 +#define CURSOR_INVALID 1 +#define CURSOR_SKIPNEXT 2 +#define CURSOR_REQUIRESEEK 3 +#define CURSOR_FAULT 4 + +/* +** The database page the PENDING_BYTE occupies. This page is never used. +*/ +#define PENDING_BYTE_PAGE(pBt) ((Pgno)((PENDING_BYTE/((pBt)->pageSize))+1)) + +/* +** These macros define the location of the pointer-map entry for a +** database page. The first argument to each is the number of usable +** bytes on each page of the database (often 1024). The second is the +** page number to look up in the pointer map. +** +** PTRMAP_PAGENO returns the database page number of the pointer-map +** page that stores the required pointer. PTRMAP_PTROFFSET returns +** the offset of the requested map entry. +** +** If the pgno argument passed to PTRMAP_PAGENO is a pointer-map page, +** then pgno is returned. So (pgno==PTRMAP_PAGENO(pgsz, pgno)) can be +** used to test if pgno is a pointer-map page. PTRMAP_ISPAGE implements +** this test. +*/ +#define PTRMAP_PAGENO(pBt, pgno) ptrmapPageno(pBt, pgno) +#define PTRMAP_PTROFFSET(pgptrmap, pgno) (5*(pgno-pgptrmap-1)) +#define PTRMAP_ISPAGE(pBt, pgno) (PTRMAP_PAGENO((pBt),(pgno))==(pgno)) + +/* +** The pointer map is a lookup table that identifies the parent page for +** each child page in the database file. The parent page is the page that +** contains a pointer to the child. Every page in the database contains +** 0 or 1 parent pages. (In this context 'database page' refers +** to any page that is not part of the pointer map itself.) Each pointer map +** entry consists of a single byte 'type' and a 4 byte parent page number. +** The PTRMAP_XXX identifiers below are the valid types. +** +** The purpose of the pointer map is to facility moving pages from one +** position in the file to another as part of autovacuum. When a page +** is moved, the pointer in its parent must be updated to point to the +** new location. The pointer map is used to locate the parent page quickly. +** +** PTRMAP_ROOTPAGE: The database page is a root-page. The page-number is not +** used in this case. +** +** PTRMAP_FREEPAGE: The database page is an unused (free) page. The page-number +** is not used in this case. +** +** PTRMAP_OVERFLOW1: The database page is the first page in a list of +** overflow pages. The page number identifies the page that +** contains the cell with a pointer to this overflow page. +** +** PTRMAP_OVERFLOW2: The database page is the second or later page in a list of +** overflow pages. The page-number identifies the previous +** page in the overflow page list. +** +** PTRMAP_BTREE: The database page is a non-root btree page. The page number +** identifies the parent page in the btree. +*/ +#define PTRMAP_ROOTPAGE 1 +#define PTRMAP_FREEPAGE 2 +#define PTRMAP_OVERFLOW1 3 +#define PTRMAP_OVERFLOW2 4 +#define PTRMAP_BTREE 5 + +/* A bunch of assert() statements to check the transaction state variables +** of handle p (type Btree*) are internally consistent. +*/ +#define btreeIntegrity(p) \ + assert( p->pBt->inTransaction!=TRANS_NONE || p->pBt->nTransaction==0 ); \ + assert( p->pBt->inTransaction>=p->inTrans ); + + +/* +** The ISAUTOVACUUM macro is used within balance_nonroot() to determine +** if the database supports auto-vacuum or not. Because it is used +** within an expression that is an argument to another macro +** (sqliteMallocRaw), it is not possible to use conditional compilation. +** So, this macro is defined instead. +*/ +#ifndef SQLITE_OMIT_AUTOVACUUM +#define ISAUTOVACUUM(pBt) (pBt->autoVacuum) +#else +#define ISAUTOVACUUM(pBt) 0 +#endif + + +/* +** This structure is passed around through all the PRAGMA integrity_check +** checking routines in order to keep track of some global state information. +** +** The aRef[] array is allocated so that there is 1 bit for each page in +** the database. As the integrity-check proceeds, for each page used in +** the database the corresponding bit is set. This allows integrity-check to +** detect pages that are used twice and orphaned pages (both of which +** indicate corruption). +*/ +typedef struct IntegrityCk IntegrityCk; +struct IntegrityCk { + BtShared *pBt; /* The tree being checked out */ + Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */ + u8 *aPgRef; /* 1 bit per page in the db (see above) */ + Pgno nCkPage; /* Pages in the database. 0 for partial check */ + int mxErr; /* Stop accumulating errors when this reaches zero */ + int nErr; /* Number of messages written to zErrMsg so far */ + int rc; /* SQLITE_OK, SQLITE_NOMEM, or SQLITE_INTERRUPT */ + u32 nStep; /* Number of steps into the integrity_check process */ + const char *zPfx; /* Error message prefix */ + Pgno v0; /* Value for first %u substitution in zPfx (root page) */ + Pgno v1; /* Value for second %u substitution in zPfx (current pg) */ + int v2; /* Value for third %d substitution in zPfx */ + StrAccum errMsg; /* Accumulate the error message text here */ + u32 *heap; /* Min-heap used for analyzing cell coverage */ + sqlite3 *db; /* Database connection running the check */ + i64 nRow; /* Number of rows visited in current tree */ +#ifdef SQLITE_DEBUG + u32 mxHeap; /* Maximum number of entries in the Min-heap */ +#endif +}; + +/* +** Routines to read or write a two- and four-byte big-endian integer values. +*/ +#define get2byte(x) ((x)[0]<<8 | (x)[1]) +#define put2byte(p,v) ((p)[0] = (u8)((v)>>8), (p)[1] = (u8)(v)) +#define get4byte sqlite3Get4byte +#define put4byte sqlite3Put4byte + +/* +** get2byteAligned(), unlike get2byte(), requires that its argument point to a +** two-byte aligned address. get2byteAligned() is only used for accessing the +** cell addresses in a btree header. +*/ +#if SQLITE_BYTEORDER==4321 +# define get2byteAligned(x) (*(u16*)(x)) +#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4008000 +# define get2byteAligned(x) __builtin_bswap16(*(u16*)(x)) +#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 +# define get2byteAligned(x) _byteswap_ushort(*(u16*)(x)) +#else +# define get2byteAligned(x) ((x)[0]<<8 | (x)[1]) +#endif + +/************** End of btreeInt.h ********************************************/ +/************** Continuing where we left off in btmutex.c ********************/ +#ifndef SQLITE_OMIT_SHARED_CACHE +#if SQLITE_THREADSAFE + +/* +** Obtain the BtShared mutex associated with B-Tree handle p. Also, +** set BtShared.db to the database handle associated with p and the +** p->locked boolean to true. +*/ +static void lockBtreeMutex(Btree *p){ + assert( p->locked==0 ); + assert( sqlite3_mutex_notheld(p->pBt->mutex) ); + assert( sqlite3_mutex_held(p->db->mutex) ); + + sqlite3_mutex_enter(p->pBt->mutex); + p->pBt->db = p->db; + p->locked = 1; +} + +/* +** Release the BtShared mutex associated with B-Tree handle p and +** clear the p->locked boolean. +*/ +static void SQLITE_NOINLINE unlockBtreeMutex(Btree *p){ + BtShared *pBt = p->pBt; + assert( p->locked==1 ); + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3_mutex_held(p->db->mutex) ); + assert( p->db==pBt->db ); + + sqlite3_mutex_leave(pBt->mutex); + p->locked = 0; +} + +/* Forward reference */ +static void SQLITE_NOINLINE btreeLockCarefully(Btree *p); + +/* +** Enter a mutex on the given BTree object. +** +** If the object is not sharable, then no mutex is ever required +** and this routine is a no-op. The underlying mutex is non-recursive. +** But we keep a reference count in Btree.wantToLock so the behavior +** of this interface is recursive. +** +** To avoid deadlocks, multiple Btrees are locked in the same order +** by all database connections. The p->pNext is a list of other +** Btrees belonging to the same database connection as the p Btree +** which need to be locked after p. If we cannot get a lock on +** p, then first unlock all of the others on p->pNext, then wait +** for the lock to become available on p, then relock all of the +** subsequent Btrees that desire a lock. +*/ +SQLITE_PRIVATE void sqlite3BtreeEnter(Btree *p){ + /* Some basic sanity checking on the Btree. The list of Btrees + ** connected by pNext and pPrev should be in sorted order by + ** Btree.pBt value. All elements of the list should belong to + ** the same connection. Only shared Btrees are on the list. */ + assert( p->pNext==0 || p->pNext->pBt>p->pBt ); + assert( p->pPrev==0 || p->pPrev->pBtpBt ); + assert( p->pNext==0 || p->pNext->db==p->db ); + assert( p->pPrev==0 || p->pPrev->db==p->db ); + assert( p->sharable || (p->pNext==0 && p->pPrev==0) ); + + /* Check for locking consistency */ + assert( !p->locked || p->wantToLock>0 ); + assert( p->sharable || p->wantToLock==0 ); + + /* We should already hold a lock on the database connection */ + assert( sqlite3_mutex_held(p->db->mutex) ); + + /* Unless the database is sharable and unlocked, then BtShared.db + ** should already be set correctly. */ + assert( (p->locked==0 && p->sharable) || p->pBt->db==p->db ); + + if( !p->sharable ) return; + p->wantToLock++; + if( p->locked ) return; + btreeLockCarefully(p); +} + +/* This is a helper function for sqlite3BtreeLock(). By moving +** complex, but seldom used logic, out of sqlite3BtreeLock() and +** into this routine, we avoid unnecessary stack pointer changes +** and thus help the sqlite3BtreeLock() routine to run much faster +** in the common case. +*/ +static void SQLITE_NOINLINE btreeLockCarefully(Btree *p){ + Btree *pLater; + + /* In most cases, we should be able to acquire the lock we + ** want without having to go through the ascending lock + ** procedure that follows. Just be sure not to block. + */ + if( sqlite3_mutex_try(p->pBt->mutex)==SQLITE_OK ){ + p->pBt->db = p->db; + p->locked = 1; + return; + } + + /* To avoid deadlock, first release all locks with a larger + ** BtShared address. Then acquire our lock. Then reacquire + ** the other BtShared locks that we used to hold in ascending + ** order. + */ + for(pLater=p->pNext; pLater; pLater=pLater->pNext){ + assert( pLater->sharable ); + assert( pLater->pNext==0 || pLater->pNext->pBt>pLater->pBt ); + assert( !pLater->locked || pLater->wantToLock>0 ); + if( pLater->locked ){ + unlockBtreeMutex(pLater); + } + } + lockBtreeMutex(p); + for(pLater=p->pNext; pLater; pLater=pLater->pNext){ + if( pLater->wantToLock ){ + lockBtreeMutex(pLater); + } + } +} + + +/* +** Exit the recursive mutex on a Btree. +*/ +SQLITE_PRIVATE void sqlite3BtreeLeave(Btree *p){ + assert( sqlite3_mutex_held(p->db->mutex) ); + if( p->sharable ){ + assert( p->wantToLock>0 ); + p->wantToLock--; + if( p->wantToLock==0 ){ + unlockBtreeMutex(p); + } + } +} + +#ifndef NDEBUG +/* +** Return true if the BtShared mutex is held on the btree, or if the +** B-Tree is not marked as sharable. +** +** This routine is used only from within assert() statements. +*/ +SQLITE_PRIVATE int sqlite3BtreeHoldsMutex(Btree *p){ + assert( p->sharable==0 || p->locked==0 || p->wantToLock>0 ); + assert( p->sharable==0 || p->locked==0 || p->db==p->pBt->db ); + assert( p->sharable==0 || p->locked==0 || sqlite3_mutex_held(p->pBt->mutex) ); + assert( p->sharable==0 || p->locked==0 || sqlite3_mutex_held(p->db->mutex) ); + + return (p->sharable==0 || p->locked); +} +#endif + + +/* +** Enter the mutex on every Btree associated with a database +** connection. This is needed (for example) prior to parsing +** a statement since we will be comparing table and column names +** against all schemas and we do not want those schemas being +** reset out from under us. +** +** There is a corresponding leave-all procedures. +** +** Enter the mutexes in ascending order by BtShared pointer address +** to avoid the possibility of deadlock when two threads with +** two or more btrees in common both try to lock all their btrees +** at the same instant. +*/ +static void SQLITE_NOINLINE btreeEnterAll(sqlite3 *db){ + int i; + u8 skipOk = 1; + Btree *p; + assert( sqlite3_mutex_held(db->mutex) ); + for(i=0; inDb; i++){ + p = db->aDb[i].pBt; + if( p && p->sharable ){ + sqlite3BtreeEnter(p); + skipOk = 0; + } + } + db->noSharedCache = skipOk; +} +SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){ + if( db->noSharedCache==0 ) btreeEnterAll(db); +} +static void SQLITE_NOINLINE btreeLeaveAll(sqlite3 *db){ + int i; + Btree *p; + assert( sqlite3_mutex_held(db->mutex) ); + for(i=0; inDb; i++){ + p = db->aDb[i].pBt; + if( p ) sqlite3BtreeLeave(p); + } +} +SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3 *db){ + if( db->noSharedCache==0 ) btreeLeaveAll(db); +} + +#ifndef NDEBUG +/* +** Return true if the current thread holds the database connection +** mutex and all required BtShared mutexes. +** +** This routine is used inside assert() statements only. +*/ +SQLITE_PRIVATE int sqlite3BtreeHoldsAllMutexes(sqlite3 *db){ + int i; + if( !sqlite3_mutex_held(db->mutex) ){ + return 0; + } + for(i=0; inDb; i++){ + Btree *p; + p = db->aDb[i].pBt; + if( p && p->sharable && + (p->wantToLock==0 || !sqlite3_mutex_held(p->pBt->mutex)) ){ + return 0; + } + } + return 1; +} +#endif /* NDEBUG */ + +#ifndef NDEBUG +/* +** Return true if the correct mutexes are held for accessing the +** db->aDb[iDb].pSchema structure. The mutexes required for schema +** access are: +** +** (1) The mutex on db +** (2) if iDb!=1, then the mutex on db->aDb[iDb].pBt. +** +** If pSchema is not NULL, then iDb is computed from pSchema and +** db using sqlite3SchemaToIndex(). +*/ +SQLITE_PRIVATE int sqlite3SchemaMutexHeld(sqlite3 *db, int iDb, Schema *pSchema){ + Btree *p; + assert( db!=0 ); + if( db->pVfs==0 && db->nDb==0 ) return 1; + if( pSchema ) iDb = sqlite3SchemaToIndex(db, pSchema); + assert( iDb>=0 && iDbnDb ); + if( !sqlite3_mutex_held(db->mutex) ) return 0; + if( iDb==1 ) return 1; + p = db->aDb[iDb].pBt; + assert( p!=0 ); + return p->sharable==0 || p->locked==1; +} +#endif /* NDEBUG */ + +#else /* SQLITE_THREADSAFE>0 above. SQLITE_THREADSAFE==0 below */ +/* +** The following are special cases for mutex enter routines for use +** in single threaded applications that use shared cache. Except for +** these two routines, all mutex operations are no-ops in that case and +** are null #defines in btree.h. +** +** If shared cache is disabled, then all btree mutex routines, including +** the ones below, are no-ops and are null #defines in btree.h. +*/ + +SQLITE_PRIVATE void sqlite3BtreeEnter(Btree *p){ + p->pBt->db = p->db; +} +SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){ + int i; + for(i=0; inDb; i++){ + Btree *p = db->aDb[i].pBt; + if( p ){ + p->pBt->db = p->db; + } + } +} +#endif /* if SQLITE_THREADSAFE */ + +#ifndef SQLITE_OMIT_INCRBLOB +/* +** Enter a mutex on a Btree given a cursor owned by that Btree. +** +** These entry points are used by incremental I/O only. Enter() is required +** any time OMIT_SHARED_CACHE is not defined, regardless of whether or not +** the build is threadsafe. Leave() is only required by threadsafe builds. +*/ +SQLITE_PRIVATE void sqlite3BtreeEnterCursor(BtCursor *pCur){ + sqlite3BtreeEnter(pCur->pBtree); +} +# if SQLITE_THREADSAFE +SQLITE_PRIVATE void sqlite3BtreeLeaveCursor(BtCursor *pCur){ + sqlite3BtreeLeave(pCur->pBtree); +} +# endif +#endif /* ifndef SQLITE_OMIT_INCRBLOB */ + +#endif /* ifndef SQLITE_OMIT_SHARED_CACHE */ + +/************** End of btmutex.c *********************************************/ +/************** Begin file btree.c *******************************************/ +/* +** 2004 April 6 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file implements an external (disk-based) database using BTrees. +** See the header comment on "btreeInt.h" for additional information. +** Including a description of file format and an overview of operation. +*/ +/* #include "btreeInt.h" */ + +/* +** The header string that appears at the beginning of every +** SQLite database. +*/ +static const char zMagicHeader[] = SQLITE_FILE_HEADER; + +/* +** Set this global variable to 1 to enable tracing using the TRACE +** macro. +*/ +#if 0 +int sqlite3BtreeTrace=1; /* True to enable tracing */ +# define TRACE(X) if(sqlite3BtreeTrace){printf X;fflush(stdout);} +#else +# define TRACE(X) +#endif + +/* +** Extract a 2-byte big-endian integer from an array of unsigned bytes. +** But if the value is zero, make it 65536. +** +** This routine is used to extract the "offset to cell content area" value +** from the header of a btree page. If the page size is 65536 and the page +** is empty, the offset should be 65536, but the 2-byte value stores zero. +** This routine makes the necessary adjustment to 65536. +*/ +#define get2byteNotZero(X) (((((int)get2byte(X))-1)&0xffff)+1) + +/* +** Values passed as the 5th argument to allocateBtreePage() +*/ +#define BTALLOC_ANY 0 /* Allocate any page */ +#define BTALLOC_EXACT 1 /* Allocate exact page if possible */ +#define BTALLOC_LE 2 /* Allocate any page <= the parameter */ + +/* +** Macro IfNotOmitAV(x) returns (x) if SQLITE_OMIT_AUTOVACUUM is not +** defined, or 0 if it is. For example: +** +** bIncrVacuum = IfNotOmitAV(pBtShared->incrVacuum); +*/ +#ifndef SQLITE_OMIT_AUTOVACUUM +#define IfNotOmitAV(expr) (expr) +#else +#define IfNotOmitAV(expr) 0 +#endif + +#ifndef SQLITE_OMIT_SHARED_CACHE +/* +** A list of BtShared objects that are eligible for participation +** in shared cache. This variable has file scope during normal builds, +** but the test harness needs to access it so we make it global for +** test builds. +** +** Access to this variable is protected by SQLITE_MUTEX_STATIC_MAIN. +*/ +#ifdef SQLITE_TEST +SQLITE_PRIVATE BtShared *SQLITE_WSD sqlite3SharedCacheList = 0; +#else +static BtShared *SQLITE_WSD sqlite3SharedCacheList = 0; +#endif +#endif /* SQLITE_OMIT_SHARED_CACHE */ + +#ifndef SQLITE_OMIT_SHARED_CACHE +/* +** Enable or disable the shared pager and schema features. +** +** This routine has no effect on existing database connections. +** The shared cache setting effects only future calls to +** sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2(). +*/ +SQLITE_API int sqlite3_enable_shared_cache(int enable){ + sqlite3GlobalConfig.sharedCacheEnabled = enable; + return SQLITE_OK; +} +#endif + + + +#ifdef SQLITE_OMIT_SHARED_CACHE + /* + ** The functions querySharedCacheTableLock(), setSharedCacheTableLock(), + ** and clearAllSharedCacheTableLocks() + ** manipulate entries in the BtShared.pLock linked list used to store + ** shared-cache table level locks. If the library is compiled with the + ** shared-cache feature disabled, then there is only ever one user + ** of each BtShared structure and so this locking is not necessary. + ** So define the lock related functions as no-ops. + */ + #define querySharedCacheTableLock(a,b,c) SQLITE_OK + #define setSharedCacheTableLock(a,b,c) SQLITE_OK + #define clearAllSharedCacheTableLocks(a) + #define downgradeAllSharedCacheTableLocks(a) + #define hasSharedCacheTableLock(a,b,c,d) 1 + #define hasReadConflicts(a, b) 0 +#endif + +#ifdef SQLITE_DEBUG +/* +** Return and reset the seek counter for a Btree object. +*/ +SQLITE_PRIVATE sqlite3_uint64 sqlite3BtreeSeekCount(Btree *pBt){ + u64 n = pBt->nSeek; + pBt->nSeek = 0; + return n; +} +#endif + +/* +** Implementation of the SQLITE_CORRUPT_PAGE() macro. Takes a single +** (MemPage*) as an argument. The (MemPage*) must not be NULL. +** +** If SQLITE_DEBUG is not defined, then this macro is equivalent to +** SQLITE_CORRUPT_BKPT. Or, if SQLITE_DEBUG is set, then the log message +** normally produced as a side-effect of SQLITE_CORRUPT_BKPT is augmented +** with the page number and filename associated with the (MemPage*). +*/ +#ifdef SQLITE_DEBUG +int corruptPageError(int lineno, MemPage *p){ + char *zMsg; + sqlite3BeginBenignMalloc(); + zMsg = sqlite3_mprintf("database corruption page %u of %s", + p->pgno, sqlite3PagerFilename(p->pBt->pPager, 0) + ); + sqlite3EndBenignMalloc(); + if( zMsg ){ + sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg); + } + sqlite3_free(zMsg); + return SQLITE_CORRUPT_BKPT; +} +# define SQLITE_CORRUPT_PAGE(pMemPage) corruptPageError(__LINE__, pMemPage) +#else +# define SQLITE_CORRUPT_PAGE(pMemPage) SQLITE_CORRUPT_PGNO(pMemPage->pgno) +#endif + +/* Default value for SHARED_LOCK_TRACE macro if shared-cache is disabled +** or if the lock tracking is disabled. This is always the value for +** release builds. +*/ +#define SHARED_LOCK_TRACE(X,MSG,TAB,TYPE) /*no-op*/ + +#ifndef SQLITE_OMIT_SHARED_CACHE + +#if 0 +/* ^---- Change to 1 and recompile to enable shared-lock tracing +** for debugging purposes. +** +** Print all shared-cache locks on a BtShared. Debugging use only. +*/ +static void sharedLockTrace( + BtShared *pBt, + const char *zMsg, + int iRoot, + int eLockType +){ + BtLock *pLock; + if( iRoot>0 ){ + printf("%s-%p %u%s:", zMsg, pBt, iRoot, eLockType==READ_LOCK?"R":"W"); + }else{ + printf("%s-%p:", zMsg, pBt); + } + for(pLock=pBt->pLock; pLock; pLock=pLock->pNext){ + printf(" %p/%u%s", pLock->pBtree, pLock->iTable, + pLock->eLock==READ_LOCK ? "R" : "W"); + while( pLock->pNext && pLock->pBtree==pLock->pNext->pBtree ){ + pLock = pLock->pNext; + printf(",%u%s", pLock->iTable, pLock->eLock==READ_LOCK ? "R" : "W"); + } + } + printf("\n"); + fflush(stdout); +} +#undef SHARED_LOCK_TRACE +#define SHARED_LOCK_TRACE(X,MSG,TAB,TYPE) sharedLockTrace(X,MSG,TAB,TYPE) +#endif /* Shared-lock tracing */ + +#ifdef SQLITE_DEBUG +/* +**** This function is only used as part of an assert() statement. *** +** +** Check to see if pBtree holds the required locks to read or write to the +** table with root page iRoot. Return 1 if it does and 0 if not. +** +** For example, when writing to a table with root-page iRoot via +** Btree connection pBtree: +** +** assert( hasSharedCacheTableLock(pBtree, iRoot, 0, WRITE_LOCK) ); +** +** When writing to an index that resides in a sharable database, the +** caller should have first obtained a lock specifying the root page of +** the corresponding table. This makes things a bit more complicated, +** as this module treats each table as a separate structure. To determine +** the table corresponding to the index being written, this +** function has to search through the database schema. +** +** Instead of a lock on the table/index rooted at page iRoot, the caller may +** hold a write-lock on the schema table (root page 1). This is also +** acceptable. +*/ +static int hasSharedCacheTableLock( + Btree *pBtree, /* Handle that must hold lock */ + Pgno iRoot, /* Root page of b-tree */ + int isIndex, /* True if iRoot is the root of an index b-tree */ + int eLockType /* Required lock type (READ_LOCK or WRITE_LOCK) */ +){ + Schema *pSchema = (Schema *)pBtree->pBt->pSchema; + Pgno iTab = 0; + BtLock *pLock; + + /* If this database is not shareable, or if the client is reading + ** and has the read-uncommitted flag set, then no lock is required. + ** Return true immediately. + */ + if( (pBtree->sharable==0) + || (eLockType==READ_LOCK && (pBtree->db->flags & SQLITE_ReadUncommit)) + ){ + return 1; + } + + /* If the client is reading or writing an index and the schema is + ** not loaded, then it is too difficult to actually check to see if + ** the correct locks are held. So do not bother - just return true. + ** This case does not come up very often anyhow. + */ + if( isIndex && (!pSchema || (pSchema->schemaFlags&DB_SchemaLoaded)==0) ){ + return 1; + } + + /* Figure out the root-page that the lock should be held on. For table + ** b-trees, this is just the root page of the b-tree being read or + ** written. For index b-trees, it is the root page of the associated + ** table. */ + if( isIndex ){ + HashElem *p; + int bSeen = 0; + for(p=sqliteHashFirst(&pSchema->idxHash); p; p=sqliteHashNext(p)){ + Index *pIdx = (Index *)sqliteHashData(p); + if( pIdx->tnum==iRoot ){ + if( bSeen ){ + /* Two or more indexes share the same root page. There must + ** be imposter tables. So just return true. The assert is not + ** useful in that case. */ + return 1; + } + iTab = pIdx->pTable->tnum; + bSeen = 1; + } + } + }else{ + iTab = iRoot; + } + + SHARED_LOCK_TRACE(pBtree->pBt,"hasLock",iRoot,eLockType); + + /* Search for the required lock. Either a write-lock on root-page iTab, a + ** write-lock on the schema table, or (if the client is reading) a + ** read-lock on iTab will suffice. Return 1 if any of these are found. */ + for(pLock=pBtree->pBt->pLock; pLock; pLock=pLock->pNext){ + if( pLock->pBtree==pBtree + && (pLock->iTable==iTab || (pLock->eLock==WRITE_LOCK && pLock->iTable==1)) + && pLock->eLock>=eLockType + ){ + return 1; + } + } + + /* Failed to find the required lock. */ + return 0; +} +#endif /* SQLITE_DEBUG */ + +#ifdef SQLITE_DEBUG +/* +**** This function may be used as part of assert() statements only. **** +** +** Return true if it would be illegal for pBtree to write into the +** table or index rooted at iRoot because other shared connections are +** simultaneously reading that same table or index. +** +** It is illegal for pBtree to write if some other Btree object that +** shares the same BtShared object is currently reading or writing +** the iRoot table. Except, if the other Btree object has the +** read-uncommitted flag set, then it is OK for the other object to +** have a read cursor. +** +** For example, before writing to any part of the table or index +** rooted at page iRoot, one should call: +** +** assert( !hasReadConflicts(pBtree, iRoot) ); +*/ +static int hasReadConflicts(Btree *pBtree, Pgno iRoot){ + BtCursor *p; + for(p=pBtree->pBt->pCursor; p; p=p->pNext){ + if( p->pgnoRoot==iRoot + && p->pBtree!=pBtree + && 0==(p->pBtree->db->flags & SQLITE_ReadUncommit) + ){ + return 1; + } + } + return 0; +} +#endif /* #ifdef SQLITE_DEBUG */ + +/* +** Query to see if Btree handle p may obtain a lock of type eLock +** (READ_LOCK or WRITE_LOCK) on the table with root-page iTab. Return +** SQLITE_OK if the lock may be obtained (by calling +** setSharedCacheTableLock()), or SQLITE_LOCKED if not. +*/ +static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){ + BtShared *pBt = p->pBt; + BtLock *pIter; + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( eLock==READ_LOCK || eLock==WRITE_LOCK ); + assert( p->db!=0 ); + assert( !(p->db->flags&SQLITE_ReadUncommit)||eLock==WRITE_LOCK||iTab==1 ); + + /* If requesting a write-lock, then the Btree must have an open write + ** transaction on this file. And, obviously, for this to be so there + ** must be an open write transaction on the file itself. + */ + assert( eLock==READ_LOCK || (p==pBt->pWriter && p->inTrans==TRANS_WRITE) ); + assert( eLock==READ_LOCK || pBt->inTransaction==TRANS_WRITE ); + + /* This routine is a no-op if the shared-cache is not enabled */ + if( !p->sharable ){ + return SQLITE_OK; + } + + /* If some other connection is holding an exclusive lock, the + ** requested lock may not be obtained. + */ + if( pBt->pWriter!=p && (pBt->btsFlags & BTS_EXCLUSIVE)!=0 ){ + sqlite3ConnectionBlocked(p->db, pBt->pWriter->db); + return SQLITE_LOCKED_SHAREDCACHE; + } + + for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){ + /* The condition (pIter->eLock!=eLock) in the following if(...) + ** statement is a simplification of: + ** + ** (eLock==WRITE_LOCK || pIter->eLock==WRITE_LOCK) + ** + ** since we know that if eLock==WRITE_LOCK, then no other connection + ** may hold a WRITE_LOCK on any table in this file (since there can + ** only be a single writer). + */ + assert( pIter->eLock==READ_LOCK || pIter->eLock==WRITE_LOCK ); + assert( eLock==READ_LOCK || pIter->pBtree==p || pIter->eLock==READ_LOCK); + if( pIter->pBtree!=p && pIter->iTable==iTab && pIter->eLock!=eLock ){ + sqlite3ConnectionBlocked(p->db, pIter->pBtree->db); + if( eLock==WRITE_LOCK ){ + assert( p==pBt->pWriter ); + pBt->btsFlags |= BTS_PENDING; + } + return SQLITE_LOCKED_SHAREDCACHE; + } + } + return SQLITE_OK; +} +#endif /* !SQLITE_OMIT_SHARED_CACHE */ + +#ifndef SQLITE_OMIT_SHARED_CACHE +/* +** Add a lock on the table with root-page iTable to the shared-btree used +** by Btree handle p. Parameter eLock must be either READ_LOCK or +** WRITE_LOCK. +** +** This function assumes the following: +** +** (a) The specified Btree object p is connected to a sharable +** database (one with the BtShared.sharable flag set), and +** +** (b) No other Btree objects hold a lock that conflicts +** with the requested lock (i.e. querySharedCacheTableLock() has +** already been called and returned SQLITE_OK). +** +** SQLITE_OK is returned if the lock is added successfully. SQLITE_NOMEM +** is returned if a malloc attempt fails. +*/ +static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){ + BtShared *pBt = p->pBt; + BtLock *pLock = 0; + BtLock *pIter; + + SHARED_LOCK_TRACE(pBt,"setLock", iTable, eLock); + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( eLock==READ_LOCK || eLock==WRITE_LOCK ); + assert( p->db!=0 ); + + /* A connection with the read-uncommitted flag set will never try to + ** obtain a read-lock using this function. The only read-lock obtained + ** by a connection in read-uncommitted mode is on the sqlite_schema + ** table, and that lock is obtained in BtreeBeginTrans(). */ + assert( 0==(p->db->flags&SQLITE_ReadUncommit) || eLock==WRITE_LOCK ); + + /* This function should only be called on a sharable b-tree after it + ** has been determined that no other b-tree holds a conflicting lock. */ + assert( p->sharable ); + assert( SQLITE_OK==querySharedCacheTableLock(p, iTable, eLock) ); + + /* First search the list for an existing lock on this table. */ + for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){ + if( pIter->iTable==iTable && pIter->pBtree==p ){ + pLock = pIter; + break; + } + } + + /* If the above search did not find a BtLock struct associating Btree p + ** with table iTable, allocate one and link it into the list. + */ + if( !pLock ){ + pLock = (BtLock *)sqlite3MallocZero(sizeof(BtLock)); + if( !pLock ){ + return SQLITE_NOMEM_BKPT; + } + pLock->iTable = iTable; + pLock->pBtree = p; + pLock->pNext = pBt->pLock; + pBt->pLock = pLock; + } + + /* Set the BtLock.eLock variable to the maximum of the current lock + ** and the requested lock. This means if a write-lock was already held + ** and a read-lock requested, we don't incorrectly downgrade the lock. + */ + assert( WRITE_LOCK>READ_LOCK ); + if( eLock>pLock->eLock ){ + pLock->eLock = eLock; + } + + return SQLITE_OK; +} +#endif /* !SQLITE_OMIT_SHARED_CACHE */ + +#ifndef SQLITE_OMIT_SHARED_CACHE +/* +** Release all the table locks (locks obtained via calls to +** the setSharedCacheTableLock() procedure) held by Btree object p. +** +** This function assumes that Btree p has an open read or write +** transaction. If it does not, then the BTS_PENDING flag +** may be incorrectly cleared. +*/ +static void clearAllSharedCacheTableLocks(Btree *p){ + BtShared *pBt = p->pBt; + BtLock **ppIter = &pBt->pLock; + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( p->sharable || 0==*ppIter ); + assert( p->inTrans>0 ); + + SHARED_LOCK_TRACE(pBt, "clearAllLocks", 0, 0); + + while( *ppIter ){ + BtLock *pLock = *ppIter; + assert( (pBt->btsFlags & BTS_EXCLUSIVE)==0 || pBt->pWriter==pLock->pBtree ); + assert( pLock->pBtree->inTrans>=pLock->eLock ); + if( pLock->pBtree==p ){ + *ppIter = pLock->pNext; + assert( pLock->iTable!=1 || pLock==&p->lock ); + if( pLock->iTable!=1 ){ + sqlite3_free(pLock); + } + }else{ + ppIter = &pLock->pNext; + } + } + + assert( (pBt->btsFlags & BTS_PENDING)==0 || pBt->pWriter ); + if( pBt->pWriter==p ){ + pBt->pWriter = 0; + pBt->btsFlags &= ~(BTS_EXCLUSIVE|BTS_PENDING); + }else if( pBt->nTransaction==2 ){ + /* This function is called when Btree p is concluding its + ** transaction. If there currently exists a writer, and p is not + ** that writer, then the number of locks held by connections other + ** than the writer must be about to drop to zero. In this case + ** set the BTS_PENDING flag to 0. + ** + ** If there is not currently a writer, then BTS_PENDING must + ** be zero already. So this next line is harmless in that case. + */ + pBt->btsFlags &= ~BTS_PENDING; + } +} + +/* +** This function changes all write-locks held by Btree p into read-locks. +*/ +static void downgradeAllSharedCacheTableLocks(Btree *p){ + BtShared *pBt = p->pBt; + + SHARED_LOCK_TRACE(pBt, "downgradeLocks", 0, 0); + + if( pBt->pWriter==p ){ + BtLock *pLock; + pBt->pWriter = 0; + pBt->btsFlags &= ~(BTS_EXCLUSIVE|BTS_PENDING); + for(pLock=pBt->pLock; pLock; pLock=pLock->pNext){ + assert( pLock->eLock==READ_LOCK || pLock->pBtree==p ); + pLock->eLock = READ_LOCK; + } + } +} + +#endif /* SQLITE_OMIT_SHARED_CACHE */ + +static void releasePage(MemPage *pPage); /* Forward reference */ +static void releasePageOne(MemPage *pPage); /* Forward reference */ +static void releasePageNotNull(MemPage *pPage); /* Forward reference */ + +/* +***** This routine is used inside of assert() only **** +** +** Verify that the cursor holds the mutex on its BtShared +*/ +#ifdef SQLITE_DEBUG +static int cursorHoldsMutex(BtCursor *p){ + return sqlite3_mutex_held(p->pBt->mutex); +} + +/* Verify that the cursor and the BtShared agree about what is the current +** database connetion. This is important in shared-cache mode. If the database +** connection pointers get out-of-sync, it is possible for routines like +** btreeInitPage() to reference an stale connection pointer that references a +** a connection that has already closed. This routine is used inside assert() +** statements only and for the purpose of double-checking that the btree code +** does keep the database connection pointers up-to-date. +*/ +static int cursorOwnsBtShared(BtCursor *p){ + assert( cursorHoldsMutex(p) ); + return (p->pBtree->db==p->pBt->db); +} +#endif + +/* +** Invalidate the overflow cache of the cursor passed as the first argument. +** on the shared btree structure pBt. +*/ +#define invalidateOverflowCache(pCur) (pCur->curFlags &= ~BTCF_ValidOvfl) + +/* +** Invalidate the overflow page-list cache for all cursors opened +** on the shared btree structure pBt. +*/ +static void invalidateAllOverflowCache(BtShared *pBt){ + BtCursor *p; + assert( sqlite3_mutex_held(pBt->mutex) ); + for(p=pBt->pCursor; p; p=p->pNext){ + invalidateOverflowCache(p); + } +} + +#ifndef SQLITE_OMIT_INCRBLOB +/* +** This function is called before modifying the contents of a table +** to invalidate any incrblob cursors that are open on the +** row or one of the rows being modified. +** +** If argument isClearTable is true, then the entire contents of the +** table is about to be deleted. In this case invalidate all incrblob +** cursors open on any row within the table with root-page pgnoRoot. +** +** Otherwise, if argument isClearTable is false, then the row with +** rowid iRow is being replaced or deleted. In this case invalidate +** only those incrblob cursors open on that specific row. +*/ +static void invalidateIncrblobCursors( + Btree *pBtree, /* The database file to check */ + Pgno pgnoRoot, /* The table that might be changing */ + i64 iRow, /* The rowid that might be changing */ + int isClearTable /* True if all rows are being deleted */ +){ + BtCursor *p; + assert( pBtree->hasIncrblobCur ); + assert( sqlite3BtreeHoldsMutex(pBtree) ); + pBtree->hasIncrblobCur = 0; + for(p=pBtree->pBt->pCursor; p; p=p->pNext){ + if( (p->curFlags & BTCF_Incrblob)!=0 ){ + pBtree->hasIncrblobCur = 1; + if( p->pgnoRoot==pgnoRoot && (isClearTable || p->info.nKey==iRow) ){ + p->eState = CURSOR_INVALID; + } + } + } +} + +#else + /* Stub function when INCRBLOB is omitted */ + #define invalidateIncrblobCursors(w,x,y,z) +#endif /* SQLITE_OMIT_INCRBLOB */ + +/* +** Set bit pgno of the BtShared.pHasContent bitvec. This is called +** when a page that previously contained data becomes a free-list leaf +** page. +** +** The BtShared.pHasContent bitvec exists to work around an obscure +** bug caused by the interaction of two useful IO optimizations surrounding +** free-list leaf pages: +** +** 1) When all data is deleted from a page and the page becomes +** a free-list leaf page, the page is not written to the database +** (as free-list leaf pages contain no meaningful data). Sometimes +** such a page is not even journalled (as it will not be modified, +** why bother journalling it?). +** +** 2) When a free-list leaf page is reused, its content is not read +** from the database or written to the journal file (why should it +** be, if it is not at all meaningful?). +** +** By themselves, these optimizations work fine and provide a handy +** performance boost to bulk delete or insert operations. However, if +** a page is moved to the free-list and then reused within the same +** transaction, a problem comes up. If the page is not journalled when +** it is moved to the free-list and it is also not journalled when it +** is extracted from the free-list and reused, then the original data +** may be lost. In the event of a rollback, it may not be possible +** to restore the database to its original configuration. +** +** The solution is the BtShared.pHasContent bitvec. Whenever a page is +** moved to become a free-list leaf page, the corresponding bit is +** set in the bitvec. Whenever a leaf page is extracted from the free-list, +** optimization 2 above is omitted if the corresponding bit is already +** set in BtShared.pHasContent. The contents of the bitvec are cleared +** at the end of every transaction. +*/ +static int btreeSetHasContent(BtShared *pBt, Pgno pgno){ + int rc = SQLITE_OK; + if( !pBt->pHasContent ){ + assert( pgno<=pBt->nPage ); + pBt->pHasContent = sqlite3BitvecCreate(pBt->nPage); + if( !pBt->pHasContent ){ + rc = SQLITE_NOMEM_BKPT; + } + } + if( rc==SQLITE_OK && pgno<=sqlite3BitvecSize(pBt->pHasContent) ){ + rc = sqlite3BitvecSet(pBt->pHasContent, pgno); + } + return rc; +} + +/* +** Query the BtShared.pHasContent vector. +** +** This function is called when a free-list leaf page is removed from the +** free-list for reuse. It returns false if it is safe to retrieve the +** page from the pager layer with the 'no-content' flag set. True otherwise. +*/ +static int btreeGetHasContent(BtShared *pBt, Pgno pgno){ + Bitvec *p = pBt->pHasContent; + return p && (pgno>sqlite3BitvecSize(p) || sqlite3BitvecTestNotNull(p, pgno)); +} + +/* +** Clear (destroy) the BtShared.pHasContent bitvec. This should be +** invoked at the conclusion of each write-transaction. +*/ +static void btreeClearHasContent(BtShared *pBt){ + sqlite3BitvecDestroy(pBt->pHasContent); + pBt->pHasContent = 0; +} + +/* +** Release all of the apPage[] pages for a cursor. +*/ +static void btreeReleaseAllCursorPages(BtCursor *pCur){ + int i; + if( pCur->iPage>=0 ){ + for(i=0; iiPage; i++){ + releasePageNotNull(pCur->apPage[i]); + } + releasePageNotNull(pCur->pPage); + pCur->iPage = -1; + } +} + +/* +** The cursor passed as the only argument must point to a valid entry +** when this function is called (i.e. have eState==CURSOR_VALID). This +** function saves the current cursor key in variables pCur->nKey and +** pCur->pKey. SQLITE_OK is returned if successful or an SQLite error +** code otherwise. +** +** If the cursor is open on an intkey table, then the integer key +** (the rowid) is stored in pCur->nKey and pCur->pKey is left set to +** NULL. If the cursor is open on a non-intkey table, then pCur->pKey is +** set to point to a malloced buffer pCur->nKey bytes in size containing +** the key. +*/ +static int saveCursorKey(BtCursor *pCur){ + int rc = SQLITE_OK; + assert( CURSOR_VALID==pCur->eState ); + assert( 0==pCur->pKey ); + assert( cursorHoldsMutex(pCur) ); + + if( pCur->curIntKey ){ + /* Only the rowid is required for a table btree */ + pCur->nKey = sqlite3BtreeIntegerKey(pCur); + }else{ + /* For an index btree, save the complete key content. It is possible + ** that the current key is corrupt. In that case, it is possible that + ** the sqlite3VdbeRecordUnpack() function may overread the buffer by + ** up to the size of 1 varint plus 1 8-byte value when the cursor + ** position is restored. Hence the 17 bytes of padding allocated + ** below. */ + void *pKey; + pCur->nKey = sqlite3BtreePayloadSize(pCur); + pKey = sqlite3Malloc( ((i64)pCur->nKey) + 9 + 8 ); + if( pKey ){ + rc = sqlite3BtreePayload(pCur, 0, (int)pCur->nKey, pKey); + if( rc==SQLITE_OK ){ + memset(((u8*)pKey)+pCur->nKey, 0, 9+8); + pCur->pKey = pKey; + }else{ + sqlite3_free(pKey); + } + }else{ + rc = SQLITE_NOMEM_BKPT; + } + } + assert( !pCur->curIntKey || !pCur->pKey ); + return rc; +} + +/* +** Save the current cursor position in the variables BtCursor.nKey +** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK. +** +** The caller must ensure that the cursor is valid (has eState==CURSOR_VALID) +** prior to calling this routine. +*/ +static int saveCursorPosition(BtCursor *pCur){ + int rc; + + assert( CURSOR_VALID==pCur->eState || CURSOR_SKIPNEXT==pCur->eState ); + assert( 0==pCur->pKey ); + assert( cursorHoldsMutex(pCur) ); + + if( pCur->curFlags & BTCF_Pinned ){ + return SQLITE_CONSTRAINT_PINNED; + } + if( pCur->eState==CURSOR_SKIPNEXT ){ + pCur->eState = CURSOR_VALID; + }else{ + pCur->skipNext = 0; + } + + rc = saveCursorKey(pCur); + if( rc==SQLITE_OK ){ + btreeReleaseAllCursorPages(pCur); + pCur->eState = CURSOR_REQUIRESEEK; + } + + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl|BTCF_AtLast); + return rc; +} + +/* Forward reference */ +static int SQLITE_NOINLINE saveCursorsOnList(BtCursor*,Pgno,BtCursor*); + +/* +** Save the positions of all cursors (except pExcept) that are open on +** the table with root-page iRoot. "Saving the cursor position" means that +** the location in the btree is remembered in such a way that it can be +** moved back to the same spot after the btree has been modified. This +** routine is called just before cursor pExcept is used to modify the +** table, for example in BtreeDelete() or BtreeInsert(). +** +** If there are two or more cursors on the same btree, then all such +** cursors should have their BTCF_Multiple flag set. The btreeCursor() +** routine enforces that rule. This routine only needs to be called in +** the uncommon case when pExpect has the BTCF_Multiple flag set. +** +** If pExpect!=NULL and if no other cursors are found on the same root-page, +** then the BTCF_Multiple flag on pExpect is cleared, to avoid another +** pointless call to this routine. +** +** Implementation note: This routine merely checks to see if any cursors +** need to be saved. It calls out to saveCursorsOnList() in the (unusual) +** event that cursors are in need to being saved. +*/ +static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){ + BtCursor *p; + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( pExcept==0 || pExcept->pBt==pBt ); + for(p=pBt->pCursor; p; p=p->pNext){ + if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ) break; + } + if( p ) return saveCursorsOnList(p, iRoot, pExcept); + if( pExcept ) pExcept->curFlags &= ~BTCF_Multiple; + return SQLITE_OK; +} + +/* This helper routine to saveAllCursors does the actual work of saving +** the cursors if and when a cursor is found that actually requires saving. +** The common case is that no cursors need to be saved, so this routine is +** broken out from its caller to avoid unnecessary stack pointer movement. +*/ +static int SQLITE_NOINLINE saveCursorsOnList( + BtCursor *p, /* The first cursor that needs saving */ + Pgno iRoot, /* Only save cursor with this iRoot. Save all if zero */ + BtCursor *pExcept /* Do not save this cursor */ +){ + do{ + if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ){ + if( p->eState==CURSOR_VALID || p->eState==CURSOR_SKIPNEXT ){ + int rc = saveCursorPosition(p); + if( SQLITE_OK!=rc ){ + return rc; + } + }else{ + testcase( p->iPage>=0 ); + btreeReleaseAllCursorPages(p); + } + } + p = p->pNext; + }while( p ); + return SQLITE_OK; +} + +/* +** Clear the current cursor position. +*/ +SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *pCur){ + assert( cursorHoldsMutex(pCur) ); + sqlite3_free(pCur->pKey); + pCur->pKey = 0; + pCur->eState = CURSOR_INVALID; +} + +/* +** In this version of BtreeMoveto, pKey is a packed index record +** such as is generated by the OP_MakeRecord opcode. Unpack the +** record and then call sqlite3BtreeIndexMoveto() to do the work. +*/ +static int btreeMoveto( + BtCursor *pCur, /* Cursor open on the btree to be searched */ + const void *pKey, /* Packed key if the btree is an index */ + i64 nKey, /* Integer key for tables. Size of pKey for indices */ + int bias, /* Bias search to the high end */ + int *pRes /* Write search results here */ +){ + int rc; /* Status code */ + UnpackedRecord *pIdxKey; /* Unpacked index key */ + + if( pKey ){ + KeyInfo *pKeyInfo = pCur->pKeyInfo; + assert( nKey==(i64)(int)nKey ); + pIdxKey = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); + if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT; + sqlite3VdbeRecordUnpack((int)nKey, pKey, pIdxKey); + if( pIdxKey->nField==0 || pIdxKey->nField>pKeyInfo->nAllField ){ + rc = SQLITE_CORRUPT_BKPT; + }else{ + rc = sqlite3BtreeIndexMoveto(pCur, pIdxKey, pRes); + } + sqlite3DbFree(pCur->pKeyInfo->db, pIdxKey); + }else{ + pIdxKey = 0; + rc = sqlite3BtreeTableMoveto(pCur, nKey, bias, pRes); + } + return rc; +} + +/* +** Restore the cursor to the position it was in (or as close to as possible) +** when saveCursorPosition() was called. Note that this call deletes the +** saved position info stored by saveCursorPosition(), so there can be +** at most one effective restoreCursorPosition() call after each +** saveCursorPosition(). +*/ +static int btreeRestoreCursorPosition(BtCursor *pCur){ + int rc; + int skipNext = 0; + assert( cursorOwnsBtShared(pCur) ); + assert( pCur->eState>=CURSOR_REQUIRESEEK ); + if( pCur->eState==CURSOR_FAULT ){ + return pCur->skipNext; + } + pCur->eState = CURSOR_INVALID; + if( sqlite3FaultSim(410) ){ + rc = SQLITE_IOERR; + }else{ + rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &skipNext); + } + if( rc==SQLITE_OK ){ + sqlite3_free(pCur->pKey); + pCur->pKey = 0; + assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID ); + if( skipNext ) pCur->skipNext = skipNext; + if( pCur->skipNext && pCur->eState==CURSOR_VALID ){ + pCur->eState = CURSOR_SKIPNEXT; + } + } + return rc; +} + +#define restoreCursorPosition(p) \ + (p->eState>=CURSOR_REQUIRESEEK ? \ + btreeRestoreCursorPosition(p) : \ + SQLITE_OK) + +/* +** Determine whether or not a cursor has moved from the position where +** it was last placed, or has been invalidated for any other reason. +** Cursors can move when the row they are pointing at is deleted out +** from under them, for example. Cursor might also move if a btree +** is rebalanced. +** +** Calling this routine with a NULL cursor pointer returns false. +** +** Use the separate sqlite3BtreeCursorRestore() routine to restore a cursor +** back to where it ought to be if this routine returns true. +*/ +SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur){ + assert( EIGHT_BYTE_ALIGNMENT(pCur) + || pCur==sqlite3BtreeFakeValidCursor() ); + assert( offsetof(BtCursor, eState)==0 ); + assert( sizeof(pCur->eState)==1 ); + return CURSOR_VALID != *(u8*)pCur; +} + +/* +** Return a pointer to a fake BtCursor object that will always answer +** false to the sqlite3BtreeCursorHasMoved() routine above. The fake +** cursor returned must not be used with any other Btree interface. +*/ +SQLITE_PRIVATE BtCursor *sqlite3BtreeFakeValidCursor(void){ + static u8 fakeCursor = CURSOR_VALID; + assert( offsetof(BtCursor, eState)==0 ); + return (BtCursor*)&fakeCursor; +} + +/* +** This routine restores a cursor back to its original position after it +** has been moved by some outside activity (such as a btree rebalance or +** a row having been deleted out from under the cursor). +** +** On success, the *pDifferentRow parameter is false if the cursor is left +** pointing at exactly the same row. *pDifferntRow is the row the cursor +** was pointing to has been deleted, forcing the cursor to point to some +** nearby row. +** +** This routine should only be called for a cursor that just returned +** TRUE from sqlite3BtreeCursorHasMoved(). +*/ +SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow){ + int rc; + + assert( pCur!=0 ); + assert( pCur->eState!=CURSOR_VALID ); + rc = restoreCursorPosition(pCur); + if( rc ){ + *pDifferentRow = 1; + return rc; + } + if( pCur->eState!=CURSOR_VALID ){ + *pDifferentRow = 1; + }else{ + *pDifferentRow = 0; + } + return SQLITE_OK; +} + +#ifdef SQLITE_ENABLE_CURSOR_HINTS +/* +** Provide hints to the cursor. The particular hint given (and the type +** and number of the varargs parameters) is determined by the eHintType +** parameter. See the definitions of the BTREE_HINT_* macros for details. +*/ +SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor *pCur, int eHintType, ...){ + /* Used only by system that substitute their own storage engine */ +#ifdef SQLITE_DEBUG + if( ALWAYS(eHintType==BTREE_HINT_RANGE) ){ + va_list ap; + Expr *pExpr; + Walker w; + memset(&w, 0, sizeof(w)); + w.xExprCallback = sqlite3CursorRangeHintExprCheck; + va_start(ap, eHintType); + pExpr = va_arg(ap, Expr*); + w.u.aMem = va_arg(ap, Mem*); + va_end(ap); + assert( pExpr!=0 ); + assert( w.u.aMem!=0 ); + sqlite3WalkExpr(&w, pExpr); + } +#endif /* SQLITE_DEBUG */ +} +#endif /* SQLITE_ENABLE_CURSOR_HINTS */ + + +/* +** Provide flag hints to the cursor. +*/ +SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor *pCur, unsigned x){ + assert( x==BTREE_SEEK_EQ || x==BTREE_BULKLOAD || x==0 ); + pCur->hints = (u8)x; +} + + +#ifndef SQLITE_OMIT_AUTOVACUUM +/* +** Given a page number of a regular database page, return the page +** number for the pointer-map page that contains the entry for the +** input page number. +** +** Return 0 (not a valid page) for pgno==1 since there is +** no pointer map associated with page 1. The integrity_check logic +** requires that ptrmapPageno(*,1)!=1. +*/ +static Pgno ptrmapPageno(BtShared *pBt, Pgno pgno){ + int nPagesPerMapPage; + Pgno iPtrMap, ret; + assert( sqlite3_mutex_held(pBt->mutex) ); + if( pgno<2 ) return 0; + nPagesPerMapPage = (pBt->usableSize/5)+1; + iPtrMap = (pgno-2)/nPagesPerMapPage; + ret = (iPtrMap*nPagesPerMapPage) + 2; + if( ret==PENDING_BYTE_PAGE(pBt) ){ + ret++; + } + return ret; +} + +/* +** Write an entry into the pointer map. +** +** This routine updates the pointer map entry for page number 'key' +** so that it maps to type 'eType' and parent page number 'pgno'. +** +** If *pRC is initially non-zero (non-SQLITE_OK) then this routine is +** a no-op. If an error occurs, the appropriate error code is written +** into *pRC. +*/ +static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){ + DbPage *pDbPage; /* The pointer map page */ + u8 *pPtrmap; /* The pointer map data */ + Pgno iPtrmap; /* The pointer map page number */ + int offset; /* Offset in pointer map page */ + int rc; /* Return code from subfunctions */ + + if( *pRC ) return; + + assert( sqlite3_mutex_held(pBt->mutex) ); + /* The super-journal page number must never be used as a pointer map page */ + assert( 0==PTRMAP_ISPAGE(pBt, PENDING_BYTE_PAGE(pBt)) ); + + assert( pBt->autoVacuum ); + if( key==0 ){ + *pRC = SQLITE_CORRUPT_BKPT; + return; + } + iPtrmap = PTRMAP_PAGENO(pBt, key); + rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage, 0); + if( rc!=SQLITE_OK ){ + *pRC = rc; + return; + } + if( ((char*)sqlite3PagerGetExtra(pDbPage))[0]!=0 ){ + /* The first byte of the extra data is the MemPage.isInit byte. + ** If that byte is set, it means this page is also being used + ** as a btree page. */ + *pRC = SQLITE_CORRUPT_BKPT; + goto ptrmap_exit; + } + offset = PTRMAP_PTROFFSET(iPtrmap, key); + if( offset<0 ){ + *pRC = SQLITE_CORRUPT_BKPT; + goto ptrmap_exit; + } + assert( offset <= (int)pBt->usableSize-5 ); + pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage); + + if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){ + TRACE(("PTRMAP_UPDATE: %u->(%u,%u)\n", key, eType, parent)); + *pRC= rc = sqlite3PagerWrite(pDbPage); + if( rc==SQLITE_OK ){ + pPtrmap[offset] = eType; + put4byte(&pPtrmap[offset+1], parent); + } + } + +ptrmap_exit: + sqlite3PagerUnref(pDbPage); +} + +/* +** Read an entry from the pointer map. +** +** This routine retrieves the pointer map entry for page 'key', writing +** the type and parent page number to *pEType and *pPgno respectively. +** An error code is returned if something goes wrong, otherwise SQLITE_OK. +*/ +static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){ + DbPage *pDbPage; /* The pointer map page */ + int iPtrmap; /* Pointer map page index */ + u8 *pPtrmap; /* Pointer map page data */ + int offset; /* Offset of entry in pointer map */ + int rc; + + assert( sqlite3_mutex_held(pBt->mutex) ); + + iPtrmap = PTRMAP_PAGENO(pBt, key); + rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage, 0); + if( rc!=0 ){ + return rc; + } + pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage); + + offset = PTRMAP_PTROFFSET(iPtrmap, key); + if( offset<0 ){ + sqlite3PagerUnref(pDbPage); + return SQLITE_CORRUPT_BKPT; + } + assert( offset <= (int)pBt->usableSize-5 ); + assert( pEType!=0 ); + *pEType = pPtrmap[offset]; + if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]); + + sqlite3PagerUnref(pDbPage); + if( *pEType<1 || *pEType>5 ) return SQLITE_CORRUPT_PGNO(iPtrmap); + return SQLITE_OK; +} + +#else /* if defined SQLITE_OMIT_AUTOVACUUM */ + #define ptrmapPut(w,x,y,z,rc) + #define ptrmapGet(w,x,y,z) SQLITE_OK + #define ptrmapPutOvflPtr(x, y, z, rc) +#endif + +/* +** Given a btree page and a cell index (0 means the first cell on +** the page, 1 means the second cell, and so forth) return a pointer +** to the cell content. +** +** findCellPastPtr() does the same except it skips past the initial +** 4-byte child pointer found on interior pages, if there is one. +** +** This routine works only for pages that do not contain overflow cells. +*/ +#define findCell(P,I) \ + ((P)->aData + ((P)->maskPage & get2byteAligned(&(P)->aCellIdx[2*(I)]))) +#define findCellPastPtr(P,I) \ + ((P)->aDataOfst + ((P)->maskPage & get2byteAligned(&(P)->aCellIdx[2*(I)]))) + + +/* +** This is common tail processing for btreeParseCellPtr() and +** btreeParseCellPtrIndex() for the case when the cell does not fit entirely +** on a single B-tree page. Make necessary adjustments to the CellInfo +** structure. +*/ +static SQLITE_NOINLINE void btreeParseCellAdjustSizeForOverflow( + MemPage *pPage, /* Page containing the cell */ + u8 *pCell, /* Pointer to the cell text. */ + CellInfo *pInfo /* Fill in this structure */ +){ + /* If the payload will not fit completely on the local page, we have + ** to decide how much to store locally and how much to spill onto + ** overflow pages. The strategy is to minimize the amount of unused + ** space on overflow pages while keeping the amount of local storage + ** in between minLocal and maxLocal. + ** + ** Warning: changing the way overflow payload is distributed in any + ** way will result in an incompatible file format. + */ + int minLocal; /* Minimum amount of payload held locally */ + int maxLocal; /* Maximum amount of payload held locally */ + int surplus; /* Overflow payload available for local storage */ + + minLocal = pPage->minLocal; + maxLocal = pPage->maxLocal; + surplus = minLocal + (pInfo->nPayload - minLocal)%(pPage->pBt->usableSize-4); + testcase( surplus==maxLocal ); + testcase( surplus==maxLocal+1 ); + if( surplus <= maxLocal ){ + pInfo->nLocal = (u16)surplus; + }else{ + pInfo->nLocal = (u16)minLocal; + } + pInfo->nSize = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell) + 4; +} + +/* +** Given a record with nPayload bytes of payload stored within btree +** page pPage, return the number of bytes of payload stored locally. +*/ +static int btreePayloadToLocal(MemPage *pPage, i64 nPayload){ + int maxLocal; /* Maximum amount of payload held locally */ + maxLocal = pPage->maxLocal; + assert( nPayload>=0 ); + if( nPayload<=maxLocal ){ + return (int)nPayload; + }else{ + int minLocal; /* Minimum amount of payload held locally */ + int surplus; /* Overflow payload available for local storage */ + minLocal = pPage->minLocal; + surplus = (int)(minLocal +(nPayload - minLocal)%(pPage->pBt->usableSize-4)); + return (surplus <= maxLocal) ? surplus : minLocal; + } +} + +/* +** The following routines are implementations of the MemPage.xParseCell() +** method. +** +** Parse a cell content block and fill in the CellInfo structure. +** +** btreeParseCellPtr() => table btree leaf nodes +** btreeParseCellNoPayload() => table btree internal nodes +** btreeParseCellPtrIndex() => index btree nodes +** +** There is also a wrapper function btreeParseCell() that works for +** all MemPage types and that references the cell by index rather than +** by pointer. +*/ +static void btreeParseCellPtrNoPayload( + MemPage *pPage, /* Page containing the cell */ + u8 *pCell, /* Pointer to the cell text. */ + CellInfo *pInfo /* Fill in this structure */ +){ + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( pPage->leaf==0 ); + assert( pPage->childPtrSize==4 ); +#ifndef SQLITE_DEBUG + UNUSED_PARAMETER(pPage); +#endif + pInfo->nSize = 4 + getVarint(&pCell[4], (u64*)&pInfo->nKey); + pInfo->nPayload = 0; + pInfo->nLocal = 0; + pInfo->pPayload = 0; + return; +} +static void btreeParseCellPtr( + MemPage *pPage, /* Page containing the cell */ + u8 *pCell, /* Pointer to the cell text. */ + CellInfo *pInfo /* Fill in this structure */ +){ + u8 *pIter; /* For scanning through pCell */ + u64 nPayload; /* Number of bytes of cell payload */ + u64 iKey; /* Extracted Key value */ + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( pPage->leaf==0 || pPage->leaf==1 ); + assert( pPage->intKeyLeaf ); + assert( pPage->childPtrSize==0 ); + pIter = pCell; + + /* The next block of code is equivalent to: + ** + ** pIter += getVarint32(pIter, nPayload); + ** + ** The code is inlined to avoid a function call. + */ + nPayload = *pIter; + if( nPayload>=0x80 ){ + u8 *pEnd = &pIter[8]; + nPayload &= 0x7f; + do{ + nPayload = (nPayload<<7) | (*++pIter & 0x7f); + }while( (*pIter)>=0x80 && pIternKey); + ** + ** The code is inlined and the loop is unrolled for performance. + ** This routine is a high-runner. + */ + iKey = *pIter; + if( iKey>=0x80 ){ + u8 x; + iKey = (iKey<<7) ^ (x = *++pIter); + if( x>=0x80 ){ + iKey = (iKey<<7) ^ (x = *++pIter); + if( x>=0x80 ){ + iKey = (iKey<<7) ^ 0x10204000 ^ (x = *++pIter); + if( x>=0x80 ){ + iKey = (iKey<<7) ^ 0x4000 ^ (x = *++pIter); + if( x>=0x80 ){ + iKey = (iKey<<7) ^ 0x4000 ^ (x = *++pIter); + if( x>=0x80 ){ + iKey = (iKey<<7) ^ 0x4000 ^ (x = *++pIter); + if( x>=0x80 ){ + iKey = (iKey<<7) ^ 0x4000 ^ (x = *++pIter); + if( x>=0x80 ){ + iKey = (iKey<<8) ^ 0x8000 ^ (*++pIter); + } + } + } + } + } + }else{ + iKey ^= 0x204000; + } + }else{ + iKey ^= 0x4000; + } + } + pIter++; + + pInfo->nKey = *(i64*)&iKey; + pInfo->nPayload = (u32)nPayload; + pInfo->pPayload = pIter; + testcase( nPayload==pPage->maxLocal ); + testcase( nPayload==(u32)pPage->maxLocal+1 ); + assert( pPage->maxLocal <= BT_MAX_LOCAL ); + if( nPayload<=pPage->maxLocal ){ + /* This is the (easy) common case where the entire payload fits + ** on the local page. No overflow is required. + */ + pInfo->nSize = (u16)nPayload + (u16)(pIter - pCell); + if( pInfo->nSize<4 ) pInfo->nSize = 4; + pInfo->nLocal = (u16)nPayload; + }else{ + btreeParseCellAdjustSizeForOverflow(pPage, pCell, pInfo); + } +} +static void btreeParseCellPtrIndex( + MemPage *pPage, /* Page containing the cell */ + u8 *pCell, /* Pointer to the cell text. */ + CellInfo *pInfo /* Fill in this structure */ +){ + u8 *pIter; /* For scanning through pCell */ + u32 nPayload; /* Number of bytes of cell payload */ + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( pPage->leaf==0 || pPage->leaf==1 ); + assert( pPage->intKeyLeaf==0 ); + pIter = pCell + pPage->childPtrSize; + nPayload = *pIter; + if( nPayload>=0x80 ){ + u8 *pEnd = &pIter[8]; + nPayload &= 0x7f; + do{ + nPayload = (nPayload<<7) | (*++pIter & 0x7f); + }while( *(pIter)>=0x80 && pIternKey = nPayload; + pInfo->nPayload = nPayload; + pInfo->pPayload = pIter; + testcase( nPayload==pPage->maxLocal ); + testcase( nPayload==(u32)pPage->maxLocal+1 ); + assert( nPayload>=0 ); + assert( pPage->maxLocal <= BT_MAX_LOCAL ); + if( nPayload<=pPage->maxLocal ){ + /* This is the (easy) common case where the entire payload fits + ** on the local page. No overflow is required. + */ + pInfo->nSize = (u16)nPayload + (u16)(pIter - pCell); + if( pInfo->nSize<4 ) pInfo->nSize = 4; + pInfo->nLocal = (u16)nPayload; + }else{ + btreeParseCellAdjustSizeForOverflow(pPage, pCell, pInfo); + } +} +static void btreeParseCell( + MemPage *pPage, /* Page containing the cell */ + int iCell, /* The cell index. First cell is 0 */ + CellInfo *pInfo /* Fill in this structure */ +){ + pPage->xParseCell(pPage, findCell(pPage, iCell), pInfo); +} + +/* +** The following routines are implementations of the MemPage.xCellSize +** method. +** +** Compute the total number of bytes that a Cell needs in the cell +** data area of the btree-page. The return number includes the cell +** data header and the local payload, but not any overflow page or +** the space used by the cell pointer. +** +** cellSizePtrNoPayload() => table internal nodes +** cellSizePtrTableLeaf() => table leaf nodes +** cellSizePtr() => index internal nodes +** cellSizeIdxLeaf() => index leaf nodes +*/ +static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ + u8 *pIter = pCell + 4; /* For looping over bytes of pCell */ + u8 *pEnd; /* End mark for a varint */ + u32 nSize; /* Size value to return */ + +#ifdef SQLITE_DEBUG + /* The value returned by this function should always be the same as + ** the (CellInfo.nSize) value found by doing a full parse of the + ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of + ** this function verifies that this invariant is not violated. */ + CellInfo debuginfo; + pPage->xParseCell(pPage, pCell, &debuginfo); +#endif + + assert( pPage->childPtrSize==4 ); + nSize = *pIter; + if( nSize>=0x80 ){ + pEnd = &pIter[8]; + nSize &= 0x7f; + do{ + nSize = (nSize<<7) | (*++pIter & 0x7f); + }while( *(pIter)>=0x80 && pItermaxLocal ); + testcase( nSize==(u32)pPage->maxLocal+1 ); + if( nSize<=pPage->maxLocal ){ + nSize += (u32)(pIter - pCell); + assert( nSize>4 ); + }else{ + int minLocal = pPage->minLocal; + nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4); + testcase( nSize==pPage->maxLocal ); + testcase( nSize==(u32)pPage->maxLocal+1 ); + if( nSize>pPage->maxLocal ){ + nSize = minLocal; + } + nSize += 4 + (u16)(pIter - pCell); + } + assert( nSize==debuginfo.nSize || CORRUPT_DB ); + return (u16)nSize; +} +static u16 cellSizePtrIdxLeaf(MemPage *pPage, u8 *pCell){ + u8 *pIter = pCell; /* For looping over bytes of pCell */ + u8 *pEnd; /* End mark for a varint */ + u32 nSize; /* Size value to return */ + +#ifdef SQLITE_DEBUG + /* The value returned by this function should always be the same as + ** the (CellInfo.nSize) value found by doing a full parse of the + ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of + ** this function verifies that this invariant is not violated. */ + CellInfo debuginfo; + pPage->xParseCell(pPage, pCell, &debuginfo); +#endif + + assert( pPage->childPtrSize==0 ); + nSize = *pIter; + if( nSize>=0x80 ){ + pEnd = &pIter[8]; + nSize &= 0x7f; + do{ + nSize = (nSize<<7) | (*++pIter & 0x7f); + }while( *(pIter)>=0x80 && pItermaxLocal ); + testcase( nSize==(u32)pPage->maxLocal+1 ); + if( nSize<=pPage->maxLocal ){ + nSize += (u32)(pIter - pCell); + if( nSize<4 ) nSize = 4; + }else{ + int minLocal = pPage->minLocal; + nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4); + testcase( nSize==pPage->maxLocal ); + testcase( nSize==(u32)pPage->maxLocal+1 ); + if( nSize>pPage->maxLocal ){ + nSize = minLocal; + } + nSize += 4 + (u16)(pIter - pCell); + } + assert( nSize==debuginfo.nSize || CORRUPT_DB ); + return (u16)nSize; +} +static u16 cellSizePtrNoPayload(MemPage *pPage, u8 *pCell){ + u8 *pIter = pCell + 4; /* For looping over bytes of pCell */ + u8 *pEnd; /* End mark for a varint */ + +#ifdef SQLITE_DEBUG + /* The value returned by this function should always be the same as + ** the (CellInfo.nSize) value found by doing a full parse of the + ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of + ** this function verifies that this invariant is not violated. */ + CellInfo debuginfo; + pPage->xParseCell(pPage, pCell, &debuginfo); +#else + UNUSED_PARAMETER(pPage); +#endif + + assert( pPage->childPtrSize==4 ); + pEnd = pIter + 9; + while( (*pIter++)&0x80 && pIterxParseCell(pPage, pCell, &debuginfo); +#endif + + nSize = *pIter; + if( nSize>=0x80 ){ + pEnd = &pIter[8]; + nSize &= 0x7f; + do{ + nSize = (nSize<<7) | (*++pIter & 0x7f); + }while( *(pIter)>=0x80 && pItermaxLocal ); + testcase( nSize==(u32)pPage->maxLocal+1 ); + if( nSize<=pPage->maxLocal ){ + nSize += (u32)(pIter - pCell); + if( nSize<4 ) nSize = 4; + }else{ + int minLocal = pPage->minLocal; + nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4); + testcase( nSize==pPage->maxLocal ); + testcase( nSize==(u32)pPage->maxLocal+1 ); + if( nSize>pPage->maxLocal ){ + nSize = minLocal; + } + nSize += 4 + (u16)(pIter - pCell); + } + assert( nSize==debuginfo.nSize || CORRUPT_DB ); + return (u16)nSize; +} + + +#ifdef SQLITE_DEBUG +/* This variation on cellSizePtr() is used inside of assert() statements +** only. */ +static u16 cellSize(MemPage *pPage, int iCell){ + return pPage->xCellSize(pPage, findCell(pPage, iCell)); +} +#endif + +#ifndef SQLITE_OMIT_AUTOVACUUM +/* +** The cell pCell is currently part of page pSrc but will ultimately be part +** of pPage. (pSrc and pPage are often the same.) If pCell contains a +** pointer to an overflow page, insert an entry into the pointer-map for +** the overflow page that will be valid after pCell has been moved to pPage. +*/ +static void ptrmapPutOvflPtr(MemPage *pPage, MemPage *pSrc, u8 *pCell,int *pRC){ + CellInfo info; + if( *pRC ) return; + assert( pCell!=0 ); + pPage->xParseCell(pPage, pCell, &info); + if( info.nLocalaDataEnd, pCell, pCell+info.nLocal) ){ + testcase( pSrc!=pPage ); + *pRC = SQLITE_CORRUPT_BKPT; + return; + } + ovfl = get4byte(&pCell[info.nSize-4]); + ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC); + } +} +#endif + + +/* +** Defragment the page given. This routine reorganizes cells within the +** page so that there are no free-blocks on the free-block list. +** +** Parameter nMaxFrag is the maximum amount of fragmented space that may be +** present in the page after this routine returns. +** +** EVIDENCE-OF: R-44582-60138 SQLite may from time to time reorganize a +** b-tree page so that there are no freeblocks or fragment bytes, all +** unused bytes are contained in the unallocated space region, and all +** cells are packed tightly at the end of the page. +*/ +static int defragmentPage(MemPage *pPage, int nMaxFrag){ + int i; /* Loop counter */ + int pc; /* Address of the i-th cell */ + int hdr; /* Offset to the page header */ + int size; /* Size of a cell */ + int usableSize; /* Number of usable bytes on a page */ + int cellOffset; /* Offset to the cell pointer array */ + int cbrk; /* Offset to the cell content area */ + int nCell; /* Number of cells on the page */ + unsigned char *data; /* The page data */ + unsigned char *temp; /* Temp area for cell content */ + unsigned char *src; /* Source of content */ + int iCellFirst; /* First allowable cell index */ + int iCellLast; /* Last possible cell index */ + int iCellStart; /* First cell offset in input */ + + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + assert( pPage->pBt!=0 ); + assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE ); + assert( pPage->nOverflow==0 ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + data = pPage->aData; + hdr = pPage->hdrOffset; + cellOffset = pPage->cellOffset; + nCell = pPage->nCell; + assert( nCell==get2byte(&data[hdr+3]) || CORRUPT_DB ); + iCellFirst = cellOffset + 2*nCell; + usableSize = pPage->pBt->usableSize; + + /* This block handles pages with two or fewer free blocks and nMaxFrag + ** or fewer fragmented bytes. In this case it is faster to move the + ** two (or one) blocks of cells using memmove() and add the required + ** offsets to each pointer in the cell-pointer array than it is to + ** reconstruct the entire page. */ + if( (int)data[hdr+7]<=nMaxFrag ){ + int iFree = get2byte(&data[hdr+1]); + if( iFree>usableSize-4 ) return SQLITE_CORRUPT_PAGE(pPage); + if( iFree ){ + int iFree2 = get2byte(&data[iFree]); + if( iFree2>usableSize-4 ) return SQLITE_CORRUPT_PAGE(pPage); + if( 0==iFree2 || (data[iFree2]==0 && data[iFree2+1]==0) ){ + u8 *pEnd = &data[cellOffset + nCell*2]; + u8 *pAddr; + int sz2 = 0; + int sz = get2byte(&data[iFree+2]); + int top = get2byte(&data[hdr+5]); + if( top>=iFree ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + if( iFree2 ){ + if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PAGE(pPage); + sz2 = get2byte(&data[iFree2+2]); + if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage); + memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz)); + sz += sz2; + }else if( iFree+sz>usableSize ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + + cbrk = top+sz; + assert( cbrk+(iFree-top) <= usableSize ); + memmove(&data[cbrk], &data[top], iFree-top); + for(pAddr=&data[cellOffset]; pAddr0 ){ + temp = sqlite3PagerTempSpace(pPage->pBt->pPager); + memcpy(temp, data, usableSize); + src = temp; + for(i=0; iiCellLast ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + assert( pc>=0 && pc<=iCellLast ); + size = pPage->xCellSize(pPage, &src[pc]); + cbrk -= size; + if( cbrkusableSize ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + assert( cbrk+size<=usableSize && cbrk>=iCellStart ); + testcase( cbrk+size==usableSize ); + testcase( pc+size==usableSize ); + put2byte(pAddr, cbrk); + memcpy(&data[cbrk], &src[pc], size); + } + } + data[hdr+7] = 0; + +defragment_out: + assert( pPage->nFree>=0 ); + if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + assert( cbrk>=iCellFirst ); + put2byte(&data[hdr+5], cbrk); + data[hdr+1] = 0; + data[hdr+2] = 0; + memset(&data[iCellFirst], 0, cbrk-iCellFirst); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + return SQLITE_OK; +} + +/* +** Search the free-list on page pPg for space to store a cell nByte bytes in +** size. If one can be found, return a pointer to the space and remove it +** from the free-list. +** +** If no suitable space can be found on the free-list, return NULL. +** +** This function may detect corruption within pPg. If corruption is +** detected then *pRc is set to SQLITE_CORRUPT and NULL is returned. +** +** Slots on the free list that are between 1 and 3 bytes larger than nByte +** will be ignored if adding the extra space to the fragmentation count +** causes the fragmentation count to exceed 60. +*/ +static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){ + const int hdr = pPg->hdrOffset; /* Offset to page header */ + u8 * const aData = pPg->aData; /* Page data */ + int iAddr = hdr + 1; /* Address of ptr to pc */ + u8 *pTmp = &aData[iAddr]; /* Temporary ptr into aData[] */ + int pc = get2byte(pTmp); /* Address of a free slot */ + int x; /* Excess size of the slot */ + int maxPC = pPg->pBt->usableSize - nByte; /* Max address for a usable slot */ + int size; /* Size of the free slot */ + + assert( pc>0 ); + while( pc<=maxPC ){ + /* EVIDENCE-OF: R-22710-53328 The third and fourth bytes of each + ** freeblock form a big-endian integer which is the size of the freeblock + ** in bytes, including the 4-byte header. */ + pTmp = &aData[pc+2]; + size = get2byte(pTmp); + if( (x = size - nByte)>=0 ){ + testcase( x==4 ); + testcase( x==3 ); + if( x<4 ){ + /* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total + ** number of bytes in fragments may not exceed 60. */ + if( aData[hdr+7]>57 ) return 0; + + /* Remove the slot from the free-list. Update the number of + ** fragmented bytes within the page. */ + memcpy(&aData[iAddr], &aData[pc], 2); + aData[hdr+7] += (u8)x; + return &aData[pc]; + }else if( x+pc > maxPC ){ + /* This slot extends off the end of the usable part of the page */ + *pRc = SQLITE_CORRUPT_PAGE(pPg); + return 0; + }else{ + /* The slot remains on the free-list. Reduce its size to account + ** for the portion used by the new allocation. */ + put2byte(&aData[pc+2], x); + } + return &aData[pc + x]; + } + iAddr = pc; + pTmp = &aData[pc]; + pc = get2byte(pTmp); + if( pc<=iAddr ){ + if( pc ){ + /* The next slot in the chain comes before the current slot */ + *pRc = SQLITE_CORRUPT_PAGE(pPg); + } + return 0; + } + } + if( pc>maxPC+nByte-4 ){ + /* The free slot chain extends off the end of the page */ + *pRc = SQLITE_CORRUPT_PAGE(pPg); + } + return 0; +} + +/* +** Allocate nByte bytes of space from within the B-Tree page passed +** as the first argument. Write into *pIdx the index into pPage->aData[] +** of the first byte of allocated space. Return either SQLITE_OK or +** an error code (usually SQLITE_CORRUPT). +** +** The caller guarantees that there is sufficient space to make the +** allocation. This routine might need to defragment in order to bring +** all the space together, however. This routine will avoid using +** the first two bytes past the cell pointer area since presumably this +** allocation is being made in order to insert a new cell, so we will +** also end up needing a new cell pointer. +*/ +static SQLITE_INLINE int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ + const int hdr = pPage->hdrOffset; /* Local cache of pPage->hdrOffset */ + u8 * const data = pPage->aData; /* Local cache of pPage->aData */ + int top; /* First byte of cell content area */ + int rc = SQLITE_OK; /* Integer return code */ + u8 *pTmp; /* Temp ptr into data[] */ + int gap; /* First byte of gap between cell pointers and cell content */ + + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + assert( pPage->pBt ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( nByte>=0 ); /* Minimum cell size is 4 */ + assert( pPage->nFree>=nByte ); + assert( pPage->nOverflow==0 ); + assert( nByte < (int)(pPage->pBt->usableSize-8) ); + + assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf ); + gap = pPage->cellOffset + 2*pPage->nCell; + assert( gap<=65536 ); + /* EVIDENCE-OF: R-29356-02391 If the database uses a 65536-byte page size + ** and the reserved space is zero (the usual value for reserved space) + ** then the cell content offset of an empty page wants to be 65536. + ** However, that integer is too large to be stored in a 2-byte unsigned + ** integer, so a value of 0 is used in its place. */ + pTmp = &data[hdr+5]; + top = get2byte(pTmp); + if( gap>top ){ + if( top==0 && pPage->pBt->usableSize==65536 ){ + top = 65536; + }else{ + return SQLITE_CORRUPT_PAGE(pPage); + } + }else if( top>(int)pPage->pBt->usableSize ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + + /* If there is enough space between gap and top for one more cell pointer, + ** and if the freelist is not empty, then search the + ** freelist looking for a slot big enough to satisfy the request. + */ + testcase( gap+2==top ); + testcase( gap+1==top ); + testcase( gap==top ); + if( (data[hdr+2] || data[hdr+1]) && gap+2<=top ){ + u8 *pSpace = pageFindSlot(pPage, nByte, &rc); + if( pSpace ){ + int g2; + assert( pSpace+nByte<=data+pPage->pBt->usableSize ); + *pIdx = g2 = (int)(pSpace-data); + if( g2<=gap ){ + return SQLITE_CORRUPT_PAGE(pPage); + }else{ + return SQLITE_OK; + } + }else if( rc ){ + return rc; + } + } + + /* The request could not be fulfilled using a freelist slot. Check + ** to see if defragmentation is necessary. + */ + testcase( gap+2+nByte==top ); + if( gap+2+nByte>top ){ + assert( pPage->nCell>0 || CORRUPT_DB ); + assert( pPage->nFree>=0 ); + rc = defragmentPage(pPage, MIN(4, pPage->nFree - (2+nByte))); + if( rc ) return rc; + top = get2byteNotZero(&data[hdr+5]); + assert( gap+2+nByte<=top ); + } + + + /* Allocate memory from the gap in between the cell pointer array + ** and the cell content area. The btreeComputeFreeSpace() call has already + ** validated the freelist. Given that the freelist is valid, there + ** is no way that the allocation can extend off the end of the page. + ** The assert() below verifies the previous sentence. + */ + top -= nByte; + put2byte(&data[hdr+5], top); + assert( top+nByte <= (int)pPage->pBt->usableSize ); + *pIdx = top; + return SQLITE_OK; +} + +/* +** Return a section of the pPage->aData to the freelist. +** The first byte of the new free block is pPage->aData[iStart] +** and the size of the block is iSize bytes. +** +** Adjacent freeblocks are coalesced. +** +** Even though the freeblock list was checked by btreeComputeFreeSpace(), +** that routine will not detect overlap between cells or freeblocks. Nor +** does it detect cells or freeblocks that encroach into the reserved bytes +** at the end of the page. So do additional corruption checks inside this +** routine and return SQLITE_CORRUPT if any problems are found. +*/ +static int freeSpace(MemPage *pPage, int iStart, int iSize){ + int iPtr; /* Address of ptr to next freeblock */ + int iFreeBlk; /* Address of the next freeblock */ + u8 hdr; /* Page header size. 0 or 100 */ + int nFrag = 0; /* Reduction in fragmentation */ + int iOrigSize = iSize; /* Original value of iSize */ + int x; /* Offset to cell content area */ + int iEnd = iStart + iSize; /* First byte past the iStart buffer */ + unsigned char *data = pPage->aData; /* Page content */ + u8 *pTmp; /* Temporary ptr into data[] */ + + assert( pPage->pBt!=0 ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + assert( CORRUPT_DB || iStart>=pPage->hdrOffset+6+pPage->childPtrSize ); + assert( CORRUPT_DB || iEnd <= (int)pPage->pBt->usableSize ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( iSize>=4 ); /* Minimum cell size is 4 */ + assert( CORRUPT_DB || iStart<=(int)pPage->pBt->usableSize-4 ); + + /* The list of freeblocks must be in ascending order. Find the + ** spot on the list where iStart should be inserted. + */ + hdr = pPage->hdrOffset; + iPtr = hdr + 1; + if( data[iPtr+1]==0 && data[iPtr]==0 ){ + iFreeBlk = 0; /* Shortcut for the case when the freelist is empty */ + }else{ + while( (iFreeBlk = get2byte(&data[iPtr]))(int)pPage->pBt->usableSize-4 ){ /* TH3: corrupt081.100 */ + return SQLITE_CORRUPT_PAGE(pPage); + } + assert( iFreeBlk>iPtr || iFreeBlk==0 || CORRUPT_DB ); + + /* At this point: + ** iFreeBlk: First freeblock after iStart, or zero if none + ** iPtr: The address of a pointer to iFreeBlk + ** + ** Check to see if iFreeBlk should be coalesced onto the end of iStart. + */ + if( iFreeBlk && iEnd+3>=iFreeBlk ){ + nFrag = iFreeBlk - iEnd; + if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_PAGE(pPage); + iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]); + if( iEnd > (int)pPage->pBt->usableSize ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + iSize = iEnd - iStart; + iFreeBlk = get2byte(&data[iFreeBlk]); + } + + /* If iPtr is another freeblock (that is, if iPtr is not the freelist + ** pointer in the page header) then check to see if iStart should be + ** coalesced onto the end of iPtr. + */ + if( iPtr>hdr+1 ){ + int iPtrEnd = iPtr + get2byte(&data[iPtr+2]); + if( iPtrEnd+3>=iStart ){ + if( iPtrEnd>iStart ) return SQLITE_CORRUPT_PAGE(pPage); + nFrag += iStart - iPtrEnd; + iSize = iEnd - iPtr; + iStart = iPtr; + } + } + if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PAGE(pPage); + data[hdr+7] -= (u8)nFrag; + } + pTmp = &data[hdr+5]; + x = get2byte(pTmp); + if( pPage->pBt->btsFlags & BTS_FAST_SECURE ){ + /* Overwrite deleted information with zeros when the secure_delete + ** option is enabled */ + memset(&data[iStart], 0, iSize); + } + if( iStart<=x ){ + /* The new freeblock is at the beginning of the cell content area, + ** so just extend the cell content area rather than create another + ** freelist entry */ + if( iStart=0 && iSize<=0xffff ); + put2byte(&data[iStart+2], (u16)iSize); + } + pPage->nFree += iOrigSize; + return SQLITE_OK; +} + +/* +** Decode the flags byte (the first byte of the header) for a page +** and initialize fields of the MemPage structure accordingly. +** +** Only the following combinations are supported. Anything different +** indicates a corrupt database files: +** +** PTF_ZERODATA (0x02, 2) +** PTF_LEAFDATA | PTF_INTKEY (0x05, 5) +** PTF_ZERODATA | PTF_LEAF (0x0a, 10) +** PTF_LEAFDATA | PTF_INTKEY | PTF_LEAF (0x0d, 13) +*/ +static int decodeFlags(MemPage *pPage, int flagByte){ + BtShared *pBt; /* A copy of pPage->pBt */ + + assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + pBt = pPage->pBt; + pPage->max1bytePayload = pBt->max1bytePayload; + if( flagByte>=(PTF_ZERODATA | PTF_LEAF) ){ + pPage->childPtrSize = 0; + pPage->leaf = 1; + if( flagByte==(PTF_LEAFDATA | PTF_INTKEY | PTF_LEAF) ){ + pPage->intKeyLeaf = 1; + pPage->xCellSize = cellSizePtrTableLeaf; + pPage->xParseCell = btreeParseCellPtr; + pPage->intKey = 1; + pPage->maxLocal = pBt->maxLeaf; + pPage->minLocal = pBt->minLeaf; + }else if( flagByte==(PTF_ZERODATA | PTF_LEAF) ){ + pPage->intKey = 0; + pPage->intKeyLeaf = 0; + pPage->xCellSize = cellSizePtrIdxLeaf; + pPage->xParseCell = btreeParseCellPtrIndex; + pPage->maxLocal = pBt->maxLocal; + pPage->minLocal = pBt->minLocal; + }else{ + pPage->intKey = 0; + pPage->intKeyLeaf = 0; + pPage->xCellSize = cellSizePtrIdxLeaf; + pPage->xParseCell = btreeParseCellPtrIndex; + return SQLITE_CORRUPT_PAGE(pPage); + } + }else{ + pPage->childPtrSize = 4; + pPage->leaf = 0; + if( flagByte==(PTF_ZERODATA) ){ + pPage->intKey = 0; + pPage->intKeyLeaf = 0; + pPage->xCellSize = cellSizePtr; + pPage->xParseCell = btreeParseCellPtrIndex; + pPage->maxLocal = pBt->maxLocal; + pPage->minLocal = pBt->minLocal; + }else if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){ + pPage->intKeyLeaf = 0; + pPage->xCellSize = cellSizePtrNoPayload; + pPage->xParseCell = btreeParseCellPtrNoPayload; + pPage->intKey = 1; + pPage->maxLocal = pBt->maxLeaf; + pPage->minLocal = pBt->minLeaf; + }else{ + pPage->intKey = 0; + pPage->intKeyLeaf = 0; + pPage->xCellSize = cellSizePtr; + pPage->xParseCell = btreeParseCellPtrIndex; + return SQLITE_CORRUPT_PAGE(pPage); + } + } + return SQLITE_OK; +} + +/* +** Compute the amount of freespace on the page. In other words, fill +** in the pPage->nFree field. +*/ +static int btreeComputeFreeSpace(MemPage *pPage){ + int pc; /* Address of a freeblock within pPage->aData[] */ + u8 hdr; /* Offset to beginning of page header */ + u8 *data; /* Equal to pPage->aData */ + int usableSize; /* Amount of usable space on each page */ + int nFree; /* Number of unused bytes on the page */ + int top; /* First byte of the cell content area */ + int iCellFirst; /* First allowable cell or freeblock offset */ + int iCellLast; /* Last possible cell or freeblock offset */ + + assert( pPage->pBt!=0 ); + assert( pPage->pBt->db!=0 ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) ); + assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) ); + assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) ); + assert( pPage->isInit==1 ); + assert( pPage->nFree<0 ); + + usableSize = pPage->pBt->usableSize; + hdr = pPage->hdrOffset; + data = pPage->aData; + /* EVIDENCE-OF: R-58015-48175 The two-byte integer at offset 5 designates + ** the start of the cell content area. A zero value for this integer is + ** interpreted as 65536. */ + top = get2byteNotZero(&data[hdr+5]); + iCellFirst = hdr + 8 + pPage->childPtrSize + 2*pPage->nCell; + iCellLast = usableSize - 4; + + /* Compute the total free space on the page + ** EVIDENCE-OF: R-23588-34450 The two-byte integer at offset 1 gives the + ** start of the first freeblock on the page, or is zero if there are no + ** freeblocks. */ + pc = get2byte(&data[hdr+1]); + nFree = data[hdr+7] + top; /* Init nFree to non-freeblock free space */ + if( pc>0 ){ + u32 next, size; + if( pciCellLast ){ + /* Freeblock off the end of the page */ + return SQLITE_CORRUPT_PAGE(pPage); + } + next = get2byte(&data[pc]); + size = get2byte(&data[pc+2]); + if( size<4 ){ + /* Minimum freeblock size is 4 */ + return SQLITE_CORRUPT_PAGE(pPage); + } + nFree = nFree + size; + if( next0 ){ + /* Freeblock not in ascending order */ + return SQLITE_CORRUPT_PAGE(pPage); + } + if( pc+size>(unsigned int)usableSize ){ + /* Last freeblock extends past page end */ + return SQLITE_CORRUPT_PAGE(pPage); + } + } + + /* At this point, nFree contains the sum of the offset to the start + ** of the cell-content area plus the number of free bytes within + ** the cell-content area. If this is greater than the usable-size + ** of the page, then the page must be corrupted. This check also + ** serves to verify that the offset to the start of the cell-content + ** area, according to the page header, lies within the page. + */ + if( nFree>usableSize || nFreenFree = (u16)(nFree - iCellFirst); + return SQLITE_OK; +} + +/* +** Do additional sanity check after btreeInitPage() if +** PRAGMA cell_size_check=ON +*/ +static SQLITE_NOINLINE int btreeCellSizeCheck(MemPage *pPage){ + int iCellFirst; /* First allowable cell or freeblock offset */ + int iCellLast; /* Last possible cell or freeblock offset */ + int i; /* Index into the cell pointer array */ + int sz; /* Size of a cell */ + int pc; /* Address of a freeblock within pPage->aData[] */ + u8 *data; /* Equal to pPage->aData */ + int usableSize; /* Maximum usable space on the page */ + int cellOffset; /* Start of cell content area */ + + iCellFirst = pPage->cellOffset + 2*pPage->nCell; + usableSize = pPage->pBt->usableSize; + iCellLast = usableSize - 4; + data = pPage->aData; + cellOffset = pPage->cellOffset; + if( !pPage->leaf ) iCellLast--; + for(i=0; inCell; i++){ + pc = get2byteAligned(&data[cellOffset+i*2]); + testcase( pc==iCellFirst ); + testcase( pc==iCellLast ); + if( pciCellLast ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + sz = pPage->xCellSize(pPage, &data[pc]); + testcase( pc+sz==usableSize ); + if( pc+sz>usableSize ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + } + return SQLITE_OK; +} + +/* +** Initialize the auxiliary information for a disk block. +** +** Return SQLITE_OK on success. If we see that the page does +** not contain a well-formed database page, then return +** SQLITE_CORRUPT. Note that a return of SQLITE_OK does not +** guarantee that the page is well-formed. It only shows that +** we failed to detect any corruption. +*/ +static int btreeInitPage(MemPage *pPage){ + u8 *data; /* Equal to pPage->aData */ + BtShared *pBt; /* The main btree structure */ + + assert( pPage->pBt!=0 ); + assert( pPage->pBt->db!=0 ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) ); + assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) ); + assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) ); + assert( pPage->isInit==0 ); + + pBt = pPage->pBt; + data = pPage->aData + pPage->hdrOffset; + /* EVIDENCE-OF: R-28594-02890 The one-byte flag at offset 0 indicating + ** the b-tree page type. */ + if( decodeFlags(pPage, data[0]) ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); + pPage->maskPage = (u16)(pBt->pageSize - 1); + pPage->nOverflow = 0; + pPage->cellOffset = (u16)(pPage->hdrOffset + 8 + pPage->childPtrSize); + pPage->aCellIdx = data + pPage->childPtrSize + 8; + pPage->aDataEnd = pPage->aData + pBt->pageSize; + pPage->aDataOfst = pPage->aData + pPage->childPtrSize; + /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the + ** number of cells on the page. */ + pPage->nCell = get2byte(&data[3]); + if( pPage->nCell>MX_CELL(pBt) ){ + /* To many cells for a single page. The page must be corrupt */ + return SQLITE_CORRUPT_PAGE(pPage); + } + testcase( pPage->nCell==MX_CELL(pBt) ); + /* EVIDENCE-OF: R-24089-57979 If a page contains no cells (which is only + ** possible for a root page of a table that contains no rows) then the + ** offset to the cell content area will equal the page size minus the + ** bytes of reserved space. */ + assert( pPage->nCell>0 + || get2byteNotZero(&data[5])==(int)pBt->usableSize + || CORRUPT_DB ); + pPage->nFree = -1; /* Indicate that this value is yet uncomputed */ + pPage->isInit = 1; + if( pBt->db->flags & SQLITE_CellSizeCk ){ + return btreeCellSizeCheck(pPage); + } + return SQLITE_OK; +} + +/* +** Set up a raw page so that it looks like a database page holding +** no entries. +*/ +static void zeroPage(MemPage *pPage, int flags){ + unsigned char *data = pPage->aData; + BtShared *pBt = pPage->pBt; + int hdr = pPage->hdrOffset; + int first; + + assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno || CORRUPT_DB ); + assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); + assert( sqlite3PagerGetData(pPage->pDbPage) == data ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + assert( sqlite3_mutex_held(pBt->mutex) ); + if( pBt->btsFlags & BTS_FAST_SECURE ){ + memset(&data[hdr], 0, pBt->usableSize - hdr); + } + data[hdr] = (char)flags; + first = hdr + ((flags&PTF_LEAF)==0 ? 12 : 8); + memset(&data[hdr+1], 0, 4); + data[hdr+7] = 0; + put2byte(&data[hdr+5], pBt->usableSize); + pPage->nFree = (u16)(pBt->usableSize - first); + decodeFlags(pPage, flags); + pPage->cellOffset = (u16)first; + pPage->aDataEnd = &data[pBt->pageSize]; + pPage->aCellIdx = &data[first]; + pPage->aDataOfst = &data[pPage->childPtrSize]; + pPage->nOverflow = 0; + assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); + pPage->maskPage = (u16)(pBt->pageSize - 1); + pPage->nCell = 0; + pPage->isInit = 1; +} + + +/* +** Convert a DbPage obtained from the pager into a MemPage used by +** the btree layer. +*/ +static MemPage *btreePageFromDbPage(DbPage *pDbPage, Pgno pgno, BtShared *pBt){ + MemPage *pPage = (MemPage*)sqlite3PagerGetExtra(pDbPage); + if( pgno!=pPage->pgno ){ + pPage->aData = sqlite3PagerGetData(pDbPage); + pPage->pDbPage = pDbPage; + pPage->pBt = pBt; + pPage->pgno = pgno; + pPage->hdrOffset = pgno==1 ? 100 : 0; + } + assert( pPage->aData==sqlite3PagerGetData(pDbPage) ); + return pPage; +} + +/* +** Get a page from the pager. Initialize the MemPage.pBt and +** MemPage.aData elements if needed. See also: btreeGetUnusedPage(). +** +** If the PAGER_GET_NOCONTENT flag is set, it means that we do not care +** about the content of the page at this time. So do not go to the disk +** to fetch the content. Just fill in the content with zeros for now. +** If in the future we call sqlite3PagerWrite() on this page, that +** means we have started to be concerned about content and the disk +** read should occur at that point. +*/ +static int btreeGetPage( + BtShared *pBt, /* The btree */ + Pgno pgno, /* Number of the page to fetch */ + MemPage **ppPage, /* Return the page in this parameter */ + int flags /* PAGER_GET_NOCONTENT or PAGER_GET_READONLY */ +){ + int rc; + DbPage *pDbPage; + + assert( flags==0 || flags==PAGER_GET_NOCONTENT || flags==PAGER_GET_READONLY ); + assert( sqlite3_mutex_held(pBt->mutex) ); + rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, flags); + if( rc ) return rc; + *ppPage = btreePageFromDbPage(pDbPage, pgno, pBt); + return SQLITE_OK; +} + +/* +** Retrieve a page from the pager cache. If the requested page is not +** already in the pager cache return NULL. Initialize the MemPage.pBt and +** MemPage.aData elements if needed. +*/ +static MemPage *btreePageLookup(BtShared *pBt, Pgno pgno){ + DbPage *pDbPage; + assert( sqlite3_mutex_held(pBt->mutex) ); + pDbPage = sqlite3PagerLookup(pBt->pPager, pgno); + if( pDbPage ){ + return btreePageFromDbPage(pDbPage, pgno, pBt); + } + return 0; +} + +/* +** Return the size of the database file in pages. If there is any kind of +** error, return ((unsigned int)-1). +*/ +static Pgno btreePagecount(BtShared *pBt){ + return pBt->nPage; +} +SQLITE_PRIVATE Pgno sqlite3BtreeLastPage(Btree *p){ + assert( sqlite3BtreeHoldsMutex(p) ); + return btreePagecount(p->pBt); +} + +/* +** Get a page from the pager and initialize it. +*/ +static int getAndInitPage( + BtShared *pBt, /* The database file */ + Pgno pgno, /* Number of the page to get */ + MemPage **ppPage, /* Write the page pointer here */ + int bReadOnly /* True for a read-only page */ +){ + int rc; + DbPage *pDbPage; + MemPage *pPage; + assert( sqlite3_mutex_held(pBt->mutex) ); + + if( pgno>btreePagecount(pBt) ){ + *ppPage = 0; + return SQLITE_CORRUPT_BKPT; + } + rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, bReadOnly); + if( rc ){ + *ppPage = 0; + return rc; + } + pPage = (MemPage*)sqlite3PagerGetExtra(pDbPage); + if( pPage->isInit==0 ){ + btreePageFromDbPage(pDbPage, pgno, pBt); + rc = btreeInitPage(pPage); + if( rc!=SQLITE_OK ){ + releasePage(pPage); + *ppPage = 0; + return rc; + } + } + assert( pPage->pgno==pgno || CORRUPT_DB ); + assert( pPage->aData==sqlite3PagerGetData(pDbPage) ); + *ppPage = pPage; + return SQLITE_OK; +} + +/* +** Release a MemPage. This should be called once for each prior +** call to btreeGetPage. +** +** Page1 is a special case and must be released using releasePageOne(). +*/ +static void releasePageNotNull(MemPage *pPage){ + assert( pPage->aData ); + assert( pPage->pBt ); + assert( pPage->pDbPage!=0 ); + assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); + assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + sqlite3PagerUnrefNotNull(pPage->pDbPage); +} +static void releasePage(MemPage *pPage){ + if( pPage ) releasePageNotNull(pPage); +} +static void releasePageOne(MemPage *pPage){ + assert( pPage!=0 ); + assert( pPage->aData ); + assert( pPage->pBt ); + assert( pPage->pDbPage!=0 ); + assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); + assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + sqlite3PagerUnrefPageOne(pPage->pDbPage); +} + +/* +** Get an unused page. +** +** This works just like btreeGetPage() with the addition: +** +** * If the page is already in use for some other purpose, immediately +** release it and return an SQLITE_CURRUPT error. +** * Make sure the isInit flag is clear +*/ +static int btreeGetUnusedPage( + BtShared *pBt, /* The btree */ + Pgno pgno, /* Number of the page to fetch */ + MemPage **ppPage, /* Return the page in this parameter */ + int flags /* PAGER_GET_NOCONTENT or PAGER_GET_READONLY */ +){ + int rc = btreeGetPage(pBt, pgno, ppPage, flags); + if( rc==SQLITE_OK ){ + if( sqlite3PagerPageRefcount((*ppPage)->pDbPage)>1 ){ + releasePage(*ppPage); + *ppPage = 0; + return SQLITE_CORRUPT_BKPT; + } + (*ppPage)->isInit = 0; + }else{ + *ppPage = 0; + } + return rc; +} + + +/* +** During a rollback, when the pager reloads information into the cache +** so that the cache is restored to its original state at the start of +** the transaction, for each page restored this routine is called. +** +** This routine needs to reset the extra data section at the end of the +** page to agree with the restored data. +*/ +static void pageReinit(DbPage *pData){ + MemPage *pPage; + pPage = (MemPage *)sqlite3PagerGetExtra(pData); + assert( sqlite3PagerPageRefcount(pData)>0 ); + if( pPage->isInit ){ + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + pPage->isInit = 0; + if( sqlite3PagerPageRefcount(pData)>1 ){ + /* pPage might not be a btree page; it might be an overflow page + ** or ptrmap page or a free page. In those cases, the following + ** call to btreeInitPage() will likely return SQLITE_CORRUPT. + ** But no harm is done by this. And it is very important that + ** btreeInitPage() be called on every btree page so we make + ** the call for every page that comes in for re-initializing. */ + btreeInitPage(pPage); + } + } +} + +/* +** Invoke the busy handler for a btree. +*/ +static int btreeInvokeBusyHandler(void *pArg){ + BtShared *pBt = (BtShared*)pArg; + assert( pBt->db ); + assert( sqlite3_mutex_held(pBt->db->mutex) ); + return sqlite3InvokeBusyHandler(&pBt->db->busyHandler); +} + +/* +** Open a database file. +** +** zFilename is the name of the database file. If zFilename is NULL +** then an ephemeral database is created. The ephemeral database might +** be exclusively in memory, or it might use a disk-based memory cache. +** Either way, the ephemeral database will be automatically deleted +** when sqlite3BtreeClose() is called. +** +** If zFilename is ":memory:" then an in-memory database is created +** that is automatically destroyed when it is closed. +** +** The "flags" parameter is a bitmask that might contain bits like +** BTREE_OMIT_JOURNAL and/or BTREE_MEMORY. +** +** If the database is already opened in the same database connection +** and we are in shared cache mode, then the open will fail with an +** SQLITE_CONSTRAINT error. We cannot allow two or more BtShared +** objects in the same database connection since doing so will lead +** to problems with locking. +*/ +SQLITE_PRIVATE int sqlite3BtreeOpen( + sqlite3_vfs *pVfs, /* VFS to use for this b-tree */ + const char *zFilename, /* Name of the file containing the BTree database */ + sqlite3 *db, /* Associated database handle */ + Btree **ppBtree, /* Pointer to new Btree object written here */ + int flags, /* Options */ + int vfsFlags /* Flags passed through to sqlite3_vfs.xOpen() */ +){ + BtShared *pBt = 0; /* Shared part of btree structure */ + Btree *p; /* Handle to return */ + sqlite3_mutex *mutexOpen = 0; /* Prevents a race condition. Ticket #3537 */ + int rc = SQLITE_OK; /* Result code from this function */ + u8 nReserve; /* Byte of unused space on each page */ + unsigned char zDbHeader[100]; /* Database header content */ + + /* True if opening an ephemeral, temporary database */ + const int isTempDb = zFilename==0 || zFilename[0]==0; + + /* Set the variable isMemdb to true for an in-memory database, or + ** false for a file-based database. + */ +#ifdef SQLITE_OMIT_MEMORYDB + const int isMemdb = 0; +#else + const int isMemdb = (zFilename && strcmp(zFilename, ":memory:")==0) + || (isTempDb && sqlite3TempInMemory(db)) + || (vfsFlags & SQLITE_OPEN_MEMORY)!=0; +#endif + + assert( db!=0 ); + assert( pVfs!=0 ); + assert( sqlite3_mutex_held(db->mutex) ); + assert( (flags&0xff)==flags ); /* flags fit in 8 bits */ + + /* Only a BTREE_SINGLE database can be BTREE_UNORDERED */ + assert( (flags & BTREE_UNORDERED)==0 || (flags & BTREE_SINGLE)!=0 ); + + /* A BTREE_SINGLE database is always a temporary and/or ephemeral */ + assert( (flags & BTREE_SINGLE)==0 || isTempDb ); + + if( isMemdb ){ + flags |= BTREE_MEMORY; + } + if( (vfsFlags & SQLITE_OPEN_MAIN_DB)!=0 && (isMemdb || isTempDb) ){ + vfsFlags = (vfsFlags & ~SQLITE_OPEN_MAIN_DB) | SQLITE_OPEN_TEMP_DB; + } + p = sqlite3MallocZero(sizeof(Btree)); + if( !p ){ + return SQLITE_NOMEM_BKPT; + } + p->inTrans = TRANS_NONE; + p->db = db; +#ifndef SQLITE_OMIT_SHARED_CACHE + p->lock.pBtree = p; + p->lock.iTable = 1; +#endif + +#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) + /* + ** If this Btree is a candidate for shared cache, try to find an + ** existing BtShared object that we can share with + */ + if( isTempDb==0 && (isMemdb==0 || (vfsFlags&SQLITE_OPEN_URI)!=0) ){ + if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){ + int nFilename = sqlite3Strlen30(zFilename)+1; + int nFullPathname = pVfs->mxPathname+1; + char *zFullPathname = sqlite3Malloc(MAX(nFullPathname,nFilename)); + MUTEX_LOGIC( sqlite3_mutex *mutexShared; ) + + p->sharable = 1; + if( !zFullPathname ){ + sqlite3_free(p); + return SQLITE_NOMEM_BKPT; + } + if( isMemdb ){ + memcpy(zFullPathname, zFilename, nFilename); + }else{ + rc = sqlite3OsFullPathname(pVfs, zFilename, + nFullPathname, zFullPathname); + if( rc ){ + if( rc==SQLITE_OK_SYMLINK ){ + rc = SQLITE_OK; + }else{ + sqlite3_free(zFullPathname); + sqlite3_free(p); + return rc; + } + } + } +#if SQLITE_THREADSAFE + mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN); + sqlite3_mutex_enter(mutexOpen); + mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); + sqlite3_mutex_enter(mutexShared); +#endif + for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){ + assert( pBt->nRef>0 ); + if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager, 0)) + && sqlite3PagerVfs(pBt->pPager)==pVfs ){ + int iDb; + for(iDb=db->nDb-1; iDb>=0; iDb--){ + Btree *pExisting = db->aDb[iDb].pBt; + if( pExisting && pExisting->pBt==pBt ){ + sqlite3_mutex_leave(mutexShared); + sqlite3_mutex_leave(mutexOpen); + sqlite3_free(zFullPathname); + sqlite3_free(p); + return SQLITE_CONSTRAINT; + } + } + p->pBt = pBt; + pBt->nRef++; + break; + } + } + sqlite3_mutex_leave(mutexShared); + sqlite3_free(zFullPathname); + } +#ifdef SQLITE_DEBUG + else{ + /* In debug mode, we mark all persistent databases as sharable + ** even when they are not. This exercises the locking code and + ** gives more opportunity for asserts(sqlite3_mutex_held()) + ** statements to find locking problems. + */ + p->sharable = 1; + } +#endif + } +#endif + if( pBt==0 ){ + /* + ** The following asserts make sure that structures used by the btree are + ** the right size. This is to guard against size changes that result + ** when compiling on a different architecture. + */ + assert( sizeof(i64)==8 ); + assert( sizeof(u64)==8 ); + assert( sizeof(u32)==4 ); + assert( sizeof(u16)==2 ); + assert( sizeof(Pgno)==4 ); + + /* Suppress false-positive compiler warning from PVS-Studio */ + memset(&zDbHeader[16], 0, 8); + + pBt = sqlite3MallocZero( sizeof(*pBt) ); + if( pBt==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto btree_open_out; + } + rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename, + sizeof(MemPage), flags, vfsFlags, pageReinit); + if( rc==SQLITE_OK ){ + sqlite3PagerSetMmapLimit(pBt->pPager, db->szMmap); + rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader); + } + if( rc!=SQLITE_OK ){ + goto btree_open_out; + } + pBt->openFlags = (u8)flags; + pBt->db = db; + sqlite3PagerSetBusyHandler(pBt->pPager, btreeInvokeBusyHandler, pBt); + p->pBt = pBt; + + pBt->pCursor = 0; + pBt->pPage1 = 0; + if( sqlite3PagerIsreadonly(pBt->pPager) ) pBt->btsFlags |= BTS_READ_ONLY; +#if defined(SQLITE_SECURE_DELETE) + pBt->btsFlags |= BTS_SECURE_DELETE; +#elif defined(SQLITE_FAST_SECURE_DELETE) + pBt->btsFlags |= BTS_OVERWRITE; +#endif + /* EVIDENCE-OF: R-51873-39618 The page size for a database file is + ** determined by the 2-byte integer located at an offset of 16 bytes from + ** the beginning of the database file. */ + pBt->pageSize = (zDbHeader[16]<<8) | (zDbHeader[17]<<16); + if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE + || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){ + pBt->pageSize = 0; +#ifndef SQLITE_OMIT_AUTOVACUUM + /* If the magic name ":memory:" will create an in-memory database, then + ** leave the autoVacuum mode at 0 (do not auto-vacuum), even if + ** SQLITE_DEFAULT_AUTOVACUUM is true. On the other hand, if + ** SQLITE_OMIT_MEMORYDB has been defined, then ":memory:" is just a + ** regular file-name. In this case the auto-vacuum applies as per normal. + */ + if( zFilename && !isMemdb ){ + pBt->autoVacuum = (SQLITE_DEFAULT_AUTOVACUUM ? 1 : 0); + pBt->incrVacuum = (SQLITE_DEFAULT_AUTOVACUUM==2 ? 1 : 0); + } +#endif + nReserve = 0; + }else{ + /* EVIDENCE-OF: R-37497-42412 The size of the reserved region is + ** determined by the one-byte unsigned integer found at an offset of 20 + ** into the database file header. */ + nReserve = zDbHeader[20]; + pBt->btsFlags |= BTS_PAGESIZE_FIXED; +#ifndef SQLITE_OMIT_AUTOVACUUM + pBt->autoVacuum = (get4byte(&zDbHeader[36 + 4*4])?1:0); + pBt->incrVacuum = (get4byte(&zDbHeader[36 + 7*4])?1:0); +#endif + } + rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve); + if( rc ) goto btree_open_out; + pBt->usableSize = pBt->pageSize - nReserve; + assert( (pBt->pageSize & 7)==0 ); /* 8-byte alignment of pageSize */ + +#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) + /* Add the new BtShared object to the linked list sharable BtShareds. + */ + pBt->nRef = 1; + if( p->sharable ){ + MUTEX_LOGIC( sqlite3_mutex *mutexShared; ) + MUTEX_LOGIC( mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN);) + if( SQLITE_THREADSAFE && sqlite3GlobalConfig.bCoreMutex ){ + pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST); + if( pBt->mutex==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto btree_open_out; + } + } + sqlite3_mutex_enter(mutexShared); + pBt->pNext = GLOBAL(BtShared*,sqlite3SharedCacheList); + GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt; + sqlite3_mutex_leave(mutexShared); + } +#endif + } + +#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) + /* If the new Btree uses a sharable pBtShared, then link the new + ** Btree into the list of all sharable Btrees for the same connection. + ** The list is kept in ascending order by pBt address. + */ + if( p->sharable ){ + int i; + Btree *pSib; + for(i=0; inDb; i++){ + if( (pSib = db->aDb[i].pBt)!=0 && pSib->sharable ){ + while( pSib->pPrev ){ pSib = pSib->pPrev; } + if( (uptr)p->pBt<(uptr)pSib->pBt ){ + p->pNext = pSib; + p->pPrev = 0; + pSib->pPrev = p; + }else{ + while( pSib->pNext && (uptr)pSib->pNext->pBt<(uptr)p->pBt ){ + pSib = pSib->pNext; + } + p->pNext = pSib->pNext; + p->pPrev = pSib; + if( p->pNext ){ + p->pNext->pPrev = p; + } + pSib->pNext = p; + } + break; + } + } + } +#endif + *ppBtree = p; + +btree_open_out: + if( rc!=SQLITE_OK ){ + if( pBt && pBt->pPager ){ + sqlite3PagerClose(pBt->pPager, 0); + } + sqlite3_free(pBt); + sqlite3_free(p); + *ppBtree = 0; + }else{ + sqlite3_file *pFile; + + /* If the B-Tree was successfully opened, set the pager-cache size to the + ** default value. Except, when opening on an existing shared pager-cache, + ** do not change the pager-cache size. + */ + if( sqlite3BtreeSchema(p, 0, 0)==0 ){ + sqlite3BtreeSetCacheSize(p, SQLITE_DEFAULT_CACHE_SIZE); + } + + pFile = sqlite3PagerFile(pBt->pPager); + if( pFile->pMethods ){ + sqlite3OsFileControlHint(pFile, SQLITE_FCNTL_PDB, (void*)&pBt->db); + } + } + if( mutexOpen ){ + assert( sqlite3_mutex_held(mutexOpen) ); + sqlite3_mutex_leave(mutexOpen); + } + assert( rc!=SQLITE_OK || sqlite3BtreeConnectionCount(*ppBtree)>0 ); + return rc; +} + +/* +** Decrement the BtShared.nRef counter. When it reaches zero, +** remove the BtShared structure from the sharing list. Return +** true if the BtShared.nRef counter reaches zero and return +** false if it is still positive. +*/ +static int removeFromSharingList(BtShared *pBt){ +#ifndef SQLITE_OMIT_SHARED_CACHE + MUTEX_LOGIC( sqlite3_mutex *pMainMtx; ) + BtShared *pList; + int removed = 0; + + assert( sqlite3_mutex_notheld(pBt->mutex) ); + MUTEX_LOGIC( pMainMtx = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); ) + sqlite3_mutex_enter(pMainMtx); + pBt->nRef--; + if( pBt->nRef<=0 ){ + if( GLOBAL(BtShared*,sqlite3SharedCacheList)==pBt ){ + GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt->pNext; + }else{ + pList = GLOBAL(BtShared*,sqlite3SharedCacheList); + while( ALWAYS(pList) && pList->pNext!=pBt ){ + pList=pList->pNext; + } + if( ALWAYS(pList) ){ + pList->pNext = pBt->pNext; + } + } + if( SQLITE_THREADSAFE ){ + sqlite3_mutex_free(pBt->mutex); + } + removed = 1; + } + sqlite3_mutex_leave(pMainMtx); + return removed; +#else + UNUSED_PARAMETER( pBt ); + return 1; +#endif +} + +/* +** Make sure pBt->pTmpSpace points to an allocation of +** MX_CELL_SIZE(pBt) bytes with a 4-byte prefix for a left-child +** pointer. +*/ +static SQLITE_NOINLINE int allocateTempSpace(BtShared *pBt){ + assert( pBt!=0 ); + assert( pBt->pTmpSpace==0 ); + /* This routine is called only by btreeCursor() when allocating the + ** first write cursor for the BtShared object */ + assert( pBt->pCursor!=0 && (pBt->pCursor->curFlags & BTCF_WriteFlag)!=0 ); + pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize ); + if( pBt->pTmpSpace==0 ){ + BtCursor *pCur = pBt->pCursor; + pBt->pCursor = pCur->pNext; /* Unlink the cursor */ + memset(pCur, 0, sizeof(*pCur)); + return SQLITE_NOMEM_BKPT; + } + + /* One of the uses of pBt->pTmpSpace is to format cells before + ** inserting them into a leaf page (function fillInCell()). If + ** a cell is less than 4 bytes in size, it is rounded up to 4 bytes + ** by the various routines that manipulate binary cells. Which + ** can mean that fillInCell() only initializes the first 2 or 3 + ** bytes of pTmpSpace, but that the first 4 bytes are copied from + ** it into a database page. This is not actually a problem, but it + ** does cause a valgrind error when the 1 or 2 bytes of uninitialized + ** data is passed to system call write(). So to avoid this error, + ** zero the first 4 bytes of temp space here. + ** + ** Also: Provide four bytes of initialized space before the + ** beginning of pTmpSpace as an area available to prepend the + ** left-child pointer to the beginning of a cell. + */ + memset(pBt->pTmpSpace, 0, 8); + pBt->pTmpSpace += 4; + return SQLITE_OK; +} + +/* +** Free the pBt->pTmpSpace allocation +*/ +static void freeTempSpace(BtShared *pBt){ + if( pBt->pTmpSpace ){ + pBt->pTmpSpace -= 4; + sqlite3PageFree(pBt->pTmpSpace); + pBt->pTmpSpace = 0; + } +} + +/* +** Close an open database and invalidate all cursors. +*/ +SQLITE_PRIVATE int sqlite3BtreeClose(Btree *p){ + BtShared *pBt = p->pBt; + + /* Close all cursors opened via this handle. */ + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + + /* Verify that no other cursors have this Btree open */ +#ifdef SQLITE_DEBUG + { + BtCursor *pCur = pBt->pCursor; + while( pCur ){ + BtCursor *pTmp = pCur; + pCur = pCur->pNext; + assert( pTmp->pBtree!=p ); + + } + } +#endif + + /* Rollback any active transaction and free the handle structure. + ** The call to sqlite3BtreeRollback() drops any table-locks held by + ** this handle. + */ + sqlite3BtreeRollback(p, SQLITE_OK, 0); + sqlite3BtreeLeave(p); + + /* If there are still other outstanding references to the shared-btree + ** structure, return now. The remainder of this procedure cleans + ** up the shared-btree. + */ + assert( p->wantToLock==0 && p->locked==0 ); + if( !p->sharable || removeFromSharingList(pBt) ){ + /* The pBt is no longer on the sharing list, so we can access + ** it without having to hold the mutex. + ** + ** Clean out and delete the BtShared object. + */ + assert( !pBt->pCursor ); + sqlite3PagerClose(pBt->pPager, p->db); + if( pBt->xFreeSchema && pBt->pSchema ){ + pBt->xFreeSchema(pBt->pSchema); + } + sqlite3DbFree(0, pBt->pSchema); + freeTempSpace(pBt); + sqlite3_free(pBt); + } + +#ifndef SQLITE_OMIT_SHARED_CACHE + assert( p->wantToLock==0 ); + assert( p->locked==0 ); + if( p->pPrev ) p->pPrev->pNext = p->pNext; + if( p->pNext ) p->pNext->pPrev = p->pPrev; +#endif + + sqlite3_free(p); + return SQLITE_OK; +} + +/* +** Change the "soft" limit on the number of pages in the cache. +** Unused and unmodified pages will be recycled when the number of +** pages in the cache exceeds this soft limit. But the size of the +** cache is allowed to grow larger than this limit if it contains +** dirty pages or pages still in active use. +*/ +SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){ + BtShared *pBt = p->pBt; + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + sqlite3PagerSetCachesize(pBt->pPager, mxPage); + sqlite3BtreeLeave(p); + return SQLITE_OK; +} + +/* +** Change the "spill" limit on the number of pages in the cache. +** If the number of pages exceeds this limit during a write transaction, +** the pager might attempt to "spill" pages to the journal early in +** order to free up memory. +** +** The value returned is the current spill size. If zero is passed +** as an argument, no changes are made to the spill size setting, so +** using mxPage of 0 is a way to query the current spill size. +*/ +SQLITE_PRIVATE int sqlite3BtreeSetSpillSize(Btree *p, int mxPage){ + BtShared *pBt = p->pBt; + int res; + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + res = sqlite3PagerSetSpillsize(pBt->pPager, mxPage); + sqlite3BtreeLeave(p); + return res; +} + +#if SQLITE_MAX_MMAP_SIZE>0 +/* +** Change the limit on the amount of the database file that may be +** memory mapped. +*/ +SQLITE_PRIVATE int sqlite3BtreeSetMmapLimit(Btree *p, sqlite3_int64 szMmap){ + BtShared *pBt = p->pBt; + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + sqlite3PagerSetMmapLimit(pBt->pPager, szMmap); + sqlite3BtreeLeave(p); + return SQLITE_OK; +} +#endif /* SQLITE_MAX_MMAP_SIZE>0 */ + +/* +** Change the way data is synced to disk in order to increase or decrease +** how well the database resists damage due to OS crashes and power +** failures. Level 1 is the same as asynchronous (no syncs() occur and +** there is a high probability of damage) Level 2 is the default. There +** is a very low but non-zero probability of damage. Level 3 reduces the +** probability of damage to near zero but with a write performance reduction. +*/ +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +SQLITE_PRIVATE int sqlite3BtreeSetPagerFlags( + Btree *p, /* The btree to set the safety level on */ + unsigned pgFlags /* Various PAGER_* flags */ +){ + BtShared *pBt = p->pBt; + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + sqlite3PagerSetFlags(pBt->pPager, pgFlags); + sqlite3BtreeLeave(p); + return SQLITE_OK; +} +#endif + +/* +** Change the default pages size and the number of reserved bytes per page. +** Or, if the page size has already been fixed, return SQLITE_READONLY +** without changing anything. +** +** The page size must be a power of 2 between 512 and 65536. If the page +** size supplied does not meet this constraint then the page size is not +** changed. +** +** Page sizes are constrained to be a power of two so that the region +** of the database file used for locking (beginning at PENDING_BYTE, +** the first byte past the 1GB boundary, 0x40000000) needs to occur +** at the beginning of a page. +** +** If parameter nReserve is less than zero, then the number of reserved +** bytes per page is left unchanged. +** +** If the iFix!=0 then the BTS_PAGESIZE_FIXED flag is set so that the page size +** and autovacuum mode can no longer be changed. +*/ +SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){ + int rc = SQLITE_OK; + int x; + BtShared *pBt = p->pBt; + assert( nReserve>=0 && nReserve<=255 ); + sqlite3BtreeEnter(p); + pBt->nReserveWanted = (u8)nReserve; + x = pBt->pageSize - pBt->usableSize; + if( x==nReserve && (pageSize==0 || (u32)pageSize==pBt->pageSize) ){ + sqlite3BtreeLeave(p); + return SQLITE_OK; + } + if( nReservebtsFlags & BTS_PAGESIZE_FIXED ){ + sqlite3BtreeLeave(p); + return SQLITE_READONLY; + } + assert( nReserve>=0 && nReserve<=255 ); + if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE && + ((pageSize-1)&pageSize)==0 ){ + assert( (pageSize & 7)==0 ); + assert( !pBt->pCursor ); + if( nReserve>32 && pageSize==512 ) pageSize = 1024; + pBt->pageSize = (u32)pageSize; + freeTempSpace(pBt); + } + rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve); + pBt->usableSize = pBt->pageSize - (u16)nReserve; + if( iFix ) pBt->btsFlags |= BTS_PAGESIZE_FIXED; + sqlite3BtreeLeave(p); + return rc; +} + +/* +** Return the currently defined page size +*/ +SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree *p){ + return p->pBt->pageSize; +} + +/* +** This function is similar to sqlite3BtreeGetReserve(), except that it +** may only be called if it is guaranteed that the b-tree mutex is already +** held. +** +** This is useful in one special case in the backup API code where it is +** known that the shared b-tree mutex is held, but the mutex on the +** database handle that owns *p is not. In this case if sqlite3BtreeEnter() +** were to be called, it might collide with some other operation on the +** database handle that owns *p, causing undefined behavior. +*/ +SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p){ + int n; + assert( sqlite3_mutex_held(p->pBt->mutex) ); + n = p->pBt->pageSize - p->pBt->usableSize; + return n; +} + +/* +** Return the number of bytes of space at the end of every page that +** are intentionally left unused. This is the "reserved" space that is +** sometimes used by extensions. +** +** The value returned is the larger of the current reserve size and +** the latest reserve size requested by SQLITE_FILECTRL_RESERVE_BYTES. +** The amount of reserve can only grow - never shrink. +*/ +SQLITE_PRIVATE int sqlite3BtreeGetRequestedReserve(Btree *p){ + int n1, n2; + sqlite3BtreeEnter(p); + n1 = (int)p->pBt->nReserveWanted; + n2 = sqlite3BtreeGetReserveNoMutex(p); + sqlite3BtreeLeave(p); + return n1>n2 ? n1 : n2; +} + + +/* +** Set the maximum page count for a database if mxPage is positive. +** No changes are made if mxPage is 0 or negative. +** Regardless of the value of mxPage, return the maximum page count. +*/ +SQLITE_PRIVATE Pgno sqlite3BtreeMaxPageCount(Btree *p, Pgno mxPage){ + Pgno n; + sqlite3BtreeEnter(p); + n = sqlite3PagerMaxPageCount(p->pBt->pPager, mxPage); + sqlite3BtreeLeave(p); + return n; +} + +/* +** Change the values for the BTS_SECURE_DELETE and BTS_OVERWRITE flags: +** +** newFlag==0 Both BTS_SECURE_DELETE and BTS_OVERWRITE are cleared +** newFlag==1 BTS_SECURE_DELETE set and BTS_OVERWRITE is cleared +** newFlag==2 BTS_SECURE_DELETE cleared and BTS_OVERWRITE is set +** newFlag==(-1) No changes +** +** This routine acts as a query if newFlag is less than zero +** +** With BTS_OVERWRITE set, deleted content is overwritten by zeros, but +** freelist leaf pages are not written back to the database. Thus in-page +** deleted content is cleared, but freelist deleted content is not. +** +** With BTS_SECURE_DELETE, operation is like BTS_OVERWRITE with the addition +** that freelist leaf pages are written back into the database, increasing +** the amount of disk I/O. +*/ +SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree *p, int newFlag){ + int b; + if( p==0 ) return 0; + sqlite3BtreeEnter(p); + assert( BTS_OVERWRITE==BTS_SECURE_DELETE*2 ); + assert( BTS_FAST_SECURE==(BTS_OVERWRITE|BTS_SECURE_DELETE) ); + if( newFlag>=0 ){ + p->pBt->btsFlags &= ~BTS_FAST_SECURE; + p->pBt->btsFlags |= (u16)(BTS_SECURE_DELETE*newFlag); + } + b = (p->pBt->btsFlags & BTS_FAST_SECURE)/BTS_SECURE_DELETE; + sqlite3BtreeLeave(p); + return b; +} + +/* +** Change the 'auto-vacuum' property of the database. If the 'autoVacuum' +** parameter is non-zero, then auto-vacuum mode is enabled. If zero, it +** is disabled. The default value for the auto-vacuum property is +** determined by the SQLITE_DEFAULT_AUTOVACUUM macro. +*/ +SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *p, int autoVacuum){ +#ifdef SQLITE_OMIT_AUTOVACUUM + return SQLITE_READONLY; +#else + BtShared *pBt = p->pBt; + int rc = SQLITE_OK; + u8 av = (u8)autoVacuum; + + sqlite3BtreeEnter(p); + if( (pBt->btsFlags & BTS_PAGESIZE_FIXED)!=0 && (av ?1:0)!=pBt->autoVacuum ){ + rc = SQLITE_READONLY; + }else{ + pBt->autoVacuum = av ?1:0; + pBt->incrVacuum = av==2 ?1:0; + } + sqlite3BtreeLeave(p); + return rc; +#endif +} + +/* +** Return the value of the 'auto-vacuum' property. If auto-vacuum is +** enabled 1 is returned. Otherwise 0. +*/ +SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *p){ +#ifdef SQLITE_OMIT_AUTOVACUUM + return BTREE_AUTOVACUUM_NONE; +#else + int rc; + sqlite3BtreeEnter(p); + rc = ( + (!p->pBt->autoVacuum)?BTREE_AUTOVACUUM_NONE: + (!p->pBt->incrVacuum)?BTREE_AUTOVACUUM_FULL: + BTREE_AUTOVACUUM_INCR + ); + sqlite3BtreeLeave(p); + return rc; +#endif +} + +/* +** If the user has not set the safety-level for this database connection +** using "PRAGMA synchronous", and if the safety-level is not already +** set to the value passed to this function as the second parameter, +** set it so. +*/ +#if SQLITE_DEFAULT_SYNCHRONOUS!=SQLITE_DEFAULT_WAL_SYNCHRONOUS \ + && !defined(SQLITE_OMIT_WAL) +static void setDefaultSyncFlag(BtShared *pBt, u8 safety_level){ + sqlite3 *db; + Db *pDb; + if( (db=pBt->db)!=0 && (pDb=db->aDb)!=0 ){ + while( pDb->pBt==0 || pDb->pBt->pBt!=pBt ){ pDb++; } + if( pDb->bSyncSet==0 + && pDb->safety_level!=safety_level + && pDb!=&db->aDb[1] + ){ + pDb->safety_level = safety_level; + sqlite3PagerSetFlags(pBt->pPager, + pDb->safety_level | (db->flags & PAGER_FLAGS_MASK)); + } + } +} +#else +# define setDefaultSyncFlag(pBt,safety_level) +#endif + +/* Forward declaration */ +static int newDatabase(BtShared*); + + +/* +** Get a reference to pPage1 of the database file. This will +** also acquire a readlock on that file. +** +** SQLITE_OK is returned on success. If the file is not a +** well-formed database file, then SQLITE_CORRUPT is returned. +** SQLITE_BUSY is returned if the database is locked. SQLITE_NOMEM +** is returned if we run out of memory. +*/ +static int lockBtree(BtShared *pBt){ + int rc; /* Result code from subfunctions */ + MemPage *pPage1; /* Page 1 of the database file */ + u32 nPage; /* Number of pages in the database */ + u32 nPageFile = 0; /* Number of pages in the database file */ + + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( pBt->pPage1==0 ); + rc = sqlite3PagerSharedLock(pBt->pPager); + if( rc!=SQLITE_OK ) return rc; + rc = btreeGetPage(pBt, 1, &pPage1, 0); + if( rc!=SQLITE_OK ) return rc; + + /* Do some checking to help insure the file we opened really is + ** a valid database file. + */ + nPage = get4byte(28+(u8*)pPage1->aData); + sqlite3PagerPagecount(pBt->pPager, (int*)&nPageFile); + if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){ + nPage = nPageFile; + } + if( (pBt->db->flags & SQLITE_ResetDatabase)!=0 ){ + nPage = 0; + } + if( nPage>0 ){ + u32 pageSize; + u32 usableSize; + u8 *page1 = pPage1->aData; + rc = SQLITE_NOTADB; + /* EVIDENCE-OF: R-43737-39999 Every valid SQLite database file begins + ** with the following 16 bytes (in hex): 53 51 4c 69 74 65 20 66 6f 72 6d + ** 61 74 20 33 00. */ + if( memcmp(page1, zMagicHeader, 16)!=0 ){ + goto page1_init_failed; + } + +#ifdef SQLITE_OMIT_WAL + if( page1[18]>1 ){ + pBt->btsFlags |= BTS_READ_ONLY; + } + if( page1[19]>1 ){ + goto page1_init_failed; + } +#else + if( page1[18]>2 ){ + pBt->btsFlags |= BTS_READ_ONLY; + } + if( page1[19]>2 ){ + goto page1_init_failed; + } + + /* If the read version is set to 2, this database should be accessed + ** in WAL mode. If the log is not already open, open it now. Then + ** return SQLITE_OK and return without populating BtShared.pPage1. + ** The caller detects this and calls this function again. This is + ** required as the version of page 1 currently in the page1 buffer + ** may not be the latest version - there may be a newer one in the log + ** file. + */ + if( page1[19]==2 && (pBt->btsFlags & BTS_NO_WAL)==0 ){ + int isOpen = 0; + rc = sqlite3PagerOpenWal(pBt->pPager, &isOpen); + if( rc!=SQLITE_OK ){ + goto page1_init_failed; + }else{ + setDefaultSyncFlag(pBt, SQLITE_DEFAULT_WAL_SYNCHRONOUS+1); + if( isOpen==0 ){ + releasePageOne(pPage1); + return SQLITE_OK; + } + } + rc = SQLITE_NOTADB; + }else{ + setDefaultSyncFlag(pBt, SQLITE_DEFAULT_SYNCHRONOUS+1); + } +#endif + + /* EVIDENCE-OF: R-15465-20813 The maximum and minimum embedded payload + ** fractions and the leaf payload fraction values must be 64, 32, and 32. + ** + ** The original design allowed these amounts to vary, but as of + ** version 3.6.0, we require them to be fixed. + */ + if( memcmp(&page1[21], "\100\040\040",3)!=0 ){ + goto page1_init_failed; + } + /* EVIDENCE-OF: R-51873-39618 The page size for a database file is + ** determined by the 2-byte integer located at an offset of 16 bytes from + ** the beginning of the database file. */ + pageSize = (page1[16]<<8) | (page1[17]<<16); + /* EVIDENCE-OF: R-25008-21688 The size of a page is a power of two + ** between 512 and 65536 inclusive. */ + if( ((pageSize-1)&pageSize)!=0 + || pageSize>SQLITE_MAX_PAGE_SIZE + || pageSize<=256 + ){ + goto page1_init_failed; + } + assert( (pageSize & 7)==0 ); + /* EVIDENCE-OF: R-59310-51205 The "reserved space" size in the 1-byte + ** integer at offset 20 is the number of bytes of space at the end of + ** each page to reserve for extensions. + ** + ** EVIDENCE-OF: R-37497-42412 The size of the reserved region is + ** determined by the one-byte unsigned integer found at an offset of 20 + ** into the database file header. */ + usableSize = pageSize - page1[20]; + if( (u32)pageSize!=pBt->pageSize ){ + /* After reading the first page of the database assuming a page size + ** of BtShared.pageSize, we have discovered that the page-size is + ** actually pageSize. Unlock the database, leave pBt->pPage1 at + ** zero and return SQLITE_OK. The caller will call this function + ** again with the correct page-size. + */ + releasePageOne(pPage1); + pBt->usableSize = usableSize; + pBt->pageSize = pageSize; + pBt->btsFlags |= BTS_PAGESIZE_FIXED; + freeTempSpace(pBt); + rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, + pageSize-usableSize); + return rc; + } + if( nPage>nPageFile ){ + if( sqlite3WritableSchema(pBt->db)==0 ){ + rc = SQLITE_CORRUPT_BKPT; + goto page1_init_failed; + }else{ + nPage = nPageFile; + } + } + /* EVIDENCE-OF: R-28312-64704 However, the usable size is not allowed to + ** be less than 480. In other words, if the page size is 512, then the + ** reserved space size cannot exceed 32. */ + if( usableSize<480 ){ + goto page1_init_failed; + } + pBt->btsFlags |= BTS_PAGESIZE_FIXED; + pBt->pageSize = pageSize; + pBt->usableSize = usableSize; +#ifndef SQLITE_OMIT_AUTOVACUUM + pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0); + pBt->incrVacuum = (get4byte(&page1[36 + 7*4])?1:0); +#endif + } + + /* maxLocal is the maximum amount of payload to store locally for + ** a cell. Make sure it is small enough so that at least minFanout + ** cells can will fit on one page. We assume a 10-byte page header. + ** Besides the payload, the cell must store: + ** 2-byte pointer to the cell + ** 4-byte child pointer + ** 9-byte nKey value + ** 4-byte nData value + ** 4-byte overflow page pointer + ** So a cell consists of a 2-byte pointer, a header which is as much as + ** 17 bytes long, 0 to N bytes of payload, and an optional 4 byte overflow + ** page pointer. + */ + pBt->maxLocal = (u16)((pBt->usableSize-12)*64/255 - 23); + pBt->minLocal = (u16)((pBt->usableSize-12)*32/255 - 23); + pBt->maxLeaf = (u16)(pBt->usableSize - 35); + pBt->minLeaf = (u16)((pBt->usableSize-12)*32/255 - 23); + if( pBt->maxLocal>127 ){ + pBt->max1bytePayload = 127; + }else{ + pBt->max1bytePayload = (u8)pBt->maxLocal; + } + assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) ); + pBt->pPage1 = pPage1; + pBt->nPage = nPage; + return SQLITE_OK; + +page1_init_failed: + releasePageOne(pPage1); + pBt->pPage1 = 0; + return rc; +} + +#ifndef NDEBUG +/* +** Return the number of cursors open on pBt. This is for use +** in assert() expressions, so it is only compiled if NDEBUG is not +** defined. +** +** Only write cursors are counted if wrOnly is true. If wrOnly is +** false then all cursors are counted. +** +** For the purposes of this routine, a cursor is any cursor that +** is capable of reading or writing to the database. Cursors that +** have been tripped into the CURSOR_FAULT state are not counted. +*/ +static int countValidCursors(BtShared *pBt, int wrOnly){ + BtCursor *pCur; + int r = 0; + for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ + if( (wrOnly==0 || (pCur->curFlags & BTCF_WriteFlag)!=0) + && pCur->eState!=CURSOR_FAULT ) r++; + } + return r; +} +#endif + +/* +** If there are no outstanding cursors and we are not in the middle +** of a transaction but there is a read lock on the database, then +** this routine unrefs the first page of the database file which +** has the effect of releasing the read lock. +** +** If there is a transaction in progress, this routine is a no-op. +*/ +static void unlockBtreeIfUnused(BtShared *pBt){ + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( countValidCursors(pBt,0)==0 || pBt->inTransaction>TRANS_NONE ); + if( pBt->inTransaction==TRANS_NONE && pBt->pPage1!=0 ){ + MemPage *pPage1 = pBt->pPage1; + assert( pPage1->aData ); + assert( sqlite3PagerRefcount(pBt->pPager)==1 ); + pBt->pPage1 = 0; + releasePageOne(pPage1); + } +} + +/* +** If pBt points to an empty file then convert that empty file +** into a new empty database by initializing the first page of +** the database. +*/ +static int newDatabase(BtShared *pBt){ + MemPage *pP1; + unsigned char *data; + int rc; + + assert( sqlite3_mutex_held(pBt->mutex) ); + if( pBt->nPage>0 ){ + return SQLITE_OK; + } + pP1 = pBt->pPage1; + assert( pP1!=0 ); + data = pP1->aData; + rc = sqlite3PagerWrite(pP1->pDbPage); + if( rc ) return rc; + memcpy(data, zMagicHeader, sizeof(zMagicHeader)); + assert( sizeof(zMagicHeader)==16 ); + data[16] = (u8)((pBt->pageSize>>8)&0xff); + data[17] = (u8)((pBt->pageSize>>16)&0xff); + data[18] = 1; + data[19] = 1; + assert( pBt->usableSize<=pBt->pageSize && pBt->usableSize+255>=pBt->pageSize); + data[20] = (u8)(pBt->pageSize - pBt->usableSize); + data[21] = 64; + data[22] = 32; + data[23] = 32; + memset(&data[24], 0, 100-24); + zeroPage(pP1, PTF_INTKEY|PTF_LEAF|PTF_LEAFDATA ); + pBt->btsFlags |= BTS_PAGESIZE_FIXED; +#ifndef SQLITE_OMIT_AUTOVACUUM + assert( pBt->autoVacuum==1 || pBt->autoVacuum==0 ); + assert( pBt->incrVacuum==1 || pBt->incrVacuum==0 ); + put4byte(&data[36 + 4*4], pBt->autoVacuum); + put4byte(&data[36 + 7*4], pBt->incrVacuum); +#endif + pBt->nPage = 1; + data[31] = 1; + return SQLITE_OK; +} + +/* +** Initialize the first page of the database file (creating a database +** consisting of a single page and no schema objects). Return SQLITE_OK +** if successful, or an SQLite error code otherwise. +*/ +SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p){ + int rc; + sqlite3BtreeEnter(p); + p->pBt->nPage = 0; + rc = newDatabase(p->pBt); + sqlite3BtreeLeave(p); + return rc; +} + +/* +** Attempt to start a new transaction. A write-transaction +** is started if the second argument is nonzero, otherwise a read- +** transaction. If the second argument is 2 or more and exclusive +** transaction is started, meaning that no other process is allowed +** to access the database. A preexisting transaction may not be +** upgraded to exclusive by calling this routine a second time - the +** exclusivity flag only works for a new transaction. +** +** A write-transaction must be started before attempting any +** changes to the database. None of the following routines +** will work unless a transaction is started first: +** +** sqlite3BtreeCreateTable() +** sqlite3BtreeCreateIndex() +** sqlite3BtreeClearTable() +** sqlite3BtreeDropTable() +** sqlite3BtreeInsert() +** sqlite3BtreeDelete() +** sqlite3BtreeUpdateMeta() +** +** If an initial attempt to acquire the lock fails because of lock contention +** and the database was previously unlocked, then invoke the busy handler +** if there is one. But if there was previously a read-lock, do not +** invoke the busy handler - just return SQLITE_BUSY. SQLITE_BUSY is +** returned when there is already a read-lock in order to avoid a deadlock. +** +** Suppose there are two processes A and B. A has a read lock and B has +** a reserved lock. B tries to promote to exclusive but is blocked because +** of A's read lock. A tries to promote to reserved but is blocked by B. +** One or the other of the two processes must give way or there can be +** no progress. By returning SQLITE_BUSY and not invoking the busy callback +** when A already has a read lock, we encourage A to give up and let B +** proceed. +*/ +static SQLITE_NOINLINE int btreeBeginTrans( + Btree *p, /* The btree in which to start the transaction */ + int wrflag, /* True to start a write transaction */ + int *pSchemaVersion /* Put schema version number here, if not NULL */ +){ + BtShared *pBt = p->pBt; + Pager *pPager = pBt->pPager; + int rc = SQLITE_OK; + + sqlite3BtreeEnter(p); + btreeIntegrity(p); + + /* If the btree is already in a write-transaction, or it + ** is already in a read-transaction and a read-transaction + ** is requested, this is a no-op. + */ + if( p->inTrans==TRANS_WRITE || (p->inTrans==TRANS_READ && !wrflag) ){ + goto trans_begun; + } + assert( pBt->inTransaction==TRANS_WRITE || IfNotOmitAV(pBt->bDoTruncate)==0 ); + + if( (p->db->flags & SQLITE_ResetDatabase) + && sqlite3PagerIsreadonly(pPager)==0 + ){ + pBt->btsFlags &= ~BTS_READ_ONLY; + } + + /* Write transactions are not possible on a read-only database */ + if( (pBt->btsFlags & BTS_READ_ONLY)!=0 && wrflag ){ + rc = SQLITE_READONLY; + goto trans_begun; + } + +#ifndef SQLITE_OMIT_SHARED_CACHE + { + sqlite3 *pBlock = 0; + /* If another database handle has already opened a write transaction + ** on this shared-btree structure and a second write transaction is + ** requested, return SQLITE_LOCKED. + */ + if( (wrflag && pBt->inTransaction==TRANS_WRITE) + || (pBt->btsFlags & BTS_PENDING)!=0 + ){ + pBlock = pBt->pWriter->db; + }else if( wrflag>1 ){ + BtLock *pIter; + for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){ + if( pIter->pBtree!=p ){ + pBlock = pIter->pBtree->db; + break; + } + } + } + if( pBlock ){ + sqlite3ConnectionBlocked(p->db, pBlock); + rc = SQLITE_LOCKED_SHAREDCACHE; + goto trans_begun; + } + } +#endif + + /* Any read-only or read-write transaction implies a read-lock on + ** page 1. So if some other shared-cache client already has a write-lock + ** on page 1, the transaction cannot be opened. */ + rc = querySharedCacheTableLock(p, SCHEMA_ROOT, READ_LOCK); + if( SQLITE_OK!=rc ) goto trans_begun; + + pBt->btsFlags &= ~BTS_INITIALLY_EMPTY; + if( pBt->nPage==0 ) pBt->btsFlags |= BTS_INITIALLY_EMPTY; + do { + sqlite3PagerWalDb(pPager, p->db); + +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + /* If transitioning from no transaction directly to a write transaction, + ** block for the WRITER lock first if possible. */ + if( pBt->pPage1==0 && wrflag ){ + assert( pBt->inTransaction==TRANS_NONE ); + rc = sqlite3PagerWalWriteLock(pPager, 1); + if( rc!=SQLITE_BUSY && rc!=SQLITE_OK ) break; + } +#endif + +#ifdef SQLITE_EXPERIMENTAL_PRAGMA_20251114 + /* If both a read and write transaction will be opened by this call, + ** then issue a file-control as if the following pragma command had + ** been evaluated: + ** + ** PRAGMA experimental_pragma_20251114 = 1|2 + ** + ** where the RHS is "1" if wrflag is 1 (RESERVED lock), or "2" if wrflag + ** is 2 (EXCLUSIVE lock). Ignore any result or error returned by the VFS. + ** + ** WARNING: This code will likely remain part of SQLite only temporarily - + ** it exists to allow users to experiment with certain types of blocking + ** locks in custom VFS implementations. It MAY BE REMOVED AT ANY TIME. */ + if( pBt->pPage1==0 && wrflag ){ + sqlite3_file *fd = sqlite3PagerFile(pPager); + char *aFcntl[3] = {0,0,0}; + aFcntl[1] = "experimental_pragma_20251114"; + assert( wrflag==1 || wrflag==2 ); + aFcntl[2] = (wrflag==1 ? "1" : "2"); + sqlite3OsFileControlHint(fd, SQLITE_FCNTL_PRAGMA, (void*)aFcntl); + sqlite3_free(aFcntl[0]); + } +#endif + + /* Call lockBtree() until either pBt->pPage1 is populated or + ** lockBtree() returns something other than SQLITE_OK. lockBtree() + ** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after + ** reading page 1 it discovers that the page-size of the database + ** file is not pBt->pageSize. In this case lockBtree() will update + ** pBt->pageSize to the page-size of the file on disk. + */ + while( pBt->pPage1==0 && SQLITE_OK==(rc = lockBtree(pBt)) ); + + if( rc==SQLITE_OK && wrflag ){ + if( (pBt->btsFlags & BTS_READ_ONLY)!=0 ){ + rc = SQLITE_READONLY; + }else{ + rc = sqlite3PagerBegin(pPager, wrflag>1, sqlite3TempInMemory(p->db)); + if( rc==SQLITE_OK ){ + rc = newDatabase(pBt); + }else if( rc==SQLITE_BUSY_SNAPSHOT && pBt->inTransaction==TRANS_NONE ){ + /* if there was no transaction opened when this function was + ** called and SQLITE_BUSY_SNAPSHOT is returned, change the error + ** code to SQLITE_BUSY. */ + rc = SQLITE_BUSY; + } + } + } + + if( rc!=SQLITE_OK ){ + (void)sqlite3PagerWalWriteLock(pPager, 0); + unlockBtreeIfUnused(pBt); + } +#if defined(SQLITE_ENABLE_SETLK_TIMEOUT) + if( rc==SQLITE_BUSY_TIMEOUT ){ + /* If a blocking lock timed out, break out of the loop here so that + ** the busy-handler is not invoked. */ + break; + } +#endif + }while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE && + btreeInvokeBusyHandler(pBt) ); + sqlite3PagerWalDb(pPager, 0); +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY; +#endif + + if( rc==SQLITE_OK ){ + if( p->inTrans==TRANS_NONE ){ + pBt->nTransaction++; +#ifndef SQLITE_OMIT_SHARED_CACHE + if( p->sharable ){ + assert( p->lock.pBtree==p && p->lock.iTable==1 ); + p->lock.eLock = READ_LOCK; + p->lock.pNext = pBt->pLock; + pBt->pLock = &p->lock; + } +#endif + } + p->inTrans = (wrflag?TRANS_WRITE:TRANS_READ); + if( p->inTrans>pBt->inTransaction ){ + pBt->inTransaction = p->inTrans; + } + if( wrflag ){ + MemPage *pPage1 = pBt->pPage1; +#ifndef SQLITE_OMIT_SHARED_CACHE + assert( !pBt->pWriter ); + pBt->pWriter = p; + pBt->btsFlags &= ~BTS_EXCLUSIVE; + if( wrflag>1 ) pBt->btsFlags |= BTS_EXCLUSIVE; +#endif + + /* If the db-size header field is incorrect (as it may be if an old + ** client has been writing the database file), update it now. Doing + ** this sooner rather than later means the database size can safely + ** re-read the database size from page 1 if a savepoint or transaction + ** rollback occurs within the transaction. + */ + if( pBt->nPage!=get4byte(&pPage1->aData[28]) ){ + rc = sqlite3PagerWrite(pPage1->pDbPage); + if( rc==SQLITE_OK ){ + put4byte(&pPage1->aData[28], pBt->nPage); + } + } + } + } + +trans_begun: + if( rc==SQLITE_OK ){ + if( pSchemaVersion ){ + *pSchemaVersion = get4byte(&pBt->pPage1->aData[40]); + } + if( wrflag ){ + /* This call makes sure that the pager has the correct number of + ** open savepoints. If the second parameter is greater than 0 and + ** the sub-journal is not already open, then it will be opened here. + */ + rc = sqlite3PagerOpenSavepoint(pPager, p->db->nSavepoint); + } + } + + btreeIntegrity(p); + sqlite3BtreeLeave(p); + return rc; +} +SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){ + BtShared *pBt; + if( p->sharable + || p->inTrans==TRANS_NONE + || (p->inTrans==TRANS_READ && wrflag!=0) + ){ + return btreeBeginTrans(p,wrflag,pSchemaVersion); + } + pBt = p->pBt; + if( pSchemaVersion ){ + *pSchemaVersion = get4byte(&pBt->pPage1->aData[40]); + } + if( wrflag ){ + /* This call makes sure that the pager has the correct number of + ** open savepoints. If the second parameter is greater than 0 and + ** the sub-journal is not already open, then it will be opened here. + */ + return sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint); + }else{ + return SQLITE_OK; + } +} + +#ifndef SQLITE_OMIT_AUTOVACUUM + +/* +** Set the pointer-map entries for all children of page pPage. Also, if +** pPage contains cells that point to overflow pages, set the pointer +** map entries for the overflow pages as well. +*/ +static int setChildPtrmaps(MemPage *pPage){ + int i; /* Counter variable */ + int nCell; /* Number of cells in page pPage */ + int rc; /* Return code */ + BtShared *pBt = pPage->pBt; + Pgno pgno = pPage->pgno; + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + rc = pPage->isInit ? SQLITE_OK : btreeInitPage(pPage); + if( rc!=SQLITE_OK ) return rc; + nCell = pPage->nCell; + + for(i=0; ileaf ){ + Pgno childPgno = get4byte(pCell); + ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno, &rc); + } + } + + if( !pPage->leaf ){ + Pgno childPgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); + ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno, &rc); + } + + return rc; +} + +/* +** Somewhere on pPage is a pointer to page iFrom. Modify this pointer so +** that it points to iTo. Parameter eType describes the type of pointer to +** be modified, as follows: +** +** PTRMAP_BTREE: pPage is a btree-page. The pointer points at a child +** page of pPage. +** +** PTRMAP_OVERFLOW1: pPage is a btree-page. The pointer points at an overflow +** page pointed to by one of the cells on pPage. +** +** PTRMAP_OVERFLOW2: pPage is an overflow-page. The pointer points at the next +** overflow page in the list. +*/ +static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){ + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + if( eType==PTRMAP_OVERFLOW2 ){ + /* The pointer is always the first 4 bytes of the page in this case. */ + if( get4byte(pPage->aData)!=iFrom ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + put4byte(pPage->aData, iTo); + }else{ + int i; + int nCell; + int rc; + + rc = pPage->isInit ? SQLITE_OK : btreeInitPage(pPage); + if( rc ) return rc; + nCell = pPage->nCell; + + for(i=0; ixParseCell(pPage, pCell, &info); + if( info.nLocal pPage->aData+pPage->pBt->usableSize ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + if( iFrom==get4byte(pCell+info.nSize-4) ){ + put4byte(pCell+info.nSize-4, iTo); + break; + } + } + }else{ + if( pCell+4 > pPage->aData+pPage->pBt->usableSize ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + if( get4byte(pCell)==iFrom ){ + put4byte(pCell, iTo); + break; + } + } + } + + if( i==nCell ){ + if( eType!=PTRMAP_BTREE || + get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + put4byte(&pPage->aData[pPage->hdrOffset+8], iTo); + } + } + return SQLITE_OK; +} + + +/* +** Move the open database page pDbPage to location iFreePage in the +** database. The pDbPage reference remains valid. +** +** The isCommit flag indicates that there is no need to remember that +** the journal needs to be sync()ed before database page pDbPage->pgno +** can be written to. The caller has already promised not to write to that +** page. +*/ +static int relocatePage( + BtShared *pBt, /* Btree */ + MemPage *pDbPage, /* Open page to move */ + u8 eType, /* Pointer map 'type' entry for pDbPage */ + Pgno iPtrPage, /* Pointer map 'page-no' entry for pDbPage */ + Pgno iFreePage, /* The location to move pDbPage to */ + int isCommit /* isCommit flag passed to sqlite3PagerMovepage */ +){ + MemPage *pPtrPage; /* The page that contains a pointer to pDbPage */ + Pgno iDbPage = pDbPage->pgno; + Pager *pPager = pBt->pPager; + int rc; + + assert( eType==PTRMAP_OVERFLOW2 || eType==PTRMAP_OVERFLOW1 || + eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ); + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( pDbPage->pBt==pBt ); + if( iDbPage<3 ) return SQLITE_CORRUPT_BKPT; + + /* Move page iDbPage from its current location to page number iFreePage */ + TRACE(("AUTOVACUUM: Moving %u to free page %u (ptr page %u type %u)\n", + iDbPage, iFreePage, iPtrPage, eType)); + rc = sqlite3PagerMovepage(pPager, pDbPage->pDbPage, iFreePage, isCommit); + if( rc!=SQLITE_OK ){ + return rc; + } + pDbPage->pgno = iFreePage; + + /* If pDbPage was a btree-page, then it may have child pages and/or cells + ** that point to overflow pages. The pointer map entries for all these + ** pages need to be changed. + ** + ** If pDbPage is an overflow page, then the first 4 bytes may store a + ** pointer to a subsequent overflow page. If this is the case, then + ** the pointer map needs to be updated for the subsequent overflow page. + */ + if( eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ){ + rc = setChildPtrmaps(pDbPage); + if( rc!=SQLITE_OK ){ + return rc; + } + }else{ + Pgno nextOvfl = get4byte(pDbPage->aData); + if( nextOvfl!=0 ){ + ptrmapPut(pBt, nextOvfl, PTRMAP_OVERFLOW2, iFreePage, &rc); + if( rc!=SQLITE_OK ){ + return rc; + } + } + } + + /* Fix the database pointer on page iPtrPage that pointed at iDbPage so + ** that it points at iFreePage. Also fix the pointer map entry for + ** iPtrPage. + */ + if( eType!=PTRMAP_ROOTPAGE ){ + rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = sqlite3PagerWrite(pPtrPage->pDbPage); + if( rc!=SQLITE_OK ){ + releasePage(pPtrPage); + return rc; + } + rc = modifyPagePointer(pPtrPage, iDbPage, iFreePage, eType); + releasePage(pPtrPage); + if( rc==SQLITE_OK ){ + ptrmapPut(pBt, iFreePage, eType, iPtrPage, &rc); + } + } + return rc; +} + +/* Forward declaration required by incrVacuumStep(). */ +static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8); + +/* +** Perform a single step of an incremental-vacuum. If successful, return +** SQLITE_OK. If there is no work to do (and therefore no point in +** calling this function again), return SQLITE_DONE. Or, if an error +** occurs, return some other error code. +** +** More specifically, this function attempts to re-organize the database so +** that the last page of the file currently in use is no longer in use. +** +** Parameter nFin is the number of pages that this database would contain +** were this function called until it returns SQLITE_DONE. +** +** If the bCommit parameter is non-zero, this function assumes that the +** caller will keep calling incrVacuumStep() until it returns SQLITE_DONE +** or an error. bCommit is passed true for an auto-vacuum-on-commit +** operation, or false for an incremental vacuum. +*/ +static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg, int bCommit){ + Pgno nFreeList; /* Number of pages still on the free-list */ + int rc; + + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( iLastPg>nFin ); + + if( !PTRMAP_ISPAGE(pBt, iLastPg) && iLastPg!=PENDING_BYTE_PAGE(pBt) ){ + u8 eType; + Pgno iPtrPage; + + nFreeList = get4byte(&pBt->pPage1->aData[36]); + if( nFreeList==0 ){ + return SQLITE_DONE; + } + + rc = ptrmapGet(pBt, iLastPg, &eType, &iPtrPage); + if( rc!=SQLITE_OK ){ + return rc; + } + if( eType==PTRMAP_ROOTPAGE ){ + return SQLITE_CORRUPT_BKPT; + } + + if( eType==PTRMAP_FREEPAGE ){ + if( bCommit==0 ){ + /* Remove the page from the files free-list. This is not required + ** if bCommit is non-zero. In that case, the free-list will be + ** truncated to zero after this function returns, so it doesn't + ** matter if it still contains some garbage entries. + */ + Pgno iFreePg; + MemPage *pFreePg; + rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iLastPg, BTALLOC_EXACT); + if( rc!=SQLITE_OK ){ + return rc; + } + assert( iFreePg==iLastPg ); + releasePage(pFreePg); + } + } else { + Pgno iFreePg; /* Index of free page to move pLastPg to */ + MemPage *pLastPg; + u8 eMode = BTALLOC_ANY; /* Mode parameter for allocateBtreePage() */ + Pgno iNear = 0; /* nearby parameter for allocateBtreePage() */ + + rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + + /* If bCommit is zero, this loop runs exactly once and page pLastPg + ** is swapped with the first free page pulled off the free list. + ** + ** On the other hand, if bCommit is greater than zero, then keep + ** looping until a free-page located within the first nFin pages + ** of the file is found. + */ + if( bCommit==0 ){ + eMode = BTALLOC_LE; + iNear = nFin; + } + do { + MemPage *pFreePg; + Pgno dbSize = btreePagecount(pBt); + rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iNear, eMode); + if( rc!=SQLITE_OK ){ + releasePage(pLastPg); + return rc; + } + releasePage(pFreePg); + if( iFreePg>dbSize ){ + releasePage(pLastPg); + return SQLITE_CORRUPT_BKPT; + } + }while( bCommit && iFreePg>nFin ); + assert( iFreePgbDoTruncate = 1; + pBt->nPage = iLastPg; + } + return SQLITE_OK; +} + +/* +** The database opened by the first argument is an auto-vacuum database +** nOrig pages in size containing nFree free pages. Return the expected +** size of the database in pages following an auto-vacuum operation. +*/ +static Pgno finalDbSize(BtShared *pBt, Pgno nOrig, Pgno nFree){ + int nEntry; /* Number of entries on one ptrmap page */ + Pgno nPtrmap; /* Number of PtrMap pages to be freed */ + Pgno nFin; /* Return value */ + + nEntry = pBt->usableSize/5; + nPtrmap = (nFree-nOrig+PTRMAP_PAGENO(pBt, nOrig)+nEntry)/nEntry; + nFin = nOrig - nFree - nPtrmap; + if( nOrig>PENDING_BYTE_PAGE(pBt) && nFinpBt; + + sqlite3BtreeEnter(p); + assert( pBt->inTransaction==TRANS_WRITE && p->inTrans==TRANS_WRITE ); + if( !pBt->autoVacuum ){ + rc = SQLITE_DONE; + }else{ + Pgno nOrig = btreePagecount(pBt); + Pgno nFree = get4byte(&pBt->pPage1->aData[36]); + Pgno nFin = finalDbSize(pBt, nOrig, nFree); + + if( nOrig=nOrig ){ + rc = SQLITE_CORRUPT_BKPT; + }else if( nFree>0 ){ + rc = saveAllCursors(pBt, 0, 0); + if( rc==SQLITE_OK ){ + invalidateAllOverflowCache(pBt); + rc = incrVacuumStep(pBt, nFin, nOrig, 0); + } + if( rc==SQLITE_OK ){ + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + put4byte(&pBt->pPage1->aData[28], pBt->nPage); + } + }else{ + rc = SQLITE_DONE; + } + } + sqlite3BtreeLeave(p); + return rc; +} + +/* +** This routine is called prior to sqlite3PagerCommit when a transaction +** is committed for an auto-vacuum database. +*/ +static int autoVacuumCommit(Btree *p){ + int rc = SQLITE_OK; + Pager *pPager; + BtShared *pBt; + sqlite3 *db; + VVA_ONLY( int nRef ); + + assert( p!=0 ); + pBt = p->pBt; + pPager = pBt->pPager; + VVA_ONLY( nRef = sqlite3PagerRefcount(pPager); ) + + assert( sqlite3_mutex_held(pBt->mutex) ); + invalidateAllOverflowCache(pBt); + assert(pBt->autoVacuum); + if( !pBt->incrVacuum ){ + Pgno nFin; /* Number of pages in database after autovacuuming */ + Pgno nFree; /* Number of pages on the freelist initially */ + Pgno nVac; /* Number of pages to vacuum */ + Pgno iFree; /* The next page to be freed */ + Pgno nOrig; /* Database size before freeing */ + + nOrig = btreePagecount(pBt); + if( PTRMAP_ISPAGE(pBt, nOrig) || nOrig==PENDING_BYTE_PAGE(pBt) ){ + /* It is not possible to create a database for which the final page + ** is either a pointer-map page or the pending-byte page. If one + ** is encountered, this indicates corruption. + */ + return SQLITE_CORRUPT_BKPT; + } + + nFree = get4byte(&pBt->pPage1->aData[36]); + db = p->db; + if( db->xAutovacPages ){ + int iDb; + for(iDb=0; ALWAYS(iDbnDb); iDb++){ + if( db->aDb[iDb].pBt==p ) break; + } + nVac = db->xAutovacPages( + db->pAutovacPagesArg, + db->aDb[iDb].zDbSName, + nOrig, + nFree, + pBt->pageSize + ); + if( nVac>nFree ){ + nVac = nFree; + } + if( nVac==0 ){ + return SQLITE_OK; + } + }else{ + nVac = nFree; + } + nFin = finalDbSize(pBt, nOrig, nVac); + if( nFin>nOrig ) return SQLITE_CORRUPT_BKPT; + if( nFinnFin && rc==SQLITE_OK; iFree--){ + rc = incrVacuumStep(pBt, nFin, iFree, nVac==nFree); + } + if( (rc==SQLITE_DONE || rc==SQLITE_OK) && nFree>0 ){ + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + if( nVac==nFree ){ + put4byte(&pBt->pPage1->aData[32], 0); + put4byte(&pBt->pPage1->aData[36], 0); + } + put4byte(&pBt->pPage1->aData[28], nFin); + pBt->bDoTruncate = 1; + pBt->nPage = nFin; + } + if( rc!=SQLITE_OK ){ + sqlite3PagerRollback(pPager); + } + } + + assert( nRef>=sqlite3PagerRefcount(pPager) ); + return rc; +} + +#else /* ifndef SQLITE_OMIT_AUTOVACUUM */ +# define setChildPtrmaps(x) SQLITE_OK +#endif + +/* +** This routine does the first phase of a two-phase commit. This routine +** causes a rollback journal to be created (if it does not already exist) +** and populated with enough information so that if a power loss occurs +** the database can be restored to its original state by playing back +** the journal. Then the contents of the journal are flushed out to +** the disk. After the journal is safely on oxide, the changes to the +** database are written into the database file and flushed to oxide. +** At the end of this call, the rollback journal still exists on the +** disk and we are still holding all locks, so the transaction has not +** committed. See sqlite3BtreeCommitPhaseTwo() for the second phase of the +** commit process. +** +** This call is a no-op if no write-transaction is currently active on pBt. +** +** Otherwise, sync the database file for the btree pBt. zSuperJrnl points to +** the name of a super-journal file that should be written into the +** individual journal file, or is NULL, indicating no super-journal file +** (single database transaction). +** +** When this is called, the super-journal should already have been +** created, populated with this journal pointer and synced to disk. +** +** Once this is routine has returned, the only thing required to commit +** the write-transaction for this database file is to delete the journal. +*/ +SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zSuperJrnl){ + int rc = SQLITE_OK; + if( p->inTrans==TRANS_WRITE ){ + BtShared *pBt = p->pBt; + sqlite3BtreeEnter(p); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + rc = autoVacuumCommit(p); + if( rc!=SQLITE_OK ){ + sqlite3BtreeLeave(p); + return rc; + } + } + if( pBt->bDoTruncate ){ + sqlite3PagerTruncateImage(pBt->pPager, pBt->nPage); + } +#endif + rc = sqlite3PagerCommitPhaseOne(pBt->pPager, zSuperJrnl, 0); + sqlite3BtreeLeave(p); + } + return rc; +} + +/* +** This function is called from both BtreeCommitPhaseTwo() and BtreeRollback() +** at the conclusion of a transaction. +*/ +static void btreeEndTransaction(Btree *p){ + BtShared *pBt = p->pBt; + sqlite3 *db = p->db; + assert( sqlite3BtreeHoldsMutex(p) ); + +#ifndef SQLITE_OMIT_AUTOVACUUM + pBt->bDoTruncate = 0; +#endif + if( p->inTrans>TRANS_NONE && db->nVdbeRead>1 ){ + /* If there are other active statements that belong to this database + ** handle, downgrade to a read-only transaction. The other statements + ** may still be reading from the database. */ + downgradeAllSharedCacheTableLocks(p); + p->inTrans = TRANS_READ; + }else{ + /* If the handle had any kind of transaction open, decrement the + ** transaction count of the shared btree. If the transaction count + ** reaches 0, set the shared state to TRANS_NONE. The unlockBtreeIfUnused() + ** call below will unlock the pager. */ + if( p->inTrans!=TRANS_NONE ){ + clearAllSharedCacheTableLocks(p); + pBt->nTransaction--; + if( 0==pBt->nTransaction ){ + pBt->inTransaction = TRANS_NONE; + } + } + + /* Set the current transaction state to TRANS_NONE and unlock the + ** pager if this call closed the only read or write transaction. */ + p->inTrans = TRANS_NONE; + unlockBtreeIfUnused(pBt); + } + + btreeIntegrity(p); +} + +/* +** Commit the transaction currently in progress. +** +** This routine implements the second phase of a 2-phase commit. The +** sqlite3BtreeCommitPhaseOne() routine does the first phase and should +** be invoked prior to calling this routine. The sqlite3BtreeCommitPhaseOne() +** routine did all the work of writing information out to disk and flushing the +** contents so that they are written onto the disk platter. All this +** routine has to do is delete or truncate or zero the header in the +** the rollback journal (which causes the transaction to commit) and +** drop locks. +** +** Normally, if an error occurs while the pager layer is attempting to +** finalize the underlying journal file, this function returns an error and +** the upper layer will attempt a rollback. However, if the second argument +** is non-zero then this b-tree transaction is part of a multi-file +** transaction. In this case, the transaction has already been committed +** (by deleting a super-journal file) and the caller will ignore this +** functions return code. So, even if an error occurs in the pager layer, +** reset the b-tree objects internal state to indicate that the write +** transaction has been closed. This is quite safe, as the pager will have +** transitioned to the error state. +** +** This will release the write lock on the database file. If there +** are no active cursors, it also releases the read lock. +*/ +SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree *p, int bCleanup){ + + if( p->inTrans==TRANS_NONE ) return SQLITE_OK; + sqlite3BtreeEnter(p); + btreeIntegrity(p); + + /* If the handle has a write-transaction open, commit the shared-btrees + ** transaction and set the shared state to TRANS_READ. + */ + if( p->inTrans==TRANS_WRITE ){ + int rc; + BtShared *pBt = p->pBt; + assert( pBt->inTransaction==TRANS_WRITE ); + assert( pBt->nTransaction>0 ); + rc = sqlite3PagerCommitPhaseTwo(pBt->pPager); + if( rc!=SQLITE_OK && bCleanup==0 ){ + sqlite3BtreeLeave(p); + return rc; + } + p->iBDataVersion--; /* Compensate for pPager->iDataVersion++; */ + pBt->inTransaction = TRANS_READ; + btreeClearHasContent(pBt); + } + + btreeEndTransaction(p); + sqlite3BtreeLeave(p); + return SQLITE_OK; +} + +/* +** Do both phases of a commit. +*/ +SQLITE_PRIVATE int sqlite3BtreeCommit(Btree *p){ + int rc; + sqlite3BtreeEnter(p); + rc = sqlite3BtreeCommitPhaseOne(p, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeCommitPhaseTwo(p, 0); + } + sqlite3BtreeLeave(p); + return rc; +} + +/* +** This routine sets the state to CURSOR_FAULT and the error +** code to errCode for every cursor on any BtShared that pBtree +** references. Or if the writeOnly flag is set to 1, then only +** trip write cursors and leave read cursors unchanged. +** +** Every cursor is a candidate to be tripped, including cursors +** that belong to other database connections that happen to be +** sharing the cache with pBtree. +** +** This routine gets called when a rollback occurs. If the writeOnly +** flag is true, then only write-cursors need be tripped - read-only +** cursors save their current positions so that they may continue +** following the rollback. Or, if writeOnly is false, all cursors are +** tripped. In general, writeOnly is false if the transaction being +** rolled back modified the database schema. In this case b-tree root +** pages may be moved or deleted from the database altogether, making +** it unsafe for read cursors to continue. +** +** If the writeOnly flag is true and an error is encountered while +** saving the current position of a read-only cursor, all cursors, +** including all read-cursors are tripped. +** +** SQLITE_OK is returned if successful, or if an error occurs while +** saving a cursor position, an SQLite error code. +*/ +SQLITE_PRIVATE int sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode, int writeOnly){ + BtCursor *p; + int rc = SQLITE_OK; + + assert( (writeOnly==0 || writeOnly==1) && BTCF_WriteFlag==1 ); + if( pBtree ){ + sqlite3BtreeEnter(pBtree); + for(p=pBtree->pBt->pCursor; p; p=p->pNext){ + if( writeOnly && (p->curFlags & BTCF_WriteFlag)==0 ){ + if( p->eState==CURSOR_VALID || p->eState==CURSOR_SKIPNEXT ){ + rc = saveCursorPosition(p); + if( rc!=SQLITE_OK ){ + (void)sqlite3BtreeTripAllCursors(pBtree, rc, 0); + break; + } + } + }else{ + sqlite3BtreeClearCursor(p); + p->eState = CURSOR_FAULT; + p->skipNext = errCode; + } + btreeReleaseAllCursorPages(p); + } + sqlite3BtreeLeave(pBtree); + } + return rc; +} + +/* +** Set the pBt->nPage field correctly, according to the current +** state of the database. Assume pBt->pPage1 is valid. +*/ +static void btreeSetNPage(BtShared *pBt, MemPage *pPage1){ + int nPage = get4byte(&pPage1->aData[28]); + testcase( nPage==0 ); + if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage); + testcase( pBt->nPage!=(u32)nPage ); + pBt->nPage = nPage; +} + +/* +** Rollback the transaction in progress. +** +** If tripCode is not SQLITE_OK then cursors will be invalidated (tripped). +** Only write cursors are tripped if writeOnly is true but all cursors are +** tripped if writeOnly is false. Any attempt to use +** a tripped cursor will result in an error. +** +** This will release the write lock on the database file. If there +** are no active cursors, it also releases the read lock. +*/ +SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p, int tripCode, int writeOnly){ + int rc; + BtShared *pBt = p->pBt; + MemPage *pPage1; + + assert( writeOnly==1 || writeOnly==0 ); + assert( tripCode==SQLITE_ABORT_ROLLBACK || tripCode==SQLITE_OK ); + sqlite3BtreeEnter(p); + if( tripCode==SQLITE_OK ){ + rc = tripCode = saveAllCursors(pBt, 0, 0); + if( rc ) writeOnly = 0; + }else{ + rc = SQLITE_OK; + } + if( tripCode ){ + int rc2 = sqlite3BtreeTripAllCursors(p, tripCode, writeOnly); + assert( rc==SQLITE_OK || (writeOnly==0 && rc2==SQLITE_OK) ); + if( rc2!=SQLITE_OK ) rc = rc2; + } + btreeIntegrity(p); + + if( p->inTrans==TRANS_WRITE ){ + int rc2; + + assert( TRANS_WRITE==pBt->inTransaction ); + rc2 = sqlite3PagerRollback(pBt->pPager); + if( rc2!=SQLITE_OK ){ + rc = rc2; + } + + /* The rollback may have destroyed the pPage1->aData value. So + ** call btreeGetPage() on page 1 again to make + ** sure pPage1->aData is set correctly. */ + if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){ + btreeSetNPage(pBt, pPage1); + releasePageOne(pPage1); + } + assert( countValidCursors(pBt, 1)==0 ); + pBt->inTransaction = TRANS_READ; + btreeClearHasContent(pBt); + } + + btreeEndTransaction(p); + sqlite3BtreeLeave(p); + return rc; +} + +/* +** Start a statement subtransaction. The subtransaction can be rolled +** back independently of the main transaction. You must start a transaction +** before starting a subtransaction. The subtransaction is ended automatically +** if the main transaction commits or rolls back. +** +** Statement subtransactions are used around individual SQL statements +** that are contained within a BEGIN...COMMIT block. If a constraint +** error occurs within the statement, the effect of that one statement +** can be rolled back without having to rollback the entire transaction. +** +** A statement sub-transaction is implemented as an anonymous savepoint. The +** value passed as the second parameter is the total number of savepoints, +** including the new anonymous savepoint, open on the B-Tree. i.e. if there +** are no active savepoints and no other statement-transactions open, +** iStatement is 1. This anonymous savepoint can be released or rolled back +** using the sqlite3BtreeSavepoint() function. +*/ +SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree *p, int iStatement){ + int rc; + BtShared *pBt = p->pBt; + sqlite3BtreeEnter(p); + assert( p->inTrans==TRANS_WRITE ); + assert( (pBt->btsFlags & BTS_READ_ONLY)==0 ); + assert( iStatement>0 ); + assert( iStatement>p->db->nSavepoint ); + assert( pBt->inTransaction==TRANS_WRITE ); + /* At the pager level, a statement transaction is a savepoint with + ** an index greater than all savepoints created explicitly using + ** SQL statements. It is illegal to open, release or rollback any + ** such savepoints while the statement transaction savepoint is active. + */ + rc = sqlite3PagerOpenSavepoint(pBt->pPager, iStatement); + sqlite3BtreeLeave(p); + return rc; +} + +/* +** The second argument to this function, op, is always SAVEPOINT_ROLLBACK +** or SAVEPOINT_RELEASE. This function either releases or rolls back the +** savepoint identified by parameter iSavepoint, depending on the value +** of op. +** +** Normally, iSavepoint is greater than or equal to zero. However, if op is +** SAVEPOINT_ROLLBACK, then iSavepoint may also be -1. In this case the +** contents of the entire transaction are rolled back. This is different +** from a normal transaction rollback, as no locks are released and the +** transaction remains open. +*/ +SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){ + int rc = SQLITE_OK; + if( p && p->inTrans==TRANS_WRITE ){ + BtShared *pBt = p->pBt; + assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK ); + assert( iSavepoint>=0 || (iSavepoint==-1 && op==SAVEPOINT_ROLLBACK) ); + sqlite3BtreeEnter(p); + if( op==SAVEPOINT_ROLLBACK ){ + rc = saveAllCursors(pBt, 0, 0); + } + if( rc==SQLITE_OK ){ + rc = sqlite3PagerSavepoint(pBt->pPager, op, iSavepoint); + } + if( rc==SQLITE_OK ){ + if( iSavepoint<0 && (pBt->btsFlags & BTS_INITIALLY_EMPTY)!=0 ){ + pBt->nPage = 0; + } + rc = newDatabase(pBt); + btreeSetNPage(pBt, pBt->pPage1); + + /* pBt->nPage might be zero if the database was corrupt when + ** the transaction was started. Otherwise, it must be at least 1. */ + assert( CORRUPT_DB || pBt->nPage>0 ); + } + sqlite3BtreeLeave(p); + } + return rc; +} + +/* +** Create a new cursor for the BTree whose root is on the page +** iTable. If a read-only cursor is requested, it is assumed that +** the caller already has at least a read-only transaction open +** on the database already. If a write-cursor is requested, then +** the caller is assumed to have an open write transaction. +** +** If the BTREE_WRCSR bit of wrFlag is clear, then the cursor can only +** be used for reading. If the BTREE_WRCSR bit is set, then the cursor +** can be used for reading or for writing if other conditions for writing +** are also met. These are the conditions that must be met in order +** for writing to be allowed: +** +** 1: The cursor must have been opened with wrFlag containing BTREE_WRCSR +** +** 2: Other database connections that share the same pager cache +** but which are not in the READ_UNCOMMITTED state may not have +** cursors open with wrFlag==0 on the same table. Otherwise +** the changes made by this write cursor would be visible to +** the read cursors in the other database connection. +** +** 3: The database must be writable (not on read-only media) +** +** 4: There must be an active transaction. +** +** The BTREE_FORDELETE bit of wrFlag may optionally be set if BTREE_WRCSR +** is set. If FORDELETE is set, that is a hint to the implementation that +** this cursor will only be used to seek to and delete entries of an index +** as part of a larger DELETE statement. The FORDELETE hint is not used by +** this implementation. But in a hypothetical alternative storage engine +** in which index entries are automatically deleted when corresponding table +** rows are deleted, the FORDELETE flag is a hint that all SEEK and DELETE +** operations on this cursor can be no-ops and all READ operations can +** return a null row (2-bytes: 0x01 0x00). +** +** No checking is done to make sure that page iTable really is the +** root page of a b-tree. If it is not, then the cursor acquired +** will not work correctly. +** +** It is assumed that the sqlite3BtreeCursorZero() has been called +** on pCur to initialize the memory space prior to invoking this routine. +*/ +static int btreeCursor( + Btree *p, /* The btree */ + Pgno iTable, /* Root page of table to open */ + int wrFlag, /* 1 to write. 0 read-only */ + struct KeyInfo *pKeyInfo, /* First arg to comparison function */ + BtCursor *pCur /* Space for new cursor */ +){ + BtShared *pBt = p->pBt; /* Shared b-tree handle */ + BtCursor *pX; /* Looping over other all cursors */ + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( wrFlag==0 + || wrFlag==BTREE_WRCSR + || wrFlag==(BTREE_WRCSR|BTREE_FORDELETE) + ); + + /* The following assert statements verify that if this is a sharable + ** b-tree database, the connection is holding the required table locks, + ** and that no other connection has any open cursor that conflicts with + ** this lock. The iTable<1 term disables the check for corrupt schemas. */ + assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, (wrFlag?2:1)) + || iTable<1 ); + assert( wrFlag==0 || !hasReadConflicts(p, iTable) ); + + /* Assert that the caller has opened the required transaction. */ + assert( p->inTrans>TRANS_NONE ); + assert( wrFlag==0 || p->inTrans==TRANS_WRITE ); + assert( pBt->pPage1 && pBt->pPage1->aData ); + assert( wrFlag==0 || (pBt->btsFlags & BTS_READ_ONLY)==0 ); + + if( iTable<=1 ){ + if( iTable<1 ){ + return SQLITE_CORRUPT_BKPT; + }else if( btreePagecount(pBt)==0 ){ + assert( wrFlag==0 ); + iTable = 0; + } + } + + /* Now that no other errors can occur, finish filling in the BtCursor + ** variables and link the cursor into the BtShared list. */ + pCur->pgnoRoot = iTable; + pCur->iPage = -1; + pCur->pKeyInfo = pKeyInfo; + pCur->pBtree = p; + pCur->pBt = pBt; + pCur->curFlags = 0; + /* If there are two or more cursors on the same btree, then all such + ** cursors *must* have the BTCF_Multiple flag set. */ + for(pX=pBt->pCursor; pX; pX=pX->pNext){ + if( pX->pgnoRoot==iTable ){ + pX->curFlags |= BTCF_Multiple; + pCur->curFlags = BTCF_Multiple; + } + } + pCur->eState = CURSOR_INVALID; + pCur->pNext = pBt->pCursor; + pBt->pCursor = pCur; + if( wrFlag ){ + pCur->curFlags |= BTCF_WriteFlag; + pCur->curPagerFlags = 0; + if( pBt->pTmpSpace==0 ) return allocateTempSpace(pBt); + }else{ + pCur->curPagerFlags = PAGER_GET_READONLY; + } + return SQLITE_OK; +} +static int btreeCursorWithLock( + Btree *p, /* The btree */ + Pgno iTable, /* Root page of table to open */ + int wrFlag, /* 1 to write. 0 read-only */ + struct KeyInfo *pKeyInfo, /* First arg to comparison function */ + BtCursor *pCur /* Space for new cursor */ +){ + int rc; + sqlite3BtreeEnter(p); + rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur); + sqlite3BtreeLeave(p); + return rc; +} +SQLITE_PRIVATE int sqlite3BtreeCursor( + Btree *p, /* The btree */ + Pgno iTable, /* Root page of table to open */ + int wrFlag, /* 1 to write. 0 read-only */ + struct KeyInfo *pKeyInfo, /* First arg to xCompare() */ + BtCursor *pCur /* Write new cursor here */ +){ + if( p->sharable ){ + return btreeCursorWithLock(p, iTable, wrFlag, pKeyInfo, pCur); + }else{ + return btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur); + } +} + +/* +** Return the size of a BtCursor object in bytes. +** +** This interfaces is needed so that users of cursors can preallocate +** sufficient storage to hold a cursor. The BtCursor object is opaque +** to users so they cannot do the sizeof() themselves - they must call +** this routine. +*/ +SQLITE_PRIVATE int sqlite3BtreeCursorSize(void){ + return ROUND8(sizeof(BtCursor)); +} + +#ifdef SQLITE_DEBUG +/* +** Return true if and only if the Btree object will be automatically +** closed with the BtCursor closes. This is used within assert() statements +** only. +*/ +SQLITE_PRIVATE int sqlite3BtreeClosesWithCursor( + Btree *pBtree, /* the btree object */ + BtCursor *pCur /* Corresponding cursor */ +){ + BtShared *pBt = pBtree->pBt; + if( (pBt->openFlags & BTREE_SINGLE)==0 ) return 0; + if( pBt->pCursor!=pCur ) return 0; + if( pCur->pNext!=0 ) return 0; + if( pCur->pBtree!=pBtree ) return 0; + return 1; +} +#endif + +/* +** Initialize memory that will be converted into a BtCursor object. +** +** The simple approach here would be to memset() the entire object +** to zero. But it turns out that the apPage[] and aiIdx[] arrays +** do not need to be zeroed and they are large, so we can save a lot +** of run-time by skipping the initialization of those elements. +*/ +SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor *p){ + memset(p, 0, offsetof(BtCursor, BTCURSOR_FIRST_UNINIT)); +} + +/* +** Close a cursor. The read lock on the database file is released +** when the last cursor is closed. +*/ +SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){ + Btree *pBtree = pCur->pBtree; + if( pBtree ){ + BtShared *pBt = pCur->pBt; + sqlite3BtreeEnter(pBtree); + assert( pBt->pCursor!=0 ); + if( pBt->pCursor==pCur ){ + pBt->pCursor = pCur->pNext; + }else{ + BtCursor *pPrev = pBt->pCursor; + do{ + if( pPrev->pNext==pCur ){ + pPrev->pNext = pCur->pNext; + break; + } + pPrev = pPrev->pNext; + }while( ALWAYS(pPrev) ); + } + btreeReleaseAllCursorPages(pCur); + unlockBtreeIfUnused(pBt); + sqlite3_free(pCur->aOverflow); + sqlite3_free(pCur->pKey); + if( (pBt->openFlags & BTREE_SINGLE) && pBt->pCursor==0 ){ + /* Since the BtShared is not sharable, there is no need to + ** worry about the missing sqlite3BtreeLeave() call here. */ + assert( pBtree->sharable==0 ); + sqlite3BtreeClose(pBtree); + }else{ + sqlite3BtreeLeave(pBtree); + } + pCur->pBtree = 0; + } + return SQLITE_OK; +} + +/* +** Make sure the BtCursor* given in the argument has a valid +** BtCursor.info structure. If it is not already valid, call +** btreeParseCell() to fill it in. +** +** BtCursor.info is a cache of the information in the current cell. +** Using this cache reduces the number of calls to btreeParseCell(). +*/ +#ifndef NDEBUG + static int cellInfoEqual(CellInfo *a, CellInfo *b){ + if( a->nKey!=b->nKey ) return 0; + if( a->pPayload!=b->pPayload ) return 0; + if( a->nPayload!=b->nPayload ) return 0; + if( a->nLocal!=b->nLocal ) return 0; + if( a->nSize!=b->nSize ) return 0; + return 1; + } + static void assertCellInfo(BtCursor *pCur){ + CellInfo info; + memset(&info, 0, sizeof(info)); + btreeParseCell(pCur->pPage, pCur->ix, &info); + assert( CORRUPT_DB || cellInfoEqual(&info, &pCur->info) ); + } +#else + #define assertCellInfo(x) +#endif +static SQLITE_NOINLINE void getCellInfo(BtCursor *pCur){ + if( pCur->info.nSize==0 ){ + pCur->curFlags |= BTCF_ValidNKey; + btreeParseCell(pCur->pPage,pCur->ix,&pCur->info); + }else{ + assertCellInfo(pCur); + } +} + +#ifndef NDEBUG /* The next routine used only within assert() statements */ +/* +** Return true if the given BtCursor is valid. A valid cursor is one +** that is currently pointing to a row in a (non-empty) table. +** This is a verification routine is used only within assert() statements. +*/ +SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor *pCur){ + return pCur && pCur->eState==CURSOR_VALID; +} +#endif /* NDEBUG */ +SQLITE_PRIVATE int sqlite3BtreeCursorIsValidNN(BtCursor *pCur){ + assert( pCur!=0 ); + return pCur->eState==CURSOR_VALID; +} + +/* +** Return the value of the integer key or "rowid" for a table btree. +** This routine is only valid for a cursor that is pointing into a +** ordinary table btree. If the cursor points to an index btree or +** is invalid, the result of this routine is undefined. +*/ +SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor *pCur){ + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + assert( pCur->curIntKey ); + getCellInfo(pCur); + return pCur->info.nKey; +} + +/* +** Pin or unpin a cursor. +*/ +SQLITE_PRIVATE void sqlite3BtreeCursorPin(BtCursor *pCur){ + assert( (pCur->curFlags & BTCF_Pinned)==0 ); + pCur->curFlags |= BTCF_Pinned; +} +SQLITE_PRIVATE void sqlite3BtreeCursorUnpin(BtCursor *pCur){ + assert( (pCur->curFlags & BTCF_Pinned)!=0 ); + pCur->curFlags &= ~BTCF_Pinned; +} + +/* +** Return the offset into the database file for the start of the +** payload to which the cursor is pointing. +*/ +SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor *pCur){ + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + getCellInfo(pCur); + return (i64)pCur->pBt->pageSize*((i64)pCur->pPage->pgno - 1) + + (i64)(pCur->info.pPayload - pCur->pPage->aData); +} + +/* +** Return the number of bytes of payload for the entry that pCur is +** currently pointing to. For table btrees, this will be the amount +** of data. For index btrees, this will be the size of the key. +** +** The caller must guarantee that the cursor is pointing to a non-NULL +** valid entry. In other words, the calling procedure must guarantee +** that the cursor has Cursor.eState==CURSOR_VALID. +*/ +SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor *pCur){ + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + getCellInfo(pCur); + return pCur->info.nPayload; +} + +/* +** Return an upper bound on the size of any record for the table +** that the cursor is pointing into. +** +** This is an optimization. Everything will still work if this +** routine always returns 2147483647 (which is the largest record +** that SQLite can handle) or more. But returning a smaller value might +** prevent large memory allocations when trying to interpret a +** corrupt database. +** +** The current implementation merely returns the size of the underlying +** database file. +*/ +SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor *pCur){ + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + return pCur->pBt->pageSize * (sqlite3_int64)pCur->pBt->nPage; +} + +/* +** Given the page number of an overflow page in the database (parameter +** ovfl), this function finds the page number of the next page in the +** linked list of overflow pages. If possible, it uses the auto-vacuum +** pointer-map data instead of reading the content of page ovfl to do so. +** +** If an error occurs an SQLite error code is returned. Otherwise: +** +** The page number of the next overflow page in the linked list is +** written to *pPgnoNext. If page ovfl is the last page in its linked +** list, *pPgnoNext is set to zero. +** +** If ppPage is not NULL, and a reference to the MemPage object corresponding +** to page number pOvfl was obtained, then *ppPage is set to point to that +** reference. It is the responsibility of the caller to call releasePage() +** on *ppPage to free the reference. In no reference was obtained (because +** the pointer-map was used to obtain the value for *pPgnoNext), then +** *ppPage is set to zero. +*/ +static int getOverflowPage( + BtShared *pBt, /* The database file */ + Pgno ovfl, /* Current overflow page number */ + MemPage **ppPage, /* OUT: MemPage handle (may be NULL) */ + Pgno *pPgnoNext /* OUT: Next overflow page number */ +){ + Pgno next = 0; + MemPage *pPage = 0; + int rc = SQLITE_OK; + + assert( sqlite3_mutex_held(pBt->mutex) ); + assert(pPgnoNext); + +#ifndef SQLITE_OMIT_AUTOVACUUM + /* Try to find the next page in the overflow list using the + ** autovacuum pointer-map pages. Guess that the next page in + ** the overflow list is page number (ovfl+1). If that guess turns + ** out to be wrong, fall back to loading the data of page + ** number ovfl to determine the next page number. + */ + if( pBt->autoVacuum ){ + Pgno pgno; + Pgno iGuess = ovfl+1; + u8 eType; + + while( PTRMAP_ISPAGE(pBt, iGuess) || iGuess==PENDING_BYTE_PAGE(pBt) ){ + iGuess++; + } + + if( iGuess<=btreePagecount(pBt) ){ + rc = ptrmapGet(pBt, iGuess, &eType, &pgno); + if( rc==SQLITE_OK && eType==PTRMAP_OVERFLOW2 && pgno==ovfl ){ + next = iGuess; + rc = SQLITE_DONE; + } + } + } +#endif + + assert( next==0 || rc==SQLITE_DONE ); + if( rc==SQLITE_OK ){ + rc = btreeGetPage(pBt, ovfl, &pPage, (ppPage==0) ? PAGER_GET_READONLY : 0); + assert( rc==SQLITE_OK || pPage==0 ); + if( rc==SQLITE_OK ){ + next = get4byte(pPage->aData); + } + } + + *pPgnoNext = next; + if( ppPage ){ + *ppPage = pPage; + }else{ + releasePage(pPage); + } + return (rc==SQLITE_DONE ? SQLITE_OK : rc); +} + +/* +** Copy data from a buffer to a page, or from a page to a buffer. +** +** pPayload is a pointer to data stored on database page pDbPage. +** If argument eOp is false, then nByte bytes of data are copied +** from pPayload to the buffer pointed at by pBuf. If eOp is true, +** then sqlite3PagerWrite() is called on pDbPage and nByte bytes +** of data are copied from the buffer pBuf to pPayload. +** +** SQLITE_OK is returned on success, otherwise an error code. +*/ +static int copyPayload( + void *pPayload, /* Pointer to page data */ + void *pBuf, /* Pointer to buffer */ + int nByte, /* Number of bytes to copy */ + int eOp, /* 0 -> copy from page, 1 -> copy to page */ + DbPage *pDbPage /* Page containing pPayload */ +){ + if( eOp ){ + /* Copy data from buffer to page (a write operation) */ + int rc = sqlite3PagerWrite(pDbPage); + if( rc!=SQLITE_OK ){ + return rc; + } + memcpy(pPayload, pBuf, nByte); + }else{ + /* Copy data from page to buffer (a read operation) */ + memcpy(pBuf, pPayload, nByte); + } + return SQLITE_OK; +} + +/* +** This function is used to read or overwrite payload information +** for the entry that the pCur cursor is pointing to. The eOp +** argument is interpreted as follows: +** +** 0: The operation is a read. Populate the overflow cache. +** 1: The operation is a write. Populate the overflow cache. +** +** A total of "amt" bytes are read or written beginning at "offset". +** Data is read to or from the buffer pBuf. +** +** The content being read or written might appear on the main page +** or be scattered out on multiple overflow pages. +** +** If the current cursor entry uses one or more overflow pages +** this function may allocate space for and lazily populate +** the overflow page-list cache array (BtCursor.aOverflow). +** Subsequent calls use this cache to make seeking to the supplied offset +** more efficient. +** +** Once an overflow page-list cache has been allocated, it must be +** invalidated if some other cursor writes to the same table, or if +** the cursor is moved to a different row. Additionally, in auto-vacuum +** mode, the following events may invalidate an overflow page-list cache. +** +** * An incremental vacuum, +** * A commit in auto_vacuum="full" mode, +** * Creating a table (may require moving an overflow page). +*/ +static int accessPayload( + BtCursor *pCur, /* Cursor pointing to entry to read from */ + u32 offset, /* Begin reading this far into payload */ + u32 amt, /* Read this many bytes */ + unsigned char *pBuf, /* Write the bytes into this buffer */ + int eOp /* zero to read. non-zero to write. */ +){ + unsigned char *aPayload; + int rc = SQLITE_OK; + int iIdx = 0; + MemPage *pPage = pCur->pPage; /* Btree page of current entry */ + BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */ +#ifdef SQLITE_DIRECT_OVERFLOW_READ + unsigned char * const pBufStart = pBuf; /* Start of original out buffer */ +#endif + + assert( pPage ); + assert( eOp==0 || eOp==1 ); + assert( pCur->eState==CURSOR_VALID ); + if( pCur->ix>=pPage->nCell ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + assert( cursorHoldsMutex(pCur) ); + + getCellInfo(pCur); + aPayload = pCur->info.pPayload; + assert( (u64)offset+(u64)amt <= (u64)pCur->info.nPayload ); + + assert( aPayload > pPage->aData ); + if( (uptr)(aPayload - pPage->aData) > (pBt->usableSize - pCur->info.nLocal) ){ + /* Trying to read or write past the end of the data is an error. The + ** conditional above is really: + ** &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize] + ** but is recast into its current form to avoid integer overflow problems + */ + return SQLITE_CORRUPT_PAGE(pPage); + } + + /* Check if data must be read/written to/from the btree page itself. */ + if( offsetinfo.nLocal ){ + int a = amt; + if( a+offset>pCur->info.nLocal ){ + a = pCur->info.nLocal - offset; + } + rc = copyPayload(&aPayload[offset], pBuf, a, eOp, pPage->pDbPage); + offset = 0; + pBuf += a; + amt -= a; + }else{ + offset -= pCur->info.nLocal; + } + + + if( rc==SQLITE_OK && amt>0 ){ + const u32 ovflSize = pBt->usableSize - 4; /* Bytes content per ovfl page */ + Pgno nextPage; + + nextPage = get4byte(&aPayload[pCur->info.nLocal]); + + /* If the BtCursor.aOverflow[] has not been allocated, allocate it now. + ** + ** The aOverflow[] array is sized at one entry for each overflow page + ** in the overflow chain. The page number of the first overflow page is + ** stored in aOverflow[0], etc. A value of 0 in the aOverflow[] array + ** means "not yet known" (the cache is lazily populated). + */ + if( (pCur->curFlags & BTCF_ValidOvfl)==0 ){ + i64 nOvfl = pCur->info.nPayload; + testcase( nOvfl - pCur->info.nLocal + ovflSize - 1 > 0xffffffffU ); + nOvfl = (nOvfl - pCur->info.nLocal + ovflSize-1)/ovflSize; + if( pCur->aOverflow==0 + || nOvfl*(int)sizeof(Pgno) > sqlite3MallocSize(pCur->aOverflow) + ){ + Pgno *aNew; + if( sqlite3FaultSim(413) ){ + aNew = 0; + }else{ + aNew = (Pgno*)sqlite3Realloc(pCur->aOverflow, nOvfl*2*sizeof(Pgno)); + } + if( aNew==0 ){ + return SQLITE_NOMEM_BKPT; + }else{ + pCur->aOverflow = aNew; + } + } + memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno)); + pCur->curFlags |= BTCF_ValidOvfl; + }else{ + /* Sanity check the validity of the overflow page cache */ + assert( pCur->aOverflow[0]==nextPage + || pCur->aOverflow[0]==0 + || CORRUPT_DB ); + assert( pCur->aOverflow[0]!=0 || pCur->aOverflow[offset/ovflSize]==0 ); + + /* If the overflow page-list cache has been allocated and the + ** entry for the first required overflow page is valid, skip + ** directly to it. + */ + if( pCur->aOverflow[offset/ovflSize] ){ + iIdx = (offset/ovflSize); + nextPage = pCur->aOverflow[iIdx]; + offset = (offset%ovflSize); + } + } + + assert( rc==SQLITE_OK && amt>0 ); + while( nextPage ){ + /* If required, populate the overflow page-list cache. */ + if( nextPage > pBt->nPage ) return SQLITE_CORRUPT_BKPT; + assert( pCur->aOverflow[iIdx]==0 + || pCur->aOverflow[iIdx]==nextPage + || CORRUPT_DB ); + pCur->aOverflow[iIdx] = nextPage; + + if( offset>=ovflSize ){ + /* The only reason to read this page is to obtain the page + ** number for the next page in the overflow chain. The page + ** data is not required. So first try to lookup the overflow + ** page-list cache, if any, then fall back to the getOverflowPage() + ** function. + */ + assert( pCur->curFlags & BTCF_ValidOvfl ); + assert( pCur->pBtree->db==pBt->db ); + if( pCur->aOverflow[iIdx+1] ){ + nextPage = pCur->aOverflow[iIdx+1]; + }else{ + rc = getOverflowPage(pBt, nextPage, 0, &nextPage); + } + offset -= ovflSize; + }else{ + /* Need to read this page properly. It contains some of the + ** range of data that is being read (eOp==0) or written (eOp!=0). + */ + int a = amt; + if( a + offset > ovflSize ){ + a = ovflSize - offset; + } + +#ifdef SQLITE_DIRECT_OVERFLOW_READ + /* If all the following are true: + ** + ** 1) this is a read operation, and + ** 2) data is required from the start of this overflow page, and + ** 3) there are no dirty pages in the page-cache + ** 4) the database is file-backed, and + ** 5) the page is not in the WAL file + ** 6) at least 4 bytes have already been read into the output buffer + ** + ** then data can be read directly from the database file into the + ** output buffer, bypassing the page-cache altogether. This speeds + ** up loading large records that span many overflow pages. + */ + if( eOp==0 /* (1) */ + && offset==0 /* (2) */ + && sqlite3PagerDirectReadOk(pBt->pPager, nextPage) /* (3,4,5) */ + && &pBuf[-4]>=pBufStart /* (6) */ + ){ + sqlite3_file *fd = sqlite3PagerFile(pBt->pPager); + u8 aSave[4]; + u8 *aWrite = &pBuf[-4]; + assert( aWrite>=pBufStart ); /* due to (6) */ + memcpy(aSave, aWrite, 4); + rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1)); + nextPage = get4byte(aWrite); + memcpy(aWrite, aSave, 4); + }else +#endif + + { + DbPage *pDbPage; + rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage, + (eOp==0 ? PAGER_GET_READONLY : 0) + ); + if( rc==SQLITE_OK ){ + if( eOp!=0 + && (sqlite3PagerPageRefcount(pDbPage)!=1 + || NEVER(((MemPage*)sqlite3PagerGetExtra(pDbPage))->isInit)) ){ + sqlite3PagerUnref(pDbPage); + return SQLITE_CORRUPT_PAGE(pPage); + } + aPayload = sqlite3PagerGetData(pDbPage); + nextPage = get4byte(aPayload); + rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage); + sqlite3PagerUnref(pDbPage); + offset = 0; + } + } + amt -= a; + if( amt==0 ) return rc; + pBuf += a; + } + if( rc ) break; + iIdx++; + } + } + + if( rc==SQLITE_OK && amt>0 ){ + /* Overflow chain ends prematurely */ + return SQLITE_CORRUPT_PAGE(pPage); + } + return rc; +} + +/* +** Read part of the payload for the row at which that cursor pCur is currently +** pointing. "amt" bytes will be transferred into pBuf[]. The transfer +** begins at "offset". +** +** pCur can be pointing to either a table or an index b-tree. +** If pointing to a table btree, then the content section is read. If +** pCur is pointing to an index b-tree then the key section is read. +** +** For sqlite3BtreePayload(), the caller must ensure that pCur is pointing +** to a valid row in the table. For sqlite3BtreePayloadChecked(), the +** cursor might be invalid or might need to be restored before being read. +** +** Return SQLITE_OK on success or an error code if anything goes +** wrong. An error is returned if "offset+amt" is larger than +** the available payload. +*/ +SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + assert( pCur->iPage>=0 && pCur->pPage ); + return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0); +} + +/* +** This variant of sqlite3BtreePayload() works even if the cursor has not +** in the CURSOR_VALID state. It is only used by the sqlite3_blob_read() +** interface. +*/ +#ifndef SQLITE_OMIT_INCRBLOB +static SQLITE_NOINLINE int accessPayloadChecked( + BtCursor *pCur, + u32 offset, + u32 amt, + void *pBuf +){ + int rc; + if ( pCur->eState==CURSOR_INVALID ){ + return SQLITE_ABORT; + } + assert( cursorOwnsBtShared(pCur) ); + rc = btreeRestoreCursorPosition(pCur); + return rc ? rc : accessPayload(pCur, offset, amt, pBuf, 0); +} +SQLITE_PRIVATE int sqlite3BtreePayloadChecked(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ + if( pCur->eState==CURSOR_VALID ){ + assert( cursorOwnsBtShared(pCur) ); + return accessPayload(pCur, offset, amt, pBuf, 0); + }else{ + return accessPayloadChecked(pCur, offset, amt, pBuf); + } +} +#endif /* SQLITE_OMIT_INCRBLOB */ + +/* +** Return a pointer to payload information from the entry that the +** pCur cursor is pointing to. The pointer is to the beginning of +** the key if index btrees (pPage->intKey==0) and is the data for +** table btrees (pPage->intKey==1). The number of bytes of available +** key/data is written into *pAmt. If *pAmt==0, then the value +** returned will not be a valid pointer. +** +** This routine is an optimization. It is common for the entire key +** and data to fit on the local page and for there to be no overflow +** pages. When that is so, this routine can be used to access the +** key and data without making a copy. If the key and/or data spills +** onto overflow pages, then accessPayload() must be used to reassemble +** the key/data and copy it into a preallocated buffer. +** +** The pointer returned by this routine looks directly into the cached +** page of the database. The data might change or move the next time +** any btree routine is called. +*/ +static const void *fetchPayload( + BtCursor *pCur, /* Cursor pointing to entry to read from */ + u32 *pAmt /* Write the number of available bytes here */ +){ + int amt; + assert( pCur!=0 && pCur->iPage>=0 && pCur->pPage); + assert( pCur->eState==CURSOR_VALID ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + assert( cursorOwnsBtShared(pCur) ); + assert( pCur->ixpPage->nCell || CORRUPT_DB ); + assert( pCur->info.nSize>0 ); + assert( pCur->info.pPayload>pCur->pPage->aData || CORRUPT_DB ); + assert( pCur->info.pPayloadpPage->aDataEnd ||CORRUPT_DB); + amt = pCur->info.nLocal; + if( amt>(int)(pCur->pPage->aDataEnd - pCur->info.pPayload) ){ + /* There is too little space on the page for the expected amount + ** of local content. Database must be corrupt. */ + assert( CORRUPT_DB ); + amt = MAX(0, (int)(pCur->pPage->aDataEnd - pCur->info.pPayload)); + } + *pAmt = (u32)amt; + return (void*)pCur->info.pPayload; +} + + +/* +** For the entry that cursor pCur is point to, return as +** many bytes of the key or data as are available on the local +** b-tree page. Write the number of available bytes into *pAmt. +** +** The pointer returned is ephemeral. The key/data may move +** or be destroyed on the next call to any Btree routine, +** including calls from other threads against the same cache. +** Hence, a mutex on the BtShared should be held prior to calling +** this routine. +** +** These routines is used to get quick access to key and data +** in the common case where no overflow pages are used. +*/ +SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor *pCur, u32 *pAmt){ + return fetchPayload(pCur, pAmt); +} + + +/* +** Move the cursor down to a new child page. The newPgno argument is the +** page number of the child page to move to. +** +** This function returns SQLITE_CORRUPT if the page-header flags field of +** the new child page does not match the flags field of the parent (i.e. +** if an intkey page appears to be the parent of a non-intkey page, or +** vice-versa). +*/ +static int moveToChild(BtCursor *pCur, u32 newPgno){ + int rc; + assert( cursorOwnsBtShared(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + assert( pCur->iPageiPage>=0 ); + if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){ + return SQLITE_CORRUPT_BKPT; + } + pCur->info.nSize = 0; + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); + pCur->aiIdx[pCur->iPage] = pCur->ix; + pCur->apPage[pCur->iPage] = pCur->pPage; + pCur->ix = 0; + pCur->iPage++; + rc = getAndInitPage(pCur->pBt, newPgno, &pCur->pPage, pCur->curPagerFlags); + assert( pCur->pPage!=0 || rc!=SQLITE_OK ); + if( rc==SQLITE_OK + && (pCur->pPage->nCell<1 || pCur->pPage->intKey!=pCur->curIntKey) + ){ + releasePage(pCur->pPage); + rc = SQLITE_CORRUPT_PGNO(newPgno); + } + if( rc ){ + pCur->pPage = pCur->apPage[--pCur->iPage]; + } + return rc; +} + +#ifdef SQLITE_DEBUG +/* +** Page pParent is an internal (non-leaf) tree page. This function +** asserts that page number iChild is the left-child if the iIdx'th +** cell in page pParent. Or, if iIdx is equal to the total number of +** cells in pParent, that page number iChild is the right-child of +** the page. +*/ +static void assertParentIndex(MemPage *pParent, int iIdx, Pgno iChild){ + if( CORRUPT_DB ) return; /* The conditions tested below might not be true + ** in a corrupt database */ + assert( iIdx<=pParent->nCell ); + if( iIdx==pParent->nCell ){ + assert( get4byte(&pParent->aData[pParent->hdrOffset+8])==iChild ); + }else{ + assert( get4byte(findCell(pParent, iIdx))==iChild ); + } +} +#else +# define assertParentIndex(x,y,z) +#endif + +/* +** Move the cursor up to the parent page. +** +** pCur->idx is set to the cell index that contains the pointer +** to the page we are coming from. If we are coming from the +** right-most child page then pCur->idx is set to one more than +** the largest cell index. +*/ +static void moveToParent(BtCursor *pCur){ + MemPage *pLeaf; + assert( cursorOwnsBtShared(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + assert( pCur->iPage>0 ); + assert( pCur->pPage ); + assertParentIndex( + pCur->apPage[pCur->iPage-1], + pCur->aiIdx[pCur->iPage-1], + pCur->pPage->pgno + ); + testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell ); + pCur->info.nSize = 0; + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); + pCur->ix = pCur->aiIdx[pCur->iPage-1]; + pLeaf = pCur->pPage; + pCur->pPage = pCur->apPage[--pCur->iPage]; + releasePageNotNull(pLeaf); +} + +/* +** Move the cursor to point to the root page of its b-tree structure. +** +** If the table has a virtual root page, then the cursor is moved to point +** to the virtual root page instead of the actual root page. A table has a +** virtual root page when the actual root page contains no cells and a +** single child page. This can only happen with the table rooted at page 1. +** +** If the b-tree structure is empty, the cursor state is set to +** CURSOR_INVALID and this routine returns SQLITE_EMPTY. Otherwise, +** the cursor is set to point to the first cell located on the root +** (or virtual root) page and the cursor state is set to CURSOR_VALID. +** +** If this function returns successfully, it may be assumed that the +** page-header flags indicate that the [virtual] root-page is the expected +** kind of b-tree page (i.e. if when opening the cursor the caller did not +** specify a KeyInfo structure the flags byte is set to 0x05 or 0x0D, +** indicating a table b-tree, or if the caller did specify a KeyInfo +** structure the flags byte is set to 0x02 or 0x0A, indicating an index +** b-tree). +*/ +static int moveToRoot(BtCursor *pCur){ + MemPage *pRoot; + int rc = SQLITE_OK; + + assert( cursorOwnsBtShared(pCur) ); + assert( CURSOR_INVALID < CURSOR_REQUIRESEEK ); + assert( CURSOR_VALID < CURSOR_REQUIRESEEK ); + assert( CURSOR_FAULT > CURSOR_REQUIRESEEK ); + assert( pCur->eState < CURSOR_REQUIRESEEK || pCur->iPage<0 ); + assert( pCur->pgnoRoot>0 || pCur->iPage<0 ); + + if( pCur->iPage>=0 ){ + if( pCur->iPage ){ + releasePageNotNull(pCur->pPage); + while( --pCur->iPage ){ + releasePageNotNull(pCur->apPage[pCur->iPage]); + } + pRoot = pCur->pPage = pCur->apPage[0]; + goto skip_init; + } + }else if( pCur->pgnoRoot==0 ){ + pCur->eState = CURSOR_INVALID; + return SQLITE_EMPTY; + }else{ + assert( pCur->iPage==(-1) ); + if( pCur->eState>=CURSOR_REQUIRESEEK ){ + if( pCur->eState==CURSOR_FAULT ){ + assert( pCur->skipNext!=SQLITE_OK ); + return pCur->skipNext; + } + sqlite3BtreeClearCursor(pCur); + } + rc = getAndInitPage(pCur->pBt, pCur->pgnoRoot, &pCur->pPage, + pCur->curPagerFlags); + if( rc!=SQLITE_OK ){ + pCur->eState = CURSOR_INVALID; + return rc; + } + pCur->iPage = 0; + pCur->curIntKey = pCur->pPage->intKey; + } + pRoot = pCur->pPage; + assert( pRoot->pgno==pCur->pgnoRoot || CORRUPT_DB ); + + /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor + ** expected to open it on an index b-tree. Otherwise, if pKeyInfo is + ** NULL, the caller expects a table b-tree. If this is not the case, + ** return an SQLITE_CORRUPT error. + ** + ** Earlier versions of SQLite assumed that this test could not fail + ** if the root page was already loaded when this function was called (i.e. + ** if pCur->iPage>=0). But this is not so if the database is corrupted + ** in such a way that page pRoot is linked into a second b-tree table + ** (or the freelist). */ + assert( pRoot->intKey==1 || pRoot->intKey==0 ); + if( pRoot->isInit==0 || (pCur->pKeyInfo==0)!=pRoot->intKey ){ + return SQLITE_CORRUPT_PAGE(pCur->pPage); + } + +skip_init: + pCur->ix = 0; + pCur->info.nSize = 0; + pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl); + + if( pRoot->nCell>0 ){ + pCur->eState = CURSOR_VALID; + }else if( !pRoot->leaf ){ + Pgno subpage; + if( pRoot->pgno!=1 ) return SQLITE_CORRUPT_BKPT; + subpage = get4byte(&pRoot->aData[pRoot->hdrOffset+8]); + pCur->eState = CURSOR_VALID; + rc = moveToChild(pCur, subpage); + }else{ + pCur->eState = CURSOR_INVALID; + rc = SQLITE_EMPTY; + } + return rc; +} + +/* +** Move the cursor down to the left-most leaf entry beneath the +** entry to which it is currently pointing. +** +** The left-most leaf is the one with the smallest key - the first +** in ascending order. +*/ +static int moveToLeftmost(BtCursor *pCur){ + Pgno pgno; + int rc = SQLITE_OK; + MemPage *pPage; + + assert( cursorOwnsBtShared(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + while( rc==SQLITE_OK && !(pPage = pCur->pPage)->leaf ){ + assert( pCur->ixnCell ); + pgno = get4byte(findCell(pPage, pCur->ix)); + rc = moveToChild(pCur, pgno); + } + return rc; +} + +/* +** Move the cursor down to the right-most leaf entry beneath the +** page to which it is currently pointing. Notice the difference +** between moveToLeftmost() and moveToRightmost(). moveToLeftmost() +** finds the left-most entry beneath the *entry* whereas moveToRightmost() +** finds the right-most entry beneath the *page*. +** +** The right-most entry is the one with the largest key - the last +** key in ascending order. +*/ +static int moveToRightmost(BtCursor *pCur){ + Pgno pgno; + int rc = SQLITE_OK; + MemPage *pPage = 0; + + assert( cursorOwnsBtShared(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + while( !(pPage = pCur->pPage)->leaf ){ + pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); + pCur->ix = pPage->nCell; + rc = moveToChild(pCur, pgno); + if( rc ) return rc; + } + pCur->ix = pPage->nCell-1; + assert( pCur->info.nSize==0 ); + assert( (pCur->curFlags & BTCF_ValidNKey)==0 ); + return SQLITE_OK; +} + +/* Move the cursor to the first entry in the table. Return SQLITE_OK +** on success. Set *pRes to 0 if the cursor actually points to something +** or set *pRes to 1 if the table is empty. +*/ +SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ + int rc; + + assert( cursorOwnsBtShared(pCur) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + rc = moveToRoot(pCur); + if( rc==SQLITE_OK ){ + assert( pCur->pPage->nCell>0 ); + *pRes = 0; + rc = moveToLeftmost(pCur); + }else if( rc==SQLITE_EMPTY ){ + assert( pCur->pgnoRoot==0 || (pCur->pPage!=0 && pCur->pPage->nCell==0) ); + *pRes = 1; + rc = SQLITE_OK; + } + return rc; +} + +/* Set *pRes to 1 (true) if the BTree pointed to by cursor pCur contains zero +** rows of content. Set *pRes to 0 (false) if the table contains content. +** Return SQLITE_OK on success or some error code (ex: SQLITE_NOMEM) if +** something goes wrong. +*/ +SQLITE_PRIVATE int sqlite3BtreeIsEmpty(BtCursor *pCur, int *pRes){ + int rc; + + assert( cursorOwnsBtShared(pCur) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + if( NEVER(pCur->eState==CURSOR_VALID) ){ + *pRes = 0; + return SQLITE_OK; + } + rc = moveToRoot(pCur); + if( rc==SQLITE_EMPTY ){ + *pRes = 1; + rc = SQLITE_OK; + }else{ + *pRes = 0; + } + return rc; +} + +#ifdef SQLITE_DEBUG +/* The cursors is CURSOR_VALID and has BTCF_AtLast set. Verify that +** this flags are true for a consistent database. +** +** This routine is is called from within assert() statements only. +** It is an internal verification routine and does not appear in production +** builds. +*/ +static int cursorIsAtLastEntry(BtCursor *pCur){ + int ii; + for(ii=0; iiiPage; ii++){ + if( pCur->aiIdx[ii]!=pCur->apPage[ii]->nCell ) return 0; + } + return pCur->ix==pCur->pPage->nCell-1 && pCur->pPage->leaf!=0; +} +#endif + +/* Move the cursor to the last entry in the table. Return SQLITE_OK +** on success. Set *pRes to 0 if the cursor actually points to something +** or set *pRes to 1 if the table is empty. +*/ +static SQLITE_NOINLINE int btreeLast(BtCursor *pCur, int *pRes){ + int rc = moveToRoot(pCur); + if( rc==SQLITE_OK ){ + assert( pCur->eState==CURSOR_VALID ); + *pRes = 0; + rc = moveToRightmost(pCur); + if( rc==SQLITE_OK ){ + pCur->curFlags |= BTCF_AtLast; + }else{ + pCur->curFlags &= ~BTCF_AtLast; + } + }else if( rc==SQLITE_EMPTY ){ + assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); + *pRes = 1; + rc = SQLITE_OK; + } + return rc; +} +SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ + assert( cursorOwnsBtShared(pCur) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + + /* If the cursor already points to the last entry, this is a no-op. */ + if( CURSOR_VALID==pCur->eState && (pCur->curFlags & BTCF_AtLast)!=0 ){ + assert( cursorIsAtLastEntry(pCur) || CORRUPT_DB ); + *pRes = 0; + return SQLITE_OK; + } + return btreeLast(pCur, pRes); +} + +/* Move the cursor so that it points to an entry in a table (a.k.a INTKEY) +** table near the key intKey. Return a success code. +** +** If an exact match is not found, then the cursor is always +** left pointing at a leaf page which would hold the entry if it +** were present. The cursor might point to an entry that comes +** before or after the key. +** +** An integer is written into *pRes which is the result of +** comparing the key with the entry to which the cursor is +** pointing. The meaning of the integer written into +** *pRes is as follows: +** +** *pRes<0 The cursor is left pointing at an entry that +** is smaller than intKey or if the table is empty +** and the cursor is therefore left point to nothing. +** +** *pRes==0 The cursor is left pointing at an entry that +** exactly matches intKey. +** +** *pRes>0 The cursor is left pointing at an entry that +** is larger than intKey. +*/ +SQLITE_PRIVATE int sqlite3BtreeTableMoveto( + BtCursor *pCur, /* The cursor to be moved */ + i64 intKey, /* The table key */ + int biasRight, /* If true, bias the search to the high end */ + int *pRes /* Write search results here */ +){ + int rc; + + assert( cursorOwnsBtShared(pCur) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + assert( pRes ); + assert( pCur->pKeyInfo==0 ); + assert( pCur->eState!=CURSOR_VALID || pCur->curIntKey!=0 ); + + /* If the cursor is already positioned at the point we are trying + ** to move to, then just return without doing any work */ + if( pCur->eState==CURSOR_VALID && (pCur->curFlags & BTCF_ValidNKey)!=0 ){ + if( pCur->info.nKey==intKey ){ + *pRes = 0; + return SQLITE_OK; + } + if( pCur->info.nKeycurFlags & BTCF_AtLast)!=0 ){ + assert( cursorIsAtLastEntry(pCur) || CORRUPT_DB ); + *pRes = -1; + return SQLITE_OK; + } + /* If the requested key is one more than the previous key, then + ** try to get there using sqlite3BtreeNext() rather than a full + ** binary search. This is an optimization only. The correct answer + ** is still obtained without this case, only a little more slowly. */ + if( pCur->info.nKey+1==intKey ){ + *pRes = 0; + rc = sqlite3BtreeNext(pCur, 0); + if( rc==SQLITE_OK ){ + getCellInfo(pCur); + if( pCur->info.nKey==intKey ){ + return SQLITE_OK; + } + }else if( rc!=SQLITE_DONE ){ + return rc; + } + } + } + } + +#ifdef SQLITE_DEBUG + pCur->pBtree->nSeek++; /* Performance measurement during testing */ +#endif + + rc = moveToRoot(pCur); + if( rc ){ + if( rc==SQLITE_EMPTY ){ + assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); + *pRes = -1; + return SQLITE_OK; + } + return rc; + } + assert( pCur->pPage ); + assert( pCur->pPage->isInit ); + assert( pCur->eState==CURSOR_VALID ); + assert( pCur->pPage->nCell > 0 ); + assert( pCur->iPage==0 || pCur->apPage[0]->intKey==pCur->curIntKey ); + assert( pCur->curIntKey ); + + for(;;){ + int lwr, upr, idx, c; + Pgno chldPg; + MemPage *pPage = pCur->pPage; + u8 *pCell; /* Pointer to current cell in pPage */ + + /* pPage->nCell must be greater than zero. If this is the root-page + ** the cursor would have been INVALID above and this for(;;) loop + ** not run. If this is not the root-page, then the moveToChild() routine + ** would have already detected db corruption. Similarly, pPage must + ** be the right kind (index or table) of b-tree page. Otherwise + ** a moveToChild() or moveToRoot() call would have detected corruption. */ + assert( pPage->nCell>0 ); + assert( pPage->intKey ); + lwr = 0; + upr = pPage->nCell-1; + assert( biasRight==0 || biasRight==1 ); + idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */ + for(;;){ + i64 nCellKey; + pCell = findCellPastPtr(pPage, idx); + if( pPage->intKeyLeaf ){ + while( 0x80 <= *(pCell++) ){ + if( pCell>=pPage->aDataEnd ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + } + } + getVarint(pCell, (u64*)&nCellKey); + if( nCellKeyupr ){ c = -1; break; } + }else if( nCellKey>intKey ){ + upr = idx-1; + if( lwr>upr ){ c = +1; break; } + }else{ + assert( nCellKey==intKey ); + pCur->ix = (u16)idx; + if( !pPage->leaf ){ + lwr = idx; + goto moveto_table_next_layer; + }else{ + pCur->curFlags |= BTCF_ValidNKey; + pCur->info.nKey = nCellKey; + pCur->info.nSize = 0; + *pRes = 0; + return SQLITE_OK; + } + } + assert( lwr+upr>=0 ); + idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2; */ + } + assert( lwr==upr+1 || !pPage->leaf ); + assert( pPage->isInit ); + if( pPage->leaf ){ + assert( pCur->ixpPage->nCell ); + pCur->ix = (u16)idx; + *pRes = c; + rc = SQLITE_OK; + goto moveto_table_finish; + } +moveto_table_next_layer: + if( lwr>=pPage->nCell ){ + chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]); + }else{ + chldPg = get4byte(findCell(pPage, lwr)); + } + pCur->ix = (u16)lwr; + rc = moveToChild(pCur, chldPg); + if( rc ) break; + } +moveto_table_finish: + pCur->info.nSize = 0; + assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); + return rc; +} + +/* +** Compare the "idx"-th cell on the page pPage against the key +** pointing to by pIdxKey using xRecordCompare. Return negative or +** zero if the cell is less than or equal pIdxKey. Return positive +** if unknown. +** +** Return value negative: Cell at pCur[idx] less than pIdxKey +** +** Return value is zero: Cell at pCur[idx] equals pIdxKey +** +** Return value positive: Nothing is known about the relationship +** of the cell at pCur[idx] and pIdxKey. +** +** This routine is part of an optimization. It is always safe to return +** a positive value as that will cause the optimization to be skipped. +*/ +static int indexCellCompare( + MemPage *pPage, + int idx, + UnpackedRecord *pIdxKey, + RecordCompare xRecordCompare +){ + int c; + int nCell; /* Size of the pCell cell in bytes */ + u8 *pCell = findCellPastPtr(pPage, idx); + + nCell = pCell[0]; + if( nCell<=pPage->max1bytePayload ){ + /* This branch runs if the record-size field of the cell is a + ** single byte varint and the record fits entirely on the main + ** b-tree page. */ + if( pCell + nCell >= pPage->aDataEnd ) return 99; + c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey); + }else if( !(pCell[1] & 0x80) + && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal + ){ + /* The record-size field is a 2 byte varint and the record + ** fits entirely on the main b-tree page. */ + if( pCell + nCell >= pPage->aDataEnd ) return 99; + c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey); + }else{ + /* If the record extends into overflow pages, do not attempt + ** the optimization. */ + c = 99; + } + return c; +} + +/* +** Return true (non-zero) if pCur is current pointing to the last +** page of a table. +*/ +static int cursorOnLastPage(BtCursor *pCur){ + int i; + assert( pCur->eState==CURSOR_VALID ); + for(i=0; iiPage; i++){ + MemPage *pPage = pCur->apPage[i]; + if( pCur->aiIdx[i]nCell ) return 0; + } + return 1; +} + +/* Move the cursor so that it points to an entry in an index table +** near the key pIdxKey. Return a success code. +** +** If an exact match is not found, then the cursor is always +** left pointing at a leaf page which would hold the entry if it +** were present. The cursor might point to an entry that comes +** before or after the key. +** +** An integer is written into *pRes which is the result of +** comparing the key with the entry to which the cursor is +** pointing. The meaning of the integer written into +** *pRes is as follows: +** +** *pRes<0 The cursor is left pointing at an entry that +** is smaller than pIdxKey or if the table is empty +** and the cursor is therefore left point to nothing. +** +** *pRes==0 The cursor is left pointing at an entry that +** exactly matches pIdxKey. +** +** *pRes>0 The cursor is left pointing at an entry that +** is larger than pIdxKey. +** +** The pIdxKey->eqSeen field is set to 1 if there +** exists an entry in the table that exactly matches pIdxKey. +*/ +SQLITE_PRIVATE int sqlite3BtreeIndexMoveto( + BtCursor *pCur, /* The cursor to be moved */ + UnpackedRecord *pIdxKey, /* Unpacked index key */ + int *pRes /* Write search results here */ +){ + int rc; + RecordCompare xRecordCompare; + + assert( cursorOwnsBtShared(pCur) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + assert( pRes ); + assert( pCur->pKeyInfo!=0 ); + +#ifdef SQLITE_DEBUG + pCur->pBtree->nSeek++; /* Performance measurement during testing */ +#endif + + xRecordCompare = sqlite3VdbeFindCompare(pIdxKey); + pIdxKey->errCode = 0; + assert( pIdxKey->default_rc==1 + || pIdxKey->default_rc==0 + || pIdxKey->default_rc==-1 + ); + + + /* Check to see if we can skip a lot of work. Two cases: + ** + ** (1) If the cursor is already pointing to the very last cell + ** in the table and the pIdxKey search key is greater than or + ** equal to that last cell, then no movement is required. + ** + ** (2) If the cursor is on the last page of the table and the first + ** cell on that last page is less than or equal to the pIdxKey + ** search key, then we can start the search on the current page + ** without needing to go back to root. + */ + if( pCur->eState==CURSOR_VALID + && pCur->pPage->leaf + && cursorOnLastPage(pCur) + ){ + int c; + if( pCur->ix==pCur->pPage->nCell-1 + && (c = indexCellCompare(pCur->pPage,pCur->ix,pIdxKey,xRecordCompare))<=0 + && pIdxKey->errCode==SQLITE_OK + ){ + *pRes = c; + return SQLITE_OK; /* Cursor already pointing at the correct spot */ + } + if( pCur->iPage>0 + && indexCellCompare(pCur->pPage, 0, pIdxKey, xRecordCompare)<=0 + && pIdxKey->errCode==SQLITE_OK + ){ + pCur->curFlags &= ~(BTCF_ValidOvfl|BTCF_AtLast); + if( !pCur->pPage->isInit ){ + return SQLITE_CORRUPT_BKPT; + } + goto bypass_moveto_root; /* Start search on the current page */ + } + pIdxKey->errCode = SQLITE_OK; + } + + rc = moveToRoot(pCur); + if( rc ){ + if( rc==SQLITE_EMPTY ){ + assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); + *pRes = -1; + return SQLITE_OK; + } + return rc; + } + +bypass_moveto_root: + assert( pCur->pPage ); + assert( pCur->pPage->isInit ); + assert( pCur->eState==CURSOR_VALID ); + assert( pCur->pPage->nCell > 0 ); + assert( pCur->curIntKey==0 ); + assert( pIdxKey!=0 ); + for(;;){ + int lwr, upr, idx, c; + Pgno chldPg; + MemPage *pPage = pCur->pPage; + u8 *pCell; /* Pointer to current cell in pPage */ + + /* pPage->nCell must be greater than zero. If this is the root-page + ** the cursor would have been INVALID above and this for(;;) loop + ** not run. If this is not the root-page, then the moveToChild() routine + ** would have already detected db corruption. Similarly, pPage must + ** be the right kind (index or table) of b-tree page. Otherwise + ** a moveToChild() or moveToRoot() call would have detected corruption. */ + assert( pPage->nCell>0 ); + assert( pPage->intKey==0 ); + lwr = 0; + upr = pPage->nCell-1; + idx = upr>>1; /* idx = (lwr+upr)/2; */ + for(;;){ + int nCell; /* Size of the pCell cell in bytes */ + pCell = findCellPastPtr(pPage, idx); + + /* The maximum supported page-size is 65536 bytes. This means that + ** the maximum number of record bytes stored on an index B-Tree + ** page is less than 16384 bytes and may be stored as a 2-byte + ** varint. This information is used to attempt to avoid parsing + ** the entire cell by checking for the cases where the record is + ** stored entirely within the b-tree page by inspecting the first + ** 2 bytes of the cell. + */ + nCell = pCell[0]; + if( nCell<=pPage->max1bytePayload ){ + /* This branch runs if the record-size field of the cell is a + ** single byte varint and the record fits entirely on the main + ** b-tree page. */ + if( pCell + nCell >= pPage->aDataEnd ){ + rc = SQLITE_CORRUPT_PAGE(pPage); + goto moveto_index_finish; + } + c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey); + }else if( !(pCell[1] & 0x80) + && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal + && pCell + nCell < pPage->aDataEnd + ){ + /* The record-size field is a 2 byte varint and the record + ** fits entirely on the main b-tree page. */ + c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey); + }else{ + /* The record flows over onto one or more overflow pages. In + ** this case the whole cell needs to be parsed, a buffer allocated + ** and accessPayload() used to retrieve the record into the + ** buffer before VdbeRecordCompare() can be called. + ** + ** If the record is corrupt, the xRecordCompare routine may read + ** up to two varints past the end of the buffer. An extra 18 + ** bytes of padding is allocated at the end of the buffer in + ** case this happens. */ + void *pCellKey; + u8 * const pCellBody = pCell - pPage->childPtrSize; + const int nOverrun = 18; /* Size of the overrun padding */ + pPage->xParseCell(pPage, pCellBody, &pCur->info); + nCell = (int)pCur->info.nKey; + testcase( nCell<0 ); /* True if key size is 2^32 or more */ + testcase( nCell==0 ); /* Invalid key size: 0x80 0x80 0x00 */ + testcase( nCell==1 ); /* Invalid key size: 0x80 0x80 0x01 */ + testcase( nCell==2 ); /* Minimum legal index key size */ + if( nCell<2 || nCell/pCur->pBt->usableSize>pCur->pBt->nPage ){ + rc = SQLITE_CORRUPT_PAGE(pPage); + goto moveto_index_finish; + } + pCellKey = sqlite3Malloc( (u64)nCell+(u64)nOverrun ); + if( pCellKey==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto moveto_index_finish; + } + pCur->ix = (u16)idx; + rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0); + memset(((u8*)pCellKey)+nCell,0,nOverrun); /* Fix uninit warnings */ + pCur->curFlags &= ~BTCF_ValidOvfl; + if( rc ){ + sqlite3_free(pCellKey); + goto moveto_index_finish; + } + c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey); + sqlite3_free(pCellKey); + } + assert( + (pIdxKey->errCode!=SQLITE_CORRUPT || c==0) + && (pIdxKey->errCode!=SQLITE_NOMEM || pCur->pBtree->db->mallocFailed) + ); + if( c<0 ){ + lwr = idx+1; + }else if( c>0 ){ + upr = idx-1; + }else{ + assert( c==0 ); + *pRes = 0; + rc = SQLITE_OK; + pCur->ix = (u16)idx; + if( pIdxKey->errCode ) rc = SQLITE_CORRUPT_BKPT; + goto moveto_index_finish; + } + if( lwr>upr ) break; + assert( lwr+upr>=0 ); + idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2 */ + } + assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) ); + assert( pPage->isInit ); + if( pPage->leaf ){ + assert( pCur->ixpPage->nCell || CORRUPT_DB ); + pCur->ix = (u16)idx; + *pRes = c; + rc = SQLITE_OK; + goto moveto_index_finish; + } + if( lwr>=pPage->nCell ){ + chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]); + }else{ + chldPg = get4byte(findCell(pPage, lwr)); + } + + /* This block is similar to an in-lined version of: + ** + ** pCur->ix = (u16)lwr; + ** rc = moveToChild(pCur, chldPg); + ** if( rc ) break; + */ + pCur->info.nSize = 0; + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); + if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){ + return SQLITE_CORRUPT_BKPT; + } + pCur->aiIdx[pCur->iPage] = (u16)lwr; + pCur->apPage[pCur->iPage] = pCur->pPage; + pCur->ix = 0; + pCur->iPage++; + rc = getAndInitPage(pCur->pBt, chldPg, &pCur->pPage, pCur->curPagerFlags); + if( rc==SQLITE_OK + && (pCur->pPage->nCell<1 || pCur->pPage->intKey!=pCur->curIntKey) + ){ + releasePage(pCur->pPage); + rc = SQLITE_CORRUPT_PGNO(chldPg); + } + if( rc ){ + pCur->pPage = pCur->apPage[--pCur->iPage]; + break; + } + /* + ***** End of in-lined moveToChild() call */ + } +moveto_index_finish: + pCur->info.nSize = 0; + assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); + return rc; +} + + +/* +** Return TRUE if the cursor is not pointing at an entry of the table. +** +** TRUE will be returned after a call to sqlite3BtreeNext() moves +** past the last entry in the table or sqlite3BtreePrev() moves past +** the first entry. TRUE is also returned if the table is empty. +*/ +SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor *pCur){ + /* TODO: What if the cursor is in CURSOR_REQUIRESEEK but all table entries + ** have been deleted? This API will need to change to return an error code + ** as well as the boolean result value. + */ + return (CURSOR_VALID!=pCur->eState); +} + +/* +** Return an estimate for the number of rows in the table that pCur is +** pointing to. Return a negative number if no estimate is currently +** available. +*/ +SQLITE_PRIVATE i64 sqlite3BtreeRowCountEst(BtCursor *pCur){ + i64 n; + u8 i; + + assert( cursorOwnsBtShared(pCur) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + + /* Currently this interface is only called by the OP_IfSizeBetween + ** opcode and the OP_Count opcode with P3=1. In either case, + ** the cursor will always be valid unless the btree is empty. */ + if( pCur->eState!=CURSOR_VALID ) return 0; + if( NEVER(pCur->pPage->leaf==0) ) return -1; + + n = pCur->pPage->nCell; + for(i=0; iiPage; i++){ + n *= pCur->apPage[i]->nCell+1; + } + return n; +} + +/* +** Advance the cursor to the next entry in the database. +** Return value: +** +** SQLITE_OK success +** SQLITE_DONE cursor is already pointing at the last element +** otherwise some kind of error occurred +** +** The main entry point is sqlite3BtreeNext(). That routine is optimized +** for the common case of merely incrementing the cell counter BtCursor.aiIdx +** to the next cell on the current page. The (slower) btreeNext() helper +** routine is called when it is necessary to move to a different page or +** to restore the cursor. +** +** If bit 0x01 of the F argument in sqlite3BtreeNext(C,F) is 1, then the +** cursor corresponds to an SQL index and this routine could have been +** skipped if the SQL index had been a unique index. The F argument +** is a hint to the implement. SQLite btree implementation does not use +** this hint, but COMDB2 does. +*/ +static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){ + int rc; + int idx; + MemPage *pPage; + + assert( cursorOwnsBtShared(pCur) ); + if( pCur->eState!=CURSOR_VALID ){ + assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); + rc = restoreCursorPosition(pCur); + if( rc!=SQLITE_OK ){ + return rc; + } + if( CURSOR_INVALID==pCur->eState ){ + return SQLITE_DONE; + } + if( pCur->eState==CURSOR_SKIPNEXT ){ + pCur->eState = CURSOR_VALID; + if( pCur->skipNext>0 ) return SQLITE_OK; + } + } + + pPage = pCur->pPage; + idx = ++pCur->ix; + if( sqlite3FaultSim(412) ) pPage->isInit = 0; + if( !pPage->isInit ){ + return SQLITE_CORRUPT_BKPT; + } + + if( idx>=pPage->nCell ){ + if( !pPage->leaf ){ + rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8])); + if( rc ) return rc; + return moveToLeftmost(pCur); + } + do{ + if( pCur->iPage==0 ){ + pCur->eState = CURSOR_INVALID; + return SQLITE_DONE; + } + moveToParent(pCur); + pPage = pCur->pPage; + }while( pCur->ix>=pPage->nCell ); + if( pPage->intKey ){ + return sqlite3BtreeNext(pCur, 0); + }else{ + return SQLITE_OK; + } + } + if( pPage->leaf ){ + return SQLITE_OK; + }else{ + return moveToLeftmost(pCur); + } +} +SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int flags){ + MemPage *pPage; + UNUSED_PARAMETER( flags ); /* Used in COMDB2 but not native SQLite */ + assert( cursorOwnsBtShared(pCur) ); + assert( flags==0 || flags==1 ); + pCur->info.nSize = 0; + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); + if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur); + pPage = pCur->pPage; + if( (++pCur->ix)>=pPage->nCell ){ + pCur->ix--; + return btreeNext(pCur); + } + if( pPage->leaf ){ + return SQLITE_OK; + }else{ + return moveToLeftmost(pCur); + } +} + +/* +** Step the cursor to the back to the previous entry in the database. +** Return values: +** +** SQLITE_OK success +** SQLITE_DONE the cursor is already on the first element of the table +** otherwise some kind of error occurred +** +** The main entry point is sqlite3BtreePrevious(). That routine is optimized +** for the common case of merely decrementing the cell counter BtCursor.aiIdx +** to the previous cell on the current page. The (slower) btreePrevious() +** helper routine is called when it is necessary to move to a different page +** or to restore the cursor. +** +** If bit 0x01 of the F argument to sqlite3BtreePrevious(C,F) is 1, then +** the cursor corresponds to an SQL index and this routine could have been +** skipped if the SQL index had been a unique index. The F argument is a +** hint to the implement. The native SQLite btree implementation does not +** use this hint, but COMDB2 does. +*/ +static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){ + int rc; + MemPage *pPage; + + assert( cursorOwnsBtShared(pCur) ); + assert( (pCur->curFlags & (BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey))==0 ); + assert( pCur->info.nSize==0 ); + if( pCur->eState!=CURSOR_VALID ){ + rc = restoreCursorPosition(pCur); + if( rc!=SQLITE_OK ){ + return rc; + } + if( CURSOR_INVALID==pCur->eState ){ + return SQLITE_DONE; + } + if( CURSOR_SKIPNEXT==pCur->eState ){ + pCur->eState = CURSOR_VALID; + if( pCur->skipNext<0 ) return SQLITE_OK; + } + } + + pPage = pCur->pPage; + if( sqlite3FaultSim(412) ) pPage->isInit = 0; + if( !pPage->isInit ){ + return SQLITE_CORRUPT_BKPT; + } + if( !pPage->leaf ){ + int idx = pCur->ix; + rc = moveToChild(pCur, get4byte(findCell(pPage, idx))); + if( rc ) return rc; + rc = moveToRightmost(pCur); + }else{ + while( pCur->ix==0 ){ + if( pCur->iPage==0 ){ + pCur->eState = CURSOR_INVALID; + return SQLITE_DONE; + } + moveToParent(pCur); + } + assert( pCur->info.nSize==0 ); + assert( (pCur->curFlags & (BTCF_ValidOvfl))==0 ); + + pCur->ix--; + pPage = pCur->pPage; + if( pPage->intKey && !pPage->leaf ){ + rc = sqlite3BtreePrevious(pCur, 0); + }else{ + rc = SQLITE_OK; + } + } + return rc; +} +SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int flags){ + assert( cursorOwnsBtShared(pCur) ); + assert( flags==0 || flags==1 ); + UNUSED_PARAMETER( flags ); /* Used in COMDB2 but not native SQLite */ + pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey); + pCur->info.nSize = 0; + if( pCur->eState!=CURSOR_VALID + || pCur->ix==0 + || pCur->pPage->leaf==0 + ){ + return btreePrevious(pCur); + } + pCur->ix--; + return SQLITE_OK; +} + +/* +** Allocate a new page from the database file. +** +** The new page is marked as dirty. (In other words, sqlite3PagerWrite() +** has already been called on the new page.) The new page has also +** been referenced and the calling routine is responsible for calling +** sqlite3PagerUnref() on the new page when it is done. +** +** SQLITE_OK is returned on success. Any other return value indicates +** an error. *ppPage is set to NULL in the event of an error. +** +** If the "nearby" parameter is not 0, then an effort is made to +** locate a page close to the page number "nearby". This can be used in an +** attempt to keep related pages close to each other in the database file, +** which in turn can make database access faster. +** +** If the eMode parameter is BTALLOC_EXACT and the nearby page exists +** anywhere on the free-list, then it is guaranteed to be returned. If +** eMode is BTALLOC_LT then the page returned will be less than or equal +** to nearby if any such page exists. If eMode is BTALLOC_ANY then there +** are no restrictions on which page is returned. +*/ +static int allocateBtreePage( + BtShared *pBt, /* The btree */ + MemPage **ppPage, /* Store pointer to the allocated page here */ + Pgno *pPgno, /* Store the page number here */ + Pgno nearby, /* Search for a page near this one */ + u8 eMode /* BTALLOC_EXACT, BTALLOC_LT, or BTALLOC_ANY */ +){ + MemPage *pPage1; + int rc; + u32 n; /* Number of pages on the freelist */ + u32 k; /* Number of leaves on the trunk of the freelist */ + MemPage *pTrunk = 0; + MemPage *pPrevTrunk = 0; + Pgno mxPage; /* Total size of the database file */ + + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( eMode==BTALLOC_ANY || (nearby>0 && IfNotOmitAV(pBt->autoVacuum)) ); + pPage1 = pBt->pPage1; + mxPage = btreePagecount(pBt); + /* EVIDENCE-OF: R-21003-45125 The 4-byte big-endian integer at offset 36 + ** stores the total number of pages on the freelist. */ + n = get4byte(&pPage1->aData[36]); + testcase( n==mxPage-1 ); + if( n>=mxPage ){ + return SQLITE_CORRUPT_BKPT; + } + if( n>0 ){ + /* There are pages on the freelist. Reuse one of those pages. */ + Pgno iTrunk; + u8 searchList = 0; /* If the free-list must be searched for 'nearby' */ + u32 nSearch = 0; /* Count of the number of search attempts */ + + /* If eMode==BTALLOC_EXACT and a query of the pointer-map + ** shows that the page 'nearby' is somewhere on the free-list, then + ** the entire-list will be searched for that page. + */ +#ifndef SQLITE_OMIT_AUTOVACUUM + if( eMode==BTALLOC_EXACT ){ + if( nearby<=mxPage ){ + u8 eType; + assert( nearby>0 ); + assert( pBt->autoVacuum ); + rc = ptrmapGet(pBt, nearby, &eType, 0); + if( rc ) return rc; + if( eType==PTRMAP_FREEPAGE ){ + searchList = 1; + } + } + }else if( eMode==BTALLOC_LE ){ + searchList = 1; + } +#endif + + /* Decrement the free-list count by 1. Set iTrunk to the index of the + ** first free-list trunk page. iPrevTrunk is initially 1. + */ + rc = sqlite3PagerWrite(pPage1->pDbPage); + if( rc ) return rc; + put4byte(&pPage1->aData[36], n-1); + + /* The code within this loop is run only once if the 'searchList' variable + ** is not true. Otherwise, it runs once for each trunk-page on the + ** free-list until the page 'nearby' is located (eMode==BTALLOC_EXACT) + ** or until a page less than 'nearby' is located (eMode==BTALLOC_LT) + */ + do { + pPrevTrunk = pTrunk; + if( pPrevTrunk ){ + /* EVIDENCE-OF: R-01506-11053 The first integer on a freelist trunk page + ** is the page number of the next freelist trunk page in the list or + ** zero if this is the last freelist trunk page. */ + iTrunk = get4byte(&pPrevTrunk->aData[0]); + }else{ + /* EVIDENCE-OF: R-59841-13798 The 4-byte big-endian integer at offset 32 + ** stores the page number of the first page of the freelist, or zero if + ** the freelist is empty. */ + iTrunk = get4byte(&pPage1->aData[32]); + } + testcase( iTrunk==mxPage ); + if( iTrunk>mxPage || nSearch++ > n ){ + rc = SQLITE_CORRUPT_PGNO(pPrevTrunk ? pPrevTrunk->pgno : 1); + }else{ + rc = btreeGetUnusedPage(pBt, iTrunk, &pTrunk, 0); + } + if( rc ){ + pTrunk = 0; + goto end_allocate_page; + } + assert( pTrunk!=0 ); + assert( pTrunk->aData!=0 ); + /* EVIDENCE-OF: R-13523-04394 The second integer on a freelist trunk page + ** is the number of leaf page pointers to follow. */ + k = get4byte(&pTrunk->aData[4]); + if( k==0 && !searchList ){ + /* The trunk has no leaves and the list is not being searched. + ** So extract the trunk page itself and use it as the newly + ** allocated page */ + assert( pPrevTrunk==0 ); + rc = sqlite3PagerWrite(pTrunk->pDbPage); + if( rc ){ + goto end_allocate_page; + } + *pPgno = iTrunk; + memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); + *ppPage = pTrunk; + pTrunk = 0; + TRACE(("ALLOCATE: %u trunk - %u free pages left\n", *pPgno, n-1)); + }else if( k>(u32)(pBt->usableSize/4 - 2) ){ + /* Value of k is out of range. Database corruption */ + rc = SQLITE_CORRUPT_PGNO(iTrunk); + goto end_allocate_page; +#ifndef SQLITE_OMIT_AUTOVACUUM + }else if( searchList + && (nearby==iTrunk || (iTrunkpDbPage); + if( rc ){ + goto end_allocate_page; + } + if( k==0 ){ + if( !pPrevTrunk ){ + memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); + }else{ + rc = sqlite3PagerWrite(pPrevTrunk->pDbPage); + if( rc!=SQLITE_OK ){ + goto end_allocate_page; + } + memcpy(&pPrevTrunk->aData[0], &pTrunk->aData[0], 4); + } + }else{ + /* The trunk page is required by the caller but it contains + ** pointers to free-list leaves. The first leaf becomes a trunk + ** page in this case. + */ + MemPage *pNewTrunk; + Pgno iNewTrunk = get4byte(&pTrunk->aData[8]); + if( iNewTrunk>mxPage ){ + rc = SQLITE_CORRUPT_PGNO(iTrunk); + goto end_allocate_page; + } + testcase( iNewTrunk==mxPage ); + rc = btreeGetUnusedPage(pBt, iNewTrunk, &pNewTrunk, 0); + if( rc!=SQLITE_OK ){ + goto end_allocate_page; + } + rc = sqlite3PagerWrite(pNewTrunk->pDbPage); + if( rc!=SQLITE_OK ){ + releasePage(pNewTrunk); + goto end_allocate_page; + } + memcpy(&pNewTrunk->aData[0], &pTrunk->aData[0], 4); + put4byte(&pNewTrunk->aData[4], k-1); + memcpy(&pNewTrunk->aData[8], &pTrunk->aData[12], (k-1)*4); + releasePage(pNewTrunk); + if( !pPrevTrunk ){ + assert( sqlite3PagerIswriteable(pPage1->pDbPage) ); + put4byte(&pPage1->aData[32], iNewTrunk); + }else{ + rc = sqlite3PagerWrite(pPrevTrunk->pDbPage); + if( rc ){ + goto end_allocate_page; + } + put4byte(&pPrevTrunk->aData[0], iNewTrunk); + } + } + pTrunk = 0; + TRACE(("ALLOCATE: %u trunk - %u free pages left\n", *pPgno, n-1)); +#endif + }else if( k>0 ){ + /* Extract a leaf from the trunk */ + u32 closest; + Pgno iPage; + unsigned char *aData = pTrunk->aData; + if( nearby>0 ){ + u32 i; + closest = 0; + if( eMode==BTALLOC_LE ){ + for(i=0; imxPage || iPage<2 ){ + rc = SQLITE_CORRUPT_PGNO(iTrunk); + goto end_allocate_page; + } + testcase( iPage==mxPage ); + if( !searchList + || (iPage==nearby || (iPagepgno, n-1)); + rc = sqlite3PagerWrite(pTrunk->pDbPage); + if( rc ) goto end_allocate_page; + if( closestpDbPage); + if( rc!=SQLITE_OK ){ + releasePage(*ppPage); + *ppPage = 0; + } + } + searchList = 0; + } + } + releasePage(pPrevTrunk); + pPrevTrunk = 0; + }while( searchList ); + }else{ + /* There are no pages on the freelist, so append a new page to the + ** database image. + ** + ** Normally, new pages allocated by this block can be requested from the + ** pager layer with the 'no-content' flag set. This prevents the pager + ** from trying to read the pages content from disk. However, if the + ** current transaction has already run one or more incremental-vacuum + ** steps, then the page we are about to allocate may contain content + ** that is required in the event of a rollback. In this case, do + ** not set the no-content flag. This causes the pager to load and journal + ** the current page content before overwriting it. + ** + ** Note that the pager will not actually attempt to load or journal + ** content for any page that really does lie past the end of the database + ** file on disk. So the effects of disabling the no-content optimization + ** here are confined to those pages that lie between the end of the + ** database image and the end of the database file. + */ + int bNoContent = (0==IfNotOmitAV(pBt->bDoTruncate))? PAGER_GET_NOCONTENT:0; + + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + if( rc ) return rc; + pBt->nPage++; + if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ) pBt->nPage++; + +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt, pBt->nPage) ){ + /* If *pPgno refers to a pointer-map page, allocate two new pages + ** at the end of the file instead of one. The first allocated page + ** becomes a new pointer-map page, the second is used by the caller. + */ + MemPage *pPg = 0; + TRACE(("ALLOCATE: %u from end of file (pointer-map page)\n", pBt->nPage)); + assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) ); + rc = btreeGetUnusedPage(pBt, pBt->nPage, &pPg, bNoContent); + if( rc==SQLITE_OK ){ + rc = sqlite3PagerWrite(pPg->pDbPage); + releasePage(pPg); + } + if( rc ) return rc; + pBt->nPage++; + if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ){ pBt->nPage++; } + } +#endif + put4byte(28 + (u8*)pBt->pPage1->aData, pBt->nPage); + *pPgno = pBt->nPage; + + assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); + rc = btreeGetUnusedPage(pBt, *pPgno, ppPage, bNoContent); + if( rc ) return rc; + rc = sqlite3PagerWrite((*ppPage)->pDbPage); + if( rc!=SQLITE_OK ){ + releasePage(*ppPage); + *ppPage = 0; + } + TRACE(("ALLOCATE: %u from end of file\n", *pPgno)); + } + + assert( CORRUPT_DB || *pPgno!=PENDING_BYTE_PAGE(pBt) ); + +end_allocate_page: + releasePage(pTrunk); + releasePage(pPrevTrunk); + assert( rc!=SQLITE_OK || sqlite3PagerPageRefcount((*ppPage)->pDbPage)<=1 ); + assert( rc!=SQLITE_OK || (*ppPage)->isInit==0 ); + return rc; +} + +/* +** This function is used to add page iPage to the database file free-list. +** It is assumed that the page is not already a part of the free-list. +** +** The value passed as the second argument to this function is optional. +** If the caller happens to have a pointer to the MemPage object +** corresponding to page iPage handy, it may pass it as the second value. +** Otherwise, it may pass NULL. +** +** If a pointer to a MemPage object is passed as the second argument, +** its reference count is not altered by this function. +*/ +static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){ + MemPage *pTrunk = 0; /* Free-list trunk page */ + Pgno iTrunk = 0; /* Page number of free-list trunk page */ + MemPage *pPage1 = pBt->pPage1; /* Local reference to page 1 */ + MemPage *pPage; /* Page being freed. May be NULL. */ + int rc; /* Return Code */ + u32 nFree; /* Initial number of pages on free-list */ + + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( CORRUPT_DB || iPage>1 ); + assert( !pMemPage || pMemPage->pgno==iPage ); + + if( iPage<2 || iPage>pBt->nPage ){ + return SQLITE_CORRUPT_BKPT; + } + if( pMemPage ){ + pPage = pMemPage; + sqlite3PagerRef(pPage->pDbPage); + }else{ + pPage = btreePageLookup(pBt, iPage); + } + + /* Increment the free page count on pPage1 */ + rc = sqlite3PagerWrite(pPage1->pDbPage); + if( rc ) goto freepage_out; + nFree = get4byte(&pPage1->aData[36]); + put4byte(&pPage1->aData[36], nFree+1); + + if( pBt->btsFlags & BTS_SECURE_DELETE ){ + /* If the secure_delete option is enabled, then + ** always fully overwrite deleted information with zeros. + */ + if( (!pPage && ((rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0) ) + || ((rc = sqlite3PagerWrite(pPage->pDbPage))!=0) + ){ + goto freepage_out; + } + memset(pPage->aData, 0, pPage->pBt->pageSize); + } + + /* If the database supports auto-vacuum, write an entry in the pointer-map + ** to indicate that the page is free. + */ + if( ISAUTOVACUUM(pBt) ){ + ptrmapPut(pBt, iPage, PTRMAP_FREEPAGE, 0, &rc); + if( rc ) goto freepage_out; + } + + /* Now manipulate the actual database free-list structure. There are two + ** possibilities. If the free-list is currently empty, or if the first + ** trunk page in the free-list is full, then this page will become a + ** new free-list trunk page. Otherwise, it will become a leaf of the + ** first trunk page in the current free-list. This block tests if it + ** is possible to add the page as a new free-list leaf. + */ + if( nFree!=0 ){ + u32 nLeaf; /* Initial number of leaf cells on trunk page */ + + iTrunk = get4byte(&pPage1->aData[32]); + if( iTrunk>btreePagecount(pBt) ){ + rc = SQLITE_CORRUPT_BKPT; + goto freepage_out; + } + rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0); + if( rc!=SQLITE_OK ){ + goto freepage_out; + } + + nLeaf = get4byte(&pTrunk->aData[4]); + assert( pBt->usableSize>32 ); + if( nLeaf > (u32)pBt->usableSize/4 - 2 ){ + rc = SQLITE_CORRUPT_BKPT; + goto freepage_out; + } + if( nLeaf < (u32)pBt->usableSize/4 - 8 ){ + /* In this case there is room on the trunk page to insert the page + ** being freed as a new leaf. + ** + ** Note that the trunk page is not really full until it contains + ** usableSize/4 - 2 entries, not usableSize/4 - 8 entries as we have + ** coded. But due to a coding error in versions of SQLite prior to + ** 3.6.0, databases with freelist trunk pages holding more than + ** usableSize/4 - 8 entries will be reported as corrupt. In order + ** to maintain backwards compatibility with older versions of SQLite, + ** we will continue to restrict the number of entries to usableSize/4 - 8 + ** for now. At some point in the future (once everyone has upgraded + ** to 3.6.0 or later) we should consider fixing the conditional above + ** to read "usableSize/4-2" instead of "usableSize/4-8". + ** + ** EVIDENCE-OF: R-19920-11576 However, newer versions of SQLite still + ** avoid using the last six entries in the freelist trunk page array in + ** order that database files created by newer versions of SQLite can be + ** read by older versions of SQLite. + */ + rc = sqlite3PagerWrite(pTrunk->pDbPage); + if( rc==SQLITE_OK ){ + put4byte(&pTrunk->aData[4], nLeaf+1); + put4byte(&pTrunk->aData[8+nLeaf*4], iPage); + if( pPage && (pBt->btsFlags & BTS_SECURE_DELETE)==0 ){ + sqlite3PagerDontWrite(pPage->pDbPage); + } + rc = btreeSetHasContent(pBt, iPage); + } + TRACE(("FREE-PAGE: %u leaf on trunk page %u\n",pPage->pgno,pTrunk->pgno)); + goto freepage_out; + } + } + + /* If control flows to this point, then it was not possible to add the + ** the page being freed as a leaf page of the first trunk in the free-list. + ** Possibly because the free-list is empty, or possibly because the + ** first trunk in the free-list is full. Either way, the page being freed + ** will become the new first trunk page in the free-list. + */ + if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0)) ){ + goto freepage_out; + } + rc = sqlite3PagerWrite(pPage->pDbPage); + if( rc!=SQLITE_OK ){ + goto freepage_out; + } + put4byte(pPage->aData, iTrunk); + put4byte(&pPage->aData[4], 0); + put4byte(&pPage1->aData[32], iPage); + TRACE(("FREE-PAGE: %u new trunk page replacing %u\n", pPage->pgno, iTrunk)); + +freepage_out: + if( pPage ){ + pPage->isInit = 0; + } + releasePage(pPage); + releasePage(pTrunk); + return rc; +} +static void freePage(MemPage *pPage, int *pRC){ + if( (*pRC)==SQLITE_OK ){ + *pRC = freePage2(pPage->pBt, pPage, pPage->pgno); + } +} + +/* +** Free the overflow pages associated with the given Cell. +*/ +static SQLITE_NOINLINE int clearCellOverflow( + MemPage *pPage, /* The page that contains the Cell */ + unsigned char *pCell, /* First byte of the Cell */ + CellInfo *pInfo /* Size information about the cell */ +){ + BtShared *pBt; + Pgno ovflPgno; + int rc; + int nOvfl; + u32 ovflPageSize; + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( pInfo->nLocal!=pInfo->nPayload ); + testcase( pCell + pInfo->nSize == pPage->aDataEnd ); + testcase( pCell + (pInfo->nSize-1) == pPage->aDataEnd ); + if( pCell + pInfo->nSize > pPage->aDataEnd ){ + /* Cell extends past end of page */ + return SQLITE_CORRUPT_PAGE(pPage); + } + ovflPgno = get4byte(pCell + pInfo->nSize - 4); + pBt = pPage->pBt; + assert( pBt->usableSize > 4 ); + ovflPageSize = pBt->usableSize - 4; + nOvfl = (pInfo->nPayload - pInfo->nLocal + ovflPageSize - 1)/ovflPageSize; + assert( nOvfl>0 || + (CORRUPT_DB && (pInfo->nPayload + ovflPageSize)btreePagecount(pBt) ){ + /* 0 is not a legal page number and page 1 cannot be an + ** overflow page. Therefore if ovflPgno<2 or past the end of the + ** file the database must be corrupt. */ + return SQLITE_CORRUPT_BKPT; + } + if( nOvfl ){ + rc = getOverflowPage(pBt, ovflPgno, &pOvfl, &iNext); + if( rc ) return rc; + } + + if( ( pOvfl || ((pOvfl = btreePageLookup(pBt, ovflPgno))!=0) ) + && sqlite3PagerPageRefcount(pOvfl->pDbPage)!=1 + ){ + /* There is no reason any cursor should have an outstanding reference + ** to an overflow page belonging to a cell that is being deleted/updated. + ** So if there exists more than one reference to this page, then it + ** must not really be an overflow page and the database must be corrupt. + ** It is helpful to detect this before calling freePage2(), as + ** freePage2() may zero the page contents if secure-delete mode is + ** enabled. If this 'overflow' page happens to be a page that the + ** caller is iterating through or using in some other way, this + ** can be problematic. + */ + rc = SQLITE_CORRUPT_BKPT; + }else{ + rc = freePage2(pBt, pOvfl, ovflPgno); + } + + if( pOvfl ){ + sqlite3PagerUnref(pOvfl->pDbPage); + } + if( rc ) return rc; + ovflPgno = iNext; + } + return SQLITE_OK; +} + +/* Call xParseCell to compute the size of a cell. If the cell contains +** overflow, then invoke cellClearOverflow to clear out that overflow. +** Store the result code (SQLITE_OK or some error code) in rc. +** +** Implemented as macro to force inlining for performance. +*/ +#define BTREE_CLEAR_CELL(rc, pPage, pCell, sInfo) \ + pPage->xParseCell(pPage, pCell, &sInfo); \ + if( sInfo.nLocal!=sInfo.nPayload ){ \ + rc = clearCellOverflow(pPage, pCell, &sInfo); \ + }else{ \ + rc = SQLITE_OK; \ + } + + +/* +** Create the byte sequence used to represent a cell on page pPage +** and write that byte sequence into pCell[]. Overflow pages are +** allocated and filled in as necessary. The calling procedure +** is responsible for making sure sufficient space has been allocated +** for pCell[]. +** +** Note that pCell does not necessary need to point to the pPage->aData +** area. pCell might point to some temporary storage. The cell will +** be constructed in this temporary area then copied into pPage->aData +** later. +*/ +static int fillInCell( + MemPage *pPage, /* The page that contains the cell */ + unsigned char *pCell, /* Complete text of the cell */ + const BtreePayload *pX, /* Payload with which to construct the cell */ + int *pnSize /* Write cell size here */ +){ + int nPayload; + const u8 *pSrc; + int nSrc, n, rc, mn; + int spaceLeft; + MemPage *pToRelease; + unsigned char *pPrior; + unsigned char *pPayload; + BtShared *pBt; + Pgno pgnoOvfl; + int nHeader; + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + + /* pPage is not necessarily writeable since pCell might be auxiliary + ** buffer space that is separate from the pPage buffer area */ + assert( pCellaData || pCell>=&pPage->aData[pPage->pBt->pageSize] + || sqlite3PagerIswriteable(pPage->pDbPage) ); + + /* Fill in the header. */ + nHeader = pPage->childPtrSize; + if( pPage->intKey ){ + nPayload = pX->nData + pX->nZero; + pSrc = pX->pData; + nSrc = pX->nData; + assert( pPage->intKeyLeaf ); /* fillInCell() only called for leaves */ + nHeader += putVarint32(&pCell[nHeader], nPayload); + nHeader += putVarint(&pCell[nHeader], *(u64*)&pX->nKey); + }else{ + assert( pX->nKey<=0x7fffffff && pX->pKey!=0 ); + nSrc = nPayload = (int)pX->nKey; + pSrc = pX->pKey; + nHeader += putVarint32(&pCell[nHeader], nPayload); + } + + /* Fill in the payload */ + pPayload = &pCell[nHeader]; + if( nPayload<=pPage->maxLocal ){ + /* This is the common case where everything fits on the btree page + ** and no overflow pages are required. */ + n = nHeader + nPayload; + testcase( n==3 ); + testcase( n==4 ); + if( n<4 ){ + n = 4; + pPayload[nPayload] = 0; + } + *pnSize = n; + assert( nSrc<=nPayload ); + testcase( nSrcminLocal; + n = mn + (nPayload - mn) % (pPage->pBt->usableSize - 4); + testcase( n==pPage->maxLocal ); + testcase( n==pPage->maxLocal+1 ); + if( n > pPage->maxLocal ) n = mn; + spaceLeft = n; + *pnSize = n + nHeader + 4; + pPrior = &pCell[nHeader+n]; + pToRelease = 0; + pgnoOvfl = 0; + pBt = pPage->pBt; + + /* At this point variables should be set as follows: + ** + ** nPayload Total payload size in bytes + ** pPayload Begin writing payload here + ** spaceLeft Space available at pPayload. If nPayload>spaceLeft, + ** that means content must spill into overflow pages. + ** *pnSize Size of the local cell (not counting overflow pages) + ** pPrior Where to write the pgno of the first overflow page + ** + ** Use a call to btreeParseCellPtr() to verify that the values above + ** were computed correctly. + */ +#ifdef SQLITE_DEBUG + { + CellInfo info; + pPage->xParseCell(pPage, pCell, &info); + assert( nHeader==(int)(info.pPayload - pCell) ); + assert( info.nKey==pX->nKey ); + assert( *pnSize == info.nSize ); + assert( spaceLeft == info.nLocal ); + } +#endif + + /* Write the payload into the local Cell and any extra into overflow pages */ + while( 1 ){ + n = nPayload; + if( n>spaceLeft ) n = spaceLeft; + + /* If pToRelease is not zero than pPayload points into the data area + ** of pToRelease. Make sure pToRelease is still writeable. */ + assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) ); + + /* If pPayload is part of the data area of pPage, then make sure pPage + ** is still writeable */ + assert( pPayloadaData || pPayload>=&pPage->aData[pBt->pageSize] + || sqlite3PagerIswriteable(pPage->pDbPage) ); + + if( nSrc>=n ){ + memcpy(pPayload, pSrc, n); + }else if( nSrc>0 ){ + n = nSrc; + memcpy(pPayload, pSrc, n); + }else{ + memset(pPayload, 0, n); + } + nPayload -= n; + if( nPayload<=0 ) break; + pPayload += n; + pSrc += n; + nSrc -= n; + spaceLeft -= n; + if( spaceLeft==0 ){ + MemPage *pOvfl = 0; +#ifndef SQLITE_OMIT_AUTOVACUUM + Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */ + if( pBt->autoVacuum ){ + do{ + pgnoOvfl++; + } while( + PTRMAP_ISPAGE(pBt, pgnoOvfl) || pgnoOvfl==PENDING_BYTE_PAGE(pBt) + ); + } +#endif + rc = allocateBtreePage(pBt, &pOvfl, &pgnoOvfl, pgnoOvfl, 0); +#ifndef SQLITE_OMIT_AUTOVACUUM + /* If the database supports auto-vacuum, and the second or subsequent + ** overflow page is being allocated, add an entry to the pointer-map + ** for that page now. + ** + ** If this is the first overflow page, then write a partial entry + ** to the pointer-map. If we write nothing to this pointer-map slot, + ** then the optimistic overflow chain processing in clearCell() + ** may misinterpret the uninitialized values and delete the + ** wrong pages from the database. + */ + if( pBt->autoVacuum && rc==SQLITE_OK ){ + u8 eType = (pgnoPtrmap?PTRMAP_OVERFLOW2:PTRMAP_OVERFLOW1); + ptrmapPut(pBt, pgnoOvfl, eType, pgnoPtrmap, &rc); + if( rc ){ + releasePage(pOvfl); + } + } +#endif + if( rc ){ + releasePage(pToRelease); + return rc; + } + + /* If pToRelease is not zero than pPrior points into the data area + ** of pToRelease. Make sure pToRelease is still writeable. */ + assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) ); + + /* If pPrior is part of the data area of pPage, then make sure pPage + ** is still writeable */ + assert( pPrioraData || pPrior>=&pPage->aData[pBt->pageSize] + || sqlite3PagerIswriteable(pPage->pDbPage) ); + + put4byte(pPrior, pgnoOvfl); + releasePage(pToRelease); + pToRelease = pOvfl; + pPrior = pOvfl->aData; + put4byte(pPrior, 0); + pPayload = &pOvfl->aData[4]; + spaceLeft = pBt->usableSize - 4; + } + } + releasePage(pToRelease); + return SQLITE_OK; +} + +/* +** Remove the i-th cell from pPage. This routine effects pPage only. +** The cell content is not freed or deallocated. It is assumed that +** the cell content has been copied someplace else. This routine just +** removes the reference to the cell from pPage. +** +** "sz" must be the number of bytes in the cell. +*/ +static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ + u32 pc; /* Offset to cell content of cell being deleted */ + u8 *data; /* pPage->aData */ + u8 *ptr; /* Used to move bytes around within data[] */ + int rc; /* The return code */ + int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */ + + if( *pRC ) return; + assert( idx>=0 ); + assert( idxnCell ); + assert( CORRUPT_DB || sz==cellSize(pPage, idx) ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( pPage->nFree>=0 ); + data = pPage->aData; + ptr = &pPage->aCellIdx[2*idx]; + assert( pPage->pBt->usableSize > (u32)(ptr-data) ); + pc = get2byte(ptr); + hdr = pPage->hdrOffset; + testcase( pc==(u32)get2byte(&data[hdr+5]) ); + testcase( pc+sz==pPage->pBt->usableSize ); + if( pc+sz > pPage->pBt->usableSize ){ + *pRC = SQLITE_CORRUPT_BKPT; + return; + } + rc = freeSpace(pPage, pc, sz); + if( rc ){ + *pRC = rc; + return; + } + pPage->nCell--; + if( pPage->nCell==0 ){ + memset(&data[hdr+1], 0, 4); + data[hdr+7] = 0; + put2byte(&data[hdr+5], pPage->pBt->usableSize); + pPage->nFree = pPage->pBt->usableSize - pPage->hdrOffset + - pPage->childPtrSize - 8; + }else{ + memmove(ptr, ptr+2, 2*(pPage->nCell - idx)); + put2byte(&data[hdr+3], pPage->nCell); + pPage->nFree += 2; + } +} + +/* +** Insert a new cell on pPage at cell index "i". pCell points to the +** content of the cell. +** +** If the cell content will fit on the page, then put it there. If it +** will not fit, then make a copy of the cell content into pTemp if +** pTemp is not null. Regardless of pTemp, allocate a new entry +** in pPage->apOvfl[] and make it point to the cell content (either +** in pTemp or the original pCell) and also record its index. +** Allocating a new entry in pPage->aCell[] implies that +** pPage->nOverflow is incremented. +** +** The insertCellFast() routine below works exactly the same as +** insertCell() except that it lacks the pTemp and iChild parameters +** which are assumed zero. Other than that, the two routines are the +** same. +** +** Fixes or enhancements to this routine should be reflected in +** insertCellFast()! +*/ +static int insertCell( + MemPage *pPage, /* Page into which we are copying */ + int i, /* New cell becomes the i-th cell of the page */ + u8 *pCell, /* Content of the new cell */ + int sz, /* Bytes of content in pCell */ + u8 *pTemp, /* Temp storage space for pCell, if needed */ + Pgno iChild /* If non-zero, replace first 4 bytes with this value */ +){ + int idx = 0; /* Where to write new cell content in data[] */ + int j; /* Loop counter */ + u8 *data; /* The content of the whole page */ + u8 *pIns; /* The point in pPage->aCellIdx[] where no cell inserted */ + + assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); + assert( MX_CELL(pPage->pBt)<=10921 ); + assert( pPage->nCell<=MX_CELL(pPage->pBt) || CORRUPT_DB ); + assert( pPage->nOverflow<=ArraySize(pPage->apOvfl) ); + assert( ArraySize(pPage->apOvfl)==ArraySize(pPage->aiOvfl) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sz==pPage->xCellSize(pPage, pCell) || CORRUPT_DB ); + assert( pPage->nFree>=0 ); + assert( iChild>0 ); + if( pPage->nOverflow || sz+2>pPage->nFree ){ + if( pTemp ){ + memcpy(pTemp, pCell, sz); + pCell = pTemp; + } + put4byte(pCell, iChild); + j = pPage->nOverflow++; + /* Comparison against ArraySize-1 since we hold back one extra slot + ** as a contingency. In other words, never need more than 3 overflow + ** slots but 4 are allocated, just to be safe. */ + assert( j < ArraySize(pPage->apOvfl)-1 ); + pPage->apOvfl[j] = pCell; + pPage->aiOvfl[j] = (u16)i; + + /* When multiple overflows occur, they are always sequential and in + ** sorted order. This invariants arise because multiple overflows can + ** only occur when inserting divider cells into the parent page during + ** balancing, and the dividers are adjacent and sorted. + */ + assert( j==0 || pPage->aiOvfl[j-1]<(u16)i ); /* Overflows in sorted order */ + assert( j==0 || i==pPage->aiOvfl[j-1]+1 ); /* Overflows are sequential */ + }else{ + int rc = sqlite3PagerWrite(pPage->pDbPage); + if( NEVER(rc!=SQLITE_OK) ){ + return rc; + } + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + data = pPage->aData; + assert( &data[pPage->cellOffset]==pPage->aCellIdx ); + rc = allocateSpace(pPage, sz, &idx); + if( rc ){ return rc; } + /* The allocateSpace() routine guarantees the following properties + ** if it returns successfully */ + assert( idx >= 0 ); + assert( idx >= pPage->cellOffset+2*pPage->nCell+2 || CORRUPT_DB ); + assert( idx+sz <= (int)pPage->pBt->usableSize ); + pPage->nFree -= (u16)(2 + sz); + /* In a corrupt database where an entry in the cell index section of + ** a btree page has a value of 3 or less, the pCell value might point + ** as many as 4 bytes in front of the start of the aData buffer for + ** the source page. Make sure this does not cause problems by not + ** reading the first 4 bytes */ + memcpy(&data[idx+4], pCell+4, sz-4); + put4byte(&data[idx], iChild); + pIns = pPage->aCellIdx + i*2; + memmove(pIns+2, pIns, 2*(pPage->nCell - i)); + put2byte(pIns, idx); + pPage->nCell++; + /* increment the cell count */ + if( (++data[pPage->hdrOffset+4])==0 ) data[pPage->hdrOffset+3]++; + assert( get2byte(&data[pPage->hdrOffset+3])==pPage->nCell || CORRUPT_DB ); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pPage->pBt->autoVacuum ){ + int rc2 = SQLITE_OK; + /* The cell may contain a pointer to an overflow page. If so, write + ** the entry for the overflow page into the pointer map. + */ + ptrmapPutOvflPtr(pPage, pPage, pCell, &rc2); + if( rc2 ) return rc2; + } +#endif + } + return SQLITE_OK; +} + +/* +** This variant of insertCell() assumes that the pTemp and iChild +** parameters are both zero. Use this variant in sqlite3BtreeInsert() +** for performance improvement, and also so that this variant is only +** called from that one place, and is thus inlined, and thus runs must +** faster. +** +** Fixes or enhancements to this routine should be reflected into +** the insertCell() routine. +*/ +static int insertCellFast( + MemPage *pPage, /* Page into which we are copying */ + int i, /* New cell becomes the i-th cell of the page */ + u8 *pCell, /* Content of the new cell */ + int sz /* Bytes of content in pCell */ +){ + int idx = 0; /* Where to write new cell content in data[] */ + int j; /* Loop counter */ + u8 *data; /* The content of the whole page */ + u8 *pIns; /* The point in pPage->aCellIdx[] where no cell inserted */ + + assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); + assert( MX_CELL(pPage->pBt)<=10921 ); + assert( pPage->nCell<=MX_CELL(pPage->pBt) || CORRUPT_DB ); + assert( pPage->nOverflow<=ArraySize(pPage->apOvfl) ); + assert( ArraySize(pPage->apOvfl)==ArraySize(pPage->aiOvfl) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sz==pPage->xCellSize(pPage, pCell) || CORRUPT_DB ); + assert( pPage->nFree>=0 ); + assert( pPage->nOverflow==0 ); + if( sz+2>pPage->nFree ){ + j = pPage->nOverflow++; + /* Comparison against ArraySize-1 since we hold back one extra slot + ** as a contingency. In other words, never need more than 3 overflow + ** slots but 4 are allocated, just to be safe. */ + assert( j < ArraySize(pPage->apOvfl)-1 ); + pPage->apOvfl[j] = pCell; + pPage->aiOvfl[j] = (u16)i; + + /* When multiple overflows occur, they are always sequential and in + ** sorted order. This invariants arise because multiple overflows can + ** only occur when inserting divider cells into the parent page during + ** balancing, and the dividers are adjacent and sorted. + */ + assert( j==0 || pPage->aiOvfl[j-1]<(u16)i ); /* Overflows in sorted order */ + assert( j==0 || i==pPage->aiOvfl[j-1]+1 ); /* Overflows are sequential */ + }else{ + int rc = sqlite3PagerWrite(pPage->pDbPage); + if( rc!=SQLITE_OK ){ + return rc; + } + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + data = pPage->aData; + assert( &data[pPage->cellOffset]==pPage->aCellIdx ); + rc = allocateSpace(pPage, sz, &idx); + if( rc ){ return rc; } + /* The allocateSpace() routine guarantees the following properties + ** if it returns successfully */ + assert( idx >= 0 ); + assert( idx >= pPage->cellOffset+2*pPage->nCell+2 || CORRUPT_DB ); + assert( idx+sz <= (int)pPage->pBt->usableSize ); + pPage->nFree -= (u16)(2 + sz); + memcpy(&data[idx], pCell, sz); + pIns = pPage->aCellIdx + i*2; + memmove(pIns+2, pIns, 2*(pPage->nCell - i)); + put2byte(pIns, idx); + pPage->nCell++; + /* increment the cell count */ + if( (++data[pPage->hdrOffset+4])==0 ) data[pPage->hdrOffset+3]++; + assert( get2byte(&data[pPage->hdrOffset+3])==pPage->nCell || CORRUPT_DB ); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pPage->pBt->autoVacuum ){ + int rc2 = SQLITE_OK; + /* The cell may contain a pointer to an overflow page. If so, write + ** the entry for the overflow page into the pointer map. + */ + ptrmapPutOvflPtr(pPage, pPage, pCell, &rc2); + if( rc2 ) return rc2; + } +#endif + } + return SQLITE_OK; +} + +/* +** The following parameters determine how many adjacent pages get involved +** in a balancing operation. NN is the number of neighbors on either side +** of the page that participate in the balancing operation. NB is the +** total number of pages that participate, including the target page and +** NN neighbors on either side. +** +** The minimum value of NN is 1 (of course). Increasing NN above 1 +** (to 2 or 3) gives a modest improvement in SELECT and DELETE performance +** in exchange for a larger degradation in INSERT and UPDATE performance. +** The value of NN appears to give the best results overall. +** +** (Later:) The description above makes it seem as if these values are +** tunable - as if you could change them and recompile and it would all work. +** But that is unlikely. NB has been 3 since the inception of SQLite and +** we have never tested any other value. +*/ +#define NN 1 /* Number of neighbors on either side of pPage */ +#define NB 3 /* (NN*2+1): Total pages involved in the balance */ + +/* +** A CellArray object contains a cache of pointers and sizes for a +** consecutive sequence of cells that might be held on multiple pages. +** +** The cells in this array are the divider cell or cells from the pParent +** page plus up to three child pages. There are a total of nCell cells. +** +** pRef is a pointer to one of the pages that contributes cells. This is +** used to access information such as MemPage.intKey and MemPage.pBt->pageSize +** which should be common to all pages that contribute cells to this array. +** +** apCell[] and szCell[] hold, respectively, pointers to the start of each +** cell and the size of each cell. Some of the apCell[] pointers might refer +** to overflow cells. In other words, some apCel[] pointers might not point +** to content area of the pages. +** +** A szCell[] of zero means the size of that cell has not yet been computed. +** +** The cells come from as many as four different pages: +** +** ----------- +** | Parent | +** ----------- +** / | \ +** / | \ +** --------- --------- --------- +** |Child-1| |Child-2| |Child-3| +** --------- --------- --------- +** +** The order of cells is in the array is for an index btree is: +** +** 1. All cells from Child-1 in order +** 2. The first divider cell from Parent +** 3. All cells from Child-2 in order +** 4. The second divider cell from Parent +** 5. All cells from Child-3 in order +** +** For a table-btree (with rowids) the items 2 and 4 are empty because +** content exists only in leaves and there are no divider cells. +** +** For an index btree, the apEnd[] array holds pointer to the end of page +** for Child-1, the Parent, Child-2, the Parent (again), and Child-3, +** respectively. The ixNx[] array holds the number of cells contained in +** each of these 5 stages, and all stages to the left. Hence: +** +** ixNx[0] = Number of cells in Child-1. +** ixNx[1] = Number of cells in Child-1 plus 1 for first divider. +** ixNx[2] = Number of cells in Child-1 and Child-2 + 1 for 1st divider. +** ixNx[3] = Number of cells in Child-1 and Child-2 + both divider cells +** ixNx[4] = Total number of cells. +** +** For a table-btree, the concept is similar, except only apEnd[0]..apEnd[2] +** are used and they point to the leaf pages only, and the ixNx value are: +** +** ixNx[0] = Number of cells in Child-1. +** ixNx[1] = Number of cells in Child-1 and Child-2. +** ixNx[2] = Total number of cells. +** +** Sometimes when deleting, a child page can have zero cells. In those +** cases, ixNx[] entries with higher indexes, and the corresponding apEnd[] +** entries, shift down. The end result is that each ixNx[] entry should +** be larger than the previous +*/ +typedef struct CellArray CellArray; +struct CellArray { + int nCell; /* Number of cells in apCell[] */ + MemPage *pRef; /* Reference page */ + u8 **apCell; /* All cells begin balanced */ + u16 *szCell; /* Local size of all cells in apCell[] */ + u8 *apEnd[NB*2]; /* MemPage.aDataEnd values */ + int ixNx[NB*2]; /* Index of at which we move to the next apEnd[] */ +}; + +/* +** Make sure the cell sizes at idx, idx+1, ..., idx+N-1 have been +** computed. +*/ +static void populateCellCache(CellArray *p, int idx, int N){ + MemPage *pRef = p->pRef; + u16 *szCell = p->szCell; + assert( idx>=0 && idx+N<=p->nCell ); + while( N>0 ){ + assert( p->apCell[idx]!=0 ); + if( szCell[idx]==0 ){ + szCell[idx] = pRef->xCellSize(pRef, p->apCell[idx]); + }else{ + assert( CORRUPT_DB || + szCell[idx]==pRef->xCellSize(pRef, p->apCell[idx]) ); + } + idx++; + N--; + } +} + +/* +** Return the size of the Nth element of the cell array +*/ +static SQLITE_NOINLINE u16 computeCellSize(CellArray *p, int N){ + assert( N>=0 && NnCell ); + assert( p->szCell[N]==0 ); + p->szCell[N] = p->pRef->xCellSize(p->pRef, p->apCell[N]); + return p->szCell[N]; +} +static u16 cachedCellSize(CellArray *p, int N){ + assert( N>=0 && NnCell ); + if( p->szCell[N] ) return p->szCell[N]; + return computeCellSize(p, N); +} + +/* +** Array apCell[] contains pointers to nCell b-tree page cells. The +** szCell[] array contains the size in bytes of each cell. This function +** replaces the current contents of page pPg with the contents of the cell +** array. +** +** Some of the cells in apCell[] may currently be stored in pPg. This +** function works around problems caused by this by making a copy of any +** such cells before overwriting the page data. +** +** The MemPage.nFree field is invalidated by this function. It is the +** responsibility of the caller to set it correctly. +*/ +static int rebuildPage( + CellArray *pCArray, /* Content to be added to page pPg */ + int iFirst, /* First cell in pCArray to use */ + int nCell, /* Final number of cells on page */ + MemPage *pPg /* The page to be reconstructed */ +){ + const int hdr = pPg->hdrOffset; /* Offset of header on pPg */ + u8 * const aData = pPg->aData; /* Pointer to data for pPg */ + const int usableSize = pPg->pBt->usableSize; + u8 * const pEnd = &aData[usableSize]; + int i = iFirst; /* Which cell to copy from pCArray*/ + u32 j; /* Start of cell content area */ + int iEnd = i+nCell; /* Loop terminator */ + u8 *pCellptr = pPg->aCellIdx; + u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager); + u8 *pData; + int k; /* Current slot in pCArray->apEnd[] */ + u8 *pSrcEnd; /* Current pCArray->apEnd[k] value */ + + assert( nCell>0 ); + assert( i(u32)usableSize ){ j = 0; } + memcpy(&pTmp[j], &aData[j], usableSize - j); + + assert( pCArray->ixNx[NB*2-1]>i ); + for(k=0; pCArray->ixNx[k]<=i; k++){} + pSrcEnd = pCArray->apEnd[k]; + + pData = pEnd; + while( 1/*exit by break*/ ){ + u8 *pCell = pCArray->apCell[i]; + u16 sz = pCArray->szCell[i]; + assert( sz>0 ); + if( SQLITE_WITHIN(pCell,aData+j,pEnd) ){ + if( ((uptr)(pCell+sz))>(uptr)pEnd ) return SQLITE_CORRUPT_BKPT; + pCell = &pTmp[pCell - aData]; + }else if( (uptr)(pCell+sz)>(uptr)pSrcEnd + && (uptr)(pCell)<(uptr)pSrcEnd + ){ + return SQLITE_CORRUPT_BKPT; + } + + pData -= sz; + put2byte(pCellptr, (pData - aData)); + pCellptr += 2; + if( pData < pCellptr ) return SQLITE_CORRUPT_BKPT; + memmove(pData, pCell, sz); + assert( sz==pPg->xCellSize(pPg, pCell) || CORRUPT_DB ); + i++; + if( i>=iEnd ) break; + if( pCArray->ixNx[k]<=i ){ + k++; + pSrcEnd = pCArray->apEnd[k]; + } + } + + /* The pPg->nFree field is now set incorrectly. The caller will fix it. */ + assert( nCell < 10922 ); + pPg->nCell = (u16)nCell; + pPg->nOverflow = 0; + + put2byte(&aData[hdr+1], 0); + put2byte(&aData[hdr+3], pPg->nCell); + put2byte(&aData[hdr+5], pData - aData); + aData[hdr+7] = 0x00; + return SQLITE_OK; +} + +/* +** The pCArray objects contains pointers to b-tree cells and the cell sizes. +** This function attempts to add the cells stored in the array to page pPg. +** If it cannot (because the page needs to be defragmented before the cells +** will fit), non-zero is returned. Otherwise, if the cells are added +** successfully, zero is returned. +** +** Argument pCellptr points to the first entry in the cell-pointer array +** (part of page pPg) to populate. After cell apCell[0] is written to the +** page body, a 16-bit offset is written to pCellptr. And so on, for each +** cell in the array. It is the responsibility of the caller to ensure +** that it is safe to overwrite this part of the cell-pointer array. +** +** When this function is called, *ppData points to the start of the +** content area on page pPg. If the size of the content area is extended, +** *ppData is updated to point to the new start of the content area +** before returning. +** +** Finally, argument pBegin points to the byte immediately following the +** end of the space required by this page for the cell-pointer area (for +** all cells - not just those inserted by the current call). If the content +** area must be extended to before this point in order to accommodate all +** cells in apCell[], then the cells do not fit and non-zero is returned. +*/ +static int pageInsertArray( + MemPage *pPg, /* Page to add cells to */ + u8 *pBegin, /* End of cell-pointer array */ + u8 **ppData, /* IN/OUT: Page content-area pointer */ + u8 *pCellptr, /* Pointer to cell-pointer area */ + int iFirst, /* Index of first cell to add */ + int nCell, /* Number of cells to add to pPg */ + CellArray *pCArray /* Array of cells */ +){ + int i = iFirst; /* Loop counter - cell index to insert */ + u8 *aData = pPg->aData; /* Complete page */ + u8 *pData = *ppData; /* Content area. A subset of aData[] */ + int iEnd = iFirst + nCell; /* End of loop. One past last cell to ins */ + int k; /* Current slot in pCArray->apEnd[] */ + u8 *pEnd; /* Maximum extent of cell data */ + assert( CORRUPT_DB || pPg->hdrOffset==0 ); /* Never called on page 1 */ + if( iEnd<=iFirst ) return 0; + assert( pCArray->ixNx[NB*2-1]>i ); + for(k=0; pCArray->ixNx[k]<=i ; k++){} + pEnd = pCArray->apEnd[k]; + while( 1 /*Exit by break*/ ){ + int sz, rc; + u8 *pSlot; + assert( pCArray->szCell[i]!=0 ); + sz = pCArray->szCell[i]; + if( (aData[1]==0 && aData[2]==0) || (pSlot = pageFindSlot(pPg,sz,&rc))==0 ){ + if( (pData - pBegin)apCell[i] will never overlap on a well-formed + ** database. But they might for a corrupt database. Hence use memmove() + ** since memcpy() sends SIGABORT with overlapping buffers on OpenBSD */ + assert( (pSlot+sz)<=pCArray->apCell[i] + || pSlot>=(pCArray->apCell[i]+sz) + || CORRUPT_DB ); + if( (uptr)(pCArray->apCell[i]+sz)>(uptr)pEnd + && (uptr)(pCArray->apCell[i])<(uptr)pEnd + ){ + assert( CORRUPT_DB ); + (void)SQLITE_CORRUPT_BKPT; + return 1; + } + memmove(pSlot, pCArray->apCell[i], sz); + put2byte(pCellptr, (pSlot - aData)); + pCellptr += 2; + i++; + if( i>=iEnd ) break; + if( pCArray->ixNx[k]<=i ){ + k++; + pEnd = pCArray->apEnd[k]; + } + } + *ppData = pData; + return 0; +} + +/* +** The pCArray object contains pointers to b-tree cells and their sizes. +** +** This function adds the space associated with each cell in the array +** that is currently stored within the body of pPg to the pPg free-list. +** The cell-pointers and other fields of the page are not updated. +** +** This function returns the total number of cells added to the free-list. +*/ +static int pageFreeArray( + MemPage *pPg, /* Page to edit */ + int iFirst, /* First cell to delete */ + int nCell, /* Cells to delete */ + CellArray *pCArray /* Array of cells */ +){ + u8 * const aData = pPg->aData; + u8 * const pEnd = &aData[pPg->pBt->usableSize]; + u8 * const pStart = &aData[pPg->hdrOffset + 8 + pPg->childPtrSize]; + int nRet = 0; + int i, j; + int iEnd = iFirst + nCell; + int nFree = 0; + int aOfst[10]; + int aAfter[10]; + + for(i=iFirst; iapCell[i]; + if( SQLITE_WITHIN(pCell, pStart, pEnd) ){ + int sz; + int iAfter; + int iOfst; + /* No need to use cachedCellSize() here. The sizes of all cells that + ** are to be freed have already been computing while deciding which + ** cells need freeing */ + sz = pCArray->szCell[i]; assert( sz>0 ); + iOfst = (u16)(pCell - aData); + iAfter = iOfst+sz; + for(j=0; j=nFree ){ + if( nFree>=(int)(sizeof(aOfst)/sizeof(aOfst[0])) ){ + for(j=0; jpEnd ) return 0; + nFree++; + } + nRet++; + } + } + for(j=0; jnCell cells starting with +** pCArray->apCell[iOld]. After balancing, this page should hold nNew cells +** starting at apCell[iNew]. +** +** This routine makes the necessary adjustments to pPg so that it contains +** the correct cells after being balanced. +** +** The pPg->nFree field is invalid when this function returns. It is the +** responsibility of the caller to set it correctly. +*/ +static int editPage( + MemPage *pPg, /* Edit this page */ + int iOld, /* Index of first cell currently on page */ + int iNew, /* Index of new first cell on page */ + int nNew, /* Final number of cells on page */ + CellArray *pCArray /* Array of cells and sizes */ +){ + u8 * const aData = pPg->aData; + const int hdr = pPg->hdrOffset; + u8 *pBegin = &pPg->aCellIdx[nNew * 2]; + int nCell = pPg->nCell; /* Cells stored on pPg */ + u8 *pData; + u8 *pCellptr; + int i; + int iOldEnd = iOld + pPg->nCell + pPg->nOverflow; + int iNewEnd = iNew + nNew; + +#ifdef SQLITE_DEBUG + u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager); + memcpy(pTmp, aData, pPg->pBt->usableSize); +#endif + + /* Remove cells from the start and end of the page */ + assert( nCell>=0 ); + if( iOldnCell) ) return SQLITE_CORRUPT_BKPT; + memmove(pPg->aCellIdx, &pPg->aCellIdx[nShift*2], nCell*2); + nCell -= nShift; + } + if( iNewEnd < iOldEnd ){ + int nTail = pageFreeArray(pPg, iNewEnd, iOldEnd - iNewEnd, pCArray); + assert( nCell>=nTail ); + nCell -= nTail; + } + + pData = &aData[get2byte(&aData[hdr+5])]; + if( pDatapPg->aDataEnd) ) goto editpage_fail; + + /* Add cells to the start of the page */ + if( iNew=0 ); + pCellptr = pPg->aCellIdx; + memmove(&pCellptr[nAdd*2], pCellptr, nCell*2); + if( pageInsertArray( + pPg, pBegin, &pData, pCellptr, + iNew, nAdd, pCArray + ) ) goto editpage_fail; + nCell += nAdd; + } + + /* Add any overflow cells */ + for(i=0; inOverflow; i++){ + int iCell = (iOld + pPg->aiOvfl[i]) - iNew; + if( iCell>=0 && iCellaCellIdx[iCell * 2]; + if( nCell>iCell ){ + memmove(&pCellptr[2], pCellptr, (nCell - iCell) * 2); + } + nCell++; + cachedCellSize(pCArray, iCell+iNew); + if( pageInsertArray( + pPg, pBegin, &pData, pCellptr, + iCell+iNew, 1, pCArray + ) ) goto editpage_fail; + } + } + + /* Append cells to the end of the page */ + assert( nCell>=0 ); + pCellptr = &pPg->aCellIdx[nCell*2]; + if( pageInsertArray( + pPg, pBegin, &pData, pCellptr, + iNew+nCell, nNew-nCell, pCArray + ) + ){ + goto editpage_fail; + } + + assert( nNew < 10922 ); + pPg->nCell = (u16)nNew; + pPg->nOverflow = 0; + + put2byte(&aData[hdr+3], pPg->nCell); + put2byte(&aData[hdr+5], pData - aData); + +#ifdef SQLITE_DEBUG + for(i=0; iapCell[i+iNew]; + int iOff = get2byteAligned(&pPg->aCellIdx[i*2]); + if( SQLITE_WITHIN(pCell, aData, &aData[pPg->pBt->usableSize]) ){ + pCell = &pTmp[pCell - aData]; + } + assert( 0==memcmp(pCell, &aData[iOff], + pCArray->pRef->xCellSize(pCArray->pRef, pCArray->apCell[i+iNew])) ); + } +#endif + + return SQLITE_OK; + editpage_fail: + /* Unable to edit this page. Rebuild it from scratch instead. */ + if( nNew<1 ) return SQLITE_CORRUPT_BKPT; + populateCellCache(pCArray, iNew, nNew); + return rebuildPage(pCArray, iNew, nNew, pPg); +} + + +#ifndef SQLITE_OMIT_QUICKBALANCE +/* +** This version of balance() handles the common special case where +** a new entry is being inserted on the extreme right-end of the +** tree, in other words, when the new entry will become the largest +** entry in the tree. +** +** Instead of trying to balance the 3 right-most leaf pages, just add +** a new page to the right-hand side and put the one new entry in +** that page. This leaves the right side of the tree somewhat +** unbalanced. But odds are that we will be inserting new entries +** at the end soon afterwards so the nearly empty page will quickly +** fill up. On average. +** +** pPage is the leaf page which is the right-most page in the tree. +** pParent is its parent. pPage must have a single overflow entry +** which is also the right-most entry on the page. +** +** The pSpace buffer is used to store a temporary copy of the divider +** cell that will be inserted into pParent. Such a cell consists of a 4 +** byte page number followed by a variable length integer. In other +** words, at most 13 bytes. Hence the pSpace buffer must be at +** least 13 bytes in size. +*/ +static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ + BtShared *const pBt = pPage->pBt; /* B-Tree Database */ + MemPage *pNew; /* Newly allocated page */ + int rc; /* Return Code */ + Pgno pgnoNew; /* Page number of pNew */ + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); + assert( pPage->nOverflow==1 ); + + if( pPage->nCell==0 ) return SQLITE_CORRUPT_BKPT; /* dbfuzz001.test */ + assert( pPage->nFree>=0 ); + assert( pParent->nFree>=0 ); + + /* Allocate a new page. This page will become the right-sibling of + ** pPage. Make the parent page writable, so that the new divider cell + ** may be inserted. If both these operations are successful, proceed. + */ + rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0); + + if( rc==SQLITE_OK ){ + + u8 *pOut = &pSpace[4]; + u8 *pCell = pPage->apOvfl[0]; + u16 szCell = pPage->xCellSize(pPage, pCell); + u8 *pStop; + CellArray b; + + assert( sqlite3PagerIswriteable(pNew->pDbPage) ); + assert( CORRUPT_DB || pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) ); + zeroPage(pNew, PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF); + b.nCell = 1; + b.pRef = pPage; + b.apCell = &pCell; + b.szCell = &szCell; + b.apEnd[0] = pPage->aDataEnd; + b.ixNx[0] = 2; + b.ixNx[NB*2-1] = 0x7fffffff; + rc = rebuildPage(&b, 0, 1, pNew); + if( NEVER(rc) ){ + releasePage(pNew); + return rc; + } + pNew->nFree = pBt->usableSize - pNew->cellOffset - 2 - szCell; + + /* If this is an auto-vacuum database, update the pointer map + ** with entries for the new page, and any pointer from the + ** cell on the page to an overflow page. If either of these + ** operations fails, the return code is set, but the contents + ** of the parent page are still manipulated by the code below. + ** That is Ok, at this point the parent page is guaranteed to + ** be marked as dirty. Returning an error code will cause a + ** rollback, undoing any changes made to the parent page. + */ + if( ISAUTOVACUUM(pBt) ){ + ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno, &rc); + if( szCell>pNew->minLocal ){ + ptrmapPutOvflPtr(pNew, pNew, pCell, &rc); + } + } + + /* Create a divider cell to insert into pParent. The divider cell + ** consists of a 4-byte page number (the page number of pPage) and + ** a variable length key value (which must be the same value as the + ** largest key on pPage). + ** + ** To find the largest key value on pPage, first find the right-most + ** cell on pPage. The first two fields of this cell are the + ** record-length (a variable length integer at most 32-bits in size) + ** and the key value (a variable length integer, may have any value). + ** The first of the while(...) loops below skips over the record-length + ** field. The second while(...) loop copies the key value from the + ** cell on pPage into the pSpace buffer. + */ + pCell = findCell(pPage, pPage->nCell-1); + pStop = &pCell[9]; + while( (*(pCell++)&0x80) && pCellnCell, pSpace, (int)(pOut-pSpace), + 0, pPage->pgno); + } + + /* Set the right-child pointer of pParent to point to the new page. */ + put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew); + + /* Release the reference to the new page. */ + releasePage(pNew); + } + + return rc; +} +#endif /* SQLITE_OMIT_QUICKBALANCE */ + +#if 0 +/* +** This function does not contribute anything to the operation of SQLite. +** it is sometimes activated temporarily while debugging code responsible +** for setting pointer-map entries. +*/ +static int ptrmapCheckPages(MemPage **apPage, int nPage){ + int i, j; + for(i=0; ipBt; + assert( pPage->isInit ); + + for(j=0; jnCell; j++){ + CellInfo info; + u8 *z; + + z = findCell(pPage, j); + pPage->xParseCell(pPage, z, &info); + if( info.nLocalpgno && e==PTRMAP_OVERFLOW1 ); + } + if( !pPage->leaf ){ + Pgno child = get4byte(z); + ptrmapGet(pBt, child, &e, &n); + assert( n==pPage->pgno && e==PTRMAP_BTREE ); + } + } + if( !pPage->leaf ){ + Pgno child = get4byte(&pPage->aData[pPage->hdrOffset+8]); + ptrmapGet(pBt, child, &e, &n); + assert( n==pPage->pgno && e==PTRMAP_BTREE ); + } + } + return 1; +} +#endif + +/* +** This function is used to copy the contents of the b-tree node stored +** on page pFrom to page pTo. If page pFrom was not a leaf page, then +** the pointer-map entries for each child page are updated so that the +** parent page stored in the pointer map is page pTo. If pFrom contained +** any cells with overflow page pointers, then the corresponding pointer +** map entries are also updated so that the parent page is page pTo. +** +** If pFrom is currently carrying any overflow cells (entries in the +** MemPage.apOvfl[] array), they are not copied to pTo. +** +** Before returning, page pTo is reinitialized using btreeInitPage(). +** +** The performance of this function is not critical. It is only used by +** the balance_shallower() and balance_deeper() procedures, neither of +** which are called often under normal circumstances. +*/ +static void copyNodeContent(MemPage *pFrom, MemPage *pTo, int *pRC){ + if( (*pRC)==SQLITE_OK ){ + BtShared * const pBt = pFrom->pBt; + u8 * const aFrom = pFrom->aData; + u8 * const aTo = pTo->aData; + int const iFromHdr = pFrom->hdrOffset; + int const iToHdr = ((pTo->pgno==1) ? 100 : 0); + int rc; + int iData; + + + assert( pFrom->isInit ); + assert( pFrom->nFree>=iToHdr ); + assert( get2byte(&aFrom[iFromHdr+5]) <= (int)pBt->usableSize ); + + /* Copy the b-tree node content from page pFrom to page pTo. */ + iData = get2byte(&aFrom[iFromHdr+5]); + memcpy(&aTo[iData], &aFrom[iData], pBt->usableSize-iData); + memcpy(&aTo[iToHdr], &aFrom[iFromHdr], pFrom->cellOffset + 2*pFrom->nCell); + + /* Reinitialize page pTo so that the contents of the MemPage structure + ** match the new data. The initialization of pTo can actually fail under + ** fairly obscure circumstances, even though it is a copy of initialized + ** page pFrom. + */ + pTo->isInit = 0; + rc = btreeInitPage(pTo); + if( rc==SQLITE_OK ) rc = btreeComputeFreeSpace(pTo); + if( rc!=SQLITE_OK ){ + *pRC = rc; + return; + } + + /* If this is an auto-vacuum database, update the pointer-map entries + ** for any b-tree or overflow pages that pTo now contains the pointers to. + */ + if( ISAUTOVACUUM(pBt) ){ + *pRC = setChildPtrmaps(pTo); + } + } +} + +/* +** This routine redistributes cells on the iParentIdx'th child of pParent +** (hereafter "the page") and up to 2 siblings so that all pages have about the +** same amount of free space. Usually a single sibling on either side of the +** page are used in the balancing, though both siblings might come from one +** side if the page is the first or last child of its parent. If the page +** has fewer than 2 siblings (something which can only happen if the page +** is a root page or a child of a root page) then all available siblings +** participate in the balancing. +** +** The number of siblings of the page might be increased or decreased by +** one or two in an effort to keep pages nearly full but not over full. +** +** Note that when this routine is called, some of the cells on the page +** might not actually be stored in MemPage.aData[]. This can happen +** if the page is overfull. This routine ensures that all cells allocated +** to the page and its siblings fit into MemPage.aData[] before returning. +** +** In the course of balancing the page and its siblings, cells may be +** inserted into or removed from the parent page (pParent). Doing so +** may cause the parent page to become overfull or underfull. If this +** happens, it is the responsibility of the caller to invoke the correct +** balancing routine to fix this problem (see the balance() routine). +** +** If this routine fails for any reason, it might leave the database +** in a corrupted state. So if this routine fails, the database should +** be rolled back. +** +** The third argument to this function, aOvflSpace, is a pointer to a +** buffer big enough to hold one page. If while inserting cells into the parent +** page (pParent) the parent page becomes overfull, this buffer is +** used to store the parent's overflow cells. Because this function inserts +** a maximum of four divider cells into the parent page, and the maximum +** size of a cell stored within an internal node is always less than 1/4 +** of the page-size, the aOvflSpace[] buffer is guaranteed to be large +** enough for all overflow cells. +** +** If aOvflSpace is set to a null pointer, this function returns +** SQLITE_NOMEM. +*/ +static int balance_nonroot( + MemPage *pParent, /* Parent page of siblings being balanced */ + int iParentIdx, /* Index of "the page" in pParent */ + u8 *aOvflSpace, /* page-size bytes of space for parent ovfl */ + int isRoot, /* True if pParent is a root-page */ + int bBulk /* True if this call is part of a bulk load */ +){ + BtShared *pBt; /* The whole database */ + int nMaxCells = 0; /* Allocated size of apCell, szCell, aFrom. */ + int nNew = 0; /* Number of pages in apNew[] */ + int nOld; /* Number of pages in apOld[] */ + int i, j, k; /* Loop counters */ + int nxDiv; /* Next divider slot in pParent->aCell[] */ + int rc = SQLITE_OK; /* The return code */ + u16 leafCorrection; /* 4 if pPage is a leaf. 0 if not */ + int leafData; /* True if pPage is a leaf of a LEAFDATA tree */ + int usableSpace; /* Bytes in pPage beyond the header */ + int pageFlags; /* Value of pPage->aData[0] */ + int iSpace1 = 0; /* First unused byte of aSpace1[] */ + int iOvflSpace = 0; /* First unused byte of aOvflSpace[] */ + u64 szScratch; /* Size of scratch memory requested */ + MemPage *apOld[NB]; /* pPage and up to two siblings */ + MemPage *apNew[NB+2]; /* pPage and up to NB siblings after balancing */ + u8 *pRight; /* Location in parent of right-sibling pointer */ + u8 *apDiv[NB-1]; /* Divider cells in pParent */ + int cntNew[NB+2]; /* Index in b.paCell[] of cell after i-th page */ + int cntOld[NB+2]; /* Old index in b.apCell[] */ + int szNew[NB+2]; /* Combined size of cells placed on i-th page */ + u8 *aSpace1; /* Space for copies of dividers cells */ + Pgno pgno; /* Temp var to store a page number in */ + u8 abDone[NB+2]; /* True after i'th new page is populated */ + Pgno aPgno[NB+2]; /* Page numbers of new pages before shuffling */ + CellArray b; /* Parsed information on cells being balanced */ + + memset(abDone, 0, sizeof(abDone)); + assert( sizeof(b) - sizeof(b.ixNx) == offsetof(CellArray,ixNx) ); + memset(&b, 0, sizeof(b)-sizeof(b.ixNx[0])); + b.ixNx[NB*2-1] = 0x7fffffff; + pBt = pParent->pBt; + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); + + /* At this point pParent may have at most one overflow cell. And if + ** this overflow cell is present, it must be the cell with + ** index iParentIdx. This scenario comes about when this function + ** is called (indirectly) from sqlite3BtreeDelete(). + */ + assert( pParent->nOverflow==0 || pParent->nOverflow==1 ); + assert( pParent->nOverflow==0 || pParent->aiOvfl[0]==iParentIdx ); + + if( !aOvflSpace ){ + return SQLITE_NOMEM_BKPT; + } + assert( pParent->nFree>=0 ); + + /* Find the sibling pages to balance. Also locate the cells in pParent + ** that divide the siblings. An attempt is made to find NN siblings on + ** either side of pPage. More siblings are taken from one side, however, + ** if there are fewer than NN siblings on the other side. If pParent + ** has NB or fewer children then all children of pParent are taken. + ** + ** This loop also drops the divider cells from the parent page. This + ** way, the remainder of the function does not have to deal with any + ** overflow cells in the parent page, since if any existed they will + ** have already been removed. + */ + i = pParent->nOverflow + pParent->nCell; + if( i<2 ){ + nxDiv = 0; + }else{ + assert( bBulk==0 || bBulk==1 ); + if( iParentIdx==0 ){ + nxDiv = 0; + }else if( iParentIdx==i ){ + nxDiv = i-2+bBulk; + }else{ + nxDiv = iParentIdx-1; + } + i = 2-bBulk; + } + nOld = i+1; + if( (i+nxDiv-pParent->nOverflow)==pParent->nCell ){ + pRight = &pParent->aData[pParent->hdrOffset+8]; + }else{ + pRight = findCell(pParent, i+nxDiv-pParent->nOverflow); + } + pgno = get4byte(pRight); + while( 1 ){ + if( rc==SQLITE_OK ){ + rc = getAndInitPage(pBt, pgno, &apOld[i], 0); + } + if( rc ){ + memset(apOld, 0, (i+1)*sizeof(MemPage*)); + goto balance_cleanup; + } + if( apOld[i]->nFree<0 ){ + rc = btreeComputeFreeSpace(apOld[i]); + if( rc ){ + memset(apOld, 0, (i)*sizeof(MemPage*)); + goto balance_cleanup; + } + } + nMaxCells += apOld[i]->nCell + ArraySize(pParent->apOvfl); + if( (i--)==0 ) break; + + if( pParent->nOverflow && i+nxDiv==pParent->aiOvfl[0] ){ + apDiv[i] = pParent->apOvfl[0]; + pgno = get4byte(apDiv[i]); + szNew[i] = pParent->xCellSize(pParent, apDiv[i]); + pParent->nOverflow = 0; + }else{ + apDiv[i] = findCell(pParent, i+nxDiv-pParent->nOverflow); + pgno = get4byte(apDiv[i]); + szNew[i] = pParent->xCellSize(pParent, apDiv[i]); + + /* Drop the cell from the parent page. apDiv[i] still points to + ** the cell within the parent, even though it has been dropped. + ** This is safe because dropping a cell only overwrites the first + ** four bytes of it, and this function does not need the first + ** four bytes of the divider cell. So the pointer is safe to use + ** later on. + ** + ** But not if we are in secure-delete mode. In secure-delete mode, + ** the dropCell() routine will overwrite the entire cell with zeroes. + ** In this case, temporarily copy the cell into the aOvflSpace[] + ** buffer. It will be copied out again as soon as the aSpace[] buffer + ** is allocated. */ + if( pBt->btsFlags & BTS_FAST_SECURE ){ + int iOff; + + /* If the following if() condition is not true, the db is corrupted. + ** The call to dropCell() below will detect this. */ + iOff = SQLITE_PTR_TO_INT(apDiv[i]) - SQLITE_PTR_TO_INT(pParent->aData); + if( (iOff+szNew[i])<=(int)pBt->usableSize ){ + memcpy(&aOvflSpace[iOff], apDiv[i], szNew[i]); + apDiv[i] = &aOvflSpace[apDiv[i]-pParent->aData]; + } + } + dropCell(pParent, i+nxDiv-pParent->nOverflow, szNew[i], &rc); + } + } + + /* Make nMaxCells a multiple of 4 in order to preserve 8-byte + ** alignment */ + nMaxCells = (nMaxCells + 3)&~3; + + /* + ** Allocate space for memory structures + */ + szScratch = + nMaxCells*sizeof(u8*) /* b.apCell */ + + nMaxCells*sizeof(u16) /* b.szCell */ + + pBt->pageSize; /* aSpace1 */ + + assert( szScratch<=7*(int)pBt->pageSize ); + b.apCell = sqlite3StackAllocRaw(0, szScratch ); + if( b.apCell==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto balance_cleanup; + } + b.szCell = (u16*)&b.apCell[nMaxCells]; + aSpace1 = (u8*)&b.szCell[nMaxCells]; + assert( EIGHT_BYTE_ALIGNMENT(aSpace1) ); + + /* + ** Load pointers to all cells on sibling pages and the divider cells + ** into the local b.apCell[] array. Make copies of the divider cells + ** into space obtained from aSpace1[]. The divider cells have already + ** been removed from pParent. + ** + ** If the siblings are on leaf pages, then the child pointers of the + ** divider cells are stripped from the cells before they are copied + ** into aSpace1[]. In this way, all cells in b.apCell[] are without + ** child pointers. If siblings are not leaves, then all cell in + ** b.apCell[] include child pointers. Either way, all cells in b.apCell[] + ** are alike. + ** + ** leafCorrection: 4 if pPage is a leaf. 0 if pPage is not a leaf. + ** leafData: 1 if pPage holds key+data and pParent holds only keys. + */ + b.pRef = apOld[0]; + leafCorrection = b.pRef->leaf*4; + leafData = b.pRef->intKeyLeaf; + for(i=0; inCell; + u8 *aData = pOld->aData; + u16 maskPage = pOld->maskPage; + u8 *piCell = aData + pOld->cellOffset; + u8 *piEnd; + VVA_ONLY( int nCellAtStart = b.nCell; ) + + /* Verify that all sibling pages are of the same "type" (table-leaf, + ** table-interior, index-leaf, or index-interior). + */ + if( pOld->aData[0]!=apOld[0]->aData[0] ){ + rc = SQLITE_CORRUPT_PAGE(pOld); + goto balance_cleanup; + } + + /* Load b.apCell[] with pointers to all cells in pOld. If pOld + ** contains overflow cells, include them in the b.apCell[] array + ** in the correct spot. + ** + ** Note that when there are multiple overflow cells, it is always the + ** case that they are sequential and adjacent. This invariant arises + ** because multiple overflows can only occurs when inserting divider + ** cells into a parent on a prior balance, and divider cells are always + ** adjacent and are inserted in order. There is an assert() tagged + ** with "NOTE 1" in the overflow cell insertion loop to prove this + ** invariant. + ** + ** This must be done in advance. Once the balance starts, the cell + ** offset section of the btree page will be overwritten and we will no + ** long be able to find the cells if a pointer to each cell is not saved + ** first. + */ + memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow)); + if( pOld->nOverflow>0 ){ + if( NEVER(limitaiOvfl[0]) ){ + rc = SQLITE_CORRUPT_PAGE(pOld); + goto balance_cleanup; + } + limit = pOld->aiOvfl[0]; + for(j=0; jnOverflow; k++){ + assert( k==0 || pOld->aiOvfl[k-1]+1==pOld->aiOvfl[k] );/* NOTE 1 */ + b.apCell[b.nCell] = pOld->apOvfl[k]; + b.nCell++; + } + } + piEnd = aData + pOld->cellOffset + 2*pOld->nCell; + while( piCellnCell+pOld->nOverflow) ); + + cntOld[i] = b.nCell; + if( imaxLocal+23 ); + assert( iSpace1 <= (int)pBt->pageSize ); + memcpy(pTemp, apDiv[i], sz); + b.apCell[b.nCell] = pTemp+leafCorrection; + assert( leafCorrection==0 || leafCorrection==4 ); + b.szCell[b.nCell] = b.szCell[b.nCell] - leafCorrection; + if( !pOld->leaf ){ + assert( leafCorrection==0 ); + assert( pOld->hdrOffset==0 || CORRUPT_DB ); + /* The right pointer of the child page pOld becomes the left + ** pointer of the divider cell */ + memcpy(b.apCell[b.nCell], &pOld->aData[8], 4); + }else{ + assert( leafCorrection==4 ); + while( b.szCell[b.nCell]<4 ){ + /* Do not allow any cells smaller than 4 bytes. If a smaller cell + ** does exist, pad it with 0x00 bytes. */ + assert( b.szCell[b.nCell]==3 || CORRUPT_DB ); + assert( b.apCell[b.nCell]==&aSpace1[iSpace1-3] || CORRUPT_DB ); + aSpace1[iSpace1++] = 0x00; + b.szCell[b.nCell]++; + } + } + b.nCell++; + } + } + + /* + ** Figure out the number of pages needed to hold all b.nCell cells. + ** Store this number in "k". Also compute szNew[] which is the total + ** size of all cells on the i-th page and cntNew[] which is the index + ** in b.apCell[] of the cell that divides page i from page i+1. + ** cntNew[k] should equal b.nCell. + ** + ** Values computed by this block: + ** + ** k: The total number of sibling pages + ** szNew[i]: Spaced used on the i-th sibling page. + ** cntNew[i]: Index in b.apCell[] and b.szCell[] for the first cell to + ** the right of the i-th sibling page. + ** usableSpace: Number of bytes of space available on each sibling. + ** + */ + usableSpace = pBt->usableSize - 12 + leafCorrection; + for(i=k=0; iaDataEnd; + b.ixNx[k] = cntOld[i]; + if( k && b.ixNx[k]==b.ixNx[k-1] ){ + k--; /* Omit b.ixNx[] entry for child pages with no cells */ + } + if( !leafData ){ + k++; + b.apEnd[k] = pParent->aDataEnd; + b.ixNx[k] = cntOld[i]+1; + } + assert( p->nFree>=0 ); + szNew[i] = usableSpace - p->nFree; + for(j=0; jnOverflow; j++){ + szNew[i] += 2 + p->xCellSize(p, p->apOvfl[j]); + } + cntNew[i] = cntOld[i]; + } + k = nOld; + for(i=0; iusableSpace ){ + if( i+1>=k ){ + k = i+2; + if( k>NB+2 ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; } + szNew[k-1] = 0; + cntNew[k-1] = b.nCell; + } + sz = 2 + cachedCellSize(&b, cntNew[i]-1); + szNew[i] -= sz; + if( !leafData ){ + if( cntNew[i]usableSpace ) break; + szNew[i] += sz; + cntNew[i]++; + if( !leafData ){ + if( cntNew[i]=b.nCell ){ + k = i+1; + }else if( cntNew[i] <= (i>0 ? cntNew[i-1] : 0) ){ + rc = SQLITE_CORRUPT_BKPT; + goto balance_cleanup; + } + } + + /* + ** The packing computed by the previous block is biased toward the siblings + ** on the left side (siblings with smaller keys). The left siblings are + ** always nearly full, while the right-most sibling might be nearly empty. + ** The next block of code attempts to adjust the packing of siblings to + ** get a better balance. + ** + ** This adjustment is more than an optimization. The packing above might + ** be so out of balance as to be illegal. For example, the right-most + ** sibling might be completely empty. This adjustment is not optional. + */ + for(i=k-1; i>0; i--){ + int szRight = szNew[i]; /* Size of sibling on the right */ + int szLeft = szNew[i-1]; /* Size of sibling on the left */ + int r; /* Index of right-most cell in left sibling */ + int d; /* Index of first cell to the left of right sibling */ + + r = cntNew[i-1] - 1; + d = r + 1 - leafData; + (void)cachedCellSize(&b, d); + do{ + int szR, szD; + assert( d szLeft-(szR+(i==k-1?0:2)))){ + break; + } + szRight += szD + 2; + szLeft -= szR + 2; + cntNew[i-1] = r; + r--; + d--; + }while( r>=0 ); + szNew[i] = szRight; + szNew[i-1] = szLeft; + if( cntNew[i-1] <= (i>1 ? cntNew[i-2] : 0) ){ + rc = SQLITE_CORRUPT_BKPT; + goto balance_cleanup; + } + } + + /* Sanity check: For a non-corrupt database file one of the following + ** must be true: + ** (1) We found one or more cells (cntNew[0])>0), or + ** (2) pPage is a virtual root page. A virtual root page is when + ** the real root page is page 1 and we are the only child of + ** that page. + */ + assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) || CORRUPT_DB); + TRACE(("BALANCE: old: %u(nc=%u) %u(nc=%u) %u(nc=%u)\n", + apOld[0]->pgno, apOld[0]->nCell, + nOld>=2 ? apOld[1]->pgno : 0, nOld>=2 ? apOld[1]->nCell : 0, + nOld>=3 ? apOld[2]->pgno : 0, nOld>=3 ? apOld[2]->nCell : 0 + )); + + /* + ** Allocate k new pages. Reuse old pages where possible. + */ + pageFlags = apOld[0]->aData[0]; + for(i=0; ipDbPage); + nNew++; + if( sqlite3PagerPageRefcount(pNew->pDbPage)!=1+(i==(iParentIdx-nxDiv)) + && rc==SQLITE_OK + ){ + rc = SQLITE_CORRUPT_BKPT; + } + if( rc ) goto balance_cleanup; + }else{ + assert( i>0 ); + rc = allocateBtreePage(pBt, &pNew, &pgno, (bBulk ? 1 : pgno), 0); + if( rc ) goto balance_cleanup; + zeroPage(pNew, pageFlags); + apNew[i] = pNew; + nNew++; + cntOld[i] = b.nCell; + + /* Set the pointer-map entry for the new sibling page. */ + if( ISAUTOVACUUM(pBt) ){ + ptrmapPut(pBt, pNew->pgno, PTRMAP_BTREE, pParent->pgno, &rc); + if( rc!=SQLITE_OK ){ + goto balance_cleanup; + } + } + } + } + + /* + ** Reassign page numbers so that the new pages are in ascending order. + ** This helps to keep entries in the disk file in order so that a scan + ** of the table is closer to a linear scan through the file. That in turn + ** helps the operating system to deliver pages from the disk more rapidly. + ** + ** An O(N*N) sort algorithm is used, but since N is never more than NB+2 + ** (5), that is not a performance concern. + ** + ** When NB==3, this one optimization makes the database about 25% faster + ** for large insertions and deletions. + */ + for(i=0; ipgno; + assert( apNew[i]->pDbPage->flags & PGHDR_WRITEABLE ); + assert( apNew[i]->pDbPage->flags & PGHDR_DIRTY ); + } + for(i=0; ipgno < apNew[iB]->pgno ) iB = j; + } + + /* If apNew[i] has a page number that is bigger than any of the + ** subsequence apNew[i] entries, then swap apNew[i] with the subsequent + ** entry that has the smallest page number (which we know to be + ** entry apNew[iB]). + */ + if( iB!=i ){ + Pgno pgnoA = apNew[i]->pgno; + Pgno pgnoB = apNew[iB]->pgno; + Pgno pgnoTemp = (PENDING_BYTE/pBt->pageSize)+1; + u16 fgA = apNew[i]->pDbPage->flags; + u16 fgB = apNew[iB]->pDbPage->flags; + sqlite3PagerRekey(apNew[i]->pDbPage, pgnoTemp, fgB); + sqlite3PagerRekey(apNew[iB]->pDbPage, pgnoA, fgA); + sqlite3PagerRekey(apNew[i]->pDbPage, pgnoB, fgB); + apNew[i]->pgno = pgnoB; + apNew[iB]->pgno = pgnoA; + } + } + + TRACE(("BALANCE: new: %u(%u nc=%u) %u(%u nc=%u) %u(%u nc=%u) " + "%u(%u nc=%u) %u(%u nc=%u)\n", + apNew[0]->pgno, szNew[0], cntNew[0], + nNew>=2 ? apNew[1]->pgno : 0, nNew>=2 ? szNew[1] : 0, + nNew>=2 ? cntNew[1] - cntNew[0] - !leafData : 0, + nNew>=3 ? apNew[2]->pgno : 0, nNew>=3 ? szNew[2] : 0, + nNew>=3 ? cntNew[2] - cntNew[1] - !leafData : 0, + nNew>=4 ? apNew[3]->pgno : 0, nNew>=4 ? szNew[3] : 0, + nNew>=4 ? cntNew[3] - cntNew[2] - !leafData : 0, + nNew>=5 ? apNew[4]->pgno : 0, nNew>=5 ? szNew[4] : 0, + nNew>=5 ? cntNew[4] - cntNew[3] - !leafData : 0 + )); + + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); + assert( nNew>=1 && nNew<=ArraySize(apNew) ); + assert( apNew[nNew-1]!=0 ); + put4byte(pRight, apNew[nNew-1]->pgno); + + /* If the sibling pages are not leaves, ensure that the right-child pointer + ** of the right-most new sibling page is set to the value that was + ** originally in the same field of the right-most old sibling page. */ + if( (pageFlags & PTF_LEAF)==0 && nOld!=nNew ){ + MemPage *pOld; + if( nNew>nOld ){ + pOld = apNew[nOld-1]; + }else{ + pOld = apOld[nOld-1]; + } + memcpy(&apNew[nNew-1]->aData[8], &pOld->aData[8], 4); + } + + /* Make any required updates to pointer map entries associated with + ** cells stored on sibling pages following the balance operation. Pointer + ** map entries associated with divider cells are set by the insertCell() + ** routine. The associated pointer map entries are: + ** + ** a) if the cell contains a reference to an overflow chain, the + ** entry associated with the first page in the overflow chain, and + ** + ** b) if the sibling pages are not leaves, the child page associated + ** with the cell. + ** + ** If the sibling pages are not leaves, then the pointer map entry + ** associated with the right-child of each sibling may also need to be + ** updated. This happens below, after the sibling pages have been + ** populated, not here. + */ + if( ISAUTOVACUUM(pBt) ){ + MemPage *pOld; + MemPage *pNew = pOld = apNew[0]; + int cntOldNext = pNew->nCell + pNew->nOverflow; + int iNew = 0; + int iOld = 0; + + for(i=0; i=0 && iOldnCell + pOld->nOverflow + !leafData; + } + if( i==cntNew[iNew] ){ + pNew = apNew[++iNew]; + if( !leafData ) continue; + } + + /* Cell pCell is destined for new sibling page pNew. Originally, it + ** was either part of sibling page iOld (possibly an overflow cell), + ** or else the divider cell to the left of sibling page iOld. So, + ** if sibling page iOld had the same page number as pNew, and if + ** pCell really was a part of sibling page iOld (not a divider or + ** overflow cell), we can skip updating the pointer map entries. */ + if( iOld>=nNew + || pNew->pgno!=aPgno[iOld] + || !SQLITE_WITHIN(pCell,pOld->aData,pOld->aDataEnd) + ){ + if( !leafCorrection ){ + ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno, &rc); + } + if( cachedCellSize(&b,i)>pNew->minLocal ){ + ptrmapPutOvflPtr(pNew, pOld, pCell, &rc); + } + if( rc ) goto balance_cleanup; + } + } + } + + /* Insert new divider cells into pParent. */ + for(i=0; ileaf ){ + memcpy(&pNew->aData[8], pCell, 4); + }else if( leafData ){ + /* If the tree is a leaf-data tree, and the siblings are leaves, + ** then there is no divider cell in b.apCell[]. Instead, the divider + ** cell consists of the integer key for the right-most cell of + ** the sibling-page assembled above only. + */ + CellInfo info; + j--; + pNew->xParseCell(pNew, b.apCell[j], &info); + pCell = pTemp; + sz = 4 + putVarint(&pCell[4], info.nKey); + pTemp = 0; + }else{ + pCell -= 4; + /* Obscure case for non-leaf-data trees: If the cell at pCell was + ** previously stored on a leaf node, and its reported size was 4 + ** bytes, then it may actually be smaller than this + ** (see btreeParseCellPtr(), 4 bytes is the minimum size of + ** any cell). But it is important to pass the correct size to + ** insertCell(), so reparse the cell now. + ** + ** This can only happen for b-trees used to evaluate "IN (SELECT ...)" + ** and WITHOUT ROWID tables with exactly one column which is the + ** primary key. + */ + if( b.szCell[j]==4 ){ + assert(leafCorrection==4); + sz = pParent->xCellSize(pParent, pCell); + } + } + iOvflSpace += sz; + assert( sz<=pBt->maxLocal+23 ); + assert( iOvflSpace <= (int)pBt->pageSize ); + assert( b.ixNx[NB*2-1]>j ); + for(k=0; b.ixNx[k]<=j; k++){} + pSrcEnd = b.apEnd[k]; + if( SQLITE_OVERFLOW(pSrcEnd, pCell, pCell+sz) ){ + rc = SQLITE_CORRUPT_BKPT; + goto balance_cleanup; + } + rc = insertCell(pParent, nxDiv+i, pCell, sz, pTemp, pNew->pgno); + if( rc!=SQLITE_OK ) goto balance_cleanup; + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); + } + + /* Now update the actual sibling pages. The order in which they are updated + ** is important, as this code needs to avoid disrupting any page from which + ** cells may still to be read. In practice, this means: + ** + ** (1) If cells are moving left (from apNew[iPg] to apNew[iPg-1]) + ** then it is not safe to update page apNew[iPg] until after + ** the left-hand sibling apNew[iPg-1] has been updated. + ** + ** (2) If cells are moving right (from apNew[iPg] to apNew[iPg+1]) + ** then it is not safe to update page apNew[iPg] until after + ** the right-hand sibling apNew[iPg+1] has been updated. + ** + ** If neither of the above apply, the page is safe to update. + ** + ** The iPg value in the following loop starts at nNew-1 goes down + ** to 0, then back up to nNew-1 again, thus making two passes over + ** the pages. On the initial downward pass, only condition (1) above + ** needs to be tested because (2) will always be true from the previous + ** step. On the upward pass, both conditions are always true, so the + ** upwards pass simply processes pages that were missed on the downward + ** pass. + */ + for(i=1-nNew; i=0 && iPg=1 || i>=0 ); + assert( iPg=0 /* On the upwards pass, or... */ + || cntOld[iPg-1]>=cntNew[iPg-1] /* Condition (1) is true */ + ){ + int iNew; + int iOld; + int nNewCell; + + /* Verify condition (1): If cells are moving left, update iPg + ** only after iPg-1 has already been updated. */ + assert( iPg==0 || cntOld[iPg-1]>=cntNew[iPg-1] || abDone[iPg-1] ); + + /* Verify condition (2): If cells are moving right, update iPg + ** only after iPg+1 has already been updated. */ + assert( cntNew[iPg]>=cntOld[iPg] || abDone[iPg+1] ); + + if( iPg==0 ){ + iNew = iOld = 0; + nNewCell = cntNew[0]; + }else{ + iOld = iPgnFree = usableSpace-szNew[iPg]; + assert( apNew[iPg]->nOverflow==0 ); + assert( apNew[iPg]->nCell==nNewCell ); + } + } + + /* All pages have been processed exactly once */ + assert( memcmp(abDone, "\01\01\01\01\01", nNew)==0 ); + + assert( nOld>0 ); + assert( nNew>0 ); + + if( isRoot && pParent->nCell==0 && pParent->hdrOffset<=apNew[0]->nFree ){ + /* The root page of the b-tree now contains no cells. The only sibling + ** page is the right-child of the parent. Copy the contents of the + ** child page into the parent, decreasing the overall height of the + ** b-tree structure by one. This is described as the "balance-shallower" + ** sub-algorithm in some documentation. + ** + ** If this is an auto-vacuum database, the call to copyNodeContent() + ** sets all pointer-map entries corresponding to database image pages + ** for which the pointer is stored within the content being copied. + ** + ** It is critical that the child page be defragmented before being + ** copied into the parent, because if the parent is page 1 then it will + ** by smaller than the child due to the database header, and so all the + ** free space needs to be up front. + */ + assert( nNew==1 || CORRUPT_DB ); + rc = defragmentPage(apNew[0], -1); + testcase( rc!=SQLITE_OK ); + assert( apNew[0]->nFree == + (get2byteNotZero(&apNew[0]->aData[5]) - apNew[0]->cellOffset + - apNew[0]->nCell*2) + || rc!=SQLITE_OK + ); + copyNodeContent(apNew[0], pParent, &rc); + freePage(apNew[0], &rc); + }else if( ISAUTOVACUUM(pBt) && !leafCorrection ){ + /* Fix the pointer map entries associated with the right-child of each + ** sibling page. All other pointer map entries have already been taken + ** care of. */ + for(i=0; iaData[8]); + ptrmapPut(pBt, key, PTRMAP_BTREE, apNew[i]->pgno, &rc); + } + } + + assert( pParent->isInit ); + TRACE(("BALANCE: finished: old=%u new=%u cells=%u\n", + nOld, nNew, b.nCell)); + + /* Free any old pages that were not reused as new pages. + */ + for(i=nNew; iisInit ){ + /* The ptrmapCheckPages() contains assert() statements that verify that + ** all pointer map pages are set correctly. This is helpful while + ** debugging. This is usually disabled because a corrupt database may + ** cause an assert() statement to fail. */ + ptrmapCheckPages(apNew, nNew); + ptrmapCheckPages(&pParent, 1); + } +#endif + + /* + ** Cleanup before returning. + */ +balance_cleanup: + sqlite3StackFree(0, b.apCell); + for(i=0; ipBt; /* The BTree */ + + assert( pRoot->nOverflow>0 ); + assert( sqlite3_mutex_held(pBt->mutex) ); + + /* Make pRoot, the root page of the b-tree, writable. Allocate a new + ** page that will become the new right-child of pPage. Copy the contents + ** of the node stored on pRoot into the new child page. + */ + rc = sqlite3PagerWrite(pRoot->pDbPage); + if( rc==SQLITE_OK ){ + rc = allocateBtreePage(pBt,&pChild,&pgnoChild,pRoot->pgno,0); + copyNodeContent(pRoot, pChild, &rc); + if( ISAUTOVACUUM(pBt) ){ + ptrmapPut(pBt, pgnoChild, PTRMAP_BTREE, pRoot->pgno, &rc); + } + } + if( rc ){ + *ppChild = 0; + releasePage(pChild); + return rc; + } + assert( sqlite3PagerIswriteable(pChild->pDbPage) ); + assert( sqlite3PagerIswriteable(pRoot->pDbPage) ); + assert( pChild->nCell==pRoot->nCell || CORRUPT_DB ); + + TRACE(("BALANCE: copy root %u into %u\n", pRoot->pgno, pChild->pgno)); + + /* Copy the overflow cells from pRoot to pChild */ + memcpy(pChild->aiOvfl, pRoot->aiOvfl, + pRoot->nOverflow*sizeof(pRoot->aiOvfl[0])); + memcpy(pChild->apOvfl, pRoot->apOvfl, + pRoot->nOverflow*sizeof(pRoot->apOvfl[0])); + pChild->nOverflow = pRoot->nOverflow; + + /* Zero the contents of pRoot. Then install pChild as the right-child. */ + zeroPage(pRoot, pChild->aData[0] & ~PTF_LEAF); + put4byte(&pRoot->aData[pRoot->hdrOffset+8], pgnoChild); + + *ppChild = pChild; + return SQLITE_OK; +} + +/* +** Return SQLITE_CORRUPT if any cursor other than pCur is currently valid +** on the same B-tree as pCur. +** +** This can occur if a database is corrupt with two or more SQL tables +** pointing to the same b-tree. If an insert occurs on one SQL table +** and causes a BEFORE TRIGGER to do a secondary insert on the other SQL +** table linked to the same b-tree. If the secondary insert causes a +** rebalance, that can change content out from under the cursor on the +** first SQL table, violating invariants on the first insert. +*/ +static int anotherValidCursor(BtCursor *pCur){ + BtCursor *pOther; + for(pOther=pCur->pBt->pCursor; pOther; pOther=pOther->pNext){ + if( pOther!=pCur + && pOther->eState==CURSOR_VALID + && pOther->pPage==pCur->pPage + ){ + return SQLITE_CORRUPT_PAGE(pCur->pPage); + } + } + return SQLITE_OK; +} + +/* +** The page that pCur currently points to has just been modified in +** some way. This function figures out if this modification means the +** tree needs to be balanced, and if so calls the appropriate balancing +** routine. Balancing routines are: +** +** balance_quick() +** balance_deeper() +** balance_nonroot() +*/ +static int balance(BtCursor *pCur){ + int rc = SQLITE_OK; + u8 aBalanceQuickSpace[13]; + u8 *pFree = 0; + + VVA_ONLY( int balance_quick_called = 0 ); + VVA_ONLY( int balance_deeper_called = 0 ); + + do { + int iPage; + MemPage *pPage = pCur->pPage; + + if( NEVER(pPage->nFree<0) && btreeComputeFreeSpace(pPage) ) break; + if( pPage->nOverflow==0 && pPage->nFree*3<=(int)pCur->pBt->usableSize*2 ){ + /* No rebalance required as long as: + ** (1) There are no overflow cells + ** (2) The amount of free space on the page is less than 2/3rds of + ** the total usable space on the page. */ + break; + }else if( (iPage = pCur->iPage)==0 ){ + if( pPage->nOverflow && (rc = anotherValidCursor(pCur))==SQLITE_OK ){ + /* The root page of the b-tree is overfull. In this case call the + ** balance_deeper() function to create a new child for the root-page + ** and copy the current contents of the root-page to it. The + ** next iteration of the do-loop will balance the child page. + */ + assert( balance_deeper_called==0 ); + VVA_ONLY( balance_deeper_called++ ); + rc = balance_deeper(pPage, &pCur->apPage[1]); + if( rc==SQLITE_OK ){ + pCur->iPage = 1; + pCur->ix = 0; + pCur->aiIdx[0] = 0; + pCur->apPage[0] = pPage; + pCur->pPage = pCur->apPage[1]; + assert( pCur->pPage->nOverflow ); + } + }else{ + break; + } + }else if( sqlite3PagerPageRefcount(pPage->pDbPage)>1 ){ + /* The page being written is not a root page, and there is currently + ** more than one reference to it. This only happens if the page is one + ** of its own ancestor pages. Corruption. */ + rc = SQLITE_CORRUPT_PAGE(pPage); + }else{ + MemPage * const pParent = pCur->apPage[iPage-1]; + int const iIdx = pCur->aiIdx[iPage-1]; + + rc = sqlite3PagerWrite(pParent->pDbPage); + if( rc==SQLITE_OK && pParent->nFree<0 ){ + rc = btreeComputeFreeSpace(pParent); + } + if( rc==SQLITE_OK ){ +#ifndef SQLITE_OMIT_QUICKBALANCE + if( pPage->intKeyLeaf + && pPage->nOverflow==1 + && pPage->aiOvfl[0]==pPage->nCell + && pParent->pgno!=1 + && pParent->nCell==iIdx + ){ + /* Call balance_quick() to create a new sibling of pPage on which + ** to store the overflow cell. balance_quick() inserts a new cell + ** into pParent, which may cause pParent overflow. If this + ** happens, the next iteration of the do-loop will balance pParent + ** use either balance_nonroot() or balance_deeper(). Until this + ** happens, the overflow cell is stored in the aBalanceQuickSpace[] + ** buffer. + ** + ** The purpose of the following assert() is to check that only a + ** single call to balance_quick() is made for each call to this + ** function. If this were not verified, a subtle bug involving reuse + ** of the aBalanceQuickSpace[] might sneak in. + */ + assert( balance_quick_called==0 ); + VVA_ONLY( balance_quick_called++ ); + rc = balance_quick(pParent, pPage, aBalanceQuickSpace); + }else +#endif + { + /* In this case, call balance_nonroot() to redistribute cells + ** between pPage and up to 2 of its sibling pages. This involves + ** modifying the contents of pParent, which may cause pParent to + ** become overfull or underfull. The next iteration of the do-loop + ** will balance the parent page to correct this. + ** + ** If the parent page becomes overfull, the overflow cell or cells + ** are stored in the pSpace buffer allocated immediately below. + ** A subsequent iteration of the do-loop will deal with this by + ** calling balance_nonroot() (balance_deeper() may be called first, + ** but it doesn't deal with overflow cells - just moves them to a + ** different page). Once this subsequent call to balance_nonroot() + ** has completed, it is safe to release the pSpace buffer used by + ** the previous call, as the overflow cell data will have been + ** copied either into the body of a database page or into the new + ** pSpace buffer passed to the latter call to balance_nonroot(). + */ + u8 *pSpace = sqlite3PageMalloc(pCur->pBt->pageSize); + rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1, + pCur->hints&BTREE_BULKLOAD); + if( pFree ){ + /* If pFree is not NULL, it points to the pSpace buffer used + ** by a previous call to balance_nonroot(). Its contents are + ** now stored either on real database pages or within the + ** new pSpace buffer, so it may be safely freed here. */ + sqlite3PageFree(pFree); + } + + /* The pSpace buffer will be freed after the next call to + ** balance_nonroot(), or just before this function returns, whichever + ** comes first. */ + pFree = pSpace; + } + } + + pPage->nOverflow = 0; + + /* The next iteration of the do-loop balances the parent page. */ + releasePage(pPage); + pCur->iPage--; + assert( pCur->iPage>=0 ); + pCur->pPage = pCur->apPage[pCur->iPage]; + } + }while( rc==SQLITE_OK ); + + if( pFree ){ + sqlite3PageFree(pFree); + } + return rc; +} + +/* Overwrite content from pX into pDest. Only do the write if the +** content is different from what is already there. +*/ +static int btreeOverwriteContent( + MemPage *pPage, /* MemPage on which writing will occur */ + u8 *pDest, /* Pointer to the place to start writing */ + const BtreePayload *pX, /* Source of data to write */ + int iOffset, /* Offset of first byte to write */ + int iAmt /* Number of bytes to be written */ +){ + int nData = pX->nData - iOffset; + if( nData<=0 ){ + /* Overwriting with zeros */ + int i; + for(i=0; ipDbPage); + if( rc ) return rc; + memset(pDest + i, 0, iAmt - i); + } + }else{ + if( nDatapData) + iOffset, iAmt)!=0 ){ + int rc = sqlite3PagerWrite(pPage->pDbPage); + if( rc ) return rc; + /* In a corrupt database, it is possible for the source and destination + ** buffers to overlap. This is harmless since the database is already + ** corrupt but it does cause valgrind and ASAN warnings. So use + ** memmove(). */ + memmove(pDest, ((u8*)pX->pData) + iOffset, iAmt); + } + } + return SQLITE_OK; +} + +/* +** Overwrite the cell that cursor pCur is pointing to with fresh content +** contained in pX. In this variant, pCur is pointing to an overflow +** cell. +*/ +static SQLITE_NOINLINE int btreeOverwriteOverflowCell( + BtCursor *pCur, /* Cursor pointing to cell to overwrite */ + const BtreePayload *pX /* Content to write into the cell */ +){ + int iOffset; /* Next byte of pX->pData to write */ + int nTotal = pX->nData + pX->nZero; /* Total bytes of to write */ + int rc; /* Return code */ + MemPage *pPage = pCur->pPage; /* Page being written */ + BtShared *pBt; /* Btree */ + Pgno ovflPgno; /* Next overflow page to write */ + u32 ovflPageSize; /* Size to write on overflow page */ + + assert( pCur->info.nLocalinfo.pPayload, pX, + 0, pCur->info.nLocal); + if( rc ) return rc; + + /* Now overwrite the overflow pages */ + iOffset = pCur->info.nLocal; + assert( nTotal>=0 ); + assert( iOffset>=0 ); + ovflPgno = get4byte(pCur->info.pPayload + iOffset); + pBt = pPage->pBt; + ovflPageSize = pBt->usableSize - 4; + do{ + rc = btreeGetPage(pBt, ovflPgno, &pPage, 0); + if( rc ) return rc; + if( sqlite3PagerPageRefcount(pPage->pDbPage)!=1 || pPage->isInit ){ + rc = SQLITE_CORRUPT_PAGE(pPage); + }else{ + if( iOffset+ovflPageSize<(u32)nTotal ){ + ovflPgno = get4byte(pPage->aData); + }else{ + ovflPageSize = nTotal - iOffset; + } + rc = btreeOverwriteContent(pPage, pPage->aData+4, pX, + iOffset, ovflPageSize); + } + sqlite3PagerUnref(pPage->pDbPage); + if( rc ) return rc; + iOffset += ovflPageSize; + }while( iOffsetnData + pX->nZero; /* Total bytes of to write */ + MemPage *pPage = pCur->pPage; /* Page being written */ + + if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd + || pCur->info.pPayload < pPage->aData + pPage->cellOffset + ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + if( pCur->info.nLocal==nTotal ){ + /* The entire cell is local */ + return btreeOverwriteContent(pPage, pCur->info.pPayload, pX, + 0, pCur->info.nLocal); + }else{ + /* The cell contains overflow content */ + return btreeOverwriteOverflowCell(pCur, pX); + } +} + + +/* +** Insert a new record into the BTree. The content of the new record +** is described by the pX object. The pCur cursor is used only to +** define what table the record should be inserted into, and is left +** pointing at a random location. +** +** For a table btree (used for rowid tables), only the pX.nKey value of +** the key is used. The pX.pKey value must be NULL. The pX.nKey is the +** rowid or INTEGER PRIMARY KEY of the row. The pX.nData,pData,nZero fields +** hold the content of the row. +** +** For an index btree (used for indexes and WITHOUT ROWID tables), the +** key is an arbitrary byte sequence stored in pX.pKey,nKey. The +** pX.pData,nData,nZero fields must be zero. +** +** If the seekResult parameter is non-zero, then a successful call to +** sqlite3BtreeIndexMoveto() to seek cursor pCur to (pKey,nKey) has already +** been performed. In other words, if seekResult!=0 then the cursor +** is currently pointing to a cell that will be adjacent to the cell +** to be inserted. If seekResult<0 then pCur points to a cell that is +** smaller then (pKey,nKey). If seekResult>0 then pCur points to a cell +** that is larger than (pKey,nKey). +** +** If seekResult==0, that means pCur is pointing at some unknown location. +** In that case, this routine must seek the cursor to the correct insertion +** point for (pKey,nKey) before doing the insertion. For index btrees, +** if pX->nMem is non-zero, then pX->aMem contains pointers to the unpacked +** key values and pX->aMem can be used instead of pX->pKey to avoid having +** to decode the key. +*/ +SQLITE_PRIVATE int sqlite3BtreeInsert( + BtCursor *pCur, /* Insert data into the table of this cursor */ + const BtreePayload *pX, /* Content of the row to be inserted */ + int flags, /* True if this is likely an append */ + int seekResult /* Result of prior IndexMoveto() call */ +){ + int rc; + int loc = seekResult; /* -1: before desired location +1: after */ + int szNew = 0; + int idx; + MemPage *pPage; + Btree *p = pCur->pBtree; + unsigned char *oldCell; + unsigned char *newCell = 0; + + assert( (flags & (BTREE_SAVEPOSITION|BTREE_APPEND|BTREE_PREFORMAT))==flags ); + assert( (flags & BTREE_PREFORMAT)==0 || seekResult || pCur->pKeyInfo==0 ); + + /* Save the positions of any other cursors open on this table. + ** + ** In some cases, the call to btreeMoveto() below is a no-op. For + ** example, when inserting data into a table with auto-generated integer + ** keys, the VDBE layer invokes sqlite3BtreeLast() to figure out the + ** integer key to use. It then calls this function to actually insert the + ** data into the intkey B-Tree. In this case btreeMoveto() recognizes + ** that the cursor is already where it needs to be and returns without + ** doing any work. To avoid thwarting these optimizations, it is important + ** not to clear the cursor here. + */ + if( pCur->curFlags & BTCF_Multiple ){ + rc = saveAllCursors(p->pBt, pCur->pgnoRoot, pCur); + if( rc ) return rc; + if( loc && pCur->iPage<0 ){ + /* This can only happen if the schema is corrupt such that there is more + ** than one table or index with the same root page as used by the cursor. + ** Which can only happen if the SQLITE_NoSchemaError flag was set when + ** the schema was loaded. This cannot be asserted though, as a user might + ** set the flag, load the schema, and then unset the flag. */ + return SQLITE_CORRUPT_PGNO(pCur->pgnoRoot); + } + } + + /* Ensure that the cursor is not in the CURSOR_FAULT state and that it + ** points to a valid cell. + */ + if( pCur->eState>=CURSOR_REQUIRESEEK ){ + testcase( pCur->eState==CURSOR_REQUIRESEEK ); + testcase( pCur->eState==CURSOR_FAULT ); + rc = moveToRoot(pCur); + if( rc && rc!=SQLITE_EMPTY ) return rc; + } + + assert( cursorOwnsBtShared(pCur) ); + assert( (pCur->curFlags & BTCF_WriteFlag)!=0 + && p->pBt->inTransaction==TRANS_WRITE + && (p->pBt->btsFlags & BTS_READ_ONLY)==0 ); + assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); + + /* Assert that the caller has been consistent. If this cursor was opened + ** expecting an index b-tree, then the caller should be inserting blob + ** keys with no associated data. If the cursor was opened expecting an + ** intkey table, the caller should be inserting integer keys with a + ** blob of associated data. */ + assert( (flags & BTREE_PREFORMAT) || (pX->pKey==0)==(pCur->pKeyInfo==0) ); + + if( pCur->pKeyInfo==0 ){ + assert( pX->pKey==0 ); + /* If this is an insert into a table b-tree, invalidate any incrblob + ** cursors open on the row being replaced */ + if( p->hasIncrblobCur ){ + invalidateIncrblobCursors(p, pCur->pgnoRoot, pX->nKey, 0); + } + + /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing + ** to a row with the same key as the new entry being inserted. + */ +#ifdef SQLITE_DEBUG + if( flags & BTREE_SAVEPOSITION ){ + assert( pCur->curFlags & BTCF_ValidNKey ); + assert( pX->nKey==pCur->info.nKey ); + assert( loc==0 ); + } +#endif + + /* On the other hand, BTREE_SAVEPOSITION==0 does not imply + ** that the cursor is not pointing to a row to be overwritten. + ** So do a complete check. + */ + if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey ){ + /* The cursor is pointing to the entry that is to be + ** overwritten */ + assert( pX->nData>=0 && pX->nZero>=0 ); + if( pCur->info.nSize!=0 + && pCur->info.nPayload==(u32)pX->nData+pX->nZero + ){ + /* New entry is the same size as the old. Do an overwrite */ + return btreeOverwriteCell(pCur, pX); + } + assert( loc==0 ); + }else if( loc==0 ){ + /* The cursor is *not* pointing to the cell to be overwritten, nor + ** to an adjacent cell. Move the cursor so that it is pointing either + ** to the cell to be overwritten or an adjacent cell. + */ + rc = sqlite3BtreeTableMoveto(pCur, pX->nKey, + (flags & BTREE_APPEND)!=0, &loc); + if( rc ) return rc; + } + }else{ + /* This is an index or a WITHOUT ROWID table */ + + /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing + ** to a row with the same key as the new entry being inserted. + */ + assert( (flags & BTREE_SAVEPOSITION)==0 || loc==0 ); + + /* If the cursor is not already pointing either to the cell to be + ** overwritten, or if a new cell is being inserted, if the cursor is + ** not pointing to an immediately adjacent cell, then move the cursor + ** so that it does. + */ + if( loc==0 && (flags & BTREE_SAVEPOSITION)==0 ){ + if( pX->nMem ){ + UnpackedRecord r; + r.pKeyInfo = pCur->pKeyInfo; + r.aMem = pX->aMem; + r.nField = pX->nMem; + r.default_rc = 0; + r.eqSeen = 0; + rc = sqlite3BtreeIndexMoveto(pCur, &r, &loc); + }else{ + rc = btreeMoveto(pCur, pX->pKey, pX->nKey, + (flags & BTREE_APPEND)!=0, &loc); + } + if( rc ) return rc; + } + + /* If the cursor is currently pointing to an entry to be overwritten + ** and the new content is the same as as the old, then use the + ** overwrite optimization. + */ + if( loc==0 ){ + getCellInfo(pCur); + if( pCur->info.nKey==pX->nKey ){ + BtreePayload x2; + x2.pData = pX->pKey; + x2.nData = (int)pX->nKey; assert( pX->nKey<=0x7fffffff ); + x2.nZero = 0; + return btreeOverwriteCell(pCur, &x2); + } + } + } + assert( pCur->eState==CURSOR_VALID + || (pCur->eState==CURSOR_INVALID && loc) || CORRUPT_DB ); + + pPage = pCur->pPage; + assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) ); + assert( pPage->leaf || !pPage->intKey ); + if( pPage->nFree<0 ){ + if( NEVER(pCur->eState>CURSOR_INVALID) ){ + /* ^^^^^--- due to the moveToRoot() call above */ + rc = SQLITE_CORRUPT_PAGE(pPage); + }else{ + rc = btreeComputeFreeSpace(pPage); + } + if( rc ) return rc; + } + + TRACE(("INSERT: table=%u nkey=%lld ndata=%u page=%u %s\n", + pCur->pgnoRoot, pX->nKey, pX->nData, pPage->pgno, + loc==0 ? "overwrite" : "new entry")); + assert( pPage->isInit || CORRUPT_DB ); + newCell = p->pBt->pTmpSpace; + assert( newCell!=0 ); + assert( BTREE_PREFORMAT==OPFLAG_PREFORMAT ); + if( flags & BTREE_PREFORMAT ){ + rc = SQLITE_OK; + szNew = p->pBt->nPreformatSize; + if( szNew<4 ){ + szNew = 4; + newCell[3] = 0; + } + if( ISAUTOVACUUM(p->pBt) && szNew>pPage->maxLocal ){ + CellInfo info; + pPage->xParseCell(pPage, newCell, &info); + if( info.nPayload!=info.nLocal ){ + Pgno ovfl = get4byte(&newCell[szNew-4]); + ptrmapPut(p->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, &rc); + if( NEVER(rc) ) goto end_insert; + } + } + }else{ + rc = fillInCell(pPage, newCell, pX, &szNew); + if( rc ) goto end_insert; + } + assert( szNew==pPage->xCellSize(pPage, newCell) ); + assert( szNew <= MX_CELL_SIZE(p->pBt) ); + idx = pCur->ix; + pCur->info.nSize = 0; + if( loc==0 ){ + CellInfo info; + assert( idx>=0 ); + if( idx>=pPage->nCell ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + rc = sqlite3PagerWrite(pPage->pDbPage); + if( rc ){ + goto end_insert; + } + oldCell = findCell(pPage, idx); + if( !pPage->leaf ){ + memcpy(newCell, oldCell, 4); + } + BTREE_CLEAR_CELL(rc, pPage, oldCell, info); + testcase( pCur->curFlags & BTCF_ValidOvfl ); + invalidateOverflowCache(pCur); + if( info.nSize==szNew && info.nLocal==info.nPayload + && (!ISAUTOVACUUM(p->pBt) || szNewminLocal) + ){ + /* Overwrite the old cell with the new if they are the same size. + ** We could also try to do this if the old cell is smaller, then add + ** the leftover space to the free list. But experiments show that + ** doing that is no faster then skipping this optimization and just + ** calling dropCell() and insertCell(). + ** + ** This optimization cannot be used on an autovacuum database if the + ** new entry uses overflow pages, as the insertCell() call below is + ** necessary to add the PTRMAP_OVERFLOW1 pointer-map entry. */ + assert( rc==SQLITE_OK ); /* clearCell never fails when nLocal==nPayload */ + if( oldCell < pPage->aData+pPage->hdrOffset+10 ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + if( oldCell+szNew > pPage->aDataEnd ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + memcpy(oldCell, newCell, szNew); + return SQLITE_OK; + } + dropCell(pPage, idx, info.nSize, &rc); + if( rc ) goto end_insert; + }else if( loc<0 && pPage->nCell>0 ){ + assert( pPage->leaf ); + idx = ++pCur->ix; + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); + }else{ + assert( pPage->leaf ); + } + rc = insertCellFast(pPage, idx, newCell, szNew); + assert( pPage->nOverflow==0 || rc==SQLITE_OK ); + assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 ); + + /* If no error has occurred and pPage has an overflow cell, call balance() + ** to redistribute the cells within the tree. Since balance() may move + ** the cursor, zero the BtCursor.info.nSize and BTCF_ValidNKey + ** variables. + ** + ** Previous versions of SQLite called moveToRoot() to move the cursor + ** back to the root page as balance() used to invalidate the contents + ** of BtCursor.apPage[] and BtCursor.aiIdx[]. Instead of doing that, + ** set the cursor state to "invalid". This makes common insert operations + ** slightly faster. + ** + ** There is a subtle but important optimization here too. When inserting + ** multiple records into an intkey b-tree using a single cursor (as can + ** happen while processing an "INSERT INTO ... SELECT" statement), it + ** is advantageous to leave the cursor pointing to the last entry in + ** the b-tree if possible. If the cursor is left pointing to the last + ** entry in the table, and the next row inserted has an integer key + ** larger than the largest existing key, it is possible to insert the + ** row without seeking the cursor. This can be a big performance boost. + */ + if( pPage->nOverflow ){ + assert( rc==SQLITE_OK ); + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); + rc = balance(pCur); + + /* Must make sure nOverflow is reset to zero even if the balance() + ** fails. Internal data structure corruption will result otherwise. + ** Also, set the cursor state to invalid. This stops saveCursorPosition() + ** from trying to save the current position of the cursor. */ + pCur->pPage->nOverflow = 0; + pCur->eState = CURSOR_INVALID; + if( (flags & BTREE_SAVEPOSITION) && rc==SQLITE_OK ){ + btreeReleaseAllCursorPages(pCur); + if( pCur->pKeyInfo ){ + assert( pCur->pKey==0 ); + pCur->pKey = sqlite3Malloc( pX->nKey ); + if( pCur->pKey==0 ){ + rc = SQLITE_NOMEM; + }else{ + memcpy(pCur->pKey, pX->pKey, pX->nKey); + } + } + pCur->eState = CURSOR_REQUIRESEEK; + pCur->nKey = pX->nKey; + } + } + assert( pCur->iPage<0 || pCur->pPage->nOverflow==0 ); + +end_insert: + return rc; +} + +/* +** This function is used as part of copying the current row from cursor +** pSrc into cursor pDest. If the cursors are open on intkey tables, then +** parameter iKey is used as the rowid value when the record is copied +** into pDest. Otherwise, the record is copied verbatim. +** +** This function does not actually write the new value to cursor pDest. +** Instead, it creates and populates any required overflow pages and +** writes the data for the new cell into the BtShared.pTmpSpace buffer +** for the destination database. The size of the cell, in bytes, is left +** in BtShared.nPreformatSize. The caller completes the insertion by +** calling sqlite3BtreeInsert() with the BTREE_PREFORMAT flag specified. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +*/ +SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 iKey){ + BtShared *pBt = pDest->pBt; + u8 *aOut = pBt->pTmpSpace; /* Pointer to next output buffer */ + const u8 *aIn; /* Pointer to next input buffer */ + u32 nIn; /* Size of input buffer aIn[] */ + u32 nRem; /* Bytes of data still to copy */ + + getCellInfo(pSrc); + if( pSrc->info.nPayload<0x80 ){ + *(aOut++) = (u8)pSrc->info.nPayload; + }else{ + aOut += sqlite3PutVarint(aOut, pSrc->info.nPayload); + } + if( pDest->pKeyInfo==0 ) aOut += putVarint(aOut, iKey); + nIn = pSrc->info.nLocal; + aIn = pSrc->info.pPayload; + if( aIn+nIn>pSrc->pPage->aDataEnd ){ + return SQLITE_CORRUPT_PAGE(pSrc->pPage); + } + nRem = pSrc->info.nPayload; + if( nIn==nRem && nInpPage->maxLocal ){ + memcpy(aOut, aIn, nIn); + pBt->nPreformatSize = nIn + (int)(aOut - pBt->pTmpSpace); + return SQLITE_OK; + }else{ + int rc = SQLITE_OK; + Pager *pSrcPager = pSrc->pBt->pPager; + u8 *pPgnoOut = 0; + Pgno ovflIn = 0; + DbPage *pPageIn = 0; + MemPage *pPageOut = 0; + u32 nOut; /* Size of output buffer aOut[] */ + + nOut = btreePayloadToLocal(pDest->pPage, pSrc->info.nPayload); + pBt->nPreformatSize = (int)nOut + (int)(aOut - pBt->pTmpSpace); + if( nOutinfo.nPayload ){ + pPgnoOut = &aOut[nOut]; + pBt->nPreformatSize += 4; + } + + if( nRem>nIn ){ + if( aIn+nIn+4>pSrc->pPage->aDataEnd ){ + return SQLITE_CORRUPT_PAGE(pSrc->pPage); + } + ovflIn = get4byte(&pSrc->info.pPayload[nIn]); + } + + do { + nRem -= nOut; + do{ + assert( nOut>0 ); + if( nIn>0 ){ + int nCopy = MIN(nOut, nIn); + memcpy(aOut, aIn, nCopy); + nOut -= nCopy; + nIn -= nCopy; + aOut += nCopy; + aIn += nCopy; + } + if( nOut>0 ){ + sqlite3PagerUnref(pPageIn); + pPageIn = 0; + rc = sqlite3PagerGet(pSrcPager, ovflIn, &pPageIn, PAGER_GET_READONLY); + if( rc==SQLITE_OK ){ + aIn = (const u8*)sqlite3PagerGetData(pPageIn); + ovflIn = get4byte(aIn); + aIn += 4; + nIn = pSrc->pBt->usableSize - 4; + } + } + }while( rc==SQLITE_OK && nOut>0 ); + + if( rc==SQLITE_OK && nRem>0 && ALWAYS(pPgnoOut) ){ + Pgno pgnoNew = 0; /* Prevent harmless static-analyzer warning */ + MemPage *pNew = 0; + rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0); + put4byte(pPgnoOut, pgnoNew); + if( ISAUTOVACUUM(pBt) && pPageOut ){ + ptrmapPut(pBt, pgnoNew, PTRMAP_OVERFLOW2, pPageOut->pgno, &rc); + } + releasePage(pPageOut); + pPageOut = pNew; + if( pPageOut ){ + pPgnoOut = pPageOut->aData; + put4byte(pPgnoOut, 0); + aOut = &pPgnoOut[4]; + nOut = MIN(pBt->usableSize - 4, nRem); + } + } + }while( nRem>0 && rc==SQLITE_OK ); + + releasePage(pPageOut); + sqlite3PagerUnref(pPageIn); + return rc; + } +} + +/* +** Delete the entry that the cursor is pointing to. +** +** If the BTREE_SAVEPOSITION bit of the flags parameter is zero, then +** the cursor is left pointing at an arbitrary location after the delete. +** But if that bit is set, then the cursor is left in a state such that +** the next call to BtreeNext() or BtreePrev() moves it to the same row +** as it would have been on if the call to BtreeDelete() had been omitted. +** +** The BTREE_AUXDELETE bit of flags indicates that is one of several deletes +** associated with a single table entry and its indexes. Only one of those +** deletes is considered the "primary" delete. The primary delete occurs +** on a cursor that is not a BTREE_FORDELETE cursor. All but one delete +** operation on non-FORDELETE cursors is tagged with the AUXDELETE flag. +** The BTREE_AUXDELETE bit is a hint that is not used by this implementation, +** but which might be used by alternative storage engines. +*/ +SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ + Btree *p = pCur->pBtree; + BtShared *pBt = p->pBt; + int rc; /* Return code */ + MemPage *pPage; /* Page to delete cell from */ + unsigned char *pCell; /* Pointer to cell to delete */ + int iCellIdx; /* Index of cell to delete */ + int iCellDepth; /* Depth of node containing pCell */ + CellInfo info; /* Size of the cell being deleted */ + u8 bPreserve; /* Keep cursor valid. 2 for CURSOR_SKIPNEXT */ + + assert( cursorOwnsBtShared(pCur) ); + assert( pBt->inTransaction==TRANS_WRITE ); + assert( (pBt->btsFlags & BTS_READ_ONLY)==0 ); + assert( pCur->curFlags & BTCF_WriteFlag ); + assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); + assert( !hasReadConflicts(p, pCur->pgnoRoot) ); + assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 ); + if( pCur->eState!=CURSOR_VALID ){ + if( pCur->eState>=CURSOR_REQUIRESEEK ){ + rc = btreeRestoreCursorPosition(pCur); + assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID ); + if( rc || pCur->eState!=CURSOR_VALID ) return rc; + }else{ + return SQLITE_CORRUPT_PGNO(pCur->pgnoRoot); + } + } + assert( pCur->eState==CURSOR_VALID ); + + iCellDepth = pCur->iPage; + iCellIdx = pCur->ix; + pPage = pCur->pPage; + if( pPage->nCell<=iCellIdx ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + pCell = findCell(pPage, iCellIdx); + if( pPage->nFree<0 && btreeComputeFreeSpace(pPage) ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + if( pCell<&pPage->aCellIdx[pPage->nCell] ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + + /* If the BTREE_SAVEPOSITION bit is on, then the cursor position must + ** be preserved following this delete operation. If the current delete + ** will cause a b-tree rebalance, then this is done by saving the cursor + ** key and leaving the cursor in CURSOR_REQUIRESEEK state before + ** returning. + ** + ** If the current delete will not cause a rebalance, then the cursor + ** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately + ** before or after the deleted entry. + ** + ** The bPreserve value records which path is required: + ** + ** bPreserve==0 Not necessary to save the cursor position + ** bPreserve==1 Use CURSOR_REQUIRESEEK to save the cursor position + ** bPreserve==2 Cursor won't move. Set CURSOR_SKIPNEXT. + */ + bPreserve = (flags & BTREE_SAVEPOSITION)!=0; + if( bPreserve ){ + if( !pPage->leaf + || (pPage->nFree+pPage->xCellSize(pPage,pCell)+2) > + (int)(pBt->usableSize*2/3) + || pPage->nCell==1 /* See dbfuzz001.test for a test case */ + ){ + /* A b-tree rebalance will be required after deleting this entry. + ** Save the cursor key. */ + rc = saveCursorKey(pCur); + if( rc ) return rc; + }else{ + bPreserve = 2; + } + } + + /* If the page containing the entry to delete is not a leaf page, move + ** the cursor to the largest entry in the tree that is smaller than + ** the entry being deleted. This cell will replace the cell being deleted + ** from the internal node. The 'previous' entry is used for this instead + ** of the 'next' entry, as the previous entry is always a part of the + ** sub-tree headed by the child page of the cell being deleted. This makes + ** balancing the tree following the delete operation easier. */ + if( !pPage->leaf ){ + rc = sqlite3BtreePrevious(pCur, 0); + assert( rc!=SQLITE_DONE ); + if( rc ) return rc; + } + + /* Save the positions of any other cursors open on this table before + ** making any modifications. */ + if( pCur->curFlags & BTCF_Multiple ){ + rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur); + if( rc ) return rc; + } + + /* If this is a delete operation to remove a row from a table b-tree, + ** invalidate any incrblob cursors open on the row being deleted. */ + if( pCur->pKeyInfo==0 && p->hasIncrblobCur ){ + invalidateIncrblobCursors(p, pCur->pgnoRoot, pCur->info.nKey, 0); + } + + /* Make the page containing the entry to be deleted writable. Then free any + ** overflow pages associated with the entry and finally remove the cell + ** itself from within the page. */ + rc = sqlite3PagerWrite(pPage->pDbPage); + if( rc ) return rc; + BTREE_CLEAR_CELL(rc, pPage, pCell, info); + dropCell(pPage, iCellIdx, info.nSize, &rc); + if( rc ) return rc; + + /* If the cell deleted was not located on a leaf page, then the cursor + ** is currently pointing to the largest entry in the sub-tree headed + ** by the child-page of the cell that was just deleted from an internal + ** node. The cell from the leaf node needs to be moved to the internal + ** node to replace the deleted cell. */ + if( !pPage->leaf ){ + MemPage *pLeaf = pCur->pPage; + int nCell; + Pgno n; + unsigned char *pTmp; + + if( pLeaf->nFree<0 ){ + rc = btreeComputeFreeSpace(pLeaf); + if( rc ) return rc; + } + if( iCellDepthiPage-1 ){ + n = pCur->apPage[iCellDepth+1]->pgno; + }else{ + n = pCur->pPage->pgno; + } + pCell = findCell(pLeaf, pLeaf->nCell-1); + if( pCell<&pLeaf->aData[4] ) return SQLITE_CORRUPT_PAGE(pLeaf); + nCell = pLeaf->xCellSize(pLeaf, pCell); + assert( MX_CELL_SIZE(pBt) >= nCell ); + pTmp = pBt->pTmpSpace; + assert( pTmp!=0 ); + rc = sqlite3PagerWrite(pLeaf->pDbPage); + if( rc==SQLITE_OK ){ + rc = insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n); + } + dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc); + if( rc ) return rc; + } + + /* Balance the tree. If the entry deleted was located on a leaf page, + ** then the cursor still points to that page. In this case the first + ** call to balance() repairs the tree, and the if(...) condition is + ** never true. + ** + ** Otherwise, if the entry deleted was on an internal node page, then + ** pCur is pointing to the leaf page from which a cell was removed to + ** replace the cell deleted from the internal node. This is slightly + ** tricky as the leaf node may be underfull, and the internal node may + ** be either under or overfull. In this case run the balancing algorithm + ** on the leaf node first. If the balance proceeds far enough up the + ** tree that we can be sure that any problem in the internal node has + ** been corrected, so be it. Otherwise, after balancing the leaf node, + ** walk the cursor up the tree to the internal node and balance it as + ** well. */ + assert( pCur->pPage->nOverflow==0 ); + assert( pCur->pPage->nFree>=0 ); + if( pCur->pPage->nFree*3<=(int)pCur->pBt->usableSize*2 ){ + /* Optimization: If the free space is less than 2/3rds of the page, + ** then balance() will always be a no-op. No need to invoke it. */ + rc = SQLITE_OK; + }else{ + rc = balance(pCur); + } + if( rc==SQLITE_OK && pCur->iPage>iCellDepth ){ + releasePageNotNull(pCur->pPage); + pCur->iPage--; + while( pCur->iPage>iCellDepth ){ + releasePage(pCur->apPage[pCur->iPage--]); + } + pCur->pPage = pCur->apPage[pCur->iPage]; + rc = balance(pCur); + } + + if( rc==SQLITE_OK ){ + if( bPreserve>1 ){ + assert( (pCur->iPage==iCellDepth || CORRUPT_DB) ); + assert( pPage==pCur->pPage || CORRUPT_DB ); + assert( (pPage->nCell>0 || CORRUPT_DB) && iCellIdx<=pPage->nCell ); + pCur->eState = CURSOR_SKIPNEXT; + if( iCellIdx>=pPage->nCell ){ + pCur->skipNext = -1; + pCur->ix = pPage->nCell-1; + }else{ + pCur->skipNext = 1; + } + }else{ + rc = moveToRoot(pCur); + if( bPreserve ){ + btreeReleaseAllCursorPages(pCur); + pCur->eState = CURSOR_REQUIRESEEK; + } + if( rc==SQLITE_EMPTY ) rc = SQLITE_OK; + } + } + return rc; +} + +/* +** Create a new BTree table. Write into *piTable the page +** number for the root page of the new table. +** +** The type of type is determined by the flags parameter. Only the +** following values of flags are currently in use. Other values for +** flags might not work: +** +** BTREE_INTKEY|BTREE_LEAFDATA Used for SQL tables with rowid keys +** BTREE_ZERODATA Used for SQL indices +*/ +static int btreeCreateTable(Btree *p, Pgno *piTable, int createTabFlags){ + BtShared *pBt = p->pBt; + MemPage *pRoot; + Pgno pgnoRoot; + int rc; + int ptfFlags; /* Page-type flags for the root page of new table */ + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( pBt->inTransaction==TRANS_WRITE ); + assert( (pBt->btsFlags & BTS_READ_ONLY)==0 ); + +#ifdef SQLITE_OMIT_AUTOVACUUM + rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0); + if( rc ){ + return rc; + } +#else + if( pBt->autoVacuum ){ + Pgno pgnoMove; /* Move a page here to make room for the root-page */ + MemPage *pPageMove; /* The page to move to. */ + + /* Creating a new table may probably require moving an existing database + ** to make room for the new tables root page. In case this page turns + ** out to be an overflow page, delete all overflow page-map caches + ** held by open cursors. + */ + invalidateAllOverflowCache(pBt); + + /* Read the value of meta[3] from the database to determine where the + ** root page of the new table should go. meta[3] is the largest root-page + ** created so far, so the new root-page is (meta[3]+1). + */ + sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &pgnoRoot); + if( pgnoRoot>btreePagecount(pBt) ){ + return SQLITE_CORRUPT_PGNO(pgnoRoot); + } + pgnoRoot++; + + /* The new root-page may not be allocated on a pointer-map page, or the + ** PENDING_BYTE page. + */ + while( pgnoRoot==PTRMAP_PAGENO(pBt, pgnoRoot) || + pgnoRoot==PENDING_BYTE_PAGE(pBt) ){ + pgnoRoot++; + } + assert( pgnoRoot>=3 ); + + /* Allocate a page. The page that currently resides at pgnoRoot will + ** be moved to the allocated page (unless the allocated page happens + ** to reside at pgnoRoot). + */ + rc = allocateBtreePage(pBt, &pPageMove, &pgnoMove, pgnoRoot, BTALLOC_EXACT); + if( rc!=SQLITE_OK ){ + return rc; + } + + if( pgnoMove!=pgnoRoot ){ + /* pgnoRoot is the page that will be used for the root-page of + ** the new table (assuming an error did not occur). But we were + ** allocated pgnoMove. If required (i.e. if it was not allocated + ** by extending the file), the current page at position pgnoMove + ** is already journaled. + */ + u8 eType = 0; + Pgno iPtrPage = 0; + + /* Save the positions of any open cursors. This is required in + ** case they are holding a reference to an xFetch reference + ** corresponding to page pgnoRoot. */ + rc = saveAllCursors(pBt, 0, 0); + releasePage(pPageMove); + if( rc!=SQLITE_OK ){ + return rc; + } + + /* Move the page currently at pgnoRoot to pgnoMove. */ + rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage); + if( eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){ + rc = SQLITE_CORRUPT_PGNO(pgnoRoot); + } + if( rc!=SQLITE_OK ){ + releasePage(pRoot); + return rc; + } + assert( eType!=PTRMAP_ROOTPAGE ); + assert( eType!=PTRMAP_FREEPAGE ); + rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove, 0); + releasePage(pRoot); + + /* Obtain the page at pgnoRoot */ + if( rc!=SQLITE_OK ){ + return rc; + } + rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = sqlite3PagerWrite(pRoot->pDbPage); + if( rc!=SQLITE_OK ){ + releasePage(pRoot); + return rc; + } + }else{ + pRoot = pPageMove; + } + + /* Update the pointer-map and meta-data with the new root-page number. */ + ptrmapPut(pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0, &rc); + if( rc ){ + releasePage(pRoot); + return rc; + } + + /* When the new root page was allocated, page 1 was made writable in + ** order either to increase the database filesize, or to decrement the + ** freelist count. Hence, the sqlite3BtreeUpdateMeta() call cannot fail. + */ + assert( sqlite3PagerIswriteable(pBt->pPage1->pDbPage) ); + rc = sqlite3BtreeUpdateMeta(p, 4, pgnoRoot); + if( NEVER(rc) ){ + releasePage(pRoot); + return rc; + } + + }else{ + rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0); + if( rc ) return rc; + } +#endif + assert( sqlite3PagerIswriteable(pRoot->pDbPage) ); + if( createTabFlags & BTREE_INTKEY ){ + ptfFlags = PTF_INTKEY | PTF_LEAFDATA | PTF_LEAF; + }else{ + ptfFlags = PTF_ZERODATA | PTF_LEAF; + } + zeroPage(pRoot, ptfFlags); + sqlite3PagerUnref(pRoot->pDbPage); + assert( (pBt->openFlags & BTREE_SINGLE)==0 || pgnoRoot==2 ); + *piTable = pgnoRoot; + return SQLITE_OK; +} +SQLITE_PRIVATE int sqlite3BtreeCreateTable(Btree *p, Pgno *piTable, int flags){ + int rc; + sqlite3BtreeEnter(p); + rc = btreeCreateTable(p, piTable, flags); + sqlite3BtreeLeave(p); + return rc; +} + +/* +** Erase the given database page and all its children. Return +** the page to the freelist. +*/ +static int clearDatabasePage( + BtShared *pBt, /* The BTree that contains the table */ + Pgno pgno, /* Page number to clear */ + int freePageFlag, /* Deallocate page if true */ + i64 *pnChange /* Add number of Cells freed to this counter */ +){ + MemPage *pPage; + int rc; + unsigned char *pCell; + int i; + int hdr; + CellInfo info; + + assert( sqlite3_mutex_held(pBt->mutex) ); + if( pgno>btreePagecount(pBt) ){ + return SQLITE_CORRUPT_PGNO(pgno); + } + rc = getAndInitPage(pBt, pgno, &pPage, 0); + if( rc ) return rc; + if( (pBt->openFlags & BTREE_SINGLE)==0 + && sqlite3PagerPageRefcount(pPage->pDbPage) != (1 + (pgno==1)) + ){ + rc = SQLITE_CORRUPT_PAGE(pPage); + goto cleardatabasepage_out; + } + hdr = pPage->hdrOffset; + for(i=0; inCell; i++){ + pCell = findCell(pPage, i); + if( !pPage->leaf ){ + rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange); + if( rc ) goto cleardatabasepage_out; + } + BTREE_CLEAR_CELL(rc, pPage, pCell, info); + if( rc ) goto cleardatabasepage_out; + } + if( !pPage->leaf ){ + rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), 1, pnChange); + if( rc ) goto cleardatabasepage_out; + if( pPage->intKey ) pnChange = 0; + } + if( pnChange ){ + testcase( !pPage->intKey ); + *pnChange += pPage->nCell; + } + if( freePageFlag ){ + freePage(pPage, &rc); + }else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){ + zeroPage(pPage, pPage->aData[hdr] | PTF_LEAF); + } + +cleardatabasepage_out: + releasePage(pPage); + return rc; +} + +/* +** Delete all information from a single table in the database. iTable is +** the page number of the root of the table. After this routine returns, +** the root page is empty, but still exists. +** +** This routine will fail with SQLITE_LOCKED if there are any open +** read cursors on the table. Open write cursors are moved to the +** root of the table. +** +** If pnChange is not NULL, then the integer value pointed to by pnChange +** is incremented by the number of entries in the table. +*/ +SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree *p, int iTable, i64 *pnChange){ + int rc; + BtShared *pBt = p->pBt; + sqlite3BtreeEnter(p); + assert( p->inTrans==TRANS_WRITE ); + + rc = saveAllCursors(pBt, (Pgno)iTable, 0); + + if( SQLITE_OK==rc ){ + /* Invalidate all incrblob cursors open on table iTable (assuming iTable + ** is the root of a table b-tree - if it is not, the following call is + ** a no-op). */ + if( p->hasIncrblobCur ){ + invalidateIncrblobCursors(p, (Pgno)iTable, 0, 1); + } + rc = clearDatabasePage(pBt, (Pgno)iTable, 0, pnChange); + } + sqlite3BtreeLeave(p); + return rc; +} + +/* +** Delete all information from the single table that pCur is open on. +** +** This routine only work for pCur on an ephemeral table. +*/ +SQLITE_PRIVATE int sqlite3BtreeClearTableOfCursor(BtCursor *pCur){ + return sqlite3BtreeClearTable(pCur->pBtree, pCur->pgnoRoot, 0); +} + +/* +** Erase all information in a table and add the root of the table to +** the freelist. Except, the root of the principle table (the one on +** page 1) is never added to the freelist. +** +** This routine will fail with SQLITE_LOCKED if there are any open +** cursors on the table. +** +** If AUTOVACUUM is enabled and the page at iTable is not the last +** root page in the database file, then the last root page +** in the database file is moved into the slot formerly occupied by +** iTable and that last slot formerly occupied by the last root page +** is added to the freelist instead of iTable. In this say, all +** root pages are kept at the beginning of the database file, which +** is necessary for AUTOVACUUM to work right. *piMoved is set to the +** page number that used to be the last root page in the file before +** the move. If no page gets moved, *piMoved is set to 0. +** The last root page is recorded in meta[3] and the value of +** meta[3] is updated by this procedure. +*/ +static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ + int rc; + MemPage *pPage = 0; + BtShared *pBt = p->pBt; + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( p->inTrans==TRANS_WRITE ); + assert( iTable>=2 ); + if( iTable>btreePagecount(pBt) ){ + return SQLITE_CORRUPT_PGNO(iTable); + } + + rc = sqlite3BtreeClearTable(p, iTable, 0); + if( rc ) return rc; + rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0); + if( NEVER(rc) ){ + releasePage(pPage); + return rc; + } + + *piMoved = 0; + +#ifdef SQLITE_OMIT_AUTOVACUUM + freePage(pPage, &rc); + releasePage(pPage); +#else + if( pBt->autoVacuum ){ + Pgno maxRootPgno; + sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &maxRootPgno); + + if( iTable==maxRootPgno ){ + /* If the table being dropped is the table with the largest root-page + ** number in the database, put the root page on the free list. + */ + freePage(pPage, &rc); + releasePage(pPage); + if( rc!=SQLITE_OK ){ + return rc; + } + }else{ + /* The table being dropped does not have the largest root-page + ** number in the database. So move the page that does into the + ** gap left by the deleted root-page. + */ + MemPage *pMove; + releasePage(pPage); + rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable, 0); + releasePage(pMove); + if( rc!=SQLITE_OK ){ + return rc; + } + pMove = 0; + rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0); + freePage(pMove, &rc); + releasePage(pMove); + if( rc!=SQLITE_OK ){ + return rc; + } + *piMoved = maxRootPgno; + } + + /* Set the new 'max-root-page' value in the database header. This + ** is the old value less one, less one more if that happens to + ** be a root-page number, less one again if that is the + ** PENDING_BYTE_PAGE. + */ + maxRootPgno--; + while( maxRootPgno==PENDING_BYTE_PAGE(pBt) + || PTRMAP_ISPAGE(pBt, maxRootPgno) ){ + maxRootPgno--; + } + assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) ); + + rc = sqlite3BtreeUpdateMeta(p, 4, maxRootPgno); + }else{ + freePage(pPage, &rc); + releasePage(pPage); + } +#endif + return rc; +} +SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){ + int rc; + sqlite3BtreeEnter(p); + rc = btreeDropTable(p, iTable, piMoved); + sqlite3BtreeLeave(p); + return rc; +} + + +/* +** This function may only be called if the b-tree connection already +** has a read or write transaction open on the database. +** +** Read the meta-information out of a database file. Meta[0] +** is the number of free pages currently in the database. Meta[1] +** through meta[15] are available for use by higher layers. Meta[0] +** is read-only, the others are read/write. +** +** The schema layer numbers meta values differently. At the schema +** layer (and the SetCookie and ReadCookie opcodes) the number of +** free pages is not visible. So Cookie[0] is the same as Meta[1]. +** +** This routine treats Meta[BTREE_DATA_VERSION] as a special case. Instead +** of reading the value out of the header, it instead loads the "DataVersion" +** from the pager. The BTREE_DATA_VERSION value is not actually stored in the +** database file. It is a number computed by the pager. But its access +** pattern is the same as header meta values, and so it is convenient to +** read it from this routine. +*/ +SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){ + BtShared *pBt = p->pBt; + + sqlite3BtreeEnter(p); + assert( p->inTrans>TRANS_NONE ); + assert( SQLITE_OK==querySharedCacheTableLock(p, SCHEMA_ROOT, READ_LOCK) ); + assert( pBt->pPage1 ); + assert( idx>=0 && idx<=15 ); + + if( idx==BTREE_DATA_VERSION ){ + *pMeta = sqlite3PagerDataVersion(pBt->pPager) + p->iBDataVersion; + }else{ + *pMeta = get4byte(&pBt->pPage1->aData[36 + idx*4]); + } + + /* If auto-vacuum is disabled in this build and this is an auto-vacuum + ** database, mark the database as read-only. */ +#ifdef SQLITE_OMIT_AUTOVACUUM + if( idx==BTREE_LARGEST_ROOT_PAGE && *pMeta>0 ){ + pBt->btsFlags |= BTS_READ_ONLY; + } +#endif + + sqlite3BtreeLeave(p); +} + +/* +** Write meta-information back into the database. Meta[0] is +** read-only and may not be written. +*/ +SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){ + BtShared *pBt = p->pBt; + unsigned char *pP1; + int rc; + assert( idx>=1 && idx<=15 ); + sqlite3BtreeEnter(p); + assert( p->inTrans==TRANS_WRITE ); + assert( pBt->pPage1!=0 ); + pP1 = pBt->pPage1->aData; + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + if( rc==SQLITE_OK ){ + put4byte(&pP1[36 + idx*4], iMeta); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( idx==BTREE_INCR_VACUUM ){ + assert( pBt->autoVacuum || iMeta==0 ); + assert( iMeta==0 || iMeta==1 ); + pBt->incrVacuum = (u8)iMeta; + } +#endif + } + sqlite3BtreeLeave(p); + return rc; +} + +/* +** The first argument, pCur, is a cursor opened on some b-tree. Count the +** number of entries in the b-tree and write the result to *pnEntry. +** +** SQLITE_OK is returned if the operation is successfully executed. +** Otherwise, if an error is encountered (i.e. an IO error or database +** corruption) an SQLite error code is returned. +*/ +SQLITE_PRIVATE int sqlite3BtreeCount(sqlite3 *db, BtCursor *pCur, i64 *pnEntry){ + i64 nEntry = 0; /* Value to return in *pnEntry */ + int rc; /* Return code */ + + rc = moveToRoot(pCur); + if( rc==SQLITE_EMPTY ){ + *pnEntry = 0; + return SQLITE_OK; + } + + /* Unless an error occurs, the following loop runs one iteration for each + ** page in the B-Tree structure (not including overflow pages). + */ + while( rc==SQLITE_OK && !AtomicLoad(&db->u1.isInterrupted) ){ + int iIdx; /* Index of child node in parent */ + MemPage *pPage; /* Current page of the b-tree */ + + /* If this is a leaf page or the tree is not an int-key tree, then + ** this page contains countable entries. Increment the entry counter + ** accordingly. + */ + pPage = pCur->pPage; + if( pPage->leaf || !pPage->intKey ){ + nEntry += pPage->nCell; + } + + /* pPage is a leaf node. This loop navigates the cursor so that it + ** points to the first interior cell that it points to the parent of + ** the next page in the tree that has not yet been visited. The + ** pCur->aiIdx[pCur->iPage] value is set to the index of the parent cell + ** of the page, or to the number of cells in the page if the next page + ** to visit is the right-child of its parent. + ** + ** If all pages in the tree have been visited, return SQLITE_OK to the + ** caller. + */ + if( pPage->leaf ){ + do { + if( pCur->iPage==0 ){ + /* All pages of the b-tree have been visited. Return successfully. */ + *pnEntry = nEntry; + return moveToRoot(pCur); + } + moveToParent(pCur); + }while ( pCur->ix>=pCur->pPage->nCell ); + + pCur->ix++; + pPage = pCur->pPage; + } + + /* Descend to the child node of the cell that the cursor currently + ** points at. This is the right-child if (iIdx==pPage->nCell). + */ + iIdx = pCur->ix; + if( iIdx==pPage->nCell ){ + rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8])); + }else{ + rc = moveToChild(pCur, get4byte(findCell(pPage, iIdx))); + } + } + + /* An error has occurred. Return an error code. */ + return rc; +} + +/* +** Return the pager associated with a BTree. This routine is used for +** testing and debugging only. +*/ +SQLITE_PRIVATE Pager *sqlite3BtreePager(Btree *p){ + return p->pBt->pPager; +} + +#ifndef SQLITE_OMIT_INTEGRITY_CHECK +/* +** Record an OOM error during integrity_check +*/ +static void checkOom(IntegrityCk *pCheck){ + pCheck->rc = SQLITE_NOMEM; + pCheck->mxErr = 0; /* Causes integrity_check processing to stop */ + if( pCheck->nErr==0 ) pCheck->nErr++; +} + +/* +** Invoke the progress handler, if appropriate. Also check for an +** interrupt. +*/ +static void checkProgress(IntegrityCk *pCheck){ + sqlite3 *db = pCheck->db; + if( AtomicLoad(&db->u1.isInterrupted) ){ + pCheck->rc = SQLITE_INTERRUPT; + pCheck->nErr++; + pCheck->mxErr = 0; + } +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + if( db->xProgress ){ + assert( db->nProgressOps>0 ); + pCheck->nStep++; + if( (pCheck->nStep % db->nProgressOps)==0 + && db->xProgress(db->pProgressArg) + ){ + pCheck->rc = SQLITE_INTERRUPT; + pCheck->nErr++; + pCheck->mxErr = 0; + } + } +#endif +} + +/* +** Append a message to the error message string. +*/ +static void checkAppendMsg( + IntegrityCk *pCheck, + const char *zFormat, + ... +){ + va_list ap; + checkProgress(pCheck); + if( !pCheck->mxErr ) return; + pCheck->mxErr--; + pCheck->nErr++; + va_start(ap, zFormat); + if( pCheck->errMsg.nChar ){ + sqlite3_str_append(&pCheck->errMsg, "\n", 1); + } + if( pCheck->zPfx ){ + sqlite3_str_appendf(&pCheck->errMsg, pCheck->zPfx, + pCheck->v0, pCheck->v1, pCheck->v2); + } + sqlite3_str_vappendf(&pCheck->errMsg, zFormat, ap); + va_end(ap); + if( pCheck->errMsg.accError==SQLITE_NOMEM ){ + checkOom(pCheck); + } +} +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ + +#ifndef SQLITE_OMIT_INTEGRITY_CHECK + +/* +** Return non-zero if the bit in the IntegrityCk.aPgRef[] array that +** corresponds to page iPg is already set. +*/ +static int getPageReferenced(IntegrityCk *pCheck, Pgno iPg){ + assert( pCheck->aPgRef!=0 ); + assert( iPg<=pCheck->nCkPage && sizeof(pCheck->aPgRef[0])==1 ); + return (pCheck->aPgRef[iPg/8] & (1 << (iPg & 0x07))); +} + +/* +** Set the bit in the IntegrityCk.aPgRef[] array that corresponds to page iPg. +*/ +static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){ + assert( pCheck->aPgRef!=0 ); + assert( iPg<=pCheck->nCkPage && sizeof(pCheck->aPgRef[0])==1 ); + pCheck->aPgRef[iPg/8] |= (1 << (iPg & 0x07)); +} + + +/* +** Add 1 to the reference count for page iPage. If this is the second +** reference to the page, add an error message to pCheck->zErrMsg. +** Return 1 if there are 2 or more references to the page and 0 if +** if this is the first reference to the page. +** +** Also check that the page number is in bounds. +*/ +static int checkRef(IntegrityCk *pCheck, Pgno iPage){ + if( iPage>pCheck->nCkPage || iPage==0 ){ + checkAppendMsg(pCheck, "invalid page number %u", iPage); + return 1; + } + if( getPageReferenced(pCheck, iPage) ){ + checkAppendMsg(pCheck, "2nd reference to page %u", iPage); + return 1; + } + setPageReferenced(pCheck, iPage); + return 0; +} + +#ifndef SQLITE_OMIT_AUTOVACUUM +/* +** Check that the entry in the pointer-map for page iChild maps to +** page iParent, pointer type ptrType. If not, append an error message +** to pCheck. +*/ +static void checkPtrmap( + IntegrityCk *pCheck, /* Integrity check context */ + Pgno iChild, /* Child page number */ + u8 eType, /* Expected pointer map type */ + Pgno iParent /* Expected pointer map parent page number */ +){ + int rc; + u8 ePtrmapType; + Pgno iPtrmapParent; + + rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) checkOom(pCheck); + checkAppendMsg(pCheck, "Failed to read ptrmap key=%u", iChild); + return; + } + + if( ePtrmapType!=eType || iPtrmapParent!=iParent ){ + checkAppendMsg(pCheck, + "Bad ptr map entry key=%u expected=(%u,%u) got=(%u,%u)", + iChild, eType, iParent, ePtrmapType, iPtrmapParent); + } +} +#endif + +/* +** Check the integrity of the freelist or of an overflow page list. +** Verify that the number of pages on the list is N. +*/ +static void checkList( + IntegrityCk *pCheck, /* Integrity checking context */ + int isFreeList, /* True for a freelist. False for overflow page list */ + Pgno iPage, /* Page number for first page in the list */ + u32 N /* Expected number of pages in the list */ +){ + int i; + u32 expected = N; + int nErrAtStart = pCheck->nErr; + while( iPage!=0 && pCheck->mxErr ){ + DbPage *pOvflPage; + unsigned char *pOvflData; + if( checkRef(pCheck, iPage) ) break; + N--; + if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage, 0) ){ + checkAppendMsg(pCheck, "failed to get page %u", iPage); + break; + } + pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage); + if( isFreeList ){ + u32 n = (u32)get4byte(&pOvflData[4]); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pCheck->pBt->autoVacuum ){ + checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0); + } +#endif + if( n>pCheck->pBt->usableSize/4-2 ){ + checkAppendMsg(pCheck, + "freelist leaf count too big on page %u", iPage); + N--; + }else{ + for(i=0; i<(int)n; i++){ + Pgno iFreePage = get4byte(&pOvflData[8+i*4]); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pCheck->pBt->autoVacuum ){ + checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0); + } +#endif + checkRef(pCheck, iFreePage); + } + N -= n; + } + } +#ifndef SQLITE_OMIT_AUTOVACUUM + else{ + /* If this database supports auto-vacuum and iPage is not the last + ** page in this overflow list, check that the pointer-map entry for + ** the following page matches iPage. + */ + if( pCheck->pBt->autoVacuum && N>0 ){ + i = get4byte(pOvflData); + checkPtrmap(pCheck, i, PTRMAP_OVERFLOW2, iPage); + } + } +#endif + iPage = get4byte(pOvflData); + sqlite3PagerUnref(pOvflPage); + } + if( N && nErrAtStart==pCheck->nErr ){ + checkAppendMsg(pCheck, + "%s is %u but should be %u", + isFreeList ? "size" : "overflow list length", + expected-N, expected); + } +} +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ + +/* +** An implementation of a min-heap. +** +** aHeap[0] is the number of elements on the heap. aHeap[1] is the +** root element. The daughter nodes of aHeap[N] are aHeap[N*2] +** and aHeap[N*2+1]. +** +** The heap property is this: Every node is less than or equal to both +** of its daughter nodes. A consequence of the heap property is that the +** root node aHeap[1] is always the minimum value currently in the heap. +** +** The btreeHeapInsert() routine inserts an unsigned 32-bit number onto +** the heap, preserving the heap property. The btreeHeapPull() routine +** removes the root element from the heap (the minimum value in the heap) +** and then moves other nodes around as necessary to preserve the heap +** property. +** +** This heap is used for cell overlap and coverage testing. Each u32 +** entry represents the span of a cell or freeblock on a btree page. +** The upper 16 bits are the index of the first byte of a range and the +** lower 16 bits are the index of the last byte of that range. +*/ +static void btreeHeapInsert(u32 *aHeap, u32 x){ + u32 j, i; + assert( aHeap!=0 ); + i = ++aHeap[0]; + aHeap[i] = x; + while( (j = i/2)>0 && aHeap[j]>aHeap[i] ){ + x = aHeap[j]; + aHeap[j] = aHeap[i]; + aHeap[i] = x; + i = j; + } +} +static int btreeHeapPull(u32 *aHeap, u32 *pOut){ + u32 j, i, x; + if( (x = aHeap[0])==0 ) return 0; + *pOut = aHeap[1]; + aHeap[1] = aHeap[x]; + aHeap[x] = 0xffffffff; + aHeap[0]--; + i = 1; + while( (j = i*2)<=aHeap[0] ){ + if( aHeap[j]>aHeap[j+1] ) j++; + if( aHeap[i]zPfx; + int saved_v1 = pCheck->v1; + int saved_v2 = pCheck->v2; + u8 savedIsInit = 0; + + /* Check that the page exists + */ + checkProgress(pCheck); + if( pCheck->mxErr==0 ) goto end_of_check; + pBt = pCheck->pBt; + usableSize = pBt->usableSize; + if( iPage==0 ) return 0; + if( checkRef(pCheck, iPage) ) return 0; + pCheck->zPfx = "Tree %u page %u: "; + pCheck->v1 = iPage; + if( (rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0 ){ + checkAppendMsg(pCheck, + "unable to get the page. error code=%d", rc); + if( rc==SQLITE_IOERR_NOMEM ) pCheck->rc = SQLITE_NOMEM; + goto end_of_check; + } + + /* Clear MemPage.isInit to make sure the corruption detection code in + ** btreeInitPage() is executed. */ + savedIsInit = pPage->isInit; + pPage->isInit = 0; + if( (rc = btreeInitPage(pPage))!=0 ){ + assert( rc==SQLITE_CORRUPT ); /* The only possible error from InitPage */ + checkAppendMsg(pCheck, + "btreeInitPage() returns error code %d", rc); + goto end_of_check; + } + if( (rc = btreeComputeFreeSpace(pPage))!=0 ){ + assert( rc==SQLITE_CORRUPT ); + checkAppendMsg(pCheck, "free space corruption", rc); + goto end_of_check; + } + data = pPage->aData; + hdr = pPage->hdrOffset; + + /* Set up for cell analysis */ + pCheck->zPfx = "Tree %u page %u cell %u: "; + contentOffset = get2byteNotZero(&data[hdr+5]); + assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */ + + /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the + ** number of cells on the page. */ + nCell = get2byte(&data[hdr+3]); + assert( pPage->nCell==nCell ); + if( pPage->leaf || pPage->intKey==0 ){ + pCheck->nRow += nCell; + } + + /* EVIDENCE-OF: R-23882-45353 The cell pointer array of a b-tree page + ** immediately follows the b-tree page header. */ + cellStart = hdr + 12 - 4*pPage->leaf; + assert( pPage->aCellIdx==&data[cellStart] ); + pCellIdx = &data[cellStart + 2*(nCell-1)]; + + if( !pPage->leaf ){ + /* Analyze the right-child page of internal pages */ + pgno = get4byte(&data[hdr+8]); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + pCheck->zPfx = "Tree %u page %u right child: "; + checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage); + } +#endif + depth = checkTreePage(pCheck, pgno, &maxKey, maxKey); + keyCanBeEqual = 0; + }else{ + /* For leaf pages, the coverage check will occur in the same loop + ** as the other cell checks, so initialize the heap. */ + heap = pCheck->heap; + heap[0] = 0; + } + + /* EVIDENCE-OF: R-02776-14802 The cell pointer array consists of K 2-byte + ** integer offsets to the cell contents. */ + for(i=nCell-1; i>=0 && pCheck->mxErr; i--){ + CellInfo info; + + /* Check cell size */ + pCheck->v2 = i; + assert( pCellIdx==&data[cellStart + i*2] ); + pc = get2byteAligned(pCellIdx); + pCellIdx -= 2; + if( pcusableSize-4 ){ + checkAppendMsg(pCheck, "Offset %u out of range %u..%u", + pc, contentOffset, usableSize-4); + doCoverageCheck = 0; + continue; + } + pCell = &data[pc]; + pPage->xParseCell(pPage, pCell, &info); + if( pc+info.nSize>usableSize ){ + checkAppendMsg(pCheck, "Extends off end of page"); + doCoverageCheck = 0; + continue; + } + + /* Check for integer primary key out of range */ + if( pPage->intKey ){ + if( keyCanBeEqual ? (info.nKey > maxKey) : (info.nKey >= maxKey) ){ + checkAppendMsg(pCheck, "Rowid %lld out of order", info.nKey); + } + maxKey = info.nKey; + keyCanBeEqual = 0; /* Only the first key on the page may ==maxKey */ + } + + /* Check the content overflow list */ + if( info.nPayload>info.nLocal ){ + u32 nPage; /* Number of pages on the overflow chain */ + Pgno pgnoOvfl; /* First page of the overflow chain */ + assert( pc + info.nSize - 4 <= usableSize ); + nPage = (info.nPayload - info.nLocal + usableSize - 5)/(usableSize - 4); + pgnoOvfl = get4byte(&pCell[info.nSize - 4]); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage); + } +#endif + checkList(pCheck, 0, pgnoOvfl, nPage); + } + + if( !pPage->leaf ){ + /* Check sanity of left child page for internal pages */ + pgno = get4byte(pCell); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage); + } +#endif + d2 = checkTreePage(pCheck, pgno, &maxKey, maxKey); + keyCanBeEqual = 0; + if( d2!=depth ){ + checkAppendMsg(pCheck, "Child page depth differs"); + depth = d2; + } + }else{ + /* Populate the coverage-checking heap for leaf pages */ + assert( heap[0] < pCheck->mxHeap ); + btreeHeapInsert(heap, (pc<<16)|(pc+info.nSize-1)); + } + } + *piMinKey = maxKey; + + /* Check for complete coverage of the page + */ + pCheck->zPfx = 0; + if( doCoverageCheck && pCheck->mxErr>0 ){ + /* For leaf pages, the min-heap has already been initialized and the + ** cells have already been inserted. But for internal pages, that has + ** not yet been done, so do it now */ + if( !pPage->leaf ){ + heap = pCheck->heap; + heap[0] = 0; + for(i=nCell-1; i>=0; i--){ + u32 size; + pc = get2byteAligned(&data[cellStart+i*2]); + size = pPage->xCellSize(pPage, &data[pc]); + assert( heap[0] < pCheck->mxHeap ); + btreeHeapInsert(heap, (pc<<16)|(pc+size-1)); + } + } + assert( heap!=0 ); + /* Add the freeblocks to the min-heap + ** + ** EVIDENCE-OF: R-20690-50594 The second field of the b-tree page header + ** is the offset of the first freeblock, or zero if there are no + ** freeblocks on the page. + */ + i = get2byte(&data[hdr+1]); + while( i>0 ){ + int size, j; + assert( (u32)i<=usableSize-4 ); /* Enforced by btreeComputeFreeSpace() */ + size = get2byte(&data[i+2]); + assert( (u32)(i+size)<=usableSize ); /* due to btreeComputeFreeSpace() */ + assert( heap[0] < pCheck->mxHeap ); + btreeHeapInsert(heap, (((u32)i)<<16)|(i+size-1)); + /* EVIDENCE-OF: R-58208-19414 The first 2 bytes of a freeblock are a + ** big-endian integer which is the offset in the b-tree page of the next + ** freeblock in the chain, or zero if the freeblock is the last on the + ** chain. */ + j = get2byte(&data[i]); + /* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of + ** increasing offset. */ + assert( j==0 || j>i+size ); /* Enforced by btreeComputeFreeSpace() */ + assert( (u32)j<=usableSize-4 ); /* Enforced by btreeComputeFreeSpace() */ + i = j; + } + /* Analyze the min-heap looking for overlap between cells and/or + ** freeblocks, and counting the number of untracked bytes in nFrag. + ** + ** Each min-heap entry is of the form: (start_address<<16)|end_address. + ** There is an implied first entry the covers the page header, the cell + ** pointer index, and the gap between the cell pointer index and the start + ** of cell content. + ** + ** The loop below pulls entries from the min-heap in order and compares + ** the start_address against the previous end_address. If there is an + ** overlap, that means bytes are used multiple times. If there is a gap, + ** that gap is added to the fragmentation count. + */ + nFrag = 0; + prev = contentOffset - 1; /* Implied first min-heap entry */ + while( btreeHeapPull(heap,&x) ){ + if( (prev&0xffff)>=(x>>16) ){ + checkAppendMsg(pCheck, + "Multiple uses for byte %u of page %u", x>>16, iPage); + break; + }else{ + nFrag += (x>>16) - (prev&0xffff) - 1; + prev = x; + } + } + nFrag += usableSize - (prev&0xffff) - 1; + /* EVIDENCE-OF: R-43263-13491 The total number of bytes in all fragments + ** is stored in the fifth field of the b-tree page header. + ** EVIDENCE-OF: R-07161-27322 The one-byte integer at offset 7 gives the + ** number of fragmented free bytes within the cell content area. + */ + if( heap[0]==0 && nFrag!=data[hdr+7] ){ + checkAppendMsg(pCheck, + "Fragmentation of %u bytes reported as %u on page %u", + nFrag, data[hdr+7], iPage); + } + } + +end_of_check: + if( !doCoverageCheck ) pPage->isInit = savedIsInit; + releasePage(pPage); + pCheck->zPfx = saved_zPfx; + pCheck->v1 = saved_v1; + pCheck->v2 = saved_v2; + return depth+1; +} +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ + +#ifndef SQLITE_OMIT_INTEGRITY_CHECK +/* +** This routine does a complete check of the given BTree file. aRoot[] is +** an array of pages numbers were each page number is the root page of +** a table. nRoot is the number of entries in aRoot. +** +** A read-only or read-write transaction must be opened before calling +** this function. +** +** Write the number of error seen in *pnErr. Except for some memory +** allocation errors, an error message held in memory obtained from +** malloc is returned if *pnErr is non-zero. If *pnErr==0 then NULL is +** returned. If a memory allocation error occurs, NULL is returned. +** +** If the first entry in aRoot[] is 0, that indicates that the list of +** root pages is incomplete. This is a "partial integrity-check". This +** happens when performing an integrity check on a single table. The +** zero is skipped, of course. But in addition, the freelist checks +** and the checks to make sure every page is referenced are also skipped, +** since obviously it is not possible to know which pages are covered by +** the unverified btrees. Except, if aRoot[1] is 1, then the freelist +** checks are still performed. +*/ +SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck( + sqlite3 *db, /* Database connection that is running the check */ + Btree *p, /* The btree to be checked */ + Pgno *aRoot, /* An array of root pages numbers for individual trees */ + Mem *aCnt, /* Memory cells to write counts for each tree to */ + int nRoot, /* Number of entries in aRoot[] */ + int mxErr, /* Stop reporting errors after this many */ + int *pnErr, /* OUT: Write number of errors seen to this variable */ + char **pzOut /* OUT: Write the error message string here */ +){ + Pgno i; + IntegrityCk sCheck; + BtShared *pBt = p->pBt; + u64 savedDbFlags = pBt->db->flags; + char zErr[100]; + int bPartial = 0; /* True if not checking all btrees */ + int bCkFreelist = 1; /* True to scan the freelist */ + VVA_ONLY( int nRef ); + + assert( nRoot>0 ); + assert( aCnt!=0 ); + + /* aRoot[0]==0 means this is a partial check */ + if( aRoot[0]==0 ){ + assert( nRoot>1 ); + bPartial = 1; + if( aRoot[1]!=1 ) bCkFreelist = 0; + } + + sqlite3BtreeEnter(p); + assert( p->inTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE ); + VVA_ONLY( nRef = sqlite3PagerRefcount(pBt->pPager) ); + assert( nRef>=0 ); + memset(&sCheck, 0, sizeof(sCheck)); + sCheck.db = db; + sCheck.pBt = pBt; + sCheck.pPager = pBt->pPager; + sCheck.nCkPage = btreePagecount(sCheck.pBt); + sCheck.mxErr = mxErr; + sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH); + sCheck.errMsg.printfFlags = SQLITE_PRINTF_INTERNAL; + if( sCheck.nCkPage==0 ){ + goto integrity_ck_cleanup; + } + + sCheck.aPgRef = sqlite3MallocZero((sCheck.nCkPage / 8)+ 1); + if( !sCheck.aPgRef ){ + checkOom(&sCheck); + goto integrity_ck_cleanup; + } + sCheck.heap = (u32*)sqlite3PageMalloc( pBt->pageSize ); +#ifdef SQLITE_DEBUG + sCheck.mxHeap = pBt->pageSize/4 - 1; +#endif + if( sCheck.heap==0 ){ + checkOom(&sCheck); + goto integrity_ck_cleanup; + } + + i = PENDING_BYTE_PAGE(pBt); + if( i<=sCheck.nCkPage ) setPageReferenced(&sCheck, i); + + /* Check the integrity of the freelist + */ + if( bCkFreelist ){ + sCheck.zPfx = "Freelist: "; + checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]), + get4byte(&pBt->pPage1->aData[36])); + sCheck.zPfx = 0; + } + + /* Check all the tables. + */ +#ifndef SQLITE_OMIT_AUTOVACUUM + if( !bPartial ){ + if( pBt->autoVacuum ){ + Pgno mx = 0; + Pgno mxInHdr; + for(i=0; (int)ipPage1->aData[52]); + if( mx!=mxInHdr ){ + checkAppendMsg(&sCheck, + "max rootpage (%u) disagrees with header (%u)", + mx, mxInHdr + ); + } + }else if( get4byte(&pBt->pPage1->aData[64])!=0 ){ + checkAppendMsg(&sCheck, + "incremental_vacuum enabled with a max rootpage of zero" + ); + } + } +#endif + testcase( pBt->db->flags & SQLITE_CellSizeCk ); + pBt->db->flags &= ~(u64)SQLITE_CellSizeCk; + for(i=0; (int)iautoVacuum && aRoot[i]>1 && !bPartial ){ + checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0); + } +#endif + sCheck.v0 = aRoot[i]; + checkTreePage(&sCheck, aRoot[i], ¬Used, LARGEST_INT64); + } + sqlite3MemSetArrayInt64(aCnt, i, sCheck.nRow); + } + pBt->db->flags = savedDbFlags; + + /* Make sure every page in the file is referenced + */ + if( !bPartial ){ + for(i=1; i<=sCheck.nCkPage && sCheck.mxErr; i++){ +#ifdef SQLITE_OMIT_AUTOVACUUM + if( getPageReferenced(&sCheck, i)==0 ){ + checkAppendMsg(&sCheck, "Page %u: never used", i); + } +#else + /* If the database supports auto-vacuum, make sure no tables contain + ** references to pointer-map pages. + */ + if( getPageReferenced(&sCheck, i)==0 && + (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){ + checkAppendMsg(&sCheck, "Page %u: never used", i); + } + if( getPageReferenced(&sCheck, i)!=0 && + (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){ + checkAppendMsg(&sCheck, "Page %u: pointer map referenced", i); + } +#endif + } + } + + /* Clean up and report errors. + */ +integrity_ck_cleanup: + sqlite3PageFree(sCheck.heap); + sqlite3_free(sCheck.aPgRef); + *pnErr = sCheck.nErr; + if( sCheck.nErr==0 ){ + sqlite3_str_reset(&sCheck.errMsg); + *pzOut = 0; + }else{ + *pzOut = sqlite3StrAccumFinish(&sCheck.errMsg); + } + /* Make sure this analysis did not leave any unref() pages. */ + assert( nRef==sqlite3PagerRefcount(pBt->pPager) ); + sqlite3BtreeLeave(p); + return sCheck.rc; +} +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ + +/* +** Return the full pathname of the underlying database file. Return +** an empty string if the database is in-memory or a TEMP database. +** +** The pager filename is invariant as long as the pager is +** open so it is safe to access without the BtShared mutex. +*/ +SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *p){ + assert( p->pBt->pPager!=0 ); + return sqlite3PagerFilename(p->pBt->pPager, 1); +} + +/* +** Return the pathname of the journal file for this database. The return +** value of this routine is the same regardless of whether the journal file +** has been created or not. +** +** The pager journal filename is invariant as long as the pager is +** open so it is safe to access without the BtShared mutex. +*/ +SQLITE_PRIVATE const char *sqlite3BtreeGetJournalname(Btree *p){ + assert( p->pBt->pPager!=0 ); + return sqlite3PagerJournalname(p->pBt->pPager); +} + +/* +** Return one of SQLITE_TXN_NONE, SQLITE_TXN_READ, or SQLITE_TXN_WRITE +** to describe the current transaction state of Btree p. +*/ +SQLITE_PRIVATE int sqlite3BtreeTxnState(Btree *p){ + assert( p==0 || sqlite3_mutex_held(p->db->mutex) ); + return p ? p->inTrans : 0; +} + +#ifndef SQLITE_OMIT_WAL +/* +** Run a checkpoint on the Btree passed as the first argument. +** +** Return SQLITE_LOCKED if this or any other connection has an open +** transaction on the shared-cache the argument Btree is connected to. +** +** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART. +*/ +SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree *p, int eMode, int *pnLog, int *pnCkpt){ + int rc = SQLITE_OK; + if( p ){ + BtShared *pBt = p->pBt; + sqlite3BtreeEnter(p); + if( pBt->inTransaction!=TRANS_NONE ){ + rc = SQLITE_LOCKED; + }else{ + rc = sqlite3PagerCheckpoint(pBt->pPager, p->db, eMode, pnLog, pnCkpt); + } + sqlite3BtreeLeave(p); + } + return rc; +} +#endif + +/* +** Return true if there is currently a backup running on Btree p. +*/ +SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree *p){ + assert( p ); + assert( sqlite3_mutex_held(p->db->mutex) ); + return p->nBackup!=0; +} + +/* +** This function returns a pointer to a blob of memory associated with +** a single shared-btree. The memory is used by client code for its own +** purposes (for example, to store a high-level schema associated with +** the shared-btree). The btree layer manages reference counting issues. +** +** The first time this is called on a shared-btree, nBytes bytes of memory +** are allocated, zeroed, and returned to the caller. For each subsequent +** call the nBytes parameter is ignored and a pointer to the same blob +** of memory returned. +** +** If the nBytes parameter is 0 and the blob of memory has not yet been +** allocated, a null pointer is returned. If the blob has already been +** allocated, it is returned as normal. +** +** Just before the shared-btree is closed, the function passed as the +** xFree argument when the memory allocation was made is invoked on the +** blob of allocated memory. The xFree function should not call sqlite3_free() +** on the memory, the btree layer does that. +*/ +SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){ + BtShared *pBt = p->pBt; + assert( nBytes==0 || nBytes==sizeof(Schema) ); + sqlite3BtreeEnter(p); + if( !pBt->pSchema && nBytes ){ + pBt->pSchema = sqlite3DbMallocZero(0, nBytes); + pBt->xFreeSchema = xFree; + } + sqlite3BtreeLeave(p); + return pBt->pSchema; +} + +/* +** Return SQLITE_LOCKED_SHAREDCACHE if another user of the same shared +** btree as the argument handle holds an exclusive lock on the +** sqlite_schema table. Otherwise SQLITE_OK. +*/ +SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *p){ + int rc; + UNUSED_PARAMETER(p); /* only used in DEBUG builds */ + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + rc = querySharedCacheTableLock(p, SCHEMA_ROOT, READ_LOCK); + assert( rc==SQLITE_OK || rc==SQLITE_LOCKED_SHAREDCACHE ); + sqlite3BtreeLeave(p); + return rc; +} + + +#ifndef SQLITE_OMIT_SHARED_CACHE +/* +** Obtain a lock on the table whose root page is iTab. The +** lock is a write lock if isWritelock is true or a read lock +** if it is false. +*/ +SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){ + int rc = SQLITE_OK; + assert( p->inTrans!=TRANS_NONE ); + if( p->sharable ){ + u8 lockType = READ_LOCK + isWriteLock; + assert( READ_LOCK+1==WRITE_LOCK ); + assert( isWriteLock==0 || isWriteLock==1 ); + + sqlite3BtreeEnter(p); + rc = querySharedCacheTableLock(p, iTab, lockType); + if( rc==SQLITE_OK ){ + rc = setSharedCacheTableLock(p, iTab, lockType); + } + sqlite3BtreeLeave(p); + } + return rc; +} +#endif + +#ifndef SQLITE_OMIT_INCRBLOB +/* +** Argument pCsr must be a cursor opened for writing on an +** INTKEY table currently pointing at a valid table entry. +** This function modifies the data stored as part of that entry. +** +** Only the data content may only be modified, it is not possible to +** change the length of the data stored. If this function is called with +** parameters that attempt to write past the end of the existing data, +** no modifications are made and SQLITE_CORRUPT is returned. +*/ +SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){ + int rc; + assert( cursorOwnsBtShared(pCsr) ); + assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) ); + assert( pCsr->curFlags & BTCF_Incrblob ); + + rc = restoreCursorPosition(pCsr); + if( rc!=SQLITE_OK ){ + return rc; + } + assert( pCsr->eState!=CURSOR_REQUIRESEEK ); + if( pCsr->eState!=CURSOR_VALID ){ + return SQLITE_ABORT; + } + + /* Save the positions of all other cursors open on this table. This is + ** required in case any of them are holding references to an xFetch + ** version of the b-tree page modified by the accessPayload call below. + ** + ** Note that pCsr must be open on a INTKEY table and saveCursorPosition() + ** and hence saveAllCursors() cannot fail on a BTREE_INTKEY table, hence + ** saveAllCursors can only return SQLITE_OK. + */ + VVA_ONLY(rc =) saveAllCursors(pCsr->pBt, pCsr->pgnoRoot, pCsr); + assert( rc==SQLITE_OK ); + + /* Check some assumptions: + ** (a) the cursor is open for writing, + ** (b) there is a read/write transaction open, + ** (c) the connection holds a write-lock on the table (if required), + ** (d) there are no conflicting read-locks, and + ** (e) the cursor points at a valid row of an intKey table. + */ + if( (pCsr->curFlags & BTCF_WriteFlag)==0 ){ + return SQLITE_READONLY; + } + assert( (pCsr->pBt->btsFlags & BTS_READ_ONLY)==0 + && pCsr->pBt->inTransaction==TRANS_WRITE ); + assert( hasSharedCacheTableLock(pCsr->pBtree, pCsr->pgnoRoot, 0, 2) ); + assert( !hasReadConflicts(pCsr->pBtree, pCsr->pgnoRoot) ); + assert( pCsr->pPage->intKey ); + + return accessPayload(pCsr, offset, amt, (unsigned char *)z, 1); +} + +/* +** Mark this cursor as an incremental blob cursor. +*/ +SQLITE_PRIVATE void sqlite3BtreeIncrblobCursor(BtCursor *pCur){ + pCur->curFlags |= BTCF_Incrblob; + pCur->pBtree->hasIncrblobCur = 1; +} +#endif + +/* +** Set both the "read version" (single byte at byte offset 18) and +** "write version" (single byte at byte offset 19) fields in the database +** header to iVersion. +*/ +SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){ + BtShared *pBt = pBtree->pBt; + int rc; /* Return code */ + + assert( iVersion==1 || iVersion==2 ); + + /* If setting the version fields to 1, do not automatically open the + ** WAL connection, even if the version fields are currently set to 2. + */ + pBt->btsFlags &= ~BTS_NO_WAL; + if( iVersion==1 ) pBt->btsFlags |= BTS_NO_WAL; + + rc = sqlite3BtreeBeginTrans(pBtree, 0, 0); + if( rc==SQLITE_OK ){ + u8 *aData = pBt->pPage1->aData; + if( aData[18]!=(u8)iVersion || aData[19]!=(u8)iVersion ){ + rc = sqlite3BtreeBeginTrans(pBtree, 2, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + if( rc==SQLITE_OK ){ + aData[18] = (u8)iVersion; + aData[19] = (u8)iVersion; + } + } + } + } + + pBt->btsFlags &= ~BTS_NO_WAL; + return rc; +} + +/* +** Return true if the cursor has a hint specified. This routine is +** only used from within assert() statements +*/ +SQLITE_PRIVATE int sqlite3BtreeCursorHasHint(BtCursor *pCsr, unsigned int mask){ + return (pCsr->hints & mask)!=0; +} + +/* +** Return true if the given Btree is read-only. +*/ +SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *p){ + return (p->pBt->btsFlags & BTS_READ_ONLY)!=0; +} + +/* +** Return the size of the header added to each page by this module. +*/ +SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void){ return ROUND8(sizeof(MemPage)); } + +/* +** If no transaction is active and the database is not a temp-db, clear +** the in-memory pager cache. +*/ +SQLITE_PRIVATE void sqlite3BtreeClearCache(Btree *p){ + BtShared *pBt = p->pBt; + if( pBt->inTransaction==TRANS_NONE ){ + sqlite3PagerClearCache(pBt->pPager); + } +} + +#if !defined(SQLITE_OMIT_SHARED_CACHE) +/* +** Return true if the Btree passed as the only argument is sharable. +*/ +SQLITE_PRIVATE int sqlite3BtreeSharable(Btree *p){ + return p->sharable; +} + +/* +** Return the number of connections to the BtShared object accessed by +** the Btree handle passed as the only argument. For private caches +** this is always 1. For shared caches it may be 1 or greater. +*/ +SQLITE_PRIVATE int sqlite3BtreeConnectionCount(Btree *p){ + testcase( p->sharable ); + return p->pBt->nRef; +} +#endif + +/************** End of btree.c ***********************************************/ +/************** Begin file backup.c ******************************************/ +/* +** 2009 January 28 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains the implementation of the sqlite3_backup_XXX() +** API functions and the related features. +*/ +/* #include "sqliteInt.h" */ +/* #include "btreeInt.h" */ + +/* +** Structure allocated for each backup operation. +*/ +struct sqlite3_backup { + sqlite3* pDestDb; /* Destination database handle */ + char *zDestDb; + Btree *pDest; /* Destination b-tree file */ + u32 iDestSchema; /* Original schema cookie in destination */ + int bDestLocked; /* True once a write-transaction is open on pDest */ + + Pgno iNext; /* Page number of the next source page to copy */ + sqlite3* pSrcDb; /* Source database handle */ + Btree *pSrc; /* Source b-tree file */ + + int rc; /* Backup process error code */ + + /* These two variables are set by every call to backup_step(). They are + ** read by calls to backup_remaining() and backup_pagecount(). + */ + Pgno nRemaining; /* Number of pages left to copy */ + Pgno nPagecount; /* Total number of pages to copy */ + + int isAttached; /* True once backup has been registered with pager */ + sqlite3_backup *pNext; /* Next backup associated with source pager */ +}; + +/* +** THREAD SAFETY NOTES: +** +** Once it has been created using backup_init(), a single sqlite3_backup +** structure may be accessed via two groups of thread-safe entry points: +** +** * Via the sqlite3_backup_XXX() API function backup_step() and +** backup_finish(). Both these functions obtain the source database +** handle mutex and the mutex associated with the source BtShared +** structure, in that order. +** +** * Via the BackupUpdate() and BackupRestart() functions, which are +** invoked by the pager layer to report various state changes in +** the page cache associated with the source database. The mutex +** associated with the source database BtShared structure will always +** be held when either of these functions are invoked. +** +** The other sqlite3_backup_XXX() API functions, backup_remaining() and +** backup_pagecount() are not thread-safe functions. If they are called +** while some other thread is calling backup_step() or backup_finish(), +** the values returned may be invalid. There is no way for a call to +** BackupUpdate() or BackupRestart() to interfere with backup_remaining() +** or backup_pagecount(). +** +** Depending on the SQLite configuration, the database handles and/or +** the Btree objects may have their own mutexes that require locking. +** Non-sharable Btrees (in-memory databases for example), do not have +** associated mutexes. +*/ + +/* +** Return a pointer corresponding to database zDb (i.e. "main", "temp") +** in connection handle pDb. If such a database cannot be found, return +** a NULL pointer and write an error message to pErrorDb. +** +** If the "temp" database is requested, it may need to be opened by this +** function. If an error occurs while doing so, return 0 and write an +** error message to pErrorDb. +*/ +static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){ + int i = sqlite3FindDbName(pDb, zDb); + + if( i==1 ){ + Parse sParse; + int rc = 0; + sqlite3ParseObjectInit(&sParse,pDb); + if( sqlite3OpenTempDatabase(&sParse) ){ + sqlite3ErrorWithMsg(pErrorDb, sParse.rc, "%s", sParse.zErrMsg); + rc = SQLITE_ERROR; + } + sqlite3DbFree(pErrorDb, sParse.zErrMsg); + sqlite3ParseObjectReset(&sParse); + if( rc ){ + return 0; + } + } + + if( i<0 ){ + sqlite3ErrorWithMsg(pErrorDb, SQLITE_ERROR, "unknown database %s", zDb); + return 0; + } + + return pDb->aDb[i].pBt; +} + +/* +** Attempt to set the page size of the destination to match the page size +** of the source. +*/ +static int setDestPgsz(Btree *pDest, Btree *pSrc){ + return sqlite3BtreeSetPageSize(pDest, sqlite3BtreeGetPageSize(pSrc), 0, 0); +} + +/* +** Check that there is no open read-transaction on the b-tree passed as the +** second argument. If there is not, return SQLITE_OK. Otherwise, if there +** is an open read-transaction, return SQLITE_ERROR and leave an error +** message in database handle db. +*/ +static int checkReadTransaction(sqlite3 *db, Btree *p){ + if( sqlite3BtreeTxnState(p)!=SQLITE_TXN_NONE ){ + sqlite3ErrorWithMsg(db, SQLITE_ERROR, "destination database is in use"); + return SQLITE_ERROR; + } + return SQLITE_OK; +} + +/* +** Create an sqlite3_backup process to copy the contents of zSrcDb from +** connection handle pSrcDb to zDestDb in pDestDb. If successful, return +** a pointer to the new sqlite3_backup object. +** +** If an error occurs, NULL is returned and an error code and error message +** stored in database handle pDestDb. +*/ +SQLITE_API sqlite3_backup *sqlite3_backup_init( + sqlite3* pDestDb, /* Database to write to */ + const char *zDestDb, /* Name of database within pDestDb */ + sqlite3* pSrcDb, /* Database connection to read from */ + const char *zSrcDb /* Name of database within pSrcDb */ +){ + sqlite3_backup *p; /* Value to return */ + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(pSrcDb)||!sqlite3SafetyCheckOk(pDestDb) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + + /* Lock the source database handle. The destination database + ** handle is not locked in this routine, but it is locked in + ** sqlite3_backup_step(). The user is required to ensure that no + ** other thread accesses the destination handle for the duration + ** of the backup operation. Any attempt to use the destination + ** database connection while a backup is in progress may cause + ** a malfunction or a deadlock. + */ + sqlite3_mutex_enter(pSrcDb->mutex); + sqlite3_mutex_enter(pDestDb->mutex); + + if( pSrcDb==pDestDb ){ + sqlite3ErrorWithMsg( + pDestDb, SQLITE_ERROR, "source and destination must be distinct" + ); + p = 0; + }else { + int nDest = sqlite3Strlen30(zDestDb); + + /* Allocate space for a new sqlite3_backup object... + ** EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a + ** call to sqlite3_backup_init() and is destroyed by a call to + ** sqlite3_backup_finish(). */ + p = (sqlite3_backup*)sqlite3MallocZero(sizeof(sqlite3_backup)+nDest+1); + if( !p ){ + sqlite3Error(pDestDb, SQLITE_NOMEM_BKPT); + }else{ + p->zDestDb = (char*)&p[1]; + memcpy(p->zDestDb, zDestDb, nDest); + } + } + + /* If the allocation succeeded, populate the new object. */ + if( p ){ + /* Do not store the pointer to the destination b-tree at this point. + ** This is because there is nothing preventing it from being detached + ** or otherwise freed before the first call to sqlite3_backup_step() + ** on this object. The source b-tree does not have this problem, as + ** incrementing Btree.nBackup (see below) effectively locks the object. */ + Btree *pDest = findBtree(pDestDb, pDestDb, zDestDb); + p->pSrc = findBtree(pDestDb, pSrcDb, zSrcDb); + p->pDestDb = pDestDb; + p->pSrcDb = pSrcDb; + p->iNext = 1; + p->isAttached = 0; + + if( 0==p->pSrc || 0==pDest + || checkReadTransaction(pDestDb, pDest)!=SQLITE_OK + ){ + /* One (or both) of the named databases did not exist or an OOM + ** error was hit. Or there is a transaction open on the destination + ** database. The error has already been written into the pDestDb + ** handle. All that is left to do here is free the sqlite3_backup + ** structure. */ + sqlite3_free(p); + p = 0; + } + } + if( p ){ + p->pSrc->nBackup++; + } + + sqlite3_mutex_leave(pDestDb->mutex); + sqlite3_mutex_leave(pSrcDb->mutex); + return p; +} + +/* +** Argument rc is an SQLite error code. Return true if this error is +** considered fatal if encountered during a backup operation. All errors +** are considered fatal except for SQLITE_BUSY and SQLITE_LOCKED. +*/ +static int isFatalError(int rc){ + return (rc!=SQLITE_OK && rc!=SQLITE_BUSY && ALWAYS(rc!=SQLITE_LOCKED)); +} + +/* +** Parameter zSrcData points to a buffer containing the data for +** page iSrcPg from the source database. Copy this data into the +** destination database. +*/ +static int backupOnePage( + sqlite3_backup *p, /* Backup handle */ + Pgno iSrcPg, /* Source database page to backup */ + const u8 *zSrcData, /* Source database page data */ + int bUpdate /* True for an update, false otherwise */ +){ + Pager * const pDestPager = sqlite3BtreePager(p->pDest); + const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc); + int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest); + const int nCopy = MIN(nSrcPgsz, nDestPgsz); + const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz; + int rc = SQLITE_OK; + i64 iOff; + + assert( sqlite3BtreeGetReserveNoMutex(p->pSrc)>=0 ); + assert( p->bDestLocked ); + assert( !isFatalError(p->rc) ); + assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ); + assert( zSrcData ); + assert( nSrcPgsz==nDestPgsz || sqlite3PagerIsMemdb(pDestPager)==0 ); + + /* This loop runs once for each destination page spanned by the source + ** page. For each iteration, variable iOff is set to the byte offset + ** of the destination page. + */ + for(iOff=iEnd-(i64)nSrcPgsz; rc==SQLITE_OK && iOffpDest->pBt) ) continue; + if( SQLITE_OK==(rc = sqlite3PagerGet(pDestPager, iDest, &pDestPg, 0)) + && SQLITE_OK==(rc = sqlite3PagerWrite(pDestPg)) + ){ + const u8 *zIn = &zSrcData[iOff%nSrcPgsz]; + u8 *zDestData = sqlite3PagerGetData(pDestPg); + u8 *zOut = &zDestData[iOff%nDestPgsz]; + + /* Copy the data from the source page into the destination page. + ** Then clear the Btree layer MemPage.isInit flag. Both this module + ** and the pager code use this trick (clearing the first byte + ** of the page 'extra' space to invalidate the Btree layers + ** cached parse of the page). MemPage.isInit is marked + ** "MUST BE FIRST" for this purpose. + */ + memcpy(zOut, zIn, nCopy); + ((u8 *)sqlite3PagerGetExtra(pDestPg))[0] = 0; + if( iOff==0 && bUpdate==0 ){ + sqlite3Put4byte(&zOut[28], sqlite3BtreeLastPage(p->pSrc)); + } + } + sqlite3PagerUnref(pDestPg); + } + + return rc; +} + +/* +** If pFile is currently larger than iSize bytes, then truncate it to +** exactly iSize bytes. If pFile is not larger than iSize bytes, then +** this function is a no-op. +** +** Return SQLITE_OK if everything is successful, or an SQLite error +** code if an error occurs. +*/ +static int backupTruncateFile(sqlite3_file *pFile, i64 iSize){ + i64 iCurrent; + int rc = sqlite3OsFileSize(pFile, &iCurrent); + if( rc==SQLITE_OK && iCurrent>iSize ){ + rc = sqlite3OsTruncate(pFile, iSize); + } + return rc; +} + +/* +** Register this backup object with the associated source pager for +** callbacks when pages are changed or the cache invalidated. +*/ +static void attachBackupObject(sqlite3_backup *p){ + sqlite3_backup **pp; + assert( sqlite3BtreeHoldsMutex(p->pSrc) ); + pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc)); + p->pNext = *pp; + *pp = p; + p->isAttached = 1; +} + +/* +** Copy nPage pages from the source b-tree to the destination. +*/ +SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ + int rc; + int destMode = 0; /* Destination journal mode */ + int pgszSrc = 0; /* Source page size */ + int pgszDest = 0; /* Destination page size */ + +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(p->pSrcDb->mutex); + sqlite3BtreeEnter(p->pSrc); + if( p->pDestDb ){ + sqlite3_mutex_enter(p->pDestDb->mutex); + } + + rc = p->rc; + if( !isFatalError(rc) ){ + Pager * const pSrcPager = sqlite3BtreePager(p->pSrc); /* Source pager */ + Btree * pDest = 0; /* Dest btree */ + Pager * pDestPager = 0; /* Dest pager */ + int ii; /* Iterator variable */ + int nSrcPage = -1; /* Size of source db in pages */ + int bCloseTrans = 0; /* True if src db requires unlocking */ + + /* If the source pager is currently in a write-transaction, return + ** SQLITE_BUSY immediately. + */ + if( p->pDestDb && p->pSrc->pBt->inTransaction==TRANS_WRITE ){ + rc = SQLITE_BUSY; + }else{ + rc = SQLITE_OK; + } + + + /* If there is no open read-transaction on the source database, open + ** one now. If a transaction is opened here, then it will be closed + ** before this function exits. + */ + if( rc==SQLITE_OK && SQLITE_TXN_NONE==sqlite3BtreeTxnState(p->pSrc) ){ + rc = sqlite3BtreeBeginTrans(p->pSrc, 0, 0); + bCloseTrans = 1; + } + + /* Locate the destination btree and pager. */ + if( (pDest = p->pDest)==0 ){ + pDest = findBtree(p->pDestDb, p->pDestDb, p->zDestDb); + } + if( pDest==0 ){ + rc = SQLITE_ERROR; + }else{ + pDestPager = sqlite3BtreePager(pDest); + } + + /* If the destination database has not yet been locked (i.e. if this + ** is the first call to backup_step() for the current backup operation), + ** try to set its page size to the same as the source database. This + ** is especially important on ZipVFS systems, as in that case it is + ** not possible to create a database file that uses one page size by + ** writing to it with another. */ + if( p->bDestLocked==0 && rc==SQLITE_OK + && setDestPgsz(pDest, p->pSrc)==SQLITE_NOMEM + ){ + rc = SQLITE_NOMEM; + } + + /* Lock the destination database, if it is not locked already. */ + if( SQLITE_OK==rc && p->bDestLocked==0 + && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(pDest, 2, + (int*)&p->iDestSchema)) + ){ + p->bDestLocked = 1; + p->pDest = pDest; + } + + /* Do not allow backup if the destination database is in WAL mode + ** and the page sizes are different between source and destination */ + if( rc==SQLITE_OK ){ + pgszSrc = sqlite3BtreeGetPageSize(p->pSrc); + pgszDest = sqlite3BtreeGetPageSize(p->pDest); + destMode = sqlite3PagerGetJournalMode(sqlite3BtreePager(p->pDest)); + if( (destMode==PAGER_JOURNALMODE_WAL || sqlite3PagerIsMemdb(pDestPager)) + && pgszSrc!=pgszDest + ){ + rc = SQLITE_READONLY; + } + } + + /* Now that there is a read-lock on the source database, query the + ** source pager for the number of pages in the database. + */ + nSrcPage = (int)sqlite3BtreeLastPage(p->pSrc); + assert( nSrcPage>=0 ); + for(ii=0; (nPage<0 || iiiNext<=(Pgno)nSrcPage && !rc; ii++){ + const Pgno iSrcPg = p->iNext; /* Source page number */ + if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){ + DbPage *pSrcPg; /* Source page object */ + rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg,PAGER_GET_READONLY); + if( rc==SQLITE_OK ){ + rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0); + sqlite3PagerUnref(pSrcPg); + } + } + p->iNext++; + } + if( rc==SQLITE_OK ){ + p->nPagecount = nSrcPage; + p->nRemaining = nSrcPage+1-p->iNext; + if( p->iNext>(Pgno)nSrcPage ){ + rc = SQLITE_DONE; + }else if( !p->isAttached ){ + attachBackupObject(p); + } + } + + /* Update the schema version field in the destination database. This + ** is to make sure that the schema-version really does change in + ** the case where the source and destination databases have the + ** same schema version. + */ + if( rc==SQLITE_DONE ){ + if( nSrcPage==0 ){ + rc = sqlite3BtreeNewDb(p->pDest); + nSrcPage = 1; + } + if( rc==SQLITE_OK || rc==SQLITE_DONE ){ + rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1); + } + if( rc==SQLITE_OK ){ + if( p->pDestDb ){ + sqlite3ResetAllSchemasOfConnection(p->pDestDb); + } + if( destMode==PAGER_JOURNALMODE_WAL ){ + rc = sqlite3BtreeSetVersion(p->pDest, 2); + } + } + if( rc==SQLITE_OK ){ + int nDestTruncate; + /* Set nDestTruncate to the final number of pages in the destination + ** database. The complication here is that the destination page + ** size may be different to the source page size. + ** + ** If the source page size is smaller than the destination page size, + ** round up. In this case the call to sqlite3OsTruncate() below will + ** fix the size of the file. However it is important to call + ** sqlite3PagerTruncateImage() here so that any pages in the + ** destination file that lie beyond the nDestTruncate page mark are + ** journalled by PagerCommitPhaseOne() before they are destroyed + ** by the file truncation. + */ + assert( pgszSrc==sqlite3BtreeGetPageSize(p->pSrc) ); + assert( pgszDest==sqlite3BtreeGetPageSize(p->pDest) ); + if( pgszSrcpDest->pBt) ){ + nDestTruncate--; + } + }else{ + nDestTruncate = nSrcPage * (pgszSrc/pgszDest); + } + assert( nDestTruncate>0 ); + + if( pgszSrc= iSize || ( + nDestTruncate==(int)(PENDING_BYTE_PAGE(p->pDest->pBt)-1) + && iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+pgszDest + )); + + /* This block ensures that all data required to recreate the original + ** database has been stored in the journal for pDestPager and the + ** journal synced to disk. So at this point we may safely modify + ** the database file in any way, knowing that if a power failure + ** occurs, the original database will be reconstructed from the + ** journal file. */ + sqlite3PagerPagecount(pDestPager, &nDstPage); + for(iPg=nDestTruncate; rc==SQLITE_OK && iPg<=(Pgno)nDstPage; iPg++){ + if( iPg!=PENDING_BYTE_PAGE(p->pDest->pBt) ){ + DbPage *pPg; + rc = sqlite3PagerGet(pDestPager, iPg, &pPg, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3PagerWrite(pPg); + sqlite3PagerUnref(pPg); + } + } + } + if( rc==SQLITE_OK ){ + rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1); + } + + /* Write the extra pages and truncate the database file as required */ + iEnd = MIN(PENDING_BYTE + pgszDest, iSize); + for( + iOff=PENDING_BYTE+pgszSrc; + rc==SQLITE_OK && iOffpDest, 0)) + ){ + rc = SQLITE_DONE; + } + } + } + + /* If bCloseTrans is true, then this function opened a read transaction + ** on the source database. Close the read transaction here. There is + ** no need to check the return values of the btree methods here, as + ** "committing" a read-only transaction cannot fail. + */ + if( bCloseTrans ){ + TESTONLY( int rc2 ); + TESTONLY( rc2 = ) sqlite3BtreeCommitPhaseOne(p->pSrc, 0); + TESTONLY( rc2 |= ) sqlite3BtreeCommitPhaseTwo(p->pSrc, 0); + assert( rc2==SQLITE_OK ); + } + + if( rc==SQLITE_IOERR_NOMEM ){ + rc = SQLITE_NOMEM_BKPT; + } + p->rc = rc; + } + if( p->pDestDb ){ + sqlite3_mutex_leave(p->pDestDb->mutex); + } + sqlite3BtreeLeave(p->pSrc); + sqlite3_mutex_leave(p->pSrcDb->mutex); + return rc; +} + +/* +** Release all resources associated with an sqlite3_backup* handle. +*/ +SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){ + sqlite3_backup **pp; /* Ptr to head of pagers backup list */ + sqlite3 *pSrcDb; /* Source database connection */ + int rc; /* Value to return */ + + /* Enter the mutexes */ + if( p==0 ) return SQLITE_OK; + pSrcDb = p->pSrcDb; + sqlite3_mutex_enter(pSrcDb->mutex); + sqlite3BtreeEnter(p->pSrc); + if( p->pDestDb ){ + sqlite3_mutex_enter(p->pDestDb->mutex); + } + + /* Detach this backup from the source pager. */ + if( p->pDestDb ){ + p->pSrc->nBackup--; + } + if( p->isAttached ){ + pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc)); + assert( pp!=0 ); + while( *pp!=p ){ + pp = &(*pp)->pNext; + assert( pp!=0 ); + } + *pp = p->pNext; + } + + /* If a transaction is still open on the Btree, roll it back. */ + if( p->pDest ){ + sqlite3BtreeRollback(p->pDest, SQLITE_OK, 0); + } + + /* Set the error code of the destination database handle. */ + rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc; + if( p->pDestDb ){ + sqlite3Error(p->pDestDb, rc); + + /* Exit the mutexes and free the backup context structure. */ + sqlite3LeaveMutexAndCloseZombie(p->pDestDb); + } + sqlite3BtreeLeave(p->pSrc); + if( p->pDestDb ){ + /* EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a + ** call to sqlite3_backup_init() and is destroyed by a call to + ** sqlite3_backup_finish(). */ + sqlite3_free(p); + } + sqlite3LeaveMutexAndCloseZombie(pSrcDb); + return rc; +} + +/* +** Return the number of pages still to be backed up as of the most recent +** call to sqlite3_backup_step(). +*/ +SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + return p->nRemaining; +} + +/* +** Return the total number of pages in the source database as of the most +** recent call to sqlite3_backup_step(). +*/ +SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + return p->nPagecount; +} + +/* +** This function is called after the contents of page iPage of the +** source database have been modified. If page iPage has already been +** copied into the destination database, then the data written to the +** destination is now invalidated. The destination copy of iPage needs +** to be updated with the new data before the backup operation is +** complete. +** +** It is assumed that the mutex associated with the BtShared object +** corresponding to the source database is held when this function is +** called. +*/ +static SQLITE_NOINLINE void backupUpdate( + sqlite3_backup *p, + Pgno iPage, + const u8 *aData +){ + assert( p!=0 ); + do{ + assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) ); + if( !isFatalError(p->rc) && iPageiNext ){ + /* The backup process p has already copied page iPage. But now it + ** has been modified by a transaction on the source pager. Copy + ** the new data into the backup. + */ + int rc; + assert( p->pDestDb ); + sqlite3_mutex_enter(p->pDestDb->mutex); + rc = backupOnePage(p, iPage, aData, 1); + sqlite3_mutex_leave(p->pDestDb->mutex); + assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED ); + if( rc!=SQLITE_OK ){ + p->rc = rc; + } + } + }while( (p = p->pNext)!=0 ); +} +SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *pBackup, Pgno iPage, const u8 *aData){ + if( pBackup ) backupUpdate(pBackup, iPage, aData); +} + +/* +** Restart the backup process. This is called when the pager layer +** detects that the database has been modified by an external database +** connection. In this case there is no way of knowing which of the +** pages that have been copied into the destination database are still +** valid and which are not, so the entire process needs to be restarted. +** +** It is assumed that the mutex associated with the BtShared object +** corresponding to the source database is held when this function is +** called. +*/ +SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *pBackup){ + sqlite3_backup *p; /* Iterator variable */ + for(p=pBackup; p; p=p->pNext){ + assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) ); + p->iNext = 1; + } +} + +#ifndef SQLITE_OMIT_VACUUM +/* +** Copy the complete content of pBtFrom into pBtTo. A transaction +** must be active for both files. +** +** The size of file pTo may be reduced by this operation. If anything +** goes wrong, the transaction on pTo is rolled back. If successful, the +** transaction is committed before returning. +*/ +SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ + int rc; + sqlite3_file *pFd; /* File descriptor for database pTo */ + sqlite3_backup b; + sqlite3BtreeEnter(pTo); + sqlite3BtreeEnter(pFrom); + + assert( sqlite3BtreeTxnState(pTo)==SQLITE_TXN_WRITE ); + pFd = sqlite3PagerFile(sqlite3BtreePager(pTo)); + if( pFd->pMethods ){ + i64 nByte = sqlite3BtreeGetPageSize(pFrom)*(i64)sqlite3BtreeLastPage(pFrom); + rc = sqlite3OsFileControl(pFd, SQLITE_FCNTL_OVERWRITE, &nByte); + if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; + if( rc ) goto copy_finished; + } + + /* Set up an sqlite3_backup object. sqlite3_backup.pDestDb must be set + ** to 0. This is used by the implementations of sqlite3_backup_step() + ** and sqlite3_backup_finish() to detect that they are being called + ** from this function, not directly by the user. + */ + memset(&b, 0, sizeof(b)); + b.pSrcDb = pFrom->db; + b.pSrc = pFrom; + b.pDest = pTo; + b.iNext = 1; + + /* 0x7FFFFFFF is the hard limit for the number of pages in a database + ** file. By passing this as the number of pages to copy to + ** sqlite3_backup_step(), we can guarantee that the copy finishes + ** within a single call (unless an error occurs). The assert() statement + ** checks this assumption - (p->rc) should be set to either SQLITE_DONE + ** or an error code. */ + sqlite3_backup_step(&b, 0x7FFFFFFF); + assert( b.rc!=SQLITE_OK ); + + rc = sqlite3_backup_finish(&b); + if( rc==SQLITE_OK ){ + pTo->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED; + }else{ + sqlite3PagerClearCache(sqlite3BtreePager(b.pDest)); + } + + assert( sqlite3BtreeTxnState(pTo)!=SQLITE_TXN_WRITE ); +copy_finished: + sqlite3BtreeLeave(pFrom); + sqlite3BtreeLeave(pTo); + return rc; +} +#endif /* SQLITE_OMIT_VACUUM */ + +/************** End of backup.c **********************************************/ +/************** Begin file vdbemem.c *****************************************/ +/* +** 2004 May 26 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains code use to manipulate "Mem" structure. A "Mem" +** stores a single value in the VDBE. Mem is an opaque structure visible +** only within the VDBE. Interface routines refer to a Mem using the +** name sqlite_value +*/ +/* #include "sqliteInt.h" */ +/* #include "vdbeInt.h" */ + +/* True if X is a power of two. 0 is considered a power of two here. +** In other words, return true if X has at most one bit set. +*/ +#define ISPOWEROF2(X) (((X)&((X)-1))==0) + +#ifdef SQLITE_DEBUG +/* +** Check invariants on a Mem object. +** +** This routine is intended for use inside of assert() statements, like +** this: assert( sqlite3VdbeCheckMemInvariants(pMem) ); +*/ +SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){ + /* If MEM_Dyn is set then Mem.xDel!=0. + ** Mem.xDel might not be initialized if MEM_Dyn is clear. + */ + assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 ); + + /* MEM_Dyn may only be set if Mem.szMalloc==0. In this way we + ** ensure that if Mem.szMalloc>0 then it is safe to do + ** Mem.z = Mem.zMalloc without having to check Mem.flags&MEM_Dyn. + ** That saves a few cycles in inner loops. */ + assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 ); + + /* Cannot have more than one of MEM_Int, MEM_Real, or MEM_IntReal */ + assert( ISPOWEROF2(p->flags & (MEM_Int|MEM_Real|MEM_IntReal)) ); + + if( p->flags & MEM_Null ){ + /* Cannot be both MEM_Null and some other type */ + assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob|MEM_Agg))==0 ); + + /* If MEM_Null is set, then either the value is a pure NULL (the usual + ** case) or it is a pointer set using sqlite3_bind_pointer() or + ** sqlite3_result_pointer(). If a pointer, then MEM_Term must also be + ** set. + */ + if( (p->flags & (MEM_Term|MEM_Subtype))==(MEM_Term|MEM_Subtype) ){ + /* This is a pointer type. There may be a flag to indicate what to + ** do with the pointer. */ + assert( ((p->flags&MEM_Dyn)!=0 ? 1 : 0) + + ((p->flags&MEM_Ephem)!=0 ? 1 : 0) + + ((p->flags&MEM_Static)!=0 ? 1 : 0) <= 1 ); + + /* No other bits set */ + assert( (p->flags & ~(MEM_Null|MEM_Term|MEM_Subtype|MEM_FromBind + |MEM_Dyn|MEM_Ephem|MEM_Static))==0 ); + }else{ + /* A pure NULL might have other flags, such as MEM_Static, MEM_Dyn, + ** MEM_Ephem, MEM_Cleared, or MEM_Subtype */ + } + }else{ + /* The MEM_Cleared bit is only allowed on NULLs */ + assert( (p->flags & MEM_Cleared)==0 ); + } + + /* The szMalloc field holds the correct memory allocation size */ + assert( p->szMalloc==0 + || (p->flags==MEM_Undefined + && p->szMalloc<=sqlite3DbMallocSize(p->db,p->zMalloc)) + || p->szMalloc==sqlite3DbMallocSize(p->db,p->zMalloc)); + + /* If p holds a string or blob, the Mem.z must point to exactly + ** one of the following: + ** + ** (1) Memory in Mem.zMalloc and managed by the Mem object + ** (2) Memory to be freed using Mem.xDel + ** (3) An ephemeral string or blob + ** (4) A static string or blob + */ + if( (p->flags & (MEM_Str|MEM_Blob)) && p->n>0 ){ + assert( + ((p->szMalloc>0 && p->z==p->zMalloc)? 1 : 0) + + ((p->flags&MEM_Dyn)!=0 ? 1 : 0) + + ((p->flags&MEM_Ephem)!=0 ? 1 : 0) + + ((p->flags&MEM_Static)!=0 ? 1 : 0) == 1 + ); + } + return 1; +} +#endif + +/* +** Render a Mem object which is one of MEM_Int, MEM_Real, or MEM_IntReal +** into a buffer. +*/ +static void vdbeMemRenderNum(int sz, char *zBuf, Mem *p){ + StrAccum acc; + assert( p->flags & (MEM_Int|MEM_Real|MEM_IntReal) ); + assert( sz>22 ); + if( p->flags & (MEM_Int|MEM_IntReal) ){ +#if GCC_VERSION>=7000000 && GCC_VERSION<15000000 && defined(__i386__) + /* Work-around for GCC bug or bugs: + ** https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96270 + ** https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114659 + ** The problem appears to be fixed in GCC 15 */ + i64 x; + assert( (MEM_Str&~p->flags)*4==sizeof(x) ); + memcpy(&x, (char*)&p->u, (MEM_Str&~p->flags)*4); + p->n = sqlite3Int64ToText(x, zBuf); +#else + p->n = sqlite3Int64ToText(p->u.i, zBuf); +#endif + if( p->flags & MEM_IntReal ){ + memcpy(zBuf+p->n,".0", 3); + p->n += 2; + } + }else{ + sqlite3StrAccumInit(&acc, 0, zBuf, sz, 0); + sqlite3_str_appendf(&acc, "%!.*g", + (p->db ? p->db->nFpDigit : 17), p->u.r); + assert( acc.zText==zBuf && acc.mxAlloc<=0 ); + zBuf[acc.nChar] = 0; /* Fast version of sqlite3StrAccumFinish(&acc) */ + p->n = acc.nChar; + } +} + +#ifdef SQLITE_DEBUG +/* +** Validity checks on pMem. pMem holds a string. +** +** (1) Check that string value of pMem agrees with its integer or real value. +** (2) Check that the string is correctly zero terminated +** +** A single int or real value always converts to the same strings. But +** many different strings can be converted into the same int or real. +** If a table contains a numeric value and an index is based on the +** corresponding string value, then it is important that the string be +** derived from the numeric value, not the other way around, to ensure +** that the index and table are consistent. See ticket +** https://sqlite.org/src/info/343634942dd54ab (2018-01-31) for +** an example. +** +** This routine looks at pMem to verify that if it has both a numeric +** representation and a string representation then the string rep has +** been derived from the numeric and not the other way around. It returns +** true if everything is ok and false if there is a problem. +** +** This routine is for use inside of assert() statements only. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemValidStrRep(Mem *p){ + Mem tmp; + char zBuf[100]; + char *z; + int i, j, incr; + if( (p->flags & MEM_Str)==0 ) return 1; + if( p->db && p->db->mallocFailed ) return 1; + if( p->flags & MEM_Term ){ + /* Insure that the string is properly zero-terminated. Pay particular + ** attention to the case where p->n is odd */ + if( p->szMalloc>0 && p->z==p->zMalloc ){ + assert( p->enc==SQLITE_UTF8 || p->szMalloc >= ((p->n+1)&~1)+2 ); + assert( p->enc!=SQLITE_UTF8 || p->szMalloc >= p->n+1 ); + } + assert( p->z[p->n]==0 ); + assert( p->enc==SQLITE_UTF8 || p->z[(p->n+1)&~1]==0 ); + assert( p->enc==SQLITE_UTF8 || p->z[((p->n+1)&~1)+1]==0 ); + } + if( (p->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 ) return 1; + if( p->db==0 ){ + return 1; /* db->nFpDigit required to validate p->z[] */ + } + memcpy(&tmp, p, sizeof(tmp)); + vdbeMemRenderNum(sizeof(zBuf), zBuf, &tmp); + z = p->z; + i = j = 0; + incr = 1; + if( p->enc!=SQLITE_UTF8 ){ + incr = 2; + if( p->enc==SQLITE_UTF16BE ) z++; + } + while( zBuf[j] ){ + if( zBuf[j++]!=z[i] ) return 0; + i += incr; + } + return 1; +} +#endif /* SQLITE_DEBUG */ + +/* +** If pMem is an object with a valid string representation, this routine +** ensures the internal encoding for the string representation is +** 'desiredEnc', one of SQLITE_UTF8, SQLITE_UTF16LE or SQLITE_UTF16BE. +** +** If pMem is not a string object, or the encoding of the string +** representation is already stored using the requested encoding, then this +** routine is a no-op. +** +** SQLITE_OK is returned if the conversion is successful (or not required). +** SQLITE_NOMEM may be returned if a malloc() fails during conversion +** between formats. +*/ +SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ +#ifndef SQLITE_OMIT_UTF16 + int rc; +#endif + assert( pMem!=0 ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); + assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE + || desiredEnc==SQLITE_UTF16BE ); + if( !(pMem->flags&MEM_Str) ){ + pMem->enc = desiredEnc; + return SQLITE_OK; + } + if( pMem->enc==desiredEnc ){ + return SQLITE_OK; + } + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); +#ifdef SQLITE_OMIT_UTF16 + return SQLITE_ERROR; +#else + + /* MemTranslate() may return SQLITE_OK or SQLITE_NOMEM. If NOMEM is returned, + ** then the encoding of the value may not have changed. + */ + rc = sqlite3VdbeMemTranslate(pMem, (u8)desiredEnc); + assert(rc==SQLITE_OK || rc==SQLITE_NOMEM); + assert(rc==SQLITE_OK || pMem->enc!=desiredEnc); + assert(rc==SQLITE_NOMEM || pMem->enc==desiredEnc); + return rc; +#endif +} + +/* +** Make sure pMem->z points to a writable allocation of at least n bytes. +** +** If the bPreserve argument is true, then copy of the content of +** pMem->z into the new allocation. pMem must be either a string or +** blob if bPreserve is true. If bPreserve is false, any prior content +** in pMem->z is discarded. +*/ +SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ + assert( sqlite3VdbeCheckMemInvariants(pMem) ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); + testcase( pMem->db==0 ); + + /* If the bPreserve flag is set to true, then the memory cell must already + ** contain a valid string or blob value. */ + assert( bPreserve==0 || pMem->flags&(MEM_Blob|MEM_Str) ); + testcase( bPreserve && pMem->z==0 ); + + assert( pMem->szMalloc==0 + || (pMem->flags==MEM_Undefined + && pMem->szMalloc<=sqlite3DbMallocSize(pMem->db,pMem->zMalloc)) + || pMem->szMalloc==sqlite3DbMallocSize(pMem->db,pMem->zMalloc)); + if( pMem->szMalloc>0 && bPreserve && pMem->z==pMem->zMalloc ){ + if( pMem->db ){ + pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n); + }else{ + pMem->zMalloc = sqlite3Realloc(pMem->z, n); + if( pMem->zMalloc==0 ) sqlite3_free(pMem->z); + pMem->z = pMem->zMalloc; + } + bPreserve = 0; + }else{ + if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc); + pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n); + } + if( pMem->zMalloc==0 ){ + sqlite3VdbeMemSetNull(pMem); + pMem->z = 0; + pMem->szMalloc = 0; + return SQLITE_NOMEM_BKPT; + }else{ + pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc); + } + + if( bPreserve && pMem->z ){ + assert( pMem->z!=pMem->zMalloc ); + memcpy(pMem->zMalloc, pMem->z, pMem->n); + } + if( (pMem->flags&MEM_Dyn)!=0 ){ + assert( pMem->xDel!=0 && pMem->xDel!=SQLITE_DYNAMIC ); + pMem->xDel((void *)(pMem->z)); + } + + pMem->z = pMem->zMalloc; + pMem->flags &= ~(MEM_Dyn|MEM_Ephem|MEM_Static); + return SQLITE_OK; +} + +/* +** Change the pMem->zMalloc allocation to be at least szNew bytes. +** If pMem->zMalloc already meets or exceeds the requested size, this +** routine is a no-op. +** +** Any prior string or blob content in the pMem object may be discarded. +** The pMem->xDel destructor is called, if it exists. Though MEM_Str +** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, MEM_IntReal, +** and MEM_Null values are preserved. +** +** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM) +** if unable to complete the resizing. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){ + assert( CORRUPT_DB || szNew>0 ); + assert( (pMem->flags & MEM_Dyn)==0 || pMem->szMalloc==0 ); + if( pMem->szMallocflags & MEM_Dyn)==0 ); + pMem->z = pMem->zMalloc; + pMem->flags &= (MEM_Null|MEM_Int|MEM_Real|MEM_IntReal); + return SQLITE_OK; +} + +/* +** If pMem is already a string, detect if it is a zero-terminated +** string, or make it into one if possible, and mark it as such. +** +** This is an optimization. Correct operation continues even if +** this routine is a no-op. +** +** Return true if the strig is zero-terminated after this routine is +** called and false if it is not. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemZeroTerminateIfAble(Mem *pMem){ + if( (pMem->flags & (MEM_Str|MEM_Term|MEM_Ephem|MEM_Static))!=MEM_Str ){ + /* pMem must be a string, and it cannot be an ephemeral or static string */ + return 0; + } + if( pMem->enc!=SQLITE_UTF8 ) return 0; + assert( pMem->z!=0 ); + if( pMem->flags & MEM_Dyn ){ + if( pMem->xDel==sqlite3_free + && sqlite3_msize(pMem->z) >= (u64)(pMem->n+1) + ){ + pMem->z[pMem->n] = 0; + pMem->flags |= MEM_Term; + return 1; + } + if( pMem->xDel==sqlite3RCStrUnref ){ + /* Blindly assume that all RCStr objects are zero-terminated */ + pMem->flags |= MEM_Term; + return 1; + } + }else if( pMem->szMalloc >= pMem->n+1 ){ + pMem->z[pMem->n] = 0; + pMem->flags |= MEM_Term; + return 1; + } + return 0; +} + +/* +** It is already known that pMem contains an unterminated string. +** Add the zero terminator. +** +** Three bytes of zero are added. In this way, there is guaranteed +** to be a double-zero byte at an even byte boundary in order to +** terminate a UTF16 string, even if the initial size of the buffer +** is an odd number of bytes. +*/ +static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){ + if( sqlite3VdbeMemGrow(pMem, pMem->n+3, 1) ){ + return SQLITE_NOMEM_BKPT; + } + pMem->z[pMem->n] = 0; + pMem->z[pMem->n+1] = 0; + pMem->z[pMem->n+2] = 0; + pMem->flags |= MEM_Term; + return SQLITE_OK; +} + +/* +** Change pMem so that its MEM_Str or MEM_Blob value is stored in +** MEM.zMalloc, where it can be safely written. +** +** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){ + assert( pMem!=0 ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); + if( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ){ + if( ExpandBlob(pMem) ) return SQLITE_NOMEM; + if( pMem->szMalloc==0 || pMem->z!=pMem->zMalloc ){ + int rc = vdbeMemAddTerminator(pMem); + if( rc ) return rc; + } + } + pMem->flags &= ~MEM_Ephem; +#ifdef SQLITE_DEBUG + pMem->pScopyFrom = 0; +#endif + + return SQLITE_OK; +} + +/* +** If the given Mem* has a zero-filled tail, turn it into an ordinary +** blob stored in dynamically allocated space. +*/ +#ifndef SQLITE_OMIT_INCRBLOB +SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){ + int nByte; + assert( pMem!=0 ); + assert( pMem->flags & MEM_Zero ); + assert( (pMem->flags&MEM_Blob)!=0 || MemNullNochng(pMem) ); + testcase( sqlite3_value_nochange(pMem) ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + + /* Set nByte to the number of bytes required to store the expanded blob. */ + nByte = pMem->n + pMem->u.nZero; + if( nByte<=0 ){ + if( (pMem->flags & MEM_Blob)==0 ) return SQLITE_OK; + nByte = 1; + } + if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){ + return SQLITE_NOMEM_BKPT; + } + assert( pMem->z!=0 ); + assert( sqlite3DbMallocSize(pMem->db,pMem->z) >= nByte ); + + memset(&pMem->z[pMem->n], 0, pMem->u.nZero); + pMem->n += pMem->u.nZero; + pMem->flags &= ~(MEM_Zero|MEM_Term); + return SQLITE_OK; +} +#endif + +/* +** Make sure the given Mem is \u0000 terminated. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){ + assert( pMem!=0 ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + testcase( (pMem->flags & (MEM_Term|MEM_Str))==(MEM_Term|MEM_Str) ); + testcase( (pMem->flags & (MEM_Term|MEM_Str))==0 ); + if( (pMem->flags & (MEM_Term|MEM_Str))!=MEM_Str ){ + return SQLITE_OK; /* Nothing to do */ + }else{ + return vdbeMemAddTerminator(pMem); + } +} + +/* +** Add MEM_Str to the set of representations for the given Mem. This +** routine is only called if pMem is a number of some kind, not a NULL +** or a BLOB. +** +** Existing representations MEM_Int, MEM_Real, or MEM_IntReal are invalidated +** if bForce is true but are retained if bForce is false. +** +** A MEM_Null value will never be passed to this function. This function is +** used for converting values to text for returning to the user (i.e. via +** sqlite3_value_text()), or for ensuring that values to be used as btree +** keys are strings. In the former case a NULL pointer is returned the +** user and the latter is an internal programming error. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){ + const int nByte = 32; + + assert( pMem!=0 ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( !(pMem->flags&MEM_Zero) ); + assert( !(pMem->flags&(MEM_Str|MEM_Blob)) ); + assert( pMem->flags&(MEM_Int|MEM_Real|MEM_IntReal) ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); + assert( EIGHT_BYTE_ALIGNMENT(pMem) ); + + + if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){ + pMem->enc = 0; + return SQLITE_NOMEM_BKPT; + } + + vdbeMemRenderNum(nByte, pMem->z, pMem); + assert( pMem->z!=0 ); + assert( pMem->n==(int)sqlite3Strlen30NN(pMem->z) ); + pMem->enc = SQLITE_UTF8; + pMem->flags |= MEM_Str|MEM_Term; + if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal); + sqlite3VdbeChangeEncoding(pMem, enc); + return SQLITE_OK; +} + +/* +** Memory cell pMem contains the context of an aggregate function. +** This routine calls the finalize method for that function. The +** result of the aggregate is stored back into pMem. +** +** Return SQLITE_ERROR if the finalizer reports an error. SQLITE_OK +** otherwise. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ + sqlite3_context ctx; + Mem t; + assert( pFunc!=0 ); + assert( pMem!=0 ); + assert( pMem->db!=0 ); + assert( pFunc->xFinalize!=0 ); + assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef ); + assert( sqlite3_mutex_held(pMem->db->mutex) ); + memset(&ctx, 0, sizeof(ctx)); + memset(&t, 0, sizeof(t)); + t.flags = MEM_Null; + t.db = pMem->db; + ctx.pOut = &t; + ctx.pMem = pMem; + ctx.pFunc = pFunc; + ctx.enc = ENC(t.db); + pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */ + assert( (pMem->flags & MEM_Dyn)==0 ); + if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc); + memcpy(pMem, &t, sizeof(t)); + return ctx.isError; +} + +/* +** Memory cell pAccum contains the context of an aggregate function. +** This routine calls the xValue method for that function and stores +** the results in memory cell pMem. +** +** SQLITE_ERROR is returned if xValue() reports an error. SQLITE_OK +** otherwise. +*/ +#ifndef SQLITE_OMIT_WINDOWFUNC +SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem *pAccum, Mem *pOut, FuncDef *pFunc){ + sqlite3_context ctx; + assert( pFunc!=0 ); + assert( pFunc->xValue!=0 ); + assert( (pAccum->flags & MEM_Null)!=0 || pFunc==pAccum->u.pDef ); + assert( pAccum->db!=0 ); + assert( sqlite3_mutex_held(pAccum->db->mutex) ); + memset(&ctx, 0, sizeof(ctx)); + sqlite3VdbeMemSetNull(pOut); + ctx.pOut = pOut; + ctx.pMem = pAccum; + ctx.pFunc = pFunc; + ctx.enc = ENC(pAccum->db); + pFunc->xValue(&ctx); + return ctx.isError; +} +#endif /* SQLITE_OMIT_WINDOWFUNC */ + +/* +** If the memory cell contains a value that must be freed by +** invoking the external callback in Mem.xDel, then this routine +** will free that value. It also sets Mem.flags to MEM_Null. +** +** This is a helper routine for sqlite3VdbeMemSetNull() and +** for sqlite3VdbeMemRelease(). Use those other routines as the +** entry point for releasing Mem resources. +*/ +static SQLITE_NOINLINE void vdbeMemClearExternAndSetNull(Mem *p){ + assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) ); + assert( VdbeMemDynamic(p) ); + if( p->flags&MEM_Agg ){ + sqlite3VdbeMemFinalize(p, p->u.pDef); + assert( (p->flags & MEM_Agg)==0 ); + testcase( p->flags & MEM_Dyn ); + } + if( p->flags&MEM_Dyn ){ + assert( p->xDel!=SQLITE_DYNAMIC && p->xDel!=0 ); + p->xDel((void *)p->z); + } + p->flags = MEM_Null; +} + +/* +** Release memory held by the Mem p, both external memory cleared +** by p->xDel and memory in p->zMalloc. +** +** This is a helper routine invoked by sqlite3VdbeMemRelease() in +** the unusual case where there really is memory in p that needs +** to be freed. +*/ +static SQLITE_NOINLINE void vdbeMemClear(Mem *p){ + if( VdbeMemDynamic(p) ){ + vdbeMemClearExternAndSetNull(p); + } + if( p->szMalloc ){ + sqlite3DbFreeNN(p->db, p->zMalloc); + p->szMalloc = 0; + } + p->z = 0; +} + +/* +** Release any memory resources held by the Mem. Both the memory that is +** free by Mem.xDel and the Mem.zMalloc allocation are freed. +** +** Use this routine prior to clean up prior to abandoning a Mem, or to +** reset a Mem back to its minimum memory utilization. +** +** Use sqlite3VdbeMemSetNull() to release just the Mem.xDel space +** prior to inserting new content into the Mem. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p){ + assert( sqlite3VdbeCheckMemInvariants(p) ); + if( VdbeMemDynamic(p) || p->szMalloc ){ + vdbeMemClear(p); + } +} + +/* Like sqlite3VdbeMemRelease() but faster for cases where we +** know in advance that the Mem is not MEM_Dyn or MEM_Agg. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemReleaseMalloc(Mem *p){ + assert( !VdbeMemDynamic(p) ); + if( p->szMalloc ) vdbeMemClear(p); +} + +/* +** Return some kind of integer value which is the best we can do +** at representing the value that *pMem describes as an integer. +** If pMem is an integer, then the value is exact. If pMem is +** a floating-point then the value returned is the integer part. +** If pMem is a string or blob, then we make an attempt to convert +** it into an integer and return that. If pMem represents an +** an SQL-NULL value, return 0. +** +** If pMem represents a string value, its encoding might be changed. +*/ +static SQLITE_NOINLINE i64 memIntValue(const Mem *pMem){ + i64 value = 0; + sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc); + return value; +} +SQLITE_PRIVATE i64 sqlite3VdbeIntValue(const Mem *pMem){ + int flags; + assert( pMem!=0 ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( EIGHT_BYTE_ALIGNMENT(pMem) ); + flags = pMem->flags; + if( flags & (MEM_Int|MEM_IntReal) ){ + testcase( flags & MEM_IntReal ); + return pMem->u.i; + }else if( flags & MEM_Real ){ + return sqlite3RealToI64(pMem->u.r); + }else if( (flags & (MEM_Str|MEM_Blob))!=0 && pMem->z!=0 ){ + return memIntValue(pMem); + }else{ + return 0; + } +} + +/* +** This routine implements the uncommon and slower path for +** sqlite3MemRealValueRC() that has to deal with input strings +** that are not UTF8 or that are not zero-terminated. It is +** broken out into a separate no-inline routine so that the +** main sqlite3MemRealValueRC() routine can avoid unnecessary +** stack pushes. +** +** A text->float translation of pMem->z is written into *pValue. +** +** Result code invariants: +** +** rc==0 => ERROR: Input string not well-formed, or OOM +** rc<0 => Some prefix of the input is well-formed +** rc>0 => All of the input is well-formed +** (rc&2)==0 => The number is expressed as an integer, with no +** decimal point or eNNN suffix. +*/ +static SQLITE_NOINLINE int sqlite3MemRealValueRCSlowPath( + Mem *pMem, + double *pValue +){ + int rc = SQLITE_OK; + *pValue = 0.0; + if( pMem->enc==SQLITE_UTF8 ){ + char *zCopy = sqlite3DbStrNDup(pMem->db, pMem->z, pMem->n); + if( zCopy ){ + rc = sqlite3AtoF(zCopy, pValue); + sqlite3DbFree(pMem->db, zCopy); + } + return rc; + }else{ + int n, i, j; + char *zCopy; + const char *z; + + n = pMem->n & ~1; + zCopy = sqlite3DbMallocRaw(pMem->db, n/2 + 2); + if( zCopy ){ + z = pMem->z; + if( pMem->enc==SQLITE_UTF16LE ){ + for(i=j=0; idb, zCopy); + } + return rc; + } +} + +/* +** Invoke sqlite3AtoF() on the text value of pMem. Write the +** translation of the text input into *pValue. +** +** The caller must ensure that pMem->db!=0 and that pMem is in +** mode MEM_Str or MEM_Blob. +** +** Result code invariants: +** +** rc==0 => ERROR: Input string not well-formed, or OOM +** rc<0 => Some prefix of the input is well-formed +** rc>0 => All of the input is well-formed +** (rc&2)==0 => The number is expressed as an integer, with no +** decimal point or eNNN suffix. +*/ +SQLITE_PRIVATE int sqlite3MemRealValueRC(Mem *pMem, double *pValue){ + testcase( pMem->db==0 ); + assert( pMem->flags & (MEM_Str|MEM_Blob) ); + if( pMem->z==0 ){ + *pValue = 0.0; + return 0; + }else if( pMem->enc==SQLITE_UTF8 + && ((pMem->flags & MEM_Term)!=0 || sqlite3VdbeMemZeroTerminateIfAble(pMem)) + ){ + return sqlite3AtoF(pMem->z, pValue); + }else if( pMem->n==0 ){ + *pValue = 0.0; + return 0; + }else{ + return sqlite3MemRealValueRCSlowPath(pMem, pValue); + } +} + +/* +** This routine acts as a bridge from sqlite3VdbeRealValue() to +** sqlite3VdbeRealValueRC, allowing sqlite3VdbeRealValue() to avoid +** stuffing values onto the stack. +*/ +static SQLITE_NOINLINE double sqlite3MemRealValueNoRC(Mem *pMem){ + double r; + (void)sqlite3MemRealValueRC(pMem, &r); + return r; +} + +/* +** Return the best representation of pMem that we can get into a +** double. If pMem is already a double or an integer, return its +** value. If it is a string or blob, try to convert it to a double. +** If it is a NULL, return 0.0. +*/ +SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){ + assert( pMem!=0 ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( EIGHT_BYTE_ALIGNMENT(pMem) ); + if( pMem->flags & MEM_Real ){ + return pMem->u.r; + }else if( pMem->flags & (MEM_Int|MEM_IntReal) ){ + testcase( pMem->flags & MEM_IntReal ); + return (double)pMem->u.i; + }else if( pMem->flags & (MEM_Str|MEM_Blob) ){ + return sqlite3MemRealValueNoRC(pMem); + }else{ + /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ + return (double)0; + } +} + +/* +** Return 1 if pMem represents true, and return 0 if pMem represents false. +** Return the value ifNull if pMem is NULL. +*/ +SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){ + testcase( pMem->flags & MEM_IntReal ); + if( pMem->flags & (MEM_Int|MEM_IntReal) ) return pMem->u.i!=0; + if( pMem->flags & MEM_Null ) return ifNull; + return sqlite3VdbeRealValue(pMem)!=0.0; +} + +/* +** The MEM structure is already a MEM_Real or MEM_IntReal. Try to +** make it a MEM_Int if we can. +*/ +SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){ + assert( pMem!=0 ); + assert( pMem->flags & (MEM_Real|MEM_IntReal) ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( EIGHT_BYTE_ALIGNMENT(pMem) ); + + if( pMem->flags & MEM_IntReal ){ + MemSetTypeFlag(pMem, MEM_Int); + }else{ + i64 ix = sqlite3RealToI64(pMem->u.r); + + /* Only mark the value as an integer if + ** + ** (1) the round-trip conversion real->int->real is a no-op, and + ** (2) The integer is neither the largest nor the smallest + ** possible integer (ticket #3922) + ** + ** The second and third terms in the following conditional enforces + ** the second condition under the assumption that addition overflow causes + ** values to wrap around. + */ + if( pMem->u.r==ix && ix>SMALLEST_INT64 && ixu.i = ix; + MemSetTypeFlag(pMem, MEM_Int); + } + } +} + +/* +** Convert pMem to type integer. Invalidate any prior representations. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem *pMem){ + assert( pMem!=0 ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); + assert( EIGHT_BYTE_ALIGNMENT(pMem) ); + + pMem->u.i = sqlite3VdbeIntValue(pMem); + MemSetTypeFlag(pMem, MEM_Int); + return SQLITE_OK; +} + +/* +** Convert pMem so that it is of type MEM_Real. +** Invalidate any prior representations. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem *pMem){ + assert( pMem!=0 ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( EIGHT_BYTE_ALIGNMENT(pMem) ); + + pMem->u.r = sqlite3VdbeRealValue(pMem); + MemSetTypeFlag(pMem, MEM_Real); + return SQLITE_OK; +} + +/* Compare a floating point value to an integer. Return true if the two +** values are the same within the precision of the floating point value. +** +** This function assumes that i was obtained by assignment from r1. +** +** For some versions of GCC on 32-bit machines, if you do the more obvious +** comparison of "r1==(double)i" you sometimes get an answer of false even +** though the r1 and (double)i values are bit-for-bit the same. +*/ +SQLITE_PRIVATE int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){ + double r2 = (double)i; + return r1==0.0 + || (memcmp(&r1, &r2, sizeof(r1))==0 + && i >= -2251799813685248LL && i < 2251799813685248LL); +} + +/* Convert a floating point value to its closest integer. Do so in +** a way that avoids 'outside the range of representable values' warnings +** from UBSAN. +*/ +SQLITE_PRIVATE i64 sqlite3RealToI64(double r){ + if( r<-9223372036854774784.0 ) return SMALLEST_INT64; + if( r>+9223372036854774784.0 ) return LARGEST_INT64; + return (i64)r; +} + +/* +** Convert pMem so that it has type MEM_Real or MEM_Int. +** Invalidate any prior representations. +** +** Every effort is made to force the conversion, even if the input +** is a string that does not look completely like a number. Convert +** as much of the string as we can and ignore the rest. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){ + assert( pMem!=0 ); + testcase( pMem->flags & MEM_Int ); + testcase( pMem->flags & MEM_Real ); + testcase( pMem->flags & MEM_IntReal ); + testcase( pMem->flags & MEM_Null ); + if( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))==0 ){ + int rc; + sqlite3_int64 ix; + assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + rc = sqlite3MemRealValueRC(pMem, &pMem->u.r); + if( ((rc&2)==0 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<2) + || sqlite3RealSameAsInt(pMem->u.r, (ix = sqlite3RealToI64(pMem->u.r))) + ){ + pMem->u.i = ix; + MemSetTypeFlag(pMem, MEM_Int); + }else{ + MemSetTypeFlag(pMem, MEM_Real); + } + } + assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))!=0 ); + pMem->flags &= ~(MEM_Str|MEM_Blob|MEM_Zero); + return SQLITE_OK; +} + +/* +** Cast the datatype of the value in pMem according to the affinity +** "aff". Casting is different from applying affinity in that a cast +** is forced. In other words, the value is converted into the desired +** affinity even if that results in loss of data. This routine is +** used (for example) to implement the SQL "cast()" operator. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){ + if( pMem->flags & MEM_Null ) return SQLITE_OK; + switch( aff ){ + case SQLITE_AFF_BLOB: { /* Really a cast to BLOB */ + if( (pMem->flags & MEM_Blob)==0 ){ + sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding); + assert( pMem->flags & MEM_Str || pMem->db->mallocFailed ); + if( pMem->flags & MEM_Str ) MemSetTypeFlag(pMem, MEM_Blob); + }else{ + pMem->flags &= ~(MEM_TypeMask&~MEM_Blob); + } + break; + } + case SQLITE_AFF_NUMERIC: { + sqlite3VdbeMemNumerify(pMem); + break; + } + case SQLITE_AFF_INTEGER: { + sqlite3VdbeMemIntegerify(pMem); + break; + } + case SQLITE_AFF_REAL: { + sqlite3VdbeMemRealify(pMem); + break; + } + default: { + int rc; + assert( aff==SQLITE_AFF_TEXT ); + assert( MEM_Str==(MEM_Blob>>3) ); + pMem->flags |= (pMem->flags&MEM_Blob)>>3; + sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding); + assert( pMem->flags & MEM_Str || pMem->db->mallocFailed ); + pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal|MEM_Blob|MEM_Zero); + if( encoding!=SQLITE_UTF8 ) pMem->n &= ~1; + rc = sqlite3VdbeChangeEncoding(pMem, encoding); + if( rc ) return rc; + sqlite3VdbeMemZeroTerminateIfAble(pMem); + } + } + return SQLITE_OK; +} + +/* +** Initialize bulk memory to be a consistent Mem object. +** +** The minimum amount of initialization feasible is performed. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem *pMem, sqlite3 *db, u16 flags){ + assert( (flags & ~MEM_TypeMask)==0 ); + pMem->flags = flags; + pMem->db = db; + pMem->szMalloc = 0; +} + + +/* +** Delete any previous value and set the value stored in *pMem to NULL. +** +** This routine calls the Mem.xDel destructor to dispose of values that +** require the destructor. But it preserves the Mem.zMalloc memory allocation. +** To free all resources, use sqlite3VdbeMemRelease(), which both calls this +** routine to invoke the destructor and deallocates Mem.zMalloc. +** +** Use this routine to reset the Mem prior to insert a new value. +** +** Use sqlite3VdbeMemRelease() to complete erase the Mem prior to abandoning it. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem *pMem){ + if( VdbeMemDynamic(pMem) ){ + vdbeMemClearExternAndSetNull(pMem); + }else{ + pMem->flags = MEM_Null; + } +} +SQLITE_PRIVATE void sqlite3ValueSetNull(sqlite3_value *p){ + sqlite3VdbeMemSetNull((Mem*)p); +} + +/* +** Delete any previous value and set the value to be a BLOB of length +** n containing all zeros. +*/ +#ifndef SQLITE_OMIT_INCRBLOB +SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){ + sqlite3VdbeMemRelease(pMem); + pMem->flags = MEM_Blob|MEM_Zero; + pMem->n = 0; + if( n<0 ) n = 0; + pMem->u.nZero = n; + pMem->enc = SQLITE_UTF8; + pMem->z = 0; +} +#else +SQLITE_PRIVATE int sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){ + int nByte = n>0?n:1; + if( sqlite3VdbeMemGrow(pMem, nByte, 0) ){ + return SQLITE_NOMEM_BKPT; + } + assert( pMem->z!=0 ); + assert( sqlite3DbMallocSize(pMem->db, pMem->z)>=nByte ); + memset(pMem->z, 0, nByte); + pMem->n = n>0?n:0; + pMem->flags = MEM_Blob; + pMem->enc = SQLITE_UTF8; + return SQLITE_OK; +} +#endif + +/* +** The pMem is known to contain content that needs to be destroyed prior +** to a value change. So invoke the destructor, then set the value to +** a 64-bit integer. +*/ +static SQLITE_NOINLINE void vdbeReleaseAndSetInt64(Mem *pMem, i64 val){ + sqlite3VdbeMemSetNull(pMem); + pMem->u.i = val; + pMem->flags = MEM_Int; +} + +/* +** Delete any previous value and set the value stored in *pMem to val, +** manifest type INTEGER. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){ + if( VdbeMemDynamic(pMem) ){ + vdbeReleaseAndSetInt64(pMem, val); + }else{ + pMem->u.i = val; + pMem->flags = MEM_Int; + } +} + +/* +** Set the iIdx'th entry of array aMem[] to contain integer value val. +*/ +SQLITE_PRIVATE void sqlite3MemSetArrayInt64(sqlite3_value *aMem, int iIdx, i64 val){ + sqlite3VdbeMemSetInt64(&aMem[iIdx], val); +} + +/* A no-op destructor */ +SQLITE_PRIVATE void sqlite3NoopDestructor(void *p){ UNUSED_PARAMETER(p); } + +/* +** Set the value stored in *pMem should already be a NULL. +** Also store a pointer to go with it. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemSetPointer( + Mem *pMem, + void *pPtr, + const char *zPType, + void (*xDestructor)(void*) +){ + assert( pMem->flags==MEM_Null ); + vdbeMemClear(pMem); + pMem->u.zPType = zPType ? zPType : ""; + pMem->z = pPtr; + pMem->flags = MEM_Null|MEM_Dyn|MEM_Subtype|MEM_Term; + pMem->eSubtype = 'p'; + pMem->xDel = xDestructor ? xDestructor : sqlite3NoopDestructor; +} + +#ifndef SQLITE_OMIT_FLOATING_POINT +/* +** Delete any previous value and set the value stored in *pMem to val, +** manifest type REAL. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem *pMem, double val){ + sqlite3VdbeMemSetNull(pMem); + if( !sqlite3IsNaN(val) ){ + pMem->u.r = val; + pMem->flags = MEM_Real; + } +} +#endif + +#ifdef SQLITE_DEBUG +/* +** Return true if the Mem holds a RowSet object. This routine is intended +** for use inside of assert() statements. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem *pMem){ + return (pMem->flags&(MEM_Blob|MEM_Dyn))==(MEM_Blob|MEM_Dyn) + && pMem->xDel==sqlite3RowSetDelete; +} +#endif + +/* +** Delete any previous value and set the value of pMem to be an +** empty boolean index. +** +** Return SQLITE_OK on success and SQLITE_NOMEM if a memory allocation +** error occurs. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem *pMem){ + sqlite3 *db = pMem->db; + RowSet *p; + assert( db!=0 ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); + sqlite3VdbeMemRelease(pMem); + p = sqlite3RowSetInit(db); + if( p==0 ) return SQLITE_NOMEM; + pMem->z = (char*)p; + pMem->flags = MEM_Blob|MEM_Dyn; + pMem->xDel = sqlite3RowSetDelete; + return SQLITE_OK; +} + +/* +** Return true if the Mem object contains a TEXT or BLOB that is +** too large - whose size exceeds SQLITE_MAX_LENGTH. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem *p){ + assert( p->db!=0 ); + if( p->flags & (MEM_Str|MEM_Blob) ){ + int n = p->n; + if( p->flags & MEM_Zero ){ + n += p->u.nZero; + } + return n>p->db->aLimit[SQLITE_LIMIT_LENGTH]; + } + return 0; +} + +#ifdef SQLITE_DEBUG +/* +** This routine prepares a memory cell for modification by breaking +** its link to a shallow copy and by marking any current shallow +** copies of this cell as invalid. +** +** This is used for testing and debugging only - to help ensure that shallow +** copies (created by OP_SCopy) are not misused. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ + int i; + Mem *pX; + if( pMem->bScopy ){ + for(i=1, pX=pVdbe->aMem+1; inMem; i++, pX++){ + if( pX->pScopyFrom==pMem ){ + u16 mFlags; + if( pVdbe->db->flags & SQLITE_VdbeTrace ){ + sqlite3DebugPrintf("Invalidate R[%d] due to change in R[%d]\n", + (int)(pX - pVdbe->aMem), (int)(pMem - pVdbe->aMem)); + } + /* If pX is marked as a shallow copy of pMem, then try to verify that + ** no significant changes have been made to pX since the OP_SCopy. + ** A significant change would indicated a missed call to this + ** function for pX. Minor changes, such as adding or removing a + ** dual type, are allowed, as long as the underlying value is the + ** same. */ + mFlags = pMem->flags & pX->flags & pX->mScopyFlags; + assert( (mFlags&(MEM_Int|MEM_IntReal))==0 || pMem->u.i==pX->u.i ); + + /* pMem is the register that is changing. But also mark pX as + ** undefined so that we can quickly detect the shallow-copy error */ + pX->flags = MEM_Undefined; + pX->pScopyFrom = 0; + } + } + pMem->bScopy = 0; + } + pMem->pScopyFrom = 0; +} +#endif /* SQLITE_DEBUG */ + +/* +** Make an shallow copy of pFrom into pTo. Prior contents of +** pTo are freed. The pFrom->z field is not duplicated. If +** pFrom->z is used, then pTo->z points to the same thing as pFrom->z +** and flags gets srcType (either MEM_Ephem or MEM_Static). +*/ +static SQLITE_NOINLINE void vdbeClrCopy(Mem *pTo, const Mem *pFrom, int eType){ + vdbeMemClearExternAndSetNull(pTo); + assert( !VdbeMemDynamic(pTo) ); + sqlite3VdbeMemShallowCopy(pTo, pFrom, eType); +} +SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){ + assert( !sqlite3VdbeMemIsRowSet(pFrom) ); + assert( pTo->db==pFrom->db ); + if( VdbeMemDynamic(pTo) ){ vdbeClrCopy(pTo,pFrom,srcType); return; } + memcpy(pTo, pFrom, MEMCELLSIZE); + if( (pFrom->flags&MEM_Static)==0 ){ + pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem); + assert( srcType==MEM_Ephem || srcType==MEM_Static ); + pTo->flags |= srcType; + } +} + +/* +** Make a full copy of pFrom into pTo. Prior contents of pTo are +** freed before the copy is made. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){ + int rc = SQLITE_OK; + + assert( !sqlite3VdbeMemIsRowSet(pFrom) ); + if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo); + memcpy(pTo, pFrom, MEMCELLSIZE); + pTo->flags &= ~MEM_Dyn; + if( pTo->flags&(MEM_Str|MEM_Blob) ){ + if( 0==(pFrom->flags&MEM_Static) ){ + pTo->flags |= MEM_Ephem; + rc = sqlite3VdbeMemMakeWriteable(pTo); + } + } + + return rc; +} + +/* +** Transfer the contents of pFrom to pTo. Any existing value in pTo is +** freed. If pFrom contains ephemeral data, a copy is made. +** +** pFrom contains an SQL NULL when this routine returns. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){ + assert( pFrom->db==0 || sqlite3_mutex_held(pFrom->db->mutex) ); + assert( pTo->db==0 || sqlite3_mutex_held(pTo->db->mutex) ); + assert( pFrom->db==0 || pTo->db==0 || pFrom->db==pTo->db ); + + sqlite3VdbeMemRelease(pTo); + memcpy(pTo, pFrom, sizeof(Mem)); + pFrom->flags = MEM_Null; + pFrom->szMalloc = 0; +} + +/* +** Change the value of a Mem to be a string or a BLOB. +** +** The memory management strategy depends on the value of the xDel +** parameter. If the value passed is SQLITE_TRANSIENT, then the +** string is copied into a (possibly existing) buffer managed by the +** Mem structure. Otherwise, any existing buffer is freed and the +** pointer copied. +** +** If the string is too large (if it exceeds the SQLITE_LIMIT_LENGTH +** size limit) then no memory allocation occurs. If the string can be +** stored without allocating memory, then it is. If a memory allocation +** is required to store the string, then value of pMem is unchanged. In +** either case, SQLITE_TOOBIG is returned. +** +** The "enc" parameter is the text encoding for the string, or zero +** to store a blob. +** +** If n is negative, then the string consists of all bytes up to but +** excluding the first zero character. The n parameter must be +** non-negative for blobs. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemSetStr( + Mem *pMem, /* Memory cell to set to string value */ + const char *z, /* String pointer */ + i64 n, /* Bytes in string, or negative */ + u8 enc, /* Encoding of z. 0 for BLOBs */ + void (*xDel)(void*) /* Destructor function */ +){ + i64 nByte = n; /* New value for pMem->n */ + int iLimit; /* Maximum allowed string or blob size */ + u16 flags; /* New value for pMem->flags */ + + assert( pMem!=0 ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); + assert( enc!=0 || n>=0 ); + + /* If z is a NULL pointer, set pMem to contain an SQL NULL. */ + if( !z ){ + sqlite3VdbeMemSetNull(pMem); + return SQLITE_OK; + } + + if( pMem->db ){ + iLimit = pMem->db->aLimit[SQLITE_LIMIT_LENGTH]; + }else{ + iLimit = SQLITE_MAX_LENGTH; + } + if( nByte<0 ){ + assert( enc!=0 ); + if( enc==SQLITE_UTF8 ){ + nByte = strlen(z); + }else{ + for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){} + } + flags= MEM_Str|MEM_Term; + }else if( enc==0 ){ + flags = MEM_Blob; + enc = SQLITE_UTF8; + }else{ + flags = MEM_Str; + } + if( nByte>iLimit ){ + if( xDel && xDel!=SQLITE_TRANSIENT ){ + if( xDel==SQLITE_DYNAMIC ){ + sqlite3DbFree(pMem->db, (void*)z); + }else{ + xDel((void*)z); + } + } + sqlite3VdbeMemSetNull(pMem); + return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG); + } + + /* The following block sets the new values of Mem.z and Mem.xDel. It + ** also sets a flag in local variable "flags" to indicate the memory + ** management (one of MEM_Dyn or MEM_Static). + */ + if( xDel==SQLITE_TRANSIENT ){ + i64 nAlloc = nByte; + if( flags&MEM_Term ){ + nAlloc += (enc==SQLITE_UTF8?1:2); + } + testcase( nAlloc==0 ); + testcase( nAlloc==31 ); + testcase( nAlloc==32 ); + if( sqlite3VdbeMemClearAndResize(pMem, (int)MAX(nAlloc,32)) ){ + return SQLITE_NOMEM_BKPT; + } + assert( pMem->z!=0 ); + memcpy(pMem->z, z, nAlloc); + }else{ + sqlite3VdbeMemRelease(pMem); + pMem->z = (char *)z; + if( xDel==SQLITE_DYNAMIC ){ + pMem->zMalloc = pMem->z; + pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc); + }else{ + pMem->xDel = xDel; + flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn); + } + } + + pMem->n = (int)(nByte & 0x7fffffff); + pMem->flags = flags; + pMem->enc = enc; + +#ifndef SQLITE_OMIT_UTF16 + if( enc>SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){ + return SQLITE_NOMEM_BKPT; + } +#endif + + + return SQLITE_OK; +} + +/* Like sqlite3VdbeMemSetStr() except: +** +** enc is always SQLITE_UTF8 +** pMem->db is always non-NULL +*/ +SQLITE_PRIVATE int sqlite3VdbeMemSetText( + Mem *pMem, /* Memory cell to set to string value */ + const char *z, /* String pointer */ + i64 n, /* Bytes in string, or negative */ + void (*xDel)(void*) /* Destructor function */ +){ + i64 nByte = n; /* New value for pMem->n */ + u16 flags; + + assert( pMem!=0 ); + assert( pMem->db!=0 ); + assert( sqlite3_mutex_held(pMem->db->mutex) ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); + + /* If z is a NULL pointer, set pMem to contain an SQL NULL. */ + if( !z ){ + sqlite3VdbeMemSetNull(pMem); + return SQLITE_OK; + } + + if( nByte<0 ){ + nByte = strlen(z); + flags = MEM_Str|MEM_Term; + }else{ + flags = MEM_Str; + } + if( nByte>(i64)pMem->db->aLimit[SQLITE_LIMIT_LENGTH] ){ + if( xDel && xDel!=SQLITE_TRANSIENT ){ + if( xDel==SQLITE_DYNAMIC ){ + sqlite3DbFree(pMem->db, (void*)z); + }else{ + xDel((void*)z); + } + } + sqlite3VdbeMemSetNull(pMem); + return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG); + } + + /* The following block sets the new values of Mem.z and Mem.xDel. It + ** also sets a flag in local variable "flags" to indicate the memory + ** management (one of MEM_Dyn or MEM_Static). + */ + if( xDel==SQLITE_TRANSIENT ){ + i64 nAlloc = nByte + 1; + testcase( nAlloc==31 ); + testcase( nAlloc==32 ); + if( sqlite3VdbeMemClearAndResize(pMem, (int)MAX(nAlloc,32)) ){ + return SQLITE_NOMEM_BKPT; + } + assert( pMem->z!=0 ); + memcpy(pMem->z, z, nByte); + pMem->z[nByte] = 0; + }else{ + sqlite3VdbeMemRelease(pMem); + pMem->z = (char *)z; + if( xDel==SQLITE_DYNAMIC ){ + pMem->zMalloc = pMem->z; + pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc); + pMem->xDel = 0; + }else if( xDel==SQLITE_STATIC ){ + pMem->xDel = xDel; + flags |= MEM_Static; + }else{ + pMem->xDel = xDel; + flags |= MEM_Dyn; + } + } + pMem->flags = flags; + pMem->n = (int)(nByte & 0x7fffffff); + pMem->enc = SQLITE_UTF8; + return SQLITE_OK; +} + +/* +** Move data out of a btree key or data field and into a Mem structure. +** The data is payload from the entry that pCur is currently pointing +** to. offset and amt determine what portion of the data or key to retrieve. +** The result is written into the pMem element. +** +** The pMem object must have been initialized. This routine will use +** pMem->zMalloc to hold the content from the btree, if possible. New +** pMem->zMalloc space will be allocated if necessary. The calling routine +** is responsible for making sure that the pMem object is eventually +** destroyed. +** +** If this routine fails for any reason (malloc returns NULL or unable +** to read from the disk) then the pMem is left in an inconsistent state. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemFromBtree( + BtCursor *pCur, /* Cursor pointing at record to retrieve. */ + u32 offset, /* Offset from the start of data to return bytes from. */ + u32 amt, /* Number of bytes to return. */ + Mem *pMem /* OUT: Return data in this Mem structure. */ +){ + int rc; + pMem->flags = MEM_Null; + testcase( amt==SQLITE_MAX_ALLOCATION_SIZE-1 ); + testcase( amt==SQLITE_MAX_ALLOCATION_SIZE ); + if( amt>=SQLITE_MAX_ALLOCATION_SIZE ){ + return SQLITE_NOMEM_BKPT; + } + if( (u64)amt + (u64)offset > (u64)sqlite3BtreeMaxRecordSize(pCur) ){ + return SQLITE_CORRUPT_BKPT; + } + if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+1)) ){ + rc = sqlite3BtreePayload(pCur, offset, amt, pMem->z); + if( rc==SQLITE_OK ){ + pMem->z[amt] = 0; /* Overrun area used when reading malformed records */ + pMem->flags = MEM_Blob; + pMem->n = (int)amt; + }else{ + sqlite3VdbeMemRelease(pMem); + } + } + return rc; +} +SQLITE_PRIVATE int sqlite3VdbeMemFromBtreeZeroOffset( + BtCursor *pCur, /* Cursor pointing at record to retrieve. */ + u32 amt, /* Number of bytes to return. */ + Mem *pMem /* OUT: Return data in this Mem structure. */ +){ + u32 available = 0; /* Number of bytes available on the local btree page */ + int rc = SQLITE_OK; /* Return code */ + + assert( sqlite3BtreeCursorIsValid(pCur) ); + assert( !VdbeMemDynamic(pMem) ); + + /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert() + ** that both the BtShared and database handle mutexes are held. */ + assert( !sqlite3VdbeMemIsRowSet(pMem) ); + pMem->z = (char *)sqlite3BtreePayloadFetch(pCur, &available); + assert( pMem->z!=0 ); + + if( amt<=available ){ + pMem->flags = MEM_Blob|MEM_Ephem; + pMem->n = (int)amt; + }else{ + rc = sqlite3VdbeMemFromBtree(pCur, 0, amt, pMem); + } + + return rc; +} + +/* +** The pVal argument is known to be a value other than NULL. +** Convert it into a string with encoding enc and return a pointer +** to a zero-terminated version of that string. +*/ +static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){ + assert( pVal!=0 ); + assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) ); + assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); + assert( !sqlite3VdbeMemIsRowSet(pVal) ); + assert( (pVal->flags & (MEM_Null))==0 ); + if( pVal->flags & (MEM_Blob|MEM_Str) ){ + if( ExpandBlob(pVal) ) return 0; + pVal->flags |= MEM_Str; + if( pVal->enc != (enc & ~SQLITE_UTF16_ALIGNED) ){ + sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED); + } + if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&SQLITE_PTR_TO_INT(pVal->z)) ){ + assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 ); + if( sqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){ + return 0; + } + } + sqlite3VdbeMemNulTerminate(pVal); /* IMP: R-31275-44060 */ + }else{ + sqlite3VdbeMemStringify(pVal, enc, 0); + assert( 0==(1&SQLITE_PTR_TO_INT(pVal->z)) ); + } + assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0 + || pVal->db->mallocFailed ); + if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){ + assert( sqlite3VdbeMemValidStrRep(pVal) ); + return pVal->z; + }else{ + return 0; + } +} + +/* This function is only available internally, it is not part of the +** external API. It works in a similar way to sqlite3_value_text(), +** except the data returned is in the encoding specified by the second +** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or +** SQLITE_UTF8. +** +** (2006-02-16:) The enc value can be or-ed with SQLITE_UTF16_ALIGNED. +** If that is the case, then the result must be aligned on an even byte +** boundary. +*/ +SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){ + if( !pVal ) return 0; + assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) ); + assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); + assert( !sqlite3VdbeMemIsRowSet(pVal) ); + if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){ + assert( sqlite3VdbeMemValidStrRep(pVal) ); + return pVal->z; + } + if( pVal->flags&MEM_Null ){ + return 0; + } + return valueToText(pVal, enc); +} + +/* Return true if sqlit3_value object pVal is a string or blob value +** that uses the destructor specified in the second argument. +** +** TODO: Maybe someday promote this interface into a published API so +** that third-party extensions can get access to it? +*/ +SQLITE_PRIVATE int sqlite3ValueIsOfClass(const sqlite3_value *pVal, void(*xFree)(void*)){ + if( ALWAYS(pVal!=0) + && ALWAYS((pVal->flags & (MEM_Str|MEM_Blob))!=0) + && (pVal->flags & MEM_Dyn)!=0 + && pVal->xDel==xFree + ){ + return 1; + }else{ + return 0; + } +} + +/* +** Create a new sqlite3_value object. +*/ +SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *db){ + Mem *p = sqlite3DbMallocZero(db, sizeof(*p)); + if( p ){ + p->flags = MEM_Null; + p->db = db; + } + return p; +} + +/* +** Context object passed by sqlite3Stat4ProbeSetValue() through to +** valueNew(). See comments above valueNew() for details. +*/ +struct ValueNewStat4Ctx { + Parse *pParse; + Index *pIdx; + UnpackedRecord **ppRec; + int iVal; +}; + +/* +** Allocate and return a pointer to a new sqlite3_value object. If +** the second argument to this function is NULL, the object is allocated +** by calling sqlite3ValueNew(). +** +** Otherwise, if the second argument is non-zero, then this function is +** being called indirectly by sqlite3Stat4ProbeSetValue(). If it has not +** already been allocated, allocate the UnpackedRecord structure that +** that function will return to its caller here. Then return a pointer to +** an sqlite3_value within the UnpackedRecord.a[] array. +*/ +static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){ +#ifdef SQLITE_ENABLE_STAT4 + if( p ){ + UnpackedRecord *pRec = p->ppRec[0]; + + if( pRec==0 ){ + Index *pIdx = p->pIdx; /* Index being probed */ + i64 nByte; /* Bytes of space to allocate */ + int i; /* Counter variable */ + int nCol = pIdx->nColumn; /* Number of index columns including rowid */ + + nByte = sizeof(Mem) * nCol + ROUND8(sizeof(UnpackedRecord)); + pRec = (UnpackedRecord*)sqlite3DbMallocZero(db, nByte); + if( pRec ){ + pRec->pKeyInfo = sqlite3KeyInfoOfIndex(p->pParse, pIdx); + if( pRec->pKeyInfo ){ + assert( pRec->pKeyInfo->nAllField==nCol ); + assert( pRec->pKeyInfo->enc==ENC(db) ); + pRec->aMem = (Mem *)((u8*)pRec + ROUND8(sizeof(UnpackedRecord))); + for(i=0; iaMem[i].flags = MEM_Null; + pRec->aMem[i].db = db; + } + }else{ + sqlite3DbFreeNN(db, pRec); + pRec = 0; + } + } + if( pRec==0 ) return 0; + p->ppRec[0] = pRec; + } + + pRec->nField = p->iVal+1; + sqlite3VdbeMemSetNull(&pRec->aMem[p->iVal]); + return &pRec->aMem[p->iVal]; + } +#else + UNUSED_PARAMETER(p); +#endif /* defined(SQLITE_ENABLE_STAT4) */ + return sqlite3ValueNew(db); +} + +/* +** The expression object indicated by the second argument is guaranteed +** to be a scalar SQL function. If +** +** * all function arguments are SQL literals, +** * one of the SQLITE_FUNC_CONSTANT or _SLOCHNG function flags is set, and +** * the SQLITE_FUNC_NEEDCOLL function flag is not set, +** +** then this routine attempts to invoke the SQL function. Assuming no +** error occurs, output parameter (*ppVal) is set to point to a value +** object containing the result before returning SQLITE_OK. +** +** Affinity aff is applied to the result of the function before returning. +** If the result is a text value, the sqlite3_value object uses encoding +** enc. +** +** If the conditions above are not met, this function returns SQLITE_OK +** and sets (*ppVal) to NULL. Or, if an error occurs, (*ppVal) is set to +** NULL and an SQLite error code returned. +*/ +#ifdef SQLITE_ENABLE_STAT4 +static int valueFromFunction( + sqlite3 *db, /* The database connection */ + const Expr *p, /* The expression to evaluate */ + u8 enc, /* Encoding to use */ + u8 aff, /* Affinity to use */ + sqlite3_value **ppVal, /* Write the new value here */ + struct ValueNewStat4Ctx *pCtx /* Second argument for valueNew() */ +){ + sqlite3_context ctx; /* Context object for function invocation */ + sqlite3_value **apVal = 0; /* Function arguments */ + int nVal = 0; /* Number of function arguments */ + FuncDef *pFunc = 0; /* Function definition */ + sqlite3_value *pVal = 0; /* New value */ + int rc = SQLITE_OK; /* Return code */ + ExprList *pList = 0; /* Function arguments */ + int i; /* Iterator variable */ + + assert( pCtx!=0 ); + assert( (p->flags & EP_TokenOnly)==0 ); + assert( ExprUseXList(p) ); + pList = p->x.pList; + if( pList ) nVal = pList->nExpr; + assert( !ExprHasProperty(p, EP_IntValue) ); + pFunc = sqlite3FindFunction(db, p->u.zToken, nVal, enc, 0); +#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION + if( pFunc==0 ) return SQLITE_OK; +#endif + assert( pFunc ); + if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0 + || (pFunc->funcFlags & (SQLITE_FUNC_NEEDCOLL|SQLITE_FUNC_RUNONLY))!=0 + ){ + return SQLITE_OK; + } + + if( pList ){ + apVal = (sqlite3_value**)sqlite3DbMallocZero(db, sizeof(apVal[0]) * nVal); + if( apVal==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto value_from_function_out; + } + for(i=0; ipParse, pList->a[i].pExpr, aff, + &apVal[i]); + if( apVal[i]==0 || rc!=SQLITE_OK ) goto value_from_function_out; + } + } + + pVal = valueNew(db, pCtx); + if( pVal==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto value_from_function_out; + } + + memset(&ctx, 0, sizeof(ctx)); + ctx.pOut = pVal; + ctx.pFunc = pFunc; + ctx.enc = ENC(db); + pFunc->xSFunc(&ctx, nVal, apVal); + if( ctx.isError ){ + rc = ctx.isError; + sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal)); + }else{ + sqlite3ValueApplyAffinity(pVal, aff, SQLITE_UTF8); + assert( rc==SQLITE_OK ); + rc = sqlite3VdbeChangeEncoding(pVal, enc); + if( NEVER(rc==SQLITE_OK && sqlite3VdbeMemTooBig(pVal)) ){ + rc = SQLITE_TOOBIG; + pCtx->pParse->nErr++; + } + } + + value_from_function_out: + if( rc!=SQLITE_OK ){ + pVal = 0; + pCtx->pParse->rc = rc; + } + if( apVal ){ + for(i=0; iop)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft; + if( op==TK_REGISTER ) op = pExpr->op2; + + /* Compressed expressions only appear when parsing the DEFAULT clause + ** on a table column definition, and hence only when pCtx==0. This + ** check ensures that an EP_TokenOnly expression is never passed down + ** into valueFromFunction(). */ + assert( (pExpr->flags & EP_TokenOnly)==0 || pCtx==0 ); + + if( op==TK_CAST ){ + u8 aff; + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + aff = sqlite3AffinityType(pExpr->u.zToken,0); + rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx); + testcase( rc!=SQLITE_OK ); + if( *ppVal ){ +#ifdef SQLITE_ENABLE_STAT4 + rc = ExpandBlob(*ppVal); +#else + /* zero-blobs only come from functions, not literal values. And + ** functions are only processed under STAT4 */ + assert( (ppVal[0][0].flags & MEM_Zero)==0 ); +#endif + sqlite3VdbeMemCast(*ppVal, aff, enc); + sqlite3ValueApplyAffinity(*ppVal, affinity, enc); + } + return rc; + } + + /* Handle negative integers in a single step. This is needed in the + ** case when the value is -9223372036854775808. Except - do not do this + ** for hexadecimal literals. */ + if( op==TK_UMINUS ){ + Expr *pLeft = pExpr->pLeft; + if( (pLeft->op==TK_INTEGER || pLeft->op==TK_FLOAT) ){ + if( ExprHasProperty(pLeft, EP_IntValue) + || pLeft->u.zToken[0]!='0' || (pLeft->u.zToken[1] & ~0x20)!='X' + ){ + pExpr = pLeft; + op = pExpr->op; + negInt = -1; + zNeg = "-"; + } + } + } + + if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){ + pVal = valueNew(db, pCtx); + if( pVal==0 ) goto no_mem; + if( ExprHasProperty(pExpr, EP_IntValue) ){ + sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt); + }else{ + i64 iVal; + if( op==TK_INTEGER && 0==sqlite3DecOrHexToI64(pExpr->u.zToken, &iVal) ){ + sqlite3VdbeMemSetInt64(pVal, iVal*negInt); + }else{ + zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken); + if( zVal==0 ) goto no_mem; + sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC); + } + } + if( affinity==SQLITE_AFF_BLOB ){ + if( op==TK_FLOAT ){ + assert( pVal && pVal->z && pVal->flags==(MEM_Str|MEM_Term) ); + sqlite3AtoF(pVal->z, &pVal->u.r); + pVal->flags = MEM_Real; + }else if( op==TK_INTEGER ){ + /* This case is required by -9223372036854775808 and other strings + ** that look like integers but cannot be handled by the + ** sqlite3DecOrHexToI64() call above. */ + sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8); + } + }else{ + sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); + } + assert( (pVal->flags & MEM_IntReal)==0 ); + if( pVal->flags & (MEM_Int|MEM_IntReal|MEM_Real) ){ + testcase( pVal->flags & MEM_Int ); + testcase( pVal->flags & MEM_Real ); + pVal->flags &= ~MEM_Str; + } + if( enc!=SQLITE_UTF8 ){ + rc = sqlite3VdbeChangeEncoding(pVal, enc); + } + }else if( op==TK_UMINUS ) { + /* This branch happens for multiple negative signs. Ex: -(-5) */ + if( SQLITE_OK==valueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal,pCtx) + && pVal!=0 + ){ + sqlite3VdbeMemNumerify(pVal); + if( pVal->flags & MEM_Real ){ + pVal->u.r = -pVal->u.r; + }else if( pVal->u.i==SMALLEST_INT64 ){ +#ifndef SQLITE_OMIT_FLOATING_POINT + pVal->u.r = -(double)SMALLEST_INT64; +#else + pVal->u.r = LARGEST_INT64; +#endif + MemSetTypeFlag(pVal, MEM_Real); + }else{ + pVal->u.i = -pVal->u.i; + } + sqlite3ValueApplyAffinity(pVal, affinity, enc); + } + }else if( op==TK_NULL ){ + pVal = valueNew(db, pCtx); + if( pVal==0 ) goto no_mem; + sqlite3VdbeMemSetNull(pVal); + } +#ifndef SQLITE_OMIT_BLOB_LITERAL + else if( op==TK_BLOB ){ + int nVal; + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' ); + assert( pExpr->u.zToken[1]=='\'' ); + pVal = valueNew(db, pCtx); + if( !pVal ) goto no_mem; + zVal = &pExpr->u.zToken[2]; + nVal = sqlite3Strlen30(zVal)-1; + assert( zVal[nVal]=='\'' ); + sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2, + 0, SQLITE_DYNAMIC); + } +#endif +#ifdef SQLITE_ENABLE_STAT4 + else if( op==TK_FUNCTION && pCtx!=0 ){ + rc = valueFromFunction(db, pExpr, enc, affinity, &pVal, pCtx); + } +#endif + else if( op==TK_TRUEFALSE ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + pVal = valueNew(db, pCtx); + if( pVal ){ + pVal->flags = MEM_Int; + pVal->u.i = pExpr->u.zToken[4]==0; + sqlite3ValueApplyAffinity(pVal, affinity, enc); + } + } + + *ppVal = pVal; + return rc; + +no_mem: +#ifdef SQLITE_ENABLE_STAT4 + if( pCtx==0 || NEVER(pCtx->pParse->nErr==0) ) +#endif + sqlite3OomFault(db); + sqlite3DbFree(db, zVal); + assert( *ppVal==0 ); +#ifdef SQLITE_ENABLE_STAT4 + if( pCtx==0 ) sqlite3ValueFree(pVal); +#else + assert( pCtx==0 ); sqlite3ValueFree(pVal); +#endif + return SQLITE_NOMEM_BKPT; +} + +/* +** Create a new sqlite3_value object, containing the value of pExpr. +** +** This only works for very simple expressions that consist of one constant +** token (i.e. "5", "5.1", "'a string'"). If the expression can +** be converted directly into a value, then the value is allocated and +** a pointer written to *ppVal. The caller is responsible for deallocating +** the value by passing it to sqlite3ValueFree() later on. If the expression +** cannot be converted to a value, then *ppVal is set to NULL. +*/ +SQLITE_PRIVATE int sqlite3ValueFromExpr( + sqlite3 *db, /* The database connection */ + const Expr *pExpr, /* The expression to evaluate */ + u8 enc, /* Encoding to use */ + u8 affinity, /* Affinity to use */ + sqlite3_value **ppVal /* Write the new value here */ +){ + return pExpr ? valueFromExpr(db, pExpr, enc, affinity, ppVal, 0) : 0; +} + +#ifdef SQLITE_ENABLE_STAT4 +/* +** Attempt to extract a value from pExpr and use it to construct *ppVal. +** +** If pAlloc is not NULL, then an UnpackedRecord object is created for +** pAlloc if one does not exist and the new value is added to the +** UnpackedRecord object. +** +** A value is extracted in the following cases: +** +** * (pExpr==0). In this case the value is assumed to be an SQL NULL, +** +** * The expression is a bound variable, and this is a reprepare, or +** +** * The expression is a literal value. +** +** On success, *ppVal is made to point to the extracted value. The caller +** is responsible for ensuring that the value is eventually freed. +*/ +static int stat4ValueFromExpr( + Parse *pParse, /* Parse context */ + Expr *pExpr, /* The expression to extract a value from */ + u8 affinity, /* Affinity to use */ + struct ValueNewStat4Ctx *pAlloc,/* How to allocate space. Or NULL */ + sqlite3_value **ppVal /* OUT: New value object (or NULL) */ +){ + int rc = SQLITE_OK; + sqlite3_value *pVal = 0; + sqlite3 *db = pParse->db; + + /* Skip over any TK_COLLATE nodes */ + pExpr = sqlite3ExprSkipCollate(pExpr); + + assert( pExpr==0 || pExpr->op!=TK_REGISTER || pExpr->op2!=TK_VARIABLE ); + if( !pExpr ){ + pVal = valueNew(db, pAlloc); + if( pVal ){ + sqlite3VdbeMemSetNull((Mem*)pVal); + } + }else if( pExpr->op==TK_VARIABLE && (db->flags & SQLITE_EnableQPSG)==0 ){ + Vdbe *v; + int iBindVar = pExpr->iColumn; + sqlite3VdbeSetVarmask(pParse->pVdbe, iBindVar); + if( (v = pParse->pReprepare)!=0 ){ + pVal = valueNew(db, pAlloc); + if( pVal ){ + rc = sqlite3VdbeMemCopy((Mem*)pVal, &v->aVar[iBindVar-1]); + sqlite3ValueApplyAffinity(pVal, affinity, ENC(db)); + pVal->db = pParse->db; + } + } + }else{ + rc = valueFromExpr(db, pExpr, ENC(db), affinity, &pVal, pAlloc); + } + + assert( pVal==0 || pVal->db==db ); + *ppVal = pVal; + return rc; +} + +/* +** This function is used to allocate and populate UnpackedRecord +** structures intended to be compared against sample index keys stored +** in the sqlite_stat4 table. +** +** A single call to this function populates zero or more fields of the +** record starting with field iVal (fields are numbered from left to +** right starting with 0). A single field is populated if: +** +** * (pExpr==0). In this case the value is assumed to be an SQL NULL, +** +** * The expression is a bound variable, and this is a reprepare, or +** +** * The sqlite3ValueFromExpr() function is able to extract a value +** from the expression (i.e. the expression is a literal value). +** +** Or, if pExpr is a TK_VECTOR, one field is populated for each of the +** vector components that match either of the two latter criteria listed +** above. +** +** Before any value is appended to the record, the affinity of the +** corresponding column within index pIdx is applied to it. Before +** this function returns, output parameter *pnExtract is set to the +** number of values appended to the record. +** +** When this function is called, *ppRec must either point to an object +** allocated by an earlier call to this function, or must be NULL. If it +** is NULL and a value can be successfully extracted, a new UnpackedRecord +** is allocated (and *ppRec set to point to it) before returning. +** +** Unless an error is encountered, SQLITE_OK is returned. It is not an +** error if a value cannot be extracted from pExpr. If an error does +** occur, an SQLite error code is returned. +*/ +SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue( + Parse *pParse, /* Parse context */ + Index *pIdx, /* Index being probed */ + UnpackedRecord **ppRec, /* IN/OUT: Probe record */ + Expr *pExpr, /* The expression to extract a value from */ + int nElem, /* Maximum number of values to append */ + int iVal, /* Array element to populate */ + int *pnExtract /* OUT: Values appended to the record */ +){ + int rc = SQLITE_OK; + int nExtract = 0; + + if( pExpr==0 || pExpr->op!=TK_SELECT ){ + int i; + struct ValueNewStat4Ctx alloc; + + alloc.pParse = pParse; + alloc.pIdx = pIdx; + alloc.ppRec = ppRec; + + for(i=0; idb, pIdx, iVal+i); + alloc.iVal = iVal+i; + rc = stat4ValueFromExpr(pParse, pElem, aff, &alloc, &pVal); + if( !pVal ) break; + nExtract++; + } + } + + *pnExtract = nExtract; + return rc; +} + +/* +** Attempt to extract a value from expression pExpr using the methods +** as described for sqlite3Stat4ProbeSetValue() above. +** +** If successful, set *ppVal to point to a new value object and return +** SQLITE_OK. If no value can be extracted, but no other error occurs +** (e.g. OOM), return SQLITE_OK and set *ppVal to NULL. Or, if an error +** does occur, return an SQLite error code. The final value of *ppVal +** is undefined in this case. +*/ +SQLITE_PRIVATE int sqlite3Stat4ValueFromExpr( + Parse *pParse, /* Parse context */ + Expr *pExpr, /* The expression to extract a value from */ + u8 affinity, /* Affinity to use */ + sqlite3_value **ppVal /* OUT: New value object (or NULL) */ +){ + return stat4ValueFromExpr(pParse, pExpr, affinity, 0, ppVal); +} + +/* +** Extract the iCol-th column from the nRec-byte record in pRec. Write +** the column value into *ppVal. If *ppVal is initially NULL then a new +** sqlite3_value object is allocated. +** +** If *ppVal is initially NULL then the caller is responsible for +** ensuring that the value written into *ppVal is eventually freed. +** +** If the buffer does not contain a well-formed record, this routine may +** read several bytes past the end of the buffer. Callers must therefore +** ensure that any buffer which may contain a corrupt record is padded +** with at least 8 bytes of addressable memory. +*/ +SQLITE_PRIVATE int sqlite3Stat4Column( + sqlite3 *db, /* Database handle */ + const void *pRec, /* Pointer to buffer containing record */ + int nRec, /* Size of buffer pRec in bytes */ + int iCol, /* Column to extract */ + sqlite3_value **ppVal /* OUT: Extracted value */ +){ + u32 t = 0; /* a column type code */ + u32 nHdr; /* Size of the header in the record */ + u32 iHdr; /* Next unread header byte */ + i64 iField; /* Next unread data byte */ + u32 szField = 0; /* Size of the current data field */ + int i; /* Column index */ + u8 *a = (u8*)pRec; /* Typecast byte array */ + Mem *pMem = *ppVal; /* Write result into this Mem object */ + + assert( iCol>0 ); + iHdr = getVarint32(a, nHdr); + if( nHdr>(u32)nRec || iHdr>=nHdr ) return SQLITE_CORRUPT_BKPT; + iField = nHdr; + for(i=0; i<=iCol; i++){ + iHdr += getVarint32(&a[iHdr], t); + testcase( iHdr==nHdr ); + testcase( iHdr==nHdr+1 ); + if( iHdr>nHdr ) return SQLITE_CORRUPT_BKPT; + szField = sqlite3VdbeSerialTypeLen(t); + iField += szField; + } + testcase( iField==nRec ); + testcase( iField==nRec+1 ); + if( iField>nRec ) return SQLITE_CORRUPT_BKPT; + if( pMem==0 ){ + pMem = *ppVal = sqlite3ValueNew(db); + if( pMem==0 ) return SQLITE_NOMEM_BKPT; + } + sqlite3VdbeSerialGet(&a[iField-szField], t, pMem); + pMem->enc = ENC(db); + return SQLITE_OK; +} + +/* +** Unless it is NULL, the argument must be an UnpackedRecord object returned +** by an earlier call to sqlite3Stat4ProbeSetValue(). This call deletes +** the object. +*/ +SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){ + if( pRec ){ + int i; + int nCol = pRec->pKeyInfo->nAllField; + Mem *aMem = pRec->aMem; + sqlite3 *db = aMem[0].db; + for(i=0; ipKeyInfo); + sqlite3DbFreeNN(db, pRec); + } +} +#endif /* ifdef SQLITE_ENABLE_STAT4 */ + +/* +** Change the string value of an sqlite3_value object +*/ +SQLITE_PRIVATE void sqlite3ValueSetStr( + sqlite3_value *v, /* Value to be set */ + int n, /* Length of string z */ + const void *z, /* Text of the new string */ + u8 enc, /* Encoding to use */ + void (*xDel)(void*) /* Destructor for the string */ +){ + if( v ) sqlite3VdbeMemSetStr((Mem *)v, z, n, enc, xDel); +} + +/* +** Free an sqlite3_value object +*/ +SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value *v){ + if( !v ) return; + sqlite3VdbeMemRelease((Mem *)v); + sqlite3DbFreeNN(((Mem*)v)->db, v); +} + +/* +** The sqlite3ValueBytes() routine returns the number of bytes in the +** sqlite3_value object assuming that it uses the encoding "enc". +** The valueBytes() routine is a helper function. +*/ +static SQLITE_NOINLINE int valueBytes(sqlite3_value *pVal, u8 enc){ + return valueToText(pVal, enc)!=0 ? pVal->n : 0; +} +SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){ + Mem *p = (Mem*)pVal; + assert( (p->flags & MEM_Null)==0 || (p->flags & (MEM_Str|MEM_Blob))==0 ); + if( (p->flags & MEM_Str)!=0 && pVal->enc==enc ){ + return p->n; + } + if( (p->flags & MEM_Str)!=0 && enc!=SQLITE_UTF8 && pVal->enc!=SQLITE_UTF8 ){ + return p->n; + } + if( (p->flags & MEM_Blob)!=0 ){ + if( p->flags & MEM_Zero ){ + return p->n + p->u.nZero; + }else{ + return p->n; + } + } + if( p->flags & MEM_Null ) return 0; + return valueBytes(pVal, enc); +} + +/************** End of vdbemem.c *********************************************/ +/************** Begin file vdbeaux.c *****************************************/ +/* +** 2003 September 6 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code used for creating, destroying, and populating +** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) +*/ +/* #include "sqliteInt.h" */ +/* #include "vdbeInt.h" */ + +/* Forward references */ +static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef); +static void vdbeFreeOpArray(sqlite3 *, Op *, int); + +/* +** Create a new virtual database engine. +*/ +SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){ + sqlite3 *db = pParse->db; + Vdbe *p; + p = sqlite3DbMallocRawNN(db, sizeof(Vdbe) ); + if( p==0 ) return 0; + memset(&p->aOp, 0, sizeof(Vdbe)-offsetof(Vdbe,aOp)); + p->db = db; + if( db->pVdbe ){ + db->pVdbe->ppVPrev = &p->pVNext; + } + p->pVNext = db->pVdbe; + p->ppVPrev = &db->pVdbe; + db->pVdbe = p; + assert( p->eVdbeState==VDBE_INIT_STATE ); + p->pParse = pParse; + pParse->pVdbe = p; + assert( pParse->aLabel==0 ); + assert( pParse->nLabel==0 ); + assert( p->nOpAlloc==0 ); + assert( pParse->szOpAlloc==0 ); + sqlite3VdbeAddOp2(p, OP_Init, 0, 1); + return p; +} + +/* +** Return the Parse object that owns a Vdbe object. +*/ +SQLITE_PRIVATE Parse *sqlite3VdbeParser(Vdbe *p){ + return p->pParse; +} + +/* +** Change the error string stored in Vdbe.zErrMsg +*/ +SQLITE_PRIVATE void sqlite3VdbeError(Vdbe *p, const char *zFormat, ...){ + va_list ap; + sqlite3DbFree(p->db, p->zErrMsg); + va_start(ap, zFormat); + p->zErrMsg = sqlite3VMPrintf(p->db, zFormat, ap); + va_end(ap); +} + +/* +** Remember the SQL string for a prepared statement. +*/ +SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, u8 prepFlags){ + if( p==0 ) return; + p->prepFlags = prepFlags; + if( (prepFlags & SQLITE_PREPARE_SAVESQL)==0 ){ + p->expmask = 0; + } + assert( p->zSql==0 ); + p->zSql = sqlite3DbStrNDup(p->db, z, n); +} + +#ifdef SQLITE_ENABLE_NORMALIZE +/* +** Add a new element to the Vdbe->pDblStr list. +*/ +SQLITE_PRIVATE void sqlite3VdbeAddDblquoteStr(sqlite3 *db, Vdbe *p, const char *z){ + if( p ){ + int n = sqlite3Strlen30(z); + DblquoteStr *pStr = sqlite3DbMallocRawNN(db, + sizeof(*pStr)+n+1-sizeof(pStr->z)); + if( pStr ){ + pStr->pNextStr = p->pDblStr; + p->pDblStr = pStr; + memcpy(pStr->z, z, n+1); + } + } +} +#endif + +#ifdef SQLITE_ENABLE_NORMALIZE +/* +** zId of length nId is a double-quoted identifier. Check to see if +** that identifier is really used as a string literal. +*/ +SQLITE_PRIVATE int sqlite3VdbeUsesDoubleQuotedString( + Vdbe *pVdbe, /* The prepared statement */ + const char *zId /* The double-quoted identifier, already dequoted */ +){ + DblquoteStr *pStr; + assert( zId!=0 ); + if( pVdbe->pDblStr==0 ) return 0; + for(pStr=pVdbe->pDblStr; pStr; pStr=pStr->pNextStr){ + if( strcmp(zId, pStr->z)==0 ) return 1; + } + return 0; +} +#endif + +/* +** Swap byte-code between two VDBE structures. +** +** This happens after pB was previously run and returned +** SQLITE_SCHEMA. The statement was then reprepared in pA. +** This routine transfers the new bytecode in pA over to pB +** so that pB can be run again. The old pB byte code is +** moved back to pA so that it will be cleaned up when pA is +** finalized. +*/ +SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){ + Vdbe tmp, *pTmp, **ppTmp; + char *zTmp; + assert( pA->db==pB->db ); + tmp = *pA; + *pA = *pB; + *pB = tmp; + pTmp = pA->pVNext; + pA->pVNext = pB->pVNext; + pB->pVNext = pTmp; + ppTmp = pA->ppVPrev; + pA->ppVPrev = pB->ppVPrev; + pB->ppVPrev = ppTmp; + zTmp = pA->zSql; + pA->zSql = pB->zSql; + pB->zSql = zTmp; +#ifdef SQLITE_ENABLE_NORMALIZE + zTmp = pA->zNormSql; + pA->zNormSql = pB->zNormSql; + pB->zNormSql = zTmp; +#endif + pB->expmask = pA->expmask; + pB->prepFlags = pA->prepFlags; + memcpy(pB->aCounter, pA->aCounter, sizeof(pB->aCounter)); + pB->aCounter[SQLITE_STMTSTATUS_REPREPARE]++; +} + +/* +** Resize the Vdbe.aOp array so that it is at least nOp elements larger +** than its current size. nOp is guaranteed to be less than or equal +** to 1024/sizeof(Op). +** +** If an out-of-memory error occurs while resizing the array, return +** SQLITE_NOMEM. In this case Vdbe.aOp and Vdbe.nOpAlloc remain +** unchanged (this is so that any opcodes already allocated can be +** correctly deallocated along with the rest of the Vdbe). +*/ +static int growOpArray(Vdbe *v, int nOp){ + VdbeOp *pNew; + Parse *p = v->pParse; + + /* The SQLITE_TEST_REALLOC_STRESS compile-time option is designed to force + ** more frequent reallocs and hence provide more opportunities for + ** simulated OOM faults. SQLITE_TEST_REALLOC_STRESS is generally used + ** during testing only. With SQLITE_TEST_REALLOC_STRESS grow the op array + ** by the minimum* amount required until the size reaches 512. Normal + ** operation (without SQLITE_TEST_REALLOC_STRESS) is to double the current + ** size of the op array or add 1KB of space, whichever is smaller. */ +#ifdef SQLITE_TEST_REALLOC_STRESS + sqlite3_int64 nNew = (v->nOpAlloc>=512 ? 2*(sqlite3_int64)v->nOpAlloc + : (sqlite3_int64)v->nOpAlloc+nOp); +#else + sqlite3_int64 nNew = (v->nOpAlloc ? 2*(sqlite3_int64)v->nOpAlloc + : (sqlite3_int64)(1024/sizeof(Op))); + UNUSED_PARAMETER(nOp); +#endif + + /* Ensure that the size of a VDBE does not grow too large */ + if( nNew > p->db->aLimit[SQLITE_LIMIT_VDBE_OP] ){ + sqlite3OomFault(p->db); + return SQLITE_NOMEM; + } + + assert( nOp<=(int)(1024/sizeof(Op)) ); + assert( nNew>=(v->nOpAlloc+nOp) ); + pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op)); + if( pNew ){ + p->szOpAlloc = sqlite3DbMallocSize(p->db, pNew); + v->nOpAlloc = p->szOpAlloc/sizeof(Op); + v->aOp = pNew; + } + return (pNew ? SQLITE_OK : SQLITE_NOMEM_BKPT); +} + +#ifdef SQLITE_DEBUG +/* This routine is just a convenient place to set a breakpoint that will +** fire after each opcode is inserted and displayed using +** "PRAGMA vdbe_addoptrace=on". Parameters "pc" (program counter) and +** pOp are available to make the breakpoint conditional. +** +** Other useful labels for breakpoints include: +** test_trace_breakpoint(pc,pOp) +** sqlite3CorruptError(lineno) +** sqlite3MisuseError(lineno) +** sqlite3CantopenError(lineno) +*/ +static void test_addop_breakpoint(int pc, Op *pOp){ + static u64 n = 0; + (void)pc; + (void)pOp; + n++; + if( n==LARGEST_UINT64 ) abort(); /* so that n is used, preventing a warning */ +} +#endif + +/* +** Slow paths for sqlite3VdbeAddOp3() and sqlite3VdbeAddOp4Int() for the +** unusual case when we need to increase the size of the Vdbe.aOp[] array +** before adding the new opcode. +*/ +static SQLITE_NOINLINE int growOp3(Vdbe *p, int op, int p1, int p2, int p3){ + assert( p->nOpAlloc<=p->nOp ); + if( growOpArray(p, 1) ) return 1; + assert( p->nOpAlloc>p->nOp ); + return sqlite3VdbeAddOp3(p, op, p1, p2, p3); +} +static SQLITE_NOINLINE int addOp4IntSlow( + Vdbe *p, /* Add the opcode to this VM */ + int op, /* The new opcode */ + int p1, /* The P1 operand */ + int p2, /* The P2 operand */ + int p3, /* The P3 operand */ + int p4 /* The P4 operand as an integer */ +){ + int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3); + if( p->db->mallocFailed==0 ){ + VdbeOp *pOp = &p->aOp[addr]; + pOp->p4type = P4_INT32; + pOp->p4.i = p4; + } + return addr; +} + + +/* +** Add a new instruction to the list of instructions current in the +** VDBE. Return the address of the new instruction. +** +** Parameters: +** +** p Pointer to the VDBE +** +** op The opcode for this instruction +** +** p1, p2, p3, p4 Operands +*/ +SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe *p, int op){ + return sqlite3VdbeAddOp3(p, op, 0, 0, 0); +} +SQLITE_PRIVATE int sqlite3VdbeAddOp1(Vdbe *p, int op, int p1){ + return sqlite3VdbeAddOp3(p, op, p1, 0, 0); +} +SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe *p, int op, int p1, int p2){ + return sqlite3VdbeAddOp3(p, op, p1, p2, 0); +} +SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ + int i; + VdbeOp *pOp; + + i = p->nOp; + assert( p->eVdbeState==VDBE_INIT_STATE ); + assert( op>=0 && op<0xff ); + if( p->nOpAlloc<=i ){ + return growOp3(p, op, p1, p2, p3); + } + assert( p->aOp!=0 ); + p->nOp++; + pOp = &p->aOp[i]; + assert( pOp!=0 ); + pOp->opcode = (u8)op; + pOp->p5 = 0; + pOp->p1 = p1; + pOp->p2 = p2; + pOp->p3 = p3; + pOp->p4.p = 0; + pOp->p4type = P4_NOTUSED; + + /* Replicate this logic in sqlite3VdbeAddOp4Int() + ** vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */ +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + pOp->zComment = 0; +#endif +#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) + pOp->nExec = 0; + pOp->nCycle = 0; +#endif +#ifdef SQLITE_DEBUG + if( p->db->flags & SQLITE_VdbeAddopTrace ){ + sqlite3VdbePrintOp(0, i, &p->aOp[i]); + test_addop_breakpoint(i, &p->aOp[i]); + } +#endif +#ifdef SQLITE_VDBE_COVERAGE + pOp->iSrcLine = 0; +#endif + /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ** Replicate in sqlite3VdbeAddOp4Int() */ + + return i; +} +SQLITE_PRIVATE int sqlite3VdbeAddOp4Int( + Vdbe *p, /* Add the opcode to this VM */ + int op, /* The new opcode */ + int p1, /* The P1 operand */ + int p2, /* The P2 operand */ + int p3, /* The P3 operand */ + int p4 /* The P4 operand as an integer */ +){ + int i; + VdbeOp *pOp; + + i = p->nOp; + if( p->nOpAlloc<=i ){ + return addOp4IntSlow(p, op, p1, p2, p3, p4); + } + p->nOp++; + pOp = &p->aOp[i]; + assert( pOp!=0 ); + pOp->opcode = (u8)op; + pOp->p5 = 0; + pOp->p1 = p1; + pOp->p2 = p2; + pOp->p3 = p3; + pOp->p4.i = p4; + pOp->p4type = P4_INT32; + + /* Replicate this logic in sqlite3VdbeAddOp3() + ** vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */ +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + pOp->zComment = 0; +#endif +#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) + pOp->nExec = 0; + pOp->nCycle = 0; +#endif +#ifdef SQLITE_DEBUG + if( p->db->flags & SQLITE_VdbeAddopTrace ){ + sqlite3VdbePrintOp(0, i, &p->aOp[i]); + test_addop_breakpoint(i, &p->aOp[i]); + } +#endif +#ifdef SQLITE_VDBE_COVERAGE + pOp->iSrcLine = 0; +#endif + /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ** Replicate in sqlite3VdbeAddOp3() */ + + return i; +} + +/* Generate code for an unconditional jump to instruction iDest +*/ +SQLITE_PRIVATE int sqlite3VdbeGoto(Vdbe *p, int iDest){ + return sqlite3VdbeAddOp3(p, OP_Goto, 0, iDest, 0); +} + +/* Generate code to cause the string zStr to be loaded into +** register iDest +*/ +SQLITE_PRIVATE int sqlite3VdbeLoadString(Vdbe *p, int iDest, const char *zStr){ + return sqlite3VdbeAddOp4(p, OP_String8, 0, iDest, 0, zStr, 0); +} + +/* +** Generate code that initializes multiple registers to string or integer +** constants. The registers begin with iDest and increase consecutively. +** One register is initialized for each characgter in zTypes[]. For each +** "s" character in zTypes[], the register is a string if the argument is +** not NULL, or OP_Null if the value is a null pointer. For each "i" character +** in zTypes[], the register is initialized to an integer. +** +** If the input string does not end with "X" then an OP_ResultRow instruction +** is generated for the values inserted. +*/ +SQLITE_PRIVATE void sqlite3VdbeMultiLoad(Vdbe *p, int iDest, const char *zTypes, ...){ + va_list ap; + int i; + char c; + va_start(ap, zTypes); + for(i=0; (c = zTypes[i])!=0; i++){ + if( c=='s' ){ + const char *z = va_arg(ap, const char*); + sqlite3VdbeAddOp4(p, z==0 ? OP_Null : OP_String8, 0, iDest+i, 0, z, 0); + }else if( c=='i' ){ + sqlite3VdbeAddOp2(p, OP_Integer, va_arg(ap, int), iDest+i); + }else{ + goto skip_op_resultrow; + } + } + sqlite3VdbeAddOp2(p, OP_ResultRow, iDest, i); +skip_op_resultrow: + va_end(ap); +} + +/* +** Add an opcode that includes the p4 value as a pointer. +*/ +SQLITE_PRIVATE int sqlite3VdbeAddOp4( + Vdbe *p, /* Add the opcode to this VM */ + int op, /* The new opcode */ + int p1, /* The P1 operand */ + int p2, /* The P2 operand */ + int p3, /* The P3 operand */ + const char *zP4, /* The P4 operand */ + int p4type /* P4 operand type */ +){ + int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3); + sqlite3VdbeChangeP4(p, addr, zP4, p4type); + return addr; +} + +/* +** Add an OP_Function or OP_PureFunc opcode. +** +** The eCallCtx argument is information (typically taken from Expr.op2) +** that describes the calling context of the function. 0 means a general +** function call. NC_IsCheck means called by a check constraint, +** NC_IdxExpr means called as part of an index expression. NC_PartIdx +** means in the WHERE clause of a partial index. NC_GenCol means called +** while computing a generated column value. 0 is the usual case. +*/ +SQLITE_PRIVATE int sqlite3VdbeAddFunctionCall( + Parse *pParse, /* Parsing context */ + int p1, /* Constant argument mask */ + int p2, /* First argument register */ + int p3, /* Register into which results are written */ + int nArg, /* Number of argument */ + const FuncDef *pFunc, /* The function to be invoked */ + int eCallCtx /* Calling context */ +){ + Vdbe *v = pParse->pVdbe; + int addr; + sqlite3_context *pCtx; + assert( v ); + pCtx = sqlite3DbMallocRawNN(pParse->db, SZ_CONTEXT(nArg)); + if( pCtx==0 ){ + assert( pParse->db->mallocFailed ); + freeEphemeralFunction(pParse->db, (FuncDef*)pFunc); + return 0; + } + pCtx->pOut = 0; + pCtx->pFunc = (FuncDef*)pFunc; + pCtx->pVdbe = 0; + pCtx->isError = 0; + pCtx->argc = nArg; + pCtx->iOp = sqlite3VdbeCurrentAddr(v); + addr = sqlite3VdbeAddOp4(v, eCallCtx ? OP_PureFunc : OP_Function, + p1, p2, p3, (char*)pCtx, P4_FUNCCTX); + sqlite3VdbeChangeP5(v, eCallCtx & NC_SelfRef); + sqlite3MayAbort(pParse); + return addr; +} + +/* +** Add an opcode that includes the p4 value with a P4_INT64 or +** P4_REAL type. +*/ +SQLITE_PRIVATE int sqlite3VdbeAddOp4Dup8( + Vdbe *p, /* Add the opcode to this VM */ + int op, /* The new opcode */ + int p1, /* The P1 operand */ + int p2, /* The P2 operand */ + int p3, /* The P3 operand */ + const u8 *zP4, /* The P4 operand */ + int p4type /* P4 operand type */ +){ + char *p4copy = sqlite3DbMallocRawNN(sqlite3VdbeDb(p), 8); + if( p4copy ) memcpy(p4copy, zP4, 8); + return sqlite3VdbeAddOp4(p, op, p1, p2, p3, p4copy, p4type); +} + +#ifndef SQLITE_OMIT_EXPLAIN +/* +** Return the address of the current EXPLAIN QUERY PLAN baseline. +** 0 means "none". +*/ +SQLITE_PRIVATE int sqlite3VdbeExplainParent(Parse *pParse){ + VdbeOp *pOp; + if( pParse->addrExplain==0 ) return 0; + pOp = sqlite3VdbeGetOp(pParse->pVdbe, pParse->addrExplain); + return pOp->p2; +} + +/* +** Set a debugger breakpoint on the following routine in order to +** monitor the EXPLAIN QUERY PLAN code generation. +*/ +#if defined(SQLITE_DEBUG) +SQLITE_PRIVATE void sqlite3ExplainBreakpoint(const char *z1, const char *z2){ + (void)z1; + (void)z2; +} +#endif + +/* +** Add a new OP_Explain opcode. +** +** If the bPush flag is true, then make this opcode the parent for +** subsequent Explains until sqlite3VdbeExplainPop() is called. +*/ +SQLITE_PRIVATE int sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){ + int addr = 0; +#if !defined(SQLITE_DEBUG) + /* Always include the OP_Explain opcodes if SQLITE_DEBUG is defined. + ** But omit them (for performance) during production builds */ + if( pParse->explain==2 || IS_STMT_SCANSTATUS(pParse->db) ) +#endif + { + char *zMsg; + Vdbe *v; + va_list ap; + int iThis; + va_start(ap, zFmt); + zMsg = sqlite3VMPrintf(pParse->db, zFmt, ap); + va_end(ap); + v = pParse->pVdbe; + iThis = v->nOp; + addr = sqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0, + zMsg, P4_DYNAMIC); + sqlite3ExplainBreakpoint(bPush?"PUSH":"", sqlite3VdbeGetLastOp(v)->p4.z); + if( bPush){ + pParse->addrExplain = iThis; + } + sqlite3VdbeScanStatus(v, iThis, -1, -1, 0, 0); + } + return addr; +} + +/* +** Pop the EXPLAIN QUERY PLAN stack one level. +*/ +SQLITE_PRIVATE void sqlite3VdbeExplainPop(Parse *pParse){ + sqlite3ExplainBreakpoint("POP", 0); + pParse->addrExplain = sqlite3VdbeExplainParent(pParse); +} +#endif /* SQLITE_OMIT_EXPLAIN */ + +/* +** Add an OP_ParseSchema opcode. This routine is broken out from +** sqlite3VdbeAddOp4() since it needs to also needs to mark all btrees +** as having been used. +** +** The zWhere string must have been obtained from sqlite3_malloc(). +** This routine will take ownership of the allocated memory. +*/ +SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere, u16 p5){ + int j; + sqlite3VdbeAddOp4(p, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC); + sqlite3VdbeChangeP5(p, p5); + for(j=0; jdb->nDb; j++) sqlite3VdbeUsesBtree(p, j); + sqlite3MayAbort(p->pParse); +} + +/* Insert the end of a co-routine +*/ +SQLITE_PRIVATE void sqlite3VdbeEndCoroutine(Vdbe *v, int regYield){ + sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield); + + /* Clear the temporary register cache, thereby ensuring that each + ** co-routine has its own independent set of registers, because co-routines + ** might expect their registers to be preserved across an OP_Yield, and + ** that could cause problems if two or more co-routines are using the same + ** temporary register. + */ + v->pParse->nTempReg = 0; + v->pParse->nRangeReg = 0; +} + +/* +** Create a new symbolic label for an instruction that has yet to be +** coded. The symbolic label is really just a negative number. The +** label can be used as the P2 value of an operation. Later, when +** the label is resolved to a specific address, the VDBE will scan +** through its operation list and change all values of P2 which match +** the label into the resolved address. +** +** The VDBE knows that a P2 value is a label because labels are +** always negative and P2 values are suppose to be non-negative. +** Hence, a negative P2 value is a label that has yet to be resolved. +** (Later:) This is only true for opcodes that have the OPFLG_JUMP +** property. +** +** Variable usage notes: +** +** Parse.aLabel[x] Stores the address that the x-th label resolves +** into. For testing (SQLITE_DEBUG), unresolved +** labels stores -1, but that is not required. +** Parse.nLabelAlloc Number of slots allocated to Parse.aLabel[] +** Parse.nLabel The *negative* of the number of labels that have +** been issued. The negative is stored because +** that gives a performance improvement over storing +** the equivalent positive value. +*/ +SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Parse *pParse){ + return --pParse->nLabel; +} + +/* +** Resolve label "x" to be the address of the next instruction to +** be inserted. The parameter "x" must have been obtained from +** a prior call to sqlite3VdbeMakeLabel(). +*/ +static SQLITE_NOINLINE void resizeResolveLabel(Parse *p, Vdbe *v, int j){ + int nNewSize = 10 - p->nLabel; + p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel, + nNewSize*sizeof(p->aLabel[0])); + if( p->aLabel==0 ){ + p->nLabelAlloc = 0; + }else{ +#ifdef SQLITE_DEBUG + int i; + for(i=p->nLabelAlloc; iaLabel[i] = -1; +#endif + if( nNewSize>=100 && (nNewSize/100)>(p->nLabelAlloc/100) ){ + sqlite3ProgressCheck(p); + } + p->nLabelAlloc = nNewSize; + p->aLabel[j] = v->nOp; + } +} +SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){ + Parse *p = v->pParse; + int j = ADDR(x); + assert( v->eVdbeState==VDBE_INIT_STATE ); + assert( j<-p->nLabel ); + assert( j>=0 ); +#ifdef SQLITE_DEBUG + if( p->db->flags & SQLITE_VdbeAddopTrace ){ + printf("RESOLVE LABEL %d to %d\n", x, v->nOp); + } +#endif + if( p->nLabelAlloc + p->nLabel < 0 ){ + resizeResolveLabel(p,v,j); + }else{ + assert( p->aLabel[j]==(-1) ); /* Labels may only be resolved once */ + p->aLabel[j] = v->nOp; + } +} + +/* +** Mark the VDBE as one that can only be run one time. +*/ +SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe *p){ + sqlite3VdbeAddOp2(p, OP_Expire, 1, 1); +} + +/* +** Mark the VDBE as one that can be run multiple times. +*/ +SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe *p){ + int i; + for(i=1; ALWAYS(inOp); i++){ + if( ALWAYS(p->aOp[i].opcode==OP_Expire) ){ + p->aOp[1].opcode = OP_Noop; + break; + } + } +} + +#ifdef SQLITE_DEBUG /* sqlite3AssertMayAbort() logic */ + +/* +** The following type and function are used to iterate through all opcodes +** in a Vdbe main program and each of the sub-programs (triggers) it may +** invoke directly or indirectly. It should be used as follows: +** +** Op *pOp; +** VdbeOpIter sIter; +** +** memset(&sIter, 0, sizeof(sIter)); +** sIter.v = v; // v is of type Vdbe* +** while( (pOp = opIterNext(&sIter)) ){ +** // Do something with pOp +** } +** sqlite3DbFree(v->db, sIter.apSub); +** +*/ +typedef struct VdbeOpIter VdbeOpIter; +struct VdbeOpIter { + Vdbe *v; /* Vdbe to iterate through the opcodes of */ + SubProgram **apSub; /* Array of subprograms */ + int nSub; /* Number of entries in apSub */ + int iAddr; /* Address of next instruction to return */ + int iSub; /* 0 = main program, 1 = first sub-program etc. */ +}; +static Op *opIterNext(VdbeOpIter *p){ + Vdbe *v = p->v; + Op *pRet = 0; + Op *aOp; + int nOp; + + if( p->iSub<=p->nSub ){ + + if( p->iSub==0 ){ + aOp = v->aOp; + nOp = v->nOp; + }else{ + aOp = p->apSub[p->iSub-1]->aOp; + nOp = p->apSub[p->iSub-1]->nOp; + } + assert( p->iAddriAddr]; + p->iAddr++; + if( p->iAddr==nOp ){ + p->iSub++; + p->iAddr = 0; + } + + if( pRet->p4type==P4_SUBPROGRAM ){ + i64 nByte = (1+(u64)p->nSub)*sizeof(SubProgram*); + int j; + for(j=0; jnSub; j++){ + if( p->apSub[j]==pRet->p4.pProgram ) break; + } + if( j==p->nSub ){ + p->apSub = sqlite3DbReallocOrFree(v->db, p->apSub, nByte); + if( !p->apSub ){ + pRet = 0; + }else{ + p->apSub[p->nSub++] = pRet->p4.pProgram; + } + } + } + } + + return pRet; +} + +/* +** Check if the program stored in the VM associated with pParse may +** throw an ABORT exception (causing the statement, but not entire transaction +** to be rolled back). This condition is true if the main program or any +** sub-programs contains any of the following: +** +** * OP_Halt with P1=SQLITE_CONSTRAINT and P2=OE_Abort. +** * OP_HaltIfNull with P1=SQLITE_CONSTRAINT and P2=OE_Abort. +** * OP_Destroy +** * OP_VUpdate +** * OP_VCreate +** * OP_VRename +** * OP_FkCounter with P2==0 (immediate foreign key constraint) +** * OP_CreateBtree/BTREE_INTKEY and OP_InitCoroutine +** (for CREATE TABLE AS SELECT ...) +** +** Then check that the value of Parse.mayAbort is true if an +** ABORT may be thrown, or false otherwise. Return true if it does +** match, or false otherwise. This function is intended to be used as +** part of an assert statement in the compiler. Similar to: +** +** assert( sqlite3VdbeAssertMayAbort(pParse->pVdbe, pParse->mayAbort) ); +*/ +SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){ + int hasAbort = 0; + int hasFkCounter = 0; + int hasCreateTable = 0; + int hasCreateIndex = 0; + int hasInitCoroutine = 0; + Op *pOp; + VdbeOpIter sIter; + + if( v==0 ) return 0; + memset(&sIter, 0, sizeof(sIter)); + sIter.v = v; + + while( (pOp = opIterNext(&sIter))!=0 ){ + int opcode = pOp->opcode; + if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename + || opcode==OP_VDestroy + || opcode==OP_VCreate + || opcode==OP_ParseSchema + || opcode==OP_Function || opcode==OP_PureFunc + || ((opcode==OP_Halt || opcode==OP_HaltIfNull) + && ((pOp->p1)!=SQLITE_OK && pOp->p2==OE_Abort)) + ){ + hasAbort = 1; + break; + } + if( opcode==OP_CreateBtree && pOp->p3==BTREE_INTKEY ) hasCreateTable = 1; + if( mayAbort ){ + /* hasCreateIndex may also be set for some DELETE statements that use + ** OP_Clear. So this routine may end up returning true in the case + ** where a "DELETE FROM tbl" has a statement-journal but does not + ** require one. This is not so bad - it is an inefficiency, not a bug. */ + if( opcode==OP_CreateBtree && pOp->p3==BTREE_BLOBKEY ) hasCreateIndex = 1; + if( opcode==OP_Clear ) hasCreateIndex = 1; + } + if( opcode==OP_InitCoroutine ) hasInitCoroutine = 1; +#ifndef SQLITE_OMIT_FOREIGN_KEY + if( opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1 ){ + hasFkCounter = 1; + } +#endif + } + sqlite3DbFree(v->db, sIter.apSub); + + /* Return true if hasAbort==mayAbort. Or if a malloc failure occurred. + ** If malloc failed, then the while() loop above may not have iterated + ** through all opcodes and hasAbort may be set incorrectly. Return + ** true for this case to prevent the assert() in the callers frame + ** from failing. */ + return ( v->db->mallocFailed || hasAbort==mayAbort || hasFkCounter + || (hasCreateTable && hasInitCoroutine) || hasCreateIndex + ); +} +#endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */ + +#ifdef SQLITE_DEBUG +/* +** Increment the nWrite counter in the VDBE if the cursor is not an +** ephemeral cursor, or if the cursor argument is NULL. +*/ +SQLITE_PRIVATE void sqlite3VdbeIncrWriteCounter(Vdbe *p, VdbeCursor *pC){ + if( pC==0 + || (pC->eCurType!=CURTYPE_SORTER + && pC->eCurType!=CURTYPE_PSEUDO + && !pC->isEphemeral) + ){ + p->nWrite++; + } +} +#endif + +#ifdef SQLITE_DEBUG +/* +** Assert if an Abort at this point in time might result in a corrupt +** database. +*/ +SQLITE_PRIVATE void sqlite3VdbeAssertAbortable(Vdbe *p){ + assert( p->nWrite==0 || p->usesStmtJournal ); +} +#endif + +/* +** This routine is called after all opcodes have been inserted. It loops +** through all the opcodes and fixes up some details. +** +** (1) For each jump instruction with a negative P2 value (a label) +** resolve the P2 value to an actual address. +** +** (2) Compute the maximum number of arguments used by the xUpdate/xFilter +** methods of any virtual table and store that value in *pMaxVtabArgs. +** +** (3) Update the Vdbe.readOnly and Vdbe.bIsReader flags to accurately +** indicate what the prepared statement actually does. +** +** (4) (discontinued) +** +** (5) Reclaim the memory allocated for storing labels. +** +** This routine will only function correctly if the mkopcodeh.tcl generator +** script numbers the opcodes correctly. Changes to this routine must be +** coordinated with changes to mkopcodeh.tcl. +*/ +static void resolveP2Values(Vdbe *p, int *pMaxVtabArgs){ + int nMaxVtabArgs = *pMaxVtabArgs; + Op *pOp; + Parse *pParse = p->pParse; + int *aLabel = pParse->aLabel; + + assert( pParse->db->mallocFailed==0 ); /* tag-20230419-1 */ + p->readOnly = 1; + p->bIsReader = 0; + pOp = &p->aOp[p->nOp-1]; + assert( p->aOp[0].opcode==OP_Init ); + while( 1 /* Loop terminates when it reaches the OP_Init opcode */ ){ + /* Only JUMP opcodes and the short list of special opcodes in the switch + ** below need to be considered. The mkopcodeh.tcl generator script groups + ** all these opcodes together near the front of the opcode list. Skip + ** any opcode that does not need processing by virtual of the fact that + ** it is larger than SQLITE_MX_JUMP_OPCODE, as a performance optimization. + */ + if( pOp->opcode<=SQLITE_MX_JUMP_OPCODE ){ + /* NOTE: Be sure to update mkopcodeh.tcl when adding or removing + ** cases from this switch! */ + switch( pOp->opcode ){ + case OP_Transaction: { + if( pOp->p2!=0 ) p->readOnly = 0; + /* no break */ deliberate_fall_through + } + case OP_AutoCommit: + case OP_Savepoint: { + p->bIsReader = 1; + break; + } +#ifndef SQLITE_OMIT_WAL + case OP_Checkpoint: +#endif + case OP_Vacuum: + case OP_JournalMode: { + p->readOnly = 0; + p->bIsReader = 1; + break; + } + case OP_Init: { + assert( pOp->p2>=0 ); + goto resolve_p2_values_loop_exit; + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + case OP_VUpdate: { + if( pOp->p2>nMaxVtabArgs ) nMaxVtabArgs = pOp->p2; + break; + } + case OP_VFilter: { + int n; + /* The instruction immediately prior to VFilter will be an + ** OP_Integer that sets the "argc" value for the VFilter. See + ** the code where OP_VFilter is generated at tag-20250207a. */ + assert( (pOp - p->aOp) >= 3 ); + assert( pOp[-1].opcode==OP_Integer ); + assert( pOp[-1].p2==pOp->p3+1 ); + n = pOp[-1].p1; + if( n>nMaxVtabArgs ) nMaxVtabArgs = n; + /* Fall through into the default case */ + /* no break */ deliberate_fall_through + } +#endif + default: { + if( pOp->p2<0 ){ + /* The mkopcodeh.tcl script has so arranged things that the only + ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to + ** have non-negative values for P2. */ + assert( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 ); + assert( ADDR(pOp->p2)<-pParse->nLabel ); + assert( aLabel!=0 ); /* True because of tag-20230419-1 */ + pOp->p2 = aLabel[ADDR(pOp->p2)]; + } + + /* OPFLG_JUMP opcodes never have P2==0, though OPFLG_JUMP0 opcodes + ** might */ + assert( pOp->p2>0 + || (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP0)!=0 ); + + /* Jumps never go off the end of the bytecode array */ + assert( pOp->p2nOp + || (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)==0 ); + break; + } + } + /* The mkopcodeh.tcl script has so arranged things that the only + ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to + ** have non-negative values for P2. */ + assert( (sqlite3OpcodeProperty[pOp->opcode]&OPFLG_JUMP)==0 || pOp->p2>=0); + } + assert( pOp>p->aOp ); + pOp--; + } +resolve_p2_values_loop_exit: + if( aLabel ){ + sqlite3DbNNFreeNN(p->db, pParse->aLabel); + pParse->aLabel = 0; + } + pParse->nLabel = 0; + *pMaxVtabArgs = nMaxVtabArgs; + assert( p->bIsReader!=0 || DbMaskAllZero(p->btreeMask) ); +} + +#ifdef SQLITE_DEBUG +/* +** Check to see if a subroutine contains a jump to a location outside of +** the subroutine. If a jump outside the subroutine is detected, add code +** that will cause the program to halt with an error message. +** +** The subroutine consists of opcodes between iFirst and iLast. Jumps to +** locations within the subroutine are acceptable. iRetReg is a register +** that contains the return address. Jumps to outside the range of iFirst +** through iLast are also acceptable as long as the jump destination is +** an OP_Return to iReturnAddr. +** +** A jump to an unresolved label means that the jump destination will be +** beyond the current address. That is normally a jump to an early +** termination and is consider acceptable. +** +** This routine only runs during debug builds. The purpose is (of course) +** to detect invalid escapes out of a subroutine. The OP_Halt opcode +** is generated rather than an assert() or other error, so that ".eqp full" +** will still work to show the original bytecode, to aid in debugging. +*/ +SQLITE_PRIVATE void sqlite3VdbeNoJumpsOutsideSubrtn( + Vdbe *v, /* The byte-code program under construction */ + int iFirst, /* First opcode of the subroutine */ + int iLast, /* Last opcode of the subroutine */ + int iRetReg /* Subroutine return address register */ +){ + VdbeOp *pOp; + Parse *pParse; + int i; + sqlite3_str *pErr = 0; + assert( v!=0 ); + pParse = v->pParse; + assert( pParse!=0 ); + if( pParse->nErr ) return; + assert( iLast>=iFirst ); + assert( iLastnOp ); + pOp = &v->aOp[iFirst]; + for(i=iFirst; i<=iLast; i++, pOp++){ + if( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 ){ + int iDest = pOp->p2; /* Jump destination */ + if( iDest==0 ) continue; + if( pOp->opcode==OP_Gosub ) continue; + if( pOp->p3==20230325 && pOp->opcode==OP_NotNull ){ + /* This is a deliberately taken illegal branch. tag-20230325-2 */ + continue; + } + if( iDest<0 ){ + int j = ADDR(iDest); + assert( j>=0 ); + if( j>=-pParse->nLabel || pParse->aLabel[j]<0 ){ + continue; + } + iDest = pParse->aLabel[j]; + } + if( iDestiLast ){ + int j = iDest; + for(; jnOp; j++){ + VdbeOp *pX = &v->aOp[j]; + if( pX->opcode==OP_Return ){ + if( pX->p1==iRetReg ) break; + continue; + } + if( pX->opcode==OP_Noop ) continue; + if( pX->opcode==OP_Explain ) continue; + if( pErr==0 ){ + pErr = sqlite3_str_new(0); + }else{ + sqlite3_str_appendchar(pErr, 1, '\n'); + } + sqlite3_str_appendf(pErr, + "Opcode at %d jumps to %d which is outside the " + "subroutine at %d..%d", + i, iDest, iFirst, iLast); + break; + } + } + } + } + if( pErr ){ + char *zErr = sqlite3_str_finish(pErr); + sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_INTERNAL, OE_Abort, 0, zErr, 0); + sqlite3_free(zErr); + sqlite3MayAbort(pParse); + } +} +#endif /* SQLITE_DEBUG */ + +/* +** Return the address of the next instruction to be inserted. +*/ +SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe *p){ + assert( p->eVdbeState==VDBE_INIT_STATE ); + return p->nOp; +} + +/* +** Verify that at least N opcode slots are available in p without +** having to malloc for more space (except when compiled using +** SQLITE_TEST_REALLOC_STRESS). This interface is used during testing +** to verify that certain calls to sqlite3VdbeAddOpList() can never +** fail due to a OOM fault and hence that the return value from +** sqlite3VdbeAddOpList() will always be non-NULL. +*/ +#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS) +SQLITE_PRIVATE void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N){ + assert( p->nOp + N <= p->nOpAlloc ); +} +#endif + +/* +** Verify that the VM passed as the only argument does not contain +** an OP_ResultRow opcode. Fail an assert() if it does. This is used +** by code in pragma.c to ensure that the implementation of certain +** pragmas comports with the flags specified in the mkpragmatab.tcl +** script. +*/ +#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS) +SQLITE_PRIVATE void sqlite3VdbeVerifyNoResultRow(Vdbe *p){ + int i; + for(i=0; inOp; i++){ + assert( p->aOp[i].opcode!=OP_ResultRow ); + } +} +#endif + +/* +** Generate code (a single OP_Abortable opcode) that will +** verify that the VDBE program can safely call Abort in the current +** context. +*/ +#if defined(SQLITE_DEBUG) +SQLITE_PRIVATE void sqlite3VdbeVerifyAbortable(Vdbe *p, int onError){ + if( onError==OE_Abort ) sqlite3VdbeAddOp0(p, OP_Abortable); +} +#endif + +/* +** This function returns a pointer to the array of opcodes associated with +** the Vdbe passed as the first argument. It is the callers responsibility +** to arrange for the returned array to be eventually freed using the +** vdbeFreeOpArray() function. +** +** Before returning, *pnOp is set to the number of entries in the returned +** array. Also, *pnMaxArg is set to the larger of its current value and +** the number of entries in the Vdbe.apArg[] array required to execute the +** returned program. +*/ +SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){ + VdbeOp *aOp = p->aOp; + assert( aOp && !p->db->mallocFailed ); + + /* Check that sqlite3VdbeUsesBtree() was not called on this VM */ + assert( DbMaskAllZero(p->btreeMask) ); + + resolveP2Values(p, pnMaxArg); + *pnOp = p->nOp; + p->aOp = 0; + return aOp; +} + +/* +** Add a whole list of operations to the operation stack. Return a +** pointer to the first operation inserted. +** +** Non-zero P2 arguments to jump instructions are automatically adjusted +** so that the jump target is relative to the first operation inserted. +*/ +SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList( + Vdbe *p, /* Add opcodes to the prepared statement */ + int nOp, /* Number of opcodes to add */ + VdbeOpList const *aOp, /* The opcodes to be added */ + int iLineno /* Source-file line number of first opcode */ +){ + int i; + VdbeOp *pOut, *pFirst; + assert( nOp>0 ); + assert( p->eVdbeState==VDBE_INIT_STATE ); + if( p->nOp + nOp > p->nOpAlloc && growOpArray(p, nOp) ){ + return 0; + } + pFirst = pOut = &p->aOp[p->nOp]; + for(i=0; iopcode = aOp->opcode; + pOut->p1 = aOp->p1; + pOut->p2 = aOp->p2; + assert( aOp->p2>=0 ); + if( (sqlite3OpcodeProperty[aOp->opcode] & OPFLG_JUMP)!=0 && aOp->p2>0 ){ + pOut->p2 += p->nOp; + } + pOut->p3 = aOp->p3; + pOut->p4type = P4_NOTUSED; + pOut->p4.p = 0; + pOut->p5 = 0; +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + pOut->zComment = 0; +#endif +#ifdef SQLITE_VDBE_COVERAGE + pOut->iSrcLine = iLineno+i; +#else + (void)iLineno; +#endif +#ifdef SQLITE_DEBUG + if( p->db->flags & SQLITE_VdbeAddopTrace ){ + sqlite3VdbePrintOp(0, i+p->nOp, &p->aOp[i+p->nOp]); + } +#endif + } + p->nOp += nOp; + return pFirst; +} + +#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) +/* +** Add an entry to the array of counters managed by sqlite3_stmt_scanstatus(). +*/ +SQLITE_PRIVATE void sqlite3VdbeScanStatus( + Vdbe *p, /* VM to add scanstatus() to */ + int addrExplain, /* Address of OP_Explain (or 0) */ + int addrLoop, /* Address of loop counter */ + int addrVisit, /* Address of rows visited counter */ + LogEst nEst, /* Estimated number of output rows */ + const char *zName /* Name of table or index being scanned */ +){ + if( IS_STMT_SCANSTATUS(p->db) ){ + i64 nByte = (1+(i64)p->nScan) * sizeof(ScanStatus); + ScanStatus *aNew; + aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte); + if( aNew ){ + ScanStatus *pNew = &aNew[p->nScan++]; + memset(pNew, 0, sizeof(ScanStatus)); + pNew->addrExplain = addrExplain; + pNew->addrLoop = addrLoop; + pNew->addrVisit = addrVisit; + pNew->nEst = nEst; + pNew->zName = sqlite3DbStrDup(p->db, zName); + p->aScan = aNew; + } + } +} + +/* +** Add the range of instructions from addrStart to addrEnd (inclusive) to +** the set of those corresponding to the sqlite3_stmt_scanstatus() counters +** associated with the OP_Explain instruction at addrExplain. The +** sum of the sqlite3Hwtime() values for each of these instructions +** will be returned for SQLITE_SCANSTAT_NCYCLE requests. +*/ +SQLITE_PRIVATE void sqlite3VdbeScanStatusRange( + Vdbe *p, + int addrExplain, + int addrStart, + int addrEnd +){ + if( IS_STMT_SCANSTATUS(p->db) ){ + ScanStatus *pScan = 0; + int ii; + for(ii=p->nScan-1; ii>=0; ii--){ + pScan = &p->aScan[ii]; + if( pScan->addrExplain==addrExplain ) break; + pScan = 0; + } + if( pScan ){ + if( addrEnd<0 ) addrEnd = sqlite3VdbeCurrentAddr(p)-1; + for(ii=0; iiaAddrRange); ii+=2){ + if( pScan->aAddrRange[ii]==0 ){ + pScan->aAddrRange[ii] = addrStart; + pScan->aAddrRange[ii+1] = addrEnd; + break; + } + } + } + } +} + +/* +** Set the addresses for the SQLITE_SCANSTAT_NLOOP and SQLITE_SCANSTAT_NROW +** counters for the query element associated with the OP_Explain at +** addrExplain. +*/ +SQLITE_PRIVATE void sqlite3VdbeScanStatusCounters( + Vdbe *p, + int addrExplain, + int addrLoop, + int addrVisit +){ + if( IS_STMT_SCANSTATUS(p->db) ){ + ScanStatus *pScan = 0; + int ii; + for(ii=p->nScan-1; ii>=0; ii--){ + pScan = &p->aScan[ii]; + if( pScan->addrExplain==addrExplain ) break; + pScan = 0; + } + if( pScan ){ + if( addrLoop>0 ) pScan->addrLoop = addrLoop; + if( addrVisit>0 ) pScan->addrVisit = addrVisit; + } + } +} +#endif /* defined(SQLITE_ENABLE_STMT_SCANSTATUS) */ + + +/* +** Change the value of the opcode, or P1, P2, P3, or P5 operands +** for a specific instruction. +*/ +SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe *p, int addr, u8 iNewOpcode){ + assert( addr>=0 ); + sqlite3VdbeGetOp(p,addr)->opcode = iNewOpcode; +} +SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe *p, int addr, int val){ + assert( addr>=0 ); + sqlite3VdbeGetOp(p,addr)->p1 = val; +} +SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){ + assert( addr>=0 || p->db->mallocFailed ); + sqlite3VdbeGetOp(p,addr)->p2 = val; +} +SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe *p, int addr, int val){ + assert( addr>=0 ); + sqlite3VdbeGetOp(p,addr)->p3 = val; +} +SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u16 p5){ + assert( p->nOp>0 || p->db->mallocFailed ); + if( p->nOp>0 ) p->aOp[p->nOp-1].p5 = p5; +} + +/* +** If the previous opcode is an OP_Column that delivers results +** into register iDest, then add the OPFLAG_TYPEOFARG flag to that +** opcode. +*/ +SQLITE_PRIVATE void sqlite3VdbeTypeofColumn(Vdbe *p, int iDest){ + VdbeOp *pOp = sqlite3VdbeGetLastOp(p); +#ifdef SQLITE_DEBUG + while( pOp->opcode==OP_ReleaseReg ) pOp--; +#endif + if( pOp->p3==iDest && pOp->opcode==OP_Column ){ + pOp->p5 |= OPFLAG_TYPEOFARG; + } +} + +/* +** Change the P2 operand of instruction addr so that it points to +** the address of the next instruction to be coded. +*/ +SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){ + sqlite3VdbeChangeP2(p, addr, p->nOp); +} + +/* +** Change the P2 operand of the jump instruction at addr so that +** the jump lands on the next opcode. Or if the jump instruction was +** the previous opcode (and is thus a no-op) then simply back up +** the next instruction counter by one slot so that the jump is +** overwritten by the next inserted opcode. +** +** This routine is an optimization of sqlite3VdbeJumpHere() that +** strives to omit useless byte-code like this: +** +** 7 Once 0 8 0 +** 8 ... +*/ +SQLITE_PRIVATE void sqlite3VdbeJumpHereOrPopInst(Vdbe *p, int addr){ + if( addr==p->nOp-1 ){ + assert( p->aOp[addr].opcode==OP_Once + || p->aOp[addr].opcode==OP_If + || p->aOp[addr].opcode==OP_FkIfZero ); + assert( p->aOp[addr].p4type==0 ); +#ifdef SQLITE_VDBE_COVERAGE + sqlite3VdbeGetLastOp(p)->iSrcLine = 0; /* Erase VdbeCoverage() macros */ +#endif + p->nOp--; + }else{ + sqlite3VdbeChangeP2(p, addr, p->nOp); + } +} + + +/* +** If the input FuncDef structure is ephemeral, then free it. If +** the FuncDef is not ephemeral, then do nothing. +*/ +static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){ + assert( db!=0 ); + if( (pDef->funcFlags & SQLITE_FUNC_EPHEM)!=0 ){ + sqlite3DbNNFreeNN(db, pDef); + } +} + +/* +** Delete a P4 value if necessary. +*/ +static SQLITE_NOINLINE void freeP4Mem(sqlite3 *db, Mem *p){ + if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); + sqlite3DbNNFreeNN(db, p); +} +static SQLITE_NOINLINE void freeP4FuncCtx(sqlite3 *db, sqlite3_context *p){ + assert( db!=0 ); + freeEphemeralFunction(db, p->pFunc); + sqlite3DbNNFreeNN(db, p); +} +static void freeP4(sqlite3 *db, int p4type, void *p4){ + assert( db ); + switch( p4type ){ + case P4_FUNCCTX: { + freeP4FuncCtx(db, (sqlite3_context*)p4); + break; + } + case P4_REAL: + case P4_INT64: + case P4_DYNAMIC: + case P4_INTARRAY: { + if( p4 ) sqlite3DbNNFreeNN(db, p4); + break; + } + case P4_KEYINFO: { + if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4); + break; + } +#ifdef SQLITE_ENABLE_CURSOR_HINTS + case P4_EXPR: { + sqlite3ExprDelete(db, (Expr*)p4); + break; + } +#endif + case P4_FUNCDEF: { + freeEphemeralFunction(db, (FuncDef*)p4); + break; + } + case P4_MEM: { + if( db->pnBytesFreed==0 ){ + sqlite3ValueFree((sqlite3_value*)p4); + }else{ + freeP4Mem(db, (Mem*)p4); + } + break; + } + case P4_VTAB : { + if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4); + break; + } + case P4_TABLEREF: { + if( db->pnBytesFreed==0 ) sqlite3DeleteTable(db, (Table*)p4); + break; + } + case P4_SUBRTNSIG: { + SubrtnSig *pSig = (SubrtnSig*)p4; + sqlite3DbFree(db, pSig->zAff); + sqlite3DbFree(db, pSig); + break; + } + } +} + +/* +** Free the space allocated for aOp and any p4 values allocated for the +** opcodes contained within. If aOp is not NULL it is assumed to contain +** nOp entries. +*/ +static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){ + assert( nOp>=0 ); + assert( db!=0 ); + if( aOp ){ + Op *pOp = &aOp[nOp-1]; + while(1){ /* Exit via break */ + if( pOp->p4type <= P4_FREE_IF_LE ) freeP4(db, pOp->p4type, pOp->p4.p); +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + sqlite3DbFree(db, pOp->zComment); +#endif + if( pOp==aOp ) break; + pOp--; + } + sqlite3DbNNFreeNN(db, aOp); + } +} + +/* +** Link the SubProgram object passed as the second argument into the linked +** list at Vdbe.pSubProgram. This list is used to delete all sub-program +** objects when the VM is no longer required. +*/ +SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *pVdbe, SubProgram *p){ + p->pNext = pVdbe->pProgram; + pVdbe->pProgram = p; +} + +/* +** Return true if the given Vdbe has any SubPrograms. +*/ +SQLITE_PRIVATE int sqlite3VdbeHasSubProgram(Vdbe *pVdbe){ + return pVdbe->pProgram!=0; +} + +/* +** Change the opcode at addr into OP_Noop +*/ +SQLITE_PRIVATE int sqlite3VdbeChangeToNoop(Vdbe *p, int addr){ + VdbeOp *pOp; + if( p->db->mallocFailed ) return 0; + assert( addr>=0 && addrnOp ); + pOp = &p->aOp[addr]; + freeP4(p->db, pOp->p4type, pOp->p4.p); + pOp->p4type = P4_NOTUSED; + pOp->p4.z = 0; + pOp->opcode = OP_Noop; + return 1; +} + +/* +** If the last opcode is "op" and it is not a jump destination, +** then remove it. Return true if and only if an opcode was removed. +*/ +SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){ + if( p->nOp>0 && p->aOp[p->nOp-1].opcode==op ){ + return sqlite3VdbeChangeToNoop(p, p->nOp-1); + }else{ + return 0; + } +} + +#ifdef SQLITE_DEBUG +/* +** Generate an OP_ReleaseReg opcode to indicate that a range of +** registers, except any identified by mask, are no longer in use. +*/ +SQLITE_PRIVATE void sqlite3VdbeReleaseRegisters( + Parse *pParse, /* Parsing context */ + int iFirst, /* Index of first register to be released */ + int N, /* Number of registers to release */ + u32 mask, /* Mask of registers to NOT release */ + int bUndefine /* If true, mark registers as undefined */ +){ + if( N==0 || OptimizationDisabled(pParse->db, SQLITE_ReleaseReg) ) return; + assert( pParse->pVdbe ); + assert( iFirst>=1 ); + assert( iFirst+N-1<=pParse->nMem ); + if( N<=31 && mask!=0 ){ + while( N>0 && (mask&1)!=0 ){ + mask >>= 1; + iFirst++; + N--; + } + while( N>0 && N<=32 && (mask & MASKBIT32(N-1))!=0 ){ + mask &= ~MASKBIT32(N-1); + N--; + } + } + if( N>0 ){ + sqlite3VdbeAddOp3(pParse->pVdbe, OP_ReleaseReg, iFirst, N, *(int*)&mask); + if( bUndefine ) sqlite3VdbeChangeP5(pParse->pVdbe, 1); + } +} +#endif /* SQLITE_DEBUG */ + +/* +** Change the value of the P4 operand for a specific instruction. +** This routine is useful when a large program is loaded from a +** static array using sqlite3VdbeAddOpList but we want to make a +** few minor changes to the program. +** +** If n>=0 then the P4 operand is dynamic, meaning that a copy of +** the string is made into memory obtained from sqlite3_malloc(). +** A value of n==0 means copy bytes of zP4 up to and including the +** first null byte. If n>0 then copy n+1 bytes of zP4. +** +** Other values of n (P4_STATIC, P4_COLLSEQ etc.) indicate that zP4 points +** to a string or structure that is guaranteed to exist for the lifetime of +** the Vdbe. In these cases we can just copy the pointer. +** +** If addr<0 then change P4 on the most recently inserted instruction. +*/ +static void SQLITE_NOINLINE vdbeChangeP4Full( + Vdbe *p, + Op *pOp, + const char *zP4, + int n +){ + if( pOp->p4type ){ + assert( pOp->p4type > P4_FREE_IF_LE ); + pOp->p4type = 0; + pOp->p4.p = 0; + } + if( n<0 ){ + sqlite3VdbeChangeP4(p, (int)(pOp - p->aOp), zP4, n); + }else{ + if( n==0 ) n = sqlite3Strlen30(zP4); + pOp->p4.z = sqlite3DbStrNDup(p->db, zP4, n); + pOp->p4type = P4_DYNAMIC; + } +} +SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){ + Op *pOp; + sqlite3 *db; + assert( p!=0 ); + db = p->db; + assert( p->eVdbeState==VDBE_INIT_STATE ); + assert( p->aOp!=0 || db->mallocFailed ); + if( db->mallocFailed ){ + if( n!=P4_VTAB ) freeP4(db, n, (void*)*(char**)&zP4); + return; + } + assert( p->nOp>0 ); + assert( addrnOp ); + if( addr<0 ){ + addr = p->nOp - 1; + } + pOp = &p->aOp[addr]; + if( n>=0 || pOp->p4type ){ + vdbeChangeP4Full(p, pOp, zP4, n); + return; + } + if( n==P4_INT32 ){ + /* Note: this cast is safe, because the origin data point was an int + ** that was cast to a (const char *). */ + pOp->p4.i = SQLITE_PTR_TO_INT(zP4); + pOp->p4type = P4_INT32; + }else if( zP4!=0 ){ + assert( n<0 ); + pOp->p4.p = (void*)zP4; + pOp->p4type = (signed char)n; + if( n==P4_VTAB ) sqlite3VtabLock((VTable*)zP4); + } +} + +/* +** Change the P4 operand of the most recently coded instruction +** to the value defined by the arguments. This is a high-speed +** version of sqlite3VdbeChangeP4(). +** +** The P4 operand must not have been previously defined. And the new +** P4 must not be P4_INT32. Use sqlite3VdbeChangeP4() in either of +** those cases. +*/ +SQLITE_PRIVATE void sqlite3VdbeAppendP4(Vdbe *p, void *pP4, int n){ + VdbeOp *pOp; + assert( n!=P4_INT32 && n!=P4_VTAB ); + assert( n<=0 ); + if( p->db->mallocFailed ){ + freeP4(p->db, n, pP4); + }else{ + assert( pP4!=0 || n==P4_DYNAMIC ); + assert( p->nOp>0 ); + pOp = &p->aOp[p->nOp-1]; + assert( pOp->p4type==P4_NOTUSED ); + pOp->p4type = n; + pOp->p4.p = pP4; + } +} + +/* +** Set the P4 on the most recently added opcode to the KeyInfo for the +** index given. +*/ +SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse *pParse, Index *pIdx){ + Vdbe *v = pParse->pVdbe; + KeyInfo *pKeyInfo; + assert( v!=0 ); + assert( pIdx!=0 ); + pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pIdx); + if( pKeyInfo ) sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO); +} + +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS +/* +** Change the comment on the most recently coded instruction. Or +** insert a No-op and add the comment to that new instruction. This +** makes the code easier to read during debugging. None of this happens +** in a production build. +*/ +static void vdbeVComment(Vdbe *p, const char *zFormat, va_list ap){ + assert( p->nOp>0 || p->aOp==0 ); + assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->pParse->nErr>0 ); + if( p->nOp ){ + assert( p->aOp ); + sqlite3DbFree(p->db, p->aOp[p->nOp-1].zComment); + p->aOp[p->nOp-1].zComment = sqlite3VMPrintf(p->db, zFormat, ap); + } +} +SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){ + va_list ap; + if( p ){ + va_start(ap, zFormat); + vdbeVComment(p, zFormat, ap); + va_end(ap); + } +} +SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){ + va_list ap; + if( p ){ + sqlite3VdbeAddOp0(p, OP_Noop); + va_start(ap, zFormat); + vdbeVComment(p, zFormat, ap); + va_end(ap); + } +} +#endif /* NDEBUG */ + +#ifdef SQLITE_VDBE_COVERAGE +/* +** Set the value if the iSrcLine field for the previously coded instruction. +*/ +SQLITE_PRIVATE void sqlite3VdbeSetLineNumber(Vdbe *v, int iLine){ + sqlite3VdbeGetLastOp(v)->iSrcLine = iLine; +} +#endif /* SQLITE_VDBE_COVERAGE */ + +/* +** Return the opcode for a given address. The address must be non-negative. +** See sqlite3VdbeGetLastOp() to get the most recently added opcode. +** +** If a memory allocation error has occurred prior to the calling of this +** routine, then a pointer to a dummy VdbeOp will be returned. That opcode +** is readable but not writable, though it is cast to a writable value. +** The return of a dummy opcode allows the call to continue functioning +** after an OOM fault without having to check to see if the return from +** this routine is a valid pointer. But because the dummy.opcode is 0, +** dummy will never be written to. This is verified by code inspection and +** by running with Valgrind. +*/ +SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){ + /* C89 specifies that the constant "dummy" will be initialized to all + ** zeros, which is correct. MSVC generates a warning, nevertheless. */ + static VdbeOp dummy; /* Ignore the MSVC warning about no initializer */ + assert( p->eVdbeState==VDBE_INIT_STATE ); + assert( (addr>=0 && addrnOp) || p->db->mallocFailed ); + if( p->db->mallocFailed ){ + return (VdbeOp*)&dummy; + }else{ + return &p->aOp[addr]; + } +} + +/* Return the most recently added opcode +*/ +SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetLastOp(Vdbe *p){ + return sqlite3VdbeGetOp(p, p->nOp - 1); +} + +#if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) +/* +** Return an integer value for one of the parameters to the opcode pOp +** determined by character c. +*/ +static int translateP(char c, const Op *pOp){ + if( c=='1' ) return pOp->p1; + if( c=='2' ) return pOp->p2; + if( c=='3' ) return pOp->p3; + if( c=='4' ) return pOp->p4.i; + return pOp->p5; +} + +/* +** Compute a string for the "comment" field of a VDBE opcode listing. +** +** The Synopsis: field in comments in the vdbe.c source file gets converted +** to an extra string that is appended to the sqlite3OpcodeName(). In the +** absence of other comments, this synopsis becomes the comment on the opcode. +** Some translation occurs: +** +** "PX" -> "r[X]" +** "PX@PY" -> "r[X..X+Y-1]" or "r[x]" if y is 0 or 1 +** "PX@PY+1" -> "r[X..X+Y]" or "r[x]" if y is 0 +** "PY..PY" -> "r[X..Y]" or "r[x]" if y<=x +*/ +SQLITE_PRIVATE char *sqlite3VdbeDisplayComment( + sqlite3 *db, /* Optional - Oom error reporting only */ + const Op *pOp, /* The opcode to be commented */ + const char *zP4 /* Previously obtained value for P4 */ +){ + const char *zOpName; + const char *zSynopsis; + int nOpName; + int ii; + char zAlt[50]; + StrAccum x; + + sqlite3StrAccumInit(&x, 0, 0, 0, SQLITE_MAX_LENGTH); + zOpName = sqlite3OpcodeName(pOp->opcode); + nOpName = sqlite3Strlen30(zOpName); + if( zOpName[nOpName+1] ){ + int seenCom = 0; + char c; + zSynopsis = zOpName + nOpName + 1; + if( strncmp(zSynopsis,"IF ",3)==0 ){ + sqlite3_snprintf(sizeof(zAlt), zAlt, "if %s goto P2", zSynopsis+3); + zSynopsis = zAlt; + } + for(ii=0; (c = zSynopsis[ii])!=0; ii++){ + if( c=='P' ){ + c = zSynopsis[++ii]; + if( c=='4' ){ + sqlite3_str_appendall(&x, zP4); + }else if( c=='X' ){ + if( pOp->zComment && pOp->zComment[0] ){ + sqlite3_str_appendall(&x, pOp->zComment); + seenCom = 1; + break; + } + }else{ + int v1 = translateP(c, pOp); + int v2; + if( strncmp(zSynopsis+ii+1, "@P", 2)==0 ){ + ii += 3; + v2 = translateP(zSynopsis[ii], pOp); + if( strncmp(zSynopsis+ii+1,"+1",2)==0 ){ + ii += 2; + v2++; + } + if( v2<2 ){ + sqlite3_str_appendf(&x, "%d", v1); + }else{ + sqlite3_str_appendf(&x, "%d..%d", v1, v1+v2-1); + } + }else if( strncmp(zSynopsis+ii+1, "@NP", 3)==0 ){ + sqlite3_context *pCtx = pOp->p4.pCtx; + if( pOp->p4type!=P4_FUNCCTX || pCtx->argc==1 ){ + sqlite3_str_appendf(&x, "%d", v1); + }else if( pCtx->argc>1 ){ + sqlite3_str_appendf(&x, "%d..%d", v1, v1+pCtx->argc-1); + }else if( x.accError==0 ){ + assert( x.nChar>2 ); + x.nChar -= 2; + ii++; + } + ii += 3; + }else{ + sqlite3_str_appendf(&x, "%d", v1); + if( strncmp(zSynopsis+ii+1, "..P3", 4)==0 && pOp->p3==0 ){ + ii += 4; + } + } + } + }else{ + sqlite3_str_appendchar(&x, 1, c); + } + } + if( !seenCom && pOp->zComment ){ + sqlite3_str_appendf(&x, "; %s", pOp->zComment); + } + }else if( pOp->zComment ){ + sqlite3_str_appendall(&x, pOp->zComment); + } + if( (x.accError & SQLITE_NOMEM)!=0 && db!=0 ){ + sqlite3OomFault(db); + } + return sqlite3StrAccumFinish(&x); +} +#endif /* SQLITE_ENABLE_EXPLAIN_COMMENTS */ + +#if VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) +/* +** Translate the P4.pExpr value for an OP_CursorHint opcode into text +** that can be displayed in the P4 column of EXPLAIN output. +*/ +static void displayP4Expr(StrAccum *p, Expr *pExpr){ + const char *zOp = 0; + switch( pExpr->op ){ + case TK_STRING: + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3_str_appendf(p, "%Q", pExpr->u.zToken); + break; + case TK_INTEGER: + sqlite3_str_appendf(p, "%d", pExpr->u.iValue); + break; + case TK_NULL: + sqlite3_str_appendf(p, "NULL"); + break; + case TK_REGISTER: { + sqlite3_str_appendf(p, "r[%d]", pExpr->iTable); + break; + } + case TK_COLUMN: { + if( pExpr->iColumn<0 ){ + sqlite3_str_appendf(p, "rowid"); + }else{ + sqlite3_str_appendf(p, "c%d", (int)pExpr->iColumn); + } + break; + } + case TK_LT: zOp = "LT"; break; + case TK_LE: zOp = "LE"; break; + case TK_GT: zOp = "GT"; break; + case TK_GE: zOp = "GE"; break; + case TK_NE: zOp = "NE"; break; + case TK_EQ: zOp = "EQ"; break; + case TK_IS: zOp = "IS"; break; + case TK_ISNOT: zOp = "ISNOT"; break; + case TK_AND: zOp = "AND"; break; + case TK_OR: zOp = "OR"; break; + case TK_PLUS: zOp = "ADD"; break; + case TK_STAR: zOp = "MUL"; break; + case TK_MINUS: zOp = "SUB"; break; + case TK_REM: zOp = "REM"; break; + case TK_BITAND: zOp = "BITAND"; break; + case TK_BITOR: zOp = "BITOR"; break; + case TK_SLASH: zOp = "DIV"; break; + case TK_LSHIFT: zOp = "LSHIFT"; break; + case TK_RSHIFT: zOp = "RSHIFT"; break; + case TK_CONCAT: zOp = "CONCAT"; break; + case TK_UMINUS: zOp = "MINUS"; break; + case TK_UPLUS: zOp = "PLUS"; break; + case TK_BITNOT: zOp = "BITNOT"; break; + case TK_NOT: zOp = "NOT"; break; + case TK_ISNULL: zOp = "ISNULL"; break; + case TK_NOTNULL: zOp = "NOTNULL"; break; + + default: + sqlite3_str_appendf(p, "%s", "expr"); + break; + } + + if( zOp ){ + sqlite3_str_appendf(p, "%s(", zOp); + displayP4Expr(p, pExpr->pLeft); + if( pExpr->pRight ){ + sqlite3_str_append(p, ",", 1); + displayP4Expr(p, pExpr->pRight); + } + sqlite3_str_append(p, ")", 1); + } +} +#endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */ + + +#if VDBE_DISPLAY_P4 +/* +** Compute a string that describes the P4 parameter for an opcode. +** Use zTemp for any required temporary buffer space. +*/ +SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){ + char *zP4 = 0; + StrAccum x; + + sqlite3StrAccumInit(&x, 0, 0, 0, SQLITE_MAX_LENGTH); + switch( pOp->p4type ){ + case P4_KEYINFO: { + int j; + KeyInfo *pKeyInfo = pOp->p4.pKeyInfo; + assert( pKeyInfo->aSortFlags!=0 ); + sqlite3_str_appendf(&x, "k(%d", pKeyInfo->nKeyField); + for(j=0; jnKeyField; j++){ + CollSeq *pColl = pKeyInfo->aColl[j]; + const char *zColl = pColl ? pColl->zName : ""; + if( strcmp(zColl, "BINARY")==0 ) zColl = "B"; + sqlite3_str_appendf(&x, ",%s%s%s", + (pKeyInfo->aSortFlags[j] & KEYINFO_ORDER_DESC) ? "-" : "", + (pKeyInfo->aSortFlags[j] & KEYINFO_ORDER_BIGNULL)? "N." : "", + zColl); + } + sqlite3_str_append(&x, ")", 1); + break; + } +#ifdef SQLITE_ENABLE_CURSOR_HINTS + case P4_EXPR: { + displayP4Expr(&x, pOp->p4.pExpr); + break; + } +#endif + case P4_COLLSEQ: { + static const char *const encnames[] = {"?", "8", "16LE", "16BE"}; + CollSeq *pColl = pOp->p4.pColl; + assert( pColl->enc<4 ); + sqlite3_str_appendf(&x, "%.18s-%s", pColl->zName, + encnames[pColl->enc]); + break; + } + case P4_FUNCDEF: { + FuncDef *pDef = pOp->p4.pFunc; + sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg); + break; + } + case P4_FUNCCTX: { + FuncDef *pDef = pOp->p4.pCtx->pFunc; + sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg); + break; + } + case P4_INT64: { + sqlite3_str_appendf(&x, "%lld", *pOp->p4.pI64); + break; + } + case P4_INT32: { + sqlite3_str_appendf(&x, "%d", pOp->p4.i); + break; + } + case P4_REAL: { + sqlite3_str_appendf(&x, "%.16g", *pOp->p4.pReal); + break; + } + case P4_MEM: { + Mem *pMem = pOp->p4.pMem; + if( pMem->flags & MEM_Str ){ + zP4 = pMem->z; + }else if( pMem->flags & (MEM_Int|MEM_IntReal) ){ + sqlite3_str_appendf(&x, "%lld", pMem->u.i); + }else if( pMem->flags & MEM_Real ){ + sqlite3_str_appendf(&x, "%.16g", pMem->u.r); + }else if( pMem->flags & MEM_Null ){ + zP4 = "NULL"; + }else{ + assert( pMem->flags & MEM_Blob ); + zP4 = "(blob)"; + } + break; + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + case P4_VTAB: { + sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab; + sqlite3_str_appendf(&x, "vtab:%p", pVtab); + break; + } +#endif + case P4_INTARRAY: { + u32 i; + u32 *ai = pOp->p4.ai; + u32 n = ai[0]; /* The first element of an INTARRAY is always the + ** count of the number of elements to follow */ + for(i=1; i<=n; i++){ + sqlite3_str_appendf(&x, "%c%u", (i==1 ? '[' : ','), ai[i]); + } + sqlite3_str_append(&x, "]", 1); + break; + } + case P4_SUBPROGRAM: { + zP4 = "program"; + break; + } + case P4_TABLE: { + zP4 = pOp->p4.pTab->zName; + break; + } + case P4_INDEX: { + zP4 = pOp->p4.pIdx->zName; + break; + } + case P4_SUBRTNSIG: { + SubrtnSig *pSig = pOp->p4.pSubrtnSig; + sqlite3_str_appendf(&x, "subrtnsig:%d,%s", pSig->selId, pSig->zAff); + break; + } + default: { + zP4 = pOp->p4.z; + } + } + if( zP4 ) sqlite3_str_appendall(&x, zP4); + if( (x.accError & SQLITE_NOMEM)!=0 ){ + sqlite3OomFault(db); + } + return sqlite3StrAccumFinish(&x); +} +#endif /* VDBE_DISPLAY_P4 */ + +/* +** Declare to the Vdbe that the BTree object at db->aDb[i] is used. +** +** The prepared statements need to know in advance the complete set of +** attached databases that will be use. A mask of these databases +** is maintained in p->btreeMask. The p->lockMask value is the subset of +** p->btreeMask of databases that will require a lock. +*/ +SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe *p, int i){ + assert( i>=0 && idb->nDb && i<(int)sizeof(yDbMask)*8 ); + assert( i<(int)sizeof(p->btreeMask)*8 ); + DbMaskSet(p->btreeMask, i); + if( i!=1 && sqlite3BtreeSharable(p->db->aDb[i].pBt) ){ + DbMaskSet(p->lockMask, i); + } +} + +#if !defined(SQLITE_OMIT_SHARED_CACHE) +/* +** If SQLite is compiled to support shared-cache mode and to be threadsafe, +** this routine obtains the mutex associated with each BtShared structure +** that may be accessed by the VM passed as an argument. In doing so it also +** sets the BtShared.db member of each of the BtShared structures, ensuring +** that the correct busy-handler callback is invoked if required. +** +** If SQLite is not threadsafe but does support shared-cache mode, then +** sqlite3BtreeEnter() is invoked to set the BtShared.db variables +** of all of BtShared structures accessible via the database handle +** associated with the VM. +** +** If SQLite is not threadsafe and does not support shared-cache mode, this +** function is a no-op. +** +** The p->btreeMask field is a bitmask of all btrees that the prepared +** statement p will ever use. Let N be the number of bits in p->btreeMask +** corresponding to btrees that use shared cache. Then the runtime of +** this routine is N*N. But as N is rarely more than 1, this should not +** be a problem. +*/ +SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe *p){ + int i; + sqlite3 *db; + Db *aDb; + int nDb; + if( DbMaskAllZero(p->lockMask) ) return; /* The common case */ + db = p->db; + aDb = db->aDb; + nDb = db->nDb; + for(i=0; ilockMask,i) && ALWAYS(aDb[i].pBt!=0) ){ + sqlite3BtreeEnter(aDb[i].pBt); + } + } +} +#endif + +#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 +/* +** Unlock all of the btrees previously locked by a call to sqlite3VdbeEnter(). +*/ +static SQLITE_NOINLINE void vdbeLeave(Vdbe *p){ + int i; + sqlite3 *db; + Db *aDb; + int nDb; + db = p->db; + aDb = db->aDb; + nDb = db->nDb; + for(i=0; ilockMask,i) && ALWAYS(aDb[i].pBt!=0) ){ + sqlite3BtreeLeave(aDb[i].pBt); + } + } +} +SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe *p){ + if( DbMaskAllZero(p->lockMask) ) return; /* The common case */ + vdbeLeave(p); +} +#endif + +#if defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) +/* +** Print a single opcode. This routine is used for debugging only. +*/ +SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){ + char *zP4; + char *zCom; + sqlite3 dummyDb; + static const char *zFormat1 = "%4d %-13s %4d %4d %4d %-13s %.2X %s\n"; + if( pOut==0 ) pOut = stdout; + sqlite3BeginBenignMalloc(); + dummyDb.mallocFailed = 1; + zP4 = sqlite3VdbeDisplayP4(&dummyDb, pOp); +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + zCom = sqlite3VdbeDisplayComment(0, pOp, zP4); +#else + zCom = 0; +#endif + /* NB: The sqlite3OpcodeName() function is implemented by code created + ** by the mkopcodeh.awk and mkopcodec.awk scripts which extract the + ** information from the vdbe.c source text */ + fprintf(pOut, zFormat1, pc, + sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, + zP4 ? zP4 : "", pOp->p5, + zCom ? zCom : "" + ); + fflush(pOut); + sqlite3_free(zP4); + sqlite3_free(zCom); + sqlite3EndBenignMalloc(); +} +#endif + +/* +** Initialize an array of N Mem element. +** +** This is a high-runner, so only those fields that really do need to +** be initialized are set. The Mem structure is organized so that +** the fields that get initialized are nearby and hopefully on the same +** cache line. +** +** Mem.flags = flags +** Mem.db = db +** Mem.szMalloc = 0 +** +** All other fields of Mem can safely remain uninitialized for now. They +** will be initialized before use. +*/ +static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){ + assert( db!=0 ); + if( N>0 ){ + do{ + p->flags = flags; + p->db = db; + p->szMalloc = 0; +#ifdef SQLITE_DEBUG + p->pScopyFrom = 0; + p->bScopy = 0; +#endif + p++; + }while( (--N)>0 ); + } +} + +/* +** Release auxiliary memory held in an array of N Mem elements. +** +** After this routine returns, all Mem elements in the array will still +** be valid. Those Mem elements that were not holding auxiliary resources +** will be unchanged. Mem elements which had something freed will be +** set to MEM_Undefined. +*/ +static void releaseMemArray(Mem *p, int N){ + if( p && N ){ + Mem *pEnd = &p[N]; + sqlite3 *db = p->db; + assert( db!=0 ); + if( db->pnBytesFreed ){ + do{ + if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); + }while( (++p)flags & MEM_Agg ); + testcase( p->flags & MEM_Dyn ); + if( p->flags&(MEM_Agg|MEM_Dyn) ){ + testcase( (p->flags & MEM_Dyn)!=0 && p->xDel==sqlite3VdbeFrameMemDel ); + sqlite3VdbeMemRelease(p); + p->flags = MEM_Undefined; + }else if( p->szMalloc ){ + sqlite3DbNNFreeNN(db, p->zMalloc); + p->szMalloc = 0; + p->flags = MEM_Undefined; + } +#ifdef SQLITE_DEBUG + else{ + p->flags = MEM_Undefined; + } +#endif + }while( (++p)iFrameMagic!=SQLITE_FRAME_MAGIC ) return 0; + return 1; +} +#endif + + +/* +** This is a destructor on a Mem object (which is really an sqlite3_value) +** that deletes the Frame object that is attached to it as a blob. +** +** This routine does not delete the Frame right away. It merely adds the +** frame to a list of frames to be deleted when the Vdbe halts. +*/ +SQLITE_PRIVATE void sqlite3VdbeFrameMemDel(void *pArg){ + VdbeFrame *pFrame = (VdbeFrame*)pArg; + assert( sqlite3VdbeFrameIsValid(pFrame) ); + pFrame->pParent = pFrame->v->pDelFrame; + pFrame->v->pDelFrame = pFrame; +} + +#if defined(SQLITE_ENABLE_BYTECODE_VTAB) || !defined(SQLITE_OMIT_EXPLAIN) +/* +** Locate the next opcode to be displayed in EXPLAIN or EXPLAIN +** QUERY PLAN output. +** +** Return SQLITE_ROW on success. Return SQLITE_DONE if there are no +** more opcodes to be displayed. +*/ +SQLITE_PRIVATE int sqlite3VdbeNextOpcode( + Vdbe *p, /* The statement being explained */ + Mem *pSub, /* Storage for keeping track of subprogram nesting */ + int eMode, /* 0: normal. 1: EQP. 2: TablesUsed */ + int *piPc, /* IN/OUT: Current rowid. Overwritten with next rowid */ + int *piAddr, /* OUT: Write index into (*paOp)[] here */ + Op **paOp /* OUT: Write the opcode array here */ +){ + int nRow; /* Stop when row count reaches this */ + int nSub = 0; /* Number of sub-vdbes seen so far */ + SubProgram **apSub = 0; /* Array of sub-vdbes */ + int i; /* Next instruction address */ + int rc = SQLITE_OK; /* Result code */ + Op *aOp = 0; /* Opcode array */ + int iPc; /* Rowid. Copy of value in *piPc */ + + /* When the number of output rows reaches nRow, that means the + ** listing has finished and sqlite3_step() should return SQLITE_DONE. + ** nRow is the sum of the number of rows in the main program, plus + ** the sum of the number of rows in all trigger subprograms encountered + ** so far. The nRow value will increase as new trigger subprograms are + ** encountered, but p->pc will eventually catch up to nRow. + */ + nRow = p->nOp; + if( pSub!=0 ){ + if( pSub->flags&MEM_Blob ){ + /* pSub is initiallly NULL. It is initialized to a BLOB by + ** the P4_SUBPROGRAM processing logic below */ + nSub = pSub->n/sizeof(Vdbe*); + apSub = (SubProgram **)pSub->z; + } + for(i=0; inOp; + } + } + iPc = *piPc; + while(1){ /* Loop exits via break */ + i = iPc++; + if( i>=nRow ){ + p->rc = SQLITE_OK; + rc = SQLITE_DONE; + break; + } + if( inOp ){ + /* The rowid is small enough that we are still in the + ** main program. */ + aOp = p->aOp; + }else{ + /* We are currently listing subprograms. Figure out which one and + ** pick up the appropriate opcode. */ + int j; + i -= p->nOp; + assert( apSub!=0 ); + assert( nSub>0 ); + for(j=0; i>=apSub[j]->nOp; j++){ + i -= apSub[j]->nOp; + assert( inOp || j+1aOp; + } + + /* When an OP_Program opcode is encounter (the only opcode that has + ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms + ** kept in p->aMem[9].z to hold the new program - assuming this subprogram + ** has not already been seen. + */ + if( pSub!=0 && aOp[i].p4type==P4_SUBPROGRAM ){ + int nByte = (nSub+1)*sizeof(SubProgram*); + int j; + for(j=0; jrc = sqlite3VdbeMemGrow(pSub, nByte, nSub!=0); + if( p->rc!=SQLITE_OK ){ + rc = SQLITE_ERROR; + break; + } + apSub = (SubProgram **)pSub->z; + apSub[nSub++] = aOp[i].p4.pProgram; + MemSetTypeFlag(pSub, MEM_Blob); + pSub->n = nSub*sizeof(SubProgram*); + nRow += aOp[i].p4.pProgram->nOp; + } + } + if( eMode==0 ) break; +#ifdef SQLITE_ENABLE_BYTECODE_VTAB + if( eMode==2 ){ + Op *pOp = aOp + i; + if( pOp->opcode==OP_OpenRead ) break; + if( pOp->opcode==OP_OpenWrite && (pOp->p5 & OPFLAG_P2ISREG)==0 ) break; + if( pOp->opcode==OP_ReopenIdx ) break; + }else +#endif + { + assert( eMode==1 ); + if( aOp[i].opcode==OP_Explain ) break; + if( aOp[i].opcode==OP_Init && iPc>1 ) break; + } + } + *piPc = iPc; + *piAddr = i; + *paOp = aOp; + return rc; +} +#endif /* SQLITE_ENABLE_BYTECODE_VTAB || !SQLITE_OMIT_EXPLAIN */ + + +/* +** Delete a VdbeFrame object and its contents. VdbeFrame objects are +** allocated by the OP_Program opcode in sqlite3VdbeExec(). +*/ +SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame *p){ + int i; + Mem *aMem = VdbeFrameMem(p); + VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem]; + assert( sqlite3VdbeFrameIsValid(p) ); + for(i=0; inChildCsr; i++){ + if( apCsr[i] ) sqlite3VdbeFreeCursorNN(p->v, apCsr[i]); + } + releaseMemArray(aMem, p->nChildMem); + sqlite3VdbeDeleteAuxData(p->v->db, &p->pAuxData, -1, 0); + sqlite3DbFree(p->v->db, p); +} + +#ifndef SQLITE_OMIT_EXPLAIN +/* +** Give a listing of the program in the virtual machine. +** +** The interface is the same as sqlite3VdbeExec(). But instead of +** running the code, it invokes the callback once for each instruction. +** This feature is used to implement "EXPLAIN". +** +** When p->explain==1, each instruction is listed. When +** p->explain==2, only OP_Explain instructions are listed and these +** are shown in a different format. p->explain==2 is used to implement +** EXPLAIN QUERY PLAN. +** 2018-04-24: In p->explain==2 mode, the OP_Init opcodes of triggers +** are also shown, so that the boundaries between the main program and +** each trigger are clear. +** +** When p->explain==1, first the main program is listed, then each of +** the trigger subprograms are listed one by one. +*/ +SQLITE_PRIVATE int sqlite3VdbeList( + Vdbe *p /* The VDBE */ +){ + Mem *pSub = 0; /* Memory cell hold array of subprogs */ + sqlite3 *db = p->db; /* The database connection */ + int i; /* Loop counter */ + int rc = SQLITE_OK; /* Return code */ + Mem *pMem = &p->aMem[1]; /* First Mem of result set */ + int bListSubprogs = (p->explain==1 || (db->flags & SQLITE_TriggerEQP)!=0); + Op *aOp; /* Array of opcodes */ + Op *pOp; /* Current opcode */ + + assert( p->explain ); + assert( p->eVdbeState==VDBE_RUN_STATE ); + assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM ); + + /* Even though this opcode does not use dynamic strings for + ** the result, result columns may become dynamic if the user calls + ** sqlite3_column_text16(), causing a translation to UTF-16 encoding. + */ + releaseMemArray(pMem, 8); + + if( p->rc==SQLITE_NOMEM ){ + /* This happens if a malloc() inside a call to sqlite3_column_text() or + ** sqlite3_column_text16() failed. */ + sqlite3OomFault(db); + return SQLITE_ERROR; + } + + if( bListSubprogs ){ + /* The first 8 memory cells are used for the result set. So we will + ** commandeer the 9th cell to use as storage for an array of pointers + ** to trigger subprograms. The VDBE is guaranteed to have at least 9 + ** cells. */ + assert( p->nMem>9 ); + pSub = &p->aMem[9]; + }else{ + pSub = 0; + } + + /* Figure out which opcode is next to display */ + rc = sqlite3VdbeNextOpcode(p, pSub, p->explain==2, &p->pc, &i, &aOp); + + if( rc==SQLITE_OK ){ + pOp = aOp + i; + if( AtomicLoad(&db->u1.isInterrupted) ){ + p->rc = SQLITE_INTERRUPT; + rc = SQLITE_ERROR; + sqlite3VdbeError(p, sqlite3ErrStr(p->rc)); + }else{ + char *zP4 = sqlite3VdbeDisplayP4(db, pOp); + if( p->explain==2 ){ + sqlite3VdbeMemSetInt64(pMem, pOp->p1); + sqlite3VdbeMemSetInt64(pMem+1, pOp->p2); + sqlite3VdbeMemSetInt64(pMem+2, pOp->p3); + sqlite3VdbeMemSetStr(pMem+3, zP4, -1, SQLITE_UTF8, sqlite3_free); + assert( p->nResColumn==4 ); + }else{ + sqlite3VdbeMemSetInt64(pMem+0, i); + sqlite3VdbeMemSetStr(pMem+1, (char*)sqlite3OpcodeName(pOp->opcode), + -1, SQLITE_UTF8, SQLITE_STATIC); + sqlite3VdbeMemSetInt64(pMem+2, pOp->p1); + sqlite3VdbeMemSetInt64(pMem+3, pOp->p2); + sqlite3VdbeMemSetInt64(pMem+4, pOp->p3); + /* pMem+5 for p4 is done last */ + sqlite3VdbeMemSetInt64(pMem+6, pOp->p5); +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + { + char *zCom = sqlite3VdbeDisplayComment(db, pOp, zP4); + sqlite3VdbeMemSetStr(pMem+7, zCom, -1, SQLITE_UTF8, sqlite3_free); + } +#else + sqlite3VdbeMemSetNull(pMem+7); +#endif + sqlite3VdbeMemSetStr(pMem+5, zP4, -1, SQLITE_UTF8, sqlite3_free); + assert( p->nResColumn==8 ); + } + p->pResultRow = pMem; + if( db->mallocFailed ){ + p->rc = SQLITE_NOMEM; + rc = SQLITE_ERROR; + }else{ + p->rc = SQLITE_OK; + rc = SQLITE_ROW; + } + } + } + return rc; +} +#endif /* SQLITE_OMIT_EXPLAIN */ + +#ifdef SQLITE_DEBUG +/* +** Print the SQL that was used to generate a VDBE program. +*/ +SQLITE_PRIVATE void sqlite3VdbePrintSql(Vdbe *p){ + const char *z = 0; + if( p->zSql ){ + z = p->zSql; + }else if( p->nOp>=1 ){ + const VdbeOp *pOp = &p->aOp[0]; + if( pOp->opcode==OP_Init && pOp->p4.z!=0 ){ + z = pOp->p4.z; + while( sqlite3Isspace(*z) ) z++; + } + } + if( z ) printf("SQL: [%s]\n", z); +} +#endif + +#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE) +/* +** Print an IOTRACE message showing SQL content. +*/ +SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe *p){ + int nOp = p->nOp; + VdbeOp *pOp; + if( sqlite3IoTrace==0 ) return; + if( nOp<1 ) return; + pOp = &p->aOp[0]; + if( pOp->opcode==OP_Init && pOp->p4.z!=0 ){ + int i, j; + char z[1000]; + sqlite3_snprintf(sizeof(z), z, "%s", pOp->p4.z); + for(i=0; sqlite3Isspace(z[i]); i++){} + for(j=0; z[i]; i++){ + if( sqlite3Isspace(z[i]) ){ + if( z[i-1]!=' ' ){ + z[j++] = ' '; + } + }else{ + z[j++] = z[i]; + } + } + z[j] = 0; + sqlite3IoTrace("SQL %s\n", z); + } +} +#endif /* !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE */ + +/* An instance of this object describes bulk memory available for use +** by subcomponents of a prepared statement. Space is allocated out +** of a ReusableSpace object by the allocSpace() routine below. +*/ +struct ReusableSpace { + u8 *pSpace; /* Available memory */ + sqlite3_int64 nFree; /* Bytes of available memory */ + sqlite3_int64 nNeeded; /* Total bytes that could not be allocated */ +}; + +/* Try to allocate nByte bytes of 8-byte aligned bulk memory for pBuf +** from the ReusableSpace object. Return a pointer to the allocated +** memory on success. If insufficient memory is available in the +** ReusableSpace object, increase the ReusableSpace.nNeeded +** value by the amount needed and return NULL. +** +** If pBuf is not initially NULL, that means that the memory has already +** been allocated by a prior call to this routine, so just return a copy +** of pBuf and leave ReusableSpace unchanged. +** +** This allocator is employed to repurpose unused slots at the end of the +** opcode array of prepared state for other memory needs of the prepared +** statement. +*/ +static void *allocSpace( + struct ReusableSpace *p, /* Bulk memory available for allocation */ + void *pBuf, /* Pointer to a prior allocation */ + sqlite3_int64 nByte /* Bytes of memory needed. */ +){ + assert( EIGHT_BYTE_ALIGNMENT(p->pSpace) ); + if( pBuf==0 ){ + nByte = ROUND8P(nByte); + if( nByte <= p->nFree ){ + p->nFree -= nByte; + pBuf = &p->pSpace[p->nFree]; + }else{ + p->nNeeded += nByte; + } + } + assert( EIGHT_BYTE_ALIGNMENT(pBuf) ); + return pBuf; +} + +/* +** Rewind the VDBE back to the beginning in preparation for +** running it. +*/ +SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){ +#if defined(SQLITE_DEBUG) + int i; +#endif + assert( p!=0 ); + assert( p->eVdbeState==VDBE_INIT_STATE + || p->eVdbeState==VDBE_READY_STATE + || p->eVdbeState==VDBE_HALT_STATE ); + + /* There should be at least one opcode. + */ + assert( p->nOp>0 ); + + p->eVdbeState = VDBE_READY_STATE; + +#ifdef SQLITE_DEBUG + for(i=0; inMem; i++){ + assert( p->aMem[i].db==p->db ); + } +#endif + p->pc = -1; + p->rc = SQLITE_OK; + p->errorAction = OE_Abort; + p->nChange = 0; + p->cacheCtr = 1; + p->minWriteFileFormat = 255; + p->iStatement = 0; + p->nFkConstraint = 0; +#ifdef VDBE_PROFILE + for(i=0; inOp; i++){ + p->aOp[i].nExec = 0; + p->aOp[i].nCycle = 0; + } +#endif +} + +/* +** Prepare a virtual machine for execution for the first time after +** creating the virtual machine. This involves things such +** as allocating registers and initializing the program counter. +** After the VDBE has be prepped, it can be executed by one or more +** calls to sqlite3VdbeExec(). +** +** This function may be called exactly once on each virtual machine. +** After this routine is called the VM has been "packaged" and is ready +** to run. After this routine is called, further calls to +** sqlite3VdbeAddOp() functions are prohibited. This routine disconnects +** the Vdbe from the Parse object that helped generate it so that the +** the Vdbe becomes an independent entity and the Parse object can be +** destroyed. +** +** Use the sqlite3VdbeRewind() procedure to restore a virtual machine back +** to its initial state after it has been run. +*/ +SQLITE_PRIVATE void sqlite3VdbeMakeReady( + Vdbe *p, /* The VDBE */ + Parse *pParse /* Parsing context */ +){ + sqlite3 *db; /* The database connection */ + int nVar; /* Number of parameters */ + int nMem; /* Number of VM memory registers */ + int nCursor; /* Number of cursors required */ + int nArg; /* Max number args to xFilter or xUpdate */ + int n; /* Loop counter */ + struct ReusableSpace x; /* Reusable bulk memory */ + + assert( p!=0 ); + assert( p->nOp>0 ); + assert( pParse!=0 ); + assert( p->eVdbeState==VDBE_INIT_STATE ); + assert( pParse==p->pParse ); + assert( pParse->db==p->db ); + p->pVList = pParse->pVList; + pParse->pVList = 0; + db = p->db; + assert( db->mallocFailed==0 ); + nVar = pParse->nVar; + nMem = pParse->nMem; + nCursor = pParse->nTab; + nArg = pParse->nMaxArg; + + /* Each cursor uses a memory cell. The first cursor (cursor 0) can + ** use aMem[0] which is not otherwise used by the VDBE program. Allocate + ** space at the end of aMem[] for cursors 1 and greater. + ** See also: allocateCursor(). + */ + nMem += nCursor; + if( nCursor==0 && nMem>0 ) nMem++; /* Space for aMem[0] even if not used */ + + /* Figure out how much reusable memory is available at the end of the + ** opcode array. This extra memory will be reallocated for other elements + ** of the prepared statement. + */ + n = ROUND8P(sizeof(Op)*p->nOp); /* Bytes of opcode memory used */ + x.pSpace = &((u8*)p->aOp)[n]; /* Unused opcode memory */ + assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) ); + x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused memory */ + assert( x.nFree>=0 ); + assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) ); + + resolveP2Values(p, &nArg); + p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort); + if( pParse->explain ){ + if( nMem<10 ) nMem = 10; + p->explain = pParse->explain; + p->nResColumn = 12 - 4*p->explain; + } + p->expired = 0; + + /* Memory for registers, parameters, cursor, etc, is allocated in one or two + ** passes. On the first pass, we try to reuse unused memory at the + ** end of the opcode array. If we are unable to satisfy all memory + ** requirements by reusing the opcode array tail, then the second + ** pass will fill in the remainder using a fresh memory allocation. + ** + ** This two-pass approach that reuses as much memory as possible from + ** the leftover memory at the end of the opcode array. This can significantly + ** reduce the amount of memory held by a prepared statement. + */ + x.nNeeded = 0; + p->aMem = allocSpace(&x, 0, nMem*sizeof(Mem)); + p->aVar = allocSpace(&x, 0, nVar*sizeof(Mem)); + p->apArg = allocSpace(&x, 0, nArg*sizeof(Mem*)); + p->apCsr = allocSpace(&x, 0, nCursor*sizeof(VdbeCursor*)); + if( x.nNeeded ){ + x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded); + x.nFree = x.nNeeded; + if( !db->mallocFailed ){ + p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem)); + p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem)); + p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*)); + p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*)); + } + } +#ifdef SQLITE_DEBUG + p->napArg = nArg; +#endif + + if( db->mallocFailed ){ + p->nVar = 0; + p->nCursor = 0; + p->nMem = 0; + }else{ + p->nCursor = nCursor; + p->nVar = (ynVar)nVar; + initMemArray(p->aVar, nVar, db, MEM_Null); + p->nMem = nMem; + initMemArray(p->aMem, nMem, db, MEM_Undefined); + memset(p->apCsr, 0, nCursor*sizeof(VdbeCursor*)); + } + sqlite3VdbeRewind(p); +} + +/* +** Close a VDBE cursor and release all the resources that cursor +** happens to hold. +*/ +SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ + if( pCx ) sqlite3VdbeFreeCursorNN(p,pCx); +} +static SQLITE_NOINLINE void freeCursorWithCache(Vdbe *p, VdbeCursor *pCx){ + VdbeTxtBlbCache *pCache = pCx->pCache; + assert( pCx->colCache ); + pCx->colCache = 0; + pCx->pCache = 0; + if( pCache->pCValue ){ + sqlite3RCStrUnref(pCache->pCValue); + pCache->pCValue = 0; + } + sqlite3DbFree(p->db, pCache); + sqlite3VdbeFreeCursorNN(p, pCx); +} +SQLITE_PRIVATE void sqlite3VdbeFreeCursorNN(Vdbe *p, VdbeCursor *pCx){ + if( pCx->colCache ){ + freeCursorWithCache(p, pCx); + return; + } + switch( pCx->eCurType ){ + case CURTYPE_SORTER: { + sqlite3VdbeSorterClose(p->db, pCx); + break; + } + case CURTYPE_BTREE: { + assert( pCx->uc.pCursor!=0 ); + sqlite3BtreeCloseCursor(pCx->uc.pCursor); + break; + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + case CURTYPE_VTAB: { + sqlite3_vtab_cursor *pVCur = pCx->uc.pVCur; + const sqlite3_module *pModule = pVCur->pVtab->pModule; + assert( pVCur->pVtab->nRef>0 ); + pVCur->pVtab->nRef--; + pModule->xClose(pVCur); + break; + } +#endif + } +} + +/* +** Close all cursors in the current frame. +*/ +static void closeCursorsInFrame(Vdbe *p){ + int i; + for(i=0; inCursor; i++){ + VdbeCursor *pC = p->apCsr[i]; + if( pC ){ + sqlite3VdbeFreeCursorNN(p, pC); + p->apCsr[i] = 0; + } + } +} + +/* +** Copy the values stored in the VdbeFrame structure to its Vdbe. This +** is used, for example, when a trigger sub-program is halted to restore +** control to the main program. +*/ +SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){ + Vdbe *v = pFrame->v; + closeCursorsInFrame(v); + v->aOp = pFrame->aOp; + v->nOp = pFrame->nOp; + v->aMem = pFrame->aMem; + v->nMem = pFrame->nMem; + v->apCsr = pFrame->apCsr; + v->nCursor = pFrame->nCursor; + v->db->lastRowid = pFrame->lastRowid; + v->nChange = pFrame->nChange; + v->db->nChange = pFrame->nDbChange; + sqlite3VdbeDeleteAuxData(v->db, &v->pAuxData, -1, 0); + v->pAuxData = pFrame->pAuxData; + pFrame->pAuxData = 0; + return pFrame->pc; +} + +/* +** Close all cursors. +** +** Also release any dynamic memory held by the VM in the Vdbe.aMem memory +** cell array. This is necessary as the memory cell array may contain +** pointers to VdbeFrame objects, which may in turn contain pointers to +** open cursors. +*/ +static void closeAllCursors(Vdbe *p){ + if( p->pFrame ){ + VdbeFrame *pFrame; + for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); + sqlite3VdbeFrameRestore(pFrame); + p->pFrame = 0; + p->nFrame = 0; + } + assert( p->nFrame==0 ); + closeCursorsInFrame(p); + releaseMemArray(p->aMem, p->nMem); + while( p->pDelFrame ){ + VdbeFrame *pDel = p->pDelFrame; + p->pDelFrame = pDel->pParent; + sqlite3VdbeFrameDelete(pDel); + } + + /* Delete any auxdata allocations made by the VM */ + if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p->db, &p->pAuxData, -1, 0); + assert( p->pAuxData==0 ); +} + +/* +** Set the number of result columns that will be returned by this SQL +** statement. This is now set at compile time, rather than during +** execution of the vdbe program so that sqlite3_column_count() can +** be called on an SQL statement before sqlite3_step(). +*/ +SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){ + int n; + sqlite3 *db = p->db; + + if( p->nResAlloc ){ + releaseMemArray(p->aColName, p->nResAlloc*COLNAME_N); + sqlite3DbFree(db, p->aColName); + } + n = nResColumn*COLNAME_N; + p->nResColumn = p->nResAlloc = (u16)nResColumn; + p->aColName = (Mem*)sqlite3DbMallocRawNN(db, sizeof(Mem)*n ); + if( p->aColName==0 ) return; + initMemArray(p->aColName, n, db, MEM_Null); +} + +/* +** Set the name of the idx'th column to be returned by the SQL statement. +** zName must be a pointer to a nul terminated string. +** +** This call must be made after a call to sqlite3VdbeSetNumCols(). +** +** The final parameter, xDel, must be one of SQLITE_DYNAMIC, SQLITE_STATIC +** or SQLITE_TRANSIENT. If it is SQLITE_DYNAMIC, then the buffer pointed +** to by zName will be freed by sqlite3DbFree() when the vdbe is destroyed. +*/ +SQLITE_PRIVATE int sqlite3VdbeSetColName( + Vdbe *p, /* Vdbe being configured */ + int idx, /* Index of column zName applies to */ + int var, /* One of the COLNAME_* constants */ + const char *zName, /* Pointer to buffer containing name */ + void (*xDel)(void*) /* Memory management strategy for zName */ +){ + int rc; + Mem *pColName; + assert( idxnResAlloc ); + assert( vardb->mallocFailed ){ + assert( !zName || xDel!=SQLITE_DYNAMIC ); + return SQLITE_NOMEM_BKPT; + } + assert( p->aColName!=0 ); + pColName = &(p->aColName[idx+var*p->nResAlloc]); + rc = sqlite3VdbeMemSetText(pColName, zName, -1, xDel); + assert( rc!=0 || !zName || (pColName->flags&MEM_Term)!=0 ); + return rc; +} + +/* +** A read or write transaction may or may not be active on database handle +** db. If a transaction is active, commit it. If there is a +** write-transaction spanning more than one database file, this routine +** takes care of the super-journal trickery. +*/ +static int vdbeCommit(sqlite3 *db, Vdbe *p){ + int i; + int nTrans = 0; /* Number of databases with an active write-transaction + ** that are candidates for a two-phase commit using a + ** super-journal */ + int rc = SQLITE_OK; + int needXcommit = 0; + +#ifdef SQLITE_OMIT_VIRTUALTABLE + /* With this option, sqlite3VtabSync() is defined to be simply + ** SQLITE_OK so p is not used. + */ + UNUSED_PARAMETER(p); +#endif + + /* Before doing anything else, call the xSync() callback for any + ** virtual module tables written in this transaction. This has to + ** be done before determining whether a super-journal file is + ** required, as an xSync() callback may add an attached database + ** to the transaction. + */ + rc = sqlite3VtabSync(db, p); + + /* This loop determines (a) if the commit hook should be invoked and + ** (b) how many database files have open write transactions, not + ** including the temp database. (b) is important because if more than + ** one database file has an open write transaction, a super-journal + ** file is required for an atomic commit. + */ + for(i=0; rc==SQLITE_OK && inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ){ + /* Whether or not a database might need a super-journal depends upon + ** its journal mode (among other things). This matrix determines which + ** journal modes use a super-journal and which do not */ + static const u8 aMJNeeded[] = { + /* DELETE */ 1, + /* PERSIST */ 1, + /* OFF */ 0, + /* TRUNCATE */ 1, + /* MEMORY */ 0, + /* WAL */ 0 + }; + Pager *pPager; /* Pager associated with pBt */ + needXcommit = 1; + sqlite3BtreeEnter(pBt); + pPager = sqlite3BtreePager(pBt); + if( db->aDb[i].safety_level!=PAGER_SYNCHRONOUS_OFF + && aMJNeeded[sqlite3PagerGetJournalMode(pPager)] + && sqlite3PagerIsMemdb(pPager)==0 + ){ + assert( i!=1 ); + nTrans++; + } + rc = sqlite3PagerExclusiveLock(pPager); + sqlite3BtreeLeave(pBt); + } + } + if( rc!=SQLITE_OK ){ + return rc; + } + + /* If there are any write-transactions at all, invoke the commit hook */ + if( needXcommit && db->xCommitCallback ){ + rc = db->xCommitCallback(db->pCommitArg); + if( rc ){ + return SQLITE_CONSTRAINT_COMMITHOOK; + } + } + + /* The simple case - no more than one database file (not counting the + ** TEMP database) has a transaction active. There is no need for the + ** super-journal. + ** + ** If the return value of sqlite3BtreeGetFilename() is a zero length + ** string, it means the main database is :memory: or a temp file. In + ** that case we do not support atomic multi-file commits, so use the + ** simple case then too. + */ + if( 0==sqlite3Strlen30(sqlite3BtreeGetFilename(db->aDb[0].pBt)) + || nTrans<=1 + ){ + if( needXcommit ){ + for(i=0; rc==SQLITE_OK && inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( sqlite3BtreeTxnState(pBt)>=SQLITE_TXN_WRITE ){ + rc = sqlite3BtreeCommitPhaseOne(pBt, 0); + } + } + } + + /* Do the commit only if all databases successfully complete phase 1. + ** If one of the BtreeCommitPhaseOne() calls fails, this indicates an + ** IO error while deleting or truncating a journal file. It is unlikely, + ** but could happen. In this case abandon processing and return the error. + */ + for(i=0; rc==SQLITE_OK && inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + int txn = sqlite3BtreeTxnState(pBt); + if( txn!=SQLITE_TXN_NONE ){ + assert( needXcommit || txn==SQLITE_TXN_READ ); + rc = sqlite3BtreeCommitPhaseTwo(pBt, 0); + } + } + if( rc==SQLITE_OK ){ + sqlite3VtabCommit(db); + } + } + + /* The complex case - There is a multi-file write-transaction active. + ** This requires a super-journal file to ensure the transaction is + ** committed atomically. + */ +#ifndef SQLITE_OMIT_DISKIO + else{ + sqlite3_vfs *pVfs = db->pVfs; + char *zSuper = 0; /* File-name for the super-journal */ + char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt); + sqlite3_file *pSuperJrnl = 0; + i64 offset = 0; + int res; + int retryCount = 0; + int nMainFile; + + /* Select a super-journal file name */ + nMainFile = sqlite3Strlen30(zMainFile); + zSuper = sqlite3MPrintf(db, "%.4c%s%.16c", 0,zMainFile,0); + if( zSuper==0 ) return SQLITE_NOMEM_BKPT; + zSuper += 4; + do { + u32 iRandom; + if( retryCount ){ + if( retryCount>100 ){ + sqlite3_log(SQLITE_FULL, "MJ delete: %s", zSuper); + sqlite3OsDelete(pVfs, zSuper, 0); + break; + }else if( retryCount==1 ){ + sqlite3_log(SQLITE_FULL, "MJ collide: %s", zSuper); + } + } + retryCount++; + sqlite3_randomness(sizeof(iRandom), &iRandom); + sqlite3_snprintf(13, &zSuper[nMainFile], "-mj%06X9%02X", + (iRandom>>8)&0xffffff, iRandom&0xff); + /* The antipenultimate character of the super-journal name must + ** be "9" to avoid name collisions when using 8+3 filenames. */ + assert( zSuper[sqlite3Strlen30(zSuper)-3]=='9' ); + sqlite3FileSuffix3(zMainFile, zSuper); + rc = sqlite3OsAccess(pVfs, zSuper, SQLITE_ACCESS_EXISTS, &res); + }while( rc==SQLITE_OK && res ); + if( rc==SQLITE_OK ){ + /* Open the super-journal. */ + rc = sqlite3OsOpenMalloc(pVfs, zSuper, &pSuperJrnl, + SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE| + SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_SUPER_JOURNAL, 0 + ); + } + if( rc!=SQLITE_OK ){ + sqlite3DbFree(db, zSuper-4); + return rc; + } + + /* Write the name of each database file in the transaction into the new + ** super-journal file. If an error occurs at this point close + ** and delete the super-journal file. All the individual journal files + ** still have 'null' as the super-journal pointer, so they will roll + ** back independently if a failure occurs. + */ + for(i=0; inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ){ + char const *zFile = sqlite3BtreeGetJournalname(pBt); + if( zFile==0 ){ + continue; /* Ignore TEMP and :memory: databases */ + } + assert( zFile[0]!=0 ); + rc = sqlite3OsWrite(pSuperJrnl, zFile, sqlite3Strlen30(zFile)+1,offset); + offset += sqlite3Strlen30(zFile)+1; + if( rc!=SQLITE_OK ){ + sqlite3OsCloseFree(pSuperJrnl); + sqlite3OsDelete(pVfs, zSuper, 0); + sqlite3DbFree(db, zSuper-4); + return rc; + } + } + } + + /* Sync the super-journal file. If the IOCAP_SEQUENTIAL device + ** flag is set this is not required. + */ + if( 0==(sqlite3OsDeviceCharacteristics(pSuperJrnl)&SQLITE_IOCAP_SEQUENTIAL) + && SQLITE_OK!=(rc = sqlite3OsSync(pSuperJrnl, SQLITE_SYNC_NORMAL)) + ){ + sqlite3OsCloseFree(pSuperJrnl); + sqlite3OsDelete(pVfs, zSuper, 0); + sqlite3DbFree(db, zSuper-4); + return rc; + } + + /* Sync all the db files involved in the transaction. The same call + ** sets the super-journal pointer in each individual journal. If + ** an error occurs here, do not delete the super-journal file. + ** + ** If the error occurs during the first call to + ** sqlite3BtreeCommitPhaseOne(), then there is a chance that the + ** super-journal file will be orphaned. But we cannot delete it, + ** in case the super-journal file name was written into the journal + ** file before the failure occurred. + */ + for(i=0; rc==SQLITE_OK && inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + rc = sqlite3BtreeCommitPhaseOne(pBt, zSuper); + } + } + sqlite3OsCloseFree(pSuperJrnl); + assert( rc!=SQLITE_BUSY ); + if( rc!=SQLITE_OK ){ + sqlite3DbFree(db, zSuper-4); + return rc; + } + + /* Delete the super-journal file. This commits the transaction. After + ** doing this the directory is synced again before any individual + ** transaction files are deleted. + */ + rc = sqlite3OsDelete(pVfs, zSuper, 1); + sqlite3DbFree(db, zSuper-4); + zSuper = 0; + if( rc ){ + return rc; + } + + /* All files and directories have already been synced, so the following + ** calls to sqlite3BtreeCommitPhaseTwo() are only closing files and + ** deleting or truncating journals. If something goes wrong while + ** this is happening we don't really care. The integrity of the + ** transaction is already guaranteed, but some stray 'cold' journals + ** may be lying around. Returning an error code won't help matters. + */ + disable_simulated_io_errors(); + sqlite3BeginBenignMalloc(); + for(i=0; inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + sqlite3BtreeCommitPhaseTwo(pBt, 1); + } + } + sqlite3EndBenignMalloc(); + enable_simulated_io_errors(); + + sqlite3VtabCommit(db); + } +#endif + + return rc; +} + +/* +** This routine checks that the sqlite3.nVdbeActive count variable +** matches the number of vdbe's in the list sqlite3.pVdbe that are +** currently active. An assertion fails if the two counts do not match. +** This is an internal self-check only - it is not an essential processing +** step. +** +** This is a no-op if NDEBUG is defined. +*/ +#ifndef NDEBUG +static void checkActiveVdbeCnt(sqlite3 *db){ + Vdbe *p; + int cnt = 0; + int nWrite = 0; + int nRead = 0; + p = db->pVdbe; + while( p ){ + if( sqlite3_stmt_busy((sqlite3_stmt*)p) ){ + cnt++; + if( p->readOnly==0 ) nWrite++; + if( p->bIsReader ) nRead++; + } + p = p->pVNext; + } + assert( cnt==db->nVdbeActive ); + assert( nWrite==db->nVdbeWrite ); + assert( nRead==db->nVdbeRead ); +} +#else +#define checkActiveVdbeCnt(x) +#endif + +/* +** If the Vdbe passed as the first argument opened a statement-transaction, +** close it now. Argument eOp must be either SAVEPOINT_ROLLBACK or +** SAVEPOINT_RELEASE. If it is SAVEPOINT_ROLLBACK, then the statement +** transaction is rolled back. If eOp is SAVEPOINT_RELEASE, then the +** statement transaction is committed. +** +** If an IO error occurs, an SQLITE_IOERR_XXX error code is returned. +** Otherwise SQLITE_OK. +*/ +static SQLITE_NOINLINE int vdbeCloseStatement(Vdbe *p, int eOp){ + sqlite3 *const db = p->db; + int rc = SQLITE_OK; + int i; + const int iSavepoint = p->iStatement-1; + + assert( eOp==SAVEPOINT_ROLLBACK || eOp==SAVEPOINT_RELEASE); + assert( db->nStatement>0 ); + assert( p->iStatement==(db->nStatement+db->nSavepoint) ); + + for(i=0; inDb; i++){ + int rc2 = SQLITE_OK; + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + if( eOp==SAVEPOINT_ROLLBACK ){ + rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_ROLLBACK, iSavepoint); + } + if( rc2==SQLITE_OK ){ + rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_RELEASE, iSavepoint); + } + if( rc==SQLITE_OK ){ + rc = rc2; + } + } + } + db->nStatement--; + p->iStatement = 0; + + if( rc==SQLITE_OK ){ + if( eOp==SAVEPOINT_ROLLBACK ){ + rc = sqlite3VtabSavepoint(db, SAVEPOINT_ROLLBACK, iSavepoint); + } + if( rc==SQLITE_OK ){ + rc = sqlite3VtabSavepoint(db, SAVEPOINT_RELEASE, iSavepoint); + } + } + + /* If the statement transaction is being rolled back, also restore the + ** database handles deferred constraint counter to the value it had when + ** the statement transaction was opened. */ + if( eOp==SAVEPOINT_ROLLBACK ){ + db->nDeferredCons = p->nStmtDefCons; + db->nDeferredImmCons = p->nStmtDefImmCons; + } + return rc; +} +SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){ + if( p->db->nStatement && p->iStatement ){ + return vdbeCloseStatement(p, eOp); + } + return SQLITE_OK; +} + + +/* +** These functions are called when a transaction opened by the database +** handle associated with the VM passed as an argument is about to be +** committed. If there are outstanding foreign key constraint violations +** return an error code. Otherwise, SQLITE_OK. +** +** If there are outstanding FK violations and this function returns +** non-zero, set the result of the VM to SQLITE_CONSTRAINT_FOREIGNKEY +** and write an error message to it. +*/ +#ifndef SQLITE_OMIT_FOREIGN_KEY +static SQLITE_NOINLINE int vdbeFkError(Vdbe *p){ + p->rc = SQLITE_CONSTRAINT_FOREIGNKEY; + p->errorAction = OE_Abort; + sqlite3VdbeError(p, "FOREIGN KEY constraint failed"); + if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)==0 ) return SQLITE_ERROR; + return SQLITE_CONSTRAINT_FOREIGNKEY; +} +SQLITE_PRIVATE int sqlite3VdbeCheckFkImmediate(Vdbe *p){ + if( p->nFkConstraint==0 ) return SQLITE_OK; + return vdbeFkError(p); +} +SQLITE_PRIVATE int sqlite3VdbeCheckFkDeferred(Vdbe *p){ + sqlite3 *db = p->db; + if( (db->nDeferredCons+db->nDeferredImmCons)==0 ) return SQLITE_OK; + return vdbeFkError(p); +} +#endif + +/* +** This routine is called the when a VDBE tries to halt. If the VDBE +** has made changes and is in autocommit mode, then commit those +** changes. If a rollback is needed, then do the rollback. +** +** This routine is the only way to move the sqlite3eOpenState of a VM from +** SQLITE_STATE_RUN to SQLITE_STATE_HALT. It is harmless to +** call this on a VM that is in the SQLITE_STATE_HALT state. +** +** Return an error code. If the commit could not complete because of +** lock contention, return SQLITE_BUSY. If SQLITE_BUSY is returned, it +** means the close did not happen and needs to be repeated. +*/ +SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ + int rc; /* Used to store transient return codes */ + sqlite3 *db = p->db; + + /* This function contains the logic that determines if a statement or + ** transaction will be committed or rolled back as a result of the + ** execution of this virtual machine. + ** + ** If any of the following errors occur: + ** + ** SQLITE_NOMEM + ** SQLITE_IOERR + ** SQLITE_FULL + ** SQLITE_INTERRUPT + ** + ** Then the internal cache might have been left in an inconsistent + ** state. We need to rollback the statement transaction, if there is + ** one, or the complete transaction if there is no statement transaction. + */ + + assert( p->eVdbeState==VDBE_RUN_STATE ); + if( db->mallocFailed ){ + p->rc = SQLITE_NOMEM_BKPT; + } + closeAllCursors(p); + checkActiveVdbeCnt(db); + + /* No commit or rollback needed if the program never started or if the + ** SQL statement does not read or write a database file. */ + if( p->bIsReader ){ + int mrc; /* Primary error code from p->rc */ + int eStatementOp = 0; + int isSpecialError; /* Set to true if a 'special' error */ + + /* Lock all btrees used by the statement */ + sqlite3VdbeEnter(p); + + /* Check for one of the special errors */ + if( p->rc ){ + mrc = p->rc & 0xff; + isSpecialError = mrc==SQLITE_NOMEM + || mrc==SQLITE_IOERR + || mrc==SQLITE_INTERRUPT + || mrc==SQLITE_FULL; + }else{ + mrc = isSpecialError = 0; + } + if( isSpecialError ){ + /* If the query was read-only and the error code is SQLITE_INTERRUPT, + ** no rollback is necessary. Otherwise, at least a savepoint + ** transaction must be rolled back to restore the database to a + ** consistent state. + ** + ** Even if the statement is read-only, it is important to perform + ** a statement or transaction rollback operation. If the error + ** occurred while writing to the journal, sub-journal or database + ** file as part of an effort to free up cache space (see function + ** pagerStress() in pager.c), the rollback is required to restore + ** the pager to a consistent state. + */ + if( !p->readOnly || mrc!=SQLITE_INTERRUPT ){ + if( (mrc==SQLITE_NOMEM || mrc==SQLITE_FULL) && p->usesStmtJournal ){ + eStatementOp = SAVEPOINT_ROLLBACK; + }else{ + /* We are forced to roll back the active transaction. Before doing + ** so, abort any other statements this handle currently has active. + */ + sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); + sqlite3CloseSavepoints(db); + db->autoCommit = 1; + p->nChange = 0; + } + } + } + + /* Check for immediate foreign key violations. */ + if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){ + (void)sqlite3VdbeCheckFkImmediate(p); + } + + /* If the auto-commit flag is set and this is the only active writer + ** VM, then we do either a commit or rollback of the current transaction. + ** + ** Note: This block also runs if one of the special errors handled + ** above has occurred. + */ + if( !sqlite3VtabInSync(db) + && db->autoCommit + && db->nVdbeWrite==(p->readOnly==0) + ){ + if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){ + rc = sqlite3VdbeCheckFkDeferred(p); + if( rc!=SQLITE_OK ){ + if( NEVER(p->readOnly) ){ + sqlite3VdbeLeave(p); + return SQLITE_ERROR; + } + rc = SQLITE_CONSTRAINT_FOREIGNKEY; + }else if( db->flags & SQLITE_CorruptRdOnly ){ + rc = SQLITE_CORRUPT; + db->flags &= ~SQLITE_CorruptRdOnly; + }else{ + /* The auto-commit flag is true, the vdbe program was successful + ** or hit an 'OR FAIL' constraint and there are no deferred foreign + ** key constraints to hold up the transaction. This means a commit + ** is required. */ + rc = vdbeCommit(db, p); + } + if( rc==SQLITE_BUSY && p->readOnly ){ + sqlite3VdbeLeave(p); + return SQLITE_BUSY; + }else if( rc!=SQLITE_OK ){ + sqlite3SystemError(db, rc); + p->rc = rc; + sqlite3RollbackAll(db, SQLITE_OK); + p->nChange = 0; + }else{ + db->nDeferredCons = 0; + db->nDeferredImmCons = 0; + db->flags &= ~(u64)SQLITE_DeferFKs; + sqlite3CommitInternalChanges(db); + } + }else if( p->rc==SQLITE_SCHEMA && db->nVdbeActive>1 ){ + p->nChange = 0; + }else{ + sqlite3RollbackAll(db, SQLITE_OK); + p->nChange = 0; + } + db->nStatement = 0; + }else if( eStatementOp==0 ){ + if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){ + eStatementOp = SAVEPOINT_RELEASE; + }else if( p->errorAction==OE_Abort ){ + eStatementOp = SAVEPOINT_ROLLBACK; + }else{ + sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); + sqlite3CloseSavepoints(db); + db->autoCommit = 1; + p->nChange = 0; + } + } + + /* If eStatementOp is non-zero, then a statement transaction needs to + ** be committed or rolled back. Call sqlite3VdbeCloseStatement() to + ** do so. If this operation returns an error, and the current statement + ** error code is SQLITE_OK or SQLITE_CONSTRAINT, then promote the + ** current statement error code. + */ + if( eStatementOp ){ + rc = sqlite3VdbeCloseStatement(p, eStatementOp); + if( rc ){ + if( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT ){ + p->rc = rc; + sqlite3DbFree(db, p->zErrMsg); + p->zErrMsg = 0; + } + sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); + sqlite3CloseSavepoints(db); + db->autoCommit = 1; + p->nChange = 0; + } + } + + /* If this was an INSERT, UPDATE or DELETE and no statement transaction + ** has been rolled back, update the database connection change-counter. + */ + if( p->changeCntOn ){ + if( eStatementOp!=SAVEPOINT_ROLLBACK ){ + sqlite3VdbeSetChanges(db, p->nChange); + }else{ + sqlite3VdbeSetChanges(db, 0); + } + p->nChange = 0; + } + + /* Release the locks */ + sqlite3VdbeLeave(p); + } + + /* We have successfully halted and closed the VM. Record this fact. */ + db->nVdbeActive--; + if( !p->readOnly ) db->nVdbeWrite--; + if( p->bIsReader ) db->nVdbeRead--; + assert( db->nVdbeActive>=db->nVdbeRead ); + assert( db->nVdbeRead>=db->nVdbeWrite ); + assert( db->nVdbeWrite>=0 ); + p->eVdbeState = VDBE_HALT_STATE; + checkActiveVdbeCnt(db); + if( db->mallocFailed ){ + p->rc = SQLITE_NOMEM_BKPT; + } + + /* If the auto-commit flag is set to true, then any locks that were held + ** by connection db have now been released. Call sqlite3ConnectionUnlocked() + ** to invoke any required unlock-notify callbacks. + */ + if( db->autoCommit ){ + sqlite3ConnectionUnlocked(db); + } + + assert( db->nVdbeActive>0 || db->autoCommit==0 || db->nStatement==0 ); + return (p->rc==SQLITE_BUSY ? SQLITE_BUSY : SQLITE_OK); +} + + +/* +** Each VDBE holds the result of the most recent sqlite3_step() call +** in p->rc. This routine sets that result back to SQLITE_OK. +*/ +SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe *p){ + p->rc = SQLITE_OK; +} + +/* +** Copy the error code and error message belonging to the VDBE passed +** as the first argument to its database handle (so that they will be +** returned by calls to sqlite3_errcode() and sqlite3_errmsg()). +** +** This function does not clear the VDBE error code or message, just +** copies them to the database handle. +*/ +SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p){ + sqlite3 *db = p->db; + int rc = p->rc; + if( p->zErrMsg ){ + db->bBenignMalloc++; + sqlite3BeginBenignMalloc(); + if( db->pErr==0 ) db->pErr = sqlite3ValueNew(db); + sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT); + sqlite3EndBenignMalloc(); + db->bBenignMalloc--; + }else if( db->pErr ){ + sqlite3ValueSetNull(db->pErr); + } + db->errCode = rc; + db->errByteOffset = -1; + return rc; +} + +#ifdef SQLITE_ENABLE_SQLLOG +/* +** If an SQLITE_CONFIG_SQLLOG hook is registered and the VM has been run, +** invoke it. +*/ +static void vdbeInvokeSqllog(Vdbe *v){ + if( sqlite3GlobalConfig.xSqllog && v->rc==SQLITE_OK && v->zSql && v->pc>=0 ){ + char *zExpanded = sqlite3VdbeExpandSql(v, v->zSql); + assert( v->db->init.busy==0 ); + if( zExpanded ){ + sqlite3GlobalConfig.xSqllog( + sqlite3GlobalConfig.pSqllogArg, v->db, zExpanded, 1 + ); + sqlite3DbFree(v->db, zExpanded); + } + } +} +#else +# define vdbeInvokeSqllog(x) +#endif + +/* +** Clean up a VDBE after execution but do not delete the VDBE just yet. +** Write any error messages into *pzErrMsg. Return the result code. +** +** After this routine is run, the VDBE should be ready to be executed +** again. +** +** To look at it another way, this routine resets the state of the +** virtual machine from VDBE_RUN_STATE or VDBE_HALT_STATE back to +** VDBE_READY_STATE. +*/ +SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){ +#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) + int i; +#endif + + sqlite3 *db; + db = p->db; + + /* If the VM did not run to completion or if it encountered an + ** error, then it might not have been halted properly. So halt + ** it now. + */ + if( p->eVdbeState==VDBE_RUN_STATE ) sqlite3VdbeHalt(p); + + /* If the VDBE has been run even partially, then transfer the error code + ** and error message from the VDBE into the main database structure. But + ** if the VDBE has just been set to run but has not actually executed any + ** instructions yet, leave the main database error information unchanged. + */ + if( p->pc>=0 ){ + vdbeInvokeSqllog(p); + if( db->pErr || p->zErrMsg ){ + sqlite3VdbeTransferError(p); + }else{ + db->errCode = p->rc; + } + } + + /* Reset register contents and reclaim error message memory. + */ +#ifdef SQLITE_DEBUG + /* Execute assert() statements to ensure that the Vdbe.apCsr[] and + ** Vdbe.aMem[] arrays have already been cleaned up. */ + if( p->apCsr ) for(i=0; inCursor; i++) assert( p->apCsr[i]==0 ); + if( p->aMem ){ + for(i=0; inMem; i++) assert( p->aMem[i].flags==MEM_Undefined ); + } +#endif + if( p->zErrMsg ){ + sqlite3DbFree(db, p->zErrMsg); + p->zErrMsg = 0; + } + p->pResultRow = 0; +#ifdef SQLITE_DEBUG + p->nWrite = 0; +#endif + + /* Save profiling information from this VDBE run. + */ +#ifdef VDBE_PROFILE + { + FILE *out = fopen("vdbe_profile.out", "a"); + if( out ){ + fprintf(out, "---- "); + for(i=0; inOp; i++){ + fprintf(out, "%02x", p->aOp[i].opcode); + } + fprintf(out, "\n"); + if( p->zSql ){ + char c, pc = 0; + fprintf(out, "-- "); + for(i=0; (c = p->zSql[i])!=0; i++){ + if( pc=='\n' ) fprintf(out, "-- "); + putc(c, out); + pc = c; + } + if( pc!='\n' ) fprintf(out, "\n"); + } + for(i=0; inOp; i++){ + char zHdr[100]; + i64 cnt = p->aOp[i].nExec; + i64 cycles = p->aOp[i].nCycle; + sqlite3_snprintf(sizeof(zHdr), zHdr, "%6u %12llu %8llu ", + cnt, + cycles, + cnt>0 ? cycles/cnt : 0 + ); + fprintf(out, "%s", zHdr); + sqlite3VdbePrintOp(out, i, &p->aOp[i]); + } + fclose(out); + } + } +#endif + return p->rc & db->errMask; +} + +/* +** Clean up and delete a VDBE after execution. Return an integer which is +** the result code. Write any error message text into *pzErrMsg. +*/ +SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe *p){ + int rc = SQLITE_OK; + assert( VDBE_RUN_STATE>VDBE_READY_STATE ); + assert( VDBE_HALT_STATE>VDBE_READY_STATE ); + assert( VDBE_INIT_STATEeVdbeState>=VDBE_READY_STATE ){ + rc = sqlite3VdbeReset(p); + assert( (rc & p->db->errMask)==rc ); + } + sqlite3VdbeDelete(p); + return rc; +} + +/* +** If parameter iOp is less than zero, then invoke the destructor for +** all auxiliary data pointers currently cached by the VM passed as +** the first argument. +** +** Or, if iOp is greater than or equal to zero, then the destructor is +** only invoked for those auxiliary data pointers created by the user +** function invoked by the OP_Function opcode at instruction iOp of +** VM pVdbe, and only then if: +** +** * the associated function parameter is the 32nd or later (counting +** from left to right), or +** +** * the corresponding bit in argument mask is clear (where the first +** function parameter corresponds to bit 0 etc.). +*/ +SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3 *db, AuxData **pp, int iOp, int mask){ + while( *pp ){ + AuxData *pAux = *pp; + if( (iOp<0) + || (pAux->iAuxOp==iOp + && pAux->iAuxArg>=0 + && (pAux->iAuxArg>31 || !(mask & MASKBIT32(pAux->iAuxArg)))) + ){ + testcase( pAux->iAuxArg==31 ); + if( pAux->xDeleteAux ){ + pAux->xDeleteAux(pAux->pAux); + } + *pp = pAux->pNextAux; + sqlite3DbFree(db, pAux); + }else{ + pp= &pAux->pNextAux; + } + } +} + +/* +** Free all memory associated with the Vdbe passed as the second argument, +** except for object itself, which is preserved. +** +** The difference between this function and sqlite3VdbeDelete() is that +** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with +** the database connection and frees the object itself. +*/ +static void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ + SubProgram *pSub, *pNext; + assert( db!=0 ); + assert( p->db==0 || p->db==db ); + if( p->aColName ){ + releaseMemArray(p->aColName, p->nResAlloc*COLNAME_N); + sqlite3DbNNFreeNN(db, p->aColName); + } + for(pSub=p->pProgram; pSub; pSub=pNext){ + pNext = pSub->pNext; + vdbeFreeOpArray(db, pSub->aOp, pSub->nOp); + sqlite3DbFree(db, pSub); + } + if( p->eVdbeState!=VDBE_INIT_STATE ){ + releaseMemArray(p->aVar, p->nVar); + if( p->pVList ) sqlite3DbNNFreeNN(db, p->pVList); + if( p->pFree ) sqlite3DbNNFreeNN(db, p->pFree); + } + vdbeFreeOpArray(db, p->aOp, p->nOp); + if( p->zSql ) sqlite3DbNNFreeNN(db, p->zSql); +#ifdef SQLITE_ENABLE_NORMALIZE + sqlite3DbFree(db, p->zNormSql); + { + DblquoteStr *pThis, *pNxt; + for(pThis=p->pDblStr; pThis; pThis=pNxt){ + pNxt = pThis->pNextStr; + sqlite3DbFree(db, pThis); + } + } +#endif +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + { + int i; + for(i=0; inScan; i++){ + sqlite3DbFree(db, p->aScan[i].zName); + } + sqlite3DbFree(db, p->aScan); + } +#endif +} + +/* +** Delete an entire VDBE. +*/ +SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){ + sqlite3 *db; + + assert( p!=0 ); + db = p->db; + assert( db!=0 ); + assert( sqlite3_mutex_held(db->mutex) ); + sqlite3VdbeClearObject(db, p); + if( db->pnBytesFreed==0 ){ + assert( p->ppVPrev!=0 ); + *p->ppVPrev = p->pVNext; + if( p->pVNext ){ + p->pVNext->ppVPrev = p->ppVPrev; + } + } + sqlite3DbNNFreeNN(db, p); +} + +/* +** The cursor "p" has a pending seek operation that has not yet been +** carried out. Seek the cursor now. If an error occurs, return +** the appropriate error code. +*/ +SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor *p){ + int res, rc; +#ifdef SQLITE_TEST + extern int sqlite3_search_count; +#endif + assert( p->deferredMoveto ); + assert( p->isTable ); + assert( p->eCurType==CURTYPE_BTREE ); + rc = sqlite3BtreeTableMoveto(p->uc.pCursor, p->movetoTarget, 0, &res); + if( rc ) return rc; + if( res!=0 ) return SQLITE_CORRUPT_BKPT; +#ifdef SQLITE_TEST + sqlite3_search_count++; +#endif + p->deferredMoveto = 0; + p->cacheStatus = CACHE_STALE; + return SQLITE_OK; +} + +/* +** Something has moved cursor "p" out of place. Maybe the row it was +** pointed to was deleted out from under it. Or maybe the btree was +** rebalanced. Whatever the cause, try to restore "p" to the place it +** is supposed to be pointing. If the row was deleted out from under the +** cursor, set the cursor to point to a NULL row. +*/ +SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeHandleMovedCursor(VdbeCursor *p){ + int isDifferentRow, rc; + assert( p->eCurType==CURTYPE_BTREE ); + assert( p->uc.pCursor!=0 ); + assert( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ); + rc = sqlite3BtreeCursorRestore(p->uc.pCursor, &isDifferentRow); + p->cacheStatus = CACHE_STALE; + if( isDifferentRow ) p->nullRow = 1; + return rc; +} + +/* +** Check to ensure that the cursor is valid. Restore the cursor +** if need be. Return any I/O error from the restore operation. +*/ +SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){ + assert( p->eCurType==CURTYPE_BTREE || IsNullCursor(p) ); + if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){ + return sqlite3VdbeHandleMovedCursor(p); + } + return SQLITE_OK; +} + +/* +** The following functions: +** +** sqlite3VdbeSerialType() +** sqlite3VdbeSerialTypeLen() +** sqlite3VdbeSerialLen() +** sqlite3VdbeSerialPut() <--- in-lined into OP_MakeRecord as of 2022-04-02 +** sqlite3VdbeSerialGet() +** +** encapsulate the code that serializes values for storage in SQLite +** data and index records. Each serialized value consists of a +** 'serial-type' and a blob of data. The serial type is an 8-byte unsigned +** integer, stored as a varint. +** +** In an SQLite index record, the serial type is stored directly before +** the blob of data that it corresponds to. In a table record, all serial +** types are stored at the start of the record, and the blobs of data at +** the end. Hence these functions allow the caller to handle the +** serial-type and data blob separately. +** +** The following table describes the various storage classes for data: +** +** serial type bytes of data type +** -------------- --------------- --------------- +** 0 0 NULL +** 1 1 signed integer +** 2 2 signed integer +** 3 3 signed integer +** 4 4 signed integer +** 5 6 signed integer +** 6 8 signed integer +** 7 8 IEEE float +** 8 0 Integer constant 0 +** 9 0 Integer constant 1 +** 10,11 reserved for expansion +** N>=12 and even (N-12)/2 BLOB +** N>=13 and odd (N-13)/2 text +** +** The 8 and 9 types were added in 3.3.0, file format 4. Prior versions +** of SQLite will not understand those serial types. +*/ + +#if 0 /* Inlined into the OP_MakeRecord opcode */ +/* +** Return the serial-type for the value stored in pMem. +** +** This routine might convert a large MEM_IntReal value into MEM_Real. +** +** 2019-07-11: The primary user of this subroutine was the OP_MakeRecord +** opcode in the byte-code engine. But by moving this routine in-line, we +** can omit some redundant tests and make that opcode a lot faster. So +** this routine is now only used by the STAT3 logic and STAT3 support has +** ended. The code is kept here for historical reference only. +*/ +SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){ + int flags = pMem->flags; + u32 n; + + assert( pLen!=0 ); + if( flags&MEM_Null ){ + *pLen = 0; + return 0; + } + if( flags&(MEM_Int|MEM_IntReal) ){ + /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */ +# define MAX_6BYTE ((((i64)0x00008000)<<32)-1) + i64 i = pMem->u.i; + u64 u; + testcase( flags & MEM_Int ); + testcase( flags & MEM_IntReal ); + if( i<0 ){ + u = ~i; + }else{ + u = i; + } + if( u<=127 ){ + if( (i&1)==i && file_format>=4 ){ + *pLen = 0; + return 8+(u32)u; + }else{ + *pLen = 1; + return 1; + } + } + if( u<=32767 ){ *pLen = 2; return 2; } + if( u<=8388607 ){ *pLen = 3; return 3; } + if( u<=2147483647 ){ *pLen = 4; return 4; } + if( u<=MAX_6BYTE ){ *pLen = 6; return 5; } + *pLen = 8; + if( flags&MEM_IntReal ){ + /* If the value is IntReal and is going to take up 8 bytes to store + ** as an integer, then we might as well make it an 8-byte floating + ** point value */ + pMem->u.r = (double)pMem->u.i; + pMem->flags &= ~MEM_IntReal; + pMem->flags |= MEM_Real; + return 7; + } + return 6; + } + if( flags&MEM_Real ){ + *pLen = 8; + return 7; + } + assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) ); + assert( pMem->n>=0 ); + n = (u32)pMem->n; + if( flags & MEM_Zero ){ + n += pMem->u.nZero; + } + *pLen = n; + return ((n*2) + 12 + ((flags&MEM_Str)!=0)); +} +#endif /* inlined into OP_MakeRecord */ + +/* +** The sizes for serial types less than 128 +*/ +SQLITE_PRIVATE const u8 sqlite3SmallTypeSizes[128] = { + /* 0 1 2 3 4 5 6 7 8 9 */ +/* 0 */ 0, 1, 2, 3, 4, 6, 8, 8, 0, 0, +/* 10 */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, +/* 20 */ 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, +/* 30 */ 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, +/* 40 */ 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, +/* 50 */ 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, +/* 60 */ 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, +/* 70 */ 29, 29, 30, 30, 31, 31, 32, 32, 33, 33, +/* 80 */ 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, +/* 90 */ 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, +/* 100 */ 44, 44, 45, 45, 46, 46, 47, 47, 48, 48, +/* 110 */ 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, +/* 120 */ 54, 54, 55, 55, 56, 56, 57, 57 +}; + +/* +** Return the length of the data corresponding to the supplied serial-type. +*/ +SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32 serial_type){ + if( serial_type>=128 ){ + return (serial_type-12)/2; + }else{ + assert( serial_type<12 + || sqlite3SmallTypeSizes[serial_type]==(serial_type - 12)/2 ); + return sqlite3SmallTypeSizes[serial_type]; + } +} +SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8 serial_type){ + assert( serial_type<128 ); + return sqlite3SmallTypeSizes[serial_type]; +} + +/* +** If we are on an architecture with mixed-endian floating +** points (ex: ARM7) then swap the lower 4 bytes with the +** upper 4 bytes. Return the result. +** +** For most architectures, this is a no-op. +** +** (later): It is reported to me that the mixed-endian problem +** on ARM7 is an issue with GCC, not with the ARM7 chip. It seems +** that early versions of GCC stored the two words of a 64-bit +** float in the wrong order. And that error has been propagated +** ever since. The blame is not necessarily with GCC, though. +** GCC might have just copying the problem from a prior compiler. +** I am also told that newer versions of GCC that follow a different +** ABI get the byte order right. +** +** Developers using SQLite on an ARM7 should compile and run their +** application using -DSQLITE_DEBUG=1 at least once. With DEBUG +** enabled, some asserts below will ensure that the byte order of +** floating point values is correct. +** +** (2007-08-30) Frank van Vugt has studied this problem closely +** and has send his findings to the SQLite developers. Frank +** writes that some Linux kernels offer floating point hardware +** emulation that uses only 32-bit mantissas instead of a full +** 48-bits as required by the IEEE standard. (This is the +** CONFIG_FPE_FASTFPE option.) On such systems, floating point +** byte swapping becomes very complicated. To avoid problems, +** the necessary byte swapping is carried out using a 64-bit integer +** rather than a 64-bit float. Frank assures us that the code here +** works for him. We, the developers, have no way to independently +** verify this, but Frank seems to know what he is talking about +** so we trust him. +*/ +#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT +SQLITE_PRIVATE u64 sqlite3FloatSwap(u64 in){ + union { + u64 r; + u32 i[2]; + } u; + u32 t; + + u.r = in; + t = u.i[0]; + u.i[0] = u.i[1]; + u.i[1] = t; + return u.r; +} +#endif /* SQLITE_MIXED_ENDIAN_64BIT_FLOAT */ + + +/* Input "x" is a sequence of unsigned characters that represent a +** big-endian integer. Return the equivalent native integer +*/ +#define ONE_BYTE_INT(x) ((i8)(x)[0]) +#define TWO_BYTE_INT(x) (256*(i8)((x)[0])|(x)[1]) +#define THREE_BYTE_INT(x) (65536*(i8)((x)[0])|((x)[1]<<8)|(x)[2]) +#define FOUR_BYTE_UINT(x) (((u32)(x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3]) +#define FOUR_BYTE_INT(x) (16777216*(i8)((x)[0])|((x)[1]<<16)|((x)[2]<<8)|(x)[3]) + +/* +** Deserialize the data blob pointed to by buf as serial type serial_type +** and store the result in pMem. +** +** This function is implemented as two separate routines for performance. +** The few cases that require local variables are broken out into a separate +** routine so that in most cases the overhead of moving the stack pointer +** is avoided. +*/ +static void serialGet( + const unsigned char *buf, /* Buffer to deserialize from */ + u32 serial_type, /* Serial type to deserialize */ + Mem *pMem /* Memory cell to write value into */ +){ + u64 x = FOUR_BYTE_UINT(buf); + u32 y = FOUR_BYTE_UINT(buf+4); + x = (x<<32) + y; + if( serial_type==6 ){ + /* EVIDENCE-OF: R-29851-52272 Value is a big-endian 64-bit + ** twos-complement integer. */ + pMem->u.i = *(i64*)&x; + pMem->flags = MEM_Int; + testcase( pMem->u.i<0 ); + }else{ + /* EVIDENCE-OF: R-57343-49114 Value is a big-endian IEEE 754-2008 64-bit + ** floating point number. */ +#if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT) + /* Verify that integers and floating point values use the same + ** byte order. Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is + ** defined that 64-bit floating point values really are mixed + ** endian. + */ + static const u64 t1 = ((u64)0x3ff00000)<<32; + static const double r1 = 1.0; + u64 t2 = t1; + swapMixedEndianFloat(t2); + assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 ); +#endif + assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 ); + swapMixedEndianFloat(x); + memcpy(&pMem->u.r, &x, sizeof(x)); + pMem->flags = IsNaN(x) ? MEM_Null : MEM_Real; + } +} +static int serialGet7( + const unsigned char *buf, /* Buffer to deserialize from */ + Mem *pMem /* Memory cell to write value into */ +){ + u64 x = FOUR_BYTE_UINT(buf); + u32 y = FOUR_BYTE_UINT(buf+4); + x = (x<<32) + y; + assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 ); + swapMixedEndianFloat(x); + memcpy(&pMem->u.r, &x, sizeof(x)); + if( IsNaN(x) ){ + pMem->flags = MEM_Null; + return 1; + } + pMem->flags = MEM_Real; + return 0; +} +SQLITE_PRIVATE void sqlite3VdbeSerialGet( + const unsigned char *buf, /* Buffer to deserialize from */ + u32 serial_type, /* Serial type to deserialize */ + Mem *pMem /* Memory cell to write value into */ +){ + switch( serial_type ){ + case 10: { /* Internal use only: NULL with virtual table + ** UPDATE no-change flag set */ + pMem->flags = MEM_Null|MEM_Zero; + pMem->n = 0; + pMem->u.nZero = 0; + return; + } + case 11: /* Reserved for future use */ + case 0: { /* Null */ + /* EVIDENCE-OF: R-24078-09375 Value is a NULL. */ + pMem->flags = MEM_Null; + return; + } + case 1: { + /* EVIDENCE-OF: R-44885-25196 Value is an 8-bit twos-complement + ** integer. */ + pMem->u.i = ONE_BYTE_INT(buf); + pMem->flags = MEM_Int; + testcase( pMem->u.i<0 ); + return; + } + case 2: { /* 2-byte signed integer */ + /* EVIDENCE-OF: R-49794-35026 Value is a big-endian 16-bit + ** twos-complement integer. */ + pMem->u.i = TWO_BYTE_INT(buf); + pMem->flags = MEM_Int; + testcase( pMem->u.i<0 ); + return; + } + case 3: { /* 3-byte signed integer */ + /* EVIDENCE-OF: R-37839-54301 Value is a big-endian 24-bit + ** twos-complement integer. */ + pMem->u.i = THREE_BYTE_INT(buf); + pMem->flags = MEM_Int; + testcase( pMem->u.i<0 ); + return; + } + case 4: { /* 4-byte signed integer */ + /* EVIDENCE-OF: R-01849-26079 Value is a big-endian 32-bit + ** twos-complement integer. */ + pMem->u.i = FOUR_BYTE_INT(buf); +#ifdef __HP_cc + /* Work around a sign-extension bug in the HP compiler for HP/UX */ + if( buf[0]&0x80 ) pMem->u.i |= 0xffffffff80000000LL; +#endif + pMem->flags = MEM_Int; + testcase( pMem->u.i<0 ); + return; + } + case 5: { /* 6-byte signed integer */ + /* EVIDENCE-OF: R-50385-09674 Value is a big-endian 48-bit + ** twos-complement integer. */ + pMem->u.i = FOUR_BYTE_UINT(buf+2) + (((i64)1)<<32)*TWO_BYTE_INT(buf); + pMem->flags = MEM_Int; + testcase( pMem->u.i<0 ); + return; + } + case 6: /* 8-byte signed integer */ + case 7: { /* IEEE floating point */ + /* These use local variables, so do them in a separate routine + ** to avoid having to move the frame pointer in the common case */ + serialGet(buf,serial_type,pMem); + return; + } + case 8: /* Integer 0 */ + case 9: { /* Integer 1 */ + /* EVIDENCE-OF: R-12976-22893 Value is the integer 0. */ + /* EVIDENCE-OF: R-18143-12121 Value is the integer 1. */ + pMem->u.i = serial_type-8; + pMem->flags = MEM_Int; + return; + } + default: { + /* EVIDENCE-OF: R-14606-31564 Value is a BLOB that is (N-12)/2 bytes in + ** length. + ** EVIDENCE-OF: R-28401-00140 Value is a string in the text encoding and + ** (N-13)/2 bytes in length. */ + static const u16 aFlag[] = { MEM_Blob|MEM_Ephem, MEM_Str|MEM_Ephem }; + pMem->z = (char *)buf; + pMem->n = (serial_type-12)/2; + pMem->flags = aFlag[serial_type&1]; + return; + } + } + return; +} +/* +** Allocate sufficient space for an UnpackedRecord structure large enough +** to hold a decoded index record for pKeyInfo. +** +** The space is allocated using sqlite3DbMallocRaw(). If an OOM error +** occurs, NULL is returned. +*/ +SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord( + KeyInfo *pKeyInfo /* Description of the record */ +){ + UnpackedRecord *p; /* Unpacked record to return */ + u64 nByte; /* Number of bytes required for *p */ + assert( sizeof(UnpackedRecord) + sizeof(Mem)*65536 < 0x7fffffff ); + nByte = ROUND8P(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1); + p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); + if( !p ) return 0; + p->aMem = (Mem*)&((char*)p)[ROUND8P(sizeof(UnpackedRecord))]; + p->pKeyInfo = pKeyInfo; + p->nField = pKeyInfo->nKeyField + 1; + return p; +} + +/* +** Given the nKey-byte encoding of a record in pKey[], populate the +** UnpackedRecord structure indicated by the fourth argument with the +** contents of the decoded record. +*/ +SQLITE_PRIVATE void sqlite3VdbeRecordUnpack( + int nKey, /* Size of the binary record */ + const void *pKey, /* The binary record */ + UnpackedRecord *p /* Populate this structure before returning. */ +){ + const unsigned char *aKey = (const unsigned char *)pKey; + u32 d; + u32 idx; /* Offset in aKey[] to read from */ + u16 u; /* Unsigned loop counter */ + u32 szHdr; + Mem *pMem = p->aMem; + KeyInfo *pKeyInfo = p->pKeyInfo; + + p->default_rc = 0; + assert( EIGHT_BYTE_ALIGNMENT(pMem) ); + idx = getVarint32(aKey, szHdr); + d = szHdr; + u = 0; + while( idxenc = pKeyInfo->enc; + pMem->db = pKeyInfo->db; + /* pMem->flags = 0; // sqlite3VdbeSerialGet() will set this for us */ + pMem->szMalloc = 0; + pMem->z = 0; + sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem); + d += sqlite3VdbeSerialTypeLen(serial_type); + if( (++u)>=p->nField ) break; + pMem++; + } + if( d>(u32)nKey && u ){ + assert( CORRUPT_DB ); + /* In a corrupt record entry, the last pMem might have been set up using + ** uninitialized memory. Overwrite its value with NULL, to prevent + ** warnings from MSAN. */ + sqlite3VdbeMemSetNull(pMem-(unField)); + } + testcase( u == pKeyInfo->nKeyField + 1 ); + testcase( u < pKeyInfo->nKeyField + 1 ); + assert( u<=pKeyInfo->nKeyField + 1 ); + p->nField = u; +} + +#ifdef SQLITE_DEBUG +/* +** This function compares two index or table record keys in the same way +** as the sqlite3VdbeRecordCompare() routine. Unlike VdbeRecordCompare(), +** this function deserializes and compares values using the +** sqlite3VdbeSerialGet() and sqlite3MemCompare() functions. It is used +** in assert() statements to ensure that the optimized code in +** sqlite3VdbeRecordCompare() returns results with these two primitives. +** +** Return true if the result of comparison is equivalent to desiredResult. +** Return false if there is a disagreement. +*/ +static int vdbeRecordCompareDebug( + int nKey1, const void *pKey1, /* Left key */ + const UnpackedRecord *pPKey2, /* Right key */ + int desiredResult /* Correct answer */ +){ + u32 d1; /* Offset into aKey[] of next data element */ + u32 idx1; /* Offset into aKey[] of next header element */ + u32 szHdr1; /* Number of bytes in header */ + int i = 0; + int rc = 0; + const unsigned char *aKey1 = (const unsigned char *)pKey1; + KeyInfo *pKeyInfo; + Mem mem1; + + pKeyInfo = pPKey2->pKeyInfo; + if( pKeyInfo->db==0 ) return 1; + mem1.enc = pKeyInfo->enc; + mem1.db = pKeyInfo->db; + /* mem1.flags = 0; // Will be initialized by sqlite3VdbeSerialGet() */ + VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */ + + /* Compilers may complain that mem1.u.i is potentially uninitialized. + ** We could initialize it, as shown here, to silence those complaints. + ** But in fact, mem1.u.i will never actually be used uninitialized, and doing + ** the unnecessary initialization has a measurable negative performance + ** impact, since this routine is a very high runner. And so, we choose + ** to ignore the compiler warnings and leave this variable uninitialized. + */ + /* mem1.u.i = 0; // not needed, here to silence compiler warning */ + + idx1 = getVarint32(aKey1, szHdr1); + if( szHdr1>98307 ) return SQLITE_CORRUPT; + d1 = szHdr1; + assert( pKeyInfo->nAllField>=pPKey2->nField || CORRUPT_DB ); + assert( pKeyInfo->aSortFlags!=0 ); + assert( pKeyInfo->nKeyField>0 ); + assert( idx1<=szHdr1 || CORRUPT_DB ); + do{ + u32 serial_type1; + + /* Read the serial types for the next element in each key. */ + idx1 += getVarint32( aKey1+idx1, serial_type1 ); + + /* Verify that there is enough key space remaining to avoid + ** a buffer overread. The "d1+serial_type1+2" subexpression will + ** always be greater than or equal to the amount of required key space. + ** Use that approximation to avoid the more expensive call to + ** sqlite3VdbeSerialTypeLen() in the common case. + */ + if( d1+(u64)serial_type1+2>(u64)nKey1 + && d1+(u64)sqlite3VdbeSerialTypeLen(serial_type1)>(u64)nKey1 + ){ + if( serial_type1>=1 + && serial_type1<=7 + && d1+(u64)sqlite3VdbeSerialTypeLen(serial_type1)<=(u64)nKey1+8 + && CORRUPT_DB + ){ + return 1; /* corrupt record not detected by + ** sqlite3VdbeRecordCompareWithSkip(). Return true + ** to avoid firing the assert() */ + } + break; + } + + /* Extract the values to be compared. + */ + sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1); + d1 += sqlite3VdbeSerialTypeLen(serial_type1); + + /* Do the comparison + */ + rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], + pKeyInfo->nAllField>i ? pKeyInfo->aColl[i] : 0); + if( rc!=0 ){ + assert( mem1.szMalloc==0 ); /* See comment below */ + if( (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) + && ((mem1.flags & MEM_Null) || (pPKey2->aMem[i].flags & MEM_Null)) + ){ + rc = -rc; + } + if( pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_DESC ){ + rc = -rc; /* Invert the result for DESC sort order. */ + } + goto debugCompareEnd; + } + i++; + }while( idx1nField ); + + /* No memory allocation is ever used on mem1. Prove this using + ** the following assert(). If the assert() fails, it indicates a + ** memory leak and a need to call sqlite3VdbeMemRelease(&mem1). + */ + assert( mem1.szMalloc==0 ); + + /* rc==0 here means that one of the keys ran out of fields and + ** all the fields up to that point were equal. Return the default_rc + ** value. */ + rc = pPKey2->default_rc; + +debugCompareEnd: + if( desiredResult==0 && rc==0 ) return 1; + if( desiredResult<0 && rc<0 ) return 1; + if( desiredResult>0 && rc>0 ) return 1; + if( CORRUPT_DB ) return 1; + if( pKeyInfo->db->mallocFailed ) return 1; + return 0; +} +#endif + +#ifdef SQLITE_DEBUG +/* +** Count the number of fields (a.k.a. columns) in the record given by +** pKey,nKey. The verify that this count is less than or equal to the +** limit given by pKeyInfo->nAllField. +** +** If this constraint is not satisfied, it means that the high-speed +** vdbeRecordCompareInt() and vdbeRecordCompareString() routines will +** not work correctly. If this assert() ever fires, it probably means +** that the KeyInfo.nKeyField or KeyInfo.nAllField values were computed +** incorrectly. +*/ +static void vdbeAssertFieldCountWithinLimits( + int nKey, const void *pKey, /* The record to verify */ + const KeyInfo *pKeyInfo /* Compare size with this KeyInfo */ +){ + int nField = 0; + u32 szHdr; + u32 idx; + u32 notUsed; + const unsigned char *aKey = (const unsigned char*)pKey; + + if( CORRUPT_DB ) return; + idx = getVarint32(aKey, szHdr); + assert( nKey>=0 ); + assert( szHdr<=(u32)nKey ); + while( idxnAllField ); +} +#else +# define vdbeAssertFieldCountWithinLimits(A,B,C) +#endif + +/* +** Both *pMem1 and *pMem2 contain string values. Compare the two values +** using the collation sequence pColl. As usual, return a negative , zero +** or positive value if *pMem1 is less than, equal to or greater than +** *pMem2, respectively. Similar in spirit to "rc = (*pMem1) - (*pMem2);". +*/ +static SQLITE_NOINLINE int vdbeCompareMemStringWithEncodingChange( + const Mem *pMem1, + const Mem *pMem2, + const CollSeq *pColl, + u8 *prcErr /* If an OOM occurs, set to SQLITE_NOMEM */ +){ + int rc; + const void *v1, *v2; + Mem c1; + Mem c2; + sqlite3VdbeMemInit(&c1, pMem1->db, MEM_Null); + sqlite3VdbeMemInit(&c2, pMem1->db, MEM_Null); + sqlite3VdbeMemShallowCopy(&c1, pMem1, MEM_Ephem); + sqlite3VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem); + v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc); + v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc); + if( (v1==0 || v2==0) ){ + if( prcErr ) *prcErr = SQLITE_NOMEM_BKPT; + rc = 0; + }else{ + rc = pColl->xCmp(pColl->pUser, c1.n, v1, c2.n, v2); + } + sqlite3VdbeMemReleaseMalloc(&c1); + sqlite3VdbeMemReleaseMalloc(&c2); + return rc; +} +static int vdbeCompareMemString( + const Mem *pMem1, + const Mem *pMem2, + const CollSeq *pColl, + u8 *prcErr /* If an OOM occurs, set to SQLITE_NOMEM */ +){ + if( pMem1->enc==pColl->enc ){ + /* The strings are already in the correct encoding. Call the + ** comparison function directly */ + return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z); + }else{ + return vdbeCompareMemStringWithEncodingChange(pMem1,pMem2,pColl,prcErr); + } +} + +/* +** The input pBlob is guaranteed to be a Blob that is not marked +** with MEM_Zero. Return true if it could be a zero-blob. +*/ +static int isAllZero(const char *z, int n){ + int i; + for(i=0; in; + int n2 = pB2->n; + + /* It is possible to have a Blob value that has some non-zero content + ** followed by zero content. But that only comes up for Blobs formed + ** by the OP_MakeRecord opcode, and such Blobs never get passed into + ** sqlite3MemCompare(). */ + assert( (pB1->flags & MEM_Zero)==0 || n1==0 ); + assert( (pB2->flags & MEM_Zero)==0 || n2==0 ); + + if( (pB1->flags|pB2->flags) & MEM_Zero ){ + if( pB1->flags & pB2->flags & MEM_Zero ){ + return pB1->u.nZero - pB2->u.nZero; + }else if( pB1->flags & MEM_Zero ){ + if( !isAllZero(pB2->z, pB2->n) ) return -1; + return pB1->u.nZero - n2; + }else{ + if( !isAllZero(pB1->z, pB1->n) ) return +1; + return n1 - pB2->u.nZero; + } + } + c = memcmp(pB1->z, pB2->z, n1>n2 ? n2 : n1); + if( c ) return c; + return n1 - n2; +} + +/* The following two functions are used only within testcase() to prove +** test coverage. These functions do no exist for production builds. +** We must use separate SQLITE_NOINLINE functions here, since otherwise +** optimizer code movement causes gcov to become very confused. +*/ +#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG) +static int SQLITE_NOINLINE doubleLt(double a, double b){ return a=9223372036854775808.0 ) return -1; + y = (i64)r; + if( iy ) return +1; + testcase( doubleLt(((double)i),r) ); + testcase( doubleLt(r,((double)i)) ); + testcase( doubleEq(r,((double)i)) ); + return (((double)i)r); + } +} + +/* +** Compare the values contained by the two memory cells, returning +** negative, zero or positive if pMem1 is less than, equal to, or greater +** than pMem2. Sorting order is NULL's first, followed by numbers (integers +** and reals) sorted numerically, followed by text ordered by the collating +** sequence pColl and finally blob's ordered by memcmp(). +** +** Two NULL values are considered equal by this function. +*/ +SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){ + int f1, f2; + int combined_flags; + + f1 = pMem1->flags; + f2 = pMem2->flags; + combined_flags = f1|f2; + assert( !sqlite3VdbeMemIsRowSet(pMem1) && !sqlite3VdbeMemIsRowSet(pMem2) ); + + /* If one value is NULL, it is less than the other. If both values + ** are NULL, return 0. + */ + if( combined_flags&MEM_Null ){ + return (f2&MEM_Null) - (f1&MEM_Null); + } + + /* At least one of the two values is a number + */ + if( combined_flags&(MEM_Int|MEM_Real|MEM_IntReal) ){ + testcase( combined_flags & MEM_Int ); + testcase( combined_flags & MEM_Real ); + testcase( combined_flags & MEM_IntReal ); + if( (f1 & f2 & (MEM_Int|MEM_IntReal))!=0 ){ + testcase( f1 & f2 & MEM_Int ); + testcase( f1 & f2 & MEM_IntReal ); + if( pMem1->u.i < pMem2->u.i ) return -1; + if( pMem1->u.i > pMem2->u.i ) return +1; + return 0; + } + if( (f1 & f2 & MEM_Real)!=0 ){ + if( pMem1->u.r < pMem2->u.r ) return -1; + if( pMem1->u.r > pMem2->u.r ) return +1; + return 0; + } + if( (f1&(MEM_Int|MEM_IntReal))!=0 ){ + testcase( f1 & MEM_Int ); + testcase( f1 & MEM_IntReal ); + if( (f2&MEM_Real)!=0 ){ + return sqlite3IntFloatCompare(pMem1->u.i, pMem2->u.r); + }else if( (f2&(MEM_Int|MEM_IntReal))!=0 ){ + if( pMem1->u.i < pMem2->u.i ) return -1; + if( pMem1->u.i > pMem2->u.i ) return +1; + return 0; + }else{ + return -1; + } + } + if( (f1&MEM_Real)!=0 ){ + if( (f2&(MEM_Int|MEM_IntReal))!=0 ){ + testcase( f2 & MEM_Int ); + testcase( f2 & MEM_IntReal ); + return -sqlite3IntFloatCompare(pMem2->u.i, pMem1->u.r); + }else{ + return -1; + } + } + return +1; + } + + /* If one value is a string and the other is a blob, the string is less. + ** If both are strings, compare using the collating functions. + */ + if( combined_flags&MEM_Str ){ + if( (f1 & MEM_Str)==0 ){ + return 1; + } + if( (f2 & MEM_Str)==0 ){ + return -1; + } + + assert( pMem1->enc==pMem2->enc || pMem1->db->mallocFailed ); + assert( pMem1->enc==SQLITE_UTF8 || + pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE ); + + /* The collation sequence must be defined at this point, even if + ** the user deletes the collation sequence after the vdbe program is + ** compiled (this was not always the case). + */ + assert( !pColl || pColl->xCmp ); + + if( pColl ){ + return vdbeCompareMemString(pMem1, pMem2, pColl, 0); + } + /* If a NULL pointer was passed as the collate function, fall through + ** to the blob case and use memcmp(). */ + } + + /* Both values must be blobs. Compare using memcmp(). */ + return sqlite3BlobCompare(pMem1, pMem2); +} + + +/* +** The first argument passed to this function is a serial-type that +** corresponds to an integer - all values between 1 and 9 inclusive +** except 7. The second points to a buffer containing an integer value +** serialized according to serial_type. This function deserializes +** and returns the value. +*/ +static i64 vdbeRecordDecodeInt(u32 serial_type, const u8 *aKey){ + u32 y; + assert( CORRUPT_DB || (serial_type>=1 && serial_type<=9 && serial_type!=7) ); + switch( serial_type ){ + case 0: + case 1: + testcase( aKey[0]&0x80 ); + return ONE_BYTE_INT(aKey); + case 2: + testcase( aKey[0]&0x80 ); + return TWO_BYTE_INT(aKey); + case 3: + testcase( aKey[0]&0x80 ); + return THREE_BYTE_INT(aKey); + case 4: { + testcase( aKey[0]&0x80 ); + y = FOUR_BYTE_UINT(aKey); + return (i64)*(int*)&y; + } + case 5: { + testcase( aKey[0]&0x80 ); + return FOUR_BYTE_UINT(aKey+2) + (((i64)1)<<32)*TWO_BYTE_INT(aKey); + } + case 6: { + u64 x = FOUR_BYTE_UINT(aKey); + testcase( aKey[0]&0x80 ); + x = (x<<32) | FOUR_BYTE_UINT(aKey+4); + return (i64)*(i64*)&x; + } + } + + return (serial_type - 8); +} + +/* +** This function compares the two table rows or index records +** specified by {nKey1, pKey1} and pPKey2. It returns a negative, zero +** or positive integer if key1 is less than, equal to or +** greater than key2. The {nKey1, pKey1} key must be a blob +** created by the OP_MakeRecord opcode of the VDBE. The pPKey2 +** key must be a parsed key such as obtained from +** sqlite3VdbeParseRecord. +** +** If argument bSkip is non-zero, it is assumed that the caller has already +** determined that the first fields of the keys are equal. +** +** Key1 and Key2 do not have to contain the same number of fields. If all +** fields that appear in both keys are equal, then pPKey2->default_rc is +** returned. +** +** If database corruption is discovered, set pPKey2->errCode to +** SQLITE_CORRUPT and return 0. If an OOM error is encountered, +** pPKey2->errCode is set to SQLITE_NOMEM and, if it is not NULL, the +** malloc-failed flag set on database handle (pPKey2->pKeyInfo->db). +*/ +SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( + int nKey1, const void *pKey1, /* Left key */ + UnpackedRecord *pPKey2, /* Right key */ + int bSkip /* If true, skip the first field */ +){ + u32 d1; /* Offset into aKey[] of next data element */ + int i; /* Index of next field to compare */ + u32 szHdr1; /* Size of record header in bytes */ + u32 idx1; /* Offset of first type in header */ + int rc = 0; /* Return value */ + Mem *pRhs = pPKey2->aMem; /* Next field of pPKey2 to compare */ + KeyInfo *pKeyInfo; + const unsigned char *aKey1 = (const unsigned char *)pKey1; + Mem mem1; + + /* If bSkip is true, then the caller has already determined that the first + ** two elements in the keys are equal. Fix the various stack variables so + ** that this routine begins comparing at the second field. */ + if( bSkip ){ + u32 s1 = aKey1[1]; + if( s1<0x80 ){ + idx1 = 2; + }else{ + idx1 = 1 + sqlite3GetVarint32(&aKey1[1], &s1); + } + szHdr1 = aKey1[0]; + d1 = szHdr1 + sqlite3VdbeSerialTypeLen(s1); + i = 1; + pRhs++; + }else{ + if( (szHdr1 = aKey1[0])<0x80 ){ + idx1 = 1; + }else{ + idx1 = sqlite3GetVarint32(aKey1, &szHdr1); + } + d1 = szHdr1; + i = 0; + } + if( d1>(unsigned)nKey1 ){ + pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; + return 0; /* Corruption */ + } + + VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */ + assert( pPKey2->pKeyInfo->nAllField>=pPKey2->nField + || CORRUPT_DB ); + assert( pPKey2->pKeyInfo->aSortFlags!=0 ); + assert( pPKey2->pKeyInfo->nKeyField>0 ); + assert( idx1<=szHdr1 || CORRUPT_DB ); + while( 1 /*exit-by-break*/ ){ + u32 serial_type; + + /* RHS is an integer */ + if( pRhs->flags & (MEM_Int|MEM_IntReal) ){ + testcase( pRhs->flags & MEM_Int ); + testcase( pRhs->flags & MEM_IntReal ); + serial_type = aKey1[idx1]; + testcase( serial_type==12 ); + if( serial_type>=10 ){ + rc = serial_type==10 ? -1 : +1; + }else if( serial_type==0 ){ + rc = -1; + }else if( serial_type==7 ){ + serialGet7(&aKey1[d1], &mem1); + rc = -sqlite3IntFloatCompare(pRhs->u.i, mem1.u.r); + }else{ + i64 lhs = vdbeRecordDecodeInt(serial_type, &aKey1[d1]); + i64 rhs = pRhs->u.i; + if( lhsrhs ){ + rc = +1; + } + } + } + + /* RHS is real */ + else if( pRhs->flags & MEM_Real ){ + serial_type = aKey1[idx1]; + if( serial_type>=10 ){ + /* Serial types 12 or greater are strings and blobs (greater than + ** numbers). Types 10 and 11 are currently "reserved for future + ** use", so it doesn't really matter what the results of comparing + ** them to numeric values are. */ + rc = serial_type==10 ? -1 : +1; + }else if( serial_type==0 ){ + rc = -1; + }else{ + if( serial_type==7 ){ + if( serialGet7(&aKey1[d1], &mem1) ){ + rc = -1; /* mem1 is a NaN */ + }else if( mem1.u.ru.r ){ + rc = -1; + }else if( mem1.u.r>pRhs->u.r ){ + rc = +1; + }else{ + assert( rc==0 ); + } + }else{ + sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); + rc = sqlite3IntFloatCompare(mem1.u.i, pRhs->u.r); + } + } + } + + /* RHS is a string */ + else if( pRhs->flags & MEM_Str ){ + getVarint32NR(&aKey1[idx1], serial_type); + testcase( serial_type==12 ); + if( serial_type<12 ){ + rc = -1; + }else if( !(serial_type & 0x01) ){ + rc = +1; + }else{ + mem1.n = (serial_type - 12) / 2; + testcase( (d1+mem1.n)==(unsigned)nKey1 ); + testcase( (d1+mem1.n+1)==(unsigned)nKey1 ); + if( (d1+mem1.n) > (unsigned)nKey1 + || (pKeyInfo = pPKey2->pKeyInfo)->nAllField<=i + ){ + pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; + return 0; /* Corruption */ + }else if( pKeyInfo->aColl[i] ){ + mem1.enc = pKeyInfo->enc; + mem1.db = pKeyInfo->db; + mem1.flags = MEM_Str; + mem1.z = (char*)&aKey1[d1]; + rc = vdbeCompareMemString( + &mem1, pRhs, pKeyInfo->aColl[i], &pPKey2->errCode + ); + }else{ + int nCmp = MIN(mem1.n, pRhs->n); + rc = memcmp(&aKey1[d1], pRhs->z, nCmp); + if( rc==0 ) rc = mem1.n - pRhs->n; + } + } + } + + /* RHS is a blob */ + else if( pRhs->flags & MEM_Blob ){ + assert( (pRhs->flags & MEM_Zero)==0 || pRhs->n==0 ); + getVarint32NR(&aKey1[idx1], serial_type); + testcase( serial_type==12 ); + if( serial_type<12 || (serial_type & 0x01) ){ + rc = -1; + }else{ + int nStr = (serial_type - 12) / 2; + testcase( (d1+nStr)==(unsigned)nKey1 ); + testcase( (d1+nStr+1)==(unsigned)nKey1 ); + if( (d1+nStr) > (unsigned)nKey1 ){ + pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; + return 0; /* Corruption */ + }else if( pRhs->flags & MEM_Zero ){ + if( !isAllZero((const char*)&aKey1[d1],nStr) ){ + rc = 1; + }else{ + rc = nStr - pRhs->u.nZero; + } + }else{ + int nCmp = MIN(nStr, pRhs->n); + rc = memcmp(&aKey1[d1], pRhs->z, nCmp); + if( rc==0 ) rc = nStr - pRhs->n; + } + } + } + + /* RHS is null */ + else{ + serial_type = aKey1[idx1]; + if( serial_type==0 + || serial_type==10 + || (serial_type==7 && serialGet7(&aKey1[d1], &mem1)!=0) + ){ + assert( rc==0 ); + }else{ + rc = 1; + } + } + + if( rc!=0 ){ + int sortFlags = pPKey2->pKeyInfo->aSortFlags[i]; + if( sortFlags ){ + if( (sortFlags & KEYINFO_ORDER_BIGNULL)==0 + || ((sortFlags & KEYINFO_ORDER_DESC) + !=(serial_type==0 || (pRhs->flags&MEM_Null))) + ){ + rc = -rc; + } + } + assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, rc) ); + assert( mem1.szMalloc==0 ); /* See comment below */ + return rc; + } + + i++; + if( i==pPKey2->nField ) break; + pRhs++; + d1 += sqlite3VdbeSerialTypeLen(serial_type); + if( d1>(unsigned)nKey1 ) break; + idx1 += sqlite3VarintLen(serial_type); + if( idx1>=(unsigned)szHdr1 ){ + pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; + return 0; /* Corrupt index */ + } + } + + /* No memory allocation is ever used on mem1. Prove this using + ** the following assert(). If the assert() fails, it indicates a + ** memory leak and a need to call sqlite3VdbeMemRelease(&mem1). */ + assert( mem1.szMalloc==0 ); + + /* rc==0 here means that one or both of the keys ran out of fields and + ** all the fields up to that point were equal. Return the default_rc + ** value. */ + assert( CORRUPT_DB + || vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, pPKey2->default_rc) + || pPKey2->pKeyInfo->db->mallocFailed + ); + pPKey2->eqSeen = 1; + return pPKey2->default_rc; +} +SQLITE_PRIVATE int sqlite3VdbeRecordCompare( + int nKey1, const void *pKey1, /* Left key */ + UnpackedRecord *pPKey2 /* Right key */ +){ + return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 0); +} + + +/* +** This function is an optimized version of sqlite3VdbeRecordCompare() +** that (a) the first field of pPKey2 is an integer, and (b) the +** size-of-header varint at the start of (pKey1/nKey1) fits in a single +** byte (i.e. is less than 128). +** +** To avoid concerns about buffer overreads, this routine is only used +** on schemas where the maximum valid header size is 63 bytes or less. +*/ +static int vdbeRecordCompareInt( + int nKey1, const void *pKey1, /* Left key */ + UnpackedRecord *pPKey2 /* Right key */ +){ + const u8 *aKey = &((const u8*)pKey1)[*(const u8*)pKey1 & 0x3F]; + int serial_type = ((const u8*)pKey1)[1]; + int res; + u32 y; + u64 x; + i64 v; + i64 lhs; + + vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo); + assert( (*(u8*)pKey1)<=0x3F || CORRUPT_DB ); + switch( serial_type ){ + case 1: { /* 1-byte signed integer */ + lhs = ONE_BYTE_INT(aKey); + testcase( lhs<0 ); + break; + } + case 2: { /* 2-byte signed integer */ + lhs = TWO_BYTE_INT(aKey); + testcase( lhs<0 ); + break; + } + case 3: { /* 3-byte signed integer */ + lhs = THREE_BYTE_INT(aKey); + testcase( lhs<0 ); + break; + } + case 4: { /* 4-byte signed integer */ + y = FOUR_BYTE_UINT(aKey); + lhs = (i64)*(int*)&y; + testcase( lhs<0 ); + break; + } + case 5: { /* 6-byte signed integer */ + lhs = FOUR_BYTE_UINT(aKey+2) + (((i64)1)<<32)*TWO_BYTE_INT(aKey); + testcase( lhs<0 ); + break; + } + case 6: { /* 8-byte signed integer */ + x = FOUR_BYTE_UINT(aKey); + x = (x<<32) | FOUR_BYTE_UINT(aKey+4); + lhs = *(i64*)&x; + testcase( lhs<0 ); + break; + } + case 8: + lhs = 0; + break; + case 9: + lhs = 1; + break; + + /* This case could be removed without changing the results of running + ** this code. Including it causes gcc to generate a faster switch + ** statement (since the range of switch targets now starts at zero and + ** is contiguous) but does not cause any duplicate code to be generated + ** (as gcc is clever enough to combine the two like cases). Other + ** compilers might be similar. */ + case 0: case 7: + return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2); + + default: + return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2); + } + + assert( pPKey2->u.i == pPKey2->aMem[0].u.i ); + v = pPKey2->u.i; + if( v>lhs ){ + res = pPKey2->r1; + }else if( vr2; + }else if( pPKey2->nField>1 ){ + /* The first fields of the two keys are equal. Compare the trailing + ** fields. */ + res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1); + }else{ + /* The first fields of the two keys are equal and there are no trailing + ** fields. Return pPKey2->default_rc in this case. */ + res = pPKey2->default_rc; + pPKey2->eqSeen = 1; + } + + assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, res) ); + return res; +} + +/* +** This function is an optimized version of sqlite3VdbeRecordCompare() +** that (a) the first field of pPKey2 is a string, that (b) the first field +** uses the collation sequence BINARY and (c) that the size-of-header varint +** at the start of (pKey1/nKey1) fits in a single byte. +*/ +static int vdbeRecordCompareString( + int nKey1, const void *pKey1, /* Left key */ + UnpackedRecord *pPKey2 /* Right key */ +){ + const u8 *aKey1 = (const u8*)pKey1; + int serial_type; + int res; + + assert( pPKey2->aMem[0].flags & MEM_Str ); + assert( pPKey2->aMem[0].n == pPKey2->n ); + assert( pPKey2->aMem[0].z == pPKey2->u.z ); + vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo); + serial_type = (signed char)(aKey1[1]); + +vrcs_restart: + if( serial_type<12 ){ + if( serial_type<0 ){ + sqlite3GetVarint32(&aKey1[1], (u32*)&serial_type); + if( serial_type>=12 ) goto vrcs_restart; + assert( CORRUPT_DB ); + } + res = pPKey2->r1; /* (pKey1/nKey1) is a number or a null */ + }else if( !(serial_type & 0x01) ){ + res = pPKey2->r2; /* (pKey1/nKey1) is a blob */ + }else{ + int nCmp; + int nStr; + int szHdr = aKey1[0]; + + nStr = (serial_type-12) / 2; + if( (szHdr + nStr) > nKey1 ){ + pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; + return 0; /* Corruption */ + } + nCmp = MIN( pPKey2->n, nStr ); + res = memcmp(&aKey1[szHdr], pPKey2->u.z, nCmp); + + if( res>0 ){ + res = pPKey2->r2; + }else if( res<0 ){ + res = pPKey2->r1; + }else{ + res = nStr - pPKey2->n; + if( res==0 ){ + if( pPKey2->nField>1 ){ + res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1); + }else{ + res = pPKey2->default_rc; + pPKey2->eqSeen = 1; + } + }else if( res>0 ){ + res = pPKey2->r2; + }else{ + res = pPKey2->r1; + } + } + } + + assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, res) + || CORRUPT_DB + || pPKey2->pKeyInfo->db->mallocFailed + ); + return res; +} + +/* +** Return a pointer to an sqlite3VdbeRecordCompare() compatible function +** suitable for comparing serialized records to the unpacked record passed +** as the only argument. +*/ +SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){ + /* varintRecordCompareInt() and varintRecordCompareString() both assume + ** that the size-of-header varint that occurs at the start of each record + ** fits in a single byte (i.e. is 127 or less). varintRecordCompareInt() + ** also assumes that it is safe to overread a buffer by at least the + ** maximum possible legal header size plus 8 bytes. Because there is + ** guaranteed to be at least 74 (but not 136) bytes of padding following each + ** buffer passed to varintRecordCompareInt() this makes it convenient to + ** limit the size of the header to 64 bytes in cases where the first field + ** is an integer. + ** + ** The easiest way to enforce this limit is to consider only records with + ** 13 fields or less. If the first field is an integer, the maximum legal + ** header size is (12*5 + 1 + 1) bytes. */ + assert( p->pKeyInfo->aSortFlags!=0 ); + if( p->pKeyInfo->nAllField<=13 ){ + int flags = p->aMem[0].flags; + if( p->pKeyInfo->aSortFlags[0] ){ + if( p->pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL ){ + return sqlite3VdbeRecordCompare; + } + p->r1 = 1; + p->r2 = -1; + }else{ + p->r1 = -1; + p->r2 = 1; + } + if( (flags & MEM_Int) ){ + p->u.i = p->aMem[0].u.i; + return vdbeRecordCompareInt; + } + testcase( flags & MEM_Real ); + testcase( flags & MEM_Null ); + testcase( flags & MEM_Blob ); + if( (flags & (MEM_Real|MEM_IntReal|MEM_Null|MEM_Blob))==0 + && p->pKeyInfo->aColl[0]==0 + ){ + assert( flags & MEM_Str ); + p->u.z = p->aMem[0].z; + p->n = p->aMem[0].n; + return vdbeRecordCompareString; + } + } + + return sqlite3VdbeRecordCompare; +} + +/* +** pCur points at an index entry created using the OP_MakeRecord opcode. +** Read the rowid (the last field in the record) and store it in *rowid. +** Return SQLITE_OK if everything works, or an error code otherwise. +** +** pCur might be pointing to text obtained from a corrupt database file. +** So the content cannot be trusted. Do appropriate checks on the content. +*/ +SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){ + i64 nCellKey = 0; + int rc; + u32 szHdr; /* Size of the header */ + u32 typeRowid; /* Serial type of the rowid */ + u32 lenRowid; /* Size of the rowid */ + Mem m, v; + + /* Get the size of the index entry. Only indices entries of less + ** than 2GiB are support - anything large must be database corruption. + ** Any corruption is detected in sqlite3BtreeParseCellPtr(), though, so + ** this code can safely assume that nCellKey is 32-bits + */ + assert( sqlite3BtreeCursorIsValid(pCur) ); + nCellKey = sqlite3BtreePayloadSize(pCur); + assert( (nCellKey & SQLITE_MAX_U32)==(u64)nCellKey ); + + /* Read in the complete content of the index entry */ + sqlite3VdbeMemInit(&m, db, 0); + rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m); + if( rc ){ + return rc; + } + + /* The index entry must begin with a header size */ + getVarint32NR((u8*)m.z, szHdr); + testcase( szHdr==3 ); + testcase( szHdr==(u32)m.n ); + testcase( szHdr>0x7fffffff ); + assert( m.n>=0 ); + if( unlikely(szHdr<3 || szHdr>(unsigned)m.n) ){ + goto idx_rowid_corruption; + } + + /* The last field of the index should be an integer - the ROWID. + ** Verify that the last entry really is an integer. */ + getVarint32NR((u8*)&m.z[szHdr-1], typeRowid); + testcase( typeRowid==1 ); + testcase( typeRowid==2 ); + testcase( typeRowid==3 ); + testcase( typeRowid==4 ); + testcase( typeRowid==5 ); + testcase( typeRowid==6 ); + testcase( typeRowid==8 ); + testcase( typeRowid==9 ); + if( unlikely(typeRowid<1 || typeRowid>9 || typeRowid==7) ){ + goto idx_rowid_corruption; + } + lenRowid = sqlite3SmallTypeSizes[typeRowid]; + testcase( (u32)m.n==szHdr+lenRowid ); + if( unlikely((u32)m.neCurType==CURTYPE_BTREE ); + pCur = pC->uc.pCursor; + assert( sqlite3BtreeCursorIsValid(pCur) ); + nCellKey = sqlite3BtreePayloadSize(pCur); + /* nCellKey will always be between 0 and 0xffffffff because of the way + ** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */ + if( nCellKey<=0 || nCellKey>0x7fffffff ){ + *res = 0; + return SQLITE_CORRUPT_BKPT; + } + sqlite3VdbeMemInit(&m, db, 0); + rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m); + if( rc ){ + return rc; + } + *res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, pUnpacked, 0); + sqlite3VdbeMemReleaseMalloc(&m); + return SQLITE_OK; +} + +/* +** This routine sets the value to be returned by subsequent calls to +** sqlite3_changes() on the database handle 'db'. +*/ +SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *db, i64 nChange){ + assert( sqlite3_mutex_held(db->mutex) ); + db->nChange = nChange; + db->nTotalChange += nChange; +} + +/* +** Set a flag in the vdbe to update the change counter when it is finalised +** or reset. +*/ +SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe *v){ + v->changeCntOn = 1; +} + +/* +** Mark every prepared statement associated with a database connection +** as expired. +** +** An expired statement means that recompilation of the statement is +** recommend. Statements expire when things happen that make their +** programs obsolete. Removing user-defined functions or collating +** sequences, or changing an authorization function are the types of +** things that make prepared statements obsolete. +** +** If iCode is 1, then expiration is advisory. The statement should +** be reprepared before being restarted, but if it is already running +** it is allowed to run to completion. +** +** Internally, this function just sets the Vdbe.expired flag on all +** prepared statements. The flag is set to 1 for an immediate expiration +** and set to 2 for an advisory expiration. +*/ +SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3 *db, int iCode){ + Vdbe *p; + for(p = db->pVdbe; p; p=p->pVNext){ + p->expired = iCode+1; + } +} + +/* +** Return the database associated with the Vdbe. +*/ +SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe *v){ + return v->db; +} + +/* +** Return the SQLITE_PREPARE flags for a Vdbe. +*/ +SQLITE_PRIVATE u8 sqlite3VdbePrepareFlags(Vdbe *v){ + return v->prepFlags; +} + +/* +** Return a pointer to an sqlite3_value structure containing the value bound +** parameter iVar of VM v. Except, if the value is an SQL NULL, return +** 0 instead. Unless it is NULL, apply affinity aff (one of the SQLITE_AFF_* +** constants) to the value before returning it. +** +** The returned value must be freed by the caller using sqlite3ValueFree(). +*/ +SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff){ + assert( iVar>0 ); + if( v ){ + Mem *pMem = &v->aVar[iVar-1]; + assert( (v->db->flags & SQLITE_EnableQPSG)==0 + || (v->db->mDbFlags & DBFLAG_InternalFunc)!=0 ); + if( 0==(pMem->flags & MEM_Null) ){ + sqlite3_value *pRet = sqlite3ValueNew(v->db); + if( pRet ){ + sqlite3VdbeMemCopy((Mem *)pRet, pMem); + sqlite3ValueApplyAffinity(pRet, aff, SQLITE_UTF8); + } + return pRet; + } + } + return 0; +} + +/* +** Configure SQL variable iVar so that binding a new value to it signals +** to sqlite3_reoptimize() that re-preparing the statement may result +** in a better query plan. +*/ +SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){ + assert( iVar>0 ); + assert( (v->db->flags & SQLITE_EnableQPSG)==0 + || (v->db->mDbFlags & DBFLAG_InternalFunc)!=0 ); + if( iVar>=32 ){ + v->expmask |= 0x80000000; + }else{ + v->expmask |= ((u32)1 << (iVar-1)); + } +} + +/* +** Helper function for vdbeIsMatchingIndexKey(). Return true if column +** iCol should be ignored when comparing a record with a record from +** an index on disk. The field should be ignored if: +** +** * the corresponding bit in mask is set, and +** * either: +** - bIntegrity is false, or +** - the two Mem values are both real values that differ by +** BTREE_ULPDISTORTION or fewer ULPs. +*/ +static int vdbeSkipField( + Bitmask mask, /* Mask of indexed expression fields */ + int iCol, /* Column of index being considered */ + Mem *pMem1, /* Expected index value */ + Mem *pMem2, /* Actual indexed value */ + int bIntegrity /* True if running PRAGMA integrity_check */ +){ +#define BTREE_ULPDISTORTION 2 + if( iCol>=BMS || (mask & MASKBIT(iCol))==0 ) return 0; + if( bIntegrity==0 ) return 1; + if( (pMem1->flags & MEM_Real) && (pMem2->flags & MEM_Real) ){ + u64 m1, m2; + memcpy(&m1,&pMem1->u.r,8); + memcpy(&m2,&pMem2->u.r,8); + if( (m1pKeyInfo->enc; + mem.db = p->pKeyInfo->db; + nRec = sqlite3BtreePayloadSize(pCur); + if( nRec>0x7fffffff ){ + return SQLITE_CORRUPT_BKPT; + } + + /* Allocate 5 extra bytes at the end of the buffer. This allows the + ** getVarint32() call below to read slightly past the end of the buffer + ** if the record is corrupt. */ + aRec = sqlite3MallocZero(nRec+5); + if( aRec==0 ){ + rc = SQLITE_NOMEM_BKPT; + }else{ + rc = sqlite3BtreePayload(pCur, 0, nRec, aRec); + } + + if( rc==SQLITE_OK ){ + u32 szHdr = 0; /* Size of record header in bytes */ + u32 idxHdr = 0; /* Current index in header */ + + idxHdr = getVarint32(aRec, szHdr); + if( szHdr>98307 ){ + rc = SQLITE_CORRUPT; + }else{ + int res = 0; /* Result of this function call */ + u32 idxRec = szHdr; /* Index of next field in record body */ + int ii = 0; /* Iterator variable */ + + int nCol = p->pKeyInfo->nAllField; + for(ii=0; ii=szHdr ){ + rc = SQLITE_CORRUPT_BKPT; + break; + } + idxHdr += getVarint32(&aRec[idxHdr], iSerial); + nSerial = sqlite3VdbeSerialTypeLen(iSerial); + if( (idxRec+nSerial)>nRec ){ + rc = SQLITE_CORRUPT_BKPT; + }else{ + sqlite3VdbeSerialGet(&aRec[idxRec], iSerial, &mem); + if( vdbeSkipField(mask, ii, &p->aMem[ii], &mem, bInt)==0 ){ + res = sqlite3MemCompare(&mem, &p->aMem[ii], p->pKeyInfo->aColl[ii]); + if( res!=0 ) break; + } + } + idxRec += sqlite3VdbeSerialTypeLen(iSerial); + } + + *piRes = res; + } + } + + sqlite3_free(aRec); + return rc; +} + +/* +** This is called when the record in (*p) should be found in the index +** opened by cursor pCur, but was not. This may happen as part of a DELETE +** operation or an integrity check. +** +** One reason that an exact match was not found may be the EIIB bug - that +** a text-to-float conversion may have caused a real value in record (*p) +** to be slightly different from its counterpart on disk. This function +** attempts to find the right index record. If it does find the right +** record, it leaves *pCur pointing to it and sets (*pRes) to 0 before +** returning. Otherwise, (*pRes) is set to non-zero and an SQLite error +** code returned. +** +** The algorithm used to find the correct record is: +** +** * Scan up to BTREE_FDK_RANGE entries either side of the current entry. +** If parameter bIntegrity is false, then all fields that are indexed +** expressions or virtual table columns are omitted from the comparison. +** If bIntegrity is true, then small differences in real values in +** such fields are overlooked, but they are not omitted from the comparison +** altogether. +** +** * If the above fails to find an entry and bIntegrity is false, search +** the entire index. +*/ +SQLITE_PRIVATE int sqlite3VdbeFindIndexKey( + BtCursor *pCur, + Index *pIdx, + UnpackedRecord *p, + int *pRes, + int bIntegrity +){ +#define BTREE_FDK_RANGE 10 + int nStep = 0; + int res = 1; + int rc = SQLITE_OK; + int ii = 0; + + /* Calculate a mask based on the first 64 columns of the index. The mask + ** bit is set if the corresponding index field is either an expression + ** or a virtual column of the table. */ + Bitmask mask = 0; + for(ii=0; iinColumn, BMS); ii++){ + int iCol = pIdx->aiColumn[ii]; + if( (iCol==XN_EXPR) + || (iCol>=0 && (pIdx->pTable->aCol[iCol].colFlags & COLFLAG_VIRTUAL)) + ){ + mask |= MASKBIT(ii); + } + } + + /* If the mask is 0 at this point, then the index contains no expressions + ** or virtual columns. So do not search for a match - return so that the + ** caller may declare the db corrupt immediately. Or, if mask is non-zero, + ** proceed. */ + if( mask!=0 ){ + + /* Move the cursor back BTREE_FDK_RANGE entries. If this hits an EOF, + ** position the cursor at the first entry in the index and set nStep + ** to -1 so that the first loop below scans the entire index. Otherwise, + ** set nStep to BTREE_FDK_RANGE*2 so that the first loop below scans + ** just that many entries. */ + for(ii=0; sqlite3BtreeEof(pCur)==0 && ii=0), or the entire index if (nStep<0). */ + while( sqlite3BtreeCursorIsValidNN(pCur) ){ + for(ii=0; rc==SQLITE_OK && (iipVdbe==0 ) return 1; +#endif + pOp = pCtx->pVdbe->aOp + pCtx->iOp; + if( pOp->opcode==OP_PureFunc ){ + const char *zContext; + char *zMsg; + if( pOp->p5 & NC_IsCheck ){ + zContext = "a CHECK constraint"; + }else if( pOp->p5 & NC_GenCol ){ + zContext = "a generated column"; + }else{ + zContext = "an index"; + } + zMsg = sqlite3_mprintf("non-deterministic use of %s() in %s", + pCtx->pFunc->zName, zContext); + sqlite3_result_error(pCtx, zMsg, -1); + sqlite3_free(zMsg); + return 0; + } + return 1; +} +#endif /* SQLITE_OMIT_DATETIME_FUNCS */ + +#if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG) +/* +** This Walker callback is used to help verify that calls to +** sqlite3BtreeCursorHint() with opcode BTREE_HINT_RANGE have +** byte-code register values correctly initialized. +*/ +SQLITE_PRIVATE int sqlite3CursorRangeHintExprCheck(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_REGISTER ){ + assert( (pWalker->u.aMem[pExpr->iTable].flags & MEM_Undefined)==0 ); + } + return WRC_Continue; +} +#endif /* SQLITE_ENABLE_CURSOR_HINTS && SQLITE_DEBUG */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored +** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored +** in memory obtained from sqlite3DbMalloc). +*/ +SQLITE_PRIVATE void sqlite3VtabImportErrmsg(Vdbe *p, sqlite3_vtab *pVtab){ + if( pVtab->zErrMsg ){ + sqlite3 *db = p->db; + sqlite3DbFree(db, p->zErrMsg); + p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg); + sqlite3_free(pVtab->zErrMsg); + pVtab->zErrMsg = 0; + } +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + +/* +** If the second argument is not NULL, release any allocations associated +** with the memory cells in the p->aMem[] array. Also free the UnpackedRecord +** structure itself, using sqlite3DbFree(). +** +** This function is used to free UnpackedRecord structures allocated by +** the vdbeUnpackRecord() function found in vdbeapi.c. +*/ +static void vdbeFreeUnpacked(sqlite3 *db, int nField, UnpackedRecord *p){ + assert( db!=0 ); + if( p ){ + int i; + for(i=0; iaMem[i]; + if( pMem->zMalloc ) sqlite3VdbeMemReleaseMalloc(pMem); + } + sqlite3DbNNFreeNN(db, p); + } +} +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ + +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +/* +** Invoke the pre-update hook. If this is an UPDATE or DELETE pre-update call, +** then cursor passed as the second argument should point to the row about +** to be update or deleted. If the application calls sqlite3_preupdate_old(), +** the required value will be read from the row the cursor points to. +*/ +SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( + Vdbe *v, /* Vdbe pre-update hook is invoked by */ + VdbeCursor *pCsr, /* Cursor to grab old.* values from */ + int op, /* SQLITE_INSERT, UPDATE or DELETE */ + const char *zDb, /* Database name */ + Table *pTab, /* Modified table */ + i64 iKey1, /* Initial key value */ + int iReg, /* Register for new.* record */ + int iBlobWrite +){ + sqlite3 *db = v->db; + i64 iKey2; + PreUpdate preupdate; + const char *zTbl = pTab->zName; +#ifdef SQLITE_DEBUG + int nRealCol; + if( pTab->tabFlags & TF_WithoutRowid ){ + nRealCol = sqlite3PrimaryKeyIndex(pTab)->nColumn; + }else if( pTab->tabFlags & TF_HasVirtual ){ + nRealCol = pTab->nNVCol; + }else{ + nRealCol = pTab->nCol; + } +#endif + + assert( db->pPreUpdate==0 ); + memset(&preupdate, 0, sizeof(PreUpdate)); + if( HasRowid(pTab)==0 ){ + iKey1 = iKey2 = 0; + preupdate.pPk = sqlite3PrimaryKeyIndex(pTab); + }else{ + if( op==SQLITE_UPDATE ){ + iKey2 = v->aMem[iReg].u.i; + }else{ + iKey2 = iKey1; + } + } + + assert( pCsr!=0 ); + assert( pCsr->eCurType==CURTYPE_BTREE ); + assert( pCsr->nField==nRealCol + || (pCsr->nField==nRealCol+1 && op==SQLITE_DELETE && iReg==-1) + ); + + preupdate.v = v; + preupdate.pCsr = pCsr; + preupdate.op = op; + preupdate.iNewReg = iReg; + preupdate.pKeyinfo = (KeyInfo*)&preupdate.uKey; + preupdate.pKeyinfo->db = db; + preupdate.pKeyinfo->enc = ENC(db); + preupdate.pKeyinfo->nKeyField = pTab->nCol; + preupdate.pKeyinfo->aSortFlags = 0; /* Indicate .aColl, .nAllField uninit */ + preupdate.iKey1 = iKey1; + preupdate.iKey2 = iKey2; + preupdate.pTab = pTab; + preupdate.iBlobWrite = iBlobWrite; + + db->pPreUpdate = &preupdate; + db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2); + db->pPreUpdate = 0; + sqlite3DbFree(db, preupdate.aRecord); + vdbeFreeUnpacked(db, preupdate.pKeyinfo->nKeyField+1,preupdate.pUnpacked); + vdbeFreeUnpacked(db, preupdate.pKeyinfo->nKeyField+1,preupdate.pNewUnpacked); + sqlite3VdbeMemRelease(&preupdate.oldipk); + if( preupdate.aNew ){ + int i; + for(i=0; inField; i++){ + sqlite3VdbeMemRelease(&preupdate.aNew[i]); + } + sqlite3DbNNFreeNN(db, preupdate.aNew); + } + if( preupdate.apDflt ){ + int i; + for(i=0; inCol; i++){ + sqlite3ValueFree(preupdate.apDflt[i]); + } + sqlite3DbFree(db, preupdate.apDflt); + } +} +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ + +#ifdef SQLITE_ENABLE_PERCENTILE +/* +** Return the name of an SQL function associated with the sqlite3_context. +*/ +SQLITE_PRIVATE const char *sqlite3VdbeFuncName(const sqlite3_context *pCtx){ + assert( pCtx!=0 ); + assert( pCtx->pFunc!=0 ); + return pCtx->pFunc->zName; +} +#endif /* SQLITE_ENABLE_PERCENTILE */ + +/************** End of vdbeaux.c *********************************************/ +/************** Begin file vdbeapi.c *****************************************/ +/* +** 2004 May 26 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains code use to implement APIs that are part of the +** VDBE. +*/ +/* #include "sqliteInt.h" */ +/* #include "vdbeInt.h" */ +/* #include "opcodes.h" */ + +#ifndef SQLITE_OMIT_DEPRECATED +/* +** Return TRUE (non-zero) of the statement supplied as an argument needs +** to be recompiled. A statement needs to be recompiled whenever the +** execution environment changes in a way that would alter the program +** that sqlite3_prepare() generates. For example, if new functions or +** collating sequences are registered or if an authorizer function is +** added or changed. +*/ +SQLITE_API int sqlite3_expired(sqlite3_stmt *pStmt){ + int iRet = 1; + if( pStmt ){ + Vdbe *p = (Vdbe*)pStmt; + sqlite3_mutex_enter(p->db->mutex); + iRet = p->expired; + sqlite3_mutex_leave(p->db->mutex); + } + return iRet; +} +#endif + +/* +** Check on a Vdbe to make sure it has not been finalized. Log +** an error and return true if it has been finalized (or is otherwise +** invalid). Return false if it is ok. +*/ +static int vdbeSafety(Vdbe *p){ + if( p->db==0 ){ + sqlite3_log(SQLITE_MISUSE, "API called with finalized prepared statement"); + return 1; + }else{ + return 0; + } +} +static int vdbeSafetyNotNull(Vdbe *p){ + if( p==0 ){ + sqlite3_log(SQLITE_MISUSE, "API called with NULL prepared statement"); + return 1; + }else{ + return vdbeSafety(p); + } +} + +#ifndef SQLITE_OMIT_TRACE +/* +** Invoke the profile callback. This routine is only called if we already +** know that the profile callback is defined and needs to be invoked. +*/ +static SQLITE_NOINLINE void invokeProfileCallback(sqlite3 *db, Vdbe *p){ + sqlite3_int64 iNow; + sqlite3_int64 iElapse; + assert( p->startTime>0 ); + assert( db->init.busy==0 ); + assert( p->zSql!=0 ); + sqlite3OsCurrentTimeInt64(db->pVfs, &iNow); + iElapse = (iNow - p->startTime)*1000000; +#ifndef SQLITE_OMIT_DEPRECATED + if( db->xProfile ){ + db->xProfile(db->pProfileArg, p->zSql, iElapse); + } +#endif + if( db->mTrace & SQLITE_TRACE_PROFILE ){ + db->trace.xV2(SQLITE_TRACE_PROFILE, db->pTraceArg, p, (void*)&iElapse); + } + p->startTime = 0; +} +/* +** The checkProfileCallback(DB,P) macro checks to see if a profile callback +** is needed, and it invokes the callback if it is needed. +*/ +# define checkProfileCallback(DB,P) \ + if( ((P)->startTime)>0 ){ invokeProfileCallback(DB,P); } +#else +# define checkProfileCallback(DB,P) /*no-op*/ +#endif + +/* +** The following routine destroys a virtual machine that is created by +** the sqlite3_compile() routine. The integer returned is an SQLITE_ +** success/failure code that describes the result of executing the virtual +** machine. +** +** This routine sets the error code and string returned by +** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16(). +*/ +SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt){ + int rc; + if( pStmt==0 ){ + /* IMPLEMENTATION-OF: R-57228-12904 Invoking sqlite3_finalize() on a NULL + ** pointer is a harmless no-op. */ + rc = SQLITE_OK; + }else{ + Vdbe *v = (Vdbe*)pStmt; + sqlite3 *db = v->db; + if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT; + sqlite3_mutex_enter(db->mutex); + checkProfileCallback(db, v); + assert( v->eVdbeState>=VDBE_READY_STATE ); + rc = sqlite3VdbeReset(v); + sqlite3VdbeDelete(v); + rc = sqlite3ApiExit(db, rc); + sqlite3LeaveMutexAndCloseZombie(db); + } + return rc; +} + +/* +** Terminate the current execution of an SQL statement and reset it +** back to its starting state so that it can be reused. A success code from +** the prior execution is returned. +** +** This routine sets the error code and string returned by +** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16(). +*/ +SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt){ + int rc; + if( pStmt==0 ){ + rc = SQLITE_OK; + }else{ + Vdbe *v = (Vdbe*)pStmt; + sqlite3 *db = v->db; + sqlite3_mutex_enter(db->mutex); + checkProfileCallback(db, v); + rc = sqlite3VdbeReset(v); + sqlite3VdbeRewind(v); + assert( (rc & (db->errMask))==rc ); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + } + return rc; +} + +/* +** Set all the parameters in the compiled SQL statement to NULL. +*/ +SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){ + int i; + int rc = SQLITE_OK; + Vdbe *p = (Vdbe*)pStmt; +#if SQLITE_THREADSAFE + sqlite3_mutex *mutex; +#endif +#ifdef SQLITE_ENABLE_API_ARMOR + if( pStmt==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif +#if SQLITE_THREADSAFE + mutex = p->db->mutex; +#endif + sqlite3_mutex_enter(mutex); + for(i=0; inVar; i++){ + sqlite3VdbeMemRelease(&p->aVar[i]); + p->aVar[i].flags = MEM_Null; + } + assert( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 || p->expmask==0 ); + if( p->expmask ){ + p->expired = 1; + } + sqlite3_mutex_leave(mutex); + return rc; +} + + +/**************************** sqlite3_value_ ******************************* +** The following routines extract information from a Mem or sqlite3_value +** structure. +*/ +SQLITE_API const void *sqlite3_value_blob(sqlite3_value *pVal){ + Mem *p = (Mem*)pVal; + if( p->flags & (MEM_Blob|MEM_Str) ){ + if( ExpandBlob(p)!=SQLITE_OK ){ + assert( p->flags==MEM_Null && p->z==0 ); + return 0; + } + p->flags |= MEM_Blob; + return p->n ? p->z : 0; + }else{ + return sqlite3_value_text(pVal); + } +} +SQLITE_API int sqlite3_value_bytes(sqlite3_value *pVal){ + return sqlite3ValueBytes(pVal, SQLITE_UTF8); +} +SQLITE_API int sqlite3_value_bytes16(sqlite3_value *pVal){ + return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE); +} +SQLITE_API double sqlite3_value_double(sqlite3_value *pVal){ + return sqlite3VdbeRealValue((Mem*)pVal); +} +SQLITE_API int sqlite3_value_int(sqlite3_value *pVal){ + return (int)sqlite3VdbeIntValue((Mem*)pVal); +} +SQLITE_API sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){ + return sqlite3VdbeIntValue((Mem*)pVal); +} +SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value *pVal){ + Mem *pMem = (Mem*)pVal; + return ((pMem->flags & MEM_Subtype) ? pMem->eSubtype : 0); +} +SQLITE_API void *sqlite3_value_pointer(sqlite3_value *pVal, const char *zPType){ + Mem *p = (Mem*)pVal; + if( (p->flags&(MEM_TypeMask|MEM_Term|MEM_Subtype)) == + (MEM_Null|MEM_Term|MEM_Subtype) + && zPType!=0 + && p->eSubtype=='p' + && strcmp(p->u.zPType, zPType)==0 + ){ + return (void*)p->z; + }else{ + return 0; + } +} +SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value *pVal){ + return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8); +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API const void *sqlite3_value_text16(sqlite3_value* pVal){ + return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE); +} +SQLITE_API const void *sqlite3_value_text16be(sqlite3_value *pVal){ + return sqlite3ValueText(pVal, SQLITE_UTF16BE); +} +SQLITE_API const void *sqlite3_value_text16le(sqlite3_value *pVal){ + return sqlite3ValueText(pVal, SQLITE_UTF16LE); +} +#endif /* SQLITE_OMIT_UTF16 */ +/* EVIDENCE-OF: R-12793-43283 Every value in SQLite has one of five +** fundamental datatypes: 64-bit signed integer 64-bit IEEE floating +** point number string BLOB NULL +*/ +SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){ + static const u8 aType[] = { + SQLITE_BLOB, /* 0x00 (not possible) */ + SQLITE_NULL, /* 0x01 NULL */ + SQLITE_TEXT, /* 0x02 TEXT */ + SQLITE_NULL, /* 0x03 (not possible) */ + SQLITE_INTEGER, /* 0x04 INTEGER */ + SQLITE_NULL, /* 0x05 (not possible) */ + SQLITE_INTEGER, /* 0x06 INTEGER + TEXT */ + SQLITE_NULL, /* 0x07 (not possible) */ + SQLITE_FLOAT, /* 0x08 FLOAT */ + SQLITE_NULL, /* 0x09 (not possible) */ + SQLITE_FLOAT, /* 0x0a FLOAT + TEXT */ + SQLITE_NULL, /* 0x0b (not possible) */ + SQLITE_INTEGER, /* 0x0c (not possible) */ + SQLITE_NULL, /* 0x0d (not possible) */ + SQLITE_INTEGER, /* 0x0e (not possible) */ + SQLITE_NULL, /* 0x0f (not possible) */ + SQLITE_BLOB, /* 0x10 BLOB */ + SQLITE_NULL, /* 0x11 (not possible) */ + SQLITE_TEXT, /* 0x12 (not possible) */ + SQLITE_NULL, /* 0x13 (not possible) */ + SQLITE_INTEGER, /* 0x14 INTEGER + BLOB */ + SQLITE_NULL, /* 0x15 (not possible) */ + SQLITE_INTEGER, /* 0x16 (not possible) */ + SQLITE_NULL, /* 0x17 (not possible) */ + SQLITE_FLOAT, /* 0x18 FLOAT + BLOB */ + SQLITE_NULL, /* 0x19 (not possible) */ + SQLITE_FLOAT, /* 0x1a (not possible) */ + SQLITE_NULL, /* 0x1b (not possible) */ + SQLITE_INTEGER, /* 0x1c (not possible) */ + SQLITE_NULL, /* 0x1d (not possible) */ + SQLITE_INTEGER, /* 0x1e (not possible) */ + SQLITE_NULL, /* 0x1f (not possible) */ + SQLITE_FLOAT, /* 0x20 INTREAL */ + SQLITE_NULL, /* 0x21 (not possible) */ + SQLITE_FLOAT, /* 0x22 INTREAL + TEXT */ + SQLITE_NULL, /* 0x23 (not possible) */ + SQLITE_FLOAT, /* 0x24 (not possible) */ + SQLITE_NULL, /* 0x25 (not possible) */ + SQLITE_FLOAT, /* 0x26 (not possible) */ + SQLITE_NULL, /* 0x27 (not possible) */ + SQLITE_FLOAT, /* 0x28 (not possible) */ + SQLITE_NULL, /* 0x29 (not possible) */ + SQLITE_FLOAT, /* 0x2a (not possible) */ + SQLITE_NULL, /* 0x2b (not possible) */ + SQLITE_FLOAT, /* 0x2c (not possible) */ + SQLITE_NULL, /* 0x2d (not possible) */ + SQLITE_FLOAT, /* 0x2e (not possible) */ + SQLITE_NULL, /* 0x2f (not possible) */ + SQLITE_BLOB, /* 0x30 (not possible) */ + SQLITE_NULL, /* 0x31 (not possible) */ + SQLITE_TEXT, /* 0x32 (not possible) */ + SQLITE_NULL, /* 0x33 (not possible) */ + SQLITE_FLOAT, /* 0x34 (not possible) */ + SQLITE_NULL, /* 0x35 (not possible) */ + SQLITE_FLOAT, /* 0x36 (not possible) */ + SQLITE_NULL, /* 0x37 (not possible) */ + SQLITE_FLOAT, /* 0x38 (not possible) */ + SQLITE_NULL, /* 0x39 (not possible) */ + SQLITE_FLOAT, /* 0x3a (not possible) */ + SQLITE_NULL, /* 0x3b (not possible) */ + SQLITE_FLOAT, /* 0x3c (not possible) */ + SQLITE_NULL, /* 0x3d (not possible) */ + SQLITE_FLOAT, /* 0x3e (not possible) */ + SQLITE_NULL, /* 0x3f (not possible) */ + }; +#ifdef SQLITE_DEBUG + { + int eType = SQLITE_BLOB; + if( pVal->flags & MEM_Null ){ + eType = SQLITE_NULL; + }else if( pVal->flags & (MEM_Real|MEM_IntReal) ){ + eType = SQLITE_FLOAT; + }else if( pVal->flags & MEM_Int ){ + eType = SQLITE_INTEGER; + }else if( pVal->flags & MEM_Str ){ + eType = SQLITE_TEXT; + } + assert( eType == aType[pVal->flags&MEM_AffMask] ); + } +#endif + return aType[pVal->flags&MEM_AffMask]; +} +SQLITE_API int sqlite3_value_encoding(sqlite3_value *pVal){ + return pVal->enc; +} + +/* Return true if a parameter to xUpdate represents an unchanged column */ +SQLITE_API int sqlite3_value_nochange(sqlite3_value *pVal){ + return (pVal->flags&(MEM_Null|MEM_Zero))==(MEM_Null|MEM_Zero); +} + +/* Return true if a parameter value originated from an sqlite3_bind() */ +SQLITE_API int sqlite3_value_frombind(sqlite3_value *pVal){ + return (pVal->flags&MEM_FromBind)!=0; +} + +/* Make a copy of an sqlite3_value object +*/ +SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){ + sqlite3_value *pNew; + if( pOrig==0 ) return 0; + pNew = sqlite3_malloc( sizeof(*pNew) ); + if( pNew==0 ) return 0; + memset(pNew, 0, sizeof(*pNew)); + memcpy(pNew, pOrig, MEMCELLSIZE); + pNew->flags &= ~MEM_Dyn; + pNew->db = 0; + if( pNew->flags&(MEM_Str|MEM_Blob) ){ + pNew->flags &= ~(MEM_Static|MEM_Dyn); + pNew->flags |= MEM_Ephem; + if( sqlite3VdbeMemMakeWriteable(pNew)!=SQLITE_OK ){ + sqlite3ValueFree(pNew); + pNew = 0; + } + }else if( pNew->flags & MEM_Null ){ + /* Do not duplicate pointer values */ + pNew->flags &= ~(MEM_Term|MEM_Subtype); + } + return pNew; +} + +/* Destroy an sqlite3_value object previously obtained from +** sqlite3_value_dup(). +*/ +SQLITE_API void sqlite3_value_free(sqlite3_value *pOld){ + sqlite3ValueFree(pOld); +} + + +/**************************** sqlite3_result_ ******************************* +** The following routines are used by user-defined functions to specify +** the function result. +** +** The setStrOrError() function calls sqlite3VdbeMemSetStr() to store the +** result as a string or blob. Appropriate errors are set if the string/blob +** is too big or if an OOM occurs. +** +** The invokeValueDestructor(P,X) routine invokes destructor function X() +** on value P if P is not going to be used and need to be destroyed. +*/ +static void setResultStrOrError( + sqlite3_context *pCtx, /* Function context */ + const char *z, /* String pointer */ + int n, /* Bytes in string, or negative */ + u8 enc, /* Encoding of z. 0 for BLOBs */ + void (*xDel)(void*) /* Destructor function */ +){ + Mem *pOut = pCtx->pOut; + int rc; + if( enc==SQLITE_UTF8 ){ + rc = sqlite3VdbeMemSetText(pOut, z, n, xDel); + }else if( enc==SQLITE_UTF8_ZT ){ + /* It is usually considered improper to assert() on an input. However, + ** the following assert() is checking for inputs that are documented + ** to result in undefined behavior. */ + assert( z==0 + || n<0 + || n>pOut->db->aLimit[SQLITE_LIMIT_LENGTH] + || z[n]==0 + ); + rc = sqlite3VdbeMemSetText(pOut, z, n, xDel); + pOut->flags |= MEM_Term; + }else{ + rc = sqlite3VdbeMemSetStr(pOut, z, n, enc, xDel); + } + if( rc ){ + if( rc==SQLITE_TOOBIG ){ + sqlite3_result_error_toobig(pCtx); + }else{ + /* The only errors possible from sqlite3VdbeMemSetStr are + ** SQLITE_TOOBIG and SQLITE_NOMEM */ + assert( rc==SQLITE_NOMEM ); + sqlite3_result_error_nomem(pCtx); + } + return; + } + sqlite3VdbeChangeEncoding(pOut, pCtx->enc); + if( sqlite3VdbeMemTooBig(pOut) ){ + sqlite3_result_error_toobig(pCtx); + } +} +static int invokeValueDestructor( + const void *p, /* Value to destroy */ + void (*xDel)(void*), /* The destructor */ + sqlite3_context *pCtx /* Set a SQLITE_TOOBIG error if not NULL */ +){ + assert( xDel!=SQLITE_DYNAMIC ); + if( xDel==0 ){ + /* noop */ + }else if( xDel==SQLITE_TRANSIENT ){ + /* noop */ + }else{ + xDel((void*)p); + } +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx!=0 ){ + sqlite3_result_error_toobig(pCtx); + } +#else + assert( pCtx!=0 ); + sqlite3_result_error_toobig(pCtx); +#endif + return SQLITE_TOOBIG; +} +SQLITE_API void sqlite3_result_blob( + sqlite3_context *pCtx, + const void *z, + int n, + void (*xDel)(void *) +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 || n<0 ){ + invokeValueDestructor(z, xDel, pCtx); + return; + } +#endif + assert( n>=0 ); + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + setResultStrOrError(pCtx, z, n, 0, xDel); +} +SQLITE_API void sqlite3_result_blob64( + sqlite3_context *pCtx, + const void *z, + sqlite3_uint64 n, + void (*xDel)(void *) +){ + assert( xDel!=SQLITE_DYNAMIC ); +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ){ + invokeValueDestructor(z, xDel, 0); + return; + } +#endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + if( n>0x7fffffff ){ + (void)invokeValueDestructor(z, xDel, pCtx); + }else{ + setResultStrOrError(pCtx, z, (int)n, 0, xDel); + } +} +SQLITE_API void sqlite3_result_double(sqlite3_context *pCtx, double rVal){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemSetDouble(pCtx->pOut, rVal); +} +SQLITE_API void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + pCtx->isError = SQLITE_ERROR; + sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT); +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + pCtx->isError = SQLITE_ERROR; + sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT); +} +#endif +SQLITE_API void sqlite3_result_int(sqlite3_context *pCtx, int iVal){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemSetInt64(pCtx->pOut, (i64)iVal); +} +SQLITE_API void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemSetInt64(pCtx->pOut, iVal); +} +SQLITE_API void sqlite3_result_null(sqlite3_context *pCtx){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemSetNull(pCtx->pOut); +} +SQLITE_API void sqlite3_result_pointer( + sqlite3_context *pCtx, + void *pPtr, + const char *zPType, + void (*xDestructor)(void*) +){ + Mem *pOut; +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ){ + invokeValueDestructor(pPtr, xDestructor, 0); + return; + } +#endif + pOut = pCtx->pOut; + assert( sqlite3_mutex_held(pOut->db->mutex) ); + sqlite3VdbeMemRelease(pOut); + pOut->flags = MEM_Null; + sqlite3VdbeMemSetPointer(pOut, pPtr, zPType, xDestructor); +} +SQLITE_API void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){ + Mem *pOut; +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif +#if defined(SQLITE_STRICT_SUBTYPE) && SQLITE_STRICT_SUBTYPE+0!=0 + if( pCtx->pFunc!=0 + && (pCtx->pFunc->funcFlags & SQLITE_RESULT_SUBTYPE)==0 + ){ + char zErr[200]; + sqlite3_snprintf(sizeof(zErr), zErr, + "misuse of sqlite3_result_subtype() by %s()", + pCtx->pFunc->zName); + sqlite3_result_error(pCtx, zErr, -1); + return; + } +#endif /* SQLITE_STRICT_SUBTYPE */ + pOut = pCtx->pOut; + assert( sqlite3_mutex_held(pOut->db->mutex) ); + pOut->eSubtype = eSubtype & 0xff; + pOut->flags |= MEM_Subtype; +} +SQLITE_API void sqlite3_result_text( + sqlite3_context *pCtx, + const char *z, + int n, + void (*xDel)(void *) +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ){ + invokeValueDestructor(z, xDel, 0); + return; + } +#endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel); +} +SQLITE_API void sqlite3_result_text64( + sqlite3_context *pCtx, + const char *z, + sqlite3_uint64 n, + void (*xDel)(void *), + unsigned char enc +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ){ + invokeValueDestructor(z, xDel, 0); + return; + } +#endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + assert( xDel!=SQLITE_DYNAMIC ); + if( enc!=SQLITE_UTF8 && enc!=SQLITE_UTF8_ZT ){ + if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; + n &= ~(u64)1; + } + if( n>0x7fffffff ){ + (void)invokeValueDestructor(z, xDel, pCtx); + }else{ + setResultStrOrError(pCtx, z, (int)n, enc, xDel); + sqlite3VdbeMemZeroTerminateIfAble(pCtx->pOut); + } +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API void sqlite3_result_text16( + sqlite3_context *pCtx, + const void *z, + int n, + void (*xDel)(void *) +){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + setResultStrOrError(pCtx, z, n & ~(u64)1, SQLITE_UTF16NATIVE, xDel); +} +SQLITE_API void sqlite3_result_text16be( + sqlite3_context *pCtx, + const void *z, + int n, + void (*xDel)(void *) +){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + setResultStrOrError(pCtx, z, n & ~(u64)1, SQLITE_UTF16BE, xDel); +} +SQLITE_API void sqlite3_result_text16le( + sqlite3_context *pCtx, + const void *z, + int n, + void (*xDel)(void *) +){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + setResultStrOrError(pCtx, z, n & ~(u64)1, SQLITE_UTF16LE, xDel); +} +#endif /* SQLITE_OMIT_UTF16 */ +SQLITE_API void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){ + Mem *pOut; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; + if( pValue==0 ){ + sqlite3_result_null(pCtx); + return; + } +#endif + pOut = pCtx->pOut; + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemCopy(pOut, pValue); + sqlite3VdbeChangeEncoding(pOut, pCtx->enc); + if( sqlite3VdbeMemTooBig(pOut) ){ + sqlite3_result_error_toobig(pCtx); + } +} +SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){ + sqlite3_result_zeroblob64(pCtx, n>0 ? n : 0); +} +SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){ + Mem *pOut; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return SQLITE_MISUSE_BKPT; +#endif + pOut = pCtx->pOut; + assert( sqlite3_mutex_held(pOut->db->mutex) ); + if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){ + sqlite3_result_error_toobig(pCtx); + return SQLITE_TOOBIG; + } +#ifndef SQLITE_OMIT_INCRBLOB + sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n); + return SQLITE_OK; +#else + return sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n); +#endif +} +SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif + pCtx->isError = errCode ? errCode : -1; +#ifdef SQLITE_DEBUG + if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode; +#endif + if( pCtx->pOut->flags & MEM_Null ){ + setResultStrOrError(pCtx, sqlite3ErrStr(errCode), -1, SQLITE_UTF8, + SQLITE_STATIC); + } +} + +/* Force an SQLITE_TOOBIG error. */ +SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + pCtx->isError = SQLITE_TOOBIG; + sqlite3VdbeMemSetStr(pCtx->pOut, "string or blob too big", -1, + SQLITE_UTF8, SQLITE_STATIC); +} + +/* An SQLITE_NOMEM error. */ +SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemSetNull(pCtx->pOut); + pCtx->isError = SQLITE_NOMEM_BKPT; + sqlite3OomFault(pCtx->pOut->db); +} + +#ifndef SQLITE_UNTESTABLE +/* Force the INT64 value currently stored as the result to be +** a MEM_IntReal value. See the SQLITE_TESTCTRL_RESULT_INTREAL +** test-control. +*/ +SQLITE_PRIVATE void sqlite3ResultIntReal(sqlite3_context *pCtx){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + if( pCtx->pOut->flags & MEM_Int ){ + pCtx->pOut->flags &= ~MEM_Int; + pCtx->pOut->flags |= MEM_IntReal; + } +} +#endif + + +/* +** This function is called after a transaction has been committed. It +** invokes callbacks registered with sqlite3_wal_hook() as required. +*/ +static int doWalCallbacks(sqlite3 *db){ + int rc = SQLITE_OK; +#ifndef SQLITE_OMIT_WAL + int i; + for(i=0; inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + int nEntry; + sqlite3BtreeEnter(pBt); + nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt)); + sqlite3BtreeLeave(pBt); + if( nEntry>0 && db->xWalCallback && rc==SQLITE_OK ){ + rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zDbSName, nEntry); + } + } + } +#else + UNUSED_PARAMETER(db); +#endif + return rc; +} + + +/* +** Execute the statement pStmt, either until a row of data is ready, the +** statement is completely executed or an error occurs. +** +** This routine implements the bulk of the logic behind the sqlite_step() +** API. The only thing omitted is the automatic recompile if a +** schema change has occurred. That detail is handled by the +** outer sqlite3_step() wrapper procedure. +*/ +static int sqlite3Step(Vdbe *p){ + sqlite3 *db; + int rc; + + assert(p); + db = p->db; + if( p->eVdbeState!=VDBE_RUN_STATE ){ + restart_step: + if( p->eVdbeState==VDBE_READY_STATE ){ + if( p->expired ){ + p->rc = SQLITE_SCHEMA; + rc = SQLITE_ERROR; + if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 ){ + /* If this statement was prepared using saved SQL and an + ** error has occurred, then return the error code in p->rc to the + ** caller. Set the error code in the database handle to the same + ** value. + */ + rc = sqlite3VdbeTransferError(p); + } + goto end_of_step; + } + + /* If there are no other statements currently running, then + ** reset the interrupt flag. This prevents a call to sqlite3_interrupt + ** from interrupting a statement that has not yet started. + */ + if( db->nVdbeActive==0 ){ + AtomicStore(&db->u1.isInterrupted, 0); + } + + assert( db->nVdbeWrite>0 || db->autoCommit==0 + || ((db->nDeferredCons + db->nDeferredImmCons)==0) + ); + +#ifndef SQLITE_OMIT_TRACE + if( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0 + && !db->init.busy && p->zSql ){ + sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime); + }else{ + assert( p->startTime==0 ); + } +#endif + + db->nVdbeActive++; + if( p->readOnly==0 ) db->nVdbeWrite++; + if( p->bIsReader ) db->nVdbeRead++; + p->pc = 0; + p->eVdbeState = VDBE_RUN_STATE; + }else + + if( ALWAYS(p->eVdbeState==VDBE_HALT_STATE) ){ + /* We used to require that sqlite3_reset() be called before retrying + ** sqlite3_step() after any error or after SQLITE_DONE. But beginning + ** with version 3.7.0, we changed this so that sqlite3_reset() would + ** be called automatically instead of throwing the SQLITE_MISUSE error. + ** This "automatic-reset" change is not technically an incompatibility, + ** since any application that receives an SQLITE_MISUSE is broken by + ** definition. + ** + ** Nevertheless, some published applications that were originally written + ** for version 3.6.23 or earlier do in fact depend on SQLITE_MISUSE + ** returns, and those were broken by the automatic-reset change. As a + ** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the + ** legacy behavior of returning SQLITE_MISUSE for cases where the + ** previous sqlite3_step() returned something other than a SQLITE_LOCKED + ** or SQLITE_BUSY error. + */ +#ifdef SQLITE_OMIT_AUTORESET + if( (rc = p->rc&0xff)==SQLITE_BUSY || rc==SQLITE_LOCKED ){ + sqlite3_reset((sqlite3_stmt*)p); + }else{ + return SQLITE_MISUSE_BKPT; + } +#else + sqlite3_reset((sqlite3_stmt*)p); +#endif + assert( p->eVdbeState==VDBE_READY_STATE ); + goto restart_step; + } + } + +#ifdef SQLITE_DEBUG + p->rcApp = SQLITE_OK; +#endif +#ifndef SQLITE_OMIT_EXPLAIN + if( p->explain ){ + rc = sqlite3VdbeList(p); + }else +#endif /* SQLITE_OMIT_EXPLAIN */ + { + db->nVdbeExec++; + rc = sqlite3VdbeExec(p); + db->nVdbeExec--; + } + + if( rc==SQLITE_ROW ){ + assert( p->rc==SQLITE_OK ); + assert( db->mallocFailed==0 ); + db->errCode = SQLITE_ROW; + return SQLITE_ROW; + }else{ +#ifndef SQLITE_OMIT_TRACE + /* If the statement completed successfully, invoke the profile callback */ + checkProfileCallback(db, p); +#endif + p->pResultRow = 0; + if( rc==SQLITE_DONE && db->autoCommit ){ + assert( p->rc==SQLITE_OK ); + p->rc = doWalCallbacks(db); + if( p->rc!=SQLITE_OK ){ + rc = SQLITE_ERROR; + } + }else if( rc!=SQLITE_DONE && (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 ){ + /* If this statement was prepared using saved SQL and an + ** error has occurred, then return the error code in p->rc to the + ** caller. Set the error code in the database handle to the same value. + */ + rc = sqlite3VdbeTransferError(p); + } + } + + db->errCode = rc; + if( SQLITE_NOMEM==sqlite3ApiExit(p->db, p->rc) ){ + p->rc = SQLITE_NOMEM_BKPT; + if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 ) rc = p->rc; + } +end_of_step: + /* There are only a limited number of result codes allowed from the + ** statements prepared using the legacy sqlite3_prepare() interface */ + assert( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 + || rc==SQLITE_ROW || rc==SQLITE_DONE || rc==SQLITE_ERROR + || (rc&0xff)==SQLITE_BUSY || rc==SQLITE_MISUSE + ); + return (rc&db->errMask); +} + +/* +** This is the top-level implementation of sqlite3_step(). Call +** sqlite3Step() to do most of the work. If a schema error occurs, +** call sqlite3Reprepare() and try again. +*/ +SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){ + int rc = SQLITE_OK; /* Result from sqlite3Step() */ + Vdbe *v = (Vdbe*)pStmt; /* the prepared statement */ + int cnt = 0; /* Counter to prevent infinite loop of reprepares */ + sqlite3 *db; /* The database connection */ + + if( vdbeSafetyNotNull(v) ){ + return SQLITE_MISUSE_BKPT; + } + db = v->db; + sqlite3_mutex_enter(db->mutex); + while( (rc = sqlite3Step(v))==SQLITE_SCHEMA + && cnt++ < SQLITE_MAX_SCHEMA_RETRY ){ + int savedPc = v->pc; + rc = sqlite3Reprepare(v); + if( rc!=SQLITE_OK ){ + /* This case occurs after failing to recompile an sql statement. + ** The error message from the SQL compiler has already been loaded + ** into the database handle. This block copies the error message + ** from the database handle into the statement and sets the statement + ** program counter to 0 to ensure that when the statement is + ** finalized or reset the parser error message is available via + ** sqlite3_errmsg() and sqlite3_errcode(). + */ + const char *zErr = (const char *)sqlite3_value_text(db->pErr); + sqlite3DbFree(db, v->zErrMsg); + if( !db->mallocFailed ){ + v->zErrMsg = sqlite3DbStrDup(db, zErr); + v->rc = rc = sqlite3ApiExit(db, rc); + } else { + v->zErrMsg = 0; + v->rc = rc = SQLITE_NOMEM_BKPT; + } + break; + } + sqlite3_reset(pStmt); + if( savedPc>=0 ){ + /* Setting minWriteFileFormat to 254 is a signal to the OP_Init and + ** OP_Trace opcodes to *not* perform SQLITE_TRACE_STMT because it has + ** already been done once on a prior invocation that failed due to + ** SQLITE_SCHEMA. tag-20220401a */ + v->minWriteFileFormat = 254; + } + assert( v->expired==0 ); + } + sqlite3_mutex_leave(db->mutex); + return rc; +} + + +/* +** Extract the user data from a sqlite3_context structure and return a +** pointer to it. +*/ +SQLITE_API void *sqlite3_user_data(sqlite3_context *p){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ) return 0; +#endif + assert( p && p->pFunc ); + return p->pFunc->pUserData; +} + +/* +** Extract the user data from a sqlite3_context structure and return a +** pointer to it. +** +** IMPLEMENTATION-OF: R-46798-50301 The sqlite3_context_db_handle() interface +** returns a copy of the pointer to the database connection (the 1st +** parameter) of the sqlite3_create_function() and +** sqlite3_create_function16() routines that originally registered the +** application defined function. +*/ +SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ) return 0; +#else + assert( p && p->pOut ); +#endif + return p->pOut->db; +} + +/* +** If this routine is invoked from within an xColumn method of a virtual +** table, then it returns true if and only if the the call is during an +** UPDATE operation and the value of the column will not be modified +** by the UPDATE. +** +** If this routine is called from any context other than within the +** xColumn method of a virtual table, then the return value is meaningless +** and arbitrary. +** +** Virtual table implements might use this routine to optimize their +** performance by substituting a NULL result, or some other light-weight +** value, as a signal to the xUpdate routine that the column is unchanged. +*/ +SQLITE_API int sqlite3_vtab_nochange(sqlite3_context *p){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ) return 0; +#else + assert( p ); +#endif + return sqlite3_value_nochange(p->pOut); +} + +/* +** The destructor function for a ValueList object. This needs to be +** a separate function, unknowable to the application, to ensure that +** calls to sqlite3_vtab_in_first()/sqlite3_vtab_in_next() that are not +** preceded by activation of IN processing via sqlite3_vtab_int() do not +** try to access a fake ValueList object inserted by a hostile extension. +*/ +SQLITE_PRIVATE void sqlite3VdbeValueListFree(void *pToDelete){ + sqlite3_free(pToDelete); +} + +/* +** Implementation of sqlite3_vtab_in_first() (if bNext==0) and +** sqlite3_vtab_in_next() (if bNext!=0). +*/ +static int valueFromValueList( + sqlite3_value *pVal, /* Pointer to the ValueList object */ + sqlite3_value **ppOut, /* Store the next value from the list here */ + int bNext /* 1 for _next(). 0 for _first() */ +){ + int rc; + ValueList *pRhs; + + *ppOut = 0; + if( pVal==0 ) return SQLITE_MISUSE_BKPT; + if( (pVal->flags & MEM_Dyn)==0 || pVal->xDel!=sqlite3VdbeValueListFree ){ + return SQLITE_ERROR; + }else{ + assert( (pVal->flags&(MEM_TypeMask|MEM_Term|MEM_Subtype)) == + (MEM_Null|MEM_Term|MEM_Subtype) ); + assert( pVal->eSubtype=='p' ); + assert( pVal->u.zPType!=0 && strcmp(pVal->u.zPType,"ValueList")==0 ); + pRhs = (ValueList*)pVal->z; + } + if( bNext ){ + rc = sqlite3BtreeNext(pRhs->pCsr, 0); + }else{ + int dummy = 0; + rc = sqlite3BtreeFirst(pRhs->pCsr, &dummy); + assert( rc==SQLITE_OK || sqlite3BtreeEof(pRhs->pCsr) ); + if( sqlite3BtreeEof(pRhs->pCsr) ) rc = SQLITE_DONE; + } + if( rc==SQLITE_OK ){ + u32 sz; /* Size of current row in bytes */ + Mem sMem; /* Raw content of current row */ + memset(&sMem, 0, sizeof(sMem)); + sz = sqlite3BtreePayloadSize(pRhs->pCsr); + rc = sqlite3VdbeMemFromBtreeZeroOffset(pRhs->pCsr,sz,&sMem); + if( rc==SQLITE_OK ){ + u8 *zBuf = (u8*)sMem.z; + u32 iSerial; + sqlite3_value *pOut = pRhs->pOut; + int iOff = 1 + getVarint32(&zBuf[1], iSerial); + sqlite3VdbeSerialGet(&zBuf[iOff], iSerial, pOut); + pOut->enc = ENC(pOut->db); + if( (pOut->flags & MEM_Ephem)!=0 && sqlite3VdbeMemMakeWriteable(pOut) ){ + rc = SQLITE_NOMEM; + }else{ + *ppOut = pOut; + } + } + sqlite3VdbeMemRelease(&sMem); + } + return rc; +} + +/* +** Set the iterator value pVal to point to the first value in the set. +** Set (*ppOut) to point to this value before returning. +*/ +SQLITE_API int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut){ + return valueFromValueList(pVal, ppOut, 0); +} + +/* +** Set the iterator value pVal to point to the next value in the set. +** Set (*ppOut) to point to this value before returning. +*/ +SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut){ + return valueFromValueList(pVal, ppOut, 1); +} + +/* +** Return the current time for a statement. If the current time +** is requested more than once within the same run of a single prepared +** statement, the exact same time is returned for each invocation regardless +** of the amount of time that elapses between invocations. In other words, +** the time returned is always the time of the first call. +*/ +SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){ + int rc; +#ifndef SQLITE_ENABLE_STAT4 + sqlite3_int64 *piTime = &p->pVdbe->iCurrentTime; + assert( p->pVdbe!=0 ); +#else + sqlite3_int64 iTime = 0; + sqlite3_int64 *piTime = p->pVdbe!=0 ? &p->pVdbe->iCurrentTime : &iTime; +#endif + if( *piTime==0 ){ + rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, piTime); + if( rc ) *piTime = 0; + } + return *piTime; +} + +/* +** Create a new aggregate context for p and return a pointer to +** its pMem->z element. +*/ +static SQLITE_NOINLINE void *createAggContext(sqlite3_context *p, int nByte){ + Mem *pMem = p->pMem; + assert( (pMem->flags & MEM_Agg)==0 ); + if( nByte<=0 ){ + sqlite3VdbeMemSetNull(pMem); + pMem->z = 0; + }else{ + sqlite3VdbeMemClearAndResize(pMem, nByte); + pMem->flags = MEM_Agg; + pMem->u.pDef = p->pFunc; + if( pMem->z ){ + memset(pMem->z, 0, nByte); + } + } + return (void*)pMem->z; +} + +/* +** Allocate or return the aggregate context for a user function. A new +** context is allocated on the first call. Subsequent calls return the +** same context that was returned on prior calls. +*/ +SQLITE_API void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){ + assert( p && p->pFunc && p->pFunc->xFinalize ); + assert( sqlite3_mutex_held(p->pOut->db->mutex) ); + testcase( nByte<0 ); + if( (p->pMem->flags & MEM_Agg)==0 ){ + return createAggContext(p, nByte); + }else{ + return (void*)p->pMem->z; + } +} + +/* +** Return the auxiliary data pointer, if any, for the iArg'th argument to +** the user-function defined by pCtx. +** +** The left-most argument is 0. +** +** Undocumented behavior: If iArg is negative then access a cache of +** auxiliary data pointers that is available to all functions within a +** single prepared statement. The iArg values must match. +*/ +SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){ + AuxData *pAuxData; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return 0; +#endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); +#if SQLITE_ENABLE_STAT4 + if( pCtx->pVdbe==0 ) return 0; +#else + assert( pCtx->pVdbe!=0 ); +#endif + for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNextAux){ + if( pAuxData->iAuxArg==iArg && (pAuxData->iAuxOp==pCtx->iOp || iArg<0) ){ + return pAuxData->pAux; + } + } + return 0; +} + +/* +** Set the auxiliary data pointer and delete function, for the iArg'th +** argument to the user-function defined by pCtx. Any previous value is +** deleted by calling the delete function specified when it was set. +** +** The left-most argument is 0. +** +** Undocumented behavior: If iArg is negative then make the data available +** to all functions within the current prepared statement using iArg as an +** access code. +*/ +SQLITE_API void sqlite3_set_auxdata( + sqlite3_context *pCtx, + int iArg, + void *pAux, + void (*xDelete)(void*) +){ + AuxData *pAuxData; + Vdbe *pVdbe; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif + pVdbe= pCtx->pVdbe; + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); +#ifdef SQLITE_ENABLE_STAT4 + if( pVdbe==0 ) goto failed; +#else + assert( pVdbe!=0 ); +#endif + + for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNextAux){ + if( pAuxData->iAuxArg==iArg && (pAuxData->iAuxOp==pCtx->iOp || iArg<0) ){ + break; + } + } + if( pAuxData==0 ){ + pAuxData = sqlite3DbMallocZero(pVdbe->db, sizeof(AuxData)); + if( !pAuxData ) goto failed; + pAuxData->iAuxOp = pCtx->iOp; + pAuxData->iAuxArg = iArg; + pAuxData->pNextAux = pVdbe->pAuxData; + pVdbe->pAuxData = pAuxData; + if( pCtx->isError==0 ) pCtx->isError = -1; + }else if( pAuxData->xDeleteAux ){ + pAuxData->xDeleteAux(pAuxData->pAux); + } + + pAuxData->pAux = pAux; + pAuxData->xDeleteAux = xDelete; + return; + +failed: + if( xDelete ){ + xDelete(pAux); + } +} + +#ifndef SQLITE_OMIT_DEPRECATED +/* +** Return the number of times the Step function of an aggregate has been +** called. +** +** This function is deprecated. Do not use it for new code. It is +** provide only to avoid breaking legacy code. New aggregate function +** implementations should keep their own counts within their aggregate +** context. +*/ +SQLITE_API int sqlite3_aggregate_count(sqlite3_context *p){ + assert( p && p->pMem && p->pFunc && p->pFunc->xFinalize ); + return p->pMem->n; +} +#endif + +/* +** Return the number of columns in the result set for the statement pStmt. +*/ +SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt){ + Vdbe *pVm = (Vdbe *)pStmt; + if( pVm==0 ) return 0; + return pVm->nResColumn; +} + +/* +** Return the number of values available from the current row of the +** currently executing statement pStmt. +*/ +SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt){ + Vdbe *pVm = (Vdbe *)pStmt; + if( pVm==0 || pVm->pResultRow==0 ) return 0; + return pVm->nResColumn; +} + +/* +** Return a pointer to static memory containing an SQL NULL value. +*/ +static const Mem *columnNullValue(void){ + /* Even though the Mem structure contains an element + ** of type i64, on certain architectures (x86) with certain compiler + ** switches (-Os), gcc may align this Mem object on a 4-byte boundary + ** instead of an 8-byte one. This all works fine, except that when + ** running with SQLITE_DEBUG defined the SQLite code sometimes assert()s + ** that a Mem structure is located on an 8-byte boundary. To prevent + ** these assert()s from failing, when building with SQLITE_DEBUG defined + ** using gcc, we force nullMem to be 8-byte aligned using the magical + ** __attribute__((aligned(8))) macro. */ + static const Mem nullMem +#if defined(SQLITE_DEBUG) && defined(__GNUC__) + __attribute__((aligned(8))) +#endif + = { + /* .u = */ {0}, + /* .z = */ (char*)0, + /* .n = */ (int)0, + /* .flags = */ (u16)MEM_Null, + /* .enc = */ (u8)0, + /* .eSubtype = */ (u8)0, + /* .db = */ (sqlite3*)0, + /* .szMalloc = */ (int)0, + /* .uTemp = */ (u32)0, + /* .zMalloc = */ (char*)0, + /* .xDel = */ (void(*)(void*))0, +#ifdef SQLITE_DEBUG + /* .pScopyFrom = */ (Mem*)0, + /* .mScopyFlags= */ 0, + /* .bScopy = */ 0, +#endif + }; + return &nullMem; +} + +/* +** Check to see if column iCol of the given statement is valid. If +** it is, return a pointer to the Mem for the value of that column. +** If iCol is not valid, return a pointer to a Mem which has a value +** of NULL. +*/ +static Mem *columnMem(sqlite3_stmt *pStmt, int i){ + Vdbe *pVm; + Mem *pOut; + + pVm = (Vdbe *)pStmt; + if( pVm==0 ) return (Mem*)columnNullValue(); + assert( pVm->db ); + sqlite3_mutex_enter(pVm->db->mutex); + if( pVm->pResultRow!=0 && inResColumn && i>=0 ){ + pOut = &pVm->pResultRow[i]; + }else{ + sqlite3Error(pVm->db, SQLITE_RANGE); + pOut = (Mem*)columnNullValue(); + } + return pOut; +} + +/* +** This function is called after invoking an sqlite3_value_XXX function on a +** column value (i.e. a value returned by evaluating an SQL expression in the +** select list of a SELECT statement) that may cause a malloc() failure. If +** malloc() has failed, the threads mallocFailed flag is cleared and the result +** code of statement pStmt set to SQLITE_NOMEM. +** +** Specifically, this is called from within: +** +** sqlite3_column_int() +** sqlite3_column_int64() +** sqlite3_column_text() +** sqlite3_column_text16() +** sqlite3_column_double() +** sqlite3_column_bytes() +** sqlite3_column_bytes16() +** sqlite3_column_blob() +*/ +static void columnMallocFailure(sqlite3_stmt *pStmt) +{ + /* If malloc() failed during an encoding conversion within an + ** sqlite3_column_XXX API, then set the return code of the statement to + ** SQLITE_NOMEM. The next call to _step() (if any) will return SQLITE_ERROR + ** and _finalize() will return NOMEM. + */ + Vdbe *p = (Vdbe *)pStmt; + if( p ){ + assert( p->db!=0 ); + assert( sqlite3_mutex_held(p->db->mutex) ); + p->rc = sqlite3ApiExit(p->db, p->rc); + sqlite3_mutex_leave(p->db->mutex); + } +} + +/**************************** sqlite3_column_ ******************************* +** The following routines are used to access elements of the current row +** in the result set. +*/ +SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int i){ + const void *val; + val = sqlite3_value_blob( columnMem(pStmt,i) ); + /* Even though there is no encoding conversion, value_blob() might + ** need to call malloc() to expand the result of a zeroblob() + ** expression. + */ + columnMallocFailure(pStmt); + return val; +} +SQLITE_API int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){ + int val = sqlite3_value_bytes( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return val; +} +SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){ + int val = sqlite3_value_bytes16( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return val; +} +SQLITE_API double sqlite3_column_double(sqlite3_stmt *pStmt, int i){ + double val = sqlite3_value_double( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return val; +} +SQLITE_API int sqlite3_column_int(sqlite3_stmt *pStmt, int i){ + int val = sqlite3_value_int( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return val; +} +SQLITE_API sqlite_int64 sqlite3_column_int64(sqlite3_stmt *pStmt, int i){ + sqlite_int64 val = sqlite3_value_int64( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return val; +} +SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){ + const unsigned char *val = sqlite3_value_text( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return val; +} +SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){ + Mem *pOut = columnMem(pStmt, i); + if( pOut->flags&MEM_Static ){ + pOut->flags &= ~MEM_Static; + pOut->flags |= MEM_Ephem; + } + columnMallocFailure(pStmt); + return (sqlite3_value *)pOut; +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){ + const void *val = sqlite3_value_text16( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return val; +} +#endif /* SQLITE_OMIT_UTF16 */ +SQLITE_API int sqlite3_column_type(sqlite3_stmt *pStmt, int i){ + int iType = sqlite3_value_type( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return iType; +} + +/* +** Column names appropriate for EXPLAIN or EXPLAIN QUERY PLAN. +*/ +static const char * const azExplainColNames8[] = { + "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment", /* EXPLAIN */ + "id", "parent", "notused", "detail" /* EQP */ +}; +static const u16 azExplainColNames16data[] = { + /* 0 */ 'a', 'd', 'd', 'r', 0, + /* 5 */ 'o', 'p', 'c', 'o', 'd', 'e', 0, + /* 12 */ 'p', '1', 0, + /* 15 */ 'p', '2', 0, + /* 18 */ 'p', '3', 0, + /* 21 */ 'p', '4', 0, + /* 24 */ 'p', '5', 0, + /* 27 */ 'c', 'o', 'm', 'm', 'e', 'n', 't', 0, + /* 35 */ 'i', 'd', 0, + /* 38 */ 'p', 'a', 'r', 'e', 'n', 't', 0, + /* 45 */ 'n', 'o', 't', 'u', 's', 'e', 'd', 0, + /* 53 */ 'd', 'e', 't', 'a', 'i', 'l', 0 +}; +static const u8 iExplainColNames16[] = { + 0, 5, 12, 15, 18, 21, 24, 27, + 35, 38, 45, 53 +}; + +/* +** Convert the N-th element of pStmt->pColName[] into a string using +** xFunc() then return that string. If N is out of range, return 0. +** +** There are up to 5 names for each column. useType determines which +** name is returned. Here are the names: +** +** 0 The column name as it should be displayed for output +** 1 The datatype name for the column +** 2 The name of the database that the column derives from +** 3 The name of the table that the column derives from +** 4 The name of the table column that the result column derives from +** +** If the result is not a simple column reference (if it is an expression +** or a constant) then useTypes 2, 3, and 4 return NULL. +*/ +static const void *columnName( + sqlite3_stmt *pStmt, /* The statement */ + int N, /* Which column to get the name for */ + int useUtf16, /* True to return the name as UTF16 */ + int useType /* What type of name */ +){ + const void *ret; + Vdbe *p; + int n; + sqlite3 *db; +#ifdef SQLITE_ENABLE_API_ARMOR + if( pStmt==0 ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + if( N<0 ) return 0; + ret = 0; + p = (Vdbe *)pStmt; + db = p->db; + assert( db!=0 ); + sqlite3_mutex_enter(db->mutex); + + if( p->explain ){ + if( useType>0 ) goto columnName_end; + n = p->explain==1 ? 8 : 4; + if( N>=n ) goto columnName_end; + if( useUtf16 ){ + int i = iExplainColNames16[N + 8*p->explain - 8]; + ret = (void*)&azExplainColNames16data[i]; + }else{ + ret = (void*)azExplainColNames8[N + 8*p->explain - 8]; + } + goto columnName_end; + } + n = p->nResColumn; + if( NmallocFailed; + N += useType*n; +#ifndef SQLITE_OMIT_UTF16 + if( useUtf16 ){ + ret = sqlite3_value_text16((sqlite3_value*)&p->aColName[N]); + }else +#endif + { + ret = sqlite3_value_text((sqlite3_value*)&p->aColName[N]); + } + /* A malloc may have failed inside of the _text() call. If this + ** is the case, clear the mallocFailed flag and return NULL. + */ + assert( db->mallocFailed==0 || db->mallocFailed==1 ); + if( db->mallocFailed > prior_mallocFailed ){ + sqlite3OomClear(db); + ret = 0; + } + } +columnName_end: + sqlite3_mutex_leave(db->mutex); + return ret; +} + +/* +** Return the name of the Nth column of the result set returned by SQL +** statement pStmt. +*/ +SQLITE_API const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, 0, COLNAME_NAME); +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, 1, COLNAME_NAME); +} +#endif + +/* +** Constraint: If you have ENABLE_COLUMN_METADATA then you must +** not define OMIT_DECLTYPE. +*/ +#if defined(SQLITE_OMIT_DECLTYPE) && defined(SQLITE_ENABLE_COLUMN_METADATA) +# error "Must not define both SQLITE_OMIT_DECLTYPE \ + and SQLITE_ENABLE_COLUMN_METADATA" +#endif + +#ifndef SQLITE_OMIT_DECLTYPE +/* +** Return the column declaration type (if applicable) of the 'i'th column +** of the result set of SQL statement pStmt. +*/ +SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, 0, COLNAME_DECLTYPE); +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, 1, COLNAME_DECLTYPE); +} +#endif /* SQLITE_OMIT_UTF16 */ +#endif /* SQLITE_OMIT_DECLTYPE */ + +#ifdef SQLITE_ENABLE_COLUMN_METADATA +/* +** Return the name of the database from which a result column derives. +** NULL is returned if the result column is an expression or constant or +** anything else which is not an unambiguous reference to a database column. +*/ +SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, 0, COLNAME_DATABASE); +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, 1, COLNAME_DATABASE); +} +#endif /* SQLITE_OMIT_UTF16 */ + +/* +** Return the name of the table from which a result column derives. +** NULL is returned if the result column is an expression or constant or +** anything else which is not an unambiguous reference to a database column. +*/ +SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, 0, COLNAME_TABLE); +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, 1, COLNAME_TABLE); +} +#endif /* SQLITE_OMIT_UTF16 */ + +/* +** Return the name of the table column from which a result column derives. +** NULL is returned if the result column is an expression or constant or +** anything else which is not an unambiguous reference to a database column. +*/ +SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, 0, COLNAME_COLUMN); +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){ + return columnName(pStmt, N, 1, COLNAME_COLUMN); +} +#endif /* SQLITE_OMIT_UTF16 */ +#endif /* SQLITE_ENABLE_COLUMN_METADATA */ + + +/******************************* sqlite3_bind_ *************************** +** +** Routines used to attach values to wildcards in a compiled SQL statement. +*/ +/* +** Unbind the value bound to variable i in virtual machine p. This is the +** the same as binding a NULL value to the column. If the "i" parameter is +** out of range, then SQLITE_RANGE is returned. Otherwise SQLITE_OK. +** +** A successful evaluation of this routine acquires the mutex on p. +** the mutex is released if any kind of error occurs. +** +** The error code stored in database p->db is overwritten with the return +** value in any case. +** +** (tag-20240917-01) If vdbeUnbind(p,(u32)(i-1)) returns SQLITE_OK, +** that means all of the the following will be true: +** +** p!=0 +** p->pVar!=0 +** i>0 +** i<=p->nVar +** +** An assert() is normally added after vdbeUnbind() to help static analyzers +** realize this. +*/ +static int vdbeUnbind(Vdbe *p, unsigned int i){ + Mem *pVar; + if( vdbeSafetyNotNull(p) ){ + return SQLITE_MISUSE_BKPT; + } + sqlite3_mutex_enter(p->db->mutex); + if( p->eVdbeState!=VDBE_READY_STATE ){ + sqlite3Error(p->db, SQLITE_MISUSE_BKPT); + sqlite3_mutex_leave(p->db->mutex); + sqlite3_log(SQLITE_MISUSE, + "bind on a busy prepared statement: [%s]", p->zSql); + return SQLITE_MISUSE_BKPT; + } + if( i>=(unsigned int)p->nVar ){ + sqlite3Error(p->db, SQLITE_RANGE); + sqlite3_mutex_leave(p->db->mutex); + return SQLITE_RANGE; + } + pVar = &p->aVar[i]; + sqlite3VdbeMemRelease(pVar); + pVar->flags = MEM_Null; + p->db->errCode = SQLITE_OK; + + /* If the bit corresponding to this variable in Vdbe.expmask is set, then + ** binding a new value to this variable invalidates the current query plan. + ** + ** IMPLEMENTATION-OF: R-57496-20354 If the specific value bound to a host + ** parameter in the WHERE clause might influence the choice of query plan + ** for a statement, then the statement will be automatically recompiled, + ** as if there had been a schema change, on the first sqlite3_step() call + ** following any change to the bindings of that parameter. + */ + assert( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 || p->expmask==0 ); + if( p->expmask!=0 && (p->expmask & (i>=31 ? 0x80000000 : (u32)1<expired = 1; + } + return SQLITE_OK; +} + +/* +** Bind a text or BLOB value. +*/ +static int bindText( + sqlite3_stmt *pStmt, /* The statement to bind against */ + int i, /* Index of the parameter to bind */ + const void *zData, /* Pointer to the data to be bound */ + i64 nData, /* Number of bytes of data to be bound */ + void (*xDel)(void*), /* Destructor for the data */ + u8 encoding /* Encoding for the data */ +){ + Vdbe *p = (Vdbe *)pStmt; + Mem *pVar; + int rc; + + rc = vdbeUnbind(p, (u32)(i-1)); + if( rc==SQLITE_OK ){ + assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ + if( zData!=0 ){ + pVar = &p->aVar[i-1]; + if( encoding==SQLITE_UTF8 ){ + rc = sqlite3VdbeMemSetText(pVar, zData, nData, xDel); + }else if( encoding==SQLITE_UTF8_ZT ){ + /* It is usually consider improper to assert() on an input. + ** However, the following assert() is checking for inputs + ** that are documented to result in undefined behavior. */ + assert( zData==0 + || nData<0 + || nData>pVar->db->aLimit[SQLITE_LIMIT_LENGTH] + || ((u8*)zData)[nData]==0 + ); + rc = sqlite3VdbeMemSetText(pVar, zData, nData, xDel); + pVar->flags |= MEM_Term; + }else{ + rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel); + if( encoding==0 ) pVar->enc = ENC(p->db); + } + if( rc==SQLITE_OK && encoding!=0 ){ + rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db)); + } + if( rc ){ + sqlite3Error(p->db, rc); + rc = sqlite3ApiExit(p->db, rc); + } + } + sqlite3_mutex_leave(p->db->mutex); + }else if( xDel!=SQLITE_STATIC && xDel!=SQLITE_TRANSIENT ){ + xDel((void*)zData); + } + return rc; +} + + +/* +** Bind a blob value to an SQL statement variable. +*/ +SQLITE_API int sqlite3_bind_blob( + sqlite3_stmt *pStmt, + int i, + const void *zData, + int nData, + void (*xDel)(void*) +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( nData<0 ) return SQLITE_MISUSE_BKPT; +#endif + return bindText(pStmt, i, zData, nData, xDel, 0); +} +SQLITE_API int sqlite3_bind_blob64( + sqlite3_stmt *pStmt, + int i, + const void *zData, + sqlite3_uint64 nData, + void (*xDel)(void*) +){ + assert( xDel!=SQLITE_DYNAMIC ); + return bindText(pStmt, i, zData, nData, xDel, 0); +} +SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){ + int rc; + Vdbe *p = (Vdbe *)pStmt; + rc = vdbeUnbind(p, (u32)(i-1)); + if( rc==SQLITE_OK ){ + assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ + sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue); + sqlite3_mutex_leave(p->db->mutex); + } + return rc; +} +SQLITE_API int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){ + return sqlite3_bind_int64(p, i, (i64)iValue); +} +SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){ + int rc; + Vdbe *p = (Vdbe *)pStmt; + rc = vdbeUnbind(p, (u32)(i-1)); + if( rc==SQLITE_OK ){ + assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ + sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue); + sqlite3_mutex_leave(p->db->mutex); + } + return rc; +} +SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){ + int rc; + Vdbe *p = (Vdbe*)pStmt; + rc = vdbeUnbind(p, (u32)(i-1)); + if( rc==SQLITE_OK ){ + assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ + sqlite3_mutex_leave(p->db->mutex); + } + return rc; +} +SQLITE_API int sqlite3_bind_pointer( + sqlite3_stmt *pStmt, + int i, + void *pPtr, + const char *zPTtype, + void (*xDestructor)(void*) +){ + int rc; + Vdbe *p = (Vdbe*)pStmt; + rc = vdbeUnbind(p, (u32)(i-1)); + if( rc==SQLITE_OK ){ + assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ + sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zPTtype, xDestructor); + sqlite3_mutex_leave(p->db->mutex); + }else if( xDestructor ){ + xDestructor(pPtr); + } + return rc; +} +SQLITE_API int sqlite3_bind_text( + sqlite3_stmt *pStmt, + int i, + const char *zData, + int nData, + void (*xDel)(void*) +){ + return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8); +} +SQLITE_API int sqlite3_bind_text64( + sqlite3_stmt *pStmt, + int i, + const char *zData, + sqlite3_uint64 nData, + void (*xDel)(void*), + unsigned char enc +){ + assert( xDel!=SQLITE_DYNAMIC ); + if( enc!=SQLITE_UTF8 && enc!=SQLITE_UTF8_ZT ){ + if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; + nData &= ~(u64)1; + } + return bindText(pStmt, i, zData, nData, xDel, enc); +} +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API int sqlite3_bind_text16( + sqlite3_stmt *pStmt, + int i, + const void *zData, + int n, + void (*xDel)(void*) +){ + return bindText(pStmt, i, zData, n & ~(u64)1, xDel, SQLITE_UTF16NATIVE); +} +#endif /* SQLITE_OMIT_UTF16 */ +SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){ + int rc; + switch( sqlite3_value_type((sqlite3_value*)pValue) ){ + case SQLITE_INTEGER: { + rc = sqlite3_bind_int64(pStmt, i, pValue->u.i); + break; + } + case SQLITE_FLOAT: { + assert( pValue->flags & (MEM_Real|MEM_IntReal) ); + rc = sqlite3_bind_double(pStmt, i, + (pValue->flags & MEM_Real) ? pValue->u.r : (double)pValue->u.i + ); + break; + } + case SQLITE_BLOB: { + if( pValue->flags & MEM_Zero ){ + rc = sqlite3_bind_zeroblob(pStmt, i, pValue->u.nZero); + }else{ + rc = sqlite3_bind_blob(pStmt, i, pValue->z, pValue->n,SQLITE_TRANSIENT); + } + break; + } + case SQLITE_TEXT: { + rc = bindText(pStmt,i, pValue->z, pValue->n, SQLITE_TRANSIENT, + pValue->enc); + break; + } + default: { + rc = sqlite3_bind_null(pStmt, i); + break; + } + } + return rc; +} +SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){ + int rc; + Vdbe *p = (Vdbe *)pStmt; + rc = vdbeUnbind(p, (u32)(i-1)); + if( rc==SQLITE_OK ){ + assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ +#ifndef SQLITE_OMIT_INCRBLOB + sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n); +#else + rc = sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n); +#endif + sqlite3_mutex_leave(p->db->mutex); + } + return rc; +} +SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt *pStmt, int i, sqlite3_uint64 n){ + int rc; + Vdbe *p = (Vdbe *)pStmt; +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(p->db->mutex); + if( n>(u64)p->db->aLimit[SQLITE_LIMIT_LENGTH] ){ + rc = SQLITE_TOOBIG; + }else{ + assert( (n & 0x7FFFFFFF)==n ); + rc = sqlite3_bind_zeroblob(pStmt, i, n); + } + rc = sqlite3ApiExit(p->db, rc); + sqlite3_mutex_leave(p->db->mutex); + return rc; +} + +/* +** Return the number of wildcards that can be potentially bound to. +** This routine is added to support DBD::SQLite. +*/ +SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){ + Vdbe *p = (Vdbe*)pStmt; + return p ? p->nVar : 0; +} + +/* +** Return the name of a wildcard parameter. Return NULL if the index +** is out of range or if the wildcard is unnamed. +** +** The result is always UTF-8. +*/ +SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){ + Vdbe *p = (Vdbe*)pStmt; + if( p==0 ) return 0; + return sqlite3VListNumToName(p->pVList, i); +} + +/* +** Given a wildcard parameter name, return the index of the variable +** with that name. If there is no variable with the given name, +** return 0. +*/ +SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nName){ + if( p==0 || zName==0 ) return 0; + return sqlite3VListNameToNum(p->pVList, zName, nName); +} +SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){ + return sqlite3VdbeParameterIndex((Vdbe*)pStmt, zName, sqlite3Strlen30(zName)); +} + +/* +** Transfer all bindings from the first statement over to the second. +*/ +SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){ + Vdbe *pFrom = (Vdbe*)pFromStmt; + Vdbe *pTo = (Vdbe*)pToStmt; + int i; + assert( pTo->db==pFrom->db ); + assert( pTo->nVar==pFrom->nVar ); + sqlite3_mutex_enter(pTo->db->mutex); + for(i=0; inVar; i++){ + sqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]); + } + sqlite3_mutex_leave(pTo->db->mutex); + return SQLITE_OK; +} + +#ifndef SQLITE_OMIT_DEPRECATED +/* +** Deprecated external interface. Internal/core SQLite code +** should call sqlite3TransferBindings. +** +** It is misuse to call this routine with statements from different +** database connections. But as this is a deprecated interface, we +** will not bother to check for that condition. +** +** If the two statements contain a different number of bindings, then +** an SQLITE_ERROR is returned. Nothing else can go wrong, so otherwise +** SQLITE_OK is returned. +*/ +SQLITE_API int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){ + Vdbe *pFrom = (Vdbe*)pFromStmt; + Vdbe *pTo = (Vdbe*)pToStmt; + if( pFrom->nVar!=pTo->nVar ){ + return SQLITE_ERROR; + } + assert( (pTo->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 || pTo->expmask==0 ); + if( pTo->expmask ){ + pTo->expired = 1; + } + assert( (pFrom->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 || pFrom->expmask==0 ); + if( pFrom->expmask ){ + pFrom->expired = 1; + } + return sqlite3TransferBindings(pFromStmt, pToStmt); +} +#endif + +/* +** Return the sqlite3* database handle to which the prepared statement given +** in the argument belongs. This is the same database handle that was +** the first argument to the sqlite3_prepare() that was used to create +** the statement in the first place. +*/ +SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){ + return pStmt ? ((Vdbe*)pStmt)->db : 0; +} + +/* +** Return true if the prepared statement is guaranteed to not modify the +** database. +*/ +SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){ + return pStmt ? ((Vdbe*)pStmt)->readOnly : 1; +} + +/* +** Return 1 if the statement is an EXPLAIN and return 2 if the +** statement is an EXPLAIN QUERY PLAN +*/ +SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt){ + return pStmt ? ((Vdbe*)pStmt)->explain : 0; +} + +/* +** Set the explain mode for a statement. +*/ +SQLITE_API int sqlite3_stmt_explain(sqlite3_stmt *pStmt, int eMode){ + Vdbe *v = (Vdbe*)pStmt; + int rc; +#ifdef SQLITE_ENABLE_API_ARMOR + if( pStmt==0 ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(v->db->mutex); + if( ((int)v->explain)==eMode ){ + rc = SQLITE_OK; + }else if( eMode<0 || eMode>2 ){ + rc = SQLITE_ERROR; + }else if( (v->prepFlags & SQLITE_PREPARE_SAVESQL)==0 ){ + rc = SQLITE_ERROR; + }else if( v->eVdbeState!=VDBE_READY_STATE ){ + rc = SQLITE_BUSY; + }else if( v->nMem>=10 && (eMode!=2 || v->haveEqpOps) ){ + /* No reprepare necessary */ + v->explain = eMode; + rc = SQLITE_OK; + }else{ + v->explain = eMode; + rc = sqlite3Reprepare(v); + v->haveEqpOps = eMode==2; + } + if( v->explain ){ + v->nResColumn = 12 - 4*v->explain; + }else{ + v->nResColumn = v->nResAlloc; + } + sqlite3_mutex_leave(v->db->mutex); + return rc; +} + +/* +** Return true if the prepared statement is in need of being reset. +*/ +SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){ + Vdbe *v = (Vdbe*)pStmt; + return v!=0 && v->eVdbeState==VDBE_RUN_STATE; +} + +/* +** Return a pointer to the next prepared statement after pStmt associated +** with database connection pDb. If pStmt is NULL, return the first +** prepared statement for the database connection. Return NULL if there +** are no more. +*/ +SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){ + sqlite3_stmt *pNext; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(pDb) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(pDb->mutex); + if( pStmt==0 ){ + pNext = (sqlite3_stmt*)pDb->pVdbe; + }else{ + pNext = (sqlite3_stmt*)((Vdbe*)pStmt)->pVNext; + } + sqlite3_mutex_leave(pDb->mutex); + return pNext; +} + +/* +** Return the value of a status counter for a prepared statement +*/ +SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){ + Vdbe *pVdbe = (Vdbe*)pStmt; + u32 v; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !pStmt + || (op!=SQLITE_STMTSTATUS_MEMUSED && (op<0||op>=ArraySize(pVdbe->aCounter))) + ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + if( op==SQLITE_STMTSTATUS_MEMUSED ){ + sqlite3 *db = pVdbe->db; + sqlite3_mutex_enter(db->mutex); + v = 0; + db->pnBytesFreed = (int*)&v; + assert( db->lookaside.pEnd==db->lookaside.pTrueEnd ); + db->lookaside.pEnd = db->lookaside.pStart; + sqlite3VdbeDelete(pVdbe); + db->pnBytesFreed = 0; + db->lookaside.pEnd = db->lookaside.pTrueEnd; + sqlite3_mutex_leave(db->mutex); + }else{ + v = pVdbe->aCounter[op]; + if( resetFlag ) pVdbe->aCounter[op] = 0; + } + return (int)v; +} + +/* +** Return the SQL associated with a prepared statement +*/ +SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt){ + Vdbe *p = (Vdbe *)pStmt; + return p ? p->zSql : 0; +} + +/* +** Return the SQL associated with a prepared statement with +** bound parameters expanded. Space to hold the returned string is +** obtained from sqlite3_malloc(). The caller is responsible for +** freeing the returned string by passing it to sqlite3_free(). +** +** The SQLITE_TRACE_SIZE_LIMIT puts an upper bound on the size of +** expanded bound parameters. +*/ +SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt){ +#ifdef SQLITE_OMIT_TRACE + return 0; +#else + char *z = 0; + const char *zSql = sqlite3_sql(pStmt); + if( zSql ){ + Vdbe *p = (Vdbe *)pStmt; + sqlite3_mutex_enter(p->db->mutex); + z = sqlite3VdbeExpandSql(p, zSql); + sqlite3_mutex_leave(p->db->mutex); + } + return z; +#endif +} + +#ifdef SQLITE_ENABLE_NORMALIZE +/* +** Return the normalized SQL associated with a prepared statement. +*/ +SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt){ + Vdbe *p = (Vdbe *)pStmt; + if( p==0 ) return 0; + if( p->zNormSql==0 && ALWAYS(p->zSql!=0) ){ + sqlite3_mutex_enter(p->db->mutex); + p->zNormSql = sqlite3Normalize(p, p->zSql); + sqlite3_mutex_leave(p->db->mutex); + } + return p->zNormSql; +} +#endif /* SQLITE_ENABLE_NORMALIZE */ + +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +/* +** Allocate and populate an UnpackedRecord structure based on the serialized +** record in nKey/pKey. Return a pointer to the new UnpackedRecord structure +** if successful, or a NULL pointer if an OOM error is encountered. +*/ +static UnpackedRecord *vdbeUnpackRecord( + KeyInfo *pKeyInfo, + int nKey, + const void *pKey +){ + UnpackedRecord *pRet; /* Return value */ + + pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); + if( pRet ){ + memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nKeyField+1)); + sqlite3VdbeRecordUnpack(nKey, pKey, pRet); + } + return pRet; +} + +/* +** This function is called from within a pre-update callback to retrieve +** a field of the row currently being updated or deleted. +*/ +SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ + PreUpdate *p; + Mem *pMem; + int rc = SQLITE_OK; + int iStore = 0; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( db==0 || ppValue==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + p = db->pPreUpdate; + /* Test that this call is being made from within an SQLITE_DELETE or + ** SQLITE_UPDATE pre-update callback, and that iIdx is within range. */ + if( !p || p->op==SQLITE_INSERT ){ + rc = SQLITE_MISUSE_BKPT; + goto preupdate_old_out; + } + if( p->pPk ){ + iStore = sqlite3TableColumnToIndex(p->pPk, iIdx); + }else if( iIdx >= p->pTab->nCol ){ + rc = SQLITE_MISUSE_BKPT; + goto preupdate_old_out; + }else{ + iStore = sqlite3TableColumnToStorage(p->pTab, iIdx); + } + if( iStore>=p->pCsr->nField || iStore<0 ){ + rc = SQLITE_RANGE; + goto preupdate_old_out; + } + + if( iIdx==p->pTab->iPKey ){ + *ppValue = pMem = &p->oldipk; + sqlite3VdbeMemSetInt64(pMem, p->iKey1); + }else{ + + /* If the old.* record has not yet been loaded into memory, do so now. */ + if( p->pUnpacked==0 ){ + u32 nRec; + u8 *aRec; + + assert( p->pCsr->eCurType==CURTYPE_BTREE ); + nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor); + aRec = sqlite3DbMallocRaw(db, nRec); + if( !aRec ) goto preupdate_old_out; + rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec); + if( rc==SQLITE_OK ){ + p->pUnpacked = vdbeUnpackRecord(p->pKeyinfo, nRec, aRec); + if( !p->pUnpacked ) rc = SQLITE_NOMEM; + } + if( rc!=SQLITE_OK ){ + sqlite3DbFree(db, aRec); + goto preupdate_old_out; + } + p->aRecord = aRec; + } + + pMem = *ppValue = &p->pUnpacked->aMem[iStore]; + if( iStore>=p->pUnpacked->nField ){ + /* This occurs when the table has been extended using ALTER TABLE + ** ADD COLUMN. The value to return is the default value of the column. */ + Column *pCol = &p->pTab->aCol[iIdx]; + if( pCol->iDflt>0 ){ + if( p->apDflt==0 ){ + int nByte; + assert( sizeof(sqlite3_value*)*UMXV(p->pTab->nCol) < 0x7fffffff ); + nByte = sizeof(sqlite3_value*)*p->pTab->nCol; + p->apDflt = (sqlite3_value**)sqlite3DbMallocZero(db, nByte); + if( p->apDflt==0 ) goto preupdate_old_out; + } + if( p->apDflt[iIdx]==0 ){ + sqlite3_value *pVal = 0; + Expr *pDflt; + assert( p->pTab!=0 && IsOrdinaryTable(p->pTab) ); + pDflt = p->pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr; + rc = sqlite3ValueFromExpr(db, pDflt, ENC(db), pCol->affinity, &pVal); + if( rc==SQLITE_OK && pVal==0 ){ + rc = SQLITE_CORRUPT_BKPT; + } + p->apDflt[iIdx] = pVal; + } + *ppValue = p->apDflt[iIdx]; + }else{ + *ppValue = (sqlite3_value *)columnNullValue(); + } + }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){ + if( pMem->flags & (MEM_Int|MEM_IntReal) ){ + testcase( pMem->flags & MEM_Int ); + testcase( pMem->flags & MEM_IntReal ); + sqlite3VdbeMemRealify(pMem); + } + } + } + + preupdate_old_out: + sqlite3Error(db, rc); + return sqlite3ApiExit(db, rc); +} +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ + +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +/* +** This function is called from within a pre-update callback to retrieve +** the number of columns in the row being updated, deleted or inserted. +*/ +SQLITE_API int sqlite3_preupdate_count(sqlite3 *db){ + PreUpdate *p; +#ifdef SQLITE_ENABLE_API_ARMOR + p = db!=0 ? db->pPreUpdate : 0; +#else + p = db->pPreUpdate; +#endif + return (p ? p->pKeyinfo->nKeyField : 0); +} +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ + +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +/* +** This function is designed to be called from within a pre-update callback +** only. It returns zero if the change that caused the callback was made +** immediately by a user SQL statement. Or, if the change was made by a +** trigger program, it returns the number of trigger programs currently +** on the stack (1 for a top-level trigger, 2 for a trigger fired by a +** top-level trigger etc.). +** +** For the purposes of the previous paragraph, a foreign key CASCADE, SET NULL +** or SET DEFAULT action is considered a trigger. +*/ +SQLITE_API int sqlite3_preupdate_depth(sqlite3 *db){ + PreUpdate *p; +#ifdef SQLITE_ENABLE_API_ARMOR + p = db!=0 ? db->pPreUpdate : 0; +#else + p = db->pPreUpdate; +#endif + return (p ? p->v->nFrame : 0); +} +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ + +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +/* +** This function is designed to be called from within a pre-update callback +** only. +*/ +SQLITE_API int sqlite3_preupdate_blobwrite(sqlite3 *db){ + PreUpdate *p; +#ifdef SQLITE_ENABLE_API_ARMOR + p = db!=0 ? db->pPreUpdate : 0; +#else + p = db->pPreUpdate; +#endif + return (p ? p->iBlobWrite : -1); +} +#endif + +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +/* +** This function is called from within a pre-update callback to retrieve +** a field of the row currently being updated or inserted. +*/ +SQLITE_API int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ + PreUpdate *p; + int rc = SQLITE_OK; + Mem *pMem; + int iStore = 0; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( db==0 || ppValue==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + p = db->pPreUpdate; + if( !p || p->op==SQLITE_DELETE ){ + rc = SQLITE_MISUSE_BKPT; + goto preupdate_new_out; + } + if( p->pPk && p->op!=SQLITE_UPDATE ){ + iStore = sqlite3TableColumnToIndex(p->pPk, iIdx); + }else if( iIdx >= p->pTab->nCol ){ + return SQLITE_MISUSE_BKPT; + }else{ + iStore = sqlite3TableColumnToStorage(p->pTab, iIdx); + } + + if( iStore>=p->pCsr->nField || iStore<0 ){ + rc = SQLITE_RANGE; + goto preupdate_new_out; + } + + if( p->op==SQLITE_INSERT ){ + /* For an INSERT, memory cell p->iNewReg contains the serialized record + ** that is being inserted. Deserialize it. */ + UnpackedRecord *pUnpack = p->pNewUnpacked; + if( !pUnpack ){ + Mem *pData = &p->v->aMem[p->iNewReg]; + rc = ExpandBlob(pData); + if( rc!=SQLITE_OK ) goto preupdate_new_out; + pUnpack = vdbeUnpackRecord(p->pKeyinfo, pData->n, pData->z); + if( !pUnpack ){ + rc = SQLITE_NOMEM; + goto preupdate_new_out; + } + p->pNewUnpacked = pUnpack; + } + pMem = &pUnpack->aMem[iStore]; + if( iIdx==p->pTab->iPKey ){ + sqlite3VdbeMemSetInt64(pMem, p->iKey2); + }else if( iStore>=pUnpack->nField ){ + pMem = (sqlite3_value *)columnNullValue(); + } + }else{ + /* For an UPDATE, memory cell (p->iNewReg+1+iStore) contains the required + ** value. Make a copy of the cell contents and return a pointer to it. + ** It is not safe to return a pointer to the memory cell itself as the + ** caller may modify the value text encoding. + */ + assert( p->op==SQLITE_UPDATE ); + if( !p->aNew ){ + assert( sizeof(Mem)*UMXV(p->pCsr->nField) < 0x7fffffff ); + p->aNew = (Mem *)sqlite3DbMallocZero(db, sizeof(Mem)*p->pCsr->nField); + if( !p->aNew ){ + rc = SQLITE_NOMEM; + goto preupdate_new_out; + } + } + assert( iStore>=0 && iStorepCsr->nField ); + pMem = &p->aNew[iStore]; + if( pMem->flags==0 ){ + if( iIdx==p->pTab->iPKey ){ + sqlite3VdbeMemSetInt64(pMem, p->iKey2); + }else{ + rc = sqlite3VdbeMemCopy(pMem, &p->v->aMem[p->iNewReg+1+iStore]); + if( rc!=SQLITE_OK ) goto preupdate_new_out; + } + } + } + *ppValue = pMem; + + preupdate_new_out: + sqlite3Error(db, rc); + return sqlite3ApiExit(db, rc); +} +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ + +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS +/* +** Return status data for a single loop within query pStmt. +*/ +SQLITE_API int sqlite3_stmt_scanstatus_v2( + sqlite3_stmt *pStmt, /* Prepared statement being queried */ + int iScan, /* Index of loop to report on */ + int iScanStatusOp, /* Which metric to return */ + int flags, + void *pOut /* OUT: Write the answer here */ +){ + Vdbe *p = (Vdbe*)pStmt; + VdbeOp *aOp; + int nOp; + ScanStatus *pScan = 0; + int idx; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 || pOut==0 + || iScanStatusOpSQLITE_SCANSTAT_NCYCLE ){ + return 1; + } +#endif + aOp = p->aOp; + nOp = p->nOp; + if( p->pFrame ){ + VdbeFrame *pFrame; + for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); + aOp = pFrame->aOp; + nOp = pFrame->nOp; + } + + if( iScan<0 ){ + int ii; + if( iScanStatusOp==SQLITE_SCANSTAT_NCYCLE ){ + i64 res = 0; + for(ii=0; iinScan; idx++){ + pScan = &p->aScan[idx]; + if( pScan->zName ){ + iScan--; + if( iScan<0 ) break; + } + } + } + if( idx>=p->nScan ) return 1; + assert( pScan==0 || pScan==&p->aScan[idx] ); + pScan = &p->aScan[idx]; + + switch( iScanStatusOp ){ + case SQLITE_SCANSTAT_NLOOP: { + if( pScan->addrLoop>0 ){ + *(sqlite3_int64*)pOut = aOp[pScan->addrLoop].nExec; + }else{ + *(sqlite3_int64*)pOut = -1; + } + break; + } + case SQLITE_SCANSTAT_NVISIT: { + if( pScan->addrVisit>0 ){ + *(sqlite3_int64*)pOut = aOp[pScan->addrVisit].nExec; + }else{ + *(sqlite3_int64*)pOut = -1; + } + break; + } + case SQLITE_SCANSTAT_EST: { + double r = 1.0; + LogEst x = pScan->nEst; + while( x<100 ){ + x += 10; + r *= 0.5; + } + *(double*)pOut = r*sqlite3LogEstToInt(x); + break; + } + case SQLITE_SCANSTAT_NAME: { + *(const char**)pOut = pScan->zName; + break; + } + case SQLITE_SCANSTAT_EXPLAIN: { + if( pScan->addrExplain ){ + *(const char**)pOut = aOp[ pScan->addrExplain ].p4.z; + }else{ + *(const char**)pOut = 0; + } + break; + } + case SQLITE_SCANSTAT_SELECTID: { + if( pScan->addrExplain ){ + *(int*)pOut = aOp[ pScan->addrExplain ].p1; + }else{ + *(int*)pOut = -1; + } + break; + } + case SQLITE_SCANSTAT_PARENTID: { + if( pScan->addrExplain ){ + *(int*)pOut = aOp[ pScan->addrExplain ].p2; + }else{ + *(int*)pOut = -1; + } + break; + } + case SQLITE_SCANSTAT_NCYCLE: { + i64 res = 0; + if( pScan->aAddrRange[0]==0 ){ + res = -1; + }else{ + int ii; + for(ii=0; iiaAddrRange); ii+=2){ + int iIns = pScan->aAddrRange[ii]; + int iEnd = pScan->aAddrRange[ii+1]; + if( iIns==0 ) break; + if( iIns>0 ){ + while( iIns<=iEnd ){ + res += aOp[iIns].nCycle; + iIns++; + } + }else{ + int iOp; + for(iOp=0; iOpp1!=iEnd ) continue; + if( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_NCYCLE)==0 ){ + continue; + } + res += aOp[iOp].nCycle; + } + } + } + } + *(i64*)pOut = res; + break; + } + default: { + return 1; + } + } + return 0; +} + +/* +** Return status data for a single loop within query pStmt. +*/ +SQLITE_API int sqlite3_stmt_scanstatus( + sqlite3_stmt *pStmt, /* Prepared statement being queried */ + int iScan, /* Index of loop to report on */ + int iScanStatusOp, /* Which metric to return */ + void *pOut /* OUT: Write the answer here */ +){ + return sqlite3_stmt_scanstatus_v2(pStmt, iScan, iScanStatusOp, 0, pOut); +} + +/* +** Zero all counters associated with the sqlite3_stmt_scanstatus() data. +*/ +SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){ + Vdbe *p = (Vdbe*)pStmt; + int ii; + for(ii=0; p!=0 && iinOp; ii++){ + Op *pOp = &p->aOp[ii]; + pOp->nExec = 0; + pOp->nCycle = 0; + } +} +#endif /* SQLITE_ENABLE_STMT_SCANSTATUS */ + +/************** End of vdbeapi.c *********************************************/ +/************** Begin file vdbetrace.c ***************************************/ +/* +** 2009 November 25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains code used to insert the values of host parameters +** (aka "wildcards") into the SQL text output by sqlite3_trace(). +** +** The Vdbe parse-tree explainer is also found here. +*/ +/* #include "sqliteInt.h" */ +/* #include "vdbeInt.h" */ + +#ifndef SQLITE_OMIT_TRACE + +/* +** zSql is a zero-terminated string of UTF-8 SQL text. Return the number of +** bytes in this text up to but excluding the first character in +** a host parameter. If the text contains no host parameters, return +** the total number of bytes in the text. +*/ +static i64 findNextHostParameter(const char *zSql, i64 *pnToken){ + int tokenType; + i64 nTotal = 0; + i64 n; + + *pnToken = 0; + while( zSql[0] ){ + n = sqlite3GetToken((u8*)zSql, &tokenType); + assert( n>0 && tokenType!=TK_ILLEGAL ); + if( tokenType==TK_VARIABLE ){ + *pnToken = n; + break; + } + nTotal += n; + zSql += n; + } + return nTotal; +} + +/* +** This function returns a pointer to a nul-terminated string in memory +** obtained from sqlite3DbMalloc(). If sqlite3.nVdbeExec is 1, then the +** string contains a copy of zRawSql but with host parameters expanded to +** their current bindings. Or, if sqlite3.nVdbeExec is greater than 1, +** then the returned string holds a copy of zRawSql with "-- " prepended +** to each line of text. +** +** If the SQLITE_TRACE_SIZE_LIMIT macro is defined to an integer, then +** then long strings and blobs are truncated to that many bytes. This +** can be used to prevent unreasonably large trace strings when dealing +** with large (multi-megabyte) strings and blobs. +** +** The calling function is responsible for making sure the memory returned +** is eventually freed. +** +** ALGORITHM: Scan the input string looking for host parameters in any of +** these forms: ?, ?N, $A, @A, :A. Take care to avoid text within +** string literals, quoted identifier names, and comments. For text forms, +** the host parameter index is found by scanning the prepared +** statement for the corresponding OP_Variable opcode. Once the host +** parameter index is known, locate the value in p->aVar[]. Then render +** the value as a literal in place of the host parameter name. +*/ +SQLITE_PRIVATE char *sqlite3VdbeExpandSql( + Vdbe *p, /* The prepared statement being evaluated */ + const char *zRawSql /* Raw text of the SQL statement */ +){ + sqlite3 *db; /* The database connection */ + int idx = 0; /* Index of a host parameter */ + int nextIndex = 1; /* Index of next ? host parameter */ + i64 n; /* Length of a token prefix */ + i64 nToken; /* Length of the parameter token */ + int i; /* Loop counter */ + Mem *pVar; /* Value of a host parameter */ + StrAccum out; /* Accumulate the output here */ +#ifndef SQLITE_OMIT_UTF16 + Mem utf8; /* Used to convert UTF16 into UTF8 for display */ +#endif + + db = p->db; + sqlite3StrAccumInit(&out, 0, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); + if( db->nVdbeExec>1 ){ + while( *zRawSql ){ + const char *zStart = zRawSql; + while( *(zRawSql++)!='\n' && *zRawSql ); + sqlite3_str_append(&out, "-- ", 3); + assert( (zRawSql - zStart) > 0 ); + sqlite3_str_append(&out, zStart, (int)(zRawSql-zStart)); + } + }else if( p->nVar==0 ){ + sqlite3_str_append(&out, zRawSql, sqlite3Strlen30(zRawSql)); + }else{ + while( zRawSql[0] ){ + n = findNextHostParameter(zRawSql, &nToken); + assert( n>0 ); + sqlite3_str_append(&out, zRawSql, n); + zRawSql += n; + assert( zRawSql[0] || nToken==0 ); + if( nToken==0 ) break; + if( zRawSql[0]=='?' ){ + if( nToken>1 ){ + assert( sqlite3Isdigit(zRawSql[1]) ); + sqlite3GetInt32(&zRawSql[1], &idx); + }else{ + idx = nextIndex; + } + }else{ + assert( zRawSql[0]==':' || zRawSql[0]=='$' || + zRawSql[0]=='@' || zRawSql[0]=='#' ); + testcase( zRawSql[0]==':' ); + testcase( zRawSql[0]=='$' ); + testcase( zRawSql[0]=='@' ); + testcase( zRawSql[0]=='#' ); + idx = sqlite3VdbeParameterIndex(p, zRawSql, nToken); + assert( idx>0 ); + } + zRawSql += nToken; + nextIndex = MAX(idx + 1, nextIndex); + assert( idx>0 && idx<=p->nVar ); + pVar = &p->aVar[idx-1]; + if( pVar->flags & MEM_Null ){ + sqlite3_str_append(&out, "NULL", 4); + }else if( pVar->flags & (MEM_Int|MEM_IntReal) ){ + sqlite3_str_appendf(&out, "%lld", pVar->u.i); + }else if( pVar->flags & MEM_Real ){ + sqlite3_str_appendf(&out, "%!.15g", pVar->u.r); + }else if( pVar->flags & MEM_Str ){ + int nOut; /* Number of bytes of the string text to include in output */ +#ifndef SQLITE_OMIT_UTF16 + u8 enc = ENC(db); + if( enc!=SQLITE_UTF8 ){ + memset(&utf8, 0, sizeof(utf8)); + utf8.db = db; + sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC); + if( SQLITE_NOMEM==sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8) ){ + out.accError = SQLITE_NOMEM; + out.nAlloc = 0; + } + pVar = &utf8; + } +#endif + nOut = pVar->n; +#ifdef SQLITE_TRACE_SIZE_LIMIT + if( nOut>SQLITE_TRACE_SIZE_LIMIT ){ + nOut = SQLITE_TRACE_SIZE_LIMIT; + while( nOutn && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; } + } +#endif + sqlite3_str_appendf(&out, "'%.*q'", nOut, pVar->z); +#ifdef SQLITE_TRACE_SIZE_LIMIT + if( nOutn ){ + sqlite3_str_appendf(&out, "/*+%d bytes*/", pVar->n-nOut); + } +#endif +#ifndef SQLITE_OMIT_UTF16 + if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8); +#endif + }else if( pVar->flags & MEM_Zero ){ + sqlite3_str_appendf(&out, "zeroblob(%d)", pVar->u.nZero); + }else{ + int nOut; /* Number of bytes of the blob to include in output */ + assert( pVar->flags & MEM_Blob ); + sqlite3_str_append(&out, "x'", 2); + nOut = pVar->n; +#ifdef SQLITE_TRACE_SIZE_LIMIT + if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT; +#endif + for(i=0; iz[i]&0xff); + } + sqlite3_str_append(&out, "'", 1); +#ifdef SQLITE_TRACE_SIZE_LIMIT + if( nOutn ){ + sqlite3_str_appendf(&out, "/*+%d bytes*/", pVar->n-nOut); + } +#endif + } + } + } + if( out.accError ) sqlite3_str_reset(&out); + return sqlite3StrAccumFinish(&out); +} + +#endif /* #ifndef SQLITE_OMIT_TRACE */ + +/************** End of vdbetrace.c *******************************************/ +/************** Begin file vdbe.c ********************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** The code in this file implements the function that runs the +** bytecode of a prepared statement. +** +** Various scripts scan this source file in order to generate HTML +** documentation, headers files, or other derived files. The formatting +** of the code in this file is, therefore, important. See other comments +** in this file for details. If in doubt, do not deviate from existing +** commenting and indentation practices when changing or adding code. +*/ +/* #include "sqliteInt.h" */ +/* #include "vdbeInt.h" */ + +/* +** High-resolution hardware timer used for debugging and testing only. +*/ +#if defined(VDBE_PROFILE) \ + || defined(SQLITE_PERFORMANCE_TRACE) \ + || defined(SQLITE_ENABLE_STMT_SCANSTATUS) +/************** Include hwtime.h in the middle of vdbe.c *********************/ +/************** Begin file hwtime.h ******************************************/ +/* +** 2008 May 27 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains inline asm code for retrieving "high-performance" +** counters for x86 and x86_64 class CPUs. +*/ +#ifndef SQLITE_HWTIME_H +#define SQLITE_HWTIME_H + +#if defined(_MSC_VER) && defined(_WIN32) + +/* #include "windows.h" */ + #include + + __inline sqlite3_uint64 sqlite3Hwtime(void){ + LARGE_INTEGER tm; + QueryPerformanceCounter(&tm); + return (sqlite3_uint64)tm.QuadPart; + } + +#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && \ + (defined(i386) || defined(__i386__) || defined(_M_IX86)) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned int lo, hi; + __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); + return (sqlite_uint64)hi << 32 | lo; + } + +#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__)) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned int lo, hi; + __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); + return (sqlite_uint64)hi << 32 | lo; + } + +#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && defined(__aarch64__) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + sqlite3_uint64 cnt; + __asm__ __volatile__ ("mrs %0, cntvct_el0" : "=r" (cnt)); + return cnt; + } + +#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__)) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned long long retval; + unsigned long junk; + __asm__ __volatile__ ("\n\ + 1: mftbu %1\n\ + mftb %L0\n\ + mftbu %0\n\ + cmpw %0,%1\n\ + bne 1b" + : "=r" (retval), "=r" (junk)); + return retval; + } + +#else + + /* + ** asm() is needed for hardware timing support. Without asm(), + ** disable the sqlite3Hwtime() routine. + ** + ** sqlite3Hwtime() is only used for some obscure debugging + ** and analysis configurations, not in any deliverable, so this + ** should not be a great loss. + */ +SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } + +#endif + +#endif /* !defined(SQLITE_HWTIME_H) */ + +/************** End of hwtime.h **********************************************/ +/************** Continuing where we left off in vdbe.c ***********************/ +#endif + +/* +** Invoke this macro on memory cells just prior to changing the +** value of the cell. This macro verifies that shallow copies are +** not misused. A shallow copy of a string or blob just copies a +** pointer to the string or blob, not the content. If the original +** is changed while the copy is still in use, the string or blob might +** be changed out from under the copy. This macro verifies that nothing +** like that ever happens. +*/ +#ifdef SQLITE_DEBUG +# define memAboutToChange(P,M) sqlite3VdbeMemAboutToChange(P,M) +#else +# define memAboutToChange(P,M) +#endif + +/* +** The following global variable is incremented every time a cursor +** moves, either by the OP_SeekXX, OP_Next, or OP_Prev opcodes. The test +** procedures use this information to make sure that indices are +** working correctly. This variable has no function other than to +** help verify the correct operation of the library. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_search_count = 0; +#endif + +/* +** When this global variable is positive, it gets decremented once before +** each instruction in the VDBE. When it reaches zero, the u1.isInterrupted +** field of the sqlite3 structure is set in order to simulate an interrupt. +** +** This facility is used for testing purposes only. It does not function +** in an ordinary build. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_interrupt_count = 0; +#endif + +/* +** The next global variable is incremented each type the OP_Sort opcode +** is executed. The test procedures use this information to make sure that +** sorting is occurring or not occurring at appropriate times. This variable +** has no function other than to help verify the correct operation of the +** library. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_sort_count = 0; +#endif + +/* +** The next global variable records the size of the largest MEM_Blob +** or MEM_Str that has been used by a VDBE opcode. The test procedures +** use this information to make sure that the zero-blob functionality +** is working correctly. This variable has no function other than to +** help verify the correct operation of the library. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_max_blobsize = 0; +static void updateMaxBlobsize(Mem *p){ + if( (p->flags & (MEM_Str|MEM_Blob))!=0 && p->n>sqlite3_max_blobsize ){ + sqlite3_max_blobsize = p->n; + } +} +#endif + +/* +** This macro evaluates to true if either the update hook or the preupdate +** hook are enabled for database connect DB. +*/ +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +# define HAS_UPDATE_HOOK(DB) ((DB)->xPreUpdateCallback||(DB)->xUpdateCallback) +#else +# define HAS_UPDATE_HOOK(DB) ((DB)->xUpdateCallback) +#endif + +/* +** The next global variable is incremented each time the OP_Found opcode +** is executed. This is used to test whether or not the foreign key +** operation implemented using OP_FkIsZero is working. This variable +** has no function other than to help verify the correct operation of the +** library. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_found_count = 0; +#endif + +/* +** Test a register to see if it exceeds the current maximum blob size. +** If it does, record the new maximum blob size. +*/ +#if defined(SQLITE_TEST) && !defined(SQLITE_UNTESTABLE) +# define UPDATE_MAX_BLOBSIZE(P) updateMaxBlobsize(P) +#else +# define UPDATE_MAX_BLOBSIZE(P) +#endif + +#ifdef SQLITE_DEBUG +/* This routine provides a convenient place to set a breakpoint during +** tracing with PRAGMA vdbe_trace=on. The breakpoint fires right after +** each opcode is printed. Variables "pc" (program counter) and pOp are +** available to add conditionals to the breakpoint. GDB example: +** +** break test_trace_breakpoint if pc=22 +** +** Other useful labels for breakpoints include: +** test_addop_breakpoint(pc,pOp) +** sqlite3CorruptError(lineno) +** sqlite3MisuseError(lineno) +** sqlite3CantopenError(lineno) +*/ +static void test_trace_breakpoint(int pc, Op *pOp, Vdbe *v){ + static u64 n = 0; + (void)pc; + (void)pOp; + (void)v; + n++; + if( n==LARGEST_UINT64 ) abort(); /* So that n is used, preventing a warning */ +} +#endif + +/* +** Invoke the VDBE coverage callback, if that callback is defined. This +** feature is used for test suite validation only and does not appear an +** production builds. +** +** M is the type of branch. I is the direction taken for this instance of +** the branch. +** +** M: 2 - two-way branch (I=0: fall-thru 1: jump ) +** 3 - two-way + NULL (I=0: fall-thru 1: jump 2: NULL ) +** 4 - OP_Jump (I=0: jump p1 1: jump p2 2: jump p3) +** +** In other words, if M is 2, then I is either 0 (for fall-through) or +** 1 (for when the branch is taken). If M is 3, the I is 0 for an +** ordinary fall-through, I is 1 if the branch was taken, and I is 2 +** if the result of comparison is NULL. For M=3, I=2 the jump may or +** may not be taken, depending on the SQLITE_JUMPIFNULL flags in p5. +** When M is 4, that means that an OP_Jump is being run. I is 0, 1, or 2 +** depending on if the operands are less than, equal, or greater than. +** +** iSrcLine is the source code line (from the __LINE__ macro) that +** generated the VDBE instruction combined with flag bits. The source +** code line number is in the lower 24 bits of iSrcLine and the upper +** 8 bytes are flags. The lower three bits of the flags indicate +** values for I that should never occur. For example, if the branch is +** always taken, the flags should be 0x05 since the fall-through and +** alternate branch are never taken. If a branch is never taken then +** flags should be 0x06 since only the fall-through approach is allowed. +** +** Bit 0x08 of the flags indicates an OP_Jump opcode that is only +** interested in equal or not-equal. In other words, I==0 and I==2 +** should be treated as equivalent +** +** Since only a line number is retained, not the filename, this macro +** only works for amalgamation builds. But that is ok, since these macros +** should be no-ops except for special builds used to measure test coverage. +*/ +#if !defined(SQLITE_VDBE_COVERAGE) +# define VdbeBranchTaken(I,M) +#else +# define VdbeBranchTaken(I,M) vdbeTakeBranch(pOp->iSrcLine,I,M) + static void vdbeTakeBranch(u32 iSrcLine, u8 I, u8 M){ + u8 mNever; + assert( I<=2 ); /* 0: fall through, 1: taken, 2: alternate taken */ + assert( M<=4 ); /* 2: two-way branch, 3: three-way branch, 4: OP_Jump */ + assert( I> 24; + assert( (I & mNever)==0 ); + if( sqlite3GlobalConfig.xVdbeBranch==0 ) return; /*NO_TEST*/ + /* Invoke the branch coverage callback with three arguments: + ** iSrcLine - the line number of the VdbeCoverage() macro, with + ** flags removed. + ** I - Mask of bits 0x07 indicating which cases are are + ** fulfilled by this instance of the jump. 0x01 means + ** fall-thru, 0x02 means taken, 0x04 means NULL. Any + ** impossible cases (ex: if the comparison is never NULL) + ** are filled in automatically so that the coverage + ** measurement logic does not flag those impossible cases + ** as missed coverage. + ** M - Type of jump. Same as M argument above + */ + I |= mNever; + if( M==2 ) I |= 0x04; + if( M==4 ){ + I |= 0x08; + if( (mNever&0x08)!=0 && (I&0x05)!=0) I |= 0x05; /*NO_TEST*/ + } + sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg, + iSrcLine&0xffffff, I, M); + } +#endif + +/* +** An ephemeral string value (signified by the MEM_Ephem flag) contains +** a pointer to a dynamically allocated string where some other entity +** is responsible for deallocating that string. Because the register +** does not control the string, it might be deleted without the register +** knowing it. +** +** This routine converts an ephemeral string into a dynamically allocated +** string that the register itself controls. In other words, it +** converts an MEM_Ephem string into a string with P.z==P.zMalloc. +*/ +#define Deephemeralize(P) \ + if( ((P)->flags&MEM_Ephem)!=0 \ + && sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;} + +/* Return true if the cursor was opened using the OP_OpenSorter opcode. */ +#define isSorter(x) ((x)->eCurType==CURTYPE_SORTER) + +/* +** Allocate VdbeCursor number iCur. Return a pointer to it. Return NULL +** if we run out of memory. +*/ +static VdbeCursor *allocateCursor( + Vdbe *p, /* The virtual machine */ + int iCur, /* Index of the new VdbeCursor */ + int nField, /* Number of fields in the table or index */ + u8 eCurType /* Type of the new cursor */ +){ + /* Find the memory cell that will be used to store the blob of memory + ** required for this VdbeCursor structure. It is convenient to use a + ** vdbe memory cell to manage the memory allocation required for a + ** VdbeCursor structure for the following reasons: + ** + ** * Sometimes cursor numbers are used for a couple of different + ** purposes in a vdbe program. The different uses might require + ** different sized allocations. Memory cells provide growable + ** allocations. + ** + ** * When using ENABLE_MEMORY_MANAGEMENT, memory cell buffers can + ** be freed lazily via the sqlite3_release_memory() API. This + ** minimizes the number of malloc calls made by the system. + ** + ** The memory cell for cursor 0 is aMem[0]. The rest are allocated from + ** the top of the register space. Cursor 1 is at Mem[p->nMem-1]. + ** Cursor 2 is at Mem[p->nMem-2]. And so forth. + */ + Mem *pMem = iCur>0 ? &p->aMem[p->nMem-iCur] : p->aMem; + + i64 nByte; + VdbeCursor *pCx = 0; + nByte = SZ_VDBECURSOR(nField); + assert( ROUND8(nByte)==nByte ); + if( eCurType==CURTYPE_BTREE ) nByte += sqlite3BtreeCursorSize(); + + assert( iCur>=0 && iCurnCursor ); + if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/ + sqlite3VdbeFreeCursorNN(p, p->apCsr[iCur]); + p->apCsr[iCur] = 0; + } + + /* There used to be a call to sqlite3VdbeMemClearAndResize() to make sure + ** the pMem used to hold space for the cursor has enough storage available + ** in pMem->zMalloc. But for the special case of the aMem[] entries used + ** to hold cursors, it is faster to in-line the logic. */ + assert( pMem->flags==MEM_Undefined ); + assert( (pMem->flags & MEM_Dyn)==0 ); + assert( pMem->szMalloc==0 || pMem->z==pMem->zMalloc ); + if( pMem->szMallocszMalloc>0 ){ + sqlite3DbFreeNN(pMem->db, pMem->zMalloc); + } + pMem->z = pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, nByte); + if( pMem->zMalloc==0 ){ + pMem->szMalloc = 0; + return 0; + } + pMem->szMalloc = (int)nByte; + } + + p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->zMalloc; + memset(pCx, 0, offsetof(VdbeCursor,pAltCursor)); + pCx->eCurType = eCurType; + pCx->nField = nField; + pCx->aOffset = &pCx->aType[nField]; + if( eCurType==CURTYPE_BTREE ){ + assert( ROUND8(SZ_VDBECURSOR(nField))==SZ_VDBECURSOR(nField) ); + pCx->uc.pCursor = (BtCursor*)&pMem->z[SZ_VDBECURSOR(nField)]; + sqlite3BtreeCursorZero(pCx->uc.pCursor); + } + return pCx; +} + +/* +** The string in pRec is known to look like an integer and to have a +** floating point value of rValue. Return true and set *piValue to the +** integer value if the string is in range to be an integer. Otherwise, +** return false. +*/ +static int alsoAnInt(Mem *pRec, double rValue, i64 *piValue){ + i64 iValue; + iValue = sqlite3RealToI64(rValue); + if( sqlite3RealSameAsInt(rValue,iValue) ){ + *piValue = iValue; + return 1; + } + return 0==sqlite3Atoi64(pRec->z, piValue, pRec->n, pRec->enc); +} + +/* +** Try to convert a value into a numeric representation if we can +** do so without loss of information. In other words, if the string +** looks like a number, convert it into a number. If it does not +** look like a number, leave it alone. +** +** If the bTryForInt flag is true, then extra effort is made to give +** an integer representation. Strings that look like floating point +** values but which have no fractional component (example: '48.00') +** will have a MEM_Int representation when bTryForInt is true. +** +** If bTryForInt is false, then if the input string contains a decimal +** point or exponential notation, the result is only MEM_Real, even +** if there is an exact integer representation of the quantity. +*/ +static void applyNumericAffinity(Mem *pRec, int bTryForInt){ + double rValue; + int rc; + assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real|MEM_IntReal))==MEM_Str ); + rc = sqlite3MemRealValueRC(pRec, &rValue); + if( rc<=0 ) return; + if( (rc&2)==0 && alsoAnInt(pRec, rValue, &pRec->u.i) ){ + pRec->flags |= MEM_Int; + }else{ + pRec->u.r = rValue; + pRec->flags |= MEM_Real; + if( bTryForInt ) sqlite3VdbeIntegerAffinity(pRec); + } + /* TEXT->NUMERIC is many->one. Hence, it is important to invalidate the + ** string representation after computing a numeric equivalent, because the + ** string representation might not be the canonical representation for the + ** numeric value. Ticket [343634942dd54ab57b7024] 2018-01-31. */ + pRec->flags &= ~MEM_Str; +} + +/* +** Processing is determine by the affinity parameter: +** +** SQLITE_AFF_INTEGER: +** SQLITE_AFF_REAL: +** SQLITE_AFF_NUMERIC: +** Try to convert pRec to an integer representation or a +** floating-point representation if an integer representation +** is not possible. Note that the integer representation is +** always preferred, even if the affinity is REAL, because +** an integer representation is more space efficient on disk. +** +** SQLITE_AFF_FLEXNUM: +** If the value is text, then try to convert it into a number of +** some kind (integer or real) but do not make any other changes. +** +** SQLITE_AFF_TEXT: +** Convert pRec to a text representation. +** +** SQLITE_AFF_BLOB: +** SQLITE_AFF_NONE: +** No-op. pRec is unchanged. +*/ +static void applyAffinity( + Mem *pRec, /* The value to apply affinity to */ + char affinity, /* The affinity to be applied */ + u8 enc /* Use this text encoding */ +){ + if( affinity>=SQLITE_AFF_NUMERIC ){ + assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL + || affinity==SQLITE_AFF_NUMERIC || affinity==SQLITE_AFF_FLEXNUM ); + if( (pRec->flags & MEM_Int)==0 ){ /*OPTIMIZATION-IF-FALSE*/ + if( (pRec->flags & (MEM_Real|MEM_IntReal))==0 ){ + if( pRec->flags & MEM_Str ) applyNumericAffinity(pRec,1); + }else if( affinity<=SQLITE_AFF_REAL ){ + sqlite3VdbeIntegerAffinity(pRec); + } + } + }else if( affinity==SQLITE_AFF_TEXT ){ + /* Only attempt the conversion to TEXT if there is an integer or real + ** representation (blob and NULL do not get converted) but no string + ** representation. It would be harmless to repeat the conversion if + ** there is already a string rep, but it is pointless to waste those + ** CPU cycles. */ + if( 0==(pRec->flags&MEM_Str) ){ /*OPTIMIZATION-IF-FALSE*/ + if( (pRec->flags&(MEM_Real|MEM_Int|MEM_IntReal)) ){ + testcase( pRec->flags & MEM_Int ); + testcase( pRec->flags & MEM_Real ); + testcase( pRec->flags & MEM_IntReal ); + sqlite3VdbeMemStringify(pRec, enc, 1); + } + } + pRec->flags &= ~(MEM_Real|MEM_Int|MEM_IntReal); + } +} + +/* +** Try to convert the type of a function argument or a result column +** into a numeric representation. Use either INTEGER or REAL whichever +** is appropriate. But only do the conversion if it is possible without +** loss of information and return the revised type of the argument. +*/ +SQLITE_API int sqlite3_value_numeric_type(sqlite3_value *pVal){ + int eType = sqlite3_value_type(pVal); + if( eType==SQLITE_TEXT ){ + Mem *pMem = (Mem*)pVal; + assert( pMem->db!=0 ); + sqlite3_mutex_enter(pMem->db->mutex); + applyNumericAffinity(pMem, 0); + sqlite3_mutex_leave(pMem->db->mutex); + eType = sqlite3_value_type(pVal); + } + return eType; +} + +/* +** Exported version of applyAffinity(). This one works on sqlite3_value*, +** not the internal Mem* type. +*/ +SQLITE_PRIVATE void sqlite3ValueApplyAffinity( + sqlite3_value *pVal, + u8 affinity, + u8 enc +){ + applyAffinity((Mem *)pVal, affinity, enc); +} + +/* +** pMem currently only holds a string type (or maybe a BLOB that we can +** interpret as a string if we want to). Compute its corresponding +** numeric type, if has one. Set the pMem->u.r and pMem->u.i fields +** accordingly. +*/ +static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){ + int rc; + sqlite3_int64 ix; + assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 ); + assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ); + if( ExpandBlob(pMem) ){ + pMem->u.i = 0; + return MEM_Int; + } + rc = sqlite3MemRealValueRC(pMem, &pMem->u.r); + if( rc<=0 ){ + if( (rc&2)==0 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1 ){ + pMem->u.i = ix; + return MEM_Int; + }else{ + return MEM_Real; + } + }else if( (rc&2)==0 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)==0 ){ + pMem->u.i = ix; + return MEM_Int; + } + return MEM_Real; +} + +/* +** Return the numeric type for pMem, either MEM_Int or MEM_Real or both or +** none. +** +** Unlike applyNumericAffinity(), this routine does not modify pMem->flags. +** But it does set pMem->u.r and pMem->u.i appropriately. +*/ +static u16 numericType(Mem *pMem){ + assert( (pMem->flags & MEM_Null)==0 + || pMem->db==0 || pMem->db->mallocFailed ); + if( pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null) ){ + testcase( pMem->flags & MEM_Int ); + testcase( pMem->flags & MEM_Real ); + testcase( pMem->flags & MEM_IntReal ); + return pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null); + } + assert( pMem->flags & (MEM_Str|MEM_Blob) ); + testcase( pMem->flags & MEM_Str ); + testcase( pMem->flags & MEM_Blob ); + return computeNumericType(pMem); + return 0; +} + +#ifdef SQLITE_DEBUG +/* +** Write a nice string representation of the contents of cell pMem +** into buffer zBuf, length nBuf. +*/ +SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, StrAccum *pStr){ + int f = pMem->flags; + static const char *const encnames[] = {"(X)", "(8)", "(16LE)", "(16BE)"}; + if( f&MEM_Blob ){ + int i; + char c; + if( f & MEM_Dyn ){ + c = 'z'; + assert( (f & (MEM_Static|MEM_Ephem))==0 ); + }else if( f & MEM_Static ){ + c = 't'; + assert( (f & (MEM_Dyn|MEM_Ephem))==0 ); + }else if( f & MEM_Ephem ){ + c = 'e'; + assert( (f & (MEM_Static|MEM_Dyn))==0 ); + }else{ + c = 's'; + } + sqlite3_str_appendf(pStr, "%cx[", c); + for(i=0; i<25 && in; i++){ + sqlite3_str_appendf(pStr, "%02X", ((int)pMem->z[i] & 0xFF)); + } + sqlite3_str_appendf(pStr, "|"); + for(i=0; i<25 && in; i++){ + char z = pMem->z[i]; + sqlite3_str_appendchar(pStr, 1, (z<32||z>126)?'.':z); + } + sqlite3_str_appendf(pStr,"]"); + if( f & MEM_Zero ){ + sqlite3_str_appendf(pStr, "+%dz",pMem->u.nZero); + } + }else if( f & MEM_Str ){ + int j; + u8 c; + if( f & MEM_Dyn ){ + c = 'z'; + assert( (f & (MEM_Static|MEM_Ephem))==0 ); + }else if( f & MEM_Static ){ + c = 't'; + assert( (f & (MEM_Dyn|MEM_Ephem))==0 ); + }else if( f & MEM_Ephem ){ + c = 'e'; + assert( (f & (MEM_Static|MEM_Dyn))==0 ); + }else{ + c = 's'; + } + sqlite3_str_appendf(pStr, " %c%d[", c, pMem->n); + for(j=0; j<25 && jn; j++){ + c = pMem->z[j]; + sqlite3_str_appendchar(pStr, 1, (c>=0x20&&c<=0x7f) ? c : '.'); + } + sqlite3_str_appendf(pStr, "]%s", encnames[pMem->enc]); + if( f & MEM_Term ){ + sqlite3_str_appendf(pStr, "(0-term)"); + } + } +} +#endif + +#ifdef SQLITE_DEBUG +/* +** Print the value of a register for tracing purposes: +*/ +static void memTracePrint(Mem *p){ + if( p->flags & MEM_Undefined ){ + printf(" undefined"); + }else if( p->flags & MEM_Null ){ + printf(p->flags & MEM_Zero ? " NULL-nochng" : " NULL"); + }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){ + printf(" si:%lld", p->u.i); + }else if( (p->flags & (MEM_IntReal))!=0 ){ + printf(" ir:%lld", p->u.i); + }else if( p->flags & MEM_Int ){ + printf(" i:%lld", p->u.i); +#ifndef SQLITE_OMIT_FLOATING_POINT + }else if( p->flags & MEM_Real ){ + printf(" r:%.17g", p->u.r); +#endif + }else if( sqlite3VdbeMemIsRowSet(p) ){ + printf(" (rowset)"); + }else{ + StrAccum acc; + char zBuf[1000]; + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); + sqlite3VdbeMemPrettyPrint(p, &acc); + printf(" %s", sqlite3StrAccumFinish(&acc)); + } + if( p->flags & MEM_Subtype ) printf(" subtype=0x%02x", p->eSubtype); +} +static void registerTrace(int iReg, Mem *p){ + printf("R[%d] = ", iReg); + memTracePrint(p); + if( p->pScopyFrom ){ + assert( p->pScopyFrom->bScopy ); + printf(" <== R[%d]", (int)(p->pScopyFrom - &p[-iReg])); + } + printf("\n"); + sqlite3VdbeCheckMemInvariants(p); +} +/**/ void sqlite3PrintMem(Mem *pMem){ + memTracePrint(pMem); + printf("\n"); + fflush(stdout); +} +#endif + +#ifdef SQLITE_DEBUG +/* +** Show the values of all registers in the virtual machine. Used for +** interactive debugging. +*/ +SQLITE_PRIVATE void sqlite3VdbeRegisterDump(Vdbe *v){ + int i; + for(i=1; inMem; i++) registerTrace(i, v->aMem+i); +} +#endif /* SQLITE_DEBUG */ + + +#ifdef SQLITE_DEBUG +# define REGISTER_TRACE(R,M) if(db->flags&SQLITE_VdbeTrace)registerTrace(R,M) +#else +# define REGISTER_TRACE(R,M) +#endif + +#ifndef NDEBUG +/* +** This function is only called from within an assert() expression. It +** checks that the sqlite3.nTransaction variable is correctly set to +** the number of non-transaction savepoints currently in the +** linked list starting at sqlite3.pSavepoint. +** +** Usage: +** +** assert( checkSavepointCount(db) ); +*/ +static int checkSavepointCount(sqlite3 *db){ + int n = 0; + Savepoint *p; + for(p=db->pSavepoint; p; p=p->pNext) n++; + assert( n==(db->nSavepoint + db->isTransactionSavepoint) ); + return 1; +} +#endif + +/* +** Return the register of pOp->p2 after first preparing it to be +** overwritten with an integer value. +*/ +static SQLITE_NOINLINE Mem *out2PrereleaseWithClear(Mem *pOut){ + sqlite3VdbeMemSetNull(pOut); + pOut->flags = MEM_Int; + return pOut; +} +static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){ + Mem *pOut; + assert( pOp->p2>0 ); + assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); + pOut = &p->aMem[pOp->p2]; + memAboutToChange(p, pOut); + if( VdbeMemDynamic(pOut) ){ /*OPTIMIZATION-IF-FALSE*/ + return out2PrereleaseWithClear(pOut); + }else{ + pOut->flags = MEM_Int; + return pOut; + } +} + +/* +** Compute a bloom filter hash using pOp->p4.i registers from aMem[] beginning +** with pOp->p3. Return the hash. +*/ +static u64 filterHash(const Mem *aMem, const Op *pOp){ + int i, mx; + u64 h = 0; + + assert( pOp->p4type==P4_INT32 ); + for(i=pOp->p3, mx=i+pOp->p4.i; iflags & (MEM_Int|MEM_IntReal) ){ + h += p->u.i; + }else if( p->flags & MEM_Real ){ + h += sqlite3VdbeIntValue(p); + }else if( p->flags & (MEM_Str|MEM_Blob) ){ + /* All strings have the same hash and all blobs have the same hash, + ** though, at least, those hashes are different from each other and + ** from NULL. */ + h += 4093 + (p->flags & (MEM_Str|MEM_Blob)); + } + } + return h; +} + + +/* +** For OP_Column, factor out the case where content is loaded from +** overflow pages, so that the code to implement this case is separate +** the common case where all content fits on the page. Factoring out +** the code reduces register pressure and helps the common case +** to run faster. +*/ +static SQLITE_NOINLINE int vdbeColumnFromOverflow( + VdbeCursor *pC, /* The BTree cursor from which we are reading */ + int iCol, /* The column to read */ + u32 t, /* The serial-type code for the column value */ + i64 iOffset, /* Offset to the start of the content value */ + u32 cacheStatus, /* Current Vdbe.cacheCtr value */ + u32 colCacheCtr, /* Current value of the column cache counter */ + Mem *pDest /* Store the value into this register. */ +){ + int rc; + sqlite3 *db = pDest->db; + int encoding = pDest->enc; + int len = sqlite3VdbeSerialTypeLen(t); + assert( pC->eCurType==CURTYPE_BTREE ); + if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) return SQLITE_TOOBIG; + if( len > 4000 && pC->pKeyInfo==0 ){ + /* Cache large column values that are on overflow pages using + ** an RCStr (reference counted string) so that if they are reloaded, + ** that do not have to be copied a second time. The overhead of + ** creating and managing the cache is such that this is only + ** profitable for larger TEXT and BLOB values. + ** + ** Only do this on table-btrees so that writes to index-btrees do not + ** need to clear the cache. This buys performance in the common case + ** in exchange for generality. + */ + VdbeTxtBlbCache *pCache; + char *pBuf; + if( pC->colCache==0 ){ + pC->pCache = sqlite3DbMallocZero(db, sizeof(VdbeTxtBlbCache) ); + if( pC->pCache==0 ) return SQLITE_NOMEM; + pC->colCache = 1; + } + pCache = pC->pCache; + if( pCache->pCValue==0 + || pCache->iCol!=iCol + || pCache->cacheStatus!=cacheStatus + || pCache->colCacheCtr!=colCacheCtr + || pCache->iOffset!=sqlite3BtreeOffset(pC->uc.pCursor) + ){ + if( pCache->pCValue ) sqlite3RCStrUnref(pCache->pCValue); + pBuf = pCache->pCValue = sqlite3RCStrNew( len+3 ); + if( pBuf==0 ) return SQLITE_NOMEM; + rc = sqlite3BtreePayload(pC->uc.pCursor, iOffset, len, pBuf); + if( rc ) return rc; + pBuf[len] = 0; + pBuf[len+1] = 0; + pBuf[len+2] = 0; + pCache->iCol = iCol; + pCache->cacheStatus = cacheStatus; + pCache->colCacheCtr = colCacheCtr; + pCache->iOffset = sqlite3BtreeOffset(pC->uc.pCursor); + }else{ + pBuf = pCache->pCValue; + } + assert( t>=12 ); + sqlite3RCStrRef(pBuf); + if( t&1 ){ + rc = sqlite3VdbeMemSetStr(pDest, pBuf, len, encoding, + sqlite3RCStrUnref); + pDest->flags |= MEM_Term; + }else{ + rc = sqlite3VdbeMemSetStr(pDest, pBuf, len, 0, + sqlite3RCStrUnref); + } + }else{ + rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, iOffset, len, pDest); + if( rc ) return rc; + sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest); + if( (t&1)!=0 && encoding==SQLITE_UTF8 ){ + pDest->z[len] = 0; + pDest->flags |= MEM_Term; + } + } + pDest->flags &= ~MEM_Ephem; + return rc; +} + +/* +** Send a "statement aborts" message to the error log. +*/ +static SQLITE_NOINLINE void sqlite3VdbeLogAbort( + Vdbe *p, /* The statement that is running at the time of failure */ + int rc, /* Error code */ + Op *pOp, /* Opcode that filed */ + Op *aOp /* All opcodes */ +){ + const char *zSql = p->zSql; /* Original SQL text */ + const char *zPrefix = ""; /* Prefix added to SQL text */ + int pc; /* Opcode address */ + char zXtra[100]; /* Buffer space to store zPrefix */ + + if( p->pFrame ){ + assert( aOp[0].opcode==OP_Init ); + if( aOp[0].p4.z!=0 ){ + assert( aOp[0].p4.z[0]=='-' + && aOp[0].p4.z[1]=='-' + && aOp[0].p4.z[2]==' ' ); + sqlite3_snprintf(sizeof(zXtra), zXtra,"/* %s */ ",aOp[0].p4.z+3); + zPrefix = zXtra; + }else{ + zPrefix = "/* unknown trigger */ "; + } + } + pc = (int)(pOp - aOp); + sqlite3_log(rc, "statement aborts at %d: %s; [%s%s]", + pc, p->zErrMsg, zPrefix, zSql); +} + +/* +** Return the symbolic name for the data type of a pMem +*/ +static const char *vdbeMemTypeName(Mem *pMem){ + static const char *azTypes[] = { + /* SQLITE_INTEGER */ "INT", + /* SQLITE_FLOAT */ "REAL", + /* SQLITE_TEXT */ "TEXT", + /* SQLITE_BLOB */ "BLOB", + /* SQLITE_NULL */ "NULL" + }; + return azTypes[sqlite3_value_type(pMem)-1]; +} + +/* +** Execute as much of a VDBE program as we can. +** This is the core of sqlite3_step(). +*/ +SQLITE_PRIVATE int sqlite3VdbeExec( + Vdbe *p /* The VDBE */ +){ + Op *aOp = p->aOp; /* Copy of p->aOp */ + Op *pOp = aOp; /* Current operation */ +#ifdef SQLITE_DEBUG + Op *pOrigOp; /* Value of pOp at the top of the loop */ + int nExtraDelete = 0; /* Verifies FORDELETE and AUXDELETE flags */ + u8 iCompareIsInit = 0; /* iCompare is initialized */ +#endif + int rc = SQLITE_OK; /* Value to return */ + sqlite3 *db = p->db; /* The database */ + u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */ + u8 encoding = ENC(db); /* The database encoding */ + int iCompare = 0; /* Result of last comparison */ + u64 nVmStep = 0; /* Number of virtual machine steps */ +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + u64 nProgressLimit; /* Invoke xProgress() when nVmStep reaches this */ +#endif + Mem *aMem = p->aMem; /* Copy of p->aMem */ + Mem *pIn1 = 0; /* 1st input operand */ + Mem *pIn2 = 0; /* 2nd input operand */ + Mem *pIn3 = 0; /* 3rd input operand */ + Mem *pOut = 0; /* Output operand */ + u32 colCacheCtr = 0; /* Column cache counter */ +#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) + u64 *pnCycle = 0; + int bStmtScanStatus = IS_STMT_SCANSTATUS(db)!=0; +#endif + /*** INSERT STACK UNION HERE ***/ + + assert( p->eVdbeState==VDBE_RUN_STATE ); /* sqlite3_step() verifies this */ + if( DbMaskNonZero(p->lockMask) ){ + sqlite3VdbeEnter(p); + } +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + if( db->xProgress ){ + u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP]; + assert( 0 < db->nProgressOps ); + nProgressLimit = db->nProgressOps - (iPrior % db->nProgressOps); + }else{ + nProgressLimit = LARGEST_UINT64; + } +#endif + if( p->rc==SQLITE_NOMEM ){ + /* This happens if a malloc() inside a call to sqlite3_column_text() or + ** sqlite3_column_text16() failed. */ + goto no_mem; + } + assert( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_BUSY ); + testcase( p->rc!=SQLITE_OK ); + p->rc = SQLITE_OK; + assert( p->bIsReader || p->readOnly!=0 ); + p->iCurrentTime = 0; + assert( p->explain==0 ); + db->busyHandler.nBusy = 0; + if( AtomicLoad(&db->u1.isInterrupted) ) goto abort_due_to_interrupt; + sqlite3VdbeIOTraceSql(p); +#ifdef SQLITE_DEBUG + sqlite3BeginBenignMalloc(); + if( p->pc==0 + && (p->db->flags & (SQLITE_VdbeListing|SQLITE_VdbeEQP|SQLITE_VdbeTrace))!=0 + ){ + int i; + int once = 1; + sqlite3VdbePrintSql(p); + if( p->db->flags & SQLITE_VdbeListing ){ + printf("VDBE Program Listing:\n"); + for(i=0; inOp; i++){ + sqlite3VdbePrintOp(stdout, i, &aOp[i]); + } + } + if( p->db->flags & SQLITE_VdbeEQP ){ + for(i=0; inOp; i++){ + if( aOp[i].opcode==OP_Explain ){ + if( once ) printf("VDBE Query Plan:\n"); + printf("%s\n", aOp[i].p4.z); + once = 0; + } + } + } + if( p->db->flags & SQLITE_VdbeTrace ) printf("VDBE Trace:\n"); + } + sqlite3EndBenignMalloc(); +#endif + for(pOp=&aOp[p->pc]; 1; pOp++){ + /* Errors are detected by individual opcodes, with an immediate + ** jumps to abort_due_to_error. */ + assert( rc==SQLITE_OK ); + + assert( pOp>=aOp && pOp<&aOp[p->nOp]); + nVmStep++; + +#if defined(VDBE_PROFILE) + pOp->nExec++; + pnCycle = &pOp->nCycle; + if( sqlite3NProfileCnt==0 ) *pnCycle -= sqlite3Hwtime(); +#elif defined(SQLITE_ENABLE_STMT_SCANSTATUS) + if( bStmtScanStatus ){ + pOp->nExec++; + pnCycle = &pOp->nCycle; + *pnCycle -= sqlite3Hwtime(); + } +#endif + + /* Only allow tracing if SQLITE_DEBUG is defined. + */ +#ifdef SQLITE_DEBUG + if( db->flags & SQLITE_VdbeTrace ){ + sqlite3VdbePrintOp(stdout, (int)(pOp - aOp), pOp); + test_trace_breakpoint((int)(pOp - aOp),pOp,p); + } +#endif + + + /* Check to see if we need to simulate an interrupt. This only happens + ** if we have a special test build. + */ +#ifdef SQLITE_TEST + if( sqlite3_interrupt_count>0 ){ + sqlite3_interrupt_count--; + if( sqlite3_interrupt_count==0 ){ + sqlite3_interrupt(db); + } + } +#endif + + /* Sanity checking on other operands */ +#ifdef SQLITE_DEBUG + { + u8 opProperty = sqlite3OpcodeProperty[pOp->opcode]; + if( (opProperty & OPFLG_IN1)!=0 ){ + assert( pOp->p1>0 ); + assert( pOp->p1<=(p->nMem+1 - p->nCursor) ); + assert( memIsValid(&aMem[pOp->p1]) ); + assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) ); + REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]); + } + if( (opProperty & OPFLG_IN2)!=0 ){ + assert( pOp->p2>0 ); + assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); + assert( memIsValid(&aMem[pOp->p2]) ); + assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p2]) ); + REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]); + } + if( (opProperty & OPFLG_IN3)!=0 ){ + assert( pOp->p3>0 ); + assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); + assert( memIsValid(&aMem[pOp->p3]) ); + assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p3]) ); + REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]); + } + if( (opProperty & OPFLG_OUT2)!=0 ){ + assert( pOp->p2>0 ); + assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); + memAboutToChange(p, &aMem[pOp->p2]); + } + if( (opProperty & OPFLG_OUT3)!=0 ){ + assert( pOp->p3>0 ); + assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); + memAboutToChange(p, &aMem[pOp->p3]); + } + } +#endif +#ifdef SQLITE_DEBUG + pOrigOp = pOp; +#endif + + switch( pOp->opcode ){ + +/***************************************************************************** +** What follows is a massive switch statement where each case implements a +** separate instruction in the virtual machine. If we follow the usual +** indentation conventions, each case should be indented by 6 spaces. But +** that is a lot of wasted space on the left margin. So the code within +** the switch statement will break with convention and be flush-left. Another +** big comment (similar to this one) will mark the point in the code where +** we transition back to normal indentation. +** +** The formatting of each case is important. The makefile for SQLite +** generates two C files "opcodes.h" and "opcodes.c" by scanning this +** file looking for lines that begin with "case OP_". The opcodes.h files +** will be filled with #defines that give unique integer values to each +** opcode and the opcodes.c file is filled with an array of strings where +** each string is the symbolic name for the corresponding opcode. If the +** case statement is followed by a comment of the form "/# same as ... #/" +** that comment is used to determine the particular value of the opcode. +** +** Other keywords in the comment that follows each case are used to +** construct the OPFLG_INITIALIZER value that initializes opcodeProperty[]. +** Keywords include: in1, in2, in3, out2, out3. See +** the mkopcodeh.awk script for additional information. +** +** Documentation about VDBE opcodes is generated by scanning this file +** for lines of that contain "Opcode:". That line and all subsequent +** comment lines are used in the generation of the opcode.html documentation +** file. +** +** SUMMARY: +** +** Formatting is important to scripts that scan this file. +** Do not deviate from the formatting style currently in use. +** +*****************************************************************************/ + +/* Opcode: Goto * P2 * * * +** +** An unconditional jump to address P2. +** The next instruction executed will be +** the one at index P2 from the beginning of +** the program. +** +** The P1 parameter is not actually used by this opcode. However, it +** is sometimes set to 1 instead of 0 as a hint to the command-line shell +** that this Goto is the bottom of a loop and that the lines from P2 down +** to the current line should be indented for EXPLAIN output. +*/ +case OP_Goto: { /* jump */ + +#ifdef SQLITE_DEBUG + /* In debugging mode, when the p5 flags is set on an OP_Goto, that + ** means we should really jump back to the preceding OP_ReleaseReg + ** instruction. */ + if( pOp->p5 ){ + assert( pOp->p2 < (int)(pOp - aOp) ); + assert( pOp->p2 > 1 ); + pOp = &aOp[pOp->p2 - 2]; + assert( pOp[1].opcode==OP_ReleaseReg ); + goto check_for_interrupt; + } +#endif + +jump_to_p2_and_check_for_interrupt: + pOp = &aOp[pOp->p2 - 1]; + + /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev, + ** OP_VNext, or OP_SorterNext) all jump here upon + ** completion. Check to see if sqlite3_interrupt() has been called + ** or if the progress callback needs to be invoked. + ** + ** This code uses unstructured "goto" statements and does not look clean. + ** But that is not due to sloppy coding habits. The code is written this + ** way for performance, to avoid having to run the interrupt and progress + ** checks on every opcode. This helps sqlite3_step() to run about 1.5% + ** faster according to "valgrind --tool=cachegrind" */ +check_for_interrupt: + if( AtomicLoad(&db->u1.isInterrupted) ) goto abort_due_to_interrupt; +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + /* Call the progress callback if it is configured and the required number + ** of VDBE ops have been executed (either since this invocation of + ** sqlite3VdbeExec() or since last time the progress callback was called). + ** If the progress callback returns non-zero, exit the virtual machine with + ** a return code SQLITE_ABORT. + */ + while( nVmStep>=nProgressLimit && db->xProgress!=0 ){ + assert( db->nProgressOps!=0 ); + nProgressLimit += db->nProgressOps; + if( db->xProgress(db->pProgressArg) ){ + nProgressLimit = LARGEST_UINT64; + rc = SQLITE_INTERRUPT; + goto abort_due_to_error; + } + } +#endif + + break; +} + +/* Opcode: Gosub P1 P2 * * * +** +** Write the current address onto register P1 +** and then jump to address P2. +*/ +case OP_Gosub: { /* jump */ + assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); + pIn1 = &aMem[pOp->p1]; + assert( VdbeMemDynamic(pIn1)==0 ); + memAboutToChange(p, pIn1); + pIn1->flags = MEM_Int; + pIn1->u.i = (int)(pOp-aOp); + REGISTER_TRACE(pOp->p1, pIn1); + goto jump_to_p2_and_check_for_interrupt; +} + +/* Opcode: Return P1 P2 P3 * * +** +** Jump to the address stored in register P1. If P1 is a return address +** register, then this accomplishes a return from a subroutine. +** +** If P3 is 1, then the jump is only taken if register P1 holds an integer +** values, otherwise execution falls through to the next opcode, and the +** OP_Return becomes a no-op. If P3 is 0, then register P1 must hold an +** integer or else an assert() is raised. P3 should be set to 1 when +** this opcode is used in combination with OP_BeginSubrtn, and set to 0 +** otherwise. +** +** The value in register P1 is unchanged by this opcode. +** +** P2 is not used by the byte-code engine. However, if P2 is positive +** and also less than the current address, then the "EXPLAIN" output +** formatter in the CLI will indent all opcodes from the P2 opcode up +** to be not including the current Return. P2 should be the first opcode +** in the subroutine from which this opcode is returning. Thus the P2 +** value is a byte-code indentation hint. See tag-20220407a in +** wherecode.c and shell.c. +*/ +case OP_Return: { /* in1 */ + pIn1 = &aMem[pOp->p1]; + if( pIn1->flags & MEM_Int ){ + if( pOp->p3 ){ VdbeBranchTaken(1, 2); } + pOp = &aOp[pIn1->u.i]; + }else if( ALWAYS(pOp->p3) ){ + VdbeBranchTaken(0, 2); + } + break; +} + +/* Opcode: InitCoroutine P1 P2 P3 * * +** +** Set up register P1 so that it will Yield to the coroutine +** located at address P3. +** +** If P2!=0 then the coroutine implementation immediately follows +** this opcode. So jump over the coroutine implementation to +** address P2. +** +** See also: EndCoroutine +*/ +case OP_InitCoroutine: { /* jump0 */ + assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); + assert( pOp->p2>=0 && pOp->p2nOp ); + assert( pOp->p3>=0 && pOp->p3nOp ); + pOut = &aMem[pOp->p1]; + assert( !VdbeMemDynamic(pOut) ); + pOut->u.i = pOp->p3 - 1; + pOut->flags = MEM_Int; + if( pOp->p2==0 ) break; + + /* Most jump operations do a goto to this spot in order to update + ** the pOp pointer. */ +jump_to_p2: + assert( pOp->p2>0 ); /* There are never any jumps to instruction 0 */ + assert( pOp->p2nOp ); /* Jumps must be in range */ + pOp = &aOp[pOp->p2 - 1]; + break; +} + +/* Opcode: EndCoroutine P1 * * * * +** +** The instruction at the address in register P1 is a Yield. +** Jump to the P2 parameter of that Yield. +** After the jump, the value register P1 is left with a value +** such that subsequent OP_Yields go back to the this same +** OP_EndCoroutine instruction. +** +** See also: InitCoroutine +*/ +case OP_EndCoroutine: { /* in1 */ + VdbeOp *pCaller; + pIn1 = &aMem[pOp->p1]; + assert( pIn1->flags==MEM_Int ); + assert( pIn1->u.i>=0 && pIn1->u.inOp ); + pCaller = &aOp[pIn1->u.i]; + assert( pCaller->opcode==OP_Yield ); + assert( pCaller->p2>=0 && pCaller->p2nOp ); + pIn1->u.i = (int)(pOp - p->aOp) - 1; + pOp = &aOp[pCaller->p2 - 1]; + break; +} + +/* Opcode: Yield P1 P2 * * * +** +** Swap the program counter with the value in register P1. This +** has the effect of yielding to a coroutine. +** +** If the coroutine that is launched by this instruction ends with +** Yield or Return then continue to the next instruction. But if +** the coroutine launched by this instruction ends with +** EndCoroutine, then jump to P2 rather than continuing with the +** next instruction. +** +** See also: InitCoroutine +*/ +case OP_Yield: { /* in1, jump0 */ + int pcDest; + pIn1 = &aMem[pOp->p1]; + assert( VdbeMemDynamic(pIn1)==0 ); + pIn1->flags = MEM_Int; + pcDest = (int)pIn1->u.i; + pIn1->u.i = (int)(pOp - aOp); + REGISTER_TRACE(pOp->p1, pIn1); + pOp = &aOp[pcDest]; + break; +} + +/* Opcode: HaltIfNull P1 P2 P3 P4 P5 +** Synopsis: if r[P3]=null halt +** +** Check the value in register P3. If it is NULL then Halt using +** parameter P1, P2, and P4 as if this were a Halt instruction. If the +** value in register P3 is not NULL, then this routine is a no-op. +** The P5 parameter should be 1. +*/ +case OP_HaltIfNull: { /* in3 */ + pIn3 = &aMem[pOp->p3]; +#ifdef SQLITE_DEBUG + if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); } +#endif + if( (pIn3->flags & MEM_Null)==0 ) break; + /* Fall through into OP_Halt */ + /* no break */ deliberate_fall_through +} + +/* Opcode: Halt P1 P2 P3 P4 P5 +** +** Exit immediately. All open cursors, etc are closed +** automatically. +** +** P1 is the result code returned by sqlite3_exec(), sqlite3_reset(), +** or sqlite3_finalize(). For a normal halt, this should be SQLITE_OK (0). +** For errors, it can be some other value. If P1!=0 then P2 will determine +** whether or not to rollback the current transaction. Do not rollback +** if P2==OE_Fail. Do the rollback if P2==OE_Rollback. If P2==OE_Abort, +** then back out all changes that have occurred during this execution of the +** VDBE, but do not rollback the transaction. +** +** If P3 is not zero and P4 is NULL, then P3 is a register that holds the +** text of an error message. +** +** If P3 is zero and P4 is not null then the error message string is held +** in P4. +** +** P5 is a value between 1 and 4, inclusive, then the P4 error message +** string is modified as follows: +** +** 1: NOT NULL constraint failed: P4 +** 2: UNIQUE constraint failed: P4 +** 3: CHECK constraint failed: P4 +** 4: FOREIGN KEY constraint failed: P4 +** +** If P3 is zero and P5 is not zero and P4 is NULL, then everything after +** the ":" is omitted. +** +** There is an implied "Halt 0 0 0" instruction inserted at the very end of +** every program. So a jump past the last instruction of the program +** is the same as executing Halt. +*/ +case OP_Halt: { + VdbeFrame *pFrame; + int pcx; + +#ifdef SQLITE_DEBUG + if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); } +#endif + assert( pOp->p4type==P4_NOTUSED + || pOp->p4type==P4_STATIC + || pOp->p4type==P4_DYNAMIC ); + + /* A deliberately coded "OP_Halt SQLITE_INTERNAL * * * *" opcode indicates + ** something is wrong with the code generator. Raise an assertion in order + ** to bring this to the attention of fuzzers and other testing tools. */ + assert( pOp->p1!=SQLITE_INTERNAL ); + + if( p->pFrame && pOp->p1==SQLITE_OK ){ + /* Halt the sub-program. Return control to the parent frame. */ + pFrame = p->pFrame; + p->pFrame = pFrame->pParent; + p->nFrame--; + sqlite3VdbeSetChanges(db, p->nChange); + pcx = sqlite3VdbeFrameRestore(pFrame); + if( pOp->p2==OE_Ignore ){ + /* Instruction pcx is the OP_Program that invoked the sub-program + ** currently being halted. If the p2 instruction of this OP_Halt + ** instruction is set to OE_Ignore, then the sub-program is throwing + ** an IGNORE exception. In this case jump to the address specified + ** as the p2 of the calling OP_Program. */ + pcx = p->aOp[pcx].p2-1; + } + aOp = p->aOp; + aMem = p->aMem; + pOp = &aOp[pcx]; + break; + } + p->rc = pOp->p1; + p->errorAction = (u8)pOp->p2; + assert( pOp->p5<=4 ); + if( p->rc ){ + if( pOp->p3>0 && pOp->p4type==P4_NOTUSED ){ + const char *zErr; + assert( pOp->p3<=(p->nMem + 1 - p->nCursor) ); + zErr = sqlite3ValueText(&aMem[pOp->p3], SQLITE_UTF8); + sqlite3VdbeError(p, "%s", zErr); + }else if( pOp->p5 ){ + static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK", + "FOREIGN KEY" }; + testcase( pOp->p5==1 ); + testcase( pOp->p5==2 ); + testcase( pOp->p5==3 ); + testcase( pOp->p5==4 ); + sqlite3VdbeError(p, "%s constraint failed", azType[pOp->p5-1]); + if( pOp->p4.z ){ + p->zErrMsg = sqlite3MPrintf(db, "%z: %s", p->zErrMsg, pOp->p4.z); + } + }else{ + sqlite3VdbeError(p, "%s", pOp->p4.z); + } + sqlite3VdbeLogAbort(p, pOp->p1, pOp, aOp); + } + rc = sqlite3VdbeHalt(p); + assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR ); + if( rc==SQLITE_BUSY ){ + p->rc = SQLITE_BUSY; + }else{ + assert( rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT ); + assert( rc==SQLITE_OK || db->nDeferredCons>0 || db->nDeferredImmCons>0 ); + rc = p->rc ? SQLITE_ERROR : SQLITE_DONE; + } + goto vdbe_return; +} + +/* Opcode: Integer P1 P2 * * * +** Synopsis: r[P2]=P1 +** +** The 32-bit integer value P1 is written into register P2. +*/ +case OP_Integer: { /* out2 */ + pOut = out2Prerelease(p, pOp); + pOut->u.i = pOp->p1; + break; +} + +/* Opcode: Int64 * P2 * P4 * +** Synopsis: r[P2]=P4 +** +** P4 is a pointer to a 64-bit integer value. +** Write that value into register P2. +*/ +case OP_Int64: { /* out2 */ + pOut = out2Prerelease(p, pOp); + assert( pOp->p4.pI64!=0 ); + pOut->u.i = *pOp->p4.pI64; + break; +} + +#ifndef SQLITE_OMIT_FLOATING_POINT +/* Opcode: Real * P2 * P4 * +** Synopsis: r[P2]=P4 +** +** P4 is a pointer to a 64-bit floating point value. +** Write that value into register P2. +*/ +case OP_Real: { /* same as TK_FLOAT, out2 */ + pOut = out2Prerelease(p, pOp); + pOut->flags = MEM_Real; + assert( !sqlite3IsNaN(*pOp->p4.pReal) ); + pOut->u.r = *pOp->p4.pReal; + break; +} +#endif + +/* Opcode: String8 * P2 * P4 * +** Synopsis: r[P2]='P4' +** +** P4 points to a nul terminated UTF-8 string. This opcode is transformed +** into a String opcode before it is executed for the first time. During +** this transformation, the length of string P4 is computed and stored +** as the P1 parameter. +*/ +case OP_String8: { /* same as TK_STRING, out2 */ + assert( pOp->p4.z!=0 ); + pOut = out2Prerelease(p, pOp); + pOp->p1 = sqlite3Strlen30(pOp->p4.z); + +#ifndef SQLITE_OMIT_UTF16 + if( encoding!=SQLITE_UTF8 ){ + rc = sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC); + assert( rc==SQLITE_OK || rc==SQLITE_TOOBIG ); + if( rc ) goto too_big; + if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem; + assert( pOut->szMalloc>0 && pOut->zMalloc==pOut->z ); + assert( VdbeMemDynamic(pOut)==0 ); + pOut->szMalloc = 0; + pOut->flags |= MEM_Static; + if( pOp->p4type==P4_DYNAMIC ){ + sqlite3DbFree(db, pOp->p4.z); + } + pOp->p4type = P4_DYNAMIC; + pOp->p4.z = pOut->z; + pOp->p1 = pOut->n; + } +#endif + if( pOp->p1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + goto too_big; + } + pOp->opcode = OP_String; + assert( rc==SQLITE_OK ); + /* Fall through to the next case, OP_String */ + /* no break */ deliberate_fall_through +} + +/* Opcode: String P1 P2 P3 P4 P5 +** Synopsis: r[P2]='P4' (len=P1) +** +** The string value P4 of length P1 (bytes) is stored in register P2. +** +** If P3 is not zero and the content of register P3 is equal to P5, then +** the datatype of the register P2 is converted to BLOB. The content is +** the same sequence of bytes, it is merely interpreted as a BLOB instead +** of a string, as if it had been CAST. In other words: +** +** if( P3!=0 and reg[P3]==P5 ) reg[P2] := CAST(reg[P2] as BLOB) +*/ +case OP_String: { /* out2 */ + assert( pOp->p4.z!=0 ); + pOut = out2Prerelease(p, pOp); + pOut->flags = MEM_Str|MEM_Static|MEM_Term; + pOut->z = pOp->p4.z; + pOut->n = pOp->p1; + pOut->enc = encoding; + UPDATE_MAX_BLOBSIZE(pOut); +#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS + if( pOp->p3>0 ){ + assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); + pIn3 = &aMem[pOp->p3]; + assert( pIn3->flags & MEM_Int ); + if( pIn3->u.i==pOp->p5 ) pOut->flags = MEM_Blob|MEM_Static|MEM_Term; + } +#endif + break; +} + +/* Opcode: BeginSubrtn * P2 * * * +** Synopsis: r[P2]=NULL +** +** Mark the beginning of a subroutine that can be entered in-line +** or that can be called using OP_Gosub. The subroutine should +** be terminated by an OP_Return instruction that has a P1 operand that +** is the same as the P2 operand to this opcode and that has P3 set to 1. +** If the subroutine is entered in-line, then the OP_Return will simply +** fall through. But if the subroutine is entered using OP_Gosub, then +** the OP_Return will jump back to the first instruction after the OP_Gosub. +** +** This routine works by loading a NULL into the P2 register. When the +** return address register contains a NULL, the OP_Return instruction is +** a no-op that simply falls through to the next instruction (assuming that +** the OP_Return opcode has a P3 value of 1). Thus if the subroutine is +** entered in-line, then the OP_Return will cause in-line execution to +** continue. But if the subroutine is entered via OP_Gosub, then the +** OP_Return will cause a return to the address following the OP_Gosub. +** +** This opcode is identical to OP_Null. It has a different name +** only to make the byte code easier to read and verify. +*/ +/* Opcode: Null P1 P2 P3 * * +** Synopsis: r[P2..P3]=NULL +** +** Write a NULL into registers P2. If P3 greater than P2, then also write +** NULL into register P3 and every register in between P2 and P3. If P3 +** is less than P2 (typically P3 is zero) then only register P2 is +** set to NULL. +** +** If the P1 value is non-zero, then also set the MEM_Cleared flag so that +** NULL values will not compare equal even if SQLITE_NULLEQ is set on +** OP_Ne or OP_Eq. +*/ +case OP_BeginSubrtn: +case OP_Null: { /* out2 */ + int cnt; + u16 nullFlag; + pOut = out2Prerelease(p, pOp); + cnt = pOp->p3-pOp->p2; + assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); + pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null; + pOut->n = 0; +#ifdef SQLITE_DEBUG + pOut->uTemp = 0; +#endif + while( cnt>0 ){ + pOut++; + memAboutToChange(p, pOut); + sqlite3VdbeMemSetNull(pOut); + pOut->flags = nullFlag; + pOut->n = 0; + cnt--; + } + break; +} + +/* Opcode: SoftNull P1 * * * * +** Synopsis: r[P1]=NULL +** +** Set register P1 to have the value NULL as seen by the OP_MakeRecord +** instruction, but do not free any string or blob memory associated with +** the register, so that if the value was a string or blob that was +** previously copied using OP_SCopy, the copies will continue to be valid. +*/ +case OP_SoftNull: { + assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); + pOut = &aMem[pOp->p1]; + pOut->flags = (pOut->flags&~(MEM_Undefined|MEM_AffMask))|MEM_Null; + break; +} + +/* Opcode: Blob P1 P2 * P4 * +** Synopsis: r[P2]=P4 (len=P1) +** +** P4 points to a blob of data P1 bytes long. Store this +** blob in register P2. If P4 is a NULL pointer, then construct +** a zero-filled blob that is P1 bytes long in P2. +*/ +case OP_Blob: { /* out2 */ + assert( pOp->p1 <= SQLITE_MAX_LENGTH ); + pOut = out2Prerelease(p, pOp); + if( pOp->p4.z==0 ){ + sqlite3VdbeMemSetZeroBlob(pOut, pOp->p1); + if( sqlite3VdbeMemExpandBlob(pOut) ) goto no_mem; + }else{ + sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0); + } + pOut->enc = encoding; + UPDATE_MAX_BLOBSIZE(pOut); + break; +} + +/* Opcode: Variable P1 P2 * * * +** Synopsis: r[P2]=parameter(P1) +** +** Transfer the values of bound parameter P1 into register P2 +*/ +case OP_Variable: { /* out2 */ + Mem *pVar; /* Value being transferred */ + + assert( pOp->p1>0 && pOp->p1<=p->nVar ); + pVar = &p->aVar[pOp->p1 - 1]; + if( sqlite3VdbeMemTooBig(pVar) ){ + goto too_big; + } + pOut = &aMem[pOp->p2]; + if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut); + memcpy(pOut, pVar, MEMCELLSIZE); + pOut->flags &= ~(MEM_Dyn|MEM_Ephem); + pOut->flags |= MEM_Static|MEM_FromBind; + UPDATE_MAX_BLOBSIZE(pOut); + break; +} + +/* Opcode: Move P1 P2 P3 * * +** Synopsis: r[P2@P3]=r[P1@P3] +** +** Move the P3 values in register P1..P1+P3-1 over into +** registers P2..P2+P3-1. Registers P1..P1+P3-1 are +** left holding a NULL. It is an error for register ranges +** P1..P1+P3-1 and P2..P2+P3-1 to overlap. It is an error +** for P3 to be less than 1. +*/ +case OP_Move: { + int n; /* Number of registers left to copy */ + int p1; /* Register to copy from */ + int p2; /* Register to copy to */ + + n = pOp->p3; + p1 = pOp->p1; + p2 = pOp->p2; + assert( n>0 && p1>0 && p2>0 ); + assert( p1+n<=p2 || p2+n<=p1 ); + + pIn1 = &aMem[p1]; + pOut = &aMem[p2]; + do{ + assert( pOut<=&aMem[(p->nMem+1 - p->nCursor)] ); + assert( pIn1<=&aMem[(p->nMem+1 - p->nCursor)] ); + assert( memIsValid(pIn1) ); + memAboutToChange(p, pOut); + sqlite3VdbeMemMove(pOut, pIn1); +#ifdef SQLITE_DEBUG + pIn1->pScopyFrom = 0; + { int i; + for(i=1; inMem; i++){ + if( aMem[i].pScopyFrom==pIn1 ){ + assert( aMem[i].bScopy ); + aMem[i].pScopyFrom = pOut; + } + } + } +#endif + Deephemeralize(pOut); + REGISTER_TRACE(p2++, pOut); + pIn1++; + pOut++; + }while( --n ); + break; +} + +/* Opcode: Copy P1 P2 P3 * P5 +** Synopsis: r[P2@P3+1]=r[P1@P3+1] +** +** Make a copy of registers P1..P1+P3 into registers P2..P2+P3. +** +** If the 0x0002 bit of P5 is set then also clear the MEM_Subtype flag in the +** destination. The 0x0001 bit of P5 indicates that this Copy opcode cannot +** be merged. The 0x0001 bit is used by the query planner and does not +** come into play during query execution. +** +** This instruction makes a deep copy of the value. A duplicate +** is made of any string or blob constant. See also OP_SCopy. +*/ +case OP_Copy: { + int n; + + n = pOp->p3; + pIn1 = &aMem[pOp->p1]; + pOut = &aMem[pOp->p2]; + assert( pOut!=pIn1 ); + while( 1 ){ + memAboutToChange(p, pOut); + sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); + Deephemeralize(pOut); + if( (pOut->flags & MEM_Subtype)!=0 && (pOp->p5 & 0x0002)!=0 ){ + pOut->flags &= ~MEM_Subtype; + } +#ifdef SQLITE_DEBUG + pOut->pScopyFrom = 0; +#endif + REGISTER_TRACE(pOp->p2+pOp->p3-n, pOut); + if( (n--)==0 ) break; + pOut++; + pIn1++; + } + break; +} + +/* Opcode: SCopy P1 P2 * * * +** Synopsis: r[P2]=r[P1] +** +** Make a shallow copy of register P1 into register P2. +** +** This instruction makes a shallow copy of the value. If the value +** is a string or blob, then the copy is only a pointer to the +** original and hence if the original changes so will the copy. +** Worse, if the original is deallocated, the copy becomes invalid. +** Thus the program must guarantee that the original will not change +** during the lifetime of the copy. Use OP_Copy to make a complete +** copy. +*/ +case OP_SCopy: { /* out2 */ + pIn1 = &aMem[pOp->p1]; + pOut = &aMem[pOp->p2]; + assert( pOut!=pIn1 ); + sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); +#ifdef SQLITE_DEBUG + pOut->pScopyFrom = pIn1; + pOut->mScopyFlags = pIn1->flags; + pIn1->bScopy = 1; +#endif + break; +} + +/* Opcode: IntCopy P1 P2 * * * +** Synopsis: r[P2]=r[P1] +** +** Transfer the integer value held in register P1 into register P2. +** +** This is an optimized version of SCopy that works only for integer +** values. +*/ +case OP_IntCopy: { /* out2 */ + pIn1 = &aMem[pOp->p1]; + assert( (pIn1->flags & MEM_Int)!=0 ); + pOut = &aMem[pOp->p2]; + sqlite3VdbeMemSetInt64(pOut, pIn1->u.i); + break; +} + +/* Opcode: FkCheck * * * * * +** +** Halt with an SQLITE_CONSTRAINT error if there are any unresolved +** foreign key constraint violations. If there are no foreign key +** constraint violations, this is a no-op. +** +** FK constraint violations are also checked when the prepared statement +** exits. This opcode is used to raise foreign key constraint errors prior +** to returning results such as a row change count or the result of a +** RETURNING clause. +*/ +case OP_FkCheck: { + if( (rc = sqlite3VdbeCheckFkImmediate(p))!=SQLITE_OK ){ + goto abort_due_to_error; + } + break; +} + +/* Opcode: ResultRow P1 P2 * * * +** Synopsis: output=r[P1@P2] +** +** The registers P1 through P1+P2-1 contain a single row of +** results. This opcode causes the sqlite3_step() call to terminate +** with an SQLITE_ROW return code and it sets up the sqlite3_stmt +** structure to provide access to the r(P1)..r(P1+P2-1) values as +** the result row. +*/ +case OP_ResultRow: { + assert( p->nResColumn==pOp->p2 ); + assert( pOp->p1>0 || CORRUPT_DB ); + assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 ); + + p->cacheCtr = (p->cacheCtr + 2)|1; + p->pResultRow = &aMem[pOp->p1]; +#ifdef SQLITE_DEBUG + { + Mem *pMem = p->pResultRow; + int i; + for(i=0; ip2; i++){ + assert( memIsValid(&pMem[i]) ); + REGISTER_TRACE(pOp->p1+i, &pMem[i]); + /* The registers in the result will not be used again when the + ** prepared statement restarts. This is because sqlite3_column() + ** APIs might have caused type conversions of made other changes to + ** the register values. Therefore, we can go ahead and break any + ** OP_SCopy dependencies. */ + pMem[i].pScopyFrom = 0; + } + } +#endif + if( db->mallocFailed ) goto no_mem; + if( db->mTrace & SQLITE_TRACE_ROW ){ + db->trace.xV2(SQLITE_TRACE_ROW, db->pTraceArg, p, 0); + } + p->pc = (int)(pOp - aOp) + 1; + rc = SQLITE_ROW; + goto vdbe_return; +} + +/* Opcode: Concat P1 P2 P3 * * +** Synopsis: r[P3]=r[P2]+r[P1] +** +** Add the text in register P1 onto the end of the text in +** register P2 and store the result in register P3. +** If either the P1 or P2 text are NULL then store NULL in P3. +** +** P3 = P2 || P1 +** +** It is illegal for P1 and P3 to be the same register. Sometimes, +** if P3 is the same register as P2, the implementation is able +** to avoid a memcpy(). +*/ +case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ + i64 nByte; /* Total size of the output string or blob */ + u16 flags1; /* Initial flags for P1 */ + u16 flags2; /* Initial flags for P2 */ + + pIn1 = &aMem[pOp->p1]; + pIn2 = &aMem[pOp->p2]; + pOut = &aMem[pOp->p3]; + testcase( pOut==pIn2 ); + assert( pIn1!=pOut ); + flags1 = pIn1->flags; + testcase( flags1 & MEM_Null ); + testcase( pIn2->flags & MEM_Null ); + if( (flags1 | pIn2->flags) & MEM_Null ){ + sqlite3VdbeMemSetNull(pOut); + break; + } + if( (flags1 & (MEM_Str|MEM_Blob))==0 ){ + if( sqlite3VdbeMemStringify(pIn1,encoding,0) ) goto no_mem; + flags1 = pIn1->flags & ~MEM_Str; + }else if( (flags1 & MEM_Zero)!=0 ){ + if( sqlite3VdbeMemExpandBlob(pIn1) ) goto no_mem; + flags1 = pIn1->flags & ~MEM_Str; + } + flags2 = pIn2->flags; + if( (flags2 & (MEM_Str|MEM_Blob))==0 ){ + if( sqlite3VdbeMemStringify(pIn2,encoding,0) ) goto no_mem; + flags2 = pIn2->flags & ~MEM_Str; + }else if( (flags2 & MEM_Zero)!=0 ){ + if( sqlite3VdbeMemExpandBlob(pIn2) ) goto no_mem; + flags2 = pIn2->flags & ~MEM_Str; + } + nByte = pIn1->n; + nByte += pIn2->n; + if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + goto too_big; + } +#if SQLITE_MAX_LENGTH>2147483645 + if( nByte>2147483645 ){ goto too_big; } +#endif + if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){ + goto no_mem; + } + MemSetTypeFlag(pOut, MEM_Str); + if( pOut!=pIn2 ){ + memcpy(pOut->z, pIn2->z, pIn2->n); + assert( (pIn2->flags & MEM_Dyn) == (flags2 & MEM_Dyn) ); + pIn2->flags = flags2; + } + memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n); + assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) ); + pIn1->flags = flags1; + if( encoding>SQLITE_UTF8 ) nByte &= ~1; + pOut->z[nByte]=0; + pOut->z[nByte+1] = 0; + pOut->flags |= MEM_Term; + pOut->n = (int)nByte; + pOut->enc = encoding; + UPDATE_MAX_BLOBSIZE(pOut); + break; +} + +/* Opcode: Add P1 P2 P3 * * +** Synopsis: r[P3]=r[P1]+r[P2] +** +** Add the value in register P1 to the value in register P2 +** and store the result in register P3. +** If either input is NULL, the result is NULL. +*/ +/* Opcode: Multiply P1 P2 P3 * * +** Synopsis: r[P3]=r[P1]*r[P2] +** +** +** Multiply the value in register P1 by the value in register P2 +** and store the result in register P3. +** If either input is NULL, the result is NULL. +*/ +/* Opcode: Subtract P1 P2 P3 * * +** Synopsis: r[P3]=r[P2]-r[P1] +** +** Subtract the value in register P1 from the value in register P2 +** and store the result in register P3. +** If either input is NULL, the result is NULL. +*/ +/* Opcode: Divide P1 P2 P3 * * +** Synopsis: r[P3]=r[P2]/r[P1] +** +** Divide the value in register P1 by the value in register P2 +** and store the result in register P3 (P3=P2/P1). If the value in +** register P1 is zero, then the result is NULL. If either input is +** NULL, the result is NULL. +*/ +/* Opcode: Remainder P1 P2 P3 * * +** Synopsis: r[P3]=r[P2]%r[P1] +** +** Compute the remainder after integer register P2 is divided by +** register P1 and store the result in register P3. +** If the value in register P1 is zero the result is NULL. +** If either operand is NULL, the result is NULL. +*/ +case OP_Add: /* same as TK_PLUS, in1, in2, out3 */ +case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */ +case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */ +case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */ +case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ + u16 type1; /* Numeric type of left operand */ + u16 type2; /* Numeric type of right operand */ + i64 iA; /* Integer value of left operand */ + i64 iB; /* Integer value of right operand */ + double rA; /* Real value of left operand */ + double rB; /* Real value of right operand */ + + pIn1 = &aMem[pOp->p1]; + type1 = pIn1->flags; + pIn2 = &aMem[pOp->p2]; + type2 = pIn2->flags; + pOut = &aMem[pOp->p3]; + if( (type1 & type2 & MEM_Int)!=0 ){ +int_math: + iA = pIn1->u.i; + iB = pIn2->u.i; + switch( pOp->opcode ){ + case OP_Add: if( sqlite3AddInt64(&iB,iA) ) goto fp_math; break; + case OP_Subtract: if( sqlite3SubInt64(&iB,iA) ) goto fp_math; break; + case OP_Multiply: if( sqlite3MulInt64(&iB,iA) ) goto fp_math; break; + case OP_Divide: { + if( iA==0 ) goto arithmetic_result_is_null; + if( iA==-1 && iB==SMALLEST_INT64 ) goto fp_math; + iB /= iA; + break; + } + default: { + if( iA==0 ) goto arithmetic_result_is_null; + if( iA==-1 ) iA = 1; + iB %= iA; + break; + } + } + pOut->u.i = iB; + MemSetTypeFlag(pOut, MEM_Int); + }else if( ((type1 | type2) & MEM_Null)!=0 ){ + goto arithmetic_result_is_null; + }else{ + type1 = numericType(pIn1); + type2 = numericType(pIn2); + if( (type1 & type2 & MEM_Int)!=0 ) goto int_math; +fp_math: + rA = sqlite3VdbeRealValue(pIn1); + rB = sqlite3VdbeRealValue(pIn2); + switch( pOp->opcode ){ + case OP_Add: rB += rA; break; + case OP_Subtract: rB -= rA; break; + case OP_Multiply: rB *= rA; break; + case OP_Divide: { + /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ + if( rA==(double)0 ) goto arithmetic_result_is_null; + rB /= rA; + break; + } + default: { + iA = sqlite3VdbeIntValue(pIn1); + iB = sqlite3VdbeIntValue(pIn2); + if( iA==0 ) goto arithmetic_result_is_null; + if( iA==-1 ) iA = 1; + rB = (double)(iB % iA); + break; + } + } +#ifdef SQLITE_OMIT_FLOATING_POINT + pOut->u.i = rB; + MemSetTypeFlag(pOut, MEM_Int); +#else + if( sqlite3IsNaN(rB) ){ + goto arithmetic_result_is_null; + } + pOut->u.r = rB; + MemSetTypeFlag(pOut, MEM_Real); +#endif + } + break; + +arithmetic_result_is_null: + sqlite3VdbeMemSetNull(pOut); + break; +} + +/* Opcode: CollSeq P1 * * P4 +** +** P4 is a pointer to a CollSeq object. If the next call to a user function +** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will +** be returned. This is used by the built-in min(), max() and nullif() +** functions. +** +** If P1 is not zero, then it is a register that a subsequent min() or +** max() aggregate will set to 1 if the current row is not the minimum or +** maximum. The P1 register is initialized to 0 by this instruction. +** +** The interface used by the implementation of the aforementioned functions +** to retrieve the collation sequence set by this opcode is not available +** publicly. Only built-in functions have access to this feature. +*/ +case OP_CollSeq: { + assert( pOp->p4type==P4_COLLSEQ ); + if( pOp->p1 ){ + sqlite3VdbeMemSetInt64(&aMem[pOp->p1], 0); + } + break; +} + +/* Opcode: BitAnd P1 P2 P3 * * +** Synopsis: r[P3]=r[P1]&r[P2] +** +** Take the bit-wise AND of the values in register P1 and P2 and +** store the result in register P3. +** If either input is NULL, the result is NULL. +*/ +/* Opcode: BitOr P1 P2 P3 * * +** Synopsis: r[P3]=r[P1]|r[P2] +** +** Take the bit-wise OR of the values in register P1 and P2 and +** store the result in register P3. +** If either input is NULL, the result is NULL. +*/ +/* Opcode: ShiftLeft P1 P2 P3 * * +** Synopsis: r[P3]=r[P2]<>r[P1] +** +** Shift the integer value in register P2 to the right by the +** number of bits specified by the integer in register P1. +** Store the result in register P3. +** If either input is NULL, the result is NULL. +*/ +case OP_BitAnd: /* same as TK_BITAND, in1, in2, out3 */ +case OP_BitOr: /* same as TK_BITOR, in1, in2, out3 */ +case OP_ShiftLeft: /* same as TK_LSHIFT, in1, in2, out3 */ +case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */ + i64 iA; + u64 uA; + i64 iB; + u8 op; + + pIn1 = &aMem[pOp->p1]; + pIn2 = &aMem[pOp->p2]; + pOut = &aMem[pOp->p3]; + if( (pIn1->flags | pIn2->flags) & MEM_Null ){ + sqlite3VdbeMemSetNull(pOut); + break; + } + iA = sqlite3VdbeIntValue(pIn2); + iB = sqlite3VdbeIntValue(pIn1); + op = pOp->opcode; + if( op==OP_BitAnd ){ + iA &= iB; + }else if( op==OP_BitOr ){ + iA |= iB; + }else if( iB!=0 ){ + assert( op==OP_ShiftRight || op==OP_ShiftLeft ); + + /* If shifting by a negative amount, shift in the other direction */ + if( iB<0 ){ + assert( OP_ShiftRight==OP_ShiftLeft+1 ); + op = 2*OP_ShiftLeft + 1 - op; + iB = iB>(-64) ? -iB : 64; + } + + if( iB>=64 ){ + iA = (iA>=0 || op==OP_ShiftLeft) ? 0 : -1; + }else{ + memcpy(&uA, &iA, sizeof(uA)); + if( op==OP_ShiftLeft ){ + uA <<= iB; + }else{ + uA >>= iB; + /* Sign-extend on a right shift of a negative number */ + if( iA<0 ) uA |= ((((u64)0xffffffff)<<32)|0xffffffff) << (64-iB); + } + memcpy(&iA, &uA, sizeof(iA)); + } + } + pOut->u.i = iA; + MemSetTypeFlag(pOut, MEM_Int); + break; +} + +/* Opcode: AddImm P1 P2 * * * +** Synopsis: r[P1]=r[P1]+P2 +** +** Add the constant P2 to the value in register P1. +** The result is always an integer. +** +** To force any register to be an integer, just add 0. +*/ +case OP_AddImm: { /* in1 */ + pIn1 = &aMem[pOp->p1]; + memAboutToChange(p, pIn1); + sqlite3VdbeMemIntegerify(pIn1); + *(u64*)&pIn1->u.i += (u64)pOp->p2; + break; +} + +/* Opcode: MustBeInt P1 P2 * * * +** +** Force the value in register P1 to be an integer. If the value +** in P1 is not an integer and cannot be converted into an integer +** without data loss, then jump immediately to P2, or if P2==0 +** raise an SQLITE_MISMATCH exception. +*/ +case OP_MustBeInt: { /* jump0, in1 */ + pIn1 = &aMem[pOp->p1]; + if( (pIn1->flags & MEM_Int)==0 ){ + applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding); + if( (pIn1->flags & MEM_Int)==0 ){ + VdbeBranchTaken(1, 2); + if( pOp->p2==0 ){ + rc = SQLITE_MISMATCH; + goto abort_due_to_error; + }else{ + goto jump_to_p2; + } + } + } + VdbeBranchTaken(0, 2); + MemSetTypeFlag(pIn1, MEM_Int); + break; +} + +#ifndef SQLITE_OMIT_FLOATING_POINT +/* Opcode: RealAffinity P1 * * * * +** +** If register P1 holds an integer convert it to a real value. +** +** This opcode is used when extracting information from a column that +** has REAL affinity. Such column values may still be stored as +** integers, for space efficiency, but after extraction we want them +** to have only a real value. +*/ +case OP_RealAffinity: { /* in1 */ + pIn1 = &aMem[pOp->p1]; + if( pIn1->flags & (MEM_Int|MEM_IntReal) ){ + testcase( pIn1->flags & MEM_Int ); + testcase( pIn1->flags & MEM_IntReal ); + sqlite3VdbeMemRealify(pIn1); + REGISTER_TRACE(pOp->p1, pIn1); + } + break; +} +#endif + +#if !defined(SQLITE_OMIT_CAST) || !defined(SQLITE_OMIT_ANALYZE) +/* Opcode: Cast P1 P2 * * * +** Synopsis: affinity(r[P1]) +** +** Force the value in register P1 to be the type defined by P2. +** +**
      +**
    • P2=='A' → BLOB +**
    • P2=='B' → TEXT +**
    • P2=='C' → NUMERIC +**
    • P2=='D' → INTEGER +**
    • P2=='E' → REAL +**
    +** +** A NULL value is not changed by this routine. It remains NULL. +*/ +case OP_Cast: { /* in1 */ + assert( pOp->p2>=SQLITE_AFF_BLOB && pOp->p2<=SQLITE_AFF_REAL ); + testcase( pOp->p2==SQLITE_AFF_TEXT ); + testcase( pOp->p2==SQLITE_AFF_BLOB ); + testcase( pOp->p2==SQLITE_AFF_NUMERIC ); + testcase( pOp->p2==SQLITE_AFF_INTEGER ); + testcase( pOp->p2==SQLITE_AFF_REAL ); + pIn1 = &aMem[pOp->p1]; + memAboutToChange(p, pIn1); + rc = ExpandBlob(pIn1); + if( rc ) goto abort_due_to_error; + rc = sqlite3VdbeMemCast(pIn1, pOp->p2, encoding); + if( rc ) goto abort_due_to_error; + UPDATE_MAX_BLOBSIZE(pIn1); + REGISTER_TRACE(pOp->p1, pIn1); + break; +} +#endif /* SQLITE_OMIT_CAST */ + +/* Opcode: Eq P1 P2 P3 P4 P5 +** Synopsis: IF r[P3]==r[P1] +** +** Compare the values in register P1 and P3. If reg(P3)==reg(P1) then +** jump to address P2. +** +** The SQLITE_AFF_MASK portion of P5 must be an affinity character - +** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made +** to coerce both inputs according to this affinity before the +** comparison is made. If the SQLITE_AFF_MASK is 0x00, then numeric +** affinity is used. Note that the affinity conversions are stored +** back into the input registers P1 and P3. So this opcode can cause +** persistent changes to registers P1 and P3. +** +** Once any conversions have taken place, and neither value is NULL, +** the values are compared. If both values are blobs then memcmp() is +** used to determine the results of the comparison. If both values +** are text, then the appropriate collating function specified in +** P4 is used to do the comparison. If P4 is not specified then +** memcmp() is used to compare text string. If both values are +** numeric, then a numeric comparison is used. If the two values +** are of different types, then numbers are considered less than +** strings and strings are considered less than blobs. +** +** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either +** true or false and is never NULL. If both operands are NULL then the result +** of comparison is true. If either operand is NULL then the result is false. +** If neither operand is NULL the result is the same as it would be if +** the SQLITE_NULLEQ flag were omitted from P5. +** +** This opcode saves the result of comparison for use by the new +** OP_Jump opcode. +*/ +/* Opcode: Ne P1 P2 P3 P4 P5 +** Synopsis: IF r[P3]!=r[P1] +** +** This works just like the Eq opcode except that the jump is taken if +** the operands in registers P1 and P3 are not equal. See the Eq opcode for +** additional information. +*/ +/* Opcode: Lt P1 P2 P3 P4 P5 +** Synopsis: IF r[P3]r[P1] +** +** This works just like the Lt opcode except that the jump is taken if +** the content of register P3 is greater than the content of +** register P1. See the Lt opcode for additional information. +*/ +/* Opcode: Ge P1 P2 P3 P4 P5 +** Synopsis: IF r[P3]>=r[P1] +** +** This works just like the Lt opcode except that the jump is taken if +** the content of register P3 is greater than or equal to the content of +** register P1. See the Lt opcode for additional information. +*/ +case OP_Eq: /* same as TK_EQ, jump, in1, in3 */ +case OP_Ne: /* same as TK_NE, jump, in1, in3 */ +case OP_Lt: /* same as TK_LT, jump, in1, in3 */ +case OP_Le: /* same as TK_LE, jump, in1, in3 */ +case OP_Gt: /* same as TK_GT, jump, in1, in3 */ +case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ + int res, res2; /* Result of the comparison of pIn1 against pIn3 */ + char affinity; /* Affinity to use for comparison */ + u16 flags1; /* Copy of initial value of pIn1->flags */ + u16 flags3; /* Copy of initial value of pIn3->flags */ + + pIn1 = &aMem[pOp->p1]; + pIn3 = &aMem[pOp->p3]; + flags1 = pIn1->flags; + flags3 = pIn3->flags; + if( (flags1 & flags3 & MEM_Int)!=0 ){ + /* Common case of comparison of two integers */ + if( pIn3->u.i > pIn1->u.i ){ + if( sqlite3aGTb[pOp->opcode] ){ + VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3); + goto jump_to_p2; + } + iCompare = +1; + VVA_ONLY( iCompareIsInit = 1; ) + }else if( pIn3->u.i < pIn1->u.i ){ + if( sqlite3aLTb[pOp->opcode] ){ + VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3); + goto jump_to_p2; + } + iCompare = -1; + VVA_ONLY( iCompareIsInit = 1; ) + }else{ + if( sqlite3aEQb[pOp->opcode] ){ + VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3); + goto jump_to_p2; + } + iCompare = 0; + VVA_ONLY( iCompareIsInit = 1; ) + } + VdbeBranchTaken(0, (pOp->p5 & SQLITE_NULLEQ)?2:3); + break; + } + if( (flags1 | flags3)&MEM_Null ){ + /* One or both operands are NULL */ + if( pOp->p5 & SQLITE_NULLEQ ){ + /* If SQLITE_NULLEQ is set (which will only happen if the operator is + ** OP_Eq or OP_Ne) then take the jump or not depending on whether + ** or not both operands are null. + */ + assert( (flags1 & MEM_Cleared)==0 ); + assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 || CORRUPT_DB ); + testcase( (pOp->p5 & SQLITE_JUMPIFNULL)!=0 ); + if( (flags1&flags3&MEM_Null)!=0 + && (flags3&MEM_Cleared)==0 + ){ + res = 0; /* Operands are equal */ + }else{ + res = ((flags3 & MEM_Null) ? -1 : +1); /* Operands are not equal */ + } + }else{ + /* SQLITE_NULLEQ is clear and at least one operand is NULL, + ** then the result is always NULL. + ** The jump is taken if the SQLITE_JUMPIFNULL bit is set. + */ + VdbeBranchTaken(2,3); + if( pOp->p5 & SQLITE_JUMPIFNULL ){ + goto jump_to_p2; + } + iCompare = 1; /* Operands are not equal */ + VVA_ONLY( iCompareIsInit = 1; ) + break; + } + }else{ + /* Neither operand is NULL and we couldn't do the special high-speed + ** integer comparison case. So do a general-case comparison. */ + affinity = pOp->p5 & SQLITE_AFF_MASK; + if( affinity>=SQLITE_AFF_NUMERIC ){ + if( (flags1 | flags3)&MEM_Str ){ + if( (flags1 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){ + applyNumericAffinity(pIn1,0); + assert( flags3==pIn3->flags || CORRUPT_DB ); + flags3 = pIn3->flags; + } + if( (flags3 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){ + applyNumericAffinity(pIn3,0); + } + } + }else if( affinity==SQLITE_AFF_TEXT && ((flags1 | flags3) & MEM_Str)!=0 ){ + if( (flags1 & MEM_Str)!=0 ){ + pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal); + }else if( (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ + testcase( pIn1->flags & MEM_Int ); + testcase( pIn1->flags & MEM_Real ); + testcase( pIn1->flags & MEM_IntReal ); + sqlite3VdbeMemStringify(pIn1, encoding, 1); + testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) ); + flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask); + if( NEVER(pIn1==pIn3) ) flags3 = flags1 | MEM_Str; + } + if( (flags3 & MEM_Str)!=0 ){ + pIn3->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal); + }else if( (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ + testcase( pIn3->flags & MEM_Int ); + testcase( pIn3->flags & MEM_Real ); + testcase( pIn3->flags & MEM_IntReal ); + sqlite3VdbeMemStringify(pIn3, encoding, 1); + testcase( (flags3&MEM_Dyn) != (pIn3->flags&MEM_Dyn) ); + flags3 = (pIn3->flags & ~MEM_TypeMask) | (flags3 & MEM_TypeMask); + } + } + assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 ); + res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl); + } + + /* At this point, res is negative, zero, or positive if reg[P1] is + ** less than, equal to, or greater than reg[P3], respectively. Compute + ** the answer to this operator in res2, depending on what the comparison + ** operator actually is. The next block of code depends on the fact + ** that the 6 comparison operators are consecutive integers in this + ** order: NE, EQ, GT, LE, LT, GE */ + assert( OP_Eq==OP_Ne+1 ); assert( OP_Gt==OP_Ne+2 ); assert( OP_Le==OP_Ne+3 ); + assert( OP_Lt==OP_Ne+4 ); assert( OP_Ge==OP_Ne+5 ); + if( res<0 ){ + res2 = sqlite3aLTb[pOp->opcode]; + }else if( res==0 ){ + res2 = sqlite3aEQb[pOp->opcode]; + }else{ + res2 = sqlite3aGTb[pOp->opcode]; + } + iCompare = res; + VVA_ONLY( iCompareIsInit = 1; ) + + /* Undo any changes made by applyAffinity() to the input registers. */ + assert( (pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn) ); + pIn3->flags = flags3; + assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) ); + pIn1->flags = flags1; + + VdbeBranchTaken(res2!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3); + if( res2 ){ + goto jump_to_p2; + } + break; +} + +/* Opcode: ElseEq * P2 * * * +** +** This opcode must follow an OP_Lt or OP_Gt comparison operator. There +** can be zero or more OP_ReleaseReg opcodes intervening, but no other +** opcodes are allowed to occur between this instruction and the previous +** OP_Lt or OP_Gt. +** +** If the result of an OP_Eq comparison on the same two operands as +** the prior OP_Lt or OP_Gt would have been true, then jump to P2. If +** the result of an OP_Eq comparison on the two previous operands +** would have been false or NULL, then fall through. +*/ +case OP_ElseEq: { /* same as TK_ESCAPE, jump */ + +#ifdef SQLITE_DEBUG + /* Verify the preconditions of this opcode - that it follows an OP_Lt or + ** OP_Gt with zero or more intervening OP_ReleaseReg opcodes */ + int iAddr; + for(iAddr = (int)(pOp - aOp) - 1; ALWAYS(iAddr>=0); iAddr--){ + if( aOp[iAddr].opcode==OP_ReleaseReg ) continue; + assert( aOp[iAddr].opcode==OP_Lt || aOp[iAddr].opcode==OP_Gt ); + break; + } +#endif /* SQLITE_DEBUG */ + assert( iCompareIsInit ); + VdbeBranchTaken(iCompare==0, 2); + if( iCompare==0 ) goto jump_to_p2; + break; +} + + +/* Opcode: Permutation * * * P4 * +** +** Set the permutation used by the OP_Compare operator in the next +** instruction. The permutation is stored in the P4 operand. +** +** The permutation is only valid for the next opcode which must be +** an OP_Compare that has the OPFLAG_PERMUTE bit set in P5. +** +** The first integer in the P4 integer array is the length of the array +** and does not become part of the permutation. +*/ +case OP_Permutation: { + assert( pOp->p4type==P4_INTARRAY ); + assert( pOp->p4.ai ); + assert( pOp[1].opcode==OP_Compare ); + assert( pOp[1].p5 & OPFLAG_PERMUTE ); + break; +} + +/* Opcode: Compare P1 P2 P3 P4 P5 +** Synopsis: r[P1@P3] <-> r[P2@P3] +** +** Compare two vectors of registers in reg(P1)..reg(P1+P3-1) (call this +** vector "A") and in reg(P2)..reg(P2+P3-1) ("B"). Save the result of +** the comparison for use by the next OP_Jump instruct. +** +** If P5 has the OPFLAG_PERMUTE bit set, then the order of comparison is +** determined by the most recent OP_Permutation operator. If the +** OPFLAG_PERMUTE bit is clear, then register are compared in sequential +** order. +** +** P4 is a KeyInfo structure that defines collating sequences and sort +** orders for the comparison. The permutation applies to registers +** only. The KeyInfo elements are used sequentially. +** +** The comparison is a sort comparison, so NULLs compare equal, +** NULLs are less than numbers, numbers are less than strings, +** and strings are less than blobs. +** +** This opcode must be immediately followed by an OP_Jump opcode. +*/ +case OP_Compare: { + int n; + int i; + int p1; + int p2; + const KeyInfo *pKeyInfo; + u32 idx; + CollSeq *pColl; /* Collating sequence to use on this term */ + int bRev; /* True for DESCENDING sort order */ + u32 *aPermute; /* The permutation */ + + if( (pOp->p5 & OPFLAG_PERMUTE)==0 ){ + aPermute = 0; + }else{ + assert( pOp>aOp ); + assert( pOp[-1].opcode==OP_Permutation ); + assert( pOp[-1].p4type==P4_INTARRAY ); + aPermute = pOp[-1].p4.ai + 1; + assert( aPermute!=0 ); + } + n = pOp->p3; + pKeyInfo = pOp->p4.pKeyInfo; + assert( n>0 ); + assert( pKeyInfo!=0 ); + assert( pKeyInfo->aSortFlags!=0 ); + p1 = pOp->p1; + p2 = pOp->p2; +#ifdef SQLITE_DEBUG + if( aPermute ){ + int k, mx = 0; + for(k=0; k(u32)mx ) mx = aPermute[k]; + assert( p1>0 && p1+mx<=(p->nMem+1 - p->nCursor)+1 ); + assert( p2>0 && p2+mx<=(p->nMem+1 - p->nCursor)+1 ); + }else{ + assert( p1>0 && p1+n<=(p->nMem+1 - p->nCursor)+1 ); + assert( p2>0 && p2+n<=(p->nMem+1 - p->nCursor)+1 ); + } +#endif /* SQLITE_DEBUG */ + for(i=0; inKeyField ); + pColl = pKeyInfo->aColl[i]; + bRev = (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_DESC); + iCompare = sqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl); + VVA_ONLY( iCompareIsInit = 1; ) + if( iCompare ){ + if( (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) + && ((aMem[p1+idx].flags & MEM_Null) || (aMem[p2+idx].flags & MEM_Null)) + ){ + iCompare = -iCompare; + } + if( bRev ) iCompare = -iCompare; + break; + } + } + assert( pOp[1].opcode==OP_Jump ); + break; +} + +/* Opcode: Jump P1 P2 P3 * * +** +** Jump to the instruction at address P1, P2, or P3 depending on whether +** in the most recent OP_Compare instruction the P1 vector was less than, +** equal to, or greater than the P2 vector, respectively. +** +** This opcode must immediately follow an OP_Compare opcode. +*/ +case OP_Jump: { /* jump */ + assert( pOp>aOp && pOp[-1].opcode==OP_Compare ); + assert( iCompareIsInit ); + if( iCompare<0 ){ + VdbeBranchTaken(0,4); pOp = &aOp[pOp->p1 - 1]; + }else if( iCompare==0 ){ + VdbeBranchTaken(1,4); pOp = &aOp[pOp->p2 - 1]; + }else{ + VdbeBranchTaken(2,4); pOp = &aOp[pOp->p3 - 1]; + } + break; +} + +/* Opcode: And P1 P2 P3 * * +** Synopsis: r[P3]=(r[P1] && r[P2]) +** +** Take the logical AND of the values in registers P1 and P2 and +** write the result into register P3. +** +** If either P1 or P2 is 0 (false) then the result is 0 even if +** the other input is NULL. A NULL and true or two NULLs give +** a NULL output. +*/ +/* Opcode: Or P1 P2 P3 * * +** Synopsis: r[P3]=(r[P1] || r[P2]) +** +** Take the logical OR of the values in register P1 and P2 and +** store the answer in register P3. +** +** If either P1 or P2 is nonzero (true) then the result is 1 (true) +** even if the other input is NULL. A NULL and false or two NULLs +** give a NULL output. +*/ +case OP_And: /* same as TK_AND, in1, in2, out3 */ +case OP_Or: { /* same as TK_OR, in1, in2, out3 */ + int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ + int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ + + v1 = sqlite3VdbeBooleanValue(&aMem[pOp->p1], 2); + v2 = sqlite3VdbeBooleanValue(&aMem[pOp->p2], 2); + if( pOp->opcode==OP_And ){ + static const unsigned char and_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 }; + v1 = and_logic[v1*3+v2]; + }else{ + static const unsigned char or_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 }; + v1 = or_logic[v1*3+v2]; + } + pOut = &aMem[pOp->p3]; + if( v1==2 ){ + MemSetTypeFlag(pOut, MEM_Null); + }else{ + pOut->u.i = v1; + MemSetTypeFlag(pOut, MEM_Int); + } + break; +} + +/* Opcode: IsTrue P1 P2 P3 P4 * +** Synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 +** +** This opcode implements the IS TRUE, IS FALSE, IS NOT TRUE, and +** IS NOT FALSE operators. +** +** Interpret the value in register P1 as a boolean value. Store that +** boolean (a 0 or 1) in register P2. Or if the value in register P1 is +** NULL, then the P3 is stored in register P2. Invert the answer if P4 +** is 1. +** +** The logic is summarized like this: +** +**
      +**
    • If P3==0 and P4==0 then r[P2] := r[P1] IS TRUE +**
    • If P3==1 and P4==1 then r[P2] := r[P1] IS FALSE +**
    • If P3==0 and P4==1 then r[P2] := r[P1] IS NOT TRUE +**
    • If P3==1 and P4==0 then r[P2] := r[P1] IS NOT FALSE +**
    +*/ +case OP_IsTrue: { /* in1, out2 */ + assert( pOp->p4type==P4_INT32 ); + assert( pOp->p4.i==0 || pOp->p4.i==1 ); + assert( pOp->p3==0 || pOp->p3==1 ); + sqlite3VdbeMemSetInt64(&aMem[pOp->p2], + sqlite3VdbeBooleanValue(&aMem[pOp->p1], pOp->p3) ^ pOp->p4.i); + break; +} + +/* Opcode: Not P1 P2 * * * +** Synopsis: r[P2]= !r[P1] +** +** Interpret the value in register P1 as a boolean value. Store the +** boolean complement in register P2. If the value in register P1 is +** NULL, then a NULL is stored in P2. +*/ +case OP_Not: { /* same as TK_NOT, in1, out2 */ + pIn1 = &aMem[pOp->p1]; + pOut = &aMem[pOp->p2]; + if( (pIn1->flags & MEM_Null)==0 ){ + sqlite3VdbeMemSetInt64(pOut, !sqlite3VdbeBooleanValue(pIn1,0)); + }else{ + sqlite3VdbeMemSetNull(pOut); + } + break; +} + +/* Opcode: BitNot P1 P2 * * * +** Synopsis: r[P2]= ~r[P1] +** +** Interpret the content of register P1 as an integer. Store the +** ones-complement of the P1 value into register P2. If P1 holds +** a NULL then store a NULL in P2. +*/ +case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */ + pIn1 = &aMem[pOp->p1]; + pOut = &aMem[pOp->p2]; + sqlite3VdbeMemSetNull(pOut); + if( (pIn1->flags & MEM_Null)==0 ){ + pOut->flags = MEM_Int; + pOut->u.i = ~sqlite3VdbeIntValue(pIn1); + } + break; +} + +/* Opcode: Once P1 P2 P3 * * +** +** Fall through to the next instruction the first time this opcode is +** encountered on each invocation of the byte-code program. Jump to P2 +** on the second and all subsequent encounters during the same invocation. +** +** Top-level programs determine first invocation by comparing the P1 +** operand against the P1 operand on the OP_Init opcode at the beginning +** of the program. If the P1 values differ, then fall through and make +** the P1 of this opcode equal to the P1 of OP_Init. If P1 values are +** the same then take the jump. +** +** For subprograms, there is a bitmask in the VdbeFrame that determines +** whether or not the jump should be taken. The bitmask is necessary +** because the self-altering code trick does not work for recursive +** triggers. +** +** The P3 operand is not used directly by this opcode. However P3 is +** used by the code generator as follows: If this opcode is the start +** of a subroutine and that subroutine uses a Bloom filter, then P3 will +** be the register that holds that Bloom filter. See tag-202407032019 +** in the source code for implementation details. +*/ +case OP_Once: { /* jump */ + u32 iAddr; /* Address of this instruction */ + assert( p->aOp[0].opcode==OP_Init ); + if( p->pFrame ){ + iAddr = (int)(pOp - p->aOp); + if( (p->pFrame->aOnce[iAddr/8] & (1<<(iAddr & 7)))!=0 ){ + VdbeBranchTaken(1, 2); + goto jump_to_p2; + } + p->pFrame->aOnce[iAddr/8] |= 1<<(iAddr & 7); + }else{ + if( p->aOp[0].p1==pOp->p1 ){ + VdbeBranchTaken(1, 2); + goto jump_to_p2; + } + } + VdbeBranchTaken(0, 2); + pOp->p1 = p->aOp[0].p1; + break; +} + +/* Opcode: If P1 P2 P3 * * +** +** Jump to P2 if the value in register P1 is true. The value +** is considered true if it is numeric and non-zero. If the value +** in P1 is NULL then take the jump if and only if P3 is non-zero. +*/ +case OP_If: { /* jump, in1 */ + int c; + c = sqlite3VdbeBooleanValue(&aMem[pOp->p1], pOp->p3); + VdbeBranchTaken(c!=0, 2); + if( c ) goto jump_to_p2; + break; +} + +/* Opcode: IfNot P1 P2 P3 * * +** +** Jump to P2 if the value in register P1 is False. The value +** is considered false if it has a numeric value of zero. If the value +** in P1 is NULL then take the jump if and only if P3 is non-zero. +*/ +case OP_IfNot: { /* jump, in1 */ + int c; + c = !sqlite3VdbeBooleanValue(&aMem[pOp->p1], !pOp->p3); + VdbeBranchTaken(c!=0, 2); + if( c ) goto jump_to_p2; + break; +} + +/* Opcode: IsNull P1 P2 * * * +** Synopsis: if r[P1]==NULL goto P2 +** +** Jump to P2 if the value in register P1 is NULL. +*/ +case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */ + pIn1 = &aMem[pOp->p1]; + VdbeBranchTaken( (pIn1->flags & MEM_Null)!=0, 2); + if( (pIn1->flags & MEM_Null)!=0 ){ + goto jump_to_p2; + } + break; +} + +/* Opcode: IsType P1 P2 P3 P4 P5 +** Synopsis: if typeof(P1.P3) in P5 goto P2 +** +** Jump to P2 if the type of a column in a btree is one of the types specified +** by the P5 bitmask. +** +** P1 is normally a cursor on a btree for which the row decode cache is +** valid through at least column P3. In other words, there should have been +** a prior OP_Column for column P3 or greater. If the cursor is not valid, +** then this opcode might give spurious results. +** The the btree row has fewer than P3 columns, then use P4 as the +** datatype. +** +** If P1 is -1, then P3 is a register number and the datatype is taken +** from the value in that register. +** +** P5 is a bitmask of data types. SQLITE_INTEGER is the least significant +** (0x01) bit. SQLITE_FLOAT is the 0x02 bit. SQLITE_TEXT is 0x04. +** SQLITE_BLOB is 0x08. SQLITE_NULL is 0x10. +** +** WARNING: This opcode does not reliably distinguish between NULL and REAL +** when P1>=0. If the database contains a NaN value, this opcode will think +** that the datatype is REAL when it should be NULL. When P1<0 and the value +** is already stored in register P3, then this opcode does reliably +** distinguish between NULL and REAL. The problem only arises then P1>=0. +** +** Take the jump to address P2 if and only if the datatype of the +** value determined by P1 and P3 corresponds to one of the bits in the +** P5 bitmask. +** +*/ +case OP_IsType: { /* jump */ + VdbeCursor *pC; + u16 typeMask; + u32 serialType; + + assert( pOp->p1>=(-1) && pOp->p1nCursor ); + assert( pOp->p1>=0 || (pOp->p3>=0 && pOp->p3<=(p->nMem+1 - p->nCursor)) ); + if( pOp->p1>=0 ){ + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pOp->p3>=0 ); + if( pOp->p3nHdrParsed ){ + serialType = pC->aType[pOp->p3]; + if( serialType>=12 ){ + if( serialType&1 ){ + typeMask = 0x04; /* SQLITE_TEXT */ + }else{ + typeMask = 0x08; /* SQLITE_BLOB */ + } + }else{ + static const unsigned char aMask[] = { + 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x2, + 0x01, 0x01, 0x10, 0x10 + }; + testcase( serialType==0 ); + testcase( serialType==1 ); + testcase( serialType==2 ); + testcase( serialType==3 ); + testcase( serialType==4 ); + testcase( serialType==5 ); + testcase( serialType==6 ); + testcase( serialType==7 ); + testcase( serialType==8 ); + testcase( serialType==9 ); + testcase( serialType==10 ); + testcase( serialType==11 ); + typeMask = aMask[serialType]; + } + }else{ + typeMask = 1 << (pOp->p4.i - 1); + testcase( typeMask==0x01 ); + testcase( typeMask==0x02 ); + testcase( typeMask==0x04 ); + testcase( typeMask==0x08 ); + testcase( typeMask==0x10 ); + } + }else{ + assert( memIsValid(&aMem[pOp->p3]) ); + typeMask = 1 << (sqlite3_value_type((sqlite3_value*)&aMem[pOp->p3])-1); + testcase( typeMask==0x01 ); + testcase( typeMask==0x02 ); + testcase( typeMask==0x04 ); + testcase( typeMask==0x08 ); + testcase( typeMask==0x10 ); + } + VdbeBranchTaken( (typeMask & pOp->p5)!=0, 2); + if( typeMask & pOp->p5 ){ + goto jump_to_p2; + } + break; +} + +/* Opcode: ZeroOrNull P1 P2 P3 * * +** Synopsis: r[P2] = 0 OR NULL +** +** If both registers P1 and P3 are NOT NULL, then store a zero in +** register P2. If either registers P1 or P3 are NULL then put +** a NULL in register P2. +*/ +case OP_ZeroOrNull: { /* in1, in2, out2, in3 */ + if( (aMem[pOp->p1].flags & MEM_Null)!=0 + || (aMem[pOp->p3].flags & MEM_Null)!=0 + ){ + sqlite3VdbeMemSetNull(aMem + pOp->p2); + }else{ + sqlite3VdbeMemSetInt64(aMem + pOp->p2, 0); + } + break; +} + +/* Opcode: NotNull P1 P2 * * * +** Synopsis: if r[P1]!=NULL goto P2 +** +** Jump to P2 if the value in register P1 is not NULL. +*/ +case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */ + pIn1 = &aMem[pOp->p1]; + VdbeBranchTaken( (pIn1->flags & MEM_Null)==0, 2); + if( (pIn1->flags & MEM_Null)==0 ){ + goto jump_to_p2; + } + break; +} + +/* Opcode: IfNullRow P1 P2 P3 * * +** Synopsis: if P1.nullRow then r[P3]=NULL, goto P2 +** +** Check the cursor P1 to see if it is currently pointing at a NULL row. +** If it is, then set register P3 to NULL and jump immediately to P2. +** If P1 is not on a NULL row, then fall through without making any +** changes. +** +** If P1 is not an open cursor, then this opcode is a no-op. +*/ +case OP_IfNullRow: { /* jump */ + VdbeCursor *pC; + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + if( pC && pC->nullRow ){ + sqlite3VdbeMemSetNull(aMem + pOp->p3); + goto jump_to_p2; + } + break; +} + +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC +/* Opcode: Offset P1 P2 P3 * * +** Synopsis: r[P3] = sqlite_offset(P1) +** +** Store in register r[P3] the byte offset into the database file that is the +** start of the payload for the record at which that cursor P1 is currently +** pointing. +** +** P2 is the column number for the argument to the sqlite_offset() function. +** This opcode does not use P2 itself, but the P2 value is used by the +** code generator. The P1, P2, and P3 operands to this opcode are the +** same as for OP_Column. +** +** This opcode is only available if SQLite is compiled with the +** -DSQLITE_ENABLE_OFFSET_SQL_FUNC option. +*/ +case OP_Offset: { /* out3 */ + VdbeCursor *pC; /* The VDBE cursor */ + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + pOut = &p->aMem[pOp->p3]; + if( pC==0 || pC->eCurType!=CURTYPE_BTREE ){ + sqlite3VdbeMemSetNull(pOut); + }else{ + if( pC->deferredMoveto ){ + rc = sqlite3VdbeFinishMoveto(pC); + if( rc ) goto abort_due_to_error; + } + if( sqlite3BtreeEof(pC->uc.pCursor) ){ + sqlite3VdbeMemSetNull(pOut); + }else{ + sqlite3VdbeMemSetInt64(pOut, sqlite3BtreeOffset(pC->uc.pCursor)); + } + } + break; +} +#endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */ + +/* Opcode: Column P1 P2 P3 P4 P5 +** Synopsis: r[P3]=PX cursor P1 column P2 +** +** Interpret the data that cursor P1 points to as a structure built using +** the MakeRecord instruction. (See the MakeRecord opcode for additional +** information about the format of the data.) Extract the P2-th column +** from this record. If there are less than (P2+1) +** values in the record, extract a NULL. +** +** The value extracted is stored in register P3. +** +** If the record contains fewer than P2 fields, then extract a NULL. Or, +** if the P4 argument is a P4_MEM use the value of the P4 argument as +** the result. +** +** If the OPFLAG_LENGTHARG bit is set in P5 then the result is guaranteed +** to only be used by the length() function or the equivalent. The content +** of large blobs is not loaded, thus saving CPU cycles. If the +** OPFLAG_TYPEOFARG bit is set then the result will only be used by the +** typeof() function or the IS NULL or IS NOT NULL operators or the +** equivalent. In this case, all content loading can be omitted. +*/ +case OP_Column: { /* ncycle */ + u32 p2; /* column number to retrieve */ + VdbeCursor *pC; /* The VDBE cursor */ + BtCursor *pCrsr; /* The B-Tree cursor corresponding to pC */ + u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */ + int len; /* The length of the serialized data for the column */ + int i; /* Loop counter */ + Mem *pDest; /* Where to write the extracted value */ + Mem sMem; /* For storing the record being decoded */ + const u8 *zData; /* Part of the record being decoded */ + const u8 *zHdr; /* Next unparsed byte of the header */ + const u8 *zEndHdr; /* Pointer to first byte after the header */ + u64 offset64; /* 64-bit offset */ + u32 t; /* A type code from the record header */ + Mem *pReg; /* PseudoTable input register */ + + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); + pC = p->apCsr[pOp->p1]; + p2 = (u32)pOp->p2; + +op_column_restart: + assert( pC!=0 ); + assert( p2<(u32)pC->nField + || (pC->eCurType==CURTYPE_PSEUDO && pC->seekResult==0) ); + aOffset = pC->aOffset; + assert( aOffset==pC->aType+pC->nField ); + assert( pC->eCurType!=CURTYPE_VTAB ); + assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow ); + assert( pC->eCurType!=CURTYPE_SORTER ); + + if( pC->cacheStatus!=p->cacheCtr ){ /*OPTIMIZATION-IF-FALSE*/ + if( pC->nullRow ){ + if( pC->eCurType==CURTYPE_PSEUDO && pC->seekResult>0 ){ + /* For the special case of as pseudo-cursor, the seekResult field + ** identifies the register that holds the record */ + pReg = &aMem[pC->seekResult]; + assert( pReg->flags & MEM_Blob ); + assert( memIsValid(pReg) ); + pC->payloadSize = pC->szRow = pReg->n; + pC->aRow = (u8*)pReg->z; + }else{ + pDest = &aMem[pOp->p3]; + memAboutToChange(p, pDest); + sqlite3VdbeMemSetNull(pDest); + goto op_column_out; + } + }else{ + pCrsr = pC->uc.pCursor; + if( pC->deferredMoveto ){ + u32 iMap; + assert( !pC->isEphemeral ); + if( pC->ub.aAltMap && (iMap = pC->ub.aAltMap[1+p2])>0 ){ + pC = pC->pAltCursor; + p2 = iMap - 1; + goto op_column_restart; + } + rc = sqlite3VdbeFinishMoveto(pC); + if( rc ) goto abort_due_to_error; + }else if( sqlite3BtreeCursorHasMoved(pCrsr) ){ + rc = sqlite3VdbeHandleMovedCursor(pC); + if( rc ) goto abort_due_to_error; + goto op_column_restart; + } + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pCrsr ); + assert( sqlite3BtreeCursorIsValid(pCrsr) ); + pC->payloadSize = sqlite3BtreePayloadSize(pCrsr); + pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &pC->szRow); + assert( pC->szRow<=pC->payloadSize ); + assert( pC->szRow<=65536 ); /* Maximum page size is 64KiB */ + } + pC->cacheStatus = p->cacheCtr; + if( (aOffset[0] = pC->aRow[0])<0x80 ){ + pC->iHdrOffset = 1; + }else{ + pC->iHdrOffset = sqlite3GetVarint32(pC->aRow, aOffset); + } + pC->nHdrParsed = 0; + + if( pC->szRowaRow does not have to hold the entire row, but it does at least + ** need to cover the header of the record. If pC->aRow does not contain + ** the complete header, then set it to zero, forcing the header to be + ** dynamically allocated. */ + pC->aRow = 0; + pC->szRow = 0; + + /* Make sure a corrupt database has not given us an oversize header. + ** Do this now to avoid an oversize memory allocation. + ** + ** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte + ** types use so much data space that there can only be 4096 and 32 of + ** them, respectively. So the maximum header length results from a + ** 3-byte type for each of the maximum of 32768 columns plus three + ** extra bytes for the header length itself. 32768*3 + 3 = 98307. + */ + if( aOffset[0] > 98307 || aOffset[0] > pC->payloadSize ){ + goto op_column_corrupt; + } + }else{ + /* This is an optimization. By skipping over the first few tests + ** (ex: pC->nHdrParsed<=p2) in the next section, we achieve a + ** measurable performance gain. + ** + ** This branch is taken even if aOffset[0]==0. Such a record is never + ** generated by SQLite, and could be considered corruption, but we + ** accept it for historical reasons. When aOffset[0]==0, the code this + ** branch jumps to reads past the end of the record, but never more + ** than a few bytes. Even if the record occurs at the end of the page + ** content area, the "page header" comes after the page content and so + ** this overread is harmless. Similar overreads can occur for a corrupt + ** database file. + */ + zData = pC->aRow; + assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */ + testcase( aOffset[0]==0 ); + goto op_column_read_header; + } + }else if( sqlite3BtreeCursorHasMoved(pC->uc.pCursor) ){ + rc = sqlite3VdbeHandleMovedCursor(pC); + if( rc ) goto abort_due_to_error; + goto op_column_restart; + } + + /* Make sure at least the first p2+1 entries of the header have been + ** parsed and valid information is in aOffset[] and pC->aType[]. + */ + if( pC->nHdrParsed<=p2 ){ + /* If there is more header available for parsing in the record, try + ** to extract additional fields up through the p2+1-th field + */ + if( pC->iHdrOffsetaRow==0 ){ + memset(&sMem, 0, sizeof(sMem)); + rc = sqlite3VdbeMemFromBtreeZeroOffset(pC->uc.pCursor,aOffset[0],&sMem); + if( rc!=SQLITE_OK ) goto abort_due_to_error; + zData = (u8*)sMem.z; + }else{ + zData = pC->aRow; + } + + /* Fill in pC->aType[i] and aOffset[i] values through the p2-th field. */ + op_column_read_header: + i = pC->nHdrParsed; + offset64 = aOffset[i]; + zHdr = zData + pC->iHdrOffset; + zEndHdr = zData + aOffset[0]; + testcase( zHdr>=zEndHdr ); + do{ + if( (pC->aType[i] = t = zHdr[0])<0x80 ){ + zHdr++; + offset64 += sqlite3VdbeOneByteSerialTypeLen(t); + }else{ + zHdr += sqlite3GetVarint32(zHdr, &t); + pC->aType[i] = t; + offset64 += sqlite3VdbeSerialTypeLen(t); + } + aOffset[++i] = (u32)(offset64 & 0xffffffff); + }while( (u32)i<=p2 && zHdr=zEndHdr && (zHdr>zEndHdr || offset64!=pC->payloadSize)) + || (offset64 > pC->payloadSize) + ){ + if( aOffset[0]==0 ){ + i = 0; + zHdr = zEndHdr; + }else{ + if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem); + goto op_column_corrupt; + } + } + + pC->nHdrParsed = i; + pC->iHdrOffset = (u32)(zHdr - zData); + if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem); + }else{ + t = 0; + } + + /* If after trying to extract new entries from the header, nHdrParsed is + ** still not up to p2, that means that the record has fewer than p2 + ** columns. So the result will be either the default value or a NULL. + */ + if( pC->nHdrParsed<=p2 ){ + pDest = &aMem[pOp->p3]; + memAboutToChange(p, pDest); + if( pOp->p4type==P4_MEM ){ + sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static); + }else{ + sqlite3VdbeMemSetNull(pDest); + } + goto op_column_out; + } + }else{ + t = pC->aType[p2]; + } + + /* Extract the content for the p2+1-th column. Control can only + ** reach this point if aOffset[p2], aOffset[p2+1], and pC->aType[p2] are + ** all valid. + */ + assert( p2nHdrParsed ); + assert( rc==SQLITE_OK ); + pDest = &aMem[pOp->p3]; + memAboutToChange(p, pDest); + assert( sqlite3VdbeCheckMemInvariants(pDest) ); + if( VdbeMemDynamic(pDest) ){ + sqlite3VdbeMemSetNull(pDest); + } + assert( t==pC->aType[p2] ); + if( pC->szRow>=aOffset[p2+1] ){ + /* This is the common case where the desired content fits on the original + ** page - where the content is not on an overflow page */ + zData = pC->aRow + aOffset[p2]; + if( t<12 ){ + sqlite3VdbeSerialGet(zData, t, pDest); + }else{ + /* If the column value is a string, we need a persistent value, not + ** a MEM_Ephem value. This branch is a fast short-cut that is equivalent + ** to calling sqlite3VdbeSerialGet() and sqlite3VdbeDeephemeralize(). + */ + static const u16 aFlag[] = { MEM_Blob, MEM_Str|MEM_Term }; + pDest->n = len = (t-12)/2; + pDest->enc = encoding; + if( pDest->szMalloc < len+2 ){ + if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) goto too_big; + pDest->flags = MEM_Null; + if( sqlite3VdbeMemGrow(pDest, len+2, 0) ) goto no_mem; + }else{ + pDest->z = pDest->zMalloc; + } + memcpy(pDest->z, zData, len); + pDest->z[len] = 0; + pDest->z[len+1] = 0; + pDest->flags = aFlag[t&1]; + } + }else{ + u8 p5; + pDest->enc = encoding; + assert( pDest->db==db ); + /* This branch happens only when content is on overflow pages */ + if( ((p5 = (pOp->p5 & OPFLAG_BYTELENARG))!=0 + && (p5==OPFLAG_TYPEOFARG + || (t>=12 && ((t&1)==0 || p5==OPFLAG_BYTELENARG)) + ) + ) + || sqlite3VdbeSerialTypeLen(t)==0 + ){ + /* Content is irrelevant for + ** 1. the typeof() function, + ** 2. the length(X) function if X is a blob, and + ** 3. if the content length is zero. + ** So we might as well use bogus content rather than reading + ** content from disk. + ** + ** Although sqlite3VdbeSerialGet() may read at most 8 bytes from the + ** buffer passed to it, debugging function VdbeMemPrettyPrint() may + ** read more. Use the global constant sqlite3CtypeMap[] as the array, + ** as that array is 256 bytes long (plenty for VdbeMemPrettyPrint()) + ** and it begins with a bunch of zeros. + */ + sqlite3VdbeSerialGet((u8*)sqlite3CtypeMap, t, pDest); + }else{ + rc = vdbeColumnFromOverflow(pC, p2, t, aOffset[p2], + p->cacheCtr, colCacheCtr, pDest); + if( rc ){ + if( rc==SQLITE_NOMEM ) goto no_mem; + if( rc==SQLITE_TOOBIG ) goto too_big; + goto abort_due_to_error; + } + } + } + +op_column_out: + UPDATE_MAX_BLOBSIZE(pDest); + REGISTER_TRACE(pOp->p3, pDest); + break; + +op_column_corrupt: + if( aOp[0].p3>0 ){ + pOp = &aOp[aOp[0].p3-1]; + break; + }else{ + rc = SQLITE_CORRUPT_BKPT; + goto abort_due_to_error; + } +} + +/* Opcode: TypeCheck P1 P2 P3 P4 * +** Synopsis: typecheck(r[P1@P2]) +** +** Apply affinities to the range of P2 registers beginning with P1. +** Take the affinities from the Table object in P4. If any value +** cannot be coerced into the correct type, then raise an error. +** +** If P3==0, then omit checking of VIRTUAL columns. +** +** If P3==1, then omit checking of all generated column, both VIRTUAL +** and STORED. +** +** If P3>=2, then only check column number P3-2 in the table (which will +** be a VIRTUAL column) against the value in reg[P1]. In this case, +** P2 will be 1. +** +** This opcode is similar to OP_Affinity except that this opcode +** forces the register type to the Table column type. This is used +** to implement "strict affinity". +** +** GENERATED ALWAYS AS ... STATIC columns are only checked if P3 +** is zero. When P3 is non-zero, no type checking occurs for +** static generated columns. Virtual columns are computed at query time +** and so they are never checked. +** +** Preconditions: +** +**
      +**
    • P2 should be the number of non-virtual columns in the +** table of P4 unless P3>1, in which case P2 will be 1. +**
    • Table P4 is a STRICT table. +**
    +** +** If any precondition is false, an assertion fault occurs. +*/ +case OP_TypeCheck: { + Table *pTab; + Column *aCol; + int i; + int nCol; + + assert( pOp->p4type==P4_TABLE ); + pTab = pOp->p4.pTab; + assert( pTab->tabFlags & TF_Strict ); + assert( pOp->p3>=0 && pOp->p3nCol+2 ); + aCol = pTab->aCol; + pIn1 = &aMem[pOp->p1]; + if( pOp->p3<2 ){ + assert( pTab->nNVCol==pOp->p2 ); + i = 0; + nCol = pTab->nCol; + }else{ + i = pOp->p3-2; + nCol = i+1; + assert( inCol ); + assert( aCol[i].colFlags & COLFLAG_VIRTUAL ); + assert( pOp->p2==1 ); + } + for(; ip3<2 ){ + if( (aCol[i].colFlags & COLFLAG_VIRTUAL)!=0 ) continue; + if( pOp->p3 ){ pIn1++; continue; } + } + assert( pIn1 < &aMem[pOp->p1+pOp->p2] ); + applyAffinity(pIn1, aCol[i].affinity, encoding); + if( (pIn1->flags & MEM_Null)==0 ){ + switch( aCol[i].eCType ){ + case COLTYPE_BLOB: { + if( (pIn1->flags & MEM_Blob)==0 ) goto vdbe_type_error; + break; + } + case COLTYPE_INTEGER: + case COLTYPE_INT: { + if( (pIn1->flags & MEM_Int)==0 ) goto vdbe_type_error; + break; + } + case COLTYPE_TEXT: { + if( (pIn1->flags & MEM_Str)==0 ) goto vdbe_type_error; + break; + } + case COLTYPE_REAL: { + testcase( (pIn1->flags & (MEM_Real|MEM_IntReal))==MEM_Real ); + assert( (pIn1->flags & MEM_IntReal)==0 ); + if( pIn1->flags & MEM_Int ){ + /* When applying REAL affinity, if the result is still an MEM_Int + ** that will fit in 6 bytes, then change the type to MEM_IntReal + ** so that we keep the high-resolution integer value but know that + ** the type really wants to be REAL. */ + testcase( pIn1->u.i==140737488355328LL ); + testcase( pIn1->u.i==140737488355327LL ); + testcase( pIn1->u.i==-140737488355328LL ); + testcase( pIn1->u.i==-140737488355329LL ); + if( pIn1->u.i<=140737488355327LL && pIn1->u.i>=-140737488355328LL){ + pIn1->flags |= MEM_IntReal; + pIn1->flags &= ~MEM_Int; + }else{ + pIn1->u.r = (double)pIn1->u.i; + pIn1->flags |= MEM_Real; + pIn1->flags &= ~MEM_Int; + } + }else if( (pIn1->flags & (MEM_Real|MEM_IntReal))==0 ){ + goto vdbe_type_error; + } + break; + } + default: { + /* COLTYPE_ANY. Accept anything. */ + break; + } + } + } + REGISTER_TRACE((int)(pIn1-aMem), pIn1); + pIn1++; + } + assert( pIn1 == &aMem[pOp->p1+pOp->p2] ); + break; + +vdbe_type_error: + sqlite3VdbeError(p, "cannot store %s value in %s column %s.%s", + vdbeMemTypeName(pIn1), sqlite3StdType[aCol[i].eCType-1], + pTab->zName, aCol[i].zCnName); + rc = SQLITE_CONSTRAINT_DATATYPE; + goto abort_due_to_error; +} + +/* Opcode: Affinity P1 P2 * P4 * +** Synopsis: affinity(r[P1@P2]) +** +** Apply affinities to a range of P2 registers starting with P1. +** +** P4 is a string that is P2 characters long. The N-th character of the +** string indicates the column affinity that should be used for the N-th +** memory cell in the range. +*/ +case OP_Affinity: { + const char *zAffinity; /* The affinity to be applied */ + + zAffinity = pOp->p4.z; + assert( zAffinity!=0 ); + assert( pOp->p2>0 ); + assert( zAffinity[pOp->p2]==0 ); + pIn1 = &aMem[pOp->p1]; + while( 1 /*exit-by-break*/ ){ + assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] ); + assert( zAffinity[0]==SQLITE_AFF_NONE || memIsValid(pIn1) ); + applyAffinity(pIn1, zAffinity[0], encoding); + if( zAffinity[0]==SQLITE_AFF_REAL && (pIn1->flags & MEM_Int)!=0 ){ + /* When applying REAL affinity, if the result is still an MEM_Int + ** that will fit in 6 bytes, then change the type to MEM_IntReal + ** so that we keep the high-resolution integer value but know that + ** the type really wants to be REAL. */ + testcase( pIn1->u.i==140737488355328LL ); + testcase( pIn1->u.i==140737488355327LL ); + testcase( pIn1->u.i==-140737488355328LL ); + testcase( pIn1->u.i==-140737488355329LL ); + if( pIn1->u.i<=140737488355327LL && pIn1->u.i>=-140737488355328LL ){ + pIn1->flags |= MEM_IntReal; + pIn1->flags &= ~MEM_Int; + }else{ + pIn1->u.r = (double)pIn1->u.i; + pIn1->flags |= MEM_Real; + pIn1->flags &= ~(MEM_Int|MEM_Str); + } + } + REGISTER_TRACE((int)(pIn1-aMem), pIn1); + zAffinity++; + if( zAffinity[0]==0 ) break; + pIn1++; + } + break; +} + +/* Opcode: MakeRecord P1 P2 P3 P4 * +** Synopsis: r[P3]=mkrec(r[P1@P2]) +** +** Convert P2 registers beginning with P1 into the [record format] +** use as a data record in a database table or as a key +** in an index. The OP_Column opcode can decode the record later. +** +** P4 may be a string that is P2 characters long. The N-th character of the +** string indicates the column affinity that should be used for the N-th +** field of the index key. +** +** The mapping from character to affinity is given by the SQLITE_AFF_ +** macros defined in sqliteInt.h. +** +** If P4 is NULL then all index fields have the affinity BLOB. +** +** The meaning of P5 depends on whether or not the SQLITE_ENABLE_NULL_TRIM +** compile-time option is enabled: +** +** * If SQLITE_ENABLE_NULL_TRIM is enabled, then the P5 is the index +** of the right-most table that can be null-trimmed. +** +** * If SQLITE_ENABLE_NULL_TRIM is omitted, then P5 has the value +** OPFLAG_NOCHNG_MAGIC if the OP_MakeRecord opcode is allowed to +** accept no-change records with serial_type 10. This value is +** only used inside an assert() and does not affect the end result. +*/ +case OP_MakeRecord: { + Mem *pRec; /* The new record */ + u64 nData; /* Number of bytes of data space */ + int nHdr; /* Number of bytes of header space */ + i64 nByte; /* Data space required for this record */ + i64 nZero; /* Number of zero bytes at the end of the record */ + int nVarint; /* Number of bytes in a varint */ + u32 serial_type; /* Type field */ + Mem *pData0; /* First field to be combined into the record */ + Mem *pLast; /* Last field of the record */ + int nField; /* Number of fields in the record */ + char *zAffinity; /* The affinity string for the record */ + u32 len; /* Length of a field */ + u8 *zHdr; /* Where to write next byte of the header */ + u8 *zPayload; /* Where to write next byte of the payload */ + + /* Assuming the record contains N fields, the record format looks + ** like this: + ** + ** ------------------------------------------------------------------------ + ** | hdr-size | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 | + ** ------------------------------------------------------------------------ + ** + ** Data(0) is taken from register P1. Data(1) comes from register P1+1 + ** and so forth. + ** + ** Each type field is a varint representing the serial type of the + ** corresponding data element (see sqlite3VdbeSerialType()). The + ** hdr-size field is also a varint which is the offset from the beginning + ** of the record to data0. + */ + nData = 0; /* Number of bytes of data space */ + nHdr = 0; /* Number of bytes of header space */ + nZero = 0; /* Number of zero bytes at the end of the record */ + nField = pOp->p1; + zAffinity = pOp->p4.z; + assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem+1 - p->nCursor)+1 ); + pData0 = &aMem[nField]; + nField = pOp->p2; + pLast = &pData0[nField-1]; + + /* Identify the output register */ + assert( pOp->p3p1 || pOp->p3>=pOp->p1+pOp->p2 ); + pOut = &aMem[pOp->p3]; + memAboutToChange(p, pOut); + + /* Apply the requested affinity to all inputs + */ + assert( pData0<=pLast ); + if( zAffinity ){ + pRec = pData0; + do{ + applyAffinity(pRec, zAffinity[0], encoding); + if( zAffinity[0]==SQLITE_AFF_REAL && (pRec->flags & MEM_Int) ){ + pRec->flags |= MEM_IntReal; + pRec->flags &= ~(MEM_Int); + } + REGISTER_TRACE((int)(pRec-aMem), pRec); + zAffinity++; + pRec++; + assert( zAffinity[0]==0 || pRec<=pLast ); + }while( zAffinity[0] ); + } + +#ifdef SQLITE_ENABLE_NULL_TRIM + /* NULLs can be safely trimmed from the end of the record, as long as + ** as the schema format is 2 or more and none of the omitted columns + ** have a non-NULL default value. Also, the record must be left with + ** at least one field. If P5>0 then it will be one more than the + ** index of the right-most column with a non-NULL default value */ + if( pOp->p5 ){ + while( (pLast->flags & MEM_Null)!=0 && nField>pOp->p5 ){ + pLast--; + nField--; + } + } +#endif + + /* Loop through the elements that will make up the record to figure + ** out how much space is required for the new record. After this loop, + ** the Mem.uTemp field of each term should hold the serial-type that will + ** be used for that term in the generated record: + ** + ** Mem.uTemp value type + ** --------------- --------------- + ** 0 NULL + ** 1 1-byte signed integer + ** 2 2-byte signed integer + ** 3 3-byte signed integer + ** 4 4-byte signed integer + ** 5 6-byte signed integer + ** 6 8-byte signed integer + ** 7 IEEE float + ** 8 Integer constant 0 + ** 9 Integer constant 1 + ** 10,11 reserved for expansion + ** N>=12 and even BLOB + ** N>=13 and odd text + ** + ** The following additional values are computed: + ** nHdr Number of bytes needed for the record header + ** nData Number of bytes of data space needed for the record + ** nZero Zero bytes at the end of the record + */ + pRec = pLast; + do{ + assert( memIsValid(pRec) ); + if( pRec->flags & MEM_Null ){ + if( pRec->flags & MEM_Zero ){ + /* Values with MEM_Null and MEM_Zero are created by xColumn virtual + ** table methods that never invoke sqlite3_result_xxxxx() while + ** computing an unchanging column value in an UPDATE statement. + ** Give such values a special internal-use-only serial-type of 10 + ** so that they can be passed through to xUpdate and have + ** a true sqlite3_value_nochange(). */ +#ifndef SQLITE_ENABLE_NULL_TRIM + assert( pOp->p5==OPFLAG_NOCHNG_MAGIC || CORRUPT_DB ); +#endif + pRec->uTemp = 10; + }else{ + pRec->uTemp = 0; + } + nHdr++; + }else if( pRec->flags & (MEM_Int|MEM_IntReal) ){ + /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */ + i64 i = pRec->u.i; + u64 uu; + testcase( pRec->flags & MEM_Int ); + testcase( pRec->flags & MEM_IntReal ); + if( i<0 ){ + uu = ~i; + }else{ + uu = i; + } + nHdr++; + testcase( uu==127 ); testcase( uu==128 ); + testcase( uu==32767 ); testcase( uu==32768 ); + testcase( uu==8388607 ); testcase( uu==8388608 ); + testcase( uu==2147483647 ); testcase( uu==2147483648LL ); + testcase( uu==140737488355327LL ); testcase( uu==140737488355328LL ); + if( uu<=127 ){ + if( (i&1)==i && p->minWriteFileFormat>=4 ){ + pRec->uTemp = 8+(u32)uu; + }else{ + nData++; + pRec->uTemp = 1; + } + }else if( uu<=32767 ){ + nData += 2; + pRec->uTemp = 2; + }else if( uu<=8388607 ){ + nData += 3; + pRec->uTemp = 3; + }else if( uu<=2147483647 ){ + nData += 4; + pRec->uTemp = 4; + }else if( uu<=140737488355327LL ){ + nData += 6; + pRec->uTemp = 5; + }else{ + nData += 8; + if( pRec->flags & MEM_IntReal ){ + /* If the value is IntReal and is going to take up 8 bytes to store + ** as an integer, then we might as well make it an 8-byte floating + ** point value */ + pRec->u.r = (double)pRec->u.i; + pRec->flags &= ~MEM_IntReal; + pRec->flags |= MEM_Real; + pRec->uTemp = 7; + }else{ + pRec->uTemp = 6; + } + } + }else if( pRec->flags & MEM_Real ){ + nHdr++; + nData += 8; + pRec->uTemp = 7; + }else{ + assert( db->mallocFailed || pRec->flags&(MEM_Str|MEM_Blob) ); + assert( pRec->n>=0 ); + len = (u32)pRec->n; + serial_type = (len*2) + 12 + ((pRec->flags & MEM_Str)!=0); + if( pRec->flags & MEM_Zero ){ + serial_type += (u32)pRec->u.nZero*2; + if( nData ){ + if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem; + len += pRec->u.nZero; + }else{ + nZero += pRec->u.nZero; + } + } + nData += len; + nHdr += sqlite3VarintLen(serial_type); + pRec->uTemp = serial_type; + } + if( pRec==pData0 ) break; + pRec--; + }while(1); + + /* EVIDENCE-OF: R-22564-11647 The header begins with a single varint + ** which determines the total number of bytes in the header. The varint + ** value is the size of the header in bytes including the size varint + ** itself. */ + testcase( nHdr==126 ); + testcase( nHdr==127 ); + if( nHdr<=126 ){ + /* The common case */ + nHdr += 1; + }else{ + /* Rare case of a really large header */ + nVarint = sqlite3VarintLen(nHdr); + nHdr += nVarint; + if( nVarintp3) is not allowed to + ** be one of the input registers (because the following call to + ** sqlite3VdbeMemClearAndResize() could clobber the value before it is used). + */ + if( nByte+nZero<=pOut->szMalloc ){ + /* The output register is already large enough to hold the record. + ** No error checks or buffer enlargement is required */ + pOut->z = pOut->zMalloc; + }else{ + /* Need to make sure that the output is not too big and then enlarge + ** the output register to hold the full result */ + if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + goto too_big; + } + if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){ + goto no_mem; + } + } + pOut->n = (int)nByte; + pOut->flags = MEM_Blob; + if( nZero ){ + pOut->u.nZero = nZero; + pOut->flags |= MEM_Zero; + } + UPDATE_MAX_BLOBSIZE(pOut); + zHdr = (u8 *)pOut->z; + zPayload = zHdr + nHdr; + + /* Write the record */ + if( nHdr<0x80 ){ + *(zHdr++) = nHdr; + }else{ + zHdr += sqlite3PutVarint(zHdr,nHdr); + } + assert( pData0<=pLast ); + pRec = pData0; + while( 1 /*exit-by-break*/ ){ + serial_type = pRec->uTemp; + /* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more + ** additional varints, one per column. + ** EVIDENCE-OF: R-64536-51728 The values for each column in the record + ** immediately follow the header. */ + if( serial_type<=7 ){ + *(zHdr++) = serial_type; + if( serial_type==0 ){ + /* NULL value. No change in zPayload */ + }else{ + u64 v; + if( serial_type==7 ){ + assert( sizeof(v)==sizeof(pRec->u.r) ); + memcpy(&v, &pRec->u.r, sizeof(v)); + swapMixedEndianFloat(v); + }else{ + v = pRec->u.i; + } + len = sqlite3SmallTypeSizes[serial_type]; + assert( len>=1 && len<=8 && len!=5 && len!=7 ); + switch( len ){ + default: zPayload[7] = (u8)(v&0xff); v >>= 8; + zPayload[6] = (u8)(v&0xff); v >>= 8; + /* no break */ deliberate_fall_through + case 6: zPayload[5] = (u8)(v&0xff); v >>= 8; + zPayload[4] = (u8)(v&0xff); v >>= 8; + /* no break */ deliberate_fall_through + case 4: zPayload[3] = (u8)(v&0xff); v >>= 8; + /* no break */ deliberate_fall_through + case 3: zPayload[2] = (u8)(v&0xff); v >>= 8; + /* no break */ deliberate_fall_through + case 2: zPayload[1] = (u8)(v&0xff); v >>= 8; + /* no break */ deliberate_fall_through + case 1: zPayload[0] = (u8)(v&0xff); + } + zPayload += len; + } + }else if( serial_type<0x80 ){ + *(zHdr++) = serial_type; + if( serial_type>=14 && pRec->n>0 ){ + assert( pRec->z!=0 ); + memcpy(zPayload, pRec->z, pRec->n); + zPayload += pRec->n; + } + }else{ + zHdr += sqlite3PutVarint(zHdr, serial_type); + if( pRec->n ){ + assert( pRec->z!=0 ); + assert( pRec->z!=(const char*)sqlite3CtypeMap ); + memcpy(zPayload, pRec->z, pRec->n); + zPayload += pRec->n; + } + } + if( pRec==pLast ) break; + pRec++; + } + assert( nHdr==(int)(zHdr - (u8*)pOut->z) ); + assert( nByte==(int)(zPayload - (u8*)pOut->z) ); + + assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); + REGISTER_TRACE(pOp->p3, pOut); + break; +} + +/* Opcode: Count P1 P2 P3 * * +** Synopsis: r[P2]=count() +** +** Store the number of entries (an integer value) in the table or index +** opened by cursor P1 in register P2. +** +** If P3==0, then an exact count is obtained, which involves visiting +** every btree page of the table. But if P3 is non-zero, an estimate +** is returned based on the current cursor position. +*/ +case OP_Count: { /* out2 */ + i64 nEntry; + BtCursor *pCrsr; + + assert( p->apCsr[pOp->p1]->eCurType==CURTYPE_BTREE ); + pCrsr = p->apCsr[pOp->p1]->uc.pCursor; + assert( pCrsr ); + if( pOp->p3 ){ + nEntry = sqlite3BtreeRowCountEst(pCrsr); + }else{ + nEntry = 0; /* Not needed. Only used to silence a warning. */ + rc = sqlite3BtreeCount(db, pCrsr, &nEntry); + if( rc ) goto abort_due_to_error; + } + pOut = out2Prerelease(p, pOp); + pOut->u.i = nEntry; + goto check_for_interrupt; +} + +/* Opcode: Savepoint P1 * * P4 * +** +** Open, release or rollback the savepoint named by parameter P4, depending +** on the value of P1. To open a new savepoint set P1==0 (SAVEPOINT_BEGIN). +** To release (commit) an existing savepoint set P1==1 (SAVEPOINT_RELEASE). +** To rollback an existing savepoint set P1==2 (SAVEPOINT_ROLLBACK). +*/ +case OP_Savepoint: { + int p1; /* Value of P1 operand */ + char *zName; /* Name of savepoint */ + int nName; + Savepoint *pNew; + Savepoint *pSavepoint; + Savepoint *pTmp; + int iSavepoint; + int ii; + + p1 = pOp->p1; + zName = pOp->p4.z; + + /* Assert that the p1 parameter is valid. Also that if there is no open + ** transaction, then there cannot be any savepoints. + */ + assert( db->pSavepoint==0 || db->autoCommit==0 ); + assert( p1==SAVEPOINT_BEGIN||p1==SAVEPOINT_RELEASE||p1==SAVEPOINT_ROLLBACK ); + assert( db->pSavepoint || db->isTransactionSavepoint==0 ); + assert( checkSavepointCount(db) ); + assert( p->bIsReader ); + + if( p1==SAVEPOINT_BEGIN ){ + if( db->nVdbeWrite>0 ){ + /* A new savepoint cannot be created if there are active write + ** statements (i.e. open read/write incremental blob handles). + */ + sqlite3VdbeError(p, "cannot open savepoint - SQL statements in progress"); + rc = SQLITE_BUSY; + }else{ + nName = sqlite3Strlen30(zName); + +#ifndef SQLITE_OMIT_VIRTUALTABLE + /* This call is Ok even if this savepoint is actually a transaction + ** savepoint (and therefore should not prompt xSavepoint()) callbacks. + ** If this is a transaction savepoint being opened, it is guaranteed + ** that the db->aVTrans[] array is empty. */ + assert( db->autoCommit==0 || db->nVTrans==0 ); + rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, + db->nStatement+db->nSavepoint); + if( rc!=SQLITE_OK ) goto abort_due_to_error; +#endif + + /* Create a new savepoint structure. */ + pNew = sqlite3DbMallocRawNN(db, sizeof(Savepoint)+nName+1); + if( pNew ){ + pNew->zName = (char *)&pNew[1]; + memcpy(pNew->zName, zName, nName+1); + + /* If there is no open transaction, then mark this as a special + ** "transaction savepoint". */ + if( db->autoCommit ){ + db->autoCommit = 0; + db->isTransactionSavepoint = 1; + }else{ + db->nSavepoint++; + } + + /* Link the new savepoint into the database handle's list. */ + pNew->pNext = db->pSavepoint; + db->pSavepoint = pNew; + pNew->nDeferredCons = db->nDeferredCons; + pNew->nDeferredImmCons = db->nDeferredImmCons; + } + } + }else{ + assert( p1==SAVEPOINT_RELEASE || p1==SAVEPOINT_ROLLBACK ); + iSavepoint = 0; + + /* Find the named savepoint. If there is no such savepoint, then an + ** an error is returned to the user. */ + for( + pSavepoint = db->pSavepoint; + pSavepoint && sqlite3StrICmp(pSavepoint->zName, zName); + pSavepoint = pSavepoint->pNext + ){ + iSavepoint++; + } + if( !pSavepoint ){ + sqlite3VdbeError(p, "no such savepoint: %s", zName); + rc = SQLITE_ERROR; + }else if( db->nVdbeWrite>0 && p1==SAVEPOINT_RELEASE ){ + /* It is not possible to release (commit) a savepoint if there are + ** active write statements. + */ + sqlite3VdbeError(p, "cannot release savepoint - " + "SQL statements in progress"); + rc = SQLITE_BUSY; + }else{ + + /* Determine whether or not this is a transaction savepoint. If so, + ** and this is a RELEASE command, then the current transaction + ** is committed. + */ + int isTransaction = pSavepoint->pNext==0 && db->isTransactionSavepoint; + if( isTransaction && p1==SAVEPOINT_RELEASE ){ + if( (rc = sqlite3VdbeCheckFkDeferred(p))!=SQLITE_OK ){ + goto vdbe_return; + } + db->autoCommit = 1; + if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ + p->pc = (int)(pOp - aOp); + db->autoCommit = 0; + p->rc = rc = SQLITE_BUSY; + goto vdbe_return; + } + rc = p->rc; + if( rc ){ + db->autoCommit = 0; + }else{ + db->isTransactionSavepoint = 0; + } + }else{ + int isSchemaChange; + iSavepoint = db->nSavepoint - iSavepoint - 1; + if( p1==SAVEPOINT_ROLLBACK ){ + isSchemaChange = (db->mDbFlags & DBFLAG_SchemaChange)!=0; + for(ii=0; iinDb; ii++){ + rc = sqlite3BtreeTripAllCursors(db->aDb[ii].pBt, + SQLITE_ABORT_ROLLBACK, + isSchemaChange==0); + if( rc!=SQLITE_OK ) goto abort_due_to_error; + } + }else{ + assert( p1==SAVEPOINT_RELEASE ); + isSchemaChange = 0; + } + for(ii=0; iinDb; ii++){ + rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint); + if( rc!=SQLITE_OK ){ + goto abort_due_to_error; + } + } + if( isSchemaChange ){ + sqlite3ExpirePreparedStatements(db, 0); + sqlite3ResetAllSchemasOfConnection(db); + db->mDbFlags |= DBFLAG_SchemaChange; + } + } + if( rc ) goto abort_due_to_error; + + /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all + ** savepoints nested inside of the savepoint being operated on. */ + while( db->pSavepoint!=pSavepoint ){ + pTmp = db->pSavepoint; + db->pSavepoint = pTmp->pNext; + sqlite3DbFree(db, pTmp); + db->nSavepoint--; + } + + /* If it is a RELEASE, then destroy the savepoint being operated on + ** too. If it is a ROLLBACK TO, then set the number of deferred + ** constraint violations present in the database to the value stored + ** when the savepoint was created. */ + if( p1==SAVEPOINT_RELEASE ){ + assert( pSavepoint==db->pSavepoint ); + db->pSavepoint = pSavepoint->pNext; + sqlite3DbFree(db, pSavepoint); + if( !isTransaction ){ + db->nSavepoint--; + } + }else{ + assert( p1==SAVEPOINT_ROLLBACK ); + db->nDeferredCons = pSavepoint->nDeferredCons; + db->nDeferredImmCons = pSavepoint->nDeferredImmCons; + } + + if( !isTransaction || p1==SAVEPOINT_ROLLBACK ){ + rc = sqlite3VtabSavepoint(db, p1, iSavepoint); + if( rc!=SQLITE_OK ) goto abort_due_to_error; + } + } + } + if( rc ) goto abort_due_to_error; + if( p->eVdbeState==VDBE_HALT_STATE ){ + rc = SQLITE_DONE; + goto vdbe_return; + } + break; +} + +/* Opcode: AutoCommit P1 P2 * * * +** +** Set the database auto-commit flag to P1 (1 or 0). If P2 is true, roll +** back any currently active btree transactions. If there are any active +** VMs (apart from this one), then a ROLLBACK fails. A COMMIT fails if +** there are active writing VMs or active VMs that use shared cache. +** +** This instruction causes the VM to halt. +*/ +case OP_AutoCommit: { + int desiredAutoCommit; + int iRollback; + + desiredAutoCommit = pOp->p1; + iRollback = pOp->p2; + assert( desiredAutoCommit==1 || desiredAutoCommit==0 ); + assert( desiredAutoCommit==1 || iRollback==0 ); + assert( db->nVdbeActive>0 ); /* At least this one VM is active */ + assert( p->bIsReader ); + + if( desiredAutoCommit!=db->autoCommit ){ + if( iRollback ){ + assert( desiredAutoCommit==1 ); + sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); + db->autoCommit = 1; + }else if( desiredAutoCommit && db->nVdbeWrite>0 ){ + /* If this instruction implements a COMMIT and other VMs are writing + ** return an error indicating that the other VMs must complete first. + */ + sqlite3VdbeError(p, "cannot commit transaction - " + "SQL statements in progress"); + rc = SQLITE_BUSY; + goto abort_due_to_error; + }else if( (rc = sqlite3VdbeCheckFkDeferred(p))!=SQLITE_OK ){ + goto vdbe_return; + }else{ + db->autoCommit = (u8)desiredAutoCommit; + } + if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ + p->pc = (int)(pOp - aOp); + db->autoCommit = (u8)(1-desiredAutoCommit); + p->rc = rc = SQLITE_BUSY; + goto vdbe_return; + } + sqlite3CloseSavepoints(db); + if( p->rc==SQLITE_OK ){ + rc = SQLITE_DONE; + }else{ + rc = SQLITE_ERROR; + } + goto vdbe_return; + }else{ + sqlite3VdbeError(p, + (!desiredAutoCommit)?"cannot start a transaction within a transaction":( + (iRollback)?"cannot rollback - no transaction is active": + "cannot commit - no transaction is active")); + + rc = SQLITE_ERROR; + goto abort_due_to_error; + } + /*NOTREACHED*/ assert(0); +} + +/* Opcode: Transaction P1 P2 P3 P4 P5 +** +** Begin a transaction on database P1 if a transaction is not already +** active. +** If P2 is non-zero, then a write-transaction is started, or if a +** read-transaction is already active, it is upgraded to a write-transaction. +** If P2 is zero, then a read-transaction is started. If P2 is 2 or more +** then an exclusive transaction is started. +** +** P1 is the index of the database file on which the transaction is +** started. Index 0 is the main database file and index 1 is the +** file used for temporary tables. Indices of 2 or more are used for +** attached databases. +** +** If a write-transaction is started and the Vdbe.usesStmtJournal flag is +** true (this flag is set if the Vdbe may modify more than one row and may +** throw an ABORT exception), a statement transaction may also be opened. +** More specifically, a statement transaction is opened iff the database +** connection is currently not in autocommit mode, or if there are other +** active statements. A statement transaction allows the changes made by this +** VDBE to be rolled back after an error without having to roll back the +** entire transaction. If no error is encountered, the statement transaction +** will automatically commit when the VDBE halts. +** +** If P5!=0 then this opcode also checks the schema cookie against P3 +** and the schema generation counter against P4. +** The cookie changes its value whenever the database schema changes. +** This operation is used to detect when that the cookie has changed +** and that the current process needs to reread the schema. If the schema +** cookie in P3 differs from the schema cookie in the database header or +** if the schema generation counter in P4 differs from the current +** generation counter, then an SQLITE_SCHEMA error is raised and execution +** halts. The sqlite3_step() wrapper function might then reprepare the +** statement and rerun it from the beginning. +*/ +case OP_Transaction: { + Btree *pBt; + Db *pDb; + int iMeta = 0; + + assert( p->bIsReader ); + assert( p->readOnly==0 || pOp->p2==0 ); + assert( pOp->p2>=0 && pOp->p2<=2 ); + assert( pOp->p1>=0 && pOp->p1nDb ); + assert( DbMaskTest(p->btreeMask, pOp->p1) ); + assert( rc==SQLITE_OK ); + if( pOp->p2 && (db->flags & (SQLITE_QueryOnly|SQLITE_CorruptRdOnly))!=0 ){ + if( db->flags & SQLITE_QueryOnly ){ + /* Writes prohibited by the "PRAGMA query_only=TRUE" statement */ + rc = SQLITE_READONLY; + }else{ + /* Writes prohibited due to a prior SQLITE_CORRUPT in the current + ** transaction */ + rc = SQLITE_CORRUPT; + } + goto abort_due_to_error; + } + pDb = &db->aDb[pOp->p1]; + pBt = pDb->pBt; + + if( pBt ){ + rc = sqlite3BtreeBeginTrans(pBt, pOp->p2, &iMeta); + testcase( rc==SQLITE_BUSY_SNAPSHOT ); + testcase( rc==SQLITE_BUSY_RECOVERY ); + if( rc!=SQLITE_OK ){ + if( (rc&0xff)==SQLITE_BUSY ){ + p->pc = (int)(pOp - aOp); + p->rc = rc; + goto vdbe_return; + } + goto abort_due_to_error; + } + + if( p->usesStmtJournal + && pOp->p2 + && (db->autoCommit==0 || db->nVdbeRead>1) + ){ + assert( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ); + if( p->iStatement==0 ){ + assert( db->nStatement>=0 && db->nSavepoint>=0 ); + db->nStatement++; + p->iStatement = db->nSavepoint + db->nStatement; + } + + rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement-1); + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeBeginStmt(pBt, p->iStatement); + } + + /* Store the current value of the database handles deferred constraint + ** counter. If the statement transaction needs to be rolled back, + ** the value of this counter needs to be restored too. */ + p->nStmtDefCons = db->nDeferredCons; + p->nStmtDefImmCons = db->nDeferredImmCons; + } + } + assert( pOp->p5==0 || pOp->p4type==P4_INT32 ); + if( rc==SQLITE_OK + && pOp->p5 + && (iMeta!=pOp->p3 || pDb->pSchema->iGeneration!=pOp->p4.i) + ){ + /* + ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema + ** version is checked to ensure that the schema has not changed since the + ** SQL statement was prepared. + */ + sqlite3DbFree(db, p->zErrMsg); + p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); + /* If the schema-cookie from the database file matches the cookie + ** stored with the in-memory representation of the schema, do + ** not reload the schema from the database file. + ** + ** If virtual-tables are in use, this is not just an optimization. + ** Often, v-tables store their data in other SQLite tables, which + ** are queried from within xNext() and other v-table methods using + ** prepared queries. If such a query is out-of-date, we do not want to + ** discard the database schema, as the user code implementing the + ** v-table would have to be ready for the sqlite3_vtab structure itself + ** to be invalidated whenever sqlite3_step() is called from within + ** a v-table method. + */ + if( db->aDb[pOp->p1].pSchema->schema_cookie!=iMeta ){ + sqlite3ResetOneSchema(db, pOp->p1); + } + p->expired = 1; + rc = SQLITE_SCHEMA; + + /* Set changeCntOn to 0 to prevent the value returned by sqlite3_changes() + ** from being modified in sqlite3VdbeHalt(). If this statement is + ** reprepared, changeCntOn will be set again. */ + p->changeCntOn = 0; + } + if( rc ) goto abort_due_to_error; + break; +} + +/* Opcode: ReadCookie P1 P2 P3 * * +** +** Read cookie number P3 from database P1 and write it into register P2. +** P3==1 is the schema version. P3==2 is the database format. +** P3==3 is the recommended pager cache size, and so forth. P1==0 is +** the main database file and P1==1 is the database file used to store +** temporary tables. +** +** There must be a read-lock on the database (either a transaction +** must be started or there must be an open cursor) before +** executing this instruction. +*/ +case OP_ReadCookie: { /* out2 */ + int iMeta; + int iDb; + int iCookie; + + assert( p->bIsReader ); + iDb = pOp->p1; + iCookie = pOp->p3; + assert( pOp->p3=0 && iDbnDb ); + assert( db->aDb[iDb].pBt!=0 ); + assert( DbMaskTest(p->btreeMask, iDb) ); + + sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta); + pOut = out2Prerelease(p, pOp); + pOut->u.i = iMeta; + break; +} + +/* Opcode: SetCookie P1 P2 P3 * P5 +** +** Write the integer value P3 into cookie number P2 of database P1. +** P2==1 is the schema version. P2==2 is the database format. +** P2==3 is the recommended pager cache +** size, and so forth. P1==0 is the main database file and P1==1 is the +** database file used to store temporary tables. +** +** A transaction must be started before executing this opcode. +** +** If P2 is the SCHEMA_VERSION cookie (cookie number 1) then the internal +** schema version is set to P3-P5. The "PRAGMA schema_version=N" statement +** has P5 set to 1, so that the internal schema version will be different +** from the database schema version, resulting in a schema reset. +*/ +case OP_SetCookie: { + Db *pDb; + + sqlite3VdbeIncrWriteCounter(p, 0); + assert( pOp->p2p1>=0 && pOp->p1nDb ); + assert( DbMaskTest(p->btreeMask, pOp->p1) ); + assert( p->readOnly==0 ); + pDb = &db->aDb[pOp->p1]; + assert( pDb->pBt!=0 ); + assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); + /* See note about index shifting on OP_ReadCookie */ + rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, pOp->p3); + if( pOp->p2==BTREE_SCHEMA_VERSION ){ + /* When the schema cookie changes, record the new cookie internally */ + *(u32*)&pDb->pSchema->schema_cookie = *(u32*)&pOp->p3 - pOp->p5; + db->mDbFlags |= DBFLAG_SchemaChange; + sqlite3FkClearTriggerCache(db, pOp->p1); + }else if( pOp->p2==BTREE_FILE_FORMAT ){ + /* Record changes in the file format */ + pDb->pSchema->file_format = pOp->p3; + } + if( pOp->p1==1 ){ + /* Invalidate all prepared statements whenever the TEMP database + ** schema is changed. Ticket #1644 */ + sqlite3ExpirePreparedStatements(db, 0); + p->expired = 0; + } + if( rc ) goto abort_due_to_error; + break; +} + +/* Opcode: OpenRead P1 P2 P3 P4 P5 +** Synopsis: root=P2 iDb=P3 +** +** Open a read-only cursor for the database table whose root page is +** P2 in a database file. The database file is determined by P3. +** P3==0 means the main database, P3==1 means the database used for +** temporary tables, and P3>1 means used the corresponding attached +** database. Give the new cursor an identifier of P1. The P1 +** values need not be contiguous but all P1 values should be small integers. +** It is an error for P1 to be negative. +** +** Allowed P5 bits: +**
      +**
    • 0x02 OPFLAG_SEEKEQ: This cursor will only be used for +** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT +** of OP_SeekLE/OP_IdxLT) +**
    +** +** The P4 value may be either an integer (P4_INT32) or a pointer to +** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo +** object, then table being opened must be an [index b-tree] where the +** KeyInfo object defines the content and collating +** sequence of that index b-tree. Otherwise, if P4 is an integer +** value, then the table being opened must be a [table b-tree] with a +** number of columns no less than the value of P4. +** +** See also: OpenWrite, ReopenIdx +*/ +/* Opcode: ReopenIdx P1 P2 P3 P4 P5 +** Synopsis: root=P2 iDb=P3 +** +** The ReopenIdx opcode works like OP_OpenRead except that it first +** checks to see if the cursor on P1 is already open on the same +** b-tree and if it is this opcode becomes a no-op. In other words, +** if the cursor is already open, do not reopen it. +** +** The ReopenIdx opcode may only be used with P5==0 or P5==OPFLAG_SEEKEQ +** and with P4 being a P4_KEYINFO object. Furthermore, the P3 value must +** be the same as every other ReopenIdx or OpenRead for the same cursor +** number. +** +** Allowed P5 bits: +**
      +**
    • 0x02 OPFLAG_SEEKEQ: This cursor will only be used for +** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT +** of OP_SeekLE/OP_IdxLT) +**
    +** +** See also: OP_OpenRead, OP_OpenWrite +*/ +/* Opcode: OpenWrite P1 P2 P3 P4 P5 +** Synopsis: root=P2 iDb=P3 +** +** Open a read/write cursor named P1 on the table or index whose root +** page is P2 (or whose root page is held in register P2 if the +** OPFLAG_P2ISREG bit is set in P5 - see below). +** +** The P4 value may be either an integer (P4_INT32) or a pointer to +** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo +** object, then table being opened must be an [index b-tree] where the +** KeyInfo object defines the content and collating +** sequence of that index b-tree. Otherwise, if P4 is an integer +** value, then the table being opened must be a [table b-tree] with a +** number of columns no less than the value of P4. +** +** Allowed P5 bits: +**
      +**
    • 0x02 OPFLAG_SEEKEQ: This cursor will only be used for +** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT +** of OP_SeekLE/OP_IdxLT) +**
    • 0x08 OPFLAG_FORDELETE: This cursor is used only to seek +** and subsequently delete entries in an index btree. This is a +** hint to the storage engine that the storage engine is allowed to +** ignore. The hint is not used by the official SQLite b*tree storage +** engine, but is used by COMDB2. +**
    • 0x10 OPFLAG_P2ISREG: Use the content of register P2 +** as the root page, not the value of P2 itself. +**
    +** +** This instruction works like OpenRead except that it opens the cursor +** in read/write mode. +** +** See also: OP_OpenRead, OP_ReopenIdx +*/ +case OP_ReopenIdx: { /* ncycle */ + int nField; + KeyInfo *pKeyInfo; + u32 p2; + int iDb; + int wrFlag; + Btree *pX; + VdbeCursor *pCur; + Db *pDb; + + assert( pOp->p5==0 || pOp->p5==OPFLAG_SEEKEQ ); + assert( pOp->p4type==P4_KEYINFO ); + pCur = p->apCsr[pOp->p1]; + if( pCur && pCur->pgnoRoot==(u32)pOp->p2 ){ + assert( pCur->iDb==pOp->p3 ); /* Guaranteed by the code generator */ + assert( pCur->eCurType==CURTYPE_BTREE ); + sqlite3BtreeClearCursor(pCur->uc.pCursor); + goto open_cursor_set_hints; + } + /* If the cursor is not currently open or is open on a different + ** index, then fall through into OP_OpenRead to force a reopen */ +case OP_OpenRead: /* ncycle */ +case OP_OpenWrite: + + assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 || pOp->p5==OPFLAG_SEEKEQ ); + assert( p->bIsReader ); + assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx + || p->readOnly==0 ); + + if( p->expired==1 ){ + rc = SQLITE_ABORT_ROLLBACK; + goto abort_due_to_error; + } + + nField = 0; + pKeyInfo = 0; + p2 = (u32)pOp->p2; + iDb = pOp->p3; + assert( iDb>=0 && iDbnDb ); + assert( DbMaskTest(p->btreeMask, iDb) ); + pDb = &db->aDb[iDb]; + pX = pDb->pBt; + assert( pX!=0 ); + if( pOp->opcode==OP_OpenWrite ){ + assert( OPFLAG_FORDELETE==BTREE_FORDELETE ); + wrFlag = BTREE_WRCSR | (pOp->p5 & OPFLAG_FORDELETE); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + if( pDb->pSchema->file_format < p->minWriteFileFormat ){ + p->minWriteFileFormat = pDb->pSchema->file_format; + } + if( pOp->p5 & OPFLAG_P2ISREG ){ + assert( p2>0 ); + assert( p2<=(u32)(p->nMem+1 - p->nCursor) ); + pIn2 = &aMem[p2]; + assert( memIsValid(pIn2) ); + assert( (pIn2->flags & MEM_Int)!=0 ); + sqlite3VdbeMemIntegerify(pIn2); + p2 = (int)pIn2->u.i; + /* The p2 value always comes from a prior OP_CreateBtree opcode and + ** that opcode will always set the p2 value to 2 or more or else fail. + ** If there were a failure, the prepared statement would have halted + ** before reaching this instruction. */ + assert( p2>=2 ); + } + }else{ + wrFlag = 0; + assert( (pOp->p5 & OPFLAG_P2ISREG)==0 ); + } + if( pOp->p4type==P4_KEYINFO ){ + pKeyInfo = pOp->p4.pKeyInfo; + assert( pKeyInfo->enc==ENC(db) ); + assert( pKeyInfo->db==db ); + nField = pKeyInfo->nAllField; + }else if( pOp->p4type==P4_INT32 ){ + nField = pOp->p4.i; + } + assert( pOp->p1>=0 ); + assert( nField>=0 ); + testcase( nField==0 ); /* Table with INTEGER PRIMARY KEY and nothing else */ + pCur = allocateCursor(p, pOp->p1, nField, CURTYPE_BTREE); + if( pCur==0 ) goto no_mem; + pCur->iDb = iDb; + pCur->nullRow = 1; + pCur->isOrdered = 1; + pCur->pgnoRoot = p2; +#ifdef SQLITE_DEBUG + pCur->wrFlag = wrFlag; +#endif + rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->uc.pCursor); + pCur->pKeyInfo = pKeyInfo; + /* Set the VdbeCursor.isTable variable. Previous versions of + ** SQLite used to check if the root-page flags were sane at this point + ** and report database corruption if they were not, but this check has + ** since moved into the btree layer. */ + pCur->isTable = pOp->p4type!=P4_KEYINFO; + +open_cursor_set_hints: + assert( OPFLAG_BULKCSR==BTREE_BULKLOAD ); + assert( OPFLAG_SEEKEQ==BTREE_SEEK_EQ ); + testcase( pOp->p5 & OPFLAG_BULKCSR ); + testcase( pOp->p2 & OPFLAG_SEEKEQ ); + sqlite3BtreeCursorHintFlags(pCur->uc.pCursor, + (pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ))); + if( rc ) goto abort_due_to_error; + break; +} + +/* Opcode: OpenDup P1 P2 * * * +** +** Open a new cursor P1 that points to the same ephemeral table as +** cursor P2. The P2 cursor must have been opened by a prior OP_OpenEphemeral +** opcode. Only ephemeral cursors may be duplicated. +** +** Duplicate ephemeral cursors are used for self-joins of materialized views. +*/ +case OP_OpenDup: { /* ncycle */ + VdbeCursor *pOrig; /* The original cursor to be duplicated */ + VdbeCursor *pCx; /* The new cursor */ + + pOrig = p->apCsr[pOp->p2]; + assert( pOrig ); + assert( pOrig->isEphemeral ); /* Only ephemeral cursors can be duplicated */ + + pCx = allocateCursor(p, pOp->p1, pOrig->nField, CURTYPE_BTREE); + if( pCx==0 ) goto no_mem; + pCx->nullRow = 1; + pCx->isEphemeral = 1; + pCx->pKeyInfo = pOrig->pKeyInfo; + pCx->isTable = pOrig->isTable; + pCx->pgnoRoot = pOrig->pgnoRoot; + pCx->isOrdered = pOrig->isOrdered; + pCx->ub.pBtx = pOrig->ub.pBtx; + pCx->noReuse = 1; + pOrig->noReuse = 1; + rc = sqlite3BtreeCursor(pCx->ub.pBtx, pCx->pgnoRoot, BTREE_WRCSR, + pCx->pKeyInfo, pCx->uc.pCursor); + /* The sqlite3BtreeCursor() routine can only fail for the first cursor + ** opened for a database. Since there is already an open cursor when this + ** opcode is run, the sqlite3BtreeCursor() cannot fail */ + assert( rc==SQLITE_OK ); + break; +} + + +/* Opcode: OpenEphemeral P1 P2 P3 P4 P5 +** Synopsis: nColumn=P2 +** +** Open a new cursor P1 to a transient table. +** The cursor is always opened read/write even if +** the main database is read-only. The ephemeral +** table is deleted automatically when the cursor is closed. +** +** If the cursor P1 is already opened on an ephemeral table, the table +** is cleared (all content is erased). +** +** P2 is the number of columns in the ephemeral table. +** The cursor points to a BTree table if P4==0 and to a BTree index +** if P4 is not 0. If P4 is not NULL, it points to a KeyInfo structure +** that defines the format of keys in the index. +** +** The P5 parameter can be a mask of the BTREE_* flags defined +** in btree.h. These flags control aspects of the operation of +** the btree. The BTREE_OMIT_JOURNAL and BTREE_SINGLE flags are +** added automatically. +** +** If P3 is positive, then reg[P3] is modified slightly so that it +** can be used as zero-length data for OP_Insert. This is an optimization +** that avoids an extra OP_Blob opcode to initialize that register. +*/ +/* Opcode: OpenAutoindex P1 P2 * P4 * +** Synopsis: nColumn=P2 +** +** This opcode works the same as OP_OpenEphemeral. It has a +** different name to distinguish its use. Tables created using +** by this opcode will be used for automatically created transient +** indices in joins. +*/ +case OP_OpenAutoindex: /* ncycle */ +case OP_OpenEphemeral: { /* ncycle */ + VdbeCursor *pCx; + KeyInfo *pKeyInfo; + + static const int vfsFlags = + SQLITE_OPEN_READWRITE | + SQLITE_OPEN_CREATE | + SQLITE_OPEN_EXCLUSIVE | + SQLITE_OPEN_DELETEONCLOSE | + SQLITE_OPEN_TRANSIENT_DB; + assert( pOp->p1>=0 ); + assert( pOp->p2>=0 ); + if( pOp->p3>0 ){ + /* Make register reg[P3] into a value that can be used as the data + ** form sqlite3BtreeInsert() where the length of the data is zero. */ + assert( pOp->p2==0 ); /* Only used when number of columns is zero */ + assert( pOp->opcode==OP_OpenEphemeral ); + assert( aMem[pOp->p3].flags & MEM_Null ); + aMem[pOp->p3].n = 0; + aMem[pOp->p3].z = ""; + } + pCx = p->apCsr[pOp->p1]; + if( pCx && !pCx->noReuse && ALWAYS(pOp->p2<=pCx->nField) ){ + /* If the ephemeral table is already open and has no duplicates from + ** OP_OpenDup, then erase all existing content so that the table is + ** empty again, rather than creating a new table. */ + assert( pCx->isEphemeral ); + pCx->seqCount = 0; + pCx->cacheStatus = CACHE_STALE; + rc = sqlite3BtreeClearTable(pCx->ub.pBtx, pCx->pgnoRoot, 0); + }else{ + pCx = allocateCursor(p, pOp->p1, pOp->p2, CURTYPE_BTREE); + if( pCx==0 ) goto no_mem; + pCx->isEphemeral = 1; + rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->ub.pBtx, + BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, + vfsFlags); + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeBeginTrans(pCx->ub.pBtx, 1, 0); + if( rc==SQLITE_OK ){ + /* If a transient index is required, create it by calling + ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before + ** opening it. If a transient table is required, just use the + ** automatically created table with root-page 1 (an BLOB_INTKEY table). + */ + if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){ + assert( pOp->p4type==P4_KEYINFO ); + rc = sqlite3BtreeCreateTable(pCx->ub.pBtx, &pCx->pgnoRoot, + BTREE_BLOBKEY | pOp->p5); + if( rc==SQLITE_OK ){ + assert( pCx->pgnoRoot==SCHEMA_ROOT+1 ); + assert( pKeyInfo->db==db ); + assert( pKeyInfo->enc==ENC(db) ); + rc = sqlite3BtreeCursor(pCx->ub.pBtx, pCx->pgnoRoot, BTREE_WRCSR, + pKeyInfo, pCx->uc.pCursor); + } + pCx->isTable = 0; + }else{ + pCx->pgnoRoot = SCHEMA_ROOT; + rc = sqlite3BtreeCursor(pCx->ub.pBtx, SCHEMA_ROOT, BTREE_WRCSR, + 0, pCx->uc.pCursor); + pCx->isTable = 1; + } + } + pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); + assert( p->apCsr[pOp->p1]==pCx ); + if( rc ){ + assert( !sqlite3BtreeClosesWithCursor(pCx->ub.pBtx, pCx->uc.pCursor) ); + sqlite3BtreeClose(pCx->ub.pBtx); + p->apCsr[pOp->p1] = 0; /* Not required; helps with static analysis */ + }else{ + assert( sqlite3BtreeClosesWithCursor(pCx->ub.pBtx, pCx->uc.pCursor) ); + } + } + } + if( rc ) goto abort_due_to_error; + pCx->nullRow = 1; + break; +} + +/* Opcode: SorterOpen P1 P2 P3 P4 * +** +** This opcode works like OP_OpenEphemeral except that it opens +** a transient index that is specifically designed to sort large +** tables using an external merge-sort algorithm. +** +** If argument P3 is non-zero, then it indicates that the sorter may +** assume that a stable sort considering the first P3 fields of each +** key is sufficient to produce the required results. +*/ +case OP_SorterOpen: { + VdbeCursor *pCx; + + assert( pOp->p1>=0 ); + assert( pOp->p2>=0 ); + pCx = allocateCursor(p, pOp->p1, pOp->p2, CURTYPE_SORTER); + if( pCx==0 ) goto no_mem; + pCx->pKeyInfo = pOp->p4.pKeyInfo; + assert( pCx->pKeyInfo->db==db ); + assert( pCx->pKeyInfo->enc==ENC(db) ); + rc = sqlite3VdbeSorterInit(db, pOp->p3, pCx); + if( rc ) goto abort_due_to_error; + break; +} + +/* Opcode: SequenceTest P1 P2 * * * +** Synopsis: if( cursor[P1].ctr++ ) pc = P2 +** +** P1 is a sorter cursor. If the sequence counter is currently zero, jump +** to P2. Regardless of whether or not the jump is taken, increment the +** the sequence value. +*/ +case OP_SequenceTest: { + VdbeCursor *pC; + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( isSorter(pC) ); + if( (pC->seqCount++)==0 ){ + goto jump_to_p2; + } + break; +} + +/* Opcode: OpenPseudo P1 P2 P3 * * +** Synopsis: P3 columns in r[P2] +** +** Open a new cursor that points to a fake table that contains a single +** row of data. The content of that one row is the content of memory +** register P2. In other words, cursor P1 becomes an alias for the +** MEM_Blob content contained in register P2. +** +** A pseudo-table created by this opcode is used to hold a single +** row output from the sorter so that the row can be decomposed into +** individual columns using the OP_Column opcode. The OP_Column opcode +** is the only cursor opcode that works with a pseudo-table. +** +** P3 is the number of fields in the records that will be stored by +** the pseudo-table. If P2 is 0 or negative then the pseudo-cursor +** will return NULL for every column. +*/ +case OP_OpenPseudo: { + VdbeCursor *pCx; + + assert( pOp->p1>=0 ); + assert( pOp->p3>=0 ); + pCx = allocateCursor(p, pOp->p1, pOp->p3, CURTYPE_PSEUDO); + if( pCx==0 ) goto no_mem; + pCx->nullRow = 1; + pCx->seekResult = pOp->p2; + pCx->isTable = 1; + /* Give this pseudo-cursor a fake BtCursor pointer so that pCx + ** can be safely passed to sqlite3VdbeCursorMoveto(). This avoids a test + ** for pCx->eCurType==CURTYPE_BTREE inside of sqlite3VdbeCursorMoveto() + ** which is a performance optimization */ + pCx->uc.pCursor = sqlite3BtreeFakeValidCursor(); + assert( pOp->p5==0 ); + break; +} + +/* Opcode: Close P1 * * * * +** +** Close a cursor previously opened as P1. If P1 is not +** currently open, this instruction is a no-op. +*/ +case OP_Close: { /* ncycle */ + assert( pOp->p1>=0 && pOp->p1nCursor ); + sqlite3VdbeFreeCursor(p, p->apCsr[pOp->p1]); + p->apCsr[pOp->p1] = 0; + break; +} + +#ifdef SQLITE_ENABLE_COLUMN_USED_MASK +/* Opcode: ColumnsUsed P1 * * P4 * +** +** This opcode (which only exists if SQLite was compiled with +** SQLITE_ENABLE_COLUMN_USED_MASK) identifies which columns of the +** table or index for cursor P1 are used. P4 is a 64-bit integer +** (P4_INT64) in which the first 63 bits are one for each of the +** first 63 columns of the table or index that are actually used +** by the cursor. The high-order bit is set if any column after +** the 64th is used. +*/ +case OP_ColumnsUsed: { + VdbeCursor *pC; + pC = p->apCsr[pOp->p1]; + assert( pC->eCurType==CURTYPE_BTREE ); + pC->maskUsed = *(u64*)pOp->p4.pI64; + break; +} +#endif + +/* Opcode: SeekGE P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), +** use the value in register P3 as the key. If cursor P1 refers +** to an SQL index, then P3 is the first in an array of P4 registers +** that are used as an unpacked index key. +** +** Reposition cursor P1 so that it points to the smallest entry that +** is greater than or equal to the key value. If there are no records +** greater than or equal to the key and P2 is not zero, then jump to P2. +** +** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this +** opcode will either land on a record that exactly matches the key, or +** else it will cause a jump to P2. When the cursor is OPFLAG_SEEKEQ, +** this opcode must be followed by an IdxLE opcode with the same arguments. +** The IdxGT opcode will be skipped if this opcode succeeds, but the +** IdxGT opcode will be used on subsequent loop iterations. The +** OPFLAG_SEEKEQ flags is a hint to the btree layer to say that this +** is an equality search. +** +** This opcode leaves the cursor configured to move in forward order, +** from the beginning toward the end. In other words, the cursor is +** configured to use Next, not Prev. +** +** See also: Found, NotFound, SeekLt, SeekGt, SeekLe +*/ +/* Opcode: SeekGT P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), +** use the value in register P3 as a key. If cursor P1 refers +** to an SQL index, then P3 is the first in an array of P4 registers +** that are used as an unpacked index key. +** +** Reposition cursor P1 so that it points to the smallest entry that +** is greater than the key value. If there are no records greater than +** the key and P2 is not zero, then jump to P2. +** +** This opcode leaves the cursor configured to move in forward order, +** from the beginning toward the end. In other words, the cursor is +** configured to use Next, not Prev. +** +** See also: Found, NotFound, SeekLt, SeekGe, SeekLe +*/ +/* Opcode: SeekLT P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), +** use the value in register P3 as a key. If cursor P1 refers +** to an SQL index, then P3 is the first in an array of P4 registers +** that are used as an unpacked index key. +** +** Reposition cursor P1 so that it points to the largest entry that +** is less than the key value. If there are no records less than +** the key and P2 is not zero, then jump to P2. +** +** This opcode leaves the cursor configured to move in reverse order, +** from the end toward the beginning. In other words, the cursor is +** configured to use Prev, not Next. +** +** See also: Found, NotFound, SeekGt, SeekGe, SeekLe +*/ +/* Opcode: SeekLE P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), +** use the value in register P3 as a key. If cursor P1 refers +** to an SQL index, then P3 is the first in an array of P4 registers +** that are used as an unpacked index key. +** +** Reposition cursor P1 so that it points to the largest entry that +** is less than or equal to the key value. If there are no records +** less than or equal to the key and P2 is not zero, then jump to P2. +** +** This opcode leaves the cursor configured to move in reverse order, +** from the end toward the beginning. In other words, the cursor is +** configured to use Prev, not Next. +** +** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this +** opcode will either land on a record that exactly matches the key, or +** else it will cause a jump to P2. When the cursor is OPFLAG_SEEKEQ, +** this opcode must be followed by an IdxLE opcode with the same arguments. +** The IdxGE opcode will be skipped if this opcode succeeds, but the +** IdxGE opcode will be used on subsequent loop iterations. The +** OPFLAG_SEEKEQ flags is a hint to the btree layer to say that this +** is an equality search. +** +** See also: Found, NotFound, SeekGt, SeekGe, SeekLt +*/ +case OP_SeekLT: /* jump0, in3, group, ncycle */ +case OP_SeekLE: /* jump0, in3, group, ncycle */ +case OP_SeekGE: /* jump0, in3, group, ncycle */ +case OP_SeekGT: { /* jump0, in3, group, ncycle */ + int res; /* Comparison result */ + int oc; /* Opcode */ + VdbeCursor *pC; /* The cursor to seek */ + UnpackedRecord r; /* The key to seek for */ + int nField; /* Number of columns or fields in the key */ + i64 iKey; /* The rowid we are to seek to */ + int eqOnly; /* Only interested in == results */ + + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( pOp->p2!=0 ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( OP_SeekLE == OP_SeekLT+1 ); + assert( OP_SeekGE == OP_SeekLT+2 ); + assert( OP_SeekGT == OP_SeekLT+3 ); + assert( pC->isOrdered ); + assert( pC->uc.pCursor!=0 ); + oc = pOp->opcode; + eqOnly = 0; + pC->nullRow = 0; +#ifdef SQLITE_DEBUG + pC->seekOp = pOp->opcode; +#endif + + pC->deferredMoveto = 0; + pC->cacheStatus = CACHE_STALE; + if( pC->isTable ){ + u16 flags3, newType; + /* The OPFLAG_SEEKEQ/BTREE_SEEK_EQ flag is only set on index cursors */ + assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0 + || CORRUPT_DB ); + + /* The input value in P3 might be of any type: integer, real, string, + ** blob, or NULL. But it needs to be an integer before we can do + ** the seek, so convert it. */ + pIn3 = &aMem[pOp->p3]; + flags3 = pIn3->flags; + if( (flags3 & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Str))==MEM_Str ){ + applyNumericAffinity(pIn3, 0); + } + iKey = sqlite3VdbeIntValue(pIn3); /* Get the integer key value */ + newType = pIn3->flags; /* Record the type after applying numeric affinity */ + pIn3->flags = flags3; /* But convert the type back to its original */ + + /* If the P3 value could not be converted into an integer without + ** loss of information, then special processing is required... */ + if( (newType & (MEM_Int|MEM_IntReal))==0 ){ + int c; + if( (newType & MEM_Real)==0 ){ + if( (newType & MEM_Null) || oc>=OP_SeekGE ){ + VdbeBranchTaken(1,2); + goto jump_to_p2; + }else{ + rc = sqlite3BtreeLast(pC->uc.pCursor, &res); + if( rc!=SQLITE_OK ) goto abort_due_to_error; + goto seek_not_found; + } + } + c = sqlite3IntFloatCompare(iKey, pIn3->u.r); + + /* If the approximation iKey is larger than the actual real search + ** term, substitute >= for > and < for <=. e.g. if the search term + ** is 4.9 and the integer approximation 5: + ** + ** (x > 4.9) -> (x >= 5) + ** (x <= 4.9) -> (x < 5) + */ + if( c>0 ){ + assert( OP_SeekGE==(OP_SeekGT-1) ); + assert( OP_SeekLT==(OP_SeekLE-1) ); + assert( (OP_SeekLE & 0x0001)==(OP_SeekGT & 0x0001) ); + if( (oc & 0x0001)==(OP_SeekGT & 0x0001) ) oc--; + } + + /* If the approximation iKey is smaller than the actual real search + ** term, substitute <= for < and > for >=. */ + else if( c<0 ){ + assert( OP_SeekLE==(OP_SeekLT+1) ); + assert( OP_SeekGT==(OP_SeekGE+1) ); + assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) ); + if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++; + } + } + rc = sqlite3BtreeTableMoveto(pC->uc.pCursor, (u64)iKey, 0, &res); + pC->movetoTarget = iKey; /* Used by OP_Delete */ + if( rc!=SQLITE_OK ){ + goto abort_due_to_error; + } + }else{ + /* For a cursor with the OPFLAG_SEEKEQ/BTREE_SEEK_EQ hint, only the + ** OP_SeekGE and OP_SeekLE opcodes are allowed, and these must be + ** immediately followed by an OP_IdxGT or OP_IdxLT opcode, respectively, + ** with the same key. + */ + if( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ) ){ + eqOnly = 1; + assert( pOp->opcode==OP_SeekGE || pOp->opcode==OP_SeekLE ); + assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT ); + assert( pOp->opcode==OP_SeekGE || pOp[1].opcode==OP_IdxLT ); + assert( pOp->opcode==OP_SeekLE || pOp[1].opcode==OP_IdxGT ); + assert( pOp[1].p1==pOp[0].p1 ); + assert( pOp[1].p2==pOp[0].p2 ); + assert( pOp[1].p3==pOp[0].p3 ); + assert( pOp[1].p4.i==pOp[0].p4.i ); + } + + nField = pOp->p4.i; + assert( pOp->p4type==P4_INT32 ); + assert( nField>0 ); + r.pKeyInfo = pC->pKeyInfo; + r.nField = (u16)nField; + + /* The next line of code computes as follows, only faster: + ** if( oc==OP_SeekGT || oc==OP_SeekLE ){ + ** r.default_rc = -1; + ** }else{ + ** r.default_rc = +1; + ** } + */ + r.default_rc = ((1 & (oc - OP_SeekLT)) ? -1 : +1); + assert( oc!=OP_SeekGT || r.default_rc==-1 ); + assert( oc!=OP_SeekLE || r.default_rc==-1 ); + assert( oc!=OP_SeekGE || r.default_rc==+1 ); + assert( oc!=OP_SeekLT || r.default_rc==+1 ); + + r.aMem = &aMem[pOp->p3]; +#ifdef SQLITE_DEBUG + { + int i; + for(i=0; i0 ) REGISTER_TRACE(pOp->p3+i, &r.aMem[i]); + } + } +#endif + r.eqSeen = 0; + rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, &r, &res); + if( rc!=SQLITE_OK ){ + goto abort_due_to_error; + } + if( eqOnly && r.eqSeen==0 ){ + assert( res!=0 ); + goto seek_not_found; + } + } +#ifdef SQLITE_TEST + sqlite3_search_count++; +#endif + if( oc>=OP_SeekGE ){ assert( oc==OP_SeekGE || oc==OP_SeekGT ); + if( res<0 || (res==0 && oc==OP_SeekGT) ){ + res = 0; + rc = sqlite3BtreeNext(pC->uc.pCursor, 0); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_DONE ){ + rc = SQLITE_OK; + res = 1; + }else{ + goto abort_due_to_error; + } + } + }else{ + res = 0; + } + }else{ + assert( oc==OP_SeekLT || oc==OP_SeekLE ); + if( res>0 || (res==0 && oc==OP_SeekLT) ){ + res = 0; + rc = sqlite3BtreePrevious(pC->uc.pCursor, 0); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_DONE ){ + rc = SQLITE_OK; + res = 1; + }else{ + goto abort_due_to_error; + } + } + }else{ + /* res might be negative because the table is empty. Check to + ** see if this is the case. + */ + res = sqlite3BtreeEof(pC->uc.pCursor); + } + } +seek_not_found: + assert( pOp->p2>0 ); + VdbeBranchTaken(res!=0,2); + if( res ){ + goto jump_to_p2; + }else if( eqOnly ){ + assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT ); + pOp++; /* Skip the OP_IdxLt or OP_IdxGT that follows */ + } + break; +} + + +/* Opcode: SeekScan P1 P2 * * P5 +** Synopsis: Scan-ahead up to P1 rows +** +** This opcode is a prefix opcode to OP_SeekGE. In other words, this +** opcode must be immediately followed by OP_SeekGE. This constraint is +** checked by assert() statements. +** +** This opcode uses the P1 through P4 operands of the subsequent +** OP_SeekGE. In the text that follows, the operands of the subsequent +** OP_SeekGE opcode are denoted as SeekOP.P1 through SeekOP.P4. Only +** the P1, P2 and P5 operands of this opcode are also used, and are called +** This.P1, This.P2 and This.P5. +** +** This opcode helps to optimize IN operators on a multi-column index +** where the IN operator is on the later terms of the index by avoiding +** unnecessary seeks on the btree, substituting steps to the next row +** of the b-tree instead. A correct answer is obtained if this opcode +** is omitted or is a no-op. +** +** The SeekGE.P3 and SeekGE.P4 operands identify an unpacked key which +** is the desired entry that we want the cursor SeekGE.P1 to be pointing +** to. Call this SeekGE.P3/P4 row the "target". +** +** If the SeekGE.P1 cursor is not currently pointing to a valid row, +** then this opcode is a no-op and control passes through into the OP_SeekGE. +** +** If the SeekGE.P1 cursor is pointing to a valid row, then that row +** might be the target row, or it might be near and slightly before the +** target row, or it might be after the target row. If the cursor is +** currently before the target row, then this opcode attempts to position +** the cursor on or after the target row by invoking sqlite3BtreeStep() +** on the cursor between 1 and This.P1 times. +** +** The This.P5 parameter is a flag that indicates what to do if the +** cursor ends up pointing at a valid row that is past the target +** row. If This.P5 is false (0) then a jump is made to SeekGE.P2. If +** This.P5 is true (non-zero) then a jump is made to This.P2. The P5==0 +** case occurs when there are no inequality constraints to the right of +** the IN constraint. The jump to SeekGE.P2 ends the loop. The P5!=0 case +** occurs when there are inequality constraints to the right of the IN +** operator. In that case, the This.P2 will point either directly to or +** to setup code prior to the OP_IdxGT or OP_IdxGE opcode that checks for +** loop terminate. +** +** Possible outcomes from this opcode:
      +** +**
    1. If the cursor is initially not pointed to any valid row, then +** fall through into the subsequent OP_SeekGE opcode. +** +**
    2. If the cursor is left pointing to a row that is before the target +** row, even after making as many as This.P1 calls to +** sqlite3BtreeNext(), then also fall through into OP_SeekGE. +** +**
    3. If the cursor is left pointing at the target row, either because it +** was at the target row to begin with or because one or more +** sqlite3BtreeNext() calls moved the cursor to the target row, +** then jump to This.P2.., +** +**
    4. If the cursor started out before the target row and a call to +** to sqlite3BtreeNext() moved the cursor off the end of the index +** (indicating that the target row definitely does not exist in the +** btree) then jump to SeekGE.P2, ending the loop. +** +**
    5. If the cursor ends up on a valid row that is past the target row +** (indicating that the target row does not exist in the btree) then +** jump to SeekOP.P2 if This.P5==0 or to This.P2 if This.P5>0. +**
    +*/ +case OP_SeekScan: { /* ncycle */ + VdbeCursor *pC; + int res; + int nStep; + UnpackedRecord r; + + assert( pOp[1].opcode==OP_SeekGE ); + + /* If pOp->p5 is clear, then pOp->p2 points to the first instruction past the + ** OP_IdxGT that follows the OP_SeekGE. Otherwise, it points to the first + ** opcode past the OP_SeekGE itself. */ + assert( pOp->p2>=(int)(pOp-aOp)+2 ); +#ifdef SQLITE_DEBUG + if( pOp->p5==0 ){ + /* There are no inequality constraints following the IN constraint. */ + assert( pOp[1].p1==aOp[pOp->p2-1].p1 ); + assert( pOp[1].p2==aOp[pOp->p2-1].p2 ); + assert( pOp[1].p3==aOp[pOp->p2-1].p3 ); + assert( aOp[pOp->p2-1].opcode==OP_IdxGT + || aOp[pOp->p2-1].opcode==OP_IdxGE ); + testcase( aOp[pOp->p2-1].opcode==OP_IdxGE ); + }else{ + /* There are inequality constraints. */ + assert( pOp->p2==(int)(pOp-aOp)+2 ); + assert( aOp[pOp->p2-1].opcode==OP_SeekGE ); + } +#endif + + assert( pOp->p1>0 ); + pC = p->apCsr[pOp[1].p1]; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( !pC->isTable ); + if( !sqlite3BtreeCursorIsValidNN(pC->uc.pCursor) ){ +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + printf("... cursor not valid - fall through\n"); + } +#endif + break; + } + nStep = pOp->p1; + assert( nStep>=1 ); + r.pKeyInfo = pC->pKeyInfo; + r.nField = (u16)pOp[1].p4.i; + r.default_rc = 0; + r.aMem = &aMem[pOp[1].p3]; +#ifdef SQLITE_DEBUG + { + int i; + for(i=0; i0 && pOp->p5==0 ){ + seekscan_search_fail: + /* Jump to SeekGE.P2, ending the loop */ +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + printf("... %d steps and then skip\n", pOp->p1 - nStep); + } +#endif + VdbeBranchTaken(1,3); + pOp++; + goto jump_to_p2; + } + if( res>=0 ){ + /* Jump to This.P2, bypassing the OP_SeekGE opcode */ +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + printf("... %d steps and then success\n", pOp->p1 - nStep); + } +#endif + VdbeBranchTaken(2,3); + goto jump_to_p2; + break; + } + if( nStep<=0 ){ +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + printf("... fall through after %d steps\n", pOp->p1); + } +#endif + VdbeBranchTaken(0,3); + break; + } + nStep--; + pC->cacheStatus = CACHE_STALE; + rc = sqlite3BtreeNext(pC->uc.pCursor, 0); + if( rc ){ + if( rc==SQLITE_DONE ){ + rc = SQLITE_OK; + goto seekscan_search_fail; + }else{ + goto abort_due_to_error; + } + } + } + + break; +} + + +/* Opcode: SeekHit P1 P2 P3 * * +** Synopsis: set P2<=seekHit<=P3 +** +** Increase or decrease the seekHit value for cursor P1, if necessary, +** so that it is no less than P2 and no greater than P3. +** +** The seekHit integer represents the maximum of terms in an index for which +** there is known to be at least one match. If the seekHit value is smaller +** than the total number of equality terms in an index lookup, then the +** OP_IfNoHope opcode might run to see if the IN loop can be abandoned +** early, thus saving work. This is part of the IN-early-out optimization. +** +** P1 must be a valid b-tree cursor. +*/ +case OP_SeekHit: { /* ncycle */ + VdbeCursor *pC; + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pOp->p3>=pOp->p2 ); + if( pC->seekHitp2 ){ +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + printf("seekHit changes from %d to %d\n", pC->seekHit, pOp->p2); + } +#endif + pC->seekHit = pOp->p2; + }else if( pC->seekHit>pOp->p3 ){ +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + printf("seekHit changes from %d to %d\n", pC->seekHit, pOp->p3); + } +#endif + pC->seekHit = pOp->p3; + } + break; +} + +/* Opcode: IfNotOpen P1 P2 * * * +** Synopsis: if( !csr[P1] ) goto P2 +** +** If cursor P1 is not open or if P1 is set to a NULL row using the +** OP_NullRow opcode, then jump to instruction P2. Otherwise, fall through. +*/ +case OP_IfNotOpen: { /* jump */ + VdbeCursor *pCur; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pCur = p->apCsr[pOp->p1]; + VdbeBranchTaken(pCur==0 || pCur->nullRow, 2); + if( pCur==0 || pCur->nullRow ){ + goto jump_to_p2_and_check_for_interrupt; + } + break; +} + +/* Opcode: Found P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** If P4==0 then register P3 holds a blob constructed by MakeRecord. If +** P4>0 then register P3 is the first of P4 registers that form an unpacked +** record. +** +** Cursor P1 is on an index btree. If the record identified by P3 and P4 +** is a prefix of any entry in P1 then a jump is made to P2 and +** P1 is left pointing at the matching entry. +** +** This operation leaves the cursor in a state where it can be +** advanced in the forward direction. The Next instruction will work, +** but not the Prev instruction. +** +** See also: NotFound, NoConflict, NotExists. SeekGe +*/ +/* Opcode: NotFound P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** If P4==0 then register P3 holds a blob constructed by MakeRecord. If +** P4>0 then register P3 is the first of P4 registers that form an unpacked +** record. +** +** Cursor P1 is on an index btree. If the record identified by P3 and P4 +** is not the prefix of any entry in P1 then a jump is made to P2. If P1 +** does contain an entry whose prefix matches the P3/P4 record then control +** falls through to the next instruction and P1 is left pointing at the +** matching entry. +** +** This operation leaves the cursor in a state where it cannot be +** advanced in either direction. In other words, the Next and Prev +** opcodes do not work after this operation. +** +** See also: Found, NotExists, NoConflict, IfNoHope +*/ +/* Opcode: IfNoHope P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** Register P3 is the first of P4 registers that form an unpacked +** record. Cursor P1 is an index btree. P2 is a jump destination. +** In other words, the operands to this opcode are the same as the +** operands to OP_NotFound and OP_IdxGT. +** +** This opcode is an optimization attempt only. If this opcode always +** falls through, the correct answer is still obtained, but extra work +** is performed. +** +** A value of N in the seekHit flag of cursor P1 means that there exists +** a key P3:N that will match some record in the index. We want to know +** if it is possible for a record P3:P4 to match some record in the +** index. If it is not possible, we can skip some work. So if seekHit +** is less than P4, attempt to find out if a match is possible by running +** OP_NotFound. +** +** This opcode is used in IN clause processing for a multi-column key. +** If an IN clause is attached to an element of the key other than the +** left-most element, and if there are no matches on the most recent +** seek over the whole key, then it might be that one of the key element +** to the left is prohibiting a match, and hence there is "no hope" of +** any match regardless of how many IN clause elements are checked. +** In such a case, we abandon the IN clause search early, using this +** opcode. The opcode name comes from the fact that the +** jump is taken if there is "no hope" of achieving a match. +** +** See also: NotFound, SeekHit +*/ +/* Opcode: NoConflict P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** If P4==0 then register P3 holds a blob constructed by MakeRecord. If +** P4>0 then register P3 is the first of P4 registers that form an unpacked +** record. +** +** Cursor P1 is on an index btree. If the record identified by P3 and P4 +** contains any NULL value, jump immediately to P2. If all terms of the +** record are not-NULL then a check is done to determine if any row in the +** P1 index btree has a matching key prefix. If there are no matches, jump +** immediately to P2. If there is a match, fall through and leave the P1 +** cursor pointing to the matching row. +** +** This opcode is similar to OP_NotFound with the exceptions that the +** branch is always taken if any part of the search key input is NULL. +** +** This operation leaves the cursor in a state where it cannot be +** advanced in either direction. In other words, the Next and Prev +** opcodes do not work after this operation. +** +** See also: NotFound, Found, NotExists +*/ +case OP_IfNoHope: { /* jump, in3, ncycle */ + VdbeCursor *pC; + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + printf("seekHit is %d\n", pC->seekHit); + } +#endif + if( pC->seekHit>=pOp->p4.i ) break; + /* Fall through into OP_NotFound */ + /* no break */ deliberate_fall_through +} +case OP_NoConflict: /* jump, in3, ncycle */ +case OP_NotFound: /* jump, in3, ncycle */ +case OP_Found: { /* jump, in3, ncycle */ + int alreadyExists; + int ii; + VdbeCursor *pC; + UnpackedRecord *pIdxKey; + UnpackedRecord r; + +#ifdef SQLITE_TEST + if( pOp->opcode!=OP_NoConflict ) sqlite3_found_count++; +#endif + + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( pOp->p4type==P4_INT32 ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); +#ifdef SQLITE_DEBUG + pC->seekOp = pOp->opcode; +#endif + r.aMem = &aMem[pOp->p3]; + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->uc.pCursor!=0 ); + assert( pC->isTable==0 ); + r.nField = (u16)pOp->p4.i; + if( r.nField>0 ){ + /* Key values in an array of registers */ + r.pKeyInfo = pC->pKeyInfo; + r.default_rc = 0; +#ifdef SQLITE_DEBUG + (void)sqlite3FaultSim(50); /* For use by --counter in TH3 */ + for(ii=0; iip3+ii, &r.aMem[ii]); + } +#endif + rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, &r, &pC->seekResult); + }else{ + /* Composite key generated by OP_MakeRecord */ + assert( r.aMem->flags & MEM_Blob ); + assert( pOp->opcode!=OP_NoConflict ); + rc = ExpandBlob(r.aMem); + assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); + if( rc ) goto no_mem; + pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo); + if( pIdxKey==0 ) goto no_mem; + sqlite3VdbeRecordUnpack(r.aMem->n, r.aMem->z, pIdxKey); + pIdxKey->default_rc = 0; + rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, pIdxKey, &pC->seekResult); + sqlite3DbFreeNN(db, pIdxKey); + } + if( rc!=SQLITE_OK ){ + goto abort_due_to_error; + } + alreadyExists = (pC->seekResult==0); + pC->nullRow = 1-alreadyExists; + pC->deferredMoveto = 0; + pC->cacheStatus = CACHE_STALE; + if( pOp->opcode==OP_Found ){ + VdbeBranchTaken(alreadyExists!=0,2); + if( alreadyExists ) goto jump_to_p2; + }else{ + if( !alreadyExists ){ + VdbeBranchTaken(1,2); + goto jump_to_p2; + } + if( pOp->opcode==OP_NoConflict ){ + /* For the OP_NoConflict opcode, take the jump if any of the + ** input fields are NULL, since any key with a NULL will not + ** conflict */ + for(ii=0; iiopcode==OP_IfNoHope ){ + pC->seekHit = pOp->p4.i; + } + } + break; +} + +/* Opcode: SeekRowid P1 P2 P3 * * +** Synopsis: intkey=r[P3] +** +** P1 is the index of a cursor open on an SQL table btree (with integer +** keys). If register P3 does not contain an integer or if P1 does not +** contain a record with rowid P3 then jump immediately to P2. +** Or, if P2 is 0, raise an SQLITE_CORRUPT error. If P1 does contain +** a record with rowid P3 then +** leave the cursor pointing at that record and fall through to the next +** instruction. +** +** The OP_NotExists opcode performs the same operation, but with OP_NotExists +** the P3 register must be guaranteed to contain an integer value. With this +** opcode, register P3 might not contain an integer. +** +** The OP_NotFound opcode performs the same operation on index btrees +** (with arbitrary multi-value keys). +** +** This opcode leaves the cursor in a state where it cannot be advanced +** in either direction. In other words, the Next and Prev opcodes will +** not work following this opcode. +** +** See also: Found, NotFound, NoConflict, SeekRowid +*/ +/* Opcode: NotExists P1 P2 P3 * * +** Synopsis: intkey=r[P3] +** +** P1 is the index of a cursor open on an SQL table btree (with integer +** keys). P3 is an integer rowid. If P1 does not contain a record with +** rowid P3 then jump immediately to P2. Or, if P2 is 0, raise an +** SQLITE_CORRUPT error. If P1 does contain a record with rowid P3 then +** leave the cursor pointing at that record and fall through to the next +** instruction. +** +** The OP_SeekRowid opcode performs the same operation but also allows the +** P3 register to contain a non-integer value, in which case the jump is +** always taken. This opcode requires that P3 always contain an integer. +** +** The OP_NotFound opcode performs the same operation on index btrees +** (with arbitrary multi-value keys). +** +** This opcode leaves the cursor in a state where it cannot be advanced +** in either direction. In other words, the Next and Prev opcodes will +** not work following this opcode. +** +** See also: Found, NotFound, NoConflict, SeekRowid +*/ +case OP_SeekRowid: { /* jump0, in3, ncycle */ + VdbeCursor *pC; + BtCursor *pCrsr; + int res; + u64 iKey; + + pIn3 = &aMem[pOp->p3]; + testcase( pIn3->flags & MEM_Int ); + testcase( pIn3->flags & MEM_IntReal ); + testcase( pIn3->flags & MEM_Real ); + testcase( (pIn3->flags & (MEM_Str|MEM_Int))==MEM_Str ); + if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){ + /* If pIn3->u.i does not contain an integer, compute iKey as the + ** integer value of pIn3. Jump to P2 if pIn3 cannot be converted + ** into an integer without loss of information. Take care to avoid + ** changing the datatype of pIn3, however, as it is used by other + ** parts of the prepared statement. */ + Mem x = pIn3[0]; + applyAffinity(&x, SQLITE_AFF_NUMERIC, encoding); + if( (x.flags & MEM_Int)==0 ) goto jump_to_p2; + iKey = x.u.i; + goto notExistsWithKey; + } + /* Fall through into OP_NotExists */ + /* no break */ deliberate_fall_through +case OP_NotExists: /* jump, in3, ncycle */ + pIn3 = &aMem[pOp->p3]; + assert( (pIn3->flags & MEM_Int)!=0 || pOp->opcode==OP_SeekRowid ); + assert( pOp->p1>=0 && pOp->p1nCursor ); + iKey = pIn3->u.i; +notExistsWithKey: + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); +#ifdef SQLITE_DEBUG + if( pOp->opcode==OP_SeekRowid ) pC->seekOp = OP_SeekRowid; +#endif + assert( pC->isTable ); + assert( pC->eCurType==CURTYPE_BTREE ); + pCrsr = pC->uc.pCursor; + assert( pCrsr!=0 ); + res = 0; + rc = sqlite3BtreeTableMoveto(pCrsr, iKey, 0, &res); + assert( rc==SQLITE_OK || res==0 ); + pC->movetoTarget = iKey; /* Used by OP_Delete */ + pC->nullRow = 0; + pC->cacheStatus = CACHE_STALE; + pC->deferredMoveto = 0; + VdbeBranchTaken(res!=0,2); + pC->seekResult = res; + if( res!=0 ){ + assert( rc==SQLITE_OK ); + if( pOp->p2==0 ){ + rc = SQLITE_CORRUPT_BKPT; + }else{ + goto jump_to_p2; + } + } + if( rc ) goto abort_due_to_error; + break; +} + +/* Opcode: Sequence P1 P2 * * * +** Synopsis: r[P2]=cursor[P1].ctr++ +** +** Find the next available sequence number for cursor P1. +** Write the sequence number into register P2. +** The sequence number on the cursor is incremented after this +** instruction. +*/ +case OP_Sequence: { /* out2 */ + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( p->apCsr[pOp->p1]!=0 ); + assert( p->apCsr[pOp->p1]->eCurType!=CURTYPE_VTAB ); + pOut = out2Prerelease(p, pOp); + pOut->u.i = p->apCsr[pOp->p1]->seqCount++; + break; +} + + +/* Opcode: NewRowid P1 P2 P3 * * +** Synopsis: r[P2]=rowid +** +** Get a new integer record number (a.k.a "rowid") used as the key to a table. +** The record number is not previously used as a key in the database +** table that cursor P1 points to. The new record number is written +** written to register P2. +** +** If P3>0 then P3 is a register in the root frame of this VDBE that holds +** the largest previously generated record number. No new record numbers are +** allowed to be less than this value. When this value reaches its maximum, +** an SQLITE_FULL error is generated. The P3 register is updated with the ' +** generated record number. This P3 mechanism is used to help implement the +** AUTOINCREMENT feature. +*/ +case OP_NewRowid: { /* out2 */ + i64 v; /* The new rowid */ + VdbeCursor *pC; /* Cursor of table to get the new rowid */ + int res; /* Result of an sqlite3BtreeLast() */ + int cnt; /* Counter to limit the number of searches */ +#ifndef SQLITE_OMIT_AUTOINCREMENT + Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ + VdbeFrame *pFrame; /* Root frame of VDBE */ +#endif + + v = 0; + res = 0; + pOut = out2Prerelease(p, pOp); + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->isTable ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->uc.pCursor!=0 ); + { + /* The next rowid or record number (different terms for the same + ** thing) is obtained in a two-step algorithm. + ** + ** First we attempt to find the largest existing rowid and add one + ** to that. But if the largest existing rowid is already the maximum + ** positive integer, we have to fall through to the second + ** probabilistic algorithm + ** + ** The second algorithm is to select a rowid at random and see if + ** it already exists in the table. If it does not exist, we have + ** succeeded. If the random rowid does exist, we select a new one + ** and try again, up to 100 times. + */ + assert( pC->isTable ); + +#ifdef SQLITE_32BIT_ROWID +# define MAX_ROWID 0x7fffffff +#else + /* Some compilers complain about constants of the form 0x7fffffffffffffff. + ** Others complain about 0x7ffffffffffffffffLL. The following macro seems + ** to provide the constant while making all compilers happy. + */ +# define MAX_ROWID (i64)( (((u64)0x7fffffff)<<32) | (u64)0xffffffff ) +#endif + + if( !pC->useRandomRowid ){ + rc = sqlite3BtreeLast(pC->uc.pCursor, &res); + if( rc!=SQLITE_OK ){ + goto abort_due_to_error; + } + if( res ){ + v = 1; /* IMP: R-61914-48074 */ + }else{ + assert( sqlite3BtreeCursorIsValid(pC->uc.pCursor) ); + v = sqlite3BtreeIntegerKey(pC->uc.pCursor); + if( v>=MAX_ROWID ){ + pC->useRandomRowid = 1; + }else{ + v++; /* IMP: R-29538-34987 */ + } + } + } + +#ifndef SQLITE_OMIT_AUTOINCREMENT + if( pOp->p3 ){ + /* Assert that P3 is a valid memory cell. */ + assert( pOp->p3>0 ); + if( p->pFrame ){ + for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); + /* Assert that P3 is a valid memory cell. */ + assert( pOp->p3<=pFrame->nMem ); + pMem = &pFrame->aMem[pOp->p3]; + }else{ + /* Assert that P3 is a valid memory cell. */ + assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); + pMem = &aMem[pOp->p3]; + memAboutToChange(p, pMem); + } + assert( memIsValid(pMem) ); + + REGISTER_TRACE(pOp->p3, pMem); + sqlite3VdbeMemIntegerify(pMem); + assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ + if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){ + rc = SQLITE_FULL; /* IMP: R-17817-00630 */ + goto abort_due_to_error; + } + if( vu.i+1 ){ + v = pMem->u.i + 1; + } + pMem->u.i = v; + } +#endif + if( pC->useRandomRowid ){ + /* IMPLEMENTATION-OF: R-07677-41881 If the largest ROWID is equal to the + ** largest possible integer (9223372036854775807) then the database + ** engine starts picking positive candidate ROWIDs at random until + ** it finds one that is not previously used. */ + assert( pOp->p3==0 ); /* We cannot be in random rowid mode if this is + ** an AUTOINCREMENT table. */ + cnt = 0; + do{ + sqlite3_randomness(sizeof(v), &v); + v &= (MAX_ROWID>>1); v++; /* Ensure that v is greater than zero */ + }while( ((rc = sqlite3BtreeTableMoveto(pC->uc.pCursor, (u64)v, + 0, &res))==SQLITE_OK) + && (res==0) + && (++cnt<100)); + if( rc ) goto abort_due_to_error; + if( res==0 ){ + rc = SQLITE_FULL; /* IMP: R-38219-53002 */ + goto abort_due_to_error; + } + assert( v>0 ); /* EV: R-40812-03570 */ + } + pC->deferredMoveto = 0; + pC->cacheStatus = CACHE_STALE; + } + pOut->u.i = v; + break; +} + +/* Opcode: Insert P1 P2 P3 P4 P5 +** Synopsis: intkey=r[P3] data=r[P2] +** +** Write an entry into the table of cursor P1. A new entry is +** created if it doesn't already exist or the data for an existing +** entry is overwritten. The data is the value MEM_Blob stored in register +** number P2. The key is stored in register P3. The key must +** be a MEM_Int. +** +** If the OPFLAG_NCHANGE flag of P5 is set, then the row change count is +** incremented (otherwise not). If the OPFLAG_LASTROWID flag of P5 is set, +** then rowid is stored for subsequent return by the +** sqlite3_last_insert_rowid() function (otherwise it is unmodified). +** +** If the OPFLAG_USESEEKRESULT flag of P5 is set, the implementation might +** run faster by avoiding an unnecessary seek on cursor P1. However, +** the OPFLAG_USESEEKRESULT flag must only be set if there have been no prior +** seeks on the cursor or if the most recent seek used a key equal to P3. +** +** If the OPFLAG_ISUPDATE flag is set, then this opcode is part of an +** UPDATE operation. Otherwise (if the flag is clear) then this opcode +** is part of an INSERT operation. The difference is only important to +** the update hook. +** +** Parameter P4 may point to a Table structure, or may be NULL. If it is +** not NULL, then the update-hook (sqlite3.xUpdateCallback) is invoked +** following a successful insert. +** +** (WARNING/TODO: If P1 is a pseudo-cursor and P2 is dynamically +** allocated, then ownership of P2 is transferred to the pseudo-cursor +** and register P2 becomes ephemeral. If the cursor is changed, the +** value of register P2 will then change. Make sure this does not +** cause any problems.) +** +** This instruction only works on tables. The equivalent instruction +** for indices is OP_IdxInsert. +*/ +case OP_Insert: { + Mem *pData; /* MEM cell holding data for the record to be inserted */ + Mem *pKey; /* MEM cell holding key for the record */ + VdbeCursor *pC; /* Cursor to table into which insert is written */ + int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ + const char *zDb; /* database name - used by the update hook */ + Table *pTab; /* Table structure - used by update and pre-update hooks */ + BtreePayload x; /* Payload to be inserted */ + + pData = &aMem[pOp->p2]; + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( memIsValid(pData) ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->deferredMoveto==0 ); + assert( pC->uc.pCursor!=0 ); + assert( (pOp->p5 & OPFLAG_ISNOOP) || pC->isTable ); + assert( pOp->p4type==P4_TABLE || pOp->p4type>=P4_STATIC ); + REGISTER_TRACE(pOp->p2, pData); + sqlite3VdbeIncrWriteCounter(p, pC); + + pKey = &aMem[pOp->p3]; + assert( pKey->flags & MEM_Int ); + assert( memIsValid(pKey) ); + REGISTER_TRACE(pOp->p3, pKey); + x.nKey = pKey->u.i; + + if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){ + assert( pC->iDb>=0 ); + zDb = db->aDb[pC->iDb].zDbSName; + pTab = pOp->p4.pTab; + assert( (pOp->p5 & OPFLAG_ISNOOP) || HasRowid(pTab) ); + }else{ + pTab = 0; + zDb = 0; + } + +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + /* Invoke the pre-update hook, if any */ + if( pTab ){ + if( db->xPreUpdateCallback && !(pOp->p5 & OPFLAG_ISUPDATE) ){ + sqlite3VdbePreUpdateHook(p,pC,SQLITE_INSERT,zDb,pTab,x.nKey,pOp->p2,-1); + } + if( db->xUpdateCallback==0 || pTab->aCol==0 ){ + /* Prevent post-update hook from running in cases when it should not */ + pTab = 0; + } + } + if( pOp->p5 & OPFLAG_ISNOOP ) break; +#endif + + assert( (pOp->p5 & OPFLAG_LASTROWID)==0 || (pOp->p5 & OPFLAG_NCHANGE)!=0 ); + if( pOp->p5 & OPFLAG_NCHANGE ){ + p->nChange++; + if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey; + } + assert( (pData->flags & (MEM_Blob|MEM_Str))!=0 || pData->n==0 ); + x.pData = pData->z; + x.nData = pData->n; + seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0); + if( pData->flags & MEM_Zero ){ + x.nZero = pData->u.nZero; + }else{ + x.nZero = 0; + } + x.pKey = 0; + assert( BTREE_PREFORMAT==OPFLAG_PREFORMAT ); + rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, + (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION|OPFLAG_PREFORMAT)), + seekResult + ); + pC->deferredMoveto = 0; + pC->cacheStatus = CACHE_STALE; + colCacheCtr++; + + /* Invoke the update-hook if required. */ + if( rc ) goto abort_due_to_error; + if( pTab ){ + assert( db->xUpdateCallback!=0 ); + assert( pTab->aCol!=0 ); + db->xUpdateCallback(db->pUpdateArg, + (pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT, + zDb, pTab->zName, x.nKey); + } + break; +} + +/* Opcode: RowCell P1 P2 P3 * * +** +** P1 and P2 are both open cursors. Both must be opened on the same type +** of table - intkey or index. This opcode is used as part of copying +** the current row from P2 into P1. If the cursors are opened on intkey +** tables, register P3 contains the rowid to use with the new record in +** P1. If they are opened on index tables, P3 is not used. +** +** This opcode must be followed by either an Insert or InsertIdx opcode +** with the OPFLAG_PREFORMAT flag set to complete the insert operation. +*/ +case OP_RowCell: { + VdbeCursor *pDest; /* Cursor to write to */ + VdbeCursor *pSrc; /* Cursor to read from */ + i64 iKey; /* Rowid value to insert with */ + assert( pOp[1].opcode==OP_Insert || pOp[1].opcode==OP_IdxInsert ); + assert( pOp[1].opcode==OP_Insert || pOp->p3==0 ); + assert( pOp[1].opcode==OP_IdxInsert || pOp->p3>0 ); + assert( pOp[1].p5 & OPFLAG_PREFORMAT ); + pDest = p->apCsr[pOp->p1]; + pSrc = p->apCsr[pOp->p2]; + iKey = pOp->p3 ? aMem[pOp->p3].u.i : 0; + rc = sqlite3BtreeTransferRow(pDest->uc.pCursor, pSrc->uc.pCursor, iKey); + if( rc!=SQLITE_OK ) goto abort_due_to_error; + break; +}; + +/* Opcode: Delete P1 P2 P3 P4 P5 +** +** Delete the record at which the P1 cursor is currently pointing. +** +** If the OPFLAG_SAVEPOSITION bit of the P5 parameter is set, then +** the cursor will be left pointing at either the next or the previous +** record in the table. If it is left pointing at the next record, then +** the next Next instruction will be a no-op. As a result, in this case +** it is ok to delete a record from within a Next loop. If +** OPFLAG_SAVEPOSITION bit of P5 is clear, then the cursor will be +** left in an undefined state. +** +** If the OPFLAG_AUXDELETE bit is set on P5, that indicates that this +** delete is one of several associated with deleting a table row and +** all its associated index entries. Exactly one of those deletes is +** the "primary" delete. The others are all on OPFLAG_FORDELETE +** cursors or else are marked with the AUXDELETE flag. +** +** If the OPFLAG_NCHANGE (0x01) flag of P2 (NB: P2 not P5) is set, then +** the row change count is incremented (otherwise not). +** +** If the OPFLAG_ISNOOP (0x40) flag of P2 (not P5!) is set, then the +** pre-update-hook for deletes is run, but the btree is otherwise unchanged. +** This happens when the OP_Delete is to be shortly followed by an OP_Insert +** with the same key, causing the btree entry to be overwritten. +** +** P1 must not be pseudo-table. It has to be a real table with +** multiple rows. +** +** If P4 is not NULL then it points to a Table object. In this case either +** the update or pre-update hook, or both, may be invoked. The P1 cursor must +** have been positioned using OP_NotFound prior to invoking this opcode in +** this case. Specifically, if one is configured, the pre-update hook is +** invoked if P4 is not NULL. The update-hook is invoked if one is configured, +** P4 is not NULL, and the OPFLAG_NCHANGE flag is set in P2. +** +** If the OPFLAG_ISUPDATE flag is set in P2, then P3 contains the address +** of the memory cell that contains the value that the rowid of the row will +** be set to by the update. +*/ +case OP_Delete: { + VdbeCursor *pC; + const char *zDb; + Table *pTab; + int opflags; + + opflags = pOp->p2; + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->uc.pCursor!=0 ); + assert( pC->deferredMoveto==0 ); + sqlite3VdbeIncrWriteCounter(p, pC); + +#ifdef SQLITE_DEBUG + if( pOp->p4type==P4_TABLE + && HasRowid(pOp->p4.pTab) + && pOp->p5==0 + && sqlite3BtreeCursorIsValidNN(pC->uc.pCursor) + ){ + /* If p5 is zero, the seek operation that positioned the cursor prior to + ** OP_Delete will have also set the pC->movetoTarget field to the rowid of + ** the row that is being deleted */ + i64 iKey = sqlite3BtreeIntegerKey(pC->uc.pCursor); + assert( CORRUPT_DB || pC->movetoTarget==iKey ); + } +#endif + + /* If the update-hook or pre-update-hook will be invoked, set zDb to + ** the name of the db to pass as to it. Also set local pTab to a copy + ** of p4.pTab. Finally, if p5 is true, indicating that this cursor was + ** last moved with OP_Next or OP_Prev, not Seek or NotFound, set + ** VdbeCursor.movetoTarget to the current rowid. */ + if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){ + assert( pC->iDb>=0 ); + assert( pOp->p4.pTab!=0 ); + zDb = db->aDb[pC->iDb].zDbSName; + pTab = pOp->p4.pTab; + if( (pOp->p5 & OPFLAG_SAVEPOSITION)!=0 && pC->isTable ){ + pC->movetoTarget = sqlite3BtreeIntegerKey(pC->uc.pCursor); + } + }else{ + zDb = 0; + pTab = 0; + } + +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + /* Invoke the pre-update-hook if required. */ + assert( db->xPreUpdateCallback==0 || pTab==pOp->p4.pTab ); + if( db->xPreUpdateCallback && pTab ){ + assert( !(opflags & OPFLAG_ISUPDATE) + || HasRowid(pTab)==0 + || (aMem[pOp->p3].flags & MEM_Int) + ); + sqlite3VdbePreUpdateHook(p, pC, + (opflags & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_DELETE, + zDb, pTab, pC->movetoTarget, + pOp->p3, -1 + ); + } + if( opflags & OPFLAG_ISNOOP ) break; +#endif + + /* Only flags that can be set are SAVEPOISTION and AUXDELETE */ + assert( (pOp->p5 & ~(OPFLAG_SAVEPOSITION|OPFLAG_AUXDELETE))==0 ); + assert( OPFLAG_SAVEPOSITION==BTREE_SAVEPOSITION ); + assert( OPFLAG_AUXDELETE==BTREE_AUXDELETE ); + +#ifdef SQLITE_DEBUG + if( p->pFrame==0 ){ + if( pC->isEphemeral==0 + && (pOp->p5 & OPFLAG_AUXDELETE)==0 + && (pC->wrFlag & OPFLAG_FORDELETE)==0 + ){ + nExtraDelete++; + } + if( pOp->p2 & OPFLAG_NCHANGE ){ + nExtraDelete--; + } + } +#endif + + rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5); + pC->cacheStatus = CACHE_STALE; + colCacheCtr++; + pC->seekResult = 0; + if( rc ) goto abort_due_to_error; + + /* Invoke the update-hook if required. */ + if( opflags & OPFLAG_NCHANGE ){ + p->nChange++; + if( db->xUpdateCallback && ALWAYS(pTab!=0) && HasRowid(pTab) ){ + db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, pTab->zName, + pC->movetoTarget); + assert( pC->iDb>=0 ); + } + } + + break; +} +/* Opcode: ResetCount * * * * * +** +** The value of the change counter is copied to the database handle +** change counter (returned by subsequent calls to sqlite3_changes()). +** Then the VMs internal change counter resets to 0. +** This is used by trigger programs. +*/ +case OP_ResetCount: { + sqlite3VdbeSetChanges(db, p->nChange); + p->nChange = 0; + break; +} + +/* Opcode: SorterCompare P1 P2 P3 P4 +** Synopsis: if key(P1)!=trim(r[P3],P4) goto P2 +** +** P1 is a sorter cursor. This instruction compares a prefix of the +** record blob in register P3 against a prefix of the entry that +** the sorter cursor currently points to. Only the first P4 fields +** of r[P3] and the sorter record are compared. +** +** If either P3 or the sorter contains a NULL in one of their significant +** fields (not counting the P4 fields at the end which are ignored) then +** the comparison is assumed to be equal. +** +** Fall through to next instruction if the two records compare equal to +** each other. Jump to P2 if they are different. +*/ +case OP_SorterCompare: { + VdbeCursor *pC; + int res; + int nKeyCol; + + pC = p->apCsr[pOp->p1]; + assert( isSorter(pC) ); + assert( pOp->p4type==P4_INT32 ); + pIn3 = &aMem[pOp->p3]; + nKeyCol = pOp->p4.i; + res = 0; + rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res); + VdbeBranchTaken(res!=0,2); + if( rc ) goto abort_due_to_error; + if( res ) goto jump_to_p2; + break; +}; + +/* Opcode: SorterData P1 P2 P3 * * +** Synopsis: r[P2]=data +** +** Write into register P2 the current sorter data for sorter cursor P1. +** Then clear the column header cache on cursor P3. +** +** This opcode is normally used to move a record out of the sorter and into +** a register that is the source for a pseudo-table cursor created using +** OpenPseudo. That pseudo-table cursor is the one that is identified by +** parameter P3. Clearing the P3 column cache as part of this opcode saves +** us from having to issue a separate NullRow instruction to clear that cache. +*/ +case OP_SorterData: { /* ncycle */ + VdbeCursor *pC; + + pOut = &aMem[pOp->p2]; + pC = p->apCsr[pOp->p1]; + assert( isSorter(pC) ); + rc = sqlite3VdbeSorterRowkey(pC, pOut); + assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) ); + assert( pOp->p1>=0 && pOp->p1nCursor ); + if( rc ) goto abort_due_to_error; + p->apCsr[pOp->p3]->cacheStatus = CACHE_STALE; + break; +} + +/* Opcode: RowData P1 P2 P3 * * +** Synopsis: r[P2]=data +** +** Write into register P2 the complete row content for the row at +** which cursor P1 is currently pointing. +** There is no interpretation of the data. +** It is just copied onto the P2 register exactly as +** it is found in the database file. +** +** If cursor P1 is an index, then the content is the key of the row. +** If cursor P2 is a table, then the content extracted is the data. +** +** If the P1 cursor must be pointing to a valid row (not a NULL row) +** of a real table, not a pseudo-table. +** +** If P3!=0 then this opcode is allowed to make an ephemeral pointer +** into the database page. That means that the content of the output +** register will be invalidated as soon as the cursor moves - including +** moves caused by other cursors that "save" the current cursors +** position in order that they can write to the same table. If P3==0 +** then a copy of the data is made into memory. P3!=0 is faster, but +** P3==0 is safer. +** +** If P3!=0 then the content of the P2 register is unsuitable for use +** in OP_Result and any OP_Result will invalidate the P2 register content. +** The P2 register content is invalidated by opcodes like OP_Function or +** by any use of another cursor pointing to the same table. +*/ +case OP_RowData: { + VdbeCursor *pC; + BtCursor *pCrsr; + u32 n; + + pOut = out2Prerelease(p, pOp); + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( isSorter(pC)==0 ); + assert( pC->nullRow==0 ); + assert( pC->uc.pCursor!=0 ); + pCrsr = pC->uc.pCursor; + + /* The OP_RowData opcodes always follow OP_NotExists or + ** OP_SeekRowid or OP_Rewind/Op_Next with no intervening instructions + ** that might invalidate the cursor. + ** If this were not the case, one of the following assert()s + ** would fail. Should this ever change (because of changes in the code + ** generator) then the fix would be to insert a call to + ** sqlite3VdbeCursorMoveto(). + */ + assert( pC->deferredMoveto==0 ); + assert( sqlite3BtreeCursorIsValid(pCrsr) ); + + n = sqlite3BtreePayloadSize(pCrsr); + if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ + goto too_big; + } + testcase( n==0 ); + rc = sqlite3VdbeMemFromBtreeZeroOffset(pCrsr, n, pOut); + if( rc ) goto abort_due_to_error; + if( !pOp->p3 ) Deephemeralize(pOut); + UPDATE_MAX_BLOBSIZE(pOut); + REGISTER_TRACE(pOp->p2, pOut); + break; +} + +/* Opcode: Rowid P1 P2 * * * +** Synopsis: r[P2]=PX rowid of P1 +** +** Store in register P2 an integer which is the key of the table entry that +** P1 is currently point to. +** +** P1 can be either an ordinary table or a virtual table. There used to +** be a separate OP_VRowid opcode for use with virtual tables, but this +** one opcode now works for both table types. +*/ +case OP_Rowid: { /* out2, ncycle */ + VdbeCursor *pC; + i64 v; + sqlite3_vtab *pVtab; + const sqlite3_module *pModule; + + pOut = out2Prerelease(p, pOp); + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow ); + if( pC->nullRow ){ + pOut->flags = MEM_Null; + break; + }else if( pC->deferredMoveto ){ + v = pC->movetoTarget; +#ifndef SQLITE_OMIT_VIRTUALTABLE + }else if( pC->eCurType==CURTYPE_VTAB ){ + assert( pC->uc.pVCur!=0 ); + pVtab = pC->uc.pVCur->pVtab; + pModule = pVtab->pModule; + assert( pModule->xRowid ); + rc = pModule->xRowid(pC->uc.pVCur, &v); + sqlite3VtabImportErrmsg(p, pVtab); + if( rc ) goto abort_due_to_error; +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + }else{ + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->uc.pCursor!=0 ); + rc = sqlite3VdbeCursorRestore(pC); + if( rc ) goto abort_due_to_error; + if( pC->nullRow ){ + pOut->flags = MEM_Null; + break; + } + v = sqlite3BtreeIntegerKey(pC->uc.pCursor); + } + pOut->u.i = v; + break; +} + +/* Opcode: NullRow P1 * * * * +** +** Move the cursor P1 to a null row. Any OP_Column operations +** that occur while the cursor is on the null row will always +** write a NULL. +** +** If cursor P1 is not previously opened, open it now to a special +** pseudo-cursor that always returns NULL for every column. +*/ +case OP_NullRow: { + VdbeCursor *pC; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + if( pC==0 ){ + /* If the cursor is not already open, create a special kind of + ** pseudo-cursor that always gives null rows. */ + pC = allocateCursor(p, pOp->p1, 1, CURTYPE_PSEUDO); + if( pC==0 ) goto no_mem; + pC->seekResult = 0; + pC->isTable = 1; + pC->noReuse = 1; + pC->uc.pCursor = sqlite3BtreeFakeValidCursor(); + } + pC->nullRow = 1; + pC->cacheStatus = CACHE_STALE; + if( pC->eCurType==CURTYPE_BTREE ){ + assert( pC->uc.pCursor!=0 ); + sqlite3BtreeClearCursor(pC->uc.pCursor); + } +#ifdef SQLITE_DEBUG + if( pC->seekOp==0 ) pC->seekOp = OP_NullRow; +#endif + break; +} + +/* Opcode: SeekEnd P1 * * * * +** +** Position cursor P1 at the end of the btree for the purpose of +** appending a new entry onto the btree. +** +** It is assumed that the cursor is used only for appending and so +** if the cursor is valid, then the cursor must already be pointing +** at the end of the btree and so no changes are made to +** the cursor. +*/ +/* Opcode: Last P1 P2 * * * +** +** The next use of the Rowid or Column or Prev instruction for P1 +** will refer to the last entry in the database table or index. +** If the table or index is empty and P2>0, then jump immediately to P2. +** If P2 is 0 or if the table or index is not empty, fall through +** to the following instruction. +** +** This opcode leaves the cursor configured to move in reverse order, +** from the end toward the beginning. In other words, the cursor is +** configured to use Prev, not Next. +*/ +case OP_SeekEnd: /* ncycle */ +case OP_Last: { /* jump0, ncycle */ + VdbeCursor *pC; + BtCursor *pCrsr; + int res; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + pCrsr = pC->uc.pCursor; + res = 0; + assert( pCrsr!=0 ); +#ifdef SQLITE_DEBUG + pC->seekOp = pOp->opcode; +#endif + if( pOp->opcode==OP_SeekEnd ){ + assert( pOp->p2==0 ); + pC->seekResult = -1; + if( sqlite3BtreeCursorIsValidNN(pCrsr) ){ + break; + } + } + rc = sqlite3BtreeLast(pCrsr, &res); + pC->nullRow = (u8)res; + pC->deferredMoveto = 0; + pC->cacheStatus = CACHE_STALE; + if( rc ) goto abort_due_to_error; + if( pOp->p2>0 ){ + VdbeBranchTaken(res!=0,2); + if( res ) goto jump_to_p2; + } + break; +} + +/* Opcode: IfSizeBetween P1 P2 P3 P4 * +** +** Let N be the approximate number of rows in the table or index +** with cursor P1 and let X be 10*log2(N) if N is positive or -1 +** if N is zero. +** +** Jump to P2 if X is in between P3 and P4, inclusive. +*/ +case OP_IfSizeBetween: { /* jump */ + VdbeCursor *pC; + BtCursor *pCrsr; + int res; + i64 sz; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( pOp->p4type==P4_INT32 ); + assert( pOp->p3>=-1 && pOp->p3<=640*2 ); + assert( pOp->p4.i>=-1 && pOp->p4.i<=640*2 ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + pCrsr = pC->uc.pCursor; + assert( pCrsr ); + rc = sqlite3BtreeFirst(pCrsr, &res); + if( rc ) goto abort_due_to_error; + if( res!=0 ){ + sz = -1; /* -Infinity encoding */ + }else{ + sz = sqlite3BtreeRowCountEst(pCrsr); + assert( sz>0 ); + sz = sqlite3LogEst((u64)sz); + } + res = sz>=pOp->p3 && sz<=pOp->p4.i; + VdbeBranchTaken(res!=0,2); + if( res ) goto jump_to_p2; + break; +} + + +/* Opcode: SorterSort P1 P2 * * * +** +** After all records have been inserted into the Sorter object +** identified by P1, invoke this opcode to actually do the sorting. +** Jump to P2 if there are no records to be sorted. +** +** This opcode is an alias for OP_Sort and OP_Rewind that is used +** for Sorter objects. +*/ +/* Opcode: Sort P1 P2 * * * +** +** This opcode does exactly the same thing as OP_Rewind except that +** it increments an undocumented global variable used for testing. +** +** Sorting is accomplished by writing records into a sorting index, +** then rewinding that index and playing it back from beginning to +** end. We use the OP_Sort opcode instead of OP_Rewind to do the +** rewinding so that the global variable will be incremented and +** regression tests can determine whether or not the optimizer is +** correctly optimizing out sorts. +*/ +case OP_SorterSort: /* jump ncycle */ +case OP_Sort: { /* jump ncycle */ +#ifdef SQLITE_TEST + sqlite3_sort_count++; + sqlite3_search_count--; +#endif + p->aCounter[SQLITE_STMTSTATUS_SORT]++; + /* Fall through into OP_Rewind */ + /* no break */ deliberate_fall_through +} +/* Opcode: Rewind P1 P2 * * * +** +** The next use of the Rowid or Column or Next instruction for P1 +** will refer to the first entry in the database table or index. +** If the table or index is empty, jump immediately to P2. +** If the table or index is not empty, fall through to the following +** instruction. +** +** If P2 is zero, that is an assertion that the P1 table is never +** empty and hence the jump will never be taken. +** +** This opcode leaves the cursor configured to move in forward order, +** from the beginning toward the end. In other words, the cursor is +** configured to use Next, not Prev. +*/ +case OP_Rewind: { /* jump0, ncycle */ + VdbeCursor *pC; + BtCursor *pCrsr; + int res; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( pOp->p5==0 ); + assert( pOp->p2>=0 && pOp->p2nOp ); + + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) ); + res = 1; +#ifdef SQLITE_DEBUG + pC->seekOp = OP_Rewind; +#endif + if( isSorter(pC) ){ + rc = sqlite3VdbeSorterRewind(pC, &res); + }else{ + assert( pC->eCurType==CURTYPE_BTREE ); + pCrsr = pC->uc.pCursor; + assert( pCrsr ); + rc = sqlite3BtreeFirst(pCrsr, &res); + pC->deferredMoveto = 0; + pC->cacheStatus = CACHE_STALE; + } + if( rc ) goto abort_due_to_error; + pC->nullRow = (u8)res; + if( pOp->p2>0 ){ + VdbeBranchTaken(res!=0,2); + if( res ) goto jump_to_p2; + } + break; +} + +/* Opcode: IfEmpty P1 P2 * * * +** Synopsis: if( empty(P1) ) goto P2 +** +** Check to see if the b-tree table that cursor P1 references is empty +** and jump to P2 if it is. +*/ +case OP_IfEmpty: { /* jump */ + VdbeCursor *pC; + BtCursor *pCrsr; + int res; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( pOp->p2>=0 && pOp->p2nOp ); + + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + pCrsr = pC->uc.pCursor; + assert( pCrsr ); + rc = sqlite3BtreeIsEmpty(pCrsr, &res); + if( rc ) goto abort_due_to_error; + VdbeBranchTaken(res!=0,2); + if( res ) goto jump_to_p2; + break; +} + +/* Opcode: Next P1 P2 P3 * P5 +** +** Advance cursor P1 so that it points to the next key/data pair in its +** table or index. If there are no more key/value pairs then fall through +** to the following instruction. But if the cursor advance was successful, +** jump immediately to P2. +** +** The Next opcode is only valid following an SeekGT, SeekGE, or +** OP_Rewind opcode used to position the cursor. Next is not allowed +** to follow SeekLT, SeekLE, or OP_Last. +** +** The P1 cursor must be for a real table, not a pseudo-table. P1 must have +** been opened prior to this opcode or the program will segfault. +** +** The P3 value is a hint to the btree implementation. If P3==1, that +** means P1 is an SQL index and that this instruction could have been +** omitted if that index had been unique. P3 is usually 0. P3 is +** always either 0 or 1. +** +** If P5 is positive and the jump is taken, then event counter +** number P5-1 in the prepared statement is incremented. +** +** See also: Prev +*/ +/* Opcode: Prev P1 P2 P3 * P5 +** +** Back up cursor P1 so that it points to the previous key/data pair in its +** table or index. If there is no previous key/value pairs then fall through +** to the following instruction. But if the cursor backup was successful, +** jump immediately to P2. +** +** +** The Prev opcode is only valid following an SeekLT, SeekLE, or +** OP_Last opcode used to position the cursor. Prev is not allowed +** to follow SeekGT, SeekGE, or OP_Rewind. +** +** The P1 cursor must be for a real table, not a pseudo-table. If P1 is +** not open then the behavior is undefined. +** +** The P3 value is a hint to the btree implementation. If P3==1, that +** means P1 is an SQL index and that this instruction could have been +** omitted if that index had been unique. P3 is usually 0. P3 is +** always either 0 or 1. +** +** If P5 is positive and the jump is taken, then event counter +** number P5-1 in the prepared statement is incremented. +*/ +/* Opcode: SorterNext P1 P2 * * P5 +** +** This opcode works just like OP_Next except that P1 must be a +** sorter object for which the OP_SorterSort opcode has been +** invoked. This opcode advances the cursor to the next sorted +** record, or jumps to P2 if there are no more sorted records. +*/ +case OP_SorterNext: { /* jump */ + VdbeCursor *pC; + + pC = p->apCsr[pOp->p1]; + assert( isSorter(pC) ); + rc = sqlite3VdbeSorterNext(db, pC); + goto next_tail; + +case OP_Prev: /* jump, ncycle */ + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( pOp->p5==0 + || pOp->p5==SQLITE_STMTSTATUS_FULLSCAN_STEP + || pOp->p5==SQLITE_STMTSTATUS_AUTOINDEX); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->deferredMoveto==0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE + || pC->seekOp==OP_Last || pC->seekOp==OP_IfNoHope + || pC->seekOp==OP_NullRow); + rc = sqlite3BtreePrevious(pC->uc.pCursor, pOp->p3); + goto next_tail; + +case OP_Next: /* jump, ncycle */ + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( pOp->p5==0 + || pOp->p5==SQLITE_STMTSTATUS_FULLSCAN_STEP + || pOp->p5==SQLITE_STMTSTATUS_AUTOINDEX); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->deferredMoveto==0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE + || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found + || pC->seekOp==OP_NullRow|| pC->seekOp==OP_SeekRowid + || pC->seekOp==OP_IfNoHope); + rc = sqlite3BtreeNext(pC->uc.pCursor, pOp->p3); + +next_tail: + pC->cacheStatus = CACHE_STALE; + VdbeBranchTaken(rc==SQLITE_OK,2); + if( rc==SQLITE_OK ){ + pC->nullRow = 0; + p->aCounter[pOp->p5]++; +#ifdef SQLITE_TEST + sqlite3_search_count++; +#endif + goto jump_to_p2_and_check_for_interrupt; + } + if( rc!=SQLITE_DONE ) goto abort_due_to_error; + rc = SQLITE_OK; + pC->nullRow = 1; + goto check_for_interrupt; +} + +/* Opcode: IdxInsert P1 P2 P3 P4 P5 +** Synopsis: key=r[P2] +** +** Register P2 holds an SQL index key made using the +** MakeRecord instructions. This opcode writes that key +** into the index P1. Data for the entry is nil. +** +** If P4 is not zero, then it is the number of values in the unpacked +** key of reg(P2). In that case, P3 is the index of the first register +** for the unpacked key. The availability of the unpacked key can sometimes +** be an optimization. +** +** If P5 has the OPFLAG_APPEND bit set, that is a hint to the b-tree layer +** that this insert is likely to be an append. +** +** If P5 has the OPFLAG_NCHANGE bit set, then the change counter is +** incremented by this instruction. If the OPFLAG_NCHANGE bit is clear, +** then the change counter is unchanged. +** +** If the OPFLAG_USESEEKRESULT flag of P5 is set, the implementation might +** run faster by avoiding an unnecessary seek on cursor P1. However, +** the OPFLAG_USESEEKRESULT flag must only be set if there have been no prior +** seeks on the cursor or if the most recent seek used a key equivalent +** to P2. +** +** This instruction only works for indices. The equivalent instruction +** for tables is OP_Insert. +*/ +case OP_IdxInsert: { /* in2 */ + VdbeCursor *pC; + BtreePayload x; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + sqlite3VdbeIncrWriteCounter(p, pC); + assert( pC!=0 ); + assert( !isSorter(pC) ); + pIn2 = &aMem[pOp->p2]; + assert( (pIn2->flags & MEM_Blob) || (pOp->p5 & OPFLAG_PREFORMAT) ); + if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->isTable==0 ); + rc = ExpandBlob(pIn2); + if( rc ) goto abort_due_to_error; + x.nKey = pIn2->n; + x.pKey = pIn2->z; + x.aMem = aMem + pOp->p3; + x.nMem = (u16)pOp->p4.i; + rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, + (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION|OPFLAG_PREFORMAT)), + ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0) + ); + assert( pC->deferredMoveto==0 ); + pC->cacheStatus = CACHE_STALE; + if( rc) goto abort_due_to_error; + break; +} + +/* Opcode: SorterInsert P1 P2 * * * +** Synopsis: key=r[P2] +** +** Register P2 holds an SQL index key made using the +** MakeRecord instructions. This opcode writes that key +** into the sorter P1. Data for the entry is nil. +*/ +case OP_SorterInsert: { /* in2 */ + VdbeCursor *pC; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + sqlite3VdbeIncrWriteCounter(p, pC); + assert( pC!=0 ); + assert( isSorter(pC) ); + pIn2 = &aMem[pOp->p2]; + assert( pIn2->flags & MEM_Blob ); + assert( pC->isTable==0 ); + rc = ExpandBlob(pIn2); + if( rc ) goto abort_due_to_error; + rc = sqlite3VdbeSorterWrite(pC, pIn2); + if( rc) goto abort_due_to_error; + break; +} + +/* Opcode: IdxDelete P1 P2 P3 P4 * +** Synopsis: key=r[P2@P3] +** +** The content of P3 registers starting at register P2 form +** an unpacked index key. This opcode removes that entry from the +** index opened by cursor P1. +** +** P4 is a pointer to an Index structure. +** +** Raise an SQLITE_CORRUPT_INDEX error if no matching index entry is found +** and not in writable_schema mode. +*/ +case OP_IdxDelete: { + VdbeCursor *pC; + BtCursor *pCrsr; + int res; + UnpackedRecord r; + + assert( pOp->p3>0 ); + assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem+1 - p->nCursor)+1 ); + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + sqlite3VdbeIncrWriteCounter(p, pC); + pCrsr = pC->uc.pCursor; + assert( pCrsr!=0 ); + r.pKeyInfo = pC->pKeyInfo; + r.nField = (u16)pOp->p3; + r.default_rc = 0; + r.aMem = &aMem[pOp->p2]; + rc = sqlite3BtreeIndexMoveto(pCrsr, &r, &res); + if( rc ) goto abort_due_to_error; + if( res!=0 ){ + rc = sqlite3VdbeFindIndexKey(pCrsr, pOp->p4.pIdx, &r, &res, 0); + if( rc!=SQLITE_OK ) goto abort_due_to_error; + if( res!=0 ){ + if( !sqlite3WritableSchema(db) ){ + rc = sqlite3ReportError( + SQLITE_CORRUPT_INDEX, __LINE__, "index corruption"); + goto abort_due_to_error; + } + pC->cacheStatus = CACHE_STALE; + pC->seekResult = 0; + break; + } + } + rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE); + if( rc ) goto abort_due_to_error; + assert( pC->deferredMoveto==0 ); + pC->cacheStatus = CACHE_STALE; + pC->seekResult = 0; + break; +} + +/* Opcode: DeferredSeek P1 * P3 P4 * +** Synopsis: Move P3 to P1.rowid if needed +** +** P1 is an open index cursor and P3 is a cursor on the corresponding +** table. This opcode does a deferred seek of the P3 table cursor +** to the row that corresponds to the current row of P1. +** +** This is a deferred seek. Nothing actually happens until +** the cursor is used to read a record. That way, if no reads +** occur, no unnecessary I/O happens. +** +** P4 may be an array of integers (type P4_INTARRAY) containing +** one entry for each column in the P3 table. If array entry a(i) +** is non-zero, then reading column a(i)-1 from cursor P3 is +** equivalent to performing the deferred seek and then reading column i +** from P1. This information is stored in P3 and used to redirect +** reads against P3 over to P1, thus possibly avoiding the need to +** seek and read cursor P3. +*/ +/* Opcode: IdxRowid P1 P2 * * * +** Synopsis: r[P2]=rowid +** +** Write into register P2 an integer which is the last entry in the record at +** the end of the index key pointed to by cursor P1. This integer should be +** the rowid of the table entry to which this index entry points. +** +** See also: Rowid, MakeRecord. +*/ +case OP_DeferredSeek: /* ncycle */ +case OP_IdxRowid: { /* out2, ncycle */ + VdbeCursor *pC; /* The P1 index cursor */ + VdbeCursor *pTabCur; /* The P2 table cursor (OP_DeferredSeek only) */ + i64 rowid; /* Rowid that P1 current points to */ + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE || IsNullCursor(pC) ); + assert( pC->uc.pCursor!=0 ); + assert( pC->isTable==0 || IsNullCursor(pC) ); + assert( pC->deferredMoveto==0 ); + assert( !pC->nullRow || pOp->opcode==OP_IdxRowid ); + + /* The IdxRowid and Seek opcodes are combined because of the commonality + ** of sqlite3VdbeCursorRestore() and sqlite3VdbeIdxRowid(). */ + rc = sqlite3VdbeCursorRestore(pC); + + /* sqlite3VdbeCursorRestore() may fail if the cursor has been disturbed + ** since it was last positioned and an error (e.g. OOM or an IO error) + ** occurs while trying to reposition it. */ + if( rc!=SQLITE_OK ) goto abort_due_to_error; + + if( !pC->nullRow ){ + rowid = 0; /* Not needed. Only used to silence a warning. */ + rc = sqlite3VdbeIdxRowid(db, pC->uc.pCursor, &rowid); + if( rc!=SQLITE_OK ){ + goto abort_due_to_error; + } + if( pOp->opcode==OP_DeferredSeek ){ + assert( pOp->p3>=0 && pOp->p3nCursor ); + pTabCur = p->apCsr[pOp->p3]; + assert( pTabCur!=0 ); + assert( pTabCur->eCurType==CURTYPE_BTREE ); + assert( pTabCur->uc.pCursor!=0 ); + assert( pTabCur->isTable ); + pTabCur->nullRow = 0; + pTabCur->movetoTarget = rowid; + pTabCur->deferredMoveto = 1; + pTabCur->cacheStatus = CACHE_STALE; + assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 ); + assert( !pTabCur->isEphemeral ); + pTabCur->ub.aAltMap = pOp->p4.ai; + assert( !pC->isEphemeral ); + pTabCur->pAltCursor = pC; + }else{ + pOut = out2Prerelease(p, pOp); + pOut->u.i = rowid; + } + }else{ + assert( pOp->opcode==OP_IdxRowid ); + sqlite3VdbeMemSetNull(&aMem[pOp->p2]); + } + break; +} + +/* Opcode: FinishSeek P1 * * * * +** +** If cursor P1 was previously moved via OP_DeferredSeek, complete that +** seek operation now, without further delay. If the cursor seek has +** already occurred, this instruction is a no-op. +*/ +case OP_FinishSeek: { /* ncycle */ + VdbeCursor *pC; /* The P1 index cursor */ + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + if( pC->deferredMoveto ){ + rc = sqlite3VdbeFinishMoveto(pC); + if( rc ) goto abort_due_to_error; + } + break; +} + +/* Opcode: IdxGE P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** The P4 register values beginning with P3 form an unpacked index +** key that omits the PRIMARY KEY. Compare this key value against the index +** that P1 is currently pointing to, ignoring the PRIMARY KEY or ROWID +** fields at the end. +** +** If the P1 index entry is greater than or equal to the key value +** then jump to P2. Otherwise fall through to the next instruction. +*/ +/* Opcode: IdxGT P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** The P4 register values beginning with P3 form an unpacked index +** key that omits the PRIMARY KEY. Compare this key value against the index +** that P1 is currently pointing to, ignoring the PRIMARY KEY or ROWID +** fields at the end. +** +** If the P1 index entry is greater than the key value +** then jump to P2. Otherwise fall through to the next instruction. +*/ +/* Opcode: IdxLT P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** The P4 register values beginning with P3 form an unpacked index +** key that omits the PRIMARY KEY or ROWID. Compare this key value against +** the index that P1 is currently pointing to, ignoring the PRIMARY KEY or +** ROWID on the P1 index. +** +** If the P1 index entry is less than the key value then jump to P2. +** Otherwise fall through to the next instruction. +*/ +/* Opcode: IdxLE P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** The P4 register values beginning with P3 form an unpacked index +** key that omits the PRIMARY KEY or ROWID. Compare this key value against +** the index that P1 is currently pointing to, ignoring the PRIMARY KEY or +** ROWID on the P1 index. +** +** If the P1 index entry is less than or equal to the key value then jump +** to P2. Otherwise fall through to the next instruction. +*/ +case OP_IdxLE: /* jump, ncycle */ +case OP_IdxGT: /* jump, ncycle */ +case OP_IdxLT: /* jump, ncycle */ +case OP_IdxGE: { /* jump, ncycle */ + VdbeCursor *pC; + int res; + UnpackedRecord r; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->isOrdered ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->uc.pCursor!=0); + assert( pC->deferredMoveto==0 ); + assert( pOp->p4type==P4_INT32 ); + r.pKeyInfo = pC->pKeyInfo; + r.nField = (u16)pOp->p4.i; + if( pOp->opcodeopcode==OP_IdxLE || pOp->opcode==OP_IdxGT ); + r.default_rc = -1; + }else{ + assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxLT ); + r.default_rc = 0; + } + r.aMem = &aMem[pOp->p3]; +#ifdef SQLITE_DEBUG + { + int i; + for(i=0; ip3+i, &aMem[pOp->p3+i]); + } + } +#endif + + /* Inlined version of sqlite3VdbeIdxKeyCompare() */ + { + i64 nCellKey = 0; + BtCursor *pCur; + Mem m; + + assert( pC->eCurType==CURTYPE_BTREE ); + pCur = pC->uc.pCursor; + assert( sqlite3BtreeCursorIsValid(pCur) ); + nCellKey = sqlite3BtreePayloadSize(pCur); + /* nCellKey will always be between 0 and 0xffffffff because of the way + ** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */ + if( nCellKey<=0 || nCellKey>0x7fffffff ){ + rc = SQLITE_CORRUPT_BKPT; + goto abort_due_to_error; + } + sqlite3VdbeMemInit(&m, db, 0); + rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m); + if( rc ) goto abort_due_to_error; + res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, &r, 0); + sqlite3VdbeMemReleaseMalloc(&m); + } + /* End of inlined sqlite3VdbeIdxKeyCompare() */ + + assert( (OP_IdxLE&1)==(OP_IdxLT&1) && (OP_IdxGE&1)==(OP_IdxGT&1) ); + if( (pOp->opcode&1)==(OP_IdxLT&1) ){ + assert( pOp->opcode==OP_IdxLE || pOp->opcode==OP_IdxLT ); + res = -res; + }else{ + assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxGT ); + res++; + } + VdbeBranchTaken(res>0,2); + assert( rc==SQLITE_OK ); + if( res>0 ) goto jump_to_p2; + break; +} + +/* Opcode: Destroy P1 P2 P3 * * +** +** Delete an entire database table or index whose root page in the database +** file is given by P1. +** +** The table being destroyed is in the main database file if P3==0. If +** P3==1 then the table to be destroyed is in the auxiliary database file +** that is used to store tables create using CREATE TEMPORARY TABLE. +** +** If AUTOVACUUM is enabled then it is possible that another root page +** might be moved into the newly deleted root page in order to keep all +** root pages contiguous at the beginning of the database. The former +** value of the root page that moved - its value before the move occurred - +** is stored in register P2. If no page movement was required (because the +** table being dropped was already the last one in the database) then a +** zero is stored in register P2. If AUTOVACUUM is disabled then a zero +** is stored in register P2. +** +** This opcode throws an error if there are any active reader VMs when +** it is invoked. This is done to avoid the difficulty associated with +** updating existing cursors when a root page is moved in an AUTOVACUUM +** database. This error is thrown even if the database is not an AUTOVACUUM +** db in order to avoid introducing an incompatibility between autovacuum +** and non-autovacuum modes. +** +** See also: Clear +*/ +case OP_Destroy: { /* out2 */ + int iMoved; + int iDb; + + sqlite3VdbeIncrWriteCounter(p, 0); + assert( p->readOnly==0 ); + assert( pOp->p1>1 ); + pOut = out2Prerelease(p, pOp); + pOut->flags = MEM_Null; + if( db->nVdbeRead > db->nVDestroy+1 ){ + rc = SQLITE_LOCKED; + p->errorAction = OE_Abort; + goto abort_due_to_error; + }else{ + iDb = pOp->p3; + assert( DbMaskTest(p->btreeMask, iDb) ); + iMoved = 0; /* Not needed. Only to silence a warning. */ + rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved); + pOut->flags = MEM_Int; + pOut->u.i = iMoved; + if( rc ) goto abort_due_to_error; +#ifndef SQLITE_OMIT_AUTOVACUUM + if( iMoved!=0 ){ + sqlite3RootPageMoved(db, iDb, iMoved, pOp->p1); + /* All OP_Destroy operations occur on the same btree */ + assert( resetSchemaOnFault==0 || resetSchemaOnFault==iDb+1 ); + resetSchemaOnFault = iDb+1; + } +#endif + } + break; +} + +/* Opcode: Clear P1 P2 P3 +** +** Delete all contents of the database table or index whose root page +** in the database file is given by P1. But, unlike Destroy, do not +** remove the table or index from the database file. +** +** The table being cleared is in the main database file if P2==0. If +** P2==1 then the table to be cleared is in the auxiliary database file +** that is used to store tables create using CREATE TEMPORARY TABLE. +** +** If the P3 value is non-zero, then the row change count is incremented +** by the number of rows in the table being cleared. If P3 is greater +** than zero, then the value stored in register P3 is also incremented +** by the number of rows in the table being cleared. +** +** See also: Destroy +*/ +case OP_Clear: { + i64 nChange; + + sqlite3VdbeIncrWriteCounter(p, 0); + nChange = 0; + assert( p->readOnly==0 ); + assert( DbMaskTest(p->btreeMask, pOp->p2) ); + rc = sqlite3BtreeClearTable(db->aDb[pOp->p2].pBt, (u32)pOp->p1, &nChange); + if( pOp->p3 ){ + p->nChange += nChange; + if( pOp->p3>0 ){ + assert( memIsValid(&aMem[pOp->p3]) ); + memAboutToChange(p, &aMem[pOp->p3]); + aMem[pOp->p3].u.i += nChange; + } + } + if( rc ) goto abort_due_to_error; + break; +} + +/* Opcode: ResetSorter P1 * * * * +** +** Delete all contents from the ephemeral table or sorter +** that is open on cursor P1. +** +** This opcode only works for cursors used for sorting and +** opened with OP_OpenEphemeral or OP_SorterOpen. +*/ +case OP_ResetSorter: { + VdbeCursor *pC; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + if( isSorter(pC) ){ + sqlite3VdbeSorterReset(db, pC->uc.pSorter); + }else{ + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->isEphemeral ); + rc = sqlite3BtreeClearTableOfCursor(pC->uc.pCursor); + if( rc ) goto abort_due_to_error; + } + break; +} + +/* Opcode: CreateBtree P1 P2 P3 * * +** Synopsis: r[P2]=root iDb=P1 flags=P3 +** +** Allocate a new b-tree in the main database file if P1==0 or in the +** TEMP database file if P1==1 or in an attached database if +** P1>1. The P3 argument must be 1 (BTREE_INTKEY) for a rowid table +** it must be 2 (BTREE_BLOBKEY) for an index or WITHOUT ROWID table. +** The root page number of the new b-tree is stored in register P2. +*/ +case OP_CreateBtree: { /* out2 */ + Pgno pgno; + Db *pDb; + + sqlite3VdbeIncrWriteCounter(p, 0); + pOut = out2Prerelease(p, pOp); + pgno = 0; + assert( pOp->p3==BTREE_INTKEY || pOp->p3==BTREE_BLOBKEY ); + assert( pOp->p1>=0 && pOp->p1nDb ); + assert( DbMaskTest(p->btreeMask, pOp->p1) ); + assert( p->readOnly==0 ); + pDb = &db->aDb[pOp->p1]; + assert( pDb->pBt!=0 ); + rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, pOp->p3); + if( rc ) goto abort_due_to_error; + pOut->u.i = pgno; + break; +} + +/* Opcode: SqlExec P1 P2 * P4 * +** +** Run the SQL statement or statements specified in the P4 string. +** +** The P1 parameter is a bitmask of options: +** +** 0x0001 Disable Auth and Trace callbacks while the statements +** in P4 are running. +** +** 0x0002 Set db->nAnalysisLimit to P2 while the statements in +** P4 are running. +** +*/ +case OP_SqlExec: { + char *zErr; +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth; +#endif + u8 mTrace; + int savedAnalysisLimit; + + sqlite3VdbeIncrWriteCounter(p, 0); + db->nSqlExec++; + zErr = 0; +#ifndef SQLITE_OMIT_AUTHORIZATION + xAuth = db->xAuth; +#endif + mTrace = db->mTrace; + savedAnalysisLimit = db->nAnalysisLimit; + if( pOp->p1 & 0x0001 ){ +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = 0; +#endif + db->mTrace = 0; + } + if( pOp->p1 & 0x0002 ){ + db->nAnalysisLimit = pOp->p2; + } + rc = sqlite3_exec(db, pOp->p4.z, 0, 0, &zErr); + db->nSqlExec--; +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; +#endif + db->mTrace = mTrace; + db->nAnalysisLimit = savedAnalysisLimit; + if( zErr || rc ){ + sqlite3VdbeError(p, "%s", zErr); + sqlite3_free(zErr); + if( rc==SQLITE_NOMEM ) goto no_mem; + goto abort_due_to_error; + } + break; +} + +/* Opcode: ParseSchema P1 * * P4 * +** +** Read and parse all entries from the schema table of database P1 +** that match the WHERE clause P4. If P4 is a NULL pointer, then the +** entire schema for P1 is reparsed. +** +** This opcode invokes the parser to create a new virtual machine, +** then runs the new virtual machine. It is thus a re-entrant opcode. +*/ +case OP_ParseSchema: { + int iDb; + const char *zSchema; + char *zSql; + InitData initData; + + /* Any prepared statement that invokes this opcode will hold mutexes + ** on every btree. This is a prerequisite for invoking + ** sqlite3InitCallback(). + */ +#ifdef SQLITE_DEBUG + for(iDb=0; iDbnDb; iDb++){ + assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); + } +#endif + + iDb = pOp->p1; + assert( iDb>=0 && iDbnDb ); + assert( DbHasProperty(db, iDb, DB_SchemaLoaded) + || db->mallocFailed + || (CORRUPT_DB && (db->flags & SQLITE_NoSchemaError)!=0) ); + +#ifndef SQLITE_OMIT_ALTERTABLE + if( pOp->p4.z==0 ){ + sqlite3SchemaClear(db->aDb[iDb].pSchema); + db->mDbFlags &= ~DBFLAG_SchemaKnownOk; + rc = sqlite3InitOne(db, iDb, &p->zErrMsg, pOp->p5); + db->mDbFlags |= DBFLAG_SchemaChange; + p->expired = 0; + }else +#endif + { + zSchema = LEGACY_SCHEMA_TABLE; + initData.db = db; + initData.iDb = iDb; + initData.pzErrMsg = &p->zErrMsg; + initData.mInitFlags = 0; + initData.mxPage = sqlite3BtreeLastPage(db->aDb[iDb].pBt); + zSql = sqlite3MPrintf(db, + "SELECT*FROM\"%w\".%s WHERE %s ORDER BY rowid", + db->aDb[iDb].zDbSName, zSchema, pOp->p4.z); + if( zSql==0 ){ + rc = SQLITE_NOMEM_BKPT; + }else{ + assert( db->init.busy==0 ); + db->init.busy = 1; + initData.rc = SQLITE_OK; + initData.nInitRow = 0; + assert( !db->mallocFailed ); + rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); + if( rc==SQLITE_OK ) rc = initData.rc; + if( rc==SQLITE_OK && initData.nInitRow==0 ){ + /* The OP_ParseSchema opcode with a non-NULL P4 argument should parse + ** at least one SQL statement. Any less than that indicates that + ** the sqlite_schema table is corrupt. */ + rc = SQLITE_CORRUPT_BKPT; + } + sqlite3DbFreeNN(db, zSql); + db->init.busy = 0; + } + } + if( rc ){ + sqlite3ResetAllSchemasOfConnection(db); + if( rc==SQLITE_NOMEM ){ + goto no_mem; + } + goto abort_due_to_error; + } + break; +} + +#if !defined(SQLITE_OMIT_ANALYZE) +/* Opcode: LoadAnalysis P1 * * * * +** +** Read the sqlite_stat1 table for database P1 and load the content +** of that table into the internal index hash table. This will cause +** the analysis to be used when preparing all subsequent queries. +*/ +case OP_LoadAnalysis: { + assert( pOp->p1>=0 && pOp->p1nDb ); + rc = sqlite3AnalysisLoad(db, pOp->p1); + if( rc ) goto abort_due_to_error; + break; +} +#endif /* !defined(SQLITE_OMIT_ANALYZE) */ + +/* Opcode: DropTable P1 * * P4 * +** +** Remove the internal (in-memory) data structures that describe +** the table named P4 in database P1. This is called after a table +** is dropped from disk (using the Destroy opcode) in order to keep +** the internal representation of the +** schema consistent with what is on disk. +*/ +case OP_DropTable: { + sqlite3VdbeIncrWriteCounter(p, 0); + sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p4.z); + break; +} + +/* Opcode: DropIndex P1 * * P4 * +** +** Remove the internal (in-memory) data structures that describe +** the index named P4 in database P1. This is called after an index +** is dropped from disk (using the Destroy opcode) +** in order to keep the internal representation of the +** schema consistent with what is on disk. +*/ +case OP_DropIndex: { + sqlite3VdbeIncrWriteCounter(p, 0); + sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p4.z); + break; +} + +/* Opcode: DropTrigger P1 * * P4 * +** +** Remove the internal (in-memory) data structures that describe +** the trigger named P4 in database P1. This is called after a trigger +** is dropped from disk (using the Destroy opcode) in order to keep +** the internal representation of the +** schema consistent with what is on disk. +*/ +case OP_DropTrigger: { + sqlite3VdbeIncrWriteCounter(p, 0); + sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p4.z); + break; +} + + +#ifndef SQLITE_OMIT_INTEGRITY_CHECK +/* Opcode: IntegrityCk P1 P2 P3 P4 P5 +** +** Do an analysis of the currently open database. Store in +** register (P1+1) the text of an error message describing any problems. +** If no problems are found, store a NULL in register (P1+1). +** +** The register (P1) contains one less than the maximum number of allowed +** errors. At most reg(P1) errors will be reported. +** In other words, the analysis stops as soon as reg(P1) errors are +** seen. Reg(P1) is updated with the number of errors remaining. +** +** The root page numbers of all tables in the database are integers +** stored in P4_INTARRAY argument. +** +** If P5 is not zero, the check is done on the auxiliary database +** file, not the main database file. +** +** This opcode is used to implement the integrity_check pragma. +*/ +case OP_IntegrityCk: { + int nRoot; /* Number of tables to check. (Number of root pages.) */ + Pgno *aRoot; /* Array of rootpage numbers for tables to be checked */ + int nErr; /* Number of errors reported */ + char *z; /* Text of the error report */ + Mem *pnErr; /* Register keeping track of errors remaining */ + + assert( p->bIsReader ); + assert( pOp->p4type==P4_INTARRAY ); + nRoot = pOp->p2; + aRoot = pOp->p4.ai; + assert( nRoot>0 ); + assert( aRoot!=0 ); + assert( aRoot[0]==(Pgno)nRoot ); + assert( pOp->p1>0 && (pOp->p1+1)<=(p->nMem+1 - p->nCursor) ); + pnErr = &aMem[pOp->p1]; + assert( (pnErr->flags & MEM_Int)!=0 ); + assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 ); + pIn1 = &aMem[pOp->p1+1]; + assert( pOp->p5nDb ); + assert( DbMaskTest(p->btreeMask, pOp->p5) ); + rc = sqlite3BtreeIntegrityCheck(db, db->aDb[pOp->p5].pBt, &aRoot[1], + &aMem[pOp->p3], nRoot, (int)pnErr->u.i+1, &nErr, &z); + sqlite3VdbeMemSetNull(pIn1); + if( nErr==0 ){ + assert( z==0 ); + }else if( rc ){ + sqlite3_free(z); + goto abort_due_to_error; + }else{ + pnErr->u.i -= nErr-1; + sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free); + } + UPDATE_MAX_BLOBSIZE(pIn1); + sqlite3VdbeChangeEncoding(pIn1, encoding); + goto check_for_interrupt; +} + +/* Opcode: IFindKey P1 P2 P3 P4 * +** +** This instruction always follows an OP_Found with the same P1, P2 and P3 +** values as this instruction and a non-zero P4 value. The P4 value to +** this opcode is of type P4_INDEX and contains a pointer to the Index +** object of for the index being searched. +** +** This opcode uses sqlite3VdbeFindIndexKey() to search around the current +** cursor location for an index key that exactly matches all fields that +** are not indexed expressions or references to VIRTUAL generated columns, +** and either exactly match or are real numbers that are within 2 ULPs of +** each other if the don't match. +** +** To put it another way, this opcode looks for nearby index entries that +** are very close to the search key, but which might have small differences +** in floating-point values that come via an expression. +** +** If no nearby alternative entry is found in cursor P1, then jump to P2. +** But if a close match is found, fall through. +** +** This opcode is used by PRAGMA integrity_check to help distinguish +** between truely corrupt indexes and expression indexes that are holding +** floating-point values that are off by one or two ULPs. +*/ +case OP_IFindKey: { /* jump, in3 */ + VdbeCursor *pC; + int res; + UnpackedRecord r; + + assert( pOp[-1].opcode==OP_Found ); + assert( pOp[-1].p1==pOp->p1 ); + assert( pOp[-1].p3==pOp->p3 ); + pC = p->apCsr[pOp->p1]; + assert( pOp->p4type==P4_INDEX ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->uc.pCursor!=0 ); + assert( pC->isTable==0 ); + + memset(&r, 0, sizeof(r)); + r.aMem = &aMem[pOp->p3]; + r.nField = pOp->p4.pIdx->nColumn; + r.pKeyInfo = pC->pKeyInfo; + + rc = sqlite3VdbeFindIndexKey(pC->uc.pCursor, pOp->p4.pIdx, &r, &res, 1); + if( rc || res!=0 ){ + rc = SQLITE_OK; + goto jump_to_p2; + } + pC->nullRow = 0; + break; +}; +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ + +/* Opcode: RowSetAdd P1 P2 * * * +** Synopsis: rowset(P1)=r[P2] +** +** Insert the integer value held by register P2 into a RowSet object +** held in register P1. +** +** An assertion fails if P2 is not an integer. +*/ +case OP_RowSetAdd: { /* in1, in2 */ + pIn1 = &aMem[pOp->p1]; + pIn2 = &aMem[pOp->p2]; + assert( (pIn2->flags & MEM_Int)!=0 ); + if( (pIn1->flags & MEM_Blob)==0 ){ + if( sqlite3VdbeMemSetRowSet(pIn1) ) goto no_mem; + } + assert( sqlite3VdbeMemIsRowSet(pIn1) ); + sqlite3RowSetInsert((RowSet*)pIn1->z, pIn2->u.i); + break; +} + +/* Opcode: RowSetRead P1 P2 P3 * * +** Synopsis: r[P3]=rowset(P1) +** +** Extract the smallest value from the RowSet object in P1 +** and put that value into register P3. +** Or, if RowSet object P1 is initially empty, leave P3 +** unchanged and jump to instruction P2. +*/ +case OP_RowSetRead: { /* jump, in1, out3 */ + i64 val; + + pIn1 = &aMem[pOp->p1]; + assert( (pIn1->flags & MEM_Blob)==0 || sqlite3VdbeMemIsRowSet(pIn1) ); + if( (pIn1->flags & MEM_Blob)==0 + || sqlite3RowSetNext((RowSet*)pIn1->z, &val)==0 + ){ + /* The boolean index is empty */ + sqlite3VdbeMemSetNull(pIn1); + VdbeBranchTaken(1,2); + goto jump_to_p2_and_check_for_interrupt; + }else{ + /* A value was pulled from the index */ + VdbeBranchTaken(0,2); + sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val); + } + goto check_for_interrupt; +} + +/* Opcode: RowSetTest P1 P2 P3 P4 +** Synopsis: if r[P3] in rowset(P1) goto P2 +** +** Register P3 is assumed to hold a 64-bit integer value. If register P1 +** contains a RowSet object and that RowSet object contains +** the value held in P3, jump to register P2. Otherwise, insert the +** integer in P3 into the RowSet and continue on to the +** next opcode. +** +** The RowSet object is optimized for the case where sets of integers +** are inserted in distinct phases, which each set contains no duplicates. +** Each set is identified by a unique P4 value. The first set +** must have P4==0, the final set must have P4==-1, and for all other sets +** must have P4>0. +** +** This allows optimizations: (a) when P4==0 there is no need to test +** the RowSet object for P3, as it is guaranteed not to contain it, +** (b) when P4==-1 there is no need to insert the value, as it will +** never be tested for, and (c) when a value that is part of set X is +** inserted, there is no need to search to see if the same value was +** previously inserted as part of set X (only if it was previously +** inserted as part of some other set). +*/ +case OP_RowSetTest: { /* jump, in1, in3 */ + int iSet; + int exists; + + pIn1 = &aMem[pOp->p1]; + pIn3 = &aMem[pOp->p3]; + iSet = pOp->p4.i; + assert( pIn3->flags&MEM_Int ); + + /* If there is anything other than a rowset object in memory cell P1, + ** delete it now and initialize P1 with an empty rowset + */ + if( (pIn1->flags & MEM_Blob)==0 ){ + if( sqlite3VdbeMemSetRowSet(pIn1) ) goto no_mem; + } + assert( sqlite3VdbeMemIsRowSet(pIn1) ); + assert( pOp->p4type==P4_INT32 ); + assert( iSet==-1 || iSet>=0 ); + if( iSet ){ + exists = sqlite3RowSetTest((RowSet*)pIn1->z, iSet, pIn3->u.i); + VdbeBranchTaken(exists!=0,2); + if( exists ) goto jump_to_p2; + } + if( iSet>=0 ){ + sqlite3RowSetInsert((RowSet*)pIn1->z, pIn3->u.i); + } + break; +} + + +#ifndef SQLITE_OMIT_TRIGGER + +/* Opcode: Program P1 P2 P3 P4 P5 +** +** Execute the trigger program passed as P4 (type P4_SUBPROGRAM). +** +** P1 contains the address of the memory cell that contains the first memory +** cell in an array of values used as arguments to the sub-program. P2 +** contains the address to jump to if the sub-program throws an IGNORE +** exception using the RAISE() function. P2 might be zero, if there is +** no possibility that an IGNORE exception will be raised. +** Register P3 contains the address +** of a memory cell in this (the parent) VM that is used to allocate the +** memory required by the sub-vdbe at runtime. +** +** P4 is a pointer to the VM containing the trigger program. +** +** If P5 is non-zero, then recursive program invocation is enabled. +*/ +case OP_Program: { /* jump0 */ + int nMem; /* Number of memory registers for sub-program */ + i64 nByte; /* Bytes of runtime space required for sub-program */ + Mem *pRt; /* Register to allocate runtime space */ + Mem *pMem; /* Used to iterate through memory cells */ + Mem *pEnd; /* Last memory cell in new array */ + VdbeFrame *pFrame; /* New vdbe frame to execute in */ + SubProgram *pProgram; /* Sub-program to execute */ + void *t; /* Token identifying trigger */ + + pProgram = pOp->p4.pProgram; + pRt = &aMem[pOp->p3]; + assert( pProgram->nOp>0 ); + + /* If the p5 flag is clear, then recursive invocation of triggers is + ** disabled for backwards compatibility (p5 is set if this sub-program + ** is really a trigger, not a foreign key action, and the flag set + ** and cleared by the "PRAGMA recursive_triggers" command is clear). + ** + ** It is recursive invocation of triggers, at the SQL level, that is + ** disabled. In some cases a single trigger may generate more than one + ** SubProgram (if the trigger may be executed with more than one different + ** ON CONFLICT algorithm). SubProgram structures associated with a + ** single trigger all have the same value for the SubProgram.token + ** variable. */ + if( pOp->p5 ){ + t = pProgram->token; + for(pFrame=p->pFrame; pFrame && pFrame->token!=t; pFrame=pFrame->pParent); + if( pFrame ) break; + } + + if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){ + rc = SQLITE_ERROR; + sqlite3VdbeError(p, "too many levels of trigger recursion"); + goto abort_due_to_error; + } + + /* Register pRt is used to store the memory required to save the state + ** of the current program, and the memory required at runtime to execute + ** the trigger program. If this trigger has been fired before, then pRt + ** is already allocated. Otherwise, it must be initialized. */ + if( (pRt->flags&MEM_Blob)==0 ){ + /* SubProgram.nMem is set to the number of memory cells used by the + ** program stored in SubProgram.aOp. As well as these, one memory + ** cell is required for each cursor used by the program. Set local + ** variable nMem (and later, VdbeFrame.nChildMem) to this value. + */ + nMem = pProgram->nMem + pProgram->nCsr; + assert( nMem>0 ); + if( pProgram->nCsr==0 ) nMem++; + nByte = ROUND8(sizeof(VdbeFrame)) + + nMem * sizeof(Mem) + + pProgram->nCsr * sizeof(VdbeCursor*) + + (7 + (i64)pProgram->nOp)/8; + pFrame = sqlite3DbMallocZero(db, nByte); + if( !pFrame ){ + goto no_mem; + } + sqlite3VdbeMemRelease(pRt); + pRt->flags = MEM_Blob|MEM_Dyn; + pRt->z = (char*)pFrame; + pRt->n = (int)nByte; + pRt->xDel = sqlite3VdbeFrameMemDel; + + pFrame->v = p; + pFrame->nChildMem = nMem; + pFrame->nChildCsr = pProgram->nCsr; + pFrame->pc = (int)(pOp - aOp); + pFrame->aMem = p->aMem; + pFrame->nMem = p->nMem; + pFrame->apCsr = p->apCsr; + pFrame->nCursor = p->nCursor; + pFrame->aOp = p->aOp; + pFrame->nOp = p->nOp; + pFrame->token = pProgram->token; +#ifdef SQLITE_DEBUG + pFrame->iFrameMagic = SQLITE_FRAME_MAGIC; +#endif + + pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem]; + for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){ + pMem->flags = MEM_Undefined; + pMem->db = db; + } + }else{ + pFrame = (VdbeFrame*)pRt->z; + assert( pRt->xDel==sqlite3VdbeFrameMemDel ); + assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem + || (pProgram->nCsr==0 && pProgram->nMem+1==pFrame->nChildMem) ); + assert( pProgram->nCsr==pFrame->nChildCsr ); + assert( (int)(pOp - aOp)==pFrame->pc ); + } + + p->nFrame++; + pFrame->pParent = p->pFrame; + pFrame->lastRowid = db->lastRowid; + pFrame->nChange = p->nChange; + pFrame->nDbChange = p->db->nChange; + assert( pFrame->pAuxData==0 ); + pFrame->pAuxData = p->pAuxData; + p->pAuxData = 0; + p->nChange = 0; + p->pFrame = pFrame; + p->aMem = aMem = VdbeFrameMem(pFrame); + p->nMem = pFrame->nChildMem; + p->nCursor = (u16)pFrame->nChildCsr; + p->apCsr = (VdbeCursor **)&aMem[p->nMem]; + pFrame->aOnce = (u8*)&p->apCsr[pProgram->nCsr]; + memset(pFrame->aOnce, 0, (pProgram->nOp + 7)/8); + p->aOp = aOp = pProgram->aOp; + p->nOp = pProgram->nOp; +#ifdef SQLITE_DEBUG + /* Verify that second and subsequent executions of the same trigger do not + ** try to reuse register values from the first use. */ + { + int i; + for(i=0; inMem; i++){ + aMem[i].pScopyFrom = 0; /* Prevent false-positive AboutToChange() errs */ + MemSetTypeFlag(&aMem[i], MEM_Undefined); /* Fault if this reg is reused */ + } + } +#endif + pOp = &aOp[-1]; + goto check_for_interrupt; +} + +/* Opcode: Param P1 P2 * * * +** +** This opcode is only ever present in sub-programs called via the +** OP_Program instruction. Copy a value currently stored in a memory +** cell of the calling (parent) frame to cell P2 in the current frames +** address space. This is used by trigger programs to access the new.* +** and old.* values. +** +** The address of the cell in the parent frame is determined by adding +** the value of the P1 argument to the value of the P1 argument to the +** calling OP_Program instruction. +*/ +case OP_Param: { /* out2 */ + VdbeFrame *pFrame; + Mem *pIn; + pOut = out2Prerelease(p, pOp); + pFrame = p->pFrame; + pIn = &pFrame->aMem[pOp->p1 + pFrame->aOp[pFrame->pc].p1]; + sqlite3VdbeMemShallowCopy(pOut, pIn, MEM_Ephem); + break; +} + +#endif /* #ifndef SQLITE_OMIT_TRIGGER */ + +#ifndef SQLITE_OMIT_FOREIGN_KEY +/* Opcode: FkCounter P1 P2 * * * +** Synopsis: fkctr[P1]+=P2 +** +** Increment a "constraint counter" by P2 (P2 may be negative or positive). +** If P1 is non-zero, the database constraint counter is incremented +** (deferred foreign key constraints). Otherwise, if P1 is zero, the +** statement counter is incremented (immediate foreign key constraints). +*/ +case OP_FkCounter: { + if( pOp->p1 ){ + db->nDeferredCons += pOp->p2; + }else{ + if( db->flags & SQLITE_DeferFKs ){ + db->nDeferredImmCons += pOp->p2; + }else{ + p->nFkConstraint += pOp->p2; + } + } + break; +} + +/* Opcode: FkIfZero P1 P2 * * * +** Synopsis: if fkctr[P1]==0 goto P2 +** +** This opcode tests if a foreign key constraint-counter is currently zero. +** If so, jump to instruction P2. Otherwise, fall through to the next +** instruction. +** +** If P1 is non-zero, then the jump is taken if the database constraint-counter +** is zero (the one that counts deferred constraint violations). If P1 is +** zero, the jump is taken if the statement constraint-counter is zero +** (immediate foreign key constraint violations). +*/ +case OP_FkIfZero: { /* jump */ + if( pOp->p1 ){ + VdbeBranchTaken(db->nDeferredCons==0 && db->nDeferredImmCons==0, 2); + if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) goto jump_to_p2; + }else{ + VdbeBranchTaken(p->nFkConstraint==0 && db->nDeferredImmCons==0, 2); + if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) goto jump_to_p2; + } + break; +} +#endif /* #ifndef SQLITE_OMIT_FOREIGN_KEY */ + +#ifndef SQLITE_OMIT_AUTOINCREMENT +/* Opcode: MemMax P1 P2 * * * +** Synopsis: r[P1]=max(r[P1],r[P2]) +** +** P1 is a register in the root frame of this VM (the root frame is +** different from the current frame if this instruction is being executed +** within a sub-program). Set the value of register P1 to the maximum of +** its current value and the value in register P2. +** +** This instruction throws an error if the memory cell is not initially +** an integer. +*/ +case OP_MemMax: { /* in2 */ + VdbeFrame *pFrame; + if( p->pFrame ){ + for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); + pIn1 = &pFrame->aMem[pOp->p1]; + }else{ + pIn1 = &aMem[pOp->p1]; + } + assert( memIsValid(pIn1) ); + sqlite3VdbeMemIntegerify(pIn1); + pIn2 = &aMem[pOp->p2]; + sqlite3VdbeMemIntegerify(pIn2); + if( pIn1->u.iu.i){ + pIn1->u.i = pIn2->u.i; + } + break; +} +#endif /* SQLITE_OMIT_AUTOINCREMENT */ + +/* Opcode: IfPos P1 P2 P3 * * +** Synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 +** +** Register P1 must contain an integer. +** If the value of register P1 is 1 or greater, subtract P3 from the +** value in P1 and jump to P2. +** +** If the initial value of register P1 is less than 1, then the +** value is unchanged and control passes through to the next instruction. +*/ +case OP_IfPos: { /* jump, in1 */ + pIn1 = &aMem[pOp->p1]; + assert( pIn1->flags&MEM_Int ); + VdbeBranchTaken( pIn1->u.i>0, 2); + if( pIn1->u.i>0 ){ + pIn1->u.i -= pOp->p3; + goto jump_to_p2; + } + break; +} + +/* Opcode: OffsetLimit P1 P2 P3 * * +** Synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) +** +** This opcode performs a commonly used computation associated with +** LIMIT and OFFSET processing. r[P1] holds the limit counter. r[P3] +** holds the offset counter. The opcode computes the combined value +** of the LIMIT and OFFSET and stores that value in r[P2]. The r[P2] +** value computed is the total number of rows that will need to be +** visited in order to complete the query. +** +** If r[P3] is zero or negative, that means there is no OFFSET +** and r[P2] is set to be the value of the LIMIT, r[P1]. +** +** if r[P1] is zero or negative, that means there is no LIMIT +** and r[P2] is set to -1. +** +** Otherwise, r[P2] is set to the sum of r[P1] and r[P3]. +*/ +case OP_OffsetLimit: { /* in1, out2, in3 */ + i64 x; + pIn1 = &aMem[pOp->p1]; + pIn3 = &aMem[pOp->p3]; + pOut = out2Prerelease(p, pOp); + assert( pIn1->flags & MEM_Int ); + assert( pIn3->flags & MEM_Int ); + x = pIn1->u.i; + if( x<=0 || sqlite3AddInt64(&x, pIn3->u.i>0?pIn3->u.i:0) ){ + /* If the LIMIT is less than or equal to zero, loop forever. This + ** is documented. But also, if the LIMIT+OFFSET exceeds 2^63 then + ** also loop forever. This is undocumented. In fact, one could argue + ** that the loop should terminate. But assuming 1 billion iterations + ** per second (far exceeding the capabilities of any current hardware) + ** it would take nearly 300 years to actually reach the limit. So + ** looping forever is a reasonable approximation. */ + pOut->u.i = -1; + }else{ + pOut->u.i = x; + } + break; +} + +/* Opcode: IfNotZero P1 P2 * * * +** Synopsis: if r[P1]!=0 then r[P1]--, goto P2 +** +** Register P1 must contain an integer. If the content of register P1 is +** initially greater than zero, then decrement the value in register P1. +** If it is non-zero (negative or positive) and then also jump to P2. +** If register P1 is initially zero, leave it unchanged and fall through. +*/ +case OP_IfNotZero: { /* jump, in1 */ + pIn1 = &aMem[pOp->p1]; + assert( pIn1->flags&MEM_Int ); + VdbeBranchTaken(pIn1->u.i<0, 2); + if( pIn1->u.i ){ + if( pIn1->u.i>0 ) pIn1->u.i--; + goto jump_to_p2; + } + break; +} + +/* Opcode: DecrJumpZero P1 P2 * * * +** Synopsis: if (--r[P1])==0 goto P2 +** +** Register P1 must hold an integer. Decrement the value in P1 +** and jump to P2 if the new value is exactly zero. +*/ +case OP_DecrJumpZero: { /* jump, in1 */ + pIn1 = &aMem[pOp->p1]; + assert( pIn1->flags&MEM_Int ); + if( pIn1->u.i>SMALLEST_INT64 ) pIn1->u.i--; + VdbeBranchTaken(pIn1->u.i==0, 2); + if( pIn1->u.i==0 ) goto jump_to_p2; + break; +} + + +/* Opcode: AggStep * P2 P3 P4 P5 +** Synopsis: accum=r[P3] step(r[P2@P5]) +** +** Execute the xStep function for an aggregate. +** The function has P5 arguments. P4 is a pointer to the +** FuncDef structure that specifies the function. Register P3 is the +** accumulator. +** +** The P5 arguments are taken from register P2 and its +** successors. +*/ +/* Opcode: AggInverse * P2 P3 P4 P5 +** Synopsis: accum=r[P3] inverse(r[P2@P5]) +** +** Execute the xInverse function for an aggregate. +** The function has P5 arguments. P4 is a pointer to the +** FuncDef structure that specifies the function. Register P3 is the +** accumulator. +** +** The P5 arguments are taken from register P2 and its +** successors. +*/ +/* Opcode: AggStep1 P1 P2 P3 P4 P5 +** Synopsis: accum=r[P3] step(r[P2@P5]) +** +** Execute the xStep (if P1==0) or xInverse (if P1!=0) function for an +** aggregate. The function has P5 arguments. P4 is a pointer to the +** FuncDef structure that specifies the function. Register P3 is the +** accumulator. +** +** The P5 arguments are taken from register P2 and its +** successors. +** +** This opcode is initially coded as OP_AggStep0. On first evaluation, +** the FuncDef stored in P4 is converted into an sqlite3_context and +** the opcode is changed. In this way, the initialization of the +** sqlite3_context only happens once, instead of on each call to the +** step function. +*/ +case OP_AggInverse: +case OP_AggStep: { + int n; + sqlite3_context *pCtx; + u64 nAlloc; + + assert( pOp->p4type==P4_FUNCDEF ); + n = pOp->p5; + assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); + assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) ); + assert( pOp->p3p2 || pOp->p3>=pOp->p2+n ); + + /* Allocate space for (a) the context object and (n-1) extra pointers + ** to append to the sqlite3_context.argv[1] array, and (b) a memory + ** cell in which to store the accumulation. Be careful that the memory + ** cell is 8-byte aligned, even on platforms where a pointer is 32-bits. + ** + ** Note: We could avoid this by using a regular memory cell from aMem[] for + ** the accumulator, instead of allocating one here. */ + nAlloc = ROUND8P( SZ_CONTEXT(n) ); + pCtx = sqlite3DbMallocRawNN(db, nAlloc + sizeof(Mem)); + if( pCtx==0 ) goto no_mem; + pCtx->pOut = (Mem*)((u8*)pCtx + nAlloc); + assert( EIGHT_BYTE_ALIGNMENT(pCtx->pOut) ); + + sqlite3VdbeMemInit(pCtx->pOut, db, MEM_Null); + pCtx->pMem = 0; + pCtx->pFunc = pOp->p4.pFunc; + pCtx->iOp = (int)(pOp - aOp); + pCtx->pVdbe = p; + pCtx->skipFlag = 0; + pCtx->isError = 0; + pCtx->enc = encoding; + pCtx->argc = n; + pOp->p4type = P4_FUNCCTX; + pOp->p4.pCtx = pCtx; + + /* OP_AggInverse must have P1==1 and OP_AggStep must have P1==0 */ + assert( pOp->p1==(pOp->opcode==OP_AggInverse) ); + + pOp->opcode = OP_AggStep1; + /* Fall through into OP_AggStep */ + /* no break */ deliberate_fall_through +} +case OP_AggStep1: { + int i; + sqlite3_context *pCtx; + Mem *pMem; + + assert( pOp->p4type==P4_FUNCCTX ); + pCtx = pOp->p4.pCtx; + pMem = &aMem[pOp->p3]; + +#ifdef SQLITE_DEBUG + if( pOp->p1 ){ + /* This is an OP_AggInverse call. Verify that xStep has always + ** been called at least once prior to any xInverse call. */ + assert( pMem->uTemp==0x1122e0e3 ); + }else{ + /* This is an OP_AggStep call. Mark it as such. */ + pMem->uTemp = 0x1122e0e3; + } +#endif + + /* If this function is inside of a trigger, the register array in aMem[] + ** might change from one evaluation to the next. The next block of code + ** checks to see if the register array has changed, and if so it + ** reinitializes the relevant parts of the sqlite3_context object */ + if( pCtx->pMem != pMem ){ + pCtx->pMem = pMem; + for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i]; + } + +#ifdef SQLITE_DEBUG + for(i=0; iargc; i++){ + assert( memIsValid(pCtx->argv[i]) ); + REGISTER_TRACE(pOp->p2+i, pCtx->argv[i]); + } +#endif + + pMem->n++; + assert( pCtx->pOut->flags==MEM_Null ); + assert( pCtx->isError==0 ); + assert( pCtx->skipFlag==0 ); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pOp->p1 ){ + (pCtx->pFunc->xInverse)(pCtx,pCtx->argc,pCtx->argv); + }else +#endif + (pCtx->pFunc->xSFunc)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */ + + if( pCtx->isError ){ + if( pCtx->isError>0 ){ + sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut)); + rc = pCtx->isError; + } + if( pCtx->skipFlag ){ + assert( pOp[-1].opcode==OP_CollSeq ); + i = pOp[-1].p1; + if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1); + pCtx->skipFlag = 0; + } + sqlite3VdbeMemRelease(pCtx->pOut); + pCtx->pOut->flags = MEM_Null; + pCtx->isError = 0; + if( rc ) goto abort_due_to_error; + } + assert( pCtx->pOut->flags==MEM_Null ); + assert( pCtx->skipFlag==0 ); + break; +} + +/* Opcode: AggFinal P1 P2 * P4 * +** Synopsis: accum=r[P1] N=P2 +** +** P1 is the memory location that is the accumulator for an aggregate +** or window function. Execute the finalizer function +** for an aggregate and store the result in P1. +** +** P2 is the number of arguments that the step function takes and +** P4 is a pointer to the FuncDef for this function. The P2 +** argument is not used by this opcode. It is only there to disambiguate +** functions that can take varying numbers of arguments. The +** P4 argument is only needed for the case where +** the step function was not previously called. +*/ +/* Opcode: AggValue * P2 P3 P4 * +** Synopsis: r[P3]=value N=P2 +** +** Invoke the xValue() function and store the result in register P3. +** +** P2 is the number of arguments that the step function takes and +** P4 is a pointer to the FuncDef for this function. The P2 +** argument is not used by this opcode. It is only there to disambiguate +** functions that can take varying numbers of arguments. The +** P4 argument is only needed for the case where +** the step function was not previously called. +*/ +case OP_AggValue: +case OP_AggFinal: { + Mem *pMem; + assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); + assert( pOp->p3==0 || pOp->opcode==OP_AggValue ); + pMem = &aMem[pOp->p1]; + assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pOp->p3 ){ + memAboutToChange(p, &aMem[pOp->p3]); + rc = sqlite3VdbeMemAggValue(pMem, &aMem[pOp->p3], pOp->p4.pFunc); + pMem = &aMem[pOp->p3]; + }else +#endif + { + rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc); + } + + if( rc ){ + sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem)); + goto abort_due_to_error; + } + sqlite3VdbeChangeEncoding(pMem, encoding); + UPDATE_MAX_BLOBSIZE(pMem); + REGISTER_TRACE((int)(pMem-aMem), pMem); + break; +} + +#ifndef SQLITE_OMIT_WAL +/* Opcode: Checkpoint P1 P2 P3 * * +** +** Checkpoint database P1. This is a no-op if P1 is not currently in +** WAL mode. Parameter P2 is one of SQLITE_CHECKPOINT_PASSIVE, FULL, +** RESTART, or TRUNCATE. Write 1 or 0 into mem[P3] if the checkpoint returns +** SQLITE_BUSY or not, respectively. Write the number of pages in the +** WAL after the checkpoint into mem[P3+1] and the number of pages +** in the WAL that have been checkpointed after the checkpoint +** completes into mem[P3+2]. However on an error, mem[P3+1] and +** mem[P3+2] are initialized to -1. +*/ +case OP_Checkpoint: { + int i; /* Loop counter */ + int aRes[3]; /* Results */ + Mem *pMem; /* Write results here */ + + assert( p->readOnly==0 ); + aRes[0] = 0; + aRes[1] = aRes[2] = -1; + assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE + || pOp->p2==SQLITE_CHECKPOINT_FULL + || pOp->p2==SQLITE_CHECKPOINT_RESTART + || pOp->p2==SQLITE_CHECKPOINT_TRUNCATE + || pOp->p2==SQLITE_CHECKPOINT_NOOP + ); + rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &aRes[1], &aRes[2]); + if( rc ){ + if( rc!=SQLITE_BUSY ) goto abort_due_to_error; + rc = SQLITE_OK; + aRes[0] = 1; + } + for(i=0, pMem = &aMem[pOp->p3]; i<3; i++, pMem++){ + sqlite3VdbeMemSetInt64(pMem, (i64)aRes[i]); + } + break; +}; +#endif + +#ifndef SQLITE_OMIT_PRAGMA +/* Opcode: JournalMode P1 P2 P3 * * +** +** Change the journal mode of database P1 to P3. P3 must be one of the +** PAGER_JOURNALMODE_XXX values. If changing between the various rollback +** modes (delete, truncate, persist, off and memory), this is a simple +** operation. No IO is required. +** +** If changing into or out of WAL mode the procedure is more complicated. +** +** Write a string containing the final journal-mode to register P2. +*/ +case OP_JournalMode: { /* out2 */ + Btree *pBt; /* Btree to change journal mode of */ + Pager *pPager; /* Pager associated with pBt */ + int eNew; /* New journal mode */ + int eOld; /* The old journal mode */ +#ifndef SQLITE_OMIT_WAL + const char *zFilename; /* Name of database file for pPager */ +#endif + + pOut = out2Prerelease(p, pOp); + eNew = pOp->p3; + assert( eNew==PAGER_JOURNALMODE_DELETE + || eNew==PAGER_JOURNALMODE_TRUNCATE + || eNew==PAGER_JOURNALMODE_PERSIST + || eNew==PAGER_JOURNALMODE_OFF + || eNew==PAGER_JOURNALMODE_MEMORY + || eNew==PAGER_JOURNALMODE_WAL + || eNew==PAGER_JOURNALMODE_QUERY + ); + assert( pOp->p1>=0 && pOp->p1nDb ); + assert( p->readOnly==0 ); + + pBt = db->aDb[pOp->p1].pBt; + pPager = sqlite3BtreePager(pBt); + eOld = sqlite3PagerGetJournalMode(pPager); + if( eNew==PAGER_JOURNALMODE_QUERY ) eNew = eOld; + assert( sqlite3BtreeHoldsMutex(pBt) ); + if( !sqlite3PagerOkToChangeJournalMode(pPager) ) eNew = eOld; + +#ifndef SQLITE_OMIT_WAL + zFilename = sqlite3PagerFilename(pPager, 1); + + /* Do not allow a transition to journal_mode=WAL for a database + ** in temporary storage or if the VFS does not support shared memory + */ + if( eNew==PAGER_JOURNALMODE_WAL + && (sqlite3Strlen30(zFilename)==0 /* Temp file */ + || !sqlite3PagerWalSupported(pPager)) /* No shared-memory support */ + ){ + eNew = eOld; + } + + if( (eNew!=eOld) + && (eOld==PAGER_JOURNALMODE_WAL || eNew==PAGER_JOURNALMODE_WAL) + ){ + if( !db->autoCommit || db->nVdbeRead>1 ){ + rc = SQLITE_ERROR; + sqlite3VdbeError(p, + "cannot change %s wal mode from within a transaction", + (eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of") + ); + goto abort_due_to_error; + }else{ + + if( eOld==PAGER_JOURNALMODE_WAL ){ + /* If leaving WAL mode, close the log file. If successful, the call + ** to PagerCloseWal() checkpoints and deletes the write-ahead-log + ** file. An EXCLUSIVE lock may still be held on the database file + ** after a successful return. + */ + rc = sqlite3PagerCloseWal(pPager, db); + if( rc==SQLITE_OK ){ + sqlite3PagerSetJournalMode(pPager, eNew); + } + }else if( eOld==PAGER_JOURNALMODE_MEMORY ){ + /* Cannot transition directly from MEMORY to WAL. Use mode OFF + ** as an intermediate */ + sqlite3PagerSetJournalMode(pPager, PAGER_JOURNALMODE_OFF); + } + + /* Open a transaction on the database file. Regardless of the journal + ** mode, this transaction always uses a rollback journal. + */ + assert( sqlite3BtreeTxnState(pBt)!=SQLITE_TXN_WRITE ); + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeSetVersion(pBt, (eNew==PAGER_JOURNALMODE_WAL ? 2 : 1)); + } + } + } +#endif /* ifndef SQLITE_OMIT_WAL */ + + if( rc ) eNew = eOld; + eNew = sqlite3PagerSetJournalMode(pPager, eNew); + + pOut->flags = MEM_Str|MEM_Static|MEM_Term; + pOut->z = (char *)sqlite3JournalModename(eNew); + pOut->n = sqlite3Strlen30(pOut->z); + pOut->enc = SQLITE_UTF8; + sqlite3VdbeChangeEncoding(pOut, encoding); + if( rc ) goto abort_due_to_error; + break; +}; +#endif /* SQLITE_OMIT_PRAGMA */ + +#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) +/* Opcode: Vacuum P1 P2 * * * +** +** Vacuum the entire database P1. P1 is 0 for "main", and 2 or more +** for an attached database. The "temp" database may not be vacuumed. +** +** If P2 is not zero, then it is a register holding a string which is +** the file into which the result of vacuum should be written. When +** P2 is zero, the vacuum overwrites the original database. +*/ +case OP_Vacuum: { + assert( p->readOnly==0 ); + rc = sqlite3RunVacuum(&p->zErrMsg, db, pOp->p1, + pOp->p2 ? &aMem[pOp->p2] : 0); + if( rc ) goto abort_due_to_error; + break; +} +#endif + +#if !defined(SQLITE_OMIT_AUTOVACUUM) +/* Opcode: IncrVacuum P1 P2 * * * +** +** Perform a single step of the incremental vacuum procedure on +** the P1 database. If the vacuum has finished, jump to instruction +** P2. Otherwise, fall through to the next instruction. +*/ +case OP_IncrVacuum: { /* jump */ + Btree *pBt; + + assert( pOp->p1>=0 && pOp->p1nDb ); + assert( DbMaskTest(p->btreeMask, pOp->p1) ); + assert( p->readOnly==0 ); + pBt = db->aDb[pOp->p1].pBt; + rc = sqlite3BtreeIncrVacuum(pBt); + VdbeBranchTaken(rc==SQLITE_DONE,2); + if( rc ){ + if( rc!=SQLITE_DONE ) goto abort_due_to_error; + rc = SQLITE_OK; + goto jump_to_p2; + } + break; +} +#endif + +/* Opcode: Expire P1 P2 * * * +** +** Cause precompiled statements to expire. When an expired statement +** is executed using sqlite3_step() it will either automatically +** reprepare itself (if it was originally created using sqlite3_prepare_v2()) +** or it will fail with SQLITE_SCHEMA. +** +** If P1 is 0, then all SQL statements become expired. If P1 is non-zero, +** then only the currently executing statement is expired. +** +** If P2 is 0, then SQL statements are expired immediately. If P2 is 1, +** then running SQL statements are allowed to continue to run to completion. +** The P2==1 case occurs when a CREATE INDEX or similar schema change happens +** that might help the statement run faster but which does not affect the +** correctness of operation. +*/ +case OP_Expire: { + assert( pOp->p2==0 || pOp->p2==1 ); + if( !pOp->p1 ){ + sqlite3ExpirePreparedStatements(db, pOp->p2); + }else{ + p->expired = pOp->p2+1; + } + break; +} + +/* Opcode: CursorLock P1 * * * * +** +** Lock the btree to which cursor P1 is pointing so that the btree cannot be +** written by an other cursor. +*/ +case OP_CursorLock: { + VdbeCursor *pC; + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + sqlite3BtreeCursorPin(pC->uc.pCursor); + break; +} + +/* Opcode: CursorUnlock P1 * * * * +** +** Unlock the btree to which cursor P1 is pointing so that it can be +** written by other cursors. +*/ +case OP_CursorUnlock: { + VdbeCursor *pC; + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + sqlite3BtreeCursorUnpin(pC->uc.pCursor); + break; +} + +#ifndef SQLITE_OMIT_SHARED_CACHE +/* Opcode: TableLock P1 P2 P3 P4 * +** Synopsis: iDb=P1 root=P2 write=P3 +** +** Obtain a lock on a particular table. This instruction is only used when +** the shared-cache feature is enabled. +** +** P1 is the index of the database in sqlite3.aDb[] of the database +** on which the lock is acquired. A readlock is obtained if P3==0 or +** a write lock if P3==1. +** +** P2 contains the root-page of the table to lock. +** +** P4 contains a pointer to the name of the table being locked. This is only +** used to generate an error message if the lock cannot be obtained. +*/ +case OP_TableLock: { + u8 isWriteLock = (u8)pOp->p3; + if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommit) ){ + int p1 = pOp->p1; + assert( p1>=0 && p1nDb ); + assert( DbMaskTest(p->btreeMask, p1) ); + assert( isWriteLock==0 || isWriteLock==1 ); + rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock); + if( rc ){ + if( (rc&0xFF)==SQLITE_LOCKED ){ + const char *z = pOp->p4.z; + sqlite3VdbeError(p, "database table is locked: %s", z); + } + goto abort_due_to_error; + } + } + break; +} +#endif /* SQLITE_OMIT_SHARED_CACHE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VBegin * * * P4 * +** +** P4 may be a pointer to an sqlite3_vtab structure. If so, call the +** xBegin method for that table. +** +** Also, whether or not P4 is set, check that this is not being called from +** within a callback to a virtual table xSync() method. If it is, the error +** code will be set to SQLITE_LOCKED. +*/ +case OP_VBegin: { + VTable *pVTab; + pVTab = pOp->p4.pVtab; + rc = sqlite3VtabBegin(db, pVTab); + if( pVTab ) sqlite3VtabImportErrmsg(p, pVTab->pVtab); + if( rc ) goto abort_due_to_error; + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VCreate P1 P2 * * * +** +** P2 is a register that holds the name of a virtual table in database +** P1. Call the xCreate method for that table. +*/ +case OP_VCreate: { + Mem sMem; /* For storing the record being decoded */ + const char *zTab; /* Name of the virtual table */ + + memset(&sMem, 0, sizeof(sMem)); + sMem.db = db; + /* Because P2 is always a static string, it is impossible for the + ** sqlite3VdbeMemCopy() to fail */ + assert( (aMem[pOp->p2].flags & MEM_Str)!=0 ); + assert( (aMem[pOp->p2].flags & MEM_Static)!=0 ); + rc = sqlite3VdbeMemCopy(&sMem, &aMem[pOp->p2]); + assert( rc==SQLITE_OK ); + zTab = (const char*)sqlite3_value_text(&sMem); + assert( zTab || db->mallocFailed ); + if( zTab ){ + rc = sqlite3VtabCallCreate(db, pOp->p1, zTab, &p->zErrMsg); + } + sqlite3VdbeMemRelease(&sMem); + if( rc ) goto abort_due_to_error; + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VDestroy P1 * * P4 * +** +** P4 is the name of a virtual table in database P1. Call the xDestroy method +** of that table. +*/ +case OP_VDestroy: { + db->nVDestroy++; + rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z); + db->nVDestroy--; + assert( p->errorAction==OE_Abort && p->usesStmtJournal ); + if( rc ) goto abort_due_to_error; + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VOpen P1 * * P4 * +** +** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. +** P1 is a cursor number. This opcode opens a cursor to the virtual +** table and stores that cursor in P1. +*/ +case OP_VOpen: { /* ncycle */ + VdbeCursor *pCur; + sqlite3_vtab_cursor *pVCur; + sqlite3_vtab *pVtab; + const sqlite3_module *pModule; + + assert( p->bIsReader ); + pCur = p->apCsr[pOp->p1]; + if( pCur!=0 + && ALWAYS( pCur->eCurType==CURTYPE_VTAB ) + && ALWAYS( pCur->uc.pVCur->pVtab==pOp->p4.pVtab->pVtab ) + ){ + /* This opcode is a no-op if the cursor is already open */ + break; + } + pVCur = 0; + pVtab = pOp->p4.pVtab->pVtab; + if( pVtab==0 || NEVER(pVtab->pModule==0) ){ + rc = SQLITE_LOCKED; + goto abort_due_to_error; + } + pModule = pVtab->pModule; + rc = pModule->xOpen(pVtab, &pVCur); + sqlite3VtabImportErrmsg(p, pVtab); + if( rc ) goto abort_due_to_error; + + /* Initialize sqlite3_vtab_cursor base class */ + pVCur->pVtab = pVtab; + + /* Initialize vdbe cursor object */ + pCur = allocateCursor(p, pOp->p1, 0, CURTYPE_VTAB); + if( pCur ){ + pCur->uc.pVCur = pVCur; + pVtab->nRef++; + }else{ + assert( db->mallocFailed ); + pModule->xClose(pVCur); + goto no_mem; + } + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VCheck P1 P2 P3 P4 * +** +** P4 is a pointer to a Table object that is a virtual table in schema P1 +** that supports the xIntegrity() method. This opcode runs the xIntegrity() +** method for that virtual table, using P3 as the integer argument. If +** an error is reported back, the table name is prepended to the error +** message and that message is stored in P2. If no errors are seen, +** register P2 is set to NULL. +*/ +case OP_VCheck: { /* out2 */ + Table *pTab; + sqlite3_vtab *pVtab; + const sqlite3_module *pModule; + char *zErr = 0; + + pOut = &aMem[pOp->p2]; + sqlite3VdbeMemSetNull(pOut); /* Innocent until proven guilty */ + assert( pOp->p4type==P4_TABLEREF ); + pTab = pOp->p4.pTab; + assert( pTab!=0 ); + assert( pTab->nTabRef>0 ); + assert( IsVirtual(pTab) ); + if( pTab->u.vtab.p==0 ) break; + pVtab = pTab->u.vtab.p->pVtab; + assert( pVtab!=0 ); + pModule = pVtab->pModule; + assert( pModule!=0 ); + assert( pModule->iVersion>=4 ); + assert( pModule->xIntegrity!=0 ); + sqlite3VtabLock(pTab->u.vtab.p); + assert( pOp->p1>=0 && pOp->p1nDb ); + rc = pModule->xIntegrity(pVtab, db->aDb[pOp->p1].zDbSName, pTab->zName, + pOp->p3, &zErr); + sqlite3VtabUnlock(pTab->u.vtab.p); + if( rc ){ + sqlite3_free(zErr); + goto abort_due_to_error; + } + if( zErr ){ + sqlite3VdbeMemSetStr(pOut, zErr, -1, SQLITE_UTF8, sqlite3_free); + } + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VInitIn P1 P2 P3 * * +** Synopsis: r[P2]=ValueList(P1,P3) +** +** Set register P2 to be a pointer to a ValueList object for cursor P1 +** with cache register P3 and output register P3+1. This ValueList object +** can be used as the first argument to sqlite3_vtab_in_first() and +** sqlite3_vtab_in_next() to extract all of the values stored in the P1 +** cursor. Register P3 is used to hold the values returned by +** sqlite3_vtab_in_first() and sqlite3_vtab_in_next(). +*/ +case OP_VInitIn: { /* out2, ncycle */ + VdbeCursor *pC; /* The cursor containing the RHS values */ + ValueList *pRhs; /* New ValueList object to put in reg[P2] */ + + pC = p->apCsr[pOp->p1]; + pRhs = sqlite3_malloc64( sizeof(*pRhs) ); + if( pRhs==0 ) goto no_mem; + pRhs->pCsr = pC->uc.pCursor; + pRhs->pOut = &aMem[pOp->p3]; + pOut = out2Prerelease(p, pOp); + pOut->flags = MEM_Null; + sqlite3VdbeMemSetPointer(pOut, pRhs, "ValueList", sqlite3VdbeValueListFree); + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VFilter P1 P2 P3 P4 * +** Synopsis: iplan=r[P3] zplan='P4' +** +** P1 is a cursor opened using VOpen. P2 is an address to jump to if +** the filtered result set is empty. +** +** P4 is either NULL or a string that was generated by the xBestIndex +** method of the module. The interpretation of the P4 string is left +** to the module implementation. +** +** This opcode invokes the xFilter method on the virtual table specified +** by P1. The integer query plan parameter to xFilter is stored in register +** P3. Register P3+1 stores the argc parameter to be passed to the +** xFilter method. Registers P3+2..P3+1+argc are the argc +** additional parameters which are passed to +** xFilter as argv. Register P3+2 becomes argv[0] when passed to xFilter. +** +** A jump is made to P2 if the result set after filtering would be empty. +*/ +case OP_VFilter: { /* jump, ncycle */ + int nArg; + int iQuery; + const sqlite3_module *pModule; + Mem *pQuery; + Mem *pArgc; + sqlite3_vtab_cursor *pVCur; + sqlite3_vtab *pVtab; + VdbeCursor *pCur; + int res; + int i; + Mem **apArg; + + pQuery = &aMem[pOp->p3]; + pArgc = &pQuery[1]; + pCur = p->apCsr[pOp->p1]; + assert( memIsValid(pQuery) ); + REGISTER_TRACE(pOp->p3, pQuery); + assert( pCur!=0 ); + assert( pCur->eCurType==CURTYPE_VTAB ); + pVCur = pCur->uc.pVCur; + pVtab = pVCur->pVtab; + pModule = pVtab->pModule; + + /* Grab the index number and argc parameters */ + assert( (pQuery->flags&MEM_Int)!=0 && pArgc->flags==MEM_Int ); + nArg = (int)pArgc->u.i; + iQuery = (int)pQuery->u.i; + + /* Invoke the xFilter method */ + apArg = p->apArg; + assert( nArg<=p->napArg ); + for(i = 0; ixFilter(pVCur, iQuery, pOp->p4.z, nArg, apArg); + sqlite3VtabImportErrmsg(p, pVtab); + if( rc ) goto abort_due_to_error; + res = pModule->xEof(pVCur); + pCur->nullRow = 0; + VdbeBranchTaken(res!=0,2); + if( res ) goto jump_to_p2; + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VColumn P1 P2 P3 * P5 +** Synopsis: r[P3]=vcolumn(P2) +** +** Store in register P3 the value of the P2-th column of +** the current row of the virtual-table of cursor P1. +** +** If the VColumn opcode is being used to fetch the value of +** an unchanging column during an UPDATE operation, then the P5 +** value is OPFLAG_NOCHNG. This will cause the sqlite3_vtab_nochange() +** function to return true inside the xColumn method of the virtual +** table implementation. The P5 column might also contain other +** bits (OPFLAG_LENGTHARG or OPFLAG_TYPEOFARG) but those bits are +** unused by OP_VColumn. +*/ +case OP_VColumn: { /* ncycle */ + sqlite3_vtab *pVtab; + const sqlite3_module *pModule; + Mem *pDest; + sqlite3_context sContext; + FuncDef nullFunc; + + VdbeCursor *pCur = p->apCsr[pOp->p1]; + assert( pCur!=0 ); + assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); + pDest = &aMem[pOp->p3]; + memAboutToChange(p, pDest); + if( pCur->nullRow ){ + sqlite3VdbeMemSetNull(pDest); + break; + } + assert( pCur->eCurType==CURTYPE_VTAB ); + pVtab = pCur->uc.pVCur->pVtab; + pModule = pVtab->pModule; + assert( pModule->xColumn ); + memset(&sContext, 0, sizeof(sContext)); + sContext.pOut = pDest; + sContext.enc = encoding; + nullFunc.pUserData = 0; + nullFunc.funcFlags = SQLITE_RESULT_SUBTYPE; + sContext.pFunc = &nullFunc; + assert( pOp->p5==OPFLAG_NOCHNG || pOp->p5==0 ); + if( pOp->p5 & OPFLAG_NOCHNG ){ + sqlite3VdbeMemSetNull(pDest); + pDest->flags = MEM_Null|MEM_Zero; + pDest->u.nZero = 0; + }else{ + MemSetTypeFlag(pDest, MEM_Null); + } + rc = pModule->xColumn(pCur->uc.pVCur, &sContext, pOp->p2); + sqlite3VtabImportErrmsg(p, pVtab); + if( sContext.isError>0 ){ + sqlite3VdbeError(p, "%s", sqlite3_value_text(pDest)); + rc = sContext.isError; + } + sqlite3VdbeChangeEncoding(pDest, encoding); + REGISTER_TRACE(pOp->p3, pDest); + UPDATE_MAX_BLOBSIZE(pDest); + + if( rc ) goto abort_due_to_error; + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VNext P1 P2 * * * +** +** Advance virtual table P1 to the next row in its result set and +** jump to instruction P2. Or, if the virtual table has reached +** the end of its result set, then fall through to the next instruction. +*/ +case OP_VNext: { /* jump, ncycle */ + sqlite3_vtab *pVtab; + const sqlite3_module *pModule; + int res; + VdbeCursor *pCur; + + pCur = p->apCsr[pOp->p1]; + assert( pCur!=0 ); + assert( pCur->eCurType==CURTYPE_VTAB ); + if( pCur->nullRow ){ + break; + } + pVtab = pCur->uc.pVCur->pVtab; + pModule = pVtab->pModule; + assert( pModule->xNext ); + + /* Invoke the xNext() method of the module. There is no way for the + ** underlying implementation to return an error if one occurs during + ** xNext(). Instead, if an error occurs, true is returned (indicating that + ** data is available) and the error code returned when xColumn or + ** some other method is next invoked on the save virtual table cursor. + */ + rc = pModule->xNext(pCur->uc.pVCur); + sqlite3VtabImportErrmsg(p, pVtab); + if( rc ) goto abort_due_to_error; + res = pModule->xEof(pCur->uc.pVCur); + VdbeBranchTaken(!res,2); + if( !res ){ + /* If there is data, jump to P2 */ + goto jump_to_p2_and_check_for_interrupt; + } + goto check_for_interrupt; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VRename P1 * * P4 * +** +** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. +** This opcode invokes the corresponding xRename method. The value +** in register P1 is passed as the zName argument to the xRename method. +*/ +case OP_VRename: { + sqlite3_vtab *pVtab; + Mem *pName; + int isLegacy; + + isLegacy = (db->flags & SQLITE_LegacyAlter); + db->flags |= SQLITE_LegacyAlter; + pVtab = pOp->p4.pVtab->pVtab; + pName = &aMem[pOp->p1]; + assert( pVtab->pModule->xRename ); + assert( memIsValid(pName) ); + assert( p->readOnly==0 ); + REGISTER_TRACE(pOp->p1, pName); + assert( pName->flags & MEM_Str ); + testcase( pName->enc==SQLITE_UTF8 ); + testcase( pName->enc==SQLITE_UTF16BE ); + testcase( pName->enc==SQLITE_UTF16LE ); + rc = sqlite3VdbeChangeEncoding(pName, SQLITE_UTF8); + if( rc ) goto abort_due_to_error; + rc = pVtab->pModule->xRename(pVtab, pName->z); + if( isLegacy==0 ) db->flags &= ~(u64)SQLITE_LegacyAlter; + sqlite3VtabImportErrmsg(p, pVtab); + p->expired = 0; + if( rc ) goto abort_due_to_error; + break; +} +#endif + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VUpdate P1 P2 P3 P4 P5 +** Synopsis: data=r[P3@P2] +** +** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. +** This opcode invokes the corresponding xUpdate method. P2 values +** are contiguous memory cells starting at P3 to pass to the xUpdate +** invocation. The value in register (P3+P2-1) corresponds to the +** p2th element of the argv array passed to xUpdate. +** +** The xUpdate method will do a DELETE or an INSERT or both. +** The argv[0] element (which corresponds to memory cell P3) +** is the rowid of a row to delete. If argv[0] is NULL then no +** deletion occurs. The argv[1] element is the rowid of the new +** row. This can be NULL to have the virtual table select the new +** rowid for itself. The subsequent elements in the array are +** the values of columns in the new row. +** +** If P2==1 then no insert is performed. argv[0] is the rowid of +** a row to delete. +** +** P1 is a boolean flag. If it is set to true and the xUpdate call +** is successful, then the value returned by sqlite3_last_insert_rowid() +** is set to the value of the rowid for the row just inserted. +** +** P5 is the error actions (OE_Replace, OE_Fail, OE_Ignore, etc) to +** apply in the case of a constraint failure on an insert or update. +*/ +case OP_VUpdate: { + sqlite3_vtab *pVtab; + const sqlite3_module *pModule; + int nArg; + int i; + sqlite_int64 rowid = 0; + Mem **apArg; + Mem *pX; + + assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback + || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace + ); + assert( p->readOnly==0 ); + if( db->mallocFailed ) goto no_mem; + sqlite3VdbeIncrWriteCounter(p, 0); + pVtab = pOp->p4.pVtab->pVtab; + if( pVtab==0 || NEVER(pVtab->pModule==0) ){ + rc = SQLITE_LOCKED; + goto abort_due_to_error; + } + pModule = pVtab->pModule; + nArg = pOp->p2; + assert( pOp->p4type==P4_VTAB ); + if( ALWAYS(pModule->xUpdate) ){ + u8 vtabOnConflict = db->vtabOnConflict; + apArg = p->apArg; + pX = &aMem[pOp->p3]; + assert( nArg<=p->napArg ); + for(i=0; ivtabOnConflict = pOp->p5; + rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid); + db->vtabOnConflict = vtabOnConflict; + sqlite3VtabImportErrmsg(p, pVtab); + if( rc==SQLITE_OK && pOp->p1 ){ + assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) ); + db->lastRowid = rowid; + } + if( (rc&0xff)==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){ + if( pOp->p5==OE_Ignore ){ + rc = SQLITE_OK; + }else{ + p->errorAction = ((pOp->p5==OE_Replace) ? OE_Abort : pOp->p5); + } + }else{ + p->nChange++; + } + if( rc ) goto abort_due_to_error; + } + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +/* Opcode: Pagecount P1 P2 * * * +** +** Write the current number of pages in database P1 to memory cell P2. +*/ +case OP_Pagecount: { /* out2 */ + pOut = out2Prerelease(p, pOp); + pOut->u.i = sqlite3BtreeLastPage(db->aDb[pOp->p1].pBt); + break; +} +#endif + + +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +/* Opcode: MaxPgcnt P1 P2 P3 * * +** +** Try to set the maximum page count for database P1 to the value in P3. +** Do not let the maximum page count fall below the current page count and +** do not change the maximum page count value if P3==0. +** +** Store the maximum page count after the change in register P2. +*/ +case OP_MaxPgcnt: { /* out2 */ + unsigned int newMax; + Btree *pBt; + + pOut = out2Prerelease(p, pOp); + pBt = db->aDb[pOp->p1].pBt; + newMax = 0; + if( pOp->p3 ){ + newMax = sqlite3BtreeLastPage(pBt); + if( newMax < (unsigned)pOp->p3 ) newMax = (unsigned)pOp->p3; + } + pOut->u.i = sqlite3BtreeMaxPageCount(pBt, newMax); + break; +} +#endif + +/* Opcode: Function P1 P2 P3 P4 * +** Synopsis: r[P3]=func(r[P2@NP]) +** +** Invoke a user function (P4 is a pointer to an sqlite3_context object that +** contains a pointer to the function to be run) with arguments taken +** from register P2 and successors. The number of arguments is in +** the sqlite3_context object that P4 points to. +** The result of the function is stored +** in register P3. Register P3 must not be one of the function inputs. +** +** P1 is a 32-bit bitmask indicating whether or not each argument to the +** function was determined to be constant at compile time. If the first +** argument was constant then bit 0 of P1 is set. This is used to determine +** whether meta data associated with a user function argument using the +** sqlite3_set_auxdata() API may be safely retained until the next +** invocation of this opcode. +** +** See also: AggStep, AggFinal, PureFunc +*/ +/* Opcode: PureFunc P1 P2 P3 P4 * +** Synopsis: r[P3]=func(r[P2@NP]) +** +** Invoke a user function (P4 is a pointer to an sqlite3_context object that +** contains a pointer to the function to be run) with arguments taken +** from register P2 and successors. The number of arguments is in +** the sqlite3_context object that P4 points to. +** The result of the function is stored +** in register P3. Register P3 must not be one of the function inputs. +** +** P1 is a 32-bit bitmask indicating whether or not each argument to the +** function was determined to be constant at compile time. If the first +** argument was constant then bit 0 of P1 is set. This is used to determine +** whether meta data associated with a user function argument using the +** sqlite3_set_auxdata() API may be safely retained until the next +** invocation of this opcode. +** +** This opcode works exactly like OP_Function. The only difference is in +** its name. This opcode is used in places where the function must be +** purely non-deterministic. Some built-in date/time functions can be +** either deterministic of non-deterministic, depending on their arguments. +** When those function are used in a non-deterministic way, they will check +** to see if they were called using OP_PureFunc instead of OP_Function, and +** if they were, they throw an error. +** +** See also: AggStep, AggFinal, Function +*/ +case OP_PureFunc: /* group */ +case OP_Function: { /* group */ + int i; + sqlite3_context *pCtx; + + assert( pOp->p4type==P4_FUNCCTX ); + pCtx = pOp->p4.pCtx; + + /* If this function is inside of a trigger, the register array in aMem[] + ** might change from one evaluation to the next. The next block of code + ** checks to see if the register array has changed, and if so it + ** reinitializes the relevant parts of the sqlite3_context object */ + pOut = &aMem[pOp->p3]; + if( pCtx->pOut != pOut ){ + pCtx->pVdbe = p; + pCtx->pOut = pOut; + pCtx->enc = encoding; + for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i]; + } + assert( pCtx->pVdbe==p ); + + memAboutToChange(p, pOut); +#ifdef SQLITE_DEBUG + for(i=0; iargc; i++){ + assert( memIsValid(pCtx->argv[i]) ); + REGISTER_TRACE(pOp->p2+i, pCtx->argv[i]); + } +#endif + MemSetTypeFlag(pOut, MEM_Null); + assert( pCtx->isError==0 ); + (*pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/* IMP: R-24505-23230 */ + + /* If the function returned an error, throw an exception */ + if( pCtx->isError ){ + if( pCtx->isError>0 ){ + sqlite3VdbeError(p, "%s", sqlite3_value_text(pOut)); + rc = pCtx->isError; + } + sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1); + pCtx->isError = 0; + if( rc ) goto abort_due_to_error; + } + + assert( (pOut->flags&MEM_Str)==0 + || pOut->enc==encoding + || db->mallocFailed ); + assert( !sqlite3VdbeMemTooBig(pOut) ); + + REGISTER_TRACE(pOp->p3, pOut); + UPDATE_MAX_BLOBSIZE(pOut); + break; +} + +/* Opcode: ClrSubtype P1 * * * * +** Synopsis: r[P1].subtype = 0 +** +** Clear the subtype from register P1. +*/ +case OP_ClrSubtype: { /* in1 */ + pIn1 = &aMem[pOp->p1]; + pIn1->flags &= ~MEM_Subtype; + break; +} + +/* Opcode: GetSubtype P1 P2 * * * +** Synopsis: r[P2] = r[P1].subtype +** +** Extract the subtype value from register P1 and write that subtype +** into register P2. If P1 has no subtype, then P1 gets a NULL. +*/ +case OP_GetSubtype: { /* in1 out2 */ + pIn1 = &aMem[pOp->p1]; + pOut = &aMem[pOp->p2]; + if( pIn1->flags & MEM_Subtype ){ + sqlite3VdbeMemSetInt64(pOut, pIn1->eSubtype); + }else{ + sqlite3VdbeMemSetNull(pOut); + } + break; +} + +/* Opcode: SetSubtype P1 P2 * * * +** Synopsis: r[P2].subtype = r[P1] +** +** Set the subtype value of register P2 to the integer from register P1. +** If P1 is NULL, clear the subtype from p2. +*/ +case OP_SetSubtype: { /* in1 out2 */ + pIn1 = &aMem[pOp->p1]; + pOut = &aMem[pOp->p2]; + if( pIn1->flags & MEM_Null ){ + pOut->flags &= ~MEM_Subtype; + }else{ + assert( pIn1->flags & MEM_Int ); + pOut->flags |= MEM_Subtype; + pOut->eSubtype = (u8)(pIn1->u.i & 0xff); + } + break; +} + +/* Opcode: FilterAdd P1 * P3 P4 * +** Synopsis: filter(P1) += key(P3@P4) +** +** Compute a hash on the P4 registers starting with r[P3] and +** add that hash to the bloom filter contained in r[P1]. +*/ +case OP_FilterAdd: { + u64 h; + + assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); + pIn1 = &aMem[pOp->p1]; + assert( pIn1->flags & MEM_Blob ); + assert( pIn1->n>0 ); + h = filterHash(aMem, pOp); +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + int ii; + for(ii=pOp->p3; iip3+pOp->p4.i; ii++){ + registerTrace(ii, &aMem[ii]); + } + printf("hash: %llu modulo %d -> %u\n", h, pIn1->n, (int)(h%pIn1->n)); + } +#endif + h %= (pIn1->n*8); + pIn1->z[h/8] |= 1<<(h&7); + break; +} + +/* Opcode: Filter P1 P2 P3 P4 * +** Synopsis: if key(P3@P4) not in filter(P1) goto P2 +** +** Compute a hash on the key contained in the P4 registers starting +** with r[P3]. Check to see if that hash is found in the +** bloom filter hosted by register P1. If it is not present then +** maybe jump to P2. Otherwise fall through. +** +** False negatives are harmless. It is always safe to fall through, +** even if the value is in the bloom filter. A false negative causes +** more CPU cycles to be used, but it should still yield the correct +** answer. However, an incorrect answer may well arise from a +** false positive - if the jump is taken when it should fall through. +*/ +case OP_Filter: { /* jump */ + u64 h; + + assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); + pIn1 = &aMem[pOp->p1]; + assert( (pIn1->flags & MEM_Blob)!=0 ); + assert( pIn1->n >= 1 ); + h = filterHash(aMem, pOp); +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + int ii; + for(ii=pOp->p3; iip3+pOp->p4.i; ii++){ + registerTrace(ii, &aMem[ii]); + } + printf("hash: %llu modulo %d -> %u\n", h, pIn1->n, (int)(h%pIn1->n)); + } +#endif + h %= (pIn1->n*8); + if( (pIn1->z[h/8] & (1<<(h&7)))==0 ){ + VdbeBranchTaken(1, 2); + p->aCounter[SQLITE_STMTSTATUS_FILTER_HIT]++; + goto jump_to_p2; + }else{ + p->aCounter[SQLITE_STMTSTATUS_FILTER_MISS]++; + VdbeBranchTaken(0, 2); + } + break; +} + +/* Opcode: Trace P1 P2 * P4 * +** +** Write P4 on the statement trace output if statement tracing is +** enabled. +** +** Operand P1 must be 0x7fffffff and P2 must positive. +*/ +/* Opcode: Init P1 P2 P3 P4 * +** Synopsis: Start at P2 +** +** Programs contain a single instance of this opcode as the very first +** opcode. +** +** If tracing is enabled (by the sqlite3_trace()) interface, then +** the UTF-8 string contained in P4 is emitted on the trace callback. +** Or if P4 is blank, use the string returned by sqlite3_sql(). +** +** If P2 is not zero, jump to instruction P2. +** +** Increment the value of P1 so that OP_Once opcodes will jump the +** first time they are evaluated for this run. +** +** If P3 is not zero, then it is an address to jump to if an SQLITE_CORRUPT +** error is encountered. +*/ +case OP_Trace: +case OP_Init: { /* jump0 */ + int i; +#ifndef SQLITE_OMIT_TRACE + char *zTrace; +#endif + + /* If the P4 argument is not NULL, then it must be an SQL comment string. + ** The "--" string is broken up to prevent false-positives with srcck1.c. + ** + ** This assert() provides evidence for: + ** EVIDENCE-OF: R-50676-09860 The callback can compute the same text that + ** would have been returned by the legacy sqlite3_trace() interface by + ** using the X argument when X begins with "--" and invoking + ** sqlite3_expanded_sql(P) otherwise. + */ + assert( pOp->p4.z==0 || strncmp(pOp->p4.z, "-" "- ", 3)==0 ); + + /* OP_Init is always instruction 0 */ + assert( pOp==p->aOp || pOp->opcode==OP_Trace ); + +#ifndef SQLITE_OMIT_TRACE + if( (db->mTrace & (SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0 + && p->minWriteFileFormat!=254 /* tag-20220401a */ + && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 + ){ +#ifndef SQLITE_OMIT_DEPRECATED + if( db->mTrace & SQLITE_TRACE_LEGACY ){ + char *z = sqlite3VdbeExpandSql(p, zTrace); + db->trace.xLegacy(db->pTraceArg, z); + sqlite3_free(z); + }else +#endif + if( db->nVdbeExec>1 ){ + char *z = sqlite3MPrintf(db, "-- %s", zTrace); + (void)db->trace.xV2(SQLITE_TRACE_STMT, db->pTraceArg, p, z); + sqlite3DbFree(db, z); + }else{ + (void)db->trace.xV2(SQLITE_TRACE_STMT, db->pTraceArg, p, zTrace); + } + } +#ifdef SQLITE_USE_FCNTL_TRACE + zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); + if( zTrace ){ + int j; + for(j=0; jnDb; j++){ + if( DbMaskTest(p->btreeMask, j)==0 ) continue; + sqlite3_file_control(db, db->aDb[j].zDbSName, SQLITE_FCNTL_TRACE, zTrace); + } + } +#endif /* SQLITE_USE_FCNTL_TRACE */ +#ifdef SQLITE_DEBUG + if( (db->flags & SQLITE_SqlTrace)!=0 + && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 + ){ + sqlite3DebugPrintf("SQL-trace: %s\n", zTrace); + } +#endif /* SQLITE_DEBUG */ +#endif /* SQLITE_OMIT_TRACE */ + assert( pOp->p2>0 ); + if( pOp->p1>=sqlite3GlobalConfig.iOnceResetThreshold ){ + if( pOp->opcode==OP_Trace ) break; + for(i=1; inOp; i++){ + if( p->aOp[i].opcode==OP_Once ) p->aOp[i].p1 = 0; + } + pOp->p1 = 0; + } + pOp->p1++; + p->aCounter[SQLITE_STMTSTATUS_RUN]++; + goto jump_to_p2; +} + +#ifdef SQLITE_ENABLE_CURSOR_HINTS +/* Opcode: CursorHint P1 * * P4 * +** +** Provide a hint to cursor P1 that it only needs to return rows that +** satisfy the Expr in P4. TK_REGISTER terms in the P4 expression refer +** to values currently held in registers. TK_COLUMN terms in the P4 +** expression refer to columns in the b-tree to which cursor P1 is pointing. +*/ +case OP_CursorHint: { + VdbeCursor *pC; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( pOp->p4type==P4_EXPR ); + pC = p->apCsr[pOp->p1]; + if( pC ){ + assert( pC->eCurType==CURTYPE_BTREE ); + sqlite3BtreeCursorHint(pC->uc.pCursor, BTREE_HINT_RANGE, + pOp->p4.pExpr, aMem); + } + break; +} +#endif /* SQLITE_ENABLE_CURSOR_HINTS */ + +#ifdef SQLITE_DEBUG +/* Opcode: Abortable * * * * * +** +** Verify that an Abort can happen. Assert if an Abort at this point +** might cause database corruption. This opcode only appears in debugging +** builds. +** +** An Abort is safe if either there have been no writes, or if there is +** an active statement journal. +*/ +case OP_Abortable: { + sqlite3VdbeAssertAbortable(p); + break; +} +#endif + +#ifdef SQLITE_DEBUG +/* Opcode: ReleaseReg P1 P2 P3 * P5 +** Synopsis: release r[P1@P2] mask P3 +** +** Release registers from service. Any content that was in the +** the registers is unreliable after this opcode completes. +** +** The registers released will be the P2 registers starting at P1, +** except if bit ii of P3 set, then do not release register P1+ii. +** In other words, P3 is a mask of registers to preserve. +** +** Releasing a register clears the Mem.pScopyFrom pointer. That means +** that if the content of the released register was set using OP_SCopy, +** a change to the value of the source register for the OP_SCopy will no longer +** generate an assertion fault in sqlite3VdbeMemAboutToChange(). +** +** If P5 is set, then all released registers have their type set +** to MEM_Undefined so that any subsequent attempt to read the released +** register (before it is reinitialized) will generate an assertion fault. +** +** P5 ought to be set on every call to this opcode. +** However, there are places in the code generator will release registers +** before their are used, under the (valid) assumption that the registers +** will not be reallocated for some other purpose before they are used and +** hence are safe to release. +** +** This opcode is only available in testing and debugging builds. It is +** not generated for release builds. The purpose of this opcode is to help +** validate the generated bytecode. This opcode does not actually contribute +** to computing an answer. +*/ +case OP_ReleaseReg: { + Mem *pMem; + int i; + u32 constMask; + assert( pOp->p1>0 ); + assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 ); + pMem = &aMem[pOp->p1]; + constMask = pOp->p3; + for(i=0; ip2; i++, pMem++){ + if( i>=32 || (constMask & MASKBIT32(i))==0 ){ + pMem->pScopyFrom = 0; + if( i<32 && pOp->p5 ) MemSetTypeFlag(pMem, MEM_Undefined); + } + } + break; +} +#endif + +/* Opcode: Noop * * * * * +** +** Do nothing. Continue downward to the next opcode. +*/ +/* Opcode: Explain P1 P2 P3 P4 * +** +** This is the same as OP_Noop during normal query execution. The +** purpose of this opcode is to hold information about the query +** plan for the purpose of EXPLAIN QUERY PLAN output. +** +** The P4 value is human-readable text that describes the query plan +** element. Something like "SCAN t1" or "SEARCH t2 USING INDEX t2x1". +** +** The P1 value is the ID of the current element and P2 is the parent +** element for the case of nested query plan elements. If P2 is zero +** then this element is a top-level element. +** +** For loop elements, P3 is the estimated code of each invocation of this +** element. +** +** As with all opcodes, the meanings of the parameters for OP_Explain +** are subject to change from one release to the next. Applications +** should not attempt to interpret or use any of the information +** contained in the OP_Explain opcode. The information provided by this +** opcode is intended for testing and debugging use only. +*/ +default: { /* This is really OP_Noop, OP_Explain */ + assert( pOp->opcode==OP_Noop || pOp->opcode==OP_Explain ); + + break; +} + +/***************************************************************************** +** The cases of the switch statement above this line should all be indented +** by 6 spaces. But the left-most 6 spaces have been removed to improve the +** readability. From this point on down, the normal indentation rules are +** restored. +*****************************************************************************/ + } + +#if defined(VDBE_PROFILE) + *pnCycle += sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime(); + pnCycle = 0; +#elif defined(SQLITE_ENABLE_STMT_SCANSTATUS) + if( pnCycle ){ + *pnCycle += sqlite3Hwtime(); + pnCycle = 0; + } +#endif + + /* The following code adds nothing to the actual functionality + ** of the program. It is only here for testing and debugging. + ** On the other hand, it does burn CPU cycles every time through + ** the evaluator loop. So we can leave it out when NDEBUG is defined. + */ +#ifndef NDEBUG + assert( pOp>=&aOp[-1] && pOp<&aOp[p->nOp-1] ); + +#ifdef SQLITE_DEBUG + if( db->flags & SQLITE_VdbeTrace ){ + u8 opProperty = sqlite3OpcodeProperty[pOrigOp->opcode]; + if( rc!=0 ) printf("rc=%d\n",rc); + if( opProperty & (OPFLG_OUT2) ){ + registerTrace(pOrigOp->p2, &aMem[pOrigOp->p2]); + } + if( opProperty & OPFLG_OUT3 ){ + registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]); + } + if( opProperty==0xff ){ + /* Never happens. This code exists to avoid a harmless linkage + ** warning about sqlite3VdbeRegisterDump() being defined but not + ** used. */ + sqlite3VdbeRegisterDump(p); + } + } +#endif /* SQLITE_DEBUG */ +#endif /* NDEBUG */ + } /* The end of the for(;;) loop the loops through opcodes */ + + /* If we reach this point, it means that execution is finished with + ** an error of some kind. + */ +abort_due_to_error: + if( db->mallocFailed ){ + rc = SQLITE_NOMEM_BKPT; + }else if( rc==SQLITE_IOERR_CORRUPTFS ){ + rc = SQLITE_CORRUPT_BKPT; + } + assert( rc ); +#ifdef SQLITE_DEBUG + if( db->flags & SQLITE_VdbeTrace ){ + const char *zTrace = p->zSql; + if( zTrace==0 ){ + if( aOp[0].opcode==OP_Trace ){ + zTrace = aOp[0].p4.z; + } + if( zTrace==0 ) zTrace = "???"; + } + printf("ABORT-due-to-error (rc=%d): %s\n", rc, zTrace); + } +#endif + if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){ + sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc)); + } + p->rc = rc; + sqlite3SystemError(db, rc); + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3VdbeLogAbort(p, rc, pOp, aOp); + if( p->eVdbeState==VDBE_RUN_STATE ) sqlite3VdbeHalt(p); + if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db); + if( rc==SQLITE_CORRUPT && db->autoCommit==0 ){ + db->flags |= SQLITE_CorruptRdOnly; + } + rc = SQLITE_ERROR; + if( resetSchemaOnFault>0 ){ + sqlite3ResetOneSchema(db, resetSchemaOnFault-1); + } + + /* This is the only way out of this procedure. We have to + ** release the mutexes on btrees that were acquired at the + ** top. */ +vdbe_return: +#if defined(VDBE_PROFILE) + if( pnCycle ){ + *pnCycle += sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime(); + pnCycle = 0; + } +#elif defined(SQLITE_ENABLE_STMT_SCANSTATUS) + if( pnCycle ){ + *pnCycle += sqlite3Hwtime(); + pnCycle = 0; + } +#endif + +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + while( nVmStep>=nProgressLimit && db->xProgress!=0 ){ + nProgressLimit += db->nProgressOps; + if( db->xProgress(db->pProgressArg) ){ + nProgressLimit = LARGEST_UINT64; + rc = SQLITE_INTERRUPT; + goto abort_due_to_error; + } + } +#endif + p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep; + if( DbMaskNonZero(p->lockMask) ){ + sqlite3VdbeLeave(p); + } + assert( rc!=SQLITE_OK || nExtraDelete==0 + || sqlite3_strlike("DELETE%",p->zSql,0)!=0 + ); + return rc; + + /* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH + ** is encountered. + */ +too_big: + sqlite3VdbeError(p, "string or blob too big"); + rc = SQLITE_TOOBIG; + goto abort_due_to_error; + + /* Jump to here if a malloc() fails. + */ +no_mem: + sqlite3OomFault(db); + sqlite3VdbeError(p, "out of memory"); + rc = SQLITE_NOMEM_BKPT; + goto abort_due_to_error; + + /* Jump to here if the sqlite3_interrupt() API sets the interrupt + ** flag. + */ +abort_due_to_interrupt: + assert( AtomicLoad(&db->u1.isInterrupted) ); + rc = SQLITE_INTERRUPT; + goto abort_due_to_error; +} + + +/************** End of vdbe.c ************************************************/ +/************** Begin file vdbeblob.c ****************************************/ +/* +** 2007 May 1 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains code used to implement incremental BLOB I/O. +*/ + +/* #include "sqliteInt.h" */ +/* #include "vdbeInt.h" */ + +#ifndef SQLITE_OMIT_INCRBLOB + +/* +** Valid sqlite3_blob* handles point to Incrblob structures. +*/ +typedef struct Incrblob Incrblob; +struct Incrblob { + int nByte; /* Size of open blob, in bytes */ + int iOffset; /* Byte offset of blob in cursor data */ + u16 iCol; /* Table column this handle is open on */ + BtCursor *pCsr; /* Cursor pointing at blob row */ + sqlite3_stmt *pStmt; /* Statement holding cursor open */ + sqlite3 *db; /* The associated database */ + char *zDb; /* Database name */ + Table *pTab; /* Table object */ +}; + + +/* +** This function is used by both blob_open() and blob_reopen(). It seeks +** the b-tree cursor associated with blob handle p to point to row iRow. +** If successful, SQLITE_OK is returned and subsequent calls to +** sqlite3_blob_read() or sqlite3_blob_write() access the specified row. +** +** If an error occurs, or if the specified row does not exist or does not +** contain a value of type TEXT or BLOB in the column nominated when the +** blob handle was opened, then an error code is returned and *pzErr may +** be set to point to a buffer containing an error message. It is the +** responsibility of the caller to free the error message buffer using +** sqlite3DbFree(). +** +** If an error does occur, then the b-tree cursor is closed. All subsequent +** calls to sqlite3_blob_read(), blob_write() or blob_reopen() will +** immediately return SQLITE_ABORT. +*/ +static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){ + int rc; /* Error code */ + char *zErr = 0; /* Error message */ + Vdbe *v = (Vdbe *)p->pStmt; + + /* Set the value of register r[1] in the SQL statement to integer iRow. + ** This is done directly as a performance optimization + */ + sqlite3VdbeMemSetInt64(&v->aMem[1], iRow); + + /* If the statement has been run before (and is paused at the OP_ResultRow) + ** then back it up to the point where it does the OP_NotExists. This could + ** have been down with an extra OP_Goto, but simply setting the program + ** counter is faster. */ + if( v->pc>4 ){ + v->pc = 4; + assert( v->aOp[v->pc].opcode==OP_NotExists ); + rc = sqlite3VdbeExec(v); + }else{ + rc = sqlite3_step(p->pStmt); + } + if( rc==SQLITE_ROW ){ + VdbeCursor *pC = v->apCsr[0]; + u32 type; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + type = pC->nHdrParsed>p->iCol ? pC->aType[p->iCol] : 0; + testcase( pC->nHdrParsed==p->iCol ); + testcase( pC->nHdrParsed==p->iCol+1 ); + if( type<12 ){ + zErr = sqlite3MPrintf(p->db, "cannot open value of type %s", + type==0?"null": type==7?"real": "integer" + ); + rc = SQLITE_ERROR; + sqlite3_finalize(p->pStmt); + p->pStmt = 0; + }else{ + p->iOffset = pC->aType[p->iCol + pC->nField]; + p->nByte = sqlite3VdbeSerialTypeLen(type); + p->pCsr = pC->uc.pCursor; + sqlite3BtreeIncrblobCursor(p->pCsr); + } + } + + if( rc==SQLITE_ROW ){ + rc = SQLITE_OK; + }else if( p->pStmt ){ + rc = sqlite3_finalize(p->pStmt); + p->pStmt = 0; + if( rc==SQLITE_OK ){ + zErr = sqlite3MPrintf(p->db, "no such rowid: %lld", iRow); + rc = SQLITE_ERROR; + }else{ + zErr = sqlite3MPrintf(p->db, "%s", sqlite3_errmsg(p->db)); + } + } + + assert( rc!=SQLITE_OK || zErr==0 ); + assert( rc!=SQLITE_ROW && rc!=SQLITE_DONE ); + + *pzErr = zErr; + return rc; +} + +/* +** Open a blob handle. +*/ +SQLITE_API int sqlite3_blob_open( + sqlite3* db, /* The database connection */ + const char *zDb, /* The attached database containing the blob */ + const char *zTable, /* The table containing the blob */ + const char *zColumn, /* The column containing the blob */ + sqlite_int64 iRow, /* The row containing the glob */ + int wrFlag, /* True -> read/write access, false -> read-only */ + sqlite3_blob **ppBlob /* Handle for accessing the blob returned here */ +){ + int nAttempt = 0; + int iCol; /* Index of zColumn in row-record */ + int rc = SQLITE_OK; + char *zErr = 0; + Table *pTab; + Incrblob *pBlob = 0; + int iDb; + Parse sParse; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( ppBlob==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + *ppBlob = 0; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zTable==0 || zColumn==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + wrFlag = !!wrFlag; /* wrFlag = (wrFlag ? 1 : 0); */ + + sqlite3_mutex_enter(db->mutex); + + pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob)); + while(1){ + sqlite3ParseObjectInit(&sParse,db); + if( !pBlob ) goto blob_open_out; + sqlite3DbFree(db, zErr); + zErr = 0; + + sqlite3BtreeEnterAll(db); + pTab = sqlite3LocateTable(&sParse, 0, zTable, zDb); + if( pTab && IsVirtual(pTab) ){ + pTab = 0; + sqlite3ErrorMsg(&sParse, "cannot open virtual table: %s", zTable); + } + if( pTab && !HasRowid(pTab) ){ + pTab = 0; + sqlite3ErrorMsg(&sParse, "cannot open table without rowid: %s", zTable); + } + if( pTab && (pTab->tabFlags&TF_HasGenerated)!=0 ){ + pTab = 0; + sqlite3ErrorMsg(&sParse, "cannot open table with generated columns: %s", + zTable); + } +#ifndef SQLITE_OMIT_VIEW + if( pTab && IsView(pTab) ){ + pTab = 0; + sqlite3ErrorMsg(&sParse, "cannot open view: %s", zTable); + } +#endif + if( pTab==0 + || ((iDb = sqlite3SchemaToIndex(db, pTab->pSchema))==1 && + sqlite3OpenTempDatabase(&sParse)) + ){ + if( sParse.zErrMsg ){ + sqlite3DbFree(db, zErr); + zErr = sParse.zErrMsg; + sParse.zErrMsg = 0; + } + rc = SQLITE_ERROR; + sqlite3BtreeLeaveAll(db); + goto blob_open_out; + } + pBlob->pTab = pTab; + pBlob->zDb = db->aDb[iDb].zDbSName; + + /* Now search pTab for the exact column. */ + iCol = sqlite3ColumnIndex(pTab, zColumn); + if( iCol<0 ){ + sqlite3DbFree(db, zErr); + zErr = sqlite3MPrintf(db, "no such column: \"%s\"", zColumn); + rc = SQLITE_ERROR; + sqlite3BtreeLeaveAll(db); + goto blob_open_out; + } + + /* If the value is being opened for writing, check that the + ** column is not indexed, and that it is not part of a foreign key. + */ + if( wrFlag ){ + const char *zFault = 0; + Index *pIdx; +#ifndef SQLITE_OMIT_FOREIGN_KEY + if( db->flags&SQLITE_ForeignKeys ){ + /* Check that the column is not part of an FK child key definition. It + ** is not necessary to check if it is part of a parent key, as parent + ** key columns must be indexed. The check below will pick up this + ** case. */ + FKey *pFKey; + assert( IsOrdinaryTable(pTab) ); + for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){ + int j; + for(j=0; jnCol; j++){ + if( pFKey->aCol[j].iFrom==iCol ){ + zFault = "foreign key"; + } + } + } + } +#endif + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + int j; + for(j=0; jnKeyCol; j++){ + /* FIXME: Be smarter about indexes that use expressions */ + if( pIdx->aiColumn[j]==iCol || pIdx->aiColumn[j]==XN_EXPR ){ + zFault = "indexed"; + } + } + } + if( zFault ){ + sqlite3DbFree(db, zErr); + zErr = sqlite3MPrintf(db, "cannot open %s column for writing", zFault); + rc = SQLITE_ERROR; + sqlite3BtreeLeaveAll(db); + goto blob_open_out; + } + } + + pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(&sParse); + assert( pBlob->pStmt || db->mallocFailed ); + if( pBlob->pStmt ){ + + /* This VDBE program seeks a btree cursor to the identified + ** db/table/row entry. The reason for using a vdbe program instead + ** of writing code to use the b-tree layer directly is that the + ** vdbe program will take advantage of the various transaction, + ** locking and error handling infrastructure built into the vdbe. + ** + ** After seeking the cursor, the vdbe executes an OP_ResultRow. + ** Code external to the Vdbe then "borrows" the b-tree cursor and + ** uses it to implement the blob_read(), blob_write() and + ** blob_bytes() functions. + ** + ** The sqlite3_blob_close() function finalizes the vdbe program, + ** which closes the b-tree cursor and (possibly) commits the + ** transaction. + */ + static const int iLn = VDBE_OFFSET_LINENO(2); + static const VdbeOpList openBlob[] = { + {OP_TableLock, 0, 0, 0}, /* 0: Acquire a read or write lock */ + {OP_OpenRead, 0, 0, 0}, /* 1: Open a cursor */ + /* blobSeekToRow() will initialize r[1] to the desired rowid */ + {OP_NotExists, 0, 5, 1}, /* 2: Seek the cursor to rowid=r[1] */ + {OP_Column, 0, 0, 1}, /* 3 */ + {OP_ResultRow, 1, 0, 0}, /* 4 */ + {OP_Halt, 0, 0, 0}, /* 5 */ + }; + Vdbe *v = (Vdbe *)pBlob->pStmt; + VdbeOp *aOp; + + sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, wrFlag, + pTab->pSchema->schema_cookie, + pTab->pSchema->iGeneration); + sqlite3VdbeChangeP5(v, 1); + assert( sqlite3VdbeCurrentAddr(v)==2 || db->mallocFailed ); + aOp = sqlite3VdbeAddOpList(v, ArraySize(openBlob), openBlob, iLn); + + /* Make sure a mutex is held on the table to be accessed */ + sqlite3VdbeUsesBtree(v, iDb); + + if( db->mallocFailed==0 ){ + assert( aOp!=0 ); + /* Configure the OP_TableLock instruction */ +#ifdef SQLITE_OMIT_SHARED_CACHE + aOp[0].opcode = OP_Noop; +#else + aOp[0].p1 = iDb; + aOp[0].p2 = pTab->tnum; + aOp[0].p3 = wrFlag; + sqlite3VdbeChangeP4(v, 2, pTab->zName, P4_TRANSIENT); + } + if( db->mallocFailed==0 ){ +#endif + + /* Remove either the OP_OpenWrite or OpenRead. Set the P2 + ** parameter of the other to pTab->tnum. */ + if( wrFlag ) aOp[1].opcode = OP_OpenWrite; + aOp[1].p2 = pTab->tnum; + aOp[1].p3 = iDb; + + /* Configure the number of columns. Configure the cursor to + ** think that the table has one more column than it really + ** does. An OP_Column to retrieve this imaginary column will + ** always return an SQL NULL. This is useful because it means + ** we can invoke OP_Column to fill in the vdbe cursors type + ** and offset cache without causing any IO. + */ + aOp[1].p4type = P4_INT32; + aOp[1].p4.i = pTab->nCol+1; + aOp[3].p2 = pTab->nCol; + + sParse.nVar = 0; + sParse.nMem = 1; + sParse.nTab = 1; + sqlite3VdbeMakeReady(v, &sParse); + } + } + + pBlob->iCol = iCol; + pBlob->db = db; + sqlite3BtreeLeaveAll(db); + if( db->mallocFailed ){ + goto blob_open_out; + } + rc = blobSeekToRow(pBlob, iRow, &zErr); + if( (++nAttempt)>=SQLITE_MAX_SCHEMA_RETRY || rc!=SQLITE_SCHEMA ) break; + sqlite3ParseObjectReset(&sParse); + } + +blob_open_out: + if( rc==SQLITE_OK && db->mallocFailed==0 ){ + *ppBlob = (sqlite3_blob *)pBlob; + }else{ + if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt); + sqlite3DbFree(db, pBlob); + } + sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : (char*)0), zErr); + sqlite3DbFree(db, zErr); + sqlite3ParseObjectReset(&sParse); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Close a blob handle that was previously created using +** sqlite3_blob_open(). +*/ +SQLITE_API int sqlite3_blob_close(sqlite3_blob *pBlob){ + Incrblob *p = (Incrblob *)pBlob; + int rc; + sqlite3 *db; + + if( p ){ + sqlite3_stmt *pStmt = p->pStmt; + db = p->db; + sqlite3_mutex_enter(db->mutex); + sqlite3DbFree(db, p); + sqlite3_mutex_leave(db->mutex); + rc = sqlite3_finalize(pStmt); + }else{ + rc = SQLITE_OK; + } + return rc; +} + +/* +** Perform a read or write operation on a blob +*/ +static int blobReadWrite( + sqlite3_blob *pBlob, + void *z, + int n, + int iOffset, + int (*xCall)(BtCursor*, u32, u32, void*) +){ + int rc = SQLITE_OK; + Incrblob *p = (Incrblob *)pBlob; + Vdbe *v; + sqlite3 *db; + + if( p==0 ) return SQLITE_MISUSE_BKPT; + db = p->db; + sqlite3_mutex_enter(db->mutex); + v = (Vdbe*)p->pStmt; + + if( n<0 || iOffset<0 || ((sqlite3_int64)iOffset+n)>p->nByte ){ + /* Request is out of range. Return a transient error. */ + rc = SQLITE_ERROR; + }else if( v==0 ){ + /* If there is no statement handle, then the blob-handle has + ** already been invalidated. Return SQLITE_ABORT in this case. + */ + rc = SQLITE_ABORT; + }else{ + /* Call either BtreeData() or BtreePutData(). If SQLITE_ABORT is + ** returned, clean-up the statement handle. + */ + assert( db == v->db ); + sqlite3BtreeEnterCursor(p->pCsr); + +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + if( xCall==sqlite3BtreePutData && db->xPreUpdateCallback ){ + /* If a pre-update hook is registered and this is a write cursor, + ** invoke it here. + ** + ** TODO: The preupdate-hook is passed SQLITE_DELETE, even though this + ** operation should really be an SQLITE_UPDATE. This is probably + ** incorrect, but is convenient because at this point the new.* values + ** are not easily obtainable. And for the sessions module, an + ** SQLITE_UPDATE where the PK columns do not change is handled in the + ** same way as an SQLITE_DELETE (the SQLITE_DELETE code is actually + ** slightly more efficient). Since you cannot write to a PK column + ** using the incremental-blob API, this works. For the sessions module + ** anyhow. + */ + if( sqlite3BtreeCursorIsValidNN(p->pCsr)==0 ){ + /* If the cursor is not currently valid, try to reseek it. This + ** always either fails or finds the correct row - the cursor will + ** have been marked permanently CURSOR_INVALID if the open row has + ** been deleted. */ + int bDiff = 0; + rc = sqlite3BtreeCursorRestore(p->pCsr, &bDiff); + assert( bDiff==0 || sqlite3BtreeCursorIsValidNN(p->pCsr)==0 ); + } + if( sqlite3BtreeCursorIsValidNN(p->pCsr) ){ + sqlite3_int64 iKey; + iKey = sqlite3BtreeIntegerKey(p->pCsr); + assert( v->apCsr[0]!=0 ); + assert( v->apCsr[0]->eCurType==CURTYPE_BTREE ); + sqlite3VdbePreUpdateHook( + v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1, p->iCol + ); + } + } + if( rc==SQLITE_OK ){ + rc = xCall(p->pCsr, iOffset+p->iOffset, n, z); + } +#else + rc = xCall(p->pCsr, iOffset+p->iOffset, n, z); +#endif + + sqlite3BtreeLeaveCursor(p->pCsr); + if( rc==SQLITE_ABORT ){ + sqlite3VdbeFinalize(v); + p->pStmt = 0; + }else{ + v->rc = rc; + } + } + sqlite3Error(db, rc); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Read data from a blob handle. +*/ +SQLITE_API int sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){ + return blobReadWrite(pBlob, z, n, iOffset, sqlite3BtreePayloadChecked); +} + +/* +** Write data to a blob handle. +*/ +SQLITE_API int sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){ + return blobReadWrite(pBlob, (void *)z, n, iOffset, sqlite3BtreePutData); +} + +/* +** Query a blob handle for the size of the data. +** +** The Incrblob.nByte field is fixed for the lifetime of the Incrblob +** so no mutex is required for access. +*/ +SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *pBlob){ + Incrblob *p = (Incrblob *)pBlob; + return (p && p->pStmt) ? p->nByte : 0; +} + +/* +** Move an existing blob handle to point to a different row of the same +** database table. +** +** If an error occurs, or if the specified row does not exist or does not +** contain a blob or text value, then an error code is returned and the +** database handle error code and message set. If this happens, then all +** subsequent calls to sqlite3_blob_xxx() functions (except blob_close()) +** immediately return SQLITE_ABORT. +*/ +SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){ + int rc; + Incrblob *p = (Incrblob *)pBlob; + sqlite3 *db; + + if( p==0 ) return SQLITE_MISUSE_BKPT; + db = p->db; + sqlite3_mutex_enter(db->mutex); + + if( p->pStmt==0 ){ + /* If there is no statement handle, then the blob-handle has + ** already been invalidated. Return SQLITE_ABORT in this case. + */ + rc = SQLITE_ABORT; + }else{ + char *zErr; + ((Vdbe*)p->pStmt)->rc = SQLITE_OK; + rc = blobSeekToRow(p, iRow, &zErr); + if( rc!=SQLITE_OK ){ + sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : (char*)0), zErr); + sqlite3DbFree(db, zErr); + } + assert( rc!=SQLITE_SCHEMA ); + } + + rc = sqlite3ApiExit(db, rc); + assert( rc==SQLITE_OK || p->pStmt==0 ); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +#endif /* #ifndef SQLITE_OMIT_INCRBLOB */ + +/************** End of vdbeblob.c ********************************************/ +/************** Begin file vdbesort.c ****************************************/ +/* +** 2011-07-09 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code for the VdbeSorter object, used in concert with +** a VdbeCursor to sort large numbers of keys for CREATE INDEX statements +** or by SELECT statements with ORDER BY clauses that cannot be satisfied +** using indexes and without LIMIT clauses. +** +** The VdbeSorter object implements a multi-threaded external merge sort +** algorithm that is efficient even if the number of elements being sorted +** exceeds the available memory. +** +** Here is the (internal, non-API) interface between this module and the +** rest of the SQLite system: +** +** sqlite3VdbeSorterInit() Create a new VdbeSorter object. +** +** sqlite3VdbeSorterWrite() Add a single new row to the VdbeSorter +** object. The row is a binary blob in the +** OP_MakeRecord format that contains both +** the ORDER BY key columns and result columns +** in the case of a SELECT w/ ORDER BY, or +** the complete record for an index entry +** in the case of a CREATE INDEX. +** +** sqlite3VdbeSorterRewind() Sort all content previously added. +** Position the read cursor on the +** first sorted element. +** +** sqlite3VdbeSorterNext() Advance the read cursor to the next sorted +** element. +** +** sqlite3VdbeSorterRowkey() Return the complete binary blob for the +** row currently under the read cursor. +** +** sqlite3VdbeSorterCompare() Compare the binary blob for the row +** currently under the read cursor against +** another binary blob X and report if +** X is strictly less than the read cursor. +** Used to enforce uniqueness in a +** CREATE UNIQUE INDEX statement. +** +** sqlite3VdbeSorterClose() Close the VdbeSorter object and reclaim +** all resources. +** +** sqlite3VdbeSorterReset() Refurbish the VdbeSorter for reuse. This +** is like Close() followed by Init() only +** much faster. +** +** The interfaces above must be called in a particular order. Write() can +** only occur in between Init()/Reset() and Rewind(). Next(), Rowkey(), and +** Compare() can only occur in between Rewind() and Close()/Reset(). i.e. +** +** Init() +** for each record: Write() +** Rewind() +** Rowkey()/Compare() +** Next() +** Close() +** +** Algorithm: +** +** Records passed to the sorter via calls to Write() are initially held +** unsorted in main memory. Assuming the amount of memory used never exceeds +** a threshold, when Rewind() is called the set of records is sorted using +** an in-memory merge sort. In this case, no temporary files are required +** and subsequent calls to Rowkey(), Next() and Compare() read records +** directly from main memory. +** +** If the amount of space used to store records in main memory exceeds the +** threshold, then the set of records currently in memory are sorted and +** written to a temporary file in "Packed Memory Array" (PMA) format. +** A PMA created at this point is known as a "level-0 PMA". Higher levels +** of PMAs may be created by merging existing PMAs together - for example +** merging two or more level-0 PMAs together creates a level-1 PMA. +** +** The threshold for the amount of main memory to use before flushing +** records to a PMA is roughly the same as the limit configured for the +** page-cache of the main database. Specifically, the threshold is set to +** the value returned by "PRAGMA main.page_size" multiplied by +** that returned by "PRAGMA main.cache_size", in bytes. +** +** If the sorter is running in single-threaded mode, then all PMAs generated +** are appended to a single temporary file. Or, if the sorter is running in +** multi-threaded mode then up to (N+1) temporary files may be opened, where +** N is the configured number of worker threads. In this case, instead of +** sorting the records and writing the PMA to a temporary file itself, the +** calling thread usually launches a worker thread to do so. Except, if +** there are already N worker threads running, the main thread does the work +** itself. +** +** The sorter is running in multi-threaded mode if (a) the library was built +** with pre-processor symbol SQLITE_MAX_WORKER_THREADS set to a value greater +** than zero, and (b) worker threads have been enabled at runtime by calling +** "PRAGMA threads=N" with some value of N greater than 0. +** +** When Rewind() is called, any data remaining in memory is flushed to a +** final PMA. So at this point the data is stored in some number of sorted +** PMAs within temporary files on disk. +** +** If there are fewer than SORTER_MAX_MERGE_COUNT PMAs in total and the +** sorter is running in single-threaded mode, then these PMAs are merged +** incrementally as keys are retrieved from the sorter by the VDBE. The +** MergeEngine object, described in further detail below, performs this +** merge. +** +** Or, if running in multi-threaded mode, then a background thread is +** launched to merge the existing PMAs. Once the background thread has +** merged T bytes of data into a single sorted PMA, the main thread +** begins reading keys from that PMA while the background thread proceeds +** with merging the next T bytes of data. And so on. +** +** Parameter T is set to half the value of the memory threshold used +** by Write() above to determine when to create a new PMA. +** +** If there are more than SORTER_MAX_MERGE_COUNT PMAs in total when +** Rewind() is called, then a hierarchy of incremental-merges is used. +** First, T bytes of data from the first SORTER_MAX_MERGE_COUNT PMAs on +** disk are merged together. Then T bytes of data from the second set, and +** so on, such that no operation ever merges more than SORTER_MAX_MERGE_COUNT +** PMAs at a time. This done is to improve locality. +** +** If running in multi-threaded mode and there are more than +** SORTER_MAX_MERGE_COUNT PMAs on disk when Rewind() is called, then more +** than one background thread may be created. Specifically, there may be +** one background thread for each temporary file on disk, and one background +** thread to merge the output of each of the others to a single PMA for +** the main thread to read from. +*/ +/* #include "sqliteInt.h" */ +/* #include "vdbeInt.h" */ + +/* +** If SQLITE_DEBUG_SORTER_THREADS is defined, this module outputs various +** messages to stderr that may be helpful in understanding the performance +** characteristics of the sorter in multi-threaded mode. +*/ +#if 0 +# define SQLITE_DEBUG_SORTER_THREADS 1 +#endif + +/* +** Hard-coded maximum amount of data to accumulate in memory before flushing +** to a level 0 PMA. The purpose of this limit is to prevent various integer +** overflows. 512MiB. +*/ +#define SQLITE_MAX_PMASZ (1<<29) + +/* +** Private objects used by the sorter +*/ +typedef struct MergeEngine MergeEngine; /* Merge PMAs together */ +typedef struct PmaReader PmaReader; /* Incrementally read one PMA */ +typedef struct PmaWriter PmaWriter; /* Incrementally write one PMA */ +typedef struct SorterRecord SorterRecord; /* A record being sorted */ +typedef struct SortSubtask SortSubtask; /* A sub-task in the sort process */ +typedef struct SorterFile SorterFile; /* Temporary file object wrapper */ +typedef struct SorterList SorterList; /* In-memory list of records */ +typedef struct IncrMerger IncrMerger; /* Read & merge multiple PMAs */ + +/* +** A container for a temp file handle and the current amount of data +** stored in the file. +*/ +struct SorterFile { + sqlite3_file *pFd; /* File handle */ + i64 iEof; /* Bytes of data stored in pFd */ +}; + +/* +** An in-memory list of objects to be sorted. +** +** If aMemory==0 then each object is allocated separately and the objects +** are connected using SorterRecord.u.pNext. If aMemory!=0 then all objects +** are stored in the aMemory[] bulk memory, one right after the other, and +** are connected using SorterRecord.u.iNext. +*/ +struct SorterList { + SorterRecord *pList; /* Linked list of records */ + u8 *aMemory; /* If non-NULL, bulk memory to hold pList */ + i64 szPMA; /* Size of pList as PMA in bytes */ +}; + +/* +** The MergeEngine object is used to combine two or more smaller PMAs into +** one big PMA using a merge operation. Separate PMAs all need to be +** combined into one big PMA in order to be able to step through the sorted +** records in order. +** +** The aReadr[] array contains a PmaReader object for each of the PMAs being +** merged. An aReadr[] object either points to a valid key or else is at EOF. +** ("EOF" means "End Of File". When aReadr[] is at EOF there is no more data.) +** For the purposes of the paragraphs below, we assume that the array is +** actually N elements in size, where N is the smallest power of 2 greater +** to or equal to the number of PMAs being merged. The extra aReadr[] elements +** are treated as if they are empty (always at EOF). +** +** The aTree[] array is also N elements in size. The value of N is stored in +** the MergeEngine.nTree variable. +** +** The final (N/2) elements of aTree[] contain the results of comparing +** pairs of PMA keys together. Element i contains the result of +** comparing aReadr[2*i-N] and aReadr[2*i-N+1]. Whichever key is smaller, the +** aTree element is set to the index of it. +** +** For the purposes of this comparison, EOF is considered greater than any +** other key value. If the keys are equal (only possible with two EOF +** values), it doesn't matter which index is stored. +** +** The (N/4) elements of aTree[] that precede the final (N/2) described +** above contains the index of the smallest of each block of 4 PmaReaders +** And so on. So that aTree[1] contains the index of the PmaReader that +** currently points to the smallest key value. aTree[0] is unused. +** +** Example: +** +** aReadr[0] -> Banana +** aReadr[1] -> Feijoa +** aReadr[2] -> Elderberry +** aReadr[3] -> Currant +** aReadr[4] -> Grapefruit +** aReadr[5] -> Apple +** aReadr[6] -> Durian +** aReadr[7] -> EOF +** +** aTree[] = { X, 5 0, 5 0, 3, 5, 6 } +** +** The current element is "Apple" (the value of the key indicated by +** PmaReader 5). When the Next() operation is invoked, PmaReader 5 will +** be advanced to the next key in its segment. Say the next key is +** "Eggplant": +** +** aReadr[5] -> Eggplant +** +** The contents of aTree[] are updated first by comparing the new PmaReader +** 5 key to the current key of PmaReader 4 (still "Grapefruit"). The PmaReader +** 5 value is still smaller, so aTree[6] is set to 5. And so on up the tree. +** The value of PmaReader 6 - "Durian" - is now smaller than that of PmaReader +** 5, so aTree[3] is set to 6. Key 0 is smaller than key 6 (Bananafile2. And instead of using a +** background thread to prepare data for the PmaReader, with a single +** threaded IncrMerger the allocate part of pTask->file2 is "refilled" with +** keys from pMerger by the calling thread whenever the PmaReader runs out +** of data. +*/ +struct IncrMerger { + SortSubtask *pTask; /* Task that owns this merger */ + MergeEngine *pMerger; /* Merge engine thread reads data from */ + i64 iStartOff; /* Offset to start writing file at */ + int mxSz; /* Maximum bytes of data to store */ + int bEof; /* Set to true when merge is finished */ + int bUseThread; /* True to use a bg thread for this object */ + SorterFile aFile[2]; /* aFile[0] for reading, [1] for writing */ +}; + +/* +** An instance of this object is used for writing a PMA. +** +** The PMA is written one record at a time. Each record is of an arbitrary +** size. But I/O is more efficient if it occurs in page-sized blocks where +** each block is aligned on a page boundary. This object caches writes to +** the PMA so that aligned, page-size blocks are written. +*/ +struct PmaWriter { + int eFWErr; /* Non-zero if in an error state */ + u8 *aBuffer; /* Pointer to write buffer */ + int nBuffer; /* Size of write buffer in bytes */ + int iBufStart; /* First byte of buffer to write */ + int iBufEnd; /* Last byte of buffer to write */ + i64 iWriteOff; /* Offset of start of buffer in file */ + sqlite3_file *pFd; /* File handle to write to */ + u64 nPmaSpill; /* Total number of bytes written */ +}; + +/* +** This object is the header on a single record while that record is being +** held in memory and prior to being written out as part of a PMA. +** +** How the linked list is connected depends on how memory is being managed +** by this module. If using a separate allocation for each in-memory record +** (VdbeSorter.list.aMemory==0), then the list is always connected using the +** SorterRecord.u.pNext pointers. +** +** Or, if using the single large allocation method (VdbeSorter.list.aMemory!=0), +** then while records are being accumulated the list is linked using the +** SorterRecord.u.iNext offset. This is because the aMemory[] array may +** be sqlite3Realloc()ed while records are being accumulated. Once the VM +** has finished passing records to the sorter, or when the in-memory buffer +** is full, the list is sorted. As part of the sorting process, it is +** converted to use the SorterRecord.u.pNext pointers. See function +** vdbeSorterSort() for details. +*/ +struct SorterRecord { + int nVal; /* Size of the record in bytes */ + union { + SorterRecord *pNext; /* Pointer to next record in list */ + int iNext; /* Offset within aMemory of next record */ + } u; + /* The data for the record immediately follows this header */ +}; + +/* Return a pointer to the buffer containing the record data for SorterRecord +** object p. Should be used as if: +** +** void *SRVAL(SorterRecord *p) { return (void*)&p[1]; } +*/ +#define SRVAL(p) ((void*)((SorterRecord*)(p) + 1)) + + +/* Maximum number of PMAs that a single MergeEngine can merge */ +#define SORTER_MAX_MERGE_COUNT 16 + +static int vdbeIncrSwap(IncrMerger*); +static void vdbeIncrFree(IncrMerger *); + +/* +** Free all memory belonging to the PmaReader object passed as the +** argument. All structure fields are set to zero before returning. +*/ +static void vdbePmaReaderClear(PmaReader *pReadr){ + sqlite3_free(pReadr->aAlloc); + sqlite3_free(pReadr->aBuffer); + if( pReadr->aMap ) sqlite3OsUnfetch(pReadr->pFd, 0, pReadr->aMap); + vdbeIncrFree(pReadr->pIncr); + memset(pReadr, 0, sizeof(PmaReader)); +} + +/* +** Read the next nByte bytes of data from the PMA p. +** If successful, set *ppOut to point to a buffer containing the data +** and return SQLITE_OK. Otherwise, if an error occurs, return an SQLite +** error code. +** +** The buffer returned in *ppOut is only valid until the +** next call to this function. +*/ +static int vdbePmaReadBlob( + PmaReader *p, /* PmaReader from which to take the blob */ + int nByte, /* Bytes of data to read */ + u8 **ppOut /* OUT: Pointer to buffer containing data */ +){ + int iBuf; /* Offset within buffer to read from */ + int nAvail; /* Bytes of data available in buffer */ + + if( p->aMap ){ + *ppOut = &p->aMap[p->iReadOff]; + p->iReadOff += nByte; + return SQLITE_OK; + } + + assert( p->aBuffer ); + + /* If there is no more data to be read from the buffer, read the next + ** p->nBuffer bytes of data from the file into it. Or, if there are less + ** than p->nBuffer bytes remaining in the PMA, read all remaining data. */ + iBuf = p->iReadOff % p->nBuffer; + if( iBuf==0 ){ + int nRead; /* Bytes to read from disk */ + int rc; /* sqlite3OsRead() return code */ + + /* Determine how many bytes of data to read. */ + if( (p->iEof - p->iReadOff) > (i64)p->nBuffer ){ + nRead = p->nBuffer; + }else{ + nRead = (int)(p->iEof - p->iReadOff); + } + assert( nRead>0 ); + + /* Readr data from the file. Return early if an error occurs. */ + rc = sqlite3OsRead(p->pFd, p->aBuffer, nRead, p->iReadOff); + assert( rc!=SQLITE_IOERR_SHORT_READ ); + if( rc!=SQLITE_OK ) return rc; + } + nAvail = p->nBuffer - iBuf; + + if( nByte<=nAvail ){ + /* The requested data is available in the in-memory buffer. In this + ** case there is no need to make a copy of the data, just return a + ** pointer into the buffer to the caller. */ + *ppOut = &p->aBuffer[iBuf]; + p->iReadOff += nByte; + }else{ + /* The requested data is not all available in the in-memory buffer. + ** In this case, allocate space at p->aAlloc[] to copy the requested + ** range into. Then return a copy of pointer p->aAlloc to the caller. */ + int nRem; /* Bytes remaining to copy */ + + /* Extend the p->aAlloc[] allocation if required. */ + if( p->nAllocnAlloc); + while( nByte>nNew ) nNew = nNew*2; + aNew = sqlite3Realloc(p->aAlloc, nNew); + if( !aNew ) return SQLITE_NOMEM_BKPT; + p->nAlloc = nNew; + p->aAlloc = aNew; + } + + /* Copy as much data as is available in the buffer into the start of + ** p->aAlloc[]. */ + memcpy(p->aAlloc, &p->aBuffer[iBuf], nAvail); + p->iReadOff += nAvail; + nRem = nByte - nAvail; + + /* The following loop copies up to p->nBuffer bytes per iteration into + ** the p->aAlloc[] buffer. */ + while( nRem>0 ){ + int rc; /* vdbePmaReadBlob() return code */ + int nCopy; /* Number of bytes to copy */ + u8 *aNext = 0; /* Pointer to buffer to copy data from */ + + nCopy = nRem; + if( nRem>p->nBuffer ) nCopy = p->nBuffer; + rc = vdbePmaReadBlob(p, nCopy, &aNext); + if( rc!=SQLITE_OK ) return rc; + assert( aNext!=p->aAlloc ); + assert( aNext!=0 ); + memcpy(&p->aAlloc[nByte - nRem], aNext, nCopy); + nRem -= nCopy; + } + + *ppOut = p->aAlloc; + } + + return SQLITE_OK; +} + +/* +** Read a varint from the stream of data accessed by p. Set *pnOut to +** the value read. +*/ +static int vdbePmaReadVarint(PmaReader *p, u64 *pnOut){ + int iBuf; + + if( p->aMap ){ + p->iReadOff += sqlite3GetVarint(&p->aMap[p->iReadOff], pnOut); + }else{ + iBuf = p->iReadOff % p->nBuffer; + if( iBuf && (p->nBuffer-iBuf)>=9 ){ + p->iReadOff += sqlite3GetVarint(&p->aBuffer[iBuf], pnOut); + }else{ + u8 aVarint[16], *a; + int i = 0, rc; + do{ + rc = vdbePmaReadBlob(p, 1, &a); + if( rc ) return rc; + aVarint[(i++)&0xf] = a[0]; + }while( (a[0]&0x80)!=0 ); + sqlite3GetVarint(aVarint, pnOut); + } + } + + return SQLITE_OK; +} + +/* +** Attempt to memory map file pFile. If successful, set *pp to point to the +** new mapping and return SQLITE_OK. If the mapping is not attempted +** (because the file is too large or the VFS layer is configured not to use +** mmap), return SQLITE_OK and set *pp to NULL. +** +** Or, if an error occurs, return an SQLite error code. The final value of +** *pp is undefined in this case. +*/ +static int vdbeSorterMapFile(SortSubtask *pTask, SorterFile *pFile, u8 **pp){ + int rc = SQLITE_OK; + if( pFile->iEof<=(i64)(pTask->pSorter->db->nMaxSorterMmap) ){ + sqlite3_file *pFd = pFile->pFd; + if( pFd->pMethods->iVersion>=3 ){ + rc = sqlite3OsFetch(pFd, 0, (int)pFile->iEof, (void**)pp); + testcase( rc!=SQLITE_OK ); + } + } + return rc; +} + +/* +** Attach PmaReader pReadr to file pFile (if it is not already attached to +** that file) and seek it to offset iOff within the file. Return SQLITE_OK +** if successful, or an SQLite error code if an error occurs. +*/ +static int vdbePmaReaderSeek( + SortSubtask *pTask, /* Task context */ + PmaReader *pReadr, /* Reader whose cursor is to be moved */ + SorterFile *pFile, /* Sorter file to read from */ + i64 iOff /* Offset in pFile */ +){ + int rc = SQLITE_OK; + + assert( pReadr->pIncr==0 || pReadr->pIncr->bEof==0 ); + + if( sqlite3FaultSim(201) ) return SQLITE_IOERR_READ; + if( pReadr->aMap ){ + sqlite3OsUnfetch(pReadr->pFd, 0, pReadr->aMap); + pReadr->aMap = 0; + } + pReadr->iReadOff = iOff; + pReadr->iEof = pFile->iEof; + pReadr->pFd = pFile->pFd; + + rc = vdbeSorterMapFile(pTask, pFile, &pReadr->aMap); + if( rc==SQLITE_OK && pReadr->aMap==0 ){ + int pgsz = pTask->pSorter->pgsz; + int iBuf = pReadr->iReadOff % pgsz; + if( pReadr->aBuffer==0 ){ + pReadr->aBuffer = (u8*)sqlite3Malloc(pgsz); + if( pReadr->aBuffer==0 ) rc = SQLITE_NOMEM_BKPT; + pReadr->nBuffer = pgsz; + } + if( rc==SQLITE_OK && iBuf ){ + int nRead = pgsz - iBuf; + if( (pReadr->iReadOff + nRead) > pReadr->iEof ){ + nRead = (int)(pReadr->iEof - pReadr->iReadOff); + } + rc = sqlite3OsRead( + pReadr->pFd, &pReadr->aBuffer[iBuf], nRead, pReadr->iReadOff + ); + testcase( rc!=SQLITE_OK ); + } + } + + return rc; +} + +/* +** Advance PmaReader pReadr to the next key in its PMA. Return SQLITE_OK if +** no error occurs, or an SQLite error code if one does. +*/ +static int vdbePmaReaderNext(PmaReader *pReadr){ + int rc = SQLITE_OK; /* Return Code */ + u64 nRec = 0; /* Size of record in bytes */ + + + if( pReadr->iReadOff>=pReadr->iEof ){ + IncrMerger *pIncr = pReadr->pIncr; + int bEof = 1; + if( pIncr ){ + rc = vdbeIncrSwap(pIncr); + if( rc==SQLITE_OK && pIncr->bEof==0 ){ + rc = vdbePmaReaderSeek( + pIncr->pTask, pReadr, &pIncr->aFile[0], pIncr->iStartOff + ); + bEof = 0; + } + } + + if( bEof ){ + /* This is an EOF condition */ + vdbePmaReaderClear(pReadr); + testcase( rc!=SQLITE_OK ); + return rc; + } + } + + if( rc==SQLITE_OK ){ + rc = vdbePmaReadVarint(pReadr, &nRec); + } + if( rc==SQLITE_OK ){ + pReadr->nKey = (int)nRec; + rc = vdbePmaReadBlob(pReadr, (int)nRec, &pReadr->aKey); + testcase( rc!=SQLITE_OK ); + } + + return rc; +} + +/* +** Initialize PmaReader pReadr to scan through the PMA stored in file pFile +** starting at offset iStart and ending at offset iEof-1. This function +** leaves the PmaReader pointing to the first key in the PMA (or EOF if the +** PMA is empty). +** +** If the pnByte parameter is NULL, then it is assumed that the file +** contains a single PMA, and that that PMA omits the initial length varint. +*/ +static int vdbePmaReaderInit( + SortSubtask *pTask, /* Task context */ + SorterFile *pFile, /* Sorter file to read from */ + i64 iStart, /* Start offset in pFile */ + PmaReader *pReadr, /* PmaReader to populate */ + i64 *pnByte /* IN/OUT: Increment this value by PMA size */ +){ + int rc; + + assert( pFile->iEof>iStart ); + assert( pReadr->aAlloc==0 && pReadr->nAlloc==0 ); + assert( pReadr->aBuffer==0 ); + assert( pReadr->aMap==0 ); + + rc = vdbePmaReaderSeek(pTask, pReadr, pFile, iStart); + if( rc==SQLITE_OK ){ + u64 nByte = 0; /* Size of PMA in bytes */ + rc = vdbePmaReadVarint(pReadr, &nByte); + pReadr->iEof = pReadr->iReadOff + nByte; + *pnByte += nByte; + } + + if( rc==SQLITE_OK ){ + rc = vdbePmaReaderNext(pReadr); + } + return rc; +} + +/* +** A version of vdbeSorterCompare() that assumes that it has already been +** determined that the first field of key1 is equal to the first field of +** key2. +*/ +static int vdbeSorterCompareTail( + SortSubtask *pTask, /* Subtask context (for pKeyInfo) */ + int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */ + const void *pKey1, int nKey1, /* Left side of comparison */ + const void *pKey2, int nKey2 /* Right side of comparison */ +){ + UnpackedRecord *r2 = pTask->pUnpacked; + if( *pbKey2Cached==0 ){ + sqlite3VdbeRecordUnpack(nKey2, pKey2, r2); + *pbKey2Cached = 1; + } + return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, r2, 1); +} + +/* +** Compare key1 (buffer pKey1, size nKey1 bytes) with key2 (buffer pKey2, +** size nKey2 bytes). Use (pTask->pKeyInfo) for the collation sequences +** used by the comparison. Return the result of the comparison. +** +** If IN/OUT parameter *pbKey2Cached is true when this function is called, +** it is assumed that (pTask->pUnpacked) contains the unpacked version +** of key2. If it is false, (pTask->pUnpacked) is populated with the unpacked +** version of key2 and *pbKey2Cached set to true before returning. +** +** If an OOM error is encountered, (pTask->pUnpacked->error_rc) is set +** to SQLITE_NOMEM. +*/ +static int vdbeSorterCompare( + SortSubtask *pTask, /* Subtask context (for pKeyInfo) */ + int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */ + const void *pKey1, int nKey1, /* Left side of comparison */ + const void *pKey2, int nKey2 /* Right side of comparison */ +){ + UnpackedRecord *r2 = pTask->pUnpacked; + if( !*pbKey2Cached ){ + sqlite3VdbeRecordUnpack(nKey2, pKey2, r2); + *pbKey2Cached = 1; + } + return sqlite3VdbeRecordCompare(nKey1, pKey1, r2); +} + +/* +** A specially optimized version of vdbeSorterCompare() that assumes that +** the first field of each key is a TEXT value and that the collation +** sequence to compare them with is BINARY. +*/ +static int vdbeSorterCompareText( + SortSubtask *pTask, /* Subtask context (for pKeyInfo) */ + int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */ + const void *pKey1, int nKey1, /* Left side of comparison */ + const void *pKey2, int nKey2 /* Right side of comparison */ +){ + const u8 * const p1 = (const u8 * const)pKey1; + const u8 * const p2 = (const u8 * const)pKey2; + const u8 * const v1 = &p1[ p1[0] ]; /* Pointer to value 1 */ + const u8 * const v2 = &p2[ p2[0] ]; /* Pointer to value 2 */ + + int n1; + int n2; + int res; + + getVarint32NR(&p1[1], n1); + getVarint32NR(&p2[1], n2); + res = memcmp(v1, v2, (MIN(n1, n2) - 13)/2); + if( res==0 ){ + res = n1 - n2; + } + + if( res==0 ){ + if( pTask->pSorter->pKeyInfo->nKeyField>1 ){ + res = vdbeSorterCompareTail( + pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 + ); + } + }else{ + assert( pTask->pSorter->pKeyInfo->aSortFlags!=0 ); + assert( !(pTask->pSorter->pKeyInfo->aSortFlags[0]&KEYINFO_ORDER_BIGNULL) ); + if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){ + res = res * -1; + } + } + + return res; +} + +/* +** A specially optimized version of vdbeSorterCompare() that assumes that +** the first field of each key is an INTEGER value. +*/ +static int vdbeSorterCompareInt( + SortSubtask *pTask, /* Subtask context (for pKeyInfo) */ + int *pbKey2Cached, /* True if pTask->pUnpacked is pKey2 */ + const void *pKey1, int nKey1, /* Left side of comparison */ + const void *pKey2, int nKey2 /* Right side of comparison */ +){ + const u8 * const p1 = (const u8 * const)pKey1; + const u8 * const p2 = (const u8 * const)pKey2; + const int s1 = p1[1]; /* Left hand serial type */ + const int s2 = p2[1]; /* Right hand serial type */ + const u8 * const v1 = &p1[ p1[0] ]; /* Pointer to value 1 */ + const u8 * const v2 = &p2[ p2[0] ]; /* Pointer to value 2 */ + int res; /* Return value */ + + assert( (s1>0 && s1<7) || s1==8 || s1==9 ); + assert( (s2>0 && s2<7) || s2==8 || s2==9 ); + + if( s1==s2 ){ + /* The two values have the same sign. Compare using memcmp(). */ + static const u8 aLen[] = {0, 1, 2, 3, 4, 6, 8, 0, 0, 0 }; + const u8 n = aLen[s1]; + int i; + res = 0; + for(i=0; i7 && s2>7 ){ + res = s1 - s2; + }else{ + if( s2>7 ){ + res = +1; + }else if( s1>7 ){ + res = -1; + }else{ + res = s1 - s2; + } + assert( res!=0 ); + + if( res>0 ){ + if( *v1 & 0x80 ) res = -1; + }else{ + if( *v2 & 0x80 ) res = +1; + } + } + + assert( pTask->pSorter->pKeyInfo->aSortFlags!=0 ); + if( res==0 ){ + if( pTask->pSorter->pKeyInfo->nKeyField>1 ){ + res = vdbeSorterCompareTail( + pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 + ); + } + }else if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){ + assert( !(pTask->pSorter->pKeyInfo->aSortFlags[0]&KEYINFO_ORDER_BIGNULL) ); + res = res * -1; + } + + return res; +} + +/* +** Initialize the temporary index cursor just opened as a sorter cursor. +** +** Usually, the sorter module uses the value of (pCsr->pKeyInfo->nKeyField) +** to determine the number of fields that should be compared from the +** records being sorted. However, if the value passed as argument nField +** is non-zero and the sorter is able to guarantee a stable sort, nField +** is used instead. This is used when sorting records for a CREATE INDEX +** statement. In this case, keys are always delivered to the sorter in +** order of the primary key, which happens to be make up the final part +** of the records being sorted. So if the sort is stable, there is never +** any reason to compare PK fields and they can be ignored for a small +** performance boost. +** +** The sorter can guarantee a stable sort when running in single-threaded +** mode, but not in multi-threaded mode. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +*/ +SQLITE_PRIVATE int sqlite3VdbeSorterInit( + sqlite3 *db, /* Database connection (for malloc()) */ + int nField, /* Number of key fields in each record */ + VdbeCursor *pCsr /* Cursor that holds the new sorter */ +){ + int pgsz; /* Page size of main database */ + int i; /* Used to iterate through aTask[] */ + VdbeSorter *pSorter; /* The new sorter */ + KeyInfo *pKeyInfo; /* Copy of pCsr->pKeyInfo with db==0 */ + int szKeyInfo; /* Size of pCsr->pKeyInfo in bytes */ + i64 sz; /* Size of pSorter in bytes */ + int rc = SQLITE_OK; +#if SQLITE_MAX_WORKER_THREADS==0 +# define nWorker 0 +#else + int nWorker; +#endif + + /* Initialize the upper limit on the number of worker threads */ +#if SQLITE_MAX_WORKER_THREADS>0 + if( sqlite3TempInMemory(db) || sqlite3GlobalConfig.bCoreMutex==0 ){ + nWorker = 0; + }else{ + nWorker = db->aLimit[SQLITE_LIMIT_WORKER_THREADS]; + } +#endif + + /* Do not allow the total number of threads (main thread + all workers) + ** to exceed the maximum merge count */ +#if SQLITE_MAX_WORKER_THREADS>=SORTER_MAX_MERGE_COUNT + if( nWorker>=SORTER_MAX_MERGE_COUNT ){ + nWorker = SORTER_MAX_MERGE_COUNT-1; + } +#endif + + assert( pCsr->pKeyInfo ); + assert( !pCsr->isEphemeral ); + assert( pCsr->eCurType==CURTYPE_SORTER ); + assert( sizeof(KeyInfo) + UMXV(pCsr->pKeyInfo->nKeyField)*sizeof(CollSeq*) + < 0x7fffffff ); + assert( pCsr->pKeyInfo->nKeyField<=pCsr->pKeyInfo->nAllField ); + szKeyInfo = SZ_KEYINFO(pCsr->pKeyInfo->nAllField); + sz = SZ_VDBESORTER(nWorker+1); + + pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo); + pCsr->uc.pSorter = pSorter; + if( pSorter==0 ){ + rc = SQLITE_NOMEM_BKPT; + }else{ + Btree *pBt = db->aDb[0].pBt; + pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz); + memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo); + pKeyInfo->db = 0; + if( nField && nWorker==0 ){ + pKeyInfo->nKeyField = nField; + assert( nField<=pCsr->pKeyInfo->nAllField ); + } + /* It is OK that pKeyInfo reuses the aSortFlags field from pCsr->pKeyInfo, + ** since the pCsr->pKeyInfo->aSortFlags[] array is invariant and lives + ** longer that pSorter. */ + assert( pKeyInfo->aSortFlags==pCsr->pKeyInfo->aSortFlags ); + sqlite3BtreeEnter(pBt); + pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(pBt); + sqlite3BtreeLeave(pBt); + pSorter->nTask = nWorker + 1; + pSorter->iPrev = (u8)(nWorker - 1); + pSorter->bUseThreads = (pSorter->nTask>1); + pSorter->db = db; + for(i=0; inTask; i++){ + SortSubtask *pTask = &pSorter->aTask[i]; + pTask->pSorter = pSorter; + } + + if( !sqlite3TempInMemory(db) ){ + i64 mxCache; /* Cache size in bytes*/ + u32 szPma = sqlite3GlobalConfig.szPma; + pSorter->mnPmaSize = szPma * pgsz; + + mxCache = db->aDb[0].pSchema->cache_size; + if( mxCache<0 ){ + /* A negative cache-size value C indicates that the cache is abs(C) + ** KiB in size. */ + mxCache = mxCache * -1024; + }else{ + mxCache = mxCache * pgsz; + } + mxCache = MIN(mxCache, SQLITE_MAX_PMASZ); + pSorter->mxPmaSize = MAX(pSorter->mnPmaSize, (int)mxCache); + + /* Avoid large memory allocations if the application has requested + ** SQLITE_CONFIG_SMALL_MALLOC. */ + if( sqlite3GlobalConfig.bSmallMalloc==0 ){ + assert( pSorter->iMemory==0 ); + pSorter->nMemory = pgsz; + pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz); + if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM_BKPT; + } + } + + if( pKeyInfo->nAllField<13 + && (pKeyInfo->aColl[0]==0 || pKeyInfo->aColl[0]==db->pDfltColl) + && (pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL)==0 + ){ + pSorter->typeMask = SORTER_TYPE_INTEGER | SORTER_TYPE_TEXT; + } + } + + return rc; +} +#undef nWorker /* Defined at the top of this function */ + +/* +** Free the list of sorted records starting at pRecord. +*/ +static void vdbeSorterRecordFree(sqlite3 *db, SorterRecord *pRecord){ + SorterRecord *p; + SorterRecord *pNext; + for(p=pRecord; p; p=pNext){ + pNext = p->u.pNext; + sqlite3DbFree(db, p); + } +} + +/* +** Free all resources owned by the object indicated by argument pTask. All +** fields of *pTask are zeroed before returning. +*/ +static void vdbeSortSubtaskCleanup(sqlite3 *db, SortSubtask *pTask){ + sqlite3DbFree(db, pTask->pUnpacked); +#if SQLITE_MAX_WORKER_THREADS>0 + /* pTask->list.aMemory can only be non-zero if it was handed memory + ** from the main thread. That only occurs SQLITE_MAX_WORKER_THREADS>0 */ + if( pTask->list.aMemory ){ + sqlite3_free(pTask->list.aMemory); + }else +#endif + { + assert( pTask->list.aMemory==0 ); + vdbeSorterRecordFree(0, pTask->list.pList); + } + if( pTask->file.pFd ){ + sqlite3OsCloseFree(pTask->file.pFd); + } + if( pTask->file2.pFd ){ + sqlite3OsCloseFree(pTask->file2.pFd); + } + memset(pTask, 0, sizeof(SortSubtask)); +} + +#ifdef SQLITE_DEBUG_SORTER_THREADS +static void vdbeSorterWorkDebug(SortSubtask *pTask, const char *zEvent){ + i64 t; + int iTask = (pTask - pTask->pSorter->aTask); + sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t); + fprintf(stderr, "%lld:%d %s\n", t, iTask, zEvent); +} +static void vdbeSorterRewindDebug(const char *zEvent){ + i64 t = 0; + sqlite3_vfs *pVfs = sqlite3_vfs_find(0); + if( ALWAYS(pVfs) ) sqlite3OsCurrentTimeInt64(pVfs, &t); + fprintf(stderr, "%lld:X %s\n", t, zEvent); +} +static void vdbeSorterPopulateDebug( + SortSubtask *pTask, + const char *zEvent +){ + i64 t; + int iTask = (pTask - pTask->pSorter->aTask); + sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t); + fprintf(stderr, "%lld:bg%d %s\n", t, iTask, zEvent); +} +static void vdbeSorterBlockDebug( + SortSubtask *pTask, + int bBlocked, + const char *zEvent +){ + if( bBlocked ){ + i64 t; + sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t); + fprintf(stderr, "%lld:main %s\n", t, zEvent); + } +} +#else +# define vdbeSorterWorkDebug(x,y) +# define vdbeSorterRewindDebug(y) +# define vdbeSorterPopulateDebug(x,y) +# define vdbeSorterBlockDebug(x,y,z) +#endif + +#if SQLITE_MAX_WORKER_THREADS>0 +/* +** Join thread pTask->thread. +*/ +static int vdbeSorterJoinThread(SortSubtask *pTask){ + int rc = SQLITE_OK; + if( pTask->pThread ){ +#ifdef SQLITE_DEBUG_SORTER_THREADS + int bDone = pTask->bDone; +#endif + void *pRet = SQLITE_INT_TO_PTR(SQLITE_ERROR); + vdbeSorterBlockDebug(pTask, !bDone, "enter"); + (void)sqlite3ThreadJoin(pTask->pThread, &pRet); + vdbeSorterBlockDebug(pTask, !bDone, "exit"); + rc = SQLITE_PTR_TO_INT(pRet); + assert( pTask->bDone==1 ); + pTask->bDone = 0; + pTask->pThread = 0; + } + return rc; +} + +/* +** Launch a background thread to run xTask(pIn). +*/ +static int vdbeSorterCreateThread( + SortSubtask *pTask, /* Thread will use this task object */ + void *(*xTask)(void*), /* Routine to run in a separate thread */ + void *pIn /* Argument passed into xTask() */ +){ + assert( pTask->pThread==0 && pTask->bDone==0 ); + return sqlite3ThreadCreate(&pTask->pThread, xTask, pIn); +} + +/* +** Join all outstanding threads launched by SorterWrite() to create +** level-0 PMAs. +*/ +static int vdbeSorterJoinAll(VdbeSorter *pSorter, int rcin){ + int rc = rcin; + int i; + + /* This function is always called by the main user thread. + ** + ** If this function is being called after SorterRewind() has been called, + ** it is possible that thread pSorter->aTask[pSorter->nTask-1].pThread + ** is currently attempt to join one of the other threads. To avoid a race + ** condition where this thread also attempts to join the same object, join + ** thread pSorter->aTask[pSorter->nTask-1].pThread first. */ + for(i=pSorter->nTask-1; i>=0; i--){ + SortSubtask *pTask = &pSorter->aTask[i]; + int rc2 = vdbeSorterJoinThread(pTask); + if( rc==SQLITE_OK ) rc = rc2; + } + return rc; +} +#else +# define vdbeSorterJoinAll(x,rcin) (rcin) +# define vdbeSorterJoinThread(pTask) SQLITE_OK +#endif + +/* +** Allocate a new MergeEngine object capable of handling up to +** nReader PmaReader inputs. +** +** nReader is automatically rounded up to the next power of two. +** nReader may not exceed SORTER_MAX_MERGE_COUNT even after rounding up. +*/ +static MergeEngine *vdbeMergeEngineNew(int nReader){ + int N = 2; /* Smallest power of two >= nReader */ + i64 nByte; /* Total bytes of space to allocate */ + MergeEngine *pNew; /* Pointer to allocated object to return */ + + assert( nReader<=SORTER_MAX_MERGE_COUNT ); + + while( NnTree = N; + pNew->pTask = 0; + pNew->aReadr = (PmaReader*)&pNew[1]; + pNew->aTree = (int*)&pNew->aReadr[N]; + } + return pNew; +} + +/* +** Free the MergeEngine object passed as the only argument. +*/ +static void vdbeMergeEngineFree(MergeEngine *pMerger){ + int i; + if( pMerger ){ + for(i=0; inTree; i++){ + vdbePmaReaderClear(&pMerger->aReadr[i]); + } + } + sqlite3_free(pMerger); +} + +/* +** Free all resources associated with the IncrMerger object indicated by +** the first argument. +*/ +static void vdbeIncrFree(IncrMerger *pIncr){ + if( pIncr ){ +#if SQLITE_MAX_WORKER_THREADS>0 + if( pIncr->bUseThread ){ + vdbeSorterJoinThread(pIncr->pTask); + if( pIncr->aFile[0].pFd ) sqlite3OsCloseFree(pIncr->aFile[0].pFd); + if( pIncr->aFile[1].pFd ) sqlite3OsCloseFree(pIncr->aFile[1].pFd); + } +#endif + vdbeMergeEngineFree(pIncr->pMerger); + sqlite3_free(pIncr); + } +} + +/* +** Reset a sorting cursor back to its original empty state. +*/ +SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *db, VdbeSorter *pSorter){ + int i; + (void)vdbeSorterJoinAll(pSorter, SQLITE_OK); + assert( pSorter->bUseThreads || pSorter->pReader==0 ); +#if SQLITE_MAX_WORKER_THREADS>0 + if( pSorter->pReader ){ + vdbePmaReaderClear(pSorter->pReader); + sqlite3DbFree(db, pSorter->pReader); + pSorter->pReader = 0; + } +#endif + vdbeMergeEngineFree(pSorter->pMerger); + pSorter->pMerger = 0; + for(i=0; inTask; i++){ + SortSubtask *pTask = &pSorter->aTask[i]; + vdbeSortSubtaskCleanup(db, pTask); + pTask->pSorter = pSorter; + } + if( pSorter->list.aMemory==0 ){ + vdbeSorterRecordFree(0, pSorter->list.pList); + } + pSorter->list.pList = 0; + pSorter->list.szPMA = 0; + pSorter->bUsePMA = 0; + pSorter->iMemory = 0; + pSorter->mxKeysize = 0; + sqlite3DbFree(db, pSorter->pUnpacked); + pSorter->pUnpacked = 0; +} + +/* +** Free any cursor components allocated by sqlite3VdbeSorterXXX routines. +*/ +SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){ + VdbeSorter *pSorter; + assert( pCsr->eCurType==CURTYPE_SORTER ); + pSorter = pCsr->uc.pSorter; + if( pSorter ){ + /* Increment db->nSpill by the total number of bytes of data written + ** to temp files by this sort operation. */ + int ii; + for(ii=0; iinTask; ii++){ + db->nSpill += pSorter->aTask[ii].nSpill; + } + sqlite3VdbeSorterReset(db, pSorter); + sqlite3_free(pSorter->list.aMemory); + sqlite3DbFree(db, pSorter); + pCsr->uc.pSorter = 0; + } +} + +#if SQLITE_MAX_MMAP_SIZE>0 +/* +** The first argument is a file-handle open on a temporary file. The file +** is guaranteed to be nByte bytes or smaller in size. This function +** attempts to extend the file to nByte bytes in size and to ensure that +** the VFS has memory mapped it. +** +** Whether or not the file does end up memory mapped of course depends on +** the specific VFS implementation. +*/ +static void vdbeSorterExtendFile(sqlite3 *db, sqlite3_file *pFd, i64 nByte){ + if( nByte<=(i64)(db->nMaxSorterMmap) && pFd->pMethods->iVersion>=3 ){ + void *p = 0; + int chunksize = 4*1024; + sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_CHUNK_SIZE, &chunksize); + sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_SIZE_HINT, &nByte); + sqlite3OsFetch(pFd, 0, (int)nByte, &p); + if( p ) sqlite3OsUnfetch(pFd, 0, p); + } +} +#else +# define vdbeSorterExtendFile(x,y,z) +#endif + +/* +** Allocate space for a file-handle and open a temporary file. If successful, +** set *ppFd to point to the malloc'd file-handle and return SQLITE_OK. +** Otherwise, set *ppFd to 0 and return an SQLite error code. +*/ +static int vdbeSorterOpenTempFile( + sqlite3 *db, /* Database handle doing sort */ + i64 nExtend, /* Attempt to extend file to this size */ + sqlite3_file **ppFd +){ + int rc; + if( sqlite3FaultSim(202) ) return SQLITE_IOERR_ACCESS; + rc = sqlite3OsOpenMalloc(db->pVfs, 0, ppFd, + SQLITE_OPEN_TEMP_JOURNAL | + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | + SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE, &rc + ); + if( rc==SQLITE_OK ){ + i64 max = SQLITE_MAX_MMAP_SIZE; + sqlite3OsFileControlHint(*ppFd, SQLITE_FCNTL_MMAP_SIZE, (void*)&max); + if( nExtend>0 ){ + vdbeSorterExtendFile(db, *ppFd, nExtend); + } + } + return rc; +} + +/* +** If it has not already been allocated, allocate the UnpackedRecord +** structure at pTask->pUnpacked. Return SQLITE_OK if successful (or +** if no allocation was required), or SQLITE_NOMEM otherwise. +*/ +static int vdbeSortAllocUnpacked(SortSubtask *pTask){ + if( pTask->pUnpacked==0 ){ + pTask->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pTask->pSorter->pKeyInfo); + if( pTask->pUnpacked==0 ) return SQLITE_NOMEM_BKPT; + pTask->pUnpacked->nField = pTask->pSorter->pKeyInfo->nKeyField; + pTask->pUnpacked->errCode = 0; + } + return SQLITE_OK; +} + + +/* +** Merge the two sorted lists p1 and p2 into a single list. +*/ +static SorterRecord *vdbeSorterMerge( + SortSubtask *pTask, /* Calling thread context */ + SorterRecord *p1, /* First list to merge */ + SorterRecord *p2 /* Second list to merge */ +){ + SorterRecord *pFinal = 0; + SorterRecord **pp = &pFinal; + int bCached = 0; + + assert( p1!=0 && p2!=0 ); + for(;;){ + int res; + res = pTask->xCompare( + pTask, &bCached, SRVAL(p1), p1->nVal, SRVAL(p2), p2->nVal + ); + + if( res<=0 ){ + *pp = p1; + pp = &p1->u.pNext; + p1 = p1->u.pNext; + if( p1==0 ){ + *pp = p2; + break; + } + }else{ + *pp = p2; + pp = &p2->u.pNext; + p2 = p2->u.pNext; + bCached = 0; + if( p2==0 ){ + *pp = p1; + break; + } + } + } + return pFinal; +} + +/* +** Return the SorterCompare function to compare values collected by the +** sorter object passed as the only argument. +*/ +static SorterCompare vdbeSorterGetCompare(VdbeSorter *p){ + if( p->typeMask==SORTER_TYPE_INTEGER ){ + return vdbeSorterCompareInt; + }else if( p->typeMask==SORTER_TYPE_TEXT ){ + return vdbeSorterCompareText; + } + return vdbeSorterCompare; +} + +/* +** Sort the linked list of records headed at pTask->pList. Return +** SQLITE_OK if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if +** an error occurs. +*/ +static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){ + int i; + SorterRecord *p; + int rc; + SorterRecord *aSlot[64]; + + rc = vdbeSortAllocUnpacked(pTask); + if( rc!=SQLITE_OK ) return rc; + + p = pList->pList; + pTask->xCompare = vdbeSorterGetCompare(pTask->pSorter); + memset(aSlot, 0, sizeof(aSlot)); + + while( p ){ + SorterRecord *pNext; + if( pList->aMemory ){ + if( (u8*)p==pList->aMemory ){ + pNext = 0; + }else{ + assert( p->u.iNextaMemory) ); + pNext = (SorterRecord*)&pList->aMemory[p->u.iNext]; + } + }else{ + pNext = p->u.pNext; + } + + p->u.pNext = 0; + for(i=0; aSlot[i]; i++){ + p = vdbeSorterMerge(pTask, p, aSlot[i]); + /* ,--Each aSlot[] holds twice as much as the previous. So we cannot use + ** | up all 64 aSlots[] with only a 64-bit address space. + ** v */ + assert( ipList = p; + + assert( pTask->pUnpacked->errCode==SQLITE_OK + || pTask->pUnpacked->errCode==SQLITE_NOMEM + ); + return pTask->pUnpacked->errCode; +} + +/* +** Initialize a PMA-writer object. +*/ +static void vdbePmaWriterInit( + sqlite3_file *pFd, /* File handle to write to */ + PmaWriter *p, /* Object to populate */ + int nBuf, /* Buffer size */ + i64 iStart /* Offset of pFd to begin writing at */ +){ + memset(p, 0, sizeof(PmaWriter)); + p->aBuffer = (u8*)sqlite3Malloc(nBuf); + if( !p->aBuffer ){ + p->eFWErr = SQLITE_NOMEM_BKPT; + }else{ + p->iBufEnd = p->iBufStart = (iStart % nBuf); + p->iWriteOff = iStart - p->iBufStart; + p->nBuffer = nBuf; + p->pFd = pFd; + } +} + +/* +** Write nData bytes of data to the PMA. Return SQLITE_OK +** if successful, or an SQLite error code if an error occurs. +*/ +static void vdbePmaWriteBlob(PmaWriter *p, u8 *pData, int nData){ + int nRem = nData; + while( nRem>0 && p->eFWErr==0 ){ + int nCopy = nRem; + if( nCopy>(p->nBuffer - p->iBufEnd) ){ + nCopy = p->nBuffer - p->iBufEnd; + } + + memcpy(&p->aBuffer[p->iBufEnd], &pData[nData-nRem], nCopy); + p->iBufEnd += nCopy; + if( p->iBufEnd==p->nBuffer ){ + p->eFWErr = sqlite3OsWrite(p->pFd, + &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, + p->iWriteOff + p->iBufStart + ); + p->nPmaSpill += (p->iBufEnd - p->iBufStart); + p->iBufStart = p->iBufEnd = 0; + p->iWriteOff += p->nBuffer; + } + assert( p->iBufEndnBuffer ); + + nRem -= nCopy; + } +} + +/* +** Flush any buffered data to disk and clean up the PMA-writer object. +** The results of using the PMA-writer after this call are undefined. +** Return SQLITE_OK if flushing the buffered data succeeds or is not +** required. Otherwise, return an SQLite error code. +** +** Before returning, set *piEof to the offset immediately following the +** last byte written to the file. Also, increment (*pnSpill) by the total +** number of bytes written to the file. +*/ +static int vdbePmaWriterFinish(PmaWriter *p, i64 *piEof, u64 *pnSpill){ + int rc; + if( p->eFWErr==0 && ALWAYS(p->aBuffer) && p->iBufEnd>p->iBufStart ){ + p->eFWErr = sqlite3OsWrite(p->pFd, + &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, + p->iWriteOff + p->iBufStart + ); + p->nPmaSpill += (p->iBufEnd - p->iBufStart); + } + *piEof = (p->iWriteOff + p->iBufEnd); + *pnSpill += p->nPmaSpill; + sqlite3_free(p->aBuffer); + rc = p->eFWErr; + memset(p, 0, sizeof(PmaWriter)); + return rc; +} + +/* +** Write value iVal encoded as a varint to the PMA. Return +** SQLITE_OK if successful, or an SQLite error code if an error occurs. +*/ +static void vdbePmaWriteVarint(PmaWriter *p, u64 iVal){ + int nByte; + u8 aByte[10]; + nByte = sqlite3PutVarint(aByte, iVal); + vdbePmaWriteBlob(p, aByte, nByte); +} + +/* +** Write the current contents of in-memory linked-list pList to a level-0 +** PMA in the temp file belonging to sub-task pTask. Return SQLITE_OK if +** successful, or an SQLite error code otherwise. +** +** The format of a PMA is: +** +** * A varint. This varint contains the total number of bytes of content +** in the PMA (not including the varint itself). +** +** * One or more records packed end-to-end in order of ascending keys. +** Each record consists of a varint followed by a blob of data (the +** key). The varint is the number of bytes in the blob of data. +*/ +static int vdbeSorterListToPMA(SortSubtask *pTask, SorterList *pList){ + sqlite3 *db = pTask->pSorter->db; + int rc = SQLITE_OK; /* Return code */ + PmaWriter writer; /* Object used to write to the file */ + +#ifdef SQLITE_DEBUG + /* Set iSz to the expected size of file pTask->file after writing the PMA. + ** This is used by an assert() statement at the end of this function. */ + i64 iSz = pList->szPMA + sqlite3VarintLen(pList->szPMA) + pTask->file.iEof; +#endif + + vdbeSorterWorkDebug(pTask, "enter"); + memset(&writer, 0, sizeof(PmaWriter)); + assert( pList->szPMA>0 ); + + /* If the first temporary PMA file has not been opened, open it now. */ + if( pTask->file.pFd==0 ){ + rc = vdbeSorterOpenTempFile(db, 0, &pTask->file.pFd); + assert( rc!=SQLITE_OK || pTask->file.pFd ); + assert( pTask->file.iEof==0 ); + assert( pTask->nPMA==0 ); + } + + /* Try to get the file to memory map */ + if( rc==SQLITE_OK ){ + vdbeSorterExtendFile(db, pTask->file.pFd, pTask->file.iEof+pList->szPMA+9); + } + + /* Sort the list */ + if( rc==SQLITE_OK ){ + rc = vdbeSorterSort(pTask, pList); + } + + if( rc==SQLITE_OK ){ + SorterRecord *p; + SorterRecord *pNext = 0; + + vdbePmaWriterInit(pTask->file.pFd, &writer, pTask->pSorter->pgsz, + pTask->file.iEof); + pTask->nPMA++; + vdbePmaWriteVarint(&writer, pList->szPMA); + for(p=pList->pList; p; p=pNext){ + pNext = p->u.pNext; + vdbePmaWriteVarint(&writer, p->nVal); + vdbePmaWriteBlob(&writer, SRVAL(p), p->nVal); + if( pList->aMemory==0 ) sqlite3_free(p); + } + pList->pList = p; + rc = vdbePmaWriterFinish(&writer, &pTask->file.iEof, &pTask->nSpill); + } + + vdbeSorterWorkDebug(pTask, "exit"); + assert( rc!=SQLITE_OK || pList->pList==0 ); + assert( rc!=SQLITE_OK || pTask->file.iEof==iSz ); + return rc; +} + +/* +** Advance the MergeEngine to its next entry. +** Set *pbEof to true there is no next entry because +** the MergeEngine has reached the end of all its inputs. +** +** Return SQLITE_OK if successful or an error code if an error occurs. +*/ +static int vdbeMergeEngineStep( + MergeEngine *pMerger, /* The merge engine to advance to the next row */ + int *pbEof /* Set TRUE at EOF. Set false for more content */ +){ + int rc; + int iPrev = pMerger->aTree[1];/* Index of PmaReader to advance */ + SortSubtask *pTask = pMerger->pTask; + + /* Advance the current PmaReader */ + rc = vdbePmaReaderNext(&pMerger->aReadr[iPrev]); + + /* Update contents of aTree[] */ + if( rc==SQLITE_OK ){ + int i; /* Index of aTree[] to recalculate */ + PmaReader *pReadr1; /* First PmaReader to compare */ + PmaReader *pReadr2; /* Second PmaReader to compare */ + int bCached = 0; + + /* Find the first two PmaReaders to compare. The one that was just + ** advanced (iPrev) and the one next to it in the array. */ + pReadr1 = &pMerger->aReadr[(iPrev & 0xFFFE)]; + pReadr2 = &pMerger->aReadr[(iPrev | 0x0001)]; + + for(i=(pMerger->nTree+iPrev)/2; i>0; i=i/2){ + /* Compare pReadr1 and pReadr2. Store the result in variable iRes. */ + int iRes; + if( pReadr1->pFd==0 ){ + iRes = +1; + }else if( pReadr2->pFd==0 ){ + iRes = -1; + }else{ + iRes = pTask->xCompare(pTask, &bCached, + pReadr1->aKey, pReadr1->nKey, pReadr2->aKey, pReadr2->nKey + ); + } + + /* If pReadr1 contained the smaller value, set aTree[i] to its index. + ** Then set pReadr2 to the next PmaReader to compare to pReadr1. In this + ** case there is no cache of pReadr2 in pTask->pUnpacked, so set + ** pKey2 to point to the record belonging to pReadr2. + ** + ** Alternatively, if pReadr2 contains the smaller of the two values, + ** set aTree[i] to its index and update pReadr1. If vdbeSorterCompare() + ** was actually called above, then pTask->pUnpacked now contains + ** a value equivalent to pReadr2. So set pKey2 to NULL to prevent + ** vdbeSorterCompare() from decoding pReadr2 again. + ** + ** If the two values were equal, then the value from the oldest + ** PMA should be considered smaller. The VdbeSorter.aReadr[] array + ** is sorted from oldest to newest, so pReadr1 contains older values + ** than pReadr2 iff (pReadr1aTree[i] = (int)(pReadr1 - pMerger->aReadr); + pReadr2 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ]; + bCached = 0; + }else{ + if( pReadr1->pFd ) bCached = 0; + pMerger->aTree[i] = (int)(pReadr2 - pMerger->aReadr); + pReadr1 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ]; + } + } + *pbEof = (pMerger->aReadr[pMerger->aTree[1]].pFd==0); + } + + return (rc==SQLITE_OK ? pTask->pUnpacked->errCode : rc); +} + +#if SQLITE_MAX_WORKER_THREADS>0 +/* +** The main routine for background threads that write level-0 PMAs. +*/ +static void *vdbeSorterFlushThread(void *pCtx){ + SortSubtask *pTask = (SortSubtask*)pCtx; + int rc; /* Return code */ + assert( pTask->bDone==0 ); + rc = vdbeSorterListToPMA(pTask, &pTask->list); + pTask->bDone = 1; + return SQLITE_INT_TO_PTR(rc); +} +#endif /* SQLITE_MAX_WORKER_THREADS>0 */ + +/* +** Flush the current contents of VdbeSorter.list to a new PMA, possibly +** using a background thread. +*/ +static int vdbeSorterFlushPMA(VdbeSorter *pSorter){ +#if SQLITE_MAX_WORKER_THREADS==0 + pSorter->bUsePMA = 1; + return vdbeSorterListToPMA(&pSorter->aTask[0], &pSorter->list); +#else + int rc = SQLITE_OK; + int i; + SortSubtask *pTask = 0; /* Thread context used to create new PMA */ + int nWorker = (pSorter->nTask-1); + + /* Set the flag to indicate that at least one PMA has been written. + ** Or will be, anyhow. */ + pSorter->bUsePMA = 1; + + /* Select a sub-task to sort and flush the current list of in-memory + ** records to disk. If the sorter is running in multi-threaded mode, + ** round-robin between the first (pSorter->nTask-1) tasks. Except, if + ** the background thread from a sub-tasks previous turn is still running, + ** skip it. If the first (pSorter->nTask-1) sub-tasks are all still busy, + ** fall back to using the final sub-task. The first (pSorter->nTask-1) + ** sub-tasks are preferred as they use background threads - the final + ** sub-task uses the main thread. */ + for(i=0; iiPrev + i + 1) % nWorker; + pTask = &pSorter->aTask[iTest]; + if( pTask->bDone ){ + rc = vdbeSorterJoinThread(pTask); + } + if( rc!=SQLITE_OK || pTask->pThread==0 ) break; + } + + if( rc==SQLITE_OK ){ + if( i==nWorker ){ + /* Use the foreground thread for this operation */ + rc = vdbeSorterListToPMA(&pSorter->aTask[nWorker], &pSorter->list); + }else{ + /* Launch a background thread for this operation */ + u8 *aMem; + void *pCtx; + + assert( pTask!=0 ); + assert( pTask->pThread==0 && pTask->bDone==0 ); + assert( pTask->list.pList==0 ); + assert( pTask->list.aMemory==0 || pSorter->list.aMemory!=0 ); + + aMem = pTask->list.aMemory; + pCtx = (void*)pTask; + pSorter->iPrev = (u8)(pTask - pSorter->aTask); + pTask->list = pSorter->list; + pSorter->list.pList = 0; + pSorter->list.szPMA = 0; + if( aMem ){ + pSorter->list.aMemory = aMem; + pSorter->nMemory = sqlite3MallocSize(aMem); + }else if( pSorter->list.aMemory ){ + pSorter->list.aMemory = sqlite3Malloc(pSorter->nMemory); + if( !pSorter->list.aMemory ) return SQLITE_NOMEM_BKPT; + } + + rc = vdbeSorterCreateThread(pTask, vdbeSorterFlushThread, pCtx); + } + } + + return rc; +#endif /* SQLITE_MAX_WORKER_THREADS!=0 */ +} + +/* +** Add a record to the sorter. +*/ +SQLITE_PRIVATE int sqlite3VdbeSorterWrite( + const VdbeCursor *pCsr, /* Sorter cursor */ + Mem *pVal /* Memory cell containing record */ +){ + VdbeSorter *pSorter; + int rc = SQLITE_OK; /* Return Code */ + SorterRecord *pNew; /* New list element */ + int bFlush; /* True to flush contents of memory to PMA */ + i64 nReq; /* Bytes of memory required */ + i64 nPMA; /* Bytes of PMA space required */ + int t; /* serial type of first record field */ + + assert( pCsr->eCurType==CURTYPE_SORTER ); + pSorter = pCsr->uc.pSorter; + getVarint32NR((const u8*)&pVal->z[1], t); + if( t>0 && t<10 && t!=7 ){ + pSorter->typeMask &= SORTER_TYPE_INTEGER; + }else if( t>10 && (t & 0x01) ){ + pSorter->typeMask &= SORTER_TYPE_TEXT; + }else{ + pSorter->typeMask = 0; + } + + assert( pSorter ); + + /* Figure out whether or not the current contents of memory should be + ** flushed to a PMA before continuing. If so, do so. + ** + ** If using the single large allocation mode (pSorter->aMemory!=0), then + ** flush the contents of memory to a new PMA if (a) at least one value is + ** already in memory and (b) the new value will not fit in memory. + ** + ** Or, if using separate allocations for each record, flush the contents + ** of memory to a PMA if either of the following are true: + ** + ** * The total memory allocated for the in-memory list is greater + ** than (page-size * cache-size), or + ** + ** * The total memory allocated for the in-memory list is greater + ** than (page-size * 10) and sqlite3HeapNearlyFull() returns true. + */ + nReq = pVal->n + sizeof(SorterRecord); + nPMA = pVal->n + sqlite3VarintLen(pVal->n); + if( pSorter->mxPmaSize ){ + if( pSorter->list.aMemory ){ + bFlush = pSorter->iMemory && (pSorter->iMemory+nReq) > pSorter->mxPmaSize; + }else{ + bFlush = ( + (pSorter->list.szPMA > pSorter->mxPmaSize) + || (pSorter->list.szPMA > pSorter->mnPmaSize && sqlite3HeapNearlyFull()) + ); + } + if( bFlush ){ + rc = vdbeSorterFlushPMA(pSorter); + pSorter->list.szPMA = 0; + pSorter->iMemory = 0; + assert( rc!=SQLITE_OK || pSorter->list.pList==0 ); + } + } + + pSorter->list.szPMA += nPMA; + if( nPMA>pSorter->mxKeysize ){ + pSorter->mxKeysize = nPMA; + } + + if( pSorter->list.aMemory ){ + int nMin = pSorter->iMemory + nReq; + + if( nMin>pSorter->nMemory ){ + u8 *aNew; + sqlite3_int64 nNew = 2 * (sqlite3_int64)pSorter->nMemory; + int iListOff = -1; + if( pSorter->list.pList ){ + iListOff = (u8*)pSorter->list.pList - pSorter->list.aMemory; + } + while( nNew < nMin ) nNew = nNew*2; + if( nNew > pSorter->mxPmaSize ) nNew = pSorter->mxPmaSize; + if( nNew < nMin ) nNew = nMin; + aNew = sqlite3Realloc(pSorter->list.aMemory, nNew); + if( !aNew ) return SQLITE_NOMEM_BKPT; + if( iListOff>=0 ){ + pSorter->list.pList = (SorterRecord*)&aNew[iListOff]; + } + pSorter->list.aMemory = aNew; + pSorter->nMemory = nNew; + } + + pNew = (SorterRecord*)&pSorter->list.aMemory[pSorter->iMemory]; + pSorter->iMemory += ROUND8(nReq); + if( pSorter->list.pList ){ + pNew->u.iNext = (int)((u8*)(pSorter->list.pList) - pSorter->list.aMemory); + } + }else{ + pNew = (SorterRecord *)sqlite3Malloc(nReq); + if( pNew==0 ){ + return SQLITE_NOMEM_BKPT; + } + pNew->u.pNext = pSorter->list.pList; + } + + memcpy(SRVAL(pNew), pVal->z, pVal->n); + pNew->nVal = pVal->n; + pSorter->list.pList = pNew; + + return rc; +} + +/* +** Read keys from pIncr->pMerger and populate pIncr->aFile[1]. The format +** of the data stored in aFile[1] is the same as that used by regular PMAs, +** except that the number-of-bytes varint is omitted from the start. +*/ +static int vdbeIncrPopulate(IncrMerger *pIncr){ + int rc = SQLITE_OK; + int rc2; + i64 iStart = pIncr->iStartOff; + SorterFile *pOut = &pIncr->aFile[1]; + SortSubtask *pTask = pIncr->pTask; + MergeEngine *pMerger = pIncr->pMerger; + PmaWriter writer; + assert( pIncr->bEof==0 ); + + vdbeSorterPopulateDebug(pTask, "enter"); + + vdbePmaWriterInit(pOut->pFd, &writer, pTask->pSorter->pgsz, iStart); + while( rc==SQLITE_OK ){ + int dummy; + PmaReader *pReader = &pMerger->aReadr[ pMerger->aTree[1] ]; + int nKey = pReader->nKey; + i64 iEof = writer.iWriteOff + writer.iBufEnd; + + /* Check if the output file is full or if the input has been exhausted. + ** In either case exit the loop. */ + if( pReader->pFd==0 ) break; + if( (iEof + nKey + sqlite3VarintLen(nKey))>(iStart + pIncr->mxSz) ) break; + + /* Write the next key to the output. */ + vdbePmaWriteVarint(&writer, nKey); + vdbePmaWriteBlob(&writer, pReader->aKey, nKey); + assert( pIncr->pMerger->pTask==pTask ); + rc = vdbeMergeEngineStep(pIncr->pMerger, &dummy); + } + + rc2 = vdbePmaWriterFinish(&writer, &pOut->iEof, &pTask->nSpill); + if( rc==SQLITE_OK ) rc = rc2; + vdbeSorterPopulateDebug(pTask, "exit"); + return rc; +} + +#if SQLITE_MAX_WORKER_THREADS>0 +/* +** The main routine for background threads that populate aFile[1] of +** multi-threaded IncrMerger objects. +*/ +static void *vdbeIncrPopulateThread(void *pCtx){ + IncrMerger *pIncr = (IncrMerger*)pCtx; + void *pRet = SQLITE_INT_TO_PTR( vdbeIncrPopulate(pIncr) ); + pIncr->pTask->bDone = 1; + return pRet; +} + +/* +** Launch a background thread to populate aFile[1] of pIncr. +*/ +static int vdbeIncrBgPopulate(IncrMerger *pIncr){ + void *p = (void*)pIncr; + assert( pIncr->bUseThread ); + return vdbeSorterCreateThread(pIncr->pTask, vdbeIncrPopulateThread, p); +} +#endif + +/* +** This function is called when the PmaReader corresponding to pIncr has +** finished reading the contents of aFile[0]. Its purpose is to "refill" +** aFile[0] such that the PmaReader should start rereading it from the +** beginning. +** +** For single-threaded objects, this is accomplished by literally reading +** keys from pIncr->pMerger and repopulating aFile[0]. +** +** For multi-threaded objects, all that is required is to wait until the +** background thread is finished (if it is not already) and then swap +** aFile[0] and aFile[1] in place. If the contents of pMerger have not +** been exhausted, this function also launches a new background thread +** to populate the new aFile[1]. +** +** SQLITE_OK is returned on success, or an SQLite error code otherwise. +*/ +static int vdbeIncrSwap(IncrMerger *pIncr){ + int rc = SQLITE_OK; + +#if SQLITE_MAX_WORKER_THREADS>0 + if( pIncr->bUseThread ){ + rc = vdbeSorterJoinThread(pIncr->pTask); + + if( rc==SQLITE_OK ){ + SorterFile f0 = pIncr->aFile[0]; + pIncr->aFile[0] = pIncr->aFile[1]; + pIncr->aFile[1] = f0; + } + + if( rc==SQLITE_OK ){ + if( pIncr->aFile[0].iEof==pIncr->iStartOff ){ + pIncr->bEof = 1; + }else{ + rc = vdbeIncrBgPopulate(pIncr); + } + } + }else +#endif + { + rc = vdbeIncrPopulate(pIncr); + pIncr->aFile[0] = pIncr->aFile[1]; + if( pIncr->aFile[0].iEof==pIncr->iStartOff ){ + pIncr->bEof = 1; + } + } + + return rc; +} + +/* +** Allocate and return a new IncrMerger object to read data from pMerger. +** +** If an OOM condition is encountered, return NULL. In this case free the +** pMerger argument before returning. +*/ +static int vdbeIncrMergerNew( + SortSubtask *pTask, /* The thread that will be using the new IncrMerger */ + MergeEngine *pMerger, /* The MergeEngine that the IncrMerger will control */ + IncrMerger **ppOut /* Write the new IncrMerger here */ +){ + int rc = SQLITE_OK; + IncrMerger *pIncr = *ppOut = (IncrMerger*) + (sqlite3FaultSim(100) ? 0 : sqlite3MallocZero(sizeof(*pIncr))); + if( pIncr ){ + pIncr->pMerger = pMerger; + pIncr->pTask = pTask; + pIncr->mxSz = MAX(pTask->pSorter->mxKeysize+9,pTask->pSorter->mxPmaSize/2); + pTask->file2.iEof += pIncr->mxSz; + }else{ + vdbeMergeEngineFree(pMerger); + rc = SQLITE_NOMEM_BKPT; + } + assert( *ppOut!=0 || rc!=SQLITE_OK ); + return rc; +} + +#if SQLITE_MAX_WORKER_THREADS>0 +/* +** Set the "use-threads" flag on object pIncr. +*/ +static void vdbeIncrMergerSetThreads(IncrMerger *pIncr){ + pIncr->bUseThread = 1; + pIncr->pTask->file2.iEof -= pIncr->mxSz; +} +#endif /* SQLITE_MAX_WORKER_THREADS>0 */ + + + +/* +** Recompute pMerger->aTree[iOut] by comparing the next keys on the +** two PmaReaders that feed that entry. Neither of the PmaReaders +** are advanced. This routine merely does the comparison. +*/ +static void vdbeMergeEngineCompare( + MergeEngine *pMerger, /* Merge engine containing PmaReaders to compare */ + int iOut /* Store the result in pMerger->aTree[iOut] */ +){ + int i1; + int i2; + int iRes; + PmaReader *p1; + PmaReader *p2; + + assert( iOutnTree && iOut>0 ); + + if( iOut>=(pMerger->nTree/2) ){ + i1 = (iOut - pMerger->nTree/2) * 2; + i2 = i1 + 1; + }else{ + i1 = pMerger->aTree[iOut*2]; + i2 = pMerger->aTree[iOut*2+1]; + } + + p1 = &pMerger->aReadr[i1]; + p2 = &pMerger->aReadr[i2]; + + if( p1->pFd==0 ){ + iRes = i2; + }else if( p2->pFd==0 ){ + iRes = i1; + }else{ + SortSubtask *pTask = pMerger->pTask; + int bCached = 0; + int res; + assert( pTask->pUnpacked!=0 ); /* from vdbeSortSubtaskMain() */ + res = pTask->xCompare( + pTask, &bCached, p1->aKey, p1->nKey, p2->aKey, p2->nKey + ); + if( res<=0 ){ + iRes = i1; + }else{ + iRes = i2; + } + } + + pMerger->aTree[iOut] = iRes; +} + +/* +** Allowed values for the eMode parameter to vdbeMergeEngineInit() +** and vdbePmaReaderIncrMergeInit(). +** +** Only INCRINIT_NORMAL is valid in single-threaded builds (when +** SQLITE_MAX_WORKER_THREADS==0). The other values are only used +** when there exists one or more separate worker threads. +*/ +#define INCRINIT_NORMAL 0 +#define INCRINIT_TASK 1 +#define INCRINIT_ROOT 2 + +/* +** Forward reference required as the vdbeIncrMergeInit() and +** vdbePmaReaderIncrInit() routines are called mutually recursively when +** building a merge tree. +*/ +static int vdbePmaReaderIncrInit(PmaReader *pReadr, int eMode); + +/* +** Initialize the MergeEngine object passed as the second argument. Once this +** function returns, the first key of merged data may be read from the +** MergeEngine object in the usual fashion. +** +** If argument eMode is INCRINIT_ROOT, then it is assumed that any IncrMerge +** objects attached to the PmaReader objects that the merger reads from have +** already been populated, but that they have not yet populated aFile[0] and +** set the PmaReader objects up to read from it. In this case all that is +** required is to call vdbePmaReaderNext() on each PmaReader to point it at +** its first key. +** +** Otherwise, if eMode is any value other than INCRINIT_ROOT, then use +** vdbePmaReaderIncrMergeInit() to initialize each PmaReader that feeds data +** to pMerger. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +*/ +static int vdbeMergeEngineInit( + SortSubtask *pTask, /* Thread that will run pMerger */ + MergeEngine *pMerger, /* MergeEngine to initialize */ + int eMode /* One of the INCRINIT_XXX constants */ +){ + int rc = SQLITE_OK; /* Return code */ + int i; /* For looping over PmaReader objects */ + int nTree; /* Number of subtrees to merge */ + + /* Failure to allocate the merge would have been detected prior to + ** invoking this routine */ + assert( pMerger!=0 ); + + /* eMode is always INCRINIT_NORMAL in single-threaded mode */ + assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL ); + + /* Verify that the MergeEngine is assigned to a single thread */ + assert( pMerger->pTask==0 ); + pMerger->pTask = pTask; + + nTree = pMerger->nTree; + for(i=0; i0 && eMode==INCRINIT_ROOT ){ + /* PmaReaders should be normally initialized in order, as if they are + ** reading from the same temp file this makes for more linear file IO. + ** However, in the INCRINIT_ROOT case, if PmaReader aReadr[nTask-1] is + ** in use it will block the vdbePmaReaderNext() call while it uses + ** the main thread to fill its buffer. So calling PmaReaderNext() + ** on this PmaReader before any of the multi-threaded PmaReaders takes + ** better advantage of multi-processor hardware. */ + rc = vdbePmaReaderNext(&pMerger->aReadr[nTree-i-1]); + }else{ + rc = vdbePmaReaderIncrInit(&pMerger->aReadr[i], INCRINIT_NORMAL); + } + if( rc!=SQLITE_OK ) return rc; + } + + for(i=pMerger->nTree-1; i>0; i--){ + vdbeMergeEngineCompare(pMerger, i); + } + return pTask->pUnpacked->errCode; +} + +/* +** The PmaReader passed as the first argument is guaranteed to be an +** incremental-reader (pReadr->pIncr!=0). This function serves to open +** and/or initialize the temp file related fields of the IncrMerge +** object at (pReadr->pIncr). +** +** If argument eMode is set to INCRINIT_NORMAL, then all PmaReaders +** in the sub-tree headed by pReadr are also initialized. Data is then +** loaded into the buffers belonging to pReadr and it is set to point to +** the first key in its range. +** +** If argument eMode is set to INCRINIT_TASK, then pReadr is guaranteed +** to be a multi-threaded PmaReader and this function is being called in a +** background thread. In this case all PmaReaders in the sub-tree are +** initialized as for INCRINIT_NORMAL and the aFile[1] buffer belonging to +** pReadr is populated. However, pReadr itself is not set up to point +** to its first key. A call to vdbePmaReaderNext() is still required to do +** that. +** +** The reason this function does not call vdbePmaReaderNext() immediately +** in the INCRINIT_TASK case is that vdbePmaReaderNext() assumes that it has +** to block on thread (pTask->thread) before accessing aFile[1]. But, since +** this entire function is being run by thread (pTask->thread), that will +** lead to the current background thread attempting to join itself. +** +** Finally, if argument eMode is set to INCRINIT_ROOT, it may be assumed +** that pReadr->pIncr is a multi-threaded IncrMerge objects, and that all +** child-trees have already been initialized using IncrInit(INCRINIT_TASK). +** In this case vdbePmaReaderNext() is called on all child PmaReaders and +** the current PmaReader set to point to the first key in its range. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +*/ +static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode){ + int rc = SQLITE_OK; + IncrMerger *pIncr = pReadr->pIncr; + SortSubtask *pTask = pIncr->pTask; + sqlite3 *db = pTask->pSorter->db; + + /* eMode is always INCRINIT_NORMAL in single-threaded mode */ + assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL ); + + rc = vdbeMergeEngineInit(pTask, pIncr->pMerger, eMode); + + /* Set up the required files for pIncr. A multi-threaded IncrMerge object + ** requires two temp files to itself, whereas a single-threaded object + ** only requires a region of pTask->file2. */ + if( rc==SQLITE_OK ){ + int mxSz = pIncr->mxSz; +#if SQLITE_MAX_WORKER_THREADS>0 + if( pIncr->bUseThread ){ + rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[0].pFd); + if( rc==SQLITE_OK ){ + rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[1].pFd); + } + }else +#endif + /*if( !pIncr->bUseThread )*/{ + if( pTask->file2.pFd==0 ){ + assert( pTask->file2.iEof>0 ); + rc = vdbeSorterOpenTempFile(db, pTask->file2.iEof, &pTask->file2.pFd); + pTask->file2.iEof = 0; + } + if( rc==SQLITE_OK ){ + pIncr->aFile[1].pFd = pTask->file2.pFd; + pIncr->iStartOff = pTask->file2.iEof; + pTask->file2.iEof += mxSz; + } + } + } + +#if SQLITE_MAX_WORKER_THREADS>0 + if( rc==SQLITE_OK && pIncr->bUseThread ){ + /* Use the current thread to populate aFile[1], even though this + ** PmaReader is multi-threaded. If this is an INCRINIT_TASK object, + ** then this function is already running in background thread + ** pIncr->pTask->thread. + ** + ** If this is the INCRINIT_ROOT object, then it is running in the + ** main VDBE thread. But that is Ok, as that thread cannot return + ** control to the VDBE or proceed with anything useful until the + ** first results are ready from this merger object anyway. + */ + assert( eMode==INCRINIT_ROOT || eMode==INCRINIT_TASK ); + rc = vdbeIncrPopulate(pIncr); + } +#endif + + if( rc==SQLITE_OK && (SQLITE_MAX_WORKER_THREADS==0 || eMode!=INCRINIT_TASK) ){ + rc = vdbePmaReaderNext(pReadr); + } + + return rc; +} + +#if SQLITE_MAX_WORKER_THREADS>0 +/* +** The main routine for vdbePmaReaderIncrMergeInit() operations run in +** background threads. +*/ +static void *vdbePmaReaderBgIncrInit(void *pCtx){ + PmaReader *pReader = (PmaReader*)pCtx; + void *pRet = SQLITE_INT_TO_PTR( + vdbePmaReaderIncrMergeInit(pReader,INCRINIT_TASK) + ); + pReader->pIncr->pTask->bDone = 1; + return pRet; +} +#endif + +/* +** If the PmaReader passed as the first argument is not an incremental-reader +** (if pReadr->pIncr==0), then this function is a no-op. Otherwise, it invokes +** the vdbePmaReaderIncrMergeInit() function with the parameters passed to +** this routine to initialize the incremental merge. +** +** If the IncrMerger object is multi-threaded (IncrMerger.bUseThread==1), +** then a background thread is launched to call vdbePmaReaderIncrMergeInit(). +** Or, if the IncrMerger is single threaded, the same function is called +** using the current thread. +*/ +static int vdbePmaReaderIncrInit(PmaReader *pReadr, int eMode){ + IncrMerger *pIncr = pReadr->pIncr; /* Incremental merger */ + int rc = SQLITE_OK; /* Return code */ + if( pIncr ){ +#if SQLITE_MAX_WORKER_THREADS>0 + assert( pIncr->bUseThread==0 || eMode==INCRINIT_TASK ); + if( pIncr->bUseThread ){ + void *pCtx = (void*)pReadr; + rc = vdbeSorterCreateThread(pIncr->pTask, vdbePmaReaderBgIncrInit, pCtx); + }else +#endif + { + rc = vdbePmaReaderIncrMergeInit(pReadr, eMode); + } + } + return rc; +} + +/* +** Allocate a new MergeEngine object to merge the contents of nPMA level-0 +** PMAs from pTask->file. If no error occurs, set *ppOut to point to +** the new object and return SQLITE_OK. Or, if an error does occur, set *ppOut +** to NULL and return an SQLite error code. +** +** When this function is called, *piOffset is set to the offset of the +** first PMA to read from pTask->file. Assuming no error occurs, it is +** set to the offset immediately following the last byte of the last +** PMA before returning. If an error does occur, then the final value of +** *piOffset is undefined. +*/ +static int vdbeMergeEngineLevel0( + SortSubtask *pTask, /* Sorter task to read from */ + int nPMA, /* Number of PMAs to read */ + i64 *piOffset, /* IN/OUT: Readr offset in pTask->file */ + MergeEngine **ppOut /* OUT: New merge-engine */ +){ + MergeEngine *pNew; /* Merge engine to return */ + i64 iOff = *piOffset; + int i; + int rc = SQLITE_OK; + + *ppOut = pNew = vdbeMergeEngineNew(nPMA); + if( pNew==0 ) rc = SQLITE_NOMEM_BKPT; + + for(i=0; iaReadr[i]; + rc = vdbePmaReaderInit(pTask, &pTask->file, iOff, pReadr, &nDummy); + iOff = pReadr->iEof; + } + + if( rc!=SQLITE_OK ){ + vdbeMergeEngineFree(pNew); + *ppOut = 0; + } + *piOffset = iOff; + return rc; +} + +/* +** Return the depth of a tree comprising nPMA PMAs, assuming a fanout of +** SORTER_MAX_MERGE_COUNT. The returned value does not include leaf nodes. +** +** i.e. +** +** nPMA<=16 -> TreeDepth() == 0 +** nPMA<=256 -> TreeDepth() == 1 +** nPMA<=65536 -> TreeDepth() == 2 +*/ +static int vdbeSorterTreeDepth(int nPMA){ + int nDepth = 0; + i64 nDiv = SORTER_MAX_MERGE_COUNT; + while( nDiv < (i64)nPMA ){ + nDiv = nDiv * SORTER_MAX_MERGE_COUNT; + nDepth++; + } + return nDepth; +} + +/* +** pRoot is the root of an incremental merge-tree with depth nDepth (according +** to vdbeSorterTreeDepth()). pLeaf is the iSeq'th leaf to be added to the +** tree, counting from zero. This function adds pLeaf to the tree. +** +** If successful, SQLITE_OK is returned. If an error occurs, an SQLite error +** code is returned and pLeaf is freed. +*/ +static int vdbeSorterAddToTree( + SortSubtask *pTask, /* Task context */ + int nDepth, /* Depth of tree according to TreeDepth() */ + int iSeq, /* Sequence number of leaf within tree */ + MergeEngine *pRoot, /* Root of tree */ + MergeEngine *pLeaf /* Leaf to add to tree */ +){ + int rc = SQLITE_OK; + int nDiv = 1; + int i; + MergeEngine *p = pRoot; + IncrMerger *pIncr; + + rc = vdbeIncrMergerNew(pTask, pLeaf, &pIncr); + + for(i=1; iaReadr[iIter]; + + if( pReadr->pIncr==0 ){ + MergeEngine *pNew = vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT); + if( pNew==0 ){ + rc = SQLITE_NOMEM_BKPT; + }else{ + rc = vdbeIncrMergerNew(pTask, pNew, &pReadr->pIncr); + } + } + if( rc==SQLITE_OK ){ + p = pReadr->pIncr->pMerger; + nDiv = nDiv / SORTER_MAX_MERGE_COUNT; + } + } + + if( rc==SQLITE_OK ){ + p->aReadr[iSeq % SORTER_MAX_MERGE_COUNT].pIncr = pIncr; + }else{ + vdbeIncrFree(pIncr); + } + return rc; +} + +/* +** This function is called as part of a SorterRewind() operation on a sorter +** that has already written two or more level-0 PMAs to one or more temp +** files. It builds a tree of MergeEngine/IncrMerger/PmaReader objects that +** can be used to incrementally merge all PMAs on disk. +** +** If successful, SQLITE_OK is returned and *ppOut set to point to the +** MergeEngine object at the root of the tree before returning. Or, if an +** error occurs, an SQLite error code is returned and the final value +** of *ppOut is undefined. +*/ +static int vdbeSorterMergeTreeBuild( + VdbeSorter *pSorter, /* The VDBE cursor that implements the sort */ + MergeEngine **ppOut /* Write the MergeEngine here */ +){ + MergeEngine *pMain = 0; + int rc = SQLITE_OK; + int iTask; + +#if SQLITE_MAX_WORKER_THREADS>0 + /* If the sorter uses more than one task, then create the top-level + ** MergeEngine here. This MergeEngine will read data from exactly + ** one PmaReader per sub-task. */ + assert( pSorter->bUseThreads || pSorter->nTask==1 ); + if( pSorter->nTask>1 ){ + pMain = vdbeMergeEngineNew(pSorter->nTask); + if( pMain==0 ) rc = SQLITE_NOMEM_BKPT; + } +#endif + + for(iTask=0; rc==SQLITE_OK && iTasknTask; iTask++){ + SortSubtask *pTask = &pSorter->aTask[iTask]; + assert( pTask->nPMA>0 || SQLITE_MAX_WORKER_THREADS>0 ); + if( SQLITE_MAX_WORKER_THREADS==0 || pTask->nPMA ){ + MergeEngine *pRoot = 0; /* Root node of tree for this task */ + int nDepth = vdbeSorterTreeDepth(pTask->nPMA); + i64 iReadOff = 0; + + if( pTask->nPMA<=SORTER_MAX_MERGE_COUNT ){ + rc = vdbeMergeEngineLevel0(pTask, pTask->nPMA, &iReadOff, &pRoot); + }else{ + int i; + int iSeq = 0; + pRoot = vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT); + if( pRoot==0 ) rc = SQLITE_NOMEM_BKPT; + for(i=0; inPMA && rc==SQLITE_OK; i += SORTER_MAX_MERGE_COUNT){ + MergeEngine *pMerger = 0; /* New level-0 PMA merger */ + int nReader; /* Number of level-0 PMAs to merge */ + + nReader = MIN(pTask->nPMA - i, SORTER_MAX_MERGE_COUNT); + rc = vdbeMergeEngineLevel0(pTask, nReader, &iReadOff, &pMerger); + if( rc==SQLITE_OK ){ + rc = vdbeSorterAddToTree(pTask, nDepth, iSeq++, pRoot, pMerger); + } + } + } + + if( rc==SQLITE_OK ){ +#if SQLITE_MAX_WORKER_THREADS>0 + if( pMain!=0 ){ + rc = vdbeIncrMergerNew(pTask, pRoot, &pMain->aReadr[iTask].pIncr); + }else +#endif + { + assert( pMain==0 ); + pMain = pRoot; + } + }else{ + vdbeMergeEngineFree(pRoot); + } + } + } + + if( rc!=SQLITE_OK ){ + vdbeMergeEngineFree(pMain); + pMain = 0; + } + *ppOut = pMain; + return rc; +} + +/* +** This function is called as part of an sqlite3VdbeSorterRewind() operation +** on a sorter that has written two or more PMAs to temporary files. It sets +** up either VdbeSorter.pMerger (for single threaded sorters) or pReader +** (for multi-threaded sorters) so that it can be used to iterate through +** all records stored in the sorter. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +*/ +static int vdbeSorterSetupMerge(VdbeSorter *pSorter){ + int rc; /* Return code */ + SortSubtask *pTask0 = &pSorter->aTask[0]; + MergeEngine *pMain = 0; +#if SQLITE_MAX_WORKER_THREADS + sqlite3 *db = pTask0->pSorter->db; + int i; + SorterCompare xCompare = vdbeSorterGetCompare(pSorter); + for(i=0; inTask; i++){ + pSorter->aTask[i].xCompare = xCompare; + } +#endif + + rc = vdbeSorterMergeTreeBuild(pSorter, &pMain); + if( rc==SQLITE_OK ){ +#if SQLITE_MAX_WORKER_THREADS + assert( pSorter->bUseThreads==0 || pSorter->nTask>1 ); + if( pSorter->bUseThreads ){ + int iTask; + PmaReader *pReadr = 0; + SortSubtask *pLast = &pSorter->aTask[pSorter->nTask-1]; + rc = vdbeSortAllocUnpacked(pLast); + if( rc==SQLITE_OK ){ + pReadr = (PmaReader*)sqlite3DbMallocZero(db, sizeof(PmaReader)); + pSorter->pReader = pReadr; + if( pReadr==0 ) rc = SQLITE_NOMEM_BKPT; + } + if( rc==SQLITE_OK ){ + rc = vdbeIncrMergerNew(pLast, pMain, &pReadr->pIncr); + if( rc==SQLITE_OK ){ + vdbeIncrMergerSetThreads(pReadr->pIncr); + for(iTask=0; iTask<(pSorter->nTask-1); iTask++){ + IncrMerger *pIncr; + if( (pIncr = pMain->aReadr[iTask].pIncr) ){ + vdbeIncrMergerSetThreads(pIncr); + assert( pIncr->pTask!=pLast ); + } + } + for(iTask=0; rc==SQLITE_OK && iTasknTask; iTask++){ + /* Check that: + ** + ** a) The incremental merge object is configured to use the + ** right task, and + ** b) If it is using task (nTask-1), it is configured to run + ** in single-threaded mode. This is important, as the + ** root merge (INCRINIT_ROOT) will be using the same task + ** object. + */ + PmaReader *p = &pMain->aReadr[iTask]; + assert( p->pIncr==0 || ( + (p->pIncr->pTask==&pSorter->aTask[iTask]) /* a */ + && (iTask!=pSorter->nTask-1 || p->pIncr->bUseThread==0) /* b */ + )); + rc = vdbePmaReaderIncrInit(p, INCRINIT_TASK); + } + } + pMain = 0; + } + if( rc==SQLITE_OK ){ + rc = vdbePmaReaderIncrMergeInit(pReadr, INCRINIT_ROOT); + } + }else +#endif + { + rc = vdbeMergeEngineInit(pTask0, pMain, INCRINIT_NORMAL); + pSorter->pMerger = pMain; + pMain = 0; + } + } + + if( rc!=SQLITE_OK ){ + vdbeMergeEngineFree(pMain); + } + return rc; +} + + +/* +** Once the sorter has been populated by calls to sqlite3VdbeSorterWrite, +** this function is called to prepare for iterating through the records +** in sorted order. +*/ +SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *pCsr, int *pbEof){ + VdbeSorter *pSorter; + int rc = SQLITE_OK; /* Return code */ + + assert( pCsr->eCurType==CURTYPE_SORTER ); + pSorter = pCsr->uc.pSorter; + assert( pSorter ); + + /* If no data has been written to disk, then do not do so now. Instead, + ** sort the VdbeSorter.pRecord list. The vdbe layer will read data directly + ** from the in-memory list. */ + if( pSorter->bUsePMA==0 ){ + if( pSorter->list.pList ){ + *pbEof = 0; + rc = vdbeSorterSort(&pSorter->aTask[0], &pSorter->list); + }else{ + *pbEof = 1; + } + return rc; + } + + /* Write the current in-memory list to a PMA. When the VdbeSorterWrite() + ** function flushes the contents of memory to disk, it immediately always + ** creates a new list consisting of a single key immediately afterwards. + ** So the list is never empty at this point. */ + assert( pSorter->list.pList ); + rc = vdbeSorterFlushPMA(pSorter); + + /* Join all threads */ + rc = vdbeSorterJoinAll(pSorter, rc); + + vdbeSorterRewindDebug("rewind"); + + /* Assuming no errors have occurred, set up a merger structure to + ** incrementally read and merge all remaining PMAs. */ + assert( pSorter->pReader==0 ); + if( rc==SQLITE_OK ){ + rc = vdbeSorterSetupMerge(pSorter); + *pbEof = 0; + } + + vdbeSorterRewindDebug("rewinddone"); + return rc; +} + +/* +** Advance to the next element in the sorter. Return value: +** +** SQLITE_OK success +** SQLITE_DONE end of data +** otherwise some kind of error. +*/ +SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr){ + VdbeSorter *pSorter; + int rc; /* Return code */ + + assert( pCsr->eCurType==CURTYPE_SORTER ); + pSorter = pCsr->uc.pSorter; + assert( pSorter->bUsePMA || (pSorter->pReader==0 && pSorter->pMerger==0) ); + if( pSorter->bUsePMA ){ + assert( pSorter->pReader==0 || pSorter->pMerger==0 ); + assert( pSorter->bUseThreads==0 || pSorter->pReader ); + assert( pSorter->bUseThreads==1 || pSorter->pMerger ); +#if SQLITE_MAX_WORKER_THREADS>0 + if( pSorter->bUseThreads ){ + rc = vdbePmaReaderNext(pSorter->pReader); + if( rc==SQLITE_OK && pSorter->pReader->pFd==0 ) rc = SQLITE_DONE; + }else +#endif + /*if( !pSorter->bUseThreads )*/ { + int res = 0; + assert( pSorter->pMerger!=0 ); + assert( pSorter->pMerger->pTask==(&pSorter->aTask[0]) ); + rc = vdbeMergeEngineStep(pSorter->pMerger, &res); + if( rc==SQLITE_OK && res ) rc = SQLITE_DONE; + } + }else{ + SorterRecord *pFree = pSorter->list.pList; + pSorter->list.pList = pFree->u.pNext; + pFree->u.pNext = 0; + if( pSorter->list.aMemory==0 ) vdbeSorterRecordFree(db, pFree); + rc = pSorter->list.pList ? SQLITE_OK : SQLITE_DONE; + } + return rc; +} + +/* +** Return a pointer to a buffer owned by the sorter that contains the +** current key. +*/ +static void *vdbeSorterRowkey( + const VdbeSorter *pSorter, /* Sorter object */ + int *pnKey /* OUT: Size of current key in bytes */ +){ + void *pKey; + if( pSorter->bUsePMA ){ + PmaReader *pReader; +#if SQLITE_MAX_WORKER_THREADS>0 + if( pSorter->bUseThreads ){ + pReader = pSorter->pReader; + }else +#endif + /*if( !pSorter->bUseThreads )*/{ + pReader = &pSorter->pMerger->aReadr[pSorter->pMerger->aTree[1]]; + } + *pnKey = pReader->nKey; + pKey = pReader->aKey; + }else{ + *pnKey = pSorter->list.pList->nVal; + pKey = SRVAL(pSorter->list.pList); + } + return pKey; +} + +/* +** Copy the current sorter key into the memory cell pOut. +*/ +SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){ + VdbeSorter *pSorter; + void *pKey; int nKey; /* Sorter key to copy into pOut */ + + assert( pCsr->eCurType==CURTYPE_SORTER ); + pSorter = pCsr->uc.pSorter; + pKey = vdbeSorterRowkey(pSorter, &nKey); + if( sqlite3VdbeMemClearAndResize(pOut, nKey) ){ + return SQLITE_NOMEM_BKPT; + } + pOut->n = nKey; + MemSetTypeFlag(pOut, MEM_Blob); + memcpy(pOut->z, pKey, nKey); + + return SQLITE_OK; +} + +/* +** Compare the key in memory cell pVal with the key that the sorter cursor +** passed as the first argument currently points to. For the purposes of +** the comparison, ignore the rowid field at the end of each record. +** +** If the sorter cursor key contains any NULL values, consider it to be +** less than pVal. Even if pVal also contains NULL values. +** +** If an error occurs, return an SQLite error code (i.e. SQLITE_NOMEM). +** Otherwise, set *pRes to a negative, zero or positive value if the +** key in pVal is smaller than, equal to or larger than the current sorter +** key. +** +** This routine forms the core of the OP_SorterCompare opcode, which in +** turn is used to verify uniqueness when constructing a UNIQUE INDEX. +*/ +SQLITE_PRIVATE int sqlite3VdbeSorterCompare( + const VdbeCursor *pCsr, /* Sorter cursor */ + Mem *pVal, /* Value to compare to current sorter key */ + int nKeyCol, /* Compare this many columns */ + int *pRes /* OUT: Result of comparison */ +){ + VdbeSorter *pSorter; + UnpackedRecord *r2; + KeyInfo *pKeyInfo; + int i; + void *pKey; int nKey; /* Sorter key to compare pVal with */ + + assert( pCsr->eCurType==CURTYPE_SORTER ); + pSorter = pCsr->uc.pSorter; + r2 = pSorter->pUnpacked; + pKeyInfo = pCsr->pKeyInfo; + if( r2==0 ){ + r2 = pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); + if( r2==0 ) return SQLITE_NOMEM_BKPT; + r2->nField = nKeyCol; + } + assert( r2->nField==nKeyCol ); + + pKey = vdbeSorterRowkey(pSorter, &nKey); + sqlite3VdbeRecordUnpack(nKey, pKey, r2); + for(i=0; iaMem[i].flags & MEM_Null ){ + *pRes = -1; + return SQLITE_OK; + } + } + + *pRes = sqlite3VdbeRecordCompare(pVal->n, pVal->z, r2); + return SQLITE_OK; +} + +/************** End of vdbesort.c ********************************************/ +/************** Begin file vdbevtab.c ****************************************/ +/* +** 2020-03-23 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file implements virtual-tables for examining the bytecode content +** of a prepared statement. +*/ +/* #include "sqliteInt.h" */ +#if defined(SQLITE_ENABLE_BYTECODE_VTAB) && !defined(SQLITE_OMIT_VIRTUALTABLE) +/* #include "vdbeInt.h" */ + +/* An instance of the bytecode() table-valued function. +*/ +typedef struct bytecodevtab bytecodevtab; +struct bytecodevtab { + sqlite3_vtab base; /* Base class - must be first */ + sqlite3 *db; /* Database connection */ + int bTablesUsed; /* 2 for tables_used(). 0 for bytecode(). */ +}; + +/* A cursor for scanning through the bytecode +*/ +typedef struct bytecodevtab_cursor bytecodevtab_cursor; +struct bytecodevtab_cursor { + sqlite3_vtab_cursor base; /* Base class - must be first */ + sqlite3_stmt *pStmt; /* The statement whose bytecode is displayed */ + int iRowid; /* The rowid of the output table */ + int iAddr; /* Address */ + int needFinalize; /* Cursors owns pStmt and must finalize it */ + int showSubprograms; /* Provide a listing of subprograms */ + Op *aOp; /* Operand array */ + char *zP4; /* Rendered P4 value */ + const char *zType; /* tables_used.type */ + const char *zSchema; /* tables_used.schema */ + const char *zName; /* tables_used.name */ + Mem sub; /* Subprograms */ +}; + +/* +** Create a new bytecode() table-valued function. +*/ +static int bytecodevtabConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + bytecodevtab *pNew; + int rc; + int isTabUsed = pAux!=0; + const char *azSchema[2] = { + /* bytecode() schema */ + "CREATE TABLE x(" + "addr INT," + "opcode TEXT," + "p1 INT," + "p2 INT," + "p3 INT," + "p4 TEXT," + "p5 INT," + "comment TEXT," + "subprog TEXT," + "nexec INT," + "ncycle INT," + "stmt HIDDEN" + ");", + + /* Tables_used() schema */ + "CREATE TABLE x(" + "type TEXT," + "schema TEXT," + "name TEXT," + "wr INT," + "subprog TEXT," + "stmt HIDDEN" + ");" + }; + + (void)argc; + (void)argv; + (void)pzErr; + rc = sqlite3_declare_vtab(db, azSchema[isTabUsed]); + if( rc==SQLITE_OK ){ + pNew = sqlite3_malloc( sizeof(*pNew) ); + *ppVtab = (sqlite3_vtab*)pNew; + if( pNew==0 ) return SQLITE_NOMEM; + memset(pNew, 0, sizeof(*pNew)); + pNew->db = db; + pNew->bTablesUsed = isTabUsed*2; + } + return rc; +} + +/* +** This method is the destructor for bytecodevtab objects. +*/ +static int bytecodevtabDisconnect(sqlite3_vtab *pVtab){ + bytecodevtab *p = (bytecodevtab*)pVtab; + sqlite3_free(p); + return SQLITE_OK; +} + +/* +** Constructor for a new bytecodevtab_cursor object. +*/ +static int bytecodevtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ + bytecodevtab *pVTab = (bytecodevtab*)p; + bytecodevtab_cursor *pCur; + pCur = sqlite3_malloc( sizeof(*pCur) ); + if( pCur==0 ) return SQLITE_NOMEM; + memset(pCur, 0, sizeof(*pCur)); + sqlite3VdbeMemInit(&pCur->sub, pVTab->db, 1); + *ppCursor = &pCur->base; + return SQLITE_OK; +} + +/* +** Clear all internal content from a bytecodevtab cursor. +*/ +static void bytecodevtabCursorClear(bytecodevtab_cursor *pCur){ + sqlite3_free(pCur->zP4); + pCur->zP4 = 0; + sqlite3VdbeMemRelease(&pCur->sub); + sqlite3VdbeMemSetNull(&pCur->sub); + if( pCur->needFinalize ){ + sqlite3_finalize(pCur->pStmt); + } + pCur->pStmt = 0; + pCur->needFinalize = 0; + pCur->zType = 0; + pCur->zSchema = 0; + pCur->zName = 0; +} + +/* +** Destructor for a bytecodevtab_cursor. +*/ +static int bytecodevtabClose(sqlite3_vtab_cursor *cur){ + bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur; + bytecodevtabCursorClear(pCur); + sqlite3_free(pCur); + return SQLITE_OK; +} + + +/* +** Advance a bytecodevtab_cursor to its next row of output. +*/ +static int bytecodevtabNext(sqlite3_vtab_cursor *cur){ + bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur; + bytecodevtab *pTab = (bytecodevtab*)cur->pVtab; + int rc; + if( pCur->zP4 ){ + sqlite3_free(pCur->zP4); + pCur->zP4 = 0; + } + if( pCur->zName ){ + pCur->zName = 0; + pCur->zType = 0; + pCur->zSchema = 0; + } + rc = sqlite3VdbeNextOpcode( + (Vdbe*)pCur->pStmt, + pCur->showSubprograms ? &pCur->sub : 0, + pTab->bTablesUsed, + &pCur->iRowid, + &pCur->iAddr, + &pCur->aOp); + if( rc!=SQLITE_OK ){ + sqlite3VdbeMemSetNull(&pCur->sub); + pCur->aOp = 0; + } + return SQLITE_OK; +} + +/* +** Return TRUE if the cursor has been moved off of the last +** row of output. +*/ +static int bytecodevtabEof(sqlite3_vtab_cursor *cur){ + bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur; + return pCur->aOp==0; +} + +/* +** Return values of columns for the row at which the bytecodevtab_cursor +** is currently pointing. +*/ +static int bytecodevtabColumn( + sqlite3_vtab_cursor *cur, /* The cursor */ + sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ + int i /* Which column to return */ +){ + bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur; + bytecodevtab *pVTab = (bytecodevtab*)cur->pVtab; + Op *pOp = pCur->aOp + pCur->iAddr; + if( pVTab->bTablesUsed ){ + if( i==4 ){ + i = 8; + }else{ + if( i<=2 && pCur->zType==0 ){ + Schema *pSchema; + HashElem *k; + int iDb = pOp->p3; + Pgno iRoot = (Pgno)pOp->p2; + sqlite3 *db = pVTab->db; + pSchema = db->aDb[iDb].pSchema; + pCur->zSchema = db->aDb[iDb].zDbSName; + for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ + Table *pTab = (Table*)sqliteHashData(k); + if( !IsVirtual(pTab) && pTab->tnum==iRoot ){ + pCur->zName = pTab->zName; + pCur->zType = "table"; + break; + } + } + if( pCur->zName==0 ){ + for(k=sqliteHashFirst(&pSchema->idxHash); k; k=sqliteHashNext(k)){ + Index *pIdx = (Index*)sqliteHashData(k); + if( pIdx->tnum==iRoot ){ + pCur->zName = pIdx->zName; + pCur->zType = "index"; + } + } + } + } + i += 20; + } + } + switch( i ){ + case 0: /* addr */ + sqlite3_result_int(ctx, pCur->iAddr); + break; + case 1: /* opcode */ + sqlite3_result_text(ctx, (char*)sqlite3OpcodeName(pOp->opcode), + -1, SQLITE_STATIC); + break; + case 2: /* p1 */ + sqlite3_result_int(ctx, pOp->p1); + break; + case 3: /* p2 */ + sqlite3_result_int(ctx, pOp->p2); + break; + case 4: /* p3 */ + sqlite3_result_int(ctx, pOp->p3); + break; + case 5: /* p4 */ + case 7: /* comment */ + if( pCur->zP4==0 ){ + pCur->zP4 = sqlite3VdbeDisplayP4(pVTab->db, pOp); + } + if( i==5 ){ + sqlite3_result_text(ctx, pCur->zP4, -1, SQLITE_STATIC); + }else{ +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + char *zCom = sqlite3VdbeDisplayComment(pVTab->db, pOp, pCur->zP4); + sqlite3_result_text(ctx, zCom, -1, sqlite3_free); +#endif + } + break; + case 6: /* p5 */ + sqlite3_result_int(ctx, pOp->p5); + break; + case 8: { /* subprog */ + Op *aOp = pCur->aOp; + assert( aOp[0].opcode==OP_Init ); + assert( aOp[0].p4.z==0 || strncmp(aOp[0].p4.z,"-" "- ",3)==0 ); + if( pCur->iRowid==pCur->iAddr+1 ){ + break; /* Result is NULL for the main program */ + }else if( aOp[0].p4.z!=0 ){ + sqlite3_result_text(ctx, aOp[0].p4.z+3, -1, SQLITE_STATIC); + }else{ + sqlite3_result_text(ctx, "(FK)", 4, SQLITE_STATIC); + } + break; + } + +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + case 9: /* nexec */ + sqlite3_result_int64(ctx, pOp->nExec); + break; + case 10: /* ncycle */ + sqlite3_result_int64(ctx, pOp->nCycle); + break; +#else + case 9: /* nexec */ + case 10: /* ncycle */ + sqlite3_result_int(ctx, 0); + break; +#endif + + case 20: /* tables_used.type */ + sqlite3_result_text(ctx, pCur->zType, -1, SQLITE_STATIC); + break; + case 21: /* tables_used.schema */ + sqlite3_result_text(ctx, pCur->zSchema, -1, SQLITE_STATIC); + break; + case 22: /* tables_used.name */ + sqlite3_result_text(ctx, pCur->zName, -1, SQLITE_STATIC); + break; + case 23: /* tables_used.wr */ + sqlite3_result_int(ctx, pOp->opcode==OP_OpenWrite); + break; + } + return SQLITE_OK; +} + +/* +** Return the rowid for the current row. In this implementation, the +** rowid is the same as the output value. +*/ +static int bytecodevtabRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ + bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur; + *pRowid = pCur->iRowid; + return SQLITE_OK; +} + +/* +** Initialize a cursor. +** +** idxNum==0 means show all subprograms +** idxNum==1 means show only the main bytecode and omit subprograms. +*/ +static int bytecodevtabFilter( + sqlite3_vtab_cursor *pVtabCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + bytecodevtab_cursor *pCur = (bytecodevtab_cursor *)pVtabCursor; + bytecodevtab *pVTab = (bytecodevtab *)pVtabCursor->pVtab; + int rc = SQLITE_OK; + (void)idxStr; + + bytecodevtabCursorClear(pCur); + pCur->iRowid = 0; + pCur->iAddr = 0; + pCur->showSubprograms = idxNum==0; + assert( argc==1 ); + if( sqlite3_value_type(argv[0])==SQLITE_TEXT ){ + const char *zSql = (const char*)sqlite3_value_text(argv[0]); + if( zSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare_v2(pVTab->db, zSql, -1, &pCur->pStmt, 0); + pCur->needFinalize = 1; + } + }else{ + pCur->pStmt = (sqlite3_stmt*)sqlite3_value_pointer(argv[0],"stmt-pointer"); + } + if( pCur->pStmt==0 ){ + pVTab->base.zErrMsg = sqlite3_mprintf( + "argument to %s() is not a valid SQL statement", + pVTab->bTablesUsed ? "tables_used" : "bytecode" + ); + rc = SQLITE_ERROR; + }else{ + bytecodevtabNext(pVtabCursor); + } + return rc; +} + +/* +** We must have a single stmt=? constraint that will be passed through +** into the xFilter method. If there is no valid stmt=? constraint, +** then return an SQLITE_CONSTRAINT error. +*/ +static int bytecodevtabBestIndex( + sqlite3_vtab *tab, + sqlite3_index_info *pIdxInfo +){ + int i; + int rc = SQLITE_CONSTRAINT; + struct sqlite3_index_constraint *p; + bytecodevtab *pVTab = (bytecodevtab*)tab; + int iBaseCol = pVTab->bTablesUsed ? 4 : 10; + pIdxInfo->estimatedCost = (double)100; + pIdxInfo->estimatedRows = 100; + pIdxInfo->idxNum = 0; + for(i=0, p=pIdxInfo->aConstraint; inConstraint; i++, p++){ + if( p->usable==0 ) continue; + if( p->op==SQLITE_INDEX_CONSTRAINT_EQ && p->iColumn==iBaseCol+1 ){ + rc = SQLITE_OK; + pIdxInfo->aConstraintUsage[i].omit = 1; + pIdxInfo->aConstraintUsage[i].argvIndex = 1; + } + if( p->op==SQLITE_INDEX_CONSTRAINT_ISNULL && p->iColumn==iBaseCol ){ + pIdxInfo->aConstraintUsage[i].omit = 1; + pIdxInfo->idxNum = 1; + } + } + return rc; +} + +/* +** This following structure defines all the methods for the +** virtual table. +*/ +static sqlite3_module bytecodevtabModule = { + /* iVersion */ 0, + /* xCreate */ 0, + /* xConnect */ bytecodevtabConnect, + /* xBestIndex */ bytecodevtabBestIndex, + /* xDisconnect */ bytecodevtabDisconnect, + /* xDestroy */ 0, + /* xOpen */ bytecodevtabOpen, + /* xClose */ bytecodevtabClose, + /* xFilter */ bytecodevtabFilter, + /* xNext */ bytecodevtabNext, + /* xEof */ bytecodevtabEof, + /* xColumn */ bytecodevtabColumn, + /* xRowid */ bytecodevtabRowid, + /* xUpdate */ 0, + /* xBegin */ 0, + /* xSync */ 0, + /* xCommit */ 0, + /* xRollback */ 0, + /* xFindMethod */ 0, + /* xRename */ 0, + /* xSavepoint */ 0, + /* xRelease */ 0, + /* xRollbackTo */ 0, + /* xShadowName */ 0, + /* xIntegrity */ 0 +}; + + +SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3 *db){ + int rc; + rc = sqlite3_create_module(db, "bytecode", &bytecodevtabModule, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3_create_module(db, "tables_used", &bytecodevtabModule, &db); + } + return rc; +} +#elif defined(SQLITE_ENABLE_BYTECODE_VTAB) +SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3 *db){ return SQLITE_OK; } +#endif /* SQLITE_ENABLE_BYTECODE_VTAB */ + +/************** End of vdbevtab.c ********************************************/ +/************** Begin file memjournal.c **************************************/ +/* +** 2008 October 7 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains code use to implement an in-memory rollback journal. +** The in-memory rollback journal is used to journal transactions for +** ":memory:" databases and when the journal_mode=MEMORY pragma is used. +** +** Update: The in-memory journal is also used to temporarily cache +** smaller journals that are not critical for power-loss recovery. +** For example, statement journals that are not too big will be held +** entirely in memory, thus reducing the number of file I/O calls, and +** more importantly, reducing temporary file creation events. If these +** journals become too large for memory, they are spilled to disk. But +** in the common case, they are usually small and no file I/O needs to +** occur. +*/ +/* #include "sqliteInt.h" */ + +/* Forward references to internal structures */ +typedef struct MemJournal MemJournal; +typedef struct FilePoint FilePoint; +typedef struct FileChunk FileChunk; + +/* +** The rollback journal is composed of a linked list of these structures. +** +** The zChunk array is always at least 8 bytes in size - usually much more. +** Its actual size is stored in the MemJournal.nChunkSize variable. +*/ +struct FileChunk { + FileChunk *pNext; /* Next chunk in the journal */ + u8 zChunk[8]; /* Content of this chunk */ +}; + +/* +** By default, allocate this many bytes of memory for each FileChunk object. +*/ +#define MEMJOURNAL_DFLT_FILECHUNKSIZE 1024 + +/* +** For chunk size nChunkSize, return the number of bytes that should +** be allocated for each FileChunk structure. +*/ +#define fileChunkSize(nChunkSize) (sizeof(FileChunk) + ((nChunkSize)-8)) + +/* +** An instance of this object serves as a cursor into the rollback journal. +** The cursor can be either for reading or writing. +*/ +struct FilePoint { + sqlite3_int64 iOffset; /* Offset from the beginning of the file */ + FileChunk *pChunk; /* Specific chunk into which cursor points */ +}; + +/* +** This structure is a subclass of sqlite3_file. Each open memory-journal +** is an instance of this class. +*/ +struct MemJournal { + const sqlite3_io_methods *pMethod; /* Parent class. MUST BE FIRST */ + int nChunkSize; /* In-memory chunk-size */ + + int nSpill; /* Bytes of data before flushing */ + FileChunk *pFirst; /* Head of in-memory chunk-list */ + FilePoint endpoint; /* Pointer to the end of the file */ + FilePoint readpoint; /* Pointer to the end of the last xRead() */ + + int flags; /* xOpen flags */ + sqlite3_vfs *pVfs; /* The "real" underlying VFS */ + const char *zJournal; /* Name of the journal file */ +}; + +/* +** Read data from the in-memory journal file. This is the implementation +** of the sqlite3_vfs.xRead method. +*/ +static int memjrnlRead( + sqlite3_file *pJfd, /* The journal file from which to read */ + void *zBuf, /* Put the results here */ + int iAmt, /* Number of bytes to read */ + sqlite_int64 iOfst /* Begin reading at this offset */ +){ + MemJournal *p = (MemJournal *)pJfd; + u8 *zOut = zBuf; + int nRead = iAmt; + int iChunkOffset; + FileChunk *pChunk; + + if( (iAmt+iOfst)>p->endpoint.iOffset ){ + return SQLITE_IOERR_SHORT_READ; + } + assert( p->readpoint.iOffset==0 || p->readpoint.pChunk!=0 ); + if( p->readpoint.iOffset!=iOfst || iOfst==0 ){ + sqlite3_int64 iOff = 0; + for(pChunk=p->pFirst; + ALWAYS(pChunk) && (iOff+p->nChunkSize)<=iOfst; + pChunk=pChunk->pNext + ){ + iOff += p->nChunkSize; + } + }else{ + pChunk = p->readpoint.pChunk; + assert( pChunk!=0 ); + } + + iChunkOffset = (int)(iOfst%p->nChunkSize); + do { + int iSpace = p->nChunkSize - iChunkOffset; + int nCopy = MIN(nRead, (p->nChunkSize - iChunkOffset)); + memcpy(zOut, (u8*)pChunk->zChunk + iChunkOffset, nCopy); + zOut += nCopy; + nRead -= iSpace; + iChunkOffset = 0; + } while( nRead>=0 && (pChunk=pChunk->pNext)!=0 && nRead>0 ); + p->readpoint.iOffset = pChunk ? iOfst+iAmt : 0; + p->readpoint.pChunk = pChunk; + + return SQLITE_OK; +} + +/* +** Free the list of FileChunk structures headed at MemJournal.pFirst. +*/ +static void memjrnlFreeChunks(FileChunk *pFirst){ + FileChunk *pIter; + FileChunk *pNext; + for(pIter=pFirst; pIter; pIter=pNext){ + pNext = pIter->pNext; + sqlite3_free(pIter); + } +} + +/* +** Flush the contents of memory to a real file on disk. +*/ +static int memjrnlCreateFile(MemJournal *p){ + int rc; + sqlite3_file *pReal = (sqlite3_file*)p; + MemJournal copy = *p; + + memset(p, 0, sizeof(MemJournal)); + rc = sqlite3OsOpen(copy.pVfs, copy.zJournal, pReal, copy.flags, 0); + if( rc==SQLITE_OK ){ + int nChunk = copy.nChunkSize; + i64 iOff = 0; + FileChunk *pIter; + for(pIter=copy.pFirst; pIter; pIter=pIter->pNext){ + if( iOff + nChunk > copy.endpoint.iOffset ){ + nChunk = copy.endpoint.iOffset - iOff; + } + rc = sqlite3OsWrite(pReal, (u8*)pIter->zChunk, nChunk, iOff); + if( rc ) break; + iOff += nChunk; + } + if( rc==SQLITE_OK ){ + /* No error has occurred. Free the in-memory buffers. */ + memjrnlFreeChunks(copy.pFirst); + } + } + if( rc!=SQLITE_OK ){ + /* If an error occurred while creating or writing to the file, restore + ** the original before returning. This way, SQLite uses the in-memory + ** journal data to roll back changes made to the internal page-cache + ** before this function was called. */ + sqlite3OsClose(pReal); + *p = copy; + } + return rc; +} + + +/* Forward reference */ +static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size); + +/* +** Write data to the file. +*/ +static int memjrnlWrite( + sqlite3_file *pJfd, /* The journal file into which to write */ + const void *zBuf, /* Take data to be written from here */ + int iAmt, /* Number of bytes to write */ + sqlite_int64 iOfst /* Begin writing at this offset into the file */ +){ + MemJournal *p = (MemJournal *)pJfd; + int nWrite = iAmt; + u8 *zWrite = (u8 *)zBuf; + + /* If the file should be created now, create it and write the new data + ** into the file on disk. */ + if( p->nSpill>0 && (iAmt+iOfst)>p->nSpill ){ + int rc = memjrnlCreateFile(p); + if( rc==SQLITE_OK ){ + rc = sqlite3OsWrite(pJfd, zBuf, iAmt, iOfst); + } + return rc; + } + + /* If the contents of this write should be stored in memory */ + else{ + /* An in-memory journal file should only ever be appended to. Random + ** access writes are not required. The only exception to this is when + ** the in-memory journal is being used by a connection using the + ** atomic-write optimization. In this case the first 28 bytes of the + ** journal file may be written as part of committing the transaction. */ + assert( iOfst<=p->endpoint.iOffset ); + if( iOfst>0 && iOfst!=p->endpoint.iOffset ){ + memjrnlTruncate(pJfd, iOfst); + } + if( iOfst==0 && p->pFirst ){ + assert( p->nChunkSize>iAmt ); + memcpy((u8*)p->pFirst->zChunk, zBuf, iAmt); + }else{ + while( nWrite>0 ){ + FileChunk *pChunk = p->endpoint.pChunk; + int iChunkOffset = (int)(p->endpoint.iOffset%p->nChunkSize); + int iSpace = MIN(nWrite, p->nChunkSize - iChunkOffset); + + assert( pChunk!=0 || iChunkOffset==0 ); + if( iChunkOffset==0 ){ + /* New chunk is required to extend the file. */ + FileChunk *pNew = sqlite3_malloc(fileChunkSize(p->nChunkSize)); + if( !pNew ){ + return SQLITE_IOERR_NOMEM_BKPT; + } + pNew->pNext = 0; + if( pChunk ){ + assert( p->pFirst ); + pChunk->pNext = pNew; + }else{ + assert( !p->pFirst ); + p->pFirst = pNew; + } + pChunk = p->endpoint.pChunk = pNew; + } + + assert( pChunk!=0 ); + memcpy((u8*)pChunk->zChunk + iChunkOffset, zWrite, iSpace); + zWrite += iSpace; + nWrite -= iSpace; + p->endpoint.iOffset += iSpace; + } + } + } + + return SQLITE_OK; +} + +/* +** Truncate the in-memory file. +*/ +static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){ + MemJournal *p = (MemJournal *)pJfd; + assert( p->endpoint.pChunk==0 || p->endpoint.pChunk->pNext==0 ); + if( sizeendpoint.iOffset ){ + FileChunk *pIter = 0; + if( size==0 ){ + memjrnlFreeChunks(p->pFirst); + p->pFirst = 0; + }else{ + i64 iOff = p->nChunkSize; + for(pIter=p->pFirst; ALWAYS(pIter) && iOffpNext){ + iOff += p->nChunkSize; + } + if( ALWAYS(pIter) ){ + memjrnlFreeChunks(pIter->pNext); + pIter->pNext = 0; + } + } + + p->endpoint.pChunk = pIter; + p->endpoint.iOffset = size; + p->readpoint.pChunk = 0; + p->readpoint.iOffset = 0; + } + return SQLITE_OK; +} + +/* +** Close the file. +*/ +static int memjrnlClose(sqlite3_file *pJfd){ + MemJournal *p = (MemJournal *)pJfd; + memjrnlFreeChunks(p->pFirst); + return SQLITE_OK; +} + +/* +** Sync the file. +** +** If the real file has been created, call its xSync method. Otherwise, +** syncing an in-memory journal is a no-op. +*/ +static int memjrnlSync(sqlite3_file *pJfd, int flags){ + UNUSED_PARAMETER2(pJfd, flags); + return SQLITE_OK; +} + +/* +** Query the size of the file in bytes. +*/ +static int memjrnlFileSize(sqlite3_file *pJfd, sqlite_int64 *pSize){ + MemJournal *p = (MemJournal *)pJfd; + *pSize = (sqlite_int64) p->endpoint.iOffset; + return SQLITE_OK; +} + +/* +** Table of methods for MemJournal sqlite3_file object. +*/ +static const struct sqlite3_io_methods MemJournalMethods = { + 1, /* iVersion */ + memjrnlClose, /* xClose */ + memjrnlRead, /* xRead */ + memjrnlWrite, /* xWrite */ + memjrnlTruncate, /* xTruncate */ + memjrnlSync, /* xSync */ + memjrnlFileSize, /* xFileSize */ + 0, /* xLock */ + 0, /* xUnlock */ + 0, /* xCheckReservedLock */ + 0, /* xFileControl */ + 0, /* xSectorSize */ + 0, /* xDeviceCharacteristics */ + 0, /* xShmMap */ + 0, /* xShmLock */ + 0, /* xShmBarrier */ + 0, /* xShmUnmap */ + 0, /* xFetch */ + 0 /* xUnfetch */ +}; + +/* +** Open a journal file. +** +** The behaviour of the journal file depends on the value of parameter +** nSpill. If nSpill is 0, then the journal file is always create and +** accessed using the underlying VFS. If nSpill is less than zero, then +** all content is always stored in main-memory. Finally, if nSpill is a +** positive value, then the journal file is initially created in-memory +** but may be flushed to disk later on. In this case the journal file is +** flushed to disk either when it grows larger than nSpill bytes in size, +** or when sqlite3JournalCreate() is called. +*/ +SQLITE_PRIVATE int sqlite3JournalOpen( + sqlite3_vfs *pVfs, /* The VFS to use for actual file I/O */ + const char *zName, /* Name of the journal file */ + sqlite3_file *pJfd, /* Preallocated, blank file handle */ + int flags, /* Opening flags */ + int nSpill /* Bytes buffered before opening the file */ +){ + MemJournal *p = (MemJournal*)pJfd; + + assert( zName || nSpill<0 || (flags & SQLITE_OPEN_EXCLUSIVE) ); + + /* Zero the file-handle object. If nSpill was passed zero, initialize + ** it using the sqlite3OsOpen() function of the underlying VFS. In this + ** case none of the code in this module is executed as a result of calls + ** made on the journal file-handle. */ + memset(p, 0, sizeof(MemJournal)); + if( nSpill==0 ){ + return sqlite3OsOpen(pVfs, zName, pJfd, flags, 0); + } + + if( nSpill>0 ){ + p->nChunkSize = nSpill; + }else{ + p->nChunkSize = 8 + MEMJOURNAL_DFLT_FILECHUNKSIZE - sizeof(FileChunk); + assert( MEMJOURNAL_DFLT_FILECHUNKSIZE==fileChunkSize(p->nChunkSize) ); + } + + pJfd->pMethods = (const sqlite3_io_methods*)&MemJournalMethods; + p->nSpill = nSpill; + p->flags = flags; + p->zJournal = zName; + p->pVfs = pVfs; + return SQLITE_OK; +} + +/* +** Open an in-memory journal file. +*/ +SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *pJfd){ + sqlite3JournalOpen(0, 0, pJfd, 0, -1); +} + +#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \ + || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) +/* +** If the argument p points to a MemJournal structure that is not an +** in-memory-only journal file (i.e. is one that was opened with a +ve +** nSpill parameter or as SQLITE_OPEN_MAIN_JOURNAL), and the underlying +** file has not yet been created, create it now. +*/ +SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *pJfd){ + int rc = SQLITE_OK; + MemJournal *p = (MemJournal*)pJfd; + if( pJfd->pMethods==&MemJournalMethods && ( +#ifdef SQLITE_ENABLE_ATOMIC_WRITE + p->nSpill>0 +#else + /* While this appears to not be possible without ATOMIC_WRITE, the + ** paths are complex, so it seems prudent to leave the test in as + ** a NEVER(), in case our analysis is subtly flawed. */ + NEVER(p->nSpill>0) +#endif +#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE + || (p->flags & SQLITE_OPEN_MAIN_JOURNAL) +#endif + )){ + rc = memjrnlCreateFile(p); + } + return rc; +} +#endif + +/* +** The file-handle passed as the only argument is open on a journal file. +** Return true if this "journal file" is currently stored in heap memory, +** or false otherwise. +*/ +SQLITE_PRIVATE int sqlite3JournalIsInMemory(sqlite3_file *p){ + return p->pMethods==&MemJournalMethods; +} + +/* +** Return the number of bytes required to store a JournalFile that uses vfs +** pVfs to create the underlying on-disk files. +*/ +SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){ + return MAX(pVfs->szOsFile, (int)sizeof(MemJournal)); +} + +/************** End of memjournal.c ******************************************/ +/************** Begin file walker.c ******************************************/ +/* +** 2008 August 16 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains routines used for walking the parser tree for +** an SQL statement. +*/ +/* #include "sqliteInt.h" */ +/* #include */ +/* #include */ + + +#if !defined(SQLITE_OMIT_WINDOWFUNC) +/* +** Walk all expressions linked into the list of Window objects passed +** as the second argument. +*/ +static int walkWindowList(Walker *pWalker, Window *pList, int bOneOnly){ + Window *pWin; + for(pWin=pList; pWin; pWin=pWin->pNextWin){ + int rc; + rc = sqlite3WalkExprList(pWalker, pWin->pOrderBy); + if( rc ) return WRC_Abort; + rc = sqlite3WalkExprList(pWalker, pWin->pPartition); + if( rc ) return WRC_Abort; + rc = sqlite3WalkExpr(pWalker, pWin->pFilter); + if( rc ) return WRC_Abort; + rc = sqlite3WalkExpr(pWalker, pWin->pStart); + if( rc ) return WRC_Abort; + rc = sqlite3WalkExpr(pWalker, pWin->pEnd); + if( rc ) return WRC_Abort; + if( bOneOnly ) break; + } + return WRC_Continue; +} +#endif + +/* +** Walk an expression tree. Invoke the callback once for each node +** of the expression, while descending. (In other words, the callback +** is invoked before visiting children.) +** +** The return value from the callback should be one of the WRC_* +** constants to specify how to proceed with the walk. +** +** WRC_Continue Continue descending down the tree. +** +** WRC_Prune Do not descend into child nodes, but allow +** the walk to continue with sibling nodes. +** +** WRC_Abort Do no more callbacks. Unwind the stack and +** return from the top-level walk call. +** +** The return value from this routine is WRC_Abort to abandon the tree walk +** and WRC_Continue to continue. +*/ +SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3WalkExprNN(Walker *pWalker, Expr *pExpr){ + int rc; + testcase( ExprHasProperty(pExpr, EP_TokenOnly) ); + testcase( ExprHasProperty(pExpr, EP_Reduced) ); + while(1){ + rc = pWalker->xExprCallback(pWalker, pExpr); + if( rc ) return rc & WRC_Abort; + if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ + assert( pExpr->x.pList==0 || pExpr->pRight==0 ); + if( pExpr->pLeft && sqlite3WalkExprNN(pWalker, pExpr->pLeft) ){ + return WRC_Abort; + } + if( pExpr->pRight ){ + assert( !ExprHasProperty(pExpr, EP_WinFunc) ); + pExpr = pExpr->pRight; + continue; + }else if( ExprUseXSelect(pExpr) ){ + assert( !ExprHasProperty(pExpr, EP_WinFunc) ); + if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort; + }else{ + if( pExpr->x.pList ){ + if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort; + } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( ExprHasProperty(pExpr, EP_WinFunc) ){ + if( walkWindowList(pWalker, pExpr->y.pWin, 1) ) return WRC_Abort; + } +#endif + } + } + break; + } + return WRC_Continue; +} +SQLITE_PRIVATE int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){ + return pExpr ? sqlite3WalkExprNN(pWalker,pExpr) : WRC_Continue; +} + +/* +** Call sqlite3WalkExpr() for every expression in list p or until +** an abort request is seen. +*/ +SQLITE_PRIVATE int sqlite3WalkExprList(Walker *pWalker, ExprList *p){ + int i; + struct ExprList_item *pItem; + if( p ){ + for(i=p->nExpr, pItem=p->a; i>0; i--, pItem++){ + if( sqlite3WalkExpr(pWalker, pItem->pExpr) ) return WRC_Abort; + } + } + return WRC_Continue; +} + +/* +** This is a no-op callback for Walker->xSelectCallback2. If this +** callback is set, then the Select->pWinDefn list is traversed. +*/ +SQLITE_PRIVATE void sqlite3WalkWinDefnDummyCallback(Walker *pWalker, Select *p){ + UNUSED_PARAMETER(pWalker); + UNUSED_PARAMETER(p); + /* No-op */ +} + +/* +** Walk all expressions associated with SELECT statement p. Do +** not invoke the SELECT callback on p, but do (of course) invoke +** any expr callbacks and SELECT callbacks that come from subqueries. +** Return WRC_Abort or WRC_Continue. +*/ +SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){ + if( sqlite3WalkExprList(pWalker, p->pEList) ) return WRC_Abort; + if( sqlite3WalkExpr(pWalker, p->pWhere) ) return WRC_Abort; + if( sqlite3WalkExprList(pWalker, p->pGroupBy) ) return WRC_Abort; + if( sqlite3WalkExpr(pWalker, p->pHaving) ) return WRC_Abort; + if( sqlite3WalkExprList(pWalker, p->pOrderBy) ) return WRC_Abort; + if( sqlite3WalkExpr(pWalker, p->pLimit) ) return WRC_Abort; +#if !defined(SQLITE_OMIT_WINDOWFUNC) + if( p->pWinDefn ){ + Parse *pParse; + if( pWalker->xSelectCallback2==sqlite3WalkWinDefnDummyCallback + || ((pParse = pWalker->pParse)!=0 && IN_RENAME_OBJECT) +#ifndef SQLITE_OMIT_CTE + || pWalker->xSelectCallback2==sqlite3SelectPopWith +#endif + ){ + /* The following may return WRC_Abort if there are unresolvable + ** symbols (e.g. a table that does not exist) in a window definition. */ + int rc = walkWindowList(pWalker, p->pWinDefn, 0); + return rc; + } + } +#endif + return WRC_Continue; +} + +/* +** Walk the parse trees associated with all subqueries in the +** FROM clause of SELECT statement p. Do not invoke the select +** callback on p, but do invoke it on each FROM clause subquery +** and on any subqueries further down in the tree. Return +** WRC_Abort or WRC_Continue; +*/ +SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ + SrcList *pSrc; + int i; + SrcItem *pItem; + + pSrc = p->pSrc; + if( ALWAYS(pSrc) ){ + for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ + if( pItem->fg.isSubquery + && sqlite3WalkSelect(pWalker, pItem->u4.pSubq->pSelect) + ){ + return WRC_Abort; + } + if( pItem->fg.isTabFunc + && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg) + ){ + return WRC_Abort; + } + } + } + return WRC_Continue; +} + +/* +** Call sqlite3WalkExpr() for every expression in Select statement p. +** Invoke sqlite3WalkSelect() for subqueries in the FROM clause and +** on the compound select chain, p->pPrior. +** +** If it is not NULL, the xSelectCallback() callback is invoked before +** the walk of the expressions and FROM clause. The xSelectCallback2() +** method is invoked following the walk of the expressions and FROM clause, +** but only if both xSelectCallback and xSelectCallback2 are both non-NULL +** and if the expressions and FROM clause both return WRC_Continue; +** +** Return WRC_Continue under normal conditions. Return WRC_Abort if +** there is an abort request. +** +** If the Walker does not have an xSelectCallback() then this routine +** is a no-op returning WRC_Continue. +*/ +SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){ + int rc; + if( p==0 ) return WRC_Continue; + if( pWalker->xSelectCallback==0 ) return WRC_Continue; + do{ + rc = pWalker->xSelectCallback(pWalker, p); + if( rc ) return rc & WRC_Abort; + if( sqlite3WalkSelectExpr(pWalker, p) + || sqlite3WalkSelectFrom(pWalker, p) + ){ + return WRC_Abort; + } + if( pWalker->xSelectCallback2 ){ + pWalker->xSelectCallback2(pWalker, p); + } + p = p->pPrior; + }while( p!=0 ); + return WRC_Continue; +} + +/* Increase the walkerDepth when entering a subquery, and +** decrease when leaving the subquery. +*/ +SQLITE_PRIVATE int sqlite3WalkerDepthIncrease(Walker *pWalker, Select *pSelect){ + UNUSED_PARAMETER(pSelect); + pWalker->walkerDepth++; + return WRC_Continue; +} +SQLITE_PRIVATE void sqlite3WalkerDepthDecrease(Walker *pWalker, Select *pSelect){ + UNUSED_PARAMETER(pSelect); + pWalker->walkerDepth--; +} + + +/* +** No-op routine for the parse-tree walker. +** +** When this routine is the Walker.xExprCallback then expression trees +** are walked without any actions being taken at each node. Presumably, +** when this routine is used for Walker.xExprCallback then +** Walker.xSelectCallback is set to do something useful for every +** subquery in the parser tree. +*/ +SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + return WRC_Continue; +} + +/* +** No-op routine for the parse-tree walker for SELECT statements. +** subquery in the parser tree. +*/ +SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker *NotUsed, Select *NotUsed2){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + return WRC_Continue; +} + +/************** End of walker.c **********************************************/ +/************** Begin file resolve.c *****************************************/ +/* +** 2008 August 18 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains routines used for walking the parser tree and +** resolve all identifiers by associating them with a particular +** table and column. +*/ +/* #include "sqliteInt.h" */ + +/* +** Magic table number to mean the EXCLUDED table in an UPSERT statement. +*/ +#define EXCLUDED_TABLE_NUMBER 2 + +/* +** Walk the expression tree pExpr and increase the aggregate function +** depth (the Expr.op2 field) by N on every TK_AGG_FUNCTION node. +** This needs to occur when copying a TK_AGG_FUNCTION node from an +** outer query into an inner subquery. +** +** incrAggFunctionDepth(pExpr,n) is the main routine. incrAggDepth(..) +** is a helper function - a callback for the tree walker. +** +** See also the sqlite3WindowExtraAggFuncDepth() routine in window.c +*/ +static int incrAggDepth(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.n; + return WRC_Continue; +} +static void incrAggFunctionDepth(Expr *pExpr, int N){ + if( N>0 ){ + Walker w; + memset(&w, 0, sizeof(w)); + w.xExprCallback = incrAggDepth; + w.u.n = N; + sqlite3WalkExpr(&w, pExpr); + } +} + +/* +** Turn the pExpr expression into an alias for the iCol-th column of the +** result set in pEList. +** +** If the reference is followed by a COLLATE operator, then make sure +** the COLLATE operator is preserved. For example: +** +** SELECT a+b, c+d FROM t1 ORDER BY 1 COLLATE nocase; +** +** Should be transformed into: +** +** SELECT a+b, c+d FROM t1 ORDER BY (a+b) COLLATE nocase; +** +** The nSubquery parameter specifies how many levels of subquery the +** alias is removed from the original expression. The usual value is +** zero but it might be more if the alias is contained within a subquery +** of the original expression. The Expr.op2 field of TK_AGG_FUNCTION +** structures must be increased by the nSubquery amount. +*/ +static void resolveAlias( + Parse *pParse, /* Parsing context */ + ExprList *pEList, /* A result set */ + int iCol, /* A column in the result set. 0..pEList->nExpr-1 */ + Expr *pExpr, /* Transform this into an alias to the result set */ + int nSubquery /* Number of subqueries that the label is moving */ +){ + Expr *pOrig; /* The iCol-th column of the result set */ + Expr *pDup; /* Copy of pOrig */ + sqlite3 *db; /* The database connection */ + + assert( iCol>=0 && iColnExpr ); + pOrig = pEList->a[iCol].pExpr; + assert( pOrig!=0 ); + assert( !ExprHasProperty(pExpr, EP_Reduced|EP_TokenOnly) ); + if( pExpr->pAggInfo ) return; + db = pParse->db; + pDup = sqlite3ExprDup(db, pOrig, 0); + if( db->mallocFailed ){ + sqlite3ExprDelete(db, pDup); + pDup = 0; + }else{ + Expr temp; + incrAggFunctionDepth(pDup, nSubquery); + if( pExpr->op==TK_COLLATE ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); + } + memcpy(&temp, pDup, sizeof(Expr)); + memcpy(pDup, pExpr, sizeof(Expr)); + memcpy(pExpr, &temp, sizeof(Expr)); + if( ExprHasProperty(pExpr, EP_WinFunc) ){ + if( ALWAYS(pExpr->y.pWin!=0) ){ + pExpr->y.pWin->pOwner = pExpr; + } + } + sqlite3ExprDeferredDelete(pParse, pDup); + } +} + +/* +** Subqueries store the original database, table and column names for their +** result sets in ExprList.a[].zSpan, in the form "DATABASE.TABLE.COLUMN", +** and mark the expression-list item by setting ExprList.a[].fg.eEName +** to ENAME_TAB. +** +** Check to see if the zSpan/eEName of the expression-list item passed to this +** routine matches the zDb, zTab, and zCol. If any of zDb, zTab, and zCol are +** NULL then those fields will match anything. Return true if there is a match, +** or false otherwise. +** +** SF_NestedFrom subqueries also store an entry for the implicit rowid (or +** _rowid_, or oid) column by setting ExprList.a[].fg.eEName to ENAME_ROWID, +** and setting zSpan to "DATABASE.TABLE.". This type of pItem +** argument matches if zCol is a rowid alias. If it is not NULL, (*pbRowid) +** is set to 1 if there is this kind of match. +*/ +SQLITE_PRIVATE int sqlite3MatchEName( + const struct ExprList_item *pItem, + const char *zCol, + const char *zTab, + const char *zDb, + int *pbRowid +){ + int n; + const char *zSpan; + int eEName = pItem->fg.eEName; + if( eEName!=ENAME_TAB && (eEName!=ENAME_ROWID || NEVER(pbRowid==0)) ){ + return 0; + } + assert( pbRowid==0 || *pbRowid==0 ); + zSpan = pItem->zEName; + for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){} + if( zDb && (sqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){ + return 0; + } + zSpan += n+1; + for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){} + if( zTab && (sqlite3StrNICmp(zSpan, zTab, n)!=0 || zTab[n]!=0) ){ + return 0; + } + zSpan += n+1; + if( zCol ){ + if( eEName==ENAME_TAB && sqlite3StrICmp(zSpan, zCol)!=0 ) return 0; + if( eEName==ENAME_ROWID && sqlite3IsRowid(zCol)==0 ) return 0; + } + if( eEName==ENAME_ROWID ) *pbRowid = 1; + return 1; +} + +/* +** Return TRUE if the double-quoted string mis-feature should be supported. +*/ +static int areDoubleQuotedStringsEnabled(sqlite3 *db, NameContext *pTopNC){ + if( db->init.busy ) return 1; /* Always support for legacy schemas */ + if( pTopNC->ncFlags & NC_IsDDL ){ + /* Currently parsing a DDL statement */ + if( sqlite3WritableSchema(db) && (db->flags & SQLITE_DqsDML)!=0 ){ + return 1; + } + return (db->flags & SQLITE_DqsDDL)!=0; + }else{ + /* Currently parsing a DML statement */ + return (db->flags & SQLITE_DqsDML)!=0; + } +} + +/* +** The argument is guaranteed to be a non-NULL Expr node of type TK_COLUMN. +** return the appropriate colUsed mask. +*/ +SQLITE_PRIVATE Bitmask sqlite3ExprColUsed(Expr *pExpr){ + int n; + Table *pExTab; + + n = pExpr->iColumn; + assert( ExprUseYTab(pExpr) ); + pExTab = pExpr->y.pTab; + assert( pExTab!=0 ); + assert( n < pExTab->nCol ); + if( (pExTab->tabFlags & TF_HasGenerated)!=0 + && (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0 + ){ + testcase( pExTab->nCol==BMS-1 ); + testcase( pExTab->nCol==BMS ); + return pExTab->nCol>=BMS ? ALLBITS : MASKBIT(pExTab->nCol)-1; + }else{ + testcase( n==BMS-1 ); + testcase( n==BMS ); + if( n>=BMS ) n = BMS-1; + return ((Bitmask)1)<db, TK_COLUMN, 0, 0); + if( pNew ){ + pNew->iTable = pMatch->iCursor; + pNew->iColumn = iColumn; + pNew->y.pTab = pMatch->pSTab; + assert( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ); + ExprSetProperty(pNew, EP_CanBeNull); + *ppList = sqlite3ExprListAppend(pParse, *ppList, pNew); + } +} + +/* +** Return TRUE (non-zero) if zTab is a valid name for the schema table pTab. +*/ +static SQLITE_NOINLINE int isValidSchemaTableName( + const char *zTab, /* Name as it appears in the SQL */ + Table *pTab, /* The schema table we are trying to match */ + const char *zDb /* non-NULL if a database qualifier is present */ +){ + const char *zLegacy; + assert( pTab!=0 ); + assert( pTab->tnum==1 ); + if( sqlite3StrNICmp(zTab, "sqlite_", 7)!=0 ) return 0; + zLegacy = pTab->zName; + if( strcmp(zLegacy+7, &LEGACY_TEMP_SCHEMA_TABLE[7])==0 ){ + if( sqlite3StrICmp(zTab+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0 ){ + return 1; + } + if( zDb==0 ) return 0; + if( sqlite3StrICmp(zTab+7, &LEGACY_SCHEMA_TABLE[7])==0 ) return 1; + if( sqlite3StrICmp(zTab+7, &PREFERRED_SCHEMA_TABLE[7])==0 ) return 1; + }else{ + if( sqlite3StrICmp(zTab+7, &PREFERRED_SCHEMA_TABLE[7])==0 ) return 1; + } + return 0; +} + +/* +** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up +** that name in the set of source tables in pSrcList and make the pExpr +** expression node refer back to that source column. The following changes +** are made to pExpr: +** +** pExpr->iDb Set the index in db->aDb[] of the database X +** (even if X is implied). +** pExpr->iTable Set to the cursor number for the table obtained +** from pSrcList. +** pExpr->y.pTab Points to the Table structure of X.Y (even if +** X and/or Y are implied.) +** pExpr->iColumn Set to the column number within the table. +** pExpr->op Set to TK_COLUMN. +** pExpr->pLeft Any expression this points to is deleted +** pExpr->pRight Any expression this points to is deleted. +** +** The zDb variable is the name of the database (the "X"). This value may be +** NULL meaning that name is of the form Y.Z or Z. Any available database +** can be used. The zTable variable is the name of the table (the "Y"). This +** value can be NULL if zDb is also NULL. If zTable is NULL it +** means that the form of the name is Z and that columns from any table +** can be used. +** +** If the name cannot be resolved unambiguously, leave an error message +** in pParse and return WRC_Abort. Return WRC_Prune on success. +*/ +static int lookupName( + Parse *pParse, /* The parsing context */ + const char *zDb, /* Name of the database containing table, or NULL */ + const char *zTab, /* Name of table containing column, or NULL */ + const Expr *pRight, /* Name of the column. */ + NameContext *pNC, /* The name context used to resolve the name */ + Expr *pExpr /* Make this EXPR node point to the selected column */ +){ + int i, j; /* Loop counters */ + int cnt = 0; /* Number of matching column names */ + int cntTab = 0; /* Number of potential "rowid" matches */ + int nSubquery = 0; /* How many levels of subquery */ + sqlite3 *db = pParse->db; /* The database connection */ + SrcItem *pItem; /* Use for looping over pSrcList items */ + SrcItem *pMatch = 0; /* The matching pSrcList item */ + NameContext *pTopNC = pNC; /* First namecontext in the list */ + Schema *pSchema = 0; /* Schema of the expression */ + int eNewExprOp = TK_COLUMN; /* New value for pExpr->op on success */ + Table *pTab = 0; /* Table holding the row */ + ExprList *pFJMatch = 0; /* Matches for FULL JOIN .. USING */ + const char *zCol = pRight->u.zToken; + + assert( pNC ); /* the name context cannot be NULL. */ + assert( zCol ); /* The Z in X.Y.Z cannot be NULL */ + assert( zDb==0 || zTab!=0 ); + assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); + + /* Initialize the node to no-match */ + pExpr->iTable = -1; + ExprSetVVAProperty(pExpr, EP_NoReduce); + + /* Translate the schema name in zDb into a pointer to the corresponding + ** schema. If not found, pSchema will remain NULL and nothing will match + ** resulting in an appropriate error message toward the end of this routine + */ + if( zDb ){ + testcase( pNC->ncFlags & NC_PartIdx ); + testcase( pNC->ncFlags & NC_IsCheck ); + if( (pNC->ncFlags & (NC_PartIdx|NC_IsCheck))!=0 ){ + /* Silently ignore database qualifiers inside CHECK constraints and + ** partial indices. Do not raise errors because that might break + ** legacy and because it does not hurt anything to just ignore the + ** database name. */ + zDb = 0; + }else{ + for(i=0; inDb; i++){ + assert( db->aDb[i].zDbSName ); + if( sqlite3StrICmp(db->aDb[i].zDbSName,zDb)==0 ){ + pSchema = db->aDb[i].pSchema; + break; + } + } + if( i==db->nDb && sqlite3StrICmp("main", zDb)==0 ){ + /* This branch is taken when the main database has been renamed + ** using SQLITE_DBCONFIG_MAINDBNAME. */ + pSchema = db->aDb[0].pSchema; + zDb = db->aDb[0].zDbSName; + } + } + } + + /* Start at the inner-most context and move outward until a match is found */ + assert( pNC && cnt==0 ); + do{ + ExprList *pEList; + SrcList *pSrcList = pNC->pSrcList; + + if( pSrcList ){ + for(i=0, pItem=pSrcList->a; inSrc; i++, pItem++){ + pTab = pItem->pSTab; + assert( pTab!=0 && pTab->zName!=0 ); + assert( pTab->nCol>0 || pParse->nErr ); + assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem)); + if( pItem->fg.isNestedFrom ){ + /* In this case, pItem is a subquery that has been formed from a + ** parenthesized subset of the FROM clause terms. Example: + ** .... FROM t1 LEFT JOIN (t2 RIGHT JOIN t3 USING(x)) USING(y) ... + ** \_________________________/ + ** This pItem -------------^ + */ + int hit = 0; + Select *pSel; + assert( pItem->fg.isSubquery ); + assert( pItem->u4.pSubq!=0 ); + pSel = pItem->u4.pSubq->pSelect; + assert( pSel!=0 ); + pEList = pSel->pEList; + assert( pEList!=0 ); + assert( pEList->nExpr==pTab->nCol ); + for(j=0; jnExpr; j++){ + int bRowid = 0; /* True if possible rowid match */ + if( !sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb, &bRowid) ){ + continue; + } + if( bRowid==0 ){ + if( cnt>0 ){ + if( pItem->fg.isUsing==0 + || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0 + || pMatch==pItem + ){ + /* Two or more tables have the same column name which is + ** not joined by USING. Or, a single table has two columns + ** that match a USING term (if pMatch==pItem). These are both + ** "ambiguous column name" errors. Signal as much by clearing + ** pFJMatch and letting cnt go above 1. */ + sqlite3ExprListDelete(db, pFJMatch); + pFJMatch = 0; + }else + if( (pItem->fg.jointype & JT_RIGHT)==0 ){ + /* An INNER or LEFT JOIN. Use the left-most table */ + continue; + }else + if( (pItem->fg.jointype & JT_LEFT)==0 ){ + /* A RIGHT JOIN. Use the right-most table */ + cnt = 0; + sqlite3ExprListDelete(db, pFJMatch); + pFJMatch = 0; + }else{ + /* For a FULL JOIN, we must construct a coalesce() func */ + extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); + } + } + cnt++; + hit = 1; + }else if( cnt>0 ){ + /* This is a potential rowid match, but there has already been + ** a real match found. So this can be ignored. */ + continue; + } + cntTab++; + pMatch = pItem; + pExpr->iColumn = j; + pEList->a[j].fg.bUsed = 1; + + /* rowid cannot be part of a USING clause - assert() this. */ + assert( bRowid==0 || pEList->a[j].fg.bUsingTerm==0 ); + if( pEList->a[j].fg.bUsingTerm ) break; + } + if( hit || zTab==0 ) continue; + } + assert( zDb==0 || zTab!=0 ); + if( zTab ){ + if( zDb ){ + if( pTab->pSchema!=pSchema ) continue; + if( pSchema==0 && strcmp(zDb,"*")!=0 ) continue; + } + if( pItem->zAlias!=0 ){ + if( sqlite3StrICmp(zTab, pItem->zAlias)!=0 ){ + continue; + } + }else if( sqlite3StrICmp(zTab, pTab->zName)!=0 ){ + if( pTab->tnum!=1 ) continue; + if( !isValidSchemaTableName(zTab, pTab, zDb) ) continue; + } + assert( ExprUseYTab(pExpr) ); + if( IN_RENAME_OBJECT && pItem->zAlias ){ + sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab); + } + } + j = sqlite3ColumnIndex(pTab, zCol); + if( j>=0 ){ + if( cnt>0 ){ + if( pItem->fg.isUsing==0 + || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0 + ){ + /* Two or more tables have the same column name which is + ** not joined by USING. This is an error. Signal as much + ** by clearing pFJMatch and letting cnt go above 1. */ + sqlite3ExprListDelete(db, pFJMatch); + pFJMatch = 0; + }else + if( (pItem->fg.jointype & JT_RIGHT)==0 ){ + /* An INNER or LEFT JOIN. Use the left-most table */ + continue; + }else + if( (pItem->fg.jointype & JT_LEFT)==0 ){ + /* A RIGHT JOIN. Use the right-most table */ + cnt = 0; + sqlite3ExprListDelete(db, pFJMatch); + pFJMatch = 0; + }else{ + /* For a FULL JOIN, we must construct a coalesce() func */ + extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); + } + } + cnt++; + pMatch = pItem; + /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ + pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j; + if( pItem->fg.isNestedFrom ){ + sqlite3SrcItemColumnUsed(pItem, j); + } + } + if( 0==cnt && VisibleRowid(pTab) ){ + /* pTab is a potential ROWID match. Keep track of it and match + ** the ROWID later if that seems appropriate. (Search for "cntTab" + ** to find related code.) Only allow a ROWID match if there is + ** a single ROWID match candidate. + */ +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + /* In SQLITE_ALLOW_ROWID_IN_VIEW mode, allow a ROWID match + ** if there is a single VIEW candidate or if there is a single + ** non-VIEW candidate plus multiple VIEW candidates. In other + ** words non-VIEW candidate terms take precedence over VIEWs. + */ + if( cntTab==0 + || (cntTab==1 + && pMatch!=0 + && ALWAYS(pMatch->pSTab!=0) + && (pMatch->pSTab->tabFlags & TF_Ephemeral)!=0 + && (pTab->tabFlags & TF_Ephemeral)==0) + ){ + cntTab = 1; + pMatch = pItem; + }else{ + cntTab++; + } +#else + /* The (much more common) non-SQLITE_ALLOW_ROWID_IN_VIEW case is + ** simpler since we require exactly one candidate, which will + ** always be a non-VIEW + */ + cntTab++; + pMatch = pItem; +#endif + } + } + if( pMatch ){ + pExpr->iTable = pMatch->iCursor; + assert( ExprUseYTab(pExpr) ); + pExpr->y.pTab = pMatch->pSTab; + if( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ){ + ExprSetProperty(pExpr, EP_CanBeNull); + } + pSchema = pExpr->y.pTab->pSchema; + } + } /* if( pSrcList ) */ + +#if !defined(SQLITE_OMIT_TRIGGER) || !defined(SQLITE_OMIT_UPSERT) + /* If we have not already resolved the name, then maybe + ** it is a new.* or old.* trigger argument reference. Or + ** maybe it is an excluded.* from an upsert. Or maybe it is + ** a reference in the RETURNING clause to a table being modified. + */ + if( cnt==0 && zDb==0 ){ + pTab = 0; +#ifndef SQLITE_OMIT_TRIGGER + if( pParse->pTriggerTab!=0 ){ + int op = pParse->eTriggerOp; + assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT ); + if( pParse->bReturning ){ + if( (pNC->ncFlags & NC_UBaseReg)!=0 + && ALWAYS(zTab==0 + || sqlite3StrICmp(zTab,pParse->pTriggerTab->zName)==0 + || isValidSchemaTableName(zTab, pParse->pTriggerTab, 0)) + ){ + pExpr->iTable = op!=TK_DELETE; + pTab = pParse->pTriggerTab; + } + }else if( op!=TK_DELETE && zTab && sqlite3StrICmp("new",zTab) == 0 ){ + pExpr->iTable = 1; + pTab = pParse->pTriggerTab; + }else if( op!=TK_INSERT && zTab && sqlite3StrICmp("old",zTab)==0 ){ + pExpr->iTable = 0; + pTab = pParse->pTriggerTab; + } + } +#endif /* SQLITE_OMIT_TRIGGER */ +#ifndef SQLITE_OMIT_UPSERT + if( (pNC->ncFlags & NC_UUpsert)!=0 && zTab!=0 ){ + Upsert *pUpsert = pNC->uNC.pUpsert; + if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){ + pTab = pUpsert->pUpsertSrc->a[0].pSTab; + pExpr->iTable = EXCLUDED_TABLE_NUMBER; + } + } +#endif /* SQLITE_OMIT_UPSERT */ + + if( pTab ){ + int iCol; + pSchema = pTab->pSchema; + cntTab++; + iCol = sqlite3ColumnIndex(pTab, zCol); + if( iCol>=0 ){ + if( pTab->iPKey==iCol ) iCol = -1; + }else{ + if( sqlite3IsRowid(zCol) && VisibleRowid(pTab) ){ + iCol = -1; + }else{ + iCol = pTab->nCol; + } + } + if( iColnCol ){ + cnt++; + pMatch = 0; +#ifndef SQLITE_OMIT_UPSERT + if( pExpr->iTable==EXCLUDED_TABLE_NUMBER ){ + testcase( iCol==(-1) ); + assert( ExprUseYTab(pExpr) ); + if( IN_RENAME_OBJECT ){ + pExpr->iColumn = iCol; + pExpr->y.pTab = pTab; + eNewExprOp = TK_COLUMN; + }else{ + pExpr->iTable = pNC->uNC.pUpsert->regData + + sqlite3TableColumnToStorage(pTab, iCol); + eNewExprOp = TK_REGISTER; + } + }else +#endif /* SQLITE_OMIT_UPSERT */ + { + assert( ExprUseYTab(pExpr) ); + pExpr->y.pTab = pTab; + if( pParse->bReturning ){ + eNewExprOp = TK_REGISTER; + pExpr->op2 = TK_COLUMN; + pExpr->iColumn = iCol; + pExpr->iTable = pNC->uNC.iBaseReg + (pTab->nCol+1)*pExpr->iTable + + sqlite3TableColumnToStorage(pTab, iCol) + 1; + }else{ + pExpr->iColumn = (i16)iCol; + eNewExprOp = TK_TRIGGER; +#ifndef SQLITE_OMIT_TRIGGER + if( iCol<0 ){ + pExpr->affExpr = SQLITE_AFF_INTEGER; + }else if( pExpr->iTable==0 ){ + testcase( iCol==31 ); + testcase( iCol==32 ); + pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<=1 + && pMatch + && (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0 + && sqlite3IsRowid(zCol) + && ALWAYS(VisibleRowid(pMatch->pSTab) || pMatch->fg.isNestedFrom) + ){ + cnt = cntTab; +#if SQLITE_ALLOW_ROWID_IN_VIEW+0==2 + if( pMatch->pSTab!=0 && IsView(pMatch->pSTab) ){ + eNewExprOp = TK_NULL; + } +#endif + if( pMatch->fg.isNestedFrom==0 ) pExpr->iColumn = -1; + pExpr->affExpr = SQLITE_AFF_INTEGER; + } + + /* + ** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z + ** might refer to an result-set alias. This happens, for example, when + ** we are resolving names in the WHERE clause of the following command: + ** + ** SELECT a+b AS x FROM table WHERE x<10; + ** + ** In cases like this, replace pExpr with a copy of the expression that + ** forms the result set entry ("a+b" in the example) and return immediately. + ** Note that the expression in the result set should have already been + ** resolved by the time the WHERE clause is resolved. + ** + ** The ability to use an output result-set column in the WHERE, GROUP BY, + ** or HAVING clauses, or as part of a larger expression in the ORDER BY + ** clause is not standard SQL. This is a (goofy) SQLite extension, that + ** is supported for backwards compatibility only. Hence, we issue a warning + ** on sqlite3_log() whenever the capability is used. + */ + if( cnt==0 + && (pNC->ncFlags & NC_UEList)!=0 + && zTab==0 + ){ + pEList = pNC->uNC.pEList; + assert( pEList!=0 ); + for(j=0; jnExpr; j++){ + char *zAs = pEList->a[j].zEName; + if( pEList->a[j].fg.eEName==ENAME_NAME + && sqlite3_stricmp(zAs, zCol)==0 + ){ + Expr *pOrig; + assert( pExpr->pLeft==0 && pExpr->pRight==0 ); + assert( ExprUseXList(pExpr)==0 || pExpr->x.pList==0 ); + assert( ExprUseXSelect(pExpr)==0 || pExpr->x.pSelect==0 ); + pOrig = pEList->a[j].pExpr; + if( (pNC->ncFlags&NC_AllowAgg)==0 && ExprHasProperty(pOrig, EP_Agg) ){ + sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs); + return WRC_Abort; + } + if( ExprHasProperty(pOrig, EP_Win) + && ((pNC->ncFlags&NC_AllowWin)==0 || pNC!=pTopNC ) + ){ + sqlite3ErrorMsg(pParse, "misuse of aliased window function %s",zAs); + return WRC_Abort; + } + if( sqlite3ExprVectorSize(pOrig)!=1 ){ + sqlite3ErrorMsg(pParse, "row value misused"); + return WRC_Abort; + } + resolveAlias(pParse, pEList, j, pExpr, nSubquery); + cnt = 1; + pMatch = 0; + assert( zTab==0 && zDb==0 ); + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, 0, (void*)pExpr); + } + goto lookupname_end; + } + } + } + + /* Advance to the next name context. The loop will exit when either + ** we have a match (cnt>0) or when we run out of name contexts. + */ + if( cnt ) break; + pNC = pNC->pNext; + nSubquery++; + }while( pNC ); + + + /* + ** If X and Y are NULL (in other words if only the column name Z is + ** supplied) and the value of Z is enclosed in double-quotes, then + ** Z is a string literal if it doesn't match any column names. In that + ** case, we need to return right away and not make any changes to + ** pExpr. + ** + ** Because no reference was made to outer contexts, the pNC->nRef + ** fields are not changed in any context. + */ + if( cnt==0 && zTab==0 ){ + assert( pExpr->op==TK_ID ); + if( ExprHasProperty(pExpr,EP_DblQuoted) + && areDoubleQuotedStringsEnabled(db, pTopNC) + ){ + /* If a double-quoted identifier does not match any known column name, + ** then treat it as a string. + ** + ** This hack was added in the early days of SQLite in a misguided attempt + ** to be compatible with MySQL 3.x, which used double-quotes for strings. + ** I now sorely regret putting in this hack. The effect of this hack is + ** that misspelled identifier names are silently converted into strings + ** rather than causing an error, to the frustration of countless + ** programmers. To all those frustrated programmers, my apologies. + ** + ** Someday, I hope to get rid of this hack. Unfortunately there is + ** a huge amount of legacy SQL that uses it. So for now, we just + ** issue a warning. + */ + sqlite3_log(SQLITE_WARNING, + "double-quoted string literal: \"%w\"", zCol); +#ifdef SQLITE_ENABLE_NORMALIZE + sqlite3VdbeAddDblquoteStr(db, pParse->pVdbe, zCol); +#endif + pExpr->op = TK_STRING; + memset(&pExpr->y, 0, sizeof(pExpr->y)); + return WRC_Prune; + } + if( sqlite3ExprIdToTrueFalse(pExpr) ){ + return WRC_Prune; + } + } + + /* + ** cnt==0 means there was not match. + ** cnt>1 means there were two or more matches. + ** + ** cnt==0 is always an error. cnt>1 is often an error, but might + ** be multiple matches for a NATURAL LEFT JOIN or a LEFT JOIN USING. + */ + assert( pFJMatch==0 || cnt>0 ); + assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) ); + if( cnt!=1 ){ + const char *zErr; + if( pFJMatch ){ + if( pFJMatch->nExpr==cnt-1 ){ + if( ExprHasProperty(pExpr,EP_Leaf) ){ + ExprClearProperty(pExpr,EP_Leaf); + }else{ + sqlite3ExprDelete(db, pExpr->pLeft); + pExpr->pLeft = 0; + sqlite3ExprDelete(db, pExpr->pRight); + pExpr->pRight = 0; + } + extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); + pExpr->op = TK_FUNCTION; + pExpr->u.zToken = "coalesce"; + pExpr->x.pList = pFJMatch; + pExpr->affExpr = SQLITE_AFF_DEFER; + cnt = 1; + goto lookupname_end; + }else{ + sqlite3ExprListDelete(db, pFJMatch); + pFJMatch = 0; + } + } + zErr = cnt==0 ? "no such column" : "ambiguous column name"; + if( zDb ){ + sqlite3ErrorMsg(pParse, "%s: %s.%s.%s", zErr, zDb, zTab, zCol); + }else if( zTab ){ + sqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol); + }else if( cnt==0 && ExprHasProperty(pRight,EP_DblQuoted) ){ + sqlite3ErrorMsg(pParse, "%s: \"%s\" - should this be a" + " string literal in single-quotes?", + zErr, zCol); + }else{ + sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol); + } + sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr); + pParse->checkSchema = 1; + pTopNC->nNcErr++; + eNewExprOp = TK_NULL; + } + assert( pFJMatch==0 ); + + /* Remove all substructure from pExpr */ + if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ + sqlite3ExprDelete(db, pExpr->pLeft); + pExpr->pLeft = 0; + sqlite3ExprDelete(db, pExpr->pRight); + pExpr->pRight = 0; + ExprSetProperty(pExpr, EP_Leaf); + } + + /* If a column from a table in pSrcList is referenced, then record + ** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes + ** bit 0 to be set. Column 1 sets bit 1. And so forth. Bit 63 is + ** set if the 63rd or any subsequent column is used. + ** + ** The colUsed mask is an optimization used to help determine if an + ** index is a covering index. The correct answer is still obtained + ** if the mask contains extra set bits. However, it is important to + ** avoid setting bits beyond the maximum column number of the table. + ** (See ticket [b92e5e8ec2cdbaa1]). + ** + ** If a generated column is referenced, set bits for every column + ** of the table. + */ + if( pMatch ){ + if( pExpr->iColumn>=0 ){ + pMatch->colUsed |= sqlite3ExprColUsed(pExpr); + }else{ + pMatch->fg.rowidUsed = 1; + } + } + + pExpr->op = eNewExprOp; +lookupname_end: + if( cnt==1 ){ + assert( pNC!=0 ); +#ifndef SQLITE_OMIT_AUTHORIZATION + if( pParse->db->xAuth + && (pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER) + ){ + sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList); + } +#endif + /* Increment the nRef value on all name contexts from TopNC up to + ** the point where the name matched. */ + for(;;){ + assert( pTopNC!=0 ); + pTopNC->nRef++; + if( pTopNC==pNC ) break; + pTopNC = pTopNC->pNext; + } + return WRC_Prune; + } else { + return WRC_Abort; + } +} + +/* +** Allocate and return a pointer to an expression to load the column iCol +** from datasource iSrc in SrcList pSrc. +*/ +SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){ + Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0); + if( p ){ + SrcItem *pItem = &pSrc->a[iSrc]; + Table *pTab; + assert( ExprUseYTab(p) ); + pTab = p->y.pTab = pItem->pSTab; + p->iTable = pItem->iCursor; + if( p->y.pTab->iPKey==iCol ){ + p->iColumn = -1; + }else{ + p->iColumn = (ynVar)iCol; + if( (pTab->tabFlags & TF_HasGenerated)!=0 + && (pTab->aCol[iCol].colFlags & COLFLAG_GENERATED)!=0 + ){ + testcase( pTab->nCol==63 ); + testcase( pTab->nCol==64 ); + pItem->colUsed = pTab->nCol>=64 ? ALLBITS : MASKBIT(pTab->nCol)-1; + }else{ + testcase( iCol==BMS ); + testcase( iCol==BMS-1 ); + pItem->colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol); + } + } + } + return p; +} + +/* +** Report an error that an expression is not valid for some set of +** pNC->ncFlags values determined by validMask. +** +** static void notValid( +** Parse *pParse, // Leave error message here +** NameContext *pNC, // The name context +** const char *zMsg, // Type of error +** int validMask, // Set of contexts for which prohibited +** Expr *pExpr // Invalidate this expression on error +** ){...} +** +** As an optimization, since the conditional is almost always false +** (because errors are rare), the conditional is moved outside of the +** function call using a macro. +*/ +static void notValidImpl( + Parse *pParse, /* Leave error message here */ + NameContext *pNC, /* The name context */ + const char *zMsg, /* Type of error */ + Expr *pExpr, /* Invalidate this expression on error */ + Expr *pError /* Associate error with this expression */ +){ + const char *zIn = "partial index WHERE clauses"; + if( pNC->ncFlags & NC_IdxExpr ) zIn = "index expressions"; +#ifndef SQLITE_OMIT_CHECK + else if( pNC->ncFlags & NC_IsCheck ) zIn = "CHECK constraints"; +#endif +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + else if( pNC->ncFlags & NC_GenCol ) zIn = "generated columns"; +#endif + sqlite3ErrorMsg(pParse, "%s prohibited in %s", zMsg, zIn); + if( pExpr ) pExpr->op = TK_NULL; + sqlite3RecordErrorOffsetOfExpr(pParse->db, pError); +} +#define sqlite3ResolveNotValid(P,N,M,X,E,R) \ + assert( ((X)&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol))==0 ); \ + if( ((N)->ncFlags & (X))!=0 ) notValidImpl(P,N,M,E,R); + +/* +** Expression p should encode a floating point value between 1.0 and 0.0. +** Return 134,217,728 (2^27) times this value. Or return -1 if p is not +** a floating point value between 1.0 and 0.0. +*/ +static int exprProbability(Expr *p){ + double r = -1.0; + if( p->op!=TK_FLOAT ) return -1; + assert( !ExprHasProperty(p, EP_IntValue) ); + sqlite3AtoF(p->u.zToken, &r); + assert( r>=0.0 ); + if( r>1.0 ) return -1; + return (int)(r*134217728.0); +} + +/* +** Set the EP_SubtArg property on every expression inside of +** pList. If any subexpression is actually a subquery, then +** also set the EP_SubtArg property on the first result-set +** column of that subquery. +*/ +static SQLITE_NOINLINE void resolveSetExprSubtypeArg(ExprList *pList){ + int nn, ii; + nn = pList ? pList->nExpr : 0; + for(ii=0; iia[ii].pExpr; + while( 1 /*exit-by-break*/ ){ + ExprSetProperty(pExpr, EP_SubtArg); + if( pExpr->op==TK_SELECT ){ + assert( ExprUseXSelect(pExpr) ); + assert( pExpr->x.pSelect!=0 ); + resolveSetExprSubtypeArg(pExpr->x.pSelect->pEList); + break; + } + if( pExpr->op==TK_UPLUS ){ + pExpr = pExpr->pLeft; + assert( pExpr!=0 ); + }else{ + break; + } + } + } +} + +/* +** This routine is callback for sqlite3WalkExpr(). +** +** Resolve symbolic names into TK_COLUMN operators for the current +** node in the expression tree. Return 0 to continue the search down +** the tree or 2 to abort the tree walk. +** +** This routine also does error checking and name resolution for +** function names. The operator for aggregate functions is changed +** to TK_AGG_FUNCTION. +*/ +static int resolveExprStep(Walker *pWalker, Expr *pExpr){ + NameContext *pNC; + Parse *pParse; + + pNC = pWalker->u.pNC; + assert( pNC!=0 ); + pParse = pNC->pParse; + assert( pParse==pWalker->pParse ); + +#ifndef NDEBUG + if( pNC->pSrcList && pNC->pSrcList->nAlloc>0 ){ + SrcList *pSrcList = pNC->pSrcList; + int i; + for(i=0; ipSrcList->nSrc; i++){ + assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursornTab); + } + } +#endif + switch( pExpr->op ){ + + /* The special operator TK_ROW means use the rowid for the first + ** column in the FROM clause. This is used by the LIMIT and ORDER BY + ** clause processing on UPDATE and DELETE statements, and by + ** UPDATE ... FROM statement processing. + */ + case TK_ROW: { + SrcList *pSrcList = pNC->pSrcList; + SrcItem *pItem; + assert( pSrcList && pSrcList->nSrc>=1 ); + pItem = pSrcList->a; + pExpr->op = TK_COLUMN; + assert( ExprUseYTab(pExpr) ); + pExpr->y.pTab = pItem->pSTab; + pExpr->iTable = pItem->iCursor; + pExpr->iColumn--; + pExpr->affExpr = SQLITE_AFF_INTEGER; + break; + } + + /* An optimization: Attempt to convert + ** + ** "expr IS NOT NULL" --> "TRUE" + ** "expr IS NULL" --> "FALSE" + ** + ** if we can prove that "expr" is never NULL. Call this the + ** "NOT NULL strength reduction optimization". + ** + ** If this optimization occurs, also restore the NameContext ref-counts + ** to the state they where in before the "column" LHS expression was + ** resolved. This prevents "column" from being counted as having been + ** referenced, which might prevent a SELECT from being erroneously + ** marked as correlated. + ** + ** 2024-03-28: Beware of aggregates. A bare column of aggregated table + ** can still evaluate to NULL even though it is marked as NOT NULL. + ** Example: + ** + ** CREATE TABLE t1(a INT NOT NULL); + ** SELECT a, a IS NULL, a IS NOT NULL, count(*) FROM t1; + ** + ** The "a IS NULL" and "a IS NOT NULL" expressions cannot be optimized + ** here because at the time this case is hit, we do not yet know whether + ** or not t1 is being aggregated. We have to assume the worst and omit + ** the optimization. The only time it is safe to apply this optimization + ** is within the WHERE clause. + */ + case TK_NOTNULL: + case TK_ISNULL: { + int anRef[8]; + NameContext *p; + int i; + for(i=0, p=pNC; p && ipNext, i++){ + anRef[i] = p->nRef; + } + sqlite3WalkExpr(pWalker, pExpr->pLeft); + if( IN_RENAME_OBJECT ) return WRC_Prune; + if( sqlite3ExprCanBeNull(pExpr->pLeft) ){ + /* The expression can be NULL. So the optimization does not apply */ + return WRC_Prune; + } + + for(i=0, p=pNC; p; p=p->pNext, i++){ + if( (p->ncFlags & NC_Where)==0 ){ + return WRC_Prune; /* Not in a WHERE clause. Unsafe to optimize. */ + } + } + testcase( ExprHasProperty(pExpr, EP_OuterON) ); + assert( !ExprHasProperty(pExpr, EP_IntValue) ); +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x80000 ){ + sqlite3DebugPrintf( + "NOT NULL strength reduction converts the following to %d:\n", + pExpr->op==TK_NOTNULL + ); + sqlite3ShowExpr(pExpr); + } +#endif /* TREETRACE_ENABLED */ + pExpr->u.iValue = (pExpr->op==TK_NOTNULL); + pExpr->flags |= EP_IntValue; + pExpr->op = TK_INTEGER; + for(i=0, p=pNC; p && ipNext, i++){ + p->nRef = anRef[i]; + } + sqlite3ExprDelete(pParse->db, pExpr->pLeft); + pExpr->pLeft = 0; + return WRC_Prune; + } + + /* A column name: ID + ** Or table name and column name: ID.ID + ** Or a database, table and column: ID.ID.ID + ** + ** The TK_ID and TK_OUT cases are combined so that there will only + ** be one call to lookupName(). Then the compiler will in-line + ** lookupName() for a size reduction and performance increase. + */ + case TK_ID: + case TK_DOT: { + const char *zTable; + const char *zDb; + Expr *pRight; + + if( pExpr->op==TK_ID ){ + zDb = 0; + zTable = 0; + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + pRight = pExpr; + }else{ + Expr *pLeft = pExpr->pLeft; + testcase( pNC->ncFlags & NC_IdxExpr ); + testcase( pNC->ncFlags & NC_GenCol ); + sqlite3ResolveNotValid(pParse, pNC, "the \".\" operator", + NC_IdxExpr|NC_GenCol, 0, pExpr); + pRight = pExpr->pRight; + if( pRight->op==TK_ID ){ + zDb = 0; + }else{ + assert( pRight->op==TK_DOT ); + assert( !ExprHasProperty(pRight, EP_IntValue) ); + zDb = pLeft->u.zToken; + pLeft = pRight->pLeft; + pRight = pRight->pRight; + } + assert( ExprUseUToken(pLeft) && ExprUseUToken(pRight) ); + zTable = pLeft->u.zToken; + assert( ExprUseYTab(pExpr) ); + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight); + sqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft); + } + } + return lookupName(pParse, zDb, zTable, pRight, pNC, pExpr); + } + + /* Resolve function names + */ + case TK_FUNCTION: { + ExprList *pList; /* The argument list */ + int n; /* Number of arguments */ + int no_such_func = 0; /* True if no such function exists */ + int wrong_num_args = 0; /* True if wrong number of arguments */ + int is_agg = 0; /* True if is an aggregate function */ + const char *zId; /* The function name. */ + FuncDef *pDef; /* Information about the function */ + u8 enc = ENC(pParse->db); /* The database encoding */ + int savedAllowFlags = (pNC->ncFlags & (NC_AllowAgg | NC_AllowWin)); +#ifndef SQLITE_OMIT_WINDOWFUNC + Window *pWin = (IsWindowFunc(pExpr) ? pExpr->y.pWin : 0); +#endif + assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) ); + assert( pExpr->pLeft==0 || pExpr->pLeft->op==TK_ORDER ); + pList = pExpr->x.pList; + n = pList ? pList->nExpr : 0; + zId = pExpr->u.zToken; + pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0); + if( pDef==0 ){ + pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0); + if( pDef==0 ){ + no_such_func = 1; + }else{ + wrong_num_args = 1; + } + }else{ + is_agg = pDef->xFinalize!=0; + if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){ + ExprSetProperty(pExpr, EP_Unlikely); + if( n==2 ){ + pExpr->iTable = exprProbability(pList->a[1].pExpr); + if( pExpr->iTable<0 ){ + sqlite3ErrorMsg(pParse, + "second argument to %#T() must be a " + "constant between 0.0 and 1.0", pExpr); + pNC->nNcErr++; + } + }else{ + /* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is + ** equivalent to likelihood(X, 0.0625). + ** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is + ** short-hand for likelihood(X,0.0625). + ** EVIDENCE-OF: R-36850-34127 The likely(X) function is short-hand + ** for likelihood(X,0.9375). + ** EVIDENCE-OF: R-53436-40973 The likely(X) function is equivalent + ** to likelihood(X,0.9375). */ + /* TUNING: unlikely() probability is 0.0625. likely() is 0.9375 */ + pExpr->iTable = pDef->zName[0]=='u' ? 8388608 : 125829120; + } + } +#ifndef SQLITE_OMIT_AUTHORIZATION + { + int auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0,pDef->zName,0); + if( auth!=SQLITE_OK ){ + if( auth==SQLITE_DENY ){ + sqlite3ErrorMsg(pParse, "not authorized to use function: %#T", + pExpr); + pNC->nNcErr++; + } + pExpr->op = TK_NULL; + return WRC_Prune; + } + } +#endif + + /* If the function may call sqlite3_value_subtype(), then set the + ** EP_SubtArg flag on all of its argument expressions. This prevents + ** where.c from replacing the expression with a value read from an + ** index on the same expression, which will not have the correct + ** subtype. Also set the flag if the function expression itself is + ** an EP_SubtArg expression. In this case subtypes are required as + ** the function may return a value with a subtype back to its + ** caller using sqlite3_result_value(). */ + if( (pDef->funcFlags & SQLITE_SUBTYPE) + || ExprHasProperty(pExpr, EP_SubtArg) + ){ + resolveSetExprSubtypeArg(pList); + } + + if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){ + /* For the purposes of the EP_ConstFunc flag, date and time + ** functions and other functions that change slowly are considered + ** constant because they are constant for the duration of one query. + ** This allows them to be factored out of inner loops. */ + ExprSetProperty(pExpr,EP_ConstFunc); + } + if( (pDef->funcFlags & SQLITE_FUNC_CONSTANT)==0 ){ + /* Clearly non-deterministic functions like random(), but also + ** date/time functions that use 'now', and other functions like + ** sqlite_version() that might change over time cannot be used + ** in an index or generated column. Curiously, they can be used + ** in a CHECK constraint. SQLServer, MySQL, and PostgreSQL all + ** allow this. */ + sqlite3ResolveNotValid(pParse, pNC, "non-deterministic functions", + NC_IdxExpr|NC_PartIdx|NC_GenCol, 0, pExpr); + }else{ + assert( (NC_SelfRef & 0xff)==NC_SelfRef ); /* Must fit in 8 bits */ + pExpr->op2 = pNC->ncFlags & NC_SelfRef; + } + if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0 + && pParse->nested==0 + && (pParse->db->mDbFlags & DBFLAG_InternalFunc)==0 + ){ + /* Internal-use-only functions are disallowed unless the + ** SQL is being compiled using sqlite3NestedParse() or + ** the SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test-control has be + ** used to activate internal functions for testing purposes */ + no_such_func = 1; + pDef = 0; + }else + if( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0 + && !IN_RENAME_OBJECT + ){ + if( pNC->ncFlags & NC_FromDDL ) ExprSetProperty(pExpr, EP_FromDDL); + sqlite3ExprFunctionUsable(pParse, pExpr, pDef); + } + } + + if( 0==IN_RENAME_OBJECT ){ +#ifndef SQLITE_OMIT_WINDOWFUNC + assert( is_agg==0 || (pDef->funcFlags & SQLITE_FUNC_MINMAX) + || (pDef->xValue==0 && pDef->xInverse==0) + || (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize) + ); + if( pDef && pDef->xValue==0 && pWin ){ + sqlite3ErrorMsg(pParse, + "%#T() may not be used as a window function", pExpr + ); + pNC->nNcErr++; + }else if( + (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) + || (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pWin) + || (is_agg && pWin && (pNC->ncFlags & NC_AllowWin)==0) + ){ + const char *zType; + if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pWin ){ + zType = "window"; + }else{ + zType = "aggregate"; + } + sqlite3ErrorMsg(pParse, "misuse of %s function %#T()",zType,pExpr); + pNC->nNcErr++; + is_agg = 0; + } +#else + if( (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) ){ + sqlite3ErrorMsg(pParse,"misuse of aggregate function %#T()",pExpr); + pNC->nNcErr++; + is_agg = 0; + } +#endif + else if( no_such_func && pParse->db->init.busy==0 +#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION + && pParse->explain==0 +#endif + ){ + sqlite3ErrorMsg(pParse, "no such function: %#T", pExpr); + pNC->nNcErr++; + }else if( wrong_num_args ){ + sqlite3ErrorMsg(pParse,"wrong number of arguments to function %#T()", + pExpr); + pNC->nNcErr++; + } +#ifndef SQLITE_OMIT_WINDOWFUNC + else if( is_agg==0 && ExprHasProperty(pExpr, EP_WinFunc) ){ + sqlite3ErrorMsg(pParse, + "FILTER may not be used with non-aggregate %#T()", + pExpr + ); + pNC->nNcErr++; + } +#endif + else if( is_agg==0 && pExpr->pLeft ){ + sqlite3ExprOrderByAggregateError(pParse, pExpr); + pNC->nNcErr++; + } + if( is_agg ){ + /* Window functions may not be arguments of aggregate functions. + ** Or arguments of other window functions. But aggregate functions + ** may be arguments for window functions. */ +#ifndef SQLITE_OMIT_WINDOWFUNC + pNC->ncFlags &= ~(NC_AllowWin | (!pWin ? NC_AllowAgg : 0)); +#else + pNC->ncFlags &= ~NC_AllowAgg; +#endif + } + } + else if( ExprHasProperty(pExpr, EP_WinFunc) || pExpr->pLeft ){ + is_agg = 1; + } + sqlite3WalkExprList(pWalker, pList); + if( is_agg ){ + if( pExpr->pLeft ){ + assert( pExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pExpr->pLeft) ); + sqlite3WalkExprList(pWalker, pExpr->pLeft->x.pList); + } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pWin && pParse->nErr==0 ){ + Select *pSel = pNC->pWinSelect; + assert( ExprUseYWin(pExpr) && pWin==pExpr->y.pWin ); + if( IN_RENAME_OBJECT==0 ){ + sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef); + if( pParse->db->mallocFailed ) break; + } + sqlite3WalkExprList(pWalker, pWin->pPartition); + sqlite3WalkExprList(pWalker, pWin->pOrderBy); + sqlite3WalkExpr(pWalker, pWin->pFilter); + sqlite3WindowLink(pSel, pWin); + pNC->ncFlags |= NC_HasWin; + }else +#endif /* SQLITE_OMIT_WINDOWFUNC */ + { + NameContext *pNC2; /* For looping up thru outer contexts */ + pExpr->op = TK_AGG_FUNCTION; + pExpr->op2 = 0; +#ifndef SQLITE_OMIT_WINDOWFUNC + if( ExprHasProperty(pExpr, EP_WinFunc) ){ + sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter); + } +#endif + pNC2 = pNC; + while( pNC2 + && sqlite3ReferencesSrcList(pParse, pExpr, pNC2->pSrcList)==0 + ){ + pExpr->op2 += (1 + pNC2->nNestedSelect); + pNC2 = pNC2->pNext; + } + assert( pDef!=0 || IN_RENAME_OBJECT ); + if( pNC2 && pDef ){ + pExpr->op2 += pNC2->nNestedSelect; + assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg ); + assert( SQLITE_FUNC_ANYORDER==NC_OrderAgg ); + testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 ); + testcase( (pDef->funcFlags & SQLITE_FUNC_ANYORDER)!=0 ); + pNC2->ncFlags |= NC_HasAgg + | ((pDef->funcFlags^SQLITE_FUNC_ANYORDER) + & (SQLITE_FUNC_MINMAX|SQLITE_FUNC_ANYORDER)); + } + } + pNC->ncFlags |= savedAllowFlags; + } + /* FIX ME: Compute pExpr->affinity based on the expected return + ** type of the function + */ + return WRC_Prune; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_EXISTS: + case TK_SELECT: +#endif + case TK_IN: { + testcase( pExpr->op==TK_IN ); + testcase( pExpr->op==TK_EXISTS ); + testcase( pExpr->op==TK_SELECT ); + if( ExprUseXSelect(pExpr) ){ + int nRef = pNC->nRef; + testcase( pNC->ncFlags & NC_IsCheck ); + testcase( pNC->ncFlags & NC_PartIdx ); + testcase( pNC->ncFlags & NC_IdxExpr ); + testcase( pNC->ncFlags & NC_GenCol ); + assert( pExpr->x.pSelect ); + if( pExpr->op==TK_EXISTS ) pParse->bHasExists = 1; + if( pNC->ncFlags & NC_SelfRef ){ + notValidImpl(pParse, pNC, "subqueries", pExpr, pExpr); + }else{ + sqlite3WalkSelect(pWalker, pExpr->x.pSelect); + } + assert( pNC->nRef>=nRef ); + if( nRef!=pNC->nRef ){ + ExprSetProperty(pExpr, EP_VarSelect); + pExpr->x.pSelect->selFlags |= SF_Correlated; + } + pNC->ncFlags |= NC_Subquery; + } + break; + } + case TK_VARIABLE: { + testcase( pNC->ncFlags & NC_IsCheck ); + testcase( pNC->ncFlags & NC_PartIdx ); + testcase( pNC->ncFlags & NC_IdxExpr ); + testcase( pNC->ncFlags & NC_GenCol ); + sqlite3ResolveNotValid(pParse, pNC, "parameters", + NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol, pExpr, pExpr); + break; + } + case TK_IS: + case TK_ISNOT: { + Expr *pRight = sqlite3ExprSkipCollateAndLikely(pExpr->pRight); + assert( !ExprHasProperty(pExpr, EP_Reduced) ); + /* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE", + ** and "x IS NOT FALSE". */ + if( ALWAYS(pRight) && (pRight->op==TK_ID || pRight->op==TK_TRUEFALSE) ){ + int rc = resolveExprStep(pWalker, pRight); + if( rc==WRC_Abort ) return WRC_Abort; + if( pRight->op==TK_TRUEFALSE ){ + pExpr->op2 = pExpr->op; + pExpr->op = TK_TRUTH; + return WRC_Continue; + } + } + /* no break */ deliberate_fall_through + } + case TK_BETWEEN: + case TK_EQ: + case TK_NE: + case TK_LT: + case TK_LE: + case TK_GT: + case TK_GE: { + int nLeft, nRight; + if( pParse->db->mallocFailed ) break; + assert( pExpr->pLeft!=0 ); + nLeft = sqlite3ExprVectorSize(pExpr->pLeft); + if( pExpr->op==TK_BETWEEN ){ + assert( ExprUseXList(pExpr) ); + nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[0].pExpr); + if( nRight==nLeft ){ + nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[1].pExpr); + } + }else{ + assert( pExpr->pRight!=0 ); + nRight = sqlite3ExprVectorSize(pExpr->pRight); + } + if( nLeft!=nRight ){ + testcase( pExpr->op==TK_EQ ); + testcase( pExpr->op==TK_NE ); + testcase( pExpr->op==TK_LT ); + testcase( pExpr->op==TK_LE ); + testcase( pExpr->op==TK_GT ); + testcase( pExpr->op==TK_GE ); + testcase( pExpr->op==TK_IS ); + testcase( pExpr->op==TK_ISNOT ); + testcase( pExpr->op==TK_BETWEEN ); + sqlite3ErrorMsg(pParse, "row value misused"); + sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr); + } + break; + } + } + assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 ); + return pParse->nErr ? WRC_Abort : WRC_Continue; +} + +/* +** pEList is a list of expressions which are really the result set of the +** a SELECT statement. pE is a term in an ORDER BY or GROUP BY clause. +** This routine checks to see if pE is a simple identifier which corresponds +** to the AS-name of one of the terms of the expression list. If it is, +** this routine return an integer between 1 and N where N is the number of +** elements in pEList, corresponding to the matching entry. If there is +** no match, or if pE is not a simple identifier, then this routine +** return 0. +** +** pEList has been resolved. pE has not. +*/ +static int resolveAsName( + Parse *pParse, /* Parsing context for error messages */ + ExprList *pEList, /* List of expressions to scan */ + Expr *pE /* Expression we are trying to match */ +){ + int i; /* Loop counter */ + + UNUSED_PARAMETER(pParse); + + if( pE->op==TK_ID ){ + const char *zCol; + assert( !ExprHasProperty(pE, EP_IntValue) ); + zCol = pE->u.zToken; + for(i=0; inExpr; i++){ + if( pEList->a[i].fg.eEName==ENAME_NAME + && sqlite3_stricmp(pEList->a[i].zEName, zCol)==0 + ){ + return i+1; + } + } + } + return 0; +} + +/* +** pE is a pointer to an expression which is a single term in the +** ORDER BY of a compound SELECT. The expression has not been +** name resolved. +** +** At the point this routine is called, we already know that the +** ORDER BY term is not an integer index into the result set. That +** case is handled by the calling routine. +** +** Attempt to match pE against result set columns in the left-most +** SELECT statement. Return the index i of the matching column, +** as an indication to the caller that it should sort by the i-th column. +** The left-most column is 1. In other words, the value returned is the +** same integer value that would be used in the SQL statement to indicate +** the column. +** +** If there is no match, return 0. Return -1 if an error occurs. +*/ +static int resolveOrderByTermToExprList( + Parse *pParse, /* Parsing context for error messages */ + Select *pSelect, /* The SELECT statement with the ORDER BY clause */ + Expr *pE /* The specific ORDER BY term */ +){ + int i; /* Loop counter */ + ExprList *pEList; /* The columns of the result set */ + NameContext nc; /* Name context for resolving pE */ + sqlite3 *db; /* Database connection */ + int rc; /* Return code from subprocedures */ + u8 savedSuppErr; /* Saved value of db->suppressErr */ + + assert( sqlite3ExprIsInteger(pE, &i, 0)==0 ); + pEList = pSelect->pEList; + + /* Resolve all names in the ORDER BY term expression + */ + memset(&nc, 0, sizeof(nc)); + nc.pParse = pParse; + nc.pSrcList = pSelect->pSrc; + nc.uNC.pEList = pEList; + nc.ncFlags = NC_AllowAgg|NC_UEList|NC_NoSelect; + nc.nNcErr = 0; + db = pParse->db; + savedSuppErr = db->suppressErr; + db->suppressErr = 1; + rc = sqlite3ResolveExprNames(&nc, pE); + db->suppressErr = savedSuppErr; + if( rc ) return 0; + + /* Try to match the ORDER BY expression against an expression + ** in the result set. Return an 1-based index of the matching + ** result-set entry. + */ + for(i=0; inExpr; i++){ + if( sqlite3ExprCompare(0, pEList->a[i].pExpr, pE, -1)<2 ){ + return i+1; + } + } + + /* If no match, return 0. */ + return 0; +} + +/* +** Generate an ORDER BY or GROUP BY term out-of-range error. +*/ +static void resolveOutOfRangeError( + Parse *pParse, /* The error context into which to write the error */ + const char *zType, /* "ORDER" or "GROUP" */ + int i, /* The index (1-based) of the term out of range */ + int mx, /* Largest permissible value of i */ + Expr *pError /* Associate the error with the expression */ +){ + sqlite3ErrorMsg(pParse, + "%r %s BY term out of range - should be " + "between 1 and %d", i, zType, mx); + sqlite3RecordErrorOffsetOfExpr(pParse->db, pError); +} + +/* +** Analyze the ORDER BY clause in a compound SELECT statement. Modify +** each term of the ORDER BY clause is a constant integer between 1 +** and N where N is the number of columns in the compound SELECT. +** +** ORDER BY terms that are already an integer between 1 and N are +** unmodified. ORDER BY terms that are integers outside the range of +** 1 through N generate an error. ORDER BY terms that are expressions +** are matched against result set expressions of compound SELECT +** beginning with the left-most SELECT and working toward the right. +** At the first match, the ORDER BY expression is transformed into +** the integer column number. +** +** Return the number of errors seen. +*/ +static int resolveCompoundOrderBy( + Parse *pParse, /* Parsing context. Leave error messages here */ + Select *pSelect /* The SELECT statement containing the ORDER BY */ +){ + int i; + ExprList *pOrderBy; + ExprList *pEList; + sqlite3 *db; + int moreToDo = 1; + + pOrderBy = pSelect->pOrderBy; + if( pOrderBy==0 ) return 0; + db = pParse->db; + if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ + sqlite3ErrorMsg(pParse, "too many terms in ORDER BY clause"); + return 1; + } + for(i=0; inExpr; i++){ + pOrderBy->a[i].fg.done = 0; + } + pSelect->pNext = 0; + while( pSelect->pPrior ){ + pSelect->pPrior->pNext = pSelect; + pSelect = pSelect->pPrior; + } + while( pSelect && moreToDo ){ + struct ExprList_item *pItem; + moreToDo = 0; + pEList = pSelect->pEList; + assert( pEList!=0 ); + for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ + int iCol = -1; + Expr *pE, *pDup; + if( pItem->fg.done ) continue; + pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr); + if( NEVER(pE==0) ) continue; + if( sqlite3ExprIsInteger(pE, &iCol, 0) ){ + if( iCol<=0 || iCol>pEList->nExpr ){ + resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr, pE); + return 1; + } + }else{ + iCol = resolveAsName(pParse, pEList, pE); + if( iCol==0 ){ + /* Now test if expression pE matches one of the values returned + ** by pSelect. In the usual case this is done by duplicating the + ** expression, resolving any symbols in it, and then comparing + ** it against each expression returned by the SELECT statement. + ** Once the comparisons are finished, the duplicate expression + ** is deleted. + ** + ** If this is running as part of an ALTER TABLE operation and + ** the symbols resolve successfully, also resolve the symbols in the + ** actual expression. This allows the code in alter.c to modify + ** column references within the ORDER BY expression as required. */ + pDup = sqlite3ExprDup(db, pE, 0); + if( !db->mallocFailed ){ + assert(pDup); + iCol = resolveOrderByTermToExprList(pParse, pSelect, pDup); + if( IN_RENAME_OBJECT && iCol>0 ){ + resolveOrderByTermToExprList(pParse, pSelect, pE); + } + } + sqlite3ExprDelete(db, pDup); + } + } + if( iCol>0 ){ + /* Convert the ORDER BY term into an integer column number iCol, + ** taking care to preserve the COLLATE clause if it exists. */ + if( !IN_RENAME_OBJECT ){ + Expr *pNew = sqlite3ExprInt32(db, iCol); + if( pNew==0 ) return 1; + if( pItem->pExpr==pE ){ + pItem->pExpr = pNew; + }else{ + Expr *pParent = pItem->pExpr; + assert( pParent->op==TK_COLLATE ); + while( pParent->pLeft->op==TK_COLLATE ) pParent = pParent->pLeft; + assert( pParent->pLeft==pE ); + pParent->pLeft = pNew; + } + sqlite3ExprDelete(db, pE); + pItem->u.x.iOrderByCol = (u16)iCol; + } + pItem->fg.done = 1; + }else{ + moreToDo = 1; + } + } + pSelect = pSelect->pNext; + } + for(i=0; inExpr; i++){ + if( pOrderBy->a[i].fg.done==0 ){ + sqlite3ErrorMsg(pParse, "%r ORDER BY term does not match any " + "column in the result set", i+1); + return 1; + } + } + return 0; +} + +/* +** Check every term in the ORDER BY or GROUP BY clause pOrderBy of +** the SELECT statement pSelect. If any term is reference to a +** result set expression (as determined by the ExprList.a.u.x.iOrderByCol +** field) then convert that term into a copy of the corresponding result set +** column. +** +** If any errors are detected, add an error message to pParse and +** return non-zero. Return zero if no errors are seen. +*/ +SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy( + Parse *pParse, /* Parsing context. Leave error messages here */ + Select *pSelect, /* The SELECT statement containing the clause */ + ExprList *pOrderBy, /* The ORDER BY or GROUP BY clause to be processed */ + const char *zType /* "ORDER" or "GROUP" */ +){ + int i; + sqlite3 *db = pParse->db; + ExprList *pEList; + struct ExprList_item *pItem; + + if( pOrderBy==0 || pParse->db->mallocFailed || IN_RENAME_OBJECT ) return 0; + if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ + sqlite3ErrorMsg(pParse, "too many terms in %s BY clause", zType); + return 1; + } + pEList = pSelect->pEList; + assert( pEList!=0 ); /* sqlite3SelectNew() guarantees this */ + for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ + if( pItem->u.x.iOrderByCol ){ + if( pItem->u.x.iOrderByCol>pEList->nExpr ){ + resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr, 0); + return 1; + } + resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr,0); + } + } + return 0; +} + +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** Walker callback for windowRemoveExprFromSelect(). +*/ +static int resolveRemoveWindowsCb(Walker *pWalker, Expr *pExpr){ + UNUSED_PARAMETER(pWalker); + if( ExprHasProperty(pExpr, EP_WinFunc) ){ + Window *pWin = pExpr->y.pWin; + sqlite3WindowUnlinkFromSelect(pWin); + } + return WRC_Continue; +} + +/* +** Remove any Window objects owned by the expression pExpr from the +** Select.pWin list of Select object pSelect. +*/ +static void windowRemoveExprFromSelect(Select *pSelect, Expr *pExpr){ + if( pSelect->pWin ){ + Walker sWalker; + memset(&sWalker, 0, sizeof(Walker)); + sWalker.xExprCallback = resolveRemoveWindowsCb; + sWalker.u.pSelect = pSelect; + sqlite3WalkExpr(&sWalker, pExpr); + } +} +#else +# define windowRemoveExprFromSelect(a, b) +#endif /* SQLITE_OMIT_WINDOWFUNC */ + +/* +** pOrderBy is an ORDER BY or GROUP BY clause in SELECT statement pSelect. +** The Name context of the SELECT statement is pNC. zType is either +** "ORDER" or "GROUP" depending on which type of clause pOrderBy is. +** +** This routine resolves each term of the clause into an expression. +** If the order-by term is an integer I between 1 and N (where N is the +** number of columns in the result set of the SELECT) then the expression +** in the resolution is a copy of the I-th result-set expression. If +** the order-by term is an identifier that corresponds to the AS-name of +** a result-set expression, then the term resolves to a copy of the +** result-set expression. Otherwise, the expression is resolved in +** the usual way - using sqlite3ResolveExprNames(). +** +** This routine returns the number of errors. If errors occur, then +** an appropriate error message might be left in pParse. (OOM errors +** excepted.) +*/ +static int resolveOrderGroupBy( + NameContext *pNC, /* The name context of the SELECT statement */ + Select *pSelect, /* The SELECT statement holding pOrderBy */ + ExprList *pOrderBy, /* An ORDER BY or GROUP BY clause to resolve */ + const char *zType /* Either "ORDER" or "GROUP", as appropriate */ +){ + int i, j; /* Loop counters */ + int iCol; /* Column number */ + struct ExprList_item *pItem; /* A term of the ORDER BY clause */ + Parse *pParse; /* Parsing context */ + int nResult; /* Number of terms in the result set */ + + assert( pOrderBy!=0 ); + nResult = pSelect->pEList->nExpr; + pParse = pNC->pParse; + for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ + Expr *pE = pItem->pExpr; + Expr *pE2 = sqlite3ExprSkipCollateAndLikely(pE); + if( NEVER(pE2==0) ) continue; + if( zType[0]!='G' ){ + iCol = resolveAsName(pParse, pSelect->pEList, pE2); + if( iCol>0 ){ + /* If an AS-name match is found, mark this ORDER BY column as being + ** a copy of the iCol-th result-set column. The subsequent call to + ** sqlite3ResolveOrderGroupBy() will convert the expression to a + ** copy of the iCol-th result-set expression. */ + pItem->u.x.iOrderByCol = (u16)iCol; + continue; + } + } + if( sqlite3ExprIsInteger(pE2, &iCol, 0) ){ + /* The ORDER BY term is an integer constant. Again, set the column + ** number so that sqlite3ResolveOrderGroupBy() will convert the + ** order-by term to a copy of the result-set expression */ + if( iCol<1 || iCol>0xffff ){ + resolveOutOfRangeError(pParse, zType, i+1, nResult, pE2); + return 1; + } + pItem->u.x.iOrderByCol = (u16)iCol; + continue; + } + + /* Otherwise, treat the ORDER BY term as an ordinary expression */ + pItem->u.x.iOrderByCol = 0; + if( sqlite3ResolveExprNames(pNC, pE) ){ + return 1; + } + for(j=0; jpEList->nExpr; j++){ + if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){ + /* Since this expression is being changed into a reference + ** to an identical expression in the result set, remove all Window + ** objects belonging to the expression from the Select.pWin list. */ + windowRemoveExprFromSelect(pSelect, pE); + pItem->u.x.iOrderByCol = j+1; + } + } + } + return sqlite3ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType); +} + +/* +** Resolve names in the SELECT statement p and all of its descendants. +*/ +static int resolveSelectStep(Walker *pWalker, Select *p){ + NameContext *pOuterNC; /* Context that contains this SELECT */ + NameContext sNC; /* Name context of this SELECT */ + int isCompound; /* True if p is a compound select */ + int nCompound; /* Number of compound terms processed so far */ + Parse *pParse; /* Parsing context */ + int i; /* Loop counter */ + ExprList *pGroupBy; /* The GROUP BY clause */ + Select *pLeftmost; /* Left-most of SELECT of a compound */ + sqlite3 *db; /* Database connection */ + + + assert( p!=0 ); + if( p->selFlags & SF_Resolved ){ + return WRC_Prune; + } + pOuterNC = pWalker->u.pNC; + pParse = pWalker->pParse; + db = pParse->db; + + /* Normally sqlite3SelectExpand() will be called first and will have + ** already expanded this SELECT. However, if this is a subquery within + ** an expression, sqlite3ResolveExprNames() will be called without a + ** prior call to sqlite3SelectExpand(). When that happens, let + ** sqlite3SelectPrep() do all of the processing for this SELECT. + ** sqlite3SelectPrep() will invoke both sqlite3SelectExpand() and + ** this routine in the correct order. + */ + if( (p->selFlags & SF_Expanded)==0 ){ + sqlite3SelectPrep(pParse, p, pOuterNC); + return pParse->nErr ? WRC_Abort : WRC_Prune; + } + + isCompound = p->pPrior!=0; + nCompound = 0; + pLeftmost = p; + while( p ){ + assert( (p->selFlags & SF_Expanded)!=0 ); + assert( (p->selFlags & SF_Resolved)==0 ); + p->selFlags |= SF_Resolved; + + /* Resolve the expressions in the LIMIT and OFFSET clauses. These + ** are not allowed to refer to any names, so pass an empty NameContext. + */ + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + sNC.pWinSelect = p; + if( sqlite3ResolveExprNames(&sNC, p->pLimit) ){ + return WRC_Abort; + } + + /* If the SF_Converted flags is set, then this Select object was + ** was created by the convertCompoundSelectToSubquery() function. + ** In this case the ORDER BY clause (p->pOrderBy) should be resolved + ** as if it were part of the sub-query, not the parent. This block + ** moves the pOrderBy down to the sub-query. It will be moved back + ** after the names have been resolved. */ + if( p->selFlags & SF_Converted ){ + Select *pSub; + assert( p->pSrc->a[0].fg.isSubquery ); + assert( p->pSrc->a[0].u4.pSubq!=0 ); + pSub = p->pSrc->a[0].u4.pSubq->pSelect; + assert( pSub!=0 ); + assert( p->pSrc->nSrc==1 && p->pOrderBy ); + assert( pSub->pPrior && pSub->pOrderBy==0 ); + pSub->pOrderBy = p->pOrderBy; + p->pOrderBy = 0; + } + + /* Recursively resolve names in all subqueries in the FROM clause + */ + if( pOuterNC ) pOuterNC->nNestedSelect++; + for(i=0; ipSrc->nSrc; i++){ + SrcItem *pItem = &p->pSrc->a[i]; + assert( pItem->zName!=0 + || pItem->fg.isSubquery ); /* Test of tag-20240424-1*/ + if( pItem->fg.isSubquery + && (pItem->u4.pSubq->pSelect->selFlags & SF_Resolved)==0 + ){ + int nRef = pOuterNC ? pOuterNC->nRef : 0; + const char *zSavedContext = pParse->zAuthContext; + + if( pItem->zName ) pParse->zAuthContext = pItem->zName; + sqlite3ResolveSelectNames(pParse, pItem->u4.pSubq->pSelect, pOuterNC); + pParse->zAuthContext = zSavedContext; + if( pParse->nErr ) return WRC_Abort; + assert( db->mallocFailed==0 ); + + /* If the number of references to the outer context changed when + ** expressions in the sub-select were resolved, the sub-select + ** is correlated. It is not required to check the refcount on any + ** but the innermost outer context object, as lookupName() increments + ** the refcount on all contexts between the current one and the + ** context containing the column when it resolves a name. */ + if( pOuterNC ){ + assert( pItem->fg.isCorrelated==0 && pOuterNC->nRef>=nRef ); + pItem->fg.isCorrelated = (pOuterNC->nRef>nRef); + } + } + } + if( pOuterNC && ALWAYS(pOuterNC->nNestedSelect>0) ){ + pOuterNC->nNestedSelect--; + } + + /* Set up the local name-context to pass to sqlite3ResolveExprNames() to + ** resolve the result-set expression list. + */ + sNC.ncFlags = NC_AllowAgg|NC_AllowWin; + sNC.pSrcList = p->pSrc; + sNC.pNext = pOuterNC; + + /* Resolve names in the result set. */ + if( sqlite3ResolveExprListNames(&sNC, p->pEList) ) return WRC_Abort; + sNC.ncFlags &= ~NC_AllowWin; + + /* If there are no aggregate functions in the result-set, and no GROUP BY + ** expression, do not allow aggregates in any of the other expressions. + */ + assert( (p->selFlags & SF_Aggregate)==0 ); + pGroupBy = p->pGroupBy; + if( pGroupBy || (sNC.ncFlags & NC_HasAgg)!=0 ){ + assert( NC_MinMaxAgg==SF_MinMaxAgg ); + assert( NC_OrderAgg==SF_OrderByReqd ); + p->selFlags |= SF_Aggregate | (sNC.ncFlags&(NC_MinMaxAgg|NC_OrderAgg)); + }else{ + sNC.ncFlags &= ~NC_AllowAgg; + } + + /* Add the output column list to the name-context before parsing the + ** other expressions in the SELECT statement. This is so that + ** expressions in the WHERE clause (etc.) can refer to expressions by + ** aliases in the result set. + ** + ** Minor point: If this is the case, then the expression will be + ** re-evaluated for each reference to it. + */ + assert( (sNC.ncFlags & (NC_UAggInfo|NC_UUpsert|NC_UBaseReg))==0 ); + sNC.uNC.pEList = p->pEList; + sNC.ncFlags |= NC_UEList; + if( p->pHaving ){ + if( (p->selFlags & SF_Aggregate)==0 ){ + sqlite3ErrorMsg(pParse, "HAVING clause on a non-aggregate query"); + return WRC_Abort; + } + if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; + } + sNC.ncFlags |= NC_Where; + if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort; + sNC.ncFlags &= ~NC_Where; + + /* Resolve names in table-valued-function arguments */ + for(i=0; ipSrc->nSrc; i++){ + SrcItem *pItem = &p->pSrc->a[i]; + if( pItem->fg.isTabFunc + && sqlite3ResolveExprListNames(&sNC, pItem->u1.pFuncArg) + ){ + return WRC_Abort; + } + } + +#ifndef SQLITE_OMIT_WINDOWFUNC + if( IN_RENAME_OBJECT ){ + Window *pWin; + for(pWin=p->pWinDefn; pWin; pWin=pWin->pNextWin){ + if( sqlite3ResolveExprListNames(&sNC, pWin->pOrderBy) + || sqlite3ResolveExprListNames(&sNC, pWin->pPartition) + ){ + return WRC_Abort; + } + } + } +#endif + + sNC.ncFlags |= NC_AllowAgg|NC_AllowWin; + + /* If this is a converted compound query, move the ORDER BY clause from + ** the sub-query back to the parent query. At this point each term + ** within the ORDER BY clause has been transformed to an integer value. + ** These integers will be replaced by copies of the corresponding result + ** set expressions by the call to resolveOrderGroupBy() below. */ + if( p->selFlags & SF_Converted ){ + Select *pSub; + assert( p->pSrc->a[0].fg.isSubquery ); + pSub = p->pSrc->a[0].u4.pSubq->pSelect; + assert( pSub!=0 ); + p->pOrderBy = pSub->pOrderBy; + pSub->pOrderBy = 0; + } + + /* Process the ORDER BY clause for singleton SELECT statements. + ** The ORDER BY clause for compounds SELECT statements is handled + ** below, after all of the result-sets for all of the elements of + ** the compound have been resolved. + ** + ** If there is an ORDER BY clause on a term of a compound-select other + ** than the right-most term, then that is a syntax error. But the error + ** is not detected until much later, and so we need to go ahead and + ** resolve those symbols on the incorrect ORDER BY for consistency. + */ + if( p->pOrderBy!=0 + && isCompound<=nCompound /* Defer right-most ORDER BY of a compound */ + && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER") + ){ + return WRC_Abort; + } + if( db->mallocFailed ){ + return WRC_Abort; + } + sNC.ncFlags &= ~NC_AllowWin; + + /* Resolve the GROUP BY clause. At the same time, make sure + ** the GROUP BY clause does not contain aggregate functions. + */ + if( pGroupBy ){ + struct ExprList_item *pItem; + + if( resolveOrderGroupBy(&sNC, p, pGroupBy, "GROUP") || db->mallocFailed ){ + return WRC_Abort; + } + for(i=0, pItem=pGroupBy->a; inExpr; i++, pItem++){ + if( ExprHasProperty(pItem->pExpr, EP_Agg) ){ + sqlite3ErrorMsg(pParse, "aggregate functions are not allowed in " + "the GROUP BY clause"); + return WRC_Abort; + } + } + } + + /* If this is part of a compound SELECT, check that it has the right + ** number of expressions in the select list. */ + if( p->pNext && p->pEList->nExpr!=p->pNext->pEList->nExpr ){ + sqlite3SelectWrongNumTermsError(pParse, p->pNext); + return WRC_Abort; + } + + /* If the SELECT statement contains ON clauses that were moved into + ** the WHERE clause, go through and verify that none of the terms + ** in the ON clauses reference tables to the right of the ON clause. */ + if( (p->selFlags & SF_OnToWhere) ){ + sqlite3SelectCheckOnClauses(pParse, p); + if( pParse->nErr ) return WRC_Abort; + } + + /* Advance to the next term of the compound + */ + p = p->pPrior; + nCompound++; + } + + /* Resolve the ORDER BY on a compound SELECT after all terms of + ** the compound have been resolved. + */ + if( isCompound && resolveCompoundOrderBy(pParse, pLeftmost) ){ + return WRC_Abort; + } + + return WRC_Prune; +} + +/* +** This routine walks an expression tree and resolves references to +** table columns and result-set columns. At the same time, do error +** checking on function usage and set a flag if any aggregate functions +** are seen. +** +** To resolve table columns references we look for nodes (or subtrees) of the +** form X.Y.Z or Y.Z or just Z where +** +** X: The name of a database. Ex: "main" or "temp" or +** the symbolic name assigned to an ATTACH-ed database. +** +** Y: The name of a table in a FROM clause. Or in a trigger +** one of the special names "old" or "new". +** +** Z: The name of a column in table Y. +** +** The node at the root of the subtree is modified as follows: +** +** Expr.op Changed to TK_COLUMN +** Expr.pTab Points to the Table object for X.Y +** Expr.iColumn The column index in X.Y. -1 for the rowid. +** Expr.iTable The VDBE cursor number for X.Y +** +** +** To resolve result-set references, look for expression nodes of the +** form Z (with no X and Y prefix) where the Z matches the right-hand +** size of an AS clause in the result-set of a SELECT. The Z expression +** is replaced by a copy of the left-hand side of the result-set expression. +** Table-name and function resolution occurs on the substituted expression +** tree. For example, in: +** +** SELECT a+b AS x, c+d AS y FROM t1 ORDER BY x; +** +** The "x" term of the order by is replaced by "a+b" to render: +** +** SELECT a+b AS x, c+d AS y FROM t1 ORDER BY a+b; +** +** Function calls are checked to make sure that the function is +** defined and that the correct number of arguments are specified. +** If the function is an aggregate function, then the NC_HasAgg flag is +** set and the opcode is changed from TK_FUNCTION to TK_AGG_FUNCTION. +** If an expression contains aggregate functions then the EP_Agg +** property on the expression is set. +** +** An error message is left in pParse if anything is amiss. The number +** if errors is returned. +*/ +SQLITE_PRIVATE int sqlite3ResolveExprNames( + NameContext *pNC, /* Namespace to resolve expressions in. */ + Expr *pExpr /* The expression to be analyzed. */ +){ + int savedHasAgg; + Walker w; + + if( pExpr==0 ) return SQLITE_OK; + savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); + pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); + w.pParse = pNC->pParse; + w.xExprCallback = resolveExprStep; + w.xSelectCallback = (pNC->ncFlags & NC_NoSelect) ? 0 : resolveSelectStep; + w.xSelectCallback2 = 0; + w.u.pNC = pNC; +#if SQLITE_MAX_EXPR_DEPTH>0 + w.pParse->nHeight += pExpr->nHeight; + if( sqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){ + return SQLITE_ERROR; + } +#endif + assert( pExpr!=0 ); + sqlite3WalkExprNN(&w, pExpr); +#if SQLITE_MAX_EXPR_DEPTH>0 + w.pParse->nHeight -= pExpr->nHeight; +#endif + assert( EP_Agg==NC_HasAgg ); + assert( EP_Win==NC_HasWin ); + testcase( pNC->ncFlags & NC_HasAgg ); + testcase( pNC->ncFlags & NC_HasWin ); + ExprSetProperty(pExpr, pNC->ncFlags & (NC_HasAgg|NC_HasWin) ); + pNC->ncFlags |= savedHasAgg; + return pNC->nNcErr>0 || w.pParse->nErr>0; +} + +/* +** Resolve all names for all expression in an expression list. This is +** just like sqlite3ResolveExprNames() except that it works for an expression +** list rather than a single expression. +** +** The return value is SQLITE_OK (0) for success or SQLITE_ERROR (1) for a +** failure. +*/ +SQLITE_PRIVATE int sqlite3ResolveExprListNames( + NameContext *pNC, /* Namespace to resolve expressions in. */ + ExprList *pList /* The expression list to be analyzed. */ +){ + int i; + int savedHasAgg = 0; + Walker w; + if( pList==0 ) return SQLITE_OK; + w.pParse = pNC->pParse; + w.xExprCallback = resolveExprStep; + w.xSelectCallback = resolveSelectStep; + w.xSelectCallback2 = 0; + w.u.pNC = pNC; + savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); + pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); + for(i=0; inExpr; i++){ + Expr *pExpr = pList->a[i].pExpr; + if( pExpr==0 ) continue; +#if SQLITE_MAX_EXPR_DEPTH>0 + w.pParse->nHeight += pExpr->nHeight; + if( sqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){ + return SQLITE_ERROR; + } +#endif + sqlite3WalkExprNN(&w, pExpr); +#if SQLITE_MAX_EXPR_DEPTH>0 + w.pParse->nHeight -= pExpr->nHeight; +#endif + assert( EP_Agg==NC_HasAgg ); + assert( EP_Win==NC_HasWin ); + testcase( pNC->ncFlags & NC_HasAgg ); + testcase( pNC->ncFlags & NC_HasWin ); + if( pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg) ){ + ExprSetProperty(pExpr, pNC->ncFlags & (NC_HasAgg|NC_HasWin) ); + savedHasAgg |= pNC->ncFlags & + (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); + pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); + } + if( w.pParse->nErr>0 ) return SQLITE_ERROR; + } + pNC->ncFlags |= savedHasAgg; + return SQLITE_OK; +} + +/* +** Resolve all names in all expressions of a SELECT and in all +** descendants of the SELECT, including compounds off of p->pPrior, +** subqueries in expressions, and subqueries used as FROM clause +** terms. +** +** See sqlite3ResolveExprNames() for a description of the kinds of +** transformations that occur. +** +** All SELECT statements should have been expanded using +** sqlite3SelectExpand() prior to invoking this routine. +*/ +SQLITE_PRIVATE void sqlite3ResolveSelectNames( + Parse *pParse, /* The parser context */ + Select *p, /* The SELECT statement being coded. */ + NameContext *pOuterNC /* Name context for parent SELECT statement */ +){ + Walker w; + + assert( p!=0 ); + w.xExprCallback = resolveExprStep; + w.xSelectCallback = resolveSelectStep; + w.xSelectCallback2 = 0; + w.pParse = pParse; + w.u.pNC = pOuterNC; + sqlite3WalkSelect(&w, p); +} + +/* +** Resolve names in expressions that can only reference a single table +** or which cannot reference any tables at all. Examples: +** +** "type" flag +** ------------ +** (1) CHECK constraints NC_IsCheck +** (2) WHERE clauses on partial indices NC_PartIdx +** (3) Expressions in indexes on expressions NC_IdxExpr +** (4) Expression arguments to VACUUM INTO. 0 +** (5) GENERATED ALWAYS as expressions NC_GenCol +** +** In all cases except (4), the Expr.iTable value for Expr.op==TK_COLUMN +** nodes of the expression is set to -1 and the Expr.iColumn value is +** set to the column number. In case (4), TK_COLUMN nodes cause an error. +** +** Any errors cause an error message to be set in pParse. +*/ +SQLITE_PRIVATE int sqlite3ResolveSelfReference( + Parse *pParse, /* Parsing context */ + Table *pTab, /* The table being referenced, or NULL */ + int type, /* NC_IsCheck, NC_PartIdx, NC_IdxExpr, NC_GenCol, or 0 */ + Expr *pExpr, /* Expression to resolve. May be NULL. */ + ExprList *pList /* Expression list to resolve. May be NULL. */ +){ + SrcList *pSrc; /* Fake SrcList for pParse->pNewTable */ + NameContext sNC; /* Name context for pParse->pNewTable */ + int rc; + union { + SrcList sSrc; + u8 srcSpace[SZ_SRCLIST_1]; /* Memory space for the fake SrcList */ + } uSrc; + + assert( type==0 || pTab!=0 ); + assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr + || type==NC_GenCol || pTab==0 ); + memset(&sNC, 0, sizeof(sNC)); + memset(&uSrc, 0, sizeof(uSrc)); + pSrc = &uSrc.sSrc; + if( pTab ){ + pSrc->nSrc = 1; + pSrc->a[0].zName = pTab->zName; + pSrc->a[0].pSTab = pTab; + pSrc->a[0].iCursor = -1; + if( pTab->pSchema!=pParse->db->aDb[1].pSchema ){ + /* Cause EP_FromDDL to be set on TK_FUNCTION nodes of non-TEMP + ** schema elements */ + type |= NC_FromDDL; + } + } + sNC.pParse = pParse; + sNC.pSrcList = pSrc; + sNC.ncFlags = type | NC_IsDDL; + if( (rc = sqlite3ResolveExprNames(&sNC, pExpr))!=SQLITE_OK ) return rc; + if( pList ) rc = sqlite3ResolveExprListNames(&sNC, pList); + return rc; +} + +/************** End of resolve.c *********************************************/ +/************** Begin file expr.c ********************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains routines used for analyzing expressions and +** for generating VDBE code that evaluates expressions in SQLite. +*/ +/* #include "sqliteInt.h" */ + +/* Forward declarations */ +static void exprCodeBetween(Parse*,Expr*,int,void(*)(Parse*,Expr*,int,int),int); +static int exprCodeVector(Parse *pParse, Expr *p, int *piToFree); + +/* +** Return the affinity character for a single column of a table. +*/ +SQLITE_PRIVATE char sqlite3TableColumnAffinity(const Table *pTab, int iCol){ + if( iCol<0 || NEVER(iCol>=pTab->nCol) ) return SQLITE_AFF_INTEGER; + return pTab->aCol[iCol].affinity; +} + +/* +** Return the 'affinity' of the expression pExpr if any. +** +** If pExpr is a column, a reference to a column via an 'AS' alias, +** or a sub-select with a column as the return value, then the +** affinity of that column is returned. Otherwise, 0x00 is returned, +** indicating no affinity for the expression. +** +** i.e. the WHERE clause expressions in the following statements all +** have an affinity: +** +** CREATE TABLE t1(a); +** SELECT * FROM t1 WHERE a; +** SELECT a AS b FROM t1 WHERE b; +** SELECT * FROM t1 WHERE (select a from t1); +*/ +SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){ + int op; + op = pExpr->op; + while( 1 /* exit-by-break */ ){ + if( op==TK_COLUMN || (op==TK_AGG_COLUMN && pExpr->y.pTab!=0) ){ + assert( ExprUseYTab(pExpr) ); + assert( pExpr->y.pTab!=0 ); + return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); + } + if( op==TK_SELECT ){ + assert( ExprUseXSelect(pExpr) ); + assert( pExpr->x.pSelect!=0 ); + assert( pExpr->x.pSelect->pEList!=0 ); + assert( pExpr->x.pSelect->pEList->a[0].pExpr!=0 ); + return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr); + } +#ifndef SQLITE_OMIT_CAST + if( op==TK_CAST ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + return sqlite3AffinityType(pExpr->u.zToken, 0); + } +#endif + if( op==TK_SELECT_COLUMN ){ + assert( pExpr->pLeft!=0 && ExprUseXSelect(pExpr->pLeft) ); + assert( pExpr->iColumn < pExpr->iTable ); + assert( pExpr->iColumn >= 0 ); + assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr ); + return sqlite3ExprAffinity( + pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr + ); + } + if( op==TK_VECTOR + || (op==TK_FUNCTION && pExpr->affExpr==SQLITE_AFF_DEFER) + ){ + assert( ExprUseXList(pExpr) ); + return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr); + } + if( ExprHasProperty(pExpr, EP_Skip|EP_IfNullRow) ){ + assert( pExpr->op==TK_COLLATE + || pExpr->op==TK_IF_NULL_ROW + || (pExpr->op==TK_REGISTER && pExpr->op2==TK_IF_NULL_ROW) ); + pExpr = pExpr->pLeft; + op = pExpr->op; + continue; + } + if( op!=TK_REGISTER ) break; + op = pExpr->op2; + if( NEVER( op==TK_REGISTER ) ) break; + } + return pExpr->affExpr; +} + +/* +** Make a guess at all the possible datatypes of the result that could +** be returned by an expression. Return a bitmask indicating the answer: +** +** 0x01 Numeric +** 0x02 Text +** 0x04 Blob +** +** If the expression must return NULL, then 0x00 is returned. +*/ +SQLITE_PRIVATE int sqlite3ExprDataType(const Expr *pExpr){ + while( pExpr ){ + switch( pExpr->op ){ + case TK_COLLATE: + case TK_IF_NULL_ROW: + case TK_UPLUS: { + pExpr = pExpr->pLeft; + break; + } + case TK_NULL: { + pExpr = 0; + break; + } + case TK_STRING: { + return 0x02; + } + case TK_BLOB: { + return 0x04; + } + case TK_CONCAT: { + return 0x06; + } + case TK_VARIABLE: + case TK_AGG_FUNCTION: + case TK_FUNCTION: { + return 0x07; + } + case TK_COLUMN: + case TK_AGG_COLUMN: + case TK_SELECT: + case TK_CAST: + case TK_SELECT_COLUMN: + case TK_VECTOR: { + int aff = sqlite3ExprAffinity(pExpr); + if( aff>=SQLITE_AFF_NUMERIC ) return 0x05; + if( aff==SQLITE_AFF_TEXT ) return 0x06; + return 0x07; + } + case TK_CASE: { + int res = 0; + int ii; + ExprList *pList = pExpr->x.pList; + assert( ExprUseXList(pExpr) && pList!=0 ); + assert( pList->nExpr > 0); + for(ii=1; iinExpr; ii+=2){ + res |= sqlite3ExprDataType(pList->a[ii].pExpr); + } + if( pList->nExpr % 2 ){ + res |= sqlite3ExprDataType(pList->a[pList->nExpr-1].pExpr); + } + return res; + } + default: { + return 0x01; + } + } /* End of switch(op) */ + } /* End of while(pExpr) */ + return 0x00; +} + +/* +** Set the collating sequence for expression pExpr to be the collating +** sequence named by pToken. Return a pointer to a new Expr node that +** implements the COLLATE operator. +** +** If a memory allocation error occurs, that fact is recorded in pParse->db +** and the pExpr parameter is returned unchanged. +*/ +SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken( + const Parse *pParse, /* Parsing context */ + Expr *pExpr, /* Add the "COLLATE" clause to this expression */ + const Token *pCollName, /* Name of collating sequence */ + int dequote /* True to dequote pCollName */ +){ + if( pCollName->n>0 ){ + Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote); + if( pNew ){ + pNew->pLeft = pExpr; + pNew->flags |= EP_Collate|EP_Skip; + pExpr = pNew; + } + } + return pExpr; +} +SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString( + const Parse *pParse, /* Parsing context */ + Expr *pExpr, /* Add the "COLLATE" clause to this expression */ + const char *zC /* The collating sequence name */ +){ + Token s; + assert( zC!=0 ); + sqlite3TokenInit(&s, (char*)zC); + return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0); +} + +/* +** Skip over any TK_COLLATE operators. +*/ +SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){ + while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){ + assert( pExpr->op==TK_COLLATE ); + pExpr = pExpr->pLeft; + } + return pExpr; +} + +/* +** Skip over any TK_COLLATE operators and/or any unlikely() +** or likelihood() or likely() functions at the root of an +** expression. +*/ +SQLITE_PRIVATE Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){ + while( pExpr && ExprHasProperty(pExpr, EP_Skip|EP_Unlikely) ){ + if( ExprHasProperty(pExpr, EP_Unlikely) ){ + assert( ExprUseXList(pExpr) ); + assert( pExpr->x.pList->nExpr>0 ); + assert( pExpr->op==TK_FUNCTION ); + pExpr = pExpr->x.pList->a[0].pExpr; + }else if( pExpr->op==TK_COLLATE ){ + pExpr = pExpr->pLeft; + }else{ + break; + } + } + return pExpr; +} + +/* +** Return the collation sequence for the expression pExpr. If +** there is no defined collating sequence, return NULL. +** +** See also: sqlite3ExprNNCollSeq() +** +** The sqlite3ExprNNCollSeq() works the same exact that it returns the +** default collation if pExpr has no defined collation. +** +** The collating sequence might be determined by a COLLATE operator +** or by the presence of a column with a defined collating sequence. +** COLLATE operators take first precedence. Left operands take +** precedence over right operands. +*/ +SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr){ + sqlite3 *db = pParse->db; + CollSeq *pColl = 0; + const Expr *p = pExpr; + while( p ){ + int op = p->op; + if( op==TK_REGISTER ) op = p->op2; + if( (op==TK_AGG_COLUMN && p->y.pTab!=0) + || op==TK_COLUMN || op==TK_TRIGGER + ){ + int j; + assert( ExprUseYTab(p) ); + assert( p->y.pTab!=0 ); + if( (j = p->iColumn)>=0 ){ + const char *zColl = sqlite3ColumnColl(&p->y.pTab->aCol[j]); + pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0); + } + break; + } + if( op==TK_CAST || op==TK_UPLUS ){ + p = p->pLeft; + continue; + } + if( op==TK_VECTOR + || (op==TK_FUNCTION && p->affExpr==SQLITE_AFF_DEFER) + ){ + assert( ExprUseXList(p) ); + p = p->x.pList->a[0].pExpr; + continue; + } + if( op==TK_COLLATE ){ + assert( !ExprHasProperty(p, EP_IntValue) ); + pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken); + break; + } + if( p->flags & EP_Collate ){ + if( p->pLeft && (p->pLeft->flags & EP_Collate)!=0 ){ + p = p->pLeft; + }else{ + Expr *pNext = p->pRight; + /* The Expr.x union is never used at the same time as Expr.pRight */ + assert( !ExprUseXList(p) || p->x.pList==0 || p->pRight==0 ); + if( ExprUseXList(p) && p->x.pList!=0 && !db->mallocFailed ){ + int i; + for(i=0; ix.pList->nExpr; i++){ + if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){ + pNext = p->x.pList->a[i].pExpr; + break; + } + } + } + p = pNext; + } + }else{ + break; + } + } + if( sqlite3CheckCollSeq(pParse, pColl) ){ + pColl = 0; + } + return pColl; +} + +/* +** Return the collation sequence for the expression pExpr. If +** there is no defined collating sequence, return a pointer to the +** default collation sequence. +** +** See also: sqlite3ExprCollSeq() +** +** The sqlite3ExprCollSeq() routine works the same except that it +** returns NULL if there is no defined collation. +*/ +SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, const Expr *pExpr){ + CollSeq *p = sqlite3ExprCollSeq(pParse, pExpr); + if( p==0 ) p = pParse->db->pDfltColl; + assert( p!=0 ); + return p; +} + +/* +** Return TRUE if the two expressions have equivalent collating sequences. +*/ +SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse *pParse, const Expr *pE1, const Expr *pE2){ + CollSeq *pColl1 = sqlite3ExprNNCollSeq(pParse, pE1); + CollSeq *pColl2 = sqlite3ExprNNCollSeq(pParse, pE2); + return sqlite3StrICmp(pColl1->zName, pColl2->zName)==0; +} + +/* +** pExpr is an operand of a comparison operator. aff2 is the +** type affinity of the other operand. This routine returns the +** type affinity that should be used for the comparison operator. +*/ +SQLITE_PRIVATE char sqlite3CompareAffinity(const Expr *pExpr, char aff2){ + char aff1 = sqlite3ExprAffinity(pExpr); + if( aff1>SQLITE_AFF_NONE && aff2>SQLITE_AFF_NONE ){ + /* Both sides of the comparison are columns. If one has numeric + ** affinity, use that. Otherwise use no affinity. + */ + if( sqlite3IsNumericAffinity(aff1) || sqlite3IsNumericAffinity(aff2) ){ + return SQLITE_AFF_NUMERIC; + }else{ + return SQLITE_AFF_BLOB; + } + }else{ + /* One side is a column, the other is not. Use the columns affinity. */ + assert( aff1<=SQLITE_AFF_NONE || aff2<=SQLITE_AFF_NONE ); + return (aff1<=SQLITE_AFF_NONE ? aff2 : aff1) | SQLITE_AFF_NONE; + } +} + +/* +** pExpr is a comparison operator. Return the type affinity that should +** be applied to both operands prior to doing the comparison. +*/ +static char comparisonAffinity(const Expr *pExpr){ + char aff; + assert( pExpr->op==TK_EQ || pExpr->op==TK_IN || pExpr->op==TK_LT || + pExpr->op==TK_GT || pExpr->op==TK_GE || pExpr->op==TK_LE || + pExpr->op==TK_NE || pExpr->op==TK_IS || pExpr->op==TK_ISNOT ); + assert( pExpr->pLeft ); + aff = sqlite3ExprAffinity(pExpr->pLeft); + if( pExpr->pRight ){ + aff = sqlite3CompareAffinity(pExpr->pRight, aff); + }else if( ExprUseXSelect(pExpr) ){ + aff = sqlite3CompareAffinity(pExpr->x.pSelect->pEList->a[0].pExpr, aff); + }else if( aff==0 ){ + aff = SQLITE_AFF_BLOB; + } + return aff; +} + +/* +** pExpr is a comparison expression, eg. '=', '<', IN(...) etc. +** idx_affinity is the affinity of an indexed column. Return true +** if the index with affinity idx_affinity may be used to implement +** the comparison in pExpr. +*/ +SQLITE_PRIVATE int sqlite3IndexAffinityOk(const Expr *pExpr, char idx_affinity){ + char aff = comparisonAffinity(pExpr); + if( affflags & EP_Collate ){ + pColl = sqlite3ExprCollSeq(pParse, pLeft); + }else if( pRight && (pRight->flags & EP_Collate)!=0 ){ + pColl = sqlite3ExprCollSeq(pParse, pRight); + }else{ + pColl = sqlite3ExprCollSeq(pParse, pLeft); + if( !pColl ){ + pColl = sqlite3ExprCollSeq(pParse, pRight); + } + } + return pColl; +} + +/* Expression p is a comparison operator. Return a collation sequence +** appropriate for the comparison operator. +** +** This is normally just a wrapper around sqlite3BinaryCompareCollSeq(). +** However, if the OP_Commuted flag is set, then the order of the operands +** is reversed in the sqlite3BinaryCompareCollSeq() call so that the +** correct collating sequence is found. +*/ +SQLITE_PRIVATE CollSeq *sqlite3ExprCompareCollSeq(Parse *pParse, const Expr *p){ + if( ExprHasProperty(p, EP_Commuted) ){ + return sqlite3BinaryCompareCollSeq(pParse, p->pRight, p->pLeft); + }else{ + return sqlite3BinaryCompareCollSeq(pParse, p->pLeft, p->pRight); + } +} + +/* +** Generate code for a comparison operator. +*/ +static int codeCompare( + Parse *pParse, /* The parsing (and code generating) context */ + Expr *pLeft, /* The left operand */ + Expr *pRight, /* The right operand */ + int opcode, /* The comparison opcode */ + int in1, int in2, /* Register holding operands */ + int dest, /* Jump here if true. */ + int jumpIfNull, /* If true, jump if either operand is NULL */ + int isCommuted /* The comparison has been commuted */ +){ + int p5; + int addr; + CollSeq *p4; + + if( pParse->nErr ) return 0; + if( isCommuted ){ + p4 = sqlite3BinaryCompareCollSeq(pParse, pRight, pLeft); + }else{ + p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight); + } + p5 = binaryCompareP5(pLeft, pRight, jumpIfNull); + addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1, + (void*)p4, P4_COLLSEQ); + sqlite3VdbeChangeP5(pParse->pVdbe, (u16)p5); + return addr; +} + +/* +** Return true if expression pExpr is a vector, or false otherwise. +** +** A vector is defined as any expression that results in two or more +** columns of result. Every TK_VECTOR node is an vector because the +** parser will not generate a TK_VECTOR with fewer than two entries. +** But a TK_SELECT might be either a vector or a scalar. It is only +** considered a vector if it has two or more result columns. +*/ +SQLITE_PRIVATE int sqlite3ExprIsVector(const Expr *pExpr){ + return sqlite3ExprVectorSize(pExpr)>1; +} + +/* +** If the expression passed as the only argument is of type TK_VECTOR +** return the number of expressions in the vector. Or, if the expression +** is a sub-select, return the number of columns in the sub-select. For +** any other type of expression, return 1. +*/ +SQLITE_PRIVATE int sqlite3ExprVectorSize(const Expr *pExpr){ + u8 op = pExpr->op; + if( op==TK_REGISTER ) op = pExpr->op2; + if( op==TK_VECTOR ){ + assert( ExprUseXList(pExpr) ); + return pExpr->x.pList->nExpr; + }else if( op==TK_SELECT ){ + assert( ExprUseXSelect(pExpr) ); + return pExpr->x.pSelect->pEList->nExpr; + }else{ + return 1; + } +} + +/* +** Return a pointer to a subexpression of pVector that is the i-th +** column of the vector (numbered starting with 0). The caller must +** ensure that i is within range. +** +** If pVector is really a scalar (and "scalar" here includes subqueries +** that return a single column!) then return pVector unmodified. +** +** pVector retains ownership of the returned subexpression. +** +** If the vector is a (SELECT ...) then the expression returned is +** just the expression for the i-th term of the result set, and may +** not be ready for evaluation because the table cursor has not yet +** been positioned. +*/ +SQLITE_PRIVATE Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){ + assert( iop==TK_ERROR ); + if( sqlite3ExprIsVector(pVector) ){ + assert( pVector->op2==0 || pVector->op==TK_REGISTER ); + if( pVector->op==TK_SELECT || pVector->op2==TK_SELECT ){ + assert( ExprUseXSelect(pVector) ); + return pVector->x.pSelect->pEList->a[i].pExpr; + }else{ + assert( ExprUseXList(pVector) ); + return pVector->x.pList->a[i].pExpr; + } + } + return pVector; +} + +/* +** Compute and return a new Expr object which when passed to +** sqlite3ExprCode() will generate all necessary code to compute +** the iField-th column of the vector expression pVector. +** +** It is ok for pVector to be a scalar (as long as iField==0). +** In that case, this routine works like sqlite3ExprDup(). +** +** The caller owns the returned Expr object and is responsible for +** ensuring that the returned value eventually gets freed. +** +** The caller retains ownership of pVector. If pVector is a TK_SELECT, +** then the returned object will reference pVector and so pVector must remain +** valid for the life of the returned object. If pVector is a TK_VECTOR +** or a scalar expression, then it can be deleted as soon as this routine +** returns. +** +** A trick to cause a TK_SELECT pVector to be deleted together with +** the returned Expr object is to attach the pVector to the pRight field +** of the returned TK_SELECT_COLUMN Expr object. +*/ +SQLITE_PRIVATE Expr *sqlite3ExprForVectorField( + Parse *pParse, /* Parsing context */ + Expr *pVector, /* The vector. List of expressions or a sub-SELECT */ + int iField, /* Which column of the vector to return */ + int nField /* Total number of columns in the vector */ +){ + Expr *pRet; + if( pVector->op==TK_SELECT ){ + assert( ExprUseXSelect(pVector) ); + /* The TK_SELECT_COLUMN Expr node: + ** + ** pLeft: pVector containing TK_SELECT. Not deleted. + ** pRight: not used. But recursively deleted. + ** iColumn: Index of a column in pVector + ** iTable: 0 or the number of columns on the LHS of an assignment + ** pLeft->iTable: First in an array of register holding result, or 0 + ** if the result is not yet computed. + ** + ** sqlite3ExprDelete() specifically skips the recursive delete of + ** pLeft on TK_SELECT_COLUMN nodes. But pRight is followed, so pVector + ** can be attached to pRight to cause this node to take ownership of + ** pVector. Typically there will be multiple TK_SELECT_COLUMN nodes + ** with the same pLeft pointer to the pVector, but only one of them + ** will own the pVector. + */ + pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, 0, 0); + if( pRet ){ + ExprSetProperty(pRet, EP_FullSize); + pRet->iTable = nField; + pRet->iColumn = iField; + pRet->pLeft = pVector; + } + }else{ + if( pVector->op==TK_VECTOR ){ + Expr **ppVector; + assert( ExprUseXList(pVector) ); + ppVector = &pVector->x.pList->a[iField].pExpr; + pVector = *ppVector; + if( IN_RENAME_OBJECT ){ + /* This must be a vector UPDATE inside a trigger */ + *ppVector = 0; + return pVector; + } + } + pRet = sqlite3ExprDup(pParse->db, pVector, 0); + } + return pRet; +} + +/* +** If expression pExpr is of type TK_SELECT, generate code to evaluate +** it. Return the register in which the result is stored (or, if the +** sub-select returns more than one column, the first in an array +** of registers in which the result is stored). +** +** If pExpr is not a TK_SELECT expression, return 0. +*/ +static int exprCodeSubselect(Parse *pParse, Expr *pExpr){ + int reg = 0; +#ifndef SQLITE_OMIT_SUBQUERY + if( pExpr->op==TK_SELECT ){ + reg = sqlite3CodeSubselect(pParse, pExpr); + } +#endif + return reg; +} + +/* +** Argument pVector points to a vector expression - either a TK_VECTOR +** or TK_SELECT that returns more than one column. This function returns +** the register number of a register that contains the value of +** element iField of the vector. +** +** If pVector is a TK_SELECT expression, then code for it must have +** already been generated using the exprCodeSubselect() routine. In this +** case parameter regSelect should be the first in an array of registers +** containing the results of the sub-select. +** +** If pVector is of type TK_VECTOR, then code for the requested field +** is generated. In this case (*pRegFree) may be set to the number of +** a temporary register to be freed by the caller before returning. +** +** Before returning, output parameter (*ppExpr) is set to point to the +** Expr object corresponding to element iElem of the vector. +*/ +static int exprVectorRegister( + Parse *pParse, /* Parse context */ + Expr *pVector, /* Vector to extract element from */ + int iField, /* Field to extract from pVector */ + int regSelect, /* First in array of registers */ + Expr **ppExpr, /* OUT: Expression element */ + int *pRegFree /* OUT: Temp register to free */ +){ + u8 op = pVector->op; + assert( op==TK_VECTOR || op==TK_REGISTER || op==TK_SELECT || op==TK_ERROR ); + if( op==TK_REGISTER ){ + *ppExpr = sqlite3VectorFieldSubexpr(pVector, iField); + return pVector->iTable+iField; + } + if( op==TK_SELECT ){ + assert( ExprUseXSelect(pVector) ); + *ppExpr = pVector->x.pSelect->pEList->a[iField].pExpr; + return regSelect+iField; + } + if( op==TK_VECTOR ){ + assert( ExprUseXList(pVector) ); + *ppExpr = pVector->x.pList->a[iField].pExpr; + return sqlite3ExprCodeTemp(pParse, *ppExpr, pRegFree); + } + return 0; +} + +/* +** Expression pExpr is a comparison between two vector values. Compute +** the result of the comparison (1, 0, or NULL) and write that +** result into register dest. +** +** The caller must satisfy the following preconditions: +** +** if pExpr->op==TK_IS: op==TK_EQ and p5==SQLITE_NULLEQ +** if pExpr->op==TK_ISNOT: op==TK_NE and p5==SQLITE_NULLEQ +** otherwise: op==pExpr->op and p5==0 +*/ +static void codeVectorCompare( + Parse *pParse, /* Code generator context */ + Expr *pExpr, /* The comparison operation */ + int dest, /* Write results into this register */ + u8 op, /* Comparison operator */ + u8 p5 /* SQLITE_NULLEQ or zero */ +){ + Vdbe *v = pParse->pVdbe; + Expr *pLeft = pExpr->pLeft; + Expr *pRight = pExpr->pRight; + int nLeft = sqlite3ExprVectorSize(pLeft); + int i; + int regLeft = 0; + int regRight = 0; + u8 opx = op; + int addrCmp = 0; + int addrDone = sqlite3VdbeMakeLabel(pParse); + int isCommuted = ExprHasProperty(pExpr,EP_Commuted); + + assert( !ExprHasVVAProperty(pExpr,EP_Immutable) ); + if( pParse->nErr ) return; + if( nLeft!=sqlite3ExprVectorSize(pRight) ){ + sqlite3ErrorMsg(pParse, "row value misused"); + return; + } + assert( pExpr->op==TK_EQ || pExpr->op==TK_NE + || pExpr->op==TK_IS || pExpr->op==TK_ISNOT + || pExpr->op==TK_LT || pExpr->op==TK_GT + || pExpr->op==TK_LE || pExpr->op==TK_GE + ); + assert( pExpr->op==op || (pExpr->op==TK_IS && op==TK_EQ) + || (pExpr->op==TK_ISNOT && op==TK_NE) ); + assert( p5==0 || pExpr->op!=op ); + assert( p5==SQLITE_NULLEQ || pExpr->op==op ); + + if( op==TK_LE ) opx = TK_LT; + if( op==TK_GE ) opx = TK_GT; + if( op==TK_NE ) opx = TK_EQ; + + regLeft = exprCodeSubselect(pParse, pLeft); + regRight = exprCodeSubselect(pParse, pRight); + + sqlite3VdbeAddOp2(v, OP_Integer, 1, dest); + for(i=0; 1 /*Loop exits by "break"*/; i++){ + int regFree1 = 0, regFree2 = 0; + Expr *pL = 0, *pR = 0; + int r1, r2; + assert( i>=0 && i0 +/* +** Check that argument nHeight is less than or equal to the maximum +** expression depth allowed. If it is not, leave an error message in +** pParse. +*/ +SQLITE_PRIVATE int sqlite3ExprCheckHeight(Parse *pParse, int nHeight){ + int rc = SQLITE_OK; + int mxHeight = pParse->db->aLimit[SQLITE_LIMIT_EXPR_DEPTH]; + if( nHeight>mxHeight ){ + sqlite3ErrorMsg(pParse, + "Expression tree is too large (maximum depth %d)", mxHeight + ); + rc = SQLITE_ERROR; + } + return rc; +} + +/* The following three functions, heightOfExpr(), heightOfExprList() +** and heightOfSelect(), are used to determine the maximum height +** of any expression tree referenced by the structure passed as the +** first argument. +** +** If this maximum height is greater than the current value pointed +** to by pnHeight, the second parameter, then set *pnHeight to that +** value. +*/ +static void heightOfExpr(const Expr *p, int *pnHeight){ + if( p ){ + if( p->nHeight>*pnHeight ){ + *pnHeight = p->nHeight; + } + } +} +static void heightOfExprList(const ExprList *p, int *pnHeight){ + if( p ){ + int i; + for(i=0; inExpr; i++){ + heightOfExpr(p->a[i].pExpr, pnHeight); + } + } +} +static void heightOfSelect(const Select *pSelect, int *pnHeight){ + const Select *p; + for(p=pSelect; p; p=p->pPrior){ + heightOfExpr(p->pWhere, pnHeight); + heightOfExpr(p->pHaving, pnHeight); + heightOfExpr(p->pLimit, pnHeight); + heightOfExprList(p->pEList, pnHeight); + heightOfExprList(p->pGroupBy, pnHeight); + heightOfExprList(p->pOrderBy, pnHeight); + } +} + +/* +** Set the Expr.nHeight variable in the structure passed as an +** argument. An expression with no children, Expr.pList or +** Expr.pSelect member has a height of 1. Any other expression +** has a height equal to the maximum height of any other +** referenced Expr plus one. +** +** Also propagate EP_Propagate flags up from Expr.x.pList to Expr.flags, +** if appropriate. +*/ +static void exprSetHeight(Expr *p){ + int nHeight = p->pLeft ? p->pLeft->nHeight : 0; + if( NEVER(p->pRight) && p->pRight->nHeight>nHeight ){ + nHeight = p->pRight->nHeight; + } + if( ExprUseXSelect(p) ){ + heightOfSelect(p->x.pSelect, &nHeight); + }else if( p->x.pList ){ + heightOfExprList(p->x.pList, &nHeight); + p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList); + } + p->nHeight = nHeight + 1; +} + +/* +** Set the Expr.nHeight variable using the exprSetHeight() function. If +** the height is greater than the maximum allowed expression depth, +** leave an error in pParse. +** +** Also propagate all EP_Propagate flags from the Expr.x.pList into +** Expr.flags. +*/ +SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){ + if( pParse->nErr ) return; + exprSetHeight(p); + sqlite3ExprCheckHeight(pParse, p->nHeight); +} + +/* +** Return the maximum height of any expression tree referenced +** by the select statement passed as an argument. +*/ +SQLITE_PRIVATE int sqlite3SelectExprHeight(const Select *p){ + int nHeight = 0; + heightOfSelect(p, &nHeight); + return nHeight; +} +#else /* ABOVE: Height enforcement enabled. BELOW: Height enforcement off */ +/* +** Propagate all EP_Propagate flags from the Expr.x.pList into +** Expr.flags. +*/ +SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){ + if( pParse->nErr ) return; + if( p && ExprUseXList(p) && p->x.pList ){ + p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList); + } +} +#define exprSetHeight(y) +#endif /* SQLITE_MAX_EXPR_DEPTH>0 */ + +/* +** Set the error offset for an Expr node, if possible. +*/ +SQLITE_PRIVATE void sqlite3ExprSetErrorOffset(Expr *pExpr, int iOfst){ + if( pExpr==0 ) return; + if( NEVER(ExprUseWJoin(pExpr)) ) return; + pExpr->w.iOfst = iOfst; +} + +/* +** This routine is the core allocator for Expr nodes. +** +** Construct a new expression node and return a pointer to it. Memory +** for this node and for the pToken argument is a single allocation +** obtained from sqlite3DbMalloc(). The calling function +** is responsible for making sure the node eventually gets freed. +** +** If dequote is true, then the token (if it exists) is dequoted. +** If dequote is false, no dequoting is performed. The deQuote +** parameter is ignored if pToken is NULL or if the token does not +** appear to be quoted. If the quotes were of the form "..." (double-quotes) +** then the EP_DblQuoted flag is set on the expression node. +** +** Special case (tag-20240227-a): If op==TK_INTEGER and pToken points to +** a string that can be translated into a 32-bit integer, then the token is +** not stored in u.zToken. Instead, the integer values is written +** into u.iValue and the EP_IntValue flag is set. No extra storage +** is allocated to hold the integer text and the dequote flag is ignored. +** See also tag-20240227-b. +*/ +SQLITE_PRIVATE Expr *sqlite3ExprAlloc( + sqlite3 *db, /* Handle for sqlite3DbMallocRawNN() */ + int op, /* Expression opcode */ + const Token *pToken, /* Token argument. Might be NULL */ + int dequote /* True to dequote */ +){ + Expr *pNew; + int nExtra = pToken ? pToken->n+1 : 0; + + assert( db!=0 ); + pNew = sqlite3DbMallocRawNN(db, sizeof(Expr)+nExtra); + if( pNew ){ + memset(pNew, 0, sizeof(Expr)); + pNew->op = (u8)op; + pNew->iAgg = -1; + if( nExtra ){ + assert( pToken!=0 ); + pNew->u.zToken = (char*)&pNew[1]; + assert( pToken->z!=0 || pToken->n==0 ); + if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n); + pNew->u.zToken[pToken->n] = 0; + if( dequote && sqlite3Isquote(pNew->u.zToken[0]) ){ + sqlite3DequoteExpr(pNew); + } + } +#if SQLITE_MAX_EXPR_DEPTH>0 + pNew->nHeight = 1; +#endif + } + return pNew; +} + +/* +** Allocate a new expression node from a zero-terminated token that has +** already been dequoted. +*/ +SQLITE_PRIVATE Expr *sqlite3Expr( + sqlite3 *db, /* Handle for sqlite3DbMallocZero() (may be null) */ + int op, /* Expression opcode */ + const char *zToken /* Token argument. Might be NULL */ +){ + Token x; + x.z = zToken; + x.n = sqlite3Strlen30(zToken); + return sqlite3ExprAlloc(db, op, &x, 0); +} + +/* +** Allocate an expression for a 32-bit signed integer literal. +*/ +SQLITE_PRIVATE Expr *sqlite3ExprInt32(sqlite3 *db, int iVal){ + Expr *pNew = sqlite3DbMallocRawNN(db, sizeof(Expr)); + if( pNew ){ + memset(pNew, 0, sizeof(Expr)); + pNew->op = TK_INTEGER; + pNew->iAgg = -1; + pNew->flags = EP_IntValue|EP_Leaf|(iVal?EP_IsTrue:EP_IsFalse); + pNew->u.iValue = iVal; +#if SQLITE_MAX_EXPR_DEPTH>0 + pNew->nHeight = 1; +#endif + } + return pNew; +} + +/* +** Attach subtrees pLeft and pRight to the Expr node pRoot. +** +** If pRoot==NULL that means that a memory allocation error has occurred. +** In that case, delete the subtrees pLeft and pRight. +*/ +SQLITE_PRIVATE void sqlite3ExprAttachSubtrees( + sqlite3 *db, + Expr *pRoot, + Expr *pLeft, + Expr *pRight +){ + if( pRoot==0 ){ + assert( db->mallocFailed ); + sqlite3ExprDelete(db, pLeft); + sqlite3ExprDelete(db, pRight); + }else{ + assert( ExprUseXList(pRoot) ); + assert( pRoot->x.pSelect==0 ); + if( pRight ){ + pRoot->pRight = pRight; + pRoot->flags |= EP_Propagate & pRight->flags; +#if SQLITE_MAX_EXPR_DEPTH>0 + pRoot->nHeight = pRight->nHeight+1; + }else{ + pRoot->nHeight = 1; +#endif + } + if( pLeft ){ + pRoot->pLeft = pLeft; + pRoot->flags |= EP_Propagate & pLeft->flags; +#if SQLITE_MAX_EXPR_DEPTH>0 + if( pLeft->nHeight>=pRoot->nHeight ){ + pRoot->nHeight = pLeft->nHeight+1; + } +#endif + } + } +} + +/* +** Allocate an Expr node which joins as many as two subtrees. +** +** One or both of the subtrees can be NULL. Return a pointer to the new +** Expr node. Or, if an OOM error occurs, set pParse->db->mallocFailed, +** free the subtrees and return NULL. +*/ +SQLITE_PRIVATE Expr *sqlite3PExpr( + Parse *pParse, /* Parsing context */ + int op, /* Expression opcode */ + Expr *pLeft, /* Left operand */ + Expr *pRight /* Right operand */ +){ + Expr *p; + p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)); + if( p ){ + memset(p, 0, sizeof(Expr)); + p->op = op & 0xff; + p->iAgg = -1; + sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight); + sqlite3ExprCheckHeight(pParse, p->nHeight); + }else{ + sqlite3ExprDelete(pParse->db, pLeft); + sqlite3ExprDelete(pParse->db, pRight); + } + return p; +} + +/* +** Add pSelect to the Expr.x.pSelect field. Or, if pExpr is NULL (due +** do a memory allocation failure) then delete the pSelect object. +*/ +SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse *pParse, Expr *pExpr, Select *pSelect){ + if( pExpr ){ + pExpr->x.pSelect = pSelect; + ExprSetProperty(pExpr, EP_xIsSelect|EP_Subquery); + sqlite3ExprSetHeightAndFlags(pParse, pExpr); + }else{ + assert( pParse->db->mallocFailed ); + sqlite3SelectDelete(pParse->db, pSelect); + } +} + +/* +** Expression list pEList is a list of vector values. This function +** converts the contents of pEList to a VALUES(...) Select statement +** returning 1 row for each element of the list. For example, the +** expression list: +** +** ( (1,2), (3,4) (5,6) ) +** +** is translated to the equivalent of: +** +** VALUES(1,2), (3,4), (5,6) +** +** Each of the vector values in pEList must contain exactly nElem terms. +** If a list element that is not a vector or does not contain nElem terms, +** an error message is left in pParse. +** +** This is used as part of processing IN(...) expressions with a list +** of vectors on the RHS. e.g. "... IN ((1,2), (3,4), (5,6))". +*/ +SQLITE_PRIVATE Select *sqlite3ExprListToValues(Parse *pParse, int nElem, ExprList *pEList){ + int ii; + Select *pRet = 0; + assert( nElem>1 ); + for(ii=0; iinExpr; ii++){ + Select *pSel; + Expr *pExpr = pEList->a[ii].pExpr; + int nExprElem; + if( pExpr->op==TK_VECTOR ){ + assert( ExprUseXList(pExpr) ); + nExprElem = pExpr->x.pList->nExpr; + }else{ + nExprElem = 1; + } + if( nExprElem!=nElem ){ + sqlite3ErrorMsg(pParse, "IN(...) element has %d term%s - expected %d", + nExprElem, nExprElem>1?"s":"", nElem + ); + break; + } + assert( ExprUseXList(pExpr) ); + pSel = sqlite3SelectNew(pParse, pExpr->x.pList, 0, 0, 0, 0, 0, SF_Values,0); + pExpr->x.pList = 0; + if( pSel ){ + if( pRet ){ + pSel->op = TK_ALL; + pSel->pPrior = pRet; + } + pRet = pSel; + } + } + + if( pRet && pRet->pPrior ){ + pRet->selFlags |= SF_MultiValue; + } + sqlite3ExprListDelete(pParse->db, pEList); + return pRet; +} + +/* +** Join two expressions using an AND operator. If either expression is +** NULL, then just return the other expression. +** +** If one side or the other of the AND is known to be false, and neither side +** is part of an ON clause, then instead of returning an AND expression, +** just return a constant expression with a value of false. +*/ +SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){ + sqlite3 *db = pParse->db; + if( pLeft==0 ){ + return pRight; + }else if( pRight==0 ){ + return pLeft; + }else{ + u32 f = pLeft->flags | pRight->flags; + if( (f&(EP_OuterON|EP_InnerON|EP_IsFalse|EP_HasFunc))==EP_IsFalse + && !IN_RENAME_OBJECT + ){ + sqlite3ExprDeferredDelete(pParse, pLeft); + sqlite3ExprDeferredDelete(pParse, pRight); + return sqlite3ExprInt32(db, 0); + }else{ + return sqlite3PExpr(pParse, TK_AND, pLeft, pRight); + } + } +} + +/* +** Construct a new expression node for a function with multiple +** arguments. +*/ +SQLITE_PRIVATE Expr *sqlite3ExprFunction( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* Argument list */ + const Token *pToken, /* Name of the function */ + int eDistinct /* SF_Distinct or SF_ALL or 0 */ +){ + Expr *pNew; + sqlite3 *db = pParse->db; + assert( pToken ); + pNew = sqlite3ExprAlloc(db, TK_FUNCTION, pToken, 1); + if( pNew==0 ){ + sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */ + return 0; + } + assert( !ExprHasProperty(pNew, EP_InnerON|EP_OuterON) ); + pNew->w.iOfst = (int)(pToken->z - pParse->zTail); + if( pList + && pList->nExpr > pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] + && !pParse->nested + ){ + sqlite3ErrorMsg(pParse, "too many arguments on function %T", pToken); + } + pNew->x.pList = pList; + ExprSetProperty(pNew, EP_HasFunc); + assert( ExprUseXList(pNew) ); + sqlite3ExprSetHeightAndFlags(pParse, pNew); + if( eDistinct==SF_Distinct ) ExprSetProperty(pNew, EP_Distinct); + return pNew; +} + +/* +** Report an error when attempting to use an ORDER BY clause within +** the arguments of a non-aggregate function. +*/ +SQLITE_PRIVATE void sqlite3ExprOrderByAggregateError(Parse *pParse, Expr *p){ + sqlite3ErrorMsg(pParse, + "ORDER BY may not be used with non-aggregate %#T()", p + ); +} + +/* +** Attach an ORDER BY clause to a function call. +** +** functionname( arguments ORDER BY sortlist ) +** \_____________________/ \______/ +** pExpr pOrderBy +** +** The ORDER BY clause is inserted into a new Expr node of type TK_ORDER +** and added to the Expr.pLeft field of the parent TK_FUNCTION node. +*/ +SQLITE_PRIVATE void sqlite3ExprAddFunctionOrderBy( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* The function call to which ORDER BY is to be added */ + ExprList *pOrderBy /* The ORDER BY clause to add */ +){ + Expr *pOB; + sqlite3 *db = pParse->db; + if( NEVER(pOrderBy==0) ){ + assert( db->mallocFailed ); + return; + } + if( pExpr==0 ){ + assert( db->mallocFailed ); + sqlite3ExprListDelete(db, pOrderBy); + return; + } + assert( pExpr->op==TK_FUNCTION ); + assert( pExpr->pLeft==0 ); + assert( ExprUseXList(pExpr) ); + if( pExpr->x.pList==0 || NEVER(pExpr->x.pList->nExpr==0) ){ + /* Ignore ORDER BY on zero-argument aggregates */ + sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, pOrderBy); + return; + } + if( IsWindowFunc(pExpr) ){ + sqlite3ExprOrderByAggregateError(pParse, pExpr); + sqlite3ExprListDelete(db, pOrderBy); + return; + } + if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ + sqlite3ErrorMsg(pParse, "too many terms in ORDER BY clause"); + sqlite3ExprListDelete(db, pOrderBy); + return; + } + + pOB = sqlite3ExprAlloc(db, TK_ORDER, 0, 0); + if( pOB==0 ){ + sqlite3ExprListDelete(db, pOrderBy); + return; + } + pOB->x.pList = pOrderBy; + assert( ExprUseXList(pOB) ); + pExpr->pLeft = pOB; + ExprSetProperty(pOB, EP_FullSize); +} + +/* +** Check to see if a function is usable according to current access +** rules: +** +** SQLITE_FUNC_DIRECT - Only usable from top-level SQL +** +** SQLITE_FUNC_UNSAFE - Usable if TRUSTED_SCHEMA or from +** top-level SQL +** +** If the function is not usable, create an error. +*/ +SQLITE_PRIVATE void sqlite3ExprFunctionUsable( + Parse *pParse, /* Parsing and code generating context */ + const Expr *pExpr, /* The function invocation */ + const FuncDef *pDef /* The function being invoked */ +){ + assert( !IN_RENAME_OBJECT ); + assert( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0 ); + if( ExprHasProperty(pExpr, EP_FromDDL) + || pParse->prepFlags & SQLITE_PREPARE_FROM_DDL + ){ + if( (pDef->funcFlags & SQLITE_FUNC_DIRECT)!=0 + || (pParse->db->flags & SQLITE_TrustedSchema)==0 + ){ + /* Functions prohibited in triggers and views if: + ** (1) tagged with SQLITE_DIRECTONLY + ** (2) not tagged with SQLITE_INNOCUOUS (which means it + ** is tagged with SQLITE_FUNC_UNSAFE) and + ** SQLITE_DBCONFIG_TRUSTED_SCHEMA is off (meaning + ** that the schema is possibly tainted). + */ + sqlite3ErrorMsg(pParse, "unsafe use of %#T()", pExpr); + } + } +} + +/* +** Assign a variable number to an expression that encodes a wildcard +** in the original SQL statement. +** +** Wildcards consisting of a single "?" are assigned the next sequential +** variable number. +** +** Wildcards of the form "?nnn" are assigned the number "nnn". We make +** sure "nnn" is not too big to avoid a denial of service attack when +** the SQL statement comes from an external source. +** +** Wildcards of the form ":aaa", "@aaa", or "$aaa" are assigned the same number +** as the previous instance of the same wildcard. Or if this is the first +** instance of the wildcard, the next sequential variable number is +** assigned. +*/ +SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){ + sqlite3 *db = pParse->db; + const char *z; + ynVar x; + + if( pExpr==0 ) return; + assert( !ExprHasProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) ); + z = pExpr->u.zToken; + assert( z!=0 ); + assert( z[0]!=0 ); + assert( n==(u32)sqlite3Strlen30(z) ); + if( z[1]==0 ){ + /* Wildcard of the form "?". Assign the next variable number */ + assert( z[0]=='?' ); + x = (ynVar)(++pParse->nVar); + }else{ + int doAdd = 0; + if( z[0]=='?' ){ + /* Wildcard of the form "?nnn". Convert "nnn" to an integer and + ** use it as the variable number */ + i64 i; + int bOk; + if( n==2 ){ /*OPTIMIZATION-IF-TRUE*/ + i = z[1]-'0'; /* The common case of ?N for a single digit N */ + bOk = 1; + }else{ + bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8); + } + testcase( i==0 ); + testcase( i==1 ); + testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 ); + testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ); + if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ + sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d", + db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]); + sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr); + return; + } + x = (ynVar)i; + if( x>pParse->nVar ){ + pParse->nVar = (int)x; + doAdd = 1; + }else if( sqlite3VListNumToName(pParse->pVList, x)==0 ){ + doAdd = 1; + } + }else{ + /* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable + ** number as the prior appearance of the same name, or if the name + ** has never appeared before, reuse the same variable number + */ + x = (ynVar)sqlite3VListNameToNum(pParse->pVList, z, n); + if( x==0 ){ + x = (ynVar)(++pParse->nVar); + doAdd = 1; + } + } + if( doAdd ){ + pParse->pVList = sqlite3VListAdd(db, pParse->pVList, z, n, x); + } + } + pExpr->iColumn = x; + if( x>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ + sqlite3ErrorMsg(pParse, "too many SQL variables"); + sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr); + } +} + +/* +** Recursively delete an expression tree. +*/ +static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ + assert( p!=0 ); + assert( db!=0 ); +exprDeleteRestart: + assert( !ExprUseUValue(p) || p->u.iValue>=0 ); + assert( !ExprUseYWin(p) || !ExprUseYSub(p) ); + assert( !ExprUseYWin(p) || p->y.pWin!=0 || db->mallocFailed ); + assert( p->op!=TK_FUNCTION || !ExprUseYSub(p) ); +#ifdef SQLITE_DEBUG + if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){ + assert( p->pLeft==0 ); + assert( p->pRight==0 ); + assert( !ExprUseXSelect(p) || p->x.pSelect==0 ); + assert( !ExprUseXList(p) || p->x.pList==0 ); + } +#endif + if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){ + /* The Expr.x union is never used at the same time as Expr.pRight */ + assert( (ExprUseXList(p) && p->x.pList==0) || p->pRight==0 ); + if( p->pRight ){ + assert( !ExprHasProperty(p, EP_WinFunc) ); + sqlite3ExprDeleteNN(db, p->pRight); + }else if( ExprUseXSelect(p) ){ + assert( !ExprHasProperty(p, EP_WinFunc) ); + sqlite3SelectDelete(db, p->x.pSelect); + }else{ + sqlite3ExprListDelete(db, p->x.pList); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( ExprHasProperty(p, EP_WinFunc) ){ + sqlite3WindowDelete(db, p->y.pWin); + } +#endif + } + if( p->pLeft && p->op!=TK_SELECT_COLUMN ){ + Expr *pLeft = p->pLeft; + if( !ExprHasProperty(p, EP_Static) + && !ExprHasProperty(pLeft, EP_Static) + ){ + /* Avoid unnecessary recursion on unary operators */ + sqlite3DbNNFreeNN(db, p); + p = pLeft; + goto exprDeleteRestart; + }else{ + sqlite3ExprDeleteNN(db, pLeft); + } + } + } + if( !ExprHasProperty(p, EP_Static) ){ + sqlite3DbNNFreeNN(db, p); + } +} +SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){ + if( p ) sqlite3ExprDeleteNN(db, p); +} +SQLITE_PRIVATE void sqlite3ExprDeleteGeneric(sqlite3 *db, void *p){ + if( ALWAYS(p) ) sqlite3ExprDeleteNN(db, (Expr*)p); +} + +/* +** Clear both elements of an OnOrUsing object +*/ +SQLITE_PRIVATE void sqlite3ClearOnOrUsing(sqlite3 *db, OnOrUsing *p){ + if( p==0 ){ + /* Nothing to clear */ + }else if( p->pOn ){ + sqlite3ExprDeleteNN(db, p->pOn); + }else if( p->pUsing ){ + sqlite3IdListDelete(db, p->pUsing); + } +} + +/* +** Arrange to cause pExpr to be deleted when the pParse is deleted. +** This is similar to sqlite3ExprDelete() except that the delete is +** deferred until the pParse is deleted. +** +** The pExpr might be deleted immediately on an OOM error. +** +** Return 0 if the delete was successfully deferred. Return non-zero +** if the delete happened immediately because of an OOM. +*/ +SQLITE_PRIVATE int sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){ + return 0==sqlite3ParserAddCleanup(pParse, sqlite3ExprDeleteGeneric, pExpr); +} + +/* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the +** expression. +*/ +SQLITE_PRIVATE void sqlite3ExprUnmapAndDelete(Parse *pParse, Expr *p){ + if( p ){ + if( IN_RENAME_OBJECT ){ + sqlite3RenameExprUnmap(pParse, p); + } + sqlite3ExprDeleteNN(pParse->db, p); + } +} + +/* +** Return the number of bytes allocated for the expression structure +** passed as the first argument. This is always one of EXPR_FULLSIZE, +** EXPR_REDUCEDSIZE or EXPR_TOKENONLYSIZE. +*/ +static int exprStructSize(const Expr *p){ + if( ExprHasProperty(p, EP_TokenOnly) ) return EXPR_TOKENONLYSIZE; + if( ExprHasProperty(p, EP_Reduced) ) return EXPR_REDUCEDSIZE; + return EXPR_FULLSIZE; +} + +/* +** The dupedExpr*Size() routines each return the number of bytes required +** to store a copy of an expression or expression tree. They differ in +** how much of the tree is measured. +** +** dupedExprStructSize() Size of only the Expr structure +** dupedExprNodeSize() Size of Expr + space for token +** dupedExprSize() Expr + token + subtree components +** +*************************************************************************** +** +** The dupedExprStructSize() function returns two values OR-ed together: +** (1) the space required for a copy of the Expr structure only and +** (2) the EP_xxx flags that indicate what the structure size should be. +** The return values is always one of: +** +** EXPR_FULLSIZE +** EXPR_REDUCEDSIZE | EP_Reduced +** EXPR_TOKENONLYSIZE | EP_TokenOnly +** +** The size of the structure can be found by masking the return value +** of this routine with 0xfff. The flags can be found by masking the +** return value with EP_Reduced|EP_TokenOnly. +** +** Note that with flags==EXPRDUP_REDUCE, this routines works on full-size +** (unreduced) Expr objects as they or originally constructed by the parser. +** During expression analysis, extra information is computed and moved into +** later parts of the Expr object and that extra information might get chopped +** off if the expression is reduced. Note also that it does not work to +** make an EXPRDUP_REDUCE copy of a reduced expression. It is only legal +** to reduce a pristine expression tree from the parser. The implementation +** of dupedExprStructSize() contain multiple assert() statements that attempt +** to enforce this constraint. +*/ +static int dupedExprStructSize(const Expr *p, int flags){ + int nSize; + assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */ + assert( EXPR_FULLSIZE<=0xfff ); + assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 ); + if( 0==flags || ExprHasProperty(p, EP_FullSize) ){ + nSize = EXPR_FULLSIZE; + }else{ + assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); + assert( !ExprHasProperty(p, EP_OuterON) ); + assert( !ExprHasVVAProperty(p, EP_NoReduce) ); + if( p->pLeft || p->x.pList ){ + nSize = EXPR_REDUCEDSIZE | EP_Reduced; + }else{ + assert( p->pRight==0 ); + nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly; + } + } + return nSize; +} + +/* +** This function returns the space in bytes required to store the copy +** of the Expr structure and a copy of the Expr.u.zToken string (if that +** string is defined.) +*/ +static int dupedExprNodeSize(const Expr *p, int flags){ + int nByte = dupedExprStructSize(p, flags) & 0xfff; + if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ + nByte += sqlite3Strlen30NN(p->u.zToken)+1; + } + return ROUND8(nByte); +} + +/* +** Return the number of bytes required to create a duplicate of the +** expression passed as the first argument. +** +** The value returned includes space to create a copy of the Expr struct +** itself and the buffer referred to by Expr.u.zToken, if any. +** +** The return value includes space to duplicate all Expr nodes in the +** tree formed by Expr.pLeft and Expr.pRight, but not any other +** substructure such as Expr.x.pList, Expr.x.pSelect, and Expr.y.pWin. +*/ +static int dupedExprSize(const Expr *p){ + int nByte; + assert( p!=0 ); + nByte = dupedExprNodeSize(p, EXPRDUP_REDUCE); + if( p->pLeft ) nByte += dupedExprSize(p->pLeft); + if( p->pRight ) nByte += dupedExprSize(p->pRight); + assert( nByte==ROUND8(nByte) ); + return nByte; +} + +/* +** An EdupBuf is a memory allocation used to stored multiple Expr objects +** together with their Expr.zToken content. This is used to help implement +** compression while doing sqlite3ExprDup(). The top-level Expr does the +** allocation for itself and many of its decendents, then passes an instance +** of the structure down into exprDup() so that they decendents can have +** access to that memory. +*/ +typedef struct EdupBuf EdupBuf; +struct EdupBuf { + u8 *zAlloc; /* Memory space available for storage */ +#ifdef SQLITE_DEBUG + u8 *zEnd; /* First byte past the end of memory */ +#endif +}; + +/* +** This function is similar to sqlite3ExprDup(), except that if pEdupBuf +** is not NULL then it points to memory that can be used to store a copy +** of the input Expr p together with its p->u.zToken (if any). pEdupBuf +** is updated with the new buffer tail prior to returning. +*/ +static Expr *exprDup( + sqlite3 *db, /* Database connection (for memory allocation) */ + const Expr *p, /* Expr tree to be duplicated */ + int dupFlags, /* EXPRDUP_REDUCE for compression. 0 if not */ + EdupBuf *pEdupBuf /* Preallocated storage space, or NULL */ +){ + Expr *pNew; /* Value to return */ + EdupBuf sEdupBuf; /* Memory space from which to build Expr object */ + u32 staticFlag; /* EP_Static if space not obtained from malloc */ + int nToken = -1; /* Space needed for p->u.zToken. -1 means unknown */ + + assert( db!=0 ); + assert( p ); + assert( dupFlags==0 || dupFlags==EXPRDUP_REDUCE ); + assert( pEdupBuf==0 || dupFlags==EXPRDUP_REDUCE ); + + /* Figure out where to write the new Expr structure. */ + if( pEdupBuf ){ + sEdupBuf.zAlloc = pEdupBuf->zAlloc; +#ifdef SQLITE_DEBUG + sEdupBuf.zEnd = pEdupBuf->zEnd; +#endif + staticFlag = EP_Static; + assert( sEdupBuf.zAlloc!=0 ); + assert( dupFlags==EXPRDUP_REDUCE ); + }else{ + int nAlloc; + if( dupFlags ){ + nAlloc = dupedExprSize(p); + }else if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ + nToken = sqlite3Strlen30NN(p->u.zToken)+1; + nAlloc = ROUND8(EXPR_FULLSIZE + nToken); + }else{ + nToken = 0; + nAlloc = ROUND8(EXPR_FULLSIZE); + } + assert( nAlloc==ROUND8(nAlloc) ); + sEdupBuf.zAlloc = sqlite3DbMallocRawNN(db, nAlloc); +#ifdef SQLITE_DEBUG + sEdupBuf.zEnd = sEdupBuf.zAlloc ? sEdupBuf.zAlloc+nAlloc : 0; +#endif + + staticFlag = 0; + } + pNew = (Expr *)sEdupBuf.zAlloc; + assert( EIGHT_BYTE_ALIGNMENT(pNew) ); + + if( pNew ){ + /* Set nNewSize to the size allocated for the structure pointed to + ** by pNew. This is either EXPR_FULLSIZE, EXPR_REDUCEDSIZE or + ** EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed + ** by the copy of the p->u.zToken string (if any). + */ + const unsigned nStructSize = dupedExprStructSize(p, dupFlags); + int nNewSize = nStructSize & 0xfff; + if( nToken<0 ){ + if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ + nToken = sqlite3Strlen30(p->u.zToken) + 1; + }else{ + nToken = 0; + } + } + if( dupFlags ){ + assert( (int)(sEdupBuf.zEnd - sEdupBuf.zAlloc) >= nNewSize+nToken ); + assert( ExprHasProperty(p, EP_Reduced)==0 ); + memcpy(sEdupBuf.zAlloc, p, nNewSize); + }else{ + u32 nSize = (u32)exprStructSize(p); + assert( (int)(sEdupBuf.zEnd - sEdupBuf.zAlloc) >= + (int)EXPR_FULLSIZE+nToken ); + memcpy(sEdupBuf.zAlloc, p, nSize); + if( nSizeflags &= ~(EP_Reduced|EP_TokenOnly|EP_Static); + pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly); + pNew->flags |= staticFlag; + ExprClearVVAProperties(pNew); + if( dupFlags ){ + ExprSetVVAProperty(pNew, EP_Immutable); + } + + /* Copy the p->u.zToken string, if any. */ + assert( nToken>=0 ); + if( nToken>0 ){ + char *zToken = pNew->u.zToken = (char*)&sEdupBuf.zAlloc[nNewSize]; + memcpy(zToken, p->u.zToken, nToken); + nNewSize += nToken; + } + sEdupBuf.zAlloc += ROUND8(nNewSize); + + if( ((p->flags|pNew->flags)&(EP_TokenOnly|EP_Leaf))==0 ){ + + /* Fill in the pNew->x.pSelect or pNew->x.pList member. */ + if( ExprUseXSelect(p) ){ + pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags); + }else{ + pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, + p->op!=TK_ORDER ? dupFlags : 0); + } + +#ifndef SQLITE_OMIT_WINDOWFUNC + if( ExprHasProperty(p, EP_WinFunc) ){ + pNew->y.pWin = sqlite3WindowDup(db, pNew, p->y.pWin); + assert( ExprHasProperty(pNew, EP_WinFunc) ); + } +#endif /* SQLITE_OMIT_WINDOWFUNC */ + + /* Fill in pNew->pLeft and pNew->pRight. */ + if( dupFlags ){ + if( p->op==TK_SELECT_COLUMN ){ + pNew->pLeft = p->pLeft; + assert( p->pRight==0 + || p->pRight==p->pLeft + || ExprHasProperty(p->pLeft, EP_Subquery) ); + }else{ + pNew->pLeft = p->pLeft ? + exprDup(db, p->pLeft, EXPRDUP_REDUCE, &sEdupBuf) : 0; + } + pNew->pRight = p->pRight ? + exprDup(db, p->pRight, EXPRDUP_REDUCE, &sEdupBuf) : 0; + }else{ + if( p->op==TK_SELECT_COLUMN ){ + pNew->pLeft = p->pLeft; + assert( p->pRight==0 + || p->pRight==p->pLeft + || ExprHasProperty(p->pLeft, EP_Subquery) ); + }else{ + pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0); + } + pNew->pRight = sqlite3ExprDup(db, p->pRight, 0); + } + } + } + if( pEdupBuf ) memcpy(pEdupBuf, &sEdupBuf, sizeof(sEdupBuf)); + assert( sEdupBuf.zAlloc <= sEdupBuf.zEnd ); + return pNew; +} + +/* +** Create and return a deep copy of the object passed as the second +** argument. If an OOM condition is encountered, NULL is returned +** and the db->mallocFailed flag set. +*/ +#ifndef SQLITE_OMIT_CTE +SQLITE_PRIVATE With *sqlite3WithDup(sqlite3 *db, With *p){ + With *pRet = 0; + if( p ){ + sqlite3_int64 nByte = SZ_WITH(p->nCte); + pRet = sqlite3DbMallocZero(db, nByte); + if( pRet ){ + int i; + pRet->nCte = p->nCte; + for(i=0; inCte; i++){ + pRet->a[i].pSelect = sqlite3SelectDup(db, p->a[i].pSelect, 0); + pRet->a[i].pCols = sqlite3ExprListDup(db, p->a[i].pCols, 0); + pRet->a[i].zName = sqlite3DbStrDup(db, p->a[i].zName); + pRet->a[i].eM10d = p->a[i].eM10d; + } + } + } + return pRet; +} +#else +# define sqlite3WithDup(x,y) 0 +#endif + +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** The gatherSelectWindows() procedure and its helper routine +** gatherSelectWindowsCallback() are used to scan all the expressions +** an a newly duplicated SELECT statement and gather all of the Window +** objects found there, assembling them onto the linked list at Select->pWin. +*/ +static int gatherSelectWindowsCallback(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_FUNCTION && ExprHasProperty(pExpr, EP_WinFunc) ){ + Select *pSelect = pWalker->u.pSelect; + Window *pWin = pExpr->y.pWin; + assert( pWin ); + assert( IsWindowFunc(pExpr) ); + assert( pWin->ppThis==0 ); + sqlite3WindowLink(pSelect, pWin); + } + return WRC_Continue; +} +static int gatherSelectWindowsSelectCallback(Walker *pWalker, Select *p){ + return p==pWalker->u.pSelect ? WRC_Continue : WRC_Prune; +} +static void gatherSelectWindows(Select *p){ + Walker w; + w.xExprCallback = gatherSelectWindowsCallback; + w.xSelectCallback = gatherSelectWindowsSelectCallback; + w.xSelectCallback2 = 0; + w.pParse = 0; + w.u.pSelect = p; + sqlite3WalkSelect(&w, p); +} +#endif + + +/* +** The following group of routines make deep copies of expressions, +** expression lists, ID lists, and select statements. The copies can +** be deleted (by being passed to their respective ...Delete() routines) +** without effecting the originals. +** +** The expression list, ID, and source lists return by sqlite3ExprListDup(), +** sqlite3IdListDup(), and sqlite3SrcListDup() can not be further expanded +** by subsequent calls to sqlite*ListAppend() routines. +** +** Any tables that the SrcList might point to are not duplicated. +** +** The flags parameter contains a combination of the EXPRDUP_XXX flags. +** If the EXPRDUP_REDUCE flag is set, then the structure returned is a +** truncated version of the usual Expr structure that will be stored as +** part of the in-memory representation of the database schema. +*/ +SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3 *db, const Expr *p, int flags){ + assert( flags==0 || flags==EXPRDUP_REDUCE ); + return p ? exprDup(db, p, flags, 0) : 0; +} +SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, const ExprList *p, int flags){ + ExprList *pNew; + struct ExprList_item *pItem; + const struct ExprList_item *pOldItem; + int i; + Expr *pPriorSelectColOld = 0; + Expr *pPriorSelectColNew = 0; + assert( db!=0 ); + if( p==0 ) return 0; + pNew = sqlite3DbMallocRawNN(db, sqlite3DbMallocSize(db, p)); + if( pNew==0 ) return 0; + pNew->nExpr = p->nExpr; + pNew->nAlloc = p->nAlloc; + pItem = pNew->a; + pOldItem = p->a; + for(i=0; inExpr; i++, pItem++, pOldItem++){ + Expr *pOldExpr = pOldItem->pExpr; + Expr *pNewExpr; + pItem->pExpr = sqlite3ExprDup(db, pOldExpr, flags); + if( pOldExpr + && pOldExpr->op==TK_SELECT_COLUMN + && (pNewExpr = pItem->pExpr)!=0 + ){ + if( pNewExpr->pRight ){ + pPriorSelectColOld = pOldExpr->pRight; + pPriorSelectColNew = pNewExpr->pRight; + pNewExpr->pLeft = pNewExpr->pRight; + }else{ + if( pOldExpr->pLeft!=pPriorSelectColOld ){ + pPriorSelectColOld = pOldExpr->pLeft; + pPriorSelectColNew = sqlite3ExprDup(db, pPriorSelectColOld, flags); + pNewExpr->pRight = pPriorSelectColNew; + } + pNewExpr->pLeft = pPriorSelectColNew; + } + } + pItem->zEName = sqlite3DbStrDup(db, pOldItem->zEName); + pItem->fg = pOldItem->fg; + pItem->u = pOldItem->u; + } + return pNew; +} + +/* +** If cursors, triggers, views and subqueries are all omitted from +** the build, then none of the following routines, except for +** sqlite3SelectDup(), can be called. sqlite3SelectDup() is sometimes +** called with a NULL argument. +*/ +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \ + || !defined(SQLITE_OMIT_SUBQUERY) +SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, const SrcList *p, int flags){ + SrcList *pNew; + int i; + assert( db!=0 ); + if( p==0 ) return 0; + pNew = sqlite3DbMallocRawNN(db, SZ_SRCLIST(p->nSrc) ); + if( pNew==0 ) return 0; + pNew->nSrc = pNew->nAlloc = p->nSrc; + for(i=0; inSrc; i++){ + SrcItem *pNewItem = &pNew->a[i]; + const SrcItem *pOldItem = &p->a[i]; + Table *pTab; + pNewItem->fg = pOldItem->fg; + if( pOldItem->fg.isSubquery ){ + Subquery *pNewSubq = sqlite3DbMallocRaw(db, sizeof(Subquery)); + if( pNewSubq==0 ){ + assert( db->mallocFailed ); + pNewItem->fg.isSubquery = 0; + }else{ + memcpy(pNewSubq, pOldItem->u4.pSubq, sizeof(*pNewSubq)); + pNewSubq->pSelect = sqlite3SelectDup(db, pNewSubq->pSelect, flags); + if( pNewSubq->pSelect==0 ){ + sqlite3DbFree(db, pNewSubq); + pNewSubq = 0; + pNewItem->fg.isSubquery = 0; + } + } + pNewItem->u4.pSubq = pNewSubq; + }else if( pOldItem->fg.fixedSchema ){ + pNewItem->u4.pSchema = pOldItem->u4.pSchema; + }else{ + pNewItem->u4.zDatabase = sqlite3DbStrDup(db, pOldItem->u4.zDatabase); + } + pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); + pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias); + pNewItem->iCursor = pOldItem->iCursor; + if( pNewItem->fg.isIndexedBy ){ + pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy); + }else if( pNewItem->fg.isTabFunc ){ + pNewItem->u1.pFuncArg = + sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags); + }else{ + pNewItem->u1.nRow = pOldItem->u1.nRow; + } + pNewItem->u2 = pOldItem->u2; + if( pNewItem->fg.isCte ){ + pNewItem->u2.pCteUse->nUse++; + } + pTab = pNewItem->pSTab = pOldItem->pSTab; + if( pTab ){ + pTab->nTabRef++; + } + if( pOldItem->fg.isUsing ){ + assert( pNewItem->fg.isUsing ); + pNewItem->u3.pUsing = sqlite3IdListDup(db, pOldItem->u3.pUsing); + }else{ + pNewItem->u3.pOn = sqlite3ExprDup(db, pOldItem->u3.pOn, flags); + } + pNewItem->colUsed = pOldItem->colUsed; + } + return pNew; +} +SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, const IdList *p){ + IdList *pNew; + int i; + assert( db!=0 ); + if( p==0 ) return 0; + pNew = sqlite3DbMallocRawNN(db, SZ_IDLIST(p->nId)); + if( pNew==0 ) return 0; + pNew->nId = p->nId; + for(i=0; inId; i++){ + struct IdList_item *pNewItem = &pNew->a[i]; + const struct IdList_item *pOldItem = &p->a[i]; + pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); + } + return pNew; +} +SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *pDup, int flags){ + Select *pRet = 0; + Select *pNext = 0; + Select **pp = &pRet; + const Select *p; + + assert( db!=0 ); + for(p=pDup; p; p=p->pPrior){ + Select *pNew = sqlite3DbMallocRawNN(db, sizeof(*p) ); + if( pNew==0 ) break; + pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags); + pNew->pSrc = sqlite3SrcListDup(db, p->pSrc, flags); + pNew->pWhere = sqlite3ExprDup(db, p->pWhere, flags); + pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy, flags); + pNew->pHaving = sqlite3ExprDup(db, p->pHaving, flags); + pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, flags); + pNew->op = p->op; + pNew->pNext = pNext; + pNew->pPrior = 0; + pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags); + pNew->iLimit = 0; + pNew->iOffset = 0; + pNew->selFlags = p->selFlags; + pNew->nSelectRow = p->nSelectRow; + pNew->pWith = sqlite3WithDup(db, p->pWith); +#ifndef SQLITE_OMIT_WINDOWFUNC + pNew->pWin = 0; + pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn); + if( p->pWin && db->mallocFailed==0 ) gatherSelectWindows(pNew); +#endif + pNew->selId = p->selId; + if( db->mallocFailed ){ + /* Any prior OOM might have left the Select object incomplete. + ** Delete the whole thing rather than allow an incomplete Select + ** to be used by the code generator. */ + pNew->pNext = 0; + sqlite3SelectDelete(db, pNew); + break; + } + *pp = pNew; + pp = &pNew->pPrior; + pNext = pNew; + } + return pRet; +} +#else +SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *p, int flags){ + assert( p==0 ); + return 0; +} +#endif + + +/* +** Add a new element to the end of an expression list. If pList is +** initially NULL, then create a new expression list. +** +** The pList argument must be either NULL or a pointer to an ExprList +** obtained from a prior call to sqlite3ExprListAppend(). +** +** If a memory allocation error occurs, the entire list is freed and +** NULL is returned. If non-NULL is returned, then it is guaranteed +** that the new entry was successfully appended. +*/ +static const struct ExprList_item zeroItem = {0}; +SQLITE_PRIVATE SQLITE_NOINLINE ExprList *sqlite3ExprListAppendNew( + sqlite3 *db, /* Database handle. Used for memory allocation */ + Expr *pExpr /* Expression to be appended. Might be NULL */ +){ + struct ExprList_item *pItem; + ExprList *pList; + + pList = sqlite3DbMallocRawNN(db, SZ_EXPRLIST(4)); + if( pList==0 ){ + sqlite3ExprDelete(db, pExpr); + return 0; + } + pList->nAlloc = 4; + pList->nExpr = 1; + pItem = &pList->a[0]; + *pItem = zeroItem; + pItem->pExpr = pExpr; + return pList; +} +SQLITE_PRIVATE SQLITE_NOINLINE ExprList *sqlite3ExprListAppendGrow( + sqlite3 *db, /* Database handle. Used for memory allocation */ + ExprList *pList, /* List to which to append. Might be NULL */ + Expr *pExpr /* Expression to be appended. Might be NULL */ +){ + struct ExprList_item *pItem; + ExprList *pNew; + pList->nAlloc *= 2; + pNew = sqlite3DbRealloc(db, pList, SZ_EXPRLIST(pList->nAlloc)); + if( pNew==0 ){ + sqlite3ExprListDelete(db, pList); + sqlite3ExprDelete(db, pExpr); + return 0; + }else{ + pList = pNew; + } + pItem = &pList->a[pList->nExpr++]; + *pItem = zeroItem; + pItem->pExpr = pExpr; + return pList; +} +SQLITE_PRIVATE ExprList *sqlite3ExprListAppend( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* List to which to append. Might be NULL */ + Expr *pExpr /* Expression to be appended. Might be NULL */ +){ + struct ExprList_item *pItem; + if( pList==0 ){ + return sqlite3ExprListAppendNew(pParse->db,pExpr); + } + if( pList->nAllocnExpr+1 ){ + return sqlite3ExprListAppendGrow(pParse->db,pList,pExpr); + } + pItem = &pList->a[pList->nExpr++]; + *pItem = zeroItem; + pItem->pExpr = pExpr; + return pList; +} + +/* +** pColumns and pExpr form a vector assignment which is part of the SET +** clause of an UPDATE statement. Like this: +** +** (a,b,c) = (expr1,expr2,expr3) +** Or: (a,b,c) = (SELECT x,y,z FROM ....) +** +** For each term of the vector assignment, append new entries to the +** expression list pList. In the case of a subquery on the RHS, append +** TK_SELECT_COLUMN expressions. +*/ +SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* List to which to append. Might be NULL */ + IdList *pColumns, /* List of names of LHS of the assignment */ + Expr *pExpr /* Vector expression to be appended. Might be NULL */ +){ + sqlite3 *db = pParse->db; + int n; + int i; + int iFirst = pList ? pList->nExpr : 0; + /* pColumns can only be NULL due to an OOM but an OOM will cause an + ** exit prior to this routine being invoked */ + if( NEVER(pColumns==0) ) goto vector_append_error; + if( pExpr==0 ) goto vector_append_error; + + /* If the RHS is a vector, then we can immediately check to see that + ** the size of the RHS and LHS match. But if the RHS is a SELECT, + ** wildcards ("*") in the result set of the SELECT must be expanded before + ** we can do the size check, so defer the size check until code generation. + */ + if( pExpr->op!=TK_SELECT && pColumns->nId!=(n=sqlite3ExprVectorSize(pExpr)) ){ + sqlite3ErrorMsg(pParse, "%d columns assigned %d values", + pColumns->nId, n); + goto vector_append_error; + } + + for(i=0; inId; i++){ + Expr *pSubExpr = sqlite3ExprForVectorField(pParse, pExpr, i, pColumns->nId); + assert( pSubExpr!=0 || db->mallocFailed ); + if( pSubExpr==0 ) continue; + pList = sqlite3ExprListAppend(pParse, pList, pSubExpr); + if( pList ){ + assert( pList->nExpr==iFirst+i+1 ); + pList->a[pList->nExpr-1].zEName = pColumns->a[i].zName; + pColumns->a[i].zName = 0; + } + } + + if( !db->mallocFailed && pExpr->op==TK_SELECT && ALWAYS(pList!=0) ){ + Expr *pFirst = pList->a[iFirst].pExpr; + assert( pFirst!=0 ); + assert( pFirst->op==TK_SELECT_COLUMN ); + + /* Store the SELECT statement in pRight so it will be deleted when + ** sqlite3ExprListDelete() is called */ + pFirst->pRight = pExpr; + pExpr = 0; + + /* Remember the size of the LHS in iTable so that we can check that + ** the RHS and LHS sizes match during code generation. */ + pFirst->iTable = pColumns->nId; + } + +vector_append_error: + sqlite3ExprUnmapAndDelete(pParse, pExpr); + sqlite3IdListDelete(db, pColumns); + return pList; +} + +/* +** Set the sort order for the last element on the given ExprList. +*/ +SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder, int eNulls){ + struct ExprList_item *pItem; + if( p==0 ) return; + assert( p->nExpr>0 ); + + assert( SQLITE_SO_UNDEFINED<0 && SQLITE_SO_ASC==0 && SQLITE_SO_DESC>0 ); + assert( iSortOrder==SQLITE_SO_UNDEFINED + || iSortOrder==SQLITE_SO_ASC + || iSortOrder==SQLITE_SO_DESC + ); + assert( eNulls==SQLITE_SO_UNDEFINED + || eNulls==SQLITE_SO_ASC + || eNulls==SQLITE_SO_DESC + ); + + pItem = &p->a[p->nExpr-1]; + assert( pItem->fg.bNulls==0 ); + if( iSortOrder==SQLITE_SO_UNDEFINED ){ + iSortOrder = SQLITE_SO_ASC; + } + pItem->fg.sortFlags = (u8)iSortOrder; + + if( eNulls!=SQLITE_SO_UNDEFINED ){ + pItem->fg.bNulls = 1; + if( iSortOrder!=eNulls ){ + pItem->fg.sortFlags |= KEYINFO_ORDER_BIGNULL; + } + } +} + +/* +** Set the ExprList.a[].zEName element of the most recently added item +** on the expression list. +** +** pList might be NULL following an OOM error. But pName should never be +** NULL. If a memory allocation fails, the pParse->db->mallocFailed flag +** is set. +*/ +SQLITE_PRIVATE void sqlite3ExprListSetName( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* List to which to add the span. */ + const Token *pName, /* Name to be added */ + int dequote /* True to cause the name to be dequoted */ +){ + assert( pList!=0 || pParse->db->mallocFailed!=0 ); + assert( pParse->eParseMode!=PARSE_MODE_UNMAP || dequote==0 ); + if( pList ){ + struct ExprList_item *pItem; + assert( pList->nExpr>0 ); + pItem = &pList->a[pList->nExpr-1]; + assert( pItem->zEName==0 ); + assert( pItem->fg.eEName==ENAME_NAME ); + pItem->zEName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n); + if( dequote ){ + /* If dequote==0, then pName->z does not point to part of a DDL + ** statement handled by the parser. And so no token need be added + ** to the token-map. */ + sqlite3Dequote(pItem->zEName); + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenMap(pParse, (const void*)pItem->zEName, pName); + } + } + } +} + +/* +** Set the ExprList.a[].zSpan element of the most recently added item +** on the expression list. +** +** pList might be NULL following an OOM error. But pSpan should never be +** NULL. If a memory allocation fails, the pParse->db->mallocFailed flag +** is set. +*/ +SQLITE_PRIVATE void sqlite3ExprListSetSpan( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* List to which to add the span. */ + const char *zStart, /* Start of the span */ + const char *zEnd /* End of the span */ +){ + sqlite3 *db = pParse->db; + assert( pList!=0 || db->mallocFailed!=0 ); + if( pList ){ + struct ExprList_item *pItem = &pList->a[pList->nExpr-1]; + assert( pList->nExpr>0 ); + if( pItem->zEName==0 ){ + pItem->zEName = sqlite3DbSpanDup(db, zStart, zEnd); + pItem->fg.eEName = ENAME_SPAN; + } + } +} + +/* +** If the expression list pEList contains more than iLimit elements, +** leave an error message in pParse. +*/ +SQLITE_PRIVATE void sqlite3ExprListCheckLength( + Parse *pParse, + ExprList *pEList, + const char *zObject +){ + int mx = pParse->db->aLimit[SQLITE_LIMIT_COLUMN]; + testcase( pEList && pEList->nExpr==mx ); + testcase( pEList && pEList->nExpr==mx+1 ); + if( pEList && pEList->nExpr>mx ){ + sqlite3ErrorMsg(pParse, "too many columns in %s", zObject); + } +} + +/* +** Delete an entire expression list. +*/ +static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){ + int i = pList->nExpr; + struct ExprList_item *pItem = pList->a; + assert( pList->nExpr>0 ); + assert( db!=0 ); + do{ + sqlite3ExprDelete(db, pItem->pExpr); + if( pItem->zEName ) sqlite3DbNNFreeNN(db, pItem->zEName); + pItem++; + }while( --i>0 ); + sqlite3DbNNFreeNN(db, pList); +} +SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){ + if( pList ) exprListDeleteNN(db, pList); +} +SQLITE_PRIVATE void sqlite3ExprListDeleteGeneric(sqlite3 *db, void *pList){ + if( ALWAYS(pList) ) exprListDeleteNN(db, (ExprList*)pList); +} + +/* +** Return the bitwise-OR of all Expr.flags fields in the given +** ExprList. +*/ +SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList *pList){ + int i; + u32 m = 0; + assert( pList!=0 ); + for(i=0; inExpr; i++){ + Expr *pExpr = pList->a[i].pExpr; + assert( pExpr!=0 ); + m |= pExpr->flags; + } + return m; +} + +/* +** This is a SELECT-node callback for the expression walker that +** always "fails". By "fail" in this case, we mean set +** pWalker->eCode to zero and abort. +** +** This callback is used by multiple expression walkers. +*/ +SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){ + UNUSED_PARAMETER(NotUsed); + pWalker->eCode = 0; + return WRC_Abort; +} + +/* +** Check the input string to see if it is "true" or "false" (in any case). +** +** If the string is.... Return +** "true" EP_IsTrue +** "false" EP_IsFalse +** anything else 0 +*/ +SQLITE_PRIVATE u32 sqlite3IsTrueOrFalse(const char *zIn){ + if( sqlite3StrICmp(zIn, "true")==0 ) return EP_IsTrue; + if( sqlite3StrICmp(zIn, "false")==0 ) return EP_IsFalse; + return 0; +} + + +/* +** If the input expression is an ID with the name "true" or "false" +** then convert it into an TK_TRUEFALSE term. Return non-zero if +** the conversion happened, and zero if the expression is unaltered. +*/ +SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr *pExpr){ + u32 v; + assert( pExpr->op==TK_ID || pExpr->op==TK_STRING ); + if( !ExprHasProperty(pExpr, EP_Quoted|EP_IntValue) + && (v = sqlite3IsTrueOrFalse(pExpr->u.zToken))!=0 + ){ + pExpr->op = TK_TRUEFALSE; + ExprSetProperty(pExpr, v); + return 1; + } + return 0; +} + +/* +** The argument must be a TK_TRUEFALSE Expr node. Return 1 if it is TRUE +** and 0 if it is FALSE. +*/ +SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr *pExpr){ + pExpr = sqlite3ExprSkipCollateAndLikely((Expr*)pExpr); + assert( pExpr->op==TK_TRUEFALSE ); + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0 + || sqlite3StrICmp(pExpr->u.zToken,"false")==0 ); + return pExpr->u.zToken[4]==0; +} + +/* +** If pExpr is an AND or OR expression, try to simplify it by eliminating +** terms that are always true or false. Return the simplified expression. +** Or return the original expression if no simplification is possible. +** +** Examples: +** +** (x<10) AND true => (x<10) +** (x<10) AND false => false +** (x<10) AND (y=22 OR false) => (x<10) AND (y=22) +** (x<10) AND (y=22 OR true) => (x<10) +** (y=22) OR true => true +*/ +SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){ + assert( pExpr!=0 ); + if( pExpr->op==TK_AND || pExpr->op==TK_OR ){ + Expr *pRight = sqlite3ExprSimplifiedAndOr(pExpr->pRight); + Expr *pLeft = sqlite3ExprSimplifiedAndOr(pExpr->pLeft); + if( ExprAlwaysTrue(pLeft) || ExprAlwaysFalse(pRight) ){ + pExpr = pExpr->op==TK_AND ? pRight : pLeft; + }else if( ExprAlwaysTrue(pRight) || ExprAlwaysFalse(pLeft) ){ + pExpr = pExpr->op==TK_AND ? pLeft : pRight; + } + } + return pExpr; +} + +/* +** Return true if it might be advantageous to compute the right operand +** of expression pExpr first, before the left operand. +** +** Normally the left operand is computed before the right operand. But if +** the left operand contains a subquery and the right does not, then it +** might be more efficient to compute the right operand first. +*/ +static int exprEvalRhsFirst(Expr *pExpr){ + if( ExprHasProperty(pExpr->pLeft, EP_Subquery) + && !ExprHasProperty(pExpr->pRight, EP_Subquery) + ){ + return 1; + }else{ + return 0; + } +} + +/* +** Compute the two operands of a binary operator. +** +** If either operand contains a subquery, then the code strives to +** compute the operand containing the subquery second. If the other +** operand evalutes to NULL, then a jump is made. The address of the +** IsNull operand that does this jump is returned. The caller can use +** this to optimize the computation so as to avoid doing the potentially +** expensive subquery. +** +** If no optimization opportunities exist, return 0. +*/ +static int exprComputeOperands( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* The comparison expression */ + int *pR1, /* OUT: Register holding the left operand */ + int *pR2, /* OUT: Register holding the right operand */ + int *pFree1, /* OUT: Temp register to free if not zero */ + int *pFree2 /* OUT: Another temp register to free if not zero */ +){ + int addrIsNull; + int r1, r2; + Vdbe *v = pParse->pVdbe; + + assert( v!=0 ); + /* + ** If the left operand contains a (possibly expensive) subquery and the + ** right operand does not and the right operation might be NULL, + ** then compute the right operand first and do an IsNull jump if the + ** right operand evalutes to NULL. + */ + if( exprEvalRhsFirst(pExpr) && sqlite3ExprCanBeNull(pExpr->pRight) ){ + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, pFree2); + addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, r2); + VdbeComment((v, "skip left operand")); + VdbeCoverage(v); + }else{ + r2 = 0; /* Silence a false-positive uninit-var warning in MSVC */ + addrIsNull = 0; + } + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, pFree1); + if( addrIsNull==0 ){ + /* + ** If the right operand contains a subquery and the left operand does not + ** and the left operand might be NULL, then do an IsNull check + ** check on the left operand before computing the right operand. + */ + if( ExprHasProperty(pExpr->pRight, EP_Subquery) + && sqlite3ExprCanBeNull(pExpr->pLeft) + ){ + addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, r1); + VdbeComment((v, "skip right operand")); + VdbeCoverage(v); + } + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, pFree2); + } + *pR1 = r1; + *pR2 = r2; + return addrIsNull; +} + +/* +** pExpr is a TK_FUNCTION node. Try to determine whether or not the +** function is a constant function. A function is constant if all of +** the following are true: +** +** (1) It is a scalar function (not an aggregate or window function) +** (2) It has either the SQLITE_FUNC_CONSTANT or SQLITE_FUNC_SLOCHNG +** property. +** (3) All of its arguments are constants +** +** This routine sets pWalker->eCode to 0 if pExpr is not a constant. +** It makes no changes to pWalker->eCode if pExpr is constant. In +** every case, it returns WRC_Abort. +** +** Called as a service subroutine from exprNodeIsConstant(). +*/ +static SQLITE_NOINLINE int exprNodeIsConstantFunction( + Walker *pWalker, + Expr *pExpr +){ + int n; /* Number of arguments */ + ExprList *pList; /* List of arguments */ + FuncDef *pDef; /* The function */ + sqlite3 *db; /* The database */ + + assert( pExpr->op==TK_FUNCTION ); + if( ExprHasProperty(pExpr, EP_TokenOnly) + || (pList = pExpr->x.pList)==0 + ){; + n = 0; + }else{ + n = pList->nExpr; + sqlite3WalkExprList(pWalker, pList); + if( pWalker->eCode==0 ) return WRC_Abort; + } + db = pWalker->pParse->db; + pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0); + if( pDef==0 + || pDef->xFinalize!=0 + || (pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0 + || ExprHasProperty(pExpr, EP_WinFunc) + ){ + pWalker->eCode = 0; + return WRC_Abort; + } + return WRC_Prune; +} + + +/* +** These routines are Walker callbacks used to check expressions to +** see if they are "constant" for some definition of constant. The +** Walker.eCode value determines the type of "constant" we are looking +** for. +** +** These callback routines are used to implement the following: +** +** sqlite3ExprIsConstant() pWalker->eCode==1 +** sqlite3ExprIsConstantNotJoin() pWalker->eCode==2 +** sqlite3ExprIsTableConstant() pWalker->eCode==3 +** sqlite3ExprIsConstantOrFunction() pWalker->eCode==4 or 5 +** +** In all cases, the callbacks set Walker.eCode=0 and abort if the expression +** is found to not be a constant. +** +** The sqlite3ExprIsConstantOrFunction() is used for evaluating DEFAULT +** expressions in a CREATE TABLE statement. The Walker.eCode value is 5 +** when parsing an existing schema out of the sqlite_schema table and 4 +** when processing a new CREATE TABLE statement. A bound parameter raises +** an error for new statements, but is silently converted +** to NULL for existing schemas. This allows sqlite_schema tables that +** contain a bound parameter because they were generated by older versions +** of SQLite to be parsed by newer versions of SQLite without raising a +** malformed schema error. +*/ +static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ + assert( pWalker->eCode>0 ); + + /* If pWalker->eCode is 2 then any term of the expression that comes from + ** the ON or USING clauses of an outer join disqualifies the expression + ** from being considered constant. */ + if( pWalker->eCode==2 && ExprHasProperty(pExpr, EP_OuterON) ){ + pWalker->eCode = 0; + return WRC_Abort; + } + + switch( pExpr->op ){ + /* Consider functions to be constant if all their arguments are constant + ** and either pWalker->eCode==4 or 5 or the function has the + ** SQLITE_FUNC_CONST flag. */ + case TK_FUNCTION: + if( (pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_ConstFunc)) + && !ExprHasProperty(pExpr, EP_WinFunc) + ){ + if( pWalker->eCode==5 ) ExprSetProperty(pExpr, EP_FromDDL); + return WRC_Continue; + }else if( pWalker->pParse ){ + return exprNodeIsConstantFunction(pWalker, pExpr); + }else{ + pWalker->eCode = 0; + return WRC_Abort; + } + case TK_ID: + /* Convert "true" or "false" in a DEFAULT clause into the + ** appropriate TK_TRUEFALSE operator */ + if( sqlite3ExprIdToTrueFalse(pExpr) ){ + return WRC_Prune; + } + /* no break */ deliberate_fall_through + case TK_COLUMN: + case TK_AGG_FUNCTION: + case TK_AGG_COLUMN: + testcase( pExpr->op==TK_ID ); + testcase( pExpr->op==TK_COLUMN ); + testcase( pExpr->op==TK_AGG_FUNCTION ); + testcase( pExpr->op==TK_AGG_COLUMN ); + if( ExprHasProperty(pExpr, EP_FixedCol) && pWalker->eCode!=2 ){ + return WRC_Continue; + } + if( pWalker->eCode==3 && pExpr->iTable==pWalker->u.iCur ){ + return WRC_Continue; + } + /* no break */ deliberate_fall_through + case TK_IF_NULL_ROW: + case TK_REGISTER: + case TK_DOT: + case TK_RAISE: + testcase( pExpr->op==TK_REGISTER ); + testcase( pExpr->op==TK_IF_NULL_ROW ); + testcase( pExpr->op==TK_DOT ); + testcase( pExpr->op==TK_RAISE ); + pWalker->eCode = 0; + return WRC_Abort; + case TK_VARIABLE: + if( pWalker->eCode==5 ){ + /* Silently convert bound parameters that appear inside of CREATE + ** statements into a NULL when parsing the CREATE statement text out + ** of the sqlite_schema table */ + pExpr->op = TK_NULL; + }else if( pWalker->eCode==4 ){ + /* A bound parameter in a CREATE statement that originates from + ** sqlite3_prepare() causes an error */ + pWalker->eCode = 0; + return WRC_Abort; + } + /* no break */ deliberate_fall_through + default: + testcase( pExpr->op==TK_SELECT ); /* sqlite3SelectWalkFail() disallows */ + testcase( pExpr->op==TK_EXISTS ); /* sqlite3SelectWalkFail() disallows */ + return WRC_Continue; + } +} +static int exprIsConst(Parse *pParse, Expr *p, int initFlag){ + Walker w; + w.eCode = initFlag; + w.pParse = pParse; + w.xExprCallback = exprNodeIsConstant; + w.xSelectCallback = sqlite3SelectWalkFail; +#ifdef SQLITE_DEBUG + w.xSelectCallback2 = sqlite3SelectWalkAssert2; +#endif + sqlite3WalkExpr(&w, p); + return w.eCode; +} + +/* +** Walk an expression tree. Return non-zero if the expression is constant +** or return zero if the expression involves variables or function calls. +** +** For the purposes of this function, a double-quoted string (ex: "abc") +** is considered a variable but a single-quoted string (ex: 'abc') is +** a constant. +** +** The pParse parameter may be NULL. But if it is NULL, there is no way +** to determine if function calls are constant or not, and hence all +** function calls will be considered to be non-constant. If pParse is +** not NULL, then a function call might be constant, depending on the +** function and on its parameters. +*/ +SQLITE_PRIVATE int sqlite3ExprIsConstant(Parse *pParse, Expr *p){ + return exprIsConst(pParse, p, 1); +} + +/* +** Walk an expression tree. Return non-zero if +** +** (1) the expression is constant, and +** (2) the expression does originate in the ON or USING clause +** of a LEFT JOIN, and +** (3) the expression does not contain any EP_FixedCol TK_COLUMN +** operands created by the constant propagation optimization. +** +** When this routine returns true, it indicates that the expression +** can be added to the pParse->pConstExpr list and evaluated once when +** the prepared statement starts up. See sqlite3ExprCodeRunJustOnce(). +*/ +static int sqlite3ExprIsConstantNotJoin(Parse *pParse, Expr *p){ + return exprIsConst(pParse, p, 2); +} + +/* +** This routine examines sub-SELECT statements as an expression is being +** walked as part of sqlite3ExprIsTableConstant(). Sub-SELECTs are considered +** constant as long as they are uncorrelated - meaning that they do not +** contain any terms from outer contexts. +*/ +static int exprSelectWalkTableConstant(Walker *pWalker, Select *pSelect){ + assert( pSelect!=0 ); + assert( pWalker->eCode==3 || pWalker->eCode==0 ); + if( (pSelect->selFlags & SF_Correlated)!=0 ){ + pWalker->eCode = 0; + return WRC_Abort; + } + return WRC_Prune; +} + +/* +** Walk an expression tree. Return non-zero if the expression is constant +** for any single row of the table with cursor iCur. In other words, the +** expression must not refer to any non-deterministic function nor any +** table other than iCur. +** +** Consider uncorrelated subqueries to be constants if the bAllowSubq +** parameter is true. +*/ +static int sqlite3ExprIsTableConstant(Expr *p, int iCur, int bAllowSubq){ + Walker w; + w.eCode = 3; + w.pParse = 0; + w.xExprCallback = exprNodeIsConstant; + if( bAllowSubq ){ + w.xSelectCallback = exprSelectWalkTableConstant; + }else{ + w.xSelectCallback = sqlite3SelectWalkFail; +#ifdef SQLITE_DEBUG + w.xSelectCallback2 = sqlite3SelectWalkAssert2; +#endif + } + w.u.iCur = iCur; + sqlite3WalkExpr(&w, p); + return w.eCode; +} + +/* +** Check pExpr to see if it is an constraint on the single data source +** pSrc = &pSrcList->a[iSrc]. In other words, check to see if pExpr +** constrains pSrc but does not depend on any other tables or data +** sources anywhere else in the query. Return true (non-zero) if pExpr +** is a constraint on pSrc only. +** +** This is an optimization. False negatives will perhaps cause slower +** queries, but false positives will yield incorrect answers. So when in +** doubt, return 0. +** +** To be an single-source constraint, the following must be true: +** +** (1) pExpr cannot refer to any table other than pSrc->iCursor. +** +** (2a) pExpr cannot use subqueries unless the bAllowSubq parameter is +** true and the subquery is non-correlated +** +** (2b) pExpr cannot use non-deterministic functions. +** +** (3) pSrc cannot be part of the left operand for a RIGHT JOIN. +** (Is there some way to relax this constraint?) +** +** (4) If pSrc is the right operand of a LEFT JOIN, then... +** (4a) pExpr must come from an ON clause.. +** (4b) and specifically the ON clause associated with the LEFT JOIN. +** +** (5) If pSrc is the right operand of a LEFT JOIN or the left +** operand of a RIGHT JOIN, then pExpr must be from the WHERE +** clause, not an ON clause. +** +** (6) Either: +** +** (6a) pExpr does not originate in an ON or USING clause, or +** +** (6b) The ON or USING clause from which pExpr is derived is +** not to the left of a RIGHT JOIN (or FULL JOIN). +** +** Without this restriction, accepting pExpr as a single-table +** constraint might move the the ON/USING filter expression +** from the left side of a RIGHT JOIN over to the right side, +** which leads to incorrect answers. See also restriction (9) +** on push-down. +*/ +SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint( + Expr *pExpr, /* The constraint */ + const SrcList *pSrcList, /* Complete FROM clause */ + int iSrc, /* Which element of pSrcList to use */ + int bAllowSubq /* Allow non-correlated subqueries */ +){ + const SrcItem *pSrc = &pSrcList->a[iSrc]; + if( pSrc->fg.jointype & JT_LTORJ ){ + return 0; /* rule (3) */ + } + if( pSrc->fg.jointype & JT_LEFT ){ + if( !ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* rule (4a) */ + if( pExpr->w.iJoin!=pSrc->iCursor ) return 0; /* rule (4b) */ + }else{ + if( ExprHasProperty(pExpr, EP_OuterON) ) return 0; /* rule (5) */ + } + if( ExprHasProperty(pExpr, EP_OuterON|EP_InnerON) /* (6a) */ + && (pSrcList->a[0].fg.jointype & JT_LTORJ)!=0 /* Fast pre-test of (6b) */ + ){ + int jj; + for(jj=0; jjw.iJoin==pSrcList->a[jj].iCursor ){ + if( (pSrcList->a[jj].fg.jointype & JT_LTORJ)!=0 ){ + return 0; /* restriction (6) */ + } + break; + } + } + } + /* Rules (1), (2a), and (2b) handled by the following: */ + return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor, bAllowSubq); +} + + +/* +** sqlite3WalkExpr() callback used by sqlite3ExprIsConstantOrGroupBy(). +*/ +static int exprNodeIsConstantOrGroupBy(Walker *pWalker, Expr *pExpr){ + ExprList *pGroupBy = pWalker->u.pGroupBy; + int i; + + /* Check if pExpr is identical to any GROUP BY term. If so, consider + ** it constant. */ + for(i=0; inExpr; i++){ + Expr *p = pGroupBy->a[i].pExpr; + if( sqlite3ExprCompare(0, pExpr, p, -1)<2 ){ + CollSeq *pColl = sqlite3ExprNNCollSeq(pWalker->pParse, p); + if( sqlite3IsBinary(pColl) ){ + return WRC_Prune; + } + } + } + + /* Check if pExpr is a sub-select. If so, consider it variable. */ + if( ExprUseXSelect(pExpr) ){ + pWalker->eCode = 0; + return WRC_Abort; + } + + return exprNodeIsConstant(pWalker, pExpr); +} + +/* +** Walk the expression tree passed as the first argument. Return non-zero +** if the expression consists entirely of constants or copies of terms +** in pGroupBy that sort with the BINARY collation sequence. +** +** This routine is used to determine if a term of the HAVING clause can +** be promoted into the WHERE clause. In order for such a promotion to work, +** the value of the HAVING clause term must be the same for all members of +** a "group". The requirement that the GROUP BY term must be BINARY +** assumes that no other collating sequence will have a finer-grained +** grouping than binary. In other words (A=B COLLATE binary) implies +** A=B in every other collating sequence. The requirement that the +** GROUP BY be BINARY is stricter than necessary. It would also work +** to promote HAVING clauses that use the same alternative collating +** sequence as the GROUP BY term, but that is much harder to check, +** alternative collating sequences are uncommon, and this is only an +** optimization, so we take the easy way out and simply require the +** GROUP BY to use the BINARY collating sequence. +*/ +SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse *pParse, Expr *p, ExprList *pGroupBy){ + Walker w; + w.eCode = 1; + w.xExprCallback = exprNodeIsConstantOrGroupBy; + w.xSelectCallback = 0; + w.u.pGroupBy = pGroupBy; + w.pParse = pParse; + sqlite3WalkExpr(&w, p); + return w.eCode; +} + +/* +** Walk an expression tree for the DEFAULT field of a column definition +** in a CREATE TABLE statement. Return non-zero if the expression is +** acceptable for use as a DEFAULT. That is to say, return non-zero if +** the expression is constant or a function call with constant arguments. +** Return and 0 if there are any variables. +** +** isInit is true when parsing from sqlite_schema. isInit is false when +** processing a new CREATE TABLE statement. When isInit is true, parameters +** (such as ? or $abc) in the expression are converted into NULL. When +** isInit is false, parameters raise an error. Parameters should not be +** allowed in a CREATE TABLE statement, but some legacy versions of SQLite +** allowed it, so we need to support it when reading sqlite_schema for +** backwards compatibility. +** +** If isInit is true, set EP_FromDDL on every TK_FUNCTION node. +** +** For the purposes of this function, a double-quoted string (ex: "abc") +** is considered a variable but a single-quoted string (ex: 'abc') is +** a constant. +*/ +SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){ + assert( isInit==0 || isInit==1 ); + return exprIsConst(0, p, 4+isInit); +} + +#ifdef SQLITE_ENABLE_CURSOR_HINTS +/* +** Walk an expression tree. Return 1 if the expression contains a +** subquery of some kind. Return 0 if there are no subqueries. +*/ +SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr *p){ + Walker w; + w.eCode = 1; + w.xExprCallback = sqlite3ExprWalkNoop; + w.xSelectCallback = sqlite3SelectWalkFail; +#ifdef SQLITE_DEBUG + w.xSelectCallback2 = sqlite3SelectWalkAssert2; +#endif + sqlite3WalkExpr(&w, p); + return w.eCode==0; +} +#endif + +/* +** If the expression p codes a constant integer that is small enough +** to fit in a 32-bit integer, return 1 and put the value of the integer +** in *pValue. If the expression is not an integer or if it is too big +** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged. +** +** If the pParse pointer is provided, then allow the expression p to be +** a parameter (TK_VARIABLE) that is bound to an integer. +** But if pParse is NULL, then p must be a pure integer literal. +*/ +SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr *p, int *pValue, Parse *pParse){ + int rc = 0; + if( NEVER(p==0) ) return 0; /* Used to only happen following on OOM */ + + /* If an expression is an integer literal that fits in a signed 32-bit + ** integer, then the EP_IntValue flag will have already been set */ + assert( p->op!=TK_INTEGER || (p->flags & EP_IntValue)!=0 + || sqlite3GetInt32(p->u.zToken, &rc)==0 ); + + if( p->flags & EP_IntValue ){ + *pValue = p->u.iValue; + return 1; + } + switch( p->op ){ + case TK_UPLUS: { + rc = sqlite3ExprIsInteger(p->pLeft, pValue, 0); + break; + } + case TK_UMINUS: { + int v = 0; + if( sqlite3ExprIsInteger(p->pLeft, &v, 0) ){ + assert( ((unsigned int)v)!=0x80000000 ); + *pValue = -v; + rc = 1; + } + break; + } + case TK_VARIABLE: { + sqlite3_value *pVal; + if( pParse==0 ) break; + if( NEVER(pParse->pVdbe==0) ) break; + if( (pParse->db->flags & SQLITE_EnableQPSG)!=0 ) break; + sqlite3VdbeSetVarmask(pParse->pVdbe, p->iColumn); + pVal = sqlite3VdbeGetBoundValue(pParse->pReprepare, p->iColumn, + SQLITE_AFF_BLOB); + if( pVal ){ + if( sqlite3_value_type(pVal)==SQLITE_INTEGER ){ + sqlite3_int64 vv = sqlite3_value_int64(pVal); + if( vv == (vv & 0x7fffffff) ){ /* non-negative numbers only */ + *pValue = (int)vv; + rc = 1; + } + } + sqlite3ValueFree(pVal); + } + break; + } + default: break; + } + return rc; +} + +/* +** Return FALSE if there is no chance that the expression can be NULL. +** +** If the expression might be NULL or if the expression is too complex +** to tell return TRUE. +** +** This routine is used as an optimization, to skip OP_IsNull opcodes +** when we know that a value cannot be NULL. Hence, a false positive +** (returning TRUE when in fact the expression can never be NULL) might +** be a small performance hit but is otherwise harmless. On the other +** hand, a false negative (returning FALSE when the result could be NULL) +** will likely result in an incorrect answer. So when in doubt, return +** TRUE. +*/ +SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){ + u8 op; + assert( p!=0 ); + while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ + p = p->pLeft; + assert( p!=0 ); + } + op = p->op; + if( op==TK_REGISTER ) op = p->op2; + switch( op ){ + case TK_INTEGER: + case TK_STRING: + case TK_FLOAT: + case TK_BLOB: + return 0; + case TK_COLUMN: + assert( ExprUseYTab(p) ); + return ExprHasProperty(p, EP_CanBeNull) + || NEVER(p->y.pTab==0) /* Reference to column of index on expr */ +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + || (p->iColumn==XN_ROWID && IsView(p->y.pTab)) +#endif + || (p->iColumn>=0 + && p->y.pTab->aCol!=0 /* Possible due to prior error */ + && ALWAYS(p->iColumny.pTab->nCol) + && p->y.pTab->aCol[p->iColumn].notNull==0); + default: + return 1; + } +} + +/* +** Return TRUE if the given expression is a constant which would be +** unchanged by OP_Affinity with the affinity given in the second +** argument. +** +** This routine is used to determine if the OP_Affinity operation +** can be omitted. When in doubt return FALSE. A false negative +** is harmless. A false positive, however, can result in the wrong +** answer. +*/ +SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr *p, char aff){ + u8 op; + int unaryMinus = 0; + if( aff==SQLITE_AFF_BLOB ) return 1; + while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ + if( p->op==TK_UMINUS ) unaryMinus = 1; + p = p->pLeft; + } + op = p->op; + if( op==TK_REGISTER ) op = p->op2; + switch( op ){ + case TK_INTEGER: { + return aff>=SQLITE_AFF_NUMERIC; + } + case TK_FLOAT: { + return aff>=SQLITE_AFF_NUMERIC; + } + case TK_STRING: { + return !unaryMinus && aff==SQLITE_AFF_TEXT; + } + case TK_BLOB: { + return !unaryMinus; + } + case TK_COLUMN: { + assert( p->iTable>=0 ); /* p cannot be part of a CHECK constraint */ + return aff>=SQLITE_AFF_NUMERIC && p->iColumn<0; + } + default: { + return 0; + } + } +} + +/* +** Return TRUE if the given string is a row-id column name. +*/ +SQLITE_PRIVATE int sqlite3IsRowid(const char *z){ + if( sqlite3StrICmp(z, "_ROWID_")==0 ) return 1; + if( sqlite3StrICmp(z, "ROWID")==0 ) return 1; + if( sqlite3StrICmp(z, "OID")==0 ) return 1; + return 0; +} + +/* +** Return a pointer to a buffer containing a usable rowid alias for table +** pTab. An alias is usable if there is not an explicit user-defined column +** of the same name. +*/ +SQLITE_PRIVATE const char *sqlite3RowidAlias(Table *pTab){ + const char *azOpt[] = {"_ROWID_", "ROWID", "OID"}; + int ii; + assert( VisibleRowid(pTab) ); + for(ii=0; iix.pSelect; + if( p->pPrior ) return 0; /* Not a compound SELECT */ + if( p->selFlags & (SF_Distinct|SF_Aggregate) ){ + testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ); + testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate ); + return 0; /* No DISTINCT keyword and no aggregate functions */ + } + assert( p->pGroupBy==0 ); /* Has no GROUP BY clause */ + if( p->pLimit ) return 0; /* Has no LIMIT clause */ + if( p->pWhere ) return 0; /* Has no WHERE clause */ + pSrc = p->pSrc; + assert( pSrc!=0 ); + if( pSrc->nSrc!=1 ) return 0; /* Single term in FROM clause */ + if( pSrc->a[0].fg.isSubquery) return 0;/* FROM is not a subquery or view */ + pTab = pSrc->a[0].pSTab; + assert( pTab!=0 ); + assert( !IsView(pTab) ); /* FROM clause is not a view */ + if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */ + pEList = p->pEList; + assert( pEList!=0 ); + /* All SELECT results must be columns. */ + for(i=0; inExpr; i++){ + Expr *pRes = pEList->a[i].pExpr; + if( pRes->op!=TK_COLUMN ) return 0; + assert( pRes->iTable==pSrc->a[0].iCursor ); /* Not a correlated subquery */ + } + return p; +} +#endif /* SQLITE_OMIT_SUBQUERY */ + +#ifndef SQLITE_OMIT_SUBQUERY +/* +** Generate code that checks the left-most column of index table iCur to see if +** it contains any NULL entries. Cause the register at regHasNull to be set +** to a non-NULL value if iCur contains no NULLs. Cause register regHasNull +** to be set to NULL if iCur contains one or more NULL values. +*/ +static void sqlite3SetHasNullFlag(Vdbe *v, int iCur, int regHasNull){ + int addr1; + sqlite3VdbeAddOp2(v, OP_Integer, 0, regHasNull); + addr1 = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_Column, iCur, 0, regHasNull); + sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); + VdbeComment((v, "first_entry_in(%d)", iCur)); + sqlite3VdbeJumpHere(v, addr1); +} +#endif + + +#ifndef SQLITE_OMIT_SUBQUERY +/* +** The argument is an IN operator with a list (not a subquery) on the +** right-hand side. Return TRUE if that list is constant. +*/ +static int sqlite3InRhsIsConstant(Parse *pParse, Expr *pIn){ + Expr *pLHS; + int res; + assert( !ExprHasProperty(pIn, EP_xIsSelect) ); + pLHS = pIn->pLeft; + pIn->pLeft = 0; + res = sqlite3ExprIsConstant(pParse, pIn); + pIn->pLeft = pLHS; + return res; +} +#endif + +/* +** This function is used by the implementation of the IN (...) operator. +** The pX parameter is the expression on the RHS of the IN operator, which +** might be either a list of expressions or a subquery. +** +** The job of this routine is to find or create a b-tree object that can +** be used either to test for membership in the RHS set or to iterate through +** all members of the RHS set, skipping duplicates. +** +** A cursor is opened on the b-tree object that is the RHS of the IN operator +** and the *piTab parameter is set to the index of that cursor. +** +** The returned value of this function indicates the b-tree type, as follows: +** +** IN_INDEX_ROWID - The cursor was opened on a database table. +** IN_INDEX_INDEX_ASC - The cursor was opened on an ascending index. +** IN_INDEX_INDEX_DESC - The cursor was opened on a descending index. +** IN_INDEX_EPH - The cursor was opened on a specially created and +** populated ephemeral table. +** IN_INDEX_NOOP - No cursor was allocated. The IN operator must be +** implemented as a sequence of comparisons. +** +** An existing b-tree might be used if the RHS expression pX is a simple +** subquery such as: +** +** SELECT , ... FROM +** +** If the RHS of the IN operator is a list or a more complex subquery, then +** an ephemeral table might need to be generated from the RHS and then +** pX->iTable made to point to the ephemeral table instead of an +** existing table. In this case, the creation and initialization of the +** ephemeral table might be put inside of a subroutine, the EP_Subrtn flag +** will be set on pX and the pX->y.sub fields will be set to show where +** the subroutine is coded. +** +** The inFlags parameter must contain, at a minimum, one of the bits +** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP but not both. If inFlags contains +** IN_INDEX_MEMBERSHIP, then the generated table will be used for a fast +** membership test. When the IN_INDEX_LOOP bit is set, the IN index will +** be used to loop over all values of the RHS of the IN operator. +** +** When IN_INDEX_LOOP is used (and the b-tree will be used to iterate +** through the set members) then the b-tree must not contain duplicates. +** An ephemeral table will be created unless the selected columns are guaranteed +** to be unique - either because it is an INTEGER PRIMARY KEY or due to +** a UNIQUE constraint or index. +** +** When IN_INDEX_MEMBERSHIP is used (and the b-tree will be used +** for fast set membership tests) then an ephemeral table must +** be used unless is a single INTEGER PRIMARY KEY column or an +** index can be found with the specified as its left-most. +** +** If the IN_INDEX_NOOP_OK and IN_INDEX_MEMBERSHIP are both set and +** if the RHS of the IN operator is a list (not a subquery) then this +** routine might decide that creating an ephemeral b-tree for membership +** testing is too expensive and return IN_INDEX_NOOP. In that case, the +** calling routine should implement the IN operator using a sequence +** of Eq or Ne comparison operations. +** +** When the b-tree is being used for membership tests, the calling function +** might need to know whether or not the RHS side of the IN operator +** contains a NULL. If prRhsHasNull is not a NULL pointer and +** if there is any chance that the (...) might contain a NULL value at +** runtime, then a register is allocated and the register number written +** to *prRhsHasNull. If there is no chance that the (...) contains a +** NULL value, then *prRhsHasNull is left unchanged. +** +** If a register is allocated and its location stored in *prRhsHasNull, then +** the value in that register will be NULL if the b-tree contains one or more +** NULL values, and it will be some non-NULL value if the b-tree contains no +** NULL values. +** +** If the aiMap parameter is not NULL, it must point to an array containing +** one element for each column returned by the SELECT statement on the RHS +** of the IN(...) operator. The i'th entry of the array is populated with the +** offset of the index column that matches the i'th column returned by the +** SELECT. For example, if the expression and selected index are: +** +** (?,?,?) IN (SELECT a, b, c FROM t1) +** CREATE INDEX i1 ON t1(b, c, a); +** +** then aiMap[] is populated with {2, 0, 1}. +*/ +#ifndef SQLITE_OMIT_SUBQUERY +SQLITE_PRIVATE int sqlite3FindInIndex( + Parse *pParse, /* Parsing context */ + Expr *pX, /* The IN expression */ + u32 inFlags, /* IN_INDEX_LOOP, _MEMBERSHIP, and/or _NOOP_OK */ + int *prRhsHasNull, /* Register holding NULL status. See notes */ + int *aiMap, /* Mapping from Index fields to RHS fields */ + int *piTab /* OUT: index to use */ +){ + Select *p; /* SELECT to the right of IN operator */ + int eType = 0; /* Type of RHS table. IN_INDEX_* */ + int iTab; /* Cursor of the RHS table */ + int mustBeUnique; /* True if RHS must be unique */ + Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ + + assert( pX->op==TK_IN ); + mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0; + iTab = pParse->nTab++; + + /* If the RHS of this IN(...) operator is a SELECT, and if it matters + ** whether or not the SELECT result contains NULL values, check whether + ** or not NULL is actually possible (it may not be, for example, due + ** to NOT NULL constraints in the schema). If no NULL values are possible, + ** set prRhsHasNull to 0 before continuing. */ + if( prRhsHasNull && ExprUseXSelect(pX) ){ + int i; + ExprList *pEList = pX->x.pSelect->pEList; + for(i=0; inExpr; i++){ + if( sqlite3ExprCanBeNull(pEList->a[i].pExpr) ) break; + } + if( i==pEList->nExpr ){ + prRhsHasNull = 0; + } + } + + /* Check to see if an existing table or index can be used to + ** satisfy the query. This is preferable to generating a new + ** ephemeral table. */ + if( pParse->nErr==0 && (p = isCandidateForInOpt(pX))!=0 ){ + sqlite3 *db = pParse->db; /* Database connection */ + Table *pTab; /* Table
    . */ + int iDb; /* Database idx for pTab */ + ExprList *pEList = p->pEList; + int nExpr = pEList->nExpr; + + assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */ + assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */ + assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */ + pTab = p->pSrc->a[0].pSTab; + + /* Code an OP_Transaction and OP_TableLock for
    . */ + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iDb>=0 && iDbtnum, 0, pTab->zName); + + assert(v); /* sqlite3GetVdbe() has always been previously called */ + if( nExpr==1 && pEList->a[0].pExpr->iColumn<0 ){ + /* The "x IN (SELECT rowid FROM table)" case */ + int iAddr = sqlite3VdbeAddOp0(v, OP_Once); + VdbeCoverage(v); + + sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); + eType = IN_INDEX_ROWID; + ExplainQueryPlan((pParse, 0, + "USING ROWID SEARCH ON TABLE %s FOR IN-OPERATOR",pTab->zName)); + sqlite3VdbeJumpHere(v, iAddr); + }else{ + Index *pIdx; /* Iterator variable */ + int affinity_ok = 1; + int i; + + /* Check that the affinity that will be used to perform each + ** comparison is the same as the affinity of each column in table + ** on the RHS of the IN operator. If it not, it is not possible to + ** use any index of the RHS table. */ + for(i=0; ipLeft, i); + int iCol = pEList->a[i].pExpr->iColumn; + char idxaff = sqlite3TableColumnAffinity(pTab,iCol); /* RHS table */ + char cmpaff = sqlite3CompareAffinity(pLhs, idxaff); + testcase( cmpaff==SQLITE_AFF_BLOB ); + testcase( cmpaff==SQLITE_AFF_TEXT ); + switch( cmpaff ){ + case SQLITE_AFF_BLOB: + break; + case SQLITE_AFF_TEXT: + /* sqlite3CompareAffinity() only returns TEXT if one side or the + ** other has no affinity and the other side is TEXT. Hence, + ** the only way for cmpaff to be TEXT is for idxaff to be TEXT + ** and for the term on the LHS of the IN to have no affinity. */ + assert( idxaff==SQLITE_AFF_TEXT ); + break; + default: + affinity_ok = sqlite3IsNumericAffinity(idxaff); + } + } + + if( affinity_ok ){ + /* Search for an existing index that will work for this IN operator */ + for(pIdx=pTab->pIndex; pIdx && eType==0; pIdx=pIdx->pNext){ + Bitmask colUsed; /* Columns of the index used */ + Bitmask mCol; /* Mask for the current column */ + if( pIdx->nColumnpPartIdxWhere!=0 ) continue; + /* Maximum nColumn is BMS-2, not BMS-1, so that we can compute + ** BITMASK(nExpr) without overflowing */ + testcase( pIdx->nColumn==BMS-2 ); + testcase( pIdx->nColumn==BMS-1 ); + if( pIdx->nColumn>=BMS-1 ) continue; + if( mustBeUnique ){ + if( pIdx->nKeyCol>nExpr + ||(pIdx->nColumn>nExpr && !IsUniqueIndex(pIdx)) + ){ + continue; /* This index is not unique over the IN RHS columns */ + } + } + + colUsed = 0; /* Columns of index used so far */ + for(i=0; ipLeft, i); + Expr *pRhs = pEList->a[i].pExpr; + CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); + int j; + + for(j=0; jaiColumn[j]!=pRhs->iColumn ) continue; + assert( pIdx->azColl[j] ); + if( pReq!=0 && sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ){ + continue; + } + break; + } + if( j==nExpr ) break; + mCol = MASKBIT(j); + if( mCol & colUsed ) break; /* Each column used only once */ + colUsed |= mCol; + if( aiMap ) aiMap[i] = j; + } + + assert( nExpr>0 && nExprzName)); + sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIdx); + VdbeComment((v, "%s", pIdx->zName)); + assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 ); + eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0]; + + if( prRhsHasNull ){ +#ifdef SQLITE_ENABLE_COLUMN_USED_MASK + i64 mask = (1<nMem; + if( nExpr==1 ){ + sqlite3SetHasNullFlag(v, iTab, *prRhsHasNull); + } + } + sqlite3VdbeJumpHere(v, iAddr); + } + } /* End loop over indexes */ + } /* End if( affinity_ok ) */ + } /* End if not an rowid index */ + } /* End attempt to optimize using an index */ + + /* If no preexisting index is available for the IN clause + ** and IN_INDEX_NOOP is an allowed reply + ** and the RHS of the IN operator is a list, not a subquery + ** and the RHS is not constant or has two or fewer terms, + ** then it is not worth creating an ephemeral table to evaluate + ** the IN operator so return IN_INDEX_NOOP. + */ + if( eType==0 + && (inFlags & IN_INDEX_NOOP_OK) + && ExprUseXList(pX) + && (!sqlite3InRhsIsConstant(pParse,pX) || pX->x.pList->nExpr<=2) + ){ + pParse->nTab--; /* Back out the allocation of the unused cursor */ + iTab = -1; /* Cursor is not allocated */ + eType = IN_INDEX_NOOP; + } + + if( eType==0 ){ + /* Could not find an existing table or index to use as the RHS b-tree. + ** We will have to generate an ephemeral table to do the job. + */ + u32 savedNQueryLoop = pParse->nQueryLoop; + int rMayHaveNull = 0; + int bloomOk = (inFlags & IN_INDEX_MEMBERSHIP)!=0; + eType = IN_INDEX_EPH; + if( inFlags & IN_INDEX_LOOP ){ + pParse->nQueryLoop = 0; + }else if( prRhsHasNull ){ + *prRhsHasNull = rMayHaveNull = ++pParse->nMem; + } + assert( pX->op==TK_IN ); + if( !bloomOk + && ExprUseXSelect(pX) + && (pX->x.pSelect->selFlags & SF_ClonedRhsIn)!=0 + ){ + bloomOk = 1; + } + sqlite3CodeRhsOfIN(pParse, pX, iTab, bloomOk); + if( rMayHaveNull ){ + sqlite3SetHasNullFlag(v, iTab, rMayHaveNull); + } + pParse->nQueryLoop = savedNQueryLoop; + } + + if( aiMap && eType!=IN_INDEX_INDEX_ASC && eType!=IN_INDEX_INDEX_DESC ){ + int i, n; + n = sqlite3ExprVectorSize(pX->pLeft); + for(i=0; ipLeft; + int nVal = sqlite3ExprVectorSize(pLeft); + Select *pSelect = ExprUseXSelect(pExpr) ? pExpr->x.pSelect : 0; + char *zRet; + + assert( pExpr->op==TK_IN ); + zRet = sqlite3DbMallocRaw(pParse->db, 1+(i64)nVal); + if( zRet ){ + int i; + for(i=0; ipEList->a[i].pExpr, a); + }else{ + zRet[i] = a; + } + } + zRet[nVal] = '\0'; + } + return zRet; +} +#endif + +#ifndef SQLITE_OMIT_SUBQUERY +/* +** Load the Parse object passed as the first argument with an error +** message of the form: +** +** "sub-select returns N columns - expected M" +*/ +SQLITE_PRIVATE void sqlite3SubselectError(Parse *pParse, int nActual, int nExpect){ + if( pParse->nErr==0 ){ + const char *zFmt = "sub-select returns %d columns - expected %d"; + sqlite3ErrorMsg(pParse, zFmt, nActual, nExpect); + } +} +#endif + +/* +** Expression pExpr is a vector that has been used in a context where +** it is not permitted. If pExpr is a sub-select vector, this routine +** loads the Parse object with a message of the form: +** +** "sub-select returns N columns - expected 1" +** +** Or, if it is a regular scalar vector: +** +** "row value misused" +*/ +SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){ +#ifndef SQLITE_OMIT_SUBQUERY + if( ExprUseXSelect(pExpr) ){ + sqlite3SubselectError(pParse, pExpr->x.pSelect->pEList->nExpr, 1); + }else +#endif + { + sqlite3ErrorMsg(pParse, "row value misused"); + } +} + +#ifndef SQLITE_OMIT_SUBQUERY +/* +** Scan all previously generated bytecode looking for an OP_BeginSubrtn +** that is compatible with pExpr. If found, add the y.sub values +** to pExpr and return true. If not found, return false. +*/ +static int findCompatibleInRhsSubrtn( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* IN operator with RHS that we want to reuse */ + SubrtnSig *pNewSig /* Signature for the IN operator */ +){ + VdbeOp *pOp, *pEnd; + SubrtnSig *pSig; + Vdbe *v; + + if( pNewSig==0 ) return 0; + if( (pParse->mSubrtnSig & (1<<(pNewSig->selId&7)))==0 ) return 0; + assert( pExpr->op==TK_IN ); + assert( !ExprUseYSub(pExpr) ); + assert( ExprUseXSelect(pExpr) ); + assert( pExpr->x.pSelect!=0 ); + assert( (pExpr->x.pSelect->selFlags & SF_All)==0 ); + v = pParse->pVdbe; + assert( v!=0 ); + pOp = sqlite3VdbeGetOp(v, 1); + pEnd = sqlite3VdbeGetLastOp(v); + for(; pOpp4type!=P4_SUBRTNSIG ) continue; + assert( pOp->opcode==OP_BeginSubrtn ); + pSig = pOp->p4.pSubrtnSig; + assert( pSig!=0 ); + if( !pSig->bComplete ) continue; + if( pNewSig->selId!=pSig->selId ) continue; + if( strcmp(pNewSig->zAff,pSig->zAff)!=0 ) continue; + pExpr->y.sub.iAddr = pSig->iAddr; + pExpr->y.sub.regReturn = pSig->regReturn; + pExpr->iTable = pSig->iTable; + ExprSetProperty(pExpr, EP_Subrtn); + return 1; + } + return 0; +} +#endif /* SQLITE_OMIT_SUBQUERY */ + +#ifndef SQLITE_OMIT_SUBQUERY +/* +** Generate code that will construct an ephemeral table containing all terms +** in the RHS of an IN operator. The IN operator can be in either of two +** forms: +** +** x IN (4,5,11) -- IN operator with list on right-hand side +** x IN (SELECT a FROM b) -- IN operator with subquery on the right +** +** The pExpr parameter is the IN operator. The cursor number for the +** constructed ephemeral table is returned. The first time the ephemeral +** table is computed, the cursor number is also stored in pExpr->iTable, +** however the cursor number returned might not be the same, as it might +** have been duplicated using OP_OpenDup. +** +** If the LHS expression ("x" in the examples) is a column value, or +** the SELECT statement returns a column value, then the affinity of that +** column is used to build the index keys. If both 'x' and the +** SELECT... statement are columns, then numeric affinity is used +** if either column has NUMERIC or INTEGER affinity. If neither +** 'x' nor the SELECT... statement are columns, then numeric affinity +** is used. +*/ +SQLITE_PRIVATE void sqlite3CodeRhsOfIN( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* The IN operator */ + int iTab, /* Use this cursor number */ + int allowBloom /* True to allow the use of a Bloom filter */ +){ + int addrOnce = 0; /* Address of the OP_Once instruction at top */ + int addr; /* Address of OP_OpenEphemeral instruction */ + Expr *pLeft; /* the LHS of the IN operator */ + KeyInfo *pKeyInfo = 0; /* Key information */ + int nVal; /* Size of vector pLeft */ + Vdbe *v; /* The prepared statement under construction */ + SubrtnSig *pSig = 0; /* Signature for this subroutine */ + + v = pParse->pVdbe; + assert( v!=0 ); + + /* The evaluation of the IN must be repeated every time it + ** is encountered if any of the following is true: + ** + ** * The right-hand side is a correlated subquery + ** * The right-hand side is an expression list containing variables + ** * We are inside a trigger + ** + ** If all of the above are false, then we can compute the RHS just once + ** and reuse it many names. + */ + if( !ExprHasProperty(pExpr, EP_VarSelect) && pParse->iSelfTab==0 ){ + /* Reuse of the RHS is allowed + ** + ** Compute a signature for the RHS of the IN operator to facility + ** finding and reusing prior instances of the same IN operator. + */ + assert( !ExprUseXSelect(pExpr) || pExpr->x.pSelect!=0 ); + if( ExprUseXSelect(pExpr) && (pExpr->x.pSelect->selFlags & SF_All)==0 ){ + pSig = sqlite3DbMallocRawNN(pParse->db, sizeof(pSig[0])); + if( pSig ){ + pSig->selId = pExpr->x.pSelect->selId; + pSig->zAff = exprINAffinity(pParse, pExpr); + } + } + + /* Check to see if there is a prior materialization of the RHS of + ** this IN operator. If there is, then make use of that prior + ** materialization rather than recomputing it. + */ + if( ExprHasProperty(pExpr, EP_Subrtn) + || findCompatibleInRhsSubrtn(pParse, pExpr, pSig) + ){ + addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + if( ExprUseXSelect(pExpr) ){ + ExplainQueryPlan((pParse, 0, "REUSE LIST SUBQUERY %d", + pExpr->x.pSelect->selId)); + } + assert( ExprUseYSub(pExpr) ); + sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, + pExpr->y.sub.iAddr); + assert( iTab!=pExpr->iTable ); + sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable); + sqlite3VdbeJumpHere(v, addrOnce); + if( pSig ){ + sqlite3DbFree(pParse->db, pSig->zAff); + sqlite3DbFree(pParse->db, pSig); + } + return; + } + + /* Begin coding the subroutine */ + assert( !ExprUseYWin(pExpr) ); + ExprSetProperty(pExpr, EP_Subrtn); + assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); + pExpr->y.sub.regReturn = ++pParse->nMem; + pExpr->y.sub.iAddr = + sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1; + if( pSig ){ + pSig->bComplete = 0; + pSig->iAddr = pExpr->y.sub.iAddr; + pSig->regReturn = pExpr->y.sub.regReturn; + pSig->iTable = iTab; + pParse->mSubrtnSig = 1 << (pSig->selId&7); + sqlite3VdbeChangeP4(v, -1, (const char*)pSig, P4_SUBRTNSIG); + } + addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + } + + /* Check to see if this is a vector IN operator */ + pLeft = pExpr->pLeft; + nVal = sqlite3ExprVectorSize(pLeft); + + /* Construct the ephemeral table that will contain the content of + ** RHS of the IN operator. + */ + pExpr->iTable = iTab; + addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, nVal); +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + if( ExprUseXSelect(pExpr) ){ + VdbeComment((v, "Result of SELECT %u", pExpr->x.pSelect->selId)); + }else{ + VdbeComment((v, "RHS of IN operator")); + } +#endif + pKeyInfo = sqlite3KeyInfoAlloc(pParse->db, nVal, 1); + + if( ExprUseXSelect(pExpr) ){ + /* Case 1: expr IN (SELECT ...) + ** + ** Generate code to write the results of the select into the temporary + ** table allocated and opened above. + */ + Select *pSelect = pExpr->x.pSelect; + ExprList *pEList = pSelect->pEList; + + ExplainQueryPlan((pParse, 1, "%sLIST SUBQUERY %d", + addrOnce?"":"CORRELATED ", pSelect->selId + )); + /* If the LHS and RHS of the IN operator do not match, that + ** error will have been caught long before we reach this point. */ + if( ALWAYS(pEList->nExpr==nVal) ){ + Select *pCopy; + SelectDest dest; + int i; + int rc; + int addrBloom = 0; + sqlite3SelectDestInit(&dest, SRT_Set, iTab); + dest.zAffSdst = exprINAffinity(pParse, pExpr); + pSelect->iLimit = 0; + if( addrOnce + && allowBloom + && OptimizationEnabled(pParse->db, SQLITE_BloomFilter) + ){ + int regBloom = ++pParse->nMem; + addrBloom = sqlite3VdbeAddOp2(v, OP_Blob, 10000, regBloom); + VdbeComment((v, "Bloom filter")); + dest.iSDParm2 = regBloom; + } + testcase( pSelect->selFlags & SF_Distinct ); + testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ + pCopy = sqlite3SelectDup(pParse->db, pSelect, 0); + rc = pParse->db->mallocFailed ? 1 :sqlite3Select(pParse, pCopy, &dest); + sqlite3SelectDelete(pParse->db, pCopy); + sqlite3DbFree(pParse->db, dest.zAffSdst); + if( addrBloom ){ + /* Remember that location of the Bloom filter in the P3 operand + ** of the OP_Once that began this subroutine. tag-202407032019 */ + sqlite3VdbeGetOp(v, addrOnce)->p3 = dest.iSDParm2; + if( dest.iSDParm2==0 ){ + /* If the Bloom filter won't actually be used, keep it small */ + sqlite3VdbeGetOp(v, addrBloom)->p1 = 10; + } + } + if( rc ){ + sqlite3KeyInfoUnref(pKeyInfo); + return; + } + assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */ + assert( pEList!=0 ); + assert( pEList->nExpr>0 ); + assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); + for(i=0; iaColl[i] = sqlite3BinaryCompareCollSeq( + pParse, p, pEList->a[i].pExpr + ); + } + } + }else if( ALWAYS(pExpr->x.pList!=0) ){ + /* Case 2: expr IN (exprlist) + ** + ** For each expression, build an index key from the evaluation and + ** store it in the temporary table. If is a column, then use + ** that columns affinity when building index keys. If is not + ** a column, use numeric affinity. + */ + char affinity; /* Affinity of the LHS of the IN */ + int i; + ExprList *pList = pExpr->x.pList; + struct ExprList_item *pItem; + int r1, r2; + affinity = sqlite3ExprAffinity(pLeft); + if( affinity<=SQLITE_AFF_NONE ){ + affinity = SQLITE_AFF_BLOB; + }else if( affinity==SQLITE_AFF_REAL ){ + affinity = SQLITE_AFF_NUMERIC; + } + if( pKeyInfo ){ + assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); + pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft); + } + + /* Loop through each expression in . */ + r1 = sqlite3GetTempReg(pParse); + r2 = sqlite3GetTempReg(pParse); + for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){ + Expr *pE2 = pItem->pExpr; + + /* If the expression is not constant then we will need to + ** disable the test that was generated above that makes sure + ** this code only executes once. Because for a non-constant + ** expression we need to rerun this code each time. + */ + if( addrOnce && !sqlite3ExprIsConstant(pParse, pE2) ){ + sqlite3VdbeChangeToNoop(v, addrOnce-1); + sqlite3VdbeChangeToNoop(v, addrOnce); + ExprClearProperty(pExpr, EP_Subrtn); + addrOnce = 0; + } + + /* Evaluate the expression and insert it into the temp table */ + sqlite3ExprCode(pParse, pE2, r1); + sqlite3VdbeAddOp4(v, OP_MakeRecord, r1, 1, r2, &affinity, 1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r1, 1); + } + sqlite3ReleaseTempReg(pParse, r1); + sqlite3ReleaseTempReg(pParse, r2); + } + if( pSig ) pSig->bComplete = 1; + if( pKeyInfo ){ + sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO); + } + if( addrOnce ){ + sqlite3VdbeAddOp1(v, OP_NullRow, iTab); + sqlite3VdbeJumpHere(v, addrOnce); + /* Subroutine return */ + assert( ExprUseYSub(pExpr) ); + assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn + || pParse->nErr ); + sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, + pExpr->y.sub.iAddr, 1); + VdbeCoverage(v); + sqlite3ClearTempRegCache(pParse); + } +} +#endif /* SQLITE_OMIT_SUBQUERY */ + +/* +** Generate code for scalar subqueries used as a subquery expression +** or EXISTS operator: +** +** (SELECT a FROM b) -- subquery +** EXISTS (SELECT a FROM b) -- EXISTS subquery +** +** The pExpr parameter is the SELECT or EXISTS operator to be coded. +** +** Return the register that holds the result. For a multi-column SELECT, +** the result is stored in a contiguous array of registers and the +** return value is the register of the left-most result column. +** Return 0 if an error occurs. +*/ +#ifndef SQLITE_OMIT_SUBQUERY +SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ + int addrOnce = 0; /* Address of OP_Once at top of subroutine */ + int rReg = 0; /* Register storing resulting */ + Select *pSel; /* SELECT statement to encode */ + SelectDest dest; /* How to deal with SELECT result */ + int nReg; /* Registers to allocate */ + Expr *pLimit; /* New limit expression */ +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + int addrExplain; /* Address of OP_Explain instruction */ +#endif + + Vdbe *v = pParse->pVdbe; + assert( v!=0 ); + if( pParse->nErr ) return 0; + testcase( pExpr->op==TK_EXISTS ); + testcase( pExpr->op==TK_SELECT ); + assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT ); + assert( ExprUseXSelect(pExpr) ); + pSel = pExpr->x.pSelect; + + /* If this routine has already been coded, then invoke it as a + ** subroutine. */ + if( ExprHasProperty(pExpr, EP_Subrtn) ){ + ExplainQueryPlan((pParse, 0, "REUSE SUBQUERY %d", pSel->selId)); + assert( ExprUseYSub(pExpr) ); + sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, + pExpr->y.sub.iAddr); + return pExpr->iTable; + } + + /* Begin coding the subroutine */ + assert( !ExprUseYWin(pExpr) ); + assert( !ExprHasProperty(pExpr, EP_Reduced|EP_TokenOnly) ); + ExprSetProperty(pExpr, EP_Subrtn); + pExpr->y.sub.regReturn = ++pParse->nMem; + pExpr->y.sub.iAddr = + sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1; + + /* The evaluation of the EXISTS/SELECT must be repeated every time it + ** is encountered if any of the following is true: + ** + ** * The right-hand side is a correlated subquery + ** * The right-hand side is an expression list containing variables + ** * We are inside a trigger + ** + ** If all of the above are false, then we can run this code just once + ** save the results, and reuse the same result on subsequent invocations. + */ + if( !ExprHasProperty(pExpr, EP_VarSelect) ){ + addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + } + + /* For a SELECT, generate code to put the values for all columns of + ** the first row into an array of registers and return the index of + ** the first register. + ** + ** If this is an EXISTS, write an integer 0 (not exists) or 1 (exists) + ** into a register and return that register number. + ** + ** In both cases, the query is augmented with "LIMIT 1". Any + ** preexisting limit is discarded in place of the new LIMIT 1. + */ + ExplainQueryPlan2(addrExplain, (pParse, 1, "%sSCALAR SUBQUERY %d", + addrOnce?"":"CORRELATED ", pSel->selId)); + sqlite3VdbeScanStatusCounters(v, addrExplain, addrExplain, -1); + nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1; + sqlite3SelectDestInit(&dest, 0, pParse->nMem+1); + pParse->nMem += nReg; + if( pExpr->op==TK_SELECT ){ + dest.eDest = SRT_Mem; + if( (pSel->selFlags&SF_Distinct) && pSel->pLimit && pSel->pLimit->pRight ){ + /* If there is both a DISTINCT and an OFFSET clause, then allocate + ** a separate dest.iSdst array for sqlite3Select() and other + ** routines to populate. In this case results will be copied over + ** into the dest.iSDParm array only after OFFSET processing. This + ** ensures that in the case where OFFSET excludes all rows, the + ** dest.iSDParm array is not left populated with the contents of the + ** last row visited - it should be all NULLs if all rows were + ** excluded by OFFSET. */ + dest.iSdst = pParse->nMem+1; + pParse->nMem += nReg; + }else{ + dest.iSdst = dest.iSDParm; + } + dest.nSdst = nReg; + sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, pParse->nMem); + VdbeComment((v, "Init subquery result")); + }else{ + dest.eDest = SRT_Exists; + sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm); + VdbeComment((v, "Init EXISTS result")); + } + if( pSel->pLimit ){ + /* The subquery already has a limit. If the pre-existing limit X is + ** not already integer value 1 or 0, then make the new limit X<>0 so that + ** the new limit is either 1 or 0 */ + Expr *pLeft = pSel->pLimit->pLeft; + if( ExprHasProperty(pLeft, EP_IntValue)==0 + || (pLeft->u.iValue!=1 && pLeft->u.iValue!=0) + ){ + sqlite3 *db = pParse->db; + pLimit = sqlite3ExprInt32(db, 0); + if( pLimit ){ + pLimit->affExpr = SQLITE_AFF_NUMERIC; + pLimit = sqlite3PExpr(pParse, TK_NE, + sqlite3ExprDup(db, pLeft, 0), pLimit); + } + sqlite3ExprDeferredDelete(pParse, pLeft); + pSel->pLimit->pLeft = pLimit; + } + }else{ + /* If there is no pre-existing limit add a limit of 1 */ + pLimit = sqlite3ExprInt32(pParse->db, 1); + pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0); + } + pSel->iLimit = 0; + if( sqlite3Select(pParse, pSel, &dest) ){ + pExpr->op2 = pExpr->op; + pExpr->op = TK_ERROR; + return 0; + } + pExpr->iTable = rReg = dest.iSDParm; + ExprSetVVAProperty(pExpr, EP_NoReduce); + if( addrOnce ){ + sqlite3VdbeJumpHere(v, addrOnce); + } + sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1); + + /* Subroutine return */ + assert( ExprUseYSub(pExpr) ); + assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn + || pParse->nErr ); + sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, + pExpr->y.sub.iAddr, 1); + VdbeCoverage(v); + sqlite3ClearTempRegCache(pParse); + return rReg; +} +#endif /* SQLITE_OMIT_SUBQUERY */ + +#ifndef SQLITE_OMIT_SUBQUERY +/* +** Expr pIn is an IN(...) expression. This function checks that the +** sub-select on the RHS of the IN() operator has the same number of +** columns as the vector on the LHS. Or, if the RHS of the IN() is not +** a sub-query, that the LHS is a vector of size 1. +*/ +SQLITE_PRIVATE int sqlite3ExprCheckIN(Parse *pParse, Expr *pIn){ + int nVector = sqlite3ExprVectorSize(pIn->pLeft); + if( ExprUseXSelect(pIn) && !pParse->db->mallocFailed ){ + if( nVector!=pIn->x.pSelect->pEList->nExpr ){ + sqlite3SubselectError(pParse, pIn->x.pSelect->pEList->nExpr, nVector); + return 1; + } + }else if( nVector!=1 ){ + sqlite3VectorErrorMsg(pParse, pIn->pLeft); + return 1; + } + return 0; +} +#endif + +#ifndef SQLITE_OMIT_SUBQUERY +/* +** Generate code for an IN expression. +** +** x IN (SELECT ...) +** x IN (value, value, ...) +** +** The left-hand side (LHS) is a scalar or vector expression. The +** right-hand side (RHS) is an array of zero or more scalar values, or a +** subquery. If the RHS is a subquery, the number of result columns must +** match the number of columns in the vector on the LHS. If the RHS is +** a list of values, the LHS must be a scalar. +** +** The IN operator is true if the LHS value is contained within the RHS. +** The result is false if the LHS is definitely not in the RHS. The +** result is NULL if the presence of the LHS in the RHS cannot be +** determined due to NULLs. +** +** This routine generates code that jumps to destIfFalse if the LHS is not +** contained within the RHS. If due to NULLs we cannot determine if the LHS +** is contained in the RHS then jump to destIfNull. If the LHS is contained +** within the RHS then fall through. +** +** See the separate in-operator.md documentation file in the canonical +** SQLite source tree for additional information. +*/ +static void sqlite3ExprCodeIN( + Parse *pParse, /* Parsing and code generating context */ + Expr *pExpr, /* The IN expression */ + int destIfFalse, /* Jump here if LHS is not contained in the RHS */ + int destIfNull /* Jump here if the results are unknown due to NULLs */ +){ + int rRhsHasNull = 0; /* Register that is true if RHS contains NULL values */ + int eType; /* Type of the RHS */ + int rLhs; /* Register(s) holding the LHS values */ + Vdbe *v; /* Statement under construction */ + int *aiMap = 0; /* Map from vector field to index column */ + char *zAff = 0; /* Affinity string for comparisons */ + int nVector; /* Size of vectors for this IN operator */ + int iDummy; /* Dummy parameter to exprCodeVector() */ + Expr *pLeft; /* The LHS of the IN operator */ + int i; /* loop counter */ + int destStep2; /* Where to jump when NULLs seen in step 2 */ + int destStep6 = 0; /* Start of code for Step 6 */ + int addrTruthOp; /* Address of opcode that determines the IN is true */ + int destNotNull; /* Jump here if a comparison is not true in step 6 */ + int addrTop; /* Top of the step-6 loop */ + int iTab = 0; /* Index to use */ + u8 okConstFactor = pParse->okConstFactor; + + assert( !ExprHasVVAProperty(pExpr,EP_Immutable) ); + pLeft = pExpr->pLeft; + if( sqlite3ExprCheckIN(pParse, pExpr) ) return; + zAff = exprINAffinity(pParse, pExpr); + nVector = sqlite3ExprVectorSize(pExpr->pLeft); + aiMap = (int*)sqlite3DbMallocZero(pParse->db, nVector*sizeof(int)); + if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error; + + /* Attempt to compute the RHS. After this step, if anything other than + ** IN_INDEX_NOOP is returned, the table opened with cursor iTab + ** contains the values that make up the RHS. If IN_INDEX_NOOP is returned, + ** the RHS has not yet been coded. */ + v = pParse->pVdbe; + assert( v!=0 ); /* OOM detected prior to this routine */ + VdbeNoopComment((v, "begin IN expr")); + eType = sqlite3FindInIndex(pParse, pExpr, + IN_INDEX_MEMBERSHIP | IN_INDEX_NOOP_OK, + destIfFalse==destIfNull ? 0 : &rRhsHasNull, + aiMap, &iTab); + + assert( pParse->nErr || nVector==1 || eType==IN_INDEX_EPH + || eType==IN_INDEX_INDEX_ASC || eType==IN_INDEX_INDEX_DESC + ); +#ifdef SQLITE_DEBUG + /* Confirm that aiMap[] contains nVector integer values between 0 and + ** nVector-1. */ + for(i=0; i from " IN (...)". If the LHS is a + ** vector, then it is stored in an array of nVector registers starting + ** at r1. + ** + ** sqlite3FindInIndex() might have reordered the fields of the LHS vector + ** so that the fields are in the same order as an existing index. The + ** aiMap[] array contains a mapping from the original LHS field order to + ** the field order that matches the RHS index. + ** + ** Avoid factoring the LHS of the IN(...) expression out of the loop, + ** even if it is constant, as OP_Affinity may be used on the register + ** by code generated below. */ + assert( pParse->okConstFactor==okConstFactor ); + pParse->okConstFactor = 0; + rLhs = exprCodeVector(pParse, pLeft, &iDummy); + pParse->okConstFactor = okConstFactor; + + /* If sqlite3FindInIndex() did not find or create an index that is + ** suitable for evaluating the IN operator, then evaluate using a + ** sequence of comparisons. + ** + ** This is step (1) in the in-operator.md optimized algorithm. + */ + if( eType==IN_INDEX_NOOP ){ + ExprList *pList; + CollSeq *pColl; + int labelOk = sqlite3VdbeMakeLabel(pParse); + int r2, regToFree; + int regCkNull = 0; + int ii; + assert( nVector==1 ); + assert( ExprUseXList(pExpr) ); + pList = pExpr->x.pList; + pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft); + if( destIfNull!=destIfFalse ){ + regCkNull = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull); + } + for(ii=0; iinExpr; ii++){ + r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, ®ToFree); + if( regCkNull && sqlite3ExprCanBeNull(pList->a[ii].pExpr) ){ + sqlite3VdbeAddOp3(v, OP_BitAnd, regCkNull, r2, regCkNull); + } + sqlite3ReleaseTempReg(pParse, regToFree); + if( iinExpr-1 || destIfNull!=destIfFalse ){ + int op = rLhs!=r2 ? OP_Eq : OP_NotNull; + sqlite3VdbeAddOp4(v, op, rLhs, labelOk, r2, + (void*)pColl, P4_COLLSEQ); + VdbeCoverageIf(v, iinExpr-1 && op==OP_Eq); + VdbeCoverageIf(v, ii==pList->nExpr-1 && op==OP_Eq); + VdbeCoverageIf(v, iinExpr-1 && op==OP_NotNull); + VdbeCoverageIf(v, ii==pList->nExpr-1 && op==OP_NotNull); + sqlite3VdbeChangeP5(v, zAff[0]); + }else{ + int op = rLhs!=r2 ? OP_Ne : OP_IsNull; + assert( destIfNull==destIfFalse ); + sqlite3VdbeAddOp4(v, op, rLhs, destIfFalse, r2, + (void*)pColl, P4_COLLSEQ); + VdbeCoverageIf(v, op==OP_Ne); + VdbeCoverageIf(v, op==OP_IsNull); + sqlite3VdbeChangeP5(v, zAff[0] | SQLITE_JUMPIFNULL); + } + } + if( regCkNull ){ + sqlite3VdbeAddOp2(v, OP_IsNull, regCkNull, destIfNull); VdbeCoverage(v); + sqlite3VdbeGoto(v, destIfFalse); + } + sqlite3VdbeResolveLabel(v, labelOk); + sqlite3ReleaseTempReg(pParse, regCkNull); + goto sqlite3ExprCodeIN_finished; + } + + if( eType!=IN_INDEX_ROWID ){ + /* If this IN operator will use an index, then the order of columns in the + ** vector might be different from the order in the index. In that case, + ** we need to reorder the LHS values to be in index order. Run Affinity + ** before reordering the columns, so that the affinity is correct. + */ + sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector); + for(i=0; ipLeft, i); + if( pParse->nErr ) goto sqlite3ExprCodeIN_oom_error; + if( sqlite3ExprCanBeNull(p) ){ + sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+aiMap[i], destStep2); + VdbeCoverage(v); + } + } + + /* Step 3. The LHS is now known to be non-NULL. Do the binary search + ** of the RHS using the LHS as a probe. If found, the result is + ** true. + */ + if( eType==IN_INDEX_ROWID ){ + /* In this case, the RHS is the ROWID of table b-tree and so we also + ** know that the RHS is non-NULL. Hence, we combine steps 3 and 4 + ** into a single opcode. */ + assert( nVector==1 ); + sqlite3VdbeAddOp3(v, OP_SeekRowid, iTab, destIfFalse, rLhs); + VdbeCoverage(v); + addrTruthOp = sqlite3VdbeAddOp0(v, OP_Goto); /* Return True */ + }else{ + if( destIfFalse==destIfNull ){ + /* Combine Step 3 and Step 5 into a single opcode */ + if( ExprHasProperty(pExpr, EP_Subrtn) ){ + const VdbeOp *pOp = sqlite3VdbeGetOp(v, pExpr->y.sub.iAddr); + assert( pOp->opcode==OP_Once || pParse->nErr ); + if( pOp->p3>0 ){ /* tag-202407032019 */ + assert( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) + || pParse->nErr ); + sqlite3VdbeAddOp4Int(v, OP_Filter, pOp->p3, destIfFalse, + rLhs, nVector); VdbeCoverage(v); + } + } + sqlite3VdbeAddOp4Int(v, OP_NotFound, iTab, destIfFalse, + rLhs, nVector); VdbeCoverage(v); + goto sqlite3ExprCodeIN_finished; + } + /* Ordinary Step 3, for the case where FALSE and NULL are distinct */ + addrTruthOp = sqlite3VdbeAddOp4Int(v, OP_Found, iTab, 0, + rLhs, nVector); VdbeCoverage(v); + } + + /* Step 4. If the RHS is known to be non-NULL and we did not find + ** an match on the search above, then the result must be FALSE. + */ + if( rRhsHasNull && nVector==1 ){ + sqlite3VdbeAddOp2(v, OP_NotNull, rRhsHasNull, destIfFalse); + VdbeCoverage(v); + } + + /* Step 5. If we do not care about the difference between NULL and + ** FALSE, then just return false. + */ + if( destIfFalse==destIfNull ) sqlite3VdbeGoto(v, destIfFalse); + + /* Step 6: Loop through rows of the RHS. Compare each row to the LHS. + ** If any comparison is NULL, then the result is NULL. If all + ** comparisons are FALSE then the final result is FALSE. + ** + ** For a scalar LHS, it is sufficient to check just the first row + ** of the RHS. + */ + if( destStep6 ) sqlite3VdbeResolveLabel(v, destStep6); + addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, destIfFalse); + VdbeCoverage(v); + if( nVector>1 ){ + destNotNull = sqlite3VdbeMakeLabel(pParse); + }else{ + /* For nVector==1, combine steps 6 and 7 by immediately returning + ** FALSE if the first comparison is not NULL */ + destNotNull = destIfFalse; + } + for(i=0; ix.pSelect->pEList->a[i].pExpr; + pColl = sqlite3BinaryCompareCollSeq(pParse, p, pRhs); + }else{ + /* If the RHS of the IN(...) expression are scalar expressions, do + ** not consider their collation sequences. The documentation says + ** "The collating sequence used for expressions of the form "x IN (y, z, + ** ...)" is the collating sequence of x.". */ + pColl = sqlite3ExprCollSeq(pParse, p); + } + sqlite3VdbeAddOp3(v, OP_Column, iTab, aiMap[i], r3); + sqlite3VdbeAddOp4(v, OP_Ne, rLhs+aiMap[i], destNotNull, r3, + (void*)pColl, P4_COLLSEQ); + VdbeCoverage(v); + sqlite3ReleaseTempReg(pParse, r3); + } + sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull); + if( nVector>1 ){ + sqlite3VdbeResolveLabel(v, destNotNull); + sqlite3VdbeAddOp2(v, OP_Next, iTab, addrTop+1); + VdbeCoverage(v); + + /* Step 7: If we reach this point, we know that the result must + ** be false. */ + sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse); + } + + /* Jumps here in order to return true. */ + sqlite3VdbeJumpHere(v, addrTruthOp); + +sqlite3ExprCodeIN_finished: + VdbeComment((v, "end IN expr")); +sqlite3ExprCodeIN_oom_error: + sqlite3DbFree(pParse->db, aiMap); + sqlite3DbFree(pParse->db, zAff); +} +#endif /* SQLITE_OMIT_SUBQUERY */ + +#ifndef SQLITE_OMIT_FLOATING_POINT +/* +** Generate an instruction that will put the floating point +** value described by z[0..n-1] into register iMem. +** +** The z[] string will probably not be zero-terminated. But the +** z[n] character is guaranteed to be something that does not look +** like the continuation of the number. +*/ +static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){ + if( ALWAYS(z!=0) ){ + double value; + sqlite3AtoF(z, &value); + assert( !sqlite3IsNaN(value) ); /* The new AtoF never returns NaN */ + if( negateFlag ) value = -value; + sqlite3VdbeAddOp4Dup8(v, OP_Real, 0, iMem, 0, (u8*)&value, P4_REAL); + } +} +#endif + + +/* +** Generate an instruction that will put the integer describe by +** text z[0..n-1] into register iMem. +** +** Expr.u.zToken is always UTF8 and zero-terminated. +*/ +static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ + Vdbe *v = pParse->pVdbe; + if( pExpr->flags & EP_IntValue ){ + int i = pExpr->u.iValue; + assert( i>=0 ); + if( negFlag ) i = -i; + sqlite3VdbeAddOp2(v, OP_Integer, i, iMem); + }else{ + int c; + i64 value; + const char *z = pExpr->u.zToken; + assert( z!=0 ); + c = sqlite3DecOrHexToI64(z, &value); + if( (c==3 && !negFlag) || (c==2) || (negFlag && value==SMALLEST_INT64)){ +#ifdef SQLITE_OMIT_FLOATING_POINT + sqlite3ErrorMsg(pParse, "oversized integer: %s%#T", negFlag?"-":"",pExpr); +#else +#ifndef SQLITE_OMIT_HEX_INTEGER + if( sqlite3_strnicmp(z,"0x",2)==0 ){ + sqlite3ErrorMsg(pParse, "hex literal too big: %s%#T", + negFlag?"-":"",pExpr); + }else +#endif + { + codeReal(v, z, negFlag, iMem); + } +#endif + }else{ + if( negFlag ){ value = c==3 ? SMALLEST_INT64 : -value; } + sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, iMem, 0, (u8*)&value, P4_INT64); + } + } +} + + +/* Generate code that will load into register regOut a value that is +** appropriate for the iIdxCol-th column of index pIdx. +*/ +SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn( + Parse *pParse, /* The parsing context */ + Index *pIdx, /* The index whose column is to be loaded */ + int iTabCur, /* Cursor pointing to a table row */ + int iIdxCol, /* The column of the index to be loaded */ + int regOut /* Store the index column value in this register */ +){ + i16 iTabCol = pIdx->aiColumn[iIdxCol]; + if( iTabCol==XN_EXPR ){ + assert( pIdx->aColExpr ); + assert( pIdx->aColExpr->nExpr>iIdxCol ); + pParse->iSelfTab = iTabCur + 1; + sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[iIdxCol].pExpr, regOut); + pParse->iSelfTab = 0; + }else{ + sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pIdx->pTable, iTabCur, + iTabCol, regOut); + } +} + +#ifndef SQLITE_OMIT_GENERATED_COLUMNS +/* +** Generate code that will compute the value of generated column pCol +** and store the result in register regOut +*/ +SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn( + Parse *pParse, /* Parsing context */ + Table *pTab, /* Table containing the generated column */ + Column *pCol, /* The generated column */ + int regOut /* Put the result in this register */ +){ + int iAddr; + Vdbe *v = pParse->pVdbe; + int nErr = pParse->nErr; + assert( v!=0 ); + assert( pParse->iSelfTab!=0 ); + if( pParse->iSelfTab>0 ){ + iAddr = sqlite3VdbeAddOp3(v, OP_IfNullRow, pParse->iSelfTab-1, 0, regOut); + }else{ + iAddr = 0; + } + sqlite3ExprCodeCopy(pParse, sqlite3ColumnExpr(pTab,pCol), regOut); + if( (pCol->colFlags & COLFLAG_VIRTUAL)!=0 + && (pTab->tabFlags & TF_Strict)!=0 + ){ + int p3 = 2+(int)(pCol - pTab->aCol); + sqlite3VdbeAddOp4(v, OP_TypeCheck, regOut, 1, p3, (char*)pTab, P4_TABLE); + }else if( pCol->affinity>=SQLITE_AFF_TEXT ){ + sqlite3VdbeAddOp4(v, OP_Affinity, regOut, 1, 0, &pCol->affinity, 1); + } + if( iAddr ) sqlite3VdbeJumpHere(v, iAddr); + if( pParse->nErr>nErr ) pParse->db->errByteOffset = -1; +} +#endif /* SQLITE_OMIT_GENERATED_COLUMNS */ + +/* +** Generate code to extract the value of the iCol-th column of a table. +*/ +SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable( + Vdbe *v, /* Parsing context */ + Table *pTab, /* The table containing the value */ + int iTabCur, /* The table cursor. Or the PK cursor for WITHOUT ROWID */ + int iCol, /* Index of the column to extract */ + int regOut /* Extract the value into this register */ +){ + Column *pCol; + assert( v!=0 ); + assert( pTab!=0 ); + assert( iCol!=XN_EXPR ); + if( iCol<0 || iCol==pTab->iPKey ){ + sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut); + VdbeComment((v, "%s.rowid", pTab->zName)); + }else{ + int op; + int x; + if( IsVirtual(pTab) ){ + op = OP_VColumn; + x = iCol; +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + }else if( (pCol = &pTab->aCol[iCol])->colFlags & COLFLAG_VIRTUAL ){ + Parse *pParse = sqlite3VdbeParser(v); + if( pCol->colFlags & COLFLAG_BUSY ){ + sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", + pCol->zCnName); + }else{ + int savedSelfTab = pParse->iSelfTab; + pCol->colFlags |= COLFLAG_BUSY; + pParse->iSelfTab = iTabCur+1; + sqlite3ExprCodeGeneratedColumn(pParse, pTab, pCol, regOut); + pParse->iSelfTab = savedSelfTab; + pCol->colFlags &= ~COLFLAG_BUSY; + } + return; +#endif + }else if( !HasRowid(pTab) ){ + testcase( iCol!=sqlite3TableColumnToStorage(pTab, iCol) ); + x = sqlite3TableColumnToIndex(sqlite3PrimaryKeyIndex(pTab), iCol); + op = OP_Column; + }else{ + x = sqlite3TableColumnToStorage(pTab,iCol); + testcase( x!=iCol ); + op = OP_Column; + } + sqlite3VdbeAddOp3(v, op, iTabCur, x, regOut); + sqlite3ColumnDefault(v, pTab, iCol, regOut); + } +} + +/* +** Generate code that will extract the iColumn-th column from +** table pTab and store the column value in register iReg. +** +** There must be an open cursor to pTab in iTable when this routine +** is called. If iColumn<0 then code is generated that extracts the rowid. +*/ +SQLITE_PRIVATE int sqlite3ExprCodeGetColumn( + Parse *pParse, /* Parsing and code generating context */ + Table *pTab, /* Description of the table we are reading from */ + int iColumn, /* Index of the table column */ + int iTable, /* The cursor pointing to the table */ + int iReg, /* Store results here */ + u8 p5 /* P5 value for OP_Column + FLAGS */ +){ + assert( pParse->pVdbe!=0 ); + assert( (p5 & (OPFLAG_NOCHNG|OPFLAG_TYPEOFARG|OPFLAG_LENGTHARG))==p5 ); + assert( IsVirtual(pTab) || (p5 & OPFLAG_NOCHNG)==0 ); + sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pTab, iTable, iColumn, iReg); + if( p5 ){ + VdbeOp *pOp = sqlite3VdbeGetLastOp(pParse->pVdbe); + if( pOp->opcode==OP_Column ) pOp->p5 = p5; + if( pOp->opcode==OP_VColumn ) pOp->p5 = (p5 & OPFLAG_NOCHNG); + } + return iReg; +} + +/* +** Generate code to move content from registers iFrom...iFrom+nReg-1 +** over to iTo..iTo+nReg-1. +*/ +SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){ + sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg); +} + +/* +** Convert a scalar expression node to a TK_REGISTER referencing +** register iReg. The caller must ensure that iReg already contains +** the correct value for the expression. +*/ +SQLITE_PRIVATE void sqlite3ExprToRegister(Expr *pExpr, int iReg){ + Expr *p = sqlite3ExprSkipCollateAndLikely(pExpr); + if( NEVER(p==0) ) return; + if( p->op==TK_REGISTER ){ + assert( p->iTable==iReg ); + }else{ + p->op2 = p->op; + p->op = TK_REGISTER; + p->iTable = iReg; + ExprClearProperty(p, EP_Skip); + } +} + +/* +** Evaluate an expression (either a vector or a scalar expression) and store +** the result in contiguous temporary registers. Return the index of +** the first register used to store the result. +** +** If the returned result register is a temporary scalar, then also write +** that register number into *piFreeable. If the returned result register +** is not a temporary or if the expression is a vector set *piFreeable +** to 0. +*/ +static int exprCodeVector(Parse *pParse, Expr *p, int *piFreeable){ + int iResult; + int nResult = sqlite3ExprVectorSize(p); + if( nResult==1 ){ + iResult = sqlite3ExprCodeTemp(pParse, p, piFreeable); + }else{ + *piFreeable = 0; + if( p->op==TK_SELECT ){ +#if SQLITE_OMIT_SUBQUERY + iResult = 0; +#else + iResult = sqlite3CodeSubselect(pParse, p); +#endif + }else{ + int i; + iResult = pParse->nMem+1; + pParse->nMem += nResult; + assert( ExprUseXList(p) ); + for(i=0; ix.pList->a[i].pExpr, i+iResult); + } + } + } + return iResult; +} + +/* +** If the last opcode is a OP_Copy, then set the do-not-merge flag (p5) +** so that a subsequent copy will not be merged into this one. +*/ +static void setDoNotMergeFlagOnCopy(Vdbe *v){ + if( sqlite3VdbeGetLastOp(v)->opcode==OP_Copy ){ + sqlite3VdbeChangeP5(v, 1); /* Tag trailing OP_Copy as not mergeable */ + } +} + +/* +** Generate code to implement special SQL functions that are implemented +** in-line rather than by using the usual callbacks. +*/ +static int exprCodeInlineFunction( + Parse *pParse, /* Parsing context */ + ExprList *pFarg, /* List of function arguments */ + int iFuncId, /* Function ID. One of the INTFUNC_... values */ + int target /* Store function result in this register */ +){ + int nFarg; + Vdbe *v = pParse->pVdbe; + assert( v!=0 ); + assert( pFarg!=0 ); + nFarg = pFarg->nExpr; + assert( nFarg>0 ); /* All in-line functions have at least one argument */ + switch( iFuncId ){ + case INLINEFUNC_coalesce: { + /* Attempt a direct implementation of the built-in COALESCE() and + ** IFNULL() functions. This avoids unnecessary evaluation of + ** arguments past the first non-NULL argument. + */ + int endCoalesce = sqlite3VdbeMakeLabel(pParse); + int i; + assert( nFarg>=2 ); + sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target); + for(i=1; ia[i].pExpr, target); + } + setDoNotMergeFlagOnCopy(v); + sqlite3VdbeResolveLabel(v, endCoalesce); + break; + } + case INLINEFUNC_iif: { + Expr caseExpr; + memset(&caseExpr, 0, sizeof(caseExpr)); + caseExpr.op = TK_CASE; + caseExpr.x.pList = pFarg; + return sqlite3ExprCodeTarget(pParse, &caseExpr, target); + } +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC + case INLINEFUNC_sqlite_offset: { + Expr *pArg = pFarg->a[0].pExpr; + if( pArg->op==TK_COLUMN && pArg->iTable>=0 ){ + sqlite3VdbeAddOp3(v, OP_Offset, pArg->iTable, pArg->iColumn, target); + }else{ + sqlite3VdbeAddOp2(v, OP_Null, 0, target); + } + break; + } +#endif + default: { + /* The UNLIKELY() function is a no-op. The result is the value + ** of the first argument. + */ + assert( nFarg==1 || nFarg==2 ); + target = sqlite3ExprCodeTarget(pParse, pFarg->a[0].pExpr, target); + break; + } + + /*********************************************************************** + ** Test-only SQL functions that are only usable if enabled + ** via SQLITE_TESTCTRL_INTERNAL_FUNCTIONS + */ +#if !defined(SQLITE_UNTESTABLE) + case INLINEFUNC_expr_compare: { + /* Compare two expressions using sqlite3ExprCompare() */ + assert( nFarg==2 ); + sqlite3VdbeAddOp2(v, OP_Integer, + sqlite3ExprCompare(0,pFarg->a[0].pExpr, pFarg->a[1].pExpr,-1), + target); + break; + } + + case INLINEFUNC_expr_implies_expr: { + /* Compare two expressions using sqlite3ExprImpliesExpr() */ + assert( nFarg==2 ); + sqlite3VdbeAddOp2(v, OP_Integer, + sqlite3ExprImpliesExpr(pParse,pFarg->a[0].pExpr, pFarg->a[1].pExpr,-1), + target); + break; + } + + case INLINEFUNC_implies_nonnull_row: { + /* Result of sqlite3ExprImpliesNonNullRow() */ + Expr *pA1; + assert( nFarg==2 ); + pA1 = pFarg->a[1].pExpr; + if( pA1->op==TK_COLUMN ){ + sqlite3VdbeAddOp2(v, OP_Integer, + sqlite3ExprImpliesNonNullRow(pFarg->a[0].pExpr,pA1->iTable,1), + target); + }else{ + sqlite3VdbeAddOp2(v, OP_Null, 0, target); + } + break; + } + + case INLINEFUNC_affinity: { + /* The AFFINITY() function evaluates to a string that describes + ** the type affinity of the argument. This is used for testing of + ** the SQLite type logic. + */ + const char *azAff[] = { "blob", "text", "numeric", "integer", + "real", "flexnum" }; + char aff; + assert( nFarg==1 ); + aff = sqlite3ExprAffinity(pFarg->a[0].pExpr); + assert( aff<=SQLITE_AFF_NONE + || (aff>=SQLITE_AFF_BLOB && aff<=SQLITE_AFF_FLEXNUM) ); + sqlite3VdbeLoadString(v, target, + (aff<=SQLITE_AFF_NONE) ? "none" : azAff[aff-SQLITE_AFF_BLOB]); + break; + } +#endif /* !defined(SQLITE_UNTESTABLE) */ + } + return target; +} + +/* +** Expression Node callback for sqlite3ExprCanReturnSubtype(). If +** pExpr is able to return a subtype, set pWalker->eCode and abort +** the search. If pExpr can never return a subtype, prune search. +** +** The only expressions that can return a subtype are: +** +** 1. A function +** 2. The no-op "+" operator +** 3. A CASE...END expression +** 4. A CAST() expression +** 5. A "expr COLLATE colseq" expression. +** +** For any other kind of expression, prune the search. +** +** For case 1, the expression can yield a subtype if the function has +** the SQLITE_RESULT_SUBTYPE property. Functions can also return +** a subtype (via sqlite3_result_value()) if any of the arguments can +** return a subtype. +** +** In all cases 1 through 5, the expression might also return a subtype +** if any operand can return a subtype. +*/ +static int exprNodeCanReturnSubtype(Walker *pWalker, Expr *pExpr){ + int n; + FuncDef *pDef; + sqlite3 *db; + if( pExpr->op==TK_CASE || pExpr->op==TK_UPLUS + || pExpr->op==TK_COLLATE || pExpr->op==TK_CAST + ){ + return WRC_Continue; + } + if( pExpr->op!=TK_FUNCTION ){ + return WRC_Prune; + } + assert( ExprUseXList(pExpr) ); + db = pWalker->pParse->db; + n = ALWAYS(pExpr->x.pList) ? pExpr->x.pList->nExpr : 0; + pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0); + if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_RESULT_SUBTYPE)!=0 ){ + pWalker->eCode = 1; + return WRC_Abort; + } + return WRC_Continue; +} + +/* +** Return TRUE if expression pExpr is able to return a subtype. +** +** A TRUE return does not guarantee that a subtype will be returned. +** It only indicates that a subtype return is possible. False positives +** are acceptable as they only disable an optimization. False negatives, +** on the other hand, can lead to incorrect answers. +*/ +static int sqlite3ExprCanReturnSubtype(Parse *pParse, Expr *pExpr){ + Walker w; + memset(&w, 0, sizeof(w)); + w.pParse = pParse; + w.xExprCallback = exprNodeCanReturnSubtype; + sqlite3WalkExpr(&w, pExpr); + return w.eCode; +} + + +/* +** Check to see if pExpr is one of the indexed expressions on pParse->pIdxEpr. +** If it is, then resolve the expression by reading from the index and +** return the register into which the value has been read. If pExpr is +** not an indexed expression, then return negative. +*/ +static SQLITE_NOINLINE int sqlite3IndexedExprLookup( + Parse *pParse, /* The parsing context */ + Expr *pExpr, /* The expression to potentially bypass */ + int target /* Where to store the result of the expression */ +){ + IndexedExpr *p; + Vdbe *v; + for(p=pParse->pIdxEpr; p; p=p->pIENext){ + u8 exprAff; + int iDataCur = p->iDataCur; + if( iDataCur<0 ) continue; + if( pParse->iSelfTab ){ + if( p->iDataCur!=pParse->iSelfTab-1 ) continue; + iDataCur = -1; + } + if( sqlite3ExprCompare(0, pExpr, p->pExpr, iDataCur)!=0 ) continue; + assert( p->aff>=SQLITE_AFF_BLOB && p->aff<=SQLITE_AFF_NUMERIC ); + exprAff = sqlite3ExprAffinity(pExpr); + if( (exprAff<=SQLITE_AFF_BLOB && p->aff!=SQLITE_AFF_BLOB) + || (exprAff==SQLITE_AFF_TEXT && p->aff!=SQLITE_AFF_TEXT) + || (exprAff>=SQLITE_AFF_NUMERIC && p->aff!=SQLITE_AFF_NUMERIC) + ){ + /* Affinity mismatch on a generated column */ + continue; + } + + + /* Functions that might set a subtype should not be replaced by the + ** value taken from an expression index if they are themselves an + ** argument to another scalar function or aggregate. + ** https://sqlite.org/forum/forumpost/68d284c86b082c3e */ + if( ExprHasProperty(pExpr, EP_SubtArg) + && sqlite3ExprCanReturnSubtype(pParse, pExpr) + ){ + continue; + } + + v = pParse->pVdbe; + assert( v!=0 ); + if( p->bMaybeNullRow ){ + /* If the index is on a NULL row due to an outer join, then we + ** cannot extract the value from the index. The value must be + ** computed using the original expression. */ + int addr = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp3(v, OP_IfNullRow, p->iIdxCur, addr+3, target); + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_Column, p->iIdxCur, p->iIdxCol, target); + VdbeComment((v, "%s expr-column %d", p->zIdxName, p->iIdxCol)); + sqlite3VdbeGoto(v, 0); + p = pParse->pIdxEpr; + pParse->pIdxEpr = 0; + sqlite3ExprCode(pParse, pExpr, target); + pParse->pIdxEpr = p; + sqlite3VdbeJumpHere(v, addr+2); + }else{ + sqlite3VdbeAddOp3(v, OP_Column, p->iIdxCur, p->iIdxCol, target); + VdbeComment((v, "%s expr-column %d", p->zIdxName, p->iIdxCol)); + } + return target; + } + return -1; /* Not found */ +} + + +/* +** Expression pExpr is guaranteed to be a TK_COLUMN or equivalent. This +** function checks the Parse.pIdxPartExpr list to see if this column +** can be replaced with a constant value. If so, it generates code to +** put the constant value in a register (ideally, but not necessarily, +** register iTarget) and returns the register number. +** +** Or, if the TK_COLUMN cannot be replaced by a constant, zero is +** returned. +*/ +static int exprPartidxExprLookup(Parse *pParse, Expr *pExpr, int iTarget){ + IndexedExpr *p; + for(p=pParse->pIdxPartExpr; p; p=p->pIENext){ + if( pExpr->iColumn==p->iIdxCol && pExpr->iTable==p->iDataCur ){ + Vdbe *v = pParse->pVdbe; + int addr = 0; + int ret; + + if( p->bMaybeNullRow ){ + addr = sqlite3VdbeAddOp1(v, OP_IfNullRow, p->iIdxCur); + } + ret = sqlite3ExprCodeTarget(pParse, p->pExpr, iTarget); + sqlite3VdbeAddOp4(pParse->pVdbe, OP_Affinity, ret, 1, 0, + (const char*)&p->aff, 1); + if( addr ){ + sqlite3VdbeJumpHere(v, addr); + sqlite3VdbeChangeP3(v, addr, ret); + } + return ret; + } + } + return 0; +} + +/* +** Generate code that evaluates an AND or OR operator leaving a +** boolean result in a register. pExpr is the AND/OR expression. +** Store the result in the "target" register. Use short-circuit +** evaluation to avoid computing both operands, if possible. +** +** The code generated might require the use of a temporary register. +** If it does, then write the number of that temporary register +** into *pTmpReg. If not, leave *pTmpReg unchanged. +*/ +static SQLITE_NOINLINE int exprCodeTargetAndOr( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* AND or OR expression to be coded */ + int target, /* Put result in this register, guaranteed */ + int *pTmpReg /* Write a temporary register here */ +){ + int op; /* The opcode. TK_AND or TK_OR */ + int skipOp; /* Opcode for the branch that skips one operand */ + int addrSkip; /* Branch instruction that skips one of the operands */ + int regSS = 0; /* Register holding computed operand when other omitted */ + int r1, r2; /* Registers for left and right operands, respectively */ + Expr *pAlt; /* Alternative, simplified expression */ + Vdbe *v; /* statement being coded */ + + assert( pExpr!=0 ); + op = pExpr->op; + assert( op==TK_AND || op==TK_OR ); + assert( TK_AND==OP_And ); testcase( op==TK_AND ); + assert( TK_OR==OP_Or ); testcase( op==TK_OR ); + assert( pParse->pVdbe!=0 ); + v = pParse->pVdbe; + pAlt = sqlite3ExprSimplifiedAndOr(pExpr); + if( pAlt!=pExpr ){ + r1 = sqlite3ExprCodeTarget(pParse, pAlt, target); + sqlite3VdbeAddOp3(v, OP_And, r1, r1, target); + return target; + } + skipOp = op==TK_AND ? OP_IfNot : OP_If; + if( exprEvalRhsFirst(pExpr) ){ + /* Compute the right operand first. Skip the computation of the left + ** operand if the right operand fully determines the result */ + r2 = regSS = sqlite3ExprCodeTarget(pParse, pExpr->pRight, target); + addrSkip = sqlite3VdbeAddOp1(v, skipOp, r2); + VdbeComment((v, "skip left operand")); + VdbeCoverage(v); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, pTmpReg); + }else{ + /* Compute the left operand first */ + r1 = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); + if( ExprHasProperty(pExpr->pRight, EP_Subquery) ){ + /* Skip over the computation of the right operand if the right + ** operand is a subquery and the left operand completely determines + ** the result */ + regSS = r1; + addrSkip = sqlite3VdbeAddOp1(v, skipOp, r1); + VdbeComment((v, "skip right operand")); + VdbeCoverage(v); + }else{ + addrSkip = regSS = 0; + } + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, pTmpReg); + } + sqlite3VdbeAddOp3(v, op, r2, r1, target); + testcase( (*pTmpReg)==0 ); + if( addrSkip ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2); + sqlite3VdbeJumpHere(v, addrSkip); + sqlite3VdbeAddOp3(v, OP_Or, regSS, regSS, target); + VdbeComment((v, "short-circut value")); + } + return target; +} + + + +/* +** Generate code into the current Vdbe to evaluate the given +** expression. Attempt to store the results in register "target". +** Return the register where results are stored. +** +** With this routine, there is no guarantee that results will +** be stored in target. The result might be stored in some other +** register if it is convenient to do so. The calling function +** must check the return code and move the results to the desired +** register. +*/ +SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ + Vdbe *v = pParse->pVdbe; /* The VM under construction */ + int op; /* The opcode being coded */ + int inReg = target; /* Results stored in register inReg */ + int regFree1 = 0; /* If non-zero free this temporary register */ + int regFree2 = 0; /* If non-zero free this temporary register */ + int r1, r2; /* Various register numbers */ + Expr tempX; /* Temporary expression node */ + int p5 = 0; + + assert( target>0 && target<=pParse->nMem ); + assert( v!=0 ); + +expr_code_doover: + if( pExpr==0 ){ + op = TK_NULL; + }else if( pParse->pIdxEpr!=0 + && !ExprHasProperty(pExpr, EP_Leaf) + && (r1 = sqlite3IndexedExprLookup(pParse, pExpr, target))>=0 + ){ + return r1; + }else{ + assert( !ExprHasVVAProperty(pExpr,EP_Immutable) ); + op = pExpr->op; + } + assert( op!=TK_ORDER ); + switch( op ){ + case TK_AGG_COLUMN: { + AggInfo *pAggInfo = pExpr->pAggInfo; + struct AggInfo_col *pCol; + assert( pAggInfo!=0 ); + assert( pExpr->iAgg>=0 ); + if( pExpr->iAgg>=pAggInfo->nColumn ){ + /* Happens when the left table of a RIGHT JOIN is null and + ** is using an expression index */ + sqlite3VdbeAddOp2(v, OP_Null, 0, target); +#ifdef SQLITE_VDBE_COVERAGE + /* Verify that the OP_Null above is exercised by tests + ** tag-20230325-2 */ + sqlite3VdbeAddOp3(v, OP_NotNull, target, 1, 20230325); + VdbeCoverageNeverTaken(v); +#endif + break; + } + pCol = &pAggInfo->aCol[pExpr->iAgg]; + if( !pAggInfo->directMode ){ + return AggInfoColumnReg(pAggInfo, pExpr->iAgg); + }else if( pAggInfo->useSortingIdx ){ + Table *pTab = pCol->pTab; + sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab, + pCol->iSorterColumn, target); + if( pTab==0 ){ + /* No comment added */ + }else if( pCol->iColumn<0 ){ + VdbeComment((v,"%s.rowid",pTab->zName)); + }else{ + VdbeComment((v,"%s.%s", + pTab->zName, pTab->aCol[pCol->iColumn].zCnName)); + if( pTab->aCol[pCol->iColumn].affinity==SQLITE_AFF_REAL ){ + sqlite3VdbeAddOp1(v, OP_RealAffinity, target); + } + } + return target; + }else if( pExpr->y.pTab==0 ){ + /* This case happens when the argument to an aggregate function + ** is rewritten by aggregateConvertIndexedExprRefToColumn() */ + sqlite3VdbeAddOp3(v, OP_Column, pExpr->iTable, pExpr->iColumn, target); + return target; + } + /* Otherwise, fall thru into the TK_COLUMN case */ + /* no break */ deliberate_fall_through + } + case TK_COLUMN: { + int iTab = pExpr->iTable; + int iReg; + if( ExprHasProperty(pExpr, EP_FixedCol) ){ + /* This COLUMN expression is really a constant due to WHERE clause + ** constraints, and that constant is coded by the pExpr->pLeft + ** expression. However, make sure the constant has the correct + ** datatype by applying the Affinity of the table column to the + ** constant. + */ + int aff; + iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target); + assert( ExprUseYTab(pExpr) ); + assert( pExpr->y.pTab!=0 ); + aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); + if( aff>SQLITE_AFF_BLOB ){ + static const char zAff[] = "B\000C\000D\000E\000F"; + assert( SQLITE_AFF_BLOB=='A' ); + assert( SQLITE_AFF_TEXT=='B' ); + sqlite3VdbeAddOp4(v, OP_Affinity, iReg, 1, 0, + &zAff[(aff-'B')*2], P4_STATIC); + } + return iReg; + } + if( iTab<0 ){ + if( pParse->iSelfTab<0 ){ + /* Other columns in the same row for CHECK constraints or + ** generated columns or for inserting into partial index. + ** The row is unpacked into registers beginning at + ** 0-(pParse->iSelfTab). The rowid (if any) is in a register + ** immediately prior to the first column. + */ + Column *pCol; + Table *pTab; + int iSrc; + int iCol = pExpr->iColumn; + assert( ExprUseYTab(pExpr) ); + pTab = pExpr->y.pTab; + assert( pTab!=0 ); + assert( iCol>=XN_ROWID ); + assert( iColnCol ); + if( iCol<0 ){ + return -1-pParse->iSelfTab; + } + pCol = pTab->aCol + iCol; + testcase( iCol!=sqlite3TableColumnToStorage(pTab,iCol) ); + iSrc = sqlite3TableColumnToStorage(pTab, iCol) - pParse->iSelfTab; +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + if( pCol->colFlags & COLFLAG_GENERATED ){ + if( pCol->colFlags & COLFLAG_BUSY ){ + sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", + pCol->zCnName); + return 0; + } + pCol->colFlags |= COLFLAG_BUSY; + if( pCol->colFlags & COLFLAG_NOTAVAIL ){ + sqlite3ExprCodeGeneratedColumn(pParse, pTab, pCol, iSrc); + } + pCol->colFlags &= ~(COLFLAG_BUSY|COLFLAG_NOTAVAIL); + return iSrc; + }else +#endif /* SQLITE_OMIT_GENERATED_COLUMNS */ + if( pCol->affinity==SQLITE_AFF_REAL ){ + sqlite3VdbeAddOp2(v, OP_SCopy, iSrc, target); + sqlite3VdbeAddOp1(v, OP_RealAffinity, target); + return target; + }else{ + return iSrc; + } + }else{ + /* Coding an expression that is part of an index where column names + ** in the index refer to the table to which the index belongs */ + iTab = pParse->iSelfTab - 1; + } + } + else if( pParse->pIdxPartExpr + && 0!=(r1 = exprPartidxExprLookup(pParse, pExpr, target)) + ){ + return r1; + } + assert( ExprUseYTab(pExpr) ); + assert( pExpr->y.pTab!=0 ); + iReg = sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab, + pExpr->iColumn, iTab, target, + pExpr->op2); + return iReg; + } + case TK_INTEGER: { + codeInteger(pParse, pExpr, 0, target); + return target; + } + case TK_TRUEFALSE: { + sqlite3VdbeAddOp2(v, OP_Integer, sqlite3ExprTruthValue(pExpr), target); + return target; + } +#ifndef SQLITE_OMIT_FLOATING_POINT + case TK_FLOAT: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + codeReal(v, pExpr->u.zToken, 0, target); + return target; + } +#endif + case TK_STRING: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3VdbeLoadString(v, target, pExpr->u.zToken); + return target; + } + case TK_NULLS: { + /* Set a range of registers to NULL. pExpr->y.nReg registers starting + ** with target */ + sqlite3VdbeAddOp3(v, OP_Null, 0, target, target + pExpr->y.nReg - 1); + return target; + } + default: { + /* Make NULL the default case so that if a bug causes an illegal + ** Expr node to be passed into this function, it will be handled + ** sanely and not crash. But keep the assert() to bring the problem + ** to the attention of the developers. */ + assert( op==TK_NULL || op==TK_ERROR || pParse->db->mallocFailed ); + sqlite3VdbeAddOp2(v, OP_Null, 0, target); + return target; + } +#ifndef SQLITE_OMIT_BLOB_LITERAL + case TK_BLOB: { + int n; + const char *z; + char *zBlob; + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' ); + assert( pExpr->u.zToken[1]=='\'' ); + z = &pExpr->u.zToken[2]; + n = sqlite3Strlen30(z) - 1; + assert( z[n]=='\'' ); + zBlob = sqlite3HexToBlob(sqlite3VdbeDb(v), z, n); + sqlite3VdbeAddOp4(v, OP_Blob, n/2, target, 0, zBlob, P4_DYNAMIC); + return target; + } +#endif + case TK_VARIABLE: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + assert( pExpr->u.zToken!=0 ); + assert( pExpr->u.zToken[0]!=0 ); + sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target); + return target; + } + case TK_REGISTER: { + return pExpr->iTable; + } +#ifndef SQLITE_OMIT_CAST + case TK_CAST: { + /* Expressions of the form: CAST(pLeft AS token) */ + sqlite3ExprCode(pParse, pExpr->pLeft, target); + assert( inReg==target ); + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3VdbeAddOp2(v, OP_Cast, target, + sqlite3AffinityType(pExpr->u.zToken, 0)); + return inReg; + } +#endif /* SQLITE_OMIT_CAST */ + case TK_IS: + case TK_ISNOT: + op = (op==TK_IS) ? TK_EQ : TK_NE; + p5 = SQLITE_NULLEQ; + /* no break */ deliberate_fall_through + case TK_LT: + case TK_LE: + case TK_GT: + case TK_GE: + case TK_NE: + case TK_EQ: { + Expr *pLeft = pExpr->pLeft; + int addrIsNull = 0; + if( sqlite3ExprIsVector(pLeft) ){ + codeVectorCompare(pParse, pExpr, target, op, p5); + }else{ + if( ExprHasProperty(pExpr, EP_Subquery) && p5!=SQLITE_NULLEQ ){ + addrIsNull = exprComputeOperands(pParse, pExpr, + &r1, &r2, ®Free1, ®Free2); + }else{ + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + } + sqlite3VdbeAddOp2(v, OP_Integer, 1, inReg); + codeCompare(pParse, pLeft, pExpr->pRight, op, r1, r2, + sqlite3VdbeCurrentAddr(v)+2, p5, + ExprHasProperty(pExpr,EP_Commuted)); + assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); + assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); + assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); + assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); + assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq); + assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne); + if( p5==SQLITE_NULLEQ ){ + sqlite3VdbeAddOp2(v, OP_Integer, 0, inReg); + }else{ + sqlite3VdbeAddOp3(v, OP_ZeroOrNull, r1, inReg, r2); + if( addrIsNull ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2); + sqlite3VdbeJumpHere(v, addrIsNull); + sqlite3VdbeAddOp2(v, OP_Null, 0, inReg); + } + } + testcase( regFree1==0 ); + testcase( regFree2==0 ); + } + break; + } + case TK_AND: + case TK_OR: { + inReg = exprCodeTargetAndOr(pParse, pExpr, target, ®Free1); + break; + } + case TK_PLUS: + case TK_STAR: + case TK_MINUS: + case TK_REM: + case TK_BITAND: + case TK_BITOR: + case TK_SLASH: + case TK_LSHIFT: + case TK_RSHIFT: + case TK_CONCAT: { + int addrIsNull; + assert( TK_PLUS==OP_Add ); testcase( op==TK_PLUS ); + assert( TK_MINUS==OP_Subtract ); testcase( op==TK_MINUS ); + assert( TK_REM==OP_Remainder ); testcase( op==TK_REM ); + assert( TK_BITAND==OP_BitAnd ); testcase( op==TK_BITAND ); + assert( TK_BITOR==OP_BitOr ); testcase( op==TK_BITOR ); + assert( TK_SLASH==OP_Divide ); testcase( op==TK_SLASH ); + assert( TK_LSHIFT==OP_ShiftLeft ); testcase( op==TK_LSHIFT ); + assert( TK_RSHIFT==OP_ShiftRight ); testcase( op==TK_RSHIFT ); + assert( TK_CONCAT==OP_Concat ); testcase( op==TK_CONCAT ); + if( ExprHasProperty(pExpr, EP_Subquery) ){ + addrIsNull = exprComputeOperands(pParse, pExpr, + &r1, &r2, ®Free1, ®Free2); + }else{ + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + addrIsNull = 0; + } + sqlite3VdbeAddOp3(v, op, r2, r1, target); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + if( addrIsNull ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2); + sqlite3VdbeJumpHere(v, addrIsNull); + sqlite3VdbeAddOp2(v, OP_Null, 0, target); + VdbeComment((v, "short-circut value")); + } + break; + } + case TK_UMINUS: { + Expr *pLeft = pExpr->pLeft; + assert( pLeft ); + if( pLeft->op==TK_INTEGER ){ + codeInteger(pParse, pLeft, 1, target); + return target; +#ifndef SQLITE_OMIT_FLOATING_POINT + }else if( pLeft->op==TK_FLOAT ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + codeReal(v, pLeft->u.zToken, 1, target); + return target; +#endif + }else{ + tempX.op = TK_INTEGER; + tempX.flags = EP_IntValue|EP_TokenOnly; + tempX.u.iValue = 0; + ExprClearVVAProperties(&tempX); + r1 = sqlite3ExprCodeTemp(pParse, &tempX, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free2); + sqlite3VdbeAddOp3(v, OP_Subtract, r2, r1, target); + testcase( regFree2==0 ); + } + break; + } + case TK_BITNOT: + case TK_NOT: { + assert( TK_BITNOT==OP_BitNot ); testcase( op==TK_BITNOT ); + assert( TK_NOT==OP_Not ); testcase( op==TK_NOT ); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + testcase( regFree1==0 ); + sqlite3VdbeAddOp2(v, op, r1, inReg); + break; + } + case TK_TRUTH: { + int isTrue; /* IS TRUE or IS NOT TRUE */ + int bNormal; /* IS TRUE or IS FALSE */ + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + testcase( regFree1==0 ); + isTrue = sqlite3ExprTruthValue(pExpr->pRight); + bNormal = pExpr->op2==TK_IS; + testcase( isTrue && bNormal); + testcase( !isTrue && bNormal); + sqlite3VdbeAddOp4Int(v, OP_IsTrue, r1, inReg, !isTrue, isTrue ^ bNormal); + break; + } + case TK_ISNULL: + case TK_NOTNULL: { + int addr; + assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL ); + assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL ); + sqlite3VdbeAddOp2(v, OP_Integer, 1, target); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + testcase( regFree1==0 ); + addr = sqlite3VdbeAddOp1(v, op, r1); + VdbeCoverageIf(v, op==TK_ISNULL); + VdbeCoverageIf(v, op==TK_NOTNULL); + sqlite3VdbeAddOp2(v, OP_Integer, 0, target); + sqlite3VdbeJumpHere(v, addr); + break; + } + case TK_AGG_FUNCTION: { + AggInfo *pInfo = pExpr->pAggInfo; + if( pInfo==0 + || NEVER(pExpr->iAgg<0) + || NEVER(pExpr->iAgg>=pInfo->nFunc) + ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3ErrorMsg(pParse, "misuse of aggregate: %#T()", pExpr); + }else{ + return AggInfoFuncReg(pInfo, pExpr->iAgg); + } + break; + } + case TK_FUNCTION: { + ExprList *pFarg; /* List of function arguments */ + int nFarg; /* Number of function arguments */ + FuncDef *pDef; /* The function definition object */ + const char *zId; /* The function name */ + u32 constMask = 0; /* Mask of function arguments that are constant */ + int i; /* Loop counter */ + sqlite3 *db = pParse->db; /* The database connection */ + u8 enc = ENC(db); /* The text encoding used by this database */ + CollSeq *pColl = 0; /* A collating sequence */ + +#ifndef SQLITE_OMIT_WINDOWFUNC + if( ExprHasProperty(pExpr, EP_WinFunc) ){ + return pExpr->y.pWin->regResult; + } +#endif + + if( ConstFactorOk(pParse) + && sqlite3ExprIsConstantNotJoin(pParse,pExpr) + ){ + /* SQL functions can be expensive. So try to avoid running them + ** multiple times if we know they always give the same result */ + return sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1); + } + assert( !ExprHasProperty(pExpr, EP_TokenOnly) ); + assert( ExprUseXList(pExpr) ); + pFarg = pExpr->x.pList; + nFarg = pFarg ? pFarg->nExpr : 0; + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + zId = pExpr->u.zToken; + pDef = sqlite3FindFunction(db, zId, nFarg, enc, 0); +#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION + if( pDef==0 && pParse->explain ){ + pDef = sqlite3FindFunction(db, "unknown", nFarg, enc, 0); + } +#endif + if( pDef==0 || pDef->xFinalize!=0 ){ + sqlite3ErrorMsg(pParse, "unknown function: %#T()", pExpr); + break; + } + if( (pDef->funcFlags & SQLITE_FUNC_INLINE)!=0 && ALWAYS(pFarg!=0) ){ + assert( (pDef->funcFlags & SQLITE_FUNC_UNSAFE)==0 ); + assert( (pDef->funcFlags & SQLITE_FUNC_DIRECT)==0 ); + return exprCodeInlineFunction(pParse, pFarg, + SQLITE_PTR_TO_INT(pDef->pUserData), target); + }else if( pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE) ){ + sqlite3ExprFunctionUsable(pParse, pExpr, pDef); + } + + for(i=0; ia[i].pExpr) ){ + testcase( i==31 ); + constMask |= MASKBIT32(i); + } + if( (pDef->funcFlags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){ + pColl = sqlite3ExprCollSeq(pParse, pFarg->a[i].pExpr); + } + } + if( pFarg ){ + if( constMask ){ + r1 = pParse->nMem+1; + pParse->nMem += nFarg; + }else{ + r1 = sqlite3GetTempRange(pParse, nFarg); + } + + /* For length() and typeof() and octet_length() functions, + ** set the P5 parameter to the OP_Column opcode to OPFLAG_LENGTHARG + ** or OPFLAG_TYPEOFARG or OPFLAG_BYTELENARG respectively, to avoid + ** unnecessary data loading. + */ + if( (pDef->funcFlags & (SQLITE_FUNC_LENGTH|SQLITE_FUNC_TYPEOF))!=0 ){ + u8 exprOp; + assert( nFarg==1 ); + assert( pFarg->a[0].pExpr!=0 ); + exprOp = pFarg->a[0].pExpr->op; + if( exprOp==TK_COLUMN || exprOp==TK_AGG_COLUMN ){ + assert( SQLITE_FUNC_LENGTH==OPFLAG_LENGTHARG ); + assert( SQLITE_FUNC_TYPEOF==OPFLAG_TYPEOFARG ); + assert( SQLITE_FUNC_BYTELEN==OPFLAG_BYTELENARG ); + assert( (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG)==OPFLAG_BYTELENARG ); + testcase( (pDef->funcFlags & OPFLAG_BYTELENARG)==OPFLAG_LENGTHARG ); + testcase( (pDef->funcFlags & OPFLAG_BYTELENARG)==OPFLAG_TYPEOFARG ); + testcase( (pDef->funcFlags & OPFLAG_BYTELENARG)==OPFLAG_BYTELENARG); + pFarg->a[0].pExpr->op2 = pDef->funcFlags & OPFLAG_BYTELENARG; + } + } + + sqlite3ExprCodeExprList(pParse, pFarg, r1, 0, SQLITE_ECEL_FACTOR); + }else{ + r1 = 0; + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + /* Possibly overload the function if the first argument is + ** a virtual table column. + ** + ** For infix functions (LIKE, GLOB, REGEXP, and MATCH) use the + ** second argument, not the first, as the argument to test to + ** see if it is a column in a virtual table. This is done because + ** the left operand of infix functions (the operand we want to + ** control overloading) ends up as the second argument to the + ** function. The expression "A glob B" is equivalent to + ** "glob(B,A). We want to use the A in "A glob B" to test + ** for function overloading. But we use the B term in "glob(B,A)". + */ + if( nFarg>=2 && ExprHasProperty(pExpr, EP_InfixFunc) ){ + pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[1].pExpr); + }else if( nFarg>0 ){ + pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr); + } +#endif + if( pDef->funcFlags & SQLITE_FUNC_NEEDCOLL ){ + if( !pColl ) pColl = db->pDfltColl; + sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ); + } + sqlite3VdbeAddFunctionCall(pParse, constMask, r1, target, nFarg, + pDef, pExpr->op2); + if( nFarg ){ + if( constMask==0 ){ + sqlite3ReleaseTempRange(pParse, r1, nFarg); + }else{ + sqlite3VdbeReleaseRegisters(pParse, r1, nFarg, constMask, 1); + } + } + return target; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_EXISTS: + case TK_SELECT: { + int nCol; + testcase( op==TK_EXISTS ); + testcase( op==TK_SELECT ); + if( pParse->db->mallocFailed ){ + return 0; + }else if( op==TK_SELECT + && ALWAYS( ExprUseXSelect(pExpr) ) + && (nCol = pExpr->x.pSelect->pEList->nExpr)!=1 + ){ + sqlite3SubselectError(pParse, nCol, 1); + }else{ + return sqlite3CodeSubselect(pParse, pExpr); + } + break; + } + case TK_SELECT_COLUMN: { + int n; + Expr *pLeft = pExpr->pLeft; + if( pLeft->iTable==0 || pParse->withinRJSubrtn > pLeft->op2 ){ + pLeft->iTable = sqlite3CodeSubselect(pParse, pLeft); + pLeft->op2 = pParse->withinRJSubrtn; + } + assert( pLeft->op==TK_SELECT || pLeft->op==TK_ERROR ); + n = sqlite3ExprVectorSize(pLeft); + if( pExpr->iTable!=n ){ + sqlite3ErrorMsg(pParse, "%d columns assigned %d values", + pExpr->iTable, n); + } + return pLeft->iTable + pExpr->iColumn; + } + case TK_IN: { + int destIfFalse = sqlite3VdbeMakeLabel(pParse); + int destIfNull = sqlite3VdbeMakeLabel(pParse); + sqlite3VdbeAddOp2(v, OP_Null, 0, target); + sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull); + sqlite3VdbeAddOp2(v, OP_Integer, 1, target); + sqlite3VdbeResolveLabel(v, destIfFalse); + sqlite3VdbeAddOp2(v, OP_AddImm, target, 0); + sqlite3VdbeResolveLabel(v, destIfNull); + return target; + } +#endif /* SQLITE_OMIT_SUBQUERY */ + + + /* + ** x BETWEEN y AND z + ** + ** This is equivalent to + ** + ** x>=y AND x<=z + ** + ** X is stored in pExpr->pLeft. + ** Y is stored in pExpr->pList->a[0].pExpr. + ** Z is stored in pExpr->pList->a[1].pExpr. + */ + case TK_BETWEEN: { + exprCodeBetween(pParse, pExpr, target, 0, 0); + return target; + } + case TK_COLLATE: { + if( !ExprHasProperty(pExpr, EP_Collate) ){ + /* A TK_COLLATE Expr node without the EP_Collate tag is a so-called + ** "SOFT-COLLATE" that is added to constraints that are pushed down + ** from outer queries into sub-queries by the WHERE-clause push-down + ** optimization. Clear subtypes as subtypes may not cross a subquery + ** boundary. + */ + assert( pExpr->pLeft ); + sqlite3ExprCode(pParse, pExpr->pLeft, target); + sqlite3VdbeAddOp1(v, OP_ClrSubtype, target); + return target; + }else{ + pExpr = pExpr->pLeft; + goto expr_code_doover; /* 2018-04-28: Prevent deep recursion. */ + } + } + case TK_SPAN: + case TK_UPLUS: { + pExpr = pExpr->pLeft; + goto expr_code_doover; /* 2018-04-28: Prevent deep recursion. OSSFuzz. */ + } + + case TK_TRIGGER: { + /* If the opcode is TK_TRIGGER, then the expression is a reference + ** to a column in the new.* or old.* pseudo-tables available to + ** trigger programs. In this case Expr.iTable is set to 1 for the + ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn + ** is set to the column of the pseudo-table to read, or to -1 to + ** read the rowid field. + ** + ** The expression is implemented using an OP_Param opcode. The p1 + ** parameter is set to 0 for an old.rowid reference, or to (i+1) + ** to reference another column of the old.* pseudo-table, where + ** i is the index of the column. For a new.rowid reference, p1 is + ** set to (n+1), where n is the number of columns in each pseudo-table. + ** For a reference to any other column in the new.* pseudo-table, p1 + ** is set to (n+2+i), where n and i are as defined previously. For + ** example, if the table on which triggers are being fired is + ** declared as: + ** + ** CREATE TABLE t1(a, b); + ** + ** Then p1 is interpreted as follows: + ** + ** p1==0 -> old.rowid p1==3 -> new.rowid + ** p1==1 -> old.a p1==4 -> new.a + ** p1==2 -> old.b p1==5 -> new.b + */ + Table *pTab; + int iCol; + int p1; + + assert( ExprUseYTab(pExpr) ); + pTab = pExpr->y.pTab; + iCol = pExpr->iColumn; + p1 = pExpr->iTable * (pTab->nCol+1) + 1 + + sqlite3TableColumnToStorage(pTab, iCol); + + assert( pExpr->iTable==0 || pExpr->iTable==1 ); + assert( iCol>=-1 && iColnCol ); + assert( pTab->iPKey<0 || iCol!=pTab->iPKey ); + assert( p1>=0 && p1<(pTab->nCol*2+2) ); + + sqlite3VdbeAddOp2(v, OP_Param, p1, target); + VdbeComment((v, "r[%d]=%s.%s", target, + (pExpr->iTable ? "new" : "old"), + (pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[iCol].zCnName) + )); + +#ifndef SQLITE_OMIT_FLOATING_POINT + /* If the column has REAL affinity, it may currently be stored as an + ** integer. Use OP_RealAffinity to make sure it is really real. + ** + ** EVIDENCE-OF: R-60985-57662 SQLite will convert the value back to + ** floating point when extracting it from the record. */ + if( iCol>=0 && pTab->aCol[iCol].affinity==SQLITE_AFF_REAL ){ + sqlite3VdbeAddOp1(v, OP_RealAffinity, target); + } +#endif + break; + } + + case TK_VECTOR: { + sqlite3ErrorMsg(pParse, "row value misused"); + break; + } + + /* TK_IF_NULL_ROW Expr nodes are inserted ahead of expressions + ** that derive from the right-hand table of a LEFT JOIN. The + ** Expr.iTable value is the table number for the right-hand table. + ** The expression is only evaluated if that table is not currently + ** on a LEFT JOIN NULL row. + */ + case TK_IF_NULL_ROW: { + int addrINR; + u8 okConstFactor = pParse->okConstFactor; + AggInfo *pAggInfo = pExpr->pAggInfo; + if( pAggInfo ){ + assert( pExpr->iAgg>=0 && pExpr->iAggnColumn ); + if( !pAggInfo->directMode ){ + inReg = AggInfoColumnReg(pAggInfo, pExpr->iAgg); + break; + } + if( pExpr->pAggInfo->useSortingIdx ){ + sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab, + pAggInfo->aCol[pExpr->iAgg].iSorterColumn, + target); + inReg = target; + break; + } + } + addrINR = sqlite3VdbeAddOp3(v, OP_IfNullRow, pExpr->iTable, 0, target); + /* The OP_IfNullRow opcode above can overwrite the result register with + ** NULL. So we have to ensure that the result register is not a value + ** that is suppose to be a constant. Two defenses are needed: + ** (1) Temporarily disable factoring of constant expressions + ** (2) Make sure the computed value really is stored in register + ** "target" and not someplace else. + */ + pParse->okConstFactor = 0; /* note (1) above */ + sqlite3ExprCode(pParse, pExpr->pLeft, target); + assert( target==inReg ); + pParse->okConstFactor = okConstFactor; + sqlite3VdbeJumpHere(v, addrINR); + break; + } + + /* + ** Form A: + ** CASE x WHEN e1 THEN r1 WHEN e2 THEN r2 ... WHEN eN THEN rN ELSE y END + ** + ** Form B: + ** CASE WHEN e1 THEN r1 WHEN e2 THEN r2 ... WHEN eN THEN rN ELSE y END + ** + ** Form A is can be transformed into the equivalent form B as follows: + ** CASE WHEN x=e1 THEN r1 WHEN x=e2 THEN r2 ... + ** WHEN x=eN THEN rN ELSE y END + ** + ** X (if it exists) is in pExpr->pLeft. + ** Y is in the last element of pExpr->x.pList if pExpr->x.pList->nExpr is + ** odd. The Y is also optional. If the number of elements in x.pList + ** is even, then Y is omitted and the "otherwise" result is NULL. + ** Ei is in pExpr->pList->a[i*2] and Ri is pExpr->pList->a[i*2+1]. + ** + ** The result of the expression is the Ri for the first matching Ei, + ** or if there is no matching Ei, the ELSE term Y, or if there is + ** no ELSE term, NULL. + */ + case TK_CASE: { + int endLabel; /* GOTO label for end of CASE stmt */ + int nextCase; /* GOTO label for next WHEN clause */ + int nExpr; /* 2x number of WHEN terms */ + int i; /* Loop counter */ + ExprList *pEList; /* List of WHEN terms */ + struct ExprList_item *aListelem; /* Array of WHEN terms */ + Expr opCompare; /* The X==Ei expression */ + Expr *pX; /* The X expression */ + Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */ + Expr *pDel = 0; + sqlite3 *db = pParse->db; + + assert( ExprUseXList(pExpr) && pExpr->x.pList!=0 ); + assert(pExpr->x.pList->nExpr > 0); + pEList = pExpr->x.pList; + aListelem = pEList->a; + nExpr = pEList->nExpr; + endLabel = sqlite3VdbeMakeLabel(pParse); + if( (pX = pExpr->pLeft)!=0 ){ + pDel = sqlite3ExprDup(db, pX, 0); + if( db->mallocFailed ){ + sqlite3ExprDelete(db, pDel); + break; + } + testcase( pX->op==TK_COLUMN ); + sqlite3ExprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1)); + testcase( regFree1==0 ); + memset(&opCompare, 0, sizeof(opCompare)); + opCompare.op = TK_EQ; + opCompare.pLeft = pDel; + pTest = &opCompare; + /* Ticket b351d95f9cd5ef17e9d9dbae18f5ca8611190001: + ** The value in regFree1 might get SCopy-ed into the file result. + ** So make sure that the regFree1 register is not reused for other + ** purposes and possibly overwritten. */ + regFree1 = 0; + } + for(i=0; iop==TK_COLUMN ); + sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL); + testcase( aListelem[i+1].pExpr->op==TK_COLUMN ); + sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target); + sqlite3VdbeGoto(v, endLabel); + sqlite3VdbeResolveLabel(v, nextCase); + } + if( (nExpr&1)!=0 ){ + sqlite3ExprCode(pParse, pEList->a[nExpr-1].pExpr, target); + }else{ + sqlite3VdbeAddOp2(v, OP_Null, 0, target); + } + sqlite3ExprDelete(db, pDel); + setDoNotMergeFlagOnCopy(v); + sqlite3VdbeResolveLabel(v, endLabel); + break; + } +#ifndef SQLITE_OMIT_TRIGGER + case TK_RAISE: { + assert( pExpr->affExpr==OE_Rollback + || pExpr->affExpr==OE_Abort + || pExpr->affExpr==OE_Fail + || pExpr->affExpr==OE_Ignore + ); + if( !pParse->pTriggerTab && !pParse->nested ){ + sqlite3ErrorMsg(pParse, + "RAISE() may only be used within a trigger-program"); + return 0; + } + if( pExpr->affExpr==OE_Abort ){ + sqlite3MayAbort(pParse); + } + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + if( pExpr->affExpr==OE_Ignore ){ + sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, OE_Ignore); + VdbeCoverage(v); + }else{ + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + sqlite3VdbeAddOp3(v, OP_Halt, + pParse->pTriggerTab ? SQLITE_CONSTRAINT_TRIGGER : SQLITE_ERROR, + pExpr->affExpr, r1); + } + break; + } +#endif + } + sqlite3ReleaseTempReg(pParse, regFree1); + sqlite3ReleaseTempReg(pParse, regFree2); + return inReg; +} + +/* +** Generate code that will evaluate expression pExpr just one time +** per prepared statement execution. +** +** If the expression uses functions (that might throw an exception) then +** guard them with an OP_Once opcode to ensure that the code is only executed +** once. If no functions are involved, then factor the code out and put it at +** the end of the prepared statement in the initialization section. +** +** If regDest>0 then the result is always stored in that register and the +** result is not reusable. If regDest<0 then this routine is free to +** store the value wherever it wants. The register where the expression +** is stored is returned. When regDest<0, two identical expressions might +** code to the same register, if they do not contain function calls and hence +** are factored out into the initialization section at the end of the +** prepared statement. +*/ +SQLITE_PRIVATE int sqlite3ExprCodeRunJustOnce( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* The expression to code when the VDBE initializes */ + int regDest /* Store the value in this register */ +){ + ExprList *p; + assert( ConstFactorOk(pParse) ); + assert( regDest!=0 ); + p = pParse->pConstExpr; + if( regDest<0 && p ){ + struct ExprList_item *pItem; + int i; + for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){ + if( pItem->fg.reusable + && sqlite3ExprCompare(0,pItem->pExpr,pExpr,-1)==0 + ){ + return pItem->u.iConstExprReg; + } + } + } + pExpr = sqlite3ExprDup(pParse->db, pExpr, 0); + if( pExpr!=0 && ExprHasProperty(pExpr, EP_HasFunc) ){ + Vdbe *v = pParse->pVdbe; + int addr; + assert( v ); + addr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + pParse->okConstFactor = 0; + if( !pParse->db->mallocFailed ){ + if( regDest<0 ) regDest = ++pParse->nMem; + sqlite3ExprCode(pParse, pExpr, regDest); + } + pParse->okConstFactor = 1; + sqlite3ExprDelete(pParse->db, pExpr); + sqlite3VdbeJumpHere(v, addr); + }else{ + p = sqlite3ExprListAppend(pParse, p, pExpr); + if( p ){ + struct ExprList_item *pItem = &p->a[p->nExpr-1]; + pItem->fg.reusable = regDest<0; + if( regDest<0 ) regDest = ++pParse->nMem; + pItem->u.iConstExprReg = regDest; + } + pParse->pConstExpr = p; + } + return regDest; +} + +/* +** Make arrangements to invoke OP_Null on a range of registers +** during initialization. +*/ +SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3ExprNullRegisterRange( + Parse *pParse, /* Parsing context */ + int iReg, /* First register to set to NULL */ + int nReg /* Number of sequential registers to NULL out */ +){ + u8 okConstFactor = pParse->okConstFactor; + Expr t; + memset(&t, 0, sizeof(t)); + t.op = TK_NULLS; + t.y.nReg = nReg; + pParse->okConstFactor = 1; + sqlite3ExprCodeRunJustOnce(pParse, &t, iReg); + pParse->okConstFactor = okConstFactor; +} + +/* +** Generate code to evaluate an expression and store the results +** into a register. Return the register number where the results +** are stored. +** +** If the register is a temporary register that can be deallocated, +** then write its number into *pReg. If the result register is not +** a temporary, then set *pReg to zero. +** +** If pExpr is a constant, then this routine might generate this +** code to fill the register in the initialization section of the +** VDBE program, in order to factor it out of the evaluation loop. +*/ +SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ + int r2; + pExpr = sqlite3ExprSkipCollateAndLikely(pExpr); + if( ConstFactorOk(pParse) + && ALWAYS(pExpr!=0) + && pExpr->op!=TK_REGISTER + && sqlite3ExprIsConstantNotJoin(pParse, pExpr) + ){ + *pReg = 0; + r2 = sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1); + }else{ + int r1 = sqlite3GetTempReg(pParse); + r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1); + if( r2==r1 ){ + *pReg = r1; + }else{ + sqlite3ReleaseTempReg(pParse, r1); + *pReg = 0; + } + } + return r2; +} + +/* +** Generate code that will evaluate expression pExpr and store the +** results in register target. The results are guaranteed to appear +** in register target. +*/ +SQLITE_PRIVATE void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ + int inReg; + + assert( pExpr==0 || !ExprHasVVAProperty(pExpr,EP_Immutable) ); + assert( target>0 && target<=pParse->nMem ); + assert( pParse->pVdbe!=0 || pParse->db->mallocFailed ); + if( pParse->pVdbe==0 ) return; + inReg = sqlite3ExprCodeTarget(pParse, pExpr, target); + if( inReg!=target ){ + u8 op; + Expr *pX = sqlite3ExprSkipCollateAndLikely(pExpr); + testcase( pX!=pExpr ); + if( ALWAYS(pX) + && (ExprHasProperty(pX,EP_Subquery) || pX->op==TK_REGISTER) + ){ + op = OP_Copy; + }else{ + op = OP_SCopy; + } + sqlite3VdbeAddOp2(pParse->pVdbe, op, inReg, target); + } +} + +/* +** Make a transient copy of expression pExpr and then code it using +** sqlite3ExprCode(). This routine works just like sqlite3ExprCode() +** except that the input expression is guaranteed to be unchanged. +*/ +SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){ + sqlite3 *db = pParse->db; + pExpr = sqlite3ExprDup(db, pExpr, 0); + if( !db->mallocFailed ) sqlite3ExprCode(pParse, pExpr, target); + sqlite3ExprDelete(db, pExpr); +} + +/* +** Generate code that will evaluate expression pExpr and store the +** results in register target. The results are guaranteed to appear +** in register target. If the expression is constant, then this routine +** might choose to code the expression at initialization time. +*/ +SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){ + if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pParse,pExpr) ){ + sqlite3ExprCodeRunJustOnce(pParse, pExpr, target); + }else{ + sqlite3ExprCodeCopy(pParse, pExpr, target); + } +} + +/* +** Generate code that pushes the value of every element of the given +** expression list into a sequence of registers beginning at target. +** +** Return the number of elements evaluated. The number returned will +** usually be pList->nExpr but might be reduced if SQLITE_ECEL_OMITREF +** is defined. +** +** The SQLITE_ECEL_DUP flag prevents the arguments from being +** filled using OP_SCopy. OP_Copy must be used instead. +** +** The SQLITE_ECEL_FACTOR argument allows constant arguments to be +** factored out into initialization code. +** +** The SQLITE_ECEL_REF flag means that expressions in the list with +** ExprList.a[].u.x.iOrderByCol>0 have already been evaluated and stored +** in registers at srcReg, and so the value can be copied from there. +** If SQLITE_ECEL_OMITREF is also set, then the values with u.x.iOrderByCol>0 +** are simply omitted rather than being copied from srcReg. +*/ +SQLITE_PRIVATE int sqlite3ExprCodeExprList( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* The expression list to be coded */ + int target, /* Where to write results */ + int srcReg, /* Source registers if SQLITE_ECEL_REF */ + u8 flags /* SQLITE_ECEL_* flags */ +){ + struct ExprList_item *pItem; + int i, j, n; + u8 copyOp = (flags & SQLITE_ECEL_DUP) ? OP_Copy : OP_SCopy; + Vdbe *v = pParse->pVdbe; + assert( pList!=0 ); + assert( target>0 ); + assert( pParse->pVdbe!=0 ); /* Never gets this far otherwise */ + n = pList->nExpr; + if( !ConstFactorOk(pParse) ) flags &= ~SQLITE_ECEL_FACTOR; + for(pItem=pList->a, i=0; ipExpr; +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + if( pItem->fg.bSorterRef ){ + i--; + n--; + }else +#endif + if( (flags & SQLITE_ECEL_REF)!=0 && (j = pItem->u.x.iOrderByCol)>0 ){ + if( flags & SQLITE_ECEL_OMITREF ){ + i--; + n--; + }else{ + sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i); + } + }else if( (flags & SQLITE_ECEL_FACTOR)!=0 + && sqlite3ExprIsConstantNotJoin(pParse,pExpr) + ){ + sqlite3ExprCodeRunJustOnce(pParse, pExpr, target+i); + }else{ + int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i); + if( inReg!=target+i ){ + VdbeOp *pOp; + if( copyOp==OP_Copy + && (pOp=sqlite3VdbeGetLastOp(v))->opcode==OP_Copy + && pOp->p1+pOp->p3+1==inReg + && pOp->p2+pOp->p3+1==target+i + && pOp->p5==0 /* The do-not-merge flag must be clear */ + ){ + pOp->p3++; + }else{ + sqlite3VdbeAddOp2(v, copyOp, inReg, target+i); + } + } + } + } + return n; +} + +/* +** Generate code for a BETWEEN operator. +** +** x BETWEEN y AND z +** +** The above is equivalent to +** +** x>=y AND x<=z +** +** Code it as such, taking care to do the common subexpression +** elimination of x. +** +** The xJumpIf parameter determines details: +** +** NULL: Store the boolean result in reg[dest] +** sqlite3ExprIfTrue: Jump to dest if true +** sqlite3ExprIfFalse: Jump to dest if false +** +** The jumpIfNull parameter is ignored if xJumpIf is NULL. +*/ +static void exprCodeBetween( + Parse *pParse, /* Parsing and code generating context */ + Expr *pExpr, /* The BETWEEN expression */ + int dest, /* Jump destination or storage location */ + void (*xJump)(Parse*,Expr*,int,int), /* Action to take */ + int jumpIfNull /* Take the jump if the BETWEEN is NULL */ +){ + Expr exprAnd; /* The AND operator in x>=y AND x<=z */ + Expr compLeft; /* The x>=y term */ + Expr compRight; /* The x<=z term */ + int regFree1 = 0; /* Temporary use register */ + Expr *pDel = 0; + sqlite3 *db = pParse->db; + + memset(&compLeft, 0, sizeof(Expr)); + memset(&compRight, 0, sizeof(Expr)); + memset(&exprAnd, 0, sizeof(Expr)); + + assert( ExprUseXList(pExpr) ); + pDel = sqlite3ExprDup(db, pExpr->pLeft, 0); + if( db->mallocFailed==0 ){ + exprAnd.op = TK_AND; + exprAnd.pLeft = &compLeft; + exprAnd.pRight = &compRight; + compLeft.op = TK_GE; + compLeft.pLeft = pDel; + compLeft.pRight = pExpr->x.pList->a[0].pExpr; + compRight.op = TK_LE; + compRight.pLeft = pDel; + compRight.pRight = pExpr->x.pList->a[1].pExpr; + sqlite3ExprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1)); + if( xJump ){ + xJump(pParse, &exprAnd, dest, jumpIfNull); + }else{ + /* Mark the expression is being from the ON or USING clause of a join + ** so that the sqlite3ExprCodeTarget() routine will not attempt to move + ** it into the Parse.pConstExpr list. We should use a new bit for this, + ** for clarity, but we are out of bits in the Expr.flags field so we + ** have to reuse the EP_OuterON bit. Bummer. */ + pDel->flags |= EP_OuterON; + sqlite3ExprCodeTarget(pParse, &exprAnd, dest); + } + sqlite3ReleaseTempReg(pParse, regFree1); + } + sqlite3ExprDelete(db, pDel); + + /* Ensure adequate test coverage */ + testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 && regFree1==0 ); + testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 && regFree1!=0 ); + testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 && regFree1==0 ); + testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 && regFree1!=0 ); + testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 && regFree1==0 ); + testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 && regFree1!=0 ); + testcase( xJump==sqlite3ExprIfFalse && jumpIfNull!=0 && regFree1==0 ); + testcase( xJump==sqlite3ExprIfFalse && jumpIfNull!=0 && regFree1!=0 ); + testcase( xJump==0 ); +} + +/* +** Generate code for a boolean expression such that a jump is made +** to the label "dest" if the expression is true but execution +** continues straight thru if the expression is false. +** +** If the expression evaluates to NULL (neither true nor false), then +** take the jump if the jumpIfNull flag is SQLITE_JUMPIFNULL. +** +** This code depends on the fact that certain token values (ex: TK_EQ) +** are the same as opcode values (ex: OP_Eq) that implement the corresponding +** operation. Special comments in vdbe.c and the mkopcodeh.awk script in +** the make process cause these values to align. Assert()s in the code +** below verify that the numbers are aligned correctly. +*/ +SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ + Vdbe *v = pParse->pVdbe; + int op = 0; + int regFree1 = 0; + int regFree2 = 0; + int r1, r2; + + assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 ); + if( NEVER(v==0) ) return; /* Existence of VDBE checked by caller */ + if( NEVER(pExpr==0) ) return; /* No way this can happen */ + assert( !ExprHasVVAProperty(pExpr, EP_Immutable) ); + op = pExpr->op; + switch( op ){ + case TK_AND: + case TK_OR: { + Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr); + if( pAlt!=pExpr ){ + sqlite3ExprIfTrue(pParse, pAlt, dest, jumpIfNull); + }else{ + Expr *pFirst, *pSecond; + if( exprEvalRhsFirst(pExpr) ){ + pFirst = pExpr->pRight; + pSecond = pExpr->pLeft; + }else{ + pFirst = pExpr->pLeft; + pSecond = pExpr->pRight; + } + if( op==TK_AND ){ + int d2 = sqlite3VdbeMakeLabel(pParse); + testcase( jumpIfNull==0 ); + sqlite3ExprIfFalse(pParse, pFirst, d2, + jumpIfNull^SQLITE_JUMPIFNULL); + sqlite3ExprIfTrue(pParse, pSecond, dest, jumpIfNull); + sqlite3VdbeResolveLabel(v, d2); + }else{ + testcase( jumpIfNull==0 ); + sqlite3ExprIfTrue(pParse, pFirst, dest, jumpIfNull); + sqlite3ExprIfTrue(pParse, pSecond, dest, jumpIfNull); + } + } + break; + } + case TK_NOT: { + testcase( jumpIfNull==0 ); + sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); + break; + } + case TK_TRUTH: { + int isNot; /* IS NOT TRUE or IS NOT FALSE */ + int isTrue; /* IS TRUE or IS NOT TRUE */ + testcase( jumpIfNull==0 ); + isNot = pExpr->op2==TK_ISNOT; + isTrue = sqlite3ExprTruthValue(pExpr->pRight); + testcase( isTrue && isNot ); + testcase( !isTrue && isNot ); + if( isTrue ^ isNot ){ + sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, + isNot ? SQLITE_JUMPIFNULL : 0); + }else{ + sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, + isNot ? SQLITE_JUMPIFNULL : 0); + } + break; + } + case TK_IS: + case TK_ISNOT: + testcase( op==TK_IS ); + testcase( op==TK_ISNOT ); + op = (op==TK_IS) ? TK_EQ : TK_NE; + jumpIfNull = SQLITE_NULLEQ; + /* no break */ deliberate_fall_through + case TK_LT: + case TK_LE: + case TK_GT: + case TK_GE: + case TK_NE: + case TK_EQ: { + int addrIsNull; + if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr; + if( ExprHasProperty(pExpr, EP_Subquery) && jumpIfNull!=SQLITE_NULLEQ ){ + addrIsNull = exprComputeOperands(pParse, pExpr, + &r1, &r2, ®Free1, ®Free2); + }else{ + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + addrIsNull = 0; + } + codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, + r1, r2, dest, jumpIfNull, ExprHasProperty(pExpr,EP_Commuted)); + assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); + assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); + assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); + assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); + assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); + VdbeCoverageIf(v, op==OP_Eq && jumpIfNull==SQLITE_NULLEQ); + VdbeCoverageIf(v, op==OP_Eq && jumpIfNull!=SQLITE_NULLEQ); + assert(TK_NE==OP_Ne); testcase(op==OP_Ne); + VdbeCoverageIf(v, op==OP_Ne && jumpIfNull==SQLITE_NULLEQ); + VdbeCoverageIf(v, op==OP_Ne && jumpIfNull!=SQLITE_NULLEQ); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + if( addrIsNull ){ + if( jumpIfNull ){ + sqlite3VdbeChangeP2(v, addrIsNull, dest); + }else{ + sqlite3VdbeJumpHere(v, addrIsNull); + } + } + break; + } + case TK_ISNULL: + case TK_NOTNULL: { + assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL ); + assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL ); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + assert( regFree1==0 || regFree1==r1 ); + if( regFree1 ) sqlite3VdbeTypeofColumn(v, r1); + sqlite3VdbeAddOp2(v, op, r1, dest); + VdbeCoverageIf(v, op==TK_ISNULL); + VdbeCoverageIf(v, op==TK_NOTNULL); + break; + } + case TK_BETWEEN: { + testcase( jumpIfNull==0 ); + exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfTrue, jumpIfNull); + break; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_IN: { + int destIfFalse = sqlite3VdbeMakeLabel(pParse); + int destIfNull = jumpIfNull ? dest : destIfFalse; + sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull); + sqlite3VdbeGoto(v, dest); + sqlite3VdbeResolveLabel(v, destIfFalse); + break; + } +#endif + default: { + default_expr: + if( ExprAlwaysTrue(pExpr) ){ + sqlite3VdbeGoto(v, dest); + }else if( ExprAlwaysFalse(pExpr) ){ + /* No-op */ + }else{ + r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1); + sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0); + VdbeCoverage(v); + testcase( regFree1==0 ); + testcase( jumpIfNull==0 ); + } + break; + } + } + sqlite3ReleaseTempReg(pParse, regFree1); + sqlite3ReleaseTempReg(pParse, regFree2); +} + +/* +** Generate code for a boolean expression such that a jump is made +** to the label "dest" if the expression is false but execution +** continues straight thru if the expression is true. +** +** If the expression evaluates to NULL (neither true nor false) then +** jump if jumpIfNull is SQLITE_JUMPIFNULL or fall through if jumpIfNull +** is 0. +*/ +SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ + Vdbe *v = pParse->pVdbe; + int op = 0; + int regFree1 = 0; + int regFree2 = 0; + int r1, r2; + + assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 ); + if( NEVER(v==0) ) return; /* Existence of VDBE checked by caller */ + if( pExpr==0 ) return; + assert( !ExprHasVVAProperty(pExpr,EP_Immutable) ); + + /* The value of pExpr->op and op are related as follows: + ** + ** pExpr->op op + ** --------- ---------- + ** TK_ISNULL OP_NotNull + ** TK_NOTNULL OP_IsNull + ** TK_NE OP_Eq + ** TK_EQ OP_Ne + ** TK_GT OP_Le + ** TK_LE OP_Gt + ** TK_GE OP_Lt + ** TK_LT OP_Ge + ** + ** For other values of pExpr->op, op is undefined and unused. + ** The value of TK_ and OP_ constants are arranged such that we + ** can compute the mapping above using the following expression. + ** Assert()s verify that the computation is correct. + */ + op = ((pExpr->op+(TK_ISNULL&1))^1)-(TK_ISNULL&1); + + /* Verify correct alignment of TK_ and OP_ constants + */ + assert( pExpr->op!=TK_ISNULL || op==OP_NotNull ); + assert( pExpr->op!=TK_NOTNULL || op==OP_IsNull ); + assert( pExpr->op!=TK_NE || op==OP_Eq ); + assert( pExpr->op!=TK_EQ || op==OP_Ne ); + assert( pExpr->op!=TK_LT || op==OP_Ge ); + assert( pExpr->op!=TK_LE || op==OP_Gt ); + assert( pExpr->op!=TK_GT || op==OP_Le ); + assert( pExpr->op!=TK_GE || op==OP_Lt ); + + switch( pExpr->op ){ + case TK_AND: + case TK_OR: { + Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr); + if( pAlt!=pExpr ){ + sqlite3ExprIfFalse(pParse, pAlt, dest, jumpIfNull); + }else{ + Expr *pFirst, *pSecond; + if( exprEvalRhsFirst(pExpr) ){ + pFirst = pExpr->pRight; + pSecond = pExpr->pLeft; + }else{ + pFirst = pExpr->pLeft; + pSecond = pExpr->pRight; + } + if( pExpr->op==TK_AND ){ + testcase( jumpIfNull==0 ); + sqlite3ExprIfFalse(pParse, pFirst, dest, jumpIfNull); + sqlite3ExprIfFalse(pParse, pSecond, dest, jumpIfNull); + }else{ + int d2 = sqlite3VdbeMakeLabel(pParse); + testcase( jumpIfNull==0 ); + sqlite3ExprIfTrue(pParse, pFirst, d2, + jumpIfNull^SQLITE_JUMPIFNULL); + sqlite3ExprIfFalse(pParse, pSecond, dest, jumpIfNull); + sqlite3VdbeResolveLabel(v, d2); + } + } + break; + } + case TK_NOT: { + testcase( jumpIfNull==0 ); + sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); + break; + } + case TK_TRUTH: { + int isNot; /* IS NOT TRUE or IS NOT FALSE */ + int isTrue; /* IS TRUE or IS NOT TRUE */ + testcase( jumpIfNull==0 ); + isNot = pExpr->op2==TK_ISNOT; + isTrue = sqlite3ExprTruthValue(pExpr->pRight); + testcase( isTrue && isNot ); + testcase( !isTrue && isNot ); + if( isTrue ^ isNot ){ + /* IS TRUE and IS NOT FALSE */ + sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, + isNot ? 0 : SQLITE_JUMPIFNULL); + + }else{ + /* IS FALSE and IS NOT TRUE */ + sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, + isNot ? 0 : SQLITE_JUMPIFNULL); + } + break; + } + case TK_IS: + case TK_ISNOT: + testcase( pExpr->op==TK_IS ); + testcase( pExpr->op==TK_ISNOT ); + op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ; + jumpIfNull = SQLITE_NULLEQ; + /* no break */ deliberate_fall_through + case TK_LT: + case TK_LE: + case TK_GT: + case TK_GE: + case TK_NE: + case TK_EQ: { + int addrIsNull; + if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr; + if( ExprHasProperty(pExpr, EP_Subquery) && jumpIfNull!=SQLITE_NULLEQ ){ + addrIsNull = exprComputeOperands(pParse, pExpr, + &r1, &r2, ®Free1, ®Free2); + }else{ + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + addrIsNull = 0; + } + codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, + r1, r2, dest, jumpIfNull,ExprHasProperty(pExpr,EP_Commuted)); + assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); + assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); + assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt); + assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); + assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); + VdbeCoverageIf(v, op==OP_Eq && jumpIfNull!=SQLITE_NULLEQ); + VdbeCoverageIf(v, op==OP_Eq && jumpIfNull==SQLITE_NULLEQ); + assert(TK_NE==OP_Ne); testcase(op==OP_Ne); + VdbeCoverageIf(v, op==OP_Ne && jumpIfNull!=SQLITE_NULLEQ); + VdbeCoverageIf(v, op==OP_Ne && jumpIfNull==SQLITE_NULLEQ); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + if( addrIsNull ){ + if( jumpIfNull ){ + sqlite3VdbeChangeP2(v, addrIsNull, dest); + }else{ + sqlite3VdbeJumpHere(v, addrIsNull); + } + } + break; + } + case TK_ISNULL: + case TK_NOTNULL: { + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + assert( regFree1==0 || regFree1==r1 ); + if( regFree1 ) sqlite3VdbeTypeofColumn(v, r1); + sqlite3VdbeAddOp2(v, op, r1, dest); + testcase( op==TK_ISNULL ); VdbeCoverageIf(v, op==TK_ISNULL); + testcase( op==TK_NOTNULL ); VdbeCoverageIf(v, op==TK_NOTNULL); + break; + } + case TK_BETWEEN: { + testcase( jumpIfNull==0 ); + exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfFalse, jumpIfNull); + break; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_IN: { + if( jumpIfNull ){ + sqlite3ExprCodeIN(pParse, pExpr, dest, dest); + }else{ + int destIfNull = sqlite3VdbeMakeLabel(pParse); + sqlite3ExprCodeIN(pParse, pExpr, dest, destIfNull); + sqlite3VdbeResolveLabel(v, destIfNull); + } + break; + } +#endif + default: { + default_expr: + if( ExprAlwaysFalse(pExpr) ){ + sqlite3VdbeGoto(v, dest); + }else if( ExprAlwaysTrue(pExpr) ){ + /* no-op */ + }else{ + r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1); + sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0); + VdbeCoverage(v); + testcase( regFree1==0 ); + testcase( jumpIfNull==0 ); + } + break; + } + } + sqlite3ReleaseTempReg(pParse, regFree1); + sqlite3ReleaseTempReg(pParse, regFree2); +} + +/* +** Like sqlite3ExprIfFalse() except that a copy is made of pExpr before +** code generation, and that copy is deleted after code generation. This +** ensures that the original pExpr is unchanged. +*/ +SQLITE_PRIVATE void sqlite3ExprIfFalseDup(Parse *pParse, Expr *pExpr, int dest,int jumpIfNull){ + sqlite3 *db = pParse->db; + Expr *pCopy = sqlite3ExprDup(db, pExpr, 0); + if( db->mallocFailed==0 ){ + sqlite3ExprIfFalse(pParse, pCopy, dest, jumpIfNull); + } + sqlite3ExprDelete(db, pCopy); +} + +/* +** Expression pVar is guaranteed to be an SQL variable. pExpr may be any +** type of expression. +** +** If pExpr is a simple SQL value - an integer, real, string, blob +** or NULL value - then the VDBE currently being prepared is configured +** to re-prepare each time a new value is bound to variable pVar. +** +** Additionally, if pExpr is a simple SQL value and the value is the +** same as that currently bound to variable pVar, non-zero is returned. +** Otherwise, if the values are not the same or if pExpr is not a simple +** SQL value, zero is returned. +** +** If the SQLITE_EnableQPSG flag is set on the database connection, then +** this routine always returns false. +*/ +static SQLITE_NOINLINE int exprCompareVariable( + const Parse *pParse, + const Expr *pVar, + const Expr *pExpr +){ + int res = 2; + int iVar; + sqlite3_value *pL, *pR = 0; + + if( pExpr->op==TK_VARIABLE && pVar->iColumn==pExpr->iColumn ){ + return 0; + } + if( (pParse->db->flags & SQLITE_EnableQPSG)!=0 ) return 2; + sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, SQLITE_AFF_BLOB, &pR); + if( pR ){ + iVar = pVar->iColumn; + sqlite3VdbeSetVarmask(pParse->pVdbe, iVar); + pL = sqlite3VdbeGetBoundValue(pParse->pReprepare, iVar, SQLITE_AFF_BLOB); + if( pL ){ + if( sqlite3_value_type(pL)==SQLITE_TEXT ){ + sqlite3_value_text(pL); /* Make sure the encoding is UTF-8 */ + } + res = sqlite3MemCompare(pL, pR, 0) ? 2 : 0; + } + sqlite3ValueFree(pR); + sqlite3ValueFree(pL); + } + return res; +} + +/* +** Do a deep comparison of two expression trees. Return 0 if the two +** expressions are completely identical. Return 1 if they differ only +** by a COLLATE operator at the top level. Return 2 if there are differences +** other than the top-level COLLATE operator. +** +** If any subelement of pB has Expr.iTable==(-1) then it is allowed +** to compare equal to an equivalent element in pA with Expr.iTable==iTab. +** +** The pA side might be using TK_REGISTER. If that is the case and pB is +** not using TK_REGISTER but is otherwise equivalent, then still return 0. +** +** Sometimes this routine will return 2 even if the two expressions +** really are equivalent. If we cannot prove that the expressions are +** identical, we return 2 just to be safe. So if this routine +** returns 2, then you do not really know for certain if the two +** expressions are the same. But if you get a 0 or 1 return, then you +** can be sure the expressions are the same. In the places where +** this routine is used, it does not hurt to get an extra 2 - that +** just might result in some slightly slower code. But returning +** an incorrect 0 or 1 could lead to a malfunction. +** +** If pParse is not NULL and SQLITE_EnableQPSG is off then TK_VARIABLE +** terms in pA with bindings in pParse->pReprepare can be matched against +** literals in pB. The pParse->pVdbe->expmask bitmask is updated for +** each variable referenced. +*/ +SQLITE_PRIVATE int sqlite3ExprCompare( + const Parse *pParse, + const Expr *pA, + const Expr *pB, + int iTab +){ + u32 combinedFlags; + if( pA==0 || pB==0 ){ + return pB==pA ? 0 : 2; + } + if( pParse && pA->op==TK_VARIABLE ){ + return exprCompareVariable(pParse, pA, pB); + } + combinedFlags = pA->flags | pB->flags; + if( combinedFlags & EP_IntValue ){ + if( (pA->flags&pB->flags&EP_IntValue)!=0 && pA->u.iValue==pB->u.iValue ){ + return 0; + } + return 2; + } + if( pA->op!=pB->op || pA->op==TK_RAISE ){ + if( pA->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA->pLeft,pB,iTab)<2 ){ + return 1; + } + if( pB->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA,pB->pLeft,iTab)<2 ){ + return 1; + } + if( pA->op==TK_AGG_COLUMN && pB->op==TK_COLUMN + && pB->iTable<0 && pA->iTable==iTab + ){ + /* fall through */ + }else{ + return 2; + } + } + assert( !ExprHasProperty(pA, EP_IntValue) ); + assert( !ExprHasProperty(pB, EP_IntValue) ); + if( pA->u.zToken ){ + if( pA->op==TK_FUNCTION || pA->op==TK_AGG_FUNCTION ){ + if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2; +#ifndef SQLITE_OMIT_WINDOWFUNC + assert( pA->op==pB->op ); + if( ExprHasProperty(pA,EP_WinFunc)!=ExprHasProperty(pB,EP_WinFunc) ){ + return 2; + } + if( ExprHasProperty(pA,EP_WinFunc) ){ + if( sqlite3WindowCompare(pParse, pA->y.pWin, pB->y.pWin, 1)!=0 ){ + return 2; + } + } +#endif + }else if( pA->op==TK_NULL ){ + return 0; + }else if( pA->op==TK_COLLATE ){ + if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2; + }else + if( pB->u.zToken!=0 + && pA->op!=TK_COLUMN + && pA->op!=TK_AGG_COLUMN + && strcmp(pA->u.zToken,pB->u.zToken)!=0 + ){ + return 2; + } + } + if( (pA->flags & (EP_Distinct|EP_Commuted)) + != (pB->flags & (EP_Distinct|EP_Commuted)) ) return 2; + if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){ + if( combinedFlags & EP_xIsSelect ) return 2; + if( (combinedFlags & EP_FixedCol)==0 + && sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2; + if( sqlite3ExprCompare(pParse, pA->pRight, pB->pRight, iTab) ) return 2; + if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2; + if( pA->op!=TK_STRING + && pA->op!=TK_TRUEFALSE + && ALWAYS((combinedFlags & EP_Reduced)==0) + ){ + if( pA->iColumn!=pB->iColumn ) return 2; + if( pA->op2!=pB->op2 && pA->op==TK_TRUTH ) return 2; + if( pA->op!=TK_IN && pA->iTable!=pB->iTable && pA->iTable!=iTab ){ + return 2; + } + } + } + return 0; +} + +/* +** Compare two ExprList objects. Return 0 if they are identical, 1 +** if they are certainly different, or 2 if it is not possible to +** determine if they are identical or not. +** +** If any subelement of pB has Expr.iTable==(-1) then it is allowed +** to compare equal to an equivalent element in pA with Expr.iTable==iTab. +** +** This routine might return non-zero for equivalent ExprLists. The +** only consequence will be disabled optimizations. But this routine +** must never return 0 if the two ExprList objects are different, or +** a malfunction will result. +** +** Two NULL pointers are considered to be the same. But a NULL pointer +** always differs from a non-NULL pointer. +*/ +SQLITE_PRIVATE int sqlite3ExprListCompare(const ExprList *pA, const ExprList *pB, int iTab){ + int i; + if( pA==0 && pB==0 ) return 0; + if( pA==0 || pB==0 ) return 1; + if( pA->nExpr!=pB->nExpr ) return 1; + for(i=0; inExpr; i++){ + int res; + Expr *pExprA = pA->a[i].pExpr; + Expr *pExprB = pB->a[i].pExpr; + if( pA->a[i].fg.sortFlags!=pB->a[i].fg.sortFlags ) return 1; + if( (res = sqlite3ExprCompare(0, pExprA, pExprB, iTab)) ) return res; + } + return 0; +} + +/* +** Like sqlite3ExprCompare() except COLLATE operators at the top-level +** are ignored. +*/ +SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr *pA,Expr *pB, int iTab){ + return sqlite3ExprCompare(0, + sqlite3ExprSkipCollate(pA), + sqlite3ExprSkipCollate(pB), + iTab); +} + +/* +** Return non-zero if Expr p can only be true if pNN is not NULL. +** +** Or if seenNot is true, return non-zero if Expr p can only be +** non-NULL if pNN is not NULL +*/ +static int exprImpliesNotNull( + const Parse *pParse,/* Parsing context */ + const Expr *p, /* The expression to be checked */ + const Expr *pNN, /* The expression that is NOT NULL */ + int iTab, /* Table being evaluated */ + int seenNot /* Return true only if p can be any non-NULL value */ +){ + assert( p ); + assert( pNN ); + if( sqlite3ExprCompare(pParse, p, pNN, iTab)==0 ){ + return pNN->op!=TK_NULL; + } + switch( p->op ){ + case TK_IN: { + if( seenNot && ExprHasProperty(p, EP_xIsSelect) ) return 0; + assert( ExprUseXSelect(p) || (p->x.pList!=0 && p->x.pList->nExpr>0) ); + return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1); + } + case TK_BETWEEN: { + ExprList *pList; + assert( ExprUseXList(p) ); + pList = p->x.pList; + assert( pList!=0 ); + assert( pList->nExpr==2 ); + if( seenNot ) return 0; + if( exprImpliesNotNull(pParse, pList->a[0].pExpr, pNN, iTab, 1) + || exprImpliesNotNull(pParse, pList->a[1].pExpr, pNN, iTab, 1) + ){ + return 1; + } + return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1); + } + case TK_EQ: + case TK_NE: + case TK_LT: + case TK_LE: + case TK_GT: + case TK_GE: + case TK_PLUS: + case TK_MINUS: + case TK_BITOR: + case TK_LSHIFT: + case TK_RSHIFT: + case TK_CONCAT: + seenNot = 1; + /* no break */ deliberate_fall_through + case TK_STAR: + case TK_REM: + case TK_BITAND: + case TK_SLASH: { + if( exprImpliesNotNull(pParse, p->pRight, pNN, iTab, seenNot) ) return 1; + /* no break */ deliberate_fall_through + } + case TK_SPAN: + case TK_COLLATE: + case TK_UPLUS: + case TK_UMINUS: { + return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot); + } + case TK_TRUTH: { + if( seenNot ) return 0; + if( p->op2!=TK_IS ) return 0; + return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1); + } + case TK_BITNOT: + case TK_NOT: { + return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1); + } + } + return 0; +} + +/* +** Return true if the boolean value of the expression is always either +** FALSE or NULL. +*/ +static int sqlite3ExprIsNotTrue(Expr *pExpr){ + int v; + if( pExpr->op==TK_NULL ) return 1; + if( pExpr->op==TK_TRUEFALSE && sqlite3ExprTruthValue(pExpr)==0 ) return 1; + v = 1; + if( sqlite3ExprIsInteger(pExpr, &v, 0) && v==0 ) return 1; + return 0; +} + +/* +** Return true if the expression is one of the following: +** +** CASE WHEN x THEN y END +** CASE WHEN x THEN y ELSE NULL END +** CASE WHEN x THEN y ELSE false END +** iif(x,y) +** iif(x,y,NULL) +** iif(x,y,false) +*/ +static int sqlite3ExprIsIIF(sqlite3 *db, const Expr *pExpr){ + ExprList *pList; + if( pExpr->op==TK_FUNCTION ){ + const char *z = pExpr->u.zToken; + FuncDef *pDef; + if( (z[0]!='i' && z[0]!='I') ) return 0; + if( pExpr->x.pList==0 ) return 0; + pDef = sqlite3FindFunction(db, z, pExpr->x.pList->nExpr, ENC(db), 0); +#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION + if( pDef==0 ) return 0; +#else + if( NEVER(pDef==0) ) return 0; +#endif + if( (pDef->funcFlags & SQLITE_FUNC_INLINE)==0 ) return 0; + if( SQLITE_PTR_TO_INT(pDef->pUserData)!=INLINEFUNC_iif ) return 0; + }else if( pExpr->op==TK_CASE ){ + if( pExpr->pLeft!=0 ) return 0; + }else{ + return 0; + } + pList = pExpr->x.pList; + assert( pList!=0 ); + if( pList->nExpr==2 ) return 1; + if( pList->nExpr==3 && sqlite3ExprIsNotTrue(pList->a[2].pExpr) ) return 1; + return 0; +} + +/* +** Return true if we can prove the pE2 will always be true if pE1 is +** true. Return false if we cannot complete the proof or if pE2 might +** be false. Examples: +** +** pE1: x==5 pE2: x==5 Result: true +** pE1: x>0 pE2: x==5 Result: false +** pE1: x=21 pE2: x=21 OR y=43 Result: true +** pE1: x!=123 pE2: x IS NOT NULL Result: true +** pE1: x!=?1 pE2: x IS NOT NULL Result: true +** pE1: x IS NULL pE2: x IS NOT NULL Result: false +** pE1: x IS ?2 pE2: x IS NOT NULL Result: false +** pE1: iif(x,y) pE2: x Result: true +** PE1: iif(x,y,0) pE2: x Result: true +** +** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has +** Expr.iTable<0 then assume a table number given by iTab. +** +** If pParse is not NULL, then the values of bound variables in pE1 are +** compared against literal values in pE2 and pParse->pVdbe->expmask is +** modified to record which bound variables are referenced. If pParse +** is NULL, then false will be returned if pE1 contains any bound variables. +** +** When in doubt, return false. Returning true might give a performance +** improvement. Returning false might cause a performance reduction, but +** it will always give the correct answer and is hence always safe. +*/ +SQLITE_PRIVATE int sqlite3ExprImpliesExpr( + const Parse *pParse, + const Expr *pE1, + const Expr *pE2, + int iTab +){ + if( sqlite3ExprCompare(pParse, pE1, pE2, iTab)==0 ){ + return 1; + } + if( pE2->op==TK_OR + && (sqlite3ExprImpliesExpr(pParse, pE1, pE2->pLeft, iTab) + || sqlite3ExprImpliesExpr(pParse, pE1, pE2->pRight, iTab) ) + ){ + return 1; + } + if( pE2->op==TK_NOTNULL + && exprImpliesNotNull(pParse, pE1, pE2->pLeft, iTab, 0) + ){ + return 1; + } + if( sqlite3ExprIsIIF(pParse->db, pE1) ){ + return sqlite3ExprImpliesExpr(pParse,pE1->x.pList->a[0].pExpr,pE2,iTab); + } + return 0; +} + +/* This is a helper function to impliesNotNullRow(). In this routine, +** set pWalker->eCode to one only if *both* of the input expressions +** separately have the implies-not-null-row property. +*/ +static void bothImplyNotNullRow(Walker *pWalker, Expr *pE1, Expr *pE2){ + if( pWalker->eCode==0 ){ + sqlite3WalkExpr(pWalker, pE1); + if( pWalker->eCode ){ + pWalker->eCode = 0; + sqlite3WalkExpr(pWalker, pE2); + } + } +} + +/* +** This is the Expr node callback for sqlite3ExprImpliesNonNullRow(). +** If the expression node requires that the table at pWalker->iCur +** have one or more non-NULL column, then set pWalker->eCode to 1 and abort. +** +** pWalker->mWFlags is non-zero if this inquiry is being undertaking on +** behalf of a RIGHT JOIN (or FULL JOIN). That makes a difference when +** evaluating terms in the ON clause of an inner join. +** +** This routine controls an optimization. False positives (setting +** pWalker->eCode to 1 when it should not be) are deadly, but false-negatives +** (never setting pWalker->eCode) is a harmless missed optimization. +*/ +static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ + testcase( pExpr->op==TK_AGG_COLUMN ); + testcase( pExpr->op==TK_AGG_FUNCTION ); + if( ExprHasProperty(pExpr, EP_OuterON) ) return WRC_Prune; + if( ExprHasProperty(pExpr, EP_InnerON) && pWalker->mWFlags ){ + /* If iCur is used in an inner-join ON clause to the left of a + ** RIGHT JOIN, that does *not* mean that the table must be non-null. + ** But it is difficult to check for that condition precisely. + ** To keep things simple, any use of iCur from any inner-join is + ** ignored while attempting to simplify a RIGHT JOIN. */ + return WRC_Prune; + } + switch( pExpr->op ){ + case TK_ISNOT: + case TK_ISNULL: + case TK_NOTNULL: + case TK_IS: + case TK_VECTOR: + case TK_FUNCTION: + case TK_TRUTH: + case TK_CASE: + testcase( pExpr->op==TK_ISNOT ); + testcase( pExpr->op==TK_ISNULL ); + testcase( pExpr->op==TK_NOTNULL ); + testcase( pExpr->op==TK_IS ); + testcase( pExpr->op==TK_VECTOR ); + testcase( pExpr->op==TK_FUNCTION ); + testcase( pExpr->op==TK_TRUTH ); + testcase( pExpr->op==TK_CASE ); + return WRC_Prune; + + case TK_COLUMN: + if( pWalker->u.iCur==pExpr->iTable ){ + pWalker->eCode = 1; + return WRC_Abort; + } + return WRC_Prune; + + case TK_OR: + case TK_AND: + /* Both sides of an AND or OR must separately imply non-null-row. + ** Consider these cases: + ** 1. NOT (x AND y) + ** 2. x OR y + ** If only one of x or y is non-null-row, then the overall expression + ** can be true if the other arm is false (case 1) or true (case 2). + */ + testcase( pExpr->op==TK_OR ); + testcase( pExpr->op==TK_AND ); + bothImplyNotNullRow(pWalker, pExpr->pLeft, pExpr->pRight); + return WRC_Prune; + + case TK_IN: + /* Beware of "x NOT IN ()" and "x NOT IN (SELECT 1 WHERE false)", + ** both of which can be true. But apart from these cases, if + ** the left-hand side of the IN is NULL then the IN itself will be + ** NULL. */ + if( ExprUseXList(pExpr) && ALWAYS(pExpr->x.pList->nExpr>0) ){ + sqlite3WalkExpr(pWalker, pExpr->pLeft); + } + return WRC_Prune; + + case TK_BETWEEN: + /* In "x NOT BETWEEN y AND z" either x must be non-null-row or else + ** both y and z must be non-null row */ + assert( ExprUseXList(pExpr) ); + assert( pExpr->x.pList->nExpr==2 ); + sqlite3WalkExpr(pWalker, pExpr->pLeft); + bothImplyNotNullRow(pWalker, pExpr->x.pList->a[0].pExpr, + pExpr->x.pList->a[1].pExpr); + return WRC_Prune; + + /* Virtual tables are allowed to use constraints like x=NULL. So + ** a term of the form x=y does not prove that y is not null if x + ** is the column of a virtual table */ + case TK_EQ: + case TK_NE: + case TK_LT: + case TK_LE: + case TK_GT: + case TK_GE: { + Expr *pLeft = pExpr->pLeft; + Expr *pRight = pExpr->pRight; + testcase( pExpr->op==TK_EQ ); + testcase( pExpr->op==TK_NE ); + testcase( pExpr->op==TK_LT ); + testcase( pExpr->op==TK_LE ); + testcase( pExpr->op==TK_GT ); + testcase( pExpr->op==TK_GE ); + /* The y.pTab=0 assignment in wherecode.c always happens after the + ** impliesNotNullRow() test */ + assert( pLeft->op!=TK_COLUMN || ExprUseYTab(pLeft) ); + assert( pRight->op!=TK_COLUMN || ExprUseYTab(pRight) ); + if( (pLeft->op==TK_COLUMN + && ALWAYS(pLeft->y.pTab!=0) + && IsVirtual(pLeft->y.pTab)) + || (pRight->op==TK_COLUMN + && ALWAYS(pRight->y.pTab!=0) + && IsVirtual(pRight->y.pTab)) + ){ + return WRC_Prune; + } + /* no break */ deliberate_fall_through + } + default: + return WRC_Continue; + } +} + +/* +** Return true (non-zero) if expression p can only be true if at least +** one column of table iTab is non-null. In other words, return true +** if expression p will always be NULL or false if every column of iTab +** is NULL. +** +** False negatives are acceptable. In other words, it is ok to return +** zero even if expression p will never be true of every column of iTab +** is NULL. A false negative is merely a missed optimization opportunity. +** +** False positives are not allowed, however. A false positive may result +** in an incorrect answer. +** +** Terms of p that are marked with EP_OuterON (and hence that come from +** the ON or USING clauses of OUTER JOINS) are excluded from the analysis. +** +** This routine is used to check if a LEFT JOIN can be converted into +** an ordinary JOIN. The p argument is the WHERE clause. If the WHERE +** clause requires that some column of the right table of the LEFT JOIN +** be non-NULL, then the LEFT JOIN can be safely converted into an +** ordinary join. +*/ +SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab, int isRJ){ + Walker w; + p = sqlite3ExprSkipCollateAndLikely(p); + if( p==0 ) return 0; + if( p->op==TK_NOTNULL ){ + p = p->pLeft; + }else{ + while( p->op==TK_AND ){ + if( sqlite3ExprImpliesNonNullRow(p->pLeft, iTab, isRJ) ) return 1; + p = p->pRight; + } + } + w.xExprCallback = impliesNotNullRow; + w.xSelectCallback = 0; + w.xSelectCallback2 = 0; + w.eCode = 0; + w.mWFlags = isRJ!=0; + w.u.iCur = iTab; + sqlite3WalkExpr(&w, p); + return w.eCode; +} + +/* +** An instance of the following structure is used by the tree walker +** to determine if an expression can be evaluated by reference to the +** index only, without having to do a search for the corresponding +** table entry. The IdxCover.pIdx field is the index. IdxCover.iCur +** is the cursor for the table. +*/ +struct IdxCover { + Index *pIdx; /* The index to be tested for coverage */ + int iCur; /* Cursor number for the table corresponding to the index */ +}; + +/* +** Check to see if there are references to columns in table +** pWalker->u.pIdxCover->iCur can be satisfied using the index +** pWalker->u.pIdxCover->pIdx. +*/ +static int exprIdxCover(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_COLUMN + && pExpr->iTable==pWalker->u.pIdxCover->iCur + && sqlite3TableColumnToIndex(pWalker->u.pIdxCover->pIdx, pExpr->iColumn)<0 + ){ + pWalker->eCode = 1; + return WRC_Abort; + } + return WRC_Continue; +} + +/* +** Determine if an index pIdx on table with cursor iCur contains will +** the expression pExpr. Return true if the index does cover the +** expression and false if the pExpr expression references table columns +** that are not found in the index pIdx. +** +** An index covering an expression means that the expression can be +** evaluated using only the index and without having to lookup the +** corresponding table entry. +*/ +SQLITE_PRIVATE int sqlite3ExprCoveredByIndex( + Expr *pExpr, /* The index to be tested */ + int iCur, /* The cursor number for the corresponding table */ + Index *pIdx /* The index that might be used for coverage */ +){ + Walker w; + struct IdxCover xcov; + memset(&w, 0, sizeof(w)); + xcov.iCur = iCur; + xcov.pIdx = pIdx; + w.xExprCallback = exprIdxCover; + w.u.pIdxCover = &xcov; + sqlite3WalkExpr(&w, pExpr); + return !w.eCode; +} + + +/* Structure used to pass information throughout the Walker in order to +** implement sqlite3ReferencesSrcList(). +*/ +struct RefSrcList { + sqlite3 *db; /* Database connection used for sqlite3DbRealloc() */ + SrcList *pRef; /* Looking for references to these tables */ + i64 nExclude; /* Number of tables to exclude from the search */ + int *aiExclude; /* Cursor IDs for tables to exclude from the search */ +}; + +/* +** Walker SELECT callbacks for sqlite3ReferencesSrcList(). +** +** When entering a new subquery on the pExpr argument, add all FROM clause +** entries for that subquery to the exclude list. +** +** When leaving the subquery, remove those entries from the exclude list. +*/ +static int selectRefEnter(Walker *pWalker, Select *pSelect){ + struct RefSrcList *p = pWalker->u.pRefSrcList; + SrcList *pSrc = pSelect->pSrc; + i64 i, j; + int *piNew; + if( pSrc->nSrc==0 ) return WRC_Continue; + j = p->nExclude; + p->nExclude += pSrc->nSrc; + piNew = sqlite3DbRealloc(p->db, p->aiExclude, p->nExclude*sizeof(int)); + if( piNew==0 ){ + p->nExclude = 0; + return WRC_Abort; + }else{ + p->aiExclude = piNew; + } + for(i=0; inSrc; i++, j++){ + p->aiExclude[j] = pSrc->a[i].iCursor; + } + return WRC_Continue; +} +static void selectRefLeave(Walker *pWalker, Select *pSelect){ + struct RefSrcList *p = pWalker->u.pRefSrcList; + SrcList *pSrc = pSelect->pSrc; + if( p->nExclude ){ + assert( p->nExclude>=pSrc->nSrc ); + p->nExclude -= pSrc->nSrc; + } +} + +/* This is the Walker EXPR callback for sqlite3ReferencesSrcList(). +** +** Set the 0x01 bit of pWalker->eCode if there is a reference to any +** of the tables shown in RefSrcList.pRef. +** +** Set the 0x02 bit of pWalker->eCode if there is a reference to a +** table is in neither RefSrcList.pRef nor RefSrcList.aiExclude. +*/ +static int exprRefToSrcList(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_COLUMN + || pExpr->op==TK_AGG_COLUMN + ){ + int i; + struct RefSrcList *p = pWalker->u.pRefSrcList; + SrcList *pSrc = p->pRef; + int nSrc = pSrc ? pSrc->nSrc : 0; + for(i=0; iiTable==pSrc->a[i].iCursor ){ + pWalker->eCode |= 1; + return WRC_Continue; + } + } + for(i=0; inExclude && p->aiExclude[i]!=pExpr->iTable; i++){} + if( i>=p->nExclude ){ + pWalker->eCode |= 2; + } + } + return WRC_Continue; +} + +/* +** Check to see if pExpr references any tables in pSrcList. +** Possible return values: +** +** 1 pExpr does references a table in pSrcList. +** +** 0 pExpr references some table that is not defined in either +** pSrcList or in subqueries of pExpr itself. +** +** -1 pExpr only references no tables at all, or it only +** references tables defined in subqueries of pExpr itself. +** +** As currently used, pExpr is always an aggregate function call. That +** fact is exploited for efficiency. +*/ +SQLITE_PRIVATE int sqlite3ReferencesSrcList(Parse *pParse, Expr *pExpr, SrcList *pSrcList){ + Walker w; + struct RefSrcList x; + assert( pParse->db!=0 ); + memset(&w, 0, sizeof(w)); + memset(&x, 0, sizeof(x)); + w.xExprCallback = exprRefToSrcList; + w.xSelectCallback = selectRefEnter; + w.xSelectCallback2 = selectRefLeave; + w.u.pRefSrcList = &x; + x.db = pParse->db; + x.pRef = pSrcList; + assert( pExpr->op==TK_AGG_FUNCTION ); + assert( ExprUseXList(pExpr) ); + sqlite3WalkExprList(&w, pExpr->x.pList); + if( pExpr->pLeft ){ + assert( pExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pExpr->pLeft) ); + assert( pExpr->pLeft->x.pList!=0 ); + sqlite3WalkExprList(&w, pExpr->pLeft->x.pList); + } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( ExprHasProperty(pExpr, EP_WinFunc) ){ + sqlite3WalkExpr(&w, pExpr->y.pWin->pFilter); + } +#endif + if( x.aiExclude ) sqlite3DbNNFreeNN(pParse->db, x.aiExclude); + if( w.eCode & 0x01 ){ + return 1; + }else if( w.eCode ){ + return 0; + }else{ + return -1; + } +} + +/* +** This is a Walker expression node callback. +** +** For Expr nodes that contain pAggInfo pointers, make sure the AggInfo +** object that is referenced does not refer directly to the Expr. If +** it does, make a copy. This is done because the pExpr argument is +** subject to change. +** +** The copy is scheduled for deletion using the sqlite3ExprDeferredDelete() +** which builds on the sqlite3ParserAddCleanup() mechanism. +*/ +static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){ + if( ALWAYS(!ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced)) + && pExpr->pAggInfo!=0 + ){ + AggInfo *pAggInfo = pExpr->pAggInfo; + int iAgg = pExpr->iAgg; + Parse *pParse = pWalker->pParse; + sqlite3 *db = pParse->db; + assert( iAgg>=0 ); + if( pExpr->op!=TK_AGG_FUNCTION ){ + if( iAggnColumn + && pAggInfo->aCol[iAgg].pCExpr==pExpr + ){ + pExpr = sqlite3ExprDup(db, pExpr, 0); + if( pExpr && !sqlite3ExprDeferredDelete(pParse, pExpr) ){ + pAggInfo->aCol[iAgg].pCExpr = pExpr; + } + } + }else{ + assert( pExpr->op==TK_AGG_FUNCTION ); + if( ALWAYS(iAggnFunc) + && pAggInfo->aFunc[iAgg].pFExpr==pExpr + ){ + pExpr = sqlite3ExprDup(db, pExpr, 0); + if( pExpr && !sqlite3ExprDeferredDelete(pParse, pExpr) ){ + pAggInfo->aFunc[iAgg].pFExpr = pExpr; + } + } + } + } + return WRC_Continue; +} + +/* +** Initialize a Walker object so that will persist AggInfo entries referenced +** by the tree that is walked. +*/ +SQLITE_PRIVATE void sqlite3AggInfoPersistWalkerInit(Walker *pWalker, Parse *pParse){ + memset(pWalker, 0, sizeof(*pWalker)); + pWalker->pParse = pParse; + pWalker->xExprCallback = agginfoPersistExprCb; + pWalker->xSelectCallback = sqlite3SelectWalkNoop; +} + +/* +** Add a new element to the pAggInfo->aCol[] array. Return the index of +** the new element. Return a negative number if malloc fails. +*/ +static int addAggInfoColumn(sqlite3 *db, AggInfo *pInfo){ + int i; + pInfo->aCol = sqlite3ArrayAllocate( + db, + pInfo->aCol, + sizeof(pInfo->aCol[0]), + &pInfo->nColumn, + &i + ); + return i; +} + +/* +** Add a new element to the pAggInfo->aFunc[] array. Return the index of +** the new element. Return a negative number if malloc fails. +*/ +static int addAggInfoFunc(sqlite3 *db, AggInfo *pInfo){ + int i; + pInfo->aFunc = sqlite3ArrayAllocate( + db, + pInfo->aFunc, + sizeof(pInfo->aFunc[0]), + &pInfo->nFunc, + &i + ); + return i; +} + +/* +** Search the AggInfo object for an aCol[] entry that has iTable and iColumn. +** Return the index in aCol[] of the entry that describes that column. +** +** If no prior entry is found, create a new one and return -1. The +** new column will have an index of pAggInfo->nColumn-1. +*/ +static void findOrCreateAggInfoColumn( + Parse *pParse, /* Parsing context */ + AggInfo *pAggInfo, /* The AggInfo object to search and/or modify */ + Expr *pExpr /* Expr describing the column to find or insert */ +){ + struct AggInfo_col *pCol; + int k; + int mxTerm = pParse->db->aLimit[SQLITE_LIMIT_COLUMN]; + + assert( mxTerm <= SMXV(i16) ); + assert( pAggInfo->iFirstReg==0 ); + pCol = pAggInfo->aCol; + for(k=0; knColumn; k++, pCol++){ + if( pCol->pCExpr==pExpr ) return; + if( pCol->iTable==pExpr->iTable + && pCol->iColumn==pExpr->iColumn + && pExpr->op!=TK_IF_NULL_ROW + ){ + goto fix_up_expr; + } + } + k = addAggInfoColumn(pParse->db, pAggInfo); + if( k<0 ){ + /* OOM on resize */ + assert( pParse->db->mallocFailed ); + return; + } + if( k>mxTerm ){ + sqlite3ErrorMsg(pParse, "more than %d aggregate terms", mxTerm); + k = mxTerm; + } + pCol = &pAggInfo->aCol[k]; + assert( ExprUseYTab(pExpr) ); + pCol->pTab = pExpr->y.pTab; + pCol->iTable = pExpr->iTable; + pCol->iColumn = pExpr->iColumn; + pCol->iSorterColumn = -1; + pCol->pCExpr = pExpr; + if( pAggInfo->pGroupBy && pExpr->op!=TK_IF_NULL_ROW ){ + int j, n; + ExprList *pGB = pAggInfo->pGroupBy; + struct ExprList_item *pTerm = pGB->a; + n = pGB->nExpr; + for(j=0; jpExpr; + if( pE->op==TK_COLUMN + && pE->iTable==pExpr->iTable + && pE->iColumn==pExpr->iColumn + ){ + pCol->iSorterColumn = j; + break; + } + } + } + if( pCol->iSorterColumn<0 ){ + pCol->iSorterColumn = pAggInfo->nSortingColumn++; + } +fix_up_expr: + ExprSetVVAProperty(pExpr, EP_NoReduce); + assert( pExpr->pAggInfo==0 || pExpr->pAggInfo==pAggInfo ); + pExpr->pAggInfo = pAggInfo; + if( pExpr->op==TK_COLUMN ){ + pExpr->op = TK_AGG_COLUMN; + } + assert( k <= SMXV(pExpr->iAgg) ); + pExpr->iAgg = (i16)k; +} + +/* +** This is the xExprCallback for a tree walker. It is used to +** implement sqlite3ExprAnalyzeAggregates(). See sqlite3ExprAnalyzeAggregates +** for additional information. +*/ +static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ + int i; + NameContext *pNC = pWalker->u.pNC; + Parse *pParse = pNC->pParse; + SrcList *pSrcList = pNC->pSrcList; + AggInfo *pAggInfo = pNC->uNC.pAggInfo; + + assert( pNC->ncFlags & NC_UAggInfo ); + assert( pAggInfo->iFirstReg==0 ); + switch( pExpr->op ){ + default: { + IndexedExpr *pIEpr; + Expr tmp; + assert( pParse->iSelfTab==0 ); + if( (pNC->ncFlags & NC_InAggFunc)==0 ) break; + if( pParse->pIdxEpr==0 ) break; + for(pIEpr=pParse->pIdxEpr; pIEpr; pIEpr=pIEpr->pIENext){ + int iDataCur = pIEpr->iDataCur; + if( iDataCur<0 ) continue; + if( sqlite3ExprCompare(0, pExpr, pIEpr->pExpr, iDataCur)==0 ) break; + } + if( pIEpr==0 ) break; + if( NEVER(!ExprUseYTab(pExpr)) ) break; + for(i=0; inSrc; i++){ + if( pSrcList->a[i].iCursor==pIEpr->iDataCur ){ + testcase( i>0 ); + break; + } + } + if( i>=pSrcList->nSrc ) break; + if( NEVER(pExpr->pAggInfo!=0) ) break; /* Resolved by outer context */ + if( pParse->nErr ){ return WRC_Abort; } + + /* If we reach this point, it means that expression pExpr can be + ** translated into a reference to an index column as described by + ** pIEpr. + */ + memset(&tmp, 0, sizeof(tmp)); + tmp.op = TK_AGG_COLUMN; + tmp.iTable = pIEpr->iIdxCur; + tmp.iColumn = pIEpr->iIdxCol; + findOrCreateAggInfoColumn(pParse, pAggInfo, &tmp); + if( pParse->nErr ){ return WRC_Abort; } + assert( pAggInfo->aCol!=0 ); + assert( tmp.iAggnColumn ); + pAggInfo->aCol[tmp.iAgg].pCExpr = pExpr; + pExpr->pAggInfo = pAggInfo; + pExpr->iAgg = tmp.iAgg; + return WRC_Prune; + } + case TK_IF_NULL_ROW: + case TK_AGG_COLUMN: + case TK_COLUMN: { + testcase( pExpr->op==TK_AGG_COLUMN ); + testcase( pExpr->op==TK_COLUMN ); + testcase( pExpr->op==TK_IF_NULL_ROW ); + /* Check to see if the column is in one of the tables in the FROM + ** clause of the aggregate query */ + if( ALWAYS(pSrcList!=0) ){ + SrcItem *pItem = pSrcList->a; + for(i=0; inSrc; i++, pItem++){ + assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); + if( pExpr->iTable==pItem->iCursor ){ + findOrCreateAggInfoColumn(pParse, pAggInfo, pExpr); + break; + } /* endif pExpr->iTable==pItem->iCursor */ + } /* end loop over pSrcList */ + } + return WRC_Continue; + } + case TK_AGG_FUNCTION: { + if( (pNC->ncFlags & NC_InAggFunc)==0 + && pWalker->walkerDepth==pExpr->op2 + && pExpr->pAggInfo==0 + ){ + /* Check to see if pExpr is a duplicate of another aggregate + ** function that is already in the pAggInfo structure + */ + struct AggInfo_func *pItem = pAggInfo->aFunc; + int mxTerm = pParse->db->aLimit[SQLITE_LIMIT_COLUMN]; + assert( mxTerm <= SMXV(i16) ); + for(i=0; inFunc; i++, pItem++){ + if( NEVER(pItem->pFExpr==pExpr) ) break; + if( sqlite3ExprCompare(0, pItem->pFExpr, pExpr, -1)==0 ){ + break; + } + } + if( i>mxTerm ){ + sqlite3ErrorMsg(pParse, "more than %d aggregate terms", mxTerm); + i = mxTerm; + assert( inFunc ); + }else if( i>=pAggInfo->nFunc ){ + /* pExpr is original. Make a new entry in pAggInfo->aFunc[] + */ + u8 enc = ENC(pParse->db); + i = addAggInfoFunc(pParse->db, pAggInfo); + if( i>=0 ){ + int nArg; + assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); + pItem = &pAggInfo->aFunc[i]; + pItem->pFExpr = pExpr; + assert( ExprUseUToken(pExpr) ); + nArg = pExpr->x.pList ? pExpr->x.pList->nExpr : 0; + pItem->pFunc = sqlite3FindFunction(pParse->db, + pExpr->u.zToken, nArg, enc, 0); + assert( pItem->bOBUnique==0 ); + if( pExpr->pLeft + && (pItem->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)==0 + ){ + /* The NEEDCOLL test above causes any ORDER BY clause on + ** aggregate min() or max() to be ignored. */ + ExprList *pOBList; + assert( nArg>0 ); + assert( pExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pExpr->pLeft) ); + pItem->iOBTab = pParse->nTab++; + pOBList = pExpr->pLeft->x.pList; + assert( pOBList->nExpr>0 ); + assert( pItem->bOBUnique==0 ); + if( pOBList->nExpr==1 + && nArg==1 + && sqlite3ExprCompare(0,pOBList->a[0].pExpr, + pExpr->x.pList->a[0].pExpr,0)==0 + ){ + pItem->bOBPayload = 0; + pItem->bOBUnique = ExprHasProperty(pExpr, EP_Distinct); + }else{ + pItem->bOBPayload = 1; + } + pItem->bUseSubtype = + (pItem->pFunc->funcFlags & SQLITE_SUBTYPE)!=0; + }else{ + pItem->iOBTab = -1; + } + if( ExprHasProperty(pExpr, EP_Distinct) && !pItem->bOBUnique ){ + pItem->iDistinct = pParse->nTab++; + }else{ + pItem->iDistinct = -1; + } + } + } + /* Make pExpr point to the appropriate pAggInfo->aFunc[] entry + */ + assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); + ExprSetVVAProperty(pExpr, EP_NoReduce); + assert( i <= SMXV(pExpr->iAgg) ); + pExpr->iAgg = (i16)i; + pExpr->pAggInfo = pAggInfo; + return WRC_Prune; + }else{ + return WRC_Continue; + } + } + } + return WRC_Continue; +} + +/* +** Analyze the pExpr expression looking for aggregate functions and +** for variables that need to be added to AggInfo object that pNC->pAggInfo +** points to. Additional entries are made on the AggInfo object as +** necessary. +** +** This routine should only be called after the expression has been +** analyzed by sqlite3ResolveExprNames(). +*/ +SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){ + Walker w; + w.xExprCallback = analyzeAggregate; + w.xSelectCallback = sqlite3WalkerDepthIncrease; + w.xSelectCallback2 = sqlite3WalkerDepthDecrease; + w.walkerDepth = 0; + w.u.pNC = pNC; + w.pParse = 0; + assert( pNC->pSrcList!=0 ); + sqlite3WalkExpr(&w, pExpr); +} + +/* +** Call sqlite3ExprAnalyzeAggregates() for every expression in an +** expression list. Return the number of errors. +** +** If an error is found, the analysis is cut short. +*/ +SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext *pNC, ExprList *pList){ + struct ExprList_item *pItem; + int i; + if( pList ){ + for(pItem=pList->a, i=0; inExpr; i++, pItem++){ + sqlite3ExprAnalyzeAggregates(pNC, pItem->pExpr); + } + } +} + +/* +** Allocate a single new register for use to hold some intermediate result. +*/ +SQLITE_PRIVATE int sqlite3GetTempReg(Parse *pParse){ + if( pParse->nTempReg==0 ){ + return ++pParse->nMem; + } + return pParse->aTempReg[--pParse->nTempReg]; +} + +/* +** Deallocate a register, making available for reuse for some other +** purpose. +*/ +SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){ + if( iReg ){ + sqlite3VdbeReleaseRegisters(pParse, iReg, 1, 0, 0); + if( pParse->nTempRegaTempReg) ){ + pParse->aTempReg[pParse->nTempReg++] = iReg; + } + } +} + +/* +** Allocate or deallocate a block of nReg consecutive registers. +*/ +SQLITE_PRIVATE int sqlite3GetTempRange(Parse *pParse, int nReg){ + int i, n; + if( nReg==1 ) return sqlite3GetTempReg(pParse); + i = pParse->iRangeReg; + n = pParse->nRangeReg; + if( nReg<=n ){ + pParse->iRangeReg += nReg; + pParse->nRangeReg -= nReg; + }else{ + i = pParse->nMem+1; + pParse->nMem += nReg; + } + return i; +} +SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){ + if( nReg==1 ){ + sqlite3ReleaseTempReg(pParse, iReg); + return; + } + sqlite3VdbeReleaseRegisters(pParse, iReg, nReg, 0, 0); + if( nReg>pParse->nRangeReg ){ + pParse->nRangeReg = nReg; + pParse->iRangeReg = iReg; + } +} + +/* +** Mark all temporary registers as being unavailable for reuse. +** +** Always invoke this procedure after coding a subroutine or co-routine +** that might be invoked from other parts of the code, to ensure that +** the sub/co-routine does not use registers in common with the code that +** invokes the sub/co-routine. +*/ +SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse *pParse){ + pParse->nTempReg = 0; + pParse->nRangeReg = 0; +} + +/* +** Make sure sufficient registers have been allocated so that +** iReg is a valid register number. +*/ +SQLITE_PRIVATE void sqlite3TouchRegister(Parse *pParse, int iReg){ + if( pParse->nMemnMem = iReg; +} + +#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_DEBUG) +/* +** Return the latest reusable register in the set of all registers. +** The value returned is no less than iMin. If any register iMin or +** greater is in permanent use, then return one more than that last +** permanent register. +*/ +SQLITE_PRIVATE int sqlite3FirstAvailableRegister(Parse *pParse, int iMin){ + const ExprList *pList = pParse->pConstExpr; + if( pList ){ + int i; + for(i=0; inExpr; i++){ + if( pList->a[i].u.iConstExprReg>=iMin ){ + iMin = pList->a[i].u.iConstExprReg + 1; + } + } + } + pParse->nTempReg = 0; + pParse->nRangeReg = 0; + return iMin; +} +#endif /* SQLITE_ENABLE_STAT4 || SQLITE_DEBUG */ + +/* +** Validate that no temporary register falls within the range of +** iFirst..iLast, inclusive. This routine is only call from within assert() +** statements. +*/ +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse *pParse, int iFirst, int iLast){ + int i; + if( pParse->nRangeReg>0 + && pParse->iRangeReg+pParse->nRangeReg > iFirst + && pParse->iRangeReg <= iLast + ){ + return 0; + } + for(i=0; inTempReg; i++){ + if( pParse->aTempReg[i]>=iFirst && pParse->aTempReg[i]<=iLast ){ + return 0; + } + } + if( pParse->pConstExpr ){ + ExprList *pList = pParse->pConstExpr; + for(i=0; inExpr; i++){ + int iReg = pList->a[i].u.iConstExprReg; + if( iReg==0 ) continue; + if( iReg>=iFirst && iReg<=iLast ) return 0; + } + } + return 1; +} +#endif /* SQLITE_DEBUG */ + +/************** End of expr.c ************************************************/ +/************** Begin file alter.c *******************************************/ +/* +** 2005 February 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains C code routines that used to generate VDBE code +** that implements the ALTER TABLE command. +*/ +/* #include "sqliteInt.h" */ + +/* +** The code in this file only exists if we are not omitting the +** ALTER TABLE logic from the build. +*/ +#ifndef SQLITE_OMIT_ALTERTABLE + +/* +** Parameter zName is the name of a table that is about to be altered +** (either with ALTER TABLE ... RENAME TO or ALTER TABLE ... ADD COLUMN). +** If the table is a system table, this function leaves an error message +** in pParse->zErr (system tables may not be altered) and returns non-zero. +** +** Or, if zName is not a system table, zero is returned. +*/ +static int isAlterableTable(Parse *pParse, Table *pTab){ + if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) +#ifndef SQLITE_OMIT_VIRTUALTABLE + || (pTab->tabFlags & TF_Eponymous)!=0 + || ( (pTab->tabFlags & TF_Shadow)!=0 + && sqlite3ReadOnlyShadowTables(pParse->db) + ) +#endif + ){ + sqlite3ErrorMsg(pParse, "table %s may not be altered", pTab->zName); + return 1; + } + return 0; +} + +/* +** Generate code to verify that the schemas of database zDb and, if +** bTemp is not true, database "temp", can still be parsed. This is +** called at the end of the generation of an ALTER TABLE ... RENAME ... +** statement to ensure that the operation has not rendered any schema +** objects unusable. +*/ +static void renameTestSchema( + Parse *pParse, /* Parse context */ + const char *zDb, /* Name of db to verify schema of */ + int bTemp, /* True if this is the temp db */ + const char *zWhen, /* "when" part of error message */ + int bNoDQS /* Do not allow DQS in the schema */ +){ + pParse->colNamesSet = 1; + sqlite3NestedParse(pParse, + "SELECT 1 " + "FROM \"%w\"." LEGACY_SCHEMA_TABLE " " + "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" + " AND sql NOT LIKE 'create virtual%%'" + " AND sqlite_rename_test(%Q, sql, type, name, %d, %Q, %d)=NULL ", + zDb, + zDb, bTemp, zWhen, bNoDQS + ); + + if( bTemp==0 ){ + sqlite3NestedParse(pParse, + "SELECT 1 " + "FROM temp." LEGACY_SCHEMA_TABLE " " + "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" + " AND sql NOT LIKE 'create virtual%%'" + " AND sqlite_rename_test(%Q, sql, type, name, 1, %Q, %d)=NULL ", + zDb, zWhen, bNoDQS + ); + } +} + +/* +** Generate VM code to replace any double-quoted strings (but not double-quoted +** identifiers) within the "sql" column of the sqlite_schema table in +** database zDb with their single-quoted equivalents. If argument bTemp is +** not true, similarly update all SQL statements in the sqlite_schema table +** of the temp db. +*/ +static void renameFixQuotes(Parse *pParse, const char *zDb, int bTemp){ + sqlite3NestedParse(pParse, + "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE + " SET sql = sqlite_rename_quotefix(%Q, sql)" + "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" + " AND sql NOT LIKE 'create virtual%%'" , zDb, zDb + ); + if( bTemp==0 ){ + sqlite3NestedParse(pParse, + "UPDATE temp." LEGACY_SCHEMA_TABLE + " SET sql = sqlite_rename_quotefix('temp', sql)" + "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" + " AND sql NOT LIKE 'create virtual%%'" + ); + } +} + +/* +** Generate code to reload the schema for database iDb. And, if iDb!=1, for +** the temp database as well. +*/ +static void renameReloadSchema(Parse *pParse, int iDb, u16 p5){ + Vdbe *v = pParse->pVdbe; + if( v ){ + sqlite3ChangeCookie(pParse, iDb); + sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, iDb, 0, p5); + if( iDb!=1 ) sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, 1, 0, p5); + } +} + +/* +** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" +** command. +*/ +SQLITE_PRIVATE void sqlite3AlterRenameTable( + Parse *pParse, /* Parser context. */ + SrcList *pSrc, /* The table to rename. */ + Token *pName /* The new table name. */ +){ + int iDb; /* Database that contains the table */ + char *zDb; /* Name of database iDb */ + Table *pTab; /* Table being renamed */ + char *zName = 0; /* NULL-terminated version of pName */ + sqlite3 *db = pParse->db; /* Database connection */ + int nTabName; /* Number of UTF-8 characters in zTabName */ + const char *zTabName; /* Original name of the table */ + Vdbe *v; + VTable *pVTab = 0; /* Non-zero if this is a v-tab with an xRename() */ + + if( NEVER(db->mallocFailed) ) goto exit_rename_table; + assert( pSrc->nSrc==1 ); + assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); + + pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); + if( !pTab ) goto exit_rename_table; + iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + zDb = db->aDb[iDb].zDbSName; + + /* Get a NULL terminated version of the new table name. */ + zName = sqlite3NameFromToken(db, pName); + if( !zName ) goto exit_rename_table; + + /* Check that a table or index named 'zName' does not already exist + ** in database iDb. If so, this is an error. + */ + if( sqlite3FindTable(db, zName, zDb) + || sqlite3FindIndex(db, zName, zDb) + || sqlite3IsShadowTableOf(db, pTab, zName) + ){ + sqlite3ErrorMsg(pParse, + "there is already another table or index with this name: %s", zName); + goto exit_rename_table; + } + + /* Make sure it is not a system table being altered, or a reserved name + ** that the table is being renamed to. + */ + if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){ + goto exit_rename_table; + } + if( SQLITE_OK!=sqlite3CheckObjectName(pParse,zName,"table",zName) ){ + goto exit_rename_table; + } + +#ifndef SQLITE_OMIT_VIEW + if( IsView(pTab) ){ + sqlite3ErrorMsg(pParse, "view %s may not be altered", pTab->zName); + goto exit_rename_table; + } +#endif + +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Invoke the authorization callback. */ + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ + goto exit_rename_table; + } +#endif + +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( sqlite3ViewGetColumnNames(pParse, pTab) ){ + goto exit_rename_table; + } + if( IsVirtual(pTab) ){ + pVTab = sqlite3GetVTable(db, pTab); + if( pVTab->pVtab->pModule->xRename==0 ){ + pVTab = 0; + } + } +#endif + + /* Begin a transaction for database iDb. Then modify the schema cookie + ** (since the ALTER TABLE modifies the schema). Call sqlite3MayAbort(), + ** as the scalar functions (e.g. sqlite_rename_table()) invoked by the + ** nested SQL may raise an exception. */ + v = sqlite3GetVdbe(pParse); + if( v==0 ){ + goto exit_rename_table; + } + sqlite3MayAbort(pParse); + + /* figure out how many UTF-8 characters are in zName */ + zTabName = pTab->zName; + nTabName = sqlite3Utf8CharLen(zTabName, -1); + + /* Rewrite all CREATE TABLE, INDEX, TRIGGER or VIEW statements in + ** the schema to use the new table name. */ + sqlite3NestedParse(pParse, + "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET " + "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) " + "WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)" + "AND name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" + , zDb, zDb, zTabName, zName, (iDb==1), zTabName + ); + + /* Update the tbl_name and name columns of the sqlite_schema table + ** as required. */ + sqlite3NestedParse(pParse, + "UPDATE %Q." LEGACY_SCHEMA_TABLE " SET " + "tbl_name = %Q, " + "name = CASE " + "WHEN type='table' THEN %Q " + "WHEN name LIKE 'sqliteX_autoindex%%' ESCAPE 'X' " + " AND type='index' THEN " + "'sqlite_autoindex_' || %Q || substr(name,%d+18) " + "ELSE name END " + "WHERE tbl_name=%Q COLLATE nocase AND " + "(type='table' OR type='index' OR type='trigger');", + zDb, + zName, zName, zName, + nTabName, zTabName + ); + +#ifndef SQLITE_OMIT_AUTOINCREMENT + /* If the sqlite_sequence table exists in this database, then update + ** it with the new table name. + */ + if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){ + sqlite3NestedParse(pParse, + "UPDATE \"%w\".sqlite_sequence set name = %Q WHERE name = %Q", + zDb, zName, pTab->zName); + } +#endif + + /* If the table being renamed is not itself part of the temp database, + ** edit view and trigger definitions within the temp database + ** as required. */ + if( iDb!=1 ){ + sqlite3NestedParse(pParse, + "UPDATE sqlite_temp_schema SET " + "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, 1), " + "tbl_name = " + "CASE WHEN tbl_name=%Q COLLATE nocase AND " + " sqlite_rename_test(%Q, sql, type, name, 1, 'after rename', 0) " + "THEN %Q ELSE tbl_name END " + "WHERE type IN ('view', 'trigger')" + , zDb, zTabName, zName, zTabName, zDb, zName); + } + + /* If this is a virtual table, invoke the xRename() function if + ** one is defined. The xRename() callback will modify the names + ** of any resources used by the v-table implementation (including other + ** SQLite tables) that are identified by the name of the virtual table. + */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( pVTab ){ + int i = ++pParse->nMem; + sqlite3VdbeLoadString(v, i, zName); + sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB); + } +#endif + + renameReloadSchema(pParse, iDb, INITFLAG_AlterRename); + renameTestSchema(pParse, zDb, iDb==1, "after rename", 0); + +exit_rename_table: + sqlite3SrcListDelete(db, pSrc); + sqlite3DbFree(db, zName); +} + +/* +** Write code that will raise an error if the table described by +** zDb and zTab is not empty. +*/ +static void sqlite3ErrorIfNotEmpty( + Parse *pParse, /* Parsing context */ + const char *zDb, /* Schema holding the table */ + const char *zTab, /* Table to check for empty */ + const char *zErr /* Error message text */ +){ + sqlite3NestedParse(pParse, + "SELECT raise(ABORT,%Q) FROM \"%w\".\"%w\"", + zErr, zDb, zTab + ); +} + +/* +** This function is called after an "ALTER TABLE ... ADD" statement +** has been parsed. Argument pColDef contains the text of the new +** column definition. +** +** The Table structure pParse->pNewTable was extended to include +** the new column during parsing. +*/ +SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ + Table *pNew; /* Copy of pParse->pNewTable */ + Table *pTab; /* Table being altered */ + int iDb; /* Database number */ + const char *zDb; /* Database name */ + const char *zTab; /* Table name */ + char *zCol; /* Null-terminated column definition */ + Column *pCol; /* The new column */ + Expr *pDflt; /* Default value for the new column */ + sqlite3 *db; /* The database connection; */ + Vdbe *v; /* The prepared statement under construction */ + int r1; /* Temporary registers */ + + db = pParse->db; + assert( db->pParse==pParse ); + if( pParse->nErr ) return; + assert( db->mallocFailed==0 ); + pNew = pParse->pNewTable; + assert( pNew ); + + assert( sqlite3BtreeHoldsAllMutexes(db) ); + iDb = sqlite3SchemaToIndex(db, pNew->pSchema); + zDb = db->aDb[iDb].zDbSName; + zTab = &pNew->zName[16]; /* Skip the "sqlite_altertab_" prefix on the name */ + pCol = &pNew->aCol[pNew->nCol-1]; + pDflt = sqlite3ColumnExpr(pNew, pCol); + pTab = sqlite3FindTable(db, zTab, zDb); + assert( pTab ); + +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Invoke the authorization callback. */ + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ + return; + } +#endif + + + /* Check that the new column is not specified as PRIMARY KEY or UNIQUE. + ** If there is a NOT NULL constraint, then the default value for the + ** column must not be NULL. + */ + if( pCol->colFlags & COLFLAG_PRIMKEY ){ + sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column"); + return; + } + if( pNew->pIndex ){ + sqlite3ErrorMsg(pParse, + "Cannot add a UNIQUE column"); + return; + } + if( (pCol->colFlags & COLFLAG_GENERATED)==0 ){ + /* If the default value for the new column was specified with a + ** literal NULL, then set pDflt to 0. This simplifies checking + ** for an SQL NULL default below. + */ + assert( pDflt==0 || pDflt->op==TK_SPAN ); + if( pDflt && pDflt->pLeft->op==TK_NULL ){ + pDflt = 0; + } + assert( IsOrdinaryTable(pNew) ); + if( (db->flags&SQLITE_ForeignKeys) && pNew->u.tab.pFKey && pDflt ){ + sqlite3ErrorIfNotEmpty(pParse, zDb, zTab, + "Cannot add a REFERENCES column with non-NULL default value"); + } + if( pCol->notNull && !pDflt ){ + sqlite3ErrorIfNotEmpty(pParse, zDb, zTab, + "Cannot add a NOT NULL column with default value NULL"); + } + + + /* Ensure the default expression is something that sqlite3ValueFromExpr() + ** can handle (i.e. not CURRENT_TIME etc.) + */ + if( pDflt ){ + sqlite3_value *pVal = 0; + int rc; + rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_BLOB, &pVal); + assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); + if( rc!=SQLITE_OK ){ + assert( db->mallocFailed == 1 ); + return; + } + if( !pVal ){ + sqlite3ErrorIfNotEmpty(pParse, zDb, zTab, + "Cannot add a column with non-constant default"); + } + sqlite3ValueFree(pVal); + } + }else if( pCol->colFlags & COLFLAG_STORED ){ + sqlite3ErrorIfNotEmpty(pParse, zDb, zTab, "cannot add a STORED column"); + } + + + /* Modify the CREATE TABLE statement. */ + zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n); + if( zCol ){ + char *zEnd = &zCol[pColDef->n-1]; + while( zEnd>zCol && (*zEnd==';' || sqlite3Isspace(*zEnd)) ){ + *zEnd-- = '\0'; + } + /* substr() operations on characters, but addColOffset is in bytes. So we + ** have to use printf() to translate between these units: */ + assert( IsOrdinaryTable(pTab) ); + assert( IsOrdinaryTable(pNew) ); + sqlite3NestedParse(pParse, + "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET " + "sql = printf('%%.%ds, ',sql) || %Q" + " || substr(sql,1+length(printf('%%.%ds',sql))) " + "WHERE type = 'table' AND name = %Q", + zDb, pNew->u.tab.addColOffset, zCol, pNew->u.tab.addColOffset, + zTab + ); + sqlite3DbFree(db, zCol); + } + + v = sqlite3GetVdbe(pParse); + if( v ){ + /* Make sure the schema version is at least 3. But do not upgrade + ** from less than 3 to 4, as that will corrupt any preexisting DESC + ** index. + */ + r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT); + sqlite3VdbeUsesBtree(v, iDb); + sqlite3VdbeAddOp2(v, OP_AddImm, r1, -2); + sqlite3VdbeAddOp2(v, OP_IfPos, r1, sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3); + sqlite3ReleaseTempReg(pParse, r1); + + /* Reload the table definition */ + renameReloadSchema(pParse, iDb, INITFLAG_AlterAdd); + + /* Verify that constraints are still satisfied */ + if( pNew->pCheck!=0 + || (pCol->notNull && (pCol->colFlags & COLFLAG_GENERATED)!=0) + || (pTab->tabFlags & TF_Strict)!=0 + ){ + sqlite3NestedParse(pParse, + "SELECT CASE WHEN quick_check GLOB 'CHECK*'" + " THEN raise(ABORT,'CHECK constraint failed')" + " WHEN quick_check GLOB 'non-* value in*'" + " THEN raise(ABORT,'type mismatch on DEFAULT')" + " ELSE raise(ABORT,'NOT NULL constraint failed')" + " END" + " FROM pragma_quick_check(%Q,%Q)" + " WHERE quick_check GLOB 'CHECK*'" + " OR quick_check GLOB 'NULL*'" + " OR quick_check GLOB 'non-* value in*'", + zTab, zDb + ); + } + } +} + +/* +** This function is called by the parser after the table-name in +** an "ALTER TABLE ADD" statement is parsed. Argument +** pSrc is the full-name of the table being altered. +** +** This routine makes a (partial) copy of the Table structure +** for the table being altered and sets Parse.pNewTable to point +** to it. Routines called by the parser as the column definition +** is parsed (i.e. sqlite3AddColumn()) add the new Column data to +** the copy. The copy of the Table structure is deleted by tokenize.c +** after parsing is finished. +** +** Routine sqlite3AlterFinishAddColumn() will be called to complete +** coding the "ALTER TABLE ... ADD" statement. +*/ +SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ + Table *pNew; + Table *pTab; + int iDb; + int i; + int nAlloc; + sqlite3 *db = pParse->db; + + /* Look up the table being altered. */ + assert( pParse->pNewTable==0 ); + assert( sqlite3BtreeHoldsAllMutexes(db) ); + if( NEVER(db->mallocFailed) ) goto exit_begin_add_column; + pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); + if( !pTab ) goto exit_begin_add_column; + +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + sqlite3ErrorMsg(pParse, "virtual tables may not be altered"); + goto exit_begin_add_column; + } +#endif + + /* Make sure this is not an attempt to ALTER a view. */ + if( IsView(pTab) ){ + sqlite3ErrorMsg(pParse, "Cannot add a column to a view"); + goto exit_begin_add_column; + } + if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){ + goto exit_begin_add_column; + } + + sqlite3MayAbort(pParse); + assert( IsOrdinaryTable(pTab) ); + assert( pTab->u.tab.addColOffset>0 ); + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + + /* Put a copy of the Table struct in Parse.pNewTable for the + ** sqlite3AddColumn() function and friends to modify. But modify + ** the name by adding an "sqlite_altertab_" prefix. By adding this + ** prefix, we insure that the name will not collide with an existing + ** table because user table are not allowed to have the "sqlite_" + ** prefix on their name. + */ + pNew = (Table*)sqlite3DbMallocZero(db, sizeof(Table)); + if( !pNew ) goto exit_begin_add_column; + pParse->pNewTable = pNew; + pNew->nTabRef = 1; + pNew->nCol = pTab->nCol; + assert( pNew->nCol>0 ); + nAlloc = (((pNew->nCol-1)/8)*8)+8; + assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 ); + pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*(u32)nAlloc); + pNew->zName = sqlite3MPrintf(db, "sqlite_altertab_%s", pTab->zName); + if( !pNew->aCol || !pNew->zName ){ + assert( db->mallocFailed ); + goto exit_begin_add_column; + } + memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*(size_t)pNew->nCol); + for(i=0; inCol; i++){ + Column *pCol = &pNew->aCol[i]; + pCol->zCnName = sqlite3DbStrDup(db, pCol->zCnName); + pCol->hName = sqlite3StrIHash(pCol->zCnName); + } + assert( IsOrdinaryTable(pNew) ); + pNew->u.tab.pDfltList = sqlite3ExprListDup(db, pTab->u.tab.pDfltList, 0); + pNew->pSchema = db->aDb[iDb].pSchema; + pNew->u.tab.addColOffset = pTab->u.tab.addColOffset; + assert( pNew->nTabRef==1 ); + +exit_begin_add_column: + sqlite3SrcListDelete(db, pSrc); + return; +} + +/* +** Parameter pTab is the subject of an ALTER TABLE ... RENAME COLUMN +** command. This function checks if the table is a view or virtual +** table (columns of views or virtual tables may not be renamed). If so, +** it loads an error message into pParse and returns non-zero. +** +** Or, if pTab is not a view or virtual table, zero is returned. +*/ +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) +static int isRealTable(Parse *pParse, Table *pTab, int iOp){ + const char *zType = 0; +#ifndef SQLITE_OMIT_VIEW + if( IsView(pTab) ){ + zType = "view"; + } +#endif +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + zType = "virtual table"; + } +#endif + if( zType ){ + const char *azMsg[] = { + "rename columns of", "drop column from", "edit constraints of" + }; + assert( iOp>=0 && iOpzName + ); + return 1; + } + return 0; +} +#else /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */ +# define isRealTable(x,y,z) (0) +#endif + +/* +** Handles the following parser reduction: +** +** cmd ::= ALTER TABLE pSrc RENAME COLUMN pOld TO pNew +*/ +SQLITE_PRIVATE void sqlite3AlterRenameColumn( + Parse *pParse, /* Parsing context */ + SrcList *pSrc, /* Table being altered. pSrc->nSrc==1 */ + Token *pOld, /* Name of column being changed */ + Token *pNew /* New column name */ +){ + sqlite3 *db = pParse->db; /* Database connection */ + Table *pTab; /* Table being updated */ + int iCol; /* Index of column being renamed */ + char *zOld = 0; /* Old column name */ + char *zNew = 0; /* New column name */ + const char *zDb; /* Name of schema containing the table */ + int iSchema; /* Index of the schema */ + int bQuote; /* True to quote the new name */ + + /* Locate the table to be altered */ + pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); + if( !pTab ) goto exit_rename_column; + + /* Cannot alter a system table */ + if( SQLITE_OK!=isAlterableTable(pParse, pTab) ) goto exit_rename_column; + if( SQLITE_OK!=isRealTable(pParse, pTab, 0) ) goto exit_rename_column; + + /* Which schema holds the table to be altered */ + iSchema = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iSchema>=0 ); + zDb = db->aDb[iSchema].zDbSName; + +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Invoke the authorization callback. */ + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ + goto exit_rename_column; + } +#endif + + /* Make sure the old name really is a column name in the table to be + ** altered. Set iCol to be the index of the column being renamed */ + zOld = sqlite3NameFromToken(db, pOld); + if( !zOld ) goto exit_rename_column; + iCol = sqlite3ColumnIndex(pTab, zOld); + if( iCol<0 ){ + sqlite3ErrorMsg(pParse, "no such column: \"%T\"", pOld); + goto exit_rename_column; + } + + /* Ensure the schema contains no double-quoted strings */ + renameTestSchema(pParse, zDb, iSchema==1, "", 0); + renameFixQuotes(pParse, zDb, iSchema==1); + + /* Do the rename operation using a recursive UPDATE statement that + ** uses the sqlite_rename_column() SQL function to compute the new + ** CREATE statement text for the sqlite_schema table. + */ + sqlite3MayAbort(pParse); + zNew = sqlite3NameFromToken(db, pNew); + if( !zNew ) goto exit_rename_column; + assert( pNew->n>0 ); + bQuote = sqlite3Isquote(pNew->z[0]); + sqlite3NestedParse(pParse, + "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET " + "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) " + "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X' " + " AND (type != 'index' OR tbl_name = %Q)", + zDb, + zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1, + pTab->zName + ); + + sqlite3NestedParse(pParse, + "UPDATE temp." LEGACY_SCHEMA_TABLE " SET " + "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, 1) " + "WHERE type IN ('trigger', 'view')", + zDb, pTab->zName, iCol, zNew, bQuote + ); + + /* Drop and reload the database schema. */ + renameReloadSchema(pParse, iSchema, INITFLAG_AlterRename); + renameTestSchema(pParse, zDb, iSchema==1, "after rename", 1); + + exit_rename_column: + sqlite3SrcListDelete(db, pSrc); + sqlite3DbFree(db, zOld); + sqlite3DbFree(db, zNew); + return; +} + +/* +** Each RenameToken object maps an element of the parse tree into +** the token that generated that element. The parse tree element +** might be one of: +** +** * A pointer to an Expr that represents an ID +** * The name of a table column in Column.zName +** +** A list of RenameToken objects can be constructed during parsing. +** Each new object is created by sqlite3RenameTokenMap(). +** As the parse tree is transformed, the sqlite3RenameTokenRemap() +** routine is used to keep the mapping current. +** +** After the parse finishes, renameTokenFind() routine can be used +** to look up the actual token value that created some element in +** the parse tree. +*/ +struct RenameToken { + const void *p; /* Parse tree element created by token t */ + Token t; /* The token that created parse tree element p */ + RenameToken *pNext; /* Next is a list of all RenameToken objects */ +}; + +/* +** The context of an ALTER TABLE RENAME COLUMN operation that gets passed +** down into the Walker. +*/ +typedef struct RenameCtx RenameCtx; +struct RenameCtx { + RenameToken *pList; /* List of tokens to overwrite */ + int nList; /* Number of tokens in pList */ + int iCol; /* Index of column being renamed */ + Table *pTab; /* Table being ALTERed */ + const char *zOld; /* Old column name */ +}; + +#ifdef SQLITE_DEBUG +/* +** This function is only for debugging. It performs two tasks: +** +** 1. Checks that pointer pPtr does not already appear in the +** rename-token list. +** +** 2. Dereferences each pointer in the rename-token list. +** +** The second is most effective when debugging under valgrind or +** address-sanitizer or similar. If any of these pointers no longer +** point to valid objects, an exception is raised by the memory-checking +** tool. +** +** The point of this is to prevent comparisons of invalid pointer values. +** Even though this always seems to work, it is undefined according to the +** C standard. Example of undefined comparison: +** +** sqlite3_free(x); +** if( x==y ) ... +** +** Technically, as x no longer points into a valid object or to the byte +** following a valid object, it may not be used in comparison operations. +*/ +static void renameTokenCheckAll(Parse *pParse, const void *pPtr){ + assert( pParse==pParse->db->pParse ); + assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 ); + if( pParse->nErr==0 ){ + const RenameToken *p; + u32 i = 1; + for(p=pParse->pRename; p; p=p->pNext){ + if( p->p ){ + assert( p->p!=pPtr ); + i += *(u8*)(p->p) | 1; + } + } + assert( i>0 ); + } +} +#else +# define renameTokenCheckAll(x,y) +#endif + +/* +** Remember that the parser tree element pPtr was created using +** the token pToken. +** +** In other words, construct a new RenameToken object and add it +** to the list of RenameToken objects currently being built up +** in pParse->pRename. +** +** The pPtr argument is returned so that this routine can be used +** with tail recursion in tokenExpr() routine, for a small performance +** improvement. +*/ +SQLITE_PRIVATE const void *sqlite3RenameTokenMap( + Parse *pParse, + const void *pPtr, + const Token *pToken +){ + RenameToken *pNew; + assert( pPtr || pParse->db->mallocFailed ); + renameTokenCheckAll(pParse, pPtr); + if( ALWAYS(pParse->eParseMode!=PARSE_MODE_UNMAP) ){ + pNew = sqlite3DbMallocZero(pParse->db, sizeof(RenameToken)); + if( pNew ){ + pNew->p = pPtr; + pNew->t = *pToken; + pNew->pNext = pParse->pRename; + pParse->pRename = pNew; + } + } + + return pPtr; +} + +/* +** It is assumed that there is already a RenameToken object associated +** with parse tree element pFrom. This function remaps the associated token +** to parse tree element pTo. +*/ +SQLITE_PRIVATE void sqlite3RenameTokenRemap(Parse *pParse, const void *pTo, const void *pFrom){ + RenameToken *p; + renameTokenCheckAll(pParse, pTo); + for(p=pParse->pRename; p; p=p->pNext){ + if( p->p==pFrom ){ + p->p = pTo; + break; + } + } +} + +/* +** Walker callback used by sqlite3RenameExprUnmap(). +*/ +static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){ + Parse *pParse = pWalker->pParse; + sqlite3RenameTokenRemap(pParse, 0, (const void*)pExpr); + if( ExprUseYTab(pExpr) ){ + sqlite3RenameTokenRemap(pParse, 0, (const void*)&pExpr->y.pTab); + } + return WRC_Continue; +} + +/* +** Iterate through the Select objects that are part of WITH clauses attached +** to select statement pSelect. +*/ +static void renameWalkWith(Walker *pWalker, Select *pSelect){ + With *pWith = pSelect->pWith; + if( pWith ){ + Parse *pParse = pWalker->pParse; + int i; + With *pCopy = 0; + assert( pWith->nCte>0 ); + if( (pWith->a[0].pSelect->selFlags & SF_Expanded)==0 ){ + /* Push a copy of the With object onto the with-stack. We use a copy + ** here as the original will be expanded and resolved (flags SF_Expanded + ** and SF_Resolved) below. And the parser code that uses the with-stack + ** fails if the Select objects on it have already been expanded and + ** resolved. */ + pCopy = sqlite3WithDup(pParse->db, pWith); + pCopy = sqlite3WithPush(pParse, pCopy, 1); + } + for(i=0; inCte; i++){ + Select *p = pWith->a[i].pSelect; + NameContext sNC; + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + if( pCopy ) sqlite3SelectPrep(sNC.pParse, p, &sNC); + if( sNC.pParse->db->mallocFailed ) return; + sqlite3WalkSelect(pWalker, p); + sqlite3RenameExprlistUnmap(pParse, pWith->a[i].pCols); + } + if( pCopy && pParse->pWith==pCopy ){ + pParse->pWith = pCopy->pOuter; + } + } +} + +/* +** Unmap all tokens in the IdList object passed as the second argument. +*/ +static void unmapColumnIdlistNames( + Parse *pParse, + const IdList *pIdList +){ + int ii; + assert( pIdList!=0 ); + for(ii=0; iinId; ii++){ + sqlite3RenameTokenRemap(pParse, 0, (const void*)pIdList->a[ii].zName); + } +} + +/* +** Walker callback used by sqlite3RenameExprUnmap(). +*/ +static int renameUnmapSelectCb(Walker *pWalker, Select *p){ + Parse *pParse = pWalker->pParse; + int i; + if( pParse->nErr ) return WRC_Abort; + testcase( p->selFlags & SF_View ); + testcase( p->selFlags & SF_CopyCte ); + if( p->selFlags & (SF_View|SF_CopyCte) ){ + return WRC_Prune; + } + if( ALWAYS(p->pEList) ){ + ExprList *pList = p->pEList; + for(i=0; inExpr; i++){ + if( pList->a[i].zEName && pList->a[i].fg.eEName==ENAME_NAME ){ + sqlite3RenameTokenRemap(pParse, 0, (void*)pList->a[i].zEName); + } + } + } + if( ALWAYS(p->pSrc) ){ /* Every Select as a SrcList, even if it is empty */ + SrcList *pSrc = p->pSrc; + for(i=0; inSrc; i++){ + sqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName); + if( pSrc->a[i].fg.isUsing==0 ){ + sqlite3WalkExpr(pWalker, pSrc->a[i].u3.pOn); + }else{ + unmapColumnIdlistNames(pParse, pSrc->a[i].u3.pUsing); + } + } + } + + renameWalkWith(pWalker, p); + return WRC_Continue; +} + +/* +** Remove all nodes that are part of expression pExpr from the rename list. +*/ +SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse *pParse, Expr *pExpr){ + u8 eMode = pParse->eParseMode; + Walker sWalker; + memset(&sWalker, 0, sizeof(Walker)); + sWalker.pParse = pParse; + sWalker.xExprCallback = renameUnmapExprCb; + sWalker.xSelectCallback = renameUnmapSelectCb; + pParse->eParseMode = PARSE_MODE_UNMAP; + sqlite3WalkExpr(&sWalker, pExpr); + pParse->eParseMode = eMode; +} + +/* +** Remove all nodes that are part of expression-list pEList from the +** rename list. +*/ +SQLITE_PRIVATE void sqlite3RenameExprlistUnmap(Parse *pParse, ExprList *pEList){ + if( pEList ){ + int i; + Walker sWalker; + memset(&sWalker, 0, sizeof(Walker)); + sWalker.pParse = pParse; + sWalker.xExprCallback = renameUnmapExprCb; + sqlite3WalkExprList(&sWalker, pEList); + for(i=0; inExpr; i++){ + if( ALWAYS(pEList->a[i].fg.eEName==ENAME_NAME) ){ + sqlite3RenameTokenRemap(pParse, 0, (void*)pEList->a[i].zEName); + } + } + } +} + +/* +** Free the list of RenameToken objects given in the second argument +*/ +static void renameTokenFree(sqlite3 *db, RenameToken *pToken){ + RenameToken *pNext; + RenameToken *p; + for(p=pToken; p; p=pNext){ + pNext = p->pNext; + sqlite3DbFree(db, p); + } +} + +/* +** Search the Parse object passed as the first argument for a RenameToken +** object associated with parse tree element pPtr. If found, return a pointer +** to it. Otherwise, return NULL. +** +** If the second argument passed to this function is not NULL and a matching +** RenameToken object is found, remove it from the Parse object and add it to +** the list maintained by the RenameCtx object. +*/ +static RenameToken *renameTokenFind( + Parse *pParse, + struct RenameCtx *pCtx, + const void *pPtr +){ + RenameToken **pp; + if( NEVER(pPtr==0) ){ + return 0; + } + for(pp=&pParse->pRename; (*pp); pp=&(*pp)->pNext){ + if( (*pp)->p==pPtr ){ + RenameToken *pToken = *pp; + if( pCtx ){ + *pp = pToken->pNext; + pToken->pNext = pCtx->pList; + pCtx->pList = pToken; + pCtx->nList++; + } + return pToken; + } + } + return 0; +} + +/* +** This is a Walker select callback. It does nothing. It is only required +** because without a dummy callback, sqlite3WalkExpr() and similar do not +** descend into sub-select statements. +*/ +static int renameColumnSelectCb(Walker *pWalker, Select *p){ + if( p->selFlags & (SF_View|SF_CopyCte) ){ + testcase( p->selFlags & SF_View ); + testcase( p->selFlags & SF_CopyCte ); + return WRC_Prune; + } + renameWalkWith(pWalker, p); + return WRC_Continue; +} + +/* +** This is a Walker expression callback. +** +** For every TK_COLUMN node in the expression tree, search to see +** if the column being references is the column being renamed by an +** ALTER TABLE statement. If it is, then attach its associated +** RenameToken object to the list of RenameToken objects being +** constructed in RenameCtx object at pWalker->u.pRename. +*/ +static int renameColumnExprCb(Walker *pWalker, Expr *pExpr){ + RenameCtx *p = pWalker->u.pRename; + if( pExpr->op==TK_TRIGGER + && pExpr->iColumn==p->iCol + && pWalker->pParse->pTriggerTab==p->pTab + ){ + renameTokenFind(pWalker->pParse, p, (void*)pExpr); + }else if( pExpr->op==TK_COLUMN + && pExpr->iColumn==p->iCol + && ALWAYS(ExprUseYTab(pExpr)) + && p->pTab==pExpr->y.pTab + ){ + renameTokenFind(pWalker->pParse, p, (void*)pExpr); + } + return WRC_Continue; +} + +/* +** The RenameCtx contains a list of tokens that reference a column that +** is being renamed by an ALTER TABLE statement. Return the "last" +** RenameToken in the RenameCtx and remove that RenameToken from the +** RenameContext. "Last" means the last RenameToken encountered when +** the input SQL is parsed from left to right. Repeated calls to this routine +** return all column name tokens in the order that they are encountered +** in the SQL statement. +*/ +static RenameToken *renameColumnTokenNext(RenameCtx *pCtx){ + RenameToken *pBest = pCtx->pList; + RenameToken *pToken; + RenameToken **pp; + + for(pToken=pBest->pNext; pToken; pToken=pToken->pNext){ + if( pToken->t.z>pBest->t.z ) pBest = pToken; + } + for(pp=&pCtx->pList; *pp!=pBest; pp=&(*pp)->pNext); + *pp = pBest->pNext; + + return pBest; +} + +/* +** Set the error message of the context passed as the first argument to +** the result of formatting zFmt using printf() style formatting. +*/ +static void errorMPrintf(sqlite3_context *pCtx, const char *zFmt, ...){ + sqlite3 *db = sqlite3_context_db_handle(pCtx); + char *zErr = 0; + va_list ap; + va_start(ap, zFmt); + zErr = sqlite3VMPrintf(db, zFmt, ap); + va_end(ap); + if( zErr ){ + sqlite3_result_error(pCtx, zErr, -1); + sqlite3DbFree(db, zErr); + }else{ + sqlite3_result_error_nomem(pCtx); + } +} + +/* +** An error occurred while parsing or otherwise processing a database +** object (either pParse->pNewTable, pNewIndex or pNewTrigger) as part of an +** ALTER TABLE RENAME COLUMN program. The error message emitted by the +** sub-routine is currently stored in pParse->zErrMsg. This function +** adds context to the error message and then stores it in pCtx. +*/ +static void renameColumnParseError( + sqlite3_context *pCtx, + const char *zWhen, + sqlite3_value *pType, + sqlite3_value *pObject, + Parse *pParse +){ + const char *zT = (const char*)sqlite3_value_text(pType); + const char *zN = (const char*)sqlite3_value_text(pObject); + char *zErr; + + zErr = sqlite3MPrintf(pParse->db, "error in %s %s%s%s: %s", + zT, zN, (zWhen[0] ? " " : ""), zWhen, + pParse->zErrMsg + ); + sqlite3_result_error(pCtx, zErr, -1); + sqlite3DbFree(pParse->db, zErr); +} + +/* +** For each name in the the expression-list pEList (i.e. each +** pEList->a[i].zName) that matches the string in zOld, extract the +** corresponding rename-token from Parse object pParse and add it +** to the RenameCtx pCtx. +*/ +static void renameColumnElistNames( + Parse *pParse, + RenameCtx *pCtx, + const ExprList *pEList, + const char *zOld +){ + if( pEList ){ + int i; + for(i=0; inExpr; i++){ + const char *zName = pEList->a[i].zEName; + if( ALWAYS(pEList->a[i].fg.eEName==ENAME_NAME) + && ALWAYS(zName!=0) + && 0==sqlite3_stricmp(zName, zOld) + ){ + renameTokenFind(pParse, pCtx, (const void*)zName); + } + } + } +} + +/* +** For each name in the the id-list pIdList (i.e. each pIdList->a[i].zName) +** that matches the string in zOld, extract the corresponding rename-token +** from Parse object pParse and add it to the RenameCtx pCtx. +*/ +static void renameColumnIdlistNames( + Parse *pParse, + RenameCtx *pCtx, + const IdList *pIdList, + const char *zOld +){ + if( pIdList ){ + int i; + for(i=0; inId; i++){ + const char *zName = pIdList->a[i].zName; + if( 0==sqlite3_stricmp(zName, zOld) ){ + renameTokenFind(pParse, pCtx, (const void*)zName); + } + } + } +} + + +/* +** Parse the SQL statement zSql using Parse object (*p). The Parse object +** is initialized by this function before it is used. +*/ +static int renameParseSql( + Parse *p, /* Memory to use for Parse object */ + const char *zDb, /* Name of schema SQL belongs to */ + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL to parse */ + int bTemp /* True if SQL is from temp schema */ +){ + int rc; + u64 flags; + + sqlite3ParseObjectInit(p, db); + if( zSql==0 ){ + return SQLITE_NOMEM; + } + if( sqlite3StrNICmp(zSql,"CREATE ",7)!=0 ){ + return SQLITE_CORRUPT_BKPT; + } + if( bTemp ){ + db->init.iDb = 1; + }else{ + int iDb = sqlite3FindDbName(db, zDb); + assert( iDb>=0 && iDb<=0xff ); + db->init.iDb = (u8)iDb; + } + p->eParseMode = PARSE_MODE_RENAME; + p->db = db; + p->nQueryLoop = 1; + flags = db->flags; + testcase( (db->flags & SQLITE_Comments)==0 && strstr(zSql," /* ")!=0 ); + db->flags |= SQLITE_Comments; + rc = sqlite3RunParser(p, zSql); + db->flags = flags; + if( db->mallocFailed ) rc = SQLITE_NOMEM; + if( rc==SQLITE_OK + && NEVER(p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0) + ){ + rc = SQLITE_CORRUPT_BKPT; + } + +#ifdef SQLITE_DEBUG + /* Ensure that all mappings in the Parse.pRename list really do map to + ** a part of the input string. */ + if( rc==SQLITE_OK ){ + int nSql = sqlite3Strlen30(zSql); + RenameToken *pToken; + for(pToken=p->pRename; pToken; pToken=pToken->pNext){ + assert( pToken->t.z>=zSql && &pToken->t.z[pToken->t.n]<=&zSql[nSql] ); + } + } +#endif + + db->init.iDb = 0; + return rc; +} + +/* +** This function edits SQL statement zSql, replacing each token identified +** by the linked list pRename with the text of zNew. If argument bQuote is +** true, then zNew is always quoted first. If no error occurs, the result +** is loaded into context object pCtx as the result. +** +** Or, if an error occurs (i.e. an OOM condition), an error is left in +** pCtx and an SQLite error code returned. +*/ +static int renameEditSql( + sqlite3_context *pCtx, /* Return result here */ + RenameCtx *pRename, /* Rename context */ + const char *zSql, /* SQL statement to edit */ + const char *zNew, /* New token text */ + int bQuote /* True to always quote token */ +){ + i64 nNew = sqlite3Strlen30(zNew); + i64 nSql = sqlite3Strlen30(zSql); + sqlite3 *db = sqlite3_context_db_handle(pCtx); + int rc = SQLITE_OK; + char *zQuot = 0; + char *zOut; + i64 nQuot = 0; + char *zBuf1 = 0; + char *zBuf2 = 0; + + if( zNew ){ + /* Set zQuot to point to a buffer containing a quoted copy of the + ** identifier zNew. If the corresponding identifier in the original + ** ALTER TABLE statement was quoted (bQuote==1), then set zNew to + ** point to zQuot so that all substitutions are made using the + ** quoted version of the new column name. */ + zQuot = sqlite3MPrintf(db, "\"%w\" ", zNew); + if( zQuot==0 ){ + return SQLITE_NOMEM; + }else{ + nQuot = sqlite3Strlen30(zQuot)-1; + } + + assert( nQuot>=nNew && nSql>=0 && nNew>=0 ); + zOut = sqlite3DbMallocZero(db, (u64)nSql + pRename->nList*(u64)nQuot + 1); + }else{ + assert( nSql>0 ); + zOut = (char*)sqlite3DbMallocZero(db, (2*(u64)nSql + 1) * 3); + if( zOut ){ + zBuf1 = &zOut[nSql*2+1]; + zBuf2 = &zOut[nSql*4+2]; + } + } + + /* At this point pRename->pList contains a list of RenameToken objects + ** corresponding to all tokens in the input SQL that must be replaced + ** with the new column name, or with single-quoted versions of themselves. + ** All that remains is to construct and return the edited SQL string. */ + if( zOut ){ + i64 nOut = nSql; + assert( nSql>0 ); + memcpy(zOut, zSql, (size_t)nSql); + while( pRename->pList ){ + int iOff; /* Offset of token to replace in zOut */ + i64 nReplace; + const char *zReplace; + RenameToken *pBest = renameColumnTokenNext(pRename); + + if( zNew ){ + if( bQuote==0 && sqlite3IsIdChar(*(u8*)pBest->t.z) ){ + nReplace = nNew; + zReplace = zNew; + }else{ + nReplace = nQuot; + zReplace = zQuot; + if( pBest->t.z[pBest->t.n]=='"' ) nReplace++; + } + }else{ + /* Dequote the double-quoted token. Then requote it again, this time + ** using single quotes. If the character immediately following the + ** original token within the input SQL was a single quote ('), then + ** add another space after the new, single-quoted version of the + ** token. This is so that (SELECT "string"'alias') maps to + ** (SELECT 'string' 'alias'), and not (SELECT 'string''alias'). */ + memcpy(zBuf1, pBest->t.z, pBest->t.n); + zBuf1[pBest->t.n] = 0; + sqlite3Dequote(zBuf1); + assert( nSql < 0x15555554 /* otherwise malloc would have failed */ ); + sqlite3_snprintf((int)(nSql*2), zBuf2, "%Q%s", zBuf1, + pBest->t.z[pBest->t.n]=='\'' ? " " : "" + ); + zReplace = zBuf2; + nReplace = sqlite3Strlen30(zReplace); + } + + iOff = (int)(pBest->t.z - zSql); + if( pBest->t.n!=nReplace ){ + memmove(&zOut[iOff + nReplace], &zOut[iOff + pBest->t.n], + nOut - (iOff + pBest->t.n) + ); + nOut += nReplace - pBest->t.n; + zOut[nOut] = '\0'; + } + memcpy(&zOut[iOff], zReplace, nReplace); + sqlite3DbFree(db, pBest); + } + + sqlite3_result_text(pCtx, zOut, -1, SQLITE_TRANSIENT); + sqlite3DbFree(db, zOut); + }else{ + rc = SQLITE_NOMEM; + } + + sqlite3_free(zQuot); + return rc; +} + +/* +** Set all pEList->a[].fg.eEName fields in the expression-list to val. +*/ +static void renameSetENames(ExprList *pEList, int val){ + assert( val==ENAME_NAME || val==ENAME_TAB || val==ENAME_SPAN ); + if( pEList ){ + int i; + for(i=0; inExpr; i++){ + assert( val==ENAME_NAME || pEList->a[i].fg.eEName==ENAME_NAME ); + pEList->a[i].fg.eEName = val&0x3; + } + } +} + +/* +** Resolve all symbols in the trigger at pParse->pNewTrigger, assuming +** it was read from the schema of database zDb. Return SQLITE_OK if +** successful. Otherwise, return an SQLite error code and leave an error +** message in the Parse object. +*/ +static int renameResolveTrigger(Parse *pParse){ + sqlite3 *db = pParse->db; + Trigger *pNew = pParse->pNewTrigger; + TriggerStep *pStep; + NameContext sNC; + int rc = SQLITE_OK; + + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + assert( pNew->pTabSchema ); + pParse->pTriggerTab = sqlite3FindTable(db, pNew->table, + db->aDb[sqlite3SchemaToIndex(db, pNew->pTabSchema)].zDbSName + ); + pParse->eTriggerOp = pNew->op; + /* ALWAYS() because if the table of the trigger does not exist, the + ** error would have been hit before this point */ + if( ALWAYS(pParse->pTriggerTab) ){ + rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab)!=0; + } + + /* Resolve symbols in WHEN clause */ + if( rc==SQLITE_OK && pNew->pWhen ){ + rc = sqlite3ResolveExprNames(&sNC, pNew->pWhen); + } + + for(pStep=pNew->step_list; rc==SQLITE_OK && pStep; pStep=pStep->pNext){ + if( pStep->pSelect ){ + sqlite3SelectPrep(pParse, pStep->pSelect, &sNC); + if( pParse->nErr ) rc = pParse->rc; + } + if( rc==SQLITE_OK && pStep->pSrc ){ + SrcList *pSrc = sqlite3SrcListDup(db, pStep->pSrc, 0); + if( pSrc ){ + Select *pSel = sqlite3SelectNew( + pParse, pStep->pExprList, pSrc, 0, 0, 0, 0, 0, 0 + ); + if( pSel==0 ){ + pStep->pExprList = 0; + pSrc = 0; + rc = SQLITE_NOMEM; + }else{ + /* pStep->pExprList contains an expression-list used for an UPDATE + ** statement. So the a[].zEName values are the RHS of the + ** "= " clauses of the UPDATE statement. So, before + ** running SelectPrep(), change all the eEName values in + ** pStep->pExprList to ENAME_SPAN (from their current value of + ** ENAME_NAME). This is to prevent any ids in ON() clauses that are + ** part of pSrc from being incorrectly resolved against the + ** a[].zEName values as if they were column aliases. */ + renameSetENames(pStep->pExprList, ENAME_SPAN); + sqlite3SelectPrep(pParse, pSel, 0); + renameSetENames(pStep->pExprList, ENAME_NAME); + rc = pParse->nErr ? SQLITE_ERROR : SQLITE_OK; + assert( pStep->pExprList==0 || pStep->pExprList==pSel->pEList ); + assert( pSrc==pSel->pSrc ); + if( pStep->pExprList ) pSel->pEList = 0; + pSel->pSrc = 0; + sqlite3SelectDelete(db, pSel); + } + if( ALWAYS(pStep->pSrc) ){ + int i; + for(i=0; ipSrc->nSrc && rc==SQLITE_OK; i++){ + SrcItem *p = &pStep->pSrc->a[i]; + if( p->fg.isSubquery ){ + assert( p->u4.pSubq!=0 ); + sqlite3SelectPrep(pParse, p->u4.pSubq->pSelect, 0); + } + } + } + + if( db->mallocFailed ){ + rc = SQLITE_NOMEM; + } + sNC.pSrcList = pSrc; + if( rc==SQLITE_OK && pStep->pWhere ){ + rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere); + } + if( rc==SQLITE_OK ){ + rc = sqlite3ResolveExprListNames(&sNC, pStep->pExprList); + } + assert( !pStep->pUpsert || (!pStep->pWhere && !pStep->pExprList) ); + if( pStep->pUpsert && rc==SQLITE_OK ){ + Upsert *pUpsert = pStep->pUpsert; + pUpsert->pUpsertSrc = pSrc; + sNC.uNC.pUpsert = pUpsert; + sNC.ncFlags = NC_UUpsert; + rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget); + if( rc==SQLITE_OK ){ + ExprList *pUpsertSet = pUpsert->pUpsertSet; + rc = sqlite3ResolveExprListNames(&sNC, pUpsertSet); + } + if( rc==SQLITE_OK ){ + rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertWhere); + } + if( rc==SQLITE_OK ){ + rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere); + } + sNC.ncFlags = 0; + } + sNC.pSrcList = 0; + sqlite3SrcListDelete(db, pSrc); + }else{ + rc = SQLITE_NOMEM; + } + } + } + return rc; +} + +/* +** Invoke sqlite3WalkExpr() or sqlite3WalkSelect() on all Select or Expr +** objects that are part of the trigger passed as the second argument. +*/ +static void renameWalkTrigger(Walker *pWalker, Trigger *pTrigger){ + TriggerStep *pStep; + + /* Find tokens to edit in WHEN clause */ + sqlite3WalkExpr(pWalker, pTrigger->pWhen); + + /* Find tokens to edit in trigger steps */ + for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){ + sqlite3WalkSelect(pWalker, pStep->pSelect); + sqlite3WalkExpr(pWalker, pStep->pWhere); + sqlite3WalkExprList(pWalker, pStep->pExprList); + if( pStep->pUpsert ){ + Upsert *pUpsert = pStep->pUpsert; + sqlite3WalkExprList(pWalker, pUpsert->pUpsertTarget); + sqlite3WalkExprList(pWalker, pUpsert->pUpsertSet); + sqlite3WalkExpr(pWalker, pUpsert->pUpsertWhere); + sqlite3WalkExpr(pWalker, pUpsert->pUpsertTargetWhere); + } + if( pStep->pSrc ){ + int i; + SrcList *pSrc = pStep->pSrc; + for(i=0; inSrc; i++){ + if( pSrc->a[i].fg.isSubquery ){ + assert( pSrc->a[i].u4.pSubq!=0 ); + sqlite3WalkSelect(pWalker, pSrc->a[i].u4.pSubq->pSelect); + } + } + } + } +} + +/* +** Free the contents of Parse object (*pParse). Do not free the memory +** occupied by the Parse object itself. +*/ +static void renameParseCleanup(Parse *pParse){ + sqlite3 *db = pParse->db; + Index *pIdx; + if( pParse->pVdbe ){ + sqlite3VdbeFinalize(pParse->pVdbe); + } + sqlite3DeleteTable(db, pParse->pNewTable); + while( (pIdx = pParse->pNewIndex)!=0 ){ + pParse->pNewIndex = pIdx->pNext; + sqlite3FreeIndex(db, pIdx); + } + sqlite3DeleteTrigger(db, pParse->pNewTrigger); + sqlite3DbFree(db, pParse->zErrMsg); + renameTokenFree(db, pParse->pRename); + sqlite3ParseObjectReset(pParse); +} + +/* +** SQL function: +** +** sqlite_rename_column(SQL,TYPE,OBJ,DB,TABLE,COL,NEWNAME,QUOTE,TEMP) +** +** 0. zSql: SQL statement to rewrite +** 1. type: Type of object ("table", "view" etc.) +** 2. object: Name of object +** 3. Database: Database name (e.g. "main") +** 4. Table: Table name +** 5. iCol: Index of column to rename +** 6. zNew: New column name +** 7. bQuote: Non-zero if the new column name should be quoted. +** 8. bTemp: True if zSql comes from temp schema +** +** Do a column rename operation on the CREATE statement given in zSql. +** The iCol-th column (left-most is 0) of table zTable is renamed from zCol +** into zNew. The name should be quoted if bQuote is true. +** +** This function is used internally by the ALTER TABLE RENAME COLUMN command. +** It is only accessible to SQL created using sqlite3NestedParse(). It is +** not reachable from ordinary SQL passed into sqlite3_prepare() unless the +** SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test setting is enabled. +*/ +static void renameColumnFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + RenameCtx sCtx; + const char *zSql = (const char*)sqlite3_value_text(argv[0]); + const char *zDb = (const char*)sqlite3_value_text(argv[3]); + const char *zTable = (const char*)sqlite3_value_text(argv[4]); + int iCol = sqlite3_value_int(argv[5]); + const char *zNew = (const char*)sqlite3_value_text(argv[6]); + int bQuote = sqlite3_value_int(argv[7]); + int bTemp = sqlite3_value_int(argv[8]); + const char *zOld; + int rc; + Parse sParse; + Walker sWalker; + Index *pIdx; + int i; + Table *pTab; +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth = db->xAuth; +#endif + + UNUSED_PARAMETER(NotUsed); + if( zSql==0 ) return; + if( zTable==0 ) return; + if( zNew==0 ) return; + if( iCol<0 ) return; + sqlite3BtreeEnterAll(db); + pTab = sqlite3FindTable(db, zTable, zDb); + if( pTab==0 || iCol>=pTab->nCol ){ + sqlite3BtreeLeaveAll(db); + return; + } + zOld = pTab->aCol[iCol].zCnName; + memset(&sCtx, 0, sizeof(sCtx)); + sCtx.iCol = ((iCol==pTab->iPKey) ? -1 : iCol); + +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = 0; +#endif + rc = renameParseSql(&sParse, zDb, db, zSql, bTemp); + + /* Find tokens that need to be replaced. */ + memset(&sWalker, 0, sizeof(Walker)); + sWalker.pParse = &sParse; + sWalker.xExprCallback = renameColumnExprCb; + sWalker.xSelectCallback = renameColumnSelectCb; + sWalker.u.pRename = &sCtx; + + sCtx.pTab = pTab; + if( rc!=SQLITE_OK ) goto renameColumnFunc_done; + if( sParse.pNewTable ){ + if( IsView(sParse.pNewTable) ){ + Select *pSelect = sParse.pNewTable->u.view.pSelect; + pSelect->selFlags &= ~(u32)SF_View; + sParse.rc = SQLITE_OK; + sqlite3SelectPrep(&sParse, pSelect, 0); + rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc); + if( rc==SQLITE_OK ){ + sqlite3WalkSelect(&sWalker, pSelect); + } + if( rc!=SQLITE_OK ) goto renameColumnFunc_done; + }else if( IsOrdinaryTable(sParse.pNewTable) ){ + /* A regular table */ + int bFKOnly = sqlite3_stricmp(zTable, sParse.pNewTable->zName); + FKey *pFKey; + sCtx.pTab = sParse.pNewTable; + if( bFKOnly==0 ){ + if( iColnCol ){ + renameTokenFind( + &sParse, &sCtx, (void*)sParse.pNewTable->aCol[iCol].zCnName + ); + } + if( sCtx.iCol<0 ){ + renameTokenFind(&sParse, &sCtx, (void*)&sParse.pNewTable->iPKey); + } + sqlite3WalkExprList(&sWalker, sParse.pNewTable->pCheck); + for(pIdx=sParse.pNewTable->pIndex; pIdx; pIdx=pIdx->pNext){ + sqlite3WalkExprList(&sWalker, pIdx->aColExpr); + } + for(pIdx=sParse.pNewIndex; pIdx; pIdx=pIdx->pNext){ + sqlite3WalkExprList(&sWalker, pIdx->aColExpr); + } +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + for(i=0; inCol; i++){ + Expr *pExpr = sqlite3ColumnExpr(sParse.pNewTable, + &sParse.pNewTable->aCol[i]); + sqlite3WalkExpr(&sWalker, pExpr); + } +#endif + } + + assert( IsOrdinaryTable(sParse.pNewTable) ); + for(pFKey=sParse.pNewTable->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){ + for(i=0; inCol; i++){ + if( bFKOnly==0 && pFKey->aCol[i].iFrom==iCol ){ + renameTokenFind(&sParse, &sCtx, (void*)&pFKey->aCol[i]); + } + if( 0==sqlite3_stricmp(pFKey->zTo, zTable) + && 0==sqlite3_stricmp(pFKey->aCol[i].zCol, zOld) + ){ + renameTokenFind(&sParse, &sCtx, (void*)pFKey->aCol[i].zCol); + } + } + } + } + }else if( sParse.pNewIndex ){ + sqlite3WalkExprList(&sWalker, sParse.pNewIndex->aColExpr); + sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere); + }else{ + /* A trigger */ + TriggerStep *pStep; + rc = renameResolveTrigger(&sParse); + if( rc!=SQLITE_OK ) goto renameColumnFunc_done; + + for(pStep=sParse.pNewTrigger->step_list; pStep; pStep=pStep->pNext){ + if( pStep->pSrc ){ + Table *pTarget = sqlite3LocateTableItem(&sParse, 0, &pStep->pSrc->a[0]); + if( pTarget==pTab ){ + if( pStep->pUpsert ){ + ExprList *pUpsertSet = pStep->pUpsert->pUpsertSet; + renameColumnElistNames(&sParse, &sCtx, pUpsertSet, zOld); + } + renameColumnIdlistNames(&sParse, &sCtx, pStep->pIdList, zOld); + renameColumnElistNames(&sParse, &sCtx, pStep->pExprList, zOld); + } + } + } + + /* Find tokens to edit in UPDATE OF clause */ + if( sParse.pTriggerTab==pTab ){ + renameColumnIdlistNames(&sParse, &sCtx,sParse.pNewTrigger->pColumns,zOld); + } + + /* Find tokens to edit in various expressions and selects */ + renameWalkTrigger(&sWalker, sParse.pNewTrigger); + } + + assert( rc==SQLITE_OK ); + rc = renameEditSql(context, &sCtx, zSql, zNew, bQuote); + +renameColumnFunc_done: + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_ERROR && sqlite3WritableSchema(db) ){ + sqlite3_result_value(context, argv[0]); + }else if( sParse.zErrMsg ){ + renameColumnParseError(context, "", argv[1], argv[2], &sParse); + }else{ + sqlite3_result_error_code(context, rc); + } + } + + renameParseCleanup(&sParse); + renameTokenFree(db, sCtx.pList); +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; +#endif + sqlite3BtreeLeaveAll(db); +} + +/* +** Walker expression callback used by "RENAME TABLE". +*/ +static int renameTableExprCb(Walker *pWalker, Expr *pExpr){ + RenameCtx *p = pWalker->u.pRename; + if( pExpr->op==TK_COLUMN + && ALWAYS(ExprUseYTab(pExpr)) + && p->pTab==pExpr->y.pTab + ){ + renameTokenFind(pWalker->pParse, p, (void*)&pExpr->y.pTab); + } + return WRC_Continue; +} + +/* +** Walker select callback used by "RENAME TABLE". +*/ +static int renameTableSelectCb(Walker *pWalker, Select *pSelect){ + int i; + RenameCtx *p = pWalker->u.pRename; + SrcList *pSrc = pSelect->pSrc; + if( pSelect->selFlags & (SF_View|SF_CopyCte) ){ + testcase( pSelect->selFlags & SF_View ); + testcase( pSelect->selFlags & SF_CopyCte ); + return WRC_Prune; + } + if( NEVER(pSrc==0) ){ + assert( pWalker->pParse->db->mallocFailed ); + return WRC_Abort; + } + for(i=0; inSrc; i++){ + SrcItem *pItem = &pSrc->a[i]; + if( pItem->pSTab==p->pTab ){ + renameTokenFind(pWalker->pParse, p, pItem->zName); + } + } + renameWalkWith(pWalker, pSelect); + + return WRC_Continue; +} + + +/* +** This C function implements an SQL user function that is used by SQL code +** generated by the ALTER TABLE ... RENAME command to modify the definition +** of any foreign key constraints that use the table being renamed as the +** parent table. It is passed three arguments: +** +** 0: The database containing the table being renamed. +** 1. type: Type of object ("table", "view" etc.) +** 2. object: Name of object +** 3: The complete text of the schema statement being modified, +** 4: The old name of the table being renamed, and +** 5: The new name of the table being renamed. +** 6: True if the schema statement comes from the temp db. +** +** It returns the new schema statement. For example: +** +** sqlite_rename_table('main', 'CREATE TABLE t1(a REFERENCES t2)','t2','t3',0) +** -> 'CREATE TABLE t1(a REFERENCES t3)' +*/ +static void renameTableFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + const char *zDb = (const char*)sqlite3_value_text(argv[0]); + const char *zInput = (const char*)sqlite3_value_text(argv[3]); + const char *zOld = (const char*)sqlite3_value_text(argv[4]); + const char *zNew = (const char*)sqlite3_value_text(argv[5]); + int bTemp = sqlite3_value_int(argv[6]); + UNUSED_PARAMETER(NotUsed); + + if( zInput && zOld && zNew ){ + Parse sParse; + int rc; + int bQuote = 1; + RenameCtx sCtx; + Walker sWalker; + +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth = db->xAuth; + db->xAuth = 0; +#endif + + sqlite3BtreeEnterAll(db); + + memset(&sCtx, 0, sizeof(RenameCtx)); + sCtx.pTab = sqlite3FindTable(db, zOld, zDb); + memset(&sWalker, 0, sizeof(Walker)); + sWalker.pParse = &sParse; + sWalker.xExprCallback = renameTableExprCb; + sWalker.xSelectCallback = renameTableSelectCb; + sWalker.u.pRename = &sCtx; + + rc = renameParseSql(&sParse, zDb, db, zInput, bTemp); + + if( rc==SQLITE_OK ){ + int isLegacy = (db->flags & SQLITE_LegacyAlter); + if( sParse.pNewTable ){ + Table *pTab = sParse.pNewTable; + + if( IsView(pTab) ){ + if( isLegacy==0 ){ + Select *pSelect = pTab->u.view.pSelect; + NameContext sNC; + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = &sParse; + + assert( pSelect->selFlags & SF_View ); + pSelect->selFlags &= ~(u32)SF_View; + sqlite3SelectPrep(&sParse, pTab->u.view.pSelect, &sNC); + if( sParse.nErr ){ + rc = sParse.rc; + }else{ + sqlite3WalkSelect(&sWalker, pTab->u.view.pSelect); + } + } + }else{ + /* Modify any FK definitions to point to the new table. */ +#ifndef SQLITE_OMIT_FOREIGN_KEY + if( (isLegacy==0 || (db->flags & SQLITE_ForeignKeys)) + && !IsVirtual(pTab) + ){ + FKey *pFKey; + assert( IsOrdinaryTable(pTab) ); + for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){ + if( sqlite3_stricmp(pFKey->zTo, zOld)==0 ){ + renameTokenFind(&sParse, &sCtx, (void*)pFKey->zTo); + } + } + } +#endif + + /* If this is the table being altered, fix any table refs in CHECK + ** expressions. Also update the name that appears right after the + ** "CREATE [VIRTUAL] TABLE" bit. */ + if( sqlite3_stricmp(zOld, pTab->zName)==0 ){ + sCtx.pTab = pTab; + if( isLegacy==0 ){ + sqlite3WalkExprList(&sWalker, pTab->pCheck); + } + renameTokenFind(&sParse, &sCtx, pTab->zName); + } + } + } + + else if( sParse.pNewIndex ){ + renameTokenFind(&sParse, &sCtx, sParse.pNewIndex->zName); + if( isLegacy==0 ){ + sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere); + } + } + +#ifndef SQLITE_OMIT_TRIGGER + else{ + Trigger *pTrigger = sParse.pNewTrigger; + TriggerStep *pStep; + if( 0==sqlite3_stricmp(sParse.pNewTrigger->table, zOld) + && sCtx.pTab->pSchema==pTrigger->pTabSchema + ){ + renameTokenFind(&sParse, &sCtx, sParse.pNewTrigger->table); + } + + if( isLegacy==0 ){ + rc = renameResolveTrigger(&sParse); + if( rc==SQLITE_OK ){ + renameWalkTrigger(&sWalker, pTrigger); + for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){ + if( pStep->pSrc ){ + int i; + for(i=0; ipSrc->nSrc; i++){ + SrcItem *pItem = &pStep->pSrc->a[i]; + if( 0==sqlite3_stricmp(pItem->zName, zOld) ){ + renameTokenFind(&sParse, &sCtx, pItem->zName); + } + } + } + } + } + } + } +#endif + } + + if( rc==SQLITE_OK ){ + rc = renameEditSql(context, &sCtx, zInput, zNew, bQuote); + } + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_ERROR && sqlite3WritableSchema(db) ){ + sqlite3_result_value(context, argv[3]); + }else if( sParse.zErrMsg ){ + renameColumnParseError(context, "", argv[1], argv[2], &sParse); + }else{ + sqlite3_result_error_code(context, rc); + } + } + + renameParseCleanup(&sParse); + renameTokenFree(db, sCtx.pList); + sqlite3BtreeLeaveAll(db); +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; +#endif + } + + return; +} + +static int renameQuotefixExprCb(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_STRING && (pExpr->flags & EP_DblQuoted) ){ + renameTokenFind(pWalker->pParse, pWalker->u.pRename, (const void*)pExpr); + } + return WRC_Continue; +} + +/* SQL function: sqlite_rename_quotefix(DB,SQL) +** +** Rewrite the DDL statement "SQL" so that any string literals that use +** double-quotes use single quotes instead. +** +** Two arguments must be passed: +** +** 0: Database name ("main", "temp" etc.). +** 1: SQL statement to edit. +** +** The returned value is the modified SQL statement. For example, given +** the database schema: +** +** CREATE TABLE t1(a, b, c); +** +** SELECT sqlite_rename_quotefix('main', +** 'CREATE VIEW v1 AS SELECT "a", "string" FROM t1' +** ); +** +** returns the string: +** +** CREATE VIEW v1 AS SELECT "a", 'string' FROM t1 +** +** If there is a error in the input SQL, then raise an error, except +** if PRAGMA writable_schema=ON, then just return the input string +** unmodified following an error. +*/ +static void renameQuotefixFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + char const *zDb = (const char*)sqlite3_value_text(argv[0]); + char const *zInput = (const char*)sqlite3_value_text(argv[1]); + +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth = db->xAuth; + db->xAuth = 0; +#endif + + sqlite3BtreeEnterAll(db); + + UNUSED_PARAMETER(NotUsed); + if( zDb && zInput ){ + int rc; + Parse sParse; + rc = renameParseSql(&sParse, zDb, db, zInput, 0); + + if( rc==SQLITE_OK ){ + RenameCtx sCtx; + Walker sWalker; + + /* Walker to find tokens that need to be replaced. */ + memset(&sCtx, 0, sizeof(RenameCtx)); + memset(&sWalker, 0, sizeof(Walker)); + sWalker.pParse = &sParse; + sWalker.xExprCallback = renameQuotefixExprCb; + sWalker.xSelectCallback = renameColumnSelectCb; + sWalker.u.pRename = &sCtx; + + if( sParse.pNewTable ){ + if( IsView(sParse.pNewTable) ){ + Select *pSelect = sParse.pNewTable->u.view.pSelect; + pSelect->selFlags &= ~(u32)SF_View; + sParse.rc = SQLITE_OK; + sqlite3SelectPrep(&sParse, pSelect, 0); + rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc); + if( rc==SQLITE_OK ){ + sqlite3WalkSelect(&sWalker, pSelect); + } + }else{ + int i; + sqlite3WalkExprList(&sWalker, sParse.pNewTable->pCheck); +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + for(i=0; inCol; i++){ + sqlite3WalkExpr(&sWalker, + sqlite3ColumnExpr(sParse.pNewTable, + &sParse.pNewTable->aCol[i])); + } +#endif /* SQLITE_OMIT_GENERATED_COLUMNS */ + } + }else if( sParse.pNewIndex ){ + sqlite3WalkExprList(&sWalker, sParse.pNewIndex->aColExpr); + sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere); + }else{ +#ifndef SQLITE_OMIT_TRIGGER + rc = renameResolveTrigger(&sParse); + if( rc==SQLITE_OK ){ + renameWalkTrigger(&sWalker, sParse.pNewTrigger); + } +#endif /* SQLITE_OMIT_TRIGGER */ + } + + if( rc==SQLITE_OK ){ + rc = renameEditSql(context, &sCtx, zInput, 0, 0); + } + renameTokenFree(db, sCtx.pList); + } + if( rc!=SQLITE_OK ){ + if( sqlite3WritableSchema(db) && rc==SQLITE_ERROR ){ + sqlite3_result_value(context, argv[1]); + }else{ + sqlite3_result_error_code(context, rc); + } + } + renameParseCleanup(&sParse); + } + +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; +#endif + + sqlite3BtreeLeaveAll(db); +} + +/* Function: sqlite_rename_test(DB,SQL,TYPE,NAME,ISTEMP,WHEN,DQS) +** +** An SQL user function that checks that there are no parse or symbol +** resolution problems in a CREATE TRIGGER|TABLE|VIEW|INDEX statement. +** After an ALTER TABLE .. RENAME operation is performed and the schema +** reloaded, this function is called on each SQL statement in the schema +** to ensure that it is still usable. +** +** 0: Database name ("main", "temp" etc.). +** 1: SQL statement. +** 2: Object type ("view", "table", "trigger" or "index"). +** 3: Object name. +** 4: True if object is from temp schema. +** 5: "when" part of error message. +** 6: True to disable the DQS quirk when parsing SQL. +** +** The return value is computed as follows: +** +** A. If an error is seen and not in PRAGMA writable_schema=ON mode, +** then raise the error. +** B. Else if a trigger is created and the the table that the trigger is +** attached to is in database zDb, then return 1. +** C. Otherwise return NULL. +*/ +static void renameTableTest( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + char const *zDb = (const char*)sqlite3_value_text(argv[0]); + char const *zInput = (const char*)sqlite3_value_text(argv[1]); + int bTemp = sqlite3_value_int(argv[4]); + int isLegacy = (db->flags & SQLITE_LegacyAlter); + char const *zWhen = (const char*)sqlite3_value_text(argv[5]); + int bNoDQS = sqlite3_value_int(argv[6]); + +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth = db->xAuth; + db->xAuth = 0; +#endif + + UNUSED_PARAMETER(NotUsed); + + if( zDb && zInput ){ + int rc; + Parse sParse; + u64 flags = db->flags; + if( bNoDQS ) db->flags &= ~(SQLITE_DqsDML|SQLITE_DqsDDL); + rc = renameParseSql(&sParse, zDb, db, zInput, bTemp); + db->flags = flags; + if( rc==SQLITE_OK ){ + if( isLegacy==0 && sParse.pNewTable && IsView(sParse.pNewTable) ){ + NameContext sNC; + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = &sParse; + sqlite3SelectPrep(&sParse, sParse.pNewTable->u.view.pSelect, &sNC); + if( sParse.nErr ) rc = sParse.rc; + } + + else if( sParse.pNewTrigger ){ + if( isLegacy==0 ){ + rc = renameResolveTrigger(&sParse); + } + if( rc==SQLITE_OK ){ + int i1 = sqlite3SchemaToIndex(db, sParse.pNewTrigger->pTabSchema); + int i2 = sqlite3FindDbName(db, zDb); + if( i1==i2 ){ + /* Handle output case B */ + sqlite3_result_int(context, 1); + } + } + } + } + + if( rc!=SQLITE_OK && zWhen && !sqlite3WritableSchema(db) ){ + /* Output case A */ + renameColumnParseError(context, zWhen, argv[2], argv[3],&sParse); + } + renameParseCleanup(&sParse); + } + +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; +#endif +} + + +/* +** Return the number of bytes until the end of the next non-whitespace and +** non-comment token. For the purpose of this function, a "(" token includes +** all of the bytes through and including the matching ")", or until the +** first illegal token, whichever comes first. +** +** Write the token type into *piToken. +** +** The value returned is the number of bytes in the token itself plus +** the number of bytes of leading whitespace and comments skipped plus +** all bytes through the next matching ")" if the token is TK_LP. +** +** Example: (Note: '.' used in place of '*' in the example z[] text) +** +** ,--------- *piToken := TK_RP +** v +** z[] = " /.comment./ --comment\n (two three four) five" +** | | +** |<-------------------------------------->| +** | +** `--- return value +*/ +static int getConstraintToken(const u8 *z, int *piToken){ + int iOff = 0; + int t = 0; + do { + iOff += sqlite3GetToken(&z[iOff], &t); + }while( t==TK_SPACE || t==TK_COMMENT ); + + *piToken = t; + + if( t==TK_LP ){ + int nNest = 1; + while( nNest>0 ){ + iOff += sqlite3GetToken(&z[iOff], &t); + if( t==TK_LP ){ + nNest++; + }else if( t==TK_RP ){ + t = TK_LP; + nNest--; + }else if( t==TK_ILLEGAL ){ + break; + } + } + } + + *piToken = t; + return iOff; +} + +/* +** The implementation of internal UDF sqlite_drop_column(). +** +** Arguments: +** +** argv[0]: An integer - the index of the schema containing the table +** argv[1]: CREATE TABLE statement to modify. +** argv[2]: An integer - the index of the column to remove. +** +** The value returned is a string containing the CREATE TABLE statement +** with column argv[2] removed. +*/ +static void dropColumnFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + int iSchema = sqlite3_value_int(argv[0]); + const char *zSql = (const char*)sqlite3_value_text(argv[1]); + int iCol = sqlite3_value_int(argv[2]); + const char *zDb = db->aDb[iSchema].zDbSName; + int rc; + Parse sParse; + RenameToken *pCol; + Table *pTab; + const char *zEnd; + char *zNew = 0; + +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth = db->xAuth; + db->xAuth = 0; +#endif + + UNUSED_PARAMETER(NotUsed); + rc = renameParseSql(&sParse, zDb, db, zSql, iSchema==1); + if( rc!=SQLITE_OK ) goto drop_column_done; + pTab = sParse.pNewTable; + if( pTab==0 || pTab->nCol==1 || iCol>=pTab->nCol ){ + /* This can happen if the sqlite_schema table is corrupt */ + rc = SQLITE_CORRUPT_BKPT; + goto drop_column_done; + } + + if( iColnCol-1 ){ + RenameToken *pEnd; + pCol = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol].zCnName); + pEnd = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol+1].zCnName); + zEnd = (const char*)pEnd->t.z; + }else{ + int eTok; + assert( IsOrdinaryTable(pTab) ); + assert( iCol!=0 ); + /* Point pCol->t.z at the "," immediately preceding the definition of + ** the column being dropped. To do this, start at the name of the + ** previous column, and tokenize until the next ",". */ + pCol = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol-1].zCnName); + do { + pCol->t.z += getConstraintToken((const u8*)pCol->t.z, &eTok); + }while( eTok!=TK_COMMA ); + pCol->t.z--; + zEnd = (const char*)&zSql[pTab->u.tab.addColOffset]; + } + + zNew = sqlite3MPrintf(db, "%.*s%s", pCol->t.z-zSql, zSql, zEnd); + sqlite3_result_text(context, zNew, -1, SQLITE_TRANSIENT); + sqlite3_free(zNew); + +drop_column_done: + renameParseCleanup(&sParse); +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; +#endif + if( rc!=SQLITE_OK ){ + sqlite3_result_error_code(context, rc); + } +} + +/* +** This function is called by the parser upon parsing an +** +** ALTER TABLE pSrc DROP COLUMN pName +** +** statement. Argument pSrc contains the possibly qualified name of the +** table being edited, and token pName the name of the column to drop. +*/ +SQLITE_PRIVATE void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, const Token *pName){ + sqlite3 *db = pParse->db; /* Database handle */ + Table *pTab; /* Table to modify */ + int iDb; /* Index of db containing pTab in aDb[] */ + const char *zDb; /* Database containing pTab ("main" etc.) */ + char *zCol = 0; /* Name of column to drop */ + int iCol; /* Index of column zCol in pTab->aCol[] */ + + /* Look up the table being altered. */ + assert( pParse->pNewTable==0 ); + assert( sqlite3BtreeHoldsAllMutexes(db) ); + if( NEVER(db->mallocFailed) ) goto exit_drop_column; + pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); + if( !pTab ) goto exit_drop_column; + + /* Make sure this is not an attempt to ALTER a view, virtual table or + ** system table. */ + if( SQLITE_OK!=isAlterableTable(pParse, pTab) ) goto exit_drop_column; + if( SQLITE_OK!=isRealTable(pParse, pTab, 1) ) goto exit_drop_column; + + /* Find the index of the column being dropped. */ + zCol = sqlite3NameFromToken(db, pName); + if( zCol==0 ){ + assert( db->mallocFailed ); + goto exit_drop_column; + } + iCol = sqlite3ColumnIndex(pTab, zCol); + if( iCol<0 ){ + sqlite3ErrorMsg(pParse, "no such column: \"%T\"", pName); + goto exit_drop_column; + } + + /* Do not allow the user to drop a PRIMARY KEY column or a column + ** constrained by a UNIQUE constraint. */ + if( pTab->aCol[iCol].colFlags & (COLFLAG_PRIMKEY|COLFLAG_UNIQUE) ){ + sqlite3ErrorMsg(pParse, "cannot drop %s column: \"%s\"", + (pTab->aCol[iCol].colFlags&COLFLAG_PRIMKEY) ? "PRIMARY KEY" : "UNIQUE", + zCol + ); + goto exit_drop_column; + } + + /* Do not allow the number of columns to go to zero */ + if( pTab->nCol<=1 ){ + sqlite3ErrorMsg(pParse, "cannot drop column \"%s\": no other columns exist",zCol); + goto exit_drop_column; + } + + /* Edit the sqlite_schema table */ + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iDb>=0 ); + zDb = db->aDb[iDb].zDbSName; +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Invoke the authorization callback. */ + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, zCol) ){ + goto exit_drop_column; + } +#endif + renameTestSchema(pParse, zDb, iDb==1, "", 0); + renameFixQuotes(pParse, zDb, iDb==1); + sqlite3NestedParse(pParse, + "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET " + "sql = sqlite_drop_column(%d, sql, %d) " + "WHERE (type=='table' AND tbl_name=%Q COLLATE nocase)" + , zDb, iDb, iCol, pTab->zName + ); + + /* Drop and reload the database schema. */ + renameReloadSchema(pParse, iDb, INITFLAG_AlterDrop); + renameTestSchema(pParse, zDb, iDb==1, "after drop column", 1); + + /* Edit rows of table on disk */ + if( pParse->nErr==0 && (pTab->aCol[iCol].colFlags & COLFLAG_VIRTUAL)==0 ){ + int i; + int addr; + int reg; + int regRec; + Index *pPk = 0; + int nField = 0; /* Number of non-virtual columns after drop */ + int iCur; + Vdbe *v = sqlite3GetVdbe(pParse); + iCur = pParse->nTab++; + sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenWrite); + addr = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v); + reg = ++pParse->nMem; + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp2(v, OP_Rowid, iCur, reg); + pParse->nMem += pTab->nCol; + }else{ + pPk = sqlite3PrimaryKeyIndex(pTab); + pParse->nMem += pPk->nColumn; + for(i=0; inKeyCol; i++){ + sqlite3VdbeAddOp3(v, OP_Column, iCur, i, reg+i+1); + } + nField = pPk->nKeyCol; + } + regRec = ++pParse->nMem; + for(i=0; inCol; i++){ + if( i!=iCol && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){ + int regOut; + if( pPk ){ + int iPos = sqlite3TableColumnToIndex(pPk, i); + int iColPos = sqlite3TableColumnToIndex(pPk, iCol); + if( iPosnKeyCol ) continue; + regOut = reg+1+iPos-(iPos>iColPos); + }else{ + regOut = reg+1+nField; + } + if( i==pTab->iPKey ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, regOut); + }else{ + char aff = pTab->aCol[i].affinity; + if( aff==SQLITE_AFF_REAL ){ + pTab->aCol[i].affinity = SQLITE_AFF_NUMERIC; + } + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, i, regOut); + pTab->aCol[i].affinity = aff; + } + nField++; + } + } + if( nField==0 ){ + /* dbsqlfuzz 5f09e7bcc78b4954d06bf9f2400d7715f48d1fef */ + pParse->nMem++; + sqlite3VdbeAddOp2(v, OP_Null, 0, reg+1); + nField = 1; + } + sqlite3VdbeAddOp3(v, OP_MakeRecord, reg+1, nField, regRec); + if( pPk ){ + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iCur, regRec, reg+1, pPk->nKeyCol); + }else{ + sqlite3VdbeAddOp3(v, OP_Insert, iCur, regRec, reg); + } + sqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION); + + sqlite3VdbeAddOp2(v, OP_Next, iCur, addr+1); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr); + } + +exit_drop_column: + sqlite3DbFree(db, zCol); + sqlite3SrcListDelete(db, pSrc); +} + +/* +** Return the number of bytes of leading whitespace/comments in string z[]. +*/ +static int getWhitespace(const u8 *z){ + int nRet = 0; + while( 1 ){ + int t = 0; + int n = sqlite3GetToken(&z[nRet], &t); + if( t!=TK_SPACE && t!=TK_COMMENT ) break; + nRet += n; + } + return nRet; +} + + +/* +** Argument z points into the body of a constraint - specifically the +** second token of the constraint definition. For a named constraint, +** z points to the first token past the CONSTRAINT keyword. For an +** unnamed NOT NULL constraint, z points to the first byte past the NOT +** keyword. +** +** Return the number of bytes until the end of the constraint. +*/ +static int getConstraint(const u8 *z){ + int iOff = 0; + int t = 0; + + /* Now, the current constraint proceeds until the next occurence of one + ** of the following tokens: + ** + ** CONSTRAINT, PRIMARY, NOT, UNIQUE, CHECK, DEFAULT, + ** COLLATE, REFERENCES, FOREIGN, GENERATED, AS, RP, or COMMA + ** + ** Also exit the loop if ILLEGAL turns up. + */ + while( 1 ){ + int n = getConstraintToken(&z[iOff], &t); + if( t==TK_CONSTRAINT || t==TK_PRIMARY || t==TK_NOT || t==TK_UNIQUE + || t==TK_CHECK || t==TK_DEFAULT || t==TK_COLLATE || t==TK_REFERENCES + || t==TK_FOREIGN || t==TK_RP || t==TK_COMMA || t==TK_ILLEGAL + || t==TK_AS || t==TK_GENERATED + ){ + break; + } + iOff += n; + } + + return iOff; +} + +/* +** Compare two constraint names. +** +** Summary: *pRes := zQuote != zCmp +** +** Details: +** Compare the (possibly quoted) constraint name zQuote[0..nQuote-1] +** against zCmp[]. Write zero into *pRes if they are the same and +** non-zero if they differ. Normally return SQLITE_OK, except if there +** is an OOM, set the OOM error condition on ctx and return SQLITE_NOMEM. +*/ +static int quotedCompare( + sqlite3_context *ctx, /* Function context on which to report errors */ + int t, /* Token type */ + const u8 *zQuote, /* Possibly quoted text. Not zero-terminated. */ + int nQuote, /* Length of zQuote in bytes */ + const u8 *zCmp, /* Zero-terminated, unquoted name to compare against */ + int *pRes /* OUT: Set to 0 if equal, non-zero if unequal */ +){ + char *zCopy = 0; /* De-quoted, zero-terminated copy of zQuote[] */ + + if( t==TK_ILLEGAL ){ + *pRes = 1; + return SQLITE_OK; + } + zCopy = sqlite3MallocZero(nQuote+1); + if( zCopy==0 ){ + sqlite3_result_error_nomem(ctx); + return SQLITE_NOMEM_BKPT; + } + memcpy(zCopy, zQuote, nQuote); + sqlite3Dequote(zCopy); + *pRes = sqlite3_stricmp((const char*)zCopy, (const char*)zCmp); + sqlite3_free(zCopy); + return SQLITE_OK; +} + +/* +** zSql[] is a CREATE TABLE statement, supposedly. Find the offset +** into zSql[] of the first character past the first "(" and write +** that offset into *piOff and return SQLITE_OK. Or, if not found, +** set the SQLITE_CORRUPT error code and return SQLITE_ERROR. +*/ +static int skipCreateTable(sqlite3_context *ctx, const u8 *zSql, int *piOff){ + int iOff = 0; + + if( zSql==0 ) return SQLITE_ERROR; + + /* Jump past the "CREATE TABLE" bit. */ + while( 1 ){ + int t = 0; + iOff += sqlite3GetToken(&zSql[iOff], &t); + if( t==TK_LP ) break; + if( t==TK_ILLEGAL ){ + sqlite3_result_error_code(ctx, SQLITE_CORRUPT_BKPT); + return SQLITE_ERROR; + } + } + + *piOff = iOff; + return SQLITE_OK; +} + +/* +** Internal SQL function sqlite3_drop_constraint(): Given an input +** CREATE TABLE statement, return a revised CREATE TABLE statement +** with a constraint removed. Two forms, depending on the datatype +** of argv[2]: +** +** sqlite_drop_constraint(SQL, INT) -- Omit NOT NULL from the INT-th column +** sqlite_drop_constraint(SQL, TEXT) -- OMIT constraint with name TEXT +** +** In the first case, the left-most column is 0. +*/ +static void dropConstraintFunc( + sqlite3_context *ctx, + int NotUsed, + sqlite3_value **argv +){ + const u8 *zSql = sqlite3_value_text(argv[0]); + const u8 *zCons = 0; + int iNotNull = -1; + int ii; + int iOff = 0; + int iStart = 0; + int iEnd = 0; + char *zNew = 0; + int t = 0; + sqlite3 *db; + UNUSED_PARAMETER(NotUsed); + + if( zSql==0 ) return; + + /* Jump past the "CREATE TABLE" bit. */ + if( skipCreateTable(ctx, zSql, &iOff) ) return; + + if( sqlite3_value_type(argv[1])==SQLITE_INTEGER ){ + iNotNull = sqlite3_value_int(argv[1]); + }else{ + zCons = sqlite3_value_text(argv[1]); + } + + /* Search for the named constraint within column definitions. */ + for(ii=0; iEnd==0; ii++){ + + /* Now parse the column or table constraint definition. Search + ** for the token CONSTRAINT if this is a DROP CONSTRAINT command, or + ** NOT in the right column if this is a DROP NOT NULL. */ + while( 1 ){ + iStart = iOff; + iOff += getConstraintToken(&zSql[iOff], &t); + if( t==TK_CONSTRAINT && (zCons || iNotNull==ii) ){ + /* Check if this is the constraint we are searching for. */ + int nTok = 0; + int cmp = 1; + + /* Skip past any whitespace. */ + iOff += getWhitespace(&zSql[iOff]); + + /* Compare the next token - which may be quoted - with the name of + ** the constraint being dropped. */ + nTok = getConstraintToken(&zSql[iOff], &t); + if( zCons ){ + if( quotedCompare(ctx, t, &zSql[iOff], nTok, zCons, &cmp) ) return; + } + iOff += nTok; + + /* The next token is usually the first token of the constraint + ** definition. This is enough to tell the type of the constraint - + ** TK_NOT means it is a NOT NULL, TK_CHECK a CHECK constraint etc. + ** + ** There is also the chance that the next token is TK_CONSTRAINT + ** (or TK_DEFAULT or TK_COLLATE), for example if a table has been + ** created as follows: + ** + ** CREATE TABLE t1(cols, CONSTRAINT one CONSTRAINT two NOT NULL); + ** + ** In this case, allow the "CONSTRAINT one" bit to be dropped by + ** this command if that is what is requested, or to advance to + ** the next iteration of the loop with &zSql[iOff] still pointing + ** to the CONSTRAINT keyword. */ + nTok = getConstraintToken(&zSql[iOff], &t); + if( t==TK_CONSTRAINT || t==TK_DEFAULT || t==TK_COLLATE + || t==TK_COMMA || t==TK_RP || t==TK_GENERATED || t==TK_AS + ){ + t = TK_CHECK; + }else{ + iOff += nTok; + iOff += getConstraint(&zSql[iOff]); + } + + if( cmp==0 || (iNotNull>=0 && t==TK_NOT) ){ + if( t!=TK_NOT && t!=TK_CHECK ){ + errorMPrintf(ctx, "constraint may not be dropped: %s", zCons); + return; + } + iEnd = iOff; + break; + } + + }else if( t==TK_NOT && iNotNull==ii ){ + iEnd = iOff + getConstraint(&zSql[iOff]); + break; + }else if( t==TK_RP || t==TK_ILLEGAL ){ + iEnd = -1; + break; + }else if( t==TK_COMMA ){ + break; + } + } + } + + /* If the constraint has not been found it is an error. */ + if( iEnd<=0 ){ + if( zCons ){ + errorMPrintf(ctx, "no such constraint: %s", zCons); + }else{ + /* SQLite follows postgres in that a DROP NOT NULL on a column that is + ** not NOT NULL is not an error. So just return the original SQL here. */ + sqlite3_result_text(ctx, (const char*)zSql, -1, SQLITE_TRANSIENT); + } + }else{ + + /* Figure out if an extra space should be inserted after the constraint + ** is removed. And if an additional comma preceding the constraint + ** should be removed. */ + const char *zSpace = " "; + iEnd += getWhitespace(&zSql[iEnd]); + sqlite3GetToken(&zSql[iEnd], &t); + if( t==TK_RP || t==TK_COMMA ){ + zSpace = ""; + if( zSql[iStart-1]==',' ) iStart--; + } + + db = sqlite3_context_db_handle(ctx); + zNew = sqlite3MPrintf(db, "%.*s%s%s", iStart, zSql, zSpace, &zSql[iEnd]); + sqlite3_result_text(ctx, zNew, -1, SQLITE_DYNAMIC); + } +} + +/* +** Internal SQL function: +** +** sqlite_add_constraint(SQL, CONSTRAINT-TEXT, ICOL) +** +** SQL is a CREATE TABLE statement. Return a modified version of +** SQL that adds CONSTRAINT-TEXT at the end of the ICOL-th column +** definition. (The left-most column defintion is 0.) +*/ +static void addConstraintFunc( + sqlite3_context *ctx, + int NotUsed, + sqlite3_value **argv +){ + const u8 *zSql = sqlite3_value_text(argv[0]); + const char *zCons = (const char*)sqlite3_value_text(argv[1]); + int iCol = sqlite3_value_int(argv[2]); + int iOff = 0; + int ii; + char *zNew = 0; + int t = 0; + sqlite3 *db; + UNUSED_PARAMETER(NotUsed); + + if( skipCreateTable(ctx, zSql, &iOff) ) return; + + for(ii=0; ii<=iCol || (iCol<0 && t!=TK_RP); ii++){ + iOff += getConstraintToken(&zSql[iOff], &t); + while( 1 ){ + int nTok = getConstraintToken(&zSql[iOff], &t); + if( t==TK_COMMA || t==TK_RP ) break; + if( t==TK_ILLEGAL ){ + sqlite3_result_error_code(ctx, SQLITE_CORRUPT_BKPT); + return; + } + iOff += nTok; + } + } + + iOff += getWhitespace(&zSql[iOff]); + + db = sqlite3_context_db_handle(ctx); + if( iCol<0 ){ + zNew = sqlite3MPrintf(db, "%.*s, %s%s", iOff, zSql, zCons, &zSql[iOff]); + }else{ + zNew = sqlite3MPrintf(db, "%.*s %s%s", iOff, zSql, zCons, &zSql[iOff]); + } + sqlite3_result_text(ctx, zNew, -1, SQLITE_DYNAMIC); +} + +/* +** Find a column named pCol in table pTab. If successful, set output +** parameter *piCol to the index of the column in the table and return +** SQLITE_OK. Otherwise, set *piCol to -1 and return an SQLite error +** code. +*/ +static int alterFindCol(Parse *pParse, Table *pTab, Token *pCol, int *piCol){ + sqlite3 *db = pParse->db; + char *zName = sqlite3NameFromToken(db, pCol); + int rc = SQLITE_NOMEM; + int iCol = -1; + + if( zName ){ + iCol = sqlite3ColumnIndex(pTab, zName); + if( iCol<0 ){ + sqlite3ErrorMsg(pParse, "no such column: %s", zName); + rc = SQLITE_ERROR; + }else{ + rc = SQLITE_OK; + } + } + +#ifndef SQLITE_OMIT_AUTHORIZATION + if( rc==SQLITE_OK ){ + const char *zDb = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zDbSName; + const char *zCol = pTab->aCol[iCol].zCnName; + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, zCol) ){ + pTab = 0; + } + } +#endif + + sqlite3DbFree(db, zName); + *piCol = iCol; + return rc; +} + + +/* +** Find the table named by the first entry in source list pSrc. If successful, +** return a pointer to the Table structure and set output variable (*pzDb) +** to point to the name of the database containin the table (i.e. "main", +** "temp" or the name of an attached database). +** +** If the table cannot be located, return NULL. The value of the two output +** parameters is undefined in this case. +*/ +static Table *alterFindTable( + Parse *pParse, /* Parsing context */ + SrcList *pSrc, /* Name of the table to look for */ + int *piDb, /* OUT: write the iDb here */ + const char **pzDb, /* OUT: write name of schema here */ + int bAuth /* Do ALTER TABLE authorization checks if true */ +){ + sqlite3 *db = pParse->db; + Table *pTab = 0; + assert( sqlite3BtreeHoldsAllMutexes(db) ); + pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); + if( pTab ){ + int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + *pzDb = db->aDb[iDb].zDbSName; + *piDb = iDb; + + if( SQLITE_OK!=isRealTable(pParse, pTab, 2) + || SQLITE_OK!=isAlterableTable(pParse, pTab) + ){ + pTab = 0; + } + } +#ifndef SQLITE_OMIT_AUTHORIZATION + if( pTab && bAuth ){ + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, *pzDb, pTab->zName, 0) ){ + pTab = 0; + } + } +#endif + sqlite3SrcListDelete(db, pSrc); + return pTab; +} + +/* +** Generate bytecode for one of: +** +** (1) ALTER TABLE pSrc DROP CONSTRAINT pCons +** (2) ALTER TABLE pSrc ALTER pCol DROP NOT NULL +** +** One of pCons and pCol must be NULL and the other non-null. +*/ +SQLITE_PRIVATE void sqlite3AlterDropConstraint( + Parse *pParse, /* Parsing context */ + SrcList *pSrc, /* The table being altered */ + Token *pCons, /* Name of the constraint to drop */ + Token *pCol /* Name of the column from which to remove the NOT NULL */ +){ + sqlite3 *db = pParse->db; + Table *pTab = 0; + int iDb = 0; + const char *zDb = 0; + char *zArg = 0; + + assert( (pCol==0)!=(pCons==0) ); + assert( pSrc->nSrc==1 ); + pTab = alterFindTable(pParse, pSrc, &iDb, &zDb, pCons!=0); + if( !pTab ) return; + + if( pCons ){ + char *z = sqlite3NameFromToken(db, pCons); + zArg = sqlite3MPrintf(db, "%Q", z); + sqlite3DbFree(db, z); + }else{ + int iCol; + if( alterFindCol(pParse, pTab, pCol, &iCol) ) return; + zArg = sqlite3MPrintf(db, "%d", iCol); + } + + /* Edit the SQL for the named table. */ + sqlite3NestedParse(pParse, + "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET " + "sql = sqlite_drop_constraint(sql, %s) " + "WHERE type='table' AND tbl_name=%Q COLLATE nocase" + , zDb, zArg, pTab->zName + ); + sqlite3DbFree(db, zArg); + + /* Finally, reload the database schema. */ + renameReloadSchema(pParse, iDb, INITFLAG_AlterDropCons); +} + +/* +** The implementation of SQL function sqlite_fail(MSG). This takes a single +** argument, and returns it as an error message with the error code set to +** SQLITE_CONSTRAINT. +*/ +static void failConstraintFunc( + sqlite3_context *ctx, + int NotUsed, + sqlite3_value **argv +){ + const char *zText = (const char*)sqlite3_value_text(argv[0]); + int err = sqlite3_value_int(argv[1]); + (void)NotUsed; + sqlite3_result_error(ctx, zText, -1); + sqlite3_result_error_code(ctx, err); +} + +/* +** Buffer pCons, which is nCons bytes in size, contains the text of a +** NOT NULL or CHECK constraint that will be inserted into a CREATE TABLE +** statement. If successful, this function returns the size of the buffer in +** bytes not including any trailing whitespace or "--" style comments. Or, +** if an OOM occurs, it returns 0 and sets db->mallocFailed to true. +** +** C-style comments at the end are preserved. "--" style comments are +** removed because the comment terminator might be \000, and we are about +** to insert the pCons[] text into the middle of a larger string, and that +** will have the effect of removing the comment terminator and messing up +** the syntax. +*/ +static int alterRtrimConstraint( + sqlite3 *db, /* used to record OOM error */ + const char *pCons, /* Buffer containing constraint */ + int nCons /* Size of pCons in bytes */ +){ + u8 *zTmp = (u8*)sqlite3MPrintf(db, "%.*s", nCons, pCons); + int iOff = 0; + int iEnd = 0; + + if( zTmp==0 ) return 0; + + while( 1 ){ + int t = 0; + int nToken = sqlite3GetToken(&zTmp[iOff], &t); + if( t==TK_ILLEGAL ) break; + if( t!=TK_SPACE && (t!=TK_COMMENT || zTmp[iOff]!='-') ){ + iEnd = iOff+nToken; + } + iOff += nToken; + } + + sqlite3DbFree(db, zTmp); + return iEnd; +} + +/* +** Prepare a statement of the form: +** +** ALTER TABLE pSrc ALTER pCol SET NOT NULL +*/ +SQLITE_PRIVATE void sqlite3AlterSetNotNull( + Parse *pParse, /* Parsing context */ + SrcList *pSrc, /* Name of the table being altered */ + Token *pCol, /* Name of the column to add a NOT NULL constraint to */ + Token *pFirst /* The NOT token of the NOT NULL constraint text */ +){ + Table *pTab = 0; + int iCol = 0; + int iDb = 0; + const char *zDb = 0; + const char *pCons = 0; + int nCons = 0; + + /* Look up the table being altered. */ + assert( pSrc->nSrc==1 ); + pTab = alterFindTable(pParse, pSrc, &iDb, &zDb, 0); + if( !pTab ) return; + + /* Find the column being altered. */ + if( alterFindCol(pParse, pTab, pCol, &iCol) ){ + return; + } + + /* Find the length in bytes of the constraint definition */ + pCons = pFirst->z; + nCons = alterRtrimConstraint(pParse->db, pCons, pParse->sLastToken.z - pCons); + + /* Search for a constraint violation. Throw an exception if one is found. */ + sqlite3NestedParse(pParse, + "SELECT sqlite_fail('constraint failed', %d) " + "FROM %Q.%Q AS x WHERE x.%.*s IS NULL", + SQLITE_CONSTRAINT, zDb, pTab->zName, (int)pCol->n, pCol->z + ); + + /* Edit the SQL for the named table. */ + sqlite3NestedParse(pParse, + "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET " + "sql = sqlite_add_constraint(sqlite_drop_constraint(sql, %d), %.*Q, %d) " + "WHERE type='table' AND tbl_name=%Q COLLATE nocase" + , zDb, iCol, nCons, pCons, iCol, pTab->zName + ); + + /* Finally, reload the database schema. */ + renameReloadSchema(pParse, iDb, INITFLAG_AlterDropCons); +} + +/* +** Implementation of internal SQL function: +** +** sqlite_find_constraint(SQL, CONSTRAINT-NAME) +** +** This function returns true if the SQL passed as the first argument is a +** CREATE TABLE that contains a constraint with the name CONSTRAINT-NAME, +** or false otherwise. +*/ +static void findConstraintFunc( + sqlite3_context *ctx, + int NotUsed, + sqlite3_value **argv +){ + const u8 *zSql = 0; + const u8 *zCons = 0; + int iOff = 0; + int t = 0; + + (void)NotUsed; + zSql = sqlite3_value_text(argv[0]); + zCons = sqlite3_value_text(argv[1]); + + if( zSql==0 || zCons==0 ) return; + while( t!=TK_LP && t!=TK_ILLEGAL ){ + iOff += sqlite3GetToken(&zSql[iOff], &t); + } + + while( 1 ){ + iOff += getConstraintToken(&zSql[iOff], &t); + if( t==TK_CONSTRAINT ){ + int nTok = 0; + int cmp = 0; + iOff += getWhitespace(&zSql[iOff]); + nTok = getConstraintToken(&zSql[iOff], &t); + if( quotedCompare(ctx, t, &zSql[iOff], nTok, zCons, &cmp) ) return; + if( cmp==0 ){ + sqlite3_result_int(ctx, 1); + return; + } + }else if( t==TK_ILLEGAL ){ + break; + } + } + + sqlite3_result_int(ctx, 0); +} + +/* +** Generate bytecode to implement: +** +** ALTER TABLE pSrc ADD [CONSTRAINT pName] CHECK(pExpr) +** +** Any "ON CONFLICT" text that occurs after the "CHECK(...)", up +** until pParse->sLastToken, is included as part of the new constraint. +*/ +SQLITE_PRIVATE void sqlite3AlterAddConstraint( + Parse *pParse, /* Parse context */ + SrcList *pSrc, /* Table to add constraint to */ + Token *pFirst, /* First token of new constraint */ + Token *pName, /* Name of new constraint. NULL if name omitted. */ + const char *zExpr, /* Text of CHECK expression */ + int nExpr, /* Size of pExpr in bytes */ + Expr *pExpr /* The parsed CHECK expression */ +){ + Table *pTab = 0; /* Table identified by pSrc */ + int iDb = 0; /* Which schema does pTab live in */ + const char *zDb = 0; /* Name of the schema in which pTab lives */ + const char *pCons = 0; /* Text of the constraint */ + int nCons; /* Bytes of text to use from pCons[] */ + int rc; /* Result from error checking pExpr */ + + /* Look up the table being altered. */ + assert( pSrc->nSrc==1 ); + pTab = alterFindTable(pParse, pSrc, &iDb, &zDb, 1); + if( !pTab ){ + sqlite3ExprDelete(pParse->db, pExpr); + return; + } + + /* Verify that the new CHECK constraint does not contain any + ** internal-use-only function. Forum post 2026-05-10T01:11:28Z + */ + rc = sqlite3ResolveSelfReference(pParse, pTab, NC_IsCheck, pExpr, 0); + sqlite3ExprDelete(pParse->db, pExpr); + if( rc ) return; + + /* If this new constraint has a name, check that it is not a duplicate of + ** an existing constraint. It is an error if it is. */ + if( pName ){ + char *zName = sqlite3NameFromToken(pParse->db, pName); + + sqlite3NestedParse(pParse, + "SELECT sqlite_fail('constraint %q already exists', %d) " + "FROM \"%w\"." LEGACY_SCHEMA_TABLE " " + "WHERE type='table' AND tbl_name=%Q COLLATE nocase " + "AND sqlite_find_constraint(sql, %Q)", + zName, SQLITE_ERROR, zDb, pTab->zName, zName + ); + sqlite3DbFree(pParse->db, zName); + } + + /* Search for a constraint violation. Throw an exception if one is found. */ + sqlite3NestedParse(pParse, + "SELECT sqlite_fail('constraint failed', %d) " + "FROM %Q.%Q WHERE (%.*s) IS NOT TRUE", + SQLITE_CONSTRAINT, zDb, pTab->zName, nExpr, zExpr + ); + + /* Edit the SQL for the named table. */ + pCons = pFirst->z; + nCons = alterRtrimConstraint(pParse->db, pCons, pParse->sLastToken.z - pCons); + + sqlite3NestedParse(pParse, + "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET " + "sql = sqlite_add_constraint(sql, %.*Q, -1) " + "WHERE type='table' AND tbl_name=%Q COLLATE nocase" + , zDb, nCons, pCons, pTab->zName + ); + + /* Finally, reload the database schema. */ + renameReloadSchema(pParse, iDb, INITFLAG_AlterDropCons); +} + +/* +** Register built-in functions used to help implement ALTER TABLE +*/ +SQLITE_PRIVATE void sqlite3AlterFunctions(void){ + static FuncDef aAlterTableFuncs[] = { + INTERNAL_FUNCTION(sqlite_rename_column, 9, renameColumnFunc), + INTERNAL_FUNCTION(sqlite_rename_table, 7, renameTableFunc), + INTERNAL_FUNCTION(sqlite_rename_test, 7, renameTableTest), + INTERNAL_FUNCTION(sqlite_drop_column, 3, dropColumnFunc), + INTERNAL_FUNCTION(sqlite_rename_quotefix,2, renameQuotefixFunc), + INTERNAL_FUNCTION(sqlite_drop_constraint,2, dropConstraintFunc), + INTERNAL_FUNCTION(sqlite_fail, 2, failConstraintFunc), + INTERNAL_FUNCTION(sqlite_add_constraint, 3, addConstraintFunc), + INTERNAL_FUNCTION(sqlite_find_constraint,2, findConstraintFunc), + }; + sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs)); +} +#endif /* SQLITE_ALTER_TABLE */ + +/************** End of alter.c ***********************************************/ +/************** Begin file analyze.c *****************************************/ +/* +** 2005-07-08 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code associated with the ANALYZE command. +** +** The ANALYZE command gather statistics about the content of tables +** and indices. These statistics are made available to the query planner +** to help it make better decisions about how to perform queries. +** +** The following system tables are or have been supported: +** +** CREATE TABLE sqlite_stat1(tbl, idx, stat); +** CREATE TABLE sqlite_stat2(tbl, idx, sampleno, sample); +** CREATE TABLE sqlite_stat3(tbl, idx, nEq, nLt, nDLt, sample); +** CREATE TABLE sqlite_stat4(tbl, idx, nEq, nLt, nDLt, sample); +** +** Additional tables might be added in future releases of SQLite. +** The sqlite_stat2 table is not created or used unless the SQLite version +** is between 3.6.18 and 3.7.8, inclusive, and unless SQLite is compiled +** with SQLITE_ENABLE_STAT2. The sqlite_stat2 table is deprecated. +** The sqlite_stat2 table is superseded by sqlite_stat3, which is only +** created and used by SQLite versions 3.7.9 through 3.29.0 when +** SQLITE_ENABLE_STAT3 defined. The functionality of sqlite_stat3 +** is a superset of sqlite_stat2 and is also now deprecated. The +** sqlite_stat4 is an enhanced version of sqlite_stat3 and is only +** available when compiled with SQLITE_ENABLE_STAT4 and in SQLite +** versions 3.8.1 and later. STAT4 is the only variant that is still +** supported. +** +** For most applications, sqlite_stat1 provides all the statistics required +** for the query planner to make good choices. +** +** Format of sqlite_stat1: +** +** There is normally one row per index, with the index identified by the +** name in the idx column. The tbl column is the name of the table to +** which the index belongs. In each such row, the stat column will be +** a string consisting of a list of integers. The first integer in this +** list is the number of rows in the index. (This is the same as the +** number of rows in the table, except for partial indices.) The second +** integer is the average number of rows in the index that have the same +** value in the first column of the index. The third integer is the average +** number of rows in the index that have the same value for the first two +** columns. The N-th integer (for N>1) is the average number of rows in +** the index which have the same value for the first N-1 columns. For +** a K-column index, there will be K+1 integers in the stat column. If +** the index is unique, then the last integer will be 1. +** +** The list of integers in the stat column can optionally be followed +** by the keyword "unordered". The "unordered" keyword, if it is present, +** must be separated from the last integer by a single space. If the +** "unordered" keyword is present, then the query planner assumes that +** the index is unordered and will not use the index for a range query. +** +** If the sqlite_stat1.idx column is NULL, then the sqlite_stat1.stat +** column contains a single integer which is the (estimated) number of +** rows in the table identified by sqlite_stat1.tbl. +** +** Format of sqlite_stat2: +** +** The sqlite_stat2 is only created and is only used if SQLite is compiled +** with SQLITE_ENABLE_STAT2 and if the SQLite version number is between +** 3.6.18 and 3.7.8. The "stat2" table contains additional information +** about the distribution of keys within an index. The index is identified by +** the "idx" column and the "tbl" column is the name of the table to which +** the index belongs. There are usually 10 rows in the sqlite_stat2 +** table for each index. +** +** The sqlite_stat2 entries for an index that have sampleno between 0 and 9 +** inclusive are samples of the left-most key value in the index taken at +** evenly spaced points along the index. Let the number of samples be S +** (10 in the standard build) and let C be the number of rows in the index. +** Then the sampled rows are given by: +** +** rownumber = (i*C*2 + C)/(S*2) +** +** For i between 0 and S-1. Conceptually, the index space is divided into +** S uniform buckets and the samples are the middle row from each bucket. +** +** The format for sqlite_stat2 is recorded here for legacy reference. This +** version of SQLite does not support sqlite_stat2. It neither reads nor +** writes the sqlite_stat2 table. This version of SQLite only supports +** sqlite_stat3. +** +** Format for sqlite_stat3: +** +** The sqlite_stat3 format is a subset of sqlite_stat4. Hence, the +** sqlite_stat4 format will be described first. Further information +** about sqlite_stat3 follows the sqlite_stat4 description. +** +** Format for sqlite_stat4: +** +** As with sqlite_stat2, the sqlite_stat4 table contains histogram data +** to aid the query planner in choosing good indices based on the values +** that indexed columns are compared against in the WHERE clauses of +** queries. +** +** The sqlite_stat4 table contains multiple entries for each index. +** The idx column names the index and the tbl column is the table of the +** index. If the idx and tbl columns are the same, then the sample is +** of the INTEGER PRIMARY KEY. The sample column is a blob which is the +** binary encoding of a key from the index. The nEq column is a +** list of integers. The first integer is the approximate number +** of entries in the index whose left-most column exactly matches +** the left-most column of the sample. The second integer in nEq +** is the approximate number of entries in the index where the +** first two columns match the first two columns of the sample. +** And so forth. nLt is another list of integers that show the approximate +** number of entries that are strictly less than the sample. The first +** integer in nLt contains the number of entries in the index where the +** left-most column is less than the left-most column of the sample. +** The K-th integer in the nLt entry is the number of index entries +** where the first K columns are less than the first K columns of the +** sample. The nDLt column is like nLt except that it contains the +** number of distinct entries in the index that are less than the +** sample. +** +** There can be an arbitrary number of sqlite_stat4 entries per index. +** The ANALYZE command will typically generate sqlite_stat4 tables +** that contain between 10 and 40 samples which are distributed across +** the key space, though not uniformly, and which include samples with +** large nEq values. +** +** Format for sqlite_stat3 redux: +** +** The sqlite_stat3 table is like sqlite_stat4 except that it only +** looks at the left-most column of the index. The sqlite_stat3.sample +** column contains the actual value of the left-most column instead +** of a blob encoding of the complete index key as is found in +** sqlite_stat4.sample. The nEq, nLt, and nDLt entries of sqlite_stat3 +** all contain just a single integer which is the same as the first +** integer in the equivalent columns in sqlite_stat4. +*/ +#ifndef SQLITE_OMIT_ANALYZE +/* #include "sqliteInt.h" */ + +#if defined(SQLITE_ENABLE_STAT4) +# define IsStat4 1 +#else +# define IsStat4 0 +# undef SQLITE_STAT4_SAMPLES +# define SQLITE_STAT4_SAMPLES 1 +#endif + +/* +** This routine generates code that opens the sqlite_statN tables. +** The sqlite_stat1 table is always relevant. sqlite_stat2 is now +** obsolete. sqlite_stat3 and sqlite_stat4 are only opened when +** appropriate compile-time options are provided. +** +** If the sqlite_statN tables do not previously exist, it is created. +** +** Argument zWhere may be a pointer to a buffer containing a table name, +** or it may be a NULL pointer. If it is not NULL, then all entries in +** the sqlite_statN tables associated with the named table are deleted. +** If zWhere==0, then code is generated to delete all stat table entries. +*/ +static void openStatTable( + Parse *pParse, /* Parsing context */ + int iDb, /* The database we are looking in */ + int iStatCur, /* Open the sqlite_stat1 table on this cursor */ + const char *zWhere, /* Delete entries for this table or index */ + const char *zWhereType /* Either "tbl" or "idx" */ +){ + static const struct { + const char *zName; + const char *zCols; + } aTable[] = { + { "sqlite_stat1", "tbl,idx,stat" }, +#if defined(SQLITE_ENABLE_STAT4) + { "sqlite_stat4", "tbl,idx,neq,nlt,ndlt,sample" }, +#else + { "sqlite_stat4", 0 }, +#endif + { "sqlite_stat3", 0 }, + }; + int i; + sqlite3 *db = pParse->db; + Db *pDb; + Vdbe *v = sqlite3GetVdbe(pParse); + u32 aRoot[ArraySize(aTable)]; + u8 aCreateTbl[ArraySize(aTable)]; +#ifdef SQLITE_ENABLE_STAT4 + const int nToOpen = OptimizationEnabled(db,SQLITE_Stat4) ? 2 : 1; +#else + const int nToOpen = 1; +#endif + + if( v==0 ) return; + assert( sqlite3BtreeHoldsAllMutexes(db) ); + assert( sqlite3VdbeDb(v)==db ); + pDb = &db->aDb[iDb]; + + /* Create new statistic tables if they do not exist, or clear them + ** if they do already exist. + */ + for(i=0; izDbSName))==0 ){ + if( iregRoot. This is important + ** because the OpenWrite opcode below will be needing it. */ + sqlite3NestedParse(pParse, + "CREATE TABLE %Q.%s(%s)", pDb->zDbSName, zTab, aTable[i].zCols + ); + assert( pParse->isCreate || pParse->nErr ); + aRoot[i] = (u32)pParse->u1.cr.regRoot; + aCreateTbl[i] = OPFLAG_P2ISREG; + } + }else{ + /* The table already exists. If zWhere is not NULL, delete all entries + ** associated with the table zWhere. If zWhere is NULL, delete the + ** entire contents of the table. */ + aRoot[i] = pStat->tnum; + sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab); + if( zWhere ){ + sqlite3NestedParse(pParse, + "DELETE FROM %Q.%s WHERE %s=%Q", + pDb->zDbSName, zTab, zWhereType, zWhere + ); +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + }else if( db->xPreUpdateCallback ){ + sqlite3NestedParse(pParse, "DELETE FROM %Q.%s", pDb->zDbSName, zTab); +#endif + }else{ + /* The sqlite_stat[134] table already exists. Delete all rows. */ + sqlite3VdbeAddOp2(v, OP_Clear, (int)aRoot[i], iDb); + } + } + } + + /* Open the sqlite_stat[134] tables for writing. */ + for(i=0; inRowid ){ + sqlite3DbFree(db, p->u.aRowid); + p->nRowid = 0; + } +} +#endif + +/* Initialize the BLOB value of a ROWID +*/ +#ifdef SQLITE_ENABLE_STAT4 +static void sampleSetRowid(sqlite3 *db, StatSample *p, int n, const u8 *pData){ + assert( db!=0 ); + if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid); + p->u.aRowid = sqlite3DbMallocRawNN(db, n); + if( p->u.aRowid ){ + p->nRowid = n; + memcpy(p->u.aRowid, pData, n); + }else{ + p->nRowid = 0; + } +} +#endif + +/* Initialize the INTEGER value of a ROWID. +*/ +#ifdef SQLITE_ENABLE_STAT4 +static void sampleSetRowidInt64(sqlite3 *db, StatSample *p, i64 iRowid){ + assert( db!=0 ); + if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid); + p->nRowid = 0; + p->u.iRowid = iRowid; +} +#endif + + +/* +** Copy the contents of object (*pFrom) into (*pTo). +*/ +#ifdef SQLITE_ENABLE_STAT4 +static void sampleCopy(StatAccum *p, StatSample *pTo, StatSample *pFrom){ + pTo->isPSample = pFrom->isPSample; + pTo->iCol = pFrom->iCol; + pTo->iHash = pFrom->iHash; + memcpy(pTo->anEq, pFrom->anEq, sizeof(tRowcnt)*p->nCol); + memcpy(pTo->anLt, pFrom->anLt, sizeof(tRowcnt)*p->nCol); + memcpy(pTo->anDLt, pFrom->anDLt, sizeof(tRowcnt)*p->nCol); + if( pFrom->nRowid ){ + sampleSetRowid(p->db, pTo, pFrom->nRowid, pFrom->u.aRowid); + }else{ + sampleSetRowidInt64(p->db, pTo, pFrom->u.iRowid); + } +} +#endif + +/* +** Reclaim all memory of a StatAccum structure. +*/ +static void statAccumDestructor(void *pOld){ + StatAccum *p = (StatAccum*)pOld; +#ifdef SQLITE_ENABLE_STAT4 + if( p->mxSample ){ + int i; + for(i=0; inCol; i++) sampleClear(p->db, p->aBest+i); + for(i=0; imxSample; i++) sampleClear(p->db, p->a+i); + sampleClear(p->db, &p->current); + } +#endif + sqlite3DbFree(p->db, p); +} + +/* +** Implementation of the stat_init(N,K,C,L) SQL function. The four parameters +** are: +** N: The number of columns in the index including the rowid/pk (note 1) +** K: The number of columns in the index excluding the rowid/pk. +** C: Estimated number of rows in the index +** L: A limit on the number of rows to scan, or 0 for no-limit +** +** Note 1: In the special case of the covering index that implements a +** WITHOUT ROWID table, N is the number of PRIMARY KEY columns, not the +** total number of columns in the table. +** +** For indexes on ordinary rowid tables, N==K+1. But for indexes on +** WITHOUT ROWID tables, N=K+P where P is the number of columns in the +** PRIMARY KEY of the table. The covering index that implements the +** original WITHOUT ROWID table as N==K as a special case. +** +** This routine allocates the StatAccum object in heap memory. The return +** value is a pointer to the StatAccum object. The datatype of the +** return value is BLOB, but it is really just a pointer to the StatAccum +** object. +*/ +static void statInit( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + StatAccum *p; + int nCol; /* Number of columns in index being sampled */ + int nKeyCol; /* Number of key columns */ + int nColUp; /* nCol rounded up for alignment */ + i64 n; /* Bytes of space to allocate */ + sqlite3 *db = sqlite3_context_db_handle(context); /* Database connection */ +#ifdef SQLITE_ENABLE_STAT4 + /* Maximum number of samples. 0 if STAT4 data is not collected */ + int mxSample = OptimizationEnabled(db,SQLITE_Stat4) ?SQLITE_STAT4_SAMPLES :0; +#endif + + /* Decode the three function arguments */ + UNUSED_PARAMETER(argc); + nCol = sqlite3_value_int(argv[0]); + assert( nCol>0 ); + nColUp = sizeof(tRowcnt)<8 ? (nCol+1)&~1 : nCol; + nKeyCol = sqlite3_value_int(argv[1]); + assert( nKeyCol<=nCol ); + assert( nKeyCol>0 ); + + /* Allocate the space required for the StatAccum object */ + n = sizeof(*p) + + sizeof(tRowcnt)*nColUp; /* StatAccum.anDLt */ +#ifdef SQLITE_ENABLE_STAT4 + n += sizeof(tRowcnt)*nColUp; /* StatAccum.anEq */ + if( mxSample ){ + n += sizeof(tRowcnt)*nColUp /* StatAccum.anLt */ + + sizeof(StatSample)*(nCol+mxSample) /* StatAccum.aBest[], a[] */ + + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample); + } +#endif + p = sqlite3DbMallocZero(db, n); + if( p==0 ){ + sqlite3_result_error_nomem(context); + return; + } + + p->db = db; + p->nEst = sqlite3_value_int64(argv[2]); + p->nRow = 0; + p->nLimit = sqlite3_value_int(argv[3]); + p->nCol = nCol; + p->nKeyCol = nKeyCol; + p->nSkipAhead = 0; + p->current.anDLt = (tRowcnt*)&p[1]; + +#ifdef SQLITE_ENABLE_STAT4 + p->current.anEq = &p->current.anDLt[nColUp]; + p->mxSample = p->nLimit==0 ? mxSample : 0; + if( mxSample ){ + u8 *pSpace; /* Allocated space not yet assigned */ + int i; /* Used to iterate through p->aSample[] */ + + p->iGet = -1; + p->nPSample = (tRowcnt)(p->nEst/(mxSample/3+1) + 1); + p->current.anLt = &p->current.anEq[nColUp]; + p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]); + + /* Set up the StatAccum.a[] and aBest[] arrays */ + p->a = (struct StatSample*)&p->current.anLt[nColUp]; + p->aBest = &p->a[mxSample]; + pSpace = (u8*)(&p->a[mxSample+nCol]); + for(i=0; i<(mxSample+nCol); i++){ + p->a[i].anEq = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); + p->a[i].anLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); + p->a[i].anDLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); + } + assert( (pSpace - (u8*)p)==n ); + + for(i=0; iaBest[i].iCol = i; + } + } +#endif + + /* Return a pointer to the allocated object to the caller. Note that + ** only the pointer (the 2nd parameter) matters. The size of the object + ** (given by the 3rd parameter) is never used and can be any positive + ** value. */ + sqlite3_result_blob(context, p, sizeof(*p), statAccumDestructor); +} +static const FuncDef statInitFuncdef = { + 4, /* nArg */ + SQLITE_UTF8, /* funcFlags */ + 0, /* pUserData */ + 0, /* pNext */ + statInit, /* xSFunc */ + 0, /* xFinalize */ + 0, 0, /* xValue, xInverse */ + "stat_init", /* zName */ + {0} +}; + +#ifdef SQLITE_ENABLE_STAT4 +/* +** pNew and pOld are both candidate non-periodic samples selected for +** the same column (pNew->iCol==pOld->iCol). Ignoring this column and +** considering only any trailing columns and the sample hash value, this +** function returns true if sample pNew is to be preferred over pOld. +** In other words, if we assume that the cardinalities of the selected +** column for pNew and pOld are equal, is pNew to be preferred over pOld. +** +** This function assumes that for each argument sample, the contents of +** the anEq[] array from pSample->anEq[pSample->iCol+1] onwards are valid. +*/ +static int sampleIsBetterPost( + StatAccum *pAccum, + StatSample *pNew, + StatSample *pOld +){ + int nCol = pAccum->nCol; + int i; + assert( pNew->iCol==pOld->iCol ); + for(i=pNew->iCol+1; ianEq[i]>pOld->anEq[i] ) return 1; + if( pNew->anEq[i]anEq[i] ) return 0; + } + if( pNew->iHash>pOld->iHash ) return 1; + return 0; +} +#endif + +#ifdef SQLITE_ENABLE_STAT4 +/* +** Return true if pNew is to be preferred over pOld. +** +** This function assumes that for each argument sample, the contents of +** the anEq[] array from pSample->anEq[pSample->iCol] onwards are valid. +*/ +static int sampleIsBetter( + StatAccum *pAccum, + StatSample *pNew, + StatSample *pOld +){ + tRowcnt nEqNew = pNew->anEq[pNew->iCol]; + tRowcnt nEqOld = pOld->anEq[pOld->iCol]; + + assert( pOld->isPSample==0 && pNew->isPSample==0 ); + assert( IsStat4 || (pNew->iCol==0 && pOld->iCol==0) ); + + if( (nEqNew>nEqOld) ) return 1; + if( nEqNew==nEqOld ){ + if( pNew->iColiCol ) return 1; + return (pNew->iCol==pOld->iCol && sampleIsBetterPost(pAccum, pNew, pOld)); + } + return 0; +} + +/* +** Copy the contents of sample *pNew into the p->a[] array. If necessary, +** remove the least desirable sample from p->a[] to make room. +*/ +static void sampleInsert(StatAccum *p, StatSample *pNew, int nEqZero){ + StatSample *pSample = 0; + int i; + + assert( IsStat4 || nEqZero==0 ); + + /* StatAccum.nMaxEqZero is set to the maximum number of leading 0 + ** values in the anEq[] array of any sample in StatAccum.a[]. In + ** other words, if nMaxEqZero is n, then it is guaranteed that there + ** are no samples with StatSample.anEq[m]==0 for (m>=n). */ + if( nEqZero>p->nMaxEqZero ){ + p->nMaxEqZero = nEqZero; + } + if( pNew->isPSample==0 ){ + StatSample *pUpgrade = 0; + assert( pNew->anEq[pNew->iCol]>0 ); + + /* This sample is being added because the prefix that ends in column + ** iCol occurs many times in the table. However, if we have already + ** added a sample that shares this prefix, there is no need to add + ** this one. Instead, upgrade the priority of the highest priority + ** existing sample that shares this prefix. */ + for(i=p->nSample-1; i>=0; i--){ + StatSample *pOld = &p->a[i]; + if( pOld->anEq[pNew->iCol]==0 ){ + if( pOld->isPSample ) return; + assert( pOld->iCol>pNew->iCol ); + assert( sampleIsBetter(p, pNew, pOld) ); + if( pUpgrade==0 || sampleIsBetter(p, pOld, pUpgrade) ){ + pUpgrade = pOld; + } + } + } + if( pUpgrade ){ + pUpgrade->iCol = pNew->iCol; + pUpgrade->anEq[pUpgrade->iCol] = pNew->anEq[pUpgrade->iCol]; + goto find_new_min; + } + } + + /* If necessary, remove sample iMin to make room for the new sample. */ + if( p->nSample>=p->mxSample ){ + StatSample *pMin = &p->a[p->iMin]; + tRowcnt *anEq = pMin->anEq; + tRowcnt *anLt = pMin->anLt; + tRowcnt *anDLt = pMin->anDLt; + sampleClear(p->db, pMin); + memmove(pMin, &pMin[1], sizeof(p->a[0])*(p->nSample-p->iMin-1)); + pSample = &p->a[p->nSample-1]; + pSample->nRowid = 0; + pSample->anEq = anEq; + pSample->anDLt = anDLt; + pSample->anLt = anLt; + p->nSample = p->mxSample-1; + } + + /* The "rows less-than" for the rowid column must be greater than that + ** for the last sample in the p->a[] array. Otherwise, the samples would + ** be out of order. */ + assert( p->nSample==0 + || pNew->anLt[p->nCol-1] > p->a[p->nSample-1].anLt[p->nCol-1] ); + + /* Insert the new sample */ + pSample = &p->a[p->nSample]; + sampleCopy(p, pSample, pNew); + p->nSample++; + + /* Zero the first nEqZero entries in the anEq[] array. */ + memset(pSample->anEq, 0, sizeof(tRowcnt)*nEqZero); + +find_new_min: + if( p->nSample>=p->mxSample ){ + int iMin = -1; + for(i=0; imxSample; i++){ + if( p->a[i].isPSample ) continue; + if( iMin<0 || sampleIsBetter(p, &p->a[iMin], &p->a[i]) ){ + iMin = i; + } + } + assert( iMin>=0 ); + p->iMin = iMin; + } +} +#endif /* SQLITE_ENABLE_STAT4 */ + +#ifdef SQLITE_ENABLE_STAT4 +/* +** Field iChng of the index being scanned has changed. So at this point +** p->current contains a sample that reflects the previous row of the +** index. The value of anEq[iChng] and subsequent anEq[] elements are +** correct at this point. +*/ +static void samplePushPrevious(StatAccum *p, int iChng){ + int i; + + /* Check if any samples from the aBest[] array should be pushed + ** into IndexSample.a[] at this point. */ + for(i=(p->nCol-2); i>=iChng; i--){ + StatSample *pBest = &p->aBest[i]; + pBest->anEq[i] = p->current.anEq[i]; + if( p->nSamplemxSample || sampleIsBetter(p, pBest, &p->a[p->iMin]) ){ + sampleInsert(p, pBest, i); + } + } + + /* Check that no sample contains an anEq[] entry with an index of + ** p->nMaxEqZero or greater set to zero. */ + for(i=p->nSample-1; i>=0; i--){ + int j; + for(j=p->nMaxEqZero; jnCol; j++) assert( p->a[i].anEq[j]>0 ); + } + + /* Update the anEq[] fields of any samples already collected. */ + if( iChngnMaxEqZero ){ + for(i=p->nSample-1; i>=0; i--){ + int j; + for(j=iChng; jnCol; j++){ + if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j]; + } + } + p->nMaxEqZero = iChng; + } +} +#endif /* SQLITE_ENABLE_STAT4 */ + +/* +** Implementation of the stat_push SQL function: stat_push(P,C,R) +** Arguments: +** +** P Pointer to the StatAccum object created by stat_init() +** C Index of left-most column to differ from previous row +** R Rowid for the current row. Might be a key record for +** WITHOUT ROWID tables. +** +** The purpose of this routine is to collect statistical data and/or +** samples from the index being analyzed into the StatAccum object. +** The stat_get() SQL function will be used afterwards to +** retrieve the information gathered. +** +** This SQL function usually returns NULL, but might return an integer +** if it wants the byte-code to do special processing. +** +** The R parameter is only used for STAT4 +*/ +static void statPush( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int i; + + /* The three function arguments */ + StatAccum *p = (StatAccum*)sqlite3_value_blob(argv[0]); + int iChng = sqlite3_value_int(argv[1]); + + UNUSED_PARAMETER( argc ); + UNUSED_PARAMETER( context ); + assert( p->nCol>0 ); + assert( iChngnCol ); + + if( p->nRow==0 ){ + /* This is the first call to this function. Do initialization. */ +#ifdef SQLITE_ENABLE_STAT4 + for(i=0; inCol; i++) p->current.anEq[i] = 1; +#endif + }else{ + /* Second and subsequent calls get processed here */ +#ifdef SQLITE_ENABLE_STAT4 + if( p->mxSample ) samplePushPrevious(p, iChng); +#endif + + /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply + ** to the current row of the index. */ +#ifdef SQLITE_ENABLE_STAT4 + for(i=0; icurrent.anEq[i]++; + } +#endif + for(i=iChng; inCol; i++){ + p->current.anDLt[i]++; +#ifdef SQLITE_ENABLE_STAT4 + if( p->mxSample ) p->current.anLt[i] += p->current.anEq[i]; + p->current.anEq[i] = 1; +#endif + } + } + + p->nRow++; +#ifdef SQLITE_ENABLE_STAT4 + if( p->mxSample ){ + tRowcnt nLt; + if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){ + sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2])); + }else{ + sampleSetRowid(p->db, &p->current, sqlite3_value_bytes(argv[2]), + sqlite3_value_blob(argv[2])); + } + p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345; + + nLt = p->current.anLt[p->nCol-1]; + /* Check if this is to be a periodic sample. If so, add it. */ + if( (nLt/p->nPSample)!=(nLt+1)/p->nPSample ){ + p->current.isPSample = 1; + p->current.iCol = 0; + sampleInsert(p, &p->current, p->nCol-1); + p->current.isPSample = 0; + } + + /* Update the aBest[] array. */ + for(i=0; i<(p->nCol-1); i++){ + p->current.iCol = i; + if( i>=iChng || sampleIsBetterPost(p, &p->current, &p->aBest[i]) ){ + sampleCopy(p, &p->aBest[i], &p->current); + } + } + }else +#endif + if( p->nLimit && p->nRow>(tRowcnt)p->nLimit*(p->nSkipAhead+1) ){ + p->nSkipAhead++; + sqlite3_result_int(context, p->current.anDLt[0]>0); + } +} + +static const FuncDef statPushFuncdef = { + 2+IsStat4, /* nArg */ + SQLITE_UTF8, /* funcFlags */ + 0, /* pUserData */ + 0, /* pNext */ + statPush, /* xSFunc */ + 0, /* xFinalize */ + 0, 0, /* xValue, xInverse */ + "stat_push", /* zName */ + {0} +}; + +#define STAT_GET_STAT1 0 /* "stat" column of stat1 table */ +#define STAT_GET_ROWID 1 /* "rowid" column of stat[34] entry */ +#define STAT_GET_NEQ 2 /* "neq" column of stat[34] entry */ +#define STAT_GET_NLT 3 /* "nlt" column of stat[34] entry */ +#define STAT_GET_NDLT 4 /* "ndlt" column of stat[34] entry */ + +/* +** Implementation of the stat_get(P,J) SQL function. This routine is +** used to query statistical information that has been gathered into +** the StatAccum object by prior calls to stat_push(). The P parameter +** has type BLOB but it is really just a pointer to the StatAccum object. +** The content to returned is determined by the parameter J +** which is one of the STAT_GET_xxxx values defined above. +** +** The stat_get(P,J) function is not available to generic SQL. It is +** inserted as part of a manually constructed bytecode program. (See +** the callStatGet() routine below.) It is guaranteed that the P +** parameter will always be a pointer to a StatAccum object, never a +** NULL. +** +** If STAT4 is not enabled, then J is always +** STAT_GET_STAT1 and is hence omitted and this routine becomes +** a one-parameter function, stat_get(P), that always returns the +** stat1 table entry information. +*/ +static void statGet( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + StatAccum *p = (StatAccum*)sqlite3_value_blob(argv[0]); +#ifdef SQLITE_ENABLE_STAT4 + /* STAT4 has a parameter on this routine. */ + int eCall = sqlite3_value_int(argv[1]); + assert( argc==2 ); + assert( eCall==STAT_GET_STAT1 || eCall==STAT_GET_NEQ + || eCall==STAT_GET_ROWID || eCall==STAT_GET_NLT + || eCall==STAT_GET_NDLT + ); + assert( eCall==STAT_GET_STAT1 || p->mxSample ); + if( eCall==STAT_GET_STAT1 ) +#else + assert( argc==1 ); +#endif + { + /* Return the value to store in the "stat" column of the sqlite_stat1 + ** table for this index. + ** + ** The value is a string composed of a list of integers describing + ** the index. The first integer in the list is the total number of + ** entries in the index. There is one additional integer in the list + ** for each indexed column. This additional integer is an estimate of + ** the number of rows matched by a equality query on the index using + ** a key with the corresponding number of fields. In other words, + ** if the index is on columns (a,b) and the sqlite_stat1 value is + ** "100 10 2", then SQLite estimates that: + ** + ** * the index contains 100 rows, + ** * "WHERE a=?" matches 10 rows, and + ** * "WHERE a=? AND b=?" matches 2 rows. + ** + ** If D is the count of distinct values and K is the total number of + ** rows, then each estimate is usually computed as: + ** + ** I = (K+D-1)/D + ** + ** In other words, I is K/D rounded up to the next whole integer. + ** However, if I is between 1.0 and 1.1 (in other words if I is + ** close to 1.0 but just a little larger) then do not round up but + ** instead keep the I value at 1.0. + */ + sqlite3_str sStat; /* Text of the constructed "stat" line */ + int i; /* Loop counter */ + + sqlite3StrAccumInit(&sStat, 0, 0, 0, (p->nKeyCol+1)*100); + sqlite3_str_appendf(&sStat, "%llu", + p->nSkipAhead ? (u64)p->nEst : (u64)p->nRow); + for(i=0; inKeyCol; i++){ + u64 nDistinct = p->current.anDLt[i] + 1; + u64 iVal = (p->nRow + nDistinct - 1) / nDistinct; + if( iVal==2 && p->nRow*10 <= nDistinct*11 ) iVal = 1; + sqlite3_str_appendf(&sStat, " %llu", iVal); +#ifdef SQLITE_ENABLE_STAT4 + assert( p->current.anEq[i] || p->nRow==0 ); +#endif + } + sqlite3ResultStrAccum(context, &sStat); + } +#ifdef SQLITE_ENABLE_STAT4 + else if( eCall==STAT_GET_ROWID ){ + if( p->iGet<0 ){ + samplePushPrevious(p, 0); + p->iGet = 0; + } + if( p->iGetnSample ){ + StatSample *pS = p->a + p->iGet; + if( pS->nRowid==0 ){ + sqlite3_result_int64(context, pS->u.iRowid); + }else{ + sqlite3_result_blob(context, pS->u.aRowid, pS->nRowid, + SQLITE_TRANSIENT); + } + } + }else{ + tRowcnt *aCnt = 0; + sqlite3_str sStat; + int i; + + assert( p->iGetnSample ); + switch( eCall ){ + case STAT_GET_NEQ: aCnt = p->a[p->iGet].anEq; break; + case STAT_GET_NLT: aCnt = p->a[p->iGet].anLt; break; + default: { + aCnt = p->a[p->iGet].anDLt; + p->iGet++; + break; + } + } + sqlite3StrAccumInit(&sStat, 0, 0, 0, p->nCol*100); + for(i=0; inCol; i++){ + sqlite3_str_appendf(&sStat, "%llu ", (u64)aCnt[i]); + } + if( sStat.nChar ) sStat.nChar--; + sqlite3ResultStrAccum(context, &sStat); + } +#endif /* SQLITE_ENABLE_STAT4 */ +#ifndef SQLITE_DEBUG + UNUSED_PARAMETER( argc ); +#endif +} +static const FuncDef statGetFuncdef = { + 1+IsStat4, /* nArg */ + SQLITE_UTF8, /* funcFlags */ + 0, /* pUserData */ + 0, /* pNext */ + statGet, /* xSFunc */ + 0, /* xFinalize */ + 0, 0, /* xValue, xInverse */ + "stat_get", /* zName */ + {0} +}; + +static void callStatGet(Parse *pParse, int regStat, int iParam, int regOut){ +#ifdef SQLITE_ENABLE_STAT4 + sqlite3VdbeAddOp2(pParse->pVdbe, OP_Integer, iParam, regStat+1); +#elif SQLITE_DEBUG + assert( iParam==STAT_GET_STAT1 ); +#else + UNUSED_PARAMETER( iParam ); +#endif + assert( regOut!=regStat && regOut!=regStat+1 ); + sqlite3VdbeAddFunctionCall(pParse, 0, regStat, regOut, 1+IsStat4, + &statGetFuncdef, 0); +} + +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS +/* Add a comment to the most recent VDBE opcode that is the name +** of the k-th column of the pIdx index. +*/ +static void analyzeVdbeCommentIndexWithColumnName( + Vdbe *v, /* Prepared statement under construction */ + Index *pIdx, /* Index whose column is being loaded */ + int k /* Which column index */ +){ + int i; /* Index of column in the table */ + assert( k>=0 && knColumn ); + i = pIdx->aiColumn[k]; + if( NEVER(i==XN_ROWID) ){ + VdbeComment((v,"%s.rowid",pIdx->zName)); + }else if( i==XN_EXPR ){ + assert( pIdx->bHasExpr ); + VdbeComment((v,"%s.expr(%d)",pIdx->zName, k)); + }else{ + VdbeComment((v,"%s.%s", pIdx->zName, pIdx->pTable->aCol[i].zCnName)); + } +} +#else +# define analyzeVdbeCommentIndexWithColumnName(a,b,c) +#endif /* SQLITE_DEBUG */ + +/* +** Generate code to do an analysis of all indices associated with +** a single table. +*/ +static void analyzeOneTable( + Parse *pParse, /* Parser context */ + Table *pTab, /* Table whose indices are to be analyzed */ + Index *pOnlyIdx, /* If not NULL, only analyze this one index */ + int iStatCur, /* Index of VdbeCursor that writes the sqlite_stat1 table */ + int iMem, /* Available memory locations begin here */ + int iTab /* Next available cursor */ +){ + sqlite3 *db = pParse->db; /* Database handle */ + Index *pIdx; /* An index to being analyzed */ + int iIdxCur; /* Cursor open on index being analyzed */ + int iTabCur; /* Table cursor */ + Vdbe *v; /* The virtual machine being built up */ + int i; /* Loop counter */ + int jZeroRows = -1; /* Jump from here if number of rows is zero */ + int iDb; /* Index of database containing pTab */ + u8 needTableCnt = 1; /* True to count the table */ + int regNewRowid = iMem++; /* Rowid for the inserted record */ + int regStat = iMem++; /* Register to hold StatAccum object */ + int regChng = iMem++; /* Index of changed index field */ + int regRowid = iMem++; /* Rowid argument passed to stat_push() */ + int regTemp = iMem++; /* Temporary use register */ + int regTemp2 = iMem++; /* Second temporary use register */ + int regTabname = iMem++; /* Register containing table name */ + int regIdxname = iMem++; /* Register containing index name */ + int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */ + int regPrev = iMem; /* MUST BE LAST (see below) */ +#ifdef SQLITE_ENABLE_STAT4 + int doOnce = 1; /* Flag for a one-time computation */ +#endif +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + Table *pStat1 = 0; +#endif + + sqlite3TouchRegister(pParse, iMem); + assert( sqlite3NoTempsInRange(pParse, regNewRowid, iMem) ); + v = sqlite3GetVdbe(pParse); + if( v==0 || NEVER(pTab==0) ){ + return; + } + if( !IsOrdinaryTable(pTab) ){ + /* Do not gather statistics on views or virtual tables */ + return; + } + if( sqlite3_strlike("sqlite\\_%", pTab->zName, '\\')==0 ){ + /* Do not gather statistics on system tables */ + return; + } + assert( sqlite3BtreeHoldsAllMutexes(db) ); + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iDb>=0 ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); +#ifndef SQLITE_OMIT_AUTHORIZATION + if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0, + db->aDb[iDb].zDbSName ) ){ + return; + } +#endif + +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + if( db->xPreUpdateCallback ){ + pStat1 = (Table*)sqlite3DbMallocZero(db, sizeof(Table) + 13); + if( pStat1==0 ) return; + pStat1->zName = (char*)&pStat1[1]; + memcpy(pStat1->zName, "sqlite_stat1", 13); + pStat1->nCol = 3; + pStat1->iPKey = -1; + sqlite3VdbeAddOp4(pParse->pVdbe, OP_Noop, 0, 0, 0,(char*)pStat1,P4_DYNAMIC); + } +#endif + + /* Establish a read-lock on the table at the shared-cache level. + ** Open a read-only cursor on the table. Also allocate a cursor number + ** to use for scanning indexes (iIdxCur). No index cursor is opened at + ** this time though. */ + sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); + iTabCur = iTab++; + iIdxCur = iTab++; + pParse->nTab = MAX(pParse->nTab, iTab); + sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); + sqlite3VdbeLoadString(v, regTabname, pTab->zName); + + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + int nCol; /* Number of columns in pIdx. "N" */ + int addrGotoEnd; /* Address of "OP_Rewind iIdxCur" */ + int addrNextRow; /* Address of "next_row:" */ + const char *zIdxName; /* Name of the index */ + int nColTest; /* Number of columns to test for changes */ + + if( pOnlyIdx && pOnlyIdx!=pIdx ) continue; + if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0; + if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIdx) ){ + nCol = pIdx->nKeyCol; + zIdxName = pTab->zName; + nColTest = nCol - 1; + }else{ + nCol = pIdx->nColumn; + zIdxName = pIdx->zName; + nColTest = pIdx->uniqNotNull ? pIdx->nKeyCol-1 : nCol-1; + } + + /* Populate the register containing the index name. */ + sqlite3VdbeLoadString(v, regIdxname, zIdxName); + VdbeComment((v, "Analysis for %s.%s", pTab->zName, zIdxName)); + + /* + ** Pseudo-code for loop that calls stat_push(): + ** + ** regChng = 0 + ** Rewind csr + ** if eof(csr){ + ** stat_init() with count = 0; + ** goto end_of_scan; + ** } + ** count() + ** stat_init() + ** goto chng_addr_0; + ** + ** next_row: + ** regChng = 0 + ** if( idx(0) != regPrev(0) ) goto chng_addr_0 + ** regChng = 1 + ** if( idx(1) != regPrev(1) ) goto chng_addr_1 + ** ... + ** regChng = N + ** goto chng_addr_N + ** + ** chng_addr_0: + ** regPrev(0) = idx(0) + ** chng_addr_1: + ** regPrev(1) = idx(1) + ** ... + ** + ** endDistinctTest: + ** regRowid = idx(rowid) + ** stat_push(P, regChng, regRowid) + ** Next csr + ** if !eof(csr) goto next_row; + ** + ** end_of_scan: + */ + + /* Make sure there are enough memory cells allocated to accommodate + ** the regPrev array and a trailing rowid (the rowid slot is required + ** when building a record to insert into the sample column of + ** the sqlite_stat4 table. */ + sqlite3TouchRegister(pParse, regPrev+nColTest); + + /* Open a read-only cursor on the index being analyzed. */ + assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) ); + sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIdx); + VdbeComment((v, "%s", pIdx->zName)); + + /* Implementation of the following: + ** + ** regChng = 0 + ** Rewind csr + ** if eof(csr){ + ** stat_init() with count = 0; + ** goto end_of_scan; + ** } + ** count() + ** stat_init() + ** goto chng_addr_0; + */ + assert( regTemp2==regStat+4 ); + sqlite3VdbeAddOp2(v, OP_Integer, db->nAnalysisLimit, regTemp2); + + /* Arguments to stat_init(): + ** (1) the number of columns in the index including the rowid + ** (or for a WITHOUT ROWID table, the number of PK columns), + ** (2) the number of columns in the key without the rowid/pk + ** (3) estimated number of rows in the index. */ + sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat+1); + assert( regRowid==regStat+2 ); + sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regRowid); + sqlite3VdbeAddOp3(v, OP_Count, iIdxCur, regTemp, + OptimizationDisabled(db, SQLITE_Stat4)); + sqlite3VdbeAddFunctionCall(pParse, 0, regStat+1, regStat, 4, + &statInitFuncdef, 0); + addrGotoEnd = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); + VdbeCoverage(v); + + sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng); + addrNextRow = sqlite3VdbeCurrentAddr(v); + + if( nColTest>0 ){ + int endDistinctTest = sqlite3VdbeMakeLabel(pParse); + int *aGotoChng; /* Array of jump instruction addresses */ + aGotoChng = sqlite3DbMallocRawNN(db, sizeof(int)*nColTest); + if( aGotoChng==0 ) continue; + + /* + ** next_row: + ** regChng = 0 + ** if( idx(0) != regPrev(0) ) goto chng_addr_0 + ** regChng = 1 + ** if( idx(1) != regPrev(1) ) goto chng_addr_1 + ** ... + ** regChng = N + ** goto endDistinctTest + */ + sqlite3VdbeAddOp0(v, OP_Goto); + addrNextRow = sqlite3VdbeCurrentAddr(v); + if( nColTest==1 && pIdx->nKeyCol==1 && IsUniqueIndex(pIdx) ){ + /* For a single-column UNIQUE index, once we have found a non-NULL + ** row, we know that all the rest will be distinct, so skip + ** subsequent distinctness tests. */ + sqlite3VdbeAddOp2(v, OP_NotNull, regPrev, endDistinctTest); + VdbeCoverage(v); + } + for(i=0; iazColl[i]); + sqlite3VdbeAddOp2(v, OP_Integer, i, regChng); + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp); + analyzeVdbeCommentIndexWithColumnName(v,pIdx,i); + aGotoChng[i] = + sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ); + sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); + VdbeCoverage(v); + } + sqlite3VdbeAddOp2(v, OP_Integer, nColTest, regChng); + sqlite3VdbeGoto(v, endDistinctTest); + + + /* + ** chng_addr_0: + ** regPrev(0) = idx(0) + ** chng_addr_1: + ** regPrev(1) = idx(1) + ** ... + */ + sqlite3VdbeJumpHere(v, addrNextRow-1); + for(i=0; ipTable); + int j, k, regKey; + regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol); + for(j=0; jnKeyCol; j++){ + k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]); + assert( k>=0 && knColumn ); + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j); + analyzeVdbeCommentIndexWithColumnName(v,pIdx,k); + } + sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid); + sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol); + } + } +#endif + assert( regChng==(regStat+1) ); + { + sqlite3VdbeAddFunctionCall(pParse, 1, regStat, regTemp, 2+IsStat4, + &statPushFuncdef, 0); + if( db->nAnalysisLimit ){ + int j1, j2, j3; + j1 = sqlite3VdbeAddOp1(v, OP_IsNull, regTemp); VdbeCoverage(v); + j2 = sqlite3VdbeAddOp1(v, OP_If, regTemp); VdbeCoverage(v); + j3 = sqlite3VdbeAddOp4Int(v, OP_SeekGT, iIdxCur, 0, regPrev, 1); + VdbeCoverage(v); + sqlite3VdbeJumpHere(v, j1); + sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, j2); + sqlite3VdbeJumpHere(v, j3); + }else{ + sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v); + } + } + + /* Add the entry to the stat1 table. */ + if( pIdx->pPartIdxWhere ){ + /* Partial indexes might get a zero-entry in sqlite_stat1. But + ** an empty table is omitted from sqlite_stat1. */ + sqlite3VdbeJumpHere(v, addrGotoEnd); + addrGotoEnd = 0; + } + callStatGet(pParse, regStat, STAT_GET_STAT1, regStat1); + assert( "BBB"[0]==SQLITE_AFF_TEXT ); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0); + sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); + sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE); +#endif + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + + /* Add the entries to the stat4 table. */ +#ifdef SQLITE_ENABLE_STAT4 + if( OptimizationEnabled(db, SQLITE_Stat4) && db->nAnalysisLimit==0 ){ + int regEq = regStat1; + int regLt = regStat1+1; + int regDLt = regStat1+2; + int regSample = regStat1+3; + int regCol = regStat1+4; + int regSampleRowid = regCol + nCol; + int addrNext; + int addrIsNull; + u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound; + + /* No STAT4 data is generated if the number of rows is zero */ + if( addrGotoEnd==0 ){ + sqlite3VdbeAddOp2(v, OP_Cast, regStat1, SQLITE_AFF_INTEGER); + addrGotoEnd = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1); + VdbeCoverage(v); + } + + if( doOnce ){ + int mxCol = nCol; + Index *pX; + + /* Compute the maximum number of columns in any index */ + for(pX=pTab->pIndex; pX; pX=pX->pNext){ + int nColX; /* Number of columns in pX */ + if( !HasRowid(pTab) && IsPrimaryKeyIndex(pX) ){ + nColX = pX->nKeyCol; + }else{ + nColX = pX->nColumn; + } + if( nColX>mxCol ) mxCol = nColX; + } + + /* Allocate space to compute results for the largest index */ + sqlite3TouchRegister(pParse, regCol+mxCol); + doOnce = 0; +#ifdef SQLITE_DEBUG + /* Verify that the call to sqlite3ClearTempRegCache() below + ** really is needed. + ** https://sqlite.org/forum/forumpost/83cb4a95a0 (2023-03-25) + */ + testcase( !sqlite3NoTempsInRange(pParse, regEq, regCol+mxCol) ); +#endif + sqlite3ClearTempRegCache(pParse); /* tag-20230325-1 */ + assert( sqlite3NoTempsInRange(pParse, regEq, regCol+mxCol) ); + } + assert( sqlite3NoTempsInRange(pParse, regEq, regCol+nCol) ); + + addrNext = sqlite3VdbeCurrentAddr(v); + callStatGet(pParse, regStat, STAT_GET_ROWID, regSampleRowid); + addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid); + VdbeCoverage(v); + callStatGet(pParse, regStat, STAT_GET_NEQ, regEq); + callStatGet(pParse, regStat, STAT_GET_NLT, regLt); + callStatGet(pParse, regStat, STAT_GET_NDLT, regDLt); + sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0); + VdbeCoverage(v); + for(i=0; izName)); + sqlite3VdbeAddOp2(v, OP_Count, iTabCur, regStat1); + jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname); + assert( "BBB"[0]==SQLITE_AFF_TEXT ); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0); + sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); + sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE); +#endif + sqlite3VdbeJumpHere(v, jZeroRows); + } +} + + +/* +** Generate code that will cause the most recent index analysis to +** be loaded into internal hash tables where is can be used. +*/ +static void loadAnalysis(Parse *pParse, int iDb){ + Vdbe *v = sqlite3GetVdbe(pParse); + if( v ){ + sqlite3VdbeAddOp1(v, OP_LoadAnalysis, iDb); + } +} + +/* +** Generate code that will do an analysis of an entire database +*/ +static void analyzeDatabase(Parse *pParse, int iDb){ + sqlite3 *db = pParse->db; + Schema *pSchema = db->aDb[iDb].pSchema; /* Schema of database iDb */ + HashElem *k; + int iStatCur; + int iMem; + int iTab; + + sqlite3BeginWriteOperation(pParse, 0, iDb); + iStatCur = pParse->nTab; + pParse->nTab += 3; + openStatTable(pParse, iDb, iStatCur, 0, 0); + iMem = pParse->nMem+1; + iTab = pParse->nTab; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ + Table *pTab = (Table*)sqliteHashData(k); + analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab); +#ifdef SQLITE_ENABLE_STAT4 + iMem = sqlite3FirstAvailableRegister(pParse, iMem); +#else + assert( iMem==sqlite3FirstAvailableRegister(pParse,iMem) ); +#endif + } + loadAnalysis(pParse, iDb); +} + +/* +** Generate code that will do an analysis of a single table in +** a database. If pOnlyIdx is not NULL then it is a single index +** in pTab that should be analyzed. +*/ +static void analyzeTable(Parse *pParse, Table *pTab, Index *pOnlyIdx){ + int iDb; + int iStatCur; + + assert( pTab!=0 ); + assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); + iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + sqlite3BeginWriteOperation(pParse, 0, iDb); + iStatCur = pParse->nTab; + pParse->nTab += 3; + if( pOnlyIdx ){ + openStatTable(pParse, iDb, iStatCur, pOnlyIdx->zName, "idx"); + }else{ + openStatTable(pParse, iDb, iStatCur, pTab->zName, "tbl"); + } + analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur,pParse->nMem+1,pParse->nTab); + loadAnalysis(pParse, iDb); +} + +/* +** Generate code for the ANALYZE command. The parser calls this routine +** when it recognizes an ANALYZE command. +** +** ANALYZE -- 1 +** ANALYZE -- 2 +** ANALYZE ?.? -- 3 +** +** Form 1 causes all indices in all attached databases to be analyzed. +** Form 2 analyzes all indices the single database named. +** Form 3 analyzes all indices associated with the named table. +*/ +SQLITE_PRIVATE void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){ + sqlite3 *db = pParse->db; + int iDb; + int i; + char *z, *zDb; + Table *pTab; + Index *pIdx; + Token *pTableName; + Vdbe *v; + + /* Read the database schema. If an error occurs, leave an error message + ** and code in pParse and return NULL. */ + assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + return; + } + + assert( pName2!=0 || pName1==0 ); + if( pName1==0 ){ + /* Form 1: Analyze everything */ + for(i=0; inDb; i++){ + if( i==1 ) continue; /* Do not analyze the TEMP database */ + analyzeDatabase(pParse, i); + } + }else if( pName2->n==0 && (iDb = sqlite3FindDb(db, pName1))>=0 ){ + /* Analyze the schema named as the argument */ + analyzeDatabase(pParse, iDb); + }else{ + /* Form 3: Analyze the table or index named as an argument */ + iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName); + if( iDb>=0 ){ + zDb = pName2->n ? db->aDb[iDb].zDbSName : 0; + z = sqlite3NameFromToken(db, pTableName); + if( z ){ + if( (pIdx = sqlite3FindIndex(db, z, zDb))!=0 ){ + analyzeTable(pParse, pIdx->pTable, pIdx); + }else if( (pTab = sqlite3LocateTable(pParse, 0, z, zDb))!=0 ){ + analyzeTable(pParse, pTab, 0); + } + sqlite3DbFree(db, z); + } + } + } + if( db->nSqlExec==0 && (v = sqlite3GetVdbe(pParse))!=0 ){ + sqlite3VdbeAddOp0(v, OP_Expire); + } +} + +/* +** Used to pass information from the analyzer reader through to the +** callback routine. +*/ +typedef struct analysisInfo analysisInfo; +struct analysisInfo { + sqlite3 *db; + const char *zDatabase; +}; + +/* +** The first argument points to a nul-terminated string containing a +** list of space separated integers. Read the first nOut of these into +** the array aOut[]. +*/ +static void decodeIntArray( + char *zIntArray, /* String containing int array to decode */ + int nOut, /* Number of slots in aOut[] */ + tRowcnt *aOut, /* Store integers here */ + LogEst *aLog, /* Or, if aOut==0, here */ + Index *pIndex /* Handle extra flags for this index, if not NULL */ +){ + char *z = zIntArray; + int c; + int i; + tRowcnt v; + +#ifdef SQLITE_ENABLE_STAT4 + if( z==0 ) z = ""; +#else + assert( z!=0 ); +#endif + for(i=0; *z && i='0' && c<='9' ){ + v = v*10 + c - '0'; + z++; + } +#ifdef SQLITE_ENABLE_STAT4 + if( aOut ) aOut[i] = v; + if( aLog ) aLog[i] = sqlite3LogEst(v); +#else + assert( aOut==0 ); + UNUSED_PARAMETER(aOut); + assert( aLog!=0 ); + aLog[i] = sqlite3LogEst(v); +#endif + if( *z==' ' ) z++; + } +#ifndef SQLITE_ENABLE_STAT4 + assert( pIndex!=0 ); { +#else + if( pIndex ){ +#endif + pIndex->bUnordered = 0; + pIndex->noSkipScan = 0; + while( z[0] ){ + if( sqlite3_strglob("unordered*", z)==0 ){ + pIndex->bUnordered = 1; + }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){ + int sz = sqlite3Atoi(z+3); + if( sz<2 ) sz = 2; + pIndex->szIdxRow = sqlite3LogEst(sz); + }else if( sqlite3_strglob("noskipscan*", z)==0 ){ + pIndex->noSkipScan = 1; + } +#ifdef SQLITE_ENABLE_COSTMULT + else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){ + pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9)); + } +#endif + while( z[0]!=0 && z[0]!=' ' ) z++; + while( z[0]==' ' ) z++; + } + } +} + +/* +** This callback is invoked once for each index when reading the +** sqlite_stat1 table. +** +** argv[0] = name of the table +** argv[1] = name of the index (might be NULL) +** argv[2] = results of analysis - on integer for each column +** +** Entries for which argv[1]==NULL simply record the number of rows in +** the table. +*/ +static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ + analysisInfo *pInfo = (analysisInfo*)pData; + Index *pIndex; + Table *pTable; + const char *z; + + assert( argc==3 ); + UNUSED_PARAMETER2(NotUsed, argc); + + if( argv==0 || argv[0]==0 || argv[2]==0 ){ + return 0; + } + pTable = sqlite3FindTable(pInfo->db, argv[0], pInfo->zDatabase); + if( pTable==0 ){ + return 0; + } + if( argv[1]==0 ){ + pIndex = 0; + }else if( sqlite3_stricmp(argv[0],argv[1])==0 ){ + pIndex = sqlite3PrimaryKeyIndex(pTable); + }else{ + pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); + } + z = argv[2]; + + if( pIndex ){ + tRowcnt *aiRowEst = 0; + int nCol = pIndex->nKeyCol+1; +#ifdef SQLITE_ENABLE_STAT4 + /* Index.aiRowEst may already be set here if there are duplicate + ** sqlite_stat1 entries for this index. In that case just clobber + ** the old data with the new instead of allocating a new array. */ + if( pIndex->aiRowEst==0 ){ + pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol); + if( pIndex->aiRowEst==0 ) sqlite3OomFault(pInfo->db); + } + aiRowEst = pIndex->aiRowEst; +#endif + pIndex->bUnordered = 0; + decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex); + pIndex->hasStat1 = 1; + if( pIndex->pPartIdxWhere==0 ){ + pTable->nRowLogEst = pIndex->aiRowLogEst[0]; + pTable->tabFlags |= TF_HasStat1; + } + }else{ + Index fakeIdx; + fakeIdx.szIdxRow = pTable->szTabRow; +#ifdef SQLITE_ENABLE_COSTMULT + fakeIdx.pTable = pTable; +#endif + decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx); + pTable->szTabRow = fakeIdx.szIdxRow; + pTable->tabFlags |= TF_HasStat1; + } + + return 0; +} + +/* +** If the Index.aSample variable is not NULL, delete the aSample[] array +** and its contents. +*/ +SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){ + assert( db!=0 ); + assert( pIdx!=0 ); +#ifdef SQLITE_ENABLE_STAT4 + if( pIdx->aSample ){ + int j; + for(j=0; jnSample; j++){ + IndexSample *p = &pIdx->aSample[j]; + sqlite3DbFree(db, p->p); + } + sqlite3DbFree(db, pIdx->aSample); + } + if( db->pnBytesFreed==0 ){ + pIdx->nSample = 0; + pIdx->aSample = 0; + } +#else + UNUSED_PARAMETER(db); + UNUSED_PARAMETER(pIdx); +#endif /* SQLITE_ENABLE_STAT4 */ +} + +#ifdef SQLITE_ENABLE_STAT4 +/* +** Populate the pIdx->aAvgEq[] array based on the samples currently +** stored in pIdx->aSample[]. +*/ +static void initAvgEq(Index *pIdx){ + if( pIdx ){ + IndexSample *aSample = pIdx->aSample; + IndexSample *pFinal = &aSample[pIdx->nSample-1]; + int iCol; + int nCol = 1; + if( pIdx->nSampleCol>1 ){ + /* If this is stat4 data, then calculate aAvgEq[] values for all + ** sample columns except the last. The last is always set to 1, as + ** once the trailing PK fields are considered all index keys are + ** unique. */ + nCol = pIdx->nSampleCol-1; + pIdx->aAvgEq[nCol] = 1; + } + for(iCol=0; iColnSample; + int i; /* Used to iterate through samples */ + tRowcnt sumEq = 0; /* Sum of the nEq values */ + tRowcnt avgEq = 0; + tRowcnt nRow; /* Number of rows in index */ + i64 nSum100 = 0; /* Number of terms contributing to sumEq */ + i64 nDist100; /* Number of distinct values in index */ + + if( !pIdx->aiRowEst || iCol>=pIdx->nKeyCol || pIdx->aiRowEst[iCol+1]==0 ){ + nRow = pFinal->anLt[iCol]; + nDist100 = (i64)100 * pFinal->anDLt[iCol]; + nSample--; + }else{ + nRow = pIdx->aiRowEst[0]; + nDist100 = ((i64)100 * pIdx->aiRowEst[0]) / pIdx->aiRowEst[iCol+1]; + } + pIdx->nRowEst0 = nRow; + + /* Set nSum to the number of distinct (iCol+1) field prefixes that + ** occur in the stat4 table for this index. Set sumEq to the sum of + ** the nEq values for column iCol for the same set (adding the value + ** only once where there exist duplicate prefixes). */ + for(i=0; inSample-1) + || aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] + ){ + sumEq += aSample[i].anEq[iCol]; + nSum100 += 100; + } + } + + if( nDist100>nSum100 && sumEqaAvgEq[iCol] = avgEq; + } + } +} + +/* +** Look up an index by name. Or, if the name of a WITHOUT ROWID table +** is supplied instead, find the PRIMARY KEY index for that table. +*/ +static Index *findIndexOrPrimaryKey( + sqlite3 *db, + const char *zName, + const char *zDb +){ + Index *pIdx = sqlite3FindIndex(db, zName, zDb); + if( pIdx==0 ){ + Table *pTab = sqlite3FindTable(db, zName, zDb); + if( pTab && !HasRowid(pTab) ) pIdx = sqlite3PrimaryKeyIndex(pTab); + } + return pIdx; +} + +/* +** Load the content from either the sqlite_stat4 +** into the relevant Index.aSample[] arrays. +** +** Arguments zSql1 and zSql2 must point to SQL statements that return +** data equivalent to the following: +** +** zSql1: SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx +** zSql2: SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4 +** +** where %Q is replaced with the database name before the SQL is executed. +*/ +static int loadStatTbl( + sqlite3 *db, /* Database handle */ + const char *zSql1, /* SQL statement 1 (see above) */ + const char *zSql2, /* SQL statement 2 (see above) */ + const char *zDb /* Database name (e.g. "main") */ +){ + int rc; /* Result codes from subroutines */ + sqlite3_stmt *pStmt = 0; /* An SQL statement being run */ + char *zSql; /* Text of the SQL statement */ + Index *pPrevIdx = 0; /* Previous index in the loop */ + IndexSample *pSample; /* A slot in pIdx->aSample[] */ + + assert( db->lookaside.bDisable ); + zSql = sqlite3MPrintf(db, zSql1, zDb); + if( !zSql ){ + return SQLITE_NOMEM_BKPT; + } + rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); + sqlite3DbFree(db, zSql); + if( rc ) return rc; + + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + int nIdxCol = 1; /* Number of columns in stat4 records */ + + char *zIndex; /* Index name */ + Index *pIdx; /* Pointer to the index object */ + int nSample; /* Number of samples */ + i64 nByte; /* Bytes of space required */ + i64 i; /* Bytes of space required */ + tRowcnt *pSpace; /* Available allocated memory space */ + u8 *pPtr; /* Available memory as a u8 for easier manipulation */ + + zIndex = (char *)sqlite3_column_text(pStmt, 0); + if( zIndex==0 ) continue; + nSample = sqlite3_column_int(pStmt, 1); + pIdx = findIndexOrPrimaryKey(db, zIndex, zDb); + assert( pIdx==0 || pIdx->nSample==0 ); + if( pIdx==0 ) continue; + if( pIdx->aSample!=0 ){ + /* The same index appears in sqlite_stat4 under multiple names */ + continue; + } + assert( !HasRowid(pIdx->pTable) || pIdx->nColumn==pIdx->nKeyCol+1 ); + if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){ + nIdxCol = pIdx->nKeyCol; + }else{ + nIdxCol = pIdx->nColumn; + } + pIdx->nSampleCol = nIdxCol; + pIdx->mxSample = nSample; + nByte = ROUND8(sizeof64(IndexSample) * nSample); + nByte += sizeof64(tRowcnt) * nIdxCol * 3 * nSample; + nByte += nIdxCol * sizeof64(tRowcnt); /* Space for Index.aAvgEq[] */ + + pIdx->aSample = sqlite3DbMallocZero(db, nByte); + if( pIdx->aSample==0 ){ + sqlite3_finalize(pStmt); + return SQLITE_NOMEM_BKPT; + } + pPtr = (u8*)pIdx->aSample; + pPtr += ROUND8(nSample*sizeof64(pIdx->aSample[0])); + pSpace = (tRowcnt*)pPtr; + assert( EIGHT_BYTE_ALIGNMENT( pSpace ) ); + pIdx->aAvgEq = pSpace; pSpace += nIdxCol; + pIdx->pTable->tabFlags |= TF_HasStat4; + for(i=0; iaSample[i].anEq = pSpace; pSpace += nIdxCol; + pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol; + pIdx->aSample[i].anDLt = pSpace; pSpace += nIdxCol; + } + assert( ((u8*)pSpace)-nByte==(u8*)(pIdx->aSample) ); + } + rc = sqlite3_finalize(pStmt); + if( rc ) return rc; + + zSql = sqlite3MPrintf(db, zSql2, zDb); + if( !zSql ){ + return SQLITE_NOMEM_BKPT; + } + rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); + sqlite3DbFree(db, zSql); + if( rc ) return rc; + + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + char *zIndex; /* Index name */ + Index *pIdx; /* Pointer to the index object */ + int nCol = 1; /* Number of columns in index */ + + zIndex = (char *)sqlite3_column_text(pStmt, 0); + if( zIndex==0 ) continue; + pIdx = findIndexOrPrimaryKey(db, zIndex, zDb); + if( pIdx==0 ) continue; + if( pIdx->nSample>=pIdx->mxSample ){ + /* Too many slots used because the same index appears in + ** sqlite_stat4 using multiple names */ + continue; + } + /* This next condition is true if data has already been loaded from + ** the sqlite_stat4 table. */ + nCol = pIdx->nSampleCol; + if( pIdx!=pPrevIdx ){ + initAvgEq(pPrevIdx); + pPrevIdx = pIdx; + } + pSample = &pIdx->aSample[pIdx->nSample]; + decodeIntArray((char*)sqlite3_column_text(pStmt,1),nCol,pSample->anEq,0,0); + decodeIntArray((char*)sqlite3_column_text(pStmt,2),nCol,pSample->anLt,0,0); + decodeIntArray((char*)sqlite3_column_text(pStmt,3),nCol,pSample->anDLt,0,0); + + /* Take a copy of the sample. Add 8 extra 0x00 bytes the end of the buffer. + ** This is in case the sample record is corrupted. In that case, the + ** sqlite3VdbeRecordCompare() may read up to two varints past the + ** end of the allocated buffer before it realizes it is dealing with + ** a corrupt record. Or it might try to read a large integer from the + ** buffer. In any case, eight 0x00 bytes prevents this from causing + ** a buffer overread. */ + pSample->n = sqlite3_column_bytes(pStmt, 4); + pSample->p = sqlite3DbMallocZero(db, pSample->n + 8); + if( pSample->p==0 ){ + sqlite3_finalize(pStmt); + return SQLITE_NOMEM_BKPT; + } + if( pSample->n ){ + memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n); + } + pIdx->nSample++; + } + rc = sqlite3_finalize(pStmt); + if( rc==SQLITE_OK ) initAvgEq(pPrevIdx); + return rc; +} + +/* +** Load content from the sqlite_stat4 table into +** the Index.aSample[] arrays of all indices. +*/ +static int loadStat4(sqlite3 *db, const char *zDb){ + int rc = SQLITE_OK; /* Result codes from subroutines */ + const Table *pStat4; + + assert( db->lookaside.bDisable ); + if( OptimizationEnabled(db, SQLITE_Stat4) + && (pStat4 = sqlite3FindTable(db, "sqlite_stat4", zDb))!=0 + && IsOrdinaryTable(pStat4) + ){ + rc = loadStatTbl(db, + "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx COLLATE nocase", + "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4", + zDb + ); + } + return rc; +} +#endif /* SQLITE_ENABLE_STAT4 */ + +/* +** Load the content of the sqlite_stat1 and sqlite_stat4 tables. The +** contents of sqlite_stat1 are used to populate the Index.aiRowEst[] +** arrays. The contents of sqlite_stat4 are used to populate the +** Index.aSample[] arrays. +** +** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR +** is returned. In this case, even if SQLITE_ENABLE_STAT4 was defined +** during compilation and the sqlite_stat4 table is present, no data is +** read from it. +** +** If SQLITE_ENABLE_STAT4 was defined during compilation and the +** sqlite_stat4 table is not present in the database, SQLITE_ERROR is +** returned. However, in this case, data is read from the sqlite_stat1 +** table (if it is present) before returning. +** +** If an OOM error occurs, this function always sets db->mallocFailed. +** This means if the caller does not care about other errors, the return +** code may be ignored. +*/ +SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ + analysisInfo sInfo; + HashElem *i; + char *zSql; + int rc = SQLITE_OK; + Schema *pSchema = db->aDb[iDb].pSchema; + const Table *pStat1; + + assert( iDb>=0 && iDbnDb ); + assert( db->aDb[iDb].pBt!=0 ); + + /* Clear any prior statistics */ + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + for(i=sqliteHashFirst(&pSchema->tblHash); i; i=sqliteHashNext(i)){ + Table *pTab = sqliteHashData(i); + pTab->tabFlags &= ~TF_HasStat1; + } + for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){ + Index *pIdx = sqliteHashData(i); + pIdx->hasStat1 = 0; +#ifdef SQLITE_ENABLE_STAT4 + sqlite3DeleteIndexSamples(db, pIdx); + pIdx->aSample = 0; +#endif + } + + /* Load new statistics out of the sqlite_stat1 table */ + sInfo.db = db; + sInfo.zDatabase = db->aDb[iDb].zDbSName; + if( (pStat1 = sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)) + && IsOrdinaryTable(pStat1) + ){ + zSql = sqlite3MPrintf(db, + "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase); + if( zSql==0 ){ + rc = SQLITE_NOMEM_BKPT; + }else{ + rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); + sqlite3DbFree(db, zSql); + } + } + + /* Set appropriate defaults on all indexes not in the sqlite_stat1 table */ + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){ + Index *pIdx = sqliteHashData(i); + if( !pIdx->hasStat1 ) sqlite3DefaultRowEst(pIdx); + } + + /* Load the statistics from the sqlite_stat4 table. */ +#ifdef SQLITE_ENABLE_STAT4 + if( rc==SQLITE_OK ){ + DisableLookaside; + rc = loadStat4(db, sInfo.zDatabase); + EnableLookaside; + } + for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){ + Index *pIdx = sqliteHashData(i); + sqlite3_free(pIdx->aiRowEst); + pIdx->aiRowEst = 0; + } +#endif + + if( rc==SQLITE_NOMEM ){ + sqlite3OomFault(db); + } + return rc; +} + + +#endif /* SQLITE_OMIT_ANALYZE */ + +/************** End of analyze.c *********************************************/ +/************** Begin file attach.c ******************************************/ +/* +** 2003 April 6 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code used to implement the ATTACH and DETACH commands. +*/ +/* #include "sqliteInt.h" */ + +#ifndef SQLITE_OMIT_ATTACH +/* +** Resolve an expression that was part of an ATTACH or DETACH statement. This +** is slightly different from resolving a normal SQL expression, because simple +** identifiers are treated as strings, not possible column names or aliases. +** +** i.e. if the parser sees: +** +** ATTACH DATABASE abc AS def +** +** it treats the two expressions as literal strings 'abc' and 'def' instead of +** looking for columns of the same name. +** +** This only applies to the root node of pExpr, so the statement: +** +** ATTACH DATABASE abc||def AS 'db2' +** +** will fail because neither abc or def can be resolved. +*/ +static int resolveAttachExpr(NameContext *pName, Expr *pExpr) +{ + int rc = SQLITE_OK; + if( pExpr ){ + if( pExpr->op!=TK_ID ){ + rc = sqlite3ResolveExprNames(pName, pExpr); + }else{ + pExpr->op = TK_STRING; + } + } + return rc; +} + +/* +** Return true if zName points to a name that may be used to refer to +** database iDb attached to handle db. +*/ +SQLITE_PRIVATE int sqlite3DbIsNamed(sqlite3 *db, int iDb, const char *zName){ + return ( + sqlite3StrICmp(db->aDb[iDb].zDbSName, zName)==0 + || (iDb==0 && sqlite3StrICmp("main", zName)==0) + ); +} + +/* +** An SQL user-function registered to do the work of an ATTACH statement. The +** three arguments to the function come directly from an attach statement: +** +** ATTACH DATABASE x AS y KEY z +** +** SELECT sqlite_attach(x, y, z) +** +** If the optional "KEY z" syntax is omitted, an SQL NULL is passed as the +** third argument. +** +** If the db->init.reopenMemdb flags is set, then instead of attaching a +** new database, close the database on db->init.iDb and reopen it as an +** empty MemDB. +*/ +static void attachFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + int i; + int rc = 0; + sqlite3 *db = sqlite3_context_db_handle(context); + const char *zName; + const char *zFile; + char *zPath = 0; + char *zErr = 0; + unsigned int flags; + Db *aNew; /* New array of Db pointers */ + Db *pNew = 0; /* Db object for the newly attached database */ + char *zErrDyn = 0; + sqlite3_vfs *pVfs; + + UNUSED_PARAMETER(NotUsed); + zFile = (const char *)sqlite3_value_text(argv[0]); + zName = (const char *)sqlite3_value_text(argv[1]); + if( zFile==0 ) zFile = ""; + if( zName==0 ) zName = ""; + +#ifndef SQLITE_OMIT_DESERIALIZE +# define REOPEN_AS_MEMDB(db) (db->init.reopenMemdb) +#else +# define REOPEN_AS_MEMDB(db) (0) +#endif + + if( REOPEN_AS_MEMDB(db) ){ + /* This is not a real ATTACH. Instead, this routine is being called + ** from sqlite3_deserialize() to close database db->init.iDb and + ** reopen it as a MemDB */ + Btree *pNewBt = 0; + + pNew = &db->aDb[db->init.iDb]; + assert( pNew->pBt!=0 ); + if( sqlite3BtreeTxnState(pNew->pBt)!=SQLITE_TXN_NONE + || sqlite3BtreeIsInBackup(pNew->pBt) + ){ + rc = SQLITE_BUSY; + goto attach_error; + } + + pVfs = sqlite3_vfs_find("memdb"); + if( pVfs==0 ) return; + rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNewBt, 0, SQLITE_OPEN_MAIN_DB); + if( rc==SQLITE_OK ){ + Schema *pNewSchema = sqlite3SchemaGet(db, pNewBt); + if( pNewSchema ){ + /* Both the Btree and the new Schema were allocated successfully. + ** Close the old db and update the aDb[] slot with the new memdb + ** values. */ + sqlite3BtreeClose(pNew->pBt); + pNew->pBt = pNewBt; + pNew->pSchema = pNewSchema; + }else{ + sqlite3BtreeClose(pNewBt); + rc = SQLITE_NOMEM; + } + } + if( rc ) goto attach_error; + }else{ + /* This is a real ATTACH + ** + ** Check for the following errors: + ** + ** * Too many attached databases, + ** * Transaction currently open + ** * Specified database name already being used. + */ + if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){ + zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d", + db->aLimit[SQLITE_LIMIT_ATTACHED] + ); + goto attach_error; + } + for(i=0; inDb; i++){ + assert( zName ); + if( sqlite3DbIsNamed(db, i, zName) ){ + zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName); + goto attach_error; + } + } + + /* Allocate the new entry in the db->aDb[] array and initialize the schema + ** hash tables. + */ + if( db->aDb==db->aDbStatic ){ + aNew = sqlite3DbMallocRawNN(db, sizeof(db->aDb[0])*3 ); + if( aNew==0 ) return; + memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); + }else{ + aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(1+(i64)db->nDb)); + if( aNew==0 ) return; + } + db->aDb = aNew; + pNew = &db->aDb[db->nDb]; + memset(pNew, 0, sizeof(*pNew)); + + /* Open the database file. If the btree is successfully opened, use + ** it to obtain the database schema. At this point the schema may + ** or may not be initialized. + */ + flags = db->openFlags; + rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); + sqlite3_result_error(context, zErr, -1); + sqlite3_free(zErr); + return; + } + if( (db->flags & SQLITE_AttachWrite)==0 ){ + flags &= ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE); + flags |= SQLITE_OPEN_READONLY; + }else if( (db->flags & SQLITE_AttachCreate)==0 ){ + flags &= ~SQLITE_OPEN_CREATE; + } + assert( pVfs ); + flags |= SQLITE_OPEN_MAIN_DB; + rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags); + db->nDb++; + pNew->zDbSName = sqlite3DbStrDup(db, zName); + } + db->noSharedCache = 0; + if( rc==SQLITE_CONSTRAINT ){ + rc = SQLITE_ERROR; + zErrDyn = sqlite3MPrintf(db, "database is already attached"); + }else if( rc==SQLITE_OK ){ + Pager *pPager; + pNew->pSchema = sqlite3SchemaGet(db, pNew->pBt); + if( !pNew->pSchema ){ + rc = SQLITE_NOMEM_BKPT; + }else if( pNew->pSchema->file_format && pNew->pSchema->enc!=ENC(db) ){ + zErrDyn = sqlite3MPrintf(db, + "attached databases must use the same text encoding as main database"); + rc = SQLITE_ERROR; + } + sqlite3BtreeEnter(pNew->pBt); + pPager = sqlite3BtreePager(pNew->pBt); + sqlite3PagerLockingMode(pPager, db->dfltLockMode); + sqlite3BtreeSecureDelete(pNew->pBt, + sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) ); +#ifndef SQLITE_OMIT_PAGER_PRAGMAS + sqlite3BtreeSetPagerFlags(pNew->pBt, + PAGER_SYNCHRONOUS_FULL | (db->flags & PAGER_FLAGS_MASK)); +#endif + sqlite3BtreeLeave(pNew->pBt); + } + pNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1; + if( rc==SQLITE_OK && pNew->zDbSName==0 ){ + rc = SQLITE_NOMEM_BKPT; + } + sqlite3_free_filename( zPath ); + + /* If the file was opened successfully, read the schema for the new database. + ** If this fails, or if opening the file failed, then close the file and + ** remove the entry from the db->aDb[] array. i.e. put everything back the + ** way we found it. + */ + if( rc==SQLITE_OK ){ + sqlite3BtreeEnterAll(db); + db->init.iDb = 0; + db->mDbFlags &= ~(DBFLAG_SchemaKnownOk); +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + if( db->setlkFlags & SQLITE_SETLK_BLOCK_ON_CONNECT ){ + int val = 1; + sqlite3_file *fd = sqlite3PagerFile(sqlite3BtreePager(pNew->pBt)); + sqlite3OsFileControlHint(fd, SQLITE_FCNTL_BLOCK_ON_CONNECT, &val); + } +#endif + if( !REOPEN_AS_MEMDB(db) ){ + rc = sqlite3Init(db, &zErrDyn); + } + sqlite3BtreeLeaveAll(db); + assert( zErrDyn==0 || rc!=SQLITE_OK ); + } + if( rc ){ + if( ALWAYS(!REOPEN_AS_MEMDB(db)) ){ + int iDb = db->nDb - 1; + assert( iDb>=2 ); + if( db->aDb[iDb].pBt ){ + sqlite3BtreeClose(db->aDb[iDb].pBt); + db->aDb[iDb].pBt = 0; + db->aDb[iDb].pSchema = 0; + } + sqlite3ResetAllSchemasOfConnection(db); + db->nDb = iDb; + if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ + sqlite3OomFault(db); + sqlite3DbFree(db, zErrDyn); + zErrDyn = sqlite3MPrintf(db, "out of memory"); + }else if( zErrDyn==0 ){ + zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile); + } + } + goto attach_error; + } + + return; + +attach_error: + /* Return an error if we get here */ + if( zErrDyn ){ + sqlite3_result_error(context, zErrDyn, -1); + sqlite3DbFree(db, zErrDyn); + } + if( rc ) sqlite3_result_error_code(context, rc); +} + +/* +** An SQL user-function registered to do the work of an DETACH statement. The +** three arguments to the function come directly from a detach statement: +** +** DETACH DATABASE x +** +** SELECT sqlite_detach(x) +*/ +static void detachFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + const char *zName = (const char *)sqlite3_value_text(argv[0]); + sqlite3 *db = sqlite3_context_db_handle(context); + int i; + Db *pDb = 0; + HashElem *pEntry; + char zErr[128]; + + UNUSED_PARAMETER(NotUsed); + + if( zName==0 ) zName = ""; + for(i=0; inDb; i++){ + pDb = &db->aDb[i]; + if( pDb->pBt==0 ) continue; + if( sqlite3DbIsNamed(db, i, zName) ) break; + } + + if( i>=db->nDb ){ + sqlite3_snprintf(sizeof(zErr),zErr, "no such database: %s", zName); + goto detach_error; + } + if( i<2 ){ + sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName); + goto detach_error; + } + if( sqlite3BtreeTxnState(pDb->pBt)!=SQLITE_TXN_NONE + || sqlite3BtreeIsInBackup(pDb->pBt) + ){ + sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName); + goto detach_error; + } + + /* If any TEMP triggers reference the schema being detached, move those + ** triggers to reference the TEMP schema itself. */ + assert( db->aDb[1].pSchema ); + pEntry = sqliteHashFirst(&db->aDb[1].pSchema->trigHash); + while( pEntry ){ + Trigger *pTrig = (Trigger*)sqliteHashData(pEntry); + if( pTrig->pTabSchema==pDb->pSchema ){ + pTrig->pTabSchema = pTrig->pSchema; + } + pEntry = sqliteHashNext(pEntry); + } + + sqlite3BtreeClose(pDb->pBt); + pDb->pBt = 0; + pDb->pSchema = 0; + sqlite3CollapseDatabaseArray(db); + return; + +detach_error: + sqlite3_result_error(context, zErr, -1); +} + +/* +** This procedure generates VDBE code for a single invocation of either the +** sqlite_detach() or sqlite_attach() SQL user functions. +*/ +static void codeAttach( + Parse *pParse, /* The parser context */ + int type, /* Either SQLITE_ATTACH or SQLITE_DETACH */ + FuncDef const *pFunc,/* FuncDef wrapper for detachFunc() or attachFunc() */ + Expr *pAuthArg, /* Expression to pass to authorization callback */ + Expr *pFilename, /* Name of database file */ + Expr *pDbname, /* Name of the database to use internally */ + Expr *pKey /* Database key for encryption extension */ +){ + int rc; + NameContext sName; + Vdbe *v; + sqlite3* db = pParse->db; + int regArgs; + + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto attach_end; + + if( pParse->nErr ) goto attach_end; + memset(&sName, 0, sizeof(NameContext)); + sName.pParse = pParse; + + if( + SQLITE_OK!=resolveAttachExpr(&sName, pFilename) || + SQLITE_OK!=resolveAttachExpr(&sName, pDbname) || + SQLITE_OK!=resolveAttachExpr(&sName, pKey) + ){ + goto attach_end; + } + +#ifndef SQLITE_OMIT_AUTHORIZATION + if( ALWAYS(pAuthArg) ){ + char *zAuthArg; + if( pAuthArg->op==TK_STRING ){ + assert( !ExprHasProperty(pAuthArg, EP_IntValue) ); + zAuthArg = pAuthArg->u.zToken; + }else{ + zAuthArg = 0; + } + rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0); + if(rc!=SQLITE_OK ){ + goto attach_end; + } + } +#endif /* SQLITE_OMIT_AUTHORIZATION */ + + + v = sqlite3GetVdbe(pParse); + regArgs = sqlite3GetTempRange(pParse, 4); + sqlite3ExprCode(pParse, pFilename, regArgs); + sqlite3ExprCode(pParse, pDbname, regArgs+1); + sqlite3ExprCode(pParse, pKey, regArgs+2); + + assert( v || db->mallocFailed ); + if( v ){ + sqlite3VdbeAddFunctionCall(pParse, 0, regArgs+3-pFunc->nArg, regArgs+3, + pFunc->nArg, pFunc, 0); + /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this + ** statement only). For DETACH, set it to false (expire all existing + ** statements). + */ + sqlite3VdbeAddOp1(v, OP_Expire, (type==SQLITE_ATTACH)); + } + +attach_end: + sqlite3ExprDelete(db, pFilename); + sqlite3ExprDelete(db, pDbname); + sqlite3ExprDelete(db, pKey); +} + +/* +** Called by the parser to compile a DETACH statement. +** +** DETACH pDbname +*/ +SQLITE_PRIVATE void sqlite3Detach(Parse *pParse, Expr *pDbname){ + static const FuncDef detach_func = { + 1, /* nArg */ + SQLITE_UTF8, /* funcFlags */ + 0, /* pUserData */ + 0, /* pNext */ + detachFunc, /* xSFunc */ + 0, /* xFinalize */ + 0, 0, /* xValue, xInverse */ + "sqlite_detach", /* zName */ + {0} + }; + codeAttach(pParse, SQLITE_DETACH, &detach_func, pDbname, 0, 0, pDbname); +} + +/* +** Called by the parser to compile an ATTACH statement. +** +** ATTACH p AS pDbname KEY pKey +*/ +SQLITE_PRIVATE void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){ + static const FuncDef attach_func = { + 3, /* nArg */ + SQLITE_UTF8, /* funcFlags */ + 0, /* pUserData */ + 0, /* pNext */ + attachFunc, /* xSFunc */ + 0, /* xFinalize */ + 0, 0, /* xValue, xInverse */ + "sqlite_attach", /* zName */ + {0} + }; + codeAttach(pParse, SQLITE_ATTACH, &attach_func, p, p, pDbname, pKey); +} +#endif /* SQLITE_OMIT_ATTACH */ + +/* +** Expression callback used by sqlite3FixAAAA() routines. +*/ +static int fixExprCb(Walker *p, Expr *pExpr){ + DbFixer *pFix = p->u.pFix; + if( !pFix->bTemp ) ExprSetProperty(pExpr, EP_FromDDL); + if( pExpr->op==TK_VARIABLE ){ + if( pFix->pParse->db->init.busy ){ + pExpr->op = TK_NULL; + }else{ + sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType); + return WRC_Abort; + } + } + return WRC_Continue; +} + +/* +** Select callback used by sqlite3FixAAAA() routines. +*/ +static int fixSelectCb(Walker *p, Select *pSelect){ + DbFixer *pFix = p->u.pFix; + int i; + SrcItem *pItem; + sqlite3 *db = pFix->pParse->db; + int iDb = sqlite3FindDbName(db, pFix->zDb); + SrcList *pList = pSelect->pSrc; + + if( NEVER(pList==0) ) return WRC_Continue; + for(i=0, pItem=pList->a; inSrc; i++, pItem++){ + if( pFix->bTemp==0 && pItem->fg.isSubquery==0 ){ + if( pItem->fg.fixedSchema==0 && pItem->u4.zDatabase!=0 ){ + if( iDb!=sqlite3FindDbName(db, pItem->u4.zDatabase) ){ + sqlite3ErrorMsg(pFix->pParse, + "%s %T cannot reference objects in database %s", + pFix->zType, pFix->pName, pItem->u4.zDatabase); + return WRC_Abort; + } + sqlite3DbFree(db, pItem->u4.zDatabase); + pItem->fg.notCte = 1; + pItem->fg.hadSchema = 1; + } + pItem->u4.pSchema = pFix->pSchema; + pItem->fg.fromDDL = 1; + pItem->fg.fixedSchema = 1; + } +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) + if( pList->a[i].fg.isUsing==0 + && sqlite3WalkExpr(&pFix->w, pList->a[i].u3.pOn) + ){ + return WRC_Abort; + } +#endif + } + if( pSelect->pWith ){ + for(i=0; ipWith->nCte; i++){ + if( sqlite3WalkSelect(p, pSelect->pWith->a[i].pSelect) ){ + return WRC_Abort; + } + } + } + return WRC_Continue; +} + +/* +** Initialize a DbFixer structure. This routine must be called prior +** to passing the structure to one of the sqliteFixAAAA() routines below. +*/ +SQLITE_PRIVATE void sqlite3FixInit( + DbFixer *pFix, /* The fixer to be initialized */ + Parse *pParse, /* Error messages will be written here */ + int iDb, /* This is the database that must be used */ + const char *zType, /* "view", "trigger", or "index" */ + const Token *pName /* Name of the view, trigger, or index */ +){ + sqlite3 *db = pParse->db; + assert( db->nDb>iDb ); + pFix->pParse = pParse; + pFix->zDb = db->aDb[iDb].zDbSName; + pFix->pSchema = db->aDb[iDb].pSchema; + pFix->zType = zType; + pFix->pName = pName; + pFix->bTemp = (iDb==1); + pFix->w.pParse = pParse; + pFix->w.xExprCallback = fixExprCb; + pFix->w.xSelectCallback = fixSelectCb; + pFix->w.xSelectCallback2 = sqlite3WalkWinDefnDummyCallback; + pFix->w.walkerDepth = 0; + pFix->w.eCode = 0; + pFix->w.u.pFix = pFix; +} + +/* +** The following set of routines walk through the parse tree and assign +** a specific database to all table references where the database name +** was left unspecified in the original SQL statement. The pFix structure +** must have been initialized by a prior call to sqlite3FixInit(). +** +** These routines are used to make sure that an index, trigger, or +** view in one database does not refer to objects in a different database. +** (Exception: indices, triggers, and views in the TEMP database are +** allowed to refer to anything.) If a reference is explicitly made +** to an object in a different database, an error message is added to +** pParse->zErrMsg and these routines return non-zero. If everything +** checks out, these routines return 0. +*/ +SQLITE_PRIVATE int sqlite3FixSrcList( + DbFixer *pFix, /* Context of the fixation */ + SrcList *pList /* The Source list to check and modify */ +){ + int res = 0; + if( pList ){ + Select s; + memset(&s, 0, sizeof(s)); + s.pSrc = pList; + res = sqlite3WalkSelect(&pFix->w, &s); + } + return res; +} +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) +SQLITE_PRIVATE int sqlite3FixSelect( + DbFixer *pFix, /* Context of the fixation */ + Select *pSelect /* The SELECT statement to be fixed to one database */ +){ + return sqlite3WalkSelect(&pFix->w, pSelect); +} +SQLITE_PRIVATE int sqlite3FixExpr( + DbFixer *pFix, /* Context of the fixation */ + Expr *pExpr /* The expression to be fixed to one database */ +){ + return sqlite3WalkExpr(&pFix->w, pExpr); +} +#endif + +#ifndef SQLITE_OMIT_TRIGGER +SQLITE_PRIVATE int sqlite3FixTriggerStep( + DbFixer *pFix, /* Context of the fixation */ + TriggerStep *pStep /* The trigger step be fixed to one database */ +){ + while( pStep ){ + if( sqlite3WalkSelect(&pFix->w, pStep->pSelect) + || sqlite3WalkExpr(&pFix->w, pStep->pWhere) + || sqlite3WalkExprList(&pFix->w, pStep->pExprList) + || sqlite3FixSrcList(pFix, pStep->pSrc) + ){ + return 1; + } +#ifndef SQLITE_OMIT_UPSERT + { + Upsert *pUp; + for(pUp=pStep->pUpsert; pUp; pUp=pUp->pNextUpsert){ + if( sqlite3WalkExprList(&pFix->w, pUp->pUpsertTarget) + || sqlite3WalkExpr(&pFix->w, pUp->pUpsertTargetWhere) + || sqlite3WalkExprList(&pFix->w, pUp->pUpsertSet) + || sqlite3WalkExpr(&pFix->w, pUp->pUpsertWhere) + ){ + return 1; + } + } + } +#endif + pStep = pStep->pNext; + } + + return 0; +} +#endif + +/************** End of attach.c **********************************************/ +/************** Begin file auth.c ********************************************/ +/* +** 2003 January 11 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code used to implement the sqlite3_set_authorizer() +** API. This facility is an optional feature of the library. Embedded +** systems that do not need this facility may omit it by recompiling +** the library with -DSQLITE_OMIT_AUTHORIZATION=1 +*/ +/* #include "sqliteInt.h" */ + +/* +** All of the code in this file may be omitted by defining a single +** macro. +*/ +#ifndef SQLITE_OMIT_AUTHORIZATION + +/* +** Set or clear the access authorization function. +** +** The access authorization function is be called during the compilation +** phase to verify that the user has read and/or write access permission on +** various fields of the database. The first argument to the auth function +** is a copy of the 3rd argument to this routine. The second argument +** to the auth function is one of these constants: +** +** SQLITE_CREATE_INDEX +** SQLITE_CREATE_TABLE +** SQLITE_CREATE_TEMP_INDEX +** SQLITE_CREATE_TEMP_TABLE +** SQLITE_CREATE_TEMP_TRIGGER +** SQLITE_CREATE_TEMP_VIEW +** SQLITE_CREATE_TRIGGER +** SQLITE_CREATE_VIEW +** SQLITE_DELETE +** SQLITE_DROP_INDEX +** SQLITE_DROP_TABLE +** SQLITE_DROP_TEMP_INDEX +** SQLITE_DROP_TEMP_TABLE +** SQLITE_DROP_TEMP_TRIGGER +** SQLITE_DROP_TEMP_VIEW +** SQLITE_DROP_TRIGGER +** SQLITE_DROP_VIEW +** SQLITE_INSERT +** SQLITE_PRAGMA +** SQLITE_READ +** SQLITE_SELECT +** SQLITE_TRANSACTION +** SQLITE_UPDATE +** +** The third and fourth arguments to the auth function are the name of +** the table and the column that are being accessed. The auth function +** should return either SQLITE_OK, SQLITE_DENY, or SQLITE_IGNORE. If +** SQLITE_OK is returned, it means that access is allowed. SQLITE_DENY +** means that the SQL statement will never-run - the sqlite3_exec() call +** will return with an error. SQLITE_IGNORE means that the SQL statement +** should run but attempts to read the specified column will return NULL +** and attempts to write the column will be ignored. +** +** Setting the auth function to NULL disables this hook. The default +** setting of the auth function is NULL. +*/ +SQLITE_API int sqlite3_set_authorizer( + sqlite3 *db, + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), + void *pArg +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + db->xAuth = (sqlite3_xauth)xAuth; + db->pAuthArg = pArg; + sqlite3ExpirePreparedStatements(db, 1); + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + +/* +** Write an error message into pParse->zErrMsg that explains that the +** user-supplied authorization function returned an illegal value. +*/ +static void sqliteAuthBadReturnCode(Parse *pParse){ + sqlite3ErrorMsg(pParse, "authorizer malfunction"); + pParse->rc = SQLITE_ERROR; +} + +/* +** Invoke the authorization callback for permission to read column zCol from +** table zTab in database zDb. This function assumes that an authorization +** callback has been registered (i.e. that sqlite3.xAuth is not NULL). +** +** If SQLITE_IGNORE is returned and pExpr is not NULL, then pExpr is changed +** to an SQL NULL expression. Otherwise, if pExpr is NULL, then SQLITE_IGNORE +** is treated as SQLITE_DENY. In this case an error is left in pParse. +*/ +SQLITE_PRIVATE int sqlite3AuthReadCol( + Parse *pParse, /* The parser context */ + const char *zTab, /* Table name */ + const char *zCol, /* Column name */ + int iDb /* Index of containing database. */ +){ + sqlite3 *db = pParse->db; /* Database handle */ + char *zDb = db->aDb[iDb].zDbSName; /* Schema name of attached database */ + int rc; /* Auth callback return code */ + + if( db->init.busy ) return SQLITE_OK; + rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext); + if( rc==SQLITE_DENY ){ + char *z = sqlite3_mprintf("%s.%s", zTab, zCol); + if( db->nDb>2 || iDb!=0 ) z = sqlite3_mprintf("%s.%z", zDb, z); + sqlite3ErrorMsg(pParse, "access to %z is prohibited", z); + pParse->rc = SQLITE_AUTH; + }else if( rc!=SQLITE_IGNORE && rc!=SQLITE_OK ){ + sqliteAuthBadReturnCode(pParse); + } + return rc; +} + +/* +** The pExpr should be a TK_COLUMN expression. The table referred to +** is in pTabList or else it is the NEW or OLD table of a trigger. +** Check to see if it is OK to read this particular column. +** +** If the auth function returns SQLITE_IGNORE, change the TK_COLUMN +** instruction into a TK_NULL. If the auth function returns SQLITE_DENY, +** then generate an error. +*/ +SQLITE_PRIVATE void sqlite3AuthRead( + Parse *pParse, /* The parser context */ + Expr *pExpr, /* The expression to check authorization on */ + Schema *pSchema, /* The schema of the expression */ + SrcList *pTabList /* All table that pExpr might refer to */ +){ + Table *pTab = 0; /* The table being read */ + const char *zCol; /* Name of the column of the table */ + int iSrc; /* Index in pTabList->a[] of table being read */ + int iDb; /* The index of the database the expression refers to */ + int iCol; /* Index of column in table */ + + assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER ); + assert( !IN_RENAME_OBJECT ); + assert( pParse->db->xAuth!=0 ); + iDb = sqlite3SchemaToIndex(pParse->db, pSchema); + if( iDb<0 ){ + /* An attempt to read a column out of a subquery or other + ** temporary table. */ + return; + } + + if( pExpr->op==TK_TRIGGER ){ + pTab = pParse->pTriggerTab; + }else{ + assert( pTabList ); + for(iSrc=0; iSrcnSrc; iSrc++){ + if( pExpr->iTable==pTabList->a[iSrc].iCursor ){ + pTab = pTabList->a[iSrc].pSTab; + break; + } + } + } + iCol = pExpr->iColumn; + if( pTab==0 ) return; + + if( iCol>=0 ){ + assert( iColnCol ); + zCol = pTab->aCol[iCol].zCnName; + }else if( pTab->iPKey>=0 ){ + assert( pTab->iPKeynCol ); + zCol = pTab->aCol[pTab->iPKey].zCnName; + }else{ + zCol = "ROWID"; + } + assert( iDb>=0 && iDbdb->nDb ); + if( SQLITE_IGNORE==sqlite3AuthReadCol(pParse, pTab->zName, zCol, iDb) ){ + pExpr->op = TK_NULL; + } +} + +/* +** Do an authorization check using the code and arguments given. Return +** either SQLITE_OK (zero) or SQLITE_IGNORE or SQLITE_DENY. If SQLITE_DENY +** is returned, then the error count and error message in pParse are +** modified appropriately. +*/ +SQLITE_PRIVATE int sqlite3AuthCheck( + Parse *pParse, + int code, + const char *zArg1, + const char *zArg2, + const char *zArg3 +){ + sqlite3 *db = pParse->db; + int rc; + + /* Don't do any authorization checks if the database is initializing + ** or if the parser is being invoked from within sqlite3_declare_vtab. + */ + assert( !IN_RENAME_OBJECT || db->xAuth==0 ); + if( db->xAuth==0 || db->init.busy || IN_SPECIAL_PARSE ){ + return SQLITE_OK; + } + + /* EVIDENCE-OF: R-43249-19882 The third through sixth parameters to the + ** callback are either NULL pointers or zero-terminated strings that + ** contain additional details about the action to be authorized. + ** + ** The following testcase() macros show that any of the 3rd through 6th + ** parameters can be either NULL or a string. */ + testcase( zArg1==0 ); + testcase( zArg2==0 ); + testcase( zArg3==0 ); + testcase( pParse->zAuthContext==0 ); + + rc = db->xAuth(db->pAuthArg,code,zArg1,zArg2,zArg3,pParse->zAuthContext); + if( rc==SQLITE_DENY ){ + sqlite3ErrorMsg(pParse, "not authorized"); + pParse->rc = SQLITE_AUTH; + }else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){ + rc = SQLITE_DENY; + sqliteAuthBadReturnCode(pParse); + } + return rc; +} + +/* +** Push an authorization context. After this routine is called, the +** zArg3 argument to authorization callbacks will be zContext until +** popped. Or if pParse==0, this routine is a no-op. +*/ +SQLITE_PRIVATE void sqlite3AuthContextPush( + Parse *pParse, + AuthContext *pContext, + const char *zContext +){ + assert( pParse ); + pContext->pParse = pParse; + pContext->zAuthContext = pParse->zAuthContext; + pParse->zAuthContext = zContext; +} + +/* +** Pop an authorization context that was previously pushed +** by sqlite3AuthContextPush +*/ +SQLITE_PRIVATE void sqlite3AuthContextPop(AuthContext *pContext){ + if( pContext->pParse ){ + pContext->pParse->zAuthContext = pContext->zAuthContext; + pContext->pParse = 0; + } +} + +#endif /* SQLITE_OMIT_AUTHORIZATION */ + +/************** End of auth.c ************************************************/ +/************** Begin file build.c *******************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains C code routines that are called by the SQLite parser +** when syntax rules are reduced. The routines in this file handle the +** following kinds of SQL syntax: +** +** CREATE TABLE +** DROP TABLE +** CREATE INDEX +** DROP INDEX +** creating ID lists +** BEGIN TRANSACTION +** COMMIT +** ROLLBACK +*/ +/* #include "sqliteInt.h" */ + +#ifndef SQLITE_OMIT_SHARED_CACHE +/* +** The TableLock structure is only used by the sqlite3TableLock() and +** codeTableLocks() functions. +*/ +struct TableLock { + int iDb; /* The database containing the table to be locked */ + Pgno iTab; /* The root page of the table to be locked */ + u8 isWriteLock; /* True for write lock. False for a read lock */ + const char *zLockName; /* Name of the table */ +}; + +/* +** Record the fact that we want to lock a table at run-time. +** +** The table to be locked has root page iTab and is found in database iDb. +** A read or a write lock can be taken depending on isWritelock. +** +** This routine just records the fact that the lock is desired. The +** code to make the lock occur is generated by a later call to +** codeTableLocks() which occurs during sqlite3FinishCoding(). +*/ +static SQLITE_NOINLINE void lockTable( + Parse *pParse, /* Parsing context */ + int iDb, /* Index of the database containing the table to lock */ + Pgno iTab, /* Root page number of the table to be locked */ + u8 isWriteLock, /* True for a write lock */ + const char *zName /* Name of the table to be locked */ +){ + Parse *pToplevel; + int i; + int nBytes; + TableLock *p; + assert( iDb>=0 ); + + pToplevel = sqlite3ParseToplevel(pParse); + for(i=0; inTableLock; i++){ + p = &pToplevel->aTableLock[i]; + if( p->iDb==iDb && p->iTab==iTab ){ + p->isWriteLock = (p->isWriteLock || isWriteLock); + return; + } + } + + assert( pToplevel->nTableLock < 0x7fff0000 ); + nBytes = sizeof(TableLock) * (pToplevel->nTableLock+1); + pToplevel->aTableLock = + sqlite3DbReallocOrFree(pToplevel->db, pToplevel->aTableLock, nBytes); + if( pToplevel->aTableLock ){ + p = &pToplevel->aTableLock[pToplevel->nTableLock++]; + p->iDb = iDb; + p->iTab = iTab; + p->isWriteLock = isWriteLock; + p->zLockName = zName; + }else{ + pToplevel->nTableLock = 0; + sqlite3OomFault(pToplevel->db); + } +} +SQLITE_PRIVATE void sqlite3TableLock( + Parse *pParse, /* Parsing context */ + int iDb, /* Index of the database containing the table to lock */ + Pgno iTab, /* Root page number of the table to be locked */ + u8 isWriteLock, /* True for a write lock */ + const char *zName /* Name of the table to be locked */ +){ + if( iDb==1 ) return; + if( !sqlite3BtreeSharable(pParse->db->aDb[iDb].pBt) ) return; + lockTable(pParse, iDb, iTab, isWriteLock, zName); +} + +/* +** Code an OP_TableLock instruction for each table locked by the +** statement (configured by calls to sqlite3TableLock()). +*/ +static void codeTableLocks(Parse *pParse){ + int i; + Vdbe *pVdbe = pParse->pVdbe; + assert( pVdbe!=0 ); + + for(i=0; inTableLock; i++){ + TableLock *p = &pParse->aTableLock[i]; + int p1 = p->iDb; + sqlite3VdbeAddOp4(pVdbe, OP_TableLock, p1, p->iTab, p->isWriteLock, + p->zLockName, P4_STATIC); + } +} +#else + #define codeTableLocks(x) +#endif + +/* +** Return TRUE if the given yDbMask object is empty - if it contains no +** 1 bits. This routine is used by the DbMaskAllZero() and DbMaskNotZero() +** macros when SQLITE_MAX_ATTACHED is greater than 30. +*/ +#if SQLITE_MAX_ATTACHED>30 +SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask m){ + int i; + for(i=0; ipToplevel==0 ); + db = pParse->db; + assert( db->pParse==pParse ); + if( pParse->nested ) return; + if( pParse->nErr ){ + if( db->mallocFailed ) pParse->rc = SQLITE_NOMEM; + return; + } + assert( db->mallocFailed==0 ); + + /* Begin by generating some termination code at the end of the + ** vdbe program + */ + v = pParse->pVdbe; + if( v==0 ){ + if( db->init.busy ){ + pParse->rc = SQLITE_DONE; + return; + } + v = sqlite3GetVdbe(pParse); + if( v==0 ) pParse->rc = SQLITE_ERROR; + } + assert( !pParse->isMultiWrite + || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort)); + if( v ){ + if( pParse->bReturning ){ + Returning *pReturning; + int addrRewind; + int reg; + + assert( !pParse->isCreate ); + pReturning = pParse->u1.d.pReturning; + if( pReturning->nRetCol ){ + sqlite3VdbeAddOp0(v, OP_FkCheck); + addrRewind = + sqlite3VdbeAddOp1(v, OP_Rewind, pReturning->iRetCur); + VdbeCoverage(v); + reg = pReturning->iRetReg; + for(i=0; inRetCol; i++){ + sqlite3VdbeAddOp3(v, OP_Column, pReturning->iRetCur, i, reg+i); + } + sqlite3VdbeAddOp2(v, OP_ResultRow, reg, i); + sqlite3VdbeAddOp2(v, OP_Next, pReturning->iRetCur, addrRewind+1); + VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addrRewind); + } + } + sqlite3VdbeAddOp0(v, OP_Halt); + + /* The cookie mask contains one bit for each database file open. + ** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are + ** set for each database that is used. Generate code to start a + ** transaction on each used database and to verify the schema cookie + ** on each used database. + */ + assert( pParse->nErr>0 || sqlite3VdbeGetOp(v, 0)->opcode==OP_Init ); + sqlite3VdbeJumpHere(v, 0); + assert( db->nDb>0 ); + iDb = 0; + do{ + Schema *pSchema; + if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue; + sqlite3VdbeUsesBtree(v, iDb); + pSchema = db->aDb[iDb].pSchema; + sqlite3VdbeAddOp4Int(v, + OP_Transaction, /* Opcode */ + iDb, /* P1 */ + DbMaskTest(pParse->writeMask,iDb), /* P2 */ + pSchema->schema_cookie, /* P3 */ + pSchema->iGeneration /* P4 */ + ); + if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1); + VdbeComment((v, + "usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite)); + }while( ++iDbnDb ); +#ifndef SQLITE_OMIT_VIRTUALTABLE + for(i=0; inVtabLock; i++){ + char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]); + sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB); + } + pParse->nVtabLock = 0; +#endif + +#ifndef SQLITE_OMIT_SHARED_CACHE + /* Once all the cookies have been verified and transactions opened, + ** obtain the required table-locks. This is a no-op unless the + ** shared-cache feature is enabled. + */ + if( pParse->nTableLock ) codeTableLocks(pParse); +#endif + + /* Initialize any AUTOINCREMENT data structures required. + */ + if( pParse->pAinc ) sqlite3AutoincrementBegin(pParse); + + /* Code constant expressions that were factored out of inner loops. + */ + if( pParse->pConstExpr ){ + ExprList *pEL = pParse->pConstExpr; + pParse->okConstFactor = 0; + for(i=0; inExpr; i++){ + assert( pEL->a[i].u.iConstExprReg>0 ); + sqlite3ExprCode(pParse, pEL->a[i].pExpr, pEL->a[i].u.iConstExprReg); + } + } + + if( pParse->bReturning ){ + Returning *pRet; + assert( !pParse->isCreate ); + pRet = pParse->u1.d.pReturning; + if( pRet->nRetCol ){ + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRet->iRetCur, pRet->nRetCol); + } + } + + /* Finally, jump back to the beginning of the executable code. */ + sqlite3VdbeGoto(v, 1); + } + + /* Get the VDBE program ready for execution + */ + assert( v!=0 || pParse->nErr ); + assert( db->mallocFailed==0 || pParse->nErr ); + if( pParse->nErr==0 ){ + /* A minimum of one cursor is required if autoincrement is used + * See ticket [a696379c1f08866] */ + assert( pParse->pAinc==0 || pParse->nTab>0 ); + sqlite3VdbeMakeReady(v, pParse); + pParse->rc = SQLITE_DONE; + }else{ + pParse->rc = SQLITE_ERROR; + } +} + +/* +** Run the parser and code generator recursively in order to generate +** code for the SQL statement given onto the end of the pParse context +** currently under construction. Notes: +** +** * The final OP_Halt is not appended and other initialization +** and finalization steps are omitted because those are handling by the +** outermost parser. +** +** * Built-in SQL functions always take precedence over application-defined +** SQL functions. In other words, it is not possible to override a +** built-in function. +*/ +SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ + va_list ap; + char *zSql; + sqlite3 *db = pParse->db; + u32 savedDbFlags = db->mDbFlags; + char saveBuf[PARSE_TAIL_SZ]; + + if( pParse->nErr ) return; + if( pParse->eParseMode ) return; + assert( pParse->nested<10 ); /* Nesting should only be of limited depth */ + va_start(ap, zFormat); + zSql = sqlite3VMPrintf(db, zFormat, ap); + va_end(ap); + if( zSql==0 ){ + /* This can result either from an OOM or because the formatted string + ** exceeds SQLITE_LIMIT_LENGTH. In the latter case, we need to set + ** an error */ + if( !db->mallocFailed ) pParse->rc = SQLITE_TOOBIG; + pParse->nErr++; + return; + } + pParse->nested++; + memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ); + memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ); + db->mDbFlags |= DBFLAG_PreferBuiltin; + sqlite3RunParser(pParse, zSql); + db->mDbFlags = savedDbFlags; + sqlite3DbFree(db, zSql); + memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ); + pParse->nested--; +} + +/* +** Locate the in-memory structure that describes a particular database +** table given the name of that table and (optionally) the name of the +** database containing the table. Return NULL if not found. +** +** If zDatabase is 0, all databases are searched for the table and the +** first matching table is returned. (No checking for duplicate table +** names is done.) The search order is TEMP first, then MAIN, then any +** auxiliary databases added using the ATTACH command. +** +** See also sqlite3LocateTable(). +*/ +SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){ + Table *p = 0; + int i; + + /* All mutexes are required for schema access. Make sure we hold them. */ + assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) ); + if( zDatabase ){ + for(i=0; inDb; i++){ + if( sqlite3StrICmp(zDatabase, db->aDb[i].zDbSName)==0 ) break; + } + if( i>=db->nDb ){ + /* No match against the official names. But always match "main" + ** to schema 0 as a legacy fallback. */ + if( sqlite3StrICmp(zDatabase,"main")==0 ){ + i = 0; + }else{ + return 0; + } + } + p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName); + if( p==0 && sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){ + if( i==1 ){ + if( sqlite3StrICmp(zName+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0 + || sqlite3StrICmp(zName+7, &PREFERRED_SCHEMA_TABLE[7])==0 + || sqlite3StrICmp(zName+7, &LEGACY_SCHEMA_TABLE[7])==0 + ){ + p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash, + LEGACY_TEMP_SCHEMA_TABLE); + } + }else{ + if( sqlite3StrICmp(zName+7, &PREFERRED_SCHEMA_TABLE[7])==0 ){ + p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, + LEGACY_SCHEMA_TABLE); + } + } + } + }else{ + /* Match against TEMP first */ + p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash, zName); + if( p ) return p; + /* The main database is second */ + p = sqlite3HashFind(&db->aDb[0].pSchema->tblHash, zName); + if( p ) return p; + /* Attached databases are in order of attachment */ + for(i=2; inDb; i++){ + assert( sqlite3SchemaMutexHeld(db, i, 0) ); + p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName); + if( p ) break; + } + if( p==0 && sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){ + if( sqlite3StrICmp(zName+7, &PREFERRED_SCHEMA_TABLE[7])==0 ){ + p = sqlite3HashFind(&db->aDb[0].pSchema->tblHash, LEGACY_SCHEMA_TABLE); + }else if( sqlite3StrICmp(zName+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0 ){ + p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash, + LEGACY_TEMP_SCHEMA_TABLE); + } + } + } + return p; +} + +/* +** Locate the in-memory structure that describes a particular database +** table given the name of that table and (optionally) the name of the +** database containing the table. Return NULL if not found. Also leave an +** error message in pParse->zErrMsg. +** +** The difference between this routine and sqlite3FindTable() is that this +** routine leaves an error message in pParse->zErrMsg where +** sqlite3FindTable() does not. +*/ +SQLITE_PRIVATE Table *sqlite3LocateTable( + Parse *pParse, /* context in which to report errors */ + u32 flags, /* LOCATE_VIEW or LOCATE_NOERR */ + const char *zName, /* Name of the table we are looking for */ + const char *zDbase /* Name of the database. Might be NULL */ +){ + Table *p; + sqlite3 *db = pParse->db; + + /* Read the database schema. If an error occurs, leave an error message + ** and code in pParse and return NULL. */ + if( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 + && SQLITE_OK!=sqlite3ReadSchema(pParse) + ){ + return 0; + } + + p = sqlite3FindTable(db, zName, zDbase); + if( p==0 ){ +#ifndef SQLITE_OMIT_VIRTUALTABLE + /* If zName is the not the name of a table in the schema created using + ** CREATE, then check to see if it is the name of an virtual table that + ** can be an eponymous virtual table. */ + if( (pParse->prepFlags & SQLITE_PREPARE_NO_VTAB)==0 && db->init.busy==0 ){ + Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName); + if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){ + pMod = sqlite3PragmaVtabRegister(db, zName); + } +#ifndef SQLITE_OMIT_JSON + if( pMod==0 && sqlite3_strnicmp(zName, "json", 4)==0 ){ + pMod = sqlite3JsonVtabRegister(db, zName); + } +#endif +#ifdef SQLITE_ENABLE_CARRAY + if( pMod==0 && sqlite3_stricmp(zName, "carray")==0 ){ + pMod = sqlite3CarrayRegister(db); + } +#endif + if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){ + testcase( pMod->pEpoTab==0 ); + return pMod->pEpoTab; + } + } +#endif + if( flags & LOCATE_NOERR ) return 0; + pParse->checkSchema = 1; + }else if( IsVirtual(p) && (pParse->prepFlags & SQLITE_PREPARE_NO_VTAB)!=0 ){ + p = 0; + } + + if( p==0 ){ + const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table"; + if( zDbase ){ + sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName); + }else{ + sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName); + } + }else{ + assert( HasRowid(p) || p->iPKey<0 ); + } + + return p; +} + +/* +** Locate the table identified by *p. +** +** This is a wrapper around sqlite3LocateTable(). The difference between +** sqlite3LocateTable() and this function is that this function restricts +** the search to schema (p->pSchema) if it is not NULL. p->pSchema may be +** non-NULL if it is part of a view or trigger program definition. See +** sqlite3FixSrcList() for details. +*/ +SQLITE_PRIVATE Table *sqlite3LocateTableItem( + Parse *pParse, + u32 flags, + SrcItem *p +){ + const char *zDb; + if( p->fg.fixedSchema ){ + int iDb = sqlite3SchemaToIndex(pParse->db, p->u4.pSchema); + assert( iDb>=0 && iDbdb->nDb ); + zDb = pParse->db->aDb[iDb].zDbSName; + }else{ + assert( !p->fg.isSubquery ); + zDb = p->u4.zDatabase; + } + return sqlite3LocateTable(pParse, flags, p->zName, zDb); +} + +/* +** Return the preferred table name for system tables. Translate legacy +** names into the new preferred names, as appropriate. +*/ +SQLITE_PRIVATE const char *sqlite3PreferredTableName(const char *zName){ + if( sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){ + if( sqlite3StrICmp(zName+7, &LEGACY_SCHEMA_TABLE[7])==0 ){ + return PREFERRED_SCHEMA_TABLE; + } + if( sqlite3StrICmp(zName+7, &LEGACY_TEMP_SCHEMA_TABLE[7])==0 ){ + return PREFERRED_TEMP_SCHEMA_TABLE; + } + } + return zName; +} + +/* +** Locate the in-memory structure that describes +** a particular index given the name of that index +** and the name of the database that contains the index. +** Return NULL if not found. +** +** If zDatabase is 0, all databases are searched for the +** table and the first matching index is returned. (No checking +** for duplicate index names is done.) The search order is +** TEMP first, then MAIN, then any auxiliary databases added +** using the ATTACH command. +*/ +SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){ + Index *p = 0; + int i; + /* All mutexes are required for schema access. Make sure we hold them. */ + assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) ); + for(i=OMIT_TEMPDB; inDb; i++){ + int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ + Schema *pSchema = db->aDb[j].pSchema; + assert( pSchema ); + if( zDb && sqlite3DbIsNamed(db, j, zDb)==0 ) continue; + assert( sqlite3SchemaMutexHeld(db, j, 0) ); + p = sqlite3HashFind(&pSchema->idxHash, zName); + if( p ) break; + } + return p; +} + +/* +** Reclaim the memory used by an index +*/ +SQLITE_PRIVATE void sqlite3FreeIndex(sqlite3 *db, Index *p){ +#ifndef SQLITE_OMIT_ANALYZE + sqlite3DeleteIndexSamples(db, p); +#endif + sqlite3ExprDelete(db, p->pPartIdxWhere); + sqlite3ExprListDelete(db, p->aColExpr); + sqlite3DbFree(db, p->zColAff); + if( p->isResized ) sqlite3DbFree(db, (void *)p->azColl); +#ifdef SQLITE_ENABLE_STAT4 + sqlite3_free(p->aiRowEst); +#endif + sqlite3DbFree(db, p); +} + +/* +** For the index called zIdxName which is found in the database iDb, +** unlike that index from its Table then remove the index from +** the index hash table and free all memory structures associated +** with the index. +*/ +SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){ + Index *pIndex; + Hash *pHash; + + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + pHash = &db->aDb[iDb].pSchema->idxHash; + pIndex = sqlite3HashInsert(pHash, zIdxName, 0); + if( ALWAYS(pIndex) ){ + if( pIndex->pTable->pIndex==pIndex ){ + pIndex->pTable->pIndex = pIndex->pNext; + }else{ + Index *p; + /* Justification of ALWAYS(); The index must be on the list of + ** indices. */ + p = pIndex->pTable->pIndex; + while( ALWAYS(p) && p->pNext!=pIndex ){ p = p->pNext; } + if( ALWAYS(p && p->pNext==pIndex) ){ + p->pNext = pIndex->pNext; + } + } + sqlite3FreeIndex(db, pIndex); + } + db->mDbFlags |= DBFLAG_SchemaChange; +} + +/* +** Look through the list of open database files in db->aDb[] and if +** any have been closed, remove them from the list. Reallocate the +** db->aDb[] structure to a smaller size, if possible. +** +** Entry 0 (the "main" database) and entry 1 (the "temp" database) +** are never candidates for being collapsed. +*/ +SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3 *db){ + int i, j; + for(i=j=2; inDb; i++){ + struct Db *pDb = &db->aDb[i]; + if( pDb->pBt==0 ){ + sqlite3DbFree(db, pDb->zDbSName); + pDb->zDbSName = 0; + continue; + } + if( jaDb[j] = db->aDb[i]; + } + j++; + } + db->nDb = j; + if( db->nDb<=2 && db->aDb!=db->aDbStatic ){ + memcpy(db->aDbStatic, db->aDb, 2*sizeof(db->aDb[0])); + sqlite3DbFree(db, db->aDb); + db->aDb = db->aDbStatic; + } +} + +/* +** Reset the schema for the database at index iDb. Also reset the +** TEMP schema. The reset is deferred if db->nSchemaLock is not zero. +** Deferred resets may be run by calling with iDb<0. +*/ +SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3 *db, int iDb){ + int i; + assert( iDbnDb ); + + if( iDb>=0 ){ + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + DbSetProperty(db, iDb, DB_ResetWanted); + DbSetProperty(db, 1, DB_ResetWanted); + db->mDbFlags &= ~DBFLAG_SchemaKnownOk; + } + + if( db->nSchemaLock==0 ){ + for(i=0; inDb; i++){ + if( DbHasProperty(db, i, DB_ResetWanted) ){ + sqlite3SchemaClear(db->aDb[i].pSchema); + } + } + } +} + +/* +** Erase all schema information from all attached databases (including +** "main" and "temp") for a single database connection. +*/ +SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){ + int i; + sqlite3BtreeEnterAll(db); + for(i=0; inDb; i++){ + Db *pDb = &db->aDb[i]; + if( pDb->pSchema ){ + if( db->nSchemaLock==0 ){ + sqlite3SchemaClear(pDb->pSchema); + }else{ + DbSetProperty(db, i, DB_ResetWanted); + } + } + } + db->mDbFlags &= ~(DBFLAG_SchemaChange|DBFLAG_SchemaKnownOk); + sqlite3VtabUnlockList(db); + sqlite3BtreeLeaveAll(db); + if( db->nSchemaLock==0 ){ + sqlite3CollapseDatabaseArray(db); + } +} + +/* +** This routine is called when a commit occurs. +*/ +SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3 *db){ + db->mDbFlags &= ~DBFLAG_SchemaChange; +} + +/* +** Set the expression associated with a column. This is usually +** the DEFAULT value, but might also be the expression that computes +** the value for a generated column. +*/ +SQLITE_PRIVATE void sqlite3ColumnSetExpr( + Parse *pParse, /* Parsing context */ + Table *pTab, /* The table containing the column */ + Column *pCol, /* The column to receive the new DEFAULT expression */ + Expr *pExpr /* The new default expression */ +){ + ExprList *pList; + assert( IsOrdinaryTable(pTab) ); + pList = pTab->u.tab.pDfltList; + if( pCol->iDflt==0 + || NEVER(pList==0) + || NEVER(pList->nExpriDflt) + ){ + pCol->iDflt = pList==0 ? 1 : pList->nExpr+1; + pTab->u.tab.pDfltList = sqlite3ExprListAppend(pParse, pList, pExpr); + }else{ + sqlite3ExprDelete(pParse->db, pList->a[pCol->iDflt-1].pExpr); + pList->a[pCol->iDflt-1].pExpr = pExpr; + } +} + +/* +** Return the expression associated with a column. The expression might be +** the DEFAULT clause or the AS clause of a generated column. +** Return NULL if the column has no associated expression. +*/ +SQLITE_PRIVATE Expr *sqlite3ColumnExpr(Table *pTab, Column *pCol){ + if( pCol->iDflt==0 ) return 0; + if( !IsOrdinaryTable(pTab) ) return 0; + if( NEVER(pTab->u.tab.pDfltList==0) ) return 0; + if( NEVER(pTab->u.tab.pDfltList->nExpriDflt) ) return 0; + return pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr; +} + +/* +** Set the collating sequence name for a column. +*/ +SQLITE_PRIVATE void sqlite3ColumnSetColl( + sqlite3 *db, + Column *pCol, + const char *zColl +){ + i64 nColl; + i64 n; + char *zNew; + assert( zColl!=0 ); + n = sqlite3Strlen30(pCol->zCnName) + 1; + if( pCol->colFlags & COLFLAG_HASTYPE ){ + n += sqlite3Strlen30(pCol->zCnName+n) + 1; + } + nColl = sqlite3Strlen30(zColl) + 1; + zNew = sqlite3DbRealloc(db, pCol->zCnName, nColl+n); + if( zNew ){ + pCol->zCnName = zNew; + memcpy(pCol->zCnName + n, zColl, nColl); + pCol->colFlags |= COLFLAG_HASCOLL; + } +} + +/* +** Return the collating sequence name for a column +*/ +SQLITE_PRIVATE const char *sqlite3ColumnColl(Column *pCol){ + const char *z; + if( (pCol->colFlags & COLFLAG_HASCOLL)==0 ) return 0; + z = pCol->zCnName; + while( *z ){ z++; } + if( pCol->colFlags & COLFLAG_HASTYPE ){ + do{ z++; }while( *z ); + } + return z+1; +} + +/* +** Delete memory allocated for the column names of a table or view (the +** Table.aCol[] array). +*/ +SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){ + int i; + Column *pCol; + assert( pTable!=0 ); + assert( db!=0 ); + if( (pCol = pTable->aCol)!=0 ){ + for(i=0; inCol; i++, pCol++){ + assert( pCol->zCnName==0 || pCol->hName==sqlite3StrIHash(pCol->zCnName) ); + sqlite3DbFree(db, pCol->zCnName); + } + sqlite3DbNNFreeNN(db, pTable->aCol); + if( IsOrdinaryTable(pTable) ){ + sqlite3ExprListDelete(db, pTable->u.tab.pDfltList); + } + if( db->pnBytesFreed==0 ){ + pTable->aCol = 0; + pTable->nCol = 0; + if( IsOrdinaryTable(pTable) ){ + pTable->u.tab.pDfltList = 0; + } + } + } +} + +/* +** Remove the memory data structures associated with the given +** Table. No changes are made to disk by this routine. +** +** This routine just deletes the data structure. It does not unlink +** the table data structure from the hash table. But it does destroy +** memory structures of the indices and foreign keys associated with +** the table. +** +** The db parameter is optional. It is needed if the Table object +** contains lookaside memory. (Table objects in the schema do not use +** lookaside memory, but some ephemeral Table objects do.) Or the +** db parameter can be used with db->pnBytesFreed to measure the memory +** used by the Table object. +*/ +static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){ + Index *pIndex, *pNext; + +#ifdef SQLITE_DEBUG + /* Record the number of outstanding lookaside allocations in schema Tables + ** prior to doing any free() operations. Since schema Tables do not use + ** lookaside, this number should not change. + ** + ** If malloc has already failed, it may be that it failed while allocating + ** a Table object that was going to be marked ephemeral. So do not check + ** that no lookaside memory is used in this case either. */ + int nLookaside = 0; + assert( db!=0 ); + if( !db->mallocFailed && (pTable->tabFlags & TF_Ephemeral)==0 ){ + nLookaside = sqlite3LookasideUsed(db, 0); + } +#endif + + /* Delete all indices associated with this table. */ + for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){ + pNext = pIndex->pNext; + assert( pIndex->pSchema==pTable->pSchema + || (IsVirtual(pTable) && pIndex->idxType!=SQLITE_IDXTYPE_APPDEF) ); + if( db->pnBytesFreed==0 && !IsVirtual(pTable) ){ + char *zName = pIndex->zName; + TESTONLY ( Index *pOld = ) sqlite3HashInsert( + &pIndex->pSchema->idxHash, zName, 0 + ); + assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); + assert( pOld==pIndex || pOld==0 ); + } + sqlite3FreeIndex(db, pIndex); + } + + if( IsOrdinaryTable(pTable) ){ + sqlite3FkDelete(db, pTable); + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + else if( IsVirtual(pTable) ){ + sqlite3VtabClear(db, pTable); + } +#endif + else{ + assert( IsView(pTable) ); + sqlite3SelectDelete(db, pTable->u.view.pSelect); + } + + /* Delete the Table structure itself. + */ + sqlite3DeleteColumnNames(db, pTable); + sqlite3DbFree(db, pTable->zName); + sqlite3DbFree(db, pTable->zColAff); + sqlite3ExprListDelete(db, pTable->pCheck); + sqlite3DbFree(db, pTable); + + /* Verify that no lookaside memory was used by schema tables */ + assert( nLookaside==0 || nLookaside==sqlite3LookasideUsed(db,0) ); +} +SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ + /* Do not delete the table until the reference count reaches zero. */ + assert( db!=0 ); + if( !pTable ) return; + if( db->pnBytesFreed==0 && (--pTable->nTabRef)>0 ) return; + deleteTable(db, pTable); +} +SQLITE_PRIVATE void sqlite3DeleteTableGeneric(sqlite3 *db, void *pTable){ + sqlite3DeleteTable(db, (Table*)pTable); +} + + +/* +** Unlink the given table from the hash tables and the delete the +** table structure with all its indices and foreign keys. +*/ +SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){ + Table *p; + Db *pDb; + + assert( db!=0 ); + assert( iDb>=0 && iDbnDb ); + assert( zTabName ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + testcase( zTabName[0]==0 ); /* Zero-length table names are allowed */ + pDb = &db->aDb[iDb]; + p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName, 0); + sqlite3DeleteTable(db, p); + db->mDbFlags |= DBFLAG_SchemaChange; +} + +/* +** Given a token, return a string that consists of the text of that +** token. Space to hold the returned string +** is obtained from sqliteMalloc() and must be freed by the calling +** function. +** +** Any quotation marks (ex: "name", 'name', [name], or `name`) that +** surround the body of the token are removed. +** +** Tokens are often just pointers into the original SQL text and so +** are not \000 terminated and are not persistent. The returned string +** is \000 terminated and is persistent. +*/ +SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3 *db, const Token *pName){ + char *zName; + if( pName ){ + zName = sqlite3DbStrNDup(db, (const char*)pName->z, pName->n); + sqlite3Dequote(zName); + }else{ + zName = 0; + } + return zName; +} + +/* +** Open the sqlite_schema table stored in database number iDb for +** writing. The table is opened using cursor 0. +*/ +SQLITE_PRIVATE void sqlite3OpenSchemaTable(Parse *p, int iDb){ + Vdbe *v = sqlite3GetVdbe(p); + sqlite3TableLock(p, iDb, SCHEMA_ROOT, 1, LEGACY_SCHEMA_TABLE); + sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, SCHEMA_ROOT, iDb, 5); + if( p->nTab==0 ){ + p->nTab = 1; + } +} + +/* +** Parameter zName points to a nul-terminated buffer containing the name +** of a database ("main", "temp" or the name of an attached db). This +** function returns the index of the named database in db->aDb[], or +** -1 if the named db cannot be found. +*/ +SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *db, const char *zName){ + int i = -1; /* Database number */ + if( zName ){ + Db *pDb; + for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){ + if( 0==sqlite3_stricmp(pDb->zDbSName, zName) ) break; + /* "main" is always an acceptable alias for the primary database + ** even if it has been renamed using SQLITE_DBCONFIG_MAINDBNAME. */ + if( i==0 && 0==sqlite3_stricmp("main", zName) ) break; + } + } + return i; +} + +/* +** The token *pName contains the name of a database (either "main" or +** "temp" or the name of an attached db). This routine returns the +** index of the named database in db->aDb[], or -1 if the named db +** does not exist. +*/ +SQLITE_PRIVATE int sqlite3FindDb(sqlite3 *db, Token *pName){ + int i; /* Database number */ + char *zName; /* Name we are searching for */ + zName = sqlite3NameFromToken(db, pName); + i = sqlite3FindDbName(db, zName); + sqlite3DbFree(db, zName); + return i; +} + +/* The table or view or trigger name is passed to this routine via tokens +** pName1 and pName2. If the table name was fully qualified, for example: +** +** CREATE TABLE xxx.yyy (...); +** +** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if +** the table name is not fully qualified, i.e.: +** +** CREATE TABLE yyy(...); +** +** Then pName1 is set to "yyy" and pName2 is "". +** +** This routine sets the *ppUnqual pointer to point at the token (pName1 or +** pName2) that stores the unqualified table name. The index of the +** database "xxx" is returned. +*/ +SQLITE_PRIVATE int sqlite3TwoPartName( + Parse *pParse, /* Parsing and code generating context */ + Token *pName1, /* The "xxx" in the name "xxx.yyy" or "xxx" */ + Token *pName2, /* The "yyy" in the name "xxx.yyy" */ + Token **pUnqual /* Write the unqualified object name here */ +){ + int iDb; /* Database holding the object */ + sqlite3 *db = pParse->db; + + assert( pName2!=0 ); + if( pName2->n>0 ){ + if( db->init.busy ) { + sqlite3ErrorMsg(pParse, "corrupt database"); + return -1; + } + *pUnqual = pName2; + iDb = sqlite3FindDb(db, pName1); + if( iDb<0 ){ + sqlite3ErrorMsg(pParse, "unknown database %T", pName1); + return -1; + } + }else{ + assert( db->init.iDb==0 || db->init.busy || IN_SPECIAL_PARSE + || (db->mDbFlags & DBFLAG_Vacuum)!=0); + iDb = db->init.iDb; + *pUnqual = pName1; + } + return iDb; +} + +/* +** True if PRAGMA writable_schema is ON +*/ +SQLITE_PRIVATE int sqlite3WritableSchema(sqlite3 *db){ + testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==0 ); + testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))== + SQLITE_WriteSchema ); + testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))== + SQLITE_Defensive ); + testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))== + (SQLITE_WriteSchema|SQLITE_Defensive) ); + return (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==SQLITE_WriteSchema; +} + +/* +** This routine is used to check if the UTF-8 string zName is a legal +** unqualified name for a new schema object (table, index, view or +** trigger). All names are legal except those that begin with the string +** "sqlite_" (in upper, lower or mixed case). This portion of the namespace +** is reserved for internal use. +** +** When parsing the sqlite_schema table, this routine also checks to +** make sure the "type", "name", and "tbl_name" columns are consistent +** with the SQL. +*/ +SQLITE_PRIVATE int sqlite3CheckObjectName( + Parse *pParse, /* Parsing context */ + const char *zName, /* Name of the object to check */ + const char *zType, /* Type of this object */ + const char *zTblName /* Parent table name for triggers and indexes */ +){ + sqlite3 *db = pParse->db; + if( sqlite3WritableSchema(db) + || db->init.imposterTable + || !sqlite3Config.bExtraSchemaChecks + ){ + /* Skip these error checks for writable_schema=ON */ + return SQLITE_OK; + } + if( db->init.busy ){ + if( sqlite3_stricmp(zType, db->init.azInit[0]) + || sqlite3_stricmp(zName, db->init.azInit[1]) + || sqlite3_stricmp(zTblName, db->init.azInit[2]) + ){ + sqlite3ErrorMsg(pParse, ""); /* corruptSchema() will supply the error */ + return SQLITE_ERROR; + } + }else{ + if( (pParse->nested==0 && 0==sqlite3StrNICmp(zName, "sqlite_", 7)) + || (sqlite3ReadOnlyShadowTables(db) && sqlite3ShadowTableName(db, zName)) + ){ + sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", + zName); + return SQLITE_ERROR; + } + + } + return SQLITE_OK; +} + +/* +** Return the PRIMARY KEY index of a table +*/ +SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table *pTab){ + Index *p; + for(p=pTab->pIndex; p && !IsPrimaryKeyIndex(p); p=p->pNext){} + return p; +} + +/* +** Convert an table column number into a index column number. That is, +** for the column iCol in the table (as defined by the CREATE TABLE statement) +** find the (first) offset of that column in index pIdx. Or return -1 +** if column iCol is not used in index pIdx. +*/ +SQLITE_PRIVATE int sqlite3TableColumnToIndex(Index *pIdx, int iCol){ + int i; + i16 iCol16; + assert( iCol>=(-1) && iCol<=SQLITE_MAX_COLUMN ); + assert( pIdx->nColumn<=SQLITE_MAX_COLUMN*2 ); + iCol16 = iCol; + for(i=0; inColumn; i++){ + if( iCol16==pIdx->aiColumn[i] ){ + return i; + } + } + return -1; +} + +#ifndef SQLITE_OMIT_GENERATED_COLUMNS +/* Convert a storage column number into a table column number. +** +** The storage column number (0,1,2,....) is the index of the value +** as it appears in the record on disk. The true column number +** is the index (0,1,2,...) of the column in the CREATE TABLE statement. +** +** The storage column number is less than the table column number if +** and only there are VIRTUAL columns to the left. +** +** If SQLITE_OMIT_GENERATED_COLUMNS, this routine is a no-op macro. +*/ +SQLITE_PRIVATE i16 sqlite3StorageColumnToTable(Table *pTab, i16 iCol){ + if( pTab->tabFlags & TF_HasVirtual ){ + int i; + for(i=0; i<=iCol; i++){ + if( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ) iCol++; + } + } + return iCol; +} +#endif + +#ifndef SQLITE_OMIT_GENERATED_COLUMNS +/* Convert a table column number into a storage column number. +** +** The storage column number (0,1,2,....) is the index of the value +** as it appears in the record on disk. Or, if the input column is +** the N-th virtual column (zero-based) then the storage number is +** the number of non-virtual columns in the table plus N. +** +** The true column number is the index (0,1,2,...) of the column in +** the CREATE TABLE statement. +** +** If the input column is a VIRTUAL column, then it should not appear +** in storage. But the value sometimes is cached in registers that +** follow the range of registers used to construct storage. This +** avoids computing the same VIRTUAL column multiple times, and provides +** values for use by OP_Param opcodes in triggers. Hence, if the +** input column is a VIRTUAL table, put it after all the other columns. +** +** In the following, N means "normal column", S means STORED, and +** V means VIRTUAL. Suppose the CREATE TABLE has columns like this: +** +** CREATE TABLE ex(N,S,V,N,S,V,N,S,V); +** -- 0 1 2 3 4 5 6 7 8 +** +** Then the mapping from this function is as follows: +** +** INPUTS: 0 1 2 3 4 5 6 7 8 +** OUTPUTS: 0 1 6 2 3 7 4 5 8 +** +** So, in other words, this routine shifts all the virtual columns to +** the end. +** +** If SQLITE_OMIT_GENERATED_COLUMNS then there are no virtual columns and +** this routine is a no-op macro. If the pTab does not have any virtual +** columns, then this routine is no-op that always return iCol. If iCol +** is negative (indicating the ROWID column) then this routine return iCol. +*/ +SQLITE_PRIVATE i16 sqlite3TableColumnToStorage(Table *pTab, i16 iCol){ + int i; + i16 n; + assert( iColnCol ); + if( (pTab->tabFlags & TF_HasVirtual)==0 || iCol<0 ) return iCol; + for(i=0, n=0; iaCol[i].colFlags & COLFLAG_VIRTUAL)==0 ) n++; + } + if( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ){ + /* iCol is a virtual column itself */ + return pTab->nNVCol + i - n; + }else{ + /* iCol is a normal or stored column */ + return n; + } +} +#endif + +/* +** Insert a single OP_JournalMode query opcode in order to force the +** prepared statement to return false for sqlite3_stmt_readonly(). This +** is used by CREATE TABLE IF NOT EXISTS and similar if the table already +** exists, so that the prepared statement for CREATE TABLE IF NOT EXISTS +** will return false for sqlite3_stmt_readonly() even if that statement +** is a read-only no-op. +*/ +static void sqlite3ForceNotReadOnly(Parse *pParse){ + int iReg = ++pParse->nMem; + Vdbe *v = sqlite3GetVdbe(pParse); + if( v ){ + sqlite3VdbeAddOp3(v, OP_JournalMode, 0, iReg, PAGER_JOURNALMODE_QUERY); + sqlite3VdbeUsesBtree(v, 0); + } +} + +/* +** Begin constructing a new table representation in memory. This is +** the first of several action routines that get called in response +** to a CREATE TABLE statement. In particular, this routine is called +** after seeing tokens "CREATE" and "TABLE" and the table name. The isTemp +** flag is true if the table should be stored in the auxiliary database +** file instead of in the main database file. This is normally the case +** when the "TEMP" or "TEMPORARY" keyword occurs in between +** CREATE and TABLE. +** +** The new table record is initialized and put in pParse->pNewTable. +** As more of the CREATE TABLE statement is parsed, additional action +** routines will be called to add more information to this record. +** At the end of the CREATE TABLE statement, the sqlite3EndTable() routine +** is called to complete the construction of the new table record. +*/ +SQLITE_PRIVATE void sqlite3StartTable( + Parse *pParse, /* Parser context */ + Token *pName1, /* First part of the name of the table or view */ + Token *pName2, /* Second part of the name of the table or view */ + int isTemp, /* True if this is a TEMP table */ + int isView, /* True if this is a VIEW */ + int isVirtual, /* True if this is a VIRTUAL table */ + int noErr /* Do nothing if table already exists */ +){ + Table *pTable; + char *zName = 0; /* The name of the new table */ + sqlite3 *db = pParse->db; + Vdbe *v; + int iDb; /* Database number to create the table in */ + Token *pName; /* Unqualified name of the table to create */ + + if( db->init.busy && db->init.newTnum==1 ){ + /* Special case: Parsing the sqlite_schema or sqlite_temp_schema schema */ + iDb = db->init.iDb; + zName = sqlite3DbStrDup(db, SCHEMA_TABLE(iDb)); + pName = pName1; + }else{ + /* The common case */ + iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName); + if( iDb<0 ) return; + if( !OMIT_TEMPDB && isTemp && pName2->n>0 && iDb!=1 ){ + /* If creating a temp table, the name may not be qualified. Unless + ** the database name is "temp" anyway. */ + sqlite3ErrorMsg(pParse, "temporary table name must be unqualified"); + return; + } + if( !OMIT_TEMPDB && isTemp ) iDb = 1; + zName = sqlite3NameFromToken(db, pName); + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenMap(pParse, (void*)zName, pName); + } + } + pParse->sNameToken = *pName; + if( zName==0 ) return; + if( sqlite3CheckObjectName(pParse, zName, isView?"view":"table", zName) ){ + goto begin_table_error; + } + if( db->init.iDb==1 ) isTemp = 1; +#ifndef SQLITE_OMIT_AUTHORIZATION + assert( isTemp==0 || isTemp==1 ); + assert( isView==0 || isView==1 ); + { + static const u8 aCode[] = { + SQLITE_CREATE_TABLE, + SQLITE_CREATE_TEMP_TABLE, + SQLITE_CREATE_VIEW, + SQLITE_CREATE_TEMP_VIEW + }; + char *zDb = db->aDb[iDb].zDbSName; + if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){ + goto begin_table_error; + } + if( !isVirtual && sqlite3AuthCheck(pParse, (int)aCode[isTemp+2*isView], + zName, 0, zDb) ){ + goto begin_table_error; + } + } +#endif + + /* Make sure the new table name does not collide with an existing + ** index or table name in the same database. Issue an error message if + ** it does. The exception is if the statement being parsed was passed + ** to an sqlite3_declare_vtab() call. In that case only the column names + ** and types will be used, so there is no need to test for namespace + ** collisions. + */ + if( !IN_SPECIAL_PARSE ){ + char *zDb = db->aDb[iDb].zDbSName; + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + goto begin_table_error; + } + pTable = sqlite3FindTable(db, zName, zDb); + if( pTable ){ + if( !noErr ){ + sqlite3ErrorMsg(pParse, "%s %T already exists", + (IsView(pTable)? "view" : "table"), pName); + }else{ + assert( !db->init.busy || CORRUPT_DB ); + sqlite3CodeVerifySchema(pParse, iDb); + sqlite3ForceNotReadOnly(pParse); + } + goto begin_table_error; + } + if( sqlite3FindIndex(db, zName, zDb)!=0 ){ + sqlite3ErrorMsg(pParse, "there is already an index named %s", zName); + goto begin_table_error; + } + } + + pTable = sqlite3DbMallocZero(db, sizeof(Table)); + if( pTable==0 ){ + assert( db->mallocFailed ); + pParse->rc = SQLITE_NOMEM_BKPT; + pParse->nErr++; + goto begin_table_error; + } + pTable->zName = zName; + pTable->iPKey = -1; + pTable->pSchema = db->aDb[iDb].pSchema; + pTable->nTabRef = 1; +#ifdef SQLITE_DEFAULT_ROWEST + pTable->nRowLogEst = sqlite3LogEst(SQLITE_DEFAULT_ROWEST); +#else + pTable->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); +#endif + assert( pParse->pNewTable==0 ); + pParse->pNewTable = pTable; + + /* Begin generating the code that will insert the table record into + ** the schema table. Note in particular that we must go ahead + ** and allocate the record number for the table entry now. Before any + ** PRIMARY KEY or UNIQUE keywords are parsed. Those keywords will cause + ** indices to be created and the table record must come before the + ** indices. Hence, the record number for the table must be allocated + ** now. + */ + if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){ + int addr1; + int fileFormat; + int reg1, reg2, reg3; + /* nullRow[] is an OP_Record encoding of a row containing 5 NULLs */ + static const char nullRow[] = { 6, 0, 0, 0, 0, 0 }; + sqlite3BeginWriteOperation(pParse, 1, iDb); + +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( isVirtual ){ + sqlite3VdbeAddOp0(v, OP_VBegin); + } +#endif + + /* If the file format and encoding in the database have not been set, + ** set them now. + */ + assert( pParse->isCreate ); + reg1 = pParse->u1.cr.regRowid = ++pParse->nMem; + reg2 = pParse->u1.cr.regRoot = ++pParse->nMem; + reg3 = ++pParse->nMem; + sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, BTREE_FILE_FORMAT); + sqlite3VdbeUsesBtree(v, iDb); + addr1 = sqlite3VdbeAddOp1(v, OP_If, reg3); VdbeCoverage(v); + fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ? + 1 : SQLITE_MAX_FILE_FORMAT; + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, fileFormat); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_TEXT_ENCODING, ENC(db)); + sqlite3VdbeJumpHere(v, addr1); + + /* This just creates a place-holder record in the sqlite_schema table. + ** The record created does not contain anything yet. It will be replaced + ** by the real entry in code generated at sqlite3EndTable(). + ** + ** The rowid for the new entry is left in register pParse->u1.cr.regRowid. + ** The root page of the new table is left in reg pParse->u1.cr.regRoot. + ** The rowid and root page number values are needed by the code that + ** sqlite3EndTable will generate. + */ +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) + if( isView || isVirtual ){ + sqlite3VdbeAddOp2(v, OP_Integer, 0, reg2); + }else +#endif + { + assert( !pParse->bReturning ); + pParse->u1.cr.addrCrTab = + sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, reg2, BTREE_INTKEY); + } + sqlite3OpenSchemaTable(pParse, iDb); + sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1); + sqlite3VdbeAddOp4(v, OP_Blob, 6, reg3, 0, nullRow, P4_STATIC); + sqlite3VdbeAddOp3(v, OP_Insert, 0, reg3, reg1); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + sqlite3VdbeAddOp0(v, OP_Close); + }else if( db->init.imposterTable ){ + pTable->tabFlags |= TF_Imposter; + if( db->init.imposterTable>=2 ) pTable->tabFlags |= TF_Readonly; + } + + /* Normal (non-error) return. */ + return; + + /* If an error occurs, we jump here */ +begin_table_error: + pParse->checkSchema = 1; + sqlite3DbFree(db, zName); + return; +} + +/* Set properties of a table column based on the (magical) +** name of the column. +*/ +#if SQLITE_ENABLE_HIDDEN_COLUMNS +SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){ + if( sqlite3_strnicmp(pCol->zCnName, "__hidden__", 10)==0 ){ + pCol->colFlags |= COLFLAG_HIDDEN; + if( pTab ) pTab->tabFlags |= TF_HasHidden; + }else if( pTab && pCol!=pTab->aCol && (pCol[-1].colFlags & COLFLAG_HIDDEN) ){ + pTab->tabFlags |= TF_OOOHidden; + } +} +#endif + +/* +** Clean up the data structures associated with the RETURNING clause. +*/ +static void sqlite3DeleteReturning(sqlite3 *db, void *pArg){ + Returning *pRet = (Returning*)pArg; + Hash *pHash; + pHash = &(db->aDb[1].pSchema->trigHash); + sqlite3HashInsert(pHash, pRet->zName, 0); + sqlite3ExprListDelete(db, pRet->pReturnEL); + sqlite3DbFree(db, pRet); +} + +/* +** Add the RETURNING clause to the parse currently underway. +** +** This routine creates a special TEMP trigger that will fire for each row +** of the DML statement. That TEMP trigger contains a single SELECT +** statement with a result set that is the argument of the RETURNING clause. +** The trigger has the Trigger.bReturning flag and an opcode of +** TK_RETURNING instead of TK_SELECT, so that the trigger code generator +** knows to handle it specially. The TEMP trigger is automatically +** removed at the end of the parse. +** +** When this routine is called, we do not yet know if the RETURNING clause +** is attached to a DELETE, INSERT, or UPDATE, so construct it as a +** RETURNING trigger instead. It will then be converted into the appropriate +** type on the first call to sqlite3TriggersExist(). +*/ +SQLITE_PRIVATE void sqlite3AddReturning(Parse *pParse, ExprList *pList){ + Returning *pRet; + Hash *pHash; + sqlite3 *db = pParse->db; + if( pParse->pNewTrigger ){ + sqlite3ErrorMsg(pParse, "cannot use RETURNING in a trigger"); + }else{ + assert( pParse->bReturning==0 || pParse->ifNotExists ); + } + pParse->bReturning = 1; + pRet = sqlite3DbMallocZero(db, sizeof(*pRet)); + if( pRet==0 ){ + sqlite3ExprListDelete(db, pList); + return; + } + assert( !pParse->isCreate ); + pParse->u1.d.pReturning = pRet; + pRet->pParse = pParse; + pRet->pReturnEL = pList; + sqlite3ParserAddCleanup(pParse, sqlite3DeleteReturning, pRet); + testcase( pParse->earlyCleanup ); + if( db->mallocFailed ) return; + sqlite3_snprintf(sizeof(pRet->zName), pRet->zName, + "sqlite_returning_%p", pParse); + pRet->retTrig.zName = pRet->zName; + pRet->retTrig.op = TK_RETURNING; + pRet->retTrig.tr_tm = TRIGGER_AFTER; + pRet->retTrig.bReturning = 1; + pRet->retTrig.pSchema = db->aDb[1].pSchema; + pRet->retTrig.pTabSchema = db->aDb[1].pSchema; + pRet->retTrig.step_list = &pRet->retTStep; + pRet->retTStep.op = TK_RETURNING; + pRet->retTStep.pTrig = &pRet->retTrig; + pRet->retTStep.pExprList = pList; + pHash = &(db->aDb[1].pSchema->trigHash); + assert( sqlite3HashFind(pHash, pRet->zName)==0 + || pParse->nErr || pParse->ifNotExists ); + if( sqlite3HashInsert(pHash, pRet->zName, &pRet->retTrig) + ==&pRet->retTrig ){ + sqlite3OomFault(db); + } +} + +/* +** Add a new column to the table currently being constructed. +** +** The parser calls this routine once for each column declaration +** in a CREATE TABLE statement. sqlite3StartTable() gets called +** first to get things going. Then this routine is called for each +** column. +*/ +SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){ + Table *p; + int i; + char *z; + char *zType; + Column *pCol; + sqlite3 *db = pParse->db; + Column *aNew; + u8 eType = COLTYPE_CUSTOM; + u8 szEst = 1; + char affinity = SQLITE_AFF_BLOB; + + if( (p = pParse->pNewTable)==0 ) return; + if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){ + sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName); + return; + } + if( !IN_RENAME_OBJECT ) sqlite3DequoteToken(&sName); + + /* Because keywords GENERATE ALWAYS can be converted into identifiers + ** by the parser, we can sometimes end up with a typename that ends + ** with "generated always". Check for this case and omit the surplus + ** text. */ + if( sType.n>=16 + && sqlite3_strnicmp(sType.z+(sType.n-6),"always",6)==0 + ){ + sType.n -= 6; + while( ALWAYS(sType.n>0) && sqlite3Isspace(sType.z[sType.n-1]) ) sType.n--; + if( sType.n>=9 + && sqlite3_strnicmp(sType.z+(sType.n-9),"generated",9)==0 + ){ + sType.n -= 9; + while( sType.n>0 && sqlite3Isspace(sType.z[sType.n-1]) ) sType.n--; + } + } + + /* Check for standard typenames. For standard typenames we will + ** set the Column.eType field rather than storing the typename after + ** the column name, in order to save space. */ + if( sType.n>=3 ){ + sqlite3DequoteToken(&sType); + for(i=0; i0) ); + if( z==0 ) return; + if( IN_RENAME_OBJECT ) sqlite3RenameTokenMap(pParse, (void*)z, &sName); + memcpy(z, sName.z, sName.n); + z[sName.n] = 0; + sqlite3Dequote(z); + if( p->nCol && sqlite3ColumnIndex(p, z)>=0 ){ + sqlite3ErrorMsg(pParse, "duplicate column name: %s", z); + sqlite3DbFree(db, z); + return; + } + aNew = sqlite3DbRealloc(db,p->aCol,((i64)p->nCol+1)*sizeof(p->aCol[0])); + if( aNew==0 ){ + sqlite3DbFree(db, z); + return; + } + p->aCol = aNew; + pCol = &p->aCol[p->nCol]; + memset(pCol, 0, sizeof(p->aCol[0])); + pCol->zCnName = z; + pCol->hName = sqlite3StrIHash(z); + sqlite3ColumnPropertiesFromName(p, pCol); + + if( sType.n==0 ){ + /* If there is no type specified, columns have the default affinity + ** 'BLOB' with a default size of 4 bytes. */ + pCol->affinity = affinity; + pCol->eCType = eType; + pCol->szEst = szEst; +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + if( affinity==SQLITE_AFF_BLOB ){ + if( 4>=sqlite3GlobalConfig.szSorterRef ){ + pCol->colFlags |= COLFLAG_SORTERREF; + } + } +#endif + }else{ + zType = z + sqlite3Strlen30(z) + 1; + memcpy(zType, sType.z, sType.n); + zType[sType.n] = 0; + sqlite3Dequote(zType); + pCol->affinity = sqlite3AffinityType(zType, pCol); + pCol->colFlags |= COLFLAG_HASTYPE; + } + if( p->nCol<=0xff ){ + u8 h = pCol->hName % sizeof(p->aHx); + p->aHx[h] = p->nCol; + } + p->nCol++; + p->nNVCol++; + assert( pParse->isCreate ); + pParse->u1.cr.constraintName.n = 0; +} + +/* +** This routine is called by the parser while in the middle of +** parsing a CREATE TABLE statement. A "NOT NULL" constraint has +** been seen on a column. This routine sets the notNull flag on +** the column currently under construction. +*/ +SQLITE_PRIVATE void sqlite3AddNotNull(Parse *pParse, int onError){ + Table *p; + Column *pCol; + p = pParse->pNewTable; + if( p==0 || NEVER(p->nCol<1) ) return; + pCol = &p->aCol[p->nCol-1]; + pCol->notNull = (u8)onError; + p->tabFlags |= TF_HasNotNull; + + /* Set the uniqNotNull flag on any UNIQUE or PK indexes already created + ** on this column. */ + if( pCol->colFlags & COLFLAG_UNIQUE ){ + Index *pIdx; + for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){ + assert( pIdx->nKeyCol==1 && pIdx->onError!=OE_None ); + if( pIdx->aiColumn[0]==p->nCol-1 ){ + pIdx->uniqNotNull = 1; + } + } + } +} + +/* +** Scan the column type name zType (length nType) and return the +** associated affinity type. +** +** This routine does a case-independent search of zType for the +** substrings in the following table. If one of the substrings is +** found, the corresponding affinity is returned. If zType contains +** more than one of the substrings, entries toward the top of +** the table take priority. For example, if zType is 'BLOBINT', +** SQLITE_AFF_INTEGER is returned. +** +** Substring | Affinity +** -------------------------------- +** 'INT' | SQLITE_AFF_INTEGER +** 'CHAR' | SQLITE_AFF_TEXT +** 'CLOB' | SQLITE_AFF_TEXT +** 'TEXT' | SQLITE_AFF_TEXT +** 'BLOB' | SQLITE_AFF_BLOB +** 'REAL' | SQLITE_AFF_REAL +** 'FLOA' | SQLITE_AFF_REAL +** 'DOUB' | SQLITE_AFF_REAL +** +** If none of the substrings in the above table are found, +** SQLITE_AFF_NUMERIC is returned. +*/ +SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn, Column *pCol){ + u32 h = 0; + char aff = SQLITE_AFF_NUMERIC; + const char *zChar = 0; + + assert( zIn!=0 ); + while( zIn[0] ){ + u8 x = *(u8*)zIn; + h = (h<<8) + sqlite3UpperToLower[x]; + zIn++; + if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){ /* CHAR */ + aff = SQLITE_AFF_TEXT; + zChar = zIn; + }else if( h==(('c'<<24)+('l'<<16)+('o'<<8)+'b') ){ /* CLOB */ + aff = SQLITE_AFF_TEXT; + }else if( h==(('t'<<24)+('e'<<16)+('x'<<8)+'t') ){ /* TEXT */ + aff = SQLITE_AFF_TEXT; + }else if( h==(('b'<<24)+('l'<<16)+('o'<<8)+'b') /* BLOB */ + && (aff==SQLITE_AFF_NUMERIC || aff==SQLITE_AFF_REAL) ){ + aff = SQLITE_AFF_BLOB; + if( zIn[0]=='(' ) zChar = zIn; +#ifndef SQLITE_OMIT_FLOATING_POINT + }else if( h==(('r'<<24)+('e'<<16)+('a'<<8)+'l') /* REAL */ + && aff==SQLITE_AFF_NUMERIC ){ + aff = SQLITE_AFF_REAL; + }else if( h==(('f'<<24)+('l'<<16)+('o'<<8)+'a') /* FLOA */ + && aff==SQLITE_AFF_NUMERIC ){ + aff = SQLITE_AFF_REAL; + }else if( h==(('d'<<24)+('o'<<16)+('u'<<8)+'b') /* DOUB */ + && aff==SQLITE_AFF_NUMERIC ){ + aff = SQLITE_AFF_REAL; +#endif + }else if( (h&0x00FFFFFF)==(('i'<<16)+('n'<<8)+'t') ){ /* INT */ + aff = SQLITE_AFF_INTEGER; + break; + } + } + + /* If pCol is not NULL, store an estimate of the field size. The + ** estimate is scaled so that the size of an integer is 1. */ + if( pCol ){ + int v = 0; /* default size is approx 4 bytes */ + if( aff r=(k/4+1) */ + sqlite3GetInt32(zChar, &v); + break; + } + zChar++; + } + }else{ + v = 16; /* BLOB, TEXT, CLOB -> r=5 (approx 20 bytes)*/ + } + } +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + if( v>=sqlite3GlobalConfig.szSorterRef ){ + pCol->colFlags |= COLFLAG_SORTERREF; + } +#endif + v = v/4 + 1; + if( v>255 ) v = 255; + pCol->szEst = v; + } + return aff; +} + +/* +** The expression is the default value for the most recently added column +** of the table currently under construction. +** +** Default value expressions must be constant. Raise an exception if this +** is not the case. +** +** This routine is called by the parser while in the middle of +** parsing a CREATE TABLE statement. +*/ +SQLITE_PRIVATE void sqlite3AddDefaultValue( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* The parsed expression of the default value */ + const char *zStart, /* Start of the default value text */ + const char *zEnd /* First character past end of default value text */ +){ + Table *p; + Column *pCol; + sqlite3 *db = pParse->db; + p = pParse->pNewTable; + if( p!=0 ){ + int isInit = db->init.busy && db->init.iDb!=1; + pCol = &(p->aCol[p->nCol-1]); + if( !sqlite3ExprIsConstantOrFunction(pExpr, isInit) ){ + sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant", + pCol->zCnName); +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + }else if( pCol->colFlags & COLFLAG_GENERATED ){ + testcase( pCol->colFlags & COLFLAG_VIRTUAL ); + testcase( pCol->colFlags & COLFLAG_STORED ); + sqlite3ErrorMsg(pParse, "cannot use DEFAULT on a generated column"); +#endif + }else{ + /* A copy of pExpr is used instead of the original, as pExpr contains + ** tokens that point to volatile memory. + */ + Expr x, *pDfltExpr; + memset(&x, 0, sizeof(x)); + x.op = TK_SPAN; + x.u.zToken = sqlite3DbSpanDup(db, zStart, zEnd); + x.pLeft = pExpr; + x.flags = EP_Skip; + pDfltExpr = sqlite3ExprDup(db, &x, EXPRDUP_REDUCE); + sqlite3DbFree(db, x.u.zToken); + sqlite3ColumnSetExpr(pParse, p, pCol, pDfltExpr); + } + } + if( IN_RENAME_OBJECT ){ + sqlite3RenameExprUnmap(pParse, pExpr); + } + sqlite3ExprDelete(db, pExpr); +} + +/* +** Backwards Compatibility Hack: +** +** Historical versions of SQLite accepted strings as column names in +** indexes and PRIMARY KEY constraints and in UNIQUE constraints. Example: +** +** CREATE TABLE xyz(a,b,c,d,e,PRIMARY KEY('a'),UNIQUE('b','c' COLLATE trim) +** CREATE INDEX abc ON xyz('c','d' DESC,'e' COLLATE nocase DESC); +** +** This is goofy. But to preserve backwards compatibility we continue to +** accept it. This routine does the necessary conversion. It converts +** the expression given in its argument from a TK_STRING into a TK_ID +** if the expression is just a TK_STRING with an optional COLLATE clause. +** If the expression is anything other than TK_STRING, the expression is +** unchanged. +*/ +static void sqlite3StringToId(Expr *p){ + if( p->op==TK_STRING ){ + p->op = TK_ID; + }else if( p->op==TK_COLLATE && p->pLeft->op==TK_STRING ){ + p->pLeft->op = TK_ID; + } +} + +/* +** Tag the given column as being part of the PRIMARY KEY +*/ +static void makeColumnPartOfPrimaryKey(Parse *pParse, Column *pCol){ + pCol->colFlags |= COLFLAG_PRIMKEY; +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + if( pCol->colFlags & COLFLAG_GENERATED ){ + testcase( pCol->colFlags & COLFLAG_VIRTUAL ); + testcase( pCol->colFlags & COLFLAG_STORED ); + sqlite3ErrorMsg(pParse, + "generated columns cannot be part of the PRIMARY KEY"); + } +#endif +} + +/* +** Designate the PRIMARY KEY for the table. pList is a list of names +** of columns that form the primary key. If pList is NULL, then the +** most recently added column of the table is the primary key. +** +** A table can have at most one primary key. If the table already has +** a primary key (and this is the second primary key) then create an +** error. +** +** If the PRIMARY KEY is on a single column whose datatype is INTEGER, +** then we will try to use that column as the rowid. Set the Table.iPKey +** field of the table under construction to be the index of the +** INTEGER PRIMARY KEY column. Table.iPKey is set to -1 if there is +** no INTEGER PRIMARY KEY. +** +** If the key is not an INTEGER PRIMARY KEY, then create a unique +** index for the key. No index is created for INTEGER PRIMARY KEYs. +*/ +SQLITE_PRIVATE void sqlite3AddPrimaryKey( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* List of field names to be indexed */ + int onError, /* What to do with a uniqueness conflict */ + int autoInc, /* True if the AUTOINCREMENT keyword is present */ + int sortOrder /* SQLITE_SO_ASC or SQLITE_SO_DESC */ +){ + Table *pTab = pParse->pNewTable; + Column *pCol = 0; + int iCol = -1, i; + int nTerm; + if( pTab==0 ) goto primary_key_exit; + if( pTab->tabFlags & TF_HasPrimaryKey ){ + sqlite3ErrorMsg(pParse, + "table \"%s\" has more than one primary key", pTab->zName); + goto primary_key_exit; + } + pTab->tabFlags |= TF_HasPrimaryKey; + if( pList==0 ){ + iCol = pTab->nCol - 1; + pCol = &pTab->aCol[iCol]; + makeColumnPartOfPrimaryKey(pParse, pCol); + nTerm = 1; + }else{ + nTerm = pList->nExpr; + for(i=0; ia[i].pExpr); + assert( pCExpr!=0 ); + sqlite3StringToId(pCExpr); + if( pCExpr->op==TK_ID ){ + assert( !ExprHasProperty(pCExpr, EP_IntValue) ); + iCol = sqlite3ColumnIndex(pTab, pCExpr->u.zToken); + if( iCol>=0 ){ + pCol = &pTab->aCol[iCol]; + makeColumnPartOfPrimaryKey(pParse, pCol); + } + } + } + } + if( nTerm==1 + && pCol + && pCol->eCType==COLTYPE_INTEGER + && sortOrder!=SQLITE_SO_DESC + ){ + if( IN_RENAME_OBJECT && pList ){ + Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[0].pExpr); + sqlite3RenameTokenRemap(pParse, &pTab->iPKey, pCExpr); + } + pTab->iPKey = iCol; + pTab->keyConf = (u8)onError; + assert( autoInc==0 || autoInc==1 ); + pTab->tabFlags |= autoInc*TF_Autoincrement; + if( pList ) pParse->iPkSortOrder = pList->a[0].fg.sortFlags; + (void)sqlite3HasExplicitNulls(pParse, pList); + }else if( autoInc ){ +#ifndef SQLITE_OMIT_AUTOINCREMENT + sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an " + "INTEGER PRIMARY KEY"); +#endif + }else{ + sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, + 0, sortOrder, 0, SQLITE_IDXTYPE_PRIMARYKEY); + pList = 0; + } + +primary_key_exit: + sqlite3ExprListDelete(pParse->db, pList); + return; +} + +/* +** Add a new CHECK constraint to the table currently under construction. +*/ +SQLITE_PRIVATE void sqlite3AddCheckConstraint( + Parse *pParse, /* Parsing context */ + Expr *pCheckExpr, /* The check expression */ + const char *zStart, /* Opening "(" */ + const char *zEnd /* Closing ")" */ +){ +#ifndef SQLITE_OMIT_CHECK + Table *pTab = pParse->pNewTable; + sqlite3 *db = pParse->db; + if( pTab && !IN_DECLARE_VTAB + && !sqlite3BtreeIsReadonly(db->aDb[db->init.iDb].pBt) + ){ + pTab->pCheck = sqlite3ExprListAppend(pParse, pTab->pCheck, pCheckExpr); + assert( pParse->isCreate ); + if( pParse->u1.cr.constraintName.n ){ + sqlite3ExprListSetName(pParse, pTab->pCheck, + &pParse->u1.cr.constraintName, 1); + }else{ + Token t; + for(zStart++; sqlite3Isspace(zStart[0]); zStart++){} + while( sqlite3Isspace(zEnd[-1]) ){ zEnd--; } + t.z = zStart; + t.n = (int)(zEnd - t.z); + sqlite3ExprListSetName(pParse, pTab->pCheck, &t, 1); + } + }else +#endif + { + sqlite3ExprDelete(pParse->db, pCheckExpr); + } +} + +/* +** Set the collation function of the most recently parsed table column +** to the CollSeq given. +*/ +SQLITE_PRIVATE void sqlite3AddCollateType(Parse *pParse, Token *pToken){ + Table *p; + int i; + char *zColl; /* Dequoted name of collation sequence */ + sqlite3 *db; + + if( (p = pParse->pNewTable)==0 || IN_RENAME_OBJECT ) return; + i = p->nCol-1; + db = pParse->db; + zColl = sqlite3NameFromToken(db, pToken); + if( !zColl ) return; + + if( sqlite3LocateCollSeq(pParse, zColl) ){ + Index *pIdx; + sqlite3ColumnSetColl(db, &p->aCol[i], zColl); + + /* If the column is declared as " PRIMARY KEY COLLATE ", + ** then an index may have been created on this column before the + ** collation type was added. Correct this if it is the case. + */ + for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){ + assert( pIdx->nKeyCol==1 ); + if( pIdx->aiColumn[0]==i ){ + pIdx->azColl[0] = sqlite3ColumnColl(&p->aCol[i]); + } + } + } + sqlite3DbFree(db, zColl); +} + +/* Change the most recently parsed column to be a GENERATED ALWAYS AS +** column. +*/ +SQLITE_PRIVATE void sqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pType){ +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + u8 eType = COLFLAG_VIRTUAL; + Table *pTab = pParse->pNewTable; + Column *pCol; + if( pTab==0 ){ + /* generated column in an CREATE TABLE IF NOT EXISTS that already exists */ + goto generated_done; + } + pCol = &(pTab->aCol[pTab->nCol-1]); + if( IN_DECLARE_VTAB ){ + sqlite3ErrorMsg(pParse, "virtual tables cannot use computed columns"); + goto generated_done; + } + if( pCol->iDflt>0 ) goto generated_error; + if( pType ){ + if( pType->n==7 && sqlite3StrNICmp("virtual",pType->z,7)==0 ){ + /* no-op */ + }else if( pType->n==6 && sqlite3StrNICmp("stored",pType->z,6)==0 ){ + eType = COLFLAG_STORED; + }else{ + goto generated_error; + } + } + if( eType==COLFLAG_VIRTUAL ) pTab->nNVCol--; + pCol->colFlags |= eType; + assert( TF_HasVirtual==COLFLAG_VIRTUAL ); + assert( TF_HasStored==COLFLAG_STORED ); + pTab->tabFlags |= eType; + if( pCol->colFlags & COLFLAG_PRIMKEY ){ + makeColumnPartOfPrimaryKey(pParse, pCol); /* For the error message */ + } + if( ALWAYS(pExpr) && pExpr->op==TK_ID ){ + /* The value of a generated column needs to be a real expression, not + ** just a reference to another column, in order for covering index + ** optimizations to work correctly. So if the value is not an expression, + ** turn it into one by adding a unary "+" operator. */ + pExpr = sqlite3PExpr(pParse, TK_UPLUS, pExpr, 0); + } + if( pExpr && pExpr->op!=TK_RAISE ) pExpr->affExpr = pCol->affinity; + sqlite3ColumnSetExpr(pParse, pTab, pCol, pExpr); + pExpr = 0; + goto generated_done; + +generated_error: + sqlite3ErrorMsg(pParse, "error in generated column \"%s\"", + pCol->zCnName); +generated_done: + sqlite3ExprDelete(pParse->db, pExpr); +#else + /* Throw and error for the GENERATED ALWAYS AS clause if the + ** SQLITE_OMIT_GENERATED_COLUMNS compile-time option is used. */ + sqlite3ErrorMsg(pParse, "generated columns not supported"); + sqlite3ExprDelete(pParse->db, pExpr); +#endif +} + +/* +** Generate code that will increment the schema cookie. +** +** The schema cookie is used to determine when the schema for the +** database changes. After each schema change, the cookie value +** changes. When a process first reads the schema it records the +** cookie. Thereafter, whenever it goes to access the database, +** it checks the cookie to make sure the schema has not changed +** since it was last read. +** +** This plan is not completely bullet-proof. It is possible for +** the schema to change multiple times and for the cookie to be +** set back to prior value. But schema changes are infrequent +** and the probability of hitting the same cookie value is only +** 1 chance in 2^32. So we're safe enough. +** +** IMPLEMENTATION-OF: R-34230-56049 SQLite automatically increments +** the schema-version whenever the schema changes. +*/ +SQLITE_PRIVATE void sqlite3ChangeCookie(Parse *pParse, int iDb){ + sqlite3 *db = pParse->db; + Vdbe *v = pParse->pVdbe; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION, + (int)(1+(unsigned)db->aDb[iDb].pSchema->schema_cookie)); +} + +/* +** Measure the number of characters needed to output the given +** identifier. The number returned includes any quotes used +** but does not include the null terminator. +** +** The estimate is conservative. It might be larger that what is +** really needed. +*/ +static i64 identLength(const char *z){ + i64 n; + for(n=0; *z; n++, z++){ + if( *z=='"' ){ n++; } + } + return n + 2; +} + +/* +** The first parameter is a pointer to an output buffer. The second +** parameter is a pointer to an integer that contains the offset at +** which to write into the output buffer. This function copies the +** nul-terminated string pointed to by the third parameter, zSignedIdent, +** to the specified offset in the buffer and updates *pIdx to refer +** to the first byte after the last byte written before returning. +** +** If the string zSignedIdent consists entirely of alphanumeric +** characters, does not begin with a digit and is not an SQL keyword, +** then it is copied to the output buffer exactly as it is. Otherwise, +** it is quoted using double-quotes. +*/ +static void identPut(char *z, int *pIdx, char *zSignedIdent){ + unsigned char *zIdent = (unsigned char*)zSignedIdent; + int i, j, needQuote; + i = *pIdx; + + for(j=0; zIdent[j]; j++){ + if( !sqlite3Isalnum(zIdent[j]) && zIdent[j]!='_' ) break; + } + needQuote = sqlite3Isdigit(zIdent[0]) + || sqlite3KeywordCode(zIdent, j)!=TK_ID + || zIdent[j]!=0 + || j==0; + + if( needQuote ) z[i++] = '"'; + for(j=0; zIdent[j]; j++){ + z[i++] = zIdent[j]; + if( zIdent[j]=='"' ) z[i++] = '"'; + } + if( needQuote ) z[i++] = '"'; + z[i] = 0; + *pIdx = i; +} + +/* +** Generate a CREATE TABLE statement appropriate for the given +** table. Memory to hold the text of the statement is obtained +** from sqliteMalloc() and must be freed by the calling function. +*/ +static char *createTableStmt(sqlite3 *db, Table *p){ + int i, k, len; + i64 n; + char *zStmt; + char *zSep, *zSep2, *zEnd; + Column *pCol; + n = 0; + for(pCol = p->aCol, i=0; inCol; i++, pCol++){ + n += identLength(pCol->zCnName) + 5; + } + n += identLength(p->zName); + if( n<50 ){ + zSep = ""; + zSep2 = ","; + zEnd = ")"; + }else{ + zSep = "\n "; + zSep2 = ",\n "; + zEnd = "\n)"; + } + n += 35 + 6*p->nCol; + zStmt = sqlite3DbMallocRaw(0, n); + if( zStmt==0 ){ + sqlite3OomFault(db); + return 0; + } + assert( n>14 && n<=0x7fffffff ); + memcpy(zStmt, "CREATE TABLE ", 13); + k = 13; + identPut(zStmt, &k, p->zName); + zStmt[k++] = '('; + for(pCol=p->aCol, i=0; inCol; i++, pCol++){ + static const char * const azType[] = { + /* SQLITE_AFF_BLOB */ "", + /* SQLITE_AFF_TEXT */ " TEXT", + /* SQLITE_AFF_NUMERIC */ " NUM", + /* SQLITE_AFF_INTEGER */ " INT", + /* SQLITE_AFF_REAL */ " REAL", + /* SQLITE_AFF_FLEXNUM */ " NUM", + }; + const char *zType; + + len = sqlite3Strlen30(zSep); + assert( k+lenzCnName); + assert( kaffinity-SQLITE_AFF_BLOB >= 0 ); + assert( pCol->affinity-SQLITE_AFF_BLOB < ArraySize(azType) ); + testcase( pCol->affinity==SQLITE_AFF_BLOB ); + testcase( pCol->affinity==SQLITE_AFF_TEXT ); + testcase( pCol->affinity==SQLITE_AFF_NUMERIC ); + testcase( pCol->affinity==SQLITE_AFF_INTEGER ); + testcase( pCol->affinity==SQLITE_AFF_REAL ); + testcase( pCol->affinity==SQLITE_AFF_FLEXNUM ); + + zType = azType[pCol->affinity - SQLITE_AFF_BLOB]; + len = sqlite3Strlen30(zType); + assert( pCol->affinity==SQLITE_AFF_BLOB + || pCol->affinity==SQLITE_AFF_FLEXNUM + || pCol->affinity==sqlite3AffinityType(zType, 0) ); + assert( k+lennColumn>=N ) return SQLITE_OK; + db = pParse->db; + assert( N>0 ); + assert( N <= SQLITE_MAX_COLUMN*2 /* tag-20250221-1 */ ); + testcase( N==2*pParse->db->aLimit[SQLITE_LIMIT_COLUMN] ); + assert( pIdx->isResized==0 ); + nByte = (sizeof(char*) + sizeof(LogEst) + sizeof(i16) + 1)*(u64)N; + zExtra = sqlite3DbMallocZero(db, nByte); + if( zExtra==0 ) return SQLITE_NOMEM_BKPT; + memcpy(zExtra, pIdx->azColl, sizeof(char*)*pIdx->nColumn); + pIdx->azColl = (const char**)zExtra; + zExtra += sizeof(char*)*N; + memcpy(zExtra, pIdx->aiRowLogEst, sizeof(LogEst)*(pIdx->nKeyCol+1)); + pIdx->aiRowLogEst = (LogEst*)zExtra; + zExtra += sizeof(LogEst)*N; + memcpy(zExtra, pIdx->aiColumn, sizeof(i16)*pIdx->nColumn); + pIdx->aiColumn = (i16*)zExtra; + zExtra += sizeof(i16)*N; + memcpy(zExtra, pIdx->aSortOrder, pIdx->nColumn); + pIdx->aSortOrder = (u8*)zExtra; + pIdx->nColumn = (u16)N; /* See tag-20250221-1 above for proof of safety */ + pIdx->isResized = 1; + return SQLITE_OK; +} + +/* +** Estimate the total row width for a table. +*/ +static void estimateTableWidth(Table *pTab){ + unsigned wTable = 0; + const Column *pTabCol; + int i; + for(i=pTab->nCol, pTabCol=pTab->aCol; i>0; i--, pTabCol++){ + wTable += pTabCol->szEst; + } + if( pTab->iPKey<0 ) wTable++; + pTab->szTabRow = sqlite3LogEst(wTable*4); +} + +/* +** Estimate the average size of a row for an index. +*/ +static void estimateIndexWidth(Index *pIdx){ + unsigned wIndex = 0; + int i; + const Column *aCol = pIdx->pTable->aCol; + for(i=0; inColumn; i++){ + i16 x = pIdx->aiColumn[i]; + assert( xpTable->nCol ); + wIndex += x<0 ? 1 : aCol[x].szEst; + } + pIdx->szIdxRow = sqlite3LogEst(wIndex*4); +} + +/* Return true if column number x is any of the first nCol entries of aiCol[]. +** This is used to determine if the column number x appears in any of the +** first nCol entries of an index. +*/ +static int hasColumn(const i16 *aiCol, int nCol, int x){ + while( nCol-- > 0 ){ + if( x==*(aiCol++) ){ + return 1; + } + } + return 0; +} + +/* +** Return true if any of the first nKey entries of index pIdx exactly +** match the iCol-th entry of pPk. pPk is always a WITHOUT ROWID +** PRIMARY KEY index. pIdx is an index on the same table. pIdx may +** or may not be the same index as pPk. +** +** The first nKey entries of pIdx are guaranteed to be ordinary columns, +** not a rowid or expression. +** +** This routine differs from hasColumn() in that both the column and the +** collating sequence must match for this routine, but for hasColumn() only +** the column name must match. +*/ +static int isDupColumn(Index *pIdx, int nKey, Index *pPk, int iCol){ + int i, j; + assert( nKey<=pIdx->nColumn ); + assert( iColnColumn,pPk->nKeyCol) ); + assert( pPk->idxType==SQLITE_IDXTYPE_PRIMARYKEY ); + assert( pPk->pTable->tabFlags & TF_WithoutRowid ); + assert( pPk->pTable==pIdx->pTable ); + testcase( pPk==pIdx ); + j = pPk->aiColumn[iCol]; + assert( j!=XN_ROWID && j!=XN_EXPR ); + for(i=0; iaiColumn[i]>=0 || j>=0 ); + if( pIdx->aiColumn[i]==j + && sqlite3StrICmp(pIdx->azColl[i], pPk->azColl[iCol])==0 + ){ + return 1; + } + } + return 0; +} + +/* Recompute the colNotIdxed field of the Index. +** +** colNotIdxed is a bitmask that has a 0 bit representing each indexed +** columns that are within the first 63 columns of the table and a 1 for +** all other bits (all columns that are not in the index). The +** high-order bit of colNotIdxed is always 1. All unindexed columns +** of the table have a 1. +** +** 2019-10-24: For the purpose of this computation, virtual columns are +** not considered to be covered by the index, even if they are in the +** index, because we do not trust the logic in whereIndexExprTrans() to be +** able to find all instances of a reference to the indexed table column +** and convert them into references to the index. Hence we always want +** the actual table at hand in order to recompute the virtual column, if +** necessary. +** +** The colNotIdxed mask is AND-ed with the SrcList.a[].colUsed mask +** to determine if the index is covering index. +*/ +static void recomputeColumnsNotIndexed(Index *pIdx){ + Bitmask m = 0; + int j; + Table *pTab = pIdx->pTable; + for(j=pIdx->nColumn-1; j>=0; j--){ + int x = pIdx->aiColumn[j]; + if( x>=0 && (pTab->aCol[x].colFlags & COLFLAG_VIRTUAL)==0 ){ + testcase( x==BMS-1 ); + testcase( x==BMS-2 ); + if( xcolNotIdxed = ~m; + assert( (pIdx->colNotIdxed>>63)==1 ); /* See note-20221022-a */ +} + +/* +** This routine runs at the end of parsing a CREATE TABLE statement that +** has a WITHOUT ROWID clause. The job of this routine is to convert both +** internal schema data structures and the generated VDBE code so that they +** are appropriate for a WITHOUT ROWID table instead of a rowid table. +** Changes include: +** +** (1) Set all columns of the PRIMARY KEY schema object to be NOT NULL. +** (2) Convert P3 parameter of the OP_CreateBtree from BTREE_INTKEY +** into BTREE_BLOBKEY. +** (3) Bypass the creation of the sqlite_schema table entry +** for the PRIMARY KEY as the primary key index is now +** identified by the sqlite_schema table entry of the table itself. +** (4) Set the Index.tnum of the PRIMARY KEY Index object in the +** schema to the rootpage from the main table. +** (5) Add all table columns to the PRIMARY KEY Index object +** so that the PRIMARY KEY is a covering index. The surplus +** columns are part of KeyInfo.nAllField and are not used for +** sorting or lookup or uniqueness checks. +** (6) Replace the rowid tail on all automatically generated UNIQUE +** indices with the PRIMARY KEY columns. +** +** For virtual tables, only (1) is performed. +*/ +static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ + Index *pIdx; + Index *pPk; + int nPk; + int nExtra; + int i, j; + sqlite3 *db = pParse->db; + Vdbe *v = pParse->pVdbe; + + /* Mark every PRIMARY KEY column as NOT NULL (except for imposter tables) + */ + if( !db->init.imposterTable ){ + for(i=0; inCol; i++){ + if( (pTab->aCol[i].colFlags & COLFLAG_PRIMKEY)!=0 + && (pTab->aCol[i].notNull==OE_None) + ){ + pTab->aCol[i].notNull = OE_Abort; + } + } + pTab->tabFlags |= TF_HasNotNull; + } + + /* Convert the P3 operand of the OP_CreateBtree opcode from BTREE_INTKEY + ** into BTREE_BLOBKEY. + */ + assert( !pParse->bReturning ); + if( pParse->u1.cr.addrCrTab ){ + assert( v ); + sqlite3VdbeChangeP3(v, pParse->u1.cr.addrCrTab, BTREE_BLOBKEY); + } + + /* Locate the PRIMARY KEY index. Or, if this table was originally + ** an INTEGER PRIMARY KEY table, create a new PRIMARY KEY index. + */ + if( pTab->iPKey>=0 ){ + ExprList *pList; + Token ipkToken; + sqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zCnName); + pList = sqlite3ExprListAppend(pParse, 0, + sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0)); + if( pList==0 ){ + pTab->tabFlags &= ~TF_WithoutRowid; + return; + } + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, pList->a[0].pExpr, &pTab->iPKey); + } + pList->a[0].fg.sortFlags = pParse->iPkSortOrder; + assert( pParse->pNewTable==pTab ); + pTab->iPKey = -1; + sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0, + SQLITE_IDXTYPE_PRIMARYKEY); + if( pParse->nErr ){ + pTab->tabFlags &= ~TF_WithoutRowid; + return; + } + assert( db->mallocFailed==0 ); + pPk = sqlite3PrimaryKeyIndex(pTab); + assert( pPk->nKeyCol==1 ); + }else{ + pPk = sqlite3PrimaryKeyIndex(pTab); + assert( pPk!=0 ); + + /* + ** Remove all redundant columns from the PRIMARY KEY. For example, change + ** "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)". Later + ** code assumes the PRIMARY KEY contains no repeated columns. + */ + for(i=j=1; inKeyCol; i++){ + if( isDupColumn(pPk, j, pPk, i) ){ + pPk->nColumn--; + }else{ + testcase( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) ); + pPk->azColl[j] = pPk->azColl[i]; + pPk->aSortOrder[j] = pPk->aSortOrder[i]; + pPk->aiColumn[j++] = pPk->aiColumn[i]; + } + } + pPk->nKeyCol = j; + } + assert( pPk!=0 ); + pPk->isCovering = 1; + if( !db->init.imposterTable ) pPk->uniqNotNull = 1; + nPk = pPk->nColumn = pPk->nKeyCol; + + /* Bypass the creation of the PRIMARY KEY btree and the sqlite_schema + ** table entry. This is only required if currently generating VDBE + ** code for a CREATE TABLE (not when parsing one as part of reading + ** a database schema). */ + if( v && pPk->tnum>0 ){ + assert( db->init.busy==0 ); + sqlite3VdbeChangeOpcode(v, (int)pPk->tnum, OP_Goto); + } + + /* The root page of the PRIMARY KEY is the table root page */ + pPk->tnum = pTab->tnum; + + /* Update the in-memory representation of all UNIQUE indices by converting + ** the final rowid column into one or more columns of the PRIMARY KEY. + */ + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + int n; + if( IsPrimaryKeyIndex(pIdx) ) continue; + for(i=n=0; inKeyCol, pPk, i) ){ + testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ); + n++; + } + } + if( n==0 ){ + /* This index is a superset of the primary key */ + pIdx->nColumn = pIdx->nKeyCol; + continue; + } + if( resizeIndexObject(pParse, pIdx, pIdx->nKeyCol+n) ) return; + for(i=0, j=pIdx->nKeyCol; inKeyCol, pPk, i) ){ + testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ); + pIdx->aiColumn[j] = pPk->aiColumn[i]; + pIdx->azColl[j] = pPk->azColl[i]; + if( pPk->aSortOrder[i] ){ + /* See ticket https://sqlite.org/src/info/bba7b69f9849b5bf */ + pIdx->bAscKeyBug = 1; + } + j++; + } + } + assert( pIdx->nColumn>=pIdx->nKeyCol+n ); + assert( pIdx->nColumn>=j ); + } + + /* Add all table columns to the PRIMARY KEY index + */ + nExtra = 0; + for(i=0; inCol; i++){ + if( !hasColumn(pPk->aiColumn, nPk, i) + && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ) nExtra++; + } + if( resizeIndexObject(pParse, pPk, nPk+nExtra) ) return; + for(i=0, j=nPk; inCol; i++){ + if( !hasColumn(pPk->aiColumn, j, i) + && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 + ){ + const char *zColl = sqlite3ColumnColl(&pTab->aCol[i]); + assert( jnColumn ); + pPk->aiColumn[j] = i; + pPk->azColl[j] = zColl ? zColl : sqlite3StrBINARY; + j++; + } + } + assert( pPk->nColumn==j ); + assert( pTab->nNVCol<=j ); + recomputeColumnsNotIndexed(pPk); +} + + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Return true if pTab is a virtual table and zName is a shadow table name +** for that virtual table. +*/ +SQLITE_PRIVATE int sqlite3IsShadowTableOf(sqlite3 *db, Table *pTab, const char *zName){ + int nName; /* Length of zName */ + Module *pMod; /* Module for the virtual table */ + + if( !IsVirtual(pTab) ) return 0; + nName = sqlite3Strlen30(pTab->zName); + if( sqlite3_strnicmp(zName, pTab->zName, nName)!=0 ) return 0; + if( zName[nName]!='_' ) return 0; + pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->u.vtab.azArg[0]); + if( pMod==0 ) return 0; + if( pMod->pModule->iVersion<3 ) return 0; + if( pMod->pModule->xShadowName==0 ) return 0; + return pMod->pModule->xShadowName(zName+nName+1); +} +#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Table pTab is a virtual table. If it the virtual table implementation +** exists and has an xShadowName method, then loop over all other ordinary +** tables within the same schema looking for shadow tables of pTab, and mark +** any shadow tables seen using the TF_Shadow flag. +*/ +SQLITE_PRIVATE void sqlite3MarkAllShadowTablesOf(sqlite3 *db, Table *pTab){ + int nName; /* Length of pTab->zName */ + Module *pMod; /* Module for the virtual table */ + HashElem *k; /* For looping through the symbol table */ + + assert( IsVirtual(pTab) ); + pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->u.vtab.azArg[0]); + if( pMod==0 ) return; + if( NEVER(pMod->pModule==0) ) return; + if( pMod->pModule->iVersion<3 ) return; + if( pMod->pModule->xShadowName==0 ) return; + assert( pTab->zName!=0 ); + nName = sqlite3Strlen30(pTab->zName); + for(k=sqliteHashFirst(&pTab->pSchema->tblHash); k; k=sqliteHashNext(k)){ + Table *pOther = sqliteHashData(k); + assert( pOther->zName!=0 ); + if( !IsOrdinaryTable(pOther) ) continue; + if( pOther->tabFlags & TF_Shadow ) continue; + if( sqlite3StrNICmp(pOther->zName, pTab->zName, nName)==0 + && pOther->zName[nName]=='_' + && pMod->pModule->xShadowName(pOther->zName+nName+1) + ){ + pOther->tabFlags |= TF_Shadow; + } + } +} +#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Return true if zName is a shadow table name in the current database +** connection. +** +** zName is temporarily modified while this routine is running, but is +** restored to its original value prior to this routine returning. +*/ +SQLITE_PRIVATE int sqlite3ShadowTableName(sqlite3 *db, const char *zName){ + const char *zTail; /* Pointer to the last "_" in zName */ + Table *pTab; /* Table that zName is a shadow of */ + char *zCopy; + zTail = strrchr(zName, '_'); + if( zTail==0 ) return 0; + zCopy = sqlite3DbStrNDup(db, zName, (int)(zTail-zName)); + pTab = zCopy ? sqlite3FindTable(db, zCopy, 0) : 0; + sqlite3DbFree(db, zCopy); + if( pTab==0 ) return 0; + if( !IsVirtual(pTab) ) return 0; + return sqlite3IsShadowTableOf(db, pTab, zName); +} +#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ + + +#ifdef SQLITE_DEBUG +/* +** Mark all nodes of an expression as EP_Immutable, indicating that +** they should not be changed. Expressions attached to a table or +** index definition are tagged this way to help ensure that we do +** not pass them into code generator routines by mistake. +*/ +static int markImmutableExprStep(Walker *pWalker, Expr *pExpr){ + (void)pWalker; + ExprSetVVAProperty(pExpr, EP_Immutable); + return WRC_Continue; +} +static void markExprListImmutable(ExprList *pList){ + if( pList ){ + Walker w; + memset(&w, 0, sizeof(w)); + w.xExprCallback = markImmutableExprStep; + w.xSelectCallback = sqlite3SelectWalkNoop; + w.xSelectCallback2 = 0; + sqlite3WalkExprList(&w, pList); + } +} +#else +#define markExprListImmutable(X) /* no-op */ +#endif /* SQLITE_DEBUG */ + + +/* +** This routine is called to report the final ")" that terminates +** a CREATE TABLE statement. +** +** The table structure that other action routines have been building +** is added to the internal hash tables, assuming no errors have +** occurred. +** +** An entry for the table is made in the schema table on disk, unless +** this is a temporary table or db->init.busy==1. When db->init.busy==1 +** it means we are reading the sqlite_schema table because we just +** connected to the database or because the sqlite_schema table has +** recently changed, so the entry for this table already exists in +** the sqlite_schema table. We do not want to create it again. +** +** If the pSelect argument is not NULL, it means that this routine +** was called to create a table generated from a +** "CREATE TABLE ... AS SELECT ..." statement. The column names of +** the new table will match the result set of the SELECT. +*/ +SQLITE_PRIVATE void sqlite3EndTable( + Parse *pParse, /* Parse context */ + Token *pCons, /* The ',' token after the last column defn. */ + Token *pEnd, /* The ')' before options in the CREATE TABLE */ + u32 tabOpts, /* Extra table options. Usually 0. */ + Select *pSelect /* Select from a "CREATE ... AS SELECT" */ +){ + Table *p; /* The new table */ + sqlite3 *db = pParse->db; /* The database connection */ + int iDb; /* Database in which the table lives */ + Index *pIdx; /* An implied index of the table */ + + if( pEnd==0 && pSelect==0 ){ + return; + } + p = pParse->pNewTable; + if( p==0 ) return; + + if( pSelect==0 && sqlite3ShadowTableName(db, p->zName) ){ + p->tabFlags |= TF_Shadow; + } + + /* If the db->init.busy is 1 it means we are reading the SQL off the + ** "sqlite_schema" or "sqlite_temp_schema" table on the disk. + ** So do not write to the disk again. Extract the root page number + ** for the table from the db->init.newTnum field. (The page number + ** should have been put there by the sqliteOpenCb routine.) + ** + ** If the root page number is 1, that means this is the sqlite_schema + ** table itself. So mark it read-only. + */ + if( db->init.busy ){ + if( pSelect || (!IsOrdinaryTable(p) && db->init.newTnum) ){ + sqlite3ErrorMsg(pParse, ""); + return; + } + p->tnum = db->init.newTnum; + if( p->tnum==1 ) p->tabFlags |= TF_Readonly; + } + + /* Special processing for tables that include the STRICT keyword: + ** + ** * Do not allow custom column datatypes. Every column must have + ** a datatype that is one of INT, INTEGER, REAL, TEXT, or BLOB. + ** + ** * If a PRIMARY KEY is defined, other than the INTEGER PRIMARY KEY, + ** then all columns of the PRIMARY KEY must have a NOT NULL + ** constraint. + */ + if( tabOpts & TF_Strict ){ + int ii; + p->tabFlags |= TF_Strict; + for(ii=0; iinCol; ii++){ + Column *pCol = &p->aCol[ii]; + if( pCol->eCType==COLTYPE_CUSTOM ){ + if( pCol->colFlags & COLFLAG_HASTYPE ){ + sqlite3ErrorMsg(pParse, + "unknown datatype for %s.%s: \"%s\"", + p->zName, pCol->zCnName, sqlite3ColumnType(pCol, "") + ); + }else{ + sqlite3ErrorMsg(pParse, "missing datatype for %s.%s", + p->zName, pCol->zCnName); + } + return; + }else if( pCol->eCType==COLTYPE_ANY ){ + pCol->affinity = SQLITE_AFF_BLOB; + } + if( (pCol->colFlags & COLFLAG_PRIMKEY)!=0 + && p->iPKey!=ii + && pCol->notNull == OE_None + ){ + pCol->notNull = OE_Abort; + p->tabFlags |= TF_HasNotNull; + } + } + } + + assert( (p->tabFlags & TF_HasPrimaryKey)==0 + || p->iPKey>=0 || sqlite3PrimaryKeyIndex(p)!=0 ); + assert( (p->tabFlags & TF_HasPrimaryKey)!=0 + || (p->iPKey<0 && sqlite3PrimaryKeyIndex(p)==0) ); + + /* Special processing for WITHOUT ROWID Tables */ + if( tabOpts & TF_WithoutRowid ){ + if( (p->tabFlags & TF_Autoincrement) ){ + sqlite3ErrorMsg(pParse, + "AUTOINCREMENT not allowed on WITHOUT ROWID tables"); + return; + } + if( (p->tabFlags & TF_HasPrimaryKey)==0 ){ + sqlite3ErrorMsg(pParse, "PRIMARY KEY missing on table %s", p->zName); + return; + } + p->tabFlags |= TF_WithoutRowid | TF_NoVisibleRowid; + convertToWithoutRowidTable(pParse, p); + } + iDb = sqlite3SchemaToIndex(db, p->pSchema); + assert( iDb>=0 && iDb<=db->nDb ); + +#ifndef SQLITE_OMIT_CHECK + /* Resolve names in all CHECK constraint expressions. + */ + if( p->pCheck ){ + sqlite3ResolveSelfReference(pParse, p, NC_IsCheck, 0, p->pCheck); + if( pParse->nErr ){ + /* If errors are seen, delete the CHECK constraints now, else they might + ** actually be used if PRAGMA writable_schema=ON is set. */ + sqlite3ExprListDelete(db, p->pCheck); + p->pCheck = 0; + }else{ + markExprListImmutable(p->pCheck); + } + } +#endif /* !defined(SQLITE_OMIT_CHECK) */ +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + if( p->tabFlags & TF_HasGenerated ){ + int ii, nNG = 0; + testcase( p->tabFlags & TF_HasVirtual ); + testcase( p->tabFlags & TF_HasStored ); + for(ii=0; iinCol; ii++){ + u32 colFlags = p->aCol[ii].colFlags; + if( (colFlags & COLFLAG_GENERATED)!=0 ){ + Expr *pX = sqlite3ColumnExpr(p, &p->aCol[ii]); + testcase( colFlags & COLFLAG_VIRTUAL ); + testcase( colFlags & COLFLAG_STORED ); + if( sqlite3ResolveSelfReference(pParse, p, NC_GenCol, pX, 0) ){ + /* If there are errors in resolving the expression, change the + ** expression to a NULL. This prevents code generators that operate + ** on the expression from inserting extra parts into the expression + ** tree that have been allocated from lookaside memory, which is + ** illegal in a schema and will lead to errors or heap corruption + ** when the database connection closes. */ + sqlite3ColumnSetExpr(pParse, p, &p->aCol[ii], + sqlite3ExprAlloc(db, TK_NULL, 0, 0)); + } + }else{ + nNG++; + } + } + if( nNG==0 ){ + sqlite3ErrorMsg(pParse, "must have at least one non-generated column"); + return; + } + } +#endif + + /* Estimate the average row size for the table and for all implied indices */ + estimateTableWidth(p); + for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){ + estimateIndexWidth(pIdx); + } + + /* If not initializing, then create a record for the new table + ** in the schema table of the database. + ** + ** If this is a TEMPORARY table, write the entry into the auxiliary + ** file instead of into the main database file. + */ + if( !db->init.busy ){ + int n; + Vdbe *v; + char *zType; /* "view" or "table" */ + char *zType2; /* "VIEW" or "TABLE" */ + char *zStmt; /* Text of the CREATE TABLE or CREATE VIEW statement */ + + v = sqlite3GetVdbe(pParse); + if( NEVER(v==0) ) return; + + sqlite3VdbeAddOp1(v, OP_Close, 0); + + /* + ** Initialize zType for the new view or table. + */ + if( IsOrdinaryTable(p) ){ + /* A regular table */ + zType = "table"; + zType2 = "TABLE"; +#ifndef SQLITE_OMIT_VIEW + }else{ + /* A view */ + zType = "view"; + zType2 = "VIEW"; +#endif + } + + /* If this is a CREATE TABLE xx AS SELECT ..., execute the SELECT + ** statement to populate the new table. The root-page number for the + ** new table is in register pParse->u1.cr.regRoot. + ** + ** Once the SELECT has been coded by sqlite3Select(), it is in a + ** suitable state to query for the column names and types to be used + ** by the new table. + ** + ** A shared-cache write-lock is not required to write to the new table, + ** as a schema-lock must have already been obtained to create it. Since + ** a schema-lock excludes all other database users, the write-lock would + ** be redundant. + */ + if( pSelect ){ + SelectDest dest; /* Where the SELECT should store results */ + int regYield; /* Register holding co-routine entry-point */ + int addrTop; /* Top of the co-routine */ + int regRec; /* A record to be insert into the new table */ + int regRowid; /* Rowid of the next row to insert */ + int addrInsLoop; /* Top of the loop for inserting rows */ + Table *pSelTab; /* A table that describes the SELECT results */ + int iCsr; /* Write cursor on the new table */ + + if( IN_SPECIAL_PARSE ){ + pParse->rc = SQLITE_ERROR; + pParse->nErr++; + return; + } + iCsr = pParse->nTab++; + regYield = ++pParse->nMem; + regRec = ++pParse->nMem; + regRowid = ++pParse->nMem; + sqlite3MayAbort(pParse); + assert( pParse->isCreate ); + sqlite3VdbeAddOp3(v, OP_OpenWrite, iCsr, pParse->u1.cr.regRoot, iDb); + sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG); + addrTop = sqlite3VdbeCurrentAddr(v) + 1; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); + if( pParse->nErr ) return; + pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect, SQLITE_AFF_BLOB); + if( pSelTab==0 ) return; + assert( p->aCol==0 ); + p->nCol = p->nNVCol = pSelTab->nCol; + p->aCol = pSelTab->aCol; + pSelTab->nCol = 0; + pSelTab->aCol = 0; + sqlite3DeleteTable(db, pSelTab); + sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); + sqlite3Select(pParse, pSelect, &dest); + if( pParse->nErr ) return; + sqlite3VdbeEndCoroutine(v, regYield); + sqlite3VdbeJumpHere(v, addrTop - 1); + addrInsLoop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_MakeRecord, dest.iSdst, dest.nSdst, regRec); + sqlite3TableAffinity(v, p, 0); + sqlite3VdbeAddOp2(v, OP_NewRowid, iCsr, regRowid); + sqlite3VdbeAddOp3(v, OP_Insert, iCsr, regRec, regRowid); + sqlite3VdbeGoto(v, addrInsLoop); + sqlite3VdbeJumpHere(v, addrInsLoop); + sqlite3VdbeAddOp1(v, OP_Close, iCsr); + } + + /* Compute the complete text of the CREATE statement */ + if( pSelect ){ + zStmt = createTableStmt(db, p); + }else{ + Token *pEnd2 = tabOpts ? &pParse->sLastToken : pEnd; + n = (int)(pEnd2->z - pParse->sNameToken.z); + if( pEnd2->z[0]!=';' ) n += pEnd2->n; + zStmt = sqlite3MPrintf(db, + "CREATE %s %.*s", zType2, n, pParse->sNameToken.z + ); + } + + /* A slot for the record has already been allocated in the + ** schema table. We just need to update that slot with all + ** the information we've collected. + */ + assert( pParse->isCreate ); + sqlite3NestedParse(pParse, + "UPDATE %Q." LEGACY_SCHEMA_TABLE + " SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q" + " WHERE rowid=#%d", + db->aDb[iDb].zDbSName, + zType, + p->zName, + p->zName, + pParse->u1.cr.regRoot, + zStmt, + pParse->u1.cr.regRowid + ); + sqlite3DbFree(db, zStmt); + sqlite3ChangeCookie(pParse, iDb); + +#ifndef SQLITE_OMIT_AUTOINCREMENT + /* Check to see if we need to create an sqlite_sequence table for + ** keeping track of autoincrement keys. + */ + if( (p->tabFlags & TF_Autoincrement)!=0 && !IN_SPECIAL_PARSE ){ + Db *pDb = &db->aDb[iDb]; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + if( pDb->pSchema->pSeqTab==0 ){ + sqlite3NestedParse(pParse, + "CREATE TABLE %Q.sqlite_sequence(name,seq)", + pDb->zDbSName + ); + } + } +#endif + + /* Reparse everything to update our internal data structures */ + sqlite3VdbeAddParseSchemaOp(v, iDb, + sqlite3MPrintf(db, "tbl_name='%q' AND type!='trigger'", p->zName),0); + + /* Test for cycles in generated columns and illegal expressions + ** in CHECK constraints and in DEFAULT clauses. */ + if( p->tabFlags & TF_HasGenerated ){ + sqlite3VdbeAddOp4(v, OP_SqlExec, 0x0001, 0, 0, + sqlite3MPrintf(db, "SELECT*FROM\"%w\".\"%w\"", + db->aDb[iDb].zDbSName, p->zName), P4_DYNAMIC); + } + } + + /* Add the table to the in-memory representation of the database. + */ + if( db->init.busy ){ + Table *pOld; + Schema *pSchema = p->pSchema; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( HasRowid(p) || p->iPKey<0 ); + pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, p); + if( pOld ){ + assert( p==pOld ); /* Malloc must have failed inside HashInsert() */ + sqlite3OomFault(db); + return; + } + pParse->pNewTable = 0; + db->mDbFlags |= DBFLAG_SchemaChange; + + /* If this is the magic sqlite_sequence table used by autoincrement, + ** then record a pointer to this table in the main database structure + ** so that INSERT can find the table easily. */ + assert( !pParse->nested ); +#ifndef SQLITE_OMIT_AUTOINCREMENT + if( strcmp(p->zName, "sqlite_sequence")==0 ){ + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + p->pSchema->pSeqTab = p; + } +#endif + } + +#ifndef SQLITE_OMIT_ALTERTABLE + if( !pSelect && IsOrdinaryTable(p) ){ + assert( pCons && pEnd ); + if( pCons->z==0 ){ + pCons = pEnd; + } + p->u.tab.addColOffset = 13 + (int)(pCons->z - pParse->sNameToken.z); + } +#endif +} + +#ifndef SQLITE_OMIT_VIEW +/* +** The parser calls this routine in order to create a new VIEW +*/ +SQLITE_PRIVATE void sqlite3CreateView( + Parse *pParse, /* The parsing context */ + Token *pBegin, /* The CREATE token that begins the statement */ + Token *pName1, /* The token that holds the name of the view */ + Token *pName2, /* The token that holds the name of the view */ + ExprList *pCNames, /* Optional list of view column names */ + Select *pSelect, /* A SELECT statement that will become the new view */ + int isTemp, /* TRUE for a TEMPORARY view */ + int noErr /* Suppress error messages if VIEW already exists */ +){ + Table *p; + int n; + const char *z; + Token sEnd; + DbFixer sFix; + Token *pName = 0; + int iDb; + sqlite3 *db = pParse->db; + + if( pParse->nVar>0 ){ + sqlite3ErrorMsg(pParse, "parameters are not allowed in views"); + goto create_view_fail; + } + sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr); + p = pParse->pNewTable; + if( p==0 || pParse->nErr ) goto create_view_fail; + + /* Legacy versions of SQLite allowed the use of the magic "rowid" column + ** on a view, even though views do not have rowids. The following flag + ** setting fixes this problem. But the fix can be disabled by compiling + ** with -DSQLITE_ALLOW_ROWID_IN_VIEW in case there are legacy apps that + ** depend upon the old buggy behavior. The ability can also be toggled + ** using sqlite3_config(SQLITE_CONFIG_ROWID_IN_VIEW,...) */ +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + p->tabFlags |= sqlite3Config.mNoVisibleRowid; /* Optional. Allow by default */ +#else + p->tabFlags |= TF_NoVisibleRowid; /* Never allow rowid in view */ +#endif + + sqlite3TwoPartName(pParse, pName1, pName2, &pName); + iDb = sqlite3SchemaToIndex(db, p->pSchema); + assert( iDb>=0 && iDbnDb ); + sqlite3FixInit(&sFix, pParse, iDb, "view", pName); + if( sqlite3FixSelect(&sFix, pSelect) ) goto create_view_fail; + + /* Make a copy of the entire SELECT statement that defines the view. + ** This will force all the Expr.token.z values to be dynamically + ** allocated rather than point to the input string - which means that + ** they will persist after the current sqlite3_exec() call returns. + */ + pSelect->selFlags |= SF_View; + if( IN_RENAME_OBJECT ){ + p->u.view.pSelect = pSelect; + pSelect = 0; + }else{ + p->u.view.pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); + } + p->pCheck = sqlite3ExprListDup(db, pCNames, EXPRDUP_REDUCE); + p->eTabType = TABTYP_VIEW; + if( db->mallocFailed ) goto create_view_fail; + + /* Locate the end of the CREATE VIEW statement. Make sEnd point to + ** the end. + */ + sEnd = pParse->sLastToken; + assert( sEnd.z[0]!=0 || sEnd.n==0 ); + if( sEnd.z[0]!=';' ){ + sEnd.z += sEnd.n; + } + sEnd.n = 0; + n = (int)(sEnd.z - pBegin->z); + assert( n>0 ); + z = pBegin->z; + while( sqlite3Isspace(z[n-1]) ){ n--; } + sEnd.z = &z[n-1]; + sEnd.n = 1; + + /* Use sqlite3EndTable() to add the view to the schema table */ + sqlite3EndTable(pParse, 0, &sEnd, 0, 0); + +create_view_fail: + sqlite3SelectDelete(db, pSelect); + if( IN_RENAME_OBJECT ){ + sqlite3RenameExprlistUnmap(pParse, pCNames); + } + sqlite3ExprListDelete(db, pCNames); + return; +} +#endif /* SQLITE_OMIT_VIEW */ + +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) +/* +** The Table structure pTable is really a VIEW. Fill in the names of +** the columns of the view in the pTable structure. Return non-zero if +** there are errors. If an error is seen an error message is left +** in pParse->zErrMsg. +*/ +static SQLITE_NOINLINE int viewGetColumnNames(Parse *pParse, Table *pTable){ + Table *pSelTab; /* A fake table from which we get the result set */ + Select *pSel; /* Copy of the SELECT that implements the view */ + int nErr = 0; /* Number of errors encountered */ + sqlite3 *db = pParse->db; /* Database connection for malloc errors */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + int rc; +#endif +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth; /* Saved xAuth pointer */ +#endif + + assert( pTable ); + +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTable) ){ + db->nSchemaLock++; + rc = sqlite3VtabCallConnect(pParse, pTable); + db->nSchemaLock--; + return rc; + } +#endif + +#ifndef SQLITE_OMIT_VIEW + /* A positive nCol means the columns names for this view are + ** already known. This routine is not called unless either the + ** table is virtual or nCol is zero. + */ + assert( pTable->nCol<=0 ); + + /* A negative nCol is a special marker meaning that we are currently + ** trying to compute the column names. If we enter this routine with + ** a negative nCol, it means two or more views form a loop, like this: + ** + ** CREATE VIEW one AS SELECT * FROM two; + ** CREATE VIEW two AS SELECT * FROM one; + ** + ** Actually, the error above is now caught prior to reaching this point. + ** But the following test is still important as it does come up + ** in the following: + ** + ** CREATE TABLE main.ex1(a); + ** CREATE TEMP VIEW ex1 AS SELECT a FROM ex1; + ** SELECT * FROM temp.ex1; + */ + if( pTable->nCol<0 ){ + sqlite3ErrorMsg(pParse, "view %s is circularly defined", pTable->zName); + return 1; + } + assert( pTable->nCol>=0 ); + + /* If we get this far, it means we need to compute the table names. + ** Note that the call to sqlite3ResultSetOfSelect() will expand any + ** "*" elements in the results set of the view and will assign cursors + ** to the elements of the FROM clause. But we do not want these changes + ** to be permanent. So the computation is done on a copy of the SELECT + ** statement that defines the view. + */ + assert( IsView(pTable) ); + pSel = sqlite3SelectDup(db, pTable->u.view.pSelect, 0); + if( pSel ){ + u8 eParseMode = pParse->eParseMode; + int nTab = pParse->nTab; + int nSelect = pParse->nSelect; + pParse->eParseMode = PARSE_MODE_NORMAL; + sqlite3SrcListAssignCursors(pParse, pSel->pSrc); + pTable->nCol = -1; + DisableLookaside; +#ifndef SQLITE_OMIT_AUTHORIZATION + xAuth = db->xAuth; + db->xAuth = 0; + pSelTab = sqlite3ResultSetOfSelect(pParse, pSel, SQLITE_AFF_NONE); + db->xAuth = xAuth; +#else + pSelTab = sqlite3ResultSetOfSelect(pParse, pSel, SQLITE_AFF_NONE); +#endif + pParse->nTab = nTab; + pParse->nSelect = nSelect; + if( pSelTab==0 ){ + pTable->nCol = 0; + nErr++; + }else if( pTable->pCheck ){ + /* CREATE VIEW name(arglist) AS ... + ** The names of the columns in the table are taken from + ** arglist which is stored in pTable->pCheck. The pCheck field + ** normally holds CHECK constraints on an ordinary table, but for + ** a VIEW it holds the list of column names. + */ + sqlite3ColumnsFromExprList(pParse, pTable->pCheck, + &pTable->nCol, &pTable->aCol); + if( pParse->nErr==0 + && pTable->nCol==pSel->pEList->nExpr + ){ + assert( db->mallocFailed==0 ); + sqlite3SubqueryColumnTypes(pParse, pTable, pSel, SQLITE_AFF_NONE); + } + }else{ + /* CREATE VIEW name AS... without an argument list. Construct + ** the column names from the SELECT statement that defines the view. + */ + assert( pTable->aCol==0 ); + pTable->nCol = pSelTab->nCol; + pTable->aCol = pSelTab->aCol; + pTable->tabFlags |= (pSelTab->tabFlags & COLFLAG_NOINSERT); + pSelTab->nCol = 0; + pSelTab->aCol = 0; + assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) ); + } + pTable->nNVCol = pTable->nCol; + sqlite3DeleteTable(db, pSelTab); + sqlite3SelectDelete(db, pSel); + EnableLookaside; + pParse->eParseMode = eParseMode; + } else { + nErr++; + } + pTable->pSchema->schemaFlags |= DB_UnresetViews; + if( db->mallocFailed ){ + sqlite3DeleteColumnNames(db, pTable); + } +#endif /* SQLITE_OMIT_VIEW */ + return nErr + pParse->nErr; +} +SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ + assert( pTable!=0 ); + if( !IsVirtual(pTable) && pTable->nCol>0 ) return 0; + return viewGetColumnNames(pParse, pTable); +} +#endif /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */ + +#ifndef SQLITE_OMIT_VIEW +/* +** Clear the column names from every VIEW in database idx. +*/ +static void sqliteViewResetAll(sqlite3 *db, int idx){ + HashElem *i; + assert( sqlite3SchemaMutexHeld(db, idx, 0) ); + if( !DbHasProperty(db, idx, DB_UnresetViews) ) return; + for(i=sqliteHashFirst(&db->aDb[idx].pSchema->tblHash); i;i=sqliteHashNext(i)){ + Table *pTab = sqliteHashData(i); + if( IsView(pTab) ){ + sqlite3DeleteColumnNames(db, pTab); + } + } + DbClearProperty(db, idx, DB_UnresetViews); +} +#else +# define sqliteViewResetAll(A,B) +#endif /* SQLITE_OMIT_VIEW */ + +/* +** This function is called by the VDBE to adjust the internal schema +** used by SQLite when the btree layer moves a table root page. The +** root-page of a table or index in database iDb has changed from iFrom +** to iTo. +** +** Ticket #1728: The symbol table might still contain information +** on tables and/or indices that are the process of being deleted. +** If you are unlucky, one of those deleted indices or tables might +** have the same rootpage number as the real table or index that is +** being moved. So we cannot stop searching after the first match +** because the first match might be for one of the deleted indices +** or tables and not the table/index that is actually being moved. +** We must continue looping until all tables and indices with +** rootpage==iFrom have been converted to have a rootpage of iTo +** in order to be certain that we got the right one. +*/ +#ifndef SQLITE_OMIT_AUTOVACUUM +SQLITE_PRIVATE void sqlite3RootPageMoved(sqlite3 *db, int iDb, Pgno iFrom, Pgno iTo){ + HashElem *pElem; + Hash *pHash; + Db *pDb; + + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + pDb = &db->aDb[iDb]; + pHash = &pDb->pSchema->tblHash; + for(pElem=sqliteHashFirst(pHash); pElem; pElem=sqliteHashNext(pElem)){ + Table *pTab = sqliteHashData(pElem); + if( pTab->tnum==iFrom ){ + pTab->tnum = iTo; + } + } + pHash = &pDb->pSchema->idxHash; + for(pElem=sqliteHashFirst(pHash); pElem; pElem=sqliteHashNext(pElem)){ + Index *pIdx = sqliteHashData(pElem); + if( pIdx->tnum==iFrom ){ + pIdx->tnum = iTo; + } + } +} +#endif + +/* +** Write code to erase the table with root-page iTable from database iDb. +** Also write code to modify the sqlite_schema table and internal schema +** if a root-page of another table is moved by the btree-layer whilst +** erasing iTable (this can happen with an auto-vacuum database). +*/ +static void destroyRootPage(Parse *pParse, int iTable, int iDb){ + Vdbe *v = sqlite3GetVdbe(pParse); + int r1 = sqlite3GetTempReg(pParse); + if( iTable<2 ) sqlite3ErrorMsg(pParse, "corrupt schema"); + sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb); + sqlite3MayAbort(pParse); +#ifndef SQLITE_OMIT_AUTOVACUUM + /* OP_Destroy stores an in integer r1. If this integer + ** is non-zero, then it is the root page number of a table moved to + ** location iTable. The following code modifies the sqlite_schema table to + ** reflect this. + ** + ** The "#NNN" in the SQL is a special constant that means whatever value + ** is in register NNN. See grammar rules associated with the TK_REGISTER + ** token for additional information. + */ + sqlite3NestedParse(pParse, + "UPDATE %Q." LEGACY_SCHEMA_TABLE + " SET rootpage=%d WHERE #%d AND rootpage=#%d", + pParse->db->aDb[iDb].zDbSName, iTable, r1, r1); +#endif + sqlite3ReleaseTempReg(pParse, r1); +} + +/* +** Write VDBE code to erase table pTab and all associated indices on disk. +** Code to update the sqlite_schema tables and internal schema definitions +** in case a root-page belonging to another table is moved by the btree layer +** is also added (this can happen with an auto-vacuum database). +*/ +static void destroyTable(Parse *pParse, Table *pTab){ + /* If the database may be auto-vacuum capable (if SQLITE_OMIT_AUTOVACUUM + ** is not defined), then it is important to call OP_Destroy on the + ** table and index root-pages in order, starting with the numerically + ** largest root-page number. This guarantees that none of the root-pages + ** to be destroyed is relocated by an earlier OP_Destroy. i.e. if the + ** following were coded: + ** + ** OP_Destroy 4 0 + ** ... + ** OP_Destroy 5 0 + ** + ** and root page 5 happened to be the largest root-page number in the + ** database, then root page 5 would be moved to page 4 by the + ** "OP_Destroy 4 0" opcode. The subsequent "OP_Destroy 5 0" would hit + ** a free-list page. + */ + Pgno iTab = pTab->tnum; + Pgno iDestroyed = 0; + + while( 1 ){ + Index *pIdx; + Pgno iLargest = 0; + + if( iDestroyed==0 || iTabpIndex; pIdx; pIdx=pIdx->pNext){ + Pgno iIdx = pIdx->tnum; + assert( pIdx->pSchema==pTab->pSchema ); + if( (iDestroyed==0 || (iIdxiLargest ){ + iLargest = iIdx; + } + } + if( iLargest==0 ){ + return; + }else{ + int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + assert( iDb>=0 && iDbdb->nDb ); + destroyRootPage(pParse, iLargest, iDb); + iDestroyed = iLargest; + } + } +} + +/* +** Remove entries from the sqlite_statN tables (for N in (1,2,3)) +** after a DROP INDEX or DROP TABLE command. +*/ +static void sqlite3ClearStatTables( + Parse *pParse, /* The parsing context */ + int iDb, /* The database number */ + const char *zType, /* "idx" or "tbl" */ + const char *zName /* Name of index or table */ +){ + int i; + const char *zDbName = pParse->db->aDb[iDb].zDbSName; + for(i=1; i<=4; i++){ + char zTab[24]; + sqlite3_snprintf(sizeof(zTab),zTab,"sqlite_stat%d",i); + if( sqlite3FindTable(pParse->db, zTab, zDbName) ){ + sqlite3NestedParse(pParse, + "DELETE FROM %Q.%s WHERE %s=%Q", + zDbName, zTab, zType, zName + ); + } + } +} + +/* +** Generate code to drop a table. +*/ +SQLITE_PRIVATE void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){ + Vdbe *v; + sqlite3 *db = pParse->db; + Trigger *pTrigger; + Db *pDb = &db->aDb[iDb]; + + v = sqlite3GetVdbe(pParse); + assert( v!=0 ); + sqlite3BeginWriteOperation(pParse, 1, iDb); + +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + sqlite3VdbeAddOp0(v, OP_VBegin); + } +#endif + + /* Drop all triggers associated with the table being dropped. Code + ** is generated to remove entries from sqlite_schema and/or + ** sqlite_temp_schema if required. + */ + pTrigger = sqlite3TriggerList(pParse, pTab); + while( pTrigger ){ + assert( pTrigger->pSchema==pTab->pSchema || + pTrigger->pSchema==db->aDb[1].pSchema ); + sqlite3DropTriggerPtr(pParse, pTrigger); + pTrigger = pTrigger->pNext; + } + +#ifndef SQLITE_OMIT_AUTOINCREMENT + /* Remove any entries of the sqlite_sequence table associated with + ** the table being dropped. This is done before the table is dropped + ** at the btree level, in case the sqlite_sequence table needs to + ** move as a result of the drop (can happen in auto-vacuum mode). + */ + if( pTab->tabFlags & TF_Autoincrement ){ + sqlite3NestedParse(pParse, + "DELETE FROM %Q.sqlite_sequence WHERE name=%Q", + pDb->zDbSName, pTab->zName + ); + } +#endif + + /* Drop all entries in the schema table that refer to the + ** table. The program name loops through the schema table and deletes + ** every row that refers to a table of the same name as the one being + ** dropped. Triggers are handled separately because a trigger can be + ** created in the temp database that refers to a table in another + ** database. + */ + sqlite3NestedParse(pParse, + "DELETE FROM %Q." LEGACY_SCHEMA_TABLE + " WHERE tbl_name=%Q and type!='trigger'", + pDb->zDbSName, pTab->zName); + if( !isView && !IsVirtual(pTab) ){ + destroyTable(pParse, pTab); + } + + /* Remove the table entry from SQLite's internal schema and modify + ** the schema cookie. + */ + if( IsVirtual(pTab) ){ + sqlite3VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0); + sqlite3MayAbort(pParse); + } + sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0); + sqlite3ChangeCookie(pParse, iDb); + sqliteViewResetAll(db, iDb); +} + +/* +** Return TRUE if shadow tables should be read-only in the current +** context. +*/ +SQLITE_PRIVATE int sqlite3ReadOnlyShadowTables(sqlite3 *db){ +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( (db->flags & SQLITE_Defensive)!=0 + && db->pVtabCtx==0 + && db->nVdbeExec==0 + && !sqlite3VtabInSync(db) + ){ + return 1; + } +#endif + return 0; +} + +/* +** Return true if it is not allowed to drop the given table +*/ +static int tableMayNotBeDropped(sqlite3 *db, Table *pTab){ + if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){ + if( sqlite3StrNICmp(pTab->zName+7, "stat", 4)==0 ) return 0; + if( sqlite3StrNICmp(pTab->zName+7, "parameters", 10)==0 ) return 0; + return 1; + } + if( (pTab->tabFlags & TF_Shadow)!=0 && sqlite3ReadOnlyShadowTables(db) ){ + return 1; + } + if( pTab->tabFlags & TF_Eponymous ){ + return 1; + } + return 0; +} + +/* +** This routine is called to do the work of a DROP TABLE statement. +** pName is the name of the table to be dropped. +*/ +SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ + Table *pTab; + Vdbe *v; + sqlite3 *db = pParse->db; + int iDb; + + if( db->mallocFailed ){ + goto exit_drop_table; + } + assert( pParse->nErr==0 ); + assert( pName->nSrc==1 ); + assert( pName->a[0].fg.fixedSchema==0 ); + assert( pName->a[0].fg.isSubquery==0 ); + if( sqlite3ReadSchema(pParse) ) goto exit_drop_table; + if( noErr ) db->suppressErr++; + assert( isView==0 || isView==LOCATE_VIEW ); + pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]); + if( noErr ) db->suppressErr--; + + if( pTab==0 ){ + if( noErr ){ + sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].u4.zDatabase); + sqlite3ForceNotReadOnly(pParse); + } + goto exit_drop_table; + } + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iDb>=0 && iDbnDb ); + + /* If pTab is a virtual table, call ViewGetColumnNames() to ensure + ** it is initialized. + */ + if( IsVirtual(pTab) && sqlite3ViewGetColumnNames(pParse, pTab) ){ + goto exit_drop_table; + } +#ifndef SQLITE_OMIT_AUTHORIZATION + { + int code; + const char *zTab = SCHEMA_TABLE(iDb); + const char *zDb = db->aDb[iDb].zDbSName; + const char *zArg2 = 0; + if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){ + goto exit_drop_table; + } + if( isView ){ + if( !OMIT_TEMPDB && iDb==1 ){ + code = SQLITE_DROP_TEMP_VIEW; + }else{ + code = SQLITE_DROP_VIEW; + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + }else if( IsVirtual(pTab) ){ + code = SQLITE_DROP_VTABLE; + zArg2 = sqlite3GetVTable(db, pTab)->pMod->zName; +#endif + }else{ + if( !OMIT_TEMPDB && iDb==1 ){ + code = SQLITE_DROP_TEMP_TABLE; + }else{ + code = SQLITE_DROP_TABLE; + } + } + if( sqlite3AuthCheck(pParse, code, pTab->zName, zArg2, zDb) ){ + goto exit_drop_table; + } + if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){ + goto exit_drop_table; + } + } +#endif + if( tableMayNotBeDropped(db, pTab) ){ + sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName); + goto exit_drop_table; + } + +#ifndef SQLITE_OMIT_VIEW + /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used + ** on a table. + */ + if( isView && !IsView(pTab) ){ + sqlite3ErrorMsg(pParse, "use DROP TABLE to delete table %s", pTab->zName); + goto exit_drop_table; + } + if( !isView && IsView(pTab) ){ + sqlite3ErrorMsg(pParse, "use DROP VIEW to delete view %s", pTab->zName); + goto exit_drop_table; + } +#endif + + /* Generate code to remove the table from the schema table + ** on disk. + */ + v = sqlite3GetVdbe(pParse); + if( v ){ + sqlite3BeginWriteOperation(pParse, 1, iDb); + if( !isView ){ + sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName); + sqlite3FkDropTable(pParse, pName, pTab); + } + sqlite3CodeDropTable(pParse, pTab, iDb, isView); + } + +exit_drop_table: + sqlite3SrcListDelete(db, pName); +} + +/* +** This routine is called to create a new foreign key on the table +** currently under construction. pFromCol determines which columns +** in the current table point to the foreign key. If pFromCol==0 then +** connect the key to the last column inserted. pTo is the name of +** the table referred to (a.k.a the "parent" table). pToCol is a list +** of tables in the parent pTo table. flags contains all +** information about the conflict resolution algorithms specified +** in the ON DELETE, ON UPDATE and ON INSERT clauses. +** +** An FKey structure is created and added to the table currently +** under construction in the pParse->pNewTable field. +** +** The foreign key is set for IMMEDIATE processing. A subsequent call +** to sqlite3DeferForeignKey() might change this to DEFERRED. +*/ +SQLITE_PRIVATE void sqlite3CreateForeignKey( + Parse *pParse, /* Parsing context */ + ExprList *pFromCol, /* Columns in this table that point to other table */ + Token *pTo, /* Name of the other table */ + ExprList *pToCol, /* Columns in the other table */ + int flags /* Conflict resolution algorithms. */ +){ + sqlite3 *db = pParse->db; +#ifndef SQLITE_OMIT_FOREIGN_KEY + FKey *pFKey = 0; + FKey *pNextTo; + Table *p = pParse->pNewTable; + i64 nByte; + int i; + int nCol; + char *z; + + assert( pTo!=0 ); + if( p==0 || IN_DECLARE_VTAB ) goto fk_end; + if( pFromCol==0 ){ + int iCol = p->nCol-1; + if( NEVER(iCol<0) ) goto fk_end; + if( pToCol && pToCol->nExpr!=1 ){ + sqlite3ErrorMsg(pParse, "foreign key on %s" + " should reference only one column of table %T", + p->aCol[iCol].zCnName, pTo); + goto fk_end; + } + nCol = 1; + }else if( pToCol && pToCol->nExpr!=pFromCol->nExpr ){ + sqlite3ErrorMsg(pParse, + "number of columns in foreign key does not match the number of " + "columns in the referenced table"); + goto fk_end; + }else{ + nCol = pFromCol->nExpr; + } + nByte = SZ_FKEY(nCol) + pTo->n + 1; + if( pToCol ){ + for(i=0; inExpr; i++){ + nByte += sqlite3Strlen30(pToCol->a[i].zEName) + 1; + } + } + pFKey = sqlite3DbMallocZero(db, nByte ); + if( pFKey==0 ){ + goto fk_end; + } + pFKey->pFrom = p; + assert( IsOrdinaryTable(p) ); + pFKey->pNextFrom = p->u.tab.pFKey; + z = (char*)&pFKey->aCol[nCol]; + pFKey->zTo = z; + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenMap(pParse, (void*)z, pTo); + } + memcpy(z, pTo->z, pTo->n); + z[pTo->n] = 0; + sqlite3Dequote(z); + z += pTo->n+1; + pFKey->nCol = nCol; + if( pFromCol==0 ){ + pFKey->aCol[0].iFrom = p->nCol-1; + }else{ + for(i=0; inCol; j++){ + if( sqlite3StrICmp(p->aCol[j].zCnName, pFromCol->a[i].zEName)==0 ){ + pFKey->aCol[i].iFrom = j; + break; + } + } + if( j>=p->nCol ){ + sqlite3ErrorMsg(pParse, + "unknown column \"%s\" in foreign key definition", + pFromCol->a[i].zEName); + goto fk_end; + } + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, &pFKey->aCol[i], pFromCol->a[i].zEName); + } + } + } + if( pToCol ){ + for(i=0; ia[i].zEName); + pFKey->aCol[i].zCol = z; + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, z, pToCol->a[i].zEName); + } + memcpy(z, pToCol->a[i].zEName, n); + z[n] = 0; + z += n+1; + } + } + pFKey->isDeferred = 0; + pFKey->aAction[0] = (u8)(flags & 0xff); /* ON DELETE action */ + pFKey->aAction[1] = (u8)((flags >> 8 ) & 0xff); /* ON UPDATE action */ + + assert( sqlite3SchemaMutexHeld(db, 0, p->pSchema) ); + pNextTo = (FKey *)sqlite3HashInsert(&p->pSchema->fkeyHash, + pFKey->zTo, (void *)pFKey + ); + if( pNextTo==pFKey ){ + sqlite3OomFault(db); + goto fk_end; + } + if( pNextTo ){ + assert( pNextTo->pPrevTo==0 ); + pFKey->pNextTo = pNextTo; + pNextTo->pPrevTo = pFKey; + } + + /* Link the foreign key to the table as the last step. + */ + assert( IsOrdinaryTable(p) ); + p->u.tab.pFKey = pFKey; + pFKey = 0; + +fk_end: + sqlite3DbFree(db, pFKey); +#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ + sqlite3ExprListDelete(db, pFromCol); + sqlite3ExprListDelete(db, pToCol); +} + +/* +** This routine is called when an INITIALLY IMMEDIATE or INITIALLY DEFERRED +** clause is seen as part of a foreign key definition. The isDeferred +** parameter is 1 for INITIALLY DEFERRED and 0 for INITIALLY IMMEDIATE. +** The behavior of the most recently created foreign key is adjusted +** accordingly. +*/ +SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse *pParse, int isDeferred){ +#ifndef SQLITE_OMIT_FOREIGN_KEY + Table *pTab; + FKey *pFKey; + if( (pTab = pParse->pNewTable)==0 ) return; + if( NEVER(!IsOrdinaryTable(pTab)) ) return; + if( (pFKey = pTab->u.tab.pFKey)==0 ) return; + assert( isDeferred==0 || isDeferred==1 ); /* EV: R-30323-21917 */ + pFKey->isDeferred = (u8)isDeferred; +#endif +} + +/* +** Generate code that will erase and refill index *pIdx. This is +** used to initialize a newly created index or to recompute the +** content of an index in response to a REINDEX command. +** +** if memRootPage is not negative, it means that the index is newly +** created. The register specified by memRootPage contains the +** root page number of the index. If memRootPage is negative, then +** the index already exists and must be cleared before being refilled and +** the root page number of the index is taken from pIndex->tnum. +*/ +static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ + Table *pTab = pIndex->pTable; /* The table that is indexed */ + int iTab = pParse->nTab++; /* Btree cursor used for pTab */ + int iIdx = pParse->nTab++; /* Btree cursor used for pIndex */ + int iSorter; /* Cursor opened by OpenSorter (if in use) */ + int addr1; /* Address of top of loop */ + int addr2; /* Address to jump to for next iteration */ + Pgno tnum; /* Root page of index */ + int iPartIdxLabel; /* Jump to this label to skip a row */ + Vdbe *v; /* Generate code into this virtual machine */ + KeyInfo *pKey; /* KeyInfo for index */ + int regRecord; /* Register holding assembled index record */ + sqlite3 *db = pParse->db; /* The database connection */ + int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); + +#ifndef SQLITE_OMIT_AUTHORIZATION + if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0, + db->aDb[iDb].zDbSName ) ){ + return; + } +#endif + + /* Require a write-lock on the table to perform this operation */ + sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName); + + v = sqlite3GetVdbe(pParse); + if( v==0 ) return; + if( memRootPage>=0 ){ + tnum = (Pgno)memRootPage; + }else{ + tnum = pIndex->tnum; + } + pKey = sqlite3KeyInfoOfIndex(pParse, pIndex); + assert( pKey!=0 || pParse->nErr ); + + /* Open the sorter cursor if we are to use one. */ + iSorter = pParse->nTab++; + sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, pIndex->nKeyCol, (char*) + sqlite3KeyInfoRef(pKey), P4_KEYINFO); + + /* Open the table. Loop through all rows of the table, inserting index + ** records into the sorter. */ + sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); + addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); VdbeCoverage(v); + regRecord = sqlite3GetTempReg(pParse); + sqlite3MultiWrite(pParse); + + sqlite3GenerateIndexKey(pParse,pIndex,iTab,regRecord,0,&iPartIdxLabel,0,0); + sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord); + sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel); + sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr1); + if( memRootPage<0 ) sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb); + sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, (int)tnum, iDb, + (char *)pKey, P4_KEYINFO); + sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0)); + + addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v); + if( IsUniqueIndex(pIndex) ){ + int j2 = sqlite3VdbeGoto(v, 1); + addr2 = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeVerifyAbortable(v, OE_Abort); + sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord, + pIndex->nKeyCol); VdbeCoverage(v); + sqlite3UniqueConstraint(pParse, OE_Abort, pIndex); + sqlite3VdbeJumpHere(v, j2); + }else{ + /* Most CREATE INDEX and REINDEX statements that are not UNIQUE can not + ** abort. The exception is if one of the indexed expressions contains a + ** user function that throws an exception when it is evaluated. But the + ** overhead of adding a statement journal to a CREATE INDEX statement is + ** very small (since most of the pages written do not contain content that + ** needs to be restored if the statement aborts), so we call + ** sqlite3MayAbort() for all CREATE INDEX statements. */ + sqlite3MayAbort(pParse); + addr2 = sqlite3VdbeCurrentAddr(v); + } + sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx); + if( !pIndex->bAscKeyBug ){ + /* This OP_SeekEnd opcode makes index insert for a REINDEX go much + ** faster by avoiding unnecessary seeks. But the optimization does + ** not work for UNIQUE constraint indexes on WITHOUT ROWID tables + ** with DESC primary keys, since those indexes have there keys in + ** a different order from the main table. + ** See ticket: https://sqlite.org/src/info/bba7b69f9849b5bf + */ + sqlite3VdbeAddOp1(v, OP_SeekEnd, iIdx); + } + sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord); + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + sqlite3ReleaseTempReg(pParse, regRecord); + sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr1); + + sqlite3VdbeAddOp1(v, OP_Close, iTab); + sqlite3VdbeAddOp1(v, OP_Close, iIdx); + sqlite3VdbeAddOp1(v, OP_Close, iSorter); +} + +/* +** Allocate heap space to hold an Index object with nCol columns. +** +** Increase the allocation size to provide an extra nExtra bytes +** of 8-byte aligned space after the Index object and return a +** pointer to this extra space in *ppExtra. +*/ +SQLITE_PRIVATE Index *sqlite3AllocateIndexObject( + sqlite3 *db, /* Database connection */ + int nCol, /* Total number of columns in the index */ + int nExtra, /* Number of bytes of extra space to alloc */ + char **ppExtra /* Pointer to the "extra" space */ +){ + Index *p; /* Allocated index object */ + i64 nByte; /* Bytes of space for Index object + arrays */ + + assert( nCol <= 2*db->aLimit[SQLITE_LIMIT_COLUMN] ); + nByte = ROUND8(sizeof(Index)) + /* Index structure */ + ROUND8(sizeof(char*)*nCol) + /* Index.azColl */ + ROUND8(sizeof(LogEst)*(nCol+1) + /* Index.aiRowLogEst */ + sizeof(i16)*nCol + /* Index.aiColumn */ + sizeof(u8)*nCol); /* Index.aSortOrder */ + p = sqlite3DbMallocZero(db, nByte + nExtra); + if( p ){ + char *pExtra = ((char*)p)+ROUND8(sizeof(Index)); + p->azColl = (const char**)pExtra; pExtra += ROUND8(sizeof(char*)*nCol); + p->aiRowLogEst = (LogEst*)pExtra; pExtra += sizeof(LogEst)*(nCol+1); + p->aiColumn = (i16*)pExtra; pExtra += sizeof(i16)*nCol; + p->aSortOrder = (u8*)pExtra; + assert( nCol>0 ); + p->nColumn = (u16)nCol; + p->nKeyCol = (u16)(nCol - 1); + *ppExtra = ((char*)p) + nByte; + } + return p; +} + +/* +** If expression list pList contains an expression that was parsed with +** an explicit "NULLS FIRST" or "NULLS LAST" clause, leave an error in +** pParse and return non-zero. Otherwise, return zero. +*/ +SQLITE_PRIVATE int sqlite3HasExplicitNulls(Parse *pParse, ExprList *pList){ + if( pList ){ + int i; + for(i=0; inExpr; i++){ + if( pList->a[i].fg.bNulls ){ + u8 sf = pList->a[i].fg.sortFlags; + sqlite3ErrorMsg(pParse, "unsupported use of NULLS %s", + (sf==0 || sf==3) ? "FIRST" : "LAST" + ); + return 1; + } + } + } + return 0; +} + +/* +** Create a new index for an SQL table. pName1.pName2 is the name of the index +** and pTblList is the name of the table that is to be indexed. Both will +** be NULL for a primary key or an index that is created to satisfy a +** UNIQUE constraint. If pTable and pIndex are NULL, use pParse->pNewTable +** as the table to be indexed. pParse->pNewTable is a table that is +** currently being constructed by a CREATE TABLE statement. +** +** pList is a list of columns to be indexed. pList will be NULL if this +** is a primary key or unique-constraint on the most recent column added +** to the table currently under construction. +*/ +SQLITE_PRIVATE void sqlite3CreateIndex( + Parse *pParse, /* All information about this parse */ + Token *pName1, /* First part of index name. May be NULL */ + Token *pName2, /* Second part of index name. May be NULL */ + SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */ + ExprList *pList, /* A list of columns to be indexed */ + int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ + Token *pStart, /* The CREATE token that begins this statement */ + Expr *pPIWhere, /* WHERE clause for partial indices */ + int sortOrder, /* Sort order of primary key when pList==NULL */ + int ifNotExist, /* Omit error if index already exists */ + u8 idxType /* The index type */ +){ + Table *pTab = 0; /* Table to be indexed */ + Index *pIndex = 0; /* The index to be created */ + char *zName = 0; /* Name of the index */ + int nName; /* Number of characters in zName */ + int i, j; + DbFixer sFix; /* For assigning database names to pTable */ + int sortOrderMask; /* 1 to honor DESC in index. 0 to ignore. */ + sqlite3 *db = pParse->db; + Db *pDb; /* The specific table containing the indexed database */ + int iDb; /* Index of the database that is being written */ + Token *pName = 0; /* Unqualified name of the index to create */ + struct ExprList_item *pListItem; /* For looping over pList */ + int nExtra = 0; /* Space allocated for zExtra[] */ + int nExtraCol; /* Number of extra columns needed */ + char *zExtra = 0; /* Extra space after the Index object */ + Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */ + + assert( db->pParse==pParse ); + if( pParse->nErr ){ + goto exit_create_index; + } + assert( db->mallocFailed==0 ); + if( IN_DECLARE_VTAB && idxType!=SQLITE_IDXTYPE_PRIMARYKEY ){ + goto exit_create_index; + } + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + goto exit_create_index; + } + if( sqlite3HasExplicitNulls(pParse, pList) ){ + goto exit_create_index; + } + + /* + ** Find the table that is to be indexed. Return early if not found. + */ + if( pTblName!=0 ){ + + /* Use the two-part index name to determine the database + ** to search for the table. 'Fix' the table name to this db + ** before looking up the table. + */ + assert( pName1 && pName2 ); + iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName); + if( iDb<0 ) goto exit_create_index; + assert( pName && pName->z ); + +#ifndef SQLITE_OMIT_TEMPDB + /* If the index name was unqualified, check if the table + ** is a temp table. If so, set the database to 1. Do not do this + ** if initializing a database schema. + */ + if( !db->init.busy ){ + pTab = sqlite3SrcListLookup(pParse, pTblName); + if( pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){ + iDb = 1; + } + } +#endif + + sqlite3FixInit(&sFix, pParse, iDb, "index", pName); + if( sqlite3FixSrcList(&sFix, pTblName) ){ + /* Because the parser constructs pTblName from a single identifier, + ** sqlite3FixSrcList can never fail. */ + assert(0); + } + pTab = sqlite3LocateTableItem(pParse, 0, &pTblName->a[0]); + assert( db->mallocFailed==0 || pTab==0 ); + if( pTab==0 ) goto exit_create_index; + if( iDb==1 && db->aDb[iDb].pSchema!=pTab->pSchema ){ + sqlite3ErrorMsg(pParse, + "cannot create a TEMP index on non-TEMP table \"%s\"", + pTab->zName); + goto exit_create_index; + } + if( !HasRowid(pTab) ) pPk = sqlite3PrimaryKeyIndex(pTab); + }else{ + assert( pName==0 ); + assert( pStart==0 ); + pTab = pParse->pNewTable; + if( !pTab ) goto exit_create_index; + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + } + pDb = &db->aDb[iDb]; + + assert( pTab!=0 ); + if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 + && db->init.busy==0 + && pTblName!=0 + ){ + sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName); + goto exit_create_index; + } +#ifndef SQLITE_OMIT_VIEW + if( IsView(pTab) ){ + sqlite3ErrorMsg(pParse, "views may not be indexed"); + goto exit_create_index; + } +#endif +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + sqlite3ErrorMsg(pParse, "virtual tables may not be indexed"); + goto exit_create_index; + } +#endif + + /* + ** Find the name of the index. Make sure there is not already another + ** index or table with the same name. + ** + ** Exception: If we are reading the names of permanent indices from the + ** sqlite_schema table (because some other process changed the schema) and + ** one of the index names collides with the name of a temporary table or + ** index, then we will continue to process this index. + ** + ** If pName==0 it means that we are + ** dealing with a primary key or UNIQUE constraint. We have to invent our + ** own name. + */ + if( pName ){ + zName = sqlite3NameFromToken(db, pName); + if( zName==0 ) goto exit_create_index; + assert( pName->z!=0 ); + if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName,"index",pTab->zName) ){ + goto exit_create_index; + } + if( !IN_RENAME_OBJECT ){ + if( !db->init.busy ){ + if( sqlite3FindTable(db, zName, pDb->zDbSName)!=0 ){ + sqlite3ErrorMsg(pParse, "there is already a table named %s", zName); + goto exit_create_index; + } + } + if( sqlite3FindIndex(db, zName, pDb->zDbSName)!=0 ){ + if( !ifNotExist ){ + sqlite3ErrorMsg(pParse, "index %s already exists", zName); + }else{ + assert( !db->init.busy ); + sqlite3CodeVerifySchema(pParse, iDb); + sqlite3ForceNotReadOnly(pParse); + } + goto exit_create_index; + } + } + }else{ + int n; + Index *pLoop; + for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){} + zName = sqlite3MPrintf(db, "sqlite_autoindex_%s_%d", pTab->zName, n); + if( zName==0 ){ + goto exit_create_index; + } + + /* Automatic index names generated from within sqlite3_declare_vtab() + ** must have names that are distinct from normal automatic index names. + ** The following statement converts "sqlite3_autoindex..." into + ** "sqlite3_butoindex..." in order to make the names distinct. + ** The "vtab_err.test" test demonstrates the need of this statement. */ + if( IN_SPECIAL_PARSE ) zName[7]++; + } + + /* Check for authorization to create an index. + */ +#ifndef SQLITE_OMIT_AUTHORIZATION + if( !IN_RENAME_OBJECT ){ + const char *zDb = pDb->zDbSName; + if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){ + goto exit_create_index; + } + i = SQLITE_CREATE_INDEX; + if( !OMIT_TEMPDB && iDb==1 ) i = SQLITE_CREATE_TEMP_INDEX; + if( sqlite3AuthCheck(pParse, i, zName, pTab->zName, zDb) ){ + goto exit_create_index; + } + } +#endif + + /* If pList==0, it means this routine was called to make a primary + ** key out of the last column added to the table under construction. + ** So create a fake list to simulate this. + */ + if( pList==0 ){ + Token prevCol; + Column *pCol = &pTab->aCol[pTab->nCol-1]; + pCol->colFlags |= COLFLAG_UNIQUE; + sqlite3TokenInit(&prevCol, pCol->zCnName); + pList = sqlite3ExprListAppend(pParse, 0, + sqlite3ExprAlloc(db, TK_ID, &prevCol, 0)); + if( pList==0 ) goto exit_create_index; + assert( pList->nExpr==1 ); + sqlite3ExprListSetSortOrder(pList, sortOrder, SQLITE_SO_UNDEFINED); + }else{ + sqlite3ExprListCheckLength(pParse, pList, "index"); + if( pParse->nErr ) goto exit_create_index; + } + + /* Figure out how many bytes of space are required to store explicitly + ** specified collation sequence names. + */ + for(i=0; inExpr; i++){ + Expr *pExpr = pList->a[i].pExpr; + assert( pExpr!=0 ); + if( pExpr->op==TK_COLLATE ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + nExtra += (1 + sqlite3Strlen30(pExpr->u.zToken)); + } + } + + /* + ** Allocate the index structure. + */ + nName = sqlite3Strlen30(zName); + nExtraCol = pPk ? pPk->nKeyCol : 1; + assert( pList->nExpr + nExtraCol <= 32767 /* Fits in i16 */ ); + pIndex = sqlite3AllocateIndexObject(db, pList->nExpr + nExtraCol, + nName + nExtra + 1, &zExtra); + if( db->mallocFailed ){ + goto exit_create_index; + } + assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowLogEst) ); + assert( EIGHT_BYTE_ALIGNMENT(pIndex->azColl) ); + pIndex->zName = zExtra; + zExtra += nName + 1; + memcpy(pIndex->zName, zName, nName+1); + pIndex->pTable = pTab; + pIndex->onError = (u8)onError; + pIndex->uniqNotNull = onError!=OE_None; + pIndex->idxType = idxType; + pIndex->pSchema = db->aDb[iDb].pSchema; + pIndex->nKeyCol = pList->nExpr; + if( pPIWhere ){ + sqlite3ResolveSelfReference(pParse, pTab, NC_PartIdx, pPIWhere, 0); + pIndex->pPartIdxWhere = pPIWhere; + pPIWhere = 0; + } + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + + /* Check to see if we should honor DESC requests on index columns + */ + if( pDb->pSchema->file_format>=4 ){ + sortOrderMask = -1; /* Honor DESC */ + }else{ + sortOrderMask = 0; /* Ignore DESC */ + } + + /* Analyze the list of expressions that form the terms of the index and + ** report any errors. In the common case where the expression is exactly + ** a table column, store that column in aiColumn[]. For general expressions, + ** populate pIndex->aColExpr and store XN_EXPR (-2) in aiColumn[]. + ** + ** TODO: Issue a warning if two or more columns of the index are identical. + ** TODO: Issue a warning if the table primary key is used as part of the + ** index key. + */ + pListItem = pList->a; + if( IN_RENAME_OBJECT ){ + pIndex->aColExpr = pList; + pList = 0; + } + for(i=0; inKeyCol; i++, pListItem++){ + Expr *pCExpr; /* The i-th index expression */ + int requestedSortOrder; /* ASC or DESC on the i-th expression */ + const char *zColl; /* Collation sequence name */ + + sqlite3StringToId(pListItem->pExpr); + sqlite3ResolveSelfReference(pParse, pTab, NC_IdxExpr, pListItem->pExpr, 0); + if( pParse->nErr ) goto exit_create_index; + pCExpr = sqlite3ExprSkipCollate(pListItem->pExpr); + if( pCExpr->op!=TK_COLUMN ){ + if( pTab==pParse->pNewTable ){ + sqlite3ErrorMsg(pParse, "expressions prohibited in PRIMARY KEY and " + "UNIQUE constraints"); + goto exit_create_index; + } + if( pIndex->aColExpr==0 ){ + pIndex->aColExpr = pList; + pList = 0; + } + j = XN_EXPR; + pIndex->aiColumn[i] = XN_EXPR; + pIndex->uniqNotNull = 0; + pIndex->bHasExpr = 1; + }else{ + j = pCExpr->iColumn; + assert( j<=0x7fff ); + if( j<0 ){ + j = pTab->iPKey; + }else{ + if( pTab->aCol[j].notNull==0 ){ + pIndex->uniqNotNull = 0; + } + if( pTab->aCol[j].colFlags & COLFLAG_VIRTUAL ){ + pIndex->bHasVCol = 1; + pIndex->bHasExpr = 1; + } + } + pIndex->aiColumn[i] = (i16)j; + } + zColl = 0; + if( pListItem->pExpr->op==TK_COLLATE ){ + int nColl; + assert( !ExprHasProperty(pListItem->pExpr, EP_IntValue) ); + zColl = pListItem->pExpr->u.zToken; + nColl = sqlite3Strlen30(zColl) + 1; + assert( nExtra>=nColl ); + memcpy(zExtra, zColl, nColl); + zColl = zExtra; + zExtra += nColl; + nExtra -= nColl; + }else if( j>=0 ){ + zColl = sqlite3ColumnColl(&pTab->aCol[j]); + } + if( !zColl ) zColl = sqlite3StrBINARY; + if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){ + goto exit_create_index; + } + pIndex->azColl[i] = zColl; + requestedSortOrder = pListItem->fg.sortFlags & sortOrderMask; + pIndex->aSortOrder[i] = (u8)requestedSortOrder; + } + + /* Append the table key to the end of the index. For WITHOUT ROWID + ** tables (when pPk!=0) this will be the declared PRIMARY KEY. For + ** normal tables (when pPk==0) this will be the rowid. + */ + if( pPk ){ + for(j=0; jnKeyCol; j++){ + int x = pPk->aiColumn[j]; + assert( x>=0 ); + if( isDupColumn(pIndex, pIndex->nKeyCol, pPk, j) ){ + pIndex->nColumn--; + }else{ + testcase( hasColumn(pIndex->aiColumn,pIndex->nKeyCol,x) ); + pIndex->aiColumn[i] = x; + pIndex->azColl[i] = pPk->azColl[j]; + pIndex->aSortOrder[i] = pPk->aSortOrder[j]; + i++; + } + } + assert( i==pIndex->nColumn ); + }else{ + pIndex->aiColumn[i] = XN_ROWID; + pIndex->azColl[i] = sqlite3StrBINARY; + } + sqlite3DefaultRowEst(pIndex); + if( pParse->pNewTable==0 ) estimateIndexWidth(pIndex); + + /* If this index contains every column of its table, then mark + ** it as a covering index */ + assert( HasRowid(pTab) + || pTab->iPKey<0 || sqlite3TableColumnToIndex(pIndex, pTab->iPKey)>=0 ); + recomputeColumnsNotIndexed(pIndex); + if( pTblName!=0 && pIndex->nColumn>=pTab->nCol ){ + pIndex->isCovering = 1; + for(j=0; jnCol; j++){ + if( j==pTab->iPKey ) continue; + if( sqlite3TableColumnToIndex(pIndex,j)>=0 ) continue; + pIndex->isCovering = 0; + break; + } + } + + if( pTab==pParse->pNewTable ){ + /* This routine has been called to create an automatic index as a + ** result of a PRIMARY KEY or UNIQUE clause on a column definition, or + ** a PRIMARY KEY or UNIQUE clause following the column definitions. + ** i.e. one of: + ** + ** CREATE TABLE t(x PRIMARY KEY, y); + ** CREATE TABLE t(x, y, UNIQUE(x, y)); + ** + ** Either way, check to see if the table already has such an index. If + ** so, don't bother creating this one. This only applies to + ** automatically created indices. Users can do as they wish with + ** explicit indices. + ** + ** Two UNIQUE or PRIMARY KEY constraints are considered equivalent + ** (and thus suppressing the second one) even if they have different + ** sort orders. + ** + ** If there are different collating sequences or if the columns of + ** the constraint occur in different orders, then the constraints are + ** considered distinct and both result in separate indices. + */ + Index *pIdx; + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + int k; + assert( IsUniqueIndex(pIdx) ); + assert( pIdx->idxType!=SQLITE_IDXTYPE_APPDEF ); + assert( IsUniqueIndex(pIndex) ); + + if( pIdx->nKeyCol!=pIndex->nKeyCol ) continue; + for(k=0; knKeyCol; k++){ + const char *z1; + const char *z2; + assert( pIdx->aiColumn[k]>=0 ); + if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break; + z1 = pIdx->azColl[k]; + z2 = pIndex->azColl[k]; + if( sqlite3StrICmp(z1, z2) ) break; + } + if( k==pIdx->nKeyCol ){ + if( pIdx->onError!=pIndex->onError ){ + /* This constraint creates the same index as a previous + ** constraint specified somewhere in the CREATE TABLE statement. + ** However the ON CONFLICT clauses are different. If both this + ** constraint and the previous equivalent constraint have explicit + ** ON CONFLICT clauses this is an error. Otherwise, use the + ** explicitly specified behavior for the index. + */ + if( !(pIdx->onError==OE_Default || pIndex->onError==OE_Default) ){ + sqlite3ErrorMsg(pParse, + "conflicting ON CONFLICT clauses specified", 0); + } + if( pIdx->onError==OE_Default ){ + pIdx->onError = pIndex->onError; + } + } + if( idxType==SQLITE_IDXTYPE_PRIMARYKEY ) pIdx->idxType = idxType; + if( IN_RENAME_OBJECT ){ + pIndex->pNext = pParse->pNewIndex; + pParse->pNewIndex = pIndex; + pIndex = 0; + } + goto exit_create_index; + } + } + } + + if( !IN_RENAME_OBJECT ){ + + /* Link the new Index structure to its table and to the other + ** in-memory database structures. + */ + assert( pParse->nErr==0 ); + if( db->init.busy ){ + Index *p; + assert( !IN_SPECIAL_PARSE ); + assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); + if( pTblName!=0 ){ + pIndex->tnum = db->init.newTnum; + if( sqlite3IndexHasDuplicateRootPage(pIndex) ){ + sqlite3ErrorMsg(pParse, "invalid rootpage"); + pParse->rc = SQLITE_CORRUPT_BKPT; + goto exit_create_index; + } + } + p = sqlite3HashInsert(&pIndex->pSchema->idxHash, + pIndex->zName, pIndex); + if( p ){ + assert( p==pIndex ); /* Malloc must have failed */ + sqlite3OomFault(db); + goto exit_create_index; + } + db->mDbFlags |= DBFLAG_SchemaChange; + } + + /* If this is the initial CREATE INDEX statement (or CREATE TABLE if the + ** index is an implied index for a UNIQUE or PRIMARY KEY constraint) then + ** emit code to allocate the index rootpage on disk and make an entry for + ** the index in the sqlite_schema table and populate the index with + ** content. But, do not do this if we are simply reading the sqlite_schema + ** table to parse the schema, or if this index is the PRIMARY KEY index + ** of a WITHOUT ROWID table. + ** + ** If pTblName==0 it means this index is generated as an implied PRIMARY KEY + ** or UNIQUE index in a CREATE TABLE statement. Since the table + ** has just been created, it contains no data and the index initialization + ** step can be skipped. + */ + else if( HasRowid(pTab) || pTblName!=0 ){ + Vdbe *v; + char *zStmt; + int iMem = ++pParse->nMem; + + v = sqlite3GetVdbe(pParse); + if( v==0 ) goto exit_create_index; + + sqlite3BeginWriteOperation(pParse, 1, iDb); + + /* Create the rootpage for the index using CreateIndex. But before + ** doing so, code a Noop instruction and store its address in + ** Index.tnum. This is required in case this index is actually a + ** PRIMARY KEY and the table is actually a WITHOUT ROWID table. In + ** that case the convertToWithoutRowidTable() routine will replace + ** the Noop with a Goto to jump over the VDBE code generated below. */ + pIndex->tnum = (Pgno)sqlite3VdbeAddOp0(v, OP_Noop); + sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, iMem, BTREE_BLOBKEY); + + /* Gather the complete text of the CREATE INDEX statement into + ** the zStmt variable + */ + assert( pName!=0 || pStart==0 ); + if( pStart ){ + int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n; + if( pName->z[n-1]==';' ) n--; + /* A named index with an explicit CREATE INDEX statement */ + zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s", + onError==OE_None ? "" : " UNIQUE", n, pName->z); + }else{ + /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */ + /* zStmt = sqlite3MPrintf(""); */ + zStmt = 0; + } + + /* Add an entry in sqlite_schema for this index + */ + sqlite3NestedParse(pParse, + "INSERT INTO %Q." LEGACY_SCHEMA_TABLE " VALUES('index',%Q,%Q,#%d,%Q);", + db->aDb[iDb].zDbSName, + pIndex->zName, + pTab->zName, + iMem, + zStmt + ); + sqlite3DbFree(db, zStmt); + + /* Fill the index with data and reparse the schema. Code an OP_Expire + ** to invalidate all pre-compiled statements. + */ + if( pTblName ){ + sqlite3RefillIndex(pParse, pIndex, iMem); + sqlite3ChangeCookie(pParse, iDb); + sqlite3VdbeAddParseSchemaOp(v, iDb, + sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName), 0); + sqlite3VdbeAddOp2(v, OP_Expire, 0, 1); + } + + sqlite3VdbeJumpHere(v, (int)pIndex->tnum); + } + } + if( db->init.busy || pTblName==0 ){ + pIndex->pNext = pTab->pIndex; + pTab->pIndex = pIndex; + pIndex = 0; + } + else if( IN_RENAME_OBJECT ){ + assert( pParse->pNewIndex==0 ); + pParse->pNewIndex = pIndex; + pIndex = 0; + } + + /* Clean up before exiting */ +exit_create_index: + if( pIndex ) sqlite3FreeIndex(db, pIndex); + if( pTab ){ + /* Ensure all REPLACE indexes on pTab are at the end of the pIndex list. + ** The list was already ordered when this routine was entered, so at this + ** point at most a single index (the newly added index) will be out of + ** order. So we have to reorder at most one index. */ + Index **ppFrom; + Index *pThis; + for(ppFrom=&pTab->pIndex; (pThis = *ppFrom)!=0; ppFrom=&pThis->pNext){ + Index *pNext; + if( pThis->onError!=OE_Replace ) continue; + while( (pNext = pThis->pNext)!=0 && pNext->onError!=OE_Replace ){ + *ppFrom = pNext; + pThis->pNext = pNext->pNext; + pNext->pNext = pThis; + ppFrom = &pNext->pNext; + } + break; + } +#ifdef SQLITE_DEBUG + /* Verify that all REPLACE indexes really are now at the end + ** of the index list. In other words, no other index type ever + ** comes after a REPLACE index on the list. */ + for(pThis = pTab->pIndex; pThis; pThis=pThis->pNext){ + assert( pThis->onError!=OE_Replace + || pThis->pNext==0 + || pThis->pNext->onError==OE_Replace ); + } +#endif + } + sqlite3ExprDelete(db, pPIWhere); + sqlite3ExprListDelete(db, pList); + sqlite3SrcListDelete(db, pTblName); + sqlite3DbFree(db, zName); +} + +/* +** Fill the Index.aiRowEst[] array with default information - information +** to be used when we have not run the ANALYZE command. +** +** aiRowEst[0] is supposed to contain the number of elements in the index. +** Since we do not know, guess 1 million. aiRowEst[1] is an estimate of the +** number of rows in the table that match any particular value of the +** first column of the index. aiRowEst[2] is an estimate of the number +** of rows that match any particular combination of the first 2 columns +** of the index. And so forth. It must always be the case that +* +** aiRowEst[N]<=aiRowEst[N-1] +** aiRowEst[N]>=1 +** +** Apart from that, we have little to go on besides intuition as to +** how aiRowEst[] should be initialized. The numbers generated here +** are based on typical values found in actual indices. +*/ +SQLITE_PRIVATE void sqlite3DefaultRowEst(Index *pIdx){ + /* 10, 9, 8, 7, 6 */ + static const LogEst aVal[] = { 33, 32, 30, 28, 26 }; + LogEst *a = pIdx->aiRowLogEst; + LogEst x; + int nCopy = MIN(ArraySize(aVal), pIdx->nKeyCol); + int i; + + /* Indexes with default row estimates should not have stat1 data */ + assert( !pIdx->hasStat1 ); + + /* Set the first entry (number of rows in the index) to the estimated + ** number of rows in the table, or half the number of rows in the table + ** for a partial index. + ** + ** 2020-05-27: If some of the stat data is coming from the sqlite_stat1 + ** table but other parts we are having to guess at, then do not let the + ** estimated number of rows in the table be less than 1000 (LogEst 99). + ** Failure to do this can cause the indexes for which we do not have + ** stat1 data to be ignored by the query planner. + */ + x = pIdx->pTable->nRowLogEst; + assert( 99==sqlite3LogEst(1000) ); + if( x<99 ){ + pIdx->pTable->nRowLogEst = x = 99; + } + if( pIdx->pPartIdxWhere!=0 ){ x -= 10; assert( 10==sqlite3LogEst(2) ); } + a[0] = x; + + /* Estimate that a[1] is 10, a[2] is 9, a[3] is 8, a[4] is 7, a[5] is + ** 6 and each subsequent value (if any) is 5. */ + memcpy(&a[1], aVal, nCopy*sizeof(LogEst)); + for(i=nCopy+1; i<=pIdx->nKeyCol; i++){ + a[i] = 23; assert( 23==sqlite3LogEst(5) ); + } + + assert( 0==sqlite3LogEst(1) ); + if( IsUniqueIndex(pIdx) ) a[pIdx->nKeyCol] = 0; +} + +/* +** This routine will drop an existing named index. This routine +** implements the DROP INDEX statement. +*/ +SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){ + Index *pIndex; + Vdbe *v; + sqlite3 *db = pParse->db; + int iDb; + + if( db->mallocFailed ){ + goto exit_drop_index; + } + assert( pParse->nErr==0 ); /* Never called with prior non-OOM errors */ + assert( pName->nSrc==1 ); + assert( pName->a[0].fg.fixedSchema==0 ); + assert( pName->a[0].fg.isSubquery==0 ); + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + goto exit_drop_index; + } + pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].u4.zDatabase); + if( pIndex==0 ){ + if( !ifExists ){ + sqlite3ErrorMsg(pParse, "no such index: %S", pName->a); + }else{ + sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].u4.zDatabase); + sqlite3ForceNotReadOnly(pParse); + } + pParse->checkSchema = 1; + goto exit_drop_index; + } + if( pIndex->idxType!=SQLITE_IDXTYPE_APPDEF ){ + sqlite3ErrorMsg(pParse, "index associated with UNIQUE " + "or PRIMARY KEY constraint cannot be dropped", 0); + goto exit_drop_index; + } + iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); + assert( iDb>=0 && iDbnDb ); +#ifndef SQLITE_OMIT_AUTHORIZATION + { + int code = SQLITE_DROP_INDEX; + Table *pTab = pIndex->pTable; + const char *zDb = db->aDb[iDb].zDbSName; + const char *zTab = SCHEMA_TABLE(iDb); + if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){ + goto exit_drop_index; + } + if( !OMIT_TEMPDB && iDb==1 ) code = SQLITE_DROP_TEMP_INDEX; + if( sqlite3AuthCheck(pParse, code, pIndex->zName, pTab->zName, zDb) ){ + goto exit_drop_index; + } + } +#endif + + /* Generate code to remove the index and from the schema table */ + v = sqlite3GetVdbe(pParse); + if( v ){ + sqlite3BeginWriteOperation(pParse, 1, iDb); + sqlite3NestedParse(pParse, + "DELETE FROM %Q." LEGACY_SCHEMA_TABLE " WHERE name=%Q AND type='index'", + db->aDb[iDb].zDbSName, pIndex->zName + ); + sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName); + sqlite3ChangeCookie(pParse, iDb); + destroyRootPage(pParse, pIndex->tnum, iDb); + sqlite3VdbeAddOp4(v, OP_DropIndex, iDb, 0, 0, pIndex->zName, 0); + } + +exit_drop_index: + sqlite3SrcListDelete(db, pName); +} + +/* +** pArray is a pointer to an array of objects. Each object in the +** array is szEntry bytes in size. This routine uses sqlite3DbRealloc() +** to extend the array so that there is space for a new object at the end. +** +** When this function is called, *pnEntry contains the current size of +** the array (in entries - so the allocation is ((*pnEntry) * szEntry) bytes +** in total). +** +** If the realloc() is successful (i.e. if no OOM condition occurs), the +** space allocated for the new object is zeroed, *pnEntry updated to +** reflect the new size of the array and a pointer to the new allocation +** returned. *pIdx is set to the index of the new array entry in this case. +** +** Otherwise, if the realloc() fails, *pIdx is set to -1, *pnEntry remains +** unchanged and a copy of pArray returned. +*/ +SQLITE_PRIVATE void *sqlite3ArrayAllocate( + sqlite3 *db, /* Connection to notify of malloc failures */ + void *pArray, /* Array of objects. Might be reallocated */ + int szEntry, /* Size of each object in the array */ + int *pnEntry, /* Number of objects currently in use */ + int *pIdx /* Write the index of a new slot here */ +){ + char *z; + sqlite3_int64 n = *pIdx = *pnEntry; + if( (n & (n-1))==0 ){ + sqlite3_int64 sz = (n==0) ? 1 : 2*n; + void *pNew = sqlite3DbRealloc(db, pArray, sz*szEntry); + if( pNew==0 ){ + *pIdx = -1; + return pArray; + } + pArray = pNew; + } + z = (char*)pArray; + memset(&z[n * szEntry], 0, szEntry); + ++*pnEntry; + return pArray; +} + +/* +** Append a new element to the given IdList. Create a new IdList if +** need be. +** +** A new IdList is returned, or NULL if malloc() fails. +*/ +SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse *pParse, IdList *pList, Token *pToken){ + sqlite3 *db = pParse->db; + int i; + if( pList==0 ){ + pList = sqlite3DbMallocZero(db, SZ_IDLIST(1)); + if( pList==0 ) return 0; + }else{ + IdList *pNew; + pNew = sqlite3DbRealloc(db, pList, SZ_IDLIST(pList->nId+1)); + if( pNew==0 ){ + sqlite3IdListDelete(db, pList); + return 0; + } + pList = pNew; + } + i = pList->nId++; + pList->a[i].zName = sqlite3NameFromToken(db, pToken); + if( IN_RENAME_OBJECT && pList->a[i].zName ){ + sqlite3RenameTokenMap(pParse, (void*)pList->a[i].zName, pToken); + } + return pList; +} + +/* +** Delete an IdList. +*/ +SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3 *db, IdList *pList){ + int i; + assert( db!=0 ); + if( pList==0 ) return; + for(i=0; inId; i++){ + sqlite3DbFree(db, pList->a[i].zName); + } + sqlite3DbNNFreeNN(db, pList); +} + +/* +** Return the index in pList of the identifier named zId. Return -1 +** if not found. +*/ +SQLITE_PRIVATE int sqlite3IdListIndex(IdList *pList, const char *zName){ + int i; + assert( pList!=0 ); + for(i=0; inId; i++){ + if( sqlite3StrICmp(pList->a[i].zName, zName)==0 ) return i; + } + return -1; +} + +/* +** Maximum size of a SrcList object. +** The SrcList object is used to represent the FROM clause of a +** SELECT statement, and the query planner cannot deal with more +** than 64 tables in a join. So any value larger than 64 here +** is sufficient for most uses. Smaller values, like say 10, are +** appropriate for small and memory-limited applications. +*/ +#ifndef SQLITE_MAX_SRCLIST +# define SQLITE_MAX_SRCLIST 200 +#endif + +/* +** Expand the space allocated for the given SrcList object by +** creating nExtra new slots beginning at iStart. iStart is zero based. +** New slots are zeroed. +** +** For example, suppose a SrcList initially contains two entries: A,B. +** To append 3 new entries onto the end, do this: +** +** sqlite3SrcListEnlarge(db, pSrclist, 3, 2); +** +** After the call above it would contain: A, B, nil, nil, nil. +** If the iStart argument had been 1 instead of 2, then the result +** would have been: A, nil, nil, nil, B. To prepend the new slots, +** the iStart value would be 0. The result then would +** be: nil, nil, nil, A, B. +** +** If a memory allocation fails or the SrcList becomes too large, leave +** the original SrcList unchanged, return NULL, and leave an error message +** in pParse. +*/ +SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge( + Parse *pParse, /* Parsing context into which errors are reported */ + SrcList *pSrc, /* The SrcList to be enlarged */ + int nExtra, /* Number of new slots to add to pSrc->a[] */ + int iStart /* Index in pSrc->a[] of first new slot */ +){ + int i; + + /* Sanity checking on calling parameters */ + assert( iStart>=0 ); + assert( nExtra>=1 ); + assert( pSrc!=0 ); + assert( iStart<=pSrc->nSrc ); + + /* Allocate additional space if needed */ + if( (u32)pSrc->nSrc+nExtra>pSrc->nAlloc ){ + SrcList *pNew; + sqlite3_int64 nAlloc = 2*(sqlite3_int64)pSrc->nSrc+nExtra; + sqlite3 *db = pParse->db; + + if( pSrc->nSrc+nExtra>=SQLITE_MAX_SRCLIST ){ + sqlite3ErrorMsg(pParse, "too many FROM clause terms, max: %d", + SQLITE_MAX_SRCLIST); + return 0; + } + if( nAlloc>SQLITE_MAX_SRCLIST ) nAlloc = SQLITE_MAX_SRCLIST; + pNew = sqlite3DbRealloc(db, pSrc, SZ_SRCLIST(nAlloc)); + if( pNew==0 ){ + assert( db->mallocFailed ); + return 0; + } + pSrc = pNew; + pSrc->nAlloc = nAlloc; + } + + /* Move existing slots that come after the newly inserted slots + ** out of the way */ + for(i=pSrc->nSrc-1; i>=iStart; i--){ + pSrc->a[i+nExtra] = pSrc->a[i]; + } + pSrc->nSrc += nExtra; + + /* Zero the newly allocated slots */ + memset(&pSrc->a[iStart], 0, sizeof(pSrc->a[0])*nExtra); + for(i=iStart; ia[i].iCursor = -1; + } + + /* Return a pointer to the enlarged SrcList */ + return pSrc; +} + + +/* +** Append a new table name to the given SrcList. Create a new SrcList if +** need be. A new entry is created in the SrcList even if pTable is NULL. +** +** A SrcList is returned, or NULL if there is an OOM error or if the +** SrcList grows to large. The returned +** SrcList might be the same as the SrcList that was input or it might be +** a new one. If an OOM error does occurs, then the prior value of pList +** that is input to this routine is automatically freed. +** +** If pDatabase is not null, it means that the table has an optional +** database name prefix. Like this: "database.table". The pDatabase +** points to the table name and the pTable points to the database name. +** The SrcList.a[].zName field is filled with the table name which might +** come from pTable (if pDatabase is NULL) or from pDatabase. +** SrcList.a[].zDatabase is filled with the database name from pTable, +** or with NULL if no database is specified. +** +** In other words, if call like this: +** +** sqlite3SrcListAppend(D,A,B,0); +** +** Then B is a table name and the database name is unspecified. If called +** like this: +** +** sqlite3SrcListAppend(D,A,B,C); +** +** Then C is the table name and B is the database name. If C is defined +** then so is B. In other words, we never have a case where: +** +** sqlite3SrcListAppend(D,A,0,C); +** +** Both pTable and pDatabase are assumed to be quoted. They are dequoted +** before being added to the SrcList. +*/ +SQLITE_PRIVATE SrcList *sqlite3SrcListAppend( + Parse *pParse, /* Parsing context, in which errors are reported */ + SrcList *pList, /* Append to this SrcList. NULL creates a new SrcList */ + Token *pTable, /* Table to append */ + Token *pDatabase /* Database of the table */ +){ + SrcItem *pItem; + sqlite3 *db; + assert( pDatabase==0 || pTable!=0 ); /* Cannot have C without B */ + assert( pParse!=0 ); + assert( pParse->db!=0 ); + db = pParse->db; + if( pList==0 ){ + pList = sqlite3DbMallocRawNN(pParse->db, SZ_SRCLIST(1)); + if( pList==0 ) return 0; + pList->nAlloc = 1; + pList->nSrc = 1; + memset(&pList->a[0], 0, sizeof(pList->a[0])); + pList->a[0].iCursor = -1; + }else{ + SrcList *pNew = sqlite3SrcListEnlarge(pParse, pList, 1, pList->nSrc); + if( pNew==0 ){ + sqlite3SrcListDelete(db, pList); + return 0; + }else{ + pList = pNew; + } + } + pItem = &pList->a[pList->nSrc-1]; + if( pDatabase && pDatabase->z==0 ){ + pDatabase = 0; + } + assert( pItem->fg.fixedSchema==0 ); + assert( pItem->fg.isSubquery==0 ); + if( pDatabase ){ + pItem->zName = sqlite3NameFromToken(db, pDatabase); + pItem->u4.zDatabase = sqlite3NameFromToken(db, pTable); + }else{ + pItem->zName = sqlite3NameFromToken(db, pTable); + pItem->u4.zDatabase = 0; + } + return pList; +} + +/* +** Assign VdbeCursor index numbers to all tables in a SrcList +*/ +SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ + int i; + SrcItem *pItem; + assert( pList || pParse->db->mallocFailed ); + if( ALWAYS(pList) ){ + for(i=0, pItem=pList->a; inSrc; i++, pItem++){ + if( pItem->iCursor>=0 ) continue; + pItem->iCursor = pParse->nTab++; + if( pItem->fg.isSubquery ){ + assert( pItem->u4.pSubq!=0 ); + assert( pItem->u4.pSubq->pSelect!=0 ); + assert( pItem->u4.pSubq->pSelect->pSrc!=0 ); + sqlite3SrcListAssignCursors(pParse, pItem->u4.pSubq->pSelect->pSrc); + } + } + } +} + +/* +** Delete a Subquery object and its substructure. +*/ +SQLITE_PRIVATE void sqlite3SubqueryDelete(sqlite3 *db, Subquery *pSubq){ + assert( pSubq!=0 && pSubq->pSelect!=0 ); + sqlite3SelectDelete(db, pSubq->pSelect); + sqlite3DbFree(db, pSubq); +} + +/* +** Remove a Subquery from a SrcItem. Return the associated Select object. +** The returned Select becomes the responsibility of the caller. +*/ +SQLITE_PRIVATE Select *sqlite3SubqueryDetach(sqlite3 *db, SrcItem *pItem){ + Select *pSel; + assert( pItem!=0 ); + assert( pItem->fg.isSubquery ); + pSel = pItem->u4.pSubq->pSelect; + sqlite3DbFree(db, pItem->u4.pSubq); + pItem->u4.pSubq = 0; + pItem->fg.isSubquery = 0; + return pSel; +} + +/* +** Delete an entire SrcList including all its substructure. +*/ +SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ + int i; + SrcItem *pItem; + assert( db!=0 ); + if( pList==0 ) return; + for(pItem=pList->a, i=0; inSrc; i++, pItem++){ + + /* Check invariants on SrcItem */ + assert( !pItem->fg.isIndexedBy || !pItem->fg.isTabFunc ); + assert( !pItem->fg.isCte || !pItem->fg.isIndexedBy ); + assert( !pItem->fg.fixedSchema || !pItem->fg.isSubquery ); + assert( !pItem->fg.isSubquery || (pItem->u4.pSubq!=0 && + pItem->u4.pSubq->pSelect!=0) ); + + if( pItem->zName ) sqlite3DbNNFreeNN(db, pItem->zName); + if( pItem->zAlias ) sqlite3DbNNFreeNN(db, pItem->zAlias); + if( pItem->fg.isSubquery ){ + sqlite3SubqueryDelete(db, pItem->u4.pSubq); + }else if( pItem->fg.fixedSchema==0 && pItem->u4.zDatabase!=0 ){ + sqlite3DbNNFreeNN(db, pItem->u4.zDatabase); + } + if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy); + if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg); + sqlite3DeleteTable(db, pItem->pSTab); + if( pItem->fg.isUsing ){ + sqlite3IdListDelete(db, pItem->u3.pUsing); + }else if( pItem->u3.pOn ){ + sqlite3ExprDelete(db, pItem->u3.pOn); + } + } + sqlite3DbNNFreeNN(db, pList); +} + +/* +** Attach a Subquery object to pItem->uv.pSubq. Set the +** pSelect value but leave all the other values initialized +** to zero. +** +** A copy of the Select object is made if dupSelect is true, and the +** SrcItem takes responsibility for deleting the copy. If dupSelect is +** false, ownership of the Select passes to the SrcItem. Either way, +** the SrcItem will take responsibility for deleting the Select. +** +** When dupSelect is zero, that means the Select might get deleted right +** away if there is an OOM error. Beware. +** +** Return non-zero on success. Return zero on an OOM error. +*/ +SQLITE_PRIVATE int sqlite3SrcItemAttachSubquery( + Parse *pParse, /* Parsing context */ + SrcItem *pItem, /* Item to which the subquery is to be attached */ + Select *pSelect, /* The subquery SELECT. Must be non-NULL */ + int dupSelect /* If true, attach a copy of pSelect, not pSelect itself.*/ +){ + Subquery *p; + assert( pSelect!=0 ); + assert( pItem->fg.isSubquery==0 ); + if( pItem->fg.fixedSchema ){ + pItem->u4.pSchema = 0; + pItem->fg.fixedSchema = 0; + }else if( pItem->u4.zDatabase!=0 ){ + sqlite3DbFree(pParse->db, pItem->u4.zDatabase); + pItem->u4.zDatabase = 0; + } + if( dupSelect ){ + pSelect = sqlite3SelectDup(pParse->db, pSelect, 0); + if( pSelect==0 ) return 0; + } + p = pItem->u4.pSubq = sqlite3DbMallocRawNN(pParse->db, sizeof(Subquery)); + if( p==0 ){ + sqlite3SelectDelete(pParse->db, pSelect); + return 0; + } + pItem->fg.isSubquery = 1; + p->pSelect = pSelect; + assert( offsetof(Subquery, pSelect)==0 ); + memset(((char*)p)+sizeof(p->pSelect), 0, sizeof(*p)-sizeof(p->pSelect)); + return 1; +} + + +/* +** This routine is called by the parser to add a new term to the +** end of a growing FROM clause. The "p" parameter is the part of +** the FROM clause that has already been constructed. "p" is NULL +** if this is the first term of the FROM clause. pTable and pDatabase +** are the name of the table and database named in the FROM clause term. +** pDatabase is NULL if the database name qualifier is missing - the +** usual case. If the term has an alias, then pAlias points to the +** alias token. If the term is a subquery, then pSubquery is the +** SELECT statement that the subquery encodes. The pTable and +** pDatabase parameters are NULL for subqueries. The pOn and pUsing +** parameters are the content of the ON and USING clauses. +** +** Return a new SrcList which encodes is the FROM with the new +** term added. +*/ +SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm( + Parse *pParse, /* Parsing context */ + SrcList *p, /* The left part of the FROM clause already seen */ + Token *pTable, /* Name of the table to add to the FROM clause */ + Token *pDatabase, /* Name of the database containing pTable */ + Token *pAlias, /* The right-hand side of the AS subexpression */ + Select *pSubquery, /* A subquery used in place of a table name */ + OnOrUsing *pOnUsing /* Either the ON clause or the USING clause */ +){ + SrcItem *pItem; + sqlite3 *db = pParse->db; + if( !p && pOnUsing!=0 && (pOnUsing->pOn || pOnUsing->pUsing) ){ + sqlite3ErrorMsg(pParse, "a JOIN clause is required before %s", + (pOnUsing->pOn ? "ON" : "USING") + ); + goto append_from_error; + } + p = sqlite3SrcListAppend(pParse, p, pTable, pDatabase); + if( p==0 ){ + goto append_from_error; + } + assert( p->nSrc>0 ); + pItem = &p->a[p->nSrc-1]; + assert( (pTable==0)==(pDatabase==0) ); + assert( pItem->zName==0 || pDatabase!=0 ); + if( IN_RENAME_OBJECT && pItem->zName ){ + Token *pToken = (ALWAYS(pDatabase) && pDatabase->z) ? pDatabase : pTable; + sqlite3RenameTokenMap(pParse, pItem->zName, pToken); + } + assert( pAlias!=0 ); + if( pAlias->n ){ + pItem->zAlias = sqlite3NameFromToken(db, pAlias); + } + assert( pSubquery==0 || pDatabase==0 ); + if( pSubquery ){ + if( sqlite3SrcItemAttachSubquery(pParse, pItem, pSubquery, 0) ){ + if( pSubquery->selFlags & SF_NestedFrom ){ + pItem->fg.isNestedFrom = 1; + } + } + } + assert( pOnUsing==0 || pOnUsing->pOn==0 || pOnUsing->pUsing==0 ); + assert( pItem->fg.isUsing==0 ); + if( pOnUsing==0 ){ + pItem->u3.pOn = 0; + }else if( pOnUsing->pUsing ){ + pItem->fg.isUsing = 1; + pItem->u3.pUsing = pOnUsing->pUsing; + }else{ + pItem->u3.pOn = pOnUsing->pOn; + } + return p; + +append_from_error: + assert( p==0 ); + sqlite3ClearOnOrUsing(db, pOnUsing); + sqlite3SelectDelete(db, pSubquery); + return 0; +} + +/* +** Add an INDEXED BY or NOT INDEXED clause to the most recently added +** element of the source-list passed as the second argument. +*/ +SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){ + assert( pIndexedBy!=0 ); + if( p && pIndexedBy->n>0 ){ + SrcItem *pItem; + assert( p->nSrc>0 ); + pItem = &p->a[p->nSrc-1]; + assert( pItem->fg.notIndexed==0 ); + assert( pItem->fg.isIndexedBy==0 ); + assert( pItem->fg.isTabFunc==0 ); + if( pIndexedBy->n==1 && !pIndexedBy->z ){ + /* A "NOT INDEXED" clause was supplied. See parse.y + ** construct "indexed_opt" for details. */ + pItem->fg.notIndexed = 1; + }else{ + pItem->u1.zIndexedBy = sqlite3NameFromToken(pParse->db, pIndexedBy); + pItem->fg.isIndexedBy = 1; + assert( pItem->fg.isCte==0 ); /* No collision on union u2 */ + } + } +} + +/* +** Append the contents of SrcList p2 to SrcList p1 and return the resulting +** SrcList. Or, if an error occurs, return NULL. In all cases, p1 and p2 +** are deleted by this function. +*/ +SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2){ + assert( p1 ); + assert( p2 || pParse->nErr ); + assert( p2==0 || p2->nSrc>=1 ); + testcase( p1->nSrc==0 ); + if( p2 ){ + int nOld = p1->nSrc; + SrcList *pNew = sqlite3SrcListEnlarge(pParse, p1, p2->nSrc, nOld); + if( pNew==0 ){ + sqlite3SrcListDelete(pParse->db, p2); + }else{ + p1 = pNew; + memcpy(&p1->a[nOld], p2->a, p2->nSrc*sizeof(SrcItem)); + assert( nOld==1 || (p2->a[0].fg.jointype & JT_LTORJ)==0 ); + assert( p1->nSrc>=1 ); + p1->a[0].fg.jointype |= (JT_LTORJ & p2->a[0].fg.jointype); + sqlite3DbFree(pParse->db, p2); + } + } + return p1; +} + +/* +** Add the list of function arguments to the SrcList entry for a +** table-valued-function. +*/ +SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList *pList){ + if( p ){ + SrcItem *pItem = &p->a[p->nSrc-1]; + assert( pItem->fg.notIndexed==0 ); + assert( pItem->fg.isIndexedBy==0 ); + assert( pItem->fg.isTabFunc==0 ); + pItem->u1.pFuncArg = pList; + pItem->fg.isTabFunc = 1; + }else{ + sqlite3ExprListDelete(pParse->db, pList); + } +} + +/* +** When building up a FROM clause in the parser, the join operator +** is initially attached to the left operand. But the code generator +** expects the join operator to be on the right operand. This routine +** Shifts all join operators from left to right for an entire FROM +** clause. +** +** Example: Suppose the join is like this: +** +** A natural cross join B +** +** The operator is "natural cross join". The A and B operands are stored +** in p->a[0] and p->a[1], respectively. The parser initially stores the +** operator with A. This routine shifts that operator over to B. +** +** Additional changes: +** +** * All tables to the left of the right-most RIGHT JOIN are tagged with +** JT_LTORJ (mnemonic: Left Table Of Right Join) so that the +** code generator can easily tell that the table is part of +** the left operand of at least one RIGHT JOIN. +*/ +SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(Parse *pParse, SrcList *p){ + (void)pParse; + if( p && p->nSrc>1 ){ + int i = p->nSrc-1; + u8 allFlags = 0; + do{ + allFlags |= p->a[i].fg.jointype = p->a[i-1].fg.jointype; + }while( (--i)>0 ); + p->a[0].fg.jointype = 0; + + /* All terms to the left of a RIGHT JOIN should be tagged with the + ** JT_LTORJ flags */ + if( allFlags & JT_RIGHT ){ + for(i=p->nSrc-1; ALWAYS(i>0) && (p->a[i].fg.jointype&JT_RIGHT)==0; i--){} + i--; + assert( i>=0 ); + do{ + p->a[i].fg.jointype |= JT_LTORJ; + }while( (--i)>=0 ); + } + } +} + +/* +** Generate VDBE code for a BEGIN statement. +*/ +SQLITE_PRIVATE void sqlite3BeginTransaction(Parse *pParse, int type){ + sqlite3 *db; + Vdbe *v; + int i; + + assert( pParse!=0 ); + db = pParse->db; + assert( db!=0 ); + if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ){ + return; + } + v = sqlite3GetVdbe(pParse); + if( !v ) return; + if( type!=TK_DEFERRED ){ + for(i=0; inDb; i++){ + int eTxnType; + Btree *pBt = db->aDb[i].pBt; + if( pBt && sqlite3BtreeIsReadonly(pBt) ){ + eTxnType = 0; /* Read txn */ + }else if( type==TK_EXCLUSIVE ){ + eTxnType = 2; /* Exclusive txn */ + }else{ + eTxnType = 1; /* Write txn */ + } + sqlite3VdbeAddOp2(v, OP_Transaction, i, eTxnType); + sqlite3VdbeUsesBtree(v, i); + } + } + sqlite3VdbeAddOp0(v, OP_AutoCommit); +} + +/* +** Generate VDBE code for a COMMIT or ROLLBACK statement. +** Code for ROLLBACK is generated if eType==TK_ROLLBACK. Otherwise +** code is generated for a COMMIT. +*/ +SQLITE_PRIVATE void sqlite3EndTransaction(Parse *pParse, int eType){ + Vdbe *v; + int isRollback; + + assert( pParse!=0 ); + assert( pParse->db!=0 ); + assert( eType==TK_COMMIT || eType==TK_END || eType==TK_ROLLBACK ); + isRollback = eType==TK_ROLLBACK; + if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, + isRollback ? "ROLLBACK" : "COMMIT", 0, 0) ){ + return; + } + v = sqlite3GetVdbe(pParse); + if( v ){ + sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, isRollback); + } +} + +/* +** This function is called by the parser when it parses a command to create, +** release or rollback an SQL savepoint. +*/ +SQLITE_PRIVATE void sqlite3Savepoint(Parse *pParse, int op, Token *pName){ + char *zName = sqlite3NameFromToken(pParse->db, pName); + if( zName ){ + Vdbe *v = sqlite3GetVdbe(pParse); +#ifndef SQLITE_OMIT_AUTHORIZATION + static const char * const az[] = { "BEGIN", "RELEASE", "ROLLBACK" }; + assert( !SAVEPOINT_BEGIN && SAVEPOINT_RELEASE==1 && SAVEPOINT_ROLLBACK==2 ); +#endif + if( !v || sqlite3AuthCheck(pParse, SQLITE_SAVEPOINT, az[op], zName, 0) ){ + sqlite3DbFree(pParse->db, zName); + return; + } + sqlite3VdbeAddOp4(v, OP_Savepoint, op, 0, 0, zName, P4_DYNAMIC); + } +} + +/* +** Make sure the TEMP database is open and available for use. Return +** the number of errors. Leave any error messages in the pParse structure. +*/ +SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *pParse){ + sqlite3 *db = pParse->db; + if( db->aDb[1].pBt==0 && !pParse->explain ){ + int rc; + Btree *pBt; + static const int flags = + SQLITE_OPEN_READWRITE | + SQLITE_OPEN_CREATE | + SQLITE_OPEN_EXCLUSIVE | + SQLITE_OPEN_DELETEONCLOSE | + SQLITE_OPEN_TEMP_DB; + + rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pBt, 0, flags); + if( rc!=SQLITE_OK ){ + sqlite3ErrorMsg(pParse, "unable to open a temporary database " + "file for storing temporary tables"); + pParse->rc = rc; + return 1; + } + db->aDb[1].pBt = pBt; + assert( db->aDb[1].pSchema ); + if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, 0, 0) ){ + sqlite3OomFault(db); + return 1; + } + } + return 0; +} + +/* +** Record the fact that the schema cookie will need to be verified +** for database iDb. The code to actually verify the schema cookie +** will occur at the end of the top-level VDBE and will be generated +** later, by sqlite3FinishCoding(). +*/ +static void sqlite3CodeVerifySchemaAtToplevel(Parse *pToplevel, int iDb){ + assert( iDb>=0 && iDbdb->nDb ); + assert( pToplevel->db->aDb[iDb].pBt!=0 || iDb==1 ); + assert( iDbdb, iDb, 0) ); + if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){ + DbMaskSet(pToplevel->cookieMask, iDb); + if( !OMIT_TEMPDB && iDb==1 ){ + sqlite3OpenTempDatabase(pToplevel); + } + } +} +SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ + sqlite3CodeVerifySchemaAtToplevel(sqlite3ParseToplevel(pParse), iDb); +} + + +/* +** If argument zDb is NULL, then call sqlite3CodeVerifySchema() for each +** attached database. Otherwise, invoke it for the database named zDb only. +*/ +SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb){ + sqlite3 *db = pParse->db; + int i; + for(i=0; inDb; i++){ + Db *pDb = &db->aDb[i]; + if( pDb->pBt && (!zDb || 0==sqlite3StrICmp(zDb, pDb->zDbSName)) ){ + sqlite3CodeVerifySchema(pParse, i); + } + } +} + +/* +** Generate VDBE code that prepares for doing an operation that +** might change the database. +** +** This routine starts a new transaction if we are not already within +** a transaction. If we are already within a transaction, then a checkpoint +** is set if the setStatement parameter is true. A checkpoint should +** be set for operations that might fail (due to a constraint) part of +** the way through and which will need to undo some writes without having to +** rollback the whole transaction. For operations where all constraints +** can be checked before any changes are made to the database, it is never +** necessary to undo a write and the checkpoint should not be set. +*/ +SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + sqlite3CodeVerifySchemaAtToplevel(pToplevel, iDb); + DbMaskSet(pToplevel->writeMask, iDb); + pToplevel->isMultiWrite |= setStatement; +} + +/* +** Indicate that the statement currently under construction might write +** more than one entry (example: deleting one row then inserting another, +** inserting multiple rows in a table, or inserting a row and index entries.) +** If an abort occurs after some of these writes have completed, then it will +** be necessary to undo the completed writes. +*/ +SQLITE_PRIVATE void sqlite3MultiWrite(Parse *pParse){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + pToplevel->isMultiWrite = 1; +} + +/* +** The code generator calls this routine if is discovers that it is +** possible to abort a statement prior to completion. In order to +** perform this abort without corrupting the database, we need to make +** sure that the statement is protected by a statement transaction. +** +** Technically, we only need to set the mayAbort flag if the +** isMultiWrite flag was previously set. There is a time dependency +** such that the abort must occur after the multiwrite. This makes +** some statements involving the REPLACE conflict resolution algorithm +** go a little faster. But taking advantage of this time dependency +** makes it more difficult to prove that the code is correct (in +** particular, it prevents us from writing an effective +** implementation of sqlite3AssertMayAbort()) and so we have chosen +** to take the safe route and skip the optimization. +*/ +SQLITE_PRIVATE void sqlite3MayAbort(Parse *pParse){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + pToplevel->mayAbort = 1; +} + +/* +** Code an OP_Halt that causes the vdbe to return an SQLITE_CONSTRAINT +** error. The onError parameter determines which (if any) of the statement +** and/or current transaction is rolled back. +*/ +SQLITE_PRIVATE void sqlite3HaltConstraint( + Parse *pParse, /* Parsing context */ + int errCode, /* extended error code */ + int onError, /* Constraint type */ + char *p4, /* Error message */ + i8 p4type, /* P4_STATIC or P4_TRANSIENT */ + u8 p5Errmsg /* P5_ErrMsg type */ +){ + Vdbe *v; + assert( pParse->pVdbe!=0 ); + v = sqlite3GetVdbe(pParse); + assert( (errCode&0xff)==SQLITE_CONSTRAINT || pParse->nested ); + if( onError==OE_Abort ){ + sqlite3MayAbort(pParse); + } + sqlite3VdbeAddOp4(v, OP_Halt, errCode, onError, 0, p4, p4type); + sqlite3VdbeChangeP5(v, p5Errmsg); +} + +/* +** Code an OP_Halt due to UNIQUE or PRIMARY KEY constraint violation. +*/ +SQLITE_PRIVATE void sqlite3UniqueConstraint( + Parse *pParse, /* Parsing context */ + int onError, /* Constraint type */ + Index *pIdx /* The index that triggers the constraint */ +){ + char *zErr; + int j; + StrAccum errMsg; + Table *pTab = pIdx->pTable; + + sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, + pParse->db->aLimit[SQLITE_LIMIT_LENGTH]); + if( pIdx->aColExpr ){ + sqlite3_str_appendf(&errMsg, "index '%q'", pIdx->zName); + }else{ + for(j=0; jnKeyCol; j++){ + char *zCol; + assert( pIdx->aiColumn[j]>=0 ); + zCol = pTab->aCol[pIdx->aiColumn[j]].zCnName; + if( j ) sqlite3_str_append(&errMsg, ", ", 2); + sqlite3_str_appendall(&errMsg, pTab->zName); + sqlite3_str_append(&errMsg, ".", 1); + sqlite3_str_appendall(&errMsg, zCol); + } + } + zErr = sqlite3StrAccumFinish(&errMsg); + sqlite3HaltConstraint(pParse, + IsPrimaryKeyIndex(pIdx) ? SQLITE_CONSTRAINT_PRIMARYKEY + : SQLITE_CONSTRAINT_UNIQUE, + onError, zErr, P4_DYNAMIC, P5_ConstraintUnique); +} + + +/* +** Code an OP_Halt due to non-unique rowid. +*/ +SQLITE_PRIVATE void sqlite3RowidConstraint( + Parse *pParse, /* Parsing context */ + int onError, /* Conflict resolution algorithm */ + Table *pTab /* The table with the non-unique rowid */ +){ + char *zMsg; + int rc; + if( pTab->iPKey>=0 ){ + zMsg = sqlite3MPrintf(pParse->db, "%s.%s", pTab->zName, + pTab->aCol[pTab->iPKey].zCnName); + rc = SQLITE_CONSTRAINT_PRIMARYKEY; + }else{ + zMsg = sqlite3MPrintf(pParse->db, "%s.rowid", pTab->zName); + rc = SQLITE_CONSTRAINT_ROWID; + } + sqlite3HaltConstraint(pParse, rc, onError, zMsg, P4_DYNAMIC, + P5_ConstraintUnique); +} + +/* +** Return true if any column of pIndex uses the zColl collation +*/ +#ifndef SQLITE_OMIT_REINDEX +static int collationMatch(const char *zColl, Index *pIndex){ + int i; + assert( zColl!=0 ); + for(i=0; inColumn; i++){ + const char *z = pIndex->azColl[i]; + assert( z!=0 ); + if( 0==sqlite3StrICmp(z, zColl) ){ + return 1; + } + } + return 0; +} +#endif + +/* +** Generate code for the REINDEX command. +** +** REINDEX -- 1 +** REINDEX -- 2 +** REINDEX ?.? -- 3 +** REINDEX ?.? -- 4 +** REINDEX EXPRESSIONS -- 5 +** +** Form 1 causes all indexes in all attached databases to be rebuilt. +** Form 2 rebuilds all indexes in all databases that use the named +** collating function. Forms 3 and 4 rebuild the named index or all +** indexes associated with the named table, respectively. Form 5 +** rebuilds all expression indexes in addition to all collations, +** indexes, or tables named "EXPRESSIONS". +** +** If the name is ambiguous such that it matches two or more of +** forms 2 through 5, then rebuild the union of all matching indexes, +** taken care to avoid rebuilding the same index more than once. +*/ +#ifndef SQLITE_OMIT_REINDEX +SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ + char *z = 0; /* Name of a table or index or collation */ + const char *zDb = 0; /* Name of the database */ + int iReDb = -1; /* The database index number */ + sqlite3 *db = pParse->db; /* The database connection */ + Token *pObjName; /* Name of the table or index to be reindexed */ + int bMatch = 0; /* At least one name match */ + const char *zColl = 0; /* Rebuild indexes using this collation */ + Table *pReTab = 0; /* Rebuild all indexes of this table */ + Index *pReIndex = 0; /* Rebuild this index */ + int isExprIdx = 0; /* Rebuild all expression indexes */ + int bAll = 0; /* Rebuild all indexes */ + + /* Read the database schema. If an error occurs, leave an error message + ** and code in pParse and return NULL. */ + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + return; + } + + if( pName1==0 ){ + /* rebuild all indexes */ + bMatch = 1; + bAll = 1; + }else if( NEVER(pName2==0) || pName2->z==0 ){ + assert( pName1->z ); + z = sqlite3NameFromToken(pParse->db, pName1); + if( z==0 ) return; + }else{ + iReDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName); + if( iReDb<0 ) return; + z = sqlite3NameFromToken(db, pObjName); + if( z==0 ) return; + zDb = db->aDb[iReDb].zDbSName; + } + if( !bAll ){ + if( zDb==0 && sqlite3StrICmp(z, "expressions")==0 ){ + isExprIdx = 1; + bMatch = 1; + } + if( zDb==0 && sqlite3FindCollSeq(db, ENC(db), z, 0)!=0 ){ + zColl = z; + bMatch = 1; + } + if( zColl==0 && (pReTab = sqlite3FindTable(db, z, zDb))!=0 ){ + bMatch = 1; + } + if( zColl==0 && (pReIndex = sqlite3FindIndex(db, z, zDb))!=0 ){ + bMatch = 1; + } + } + if( bMatch ){ + int iDb; + HashElem *k; + Table *pTab; + Index *pIdx; + Db *pDb; + for(iDb=0, pDb=db->aDb; iDbnDb; iDb++, pDb++){ + assert( pDb!=0 ); + if( iReDb>=0 && iReDb!=iDb ) continue; + for(k=sqliteHashFirst(&pDb->pSchema->tblHash); k; k=sqliteHashNext(k)){ + pTab = (Table*)sqliteHashData(k); + if( IsVirtual(pTab) ) continue; + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + if( bAll + || pTab==pReTab + || pIdx==pReIndex + || (isExprIdx && pIdx->bHasExpr) + || (zColl!=0 && collationMatch(zColl,pIdx)) + ){ + sqlite3BeginWriteOperation(pParse, 0, iDb); + sqlite3RefillIndex(pParse, pIdx, -1); + } + } /* End loop over indexes of pTab */ + } /* End loop over tables of iDb */ + } /* End loop over databases */ + }else{ + sqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed"); + } + sqlite3DbFree(db, z); + return; +} +#endif + +/* +** Return a KeyInfo structure that is appropriate for the given Index. +** +** The caller should invoke sqlite3KeyInfoUnref() on the returned object +** when it has finished using it. +*/ +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ + int i; + int nCol = pIdx->nColumn; + int nKey = pIdx->nKeyCol; + KeyInfo *pKey; + if( pParse->nErr ) return 0; + if( pIdx->uniqNotNull ){ + pKey = sqlite3KeyInfoAlloc(pParse->db, nKey, nCol-nKey); + }else{ + pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0); + } + if( pKey ){ + assert( sqlite3KeyInfoIsWriteable(pKey) ); + for(i=0; iazColl[i]; + pKey->aColl[i] = zColl==sqlite3StrBINARY ? 0 : + sqlite3LocateCollSeq(pParse, zColl); + pKey->aSortFlags[i] = pIdx->aSortOrder[i]; + assert( 0==(pKey->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) ); + } + if( pParse->nErr ){ + assert( pParse->rc==SQLITE_ERROR_MISSING_COLLSEQ ); + if( pIdx->bNoQuery==0 + && sqlite3HashFind(&pIdx->pSchema->idxHash, pIdx->zName) + ){ + /* Deactivate the index because it contains an unknown collating + ** sequence. The only way to reactive the index is to reload the + ** schema. Adding the missing collating sequence later does not + ** reactive the index. The application had the chance to register + ** the missing index using the collation-needed callback. For + ** simplicity, SQLite will not give the application a second chance. + ** + ** Except, do not do this if the index is not in the schema hash + ** table. In this case the index is currently being constructed + ** by a CREATE INDEX statement, and retrying will not help. */ + pIdx->bNoQuery = 1; + pParse->rc = SQLITE_ERROR_RETRY; + } + sqlite3KeyInfoUnref(pKey); + pKey = 0; + } + } + return pKey; +} + +#ifndef SQLITE_OMIT_CTE +/* +** Create a new CTE object +*/ +SQLITE_PRIVATE Cte *sqlite3CteNew( + Parse *pParse, /* Parsing context */ + Token *pName, /* Name of the common-table */ + ExprList *pArglist, /* Optional column name list for the table */ + Select *pQuery, /* Query used to initialize the table */ + u8 eM10d /* The MATERIALIZED flag */ +){ + Cte *pNew; + sqlite3 *db = pParse->db; + + pNew = sqlite3DbMallocZero(db, sizeof(*pNew)); + assert( pNew!=0 || db->mallocFailed ); + + if( db->mallocFailed ){ + sqlite3ExprListDelete(db, pArglist); + sqlite3SelectDelete(db, pQuery); + }else{ + pNew->pSelect = pQuery; + pNew->pCols = pArglist; + pNew->zName = sqlite3NameFromToken(pParse->db, pName); + pNew->eM10d = eM10d; + } + return pNew; +} + +/* +** Clear information from a Cte object, but do not deallocate storage +** for the object itself. +*/ +static void cteClear(sqlite3 *db, Cte *pCte){ + assert( pCte!=0 ); + sqlite3ExprListDelete(db, pCte->pCols); + sqlite3SelectDelete(db, pCte->pSelect); + sqlite3DbFree(db, pCte->zName); +} + +/* +** Free the contents of the CTE object passed as the second argument. +*/ +SQLITE_PRIVATE void sqlite3CteDelete(sqlite3 *db, Cte *pCte){ + assert( pCte!=0 ); + cteClear(db, pCte); + sqlite3DbFree(db, pCte); +} + +/* +** This routine is invoked once per CTE by the parser while parsing a +** WITH clause. The CTE described by the third argument is added to +** the WITH clause of the second argument. If the second argument is +** NULL, then a new WITH argument is created. +*/ +SQLITE_PRIVATE With *sqlite3WithAdd( + Parse *pParse, /* Parsing context */ + With *pWith, /* Existing WITH clause, or NULL */ + Cte *pCte /* CTE to add to the WITH clause */ +){ + sqlite3 *db = pParse->db; + With *pNew; + char *zName; + + if( pCte==0 ){ + return pWith; + } + + /* Check that the CTE name is unique within this WITH clause. If + ** not, store an error in the Parse structure. */ + zName = pCte->zName; + if( zName && pWith ){ + int i; + for(i=0; inCte; i++){ + if( sqlite3StrICmp(zName, pWith->a[i].zName)==0 ){ + sqlite3ErrorMsg(pParse, "duplicate WITH table name: %s", zName); + } + } + } + + if( pWith ){ + pNew = sqlite3DbRealloc(db, pWith, SZ_WITH(pWith->nCte+1)); + }else{ + pNew = sqlite3DbMallocZero(db, SZ_WITH(1)); + } + assert( (pNew!=0 && zName!=0) || db->mallocFailed ); + + if( db->mallocFailed ){ + sqlite3CteDelete(db, pCte); + pNew = pWith; + }else{ + pNew->a[pNew->nCte++] = *pCte; + sqlite3DbFree(db, pCte); + } + + return pNew; +} + +/* +** Free the contents of the With object passed as the second argument. +*/ +SQLITE_PRIVATE void sqlite3WithDelete(sqlite3 *db, With *pWith){ + if( pWith ){ + int i; + for(i=0; inCte; i++){ + cteClear(db, &pWith->a[i]); + } + sqlite3DbFree(db, pWith); + } +} +SQLITE_PRIVATE void sqlite3WithDeleteGeneric(sqlite3 *db, void *pWith){ + sqlite3WithDelete(db, (With*)pWith); +} +#endif /* !defined(SQLITE_OMIT_CTE) */ + +/************** End of build.c ***********************************************/ +/************** Begin file callback.c ****************************************/ +/* +** 2005 May 23 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains functions used to access the internal hash tables +** of user defined functions and collation sequences. +*/ + +/* #include "sqliteInt.h" */ + +/* +** Invoke the 'collation needed' callback to request a collation sequence +** in the encoding enc of name zName, length nName. +*/ +static void callCollNeeded(sqlite3 *db, int enc, const char *zName){ + assert( !db->xCollNeeded || !db->xCollNeeded16 ); + if( db->xCollNeeded ){ + char *zExternal = sqlite3DbStrDup(db, zName); + if( !zExternal ) return; + db->xCollNeeded(db->pCollNeededArg, db, enc, zExternal); + sqlite3DbFree(db, zExternal); + } +#ifndef SQLITE_OMIT_UTF16 + if( db->xCollNeeded16 ){ + char const *zExternal; + sqlite3_value *pTmp = sqlite3ValueNew(db); + sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC); + zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE); + if( zExternal ){ + db->xCollNeeded16(db->pCollNeededArg, db, (int)ENC(db), zExternal); + } + sqlite3ValueFree(pTmp); + } +#endif +} + +/* +** This routine is called if the collation factory fails to deliver a +** collation function in the best encoding but there may be other versions +** of this collation function (for other text encodings) available. Use one +** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if +** possible. +*/ +static int synthCollSeq(sqlite3 *db, CollSeq *pColl){ + CollSeq *pColl2; + char *z = pColl->zName; + int i; + static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 }; + for(i=0; i<3; i++){ + pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, 0); + if( pColl2->xCmp!=0 ){ + memcpy(pColl, pColl2, sizeof(CollSeq)); + pColl->xDel = 0; /* Do not copy the destructor */ + return SQLITE_OK; + } + } + return SQLITE_ERROR; +} + +/* +** This routine is called on a collation sequence before it is used to +** check that it is defined. An undefined collation sequence exists when +** a database is loaded that contains references to collation sequences +** that have not been defined by sqlite3_create_collation() etc. +** +** If required, this routine calls the 'collation needed' callback to +** request a definition of the collating sequence. If this doesn't work, +** an equivalent collating sequence that uses a text encoding different +** from the main database is substituted, if one is available. +*/ +SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){ + if( pColl && pColl->xCmp==0 ){ + const char *zName = pColl->zName; + sqlite3 *db = pParse->db; + CollSeq *p = sqlite3GetCollSeq(pParse, ENC(db), pColl, zName); + if( !p ){ + return SQLITE_ERROR; + } + assert( p==pColl ); + } + return SQLITE_OK; +} + + + +/* +** Locate and return an entry from the db.aCollSeq hash table. If the entry +** specified by zName and nName is not found and parameter 'create' is +** true, then create a new entry. Otherwise return NULL. +** +** Each pointer stored in the sqlite3.aCollSeq hash table contains an +** array of three CollSeq structures. The first is the collation sequence +** preferred for UTF-8, the second UTF-16le, and the third UTF-16be. +** +** Stored immediately after the three collation sequences is a copy of +** the collation sequence name. A pointer to this string is stored in +** each collation sequence structure. +*/ +static CollSeq *findCollSeqEntry( + sqlite3 *db, /* Database connection */ + const char *zName, /* Name of the collating sequence */ + int create /* Create a new entry if true */ +){ + CollSeq *pColl; + pColl = sqlite3HashFind(&db->aCollSeq, zName); + + if( 0==pColl && create ){ + int nName = sqlite3Strlen30(zName) + 1; + pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName); + if( pColl ){ + CollSeq *pDel = 0; + pColl[0].zName = (char*)&pColl[3]; + pColl[0].enc = SQLITE_UTF8; + pColl[1].zName = (char*)&pColl[3]; + pColl[1].enc = SQLITE_UTF16LE; + pColl[2].zName = (char*)&pColl[3]; + pColl[2].enc = SQLITE_UTF16BE; + memcpy(pColl[0].zName, zName, nName); + pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, pColl); + + /* If a malloc() failure occurred in sqlite3HashInsert(), it will + ** return the pColl pointer to be deleted (because it wasn't added + ** to the hash table). + */ + assert( pDel==0 || pDel==pColl ); + if( pDel!=0 ){ + sqlite3OomFault(db); + sqlite3DbFree(db, pDel); + pColl = 0; + } + } + } + return pColl; +} + +/* +** Parameter zName points to a UTF-8 encoded string nName bytes long. +** Return the CollSeq* pointer for the collation sequence named zName +** for the encoding 'enc' from the database 'db'. +** +** If the entry specified is not found and 'create' is true, then create a +** new entry. Otherwise return NULL. +** +** A separate function sqlite3LocateCollSeq() is a wrapper around +** this routine. sqlite3LocateCollSeq() invokes the collation factory +** if necessary and generates an error message if the collating sequence +** cannot be found. +** +** See also: sqlite3LocateCollSeq(), sqlite3GetCollSeq() +*/ +SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq( + sqlite3 *db, /* Database connection to search */ + u8 enc, /* Desired text encoding */ + const char *zName, /* Name of the collating sequence. Might be NULL */ + int create /* True to create CollSeq if doesn't already exist */ +){ + CollSeq *pColl; + assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); + assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE ); + if( zName ){ + pColl = findCollSeqEntry(db, zName, create); + if( pColl ) pColl += enc-1; + }else{ + pColl = db->pDfltColl; + } + return pColl; +} + +/* +** Change the text encoding for a database connection. This means that +** the pDfltColl must change as well. +*/ +SQLITE_PRIVATE void sqlite3SetTextEncoding(sqlite3 *db, u8 enc){ + assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); + db->enc = enc; + /* EVIDENCE-OF: R-08308-17224 The default collating function for all + ** strings is BINARY. + */ + db->pDfltColl = sqlite3FindCollSeq(db, enc, sqlite3StrBINARY, 0); + sqlite3ExpirePreparedStatements(db, 1); +} + +/* +** This function is responsible for invoking the collation factory callback +** or substituting a collation sequence of a different encoding when the +** requested collation sequence is not available in the desired encoding. +** +** If it is not NULL, then pColl must point to the database native encoding +** collation sequence with name zName, length nName. +** +** The return value is either the collation sequence to be used in database +** db for collation type name zName, length nName, or NULL, if no collation +** sequence can be found. If no collation is found, leave an error message. +** +** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq() +*/ +SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq( + Parse *pParse, /* Parsing context */ + u8 enc, /* The desired encoding for the collating sequence */ + CollSeq *pColl, /* Collating sequence with native encoding, or NULL */ + const char *zName /* Collating sequence name */ +){ + CollSeq *p; + sqlite3 *db = pParse->db; + + p = pColl; + if( !p ){ + p = sqlite3FindCollSeq(db, enc, zName, 0); + } + if( !p || !p->xCmp ){ + /* No collation sequence of this type for this encoding is registered. + ** Call the collation factory to see if it can supply us with one. + */ + callCollNeeded(db, enc, zName); + p = sqlite3FindCollSeq(db, enc, zName, 0); + } + if( p && !p->xCmp && synthCollSeq(db, p) ){ + p = 0; + } + assert( !p || p->xCmp ); + if( p==0 ){ + sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); + pParse->rc = SQLITE_ERROR_MISSING_COLLSEQ; + } + return p; +} + +/* +** This function returns the collation sequence for database native text +** encoding identified by the string zName. +** +** If the requested collation sequence is not available, or not available +** in the database native encoding, the collation factory is invoked to +** request it. If the collation factory does not supply such a sequence, +** and the sequence is available in another text encoding, then that is +** returned instead. +** +** If no versions of the requested collations sequence are available, or +** another error occurs, NULL is returned and an error message written into +** pParse. +** +** This routine is a wrapper around sqlite3FindCollSeq(). This routine +** invokes the collation factory if the named collation cannot be found +** and generates an error message. +** +** See also: sqlite3FindCollSeq(), sqlite3GetCollSeq() +*/ +SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){ + sqlite3 *db = pParse->db; + u8 enc = ENC(db); + u8 initbusy = db->init.busy; + CollSeq *pColl; + + pColl = sqlite3FindCollSeq(db, enc, zName, initbusy); + if( !initbusy && (!pColl || !pColl->xCmp) ){ + pColl = sqlite3GetCollSeq(pParse, enc, pColl, zName); + } + + return pColl; +} + +/* During the search for the best function definition, this procedure +** is called to test how well the function passed as the first argument +** matches the request for a function with nArg arguments in a system +** that uses encoding enc. The value returned indicates how well the +** request is matched. A higher value indicates a better match. +** +** If nArg is -1 that means to only return a match (non-zero) if p->nArg +** is also -1. In other words, we are searching for a function that +** takes a variable number of arguments. +** +** If nArg is -2 that means that we are searching for any function +** regardless of the number of arguments it uses, so return a positive +** match score for any +** +** The returned value is always between 0 and 6, as follows: +** +** 0: Not a match. +** 1: UTF8/16 conversion required and function takes any number of arguments. +** 2: UTF16 byte order change required and function takes any number of args. +** 3: encoding matches and function takes any number of arguments +** 4: UTF8/16 conversion required - argument count matches exactly +** 5: UTF16 byte order conversion required - argument count matches exactly +** 6: Perfect match: encoding and argument count match exactly. +** +** If nArg==(-2) then any function with a non-null xSFunc is +** a perfect match and any function with xSFunc NULL is +** a non-match. +*/ +#define FUNC_PERFECT_MATCH 6 /* The score for a perfect match */ +static int matchQuality( + FuncDef *p, /* The function we are evaluating for match quality */ + int nArg, /* Desired number of arguments. (-1)==any */ + u8 enc /* Desired text encoding */ +){ + int match; + assert( p->nArg>=(-4) && p->nArg!=(-2) ); + assert( nArg>=(-2) ); + + /* Wrong number of arguments means "no match" */ + if( p->nArg!=nArg ){ + if( nArg==(-2) ) return p->xSFunc==0 ? 0 : FUNC_PERFECT_MATCH; + if( p->nArg>=0 ) return 0; + /* Special p->nArg values available to built-in functions only: + ** -3 1 or more arguments required + ** -4 2 or more arguments required + */ + if( p->nArg<(-2) && nArg<(-2-p->nArg) ) return 0; + } + + /* Give a better score to a function with a specific number of arguments + ** than to function that accepts any number of arguments. */ + if( p->nArg==nArg ){ + match = 4; + }else{ + match = 1; + } + + /* Bonus points if the text encoding matches */ + if( enc==(p->funcFlags & SQLITE_FUNC_ENCMASK) ){ + match += 2; /* Exact encoding match */ + }else if( (enc & p->funcFlags & 2)!=0 ){ + match += 1; /* Both are UTF16, but with different byte orders */ + } + + return match; +} + +/* +** Search a FuncDefHash for a function with the given name. Return +** a pointer to the matching FuncDef if found, or 0 if there is no match. +*/ +SQLITE_PRIVATE FuncDef *sqlite3FunctionSearch( + int h, /* Hash of the name */ + const char *zFunc /* Name of function */ +){ + FuncDef *p; + for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){ + assert( p->funcFlags & SQLITE_FUNC_BUILTIN ); + if( sqlite3StrICmp(p->zName, zFunc)==0 ){ + return p; + } + } + return 0; +} + +/* +** Insert a new FuncDef into a FuncDefHash hash table. +*/ +SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs( + FuncDef *aDef, /* List of global functions to be inserted */ + int nDef /* Length of the apDef[] list */ +){ + int i; + for(i=0; ipNext!=&aDef[i] ); + aDef[i].pNext = pOther->pNext; + pOther->pNext = &aDef[i]; + }else{ + aDef[i].pNext = 0; + aDef[i].u.pHash = sqlite3BuiltinFunctions.a[h]; + sqlite3BuiltinFunctions.a[h] = &aDef[i]; + } + } +} + + + +/* +** Locate a user function given a name, a number of arguments and a flag +** indicating whether the function prefers UTF-16 over UTF-8. Return a +** pointer to the FuncDef structure that defines that function, or return +** NULL if the function does not exist. +** +** If the createFlag argument is true, then a new (blank) FuncDef +** structure is created and liked into the "db" structure if a +** no matching function previously existed. +** +** If nArg is -2, then the first valid function found is returned. A +** function is valid if xSFunc is non-zero. The nArg==(-2) +** case is used to see if zName is a valid function name for some number +** of arguments. If nArg is -2, then createFlag must be 0. +** +** If createFlag is false, then a function with the required name and +** number of arguments may be returned even if the eTextRep flag does not +** match that requested. +*/ +SQLITE_PRIVATE FuncDef *sqlite3FindFunction( + sqlite3 *db, /* An open database */ + const char *zName, /* Name of the function. zero-terminated */ + int nArg, /* Number of arguments. -1 means any number */ + u8 enc, /* Preferred text encoding */ + u8 createFlag /* Create new entry if true and does not otherwise exist */ +){ + FuncDef *p; /* Iterator variable */ + FuncDef *pBest = 0; /* Best match found so far */ + int bestScore = 0; /* Score of best match */ + int h; /* Hash value */ + int nName; /* Length of the name */ + + assert( nArg>=(-2) ); + assert( nArg>=(-1) || createFlag==0 ); + nName = sqlite3Strlen30(zName); + + /* First search for a match amongst the application-defined functions. + */ + p = (FuncDef*)sqlite3HashFind(&db->aFunc, zName); + while( p ){ + int score = matchQuality(p, nArg, enc); + if( score>bestScore ){ + pBest = p; + bestScore = score; + } + p = p->pNext; + } + + /* If no match is found, search the built-in functions. + ** + ** If the DBFLAG_PreferBuiltin flag is set, then search the built-in + ** functions even if a prior app-defined function was found. And give + ** priority to built-in functions. + ** + ** Except, if createFlag is true, that means that we are trying to + ** install a new function. Whatever FuncDef structure is returned it will + ** have fields overwritten with new information appropriate for the + ** new function. But the FuncDefs for built-in functions are read-only. + ** So we must not search for built-ins when creating a new function. + */ + if( !createFlag && (pBest==0 || (db->mDbFlags & DBFLAG_PreferBuiltin)!=0) ){ + bestScore = 0; + h = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zName[0]], nName); + p = sqlite3FunctionSearch(h, zName); + while( p ){ + int score = matchQuality(p, nArg, enc); + if( score>bestScore ){ + pBest = p; + bestScore = score; + } + p = p->pNext; + } + } + + /* If the createFlag parameter is true and the search did not reveal an + ** exact match for the name, number of arguments and encoding, then add a + ** new entry to the hash table and return it. + */ + if( createFlag && bestScorezName = (const char*)&pBest[1]; + pBest->nArg = (u16)nArg; + pBest->funcFlags = enc; + memcpy((char*)&pBest[1], zName, nName+1); + for(z=(u8*)pBest->zName; *z; z++) *z = sqlite3UpperToLower[*z]; + pOther = (FuncDef*)sqlite3HashInsert(&db->aFunc, pBest->zName, pBest); + if( pOther==pBest ){ + sqlite3DbFree(db, pBest); + sqlite3OomFault(db); + return 0; + }else{ + pBest->pNext = pOther; + } + } + + if( pBest && (pBest->xSFunc || createFlag) ){ + return pBest; + } + return 0; +} + +/* +** Free all resources held by the schema structure. The void* argument points +** at a Schema struct. This function does not call sqlite3DbFree(db, ) on the +** pointer itself, it just cleans up subsidiary resources (i.e. the contents +** of the schema hash tables). +** +** The Schema.cache_size variable is not cleared. +*/ +SQLITE_PRIVATE void sqlite3SchemaClear(void *p){ + Hash temp1; + Hash temp2; + HashElem *pElem; + Schema *pSchema = (Schema *)p; + sqlite3 xdb; + + memset(&xdb, 0, sizeof(xdb)); + temp1 = pSchema->tblHash; + temp2 = pSchema->trigHash; + sqlite3HashInit(&pSchema->trigHash); + sqlite3HashClear(&pSchema->idxHash); + for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){ + sqlite3DeleteTrigger(&xdb, (Trigger*)sqliteHashData(pElem)); + } + + sqlite3HashClear(&temp2); + sqlite3HashInit(&pSchema->tblHash); + for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){ + Table *pTab = sqliteHashData(pElem); + sqlite3DeleteTable(&xdb, pTab); + } + sqlite3HashClear(&temp1); + sqlite3HashClear(&pSchema->fkeyHash); + pSchema->pSeqTab = 0; + if( pSchema->schemaFlags & DB_SchemaLoaded ){ + pSchema->iGeneration++; + } + pSchema->schemaFlags &= ~(DB_SchemaLoaded|DB_ResetWanted); +} + +/* +** Find and return the schema associated with a BTree. Create +** a new one if necessary. +*/ +SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ + Schema * p; + if( pBt ){ + p = (Schema *)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaClear); + }else{ + p = (Schema *)sqlite3DbMallocZero(0, sizeof(Schema)); + } + if( !p ){ + sqlite3OomFault(db); + }else if ( 0==p->file_format ){ + sqlite3HashInit(&p->tblHash); + sqlite3HashInit(&p->idxHash); + sqlite3HashInit(&p->trigHash); + sqlite3HashInit(&p->fkeyHash); + p->enc = SQLITE_UTF8; + } + return p; +} + +/************** End of callback.c ********************************************/ +/************** Begin file delete.c ******************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains C code routines that are called by the parser +** in order to generate code for DELETE FROM statements. +*/ +/* #include "sqliteInt.h" */ + +/* +** While a SrcList can in general represent multiple tables and subqueries +** (as in the FROM clause of a SELECT statement) in this case it contains +** the name of a single table, as one might find in an INSERT, DELETE, +** or UPDATE statement. Look up that table in the symbol table and +** return a pointer. Set an error message and return NULL if the table +** name is not found or if any other error occurs. +** +** The following fields are initialized appropriate in pSrc: +** +** pSrc->a[0].spTab Pointer to the Table object +** pSrc->a[0].u2.pIBIndex Pointer to the INDEXED BY index, if there is one +** +*/ +SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ + SrcItem *pItem = pSrc->a; + Table *pTab; + assert( pItem && pSrc->nSrc>=1 ); + pTab = sqlite3LocateTableItem(pParse, 0, pItem); + if( pItem->pSTab ) sqlite3DeleteTable(pParse->db, pItem->pSTab); + pItem->pSTab = pTab; + pItem->fg.notCte = 1; + if( pTab ){ + pTab->nTabRef++; + if( pItem->fg.isIndexedBy && sqlite3IndexedByLookup(pParse, pItem) ){ + pTab = 0; + } + } + return pTab; +} + +/* Generate byte-code that will report the number of rows modified +** by a DELETE, INSERT, or UPDATE statement. +*/ +SQLITE_PRIVATE void sqlite3CodeChangeCount(Vdbe *v, int regCounter, const char *zColName){ + sqlite3VdbeAddOp0(v, OP_FkCheck); + sqlite3VdbeAddOp2(v, OP_ResultRow, regCounter, 1); + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zColName, SQLITE_STATIC); +} + +/* Return true if table pTab is read-only. +** +** A table is read-only if any of the following are true: +** +** 1) It is a virtual table and no implementation of the xUpdate method +** has been provided +** +** 2) A trigger is currently being coded and the table is a virtual table +** that is SQLITE_VTAB_DIRECTONLY or if PRAGMA trusted_schema=OFF and +** the table is not SQLITE_VTAB_INNOCUOUS. +** +** 3) It is a system table (i.e. sqlite_schema), this call is not +** part of a nested parse and writable_schema pragma has not +** been specified +** +** 4) The table is a shadow table, the database connection is in +** defensive mode, and the current sqlite3_prepare() +** is for a top-level SQL statement. +*/ +static int vtabIsReadOnly(Parse *pParse, Table *pTab){ + assert( IsVirtual(pTab) ); + if( sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 ){ + return 1; + } + + /* Within triggers: + ** * Do not allow DELETE, INSERT, or UPDATE of SQLITE_VTAB_DIRECTONLY + ** virtual tables + ** * Only allow DELETE, INSERT, or UPDATE of non-SQLITE_VTAB_INNOCUOUS + ** virtual tables if PRAGMA trusted_schema=ON. + */ + if( (pParse->pToplevel!=0 || (pParse->prepFlags & SQLITE_PREPARE_FROM_DDL)) + && pTab->u.vtab.p->eVtabRisk > + ((pParse->db->flags & SQLITE_TrustedSchema)!=0) + ){ + sqlite3ErrorMsg(pParse, "unsafe use of virtual table \"%s\"", + pTab->zName); + } + return 0; +} +static int tabIsReadOnly(Parse *pParse, Table *pTab){ + sqlite3 *db; + if( IsVirtual(pTab) ){ + return vtabIsReadOnly(pParse, pTab); + } + if( (pTab->tabFlags & (TF_Readonly|TF_Shadow))==0 ) return 0; + db = pParse->db; + if( (pTab->tabFlags & TF_Readonly)!=0 ){ + return sqlite3WritableSchema(db)==0 && pParse->nested==0; + } + assert( pTab->tabFlags & TF_Shadow ); + return sqlite3ReadOnlyShadowTables(db); +} + +/* +** Check to make sure the given table is writable. +** +** If pTab is not writable -> generate an error message and return 1. +** If pTab is writable but other errors have occurred -> return 1. +** If pTab is writable and no prior errors -> return 0; +*/ +SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, Trigger *pTrigger){ + if( tabIsReadOnly(pParse, pTab) ){ + sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName); + return 1; + } +#ifndef SQLITE_OMIT_VIEW + if( IsView(pTab) + && (pTrigger==0 || (pTrigger->bReturning && pTrigger->pNext==0)) + ){ + sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName); + return 1; + } +#endif + return 0; +} + + +#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) +/* +** Evaluate a view and store its result in an ephemeral table. The +** pWhere argument is an optional WHERE clause that restricts the +** set of rows in the view that are to be added to the ephemeral table. +*/ +SQLITE_PRIVATE void sqlite3MaterializeView( + Parse *pParse, /* Parsing context */ + Table *pView, /* View definition */ + Expr *pWhere, /* Optional WHERE clause to be added */ + ExprList *pOrderBy, /* Optional ORDER BY clause */ + Expr *pLimit, /* Optional LIMIT clause */ + int iCur /* Cursor number for ephemeral table */ +){ + SelectDest dest; + Select *pSel; + SrcList *pFrom; + sqlite3 *db = pParse->db; + int iDb = sqlite3SchemaToIndex(db, pView->pSchema); + pWhere = sqlite3ExprDup(db, pWhere, 0); + pFrom = sqlite3SrcListAppend(pParse, 0, 0, 0); + if( pFrom ){ + assert( pFrom->nSrc==1 ); + pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName); + assert( pFrom->a[0].fg.fixedSchema==0 && pFrom->a[0].fg.isSubquery==0 ); + pFrom->a[0].u4.zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); + assert( pFrom->a[0].fg.isUsing==0 ); + assert( pFrom->a[0].u3.pOn==0 ); + } + pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, pOrderBy, + SF_IncludeHidden, pLimit); + sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur); + sqlite3Select(pParse, pSel, &dest); + sqlite3SelectDelete(db, pSel); +} +#endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */ + +#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) +/* +** Generate an expression tree to implement the WHERE, ORDER BY, +** and LIMIT/OFFSET portion of DELETE and UPDATE statements. +** +** DELETE FROM table_wxyz WHERE a<5 ORDER BY a LIMIT 1; +** \__________________________/ +** pLimitWhere (pInClause) +*/ +SQLITE_PRIVATE Expr *sqlite3LimitWhere( + Parse *pParse, /* The parser context */ + SrcList *pSrc, /* the FROM clause -- which tables to scan */ + Expr *pWhere, /* The WHERE clause. May be null */ + ExprList *pOrderBy, /* The ORDER BY clause. May be null */ + Expr *pLimit, /* The LIMIT clause. May be null */ + char *zStmtType /* Either DELETE or UPDATE. For err msgs. */ +){ + sqlite3 *db = pParse->db; + Expr *pLhs = NULL; /* LHS of IN(SELECT...) operator */ + Expr *pInClause = NULL; /* WHERE rowid IN ( select ) */ + ExprList *pEList = NULL; /* Expression list containing only pSelectRowid*/ + SrcList *pSelectSrc = NULL; /* SELECT rowid FROM x ... (dup of pSrc) */ + Select *pSelect = NULL; /* Complete SELECT tree */ + Table *pTab; + + /* Check that there isn't an ORDER BY without a LIMIT clause. + */ + if( pOrderBy && pLimit==0 ) { + sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType); + sqlite3ExprDelete(pParse->db, pWhere); + sqlite3ExprListDelete(pParse->db, pOrderBy); + return 0; + } + + /* We only need to generate a select expression if there + ** is a limit/offset term to enforce. + */ + if( pLimit == 0 ) { + return pWhere; + } + + /* Generate a select expression tree to enforce the limit/offset + ** term for the DELETE or UPDATE statement. For example: + ** DELETE FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1 + ** becomes: + ** DELETE FROM table_a WHERE rowid IN ( + ** SELECT rowid FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1 + ** ); + */ + + pTab = pSrc->a[0].pSTab; + if( HasRowid(pTab) ){ + pLhs = sqlite3PExpr(pParse, TK_ROW, 0, 0); + pEList = sqlite3ExprListAppend( + pParse, 0, sqlite3PExpr(pParse, TK_ROW, 0, 0) + ); + }else{ + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + assert( pPk!=0 ); + assert( pPk->nKeyCol>=1 ); + if( pPk->nKeyCol==1 ){ + const char *zName; + assert( pPk->aiColumn[0]>=0 && pPk->aiColumn[0]nCol ); + zName = pTab->aCol[pPk->aiColumn[0]].zCnName; + pLhs = sqlite3Expr(db, TK_ID, zName); + pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ID, zName)); + }else{ + int i; + for(i=0; inKeyCol; i++){ + Expr *p; + assert( pPk->aiColumn[i]>=0 && pPk->aiColumn[i]nCol ); + p = sqlite3Expr(db, TK_ID, pTab->aCol[pPk->aiColumn[i]].zCnName); + pEList = sqlite3ExprListAppend(pParse, pEList, p); + } + pLhs = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); + if( pLhs ){ + pLhs->x.pList = sqlite3ExprListDup(db, pEList, 0); + } + } + } + + /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree + ** and the SELECT subtree. */ + pSrc->a[0].pSTab = 0; + pSelectSrc = sqlite3SrcListDup(db, pSrc, 0); + pSrc->a[0].pSTab = pTab; + if( pSrc->a[0].fg.isIndexedBy ){ + assert( pSrc->a[0].fg.isCte==0 ); + pSrc->a[0].u2.pIBIndex = 0; + pSrc->a[0].fg.isIndexedBy = 0; + sqlite3DbFree(db, pSrc->a[0].u1.zIndexedBy); + }else if( pSrc->a[0].fg.isCte ){ + pSrc->a[0].u2.pCteUse->nUse++; + } + + /* generate the SELECT expression tree. */ + pSelect = sqlite3SelectNew(pParse, pEList, pSelectSrc, pWhere, 0 ,0, + pOrderBy,0,pLimit + ); + + /* now generate the new WHERE rowid IN clause for the DELETE/UPDATE */ + pInClause = sqlite3PExpr(pParse, TK_IN, pLhs, 0); + sqlite3PExprAddSelect(pParse, pInClause, pSelect); + return pInClause; +} +#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) */ + /* && !defined(SQLITE_OMIT_SUBQUERY) */ + +/* +** Generate code for a DELETE FROM statement. +** +** DELETE FROM table_wxyz WHERE a<5 AND b NOT NULL; +** \________/ \________________/ +** pTabList pWhere +*/ +SQLITE_PRIVATE void sqlite3DeleteFrom( + Parse *pParse, /* The parser context */ + SrcList *pTabList, /* The table from which we should delete things */ + Expr *pWhere, /* The WHERE clause. May be null */ + ExprList *pOrderBy, /* ORDER BY clause. May be null */ + Expr *pLimit /* LIMIT clause. May be null */ +){ + Vdbe *v; /* The virtual database engine */ + Table *pTab; /* The table from which records will be deleted */ + int i; /* Loop counter */ + WhereInfo *pWInfo; /* Information about the WHERE clause */ + Index *pIdx; /* For looping over indices of the table */ + int iTabCur; /* Cursor number for the table */ + int iDataCur = 0; /* VDBE cursor for the canonical data source */ + int iIdxCur = 0; /* Cursor number of the first index */ + int nIdx; /* Number of indices */ + sqlite3 *db; /* Main database structure */ + AuthContext sContext; /* Authorization context */ + NameContext sNC; /* Name context to resolve expressions in */ + int iDb; /* Database number */ + int memCnt = 0; /* Memory cell used for change counting */ + int rcauth; /* Value returned by authorization callback */ + int eOnePass; /* ONEPASS_OFF or _SINGLE or _MULTI */ + int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */ + u8 *aToOpen = 0; /* Open cursor iTabCur+j if aToOpen[j] is true */ + Index *pPk; /* The PRIMARY KEY index on the table */ + int iPk = 0; /* First of nPk registers holding PRIMARY KEY value */ + i16 nPk = 1; /* Number of columns in the PRIMARY KEY */ + int iKey; /* Memory cell holding key of row to be deleted */ + i16 nKey; /* Number of memory cells in the row key */ + int iEphCur = 0; /* Ephemeral table holding all primary key values */ + int iRowSet = 0; /* Register for rowset of rows to delete */ + int addrBypass = 0; /* Address of jump over the delete logic */ + int addrLoop = 0; /* Top of the delete loop */ + int addrEphOpen = 0; /* Instruction to open the Ephemeral table */ + int bComplex; /* True if there are triggers or FKs or + ** subqueries in the WHERE clause */ + +#ifndef SQLITE_OMIT_TRIGGER + int isView; /* True if attempting to delete from a view */ + Trigger *pTrigger; /* List of table triggers, if required */ +#endif + + memset(&sContext, 0, sizeof(sContext)); + db = pParse->db; + assert( db->pParse==pParse ); + if( pParse->nErr ){ + goto delete_from_cleanup; + } + assert( db->mallocFailed==0 ); + assert( pTabList->nSrc==1 ); + + /* Locate the table which we want to delete. This table has to be + ** put in an SrcList structure because some of the subroutines we + ** will be calling are designed to work with multiple tables and expect + ** an SrcList* parameter instead of just a Table* parameter. + */ + pTab = sqlite3SrcListLookup(pParse, pTabList); + if( pTab==0 ) goto delete_from_cleanup; + + /* Figure out if we have any triggers and if the table being + ** deleted from is a view + */ +#ifndef SQLITE_OMIT_TRIGGER + pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); + isView = IsView(pTab); +#else +# define pTrigger 0 +# define isView 0 +#endif + bComplex = pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0); +#ifdef SQLITE_OMIT_VIEW +# undef isView +# define isView 0 +#endif + +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x10000 ){ + sqlite3TreeViewLine(0, "In sqlite3Delete() at %s:%d", __FILE__, __LINE__); + sqlite3TreeViewDelete(pParse->pWith, pTabList, pWhere, + pOrderBy, pLimit, pTrigger); + } +#endif + +#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT + if( !isView ){ + pWhere = sqlite3LimitWhere( + pParse, pTabList, pWhere, pOrderBy, pLimit, "DELETE" + ); + pOrderBy = 0; + pLimit = 0; + } +#endif + + /* If pTab is really a view, make sure it has been initialized. + */ + if( sqlite3ViewGetColumnNames(pParse, pTab) ){ + goto delete_from_cleanup; + } + + if( sqlite3IsReadOnly(pParse, pTab, pTrigger) ){ + goto delete_from_cleanup; + } + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iDbnDb ); + rcauth = sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, + db->aDb[iDb].zDbSName); + assert( rcauth==SQLITE_OK || rcauth==SQLITE_DENY || rcauth==SQLITE_IGNORE ); + if( rcauth==SQLITE_DENY ){ + goto delete_from_cleanup; + } + assert(!isView || pTrigger); + + /* Assign cursor numbers to the table and all its indices. + */ + assert( pTabList->nSrc==1 ); + iTabCur = pTabList->a[0].iCursor = pParse->nTab++; + for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ + pParse->nTab++; + } + + /* Start the view context + */ + if( isView ){ + sqlite3AuthContextPush(pParse, &sContext, pTab->zName); + } + + /* Begin generating code. + */ + v = sqlite3GetVdbe(pParse); + if( v==0 ){ + goto delete_from_cleanup; + } + if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); + sqlite3BeginWriteOperation(pParse, bComplex, iDb); + + /* If we are trying to delete from a view, realize that view into + ** an ephemeral table. + */ +#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) + if( isView ){ + sqlite3MaterializeView(pParse, pTab, + pWhere, pOrderBy, pLimit, iTabCur + ); + iDataCur = iIdxCur = iTabCur; + pOrderBy = 0; + pLimit = 0; + } +#endif + + /* Resolve the column names in the WHERE clause. + */ + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + sNC.pSrcList = pTabList; + if( sqlite3ResolveExprNames(&sNC, pWhere) ){ + goto delete_from_cleanup; + } + + /* Initialize the counter of the number of rows deleted, if + ** we are counting rows. + */ + if( (db->flags & SQLITE_CountRows)!=0 + && !pParse->nested + && !pParse->pTriggerTab + && !pParse->bReturning + ){ + memCnt = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt); + } + +#ifndef SQLITE_OMIT_TRUNCATE_OPTIMIZATION + /* Special case: A DELETE without a WHERE clause deletes everything. + ** It is easier just to erase the whole table. Prior to version 3.6.5, + ** this optimization caused the row change count (the value returned by + ** API function sqlite3_count_changes) to be set incorrectly. + ** + ** The "rcauth==SQLITE_OK" terms is the + ** IMPLEMENTATION-OF: R-17228-37124 If the action code is SQLITE_DELETE and + ** the callback returns SQLITE_IGNORE then the DELETE operation proceeds but + ** the truncate optimization is disabled and all rows are deleted + ** individually. + */ + if( rcauth==SQLITE_OK + && pWhere==0 + && !bComplex + && !IsVirtual(pTab) +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + && db->xPreUpdateCallback==0 +#endif + ){ + assert( !isView ); + sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName); + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt ? memCnt : -1, + pTab->zName, P4_STATIC); + } + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + assert( pIdx->pSchema==pTab->pSchema ); + if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ + sqlite3VdbeAddOp3(v, OP_Clear, pIdx->tnum, iDb, memCnt ? memCnt : -1); + }else{ + sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb); + } + } + }else +#endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */ + { + u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK; + if( sNC.ncFlags & NC_Subquery ) bComplex = 1; + wcf |= (bComplex ? 0 : WHERE_ONEPASS_MULTIROW); + if( HasRowid(pTab) ){ + /* For a rowid table, initialize the RowSet to an empty set */ + pPk = 0; + assert( nPk==1 ); + iRowSet = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet); + }else{ + /* For a WITHOUT ROWID table, create an ephemeral table used to + ** hold all primary keys for rows to be deleted. */ + pPk = sqlite3PrimaryKeyIndex(pTab); + assert( pPk!=0 ); + nPk = pPk->nKeyCol; + iPk = pParse->nMem+1; + pParse->nMem += nPk; + iEphCur = pParse->nTab++; + addrEphOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEphCur, nPk); + sqlite3VdbeSetP4KeyInfo(pParse, pPk); + } + + /* Construct a query to find the rowid or primary key for every row + ** to be deleted, based on the WHERE clause. Set variable eOnePass + ** to indicate the strategy used to implement this delete: + ** + ** ONEPASS_OFF: Two-pass approach - use a FIFO for rowids/PK values. + ** ONEPASS_SINGLE: One-pass approach - at most one row deleted. + ** ONEPASS_MULTI: One-pass approach - any number of rows may be deleted. + */ + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0,0,wcf,iTabCur+1); + if( pWInfo==0 ) goto delete_from_cleanup; + eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); + assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI ); + assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF + || OptimizationDisabled(db, SQLITE_OnePass) ); + if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse); + if( sqlite3WhereUsesDeferredSeek(pWInfo) ){ + sqlite3VdbeAddOp1(v, OP_FinishSeek, iTabCur); + } + + /* Keep track of the number of rows to be deleted */ + if( memCnt ){ + sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1); + } + + /* Extract the rowid or primary key for the current row */ + if( pPk ){ + for(i=0; iaiColumn[i]>=0 ); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, + pPk->aiColumn[i], iPk+i); + } + iKey = iPk; + }else{ + iKey = ++pParse->nMem; + sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, -1, iKey); + } + + if( eOnePass!=ONEPASS_OFF ){ + /* For ONEPASS, no need to store the rowid/primary-key. There is only + ** one, so just keep it in its register(s) and fall through to the + ** delete code. */ + nKey = nPk; /* OP_Found will use an unpacked key */ + aToOpen = sqlite3DbMallocRawNN(db, nIdx+2); + if( aToOpen==0 ){ + sqlite3WhereEnd(pWInfo); + goto delete_from_cleanup; + } + memset(aToOpen, 1, nIdx+1); + aToOpen[nIdx+1] = 0; + if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0; + if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iTabCur] = 0; + if( addrEphOpen ) sqlite3VdbeChangeToNoop(v, addrEphOpen); + addrBypass = sqlite3VdbeMakeLabel(pParse); + }else{ + if( pPk ){ + /* Add the PK key for this row to the temporary table */ + iKey = ++pParse->nMem; + nKey = 0; /* Zero tells OP_Found to use a composite key */ + sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey, + sqlite3IndexAffinityStr(pParse->db, pPk), nPk); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iEphCur, iKey, iPk, nPk); + }else{ + /* Add the rowid of the row to be deleted to the RowSet */ + nKey = 1; /* OP_DeferredSeek always uses a single rowid */ + sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey); + } + sqlite3WhereEnd(pWInfo); + } + + /* Unless this is a view, open cursors for the table we are + ** deleting from and all its indices. If this is a view, then the + ** only effect this statement has is to fire the INSTEAD OF + ** triggers. + */ + if( !isView ){ + int iAddrOnce = 0; + if( eOnePass==ONEPASS_MULTI ){ + iAddrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + } + testcase( IsVirtual(pTab) ); + sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, OPFLAG_FORDELETE, + iTabCur, aToOpen, &iDataCur, &iIdxCur); + assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur ); + assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 ); + if( eOnePass==ONEPASS_MULTI ){ + sqlite3VdbeJumpHereOrPopInst(v, iAddrOnce); + } + } + + /* Set up a loop over the rowids/primary-keys that were found in the + ** where-clause loop above. + */ + if( eOnePass!=ONEPASS_OFF ){ + assert( nKey==nPk ); /* OP_Found will use an unpacked key */ + if( !IsVirtual(pTab) && aToOpen[iDataCur-iTabCur] ){ + assert( pPk!=0 || IsView(pTab) ); + sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey); + VdbeCoverage(v); + } + }else if( pPk ){ + addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v); + if( IsVirtual(pTab) ){ + sqlite3VdbeAddOp3(v, OP_Column, iEphCur, 0, iKey); + }else{ + sqlite3VdbeAddOp2(v, OP_RowData, iEphCur, iKey); + } + assert( nKey==0 ); /* OP_Found will use a composite key */ + }else{ + addrLoop = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, 0, iKey); + VdbeCoverage(v); + assert( nKey==1 ); + } + + /* Delete the row */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); + sqlite3VtabMakeWritable(pParse, pTab); + assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE ); + sqlite3MayAbort(pParse); + if( eOnePass==ONEPASS_SINGLE ){ + sqlite3VdbeAddOp1(v, OP_Close, iTabCur); + if( sqlite3IsToplevel(pParse) ){ + pParse->isMultiWrite = 0; + } + } + sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB); + sqlite3VdbeChangeP5(v, OE_Abort); + }else +#endif + { + int count = (pParse->nested==0); /* True to count changes */ + sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, + iKey, nKey, count, OE_Default, eOnePass, aiCurOnePass[1]); + } + + /* End of the loop over all rowids/primary-keys. */ + if( eOnePass!=ONEPASS_OFF ){ + sqlite3VdbeResolveLabel(v, addrBypass); + sqlite3WhereEnd(pWInfo); + }else if( pPk ){ + sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addrLoop); + }else{ + sqlite3VdbeGoto(v, addrLoop); + sqlite3VdbeJumpHere(v, addrLoop); + } + } /* End non-truncate path */ + + /* Update the sqlite_sequence table by storing the content of the + ** maximum rowid counter values recorded while inserting into + ** autoincrement tables. + */ + if( pParse->nested==0 && pParse->pTriggerTab==0 ){ + sqlite3AutoincrementEnd(pParse); + } + + /* Return the number of rows that were deleted. If this routine is + ** generating code because of a call to sqlite3NestedParse(), do not + ** invoke the callback function. + */ + if( memCnt ){ + sqlite3CodeChangeCount(v, memCnt, "rows deleted"); + } + +delete_from_cleanup: + sqlite3AuthContextPop(&sContext); + sqlite3SrcListDelete(db, pTabList); + sqlite3ExprDelete(db, pWhere); +#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) + sqlite3ExprListDelete(db, pOrderBy); + sqlite3ExprDelete(db, pLimit); +#endif + if( aToOpen ) sqlite3DbNNFreeNN(db, aToOpen); + return; +} +/* Make sure "isView" and other macros defined above are undefined. Otherwise +** they may interfere with compilation of other functions in this file +** (or in another file, if this file becomes part of the amalgamation). */ +#ifdef isView + #undef isView +#endif +#ifdef pTrigger + #undef pTrigger +#endif + +/* +** This routine generates VDBE code that causes a single row of a +** single table to be deleted. Both the original table entry and +** all indices are removed. +** +** Preconditions: +** +** 1. iDataCur is an open cursor on the btree that is the canonical data +** store for the table. (This will be either the table itself, +** in the case of a rowid table, or the PRIMARY KEY index in the case +** of a WITHOUT ROWID table.) +** +** 2. Read/write cursors for all indices of pTab must be open as +** cursor number iIdxCur+i for the i-th index. +** +** 3. The primary key for the row to be deleted must be stored in a +** sequence of nPk memory cells starting at iPk. If nPk==0 that means +** that a search record formed from OP_MakeRecord is contained in the +** single memory location iPk. +** +** eMode: +** Parameter eMode may be passed either ONEPASS_OFF (0), ONEPASS_SINGLE, or +** ONEPASS_MULTI. If eMode is not ONEPASS_OFF, then the cursor +** iDataCur already points to the row to delete. If eMode is ONEPASS_OFF +** then this function must seek iDataCur to the entry identified by iPk +** and nPk before reading from it. +** +** If eMode is ONEPASS_MULTI, then this call is being made as part +** of a ONEPASS delete that affects multiple rows. In this case, if +** iIdxNoSeek is a valid cursor number (>=0) and is not the same as +** iDataCur, then its position should be preserved following the delete +** operation. Or, if iIdxNoSeek is not a valid cursor number, the +** position of iDataCur should be preserved instead. +** +** iIdxNoSeek: +** If iIdxNoSeek is a valid cursor number (>=0) not equal to iDataCur, +** then it identifies an index cursor (from within array of cursors +** starting at iIdxCur) that already points to the index entry to be deleted. +** Except, this optimization is disabled if there are BEFORE triggers since +** the trigger body might have moved the cursor. +*/ +SQLITE_PRIVATE void sqlite3GenerateRowDelete( + Parse *pParse, /* Parsing context */ + Table *pTab, /* Table containing the row to be deleted */ + Trigger *pTrigger, /* List of triggers to (potentially) fire */ + int iDataCur, /* Cursor from which column data is extracted */ + int iIdxCur, /* First index cursor */ + int iPk, /* First memory cell containing the PRIMARY KEY */ + i16 nPk, /* Number of PRIMARY KEY memory cells */ + u8 count, /* If non-zero, increment the row change counter */ + u8 onconf, /* Default ON CONFLICT policy for triggers */ + u8 eMode, /* ONEPASS_OFF, _SINGLE, or _MULTI. See above */ + int iIdxNoSeek /* Cursor number of cursor that does not need seeking */ +){ + Vdbe *v = pParse->pVdbe; /* Vdbe */ + int iOld = 0; /* First register in OLD.* array */ + int iLabel; /* Label resolved to end of generated code */ + u8 opSeek; /* Seek opcode */ + + /* Vdbe is guaranteed to have been allocated by this stage. */ + assert( v ); + VdbeModuleComment((v, "BEGIN: GenRowDel(%d,%d,%d,%d)", + iDataCur, iIdxCur, iPk, (int)nPk)); + + /* Seek cursor iCur to the row to delete. If this row no longer exists + ** (this can happen if a trigger program has already deleted it), do + ** not attempt to delete it or fire any DELETE triggers. */ + iLabel = sqlite3VdbeMakeLabel(pParse); + opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound; + if( eMode==ONEPASS_OFF ){ + sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk); + VdbeCoverageIf(v, opSeek==OP_NotExists); + VdbeCoverageIf(v, opSeek==OP_NotFound); + } + + /* If there are any triggers to fire, allocate a range of registers to + ** use for the old.* references in the triggers. */ + if( sqlite3FkRequired(pParse, pTab, 0, 0) || pTrigger ){ + u32 mask; /* Mask of OLD.* columns in use */ + int iCol; /* Iterator used while populating OLD.* */ + int addrStart; /* Start of BEFORE trigger programs */ + + /* TODO: Could use temporary registers here. Also could attempt to + ** avoid copying the contents of the rowid register. */ + mask = sqlite3TriggerColmask( + pParse, pTrigger, 0, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onconf + ); + mask |= sqlite3FkOldmask(pParse, pTab); + iOld = pParse->nMem+1; + pParse->nMem += (1 + pTab->nCol); + + /* Populate the OLD.* pseudo-table register array. These values will be + ** used by any BEFORE and AFTER triggers that exist. */ + sqlite3VdbeAddOp2(v, OP_Copy, iPk, iOld); + for(iCol=0; iColnCol; iCol++){ + testcase( mask!=0xffffffff && iCol==31 ); + testcase( mask!=0xffffffff && iCol==32 ); + if( mask==0xffffffff || (iCol<=31 && (mask & MASKBIT32(iCol))!=0) ){ + int kk = sqlite3TableColumnToStorage(pTab, iCol); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, iCol, iOld+kk+1); + } + } + + /* Invoke BEFORE DELETE trigger programs. */ + addrStart = sqlite3VdbeCurrentAddr(v); + sqlite3CodeRowTrigger(pParse, pTrigger, + TK_DELETE, 0, TRIGGER_BEFORE, pTab, iOld, onconf, iLabel + ); + + /* If any BEFORE triggers were coded, then seek the cursor to the + ** row to be deleted again. It may be that the BEFORE triggers moved + ** the cursor or already deleted the row that the cursor was + ** pointing to. + ** + ** Also disable the iIdxNoSeek optimization since the BEFORE trigger + ** may have moved that cursor. + */ + if( addrStart=0 ); + iIdxNoSeek = -1; + } + + /* Do FK processing. This call checks that any FK constraints that + ** refer to this table (i.e. constraints attached to other tables) + ** are not violated by deleting this row. */ + sqlite3FkCheck(pParse, pTab, iOld, 0, 0, 0); + } + + /* Delete the index and table entries. Skip this step if pTab is really + ** a view (in which case the only effect of the DELETE statement is to + ** fire the INSTEAD OF triggers). + ** + ** If variable 'count' is non-zero, then this OP_Delete instruction should + ** invoke the update-hook. The pre-update-hook, on the other hand should + ** be invoked unless table pTab is a system table. The difference is that + ** the update-hook is not invoked for rows removed by REPLACE, but the + ** pre-update-hook is. + */ + if( !IsView(pTab) ){ + u8 p5 = 0; + sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek); + sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0)); + if( pParse->nested==0 || 0==sqlite3_stricmp(pTab->zName, "sqlite_stat1") ){ + sqlite3VdbeAppendP4(v, (char*)pTab, P4_TABLE); + } + if( eMode!=ONEPASS_OFF ){ + sqlite3VdbeChangeP5(v, OPFLAG_AUXDELETE); + } + if( iIdxNoSeek>=0 && iIdxNoSeek!=iDataCur ){ + sqlite3VdbeAddOp1(v, OP_Delete, iIdxNoSeek); + } + if( eMode==ONEPASS_MULTI ) p5 |= OPFLAG_SAVEPOSITION; + sqlite3VdbeChangeP5(v, p5); + } + + /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to + ** handle rows (possibly in other tables) that refer via a foreign key + ** to the row just deleted. */ + sqlite3FkActions(pParse, pTab, 0, iOld, 0, 0); + + /* Invoke AFTER DELETE trigger programs. */ + if( pTrigger ){ + sqlite3CodeRowTrigger(pParse, pTrigger, + TK_DELETE, 0, TRIGGER_AFTER, pTab, iOld, onconf, iLabel + ); + } + + /* Jump here if the row had already been deleted before any BEFORE + ** trigger programs were invoked. Or if a trigger program throws a + ** RAISE(IGNORE) exception. */ + sqlite3VdbeResolveLabel(v, iLabel); + VdbeModuleComment((v, "END: GenRowDel()")); +} + +/* +** This routine generates VDBE code that causes the deletion of all +** index entries associated with a single row of a single table, pTab +** +** Preconditions: +** +** 1. A read/write cursor "iDataCur" must be open on the canonical storage +** btree for the table pTab. (This will be either the table itself +** for rowid tables or to the primary key index for WITHOUT ROWID +** tables.) +** +** 2. Read/write cursors for all indices of pTab must be open as +** cursor number iIdxCur+i for the i-th index. (The pTab->pIndex +** index is the 0-th index.) +** +** 3. The "iDataCur" cursor must be already be positioned on the row +** that is to be deleted. +*/ +SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete( + Parse *pParse, /* Parsing and code generating context */ + Table *pTab, /* Table containing the row to be deleted */ + int iDataCur, /* Cursor of table holding data. */ + int iIdxCur, /* First index cursor */ + int *aRegIdx, /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */ + int iIdxNoSeek /* Do not delete from this cursor */ +){ + int i; /* Index loop counter */ + int r1 = -1; /* Register holding an index key */ + int iPartIdxLabel; /* Jump destination for skipping partial index entries */ + Index *pIdx; /* Current index */ + Index *pPrior = 0; /* Prior index */ + Vdbe *v; /* The prepared statement under construction */ + Index *pPk; /* PRIMARY KEY index, or NULL for rowid tables */ + + v = pParse->pVdbe; + pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); + for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ + assert( iIdxCur+i!=iDataCur || pPk==pIdx ); + if( aRegIdx!=0 && aRegIdx[i]==0 ) continue; + if( pIdx==pPk ) continue; + if( iIdxCur+i==iIdxNoSeek ) continue; + VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName)); + r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1, + &iPartIdxLabel, pPrior, r1); + sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1, + pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn + ); + sqlite3VdbeChangeP4(v, -1, (const char*)pIdx, P4_INDEX); + sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel); + pPrior = pIdx; + } +} + +/* +** Generate code that will assemble an index key and stores it in register +** regOut. The key with be for index pIdx which is an index on pTab. +** iCur is the index of a cursor open on the pTab table and pointing to +** the entry that needs indexing. If pTab is a WITHOUT ROWID table, then +** iCur must be the cursor of the PRIMARY KEY index. +** +** Return a register number which is the first in a block of +** registers that holds the elements of the index key. The +** block of registers has already been deallocated by the time +** this routine returns. +** +** If *piPartIdxLabel is not NULL, fill it in with a label and jump +** to that label if pIdx is a partial index that should be skipped. +** The label should be resolved using sqlite3ResolvePartIdxLabel(). +** A partial index should be skipped if its WHERE clause evaluates +** to false or null. If pIdx is not a partial index, *piPartIdxLabel +** will be set to zero which is an empty label that is ignored by +** sqlite3ResolvePartIdxLabel(). +** +** The pPrior and regPrior parameters are used to implement a cache to +** avoid unnecessary register loads. If pPrior is not NULL, then it is +** a pointer to a different index for which an index key has just been +** computed into register regPrior. If the current pIdx index is generating +** its key into the same sequence of registers and if pPrior and pIdx share +** a column in common, then the register corresponding to that column already +** holds the correct value and the loading of that register is skipped. +** This optimization is helpful when doing a DELETE or an INTEGRITY_CHECK +** on a table with multiple indices, and especially with the ROWID or +** PRIMARY KEY columns of the index. +*/ +SQLITE_PRIVATE int sqlite3GenerateIndexKey( + Parse *pParse, /* Parsing context */ + Index *pIdx, /* The index for which to generate a key */ + int iDataCur, /* Cursor number from which to take column data */ + int regOut, /* Put the new key into this register if not 0 */ + int prefixOnly, /* Compute only a unique prefix of the key */ + int *piPartIdxLabel, /* OUT: Jump to this label to skip partial index */ + Index *pPrior, /* Previously generated index key */ + int regPrior /* Register holding previous generated key */ +){ + Vdbe *v = pParse->pVdbe; + int j; + int regBase; + int nCol; + + if( piPartIdxLabel ){ + if( pIdx->pPartIdxWhere ){ + *piPartIdxLabel = sqlite3VdbeMakeLabel(pParse); + pParse->iSelfTab = iDataCur + 1; + sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, + SQLITE_JUMPIFNULL); + pParse->iSelfTab = 0; + pPrior = 0; /* Ticket a9efb42811fa41ee 2019-11-02; + ** pPartIdxWhere may have corrupted regPrior registers */ + }else{ + *piPartIdxLabel = 0; + } + } + nCol = (prefixOnly && pIdx->uniqNotNull) ? pIdx->nKeyCol : pIdx->nColumn; + regBase = sqlite3GetTempRange(pParse, nCol); + if( pPrior && (regBase!=regPrior || pPrior->pPartIdxWhere) ) pPrior = 0; + for(j=0; jaiColumn[j]==pIdx->aiColumn[j] + && pPrior->aiColumn[j]!=XN_EXPR + ){ + /* This column was already computed by the previous index */ + continue; + } + sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iDataCur, j, regBase+j); + if( pIdx->aiColumn[j]>=0 ){ + /* If the column affinity is REAL but the number is an integer, then it + ** might be stored in the table as an integer (using a compact + ** representation) then converted to REAL by an OP_RealAffinity opcode. + ** But we are getting ready to store this value back into an index, where + ** it should be converted by to INTEGER again. So omit the + ** OP_RealAffinity opcode if it is present */ + sqlite3VdbeDeletePriorOpcode(v, OP_RealAffinity); + } + } + if( regOut ){ + sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut); + } + sqlite3ReleaseTempRange(pParse, regBase, nCol); + return regBase; +} + +/* +** If a prior call to sqlite3GenerateIndexKey() generated a jump-over label +** because it was a partial index, then this routine should be called to +** resolve that label. +*/ +SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){ + if( iLabel ){ + sqlite3VdbeResolveLabel(pParse->pVdbe, iLabel); + } +} + +/************** End of delete.c **********************************************/ +/************** Begin file func.c ********************************************/ +/* +** 2002 February 23 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains the C-language implementations for many of the SQL +** functions of SQLite. (Some function, and in particular the date and +** time functions, are implemented separately.) +*/ +/* #include "sqliteInt.h" */ +/* #include */ +/* #include */ +#ifndef SQLITE_OMIT_FLOATING_POINT +/* #include */ +#endif +/* #include "vdbeInt.h" */ + +/* +** Return the collating function associated with a function. +*/ +static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){ + VdbeOp *pOp; + assert( context->pVdbe!=0 ); + pOp = &context->pVdbe->aOp[context->iOp-1]; + assert( pOp->opcode==OP_CollSeq ); + assert( pOp->p4type==P4_COLLSEQ ); + return pOp->p4.pColl; +} + +/* +** Indicate that the accumulator load should be skipped on this +** iteration of the aggregate loop. +*/ +static void sqlite3SkipAccumulatorLoad(sqlite3_context *context){ + assert( context->isError<=0 ); + context->isError = -1; + context->skipFlag = 1; +} + +/* +** Implementation of the non-aggregate min() and max() functions +*/ +static void minmaxFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int i; + int mask; /* 0 for min() or 0xffffffff for max() */ + int iBest; + CollSeq *pColl; + + assert( argc>1 ); + mask = sqlite3_user_data(context)==0 ? 0 : -1; + pColl = sqlite3GetFuncCollSeq(context); + assert( pColl ); + assert( mask==-1 || mask==0 ); + iBest = 0; + if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; + for(i=1; i=0 ){ + testcase( mask==0 ); + iBest = i; + } + } + sqlite3_result_value(context, argv[iBest]); +} + +/* +** Return the type of the argument. +*/ +static void typeofFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + static const char *azType[] = { "integer", "real", "text", "blob", "null" }; + int i = sqlite3_value_type(argv[0]) - 1; + UNUSED_PARAMETER(NotUsed); + assert( i>=0 && i=0xc0 ){ + while( (*z & 0xc0)==0x80 ){ z++; z0++; } + } + } + sqlite3_result_int(context, (int)(z-z0)); + break; + } + default: { + sqlite3_result_null(context); + break; + } + } +} + +/* +** Implementation of the octet_length() function +*/ +static void bytelengthFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + assert( argc==1 ); + UNUSED_PARAMETER(argc); + switch( sqlite3_value_type(argv[0]) ){ + case SQLITE_BLOB: { + sqlite3_result_int(context, sqlite3_value_bytes(argv[0])); + break; + } + case SQLITE_INTEGER: + case SQLITE_FLOAT: { + i64 m = sqlite3_context_db_handle(context)->enc<=SQLITE_UTF8 ? 1 : 2; + sqlite3_result_int64(context, sqlite3_value_bytes(argv[0])*m); + break; + } + case SQLITE_TEXT: { + if( sqlite3_value_encoding(argv[0])<=SQLITE_UTF8 ){ + sqlite3_result_int(context, sqlite3_value_bytes(argv[0])); + }else{ + sqlite3_result_int(context, sqlite3_value_bytes16(argv[0])); + } + break; + } + default: { + sqlite3_result_null(context); + break; + } + } +} + +/* +** Implementation of the abs() function. +** +** IMP: R-23979-26855 The abs(X) function returns the absolute value of +** the numeric argument X. +*/ +static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ + assert( argc==1 ); + UNUSED_PARAMETER(argc); + switch( sqlite3_value_type(argv[0]) ){ + case SQLITE_INTEGER: { + i64 iVal = sqlite3_value_int64(argv[0]); + if( iVal<0 ){ + if( iVal==SMALLEST_INT64 ){ + /* IMP: R-31676-45509 If X is the integer -9223372036854775808 + ** then abs(X) throws an integer overflow error since there is no + ** equivalent positive 64-bit two complement value. */ + sqlite3_result_error(context, "integer overflow", -1); + return; + } + iVal = -iVal; + } + sqlite3_result_int64(context, iVal); + break; + } + case SQLITE_NULL: { + /* IMP: R-37434-19929 Abs(X) returns NULL if X is NULL. */ + sqlite3_result_null(context); + break; + } + default: { + /* Because sqlite3_value_double() returns 0.0 if the argument is not + ** something that can be converted into a number, we have: + ** IMP: R-01992-00519 Abs(X) returns 0.0 if X is a string or blob + ** that cannot be converted to a numeric value. + */ + double rVal = sqlite3_value_double(argv[0]); + if( rVal<0 ) rVal = -rVal; + sqlite3_result_double(context, rVal); + break; + } + } +} + +/* +** Implementation of the instr() function. +** +** instr(haystack,needle) finds the first occurrence of needle +** in haystack and returns the number of previous characters plus 1, +** or 0 if needle does not occur within haystack. +** +** If both haystack and needle are BLOBs, then the result is one more than +** the number of bytes in haystack prior to the first occurrence of needle, +** or 0 if needle never occurs in haystack. +*/ +static void instrFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const unsigned char *zHaystack; + const unsigned char *zNeedle; + int nHaystack; + int nNeedle; + int typeHaystack, typeNeedle; + int N = 1; + int isText; + unsigned char firstChar; + sqlite3_value *pC1 = 0; + sqlite3_value *pC2 = 0; + + UNUSED_PARAMETER(argc); + typeHaystack = sqlite3_value_type(argv[0]); + typeNeedle = sqlite3_value_type(argv[1]); + if( typeHaystack==SQLITE_NULL || typeNeedle==SQLITE_NULL ) return; + nHaystack = sqlite3_value_bytes(argv[0]); + nNeedle = sqlite3_value_bytes(argv[1]); + if( nNeedle>0 ){ + if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){ + zHaystack = sqlite3_value_blob(argv[0]); + zNeedle = sqlite3_value_blob(argv[1]); + isText = 0; + }else if( typeHaystack!=SQLITE_BLOB && typeNeedle!=SQLITE_BLOB ){ + zHaystack = sqlite3_value_text(argv[0]); + zNeedle = sqlite3_value_text(argv[1]); + isText = 1; + }else{ + pC1 = sqlite3_value_dup(argv[0]); + zHaystack = sqlite3_value_text(pC1); + if( zHaystack==0 ) goto endInstrOOM; + nHaystack = sqlite3_value_bytes(pC1); + pC2 = sqlite3_value_dup(argv[1]); + zNeedle = sqlite3_value_text(pC2); + if( zNeedle==0 ) goto endInstrOOM; + nNeedle = sqlite3_value_bytes(pC2); + isText = 1; + } + if( zNeedle==0 || (nHaystack && zHaystack==0) ) goto endInstrOOM; + firstChar = zNeedle[0]; + while( nNeedle<=nHaystack + && (zHaystack[0]!=firstChar || memcmp(zHaystack, zNeedle, nNeedle)!=0) + ){ + N++; + do{ + nHaystack--; + zHaystack++; + }while( isText && (zHaystack[0]&0xc0)==0x80 ); + } + if( nNeedle>nHaystack ) N = 0; + } + sqlite3_result_int(context, N); +endInstr: + sqlite3_value_free(pC1); + sqlite3_value_free(pC2); + return; +endInstrOOM: + sqlite3_result_error_nomem(context); + goto endInstr; +} + +/* +** Implementation of the printf() (a.k.a. format()) SQL function. +*/ +static void printfFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + PrintfArguments x; + StrAccum str; + const char *zFormat; + int n; + sqlite3 *db = sqlite3_context_db_handle(context); + + if( argc>=1 && (zFormat = (const char*)sqlite3_value_text(argv[0]))!=0 ){ + x.nArg = argc-1; + x.nUsed = 0; + x.apArg = argv+1; + sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); + str.printfFlags = SQLITE_PRINTF_SQLFUNC; + sqlite3_str_appendf(&str, zFormat, &x); + if( str.accError==SQLITE_OK ){ + n = str.nChar; + sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n, + SQLITE_DYNAMIC); + }else{ + if( str.accError==SQLITE_NOMEM ){ + sqlite3_result_error_nomem(context); + }else{ + sqlite3_result_error_toobig(context); + } + sqlite3_str_reset(&str); + } + } +} + +/* +** Implementation of the substr() function. +** +** substr(x,p1,p2) returns p2 characters of x[] beginning with p1. +** p1 is 1-indexed. So substr(x,1,1) returns the first character +** of x. If x is text, then we actually count UTF-8 characters. +** If x is a blob, then we count bytes. +** +** If p1 is negative, then we begin abs(p1) from the end of x[]. +** +** If p2 is negative, return the p2 characters preceding p1. +*/ +static void substrFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const unsigned char *z; + const unsigned char *z2; + int len; + int p0type; + i64 p1, p2; + + assert( argc==3 || argc==2 ); + p0type = sqlite3_value_type(argv[0]); + p1 = sqlite3_value_int64(argv[1]); + if( p0type==SQLITE_BLOB ){ + len = sqlite3_value_bytes(argv[0]); + z = sqlite3_value_blob(argv[0]); + if( z==0 ) return; + assert( len==sqlite3_value_bytes(argv[0]) ); + }else{ + z = sqlite3_value_text(argv[0]); + if( z==0 ) return; + len = 0; + if( p1<0 ){ + for(z2=z; *z2; len++){ + SQLITE_SKIP_UTF8(z2); + } + } + } + if( argc==3 ){ + p2 = sqlite3_value_int64(argv[2]); + if( p2==0 && sqlite3_value_type(argv[2])==SQLITE_NULL ) return; + }else{ + p2 = sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH]; + } + if( p1==0 ){ +#ifdef SQLITE_SUBSTR_COMPATIBILITY + /* If SUBSTR_COMPATIBILITY is defined then substr(X,0,N) work the same as + ** as substr(X,1,N) - it returns the first N characters of X. This + ** is essentially a back-out of the bug-fix in check-in [5fc125d362df4b8] + ** from 2009-02-02 for compatibility of applications that exploited the + ** old buggy behavior. */ + p1 = 1; /* */ +#endif + if( sqlite3_value_type(argv[1])==SQLITE_NULL ) return; + } + if( p1<0 ){ + p1 += len; + if( p1<0 ){ + if( p2<0 ){ + p2 = 0; + }else{ + p2 += p1; + } + p1 = 0; + } + }else if( p1>0 ){ + p1--; + }else if( p2>0 ){ + p2--; + } + if( p2<0 ){ + if( p2<-p1 ){ + p2 = p1; + }else{ + p2 = -p2; + } + p1 -= p2; + } + assert( p1>=0 && p2>=0 ); + if( p0type!=SQLITE_BLOB ){ + while( *z && p1 ){ + SQLITE_SKIP_UTF8(z); + p1--; + } + for(z2=z; *z2 && p2; p2--){ + SQLITE_SKIP_UTF8(z2); + } + sqlite3_result_text64(context, (char*)z, z2-z, SQLITE_TRANSIENT, + SQLITE_UTF8); + }else{ + if( p1>=len ){ + p1 = p2 = 0; + }else if( p2>len-p1 ){ + p2 = len-p1; + assert( p2>0 ); + } + sqlite3_result_blob64(context, (char*)&z[p1], (u64)p2, SQLITE_TRANSIENT); + } +} + +/* +** Implementation of the round() function +*/ +#ifndef SQLITE_OMIT_FLOATING_POINT +static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ + i64 n = 0; + double r; + char *zBuf; + assert( argc==1 || argc==2 ); + if( argc==2 ){ + if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return; + n = sqlite3_value_int64(argv[1]); + if( n>30 ) n = 30; + if( n<0 ) n = 0; + } + if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; + r = sqlite3_value_double(argv[0]); + /* If Y==0 and X will fit in a 64-bit int, + ** handle the rounding directly, + ** otherwise use printf. + */ + if( r<-4503599627370496.0 || r>+4503599627370496.0 ){ + /* The value has no fractional part so there is nothing to round */ + }else if( n==0 ){ + r = (double)((sqlite_int64)(r+(r<0?-0.5:+0.5))); + }else{ + zBuf = sqlite3_mprintf("%!.*f",(int)n,r); + if( zBuf==0 ){ + sqlite3_result_error_nomem(context); + return; + } + sqlite3AtoF(zBuf, &r); + sqlite3_free(zBuf); + } + sqlite3_result_double(context, r); +} +#endif + +/* +** Allocate nByte bytes of space using sqlite3Malloc(). If the +** allocation fails, call sqlite3_result_error_nomem() to notify +** the database handle that malloc() has failed and return NULL. +** If nByte is larger than the maximum string or blob length, then +** raise an SQLITE_TOOBIG exception and return NULL. +*/ +static void *contextMalloc(sqlite3_context *context, i64 nByte){ + char *z; + sqlite3 *db = sqlite3_context_db_handle(context); + assert( nByte>0 ); + testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH] ); + testcase( nByte==(i64)db->aLimit[SQLITE_LIMIT_LENGTH]+1 ); + if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + sqlite3_result_error_toobig(context); + z = 0; + }else{ + z = sqlite3Malloc(nByte); + if( !z ){ + sqlite3_result_error_nomem(context); + } + } + return z; +} + +/* +** Implementation of the upper() and lower() SQL functions. +*/ +static void upperFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ + char *z1; + const char *z2; + int i, n; + UNUSED_PARAMETER(argc); + z2 = (char*)sqlite3_value_text(argv[0]); + n = sqlite3_value_bytes(argv[0]); + /* Verify that the call to _bytes() does not invalidate the _text() pointer */ + assert( z2==(char*)sqlite3_value_text(argv[0]) ); + if( z2 ){ + z1 = contextMalloc(context, ((i64)n)+1); + if( z1 ){ + for(i=0; imatchOne; /* "?" or "_" */ + u32 matchAll = pInfo->matchAll; /* "*" or "%" */ + u8 noCase = pInfo->noCase; /* True if uppercase==lowercase */ + const u8 *zEscaped = 0; /* One past the last escaped input char */ + + while( (c = Utf8Read(zPattern))!=0 ){ + if( c==matchAll ){ /* Match "*" */ + /* Skip over multiple "*" characters in the pattern. If there + ** are also "?" characters, skip those as well, but consume a + ** single character of the input string for each "?" skipped */ + while( (c=Utf8Read(zPattern)) == matchAll + || (c == matchOne && matchOne!=0) ){ + if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){ + return SQLITE_NOWILDCARDMATCH; + } + } + if( c==0 ){ + return SQLITE_MATCH; /* "*" at the end of the pattern matches */ + }else if( c==matchOther ){ + if( pInfo->matchSet==0 ){ + c = sqlite3Utf8Read(&zPattern); + if( c==0 ) return SQLITE_NOWILDCARDMATCH; + }else{ + /* "[...]" immediately follows the "*". We have to do a slow + ** recursive search in this case, but it is an unusual case. */ + assert( matchOther<0x80 ); /* '[' is a single-byte character */ + while( *zString ){ + int bMatch = patternCompare(&zPattern[-1],zString,pInfo,matchOther); + if( bMatch!=SQLITE_NOMATCH ) return bMatch; + SQLITE_SKIP_UTF8(zString); + } + return SQLITE_NOWILDCARDMATCH; + } + } + + /* At this point variable c contains the first character of the + ** pattern string past the "*". Search in the input string for the + ** first matching character and recursively continue the match from + ** that point. + ** + ** For a case-insensitive search, set variable cx to be the same as + ** c but in the other case and search the input string for either + ** c or cx. + */ + if( c<0x80 ){ + char zStop[3]; + int bMatch; + if( noCase ){ + zStop[0] = sqlite3Toupper(c); + zStop[1] = sqlite3Tolower(c); + zStop[2] = 0; + }else{ + zStop[0] = c; + zStop[1] = 0; + } + while(1){ + zString += strcspn((const char*)zString, zStop); + if( zString[0]==0 ) break; + zString++; + bMatch = patternCompare(zPattern,zString,pInfo,matchOther); + if( bMatch!=SQLITE_NOMATCH ) return bMatch; + } + }else{ + int bMatch; + while( (c2 = Utf8Read(zString))!=0 ){ + if( c2!=c ) continue; + bMatch = patternCompare(zPattern,zString,pInfo,matchOther); + if( bMatch!=SQLITE_NOMATCH ) return bMatch; + } + } + return SQLITE_NOWILDCARDMATCH; + } + if( c==matchOther ){ + if( pInfo->matchSet==0 ){ + c = sqlite3Utf8Read(&zPattern); + if( c==0 ) return SQLITE_NOMATCH; + zEscaped = zPattern; + }else{ + u32 prior_c = 0; + int seen = 0; + int invert = 0; + c = sqlite3Utf8Read(&zString); + if( c==0 ) return SQLITE_NOMATCH; + c2 = sqlite3Utf8Read(&zPattern); + if( c2=='^' ){ + invert = 1; + c2 = sqlite3Utf8Read(&zPattern); + } + if( c2==']' ){ + if( c==']' ) seen = 1; + c2 = sqlite3Utf8Read(&zPattern); + } + while( c2 && c2!=']' ){ + if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){ + c2 = sqlite3Utf8Read(&zPattern); + if( c>=prior_c && c<=c2 ) seen = 1; + prior_c = 0; + }else{ + if( c==c2 ){ + seen = 1; + } + prior_c = c2; + } + c2 = sqlite3Utf8Read(&zPattern); + } + if( c2==0 || (seen ^ invert)==0 ){ + return SQLITE_NOMATCH; + } + continue; + } + } + c2 = Utf8Read(zString); + if( c==c2 ) continue; + if( noCase && sqlite3Tolower(c)==sqlite3Tolower(c2) && c<0x80 && c2<0x80 ){ + continue; + } + if( c==matchOne && zPattern!=zEscaped && c2!=0 ) continue; + return SQLITE_NOMATCH; + } + return *zString==0 ? SQLITE_MATCH : SQLITE_NOMATCH; +} + +/* +** The sqlite3_strglob() interface. Return 0 on a match (like strcmp()) and +** non-zero if there is no match. +*/ +SQLITE_API int sqlite3_strglob(const char *zGlobPattern, const char *zString){ + if( zString==0 ){ + return zGlobPattern!=0; + }else if( zGlobPattern==0 ){ + return 1; + }else { + return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '['); + } +} + +/* +** The sqlite3_strlike() interface. Return 0 on a match and non-zero for +** a miss - like strcmp(). +*/ +SQLITE_API int sqlite3_strlike(const char *zPattern, const char *zStr, unsigned int esc){ + if( zStr==0 ){ + return zPattern!=0; + }else if( zPattern==0 ){ + return 1; + }else{ + return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc); + } +} + +/* +** Count the number of times that the LIKE operator (or GLOB which is +** just a variation of LIKE) gets called. This is used for testing +** only. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_like_count = 0; +#endif + + +/* +** Implementation of the like() SQL function. This function implements +** the built-in LIKE operator. The first argument to the function is the +** pattern and the second argument is the string. So, the SQL statements: +** +** A LIKE B +** +** is implemented as like(B,A). +** +** This same function (with a different compareInfo structure) computes +** the GLOB operator. +*/ +static void likeFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const unsigned char *zA, *zB; + u32 escape; + int nPat; + sqlite3 *db = sqlite3_context_db_handle(context); + struct compareInfo *pInfo = sqlite3_user_data(context); + struct compareInfo backupInfo; + +#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS + if( sqlite3_value_type(argv[0])==SQLITE_BLOB + || sqlite3_value_type(argv[1])==SQLITE_BLOB + ){ +#ifdef SQLITE_TEST + sqlite3_like_count++; +#endif + sqlite3_result_int(context, 0); + return; + } +#endif + + /* Limit the length of the LIKE or GLOB pattern to avoid problems + ** of deep recursion and N*N behavior in patternCompare(). + */ + nPat = sqlite3_value_bytes(argv[0]); + testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] ); + testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]+1 ); + if( nPat > db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] ){ + sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1); + return; + } + if( argc==3 ){ + /* The escape character string must consist of a single UTF-8 character. + ** Otherwise, return an error. + */ + const unsigned char *zEsc = sqlite3_value_text(argv[2]); + if( zEsc==0 ) return; + if( sqlite3Utf8CharLen((char*)zEsc, -1)!=1 ){ + sqlite3_result_error(context, + "ESCAPE expression must be a single character", -1); + return; + } + escape = sqlite3Utf8Read(&zEsc); + if( escape==pInfo->matchAll || escape==pInfo->matchOne ){ + memcpy(&backupInfo, pInfo, sizeof(backupInfo)); + pInfo = &backupInfo; + if( escape==pInfo->matchAll ) pInfo->matchAll = 0; + if( escape==pInfo->matchOne ) pInfo->matchOne = 0; + } + }else{ + escape = pInfo->matchSet; + } + zB = sqlite3_value_text(argv[0]); + zA = sqlite3_value_text(argv[1]); + if( zA && zB ){ +#ifdef SQLITE_TEST + sqlite3_like_count++; +#endif + sqlite3_result_int(context, + patternCompare(zB, zA, pInfo, escape)==SQLITE_MATCH); + } +} + +/* +** Implementation of the NULLIF(x,y) function. The result is the first +** argument if the arguments are different. The result is NULL if the +** arguments are equal to each other. +*/ +static void nullifFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + CollSeq *pColl = sqlite3GetFuncCollSeq(context); + UNUSED_PARAMETER(NotUsed); + if( sqlite3MemCompare(argv[0], argv[1], pColl)!=0 ){ + sqlite3_result_value(context, argv[0]); + } +} + +/* +** Implementation of the sqlite_version() function. The result is the version +** of the SQLite library that is running. +*/ +static void versionFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **NotUsed2 +){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + /* IMP: R-48699-48617 This function is an SQL wrapper around the + ** sqlite3_libversion() C-interface. */ + sqlite3_result_text(context, sqlite3_libversion(), -1, SQLITE_STATIC); +} + +/* +** Implementation of the sqlite_source_id() function. The result is a string +** that identifies the particular version of the source code used to build +** SQLite. +*/ +static void sourceidFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **NotUsed2 +){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + /* IMP: R-24470-31136 This function is an SQL wrapper around the + ** sqlite3_sourceid() C interface. */ + sqlite3_result_text(context, sqlite3_sourceid(), -1, SQLITE_STATIC); +} + +/* +** Implementation of the sqlite_log() function. This is a wrapper around +** sqlite3_log(). The return value is NULL. The function exists purely for +** its side-effects. +*/ +static void errlogFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + UNUSED_PARAMETER(argc); + UNUSED_PARAMETER(context); + sqlite3_log(sqlite3_value_int(argv[0]), "%s", sqlite3_value_text(argv[1])); +} + +/* +** Implementation of the sqlite_compileoption_used() function. +** The result is an integer that identifies if the compiler option +** was used to build SQLite. +*/ +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS +static void compileoptionusedFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const char *zOptName; + assert( argc==1 ); + UNUSED_PARAMETER(argc); + /* IMP: R-39564-36305 The sqlite_compileoption_used() SQL + ** function is a wrapper around the sqlite3_compileoption_used() C/C++ + ** function. + */ + if( (zOptName = (const char*)sqlite3_value_text(argv[0]))!=0 ){ + sqlite3_result_int(context, sqlite3_compileoption_used(zOptName)); + } +} +#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ + +/* +** Implementation of the sqlite_compileoption_get() function. +** The result is a string that identifies the compiler options +** used to build SQLite. +*/ +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS +static void compileoptiongetFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int n; + assert( argc==1 ); + UNUSED_PARAMETER(argc); + /* IMP: R-04922-24076 The sqlite_compileoption_get() SQL function + ** is a wrapper around the sqlite3_compileoption_get() C/C++ function. + */ + n = sqlite3_value_int(argv[0]); + sqlite3_result_text(context, sqlite3_compileoption_get(n), -1, SQLITE_STATIC); +} +#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ + +/* Array for converting from half-bytes (nybbles) into ASCII hex +** digits. */ +static const char hexdigits[] = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' +}; + +/* +** Append to pStr text that is the SQL literal representation of the +** value contained in pValue. +*/ +SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum *pStr, sqlite3_value *pValue, int bEscape){ + /* As currently implemented, the string must be initially empty. + ** we might relax this requirement in the future, but that will + ** require enhancements to the implementation. */ + assert( pStr!=0 && pStr->nChar==0 ); + + switch( sqlite3_value_type(pValue) ){ + case SQLITE_FLOAT: { + /* ,--- Show infinity as 9.0e+999 + ** | + ** | ,--- 17 precision guarantees round-trip + ** v v */ + sqlite3_str_appendf(pStr, "%!0.17g", sqlite3_value_double(pValue)); + break; + } + case SQLITE_INTEGER: { + sqlite3_str_appendf(pStr, "%lld", sqlite3_value_int64(pValue)); + break; + } + case SQLITE_BLOB: { + char const *zBlob = sqlite3_value_blob(pValue); + i64 nBlob = sqlite3_value_bytes(pValue); + assert( zBlob==sqlite3_value_blob(pValue) ); /* No encoding change */ + sqlite3StrAccumEnlarge(pStr, nBlob*2 + 4); + if( pStr->accError==0 ){ + char *zText = pStr->zText; + int i; + for(i=0; i>4)&0x0F]; + zText[(i*2)+3] = hexdigits[(zBlob[i])&0x0F]; + } + zText[(nBlob*2)+2] = '\''; + zText[(nBlob*2)+3] = '\0'; + zText[0] = 'X'; + zText[1] = '\''; + pStr->nChar = nBlob*2 + 3; + } + break; + } + case SQLITE_TEXT: { + const unsigned char *zArg = sqlite3_value_text(pValue); + sqlite3_str_appendf(pStr, bEscape ? "%#Q" : "%Q", zArg); + break; + } + default: { + assert( sqlite3_value_type(pValue)==SQLITE_NULL ); + sqlite3_str_append(pStr, "NULL", 4); + break; + } + } +} + +/* +** Return true if z[] begins with N hexadecimal digits, and write +** a decoding of those digits into *pVal. Or return false if any +** one of the first N characters in z[] is not a hexadecimal digit. +*/ +static int isNHex(const char *z, int N, u32 *pVal){ + int i; + u32 v = 0; + for(i=0; i0 ){ + memmove(&zOut[j], &zIn[i], n); + j += n; + i += n; + } + if( zIn[i+1]=='\\' ){ + i += 2; + zOut[j++] = '\\'; + }else if( sqlite3Isxdigit(zIn[i+1]) ){ + if( !isNHex(&zIn[i+1], 4, &v) ) goto unistr_error; + i += 5; + j += sqlite3AppendOneUtf8Character(&zOut[j], v); + }else if( zIn[i+1]=='+' ){ + if( !isNHex(&zIn[i+2], 6, &v) ) goto unistr_error; + i += 8; + j += sqlite3AppendOneUtf8Character(&zOut[j], v); + }else if( zIn[i+1]=='u' ){ + if( !isNHex(&zIn[i+2], 4, &v) ) goto unistr_error; + i += 6; + j += sqlite3AppendOneUtf8Character(&zOut[j], v); + }else if( zIn[i+1]=='U' ){ + if( !isNHex(&zIn[i+2], 8, &v) ) goto unistr_error; + i += 10; + j += sqlite3AppendOneUtf8Character(&zOut[j], v); + }else{ + goto unistr_error; + } + } + zOut[j] = 0; + sqlite3_result_text64(context, zOut, j, sqlite3_free, SQLITE_UTF8_ZT); + return; + +unistr_error: + sqlite3_free(zOut); + sqlite3_result_error(context, "invalid Unicode escape", -1); + return; +} + + +/* +** Implementation of the QUOTE() function. +** +** The quote(X) function returns the text of an SQL literal which is the +** value of its argument suitable for inclusion into an SQL statement. +** Strings are surrounded by single-quotes with escapes on interior quotes +** as needed. BLOBs are encoded as hexadecimal literals. Strings with +** embedded NUL characters cannot be represented as string literals in SQL +** and hence the returned string literal is truncated prior to the first NUL. +** +** If sqlite3_user_data() is non-zero, then the UNISTR_QUOTE() function is +** implemented instead. The difference is that UNISTR_QUOTE() uses the +** UNISTR() function to escape control characters. +*/ +static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ + sqlite3_str str; + sqlite3 *db = sqlite3_context_db_handle(context); + assert( argc==1 ); + UNUSED_PARAMETER(argc); + sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); + sqlite3QuoteValue(&str,argv[0],SQLITE_PTR_TO_INT(sqlite3_user_data(context))); + sqlite3_result_text(context, sqlite3StrAccumFinish(&str), str.nChar, + SQLITE_DYNAMIC); + if( str.accError!=SQLITE_OK ){ + sqlite3_result_null(context); + sqlite3_result_error_code(context, str.accError); + } +} + +/* +** The unicode() function. Return the integer unicode code-point value +** for the first character of the input string. +*/ +static void unicodeFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const unsigned char *z = sqlite3_value_text(argv[0]); + (void)argc; + if( z && z[0] ) sqlite3_result_int(context, sqlite3Utf8Read(&z)); +} + +/* +** The char() function takes zero or more arguments, each of which is +** an integer. It constructs a string where each character of the string +** is the unicode character for the corresponding integer argument. +*/ +static void charFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + unsigned char *z, *zOut; + int i; + zOut = z = sqlite3_malloc64( argc*4+1 ); + if( z==0 ){ + sqlite3_result_error_nomem(context); + return; + } + for(i=0; i0x10ffff ) x = 0xfffd; + c = (unsigned)(x & 0x1fffff); + if( c<0x00080 ){ + *zOut++ = (u8)(c&0xFF); + }else if( c<0x00800 ){ + *zOut++ = 0xC0 + (u8)((c>>6)&0x1F); + *zOut++ = 0x80 + (u8)(c & 0x3F); + }else if( c<0x10000 ){ + *zOut++ = 0xE0 + (u8)((c>>12)&0x0F); + *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); + *zOut++ = 0x80 + (u8)(c & 0x3F); + }else{ + *zOut++ = 0xF0 + (u8)((c>>18) & 0x07); + *zOut++ = 0x80 + (u8)((c>>12) & 0x3F); + *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); + *zOut++ = 0x80 + (u8)(c & 0x3F); + } \ + } + *zOut = 0; + sqlite3_result_text64(context, (char*)z, zOut-z,sqlite3_free,SQLITE_UTF8_ZT); +} + +/* +** The hex() function. Interpret the argument as a blob. Return +** a hexadecimal rendering as text. +*/ +static void hexFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int i, n; + const unsigned char *pBlob; + char *zHex, *z; + assert( argc==1 ); + UNUSED_PARAMETER(argc); + pBlob = sqlite3_value_blob(argv[0]); + n = sqlite3_value_bytes(argv[0]); + assert( pBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */ + z = zHex = contextMalloc(context, ((i64)n)*2 + 1); + if( zHex ){ + for(i=0; i>4)&0xf]; + *(z++) = hexdigits[c&0xf]; + } + *z = 0; + sqlite3_result_text64(context, zHex, (u64)(z-zHex), + sqlite3_free, SQLITE_UTF8_ZT); + } +} + +/* +** Buffer zStr contains nStr bytes of utf-8 encoded text. Return 1 if zStr +** contains character ch, or 0 if it does not. +*/ +static int strContainsChar(const u8 *zStr, int nStr, u32 ch){ + const u8 *zEnd = &zStr[nStr]; + const u8 *z = zStr; + while( zmallocFailed ); + return; + } + if( zPattern[0]==0 ){ + assert( sqlite3_value_type(argv[1])!=SQLITE_NULL ); + sqlite3_result_text(context, (const char*)zStr, nStr, SQLITE_TRANSIENT); + return; + } + nPattern = sqlite3_value_bytes(argv[1]); + assert( zPattern==sqlite3_value_text(argv[1]) ); /* No encoding change */ + zRep = sqlite3_value_text(argv[2]); + if( zRep==0 ) return; + nRep = sqlite3_value_bytes(argv[2]); + assert( zRep==sqlite3_value_text(argv[2]) ); + nOut = nStr + 1; + assert( nOutnPattern ){ + nOut += nRep - nPattern; + testcase( nOut-1==db->aLimit[SQLITE_LIMIT_LENGTH] ); + testcase( nOut-2==db->aLimit[SQLITE_LIMIT_LENGTH] ); + if( nOut-1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + sqlite3_result_error_toobig(context); + sqlite3_free(zOut); + return; + } + cntExpand++; + if( (cntExpand&(cntExpand-1))==0 ){ + /* Grow the size of the output buffer only on substitutions + ** whose index is a power of two: 1, 2, 4, 8, 16, 32, ... */ + u8 *zOld; + zOld = zOut; + zOut = sqlite3Realloc(zOut, (int)nOut + (nOut - nStr - 1)); + if( zOut==0 ){ + sqlite3_result_error_nomem(context); + sqlite3_free(zOld); + return; + } + } + } + memcpy(&zOut[j], zRep, nRep); + j += nRep; + i += nPattern-1; + } + } + assert( j+nStr-i+1<=nOut ); + memcpy(&zOut[j], &zStr[i], nStr-i); + j += nStr - i; + assert( j<=nOut ); + zOut[j] = 0; + sqlite3_result_text(context, (char*)zOut, j, sqlite3_free); +} + +/* +** Implementation of the TRIM(), LTRIM(), and RTRIM() functions. +** The userdata is 0x1 for left trim, 0x2 for right trim, 0x3 for both. +*/ +static void trimFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const unsigned char *zIn; /* Input string */ + const unsigned char *zCharSet; /* Set of characters to trim */ + unsigned int nIn; /* Number of bytes in input */ + int flags; /* 1: trimleft 2: trimright 3: trim */ + int i; /* Loop counter */ + unsigned int *aLen = 0; /* Length of each character in zCharSet */ + unsigned char **azChar = 0; /* Individual characters in zCharSet */ + int nChar; /* Number of characters in zCharSet */ + + if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ + return; + } + zIn = sqlite3_value_text(argv[0]); + if( zIn==0 ) return; + nIn = (unsigned)sqlite3_value_bytes(argv[0]); + assert( zIn==sqlite3_value_text(argv[0]) ); + if( argc==1 ){ + static const unsigned lenOne[] = { 1 }; + static unsigned char * const azOne[] = { (u8*)" " }; + nChar = 1; + aLen = (unsigned*)lenOne; + azChar = (unsigned char **)azOne; + zCharSet = 0; + }else if( (zCharSet = sqlite3_value_text(argv[1]))==0 ){ + return; + }else{ + const unsigned char *z; + for(z=zCharSet, nChar=0; *z; nChar++){ + SQLITE_SKIP_UTF8(z); + } + if( nChar>0 ){ + azChar = contextMalloc(context, + ((i64)nChar)*(sizeof(char*)+sizeof(unsigned))); + if( azChar==0 ){ + return; + } + aLen = (unsigned*)&azChar[nChar]; + for(z=zCharSet, nChar=0; *z; nChar++){ + azChar[nChar] = (unsigned char *)z; + SQLITE_SKIP_UTF8(z); + aLen[nChar] = (unsigned)(z - azChar[nChar]); + } + } + } + if( nChar>0 ){ + flags = SQLITE_PTR_TO_INT(sqlite3_user_data(context)); + if( flags & 1 ){ + while( nIn>0 ){ + unsigned int len = 0; + for(i=0; i=nChar ) break; + zIn += len; + nIn -= len; + } + } + if( flags & 2 ){ + while( nIn>0 ){ + unsigned int len = 0; + for(i=0; i=nChar ) break; + nIn -= len; + } + } + if( zCharSet ){ + sqlite3_free(azChar); + } + } + sqlite3_result_text(context, (char*)zIn, nIn, SQLITE_TRANSIENT); +} + +/* The core implementation of the CONCAT(...) and CONCAT_WS(SEP,...) +** functions. +** +** Return a string value that is the concatenation of all non-null +** entries in argv[]. Use zSep as the separator. +*/ +static void concatFuncCore( + sqlite3_context *context, + int argc, + sqlite3_value **argv, + int nSep, + const char *zSep +){ + i64 j, n = 0; + int i; + int bNotNull = 0; /* True after at least NOT NULL argument seen */ + char *z; + for(i=0; i0 ){ + memcpy(&z[j], zSep, nSep); + j += nSep; + } + memcpy(&z[j], v, k); + j += k; + bNotNull = 1; + } + } + } + z[j] = 0; + assert( j<=n ); + sqlite3_result_text64(context, z, j, sqlite3_free, SQLITE_UTF8_ZT); +} + +/* +** The CONCAT(...) function. Generate a string result that is the +** concatentation of all non-null arguments. +*/ +static void concatFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + concatFuncCore(context, argc, argv, 0, ""); +} + +/* +** The CONCAT_WS(separator, ...) function. +** +** Generate a string that is the concatenation of 2nd through the Nth +** argument. Use the first argument (which must be non-NULL) as the +** separator. +*/ +static void concatwsFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int nSep = sqlite3_value_bytes(argv[0]); + const char *zSep = (const char*)sqlite3_value_text(argv[0]); + if( zSep==0 ) return; + concatFuncCore(context, argc-1, argv+1, nSep, zSep); +} + + +#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION +/* +** The "unknown" function is automatically substituted in place of +** any unrecognized function name when doing an EXPLAIN or EXPLAIN QUERY PLAN +** when the SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION compile-time option is used. +** When the "sqlite3" command-line shell is built using this functionality, +** that allows an EXPLAIN or EXPLAIN QUERY PLAN for complex queries +** involving application-defined functions to be examined in a generic +** sqlite3 shell. +*/ +static void unknownFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + /* no-op */ + (void)context; + (void)argc; + (void)argv; +} +#endif /*SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION*/ + + +/* IMP: R-25361-16150 This function is omitted from SQLite by default. It +** is only available if the SQLITE_SOUNDEX compile-time option is used +** when SQLite is built. +*/ +#ifdef SQLITE_SOUNDEX +/* +** Compute the soundex encoding of a word. +** +** IMP: R-59782-00072 The soundex(X) function returns a string that is the +** soundex encoding of the string X. +*/ +static void soundexFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + char zResult[8]; + const u8 *zIn; + int i, j; + static const unsigned char iCode[] = { + 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, 0, + 0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0, + 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0, + 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0, + }; + assert( argc==1 ); + zIn = (u8*)sqlite3_value_text(argv[0]); + if( zIn==0 ) zIn = (u8*)""; + for(i=0; zIn[i] && !sqlite3Isalpha(zIn[i]); i++){} + if( zIn[i] ){ + u8 prevcode = iCode[zIn[i]&0x7f]; + zResult[0] = sqlite3Toupper(zIn[i]); + for(j=1; j<4 && zIn[i]; i++){ + int code = iCode[zIn[i]&0x7f]; + if( code>0 ){ + if( code!=prevcode ){ + prevcode = code; + zResult[j++] = code + '0'; + } + }else{ + prevcode = 0; + } + } + while( j<4 ){ + zResult[j++] = '0'; + } + zResult[j] = 0; + sqlite3_result_text(context, zResult, 4, SQLITE_TRANSIENT); + }else{ + /* IMP: R-64894-50321 The string "?000" is returned if the argument + ** is NULL or contains no ASCII alphabetic characters. */ + sqlite3_result_text(context, "?000", 4, SQLITE_STATIC); + } +} +#endif /* SQLITE_SOUNDEX */ + +#ifndef SQLITE_OMIT_LOAD_EXTENSION +/* +** A function that loads a shared-library extension then returns NULL. +*/ +static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){ + const char *zFile = (const char *)sqlite3_value_text(argv[0]); + const char *zProc; + sqlite3 *db = sqlite3_context_db_handle(context); + char *zErrMsg = 0; + + /* Disallow the load_extension() SQL function unless the SQLITE_LoadExtFunc + ** flag is set. See the sqlite3_enable_load_extension() API. + */ + if( (db->flags & SQLITE_LoadExtFunc)==0 ){ + sqlite3_result_error(context, "not authorized", -1); + return; + } + + if( argc==2 ){ + zProc = (const char *)sqlite3_value_text(argv[1]); + }else{ + zProc = 0; + } + if( zFile && sqlite3_load_extension(db, zFile, zProc, &zErrMsg) ){ + sqlite3_result_error(context, zErrMsg, -1); + sqlite3_free(zErrMsg); + } +} +#endif + + +/* +** An instance of the following structure holds the context of a +** sum() or avg() aggregate computation. +*/ +typedef struct SumCtx SumCtx; +struct SumCtx { + double rSum; /* Running sum as as a double */ + double rErr; /* Error term for Kahan-Babushka-Neumaier summation */ + i64 iSum; /* Running sum as a signed integer */ + i64 cnt; /* Number of elements summed */ + u8 approx; /* True if any non-integer value was input to the sum */ + u8 ovrfl; /* Integer overflow seen */ +}; + +/* +** Do one step of the Kahan-Babushka-Neumaier summation. +** +** https://en.wikipedia.org/wiki/Kahan_summation_algorithm +** +** Variables are marked "volatile" to defeat c89 x86 floating point +** optimizations can mess up this algorithm. +*/ +static void kahanBabuskaNeumaierStep( + volatile SumCtx *pSum, + volatile double r +){ + volatile double s = pSum->rSum; + volatile double t = s + r; + if( fabs(s) > fabs(r) ){ + pSum->rErr += (s - t) + r; + }else{ + pSum->rErr += (r - t) + s; + } + pSum->rSum = t; +} + +/* +** Add a (possibly large) integer to the running sum. +*/ +static void kahanBabuskaNeumaierStepInt64(volatile SumCtx *pSum, i64 iVal){ + if( iVal<=-4503599627370496LL || iVal>=+4503599627370496LL ){ + i64 iBig, iSm; + iSm = iVal % 16384; + iBig = iVal - iSm; + kahanBabuskaNeumaierStep(pSum, iBig); + kahanBabuskaNeumaierStep(pSum, iSm); + }else{ + kahanBabuskaNeumaierStep(pSum, (double)iVal); + } +} + +/* +** Initialize the Kahan-Babaska-Neumaier sum from a 64-bit integer +*/ +static void kahanBabuskaNeumaierInit( + volatile SumCtx *p, + i64 iVal +){ + if( iVal<=-4503599627370496LL || iVal>=+4503599627370496LL ){ + i64 iSm = iVal % 16384; + p->rSum = (double)(iVal - iSm); + p->rErr = (double)iSm; + }else{ + p->rSum = (double)iVal; + p->rErr = 0.0; + } +} + +/* +** Routines used to compute the sum, average, and total. +** +** The SUM() function follows the (broken) SQL standard which means +** that it returns NULL if it sums over no inputs. TOTAL returns +** 0.0 in that case. In addition, TOTAL always returns a float where +** SUM might return an integer if it never encounters a floating point +** value. TOTAL never fails, but SUM might throw an exception if +** it overflows an integer. +*/ +static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){ + SumCtx *p; + int type; + assert( argc==1 ); + UNUSED_PARAMETER(argc); + p = sqlite3_aggregate_context(context, sizeof(*p)); + type = sqlite3_value_numeric_type(argv[0]); + if( p && type!=SQLITE_NULL ){ + p->cnt++; + if( p->approx==0 ){ + if( type!=SQLITE_INTEGER ){ + kahanBabuskaNeumaierInit(p, p->iSum); + p->approx = 1; + kahanBabuskaNeumaierStep(p, sqlite3_value_double(argv[0])); + }else{ + i64 x = p->iSum; + if( sqlite3AddInt64(&x, sqlite3_value_int64(argv[0]))==0 ){ + p->iSum = x; + }else{ + p->ovrfl = 1; + kahanBabuskaNeumaierInit(p, p->iSum); + p->approx = 1; + kahanBabuskaNeumaierStepInt64(p, sqlite3_value_int64(argv[0])); + } + } + }else{ + if( type==SQLITE_INTEGER ){ + kahanBabuskaNeumaierStepInt64(p, sqlite3_value_int64(argv[0])); + }else{ + p->ovrfl = 0; + kahanBabuskaNeumaierStep(p, sqlite3_value_double(argv[0])); + } + } + } +} +#ifndef SQLITE_OMIT_WINDOWFUNC +static void sumInverse(sqlite3_context *context, int argc, sqlite3_value**argv){ + SumCtx *p; + int type; + assert( argc==1 ); + UNUSED_PARAMETER(argc); + p = sqlite3_aggregate_context(context, sizeof(*p)); + type = sqlite3_value_numeric_type(argv[0]); + /* p is always non-NULL because sumStep() will have been called first + ** to initialize it */ + if( ALWAYS(p) && type!=SQLITE_NULL ){ + assert( p->cnt>0 ); + p->cnt--; + if( !p->approx ){ + i64 x = p->iSum; + if( sqlite3SubInt64(&x, sqlite3_value_int64(argv[0]))==0 ){ + p->iSum = x; + return; + } + p->ovrfl = 1; + p->approx = 1; + kahanBabuskaNeumaierInit(p, p->iSum); + } + if( type==SQLITE_INTEGER ){ + i64 iVal = sqlite3_value_int64(argv[0]); + if( iVal!=SMALLEST_INT64 ){ + kahanBabuskaNeumaierStepInt64(p, -iVal); + }else{ + kahanBabuskaNeumaierStepInt64(p, LARGEST_INT64); + kahanBabuskaNeumaierStepInt64(p, 1); + } + }else{ + kahanBabuskaNeumaierStep(p, -sqlite3_value_double(argv[0])); + } + } +} +#else +# define sumInverse 0 +#endif /* SQLITE_OMIT_WINDOWFUNC */ +static void sumFinalize(sqlite3_context *context){ + SumCtx *p; + p = sqlite3_aggregate_context(context, 0); + if( p && p->cnt>0 ){ + if( p->approx ){ + if( p->ovrfl ){ + sqlite3_result_error(context,"integer overflow",-1); + }else if( !sqlite3IsOverflow(p->rErr) ){ + sqlite3_result_double(context, p->rSum+p->rErr); + }else{ + sqlite3_result_double(context, p->rSum); + } + }else{ + sqlite3_result_int64(context, p->iSum); + } + } +} +static void avgFinalize(sqlite3_context *context){ + SumCtx *p; + p = sqlite3_aggregate_context(context, 0); + if( p && p->cnt>0 ){ + double r; + if( p->approx ){ + r = p->rSum; + if( !sqlite3IsOverflow(p->rErr) ) r += p->rErr; + }else{ + r = (double)(p->iSum); + } + sqlite3_result_double(context, r/(double)p->cnt); + } +} +static void totalFinalize(sqlite3_context *context){ + SumCtx *p; + double r = 0.0; + p = sqlite3_aggregate_context(context, 0); + if( p ){ + if( p->approx ){ + r = p->rSum; + if( !sqlite3IsOverflow(p->rErr) ) r += p->rErr; + }else{ + r = (double)(p->iSum); + } + } + sqlite3_result_double(context, r); +} + +/* +** The following structure keeps track of state information for the +** count() aggregate function. +*/ +typedef struct CountCtx CountCtx; +struct CountCtx { + i64 n; +#ifdef SQLITE_DEBUG + int bInverse; /* True if xInverse() ever called */ +#endif +}; + +/* +** Routines to implement the count() aggregate function. +*/ +static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){ + CountCtx *p; + p = sqlite3_aggregate_context(context, sizeof(*p)); + if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && p ){ + p->n++; + } + +#ifndef SQLITE_OMIT_DEPRECATED + /* The sqlite3_aggregate_count() function is deprecated. But just to make + ** sure it still operates correctly, verify that its count agrees with our + ** internal count when using count(*) and when the total count can be + ** expressed as a 32-bit integer. */ + assert( argc==1 || p==0 || p->n>0x7fffffff || p->bInverse + || p->n==sqlite3_aggregate_count(context) ); +#endif +} +static void countFinalize(sqlite3_context *context){ + CountCtx *p; + p = sqlite3_aggregate_context(context, 0); + sqlite3_result_int64(context, p ? p->n : 0); +} +#ifndef SQLITE_OMIT_WINDOWFUNC +static void countInverse(sqlite3_context *ctx, int argc, sqlite3_value **argv){ + CountCtx *p; + p = sqlite3_aggregate_context(ctx, sizeof(*p)); + /* p is always non-NULL since countStep() will have been called first */ + if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && ALWAYS(p) ){ + p->n--; +#ifdef SQLITE_DEBUG + p->bInverse = 1; +#endif + } +} +#else +# define countInverse 0 +#endif /* SQLITE_OMIT_WINDOWFUNC */ + +/* +** Routines to implement min() and max() aggregate functions. +*/ +static void minmaxStep( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + Mem *pArg = (Mem *)argv[0]; + Mem *pBest; + UNUSED_PARAMETER(NotUsed); + + pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest)); + if( !pBest ) return; + + if( sqlite3_value_type(pArg)==SQLITE_NULL ){ + if( pBest->flags ) sqlite3SkipAccumulatorLoad(context); + }else if( pBest->flags ){ + int max; + int cmp; + CollSeq *pColl = sqlite3GetFuncCollSeq(context); + /* This step function is used for both the min() and max() aggregates, + ** the only difference between the two being that the sense of the + ** comparison is inverted. For the max() aggregate, the + ** sqlite3_user_data() function returns (void *)-1. For min() it + ** returns (void *)db, where db is the sqlite3* database pointer. + ** Therefore the next statement sets variable 'max' to 1 for the max() + ** aggregate, or 0 for min(). + */ + max = sqlite3_user_data(context)!=0; + cmp = sqlite3MemCompare(pBest, pArg, pColl); + if( (max && cmp<0) || (!max && cmp>0) ){ + sqlite3VdbeMemCopy(pBest, pArg); + }else{ + sqlite3SkipAccumulatorLoad(context); + } + }else{ + pBest->db = sqlite3_context_db_handle(context); + sqlite3VdbeMemCopy(pBest, pArg); + } +} +static void minMaxValueFinalize(sqlite3_context *context, int bValue){ + sqlite3_value *pRes; + pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0); + if( pRes ){ + if( pRes->flags ){ + sqlite3_result_value(context, pRes); + } + if( bValue==0 ) sqlite3VdbeMemRelease(pRes); + } +} +#ifndef SQLITE_OMIT_WINDOWFUNC +static void minMaxValue(sqlite3_context *context){ + minMaxValueFinalize(context, 1); +} +#else +# define minMaxValue 0 +#endif /* SQLITE_OMIT_WINDOWFUNC */ +static void minMaxFinalize(sqlite3_context *context){ + minMaxValueFinalize(context, 0); +} + +/* +** group_concat(EXPR, ?SEPARATOR?) +** string_agg(EXPR, SEPARATOR) +** +** Content is accumulated in GroupConcatCtx.str with the SEPARATOR +** coming before the EXPR value, except for the first entry which +** omits the SEPARATOR. +** +** It is tragic that the SEPARATOR goes before the EXPR string. The +** groupConcatInverse() implementation would have been easier if the +** SEPARATOR were appended after EXPR. And the order is undocumented, +** so we could change it, in theory. But the old behavior has been +** around for so long that we dare not, for fear of breaking something. +*/ +typedef struct { + StrAccum str; /* The accumulated concatenation */ +#ifndef SQLITE_OMIT_WINDOWFUNC + int nAccum; /* Number of strings presently concatenated */ + int nFirstSepLength; /* Used to detect separator length change */ + /* If pnSepLengths!=0, refs an array of inter-string separator lengths, + ** stored as actually incorporated into presently accumulated result. + ** (Hence, its slots in use number nAccum-1 between method calls.) + ** If pnSepLengths==0, nFirstSepLength is the length used throughout. + */ + int *pnSepLengths; +#endif +} GroupConcatCtx; + +static void groupConcatStep( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const char *zVal; + GroupConcatCtx *pGCC; + const char *zSep; + int nVal, nSep; + assert( argc==1 || argc==2 ); + if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; + pGCC = (GroupConcatCtx*)sqlite3_aggregate_context(context, sizeof(*pGCC)); + if( pGCC ){ + sqlite3 *db = sqlite3_context_db_handle(context); + int firstTerm = pGCC->str.mxAlloc==0; + pGCC->str.mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH]; + if( argc==1 ){ + if( !firstTerm ){ + sqlite3_str_appendchar(&pGCC->str, 1, ','); + } +#ifndef SQLITE_OMIT_WINDOWFUNC + else{ + pGCC->nFirstSepLength = 1; + } +#endif + }else if( !firstTerm ){ + zSep = (char*)sqlite3_value_text(argv[1]); + nSep = sqlite3_value_bytes(argv[1]); + if( zSep ){ + sqlite3_str_append(&pGCC->str, zSep, nSep); + } +#ifndef SQLITE_OMIT_WINDOWFUNC + else{ + nSep = 0; + } + if( nSep != pGCC->nFirstSepLength || pGCC->pnSepLengths != 0 ){ + int *pnsl = pGCC->pnSepLengths; + if( pnsl == 0 ){ + /* First separator length variation seen, start tracking them. */ + pnsl = (int*)sqlite3_malloc64((pGCC->nAccum+1) * sizeof(int)); + if( pnsl!=0 ){ + int i = 0, nA = pGCC->nAccum-1; + while( inFirstSepLength; + } + }else{ + pnsl = (int*)sqlite3_realloc64(pnsl, pGCC->nAccum * sizeof(int)); + } + if( pnsl!=0 ){ + if( ALWAYS(pGCC->nAccum>0) ){ + pnsl[pGCC->nAccum-1] = nSep; + } + pGCC->pnSepLengths = pnsl; + }else{ + sqlite3StrAccumSetError(&pGCC->str, SQLITE_NOMEM); + } + } +#endif + } +#ifndef SQLITE_OMIT_WINDOWFUNC + else{ + pGCC->nFirstSepLength = sqlite3_value_bytes(argv[1]); + } + pGCC->nAccum += 1; +#endif + zVal = (char*)sqlite3_value_text(argv[0]); + nVal = sqlite3_value_bytes(argv[0]); + if( zVal ) sqlite3_str_append(&pGCC->str, zVal, nVal); + } +} + +#ifndef SQLITE_OMIT_WINDOWFUNC +static void groupConcatInverse( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GroupConcatCtx *pGCC; + assert( argc==1 || argc==2 ); + (void)argc; /* Suppress unused parameter warning */ + if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; + pGCC = (GroupConcatCtx*)sqlite3_aggregate_context(context, sizeof(*pGCC)); + /* pGCC is always non-NULL since groupConcatStep() will have always + ** run first to initialize it */ + if( ALWAYS(pGCC) ){ + int nVS; /* Number of characters to remove */ + /* Must call sqlite3_value_text() to convert the argument into text prior + ** to invoking sqlite3_value_bytes(), in case the text encoding is UTF16 */ + (void)sqlite3_value_text(argv[0]); + nVS = sqlite3_value_bytes(argv[0]); + pGCC->nAccum -= 1; + if( pGCC->pnSepLengths!=0 ){ + assert(pGCC->nAccum >= 0); + if( pGCC->nAccum>0 ){ + nVS += *pGCC->pnSepLengths; + memmove(pGCC->pnSepLengths, pGCC->pnSepLengths+1, + (pGCC->nAccum-1)*sizeof(int)); + } + }else{ + /* If removing single accumulated string, harmlessly over-do. */ + nVS += pGCC->nFirstSepLength; + } + if( nVS>=(int)pGCC->str.nChar ){ + pGCC->str.nChar = 0; + }else{ + pGCC->str.nChar -= nVS; + memmove(pGCC->str.zText, &pGCC->str.zText[nVS], pGCC->str.nChar); + } + if( pGCC->str.nChar==0 ){ + pGCC->str.mxAlloc = 0; + sqlite3_free(pGCC->pnSepLengths); + pGCC->pnSepLengths = 0; + } + } +} +#else +# define groupConcatInverse 0 +#endif /* SQLITE_OMIT_WINDOWFUNC */ +static void groupConcatFinalize(sqlite3_context *context){ + GroupConcatCtx *pGCC + = (GroupConcatCtx*)sqlite3_aggregate_context(context, 0); + if( pGCC ){ + sqlite3ResultStrAccum(context, &pGCC->str); +#ifndef SQLITE_OMIT_WINDOWFUNC + sqlite3_free(pGCC->pnSepLengths); +#endif + } +} +#ifndef SQLITE_OMIT_WINDOWFUNC +static void groupConcatValue(sqlite3_context *context){ + GroupConcatCtx *pGCC + = (GroupConcatCtx*)sqlite3_aggregate_context(context, 0); + if( pGCC ){ + StrAccum *pAccum = &pGCC->str; + if( pAccum->accError==SQLITE_TOOBIG ){ + sqlite3_result_error_toobig(context); + }else if( pAccum->accError==SQLITE_NOMEM ){ + sqlite3_result_error_nomem(context); + }else if( pGCC->nAccum>0 && pAccum->nChar==0 ){ + sqlite3_result_text(context, "", 1, SQLITE_STATIC); + }else{ + const char *zText = sqlite3_str_value(pAccum); + sqlite3_result_text(context, zText, pAccum->nChar, SQLITE_TRANSIENT); + } + } +} +#else +# define groupConcatValue 0 +#endif /* SQLITE_OMIT_WINDOWFUNC */ + +/* +** This routine does per-connection function registration. Most +** of the built-in functions above are part of the global function set. +** This routine only deals with those that are not global. +*/ +SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3 *db){ + int rc = sqlite3_overload_function(db, "MATCH", 2); + assert( rc==SQLITE_NOMEM || rc==SQLITE_OK ); + if( rc==SQLITE_NOMEM ){ + sqlite3OomFault(db); + } +} + +/* +** Re-register the built-in LIKE functions. The caseSensitive +** parameter determines whether or not the LIKE operator is case +** sensitive. +*/ +SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){ + FuncDef *pDef; + struct compareInfo *pInfo; + int flags; + int nArg; + if( caseSensitive ){ + pInfo = (struct compareInfo*)&likeInfoAlt; + flags = SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE; + }else{ + pInfo = (struct compareInfo*)&likeInfoNorm; + flags = SQLITE_FUNC_LIKE; + } + for(nArg=2; nArg<=3; nArg++){ + sqlite3CreateFunc(db, "like", nArg, SQLITE_UTF8, pInfo, likeFunc, + 0, 0, 0, 0, 0); + pDef = sqlite3FindFunction(db, "like", nArg, SQLITE_UTF8, 0); + assert( pDef!=0 ); /* The sqlite3CreateFunc() call above cannot fail + ** because the "like" SQL-function already exists */ + pDef->funcFlags |= flags; + pDef->funcFlags &= ~SQLITE_FUNC_UNSAFE; + } +} + +/* +** pExpr points to an expression which implements a function. If +** it is appropriate to apply the LIKE optimization to that function +** then set aWc[0] through aWc[2] to the wildcard characters and the +** escape character and then return TRUE. If the function is not a +** LIKE-style function then return FALSE. +** +** The expression "a LIKE b ESCAPE c" is only considered a valid LIKE +** operator if c is a string literal that is exactly one byte in length. +** That one byte is stored in aWc[3]. aWc[3] is set to zero if there is +** no ESCAPE clause. +** +** *pIsNocase is set to true if uppercase and lowercase are equivalent for +** the function (default for LIKE). If the function makes the distinction +** between uppercase and lowercase (as does GLOB) then *pIsNocase is set to +** false. +*/ +SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){ + FuncDef *pDef; + int nExpr; + assert( pExpr!=0 ); + assert( pExpr->op==TK_FUNCTION ); + assert( ExprUseXList(pExpr) ); + if( !pExpr->x.pList ){ + return 0; + } + nExpr = pExpr->x.pList->nExpr; + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + pDef = sqlite3FindFunction(db, pExpr->u.zToken, nExpr, SQLITE_UTF8, 0); +#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION + if( pDef==0 ) return 0; +#endif + if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_LIKE)==0 ){ + return 0; + } + + /* The memcpy() statement assumes that the wildcard characters are + ** the first three statements in the compareInfo structure. The + ** asserts() that follow verify that assumption + */ + memcpy(aWc, pDef->pUserData, 3); + assert( (char*)&likeInfoAlt == (char*)&likeInfoAlt.matchAll ); + assert( &((char*)&likeInfoAlt)[1] == (char*)&likeInfoAlt.matchOne ); + assert( &((char*)&likeInfoAlt)[2] == (char*)&likeInfoAlt.matchSet ); + + if( nExpr<3 ){ + aWc[3] = 0; + }else{ + Expr *pEscape = pExpr->x.pList->a[2].pExpr; + char *zEscape; + if( pEscape->op!=TK_STRING ) return 0; + assert( !ExprHasProperty(pEscape, EP_IntValue) ); + zEscape = pEscape->u.zToken; + if( zEscape[0]==0 || zEscape[1]!=0 ) return 0; + if( zEscape[0]==aWc[0] ) return 0; + if( zEscape[0]==aWc[1] ) return 0; + aWc[3] = zEscape[0]; + } + + *pIsNocase = (pDef->funcFlags & SQLITE_FUNC_CASE)==0; + return 1; +} + +/* Mathematical Constants */ +#ifndef M_PI +# define M_PI 3.141592653589793238462643383279502884 +#endif +#ifndef M_LN10 +# define M_LN10 2.302585092994045684017991454684364208 +#endif +#ifndef M_LN2 +# define M_LN2 0.693147180559945309417232121458176568 +#endif + + +/* Extra math functions that require linking with -lm +*/ +#ifdef SQLITE_ENABLE_MATH_FUNCTIONS +/* +** Implementation SQL functions: +** +** ceil(X) +** ceiling(X) +** floor(X) +** +** The sqlite3_user_data() pointer is a pointer to the libm implementation +** of the underlying C function. +*/ +static void ceilingFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + assert( argc==1 ); + switch( sqlite3_value_numeric_type(argv[0]) ){ + case SQLITE_INTEGER: { + sqlite3_result_int64(context, sqlite3_value_int64(argv[0])); + break; + } + case SQLITE_FLOAT: { + double (*x)(double) = (double(*)(double))sqlite3_user_data(context); + sqlite3_result_double(context, x(sqlite3_value_double(argv[0]))); + break; + } + default: { + break; + } + } +} + +/* +** On some systems, ceil() and floor() are intrinsic function. You are +** unable to take a pointer to these functions. Hence, we here wrap them +** in our own actual functions. +*/ +static double xCeil(double x){ return ceil(x); } +static double xFloor(double x){ return floor(x); } + +/* +** Some systems do not have log2() and log10() in their standard math +** libraries. +*/ +#if defined(HAVE_LOG10) && HAVE_LOG10==0 +# define log10(X) (0.4342944819032517867*log(X)) +#endif +#if defined(HAVE_LOG2) && HAVE_LOG2==0 +# define log2(X) (1.442695040888963456*log(X)) +#endif + + +/* +** Implementation of SQL functions: +** +** ln(X) - natural logarithm +** log(X) - log X base 10 +** log10(X) - log X base 10 +** log(B,X) - log X base B +*/ +static void logFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + double x, b, ans; + assert( argc==1 || argc==2 ); + switch( sqlite3_value_numeric_type(argv[0]) ){ + case SQLITE_INTEGER: + case SQLITE_FLOAT: + x = sqlite3_value_double(argv[0]); + if( x<=0.0 ) return; + break; + default: + return; + } + if( argc==2 ){ + switch( sqlite3_value_numeric_type(argv[0]) ){ + case SQLITE_INTEGER: + case SQLITE_FLOAT: + b = log(x); + if( b<=0.0 ) return; + x = sqlite3_value_double(argv[1]); + if( x<=0.0 ) return; + break; + default: + return; + } + ans = log(x)/b; + }else{ + switch( SQLITE_PTR_TO_INT(sqlite3_user_data(context)) ){ + case 1: + ans = log10(x); + break; + case 2: + ans = log2(x); + break; + default: + ans = log(x); + break; + } + } + sqlite3_result_double(context, ans); +} + +/* +** Functions to converts degrees to radians and radians to degrees. +*/ +static double degToRad(double x){ return x*(M_PI/180.0); } +static double radToDeg(double x){ return x*(180.0/M_PI); } + +/* +** Implementation of 1-argument SQL math functions: +** +** exp(X) - Compute e to the X-th power +*/ +static void math1Func( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int type0; + double v0, ans; + double (*x)(double); + assert( argc==1 ); + type0 = sqlite3_value_numeric_type(argv[0]); + if( type0!=SQLITE_INTEGER && type0!=SQLITE_FLOAT ) return; + v0 = sqlite3_value_double(argv[0]); + x = (double(*)(double))sqlite3_user_data(context); + ans = x(v0); + sqlite3_result_double(context, ans); +} + +/* +** Implementation of 2-argument SQL math functions: +** +** power(X,Y) - Compute X to the Y-th power +*/ +static void math2Func( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int type0, type1; + double v0, v1, ans; + double (*x)(double,double); + assert( argc==2 ); + type0 = sqlite3_value_numeric_type(argv[0]); + if( type0!=SQLITE_INTEGER && type0!=SQLITE_FLOAT ) return; + type1 = sqlite3_value_numeric_type(argv[1]); + if( type1!=SQLITE_INTEGER && type1!=SQLITE_FLOAT ) return; + v0 = sqlite3_value_double(argv[0]); + v1 = sqlite3_value_double(argv[1]); + x = (double(*)(double,double))sqlite3_user_data(context); + ans = x(v0, v1); + sqlite3_result_double(context, ans); +} + +/* +** Implementation of 0-argument pi() function. +*/ +static void piFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + assert( argc==0 ); + (void)argv; + sqlite3_result_double(context, M_PI); +} + +#endif /* SQLITE_ENABLE_MATH_FUNCTIONS */ + +/* +** Implementation of sign(X) function. +*/ +static void signFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int type0; + double x; + UNUSED_PARAMETER(argc); + assert( argc==1 ); + type0 = sqlite3_value_numeric_type(argv[0]); + if( type0!=SQLITE_INTEGER && type0!=SQLITE_FLOAT ) return; + x = sqlite3_value_double(argv[0]); + sqlite3_result_int(context, x<0.0 ? -1 : x>0.0 ? +1 : 0); +} + +#if defined(SQLITE_ENABLE_PERCENTILE) +/*********************************************************************** +** This section implements the percentile(Y,P) SQL function and similar. +** Requirements: +** +** (1) The percentile(Y,P) function is an aggregate function taking +** exactly two arguments. +** +** (2) If the P argument to percentile(Y,P) is not the same for every +** row in the aggregate then an error is thrown. The word "same" +** in the previous sentence means that the value differ by less +** than 0.001. +** +** (3) If the P argument to percentile(Y,P) evaluates to anything other +** than a number in the range of 0.0 to 100.0 inclusive then an +** error is thrown. +** +** (4) If any Y argument to percentile(Y,P) evaluates to a value that +** is not NULL and is not numeric then an error is thrown. +** +** (5) If any Y argument to percentile(Y,P) evaluates to plus or minus +** infinity then an error is thrown. (SQLite always interprets NaN +** values as NULL.) +** +** (6) Both Y and P in percentile(Y,P) can be arbitrary expressions, +** including CASE WHEN expressions. +** +** (7) The percentile(Y,P) aggregate is able to handle inputs of at least +** one million (1,000,000) rows. +** +** (8) If there are no non-NULL values for Y, then percentile(Y,P) +** returns NULL. +** +** (9) If there is exactly one non-NULL value for Y, the percentile(Y,P) +** returns the one Y value. +** +** (10) If there N non-NULL values of Y where N is two or more and +** the Y values are ordered from least to greatest and a graph is +** drawn from 0 to N-1 such that the height of the graph at J is +** the J-th Y value and such that straight lines are drawn between +** adjacent Y values, then the percentile(Y,P) function returns +** the height of the graph at P*(N-1)/100. +** +** (11) The percentile(Y,P) function always returns either a floating +** point number or NULL. +** +** (12) The percentile(Y,P) is implemented as a single C99 source-code +** file that compiles into a shared-library or DLL that can be loaded +** into SQLite using the sqlite3_load_extension() interface. +** +** (13) A separate median(Y) function is the equivalent percentile(Y,50). +** +** (14) A separate percentile_cont(Y,P) function is equivalent to +** percentile(Y,P/100.0). In other words, the fraction value in +** the second argument is in the range of 0 to 1 instead of 0 to 100. +** +** (15) A separate percentile_disc(Y,P) function is like +** percentile_cont(Y,P) except that instead of returning the weighted +** average of the nearest two input values, it returns the next lower +** value. So the percentile_disc(Y,P) will always return a value +** that was one of the inputs. +** +** (16) All of median(), percentile(Y,P), percentile_cont(Y,P) and +** percentile_disc(Y,P) can be used as window functions. +** +** Differences from standard SQL: +** +** * The percentile_cont(X,P) function is equivalent to the following in +** standard SQL: +** +** (percentile_cont(P) WITHIN GROUP (ORDER BY X)) +** +** The SQLite syntax is much more compact. The standard SQL syntax +** is also supported if SQLite is compiled with the +** -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES option. +** +** * No median(X) function exists in the SQL standard. App developers +** are expected to write "percentile_cont(0.5)WITHIN GROUP(ORDER BY X)". +** +** * No percentile(Y,P) function exists in the SQL standard. Instead of +** percential(Y,P), developers must write this: +** "percentile_cont(P/100.0) WITHIN GROUP (ORDER BY Y)". Note that +** the fraction parameter to percentile() goes from 0 to 100 whereas +** the fraction parameter in SQL standard percentile_cont() goes from +** 0 to 1. +** +** Implementation notes as of 2024-08-31: +** +** * The regular aggregate-function versions of these routines work +** by accumulating all values in an array of doubles, then sorting +** that array using quicksort before computing the answer. Thus +** the runtime is O(NlogN) where N is the number of rows of input. +** +** * For the window-function versions of these routines, the array of +** inputs is sorted as soon as the first value is computed. Thereafter, +** the array is kept in sorted order using an insert-sort. This +** results in O(N*K) performance where K is the size of the window. +** One can imagine alternative implementations that give O(N*logN*logK) +** performance, but they require more complex logic and data structures. +** The developers have elected to keep the asymptotically slower +** algorithm for now, for simplicity, under the theory that window +** functions are seldom used and when they are, the window size K is +** often small. The developers might revisit that decision later, +** should the need arise. +*/ + +/* The following object is the group context for a single percentile() +** aggregate. Remember all input Y values until the very end. +** Those values are accumulated in the Percentile.a[] array. +*/ +typedef struct Percentile Percentile; +struct Percentile { + u64 nAlloc; /* Number of slots allocated for a[] */ + u64 nUsed; /* Number of slots actually used in a[] */ + char bSorted; /* True if a[] is already in sorted order */ + char bKeepSorted; /* True if advantageous to keep a[] sorted */ + char bPctValid; /* True if rPct is valid */ + double rPct; /* Fraction. 0.0 to 1.0 */ + double *a; /* Array of Y values */ +}; + +/* +** Return TRUE if the input floating-point number is an infinity. +*/ +static int percentIsInfinity(double r){ + sqlite3_uint64 u; + assert( sizeof(u)==sizeof(r) ); + memcpy(&u, &r, sizeof(u)); + return ((u>>52)&0x7ff)==0x7ff; +} + +/* +** Return TRUE if two doubles differ by 0.001 or less. +*/ +static int percentSameValue(double a, double b){ + a -= b; + return a>=-0.001 && a<=0.001; +} + +/* +** Search p (which must have p->bSorted) looking for an entry with +** value y. Return the index of that entry. +** +** If bExact is true, return -1 if the entry is not found. +** +** If bExact is false, return the index at which a new entry with +** value y should be insert in order to keep the values in sorted +** order. The smallest return value in this case will be 0, and +** the largest return value will be p->nUsed. +*/ +static i64 percentBinarySearch(Percentile *p, double y, int bExact){ + i64 iFirst = 0; /* First element of search range */ + i64 iLast = (i64)p->nUsed - 1; /* Last element of search range */ + while( iLast>=iFirst ){ + i64 iMid = (iFirst+iLast)/2; + double x = p->a[iMid]; + if( xy ){ + iLast = iMid - 1; + }else{ + return iMid; + } + } + if( bExact ) return -1; + return iFirst; +} + +/* +** Generate an error for a percentile function. +** +** The error format string must have exactly one occurrence of "%%s()" +** (with two '%' characters). That substring will be replaced by the name +** of the function. +*/ +static void percentError(sqlite3_context *pCtx, const char *zFormat, ...){ + char *zMsg1; + char *zMsg2; + va_list ap; + + va_start(ap, zFormat); + zMsg1 = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + zMsg2 = zMsg1 ? sqlite3_mprintf(zMsg1, sqlite3VdbeFuncName(pCtx)) : 0; + sqlite3_result_error(pCtx, zMsg2, -1); + sqlite3_free(zMsg1); + sqlite3_free(zMsg2); +} + +/* +** The "step" function for percentile(Y,P) is called once for each +** input row. +*/ +static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){ + Percentile *p; + double rPct; + int eType; + double y; + assert( argc==2 || argc==1 ); + + if( argc==1 ){ + /* Requirement 13: median(Y) is the same as percentile(Y,50). */ + rPct = 0.5; + }else{ + /* P must be a number between 0 and 100 for percentile() or between + ** 0.0 and 1.0 for percentile_cont() and percentile_disc(). + ** + ** The user-data is an integer which is 10 times the upper bound. + */ + double mxFrac = (SQLITE_PTR_TO_INT(sqlite3_user_data(pCtx))&2)? 100.0 : 1.0; + eType = sqlite3_value_numeric_type(argv[1]); + rPct = sqlite3_value_double(argv[1])/mxFrac; + if( (eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT) + || rPct<0.0 || rPct>1.0 + ){ + percentError(pCtx, "the fraction argument to %%s()" + " is not between 0.0 and %.1f", + (double)mxFrac); + return; + } + } + + /* Allocate the session context. */ + p = (Percentile*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p==0 ) return; + + /* Remember the P value. Throw an error if the P value is different + ** from any prior row, per Requirement (2). */ + if( !p->bPctValid ){ + p->rPct = rPct; + p->bPctValid = 1; + }else if( !percentSameValue(p->rPct,rPct) ){ + percentError(pCtx, "the fraction argument to %%s()" + " is not the same for all input rows"); + return; + } + + /* Ignore rows for which Y is NULL */ + eType = sqlite3_value_type(argv[0]); + if( eType==SQLITE_NULL ) return; + + /* If not NULL, then Y must be numeric. Otherwise throw an error. + ** Requirement 4 */ + if( eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT ){ + percentError(pCtx, "input to %%s() is not numeric"); + return; + } + + /* Throw an error if the Y value is infinity or NaN */ + y = sqlite3_value_double(argv[0]); + if( percentIsInfinity(y) ){ + percentError(pCtx, "Inf input to %%s()"); + return; + } + + /* Allocate and store the Y */ + if( p->nUsed>=p->nAlloc ){ + u64 n = p->nAlloc*2 + 250; + double *a = sqlite3_realloc64(p->a, sizeof(double)*n); + if( a==0 ){ + sqlite3_free(p->a); + memset(p, 0, sizeof(*p)); + sqlite3_result_error_nomem(pCtx); + return; + } + p->nAlloc = n; + p->a = a; + } + if( p->nUsed==0 ){ + p->a[p->nUsed++] = y; + p->bSorted = 1; + }else if( !p->bSorted || y>=p->a[p->nUsed-1] ){ + p->a[p->nUsed++] = y; + }else if( p->bKeepSorted ){ + i64 i; + i = percentBinarySearch(p, y, 0); + if( i<(int)p->nUsed ){ + memmove(&p->a[i+1], &p->a[i], (p->nUsed-i)*sizeof(p->a[0])); + } + p->a[i] = y; + p->nUsed++; + }else{ + p->a[p->nUsed++] = y; + p->bSorted = 0; + } +} + +/* +** Interchange two doubles. +*/ +#define SWAP_DOUBLE(X,Y) {double ttt=(X);(X)=(Y);(Y)=ttt;} + +/* +** Sort an array of doubles. +** +** Algorithm: quicksort +** +** This is implemented separately rather than using the qsort() routine +** from the standard library because: +** +** (1) To avoid a dependency on qsort() +** (2) To avoid the function call to the comparison routine for each +** comparison. +*/ +static void percentSort(double *a, unsigned int n){ + int iLt; /* Entries before a[iLt] are less than rPivot */ + int iGt; /* Entries at or after a[iGt] are greater than rPivot */ + int i; /* Loop counter */ + double rPivot; /* The pivot value */ + + while( n>=2 ){ + if( a[0]>a[n-1] ){ + SWAP_DOUBLE(a[0],a[n-1]) + } + if( n==2 ) return; + iGt = n-1; + i = n/2; + if( a[0]>a[i] ){ + SWAP_DOUBLE(a[0],a[i]) + }else if( a[i]>a[iGt] ){ + SWAP_DOUBLE(a[i],a[iGt]) + } + if( n==3 ) return; + rPivot = a[i]; + iLt = i = 1; + do{ + if( a[i]iLt ) SWAP_DOUBLE(a[i],a[iLt]) + iLt++; + i++; + }else if( a[i]>rPivot ){ + do{ + iGt--; + }while( iGt>i && a[iGt]>rPivot ); + SWAP_DOUBLE(a[i],a[iGt]) + }else{ + i++; + } + }while( i(int)(n/2) ){ + if( n-iGt>=2 ) percentSort(a+iGt, n-iGt); + n = iLt; + }else{ + if( iLt>=2 ) percentSort(a, iLt); + a += iGt; + n -= iGt; + } + } +} + +/* +** The "inverse" function for percentile(Y,P) is called to remove a +** row that was previously inserted by "step". +*/ +static void percentInverse(sqlite3_context *pCtx,int argc,sqlite3_value **argv){ + Percentile *p; + int eType; + double y; + i64 i; + assert( argc==2 || argc==1 ); + + /* Allocate the session context. */ + p = (Percentile*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + assert( p!=0 ); + + /* Ignore rows for which Y is NULL */ + eType = sqlite3_value_type(argv[0]); + if( eType==SQLITE_NULL ) return; + + /* If not NULL, then Y must be numeric. Otherwise throw an error. + ** Requirement 4 */ + if( eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT ){ + return; + } + + /* Ignore the Y value if it is infinity or NaN */ + y = sqlite3_value_double(argv[0]); + if( percentIsInfinity(y) ){ + return; + } + if( p->bSorted==0 ){ + assert( p->nUsed>1 ); + percentSort(p->a, p->nUsed); + p->bSorted = 1; + } + p->bKeepSorted = 1; + + /* Find and remove the row */ + i = percentBinarySearch(p, y, 1); + if( i>=0 ){ + p->nUsed--; + if( i<(int)p->nUsed ){ + memmove(&p->a[i], &p->a[i+1], (p->nUsed - i)*sizeof(p->a[0])); + } + } +} + +/* +** Compute the final output of percentile(). Clean up all allocated +** memory if and only if bIsFinal is true. +*/ +static void percentCompute(sqlite3_context *pCtx, int bIsFinal){ + Percentile *p; + int settings = SQLITE_PTR_TO_INT(sqlite3_user_data(pCtx))&1; /* Discrete? */ + unsigned i1, i2; + double v1, v2; + double ix, vx; + p = (Percentile*)sqlite3_aggregate_context(pCtx, 0); + if( p==0 ) return; + if( p->a==0 ) return; + if( p->nUsed ){ + if( p->bSorted==0 ){ + assert( p->nUsed>1 ); + percentSort(p->a, p->nUsed); + p->bSorted = 1; + } + ix = p->rPct*(p->nUsed-1); + i1 = (unsigned)ix; + if( settings & 1 ){ + vx = p->a[i1]; + }else{ + i2 = ix==(double)i1 || i1==p->nUsed-1 ? i1 : i1+1; + v1 = p->a[i1]; + v2 = p->a[i2]; + vx = v1 + (v2-v1)*(ix-i1); + } + sqlite3_result_double(pCtx, vx); + } + if( bIsFinal ){ + sqlite3_free(p->a); + memset(p, 0, sizeof(*p)); + }else{ + p->bKeepSorted = 1; + } +} +static void percentFinal(sqlite3_context *pCtx){ + percentCompute(pCtx, 1); +} +static void percentValue(sqlite3_context *pCtx){ + percentCompute(pCtx, 0); +} +/****** End of percentile family of functions ******/ +#endif /* SQLITE_ENABLE_PERCENTILE */ + +#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT) +/* +** Implementation of sqlite_filestat(SCHEMA). +** +** Return JSON text that describes low-level debug/diagnostic information +** about the sqlite3_file object associated with SCHEMA. +*/ +static void filestatFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + const char *zDbName; + sqlite3_str *pStr; + Btree *pBtree; + + zDbName = (const char*)sqlite3_value_text(argv[0]); + pBtree = sqlite3DbNameToBtree(db, zDbName); + if( pBtree ){ + Pager *pPager; + sqlite3_file *fd; + int rc; + sqlite3BtreeEnter(pBtree); + pPager = sqlite3BtreePager(pBtree); + assert( pPager!=0 ); + fd = sqlite3PagerFile(pPager); + pStr = sqlite3_str_new(db); + if( pStr==0 ){ + sqlite3_result_error_nomem(context); + }else{ + sqlite3_str_append(pStr, "{\"db\":", 6); + rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_FILESTAT, pStr); + if( rc ) sqlite3_str_append(pStr, "null", 4); + fd = sqlite3PagerJrnlFile(pPager); + if( fd && fd->pMethods!=0 ){ + sqlite3_str_appendall(pStr, ",\"journal\":"); + rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_FILESTAT, pStr); + if( rc ) sqlite3_str_append(pStr, "null", 4); + } + sqlite3_str_append(pStr, "}", 1); + sqlite3_result_text(context, sqlite3_str_finish(pStr), -1, + sqlite3_free); + } + sqlite3BtreeLeave(pBtree); + }else{ + sqlite3_result_text(context, "{}", 2, SQLITE_STATIC); + } +} +#endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */ + +#ifdef SQLITE_DEBUG +/* +** Implementation of fpdecode(x,y,z) function. +** +** x is a real number that is to be decoded. y is the precision. +** z is the maximum real precision. Return a string that shows the +** results of the sqlite3FpDecode() function. +** +** Used for testing and debugging only, specifically testing and debugging +** of the sqlite3FpDecode() function. This SQL function does not appear +** in production builds. This function is not an API and is subject to +** modification or removal in future versions of SQLite. +*/ +static void fpdecodeFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + FpDecode s; + double x; + int y, z; + char zBuf[100]; + UNUSED_PARAMETER(argc); + assert( argc==3 ); + x = sqlite3_value_double(argv[0]); + y = sqlite3_value_int(argv[1]); + z = sqlite3_value_int(argv[2]); + if( z<=0 ) z = 1; + sqlite3FpDecode(&s, x, y, z); + if( s.isSpecial==2 ){ + sqlite3_snprintf(sizeof(zBuf), zBuf, "NaN"); + }else{ + sqlite3_snprintf(sizeof(zBuf), zBuf, "%c%.*s/%d", s.sign, s.n, s.z, s.iDP); + } + sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); +} +#endif /* SQLITE_DEBUG */ + +#ifdef SQLITE_DEBUG +/* +** Implementation of parseuri(uri,flags) function. +** +** Required Arguments: +** "uri" The URI to parse. +** "flags" Bitmask of flags, as if to sqlite3_open_v2(). +** +** Additional arguments beyond the first two make calls to +** sqlite3_uri_key() for integers and sqlite3_uri_parameter for +** anything else. +** +** The result is a string showing the results of calling sqlite3ParseUri(). +** +** Used for testing and debugging only, specifically testing and debugging +** of the sqlite3ParseUri() function. This SQL function does not appear +** in production builds. This function is not an API and is subject to +** modification or removal in future versions of SQLite. +*/ +static void parseuriFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + sqlite3_str *pResult; + const char *zVfs; + const char *zUri; + unsigned int flgs; + int rc; + sqlite3_vfs *pVfs = 0; + char *zFile = 0; + char *zErr = 0; + + if( argc<2 ) return; + pVfs = sqlite3_vfs_find(0); + assert( pVfs ); + zVfs = pVfs->zName; + zUri = (const char*)sqlite3_value_text(argv[0]); + if( zUri==0 ) return; + flgs = (unsigned int)sqlite3_value_int(argv[1]); + rc = sqlite3ParseUri(zVfs, zUri, &flgs, &pVfs, &zFile, &zErr); + pResult = sqlite3_str_new(0); + if( pResult ){ + int i; + sqlite3_str_appendf(pResult, "rc=%d", rc); + sqlite3_str_appendf(pResult, ", flags=0x%x", flgs); + sqlite3_str_appendf(pResult, ", vfs=%Q", pVfs ? pVfs->zName: 0); + sqlite3_str_appendf(pResult, ", err=%Q", zErr); + sqlite3_str_appendf(pResult, ", file=%Q", zFile); + if( zFile ){ + const char *z = zFile; + z += sqlite3Strlen30(z)+1; + while( z[0] ){ + sqlite3_str_appendf(pResult, ", %Q", z); + z += sqlite3Strlen30(z)+1; + } + for(i=2; iu.pHash){ + int n = sqlite3Strlen30(p->zName); + int h = p->zName[0] + n; + assert( p->funcFlags & SQLITE_FUNC_BUILTIN ); + printf(" %s(%d)", p->zName, h); + } + printf("\n"); + } + } +#endif +} + +/************** End of func.c ************************************************/ +/************** Begin file fkey.c ********************************************/ +/* +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code used by the compiler to add foreign key +** support to compiled SQL statements. +*/ +/* #include "sqliteInt.h" */ + +#ifndef SQLITE_OMIT_FOREIGN_KEY +#ifndef SQLITE_OMIT_TRIGGER + +/* +** Deferred and Immediate FKs +** -------------------------- +** +** Foreign keys in SQLite come in two flavours: deferred and immediate. +** If an immediate foreign key constraint is violated, +** SQLITE_CONSTRAINT_FOREIGNKEY is returned and the current +** statement transaction rolled back. If a +** deferred foreign key constraint is violated, no action is taken +** immediately. However if the application attempts to commit the +** transaction before fixing the constraint violation, the attempt fails. +** +** Deferred constraints are implemented using a simple counter associated +** with the database handle. The counter is set to zero each time a +** database transaction is opened. Each time a statement is executed +** that causes a foreign key violation, the counter is incremented. Each +** time a statement is executed that removes an existing violation from +** the database, the counter is decremented. When the transaction is +** committed, the commit fails if the current value of the counter is +** greater than zero. This scheme has two big drawbacks: +** +** * When a commit fails due to a deferred foreign key constraint, +** there is no way to tell which foreign constraint is not satisfied, +** or which row it is not satisfied for. +** +** * If the database contains foreign key violations when the +** transaction is opened, this may cause the mechanism to malfunction. +** +** Despite these problems, this approach is adopted as it seems simpler +** than the alternatives. +** +** INSERT operations: +** +** I.1) For each FK for which the table is the child table, search +** the parent table for a match. If none is found increment the +** constraint counter. +** +** I.2) For each FK for which the table is the parent table, +** search the child table for rows that correspond to the new +** row in the parent table. Decrement the counter for each row +** found (as the constraint is now satisfied). +** +** DELETE operations: +** +** D.1) For each FK for which the table is the child table, +** search the parent table for a row that corresponds to the +** deleted row in the child table. If such a row is not found, +** decrement the counter. +** +** D.2) For each FK for which the table is the parent table, search +** the child table for rows that correspond to the deleted row +** in the parent table. For each found increment the counter. +** +** UPDATE operations: +** +** An UPDATE command requires that all 4 steps above are taken, but only +** for FK constraints for which the affected columns are actually +** modified (values must be compared at runtime). +** +** Note that I.1 and D.1 are very similar operations, as are I.2 and D.2. +** This simplifies the implementation a bit. +** +** For the purposes of immediate FK constraints, the OR REPLACE conflict +** resolution is considered to delete rows before the new row is inserted. +** If a delete caused by OR REPLACE violates an FK constraint, an exception +** is thrown, even if the FK constraint would be satisfied after the new +** row is inserted. +** +** Immediate constraints are usually handled similarly. The only difference +** is that the counter used is stored as part of each individual statement +** object (struct Vdbe). If, after the statement has run, its immediate +** constraint counter is greater than zero, +** it returns SQLITE_CONSTRAINT_FOREIGNKEY +** and the statement transaction is rolled back. An exception is an INSERT +** statement that inserts a single row only (no triggers). In this case, +** instead of using a counter, an exception is thrown immediately if the +** INSERT violates a foreign key constraint. This is necessary as such +** an INSERT does not open a statement transaction. +** +** TODO: How should dropping a table be handled? How should renaming a +** table be handled? +** +** +** Query API Notes +** --------------- +** +** Before coding an UPDATE or DELETE row operation, the code-generator +** for those two operations needs to know whether or not the operation +** requires any FK processing and, if so, which columns of the original +** row are required by the FK processing VDBE code (i.e. if FKs were +** implemented using triggers, which of the old.* columns would be +** accessed). No information is required by the code-generator before +** coding an INSERT operation. The functions used by the UPDATE/DELETE +** generation code to query for this information are: +** +** sqlite3FkRequired() - Test to see if FK processing is required. +** sqlite3FkOldmask() - Query for the set of required old.* columns. +** +** +** Externally accessible module functions +** -------------------------------------- +** +** sqlite3FkCheck() - Check for foreign key violations. +** sqlite3FkActions() - Code triggers for ON UPDATE/ON DELETE actions. +** sqlite3FkDelete() - Delete an FKey structure. +*/ + +/* +** VDBE Calling Convention +** ----------------------- +** +** Example: +** +** For the following INSERT statement: +** +** CREATE TABLE t1(a, b INTEGER PRIMARY KEY, c); +** INSERT INTO t1 VALUES(1, 2, 3.1); +** +** Register (x): 2 (type integer) +** Register (x+1): 1 (type integer) +** Register (x+2): NULL (type NULL) +** Register (x+3): 3.1 (type real) +*/ + +/* +** A foreign key constraint requires that the key columns in the parent +** table are collectively subject to a UNIQUE or PRIMARY KEY constraint. +** Given that pParent is the parent table for foreign key constraint pFKey, +** search the schema for a unique index on the parent key columns. +** +** If successful, zero is returned. If the parent key is an INTEGER PRIMARY +** KEY column, then output variable *ppIdx is set to NULL. Otherwise, *ppIdx +** is set to point to the unique index. +** +** If the parent key consists of a single column (the foreign key constraint +** is not a composite foreign key), output variable *paiCol is set to NULL. +** Otherwise, it is set to point to an allocated array of size N, where +** N is the number of columns in the parent key. The first element of the +** array is the index of the child table column that is mapped by the FK +** constraint to the parent table column stored in the left-most column +** of index *ppIdx. The second element of the array is the index of the +** child table column that corresponds to the second left-most column of +** *ppIdx, and so on. +** +** If the required index cannot be found, either because: +** +** 1) The named parent key columns do not exist, or +** +** 2) The named parent key columns do exist, but are not subject to a +** UNIQUE or PRIMARY KEY constraint, or +** +** 3) No parent key columns were provided explicitly as part of the +** foreign key definition, and the parent table does not have a +** PRIMARY KEY, or +** +** 4) No parent key columns were provided explicitly as part of the +** foreign key definition, and the PRIMARY KEY of the parent table +** consists of a different number of columns to the child key in +** the child table. +** +** then non-zero is returned, and a "foreign key mismatch" error loaded +** into pParse. If an OOM error occurs, non-zero is returned and the +** pParse->db->mallocFailed flag is set. +*/ +SQLITE_PRIVATE int sqlite3FkLocateIndex( + Parse *pParse, /* Parse context to store any error in */ + Table *pParent, /* Parent table of FK constraint pFKey */ + FKey *pFKey, /* Foreign key to find index for */ + Index **ppIdx, /* OUT: Unique index on parent table */ + int **paiCol /* OUT: Map of index columns in pFKey */ +){ + Index *pIdx = 0; /* Value to return via *ppIdx */ + int *aiCol = 0; /* Value to return via *paiCol */ + int nCol = pFKey->nCol; /* Number of columns in parent key */ + char *zKey = pFKey->aCol[0].zCol; /* Name of left-most parent key column */ + + /* The caller is responsible for zeroing output parameters. */ + assert( ppIdx && *ppIdx==0 ); + assert( !paiCol || *paiCol==0 ); + assert( pParse ); + + /* If this is a non-composite (single column) foreign key, check if it + ** maps to the INTEGER PRIMARY KEY of table pParent. If so, leave *ppIdx + ** and *paiCol set to zero and return early. + ** + ** Otherwise, for a composite foreign key (more than one column), allocate + ** space for the aiCol array (returned via output parameter *paiCol). + ** Non-composite foreign keys do not require the aiCol array. + */ + if( nCol==1 ){ + /* The FK maps to the IPK if any of the following are true: + ** + ** 1) There is an INTEGER PRIMARY KEY column and the FK is implicitly + ** mapped to the primary key of table pParent, or + ** 2) The FK is explicitly mapped to a column declared as INTEGER + ** PRIMARY KEY. + */ + if( pParent->iPKey>=0 ){ + if( !zKey ) return 0; + if( !sqlite3StrICmp(pParent->aCol[pParent->iPKey].zCnName, zKey) ){ + return 0; + } + } + }else if( paiCol ){ + assert( nCol>1 ); + aiCol = (int *)sqlite3DbMallocRawNN(pParse->db, nCol*sizeof(int)); + if( !aiCol ) return 1; + *paiCol = aiCol; + } + + for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){ + if( pIdx->nKeyCol==nCol && IsUniqueIndex(pIdx) && pIdx->pPartIdxWhere==0 ){ + /* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number + ** of columns. If each indexed column corresponds to a foreign key + ** column of pFKey, then this index is a winner. */ + + if( zKey==0 ){ + /* If zKey is NULL, then this foreign key is implicitly mapped to + ** the PRIMARY KEY of table pParent. The PRIMARY KEY index may be + ** identified by the test. */ + if( IsPrimaryKeyIndex(pIdx) ){ + if( aiCol ){ + int i; + for(i=0; iaCol[i].iFrom; + } + break; + } + }else{ + /* If zKey is non-NULL, then this foreign key was declared to + ** map to an explicit list of columns in table pParent. Check if this + ** index matches those columns. Also, check that the index uses + ** the default collation sequences for each column. */ + int i, j; + for(i=0; iaiColumn[i]; /* Index of column in parent tbl */ + const char *zDfltColl; /* Def. collation for column */ + char *zIdxCol; /* Name of indexed column */ + + if( iCol<0 ) break; /* No foreign keys against expression indexes */ + + /* If the index uses a collation sequence that is different from + ** the default collation sequence for the column, this index is + ** unusable. Bail out early in this case. */ + zDfltColl = sqlite3ColumnColl(&pParent->aCol[iCol]); + if( !zDfltColl ) zDfltColl = sqlite3StrBINARY; + if( sqlite3StrICmp(pIdx->azColl[i], zDfltColl) ) break; + + zIdxCol = pParent->aCol[iCol].zCnName; + for(j=0; jaCol[j].zCol, zIdxCol)==0 ){ + if( aiCol ) aiCol[i] = pFKey->aCol[j].iFrom; + break; + } + } + if( j==nCol ) break; + } + if( i==nCol ) break; /* pIdx is usable */ + } + } + } + + if( !pIdx ){ + if( !pParse->disableTriggers ){ + sqlite3ErrorMsg(pParse, + "foreign key mismatch - \"%w\" referencing \"%w\"", + pFKey->pFrom->zName, pFKey->zTo); + } + sqlite3DbFree(pParse->db, aiCol); + return 1; + } + + *ppIdx = pIdx; + return 0; +} + +/* +** This function is called when a row is inserted into or deleted from the +** child table of foreign key constraint pFKey. If an SQL UPDATE is executed +** on the child table of pFKey, this function is invoked twice for each row +** affected - once to "delete" the old row, and then again to "insert" the +** new row. +** +** Each time it is called, this function generates VDBE code to locate the +** row in the parent table that corresponds to the row being inserted into +** or deleted from the child table. If the parent row can be found, no +** special action is taken. Otherwise, if the parent row can *not* be +** found in the parent table: +** +** Operation | FK type | Action taken +** -------------------------------------------------------------------------- +** INSERT immediate Increment the "immediate constraint counter". +** +** DELETE immediate Decrement the "immediate constraint counter". +** +** INSERT deferred Increment the "deferred constraint counter". +** +** DELETE deferred Decrement the "deferred constraint counter". +** +** These operations are identified in the comment at the top of this file +** (fkey.c) as "I.1" and "D.1". +*/ +static void fkLookupParent( + Parse *pParse, /* Parse context */ + int iDb, /* Index of database housing pTab */ + Table *pTab, /* Parent table of FK pFKey */ + Index *pIdx, /* Unique index on parent key columns in pTab */ + FKey *pFKey, /* Foreign key constraint */ + int *aiCol, /* Map from parent key columns to child table columns */ + int regData, /* Address of array containing child table row */ + int nIncr, /* Increment constraint counter by this */ + int isIgnore /* If true, pretend pTab contains all NULL values */ +){ + int i; /* Iterator variable */ + Vdbe *v = sqlite3GetVdbe(pParse); /* Vdbe to add code to */ + int iCur = pParse->nTab - 1; /* Cursor number to use */ + int iOk = sqlite3VdbeMakeLabel(pParse); /* jump here if parent key found */ + + sqlite3VdbeVerifyAbortable(v, + (!pFKey->isDeferred + && !(pParse->db->flags & SQLITE_DeferFKs) + && !pParse->pToplevel + && !pParse->isMultiWrite) ? OE_Abort : OE_Ignore); + + /* If nIncr is less than zero, then check at runtime if there are any + ** outstanding constraints to resolve. If there are not, there is no need + ** to check if deleting this row resolves any outstanding violations. + ** + ** Check if any of the key columns in the child table row are NULL. If + ** any are, then the constraint is considered satisfied. No need to + ** search for a matching row in the parent table. */ + if( nIncr<0 ){ + sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, iOk); + VdbeCoverage(v); + } + for(i=0; inCol; i++){ + int iReg = sqlite3TableColumnToStorage(pFKey->pFrom,aiCol[i]) + regData + 1; + sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk); VdbeCoverage(v); + } + + if( isIgnore==0 ){ + if( pIdx==0 ){ + /* If pIdx is NULL, then the parent key is the INTEGER PRIMARY KEY + ** column of the parent table (table pTab). */ + int iMustBeInt; /* Address of MustBeInt instruction */ + int regTemp = sqlite3GetTempReg(pParse); + + /* Invoke MustBeInt to coerce the child key value to an integer (i.e. + ** apply the affinity of the parent key). If this fails, then there + ** is no matching parent key. Before using MustBeInt, make a copy of + ** the value. Otherwise, the value inserted into the child key column + ** will have INTEGER affinity applied to it, which may not be correct. */ + sqlite3VdbeAddOp2(v, OP_SCopy, + sqlite3TableColumnToStorage(pFKey->pFrom,aiCol[0])+1+regData, regTemp); + iMustBeInt = sqlite3VdbeAddOp2(v, OP_MustBeInt, regTemp, 0); + VdbeCoverage(v); + + /* If the parent table is the same as the child table, and we are about + ** to increment the constraint-counter (i.e. this is an INSERT operation), + ** then check if the row being inserted matches itself. If so, do not + ** increment the constraint-counter. */ + if( pTab==pFKey->pFrom && nIncr==1 ){ + sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp); VdbeCoverage(v); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); + } + + sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead); + sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp); VdbeCoverage(v); + sqlite3VdbeGoto(v, iOk); + sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); + sqlite3VdbeJumpHere(v, iMustBeInt); + sqlite3ReleaseTempReg(pParse, regTemp); + }else{ + int nCol = pFKey->nCol; + int regTemp = sqlite3GetTempRange(pParse, nCol); + + sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIdx); + for(i=0; ipFrom, aiCol[i])+1+regData, + regTemp+i); + } + + /* If the parent table is the same as the child table, and we are about + ** to increment the constraint-counter (i.e. this is an INSERT operation), + ** then check if the row being inserted matches itself. If so, do not + ** increment the constraint-counter. + ** + ** If any of the parent-key values are NULL, then the row cannot match + ** itself. So set JUMPIFNULL to make sure we do the OP_Found if any + ** of the parent-key values are NULL (at this point it is known that + ** none of the child key values are). + */ + if( pTab==pFKey->pFrom && nIncr==1 ){ + int iJump = sqlite3VdbeCurrentAddr(v) + nCol + 1; + for(i=0; ipFrom,aiCol[i]) + +1+regData; + int iParent = 1+regData; + iParent += sqlite3TableColumnToStorage(pIdx->pTable, + pIdx->aiColumn[i]); + assert( pIdx->aiColumn[i]>=0 ); + assert( aiCol[i]!=pTab->iPKey ); + if( pIdx->aiColumn[i]==pTab->iPKey ){ + /* The parent key is a composite key that includes the IPK column */ + iParent = regData; + } + sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent); VdbeCoverage(v); + sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL); + } + sqlite3VdbeGoto(v, iOk); + } + + sqlite3VdbeAddOp4(v, OP_Affinity, regTemp, nCol, 0, + sqlite3IndexAffinityStr(pParse->db,pIdx), nCol); + sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regTemp, nCol); + VdbeCoverage(v); + sqlite3ReleaseTempRange(pParse, regTemp, nCol); + } + } + + if( !pFKey->isDeferred && !(pParse->db->flags & SQLITE_DeferFKs) + && !pParse->pToplevel + && !pParse->isMultiWrite + ){ + /* Special case: If this is an INSERT statement that will insert exactly + ** one row into the table, raise a constraint immediately instead of + ** incrementing a counter. This is necessary as the VM code is being + ** generated for will not open a statement transaction. */ + assert( nIncr==1 ); + sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY, + OE_Abort, 0, P4_STATIC, P5_ConstraintFK); + }else{ + if( nIncr>0 && pFKey->isDeferred==0 ){ + sqlite3MayAbort(pParse); + } + sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr); + } + + sqlite3VdbeResolveLabel(v, iOk); + sqlite3VdbeAddOp1(v, OP_Close, iCur); +} + + +/* +** Return an Expr object that refers to a memory register corresponding +** to column iCol of table pTab. +** +** regBase is the first of an array of register that contains the data +** for pTab. regBase itself holds the rowid. regBase+1 holds the first +** column. regBase+2 holds the second column, and so forth. +*/ +static Expr *exprTableRegister( + Parse *pParse, /* Parsing and code generating context */ + Table *pTab, /* The table whose content is at r[regBase]... */ + int regBase, /* Contents of table pTab */ + i16 iCol /* Which column of pTab is desired */ +){ + Expr *pExpr; + Column *pCol; + const char *zColl; + sqlite3 *db = pParse->db; + + pExpr = sqlite3Expr(db, TK_REGISTER, 0); + if( pExpr ){ + if( iCol>=0 && iCol!=pTab->iPKey ){ + pCol = &pTab->aCol[iCol]; + pExpr->iTable = regBase + sqlite3TableColumnToStorage(pTab,iCol) + 1; + pExpr->affExpr = pCol->affinity; + zColl = sqlite3ColumnColl(pCol); + if( zColl==0 ) zColl = db->pDfltColl->zName; + pExpr = sqlite3ExprAddCollateString(pParse, pExpr, zColl); + }else{ + pExpr->iTable = regBase; + pExpr->affExpr = SQLITE_AFF_INTEGER; + } + } + return pExpr; +} + +/* +** Return an Expr object that refers to column iCol of table pTab which +** has cursor iCur. +*/ +static Expr *exprTableColumn( + sqlite3 *db, /* The database connection */ + Table *pTab, /* The table whose column is desired */ + int iCursor, /* The open cursor on the table */ + i16 iCol /* The column that is wanted */ +){ + Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0); + if( pExpr ){ + assert( ExprUseYTab(pExpr) ); + pExpr->y.pTab = pTab; + pExpr->iTable = iCursor; + pExpr->iColumn = iCol; + } + return pExpr; +} + +/* +** This function is called to generate code executed when a row is deleted +** from the parent table of foreign key constraint pFKey and, if pFKey is +** deferred, when a row is inserted into the same table. When generating +** code for an SQL UPDATE operation, this function may be called twice - +** once to "delete" the old row and once to "insert" the new row. +** +** Parameter nIncr is passed -1 when inserting a row (as this may decrease +** the number of FK violations in the db) or +1 when deleting one (as this +** may increase the number of FK constraint problems). +** +** The code generated by this function scans through the rows in the child +** table that correspond to the parent table row being deleted or inserted. +** For each child row found, one of the following actions is taken: +** +** Operation | FK type | Action taken +** -------------------------------------------------------------------------- +** DELETE immediate Increment the "immediate constraint counter". +** +** INSERT immediate Decrement the "immediate constraint counter". +** +** DELETE deferred Increment the "deferred constraint counter". +** +** INSERT deferred Decrement the "deferred constraint counter". +** +** These operations are identified in the comment at the top of this file +** (fkey.c) as "I.2" and "D.2". +*/ +static void fkScanChildren( + Parse *pParse, /* Parse context */ + SrcList *pSrc, /* The child table to be scanned */ + Table *pTab, /* The parent table */ + Index *pIdx, /* Index on parent covering the foreign key */ + FKey *pFKey, /* The foreign key linking pSrc to pTab */ + int *aiCol, /* Map from pIdx cols to child table cols */ + int regData, /* Parent row data starts here */ + int nIncr /* Amount to increment deferred counter by */ +){ + sqlite3 *db = pParse->db; /* Database handle */ + int i; /* Iterator variable */ + Expr *pWhere = 0; /* WHERE clause to scan with */ + NameContext sNameContext; /* Context used to resolve WHERE clause */ + WhereInfo *pWInfo; /* Context used by sqlite3WhereXXX() */ + int iFkIfZero = 0; /* Address of OP_FkIfZero */ + Vdbe *v = sqlite3GetVdbe(pParse); + + assert( pIdx==0 || pIdx->pTable==pTab ); + assert( pIdx==0 || pIdx->nKeyCol==pFKey->nCol ); + assert( pIdx!=0 || pFKey->nCol==1 ); + assert( pIdx!=0 || HasRowid(pTab) ); + + if( nIncr<0 ){ + iFkIfZero = sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, 0); + VdbeCoverage(v); + } + + /* Create an Expr object representing an SQL expression like: + ** + ** = AND = ... + ** + ** The collation sequence used for the comparison should be that of + ** the parent key columns. The affinity of the parent key column should + ** be applied to each child key value before the comparison takes place. + */ + for(i=0; inCol; i++){ + Expr *pLeft; /* Value from parent table row */ + Expr *pRight; /* Column ref to child table */ + Expr *pEq; /* Expression (pLeft = pRight) */ + i16 iCol; /* Index of column in child table */ + const char *zCol; /* Name of column in child table */ + + iCol = pIdx ? pIdx->aiColumn[i] : -1; + pLeft = exprTableRegister(pParse, pTab, regData, iCol); + iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom; + assert( iCol>=0 ); + zCol = pFKey->pFrom->aCol[iCol].zCnName; + pRight = sqlite3Expr(db, TK_ID, zCol); + pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight); + pWhere = sqlite3ExprAnd(pParse, pWhere, pEq); + } + + /* If the child table is the same as the parent table, then add terms + ** to the WHERE clause that prevent this entry from being scanned. + ** The added WHERE clause terms are like this: + ** + ** $current_rowid!=rowid + ** NOT( $current_a==a AND $current_b==b AND ... ) + ** + ** The first form is used for rowid tables. The second form is used + ** for WITHOUT ROWID tables. In the second form, the *parent* key is + ** (a,b,...). Either the parent or primary key could be used to + ** uniquely identify the current row, but the parent key is more convenient + ** as the required values have already been loaded into registers + ** by the caller. + */ + if( pTab==pFKey->pFrom && nIncr>0 ){ + Expr *pNe; /* Expression (pLeft != pRight) */ + Expr *pLeft; /* Value from parent table row */ + Expr *pRight; /* Column ref to child table */ + if( HasRowid(pTab) ){ + pLeft = exprTableRegister(pParse, pTab, regData, -1); + pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, -1); + pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight); + }else{ + Expr *pEq, *pAll = 0; + assert( pIdx!=0 ); + for(i=0; inKeyCol; i++){ + i16 iCol = pIdx->aiColumn[i]; + assert( iCol>=0 ); + pLeft = exprTableRegister(pParse, pTab, regData, iCol); + pRight = sqlite3Expr(db, TK_ID, pTab->aCol[iCol].zCnName); + pEq = sqlite3PExpr(pParse, TK_IS, pLeft, pRight); + pAll = sqlite3ExprAnd(pParse, pAll, pEq); + } + pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0); + } + pWhere = sqlite3ExprAnd(pParse, pWhere, pNe); + } + + /* Resolve the references in the WHERE clause. */ + memset(&sNameContext, 0, sizeof(NameContext)); + sNameContext.pSrcList = pSrc; + sNameContext.pParse = pParse; + sqlite3ResolveExprNames(&sNameContext, pWhere); + + /* Create VDBE to loop through the entries in pSrc that match the WHERE + ** clause. For each row found, increment either the deferred or immediate + ** foreign key constraint counter. */ + if( pParse->nErr==0 ){ + pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0, 0); + sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr); + if( pWInfo ){ + sqlite3WhereEnd(pWInfo); + } + } + + /* Clean up the WHERE clause constructed above. */ + sqlite3ExprDelete(db, pWhere); + if( iFkIfZero ){ + sqlite3VdbeJumpHereOrPopInst(v, iFkIfZero); + } +} + +/* +** This function returns a linked list of FKey objects (connected by +** FKey.pNextTo) holding all children of table pTab. For example, +** given the following schema: +** +** CREATE TABLE t1(a PRIMARY KEY); +** CREATE TABLE t2(b REFERENCES t1(a); +** +** Calling this function with table "t1" as an argument returns a pointer +** to the FKey structure representing the foreign key constraint on table +** "t2". Calling this function with "t2" as the argument would return a +** NULL pointer (as there are no FK constraints for which t2 is the parent +** table). +*/ +SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *pTab){ + return (FKey *)sqlite3HashFind(&pTab->pSchema->fkeyHash, pTab->zName); +} + +/* +** The second argument is a Trigger structure allocated by the +** fkActionTrigger() routine. This function deletes the Trigger structure +** and all of its sub-components. +** +** The Trigger structure or any of its sub-components may be allocated from +** the lookaside buffer belonging to database handle dbMem. +*/ +static void fkTriggerDelete(sqlite3 *dbMem, Trigger *p){ + if( p ){ + TriggerStep *pStep = p->step_list; + sqlite3SrcListDelete(dbMem, pStep->pSrc); + sqlite3ExprDelete(dbMem, pStep->pWhere); + sqlite3ExprListDelete(dbMem, pStep->pExprList); + sqlite3SelectDelete(dbMem, pStep->pSelect); + sqlite3ExprDelete(dbMem, p->pWhen); + sqlite3DbFree(dbMem, p); + } +} + +/* +** Clear the apTrigger[] cache of CASCADE triggers for all foreign keys +** in a particular database. This needs to happen when the schema +** changes. +*/ +SQLITE_PRIVATE void sqlite3FkClearTriggerCache(sqlite3 *db, int iDb){ + HashElem *k; + Hash *pHash = &db->aDb[iDb].pSchema->tblHash; + for(k=sqliteHashFirst(pHash); k; k=sqliteHashNext(k)){ + Table *pTab = sqliteHashData(k); + FKey *pFKey; + if( !IsOrdinaryTable(pTab) ) continue; + for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){ + fkTriggerDelete(db, pFKey->apTrigger[0]); pFKey->apTrigger[0] = 0; + fkTriggerDelete(db, pFKey->apTrigger[1]); pFKey->apTrigger[1] = 0; + } + } +} + +/* +** This function is called to generate code that runs when table pTab is +** being dropped from the database. The SrcList passed as the second argument +** to this function contains a single entry guaranteed to resolve to +** table pTab. +** +** Normally, no code is required. However, if either +** +** (a) The table is the parent table of a FK constraint, or +** (b) The table is the child table of a deferred FK constraint and it is +** determined at runtime that there are outstanding deferred FK +** constraint violations in the database, +** +** then the equivalent of "DELETE FROM " is executed before dropping +** the table from the database. Triggers are disabled while running this +** DELETE, but foreign key actions are not. +*/ +SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){ + sqlite3 *db = pParse->db; + if( (db->flags&SQLITE_ForeignKeys) && IsOrdinaryTable(pTab) ){ + int iSkip = 0; + Vdbe *v = sqlite3GetVdbe(pParse); + + assert( v ); /* VDBE has already been allocated */ + assert( IsOrdinaryTable(pTab) ); + if( sqlite3FkReferences(pTab)==0 ){ + /* Search for a deferred foreign key constraint for which this table + ** is the child table. If one cannot be found, return without + ** generating any VDBE code. If one can be found, then jump over + ** the entire DELETE if there are no outstanding deferred constraints + ** when this statement is run. */ + FKey *p; + for(p=pTab->u.tab.pFKey; p; p=p->pNextFrom){ + if( p->isDeferred || (db->flags & SQLITE_DeferFKs) ) break; + } + if( !p ) return; + iSkip = sqlite3VdbeMakeLabel(pParse); + sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip); VdbeCoverage(v); + } + + pParse->disableTriggers = 1; + sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0, 0, 0); + pParse->disableTriggers = 0; + + /* If the DELETE has generated immediate foreign key constraint + ** violations, halt the VDBE and return an error at this point, before + ** any modifications to the schema are made. This is because statement + ** transactions are not able to rollback schema changes. + ** + ** If the SQLITE_DeferFKs flag is set, then this is not required, as + ** the statement transaction will not be rolled back even if FK + ** constraints are violated. + */ + if( (db->flags & SQLITE_DeferFKs)==0 ){ + sqlite3VdbeVerifyAbortable(v, OE_Abort); + sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); + sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY, + OE_Abort, 0, P4_STATIC, P5_ConstraintFK); + } + + if( iSkip ){ + sqlite3VdbeResolveLabel(v, iSkip); + } + } +} + + +/* +** The second argument points to an FKey object representing a foreign key +** for which pTab is the child table. An UPDATE statement against pTab +** is currently being processed. For each column of the table that is +** actually updated, the corresponding element in the aChange[] array +** is zero or greater (if a column is unmodified the corresponding element +** is set to -1). If the rowid column is modified by the UPDATE statement +** the bChngRowid argument is non-zero. +** +** This function returns true if any of the columns that are part of the +** child key for FK constraint *p are modified. +*/ +static int fkChildIsModified( + Table *pTab, /* Table being updated */ + FKey *p, /* Foreign key for which pTab is the child */ + int *aChange, /* Array indicating modified columns */ + int bChngRowid /* True if rowid is modified by this update */ +){ + int i; + for(i=0; inCol; i++){ + int iChildKey = p->aCol[i].iFrom; + if( aChange[iChildKey]>=0 ) return 1; + if( iChildKey==pTab->iPKey && bChngRowid ) return 1; + } + return 0; +} + +/* +** The second argument points to an FKey object representing a foreign key +** for which pTab is the parent table. An UPDATE statement against pTab +** is currently being processed. For each column of the table that is +** actually updated, the corresponding element in the aChange[] array +** is zero or greater (if a column is unmodified the corresponding element +** is set to -1). If the rowid column is modified by the UPDATE statement +** the bChngRowid argument is non-zero. +** +** This function returns true if any of the columns that are part of the +** parent key for FK constraint *p are modified. +*/ +static int fkParentIsModified( + Table *pTab, + FKey *p, + int *aChange, + int bChngRowid +){ + int i; + for(i=0; inCol; i++){ + char *zKey = p->aCol[i].zCol; + int iKey; + for(iKey=0; iKeynCol; iKey++){ + if( aChange[iKey]>=0 || (iKey==pTab->iPKey && bChngRowid) ){ + Column *pCol = &pTab->aCol[iKey]; + if( zKey ){ + if( 0==sqlite3StrICmp(pCol->zCnName, zKey) ) return 1; + }else if( pCol->colFlags & COLFLAG_PRIMKEY ){ + return 1; + } + } + } + } + return 0; +} + +/* +** Return true if the parser passed as the first argument is being +** used to code a trigger that is really a "SET NULL" action belonging +** to trigger pFKey. +*/ +static int isSetNullAction(Parse *pParse, FKey *pFKey){ + Parse *pTop = sqlite3ParseToplevel(pParse); + if( pTop->pTriggerPrg ){ + Trigger *p = pTop->pTriggerPrg->pTrigger; + if( (p==pFKey->apTrigger[0] && pFKey->aAction[0]==OE_SetNull) + || (p==pFKey->apTrigger[1] && pFKey->aAction[1]==OE_SetNull) + ){ + assert( (pTop->db->flags & SQLITE_FkNoAction)==0 ); + return 1; + } + } + return 0; +} + +/* +** This function is called when inserting, deleting or updating a row of +** table pTab to generate VDBE code to perform foreign key constraint +** processing for the operation. +** +** For a DELETE operation, parameter regOld is passed the index of the +** first register in an array of (pTab->nCol+1) registers containing the +** rowid of the row being deleted, followed by each of the column values +** of the row being deleted, from left to right. Parameter regNew is passed +** zero in this case. +** +** For an INSERT operation, regOld is passed zero and regNew is passed the +** first register of an array of (pTab->nCol+1) registers containing the new +** row data. +** +** For an UPDATE operation, this function is called twice. Once before +** the original record is deleted from the table using the calling convention +** described for DELETE. Then again after the original record is deleted +** but before the new record is inserted using the INSERT convention. +*/ +SQLITE_PRIVATE void sqlite3FkCheck( + Parse *pParse, /* Parse context */ + Table *pTab, /* Row is being deleted from this table */ + int regOld, /* Previous row data is stored here */ + int regNew, /* New row data is stored here */ + int *aChange, /* Array indicating UPDATEd columns (or 0) */ + int bChngRowid /* True if rowid is UPDATEd */ +){ + sqlite3 *db = pParse->db; /* Database handle */ + FKey *pFKey; /* Used to iterate through FKs */ + int iDb; /* Index of database containing pTab */ + const char *zDb; /* Name of database containing pTab */ + int isIgnoreErrors = pParse->disableTriggers; + + /* Exactly one of regOld and regNew should be non-zero. */ + assert( (regOld==0)!=(regNew==0) ); + + /* If foreign-keys are disabled, this function is a no-op. */ + if( (db->flags&SQLITE_ForeignKeys)==0 ) return; + if( !IsOrdinaryTable(pTab) ) return; + + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iDb>=00 && iDbnDb ); + zDb = db->aDb[iDb].zDbSName; + + /* Loop through all the foreign key constraints for which pTab is the + ** child table (the table that the foreign key definition is part of). */ + for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){ + Table *pTo; /* Parent table of foreign key pFKey */ + Index *pIdx = 0; /* Index on key columns in pTo */ + int *aiFree = 0; + int *aiCol; + int iCol; + int i; + int bIgnore = 0; + + if( aChange + && sqlite3_stricmp(pTab->zName, pFKey->zTo)!=0 + && fkChildIsModified(pTab, pFKey, aChange, bChngRowid)==0 + ){ + continue; + } + + /* Find the parent table of this foreign key. Also find a unique index + ** on the parent key columns in the parent table. If either of these + ** schema items cannot be located, set an error in pParse and return + ** early. */ + if( pParse->disableTriggers ){ + pTo = sqlite3FindTable(db, pFKey->zTo, zDb); + }else{ + pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo, zDb); + } + if( !pTo || sqlite3FkLocateIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){ + assert( isIgnoreErrors==0 || (regOld!=0 && regNew==0) ); + if( !isIgnoreErrors || db->mallocFailed ) return; + if( pTo==0 ){ + /* If isIgnoreErrors is true, then a table is being dropped. In this + ** case SQLite runs a "DELETE FROM xxx" on the table being dropped + ** before actually dropping it in order to check FK constraints. + ** If the parent table of an FK constraint on the current table is + ** missing, behave as if it is empty. i.e. decrement the relevant + ** FK counter for each row of the current table with non-NULL keys. + */ + Vdbe *v = sqlite3GetVdbe(pParse); + int iJump = sqlite3VdbeCurrentAddr(v) + pFKey->nCol + 1; + for(i=0; inCol; i++){ + int iFromCol, iReg; + iFromCol = pFKey->aCol[i].iFrom; + iReg = sqlite3TableColumnToStorage(pFKey->pFrom,iFromCol) + regOld+1; + sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iJump); VdbeCoverage(v); + } + sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, -1); + } + continue; + } + assert( pFKey->nCol==1 || (aiFree && pIdx) ); + + if( aiFree ){ + aiCol = aiFree; + }else{ + iCol = pFKey->aCol[0].iFrom; + aiCol = &iCol; + } + for(i=0; inCol; i++){ + if( aiCol[i]==pTab->iPKey ){ + aiCol[i] = -1; + } + assert( pIdx==0 || pIdx->aiColumn[i]>=0 ); +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Request permission to read the parent key columns. If the + ** authorization callback returns SQLITE_IGNORE, behave as if any + ** values read from the parent table are NULL. */ + if( db->xAuth ){ + int rcauth; + char *zCol = pTo->aCol[pIdx ? pIdx->aiColumn[i] : pTo->iPKey].zCnName; + rcauth = sqlite3AuthReadCol(pParse, pTo->zName, zCol, iDb); + bIgnore = (rcauth==SQLITE_IGNORE); + } +#endif + } + + /* Take a shared-cache advisory read-lock on the parent table. Allocate + ** a cursor to use to search the unique index on the parent key columns + ** in the parent table. */ + sqlite3TableLock(pParse, iDb, pTo->tnum, 0, pTo->zName); + pParse->nTab++; + + if( regOld!=0 ){ + /* A row is being removed from the child table. Search for the parent. + ** If the parent does not exist, removing the child row resolves an + ** outstanding foreign key constraint violation. */ + fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regOld, -1, bIgnore); + } + if( regNew!=0 && !isSetNullAction(pParse, pFKey) ){ + /* A row is being added to the child table. If a parent row cannot + ** be found, adding the child row has violated the FK constraint. + ** + ** If this operation is being performed as part of a trigger program + ** that is actually a "SET NULL" action belonging to this very + ** foreign key, then omit this scan altogether. As all child key + ** values are guaranteed to be NULL, it is not possible for adding + ** this row to cause an FK violation. */ + fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regNew, +1, bIgnore); + } + + sqlite3DbFree(db, aiFree); + } + + /* Loop through all the foreign key constraints that refer to this table. + ** (the "child" constraints) */ + for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){ + Index *pIdx = 0; /* Foreign key index for pFKey */ + SrcList *pSrc; + int *aiCol = 0; + + if( aChange && fkParentIsModified(pTab, pFKey, aChange, bChngRowid)==0 ){ + continue; + } + + if( !pFKey->isDeferred && !(db->flags & SQLITE_DeferFKs) + && !pParse->pToplevel && !pParse->isMultiWrite + ){ + assert( regOld==0 && regNew!=0 ); + /* Inserting a single row into a parent table cannot cause (or fix) + ** an immediate foreign key violation. So do nothing in this case. */ + continue; + } + + if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ){ + if( !isIgnoreErrors || db->mallocFailed ) return; + continue; + } + assert( aiCol || pFKey->nCol==1 ); + + /* Create a SrcList structure containing the child table. We need the + ** child table as a SrcList for sqlite3WhereBegin() */ + pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); + if( pSrc ){ + SrcItem *pItem = pSrc->a; + pItem->pSTab = pFKey->pFrom; + pItem->zName = pFKey->pFrom->zName; + pItem->pSTab->nTabRef++; + pItem->iCursor = pParse->nTab++; + + if( regNew!=0 ){ + fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1); + } + if( regOld!=0 ){ + int eAction = pFKey->aAction[aChange!=0]; + if( (db->flags & SQLITE_FkNoAction) ) eAction = OE_None; + + fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regOld, 1); + /* If this is a deferred FK constraint, or a CASCADE or SET NULL + ** action applies, then any foreign key violations caused by + ** removing the parent key will be rectified by the action trigger. + ** So do not set the "may-abort" flag in this case. + ** + ** Note 1: If the FK is declared "ON UPDATE CASCADE", then the + ** may-abort flag will eventually be set on this statement anyway + ** (when this function is called as part of processing the UPDATE + ** within the action trigger). + ** + ** Note 2: At first glance it may seem like SQLite could simply omit + ** all OP_FkCounter related scans when either CASCADE or SET NULL + ** applies. The trouble starts if the CASCADE or SET NULL action + ** trigger causes other triggers or action rules attached to the + ** child table to fire. In these cases the fk constraint counters + ** might be set incorrectly if any OP_FkCounter related scans are + ** omitted. */ + if( !pFKey->isDeferred && eAction!=OE_Cascade && eAction!=OE_SetNull ){ + sqlite3MayAbort(pParse); + } + } + pItem->zName = 0; + sqlite3SrcListDelete(db, pSrc); + } + sqlite3DbFree(db, aiCol); + } +} + +#define COLUMN_MASK(x) (((x)>31) ? 0xffffffff : ((u32)1<<(x))) + +/* +** This function is called before generating code to update or delete a +** row contained in table pTab. +*/ +SQLITE_PRIVATE u32 sqlite3FkOldmask( + Parse *pParse, /* Parse context */ + Table *pTab /* Table being modified */ +){ + u32 mask = 0; + if( pParse->db->flags&SQLITE_ForeignKeys && IsOrdinaryTable(pTab) ){ + FKey *p; + int i; + for(p=pTab->u.tab.pFKey; p; p=p->pNextFrom){ + for(i=0; inCol; i++) mask |= COLUMN_MASK(p->aCol[i].iFrom); + } + for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ + Index *pIdx = 0; + sqlite3FkLocateIndex(pParse, pTab, p, &pIdx, 0); + if( pIdx ){ + for(i=0; inKeyCol; i++){ + assert( pIdx->aiColumn[i]>=0 ); + mask |= COLUMN_MASK(pIdx->aiColumn[i]); + } + } + } + } + return mask; +} + + +/* +** This function is called before generating code to update or delete a +** row contained in table pTab. If the operation is a DELETE, then +** parameter aChange is passed a NULL value. For an UPDATE, aChange points +** to an array of size N, where N is the number of columns in table pTab. +** If the i'th column is not modified by the UPDATE, then the corresponding +** entry in the aChange[] array is set to -1. If the column is modified, +** the value is 0 or greater. Parameter chngRowid is set to true if the +** UPDATE statement modifies the rowid fields of the table. +** +** If any foreign key processing will be required, this function returns +** non-zero. If there is no foreign key related processing, this function +** returns zero. +** +** For an UPDATE, this function returns 2 if: +** +** * There are any FKs for which pTab is the child and the parent table +** and any FK processing at all is required (even of a different FK), or +** +** * the UPDATE modifies one or more parent keys for which the action is +** not "NO ACTION" (i.e. is CASCADE, SET DEFAULT or SET NULL). +** +** Or, assuming some other foreign key processing is required, 1. +*/ +SQLITE_PRIVATE int sqlite3FkRequired( + Parse *pParse, /* Parse context */ + Table *pTab, /* Table being modified */ + int *aChange, /* Non-NULL for UPDATE operations */ + int chngRowid /* True for UPDATE that affects rowid */ +){ + int eRet = 1; /* Value to return if bHaveFK is true */ + int bHaveFK = 0; /* If FK processing is required */ + if( pParse->db->flags&SQLITE_ForeignKeys && IsOrdinaryTable(pTab) ){ + if( !aChange ){ + /* A DELETE operation. Foreign key processing is required if the + ** table in question is either the child or parent table for any + ** foreign key constraint. */ + bHaveFK = (sqlite3FkReferences(pTab) || pTab->u.tab.pFKey); + }else{ + /* This is an UPDATE. Foreign key processing is only required if the + ** operation modifies one or more child or parent key columns. */ + FKey *p; + + /* Check if any child key columns are being modified. */ + for(p=pTab->u.tab.pFKey; p; p=p->pNextFrom){ + if( fkChildIsModified(pTab, p, aChange, chngRowid) ){ + if( 0==sqlite3_stricmp(pTab->zName, p->zTo) ) eRet = 2; + bHaveFK = 1; + } + } + + /* Check if any parent key columns are being modified. */ + for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ + if( fkParentIsModified(pTab, p, aChange, chngRowid) ){ + if( (pParse->db->flags & SQLITE_FkNoAction)==0 + && p->aAction[1]!=OE_None + ){ + return 2; + } + bHaveFK = 1; + } + } + } + } + return bHaveFK ? eRet : 0; +} + +/* +** This function is called when an UPDATE or DELETE operation is being +** compiled on table pTab, which is the parent table of foreign-key pFKey. +** If the current operation is an UPDATE, then the pChanges parameter is +** passed a pointer to the list of columns being modified. If it is a +** DELETE, pChanges is passed a NULL pointer. +** +** It returns a pointer to a Trigger structure containing a trigger +** equivalent to the ON UPDATE or ON DELETE action specified by pFKey. +** If the action is "NO ACTION" then a NULL pointer is returned (these actions +** require no special handling by the triggers sub-system, code for them is +** created by fkScanChildren()). +** +** For example, if pFKey is the foreign key and pTab is table "p" in +** the following schema: +** +** CREATE TABLE p(pk PRIMARY KEY); +** CREATE TABLE c(ck REFERENCES p ON DELETE CASCADE); +** +** then the returned trigger structure is equivalent to: +** +** CREATE TRIGGER ... DELETE ON p BEGIN +** DELETE FROM c WHERE ck = old.pk; +** END; +** +** The returned pointer is cached as part of the foreign key object. It +** is eventually freed along with the rest of the foreign key object by +** sqlite3FkDelete(). +*/ +static Trigger *fkActionTrigger( + Parse *pParse, /* Parse context */ + Table *pTab, /* Table being updated or deleted from */ + FKey *pFKey, /* Foreign key to get action for */ + ExprList *pChanges /* Change-list for UPDATE, NULL for DELETE */ +){ + sqlite3 *db = pParse->db; /* Database handle */ + int action; /* One of OE_None, OE_Cascade etc. */ + Trigger *pTrigger; /* Trigger definition to return */ + int iAction = (pChanges!=0); /* 1 for UPDATE, 0 for DELETE */ + + action = pFKey->aAction[iAction]; + if( (db->flags & SQLITE_FkNoAction) ) action = OE_None; + if( action==OE_Restrict && (db->flags & SQLITE_DeferFKs) ){ + return 0; + } + pTrigger = pFKey->apTrigger[iAction]; + + if( action!=OE_None && !pTrigger ){ + char const *zFrom; /* Name of child table */ + int nFrom; /* Length in bytes of zFrom */ + Index *pIdx = 0; /* Parent key index for this FK */ + int *aiCol = 0; /* child table cols -> parent key cols */ + TriggerStep *pStep = 0; /* First (only) step of trigger program */ + Expr *pWhere = 0; /* WHERE clause of trigger step */ + ExprList *pList = 0; /* Changes list if ON UPDATE CASCADE */ + Select *pSelect = 0; /* If RESTRICT, "SELECT RAISE(...)" */ + int i; /* Iterator variable */ + Expr *pWhen = 0; /* WHEN clause for the trigger */ + + if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ) return 0; + assert( aiCol || pFKey->nCol==1 ); + + for(i=0; inCol; i++){ + Token tOld = { "old", 3 }; /* Literal "old" token */ + Token tNew = { "new", 3 }; /* Literal "new" token */ + Token tFromCol; /* Name of column in child table */ + Token tToCol; /* Name of column in parent table */ + int iFromCol; /* Idx of column in child table */ + Expr *pEq; /* tFromCol = OLD.tToCol */ + + iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom; + assert( iFromCol>=0 ); + assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKeynCol) ); + assert( pIdx==0 || pIdx->aiColumn[i]>=0 ); + sqlite3TokenInit(&tToCol, + pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zCnName); + sqlite3TokenInit(&tFromCol, pFKey->pFrom->aCol[iFromCol].zCnName); + + /* Create the expression "OLD.zToCol = zFromCol". It is important + ** that the "OLD.zToCol" term is on the LHS of the = operator, so + ** that the affinity and collation sequence associated with the + ** parent table are used for the comparison. */ + pEq = sqlite3PExpr(pParse, TK_EQ, + sqlite3PExpr(pParse, TK_DOT, + sqlite3ExprAlloc(db, TK_ID, &tOld, 0), + sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)), + sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0) + ); + pWhere = sqlite3ExprAnd(pParse, pWhere, pEq); + + /* For ON UPDATE, construct the next term of the WHEN clause. + ** The final WHEN clause will be like this: + ** + ** WHEN NOT(old.col1 IS new.col1 AND ... AND old.colN IS new.colN) + */ + if( pChanges ){ + pEq = sqlite3PExpr(pParse, TK_IS, + sqlite3PExpr(pParse, TK_DOT, + sqlite3ExprAlloc(db, TK_ID, &tOld, 0), + sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)), + sqlite3PExpr(pParse, TK_DOT, + sqlite3ExprAlloc(db, TK_ID, &tNew, 0), + sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)) + ); + pWhen = sqlite3ExprAnd(pParse, pWhen, pEq); + } + + if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){ + Expr *pNew; + if( action==OE_Cascade ){ + pNew = sqlite3PExpr(pParse, TK_DOT, + sqlite3ExprAlloc(db, TK_ID, &tNew, 0), + sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)); + }else if( action==OE_SetDflt ){ + Column *pCol = pFKey->pFrom->aCol + iFromCol; + Expr *pDflt; + if( pCol->colFlags & COLFLAG_GENERATED ){ + testcase( pCol->colFlags & COLFLAG_VIRTUAL ); + testcase( pCol->colFlags & COLFLAG_STORED ); + pDflt = 0; + }else{ + pDflt = sqlite3ColumnExpr(pFKey->pFrom, pCol); + } + if( pDflt ){ + pNew = sqlite3ExprDup(db, pDflt, 0); + }else{ + pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0); + } + }else{ + pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0); + } + pList = sqlite3ExprListAppend(pParse, pList, pNew); + sqlite3ExprListSetName(pParse, pList, &tFromCol, 0); + } + } + sqlite3DbFree(db, aiCol); + + zFrom = pFKey->pFrom->zName; + nFrom = sqlite3Strlen30(zFrom); + + if( action==OE_Restrict ){ + SrcList *pSrc; + Expr *pRaise; + + pRaise = sqlite3Expr(db, TK_STRING, "FOREIGN KEY constraint failed"), + pRaise = sqlite3PExpr(pParse, TK_RAISE, pRaise, 0); + if( pRaise ){ + pRaise->affExpr = OE_Abort; + } + pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); + if( pSrc ){ + SrcItem *pItem = &pSrc->a[0]; + pItem->zName = sqlite3DbStrDup(db, zFrom); + pItem->fg.fixedSchema = 1; + pItem->u4.pSchema = pTab->pSchema; + } + pSelect = sqlite3SelectNew(pParse, + sqlite3ExprListAppend(pParse, 0, pRaise), + pSrc, + pWhere, + 0, 0, 0, 0, 0 + ); + pWhere = 0; + } + + /* Disable lookaside memory allocation */ + DisableLookaside; + + pTrigger = (Trigger *)sqlite3DbMallocZero(db, + sizeof(Trigger) + /* struct Trigger */ + sizeof(TriggerStep) /* Single step in trigger program */ + ); + if( pTrigger ){ + pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1]; + pStep->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); + if( pStep->pSrc ){ + SrcItem *pItem = &pStep->pSrc->a[0]; + pItem->zName = sqlite3DbStrNDup(db, zFrom, nFrom); + pItem->u4.pSchema = pTab->pSchema; + pItem->fg.fixedSchema = 1; + } + pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); + pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE); + pStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); + if( pWhen ){ + pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0); + pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); + } + } + + /* Re-enable the lookaside buffer, if it was disabled earlier. */ + EnableLookaside; + + sqlite3ExprDelete(db, pWhere); + sqlite3ExprDelete(db, pWhen); + sqlite3ExprListDelete(db, pList); + sqlite3SelectDelete(db, pSelect); + if( db->mallocFailed==1 ){ + fkTriggerDelete(db, pTrigger); + return 0; + } + assert( pStep!=0 ); + assert( pTrigger!=0 ); + + switch( action ){ + case OE_Restrict: + pStep->op = TK_SELECT; + break; + case OE_Cascade: + if( !pChanges ){ + pStep->op = TK_DELETE; + break; + } + /* no break */ deliberate_fall_through + default: + pStep->op = TK_UPDATE; + } + pStep->pTrig = pTrigger; + pTrigger->pSchema = pTab->pSchema; + pTrigger->pTabSchema = pTab->pSchema; + pFKey->apTrigger[iAction] = pTrigger; + pTrigger->op = (pChanges ? TK_UPDATE : TK_DELETE); + } + + return pTrigger; +} + +/* +** This function is called when deleting or updating a row to implement +** any required CASCADE, SET NULL or SET DEFAULT actions. +*/ +SQLITE_PRIVATE void sqlite3FkActions( + Parse *pParse, /* Parse context */ + Table *pTab, /* Table being updated or deleted from */ + ExprList *pChanges, /* Change-list for UPDATE, NULL for DELETE */ + int regOld, /* Address of array containing old row */ + int *aChange, /* Array indicating UPDATEd columns (or 0) */ + int bChngRowid /* True if rowid is UPDATEd */ +){ + /* If foreign-key support is enabled, iterate through all FKs that + ** refer to table pTab. If there is an action associated with the FK + ** for this operation (either update or delete), invoke the associated + ** trigger sub-program. */ + if( pParse->db->flags&SQLITE_ForeignKeys ){ + FKey *pFKey; /* Iterator variable */ + for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){ + if( aChange==0 || fkParentIsModified(pTab, pFKey, aChange, bChngRowid) ){ + Trigger *pAct = fkActionTrigger(pParse, pTab, pFKey, pChanges); + if( pAct ){ + sqlite3CodeRowTriggerDirect(pParse, pAct, pTab, regOld, OE_Abort, 0); + } + } + } + } +} + +#endif /* ifndef SQLITE_OMIT_TRIGGER */ + +/* +** Free all memory associated with foreign key definitions attached to +** table pTab. Remove the deleted foreign keys from the Schema.fkeyHash +** hash table. +*/ +SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *db, Table *pTab){ + FKey *pFKey; /* Iterator variable */ + FKey *pNext; /* Copy of pFKey->pNextFrom */ + + assert( IsOrdinaryTable(pTab) ); + assert( db!=0 ); + for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pNext){ + assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) ); + + /* Remove the FK from the fkeyHash hash table. */ + if( db->pnBytesFreed==0 ){ + if( pFKey->pPrevTo ){ + pFKey->pPrevTo->pNextTo = pFKey->pNextTo; + }else{ + const char *z = (pFKey->pNextTo ? pFKey->pNextTo->zTo : pFKey->zTo); + sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, pFKey->pNextTo); + } + if( pFKey->pNextTo ){ + pFKey->pNextTo->pPrevTo = pFKey->pPrevTo; + } + } + + /* EV: R-30323-21917 Each foreign key constraint in SQLite is + ** classified as either immediate or deferred. + */ + assert( pFKey->isDeferred==0 || pFKey->isDeferred==1 ); + + /* Delete any triggers created to implement actions for this FK. */ +#ifndef SQLITE_OMIT_TRIGGER + fkTriggerDelete(db, pFKey->apTrigger[0]); + fkTriggerDelete(db, pFKey->apTrigger[1]); +#endif + + pNext = pFKey->pNextFrom; + sqlite3DbFree(db, pFKey); + } +} +#endif /* ifndef SQLITE_OMIT_FOREIGN_KEY */ + +/************** End of fkey.c ************************************************/ +/************** Begin file insert.c ******************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains C code routines that are called by the parser +** to handle INSERT statements in SQLite. +*/ +/* #include "sqliteInt.h" */ + +/* +** Generate code that will +** +** (1) acquire a lock for table pTab then +** (2) open pTab as cursor iCur. +** +** If pTab is a WITHOUT ROWID table, then it is the PRIMARY KEY index +** for that table that is actually opened. +*/ +SQLITE_PRIVATE void sqlite3OpenTable( + Parse *pParse, /* Generate code into this VDBE */ + int iCur, /* The cursor number of the table */ + int iDb, /* The database index in sqlite3.aDb[] */ + Table *pTab, /* The table to be opened */ + int opcode /* OP_OpenRead or OP_OpenWrite */ +){ + Vdbe *v; + assert( !IsVirtual(pTab) ); + assert( pParse->pVdbe!=0 ); + v = pParse->pVdbe; + assert( opcode==OP_OpenWrite || opcode==OP_OpenRead ); + if( !pParse->db->noSharedCache ){ + sqlite3TableLock(pParse, iDb, pTab->tnum, + (opcode==OP_OpenWrite)?1:0, pTab->zName); + } + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nNVCol); + VdbeComment((v, "%s", pTab->zName)); + }else{ + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + assert( pPk!=0 ); + assert( pPk->tnum==pTab->tnum || CORRUPT_DB ); + sqlite3VdbeAddOp3(v, opcode, iCur, pPk->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pPk); + VdbeComment((v, "%s", pTab->zName)); + } +} + +/* +** Return a pointer to the column affinity string associated with index +** pIdx. A column affinity string has one character for each column in +** the table, according to the affinity of the column: +** +** Character Column affinity +** ------------------------------ +** 'A' BLOB +** 'B' TEXT +** 'C' NUMERIC +** 'D' INTEGER +** 'F' REAL +** +** An extra 'D' is appended to the end of the string to cover the +** rowid that appears as the last column in every index. +** +** Memory for the buffer containing the column index affinity string +** is managed along with the rest of the Index structure. It will be +** released when sqlite3DeleteIndex() is called. +*/ +static SQLITE_NOINLINE const char *computeIndexAffStr(sqlite3 *db, Index *pIdx){ + /* The first time a column affinity string for a particular index is + ** required, it is allocated and populated here. It is then stored as + ** a member of the Index structure for subsequent use. + ** + ** The column affinity string will eventually be deleted by + ** sqliteDeleteIndex() when the Index structure itself is cleaned + ** up. + */ + int n; + Table *pTab = pIdx->pTable; + pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1); + if( !pIdx->zColAff ){ + sqlite3OomFault(db); + return 0; + } + for(n=0; nnColumn; n++){ + i16 x = pIdx->aiColumn[n]; + char aff; + if( x>=0 ){ + aff = pTab->aCol[x].affinity; + }else if( x==XN_ROWID ){ + aff = SQLITE_AFF_INTEGER; + }else{ + assert( x==XN_EXPR ); + assert( pIdx->bHasExpr ); + assert( pIdx->aColExpr!=0 ); + aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr); + } + if( affSQLITE_AFF_NUMERIC) aff = SQLITE_AFF_NUMERIC; + pIdx->zColAff[n] = aff; + } + pIdx->zColAff[n] = 0; + return pIdx->zColAff; +} +SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){ + if( !pIdx->zColAff ) return computeIndexAffStr(db, pIdx); + return pIdx->zColAff; +} + + +/* +** Compute an affinity string for a table. Space is obtained +** from sqlite3DbMalloc(). The caller is responsible for freeing +** the space when done. +*/ +SQLITE_PRIVATE char *sqlite3TableAffinityStr(sqlite3 *db, const Table *pTab){ + char *zColAff; + zColAff = (char *)sqlite3DbMallocRaw(db, pTab->nCol+1); + if( zColAff ){ + int i, j; + for(i=j=0; inCol; i++){ + if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){ + zColAff[j++] = pTab->aCol[i].affinity; + } + } + do{ + zColAff[j--] = 0; + }while( j>=0 && zColAff[j]<=SQLITE_AFF_BLOB ); + } + return zColAff; +} + +/* +** Make changes to the evolving bytecode to do affinity transformations +** of values that are about to be gathered into a row for table pTab. +** +** For ordinary (legacy, non-strict) tables: +** ----------------------------------------- +** +** Compute the affinity string for table pTab, if it has not already been +** computed. As an optimization, omit trailing SQLITE_AFF_BLOB affinities. +** +** If the affinity string is empty (because it was all SQLITE_AFF_BLOB entries +** which were then optimized out) then this routine becomes a no-op. +** +** Otherwise if iReg>0 then code an OP_Affinity opcode that will set the +** affinities for register iReg and following. Or if iReg==0, +** then just set the P4 operand of the previous opcode (which should be +** an OP_MakeRecord) to the affinity string. +** +** A column affinity string has one character per column: +** +** Character Column affinity +** --------- --------------- +** 'A' BLOB +** 'B' TEXT +** 'C' NUMERIC +** 'D' INTEGER +** 'E' REAL +** +** For STRICT tables: +** ------------------ +** +** Generate an appropriate OP_TypeCheck opcode that will verify the +** datatypes against the column definitions in pTab. If iReg==0, that +** means an OP_MakeRecord opcode has already been generated and should be +** the last opcode generated. The new OP_TypeCheck needs to be inserted +** before the OP_MakeRecord. The new OP_TypeCheck should use the same +** register set as the OP_MakeRecord. If iReg>0 then register iReg is +** the first of a series of registers that will form the new record. +** Apply the type checking to that array of registers. +*/ +SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ + int i; + char *zColAff; + if( pTab->tabFlags & TF_Strict ){ + if( iReg==0 ){ + /* Move the previous opcode (which should be OP_MakeRecord) forward + ** by one slot and insert a new OP_TypeCheck where the current + ** OP_MakeRecord is found */ + VdbeOp *pPrev; + int p3; + sqlite3VdbeAppendP4(v, pTab, P4_TABLE); + pPrev = sqlite3VdbeGetLastOp(v); + assert( pPrev!=0 ); + assert( pPrev->opcode==OP_MakeRecord || sqlite3VdbeDb(v)->mallocFailed ); + pPrev->opcode = OP_TypeCheck; + p3 = pPrev->p3; + pPrev->p3 = 0; + sqlite3VdbeAddOp3(v, OP_MakeRecord, pPrev->p1, pPrev->p2, p3); + }else{ + /* Insert an isolated OP_Typecheck */ + sqlite3VdbeAddOp2(v, OP_TypeCheck, iReg, pTab->nNVCol); + sqlite3VdbeAppendP4(v, pTab, P4_TABLE); + } + return; + } + zColAff = pTab->zColAff; + if( zColAff==0 ){ + zColAff = sqlite3TableAffinityStr(0, pTab); + if( !zColAff ){ + sqlite3OomFault(sqlite3VdbeDb(v)); + return; + } + pTab->zColAff = zColAff; + } + assert( zColAff!=0 ); + i = sqlite3Strlen30NN(zColAff); + if( i ){ + if( iReg ){ + sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i); + }else{ + assert( sqlite3VdbeGetLastOp(v)->opcode==OP_MakeRecord + || sqlite3VdbeDb(v)->mallocFailed ); + sqlite3VdbeChangeP4(v, -1, zColAff, i); + } + } +} + +/* +** Return non-zero if the table pTab in database iDb or any of its indices +** have been opened at any point in the VDBE program. This is used to see if +** a statement of the form "INSERT INTO SELECT ..." can +** run without using a temporary table for the results of the SELECT. +*/ +static int readsTable(Parse *p, int iDb, Table *pTab){ + Vdbe *v = sqlite3GetVdbe(p); + int i; + int iEnd = sqlite3VdbeCurrentAddr(v); +#ifndef SQLITE_OMIT_VIRTUALTABLE + VTable *pVTab = IsVirtual(pTab) ? sqlite3GetVTable(p->db, pTab) : 0; +#endif + + for(i=1; iopcode==OP_OpenRead && pOp->p3==iDb ){ + Index *pIndex; + Pgno tnum = pOp->p2; + if( tnum==pTab->tnum ){ + return 1; + } + for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){ + if( tnum==pIndex->tnum ){ + return 1; + } + } + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( pOp->opcode==OP_VOpen && pOp->p4.pVtab==pVTab ){ + assert( pOp->p4.pVtab!=0 ); + assert( pOp->p4type==P4_VTAB ); + return 1; + } +#endif + } + return 0; +} + +/* This walker callback will compute the union of colFlags flags for all +** referenced columns in a CHECK constraint or generated column expression. +*/ +static int exprColumnFlagUnion(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_COLUMN && pExpr->iColumn>=0 ){ + assert( pExpr->iColumn < pWalker->u.pTab->nCol ); + pWalker->eCode |= pWalker->u.pTab->aCol[pExpr->iColumn].colFlags; + } + return WRC_Continue; +} + +#ifndef SQLITE_OMIT_GENERATED_COLUMNS +/* +** All regular columns for table pTab have been puts into registers +** starting with iRegStore. The registers that correspond to STORED +** or VIRTUAL columns have not yet been initialized. This routine goes +** back and computes the values for those columns based on the previously +** computed normal columns. +*/ +SQLITE_PRIVATE void sqlite3ComputeGeneratedColumns( + Parse *pParse, /* Parsing context */ + int iRegStore, /* Register holding the first column */ + Table *pTab /* The table */ +){ + int i; + Walker w; + Column *pRedo; + int eProgress; + VdbeOp *pOp; + + assert( pTab->tabFlags & TF_HasGenerated ); + testcase( pTab->tabFlags & TF_HasVirtual ); + testcase( pTab->tabFlags & TF_HasStored ); + + /* Before computing generated columns, first go through and make sure + ** that appropriate affinity has been applied to the regular columns + */ + sqlite3TableAffinity(pParse->pVdbe, pTab, iRegStore); + if( (pTab->tabFlags & TF_HasStored)!=0 ){ + pOp = sqlite3VdbeGetLastOp(pParse->pVdbe); + if( pOp->opcode==OP_Affinity ){ + /* Change the OP_Affinity argument to '@' (NONE) for all stored + ** columns. '@' is the no-op affinity and those columns have not + ** yet been computed. */ + int ii, jj; + char *zP4 = pOp->p4.z; + assert( zP4!=0 ); + assert( pOp->p4type==P4_DYNAMIC ); + for(ii=jj=0; zP4[jj]; ii++){ + if( pTab->aCol[ii].colFlags & COLFLAG_VIRTUAL ){ + continue; + } + if( pTab->aCol[ii].colFlags & COLFLAG_STORED ){ + zP4[jj] = SQLITE_AFF_NONE; + } + jj++; + } + }else if( pOp->opcode==OP_TypeCheck ){ + /* If an OP_TypeCheck was generated because the table is STRICT, + ** then set the P3 operand to indicate that generated columns should + ** not be checked */ + pOp->p3 = 1; + } + } + + /* Because there can be multiple generated columns that refer to one another, + ** this is a two-pass algorithm. On the first pass, mark all generated + ** columns as "not available". + */ + for(i=0; inCol; i++){ + if( pTab->aCol[i].colFlags & COLFLAG_GENERATED ){ + testcase( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ); + testcase( pTab->aCol[i].colFlags & COLFLAG_STORED ); + pTab->aCol[i].colFlags |= COLFLAG_NOTAVAIL; + } + } + + w.u.pTab = pTab; + w.xExprCallback = exprColumnFlagUnion; + w.xSelectCallback = 0; + w.xSelectCallback2 = 0; + + /* On the second pass, compute the value of each NOT-AVAILABLE column. + ** Companion code in the TK_COLUMN case of sqlite3ExprCodeTarget() will + ** compute dependencies and mark remove the COLSPAN_NOTAVAIL mark, as + ** they are needed. + */ + pParse->iSelfTab = -iRegStore; + do{ + eProgress = 0; + pRedo = 0; + for(i=0; inCol; i++){ + Column *pCol = pTab->aCol + i; + if( (pCol->colFlags & COLFLAG_NOTAVAIL)!=0 ){ + int x; + pCol->colFlags |= COLFLAG_BUSY; + w.eCode = 0; + sqlite3WalkExpr(&w, sqlite3ColumnExpr(pTab, pCol)); + pCol->colFlags &= ~COLFLAG_BUSY; + if( w.eCode & COLFLAG_NOTAVAIL ){ + pRedo = pCol; + continue; + } + eProgress = 1; + assert( pCol->colFlags & COLFLAG_GENERATED ); + x = sqlite3TableColumnToStorage(pTab, i) + iRegStore; + sqlite3ExprCodeGeneratedColumn(pParse, pTab, pCol, x); + pCol->colFlags &= ~COLFLAG_NOTAVAIL; + } + } + }while( pRedo && eProgress ); + if( pRedo ){ + sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", pRedo->zCnName); + } + pParse->iSelfTab = 0; +} +#endif /* SQLITE_OMIT_GENERATED_COLUMNS */ + + +#ifndef SQLITE_OMIT_AUTOINCREMENT +/* +** Locate or create an AutoincInfo structure associated with table pTab +** which is in database iDb. Return the register number for the register +** that holds the maximum rowid. Return zero if pTab is not an AUTOINCREMENT +** table. (Also return zero when doing a VACUUM since we do not want to +** update the AUTOINCREMENT counters during a VACUUM.) +** +** There is at most one AutoincInfo structure per table even if the +** same table is autoincremented multiple times due to inserts within +** triggers. A new AutoincInfo structure is created if this is the +** first use of table pTab. On 2nd and subsequent uses, the original +** AutoincInfo structure is used. +** +** Four consecutive registers are allocated: +** +** (1) The name of the pTab table. +** (2) The maximum ROWID of pTab. +** (3) The rowid in sqlite_sequence of pTab +** (4) The original value of the max ROWID in pTab, or NULL if none +** +** The 2nd register is the one that is returned. That is all the +** insert routine needs to know about. +*/ +static int autoIncBegin( + Parse *pParse, /* Parsing context */ + int iDb, /* Index of the database holding pTab */ + Table *pTab /* The table we are writing to */ +){ + int memId = 0; /* Register holding maximum rowid */ + assert( pParse->db->aDb[iDb].pSchema!=0 ); + if( (pTab->tabFlags & TF_Autoincrement)!=0 + && (pParse->db->mDbFlags & DBFLAG_Vacuum)==0 + ){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + AutoincInfo *pInfo; + Table *pSeqTab = pParse->db->aDb[iDb].pSchema->pSeqTab; + + /* Verify that the sqlite_sequence table exists and is an ordinary + ** rowid table with exactly two columns. + ** Ticket d8dc2b3a58cd5dc2918a1d4acb 2018-05-23 */ + if( pSeqTab==0 + || !HasRowid(pSeqTab) + || NEVER(IsVirtual(pSeqTab)) + || pSeqTab->nCol!=2 + ){ + pParse->nErr++; + pParse->rc = SQLITE_CORRUPT_SEQUENCE; + return 0; + } + + pInfo = pToplevel->pAinc; + while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; } + if( pInfo==0 ){ + pInfo = sqlite3DbMallocRawNN(pParse->db, sizeof(*pInfo)); + sqlite3ParserAddCleanup(pToplevel, sqlite3DbFree, pInfo); + testcase( pParse->earlyCleanup ); + if( pParse->db->mallocFailed ) return 0; + pInfo->pNext = pToplevel->pAinc; + pToplevel->pAinc = pInfo; + pInfo->pTab = pTab; + pInfo->iDb = iDb; + pToplevel->nMem++; /* Register to hold name of table */ + pInfo->regCtr = ++pToplevel->nMem; /* Max rowid register */ + pToplevel->nMem +=2; /* Rowid in sqlite_sequence + orig max val */ + } + memId = pInfo->regCtr; + } + return memId; +} + +/* +** This routine generates code that will initialize all of the +** register used by the autoincrement tracker. +*/ +SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse){ + AutoincInfo *p; /* Information about an AUTOINCREMENT */ + sqlite3 *db = pParse->db; /* The database connection */ + Db *pDb; /* Database only autoinc table */ + int memId; /* Register holding max rowid */ + Vdbe *v = pParse->pVdbe; /* VDBE under construction */ + + /* This routine is never called during trigger-generation. It is + ** only called from the top-level */ + assert( pParse->pTriggerTab==0 ); + assert( sqlite3IsToplevel(pParse) ); + + assert( v ); /* We failed long ago if this is not so */ + for(p = pParse->pAinc; p; p = p->pNext){ + static const int iLn = VDBE_OFFSET_LINENO(2); + static const VdbeOpList autoInc[] = { + /* 0 */ {OP_Null, 0, 0, 0}, + /* 1 */ {OP_Rewind, 0, 10, 0}, + /* 2 */ {OP_Column, 0, 0, 0}, + /* 3 */ {OP_Ne, 0, 9, 0}, + /* 4 */ {OP_Rowid, 0, 0, 0}, + /* 5 */ {OP_Column, 0, 1, 0}, + /* 6 */ {OP_AddImm, 0, 0, 0}, + /* 7 */ {OP_Copy, 0, 0, 0}, + /* 8 */ {OP_Goto, 0, 11, 0}, + /* 9 */ {OP_Next, 0, 2, 0}, + /* 10 */ {OP_Integer, 0, 0, 0}, + /* 11 */ {OP_Close, 0, 0, 0} + }; + VdbeOp *aOp; + pDb = &db->aDb[p->iDb]; + memId = p->regCtr; + assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); + sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead); + sqlite3VdbeLoadString(v, memId-1, p->pTab->zName); + aOp = sqlite3VdbeAddOpList(v, ArraySize(autoInc), autoInc, iLn); + if( aOp==0 ) break; + aOp[0].p2 = memId; + aOp[0].p3 = memId+2; + aOp[2].p3 = memId; + aOp[3].p1 = memId-1; + aOp[3].p3 = memId; + aOp[3].p5 = SQLITE_JUMPIFNULL; + aOp[4].p2 = memId+1; + aOp[5].p3 = memId; + aOp[6].p1 = memId; + aOp[7].p2 = memId+2; + aOp[7].p1 = memId; + aOp[10].p2 = memId; + if( pParse->nTab==0 ) pParse->nTab = 1; + } +} + +/* +** Update the maximum rowid for an autoincrement calculation. +** +** This routine should be called when the regRowid register holds a +** new rowid that is about to be inserted. If that new rowid is +** larger than the maximum rowid in the memId memory cell, then the +** memory cell is updated. +*/ +static void autoIncStep(Parse *pParse, int memId, int regRowid){ + if( memId>0 ){ + sqlite3VdbeAddOp2(pParse->pVdbe, OP_MemMax, memId, regRowid); + } +} + +/* +** This routine generates the code needed to write autoincrement +** maximum rowid values back into the sqlite_sequence register. +** Every statement that might do an INSERT into an autoincrement +** table (either directly or through triggers) needs to call this +** routine just before the "exit" code. +*/ +static SQLITE_NOINLINE void autoIncrementEnd(Parse *pParse){ + AutoincInfo *p; + Vdbe *v = pParse->pVdbe; + sqlite3 *db = pParse->db; + + assert( v ); + for(p = pParse->pAinc; p; p = p->pNext){ + static const int iLn = VDBE_OFFSET_LINENO(2); + static const VdbeOpList autoIncEnd[] = { + /* 0 */ {OP_NotNull, 0, 2, 0}, + /* 1 */ {OP_NewRowid, 0, 0, 0}, + /* 2 */ {OP_MakeRecord, 0, 2, 0}, + /* 3 */ {OP_Insert, 0, 0, 0}, + /* 4 */ {OP_Close, 0, 0, 0} + }; + VdbeOp *aOp; + Db *pDb = &db->aDb[p->iDb]; + int iRec; + int memId = p->regCtr; + + iRec = sqlite3GetTempReg(pParse); + assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); + sqlite3VdbeAddOp3(v, OP_Le, memId+2, sqlite3VdbeCurrentAddr(v)+7, memId); + VdbeCoverage(v); + sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite); + aOp = sqlite3VdbeAddOpList(v, ArraySize(autoIncEnd), autoIncEnd, iLn); + if( aOp==0 ) break; + aOp[0].p1 = memId+1; + aOp[1].p2 = memId+1; + aOp[2].p1 = memId-1; + aOp[2].p3 = iRec; + aOp[3].p2 = iRec; + aOp[3].p3 = memId+1; + aOp[3].p5 = OPFLAG_APPEND; + sqlite3ReleaseTempReg(pParse, iRec); + } +} +SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){ + if( pParse->pAinc ) autoIncrementEnd(pParse); +} +#else +/* +** If SQLITE_OMIT_AUTOINCREMENT is defined, then the three routines +** above are all no-ops +*/ +# define autoIncBegin(A,B,C) (0) +# define autoIncStep(A,B,C) +#endif /* SQLITE_OMIT_AUTOINCREMENT */ + +/* +** If argument pVal is a Select object returned by an sqlite3MultiValues() +** that was able to use the co-routine optimization, finish coding the +** co-routine. +*/ +SQLITE_PRIVATE void sqlite3MultiValuesEnd(Parse *pParse, Select *pVal){ + if( ALWAYS(pVal) && pVal->pSrc->nSrc>0 ){ + SrcItem *pItem = &pVal->pSrc->a[0]; + assert( (pItem->fg.isSubquery && pItem->u4.pSubq!=0) || pParse->nErr ); + if( pItem->fg.isSubquery ){ + sqlite3VdbeEndCoroutine(pParse->pVdbe, pItem->u4.pSubq->regReturn); + sqlite3VdbeJumpHere(pParse->pVdbe, pItem->u4.pSubq->addrFillSub - 1); + } + } +} + +/* +** Return true if all expressions in the expression-list passed as the +** only argument are constant. +*/ +static int exprListIsConstant(Parse *pParse, ExprList *pRow){ + int ii; + for(ii=0; iinExpr; ii++){ + if( 0==sqlite3ExprIsConstant(pParse, pRow->a[ii].pExpr) ) return 0; + } + return 1; +} + +/* +** Return true if all expressions in the expression-list passed as the +** only argument are both constant and have no affinity. +*/ +static int exprListIsNoAffinity(Parse *pParse, ExprList *pRow){ + int ii; + if( exprListIsConstant(pParse,pRow)==0 ) return 0; + for(ii=0; iinExpr; ii++){ + Expr *pExpr = pRow->a[ii].pExpr; + assert( pExpr->op!=TK_RAISE ); + assert( pExpr->affExpr==0 ); + if( 0!=sqlite3ExprAffinity(pExpr) ) return 0; + } + return 1; + +} + +/* +** This function is called by the parser for the second and subsequent +** rows of a multi-row VALUES clause. Argument pLeft is the part of +** the VALUES clause already parsed, argument pRow is the vector of values +** for the new row. The Select object returned represents the complete +** VALUES clause, including the new row. +** +** There are two ways in which this may be achieved - by incremental +** coding of a co-routine (the "co-routine" method) or by returning a +** Select object equivalent to the following (the "UNION ALL" method): +** +** "pLeft UNION ALL SELECT pRow" +** +** If the VALUES clause contains a lot of rows, this compound Select +** object may consume a lot of memory. +** +** When the co-routine method is used, each row that will be returned +** by the VALUES clause is coded into part of a co-routine as it is +** passed to this function. The returned Select object is equivalent to: +** +** SELECT * FROM ( +** Select object to read co-routine +** ) +** +** The co-routine method is used in most cases. Exceptions are: +** +** a) If the current statement has a WITH clause. This is to avoid +** statements like: +** +** WITH cte AS ( VALUES('x'), ('y') ... ) +** SELECT * FROM cte AS a, cte AS b; +** +** This will not work, as the co-routine uses a hard-coded register +** for its OP_Yield instructions, and so it is not possible for two +** cursors to iterate through it concurrently. +** +** b) The schema is currently being parsed (i.e. the VALUES clause is part +** of a schema item like a VIEW or TRIGGER). In this case there is no VM +** being generated when parsing is taking place, and so generating +** a co-routine is not possible. +** +** c) There are non-constant expressions in the VALUES clause (e.g. +** the VALUES clause is part of a correlated sub-query). +** +** d) One or more of the values in the first row of the VALUES clause +** has an affinity (i.e. is a CAST expression). This causes problems +** because the complex rules SQLite uses (see function +** sqlite3SubqueryColumnTypes() in select.c) to determine the effective +** affinity of such a column for all rows require access to all values in +** the column simultaneously. +*/ +SQLITE_PRIVATE Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList *pRow){ + + if( pParse->bHasWith /* condition (a) above */ + || pParse->db->init.busy /* condition (b) above */ + || exprListIsConstant(pParse,pRow)==0 /* condition (c) above */ + || (pLeft->pSrc->nSrc==0 && + exprListIsNoAffinity(pParse,pLeft->pEList)==0) /* condition (d) above */ + || IN_SPECIAL_PARSE + ){ + /* The co-routine method cannot be used. Fall back to UNION ALL. */ + Select *pSelect = 0; + int f = SF_Values | SF_MultiValue; + if( pLeft->pSrc->nSrc ){ + sqlite3MultiValuesEnd(pParse, pLeft); + f = SF_Values; + }else if( pLeft->pPrior ){ + /* In this case set the SF_MultiValue flag only if it was set on pLeft */ + f = (f & pLeft->selFlags); + } + pSelect = sqlite3SelectNew(pParse, pRow, 0, 0, 0, 0, 0, f, 0); + pLeft->selFlags &= ~(u32)SF_MultiValue; + if( pSelect ){ + pSelect->op = TK_ALL; + pSelect->pPrior = pLeft; + pLeft = pSelect; + } + }else{ + SrcItem *p = 0; /* SrcItem that reads from co-routine */ + + if( pLeft->pSrc->nSrc==0 ){ + /* Co-routine has not yet been started and the special Select object + ** that accesses the co-routine has not yet been created. This block + ** does both those things. */ + Vdbe *v = sqlite3GetVdbe(pParse); + Select *pRet = sqlite3SelectNew(pParse, 0, 0, 0, 0, 0, 0, 0, 0); + + /* Ensure the database schema has been read. This is to ensure we have + ** the correct text encoding. */ + if( (pParse->db->mDbFlags & DBFLAG_SchemaKnownOk)==0 ){ + sqlite3ReadSchema(pParse); + } + + if( pRet ){ + SelectDest dest; + Subquery *pSubq; + pRet->pSrc->nSrc = 1; + pRet->pPrior = pLeft->pPrior; + pRet->op = pLeft->op; + if( pRet->pPrior ) pRet->selFlags |= SF_Values; + pLeft->pPrior = 0; + pLeft->op = TK_SELECT; + assert( pLeft->pNext==0 ); + assert( pRet->pNext==0 ); + p = &pRet->pSrc->a[0]; + p->fg.viaCoroutine = 1; + p->iCursor = -1; + assert( !p->fg.isIndexedBy && !p->fg.isTabFunc ); + p->u1.nRow = 2; + if( sqlite3SrcItemAttachSubquery(pParse, p, pLeft, 0) ){ + pSubq = p->u4.pSubq; + pSubq->addrFillSub = sqlite3VdbeCurrentAddr(v) + 1; + pSubq->regReturn = ++pParse->nMem; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, + pSubq->regReturn, 0, pSubq->addrFillSub); + sqlite3SelectDestInit(&dest, SRT_Coroutine, pSubq->regReturn); + + /* Allocate registers for the output of the co-routine. Do so so + ** that there are two unused registers immediately before those + ** used by the co-routine. This allows the code in sqlite3Insert() + ** to use these registers directly, instead of copying the output + ** of the co-routine to a separate array for processing. */ + dest.iSdst = pParse->nMem + 3; + dest.nSdst = pLeft->pEList->nExpr; + pParse->nMem += 2 + dest.nSdst; + + pLeft->selFlags |= SF_MultiValue; + sqlite3Select(pParse, pLeft, &dest); + pSubq->regResult = dest.iSdst; + assert( pParse->nErr || dest.iSdst>0 ); + } + pLeft = pRet; + } + }else{ + p = &pLeft->pSrc->a[0]; + assert( !p->fg.isTabFunc && !p->fg.isIndexedBy ); + p->u1.nRow++; + } + + if( pParse->nErr==0 ){ + Subquery *pSubq; + assert( p!=0 ); + assert( p->fg.isSubquery ); + pSubq = p->u4.pSubq; + assert( pSubq!=0 ); + assert( pSubq->pSelect!=0 ); + assert( pSubq->pSelect->pEList!=0 ); + if( pSubq->pSelect->pEList->nExpr!=pRow->nExpr ){ + sqlite3SelectWrongNumTermsError(pParse, pSubq->pSelect); + }else{ + sqlite3ExprCodeExprList(pParse, pRow, pSubq->regResult, 0, 0); + sqlite3VdbeAddOp1(pParse->pVdbe, OP_Yield, pSubq->regReturn); + } + } + sqlite3ExprListDelete(pParse->db, pRow); + } + + return pLeft; +} + +/* Forward declaration */ +static int xferOptimization( + Parse *pParse, /* Parser context */ + Table *pDest, /* The table we are inserting into */ + Select *pSelect, /* A SELECT statement to use as the data source */ + int onError, /* How to handle constraint errors */ + int iDbDest /* The database of pDest */ +); + +/* +** This routine is called to handle SQL of the following forms: +** +** insert into TABLE (IDLIST) values(EXPRLIST),(EXPRLIST),... +** insert into TABLE (IDLIST) select +** insert into TABLE (IDLIST) default values +** +** The IDLIST following the table name is always optional. If omitted, +** then a list of all (non-hidden) columns for the table is substituted. +** The IDLIST appears in the pColumn parameter. pColumn is NULL if IDLIST +** is omitted. +** +** For the pSelect parameter holds the values to be inserted for the +** first two forms shown above. A VALUES clause is really just short-hand +** for a SELECT statement that omits the FROM clause and everything else +** that follows. If the pSelect parameter is NULL, that means that the +** DEFAULT VALUES form of the INSERT statement is intended. +** +** The code generated follows one of four templates. For a simple +** insert with data coming from a single-row VALUES clause, the code executes +** once straight down through. Pseudo-code follows (we call this +** the "1st template"): +** +** open write cursor to
    and its indices +** put VALUES clause expressions into registers +** write the resulting record into
    +** cleanup +** +** The three remaining templates assume the statement is of the form +** +** INSERT INTO
    SELECT ... +** +** If the SELECT clause is of the restricted form "SELECT * FROM " - +** in other words if the SELECT pulls all columns from a single table +** and there is no WHERE or LIMIT or GROUP BY or ORDER BY clauses, and +** if and are distinct tables but have identical +** schemas, including all the same indices, then a special optimization +** is invoked that copies raw records from over to . +** See the xferOptimization() function for the implementation of this +** template. This is the 2nd template. +** +** open a write cursor to
    +** open read cursor on +** transfer all records in over to
    +** close cursors +** foreach index on
    +** open a write cursor on the
    index +** open a read cursor on the corresponding index +** transfer all records from the read to the write cursors +** close cursors +** end foreach +** +** The 3rd template is for when the second template does not apply +** and the SELECT clause does not read from
    at any time. +** The generated code follows this template: +** +** X <- A +** goto B +** A: setup for the SELECT +** loop over the rows in the SELECT +** load values into registers R..R+n +** yield X +** end loop +** cleanup after the SELECT +** end-coroutine X +** B: open write cursor to
    and its indices +** C: yield X, at EOF goto D +** insert the select result into
    from R..R+n +** goto C +** D: cleanup +** +** The 4th template is used if the insert statement takes its +** values from a SELECT but the data is being inserted into a table +** that is also read as part of the SELECT. In the third form, +** we have to use an intermediate table to store the results of +** the select. The template is like this: +** +** X <- A +** goto B +** A: setup for the SELECT +** loop over the tables in the SELECT +** load value into register R..R+n +** yield X +** end loop +** cleanup after the SELECT +** end co-routine R +** B: open temp table +** L: yield X, at EOF goto M +** insert row from R..R+n into temp table +** goto L +** M: open write cursor to
    and its indices +** rewind temp table +** C: loop over rows of intermediate table +** transfer values form intermediate table into
    +** end loop +** D: cleanup +*/ +SQLITE_PRIVATE void sqlite3Insert( + Parse *pParse, /* Parser context */ + SrcList *pTabList, /* Name of table into which we are inserting */ + Select *pSelect, /* A SELECT statement to use as the data source */ + IdList *pColumn, /* Column names corresponding to IDLIST, or NULL. */ + int onError, /* How to handle constraint errors */ + Upsert *pUpsert /* ON CONFLICT clauses for upsert, or NULL */ +){ + sqlite3 *db; /* The main database structure */ + Table *pTab; /* The table to insert into. aka TABLE */ + int i, j; /* Loop counters */ + Vdbe *v; /* Generate code into this virtual machine */ + Index *pIdx; /* For looping over indices of the table */ + int nColumn; /* Number of columns in the data */ + int nHidden = 0; /* Number of hidden columns if TABLE is virtual */ + int iDataCur = 0; /* VDBE cursor that is the main data repository */ + int iIdxCur = 0; /* First index cursor */ + int ipkColumn = -1; /* Column that is the INTEGER PRIMARY KEY */ + int endOfLoop; /* Label for the end of the insertion loop */ + int srcTab = 0; /* Data comes from this temporary cursor if >=0 */ + int addrInsTop = 0; /* Jump to label "D" */ + int addrCont = 0; /* Top of insert loop. Label "C" in templates 3 and 4 */ + SelectDest dest; /* Destination for SELECT on rhs of INSERT */ + int iDb; /* Index of database holding TABLE */ + u8 useTempTable = 0; /* Store SELECT results in intermediate table */ + u8 appendFlag = 0; /* True if the insert is likely to be an append */ + u8 withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */ + u8 bIdListInOrder; /* True if IDLIST is in table order */ + ExprList *pList = 0; /* List of VALUES() to be inserted */ + int iRegStore; /* Register in which to store next column */ + + /* Register allocations */ + int regFromSelect = 0;/* Base register for data coming from SELECT */ + int regAutoinc = 0; /* Register holding the AUTOINCREMENT counter */ + int regRowCount = 0; /* Memory cell used for the row counter */ + int regIns; /* Block of regs holding rowid+data being inserted */ + int regRowid; /* registers holding insert rowid */ + int regData; /* register holding first column to insert */ + int *aRegIdx = 0; /* One register allocated to each index */ + int *aTabColMap = 0; /* Mapping from pTab columns to pCol entries */ + +#ifndef SQLITE_OMIT_TRIGGER + int isView; /* True if attempting to insert into a view */ + Trigger *pTrigger; /* List of triggers on pTab, if required */ + int tmask; /* Mask of trigger times */ +#endif + + db = pParse->db; + assert( db->pParse==pParse ); + if( pParse->nErr ){ + goto insert_cleanup; + } + assert( db->mallocFailed==0 ); + dest.iSDParm = 0; /* Suppress a harmless compiler warning */ + + /* If the Select object is really just a simple VALUES() list with a + ** single row (the common case) then keep that one row of values + ** and discard the other (unused) parts of the pSelect object + */ + if( pSelect && (pSelect->selFlags & SF_Values)!=0 && pSelect->pPrior==0 ){ + pList = pSelect->pEList; + pSelect->pEList = 0; + sqlite3SelectDelete(db, pSelect); + pSelect = 0; + } + + /* Locate the table into which we will be inserting new information. + */ + assert( pTabList->nSrc==1 ); + pTab = sqlite3SrcListLookup(pParse, pTabList); + if( pTab==0 ){ + goto insert_cleanup; + } + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iDbnDb ); + if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, + db->aDb[iDb].zDbSName) ){ + goto insert_cleanup; + } + withoutRowid = !HasRowid(pTab); + + /* Figure out if we have any triggers and if the table being + ** inserted into is a view + */ +#ifndef SQLITE_OMIT_TRIGGER + pTrigger = sqlite3TriggersExist(pParse, pTab, TK_INSERT, 0, &tmask); + isView = IsView(pTab); +#else +# define pTrigger 0 +# define tmask 0 +# define isView 0 +#endif +#ifdef SQLITE_OMIT_VIEW +# undef isView +# define isView 0 +#endif + assert( (pTrigger && tmask) || (pTrigger==0 && tmask==0) ); + +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x10000 ){ + sqlite3TreeViewLine(0, "In sqlite3Insert() at %s:%d", __FILE__, __LINE__); + sqlite3TreeViewInsert(pParse->pWith, pTabList, pColumn, pSelect, pList, + onError, pUpsert, pTrigger); + } +#endif + + /* If pTab is really a view, make sure it has been initialized. + ** ViewGetColumnNames() is a no-op if pTab is not a view. + */ + if( sqlite3ViewGetColumnNames(pParse, pTab) ){ + goto insert_cleanup; + } + + /* Cannot insert into a read-only table. + */ + if( sqlite3IsReadOnly(pParse, pTab, pTrigger) ){ + goto insert_cleanup; + } + + /* Allocate a VDBE + */ + v = sqlite3GetVdbe(pParse); + if( v==0 ) goto insert_cleanup; + if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); + sqlite3BeginWriteOperation(pParse, pSelect || pTrigger, iDb); + +#ifndef SQLITE_OMIT_XFER_OPT + /* If the statement is of the form + ** + ** INSERT INTO SELECT * FROM ; + ** + ** Then special optimizations can be applied that make the transfer + ** very fast and which reduce fragmentation of indices. + ** + ** This is the 2nd template. + */ + if( pColumn==0 + && pSelect!=0 + && pTrigger==0 + && xferOptimization(pParse, pTab, pSelect, onError, iDb) + ){ + assert( !pTrigger ); + assert( pList==0 ); + goto insert_end; + } +#endif /* SQLITE_OMIT_XFER_OPT */ + + /* If this is an AUTOINCREMENT table, look up the sequence number in the + ** sqlite_sequence table and store it in memory cell regAutoinc. + */ + regAutoinc = autoIncBegin(pParse, iDb, pTab); + + /* Allocate a block registers to hold the rowid and the values + ** for all columns of the new row. + */ + regRowid = regIns = pParse->nMem+1; + pParse->nMem += pTab->nCol + 1; + if( IsVirtual(pTab) ){ + regRowid++; + pParse->nMem++; + } + regData = regRowid+1; + + /* If the INSERT statement included an IDLIST term, then make sure + ** all elements of the IDLIST really are columns of the table and + ** remember the column indices. + ** + ** If the table has an INTEGER PRIMARY KEY column and that column + ** is named in the IDLIST, then record in the ipkColumn variable + ** the index into IDLIST of the primary key column. ipkColumn is + ** the index of the primary key as it appears in IDLIST, not as + ** is appears in the original table. (The index of the INTEGER + ** PRIMARY KEY in the original table is pTab->iPKey.) After this + ** loop, if ipkColumn==(-1), that means that integer primary key + ** is unspecified, and hence the table is either WITHOUT ROWID or + ** it will automatically generated an integer primary key. + ** + ** bIdListInOrder is true if the columns in IDLIST are in storage + ** order. This enables an optimization that avoids shuffling the + ** columns into storage order. False negatives are harmless, + ** but false positives will cause database corruption. + */ + bIdListInOrder = (pTab->tabFlags & (TF_OOOHidden|TF_HasStored))==0; + if( pColumn ){ + aTabColMap = sqlite3DbMallocZero(db, pTab->nCol*sizeof(int)); + if( aTabColMap==0 ) goto insert_cleanup; + for(i=0; inId; i++){ + j = sqlite3ColumnIndex(pTab, pColumn->a[i].zName); + if( j>=0 ){ + if( aTabColMap[j]==0 ) aTabColMap[j] = i+1; + if( i!=j ) bIdListInOrder = 0; + if( j==pTab->iPKey ){ + ipkColumn = i; assert( !withoutRowid ); + } +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + if( pTab->aCol[j].colFlags & (COLFLAG_STORED|COLFLAG_VIRTUAL) ){ + sqlite3ErrorMsg(pParse, + "cannot INSERT into generated column \"%s\"", + pTab->aCol[j].zCnName); + goto insert_cleanup; + } +#endif + }else{ + if( sqlite3IsRowid(pColumn->a[i].zName) && !withoutRowid ){ + ipkColumn = i; + bIdListInOrder = 0; + }else{ + sqlite3ErrorMsg(pParse, "table %S has no column named %s", + pTabList->a, pColumn->a[i].zName); + pParse->checkSchema = 1; + goto insert_cleanup; + } + } + } + } + + /* Figure out how many columns of data are supplied. If the data + ** is coming from a SELECT statement, then generate a co-routine that + ** produces a single row of the SELECT on each invocation. The + ** co-routine is the common header to the 3rd and 4th templates. + */ + if( pSelect ){ + /* Data is coming from a SELECT or from a multi-row VALUES clause. + ** Generate a co-routine to run the SELECT. */ + int rc; /* Result code */ + + if( pSelect->pSrc->nSrc==1 + && pSelect->pSrc->a[0].fg.viaCoroutine + && pSelect->pPrior==0 + ){ + SrcItem *pItem = &pSelect->pSrc->a[0]; + Subquery *pSubq; + assert( pItem->fg.isSubquery ); + pSubq = pItem->u4.pSubq; + dest.iSDParm = pSubq->regReturn; + regFromSelect = pSubq->regResult; + assert( pSubq->pSelect!=0 ); + assert( pSubq->pSelect->pEList!=0 ); + nColumn = pSubq->pSelect->pEList->nExpr; + ExplainQueryPlan((pParse, 0, "SCAN %S", pItem)); + if( bIdListInOrder && nColumn==pTab->nCol ){ + regData = regFromSelect; + regRowid = regData - 1; + regIns = regRowid - (IsVirtual(pTab) ? 1 : 0); + } + }else{ + int addrTop; /* Top of the co-routine */ + int regYield = ++pParse->nMem; + addrTop = sqlite3VdbeCurrentAddr(v) + 1; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); + sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); + dest.iSdst = bIdListInOrder ? regData : 0; + dest.nSdst = pTab->nCol; + rc = sqlite3Select(pParse, pSelect, &dest); + regFromSelect = dest.iSdst; + assert( db->pParse==pParse ); + if( rc || pParse->nErr ) goto insert_cleanup; + assert( db->mallocFailed==0 ); + sqlite3VdbeEndCoroutine(v, regYield); + sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */ + assert( pSelect->pEList ); + nColumn = pSelect->pEList->nExpr; + } + + /* Set useTempTable to TRUE if the result of the SELECT statement + ** should be written into a temporary table (template 4). Set to + ** FALSE if each output row of the SELECT can be written directly into + ** the destination table (template 3). + ** + ** A temp table must be used if the table being updated is also one + ** of the tables being read by the SELECT statement. Also use a + ** temp table in the case of row triggers. + */ + if( pTrigger || readsTable(pParse, iDb, pTab) ){ + useTempTable = 1; + } + + if( useTempTable ){ + /* Invoke the coroutine to extract information from the SELECT + ** and add it to a transient table srcTab. The code generated + ** here is from the 4th template: + ** + ** B: open temp table + ** L: yield X, goto M at EOF + ** insert row from R..R+n into temp table + ** goto L + ** M: ... + */ + int regRec; /* Register to hold packed record */ + int regTempRowid; /* Register to hold temp table ROWID */ + int addrL; /* Label "L" */ + + srcTab = pParse->nTab++; + regRec = sqlite3GetTempReg(pParse); + regTempRowid = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn); + addrL = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec); + sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid); + sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid); + sqlite3VdbeGoto(v, addrL); + sqlite3VdbeJumpHere(v, addrL); + sqlite3ReleaseTempReg(pParse, regRec); + sqlite3ReleaseTempReg(pParse, regTempRowid); + } + }else{ + /* This is the case if the data for the INSERT is coming from a + ** single-row VALUES clause + */ + NameContext sNC; + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + srcTab = -1; + assert( useTempTable==0 ); + if( pList ){ + nColumn = pList->nExpr; + if( sqlite3ResolveExprListNames(&sNC, pList) ){ + goto insert_cleanup; + } + }else{ + nColumn = 0; + } + } + + /* If there is no IDLIST term but the table has an integer primary + ** key, the set the ipkColumn variable to the integer primary key + ** column index in the original table definition. + */ + if( pColumn==0 && nColumn>0 ){ + ipkColumn = pTab->iPKey; +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + if( ipkColumn>=0 && (pTab->tabFlags & TF_HasGenerated)!=0 ){ + testcase( pTab->tabFlags & TF_HasVirtual ); + testcase( pTab->tabFlags & TF_HasStored ); + for(i=ipkColumn-1; i>=0; i--){ + if( pTab->aCol[i].colFlags & COLFLAG_GENERATED ){ + testcase( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ); + testcase( pTab->aCol[i].colFlags & COLFLAG_STORED ); + ipkColumn--; + } + } + } +#endif + + /* Make sure the number of columns in the source data matches the number + ** of columns to be inserted into the table. + */ + assert( TF_HasHidden==COLFLAG_HIDDEN ); + assert( TF_HasGenerated==COLFLAG_GENERATED ); + assert( COLFLAG_NOINSERT==(COLFLAG_GENERATED|COLFLAG_HIDDEN) ); + if( (pTab->tabFlags & (TF_HasGenerated|TF_HasHidden))!=0 ){ + for(i=0; inCol; i++){ + if( pTab->aCol[i].colFlags & COLFLAG_NOINSERT ) nHidden++; + } + } + if( nColumn!=(pTab->nCol-nHidden) ){ + sqlite3ErrorMsg(pParse, + "table %S has %d columns but %d values were supplied", + pTabList->a, pTab->nCol-nHidden, nColumn); + goto insert_cleanup; + } + } + if( pColumn!=0 && nColumn!=pColumn->nId ){ + sqlite3ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId); + goto insert_cleanup; + } + + /* Initialize the count of rows to be inserted + */ + if( (db->flags & SQLITE_CountRows)!=0 + && !pParse->nested + && !pParse->pTriggerTab + && !pParse->bReturning + ){ + regRowCount = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount); + } + + /* If this is not a view, open the table and and all indices */ + if( !isView ){ + int nIdx; + nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0, + &iDataCur, &iIdxCur); + aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+2)); + if( aRegIdx==0 ){ + goto insert_cleanup; + } + for(i=0, pIdx=pTab->pIndex; ipNext, i++){ + assert( pIdx ); + aRegIdx[i] = ++pParse->nMem; + pParse->nMem += pIdx->nColumn; + } + aRegIdx[i] = ++pParse->nMem; /* Register to store the table record */ + } +#ifndef SQLITE_OMIT_UPSERT + if( pUpsert ){ + Upsert *pNx; + if( IsVirtual(pTab) ){ + sqlite3ErrorMsg(pParse, "UPSERT not implemented for virtual table \"%s\"", + pTab->zName); + goto insert_cleanup; + } + if( IsView(pTab) ){ + sqlite3ErrorMsg(pParse, "cannot UPSERT a view"); + goto insert_cleanup; + } + if( sqlite3HasExplicitNulls(pParse, pUpsert->pUpsertTarget) ){ + goto insert_cleanup; + } + pTabList->a[0].iCursor = iDataCur; + pNx = pUpsert; + do{ + pNx->pUpsertSrc = pTabList; + pNx->regData = regData; + pNx->iDataCur = iDataCur; + pNx->iIdxCur = iIdxCur; + if( pNx->pUpsertTarget ){ + if( sqlite3UpsertAnalyzeTarget(pParse, pTabList, pNx, pUpsert) ){ + goto insert_cleanup; + } + } + pNx = pNx->pNextUpsert; + }while( pNx!=0 ); + } +#endif + + + /* This is the top of the main insertion loop */ + if( useTempTable ){ + /* This block codes the top of loop only. The complete loop is the + ** following pseudocode (template 4): + ** + ** rewind temp table, if empty goto D + ** C: loop over rows of intermediate table + ** transfer values form intermediate table into
    + ** end loop + ** D: ... + */ + addrInsTop = sqlite3VdbeAddOp1(v, OP_Rewind, srcTab); VdbeCoverage(v); + addrCont = sqlite3VdbeCurrentAddr(v); + }else if( pSelect ){ + /* This block codes the top of loop only. The complete loop is the + ** following pseudocode (template 3): + ** + ** C: yield X, at EOF goto D + ** insert the select result into
    from R..R+n + ** goto C + ** D: ... + */ + sqlite3VdbeReleaseRegisters(pParse, regData, pTab->nCol, 0, 0); + addrInsTop = addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); + VdbeCoverage(v); + if( ipkColumn>=0 ){ + /* tag-20191021-001: If the INTEGER PRIMARY KEY is being generated by the + ** SELECT, go ahead and copy the value into the rowid slot now, so that + ** the value does not get overwritten by a NULL at tag-20191021-002. */ + sqlite3VdbeAddOp2(v, OP_Copy, regFromSelect+ipkColumn, regRowid); + } + } + + /* Compute data for ordinary columns of the new entry. Values + ** are written in storage order into registers starting with regData. + ** Only ordinary columns are computed in this loop. The rowid + ** (if there is one) is computed later and generated columns are + ** computed after the rowid since they might depend on the value + ** of the rowid. + */ + nHidden = 0; + iRegStore = regData; assert( regData==regRowid+1 ); + for(i=0; inCol; i++, iRegStore++){ + int k; + u32 colFlags; + assert( i>=nHidden ); + if( i==pTab->iPKey ){ + /* tag-20191021-002: References to the INTEGER PRIMARY KEY are filled + ** using the rowid. So put a NULL in the IPK slot of the record to avoid + ** using excess space. The file format definition requires this extra + ** NULL - we cannot optimize further by skipping the column completely */ + sqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore); + continue; + } + if( ((colFlags = pTab->aCol[i].colFlags) & COLFLAG_NOINSERT)!=0 ){ + nHidden++; + if( (colFlags & COLFLAG_VIRTUAL)!=0 ){ + /* Virtual columns do not participate in OP_MakeRecord. So back up + ** iRegStore by one slot to compensate for the iRegStore++ in the + ** outer for() loop */ + iRegStore--; + continue; + }else if( (colFlags & COLFLAG_STORED)!=0 ){ + /* Stored columns are computed later. But if there are BEFORE + ** triggers, the slots used for stored columns will be OP_Copy-ed + ** to a second block of registers, so the register needs to be + ** initialized to NULL to avoid an uninitialized register read */ + if( tmask & TRIGGER_BEFORE ){ + sqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore); + } + continue; + }else if( pColumn==0 ){ + /* Hidden columns that are not explicitly named in the INSERT + ** get their default value */ + sqlite3ExprCodeFactorable(pParse, + sqlite3ColumnExpr(pTab, &pTab->aCol[i]), + iRegStore); + continue; + } + } + if( pColumn ){ + j = aTabColMap[i]; + assert( j>=0 && j<=pColumn->nId ); + if( j==0 ){ + /* A column not named in the insert column list gets its + ** default value */ + sqlite3ExprCodeFactorable(pParse, + sqlite3ColumnExpr(pTab, &pTab->aCol[i]), + iRegStore); + continue; + } + k = j - 1; + }else if( nColumn==0 ){ + /* This is INSERT INTO ... DEFAULT VALUES. Load the default value. */ + sqlite3ExprCodeFactorable(pParse, + sqlite3ColumnExpr(pTab, &pTab->aCol[i]), + iRegStore); + continue; + }else{ + k = i - nHidden; + } + + if( useTempTable ){ + sqlite3VdbeAddOp3(v, OP_Column, srcTab, k, iRegStore); + }else if( pSelect ){ + if( regFromSelect!=regData ){ + sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+k, iRegStore); + } + }else{ + Expr *pX = pList->a[k].pExpr; + int y = sqlite3ExprCodeTarget(pParse, pX, iRegStore); + if( y!=iRegStore ){ + sqlite3VdbeAddOp2(v, + ExprHasProperty(pX, EP_Subquery) ? OP_Copy : OP_SCopy, y, iRegStore); + } + } + } + + + /* Run the BEFORE and INSTEAD OF triggers, if there are any + */ + endOfLoop = sqlite3VdbeMakeLabel(pParse); + if( tmask & TRIGGER_BEFORE ){ + int regCols = sqlite3GetTempRange(pParse, pTab->nCol+1); + + /* build the NEW.* reference row. Note that if there is an INTEGER + ** PRIMARY KEY into which a NULL is being inserted, that NULL will be + ** translated into a unique ID for the row. But on a BEFORE trigger, + ** we do not know what the unique ID will be (because the insert has + ** not happened yet) so we substitute a rowid of -1 + */ + if( ipkColumn<0 ){ + sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols); + }else{ + int addr1; + assert( !withoutRowid ); + if( useTempTable ){ + sqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regCols); + }else{ + assert( pSelect==0 ); /* Otherwise useTempTable is true */ + sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regCols); + } + addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols); + sqlite3VdbeJumpHere(v, addr1); + sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols); VdbeCoverage(v); + } + + /* Copy the new data already generated. */ + assert( pTab->nNVCol>0 || pParse->nErr>0 ); + sqlite3VdbeAddOp3(v, OP_Copy, regRowid+1, regCols+1, pTab->nNVCol-1); + +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + /* Compute the new value for generated columns after all other + ** columns have already been computed. This must be done after + ** computing the ROWID in case one of the generated columns + ** refers to the ROWID. */ + if( pTab->tabFlags & TF_HasGenerated ){ + testcase( pTab->tabFlags & TF_HasVirtual ); + testcase( pTab->tabFlags & TF_HasStored ); + sqlite3ComputeGeneratedColumns(pParse, regCols+1, pTab); + } +#endif + + /* If this is an INSERT on a view with an INSTEAD OF INSERT trigger, + ** do not attempt any conversions before assembling the record. + ** If this is a real table, attempt conversions as required by the + ** table column affinities. + */ + if( !isView ){ + sqlite3TableAffinity(v, pTab, regCols+1); + } + + /* Fire BEFORE or INSTEAD OF triggers */ + sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE, + pTab, regCols-pTab->nCol-1, onError, endOfLoop); + + sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol+1); + } + + if( !isView ){ + if( IsVirtual(pTab) ){ + /* The row that the VUpdate opcode will delete: none */ + sqlite3VdbeAddOp2(v, OP_Null, 0, regIns); + } + if( ipkColumn>=0 ){ + /* Compute the new rowid */ + if( useTempTable ){ + sqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regRowid); + }else if( pSelect ){ + /* Rowid already initialized at tag-20191021-001 */ + }else{ + Expr *pIpk = pList->a[ipkColumn].pExpr; + if( pIpk->op==TK_NULL && !IsVirtual(pTab) ){ + sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc); + appendFlag = 1; + }else{ + sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid); + } + } + /* If the PRIMARY KEY expression is NULL, then use OP_NewRowid + ** to generate a unique primary key value. + */ + if( !appendFlag ){ + int addr1; + if( !IsVirtual(pTab) ){ + addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid); VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc); + sqlite3VdbeJumpHere(v, addr1); + }else{ + addr1 = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, addr1+2); VdbeCoverage(v); + } + sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid); VdbeCoverage(v); + } + }else if( IsVirtual(pTab) || withoutRowid ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, regRowid); + }else{ + sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc); + appendFlag = 1; + } + autoIncStep(pParse, regAutoinc, regRowid); + +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + /* Compute the new value for generated columns after all other + ** columns have already been computed. This must be done after + ** computing the ROWID in case one of the generated columns + ** is derived from the INTEGER PRIMARY KEY. */ + if( pTab->tabFlags & TF_HasGenerated ){ + sqlite3ComputeGeneratedColumns(pParse, regRowid+1, pTab); + } +#endif + + /* Generate code to check constraints and generate index keys and + ** do the insertion. + */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); + sqlite3VtabMakeWritable(pParse, pTab); + sqlite3VdbeAddOp4(v, OP_VUpdate, 1, pTab->nCol+2, regIns, pVTab, P4_VTAB); + sqlite3VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError); + sqlite3MayAbort(pParse); + }else +#endif + { + int isReplace = 0;/* Set to true if constraints may cause a replace */ + int bUseSeek; /* True to use OPFLAG_SEEKRESULT */ + sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur, + regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0, pUpsert + ); + if( db->flags & SQLITE_ForeignKeys ){ + sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0); + } + + /* Set the OPFLAG_USESEEKRESULT flag if either (a) there are no REPLACE + ** constraints or (b) there are no triggers and this table is not a + ** parent table in a foreign key constraint. It is safe to set the + ** flag in the second case as if any REPLACE constraint is hit, an + ** OP_Delete or OP_IdxDelete instruction will be executed on each + ** cursor that is disturbed. And these instructions both clear the + ** VdbeCursor.seekResult variable, disabling the OPFLAG_USESEEKRESULT + ** functionality. */ + bUseSeek = (isReplace==0 || !sqlite3VdbeHasSubProgram(v)); + sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur, + regIns, aRegIdx, 0, appendFlag, bUseSeek + ); + } +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + }else if( pParse->bReturning ){ + /* If there is a RETURNING clause, populate the rowid register with + ** constant value -1, in case one or more of the returned expressions + ** refer to the "rowid" of the view. */ + sqlite3VdbeAddOp2(v, OP_Integer, -1, regRowid); +#endif + } + + /* Update the count of rows that are inserted + */ + if( regRowCount ){ + sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1); + } + + if( pTrigger ){ + /* Code AFTER triggers */ + sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_AFTER, + pTab, regData-2-pTab->nCol, onError, endOfLoop); + } + + /* The bottom of the main insertion loop, if the data source + ** is a SELECT statement. + */ + sqlite3VdbeResolveLabel(v, endOfLoop); + if( useTempTable ){ + sqlite3VdbeAddOp2(v, OP_Next, srcTab, addrCont); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addrInsTop); + sqlite3VdbeAddOp1(v, OP_Close, srcTab); + }else if( pSelect ){ + sqlite3VdbeGoto(v, addrCont); +#ifdef SQLITE_DEBUG + /* If we are jumping back to an OP_Yield that is preceded by an + ** OP_ReleaseReg, set the p5 flag on the OP_Goto so that the + ** OP_ReleaseReg will be included in the loop. */ + if( sqlite3VdbeGetOp(v, addrCont-1)->opcode==OP_ReleaseReg ){ + assert( sqlite3VdbeGetOp(v, addrCont)->opcode==OP_Yield ); + sqlite3VdbeChangeP5(v, 1); + } +#endif + sqlite3VdbeJumpHere(v, addrInsTop); + } + +#ifndef SQLITE_OMIT_XFER_OPT +insert_end: +#endif /* SQLITE_OMIT_XFER_OPT */ + /* Update the sqlite_sequence table by storing the content of the + ** maximum rowid counter values recorded while inserting into + ** autoincrement tables. + */ + if( pParse->nested==0 && pParse->pTriggerTab==0 ){ + sqlite3AutoincrementEnd(pParse); + } + + /* + ** Return the number of rows inserted. If this routine is + ** generating code because of a call to sqlite3NestedParse(), do not + ** invoke the callback function. + */ + if( regRowCount ){ + sqlite3CodeChangeCount(v, regRowCount, "rows inserted"); + } + +insert_cleanup: + sqlite3SrcListDelete(db, pTabList); + sqlite3ExprListDelete(db, pList); + sqlite3UpsertDelete(db, pUpsert); + sqlite3SelectDelete(db, pSelect); + if( pColumn ){ + sqlite3IdListDelete(db, pColumn); + sqlite3DbFree(db, aTabColMap); + } + if( aRegIdx ) sqlite3DbNNFreeNN(db, aRegIdx); +} + +/* Make sure "isView" and other macros defined above are undefined. Otherwise +** they may interfere with compilation of other functions in this file +** (or in another file, if this file becomes part of the amalgamation). */ +#ifdef isView + #undef isView +#endif +#ifdef pTrigger + #undef pTrigger +#endif +#ifdef tmask + #undef tmask +#endif + +/* +** Meanings of bits in of pWalker->eCode for +** sqlite3ExprReferencesUpdatedColumn() +*/ +#define CKCNSTRNT_COLUMN 0x01 /* CHECK constraint uses a changing column */ +#define CKCNSTRNT_ROWID 0x02 /* CHECK constraint references the ROWID */ + +/* This is the Walker callback from sqlite3ExprReferencesUpdatedColumn(). +* Set bit 0x01 of pWalker->eCode if pWalker->eCode to 0 and if this +** expression node references any of the +** columns that are being modified by an UPDATE statement. +*/ +static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_COLUMN ){ + assert( pExpr->iColumn>=0 || pExpr->iColumn==-1 ); + if( pExpr->iColumn>=0 ){ + if( pWalker->u.aiCol[pExpr->iColumn]>=0 ){ + pWalker->eCode |= CKCNSTRNT_COLUMN; + } + }else{ + pWalker->eCode |= CKCNSTRNT_ROWID; + } + } + return WRC_Continue; +} + +/* +** pExpr is a CHECK constraint on a row that is being UPDATE-ed. The +** only columns that are modified by the UPDATE are those for which +** aiChng[i]>=0, and also the ROWID is modified if chngRowid is true. +** +** Return true if CHECK constraint pExpr uses any of the +** changing columns (or the rowid if it is changing). In other words, +** return true if this CHECK constraint must be validated for +** the new row in the UPDATE statement. +** +** 2018-09-15: pExpr might also be an expression for an index-on-expressions. +** The operation of this routine is the same - return true if an only if +** the expression uses one or more of columns identified by the second and +** third arguments. +*/ +SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn( + Expr *pExpr, /* The expression to be checked */ + int *aiChng, /* aiChng[x]>=0 if column x changed by the UPDATE */ + int chngRowid /* True if UPDATE changes the rowid */ +){ + Walker w; + memset(&w, 0, sizeof(w)); + w.eCode = 0; + w.xExprCallback = checkConstraintExprNode; + w.u.aiCol = aiChng; + sqlite3WalkExpr(&w, pExpr); + if( !chngRowid ){ + testcase( (w.eCode & CKCNSTRNT_ROWID)!=0 ); + w.eCode &= ~CKCNSTRNT_ROWID; + } + testcase( w.eCode==0 ); + testcase( w.eCode==CKCNSTRNT_COLUMN ); + testcase( w.eCode==CKCNSTRNT_ROWID ); + testcase( w.eCode==(CKCNSTRNT_ROWID|CKCNSTRNT_COLUMN) ); + return w.eCode!=0; +} + +/* +** The sqlite3GenerateConstraintChecks() routine usually wants to visit +** the indexes of a table in the order provided in the Table->pIndex list. +** However, sometimes (rarely - when there is an upsert) it wants to visit +** the indexes in a different order. The following data structures accomplish +** this. +** +** The IndexIterator object is used to walk through all of the indexes +** of a table in either Index.pNext order, or in some other order established +** by an array of IndexListTerm objects. +*/ +typedef struct IndexListTerm IndexListTerm; +typedef struct IndexIterator IndexIterator; +struct IndexIterator { + int eType; /* 0 for Index.pNext list. 1 for an array of IndexListTerm */ + int i; /* Index of the current item from the list */ + union { + struct { /* Use this object for eType==0: A Index.pNext list */ + Index *pIdx; /* The current Index */ + } lx; + struct { /* Use this object for eType==1; Array of IndexListTerm */ + int nIdx; /* Size of the array */ + IndexListTerm *aIdx; /* Array of IndexListTerms */ + } ax; + } u; +}; + +/* When IndexIterator.eType==1, then each index is an array of instances +** of the following object +*/ +struct IndexListTerm { + Index *p; /* The index */ + int ix; /* Which entry in the original Table.pIndex list is this index*/ +}; + +/* Return the first index on the list */ +static Index *indexIteratorFirst(IndexIterator *pIter, int *pIx){ + assert( pIter->i==0 ); + if( pIter->eType ){ + *pIx = pIter->u.ax.aIdx[0].ix; + return pIter->u.ax.aIdx[0].p; + }else{ + *pIx = 0; + return pIter->u.lx.pIdx; + } +} + +/* Return the next index from the list. Return NULL when out of indexes */ +static Index *indexIteratorNext(IndexIterator *pIter, int *pIx){ + if( pIter->eType ){ + int i = ++pIter->i; + if( i>=pIter->u.ax.nIdx ){ + *pIx = i; + return 0; + } + *pIx = pIter->u.ax.aIdx[i].ix; + return pIter->u.ax.aIdx[i].p; + }else{ + ++(*pIx); + pIter->u.lx.pIdx = pIter->u.lx.pIdx->pNext; + return pIter->u.lx.pIdx; + } +} + +/* +** Generate code to do constraint checks prior to an INSERT or an UPDATE +** on table pTab. +** +** The regNewData parameter is the first register in a range that contains +** the data to be inserted or the data after the update. There will be +** pTab->nCol+1 registers in this range. The first register (the one +** that regNewData points to) will contain the new rowid, or NULL in the +** case of a WITHOUT ROWID table. The second register in the range will +** contain the content of the first table column. The third register will +** contain the content of the second table column. And so forth. +** +** The regOldData parameter is similar to regNewData except that it contains +** the data prior to an UPDATE rather than afterwards. regOldData is zero +** for an INSERT. This routine can distinguish between UPDATE and INSERT by +** checking regOldData for zero. +** +** For an UPDATE, the pkChng boolean is true if the true primary key (the +** rowid for a normal table or the PRIMARY KEY for a WITHOUT ROWID table) +** might be modified by the UPDATE. If pkChng is false, then the key of +** the iDataCur content table is guaranteed to be unchanged by the UPDATE. +** +** For an INSERT, the pkChng boolean indicates whether or not the rowid +** was explicitly specified as part of the INSERT statement. If pkChng +** is zero, it means that the either rowid is computed automatically or +** that the table is a WITHOUT ROWID table and has no rowid. On an INSERT, +** pkChng will only be true if the INSERT statement provides an integer +** value for either the rowid column or its INTEGER PRIMARY KEY alias. +** +** The code generated by this routine will store new index entries into +** registers identified by aRegIdx[]. No index entry is created for +** indices where aRegIdx[i]==0. The order of indices in aRegIdx[] is +** the same as the order of indices on the linked list of indices +** at pTab->pIndex. +** +** (2019-05-07) The generated code also creates a new record for the +** main table, if pTab is a rowid table, and stores that record in the +** register identified by aRegIdx[nIdx] - in other words in the first +** entry of aRegIdx[] past the last index. It is important that the +** record be generated during constraint checks to avoid affinity changes +** to the register content that occur after constraint checks but before +** the new record is inserted. +** +** The caller must have already opened writeable cursors on the main +** table and all applicable indices (that is to say, all indices for which +** aRegIdx[] is not zero). iDataCur is the cursor for the main table when +** inserting or updating a rowid table, or the cursor for the PRIMARY KEY +** index when operating on a WITHOUT ROWID table. iIdxCur is the cursor +** for the first index in the pTab->pIndex list. Cursors for other indices +** are at iIdxCur+N for the N-th element of the pTab->pIndex list. +** +** This routine also generates code to check constraints. NOT NULL, +** CHECK, and UNIQUE constraints are all checked. If a constraint fails, +** then the appropriate action is performed. There are five possible +** actions: ROLLBACK, ABORT, FAIL, REPLACE, and IGNORE. +** +** Constraint type Action What Happens +** --------------- ---------- ---------------------------------------- +** any ROLLBACK The current transaction is rolled back and +** sqlite3_step() returns immediately with a +** return code of SQLITE_CONSTRAINT. +** +** any ABORT Back out changes from the current command +** only (do not do a complete rollback) then +** cause sqlite3_step() to return immediately +** with SQLITE_CONSTRAINT. +** +** any FAIL Sqlite3_step() returns immediately with a +** return code of SQLITE_CONSTRAINT. The +** transaction is not rolled back and any +** changes to prior rows are retained. +** +** any IGNORE The attempt in insert or update the current +** row is skipped, without throwing an error. +** Processing continues with the next row. +** (There is an immediate jump to ignoreDest.) +** +** NOT NULL REPLACE The NULL value is replace by the default +** value for that column. If the default value +** is NULL, the action is the same as ABORT. +** +** UNIQUE REPLACE The other row that conflicts with the row +** being inserted is removed. +** +** CHECK REPLACE Illegal. The results in an exception. +** +** Which action to take is determined by the overrideError parameter. +** Or if overrideError==OE_Default, then the pParse->onError parameter +** is used. Or if pParse->onError==OE_Default then the onError value +** for the constraint is used. +*/ +SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( + Parse *pParse, /* The parser context */ + Table *pTab, /* The table being inserted or updated */ + int *aRegIdx, /* Use register aRegIdx[i] for index i. 0 for unused */ + int iDataCur, /* Canonical data cursor (main table or PK index) */ + int iIdxCur, /* First index cursor */ + int regNewData, /* First register in a range holding values to insert */ + int regOldData, /* Previous content. 0 for INSERTs */ + u8 pkChng, /* Non-zero if the rowid or PRIMARY KEY changed */ + u8 overrideError, /* Override onError to this if not OE_Default */ + int ignoreDest, /* Jump to this label on an OE_Ignore resolution */ + int *pbMayReplace, /* OUT: Set to true if constraint may cause a replace */ + int *aiChng, /* column i is unchanged if aiChng[i]<0 */ + Upsert *pUpsert /* ON CONFLICT clauses, if any. NULL otherwise */ +){ + Vdbe *v; /* VDBE under construction */ + Index *pIdx; /* Pointer to one of the indices */ + Index *pPk = 0; /* The PRIMARY KEY index for WITHOUT ROWID tables */ + sqlite3 *db; /* Database connection */ + int i; /* loop counter */ + int ix; /* Index loop counter */ + int nCol; /* Number of columns */ + int onError; /* Conflict resolution strategy */ + int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */ + int nPkField; /* Number of fields in PRIMARY KEY. 1 for ROWID tables */ + Upsert *pUpsertClause = 0; /* The specific ON CONFLICT clause for pIdx */ + u8 isUpdate; /* True if this is an UPDATE operation */ + u8 bAffinityDone = 0; /* True if the OP_Affinity operation has been run */ + int upsertIpkReturn = 0; /* Address of Goto at end of IPK uniqueness check */ + int upsertIpkDelay = 0; /* Address of Goto to bypass initial IPK check */ + int ipkTop = 0; /* Top of the IPK uniqueness check */ + int ipkBottom = 0; /* OP_Goto at the end of the IPK uniqueness check */ + /* Variables associated with retesting uniqueness constraints after + ** replace triggers fire have run */ + int regTrigCnt; /* Register used to count replace trigger invocations */ + int addrRecheck = 0; /* Jump here to recheck all uniqueness constraints */ + int lblRecheckOk = 0; /* Each recheck jumps to this label if it passes */ + Trigger *pTrigger; /* List of DELETE triggers on the table pTab */ + int nReplaceTrig = 0; /* Number of replace triggers coded */ + IndexIterator sIdxIter; /* Index iterator */ + + isUpdate = regOldData!=0; + db = pParse->db; + v = pParse->pVdbe; + assert( v!=0 ); + assert( !IsView(pTab) ); /* This table is not a VIEW */ + nCol = pTab->nCol; + + /* pPk is the PRIMARY KEY index for WITHOUT ROWID tables and NULL for + ** normal rowid tables. nPkField is the number of key fields in the + ** pPk index or 1 for a rowid table. In other words, nPkField is the + ** number of fields in the true primary key of the table. */ + if( HasRowid(pTab) ){ + pPk = 0; + nPkField = 1; + }else{ + pPk = sqlite3PrimaryKeyIndex(pTab); + nPkField = pPk->nKeyCol; + } + + /* Record that this module has started */ + VdbeModuleComment((v, "BEGIN: GenCnstCks(%d,%d,%d,%d,%d)", + iDataCur, iIdxCur, regNewData, regOldData, pkChng)); + + /* Test all NOT NULL constraints. + */ + if( pTab->tabFlags & TF_HasNotNull ){ + int b2ndPass = 0; /* True if currently running 2nd pass */ + int nSeenReplace = 0; /* Number of ON CONFLICT REPLACE operations */ + int nGenerated = 0; /* Number of generated columns with NOT NULL */ + while(1){ /* Make 2 passes over columns. Exit loop via "break" */ + for(i=0; iaCol[i]; /* The column to check for NOT NULL */ + int isGenerated; /* non-zero if column is generated */ + onError = pCol->notNull; + if( onError==OE_None ) continue; /* No NOT NULL on this column */ + if( i==pTab->iPKey ){ + continue; /* ROWID is never NULL */ + } + isGenerated = pCol->colFlags & COLFLAG_GENERATED; + if( isGenerated && !b2ndPass ){ + nGenerated++; + continue; /* Generated columns processed on 2nd pass */ + } + if( aiChng && aiChng[i]<0 && !isGenerated ){ + /* Do not check NOT NULL on columns that do not change */ + continue; + } + if( overrideError!=OE_Default ){ + onError = overrideError; + }else if( onError==OE_Default ){ + onError = OE_Abort; + } + if( onError==OE_Replace ){ + if( b2ndPass /* REPLACE becomes ABORT on the 2nd pass */ + || pCol->iDflt==0 /* REPLACE is ABORT if no DEFAULT value */ + ){ + testcase( pCol->colFlags & COLFLAG_VIRTUAL ); + testcase( pCol->colFlags & COLFLAG_STORED ); + testcase( pCol->colFlags & COLFLAG_GENERATED ); + onError = OE_Abort; + }else{ + assert( !isGenerated ); + } + }else if( b2ndPass && !isGenerated ){ + continue; + } + assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail + || onError==OE_Ignore || onError==OE_Replace ); + testcase( i!=sqlite3TableColumnToStorage(pTab, i) ); + iReg = sqlite3TableColumnToStorage(pTab, i) + regNewData + 1; + switch( onError ){ + case OE_Replace: { + int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, iReg); + VdbeCoverage(v); + assert( (pCol->colFlags & COLFLAG_GENERATED)==0 ); + nSeenReplace++; + sqlite3ExprCodeCopy(pParse, + sqlite3ColumnExpr(pTab, pCol), iReg); + sqlite3VdbeJumpHere(v, addr1); + break; + } + case OE_Abort: + sqlite3MayAbort(pParse); + /* no break */ deliberate_fall_through + case OE_Rollback: + case OE_Fail: { + char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName, + pCol->zCnName); + testcase( zMsg==0 && db->mallocFailed==0 ); + sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, + onError, iReg); + sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC); + sqlite3VdbeChangeP5(v, P5_ConstraintNotNull); + VdbeCoverage(v); + break; + } + default: { + assert( onError==OE_Ignore ); + sqlite3VdbeAddOp2(v, OP_IsNull, iReg, ignoreDest); + VdbeCoverage(v); + break; + } + } /* end switch(onError) */ + } /* end loop i over columns */ + if( nGenerated==0 && nSeenReplace==0 ){ + /* If there are no generated columns with NOT NULL constraints + ** and no NOT NULL ON CONFLICT REPLACE constraints, then a single + ** pass is sufficient */ + break; + } + if( b2ndPass ) break; /* Never need more than 2 passes */ + b2ndPass = 1; +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + if( nSeenReplace>0 && (pTab->tabFlags & TF_HasGenerated)!=0 ){ + /* If any NOT NULL ON CONFLICT REPLACE constraints fired on the + ** first pass, recomputed values for all generated columns, as + ** those values might depend on columns affected by the REPLACE. + */ + sqlite3ComputeGeneratedColumns(pParse, regNewData+1, pTab); + } +#endif + } /* end of 2-pass loop */ + } /* end if( has-not-null-constraints ) */ + + /* Test all CHECK constraints + */ +#ifndef SQLITE_OMIT_CHECK + if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){ + ExprList *pCheck = pTab->pCheck; + pParse->iSelfTab = -(regNewData+1); + onError = overrideError!=OE_Default ? overrideError : OE_Abort; + for(i=0; inExpr; i++){ + int allOk; + Expr *pCopy; + Expr *pExpr = pCheck->a[i].pExpr; + if( aiChng + && !sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, pkChng) + ){ + /* The check constraints do not reference any of the columns being + ** updated so there is no point it verifying the check constraint */ + continue; + } + if( bAffinityDone==0 ){ + sqlite3TableAffinity(v, pTab, regNewData+1); + bAffinityDone = 1; + } + allOk = sqlite3VdbeMakeLabel(pParse); + sqlite3VdbeVerifyAbortable(v, onError); + pCopy = sqlite3ExprDup(db, pExpr, 0); + if( !db->mallocFailed ){ + sqlite3ExprIfTrue(pParse, pCopy, allOk, SQLITE_JUMPIFNULL); + } + sqlite3ExprDelete(db, pCopy); + if( onError==OE_Ignore ){ + sqlite3VdbeGoto(v, ignoreDest); + }else{ + char *zName = pCheck->a[i].zEName; + assert( zName!=0 || pParse->db->mallocFailed ); + if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-26383-51744 */ + sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_CHECK, + onError, zName, P4_TRANSIENT, + P5_ConstraintCheck); + } + sqlite3VdbeResolveLabel(v, allOk); + } + pParse->iSelfTab = 0; + } +#endif /* !defined(SQLITE_OMIT_CHECK) */ + + /* UNIQUE and PRIMARY KEY constraints should be handled in the following + ** order: + ** + ** (1) OE_Update + ** (2) OE_Abort, OE_Fail, OE_Rollback, OE_Ignore + ** (3) OE_Replace + ** + ** OE_Fail and OE_Ignore must happen before any changes are made. + ** OE_Update guarantees that only a single row will change, so it + ** must happen before OE_Replace. Technically, OE_Abort and OE_Rollback + ** could happen in any order, but they are grouped up front for + ** convenience. + ** + ** 2018-08-14: Ticket https://sqlite.org/src/info/908f001483982c43 + ** The order of constraints used to have OE_Update as (2) and OE_Abort + ** and so forth as (1). But apparently PostgreSQL checks the OE_Update + ** constraint before any others, so it had to be moved. + ** + ** Constraint checking code is generated in this order: + ** (A) The rowid constraint + ** (B) Unique index constraints that do not have OE_Replace as their + ** default conflict resolution strategy + ** (C) Unique index that do use OE_Replace by default. + ** + ** The ordering of (2) and (3) is accomplished by making sure the linked + ** list of indexes attached to a table puts all OE_Replace indexes last + ** in the list. See sqlite3CreateIndex() for where that happens. + */ + sIdxIter.eType = 0; + sIdxIter.i = 0; + sIdxIter.u.ax.aIdx = 0; /* Silence harmless compiler warning */ + sIdxIter.u.lx.pIdx = pTab->pIndex; + if( pUpsert ){ + if( pUpsert->pUpsertTarget==0 ){ + /* There is just on ON CONFLICT clause and it has no constraint-target */ + assert( pUpsert->pNextUpsert==0 ); + if( pUpsert->isDoUpdate==0 ){ + /* A single ON CONFLICT DO NOTHING clause, without a constraint-target. + ** Make all unique constraint resolution be OE_Ignore */ + overrideError = OE_Ignore; + pUpsert = 0; + }else{ + /* A single ON CONFLICT DO UPDATE. Make all resolutions OE_Update */ + overrideError = OE_Update; + } + }else if( pTab->pIndex!=0 ){ + /* Otherwise, we'll need to run the IndexListTerm array version of the + ** iterator to ensure that all of the ON CONFLICT conditions are + ** checked first and in order. */ + int nIdx, jj; + u64 nByte; + Upsert *pTerm; + u8 *bUsed; + for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ + assert( aRegIdx[nIdx]>0 ); + } + sIdxIter.eType = 1; + sIdxIter.u.ax.nIdx = nIdx; + nByte = (sizeof(IndexListTerm)+1)*nIdx + nIdx; + sIdxIter.u.ax.aIdx = sqlite3DbMallocZero(db, nByte); + if( sIdxIter.u.ax.aIdx==0 ) return; /* OOM */ + bUsed = (u8*)&sIdxIter.u.ax.aIdx[nIdx]; + pUpsert->pToFree = sIdxIter.u.ax.aIdx; + for(i=0, pTerm=pUpsert; pTerm; pTerm=pTerm->pNextUpsert){ + if( pTerm->pUpsertTarget==0 ) break; + if( pTerm->pUpsertIdx==0 ) continue; /* Skip ON CONFLICT for the IPK */ + jj = 0; + pIdx = pTab->pIndex; + while( ALWAYS(pIdx!=0) && pIdx!=pTerm->pUpsertIdx ){ + pIdx = pIdx->pNext; + jj++; + } + if( bUsed[jj] ) continue; /* Duplicate ON CONFLICT clause ignored */ + bUsed[jj] = 1; + sIdxIter.u.ax.aIdx[i].p = pIdx; + sIdxIter.u.ax.aIdx[i].ix = jj; + i++; + } + for(jj=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, jj++){ + if( bUsed[jj] ) continue; + sIdxIter.u.ax.aIdx[i].p = pIdx; + sIdxIter.u.ax.aIdx[i].ix = jj; + i++; + } + assert( i==nIdx ); + } + } + + /* Determine if it is possible that triggers (either explicitly coded + ** triggers or FK resolution actions) might run as a result of deletes + ** that happen when OE_Replace conflict resolution occurs. (Call these + ** "replace triggers".) If any replace triggers run, we will need to + ** recheck all of the uniqueness constraints after they have all run. + ** But on the recheck, the resolution is OE_Abort instead of OE_Replace. + ** + ** If replace triggers are a possibility, then + ** + ** (1) Allocate register regTrigCnt and initialize it to zero. + ** That register will count the number of replace triggers that + ** fire. Constraint recheck only occurs if the number is positive. + ** (2) Initialize pTrigger to the list of all DELETE triggers on pTab. + ** (3) Initialize addrRecheck and lblRecheckOk + ** + ** The uniqueness rechecking code will create a series of tests to run + ** in a second pass. The addrRecheck and lblRecheckOk variables are + ** used to link together these tests which are separated from each other + ** in the generate bytecode. + */ + if( (db->flags & (SQLITE_RecTriggers|SQLITE_ForeignKeys))==0 ){ + /* There are not DELETE triggers nor FK constraints. No constraint + ** rechecks are needed. */ + pTrigger = 0; + regTrigCnt = 0; + }else{ + if( db->flags&SQLITE_RecTriggers ){ + pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); + regTrigCnt = pTrigger!=0 || sqlite3FkRequired(pParse, pTab, 0, 0); + }else{ + pTrigger = 0; + regTrigCnt = sqlite3FkRequired(pParse, pTab, 0, 0); + } + if( regTrigCnt ){ + /* Replace triggers might exist. Allocate the counter and + ** initialize it to zero. */ + regTrigCnt = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 0, regTrigCnt); + VdbeComment((v, "trigger count")); + lblRecheckOk = sqlite3VdbeMakeLabel(pParse); + addrRecheck = lblRecheckOk; + } + } + + /* If rowid is changing, make sure the new rowid does not previously + ** exist in the table. + */ + if( pkChng && pPk==0 ){ + int addrRowidOk = sqlite3VdbeMakeLabel(pParse); + + /* Figure out what action to take in case of a rowid collision */ + onError = pTab->keyConf; + if( overrideError!=OE_Default ){ + onError = overrideError; + }else if( onError==OE_Default ){ + onError = OE_Abort; + } + + /* figure out whether or not upsert applies in this case */ + if( pUpsert ){ + pUpsertClause = sqlite3UpsertOfIndex(pUpsert,0); + if( pUpsertClause!=0 ){ + if( pUpsertClause->isDoUpdate==0 ){ + onError = OE_Ignore; /* DO NOTHING is the same as INSERT OR IGNORE */ + }else{ + onError = OE_Update; /* DO UPDATE */ + } + } + if( pUpsertClause!=pUpsert ){ + /* The first ON CONFLICT clause has a conflict target other than + ** the IPK. We have to jump ahead to that first ON CONFLICT clause + ** and then come back here and deal with the IPK afterwards */ + upsertIpkDelay = sqlite3VdbeAddOp0(v, OP_Goto); + } + } + + /* If the response to a rowid conflict is REPLACE but the response + ** to some other UNIQUE constraint is FAIL or IGNORE, then we need + ** to defer the running of the rowid conflict checking until after + ** the UNIQUE constraints have run. + */ + if( onError==OE_Replace /* IPK rule is REPLACE */ + && onError!=overrideError /* Rules for other constraints are different */ + && pTab->pIndex /* There exist other constraints */ + && !upsertIpkDelay /* IPK check already deferred by UPSERT */ + ){ + ipkTop = sqlite3VdbeAddOp0(v, OP_Goto)+1; + VdbeComment((v, "defer IPK REPLACE until last")); + } + + if( isUpdate ){ + /* pkChng!=0 does not mean that the rowid has changed, only that + ** it might have changed. Skip the conflict logic below if the rowid + ** is unchanged. */ + sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); + VdbeCoverage(v); + } + + /* Check to see if the new rowid already exists in the table. Skip + ** the following conflict logic if it does not. */ + VdbeNoopComment((v, "uniqueness check for ROWID")); + sqlite3VdbeVerifyAbortable(v, onError); + sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData); + VdbeCoverage(v); + + switch( onError ){ + default: { + onError = OE_Abort; + /* no break */ deliberate_fall_through + } + case OE_Rollback: + case OE_Abort: + case OE_Fail: { + testcase( onError==OE_Rollback ); + testcase( onError==OE_Abort ); + testcase( onError==OE_Fail ); + sqlite3RowidConstraint(pParse, onError, pTab); + break; + } + case OE_Replace: { + /* If there are DELETE triggers on this table and the + ** recursive-triggers flag is set, call GenerateRowDelete() to + ** remove the conflicting row from the table. This will fire + ** the triggers and remove both the table and index b-tree entries. + ** + ** Otherwise, if there are no triggers or the recursive-triggers + ** flag is not set, but the table has one or more indexes, call + ** GenerateRowIndexDelete(). This removes the index b-tree entries + ** only. The table b-tree entry will be replaced by the new entry + ** when it is inserted. + ** + ** If either GenerateRowDelete() or GenerateRowIndexDelete() is called, + ** also invoke MultiWrite() to indicate that this VDBE may require + ** statement rollback (if the statement is aborted after the delete + ** takes place). Earlier versions called sqlite3MultiWrite() regardless, + ** but being more selective here allows statements like: + ** + ** REPLACE INTO t(rowid) VALUES($newrowid) + ** + ** to run without a statement journal if there are no indexes on the + ** table. + */ + if( regTrigCnt ){ + sqlite3MultiWrite(pParse); + sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, + regNewData, 1, 0, OE_Replace, 1, -1); + sqlite3VdbeAddOp2(v, OP_AddImm, regTrigCnt, 1); /* incr trigger cnt */ + nReplaceTrig++; + }else{ +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + assert( HasRowid(pTab) ); + /* This OP_Delete opcode fires the pre-update-hook only. It does + ** not modify the b-tree. It is more efficient to let the coming + ** OP_Insert replace the existing entry than it is to delete the + ** existing entry and then insert a new one. */ + sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, OPFLAG_ISNOOP); + sqlite3VdbeAppendP4(v, pTab, P4_TABLE); +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ + if( pTab->pIndex ){ + sqlite3MultiWrite(pParse); + sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,-1); + } + } + seenReplace = 1; + break; + } +#ifndef SQLITE_OMIT_UPSERT + case OE_Update: { + sqlite3UpsertDoUpdate(pParse, pUpsert, pTab, 0, iDataCur); + /* no break */ deliberate_fall_through + } +#endif + case OE_Ignore: { + testcase( onError==OE_Ignore ); + sqlite3VdbeGoto(v, ignoreDest); + break; + } + } + sqlite3VdbeResolveLabel(v, addrRowidOk); + if( pUpsert && pUpsertClause!=pUpsert ){ + upsertIpkReturn = sqlite3VdbeAddOp0(v, OP_Goto); + }else if( ipkTop ){ + ipkBottom = sqlite3VdbeAddOp0(v, OP_Goto); + sqlite3VdbeJumpHere(v, ipkTop-1); + } + } + + /* Test all UNIQUE constraints by creating entries for each UNIQUE + ** index and making sure that duplicate entries do not already exist. + ** Compute the revised record entries for indices as we go. + ** + ** This loop also handles the case of the PRIMARY KEY index for a + ** WITHOUT ROWID table. + */ + for(pIdx = indexIteratorFirst(&sIdxIter, &ix); + pIdx; + pIdx = indexIteratorNext(&sIdxIter, &ix) + ){ + int regIdx; /* Range of registers holding content for pIdx */ + int regR; /* Range of registers holding conflicting PK */ + int iThisCur; /* Cursor for this UNIQUE index */ + int addrUniqueOk; /* Jump here if the UNIQUE constraint is satisfied */ + int addrConflictCk; /* First opcode in the conflict check logic */ + + if( aRegIdx[ix]==0 ) continue; /* Skip indices that do not change */ + if( pUpsert ){ + pUpsertClause = sqlite3UpsertOfIndex(pUpsert, pIdx); + if( upsertIpkDelay && pUpsertClause==pUpsert ){ + sqlite3VdbeJumpHere(v, upsertIpkDelay); + } + } + addrUniqueOk = sqlite3VdbeMakeLabel(pParse); + if( bAffinityDone==0 ){ + sqlite3TableAffinity(v, pTab, regNewData+1); + bAffinityDone = 1; + } + VdbeNoopComment((v, "prep index %s", pIdx->zName)); + iThisCur = iIdxCur+ix; + + + /* Skip partial indices for which the WHERE clause is not true */ + if( pIdx->pPartIdxWhere ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[ix]); + pParse->iSelfTab = -(regNewData+1); + sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, addrUniqueOk, + SQLITE_JUMPIFNULL); + pParse->iSelfTab = 0; + } + + /* Create a record for this index entry as it should appear after + ** the insert or update. Store that record in the aRegIdx[ix] register + */ + regIdx = aRegIdx[ix]+1; + for(i=0; inColumn; i++){ + int iField = pIdx->aiColumn[i]; + int x; + if( iField==XN_EXPR ){ + pParse->iSelfTab = -(regNewData+1); + sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[i].pExpr, regIdx+i); + pParse->iSelfTab = 0; + VdbeComment((v, "%s column %d", pIdx->zName, i)); + }else if( iField==XN_ROWID || iField==pTab->iPKey ){ + x = regNewData; + sqlite3VdbeAddOp2(v, OP_IntCopy, x, regIdx+i); + VdbeComment((v, "rowid")); + }else{ + testcase( sqlite3TableColumnToStorage(pTab, iField)!=iField ); + x = sqlite3TableColumnToStorage(pTab, iField) + regNewData + 1; + sqlite3VdbeAddOp2(v, OP_SCopy, x, regIdx+i); + VdbeComment((v, "%s", pTab->aCol[iField].zCnName)); + } + } + sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]); + VdbeComment((v, "for %s", pIdx->zName)); +#ifdef SQLITE_ENABLE_NULL_TRIM + if( pIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){ + sqlite3SetMakeRecordP5(v, pIdx->pTable); + } +#endif + sqlite3VdbeReleaseRegisters(pParse, regIdx, pIdx->nColumn, 0, 0); + + /* In an UPDATE operation, if this index is the PRIMARY KEY index + ** of a WITHOUT ROWID table and there has been no change the + ** primary key, then no collision is possible. The collision detection + ** logic below can all be skipped. */ + if( isUpdate && pPk==pIdx && pkChng==0 ){ + sqlite3VdbeResolveLabel(v, addrUniqueOk); + continue; + } + + /* Find out what action to take in case there is a uniqueness conflict */ + onError = pIdx->onError; + if( onError==OE_None ){ + sqlite3VdbeResolveLabel(v, addrUniqueOk); + continue; /* pIdx is not a UNIQUE index */ + } + if( overrideError!=OE_Default ){ + onError = overrideError; + }else if( onError==OE_Default ){ + onError = OE_Abort; + } + + /* Figure out if the upsert clause applies to this index */ + if( pUpsertClause ){ + if( pUpsertClause->isDoUpdate==0 ){ + onError = OE_Ignore; /* DO NOTHING is the same as INSERT OR IGNORE */ + }else{ + onError = OE_Update; /* DO UPDATE */ + } + } + + /* Collision detection may be omitted if all of the following are true: + ** (1) The conflict resolution algorithm is REPLACE + ** (2) The table is a WITHOUT ROWID table + ** (3) There are no secondary indexes on the table + ** (4) No delete triggers need to be fired if there is a conflict + ** (5) No FK constraint counters need to be updated if a conflict occurs. + ** + ** This is not possible for ENABLE_PREUPDATE_HOOK builds, as the row + ** must be explicitly deleted in order to ensure any pre-update hook + ** is invoked. */ + assert( IsOrdinaryTable(pTab) ); +#ifndef SQLITE_ENABLE_PREUPDATE_HOOK + if( (ix==0 && pIdx->pNext==0) /* Condition 3 */ + && pPk==pIdx /* Condition 2 */ + && onError==OE_Replace /* Condition 1 */ + && ( 0==(db->flags&SQLITE_RecTriggers) || /* Condition 4 */ + 0==sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0)) + && ( 0==(db->flags&SQLITE_ForeignKeys) || /* Condition 5 */ + (0==pTab->u.tab.pFKey && 0==sqlite3FkReferences(pTab))) + ){ + sqlite3VdbeResolveLabel(v, addrUniqueOk); + continue; + } +#endif /* ifndef SQLITE_ENABLE_PREUPDATE_HOOK */ + + /* Check to see if the new index entry will be unique */ + sqlite3VdbeVerifyAbortable(v, onError); + addrConflictCk = + sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk, + regIdx, pIdx->nKeyCol); VdbeCoverage(v); + + /* Generate code to handle collisions */ + regR = pIdx==pPk ? regIdx : sqlite3GetTempRange(pParse, nPkField); + if( isUpdate || onError==OE_Replace ){ + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp2(v, OP_IdxRowid, iThisCur, regR); + /* Conflict only if the rowid of the existing index entry + ** is different from old-rowid */ + if( isUpdate ){ + sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); + VdbeCoverage(v); + } + }else{ + int x; + /* Extract the PRIMARY KEY from the end of the index entry and + ** store it in registers regR..regR+nPk-1 */ + if( pIdx!=pPk ){ + for(i=0; inKeyCol; i++){ + assert( pPk->aiColumn[i]>=0 ); + x = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[i]); + sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i); + VdbeComment((v, "%s.%s", pTab->zName, + pTab->aCol[pPk->aiColumn[i]].zCnName)); + } + } + if( isUpdate ){ + /* If currently processing the PRIMARY KEY of a WITHOUT ROWID + ** table, only conflict if the new PRIMARY KEY values are actually + ** different from the old. See TH3 withoutrowid04.test. + ** + ** For a UNIQUE index, only conflict if the PRIMARY KEY values + ** of the matched index row are different from the original PRIMARY + ** KEY values of this row before the update. */ + int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol; + int op = OP_Ne; + int regCmp = (IsPrimaryKeyIndex(pIdx) ? regIdx : regR); + + for(i=0; inKeyCol; i++){ + char *p4 = (char*)sqlite3LocateCollSeq(pParse, pPk->azColl[i]); + x = pPk->aiColumn[i]; + assert( x>=0 ); + if( i==(pPk->nKeyCol-1) ){ + addrJump = addrUniqueOk; + op = OP_Eq; + } + x = sqlite3TableColumnToStorage(pTab, x); + sqlite3VdbeAddOp4(v, op, + regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ + ); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); + VdbeCoverageIf(v, op==OP_Eq); + VdbeCoverageIf(v, op==OP_Ne); + } + } + } + } + + /* Generate code that executes if the new index entry is not unique */ + assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail + || onError==OE_Ignore || onError==OE_Replace || onError==OE_Update ); + switch( onError ){ + case OE_Rollback: + case OE_Abort: + case OE_Fail: { + testcase( onError==OE_Rollback ); + testcase( onError==OE_Abort ); + testcase( onError==OE_Fail ); + sqlite3UniqueConstraint(pParse, onError, pIdx); + break; + } +#ifndef SQLITE_OMIT_UPSERT + case OE_Update: { + sqlite3UpsertDoUpdate(pParse, pUpsert, pTab, pIdx, iIdxCur+ix); + /* no break */ deliberate_fall_through + } +#endif + case OE_Ignore: { + testcase( onError==OE_Ignore ); + sqlite3VdbeGoto(v, ignoreDest); + break; + } + default: { + int nConflictCk; /* Number of opcodes in conflict check logic */ + + assert( onError==OE_Replace ); + nConflictCk = sqlite3VdbeCurrentAddr(v) - addrConflictCk; + assert( nConflictCk>0 || db->mallocFailed ); + testcase( nConflictCk<=0 ); + testcase( nConflictCk>1 ); + if( regTrigCnt ){ + sqlite3MultiWrite(pParse); + nReplaceTrig++; + } + if( pTrigger && isUpdate ){ + sqlite3VdbeAddOp1(v, OP_CursorLock, iDataCur); + } + sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, + regR, nPkField, 0, OE_Replace, + (pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), iThisCur); + if( pTrigger && isUpdate ){ + sqlite3VdbeAddOp1(v, OP_CursorUnlock, iDataCur); + } + if( regTrigCnt ){ + int addrBypass; /* Jump destination to bypass recheck logic */ + + sqlite3VdbeAddOp2(v, OP_AddImm, regTrigCnt, 1); /* incr trigger cnt */ + addrBypass = sqlite3VdbeAddOp0(v, OP_Goto); /* Bypass recheck */ + VdbeComment((v, "bypass recheck")); + + /* Here we insert code that will be invoked after all constraint + ** checks have run, if and only if one or more replace triggers + ** fired. */ + sqlite3VdbeResolveLabel(v, lblRecheckOk); + lblRecheckOk = sqlite3VdbeMakeLabel(pParse); + if( pIdx->pPartIdxWhere ){ + /* Bypass the recheck if this partial index is not defined + ** for the current row */ + sqlite3VdbeAddOp2(v, OP_IsNull, regIdx-1, lblRecheckOk); + VdbeCoverage(v); + } + /* Copy the constraint check code from above, except change + ** the constraint-ok jump destination to be the address of + ** the next retest block */ + while( nConflictCk>0 ){ + VdbeOp x; /* Conflict check opcode to copy */ + /* The sqlite3VdbeAddOp4() call might reallocate the opcode array. + ** Hence, make a complete copy of the opcode, rather than using + ** a pointer to the opcode. */ + x = *sqlite3VdbeGetOp(v, addrConflictCk); + if( x.opcode!=OP_IdxRowid ){ + int p2; /* New P2 value for copied conflict check opcode */ + const char *zP4; + if( sqlite3OpcodeProperty[x.opcode]&OPFLG_JUMP ){ + p2 = lblRecheckOk; + }else{ + p2 = x.p2; + } + zP4 = x.p4type==P4_INT32 ? SQLITE_INT_TO_PTR(x.p4.i) : x.p4.z; + sqlite3VdbeAddOp4(v, x.opcode, x.p1, p2, x.p3, zP4, x.p4type); + sqlite3VdbeChangeP5(v, x.p5); + VdbeCoverageIf(v, p2!=x.p2); + } + nConflictCk--; + addrConflictCk++; + } + /* If the retest fails, issue an abort */ + sqlite3UniqueConstraint(pParse, OE_Abort, pIdx); + + sqlite3VdbeJumpHere(v, addrBypass); /* Terminate the recheck bypass */ + } + seenReplace = 1; + break; + } + } + sqlite3VdbeResolveLabel(v, addrUniqueOk); + if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField); + if( pUpsertClause + && upsertIpkReturn + && sqlite3UpsertNextIsIPK(pUpsertClause) + ){ + sqlite3VdbeGoto(v, upsertIpkDelay+1); + sqlite3VdbeJumpHere(v, upsertIpkReturn); + upsertIpkReturn = 0; + } + } + + /* If the IPK constraint is a REPLACE, run it last */ + if( ipkTop ){ + sqlite3VdbeGoto(v, ipkTop); + VdbeComment((v, "Do IPK REPLACE")); + assert( ipkBottom>0 ); + sqlite3VdbeJumpHere(v, ipkBottom); + } + + /* Recheck all uniqueness constraints after replace triggers have run */ + testcase( regTrigCnt!=0 && nReplaceTrig==0 ); + assert( regTrigCnt!=0 || nReplaceTrig==0 ); + if( nReplaceTrig ){ + sqlite3VdbeAddOp2(v, OP_IfNot, regTrigCnt, lblRecheckOk);VdbeCoverage(v); + if( !pPk ){ + if( isUpdate ){ + sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRecheck, regOldData); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); + VdbeCoverage(v); + } + sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRecheck, regNewData); + VdbeCoverage(v); + sqlite3RowidConstraint(pParse, OE_Abort, pTab); + }else{ + sqlite3VdbeGoto(v, addrRecheck); + } + sqlite3VdbeResolveLabel(v, lblRecheckOk); + } + + /* Generate the table record */ + if( HasRowid(pTab) ){ + int regRec = aRegIdx[ix]; + sqlite3VdbeAddOp3(v, OP_MakeRecord, regNewData+1, pTab->nNVCol, regRec); + sqlite3SetMakeRecordP5(v, pTab); + if( !bAffinityDone ){ + sqlite3TableAffinity(v, pTab, 0); + } + } + + *pbMayReplace = seenReplace; + VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace)); +} + +#ifdef SQLITE_ENABLE_NULL_TRIM +/* +** Change the P5 operand on the last opcode (which should be an OP_MakeRecord) +** to be the number of columns in table pTab that must not be NULL-trimmed. +** +** Or if no columns of pTab may be NULL-trimmed, leave P5 at zero. +*/ +SQLITE_PRIVATE void sqlite3SetMakeRecordP5(Vdbe *v, Table *pTab){ + u16 i; + + /* Records with omitted columns are only allowed for schema format + ** version 2 and later (SQLite version 3.1.4, 2005-02-20). */ + if( pTab->pSchema->file_format<2 ) return; + + for(i=pTab->nCol-1; i>0; i--){ + if( pTab->aCol[i].iDflt!=0 ) break; + if( pTab->aCol[i].colFlags & COLFLAG_PRIMKEY ) break; + } + sqlite3VdbeChangeP5(v, i+1); +} +#endif + +/* +** Table pTab is a WITHOUT ROWID table that is being written to. The cursor +** number is iCur, and register regData contains the new record for the +** PK index. This function adds code to invoke the pre-update hook, +** if one is registered. +*/ +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +static void codeWithoutRowidPreupdate( + Parse *pParse, /* Parse context */ + Table *pTab, /* Table being updated */ + int iCur, /* Cursor number for table */ + int regData /* Data containing new record */ +){ + Vdbe *v = pParse->pVdbe; + int r = sqlite3GetTempReg(pParse); + assert( !HasRowid(pTab) ); + assert( 0==(pParse->db->mDbFlags & DBFLAG_Vacuum) || CORRUPT_DB ); + sqlite3VdbeAddOp2(v, OP_Integer, 0, r); + sqlite3VdbeAddOp4(v, OP_Insert, iCur, regData, r, (char*)pTab, P4_TABLE); + sqlite3VdbeChangeP5(v, OPFLAG_ISNOOP); + sqlite3ReleaseTempReg(pParse, r); +} +#else +# define codeWithoutRowidPreupdate(a,b,c,d) +#endif + +/* +** This routine generates code to finish the INSERT or UPDATE operation +** that was started by a prior call to sqlite3GenerateConstraintChecks. +** A consecutive range of registers starting at regNewData contains the +** rowid and the content to be inserted. +** +** The arguments to this routine should be the same as the first six +** arguments to sqlite3GenerateConstraintChecks. +*/ +SQLITE_PRIVATE void sqlite3CompleteInsertion( + Parse *pParse, /* The parser context */ + Table *pTab, /* the table into which we are inserting */ + int iDataCur, /* Cursor of the canonical data source */ + int iIdxCur, /* First index cursor */ + int regNewData, /* Range of content */ + int *aRegIdx, /* Register used by each index. 0 for unused indices */ + int update_flags, /* True for UPDATE, False for INSERT */ + int appendBias, /* True if this is likely to be an append */ + int useSeekResult /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */ +){ + Vdbe *v; /* Prepared statements under construction */ + Index *pIdx; /* An index being inserted or updated */ + u8 pik_flags; /* flag values passed to the btree insert */ + int i; /* Loop counter */ + + assert( update_flags==0 + || update_flags==OPFLAG_ISUPDATE + || update_flags==(OPFLAG_ISUPDATE|OPFLAG_SAVEPOSITION) + ); + + v = pParse->pVdbe; + assert( v!=0 ); + assert( !IsView(pTab) ); /* This table is not a VIEW */ + for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ + /* All REPLACE indexes are at the end of the list */ + assert( pIdx->onError!=OE_Replace + || pIdx->pNext==0 + || pIdx->pNext->onError==OE_Replace ); + if( aRegIdx[i]==0 ) continue; + if( pIdx->pPartIdxWhere ){ + sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); + } + pik_flags = (useSeekResult ? OPFLAG_USESEEKRESULT : 0); + if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ + pik_flags |= OPFLAG_NCHANGE; + pik_flags |= (update_flags & OPFLAG_SAVEPOSITION); + if( update_flags==0 ){ + codeWithoutRowidPreupdate(pParse, pTab, iIdxCur+i, aRegIdx[i]); + } + } + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i], + aRegIdx[i]+1, + pIdx->uniqNotNull ? pIdx->nKeyCol: pIdx->nColumn); + sqlite3VdbeChangeP5(v, pik_flags); + } + if( !HasRowid(pTab) ) return; + if( pParse->nested ){ + pik_flags = 0; + }else{ + pik_flags = OPFLAG_NCHANGE; + pik_flags |= (update_flags?update_flags:OPFLAG_LASTROWID); + } + if( appendBias ){ + pik_flags |= OPFLAG_APPEND; + } + if( useSeekResult ){ + pik_flags |= OPFLAG_USESEEKRESULT; + } + sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, aRegIdx[i], regNewData); + if( !pParse->nested ){ + sqlite3VdbeAppendP4(v, pTab, P4_TABLE); + } + sqlite3VdbeChangeP5(v, pik_flags); +} + +/* +** Allocate cursors for the pTab table and all its indices and generate +** code to open and initialized those cursors. +** +** The cursor for the object that contains the complete data (normally +** the table itself, but the PRIMARY KEY index in the case of a WITHOUT +** ROWID table) is returned in *piDataCur. The first index cursor is +** returned in *piIdxCur. The number of indices is returned. +** +** Use iBase as the first cursor (either the *piDataCur for rowid tables +** or the first index for WITHOUT ROWID tables) if it is non-negative. +** If iBase is negative, then allocate the next available cursor. +** +** For a rowid table, *piDataCur will be exactly one less than *piIdxCur. +** For a WITHOUT ROWID table, *piDataCur will be somewhere in the range +** of *piIdxCurs, depending on where the PRIMARY KEY index appears on the +** pTab->pIndex list. +** +** If pTab is a virtual table, then this routine is a no-op and the +** *piDataCur and *piIdxCur values are left uninitialized. +*/ +SQLITE_PRIVATE int sqlite3OpenTableAndIndices( + Parse *pParse, /* Parsing context */ + Table *pTab, /* Table to be opened */ + int op, /* OP_OpenRead or OP_OpenWrite */ + u8 p5, /* P5 value for OP_Open* opcodes (except on WITHOUT ROWID) */ + int iBase, /* Use this for the table cursor, if there is one */ + u8 *aToOpen, /* If not NULL: boolean for each table and index */ + int *piDataCur, /* Write the database source cursor number here */ + int *piIdxCur /* Write the first index cursor number here */ +){ + int i; + int iDb; + int iDataCur; + Index *pIdx; + Vdbe *v; + + assert( op==OP_OpenRead || op==OP_OpenWrite ); + assert( op==OP_OpenWrite || p5==0 ); + assert( piDataCur!=0 ); + assert( piIdxCur!=0 ); + if( IsVirtual(pTab) ){ + /* This routine is a no-op for virtual tables. Leave the output + ** variables *piDataCur and *piIdxCur set to illegal cursor numbers + ** for improved error detection. */ + *piDataCur = *piIdxCur = -999; + return 0; + } + iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + v = pParse->pVdbe; + assert( v!=0 ); + if( iBase<0 ) iBase = pParse->nTab; + iDataCur = iBase++; + *piDataCur = iDataCur; + if( HasRowid(pTab) && (aToOpen==0 || aToOpen[0]) ){ + sqlite3OpenTable(pParse, iDataCur, iDb, pTab, op); + }else if( pParse->db->noSharedCache==0 ){ + sqlite3TableLock(pParse, iDb, pTab->tnum, op==OP_OpenWrite, pTab->zName); + } + *piIdxCur = iBase; + for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ + int iIdxCur = iBase++; + assert( pIdx->pSchema==pTab->pSchema ); + if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ + *piDataCur = iIdxCur; + p5 = 0; + } + if( aToOpen==0 || aToOpen[i+1] ){ + sqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIdx); + sqlite3VdbeChangeP5(v, p5); + VdbeComment((v, "%s", pIdx->zName)); + } + } + if( iBase>pParse->nTab ) pParse->nTab = iBase; + return i; +} + + +#ifdef SQLITE_TEST +/* +** The following global variable is incremented whenever the +** transfer optimization is used. This is used for testing +** purposes only - to make sure the transfer optimization really +** is happening when it is supposed to. +*/ +SQLITE_API int sqlite3_xferopt_count; +#endif /* SQLITE_TEST */ + + +#ifndef SQLITE_OMIT_XFER_OPT +/* +** Check to see if index pSrc is compatible as a source of data +** for index pDest in an insert transfer optimization. The rules +** for a compatible index: +** +** * The index is over the same set of columns +** * The same DESC and ASC markings occurs on all columns +** * The same onError processing (OE_Abort, OE_Ignore, etc) +** * The same collating sequence on each column +** * The index has the exact same WHERE clause +*/ +static int xferCompatibleIndex(Index *pDest, Index *pSrc){ + int i; + assert( pDest && pSrc ); + assert( pDest->pTable!=pSrc->pTable ); + if( pDest->nKeyCol!=pSrc->nKeyCol || pDest->nColumn!=pSrc->nColumn ){ + return 0; /* Different number of columns */ + } + if( pDest->onError!=pSrc->onError ){ + return 0; /* Different conflict resolution strategies */ + } + for(i=0; inKeyCol; i++){ + if( pSrc->aiColumn[i]!=pDest->aiColumn[i] ){ + return 0; /* Different columns indexed */ + } + if( pSrc->aiColumn[i]==XN_EXPR ){ + assert( pSrc->aColExpr!=0 && pDest->aColExpr!=0 ); + if( sqlite3ExprCompare(0, pSrc->aColExpr->a[i].pExpr, + pDest->aColExpr->a[i].pExpr, -1)!=0 ){ + return 0; /* Different expressions in the index */ + } + } + if( pSrc->aSortOrder[i]!=pDest->aSortOrder[i] ){ + return 0; /* Different sort orders */ + } + if( sqlite3_stricmp(pSrc->azColl[i],pDest->azColl[i])!=0 ){ + return 0; /* Different collating sequences */ + } + } + if( sqlite3ExprCompare(0, pSrc->pPartIdxWhere, pDest->pPartIdxWhere, -1) ){ + return 0; /* Different WHERE clauses */ + } + + /* If no test above fails then the indices must be compatible */ + return 1; +} + +/* +** Attempt the transfer optimization on INSERTs of the form +** +** INSERT INTO tab1 SELECT * FROM tab2; +** +** The xfer optimization transfers raw records from tab2 over to tab1. +** Columns are not decoded and reassembled, which greatly improves +** performance. Raw index records are transferred in the same way. +** +** The xfer optimization is only attempted if tab1 and tab2 are compatible. +** There are lots of rules for determining compatibility - see comments +** embedded in the code for details. +** +** This routine returns TRUE if the optimization is guaranteed to be used. +** Sometimes the xfer optimization will only work if the destination table +** is empty - a factor that can only be determined at run-time. In that +** case, this routine generates code for the xfer optimization but also +** does a test to see if the destination table is empty and jumps over the +** xfer optimization code if the test fails. In that case, this routine +** returns FALSE so that the caller will know to go ahead and generate +** an unoptimized transfer. This routine also returns FALSE if there +** is no chance that the xfer optimization can be applied. +** +** This optimization is particularly useful at making VACUUM run faster. +*/ +static int xferOptimization( + Parse *pParse, /* Parser context */ + Table *pDest, /* The table we are inserting into */ + Select *pSelect, /* A SELECT statement to use as the data source */ + int onError, /* How to handle constraint errors */ + int iDbDest /* The database of pDest */ +){ + sqlite3 *db = pParse->db; + ExprList *pEList; /* The result set of the SELECT */ + Table *pSrc; /* The table in the FROM clause of SELECT */ + Index *pSrcIdx, *pDestIdx; /* Source and destination indices */ + SrcItem *pItem; /* An element of pSelect->pSrc */ + int i; /* Loop counter */ + int iDbSrc; /* The database of pSrc */ + int iSrc, iDest; /* Cursors from source and destination */ + int addr1, addr2; /* Loop addresses */ + int emptyDestTest = 0; /* Address of test for empty pDest */ + int emptySrcTest = 0; /* Address of test for empty pSrc */ + Vdbe *v; /* The VDBE we are building */ + int regAutoinc; /* Memory register used by AUTOINC */ + int destHasUniqueIdx = 0; /* True if pDest has a UNIQUE index */ + int regData, regRowid; /* Registers holding data and rowid */ + + assert( pSelect!=0 ); + if( pParse->pWith || pSelect->pWith ){ + /* Do not attempt to process this query if there are an WITH clauses + ** attached to it. Proceeding may generate a false "no such table: xxx" + ** error if pSelect reads from a CTE named "xxx". */ + return 0; + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pDest) ){ + return 0; /* tab1 must not be a virtual table */ + } +#endif + if( onError==OE_Default ){ + if( pDest->iPKey>=0 ) onError = pDest->keyConf; + if( onError==OE_Default ) onError = OE_Abort; + } + assert(pSelect->pSrc); /* allocated even if there is no FROM clause */ + if( pSelect->pSrc->nSrc!=1 ){ + return 0; /* FROM clause must have exactly one term */ + } + if( pSelect->pSrc->a[0].fg.isSubquery ){ + return 0; /* FROM clause cannot contain a subquery */ + } + if( pSelect->pWhere ){ + return 0; /* SELECT may not have a WHERE clause */ + } + if( pSelect->pOrderBy ){ + return 0; /* SELECT may not have an ORDER BY clause */ + } + /* Do not need to test for a HAVING clause. If HAVING is present but + ** there is no ORDER BY, we will get an error. */ + if( pSelect->pGroupBy ){ + return 0; /* SELECT may not have a GROUP BY clause */ + } + if( pSelect->pLimit ){ + return 0; /* SELECT may not have a LIMIT clause */ + } + if( pSelect->pPrior ){ + return 0; /* SELECT may not be a compound query */ + } + if( pSelect->selFlags & SF_Distinct ){ + return 0; /* SELECT may not be DISTINCT */ + } + pEList = pSelect->pEList; + assert( pEList!=0 ); + if( pEList->nExpr!=1 ){ + return 0; /* The result set must have exactly one column */ + } + assert( pEList->a[0].pExpr ); + if( pEList->a[0].pExpr->op!=TK_ASTERISK ){ + return 0; /* The result set must be the special operator "*" */ + } + + /* At this point we have established that the statement is of the + ** correct syntactic form to participate in this optimization. Now + ** we have to check the semantics. + */ + pItem = pSelect->pSrc->a; + pSrc = sqlite3LocateTableItem(pParse, 0, pItem); + if( pSrc==0 ){ + return 0; /* FROM clause does not contain a real table */ + } + if( pSrc->tnum==pDest->tnum && pSrc->pSchema==pDest->pSchema ){ + testcase( pSrc!=pDest ); /* Possible due to bad sqlite_schema.rootpage */ + return 0; /* tab1 and tab2 may not be the same table */ + } + if( HasRowid(pDest)!=HasRowid(pSrc) ){ + return 0; /* source and destination must both be WITHOUT ROWID or not */ + } + if( !IsOrdinaryTable(pSrc) ){ + return 0; /* tab2 may not be a view or virtual table */ + } + if( pDest->nCol!=pSrc->nCol ){ + return 0; /* Number of columns must be the same in tab1 and tab2 */ + } + if( pDest->iPKey!=pSrc->iPKey ){ + return 0; /* Both tables must have the same INTEGER PRIMARY KEY */ + } + if( (pDest->tabFlags & TF_Strict)!=0 && (pSrc->tabFlags & TF_Strict)==0 ){ + return 0; /* Cannot feed from a non-strict into a strict table */ + } + for(i=0; inCol; i++){ + Column *pDestCol = &pDest->aCol[i]; + Column *pSrcCol = &pSrc->aCol[i]; +#ifdef SQLITE_ENABLE_HIDDEN_COLUMNS + if( (db->mDbFlags & DBFLAG_Vacuum)==0 + && (pDestCol->colFlags | pSrcCol->colFlags) & COLFLAG_HIDDEN + ){ + return 0; /* Neither table may have __hidden__ columns */ + } +#endif +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + /* Even if tables t1 and t2 have identical schemas, if they contain + ** generated columns, then this statement is semantically incorrect: + ** + ** INSERT INTO t2 SELECT * FROM t1; + ** + ** The reason is that generated column values are returned by the + ** the SELECT statement on the right but the INSERT statement on the + ** left wants them to be omitted. + ** + ** Nevertheless, this is a useful notational shorthand to tell SQLite + ** to do a bulk transfer all of the content from t1 over to t2. + ** + ** We could, in theory, disable this (except for internal use by the + ** VACUUM command where it is actually needed). But why do that? It + ** seems harmless enough, and provides a useful service. + */ + if( (pDestCol->colFlags & COLFLAG_GENERATED) != + (pSrcCol->colFlags & COLFLAG_GENERATED) ){ + return 0; /* Both columns have the same generated-column type */ + } + /* But the transfer is only allowed if both the source and destination + ** tables have the exact same expressions for generated columns. + ** This requirement could be relaxed for VIRTUAL columns, I suppose. + */ + if( (pDestCol->colFlags & COLFLAG_GENERATED)!=0 ){ + if( sqlite3ExprCompare(0, + sqlite3ColumnExpr(pSrc, pSrcCol), + sqlite3ColumnExpr(pDest, pDestCol), -1)!=0 ){ + testcase( pDestCol->colFlags & COLFLAG_VIRTUAL ); + testcase( pDestCol->colFlags & COLFLAG_STORED ); + return 0; /* Different generator expressions */ + } + } +#endif + if( pDestCol->affinity!=pSrcCol->affinity ){ + return 0; /* Affinity must be the same on all columns */ + } + if( sqlite3_stricmp(sqlite3ColumnColl(pDestCol), + sqlite3ColumnColl(pSrcCol))!=0 ){ + return 0; /* Collating sequence must be the same on all columns */ + } + if( pDestCol->notNull && !pSrcCol->notNull ){ + return 0; /* tab2 must be NOT NULL if tab1 is */ + } + /* Default values for second and subsequent columns need to match. */ + if( (pDestCol->colFlags & COLFLAG_GENERATED)==0 && i>0 ){ + Expr *pDestExpr = sqlite3ColumnExpr(pDest, pDestCol); + Expr *pSrcExpr = sqlite3ColumnExpr(pSrc, pSrcCol); + assert( pDestExpr==0 || pDestExpr->op==TK_SPAN ); + assert( pDestExpr==0 || !ExprHasProperty(pDestExpr, EP_IntValue) ); + assert( pSrcExpr==0 || pSrcExpr->op==TK_SPAN ); + assert( pSrcExpr==0 || !ExprHasProperty(pSrcExpr, EP_IntValue) ); + if( (pDestExpr==0)!=(pSrcExpr==0) + || (pDestExpr!=0 && strcmp(pDestExpr->u.zToken, + pSrcExpr->u.zToken)!=0) + ){ + return 0; /* Default values must be the same for all columns */ + } + } + } + for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){ + if( IsUniqueIndex(pDestIdx) ){ + destHasUniqueIdx = 1; + } + for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){ + if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break; + } + if( pSrcIdx==0 ){ + return 0; /* pDestIdx has no corresponding index in pSrc */ + } + if( pSrcIdx->tnum==pDestIdx->tnum && pSrc->pSchema==pDest->pSchema + && sqlite3FaultSim(411)==SQLITE_OK ){ + /* The sqlite3FaultSim() call allows this corruption test to be + ** bypassed during testing, in order to exercise other corruption tests + ** further downstream. */ + return 0; /* Corrupt schema - two indexes on the same btree */ + } + } +#ifndef SQLITE_OMIT_CHECK + if( pDest->pCheck + && (db->mDbFlags & DBFLAG_Vacuum)==0 + && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) + ){ + return 0; /* Tables have different CHECK constraints. Ticket #2252 */ + } +#endif +#ifndef SQLITE_OMIT_FOREIGN_KEY + /* Disallow the transfer optimization if the destination table contains + ** any foreign key constraints. This is more restrictive than necessary. + ** But the main beneficiary of the transfer optimization is the VACUUM + ** command, and the VACUUM command disables foreign key constraints. So + ** the extra complication to make this rule less restrictive is probably + ** not worth the effort. Ticket [6284df89debdfa61db8073e062908af0c9b6118e] + */ + assert( IsOrdinaryTable(pDest) ); + if( (db->flags & SQLITE_ForeignKeys)!=0 && pDest->u.tab.pFKey!=0 ){ + return 0; + } +#endif + if( (db->flags & SQLITE_CountRows)!=0 ){ + return 0; /* xfer opt does not play well with PRAGMA count_changes */ + } + + /* If we get this far, it means that the xfer optimization is at + ** least a possibility, though it might only work if the destination + ** table (tab1) is initially empty. + */ +#ifdef SQLITE_TEST + sqlite3_xferopt_count++; +#endif + iDbSrc = sqlite3SchemaToIndex(db, pSrc->pSchema); + v = sqlite3GetVdbe(pParse); + sqlite3CodeVerifySchema(pParse, iDbSrc); + iSrc = pParse->nTab++; + iDest = pParse->nTab++; + regAutoinc = autoIncBegin(pParse, iDbDest, pDest); + regData = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_Null, 0, regData); + regRowid = sqlite3GetTempReg(pParse); + sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite); + assert( HasRowid(pDest) || destHasUniqueIdx ); + if( (db->mDbFlags & DBFLAG_Vacuum)==0 && ( + (pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */ + || destHasUniqueIdx /* (2) */ + || (onError!=OE_Abort && onError!=OE_Rollback) /* (3) */ + )){ + /* In some circumstances, we are able to run the xfer optimization + ** only if the destination table is initially empty. Unless the + ** DBFLAG_Vacuum flag is set, this block generates code to make + ** that determination. If DBFLAG_Vacuum is set, then the destination + ** table is always empty. + ** + ** Conditions under which the destination must be empty: + ** + ** (1) There is no INTEGER PRIMARY KEY but there are indices. + ** (If the destination is not initially empty, the rowid fields + ** of index entries might need to change.) + ** + ** (2) The destination has a unique index. (The xfer optimization + ** is unable to test uniqueness.) + ** + ** (3) onError is something other than OE_Abort and OE_Rollback. + */ + addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0); VdbeCoverage(v); + emptyDestTest = sqlite3VdbeAddOp0(v, OP_Goto); + sqlite3VdbeJumpHere(v, addr1); + } + if( HasRowid(pSrc) ){ + u8 insFlags; + sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead); + emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v); + if( pDest->iPKey>=0 ){ + addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid); + if( (db->mDbFlags & DBFLAG_Vacuum)==0 ){ + sqlite3VdbeVerifyAbortable(v, onError); + addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid); + VdbeCoverage(v); + sqlite3RowidConstraint(pParse, onError, pDest); + sqlite3VdbeJumpHere(v, addr2); + } + autoIncStep(pParse, regAutoinc, regRowid); + }else if( pDest->pIndex==0 && !(db->mDbFlags & DBFLAG_VacuumInto) ){ + addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid); + }else{ + addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid); + assert( (pDest->tabFlags & TF_Autoincrement)==0 ); + } + + if( db->mDbFlags & DBFLAG_Vacuum ){ + sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest); + insFlags = OPFLAG_APPEND|OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT; + }else{ + insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND|OPFLAG_PREFORMAT; + } +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + if( (db->mDbFlags & DBFLAG_Vacuum)==0 ){ + sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); + insFlags &= ~OPFLAG_PREFORMAT; + }else +#endif + { + sqlite3VdbeAddOp3(v, OP_RowCell, iDest, iSrc, regRowid); + } + sqlite3VdbeAddOp3(v, OP_Insert, iDest, regData, regRowid); + if( (db->mDbFlags & DBFLAG_Vacuum)==0 ){ + sqlite3VdbeChangeP4(v, -1, (char*)pDest, P4_TABLE); + } + sqlite3VdbeChangeP5(v, insFlags); + + sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); + sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); + }else{ + sqlite3TableLock(pParse, iDbDest, pDest->tnum, 1, pDest->zName); + sqlite3TableLock(pParse, iDbSrc, pSrc->tnum, 0, pSrc->zName); + } + for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){ + u8 idxInsFlags = 0; + for(pSrcIdx=pSrc->pIndex; ALWAYS(pSrcIdx); pSrcIdx=pSrcIdx->pNext){ + if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break; + } + assert( pSrcIdx ); + sqlite3VdbeAddOp3(v, OP_OpenRead, iSrc, pSrcIdx->tnum, iDbSrc); + sqlite3VdbeSetP4KeyInfo(pParse, pSrcIdx); + VdbeComment((v, "%s", pSrcIdx->zName)); + sqlite3VdbeAddOp3(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest); + sqlite3VdbeSetP4KeyInfo(pParse, pDestIdx); + sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR); + VdbeComment((v, "%s", pDestIdx->zName)); + addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v); + if( db->mDbFlags & DBFLAG_Vacuum ){ + /* This INSERT command is part of a VACUUM operation, which guarantees + ** that the destination table is empty. If all indexed columns use + ** collation sequence BINARY, then it can also be assumed that the + ** index will be populated by inserting keys in strictly sorted + ** order. In this case, instead of seeking within the b-tree as part + ** of every OP_IdxInsert opcode, an OP_SeekEnd is added before the + ** OP_IdxInsert to seek to the point within the b-tree where each key + ** should be inserted. This is faster. + ** + ** If any of the indexed columns use a collation sequence other than + ** BINARY, this optimization is disabled. This is because the user + ** might change the definition of a collation sequence and then run + ** a VACUUM command. In that case keys may not be written in strictly + ** sorted order. */ + for(i=0; inColumn; i++){ + const char *zColl = pSrcIdx->azColl[i]; + if( sqlite3_stricmp(sqlite3StrBINARY, zColl) ) break; + } + if( i==pSrcIdx->nColumn ){ + idxInsFlags = OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT; + sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest); + sqlite3VdbeAddOp2(v, OP_RowCell, iDest, iSrc); + } + }else if( !HasRowid(pSrc) && pDestIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){ + idxInsFlags |= OPFLAG_NCHANGE; + } + if( idxInsFlags!=(OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT) ){ + sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); + if( (db->mDbFlags & DBFLAG_Vacuum)==0 + && !HasRowid(pDest) + && IsPrimaryKeyIndex(pDestIdx) + ){ + codeWithoutRowidPreupdate(pParse, pDest, iDest, regData); + } + } + sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, regData); + sqlite3VdbeChangeP5(v, idxInsFlags|OPFLAG_APPEND); + sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr1); + sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); + sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); + } + if( emptySrcTest ) sqlite3VdbeJumpHere(v, emptySrcTest); + sqlite3ReleaseTempReg(pParse, regRowid); + sqlite3ReleaseTempReg(pParse, regData); + if( emptyDestTest ){ + sqlite3AutoincrementEnd(pParse); + sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, 0); + sqlite3VdbeJumpHere(v, emptyDestTest); + sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); + return 0; + }else{ + return 1; + } +} +#endif /* SQLITE_OMIT_XFER_OPT */ + +/************** End of insert.c **********************************************/ +/************** Begin file legacy.c ******************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** Main file for the SQLite library. The routines in this file +** implement the programmer interface to the library. Routines in +** other files are for internal use by SQLite and should not be +** accessed by users of the library. +*/ + +/* #include "sqliteInt.h" */ + +/* +** Execute SQL code. Return one of the SQLITE_ success/failure +** codes. Also write an error message into memory obtained from +** malloc() and make *pzErrMsg point to that message. +** +** If the SQL is a query, then for each row in the query result +** the xCallback() function is called. pArg becomes the first +** argument to xCallback(). If xCallback=NULL then no callback +** is invoked, even for queries. +*/ +SQLITE_API int sqlite3_exec( + sqlite3 *db, /* The database on which the SQL executes */ + const char *zSql, /* The SQL to be executed */ + sqlite3_callback xCallback, /* Invoke this callback routine */ + void *pArg, /* First argument to xCallback() */ + char **pzErrMsg /* Write error messages here */ +){ + int rc = SQLITE_OK; /* Return code */ + const char *zLeftover; /* Tail of unprocessed SQL */ + sqlite3_stmt *pStmt = 0; /* The current SQL statement */ + char **azCols = 0; /* Names of result columns */ + int callbackIsInit; /* True if callback data is initialized */ + + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; + if( zSql==0 ) zSql = ""; + + sqlite3_mutex_enter(db->mutex); + sqlite3Error(db, SQLITE_OK); + while( rc==SQLITE_OK && zSql[0] ){ + int nCol = 0; + char **azVals = 0; + + pStmt = 0; + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover); + assert( rc==SQLITE_OK || pStmt==0 ); + if( rc!=SQLITE_OK ){ + continue; + } + if( !pStmt ){ + /* this happens for a comment or white-space */ + zSql = zLeftover; + continue; + } + callbackIsInit = 0; + + while( 1 ){ + int i; + rc = sqlite3_step(pStmt); + + /* Invoke the callback function if required */ + if( xCallback && (SQLITE_ROW==rc || + (SQLITE_DONE==rc && !callbackIsInit + && db->flags&SQLITE_NullCallback)) ){ + if( !callbackIsInit ){ + nCol = sqlite3_column_count(pStmt); + azCols = sqlite3DbMallocRaw(db, (2*nCol+1)*sizeof(const char*)); + if( azCols==0 ){ + goto exec_out; + } + for(i=0; ierrMask)==rc ); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/************** End of legacy.c **********************************************/ +/************** Begin file loadext.c *****************************************/ +/* +** 2006 June 7 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code used to dynamically load extensions into +** the SQLite library. +*/ + +#ifndef SQLITE_CORE + #define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */ +#endif +/************** Include sqlite3ext.h in the middle of loadext.c **************/ +/************** Begin file sqlite3ext.h **************************************/ +/* +** 2006 June 7 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This header file defines the SQLite interface for use by +** shared libraries that want to be imported as extensions into +** an SQLite instance. Shared libraries that intend to be loaded +** as extensions by SQLite should #include this file instead of +** sqlite3.h. +*/ +#ifndef SQLITE3EXT_H +#define SQLITE3EXT_H +/* #include "sqlite3.h" */ + +/* +** The following structure holds pointers to all of the SQLite API +** routines. +** +** WARNING: In order to maintain backwards compatibility, add new +** interfaces to the end of this structure only. If you insert new +** interfaces in the middle of this structure, then older different +** versions of SQLite will not be able to load each other's shared +** libraries! +*/ +struct sqlite3_api_routines { + void * (*aggregate_context)(sqlite3_context*,int nBytes); + int (*aggregate_count)(sqlite3_context*); + int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*)); + int (*bind_double)(sqlite3_stmt*,int,double); + int (*bind_int)(sqlite3_stmt*,int,int); + int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64); + int (*bind_null)(sqlite3_stmt*,int); + int (*bind_parameter_count)(sqlite3_stmt*); + int (*bind_parameter_index)(sqlite3_stmt*,const char*zName); + const char * (*bind_parameter_name)(sqlite3_stmt*,int); + int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*)); + int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*)); + int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*); + int (*busy_handler)(sqlite3*,int(*)(void*,int),void*); + int (*busy_timeout)(sqlite3*,int ms); + int (*changes)(sqlite3*); + int (*close)(sqlite3*); + int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*, + int eTextRep,const char*)); + int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*, + int eTextRep,const void*)); + const void * (*column_blob)(sqlite3_stmt*,int iCol); + int (*column_bytes)(sqlite3_stmt*,int iCol); + int (*column_bytes16)(sqlite3_stmt*,int iCol); + int (*column_count)(sqlite3_stmt*pStmt); + const char * (*column_database_name)(sqlite3_stmt*,int); + const void * (*column_database_name16)(sqlite3_stmt*,int); + const char * (*column_decltype)(sqlite3_stmt*,int i); + const void * (*column_decltype16)(sqlite3_stmt*,int); + double (*column_double)(sqlite3_stmt*,int iCol); + int (*column_int)(sqlite3_stmt*,int iCol); + sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol); + const char * (*column_name)(sqlite3_stmt*,int); + const void * (*column_name16)(sqlite3_stmt*,int); + const char * (*column_origin_name)(sqlite3_stmt*,int); + const void * (*column_origin_name16)(sqlite3_stmt*,int); + const char * (*column_table_name)(sqlite3_stmt*,int); + const void * (*column_table_name16)(sqlite3_stmt*,int); + const unsigned char * (*column_text)(sqlite3_stmt*,int iCol); + const void * (*column_text16)(sqlite3_stmt*,int iCol); + int (*column_type)(sqlite3_stmt*,int iCol); + sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol); + void * (*commit_hook)(sqlite3*,int(*)(void*),void*); + int (*complete)(const char*sql); + int (*complete16)(const void*sql); + int (*create_collation)(sqlite3*,const char*,int,void*, + int(*)(void*,int,const void*,int,const void*)); + int (*create_collation16)(sqlite3*,const void*,int,void*, + int(*)(void*,int,const void*,int,const void*)); + int (*create_function)(sqlite3*,const char*,int,int,void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*)); + int (*create_function16)(sqlite3*,const void*,int,int,void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*)); + int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*); + int (*data_count)(sqlite3_stmt*pStmt); + sqlite3 * (*db_handle)(sqlite3_stmt*); + int (*declare_vtab)(sqlite3*,const char*); + int (*enable_shared_cache)(int); + int (*errcode)(sqlite3*db); + const char * (*errmsg)(sqlite3*); + const void * (*errmsg16)(sqlite3*); + int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**); + int (*expired)(sqlite3_stmt*); + int (*finalize)(sqlite3_stmt*pStmt); + void (*free)(void*); + void (*free_table)(char**result); + int (*get_autocommit)(sqlite3*); + void * (*get_auxdata)(sqlite3_context*,int); + int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**); + int (*global_recover)(void); + void (*interruptx)(sqlite3*); + sqlite_int64 (*last_insert_rowid)(sqlite3*); + const char * (*libversion)(void); + int (*libversion_number)(void); + void *(*malloc)(int); + char * (*mprintf)(const char*,...); + int (*open)(const char*,sqlite3**); + int (*open16)(const void*,sqlite3**); + int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); + int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); + void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*); + void (*progress_handler)(sqlite3*,int,int(*)(void*),void*); + void *(*realloc)(void*,int); + int (*reset)(sqlite3_stmt*pStmt); + void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_double)(sqlite3_context*,double); + void (*result_error)(sqlite3_context*,const char*,int); + void (*result_error16)(sqlite3_context*,const void*,int); + void (*result_int)(sqlite3_context*,int); + void (*result_int64)(sqlite3_context*,sqlite_int64); + void (*result_null)(sqlite3_context*); + void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*)); + void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_value)(sqlite3_context*,sqlite3_value*); + void * (*rollback_hook)(sqlite3*,void(*)(void*),void*); + int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*, + const char*,const char*),void*); + void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*)); + char * (*xsnprintf)(int,char*,const char*,...); + int (*step)(sqlite3_stmt*); + int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*, + char const**,char const**,int*,int*,int*); + void (*thread_cleanup)(void); + int (*total_changes)(sqlite3*); + void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*); + int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*); + void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*, + sqlite_int64),void*); + void * (*user_data)(sqlite3_context*); + const void * (*value_blob)(sqlite3_value*); + int (*value_bytes)(sqlite3_value*); + int (*value_bytes16)(sqlite3_value*); + double (*value_double)(sqlite3_value*); + int (*value_int)(sqlite3_value*); + sqlite_int64 (*value_int64)(sqlite3_value*); + int (*value_numeric_type)(sqlite3_value*); + const unsigned char * (*value_text)(sqlite3_value*); + const void * (*value_text16)(sqlite3_value*); + const void * (*value_text16be)(sqlite3_value*); + const void * (*value_text16le)(sqlite3_value*); + int (*value_type)(sqlite3_value*); + char *(*vmprintf)(const char*,va_list); + /* Added ??? */ + int (*overload_function)(sqlite3*, const char *zFuncName, int nArg); + /* Added by 3.3.13 */ + int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); + int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); + int (*clear_bindings)(sqlite3_stmt*); + /* Added by 3.4.1 */ + int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*, + void (*xDestroy)(void *)); + /* Added by 3.5.0 */ + int (*bind_zeroblob)(sqlite3_stmt*,int,int); + int (*blob_bytes)(sqlite3_blob*); + int (*blob_close)(sqlite3_blob*); + int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64, + int,sqlite3_blob**); + int (*blob_read)(sqlite3_blob*,void*,int,int); + int (*blob_write)(sqlite3_blob*,const void*,int,int); + int (*create_collation_v2)(sqlite3*,const char*,int,void*, + int(*)(void*,int,const void*,int,const void*), + void(*)(void*)); + int (*file_control)(sqlite3*,const char*,int,void*); + sqlite3_int64 (*memory_highwater)(int); + sqlite3_int64 (*memory_used)(void); + sqlite3_mutex *(*mutex_alloc)(int); + void (*mutex_enter)(sqlite3_mutex*); + void (*mutex_free)(sqlite3_mutex*); + void (*mutex_leave)(sqlite3_mutex*); + int (*mutex_try)(sqlite3_mutex*); + int (*open_v2)(const char*,sqlite3**,int,const char*); + int (*release_memory)(int); + void (*result_error_nomem)(sqlite3_context*); + void (*result_error_toobig)(sqlite3_context*); + int (*sleep)(int); + void (*soft_heap_limit)(int); + sqlite3_vfs *(*vfs_find)(const char*); + int (*vfs_register)(sqlite3_vfs*,int); + int (*vfs_unregister)(sqlite3_vfs*); + int (*xthreadsafe)(void); + void (*result_zeroblob)(sqlite3_context*,int); + void (*result_error_code)(sqlite3_context*,int); + int (*test_control)(int, ...); + void (*randomness)(int,void*); + sqlite3 *(*context_db_handle)(sqlite3_context*); + int (*extended_result_codes)(sqlite3*,int); + int (*limit)(sqlite3*,int,int); + sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*); + const char *(*sql)(sqlite3_stmt*); + int (*status)(int,int*,int*,int); + int (*backup_finish)(sqlite3_backup*); + sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*); + int (*backup_pagecount)(sqlite3_backup*); + int (*backup_remaining)(sqlite3_backup*); + int (*backup_step)(sqlite3_backup*,int); + const char *(*compileoption_get)(int); + int (*compileoption_used)(const char*); + int (*create_function_v2)(sqlite3*,const char*,int,int,void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void(*xDestroy)(void*)); + int (*db_config)(sqlite3*,int,...); + sqlite3_mutex *(*db_mutex)(sqlite3*); + int (*db_status)(sqlite3*,int,int*,int*,int); + int (*extended_errcode)(sqlite3*); + void (*log)(int,const char*,...); + sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64); + const char *(*sourceid)(void); + int (*stmt_status)(sqlite3_stmt*,int,int); + int (*strnicmp)(const char*,const char*,int); + int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*); + int (*wal_autocheckpoint)(sqlite3*,int); + int (*wal_checkpoint)(sqlite3*,const char*); + void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*); + int (*blob_reopen)(sqlite3_blob*,sqlite3_int64); + int (*vtab_config)(sqlite3*,int op,...); + int (*vtab_on_conflict)(sqlite3*); + /* Version 3.7.16 and later */ + int (*close_v2)(sqlite3*); + const char *(*db_filename)(sqlite3*,const char*); + int (*db_readonly)(sqlite3*,const char*); + int (*db_release_memory)(sqlite3*); + const char *(*errstr)(int); + int (*stmt_busy)(sqlite3_stmt*); + int (*stmt_readonly)(sqlite3_stmt*); + int (*stricmp)(const char*,const char*); + int (*uri_boolean)(const char*,const char*,int); + sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64); + const char *(*uri_parameter)(const char*,const char*); + char *(*xvsnprintf)(int,char*,const char*,va_list); + int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*); + /* Version 3.8.7 and later */ + int (*auto_extension)(void(*)(void)); + int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64, + void(*)(void*)); + int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64, + void(*)(void*),unsigned char); + int (*cancel_auto_extension)(void(*)(void)); + int (*load_extension)(sqlite3*,const char*,const char*,char**); + void *(*malloc64)(sqlite3_uint64); + sqlite3_uint64 (*msize)(void*); + void *(*realloc64)(void*,sqlite3_uint64); + void (*reset_auto_extension)(void); + void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64, + void(*)(void*)); + void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64, + void(*)(void*), unsigned char); + int (*strglob)(const char*,const char*); + /* Version 3.8.11 and later */ + sqlite3_value *(*value_dup)(const sqlite3_value*); + void (*value_free)(sqlite3_value*); + int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64); + int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64); + /* Version 3.9.0 and later */ + unsigned int (*value_subtype)(sqlite3_value*); + void (*result_subtype)(sqlite3_context*,unsigned int); + /* Version 3.10.0 and later */ + int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int); + int (*strlike)(const char*,const char*,unsigned int); + int (*db_cacheflush)(sqlite3*); + /* Version 3.12.0 and later */ + int (*system_errno)(sqlite3*); + /* Version 3.14.0 and later */ + int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*); + char *(*expanded_sql)(sqlite3_stmt*); + /* Version 3.18.0 and later */ + void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64); + /* Version 3.20.0 and later */ + int (*prepare_v3)(sqlite3*,const char*,int,unsigned int, + sqlite3_stmt**,const char**); + int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int, + sqlite3_stmt**,const void**); + int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*)); + void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*)); + void *(*value_pointer)(sqlite3_value*,const char*); + int (*vtab_nochange)(sqlite3_context*); + int (*value_nochange)(sqlite3_value*); + const char *(*vtab_collation)(sqlite3_index_info*,int); + /* Version 3.24.0 and later */ + int (*keyword_count)(void); + int (*keyword_name)(int,const char**,int*); + int (*keyword_check)(const char*,int); + sqlite3_str *(*str_new)(sqlite3*); + char *(*str_finish)(sqlite3_str*); + void (*str_appendf)(sqlite3_str*, const char *zFormat, ...); + void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list); + void (*str_append)(sqlite3_str*, const char *zIn, int N); + void (*str_appendall)(sqlite3_str*, const char *zIn); + void (*str_appendchar)(sqlite3_str*, int N, char C); + void (*str_reset)(sqlite3_str*); + int (*str_errcode)(sqlite3_str*); + int (*str_length)(sqlite3_str*); + char *(*str_value)(sqlite3_str*); + /* Version 3.25.0 and later */ + int (*create_window_function)(sqlite3*,const char*,int,int,void*, + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void (*xValue)(sqlite3_context*), + void (*xInv)(sqlite3_context*,int,sqlite3_value**), + void(*xDestroy)(void*)); + /* Version 3.26.0 and later */ + const char *(*normalized_sql)(sqlite3_stmt*); + /* Version 3.28.0 and later */ + int (*stmt_isexplain)(sqlite3_stmt*); + int (*value_frombind)(sqlite3_value*); + /* Version 3.30.0 and later */ + int (*drop_modules)(sqlite3*,const char**); + /* Version 3.31.0 and later */ + sqlite3_int64 (*hard_heap_limit64)(sqlite3_int64); + const char *(*uri_key)(const char*,int); + const char *(*filename_database)(const char*); + const char *(*filename_journal)(const char*); + const char *(*filename_wal)(const char*); + /* Version 3.32.0 and later */ + const char *(*create_filename)(const char*,const char*,const char*, + int,const char**); + void (*free_filename)(const char*); + sqlite3_file *(*database_file_object)(const char*); + /* Version 3.34.0 and later */ + int (*txn_state)(sqlite3*,const char*); + /* Version 3.36.1 and later */ + sqlite3_int64 (*changes64)(sqlite3*); + sqlite3_int64 (*total_changes64)(sqlite3*); + /* Version 3.37.0 and later */ + int (*autovacuum_pages)(sqlite3*, + unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int), + void*, void(*)(void*)); + /* Version 3.38.0 and later */ + int (*error_offset)(sqlite3*); + int (*vtab_rhs_value)(sqlite3_index_info*,int,sqlite3_value**); + int (*vtab_distinct)(sqlite3_index_info*); + int (*vtab_in)(sqlite3_index_info*,int,int); + int (*vtab_in_first)(sqlite3_value*,sqlite3_value**); + int (*vtab_in_next)(sqlite3_value*,sqlite3_value**); + /* Version 3.39.0 and later */ + int (*deserialize)(sqlite3*,const char*,unsigned char*, + sqlite3_int64,sqlite3_int64,unsigned); + unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*, + unsigned int); + const char *(*db_name)(sqlite3*,int); + /* Version 3.40.0 and later */ + int (*value_encoding)(sqlite3_value*); + /* Version 3.41.0 and later */ + int (*is_interrupted)(sqlite3*); + /* Version 3.43.0 and later */ + int (*stmt_explain)(sqlite3_stmt*,int); + /* Version 3.44.0 and later */ + void *(*get_clientdata)(sqlite3*,const char*); + int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*)); + /* Version 3.50.0 and later */ + int (*setlk_timeout)(sqlite3*,int,int); + /* Version 3.51.0 and later */ + int (*set_errmsg)(sqlite3*,int,const char*); + int (*db_status64)(sqlite3*,int,sqlite3_int64*,sqlite3_int64*,int); + /* Version 3.52.0 and later */ + void (*str_truncate)(sqlite3_str*,int); + void (*str_free)(sqlite3_str*); + int (*carray_bind)(sqlite3_stmt*,int,void*,int,int,void(*)(void*)); + int (*carray_bind_v2)(sqlite3_stmt*,int,void*,int,int,void(*)(void*),void*); +}; + +/* +** This is the function signature used for all extension entry points. It +** is also defined in the file "loadext.c". +*/ +typedef int (*sqlite3_loadext_entry)( + sqlite3 *db, /* Handle to the database. */ + char **pzErrMsg, /* Used to set error string on failure. */ + const sqlite3_api_routines *pThunk /* Extension API function pointers. */ +); + +/* +** The following macros redefine the API routines so that they are +** redirected through the global sqlite3_api structure. +** +** This header file is also used by the loadext.c source file +** (part of the main SQLite library - not an extension) so that +** it can get access to the sqlite3_api_routines structure +** definition. But the main library does not want to redefine +** the API. So the redefinition macros are only valid if the +** SQLITE_CORE macros is undefined. +*/ +#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) +#define sqlite3_aggregate_context sqlite3_api->aggregate_context +#ifndef SQLITE_OMIT_DEPRECATED +#define sqlite3_aggregate_count sqlite3_api->aggregate_count +#endif +#define sqlite3_bind_blob sqlite3_api->bind_blob +#define sqlite3_bind_double sqlite3_api->bind_double +#define sqlite3_bind_int sqlite3_api->bind_int +#define sqlite3_bind_int64 sqlite3_api->bind_int64 +#define sqlite3_bind_null sqlite3_api->bind_null +#define sqlite3_bind_parameter_count sqlite3_api->bind_parameter_count +#define sqlite3_bind_parameter_index sqlite3_api->bind_parameter_index +#define sqlite3_bind_parameter_name sqlite3_api->bind_parameter_name +#define sqlite3_bind_text sqlite3_api->bind_text +#define sqlite3_bind_text16 sqlite3_api->bind_text16 +#define sqlite3_bind_value sqlite3_api->bind_value +#define sqlite3_busy_handler sqlite3_api->busy_handler +#define sqlite3_busy_timeout sqlite3_api->busy_timeout +#define sqlite3_changes sqlite3_api->changes +#define sqlite3_close sqlite3_api->close +#define sqlite3_collation_needed sqlite3_api->collation_needed +#define sqlite3_collation_needed16 sqlite3_api->collation_needed16 +#define sqlite3_column_blob sqlite3_api->column_blob +#define sqlite3_column_bytes sqlite3_api->column_bytes +#define sqlite3_column_bytes16 sqlite3_api->column_bytes16 +#define sqlite3_column_count sqlite3_api->column_count +#define sqlite3_column_database_name sqlite3_api->column_database_name +#define sqlite3_column_database_name16 sqlite3_api->column_database_name16 +#define sqlite3_column_decltype sqlite3_api->column_decltype +#define sqlite3_column_decltype16 sqlite3_api->column_decltype16 +#define sqlite3_column_double sqlite3_api->column_double +#define sqlite3_column_int sqlite3_api->column_int +#define sqlite3_column_int64 sqlite3_api->column_int64 +#define sqlite3_column_name sqlite3_api->column_name +#define sqlite3_column_name16 sqlite3_api->column_name16 +#define sqlite3_column_origin_name sqlite3_api->column_origin_name +#define sqlite3_column_origin_name16 sqlite3_api->column_origin_name16 +#define sqlite3_column_table_name sqlite3_api->column_table_name +#define sqlite3_column_table_name16 sqlite3_api->column_table_name16 +#define sqlite3_column_text sqlite3_api->column_text +#define sqlite3_column_text16 sqlite3_api->column_text16 +#define sqlite3_column_type sqlite3_api->column_type +#define sqlite3_column_value sqlite3_api->column_value +#define sqlite3_commit_hook sqlite3_api->commit_hook +#define sqlite3_complete sqlite3_api->complete +#define sqlite3_complete16 sqlite3_api->complete16 +#define sqlite3_create_collation sqlite3_api->create_collation +#define sqlite3_create_collation16 sqlite3_api->create_collation16 +#define sqlite3_create_function sqlite3_api->create_function +#define sqlite3_create_function16 sqlite3_api->create_function16 +#define sqlite3_create_module sqlite3_api->create_module +#define sqlite3_create_module_v2 sqlite3_api->create_module_v2 +#define sqlite3_data_count sqlite3_api->data_count +#define sqlite3_db_handle sqlite3_api->db_handle +#define sqlite3_declare_vtab sqlite3_api->declare_vtab +#define sqlite3_enable_shared_cache sqlite3_api->enable_shared_cache +#define sqlite3_errcode sqlite3_api->errcode +#define sqlite3_errmsg sqlite3_api->errmsg +#define sqlite3_errmsg16 sqlite3_api->errmsg16 +#define sqlite3_exec sqlite3_api->exec +#ifndef SQLITE_OMIT_DEPRECATED +#define sqlite3_expired sqlite3_api->expired +#endif +#define sqlite3_finalize sqlite3_api->finalize +#define sqlite3_free sqlite3_api->free +#define sqlite3_free_table sqlite3_api->free_table +#define sqlite3_get_autocommit sqlite3_api->get_autocommit +#define sqlite3_get_auxdata sqlite3_api->get_auxdata +#define sqlite3_get_table sqlite3_api->get_table +#ifndef SQLITE_OMIT_DEPRECATED +#define sqlite3_global_recover sqlite3_api->global_recover +#endif +#define sqlite3_interrupt sqlite3_api->interruptx +#define sqlite3_last_insert_rowid sqlite3_api->last_insert_rowid +#define sqlite3_libversion sqlite3_api->libversion +#define sqlite3_libversion_number sqlite3_api->libversion_number +#define sqlite3_malloc sqlite3_api->malloc +#define sqlite3_mprintf sqlite3_api->mprintf +#define sqlite3_open sqlite3_api->open +#define sqlite3_open16 sqlite3_api->open16 +#define sqlite3_prepare sqlite3_api->prepare +#define sqlite3_prepare16 sqlite3_api->prepare16 +#define sqlite3_prepare_v2 sqlite3_api->prepare_v2 +#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2 +#define sqlite3_profile sqlite3_api->profile +#define sqlite3_progress_handler sqlite3_api->progress_handler +#define sqlite3_realloc sqlite3_api->realloc +#define sqlite3_reset sqlite3_api->reset +#define sqlite3_result_blob sqlite3_api->result_blob +#define sqlite3_result_double sqlite3_api->result_double +#define sqlite3_result_error sqlite3_api->result_error +#define sqlite3_result_error16 sqlite3_api->result_error16 +#define sqlite3_result_int sqlite3_api->result_int +#define sqlite3_result_int64 sqlite3_api->result_int64 +#define sqlite3_result_null sqlite3_api->result_null +#define sqlite3_result_text sqlite3_api->result_text +#define sqlite3_result_text16 sqlite3_api->result_text16 +#define sqlite3_result_text16be sqlite3_api->result_text16be +#define sqlite3_result_text16le sqlite3_api->result_text16le +#define sqlite3_result_value sqlite3_api->result_value +#define sqlite3_rollback_hook sqlite3_api->rollback_hook +#define sqlite3_set_authorizer sqlite3_api->set_authorizer +#define sqlite3_set_auxdata sqlite3_api->set_auxdata +#define sqlite3_snprintf sqlite3_api->xsnprintf +#define sqlite3_step sqlite3_api->step +#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata +#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup +#define sqlite3_total_changes sqlite3_api->total_changes +#define sqlite3_trace sqlite3_api->trace +#ifndef SQLITE_OMIT_DEPRECATED +#define sqlite3_transfer_bindings sqlite3_api->transfer_bindings +#endif +#define sqlite3_update_hook sqlite3_api->update_hook +#define sqlite3_user_data sqlite3_api->user_data +#define sqlite3_value_blob sqlite3_api->value_blob +#define sqlite3_value_bytes sqlite3_api->value_bytes +#define sqlite3_value_bytes16 sqlite3_api->value_bytes16 +#define sqlite3_value_double sqlite3_api->value_double +#define sqlite3_value_int sqlite3_api->value_int +#define sqlite3_value_int64 sqlite3_api->value_int64 +#define sqlite3_value_numeric_type sqlite3_api->value_numeric_type +#define sqlite3_value_text sqlite3_api->value_text +#define sqlite3_value_text16 sqlite3_api->value_text16 +#define sqlite3_value_text16be sqlite3_api->value_text16be +#define sqlite3_value_text16le sqlite3_api->value_text16le +#define sqlite3_value_type sqlite3_api->value_type +#define sqlite3_vmprintf sqlite3_api->vmprintf +#define sqlite3_vsnprintf sqlite3_api->xvsnprintf +#define sqlite3_overload_function sqlite3_api->overload_function +#define sqlite3_prepare_v2 sqlite3_api->prepare_v2 +#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2 +#define sqlite3_clear_bindings sqlite3_api->clear_bindings +#define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob +#define sqlite3_blob_bytes sqlite3_api->blob_bytes +#define sqlite3_blob_close sqlite3_api->blob_close +#define sqlite3_blob_open sqlite3_api->blob_open +#define sqlite3_blob_read sqlite3_api->blob_read +#define sqlite3_blob_write sqlite3_api->blob_write +#define sqlite3_create_collation_v2 sqlite3_api->create_collation_v2 +#define sqlite3_file_control sqlite3_api->file_control +#define sqlite3_memory_highwater sqlite3_api->memory_highwater +#define sqlite3_memory_used sqlite3_api->memory_used +#define sqlite3_mutex_alloc sqlite3_api->mutex_alloc +#define sqlite3_mutex_enter sqlite3_api->mutex_enter +#define sqlite3_mutex_free sqlite3_api->mutex_free +#define sqlite3_mutex_leave sqlite3_api->mutex_leave +#define sqlite3_mutex_try sqlite3_api->mutex_try +#define sqlite3_open_v2 sqlite3_api->open_v2 +#define sqlite3_release_memory sqlite3_api->release_memory +#define sqlite3_result_error_nomem sqlite3_api->result_error_nomem +#define sqlite3_result_error_toobig sqlite3_api->result_error_toobig +#define sqlite3_sleep sqlite3_api->sleep +#define sqlite3_soft_heap_limit sqlite3_api->soft_heap_limit +#define sqlite3_vfs_find sqlite3_api->vfs_find +#define sqlite3_vfs_register sqlite3_api->vfs_register +#define sqlite3_vfs_unregister sqlite3_api->vfs_unregister +#define sqlite3_threadsafe sqlite3_api->xthreadsafe +#define sqlite3_result_zeroblob sqlite3_api->result_zeroblob +#define sqlite3_result_error_code sqlite3_api->result_error_code +#define sqlite3_test_control sqlite3_api->test_control +#define sqlite3_randomness sqlite3_api->randomness +#define sqlite3_context_db_handle sqlite3_api->context_db_handle +#define sqlite3_extended_result_codes sqlite3_api->extended_result_codes +#define sqlite3_limit sqlite3_api->limit +#define sqlite3_next_stmt sqlite3_api->next_stmt +#define sqlite3_sql sqlite3_api->sql +#define sqlite3_status sqlite3_api->status +#define sqlite3_backup_finish sqlite3_api->backup_finish +#define sqlite3_backup_init sqlite3_api->backup_init +#define sqlite3_backup_pagecount sqlite3_api->backup_pagecount +#define sqlite3_backup_remaining sqlite3_api->backup_remaining +#define sqlite3_backup_step sqlite3_api->backup_step +#define sqlite3_compileoption_get sqlite3_api->compileoption_get +#define sqlite3_compileoption_used sqlite3_api->compileoption_used +#define sqlite3_create_function_v2 sqlite3_api->create_function_v2 +#define sqlite3_db_config sqlite3_api->db_config +#define sqlite3_db_mutex sqlite3_api->db_mutex +#define sqlite3_db_status sqlite3_api->db_status +#define sqlite3_extended_errcode sqlite3_api->extended_errcode +#define sqlite3_log sqlite3_api->log +#define sqlite3_soft_heap_limit64 sqlite3_api->soft_heap_limit64 +#define sqlite3_sourceid sqlite3_api->sourceid +#define sqlite3_stmt_status sqlite3_api->stmt_status +#define sqlite3_strnicmp sqlite3_api->strnicmp +#define sqlite3_unlock_notify sqlite3_api->unlock_notify +#define sqlite3_wal_autocheckpoint sqlite3_api->wal_autocheckpoint +#define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint +#define sqlite3_wal_hook sqlite3_api->wal_hook +#define sqlite3_blob_reopen sqlite3_api->blob_reopen +#define sqlite3_vtab_config sqlite3_api->vtab_config +#define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict +/* Version 3.7.16 and later */ +#define sqlite3_close_v2 sqlite3_api->close_v2 +#define sqlite3_db_filename sqlite3_api->db_filename +#define sqlite3_db_readonly sqlite3_api->db_readonly +#define sqlite3_db_release_memory sqlite3_api->db_release_memory +#define sqlite3_errstr sqlite3_api->errstr +#define sqlite3_stmt_busy sqlite3_api->stmt_busy +#define sqlite3_stmt_readonly sqlite3_api->stmt_readonly +#define sqlite3_stricmp sqlite3_api->stricmp +#define sqlite3_uri_boolean sqlite3_api->uri_boolean +#define sqlite3_uri_int64 sqlite3_api->uri_int64 +#define sqlite3_uri_parameter sqlite3_api->uri_parameter +#define sqlite3_uri_vsnprintf sqlite3_api->xvsnprintf +#define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2 +/* Version 3.8.7 and later */ +#define sqlite3_auto_extension sqlite3_api->auto_extension +#define sqlite3_bind_blob64 sqlite3_api->bind_blob64 +#define sqlite3_bind_text64 sqlite3_api->bind_text64 +#define sqlite3_cancel_auto_extension sqlite3_api->cancel_auto_extension +#define sqlite3_load_extension sqlite3_api->load_extension +#define sqlite3_malloc64 sqlite3_api->malloc64 +#define sqlite3_msize sqlite3_api->msize +#define sqlite3_realloc64 sqlite3_api->realloc64 +#define sqlite3_reset_auto_extension sqlite3_api->reset_auto_extension +#define sqlite3_result_blob64 sqlite3_api->result_blob64 +#define sqlite3_result_text64 sqlite3_api->result_text64 +#define sqlite3_strglob sqlite3_api->strglob +/* Version 3.8.11 and later */ +#define sqlite3_value_dup sqlite3_api->value_dup +#define sqlite3_value_free sqlite3_api->value_free +#define sqlite3_result_zeroblob64 sqlite3_api->result_zeroblob64 +#define sqlite3_bind_zeroblob64 sqlite3_api->bind_zeroblob64 +/* Version 3.9.0 and later */ +#define sqlite3_value_subtype sqlite3_api->value_subtype +#define sqlite3_result_subtype sqlite3_api->result_subtype +/* Version 3.10.0 and later */ +#define sqlite3_status64 sqlite3_api->status64 +#define sqlite3_strlike sqlite3_api->strlike +#define sqlite3_db_cacheflush sqlite3_api->db_cacheflush +/* Version 3.12.0 and later */ +#define sqlite3_system_errno sqlite3_api->system_errno +/* Version 3.14.0 and later */ +#define sqlite3_trace_v2 sqlite3_api->trace_v2 +#define sqlite3_expanded_sql sqlite3_api->expanded_sql +/* Version 3.18.0 and later */ +#define sqlite3_set_last_insert_rowid sqlite3_api->set_last_insert_rowid +/* Version 3.20.0 and later */ +#define sqlite3_prepare_v3 sqlite3_api->prepare_v3 +#define sqlite3_prepare16_v3 sqlite3_api->prepare16_v3 +#define sqlite3_bind_pointer sqlite3_api->bind_pointer +#define sqlite3_result_pointer sqlite3_api->result_pointer +#define sqlite3_value_pointer sqlite3_api->value_pointer +/* Version 3.22.0 and later */ +#define sqlite3_vtab_nochange sqlite3_api->vtab_nochange +#define sqlite3_value_nochange sqlite3_api->value_nochange +#define sqlite3_vtab_collation sqlite3_api->vtab_collation +/* Version 3.24.0 and later */ +#define sqlite3_keyword_count sqlite3_api->keyword_count +#define sqlite3_keyword_name sqlite3_api->keyword_name +#define sqlite3_keyword_check sqlite3_api->keyword_check +#define sqlite3_str_new sqlite3_api->str_new +#define sqlite3_str_finish sqlite3_api->str_finish +#define sqlite3_str_appendf sqlite3_api->str_appendf +#define sqlite3_str_vappendf sqlite3_api->str_vappendf +#define sqlite3_str_append sqlite3_api->str_append +#define sqlite3_str_appendall sqlite3_api->str_appendall +#define sqlite3_str_appendchar sqlite3_api->str_appendchar +#define sqlite3_str_reset sqlite3_api->str_reset +#define sqlite3_str_errcode sqlite3_api->str_errcode +#define sqlite3_str_length sqlite3_api->str_length +#define sqlite3_str_value sqlite3_api->str_value +/* Version 3.25.0 and later */ +#define sqlite3_create_window_function sqlite3_api->create_window_function +/* Version 3.26.0 and later */ +#define sqlite3_normalized_sql sqlite3_api->normalized_sql +/* Version 3.28.0 and later */ +#define sqlite3_stmt_isexplain sqlite3_api->stmt_isexplain +#define sqlite3_value_frombind sqlite3_api->value_frombind +/* Version 3.30.0 and later */ +#define sqlite3_drop_modules sqlite3_api->drop_modules +/* Version 3.31.0 and later */ +#define sqlite3_hard_heap_limit64 sqlite3_api->hard_heap_limit64 +#define sqlite3_uri_key sqlite3_api->uri_key +#define sqlite3_filename_database sqlite3_api->filename_database +#define sqlite3_filename_journal sqlite3_api->filename_journal +#define sqlite3_filename_wal sqlite3_api->filename_wal +/* Version 3.32.0 and later */ +#define sqlite3_create_filename sqlite3_api->create_filename +#define sqlite3_free_filename sqlite3_api->free_filename +#define sqlite3_database_file_object sqlite3_api->database_file_object +/* Version 3.34.0 and later */ +#define sqlite3_txn_state sqlite3_api->txn_state +/* Version 3.36.1 and later */ +#define sqlite3_changes64 sqlite3_api->changes64 +#define sqlite3_total_changes64 sqlite3_api->total_changes64 +/* Version 3.37.0 and later */ +#define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages +/* Version 3.38.0 and later */ +#define sqlite3_error_offset sqlite3_api->error_offset +#define sqlite3_vtab_rhs_value sqlite3_api->vtab_rhs_value +#define sqlite3_vtab_distinct sqlite3_api->vtab_distinct +#define sqlite3_vtab_in sqlite3_api->vtab_in +#define sqlite3_vtab_in_first sqlite3_api->vtab_in_first +#define sqlite3_vtab_in_next sqlite3_api->vtab_in_next +/* Version 3.39.0 and later */ +#ifndef SQLITE_OMIT_DESERIALIZE +#define sqlite3_deserialize sqlite3_api->deserialize +#define sqlite3_serialize sqlite3_api->serialize +#endif +#define sqlite3_db_name sqlite3_api->db_name +/* Version 3.40.0 and later */ +#define sqlite3_value_encoding sqlite3_api->value_encoding +/* Version 3.41.0 and later */ +#define sqlite3_is_interrupted sqlite3_api->is_interrupted +/* Version 3.43.0 and later */ +#define sqlite3_stmt_explain sqlite3_api->stmt_explain +/* Version 3.44.0 and later */ +#define sqlite3_get_clientdata sqlite3_api->get_clientdata +#define sqlite3_set_clientdata sqlite3_api->set_clientdata +/* Version 3.50.0 and later */ +#define sqlite3_setlk_timeout sqlite3_api->setlk_timeout +/* Version 3.51.0 and later */ +#define sqlite3_set_errmsg sqlite3_api->set_errmsg +#define sqlite3_db_status64 sqlite3_api->db_status64 +/* Version 3.52.0 and later */ +#define sqlite3_str_truncate sqlite3_api->str_truncate +#define sqlite3_str_free sqlite3_api->str_free +#define sqlite3_carray_bind sqlite3_api->carray_bind +#define sqlite3_carray_bind_v2 sqlite3_api->carray_bind_v2 +#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ + +#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) + /* This case when the file really is being compiled as a loadable + ** extension */ +# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0; +# define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v; +# define SQLITE_EXTENSION_INIT3 \ + extern const sqlite3_api_routines *sqlite3_api; +#else + /* This case when the file is being statically linked into the + ** application */ +# define SQLITE_EXTENSION_INIT1 /*no-op*/ +# define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */ +# define SQLITE_EXTENSION_INIT3 /*no-op*/ +#endif + +#endif /* SQLITE3EXT_H */ + +/************** End of sqlite3ext.h ******************************************/ +/************** Continuing where we left off in loadext.c ********************/ +/* #include "sqliteInt.h" */ + +#ifndef SQLITE_OMIT_LOAD_EXTENSION +/* +** Some API routines are omitted when various features are +** excluded from a build of SQLite. Substitute a NULL pointer +** for any missing APIs. +*/ +#ifndef SQLITE_ENABLE_COLUMN_METADATA +# define sqlite3_column_database_name 0 +# define sqlite3_column_database_name16 0 +# define sqlite3_column_table_name 0 +# define sqlite3_column_table_name16 0 +# define sqlite3_column_origin_name 0 +# define sqlite3_column_origin_name16 0 +#endif + +#ifdef SQLITE_OMIT_AUTHORIZATION +# define sqlite3_set_authorizer 0 +#endif + +#ifdef SQLITE_OMIT_UTF16 +# define sqlite3_bind_text16 0 +# define sqlite3_collation_needed16 0 +# define sqlite3_column_decltype16 0 +# define sqlite3_column_name16 0 +# define sqlite3_column_text16 0 +# define sqlite3_complete16 0 +# define sqlite3_create_collation16 0 +# define sqlite3_create_function16 0 +# define sqlite3_errmsg16 0 +# define sqlite3_open16 0 +# define sqlite3_prepare16 0 +# define sqlite3_prepare16_v2 0 +# define sqlite3_prepare16_v3 0 +# define sqlite3_result_error16 0 +# define sqlite3_result_text16 0 +# define sqlite3_result_text16be 0 +# define sqlite3_result_text16le 0 +# define sqlite3_value_text16 0 +# define sqlite3_value_text16be 0 +# define sqlite3_value_text16le 0 +# define sqlite3_column_database_name16 0 +# define sqlite3_column_table_name16 0 +# define sqlite3_column_origin_name16 0 +#endif + +#ifdef SQLITE_OMIT_COMPLETE +# define sqlite3_complete 0 +# define sqlite3_complete16 0 +#endif + +#ifdef SQLITE_OMIT_DECLTYPE +# define sqlite3_column_decltype16 0 +# define sqlite3_column_decltype 0 +#endif + +#ifdef SQLITE_OMIT_PROGRESS_CALLBACK +# define sqlite3_progress_handler 0 +#endif + +#ifdef SQLITE_OMIT_VIRTUALTABLE +# define sqlite3_create_module 0 +# define sqlite3_create_module_v2 0 +# define sqlite3_declare_vtab 0 +# define sqlite3_vtab_config 0 +# define sqlite3_vtab_on_conflict 0 +# define sqlite3_vtab_collation 0 +#endif + +#ifdef SQLITE_OMIT_SHARED_CACHE +# define sqlite3_enable_shared_cache 0 +#endif + +#if defined(SQLITE_OMIT_TRACE) || defined(SQLITE_OMIT_DEPRECATED) +# define sqlite3_profile 0 +# define sqlite3_trace 0 +#endif + +#ifdef SQLITE_OMIT_GET_TABLE +# define sqlite3_free_table 0 +# define sqlite3_get_table 0 +#endif + +#ifdef SQLITE_OMIT_INCRBLOB +#define sqlite3_bind_zeroblob 0 +#define sqlite3_blob_bytes 0 +#define sqlite3_blob_close 0 +#define sqlite3_blob_open 0 +#define sqlite3_blob_read 0 +#define sqlite3_blob_write 0 +#define sqlite3_blob_reopen 0 +#endif + +#if defined(SQLITE_OMIT_TRACE) +# define sqlite3_trace_v2 0 +#endif + +/* +** The following structure contains pointers to all SQLite API routines. +** A pointer to this structure is passed into extensions when they are +** loaded so that the extension can make calls back into the SQLite +** library. +** +** When adding new APIs, add them to the bottom of this structure +** in order to preserve backwards compatibility. +** +** Extensions that use newer APIs should first call the +** sqlite3_libversion_number() to make sure that the API they +** intend to use is supported by the library. Extensions should +** also check to make sure that the pointer to the function is +** not NULL before calling it. +*/ +static const sqlite3_api_routines sqlite3Apis = { + sqlite3_aggregate_context, +#ifndef SQLITE_OMIT_DEPRECATED + sqlite3_aggregate_count, +#else + 0, +#endif + sqlite3_bind_blob, + sqlite3_bind_double, + sqlite3_bind_int, + sqlite3_bind_int64, + sqlite3_bind_null, + sqlite3_bind_parameter_count, + sqlite3_bind_parameter_index, + sqlite3_bind_parameter_name, + sqlite3_bind_text, + sqlite3_bind_text16, + sqlite3_bind_value, + sqlite3_busy_handler, + sqlite3_busy_timeout, + sqlite3_changes, + sqlite3_close, + sqlite3_collation_needed, + sqlite3_collation_needed16, + sqlite3_column_blob, + sqlite3_column_bytes, + sqlite3_column_bytes16, + sqlite3_column_count, + sqlite3_column_database_name, + sqlite3_column_database_name16, + sqlite3_column_decltype, + sqlite3_column_decltype16, + sqlite3_column_double, + sqlite3_column_int, + sqlite3_column_int64, + sqlite3_column_name, + sqlite3_column_name16, + sqlite3_column_origin_name, + sqlite3_column_origin_name16, + sqlite3_column_table_name, + sqlite3_column_table_name16, + sqlite3_column_text, + sqlite3_column_text16, + sqlite3_column_type, + sqlite3_column_value, + sqlite3_commit_hook, + sqlite3_complete, + sqlite3_complete16, + sqlite3_create_collation, + sqlite3_create_collation16, + sqlite3_create_function, + sqlite3_create_function16, + sqlite3_create_module, + sqlite3_data_count, + sqlite3_db_handle, + sqlite3_declare_vtab, + sqlite3_enable_shared_cache, + sqlite3_errcode, + sqlite3_errmsg, + sqlite3_errmsg16, + sqlite3_exec, +#ifndef SQLITE_OMIT_DEPRECATED + sqlite3_expired, +#else + 0, +#endif + sqlite3_finalize, + sqlite3_free, + sqlite3_free_table, + sqlite3_get_autocommit, + sqlite3_get_auxdata, + sqlite3_get_table, + 0, /* Was sqlite3_global_recover(), but that function is deprecated */ + sqlite3_interrupt, + sqlite3_last_insert_rowid, + sqlite3_libversion, + sqlite3_libversion_number, + sqlite3_malloc, + sqlite3_mprintf, + sqlite3_open, + sqlite3_open16, + sqlite3_prepare, + sqlite3_prepare16, + sqlite3_profile, + sqlite3_progress_handler, + sqlite3_realloc, + sqlite3_reset, + sqlite3_result_blob, + sqlite3_result_double, + sqlite3_result_error, + sqlite3_result_error16, + sqlite3_result_int, + sqlite3_result_int64, + sqlite3_result_null, + sqlite3_result_text, + sqlite3_result_text16, + sqlite3_result_text16be, + sqlite3_result_text16le, + sqlite3_result_value, + sqlite3_rollback_hook, + sqlite3_set_authorizer, + sqlite3_set_auxdata, + sqlite3_snprintf, + sqlite3_step, + sqlite3_table_column_metadata, +#ifndef SQLITE_OMIT_DEPRECATED + sqlite3_thread_cleanup, +#else + 0, +#endif + sqlite3_total_changes, + sqlite3_trace, +#ifndef SQLITE_OMIT_DEPRECATED + sqlite3_transfer_bindings, +#else + 0, +#endif + sqlite3_update_hook, + sqlite3_user_data, + sqlite3_value_blob, + sqlite3_value_bytes, + sqlite3_value_bytes16, + sqlite3_value_double, + sqlite3_value_int, + sqlite3_value_int64, + sqlite3_value_numeric_type, + sqlite3_value_text, + sqlite3_value_text16, + sqlite3_value_text16be, + sqlite3_value_text16le, + sqlite3_value_type, + sqlite3_vmprintf, + /* + ** The original API set ends here. All extensions can call any + ** of the APIs above provided that the pointer is not NULL. But + ** before calling APIs that follow, extension should check the + ** sqlite3_libversion_number() to make sure they are dealing with + ** a library that is new enough to support that API. + ************************************************************************* + */ + sqlite3_overload_function, + + /* + ** Added after 3.3.13 + */ + sqlite3_prepare_v2, + sqlite3_prepare16_v2, + sqlite3_clear_bindings, + + /* + ** Added for 3.4.1 + */ + sqlite3_create_module_v2, + + /* + ** Added for 3.5.0 + */ + sqlite3_bind_zeroblob, + sqlite3_blob_bytes, + sqlite3_blob_close, + sqlite3_blob_open, + sqlite3_blob_read, + sqlite3_blob_write, + sqlite3_create_collation_v2, + sqlite3_file_control, + sqlite3_memory_highwater, + sqlite3_memory_used, +#ifdef SQLITE_MUTEX_OMIT + 0, + 0, + 0, + 0, + 0, +#else + sqlite3_mutex_alloc, + sqlite3_mutex_enter, + sqlite3_mutex_free, + sqlite3_mutex_leave, + sqlite3_mutex_try, +#endif + sqlite3_open_v2, + sqlite3_release_memory, + sqlite3_result_error_nomem, + sqlite3_result_error_toobig, + sqlite3_sleep, + sqlite3_soft_heap_limit, + sqlite3_vfs_find, + sqlite3_vfs_register, + sqlite3_vfs_unregister, + + /* + ** Added for 3.5.8 + */ + sqlite3_threadsafe, + sqlite3_result_zeroblob, + sqlite3_result_error_code, + sqlite3_test_control, + sqlite3_randomness, + sqlite3_context_db_handle, + + /* + ** Added for 3.6.0 + */ + sqlite3_extended_result_codes, + sqlite3_limit, + sqlite3_next_stmt, + sqlite3_sql, + sqlite3_status, + + /* + ** Added for 3.7.4 + */ + sqlite3_backup_finish, + sqlite3_backup_init, + sqlite3_backup_pagecount, + sqlite3_backup_remaining, + sqlite3_backup_step, +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS + sqlite3_compileoption_get, + sqlite3_compileoption_used, +#else + 0, + 0, +#endif + sqlite3_create_function_v2, + sqlite3_db_config, + sqlite3_db_mutex, + sqlite3_db_status, + sqlite3_extended_errcode, + sqlite3_log, + sqlite3_soft_heap_limit64, + sqlite3_sourceid, + sqlite3_stmt_status, + sqlite3_strnicmp, +#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY + sqlite3_unlock_notify, +#else + 0, +#endif +#ifndef SQLITE_OMIT_WAL + sqlite3_wal_autocheckpoint, + sqlite3_wal_checkpoint, + sqlite3_wal_hook, +#else + 0, + 0, + 0, +#endif + sqlite3_blob_reopen, + sqlite3_vtab_config, + sqlite3_vtab_on_conflict, + sqlite3_close_v2, + sqlite3_db_filename, + sqlite3_db_readonly, + sqlite3_db_release_memory, + sqlite3_errstr, + sqlite3_stmt_busy, + sqlite3_stmt_readonly, + sqlite3_stricmp, + sqlite3_uri_boolean, + sqlite3_uri_int64, + sqlite3_uri_parameter, + sqlite3_vsnprintf, + sqlite3_wal_checkpoint_v2, + /* Version 3.8.7 and later */ + sqlite3_auto_extension, + sqlite3_bind_blob64, + sqlite3_bind_text64, + sqlite3_cancel_auto_extension, + sqlite3_load_extension, + sqlite3_malloc64, + sqlite3_msize, + sqlite3_realloc64, + sqlite3_reset_auto_extension, + sqlite3_result_blob64, + sqlite3_result_text64, + sqlite3_strglob, + /* Version 3.8.11 and later */ + (sqlite3_value*(*)(const sqlite3_value*))sqlite3_value_dup, + sqlite3_value_free, + sqlite3_result_zeroblob64, + sqlite3_bind_zeroblob64, + /* Version 3.9.0 and later */ + sqlite3_value_subtype, + sqlite3_result_subtype, + /* Version 3.10.0 and later */ + sqlite3_status64, + sqlite3_strlike, + sqlite3_db_cacheflush, + /* Version 3.12.0 and later */ + sqlite3_system_errno, + /* Version 3.14.0 and later */ + sqlite3_trace_v2, + sqlite3_expanded_sql, + /* Version 3.18.0 and later */ + sqlite3_set_last_insert_rowid, + /* Version 3.20.0 and later */ + sqlite3_prepare_v3, + sqlite3_prepare16_v3, + sqlite3_bind_pointer, + sqlite3_result_pointer, + sqlite3_value_pointer, + /* Version 3.22.0 and later */ + sqlite3_vtab_nochange, + sqlite3_value_nochange, + sqlite3_vtab_collation, + /* Version 3.24.0 and later */ + sqlite3_keyword_count, + sqlite3_keyword_name, + sqlite3_keyword_check, + sqlite3_str_new, + sqlite3_str_finish, + sqlite3_str_appendf, + sqlite3_str_vappendf, + sqlite3_str_append, + sqlite3_str_appendall, + sqlite3_str_appendchar, + sqlite3_str_reset, + sqlite3_str_errcode, + sqlite3_str_length, + sqlite3_str_value, + /* Version 3.25.0 and later */ + sqlite3_create_window_function, + /* Version 3.26.0 and later */ +#ifdef SQLITE_ENABLE_NORMALIZE + sqlite3_normalized_sql, +#else + 0, +#endif + /* Version 3.28.0 and later */ + sqlite3_stmt_isexplain, + sqlite3_value_frombind, + /* Version 3.30.0 and later */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + sqlite3_drop_modules, +#else + 0, +#endif + /* Version 3.31.0 and later */ + sqlite3_hard_heap_limit64, + sqlite3_uri_key, + sqlite3_filename_database, + sqlite3_filename_journal, + sqlite3_filename_wal, + /* Version 3.32.0 and later */ + sqlite3_create_filename, + sqlite3_free_filename, + sqlite3_database_file_object, + /* Version 3.34.0 and later */ + sqlite3_txn_state, + /* Version 3.36.1 and later */ + sqlite3_changes64, + sqlite3_total_changes64, + /* Version 3.37.0 and later */ + sqlite3_autovacuum_pages, + /* Version 3.38.0 and later */ + sqlite3_error_offset, +#ifndef SQLITE_OMIT_VIRTUALTABLE + sqlite3_vtab_rhs_value, + sqlite3_vtab_distinct, + sqlite3_vtab_in, + sqlite3_vtab_in_first, + sqlite3_vtab_in_next, +#else + 0, + 0, + 0, + 0, + 0, +#endif + /* Version 3.39.0 and later */ +#ifndef SQLITE_OMIT_DESERIALIZE + sqlite3_deserialize, + sqlite3_serialize, +#else + 0, + 0, +#endif + sqlite3_db_name, + /* Version 3.40.0 and later */ + sqlite3_value_encoding, + /* Version 3.41.0 and later */ + sqlite3_is_interrupted, + /* Version 3.43.0 and later */ + sqlite3_stmt_explain, + /* Version 3.44.0 and later */ + sqlite3_get_clientdata, + sqlite3_set_clientdata, + /* Version 3.50.0 and later */ + sqlite3_setlk_timeout, + /* Version 3.51.0 and later */ + sqlite3_set_errmsg, + sqlite3_db_status64, + /* Version 3.52.0 and later */ + sqlite3_str_truncate, + sqlite3_str_free, +#ifdef SQLITE_ENABLE_CARRAY + sqlite3_carray_bind, + sqlite3_carray_bind_v2 +#else + 0, + 0 +#endif +}; + +/* True if x is the directory separator character +*/ +#if SQLITE_OS_WIN +# define DirSep(X) ((X)=='/'||(X)=='\\') +#else +# define DirSep(X) ((X)=='/') +#endif + +/* +** Attempt to load an SQLite extension library contained in the file +** zFile. The entry point is zProc. zProc may be 0 in which case a +** default entry point name (sqlite3_extension_init) is used. Use +** of the default name is recommended. +** +** Return SQLITE_OK on success and SQLITE_ERROR if something goes wrong. +** +** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with +** error message text. The calling function should free this memory +** by calling sqlite3DbFree(db, ). +*/ +static int sqlite3LoadExtension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +){ + sqlite3_vfs *pVfs = db->pVfs; + void *handle; + sqlite3_loadext_entry xInit; + char *zErrmsg = 0; + const char *zEntry; + char *zAltEntry = 0; + void **aHandle; + u64 nMsg = strlen(zFile); + int ii; + int rc; + + /* Shared library endings to try if zFile cannot be loaded as written */ + static const char *azEndings[] = { +#if SQLITE_OS_WIN + "dll" +#elif defined(__APPLE__) + "dylib" +#else + "so" +#endif + }; + + + if( pzErrMsg ) *pzErrMsg = 0; + + /* Ticket #1863. To avoid a creating security problems for older + ** applications that relink against newer versions of SQLite, the + ** ability to run load_extension is turned off by default. One + ** must call either sqlite3_enable_load_extension(db) or + ** sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, 0) + ** to turn on extension loading. + */ + if( (db->flags & SQLITE_LoadExtension)==0 ){ + if( pzErrMsg ){ + *pzErrMsg = sqlite3_mprintf("not authorized"); + } + return SQLITE_ERROR; + } + + zEntry = zProc ? zProc : "sqlite3_extension_init"; + + /* tag-20210611-1. Some dlopen() implementations will segfault if given + ** an oversize filename. Most filesystems have a pathname limit of 4K, + ** so limit the extension filename length to about twice that. + ** https://sqlite.org/forum/forumpost/08a0d6d9bf + ** + ** Later (2023-03-25): Save an extra 6 bytes for the filename suffix. + ** See https://sqlite.org/forum/forumpost/24083b579d. + */ + if( nMsg>SQLITE_MAX_PATHLEN ) goto extension_not_found; + + /* Do not allow sqlite3_load_extension() to link to a copy of the + ** running application, by passing in an empty filename. */ + if( nMsg==0 ) goto extension_not_found; + + handle = sqlite3OsDlOpen(pVfs, zFile); +#if SQLITE_OS_UNIX || SQLITE_OS_WIN + for(ii=0; ii sqlite3_example_init + ** C:/lib/mathfuncs.dll ==> sqlite3_mathfuncs_init + ** + ** If that still finds no entry point, repeat a second time but this + ** time include both alphabetic and numeric characters up to the first + ** ".". Example: + ** + ** /usr/local/lib/libExample5.4.3.so ==> sqlite3_example5_init + */ + if( xInit==0 && zProc==0 ){ + int iFile, iEntry, c; + int ncFile = sqlite3Strlen30(zFile); + int cnt = 0; + zAltEntry = sqlite3_malloc64(ncFile+30); + if( zAltEntry==0 ){ + sqlite3OsDlClose(pVfs, handle); + return SQLITE_NOMEM_BKPT; + } + do{ + memcpy(zAltEntry, "sqlite3_", 8); + for(iFile=ncFile-1; iFile>=0 && !DirSep(zFile[iFile]); iFile--){} + iFile++; + if( sqlite3_strnicmp(zFile+iFile, "lib", 3)==0 ) iFile += 3; + for(iEntry=8; (c = zFile[iFile])!=0 && c!='.'; iFile++){ + if( sqlite3Isalpha(c) || (cnt && sqlite3Isdigit(c)) ){ + zAltEntry[iEntry++] = (char)sqlite3UpperToLower[(unsigned)c]; + } + } + memcpy(zAltEntry+iEntry, "_init", 6); + zEntry = zAltEntry; + xInit = (sqlite3_loadext_entry)sqlite3OsDlSym(pVfs, handle, zEntry); + }while( xInit==0 && (++cnt)<2 ); + } + if( xInit==0 ){ + if( pzErrMsg ){ + nMsg += strlen(zEntry) + 300; + *pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg); + if( zErrmsg ){ + assert( nMsg<0x7fffffff ); /* zErrmsg would be NULL if not so */ + sqlite3_snprintf((int)nMsg, zErrmsg, + "no entry point [%s] in shared library [%s]", zEntry, zFile); + sqlite3OsDlError(pVfs, nMsg-1, zErrmsg); + } + } + sqlite3OsDlClose(pVfs, handle); + sqlite3_free(zAltEntry); + return SQLITE_ERROR; + } + sqlite3_free(zAltEntry); + rc = xInit(db, &zErrmsg, &sqlite3Apis); + if( rc ){ + if( rc==SQLITE_OK_LOAD_PERMANENTLY ) return SQLITE_OK; + if( pzErrMsg ){ + *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg); + } + sqlite3_free(zErrmsg); + sqlite3OsDlClose(pVfs, handle); + return SQLITE_ERROR; + } + + /* Append the new shared library handle to the db->aExtension array. */ + aHandle = sqlite3DbMallocZero(db, sizeof(handle)*(db->nExtension+1)); + if( aHandle==0 ){ + return SQLITE_NOMEM_BKPT; + } + if( db->nExtension>0 ){ + memcpy(aHandle, db->aExtension, sizeof(handle)*db->nExtension); + } + sqlite3DbFree(db, db->aExtension); + db->aExtension = aHandle; + + db->aExtension[db->nExtension++] = handle; + return SQLITE_OK; + +extension_not_found: + if( pzErrMsg ){ + nMsg += 300; + *pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg); + if( zErrmsg ){ + assert( nMsg<0x7fffffff ); /* zErrmsg would be NULL if not so */ + sqlite3_snprintf((int)nMsg, zErrmsg, + "unable to open shared library [%.*s]", SQLITE_MAX_PATHLEN, zFile); + sqlite3OsDlError(pVfs, nMsg-1, zErrmsg); + } + } + return SQLITE_ERROR; +} +SQLITE_API int sqlite3_load_extension( + sqlite3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ +){ + int rc; + sqlite3_mutex_enter(db->mutex); + rc = sqlite3LoadExtension(db, zFile, zProc, pzErrMsg); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Call this routine when the database connection is closing in order +** to clean up loaded extensions +*/ +SQLITE_PRIVATE void sqlite3CloseExtensions(sqlite3 *db){ + int i; + assert( sqlite3_mutex_held(db->mutex) ); + for(i=0; inExtension; i++){ + sqlite3OsDlClose(db->pVfs, db->aExtension[i]); + } + sqlite3DbFree(db, db->aExtension); +} + +/* +** Enable or disable extension loading. Extension loading is disabled by +** default so as not to open security holes in older applications. +*/ +SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + if( onoff ){ + db->flags |= SQLITE_LoadExtension|SQLITE_LoadExtFunc; + }else{ + db->flags &= ~(u64)(SQLITE_LoadExtension|SQLITE_LoadExtFunc); + } + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + +#endif /* !defined(SQLITE_OMIT_LOAD_EXTENSION) */ + +/* +** The following object holds the list of automatically loaded +** extensions. +** +** This list is shared across threads. The SQLITE_MUTEX_STATIC_MAIN +** mutex must be held while accessing this list. +*/ +typedef struct sqlite3AutoExtList sqlite3AutoExtList; +static SQLITE_WSD struct sqlite3AutoExtList { + u32 nExt; /* Number of entries in aExt[] */ + void (**aExt)(void); /* Pointers to the extension init functions */ +} sqlite3Autoext = { 0, 0 }; + +/* The "wsdAutoext" macro will resolve to the autoextension +** state vector. If writable static data is unsupported on the target, +** we have to locate the state vector at run-time. In the more common +** case where writable static data is supported, wsdStat can refer directly +** to the "sqlite3Autoext" state vector declared above. +*/ +#ifdef SQLITE_OMIT_WSD +# define wsdAutoextInit \ + sqlite3AutoExtList *x = &GLOBAL(sqlite3AutoExtList,sqlite3Autoext) +# define wsdAutoext x[0] +#else +# define wsdAutoextInit +# define wsdAutoext sqlite3Autoext +#endif + + +/* +** Register a statically linked extension that is automatically +** loaded by every new database connection. +*/ +SQLITE_API int sqlite3_auto_extension( + void (*xInit)(void) +){ + int rc = SQLITE_OK; +#ifdef SQLITE_ENABLE_API_ARMOR + if( xInit==0 ) return SQLITE_MISUSE_BKPT; +#endif +#ifndef SQLITE_OMIT_AUTOINIT + rc = sqlite3_initialize(); + if( rc ){ + return rc; + }else +#endif + { + u32 i; +#if SQLITE_THREADSAFE + sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); +#endif + wsdAutoextInit; + sqlite3_mutex_enter(mutex); + for(i=0; i=0; i--){ + if( wsdAutoext.aExt[i]==xInit ){ + wsdAutoext.nExt--; + wsdAutoext.aExt[i] = wsdAutoext.aExt[wsdAutoext.nExt]; + n++; + break; + } + } + sqlite3_mutex_leave(mutex); + return n; +} + +/* +** Reset the automatic extension loading mechanism. +*/ +SQLITE_API void sqlite3_reset_auto_extension(void){ +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize()==SQLITE_OK ) +#endif + { +#if SQLITE_THREADSAFE + sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); +#endif + wsdAutoextInit; + sqlite3_mutex_enter(mutex); + sqlite3_free(wsdAutoext.aExt); + wsdAutoext.aExt = 0; + wsdAutoext.nExt = 0; + sqlite3_mutex_leave(mutex); + } +} + +/* +** Load all automatic extensions. +** +** If anything goes wrong, set an error in the database connection. +*/ +SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){ + u32 i; + int go = 1; + int rc; + sqlite3_loadext_entry xInit; + + wsdAutoextInit; + if( wsdAutoext.nExt==0 ){ + /* Common case: early out without every having to acquire a mutex */ + return; + } + for(i=0; go; i++){ + char *zErrmsg; +#if SQLITE_THREADSAFE + sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); +#endif +#ifdef SQLITE_OMIT_LOAD_EXTENSION + const sqlite3_api_routines *pThunk = 0; +#else + const sqlite3_api_routines *pThunk = &sqlite3Apis; +#endif + sqlite3_mutex_enter(mutex); + if( i>=wsdAutoext.nExt ){ + xInit = 0; + go = 0; + }else{ + xInit = (sqlite3_loadext_entry)wsdAutoext.aExt[i]; + } + sqlite3_mutex_leave(mutex); + zErrmsg = 0; + if( xInit && (rc = xInit(db, &zErrmsg, pThunk))!=0 ){ + sqlite3ErrorWithMsg(db, rc, + "automatic extension loading failed: %s", zErrmsg); + go = 0; + } + sqlite3_free(zErrmsg); + } +} + +/************** End of loadext.c *********************************************/ +/************** Begin file pragma.c ******************************************/ +/* +** 2003 April 6 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code used to implement the PRAGMA command. +*/ +/* #include "sqliteInt.h" */ + +#if !defined(SQLITE_ENABLE_LOCKING_STYLE) +# if defined(__APPLE__) +# define SQLITE_ENABLE_LOCKING_STYLE 1 +# else +# define SQLITE_ENABLE_LOCKING_STYLE 0 +# endif +#endif + +/*************************************************************************** +** The "pragma.h" include file is an automatically generated file that +** that includes the PragType_XXXX macro definitions and the aPragmaName[] +** object. This ensures that the aPragmaName[] table is arranged in +** lexicographical order to facility a binary search of the pragma name. +** Do not edit pragma.h directly. Edit and rerun the script in at +** ../tool/mkpragmatab.tcl. */ +/************** Include pragma.h in the middle of pragma.c *******************/ +/************** Begin file pragma.h ******************************************/ +/* DO NOT EDIT! +** This file is automatically generated by the script at +** ../tool/mkpragmatab.tcl. To update the set of pragmas, edit +** that script and rerun it. +*/ + +/* The various pragma types */ +#define PragTyp_ACTIVATE_EXTENSIONS 0 +#define PragTyp_ANALYSIS_LIMIT 1 +#define PragTyp_HEADER_VALUE 2 +#define PragTyp_AUTO_VACUUM 3 +#define PragTyp_FLAG 4 +#define PragTyp_BUSY_TIMEOUT 5 +#define PragTyp_CACHE_SIZE 6 +#define PragTyp_CACHE_SPILL 7 +#define PragTyp_CASE_SENSITIVE_LIKE 8 +#define PragTyp_COLLATION_LIST 9 +#define PragTyp_COMPILE_OPTIONS 10 +#define PragTyp_DATA_STORE_DIRECTORY 11 +#define PragTyp_DATABASE_LIST 12 +#define PragTyp_DEFAULT_CACHE_SIZE 13 +#define PragTyp_ENCODING 14 +#define PragTyp_FOREIGN_KEY_CHECK 15 +#define PragTyp_FOREIGN_KEY_LIST 16 +#define PragTyp_FUNCTION_LIST 17 +#define PragTyp_HARD_HEAP_LIMIT 18 +#define PragTyp_INCREMENTAL_VACUUM 19 +#define PragTyp_INDEX_INFO 20 +#define PragTyp_INDEX_LIST 21 +#define PragTyp_INTEGRITY_CHECK 22 +#define PragTyp_JOURNAL_MODE 23 +#define PragTyp_JOURNAL_SIZE_LIMIT 24 +#define PragTyp_LOCK_PROXY_FILE 25 +#define PragTyp_LOCKING_MODE 26 +#define PragTyp_PAGE_COUNT 27 +#define PragTyp_MMAP_SIZE 28 +#define PragTyp_MODULE_LIST 29 +#define PragTyp_OPTIMIZE 30 +#define PragTyp_PAGE_SIZE 31 +#define PragTyp_PRAGMA_LIST 32 +#define PragTyp_SECURE_DELETE 33 +#define PragTyp_SHRINK_MEMORY 34 +#define PragTyp_SOFT_HEAP_LIMIT 35 +#define PragTyp_SYNCHRONOUS 36 +#define PragTyp_TABLE_INFO 37 +#define PragTyp_TABLE_LIST 38 +#define PragTyp_TEMP_STORE 39 +#define PragTyp_TEMP_STORE_DIRECTORY 40 +#define PragTyp_THREADS 41 +#define PragTyp_WAL_AUTOCHECKPOINT 42 +#define PragTyp_WAL_CHECKPOINT 43 +#define PragTyp_LOCK_STATUS 44 +#define PragTyp_STATS 45 + +/* Property flags associated with various pragma. */ +#define PragFlg_NeedSchema 0x01 /* Force schema load before running */ +#define PragFlg_NoColumns 0x02 /* OP_ResultRow called with zero columns */ +#define PragFlg_NoColumns1 0x04 /* zero columns if RHS argument is present */ +#define PragFlg_ReadOnly 0x08 /* Read-only HEADER_VALUE */ +#define PragFlg_Result0 0x10 /* Acts as query when no argument */ +#define PragFlg_Result1 0x20 /* Acts as query when has one argument */ +#define PragFlg_SchemaOpt 0x40 /* Schema restricts name search if present */ +#define PragFlg_SchemaReq 0x80 /* Schema required - "main" is default */ + +/* Names of columns for pragmas that return multi-column result +** or that return single-column results where the name of the +** result column is different from the name of the pragma +*/ +static const char *const pragCName[] = { + /* 0 */ "id", /* Used by: foreign_key_list */ + /* 1 */ "seq", + /* 2 */ "table", + /* 3 */ "from", + /* 4 */ "to", + /* 5 */ "on_update", + /* 6 */ "on_delete", + /* 7 */ "match", + /* 8 */ "cid", /* Used by: table_xinfo */ + /* 9 */ "name", + /* 10 */ "type", + /* 11 */ "notnull", + /* 12 */ "dflt_value", + /* 13 */ "pk", + /* 14 */ "hidden", + /* table_info reuses 8 */ + /* 15 */ "name", /* Used by: function_list */ + /* 16 */ "builtin", + /* 17 */ "type", + /* 18 */ "enc", + /* 19 */ "narg", + /* 20 */ "flags", + /* 21 */ "schema", /* Used by: table_list */ + /* 22 */ "name", + /* 23 */ "type", + /* 24 */ "ncol", + /* 25 */ "wr", + /* 26 */ "strict", + /* 27 */ "seqno", /* Used by: index_xinfo */ + /* 28 */ "cid", + /* 29 */ "name", + /* 30 */ "desc", + /* 31 */ "coll", + /* 32 */ "key", + /* 33 */ "seq", /* Used by: index_list */ + /* 34 */ "name", + /* 35 */ "unique", + /* 36 */ "origin", + /* 37 */ "partial", + /* 38 */ "tbl", /* Used by: stats */ + /* 39 */ "idx", + /* 40 */ "wdth", + /* 41 */ "hght", + /* 42 */ "flgs", + /* 43 */ "table", /* Used by: foreign_key_check */ + /* 44 */ "rowid", + /* 45 */ "parent", + /* 46 */ "fkid", + /* 47 */ "busy", /* Used by: wal_checkpoint */ + /* 48 */ "log", + /* 49 */ "checkpointed", + /* 50 */ "seq", /* Used by: database_list */ + /* 51 */ "name", + /* 52 */ "file", + /* index_info reuses 27 */ + /* 53 */ "database", /* Used by: lock_status */ + /* 54 */ "status", + /* collation_list reuses 33 */ + /* 55 */ "cache_size", /* Used by: default_cache_size */ + /* module_list pragma_list reuses 9 */ + /* 56 */ "timeout", /* Used by: busy_timeout */ +}; + +/* Definitions of all built-in pragmas */ +typedef struct PragmaName { + const char *const zName; /* Name of pragma */ + u8 ePragTyp; /* PragTyp_XXX value */ + u8 mPragFlg; /* Zero or more PragFlg_XXX values */ + u8 iPragCName; /* Start of column names in pragCName[] */ + u8 nPragCName; /* Num of col names. 0 means use pragma name */ + u64 iArg; /* Extra argument */ +} PragmaName; +static const PragmaName aPragmaName[] = { +#if defined(SQLITE_ENABLE_CEROD) + {/* zName: */ "activate_extensions", + /* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS, + /* ePragFlg: */ 0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif + {/* zName: */ "analysis_limit", + /* ePragTyp: */ PragTyp_ANALYSIS_LIMIT, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) + {/* zName: */ "application_id", + /* ePragTyp: */ PragTyp_HEADER_VALUE, + /* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ BTREE_APPLICATION_ID }, +#endif +#if !defined(SQLITE_OMIT_AUTOVACUUM) + {/* zName: */ "auto_vacuum", + /* ePragTyp: */ PragTyp_AUTO_VACUUM, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) +#if !defined(SQLITE_OMIT_AUTOMATIC_INDEX) + {/* zName: */ "automatic_index", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_AutoIndex }, +#endif +#endif + {/* zName: */ "busy_timeout", + /* ePragTyp: */ PragTyp_BUSY_TIMEOUT, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 56, 1, + /* iArg: */ 0 }, +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + {/* zName: */ "cache_size", + /* ePragTyp: */ PragTyp_CACHE_SIZE, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + {/* zName: */ "cache_spill", + /* ePragTyp: */ PragTyp_CACHE_SPILL, + /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA) + {/* zName: */ "case_sensitive_like", + /* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE, + /* ePragFlg: */ PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif + {/* zName: */ "cell_size_check", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_CellSizeCk }, +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + {/* zName: */ "checkpoint_fullfsync", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_CkptFullFSync }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + {/* zName: */ "collation_list", + /* ePragTyp: */ PragTyp_COLLATION_LIST, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 33, 2, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) + {/* zName: */ "compile_options", + /* ePragTyp: */ PragTyp_COMPILE_OPTIONS, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + {/* zName: */ "count_changes", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_CountRows }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN + {/* zName: */ "data_store_directory", + /* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY, + /* ePragFlg: */ PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) + {/* zName: */ "data_version", + /* ePragTyp: */ PragTyp_HEADER_VALUE, + /* ePragFlg: */ PragFlg_ReadOnly|PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ BTREE_DATA_VERSION }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + {/* zName: */ "database_list", + /* ePragTyp: */ PragTyp_DATABASE_LIST, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 50, 3, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) + {/* zName: */ "default_cache_size", + /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, + /* ColNames: */ 55, 1, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) + {/* zName: */ "defer_foreign_keys", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_DeferFKs }, +#endif +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + {/* zName: */ "empty_result_callbacks", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_NullCallback }, +#endif +#if !defined(SQLITE_OMIT_UTF16) + {/* zName: */ "encoding", + /* ePragTyp: */ PragTyp_ENCODING, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) + {/* zName: */ "foreign_key_check", + /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1|PragFlg_SchemaOpt, + /* ColNames: */ 43, 4, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FOREIGN_KEY) + {/* zName: */ "foreign_key_list", + /* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, + /* ColNames: */ 0, 8, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) + {/* zName: */ "foreign_keys", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_ForeignKeys }, +#endif +#endif +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) + {/* zName: */ "freelist_count", + /* ePragTyp: */ PragTyp_HEADER_VALUE, + /* ePragFlg: */ PragFlg_ReadOnly|PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ BTREE_FREE_PAGE_COUNT }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + {/* zName: */ "full_column_names", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_FullColNames }, + {/* zName: */ "fullfsync", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_FullFSync }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) +#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) + {/* zName: */ "function_list", + /* ePragTyp: */ PragTyp_FUNCTION_LIST, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 15, 6, + /* iArg: */ 0 }, +#endif +#endif + {/* zName: */ "hard_heap_limit", + /* ePragTyp: */ PragTyp_HARD_HEAP_LIMIT, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) +#if !defined(SQLITE_OMIT_CHECK) + {/* zName: */ "ignore_check_constraints", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_IgnoreChecks }, +#endif +#endif +#if !defined(SQLITE_OMIT_AUTOVACUUM) + {/* zName: */ "incremental_vacuum", + /* ePragTyp: */ PragTyp_INCREMENTAL_VACUUM, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + {/* zName: */ "index_info", + /* ePragTyp: */ PragTyp_INDEX_INFO, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, + /* ColNames: */ 27, 3, + /* iArg: */ 0 }, + {/* zName: */ "index_list", + /* ePragTyp: */ PragTyp_INDEX_LIST, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, + /* ColNames: */ 33, 5, + /* iArg: */ 0 }, + {/* zName: */ "index_xinfo", + /* ePragTyp: */ PragTyp_INDEX_INFO, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, + /* ColNames: */ 27, 6, + /* iArg: */ 1 }, +#endif +#if !defined(SQLITE_OMIT_INTEGRITY_CHECK) + {/* zName: */ "integrity_check", + /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1|PragFlg_SchemaOpt, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + {/* zName: */ "journal_mode", + /* ePragTyp: */ PragTyp_JOURNAL_MODE, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, + {/* zName: */ "journal_size_limit", + /* ePragTyp: */ PragTyp_JOURNAL_SIZE_LIMIT, + /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + {/* zName: */ "legacy_alter_table", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_LegacyAlter }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE + {/* zName: */ "lock_proxy_file", + /* ePragTyp: */ PragTyp_LOCK_PROXY_FILE, + /* ePragFlg: */ PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + {/* zName: */ "lock_status", + /* ePragTyp: */ PragTyp_LOCK_STATUS, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 53, 2, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + {/* zName: */ "locking_mode", + /* ePragTyp: */ PragTyp_LOCKING_MODE, + /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, + {/* zName: */ "max_page_count", + /* ePragTyp: */ PragTyp_PAGE_COUNT, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, + {/* zName: */ "mmap_size", + /* ePragTyp: */ PragTyp_MMAP_SIZE, + /* ePragFlg: */ 0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) +#if !defined(SQLITE_OMIT_VIRTUALTABLE) +#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) + {/* zName: */ "module_list", + /* ePragTyp: */ PragTyp_MODULE_LIST, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 9, 1, + /* iArg: */ 0 }, +#endif +#endif +#endif + {/* zName: */ "optimize", + /* ePragTyp: */ PragTyp_OPTIMIZE, + /* ePragFlg: */ PragFlg_Result1|PragFlg_NeedSchema, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + {/* zName: */ "page_count", + /* ePragTyp: */ PragTyp_PAGE_COUNT, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, + {/* zName: */ "page_size", + /* ePragTyp: */ PragTyp_PAGE_SIZE, + /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) +#if defined(SQLITE_DEBUG) + {/* zName: */ "parser_trace", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_ParserTrace }, +#endif +#endif +#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) + {/* zName: */ "pragma_list", + /* ePragTyp: */ PragTyp_PRAGMA_LIST, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 9, 1, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + {/* zName: */ "query_only", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_QueryOnly }, +#endif +#if !defined(SQLITE_OMIT_INTEGRITY_CHECK) + {/* zName: */ "quick_check", + /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1|PragFlg_SchemaOpt, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + {/* zName: */ "read_uncommitted", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_ReadUncommit }, + {/* zName: */ "recursive_triggers", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_RecTriggers }, + {/* zName: */ "reverse_unordered_selects", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_ReverseOrder }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) + {/* zName: */ "schema_version", + /* ePragTyp: */ PragTyp_HEADER_VALUE, + /* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ BTREE_SCHEMA_VERSION }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + {/* zName: */ "secure_delete", + /* ePragTyp: */ PragTyp_SECURE_DELETE, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + {/* zName: */ "short_column_names", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_ShortColNames }, +#endif + {/* zName: */ "shrink_memory", + /* ePragTyp: */ PragTyp_SHRINK_MEMORY, + /* ePragFlg: */ PragFlg_NoColumns, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, + {/* zName: */ "soft_heap_limit", + /* ePragTyp: */ PragTyp_SOFT_HEAP_LIMIT, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) +#if defined(SQLITE_DEBUG) + {/* zName: */ "sql_trace", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_SqlTrace }, +#endif +#endif +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG) + {/* zName: */ "stats", + /* ePragTyp: */ PragTyp_STATS, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, + /* ColNames: */ 38, 5, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + {/* zName: */ "synchronous", + /* ePragTyp: */ PragTyp_SYNCHRONOUS, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) + {/* zName: */ "table_info", + /* ePragTyp: */ PragTyp_TABLE_INFO, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, + /* ColNames: */ 8, 6, + /* iArg: */ 0 }, + {/* zName: */ "table_list", + /* ePragTyp: */ PragTyp_TABLE_LIST, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1, + /* ColNames: */ 21, 6, + /* iArg: */ 0 }, + {/* zName: */ "table_xinfo", + /* ePragTyp: */ PragTyp_TABLE_INFO, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, + /* ColNames: */ 8, 7, + /* iArg: */ 1 }, +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + {/* zName: */ "temp_store", + /* ePragTyp: */ PragTyp_TEMP_STORE, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, + {/* zName: */ "temp_store_directory", + /* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY, + /* ePragFlg: */ PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#endif + {/* zName: */ "threads", + /* ePragTyp: */ PragTyp_THREADS, + /* ePragFlg: */ PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + {/* zName: */ "trusted_schema", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_TrustedSchema }, +#endif +#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS) + {/* zName: */ "user_version", + /* ePragTyp: */ PragTyp_HEADER_VALUE, + /* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0, + /* ColNames: */ 0, 0, + /* iArg: */ BTREE_USER_VERSION }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) +#if defined(SQLITE_DEBUG) + {/* zName: */ "vdbe_addoptrace", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_VdbeAddopTrace }, + {/* zName: */ "vdbe_debug", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace }, + {/* zName: */ "vdbe_eqp", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_VdbeEQP }, + {/* zName: */ "vdbe_listing", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_VdbeListing }, + {/* zName: */ "vdbe_trace", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_VdbeTrace }, +#endif +#endif +#if !defined(SQLITE_OMIT_WAL) + {/* zName: */ "wal_autocheckpoint", + /* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT, + /* ePragFlg: */ 0, + /* ColNames: */ 0, 0, + /* iArg: */ 0 }, + {/* zName: */ "wal_checkpoint", + /* ePragTyp: */ PragTyp_WAL_CHECKPOINT, + /* ePragFlg: */ PragFlg_NeedSchema, + /* ColNames: */ 47, 3, + /* iArg: */ 0 }, +#endif +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + {/* zName: */ "writable_schema", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError }, +#endif +}; +/* Number of pragmas: 68 on by default, 78 total. */ + +/************** End of pragma.h **********************************************/ +/************** Continuing where we left off in pragma.c *********************/ + +/* +** When the 0x10 bit of PRAGMA optimize is set, any ANALYZE commands +** will be run with an analysis_limit set to the lessor of the value of +** the following macro or to the actual analysis_limit if it is non-zero, +** in order to prevent PRAGMA optimize from running for too long. +** +** The value of 2000 is chosen empirically so that the worst-case run-time +** for PRAGMA optimize does not exceed 100 milliseconds against a variety +** of test databases on a RaspberryPI-4 compiled using -Os and without +** -DSQLITE_DEBUG. Of course, your mileage may vary. For the purpose of +** this paragraph, "worst-case" means that ANALYZE ends up being +** run on every table in the database. The worst case typically only +** happens if PRAGMA optimize is run on a database file for which ANALYZE +** has not been previously run and the 0x10000 flag is included so that +** all tables are analyzed. The usual case for PRAGMA optimize is that +** no ANALYZE commands will be run at all, or if any ANALYZE happens it +** will be against a single table, so that expected timing for PRAGMA +** optimize on a PI-4 is more like 1 millisecond or less with the 0x10000 +** flag or less than 100 microseconds without the 0x10000 flag. +** +** An analysis limit of 2000 is almost always sufficient for the query +** planner to fully characterize an index. The additional accuracy from +** a larger analysis is not usually helpful. +*/ +#ifndef SQLITE_DEFAULT_OPTIMIZE_LIMIT +# define SQLITE_DEFAULT_OPTIMIZE_LIMIT 2000 +#endif + +/* +** Interpret the given string as a safety level. Return 0 for OFF, +** 1 for ON or NORMAL, 2 for FULL, and 3 for EXTRA. Return 1 for an empty or +** unrecognized string argument. The FULL and EXTRA option is disallowed +** if the omitFull parameter it 1. +** +** Note that the values returned are one less that the values that +** should be passed into sqlite3BtreeSetSafetyLevel(). The is done +** to support legacy SQL code. The safety level used to be boolean +** and older scripts may have used numbers 0 for OFF and 1 for ON. +*/ +static u8 getSafetyLevel(const char *z, int omitFull, u8 dflt){ + /* 123456789 123456789 123 */ + static const char zText[] = "onoffalseyestruextrafull"; + static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 15, 20}; + static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 5, 4}; + static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 3, 2}; + /* on no off false yes true extra full */ + int i, n; + if( sqlite3Isdigit(*z) ){ + return (u8)sqlite3Atoi(z); + } + n = sqlite3Strlen30(z); + for(i=0; i=0&&i<=2)?i:0); +} +#endif /* ifndef SQLITE_OMIT_AUTOVACUUM */ + +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +/* +** Interpret the given string as a temp db location. Return 1 for file +** backed temporary databases, 2 for the Red-Black tree in memory database +** and 0 to use the compile-time default. +*/ +static int getTempStore(const char *z){ + if( z[0]>='0' && z[0]<='2' ){ + return z[0] - '0'; + }else if( sqlite3StrICmp(z, "file")==0 ){ + return 1; + }else if( sqlite3StrICmp(z, "memory")==0 ){ + return 2; + }else{ + return 0; + } +} +#endif /* SQLITE_PAGER_PRAGMAS */ + +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +/* +** Invalidate temp storage, either when the temp storage is changed +** from default, or when 'file' and the temp_store_directory has changed +*/ +static int invalidateTempStorage(Parse *pParse){ + sqlite3 *db = pParse->db; + if( db->aDb[1].pBt!=0 ){ + if( !db->autoCommit + || sqlite3BtreeTxnState(db->aDb[1].pBt)!=SQLITE_TXN_NONE + ){ + sqlite3ErrorMsg(pParse, "temporary storage cannot be changed " + "from within a transaction"); + return SQLITE_ERROR; + } + sqlite3BtreeClose(db->aDb[1].pBt); + db->aDb[1].pBt = 0; + sqlite3ResetAllSchemasOfConnection(db); + } + return SQLITE_OK; +} +#endif /* SQLITE_PAGER_PRAGMAS */ + +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +/* +** If the TEMP database is open, close it and mark the database schema +** as needing reloading. This must be done when using the SQLITE_TEMP_STORE +** or DEFAULT_TEMP_STORE pragmas. +*/ +static int changeTempStorage(Parse *pParse, const char *zStorageType){ + int ts = getTempStore(zStorageType); + sqlite3 *db = pParse->db; + if( db->temp_store==ts ) return SQLITE_OK; + if( invalidateTempStorage( pParse ) != SQLITE_OK ){ + return SQLITE_ERROR; + } + db->temp_store = (u8)ts; + return SQLITE_OK; +} +#endif /* SQLITE_PAGER_PRAGMAS */ + +/* +** Set result column names for a pragma. +*/ +static void setPragmaResultColumnNames( + Vdbe *v, /* The query under construction */ + const PragmaName *pPragma /* The pragma */ +){ + u8 n = pPragma->nPragCName; + sqlite3VdbeSetNumCols(v, n==0 ? 1 : n); + if( n==0 ){ + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, pPragma->zName, SQLITE_STATIC); + }else{ + int i, j; + for(i=0, j=pPragma->iPragCName; iautoCommit ){ + Db *pDb = db->aDb; + int n = db->nDb; + assert( SQLITE_FullFSync==PAGER_FULLFSYNC ); + assert( SQLITE_CkptFullFSync==PAGER_CKPT_FULLFSYNC ); + assert( SQLITE_CacheSpill==PAGER_CACHESPILL ); + assert( (PAGER_FULLFSYNC | PAGER_CKPT_FULLFSYNC | PAGER_CACHESPILL) + == PAGER_FLAGS_MASK ); + assert( (pDb->safety_level & PAGER_SYNCHRONOUS_MASK)==pDb->safety_level ); + while( (n--) > 0 ){ + if( pDb->pBt ){ + sqlite3BtreeSetPagerFlags(pDb->pBt, + pDb->safety_level | (db->flags & PAGER_FLAGS_MASK) ); + } + pDb++; + } + } +} +#else +# define setAllPagerFlags(X) /* no-op */ +#endif + + +/* +** Return a human-readable name for a constraint resolution action. +*/ +#ifndef SQLITE_OMIT_FOREIGN_KEY +static const char *actionName(u8 action){ + const char *zName; + switch( action ){ + case OE_SetNull: zName = "SET NULL"; break; + case OE_SetDflt: zName = "SET DEFAULT"; break; + case OE_Cascade: zName = "CASCADE"; break; + case OE_Restrict: zName = "RESTRICT"; break; + default: zName = "NO ACTION"; + assert( action==OE_None ); break; + } + return zName; +} +#endif + + +/* +** Parameter eMode must be one of the PAGER_JOURNALMODE_XXX constants +** defined in pager.h. This function returns the associated lowercase +** journal-mode name. +*/ +SQLITE_PRIVATE const char *sqlite3JournalModename(int eMode){ + static char * const azModeName[] = { + "delete", "persist", "off", "truncate", "memory" +#ifndef SQLITE_OMIT_WAL + , "wal" +#endif + }; + assert( PAGER_JOURNALMODE_DELETE==0 ); + assert( PAGER_JOURNALMODE_PERSIST==1 ); + assert( PAGER_JOURNALMODE_OFF==2 ); + assert( PAGER_JOURNALMODE_TRUNCATE==3 ); + assert( PAGER_JOURNALMODE_MEMORY==4 ); + assert( PAGER_JOURNALMODE_WAL==5 ); + assert( eMode>=0 && eMode<=ArraySize(azModeName) ); + + if( eMode==ArraySize(azModeName) ) return 0; + return azModeName[eMode]; +} + +/* +** Locate a pragma in the aPragmaName[] array. +*/ +static const PragmaName *pragmaLocate(const char *zName){ + int upr, lwr, mid = 0, rc; + lwr = 0; + upr = ArraySize(aPragmaName)-1; + while( lwr<=upr ){ + mid = (lwr+upr)/2; + rc = sqlite3_stricmp(zName, aPragmaName[mid].zName); + if( rc==0 ) break; + if( rc<0 ){ + upr = mid - 1; + }else{ + lwr = mid + 1; + } + } + return lwr>upr ? 0 : &aPragmaName[mid]; +} + +/* +** Create zero or more entries in the output for the SQL functions +** defined by FuncDef p. +*/ +static void pragmaFunclistLine( + Vdbe *v, /* The prepared statement being created */ + FuncDef *p, /* A particular function definition */ + int isBuiltin, /* True if this is a built-in function */ + int showInternFuncs /* True if showing internal functions */ +){ + u32 mask = + SQLITE_DETERMINISTIC | + SQLITE_DIRECTONLY | + SQLITE_SUBTYPE | + SQLITE_INNOCUOUS | + SQLITE_FUNC_INTERNAL + ; + if( showInternFuncs ) mask = 0xffffffff; + for(; p; p=p->pNext){ + const char *zType; + static const char *azEnc[] = { 0, "utf8", "utf16le", "utf16be" }; + + assert( SQLITE_FUNC_ENCMASK==0x3 ); + assert( strcmp(azEnc[SQLITE_UTF8],"utf8")==0 ); + assert( strcmp(azEnc[SQLITE_UTF16LE],"utf16le")==0 ); + assert( strcmp(azEnc[SQLITE_UTF16BE],"utf16be")==0 ); + + if( p->xSFunc==0 ) continue; + if( (p->funcFlags & SQLITE_FUNC_INTERNAL)!=0 + && showInternFuncs==0 + ){ + continue; + } + if( p->xValue!=0 ){ + zType = "w"; + }else if( p->xFinalize!=0 ){ + zType = "a"; + }else{ + zType = "s"; + } + sqlite3VdbeMultiLoad(v, 1, "sissii", + p->zName, isBuiltin, + zType, azEnc[p->funcFlags&SQLITE_FUNC_ENCMASK], + p->nArg, + (p->funcFlags & mask) ^ SQLITE_INNOCUOUS + ); + } +} + + +/* +** Helper subroutine for PRAGMA integrity_check: +** +** Generate code to output a single-column result row with a value of the +** string held in register 3. Decrement the result count in register 1 +** and halt if the maximum number of result rows have been issued. +*/ +static int integrityCheckResultRow(Vdbe *v){ + int addr; + sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); + addr = sqlite3VdbeAddOp3(v, OP_IfPos, 1, sqlite3VdbeCurrentAddr(v)+2, 1); + VdbeCoverage(v); + sqlite3VdbeAddOp0(v, OP_Halt); + return addr; +} + +/* +** Should table pTab be skipped when doing an integrity_check? +** Return true or false. +** +** If pObjTab is not null, the return true if pTab matches pObjTab. +** +** If pObjTab is null, then return true only if pTab is an imposter table. +*/ +static int tableSkipIntegrityCheck(const Table *pTab, const Table *pObjTab){ + if( pObjTab ){ + return pTab!=pObjTab; + }else{ + return (pTab->tabFlags & TF_Imposter)!=0; + } +} + +/* +** Process a pragma statement. +** +** Pragmas are of this form: +** +** PRAGMA [schema.]id [= value] +** +** The identifier might also be a string. The value is a string, and +** identifier, or a number. If minusFlag is true, then the value is +** a number that was preceded by a minus sign. +** +** If the left side is "database.id" then pId1 is the database name +** and pId2 is the id. If the left side is just "id" then pId1 is the +** id and pId2 is any empty string. +*/ +SQLITE_PRIVATE void sqlite3Pragma( + Parse *pParse, + Token *pId1, /* First part of [schema.]id field */ + Token *pId2, /* Second part of [schema.]id field, or NULL */ + Token *pValue, /* Token for , or NULL */ + int minusFlag /* True if a '-' sign preceded */ +){ + char *zLeft = 0; /* Nul-terminated UTF-8 string */ + char *zRight = 0; /* Nul-terminated UTF-8 string , or NULL */ + const char *zDb = 0; /* The database name */ + Token *pId; /* Pointer to token */ + char *aFcntl[4]; /* Argument to SQLITE_FCNTL_PRAGMA */ + int iDb; /* Database index for */ + int rc; /* return value form SQLITE_FCNTL_PRAGMA */ + sqlite3 *db = pParse->db; /* The database connection */ + Db *pDb; /* The specific database being pragmaed */ + Vdbe *v = sqlite3GetVdbe(pParse); /* Prepared statement */ + const PragmaName *pPragma; /* The pragma */ + + if( v==0 ) return; + sqlite3VdbeRunOnlyOnce(v); + pParse->nMem = 2; + + /* Interpret the [schema.] part of the pragma statement. iDb is the + ** index of the database this pragma is being applied to in db.aDb[]. */ + iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId); + if( iDb<0 ) return; + pDb = &db->aDb[iDb]; + + /* If the temp database has been explicitly named as part of the + ** pragma, make sure it is open. + */ + if( iDb==1 && sqlite3OpenTempDatabase(pParse) ){ + return; + } + + zLeft = sqlite3NameFromToken(db, pId); + if( !zLeft ) return; + if( minusFlag ){ + zRight = sqlite3MPrintf(db, "-%T", pValue); + }else{ + zRight = sqlite3NameFromToken(db, pValue); + } + + assert( pId2 ); + zDb = pId2->n>0 ? pDb->zDbSName : 0; + if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){ + goto pragma_out; + } + + /* Send an SQLITE_FCNTL_PRAGMA file-control to the underlying VFS + ** connection. If it returns SQLITE_OK, then assume that the VFS + ** handled the pragma and generate a no-op prepared statement. + ** + ** IMPLEMENTATION-OF: R-12238-55120 Whenever a PRAGMA statement is parsed, + ** an SQLITE_FCNTL_PRAGMA file control is sent to the open sqlite3_file + ** object corresponding to the database file to which the pragma + ** statement refers. + ** + ** IMPLEMENTATION-OF: R-29875-31678 The argument to the SQLITE_FCNTL_PRAGMA + ** file control is an array of pointers to strings (char**) in which the + ** second element of the array is the name of the pragma and the third + ** element is the argument to the pragma or NULL if the pragma has no + ** argument. + */ + aFcntl[0] = 0; + aFcntl[1] = zLeft; + aFcntl[2] = zRight; + aFcntl[3] = 0; + db->busyHandler.nBusy = 0; + rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl); + if( rc==SQLITE_OK ){ + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, aFcntl[0], SQLITE_TRANSIENT); + returnSingleText(v, aFcntl[0]); + sqlite3_free(aFcntl[0]); + goto pragma_out; + } + if( rc!=SQLITE_NOTFOUND ){ + if( aFcntl[0] ){ + sqlite3ErrorMsg(pParse, "%s", aFcntl[0]); + sqlite3_free(aFcntl[0]); + } + pParse->nErr++; + pParse->rc = rc; + goto pragma_out; + } + + /* Locate the pragma in the lookup table */ + pPragma = pragmaLocate(zLeft); + if( pPragma==0 ){ + /* IMP: R-43042-22504 No error messages are generated if an + ** unknown pragma is issued. */ + goto pragma_out; + } + + /* Make sure the database schema is loaded if the pragma requires that */ + if( (pPragma->mPragFlg & PragFlg_NeedSchema)!=0 ){ + if( sqlite3ReadSchema(pParse) ) goto pragma_out; + } + + /* Register the result column names for pragmas that return results */ + if( (pPragma->mPragFlg & PragFlg_NoColumns)==0 + && ((pPragma->mPragFlg & PragFlg_NoColumns1)==0 || zRight==0) + ){ + setPragmaResultColumnNames(v, pPragma); + } + + /* Jump to the appropriate pragma handler */ + switch( pPragma->ePragTyp ){ + +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) + /* + ** PRAGMA [schema.]default_cache_size + ** PRAGMA [schema.]default_cache_size=N + ** + ** The first form reports the current persistent setting for the + ** page cache size. The value returned is the maximum number of + ** pages in the page cache. The second form sets both the current + ** page cache size value and the persistent page cache size value + ** stored in the database file. + ** + ** Older versions of SQLite would set the default cache size to a + ** negative number to indicate synchronous=OFF. These days, synchronous + ** is always on by default regardless of the sign of the default cache + ** size. But continue to take the absolute value of the default cache + ** size of historical compatibility. + */ + case PragTyp_DEFAULT_CACHE_SIZE: { + static const int iLn = VDBE_OFFSET_LINENO(2); + static const VdbeOpList getCacheSize[] = { + { OP_Transaction, 0, 0, 0}, /* 0 */ + { OP_ReadCookie, 0, 1, BTREE_DEFAULT_CACHE_SIZE}, /* 1 */ + { OP_IfPos, 1, 8, 0}, + { OP_Integer, 0, 2, 0}, + { OP_Subtract, 1, 2, 1}, + { OP_IfPos, 1, 8, 0}, + { OP_Integer, 0, 1, 0}, /* 6 */ + { OP_Noop, 0, 0, 0}, + { OP_ResultRow, 1, 1, 0}, + }; + VdbeOp *aOp; + sqlite3VdbeUsesBtree(v, iDb); + if( !zRight ){ + pParse->nMem += 2; + sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(getCacheSize)); + aOp = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize, iLn); + if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; + aOp[0].p1 = iDb; + aOp[1].p1 = iDb; + aOp[6].p1 = SQLITE_DEFAULT_CACHE_SIZE; + }else{ + int size = sqlite3AbsInt32(sqlite3Atoi(zRight)); + sqlite3BeginWriteOperation(pParse, 0, iDb); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, size); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + pDb->pSchema->cache_size = size; + sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); + } + break; + } +#endif /* !SQLITE_OMIT_PAGER_PRAGMAS && !SQLITE_OMIT_DEPRECATED */ + +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) + /* + ** PRAGMA [schema.]page_size + ** PRAGMA [schema.]page_size=N + ** + ** The first form reports the current setting for the + ** database page size in bytes. The second form sets the + ** database page size value. The value can only be set if + ** the database has not yet been created. + */ + case PragTyp_PAGE_SIZE: { + Btree *pBt = pDb->pBt; + assert( pBt!=0 ); + if( !zRight ){ + int size = ALWAYS(pBt) ? sqlite3BtreeGetPageSize(pBt) : 0; + returnSingleInt(v, size); + }else{ + /* Malloc may fail when setting the page-size, as there is an internal + ** buffer that the pager module resizes using sqlite3_realloc(). + */ + db->nextPagesize = sqlite3Atoi(zRight); + if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,0,0) ){ + sqlite3OomFault(db); + } + } + break; + } + + /* + ** PRAGMA [schema.]secure_delete + ** PRAGMA [schema.]secure_delete=ON/OFF/FAST + ** + ** The first form reports the current setting for the + ** secure_delete flag. The second form changes the secure_delete + ** flag setting and reports the new value. + */ + case PragTyp_SECURE_DELETE: { + Btree *pBt = pDb->pBt; + int b = -1; + assert( pBt!=0 ); + if( zRight ){ + if( sqlite3_stricmp(zRight, "fast")==0 ){ + b = 2; + }else{ + b = sqlite3GetBoolean(zRight, 0); + } + } + if( pId2->n==0 && b>=0 ){ + int ii; + for(ii=0; iinDb; ii++){ + sqlite3BtreeSecureDelete(db->aDb[ii].pBt, b); + } + } + b = sqlite3BtreeSecureDelete(pBt, b); + returnSingleInt(v, b); + break; + } + + /* + ** PRAGMA [schema.]max_page_count + ** PRAGMA [schema.]max_page_count=N + ** + ** The first form reports the current setting for the + ** maximum number of pages in the database file. The + ** second form attempts to change this setting. Both + ** forms return the current setting. + ** + ** The absolute value of N is used. This is undocumented and might + ** change. The only purpose is to provide an easy way to test + ** the sqlite3AbsInt32() function. + ** + ** PRAGMA [schema.]page_count + ** + ** Return the number of pages in the specified database. + */ + case PragTyp_PAGE_COUNT: { + int iReg; + i64 x = 0; + sqlite3CodeVerifySchema(pParse, iDb); + iReg = ++pParse->nMem; + if( sqlite3Tolower(zLeft[0])=='p' ){ + sqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg); + }else{ + if( zRight && sqlite3DecOrHexToI64(zRight,&x)==0 ){ + if( x<0 ) x = 0; + else if( x>0xfffffffe ) x = 0xfffffffe; + }else{ + x = 0; + } + sqlite3VdbeAddOp3(v, OP_MaxPgcnt, iDb, iReg, (int)x); + } + sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1); + break; + } + + /* + ** PRAGMA [schema.]locking_mode + ** PRAGMA [schema.]locking_mode = (normal|exclusive) + */ + case PragTyp_LOCKING_MODE: { + const char *zRet = "normal"; + int eMode = getLockingMode(zRight); + + if( pId2->n==0 && eMode==PAGER_LOCKINGMODE_QUERY ){ + /* Simple "PRAGMA locking_mode;" statement. This is a query for + ** the current default locking mode (which may be different to + ** the locking-mode of the main database). + */ + eMode = db->dfltLockMode; + }else{ + Pager *pPager; + if( pId2->n==0 ){ + /* This indicates that no database name was specified as part + ** of the PRAGMA command. In this case the locking-mode must be + ** set on all attached databases, as well as the main db file. + ** + ** Also, the sqlite3.dfltLockMode variable is set so that + ** any subsequently attached databases also use the specified + ** locking mode. + */ + int ii; + assert(pDb==&db->aDb[0]); + for(ii=2; iinDb; ii++){ + pPager = sqlite3BtreePager(db->aDb[ii].pBt); + sqlite3PagerLockingMode(pPager, eMode); + } + db->dfltLockMode = (u8)eMode; + } + pPager = sqlite3BtreePager(pDb->pBt); + eMode = sqlite3PagerLockingMode(pPager, eMode); + } + + assert( eMode==PAGER_LOCKINGMODE_NORMAL + || eMode==PAGER_LOCKINGMODE_EXCLUSIVE ); + if( eMode==PAGER_LOCKINGMODE_EXCLUSIVE ){ + zRet = "exclusive"; + } + returnSingleText(v, zRet); + break; + } + + /* + ** PRAGMA [schema.]journal_mode + ** PRAGMA [schema.]journal_mode = + ** (delete|persist|off|truncate|memory|wal|off) + */ + case PragTyp_JOURNAL_MODE: { + int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */ + int ii; /* Loop counter */ + + if( zRight==0 ){ + /* If there is no "=MODE" part of the pragma, do a query for the + ** current mode */ + eMode = PAGER_JOURNALMODE_QUERY; + }else{ + const char *zMode; + int n = sqlite3Strlen30(zRight); + for(eMode=0; (zMode = sqlite3JournalModename(eMode))!=0; eMode++){ + if( sqlite3StrNICmp(zRight, zMode, n)==0 ) break; + } + if( !zMode ){ + /* If the "=MODE" part does not match any known journal mode, + ** then do a query */ + eMode = PAGER_JOURNALMODE_QUERY; + } + if( eMode==PAGER_JOURNALMODE_OFF && (db->flags & SQLITE_Defensive)!=0 ){ + /* Do not allow journal-mode "OFF" in defensive since the database + ** can become corrupted using ordinary SQL when the journal is off */ + eMode = PAGER_JOURNALMODE_QUERY; + } + } + if( eMode==PAGER_JOURNALMODE_QUERY && pId2->n==0 ){ + /* Convert "PRAGMA journal_mode" into "PRAGMA main.journal_mode" */ + iDb = 0; + pId2->n = 1; + } + for(ii=db->nDb-1; ii>=0; ii--){ + if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ + sqlite3VdbeUsesBtree(v, ii); + sqlite3VdbeAddOp3(v, OP_JournalMode, ii, 1, eMode); + } + } + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + break; + } + + /* + ** PRAGMA [schema.]journal_size_limit + ** PRAGMA [schema.]journal_size_limit=N + ** + ** Get or set the size limit on rollback journal files. + */ + case PragTyp_JOURNAL_SIZE_LIMIT: { + Pager *pPager = sqlite3BtreePager(pDb->pBt); + i64 iLimit = -2; + if( zRight ){ + sqlite3DecOrHexToI64(zRight, &iLimit); + if( iLimit<-1 ) iLimit = -1; + } + iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit); + returnSingleInt(v, iLimit); + break; + } + +#endif /* SQLITE_OMIT_PAGER_PRAGMAS */ + + /* + ** PRAGMA [schema.]auto_vacuum + ** PRAGMA [schema.]auto_vacuum=N + ** + ** Get or set the value of the database 'auto-vacuum' parameter. + ** The value is one of: 0 NONE 1 FULL 2 INCREMENTAL + */ +#ifndef SQLITE_OMIT_AUTOVACUUM + case PragTyp_AUTO_VACUUM: { + Btree *pBt = pDb->pBt; + assert( pBt!=0 ); + if( !zRight ){ + returnSingleInt(v, sqlite3BtreeGetAutoVacuum(pBt)); + }else{ + int eAuto = getAutoVacuum(zRight); + assert( eAuto>=0 && eAuto<=2 ); + db->nextAutovac = (u8)eAuto; + /* Call SetAutoVacuum() to set initialize the internal auto and + ** incr-vacuum flags. This is required in case this connection + ** creates the database file. It is important that it is created + ** as an auto-vacuum capable db. + */ + rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto); + if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){ + /* When setting the auto_vacuum mode to either "full" or + ** "incremental", write the value of meta[6] in the database + ** file. Before writing to meta[6], check that meta[3] indicates + ** that this really is an auto-vacuum capable database. + */ + static const int iLn = VDBE_OFFSET_LINENO(2); + static const VdbeOpList setMeta6[] = { + { OP_Transaction, 0, 1, 0}, /* 0 */ + { OP_ReadCookie, 0, 1, BTREE_LARGEST_ROOT_PAGE}, + { OP_If, 1, 0, 0}, /* 2 */ + { OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */ + { OP_SetCookie, 0, BTREE_INCR_VACUUM, 0}, /* 4 */ + }; + VdbeOp *aOp; + int iAddr = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setMeta6)); + aOp = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6, iLn); + if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; + aOp[0].p1 = iDb; + aOp[1].p1 = iDb; + aOp[2].p2 = iAddr+4; + aOp[4].p1 = iDb; + aOp[4].p3 = eAuto - 1; + sqlite3VdbeUsesBtree(v, iDb); + } + } + break; + } +#endif + + /* + ** PRAGMA [schema.]incremental_vacuum(N) + ** + ** Do N steps of incremental vacuuming on a database. + */ +#ifndef SQLITE_OMIT_AUTOVACUUM + case PragTyp_INCREMENTAL_VACUUM: { + int iLimit = 0, addr; + if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){ + iLimit = 0x7fffffff; + } + sqlite3BeginWriteOperation(pParse, 0, iDb); + sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1); + addr = sqlite3VdbeAddOp1(v, OP_IncrVacuum, iDb); VdbeCoverage(v); + sqlite3VdbeAddOp1(v, OP_ResultRow, 1); + sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); + sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr); + break; + } +#endif + +#ifndef SQLITE_OMIT_PAGER_PRAGMAS + /* + ** PRAGMA [schema.]cache_size + ** PRAGMA [schema.]cache_size=N + ** + ** The first form reports the current local setting for the + ** page cache size. The second form sets the local + ** page cache size value. If N is positive then that is the + ** number of pages in the cache. If N is negative, then the + ** number of pages is adjusted so that the cache uses -N kibibytes + ** of memory. + */ + case PragTyp_CACHE_SIZE: { + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + if( !zRight ){ + returnSingleInt(v, pDb->pSchema->cache_size); + }else{ + int size = sqlite3Atoi(zRight); + pDb->pSchema->cache_size = size; + sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); + } + break; + } + + /* + ** PRAGMA [schema.]cache_spill + ** PRAGMA cache_spill=BOOLEAN + ** PRAGMA [schema.]cache_spill=N + ** + ** The first form reports the current local setting for the + ** page cache spill size. The second form turns cache spill on + ** or off. When turning cache spill on, the size is set to the + ** current cache_size. The third form sets a spill size that + ** may be different form the cache size. + ** If N is positive then that is the + ** number of pages in the cache. If N is negative, then the + ** number of pages is adjusted so that the cache uses -N kibibytes + ** of memory. + ** + ** If the number of cache_spill pages is less then the number of + ** cache_size pages, no spilling occurs until the page count exceeds + ** the number of cache_size pages. + ** + ** The cache_spill=BOOLEAN setting applies to all attached schemas, + ** not just the schema specified. + */ + case PragTyp_CACHE_SPILL: { + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + if( !zRight ){ + returnSingleInt(v, + (db->flags & SQLITE_CacheSpill)==0 ? 0 : + sqlite3BtreeSetSpillSize(pDb->pBt,0)); + }else{ + int size = 1; + if( sqlite3GetInt32(zRight, &size) ){ + sqlite3BtreeSetSpillSize(pDb->pBt, size); + } + if( sqlite3GetBoolean(zRight, size!=0) ){ + db->flags |= SQLITE_CacheSpill; + }else{ + db->flags &= ~(u64)SQLITE_CacheSpill; + } + setAllPagerFlags(db); + } + break; + } + + /* + ** PRAGMA [schema.]mmap_size(N) + ** + ** Used to set mapping size limit. The mapping size limit is + ** used to limit the aggregate size of all memory mapped regions of the + ** database file. If this parameter is set to zero, then memory mapping + ** is not used at all. If N is negative, then the default memory map + ** limit determined by sqlite3_config(SQLITE_CONFIG_MMAP_SIZE) is set. + ** The parameter N is measured in bytes. + ** + ** This value is advisory. The underlying VFS is free to memory map + ** as little or as much as it wants. Except, if N is set to 0 then the + ** upper layers will never invoke the xFetch interfaces to the VFS. + */ + case PragTyp_MMAP_SIZE: { + sqlite3_int64 sz; +#if SQLITE_MAX_MMAP_SIZE>0 + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + if( zRight ){ + int ii; + sqlite3DecOrHexToI64(zRight, &sz); + if( sz<0 ) sz = sqlite3GlobalConfig.szMmap; + if( pId2->n==0 ) db->szMmap = sz; + for(ii=db->nDb-1; ii>=0; ii--){ + if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ + sqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, sz); + } + } + } + sz = -1; + rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_MMAP_SIZE, &sz); +#else + sz = 0; + rc = SQLITE_OK; +#endif + if( rc==SQLITE_OK ){ + returnSingleInt(v, sz); + }else if( rc!=SQLITE_NOTFOUND ){ + pParse->nErr++; + pParse->rc = rc; + } + break; + } + + /* + ** PRAGMA temp_store + ** PRAGMA temp_store = "default"|"memory"|"file" + ** + ** Return or set the local value of the temp_store flag. Changing + ** the local value does not make changes to the disk file and the default + ** value will be restored the next time the database is opened. + ** + ** Note that it is possible for the library compile-time options to + ** override this setting + */ + case PragTyp_TEMP_STORE: { + if( !zRight ){ + returnSingleInt(v, db->temp_store); + }else{ + changeTempStorage(pParse, zRight); + } + break; + } + + /* + ** PRAGMA temp_store_directory + ** PRAGMA temp_store_directory = ""|"directory_name" + ** + ** Return or set the local value of the temp_store_directory flag. Changing + ** the value sets a specific directory to be used for temporary files. + ** Setting to a null string reverts to the default temporary directory search. + ** If temporary directory is changed, then invalidateTempStorage. + ** + */ + case PragTyp_TEMP_STORE_DIRECTORY: { + sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); + if( !zRight ){ + returnSingleText(v, sqlite3_temp_directory); + }else{ +#ifndef SQLITE_OMIT_WSD + if( zRight[0] ){ + int res; + rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res); + if( rc!=SQLITE_OK || res==0 ){ + sqlite3ErrorMsg(pParse, "not a writable directory"); + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); + goto pragma_out; + } + } + if( SQLITE_TEMP_STORE==0 + || (SQLITE_TEMP_STORE==1 && db->temp_store<=1) + || (SQLITE_TEMP_STORE==2 && db->temp_store==1) + ){ + invalidateTempStorage(pParse); + } + sqlite3_free(sqlite3_temp_directory); + if( zRight[0] ){ + sqlite3_temp_directory = sqlite3_mprintf("%s", zRight); + }else{ + sqlite3_temp_directory = 0; + } +#endif /* SQLITE_OMIT_WSD */ + } + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); + break; + } + +#if SQLITE_OS_WIN + /* + ** PRAGMA data_store_directory + ** PRAGMA data_store_directory = ""|"directory_name" + ** + ** Return or set the local value of the data_store_directory flag. Changing + ** the value sets a specific directory to be used for database files that + ** were specified with a relative pathname. Setting to a null string reverts + ** to the default database directory, which for database files specified with + ** a relative path will probably be based on the current directory for the + ** process. Database file specified with an absolute path are not impacted + ** by this setting, regardless of its value. + ** + */ + case PragTyp_DATA_STORE_DIRECTORY: { + sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); + if( !zRight ){ + returnSingleText(v, sqlite3_data_directory); + }else{ +#ifndef SQLITE_OMIT_WSD + if( zRight[0] ){ + int res; + rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res); + if( rc!=SQLITE_OK || res==0 ){ + sqlite3ErrorMsg(pParse, "not a writable directory"); + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); + goto pragma_out; + } + } + sqlite3_free(sqlite3_data_directory); + if( zRight[0] ){ + sqlite3_data_directory = sqlite3_mprintf("%s", zRight); + }else{ + sqlite3_data_directory = 0; + } +#endif /* SQLITE_OMIT_WSD */ + } + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); + break; + } +#endif + +#if SQLITE_ENABLE_LOCKING_STYLE + /* + ** PRAGMA [schema.]lock_proxy_file + ** PRAGMA [schema.]lock_proxy_file = ":auto:"|"lock_file_path" + ** + ** Return or set the value of the lock_proxy_file flag. Changing + ** the value sets a specific file to be used for database access locks. + ** + */ + case PragTyp_LOCK_PROXY_FILE: { + if( !zRight ){ + Pager *pPager = sqlite3BtreePager(pDb->pBt); + char *proxy_file_path = NULL; + sqlite3_file *pFile = sqlite3PagerFile(pPager); + sqlite3OsFileControlHint(pFile, SQLITE_GET_LOCKPROXYFILE, + &proxy_file_path); + returnSingleText(v, proxy_file_path); + }else{ + Pager *pPager = sqlite3BtreePager(pDb->pBt); + sqlite3_file *pFile = sqlite3PagerFile(pPager); + int res; + if( zRight[0] ){ + res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE, + zRight); + } else { + res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE, + NULL); + } + if( res!=SQLITE_OK ){ + sqlite3ErrorMsg(pParse, "failed to set lock proxy file"); + goto pragma_out; + } + } + break; + } +#endif /* SQLITE_ENABLE_LOCKING_STYLE */ + + /* + ** PRAGMA [schema.]synchronous + ** PRAGMA [schema.]synchronous=OFF|ON|NORMAL|FULL|EXTRA + ** + ** Return or set the local value of the synchronous flag. Changing + ** the local value does not make changes to the disk file and the + ** default value will be restored the next time the database is + ** opened. + */ + case PragTyp_SYNCHRONOUS: { + if( !zRight ){ + returnSingleInt(v, pDb->safety_level-1); + }else{ + if( !db->autoCommit ){ + sqlite3ErrorMsg(pParse, + "Safety level may not be changed inside a transaction"); + }else if( iDb!=1 ){ + int iLevel = (getSafetyLevel(zRight,0,1)+1) & PAGER_SYNCHRONOUS_MASK; + if( iLevel==0 ) iLevel = 1; + pDb->safety_level = iLevel; + pDb->bSyncSet = 1; + setAllPagerFlags(db); + } + } + break; + } +#endif /* SQLITE_OMIT_PAGER_PRAGMAS */ + +#ifndef SQLITE_OMIT_FLAG_PRAGMAS + case PragTyp_FLAG: { + if( zRight==0 ){ + setPragmaResultColumnNames(v, pPragma); + returnSingleInt(v, (db->flags & pPragma->iArg)!=0 ); + }else{ + u64 mask = pPragma->iArg; /* Mask of bits to set or clear. */ + if( db->autoCommit==0 ){ + /* Foreign key support may not be enabled or disabled while not + ** in auto-commit mode. */ + mask &= ~(SQLITE_ForeignKeys); + } + + if( sqlite3GetBoolean(zRight, 0) ){ + if( (mask & SQLITE_WriteSchema)==0 + || (db->flags & SQLITE_Defensive)==0 + ){ + db->flags |= mask; + } + }else{ + db->flags &= ~mask; + if( mask==SQLITE_DeferFKs ){ + db->nDeferredImmCons = 0; + db->nDeferredCons = 0; + } + if( (mask & SQLITE_WriteSchema)!=0 + && sqlite3_stricmp(zRight, "reset")==0 + ){ + /* IMP: R-60817-01178 If the argument is "RESET" then schema + ** writing is disabled (as with "PRAGMA writable_schema=OFF") and, + ** in addition, the schema is reloaded. */ + sqlite3ResetAllSchemasOfConnection(db); + } + } + + /* Many of the flag-pragmas modify the code generated by the SQL + ** compiler (eg. count_changes). So add an opcode to expire all + ** compiled SQL statements after modifying a pragma value. + */ + sqlite3VdbeAddOp0(v, OP_Expire); + setAllPagerFlags(db); + } + break; + } +#endif /* SQLITE_OMIT_FLAG_PRAGMAS */ + +#ifndef SQLITE_OMIT_SCHEMA_PRAGMAS + /* + ** PRAGMA table_info(
    ) + ** + ** Return a single row for each column of the named table. The columns of + ** the returned data set are: + ** + ** cid: Column id (numbered from left to right, starting at 0) + ** name: Column name + ** type: Column declaration type. + ** notnull: True if 'NOT NULL' is part of column declaration + ** dflt_value: The default value for the column, if any. + ** pk: Non-zero for PK fields. + */ + case PragTyp_TABLE_INFO: if( zRight ){ + Table *pTab; + sqlite3CodeVerifyNamedSchema(pParse, zDb); + pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb); + if( pTab ){ + int i, k; + int nHidden = 0; + Column *pCol; + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + pParse->nMem = 7; + sqlite3ViewGetColumnNames(pParse, pTab); + for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){ + int isHidden = 0; + const Expr *pColExpr; + if( pCol->colFlags & COLFLAG_NOINSERT ){ + if( pPragma->iArg==0 ){ + nHidden++; + continue; + } + if( pCol->colFlags & COLFLAG_VIRTUAL ){ + isHidden = 2; /* GENERATED ALWAYS AS ... VIRTUAL */ + }else if( pCol->colFlags & COLFLAG_STORED ){ + isHidden = 3; /* GENERATED ALWAYS AS ... STORED */ + }else{ assert( pCol->colFlags & COLFLAG_HIDDEN ); + isHidden = 1; /* HIDDEN */ + } + } + if( (pCol->colFlags & COLFLAG_PRIMKEY)==0 ){ + k = 0; + }else if( pPk==0 ){ + k = 1; + }else{ + for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){} + } + pColExpr = sqlite3ColumnExpr(pTab,pCol); + assert( pColExpr==0 || pColExpr->op==TK_SPAN || isHidden>=2 ); + assert( pColExpr==0 || !ExprHasProperty(pColExpr, EP_IntValue) + || isHidden>=2 ); + sqlite3VdbeMultiLoad(v, 1, pPragma->iArg ? "issisii" : "issisi", + i-nHidden, + pCol->zCnName, + sqlite3ColumnType(pCol,""), + pCol->notNull ? 1 : 0, + (isHidden>=2 || pColExpr==0) ? 0 : pColExpr->u.zToken, + k, + isHidden); + } + } + } + break; + + /* + ** PRAGMA table_list + ** + ** Return a single row for each table, virtual table, or view in the + ** entire schema. + ** + ** schema: Name of attached database hold this table + ** name: Name of the table itself + ** type: "table", "view", "virtual", "shadow" + ** ncol: Number of columns + ** wr: True for a WITHOUT ROWID table + ** strict: True for a STRICT table + */ + case PragTyp_TABLE_LIST: { + int ii; + pParse->nMem = 6; + sqlite3CodeVerifyNamedSchema(pParse, zDb); + for(ii=0; iinDb; ii++){ + HashElem *k; + Hash *pHash; + int initNCol; + if( zDb && sqlite3_stricmp(zDb, db->aDb[ii].zDbSName)!=0 ) continue; + + /* Ensure that the Table.nCol field is initialized for all views + ** and virtual tables. Each time we initialize a Table.nCol value + ** for a table, that can potentially disrupt the hash table, so restart + ** the initialization scan. + */ + pHash = &db->aDb[ii].pSchema->tblHash; + initNCol = sqliteHashCount(pHash); + while( initNCol-- ){ + for(k=sqliteHashFirst(pHash); 1; k=sqliteHashNext(k) ){ + Table *pTab; + if( k==0 ){ initNCol = 0; break; } + pTab = sqliteHashData(k); + if( pTab->nCol==0 ){ + char *zSql = sqlite3MPrintf(db, "SELECT*FROM\"%w\"", pTab->zName); + if( zSql ){ + sqlite3_stmt *pDummy = 0; + (void)sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_DONT_LOG, + &pDummy, 0); + (void)sqlite3_finalize(pDummy); + sqlite3DbFree(db, zSql); + } + if( db->mallocFailed ){ + sqlite3ErrorMsg(db->pParse, "out of memory"); + db->pParse->rc = SQLITE_NOMEM_BKPT; + } + pHash = &db->aDb[ii].pSchema->tblHash; + break; + } + } + } + + for(k=sqliteHashFirst(pHash); k; k=sqliteHashNext(k) ){ + Table *pTab = sqliteHashData(k); + const char *zType; + if( zRight && sqlite3_stricmp(zRight, pTab->zName)!=0 ) continue; + if( IsView(pTab) ){ + zType = "view"; + }else if( IsVirtual(pTab) ){ + zType = "virtual"; + }else if( pTab->tabFlags & TF_Shadow ){ + zType = "shadow"; + }else{ + zType = "table"; + } + sqlite3VdbeMultiLoad(v, 1, "sssiii", + db->aDb[ii].zDbSName, + sqlite3PreferredTableName(pTab->zName), + zType, + pTab->nCol, + (pTab->tabFlags & TF_WithoutRowid)!=0, + (pTab->tabFlags & TF_Strict)!=0 + ); + } + } + } + break; + +#ifdef SQLITE_DEBUG + case PragTyp_STATS: { + Index *pIdx; + HashElem *i; + pParse->nMem = 5; + sqlite3CodeVerifySchema(pParse, iDb); + for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){ + Table *pTab = sqliteHashData(i); + sqlite3VdbeMultiLoad(v, 1, "ssiii", + sqlite3PreferredTableName(pTab->zName), + 0, + pTab->szTabRow, + pTab->nRowLogEst, + pTab->tabFlags); + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + sqlite3VdbeMultiLoad(v, 2, "siiiX", + pIdx->zName, + pIdx->szIdxRow, + pIdx->aiRowLogEst[0], + pIdx->hasStat1); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5); + } + } + } + break; +#endif + + case PragTyp_INDEX_INFO: if( zRight ){ + Index *pIdx; + Table *pTab; + pIdx = sqlite3FindIndex(db, zRight, zDb); + if( pIdx==0 ){ + /* If there is no index named zRight, check to see if there is a + ** WITHOUT ROWID table named zRight, and if there is, show the + ** structure of the PRIMARY KEY index for that table. */ + pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb); + if( pTab && !HasRowid(pTab) ){ + pIdx = sqlite3PrimaryKeyIndex(pTab); + } + } + if( pIdx ){ + int iIdxDb = sqlite3SchemaToIndex(db, pIdx->pSchema); + int i; + int mx; + if( pPragma->iArg ){ + /* PRAGMA index_xinfo (newer version with more rows and columns) */ + mx = pIdx->nColumn; + pParse->nMem = 6; + }else{ + /* PRAGMA index_info (legacy version) */ + mx = pIdx->nKeyCol; + pParse->nMem = 3; + } + pTab = pIdx->pTable; + sqlite3CodeVerifySchema(pParse, iIdxDb); + assert( pParse->nMem<=pPragma->nPragCName ); + for(i=0; iaiColumn[i]; + sqlite3VdbeMultiLoad(v, 1, "iisX", i, cnum, + cnum<0 ? 0 : pTab->aCol[cnum].zCnName); + if( pPragma->iArg ){ + sqlite3VdbeMultiLoad(v, 4, "isiX", + pIdx->aSortOrder[i], + pIdx->azColl[i], + inKeyCol); + } + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, pParse->nMem); + } + } + } + break; + + case PragTyp_INDEX_LIST: if( zRight ){ + Index *pIdx; + Table *pTab; + int i; + pTab = sqlite3FindTable(db, zRight, zDb); + if( pTab ){ + int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); + pParse->nMem = 5; + sqlite3CodeVerifySchema(pParse, iTabDb); + for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){ + const char *azOrigin[] = { "c", "u", "pk" }; + sqlite3VdbeMultiLoad(v, 1, "isisi", + i, + pIdx->zName, + IsUniqueIndex(pIdx), + azOrigin[pIdx->idxType], + pIdx->pPartIdxWhere!=0); + } + } + } + break; + + case PragTyp_DATABASE_LIST: { + int i; + pParse->nMem = 3; + for(i=0; inDb; i++){ + if( db->aDb[i].pBt==0 ) continue; + assert( db->aDb[i].zDbSName!=0 ); + sqlite3VdbeMultiLoad(v, 1, "iss", + i, + db->aDb[i].zDbSName, + sqlite3BtreeGetFilename(db->aDb[i].pBt)); + } + } + break; + + case PragTyp_COLLATION_LIST: { + int i = 0; + HashElem *p; + pParse->nMem = 2; + for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){ + CollSeq *pColl = (CollSeq *)sqliteHashData(p); + sqlite3VdbeMultiLoad(v, 1, "is", i++, pColl->zName); + } + } + break; + +#ifndef SQLITE_OMIT_INTROSPECTION_PRAGMAS + case PragTyp_FUNCTION_LIST: { + int i; + HashElem *j; + FuncDef *p; + int showInternFunc = (db->mDbFlags & DBFLAG_InternalFunc)!=0; + pParse->nMem = 6; + for(i=0; iu.pHash ){ + assert( p->funcFlags & SQLITE_FUNC_BUILTIN ); + pragmaFunclistLine(v, p, 1, showInternFunc); + } + } + for(j=sqliteHashFirst(&db->aFunc); j; j=sqliteHashNext(j)){ + p = (FuncDef*)sqliteHashData(j); + assert( (p->funcFlags & SQLITE_FUNC_BUILTIN)==0 ); + pragmaFunclistLine(v, p, 0, showInternFunc); + } + } + break; + +#ifndef SQLITE_OMIT_VIRTUALTABLE + case PragTyp_MODULE_LIST: { + HashElem *j; + pParse->nMem = 1; + for(j=sqliteHashFirst(&db->aModule); j; j=sqliteHashNext(j)){ + Module *pMod = (Module*)sqliteHashData(j); + sqlite3VdbeMultiLoad(v, 1, "s", pMod->zName); + } + } + break; +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + + case PragTyp_PRAGMA_LIST: { + int i; + for(i=0; iu.tab.pFKey; + if( pFK ){ + int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); + int i = 0; + pParse->nMem = 8; + sqlite3CodeVerifySchema(pParse, iTabDb); + while(pFK){ + int j; + for(j=0; jnCol; j++){ + sqlite3VdbeMultiLoad(v, 1, "iissssss", + i, + j, + pFK->zTo, + pTab->aCol[pFK->aCol[j].iFrom].zCnName, + pFK->aCol[j].zCol, + actionName(pFK->aAction[1]), /* ON UPDATE */ + actionName(pFK->aAction[0]), /* ON DELETE */ + "NONE"); + } + ++i; + pFK = pFK->pNextFrom; + } + } + } + } + break; +#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ + +#ifndef SQLITE_OMIT_FOREIGN_KEY +#ifndef SQLITE_OMIT_TRIGGER + case PragTyp_FOREIGN_KEY_CHECK: { + FKey *pFK; /* A foreign key constraint */ + Table *pTab; /* Child table contain "REFERENCES" keyword */ + Table *pParent; /* Parent table that child points to */ + Index *pIdx; /* Index in the parent table */ + int i; /* Loop counter: Foreign key number for pTab */ + int j; /* Loop counter: Field of the foreign key */ + HashElem *k; /* Loop counter: Next table in schema */ + int x; /* result variable */ + int regResult; /* 3 registers to hold a result row */ + int regRow; /* Registers to hold a row from pTab */ + int addrTop; /* Top of a loop checking foreign keys */ + int addrOk; /* Jump here if the key is OK */ + int *aiCols; /* child to parent column mapping */ + + regResult = pParse->nMem+1; + pParse->nMem += 4; + regRow = ++pParse->nMem; + k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash); + while( k ){ + if( zRight ){ + pTab = sqlite3LocateTable(pParse, 0, zRight, zDb); + k = 0; + }else{ + pTab = (Table*)sqliteHashData(k); + k = sqliteHashNext(k); + } + if( pTab==0 || !IsOrdinaryTable(pTab) || pTab->u.tab.pFKey==0 ) continue; + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + zDb = db->aDb[iDb].zDbSName; + sqlite3CodeVerifySchema(pParse, iDb); + sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); + sqlite3TouchRegister(pParse, pTab->nCol+regRow); + sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead); + sqlite3VdbeLoadString(v, regResult, pTab->zName); + assert( IsOrdinaryTable(pTab) ); + for(i=1, pFK=pTab->u.tab.pFKey; pFK; i++, pFK=pFK->pNextFrom){ + pParent = sqlite3FindTable(db, pFK->zTo, zDb); + if( pParent==0 ) continue; + pIdx = 0; + sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName); + x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0); + if( x==0 ){ + if( pIdx==0 ){ + sqlite3OpenTable(pParse, i, iDb, pParent, OP_OpenRead); + }else{ + sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIdx); + } + }else{ + k = 0; + break; + } + } + assert( pParse->nErr>0 || pFK==0 ); + if( pFK ) break; + if( pParse->nTabnTab = i; + addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0); VdbeCoverage(v); + assert( IsOrdinaryTable(pTab) ); + for(i=1, pFK=pTab->u.tab.pFKey; pFK; i++, pFK=pFK->pNextFrom){ + pParent = sqlite3FindTable(db, pFK->zTo, zDb); + pIdx = 0; + aiCols = 0; + if( pParent ){ + x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols); + assert( x==0 || db->mallocFailed ); + } + addrOk = sqlite3VdbeMakeLabel(pParse); + + /* Generate code to read the child key values into registers + ** regRow..regRow+n. If any of the child key values are NULL, this + ** row cannot cause an FK violation. Jump directly to addrOk in + ** this case. */ + sqlite3TouchRegister(pParse, regRow + pFK->nCol); + for(j=0; jnCol; j++){ + int iCol = aiCols ? aiCols[j] : pFK->aCol[j].iFrom; + sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, iCol, regRow+j); + sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v); + } + + /* Generate code to query the parent index for a matching parent + ** key. If a match is found, jump to addrOk. */ + if( pIdx ){ + sqlite3VdbeAddOp4(v, OP_Affinity, regRow, pFK->nCol, 0, + sqlite3IndexAffinityStr(db,pIdx), pFK->nCol); + sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regRow, pFK->nCol); + VdbeCoverage(v); + }else if( pParent ){ + int jmp = sqlite3VdbeCurrentAddr(v)+2; + sqlite3VdbeAddOp3(v, OP_SeekRowid, i, jmp, regRow); VdbeCoverage(v); + sqlite3VdbeGoto(v, addrOk); + assert( pFK->nCol==1 || db->mallocFailed ); + } + + /* Generate code to report an FK violation to the caller. */ + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1); + }else{ + sqlite3VdbeAddOp2(v, OP_Null, 0, regResult+1); + } + sqlite3VdbeMultiLoad(v, regResult+2, "siX", pFK->zTo, i-1); + sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 4); + sqlite3VdbeResolveLabel(v, addrOk); + sqlite3DbFree(db, aiCols); + } + sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addrTop); + } + } + break; +#endif /* !defined(SQLITE_OMIT_TRIGGER) */ +#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ + +#ifndef SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA + /* Reinstall the LIKE and GLOB functions. The variant of LIKE + ** used will be case sensitive or not depending on the RHS. + */ + case PragTyp_CASE_SENSITIVE_LIKE: { + if( zRight ){ + sqlite3RegisterLikeFunctions(db, sqlite3GetBoolean(zRight, 0)); + } + } + break; +#endif /* SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA */ + +#ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX +# define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100 +#endif + +#ifndef SQLITE_OMIT_INTEGRITY_CHECK + /* PRAGMA integrity_check + ** PRAGMA integrity_check(N) + ** PRAGMA quick_check + ** PRAGMA quick_check(N) + ** + ** Verify the integrity of the database. + ** + ** The "quick_check" is reduced version of + ** integrity_check designed to detect most database corruption + ** without the overhead of cross-checking indexes. Quick_check + ** is linear time whereas integrity_check is O(NlogN). + ** + ** The maximum number of errors is 100 by default. A different default + ** can be specified using a numeric parameter N. + ** + ** Or, the parameter N can be the name of a table. In that case, only + ** the one table named is verified. The freelist is only verified if + ** the named table is "sqlite_schema" (or one of its aliases). + ** + ** All schemas are checked by default. To check just a single + ** schema, use the form: + ** + ** PRAGMA schema.integrity_check; + */ + case PragTyp_INTEGRITY_CHECK: { + int i, j, addr, mxErr; + Table *pObjTab = 0; /* Check only this one table, if not NULL */ + + int isQuick = (sqlite3Tolower(zLeft[0])=='q'); + + /* If the PRAGMA command was of the form "PRAGMA .integrity_check", + ** then iDb is set to the index of the database identified by . + ** In this case, the integrity of database iDb only is verified by + ** the VDBE created below. + ** + ** Otherwise, if the command was simply "PRAGMA integrity_check" (or + ** "PRAGMA quick_check"), then iDb is set to 0. In this case, set iDb + ** to -1 here, to indicate that the VDBE should verify the integrity + ** of all attached databases. */ + assert( iDb>=0 ); + assert( iDb==0 || pId2->z ); + if( pId2->z==0 ) iDb = -1; + + /* Initialize the VDBE program */ + pParse->nMem = 6; + + /* Set the maximum error count */ + mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; + if( zRight ){ + if( sqlite3GetInt32(pValue->z, &mxErr) ){ + if( mxErr<=0 ){ + mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; + } + }else{ + pObjTab = sqlite3LocateTable(pParse, 0, zRight, + iDb>=0 ? db->aDb[iDb].zDbSName : 0); + } + } + sqlite3VdbeAddOp2(v, OP_Integer, mxErr-1, 1); /* reg[1] holds errors left */ + + /* Do an integrity check on each database file */ + for(i=0; inDb; i++){ + HashElem *x; /* For looping over tables in the schema */ + Hash *pTbls; /* Set of all tables in the schema */ + int *aRoot; /* Array of root page numbers of all btrees */ + int cnt = 0; /* Number of entries in aRoot[] */ + + if( OMIT_TEMPDB && i==1 ) continue; + if( iDb>=0 && i!=iDb ) continue; + + sqlite3CodeVerifySchema(pParse, i); + pParse->okConstFactor = 0; /* tag-20230327-1 */ + + /* Do an integrity check of the B-Tree + ** + ** Begin by finding the root pages numbers + ** for all tables and indices in the database. + */ + assert( sqlite3SchemaMutexHeld(db, i, 0) ); + pTbls = &db->aDb[i].pSchema->tblHash; + for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ + Table *pTab = sqliteHashData(x); /* Current table */ + Index *pIdx; /* An index on pTab */ + int nIdx; /* Number of indexes on pTab */ + if( tableSkipIntegrityCheck(pTab,pObjTab) ) continue; + if( HasRowid(pTab) ) cnt++; + for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ cnt++; } + } + if( cnt==0 ) continue; + if( pObjTab ) cnt++; + aRoot = sqlite3DbMallocRawNN(db, sizeof(int)*(cnt+1)); + if( aRoot==0 ) break; + cnt = 0; + if( pObjTab ) aRoot[++cnt] = 0; + for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ + Table *pTab = sqliteHashData(x); + Index *pIdx; + if( tableSkipIntegrityCheck(pTab,pObjTab) ) continue; + if( HasRowid(pTab) ) aRoot[++cnt] = pTab->tnum; + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + aRoot[++cnt] = pIdx->tnum; + } + } + aRoot[0] = cnt; + + /* Make sure sufficient number of registers have been allocated */ + sqlite3TouchRegister(pParse, 8+cnt); + sqlite3VdbeAddOp3(v, OP_Null, 0, 8, 8+cnt); + sqlite3ClearTempRegCache(pParse); + + /* Do the b-tree integrity checks */ + sqlite3VdbeAddOp4(v, OP_IntegrityCk, 1, cnt, 8, (char*)aRoot,P4_INTARRAY); + sqlite3VdbeChangeP5(v, (u16)i); + addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, + sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zDbSName), + P4_DYNAMIC); + sqlite3VdbeAddOp3(v, OP_Concat, 2, 3, 3); + integrityCheckResultRow(v); + sqlite3VdbeJumpHere(v, addr); + + /* Check that the indexes all have the right number of rows */ + cnt = pObjTab ? 1 : 0; + sqlite3VdbeLoadString(v, 2, "wrong # of entries in index "); + for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ + int iTab = 0; + Table *pTab = sqliteHashData(x); + Index *pIdx; + if( tableSkipIntegrityCheck(pTab,pObjTab) ) continue; + if( HasRowid(pTab) ){ + iTab = cnt++; + }else{ + iTab = cnt; + for(pIdx=pTab->pIndex; ALWAYS(pIdx); pIdx=pIdx->pNext){ + if( IsPrimaryKeyIndex(pIdx) ) break; + iTab++; + } + } + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + if( pIdx->pPartIdxWhere==0 ){ + addr = sqlite3VdbeAddOp3(v, OP_Eq, 8+cnt, 0, 8+iTab); + VdbeCoverageNeverNull(v); + sqlite3VdbeLoadString(v, 4, pIdx->zName); + sqlite3VdbeAddOp3(v, OP_Concat, 4, 2, 3); + integrityCheckResultRow(v); + sqlite3VdbeJumpHere(v, addr); + } + cnt++; + } + } + + /* Make sure all the indices are constructed correctly. + */ + for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ + Table *pTab = sqliteHashData(x); + Index *pIdx, *pPk; + Index *pPrior = 0; /* Previous index */ + int loopTop; + int iDataCur, iIdxCur; + int r1 = -1; + int bStrict; /* True for a STRICT table */ + int r2; /* Previous key for WITHOUT ROWID tables */ + int mxCol; /* Maximum non-virtual column number */ + + if( tableSkipIntegrityCheck(pTab,pObjTab) ) continue; + if( !IsOrdinaryTable(pTab) ) continue; + if( isQuick || HasRowid(pTab) ){ + pPk = 0; + r2 = 0; + }else{ + pPk = sqlite3PrimaryKeyIndex(pTab); + r2 = sqlite3GetTempRange(pParse, pPk->nKeyCol); + sqlite3VdbeAddOp3(v, OP_Null, 1, r2, r2+pPk->nKeyCol-1); + } + sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0, + 1, 0, &iDataCur, &iIdxCur); + /* reg[7] counts the number of entries in the table. + ** reg[8+i] counts the number of entries in the i-th index + */ + sqlite3VdbeAddOp2(v, OP_Integer, 0, 7); + for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ + sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */ + } + assert( pParse->nMem>=8+j ); + assert( sqlite3NoTempsInRange(pParse,1,7+j) ); + sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v); + loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1); + + /* Fetch the right-most column from the table. This will cause + ** the entire record header to be parsed and sanity checked. It + ** will also prepopulate the cursor column cache that is used + ** by the OP_IsType code, so it is a required step. + */ + assert( !IsVirtual(pTab) ); + if( HasRowid(pTab) ){ + mxCol = -1; + for(j=0; jnCol; j++){ + if( (pTab->aCol[j].colFlags & COLFLAG_VIRTUAL)==0 ) mxCol++; + } + if( mxCol==pTab->iPKey ) mxCol--; + }else{ + /* COLFLAG_VIRTUAL columns are not included in the WITHOUT ROWID + ** PK index column-count, so there is no need to account for them + ** in this case. */ + mxCol = sqlite3PrimaryKeyIndex(pTab)->nColumn-1; + } + if( mxCol>=0 ){ + sqlite3VdbeAddOp3(v, OP_Column, iDataCur, mxCol, 3); + sqlite3VdbeTypeofColumn(v, 3); + } + + if( !isQuick ){ + if( pPk ){ + /* Verify WITHOUT ROWID keys are in ascending order */ + int a1; + char *zErr; + a1 = sqlite3VdbeAddOp4Int(v, OP_IdxGT, iDataCur, 0,r2,pPk->nKeyCol); + VdbeCoverage(v); + sqlite3VdbeAddOp1(v, OP_IsNull, r2); VdbeCoverage(v); + zErr = sqlite3MPrintf(db, + "row not in PRIMARY KEY order for %s", + pTab->zName); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); + integrityCheckResultRow(v); + sqlite3VdbeJumpHere(v, a1); + sqlite3VdbeJumpHere(v, a1+1); + for(j=0; jnKeyCol; j++){ + sqlite3ExprCodeLoadIndexColumn(pParse, pPk, iDataCur, j, r2+j); + } + } + } + /* Verify datatypes for all columns: + ** + ** (1) NOT NULL columns may not contain a NULL + ** (2) Datatype must be exact for non-ANY columns in STRICT tables + ** (3) Datatype for TEXT columns in non-STRICT tables must be + ** NULL, TEXT, or BLOB. + ** (4) Datatype for numeric columns in non-STRICT tables must not + ** be a TEXT value that can be losslessly converted to numeric. + */ + bStrict = (pTab->tabFlags & TF_Strict)!=0; + for(j=0; jnCol; j++){ + char *zErr; + Column *pCol = pTab->aCol + j; /* The column to be checked */ + int labelError; /* Jump here to report an error */ + int labelOk; /* Jump here if all looks ok */ + int p1, p3, p4; /* Operands to the OP_IsType opcode */ + int doTypeCheck; /* Check datatypes (besides NOT NULL) */ + + if( j==pTab->iPKey ) continue; + if( bStrict ){ + doTypeCheck = pCol->eCType>COLTYPE_ANY; + }else{ + doTypeCheck = pCol->affinity>SQLITE_AFF_BLOB; + } + if( pCol->notNull==0 && !doTypeCheck ) continue; + + /* Compute the operands that will be needed for OP_IsType */ + p4 = SQLITE_NULL; + if( pCol->colFlags & COLFLAG_VIRTUAL ){ + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3); + p1 = -1; + p3 = 3; + }else{ + if( pCol->iDflt ){ + sqlite3_value *pDfltValue = 0; + sqlite3ValueFromExpr(db, sqlite3ColumnExpr(pTab,pCol), ENC(db), + pCol->affinity, &pDfltValue); + if( pDfltValue ){ + p4 = sqlite3_value_type(pDfltValue); + sqlite3ValueFree(pDfltValue); + } + } + p1 = iDataCur; + if( !HasRowid(pTab) ){ + testcase( j!=sqlite3TableColumnToStorage(pTab, j) ); + p3 = sqlite3TableColumnToIndex(sqlite3PrimaryKeyIndex(pTab), j); + }else{ + p3 = sqlite3TableColumnToStorage(pTab,j); + testcase( p3!=j); + } + } + + labelError = sqlite3VdbeMakeLabel(pParse); + labelOk = sqlite3VdbeMakeLabel(pParse); + if( pCol->notNull ){ + /* (1) NOT NULL columns may not contain a NULL */ + int jmp3; + int jmp2 = sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4); + VdbeCoverage(v); + if( p1<0 ){ + sqlite3VdbeChangeP5(v, 0x0f); /* INT, REAL, TEXT, or BLOB */ + jmp3 = jmp2; + }else{ + sqlite3VdbeChangeP5(v, 0x0d); /* INT, TEXT, or BLOB */ + /* OP_IsType does not detect NaN values in the database file + ** which should be treated as a NULL. So if the header type + ** is REAL, we have to load the actual data using OP_Column + ** to reliably determine if the value is a NULL. */ + sqlite3VdbeAddOp3(v, OP_Column, p1, p3, 3); + sqlite3ColumnDefault(v, pTab, j, 3); + jmp3 = sqlite3VdbeAddOp2(v, OP_NotNull, 3, labelOk); + VdbeCoverage(v); + } + zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName, + pCol->zCnName); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); + if( doTypeCheck ){ + sqlite3VdbeGoto(v, labelError); + sqlite3VdbeJumpHere(v, jmp2); + sqlite3VdbeJumpHere(v, jmp3); + }else{ + /* VDBE byte code will fall thru */ + } + } + if( bStrict && doTypeCheck ){ + /* (2) Datatype must be exact for non-ANY columns in STRICT tables*/ + static unsigned char aStdTypeMask[] = { + 0x1f, /* ANY */ + 0x18, /* BLOB */ + 0x11, /* INT */ + 0x11, /* INTEGER */ + 0x13, /* REAL */ + 0x14 /* TEXT */ + }; + sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4); + assert( pCol->eCType>=1 && pCol->eCType<=sizeof(aStdTypeMask) ); + sqlite3VdbeChangeP5(v, aStdTypeMask[pCol->eCType-1]); + VdbeCoverage(v); + zErr = sqlite3MPrintf(db, "non-%s value in %s.%s", + sqlite3StdType[pCol->eCType-1], + pTab->zName, pTab->aCol[j].zCnName); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); + }else if( !bStrict && pCol->affinity==SQLITE_AFF_TEXT ){ + /* (3) Datatype for TEXT columns in non-STRICT tables must be + ** NULL, TEXT, or BLOB. */ + sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4); + sqlite3VdbeChangeP5(v, 0x1c); /* NULL, TEXT, or BLOB */ + VdbeCoverage(v); + zErr = sqlite3MPrintf(db, "NUMERIC value in %s.%s", + pTab->zName, pTab->aCol[j].zCnName); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); + }else if( !bStrict && pCol->affinity>=SQLITE_AFF_NUMERIC ){ + /* (4) Datatype for numeric columns in non-STRICT tables must not + ** be a TEXT value that can be converted to numeric. */ + sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4); + sqlite3VdbeChangeP5(v, 0x1b); /* NULL, INT, FLOAT, or BLOB */ + VdbeCoverage(v); + if( p1>=0 ){ + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3); + } + sqlite3VdbeAddOp4(v, OP_Affinity, 3, 1, 0, "C", P4_STATIC); + sqlite3VdbeAddOp4Int(v, OP_IsType, -1, labelOk, 3, p4); + sqlite3VdbeChangeP5(v, 0x1c); /* NULL, TEXT, or BLOB */ + VdbeCoverage(v); + zErr = sqlite3MPrintf(db, "TEXT value in %s.%s", + pTab->zName, pTab->aCol[j].zCnName); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); + } + sqlite3VdbeResolveLabel(v, labelError); + integrityCheckResultRow(v); + sqlite3VdbeResolveLabel(v, labelOk); + } + /* Verify CHECK constraints */ + if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){ + ExprList *pCheck = sqlite3ExprListDup(db, pTab->pCheck, 0); + if( db->mallocFailed==0 ){ + int addrCkFault = sqlite3VdbeMakeLabel(pParse); + int addrCkOk = sqlite3VdbeMakeLabel(pParse); + char *zErr; + int k; + pParse->iSelfTab = iDataCur + 1; + for(k=pCheck->nExpr-1; k>0; k--){ + sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0); + } + sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk, + SQLITE_JUMPIFNULL); + sqlite3VdbeResolveLabel(v, addrCkFault); + pParse->iSelfTab = 0; + zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s", + pTab->zName); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); + integrityCheckResultRow(v); + sqlite3VdbeResolveLabel(v, addrCkOk); + } + sqlite3ExprListDelete(db, pCheck); + } + if( !isQuick ){ /* Omit the remaining tests for quick_check */ + /* Validate index entries for the current row */ + for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ + int jmp2, jmp3, jmp4, jmp5, label6; + int kk; + int ckUniq = sqlite3VdbeMakeLabel(pParse); + if( pPk==pIdx ) continue; + r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3, + pPrior, r1); + pPrior = pIdx; + sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1);/* increment entry count */ + /* Verify that an index entry exists for the current table row */ + sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1, + pIdx->nColumn); VdbeCoverage(v); + jmp2 = sqlite3VdbeAddOp3(v, OP_IFindKey, iIdxCur+j, ckUniq, r1); + VdbeCoverage(v); + sqlite3VdbeChangeP4(v, -1, (const char*)pIdx, P4_INDEX); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, + sqlite3MPrintf(db, "index %s stores an imprecise floating-point " + "value for row ", pIdx->zName), + P4_DYNAMIC); + sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); + integrityCheckResultRow(v); + sqlite3VdbeAddOp2(v, OP_Goto, 0, ckUniq); + + sqlite3VdbeJumpHere(v, jmp2); + sqlite3VdbeLoadString(v, 3, "row "); + sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); + sqlite3VdbeLoadString(v, 4, " missing from index "); + sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); + jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName); + sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); + jmp4 = integrityCheckResultRow(v); + sqlite3VdbeResolveLabel(v, ckUniq); + + /* The OP_IdxRowid opcode is an optimized version of OP_Column + ** that extracts the rowid off the end of the index record. + ** But it only works correctly if index record does not have + ** any extra bytes at the end. Verify that this is the case. */ + if( HasRowid(pTab) ){ + int jmp7; + sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur+j, 3); + jmp7 = sqlite3VdbeAddOp3(v, OP_Eq, 3, 0, r1+pIdx->nColumn-1); + VdbeCoverageNeverNull(v); + sqlite3VdbeLoadString(v, 3, + "rowid not at end-of-record for row "); + sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); + sqlite3VdbeLoadString(v, 4, " of index "); + sqlite3VdbeGoto(v, jmp5-1); + sqlite3VdbeJumpHere(v, jmp7); + } + + /* Any indexed columns with non-BINARY collations must still hold + ** the exact same text value as the table. */ + label6 = 0; + for(kk=0; kknKeyCol; kk++){ + if( pIdx->azColl[kk]==sqlite3StrBINARY ) continue; + if( label6==0 ) label6 = sqlite3VdbeMakeLabel(pParse); + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur+j, kk, 3); + sqlite3VdbeAddOp3(v, OP_Ne, 3, label6, r1+kk); VdbeCoverage(v); + } + if( label6 ){ + int jmp6 = sqlite3VdbeAddOp0(v, OP_Goto); + sqlite3VdbeResolveLabel(v, label6); + sqlite3VdbeLoadString(v, 3, "row "); + sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); + sqlite3VdbeLoadString(v, 4, " values differ from index "); + sqlite3VdbeGoto(v, jmp5-1); + sqlite3VdbeJumpHere(v, jmp6); + } + + /* For UNIQUE indexes, verify that only one entry exists with the + ** current key. The entry is unique if (1) any column is NULL + ** or (2) the next entry has a different key */ + if( IsUniqueIndex(pIdx) ){ + int uniqOk = sqlite3VdbeMakeLabel(pParse); + int jmp6; + for(kk=0; kknKeyCol; kk++){ + int iCol = pIdx->aiColumn[kk]; + assert( iCol!=XN_ROWID && iColnCol ); + if( iCol>=0 && pTab->aCol[iCol].notNull ) continue; + sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk); + VdbeCoverage(v); + } + jmp6 = sqlite3VdbeAddOp1(v, OP_Next, iIdxCur+j); VdbeCoverage(v); + sqlite3VdbeGoto(v, uniqOk); + sqlite3VdbeJumpHere(v, jmp6); + sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1, + pIdx->nKeyCol); VdbeCoverage(v); + sqlite3VdbeLoadString(v, 3, "non-unique entry in index "); + sqlite3VdbeGoto(v, jmp5); + sqlite3VdbeResolveLabel(v, uniqOk); + } + sqlite3VdbeJumpHere(v, jmp4); + sqlite3ResolvePartIdxLabel(pParse, jmp3); + } + } + sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, loopTop-1); + if( pPk ){ + assert( !isQuick ); + sqlite3ReleaseTempRange(pParse, r2, pPk->nKeyCol); + } + } + +#ifndef SQLITE_OMIT_VIRTUALTABLE + /* Second pass to invoke the xIntegrity method on all virtual + ** tables. + */ + for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ + Table *pTab = sqliteHashData(x); + sqlite3_vtab *pVTab; + int a1; + if( tableSkipIntegrityCheck(pTab,pObjTab) ) continue; + if( IsOrdinaryTable(pTab) ) continue; + if( !IsVirtual(pTab) ) continue; + if( pTab->nCol<=0 ){ + const char *zMod = pTab->u.vtab.azArg[0]; + if( sqlite3HashFind(&db->aModule, zMod)==0 ) continue; + } + sqlite3ViewGetColumnNames(pParse, pTab); + if( pTab->u.vtab.p==0 ) continue; + pVTab = pTab->u.vtab.p->pVtab; + if( NEVER(pVTab==0) ) continue; + if( NEVER(pVTab->pModule==0) ) continue; + if( pVTab->pModule->iVersion<4 ) continue; + if( pVTab->pModule->xIntegrity==0 ) continue; + sqlite3VdbeAddOp3(v, OP_VCheck, i, 3, isQuick); + pTab->nTabRef++; + sqlite3VdbeAppendP4(v, pTab, P4_TABLEREF); + a1 = sqlite3VdbeAddOp1(v, OP_IsNull, 3); VdbeCoverage(v); + integrityCheckResultRow(v); + sqlite3VdbeJumpHere(v, a1); + continue; + } +#endif + } + { + static const int iLn = VDBE_OFFSET_LINENO(2); + static const VdbeOpList endCode[] = { + { OP_AddImm, 1, 0, 0}, /* 0 */ + { OP_IfNotZero, 1, 4, 0}, /* 1 */ + { OP_String8, 0, 3, 0}, /* 2 */ + { OP_ResultRow, 3, 1, 0}, /* 3 */ + { OP_Halt, 0, 0, 0}, /* 4 */ + { OP_String8, 0, 3, 0}, /* 5 */ + { OP_Goto, 0, 3, 0}, /* 6 */ + }; + VdbeOp *aOp; + + aOp = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn); + if( aOp ){ + aOp[0].p2 = 1-mxErr; + aOp[2].p4type = P4_STATIC; + aOp[2].p4.z = "ok"; + aOp[5].p4type = P4_STATIC; + aOp[5].p4.z = (char*)sqlite3ErrStr(SQLITE_CORRUPT); + } + sqlite3VdbeChangeP3(v, 0, sqlite3VdbeCurrentAddr(v)-2); + } + } + break; +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ + +#ifndef SQLITE_OMIT_UTF16 + /* + ** PRAGMA encoding + ** PRAGMA encoding = "utf-8"|"utf-16"|"utf-16le"|"utf-16be" + ** + ** In its first form, this pragma returns the encoding of the main + ** database. If the database is not initialized, it is initialized now. + ** + ** The second form of this pragma is a no-op if the main database file + ** has not already been initialized. In this case it sets the default + ** encoding that will be used for the main database file if a new file + ** is created. If an existing main database file is opened, then the + ** default text encoding for the existing database is used. + ** + ** In all cases new databases created using the ATTACH command are + ** created to use the same default text encoding as the main database. If + ** the main database has not been initialized and/or created when ATTACH + ** is executed, this is done before the ATTACH operation. + ** + ** In the second form this pragma sets the text encoding to be used in + ** new database files created using this database handle. It is only + ** useful if invoked immediately after the main database i + */ + case PragTyp_ENCODING: { + static const struct EncName { + char *zName; + u8 enc; + } encnames[] = { + { "UTF8", SQLITE_UTF8 }, + { "UTF-8", SQLITE_UTF8 }, /* Must be element [1] */ + { "UTF-16le", SQLITE_UTF16LE }, /* Must be element [2] */ + { "UTF-16be", SQLITE_UTF16BE }, /* Must be element [3] */ + { "UTF16le", SQLITE_UTF16LE }, + { "UTF16be", SQLITE_UTF16BE }, + { "UTF-16", 0 }, /* SQLITE_UTF16NATIVE */ + { "UTF16", 0 }, /* SQLITE_UTF16NATIVE */ + { 0, 0 } + }; + const struct EncName *pEnc; + if( !zRight ){ /* "PRAGMA encoding" */ + if( sqlite3ReadSchema(pParse) ) goto pragma_out; + assert( encnames[SQLITE_UTF8].enc==SQLITE_UTF8 ); + assert( encnames[SQLITE_UTF16LE].enc==SQLITE_UTF16LE ); + assert( encnames[SQLITE_UTF16BE].enc==SQLITE_UTF16BE ); + returnSingleText(v, encnames[ENC(pParse->db)].zName); + }else{ /* "PRAGMA encoding = XXX" */ + /* Only change the value of sqlite.enc if the database handle is not + ** initialized. If the main database exists, the new sqlite.enc value + ** will be overwritten when the schema is next loaded. If it does not + ** already exists, it will be created to use the new encoding value. + */ + if( (db->mDbFlags & DBFLAG_EncodingFixed)==0 ){ + for(pEnc=&encnames[0]; pEnc->zName; pEnc++){ + if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){ + u8 enc = pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE; + SCHEMA_ENC(db) = enc; + sqlite3SetTextEncoding(db, enc); + break; + } + } + if( !pEnc->zName ){ + sqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight); + } + } + } + } + break; +#endif /* SQLITE_OMIT_UTF16 */ + +#ifndef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS + /* + ** PRAGMA [schema.]schema_version + ** PRAGMA [schema.]schema_version = + ** + ** PRAGMA [schema.]user_version + ** PRAGMA [schema.]user_version = + ** + ** PRAGMA [schema.]freelist_count + ** + ** PRAGMA [schema.]data_version + ** + ** PRAGMA [schema.]application_id + ** PRAGMA [schema.]application_id = + ** + ** The pragma's schema_version and user_version are used to set or get + ** the value of the schema-version and user-version, respectively. Both + ** the schema-version and the user-version are 32-bit signed integers + ** stored in the database header. + ** + ** The schema-cookie is usually only manipulated internally by SQLite. It + ** is incremented by SQLite whenever the database schema is modified (by + ** creating or dropping a table or index). The schema version is used by + ** SQLite each time a query is executed to ensure that the internal cache + ** of the schema used when compiling the SQL query matches the schema of + ** the database against which the compiled query is actually executed. + ** Subverting this mechanism by using "PRAGMA schema_version" to modify + ** the schema-version is potentially dangerous and may lead to program + ** crashes or database corruption. Use with caution! + ** + ** The user-version is not used internally by SQLite. It may be used by + ** applications for any purpose. + */ + case PragTyp_HEADER_VALUE: { + int iCookie = pPragma->iArg; /* Which cookie to read or write */ + sqlite3VdbeUsesBtree(v, iDb); + if( zRight && (pPragma->mPragFlg & PragFlg_ReadOnly)==0 ){ + /* Write the specified cookie value */ + static const VdbeOpList setCookie[] = { + { OP_Transaction, 0, 1, 0}, /* 0 */ + { OP_SetCookie, 0, 0, 0}, /* 1 */ + }; + VdbeOp *aOp; + sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setCookie)); + aOp = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie, 0); + if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; + aOp[0].p1 = iDb; + aOp[1].p1 = iDb; + aOp[1].p2 = iCookie; + aOp[1].p3 = sqlite3Atoi(zRight); + aOp[1].p5 = 1; + if( iCookie==BTREE_SCHEMA_VERSION && (db->flags & SQLITE_Defensive)!=0 ){ + /* Do not allow the use of PRAGMA schema_version=VALUE in defensive + ** mode. Change the OP_SetCookie opcode into a no-op. */ + aOp[1].opcode = OP_Noop; + } + }else{ + /* Read the specified cookie value */ + static const VdbeOpList readCookie[] = { + { OP_Transaction, 0, 0, 0}, /* 0 */ + { OP_ReadCookie, 0, 1, 0}, /* 1 */ + { OP_ResultRow, 1, 1, 0} + }; + VdbeOp *aOp; + sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(readCookie)); + aOp = sqlite3VdbeAddOpList(v, ArraySize(readCookie),readCookie,0); + if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; + aOp[0].p1 = iDb; + aOp[1].p1 = iDb; + aOp[1].p3 = iCookie; + sqlite3VdbeReusable(v); + } + } + break; +#endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */ + +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS + /* + ** PRAGMA compile_options + ** + ** Return the names of all compile-time options used in this build, + ** one option per row. + */ + case PragTyp_COMPILE_OPTIONS: { + int i = 0; + const char *zOpt; + pParse->nMem = 1; + while( (zOpt = sqlite3_compileoption_get(i++))!=0 ){ + sqlite3VdbeLoadString(v, 1, zOpt); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + } + sqlite3VdbeReusable(v); + } + break; +#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ + +#ifndef SQLITE_OMIT_WAL + /* + ** PRAGMA [schema.]wal_checkpoint = passive|full|restart|truncate + ** + ** Checkpoint the database. + */ + case PragTyp_WAL_CHECKPOINT: { + int iBt = (pId2->z?iDb:SQLITE_MAX_DB); + int eMode = SQLITE_CHECKPOINT_PASSIVE; + if( zRight ){ + if( sqlite3StrICmp(zRight, "full")==0 ){ + eMode = SQLITE_CHECKPOINT_FULL; + }else if( sqlite3StrICmp(zRight, "restart")==0 ){ + eMode = SQLITE_CHECKPOINT_RESTART; + }else if( sqlite3StrICmp(zRight, "truncate")==0 ){ + eMode = SQLITE_CHECKPOINT_TRUNCATE; + }else if( sqlite3StrICmp(zRight, "noop")==0 ){ + eMode = SQLITE_CHECKPOINT_NOOP; + } + } + pParse->nMem = 3; + sqlite3VdbeAddOp3(v, OP_Checkpoint, iBt, eMode, 1); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); + } + break; + + /* + ** PRAGMA wal_autocheckpoint + ** PRAGMA wal_autocheckpoint = N + ** + ** Configure a database connection to automatically checkpoint a database + ** after accumulating N frames in the log. Or query for the current value + ** of N. + */ + case PragTyp_WAL_AUTOCHECKPOINT: { + if( zRight ){ + sqlite3_wal_autocheckpoint(db, sqlite3Atoi(zRight)); + } + returnSingleInt(v, + db->xWalCallback==sqlite3WalDefaultHook ? + SQLITE_PTR_TO_INT(db->pWalArg) : 0); + } + break; +#endif + + /* + ** PRAGMA shrink_memory + ** + ** IMPLEMENTATION-OF: R-23445-46109 This pragma causes the database + ** connection on which it is invoked to free up as much memory as it + ** can, by calling sqlite3_db_release_memory(). + */ + case PragTyp_SHRINK_MEMORY: { + sqlite3_db_release_memory(db); + break; + } + + /* + ** PRAGMA optimize + ** PRAGMA optimize(MASK) + ** PRAGMA schema.optimize + ** PRAGMA schema.optimize(MASK) + ** + ** Attempt to optimize the database. All schemas are optimized in the first + ** two forms, and only the specified schema is optimized in the latter two. + ** + ** The details of optimizations performed by this pragma are expected + ** to change and improve over time. Applications should anticipate that + ** this pragma will perform new optimizations in future releases. + ** + ** The optional argument is a bitmask of optimizations to perform: + ** + ** 0x00001 Debugging mode. Do not actually perform any optimizations + ** but instead return one line of text for each optimization + ** that would have been done. Off by default. + ** + ** 0x00002 Run ANALYZE on tables that might benefit. On by default. + ** See below for additional information. + ** + ** 0x00010 Run all ANALYZE operations using an analysis_limit that + ** is the lessor of the current analysis_limit and the + ** SQLITE_DEFAULT_OPTIMIZE_LIMIT compile-time option. + ** The default value of SQLITE_DEFAULT_OPTIMIZE_LIMIT is + ** currently (2024-02-19) set to 2000, which is such that + ** the worst case run-time for PRAGMA optimize on a 100MB + ** database will usually be less than 100 milliseconds on + ** a RaspberryPI-4 class machine. On by default. + ** + ** 0x10000 Look at tables to see if they need to be reanalyzed + ** due to growth or shrinkage even if they have not been + ** queried during the current connection. Off by default. + ** + ** The default MASK is and always shall be 0x0fffe. In the current + ** implementation, the default mask only covers the 0x00002 optimization, + ** though additional optimizations that are covered by 0x0fffe might be + ** added in the future. Optimizations that are off by default and must + ** be explicitly requested have masks of 0x10000 or greater. + ** + ** DETERMINATION OF WHEN TO RUN ANALYZE + ** + ** In the current implementation, a table is analyzed if only if all of + ** the following are true: + ** + ** (1) MASK bit 0x00002 is set. + ** + ** (2) The table is an ordinary table, not a virtual table or view. + ** + ** (3) The table name does not begin with "sqlite_". + ** + ** (4) One or more of the following is true: + ** (4a) The 0x10000 MASK bit is set. + ** (4b) One or more indexes on the table lacks an entry + ** in the sqlite_stat1 table. + ** (4c) The query planner used sqlite_stat1-style statistics for one + ** or more indexes of the table at some point during the lifetime + ** of the current connection. + ** + ** (5) One or more of the following is true: + ** (5a) One or more indexes on the table lacks an entry + ** in the sqlite_stat1 table. (Same as 4a) + ** (5b) The number of rows in the table has increased or decreased by + ** 10-fold. In other words, the current size of the table is + ** 10 times larger than the size in sqlite_stat1 or else the + ** current size is less than 1/10th the size in sqlite_stat1. + ** + ** The rules for when tables are analyzed are likely to change in + ** future releases. Future versions of SQLite might accept a string + ** literal argument to this pragma that contains a mnemonic description + ** of the options rather than a bitmap. + */ + case PragTyp_OPTIMIZE: { + int iDbLast; /* Loop termination point for the schema loop */ + int iTabCur; /* Cursor for a table whose size needs checking */ + HashElem *k; /* Loop over tables of a schema */ + Schema *pSchema; /* The current schema */ + Table *pTab; /* A table in the schema */ + Index *pIdx; /* An index of the table */ + LogEst szThreshold; /* Size threshold above which reanalysis needed */ + char *zSubSql; /* SQL statement for the OP_SqlExec opcode */ + u32 opMask; /* Mask of operations to perform */ + int nLimit; /* Analysis limit to use */ + int nCheck = 0; /* Number of tables to be optimized */ + int nBtree = 0; /* Number of btrees to scan */ + int nIndex; /* Number of indexes on the current table */ + + if( zRight ){ + opMask = (u32)sqlite3Atoi(zRight); + if( (opMask & 0x02)==0 ) break; + }else{ + opMask = 0xfffe; + } + if( (opMask & 0x10)==0 ){ + nLimit = 0; + }else if( db->nAnalysisLimit>0 + && db->nAnalysisLimitnTab++; + for(iDbLast = zDb?iDb:db->nDb-1; iDb<=iDbLast; iDb++){ + if( iDb==1 ) continue; + sqlite3CodeVerifySchema(pParse, iDb); + pSchema = db->aDb[iDb].pSchema; + for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ + pTab = (Table*)sqliteHashData(k); + + /* This only works for ordinary tables */ + if( !IsOrdinaryTable(pTab) ) continue; + + /* Do not scan system tables */ + if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) ) continue; + + /* Find the size of the table as last recorded in sqlite_stat1. + ** If any index is unanalyzed, then the threshold is -1 to + ** indicate a new, unanalyzed index + */ + szThreshold = pTab->nRowLogEst; + nIndex = 0; + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + nIndex++; + if( !pIdx->hasStat1 ){ + szThreshold = -1; /* Always analyze if any index lacks statistics */ + } + } + + /* If table pTab has not been used in a way that would benefit from + ** having analysis statistics during the current session, then skip it, + ** unless the 0x10000 MASK bit is set. */ + if( (pTab->tabFlags & TF_MaybeReanalyze)!=0 ){ + /* Check for size change if stat1 has been used for a query */ + }else if( opMask & 0x10000 ){ + /* Check for size change if 0x10000 is set */ + }else if( pTab->pIndex!=0 && szThreshold<0 ){ + /* Do analysis if unanalyzed indexes exists */ + }else{ + /* Otherwise, we can skip this table */ + continue; + } + + nCheck++; + if( nCheck==2 ){ + /* If ANALYZE might be invoked two or more times, hold a write + ** transaction for efficiency */ + sqlite3BeginWriteOperation(pParse, 0, iDb); + } + nBtree += nIndex+1; + + /* Reanalyze if the table is 10 times larger or smaller than + ** the last analysis. Unconditional reanalysis if there are + ** unanalyzed indexes. */ + sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); + if( szThreshold>=0 ){ + const LogEst iRange = 33; /* 10x size change */ + sqlite3VdbeAddOp4Int(v, OP_IfSizeBetween, iTabCur, + sqlite3VdbeCurrentAddr(v)+2+(opMask&1), + szThreshold>=iRange ? szThreshold-iRange : -1, + szThreshold+iRange); + VdbeCoverage(v); + }else{ + sqlite3VdbeAddOp2(v, OP_Rewind, iTabCur, + sqlite3VdbeCurrentAddr(v)+2+(opMask&1)); + VdbeCoverage(v); + } + zSubSql = sqlite3MPrintf(db, "ANALYZE \"%w\".\"%w\"", + db->aDb[iDb].zDbSName, pTab->zName); + if( opMask & 0x01 ){ + int r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp4(v, OP_String8, 0, r1, 0, zSubSql, P4_DYNAMIC); + sqlite3VdbeAddOp2(v, OP_ResultRow, r1, 1); + }else{ + sqlite3VdbeAddOp4(v, OP_SqlExec, nLimit ? 0x02 : 00, nLimit, 0, + zSubSql, P4_DYNAMIC); + } + } + } + sqlite3VdbeAddOp0(v, OP_Expire); + + /* In a schema with a large number of tables and indexes, scale back + ** the analysis_limit to avoid excess run-time in the worst case. + */ + if( !db->mallocFailed && nLimit>0 && nBtree>100 ){ + int iAddr, iEnd; + VdbeOp *aOp; + nLimit = 100*nLimit/nBtree; + if( nLimit<100 ) nLimit = 100; + aOp = sqlite3VdbeGetOp(v, 0); + iEnd = sqlite3VdbeCurrentAddr(v); + for(iAddr=0; iAddrePragTyp==PragTyp_BUSY_TIMEOUT ); + if( zRight ){ + sqlite3_busy_timeout(db, sqlite3Atoi(zRight)); + } + returnSingleInt(v, db->busyTimeout); + break; + } + + /* + ** PRAGMA soft_heap_limit + ** PRAGMA soft_heap_limit = N + ** + ** IMPLEMENTATION-OF: R-26343-45930 This pragma invokes the + ** sqlite3_soft_heap_limit64() interface with the argument N, if N is + ** specified and is a non-negative integer. + ** IMPLEMENTATION-OF: R-64451-07163 The soft_heap_limit pragma always + ** returns the same integer that would be returned by the + ** sqlite3_soft_heap_limit64(-1) C-language function. + */ + case PragTyp_SOFT_HEAP_LIMIT: { + sqlite3_int64 N; + if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){ + sqlite3_soft_heap_limit64(N); + } + returnSingleInt(v, sqlite3_soft_heap_limit64(-1)); + break; + } + + /* + ** PRAGMA hard_heap_limit + ** PRAGMA hard_heap_limit = N + ** + ** Invoke sqlite3_hard_heap_limit64() to query or set the hard heap + ** limit. The hard heap limit can be activated or lowered by this + ** pragma, but not raised or deactivated. Only the + ** sqlite3_hard_heap_limit64() C-language API can raise or deactivate + ** the hard heap limit. This allows an application to set a heap limit + ** constraint that cannot be relaxed by an untrusted SQL script. + */ + case PragTyp_HARD_HEAP_LIMIT: { + sqlite3_int64 N; + if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){ + sqlite3_int64 iPrior = sqlite3_hard_heap_limit64(-1); + if( N>0 && (iPrior==0 || iPrior>N) ) sqlite3_hard_heap_limit64(N); + } + returnSingleInt(v, sqlite3_hard_heap_limit64(-1)); + break; + } + + /* + ** PRAGMA threads + ** PRAGMA threads = N + ** + ** Configure the maximum number of worker threads. Return the new + ** maximum, which might be less than requested. + */ + case PragTyp_THREADS: { + sqlite3_int64 N; + if( zRight + && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK + && N>=0 + ){ + sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, (int)(N&0x7fffffff)); + } + returnSingleInt(v, sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1)); + break; + } + + /* + ** PRAGMA analysis_limit + ** PRAGMA analysis_limit = N + ** + ** Configure the maximum number of rows that ANALYZE will examine + ** in each index that it looks at. Return the new limit. + */ + case PragTyp_ANALYSIS_LIMIT: { + sqlite3_int64 N; + if( zRight + && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK /* IMP: R-40975-20399 */ + && N>=0 + ){ + db->nAnalysisLimit = (int)(N&0x7fffffff); + } + returnSingleInt(v, db->nAnalysisLimit); /* IMP: R-57594-65522 */ + break; + } + +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + /* + ** Report the current state of file logs for all databases + */ + case PragTyp_LOCK_STATUS: { + static const char *const azLockName[] = { + "unlocked", "shared", "reserved", "pending", "exclusive" + }; + int i; + pParse->nMem = 2; + for(i=0; inDb; i++){ + Btree *pBt; + const char *zState = "unknown"; + int j; + if( db->aDb[i].zDbSName==0 ) continue; + pBt = db->aDb[i].pBt; + if( pBt==0 || sqlite3BtreePager(pBt)==0 ){ + zState = "closed"; + }else if( sqlite3_file_control(db, i ? db->aDb[i].zDbSName : 0, + SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){ + zState = azLockName[j]; + } + sqlite3VdbeMultiLoad(v, 1, "ss", db->aDb[i].zDbSName, zState); + } + break; + } +#endif + +#if defined(SQLITE_ENABLE_CEROD) + case PragTyp_ACTIVATE_EXTENSIONS: if( zRight ){ + if( sqlite3StrNICmp(zRight, "cerod-", 6)==0 ){ + sqlite3_activate_cerod(&zRight[6]); + } + } + break; +#endif + + } /* End of the PRAGMA switch */ + + /* The following block is a no-op unless SQLITE_DEBUG is defined. Its only + ** purpose is to execute assert() statements to verify that if the + ** PragFlg_NoColumns1 flag is set and the caller specified an argument + ** to the PRAGMA, the implementation has not added any OP_ResultRow + ** instructions to the VM. */ + if( (pPragma->mPragFlg & PragFlg_NoColumns1) && zRight ){ + sqlite3VdbeVerifyNoResultRow(v); + } + +pragma_out: + sqlite3DbFree(db, zLeft); + sqlite3DbFree(db, zRight); +} +#ifndef SQLITE_OMIT_VIRTUALTABLE +/***************************************************************************** +** Implementation of an eponymous virtual table that runs a pragma. +** +*/ +typedef struct PragmaVtab PragmaVtab; +typedef struct PragmaVtabCursor PragmaVtabCursor; +struct PragmaVtab { + sqlite3_vtab base; /* Base class. Must be first */ + sqlite3 *db; /* The database connection to which it belongs */ + const PragmaName *pName; /* Name of the pragma */ + u8 nHidden; /* Number of hidden columns */ + u8 iHidden; /* Index of the first hidden column */ +}; +struct PragmaVtabCursor { + sqlite3_vtab_cursor base; /* Base class. Must be first */ + sqlite3_stmt *pPragma; /* The pragma statement to run */ + sqlite_int64 iRowid; /* Current rowid */ + char *azArg[2]; /* Value of the argument and schema */ +}; + +/* +** Pragma virtual table module xConnect method. +*/ +static int pragmaVtabConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + const PragmaName *pPragma = (const PragmaName*)pAux; + PragmaVtab *pTab = 0; + int rc; + int i, j; + char cSep = '('; + StrAccum acc; + char zBuf[200]; + + UNUSED_PARAMETER(argc); + UNUSED_PARAMETER(argv); + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); + sqlite3_str_appendall(&acc, "CREATE TABLE x"); + for(i=0, j=pPragma->iPragCName; inPragCName; i++, j++){ + sqlite3_str_appendf(&acc, "%c\"%s\"", cSep, pragCName[j]); + cSep = ','; + } + if( i==0 ){ + sqlite3_str_appendf(&acc, "(\"%s\"", pPragma->zName); + i++; + } + j = 0; + if( pPragma->mPragFlg & PragFlg_Result1 ){ + sqlite3_str_appendall(&acc, ",arg HIDDEN"); + j++; + } + if( pPragma->mPragFlg & (PragFlg_SchemaOpt|PragFlg_SchemaReq) ){ + sqlite3_str_appendall(&acc, ",schema HIDDEN"); + j++; + } + sqlite3_str_append(&acc, ")", 1); + sqlite3StrAccumFinish(&acc); + assert( strlen(zBuf) < sizeof(zBuf)-1 ); + rc = sqlite3_declare_vtab(db, zBuf); + if( rc==SQLITE_OK ){ + pTab = (PragmaVtab*)sqlite3_malloc(sizeof(PragmaVtab)); + if( pTab==0 ){ + rc = SQLITE_NOMEM; + }else{ + memset(pTab, 0, sizeof(PragmaVtab)); + pTab->pName = pPragma; + pTab->db = db; + pTab->iHidden = i; + pTab->nHidden = j; + } + }else{ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + } + + *ppVtab = (sqlite3_vtab*)pTab; + return rc; +} + +/* +** Pragma virtual table module xDisconnect method. +*/ +static int pragmaVtabDisconnect(sqlite3_vtab *pVtab){ + PragmaVtab *pTab = (PragmaVtab*)pVtab; + sqlite3_free(pTab); + return SQLITE_OK; +} + +/* Figure out the best index to use to search a pragma virtual table. +** +** There are not really any index choices. But we want to encourage the +** query planner to give == constraints on as many hidden parameters as +** possible, and especially on the first hidden parameter. So return a +** high cost if hidden parameters are unconstrained. +*/ +static int pragmaVtabBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ + PragmaVtab *pTab = (PragmaVtab*)tab; + const struct sqlite3_index_constraint *pConstraint; + int i, j; + int seen[2]; + + pIdxInfo->estimatedCost = (double)1; + if( pTab->nHidden==0 ){ return SQLITE_OK; } + pConstraint = pIdxInfo->aConstraint; + seen[0] = 0; + seen[1] = 0; + for(i=0; inConstraint; i++, pConstraint++){ + if( pConstraint->iColumn < pTab->iHidden ) continue; + if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; + if( pConstraint->usable==0 ) return SQLITE_CONSTRAINT; + j = pConstraint->iColumn - pTab->iHidden; + assert( j < 2 ); + seen[j] = i+1; + } + if( seen[0]==0 ){ + pIdxInfo->estimatedCost = (double)2147483647; + pIdxInfo->estimatedRows = 2147483647; + return SQLITE_OK; + } + j = seen[0]-1; + pIdxInfo->aConstraintUsage[j].argvIndex = 1; + pIdxInfo->aConstraintUsage[j].omit = 1; + pIdxInfo->estimatedCost = (double)20; + pIdxInfo->estimatedRows = 20; + if( seen[1] ){ + j = seen[1]-1; + pIdxInfo->aConstraintUsage[j].argvIndex = 2; + pIdxInfo->aConstraintUsage[j].omit = 1; + } + return SQLITE_OK; +} + +/* Create a new cursor for the pragma virtual table */ +static int pragmaVtabOpen(sqlite3_vtab *pVtab, sqlite3_vtab_cursor **ppCursor){ + PragmaVtabCursor *pCsr; + pCsr = (PragmaVtabCursor*)sqlite3_malloc(sizeof(*pCsr)); + if( pCsr==0 ) return SQLITE_NOMEM; + memset(pCsr, 0, sizeof(PragmaVtabCursor)); + pCsr->base.pVtab = pVtab; + *ppCursor = &pCsr->base; + return SQLITE_OK; +} + +/* Clear all content from pragma virtual table cursor. */ +static void pragmaVtabCursorClear(PragmaVtabCursor *pCsr){ + int i; + sqlite3_finalize(pCsr->pPragma); + pCsr->pPragma = 0; + pCsr->iRowid = 0; + for(i=0; iazArg); i++){ + sqlite3_free(pCsr->azArg[i]); + pCsr->azArg[i] = 0; + } +} + +/* Close a pragma virtual table cursor */ +static int pragmaVtabClose(sqlite3_vtab_cursor *cur){ + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)cur; + pragmaVtabCursorClear(pCsr); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +/* Advance the pragma virtual table cursor to the next row */ +static int pragmaVtabNext(sqlite3_vtab_cursor *pVtabCursor){ + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; + int rc = SQLITE_OK; + + /* Increment the xRowid value */ + pCsr->iRowid++; + assert( pCsr->pPragma ); + if( SQLITE_ROW!=sqlite3_step(pCsr->pPragma) ){ + rc = sqlite3_finalize(pCsr->pPragma); + pCsr->pPragma = 0; + pragmaVtabCursorClear(pCsr); + } + return rc; +} + +/* +** Pragma virtual table module xFilter method. +*/ +static int pragmaVtabFilter( + sqlite3_vtab_cursor *pVtabCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; + PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab); + int rc; + int i, j; + StrAccum acc; + char *zSql; + + UNUSED_PARAMETER(idxNum); + UNUSED_PARAMETER(idxStr); + pragmaVtabCursorClear(pCsr); + j = (pTab->pName->mPragFlg & PragFlg_Result1)!=0 ? 0 : 1; + for(i=0; iazArg) ); + assert( pCsr->azArg[j]==0 ); + if( zText ){ + pCsr->azArg[j] = sqlite3_mprintf("%s", zText); + if( pCsr->azArg[j]==0 ){ + return SQLITE_NOMEM; + } + } + } + sqlite3StrAccumInit(&acc, 0, 0, 0, pTab->db->aLimit[SQLITE_LIMIT_SQL_LENGTH]); + sqlite3_str_appendall(&acc, "PRAGMA "); + if( pCsr->azArg[1] ){ + sqlite3_str_appendf(&acc, "%Q.", pCsr->azArg[1]); + } + sqlite3_str_appendall(&acc, pTab->pName->zName); + if( pCsr->azArg[0] ){ + sqlite3_str_appendf(&acc, "=%Q", pCsr->azArg[0]); + } + zSql = sqlite3StrAccumFinish(&acc); + if( zSql==0 ) return SQLITE_NOMEM; + rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pPragma, 0); + sqlite3_free(zSql); + if( rc!=SQLITE_OK ){ + pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db)); + return rc; + } + return pragmaVtabNext(pVtabCursor); +} + +/* +** Pragma virtual table module xEof method. +*/ +static int pragmaVtabEof(sqlite3_vtab_cursor *pVtabCursor){ + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; + return (pCsr->pPragma==0); +} + +/* The xColumn method simply returns the corresponding column from +** the PRAGMA. +*/ +static int pragmaVtabColumn( + sqlite3_vtab_cursor *pVtabCursor, + sqlite3_context *ctx, + int i +){ + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; + PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab); + if( iiHidden ){ + sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pPragma, i)); + }else{ + sqlite3_result_text(ctx, pCsr->azArg[i-pTab->iHidden],-1,SQLITE_TRANSIENT); + } + return SQLITE_OK; +} + +/* +** Pragma virtual table module xRowid method. +*/ +static int pragmaVtabRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *p){ + PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; + *p = pCsr->iRowid; + return SQLITE_OK; +} + +/* The pragma virtual table object */ +static const sqlite3_module pragmaVtabModule = { + 0, /* iVersion */ + 0, /* xCreate - create a table */ + pragmaVtabConnect, /* xConnect - connect to an existing table */ + pragmaVtabBestIndex, /* xBestIndex - Determine search strategy */ + pragmaVtabDisconnect, /* xDisconnect - Disconnect from a table */ + 0, /* xDestroy - Drop a table */ + pragmaVtabOpen, /* xOpen - open a cursor */ + pragmaVtabClose, /* xClose - close a cursor */ + pragmaVtabFilter, /* xFilter - configure scan constraints */ + pragmaVtabNext, /* xNext - advance a cursor */ + pragmaVtabEof, /* xEof */ + pragmaVtabColumn, /* xColumn - read data */ + pragmaVtabRowid, /* xRowid - read data */ + 0, /* xUpdate - write data */ + 0, /* xBegin - begin transaction */ + 0, /* xSync - sync transaction */ + 0, /* xCommit - commit transaction */ + 0, /* xRollback - rollback transaction */ + 0, /* xFindFunction - function overloading */ + 0, /* xRename - rename the table */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ +}; + +/* +** Check to see if zTabName is really the name of a pragma. If it is, +** then register an eponymous virtual table for that pragma and return +** a pointer to the Module object for the new virtual table. +*/ +SQLITE_PRIVATE Module *sqlite3PragmaVtabRegister(sqlite3 *db, const char *zName){ + const PragmaName *pName; + assert( sqlite3_strnicmp(zName, "pragma_", 7)==0 ); + pName = pragmaLocate(zName+7); + if( pName==0 ) return 0; + if( (pName->mPragFlg & (PragFlg_Result0|PragFlg_Result1))==0 ) return 0; + assert( sqlite3HashFind(&db->aModule, zName)==0 ); + return sqlite3VtabCreateModule(db, zName, &pragmaVtabModule, (void*)pName, 0); +} + +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#endif /* SQLITE_OMIT_PRAGMA */ + +/************** End of pragma.c **********************************************/ +/************** Begin file prepare.c *****************************************/ +/* +** 2005 May 25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains the implementation of the sqlite3_prepare() +** interface, and routines that contribute to loading the database schema +** from disk. +*/ +/* #include "sqliteInt.h" */ + +/* +** Fill the InitData structure with an error message that indicates +** that the database is corrupt. +*/ +static void corruptSchema( + InitData *pData, /* Initialization context */ + char **azObj, /* Type and name of object being parsed */ + const char *zExtra /* Error information */ +){ + sqlite3 *db = pData->db; + if( db->mallocFailed ){ + pData->rc = SQLITE_NOMEM_BKPT; + }else if( pData->pzErrMsg[0]!=0 ){ + /* A error message has already been generated. Do not overwrite it */ + }else if( pData->mInitFlags & (INITFLAG_AlterMask) ){ + static const char *azAlterType[] = { + "rename", + "drop column", + "add column", + "drop constraint" + }; + *pData->pzErrMsg = sqlite3MPrintf(db, + "error in %s %s after %s: %s", azObj[0], azObj[1], + azAlterType[(pData->mInitFlags&INITFLAG_AlterMask)-1], + zExtra + ); + pData->rc = SQLITE_ERROR; + }else if( db->flags & SQLITE_WriteSchema ){ + pData->rc = SQLITE_CORRUPT_BKPT; + }else{ + char *z; + const char *zObj = azObj[1] ? azObj[1] : "?"; + z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj); + if( zExtra && zExtra[0] ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra); + *pData->pzErrMsg = z; + pData->rc = SQLITE_CORRUPT_BKPT; + } +} + +/* +** Check to see if any sibling index (another index on the same table) +** of pIndex has the same root page number, and if it does, return true. +** This would indicate a corrupt schema. +*/ +SQLITE_PRIVATE int sqlite3IndexHasDuplicateRootPage(Index *pIndex){ + Index *p; + for(p=pIndex->pTable->pIndex; p; p=p->pNext){ + if( p->tnum==pIndex->tnum && p!=pIndex ) return 1; + } + return 0; +} + +/* forward declaration */ +static int sqlite3Prepare( + sqlite3 *db, /* Database handle. */ + const char *zSql, /* UTF-8 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + u32 prepFlags, /* Zero or more SQLITE_PREPARE_* flags */ + Vdbe *pReprepare, /* VM being reprepared */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const char **pzTail /* OUT: End of parsed string */ +); + + +/* +** This is the callback routine for the code that initializes the +** database. See sqlite3Init() below for additional information. +** This routine is also called from the OP_ParseSchema opcode of the VDBE. +** +** Each callback contains the following information: +** +** argv[0] = type of object: "table", "index", "trigger", or "view". +** argv[1] = name of thing being created +** argv[2] = associated table if an index or trigger +** argv[3] = root page number for table or index. 0 for trigger or view. +** argv[4] = SQL text for the CREATE statement. +** +*/ +SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ + InitData *pData = (InitData*)pInit; + sqlite3 *db = pData->db; + int iDb = pData->iDb; + + assert( argc==5 ); + UNUSED_PARAMETER2(NotUsed, argc); + assert( sqlite3_mutex_held(db->mutex) ); + db->mDbFlags |= DBFLAG_EncodingFixed; + if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */ + pData->nInitRow++; + if( db->mallocFailed ){ + corruptSchema(pData, argv, 0); + return 1; + } + + assert( iDb>=0 && iDbnDb ); + if( argv[3]==0 ){ + corruptSchema(pData, argv, 0); + }else if( argv[4] + && 'c'==sqlite3UpperToLower[(unsigned char)argv[4][0]] + && 'r'==sqlite3UpperToLower[(unsigned char)argv[4][1]] ){ + /* Call the parser to process a CREATE TABLE, INDEX or VIEW. + ** But because db->init.busy is set to 1, no VDBE code is generated + ** or executed. All the parser does is build the internal data + ** structures that describe the table, index, or view. + ** + ** No other valid SQL statement, other than the variable CREATE statements, + ** can begin with the letters "C" and "R". Thus, it is not possible run + ** any other kind of statement while parsing the schema, even a corrupt + ** schema. + */ + int rc; + u8 saved_iDb = db->init.iDb; + sqlite3_stmt *pStmt; + TESTONLY(int rcp); /* Return code from sqlite3_prepare() */ + + assert( db->init.busy ); + db->init.iDb = iDb; + if( sqlite3GetUInt32(argv[3], &db->init.newTnum)==0 + || (db->init.newTnum>pData->mxPage && pData->mxPage>0) + ){ + if( sqlite3Config.bExtraSchemaChecks ){ + corruptSchema(pData, argv, "invalid rootpage"); + } + } + db->init.orphanTrigger = 0; + db->init.azInit = (const char**)argv; + pStmt = 0; + TESTONLY(rcp = ) sqlite3Prepare(db, argv[4], -1, 0, 0, &pStmt, 0); + rc = db->errCode; + assert( (rc&0xFF)==(rcp&0xFF) ); + db->init.iDb = saved_iDb; + /* assert( saved_iDb==0 || (db->mDbFlags & DBFLAG_Vacuum)!=0 ); */ + if( SQLITE_OK!=rc ){ + if( db->init.orphanTrigger ){ + assert( iDb==1 ); + }else{ + if( rc > pData->rc ) pData->rc = rc; + if( rc==SQLITE_NOMEM ){ + sqlite3OomFault(db); + }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){ + corruptSchema(pData, argv, sqlite3_errmsg(db)); + } + } + } + db->init.azInit = sqlite3StdType; /* Any array of string ptrs will do */ + sqlite3_finalize(pStmt); + }else if( argv[1]==0 || (argv[4]!=0 && argv[4][0]!=0) ){ + corruptSchema(pData, argv, 0); + }else{ + /* If the SQL column is blank it means this is an index that + ** was created to be the PRIMARY KEY or to fulfill a UNIQUE + ** constraint for a CREATE TABLE. The index should have already + ** been created when we processed the CREATE TABLE. All we have + ** to do here is record the root page number for that index. + */ + Index *pIndex; + pIndex = sqlite3FindIndex(db, argv[1], db->aDb[iDb].zDbSName); + if( pIndex==0 ){ + corruptSchema(pData, argv, "orphan index"); + }else + if( sqlite3GetUInt32(argv[3],&pIndex->tnum)==0 + || pIndex->tnum<2 + || pIndex->tnum>pData->mxPage + || sqlite3IndexHasDuplicateRootPage(pIndex) + ){ + if( sqlite3Config.bExtraSchemaChecks ){ + corruptSchema(pData, argv, "invalid rootpage"); + } + } + } + return 0; +} + +/* +** Attempt to read the database schema and initialize internal +** data structures for a single database file. The index of the +** database file is given by iDb. iDb==0 is used for the main +** database. iDb==1 should never be used. iDb>=2 is used for +** auxiliary databases. Return one of the SQLITE_ error codes to +** indicate success or failure. +*/ +SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){ + int rc; + int i; +#ifndef SQLITE_OMIT_DEPRECATED + int size; +#endif + Db *pDb; + char const *azArg[6]; + int meta[5]; + InitData initData; + const char *zSchemaTabName; + int openedTransaction = 0; + int mask = ((db->mDbFlags & DBFLAG_EncodingFixed) | ~DBFLAG_EncodingFixed); + + assert( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 ); + assert( iDb>=0 && iDbnDb ); + assert( db->aDb[iDb].pSchema ); + assert( sqlite3_mutex_held(db->mutex) ); + assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); + + db->init.busy = 1; + + /* Construct the in-memory representation schema tables (sqlite_schema or + ** sqlite_temp_schema) by invoking the parser directly. The appropriate + ** table name will be inserted automatically by the parser so we can just + ** use the abbreviation "x" here. The parser will also automatically tag + ** the schema table as read-only. */ + azArg[0] = "table"; + azArg[1] = zSchemaTabName = SCHEMA_TABLE(iDb); + azArg[2] = azArg[1]; + azArg[3] = "1"; + azArg[4] = "CREATE TABLE x(type text,name text,tbl_name text," + "rootpage int,sql text)"; + azArg[5] = 0; + initData.db = db; + initData.iDb = iDb; + initData.rc = SQLITE_OK; + initData.pzErrMsg = pzErrMsg; + initData.mInitFlags = mFlags; + initData.nInitRow = 0; + initData.mxPage = 0; + sqlite3InitCallback(&initData, 5, (char **)azArg, 0); + db->mDbFlags &= mask; + if( initData.rc ){ + rc = initData.rc; + goto error_out; + } + + /* Create a cursor to hold the database open + */ + pDb = &db->aDb[iDb]; + if( pDb->pBt==0 ){ + assert( iDb==1 ); + DbSetProperty(db, 1, DB_SchemaLoaded); + rc = SQLITE_OK; + goto error_out; + } + + /* If there is not already a read-only (or read-write) transaction opened + ** on the b-tree database, open one now. If a transaction is opened, it + ** will be closed before this function returns. */ + sqlite3BtreeEnter(pDb->pBt); + if( sqlite3BtreeTxnState(pDb->pBt)==SQLITE_TXN_NONE ){ + rc = sqlite3BtreeBeginTrans(pDb->pBt, 0, 0); + if( rc!=SQLITE_OK ){ + sqlite3SetString(pzErrMsg, db, sqlite3ErrStr(rc)); + goto initone_error_out; + } + openedTransaction = 1; + } + + /* Get the database meta information. + ** + ** Meta values are as follows: + ** meta[0] Schema cookie. Changes with each schema change. + ** meta[1] File format of schema layer. + ** meta[2] Size of the page cache. + ** meta[3] Largest rootpage (auto/incr_vacuum mode) + ** meta[4] Db text encoding. 1:UTF-8 2:UTF-16LE 3:UTF-16BE + ** meta[5] User version + ** meta[6] Incremental vacuum mode + ** meta[7] unused + ** meta[8] unused + ** meta[9] unused + ** + ** Note: The #defined SQLITE_UTF* symbols in sqliteInt.h correspond to + ** the possible values of meta[4]. + */ + for(i=0; ipBt, i+1, (u32 *)&meta[i]); + } + if( (db->flags & SQLITE_ResetDatabase)!=0 ){ + memset(meta, 0, sizeof(meta)); + } + pDb->pSchema->schema_cookie = meta[BTREE_SCHEMA_VERSION-1]; + + /* If opening a non-empty database, check the text encoding. For the + ** main database, set sqlite3.enc to the encoding of the main database. + ** For an attached db, it is an error if the encoding is not the same + ** as sqlite3.enc. + */ + if( meta[BTREE_TEXT_ENCODING-1] ){ /* text encoding */ + if( iDb==0 && (db->mDbFlags & DBFLAG_EncodingFixed)==0 ){ + u8 encoding; +#ifndef SQLITE_OMIT_UTF16 + /* If opening the main database, set ENC(db). */ + encoding = (u8)meta[BTREE_TEXT_ENCODING-1] & 3; + if( encoding==0 ) encoding = SQLITE_UTF8; +#else + encoding = SQLITE_UTF8; +#endif + sqlite3SetTextEncoding(db, encoding); + }else{ + /* If opening an attached database, the encoding much match ENC(db) */ + if( (meta[BTREE_TEXT_ENCODING-1] & 3)!=ENC(db) ){ + sqlite3SetString(pzErrMsg, db, "attached databases must use the same" + " text encoding as main database"); + rc = SQLITE_ERROR; + goto initone_error_out; + } + } + } + pDb->pSchema->enc = ENC(db); + + if( pDb->pSchema->cache_size==0 ){ +#ifndef SQLITE_OMIT_DEPRECATED + size = sqlite3AbsInt32(meta[BTREE_DEFAULT_CACHE_SIZE-1]); + if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; } + pDb->pSchema->cache_size = size; +#else + pDb->pSchema->cache_size = SQLITE_DEFAULT_CACHE_SIZE; +#endif + sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); + } + + /* + ** file_format==1 Version 3.0.0. + ** file_format==2 Version 3.1.3. // ALTER TABLE ADD COLUMN + ** file_format==3 Version 3.1.4. // ditto but with non-NULL defaults + ** file_format==4 Version 3.3.0. // DESC indices. Boolean constants + */ + pDb->pSchema->file_format = (u8)meta[BTREE_FILE_FORMAT-1]; + if( pDb->pSchema->file_format==0 ){ + pDb->pSchema->file_format = 1; + } + if( pDb->pSchema->file_format>SQLITE_MAX_FILE_FORMAT ){ + sqlite3SetString(pzErrMsg, db, "unsupported file format"); + rc = SQLITE_ERROR; + goto initone_error_out; + } + + /* Ticket #2804: When we open a database in the newer file format, + ** clear the legacy_file_format pragma flag so that a VACUUM will + ** not downgrade the database and thus invalidate any descending + ** indices that the user might have created. + */ + if( iDb==0 && meta[BTREE_FILE_FORMAT-1]>=4 ){ + db->flags &= ~(u64)SQLITE_LegacyFileFmt; + } + + /* Read the schema information out of the schema tables + */ + assert( db->init.busy ); + initData.mxPage = sqlite3BtreeLastPage(pDb->pBt); + { + char *zSql; + zSql = sqlite3MPrintf(db, + "SELECT*FROM\"%w\".%s ORDER BY rowid", + db->aDb[iDb].zDbSName, zSchemaTabName); +#ifndef SQLITE_OMIT_AUTHORIZATION + { + sqlite3_xauth xAuth; + xAuth = db->xAuth; + db->xAuth = 0; +#endif + rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; + } +#endif + if( rc==SQLITE_OK ) rc = initData.rc; + sqlite3DbFree(db, zSql); +#ifndef SQLITE_OMIT_ANALYZE + if( rc==SQLITE_OK ){ + sqlite3AnalysisLoad(db, iDb); + } +#endif + } + assert( pDb == &(db->aDb[iDb]) ); + if( db->mallocFailed ){ + rc = SQLITE_NOMEM_BKPT; + sqlite3ResetAllSchemasOfConnection(db); + pDb = &db->aDb[iDb]; + }else + if( rc==SQLITE_OK || ((db->flags&SQLITE_NoSchemaError) && rc!=SQLITE_NOMEM)){ + /* Hack: If the SQLITE_NoSchemaError flag is set, then consider + ** the schema loaded, even if errors (other than OOM) occurred. In + ** this situation the current sqlite3_prepare() operation will fail, + ** but the following one will attempt to compile the supplied statement + ** against whatever subset of the schema was loaded before the error + ** occurred. + ** + ** The primary purpose of this is to allow access to the sqlite_schema + ** table even when its contents have been corrupted. + */ + DbSetProperty(db, iDb, DB_SchemaLoaded); + rc = SQLITE_OK; + } + + /* Jump here for an error that occurs after successfully allocating + ** curMain and calling sqlite3BtreeEnter(). For an error that occurs + ** before that point, jump to error_out. + */ +initone_error_out: + if( openedTransaction ){ + sqlite3BtreeCommit(pDb->pBt); + } + sqlite3BtreeLeave(pDb->pBt); + +error_out: + if( rc ){ + if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ + sqlite3OomFault(db); + } + sqlite3ResetOneSchema(db, iDb); + } + db->init.busy = 0; + return rc; +} + +/* +** Initialize all database files - the main database file, the file +** used to store temporary tables, and any additional database files +** created using ATTACH statements. Return a success code. If an +** error occurs, write an error message into *pzErrMsg. +** +** After a database is initialized, the DB_SchemaLoaded bit is set +** bit is set in the flags field of the Db structure. +*/ +SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){ + int i, rc; + int commit_internal = !(db->mDbFlags&DBFLAG_SchemaChange); + + assert( sqlite3_mutex_held(db->mutex) ); + assert( sqlite3BtreeHoldsMutex(db->aDb[0].pBt) ); + assert( db->init.busy==0 ); + ENC(db) = SCHEMA_ENC(db); + assert( db->nDb>0 ); + /* Do the main schema first */ + if( !DbHasProperty(db, 0, DB_SchemaLoaded) ){ + rc = sqlite3InitOne(db, 0, pzErrMsg, 0); + if( rc ) return rc; + } + /* All other schemas after the main schema. The "temp" schema must be last */ + for(i=db->nDb-1; i>0; i--){ + assert( i==1 || sqlite3BtreeHoldsMutex(db->aDb[i].pBt) ); + if( !DbHasProperty(db, i, DB_SchemaLoaded) ){ + rc = sqlite3InitOne(db, i, pzErrMsg, 0); + if( rc ) return rc; + } + } + if( commit_internal ){ + sqlite3CommitInternalChanges(db); + } + return SQLITE_OK; +} + +/* +** This routine is a no-op if the database schema is already initialized. +** Otherwise, the schema is loaded. An error code is returned. +*/ +SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse){ + int rc = SQLITE_OK; + sqlite3 *db = pParse->db; + assert( sqlite3_mutex_held(db->mutex) ); + if( !db->init.busy ){ + rc = sqlite3Init(db, &pParse->zErrMsg); + if( rc!=SQLITE_OK ){ + pParse->rc = rc; + pParse->nErr++; + }else if( db->noSharedCache ){ + db->mDbFlags |= DBFLAG_SchemaKnownOk; + } + } + return rc; +} + + +/* +** Check schema cookies in all databases. If any cookie is out +** of date set pParse->rc to SQLITE_SCHEMA. If all schema cookies +** make no changes to pParse->rc. +*/ +static void schemaIsValid(Parse *pParse){ + sqlite3 *db = pParse->db; + int iDb; + int rc; + int cookie; + + assert( pParse->checkSchema ); + assert( sqlite3_mutex_held(db->mutex) ); + for(iDb=0; iDbnDb; iDb++){ + int openedTransaction = 0; /* True if a transaction is opened */ + Btree *pBt = db->aDb[iDb].pBt; /* Btree database to read cookie from */ + if( pBt==0 ) continue; + + /* If there is not already a read-only (or read-write) transaction opened + ** on the b-tree database, open one now. If a transaction is opened, it + ** will be closed immediately after reading the meta-value. */ + if( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_NONE ){ + rc = sqlite3BtreeBeginTrans(pBt, 0, 0); + if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ + sqlite3OomFault(db); + pParse->rc = SQLITE_NOMEM; + } + if( rc!=SQLITE_OK ) return; + openedTransaction = 1; + } + + /* Read the schema cookie from the database. If it does not match the + ** value stored as part of the in-memory schema representation, + ** set Parse.rc to SQLITE_SCHEMA. */ + sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + if( cookie!=db->aDb[iDb].pSchema->schema_cookie ){ + if( DbHasProperty(db, iDb, DB_SchemaLoaded) ) pParse->rc = SQLITE_SCHEMA; + sqlite3ResetOneSchema(db, iDb); + } + + /* Close the transaction, if one was opened. */ + if( openedTransaction ){ + sqlite3BtreeCommit(pBt); + } + } +} + +/* +** Convert a schema pointer into the iDb index that indicates +** which database file in db->aDb[] the schema refers to. +** +** If the same database is attached more than once, the first +** attached database is returned. +*/ +SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){ + int i = -32768; + + /* If pSchema is NULL, then return -32768. This happens when code in + ** expr.c is trying to resolve a reference to a transient table (i.e. one + ** created by a sub-select). In this case the return value of this + ** function should never be used. + ** + ** We return -32768 instead of the more usual -1 simply because using + ** -32768 as the incorrect index into db->aDb[] is much + ** more likely to cause a segfault than -1 (of course there are assert() + ** statements too, but it never hurts to play the odds) and + ** -32768 will still fit into a 16-bit signed integer. + */ + assert( sqlite3_mutex_held(db->mutex) ); + if( pSchema ){ + for(i=0; 1; i++){ + assert( inDb ); + if( db->aDb[i].pSchema==pSchema ){ + break; + } + } + assert( i>=0 && inDb ); + } + return i; +} + +/* +** Free all memory allocations in the pParse object +*/ +SQLITE_PRIVATE void sqlite3ParseObjectReset(Parse *pParse){ + sqlite3 *db = pParse->db; + assert( db!=0 ); + assert( db->pParse==pParse ); + assert( pParse->nested==0 ); +#ifndef SQLITE_OMIT_SHARED_CACHE + if( pParse->aTableLock ) sqlite3DbNNFreeNN(db, pParse->aTableLock); +#endif + while( pParse->pCleanup ){ + ParseCleanup *pCleanup = pParse->pCleanup; + pParse->pCleanup = pCleanup->pNext; + pCleanup->xCleanup(db, pCleanup->pPtr); + sqlite3DbNNFreeNN(db, pCleanup); + } + if( pParse->aLabel ) sqlite3DbNNFreeNN(db, pParse->aLabel); + if( pParse->pConstExpr ){ + sqlite3ExprListDelete(db, pParse->pConstExpr); + } + assert( db->lookaside.bDisable >= pParse->disableLookaside ); + db->lookaside.bDisable -= pParse->disableLookaside; + db->lookaside.sz = db->lookaside.bDisable ? 0 : db->lookaside.szTrue; + assert( pParse->db->pParse==pParse ); + db->pParse = pParse->pOuterParse; +} + +/* +** Add a new cleanup operation to a Parser. The cleanup should happen when +** the parser object is destroyed. But, beware: the cleanup might happen +** immediately. +** +** Use this mechanism for uncommon cleanups. There is a higher setup +** cost for this mechanism (an extra malloc), so it should not be used +** for common cleanups that happen on most calls. But for less +** common cleanups, we save a single NULL-pointer comparison in +** sqlite3ParseObjectReset(), which reduces the total CPU cycle count. +** +** If a memory allocation error occurs, then the cleanup happens immediately. +** When either SQLITE_DEBUG or SQLITE_COVERAGE_TEST are defined, the +** pParse->earlyCleanup flag is set in that case. Calling code show verify +** that test cases exist for which this happens, to guard against possible +** use-after-free errors following an OOM. The preferred way to do this is +** to immediately follow the call to this routine with: +** +** testcase( pParse->earlyCleanup ); +** +** This routine returns a copy of its pPtr input (the third parameter) +** except if an early cleanup occurs, in which case it returns NULL. So +** another way to check for early cleanup is to check the return value. +** Or, stop using the pPtr parameter with this call and use only its +** return value thereafter. Something like this: +** +** pObj = sqlite3ParserAddCleanup(pParse, destructor, pObj); +*/ +SQLITE_PRIVATE void *sqlite3ParserAddCleanup( + Parse *pParse, /* Destroy when this Parser finishes */ + void (*xCleanup)(sqlite3*,void*), /* The cleanup routine */ + void *pPtr /* Pointer to object to be cleaned up */ +){ + ParseCleanup *pCleanup; + if( sqlite3FaultSim(300) ){ + pCleanup = 0; + sqlite3OomFault(pParse->db); + }else{ + pCleanup = sqlite3DbMallocRaw(pParse->db, sizeof(*pCleanup)); + } + if( pCleanup ){ + pCleanup->pNext = pParse->pCleanup; + pParse->pCleanup = pCleanup; + pCleanup->pPtr = pPtr; + pCleanup->xCleanup = xCleanup; + }else{ + xCleanup(pParse->db, pPtr); + pPtr = 0; +#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) + pParse->earlyCleanup = 1; +#endif + } + return pPtr; +} + +/* +** Turn bulk memory into a valid Parse object and link that Parse object +** into database connection db. +** +** Call sqlite3ParseObjectReset() to undo this operation. +** +** Caution: Do not confuse this routine with sqlite3ParseObjectInit() which +** is generated by Lemon. +*/ +SQLITE_PRIVATE void sqlite3ParseObjectInit(Parse *pParse, sqlite3 *db){ + memset(PARSE_HDR(pParse), 0, PARSE_HDR_SZ); + memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ); + assert( db->pParse!=pParse ); + pParse->pOuterParse = db->pParse; + db->pParse = pParse; + pParse->db = db; + if( db->mallocFailed ) sqlite3ErrorMsg(pParse, "out of memory"); +} + +/* +** Maximum number of times that we will try again to prepare a statement +** that returns SQLITE_ERROR_RETRY. +*/ +#ifndef SQLITE_MAX_PREPARE_RETRY +# define SQLITE_MAX_PREPARE_RETRY 25 +#endif + +/* +** Compile the UTF-8 encoded SQL statement zSql into a statement handle. +*/ +static int sqlite3Prepare( + sqlite3 *db, /* Database handle. */ + const char *zSql, /* UTF-8 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + u32 prepFlags, /* Zero or more SQLITE_PREPARE_* flags */ + Vdbe *pReprepare, /* VM being reprepared */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const char **pzTail /* OUT: End of parsed string */ +){ + int rc = SQLITE_OK; /* Result code */ + int i; /* Loop counter */ + Parse sParse; /* Parsing context */ + + /* sqlite3ParseObjectInit(&sParse, db); // inlined for performance */ + memset(PARSE_HDR(&sParse), 0, PARSE_HDR_SZ); + memset(PARSE_TAIL(&sParse), 0, PARSE_TAIL_SZ); + sParse.pOuterParse = db->pParse; + db->pParse = &sParse; + sParse.db = db; + if( pReprepare ){ + sParse.pReprepare = pReprepare; + sParse.explain = sqlite3_stmt_isexplain((sqlite3_stmt*)pReprepare); + }else{ + assert( sParse.pReprepare==0 ); + } + assert( ppStmt && *ppStmt==0 ); + if( db->mallocFailed ){ + sqlite3ErrorMsg(&sParse, "out of memory"); + db->errCode = rc = SQLITE_NOMEM; + goto end_prepare; + } + assert( sqlite3_mutex_held(db->mutex) ); + + /* For a long-term use prepared statement avoid the use of + ** lookaside memory. + */ + if( prepFlags & SQLITE_PREPARE_PERSISTENT ){ + sParse.disableLookaside++; + DisableLookaside; + } + sParse.prepFlags = prepFlags & 0xff; + + /* Check to verify that it is possible to get a read lock on all + ** database schemas. The inability to get a read lock indicates that + ** some other database connection is holding a write-lock, which in + ** turn means that the other connection has made uncommitted changes + ** to the schema. + ** + ** Were we to proceed and prepare the statement against the uncommitted + ** schema changes and if those schema changes are subsequently rolled + ** back and different changes are made in their place, then when this + ** prepared statement goes to run the schema cookie would fail to detect + ** the schema change. Disaster would follow. + ** + ** This thread is currently holding mutexes on all Btrees (because + ** of the sqlite3BtreeEnterAll() in sqlite3LockAndPrepare()) so it + ** is not possible for another thread to start a new schema change + ** while this routine is running. Hence, we do not need to hold + ** locks on the schema, we just need to make sure nobody else is + ** holding them. + ** + ** Note that setting READ_UNCOMMITTED overrides most lock detection, + ** but it does *not* override schema lock detection, so this all still + ** works even if READ_UNCOMMITTED is set. + */ + if( !db->noSharedCache ){ + for(i=0; inDb; i++) { + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + assert( sqlite3BtreeHoldsMutex(pBt) ); + rc = sqlite3BtreeSchemaLocked(pBt); + if( rc ){ + const char *zDb = db->aDb[i].zDbSName; + sqlite3ErrorWithMsg(db, rc, "database schema is locked: %s", zDb); + testcase( db->flags & SQLITE_ReadUncommit ); + goto end_prepare; + } + } + } + } + +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( db->pDisconnect ) sqlite3VtabUnlockList(db); +#endif + + if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){ + char *zSqlCopy; + int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; + testcase( nBytes==mxLen ); + testcase( nBytes==mxLen+1 ); + if( nBytes>mxLen ){ + sqlite3ErrorWithMsg(db, SQLITE_TOOBIG, "statement too long"); + rc = sqlite3ApiExit(db, SQLITE_TOOBIG); + goto end_prepare; + } + zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes); + if( zSqlCopy ){ + sqlite3RunParser(&sParse, zSqlCopy); + sParse.zTail = &zSql[sParse.zTail-zSqlCopy]; + sqlite3DbFree(db, zSqlCopy); + }else{ + sParse.zTail = &zSql[nBytes]; + } + }else{ + sqlite3RunParser(&sParse, zSql); + } + assert( 0==sParse.nQueryLoop ); + + if( pzTail ){ + *pzTail = sParse.zTail; + } + + if( db->init.busy==0 ){ + sqlite3VdbeSetSql(sParse.pVdbe, zSql, (int)(sParse.zTail-zSql), prepFlags); + } + if( db->mallocFailed ){ + sParse.rc = SQLITE_NOMEM_BKPT; + sParse.checkSchema = 0; + } + if( sParse.rc!=SQLITE_OK && sParse.rc!=SQLITE_DONE ){ + if( sParse.checkSchema && db->init.busy==0 ){ + schemaIsValid(&sParse); + } + if( sParse.pVdbe ){ + sqlite3VdbeFinalize(sParse.pVdbe); + } + assert( 0==(*ppStmt) ); + rc = sParse.rc; + if( sParse.zErrMsg ){ + sqlite3ErrorWithMsg(db, rc, "%s", sParse.zErrMsg); + sqlite3DbFree(db, sParse.zErrMsg); + }else{ + sqlite3Error(db, rc); + } + }else{ + assert( sParse.zErrMsg==0 ); + *ppStmt = (sqlite3_stmt*)sParse.pVdbe; + rc = SQLITE_OK; + sqlite3ErrorClear(db); + } + + + /* Delete any TriggerPrg structures allocated while parsing this statement. */ + while( sParse.pTriggerPrg ){ + TriggerPrg *pT = sParse.pTriggerPrg; + sParse.pTriggerPrg = pT->pNext; + sqlite3DbFree(db, pT); + } + +end_prepare: + + sqlite3ParseObjectReset(&sParse); + return rc; +} +static int sqlite3LockAndPrepare( + sqlite3 *db, /* Database handle. */ + const char *zSql, /* UTF-8 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + u32 prepFlags, /* Zero or more SQLITE_PREPARE_* flags */ + Vdbe *pOld, /* VM being reprepared */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const char **pzTail /* OUT: End of parsed string */ +){ + int rc; + int cnt = 0; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( ppStmt==0 ) return SQLITE_MISUSE_BKPT; +#endif + *ppStmt = 0; + if( !sqlite3SafetyCheckOk(db)||zSql==0 ){ + return SQLITE_MISUSE_BKPT; + } + sqlite3_mutex_enter(db->mutex); + sqlite3BtreeEnterAll(db); + do{ + /* Make multiple attempts to compile the SQL, until it either succeeds + ** or encounters a permanent error. A schema problem after one schema + ** reset is considered a permanent error. */ + rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail); + assert( rc==SQLITE_OK || *ppStmt==0 ); + if( rc==SQLITE_OK || db->mallocFailed ) break; + cnt++; + }while( (rc==SQLITE_ERROR_RETRY && ALWAYS(cnt<=SQLITE_MAX_PREPARE_RETRY)) + || (rc==SQLITE_SCHEMA && (sqlite3ResetOneSchema(db,-1), cnt)==1) ); + sqlite3BtreeLeaveAll(db); + assert( rc!=SQLITE_ERROR_RETRY ); + rc = sqlite3ApiExit(db, rc); + assert( (rc&db->errMask)==rc ); + db->busyHandler.nBusy = 0; + sqlite3_mutex_leave(db->mutex); + assert( rc==SQLITE_OK || (*ppStmt)==0 ); + return rc; +} + + +/* +** Rerun the compilation of a statement after a schema change. +** +** If the statement is successfully recompiled, return SQLITE_OK. Otherwise, +** if the statement cannot be recompiled because another connection has +** locked the sqlite3_schema table, return SQLITE_LOCKED. If any other error +** occurs, return SQLITE_SCHEMA. +*/ +SQLITE_PRIVATE int sqlite3Reprepare(Vdbe *p){ + int rc; + sqlite3_stmt *pNew; + const char *zSql; + sqlite3 *db; + u8 prepFlags; + + assert( sqlite3_mutex_held(sqlite3VdbeDb(p)->mutex) ); + zSql = sqlite3_sql((sqlite3_stmt *)p); + assert( zSql!=0 ); /* Reprepare only called for prepare_v2() statements */ + db = sqlite3VdbeDb(p); + assert( sqlite3_mutex_held(db->mutex) ); + prepFlags = sqlite3VdbePrepareFlags(p); + rc = sqlite3LockAndPrepare(db, zSql, -1, prepFlags, p, &pNew, 0); + if( rc ){ + if( rc==SQLITE_NOMEM ){ + sqlite3OomFault(db); + } + assert( pNew==0 ); + return rc; + }else{ + assert( pNew!=0 ); + } + sqlite3VdbeSwap((Vdbe*)pNew, p); + sqlite3TransferBindings(pNew, (sqlite3_stmt*)p); + sqlite3VdbeResetStepResult((Vdbe*)pNew); + sqlite3VdbeFinalize((Vdbe*)pNew); + return SQLITE_OK; +} + + +/* +** Two versions of the official API. Legacy and new use. In the legacy +** version, the original SQL text is not saved in the prepared statement +** and so if a schema change occurs, SQLITE_SCHEMA is returned by +** sqlite3_step(). In the new version, the original SQL text is retained +** and the statement is automatically recompiled if an schema change +** occurs. +*/ +SQLITE_API int sqlite3_prepare( + sqlite3 *db, /* Database handle. */ + const char *zSql, /* UTF-8 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const char **pzTail /* OUT: End of parsed string */ +){ + int rc; + rc = sqlite3LockAndPrepare(db,zSql,nBytes,0,0,ppStmt,pzTail); + assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ + return rc; +} +SQLITE_API int sqlite3_prepare_v2( + sqlite3 *db, /* Database handle. */ + const char *zSql, /* UTF-8 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const char **pzTail /* OUT: End of parsed string */ +){ + int rc; + /* EVIDENCE-OF: R-37923-12173 The sqlite3_prepare_v2() interface works + ** exactly the same as sqlite3_prepare_v3() with a zero prepFlags + ** parameter. + ** + ** Proof in that the 5th parameter to sqlite3LockAndPrepare is 0 */ + rc = sqlite3LockAndPrepare(db,zSql,nBytes,SQLITE_PREPARE_SAVESQL,0, + ppStmt,pzTail); + assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); + return rc; +} +SQLITE_API int sqlite3_prepare_v3( + sqlite3 *db, /* Database handle. */ + const char *zSql, /* UTF-8 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_* flags */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const char **pzTail /* OUT: End of parsed string */ +){ + int rc; + /* EVIDENCE-OF: R-56861-42673 sqlite3_prepare_v3() differs from + ** sqlite3_prepare_v2() only in having the extra prepFlags parameter, + ** which is a bit array consisting of zero or more of the + ** SQLITE_PREPARE_* flags. + ** + ** Proof by comparison to the implementation of sqlite3_prepare_v2() + ** directly above. */ + rc = sqlite3LockAndPrepare(db,zSql,nBytes, + SQLITE_PREPARE_SAVESQL|(prepFlags&SQLITE_PREPARE_MASK), + 0,ppStmt,pzTail); + assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); + return rc; +} + + +#ifndef SQLITE_OMIT_UTF16 +/* +** Compile the UTF-16 encoded SQL statement zSql into a statement handle. +*/ +static int sqlite3Prepare16( + sqlite3 *db, /* Database handle. */ + const void *zSql, /* UTF-16 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + u32 prepFlags, /* Zero or more SQLITE_PREPARE_* flags */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const void **pzTail /* OUT: End of parsed string */ +){ + /* This function currently works by first transforming the UTF-16 + ** encoded string to UTF-8, then invoking sqlite3_prepare(). The + ** tricky bit is figuring out the pointer to return in *pzTail. + */ + char *zSql8; + const char *zTail8 = 0; + int rc = SQLITE_OK; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( ppStmt==0 ) return SQLITE_MISUSE_BKPT; +#endif + *ppStmt = 0; + if( !sqlite3SafetyCheckOk(db)||zSql==0 ){ + return SQLITE_MISUSE_BKPT; + } + + /* Make sure nBytes is non-negative and correct. It should be the + ** number of bytes until the end of the input buffer or until the first + ** U+0000 character. If the input nBytes is odd, convert it into + ** an even number. If the input nBytes is negative, then the input + ** must be terminated by at least one U+0000 character */ + if( nBytes>=0 ){ + int sz; + const char *z = (const char*)zSql; + for(sz=0; szmutex); + zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE); + if( zSql8 ){ + rc = sqlite3LockAndPrepare(db, zSql8, -1, prepFlags, 0, ppStmt, &zTail8); + } + + if( zTail8 && pzTail ){ + /* If sqlite3_prepare returns a tail pointer, we calculate the + ** equivalent pointer into the UTF-16 string by counting the unicode + ** characters between zSql8 and zTail8, and then returning a pointer + ** the same number of characters into the UTF-16 string. + */ + int chars_parsed = sqlite3Utf8CharLen(zSql8, (int)(zTail8-zSql8)); + *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, nBytes, chars_parsed); + } + sqlite3DbFree(db, zSql8); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Two versions of the official API. Legacy and new use. In the legacy +** version, the original SQL text is not saved in the prepared statement +** and so if a schema change occurs, SQLITE_SCHEMA is returned by +** sqlite3_step(). In the new version, the original SQL text is retained +** and the statement is automatically recompiled if an schema change +** occurs. +*/ +SQLITE_API int sqlite3_prepare16( + sqlite3 *db, /* Database handle. */ + const void *zSql, /* UTF-16 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const void **pzTail /* OUT: End of parsed string */ +){ + int rc; + rc = sqlite3Prepare16(db,zSql,nBytes,0,ppStmt,pzTail); + assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ + return rc; +} +SQLITE_API int sqlite3_prepare16_v2( + sqlite3 *db, /* Database handle. */ + const void *zSql, /* UTF-16 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const void **pzTail /* OUT: End of parsed string */ +){ + int rc; + rc = sqlite3Prepare16(db,zSql,nBytes,SQLITE_PREPARE_SAVESQL,ppStmt,pzTail); + assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ + return rc; +} +SQLITE_API int sqlite3_prepare16_v3( + sqlite3 *db, /* Database handle. */ + const void *zSql, /* UTF-16 encoded SQL statement. */ + int nBytes, /* Length of zSql in bytes. */ + unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_* flags */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + const void **pzTail /* OUT: End of parsed string */ +){ + int rc; + rc = sqlite3Prepare16(db,zSql,nBytes, + SQLITE_PREPARE_SAVESQL|(prepFlags&SQLITE_PREPARE_MASK), + ppStmt,pzTail); + assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ + return rc; +} + +#endif /* SQLITE_OMIT_UTF16 */ + +/************** End of prepare.c *********************************************/ +/************** Begin file select.c ******************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains C code routines that are called by the parser +** to handle SELECT statements in SQLite. +*/ +/* #include "sqliteInt.h" */ + +/* +** An instance of the following object is used to record information about +** how to process the DISTINCT keyword, to simplify passing that information +** into the selectInnerLoop() routine. +*/ +typedef struct DistinctCtx DistinctCtx; +struct DistinctCtx { + u8 isTnct; /* 0: Not distinct. 1: DISTINCT 2: DISTINCT and ORDER BY */ + u8 eTnctType; /* One of the WHERE_DISTINCT_* operators */ + int tabTnct; /* Ephemeral table used for DISTINCT processing */ + int addrTnct; /* Address of OP_OpenEphemeral opcode for tabTnct */ +}; + +/* +** An instance of the following object is used to record information about +** the ORDER BY (or GROUP BY) clause of query is being coded. +** +** The aDefer[] array is used by the sorter-references optimization. For +** example, assuming there is no index that can be used for the ORDER BY, +** for the query: +** +** SELECT a, bigblob FROM t1 ORDER BY a LIMIT 10; +** +** it may be more efficient to add just the "a" values to the sorter, and +** retrieve the associated "bigblob" values directly from table t1 as the +** 10 smallest "a" values are extracted from the sorter. +** +** When the sorter-reference optimization is used, there is one entry in the +** aDefer[] array for each database table that may be read as values are +** extracted from the sorter. +*/ +typedef struct SortCtx SortCtx; +struct SortCtx { + ExprList *pOrderBy; /* The ORDER BY (or GROUP BY clause) */ + int nOBSat; /* Number of ORDER BY terms satisfied by indices */ + int iECursor; /* Cursor number for the sorter */ + int regReturn; /* Register holding block-output return address */ + int labelBkOut; /* Start label for the block-output subroutine */ + int addrSortIndex; /* Address of the OP_SorterOpen or OP_OpenEphemeral */ + int labelDone; /* Jump here when done, ex: LIMIT reached */ + int labelOBLopt; /* Jump here when sorter is full */ + u8 sortFlags; /* Zero or more SORTFLAG_* bits */ +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + u8 nDefer; /* Number of valid entries in aDefer[] */ + struct DeferredCsr { + Table *pTab; /* Table definition */ + int iCsr; /* Cursor number for table */ + int nKey; /* Number of PK columns for table pTab (>=1) */ + } aDefer[4]; +#endif + struct RowLoadInfo *pDeferredRowLoad; /* Deferred row loading info or NULL */ +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + int addrPush; /* First instruction to push data into sorter */ + int addrPushEnd; /* Last instruction that pushes data into sorter */ +#endif +}; +#define SORTFLAG_UseSorter 0x01 /* Use SorterOpen instead of OpenEphemeral */ + +/* +** Delete all the content of a Select structure. Deallocate the structure +** itself depending on the value of bFree +** +** If bFree==1, call sqlite3DbFree() on the p object. +** If bFree==0, Leave the first Select object unfreed +*/ +static void clearSelect(sqlite3 *db, Select *p, int bFree){ + assert( db!=0 ); + while( p ){ + Select *pPrior = p->pPrior; + sqlite3ExprListDelete(db, p->pEList); + sqlite3SrcListDelete(db, p->pSrc); + sqlite3ExprDelete(db, p->pWhere); + sqlite3ExprListDelete(db, p->pGroupBy); + sqlite3ExprDelete(db, p->pHaving); + sqlite3ExprListDelete(db, p->pOrderBy); + sqlite3ExprDelete(db, p->pLimit); + if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( OK_IF_ALWAYS_TRUE(p->pWinDefn) ){ + sqlite3WindowListDelete(db, p->pWinDefn); + } + while( p->pWin ){ + assert( p->pWin->ppThis==&p->pWin ); + sqlite3WindowUnlinkFromSelect(p->pWin); + } +#endif + if( bFree ) sqlite3DbNNFreeNN(db, p); + p = pPrior; + bFree = 1; + } +} + +/* +** Initialize a SelectDest structure. +*/ +SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){ + pDest->eDest = (u8)eDest; + pDest->iSDParm = iParm; + pDest->iSDParm2 = 0; + pDest->zAffSdst = 0; + pDest->iSdst = 0; + pDest->nSdst = 0; +} + + +/* +** Allocate a new Select structure and return a pointer to that +** structure. +*/ +SQLITE_PRIVATE Select *sqlite3SelectNew( + Parse *pParse, /* Parsing context */ + ExprList *pEList, /* which columns to include in the result */ + SrcList *pSrc, /* the FROM clause -- which tables to scan */ + Expr *pWhere, /* the WHERE clause */ + ExprList *pGroupBy, /* the GROUP BY clause */ + Expr *pHaving, /* the HAVING clause */ + ExprList *pOrderBy, /* the ORDER BY clause */ + u32 selFlags, /* Flag parameters, such as SF_Distinct */ + Expr *pLimit /* LIMIT value. NULL means not used */ +){ + Select *pNew, *pAllocated; + Select standin; + pAllocated = pNew = sqlite3DbMallocRawNN(pParse->db, sizeof(*pNew) ); + if( pNew==0 ){ + assert( pParse->db->mallocFailed ); + pNew = &standin; + } + if( pEList==0 ){ + pEList = sqlite3ExprListAppend(pParse, 0, + sqlite3Expr(pParse->db,TK_ASTERISK,0)); + } + pNew->pEList = pEList; + pNew->op = TK_SELECT; + pNew->selFlags = selFlags; + pNew->iLimit = 0; + pNew->iOffset = 0; + pNew->selId = ++pParse->nSelect; + pNew->nSelectRow = 0; + if( pSrc==0 ) pSrc = sqlite3DbMallocZero(pParse->db, SZ_SRCLIST_1); + pNew->pSrc = pSrc; + pNew->pWhere = pWhere; + pNew->pGroupBy = pGroupBy; + pNew->pHaving = pHaving; + pNew->pOrderBy = pOrderBy; + pNew->pPrior = 0; + pNew->pNext = 0; + pNew->pLimit = pLimit; + pNew->pWith = 0; +#ifndef SQLITE_OMIT_WINDOWFUNC + pNew->pWin = 0; + pNew->pWinDefn = 0; +#endif + if( pParse->db->mallocFailed ) { + clearSelect(pParse->db, pNew, pNew!=&standin); + pAllocated = 0; + }else{ + assert( pNew->pSrc!=0 || pParse->nErr>0 ); + } + return pAllocated; +} + + +/* +** Delete the given Select structure and all of its substructures. +*/ +SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){ + if( OK_IF_ALWAYS_TRUE(p) ) clearSelect(db, p, 1); +} +SQLITE_PRIVATE void sqlite3SelectDeleteGeneric(sqlite3 *db, void *p){ + if( ALWAYS(p) ) clearSelect(db, (Select*)p, 1); +} + +/* +** Return a pointer to the right-most SELECT statement in a compound. +*/ +static Select *findRightmost(Select *p){ + while( p->pNext ) p = p->pNext; + return p; +} + +/* +** Given 1 to 3 identifiers preceding the JOIN keyword, determine the +** type of join. Return an integer constant that expresses that type +** in terms of the following bit values: +** +** JT_INNER +** JT_CROSS +** JT_OUTER +** JT_NATURAL +** JT_LEFT +** JT_RIGHT +** +** A full outer join is the combination of JT_LEFT and JT_RIGHT. +** +** If an illegal or unsupported join type is seen, then still return +** a join type, but put an error in the pParse structure. +** +** These are the valid join types: +** +** +** pA pB pC Return Value +** ------- ----- ----- ------------ +** CROSS - - JT_CROSS +** INNER - - JT_INNER +** LEFT - - JT_LEFT|JT_OUTER +** LEFT OUTER - JT_LEFT|JT_OUTER +** RIGHT - - JT_RIGHT|JT_OUTER +** RIGHT OUTER - JT_RIGHT|JT_OUTER +** FULL - - JT_LEFT|JT_RIGHT|JT_OUTER +** FULL OUTER - JT_LEFT|JT_RIGHT|JT_OUTER +** NATURAL INNER - JT_NATURAL|JT_INNER +** NATURAL LEFT - JT_NATURAL|JT_LEFT|JT_OUTER +** NATURAL LEFT OUTER JT_NATURAL|JT_LEFT|JT_OUTER +** NATURAL RIGHT - JT_NATURAL|JT_RIGHT|JT_OUTER +** NATURAL RIGHT OUTER JT_NATURAL|JT_RIGHT|JT_OUTER +** NATURAL FULL - JT_NATURAL|JT_LEFT|JT_RIGHT +** NATURAL FULL OUTER JT_NATRUAL|JT_LEFT|JT_RIGHT +** +** To preserve historical compatibly, SQLite also accepts a variety +** of other non-standard and in many cases nonsensical join types. +** This routine makes as much sense at it can from the nonsense join +** type and returns a result. Examples of accepted nonsense join types +** include but are not limited to: +** +** INNER CROSS JOIN -> same as JOIN +** NATURAL CROSS JOIN -> same as NATURAL JOIN +** OUTER LEFT JOIN -> same as LEFT JOIN +** LEFT NATURAL JOIN -> same as NATURAL LEFT JOIN +** LEFT RIGHT JOIN -> same as FULL JOIN +** RIGHT OUTER FULL JOIN -> same as FULL JOIN +** CROSS CROSS CROSS JOIN -> same as JOIN +** +** The only restrictions on the join type name are: +** +** * "INNER" cannot appear together with "OUTER", "LEFT", "RIGHT", +** or "FULL". +** +** * "CROSS" cannot appear together with "OUTER", "LEFT", "RIGHT, +** or "FULL". +** +** * If "OUTER" is present then there must also be one of +** "LEFT", "RIGHT", or "FULL" +*/ +SQLITE_PRIVATE int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){ + int jointype = 0; + Token *apAll[3]; + Token *p; + /* 0123456789 123456789 123456789 123 */ + static const char zKeyText[] = "naturaleftouterightfullinnercross"; + static const struct { + u8 i; /* Beginning of keyword text in zKeyText[] */ + u8 nChar; /* Length of the keyword in characters */ + u8 code; /* Join type mask */ + } aKeyword[] = { + /* (0) natural */ { 0, 7, JT_NATURAL }, + /* (1) left */ { 6, 4, JT_LEFT|JT_OUTER }, + /* (2) outer */ { 10, 5, JT_OUTER }, + /* (3) right */ { 14, 5, JT_RIGHT|JT_OUTER }, + /* (4) full */ { 19, 4, JT_LEFT|JT_RIGHT|JT_OUTER }, + /* (5) inner */ { 23, 5, JT_INNER }, + /* (6) cross */ { 28, 5, JT_INNER|JT_CROSS }, + }; + int i, j; + apAll[0] = pA; + apAll[1] = pB; + apAll[2] = pC; + for(i=0; i<3 && apAll[i]; i++){ + p = apAll[i]; + for(j=0; jn==aKeyword[j].nChar + && sqlite3StrNICmp((char*)p->z, &zKeyText[aKeyword[j].i], p->n)==0 ){ + jointype |= aKeyword[j].code; + break; + } + } + testcase( j==0 || j==1 || j==2 || j==3 || j==4 || j==5 || j==6 ); + if( j>=ArraySize(aKeyword) ){ + jointype |= JT_ERROR; + break; + } + } + if( + (jointype & (JT_INNER|JT_OUTER))==(JT_INNER|JT_OUTER) || + (jointype & JT_ERROR)!=0 || + (jointype & (JT_OUTER|JT_LEFT|JT_RIGHT))==JT_OUTER + ){ + const char *zSp1 = " "; + const char *zSp2 = " "; + if( pB==0 ){ zSp1++; } + if( pC==0 ){ zSp2++; } + sqlite3ErrorMsg(pParse, "unknown join type: " + "%T%s%T%s%T", pA, zSp1, pB, zSp2, pC); + jointype = JT_INNER; + } + return jointype; +} + +/* +** Return the index of a column in a table. Return -1 if the column +** is not contained in the table. +*/ +SQLITE_PRIVATE int sqlite3ColumnIndex(Table *pTab, const char *zCol){ + int i; + u8 h; + const Column *aCol; + int nCol; + + h = sqlite3StrIHash(zCol); + aCol = pTab->aCol; + nCol = pTab->nCol; + + /* See if the aHx gives us a lucky match */ + i = pTab->aHx[h % sizeof(pTab->aHx)]; + assert( i=nCol ) break; + } + return -1; +} + +/* +** Mark a subquery result column as having been used. +*/ +SQLITE_PRIVATE void sqlite3SrcItemColumnUsed(SrcItem *pItem, int iCol){ + assert( pItem!=0 ); + assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem) ); + if( pItem->fg.isNestedFrom ){ + ExprList *pResults; + assert( pItem->fg.isSubquery ); + assert( pItem->u4.pSubq!=0 ); + assert( pItem->u4.pSubq->pSelect!=0 ); + pResults = pItem->u4.pSubq->pSelect->pEList; + assert( pResults!=0 ); + assert( iCol>=0 && iColnExpr ); + pResults->a[iCol].fg.bUsed = 1; + } +} + +/* +** Search the tables iStart..iEnd (inclusive) in pSrc, looking for a +** table that has a column named zCol. The search is left-to-right. +** The first match found is returned. +** +** When found, set *piTab and *piCol to the table index and column index +** of the matching column and return TRUE. +** +** If not found, return FALSE. +*/ +static int tableAndColumnIndex( + SrcList *pSrc, /* Array of tables to search */ + int iStart, /* First member of pSrc->a[] to check */ + int iEnd, /* Last member of pSrc->a[] to check */ + const char *zCol, /* Name of the column we are looking for */ + int *piTab, /* Write index of pSrc->a[] here */ + int *piCol, /* Write index of pSrc->a[*piTab].pSTab->aCol[] here */ + int bIgnoreHidden /* Ignore hidden columns */ +){ + int i; /* For looping over tables in pSrc */ + int iCol; /* Index of column matching zCol */ + + assert( iEndnSrc ); + assert( iStart>=0 ); + assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */ + + for(i=iStart; i<=iEnd; i++){ + iCol = sqlite3ColumnIndex(pSrc->a[i].pSTab, zCol); + if( iCol>=0 + && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pSTab->aCol[iCol])==0) + ){ + if( piTab ){ + sqlite3SrcItemColumnUsed(&pSrc->a[i], iCol); + *piTab = i; + *piCol = iCol; + } + return 1; + } + } + return 0; +} + +/* +** Set the EP_OuterON property on all terms of the given expression. +** And set the Expr.w.iJoin to iTable for every term in the +** expression. +** +** The EP_OuterON property is used on terms of an expression to tell +** the OUTER JOIN processing logic that this term is part of the +** join restriction specified in the ON or USING clause and not a part +** of the more general WHERE clause. These terms are moved over to the +** WHERE clause during join processing but we need to remember that they +** originated in the ON or USING clause. +** +** The Expr.w.iJoin tells the WHERE clause processing that the +** expression depends on table w.iJoin even if that table is not +** explicitly mentioned in the expression. That information is needed +** for cases like this: +** +** SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.b AND t1.x=5 +** +** The where clause needs to defer the handling of the t1.x=5 +** term until after the t2 loop of the join. In that way, a +** NULL t2 row will be inserted whenever t1.x!=5. If we do not +** defer the handling of t1.x=5, it will be processed immediately +** after the t1 loop and rows with t1.x!=5 will never appear in +** the output, which is incorrect. +*/ +SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr *p, int iTable, u32 joinFlag){ + assert( joinFlag==EP_OuterON || joinFlag==EP_InnerON ); + while( p ){ + ExprSetProperty(p, joinFlag); + assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); + ExprSetVVAProperty(p, EP_NoReduce); + p->w.iJoin = iTable; + if( ExprUseXList(p) ){ + if( p->x.pList ){ + int i; + for(i=0; ix.pList->nExpr; i++){ + sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable, joinFlag); + } + } + } + sqlite3SetJoinExpr(p->pLeft, iTable, joinFlag); + p = p->pRight; + } +} + +/* Undo the work of sqlite3SetJoinExpr(). This is used when a LEFT JOIN +** is simplified into an ordinary JOIN, and when an ON expression is +** "pushed down" into the WHERE clause of a subquery. +** +** Convert every term that is marked with EP_OuterON and w.iJoin==iTable into +** an ordinary term that omits the EP_OuterON mark. Or if iTable<0, then +** just clear every EP_OuterON and EP_InnerON mark from the expression tree. +** +** If nullable is true, that means that Expr p might evaluate to NULL even +** if it is a reference to a NOT NULL column. This can happen, for example, +** if the table that p references is on the left side of a RIGHT JOIN. +** If nullable is true, then take care to not remove the EP_CanBeNull bit. +** See forum thread https://sqlite.org/forum/forumpost/b40696f50145d21c +*/ +static void unsetJoinExpr(Expr *p, int iTable, int nullable){ + while( p ){ + if( iTable<0 || (ExprHasProperty(p, EP_OuterON) && p->w.iJoin==iTable) ){ + ExprClearProperty(p, EP_OuterON|EP_InnerON); + if( iTable>=0 ) ExprSetProperty(p, EP_InnerON); + } + if( p->op==TK_COLUMN && p->iTable==iTable && !nullable ){ + ExprClearProperty(p, EP_CanBeNull); + } + if( p->op==TK_FUNCTION ){ + assert( ExprUseXList(p) ); + assert( p->pLeft==0 ); + if( p->x.pList ){ + int i; + for(i=0; ix.pList->nExpr; i++){ + unsetJoinExpr(p->x.pList->a[i].pExpr, iTable, nullable); + } + } + } + unsetJoinExpr(p->pLeft, iTable, nullable); + p = p->pRight; + } +} + +/* +** This routine processes the join information for a SELECT statement. +** +** * A NATURAL join is converted into a USING join. After that, we +** do not need to be concerned with NATURAL joins and we only have +** think about USING joins. +** +** * ON and USING clauses result in extra terms being added to the +** WHERE clause to enforce the specified constraints. The extra +** WHERE clause terms will be tagged with EP_OuterON or +** EP_InnerON so that we know that they originated in ON/USING. +** +** The terms of a FROM clause are contained in the Select.pSrc structure. +** The left most table is the first entry in Select.pSrc. The right-most +** table is the last entry. The join operator is held in the entry to +** the right. Thus entry 1 contains the join operator for the join between +** entries 0 and 1. Any ON or USING clauses associated with the join are +** also attached to the right entry. +** +** This routine returns the number of errors encountered. +*/ +static int sqlite3ProcessJoin(Parse *pParse, Select *p){ + SrcList *pSrc; /* All tables in the FROM clause */ + int i, j; /* Loop counters */ + SrcItem *pLeft; /* Left table being joined */ + SrcItem *pRight; /* Right table being joined */ + + pSrc = p->pSrc; + pLeft = &pSrc->a[0]; + pRight = &pLeft[1]; + for(i=0; inSrc-1; i++, pRight++, pLeft++){ + Table *pRightTab = pRight->pSTab; + u32 joinType; + + if( NEVER(pLeft->pSTab==0 || pRightTab==0) ) continue; + joinType = (pRight->fg.jointype & JT_OUTER)!=0 ? EP_OuterON : EP_InnerON; + + /* If this is a NATURAL join, synthesize an appropriate USING clause + ** to specify which columns should be joined. + */ + if( pRight->fg.jointype & JT_NATURAL ){ + IdList *pUsing = 0; + if( pRight->fg.isUsing || pRight->u3.pOn ){ + sqlite3ErrorMsg(pParse, "a NATURAL join may not have " + "an ON or USING clause", 0); + return 1; + } + for(j=0; jnCol; j++){ + char *zName; /* Name of column in the right table */ + + if( IsHiddenColumn(&pRightTab->aCol[j]) ) continue; + zName = pRightTab->aCol[j].zCnName; + if( tableAndColumnIndex(pSrc, 0, i, zName, 0, 0, 1) ){ + pUsing = sqlite3IdListAppend(pParse, pUsing, 0); + if( pUsing ){ + assert( pUsing->nId>0 ); + assert( pUsing->a[pUsing->nId-1].zName==0 ); + pUsing->a[pUsing->nId-1].zName = sqlite3DbStrDup(pParse->db, zName); + } + } + } + if( pUsing ){ + pRight->fg.isUsing = 1; + pRight->fg.isSynthUsing = 1; + pRight->u3.pUsing = pUsing; + } + if( pParse->nErr ) return 1; + } + + /* Create extra terms on the WHERE clause for each column named + ** in the USING clause. Example: If the two tables to be joined are + ** A and B and the USING clause names X, Y, and Z, then add this + ** to the WHERE clause: A.X=B.X AND A.Y=B.Y AND A.Z=B.Z + ** Report an error if any column mentioned in the USING clause is + ** not contained in both tables to be joined. + */ + if( pRight->fg.isUsing ){ + IdList *pList = pRight->u3.pUsing; + sqlite3 *db = pParse->db; + assert( pList!=0 ); + for(j=0; jnId; j++){ + char *zName; /* Name of the term in the USING clause */ + int iLeft; /* Table on the left with matching column name */ + int iLeftCol; /* Column number of matching column on the left */ + int iRightCol; /* Column number of matching column on the right */ + Expr *pE1; /* Reference to the column on the LEFT of the join */ + Expr *pE2; /* Reference to the column on the RIGHT of the join */ + Expr *pEq; /* Equality constraint. pE1 == pE2 */ + + zName = pList->a[j].zName; + iRightCol = sqlite3ColumnIndex(pRightTab, zName); + if( iRightCol<0 + || tableAndColumnIndex(pSrc, 0, i, zName, &iLeft, &iLeftCol, + pRight->fg.isSynthUsing)==0 + ){ + sqlite3ErrorMsg(pParse, "cannot join using column %s - column " + "not present in both tables", zName); + return 1; + } + pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol); + sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol); + if( (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 && pParse->nErr==0 ){ + /* This branch runs if the query contains one or more RIGHT or FULL + ** JOINs. If only a single table on the left side of this join + ** contains the zName column, then this branch is a no-op. + ** But if there are two or more tables on the left side + ** of the join, construct a coalesce() function that gathers all + ** such tables. Raise an error if more than one of those references + ** to zName is not also within a prior USING clause. + ** + ** We really ought to raise an error if there are two or more + ** non-USING references to zName on the left of an INNER or LEFT + ** JOIN. But older versions of SQLite do not do that, so we avoid + ** adding a new error so as to not break legacy applications. + */ + ExprList *pFuncArgs = 0; /* Arguments to the coalesce() */ + static const Token tkCoalesce = { "coalesce", 8 }; + assert( pE1!=0 ); + ExprSetProperty(pE1, EP_CanBeNull); + while( tableAndColumnIndex(pSrc, iLeft+1, i, zName, &iLeft, &iLeftCol, + pRight->fg.isSynthUsing)!=0 ){ + if( pSrc->a[iLeft].fg.isUsing==0 + || sqlite3IdListIndex(pSrc->a[iLeft].u3.pUsing, zName)<0 + ){ + sqlite3ErrorMsg(pParse, "ambiguous reference to %s in USING()", + zName); + break; + } + pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1); + pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol); + sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol); + } + if( pFuncArgs ){ + pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1); + pE1 = sqlite3ExprFunction(pParse, pFuncArgs, &tkCoalesce, 0); + if( pE1 ){ + pE1->affExpr = SQLITE_AFF_DEFER; + } + } + }else if( (pSrc->a[i+1].fg.jointype & JT_LEFT)!=0 && pParse->nErr==0 ){ + assert( pE1!=0 ); + ExprSetProperty(pE1, EP_CanBeNull); + } + pE2 = sqlite3CreateColumnExpr(db, pSrc, i+1, iRightCol); + sqlite3SrcItemColumnUsed(pRight, iRightCol); + pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2); + assert( pE2!=0 || pEq==0 ); + if( pEq ){ + ExprSetProperty(pEq, joinType); + assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) ); + ExprSetVVAProperty(pEq, EP_NoReduce); + pEq->w.iJoin = pE2->iTable; + } + p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pEq); + } + } + + /* Add the ON clause to the end of the WHERE clause, connected by + ** an AND operator. + */ + else if( pRight->u3.pOn ){ + sqlite3SetJoinExpr(pRight->u3.pOn, pRight->iCursor, joinType); + p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->u3.pOn); + pRight->u3.pOn = 0; + pRight->fg.isOn = 1; + p->selFlags |= SF_OnToWhere; + } + + if( IsVirtual(pRightTab) && joinType==EP_OuterON && pRight->u1.pFuncArg ){ + p->selFlags |= SF_OnToWhere; + } + } + return 0; +} + +/* +** An instance of this object holds information (beyond pParse and pSelect) +** needed to load the next result row that is to be added to the sorter. +*/ +typedef struct RowLoadInfo RowLoadInfo; +struct RowLoadInfo { + int regResult; /* Store results in array of registers here */ + u8 ecelFlags; /* Flag argument to ExprCodeExprList() */ +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + ExprList *pExtra; /* Extra columns needed by sorter refs */ + int regExtraResult; /* Where to load the extra columns */ +#endif +}; + +/* +** This routine does the work of loading query data into an array of +** registers so that it can be added to the sorter. +*/ +static void innerLoopLoadRow( + Parse *pParse, /* Statement under construction */ + Select *pSelect, /* The query being coded */ + RowLoadInfo *pInfo /* Info needed to complete the row load */ +){ + sqlite3ExprCodeExprList(pParse, pSelect->pEList, pInfo->regResult, + 0, pInfo->ecelFlags); +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + if( pInfo->pExtra ){ + sqlite3ExprCodeExprList(pParse, pInfo->pExtra, pInfo->regExtraResult, 0, 0); + sqlite3ExprListDelete(pParse->db, pInfo->pExtra); + } +#endif +} + +/* +** Code the OP_MakeRecord instruction that generates the entry to be +** added into the sorter. +** +** Return the register in which the result is stored. +*/ +static int makeSorterRecord( + Parse *pParse, + SortCtx *pSort, + Select *pSelect, + int regBase, + int nBase +){ + int nOBSat = pSort->nOBSat; + Vdbe *v = pParse->pVdbe; + int regOut = ++pParse->nMem; + if( pSort->pDeferredRowLoad ){ + innerLoopLoadRow(pParse, pSelect, pSort->pDeferredRowLoad); + } + sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regOut); + return regOut; +} + +/* +** Generate code that will push the record in registers regData +** through regData+nData-1 onto the sorter. +*/ +static void pushOntoSorter( + Parse *pParse, /* Parser context */ + SortCtx *pSort, /* Information about the ORDER BY clause */ + Select *pSelect, /* The whole SELECT statement */ + int regData, /* First register holding data to be sorted */ + int regOrigData, /* First register holding data before packing */ + int nData, /* Number of elements in the regData data array */ + int nPrefixReg /* No. of reg prior to regData available for use */ +){ + Vdbe *v = pParse->pVdbe; /* Stmt under construction */ + int bSeq = ((pSort->sortFlags & SORTFLAG_UseSorter)==0); + int nExpr = pSort->pOrderBy->nExpr; /* No. of ORDER BY terms */ + int nBase = nExpr + bSeq + nData; /* Fields in sorter record */ + int regBase; /* Regs for sorter record */ + int regRecord = 0; /* Assembled sorter record */ + int nOBSat = pSort->nOBSat; /* ORDER BY terms to skip */ + int op; /* Opcode to add sorter record to sorter */ + int iLimit; /* LIMIT counter */ + int iSkip = 0; /* End of the sorter insert loop */ + + assert( bSeq==0 || bSeq==1 ); + + /* Three cases: + ** (1) The data to be sorted has already been packed into a Record + ** by a prior OP_MakeRecord. In this case nData==1 and regData + ** will be completely unrelated to regOrigData. + ** (2) All output columns are included in the sort record. In that + ** case regData==regOrigData. + ** (3) Some output columns are omitted from the sort record due to + ** the SQLITE_ENABLE_SORTER_REFERENCES optimization, or due to the + ** SQLITE_ECEL_OMITREF optimization, or due to the + ** SortCtx.pDeferredRowLoad optimization. In any of these cases + ** regOrigData is 0 to prevent this routine from trying to copy + ** values that might not yet exist. + */ + assert( nData==1 || regData==regOrigData || regOrigData==0 ); + +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + pSort->addrPush = sqlite3VdbeCurrentAddr(v); +#endif + + if( nPrefixReg ){ + assert( nPrefixReg==nExpr+bSeq ); + regBase = regData - nPrefixReg; + }else{ + regBase = pParse->nMem + 1; + pParse->nMem += nBase; + } + assert( pSelect->iOffset==0 || pSelect->iLimit!=0 ); + iLimit = pSelect->iOffset ? pSelect->iOffset+1 : pSelect->iLimit; + pSort->labelDone = sqlite3VdbeMakeLabel(pParse); + sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, regOrigData, + SQLITE_ECEL_DUP | (regOrigData? SQLITE_ECEL_REF : 0)); + if( bSeq ){ + sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr); + } + if( nPrefixReg==0 && nData>0 ){ + sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+bSeq, nData); + } + if( nOBSat>0 ){ + int regPrevKey; /* The first nOBSat columns of the previous row */ + int addrFirst; /* Address of the OP_IfNot opcode */ + int addrJmp; /* Address of the OP_Jump opcode */ + VdbeOp *pOp; /* Opcode that opens the sorter */ + int nKey; /* Number of sorting key columns, including OP_Sequence */ + KeyInfo *pKI; /* Original KeyInfo on the sorter table */ + + regRecord = makeSorterRecord(pParse, pSort, pSelect, regBase, nBase); + regPrevKey = pParse->nMem+1; + pParse->nMem += pSort->nOBSat; + nKey = nExpr - pSort->nOBSat + bSeq; + if( bSeq ){ + addrFirst = sqlite3VdbeAddOp1(v, OP_IfNot, regBase+nExpr); + }else{ + addrFirst = sqlite3VdbeAddOp1(v, OP_SequenceTest, pSort->iECursor); + } + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_Compare, regPrevKey, regBase, pSort->nOBSat); + pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex); + if( pParse->db->mallocFailed ) return; + pOp->p2 = nKey + nData; + pKI = pOp->p4.pKeyInfo; + memset(pKI->aSortFlags, 0, pKI->nKeyField); /* Makes OP_Jump testable */ + sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO); + testcase( pKI->nAllField > pKI->nKeyField+2 ); + pOp->p4.pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pSort->pOrderBy,nOBSat, + pKI->nAllField-pKI->nKeyField-1); + pOp = 0; /* Ensure pOp not used after sqlite3VdbeAddOp3() */ + addrJmp = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v); + pSort->labelBkOut = sqlite3VdbeMakeLabel(pParse); + pSort->regReturn = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut); + sqlite3VdbeAddOp1(v, OP_ResetSorter, pSort->iECursor); + if( iLimit ){ + sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, pSort->labelDone); + VdbeCoverage(v); + } + sqlite3VdbeJumpHere(v, addrFirst); + sqlite3ExprCodeMove(pParse, regBase, regPrevKey, pSort->nOBSat); + sqlite3VdbeJumpHere(v, addrJmp); + } + if( iLimit ){ + /* At this point the values for the new sorter entry are stored + ** in an array of registers. They need to be composed into a record + ** and inserted into the sorter if either (a) there are currently + ** less than LIMIT+OFFSET items or (b) the new record is smaller than + ** the largest record currently in the sorter. If (b) is true and there + ** are already LIMIT+OFFSET items in the sorter, delete the largest + ** entry before inserting the new one. This way there are never more + ** than LIMIT+OFFSET items in the sorter. + ** + ** If the new record does not need to be inserted into the sorter, + ** jump to the next iteration of the loop. If the pSort->labelOBLopt + ** value is not zero, then it is a label of where to jump. Otherwise, + ** just bypass the row insert logic. See the header comment on the + ** sqlite3WhereOrderByLimitOptLabel() function for additional info. + */ + int iCsr = pSort->iECursor; + sqlite3VdbeAddOp2(v, OP_IfNotZero, iLimit, sqlite3VdbeCurrentAddr(v)+4); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Last, iCsr, 0); + iSkip = sqlite3VdbeAddOp4Int(v, OP_IdxLE, + iCsr, 0, regBase+nOBSat, nExpr-nOBSat); + VdbeCoverage(v); + sqlite3VdbeAddOp1(v, OP_Delete, iCsr); + } + if( regRecord==0 ){ + regRecord = makeSorterRecord(pParse, pSort, pSelect, regBase, nBase); + } + if( pSort->sortFlags & SORTFLAG_UseSorter ){ + op = OP_SorterInsert; + }else{ + op = OP_IdxInsert; + } + sqlite3VdbeAddOp4Int(v, op, pSort->iECursor, regRecord, + regBase+nOBSat, nBase-nOBSat); + if( iSkip ){ + sqlite3VdbeChangeP2(v, iSkip, + pSort->labelOBLopt ? pSort->labelOBLopt : sqlite3VdbeCurrentAddr(v)); + } +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + pSort->addrPushEnd = sqlite3VdbeCurrentAddr(v)-1; +#endif +} + +/* +** Add code to implement the OFFSET +*/ +static void codeOffset( + Vdbe *v, /* Generate code into this VM */ + int iOffset, /* Register holding the offset counter */ + int iContinue /* Jump here to skip the current record */ +){ + if( iOffset>0 ){ + sqlite3VdbeAddOp3(v, OP_IfPos, iOffset, iContinue, 1); VdbeCoverage(v); + VdbeComment((v, "OFFSET")); + } +} + +/* +** Add code that will check to make sure the array of registers starting at +** iMem form a distinct entry. This is used by both "SELECT DISTINCT ..." and +** distinct aggregates ("SELECT count(DISTINCT ) ..."). Three strategies +** are available. Which is used depends on the value of parameter eTnctType, +** as follows: +** +** WHERE_DISTINCT_UNORDERED/WHERE_DISTINCT_NOOP: +** Build an ephemeral table that contains all entries seen before and +** skip entries which have been seen before. +** +** Parameter iTab is the cursor number of an ephemeral table that must +** be opened before the VM code generated by this routine is executed. +** The ephemeral cursor table is queried for a record identical to the +** record formed by the current array of registers. If one is found, +** jump to VM address addrRepeat. Otherwise, insert a new record into +** the ephemeral cursor and proceed. +** +** The returned value in this case is a copy of parameter iTab. +** +** WHERE_DISTINCT_ORDERED: +** In this case rows are being delivered sorted order. The ephemeral +** table is not required. Instead, the current set of values +** is compared against previous row. If they match, the new row +** is not distinct and control jumps to VM address addrRepeat. Otherwise, +** the VM program proceeds with processing the new row. +** +** The returned value in this case is the register number of the first +** in an array of registers used to store the previous result row so that +** it can be compared to the next. The caller must ensure that this +** register is initialized to NULL. (The fixDistinctOpenEph() routine +** will take care of this initialization.) +** +** WHERE_DISTINCT_UNIQUE: +** In this case it has already been determined that the rows are distinct. +** No special action is required. The return value is zero. +** +** Parameter pEList is the list of expressions used to generated the +** contents of each row. It is used by this routine to determine (a) +** how many elements there are in the array of registers and (b) the +** collation sequences that should be used for the comparisons if +** eTnctType is WHERE_DISTINCT_ORDERED. +*/ +static int codeDistinct( + Parse *pParse, /* Parsing and code generating context */ + int eTnctType, /* WHERE_DISTINCT_* value */ + int iTab, /* A sorting index used to test for distinctness */ + int addrRepeat, /* Jump to here if not distinct */ + ExprList *pEList, /* Expression for each element */ + int regElem /* First element */ +){ + int iRet = 0; + int nResultCol = pEList->nExpr; + Vdbe *v = pParse->pVdbe; + + switch( eTnctType ){ + case WHERE_DISTINCT_ORDERED: { + int i; + int iJump; /* Jump destination */ + int regPrev; /* Previous row content */ + + /* Allocate space for the previous row */ + iRet = regPrev = pParse->nMem+1; + pParse->nMem += nResultCol; + + iJump = sqlite3VdbeCurrentAddr(v) + nResultCol; + for(i=0; ia[i].pExpr); + if( idb->mallocFailed ); + sqlite3VdbeAddOp3(v, OP_Copy, regElem, regPrev, nResultCol-1); + break; + } + + case WHERE_DISTINCT_UNIQUE: { + /* nothing to do */ + break; + } + + default: { + int r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, regElem, nResultCol); + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regElem, nResultCol, r1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r1, regElem, nResultCol); + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + sqlite3ReleaseTempReg(pParse, r1); + iRet = iTab; + break; + } + } + + return iRet; +} + +/* +** This routine runs after codeDistinct(). It makes necessary +** adjustments to the OP_OpenEphemeral opcode that the codeDistinct() +** routine made use of. This processing must be done separately since +** sometimes codeDistinct is called before the OP_OpenEphemeral is actually +** laid down. +** +** WHERE_DISTINCT_NOOP: +** WHERE_DISTINCT_UNORDERED: +** +** No adjustments necessary. This function is a no-op. +** +** WHERE_DISTINCT_UNIQUE: +** +** The ephemeral table is not needed. So change the +** OP_OpenEphemeral opcode into an OP_Noop. +** +** WHERE_DISTINCT_ORDERED: +** +** The ephemeral table is not needed. But we do need register +** iVal to be initialized to NULL. So change the OP_OpenEphemeral +** into an OP_Null on the iVal register. +*/ +static void fixDistinctOpenEph( + Parse *pParse, /* Parsing and code generating context */ + int eTnctType, /* WHERE_DISTINCT_* value */ + int iVal, /* Value returned by codeDistinct() */ + int iOpenEphAddr /* Address of OP_OpenEphemeral instruction for iTab */ +){ + if( pParse->nErr==0 + && (eTnctType==WHERE_DISTINCT_UNIQUE || eTnctType==WHERE_DISTINCT_ORDERED) + ){ + Vdbe *v = pParse->pVdbe; + sqlite3VdbeChangeToNoop(v, iOpenEphAddr); + if( sqlite3VdbeGetOp(v, iOpenEphAddr+1)->opcode==OP_Explain ){ + sqlite3VdbeChangeToNoop(v, iOpenEphAddr+1); + } + if( eTnctType==WHERE_DISTINCT_ORDERED ){ + /* Change the OP_OpenEphemeral to an OP_Null that sets the MEM_Cleared + ** bit on the first register of the previous value. This will cause the + ** OP_Ne added in codeDistinct() to always fail on the first iteration of + ** the loop even if the first row is all NULLs. */ + VdbeOp *pOp = sqlite3VdbeGetOp(v, iOpenEphAddr); + pOp->opcode = OP_Null; + pOp->p1 = 1; + pOp->p2 = iVal; + } + } +} + +#ifdef SQLITE_ENABLE_SORTER_REFERENCES +/* +** This function is called as part of inner-loop generation for a SELECT +** statement with an ORDER BY that is not optimized by an index. It +** determines the expressions, if any, that the sorter-reference +** optimization should be used for. The sorter-reference optimization +** is used for SELECT queries like: +** +** SELECT a, bigblob FROM t1 ORDER BY a LIMIT 10 +** +** If the optimization is used for expression "bigblob", then instead of +** storing values read from that column in the sorter records, the PK of +** the row from table t1 is stored instead. Then, as records are extracted from +** the sorter to return to the user, the required value of bigblob is +** retrieved directly from table t1. If the values are very large, this +** can be more efficient than storing them directly in the sorter records. +** +** The ExprList_item.fg.bSorterRef flag is set for each expression in pEList +** for which the sorter-reference optimization should be enabled. +** Additionally, the pSort->aDefer[] array is populated with entries +** for all cursors required to evaluate all selected expressions. Finally. +** output variable (*ppExtra) is set to an expression list containing +** expressions for all extra PK values that should be stored in the +** sorter records. +*/ +static void selectExprDefer( + Parse *pParse, /* Leave any error here */ + SortCtx *pSort, /* Sorter context */ + ExprList *pEList, /* Expressions destined for sorter */ + ExprList **ppExtra /* Expressions to append to sorter record */ +){ + int i; + int nDefer = 0; + ExprList *pExtra = 0; + for(i=0; inExpr; i++){ + struct ExprList_item *pItem = &pEList->a[i]; + if( pItem->u.x.iOrderByCol==0 ){ + Expr *pExpr = pItem->pExpr; + Table *pTab; + if( pExpr->op==TK_COLUMN + && pExpr->iColumn>=0 + && ALWAYS( ExprUseYTab(pExpr) ) + && (pTab = pExpr->y.pTab)!=0 + && IsOrdinaryTable(pTab) + && (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF)!=0 + ){ + int j; + for(j=0; jaDefer[j].iCsr==pExpr->iTable ) break; + } + if( j==nDefer ){ + if( nDefer==ArraySize(pSort->aDefer) ){ + continue; + }else{ + int nKey = 1; + int k; + Index *pPk = 0; + if( !HasRowid(pTab) ){ + pPk = sqlite3PrimaryKeyIndex(pTab); + nKey = pPk->nKeyCol; + } + for(k=0; kiTable = pExpr->iTable; + assert( ExprUseYTab(pNew) ); + pNew->y.pTab = pExpr->y.pTab; + pNew->iColumn = pPk ? pPk->aiColumn[k] : -1; + pExtra = sqlite3ExprListAppend(pParse, pExtra, pNew); + } + } + pSort->aDefer[nDefer].pTab = pExpr->y.pTab; + pSort->aDefer[nDefer].iCsr = pExpr->iTable; + pSort->aDefer[nDefer].nKey = nKey; + nDefer++; + } + } + pItem->fg.bSorterRef = 1; + } + } + } + pSort->nDefer = (u8)nDefer; + *ppExtra = pExtra; +} +#endif + +/* +** This routine generates the code for the inside of the inner loop +** of a SELECT. +** +** If srcTab is negative, then the p->pEList expressions +** are evaluated in order to get the data for this row. If srcTab is +** zero or more, then data is pulled from srcTab and p->pEList is used only +** to get the number of columns and the collation sequence for each column. +*/ +static void selectInnerLoop( + Parse *pParse, /* The parser context */ + Select *p, /* The complete select statement being coded */ + int srcTab, /* Pull data from this table if non-negative */ + SortCtx *pSort, /* If not NULL, info on how to process ORDER BY */ + DistinctCtx *pDistinct, /* If not NULL, info on how to process DISTINCT */ + SelectDest *pDest, /* How to dispose of the results */ + int iContinue, /* Jump here to continue with next row */ + int iBreak /* Jump here to break out of the inner loop */ +){ + Vdbe *v = pParse->pVdbe; + int i; + int hasDistinct; /* True if the DISTINCT keyword is present */ + int eDest = pDest->eDest; /* How to dispose of results */ + int iParm = pDest->iSDParm; /* First argument to disposal method */ + int nResultCol; /* Number of result columns */ + int nPrefixReg = 0; /* Number of extra registers before regResult */ + RowLoadInfo sRowLoadInfo; /* Info for deferred row loading */ + + /* Usually, regResult is the first cell in an array of memory cells + ** containing the current result row. In this case regOrig is set to the + ** same value. However, if the results are being sent to the sorter, the + ** values for any expressions that are also part of the sort-key are omitted + ** from this array. In this case regOrig is set to zero. */ + int regResult; /* Start of memory holding current results */ + int regOrig; /* Start of memory holding full result (or 0) */ + + assert( v ); + assert( p->pEList!=0 ); + hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP; + if( pSort && pSort->pOrderBy==0 ) pSort = 0; + if( pSort==0 && !hasDistinct ){ + assert( iContinue!=0 ); + codeOffset(v, p->iOffset, iContinue); + } + + /* Pull the requested columns. + */ + nResultCol = p->pEList->nExpr; + + if( pDest->iSdst==0 ){ + if( pSort ){ + nPrefixReg = pSort->pOrderBy->nExpr; + if( !(pSort->sortFlags & SORTFLAG_UseSorter) ) nPrefixReg++; + pParse->nMem += nPrefixReg; + } + pDest->iSdst = pParse->nMem+1; + pParse->nMem += nResultCol; + }else if( pDest->iSdst+nResultCol > pParse->nMem ){ + /* This is an error condition that can result, for example, when a SELECT + ** on the right-hand side of an INSERT contains more result columns than + ** there are columns in the table on the left. The error will be caught + ** and reported later. But we need to make sure enough memory is allocated + ** to avoid other spurious errors in the meantime. */ + pParse->nMem += nResultCol; + } + pDest->nSdst = nResultCol; + regOrig = regResult = pDest->iSdst; + if( srcTab>=0 ){ + for(i=0; ipEList->a[i].zEName)); + } + }else if( eDest!=SRT_Exists ){ +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + ExprList *pExtra = 0; +#endif + /* If the destination is an EXISTS(...) expression, the actual + ** values returned by the SELECT are not required. + */ + u8 ecelFlags; /* "ecel" is an abbreviation of "ExprCodeExprList" */ + ExprList *pEList; + if( eDest==SRT_Mem || eDest==SRT_Output || eDest==SRT_Coroutine ){ + ecelFlags = SQLITE_ECEL_DUP; + }else{ + ecelFlags = 0; + } + if( pSort && hasDistinct==0 && eDest!=SRT_EphemTab && eDest!=SRT_Table ){ + /* For each expression in p->pEList that is a copy of an expression in + ** the ORDER BY clause (pSort->pOrderBy), set the associated + ** iOrderByCol value to one more than the index of the ORDER BY + ** expression within the sort-key that pushOntoSorter() will generate. + ** This allows the p->pEList field to be omitted from the sorted record, + ** saving space and CPU cycles. */ + ecelFlags |= (SQLITE_ECEL_OMITREF|SQLITE_ECEL_REF); + + for(i=pSort->nOBSat; ipOrderBy->nExpr; i++){ + int j; + if( (j = pSort->pOrderBy->a[i].u.x.iOrderByCol)>0 ){ + p->pEList->a[j-1].u.x.iOrderByCol = i+1-pSort->nOBSat; + } + } +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + selectExprDefer(pParse, pSort, p->pEList, &pExtra); + if( pExtra && pParse->db->mallocFailed==0 ){ + /* If there are any extra PK columns to add to the sorter records, + ** allocate extra memory cells and adjust the OpenEphemeral + ** instruction to account for the larger records. This is only + ** required if there are one or more WITHOUT ROWID tables with + ** composite primary keys in the SortCtx.aDefer[] array. */ + VdbeOp *pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex); + pOp->p2 += (pExtra->nExpr - pSort->nDefer); + pOp->p4.pKeyInfo->nAllField += (pExtra->nExpr - pSort->nDefer); + pParse->nMem += pExtra->nExpr; + } +#endif + + /* Adjust nResultCol to account for columns that are omitted + ** from the sorter by the optimizations in this branch */ + pEList = p->pEList; + for(i=0; inExpr; i++){ + if( pEList->a[i].u.x.iOrderByCol>0 +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + || pEList->a[i].fg.bSorterRef +#endif + ){ + nResultCol--; + regOrig = 0; + } + } + + testcase( regOrig ); + testcase( eDest==SRT_Set ); + testcase( eDest==SRT_Mem ); + testcase( eDest==SRT_Coroutine ); + testcase( eDest==SRT_Output ); + assert( eDest==SRT_Set || eDest==SRT_Mem + || eDest==SRT_Coroutine || eDest==SRT_Output + || eDest==SRT_Upfrom ); + } + sRowLoadInfo.regResult = regResult; + sRowLoadInfo.ecelFlags = ecelFlags; +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + sRowLoadInfo.pExtra = pExtra; + sRowLoadInfo.regExtraResult = regResult + nResultCol; + if( pExtra ) nResultCol += pExtra->nExpr; +#endif + if( p->iLimit + && (ecelFlags & SQLITE_ECEL_OMITREF)!=0 + && nPrefixReg>0 + ){ + assert( pSort!=0 ); + assert( hasDistinct==0 ); + pSort->pDeferredRowLoad = &sRowLoadInfo; + regOrig = 0; + }else{ + innerLoopLoadRow(pParse, p, &sRowLoadInfo); + } + } + + /* If the DISTINCT keyword was present on the SELECT statement + ** and this row has been seen before, then do not make this row + ** part of the result. + */ + if( hasDistinct ){ + int eType = pDistinct->eTnctType; + int iTab = pDistinct->tabTnct; + assert( nResultCol==p->pEList->nExpr ); + iTab = codeDistinct(pParse, eType, iTab, iContinue, p->pEList, regResult); + fixDistinctOpenEph(pParse, eType, iTab, pDistinct->addrTnct); + if( pSort==0 ){ + codeOffset(v, p->iOffset, iContinue); + } + } + + switch( eDest ){ + /* Store the result as data using a unique key. + */ + case SRT_Fifo: + case SRT_DistFifo: + case SRT_Table: + case SRT_EphemTab: { + int r1 = sqlite3GetTempRange(pParse, nPrefixReg+1); + testcase( eDest==SRT_Table ); + testcase( eDest==SRT_EphemTab ); + testcase( eDest==SRT_Fifo ); + testcase( eDest==SRT_DistFifo ); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1+nPrefixReg); +#if !defined(SQLITE_ENABLE_NULL_TRIM) && defined(SQLITE_DEBUG) + /* A destination of SRT_Table and a non-zero iSDParm2 parameter means + ** that this is an "UPDATE ... FROM" on a virtual table or view. In this + ** case set the p5 parameter of the OP_MakeRecord to OPFLAG_NOCHNG_MAGIC. + ** This does not affect operation in any way - it just allows MakeRecord + ** to process OPFLAG_NOCHANGE values without an assert() failing. */ + if( eDest==SRT_Table && pDest->iSDParm2 ){ + sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG_MAGIC); + } +#endif +#ifndef SQLITE_OMIT_CTE + if( eDest==SRT_DistFifo ){ + /* If the destination is DistFifo, then cursor (iParm+1) is open + ** on an ephemeral index. If the current row is already present + ** in the index, do not write it to the output. If not, add the + ** current row to the index and proceed with writing it to the + ** output table as well. */ + int addr = sqlite3VdbeCurrentAddr(v) + 4; + sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, addr, r1, 0); + VdbeCoverage(v); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm+1, r1,regResult,nResultCol); + assert( pSort==0 ); + } +#endif + if( pSort ){ + assert( regResult==regOrig ); + pushOntoSorter(pParse, pSort, p, r1+nPrefixReg, regOrig, 1, nPrefixReg); + }else{ + int r2 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2); + sqlite3VdbeAddOp3(v, OP_Insert, iParm, r1, r2); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + sqlite3ReleaseTempReg(pParse, r2); + } + sqlite3ReleaseTempRange(pParse, r1, nPrefixReg+1); + break; + } + + case SRT_Upfrom: { + if( pSort ){ + pushOntoSorter( + pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg); + }else{ + int i2 = pDest->iSDParm2; + int r1 = sqlite3GetTempReg(pParse); + + /* If the UPDATE FROM join is an aggregate that matches no rows, it + ** might still be trying to return one row, because that is what + ** aggregates do. Don't record that empty row in the output table. */ + sqlite3VdbeAddOp2(v, OP_IsNull, regResult, iBreak); VdbeCoverage(v); + + sqlite3VdbeAddOp3(v, OP_MakeRecord, + regResult+(i2<0), nResultCol-(i2<0), r1); + if( i2<0 ){ + sqlite3VdbeAddOp3(v, OP_Insert, iParm, r1, regResult); + }else{ + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, i2); + } + } + break; + } + +#ifndef SQLITE_OMIT_SUBQUERY + /* If we are creating a set for an "expr IN (SELECT ...)" construct, + ** then there should be a single item on the stack. Write this + ** item into the set table with bogus data. + */ + case SRT_Set: { + if( pSort ){ + /* At first glance you would think we could optimize out the + ** ORDER BY in this case since the order of entries in the set + ** does not matter. But there might be a LIMIT clause, in which + ** case the order does matter */ + pushOntoSorter( + pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg); + pDest->iSDParm2 = 0; /* Signal that any Bloom filter is unpopulated */ + }else{ + int r1 = sqlite3GetTempReg(pParse); + assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol ); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol, + r1, pDest->zAffSdst, nResultCol); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol); + if( pDest->iSDParm2 ){ + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pDest->iSDParm2, 0, + regResult, nResultCol); + ExplainQueryPlan((pParse, 0, "CREATE BLOOM FILTER")); + } + sqlite3ReleaseTempReg(pParse, r1); + } + break; + } + + + /* If any row exist in the result set, record that fact and abort. + */ + case SRT_Exists: { + sqlite3VdbeAddOp2(v, OP_Integer, 1, iParm); + /* The LIMIT clause will terminate the loop for us */ + break; + } + + /* If this is a scalar select that is part of an expression, then + ** store the results in the appropriate memory cell or array of + ** memory cells and break out of the scan loop. + */ + case SRT_Mem: { + if( pSort ){ + assert( nResultCol<=pDest->nSdst ); + pushOntoSorter( + pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg); + pDest->iSDParm = regResult; + }else{ + assert( nResultCol==pDest->nSdst ); + if( regResult!=iParm ){ + /* This occurs in cases where the SELECT had both a DISTINCT and + ** an OFFSET clause. */ + sqlite3VdbeAddOp3(v, OP_Copy, regResult, iParm, nResultCol-1); + } + /* The LIMIT clause will jump out of the loop for us */ + } + break; + } +#endif /* #ifndef SQLITE_OMIT_SUBQUERY */ + + case SRT_Coroutine: /* Send data to a co-routine */ + case SRT_Output: { /* Return the results */ + testcase( eDest==SRT_Coroutine ); + testcase( eDest==SRT_Output ); + if( pSort ){ + pushOntoSorter(pParse, pSort, p, regResult, regOrig, nResultCol, + nPrefixReg); + }else if( eDest==SRT_Coroutine ){ + sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); + }else{ + sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nResultCol); + } + break; + } + +#ifndef SQLITE_OMIT_CTE + /* Write the results into a priority queue that is order according to + ** pDest->pOrderBy (in pSO). pDest->iSDParm (in iParm) is the cursor for an + ** index with pSO->nExpr+2 columns. Build a key using pSO for the first + ** pSO->nExpr columns, then make sure all keys are unique by adding a + ** final OP_Sequence column. The last column is the record as a blob. + */ + case SRT_DistQueue: + case SRT_Queue: { + int nKey; + int r1, r2, r3; + int addrTest = 0; + ExprList *pSO; + pSO = pDest->pOrderBy; + assert( pSO ); + nKey = pSO->nExpr; + r1 = sqlite3GetTempReg(pParse); + r2 = sqlite3GetTempRange(pParse, nKey+2); + r3 = r2+nKey+1; + if( eDest==SRT_DistQueue ){ + /* If the destination is DistQueue, then cursor (iParm+1) is open + ** on a second ephemeral index that holds all values every previously + ** added to the queue. */ + addrTest = sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, 0, + regResult, nResultCol); + VdbeCoverage(v); + } + sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r3); + if( eDest==SRT_DistQueue ){ + sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r3); + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + } + for(i=0; ia[i].u.x.iOrderByCol - 1, + r2+i); + } + sqlite3VdbeAddOp2(v, OP_Sequence, iParm, r2+nKey); + sqlite3VdbeAddOp3(v, OP_MakeRecord, r2, nKey+2, r1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, r2, nKey+2); + if( addrTest ) sqlite3VdbeJumpHere(v, addrTest); + sqlite3ReleaseTempReg(pParse, r1); + sqlite3ReleaseTempRange(pParse, r2, nKey+2); + break; + } +#endif /* SQLITE_OMIT_CTE */ + + + +#if !defined(SQLITE_OMIT_TRIGGER) + /* Discard the results. This is used for SELECT statements inside + ** the body of a TRIGGER. The purpose of such selects is to call + ** user-defined functions that have side effects. We do not care + ** about the actual results of the select. + */ + default: { + assert( eDest==SRT_Discard ); + break; + } +#endif + } + + /* Jump to the end of the loop if the LIMIT is reached. Except, if + ** there is a sorter, in which case the sorter has already limited + ** the output for us. + */ + if( pSort==0 && p->iLimit ){ + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v); + } +} + +/* +** Allocate a KeyInfo object sufficient for an index of N key columns and +** X extra columns. +*/ +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){ + int nExtra = (N+X)*(sizeof(CollSeq*)+1); + KeyInfo *p; + assert( X>=0 ); + if( NEVER(N+X>0xffff) ) return (KeyInfo*)sqlite3OomFault(db); + p = sqlite3DbMallocRawNN(db, SZ_KEYINFO(0) + nExtra); + if( p ){ + p->aSortFlags = (u8*)&p->aColl[N+X]; + p->nKeyField = (u16)N; + p->nAllField = (u16)(N+X); + p->enc = ENC(db); + p->db = db; + p->nRef = 1; + memset(p->aColl, 0, nExtra); + }else{ + return (KeyInfo*)sqlite3OomFault(db); + } + return p; +} + +/* +** Deallocate a KeyInfo object +*/ +SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo *p){ + if( p ){ + assert( p->db!=0 ); + assert( p->nRef>0 ); + p->nRef--; + if( p->nRef==0 ) sqlite3DbNNFreeNN(p->db, p); + } +} + +/* +** Make a new pointer to a KeyInfo object +*/ +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoRef(KeyInfo *p){ + if( p ){ + assert( p->nRef>0 ); + p->nRef++; + } + return p; +} + +#ifdef SQLITE_DEBUG +/* +** Return TRUE if a KeyInfo object can be change. The KeyInfo object +** can only be changed if this is just a single reference to the object. +** +** This routine is used only inside of assert() statements. +*/ +SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo *p){ return p->nRef==1; } +#endif /* SQLITE_DEBUG */ + +/* +** Given an expression list, generate a KeyInfo structure that records +** the collating sequence for each expression in that expression list. +** +** If the ExprList is an ORDER BY or GROUP BY clause then the resulting +** KeyInfo structure is appropriate for initializing a virtual index to +** implement that clause. If the ExprList is the result set of a SELECT +** then the KeyInfo structure is appropriate for initializing a virtual +** index to implement a DISTINCT test. +** +** Space to hold the KeyInfo structure is obtained from malloc. The calling +** function is responsible for seeing that this structure is eventually +** freed. +*/ +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoFromExprList( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* Form the KeyInfo object from this ExprList */ + int iStart, /* Begin with this column of pList */ + int nExtra /* Add this many extra columns to the end */ +){ + int nExpr; + KeyInfo *pInfo; + struct ExprList_item *pItem; + sqlite3 *db = pParse->db; + int i; + + nExpr = pList->nExpr; + pInfo = sqlite3KeyInfoAlloc(db, nExpr-iStart, nExtra+1); + if( pInfo ){ + assert( sqlite3KeyInfoIsWriteable(pInfo) ); + for(i=iStart, pItem=pList->a+iStart; iaColl[i-iStart] = sqlite3ExprNNCollSeq(pParse, pItem->pExpr); + pInfo->aSortFlags[i-iStart] = pItem->fg.sortFlags; + } + } + return pInfo; +} + +/* +** Name of the connection operator, used for error messages. +*/ +SQLITE_PRIVATE const char *sqlite3SelectOpName(int id){ + char *z; + switch( id ){ + case TK_ALL: z = "UNION ALL"; break; + case TK_INTERSECT: z = "INTERSECT"; break; + case TK_EXCEPT: z = "EXCEPT"; break; + default: z = "UNION"; break; + } + return z; +} + +#ifndef SQLITE_OMIT_EXPLAIN +/* +** Unless an "EXPLAIN QUERY PLAN" command is being processed, this function +** is a no-op. Otherwise, it adds a single row of output to the EQP result, +** where the caption is of the form: +** +** "USE TEMP B-TREE FOR xxx" +** +** where xxx is one of "DISTINCT", "ORDER BY" or "GROUP BY". Exactly which +** is determined by the zUsage argument. +*/ +static void explainTempTable(Parse *pParse, const char *zUsage){ + ExplainQueryPlan((pParse, 0, "USE TEMP B-TREE FOR %s", zUsage)); +} + +/* +** Assign expression b to lvalue a. A second, no-op, version of this macro +** is provided when SQLITE_OMIT_EXPLAIN is defined. This allows the code +** in sqlite3Select() to assign values to structure member variables that +** only exist if SQLITE_OMIT_EXPLAIN is not defined without polluting the +** code with #ifndef directives. +*/ +# define explainSetInteger(a, b) a = b + +#else +/* No-op versions of the explainXXX() functions and macros. */ +# define explainTempTable(y,z) +# define explainSetInteger(y,z) +#endif + + +/* +** If the inner loop was generated using a non-null pOrderBy argument, +** then the results were placed in a sorter. After the loop is terminated +** we need to run the sorter and output the results. The following +** routine generates the code needed to do that. +*/ +static void generateSortTail( + Parse *pParse, /* Parsing context */ + Select *p, /* The SELECT statement */ + SortCtx *pSort, /* Information on the ORDER BY clause */ + int nColumn, /* Number of columns of data */ + SelectDest *pDest /* Write the sorted results here */ +){ + Vdbe *v = pParse->pVdbe; /* The prepared statement */ + int addrBreak = pSort->labelDone; /* Jump here to exit loop */ + int addrContinue = sqlite3VdbeMakeLabel(pParse);/* Jump here for next cycle */ + int addr; /* Top of output loop. Jump for Next. */ + int addrOnce = 0; + int iTab; + ExprList *pOrderBy = pSort->pOrderBy; + int eDest = pDest->eDest; + int iParm = pDest->iSDParm; + int regRow; + int regRowid; + int iCol; + int nKey; /* Number of key columns in sorter record */ + int iSortTab; /* Sorter cursor to read from */ + int i; + int bSeq; /* True if sorter record includes seq. no. */ + int nRefKey = 0; + struct ExprList_item *aOutEx = p->pEList->a; +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + int addrExplain; /* Address of OP_Explain instruction */ +#endif + + nKey = pOrderBy->nExpr - pSort->nOBSat; + if( pSort->nOBSat==0 || nKey==1 ){ + ExplainQueryPlan2(addrExplain, (pParse, 0, + "USE TEMP B-TREE FOR %sORDER BY", pSort->nOBSat?"LAST TERM OF ":"" + )); + }else{ + ExplainQueryPlan2(addrExplain, (pParse, 0, + "USE TEMP B-TREE FOR LAST %d TERMS OF ORDER BY", nKey + )); + } + sqlite3VdbeScanStatusRange(v, addrExplain,pSort->addrPush,pSort->addrPushEnd); + sqlite3VdbeScanStatusCounters(v, addrExplain, addrExplain, pSort->addrPush); + + + assert( addrBreak<0 ); + if( pSort->labelBkOut ){ + sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut); + sqlite3VdbeGoto(v, addrBreak); + sqlite3VdbeResolveLabel(v, pSort->labelBkOut); + } + +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + /* Open any cursors needed for sorter-reference expressions */ + for(i=0; inDefer; i++){ + Table *pTab = pSort->aDefer[i].pTab; + int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + sqlite3OpenTable(pParse, pSort->aDefer[i].iCsr, iDb, pTab, OP_OpenRead); + nRefKey = MAX(nRefKey, pSort->aDefer[i].nKey); + } +#endif + + iTab = pSort->iECursor; + if( eDest==SRT_Output || eDest==SRT_Coroutine || eDest==SRT_Mem ){ + if( eDest==SRT_Mem && p->iOffset ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, pDest->iSdst); + } + regRowid = 0; + regRow = pDest->iSdst; + }else{ + regRowid = sqlite3GetTempReg(pParse); + if( eDest==SRT_EphemTab || eDest==SRT_Table ){ + regRow = sqlite3GetTempReg(pParse); + nColumn = 0; + }else{ + regRow = sqlite3GetTempRange(pParse, nColumn); + } + } + if( pSort->sortFlags & SORTFLAG_UseSorter ){ + int regSortOut = ++pParse->nMem; + iSortTab = pParse->nTab++; + if( pSort->labelBkOut ){ + addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + } + sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, + nKey+1+nColumn+nRefKey); + if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce); + addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak); + VdbeCoverage(v); + assert( p->iLimit==0 && p->iOffset==0 ); + sqlite3VdbeAddOp3(v, OP_SorterData, iTab, regSortOut, iSortTab); + bSeq = 0; + }else{ + addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v); + codeOffset(v, p->iOffset, addrContinue); + iSortTab = iTab; + bSeq = 1; + if( p->iOffset>0 ){ + sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1); + } + } + for(i=0, iCol=nKey+bSeq-1; inDefer ){ + int iKey = iCol+1; + int regKey = sqlite3GetTempRange(pParse, nRefKey); + + for(i=0; inDefer; i++){ + int iCsr = pSort->aDefer[i].iCsr; + Table *pTab = pSort->aDefer[i].pTab; + int nKey = pSort->aDefer[i].nKey; + + sqlite3VdbeAddOp1(v, OP_NullRow, iCsr); + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iKey++, regKey); + sqlite3VdbeAddOp3(v, OP_SeekRowid, iCsr, + sqlite3VdbeCurrentAddr(v)+1, regKey); + }else{ + int k; + int iJmp; + assert( sqlite3PrimaryKeyIndex(pTab)->nKeyCol==nKey ); + for(k=0; k=0; i--){ +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + if( aOutEx[i].fg.bSorterRef ){ + sqlite3ExprCode(pParse, aOutEx[i].pExpr, regRow+i); + }else +#endif + { + int iRead; + if( aOutEx[i].u.x.iOrderByCol ){ + iRead = aOutEx[i].u.x.iOrderByCol-1; + }else{ + iRead = iCol--; + } + sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iRead, regRow+i); + VdbeComment((v, "%s", aOutEx[i].zEName)); + } + } + sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1); + switch( eDest ){ + case SRT_Table: + case SRT_EphemTab: { + sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq, regRow); + sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid); + sqlite3VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + break; + } +#ifndef SQLITE_OMIT_SUBQUERY + case SRT_Set: { + assert( nColumn==sqlite3Strlen30(pDest->zAffSdst) ); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, nColumn, regRowid, + pDest->zAffSdst, nColumn); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, regRowid, regRow, nColumn); + break; + } + case SRT_Mem: { + /* The LIMIT clause will terminate the loop for us */ + break; + } +#endif + case SRT_Upfrom: { + int i2 = pDest->iSDParm2; + int r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_MakeRecord,regRow+(i2<0),nColumn-(i2<0),r1); + if( i2<0 ){ + sqlite3VdbeAddOp3(v, OP_Insert, iParm, r1, regRow); + }else{ + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regRow, i2); + } + break; + } + default: { + assert( eDest==SRT_Output || eDest==SRT_Coroutine ); + testcase( eDest==SRT_Output ); + testcase( eDest==SRT_Coroutine ); + if( eDest==SRT_Output ){ + sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iSdst, nColumn); + }else{ + sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); + } + break; + } + } + if( regRowid ){ + if( eDest==SRT_Set ){ + sqlite3ReleaseTempRange(pParse, regRow, nColumn); + }else{ + sqlite3ReleaseTempReg(pParse, regRow); + } + sqlite3ReleaseTempReg(pParse, regRowid); + } + /* The bottom of the loop + */ + sqlite3VdbeResolveLabel(v, addrContinue); + if( pSort->sortFlags & SORTFLAG_UseSorter ){ + sqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr); VdbeCoverage(v); + }else{ + sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); VdbeCoverage(v); + } + sqlite3VdbeScanStatusRange(v, addrExplain, sqlite3VdbeCurrentAddr(v)-1, -1); + if( pSort->regReturn ) sqlite3VdbeAddOp1(v, OP_Return, pSort->regReturn); + sqlite3VdbeResolveLabel(v, addrBreak); +} + +/* +** Return a pointer to a string containing the 'declaration type' of the +** expression pExpr. The string may be treated as static by the caller. +** +** The declaration type is the exact datatype definition extracted from the +** original CREATE TABLE statement if the expression is a column. The +** declaration type for a ROWID field is INTEGER. Exactly when an expression +** is considered a column can be complex in the presence of subqueries. The +** result-set expression in all of the following SELECT statements is +** considered a column by this function. +** +** SELECT col FROM tbl; +** SELECT (SELECT col FROM tbl; +** SELECT (SELECT col FROM tbl); +** SELECT abc FROM (SELECT col AS abc FROM tbl); +** +** The declaration type for any expression other than a column is NULL. +** +** This routine has either 3 or 6 parameters depending on whether or not +** the SQLITE_ENABLE_COLUMN_METADATA compile-time option is used. +*/ +#ifdef SQLITE_ENABLE_COLUMN_METADATA +# define columnType(A,B,C,D,E) columnTypeImpl(A,B,C,D,E) +#else /* if !defined(SQLITE_ENABLE_COLUMN_METADATA) */ +# define columnType(A,B,C,D,E) columnTypeImpl(A,B) +#endif +static const char *columnTypeImpl( + NameContext *pNC, +#ifndef SQLITE_ENABLE_COLUMN_METADATA + Expr *pExpr +#else + Expr *pExpr, + const char **pzOrigDb, + const char **pzOrigTab, + const char **pzOrigCol +#endif +){ + char const *zType = 0; + int j; +#ifdef SQLITE_ENABLE_COLUMN_METADATA + char const *zOrigDb = 0; + char const *zOrigTab = 0; + char const *zOrigCol = 0; +#endif + + assert( pExpr!=0 ); + assert( pNC->pSrcList!=0 ); + switch( pExpr->op ){ + case TK_COLUMN: { + /* The expression is a column. Locate the table the column is being + ** extracted from in NameContext.pSrcList. This table may be real + ** database table or a subquery. + */ + Table *pTab = 0; /* Table structure column is extracted from */ + Select *pS = 0; /* Select the column is extracted from */ + int iCol = pExpr->iColumn; /* Index of column in pTab */ + while( pNC && !pTab ){ + SrcList *pTabList = pNC->pSrcList; + for(j=0;jnSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++); + if( jnSrc ){ + pTab = pTabList->a[j].pSTab; + if( pTabList->a[j].fg.isSubquery ){ + pS = pTabList->a[j].u4.pSubq->pSelect; + }else{ + pS = 0; + } + }else{ + pNC = pNC->pNext; + } + } + + if( pTab==0 ){ + /* At one time, code such as "SELECT new.x" within a trigger would + ** cause this condition to run. Since then, we have restructured how + ** trigger code is generated and so this condition is no longer + ** possible. However, it can still be true for statements like + ** the following: + ** + ** CREATE TABLE t1(col INTEGER); + ** SELECT (SELECT t1.col) FROM FROM t1; + ** + ** when columnType() is called on the expression "t1.col" in the + ** sub-select. In this case, set the column type to NULL, even + ** though it should really be "INTEGER". + ** + ** This is not a problem, as the column type of "t1.col" is never + ** used. When columnType() is called on the expression + ** "(SELECT t1.col)", the correct type is returned (see the TK_SELECT + ** branch below. */ + break; + } + + assert( pTab && ExprUseYTab(pExpr) && pExpr->y.pTab==pTab ); + if( pS ){ + /* The "table" is actually a sub-select or a view in the FROM clause + ** of the SELECT statement. Return the declaration type and origin + ** data for the result-set column of the sub-select. + */ + if( iColpEList->nExpr + && (!ViewCanHaveRowid || iCol>=0) + ){ + /* If iCol is less than zero, then the expression requests the + ** rowid of the sub-select or view. This expression is legal (see + ** test case misc2.2.2) - it always evaluates to NULL. + */ + NameContext sNC; + Expr *p = pS->pEList->a[iCol].pExpr; + sNC.pSrcList = pS->pSrc; + sNC.pNext = pNC; + sNC.pParse = pNC->pParse; + zType = columnType(&sNC, p,&zOrigDb,&zOrigTab,&zOrigCol); + } + }else{ + /* A real table or a CTE table */ + assert( !pS ); +#ifdef SQLITE_ENABLE_COLUMN_METADATA + if( iCol<0 ) iCol = pTab->iPKey; + assert( iCol==XN_ROWID || (iCol>=0 && iColnCol) ); + if( iCol<0 ){ + zType = "INTEGER"; + zOrigCol = "rowid"; + }else{ + zOrigCol = pTab->aCol[iCol].zCnName; + zType = sqlite3ColumnType(&pTab->aCol[iCol],0); + } + zOrigTab = pTab->zName; + if( pNC->pParse && pTab->pSchema ){ + int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema); + zOrigDb = pNC->pParse->db->aDb[iDb].zDbSName; + } +#else + assert( iCol==XN_ROWID || (iCol>=0 && iColnCol) ); + if( iCol<0 ){ + zType = "INTEGER"; + }else{ + zType = sqlite3ColumnType(&pTab->aCol[iCol],0); + } +#endif + } + break; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_SELECT: { + /* The expression is a sub-select. Return the declaration type and + ** origin info for the single column in the result set of the SELECT + ** statement. + */ + NameContext sNC; + Select *pS; + Expr *p; + assert( ExprUseXSelect(pExpr) ); + pS = pExpr->x.pSelect; + p = pS->pEList->a[0].pExpr; + sNC.pSrcList = pS->pSrc; + sNC.pNext = pNC; + sNC.pParse = pNC->pParse; + zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol); + break; + } +#endif + } + +#ifdef SQLITE_ENABLE_COLUMN_METADATA + if( pzOrigDb ){ + assert( pzOrigTab && pzOrigCol ); + *pzOrigDb = zOrigDb; + *pzOrigTab = zOrigTab; + *pzOrigCol = zOrigCol; + } +#endif + return zType; +} + +/* +** Generate code that will tell the VDBE the declaration types of columns +** in the result set. +*/ +static void generateColumnTypes( + Parse *pParse, /* Parser context */ + SrcList *pTabList, /* List of tables */ + ExprList *pEList /* Expressions defining the result set */ +){ +#ifndef SQLITE_OMIT_DECLTYPE + Vdbe *v = pParse->pVdbe; + int i; + NameContext sNC; + sNC.pSrcList = pTabList; + sNC.pParse = pParse; + sNC.pNext = 0; + for(i=0; inExpr; i++){ + Expr *p = pEList->a[i].pExpr; + const char *zType; +#ifdef SQLITE_ENABLE_COLUMN_METADATA + const char *zOrigDb = 0; + const char *zOrigTab = 0; + const char *zOrigCol = 0; + zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol); + + /* The vdbe must make its own copy of the column-type and other + ** column specific strings, in case the schema is reset before this + ** virtual machine is deleted. + */ + sqlite3VdbeSetColName(v, i, COLNAME_DATABASE, zOrigDb, SQLITE_TRANSIENT); + sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, SQLITE_TRANSIENT); + sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, SQLITE_TRANSIENT); +#else + zType = columnType(&sNC, p, 0, 0, 0); +#endif + sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT); + } +#else + UNUSED_PARAMETER(pParse); + UNUSED_PARAMETER(pTabList); + UNUSED_PARAMETER(pEList); +#endif /* !defined(SQLITE_OMIT_DECLTYPE) */ +} + + +/* +** Compute the column names for a SELECT statement. +** +** The only guarantee that SQLite makes about column names is that if the +** column has an AS clause assigning it a name, that will be the name used. +** That is the only documented guarantee. However, countless applications +** developed over the years have made baseless assumptions about column names +** and will break if those assumptions changes. Hence, use extreme caution +** when modifying this routine to avoid breaking legacy. +** +** See Also: sqlite3ColumnsFromExprList() +** +** The PRAGMA short_column_names and PRAGMA full_column_names settings are +** deprecated. The default setting is short=ON, full=OFF. 99.9% of all +** applications should operate this way. Nevertheless, we need to support the +** other modes for legacy: +** +** short=OFF, full=OFF: Column name is the text of the expression has it +** originally appears in the SELECT statement. In +** other words, the zSpan of the result expression. +** +** short=ON, full=OFF: (This is the default setting). If the result +** refers directly to a table column, then the +** result column name is just the table column +** name: COLUMN. Otherwise use zSpan. +** +** full=ON, short=ANY: If the result refers directly to a table column, +** then the result column name with the table name +** prefix, ex: TABLE.COLUMN. Otherwise use zSpan. +*/ +SQLITE_PRIVATE void sqlite3GenerateColumnNames( + Parse *pParse, /* Parser context */ + Select *pSelect /* Generate column names for this SELECT statement */ +){ + Vdbe *v = pParse->pVdbe; + int i; + Table *pTab; + SrcList *pTabList; + ExprList *pEList; + sqlite3 *db = pParse->db; + int fullName; /* TABLE.COLUMN if no AS clause and is a direct table ref */ + int srcName; /* COLUMN or TABLE.COLUMN if no AS clause and is direct */ + + if( pParse->colNamesSet ) return; + /* Column names are determined by the left-most term of a compound select */ + while( pSelect->pPrior ) pSelect = pSelect->pPrior; + TREETRACE(0x80,pParse,pSelect,("generating column names\n")); + pTabList = pSelect->pSrc; + pEList = pSelect->pEList; + assert( v!=0 ); + assert( pTabList!=0 ); + pParse->colNamesSet = 1; + fullName = (db->flags & SQLITE_FullColNames)!=0; + srcName = (db->flags & SQLITE_ShortColNames)!=0 || fullName; + sqlite3VdbeSetNumCols(v, pEList->nExpr); + for(i=0; inExpr; i++){ + Expr *p = pEList->a[i].pExpr; + + assert( p!=0 ); + assert( p->op!=TK_AGG_COLUMN ); /* Agg processing has not run yet */ + assert( p->op!=TK_COLUMN + || (ExprUseYTab(p) && p->y.pTab!=0) ); /* Covering idx not yet coded */ + if( pEList->a[i].zEName && pEList->a[i].fg.eEName==ENAME_NAME ){ + /* An AS clause always takes first priority */ + char *zName = pEList->a[i].zEName; + sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT); + }else if( srcName && p->op==TK_COLUMN ){ + char *zCol; + int iCol = p->iColumn; + pTab = p->y.pTab; + assert( pTab!=0 ); + if( iCol<0 ) iCol = pTab->iPKey; + assert( iCol==-1 || (iCol>=0 && iColnCol) ); + if( iCol<0 ){ + zCol = "rowid"; + }else{ + zCol = pTab->aCol[iCol].zCnName; + } + if( fullName ){ + char *zName = 0; + zName = sqlite3MPrintf(db, "%s.%s", pTab->zName, zCol); + sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_DYNAMIC); + }else{ + sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, SQLITE_TRANSIENT); + } + }else{ + const char *z = pEList->a[i].zEName; + z = z==0 ? sqlite3MPrintf(db, "column%d", i+1) : sqlite3DbStrDup(db, z); + sqlite3VdbeSetColName(v, i, COLNAME_NAME, z, SQLITE_DYNAMIC); + } + } + generateColumnTypes(pParse, pTabList, pEList); +} + +/* +** Given an expression list (which is really the list of expressions +** that form the result set of a SELECT statement) compute appropriate +** column names for a table that would hold the expression list. +** +** All column names will be unique. +** +** Only the column names are computed. Column.zType, Column.zColl, +** and other fields of Column are zeroed. +** +** Return SQLITE_OK on success. If a memory allocation error occurs, +** store NULL in *paCol and 0 in *pnCol and return SQLITE_NOMEM. +** +** The only guarantee that SQLite makes about column names is that if the +** column has an AS clause assigning it a name, that will be the name used. +** That is the only documented guarantee. However, countless applications +** developed over the years have made baseless assumptions about column names +** and will break if those assumptions changes. Hence, use extreme caution +** when modifying this routine to avoid breaking legacy. +** +** See Also: sqlite3GenerateColumnNames() +*/ +SQLITE_PRIVATE int sqlite3ColumnsFromExprList( + Parse *pParse, /* Parsing context */ + ExprList *pEList, /* Expr list from which to derive column names */ + i16 *pnCol, /* Write the number of columns here */ + Column **paCol /* Write the new column list here */ +){ + sqlite3 *db = pParse->db; /* Database connection */ + int i, j; /* Loop counters */ + u32 cnt; /* Index added to make the name unique */ + Column *aCol, *pCol; /* For looping over result columns */ + int nCol; /* Number of columns in the result set */ + char *zName; /* Column name */ + int nName; /* Size of name in zName[] */ + Hash ht; /* Hash table of column names */ + Table *pTab; + + sqlite3HashInit(&ht); + if( pEList ){ + nCol = pEList->nExpr; + aCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol); + testcase( aCol==0 ); + if( NEVER(nCol>32767) ) nCol = 32767; + }else{ + nCol = 0; + aCol = 0; + } + assert( nCol==(i16)nCol ); + *pnCol = nCol; + *paCol = aCol; + + for(i=0, pCol=aCol; inErr; i++, pCol++){ + struct ExprList_item *pX = &pEList->a[i]; + struct ExprList_item *pCollide; + /* Get an appropriate name for the column + */ + if( (zName = pX->zEName)!=0 && pX->fg.eEName==ENAME_NAME ){ + /* If the column contains an "AS " phrase, use as the name */ + }else{ + Expr *pColExpr = sqlite3ExprSkipCollateAndLikely(pX->pExpr); + while( ALWAYS(pColExpr!=0) && pColExpr->op==TK_DOT ){ + pColExpr = pColExpr->pRight; + assert( pColExpr!=0 ); + } + if( pColExpr->op==TK_COLUMN + && ALWAYS( ExprUseYTab(pColExpr) ) + && ALWAYS( pColExpr->y.pTab!=0 ) + ){ + /* For columns use the column name name */ + int iCol = pColExpr->iColumn; + pTab = pColExpr->y.pTab; + if( iCol<0 ) iCol = pTab->iPKey; + zName = iCol>=0 ? pTab->aCol[iCol].zCnName : "rowid"; + }else if( pColExpr->op==TK_ID ){ + assert( !ExprHasProperty(pColExpr, EP_IntValue) ); + zName = pColExpr->u.zToken; + }else{ + /* Use the original text of the column expression as its name */ + assert( zName==pX->zEName ); /* pointer comparison intended */ + } + } + if( zName && !sqlite3IsTrueOrFalse(zName) ){ + zName = sqlite3DbStrDup(db, zName); + }else{ + zName = sqlite3MPrintf(db,"column%d",i+1); + } + + /* Make sure the column name is unique. If the name is not unique, + ** append an integer to the name so that it becomes unique. + */ + cnt = 0; + while( zName && (pCollide = sqlite3HashFind(&ht, zName))!=0 ){ + if( pCollide->fg.bUsingTerm ){ + pCol->colFlags |= COLFLAG_NOEXPAND; + } + nName = sqlite3Strlen30(zName); + if( nName>0 ){ + for(j=nName-1; j>0 && sqlite3Isdigit(zName[j]); j--){} + if( zName[j]==':' ) nName = j; + } + zName = sqlite3MPrintf(db, "%.*z:%u", nName, zName, ++cnt); + sqlite3ProgressCheck(pParse); + if( cnt>3 ){ + sqlite3_randomness(sizeof(cnt), &cnt); + } + } + pCol->zCnName = zName; + pCol->hName = sqlite3StrIHash(zName); + if( pX->fg.bNoExpand ){ + pCol->colFlags |= COLFLAG_NOEXPAND; + } + sqlite3ColumnPropertiesFromName(0, pCol); + if( zName && sqlite3HashInsert(&ht, zName, pX)==pX ){ + sqlite3OomFault(db); + } + } + sqlite3HashClear(&ht); + if( pParse->nErr ){ + for(j=0; jrc; + } + return SQLITE_OK; +} + +/* +** pTab is a transient Table object that represents a subquery of some +** kind (maybe a parenthesized subquery in the FROM clause of a larger +** query, or a VIEW, or a CTE). This routine computes type information +** for that Table object based on the Select object that implements the +** subquery. For the purposes of this routine, "type information" means: +** +** * The datatype name, as it might appear in a CREATE TABLE statement +** * Which collating sequence to use for the column +** * The affinity of the column +*/ +SQLITE_PRIVATE void sqlite3SubqueryColumnTypes( + Parse *pParse, /* Parsing contexts */ + Table *pTab, /* Add column type information to this table */ + Select *pSelect, /* SELECT used to determine types and collations */ + char aff /* Default affinity. */ +){ + sqlite3 *db = pParse->db; + Column *pCol; + CollSeq *pColl; + int i,j; + Expr *p; + struct ExprList_item *a; + NameContext sNC; + + assert( pSelect!=0 ); + assert( (pSelect->selFlags & SF_Resolved)!=0 ); + assert( pTab->nCol==pSelect->pEList->nExpr || pParse->nErr>0 ); + assert( aff==SQLITE_AFF_NONE || aff==SQLITE_AFF_BLOB ); + if( db->mallocFailed || IN_RENAME_OBJECT ) return; + while( pSelect->pPrior ) pSelect = pSelect->pPrior; + a = pSelect->pEList->a; + memset(&sNC, 0, sizeof(sNC)); + sNC.pSrcList = pSelect->pSrc; + for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){ + const char *zType; + i64 n; + int m = 0; + Select *pS2 = pSelect; + pTab->tabFlags |= (pCol->colFlags & COLFLAG_NOINSERT); + p = a[i].pExpr; + /* pCol->szEst = ... // Column size est for SELECT tables never used */ + pCol->affinity = sqlite3ExprAffinity(p); + while( pCol->affinity<=SQLITE_AFF_NONE && pS2->pNext!=0 ){ + m |= sqlite3ExprDataType(pS2->pEList->a[i].pExpr); + pS2 = pS2->pNext; + pCol->affinity = sqlite3ExprAffinity(pS2->pEList->a[i].pExpr); + } + if( pCol->affinity<=SQLITE_AFF_NONE ){ + pCol->affinity = aff; + } + if( pCol->affinity>=SQLITE_AFF_TEXT && (pS2->pNext || pS2!=pSelect) ){ + for(pS2=pS2->pNext; pS2; pS2=pS2->pNext){ + m |= sqlite3ExprDataType(pS2->pEList->a[i].pExpr); + } + if( pCol->affinity==SQLITE_AFF_TEXT && (m&0x01)!=0 ){ + pCol->affinity = SQLITE_AFF_BLOB; + }else + if( pCol->affinity>=SQLITE_AFF_NUMERIC && (m&0x02)!=0 ){ + pCol->affinity = SQLITE_AFF_BLOB; + } + if( pCol->affinity>=SQLITE_AFF_NUMERIC && p->op==TK_CAST ){ + pCol->affinity = SQLITE_AFF_FLEXNUM; + } + } + zType = columnType(&sNC, p, 0, 0, 0); + if( zType==0 || pCol->affinity!=sqlite3AffinityType(zType, 0) ){ + if( pCol->affinity==SQLITE_AFF_NUMERIC + || pCol->affinity==SQLITE_AFF_FLEXNUM + ){ + zType = "NUM"; + }else{ + zType = 0; + for(j=1; jaffinity ){ + zType = sqlite3StdType[j]; + break; + } + } + } + } + if( zType ){ + const i64 k = strlen(zType); + n = strlen(pCol->zCnName); + pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+k+2); + pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL); + if( pCol->zCnName ){ + memcpy(&pCol->zCnName[n+1], zType, k+1); + pCol->colFlags |= COLFLAG_HASTYPE; + } + } + pColl = sqlite3ExprCollSeq(pParse, p); + if( pColl ){ + assert( pTab->pIndex==0 ); + sqlite3ColumnSetColl(db, pCol, pColl->zName); + } + } + pTab->szTabRow = 1; /* Any non-zero value works */ +} + +/* +** Given a SELECT statement, generate a Table structure that describes +** the result set of that SELECT. +*/ +SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect, char aff){ + Table *pTab; + sqlite3 *db = pParse->db; + u64 savedFlags; + + pParse->nNestSel++; +#if SQLITE_MAX_EXPR_DEPTH>0 + if( pParse->nNestSel >= db->aLimit[SQLITE_LIMIT_EXPR_DEPTH] ){ + sqlite3ErrorMsg(pParse, "VIEWs and/or subqueries nested too deep"); + return 0; + } +#endif + savedFlags = db->flags; + db->flags &= ~(u64)SQLITE_FullColNames; + db->flags |= SQLITE_ShortColNames; + sqlite3SelectPrep(pParse, pSelect, 0); + db->flags = savedFlags; + if( pParse->nErr ) return 0; + while( pSelect->pPrior ) pSelect = pSelect->pPrior; + pTab = sqlite3DbMallocZero(db, sizeof(Table) ); + if( pTab==0 ){ + return 0; + } + pTab->nTabRef = 1; + pTab->zName = 0; + pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); + sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol); + sqlite3SubqueryColumnTypes(pParse, pTab, pSelect, aff); + pTab->iPKey = -1; + if( db->mallocFailed ){ + sqlite3DeleteTable(db, pTab); + return 0; + } + pParse->nNestSel--; + assert( pParse->nNestSel>=0 ); + return pTab; +} + +/* +** Get a VDBE for the given parser context. Create a new one if necessary. +** If an error occurs, return NULL and leave a message in pParse. +*/ +SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){ + if( pParse->pVdbe ){ + return pParse->pVdbe; + } + if( pParse->pToplevel==0 + && OptimizationEnabled(pParse->db,SQLITE_FactorOutConst) + ){ + pParse->okConstFactor = 1; + } + return sqlite3VdbeCreate(pParse); +} + + +/* +** Compute the iLimit and iOffset fields of the SELECT based on the +** pLimit expressions. pLimit->pLeft and pLimit->pRight hold the expressions +** that appear in the original SQL statement after the LIMIT and OFFSET +** keywords. Or NULL if those keywords are omitted. iLimit and iOffset +** are the integer memory register numbers for counters used to compute +** the limit and offset. If there is no limit and/or offset, then +** iLimit and iOffset are negative. +** +** This routine changes the values of iLimit and iOffset only if +** a limit or offset is defined by pLimit->pLeft and pLimit->pRight. iLimit +** and iOffset should have been preset to appropriate default values (zero) +** prior to calling this routine. +** +** The iOffset register (if it exists) is initialized to the value +** of the OFFSET. The iLimit register is initialized to LIMIT. Register +** iOffset+1 is initialized to LIMIT+OFFSET. +** +** Only if pLimit->pLeft!=0 do the limit registers get +** redefined. The UNION ALL operator uses this property to force +** the reuse of the same limit and offset registers across multiple +** SELECT statements. +*/ +static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ + Vdbe *v = 0; + int iLimit = 0; + int iOffset; + int n; + Expr *pLimit = p->pLimit; + + if( p->iLimit ) return; + + /* + ** "LIMIT -1" always shows all rows. There is some + ** controversy about what the correct behavior should be. + ** The current implementation interprets "LIMIT 0" to mean + ** no rows. + */ + if( pLimit ){ + assert( pLimit->op==TK_LIMIT ); + assert( pLimit->pLeft!=0 ); + p->iLimit = iLimit = ++pParse->nMem; + v = sqlite3GetVdbe(pParse); + assert( v!=0 ); + if( sqlite3ExprIsInteger(pLimit->pLeft, &n, pParse) ){ + sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit); + VdbeComment((v, "LIMIT counter")); + if( n==0 ){ + sqlite3VdbeGoto(v, iBreak); + }else if( n>=0 && p->nSelectRow>sqlite3LogEst((u64)n) ){ + p->nSelectRow = sqlite3LogEst((u64)n); + p->selFlags |= SF_FixedLimit; + } + }else{ + sqlite3ExprCode(pParse, pLimit->pLeft, iLimit); + sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeCoverage(v); + VdbeComment((v, "LIMIT counter")); + sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, iBreak); VdbeCoverage(v); + } + if( pLimit->pRight ){ + p->iOffset = iOffset = ++pParse->nMem; + pParse->nMem++; /* Allocate an extra register for limit+offset */ + sqlite3ExprCode(pParse, pLimit->pRight, iOffset); + sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v); + VdbeComment((v, "OFFSET counter")); + sqlite3VdbeAddOp3(v, OP_OffsetLimit, iLimit, iOffset+1, iOffset); + VdbeComment((v, "LIMIT+OFFSET")); + } + } +} + +#ifndef SQLITE_OMIT_COMPOUND_SELECT +/* +** Return the appropriate collating sequence for the iCol-th column of +** the result set for the compound-select statement "p". Return NULL if +** the column has no default collating sequence. +** +** The collating sequence for the compound select is taken from the +** left-most term of the select that has a collating sequence. +*/ +static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){ + CollSeq *pRet; + if( p->pPrior ){ + pRet = multiSelectCollSeq(pParse, p->pPrior, iCol); + }else{ + pRet = 0; + } + assert( iCol>=0 ); + /* iCol must be less than p->pEList->nExpr. Otherwise an error would + ** have been thrown during name resolution and we would not have gotten + ** this far */ + if( pRet==0 && ALWAYS(iColpEList->nExpr) ){ + pRet = sqlite3ExprCollSeq(pParse, p->pEList->a[iCol].pExpr); + } + return pRet; +} + +/* +** The select statement passed as the second parameter is a compound SELECT +** with an ORDER BY clause. This function allocates and returns a KeyInfo +** structure suitable for implementing the ORDER BY. +** +** Space to hold the KeyInfo structure is obtained from malloc. The calling +** function is responsible for ensuring that this structure is eventually +** freed. +*/ +static KeyInfo *multiSelectByMergeKeyInfo(Parse *pParse, Select *p, int nExtra){ + ExprList *pOrderBy = p->pOrderBy; + int nOrderBy = (pOrderBy!=0) ? pOrderBy->nExpr : 0; + sqlite3 *db = pParse->db; + KeyInfo *pRet = sqlite3KeyInfoAlloc(db, nOrderBy+nExtra, 1); + if( pRet ){ + int i; + for(i=0; ia[i]; + Expr *pTerm = pItem->pExpr; + CollSeq *pColl; + + if( pTerm->flags & EP_Collate ){ + pColl = sqlite3ExprCollSeq(pParse, pTerm); + }else{ + pColl = multiSelectCollSeq(pParse, p, pItem->u.x.iOrderByCol-1); + if( pColl==0 ) pColl = db->pDfltColl; + pOrderBy->a[i].pExpr = + sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName); + } + assert( sqlite3KeyInfoIsWriteable(pRet) ); + pRet->aColl[i] = pColl; + pRet->aSortFlags[i] = pOrderBy->a[i].fg.sortFlags; + } + } + + return pRet; +} + +#ifndef SQLITE_OMIT_CTE +/* +** This routine generates VDBE code to compute the content of a WITH RECURSIVE +** query of the form: +** +** AS ( UNION [ALL] ) +** \___________/ \_______________/ +** p->pPrior p +** +** +** There is exactly one reference to the recursive-table in the FROM clause +** of recursive-query, marked with the SrcList->a[].fg.isRecursive flag. +** +** The setup-query runs once to generate an initial set of rows that go +** into a Queue table. Rows are extracted from the Queue table one by +** one. Each row extracted from Queue is output to pDest. Then the single +** extracted row (now in the iCurrent table) becomes the content of the +** recursive-table for a recursive-query run. The output of the recursive-query +** is added back into the Queue table. Then another row is extracted from Queue +** and the iteration continues until the Queue table is empty. +** +** If the compound query operator is UNION then no duplicate rows are ever +** inserted into the Queue table. The iDistinct table keeps a copy of all rows +** that have ever been inserted into Queue and causes duplicates to be +** discarded. If the operator is UNION ALL, then duplicates are allowed. +** +** If the query has an ORDER BY, then entries in the Queue table are kept in +** ORDER BY order and the first entry is extracted for each cycle. Without +** an ORDER BY, the Queue table is just a FIFO. +** +** If a LIMIT clause is provided, then the iteration stops after LIMIT rows +** have been output to pDest. A LIMIT of zero means to output no rows and a +** negative LIMIT means to output all rows. If there is also an OFFSET clause +** with a positive value, then the first OFFSET outputs are discarded rather +** than being sent to pDest. The LIMIT count does not begin until after OFFSET +** rows have been skipped. +*/ +static void generateWithRecursiveQuery( + Parse *pParse, /* Parsing context */ + Select *p, /* The recursive SELECT to be coded */ + SelectDest *pDest /* What to do with query results */ +){ + SrcList *pSrc = p->pSrc; /* The FROM clause of the recursive query */ + int nCol = p->pEList->nExpr; /* Number of columns in the recursive table */ + Vdbe *v = pParse->pVdbe; /* The prepared statement under construction */ + Select *pSetup; /* The setup query */ + Select *pFirstRec; /* Left-most recursive term */ + int addrTop; /* Top of the loop */ + int addrCont, addrBreak; /* CONTINUE and BREAK addresses */ + int iCurrent = 0; /* The Current table */ + int regCurrent; /* Register holding Current table */ + int iQueue; /* The Queue table */ + int iDistinct = 0; /* To ensure unique results if UNION */ + int eDest = SRT_Fifo; /* How to write to Queue */ + SelectDest destQueue; /* SelectDest targeting the Queue table */ + int i; /* Loop counter */ + int rc; /* Result code */ + ExprList *pOrderBy; /* The ORDER BY clause */ + Expr *pLimit; /* Saved LIMIT and OFFSET */ + int regLimit, regOffset; /* Registers used by LIMIT and OFFSET */ + +#ifndef SQLITE_OMIT_WINDOWFUNC + if( p->pWin ){ + sqlite3ErrorMsg(pParse, "cannot use window functions in recursive queries"); + return; + } +#endif + + /* Obtain authorization to do a recursive query */ + if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return; + + /* Process the LIMIT and OFFSET clauses, if they exist */ + addrBreak = sqlite3VdbeMakeLabel(pParse); + p->nSelectRow = 320; /* 4 billion rows */ + computeLimitRegisters(pParse, p, addrBreak); + pLimit = p->pLimit; + regLimit = p->iLimit; + regOffset = p->iOffset; + p->pLimit = 0; + p->iLimit = p->iOffset = 0; + pOrderBy = p->pOrderBy; + + /* Locate the cursor number of the Current table */ + for(i=0; ALWAYS(inSrc); i++){ + if( pSrc->a[i].fg.isRecursive ){ + iCurrent = pSrc->a[i].iCursor; + break; + } + } + + /* Allocate cursors numbers for Queue and Distinct. The cursor number for + ** the Distinct table must be exactly one greater than Queue in order + ** for the SRT_DistFifo and SRT_DistQueue destinations to work. */ + iQueue = pParse->nTab++; + if( p->op==TK_UNION ){ + eDest = pOrderBy ? SRT_DistQueue : SRT_DistFifo; + iDistinct = pParse->nTab++; + }else{ + eDest = pOrderBy ? SRT_Queue : SRT_Fifo; + } + sqlite3SelectDestInit(&destQueue, eDest, iQueue); + + /* Allocate cursors for Current, Queue, and Distinct. */ + regCurrent = ++pParse->nMem; + sqlite3VdbeAddOp3(v, OP_OpenPseudo, iCurrent, regCurrent, nCol); + if( pOrderBy ){ + KeyInfo *pKeyInfo = multiSelectByMergeKeyInfo(pParse, p, 1); + sqlite3VdbeAddOp4(v, OP_OpenEphemeral, iQueue, pOrderBy->nExpr+2, 0, + (char*)pKeyInfo, P4_KEYINFO); + destQueue.pOrderBy = pOrderBy; + }else{ + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iQueue, nCol); + } + VdbeComment((v, "Queue table")); + if( iDistinct ){ + /* Generate an ephemeral table used to enforce distinctness on the + ** output of the recursive part of the CTE. + */ + KeyInfo *pKeyInfo; /* Collating sequence for the result set */ + CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */ + + assert( p->pNext==0 ); + assert( p->pEList!=0 ); + nCol = p->pEList->nExpr; + pKeyInfo = sqlite3KeyInfoAlloc(pParse->db, nCol, 1); + if( pKeyInfo ){ + for(i=0, apColl=pKeyInfo->aColl; idb->pDfltColl; + } + } + sqlite3VdbeAddOp4(v, OP_OpenEphemeral, iDistinct, nCol, 0, + (void*)pKeyInfo, P4_KEYINFO); + }else{ + assert( pParse->nErr>0 ); + } + } + + /* Detach the ORDER BY clause from the compound SELECT */ + p->pOrderBy = 0; + + /* Figure out how many elements of the compound SELECT are part of the + ** recursive query. Make sure no recursive elements use aggregate + ** functions. Mark the recursive elements as UNION ALL even if they + ** are really UNION because the distinctness will be enforced by the + ** iDistinct table. pFirstRec is left pointing to the left-most + ** recursive term of the CTE. + */ + for(pFirstRec=p; ALWAYS(pFirstRec!=0); pFirstRec=pFirstRec->pPrior){ + if( pFirstRec->selFlags & SF_Aggregate ){ + sqlite3ErrorMsg(pParse, "recursive aggregate queries not supported"); + goto end_of_recursive_query; + } + pFirstRec->op = TK_ALL; + if( (pFirstRec->pPrior->selFlags & SF_Recursive)==0 ) break; + } + + /* Store the results of the setup-query in Queue. */ + pSetup = pFirstRec->pPrior; + pSetup->pNext = 0; + ExplainQueryPlan((pParse, 1, "SETUP")); + rc = sqlite3Select(pParse, pSetup, &destQueue); + pSetup->pNext = p; + if( rc ) goto end_of_recursive_query; + + /* Find the next row in the Queue and output that row */ + addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iQueue, addrBreak); VdbeCoverage(v); + + /* Transfer the next row in Queue over to Current */ + sqlite3VdbeAddOp1(v, OP_NullRow, iCurrent); /* To reset column cache */ + if( pOrderBy ){ + sqlite3VdbeAddOp3(v, OP_Column, iQueue, pOrderBy->nExpr+1, regCurrent); + }else{ + sqlite3VdbeAddOp2(v, OP_RowData, iQueue, regCurrent); + } + sqlite3VdbeAddOp1(v, OP_Delete, iQueue); + + /* Output the single row in Current */ + addrCont = sqlite3VdbeMakeLabel(pParse); + codeOffset(v, regOffset, addrCont); + selectInnerLoop(pParse, p, iCurrent, + 0, 0, pDest, addrCont, addrBreak); + if( regLimit ){ + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, regLimit, addrBreak); + VdbeCoverage(v); + } + sqlite3VdbeResolveLabel(v, addrCont); + + /* Execute the recursive SELECT taking the single row in Current as + ** the value for the recursive-table. Store the results in the Queue. + */ + pFirstRec->pPrior = 0; + ExplainQueryPlan((pParse, 1, "RECURSIVE STEP")); + sqlite3Select(pParse, p, &destQueue); + assert( pFirstRec->pPrior==0 ); + pFirstRec->pPrior = pSetup; + + /* Keep running the loop until the Queue is empty */ + sqlite3VdbeGoto(v, addrTop); + sqlite3VdbeResolveLabel(v, addrBreak); + +end_of_recursive_query: + sqlite3ExprListDelete(pParse->db, p->pOrderBy); + p->pOrderBy = pOrderBy; + p->pLimit = pLimit; + return; +} +#endif /* SQLITE_OMIT_CTE */ + +/* Forward references */ +static int multiSelectByMerge( + Parse *pParse, /* Parsing context */ + Select *p, /* The right-most of SELECTs to be coded */ + SelectDest *pDest /* What to do with query results */ +); + +/* +** Handle the special case of a compound-select that originates from a +** VALUES clause. By handling this as a special case, we avoid deep +** recursion, and thus do not need to enforce the SQLITE_LIMIT_COMPOUND_SELECT +** on a VALUES clause. +** +** Because the Select object originates from a VALUES clause: +** (1) There is no LIMIT or OFFSET or else there is a LIMIT of exactly 1 +** (2) All terms are UNION ALL +** (3) There is no ORDER BY clause +** +** The "LIMIT of exactly 1" case of condition (1) comes about when a VALUES +** clause occurs within scalar expression (ex: "SELECT (VALUES(1),(2),(3))"). +** The sqlite3CodeSubselect will have added the LIMIT 1 clause in tht case. +** Since the limit is exactly 1, we only need to evaluate the left-most VALUES. +*/ +static int multiSelectValues( + Parse *pParse, /* Parsing context */ + Select *p, /* The right-most of SELECTs to be coded */ + SelectDest *pDest /* What to do with query results */ +){ + int nRow = 1; + int rc = 0; + int bShowAll = p->pLimit==0; + assert( p->selFlags & SF_MultiValue ); + do{ + assert( p->selFlags & SF_Values ); + assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) ); + assert( p->pNext==0 || p->pEList->nExpr==p->pNext->pEList->nExpr ); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( p->pWin ) return -1; +#endif + if( p->pPrior==0 ) break; + assert( p->pPrior->pNext==p ); + p = p->pPrior; + nRow += bShowAll; + }while(1); + ExplainQueryPlan((pParse, 0, "SCAN %d CONSTANT ROW%s", nRow, + nRow==1 ? "" : "S")); + while( p ){ + selectInnerLoop(pParse, p, -1, 0, 0, pDest, 1, 1); + if( !bShowAll ) break; + p->nSelectRow = nRow; + p = p->pNext; + } + return rc; +} + +/* +** Return true if the SELECT statement which is known to be the recursive +** part of a recursive CTE still has its anchor terms attached. If the +** anchor terms have already been removed, then return false. +*/ +static int hasAnchor(Select *p){ + while( p && (p->selFlags & SF_Recursive)!=0 ){ p = p->pPrior; } + return p!=0; +} + +/* +** This routine is called to process a compound query form from +** two or more separate queries using UNION, UNION ALL, EXCEPT, or +** INTERSECT +** +** "p" points to the right-most of the two queries. the query on the +** left is p->pPrior. The left query could also be a compound query +** in which case this routine will be called recursively. +** +** The results of the total query are to be written into a destination +** of type eDest with parameter iParm. +** +** Example 1: Consider a three-way compound SQL statement. +** +** SELECT a FROM t1 UNION SELECT b FROM t2 UNION SELECT c FROM t3 +** +** This statement is parsed up as follows: +** +** SELECT c FROM t3 +** | +** `-----> SELECT b FROM t2 +** | +** `------> SELECT a FROM t1 +** +** The arrows in the diagram above represent the Select.pPrior pointer. +** So if this routine is called with p equal to the t3 query, then +** pPrior will be the t2 query. p->op will be TK_UNION in this case. +** +** Notice that because of the way SQLite parses compound SELECTs, the +** individual selects always group from left to right. +*/ +static int multiSelect( + Parse *pParse, /* Parsing context */ + Select *p, /* The right-most of SELECTs to be coded */ + SelectDest *pDest /* What to do with query results */ +){ + int rc = SQLITE_OK; /* Success code from a subroutine */ + Select *pPrior; /* Another SELECT immediately to our left */ + Vdbe *v; /* Generate code to this VDBE */ + SelectDest dest; /* Alternative data destination */ + Select *pDelete = 0; /* Chain of simple selects to delete */ + sqlite3 *db; /* Database connection */ + + /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only + ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT. + */ + assert( p && p->pPrior ); /* Calling function guarantees this much */ + assert( (p->selFlags & SF_Recursive)==0 || p->op==TK_ALL || p->op==TK_UNION ); + assert( p->selFlags & SF_Compound ); + db = pParse->db; + pPrior = p->pPrior; + dest = *pDest; + assert( pPrior->pOrderBy==0 ); + assert( pPrior->pLimit==0 ); + + v = sqlite3GetVdbe(pParse); + assert( v!=0 ); /* The VDBE already created by calling function */ + + /* Create the destination temporary table if necessary + */ + if( dest.eDest==SRT_EphemTab ){ + assert( p->pEList ); + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iSDParm, p->pEList->nExpr); + dest.eDest = SRT_Table; + } + + /* Special handling for a compound-select that originates as a VALUES clause. + */ + if( p->selFlags & SF_MultiValue ){ + rc = multiSelectValues(pParse, p, &dest); + if( rc>=0 ) goto multi_select_end; + rc = SQLITE_OK; + } + + /* Make sure all SELECTs in the statement have the same number of elements + ** in their result sets. + */ + assert( p->pEList && pPrior->pEList ); + assert( p->pEList->nExpr==pPrior->pEList->nExpr ); + +#ifndef SQLITE_OMIT_CTE + if( (p->selFlags & SF_Recursive)!=0 && hasAnchor(p) ){ + generateWithRecursiveQuery(pParse, p, &dest); + }else +#endif + if( p->pOrderBy ){ + /* If the compound has an ORDER BY clause, then always use the merge + ** algorithm. */ + return multiSelectByMerge(pParse, p, pDest); + }else if( p->op!=TK_ALL ){ + /* If the compound is EXCEPT, INTERSECT, or UNION (anything other than + ** UNION ALL) then also always use the merge algorithm. However, the + ** multiSelectByMerge() routine requires that the compound have an + ** ORDER BY clause, and it doesn't right now. So invent one first. */ + Expr *pOne = sqlite3ExprInt32(db, 1); + p->pOrderBy = sqlite3ExprListAppend(pParse, 0, pOne); + if( pParse->nErr ) goto multi_select_end; + assert( p->pOrderBy!=0 ); + p->pOrderBy->a[0].u.x.iOrderByCol = 1; + return multiSelectByMerge(pParse, p, pDest); + }else{ + /* For a UNION ALL compound without ORDER BY, simply run the left + ** query, then run the right query */ + int addr = 0; + int nLimit = 0; /* Initialize to suppress harmless compiler warning */ + +#ifndef SQLITE_OMIT_EXPLAIN + if( pPrior->pPrior==0 ){ + ExplainQueryPlan((pParse, 1, "COMPOUND QUERY")); + ExplainQueryPlan((pParse, 1, "LEFT-MOST SUBQUERY")); + } +#endif + assert( !pPrior->pLimit ); + pPrior->iLimit = p->iLimit; + pPrior->iOffset = p->iOffset; + pPrior->pLimit = sqlite3ExprDup(db, p->pLimit, 0); + TREETRACE(0x200, pParse, p, ("multiSelect UNION ALL left...\n")); + rc = sqlite3Select(pParse, pPrior, &dest); + sqlite3ExprDelete(db, pPrior->pLimit); + pPrior->pLimit = 0; + if( rc ){ + goto multi_select_end; + } + p->pPrior = 0; + p->iLimit = pPrior->iLimit; + p->iOffset = pPrior->iOffset; + if( p->iLimit ){ + addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v); + VdbeComment((v, "Jump ahead if LIMIT reached")); + if( p->iOffset ){ + sqlite3VdbeAddOp3(v, OP_OffsetLimit, + p->iLimit, p->iOffset+1, p->iOffset); + } + } + ExplainQueryPlan((pParse, 1, "UNION ALL")); + TREETRACE(0x200, pParse, p, ("multiSelect UNION ALL right...\n")); + rc = sqlite3Select(pParse, p, &dest); + testcase( rc!=SQLITE_OK ); + pDelete = p->pPrior; + p->pPrior = pPrior; + p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); + if( p->pLimit + && sqlite3ExprIsInteger(p->pLimit->pLeft, &nLimit, pParse) + && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) + ){ + p->nSelectRow = sqlite3LogEst((u64)nLimit); + } + if( addr ){ + sqlite3VdbeJumpHere(v, addr); + } +#ifndef SQLITE_OMIT_EXPLAIN + if( p->pNext==0 ){ + ExplainQueryPlanPop(pParse); + } +#endif + } + +multi_select_end: + pDest->iSdst = dest.iSdst; + pDest->nSdst = dest.nSdst; + pDest->iSDParm2 = dest.iSDParm2; + if( pDelete ){ + sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pDelete); + } + return rc; +} +#endif /* SQLITE_OMIT_COMPOUND_SELECT */ + +/* +** Error message for when two or more terms of a compound select have different +** size result sets. +*/ +SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p){ + if( p->selFlags & SF_Values ){ + sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms"); + }else{ + sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s" + " do not have the same number of result columns", + sqlite3SelectOpName(p->op)); + } +} + +/* +** Code an output subroutine for a coroutine implementation of a +** SELECT statement. +** +** The data to be output is contained in an array of pIn->nSdst registers +** starting at register pIn->iSdst. pDest is where the output should +** be sent. +** +** regReturn is the number of the register holding the subroutine +** return address. +** +** If regPrev>0 then it is the first register in a vector that +** records the previous output. mem[regPrev] is a flag that is false +** if there has been no previous output. If regPrev>0 then code is +** generated to suppress duplicates. pKeyInfo is used for comparing +** keys. +** +** If the LIMIT found in p->iLimit is reached, jump immediately to +** iBreak. +*/ +static int generateOutputSubroutine( + Parse *pParse, /* Parsing context */ + Select *p, /* The SELECT statement */ + SelectDest *pIn, /* Coroutine supplying data */ + SelectDest *pDest, /* Where to send the data */ + int regReturn, /* The return address register */ + int regPrev, /* Previous result register. No uniqueness if 0 */ + KeyInfo *pKeyInfo, /* For comparing with previous entry */ + int iBreak /* Jump here if we hit the LIMIT */ +){ + Vdbe *v = pParse->pVdbe; + int iContinue; + int addr; + + assert( pIn->eDest==SRT_Coroutine ); + + addr = sqlite3VdbeCurrentAddr(v); + iContinue = sqlite3VdbeMakeLabel(pParse); + + /* Suppress duplicates for UNION, EXCEPT, and INTERSECT + */ + if( regPrev ){ + int addr1, addr2; + addr1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); VdbeCoverage(v); + addr2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst, + (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO); + sqlite3VdbeAddOp3(v, OP_Jump, addr2+2, iContinue, addr2+2); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr1); + sqlite3VdbeAddOp3(v, OP_Copy, pIn->iSdst, regPrev+1, pIn->nSdst-1); + sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev); + } + if( pParse->db->mallocFailed ) return 0; + + /* Suppress the first OFFSET entries if there is an OFFSET clause + */ + codeOffset(v, p->iOffset, iContinue); + + switch( pDest->eDest ){ + /* Store the result as data using a unique key. + */ + case SRT_Fifo: + case SRT_DistFifo: + case SRT_Table: + case SRT_EphemTab: { + int r1 = sqlite3GetTempReg(pParse); + int r2 = sqlite3GetTempReg(pParse); + int iParm = pDest->iSDParm; + testcase( pDest->eDest==SRT_Table ); + testcase( pDest->eDest==SRT_EphemTab ); + testcase( pDest->eDest==SRT_Fifo ); + testcase( pDest->eDest==SRT_DistFifo ); + sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1); +#if !defined(SQLITE_ENABLE_NULL_TRIM) && defined(SQLITE_DEBUG) + /* A destination of SRT_Table and a non-zero iSDParm2 parameter means + ** that this is an "UPDATE ... FROM" on a virtual table or view. In this + ** case set the p5 parameter of the OP_MakeRecord to OPFLAG_NOCHNG_MAGIC. + ** This does not affect operation in any way - it just allows MakeRecord + ** to process OPFLAG_NOCHANGE values without an assert() failing. */ + if( pDest->eDest==SRT_Table && pDest->iSDParm2 ){ + sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG_MAGIC); + } +#endif +#ifndef SQLITE_OMIT_CTE + if( pDest->eDest==SRT_DistFifo ){ + /* If the destination is DistFifo, then cursor (iParm+1) is open + ** on an ephemeral index that is used to enforce uniqueness on the + ** total result. At this point, we are processing the setup portion + ** of the recursive CTE using the merge algorithm, so the results are + ** guaranteed to be unique anyhow. But we still need to populate the + ** (iParm+1) cursor for use by the subsequent recursive phase. + */ + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm+1, r1, + pIn->iSdst, pIn->nSdst); + } +#endif + sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2); + sqlite3VdbeAddOp3(v, OP_Insert, iParm, r1, r2); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + sqlite3ReleaseTempReg(pParse, r2); + sqlite3ReleaseTempReg(pParse, r1); + break; + } + + /* If any row exist in the result set, record that fact and abort. + */ + case SRT_Exists: { + sqlite3VdbeAddOp2(v, OP_Integer, 1, pDest->iSDParm); + /* The LIMIT clause will terminate the loop for us */ + break; + } + +#ifndef SQLITE_OMIT_SUBQUERY + /* If we are creating a set for an "expr IN (SELECT ...)". + */ + case SRT_Set: { + int r1; + testcase( pIn->nSdst>1 ); + r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, + r1, pDest->zAffSdst, pIn->nSdst); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1, + pIn->iSdst, pIn->nSdst); + if( pDest->iSDParm2>0 ){ + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pDest->iSDParm2, 0, + pIn->iSdst, pIn->nSdst); + ExplainQueryPlan((pParse, 0, "CREATE BLOOM FILTER")); + } + sqlite3ReleaseTempReg(pParse, r1); + break; + } + + /* If this is a scalar select that is part of an expression, then + ** store the results in the appropriate memory cell and break out + ** of the scan loop. Note that the select might return multiple columns + ** if it is the RHS of a row-value IN operator. + */ + case SRT_Mem: { + testcase( pIn->nSdst>1 ); + sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, pIn->nSdst); + /* The LIMIT clause will jump out of the loop for us */ + break; + } +#endif /* #ifndef SQLITE_OMIT_SUBQUERY */ + + /* The results are stored in a sequence of registers + ** starting at pDest->iSdst. Then the co-routine yields. + */ + case SRT_Coroutine: { + if( pDest->iSdst==0 ){ + pDest->iSdst = sqlite3GetTempRange(pParse, pIn->nSdst); + pDest->nSdst = pIn->nSdst; + } + sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pIn->nSdst); + sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); + break; + } + +#ifndef SQLITE_OMIT_CTE + /* Write the results into a priority queue that is order according to + ** pDest->pOrderBy (in pSO). pDest->iSDParm (in iParm) is the cursor for an + ** index with pSO->nExpr+2 columns. Build a key using pSO for the first + ** pSO->nExpr columns, then make sure all keys are unique by adding a + ** final OP_Sequence column. The last column is the record as a blob. + */ + case SRT_DistQueue: + case SRT_Queue: { + int nKey; + int r1, r2, r3, ii; + ExprList *pSO; + int iParm = pDest->iSDParm; + pSO = pDest->pOrderBy; + assert( pSO ); + nKey = pSO->nExpr; + r1 = sqlite3GetTempReg(pParse); + r2 = sqlite3GetTempRange(pParse, nKey+2); + r3 = r2+nKey+1; + + sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r3); + if( pDest->eDest==SRT_DistQueue ){ + sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r3); + } + for(ii=0; iiiSdst + pSO->a[ii].u.x.iOrderByCol - 1, + r2+ii); + } + sqlite3VdbeAddOp2(v, OP_Sequence, iParm, r2+nKey); + sqlite3VdbeAddOp3(v, OP_MakeRecord, r2, nKey+2, r1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, r2, nKey+2); + sqlite3ReleaseTempReg(pParse, r1); + sqlite3ReleaseTempRange(pParse, r2, nKey+2); + break; + } +#endif /* SQLITE_OMIT_CTE */ + + /* Ignore the output */ + case SRT_Discard: { + break; + } + + /* If none of the above, then the result destination must be + ** SRT_Output. + ** + ** For SRT_Output, results are stored in a sequence of registers. + ** Then the OP_ResultRow opcode is used to cause sqlite3_step() to + ** return the next row of result. + */ + default: { + assert( pDest->eDest==SRT_Output ); + sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iSdst, pIn->nSdst); + break; + } + } + + /* Jump to the end of the loop if the LIMIT is reached. + */ + if( p->iLimit ){ + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v); + } + + /* Generate the subroutine return + */ + sqlite3VdbeResolveLabel(v, iContinue); + sqlite3VdbeAddOp1(v, OP_Return, regReturn); + + return addr; +} + +/* +** Generate code for a compound SELECT statement using a merge +** algorithm. The compound must have an ORDER BY clause for this +** to work. +** +** We assume a query of the following form: +** +** ORDER BY +** +** is one of UNION ALL, UNION, EXCEPT, or INTERSECT. The idea +** is to code both and with the ORDER BY clause as +** co-routines. Then run the co-routines in parallel and merge the results +** into the output. In addition to the two coroutines (called selectA and +** selectB) there are 7 subroutines: +** +** outA: Move the output of the selectA coroutine into the output +** of the compound query. +** +** outB: Move the output of the selectB coroutine into the output +** of the compound query. (Only generated for UNION and +** UNION ALL. EXCEPT and INTERSECT never output a row that +** appears only in B.) +** +** AltB: Called when there is data from both coroutines and AB. +** +** EofA: Called when data is exhausted from selectA. +** +** EofB: Called when data is exhausted from selectB. +** +** The implementation of the latter five subroutines depend on which +** is used: +** +** +** UNION ALL UNION EXCEPT INTERSECT +** ------------- ----------------- -------------- ----------------- +** AltB: outA, nextA outA, nextA outA, nextA nextA +** +** AeqB: outA, nextA nextA nextA outA, nextA +** +** AgtB: outB, nextB outB, nextB nextB nextB +** +** EofA: outB, nextB outB, nextB halt halt +** +** EofB: outA, nextA outA, nextA outA, nextA halt +** +** In the AltB, AeqB, and AgtB subroutines, an EOF on A following nextA +** causes an immediate jump to EofA and an EOF on B following nextB causes +** an immediate jump to EofB. Within EofA and EofB, and EOF on entry or +** following nextX causes a jump to the end of the select processing. +** +** Duplicate removal in the UNION, EXCEPT, and INTERSECT cases is handled +** within the output subroutine. The regPrev register set holds the previously +** output value. A comparison is made against this value and the output +** is skipped if the next results would be the same as the previous. +** +** The implementation plan is to implement the two coroutines and seven +** subroutines first, then put the control logic at the bottom. Like this: +** +** goto Init +** coA: coroutine for left query (A) +** coB: coroutine for right query (B) +** outA: output one row of A +** outB: output one row of B (UNION and UNION ALL only) +** EofA: ... +** EofB: ... +** AltB: ... +** AeqB: ... +** AgtB: ... +** Init: initialize coroutine registers +** yield coA, on eof goto EofA +** yield coB, on eof goto EofB +** Cmpr: Compare A, B +** Jump AltB, AeqB, AgtB +** End: ... +** +** We call AltB, AeqB, AgtB, EofA, and EofB "subroutines" but they are not +** actually called using Gosub and they do not Return. EofA and EofB loop +** until all data is exhausted then jump to the "end" label. AltB, AeqB, +** and AgtB jump to either Cmpr or to one of EofA or EofB. +*/ +#ifndef SQLITE_OMIT_COMPOUND_SELECT +static int multiSelectByMerge( + Parse *pParse, /* Parsing context */ + Select *p, /* The right-most of SELECTs to be coded */ + SelectDest *pDest /* What to do with query results */ +){ + int i, j; /* Loop counters */ + Select *pPrior; /* Another SELECT immediately to our left */ + Select *pSplit; /* Left-most SELECT in the right-hand group */ + int nSelect; /* Number of SELECT statements in the compound */ + Vdbe *v; /* Generate code to this VDBE */ + SelectDest destA; /* Destination for coroutine A */ + SelectDest destB; /* Destination for coroutine B */ + int regAddrA; /* Address register for select-A coroutine */ + int regAddrB; /* Address register for select-B coroutine */ + int addrSelectA; /* Address of the select-A coroutine */ + int addrSelectB; /* Address of the select-B coroutine */ + int regOutA; /* Address register for the output-A subroutine */ + int regOutB; /* Address register for the output-B subroutine */ + int addrOutA; /* Address of the output-A subroutine */ + int addrOutB = 0; /* Address of the output-B subroutine */ + int addrEofA; /* Address of the select-A-exhausted subroutine */ + int addrEofA_noB; /* Alternate addrEofA if B is uninitialized */ + int addrEofB; /* Address of the select-B-exhausted subroutine */ + int addrAltB; /* Address of the AB subroutine */ + int regLimitA; /* Limit register for select-A */ + int regLimitB; /* Limit register for select-A */ + int regPrev; /* A range of registers to hold previous output */ + int savedLimit; /* Saved value of p->iLimit */ + int savedOffset; /* Saved value of p->iOffset */ + int labelCmpr; /* Label for the start of the merge algorithm */ + int labelEnd; /* Label for the end of the overall SELECT stmt */ + int addr1; /* Jump instructions that get retargeted */ + int op; /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */ + KeyInfo *pKeyDup = 0; /* Comparison information for duplicate removal */ + KeyInfo *pKeyMerge; /* Comparison information for merging rows */ + sqlite3 *db; /* Database connection */ + ExprList *pOrderBy; /* The ORDER BY clause */ + int nOrderBy; /* Number of terms in the ORDER BY clause */ + u32 *aPermute; /* Mapping from ORDER BY terms to result set columns */ + + assert( p->pOrderBy!=0 ); + assert( pKeyDup==0 ); /* "Managed" code needs this. Ticket #3382. */ + db = pParse->db; + v = pParse->pVdbe; + assert( v!=0 ); /* Already thrown the error if VDBE alloc failed */ + labelEnd = sqlite3VdbeMakeLabel(pParse); + labelCmpr = sqlite3VdbeMakeLabel(pParse); + + + /* Patch up the ORDER BY clause + */ + op = p->op; + assert( p->pPrior->pOrderBy==0 ); + pOrderBy = p->pOrderBy; + assert( pOrderBy ); + nOrderBy = pOrderBy->nExpr; + + /* For operators other than UNION ALL we have to make sure that + ** the ORDER BY clause covers every term of the result set. Add + ** terms to the ORDER BY clause as necessary. + */ + if( op!=TK_ALL ){ + for(i=1; db->mallocFailed==0 && i<=p->pEList->nExpr; i++){ + struct ExprList_item *pItem; + for(j=0, pItem=pOrderBy->a; ju.x.iOrderByCol>0 ); + if( pItem->u.x.iOrderByCol==i ) break; + } + if( j==nOrderBy ){ + Expr *pNew = sqlite3ExprInt32(db, i); + if( pNew==0 ) return SQLITE_NOMEM_BKPT; + p->pOrderBy = pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew); + if( pOrderBy ) pOrderBy->a[nOrderBy++].u.x.iOrderByCol = (u16)i; + } + } + } + + /* Compute the comparison permutation and keyinfo that is used with + ** the permutation to determine if the next row of results comes + ** from selectA or selectB. Also add literal collations to the + ** ORDER BY clause terms so that when selectA and selectB are + ** evaluated, they use the correct collation. + */ + aPermute = sqlite3DbMallocRawNN(db, sizeof(u32)*(nOrderBy + 1)); + if( aPermute ){ + struct ExprList_item *pItem; + int bKeep = 0; + aPermute[0] = nOrderBy; + for(i=1, pItem=pOrderBy->a; i<=nOrderBy; i++, pItem++){ + assert( pItem!=0 ); + assert( pItem->u.x.iOrderByCol>0 ); + assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr ); + aPermute[i] = pItem->u.x.iOrderByCol - 1; + if( aPermute[i]!=(u32)i-1 ) bKeep = 1; + } + if( bKeep==0 ){ + sqlite3DbFreeNN(db, aPermute); + aPermute = 0; + } + } + pKeyMerge = multiSelectByMergeKeyInfo(pParse, p, 1); + + /* Allocate a range of temporary registers and the KeyInfo needed + ** for the logic that removes duplicate result rows when the + ** operator is UNION, EXCEPT, or INTERSECT (but not UNION ALL). + */ + if( op==TK_ALL ){ + regPrev = 0; + }else{ + int nExpr = p->pEList->nExpr; + assert( nOrderBy>=nExpr || db->mallocFailed ); + regPrev = pParse->nMem+1; + pParse->nMem += nExpr+1; + sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev); + pKeyDup = sqlite3KeyInfoAlloc(db, nExpr, 1); + if( pKeyDup ){ + assert( sqlite3KeyInfoIsWriteable(pKeyDup) ); + for(i=0; iaColl[i] = multiSelectCollSeq(pParse, p, i); + pKeyDup->aSortFlags[i] = 0; + } + } + } + + /* Separate the left and the right query from one another + */ + nSelect = 1; + if( (op==TK_ALL || op==TK_UNION) + && OptimizationEnabled(db, SQLITE_BalancedMerge) + ){ + for(pSplit=p; pSplit->pPrior!=0 && pSplit->op==op; pSplit=pSplit->pPrior){ + nSelect++; + assert( pSplit->pPrior->pNext==pSplit ); + } + } + if( nSelect<=3 ){ + pSplit = p; + }else{ + pSplit = p; + for(i=2; ipPrior; } + } + pPrior = pSplit->pPrior; + assert( pPrior!=0 ); + pSplit->pPrior = 0; + pPrior->pNext = 0; + assert( p->pOrderBy == pOrderBy ); + assert( pOrderBy!=0 || db->mallocFailed ); + pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, pOrderBy, 0); + sqlite3ResolveOrderGroupBy(pParse, p, p->pOrderBy, "ORDER"); + sqlite3ResolveOrderGroupBy(pParse, pPrior, pPrior->pOrderBy, "ORDER"); + + /* Compute the limit registers */ + computeLimitRegisters(pParse, p, labelEnd); + if( p->iLimit && op==TK_ALL ){ + regLimitA = ++pParse->nMem; + regLimitB = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Copy, p->iOffset ? p->iOffset+1 : p->iLimit, + regLimitA); + sqlite3VdbeAddOp2(v, OP_Copy, regLimitA, regLimitB); + }else{ + regLimitA = regLimitB = 0; + } + sqlite3ExprDelete(db, p->pLimit); + p->pLimit = 0; + + regAddrA = ++pParse->nMem; + regAddrB = ++pParse->nMem; + regOutA = ++pParse->nMem; + regOutB = ++pParse->nMem; + sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA); + sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB); + + ExplainQueryPlan((pParse, 1, "MERGE (%s)", sqlite3SelectOpName(p->op))); + + /* Generate a coroutine to evaluate the SELECT statement to the + ** left of the compound operator - the "A" select. + */ + addrSelectA = sqlite3VdbeCurrentAddr(v) + 1; + addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA); + VdbeComment((v, "SUBR: next-A")); + pPrior->iLimit = regLimitA; + ExplainQueryPlan((pParse, 1, "LEFT")); + sqlite3Select(pParse, pPrior, &destA); + sqlite3VdbeEndCoroutine(v, regAddrA); + sqlite3VdbeJumpHere(v, addr1); + + /* Generate a coroutine to evaluate the SELECT statement on + ** the right - the "B" select + */ + addrSelectB = sqlite3VdbeCurrentAddr(v) + 1; + addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrB, 0, addrSelectB); + VdbeComment((v, "SUBR: next-B")); + savedLimit = p->iLimit; + savedOffset = p->iOffset; + p->iLimit = regLimitB; + p->iOffset = 0; + ExplainQueryPlan((pParse, 1, "RIGHT")); + sqlite3Select(pParse, p, &destB); + p->iLimit = savedLimit; + p->iOffset = savedOffset; + sqlite3VdbeEndCoroutine(v, regAddrB); + + /* Generate a subroutine that outputs the current row of the A + ** select as the next output row of the compound select. + */ + VdbeNoopComment((v, "SUBR: out-A")); + addrOutA = generateOutputSubroutine(pParse, + p, &destA, pDest, regOutA, + regPrev, pKeyDup, labelEnd); + + /* Generate a subroutine that outputs the current row of the B + ** select as the next output row of the compound select. + */ + if( op==TK_ALL || op==TK_UNION ){ + VdbeNoopComment((v, "SUBR: out-B")); + addrOutB = generateOutputSubroutine(pParse, + p, &destB, pDest, regOutB, + regPrev, pKeyDup, labelEnd); + } + sqlite3KeyInfoUnref(pKeyDup); + + /* Generate a subroutine to run when the results from select A + ** are exhausted and only data in select B remains. + */ + if( op==TK_EXCEPT || op==TK_INTERSECT ){ + addrEofA_noB = addrEofA = labelEnd; + }else{ + VdbeNoopComment((v, "SUBR: eof-A")); + addrEofA = sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); + VdbeComment((v, "out-B")); + addrEofA_noB = sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, labelEnd); + VdbeCoverage(v); + VdbeComment((v, "next-B")); + sqlite3VdbeGoto(v, addrEofA); + p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); + } + + /* Generate a subroutine to run when the results from select B + ** are exhausted and only data in select A remains. + */ + if( op==TK_INTERSECT ){ + addrEofB = addrEofA; + if( p->nSelectRow > pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow; + }else{ + VdbeNoopComment((v, "SUBR: eof-B")); + addrEofB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA); + VdbeComment((v, "out-A")); + sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, labelEnd); VdbeCoverage(v); + VdbeComment((v, "next-A")); + sqlite3VdbeGoto(v, addrEofB); + } + + /* Generate code to handle the case of AB + */ + addrAgtB = sqlite3VdbeCurrentAddr(v); + if( op==TK_ALL || op==TK_UNION ){ + sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); + VdbeComment((v, "out-B")); + sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v); + VdbeComment((v, "next-B")); + sqlite3VdbeGoto(v, labelCmpr); + }else{ + addrAgtB++; /* Just do next-B. Might as well use the next-B call + ** in the next code block */ + } + + /* This code runs once to initialize everything. + */ + sqlite3VdbeJumpHere(v, addr1); + sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA_noB); VdbeCoverage(v); + VdbeComment((v, "next-A")); + /* v--- Also the A>B case for EXCEPT and INTERSECT */ + sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v); + VdbeComment((v, "next-B")); + + /* Implement the main merge loop + */ + if( aPermute!=0 ){ + sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY); + } + sqlite3VdbeResolveLabel(v, labelCmpr); + sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy, + (char*)pKeyMerge, P4_KEYINFO); + if( aPermute!=0 ){ + sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE); + } + sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB); + VdbeCoverageIf(v, op==TK_ALL); + VdbeCoverageIf(v, op==TK_UNION); + VdbeCoverageIf(v, op==TK_EXCEPT); + VdbeCoverageIf(v, op==TK_INTERSECT); + + /* Jump to the this point in order to terminate the query. + */ + sqlite3VdbeResolveLabel(v, labelEnd); + + /* Make arrangements to free the 2nd and subsequent arms of the compound + ** after the parse has finished */ + if( pSplit->pPrior ){ + sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pSplit->pPrior); + } + pSplit->pPrior = pPrior; + pPrior->pNext = pSplit; + sqlite3ExprListDelete(db, pPrior->pOrderBy); + pPrior->pOrderBy = 0; + + /*** TBD: Insert subroutine calls to close cursors on incomplete + **** subqueries ****/ + ExplainQueryPlanPop(pParse); + return pParse->nErr!=0; +} +#endif + +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) + +/* An instance of the SubstContext object describes an substitution edit +** to be performed on a parse tree. +** +** All references to columns in table iTable are to be replaced by corresponding +** expressions in pEList. +** +** ## About "isOuterJoin": +** +** The isOuterJoin column indicates that the replacement will occur into a +** position in the parent that is NULL-able due to an OUTER JOIN. Either the +** target slot in the parent is the right operand of a LEFT JOIN, or one of +** the left operands of a RIGHT JOIN. In either case, we need to potentially +** bypass the substituted expression with OP_IfNullRow. +** +** Suppose the original expression is an integer constant. Even though the table +** has the nullRow flag set, because the expression is an integer constant, +** it will not be NULLed out. So instead, we insert an OP_IfNullRow opcode +** that checks to see if the nullRow flag is set on the table. If the nullRow +** flag is set, then the value in the register is set to NULL and the original +** expression is bypassed. If the nullRow flag is not set, then the original +** expression runs to populate the register. +** +** Example where this is needed: +** +** CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT); +** CREATE TABLE t2(x INT UNIQUE); +** +** SELECT a,b,m,x FROM t1 LEFT JOIN (SELECT 59 AS m,x FROM t2) ON b=x; +** +** When the subquery on the right side of the LEFT JOIN is flattened, we +** have to add OP_IfNullRow in front of the OP_Integer that implements the +** "m" value of the subquery so that a NULL will be loaded instead of 59 +** when processing a non-matched row of the left. +*/ +typedef struct SubstContext { + Parse *pParse; /* The parsing context */ + int iTable; /* Replace references to this table */ + int iNewTable; /* New table number */ + int isOuterJoin; /* Add TK_IF_NULL_ROW opcodes on each replacement */ + int nSelDepth; /* Depth of sub-query recursion. Top==1 */ + ExprList *pEList; /* Replacement expressions */ + ExprList *pCList; /* Collation sequences for replacement expr */ +} SubstContext; + +/* Forward Declarations */ +static void substExprList(SubstContext*, ExprList*); +static void substSelect(SubstContext*, Select*, int); + +/* +** Scan through the expression pExpr. Replace every reference to +** a column in table number iTable with a copy of the iColumn-th +** entry in pEList. (But leave references to the ROWID column +** unchanged.) +** +** This routine is part of the flattening procedure. A subquery +** whose result set is defined by pEList appears as entry in the +** FROM clause of a SELECT such that the VDBE cursor assigned to that +** FORM clause entry is iTable. This routine makes the necessary +** changes to pExpr so that it refers directly to the source table +** of the subquery rather the result set of the subquery. +*/ +static Expr *substExpr( + SubstContext *pSubst, /* Description of the substitution */ + Expr *pExpr /* Expr in which substitution occurs */ +){ + if( pExpr==0 ) return 0; + if( ExprHasProperty(pExpr, EP_OuterON|EP_InnerON) + && pExpr->w.iJoin==pSubst->iTable + ){ + testcase( ExprHasProperty(pExpr, EP_InnerON) ); + pExpr->w.iJoin = pSubst->iNewTable; + } + if( pExpr->op==TK_COLUMN + && pExpr->iTable==pSubst->iTable + && !ExprHasProperty(pExpr, EP_FixedCol) + ){ +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + if( pExpr->iColumn<0 ){ + pExpr->op = TK_NULL; + }else +#endif + { + Expr *pNew; + int iColumn; + Expr *pCopy; + Expr ifNullRow; + iColumn = pExpr->iColumn; + assert( iColumn>=0 ); + assert( pSubst->pEList!=0 && iColumnpEList->nExpr ); + assert( pExpr->pRight==0 ); + pCopy = pSubst->pEList->a[iColumn].pExpr; + if( sqlite3ExprIsVector(pCopy) ){ + sqlite3VectorErrorMsg(pSubst->pParse, pCopy); + }else{ + sqlite3 *db = pSubst->pParse->db; + if( pSubst->isOuterJoin + && (pCopy->op!=TK_COLUMN || pCopy->iTable!=pSubst->iNewTable) + ){ + memset(&ifNullRow, 0, sizeof(ifNullRow)); + ifNullRow.op = TK_IF_NULL_ROW; + ifNullRow.pLeft = pCopy; + ifNullRow.iTable = pSubst->iNewTable; + ifNullRow.iColumn = -99; + ifNullRow.flags = EP_IfNullRow; + pCopy = &ifNullRow; + } + testcase( ExprHasProperty(pCopy, EP_Subquery) ); + pNew = sqlite3ExprDup(db, pCopy, 0); + if( db->mallocFailed ){ + sqlite3ExprDelete(db, pNew); + return pExpr; + } + if( pSubst->isOuterJoin ){ + ExprSetProperty(pNew, EP_CanBeNull); + } + if( pNew->op==TK_TRUEFALSE ){ + pNew->u.iValue = sqlite3ExprTruthValue(pNew); + pNew->op = TK_INTEGER; + ExprSetProperty(pNew, EP_IntValue); + } + + /* Ensure that the expression now has an implicit collation sequence, + ** just as it did when it was a column of a view or sub-query. */ + { + CollSeq *pNat = sqlite3ExprCollSeq(pSubst->pParse, pNew); + CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse, + pSubst->pCList->a[iColumn].pExpr + ); + if( pNat!=pColl || (pNew->op!=TK_COLUMN && pNew->op!=TK_COLLATE) ){ + pNew = sqlite3ExprAddCollateString(pSubst->pParse, pNew, + (pColl ? pColl->zName : "BINARY") + ); + } + } + ExprClearProperty(pNew, EP_Collate); + if( ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) ){ + sqlite3SetJoinExpr(pNew, pExpr->w.iJoin, + pExpr->flags & (EP_OuterON|EP_InnerON)); + } + sqlite3ExprDelete(db, pExpr); + pExpr = pNew; + } + } + }else{ + if( pExpr->op==TK_IF_NULL_ROW && pExpr->iTable==pSubst->iTable ){ + pExpr->iTable = pSubst->iNewTable; + } + if( pExpr->op==TK_AGG_FUNCTION && pExpr->op2>=pSubst->nSelDepth ){ + pExpr->op2--; + } + pExpr->pLeft = substExpr(pSubst, pExpr->pLeft); + pExpr->pRight = substExpr(pSubst, pExpr->pRight); + if( ExprUseXSelect(pExpr) ){ + substSelect(pSubst, pExpr->x.pSelect, 1); + }else{ + substExprList(pSubst, pExpr->x.pList); + } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( ExprHasProperty(pExpr, EP_WinFunc) ){ + Window *pWin = pExpr->y.pWin; + pWin->pFilter = substExpr(pSubst, pWin->pFilter); + substExprList(pSubst, pWin->pPartition); + substExprList(pSubst, pWin->pOrderBy); + } +#endif + } + return pExpr; +} +static void substExprList( + SubstContext *pSubst, /* Description of the substitution */ + ExprList *pList /* List to scan and in which to make substitutes */ +){ + int i; + if( pList==0 ) return; + for(i=0; inExpr; i++){ + pList->a[i].pExpr = substExpr(pSubst, pList->a[i].pExpr); + } +} +static void substSelect( + SubstContext *pSubst, /* Description of the substitution */ + Select *p, /* SELECT statement in which to make substitutions */ + int doPrior /* Do substitutes on p->pPrior too */ +){ + SrcList *pSrc; + SrcItem *pItem; + int i; + if( !p ) return; + pSubst->nSelDepth++; + do{ + substExprList(pSubst, p->pEList); + substExprList(pSubst, p->pGroupBy); + substExprList(pSubst, p->pOrderBy); + p->pHaving = substExpr(pSubst, p->pHaving); + p->pWhere = substExpr(pSubst, p->pWhere); + pSrc = p->pSrc; + assert( pSrc!=0 ); + for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ + if( pItem->fg.isSubquery ){ + substSelect(pSubst, pItem->u4.pSubq->pSelect, 1); + } + if( pItem->fg.isTabFunc ){ + substExprList(pSubst, pItem->u1.pFuncArg); + } + } + }while( doPrior && (p = p->pPrior)!=0 ); + pSubst->nSelDepth--; +} +#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ + +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) +/* +** pSelect is a SELECT statement and pSrcItem is one item in the FROM +** clause of that SELECT. +** +** This routine scans the entire SELECT statement and recomputes the +** pSrcItem->colUsed mask. +*/ +static int recomputeColumnsUsedExpr(Walker *pWalker, Expr *pExpr){ + SrcItem *pItem; + if( pExpr->op!=TK_COLUMN ) return WRC_Continue; + pItem = pWalker->u.pSrcItem; + if( pItem->iCursor!=pExpr->iTable ) return WRC_Continue; + if( pExpr->iColumn<0 ) return WRC_Continue; + pItem->colUsed |= sqlite3ExprColUsed(pExpr); + return WRC_Continue; +} +static void recomputeColumnsUsed( + Select *pSelect, /* The complete SELECT statement */ + SrcItem *pSrcItem /* Which FROM clause item to recompute */ +){ + Walker w; + if( NEVER(pSrcItem->pSTab==0) ) return; + memset(&w, 0, sizeof(w)); + w.xExprCallback = recomputeColumnsUsedExpr; + w.xSelectCallback = sqlite3SelectWalkNoop; + w.u.pSrcItem = pSrcItem; + pSrcItem->colUsed = 0; + sqlite3WalkSelect(&w, pSelect); +} +#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ + +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) +/* +** Assign new cursor numbers to each of the items in pSrc. For each +** new cursor number assigned, set an entry in the aCsrMap[] array +** to map the old cursor number to the new: +** +** aCsrMap[iOld+1] = iNew; +** +** The array is guaranteed by the caller to be large enough for all +** existing cursor numbers in pSrc. aCsrMap[0] is the array size. +** +** If pSrc contains any sub-selects, call this routine recursively +** on the FROM clause of each such sub-select, with iExcept set to -1. +*/ +static void srclistRenumberCursors( + Parse *pParse, /* Parse context */ + int *aCsrMap, /* Array to store cursor mappings in */ + SrcList *pSrc, /* FROM clause to renumber */ + int iExcept /* FROM clause item to skip */ +){ + int i; + SrcItem *pItem; + for(i=0, pItem=pSrc->a; inSrc; i++, pItem++){ + if( i!=iExcept ){ + Select *p; + assert( pItem->iCursor < aCsrMap[0] ); + if( !pItem->fg.isRecursive || aCsrMap[pItem->iCursor+1]==0 ){ + aCsrMap[pItem->iCursor+1] = pParse->nTab++; + } + pItem->iCursor = aCsrMap[pItem->iCursor+1]; + if( pItem->fg.isSubquery ){ + for(p=pItem->u4.pSubq->pSelect; p; p=p->pPrior){ + srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1); + } + } + } + } +} + +/* +** *piCursor is a cursor number. Change it if it needs to be mapped. +*/ +static void renumberCursorDoMapping(Walker *pWalker, int *piCursor){ + int *aCsrMap = pWalker->u.aiCol; + int iCsr = *piCursor; + if( iCsr < aCsrMap[0] && aCsrMap[iCsr+1]>0 ){ + *piCursor = aCsrMap[iCsr+1]; + } +} + +/* +** Expression walker callback used by renumberCursors() to update +** Expr objects to match newly assigned cursor numbers. +*/ +static int renumberCursorsCb(Walker *pWalker, Expr *pExpr){ + int op = pExpr->op; + if( op==TK_COLUMN || op==TK_IF_NULL_ROW ){ + renumberCursorDoMapping(pWalker, &pExpr->iTable); + } + if( ExprHasProperty(pExpr, EP_OuterON) ){ + renumberCursorDoMapping(pWalker, &pExpr->w.iJoin); + } + return WRC_Continue; +} + +/* +** Assign a new cursor number to each cursor in the FROM clause (Select.pSrc) +** of the SELECT statement passed as the second argument, and to each +** cursor in the FROM clause of any FROM clause sub-selects, recursively. +** Except, do not assign a new cursor number to the iExcept'th element in +** the FROM clause of (*p). Update all expressions and other references +** to refer to the new cursor numbers. +** +** Argument aCsrMap is an array that may be used for temporary working +** space. Two guarantees are made by the caller: +** +** * the array is larger than the largest cursor number used within the +** select statement passed as an argument, and +** +** * the array entries for all cursor numbers that do *not* appear in +** FROM clauses of the select statement as described above are +** initialized to zero. +*/ +static void renumberCursors( + Parse *pParse, /* Parse context */ + Select *p, /* Select to renumber cursors within */ + int iExcept, /* FROM clause item to skip */ + int *aCsrMap /* Working space */ +){ + Walker w; + srclistRenumberCursors(pParse, aCsrMap, p->pSrc, iExcept); + memset(&w, 0, sizeof(w)); + w.u.aiCol = aCsrMap; + w.xExprCallback = renumberCursorsCb; + w.xSelectCallback = sqlite3SelectWalkNoop; + sqlite3WalkSelect(&w, p); +} +#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ + +/* +** If pSel is not part of a compound SELECT, return a pointer to its +** expression list. Otherwise, return a pointer to the expression list +** of the leftmost SELECT in the compound. +*/ +static ExprList *findLeftmostExprlist(Select *pSel){ + while( pSel->pPrior ){ + pSel = pSel->pPrior; + } + return pSel->pEList; +} + +/* +** Return true if any of the result-set columns in the compound query +** have incompatible affinities on one or more arms of the compound. +*/ +static int compoundHasDifferentAffinities(Select *p){ + int ii; + ExprList *pList; + assert( p!=0 ); + assert( p->pEList!=0 ); + assert( p->pPrior!=0 ); + pList = p->pEList; + for(ii=0; iinExpr; ii++){ + char aff; + Select *pSub1; + assert( pList->a[ii].pExpr!=0 ); + aff = sqlite3ExprAffinity(pList->a[ii].pExpr); + for(pSub1=p->pPrior; pSub1; pSub1=pSub1->pPrior){ + assert( pSub1->pEList!=0 ); + assert( pSub1->pEList->nExpr>ii ); + assert( pSub1->pEList->a[ii].pExpr!=0 ); + if( sqlite3ExprAffinity(pSub1->pEList->a[ii].pExpr)!=aff ){ + return 1; + } + } + } + return 0; +} + +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) +/* +** This routine attempts to flatten subqueries as a performance optimization. +** This routine returns 1 if it makes changes and 0 if no flattening occurs. +** +** To understand the concept of flattening, consider the following +** query: +** +** SELECT a FROM (SELECT x+y AS a FROM t1 WHERE z<100) WHERE a>5 +** +** The default way of implementing this query is to execute the +** subquery first and store the results in a temporary table, then +** run the outer query on that temporary table. This requires two +** passes over the data. Furthermore, because the temporary table +** has no indices, the WHERE clause on the outer query cannot be +** optimized. +** +** This routine attempts to rewrite queries such as the above into +** a single flat select, like this: +** +** SELECT x+y AS a FROM t1 WHERE z<100 AND a>5 +** +** The code generated for this simplification gives the same result +** but only has to scan the data once. And because indices might +** exist on the table t1, a complete scan of the data might be +** avoided. +** +** Flattening is subject to the following constraints: +** +** (**) We no longer attempt to flatten aggregate subqueries. Was: +** The subquery and the outer query cannot both be aggregates. +** +** (**) We no longer attempt to flatten aggregate subqueries. Was: +** (2) If the subquery is an aggregate then +** (2a) the outer query must not be a join and +** (2b) the outer query must not use subqueries +** other than the one FROM-clause subquery that is a candidate +** for flattening. (This is due to ticket [2f7170d73bf9abf80] +** from 2015-02-09.) +** +** (3) If the subquery is the right operand of a LEFT JOIN then +** (3a) the subquery may not be a join +** (**) Was (3b): "the FROM clause of the subquery may not contain +** a virtual table" +** (**) Was: "The outer query may not have a GROUP BY." This case +** is now managed correctly +** (3d) the outer query may not be DISTINCT. +** See also (26) for restrictions on RIGHT JOIN. +** +** (4) The subquery can not be DISTINCT. +** +** (**) At one point restrictions (4) and (5) defined a subset of DISTINCT +** sub-queries that were excluded from this optimization. Restriction +** (4) has since been expanded to exclude all DISTINCT subqueries. +** +** (**) We no longer attempt to flatten aggregate subqueries. Was: +** If the subquery is aggregate, the outer query may not be DISTINCT. +** +** (7) The subquery must have a FROM clause. TODO: For subqueries without +** A FROM clause, consider adding a FROM clause with the special +** table sqlite_once that consists of a single row containing a +** single NULL. +** +** (8) If the subquery uses LIMIT then the outer query may not be a join. +** +** (9) If the subquery uses LIMIT then the outer query may not be aggregate. +** +** (**) Restriction (10) was removed from the code on 2005-02-05 but we +** accidentally carried the comment forward until 2014-09-15. Original +** constraint: "If the subquery is aggregate then the outer query +** may not use LIMIT." +** +** (11) The subquery and the outer query may not both have ORDER BY clauses. +** +** (**) Not implemented. Subsumed into restriction (3). Was previously +** a separate restriction deriving from ticket #350. +** +** (13) The subquery and outer query may not both use LIMIT. +** +** (14) The subquery may not use OFFSET. +** +** (15) If the outer query is part of a compound select, then the +** subquery may not use LIMIT. +** (See ticket #2339 and ticket [02a8e81d44]). +** +** (16) If the outer query is aggregate, then the subquery may not +** use ORDER BY. (Ticket #2942) This used to not matter +** until we introduced the group_concat() function. +** +** (17) If the subquery is a compound select, then +** (17a) all compound operators must be a UNION ALL, and +** (17b) no terms within the subquery compound may be aggregate +** or DISTINCT, and +** (17c) every term within the subquery compound must have a FROM clause +** (17d) the outer query may not be +** (17d1) aggregate, or +** (17d2) DISTINCT +** (17e) the subquery may not contain window functions, and +** (17f) the subquery must not be the RHS of a LEFT JOIN. +** (17g) either the subquery is the first element of the outer +** query or there are no RIGHT or FULL JOINs in any arm +** of the subquery. (This is a duplicate of condition (27b).) +** (17h) The corresponding result set expressions in all arms of the +** compound must have the same affinity. +** +** The parent and sub-query may contain WHERE clauses. Subject to +** rules (11), (13) and (14), they may also contain ORDER BY, +** LIMIT and OFFSET clauses. The subquery cannot use any compound +** operator other than UNION ALL because all the other compound +** operators have an implied DISTINCT which is disallowed by +** restriction (4). +** +** Also, each component of the sub-query must return the same number +** of result columns. This is actually a requirement for any compound +** SELECT statement, but all the code here does is make sure that no +** such (illegal) sub-query is flattened. The caller will detect the +** syntax error and return a detailed message. +** +** (18) If the sub-query is a compound select, then all terms of the +** ORDER BY clause of the parent must be copies of a term returned +** by the parent query. +** +** (19) If the subquery uses LIMIT then the outer query may not +** have a WHERE clause. +** +** (20) If the sub-query is a compound select, then it must not use +** an ORDER BY clause. Ticket #3773. We could relax this constraint +** somewhat by saying that the terms of the ORDER BY clause must +** appear as unmodified result columns in the outer query. But we +** have other optimizations in mind to deal with that case. +** +** (21) If the subquery uses LIMIT then the outer query may not be +** DISTINCT. (See ticket [752e1646fc]). +** +** (22) The subquery may not be a recursive CTE. +** +** (23) If the outer query is a recursive CTE, then the sub-query may not be +** a compound query. This restriction is because transforming the +** parent to a compound query confuses the code that handles +** recursive queries in multiSelect(). +** +** (**) We no longer attempt to flatten aggregate subqueries. Was: +** The subquery may not be an aggregate that uses the built-in min() or +** or max() functions. (Without this restriction, a query like: +** "SELECT x FROM (SELECT max(y), x FROM t1)" would not necessarily +** return the value X for which Y was maximal.) +** +** (25) If either the subquery or the parent query contains a window +** function in the select list or ORDER BY clause, flattening +** is not attempted. +** +** (26) The subquery may not be the right operand of a RIGHT JOIN. +** See also (3) for restrictions on LEFT JOIN. +** +** (27) The subquery may not contain a FULL or RIGHT JOIN unless it +** is the first element of the parent query. Two subcases: +** (27a) the subquery is not a compound query. +** (27b) the subquery is a compound query and the RIGHT JOIN occurs +** in any arm of the compound query. (See also (17g).) +** +** (28) The subquery is not a MATERIALIZED CTE. (This is handled +** in the caller before ever reaching this routine.) +** +** +** In this routine, the "p" parameter is a pointer to the outer query. +** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query +** uses aggregates. +** +** If flattening is not attempted, this routine is a no-op and returns 0. +** If flattening is attempted this routine returns 1. +** +** All of the expression analysis must occur on both the outer query and +** the subquery before this routine runs. +*/ +static int flattenSubquery( + Parse *pParse, /* Parsing context */ + Select *p, /* The parent or outer SELECT statement */ + int iFrom, /* Index in p->pSrc->a[] of the inner subquery */ + int isAgg /* True if outer SELECT uses aggregate functions */ +){ + const char *zSavedAuthContext = pParse->zAuthContext; + Select *pParent; /* Current UNION ALL term of the other query */ + Select *pSub; /* The inner query or "subquery" */ + Select *pSub1; /* Pointer to the rightmost select in sub-query */ + SrcList *pSrc; /* The FROM clause of the outer query */ + SrcList *pSubSrc; /* The FROM clause of the subquery */ + int iParent; /* VDBE cursor number of the pSub result set temp table */ + int iNewParent = -1;/* Replacement table for iParent */ + int isOuterJoin = 0; /* True if pSub is the right side of a LEFT JOIN */ + int i; /* Loop counter */ + Expr *pWhere; /* The WHERE clause */ + SrcItem *pSubitem; /* The subquery */ + sqlite3 *db = pParse->db; + Walker w; /* Walker to persist agginfo data */ + int *aCsrMap = 0; + + /* Check to see if flattening is permitted. Return 0 if not. + */ + assert( p!=0 ); + assert( p->pPrior==0 ); + if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0; + pSrc = p->pSrc; + assert( pSrc && iFrom>=0 && iFromnSrc ); + pSubitem = &pSrc->a[iFrom]; + iParent = pSubitem->iCursor; + assert( pSubitem->fg.isSubquery ); + pSub = pSubitem->u4.pSubq->pSelect; + assert( pSub!=0 ); + +#ifndef SQLITE_OMIT_WINDOWFUNC + if( p->pWin || pSub->pWin ) return 0; /* Restriction (25) */ +#endif + + pSubSrc = pSub->pSrc; + assert( pSubSrc ); + /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants, + ** not arbitrary expressions, we allowed some combining of LIMIT and OFFSET + ** because they could be computed at compile-time. But when LIMIT and OFFSET + ** became arbitrary expressions, we were forced to add restrictions (13) + ** and (14). */ + if( pSub->pLimit && p->pLimit ) return 0; /* Restriction (13) */ + if( pSub->pLimit && pSub->pLimit->pRight ) return 0; /* Restriction (14) */ + if( (p->selFlags & SF_Compound)!=0 && pSub->pLimit ){ + return 0; /* Restriction (15) */ + } + if( pSubSrc->nSrc==0 ) return 0; /* Restriction (7) */ + if( pSub->selFlags & SF_Distinct ) return 0; /* Restriction (4) */ + if( pSub->pLimit && (pSrc->nSrc>1 || isAgg) ){ + return 0; /* Restrictions (8)(9) */ + } + if( p->pOrderBy && pSub->pOrderBy ){ + return 0; /* Restriction (11) */ + } + if( isAgg && pSub->pOrderBy ) return 0; /* Restriction (16) */ + if( pSub->pLimit && p->pWhere ) return 0; /* Restriction (19) */ + if( pSub->pLimit && (p->selFlags & SF_Distinct)!=0 ){ + return 0; /* Restriction (21) */ + } + if( pSub->selFlags & (SF_Recursive) ){ + return 0; /* Restrictions (22) */ + } + + /* + ** If the subquery is the right operand of a LEFT JOIN, then the + ** subquery may not be a join itself (3a). Example of why this is not + ** allowed: + ** + ** t1 LEFT OUTER JOIN (t2 JOIN t3) + ** + ** If we flatten the above, we would get + ** + ** (t1 LEFT OUTER JOIN t2) JOIN t3 + ** + ** which is not at all the same thing. + ** + ** See also tickets #306, #350, and #3300. + */ + if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){ + if( pSubSrc->nSrc>1 /* (3a) */ + /**** || IsVirtual(pSubSrc->a[0].pSTab) (3b)-omitted */ + || (p->selFlags & SF_Distinct)!=0 /* (3d) */ + || (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */ + ){ + return 0; + } + isOuterJoin = 1; + } + + assert( pSubSrc->nSrc>0 ); /* True by restriction (7) */ + if( iFrom>0 && (pSubSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ + return 0; /* Restriction (27a) */ + } + + /* Condition (28) is blocked by the caller */ + assert( !pSubitem->fg.isCte || pSubitem->u2.pCteUse->eM10d!=M10d_Yes ); + + /* Restriction (17): If the sub-query is a compound SELECT, then it must + ** use only the UNION ALL operator. And none of the simple select queries + ** that make up the compound SELECT are allowed to be aggregate or distinct + ** queries. + */ + if( pSub->pPrior ){ + int ii; + if( pSub->pOrderBy ){ + return 0; /* Restriction (20) */ + } + if( isAgg || (p->selFlags & SF_Distinct)!=0 || isOuterJoin>0 ){ + return 0; /* (17d1), (17d2), or (17f) */ + } + for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){ + testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ); + testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate ); + assert( pSub->pSrc!=0 ); + assert( (pSub->selFlags & SF_Recursive)==0 ); + assert( pSub->pEList->nExpr==pSub1->pEList->nExpr ); + if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0 /* (17b) */ + || (pSub1->pPrior && pSub1->op!=TK_ALL) /* (17a) */ + || pSub1->pSrc->nSrc<1 /* (17c) */ +#ifndef SQLITE_OMIT_WINDOWFUNC + || pSub1->pWin /* (17e) */ +#endif + ){ + return 0; + } + if( iFrom>0 && (pSub1->pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ + /* Without this restriction, the JT_LTORJ flag would end up being + ** omitted on left-hand tables of the right join that is being + ** flattened. */ + return 0; /* Restrictions (17g), (27b) */ + } + testcase( pSub1->pSrc->nSrc>1 ); + } + + /* Restriction (18). */ + if( p->pOrderBy ){ + for(ii=0; iipOrderBy->nExpr; ii++){ + if( p->pOrderBy->a[ii].u.x.iOrderByCol==0 ) return 0; + } + } + + /* Restriction (23) */ + if( (p->selFlags & SF_Recursive) ) return 0; + + /* Restriction (17h) */ + if( compoundHasDifferentAffinities(pSub) ) return 0; + + if( pSrc->nSrc>1 ){ + if( pParse->nSelect>500 ) return 0; + if( OptimizationDisabled(db, SQLITE_FlttnUnionAll) ) return 0; + aCsrMap = sqlite3DbMallocZero(db, ((i64)pParse->nTab+1)*sizeof(int)); + if( aCsrMap ) aCsrMap[0] = pParse->nTab; + } + } + + /***** If we reach this point, flattening is permitted. *****/ + TREETRACE(0x4,pParse,p,("flatten %u.%p from term %d\n", + pSub->selId, pSub, iFrom)); + + /* Authorize the subquery */ + pParse->zAuthContext = pSubitem->zName; + TESTONLY(i =) sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0); + testcase( i==SQLITE_DENY ); + pParse->zAuthContext = zSavedAuthContext; + + /* Delete the transient structures associated with the subquery */ + + if( ALWAYS(pSubitem->fg.isSubquery) ){ + pSub1 = sqlite3SubqueryDetach(db, pSubitem); + }else{ + pSub1 = 0; + } + assert( pSubitem->fg.isSubquery==0 ); + assert( pSubitem->fg.fixedSchema==0 ); + sqlite3DbFree(db, pSubitem->zName); + sqlite3DbFree(db, pSubitem->zAlias); + pSubitem->zName = 0; + pSubitem->zAlias = 0; + assert( pSubitem->fg.isUsing!=0 || pSubitem->u3.pOn==0 ); + + /* If the sub-query is a compound SELECT statement, then (by restrictions + ** 17 and 18 above) it must be a UNION ALL and the parent query must + ** be of the form: + ** + ** SELECT FROM () + ** + ** followed by any ORDER BY, LIMIT and/or OFFSET clauses. This block + ** creates N-1 copies of the parent query without any ORDER BY, LIMIT or + ** OFFSET clauses and joins them to the left-hand-side of the original + ** using UNION ALL operators. In this case N is the number of simple + ** select statements in the compound sub-query. + ** + ** Example: + ** + ** SELECT a+1 FROM ( + ** SELECT x FROM tab + ** UNION ALL + ** SELECT y FROM tab + ** UNION ALL + ** SELECT abs(z*2) FROM tab2 + ** ) WHERE a!=5 ORDER BY 1 + ** + ** Transformed into: + ** + ** SELECT x+1 FROM tab WHERE x+1!=5 + ** UNION ALL + ** SELECT y+1 FROM tab WHERE y+1!=5 + ** UNION ALL + ** SELECT abs(z*2)+1 FROM tab2 WHERE abs(z*2)+1!=5 + ** ORDER BY 1 + ** + ** We call this the "compound-subquery flattening". + */ + for(pSub=pSub->pPrior; pSub; pSub=pSub->pPrior){ + Select *pNew; + ExprList *pOrderBy = p->pOrderBy; + Expr *pLimit = p->pLimit; + Select *pPrior = p->pPrior; + Table *pItemTab = pSubitem->pSTab; + pSubitem->pSTab = 0; + p->pOrderBy = 0; + p->pPrior = 0; + p->pLimit = 0; + pNew = sqlite3SelectDup(db, p, 0); + p->pLimit = pLimit; + p->pOrderBy = pOrderBy; + p->op = TK_ALL; + pSubitem->pSTab = pItemTab; + if( pNew==0 ){ + p->pPrior = pPrior; + }else{ + pNew->selId = ++pParse->nSelect; + if( aCsrMap && ALWAYS(db->mallocFailed==0) ){ + renumberCursors(pParse, pNew, iFrom, aCsrMap); + } + pNew->pPrior = pPrior; + if( pPrior ) pPrior->pNext = pNew; + pNew->pNext = p; + p->pPrior = pNew; + TREETRACE(0x4,pParse,p,("compound-subquery flattener" + " creates %u as peer\n",pNew->selId)); + } + assert( pSubitem->fg.isSubquery==0 ); + } + sqlite3DbFree(db, aCsrMap); + if( db->mallocFailed ){ + assert( pSubitem->fg.fixedSchema==0 ); + assert( pSubitem->fg.isSubquery==0 ); + assert( pSubitem->u4.zDatabase==0 ); + sqlite3SrcItemAttachSubquery(pParse, pSubitem, pSub1, 0); + return 1; + } + + /* Defer deleting the Table object associated with the + ** subquery until code generation is + ** complete, since there may still exist Expr.pTab entries that + ** refer to the subquery even after flattening. Ticket #3346. + ** + ** pSubitem->pSTab is always non-NULL by test restrictions and tests above. + */ + if( ALWAYS(pSubitem->pSTab!=0) ){ + Table *pTabToDel = pSubitem->pSTab; + if( pTabToDel->nTabRef==1 ){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + sqlite3ParserAddCleanup(pToplevel, sqlite3DeleteTableGeneric, pTabToDel); + testcase( pToplevel->earlyCleanup ); + }else{ + pTabToDel->nTabRef--; + } + pSubitem->pSTab = 0; + } + + /* The following loop runs once for each term in a compound-subquery + ** flattening (as described above). If we are doing a different kind + ** of flattening - a flattening other than a compound-subquery flattening - + ** then this loop only runs once. + ** + ** This loop moves all of the FROM elements of the subquery into the + ** the FROM clause of the outer query. Before doing this, remember + ** the cursor number for the original outer query FROM element in + ** iParent. The iParent cursor will never be used. Subsequent code + ** will scan expressions looking for iParent references and replace + ** those references with expressions that resolve to the subquery FROM + ** elements we are now copying in. + */ + pSub = pSub1; + for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){ + int nSubSrc; + u8 jointype = pSubitem->fg.jointype; + assert( pSub!=0 ); + pSubSrc = pSub->pSrc; /* FROM clause of subquery */ + nSubSrc = pSubSrc->nSrc; /* Number of terms in subquery FROM clause */ + pSrc = pParent->pSrc; /* FROM clause of the outer query */ + + /* The subquery uses a single slot of the FROM clause of the outer + ** query. If the subquery has more than one element in its FROM clause, + ** then expand the outer query to make space for it to hold all elements + ** of the subquery. + ** + ** Example: + ** + ** SELECT * FROM tabA, (SELECT * FROM sub1, sub2), tabB; + ** + ** The outer query has 3 slots in its FROM clause. One slot of the + ** outer query (the middle slot) is used by the subquery. The next + ** block of code will expand the outer query FROM clause to 4 slots. + ** The middle slot is expanded to two slots in order to make space + ** for the two elements in the FROM clause of the subquery. + */ + if( nSubSrc>1 ){ + pSrc = sqlite3SrcListEnlarge(pParse, pSrc, nSubSrc-1,iFrom+1); + if( pSrc==0 ) break; + pParent->pSrc = pSrc; + pSubitem = &pSrc->a[iFrom]; + } + + /* Transfer the FROM clause terms from the subquery into the + ** outer query. + */ + iNewParent = pSubSrc->a[0].iCursor; + for(i=0; ia[i+iFrom]; + assert( pItem->fg.isTabFunc==0 ); + assert( pItem->fg.isSubquery + || pItem->fg.fixedSchema + || pItem->u4.zDatabase==0 ); + if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing); + *pItem = pSubSrc->a[i]; + pItem->fg.jointype |= (jointype & JT_LTORJ); + memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i])); + } + pSubitem->fg.jointype |= jointype; + + /* Begin substituting subquery result set expressions for + ** references to the iParent in the outer query. + ** + ** Example: + ** + ** SELECT a+5, b*10 FROM (SELECT x*3 AS a, y+10 AS b FROM t1) WHERE a>b; + ** \ \_____________ subquery __________/ / + ** \_____________________ outer query ______________________________/ + ** + ** We look at every expression in the outer query and every place we see + ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10". + */ + if( pSub->pOrderBy ){ + /* At this point, any non-zero iOrderByCol values indicate that the + ** ORDER BY column expression is identical to the iOrderByCol'th + ** expression returned by SELECT statement pSub. Since these values + ** do not necessarily correspond to columns in SELECT statement pParent, + ** zero them before transferring the ORDER BY clause. + ** + ** Not doing this may cause an error if a subsequent call to this + ** function attempts to flatten a compound sub-query into pParent. + ** See ticket [d11a6e908f]. + */ + ExprList *pOrderBy = pSub->pOrderBy; + for(i=0; inExpr; i++){ + pOrderBy->a[i].u.x.iOrderByCol = 0; + } + assert( pParent->pOrderBy==0 ); + pParent->pOrderBy = pOrderBy; + pSub->pOrderBy = 0; + } + pWhere = pSub->pWhere; + pSub->pWhere = 0; + if( isOuterJoin>0 ){ + assert( pSubSrc->nSrc==1 ); + sqlite3SetJoinExpr(pWhere, iNewParent, EP_OuterON); + } + if( pWhere ){ + if( pParent->pWhere ){ + pParent->pWhere = sqlite3PExpr(pParse, TK_AND, pWhere, pParent->pWhere); + }else{ + pParent->pWhere = pWhere; + } + } + if( db->mallocFailed==0 ){ + SubstContext x; + x.pParse = pParse; + x.iTable = iParent; + x.iNewTable = iNewParent; + x.isOuterJoin = isOuterJoin; + x.nSelDepth = 0; + x.pEList = pSub->pEList; + x.pCList = findLeftmostExprlist(pSub); + substSelect(&x, pParent, 0); + } + + /* The flattened query is a compound if either the inner or the + ** outer query is a compound. */ + pParent->selFlags |= pSub->selFlags & SF_Compound; + assert( (pSub->selFlags & SF_Distinct)==0 ); /* restriction (17b) */ + + /* + ** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y; + ** + ** One is tempted to try to add a and b to combine the limits. But this + ** does not work if either limit is negative. + */ + if( pSub->pLimit ){ + pParent->pLimit = pSub->pLimit; + pSub->pLimit = 0; + } + + /* Recompute the SrcItem.colUsed masks for the flattened + ** tables. */ + for(i=0; ia[i+iFrom]); + } + } + + /* Finally, delete what is left of the subquery and return success. + */ + sqlite3AggInfoPersistWalkerInit(&w, pParse); + sqlite3WalkSelect(&w,pSub1); + sqlite3SelectDelete(db, pSub1); + +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x4 ){ + TREETRACE(0x4,pParse,p,("After flattening:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif + + return 1; +} +#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ + +/* +** A structure to keep track of all of the column values that are fixed to +** a known value due to WHERE clause constraints of the form COLUMN=VALUE. +*/ +typedef struct WhereConst WhereConst; +struct WhereConst { + Parse *pParse; /* Parsing context */ + u8 *pOomFault; /* Pointer to pParse->db->mallocFailed */ + int nConst; /* Number for COLUMN=CONSTANT terms */ + int nChng; /* Number of times a constant is propagated */ + int bHasAffBlob; /* At least one column in apExpr[] as affinity BLOB */ + u32 mExcludeOn; /* Which ON expressions to exclude from considertion. + ** Either EP_OuterON or EP_InnerON|EP_OuterON */ + Expr **apExpr; /* [i*2] is COLUMN and [i*2+1] is VALUE */ +}; + +/* +** Add a new entry to the pConst object. Except, do not add duplicate +** pColumn entries. Also, do not add if doing so would not be appropriate. +** +** The caller guarantees the pColumn is a column and pValue is a constant. +** This routine has to do some additional checks before completing the +** insert. +*/ +static void constInsert( + WhereConst *pConst, /* The WhereConst into which we are inserting */ + Expr *pColumn, /* The COLUMN part of the constraint */ + Expr *pValue, /* The VALUE part of the constraint */ + Expr *pExpr /* Overall expression: COLUMN=VALUE or VALUE=COLUMN */ +){ + int i; + assert( pColumn->op==TK_COLUMN ); + assert( sqlite3ExprIsConstant(pConst->pParse, pValue) ); + + if( ExprHasProperty(pColumn, EP_FixedCol) ) return; + if( sqlite3ExprAffinity(pValue)!=0 ) return; + if( !sqlite3IsBinary(sqlite3ExprCompareCollSeq(pConst->pParse,pExpr)) ){ + return; + } + + /* 2018-10-25 ticket [cf5ed20f] + ** Make sure the same pColumn is not inserted more than once */ + for(i=0; inConst; i++){ + const Expr *pE2 = pConst->apExpr[i*2]; + assert( pE2->op==TK_COLUMN ); + if( pE2->iTable==pColumn->iTable + && pE2->iColumn==pColumn->iColumn + ){ + return; /* Already present. Return without doing anything. */ + } + } + assert( SQLITE_AFF_NONEbHasAffBlob = 1; + } + + pConst->nConst++; + pConst->apExpr = sqlite3DbReallocOrFree(pConst->pParse->db, pConst->apExpr, + pConst->nConst*2*sizeof(Expr*)); + if( pConst->apExpr==0 ){ + pConst->nConst = 0; + }else{ + pConst->apExpr[pConst->nConst*2-2] = pColumn; + pConst->apExpr[pConst->nConst*2-1] = pValue; + } +} + +/* +** Find all terms of COLUMN=VALUE or VALUE=COLUMN in pExpr where VALUE +** is a constant expression and where the term must be true because it +** is part of the AND-connected terms of the expression. For each term +** found, add it to the pConst structure. +*/ +static void findConstInWhere(WhereConst *pConst, Expr *pExpr){ + Expr *pRight, *pLeft; + if( NEVER(pExpr==0) ) return; + if( ExprHasProperty(pExpr, pConst->mExcludeOn) ){ + testcase( ExprHasProperty(pExpr, EP_OuterON) ); + testcase( ExprHasProperty(pExpr, EP_InnerON) ); + return; + } + if( pExpr->op==TK_AND ){ + findConstInWhere(pConst, pExpr->pRight); + findConstInWhere(pConst, pExpr->pLeft); + return; + } + if( pExpr->op!=TK_EQ ) return; + pRight = pExpr->pRight; + pLeft = pExpr->pLeft; + assert( pRight!=0 ); + assert( pLeft!=0 ); + if( pRight->op==TK_COLUMN && sqlite3ExprIsConstant(pConst->pParse, pLeft) ){ + constInsert(pConst,pRight,pLeft,pExpr); + } + if( pLeft->op==TK_COLUMN && sqlite3ExprIsConstant(pConst->pParse, pRight) ){ + constInsert(pConst,pLeft,pRight,pExpr); + } +} + +/* +** This is a helper function for Walker callback propagateConstantExprRewrite(). +** +** Argument pExpr is a candidate expression to be replaced by a value. If +** pExpr is equivalent to one of the columns named in pWalker->u.pConst, +** then overwrite it with the corresponding value. Except, do not do so +** if argument bIgnoreAffBlob is non-zero and the affinity of pExpr +** is SQLITE_AFF_BLOB. +*/ +static int propagateConstantExprRewriteOne( + WhereConst *pConst, + Expr *pExpr, + int bIgnoreAffBlob +){ + int i; + if( pConst->pOomFault[0] ) return WRC_Prune; + if( pExpr->op!=TK_COLUMN ) return WRC_Continue; + if( ExprHasProperty(pExpr, EP_FixedCol|pConst->mExcludeOn) ){ + testcase( ExprHasProperty(pExpr, EP_FixedCol) ); + testcase( ExprHasProperty(pExpr, EP_OuterON) ); + testcase( ExprHasProperty(pExpr, EP_InnerON) ); + return WRC_Continue; + } + for(i=0; inConst; i++){ + Expr *pColumn = pConst->apExpr[i*2]; + if( pColumn==pExpr ) continue; + if( pColumn->iTable!=pExpr->iTable ) continue; + if( pColumn->iColumn!=pExpr->iColumn ) continue; + assert( SQLITE_AFF_NONEnChng++; + ExprClearProperty(pExpr, EP_Leaf); + ExprSetProperty(pExpr, EP_FixedCol); + assert( pExpr->pLeft==0 ); + pExpr->pLeft = sqlite3ExprDup(pConst->pParse->db, pConst->apExpr[i*2+1], 0); + if( pConst->pParse->db->mallocFailed ) return WRC_Prune; + break; + } + return WRC_Prune; +} + +/* +** This is a Walker expression callback. pExpr is a node from the WHERE +** clause of a SELECT statement. This function examines pExpr to see if +** any substitutions based on the contents of pWalker->u.pConst should +** be made to pExpr or its immediate children. +** +** A substitution is made if: +** +** + pExpr is a column with an affinity other than BLOB that matches +** one of the columns in pWalker->u.pConst, or +** +** + pExpr is a binary comparison operator (=, <=, >=, <, >) that +** uses an affinity other than TEXT and one of its immediate +** children is a column that matches one of the columns in +** pWalker->u.pConst. +*/ +static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){ + WhereConst *pConst = pWalker->u.pConst; + assert( TK_GT==TK_EQ+1 ); + assert( TK_LE==TK_EQ+2 ); + assert( TK_LT==TK_EQ+3 ); + assert( TK_GE==TK_EQ+4 ); + if( pConst->bHasAffBlob ){ + if( (pExpr->op>=TK_EQ && pExpr->op<=TK_GE) + || pExpr->op==TK_IS + ){ + propagateConstantExprRewriteOne(pConst, pExpr->pLeft, 0); + if( pConst->pOomFault[0] ) return WRC_Prune; + if( sqlite3ExprAffinity(pExpr->pLeft)!=SQLITE_AFF_TEXT ){ + propagateConstantExprRewriteOne(pConst, pExpr->pRight, 0); + } + } + } + return propagateConstantExprRewriteOne(pConst, pExpr, pConst->bHasAffBlob); +} + +/* +** The WHERE-clause constant propagation optimization. +** +** If the WHERE clause contains terms of the form COLUMN=CONSTANT or +** CONSTANT=COLUMN that are top-level AND-connected terms that are not +** part of a ON clause from a LEFT JOIN, then throughout the query +** replace all other occurrences of COLUMN with CONSTANT. +** +** For example, the query: +** +** SELECT * FROM t1, t2, t3 WHERE t1.a=39 AND t2.b=t1.a AND t3.c=t2.b +** +** Is transformed into +** +** SELECT * FROM t1, t2, t3 WHERE t1.a=39 AND t2.b=39 AND t3.c=39 +** +** Return true if any transformations where made and false if not. +** +** Implementation note: Constant propagation is tricky due to affinity +** and collating sequence interactions. Consider this example: +** +** CREATE TABLE t1(a INT,b TEXT); +** INSERT INTO t1 VALUES(123,'0123'); +** SELECT * FROM t1 WHERE a=123 AND b=a; +** SELECT * FROM t1 WHERE a=123 AND b=123; +** +** The two SELECT statements above should return different answers. b=a +** is always true because the comparison uses numeric affinity, but b=123 +** is false because it uses text affinity and '0123' is not the same as '123'. +** To work around this, the expression tree is not actually changed from +** "b=a" to "b=123" but rather the "a" in "b=a" is tagged with EP_FixedCol +** and the "123" value is hung off of the pLeft pointer. Code generator +** routines know to generate the constant "123" instead of looking up the +** column value. Also, to avoid collation problems, this optimization is +** only attempted if the "a=123" term uses the default BINARY collation. +** +** 2021-05-25 forum post 6a06202608: Another troublesome case is... +** +** CREATE TABLE t1(x); +** INSERT INTO t1 VALUES(10.0); +** SELECT 1 FROM t1 WHERE x=10 AND x LIKE 10; +** +** The query should return no rows, because the t1.x value is '10.0' not '10' +** and '10.0' is not LIKE '10'. But if we are not careful, the first WHERE +** term "x=10" will cause the second WHERE term to become "10 LIKE 10", +** resulting in a false positive. To avoid this, constant propagation for +** columns with BLOB affinity is only allowed if the constant is used with +** operators ==, <=, <, >=, >, or IS in a way that will cause the correct +** type conversions to occur. See logic associated with the bHasAffBlob flag +** for details. +*/ +static int propagateConstants( + Parse *pParse, /* The parsing context */ + Select *p /* The query in which to propagate constants */ +){ + WhereConst x; + Walker w; + int nChng = 0; + x.pParse = pParse; + x.pOomFault = &pParse->db->mallocFailed; + do{ + x.nConst = 0; + x.nChng = 0; + x.apExpr = 0; + x.bHasAffBlob = 0; + if( ALWAYS(p->pSrc!=0) + && p->pSrc->nSrc>0 + && (p->pSrc->a[0].fg.jointype & JT_LTORJ)!=0 + ){ + /* Do not propagate constants on any ON clause if there is a + ** RIGHT JOIN anywhere in the query */ + x.mExcludeOn = EP_InnerON | EP_OuterON; + }else{ + /* Do not propagate constants through the ON clause of a LEFT JOIN */ + x.mExcludeOn = EP_OuterON; + } + findConstInWhere(&x, p->pWhere); + if( x.nConst ){ + memset(&w, 0, sizeof(w)); + w.pParse = pParse; + w.xExprCallback = propagateConstantExprRewrite; + w.xSelectCallback = sqlite3SelectWalkNoop; + w.xSelectCallback2 = 0; + w.walkerDepth = 0; + w.u.pConst = &x; + sqlite3WalkExpr(&w, p->pWhere); + sqlite3DbFree(x.pParse->db, x.apExpr); + nChng += x.nChng; + } + }while( x.nChng ); + return nChng; +} + +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) +# if !defined(SQLITE_OMIT_WINDOWFUNC) +/* +** This function is called to determine whether or not it is safe to +** push WHERE clause expression pExpr down to FROM clause sub-query +** pSubq, which contains at least one window function. Return 1 +** if it is safe and the expression should be pushed down, or 0 +** otherwise. +** +** It is only safe to push the expression down if it consists only +** of constants and copies of expressions that appear in the PARTITION +** BY clause of all window function used by the sub-query. It is safe +** to filter out entire partitions, but not rows within partitions, as +** this may change the results of the window functions. +** +** At the time this function is called it is guaranteed that +** +** * the sub-query uses only one distinct window frame, and +** * that the window frame has a PARTITION BY clause. +*/ +static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){ + assert( pSubq->pWin->pPartition ); + assert( (pSubq->selFlags & SF_MultiPart)==0 ); + assert( pSubq->pPrior==0 ); + return sqlite3ExprIsConstantOrGroupBy(pParse, pExpr, pSubq->pWin->pPartition); +} +# endif /* SQLITE_OMIT_WINDOWFUNC */ +#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ + +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) +/* +** Make copies of relevant WHERE clause terms of the outer query into +** the WHERE clause of subquery. Example: +** +** SELECT * FROM (SELECT a AS x, c-d AS y FROM t1) WHERE x=5 AND y=10; +** +** Transformed into: +** +** SELECT * FROM (SELECT a AS x, c-d AS y FROM t1 WHERE a=5 AND c-d=10) +** WHERE x=5 AND y=10; +** +** The hope is that the terms added to the inner query will make it more +** efficient. +** +** NAME AMBIGUITY +** +** This optimization is called the "WHERE-clause push-down optimization" +** or sometimes the "predicate push-down optimization". +** +** Do not confuse this optimization with another unrelated optimization +** with a similar name: The "MySQL push-down optimization" causes WHERE +** clause terms that can be evaluated using only the index and without +** reference to the table are run first, so that if they are false, +** unnecessary table seeks are avoided. +** +** RULES +** +** Do not attempt this optimization if: +** +** (1) (** This restriction was removed on 2017-09-29. We used to +** disallow this optimization for aggregate subqueries, but now +** it is allowed by putting the extra terms on the HAVING clause. +** The added HAVING clause is pointless if the subquery lacks +** a GROUP BY clause. But such a HAVING clause is also harmless +** so there does not appear to be any reason to add extra logic +** to suppress it. **) +** +** (2) The inner query is the recursive part of a common table expression. +** +** (3) The inner query has a LIMIT clause (since the changes to the WHERE +** clause would change the meaning of the LIMIT). +** +** (4) The inner query is the right operand of a LEFT JOIN and the +** expression to be pushed down does not come from the ON clause +** on that LEFT JOIN. +** +** (5) The WHERE clause expression originates in the ON or USING clause +** of a LEFT JOIN where iCursor is not the right-hand table of that +** left join. An example: +** +** SELECT * +** FROM (SELECT 1 AS a1 UNION ALL SELECT 2) AS aa +** JOIN (SELECT 1 AS b2 UNION ALL SELECT 2) AS bb ON (a1=b2) +** LEFT JOIN (SELECT 8 AS c3 UNION ALL SELECT 9) AS cc ON (b2=2); +** +** The correct answer is three rows: (1,1,NULL),(2,2,8),(2,2,9). +** But if the (b2=2) term were to be pushed down into the bb subquery, +** then the (1,1,NULL) row would be suppressed. +** +** (6) Window functions make things tricky as changes to the WHERE clause +** of the inner query could change the window over which window +** functions are calculated. Therefore, do not attempt the optimization +** if: +** +** (6a) The inner query uses multiple incompatible window partitions. +** +** (6b) The inner query is a compound and uses window-functions. +** +** (6c) The WHERE clause does not consist entirely of constants and +** copies of expressions found in the PARTITION BY clause of +** all window-functions used by the sub-query. It is safe to +** filter out entire partitions, as this does not change the +** window over which any window-function is calculated. +** +** (7) The inner query is a Common Table Expression (CTE) that should +** be materialized. (This restriction is implemented in the calling +** routine.) +** +** (8) If the subquery is a compound that uses UNION, INTERSECT, +** or EXCEPT, then all of the result set columns for all arms of +** the compound must use the BINARY collating sequence. +** +** (9) All three of the following are true: +** +** (9a) The WHERE clause expression originates in the ON or USING clause +** of a join (either an INNER or an OUTER join), and +** +** (9b) The subquery is to the right of the ON/USING clause +** +** (9c) There is a RIGHT JOIN (or FULL JOIN) in between the ON/USING +** clause and the subquery. +** +** Without this restriction, the WHERE-clause push-down optimization +** might move the ON/USING filter expression from the left side of a +** RIGHT JOIN over to the right side, which leads to incorrect answers. +** See also restriction (6) in sqlite3ExprIsSingleTableConstraint(). +** +** (10) The inner query is not the right-hand table of a RIGHT JOIN. +** +** (11) The subquery is not a VALUES clause +** +** (12) The WHERE clause is not "rowid ISNULL" or the equivalent. This +** case only comes up if SQLite is compiled using +** SQLITE_ALLOW_ROWID_IN_VIEW. +** +** Return 0 if no changes are made and non-zero if one or more WHERE clause +** terms are duplicated into the subquery. +*/ +static int pushDownWhereTerms( + Parse *pParse, /* Parse context (for malloc() and error reporting) */ + Select *pSubq, /* The subquery whose WHERE clause is to be augmented */ + Expr *pWhere, /* The WHERE clause of the outer query */ + SrcList *pSrcList, /* The complete from clause of the outer query */ + int iSrc /* Which FROM clause term to try to push into */ +){ + Expr *pNew; + SrcItem *pSrc; /* The subquery FROM term into which WHERE is pushed */ + int nChng = 0; + pSrc = &pSrcList->a[iSrc]; + if( pWhere==0 ) return 0; + if( pSubq->selFlags & (SF_Recursive|SF_MultiPart) ){ + return 0; /* restrictions (2) and (11) */ + } + if( pSrc->fg.jointype & (JT_LTORJ|JT_RIGHT) ){ + return 0; /* restrictions (10) */ + } + + if( pSubq->pPrior ){ + Select *pSel; + int notUnionAll = 0; + for(pSel=pSubq; pSel; pSel=pSel->pPrior){ + u8 op = pSel->op; + assert( op==TK_ALL || op==TK_SELECT + || op==TK_UNION || op==TK_INTERSECT || op==TK_EXCEPT ); + if( op!=TK_ALL && op!=TK_SELECT ){ + notUnionAll = 1; + } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pSel->pWin ) return 0; /* restriction (6b) */ +#endif + } + if( notUnionAll ){ + /* If any of the compound arms are connected using UNION, INTERSECT, + ** or EXCEPT, then we must ensure that none of the columns use a + ** non-BINARY collating sequence. */ + for(pSel=pSubq; pSel; pSel=pSel->pPrior){ + int ii; + const ExprList *pList = pSel->pEList; + assert( pList!=0 ); + for(ii=0; iinExpr; ii++){ + CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[ii].pExpr); + if( !sqlite3IsBinary(pColl) ){ + return 0; /* Restriction (8) */ + } + } + } + } + }else{ +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pSubq->pWin && pSubq->pWin->pPartition==0 ) return 0; +#endif + } + +#ifdef SQLITE_DEBUG + /* Only the first term of a compound can have a WITH clause. But make + ** sure no other terms are marked SF_Recursive in case something changes + ** in the future. + */ + { + Select *pX; + for(pX=pSubq; pX; pX=pX->pPrior){ + assert( (pX->selFlags & (SF_Recursive))==0 ); + } + } +#endif + + if( pSubq->pLimit!=0 ){ + return 0; /* restriction (3) */ + } + while( pWhere->op==TK_AND ){ + nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, pSrcList, iSrc); + pWhere = pWhere->pLeft; + } + +#if 0 /* These checks now done by sqlite3ExprIsSingleTableConstraint() */ + if( ExprHasProperty(pWhere, EP_OuterON|EP_InnerON) /* (9a) */ + && (pSrcList->a[0].fg.jointype & JT_LTORJ)!=0 /* Fast pre-test of (9c) */ + ){ + int jj; + for(jj=0; jjw.iJoin==pSrcList->a[jj].iCursor ){ + /* If we reach this point, both (9a) and (9b) are satisfied. + ** The following loop checks (9c): + */ + for(jj++; jja[jj].fg.jointype & JT_RIGHT)!=0 ){ + return 0; /* restriction (9) */ + } + } + } + } + } + if( isLeftJoin + && (ExprHasProperty(pWhere,EP_OuterON)==0 + || pWhere->w.iJoin!=iCursor) + ){ + return 0; /* restriction (4) */ + } + if( ExprHasProperty(pWhere,EP_OuterON) + && pWhere->w.iJoin!=iCursor + ){ + return 0; /* restriction (5) */ + } +#endif + +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + if( ViewCanHaveRowid && (pWhere->op==TK_ISNULL || pWhere->op==TK_NOTNULL) ){ + Expr *pLeft = pWhere->pLeft; + if( ALWAYS(pLeft) + && pLeft->op==TK_COLUMN + && pLeft->iColumn < 0 + ){ + return 0; /* Restriction (12) */ + } + } +#endif + + if( sqlite3ExprIsSingleTableConstraint(pWhere, pSrcList, iSrc, 1) ){ + nChng++; + pSubq->selFlags |= SF_PushDown; + while( pSubq ){ + SubstContext x; + pNew = sqlite3ExprDup(pParse->db, pWhere, 0); + unsetJoinExpr(pNew, -1, 1); + x.pParse = pParse; + x.iTable = pSrc->iCursor; + x.iNewTable = pSrc->iCursor; + x.isOuterJoin = 0; + x.nSelDepth = 0; + x.pEList = pSubq->pEList; + x.pCList = findLeftmostExprlist(pSubq); + pNew = substExpr(&x, pNew); + assert( pNew!=0 || pParse->nErr!=0 ); + if( pParse->nErr==0 && pNew->op==TK_IN && ExprUseXSelect(pNew) ){ + assert( pNew->x.pSelect!=0 ); + pNew->x.pSelect->selFlags |= SF_ClonedRhsIn; + assert( pWhere!=0 ); + assert( pWhere->op==TK_IN ); + assert( ExprUseXSelect(pWhere) ); + assert( pWhere->x.pSelect!=0 ); + pWhere->x.pSelect->selFlags |= SF_ClonedRhsIn; + } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pSubq->pWin && 0==pushDownWindowCheck(pParse, pSubq, pNew) ){ + /* Restriction 6c has prevented push-down in this case */ + sqlite3ExprDelete(pParse->db, pNew); + nChng--; + break; + } +#endif + if( pSubq->selFlags & SF_Aggregate ){ + pSubq->pHaving = sqlite3ExprAnd(pParse, pSubq->pHaving, pNew); + }else{ + pSubq->pWhere = sqlite3ExprAnd(pParse, pSubq->pWhere, pNew); + } + pSubq = pSubq->pPrior; + } + } + return nChng; +} +#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ + +/* +** Check to see if a subquery contains result-set columns that are +** never used. If it does, change the value of those result-set columns +** to NULL so that they do not cause unnecessary work to compute. +** +** Return the number of column that were changed to NULL. +*/ +static int disableUnusedSubqueryResultColumns(SrcItem *pItem){ + int nCol; + Select *pSub; /* The subquery to be simplified */ + Select *pX; /* For looping over compound elements of pSub */ + Table *pTab; /* The table that describes the subquery */ + int j; /* Column number */ + int nChng = 0; /* Number of columns converted to NULL */ + Bitmask colUsed; /* Columns that may not be NULLed out */ + + assert( pItem!=0 ); + if( pItem->fg.isCorrelated || pItem->fg.isCte ){ + return 0; + } + assert( pItem->pSTab!=0 ); + pTab = pItem->pSTab; + assert( pItem->fg.isSubquery ); + pSub = pItem->u4.pSubq->pSelect; + assert( pSub->pEList->nExpr==pTab->nCol ); + for(pX=pSub; pX; pX=pX->pPrior){ + if( (pX->selFlags & (SF_Distinct|SF_Aggregate))!=0 ){ + testcase( pX->selFlags & SF_Distinct ); + testcase( pX->selFlags & SF_Aggregate ); + return 0; + } + if( pX->pPrior && pX->op!=TK_ALL ){ + /* This optimization does not work for compound subqueries that + ** use UNION, INTERSECT, or EXCEPT. Only UNION ALL is allowed. */ + return 0; + } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pX->pWin ){ + /* This optimization does not work for subqueries that use window + ** functions. */ + return 0; + } +#endif + } + colUsed = pItem->colUsed; + if( pSub->pOrderBy ){ + ExprList *pList = pSub->pOrderBy; + for(j=0; jnExpr; j++){ + u16 iCol = pList->a[j].u.x.iOrderByCol; + if( iCol>0 ){ + iCol--; + colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol); + } + } + } + nCol = pTab->nCol; + for(j=0; jpPrior) { + Expr *pY = pX->pEList->a[j].pExpr; + if( pY->op==TK_NULL ) continue; + pY->op = TK_NULL; + ExprClearProperty(pY, EP_Skip|EP_Unlikely); + pX->selFlags |= SF_PushDown; + nChng++; + } + } + return nChng; +} + + +/* +** The pFunc is the only aggregate function in the query. Check to see +** if the query is a candidate for the min/max optimization. +** +** If the query is a candidate for the min/max optimization, then set +** *ppMinMax to be an ORDER BY clause to be used for the optimization +** and return either WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX depending on +** whether pFunc is a min() or max() function. +** +** If the query is not a candidate for the min/max optimization, return +** WHERE_ORDERBY_NORMAL (which must be zero). +** +** This routine must be called after aggregate functions have been +** located but before their arguments have been subjected to aggregate +** analysis. +*/ +static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){ + int eRet = WHERE_ORDERBY_NORMAL; /* Return value */ + ExprList *pEList; /* Arguments to agg function */ + const char *zFunc; /* Name of aggregate function pFunc */ + ExprList *pOrderBy; + u8 sortFlags = 0; + + assert( *ppMinMax==0 ); + assert( pFunc->op==TK_AGG_FUNCTION ); + assert( !IsWindowFunc(pFunc) ); + assert( ExprUseXList(pFunc) ); + pEList = pFunc->x.pList; + if( pEList==0 + || pEList->nExpr!=1 + || ExprHasProperty(pFunc, EP_WinFunc) + || OptimizationDisabled(db, SQLITE_MinMaxOpt) + ){ + return eRet; + } + assert( !ExprHasProperty(pFunc, EP_IntValue) ); + zFunc = pFunc->u.zToken; + if( sqlite3StrICmp(zFunc, "min")==0 ){ + eRet = WHERE_ORDERBY_MIN; + if( sqlite3ExprCanBeNull(pEList->a[0].pExpr) ){ + sortFlags = KEYINFO_ORDER_BIGNULL; + } + }else if( sqlite3StrICmp(zFunc, "max")==0 ){ + eRet = WHERE_ORDERBY_MAX; + sortFlags = KEYINFO_ORDER_DESC; + }else{ + return eRet; + } + *ppMinMax = pOrderBy = sqlite3ExprListDup(db, pEList, 0); + assert( pOrderBy!=0 || db->mallocFailed ); + if( pOrderBy ) pOrderBy->a[0].fg.sortFlags = sortFlags; + return eRet; +} + +/* +** The select statement passed as the first argument is an aggregate query. +** The second argument is the associated aggregate-info object. This +** function tests if the SELECT is of the form: +** +** SELECT count(*) FROM +** +** where table is a database table, not a sub-select or view. If the query +** does match this pattern, then a pointer to the Table object representing +** is returned. Otherwise, NULL is returned. +** +** This routine checks to see if it is safe to use the count optimization. +** A correct answer is still obtained (though perhaps more slowly) if +** this routine returns NULL when it could have returned a table pointer. +** But returning the pointer when NULL should have been returned can +** result in incorrect answers and/or crashes. So, when in doubt, return NULL. +*/ +static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){ + Table *pTab; + Expr *pExpr; + + assert( !p->pGroupBy ); + + if( p->pWhere + || p->pEList->nExpr!=1 + || p->pSrc->nSrc!=1 + || p->pSrc->a[0].fg.isSubquery + || pAggInfo->nFunc!=1 + || p->pHaving + ){ + return 0; + } + pTab = p->pSrc->a[0].pSTab; + assert( pTab!=0 ); + assert( !IsView(pTab) ); + if( !IsOrdinaryTable(pTab) ) return 0; + pExpr = p->pEList->a[0].pExpr; + assert( pExpr!=0 ); + if( pExpr->op!=TK_AGG_FUNCTION ) return 0; + if( pExpr->pAggInfo!=pAggInfo ) return 0; + if( (pAggInfo->aFunc[0].pFunc->funcFlags&SQLITE_FUNC_COUNT)==0 ) return 0; + assert( pAggInfo->aFunc[0].pFExpr==pExpr ); + testcase( ExprHasProperty(pExpr, EP_Distinct) ); + testcase( ExprHasProperty(pExpr, EP_WinFunc) ); + if( ExprHasProperty(pExpr, EP_Distinct|EP_WinFunc) ) return 0; + + return pTab; +} + +/* +** If the source-list item passed as an argument was augmented with an +** INDEXED BY clause, then try to locate the specified index. If there +** was such a clause and the named index cannot be found, return +** SQLITE_ERROR and leave an error in pParse. Otherwise, populate +** pFrom->pIndex and return SQLITE_OK. +*/ +SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, SrcItem *pFrom){ + Table *pTab = pFrom->pSTab; + char *zIndexedBy = pFrom->u1.zIndexedBy; + Index *pIdx; + assert( pTab!=0 ); + assert( pFrom->fg.isIndexedBy!=0 ); + + for(pIdx=pTab->pIndex; + pIdx && sqlite3StrICmp(pIdx->zName, zIndexedBy); + pIdx=pIdx->pNext + ); + if( !pIdx ){ + sqlite3ErrorMsg(pParse, "no such index: %s", zIndexedBy, 0); + pParse->checkSchema = 1; + return SQLITE_ERROR; + } + assert( pFrom->fg.isCte==0 ); + pFrom->u2.pIBIndex = pIdx; + return SQLITE_OK; +} + +/* +** Detect compound SELECT statements that use an ORDER BY clause with +** an alternative collating sequence. +** +** SELECT ... FROM t1 EXCEPT SELECT ... FROM t2 ORDER BY .. COLLATE ... +** +** These are rewritten as a subquery: +** +** SELECT * FROM (SELECT ... FROM t1 EXCEPT SELECT ... FROM t2) +** ORDER BY ... COLLATE ... +** +** This transformation is necessary because the multiSelectByMerge() routine +** above that generates the code for a compound SELECT with an ORDER BY clause +** uses a merge algorithm that requires the same collating sequence on the +** result columns as on the ORDER BY clause. See ticket +** http://sqlite.org/src/info/6709574d2a +** +** This transformation is only needed for EXCEPT, INTERSECT, and UNION. +** The UNION ALL operator works fine with multiSelectByMerge() even when +** there are COLLATE terms in the ORDER BY. +*/ +static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ + int i; + Select *pNew; + Select *pX; + sqlite3 *db; + struct ExprList_item *a; + SrcList *pNewSrc; + Parse *pParse; + Token dummy; + + if( p->pPrior==0 ) return WRC_Continue; + if( p->pOrderBy==0 ) return WRC_Continue; + for(pX=p; pX && (pX->op==TK_ALL || pX->op==TK_SELECT); pX=pX->pPrior){} + if( pX==0 ) return WRC_Continue; + a = p->pOrderBy->a; +#ifndef SQLITE_OMIT_WINDOWFUNC + /* If iOrderByCol is already non-zero, then it has already been matched + ** to a result column of the SELECT statement. This occurs when the + ** SELECT is rewritten for window-functions processing and then passed + ** to sqlite3SelectPrep() and similar a second time. The rewriting done + ** by this function is not required in this case. */ + if( a[0].u.x.iOrderByCol ) return WRC_Continue; +#endif + for(i=p->pOrderBy->nExpr-1; i>=0; i--){ + if( a[i].pExpr->flags & EP_Collate ) break; + } + if( i<0 ) return WRC_Continue; + + /* If we reach this point, that means the transformation is required. */ + + pParse = pWalker->pParse; + db = pParse->db; + pNew = sqlite3DbMallocZero(db, sizeof(*pNew) ); + if( pNew==0 ) return WRC_Abort; + memset(&dummy, 0, sizeof(dummy)); + pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0); + assert( pNewSrc!=0 || pParse->nErr ); + if( pParse->nErr ){ + sqlite3SrcListDelete(db, pNewSrc); + return WRC_Abort; + } + *pNew = *p; + p->pSrc = pNewSrc; + p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ASTERISK, 0)); + p->op = TK_SELECT; + p->pWhere = 0; + pNew->pGroupBy = 0; + pNew->pHaving = 0; + pNew->pOrderBy = 0; + p->pPrior = 0; + p->pNext = 0; + p->pWith = 0; +#ifndef SQLITE_OMIT_WINDOWFUNC + p->pWinDefn = 0; +#endif + p->selFlags &= ~(u32)SF_Compound; + assert( (p->selFlags & SF_Converted)==0 ); + p->selFlags |= SF_Converted; + assert( pNew->pPrior!=0 ); + pNew->pPrior->pNext = pNew; + pNew->pLimit = 0; + return WRC_Continue; +} + +/* +** Check to see if the FROM clause term pFrom has table-valued function +** arguments. If it does, leave an error message in pParse and return +** non-zero, since pFrom is not allowed to be a table-valued function. +*/ +static int cannotBeFunction(Parse *pParse, SrcItem *pFrom){ + if( pFrom->fg.isTabFunc ){ + sqlite3ErrorMsg(pParse, "'%s' is not a function", pFrom->zName); + return 1; + } + return 0; +} + +#ifndef SQLITE_OMIT_CTE +/* +** Argument pWith (which may be NULL) points to a linked list of nested +** WITH contexts, from inner to outermost. If the table identified by +** FROM clause element pItem is really a common-table-expression (CTE) +** then return a pointer to the CTE definition for that table. Otherwise +** return NULL. +** +** If a non-NULL value is returned, set *ppContext to point to the With +** object that the returned CTE belongs to. +*/ +static struct Cte *searchWith( + With *pWith, /* Current innermost WITH clause */ + SrcItem *pItem, /* FROM clause element to resolve */ + With **ppContext /* OUT: WITH clause return value belongs to */ +){ + const char *zName = pItem->zName; + With *p; + assert( pItem->fg.fixedSchema || pItem->u4.zDatabase==0 ); + assert( zName!=0 ); + for(p=pWith; p; p=p->pOuter){ + int i; + for(i=0; inCte; i++){ + if( sqlite3StrICmp(zName, p->a[i].zName)==0 ){ + *ppContext = p; + return &p->a[i]; + } + } + if( p->bView ) break; + } + return 0; +} + +/* The code generator maintains a stack of active WITH clauses +** with the inner-most WITH clause being at the top of the stack. +** +** This routine pushes the WITH clause passed as the second argument +** onto the top of the stack. If argument bFree is true, then this +** WITH clause will never be popped from the stack but should instead +** be freed along with the Parse object. In other cases, when +** bFree==0, the With object will be freed along with the SELECT +** statement with which it is associated. +** +** This routine returns a copy of pWith. Or, if bFree is true and +** the pWith object is destroyed immediately due to an OOM condition, +** then this routine return NULL. +** +** If bFree is true, do not continue to use the pWith pointer after +** calling this routine, Instead, use only the return value. +*/ +SQLITE_PRIVATE With *sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){ + if( pWith ){ + if( bFree ){ + pWith = (With*)sqlite3ParserAddCleanup(pParse, sqlite3WithDeleteGeneric, + pWith); + if( pWith==0 ) return 0; + } + if( pParse->nErr==0 ){ + assert( pParse->pWith!=pWith ); + pWith->pOuter = pParse->pWith; + pParse->pWith = pWith; + } + } + return pWith; +} + +/* +** This function checks if argument pFrom refers to a CTE declared by +** a WITH clause on the stack currently maintained by the parser (on the +** pParse->pWith linked list). And if currently processing a CTE +** CTE expression, through routine checks to see if the reference is +** a recursive reference to the CTE. +** +** If pFrom matches a CTE according to either of these two above, pFrom->pSTab +** and other fields are populated accordingly. +** +** Return 0 if no match is found. +** Return 1 if a match is found. +** Return 2 if an error condition is detected. +*/ +static int resolveFromTermToCte( + Parse *pParse, /* The parsing context */ + Walker *pWalker, /* Current tree walker */ + SrcItem *pFrom /* The FROM clause term to check */ +){ + Cte *pCte; /* Matched CTE (or NULL if no match) */ + With *pWith; /* The matching WITH */ + + assert( pFrom->pSTab==0 ); + if( pParse->pWith==0 ){ + /* There are no WITH clauses in the stack. No match is possible */ + return 0; + } + if( pParse->nErr ){ + /* Prior errors might have left pParse->pWith in a goofy state, so + ** go no further. */ + return 0; + } + assert( pFrom->fg.hadSchema==0 || pFrom->fg.notCte!=0 ); + if( pFrom->fg.fixedSchema==0 && pFrom->u4.zDatabase!=0 ){ + /* The FROM term contains a schema qualifier (ex: main.t1) and so + ** it cannot possibly be a CTE reference. */ + return 0; + } + if( pFrom->fg.notCte ){ + /* The FROM term is specifically excluded from matching a CTE. + ** (1) It is part of a trigger that used to have zDatabase but had + ** zDatabase removed by sqlite3FixTriggerStep(). + ** (2) This is the first term in the FROM clause of an UPDATE. + */ + return 0; + } + pCte = searchWith(pParse->pWith, pFrom, &pWith); + if( pCte ){ + sqlite3 *db = pParse->db; + Table *pTab; + ExprList *pEList; + Select *pSel; + Select *pLeft; /* Left-most SELECT statement */ + Select *pRecTerm; /* Left-most recursive term */ + int bMayRecursive; /* True if compound joined by UNION [ALL] */ + With *pSavedWith; /* Initial value of pParse->pWith */ + int iRecTab = -1; /* Cursor for recursive table */ + CteUse *pCteUse; + + /* If pCte->zCteErr is non-NULL at this point, then this is an illegal + ** recursive reference to CTE pCte. Leave an error in pParse and return + ** early. If pCte->zCteErr is NULL, then this is not a recursive reference. + ** In this case, proceed. */ + if( pCte->zCteErr ){ + sqlite3ErrorMsg(pParse, pCte->zCteErr, pCte->zName); + return 2; + } + if( cannotBeFunction(pParse, pFrom) ) return 2; + + assert( pFrom->pSTab==0 ); + pTab = sqlite3DbMallocZero(db, sizeof(Table)); + if( pTab==0 ) return 2; + pCteUse = pCte->pUse; + if( pCteUse==0 ){ + pCte->pUse = pCteUse = sqlite3DbMallocZero(db, sizeof(pCteUse[0])); + if( pCteUse==0 + || sqlite3ParserAddCleanup(pParse,sqlite3DbFree,pCteUse)==0 + ){ + sqlite3DbFree(db, pTab); + return 2; + } + pCteUse->eM10d = pCte->eM10d; + } + pFrom->pSTab = pTab; + pTab->nTabRef = 1; + pTab->zName = sqlite3DbStrDup(db, pCte->zName); + pTab->iPKey = -1; + pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); + pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid; + sqlite3SrcItemAttachSubquery(pParse, pFrom, pCte->pSelect, 1); + if( db->mallocFailed ) return 2; + assert( pFrom->fg.isSubquery && pFrom->u4.pSubq ); + pSel = pFrom->u4.pSubq->pSelect; + assert( pSel!=0 ); + pSel->selFlags |= SF_CopyCte; + if( pFrom->fg.isIndexedBy ){ + sqlite3ErrorMsg(pParse, "no such index: \"%s\"", pFrom->u1.zIndexedBy); + return 2; + } + assert( !pFrom->fg.isIndexedBy ); + pFrom->fg.isCte = 1; + pFrom->u2.pCteUse = pCteUse; + pCteUse->nUse++; + + /* Check if this is a recursive CTE. */ + pRecTerm = pSel; + bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION ); + while( bMayRecursive && pRecTerm->op==pSel->op ){ + int i; + SrcList *pSrc = pRecTerm->pSrc; + assert( pRecTerm->pPrior!=0 ); + for(i=0; inSrc; i++){ + SrcItem *pItem = &pSrc->a[i]; + if( pItem->zName!=0 + && !pItem->fg.hadSchema + && ALWAYS( !pItem->fg.isSubquery ) + && (pItem->fg.fixedSchema || pItem->u4.zDatabase==0) + && 0==sqlite3StrICmp(pItem->zName, pCte->zName) + ){ + pItem->pSTab = pTab; + pTab->nTabRef++; + pItem->fg.isRecursive = 1; + if( pRecTerm->selFlags & SF_Recursive ){ + sqlite3ErrorMsg(pParse, + "multiple references to recursive table: %s", pCte->zName + ); + return 2; + } + pRecTerm->selFlags |= SF_Recursive; + if( iRecTab<0 ) iRecTab = pParse->nTab++; + pItem->iCursor = iRecTab; + } + } + if( (pRecTerm->selFlags & SF_Recursive)==0 ) break; + pRecTerm = pRecTerm->pPrior; + } + + pCte->zCteErr = "circular reference: %s"; + pSavedWith = pParse->pWith; + pParse->pWith = pWith; + if( pSel->selFlags & SF_Recursive ){ + int rc; + assert( pRecTerm!=0 ); + assert( (pRecTerm->selFlags & SF_Recursive)==0 ); + assert( pRecTerm->pNext!=0 ); + assert( (pRecTerm->pNext->selFlags & SF_Recursive)!=0 ); + assert( pRecTerm->pWith==0 ); + pRecTerm->pWith = pSel->pWith; + rc = sqlite3WalkSelect(pWalker, pRecTerm); + pRecTerm->pWith = 0; + if( rc ){ + pParse->pWith = pSavedWith; + return 2; + } + }else{ + if( sqlite3WalkSelect(pWalker, pSel) ){ + pParse->pWith = pSavedWith; + return 2; + } + } + pParse->pWith = pWith; + + for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior); + pEList = pLeft->pEList; + if( pCte->pCols ){ + if( pEList && pEList->nExpr!=pCte->pCols->nExpr ){ + sqlite3ErrorMsg(pParse, "table %s has %d values for %d columns", + pCte->zName, pEList->nExpr, pCte->pCols->nExpr + ); + pParse->pWith = pSavedWith; + return 2; + } + pEList = pCte->pCols; + } + + sqlite3ColumnsFromExprList(pParse, pEList, &pTab->nCol, &pTab->aCol); + if( bMayRecursive ){ + if( pSel->selFlags & SF_Recursive ){ + pCte->zCteErr = "multiple recursive references: %s"; + }else{ + pCte->zCteErr = "recursive reference in a subquery: %s"; + } + sqlite3WalkSelect(pWalker, pSel); + } + pCte->zCteErr = 0; + pParse->pWith = pSavedWith; + return 1; /* Success */ + } + return 0; /* No match */ +} +#endif + +#ifndef SQLITE_OMIT_CTE +/* +** If the SELECT passed as the second argument has an associated WITH +** clause, pop it from the stack stored as part of the Parse object. +** +** This function is used as the xSelectCallback2() callback by +** sqlite3SelectExpand() when walking a SELECT tree to resolve table +** names and other FROM clause elements. +*/ +SQLITE_PRIVATE void sqlite3SelectPopWith(Walker *pWalker, Select *p){ + Parse *pParse = pWalker->pParse; + if( OK_IF_ALWAYS_TRUE(pParse->pWith) && p->pPrior==0 ){ + With *pWith = findRightmost(p)->pWith; + if( pWith!=0 ){ + assert( pParse->pWith==pWith || pParse->nErr ); + pParse->pWith = pWith->pOuter; + } + } +} +#endif + +/* +** The SrcItem structure passed as the second argument represents a +** sub-query in the FROM clause of a SELECT statement. This function +** allocates and populates the SrcItem.pTab object. If successful, +** SQLITE_OK is returned. Otherwise, if an OOM error is encountered, +** SQLITE_NOMEM. +*/ +SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){ + Select *pSel; + Table *pTab; + + assert( pFrom->fg.isSubquery ); + assert( pFrom->u4.pSubq!=0 ); + pSel = pFrom->u4.pSubq->pSelect; + assert( pSel ); + pFrom->pSTab = pTab = sqlite3DbMallocZero(pParse->db, sizeof(Table)); + if( pTab==0 ) return SQLITE_NOMEM; + pTab->nTabRef = 1; + if( pFrom->zAlias ){ + pTab->zName = sqlite3DbStrDup(pParse->db, pFrom->zAlias); + }else{ + pTab->zName = sqlite3MPrintf(pParse->db, "%!S", pFrom); + } + while( pSel->pPrior ){ pSel = pSel->pPrior; } + sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol); + pTab->iPKey = -1; + pTab->eTabType = TABTYP_VIEW; + pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); +#ifndef SQLITE_ALLOW_ROWID_IN_VIEW + /* The usual case - do not allow ROWID on a subquery */ + pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid; +#else + /* Legacy compatibility mode */ + pTab->tabFlags |= TF_Ephemeral | sqlite3Config.mNoVisibleRowid; +#endif + return pParse->nErr ? SQLITE_ERROR : SQLITE_OK; +} + + +/* +** Check the N SrcItem objects to the right of pBase. (N might be zero!) +** If any of those SrcItem objects have a USING clause containing zName +** then return true. +** +** If N is zero, or none of the N SrcItem objects to the right of pBase +** contains a USING clause, or if none of the USING clauses contain zName, +** then return false. +*/ +static int inAnyUsingClause( + const char *zName, /* Name we are looking for */ + SrcItem *pBase, /* The base SrcItem. Looking at pBase[1] and following */ + int N /* How many SrcItems to check */ +){ + while( N>0 ){ + N--; + pBase++; + if( pBase->fg.isUsing==0 ) continue; + if( NEVER(pBase->u3.pUsing==0) ) continue; + if( sqlite3IdListIndex(pBase->u3.pUsing, zName)>=0 ) return 1; + } + return 0; +} + + +/* +** This routine is a Walker callback for "expanding" a SELECT statement. +** "Expanding" means to do the following: +** +** (1) Make sure VDBE cursor numbers have been assigned to every +** element of the FROM clause. +** +** (2) Fill in the pTabList->a[].pTab fields in the SrcList that +** defines FROM clause. When views appear in the FROM clause, +** fill pTabList->a[].pSelect with a copy of the SELECT statement +** that implements the view. A copy is made of the view's SELECT +** statement so that we can freely modify or delete that statement +** without worrying about messing up the persistent representation +** of the view. +** +** (3) Add terms to the WHERE clause to accommodate the NATURAL keyword +** on joins and the ON and USING clause of joins. +** +** (4) Scan the list of columns in the result set (pEList) looking +** for instances of the "*" operator or the TABLE.* operator. +** If found, expand each "*" to be every column in every table +** and TABLE.* to be every column in TABLE. +** +*/ +static int selectExpander(Walker *pWalker, Select *p){ + Parse *pParse = pWalker->pParse; + int i, j, k, rc; + SrcList *pTabList; + ExprList *pEList; + SrcItem *pFrom; + sqlite3 *db = pParse->db; + Expr *pE, *pRight, *pExpr; + u16 selFlags = p->selFlags; + u32 elistFlags = 0; + + p->selFlags |= SF_Expanded; + if( db->mallocFailed ){ + return WRC_Abort; + } + assert( p->pSrc!=0 ); + if( (selFlags & SF_Expanded)!=0 ){ + return WRC_Prune; + } + if( pWalker->eCode ){ + /* Renumber selId because it has been copied from a view */ + p->selId = ++pParse->nSelect; + } + pTabList = p->pSrc; + pEList = p->pEList; + if( pParse->pWith && (p->selFlags & SF_View) ){ + if( p->pWith==0 ){ + p->pWith = (With*)sqlite3DbMallocZero(db, SZ_WITH(1) ); + if( p->pWith==0 ){ + return WRC_Abort; + } + } + p->pWith->bView = 1; + } + sqlite3WithPush(pParse, p->pWith, 0); + + /* Make sure cursor numbers have been assigned to all entries in + ** the FROM clause of the SELECT statement. + */ + sqlite3SrcListAssignCursors(pParse, pTabList); + + /* Look up every table named in the FROM clause of the select. If + ** an entry of the FROM clause is a subquery instead of a table or view, + ** then create a transient table structure to describe the subquery. + */ + for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ + Table *pTab; + assert( pFrom->fg.isRecursive==0 || pFrom->pSTab!=0 ); + if( pFrom->pSTab ) continue; + assert( pFrom->fg.isRecursive==0 ); + if( pFrom->zName==0 ){ +#ifndef SQLITE_OMIT_SUBQUERY + Select *pSel; + assert( pFrom->fg.isSubquery && pFrom->u4.pSubq!=0 ); + pSel = pFrom->u4.pSubq->pSelect; + /* A sub-query in the FROM clause of a SELECT */ + assert( pSel!=0 ); + assert( pFrom->pSTab==0 ); + if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort; + if( sqlite3ExpandSubquery(pParse, pFrom) ) return WRC_Abort; +#endif +#ifndef SQLITE_OMIT_CTE + }else if( (rc = resolveFromTermToCte(pParse, pWalker, pFrom))!=0 ){ + if( rc>1 ) return WRC_Abort; + pTab = pFrom->pSTab; + assert( pTab!=0 ); +#endif + }else{ + /* An ordinary table or view name in the FROM clause */ + assert( pFrom->pSTab==0 ); + pFrom->pSTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom); + if( pTab==0 ) return WRC_Abort; + if( pTab->nTabRef>=0xffff ){ + sqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535", + pTab->zName); + pFrom->pSTab = 0; + return WRC_Abort; + } + pTab->nTabRef++; + if( !IsVirtual(pTab) && cannotBeFunction(pParse, pFrom) ){ + return WRC_Abort; + } +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) + if( !IsOrdinaryTable(pTab) ){ + i16 nCol; + u8 eCodeOrig = pWalker->eCode; + if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; + assert( pFrom->fg.isSubquery==0 ); + if( IsView(pTab) ){ + if( (db->flags & SQLITE_EnableView)==0 + && pTab->pSchema!=db->aDb[1].pSchema + ){ + sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited", + pTab->zName); + } + sqlite3SrcItemAttachSubquery(pParse, pFrom, pTab->u.view.pSelect, 1); + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + else if( ALWAYS(IsVirtual(pTab)) + && (pFrom->fg.fromDDL || (pParse->prepFlags & SQLITE_PREPARE_FROM_DDL)) + && ALWAYS(pTab->u.vtab.p!=0) + && pTab->u.vtab.p->eVtabRisk > ((db->flags & SQLITE_TrustedSchema)!=0) + ){ + sqlite3ErrorMsg(pParse, "unsafe use of virtual table \"%s\"", + pTab->zName); + } + assert( SQLITE_VTABRISK_Normal==1 && SQLITE_VTABRISK_High==2 ); +#endif + nCol = pTab->nCol; + pTab->nCol = -1; + pWalker->eCode = 1; /* Turn on Select.selId renumbering */ + if( pFrom->fg.isSubquery ){ + sqlite3WalkSelect(pWalker, pFrom->u4.pSubq->pSelect); + } + pWalker->eCode = eCodeOrig; + pTab->nCol = nCol; + } +#endif + } + + /* Locate the index named by the INDEXED BY clause, if any. */ + if( pFrom->fg.isIndexedBy && sqlite3IndexedByLookup(pParse, pFrom) ){ + return WRC_Abort; + } + } + + /* Process NATURAL keywords, and ON and USING clauses of joins. + */ + assert( db->mallocFailed==0 || pParse->nErr!=0 ); + if( pParse->nErr || sqlite3ProcessJoin(pParse, p) ){ + return WRC_Abort; + } + + /* For every "*" that occurs in the column list, insert the names of + ** all columns in all tables. And for every TABLE.* insert the names + ** of all columns in TABLE. The parser inserted a special expression + ** with the TK_ASTERISK operator for each "*" that it found in the column + ** list. The following code just has to locate the TK_ASTERISK + ** expressions and expand each one to the list of all columns in + ** all tables. + ** + ** The first loop just checks to see if there are any "*" operators + ** that need expanding. + */ + for(k=0; knExpr; k++){ + pE = pEList->a[k].pExpr; + if( pE->op==TK_ASTERISK ) break; + assert( pE->op!=TK_DOT || pE->pRight!=0 ); + assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) ); + if( pE->op==TK_DOT && pE->pRight->op==TK_ASTERISK ) break; + elistFlags |= pE->flags; + } + if( knExpr ){ + /* + ** If we get here it means the result set contains one or more "*" + ** operators that need to be expanded. Loop through each expression + ** in the result set and expand them one by one. + */ + struct ExprList_item *a = pEList->a; + ExprList *pNew = 0; + int flags = pParse->db->flags; + int longNames = (flags & SQLITE_FullColNames)!=0 + && (flags & SQLITE_ShortColNames)==0; + + for(k=0; knExpr; k++){ + pE = a[k].pExpr; + elistFlags |= pE->flags; + pRight = pE->pRight; + assert( pE->op!=TK_DOT || pRight!=0 ); + if( pE->op!=TK_ASTERISK + && (pE->op!=TK_DOT || pRight->op!=TK_ASTERISK) + ){ + /* This particular expression does not need to be expanded. + */ + pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr); + if( pNew ){ + pNew->a[pNew->nExpr-1].zEName = a[k].zEName; + pNew->a[pNew->nExpr-1].fg.eEName = a[k].fg.eEName; + a[k].zEName = 0; + } + a[k].pExpr = 0; + }else{ + /* This expression is a "*" or a "TABLE.*" and needs to be + ** expanded. */ + int tableSeen = 0; /* Set to 1 when TABLE matches */ + char *zTName = 0; /* text of name of TABLE */ + int iErrOfst; + if( pE->op==TK_DOT ){ + assert( (selFlags & SF_NestedFrom)==0 ); + assert( pE->pLeft!=0 ); + assert( !ExprHasProperty(pE->pLeft, EP_IntValue) ); + zTName = pE->pLeft->u.zToken; + assert( ExprUseWOfst(pE->pLeft) ); + iErrOfst = pE->pRight->w.iOfst; + }else{ + assert( ExprUseWOfst(pE) ); + iErrOfst = pE->w.iOfst; + } + for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ + int nAdd; /* Number of cols including rowid */ + Table *pTab = pFrom->pSTab; /* Table for this data source */ + ExprList *pNestedFrom; /* Result-set of a nested FROM clause */ + char *zTabName; /* AS name for this data source */ + const char *zSchemaName = 0; /* Schema name for this data source */ + int iDb; /* Schema index for this data src */ + IdList *pUsing; /* USING clause for pFrom[1] */ + + if( (zTabName = pFrom->zAlias)==0 ){ + zTabName = pTab->zName; + } + if( db->mallocFailed ) break; + assert( (int)pFrom->fg.isNestedFrom == IsNestedFrom(pFrom) ); + if( pFrom->fg.isNestedFrom ){ + assert( pFrom->fg.isSubquery && pFrom->u4.pSubq ); + assert( pFrom->u4.pSubq->pSelect!=0 ); + pNestedFrom = pFrom->u4.pSubq->pSelect->pEList; + assert( pNestedFrom!=0 ); + assert( pNestedFrom->nExpr==pTab->nCol ); + assert( VisibleRowid(pTab)==0 || ViewCanHaveRowid ); + }else{ + if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){ + continue; + } + pNestedFrom = 0; + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + zSchemaName = iDb>=0 ? db->aDb[iDb].zDbSName : "*"; + } + if( i+1nSrc + && pFrom[1].fg.isUsing + && (selFlags & SF_NestedFrom)!=0 + ){ + int ii; + pUsing = pFrom[1].u3.pUsing; + for(ii=0; iinId; ii++){ + const char *zUName = pUsing->a[ii].zName; + pRight = sqlite3Expr(db, TK_ID, zUName); + sqlite3ExprSetErrorOffset(pRight, iErrOfst); + pNew = sqlite3ExprListAppend(pParse, pNew, pRight); + if( pNew ){ + struct ExprList_item *pX = &pNew->a[pNew->nExpr-1]; + assert( pX->zEName==0 ); + pX->zEName = sqlite3MPrintf(db,"..%s", zUName); + pX->fg.eEName = ENAME_TAB; + pX->fg.bUsingTerm = 1; + } + } + }else{ + pUsing = 0; + } + + nAdd = pTab->nCol; + if( VisibleRowid(pTab) && (selFlags & SF_NestedFrom)!=0 ) nAdd++; + for(j=0; jnCol ){ + zName = sqlite3RowidAlias(pTab); + if( zName==0 ) continue; + }else{ + zName = pTab->aCol[j].zCnName; + + /* If pTab is actually an SF_NestedFrom sub-select, do not + ** expand any ENAME_ROWID columns. */ + if( pNestedFrom && pNestedFrom->a[j].fg.eEName==ENAME_ROWID ){ + continue; + } + + if( zTName + && pNestedFrom + && sqlite3MatchEName(&pNestedFrom->a[j], 0, zTName, 0, 0)==0 + ){ + continue; + } + + /* If a column is marked as 'hidden', omit it from the expanded + ** result-set list unless the SELECT has the SF_IncludeHidden + ** bit set. + */ + if( (p->selFlags & SF_IncludeHidden)==0 + && IsHiddenColumn(&pTab->aCol[j]) + ){ + continue; + } + if( (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0 + && zTName==0 + && (selFlags & (SF_NestedFrom))==0 + ){ + continue; + } + } + assert( zName ); + tableSeen = 1; + + if( i>0 && zTName==0 && (selFlags & SF_NestedFrom)==0 ){ + if( pFrom->fg.isUsing + && sqlite3IdListIndex(pFrom->u3.pUsing, zName)>=0 + ){ + /* In a join with a USING clause, omit columns in the + ** using clause from the table on the right. */ + continue; + } + } + pRight = sqlite3Expr(db, TK_ID, zName); + if( (pTabList->nSrc>1 + && ( (pFrom->fg.jointype & JT_LTORJ)==0 + || (selFlags & SF_NestedFrom)!=0 + || !inAnyUsingClause(zName,pFrom,pTabList->nSrc-i-1) + ) + ) + || IN_RENAME_OBJECT + ){ + Expr *pLeft; + pLeft = sqlite3Expr(db, TK_ID, zTabName); + pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); + if( IN_RENAME_OBJECT && pE->pLeft ){ + sqlite3RenameTokenRemap(pParse, pLeft, pE->pLeft); + } + if( zSchemaName ){ + pLeft = sqlite3Expr(db, TK_ID, zSchemaName); + pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pExpr); + } + }else{ + pExpr = pRight; + } + sqlite3ExprSetErrorOffset(pExpr, iErrOfst); + pNew = sqlite3ExprListAppend(pParse, pNew, pExpr); + if( pNew==0 ){ + break; /* OOM */ + } + pX = &pNew->a[pNew->nExpr-1]; + assert( pX->zEName==0 ); + if( (selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){ + if( pNestedFrom && (!ViewCanHaveRowid || jnExpr) ){ + assert( jnExpr ); + pX->zEName = sqlite3DbStrDup(db, pNestedFrom->a[j].zEName); + testcase( pX->zEName==0 ); + }else{ + pX->zEName = sqlite3MPrintf(db, "%s.%s.%s", + zSchemaName, zTabName, zName); + testcase( pX->zEName==0 ); + } + pX->fg.eEName = (j==pTab->nCol ? ENAME_ROWID : ENAME_TAB); + if( (pFrom->fg.isUsing + && sqlite3IdListIndex(pFrom->u3.pUsing, zName)>=0) + || (pUsing && sqlite3IdListIndex(pUsing, zName)>=0) + || (jnCol && (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)) + ){ + pX->fg.bNoExpand = 1; + } + }else if( longNames ){ + pX->zEName = sqlite3MPrintf(db, "%s.%s", zTabName, zName); + pX->fg.eEName = ENAME_NAME; + }else{ + pX->zEName = sqlite3DbStrDup(db, zName); + pX->fg.eEName = ENAME_NAME; + } + } + } + if( !tableSeen ){ + if( zTName ){ + sqlite3ErrorMsg(pParse, "no such table: %s", zTName); + }else{ + sqlite3ErrorMsg(pParse, "no tables specified"); + } + } + } + } + sqlite3ExprListDelete(db, pEList); + p->pEList = pNew; + } + if( p->pEList ){ + if( p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ + sqlite3ErrorMsg(pParse, "too many columns in result set"); + return WRC_Abort; + } + if( (elistFlags & (EP_HasFunc|EP_Subquery))!=0 ){ + p->selFlags |= SF_ComplexResult; + } + } +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x8 ){ + TREETRACE(0x8,pParse,p,("After result-set wildcard expansion:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif + return WRC_Continue; +} + +#if SQLITE_DEBUG +/* +** Always assert. This xSelectCallback2 implementation proves that the +** xSelectCallback2 is never invoked. +*/ +SQLITE_PRIVATE void sqlite3SelectWalkAssert2(Walker *NotUsed, Select *NotUsed2){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + assert( 0 ); +} +#endif +/* +** This routine "expands" a SELECT statement and all of its subqueries. +** For additional information on what it means to "expand" a SELECT +** statement, see the comment on the selectExpand worker callback above. +** +** Expanding a SELECT statement is the first step in processing a +** SELECT statement. The SELECT statement must be expanded before +** name resolution is performed. +** +** If anything goes wrong, an error message is written into pParse. +** The calling function can detect the problem by looking at pParse->nErr +** and/or pParse->db->mallocFailed. +*/ +static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){ + Walker w; + w.xExprCallback = sqlite3ExprWalkNoop; + w.pParse = pParse; + if( OK_IF_ALWAYS_TRUE(pParse->hasCompound) ){ + w.xSelectCallback = convertCompoundSelectToSubquery; + w.xSelectCallback2 = 0; + sqlite3WalkSelect(&w, pSelect); + } + w.xSelectCallback = selectExpander; + w.xSelectCallback2 = sqlite3SelectPopWith; + w.eCode = 0; + sqlite3WalkSelect(&w, pSelect); +} + + +#ifndef SQLITE_OMIT_SUBQUERY +/* +** This is a Walker.xSelectCallback callback for the sqlite3SelectTypeInfo() +** interface. +** +** For each FROM-clause subquery, add Column.zType, Column.zColl, and +** Column.affinity information to the Table structure that represents +** the result set of that subquery. +** +** The Table structure that represents the result set was constructed +** by selectExpander() but the type and collation and affinity information +** was omitted at that point because identifiers had not yet been resolved. +** This routine is called after identifier resolution. +*/ +static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ + Parse *pParse; + int i; + SrcList *pTabList; + SrcItem *pFrom; + + if( p->selFlags & SF_HasTypeInfo ) return; + p->selFlags |= SF_HasTypeInfo; + pParse = pWalker->pParse; + assert( (p->selFlags & SF_Resolved) ); + pTabList = p->pSrc; + for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ + Table *pTab = pFrom->pSTab; + assert( pTab!=0 ); + if( (pTab->tabFlags & TF_Ephemeral)!=0 && pFrom->fg.isSubquery ){ + /* A sub-query in the FROM clause of a SELECT */ + Select *pSel = pFrom->u4.pSubq->pSelect; + sqlite3SubqueryColumnTypes(pParse, pTab, pSel, SQLITE_AFF_NONE); + } + } +} +#endif + + +/* +** This routine adds datatype and collating sequence information to +** the Table structures of all FROM-clause subqueries in a +** SELECT statement. +** +** Use this routine after name resolution. +*/ +static void sqlite3SelectAddTypeInfo(Parse *pParse, Select *pSelect){ +#ifndef SQLITE_OMIT_SUBQUERY + Walker w; + w.xSelectCallback = sqlite3SelectWalkNoop; + w.xSelectCallback2 = selectAddSubqueryTypeInfo; + w.xExprCallback = sqlite3ExprWalkNoop; + w.pParse = pParse; + sqlite3WalkSelect(&w, pSelect); +#endif +} + + +/* +** This routine sets up a SELECT statement for processing. The +** following is accomplished: +** +** * VDBE Cursor numbers are assigned to all FROM-clause terms. +** * Ephemeral Table objects are created for all FROM-clause subqueries. +** * ON and USING clauses are shifted into WHERE statements +** * Wildcards "*" and "TABLE.*" in result sets are expanded. +** * Identifiers in expression are matched to tables. +** +** This routine acts recursively on all subqueries within the SELECT. +*/ +SQLITE_PRIVATE void sqlite3SelectPrep( + Parse *pParse, /* The parser context */ + Select *p, /* The SELECT statement being coded. */ + NameContext *pOuterNC /* Name context for container */ +){ + assert( p!=0 || pParse->db->mallocFailed ); + assert( pParse->db->pParse==pParse ); + if( pParse->db->mallocFailed ) return; + if( p->selFlags & SF_HasTypeInfo ) return; + sqlite3SelectExpand(pParse, p); + if( pParse->nErr ) return; + sqlite3ResolveSelectNames(pParse, p, pOuterNC); + if( pParse->nErr ) return; + sqlite3SelectAddTypeInfo(pParse, p); +} + +#if TREETRACE_ENABLED +/* +** Display all information about an AggInfo object +*/ +static void printAggInfo(AggInfo *pAggInfo){ + int ii; + sqlite3DebugPrintf("AggInfo %d/%p:\n", + pAggInfo->selId, pAggInfo); + for(ii=0; iinColumn; ii++){ + struct AggInfo_col *pCol = &pAggInfo->aCol[ii]; + sqlite3DebugPrintf( + "agg-column[%d] pTab=%s iTable=%d iColumn=%d iMem=%d" + " iSorterColumn=%d %s\n", + ii, pCol->pTab ? pCol->pTab->zName : "NULL", + pCol->iTable, pCol->iColumn, pAggInfo->iFirstReg+ii, + pCol->iSorterColumn, + ii>=pAggInfo->nAccumulator ? "" : " Accumulator"); + sqlite3TreeViewExpr(0, pAggInfo->aCol[ii].pCExpr, 0); + } + for(ii=0; iinFunc; ii++){ + sqlite3DebugPrintf("agg-func[%d]: iMem=%d\n", + ii, pAggInfo->iFirstReg+pAggInfo->nColumn+ii); + sqlite3TreeViewExpr(0, pAggInfo->aFunc[ii].pFExpr, 0); + } +} +#endif /* TREETRACE_ENABLED */ + +/* +** Analyze the arguments to aggregate functions. Create new pAggInfo->aCol[] +** entries for columns that are arguments to aggregate functions but which +** are not otherwise used. +** +** The aCol[] entries in AggInfo prior to nAccumulator are columns that +** are referenced outside of aggregate functions. These might be columns +** that are part of the GROUP by clause, for example. Other database engines +** would throw an error if there is a column reference that is not in the +** GROUP BY clause and that is not part of an aggregate function argument. +** But SQLite allows this. +** +** The aCol[] entries beginning with the aCol[nAccumulator] and following +** are column references that are used exclusively as arguments to +** aggregate functions. This routine is responsible for computing +** (or recomputing) those aCol[] entries. +*/ +static void analyzeAggFuncArgs( + AggInfo *pAggInfo, + NameContext *pNC +){ + int i; + assert( pAggInfo!=0 ); + assert( pAggInfo->iFirstReg==0 ); + pNC->ncFlags |= NC_InAggFunc; + for(i=0; inFunc; i++){ + Expr *pExpr = pAggInfo->aFunc[i].pFExpr; + assert( pExpr->op==TK_FUNCTION || pExpr->op==TK_AGG_FUNCTION ); + assert( ExprUseXList(pExpr) ); + sqlite3ExprAnalyzeAggList(pNC, pExpr->x.pList); + if( pExpr->pLeft ){ + assert( pExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pExpr->pLeft) ); + sqlite3ExprAnalyzeAggList(pNC, pExpr->pLeft->x.pList); + } +#ifndef SQLITE_OMIT_WINDOWFUNC + assert( !IsWindowFunc(pExpr) ); + if( ExprHasProperty(pExpr, EP_WinFunc) ){ + sqlite3ExprAnalyzeAggregates(pNC, pExpr->y.pWin->pFilter); + } +#endif + } + pNC->ncFlags &= ~NC_InAggFunc; +} + +/* +** An index on expressions is being used in the inner loop of an +** aggregate query with a GROUP BY clause. This routine attempts +** to adjust the AggInfo object to take advantage of index and to +** perhaps use the index as a covering index. +** +*/ +static void optimizeAggregateUseOfIndexedExpr( + Parse *pParse, /* Parsing context */ + Select *pSelect, /* The SELECT statement being processed */ + AggInfo *pAggInfo, /* The aggregate info */ + NameContext *pNC /* Name context used to resolve agg-func args */ +){ + assert( pAggInfo->iFirstReg==0 ); + assert( pSelect!=0 ); + assert( pSelect->pGroupBy!=0 ); + pAggInfo->nColumn = pAggInfo->nAccumulator; + if( ALWAYS(pAggInfo->nSortingColumn>0) ){ + int mx = pSelect->pGroupBy->nExpr - 1; + int j, k; + for(j=0; jnColumn; j++){ + k = pAggInfo->aCol[j].iSorterColumn; + if( k>mx ) mx = k; + } + pAggInfo->nSortingColumn = mx+1; + } + analyzeAggFuncArgs(pAggInfo, pNC); +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x20 ){ + IndexedExpr *pIEpr; + TREETRACE(0x20, pParse, pSelect, + ("AggInfo (possibly) adjusted for Indexed Exprs\n")); + sqlite3TreeViewSelect(0, pSelect, 0); + for(pIEpr=pParse->pIdxEpr; pIEpr; pIEpr=pIEpr->pIENext){ + printf("data-cursor=%d index={%d,%d}\n", + pIEpr->iDataCur, pIEpr->iIdxCur, pIEpr->iIdxCol); + sqlite3TreeViewExpr(0, pIEpr->pExpr, 0); + } + printAggInfo(pAggInfo); + } +#else + UNUSED_PARAMETER(pSelect); + UNUSED_PARAMETER(pParse); +#endif +} + +/* +** Walker callback for aggregateConvertIndexedExprRefToColumn(). +*/ +static int aggregateIdxEprRefToColCallback(Walker *pWalker, Expr *pExpr){ + AggInfo *pAggInfo; + struct AggInfo_col *pCol; + UNUSED_PARAMETER(pWalker); + if( pExpr->pAggInfo==0 ) return WRC_Continue; + if( pExpr->op==TK_AGG_COLUMN ) return WRC_Continue; + if( pExpr->op==TK_AGG_FUNCTION ) return WRC_Continue; + if( pExpr->op==TK_IF_NULL_ROW ) return WRC_Continue; + pAggInfo = pExpr->pAggInfo; + if( NEVER(pExpr->iAgg>=pAggInfo->nColumn) ) return WRC_Continue; + assert( pExpr->iAgg>=0 ); + pCol = &pAggInfo->aCol[pExpr->iAgg]; + pExpr->op = TK_AGG_COLUMN; + pExpr->iTable = pCol->iTable; + pExpr->iColumn = pCol->iColumn; + ExprClearProperty(pExpr, EP_Skip|EP_Collate|EP_Unlikely); + return WRC_Prune; +} + +/* +** Convert every pAggInfo->aFunc[].pExpr such that any node within +** those expressions that has pAppInfo set is changed into a TK_AGG_COLUMN +** opcode. +*/ +static void aggregateConvertIndexedExprRefToColumn(AggInfo *pAggInfo){ + int i; + Walker w; + memset(&w, 0, sizeof(w)); + w.xExprCallback = aggregateIdxEprRefToColCallback; + for(i=0; inFunc; i++){ + sqlite3WalkExpr(&w, pAggInfo->aFunc[i].pFExpr); + } +} + + +/* +** Allocate a block of registers so that there is one register for each +** pAggInfo->aCol[] and pAggInfo->aFunc[] entry in pAggInfo. The first +** register in this block is stored in pAggInfo->iFirstReg. +** +** This routine may only be called once for each AggInfo object. Prior +** to calling this routine: +** +** * The aCol[] and aFunc[] arrays may be modified +** * The AggInfoColumnReg() and AggInfoFuncReg() macros may not be used +** +** After calling this routine: +** +** * The aCol[] and aFunc[] arrays are fixed +** * The AggInfoColumnReg() and AggInfoFuncReg() macros may be used +** +*/ +static void assignAggregateRegisters(Parse *pParse, AggInfo *pAggInfo){ + assert( pAggInfo!=0 ); + assert( pAggInfo->iFirstReg==0 ); + pAggInfo->iFirstReg = pParse->nMem + 1; + pParse->nMem += pAggInfo->nColumn + pAggInfo->nFunc; +} + +/* +** Reset the aggregate accumulator. +** +** The aggregate accumulator is a set of memory cells that hold +** intermediate results while calculating an aggregate. This +** routine generates code that stores NULLs in all of those memory +** cells. +*/ +static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ + Vdbe *v = pParse->pVdbe; + int i; + struct AggInfo_func *pFunc; + int nReg = pAggInfo->nFunc + pAggInfo->nColumn; + assert( pAggInfo->iFirstReg>0 ); + assert( pParse->db->pParse==pParse ); + assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 ); + if( nReg==0 ) return; + if( pParse->nErr ) return; + sqlite3VdbeAddOp3(v, OP_Null, 0, pAggInfo->iFirstReg, + pAggInfo->iFirstReg+nReg-1); + for(pFunc=pAggInfo->aFunc, i=0; inFunc; i++, pFunc++){ + if( pFunc->iDistinct>=0 ){ + Expr *pE = pFunc->pFExpr; + assert( ExprUseXList(pE) ); + if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){ + sqlite3ErrorMsg(pParse, "DISTINCT aggregates must have exactly one " + "argument"); + pFunc->iDistinct = -1; + }else{ + KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pE->x.pList,0,0); + pFunc->iDistAddr = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, + pFunc->iDistinct, 0, 0, (char*)pKeyInfo, P4_KEYINFO); + ExplainQueryPlan((pParse, 0, "USE TEMP B-TREE FOR %s(DISTINCT)", + pFunc->pFunc->zName)); + } + } + if( pFunc->iOBTab>=0 ){ + ExprList *pOBList; + KeyInfo *pKeyInfo; + int nExtra = 0; + assert( pFunc->pFExpr->pLeft!=0 ); + assert( pFunc->pFExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pFunc->pFExpr->pLeft) ); + assert( pFunc->pFunc!=0 ); + pOBList = pFunc->pFExpr->pLeft->x.pList; + if( !pFunc->bOBUnique ){ + nExtra++; /* One extra column for the OP_Sequence */ + } + if( pFunc->bOBPayload ){ + /* extra columns for the function arguments */ + assert( ExprUseXList(pFunc->pFExpr) ); + assert( pFunc->pFExpr->x.pList!=0 ); + nExtra += pFunc->pFExpr->x.pList->nExpr; + } + if( pFunc->bUseSubtype ){ + nExtra += pFunc->pFExpr->x.pList->nExpr; + } + pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOBList, 0, nExtra); + if( !pFunc->bOBUnique && pParse->nErr==0 ){ + pKeyInfo->nKeyField++; + } + sqlite3VdbeAddOp4(v, OP_OpenEphemeral, + pFunc->iOBTab, pOBList->nExpr+nExtra, 0, + (char*)pKeyInfo, P4_KEYINFO); + ExplainQueryPlan((pParse, 0, "USE TEMP B-TREE FOR %s(ORDER BY)", + pFunc->pFunc->zName)); + } + } +} + +/* +** Invoke the OP_AggFinalize opcode for every aggregate function +** in the AggInfo structure. +*/ +static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ + Vdbe *v = pParse->pVdbe; + int i; + struct AggInfo_func *pF; + for(i=0, pF=pAggInfo->aFunc; inFunc; i++, pF++){ + ExprList *pList; + assert( ExprUseXList(pF->pFExpr) ); + if( pParse->nErr ) return; + pList = pF->pFExpr->x.pList; + if( pF->iOBTab>=0 ){ + /* For an ORDER BY aggregate, calls to OP_AggStep were deferred. Inputs + ** were stored in emphermal table pF->iOBTab. Here, we extract those + ** inputs (in ORDER BY order) and make all calls to OP_AggStep + ** before doing the OP_AggFinal call. */ + int iTop; /* Start of loop for extracting columns */ + int nArg; /* Number of columns to extract */ + int nKey; /* Key columns to be skipped */ + int regAgg; /* Extract into this array */ + int j; /* Loop counter */ + + assert( pF->pFunc!=0 ); + nArg = pList->nExpr; + regAgg = sqlite3GetTempRange(pParse, nArg); + + if( pF->bOBPayload==0 ){ + nKey = 0; + }else{ + assert( pF->pFExpr->pLeft!=0 ); + assert( ExprUseXList(pF->pFExpr->pLeft) ); + assert( pF->pFExpr->pLeft->x.pList!=0 ); + nKey = pF->pFExpr->pLeft->x.pList->nExpr; + if( ALWAYS(!pF->bOBUnique) ) nKey++; + } + iTop = sqlite3VdbeAddOp1(v, OP_Rewind, pF->iOBTab); VdbeCoverage(v); + for(j=nArg-1; j>=0; j--){ + sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, nKey+j, regAgg+j); + } + if( pF->bUseSubtype ){ + int regSubtype = sqlite3GetTempReg(pParse); + int iBaseCol = nKey + nArg + (pF->bOBPayload==0 && pF->bOBUnique==0); + for(j=nArg-1; j>=0; j--){ + sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, iBaseCol+j, regSubtype); + sqlite3VdbeAddOp2(v, OP_SetSubtype, regSubtype, regAgg+j); + } + sqlite3ReleaseTempReg(pParse, regSubtype); + } + sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); + sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, (u16)nArg); + sqlite3VdbeAddOp2(v, OP_Next, pF->iOBTab, iTop+1); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, iTop); + sqlite3ReleaseTempRange(pParse, regAgg, nArg); + } + sqlite3VdbeAddOp2(v, OP_AggFinal, AggInfoFuncReg(pAggInfo,i), + pList ? pList->nExpr : 0); + sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); + } +} + +/* +** Generate code that will update the accumulator memory cells for an +** aggregate based on the current cursor position. +** +** If regAcc is non-zero and there are no min() or max() aggregates +** in pAggInfo, then only populate the pAggInfo->nAccumulator accumulator +** registers if register regAcc contains 0. The caller will take care +** of setting and clearing regAcc. +** +** For an ORDER BY aggregate, the actual accumulator memory cell update +** is deferred until after all input rows have been received, so that they +** can be run in the requested order. In that case, instead of invoking +** OP_AggStep to update the accumulator, just add the arguments that would +** have been passed into OP_AggStep into the sorting ephemeral table +** (along with the appropriate sort key). +*/ +static void updateAccumulator( + Parse *pParse, + int regAcc, + AggInfo *pAggInfo, + int eDistinctType +){ + Vdbe *v = pParse->pVdbe; + int i; + int regHit = 0; + int addrHitTest = 0; + struct AggInfo_func *pF; + struct AggInfo_col *pC; + + assert( pAggInfo->iFirstReg>0 ); + if( pParse->nErr ) return; + pAggInfo->directMode = 1; + for(i=0, pF=pAggInfo->aFunc; inFunc; i++, pF++){ + int nArg; + int addrNext = 0; + int regAgg; + int regAggSz = 0; + int regDistinct = 0; + ExprList *pList; + assert( ExprUseXList(pF->pFExpr) ); + assert( !IsWindowFunc(pF->pFExpr) ); + assert( pF->pFunc!=0 ); + pList = pF->pFExpr->x.pList; + if( ExprHasProperty(pF->pFExpr, EP_WinFunc) ){ + Expr *pFilter = pF->pFExpr->y.pWin->pFilter; + if( pAggInfo->nAccumulator + && (pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL) + && regAcc + ){ + /* If regAcc==0, there there exists some min() or max() function + ** without a FILTER clause that will ensure the magnet registers + ** are populated. */ + if( regHit==0 ) regHit = ++pParse->nMem; + /* If this is the first row of the group (regAcc contains 0), clear the + ** "magnet" register regHit so that the accumulator registers + ** are populated if the FILTER clause jumps over the the + ** invocation of min() or max() altogether. Or, if this is not + ** the first row (regAcc contains 1), set the magnet register so that + ** the accumulators are not populated unless the min()/max() is invoked + ** and indicates that they should be. */ + sqlite3VdbeAddOp2(v, OP_Copy, regAcc, regHit); + } + addrNext = sqlite3VdbeMakeLabel(pParse); + sqlite3ExprIfFalse(pParse, pFilter, addrNext, SQLITE_JUMPIFNULL); + } + if( pF->iOBTab>=0 ){ + /* Instead of invoking AggStep, we must push the arguments that would + ** have been passed to AggStep onto the sorting table. */ + int jj; /* Registered used so far in building the record */ + ExprList *pOBList; /* The ORDER BY clause */ + assert( pList!=0 ); + nArg = pList->nExpr; + assert( nArg>0 ); + assert( pF->pFExpr->pLeft!=0 ); + assert( pF->pFExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pF->pFExpr->pLeft) ); + pOBList = pF->pFExpr->pLeft->x.pList; + assert( pOBList!=0 ); + assert( pOBList->nExpr>0 ); + regAggSz = pOBList->nExpr; + if( !pF->bOBUnique ){ + regAggSz++; /* One register for OP_Sequence */ + } + if( pF->bOBPayload ){ + regAggSz += nArg; + } + if( pF->bUseSubtype ){ + regAggSz += nArg; + } + regAggSz++; /* One extra register to hold result of MakeRecord */ + regAgg = sqlite3GetTempRange(pParse, regAggSz); + regDistinct = regAgg; + sqlite3ExprCodeExprList(pParse, pOBList, regAgg, 0, SQLITE_ECEL_DUP); + jj = pOBList->nExpr; + if( !pF->bOBUnique ){ + sqlite3VdbeAddOp2(v, OP_Sequence, pF->iOBTab, regAgg+jj); + jj++; + } + if( pF->bOBPayload ){ + regDistinct = regAgg+jj; + sqlite3ExprCodeExprList(pParse, pList, regDistinct, 0, SQLITE_ECEL_DUP); + jj += nArg; + } + if( pF->bUseSubtype ){ + int kk; + int regBase = pF->bOBPayload ? regDistinct : regAgg; + for(kk=0; kknExpr; + regAgg = sqlite3GetTempRange(pParse, nArg); + regDistinct = regAgg; + sqlite3ExprCodeExprList(pParse, pList, regAgg, 0, SQLITE_ECEL_DUP); + }else{ + nArg = 0; + regAgg = 0; + } + if( pF->iDistinct>=0 && pList ){ + if( addrNext==0 ){ + addrNext = sqlite3VdbeMakeLabel(pParse); + } + pF->iDistinct = codeDistinct(pParse, eDistinctType, + pF->iDistinct, addrNext, pList, regDistinct); + } + if( pF->iOBTab>=0 ){ + /* Insert a new record into the ORDER BY table */ + sqlite3VdbeAddOp3(v, OP_MakeRecord, regAgg, regAggSz-1, + regAgg+regAggSz-1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pF->iOBTab, regAgg+regAggSz-1, + regAgg, regAggSz-1); + sqlite3ReleaseTempRange(pParse, regAgg, regAggSz); + }else{ + /* Invoke the AggStep function */ + if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ + CollSeq *pColl = 0; + struct ExprList_item *pItem; + int j; + assert( pList!=0 ); /* pList!=0 if pF->pFunc has NEEDCOLL */ + for(j=0, pItem=pList->a; !pColl && jpExpr); + } + if( !pColl ){ + pColl = pParse->db->pDfltColl; + } + if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem; + sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, + (char *)pColl, P4_COLLSEQ); + } + sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); + sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, (u16)nArg); + sqlite3ReleaseTempRange(pParse, regAgg, nArg); + } + if( addrNext ){ + sqlite3VdbeResolveLabel(v, addrNext); + } + if( pParse->nErr ) return; + } + if( regHit==0 && pAggInfo->nAccumulator ){ + regHit = regAcc; + } + if( regHit ){ + addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v); + } + for(i=0, pC=pAggInfo->aCol; inAccumulator; i++, pC++){ + sqlite3ExprCode(pParse, pC->pCExpr, AggInfoColumnReg(pAggInfo,i)); + if( pParse->nErr ) return; + } + + pAggInfo->directMode = 0; + if( addrHitTest ){ + sqlite3VdbeJumpHereOrPopInst(v, addrHitTest); + } +} + +/* +** Add a single OP_Explain instruction to the VDBE to explain a simple +** count(*) query ("SELECT count(*) FROM pTab"). +*/ +#ifndef SQLITE_OMIT_EXPLAIN +static void explainSimpleCount( + Parse *pParse, /* Parse context */ + Table *pTab, /* Table being queried */ + Index *pIdx /* Index used to optimize scan, or NULL */ +){ + if( pParse->explain==2 ){ + int bCover = (pIdx!=0 && (HasRowid(pTab) || !IsPrimaryKeyIndex(pIdx))); + sqlite3VdbeExplain(pParse, 0, "SCAN %s%s%s", + pTab->zName, + bCover ? " USING COVERING INDEX " : "", + bCover ? pIdx->zName : "" + ); + } +} +#else +# define explainSimpleCount(a,b,c) +#endif + +/* +** sqlite3WalkExpr() callback used by havingToWhere(). +** +** If the node passed to the callback is a TK_AND node, return +** WRC_Continue to tell sqlite3WalkExpr() to iterate through child nodes. +** +** Otherwise, return WRC_Prune. In this case, also check if the +** sub-expression matches the criteria for being moved to the WHERE +** clause. If so, add it to the WHERE clause and replace the sub-expression +** within the HAVING expression with a constant "1". +*/ +static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){ + if( pExpr->op!=TK_AND ){ + Select *pS = pWalker->u.pSelect; + /* This routine is called before the HAVING clause of the current + ** SELECT is analyzed for aggregates. So if pExpr->pAggInfo is set + ** here, it indicates that the expression is a correlated reference to a + ** column from an outer aggregate query, or an aggregate function that + ** belongs to an outer query. Do not move the expression to the WHERE + ** clause in this obscure case, as doing so may corrupt the outer Select + ** statements AggInfo structure. */ + if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, pS->pGroupBy) + && ExprAlwaysFalse(pExpr)==0 + && pExpr->pAggInfo==0 + ){ + sqlite3 *db = pWalker->pParse->db; + Expr *pNew = sqlite3ExprInt32(db, 1); + if( pNew ){ + Expr *pWhere = pS->pWhere; + SWAP(Expr, *pNew, *pExpr); + pNew = sqlite3ExprAnd(pWalker->pParse, pWhere, pNew); + pS->pWhere = pNew; + pWalker->eCode = 1; + } + } + return WRC_Prune; + } + return WRC_Continue; +} + +/* +** Transfer eligible terms from the HAVING clause of a query, which is +** processed after grouping, to the WHERE clause, which is processed before +** grouping. For example, the query: +** +** SELECT * FROM WHERE a=? GROUP BY b HAVING b=? AND c=? +** +** can be rewritten as: +** +** SELECT * FROM WHERE a=? AND b=? GROUP BY b HAVING c=? +** +** A term of the HAVING expression is eligible for transfer if it consists +** entirely of constants and expressions that are also GROUP BY terms that +** use the "BINARY" collation sequence. +*/ +static void havingToWhere(Parse *pParse, Select *p){ + Walker sWalker; + memset(&sWalker, 0, sizeof(sWalker)); + sWalker.pParse = pParse; + sWalker.xExprCallback = havingToWhereExprCb; + sWalker.u.pSelect = p; + sqlite3WalkExpr(&sWalker, p->pHaving); +#if TREETRACE_ENABLED + if( sWalker.eCode && (sqlite3TreeTrace & 0x100)!=0 ){ + TREETRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif +} + +/* +** Check to see if the pThis entry of pTabList is a self-join of another view. +** Search FROM-clause entries in the range of iFirst..iEnd, including iFirst +** but stopping before iEnd. +** +** If pThis is a self-join, then return the SrcItem for the first other +** instance of that view found. If pThis is not a self-join then return 0. +*/ +static SrcItem *isSelfJoinView( + SrcList *pTabList, /* Search for self-joins in this FROM clause */ + SrcItem *pThis, /* Search for prior reference to this subquery */ + int iFirst, int iEnd /* Range of FROM-clause entries to search. */ +){ + SrcItem *pItem; + Select *pSel; + assert( pThis->fg.isSubquery ); + pSel = pThis->u4.pSubq->pSelect; + assert( pSel!=0 ); + if( pSel->selFlags & SF_PushDown ) return 0; + while( iFirsta[iFirst++]; + if( !pItem->fg.isSubquery ) continue; + if( pItem->fg.viaCoroutine ) continue; + if( pItem->zName==0 ) continue; + assert( pItem->pSTab!=0 ); + assert( pThis->pSTab!=0 ); + if( pItem->pSTab->pSchema!=pThis->pSTab->pSchema ) continue; + if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue; + pS1 = pItem->u4.pSubq->pSelect; + if( pItem->pSTab->pSchema==0 && pSel->selId!=pS1->selId ){ + /* The query flattener left two different CTE tables with identical + ** names in the same FROM clause. */ + continue; + } + if( pS1->selFlags & SF_PushDown ){ + /* The view was modified by some other optimization such as + ** pushDownWhereTerms() */ + continue; + } + return pItem; + } + return 0; +} + +/* +** Deallocate a single AggInfo object +*/ +static void agginfoFree(sqlite3 *db, void *pArg){ + AggInfo *p = (AggInfo*)pArg; + sqlite3DbFree(db, p->aCol); + sqlite3DbFree(db, p->aFunc); + sqlite3DbFreeNN(db, p); +} + +/* +** Attempt to transform a query of the form +** +** SELECT count(*) FROM (SELECT x FROM t1 UNION ALL SELECT y FROM t2) +** +** Into this: +** +** SELECT (SELECT count(*) FROM t1)+(SELECT count(*) FROM t2) +** +** The transformation only works if all of the following are true: +** +** * The subquery is a UNION ALL of two or more terms +** * The subquery does not have a LIMIT clause +** * There is no WHERE or GROUP BY or HAVING clauses on the subqueries +** * The outer query is a simple count(*) with no WHERE clause or other +** extraneous syntax. +** * None of the subqueries are DISTINCT (forumpost/a860f5fb2e 2025-03-10) +** +** Return TRUE if the optimization is undertaken. +*/ +static int countOfViewOptimization(Parse *pParse, Select *p){ + Select *pSub, *pPrior; + Expr *pExpr; + Expr *pCount; + sqlite3 *db; + SrcItem *pFrom; + if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate */ + if( p->pEList->nExpr!=1 ) return 0; /* Single result column */ + if( p->pWhere ) return 0; + if( p->pHaving ) return 0; + if( p->pGroupBy ) return 0; + if( p->pOrderBy ) return 0; + pExpr = p->pEList->a[0].pExpr; + if( pExpr->op!=TK_AGG_FUNCTION ) return 0; /* Result is an aggregate */ + assert( ExprUseUToken(pExpr) ); + if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0; /* Is count() */ + assert( ExprUseXList(pExpr) ); + if( pExpr->x.pList!=0 ) return 0; /* Must be count(*) */ + if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */ + if( ExprHasProperty(pExpr, EP_WinFunc) ) return 0;/* Not a window function */ + pFrom = p->pSrc->a; + if( pFrom->fg.isSubquery==0 ) return 0; /* FROM is a subquery */ + pSub = pFrom->u4.pSubq->pSelect; + if( pSub->pPrior==0 ) return 0; /* Must be a compound */ + if( pSub->selFlags & SF_CopyCte ) return 0; /* Not a CTE */ + do{ + if( pSub->op!=TK_ALL && pSub->pPrior ) return 0; /* Must be UNION ALL */ + if( pSub->pWhere ) return 0; /* No WHERE clause */ + if( pSub->pLimit ) return 0; /* No LIMIT clause */ + if( pSub->selFlags & (SF_Aggregate|SF_Distinct) ){ + testcase( pSub->selFlags & SF_Aggregate ); + testcase( pSub->selFlags & SF_Distinct ); + return 0; /* Not an aggregate nor DISTINCT */ + } + assert( pSub->pHaving==0 ); /* Due to the previous */ + pSub = pSub->pPrior; /* Repeat over compound */ + }while( pSub ); + + /* If we reach this point then it is OK to perform the transformation */ + + db = pParse->db; + pCount = pExpr; + pExpr = 0; + pSub = sqlite3SubqueryDetach(db, pFrom); + sqlite3SrcListDelete(db, p->pSrc); + p->pSrc = sqlite3DbMallocZero(pParse->db, SZ_SRCLIST_1); + while( pSub ){ + Expr *pTerm; + pPrior = pSub->pPrior; + pSub->pPrior = 0; + pSub->pNext = 0; + pSub->selFlags |= SF_Aggregate; + pSub->selFlags &= ~(u32)SF_Compound; + pSub->nSelectRow = 0; + sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, pSub->pEList); + pTerm = pPrior ? sqlite3ExprDup(db, pCount, 0) : pCount; + pSub->pEList = sqlite3ExprListAppend(pParse, 0, pTerm); + pTerm = sqlite3PExpr(pParse, TK_SELECT, 0, 0); + sqlite3PExprAddSelect(pParse, pTerm, pSub); + if( pExpr==0 ){ + pExpr = pTerm; + }else{ + pExpr = sqlite3PExpr(pParse, TK_PLUS, pTerm, pExpr); + } + pSub = pPrior; + } + p->pEList->a[0].pExpr = pExpr; + p->selFlags &= ~(u32)SF_Aggregate; + +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x200 ){ + TREETRACE(0x200,pParse,p,("After count-of-view optimization:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif + return 1; +} + +/* +** If any term of pSrc, or any SF_NestedFrom sub-query, is not the same +** as pSrcItem but has the same alias as p0, then return true. +** Otherwise return false. +*/ +static int sameSrcAlias(SrcItem *p0, SrcList *pSrc){ + int i; + for(i=0; inSrc; i++){ + SrcItem *p1 = &pSrc->a[i]; + if( p1==p0 ) continue; + if( p0->pSTab==p1->pSTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){ + return 1; + } + if( p1->fg.isSubquery + && (p1->u4.pSubq->pSelect->selFlags & SF_NestedFrom)!=0 + && sameSrcAlias(p0, p1->u4.pSubq->pSelect->pSrc) + ){ + return 1; + } + } + return 0; +} + +/* +** Return TRUE (non-zero) if the i-th entry in the pTabList SrcList can +** be implemented as a co-routine. The i-th entry is guaranteed to be +** a subquery. +** +** The subquery is implemented as a co-routine if all of the following are +** true: +** +** (1) The subquery will likely be implemented in the outer loop of +** the query. This will be the case if any one of the following +** conditions hold: +** (a) The subquery is the only term in the FROM clause +** (b) The subquery is the left-most term and a CROSS JOIN or similar +** requires it to be the outer loop +** (c) All of the following are true: +** (i) The subquery is the left-most subquery in the FROM clause +** (ii) There is nothing that would prevent the subquery from +** being used as the outer loop if the sqlite3WhereBegin() +** routine nominates it to that position. +** (iii) The query is not a UPDATE ... FROM +** (2) The subquery is not a CTE that should be materialized because +** (a) the AS MATERIALIZED keyword is used, or +** (b) the CTE is used multiple times and does not have the +** NOT MATERIALIZED keyword +** (3) The subquery is not part of a left operand for a RIGHT JOIN +** (4) The SQLITE_Coroutine optimization disable flag is not set +** (5) The subquery is not self-joined +*/ +static int fromClauseTermCanBeCoroutine( + Parse *pParse, /* Parsing context */ + SrcList *pTabList, /* FROM clause */ + int i, /* Which term of the FROM clause holds the subquery */ + int selFlags /* Flags on the SELECT statement */ +){ + SrcItem *pItem = &pTabList->a[i]; + if( pItem->fg.isCte ){ + const CteUse *pCteUse = pItem->u2.pCteUse; + if( pCteUse->eM10d==M10d_Yes ) return 0; /* (2a) */ + if( pCteUse->nUse>=2 && pCteUse->eM10d!=M10d_No ) return 0; /* (2b) */ + } + if( pTabList->a[0].fg.jointype & JT_LTORJ ) return 0; /* (3) */ + if( OptimizationDisabled(pParse->db, SQLITE_Coroutines) ) return 0; /* (4) */ + if( isSelfJoinView(pTabList, pItem, i+1, pTabList->nSrc)!=0 ){ + return 0; /* (5) */ + } + if( i==0 ){ + if( pTabList->nSrc==1 ) return 1; /* (1a) */ + if( pTabList->a[1].fg.jointype & JT_CROSS ) return 1; /* (1b) */ + if( selFlags & SF_UpdateFrom ) return 0; /* (1c-iii) */ + return 1; + } + if( selFlags & SF_UpdateFrom ) return 0; /* (1c-iii) */ + while( 1 /*exit-by-break*/ ){ + if( pItem->fg.jointype & (JT_OUTER|JT_CROSS) ) return 0; /* (1c-ii) */ + if( i==0 ) break; + i--; + pItem--; + if( pItem->fg.isSubquery ) return 0; /* (1c-i) */ + } + return 1; +} + +/* +** Argument pWhere is the WHERE clause belonging to SELECT statement p. This +** function attempts to transform expressions of the form: +** +** EXISTS (SELECT ...) +** +** into joins. For example, given +** +** CREATE TABLE sailors(sid INTEGER PRIMARY KEY, name TEXT); +** CREATE TABLE reserves(sid INT, day DATE, PRIMARY KEY(sid, day)); +** +** SELECT name FROM sailors AS S WHERE EXISTS ( +** SELECT * FROM reserves AS R WHERE S.sid = R.sid AND R.day = '2022-10-25' +** ); +** +** the SELECT statement may be transformed as follows: +** +** SELECT name FROM sailors AS S, reserves AS R +** WHERE S.sid = R.sid AND R.day = '2022-10-25'; +** +** **Approximately**. Really, we have to ensure that the FROM-clause term +** that was formerly inside the EXISTS is only executed once. This is handled +** by setting the SrcItem.fg.fromExists flag, which then causes code in +** the where.c file to exit the corresponding loop after the first successful +** match (if any). +*/ +static SQLITE_NOINLINE void existsToJoin( + Parse *pParse, /* Parsing context */ + Select *p, /* The SELECT statement being optimized */ + Expr *pWhere /* part of the WHERE clause currently being examined */ +){ + if( pParse->nErr==0 + && pWhere!=0 + && !ExprHasProperty(pWhere, EP_OuterON|EP_InnerON) + && ALWAYS(p->pSrc!=0) + && p->pSrc->nSrcpLimit==0 || p->pLimit->pRight==0) + ){ + if( pWhere->op==TK_AND ){ + Expr *pRight = pWhere->pRight; + existsToJoin(pParse, p, pWhere->pLeft); + existsToJoin(pParse, p, pRight); + } + else if( pWhere->op==TK_EXISTS ){ + Select *pSub = pWhere->x.pSelect; + Expr *pSubWhere = pSub->pWhere; + if( pSub->pSrc->nSrc==1 + && (pSub->selFlags & SF_Aggregate)==0 + && !pSub->pSrc->a[0].fg.isSubquery + && pSub->pLimit==0 + && pSub->pPrior==0 + ){ + /* Before combining the sub-select with the parent, renumber the + ** cursor used by the subselect. This is because the EXISTS expression + ** might be a copy of another EXISTS expression from somewhere + ** else in the tree, and in this case it is important that it use + ** a unique cursor number. */ + sqlite3 *db = pParse->db; + int *aCsrMap = sqlite3DbMallocZero(db, (pParse->nTab+2)*sizeof(int)); + if( aCsrMap==0 ) return; + aCsrMap[0] = (pParse->nTab+1); + renumberCursors(pParse, pSub, -1, aCsrMap); + sqlite3DbFree(db, aCsrMap); + + memset(pWhere, 0, sizeof(*pWhere)); + pWhere->op = TK_INTEGER; + pWhere->u.iValue = 1; + ExprSetProperty(pWhere, EP_IntValue); + assert( p->pWhere!=0 ); + pSub->pSrc->a[0].fg.fromExists = 1; + p->pSrc = sqlite3SrcListAppendList(pParse, p->pSrc, pSub->pSrc); + if( pSubWhere ){ + p->pWhere = sqlite3PExpr(pParse, TK_AND, p->pWhere, pSubWhere); + pSub->pWhere = 0; + } + pSub->pSrc = 0; + sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pSub); +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x100000 ){ + TREETRACE(0x100000,pParse,p, + ("After EXISTS-to-JOIN optimization:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif + } + } + } +} + +/* +** Type used for Walker callbacks by selectCheckOnClauses(). +*/ +typedef struct CheckOnCtx CheckOnCtx; +struct CheckOnCtx { + SrcList *pSrc; /* SrcList for this context */ + int iJoin; /* Cursor numbers must be =< than this */ + int bFuncArg; /* True for table-function arg */ + CheckOnCtx *pParent; /* Parent context */ +}; + +/* +** True if the SrcList passed as the only argument contains at least +** one RIGHT or FULL JOIN. False otherwise. +*/ +#define hasRightJoin(pSrc) (((pSrc)->a[0].fg.jointype & JT_LTORJ)!=0) + +/* +** The xExpr callback for the search of invalid ON clause terms. +*/ +static int selectCheckOnClausesExpr(Walker *pWalker, Expr *pExpr){ + CheckOnCtx *pCtx = pWalker->u.pCheckOnCtx; + + /* Check if pExpr is root or near-root of an ON clause constraint that needs + ** to be checked to ensure that it does not refer to tables in its FROM + ** clause to the right of itself. i.e. it is either: + ** + ** + an ON clause on an OUTER join, or + ** + an ON clause on an INNER join within a FROM that features at + ** least one RIGHT or FULL join. + */ + if( (ExprHasProperty(pExpr, EP_OuterON)) + || (ExprHasProperty(pExpr, EP_InnerON) && hasRightJoin(pCtx->pSrc)) + ){ + /* If CheckOnCtx.iJoin is already set, then fall through and process + ** this expression node as normal. Or, if CheckOnCtx.iJoin is still 0, + ** set it to the cursor number of the RHS of the join to which this + ** ON expression was attached and then iterate through the entire + ** expression. */ + assert( pCtx->iJoin==0 || pCtx->iJoin==pExpr->w.iJoin ); + if( pCtx->iJoin==0 ){ + pCtx->iJoin = pExpr->w.iJoin; + sqlite3WalkExprNN(pWalker, pExpr); + pCtx->iJoin = 0; + return WRC_Prune; + } + } + + if( pExpr->op==TK_COLUMN ){ + /* A column expression. Find the SrcList (if any) to which it refers. + ** Then, if CheckOnCtx.iJoin indicates that this expression is part of an + ** ON clause from that SrcList (i.e. if iJoin is non-zero), check that it + ** does not refer to a table to the right of CheckOnCtx.iJoin. */ + do { + SrcList *pSrc = pCtx->pSrc; + int nSrc = pSrc->nSrc; + int iTab = pExpr->iTable; + int ii; + for(ii=0; iia[ii].iCursor!=iTab; ii++){} + if( iiiJoin && iTab>pCtx->iJoin ){ + sqlite3ErrorMsg(pWalker->pParse, + "%s references tables to its right", + (pCtx->bFuncArg ? "table-function argument" : "ON clause") + ); + return WRC_Abort; + } + break; + } + pCtx = pCtx->pParent; + }while( pCtx ); + } + return WRC_Continue; +} + +/* +** The xSelect callback for the search of invalid ON clause terms. +*/ +static int selectCheckOnClausesSelect(Walker *pWalker, Select *pSelect){ + CheckOnCtx *pCtx = pWalker->u.pCheckOnCtx; + if( pSelect->pSrc==pCtx->pSrc || pSelect->pSrc->nSrc==0 ){ + return WRC_Continue; + }else{ + CheckOnCtx sCtx; + memset(&sCtx, 0, sizeof(sCtx)); + sCtx.pSrc = pSelect->pSrc; + sCtx.pParent = pCtx; + pWalker->u.pCheckOnCtx = &sCtx; + sqlite3WalkSelect(pWalker, pSelect); + pWalker->u.pCheckOnCtx = pCtx; + pSelect->selFlags &= ~SF_OnToWhere; + return WRC_Prune; + } +} + +/* +** Check all ON clauses in pSelect to verify that they do not reference +** columns to the right. +*/ +SQLITE_PRIVATE void sqlite3SelectCheckOnClauses(Parse *pParse, Select *pSelect){ + Walker w; + CheckOnCtx sCtx; + int ii; + assert( pSelect->selFlags & SF_OnToWhere ); + assert( pSelect->pSrc!=0 && pSelect->pSrc->nSrc>=2 ); + memset(&w, 0, sizeof(w)); + w.pParse = pParse; + w.xExprCallback = selectCheckOnClausesExpr; + w.xSelectCallback = selectCheckOnClausesSelect; + w.u.pCheckOnCtx = &sCtx; + memset(&sCtx, 0, sizeof(sCtx)); + sCtx.pSrc = pSelect->pSrc; + sqlite3WalkExpr(&w, pSelect->pWhere); + pSelect->selFlags &= ~SF_OnToWhere; + + /* Check for any table-function args that are attached to virtual tables + ** on the RHS of an outer join. They are subject to the same constraints + ** as ON clauses. */ + sCtx.bFuncArg = 1; + for(ii=0; iipSrc->nSrc; ii++){ + SrcItem *pItem = &pSelect->pSrc->a[ii]; + if( pItem->fg.isTabFunc + && (pItem->fg.jointype & JT_OUTER) + ){ + sCtx.iJoin = pItem->iCursor; + sqlite3WalkExprList(&w, pItem->u1.pFuncArg); + } + } +} + +/* +** If p2 exists and p1 and p2 have the same number of terms, then change +** every term of p1 to have the same sort order as p2 and return true. +** +** If p2 is NULL or p1 and p2 are different lengths, then make no changes +** and return false. +** +** p1 must be non-NULL. +*/ +static int sqlite3CopySortOrder(ExprList *p1, ExprList *p2){ + assert( p1 ); + if( p2 && p1->nExpr==p2->nExpr ){ + int ii; + for(ii=0; iinExpr; ii++){ + u8 sortFlags; + sortFlags = p2->a[ii].fg.sortFlags & KEYINFO_ORDER_DESC; + p1->a[ii].fg.sortFlags = sortFlags; + } + return 1; + }else{ + return 0; + } +} + +/* +** Generate byte-code for the SELECT statement given in the p argument. +** +** The results are returned according to the SelectDest structure. +** See comments in sqliteInt.h for further information. +** +** This routine returns the number of errors. If any errors are +** encountered, then an appropriate error message is left in +** pParse->zErrMsg. +** +** This routine does NOT free the Select structure passed in. The +** calling function needs to do that. +** +** This is a long function. The following is an outline of the processing +** steps, with tags referencing various milestones: +** +** * Resolve names and similar preparation tag-select-0100 +** * Scan of the FROM clause tag-select-0200 +** + OUTER JOIN strength reduction tag-select-0220 +** + Sub-query ORDER BY removal tag-select-0230 +** + Query flattening tag-select-0240 +** * Separate subroutine for compound-SELECT tag-select-0300 +** * WHERE-clause constant propagation tag-select-0330 +** * Count()-of-VIEW optimization tag-select-0350 +** * Scan of the FROM clause again tag-select-0400 +** + Authorize unreferenced tables tag-select-0410 +** + Predicate push-down optimization tag-select-0420 +** + Omit unused subquery columns optimization tag-select-0440 +** + Generate code to implement subqueries tag-select-0480 +** - Co-routines tag-select-0482 +** - Reuse previously computed CTE tag-select-0484 +** - REuse previously computed VIEW tag-select-0486 +** - Materialize a VIEW or CTE tag-select-0488 +** * DISTINCT ORDER BY -> GROUP BY optimization tag-select-0500 +** * Set up for ORDER BY tag-select-0600 +** * Create output table tag-select-0630 +** * Prepare registers for LIMIT tag-select-0650 +** * Setup for DISTINCT tag-select-0680 +** * Generate code for non-aggregate and non-GROUP BY tag-select-0700 +** * Generate code for aggregate and/or GROUP BY tag-select-0800 +** + GROUP BY queries tag-select-0810 +** + non-GROUP BY queries tag-select-0820 +** - Special case of count() w/o GROUP BY tag-select-0821 +** - General case of non-GROUP BY aggregates tag-select-0822 +** * Sort results, as needed tag-select-0900 +** * Internal self-checks tag-select-1000 +*/ +SQLITE_PRIVATE int sqlite3Select( + Parse *pParse, /* The parser context */ + Select *p, /* The SELECT statement being coded. */ + SelectDest *pDest /* What to do with the query results */ +){ + int i, j; /* Loop counters */ + WhereInfo *pWInfo; /* Return from sqlite3WhereBegin() */ + Vdbe *v; /* The virtual machine under construction */ + int isAgg; /* True for select lists like "count(*)" */ + ExprList *pEList = 0; /* List of columns to extract. */ + SrcList *pTabList; /* List of tables to select from */ + Expr *pWhere; /* The WHERE clause. May be NULL */ + ExprList *pGroupBy; /* The GROUP BY clause. May be NULL */ + Expr *pHaving; /* The HAVING clause. May be NULL */ + AggInfo *pAggInfo = 0; /* Aggregate information */ + int rc = 1; /* Value to return from this function */ + DistinctCtx sDistinct; /* Info on how to code the DISTINCT keyword */ + SortCtx sSort; /* Info on how to code the ORDER BY clause */ + int iEnd; /* Address of the end of the query */ + sqlite3 *db; /* The database connection */ + ExprList *pMinMaxOrderBy = 0; /* Added ORDER BY for min/max queries */ + u8 minMaxFlag; /* Flag for min/max queries */ + + db = pParse->db; + assert( pParse==db->pParse ); + v = sqlite3GetVdbe(pParse); + if( p==0 || pParse->nErr ){ + return 1; + } + assert( db->mallocFailed==0 ); + if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; +#if TREETRACE_ENABLED + TREETRACE(0x1,pParse,p, ("begin processing:\n", pParse->addrExplain)); + if( sqlite3TreeTrace & 0x10000 ){ + if( (sqlite3TreeTrace & 0x10001)==0x10000 ){ + sqlite3TreeViewLine(0, "In sqlite3Select() at %s:%d", + __FILE__, __LINE__); + } + sqlite3ShowSelect(p); + } +#endif + + /* tag-select-0100 */ + assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo ); + assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo ); + assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue ); + assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue ); + if( IgnorableDistinct(pDest) ){ + assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Discard || + pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_DistFifo ); + /* All of these destinations are also able to ignore the ORDER BY clause */ + if( p->pOrderBy ){ +#if TREETRACE_ENABLED + TREETRACE(0x800,pParse,p, ("dropping superfluous ORDER BY:\n")); + if( sqlite3TreeTrace & 0x800 ){ + sqlite3TreeViewExprList(0, p->pOrderBy, 0, "ORDERBY"); + } +#endif + sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, + p->pOrderBy); + testcase( pParse->earlyCleanup ); + p->pOrderBy = 0; + } + p->selFlags &= ~(u32)SF_Distinct; + } + sqlite3SelectPrep(pParse, p, 0); + if( pParse->nErr ){ + goto select_end; + } + assert( db->mallocFailed==0 ); + assert( p->pEList!=0 ); +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x10 ){ + TREETRACE(0x10,pParse,p, ("after name resolution:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif + + /* If the SF_UFSrcCheck flag is set, then this function is being called + ** as part of populating the temp table for an UPDATE...FROM statement. + ** In this case, it is an error if the target object (pSrc->a[0]) name + ** or alias is duplicated within FROM clause (pSrc->a[1..n]). + ** + ** Postgres disallows this case too. The reason is that some other + ** systems handle this case differently, and not all the same way, + ** which is just confusing. To avoid this, we follow PG's lead and + ** disallow it altogether. */ + if( p->selFlags & SF_UFSrcCheck ){ + SrcItem *p0 = &p->pSrc->a[0]; + if( sameSrcAlias(p0, p->pSrc) ){ + sqlite3ErrorMsg(pParse, + "target object/alias may not appear in FROM clause: %s", + p0->zAlias ? p0->zAlias : p0->pSTab->zName + ); + goto select_end; + } + + /* Clear the SF_UFSrcCheck flag. The check has already been performed, + ** and leaving this flag set can cause errors if a compound sub-query + ** in p->pSrc is flattened into this query and this function called + ** again as part of compound SELECT processing. */ + p->selFlags &= ~(u32)SF_UFSrcCheck; + } + + if( pDest->eDest==SRT_Output ){ + sqlite3GenerateColumnNames(pParse, p); + } + +#ifndef SQLITE_OMIT_WINDOWFUNC + if( sqlite3WindowRewrite(pParse, p) ){ + assert( pParse->nErr ); + goto select_end; + } +#if TREETRACE_ENABLED + if( p->pWin && (sqlite3TreeTrace & 0x40)!=0 ){ + TREETRACE(0x40,pParse,p, ("after window rewrite:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif +#endif /* SQLITE_OMIT_WINDOWFUNC */ + pTabList = p->pSrc; + isAgg = (p->selFlags & SF_Aggregate)!=0; + memset(&sSort, 0, sizeof(sSort)); + sSort.pOrderBy = p->pOrderBy; + + /* Try to do various optimizations (flattening subqueries, and strength + ** reduction of join operators) in the FROM clause up into the main query + ** tag-select-0200 + */ +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) + for(i=0; !p->pPrior && inSrc; i++){ + SrcItem *pItem = &pTabList->a[i]; + Select *pSub = pItem->fg.isSubquery ? pItem->u4.pSubq->pSelect : 0; + Table *pTab = pItem->pSTab; + + /* The expander should have already created transient Table objects + ** even for FROM clause elements such as subqueries that do not correspond + ** to a real table */ + assert( pTab!=0 ); + + /* Try to simplify joins: + ** + ** LEFT JOIN -> JOIN + ** RIGHT JOIN -> JOIN + ** FULL JOIN -> RIGHT JOIN + ** + ** If terms of the i-th table are used in the WHERE clause in such a + ** way that the i-th table cannot be the NULL row of a join, then + ** perform the appropriate simplification. This is called + ** "OUTER JOIN strength reduction" in the SQLite documentation. + ** tag-select-0220 + */ + if( (pItem->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 + && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor, + pItem->fg.jointype & JT_LTORJ) + && OptimizationEnabled(db, SQLITE_SimplifyJoin) + ){ + if( pItem->fg.jointype & JT_LEFT ){ + if( pItem->fg.jointype & JT_RIGHT ){ + TREETRACE(0x1000,pParse,p, + ("FULL-JOIN simplifies to RIGHT-JOIN on term %d\n",i)); + pItem->fg.jointype &= ~JT_LEFT; + }else{ + TREETRACE(0x1000,pParse,p, + ("LEFT-JOIN simplifies to JOIN on term %d\n",i)); + pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER); + unsetJoinExpr(p->pWhere, pItem->iCursor, 0); + } + } + if( pItem->fg.jointype & JT_LTORJ ){ + for(j=i+1; jnSrc; j++){ + SrcItem *pI2 = &pTabList->a[j]; + if( pI2->fg.jointype & JT_RIGHT ){ + if( pI2->fg.jointype & JT_LEFT ){ + TREETRACE(0x1000,pParse,p, + ("FULL-JOIN simplifies to LEFT-JOIN on term %d\n",j)); + pI2->fg.jointype &= ~JT_RIGHT; + }else{ + TREETRACE(0x1000,pParse,p, + ("RIGHT-JOIN simplifies to JOIN on term %d\n",j)); + pI2->fg.jointype &= ~(JT_RIGHT|JT_OUTER); + unsetJoinExpr(p->pWhere, pI2->iCursor, 1); + } + } + } + for(j=pTabList->nSrc-1; j>=0; j--){ + pTabList->a[j].fg.jointype &= ~JT_LTORJ; + if( pTabList->a[j].fg.jointype & JT_RIGHT ) break; + } + } + } + + /* No further action if this term of the FROM clause is not a subquery */ + if( pSub==0 ) continue; + + /* Catch mismatch in the declared columns of a view and the number of + ** columns in the SELECT on the RHS */ + if( pTab->nCol!=pSub->pEList->nExpr ){ + sqlite3ErrorMsg(pParse, "expected %d columns for '%s' but got %d", + pTab->nCol, pTab->zName, pSub->pEList->nExpr); + goto select_end; + } + + /* Do not attempt the usual optimizations (flattening and ORDER BY + ** elimination) on a MATERIALIZED common table expression because + ** a MATERIALIZED common table expression is an optimization fence. + */ + if( pItem->fg.isCte && pItem->u2.pCteUse->eM10d==M10d_Yes ){ + continue; + } + + /* Do not try to flatten an aggregate subquery. + ** + ** Flattening an aggregate subquery is only possible if the outer query + ** is not a join. But if the outer query is not a join, then the subquery + ** will be implemented as a co-routine and there is no advantage to + ** flattening in that case. + */ + if( (pSub->selFlags & SF_Aggregate)!=0 ) continue; + assert( pSub->pGroupBy==0 ); + + /* tag-select-0230: + ** If a FROM-clause subquery has an ORDER BY clause that is not + ** really doing anything, then delete it now so that it does not + ** interfere with query flattening. See the discussion at + ** https://sqlite.org/forum/forumpost/2d76f2bcf65d256a + ** + ** Beware of these cases where the ORDER BY clause may not be safely + ** omitted: + ** + ** (1) There is also a LIMIT clause + ** (2) The subquery was added to help with window-function + ** processing + ** (3) The subquery is in the FROM clause of an UPDATE + ** (4) The outer query uses an aggregate function other than + ** the built-in count(), min(), or max(). + ** (5) The ORDER BY isn't going to accomplish anything because + ** one of: + ** (a) The outer query has a different ORDER BY clause + ** (b) The subquery is part of a join + ** See forum post 062d576715d277c8 + ** (6) The subquery is not a recursive CTE. ORDER BY has a different + ** meaning for recursive CTEs and this optimization does not + ** apply. + ** + ** Also retain the ORDER BY if the OmitOrderBy optimization is disabled. + */ + if( pSub->pOrderBy!=0 + && (p->pOrderBy!=0 || pTabList->nSrc>1) /* Condition (5) */ + && pSub->pLimit==0 /* Condition (1) */ + && (pSub->selFlags & (SF_OrderByReqd|SF_Recursive))==0 /* (2) and (6) */ + && (p->selFlags & SF_OrderByReqd)==0 /* Condition (3) and (4) */ + && OptimizationEnabled(db, SQLITE_OmitOrderBy) + ){ + TREETRACE(0x800,pParse,p, + ("omit superfluous ORDER BY on %r FROM-clause subquery\n",i+1)); + sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, + pSub->pOrderBy); + pSub->pOrderBy = 0; + } + + /* If the outer query contains a "complex" result set (that is, + ** if the result set of the outer query uses functions or subqueries) + ** and if the subquery contains an ORDER BY clause and if + ** it will be implemented as a co-routine, then do not flatten. This + ** restriction allows SQL constructs like this: + ** + ** SELECT expensive_function(x) + ** FROM (SELECT x FROM tab ORDER BY y LIMIT 10); + ** + ** The expensive_function() is only computed on the 10 rows that + ** are output, rather than every row of the table. + ** + ** The requirement that the outer query have a complex result set + ** means that flattening does occur on simpler SQL constraints without + ** the expensive_function() like: + ** + ** SELECT x FROM (SELECT x FROM tab ORDER BY y LIMIT 10); + */ + if( pSub->pOrderBy!=0 + && i==0 + && (p->selFlags & SF_ComplexResult)!=0 + && (pTabList->nSrc==1 + || (pTabList->a[1].fg.jointype&(JT_OUTER|JT_CROSS))!=0) + ){ + continue; + } + + /* tag-select-0240 */ + if( flattenSubquery(pParse, p, i, isAgg) ){ + if( pParse->nErr ) goto select_end; + /* This subquery can be absorbed into its parent. */ + i = -1; + } + pTabList = p->pSrc; + if( db->mallocFailed ) goto select_end; + if( !IgnorableOrderby(pDest) ){ + sSort.pOrderBy = p->pOrderBy; + } + } +#endif + +#ifndef SQLITE_OMIT_COMPOUND_SELECT + /* Handle compound SELECT statements using the separate multiSelect() + ** procedure. tag-select-0300 + */ + if( p->pPrior ){ + rc = multiSelect(pParse, p, pDest); +#if TREETRACE_ENABLED + TREETRACE(0x400,pParse,p,("end compound-select processing\n")); + if( (sqlite3TreeTrace & 0x400)!=0 && ExplainQueryPlanParent(pParse)==0 ){ + sqlite3TreeViewSelect(0, p, 0); + } +#endif + if( p->pNext==0 ) ExplainQueryPlanPop(pParse); + return rc; + } +#endif + + /* If there may be an "EXISTS (SELECT ...)" in the WHERE clause, attempt + ** to change it into a join. */ + if( pParse->bHasExists && OptimizationEnabled(db,SQLITE_ExistsToJoin) ){ + existsToJoin(pParse, p, p->pWhere); + pTabList = p->pSrc; + } + + /* Do the WHERE-clause constant propagation optimization if this is + ** a join. No need to spend time on this operation for non-join queries + ** as the equivalent optimization will be handled by query planner in + ** sqlite3WhereBegin(). tag-select-0330 + */ + if( p->pWhere!=0 + && p->pWhere->op==TK_AND + && OptimizationEnabled(db, SQLITE_PropagateConst) + && propagateConstants(pParse, p) + ){ +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x2000 ){ + TREETRACE(0x2000,pParse,p,("After constant propagation:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif + }else{ + TREETRACE(0x2000,pParse,p,("Constant propagation not helpful\n")); + } + + /* tag-select-0350 */ + if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView) + && countOfViewOptimization(pParse, p) + ){ + if( db->mallocFailed ) goto select_end; + pTabList = p->pSrc; + } + + /* Loop over all terms in the FROM clause and do two things for each term: + ** + ** (1) Authorize unreferenced tables + ** (2) Generate code for all sub-queries + ** + ** tag-select-0400 + */ + for(i=0; inSrc; i++){ + SrcItem *pItem = &pTabList->a[i]; + SrcItem *pPrior; + SelectDest dest; + Subquery *pSubq; + Select *pSub; +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) + const char *zSavedAuthContext; +#endif + + /* Authorized unreferenced tables. tag-select-0410 + ** + ** Issue SQLITE_READ authorizations with a fake column name for any + ** tables that are referenced but from which no values are extracted. + ** Examples of where these kinds of null SQLITE_READ authorizations + ** would occur: + ** + ** SELECT count(*) FROM t1; -- SQLITE_READ t1."" + ** SELECT t1.* FROM t1, t2; -- SQLITE_READ t2."" + ** + ** The fake column name is an empty string. It is possible for a table to + ** have a column named by the empty string, in which case there is no way to + ** distinguish between an unreferenced table and an actual reference to the + ** "" column. The original design was for the fake column name to be a NULL, + ** which would be unambiguous. But legacy authorization callbacks might + ** assume the column name is non-NULL and segfault. The use of an empty + ** string for the fake column name seems safer. + */ + if( pItem->colUsed==0 && pItem->zName!=0 ){ + const char *zDb; + if( pItem->fg.fixedSchema ){ + int iDb = sqlite3SchemaToIndex(pParse->db, pItem->u4.pSchema); + zDb = db->aDb[iDb].zDbSName; + }else if( pItem->fg.isSubquery ){ + zDb = 0; + }else{ + zDb = pItem->u4.zDatabase; + } + sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", zDb); + } + +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) + /* Generate code for all sub-queries in the FROM clause + */ + if( pItem->fg.isSubquery==0 ) continue; + pSubq = pItem->u4.pSubq; + assert( pSubq!=0 ); + pSub = pSubq->pSelect; + + /* The code for a subquery should only be generated once. */ + if( pSubq->addrFillSub!=0 ) continue; + + /* Increment Parse.nHeight by the height of the largest expression + ** tree referred to by this, the parent select. The child select + ** may contain expression trees of at most + ** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit + ** more conservative than necessary, but much easier than enforcing + ** an exact limit. + */ + pParse->nHeight += sqlite3SelectExprHeight(p); + + /* Make copies of constant WHERE-clause terms in the outer query down + ** inside the subquery. This can help the subquery to run more efficiently. + ** This is the "predicate push-down optimization". tag-select-0420 + */ + if( OptimizationEnabled(db, SQLITE_PushDown) + && (pItem->fg.isCte==0 + || (pItem->u2.pCteUse->eM10d!=M10d_Yes && pItem->u2.pCteUse->nUse<2)) + && pushDownWhereTerms(pParse, pSub, p->pWhere, pTabList, i) + ){ +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x4000 ){ + TREETRACE(0x4000,pParse,p, + ("After WHERE-clause push-down into subquery %d:\n", pSub->selId)); + sqlite3TreeViewSelect(0, p, 0); + } +#endif + assert( pSubq->pSelect && (pSub->selFlags & SF_PushDown)!=0 ); + }else{ + TREETRACE(0x4000,pParse,p,("WHERE-clause push-down not possible\n")); + } + + /* Convert unused result columns of the subquery into simple NULL + ** expressions, to avoid unneeded searching and computation. + ** tag-select-0440 + */ + if( OptimizationEnabled(db, SQLITE_NullUnusedCols) + && disableUnusedSubqueryResultColumns(pItem) + ){ +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x4000 ){ + TREETRACE(0x4000,pParse,p, + ("Change unused result columns to NULL for subquery %d:\n", + pSub->selId)); + sqlite3TreeViewSelect(0, p, 0); + } +#endif + } + + zSavedAuthContext = pParse->zAuthContext; + pParse->zAuthContext = pItem->zName; + + /* Generate byte-code to implement the subquery tag-select-0480 + */ + if( fromClauseTermCanBeCoroutine(pParse, pTabList, i, p->selFlags) ){ + /* Implement a co-routine that will return a single row of the result + ** set on each invocation. tag-select-0482 + */ + int addrTop = sqlite3VdbeCurrentAddr(v)+1; + + pSubq->regReturn = ++pParse->nMem; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, pSubq->regReturn, 0, addrTop); + VdbeComment((v, "%!S", pItem)); + pSubq->addrFillSub = addrTop; + sqlite3SelectDestInit(&dest, SRT_Coroutine, pSubq->regReturn); + ExplainQueryPlan((pParse, 1, "CO-ROUTINE %!S", pItem)); + sqlite3Select(pParse, pSub, &dest); + pItem->pSTab->nRowLogEst = pSub->nSelectRow; + pItem->fg.viaCoroutine = 1; + pSubq->regResult = dest.iSdst; + sqlite3VdbeEndCoroutine(v, pSubq->regReturn); + VdbeComment((v, "end %!S", pItem)); + sqlite3VdbeJumpHere(v, addrTop-1); + sqlite3ClearTempRegCache(pParse); + }else if( pItem->fg.isCte && pItem->u2.pCteUse->addrM9e>0 ){ + /* This is a CTE for which materialization code has already been + ** generated. Invoke the subroutine to compute the materialization, + ** then make the pItem->iCursor be a copy of the ephemeral table that + ** holds the result of the materialization. tag-select-0484 */ + CteUse *pCteUse = pItem->u2.pCteUse; + sqlite3VdbeAddOp2(v, OP_Gosub, pCteUse->regRtn, pCteUse->addrM9e); + if( pItem->iCursor!=pCteUse->iCur ){ + sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pCteUse->iCur); + VdbeComment((v, "%!S", pItem)); + } + pSub->nSelectRow = pCteUse->nRowEst; + }else if( (pPrior = isSelfJoinView(pTabList, pItem, 0, i))!=0 ){ + /* This view has already been materialized by a prior entry in + ** this same FROM clause. Reuse it. tag-select-0486 */ + Subquery *pPriorSubq; + assert( pPrior->fg.isSubquery ); + pPriorSubq = pPrior->u4.pSubq; + assert( pPriorSubq!=0 ); + if( pPriorSubq->addrFillSub ){ + sqlite3VdbeAddOp2(v, OP_Gosub, pPriorSubq->regReturn, + pPriorSubq->addrFillSub); + } + sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor); + pSub->nSelectRow = pPriorSubq->pSelect->nSelectRow; + }else{ + /* Materialize the view. If the view is not correlated, generate a + ** subroutine to do the materialization so that subsequent uses of + ** the same view can reuse the materialization. tag-select-0488 */ + int topAddr; + int onceAddr = 0; +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + int addrExplain; +#endif + + pSubq->regReturn = ++pParse->nMem; + topAddr = sqlite3VdbeAddOp0(v, OP_Goto); + pSubq->addrFillSub = topAddr+1; + pItem->fg.isMaterialized = 1; + if( pItem->fg.isCorrelated==0 ){ + /* If the subquery is not correlated and if we are not inside of + ** a trigger, then we only need to compute the value of the subquery + ** once. */ + onceAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + VdbeComment((v, "materialize %!S", pItem)); + }else{ + VdbeNoopComment((v, "materialize %!S", pItem)); + } + sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); + + ExplainQueryPlan2(addrExplain, (pParse, 1, "MATERIALIZE %!S", pItem)); + sqlite3Select(pParse, pSub, &dest); + pItem->pSTab->nRowLogEst = pSub->nSelectRow; + if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); + sqlite3VdbeAddOp2(v, OP_Return, pSubq->regReturn, topAddr+1); + VdbeComment((v, "end %!S", pItem)); + sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1); + sqlite3VdbeJumpHere(v, topAddr); + sqlite3ClearTempRegCache(pParse); + if( pItem->fg.isCte && pItem->fg.isCorrelated==0 ){ + CteUse *pCteUse = pItem->u2.pCteUse; + pCteUse->addrM9e = pSubq->addrFillSub; + pCteUse->regRtn = pSubq->regReturn; + pCteUse->iCur = pItem->iCursor; + pCteUse->nRowEst = pSub->nSelectRow; + } + } + if( db->mallocFailed ) goto select_end; + pParse->nHeight -= sqlite3SelectExprHeight(p); + pParse->zAuthContext = zSavedAuthContext; +#endif + } + + /* Various elements of the SELECT copied into local variables for + ** convenience */ + pEList = p->pEList; + pWhere = p->pWhere; + pGroupBy = p->pGroupBy; + pHaving = p->pHaving; + sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0; + +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x8000 ){ + TREETRACE(0x8000,pParse,p,("After all FROM-clause analysis:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif + + /* tag-select-0500 + ** + ** If the query is DISTINCT with an ORDER BY but is not an aggregate, and + ** if the select-list is the same as the ORDER BY list, then this query + ** can be rewritten as a GROUP BY. In other words, this: + ** + ** SELECT DISTINCT xyz FROM ... ORDER BY xyz + ** + ** is transformed to: + ** + ** SELECT xyz FROM ... GROUP BY xyz ORDER BY xyz + ** + ** The second form is preferred as a single index (or temp-table) may be + ** used for both the ORDER BY and DISTINCT processing. As originally + ** written the query must use a temp-table for at least one of the ORDER + ** BY and DISTINCT, and an index or separate temp-table for the other. + */ + if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct + && sqlite3CopySortOrder(pEList, sSort.pOrderBy) + && sqlite3ExprListCompare(pEList, sSort.pOrderBy, -1)==0 + && OptimizationEnabled(db, SQLITE_GroupByOrder) +#ifndef SQLITE_OMIT_WINDOWFUNC + && p->pWin==0 +#endif + ){ + p->selFlags &= ~(u32)SF_Distinct; + pGroupBy = p->pGroupBy = sqlite3ExprListDup(db, pEList, 0); + if( pGroupBy ){ + for(i=0; inExpr; i++){ + pGroupBy->a[i].u.x.iOrderByCol = i+1; + } + } + p->selFlags |= SF_Aggregate; + /* Notice that even thought SF_Distinct has been cleared from p->selFlags, + ** the sDistinct.isTnct is still set. Hence, isTnct represents the + ** original setting of the SF_Distinct flag, not the current setting */ + assert( sDistinct.isTnct ); + sDistinct.isTnct = 2; + +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x20000 ){ + TREETRACE(0x20000,pParse,p,("Transform DISTINCT into GROUP BY:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif + } + + /* If there is an ORDER BY clause, then create an ephemeral index to + ** do the sorting. But this sorting ephemeral index might end up + ** being unused if the data can be extracted in pre-sorted order. + ** If that is the case, then the OP_OpenEphemeral instruction will be + ** changed to an OP_Noop once we figure out that the sorting index is + ** not needed. The sSort.addrSortIndex variable is used to facilitate + ** that change. tag-select-0600 + */ + if( sSort.pOrderBy ){ + KeyInfo *pKeyInfo; + pKeyInfo = sqlite3KeyInfoFromExprList( + pParse, sSort.pOrderBy, 0, pEList->nExpr); + sSort.iECursor = pParse->nTab++; + sSort.addrSortIndex = + sqlite3VdbeAddOp4(v, OP_OpenEphemeral, + sSort.iECursor, sSort.pOrderBy->nExpr+1+pEList->nExpr, 0, + (char*)pKeyInfo, P4_KEYINFO + ); + }else{ + sSort.addrSortIndex = -1; + } + + /* If the output is destined for a temporary table, open that table. + ** tag-select-0630 + */ + if( pDest->eDest==SRT_EphemTab ){ + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr); + if( p->selFlags & SF_NestedFrom ){ + /* Delete or NULL-out result columns that will never be used */ + int ii; + for(ii=pEList->nExpr-1; ii>0 && pEList->a[ii].fg.bUsed==0; ii--){ + sqlite3ExprDelete(db, pEList->a[ii].pExpr); + sqlite3DbFree(db, pEList->a[ii].zEName); + pEList->nExpr--; + } + for(ii=0; iinExpr; ii++){ + if( pEList->a[ii].fg.bUsed==0 ) pEList->a[ii].pExpr->op = TK_NULL; + } + } + } + + /* Set the limiter. tag-select-0650 + */ + iEnd = sqlite3VdbeMakeLabel(pParse); + if( (p->selFlags & SF_FixedLimit)==0 ){ + p->nSelectRow = 320; /* 4 billion rows */ + } + if( p->pLimit ) computeLimitRegisters(pParse, p, iEnd); + if( p->iLimit==0 && sSort.addrSortIndex>=0 ){ + sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen); + sSort.sortFlags |= SORTFLAG_UseSorter; + } + + /* Open an ephemeral index to use for the distinct set. tag-select-0680 + */ + if( p->selFlags & SF_Distinct ){ + sDistinct.tabTnct = pParse->nTab++; + sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, + sDistinct.tabTnct, 0, 0, + (char*)sqlite3KeyInfoFromExprList(pParse, p->pEList,0,0), + P4_KEYINFO); + sqlite3VdbeChangeP5(v, BTREE_UNORDERED); + sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED; + }else{ + sDistinct.eTnctType = WHERE_DISTINCT_NOOP; + } + + if( !isAgg && pGroupBy==0 ){ + /* No aggregate functions and no GROUP BY clause. tag-select-0700 */ + u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0) + | (p->selFlags & SF_FixedLimit); +#ifndef SQLITE_OMIT_WINDOWFUNC + Window *pWin = p->pWin; /* Main window object (or NULL) */ + if( pWin ){ + sqlite3WindowCodeInit(pParse, p); + } +#endif + assert( WHERE_USE_LIMIT==SF_FixedLimit ); + + + /* Begin the database scan. */ + TREETRACE(0x2,pParse,p,("WhereBegin\n")); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy, + p->pEList, p, wctrlFlags, p->nSelectRow); + if( pWInfo==0 ) goto select_end; + if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){ + p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo); + if( pDest->eDest<=SRT_DistQueue && pDest->eDest>=SRT_DistFifo ){ + /* TUNING: For a UNION CTE, because UNION is implies DISTINCT, + ** reduce the estimated output row count by 8 (LogEst 30). + ** Search for tag-20250414a to see other cases */ + p->nSelectRow -= 30; + } + } + if( sDistinct.isTnct && sqlite3WhereIsDistinct(pWInfo) ){ + sDistinct.eTnctType = sqlite3WhereIsDistinct(pWInfo); + } + if( sSort.pOrderBy ){ + sSort.nOBSat = sqlite3WhereIsOrdered(pWInfo); + sSort.labelOBLopt = sqlite3WhereOrderByLimitOptLabel(pWInfo); + if( sSort.nOBSat==sSort.pOrderBy->nExpr ){ + sSort.pOrderBy = 0; + } + } + TREETRACE(0x2,pParse,p,("WhereBegin returns\n")); + + /* If sorting index that was created by a prior OP_OpenEphemeral + ** instruction ended up not being needed, then change the OP_OpenEphemeral + ** into an OP_Noop. + */ + if( sSort.addrSortIndex>=0 && sSort.pOrderBy==0 ){ + sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex); + } + + assert( p->pEList==pEList ); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pWin ){ + int addrGosub = sqlite3VdbeMakeLabel(pParse); + int iCont = sqlite3VdbeMakeLabel(pParse); + int iBreak = sqlite3VdbeMakeLabel(pParse); + int regGosub = ++pParse->nMem; + + sqlite3WindowCodeStep(pParse, p, pWInfo, regGosub, addrGosub); + + sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak); + sqlite3VdbeResolveLabel(v, addrGosub); + VdbeNoopComment((v, "inner-loop subroutine")); + sSort.labelOBLopt = 0; + selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest, iCont, iBreak); + sqlite3VdbeResolveLabel(v, iCont); + sqlite3VdbeAddOp1(v, OP_Return, regGosub); + VdbeComment((v, "end inner-loop subroutine")); + sqlite3VdbeResolveLabel(v, iBreak); + }else +#endif /* SQLITE_OMIT_WINDOWFUNC */ + { + /* Use the standard inner loop. */ + selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest, + sqlite3WhereContinueLabel(pWInfo), + sqlite3WhereBreakLabel(pWInfo)); + + /* End the database scan loop. + */ + TREETRACE(0x2,pParse,p,("WhereEnd\n")); + sqlite3WhereEnd(pWInfo); + } + }else{ + /* This case is for when there exist aggregate functions or a GROUP BY + ** clause or both. tag-select-0800 */ + NameContext sNC; /* Name context for processing aggregate information */ + int iAMem; /* First Mem address for storing current GROUP BY */ + int iBMem; /* First Mem address for previous GROUP BY */ + int iUseFlag; /* Mem address holding flag indicating that at least + ** one row of the input to the aggregator has been + ** processed */ + int iAbortFlag; /* Mem address which causes query abort if positive */ + int groupBySort; /* Rows come from source in GROUP BY order */ + int addrEnd; /* End of processing for this SELECT */ + int sortPTab = 0; /* Pseudotable used to decode sorting results */ + int sortOut = 0; /* Output register from the sorter */ + int orderByGrp = 0; /* True if the GROUP BY and ORDER BY are the same */ + + /* Remove any and all aliases between the result set and the + ** GROUP BY clause. + */ + if( pGroupBy ){ + int k; /* Loop counter */ + struct ExprList_item *pItem; /* For looping over expression in a list */ + + for(k=p->pEList->nExpr, pItem=p->pEList->a; k>0; k--, pItem++){ + pItem->u.x.iAlias = 0; + } + for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){ + pItem->u.x.iAlias = 0; + } + assert( 66==sqlite3LogEst(100) ); + if( p->nSelectRow>66 ) p->nSelectRow = 66; + + /* If there is both a GROUP BY and an ORDER BY clause and they are + ** identical, then it may be possible to disable the ORDER BY clause + ** on the grounds that the GROUP BY will cause elements to come out + ** in the correct order. It also may not - the GROUP BY might use a + ** database index that causes rows to be grouped together as required + ** but not actually sorted. Either way, record the fact that the + ** ORDER BY and GROUP BY clauses are the same by setting the orderByGrp + ** variable. */ + if( sqlite3CopySortOrder(pGroupBy, sSort.pOrderBy) + && sqlite3ExprListCompare(pGroupBy, sSort.pOrderBy, -1)==0 + ){ + orderByGrp = 1; + } + }else{ + assert( 0==sqlite3LogEst(1) ); + p->nSelectRow = 0; + } + + /* Create a label to jump to when we want to abort the query */ + addrEnd = sqlite3VdbeMakeLabel(pParse); + + /* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in + ** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the + ** SELECT statement. + */ + pAggInfo = sqlite3DbMallocZero(db, sizeof(*pAggInfo) ); + if( pAggInfo ){ + sqlite3ParserAddCleanup(pParse, agginfoFree, pAggInfo); + testcase( pParse->earlyCleanup ); + } + if( db->mallocFailed ){ + goto select_end; + } + pAggInfo->selId = p->selId; +#ifdef SQLITE_DEBUG + pAggInfo->pSelect = p; +#endif + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + sNC.pSrcList = pTabList; + sNC.uNC.pAggInfo = pAggInfo; + VVA_ONLY( sNC.ncFlags = NC_UAggInfo; ) + pAggInfo->nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0; + pAggInfo->pGroupBy = pGroupBy; + sqlite3ExprAnalyzeAggList(&sNC, pEList); + sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy); + if( pHaving ){ + if( pGroupBy ){ + assert( pWhere==p->pWhere ); + assert( pHaving==p->pHaving ); + assert( pGroupBy==p->pGroupBy ); + havingToWhere(pParse, p); + pWhere = p->pWhere; + } + sqlite3ExprAnalyzeAggregates(&sNC, pHaving); + } + pAggInfo->nAccumulator = pAggInfo->nColumn; + if( p->pGroupBy==0 && p->pHaving==0 && pAggInfo->nFunc==1 ){ + minMaxFlag = minMaxQuery(db, pAggInfo->aFunc[0].pFExpr, &pMinMaxOrderBy); + }else{ + minMaxFlag = WHERE_ORDERBY_NORMAL; + } + analyzeAggFuncArgs(pAggInfo, &sNC); + if( db->mallocFailed ) goto select_end; +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x20 ){ + TREETRACE(0x20,pParse,p,("After aggregate analysis %p:\n", pAggInfo)); + sqlite3TreeViewSelect(0, p, 0); + if( minMaxFlag ){ + sqlite3DebugPrintf("MIN/MAX Optimization (0x%02x) adds:\n", minMaxFlag); + sqlite3TreeViewExprList(0, pMinMaxOrderBy, 0, "ORDERBY"); + } + printAggInfo(pAggInfo); + } +#endif + + + /* Processing for aggregates with GROUP BY is very different and + ** much more complex than aggregates without a GROUP BY. tag-select-0810 + */ + if( pGroupBy ){ + KeyInfo *pKeyInfo; /* Keying information for the group by clause */ + int addr1; /* A-vs-B comparison jump */ + int addrOutputRow; /* Start of subroutine that outputs a result row */ + int regOutputRow; /* Return address register for output subroutine */ + int addrSetAbort; /* Set the abort flag and return */ + int addrTopOfLoop; /* Top of the input loop */ + int addrSortingIdx; /* The OP_OpenEphemeral for the sorting index */ + int addrReset; /* Subroutine for resetting the accumulator */ + int regReset; /* Return address register for reset subroutine */ + ExprList *pDistinct = 0; + u16 distFlag = 0; + int eDist = WHERE_DISTINCT_NOOP; + + if( pAggInfo->nFunc==1 + && pAggInfo->aFunc[0].iDistinct>=0 + && ALWAYS(pAggInfo->aFunc[0].pFExpr!=0) + && ALWAYS(ExprUseXList(pAggInfo->aFunc[0].pFExpr)) + && pAggInfo->aFunc[0].pFExpr->x.pList!=0 + ){ + Expr *pExpr = pAggInfo->aFunc[0].pFExpr->x.pList->a[0].pExpr; + pExpr = sqlite3ExprDup(db, pExpr, 0); + pDistinct = sqlite3ExprListDup(db, pGroupBy, 0); + pDistinct = sqlite3ExprListAppend(pParse, pDistinct, pExpr); + distFlag = pDistinct ? (WHERE_WANT_DISTINCT|WHERE_AGG_DISTINCT) : 0; + } + + /* If there is a GROUP BY clause we might need a sorting index to + ** implement it. Allocate that sorting index now. If it turns out + ** that we do not need it after all, the OP_SorterOpen instruction + ** will be converted into a Noop. + */ + pAggInfo->sortingIdx = pParse->nTab++; + pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pGroupBy, + 0, pAggInfo->nColumn); + addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen, + pAggInfo->sortingIdx, pAggInfo->nSortingColumn, + 0, (char*)pKeyInfo, P4_KEYINFO); + + /* Initialize memory locations used by GROUP BY aggregate processing + */ + iUseFlag = ++pParse->nMem; + iAbortFlag = ++pParse->nMem; + regOutputRow = ++pParse->nMem; + addrOutputRow = sqlite3VdbeMakeLabel(pParse); + regReset = ++pParse->nMem; + addrReset = sqlite3VdbeMakeLabel(pParse); + iAMem = pParse->nMem + 1; + pParse->nMem += pGroupBy->nExpr; + iBMem = pParse->nMem + 1; + pParse->nMem += pGroupBy->nExpr; + sqlite3VdbeAddOp2(v, OP_Integer, 0, iAbortFlag); + VdbeComment((v, "clear abort flag")); + sqlite3VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1); + sqlite3ExprNullRegisterRange(pParse, iAMem, pGroupBy->nExpr); + + /* Begin a loop that will extract all source rows in GROUP BY order. + ** This might involve two separate loops with an OP_Sort in between, or + ** it might be a single loop that uses an index to extract information + ** in the right order to begin with. + */ + sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); + TREETRACE(0x2,pParse,p,("WhereBegin\n")); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, pDistinct, + p, (sDistinct.isTnct==2 ? WHERE_DISTINCTBY : WHERE_GROUPBY) + | (orderByGrp ? WHERE_SORTBYGROUP : 0) | distFlag, 0 + ); + if( pWInfo==0 ){ + sqlite3ExprListDelete(db, pDistinct); + goto select_end; + } + if( pParse->pIdxEpr ){ + optimizeAggregateUseOfIndexedExpr(pParse, p, pAggInfo, &sNC); + } + assignAggregateRegisters(pParse, pAggInfo); + eDist = sqlite3WhereIsDistinct(pWInfo); + TREETRACE(0x2,pParse,p,("WhereBegin returns\n")); + if( sqlite3WhereIsOrdered(pWInfo)==pGroupBy->nExpr ){ + /* The optimizer is able to deliver rows in group by order so + ** we do not have to sort. The OP_OpenEphemeral table will be + ** cancelled later because we still need to use the pKeyInfo + */ + groupBySort = 0; + }else{ + /* Rows are coming out in undetermined order. We have to push + ** each row into a sorting index, terminate the first loop, + ** then loop over the sorting index in order to get the output + ** in sorted order + */ + int regBase; + int regRecord; + int nCol; + int nGroupBy; + +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + int addrExp; /* Address of OP_Explain instruction */ +#endif + ExplainQueryPlan2(addrExp, (pParse, 0, "USE TEMP B-TREE FOR %s", + (sDistinct.isTnct && (p->selFlags&SF_Distinct)==0) ? + "DISTINCT" : "GROUP BY" + )); + + groupBySort = 1; + nGroupBy = pGroupBy->nExpr; + nCol = nGroupBy; + j = nGroupBy; + for(i=0; inColumn; i++){ + if( pAggInfo->aCol[i].iSorterColumn>=j ){ + nCol++; + j++; + } + } + regBase = sqlite3GetTempRange(pParse, nCol); + sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0); + j = nGroupBy; + pAggInfo->directMode = 1; + for(i=0; inColumn; i++){ + struct AggInfo_col *pCol = &pAggInfo->aCol[i]; + if( pCol->iSorterColumn>=j ){ + sqlite3ExprCode(pParse, pCol->pCExpr, j + regBase); + j++; + } + } + pAggInfo->directMode = 0; + regRecord = sqlite3GetTempReg(pParse); + sqlite3VdbeScanStatusCounters(v, addrExp, 0, sqlite3VdbeCurrentAddr(v)); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord); + sqlite3VdbeAddOp2(v, OP_SorterInsert, pAggInfo->sortingIdx, regRecord); + sqlite3VdbeScanStatusRange(v, addrExp, sqlite3VdbeCurrentAddr(v)-2, -1); + sqlite3ReleaseTempReg(pParse, regRecord); + sqlite3ReleaseTempRange(pParse, regBase, nCol); + TREETRACE(0x2,pParse,p,("WhereEnd\n")); + sqlite3WhereEnd(pWInfo); + pAggInfo->sortingIdxPTab = sortPTab = pParse->nTab++; + sortOut = sqlite3GetTempReg(pParse); + sqlite3VdbeScanStatusCounters(v, addrExp, sqlite3VdbeCurrentAddr(v), 0); + sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol); + sqlite3VdbeAddOp2(v, OP_SorterSort, pAggInfo->sortingIdx, addrEnd); + VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v); + pAggInfo->useSortingIdx = 1; + sqlite3VdbeScanStatusRange(v, addrExp, -1, sortPTab); + sqlite3VdbeScanStatusRange(v, addrExp, -1, pAggInfo->sortingIdx); + } + + /* If there are entries in pAgggInfo->aFunc[] that contain subexpressions + ** that are indexed (and that were previously identified and tagged + ** in optimizeAggregateUseOfIndexedExpr()) then those subexpressions + ** must now be converted into a TK_AGG_COLUMN node so that the value + ** is correctly pulled from the index rather than being recomputed. */ + if( pParse->pIdxEpr ){ + aggregateConvertIndexedExprRefToColumn(pAggInfo); +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x20 ){ + TREETRACE(0x20, pParse, p, + ("AggInfo function expressions converted to reference index\n")); + sqlite3TreeViewSelect(0, p, 0); + printAggInfo(pAggInfo); + } +#endif + } + + /* If the index or temporary table used by the GROUP BY sort + ** will naturally deliver rows in the order required by the ORDER BY + ** clause, cancel the ephemeral table open coded earlier. + ** + ** This is an optimization - the correct answer should result regardless. + ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER to + ** disable this optimization for testing purposes. */ + if( orderByGrp && OptimizationEnabled(db, SQLITE_GroupByOrder) + && (groupBySort || sqlite3WhereIsSorted(pWInfo)) + ){ + sSort.pOrderBy = 0; + sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex); + } + + /* Evaluate the current GROUP BY terms and store in b0, b1, b2... + ** (b0 is memory location iBMem+0, b1 is iBMem+1, and so forth) + ** Then compare the current GROUP BY terms against the GROUP BY terms + ** from the previous row currently stored in a0, a1, a2... + */ + addrTopOfLoop = sqlite3VdbeCurrentAddr(v); + if( groupBySort ){ + sqlite3VdbeAddOp3(v, OP_SorterData, pAggInfo->sortingIdx, + sortOut, sortPTab); + } + for(j=0; jnExpr; j++){ + int iOrderByCol = pGroupBy->a[j].u.x.iOrderByCol; + + if( groupBySort ){ + sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j); + }else{ + pAggInfo->directMode = 1; + sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j); + } + + if( iOrderByCol ){ + Expr *pX = p->pEList->a[iOrderByCol-1].pExpr; + Expr *pBase = sqlite3ExprSkipCollateAndLikely(pX); + while( ALWAYS(pBase!=0) && pBase->op==TK_IF_NULL_ROW ){ + pX = pBase->pLeft; + pBase = sqlite3ExprSkipCollateAndLikely(pX); + } + if( ALWAYS(pBase!=0) + && pBase->op!=TK_AGG_COLUMN + && pBase->op!=TK_REGISTER + ){ + sqlite3ExprToRegister(pX, iAMem+j); + } + } + } + sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr, + (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO); + addr1 = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp3(v, OP_Jump, addr1+1, 0, addr1+1); VdbeCoverage(v); + + /* Generate code that runs whenever the GROUP BY changes. + ** Changes in the GROUP BY are detected by the previous code + ** block. If there were no changes, this block is skipped. + ** + ** This code copies current group by terms in b0,b1,b2,... + ** over to a0,a1,a2. It then calls the output subroutine + ** and resets the aggregate accumulator registers in preparation + ** for the next GROUP BY batch. + */ + sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); + VdbeComment((v, "output one row of %d", p->selId)); + sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr); + sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); VdbeCoverage(v); + VdbeComment((v, "check abort flag")); + sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); + VdbeComment((v, "reset accumulator %d", p->selId)); + + /* Update the aggregate accumulators based on the content of + ** the current row + */ + sqlite3VdbeJumpHere(v, addr1); + updateAccumulator(pParse, iUseFlag, pAggInfo, eDist); + sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag); + VdbeComment((v, "indicate data in accumulator %d", p->selId)); + + /* End of the loop + */ + if( groupBySort ){ + sqlite3VdbeAddOp2(v, OP_SorterNext, pAggInfo->sortingIdx,addrTopOfLoop); + VdbeCoverage(v); + }else{ + TREETRACE(0x2,pParse,p,("WhereEnd\n")); + sqlite3WhereEnd(pWInfo); + sqlite3VdbeChangeToNoop(v, addrSortingIdx); + } + sqlite3ExprListDelete(db, pDistinct); + + /* Output the final row of result + */ + sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); + VdbeComment((v, "output final row of %d", p->selId)); + + /* Jump over the subroutines + */ + sqlite3VdbeGoto(v, addrEnd); + + /* Generate a subroutine that outputs a single row of the result + ** set. This subroutine first looks at the iUseFlag. If iUseFlag + ** is less than or equal to zero, the subroutine is a no-op. If + ** the processing calls for the query to abort, this subroutine + ** increments the iAbortFlag memory location before returning in + ** order to signal the caller to abort. + */ + addrSetAbort = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_Integer, 1, iAbortFlag); + VdbeComment((v, "set abort flag")); + sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); + sqlite3VdbeResolveLabel(v, addrOutputRow); + addrOutputRow = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2); + VdbeCoverage(v); + VdbeComment((v, "Groupby result generator entry point %d", p->selId)); + sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); + finalizeAggFunctions(pParse, pAggInfo); + sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL); + selectInnerLoop(pParse, p, -1, &sSort, + &sDistinct, pDest, + addrOutputRow+1, addrSetAbort); + sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); + VdbeComment((v, "end groupby result generator %d", p->selId)); + + /* Generate a subroutine that will reset the group-by accumulator + */ + sqlite3VdbeResolveLabel(v, addrReset); + resetAccumulator(pParse, pAggInfo); + sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag); + VdbeComment((v, "indicate accumulator %d empty", p->selId)); + sqlite3VdbeAddOp1(v, OP_Return, regReset); + + if( distFlag!=0 && eDist!=WHERE_DISTINCT_NOOP ){ + struct AggInfo_func *pF = &pAggInfo->aFunc[0]; + fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr); + } + } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */ + else { + /* Aggregate functions without GROUP BY. tag-select-0820 */ + Table *pTab; + if( (pTab = isSimpleCount(p, pAggInfo))!=0 ){ + /* tag-select-0821 + ** + ** If isSimpleCount() returns a pointer to a Table structure, then + ** the SQL statement is of the form: + ** + ** SELECT count(*) FROM + ** + ** where the Table structure returned represents table . + ** + ** This statement is so common that it is optimized specially. The + ** OP_Count instruction is executed either on the intkey table that + ** contains the data for table or on one of its indexes. It + ** is better to execute the op on an index, as indexes are almost + ** always spread across less pages than their corresponding tables. + */ + const int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + const int iCsr = pParse->nTab++; /* Cursor to scan b-tree */ + Index *pIdx; /* Iterator variable */ + KeyInfo *pKeyInfo = 0; /* Keyinfo for scanned index */ + Index *pBest = 0; /* Best index found so far */ + Pgno iRoot = pTab->tnum; /* Root page of scanned b-tree */ + + sqlite3CodeVerifySchema(pParse, iDb); + sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); + + /* Search for the index that has the lowest scan cost. + ** + ** (2011-04-15) Do not do a full scan of an unordered index. + ** + ** (2013-10-03) Do not count the entries in a partial index. + ** + ** In practice the KeyInfo structure will not be used. It is only + ** passed to keep OP_OpenRead happy. + */ + if( !HasRowid(pTab) ) pBest = sqlite3PrimaryKeyIndex(pTab); + if( !p->pSrc->a[0].fg.notIndexed ){ + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + if( pIdx->bUnordered==0 + && pIdx->szIdxRowszTabRow + && pIdx->pPartIdxWhere==0 + && (!pBest || pIdx->szIdxRowszIdxRow) + ){ + pBest = pIdx; + } + } + } + if( pBest ){ + iRoot = pBest->tnum; + pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pBest); + } + + /* Open a read-only cursor, execute the OP_Count, close the cursor. */ + sqlite3VdbeAddOp4Int(v, OP_OpenRead, iCsr, (int)iRoot, iDb, 1); + if( pKeyInfo ){ + sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO); + } + assignAggregateRegisters(pParse, pAggInfo); + sqlite3VdbeAddOp2(v, OP_Count, iCsr, AggInfoFuncReg(pAggInfo,0)); + sqlite3VdbeAddOp1(v, OP_Close, iCsr); + explainSimpleCount(pParse, pTab, pBest); + }else{ + /* The general case of an aggregate query without GROUP BY + ** tag-select-0822 */ + int regAcc = 0; /* "populate accumulators" flag */ + ExprList *pDistinct = 0; + u16 distFlag = 0; + int eDist; + + /* If there are accumulator registers but no min() or max() functions + ** without FILTER clauses, allocate register regAcc. Register regAcc + ** will contain 0 the first time the inner loop runs, and 1 thereafter. + ** The code generated by updateAccumulator() uses this to ensure + ** that the accumulator registers are (a) updated only once if + ** there are no min() or max functions or (b) always updated for the + ** first row visited by the aggregate, so that they are updated at + ** least once even if the FILTER clause means the min() or max() + ** function visits zero rows. */ + if( pAggInfo->nAccumulator ){ + for(i=0; inFunc; i++){ + if( ExprHasProperty(pAggInfo->aFunc[i].pFExpr, EP_WinFunc) ){ + continue; + } + if( pAggInfo->aFunc[i].pFunc->funcFlags&SQLITE_FUNC_NEEDCOLL ){ + break; + } + } + if( i==pAggInfo->nFunc ){ + regAcc = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 0, regAcc); + } + }else if( pAggInfo->nFunc==1 && pAggInfo->aFunc[0].iDistinct>=0 ){ + assert( ExprUseXList(pAggInfo->aFunc[0].pFExpr) ); + pDistinct = pAggInfo->aFunc[0].pFExpr->x.pList; + distFlag = pDistinct ? (WHERE_WANT_DISTINCT|WHERE_AGG_DISTINCT) : 0; + } + assignAggregateRegisters(pParse, pAggInfo); + + /* This case runs if the aggregate has no GROUP BY clause. The + ** processing is much simpler since there is only a single row + ** of output. + */ + assert( p->pGroupBy==0 ); + resetAccumulator(pParse, pAggInfo); + + /* If this query is a candidate for the min/max optimization, then + ** minMaxFlag will have been previously set to either + ** WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX and pMinMaxOrderBy will + ** be an appropriate ORDER BY expression for the optimization. + */ + assert( minMaxFlag==WHERE_ORDERBY_NORMAL || pMinMaxOrderBy!=0 ); + assert( pMinMaxOrderBy==0 || pMinMaxOrderBy->nExpr==1 ); + + TREETRACE(0x2,pParse,p,("WhereBegin\n")); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy, + pDistinct, p, minMaxFlag|distFlag, 0); + if( pWInfo==0 ){ + goto select_end; + } + TREETRACE(0x2,pParse,p,("WhereBegin returns\n")); + eDist = sqlite3WhereIsDistinct(pWInfo); + updateAccumulator(pParse, regAcc, pAggInfo, eDist); + if( eDist!=WHERE_DISTINCT_NOOP ){ + struct AggInfo_func *pF = pAggInfo->aFunc; + if( pF ){ + fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr); + } + } + + if( regAcc ) sqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc); + if( minMaxFlag ){ + sqlite3WhereMinMaxOptEarlyOut(v, pWInfo); + } + TREETRACE(0x2,pParse,p,("WhereEnd\n")); + sqlite3WhereEnd(pWInfo); + finalizeAggFunctions(pParse, pAggInfo); + } + + sSort.pOrderBy = 0; + sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL); + selectInnerLoop(pParse, p, -1, 0, 0, + pDest, addrEnd, addrEnd); + } + sqlite3VdbeResolveLabel(v, addrEnd); + + } /* endif aggregate query */ + + if( sDistinct.eTnctType==WHERE_DISTINCT_UNORDERED ){ + explainTempTable(pParse, "DISTINCT"); + } + + /* If there is an ORDER BY clause, then we need to sort the results + ** and send them to the callback one by one. tag-select-0900 + */ + if( sSort.pOrderBy ){ + assert( p->pEList==pEList ); + generateSortTail(pParse, p, &sSort, pEList->nExpr, pDest); + } + + /* Jump here to skip this query + */ + sqlite3VdbeResolveLabel(v, iEnd); + + /* The SELECT has been coded. If there is an error in the Parse structure, + ** set the return code to 1. Otherwise 0. */ + rc = (pParse->nErr>0); + + /* Control jumps to here if an error is encountered above, or upon + ** successful coding of the SELECT. + */ +select_end: + assert( db->mallocFailed==0 || db->mallocFailed==1 ); + assert( db->mallocFailed==0 || pParse->nErr!=0 ); + sqlite3ExprListDelete(db, pMinMaxOrderBy); +#ifdef SQLITE_DEBUG + /* Internal self-checks. tag-select-1000 */ + if( pAggInfo && !db->mallocFailed ){ +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x20 ){ + TREETRACE(0x20,pParse,p,("Finished with AggInfo\n")); + printAggInfo(pAggInfo); + } +#endif + for(i=0; inColumn; i++){ + Expr *pExpr = pAggInfo->aCol[i].pCExpr; + if( pExpr==0 ) continue; + assert( pExpr->pAggInfo==pAggInfo ); + assert( pExpr->iAgg==i ); + } + for(i=0; inFunc; i++){ + Expr *pExpr = pAggInfo->aFunc[i].pFExpr; + assert( pExpr!=0 ); + assert( pExpr->pAggInfo==pAggInfo ); + assert( pExpr->iAgg==i ); + } + } +#endif + +#if TREETRACE_ENABLED + TREETRACE(0x1,pParse,p,("end processing\n")); + if( (sqlite3TreeTrace & 0x40000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ + sqlite3TreeViewSelect(0, p, 0); + } +#endif + ExplainQueryPlanPop(pParse); + return rc; +} + +/************** End of select.c **********************************************/ +/************** Begin file table.c *******************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains the sqlite3_get_table() and sqlite3_free_table() +** interface routines. These are just wrappers around the main +** interface routine of sqlite3_exec(). +** +** These routines are in a separate files so that they will not be linked +** if they are not used. +*/ +/* #include "sqliteInt.h" */ + +#ifndef SQLITE_OMIT_GET_TABLE + +/* +** This structure is used to pass data from sqlite3_get_table() through +** to the callback function is uses to build the result. +*/ +typedef struct TabResult { + char **azResult; /* Accumulated output */ + char *zErrMsg; /* Error message text, if an error occurs */ + u32 nAlloc; /* Slots allocated for azResult[] */ + u32 nRow; /* Number of rows in the result */ + u32 nColumn; /* Number of columns in the result */ + u32 nData; /* Slots used in azResult[]. (nRow+1)*nColumn */ + int rc; /* Return code from sqlite3_exec() */ +} TabResult; + +/* +** This routine is called once for each row in the result table. Its job +** is to fill in the TabResult structure appropriately, allocating new +** memory as necessary. +*/ +static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){ + TabResult *p = (TabResult*)pArg; /* Result accumulator */ + int need; /* Slots needed in p->azResult[] */ + int i; /* Loop counter */ + char *z; /* A single column of result */ + + /* Make sure there is enough space in p->azResult to hold everything + ** we need to remember from this invocation of the callback. + */ + if( p->nRow==0 && argv!=0 ){ + need = nCol*2; + }else{ + need = nCol; + } + if( p->nData + need > p->nAlloc ){ + char **azNew; + p->nAlloc = p->nAlloc*2 + need; + azNew = sqlite3Realloc( p->azResult, sizeof(char*)*p->nAlloc ); + if( azNew==0 ) goto malloc_failed; + p->azResult = azNew; + } + + /* If this is the first row, then generate an extra row containing + ** the names of all columns. + */ + if( p->nRow==0 ){ + p->nColumn = nCol; + for(i=0; iazResult[p->nData++] = z; + } + }else if( (int)p->nColumn!=nCol ){ + sqlite3_free(p->zErrMsg); + p->zErrMsg = sqlite3_mprintf( + "sqlite3_get_table() called with two or more incompatible queries" + ); + p->rc = SQLITE_ERROR; + return 1; + } + + /* Copy over the row data + */ + if( argv!=0 ){ + for(i=0; iazResult[p->nData++] = z; + } + p->nRow++; + } + return 0; + +malloc_failed: + p->rc = SQLITE_NOMEM_BKPT; + return 1; +} + +/* +** Query the database. But instead of invoking a callback for each row, +** malloc() for space to hold the result and return the entire results +** at the conclusion of the call. +** +** The result that is written to ***pazResult is held in memory obtained +** from malloc(). But the caller cannot free this memory directly. +** Instead, the entire table should be passed to sqlite3_free_table() when +** the calling procedure is finished using it. +*/ +SQLITE_API int sqlite3_get_table( + sqlite3 *db, /* The database on which the SQL executes */ + const char *zSql, /* The SQL to be executed */ + char ***pazResult, /* Write the result table here */ + int *pnRow, /* Write the number of rows in the result here */ + int *pnColumn, /* Write the number of columns of result here */ + char **pzErrMsg /* Write error messages here */ +){ + int rc; + TabResult res; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || pazResult==0 ) return SQLITE_MISUSE_BKPT; +#endif + *pazResult = 0; + if( pnColumn ) *pnColumn = 0; + if( pnRow ) *pnRow = 0; + if( pzErrMsg ) *pzErrMsg = 0; + res.zErrMsg = 0; + res.nRow = 0; + res.nColumn = 0; + res.nData = 1; + res.nAlloc = 20; + res.rc = SQLITE_OK; + res.azResult = sqlite3_malloc64(sizeof(char*)*res.nAlloc ); + if( res.azResult==0 ){ + db->errCode = SQLITE_NOMEM; + return SQLITE_NOMEM_BKPT; + } + res.azResult[0] = 0; + rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg); + assert( sizeof(res.azResult[0])>= sizeof(res.nData) ); + res.azResult[0] = SQLITE_INT_TO_PTR(res.nData); + if( (rc&0xff)==SQLITE_ABORT ){ + sqlite3_free_table(&res.azResult[1]); + if( res.zErrMsg ){ + if( pzErrMsg ){ + sqlite3_free(*pzErrMsg); + *pzErrMsg = sqlite3_mprintf("%s",res.zErrMsg); + } + sqlite3_free(res.zErrMsg); + } + db->errCode = res.rc; /* Assume 32-bit assignment is atomic */ + return res.rc; + } + sqlite3_free(res.zErrMsg); + if( rc!=SQLITE_OK ){ + sqlite3_free_table(&res.azResult[1]); + return rc; + } + if( res.nAlloc>res.nData ){ + char **azNew; + azNew = sqlite3Realloc( res.azResult, sizeof(char*)*res.nData ); + if( azNew==0 ){ + sqlite3_free_table(&res.azResult[1]); + db->errCode = SQLITE_NOMEM; + return SQLITE_NOMEM_BKPT; + } + res.azResult = azNew; + } + *pazResult = &res.azResult[1]; + if( pnColumn ) *pnColumn = res.nColumn; + if( pnRow ) *pnRow = res.nRow; + return rc; +} + +/* +** This routine frees the space the sqlite3_get_table() malloced. +*/ +SQLITE_API void sqlite3_free_table( + char **azResult /* Result returned from sqlite3_get_table() */ +){ + if( azResult ){ + int i, n; + azResult--; + assert( azResult!=0 ); + n = SQLITE_PTR_TO_INT(azResult[0]); + for(i=1; ipNext; + + sqlite3ExprDelete(db, pTmp->pWhere); + sqlite3ExprListDelete(db, pTmp->pExprList); + sqlite3SelectDelete(db, pTmp->pSelect); + sqlite3IdListDelete(db, pTmp->pIdList); + sqlite3UpsertDelete(db, pTmp->pUpsert); + sqlite3SrcListDelete(db, pTmp->pSrc); + sqlite3DbFree(db, pTmp->zSpan); + + sqlite3DbFree(db, pTmp); + } +} + +/* +** Given table pTab, return a list of all the triggers attached to +** the table. The list is connected by Trigger.pNext pointers. +** +** All of the triggers on pTab that are in the same database as pTab +** are already attached to pTab->pTrigger. But there might be additional +** triggers on pTab in the TEMP schema. This routine prepends all +** TEMP triggers on pTab to the beginning of the pTab->pTrigger list +** and returns the combined list. +** +** To state it another way: This routine returns a list of all triggers +** that fire off of pTab. The list will include any TEMP triggers on +** pTab as well as the triggers lised in pTab->pTrigger. +*/ +SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){ + Schema *pTmpSchema; /* Schema of the pTab table */ + Trigger *pList; /* List of triggers to return */ + HashElem *p; /* Loop variable for TEMP triggers */ + + assert( pParse->disableTriggers==0 ); + pTmpSchema = pParse->db->aDb[1].pSchema; + p = sqliteHashFirst(&pTmpSchema->trigHash); + pList = pTab->pTrigger; + while( p ){ + Trigger *pTrig = (Trigger *)sqliteHashData(p); + if( pTrig->pTabSchema==pTab->pSchema + && pTrig->table + && 0==sqlite3StrICmp(pTrig->table, pTab->zName) + && (pTrig->pTabSchema!=pTmpSchema || pTrig->bReturning) + ){ + pTrig->pNext = pList; + pList = pTrig; + }else if( pTrig->op==TK_RETURNING ){ +#ifndef SQLITE_OMIT_VIRTUALTABLE + assert( pParse->db->pVtabCtx==0 ); +#endif + assert( pParse->bReturning ); + assert( !pParse->isCreate ); + assert( &(pParse->u1.d.pReturning->retTrig) == pTrig ); + pTrig->table = pTab->zName; + pTrig->pTabSchema = pTab->pSchema; + pTrig->pNext = pList; + pList = pTrig; + } + p = sqliteHashNext(p); + } +#if 0 + if( pList ){ + Trigger *pX; + printf("Triggers for %s:", pTab->zName); + for(pX=pList; pX; pX=pX->pNext){ + printf(" %s", pX->zName); + } + printf("\n"); + fflush(stdout); + } +#endif + return pList; +} + +/* +** This is called by the parser when it sees a CREATE TRIGGER statement +** up to the point of the BEGIN before the trigger actions. A Trigger +** structure is generated based on the information available and stored +** in pParse->pNewTrigger. After the trigger actions have been parsed, the +** sqlite3FinishTrigger() function is called to complete the trigger +** construction process. +*/ +SQLITE_PRIVATE void sqlite3BeginTrigger( + Parse *pParse, /* The parse context of the CREATE TRIGGER statement */ + Token *pName1, /* The name of the trigger */ + Token *pName2, /* The name of the trigger */ + int tr_tm, /* One of TK_BEFORE, TK_AFTER, TK_INSTEAD */ + int op, /* One of TK_INSERT, TK_UPDATE, TK_DELETE */ + IdList *pColumns, /* column list if this is an UPDATE OF trigger */ + SrcList *pTableName,/* The name of the table/view the trigger applies to */ + Expr *pWhen, /* WHEN clause */ + int isTemp, /* True if the TEMPORARY keyword is present */ + int noErr /* Suppress errors if the trigger already exists */ +){ + Trigger *pTrigger = 0; /* The new trigger */ + Table *pTab; /* Table that the trigger fires off of */ + char *zName = 0; /* Name of the trigger */ + sqlite3 *db = pParse->db; /* The database connection */ + int iDb; /* The database to store the trigger in */ + Token *pName; /* The unqualified db name */ + DbFixer sFix; /* State vector for the DB fixer */ + + assert( pName1!=0 ); /* pName1->z might be NULL, but not pName1 itself */ + assert( pName2!=0 ); + assert( op==TK_INSERT || op==TK_UPDATE || op==TK_DELETE ); + assert( op>0 && op<0xff ); + if( isTemp ){ + /* If TEMP was specified, then the trigger name may not be qualified. */ + if( pName2->n>0 ){ + sqlite3ErrorMsg(pParse, "temporary trigger may not have qualified name"); + goto trigger_cleanup; + } + iDb = 1; + pName = pName1; + }else{ + /* Figure out the db that the trigger will be created in */ + iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName); + if( iDb<0 ){ + goto trigger_cleanup; + } + } + if( !pTableName || db->mallocFailed ){ + goto trigger_cleanup; + } + + /* A long-standing parser bug is that this syntax was allowed: + ** + ** CREATE TRIGGER attached.demo AFTER INSERT ON attached.tab .... + ** ^^^^^^^^ + ** + ** To maintain backwards compatibility, ignore the database + ** name on pTableName if we are reparsing out of the schema table + */ + if( db->init.busy && iDb!=1 ){ + assert( pTableName->a[0].fg.fixedSchema==0 ); + assert( pTableName->a[0].fg.isSubquery==0 ); + sqlite3DbFree(db, pTableName->a[0].u4.zDatabase); + pTableName->a[0].u4.zDatabase = 0; + } + + /* If the trigger name was unqualified, and the table is a temp table, + ** then set iDb to 1 to create the trigger in the temporary database. + ** If sqlite3SrcListLookup() returns 0, indicating the table does not + ** exist, the error is caught by the block below. + */ + pTab = sqlite3SrcListLookup(pParse, pTableName); + if( db->init.busy==0 && pName2->n==0 && pTab + && pTab->pSchema==db->aDb[1].pSchema ){ + iDb = 1; + } + + /* Ensure the table name matches database name and that the table exists */ + if( db->mallocFailed ) goto trigger_cleanup; + assert( pTableName->nSrc==1 ); + sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName); + if( sqlite3FixSrcList(&sFix, pTableName) ){ + goto trigger_cleanup; + } + pTab = sqlite3SrcListLookup(pParse, pTableName); + if( !pTab ){ + /* The table does not exist. */ + goto trigger_orphan_error; + } + if( IsVirtual(pTab) ){ + sqlite3ErrorMsg(pParse, "cannot create triggers on virtual tables"); + goto trigger_orphan_error; + } + if( (pTab->tabFlags & TF_Shadow)!=0 && sqlite3ReadOnlyShadowTables(db) ){ + sqlite3ErrorMsg(pParse, "cannot create triggers on shadow tables"); + goto trigger_orphan_error; + } + + /* Check that the trigger name is not reserved and that no trigger of the + ** specified name exists */ + zName = sqlite3NameFromToken(db, pName); + if( zName==0 ){ + assert( db->mallocFailed ); + goto trigger_cleanup; + } + if( sqlite3CheckObjectName(pParse, zName, "trigger", pTab->zName) ){ + goto trigger_cleanup; + } + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + if( !IN_RENAME_OBJECT ){ + if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){ + if( !noErr ){ + sqlite3ErrorMsg(pParse, "trigger %T already exists", pName); + }else{ + assert( !db->init.busy ); + sqlite3CodeVerifySchema(pParse, iDb); + VVA_ONLY( pParse->ifNotExists = 1; ) + } + goto trigger_cleanup; + } + } + + /* NB: The SQLITE_ALLOW_TRIGGERS_ON_SYSTEM_TABLES compile-time option is + ** experimental and unsupported. Do not use it unless understand the + ** implications and you cannot get by without this capability. */ +#if !defined(SQLITE_ALLOW_TRIGGERS_ON_SYSTEM_TABLES) /* Experimental */ + /* Do not create a trigger on a system table */ + if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){ + sqlite3ErrorMsg(pParse, "cannot create trigger on system table"); + goto trigger_cleanup; + } +#endif + + /* INSTEAD of triggers are only for views and views only support INSTEAD + ** of triggers. + */ + if( IsView(pTab) && tr_tm!=TK_INSTEAD ){ + sqlite3ErrorMsg(pParse, "cannot create %s trigger on view: %S", + (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName->a); + goto trigger_orphan_error; + } + if( !IsView(pTab) && tr_tm==TK_INSTEAD ){ + sqlite3ErrorMsg(pParse, "cannot create INSTEAD OF" + " trigger on table: %S", pTableName->a); + goto trigger_orphan_error; + } + +#ifndef SQLITE_OMIT_AUTHORIZATION + if( !IN_RENAME_OBJECT ){ + int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); + int code = SQLITE_CREATE_TRIGGER; + const char *zDb = db->aDb[iTabDb].zDbSName; + const char *zDbTrig = isTemp ? db->aDb[1].zDbSName : zDb; + if( iTabDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER; + if( sqlite3AuthCheck(pParse, code, zName, pTab->zName, zDbTrig) ){ + goto trigger_cleanup; + } + if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iTabDb),0,zDb)){ + goto trigger_cleanup; + } + } +#endif + + /* INSTEAD OF triggers can only appear on views and BEFORE triggers + ** cannot appear on views. So we might as well translate every + ** INSTEAD OF trigger into a BEFORE trigger. It simplifies code + ** elsewhere. + */ + if (tr_tm == TK_INSTEAD){ + tr_tm = TK_BEFORE; + } + + /* Build the Trigger object */ + pTrigger = (Trigger*)sqlite3DbMallocZero(db, sizeof(Trigger)); + if( pTrigger==0 ) goto trigger_cleanup; + pTrigger->zName = zName; + zName = 0; + pTrigger->table = sqlite3DbStrDup(db, pTableName->a[0].zName); + pTrigger->pSchema = db->aDb[iDb].pSchema; + pTrigger->pTabSchema = pTab->pSchema; + pTrigger->op = (u8)op; + pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER; + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, pTrigger->table, pTableName->a[0].zName); + pTrigger->pWhen = pWhen; + pWhen = 0; + }else{ + pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); + } + pTrigger->pColumns = pColumns; + pColumns = 0; + assert( pParse->pNewTrigger==0 ); + pParse->pNewTrigger = pTrigger; + +trigger_cleanup: + sqlite3DbFree(db, zName); + sqlite3SrcListDelete(db, pTableName); + sqlite3IdListDelete(db, pColumns); + sqlite3ExprDelete(db, pWhen); + if( !pParse->pNewTrigger ){ + sqlite3DeleteTrigger(db, pTrigger); + }else{ + assert( pParse->pNewTrigger==pTrigger ); + } + return; + +trigger_orphan_error: + if( db->init.iDb==1 ){ + /* Ticket #3810. + ** Normally, whenever a table is dropped, all associated triggers are + ** dropped too. But if a TEMP trigger is created on a non-TEMP table + ** and the table is dropped by a different database connection, the + ** trigger is not visible to the database connection that does the + ** drop so the trigger cannot be dropped. This results in an + ** "orphaned trigger" - a trigger whose associated table is missing. + ** + ** 2020-11-05 see also https://sqlite.org/forum/forumpost/157dc791df + */ + db->init.orphanTrigger = 1; + } + goto trigger_cleanup; +} + +/* +** This routine is called after all of the trigger actions have been parsed +** in order to complete the process of building the trigger. +*/ +SQLITE_PRIVATE void sqlite3FinishTrigger( + Parse *pParse, /* Parser context */ + TriggerStep *pStepList, /* The triggered program */ + Token *pAll /* Token that describes the complete CREATE TRIGGER */ +){ + Trigger *pTrig = pParse->pNewTrigger; /* Trigger being finished */ + char *zName; /* Name of trigger */ + sqlite3 *db = pParse->db; /* The database */ + DbFixer sFix; /* Fixer object */ + int iDb; /* Database containing the trigger */ + Token nameToken; /* Trigger name for error reporting */ + + pParse->pNewTrigger = 0; + if( NEVER(pParse->nErr) || !pTrig ) goto triggerfinish_cleanup; + zName = pTrig->zName; + iDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema); + assert( iDb>=00 && iDbnDb ); + pTrig->step_list = pStepList; + while( pStepList ){ + pStepList->pTrig = pTrig; + pStepList = pStepList->pNext; + } + sqlite3TokenInit(&nameToken, pTrig->zName); + sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken); + if( sqlite3FixTriggerStep(&sFix, pTrig->step_list) + || sqlite3FixExpr(&sFix, pTrig->pWhen) + ){ + goto triggerfinish_cleanup; + } + +#ifndef SQLITE_OMIT_ALTERTABLE + if( IN_RENAME_OBJECT ){ + assert( !db->init.busy ); + pParse->pNewTrigger = pTrig; + pTrig = 0; + }else +#endif + + /* if we are not initializing, + ** build the sqlite_schema entry + */ + if( !db->init.busy ){ + Vdbe *v; + char *z; + + /* If this is a new CREATE TABLE statement, and if shadow tables + ** are read-only, and the trigger makes a change to a shadow table, + ** then raise an error - do not allow the trigger to be created. */ + if( sqlite3ReadOnlyShadowTables(db) ){ + TriggerStep *pStep; + for(pStep=pTrig->step_list; pStep; pStep=pStep->pNext){ + if( pStep->pSrc!=0 + && sqlite3ShadowTableName(db, pStep->pSrc->a[0].zName) + ){ + sqlite3ErrorMsg(pParse, + "trigger \"%s\" may not write to shadow table \"%s\"", + pTrig->zName, pStep->pSrc->a[0].zName); + goto triggerfinish_cleanup; + } + } + } + + /* Make an entry in the sqlite_schema table */ + v = sqlite3GetVdbe(pParse); + if( v==0 ) goto triggerfinish_cleanup; + sqlite3BeginWriteOperation(pParse, 0, iDb); + z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n); + testcase( z==0 ); + sqlite3NestedParse(pParse, + "INSERT INTO %Q." LEGACY_SCHEMA_TABLE + " VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')", + db->aDb[iDb].zDbSName, zName, + pTrig->table, z); + sqlite3DbFree(db, z); + sqlite3ChangeCookie(pParse, iDb); + sqlite3VdbeAddParseSchemaOp(v, iDb, + sqlite3MPrintf(db, "type='trigger' AND name='%q'", zName), 0); + } + + if( db->init.busy ){ + Trigger *pLink = pTrig; + Hash *pHash = &db->aDb[iDb].pSchema->trigHash; + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( pLink!=0 ); + pTrig = sqlite3HashInsert(pHash, zName, pTrig); + if( pTrig ){ + sqlite3OomFault(db); + }else if( pLink->pSchema==pLink->pTabSchema ){ + Table *pTab; + pTab = sqlite3HashFind(&pLink->pTabSchema->tblHash, pLink->table); + assert( pTab!=0 ); + pLink->pNext = pTab->pTrigger; + pTab->pTrigger = pLink; + } + } + +triggerfinish_cleanup: + sqlite3DeleteTrigger(db, pTrig); + assert( IN_RENAME_OBJECT || !pParse->pNewTrigger ); + sqlite3DeleteTriggerStep(db, pStepList); +} + +/* +** Duplicate a range of text from an SQL statement, then convert all +** whitespace characters into ordinary space characters. +*/ +static char *triggerSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){ + char *z = sqlite3DbSpanDup(db, zStart, zEnd); + int i; + if( z ) for(i=0; z[i]; i++) if( sqlite3Isspace(z[i]) ) z[i] = ' '; + return z; +} + +/* +** Turn a SELECT statement (that the pSelect parameter points to) into +** a trigger step. Return a pointer to a TriggerStep structure. +** +** The parser calls this routine when it finds a SELECT statement in +** body of a TRIGGER. +*/ +SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep( + sqlite3 *db, /* Database connection */ + Select *pSelect, /* The SELECT statement */ + const char *zStart, /* Start of SQL text */ + const char *zEnd /* End of SQL text */ +){ + TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep)); + if( pTriggerStep==0 ) { + sqlite3SelectDelete(db, pSelect); + return 0; + } + pTriggerStep->op = TK_SELECT; + pTriggerStep->pSelect = pSelect; + pTriggerStep->orconf = OE_Default; + pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd); + return pTriggerStep; +} + +/* +** Allocate space to hold a new trigger step. The allocated space +** holds both the TriggerStep object and the TriggerStep.target.z string. +** +** If an OOM error occurs, NULL is returned and db->mallocFailed is set. +*/ +static TriggerStep *triggerStepAllocate( + Parse *pParse, /* Parser context */ + u8 op, /* Trigger opcode */ + SrcList *pTabList, /* Target table */ + const char *zStart, /* Start of SQL text */ + const char *zEnd /* End of SQL text */ +){ + Trigger *pNew = pParse->pNewTrigger; + sqlite3 *db = pParse->db; + TriggerStep *pTriggerStep = 0; + + if( pParse->nErr==0 ){ + if( pNew + && pNew->pSchema!=db->aDb[1].pSchema + && pTabList->a[0].u4.zDatabase + ){ + sqlite3ErrorMsg(pParse, + "qualified table names are not allowed on INSERT, UPDATE, and DELETE " + "statements within triggers"); + }else{ + pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep)); + if( pTriggerStep ){ + pTriggerStep->pSrc = sqlite3SrcListDup(db, pTabList, EXPRDUP_REDUCE); + pTriggerStep->op = op; + pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd); + if( pTriggerStep->pSrc && IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, + pTriggerStep->pSrc->a[0].zName, + pTabList->a[0].zName + ); + } + } + } + } + + sqlite3SrcListDelete(db, pTabList); + return pTriggerStep; +} + +/* +** Build a trigger step out of an INSERT statement. Return a pointer +** to the new trigger step. +** +** The parser calls this routine when it sees an INSERT inside the +** body of a trigger. +*/ +SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep( + Parse *pParse, /* Parser */ + SrcList *pTabList, /* Table to INSERT into */ + IdList *pColumn, /* List of columns in pTableName to insert into */ + Select *pSelect, /* A SELECT statement that supplies values */ + u8 orconf, /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */ + Upsert *pUpsert, /* ON CONFLICT clauses for upsert */ + const char *zStart, /* Start of SQL text */ + const char *zEnd /* End of SQL text */ +){ + sqlite3 *db = pParse->db; + TriggerStep *pTriggerStep; + + assert(pSelect != 0 || db->mallocFailed); + + pTriggerStep = triggerStepAllocate(pParse, TK_INSERT, pTabList, zStart, zEnd); + if( pTriggerStep ){ + if( IN_RENAME_OBJECT ){ + pTriggerStep->pSelect = pSelect; + pSelect = 0; + }else{ + pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); + } + pTriggerStep->pIdList = pColumn; + pTriggerStep->pUpsert = pUpsert; + pTriggerStep->orconf = orconf; + if( pUpsert ){ + sqlite3HasExplicitNulls(pParse, pUpsert->pUpsertTarget); + } + }else{ + testcase( pColumn ); + sqlite3IdListDelete(db, pColumn); + testcase( pUpsert ); + sqlite3UpsertDelete(db, pUpsert); + } + sqlite3SelectDelete(db, pSelect); + + return pTriggerStep; +} + +/* +** Construct a trigger step that implements an UPDATE statement and return +** a pointer to that trigger step. The parser calls this routine when it +** sees an UPDATE statement inside the body of a CREATE TRIGGER. +*/ +SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep( + Parse *pParse, /* Parser */ + SrcList *pTabList, /* Name of the table to be updated */ + SrcList *pFrom, /* FROM clause for an UPDATE-FROM, or NULL */ + ExprList *pEList, /* The SET clause: list of column and new values */ + Expr *pWhere, /* The WHERE clause */ + u8 orconf, /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */ + const char *zStart, /* Start of SQL text */ + const char *zEnd /* End of SQL text */ +){ + sqlite3 *db = pParse->db; + TriggerStep *pTriggerStep; + + pTriggerStep = triggerStepAllocate(pParse, TK_UPDATE, pTabList, zStart, zEnd); + if( pTriggerStep ){ + SrcList *pFromDup = 0; + if( IN_RENAME_OBJECT ){ + pTriggerStep->pExprList = pEList; + pTriggerStep->pWhere = pWhere; + pFromDup = pFrom; + pEList = 0; + pWhere = 0; + pFrom = 0; + }else{ + pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE); + pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); + pFromDup = sqlite3SrcListDup(db, pFrom, EXPRDUP_REDUCE); + } + pTriggerStep->orconf = orconf; + + if( pFromDup && !IN_RENAME_OBJECT){ + Select *pSub; + Token as = {0, 0}; + pSub = sqlite3SelectNew(pParse, 0, pFromDup, 0,0,0,0, SF_NestedFrom, 0); + pFromDup = sqlite3SrcListAppendFromTerm(pParse, 0, 0, 0, &as, pSub ,0); + } + if( pFromDup && pTriggerStep->pSrc ){ + pTriggerStep->pSrc = sqlite3SrcListAppendList( + pParse, pTriggerStep->pSrc, pFromDup + ); + }else{ + sqlite3SrcListDelete(db, pFromDup); + } + } + sqlite3ExprListDelete(db, pEList); + sqlite3ExprDelete(db, pWhere); + sqlite3SrcListDelete(db, pFrom); + return pTriggerStep; +} + +/* +** Construct a trigger step that implements a DELETE statement and return +** a pointer to that trigger step. The parser calls this routine when it +** sees a DELETE statement inside the body of a CREATE TRIGGER. +*/ +SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep( + Parse *pParse, /* Parser */ + SrcList *pTabList, /* The table from which rows are deleted */ + Expr *pWhere, /* The WHERE clause */ + const char *zStart, /* Start of SQL text */ + const char *zEnd /* End of SQL text */ +){ + sqlite3 *db = pParse->db; + TriggerStep *pTriggerStep; + + pTriggerStep = triggerStepAllocate(pParse, TK_DELETE, pTabList, zStart, zEnd); + if( pTriggerStep ){ + if( IN_RENAME_OBJECT ){ + pTriggerStep->pWhere = pWhere; + pWhere = 0; + }else{ + pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); + } + pTriggerStep->orconf = OE_Default; + } + sqlite3ExprDelete(db, pWhere); + return pTriggerStep; +} + +/* +** Recursively delete a Trigger structure +*/ +SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){ + if( pTrigger==0 || pTrigger->bReturning ) return; + sqlite3DeleteTriggerStep(db, pTrigger->step_list); + sqlite3DbFree(db, pTrigger->zName); + sqlite3DbFree(db, pTrigger->table); + sqlite3ExprDelete(db, pTrigger->pWhen); + sqlite3IdListDelete(db, pTrigger->pColumns); + sqlite3DbFree(db, pTrigger); +} + +/* +** This function is called to drop a trigger from the database schema. +** +** This may be called directly from the parser and therefore identifies +** the trigger by name. The sqlite3DropTriggerPtr() routine does the +** same job as this routine except it takes a pointer to the trigger +** instead of the trigger name. +**/ +SQLITE_PRIVATE void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){ + Trigger *pTrigger = 0; + int i; + const char *zDb; + const char *zName; + sqlite3 *db = pParse->db; + + if( db->mallocFailed ) goto drop_trigger_cleanup; + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + goto drop_trigger_cleanup; + } + + assert( pName->nSrc==1 ); + assert( pName->a[0].fg.fixedSchema==0 && pName->a[0].fg.isSubquery==0 ); + zDb = pName->a[0].u4.zDatabase; + zName = pName->a[0].zName; + assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) ); + for(i=OMIT_TEMPDB; inDb; i++){ + int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ + if( zDb && sqlite3DbIsNamed(db, j, zDb)==0 ) continue; + assert( sqlite3SchemaMutexHeld(db, j, 0) ); + pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName); + if( pTrigger ) break; + } + if( !pTrigger ){ + if( !noErr ){ + sqlite3ErrorMsg(pParse, "no such trigger: %S", pName->a); + }else{ + sqlite3CodeVerifyNamedSchema(pParse, zDb); + } + pParse->checkSchema = 1; + goto drop_trigger_cleanup; + } + sqlite3DropTriggerPtr(pParse, pTrigger); + +drop_trigger_cleanup: + sqlite3SrcListDelete(db, pName); +} + +/* +** Return a pointer to the Table structure for the table that a trigger +** is set on. +*/ +static Table *tableOfTrigger(Trigger *pTrigger){ + return sqlite3HashFind(&pTrigger->pTabSchema->tblHash, pTrigger->table); +} + + +/* +** Drop a trigger given a pointer to that trigger. +*/ +SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){ + Table *pTable; + Vdbe *v; + sqlite3 *db = pParse->db; + int iDb; + + iDb = sqlite3SchemaToIndex(pParse->db, pTrigger->pSchema); + assert( iDb>=0 && iDbnDb ); + pTable = tableOfTrigger(pTrigger); + assert( (pTable && pTable->pSchema==pTrigger->pSchema) || iDb==1 ); +#ifndef SQLITE_OMIT_AUTHORIZATION + if( pTable ){ + int code = SQLITE_DROP_TRIGGER; + const char *zDb = db->aDb[iDb].zDbSName; + const char *zTab = SCHEMA_TABLE(iDb); + if( iDb==1 ) code = SQLITE_DROP_TEMP_TRIGGER; + if( sqlite3AuthCheck(pParse, code, pTrigger->zName, pTable->zName, zDb) || + sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){ + return; + } + } +#endif + + /* Generate code to destroy the database record of the trigger. + */ + if( (v = sqlite3GetVdbe(pParse))!=0 ){ + sqlite3NestedParse(pParse, + "DELETE FROM %Q." LEGACY_SCHEMA_TABLE " WHERE name=%Q AND type='trigger'", + db->aDb[iDb].zDbSName, pTrigger->zName + ); + sqlite3ChangeCookie(pParse, iDb); + sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0); + } +} + +/* +** Remove a trigger from the hash tables of the sqlite* pointer. +*/ +SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){ + Trigger *pTrigger; + Hash *pHash; + + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + pHash = &(db->aDb[iDb].pSchema->trigHash); + pTrigger = sqlite3HashInsert(pHash, zName, 0); + if( ALWAYS(pTrigger) ){ + if( pTrigger->pSchema==pTrigger->pTabSchema ){ + Table *pTab = tableOfTrigger(pTrigger); + if( pTab ){ + Trigger **pp; + for(pp=&pTab->pTrigger; *pp; pp=&((*pp)->pNext)){ + if( *pp==pTrigger ){ + *pp = (*pp)->pNext; + break; + } + } + } + } + sqlite3DeleteTrigger(db, pTrigger); + db->mDbFlags |= DBFLAG_SchemaChange; + } +} + +/* +** pEList is the SET clause of an UPDATE statement. Each entry +** in pEList is of the format =. If any of the entries +** in pEList have an which matches an identifier in pIdList, +** then return TRUE. If pIdList==NULL, then it is considered a +** wildcard that matches anything. Likewise if pEList==NULL then +** it matches anything so always return true. Return false only +** if there is no match. +*/ +static int checkColumnOverlap(IdList *pIdList, ExprList *pEList){ + int e; + if( pIdList==0 || NEVER(pEList==0) ) return 1; + for(e=0; enExpr; e++){ + if( sqlite3IdListIndex(pIdList, pEList->a[e].zEName)>=0 ) return 1; + } + return 0; +} + +/* +** Return true if any TEMP triggers exist +*/ +static int tempTriggersExist(sqlite3 *db){ + if( NEVER(db->aDb[1].pSchema==0) ) return 0; + if( sqliteHashFirst(&db->aDb[1].pSchema->trigHash)==0 ) return 0; + return 1; +} + +/* +** Return a list of all triggers on table pTab if there exists at least +** one trigger that must be fired when an operation of type 'op' is +** performed on the table, and, if that operation is an UPDATE, if at +** least one of the columns in pChanges is being modified. +*/ +static SQLITE_NOINLINE Trigger *triggersReallyExist( + Parse *pParse, /* Parse context */ + Table *pTab, /* The table the contains the triggers */ + int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */ + ExprList *pChanges, /* Columns that change in an UPDATE statement */ + int *pMask /* OUT: Mask of TRIGGER_BEFORE|TRIGGER_AFTER */ +){ + int mask = 0; + Trigger *pList = 0; + Trigger *p; + + pList = sqlite3TriggerList(pParse, pTab); + assert( pList==0 || IsVirtual(pTab)==0 + || (pList->bReturning && pList->pNext==0) ); + if( pList!=0 ){ + p = pList; + if( (pParse->db->flags & SQLITE_EnableTrigger)==0 + && pTab->pTrigger!=0 + && sqlite3SchemaToIndex(pParse->db, pTab->pTrigger->pSchema)!=1 + ){ + /* The SQLITE_DBCONFIG_ENABLE_TRIGGER setting is off. That means that + ** only TEMP triggers are allowed. Truncate the pList so that it + ** includes only TEMP triggers */ + if( pList==pTab->pTrigger ){ + pList = 0; + goto exit_triggers_exist; + } + while( ALWAYS(p->pNext) && p->pNext!=pTab->pTrigger ) p = p->pNext; + p->pNext = 0; + p = pList; + } + do{ + if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){ + mask |= p->tr_tm; + }else if( p->op==TK_RETURNING ){ + /* The first time a RETURNING trigger is seen, the "op" value tells + ** us what time of trigger it should be. */ + assert( sqlite3IsToplevel(pParse) ); + p->op = op; + if( IsVirtual(pTab) ){ + if( op!=TK_INSERT ){ + sqlite3ErrorMsg(pParse, + "%s RETURNING is not available on virtual tables", + op==TK_DELETE ? "DELETE" : "UPDATE"); + } + p->tr_tm = TRIGGER_BEFORE; + }else{ + p->tr_tm = TRIGGER_AFTER; + } + mask |= p->tr_tm; + }else if( p->bReturning && p->op==TK_INSERT && op==TK_UPDATE + && sqlite3IsToplevel(pParse) ){ + /* Also fire a RETURNING trigger for an UPSERT */ + mask |= p->tr_tm; + } + p = p->pNext; + }while( p ); + } +exit_triggers_exist: + if( pMask ){ + *pMask = mask; + } + return (mask ? pList : 0); +} +SQLITE_PRIVATE Trigger *sqlite3TriggersExist( + Parse *pParse, /* Parse context */ + Table *pTab, /* The table the contains the triggers */ + int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */ + ExprList *pChanges, /* Columns that change in an UPDATE statement */ + int *pMask /* OUT: Mask of TRIGGER_BEFORE|TRIGGER_AFTER */ +){ + assert( pTab!=0 ); + if( (pTab->pTrigger==0 && !tempTriggersExist(pParse->db)) + || pParse->disableTriggers + ){ + if( pMask ) *pMask = 0; + return 0; + } + return triggersReallyExist(pParse,pTab,op,pChanges,pMask); +} + +/* +** Return true if the pExpr term from the RETURNING clause argument +** list is of the form "*". Raise an error if the terms if of the +** form "table.*". +*/ +static int isAsteriskTerm( + Parse *pParse, /* Parsing context */ + Expr *pTerm /* A term in the RETURNING clause */ +){ + assert( pTerm!=0 ); + if( pTerm->op==TK_ASTERISK ) return 1; + if( pTerm->op!=TK_DOT ) return 0; + assert( pTerm->pRight!=0 ); + assert( pTerm->pLeft!=0 ); + if( pTerm->pRight->op!=TK_ASTERISK ) return 0; + sqlite3ErrorMsg(pParse, "RETURNING may not use \"TABLE.*\" wildcards"); + return 1; +} + +/* The input list pList is the list of result set terms from a RETURNING +** clause. The table that we are returning from is pTab. +** +** This routine makes a copy of the pList, and at the same time expands +** any "*" wildcards to be the complete set of columns from pTab. +*/ +static ExprList *sqlite3ExpandReturning( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* The arguments to RETURNING */ + Table *pTab /* The table being updated */ +){ + ExprList *pNew = 0; + sqlite3 *db = pParse->db; + int i; + + for(i=0; inExpr; i++){ + Expr *pOldExpr = pList->a[i].pExpr; + if( NEVER(pOldExpr==0) ) continue; + if( isAsteriskTerm(pParse, pOldExpr) ){ + int jj; + for(jj=0; jjnCol; jj++){ + Expr *pNewExpr; + if( IsHiddenColumn(pTab->aCol+jj) ) continue; + pNewExpr = sqlite3Expr(db, TK_ID, pTab->aCol[jj].zCnName); + pNew = sqlite3ExprListAppend(pParse, pNew, pNewExpr); + if( !db->mallocFailed ){ + struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1]; + pItem->zEName = sqlite3DbStrDup(db, pTab->aCol[jj].zCnName); + pItem->fg.eEName = ENAME_NAME; + } + } + }else{ + Expr *pNewExpr = sqlite3ExprDup(db, pOldExpr, 0); + pNew = sqlite3ExprListAppend(pParse, pNew, pNewExpr); + if( !db->mallocFailed && ALWAYS(pList->a[i].zEName!=0) ){ + struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1]; + pItem->zEName = sqlite3DbStrDup(db, pList->a[i].zEName); + pItem->fg.eEName = pList->a[i].fg.eEName; + } + } + } + return pNew; +} + +/* If the Expr node is a subquery or an EXISTS operator or an IN operator that +** uses a subquery, and if the subquery is SF_Correlated, then mark the +** expression as EP_VarSelect. +*/ +static int sqlite3ReturningSubqueryVarSelect(Walker *NotUsed, Expr *pExpr){ + UNUSED_PARAMETER(NotUsed); + if( ExprUseXSelect(pExpr) + && (pExpr->x.pSelect->selFlags & SF_Correlated)!=0 + ){ + testcase( ExprHasProperty(pExpr, EP_VarSelect) ); + ExprSetProperty(pExpr, EP_VarSelect); + } + return WRC_Continue; +} + + +/* +** If the SELECT references the table pWalker->u.pTab, then do two things: +** +** (1) Mark the SELECT as as SF_Correlated. +** (2) Set pWalker->eCode to non-zero so that the caller will know +** that (1) has happened. +*/ +static int sqlite3ReturningSubqueryCorrelated(Walker *pWalker, Select *pSelect){ + int i; + SrcList *pSrc; + assert( pSelect!=0 ); + pSrc = pSelect->pSrc; + assert( pSrc!=0 ); + for(i=0; inSrc; i++){ + if( pSrc->a[i].pSTab==pWalker->u.pTab ){ + testcase( pSelect->selFlags & SF_Correlated ); + pSelect->selFlags |= SF_Correlated; + pWalker->eCode = 1; + break; + } + } + return WRC_Continue; +} + +/* +** Scan the expression list that is the argument to RETURNING looking +** for subqueries that depend on the table which is being modified in the +** statement that is hosting the RETURNING clause (pTab). Mark all such +** subqueries as SF_Correlated. If the subqueries are part of an +** expression, mark the expression as EP_VarSelect. +** +** https://sqlite.org/forum/forumpost/2c83569ce8945d39 +*/ +static void sqlite3ProcessReturningSubqueries( + ExprList *pEList, + Table *pTab +){ + Walker w; + memset(&w, 0, sizeof(w)); + w.xExprCallback = sqlite3ExprWalkNoop; + w.xSelectCallback = sqlite3ReturningSubqueryCorrelated; + w.u.pTab = pTab; + sqlite3WalkExprList(&w, pEList); + if( w.eCode ){ + w.xExprCallback = sqlite3ReturningSubqueryVarSelect; + w.xSelectCallback = sqlite3SelectWalkNoop; + sqlite3WalkExprList(&w, pEList); + } +} + +/* +** Generate code for the RETURNING trigger. Unlike other triggers +** that invoke a subprogram in the bytecode, the code for RETURNING +** is generated in-line. +*/ +static void codeReturningTrigger( + Parse *pParse, /* Parse context */ + Trigger *pTrigger, /* The trigger step that defines the RETURNING */ + Table *pTab, /* The table to code triggers from */ + int regIn /* The first in an array of registers */ +){ + Vdbe *v = pParse->pVdbe; + sqlite3 *db = pParse->db; + ExprList *pNew; + Returning *pReturning; + Select sSelect; + SrcList *pFrom; + union { + SrcList sSrc; + u8 fromSpace[SZ_SRCLIST_1]; + } uSrc; + + assert( v!=0 ); + if( !pParse->bReturning ){ + /* This RETURNING trigger must be for a different statement as + ** this statement lacks a RETURNING clause. */ + return; + } + assert( db->pParse==pParse ); + assert( !pParse->isCreate ); + pReturning = pParse->u1.d.pReturning; + if( pTrigger != &(pReturning->retTrig) ){ + /* This RETURNING trigger is for a different statement */ + return; + } + memset(&sSelect, 0, sizeof(sSelect)); + memset(&uSrc, 0, sizeof(uSrc)); + pFrom = &uSrc.sSrc; + sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0); + sSelect.pSrc = pFrom; + pFrom->nSrc = 1; + pFrom->a[0].pSTab = pTab; + pFrom->a[0].zName = pTab->zName; /* tag-20240424-1 */ + pFrom->a[0].iCursor = -1; + sqlite3SelectPrep(pParse, &sSelect, 0); + if( pParse->nErr==0 ){ + assert( db->mallocFailed==0 ); + sqlite3GenerateColumnNames(pParse, &sSelect); + } + sqlite3ExprListDelete(db, sSelect.pEList); + pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab); + if( pParse->nErr==0 ){ + NameContext sNC; + memset(&sNC, 0, sizeof(sNC)); + if( pReturning->nRetCol==0 ){ + pReturning->nRetCol = pNew->nExpr; + pReturning->iRetCur = pParse->nTab++; + } + sNC.pParse = pParse; + sNC.uNC.iBaseReg = regIn; + sNC.ncFlags = NC_UBaseReg; + pParse->eTriggerOp = pTrigger->op; + pParse->pTriggerTab = pTab; + if( sqlite3ResolveExprListNames(&sNC, pNew)==SQLITE_OK + && ALWAYS(!db->mallocFailed) + ){ + int i; + int nCol = pNew->nExpr; + int reg = pParse->nMem+1; + sqlite3ProcessReturningSubqueries(pNew, pTab); + pParse->nMem += nCol+2; + pReturning->iRetReg = reg; + for(i=0; ia[i].pExpr; + assert( pCol!=0 ); /* Due to !db->mallocFailed ~9 lines above */ + sqlite3ExprCodeFactorable(pParse, pCol, reg+i); + if( sqlite3ExprAffinity(pCol)==SQLITE_AFF_REAL ){ + sqlite3VdbeAddOp1(v, OP_RealAffinity, reg+i); + } + } + sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, i, reg+i); + sqlite3VdbeAddOp2(v, OP_NewRowid, pReturning->iRetCur, reg+i+1); + sqlite3VdbeAddOp3(v, OP_Insert, pReturning->iRetCur, reg+i, reg+i+1); + } + } + sqlite3ExprListDelete(db, pNew); + pParse->eTriggerOp = 0; + pParse->pTriggerTab = 0; +} + + + +/* +** Generate VDBE code for the statements inside the body of a single +** trigger. +*/ +static int codeTriggerProgram( + Parse *pParse, /* The parser context */ + TriggerStep *pStepList, /* List of statements inside the trigger body */ + int orconf /* Conflict algorithm. (OE_Abort, etc) */ +){ + TriggerStep *pStep; + Vdbe *v = pParse->pVdbe; + sqlite3 *db = pParse->db; + + assert( pParse->pTriggerTab && pParse->pToplevel ); + assert( pStepList ); + assert( v!=0 ); + for(pStep=pStepList; pStep; pStep=pStep->pNext){ + /* Figure out the ON CONFLICT policy that will be used for this step + ** of the trigger program. If the statement that caused this trigger + ** to fire had an explicit ON CONFLICT, then use it. Otherwise, use + ** the ON CONFLICT policy that was specified as part of the trigger + ** step statement. Example: + ** + ** CREATE TRIGGER AFTER INSERT ON t1 BEGIN; + ** INSERT OR REPLACE INTO t2 VALUES(new.a, new.b); + ** END; + ** + ** INSERT INTO t1 ... ; -- insert into t2 uses REPLACE policy + ** INSERT OR IGNORE INTO t1 ... ; -- insert into t2 uses IGNORE policy + */ + pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf; + assert( pParse->okConstFactor==0 ); + +#ifndef SQLITE_OMIT_TRACE + if( pStep->zSpan ){ + sqlite3VdbeAddOp4(v, OP_Trace, 0x7fffffff, 1, 0, + sqlite3MPrintf(db, "-- %s", pStep->zSpan), + P4_DYNAMIC); + } +#endif + + switch( pStep->op ){ + case TK_UPDATE: { + sqlite3Update(pParse, + sqlite3SrcListDup(db, pStep->pSrc, 0), + sqlite3ExprListDup(db, pStep->pExprList, 0), + sqlite3ExprDup(db, pStep->pWhere, 0), + pParse->eOrconf, 0, 0, 0 + ); + sqlite3VdbeAddOp0(v, OP_ResetCount); + break; + } + case TK_INSERT: { + sqlite3Insert(pParse, + sqlite3SrcListDup(db, pStep->pSrc, 0), + sqlite3SelectDup(db, pStep->pSelect, 0), + sqlite3IdListDup(db, pStep->pIdList), + pParse->eOrconf, + sqlite3UpsertDup(db, pStep->pUpsert) + ); + sqlite3VdbeAddOp0(v, OP_ResetCount); + break; + } + case TK_DELETE: { + sqlite3DeleteFrom(pParse, + sqlite3SrcListDup(db, pStep->pSrc, 0), + sqlite3ExprDup(db, pStep->pWhere, 0), 0, 0 + ); + sqlite3VdbeAddOp0(v, OP_ResetCount); + break; + } + default: assert( pStep->op==TK_SELECT ); { + SelectDest sDest; + Select *pSelect = sqlite3SelectDup(db, pStep->pSelect, 0); + sqlite3SelectDestInit(&sDest, SRT_Discard, 0); + sqlite3Select(pParse, pSelect, &sDest); + sqlite3SelectDelete(db, pSelect); + break; + } + } + } + + return 0; +} + +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS +/* +** This function is used to add VdbeComment() annotations to a VDBE +** program. It is not used in production code, only for debugging. +*/ +static const char *onErrorText(int onError){ + switch( onError ){ + case OE_Abort: return "abort"; + case OE_Rollback: return "rollback"; + case OE_Fail: return "fail"; + case OE_Replace: return "replace"; + case OE_Ignore: return "ignore"; + case OE_Default: return "default"; + } + return "n/a"; +} +#endif + +/* +** Parse context structure pFrom has just been used to create a sub-vdbe +** (trigger program). If an error has occurred, transfer error information +** from pFrom to pTo. +*/ +static void transferParseError(Parse *pTo, Parse *pFrom){ + assert( pFrom->zErrMsg==0 || pFrom->nErr ); + assert( pTo->zErrMsg==0 || pTo->nErr ); + if( pTo->nErr==0 ){ + pTo->zErrMsg = pFrom->zErrMsg; + pTo->nErr = pFrom->nErr; + pTo->rc = pFrom->rc; + }else{ + sqlite3DbFree(pFrom->db, pFrom->zErrMsg); + } +} + +/* +** Create and populate a new TriggerPrg object with a sub-program +** implementing trigger pTrigger with ON CONFLICT policy orconf. +*/ +static TriggerPrg *codeRowTrigger( + Parse *pParse, /* Current parse context */ + Trigger *pTrigger, /* Trigger to code */ + Table *pTab, /* The table pTrigger is attached to */ + int orconf /* ON CONFLICT policy to code trigger program with */ +){ + Parse *pTop; /* Top level Parse object */ + sqlite3 *db = pParse->db; /* Database handle */ + TriggerPrg *pPrg; /* Value to return */ + Expr *pWhen = 0; /* Duplicate of trigger WHEN expression */ + Vdbe *v; /* Temporary VM */ + NameContext sNC; /* Name context for sub-vdbe */ + SubProgram *pProgram = 0; /* Sub-vdbe for trigger program */ + int iEndTrigger = 0; /* Label to jump to if WHEN is false */ + Parse sSubParse; /* Parse context for sub-vdbe */ + int nDepth; /* Trigger depth */ + + /* Ensure that triggers are not chained too deep. This test is linear + ** in the chaining depth, but sensible code ought not be chaining + ** triggers excessively, so that shouldn't be a problem. + */ + pTop = pParse; + for(nDepth=0; pTop->pOuterParse; pTop = pTop->pOuterParse, nDepth++){} + if( nDepth>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){ + sqlite3ErrorMsg(pParse, "triggers nested too deep"); + return 0; + } + + pTop = sqlite3ParseToplevel(pParse); + assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) ); + assert( pTop->pVdbe ); + + + /* Allocate the TriggerPrg and SubProgram objects. To ensure that they + ** are freed if an error occurs, link them into the Parse.pTriggerPrg + ** list of the top-level Parse object sooner rather than later. */ + pPrg = sqlite3DbMallocZero(db, sizeof(TriggerPrg)); + if( !pPrg ) return 0; + pPrg->pNext = pTop->pTriggerPrg; + pTop->pTriggerPrg = pPrg; + pPrg->pProgram = pProgram = sqlite3DbMallocZero(db, sizeof(SubProgram)); + if( !pProgram ) return 0; + sqlite3VdbeLinkSubProgram(pTop->pVdbe, pProgram); + pPrg->pTrigger = pTrigger; + pPrg->orconf = orconf; + pPrg->aColmask[0] = 0xffffffff; + pPrg->aColmask[1] = 0xffffffff; + + /* Allocate and populate a new Parse context to use for coding the + ** trigger sub-program. */ + sqlite3ParseObjectInit(&sSubParse, db); + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = &sSubParse; + sSubParse.pTriggerTab = pTab; + sSubParse.pToplevel = pTop; + sSubParse.zAuthContext = pTrigger->zName; + sSubParse.eTriggerOp = pTrigger->op; + sSubParse.nQueryLoop = pParse->nQueryLoop; + sSubParse.prepFlags = pParse->prepFlags; + sSubParse.oldmask = 0; + sSubParse.newmask = 0; + + v = sqlite3GetVdbe(&sSubParse); + if( v ){ + VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)", + pTrigger->zName, onErrorText(orconf), + (pTrigger->tr_tm==TRIGGER_BEFORE ? "BEFORE" : "AFTER"), + (pTrigger->op==TK_UPDATE ? "UPDATE" : ""), + (pTrigger->op==TK_INSERT ? "INSERT" : ""), + (pTrigger->op==TK_DELETE ? "DELETE" : ""), + pTab->zName + )); +#ifndef SQLITE_OMIT_TRACE + if( pTrigger->zName ){ + sqlite3VdbeChangeP4(v, -1, + sqlite3MPrintf(db, "-- TRIGGER %s", pTrigger->zName), P4_DYNAMIC + ); + } +#endif + + /* If one was specified, code the WHEN clause. If it evaluates to false + ** (or NULL) the sub-vdbe is immediately halted by jumping to the + ** OP_Halt inserted at the end of the program. */ + if( pTrigger->pWhen ){ + pWhen = sqlite3ExprDup(db, pTrigger->pWhen, 0); + if( db->mallocFailed==0 + && SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen) + ){ + iEndTrigger = sqlite3VdbeMakeLabel(&sSubParse); + sqlite3ExprIfFalse(&sSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL); + } + sqlite3ExprDelete(db, pWhen); + } + + /* Code the trigger program into the sub-vdbe. */ + codeTriggerProgram(&sSubParse, pTrigger->step_list, orconf); + + /* Insert an OP_Halt at the end of the sub-program. */ + if( iEndTrigger ){ + sqlite3VdbeResolveLabel(v, iEndTrigger); + } + sqlite3VdbeAddOp0(v, OP_Halt); + VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf))); + transferParseError(pParse, &sSubParse); + + if( pParse->nErr==0 ){ + assert( db->mallocFailed==0 ); + pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg); + } + pProgram->nMem = sSubParse.nMem; + pProgram->nCsr = sSubParse.nTab; + pProgram->token = (void *)pTrigger; + pPrg->aColmask[0] = sSubParse.oldmask; + pPrg->aColmask[1] = sSubParse.newmask; + sqlite3VdbeDelete(v); + }else{ + transferParseError(pParse, &sSubParse); + } + + assert( !sSubParse.pTriggerPrg && !sSubParse.nMaxArg ); + sqlite3ParseObjectReset(&sSubParse); + return pPrg; +} + +/* +** Return a pointer to a TriggerPrg object containing the sub-program for +** trigger pTrigger with default ON CONFLICT algorithm orconf. If no such +** TriggerPrg object exists, a new object is allocated and populated before +** being returned. +*/ +static TriggerPrg *getRowTrigger( + Parse *pParse, /* Current parse context */ + Trigger *pTrigger, /* Trigger to code */ + Table *pTab, /* The table trigger pTrigger is attached to */ + int orconf /* ON CONFLICT algorithm. */ +){ + Parse *pRoot = sqlite3ParseToplevel(pParse); + TriggerPrg *pPrg; + + assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) ); + + /* It may be that this trigger has already been coded (or is in the + ** process of being coded). If this is the case, then an entry with + ** a matching TriggerPrg.pTrigger field will be present somewhere + ** in the Parse.pTriggerPrg list. Search for such an entry. */ + for(pPrg=pRoot->pTriggerPrg; + pPrg && (pPrg->pTrigger!=pTrigger || pPrg->orconf!=orconf); + pPrg=pPrg->pNext + ); + + /* If an existing TriggerPrg could not be located, create a new one. */ + if( !pPrg ){ + pPrg = codeRowTrigger(pParse, pTrigger, pTab, orconf); + pParse->db->errByteOffset = -1; + } + + return pPrg; +} + +/* +** Generate code for the trigger program associated with trigger p on +** table pTab. The reg, orconf and ignoreJump parameters passed to this +** function are the same as those described in the header function for +** sqlite3CodeRowTrigger() +*/ +SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect( + Parse *pParse, /* Parse context */ + Trigger *p, /* Trigger to code */ + Table *pTab, /* The table to code triggers from */ + int reg, /* Reg array containing OLD.* and NEW.* values */ + int orconf, /* ON CONFLICT policy */ + int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */ +){ + Vdbe *v = sqlite3GetVdbe(pParse); /* Main VM */ + TriggerPrg *pPrg; + pPrg = getRowTrigger(pParse, p, pTab, orconf); + assert( pPrg || pParse->nErr ); + + /* Code the OP_Program opcode in the parent VDBE. P4 of the OP_Program + ** is a pointer to the sub-vdbe containing the trigger program. */ + if( pPrg ){ + int bRecursive = (p->zName && 0==(pParse->db->flags&SQLITE_RecTriggers)); + + sqlite3VdbeAddOp4(v, OP_Program, reg, ignoreJump, ++pParse->nMem, + (const char *)pPrg->pProgram, P4_SUBPROGRAM); + VdbeComment( + (v, "Call: %s.%s", (p->zName?p->zName:"fkey"), onErrorText(orconf))); + + /* Set the P5 operand of the OP_Program instruction to non-zero if + ** recursive invocation of this trigger program is disallowed. Recursive + ** invocation is disallowed if (a) the sub-program is really a trigger, + ** not a foreign key action, and (b) the flag to enable recursive triggers + ** is clear. */ + sqlite3VdbeChangeP5(v, (u16)bRecursive); + } +} + +/* +** This is called to code the required FOR EACH ROW triggers for an operation +** on table pTab. The operation to code triggers for (INSERT, UPDATE or DELETE) +** is given by the op parameter. The tr_tm parameter determines whether the +** BEFORE or AFTER triggers are coded. If the operation is an UPDATE, then +** parameter pChanges is passed the list of columns being modified. +** +** If there are no triggers that fire at the specified time for the specified +** operation on pTab, this function is a no-op. +** +** The reg argument is the address of the first in an array of registers +** that contain the values substituted for the new.* and old.* references +** in the trigger program. If N is the number of columns in table pTab +** (a copy of pTab->nCol), then registers are populated as follows: +** +** Register Contains +** ------------------------------------------------------ +** reg+0 OLD.rowid +** reg+1 OLD.* value of left-most column of pTab +** ... ... +** reg+N OLD.* value of right-most column of pTab +** reg+N+1 NEW.rowid +** reg+N+2 NEW.* value of left-most column of pTab +** ... ... +** reg+N+N+1 NEW.* value of right-most column of pTab +** +** For ON DELETE triggers, the registers containing the NEW.* values will +** never be accessed by the trigger program, so they are not allocated or +** populated by the caller (there is no data to populate them with anyway). +** Similarly, for ON INSERT triggers the values stored in the OLD.* registers +** are never accessed, and so are not allocated by the caller. So, for an +** ON INSERT trigger, the value passed to this function as parameter reg +** is not a readable register, although registers (reg+N) through +** (reg+N+N+1) are. +** +** Parameter orconf is the default conflict resolution algorithm for the +** trigger program to use (REPLACE, IGNORE etc.). Parameter ignoreJump +** is the instruction that control should jump to if a trigger program +** raises an IGNORE exception. +*/ +SQLITE_PRIVATE void sqlite3CodeRowTrigger( + Parse *pParse, /* Parse context */ + Trigger *pTrigger, /* List of triggers on table pTab */ + int op, /* One of TK_UPDATE, TK_INSERT, TK_DELETE */ + ExprList *pChanges, /* Changes list for any UPDATE OF triggers */ + int tr_tm, /* One of TRIGGER_BEFORE, TRIGGER_AFTER */ + Table *pTab, /* The table to code triggers from */ + int reg, /* The first in an array of registers (see above) */ + int orconf, /* ON CONFLICT policy */ + int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */ +){ + Trigger *p; /* Used to iterate through pTrigger list */ + + assert( op==TK_UPDATE || op==TK_INSERT || op==TK_DELETE ); + assert( tr_tm==TRIGGER_BEFORE || tr_tm==TRIGGER_AFTER ); + assert( (op==TK_UPDATE)==(pChanges!=0) ); + + for(p=pTrigger; p; p=p->pNext){ + + /* Sanity checking: The schema for the trigger and for the table are + ** always defined. The trigger must be in the same schema as the table + ** or else it must be a TEMP trigger. */ + assert( p->pSchema!=0 ); + assert( p->pTabSchema!=0 ); + assert( p->pSchema==p->pTabSchema + || p->pSchema==pParse->db->aDb[1].pSchema ); + + /* Determine whether we should code this trigger. One of two choices: + ** 1. The trigger is an exact match to the current DML statement + ** 2. This is a RETURNING trigger for INSERT but we are currently + ** doing the UPDATE part of an UPSERT. + */ + if( (p->op==op || (p->bReturning && p->op==TK_INSERT && op==TK_UPDATE)) + && p->tr_tm==tr_tm + && checkColumnOverlap(p->pColumns, pChanges) + ){ + if( !p->bReturning ){ + sqlite3CodeRowTriggerDirect(pParse, p, pTab, reg, orconf, ignoreJump); + }else if( sqlite3IsToplevel(pParse) ){ + codeReturningTrigger(pParse, p, pTab, reg); + } + } + } +} + +/* +** Triggers may access values stored in the old.* or new.* pseudo-table. +** This function returns a 32-bit bitmask indicating which columns of the +** old.* or new.* tables actually are used by triggers. This information +** may be used by the caller, for example, to avoid having to load the entire +** old.* record into memory when executing an UPDATE or DELETE command. +** +** Bit 0 of the returned mask is set if the left-most column of the +** table may be accessed using an [old|new].reference. Bit 1 is set if +** the second leftmost column value is required, and so on. If there +** are more than 32 columns in the table, and at least one of the columns +** with an index greater than 32 may be accessed, 0xffffffff is returned. +** +** It is not possible to determine if the old.rowid or new.rowid column is +** accessed by triggers. The caller must always assume that it is. +** +** Parameter isNew must be either 1 or 0. If it is 0, then the mask returned +** applies to the old.* table. If 1, the new.* table. +** +** Parameter tr_tm must be a mask with one or both of the TRIGGER_BEFORE +** and TRIGGER_AFTER bits set. Values accessed by BEFORE triggers are only +** included in the returned mask if the TRIGGER_BEFORE bit is set in the +** tr_tm parameter. Similarly, values accessed by AFTER triggers are only +** included in the returned mask if the TRIGGER_AFTER bit is set in tr_tm. +*/ +SQLITE_PRIVATE u32 sqlite3TriggerColmask( + Parse *pParse, /* Parse context */ + Trigger *pTrigger, /* List of triggers on table pTab */ + ExprList *pChanges, /* Changes list for any UPDATE OF triggers */ + int isNew, /* 1 for new.* ref mask, 0 for old.* ref mask */ + int tr_tm, /* Mask of TRIGGER_BEFORE|TRIGGER_AFTER */ + Table *pTab, /* The table to code triggers from */ + int orconf /* Default ON CONFLICT policy for trigger steps */ +){ + const int op = pChanges ? TK_UPDATE : TK_DELETE; + u32 mask = 0; + Trigger *p; + + assert( isNew==1 || isNew==0 ); + if( IsView(pTab) ){ + return 0xffffffff; + } + for(p=pTrigger; p; p=p->pNext){ + if( p->op==op + && (tr_tm&p->tr_tm) + && checkColumnOverlap(p->pColumns,pChanges) + ){ + if( p->bReturning ){ + mask = 0xffffffff; + }else{ + TriggerPrg *pPrg; + pPrg = getRowTrigger(pParse, p, pTab, orconf); + if( pPrg ){ + mask |= pPrg->aColmask[isNew]; + } + } + } + } + + return mask; +} + +#endif /* !defined(SQLITE_OMIT_TRIGGER) */ + +/************** End of trigger.c *********************************************/ +/************** Begin file update.c ******************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains C code routines that are called by the parser +** to handle UPDATE statements. +*/ +/* #include "sqliteInt.h" */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Forward declaration */ +static void updateVirtualTable( + Parse *pParse, /* The parsing context */ + SrcList *pSrc, /* The virtual table to be modified */ + Table *pTab, /* The virtual table */ + ExprList *pChanges, /* The columns to change in the UPDATE statement */ + Expr *pRowidExpr, /* Expression used to recompute the rowid */ + int *aXRef, /* Mapping from columns of pTab to entries in pChanges */ + Expr *pWhere, /* WHERE clause of the UPDATE statement */ + int onError /* ON CONFLICT strategy */ +); +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +/* +** The most recently coded instruction was an OP_Column to retrieve the +** i-th column of table pTab. This routine sets the P4 parameter of the +** OP_Column to the default value, if any. +** +** The default value of a column is specified by a DEFAULT clause in the +** column definition. This was either supplied by the user when the table +** was created, or added later to the table definition by an ALTER TABLE +** command. If the latter, then the row-records in the table btree on disk +** may not contain a value for the column and the default value, taken +** from the P4 parameter of the OP_Column instruction, is returned instead. +** If the former, then all row-records are guaranteed to include a value +** for the column and the P4 value is not required. +** +** Column definitions created by an ALTER TABLE command may only have +** literal default values specified: a number, null or a string. (If a more +** complicated default expression value was provided, it is evaluated +** when the ALTER TABLE is executed and one of the literal values written +** into the sqlite_schema table.) +** +** Therefore, the P4 parameter is only required if the default value for +** the column is a literal number, string or null. The sqlite3ValueFromExpr() +** function is capable of transforming these types of expressions into +** sqlite3_value objects. +** +** If column as REAL affinity and the table is an ordinary b-tree table +** (not a virtual table) then the value might have been stored as an +** integer. In that case, add an OP_RealAffinity opcode to make sure +** it has been converted into REAL. +*/ +SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ + Column *pCol; + assert( pTab!=0 ); + assert( pTab->nCol>i ); + pCol = &pTab->aCol[i]; + if( pCol->iDflt ){ + sqlite3_value *pValue = 0; + u8 enc = ENC(sqlite3VdbeDb(v)); + assert( !IsView(pTab) ); + VdbeComment((v, "%s.%s", pTab->zName, pCol->zCnName)); + assert( inCol ); + sqlite3ValueFromExpr(sqlite3VdbeDb(v), + sqlite3ColumnExpr(pTab,pCol), enc, + pCol->affinity, &pValue); + if( pValue ){ + sqlite3VdbeAppendP4(v, pValue, P4_MEM); + } + } +#ifndef SQLITE_OMIT_FLOATING_POINT + if( pCol->affinity==SQLITE_AFF_REAL && !IsVirtual(pTab) ){ + sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg); + } +#endif +} + +/* +** Check to see if column iCol of index pIdx references any of the +** columns defined by aXRef and chngRowid. Return true if it does +** and false if not. This is an optimization. False-positives are a +** performance degradation, but false-negatives can result in a corrupt +** index and incorrect answers. +** +** aXRef[j] will be non-negative if column j of the original table is +** being updated. chngRowid will be true if the rowid of the table is +** being updated. +*/ +static int indexColumnIsBeingUpdated( + Index *pIdx, /* The index to check */ + int iCol, /* Which column of the index to check */ + int *aXRef, /* aXRef[j]>=0 if column j is being updated */ + int chngRowid /* true if the rowid is being updated */ +){ + i16 iIdxCol = pIdx->aiColumn[iCol]; + assert( iIdxCol!=XN_ROWID ); /* Cannot index rowid */ + if( iIdxCol>=0 ){ + return aXRef[iIdxCol]>=0; + } + assert( iIdxCol==XN_EXPR ); + assert( pIdx->aColExpr!=0 ); + assert( pIdx->aColExpr->a[iCol].pExpr!=0 ); + return sqlite3ExprReferencesUpdatedColumn(pIdx->aColExpr->a[iCol].pExpr, + aXRef,chngRowid); +} + +/* +** Check to see if index pIdx is a partial index whose conditional +** expression might change values due to an UPDATE. Return true if +** the index is subject to change and false if the index is guaranteed +** to be unchanged. This is an optimization. False-positives are a +** performance degradation, but false-negatives can result in a corrupt +** index and incorrect answers. +** +** aXRef[j] will be non-negative if column j of the original table is +** being updated. chngRowid will be true if the rowid of the table is +** being updated. +*/ +static int indexWhereClauseMightChange( + Index *pIdx, /* The index to check */ + int *aXRef, /* aXRef[j]>=0 if column j is being updated */ + int chngRowid /* true if the rowid is being updated */ +){ + if( pIdx->pPartIdxWhere==0 ) return 0; + return sqlite3ExprReferencesUpdatedColumn(pIdx->pPartIdxWhere, + aXRef, chngRowid); +} + +/* +** Allocate and return a pointer to an expression of type TK_ROW with +** Expr.iColumn set to value (iCol+1). The resolver will modify the +** expression to be a TK_COLUMN reading column iCol of the first +** table in the source-list (pSrc->a[0]). +*/ +static Expr *exprRowColumn(Parse *pParse, int iCol){ + Expr *pRet = sqlite3PExpr(pParse, TK_ROW, 0, 0); + if( pRet ) pRet->iColumn = iCol+1; + return pRet; +} + +/* +** Assuming both the pLimit and pOrderBy parameters are NULL, this function +** generates VM code to run the query: +** +** SELECT , pChanges FROM pTabList WHERE pWhere +** +** and write the results to the ephemeral table already opened as cursor +** iEph. None of pChanges, pTabList or pWhere are modified or consumed by +** this function, they must be deleted by the caller. +** +** Or, if pLimit and pOrderBy are not NULL, and pTab is not a view: +** +** SELECT , pChanges FROM pTabList +** WHERE pWhere +** GROUP BY +** ORDER BY pOrderBy LIMIT pLimit +** +** If pTab is a view, the GROUP BY clause is omitted. +** +** Exactly how results are written to table iEph, and exactly what +** the in the query above are is determined by the type +** of table pTabList->a[0].pTab. +** +** If the table is a WITHOUT ROWID table, then argument pPk must be its +** PRIMARY KEY. In this case are the primary key columns +** of the table, in order. The results of the query are written to ephemeral +** table iEph as index keys, using OP_IdxInsert. +** +** If the table is actually a view, then are all columns of +** the view. The results are written to the ephemeral table iEph as records +** with automatically assigned integer keys. +** +** If the table is a virtual or ordinary intkey table, then +** is its rowid. For a virtual table, the results are written to iEph as +** records with automatically assigned integer keys For intkey tables, the +** rowid value in is used as the integer key, and the +** remaining fields make up the table record. +*/ +static void updateFromSelect( + Parse *pParse, /* Parse context */ + int iEph, /* Cursor for open eph. table */ + Index *pPk, /* PK if table 0 is WITHOUT ROWID */ + ExprList *pChanges, /* List of expressions to return */ + SrcList *pTabList, /* List of tables to select from */ + Expr *pWhere, /* WHERE clause for query */ + ExprList *pOrderBy, /* ORDER BY clause */ + Expr *pLimit /* LIMIT clause */ +){ + int i; + SelectDest dest; + Select *pSelect = 0; + ExprList *pList = 0; + ExprList *pGrp = 0; + Expr *pLimit2 = 0; + ExprList *pOrderBy2 = 0; + sqlite3 *db = pParse->db; + Table *pTab = pTabList->a[0].pSTab; + SrcList *pSrc; + Expr *pWhere2; + int eDest; + +#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT + if( pOrderBy && pLimit==0 ) { + sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on UPDATE"); + return; + } + pOrderBy2 = sqlite3ExprListDup(db, pOrderBy, 0); + pLimit2 = sqlite3ExprDup(db, pLimit, 0); +#else + UNUSED_PARAMETER(pOrderBy); + UNUSED_PARAMETER(pLimit); +#endif + + pSrc = sqlite3SrcListDup(db, pTabList, 0); + pWhere2 = sqlite3ExprDup(db, pWhere, 0); + + assert( pTabList->nSrc>1 ); + if( pSrc ){ + assert( pSrc->a[0].fg.notCte ); + pSrc->a[0].iCursor = -1; + pSrc->a[0].pSTab->nTabRef--; + pSrc->a[0].pSTab = 0; + } + if( pPk ){ + for(i=0; inKeyCol; i++){ + Expr *pNew = exprRowColumn(pParse, pPk->aiColumn[i]); +#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT + if( pLimit ){ + pGrp = sqlite3ExprListAppend(pParse, pGrp, sqlite3ExprDup(db, pNew, 0)); + } +#endif + pList = sqlite3ExprListAppend(pParse, pList, pNew); + } + eDest = IsVirtual(pTab) ? SRT_Table : SRT_Upfrom; + }else if( IsView(pTab) ){ + for(i=0; inCol; i++){ + pList = sqlite3ExprListAppend(pParse, pList, exprRowColumn(pParse, i)); + } + eDest = SRT_Table; + }else{ + eDest = IsVirtual(pTab) ? SRT_Table : SRT_Upfrom; + pList = sqlite3ExprListAppend(pParse, 0, sqlite3PExpr(pParse,TK_ROW,0,0)); +#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT + if( pLimit ){ + pGrp = sqlite3ExprListAppend(pParse, 0, sqlite3PExpr(pParse,TK_ROW,0,0)); + } +#endif + } + assert( pChanges!=0 || pParse->db->mallocFailed ); + if( pChanges ){ + for(i=0; inExpr; i++){ + pList = sqlite3ExprListAppend(pParse, pList, + sqlite3ExprDup(db, pChanges->a[i].pExpr, 0) + ); + } + } + pSelect = sqlite3SelectNew(pParse, pList, + pSrc, pWhere2, pGrp, 0, pOrderBy2, + SF_UFSrcCheck|SF_IncludeHidden|SF_UpdateFrom, pLimit2 + ); + if( pSelect ) pSelect->selFlags |= SF_OrderByReqd; + sqlite3SelectDestInit(&dest, eDest, iEph); + dest.iSDParm2 = (pPk ? pPk->nKeyCol : -1); + sqlite3Select(pParse, pSelect, &dest); + sqlite3SelectDelete(db, pSelect); +} + +/* +** Process an UPDATE statement. +** +** UPDATE OR IGNORE tbl SET a=b, c=d FROM tbl2... WHERE e<5 AND f NOT NULL; +** \_______/ \_/ \______/ \_____/ \________________/ +** onError | pChanges | pWhere +** \_______________________/ +** pTabList +*/ +SQLITE_PRIVATE void sqlite3Update( + Parse *pParse, /* The parser context */ + SrcList *pTabList, /* The table in which we should change things */ + ExprList *pChanges, /* Things to be changed */ + Expr *pWhere, /* The WHERE clause. May be null */ + int onError, /* How to handle constraint errors */ + ExprList *pOrderBy, /* ORDER BY clause. May be null */ + Expr *pLimit, /* LIMIT clause. May be null */ + Upsert *pUpsert /* ON CONFLICT clause, or null */ +){ + int i, j, k; /* Loop counters */ + Table *pTab; /* The table to be updated */ + int addrTop = 0; /* VDBE instruction address of the start of the loop */ + WhereInfo *pWInfo = 0; /* Information about the WHERE clause */ + Vdbe *v; /* The virtual database engine */ + Index *pIdx; /* For looping over indices */ + Index *pPk; /* The PRIMARY KEY index for WITHOUT ROWID tables */ + int nIdx; /* Number of indices that need updating */ + int nAllIdx; /* Total number of indexes */ + int iBaseCur; /* Base cursor number */ + int iDataCur; /* Cursor for the canonical data btree */ + int iIdxCur; /* Cursor for the first index */ + sqlite3 *db; /* The database structure */ + int *aRegIdx = 0; /* Registers for to each index and the main table */ + int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the + ** an expression for the i-th column of the table. + ** aXRef[i]==-1 if the i-th column is not changed. */ + u8 *aToOpen; /* 1 for tables and indices to be opened */ + u8 chngPk; /* PRIMARY KEY changed in a WITHOUT ROWID table */ + u8 chngRowid; /* Rowid changed in a normal table */ + u8 chngKey; /* Either chngPk or chngRowid */ + Expr *pRowidExpr = 0; /* Expression defining the new record number */ + int iRowidExpr = -1; /* Index of "rowid=" (or IPK) assignment in pChanges */ + AuthContext sContext; /* The authorization context */ + NameContext sNC; /* The name-context to resolve expressions in */ + int iDb; /* Database containing the table being updated */ + int eOnePass; /* ONEPASS_XXX value from where.c */ + int hasFK; /* True if foreign key processing is required */ + int labelBreak; /* Jump here to break out of UPDATE loop */ + int labelContinue; /* Jump here to continue next step of UPDATE loop */ + int flags; /* Flags for sqlite3WhereBegin() */ + +#ifndef SQLITE_OMIT_TRIGGER + int isView; /* True when updating a view (INSTEAD OF trigger) */ + Trigger *pTrigger; /* List of triggers on pTab, if required */ + int tmask; /* Mask of TRIGGER_BEFORE|TRIGGER_AFTER */ +#endif + int newmask; /* Mask of NEW.* columns accessed by BEFORE triggers */ + int iEph = 0; /* Ephemeral table holding all primary key values */ + int nKey = 0; /* Number of elements in regKey for WITHOUT ROWID */ + int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */ + int addrOpen = 0; /* Address of OP_OpenEphemeral */ + int iPk = 0; /* First of nPk cells holding PRIMARY KEY value */ + i16 nPk = 0; /* Number of components of the PRIMARY KEY */ + int bReplace = 0; /* True if REPLACE conflict resolution might happen */ + int bFinishSeek = 1; /* The OP_FinishSeek opcode is needed */ + int nChangeFrom = 0; /* If there is a FROM, pChanges->nExpr, else 0 */ + + /* Register Allocations */ + int regRowCount = 0; /* A count of rows changed */ + int regOldRowid = 0; /* The old rowid */ + int regNewRowid = 0; /* The new rowid */ + int regNew = 0; /* Content of the NEW.* table in triggers */ + int regOld = 0; /* Content of OLD.* table in triggers */ + int regRowSet = 0; /* Rowset of rows to be updated */ + int regKey = 0; /* composite PRIMARY KEY value */ + + memset(&sContext, 0, sizeof(sContext)); + db = pParse->db; + assert( db->pParse==pParse ); + if( pParse->nErr ){ + goto update_cleanup; + } + assert( db->mallocFailed==0 ); + + /* Locate the table which we want to update. + */ + pTab = sqlite3SrcListLookup(pParse, pTabList); + if( pTab==0 ) goto update_cleanup; + iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + + /* Figure out if we have any triggers and if the table being + ** updated is a view. + */ +#ifndef SQLITE_OMIT_TRIGGER + pTrigger = sqlite3TriggersExist(pParse, pTab, TK_UPDATE, pChanges, &tmask); + isView = IsView(pTab); + assert( pTrigger || tmask==0 ); +#else +# define pTrigger 0 +# define isView 0 +# define tmask 0 +#endif +#ifdef SQLITE_OMIT_VIEW +# undef isView +# define isView 0 +#endif + +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x10000 ){ + sqlite3TreeViewLine(0, "In sqlite3Update() at %s:%d", __FILE__, __LINE__); + sqlite3TreeViewUpdate(pParse->pWith, pTabList, pChanges, pWhere, + onError, pOrderBy, pLimit, pUpsert, pTrigger); + } +#endif + + /* If there was a FROM clause, set nChangeFrom to the number of expressions + ** in the change-list. Otherwise, set it to 0. There cannot be a FROM + ** clause if this function is being called to generate code for part of + ** an UPSERT statement. */ + nChangeFrom = (pTabList->nSrc>1) ? pChanges->nExpr : 0; + assert( nChangeFrom==0 || pUpsert==0 ); + +#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT + if( !isView && nChangeFrom==0 ){ + pWhere = sqlite3LimitWhere( + pParse, pTabList, pWhere, pOrderBy, pLimit, "UPDATE" + ); + pOrderBy = 0; + pLimit = 0; + } +#endif + + if( sqlite3ViewGetColumnNames(pParse, pTab) ){ + goto update_cleanup; + } + if( sqlite3IsReadOnly(pParse, pTab, pTrigger) ){ + goto update_cleanup; + } + + /* Allocate a cursors for the main database table and for all indices. + ** The index cursors might not be used, but if they are used they + ** need to occur right after the database cursor. So go ahead and + ** allocate enough space, just in case. + */ + iBaseCur = iDataCur = pParse->nTab++; + iIdxCur = iDataCur+1; + pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); + testcase( pPk!=0 && pPk!=pTab->pIndex ); + for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ + if( pPk==pIdx ){ + iDataCur = pParse->nTab; + } + pParse->nTab++; + } + if( pUpsert ){ + /* On an UPSERT, reuse the same cursors already opened by INSERT */ + iDataCur = pUpsert->iDataCur; + iIdxCur = pUpsert->iIdxCur; + pParse->nTab = iBaseCur; + } + pTabList->a[0].iCursor = iDataCur; + + /* Allocate space for aXRef[], aRegIdx[], and aToOpen[]. + ** Initialize aXRef[] and aToOpen[] to their default values. + */ + aXRef = sqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx+1) + nIdx+2 ); + if( aXRef==0 ) goto update_cleanup; + aRegIdx = aXRef+pTab->nCol; + aToOpen = (u8*)(aRegIdx+nIdx+1); + memset(aToOpen, 1, nIdx+1); + aToOpen[nIdx+1] = 0; + for(i=0; inCol; i++) aXRef[i] = -1; + + /* Initialize the name-context */ + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + sNC.pSrcList = pTabList; + sNC.uNC.pUpsert = pUpsert; + sNC.ncFlags = NC_UUpsert; + + /* Begin generating code. */ + v = sqlite3GetVdbe(pParse); + if( v==0 ) goto update_cleanup; + + /* Resolve the column names in all the expressions of the + ** of the UPDATE statement. Also find the column index + ** for each column to be updated in the pChanges array. For each + ** column to be updated, make sure we have authorization to change + ** that column. + */ + chngRowid = chngPk = 0; + for(i=0; inExpr; i++){ + /* If this is an UPDATE with a FROM clause, do not resolve expressions + ** here. The call to sqlite3Select() below will do that. */ + if( nChangeFrom==0 && sqlite3ResolveExprNames(&sNC, pChanges->a[i].pExpr) ){ + goto update_cleanup; + } + j = sqlite3ColumnIndex(pTab, pChanges->a[i].zEName); + if( j>=0 ){ + if( j==pTab->iPKey ){ + chngRowid = 1; + pRowidExpr = pChanges->a[i].pExpr; + iRowidExpr = i; + }else if( pPk && (pTab->aCol[j].colFlags & COLFLAG_PRIMKEY)!=0 ){ + chngPk = 1; + } +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + else if( pTab->aCol[j].colFlags & COLFLAG_GENERATED ){ + testcase( pTab->aCol[j].colFlags & COLFLAG_VIRTUAL ); + testcase( pTab->aCol[j].colFlags & COLFLAG_STORED ); + sqlite3ErrorMsg(pParse, + "cannot UPDATE generated column \"%s\"", + pTab->aCol[j].zCnName); + goto update_cleanup; + } +#endif + aXRef[j] = i; + }else{ + if( pPk==0 && sqlite3IsRowid(pChanges->a[i].zEName) ){ + j = -1; + chngRowid = 1; + pRowidExpr = pChanges->a[i].pExpr; + iRowidExpr = i; + }else{ + sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zEName); + pParse->checkSchema = 1; + goto update_cleanup; + } + } +#ifndef SQLITE_OMIT_AUTHORIZATION + { + int rc; + rc = sqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName, + j<0 ? "ROWID" : pTab->aCol[j].zCnName, + db->aDb[iDb].zDbSName); + if( rc==SQLITE_DENY ){ + goto update_cleanup; + }else if( rc==SQLITE_IGNORE ){ + aXRef[j] = -1; + } + } +#endif + } + assert( (chngRowid & chngPk)==0 ); + assert( chngRowid==0 || chngRowid==1 ); + assert( chngPk==0 || chngPk==1 ); + chngKey = chngRowid + chngPk; + +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + /* Mark generated columns as changing if their generator expressions + ** reference any changing column. The actual aXRef[] value for + ** generated expressions is not used, other than to check to see that it + ** is non-negative, so the value of aXRef[] for generated columns can be + ** set to any non-negative number. We use 99999 so that the value is + ** obvious when looking at aXRef[] in a symbolic debugger. + */ + if( pTab->tabFlags & TF_HasGenerated ){ + int bProgress; + testcase( pTab->tabFlags & TF_HasVirtual ); + testcase( pTab->tabFlags & TF_HasStored ); + do{ + bProgress = 0; + for(i=0; inCol; i++){ + if( aXRef[i]>=0 ) continue; + if( (pTab->aCol[i].colFlags & COLFLAG_GENERATED)==0 ) continue; + if( sqlite3ExprReferencesUpdatedColumn( + sqlite3ColumnExpr(pTab, &pTab->aCol[i]), + aXRef, chngRowid) + ){ + aXRef[i] = 99999; + bProgress = 1; + } + } + }while( bProgress ); + } +#endif + + /* The SET expressions are not actually used inside the WHERE loop. + ** So reset the colUsed mask. Unless this is a virtual table. In that + ** case, set all bits of the colUsed mask (to ensure that the virtual + ** table implementation makes all columns available). + */ + pTabList->a[0].colUsed = IsVirtual(pTab) ? ALLBITS : 0; + + hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngKey); + + /* There is one entry in the aRegIdx[] array for each index on the table + ** being updated. Fill in aRegIdx[] with a register number that will hold + ** the key for accessing each index. + */ + if( onError==OE_Replace ) bReplace = 1; + for(nAllIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nAllIdx++){ + int reg; + if( chngKey || hasFK>1 || pIdx==pPk + || indexWhereClauseMightChange(pIdx,aXRef,chngRowid) + ){ + reg = ++pParse->nMem; + pParse->nMem += pIdx->nColumn; + }else{ + reg = 0; + for(i=0; inKeyCol; i++){ + if( indexColumnIsBeingUpdated(pIdx, i, aXRef, chngRowid) ){ + reg = ++pParse->nMem; + pParse->nMem += pIdx->nColumn; + if( onError==OE_Default && pIdx->onError==OE_Replace ){ + bReplace = 1; + } + break; + } + } + } + if( reg==0 ) aToOpen[nAllIdx+1] = 0; + aRegIdx[nAllIdx] = reg; + } + aRegIdx[nAllIdx] = ++pParse->nMem; /* Register storing the table record */ + if( bReplace ){ + /* If REPLACE conflict resolution might be invoked, open cursors on all + ** indexes in case they are needed to delete records. */ + memset(aToOpen, 1, nIdx+1); + } + + if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); + sqlite3BeginWriteOperation(pParse, pTrigger || hasFK, iDb); + + /* Allocate required registers. */ + if( !IsVirtual(pTab) ){ + /* For now, regRowSet and aRegIdx[nAllIdx] share the same register. + ** If regRowSet turns out to be needed, then aRegIdx[nAllIdx] will be + ** reallocated. aRegIdx[nAllIdx] is the register in which the main + ** table record is written. regRowSet holds the RowSet for the + ** two-pass update algorithm. */ + assert( aRegIdx[nAllIdx]==pParse->nMem ); + regRowSet = aRegIdx[nAllIdx]; + regOldRowid = regNewRowid = ++pParse->nMem; + if( chngPk || pTrigger || hasFK ){ + regOld = pParse->nMem + 1; + pParse->nMem += pTab->nCol; + } + if( chngKey || pTrigger || hasFK ){ + regNewRowid = ++pParse->nMem; + } + regNew = pParse->nMem + 1; + pParse->nMem += pTab->nCol; + } + + /* Start the view context. */ + if( isView ){ + sqlite3AuthContextPush(pParse, &sContext, pTab->zName); + } + + /* If we are trying to update a view, realize that view into + ** an ephemeral table. + */ +#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) + if( nChangeFrom==0 && isView ){ + sqlite3MaterializeView(pParse, pTab, + pWhere, pOrderBy, pLimit, iDataCur + ); + pOrderBy = 0; + pLimit = 0; + } +#endif + + /* Resolve the column names in all the expressions in the + ** WHERE clause. + */ + if( nChangeFrom==0 && sqlite3ResolveExprNames(&sNC, pWhere) ){ + goto update_cleanup; + } + +#ifndef SQLITE_OMIT_VIRTUALTABLE + /* Virtual tables must be handled separately */ + if( IsVirtual(pTab) ){ + updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef, + pWhere, onError); + goto update_cleanup; + } +#endif + + /* Jump to labelBreak to abandon further processing of this UPDATE */ + labelContinue = labelBreak = sqlite3VdbeMakeLabel(pParse); + + /* Not an UPSERT. Normal processing. Begin by + ** initialize the count of updated rows */ + if( (db->flags&SQLITE_CountRows)!=0 + && !pParse->pTriggerTab + && !pParse->nested + && !pParse->bReturning + && pUpsert==0 + ){ + regRowCount = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount); + } + + if( nChangeFrom==0 && HasRowid(pTab) ){ + sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid); + iEph = pParse->nTab++; + addrOpen = sqlite3VdbeAddOp3(v, OP_OpenEphemeral, iEph, 0, regRowSet); + }else{ + assert( pPk!=0 || HasRowid(pTab) ); + nPk = pPk ? pPk->nKeyCol : 0; + iPk = pParse->nMem+1; + pParse->nMem += nPk; + pParse->nMem += nChangeFrom; + regKey = ++pParse->nMem; + if( pUpsert==0 ){ + int nEphCol = nPk + nChangeFrom + (isView ? pTab->nCol : 0); + iEph = pParse->nTab++; + if( pPk ) sqlite3VdbeAddOp3(v, OP_Null, 0, iPk, iPk+nPk-1); + addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nEphCol); + if( pPk ){ + KeyInfo *pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pPk); + if( pKeyInfo ){ + pKeyInfo->nAllField = nEphCol; + sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO); + } + } + if( nChangeFrom ){ + updateFromSelect( + pParse, iEph, pPk, pChanges, pTabList, pWhere, pOrderBy, pLimit + ); +#ifndef SQLITE_OMIT_SUBQUERY + if( isView ) iDataCur = iEph; +#endif + } + } + } + + if( nChangeFrom ){ + sqlite3MultiWrite(pParse); + eOnePass = ONEPASS_OFF; + nKey = nPk; + regKey = iPk; + }else{ + if( pUpsert ){ + /* If this is an UPSERT, then all cursors have already been opened by + ** the outer INSERT and the data cursor should be pointing at the row + ** that is to be updated. So bypass the code that searches for the + ** row(s) to be updated. + */ + pWInfo = 0; + eOnePass = ONEPASS_SINGLE; + sqlite3ExprIfFalse(pParse, pWhere, labelBreak, SQLITE_JUMPIFNULL); + bFinishSeek = 0; + }else{ + /* Begin the database scan. + ** + ** Do not consider a single-pass strategy for a multi-row update if + ** there is anything that might disrupt the cursor being used to do + ** the UPDATE: + ** (1) This is a nested UPDATE + ** (2) There are triggers + ** (3) There are FOREIGN KEY constraints + ** (4) There are REPLACE conflict handlers + ** (5) There are subqueries in the WHERE clause + */ + flags = WHERE_ONEPASS_DESIRED; + if( !pParse->nested + && !pTrigger + && !hasFK + && !chngKey + && !bReplace + && (pWhere==0 || !ExprHasProperty(pWhere, EP_Subquery)) + ){ + flags |= WHERE_ONEPASS_MULTIROW; + } + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,0,0,0,flags,iIdxCur); + if( pWInfo==0 ) goto update_cleanup; + + /* A one-pass strategy that might update more than one row may not + ** be used if any column of the index used for the scan is being + ** updated. Otherwise, if there is an index on "b", statements like + ** the following could create an infinite loop: + ** + ** UPDATE t1 SET b=b+1 WHERE b>? + ** + ** Fall back to ONEPASS_OFF if where.c has selected a ONEPASS_MULTI + ** strategy that uses an index for which one or more columns are being + ** updated. */ + eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); + bFinishSeek = sqlite3WhereUsesDeferredSeek(pWInfo); + if( eOnePass!=ONEPASS_SINGLE ){ + sqlite3MultiWrite(pParse); + if( eOnePass==ONEPASS_MULTI ){ + int iCur = aiCurOnePass[1]; + if( iCur>=0 && iCur!=iDataCur && aToOpen[iCur-iBaseCur] ){ + eOnePass = ONEPASS_OFF; + } + assert( iCur!=iDataCur || !HasRowid(pTab) ); + } + } + } + + if( HasRowid(pTab) ){ + /* Read the rowid of the current row of the WHERE scan. In ONEPASS_OFF + ** mode, write the rowid into the FIFO. In either of the one-pass modes, + ** leave it in register regOldRowid. */ + sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid); + if( eOnePass==ONEPASS_OFF ){ + aRegIdx[nAllIdx] = ++pParse->nMem; + sqlite3VdbeAddOp3(v, OP_Insert, iEph, regRowSet, regOldRowid); + }else{ + if( ALWAYS(addrOpen) ) sqlite3VdbeChangeToNoop(v, addrOpen); + } + }else{ + /* Read the PK of the current row into an array of registers. In + ** ONEPASS_OFF mode, serialize the array into a record and store it in + ** the ephemeral table. Or, in ONEPASS_SINGLE or MULTI mode, change + ** the OP_OpenEphemeral instruction to a Noop (the ephemeral table + ** is not required) and leave the PK fields in the array of registers. */ + for(i=0; iaiColumn[i]>=0 ); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, + pPk->aiColumn[i], iPk+i); + } + if( eOnePass ){ + if( addrOpen ) sqlite3VdbeChangeToNoop(v, addrOpen); + nKey = nPk; + regKey = iPk; + }else{ + sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, regKey, + sqlite3IndexAffinityStr(db, pPk), nPk); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iEph, regKey, iPk, nPk); + } + } + } + + if( pUpsert==0 ){ + if( nChangeFrom==0 && eOnePass!=ONEPASS_MULTI ){ + sqlite3WhereEnd(pWInfo); + } + + if( !isView ){ + int addrOnce = 0; + int iNotUsed1 = 0; + int iNotUsed2 = 0; + + /* Open every index that needs updating. */ + if( eOnePass!=ONEPASS_OFF ){ + if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0; + if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0; + } + + if( eOnePass==ONEPASS_MULTI && (nIdx-(aiCurOnePass[1]>=0))>0 ){ + addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + } + sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur, + aToOpen, &iNotUsed1, &iNotUsed2); + if( addrOnce ){ + sqlite3VdbeJumpHereOrPopInst(v, addrOnce); + } + } + + /* Top of the update loop */ + if( eOnePass!=ONEPASS_OFF ){ + if( aiCurOnePass[0]!=iDataCur + && aiCurOnePass[1]!=iDataCur +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + && !isView +#endif + ){ + assert( pPk ); + sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey,nKey); + VdbeCoverage(v); + } + if( eOnePass!=ONEPASS_SINGLE ){ + labelContinue = sqlite3VdbeMakeLabel(pParse); + } + sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak); + VdbeCoverageIf(v, pPk==0); + VdbeCoverageIf(v, pPk!=0); + }else if( pPk || nChangeFrom ){ + labelContinue = sqlite3VdbeMakeLabel(pParse); + sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v); + addrTop = sqlite3VdbeCurrentAddr(v); + if( nChangeFrom ){ + if( !isView ){ + if( pPk ){ + for(i=0; i=0 ); + if( nChangeFrom==0 ){ + sqlite3ExprCode(pParse, pRowidExpr, regNewRowid); + }else{ + sqlite3VdbeAddOp3(v, OP_Column, iEph, iRowidExpr, regNewRowid); + } + sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid); VdbeCoverage(v); + } + + /* Compute the old pre-UPDATE content of the row being changed, if that + ** information is needed */ + if( chngPk || hasFK || pTrigger ){ + u32 oldmask = (hasFK ? sqlite3FkOldmask(pParse, pTab) : 0); + oldmask |= sqlite3TriggerColmask(pParse, + pTrigger, pChanges, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onError + ); + for(i=0; inCol; i++){ + u32 colFlags = pTab->aCol[i].colFlags; + k = sqlite3TableColumnToStorage(pTab, i) + regOld; + if( oldmask==0xffffffff + || (i<32 && (oldmask & MASKBIT32(i))!=0) + || (colFlags & COLFLAG_PRIMKEY)!=0 + ){ + testcase( oldmask!=0xffffffff && i==31 ); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, k); + }else{ + sqlite3VdbeAddOp2(v, OP_Null, 0, k); + } + } + if( chngRowid==0 && pPk==0 ){ +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + if( isView ) sqlite3VdbeAddOp2(v, OP_Null, 0, regOldRowid); +#endif + sqlite3VdbeAddOp2(v, OP_Copy, regOldRowid, regNewRowid); + } + } + + /* Populate the array of registers beginning at regNew with the new + ** row data. This array is used to check constants, create the new + ** table and index records, and as the values for any new.* references + ** made by triggers. + ** + ** If there are one or more BEFORE triggers, then do not populate the + ** registers associated with columns that are (a) not modified by + ** this UPDATE statement and (b) not accessed by new.* references. The + ** values for registers not modified by the UPDATE must be reloaded from + ** the database after the BEFORE triggers are fired anyway (as the trigger + ** may have modified them). So not loading those that are not going to + ** be used eliminates some redundant opcodes. + */ + newmask = sqlite3TriggerColmask( + pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE, pTab, onError + ); + for(i=0, k=regNew; inCol; i++, k++){ + if( i==pTab->iPKey ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, k); + }else if( (pTab->aCol[i].colFlags & COLFLAG_GENERATED)!=0 ){ + if( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ) k--; + }else{ + j = aXRef[i]; + if( j>=0 ){ + if( nChangeFrom ){ + int nOff = (isView ? pTab->nCol : nPk); + assert( eOnePass==ONEPASS_OFF ); + sqlite3VdbeAddOp3(v, OP_Column, iEph, nOff+j, k); + }else{ + sqlite3ExprCode(pParse, pChanges->a[j].pExpr, k); + } + }else if( 0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask & MASKBIT32(i)) ){ + /* This branch loads the value of a column that will not be changed + ** into a register. This is done if there are no BEFORE triggers, or + ** if there are one or more BEFORE triggers that use this value via + ** a new.* reference in a trigger program. + */ + testcase( i==31 ); + testcase( i==32 ); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, k); + bFinishSeek = 0; + }else{ + sqlite3VdbeAddOp2(v, OP_Null, 0, k); + } + } + } +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + if( pTab->tabFlags & TF_HasGenerated ){ + testcase( pTab->tabFlags & TF_HasVirtual ); + testcase( pTab->tabFlags & TF_HasStored ); + sqlite3ComputeGeneratedColumns(pParse, regNew, pTab); + } +#endif + + /* Fire any BEFORE UPDATE triggers. This happens before constraints are + ** verified. One could argue that this is wrong. + */ + if( tmask&TRIGGER_BEFORE ){ + sqlite3TableAffinity(v, pTab, regNew); + sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, + TRIGGER_BEFORE, pTab, regOldRowid, onError, labelContinue); + + if( !isView ){ + /* The row-trigger may have deleted the row being updated. In this + ** case, jump to the next row. No updates or AFTER triggers are + ** required. This behavior - what happens when the row being updated + ** is deleted or renamed by a BEFORE trigger - is left undefined in the + ** documentation. + */ + if( pPk ){ + sqlite3VdbeAddOp4Int(v, OP_NotFound,iDataCur,labelContinue,regKey,nKey); + VdbeCoverage(v); + }else{ + sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue,regOldRowid); + VdbeCoverage(v); + } + + /* After-BEFORE-trigger-reload-loop: + ** If it did not delete it, the BEFORE trigger may still have modified + ** some of the columns of the row being updated. Load the values for + ** all columns not modified by the update statement into their registers + ** in case this has happened. Only unmodified columns are reloaded. + ** The values computed for modified columns use the values before the + ** BEFORE trigger runs. See test case trigger1-18.0 (added 2018-04-26) + ** for an example. + */ + for(i=0, k=regNew; inCol; i++, k++){ + if( pTab->aCol[i].colFlags & COLFLAG_GENERATED ){ + if( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ) k--; + }else if( aXRef[i]<0 && i!=pTab->iPKey ){ + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, k); + } + } +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + if( pTab->tabFlags & TF_HasGenerated ){ + testcase( pTab->tabFlags & TF_HasVirtual ); + testcase( pTab->tabFlags & TF_HasStored ); + sqlite3ComputeGeneratedColumns(pParse, regNew, pTab); + } +#endif + } + } + + if( !isView ){ + /* Do constraint checks. */ + assert( regOldRowid>0 ); + sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur, + regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace, + aXRef, 0); + + /* If REPLACE conflict handling may have been used, or if the PK of the + ** row is changing, then the GenerateConstraintChecks() above may have + ** moved cursor iDataCur. Reseek it. */ + if( bReplace || chngKey ){ + if( pPk ){ + sqlite3VdbeAddOp4Int(v, OP_NotFound,iDataCur,labelContinue,regKey,nKey); + }else{ + sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue,regOldRowid); + } + VdbeCoverage(v); + } + + /* Do FK constraint checks. */ + if( hasFK ){ + sqlite3FkCheck(pParse, pTab, regOldRowid, 0, aXRef, chngKey); + } + + /* Delete the index entries associated with the current record. */ + sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx, -1); + + /* We must run the OP_FinishSeek opcode to resolve a prior + ** OP_DeferredSeek if there is any possibility that there have been + ** no OP_Column opcodes since the OP_DeferredSeek was issued. But + ** we want to avoid the OP_FinishSeek if possible, as running it + ** costs CPU cycles. */ + if( bFinishSeek ){ + sqlite3VdbeAddOp1(v, OP_FinishSeek, iDataCur); + } + + /* If changing the rowid value, or if there are foreign key constraints + ** to process, delete the old record. Otherwise, add a noop OP_Delete + ** to invoke the pre-update hook. + ** + ** That (regNew==regnewRowid+1) is true is also important for the + ** pre-update hook. If the caller invokes preupdate_new(), the returned + ** value is copied from memory cell (regNewRowid+1+iCol), where iCol + ** is the column index supplied by the user. + */ + assert( regNew==regNewRowid+1 ); +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + sqlite3VdbeAddOp3(v, OP_Delete, iDataCur, + OPFLAG_ISUPDATE | ((hasFK>1 || chngKey) ? 0 : OPFLAG_ISNOOP), + regNewRowid + ); + if( eOnePass==ONEPASS_MULTI ){ + assert( hasFK==0 && chngKey==0 ); + sqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION); + } + if( !pParse->nested ){ + sqlite3VdbeAppendP4(v, pTab, P4_TABLE); + } +#else + if( hasFK>1 || chngKey ){ + sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0); + } +#endif + + if( hasFK ){ + sqlite3FkCheck(pParse, pTab, 0, regNewRowid, aXRef, chngKey); + } + + /* Insert the new index entries and the new record. */ + sqlite3CompleteInsertion( + pParse, pTab, iDataCur, iIdxCur, regNewRowid, aRegIdx, + OPFLAG_ISUPDATE | (eOnePass==ONEPASS_MULTI ? OPFLAG_SAVEPOSITION : 0), + 0, 0 + ); + + /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to + ** handle rows (possibly in other tables) that refer via a foreign key + ** to the row just updated. */ + if( hasFK ){ + sqlite3FkActions(pParse, pTab, pChanges, regOldRowid, aXRef, chngKey); + } + } + + /* Increment the row counter + */ + if( regRowCount ){ + sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1); + } + + if( pTrigger ){ + sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, + TRIGGER_AFTER, pTab, regOldRowid, onError, labelContinue); + } + + /* Repeat the above with the next record to be updated, until + ** all record selected by the WHERE clause have been updated. + */ + if( eOnePass==ONEPASS_SINGLE ){ + /* Nothing to do at end-of-loop for a single-pass */ + }else if( eOnePass==ONEPASS_MULTI ){ + sqlite3VdbeResolveLabel(v, labelContinue); + sqlite3WhereEnd(pWInfo); + }else{ + sqlite3VdbeResolveLabel(v, labelContinue); + sqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop); VdbeCoverage(v); + } + sqlite3VdbeResolveLabel(v, labelBreak); + + /* Update the sqlite_sequence table by storing the content of the + ** maximum rowid counter values recorded while inserting into + ** autoincrement tables. + */ + if( pParse->nested==0 && pParse->pTriggerTab==0 && pUpsert==0 ){ + sqlite3AutoincrementEnd(pParse); + } + + /* + ** Return the number of rows that were changed, if we are tracking + ** that information. + */ + if( regRowCount ){ + sqlite3CodeChangeCount(v, regRowCount, "rows updated"); + } + +update_cleanup: + sqlite3AuthContextPop(&sContext); + sqlite3DbFree(db, aXRef); /* Also frees aRegIdx[] and aToOpen[] */ + sqlite3SrcListDelete(db, pTabList); + sqlite3ExprListDelete(db, pChanges); + sqlite3ExprDelete(db, pWhere); +#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) + sqlite3ExprListDelete(db, pOrderBy); + sqlite3ExprDelete(db, pLimit); +#endif + return; +} +/* Make sure "isView" and other macros defined above are undefined. Otherwise +** they may interfere with compilation of other functions in this file +** (or in another file, if this file becomes part of the amalgamation). */ +#ifdef isView + #undef isView +#endif +#ifdef pTrigger + #undef pTrigger +#endif + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Generate code for an UPDATE of a virtual table. +** +** There are two possible strategies - the default and the special +** "onepass" strategy. Onepass is only used if the virtual table +** implementation indicates that pWhere may match at most one row. +** +** The default strategy is to create an ephemeral table that contains +** for each row to be changed: +** +** (A) The original rowid of that row. +** (B) The revised rowid for the row. +** (C) The content of every column in the row. +** +** Then loop through the contents of this ephemeral table executing a +** VUpdate for each row. When finished, drop the ephemeral table. +** +** The "onepass" strategy does not use an ephemeral table. Instead, it +** stores the same values (A, B and C above) in a register array and +** makes a single invocation of VUpdate. +*/ +static void updateVirtualTable( + Parse *pParse, /* The parsing context */ + SrcList *pSrc, /* The virtual table to be modified */ + Table *pTab, /* The virtual table */ + ExprList *pChanges, /* The columns to change in the UPDATE statement */ + Expr *pRowid, /* Expression used to recompute the rowid */ + int *aXRef, /* Mapping from columns of pTab to entries in pChanges */ + Expr *pWhere, /* WHERE clause of the UPDATE statement */ + int onError /* ON CONFLICT strategy */ +){ + Vdbe *v = pParse->pVdbe; /* Virtual machine under construction */ + int ephemTab; /* Table holding the result of the SELECT */ + int i; /* Loop counter */ + sqlite3 *db = pParse->db; /* Database connection */ + const char *pVTab = (const char*)sqlite3GetVTable(db, pTab); + WhereInfo *pWInfo = 0; + int nArg = 2 + pTab->nCol; /* Number of arguments to VUpdate */ + int regArg; /* First register in VUpdate arg array */ + int regRec; /* Register in which to assemble record */ + int regRowid; /* Register for ephemeral table rowid */ + int iCsr = pSrc->a[0].iCursor; /* Cursor used for virtual table scan */ + int aDummy[2]; /* Unused arg for sqlite3WhereOkOnePass() */ + int eOnePass; /* True to use onepass strategy */ + int addr; /* Address of OP_OpenEphemeral */ + + /* Allocate nArg registers in which to gather the arguments for VUpdate. Then + ** create and open the ephemeral table in which the records created from + ** these arguments will be temporarily stored. */ + assert( v ); + ephemTab = pParse->nTab++; + addr= sqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, nArg); + regArg = pParse->nMem + 1; + pParse->nMem += nArg; + if( pSrc->nSrc>1 ){ + Index *pPk = 0; + Expr *pRow; + ExprList *pList; + if( HasRowid(pTab) ){ + if( pRowid ){ + pRow = sqlite3ExprDup(db, pRowid, 0); + }else{ + pRow = sqlite3PExpr(pParse, TK_ROW, 0, 0); + } + }else{ + i16 iPk; /* PRIMARY KEY column */ + pPk = sqlite3PrimaryKeyIndex(pTab); + assert( pPk!=0 ); + assert( pPk->nKeyCol==1 ); + iPk = pPk->aiColumn[0]; + if( aXRef[iPk]>=0 ){ + pRow = sqlite3ExprDup(db, pChanges->a[aXRef[iPk]].pExpr, 0); + }else{ + pRow = exprRowColumn(pParse, iPk); + } + } + pList = sqlite3ExprListAppend(pParse, 0, pRow); + + for(i=0; inCol; i++){ + if( aXRef[i]>=0 ){ + pList = sqlite3ExprListAppend(pParse, pList, + sqlite3ExprDup(db, pChanges->a[aXRef[i]].pExpr, 0) + ); + }else{ + Expr *pRowExpr = exprRowColumn(pParse, i); + if( pRowExpr ) pRowExpr->op2 = OPFLAG_NOCHNG; + pList = sqlite3ExprListAppend(pParse, pList, pRowExpr); + } + } + + updateFromSelect(pParse, ephemTab, pPk, pList, pSrc, pWhere, 0, 0); + sqlite3ExprListDelete(db, pList); + eOnePass = ONEPASS_OFF; + }else{ + regRec = ++pParse->nMem; + regRowid = ++pParse->nMem; + + /* Start scanning the virtual table */ + pWInfo = sqlite3WhereBegin( + pParse, pSrc, pWhere, 0, 0, 0, WHERE_ONEPASS_DESIRED, 0 + ); + if( pWInfo==0 ) return; + + /* Populate the argument registers. */ + for(i=0; inCol; i++){ + assert( (pTab->aCol[i].colFlags & COLFLAG_GENERATED)==0 ); + if( aXRef[i]>=0 ){ + sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i); + }else{ + sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i); + sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG);/* For sqlite3_vtab_nochange() */ + } + } + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg); + if( pRowid ){ + sqlite3ExprCode(pParse, pRowid, regArg+1); + }else{ + sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg+1); + } + }else{ + Index *pPk; /* PRIMARY KEY index */ + i16 iPk; /* PRIMARY KEY column */ + pPk = sqlite3PrimaryKeyIndex(pTab); + assert( pPk!=0 ); + assert( pPk->nKeyCol==1 ); + iPk = pPk->aiColumn[0]; + sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, iPk, regArg); + sqlite3VdbeAddOp2(v, OP_SCopy, regArg+2+iPk, regArg+1); + } + + eOnePass = sqlite3WhereOkOnePass(pWInfo, aDummy); + + /* There is no ONEPASS_MULTI on virtual tables */ + assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE ); + + if( eOnePass ){ + /* If using the onepass strategy, no-op out the OP_OpenEphemeral coded + ** above. */ + sqlite3VdbeChangeToNoop(v, addr); + sqlite3VdbeAddOp1(v, OP_Close, iCsr); + }else{ + /* Create a record from the argument register contents and insert it into + ** the ephemeral table. */ + sqlite3MultiWrite(pParse); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regArg, nArg, regRec); +#if defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_NULL_TRIM) + /* Signal an assert() within OP_MakeRecord that it is allowed to + ** accept no-change records with serial_type 10 */ + sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG_MAGIC); +#endif + sqlite3VdbeAddOp2(v, OP_NewRowid, ephemTab, regRowid); + sqlite3VdbeAddOp3(v, OP_Insert, ephemTab, regRec, regRowid); + } + } + + + if( eOnePass==ONEPASS_OFF ){ + /* End the virtual table scan */ + if( pSrc->nSrc==1 ){ + sqlite3WhereEnd(pWInfo); + } + + /* Begin scanning through the ephemeral table. */ + addr = sqlite3VdbeAddOp1(v, OP_Rewind, ephemTab); VdbeCoverage(v); + + /* Extract arguments from the current row of the ephemeral table and + ** invoke the VUpdate method. */ + for(i=0; ipNextUpsert; + sqlite3ExprListDelete(db, p->pUpsertTarget); + sqlite3ExprDelete(db, p->pUpsertTargetWhere); + sqlite3ExprListDelete(db, p->pUpsertSet); + sqlite3ExprDelete(db, p->pUpsertWhere); + sqlite3DbFree(db, p->pToFree); + sqlite3DbFree(db, p); + p = pNext; + }while( p ); +} +SQLITE_PRIVATE void sqlite3UpsertDelete(sqlite3 *db, Upsert *p){ + if( p ) upsertDelete(db, p); +} + + +/* +** Duplicate an Upsert object. +*/ +SQLITE_PRIVATE Upsert *sqlite3UpsertDup(sqlite3 *db, Upsert *p){ + if( p==0 ) return 0; + return sqlite3UpsertNew(db, + sqlite3ExprListDup(db, p->pUpsertTarget, 0), + sqlite3ExprDup(db, p->pUpsertTargetWhere, 0), + sqlite3ExprListDup(db, p->pUpsertSet, 0), + sqlite3ExprDup(db, p->pUpsertWhere, 0), + sqlite3UpsertDup(db, p->pNextUpsert) + ); +} + +/* +** Create a new Upsert object. +*/ +SQLITE_PRIVATE Upsert *sqlite3UpsertNew( + sqlite3 *db, /* Determines which memory allocator to use */ + ExprList *pTarget, /* Target argument to ON CONFLICT, or NULL */ + Expr *pTargetWhere, /* Optional WHERE clause on the target */ + ExprList *pSet, /* UPDATE columns, or NULL for a DO NOTHING */ + Expr *pWhere, /* WHERE clause for the ON CONFLICT UPDATE */ + Upsert *pNext /* Next ON CONFLICT clause in the list */ +){ + Upsert *pNew; + pNew = sqlite3DbMallocZero(db, sizeof(Upsert)); + if( pNew==0 ){ + sqlite3ExprListDelete(db, pTarget); + sqlite3ExprDelete(db, pTargetWhere); + sqlite3ExprListDelete(db, pSet); + sqlite3ExprDelete(db, pWhere); + sqlite3UpsertDelete(db, pNext); + return 0; + }else{ + pNew->pUpsertTarget = pTarget; + pNew->pUpsertTargetWhere = pTargetWhere; + pNew->pUpsertSet = pSet; + pNew->pUpsertWhere = pWhere; + pNew->isDoUpdate = pSet!=0; + pNew->pNextUpsert = pNext; + } + return pNew; +} + +/* +** Analyze the ON CONFLICT clause described by pUpsert. Resolve all +** symbols in the conflict-target. +** +** Return SQLITE_OK if everything works, or an error code is something +** is wrong. +*/ +SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget( + Parse *pParse, /* The parsing context */ + SrcList *pTabList, /* Table into which we are inserting */ + Upsert *pUpsert, /* The ON CONFLICT clauses */ + Upsert *pAll /* Complete list of all ON CONFLICT clauses */ +){ + Table *pTab; /* That table into which we are inserting */ + int rc; /* Result code */ + int iCursor; /* Cursor used by pTab */ + Index *pIdx; /* One of the indexes of pTab */ + ExprList *pTarget; /* The conflict-target clause */ + Expr *pTerm; /* One term of the conflict-target clause */ + NameContext sNC; /* Context for resolving symbolic names */ + Expr sCol[2]; /* Index column converted into an Expr */ + int nClause = 0; /* Counter of ON CONFLICT clauses */ + + assert( pTabList->nSrc==1 ); + assert( pTabList->a[0].pSTab!=0 ); + assert( pUpsert!=0 ); + assert( pUpsert->pUpsertTarget!=0 ); + + /* Resolve all symbolic names in the conflict-target clause, which + ** includes both the list of columns and the optional partial-index + ** WHERE clause. + */ + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + sNC.pSrcList = pTabList; + for(; pUpsert && pUpsert->pUpsertTarget; + pUpsert=pUpsert->pNextUpsert, nClause++){ + rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget); + if( rc ) return rc; + rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere); + if( rc ) return rc; + + /* Check to see if the conflict target matches the rowid. */ + pTab = pTabList->a[0].pSTab; + pTarget = pUpsert->pUpsertTarget; + iCursor = pTabList->a[0].iCursor; + if( HasRowid(pTab) + && pTarget->nExpr==1 + && (pTerm = pTarget->a[0].pExpr)->op==TK_COLUMN + && pTerm->iColumn==XN_ROWID + ){ + /* The conflict-target is the rowid of the primary table */ + assert( pUpsert->pUpsertIdx==0 ); + continue; + } + + /* Initialize sCol[0..1] to be an expression parse tree for a + ** single column of an index. The sCol[0] node will be the TK_COLLATE + ** operator and sCol[1] will be the TK_COLUMN operator. Code below + ** will populate the specific collation and column number values + ** prior to comparing against the conflict-target expression. + */ + memset(sCol, 0, sizeof(sCol)); + sCol[0].op = TK_COLLATE; + sCol[0].pLeft = &sCol[1]; + sCol[1].op = TK_COLUMN; + sCol[1].iTable = pTabList->a[0].iCursor; + + /* Check for matches against other indexes */ + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + int ii, jj, nn; + if( !IsUniqueIndex(pIdx) ) continue; + if( pTarget->nExpr!=pIdx->nKeyCol ) continue; + if( pIdx->pPartIdxWhere ){ + if( pUpsert->pUpsertTargetWhere==0 ) continue; + if( sqlite3ExprCompare(pParse, pUpsert->pUpsertTargetWhere, + pIdx->pPartIdxWhere, iCursor)!=0 ){ + continue; + } + } + nn = pIdx->nKeyCol; + for(ii=0; iiazColl[ii]; + if( pIdx->aiColumn[ii]==XN_EXPR ){ + assert( pIdx->aColExpr!=0 ); + assert( pIdx->aColExpr->nExpr>ii ); + assert( pIdx->bHasExpr ); + pExpr = pIdx->aColExpr->a[ii].pExpr; + if( pExpr->op!=TK_COLLATE ){ + sCol[0].pLeft = pExpr; + pExpr = &sCol[0]; + } + }else{ + sCol[0].pLeft = &sCol[1]; + sCol[1].iColumn = pIdx->aiColumn[ii]; + pExpr = &sCol[0]; + } + for(jj=0; jja[jj].pExpr,pExpr,iCursor)<2 ){ + break; /* Column ii of the index matches column jj of target */ + } + } + if( jj>=nn ){ + /* The target contains no match for column jj of the index */ + break; + } + } + if( iipUpsertIdx = pIdx; + if( sqlite3UpsertOfIndex(pAll,pIdx)!=pUpsert ){ + /* Really this should be an error. The isDup ON CONFLICT clause will + ** never fire. But this problem was not discovered until three years + ** after multi-CONFLICT upsert was added, and so we silently ignore + ** the problem to prevent breaking applications that might actually + ** have redundant ON CONFLICT clauses. */ + pUpsert->isDup = 1; + } + break; + } + if( pUpsert->pUpsertIdx==0 ){ + char zWhich[16]; + if( nClause==0 && pUpsert->pNextUpsert==0 ){ + zWhich[0] = 0; + }else{ + sqlite3_snprintf(sizeof(zWhich),zWhich,"%r ", nClause+1); + } + sqlite3ErrorMsg(pParse, "%sON CONFLICT clause does not match any " + "PRIMARY KEY or UNIQUE constraint", zWhich); + return SQLITE_ERROR; + } + } + return SQLITE_OK; +} + +/* +** Return true if pUpsert is the last ON CONFLICT clause with a +** conflict target, or if pUpsert is followed by another ON CONFLICT +** clause that targets the INTEGER PRIMARY KEY. +*/ +SQLITE_PRIVATE int sqlite3UpsertNextIsIPK(Upsert *pUpsert){ + Upsert *pNext; + if( NEVER(pUpsert==0) ) return 0; + pNext = pUpsert->pNextUpsert; + while( 1 /*exit-by-return*/ ){ + if( pNext==0 ) return 1; + if( pNext->pUpsertTarget==0 ) return 1; + if( pNext->pUpsertIdx==0 ) return 1; + if( !pNext->isDup ) return 0; + pNext = pNext->pNextUpsert; + } + return 0; +} + +/* +** Given the list of ON CONFLICT clauses described by pUpsert, and +** a particular index pIdx, return a pointer to the particular ON CONFLICT +** clause that applies to the index. Or, if the index is not subject to +** any ON CONFLICT clause, return NULL. +*/ +SQLITE_PRIVATE Upsert *sqlite3UpsertOfIndex(Upsert *pUpsert, Index *pIdx){ + while( + pUpsert + && pUpsert->pUpsertTarget!=0 + && pUpsert->pUpsertIdx!=pIdx + ){ + pUpsert = pUpsert->pNextUpsert; + } + return pUpsert; +} + +/* +** Generate bytecode that does an UPDATE as part of an upsert. +** +** If pIdx is NULL, then the UNIQUE constraint that failed was the IPK. +** In this case parameter iCur is a cursor open on the table b-tree that +** currently points to the conflicting table row. Otherwise, if pIdx +** is not NULL, then pIdx is the constraint that failed and iCur is a +** cursor points to the conflicting row. +*/ +SQLITE_PRIVATE void sqlite3UpsertDoUpdate( + Parse *pParse, /* The parsing and code-generating context */ + Upsert *pUpsert, /* The ON CONFLICT clause for the upsert */ + Table *pTab, /* The table being updated */ + Index *pIdx, /* The UNIQUE constraint that failed */ + int iCur /* Cursor for pIdx (or pTab if pIdx==NULL) */ +){ + Vdbe *v = pParse->pVdbe; + sqlite3 *db = pParse->db; + SrcList *pSrc; /* FROM clause for the UPDATE */ + int iDataCur; + int i; + Upsert *pTop = pUpsert; + + assert( v!=0 ); + assert( pUpsert!=0 ); + iDataCur = pUpsert->iDataCur; + pUpsert = sqlite3UpsertOfIndex(pTop, pIdx); + VdbeNoopComment((v, "Begin DO UPDATE of UPSERT")); + if( pIdx && iCur!=iDataCur ){ + if( HasRowid(pTab) ){ + int regRowid = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_IdxRowid, iCur, regRowid); + sqlite3VdbeAddOp3(v, OP_SeekRowid, iDataCur, 0, regRowid); + VdbeCoverage(v); + sqlite3ReleaseTempReg(pParse, regRowid); + }else{ + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + int nPk = pPk->nKeyCol; + int iPk = pParse->nMem+1; + pParse->nMem += nPk; + for(i=0; iaiColumn[i]>=0 ); + k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[i]); + sqlite3VdbeAddOp3(v, OP_Column, iCur, k, iPk+i); + VdbeComment((v, "%s.%s", pIdx->zName, + pTab->aCol[pPk->aiColumn[i]].zCnName)); + } + sqlite3VdbeVerifyAbortable(v, OE_Abort); + i = sqlite3VdbeAddOp4Int(v, OP_Found, iDataCur, 0, iPk, nPk); + VdbeCoverage(v); + sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CORRUPT, OE_Abort, 0, + "corrupt database", P4_STATIC); + sqlite3MayAbort(pParse); + sqlite3VdbeJumpHere(v, i); + } + } + /* pUpsert does not own pTop->pUpsertSrc - the outer INSERT statement does. + ** So we have to make a copy before passing it down into sqlite3Update() */ + pSrc = sqlite3SrcListDup(db, pTop->pUpsertSrc, 0); + /* excluded.* columns of type REAL need to be converted to a hard real */ + for(i=0; inCol; i++){ + if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){ + int iStorage = pTop->regData + sqlite3TableColumnToStorage(pTab, i); + sqlite3VdbeAddOp1(v, OP_RealAffinity, iStorage); + } + } + sqlite3Update(pParse, pSrc, sqlite3ExprListDup(db,pUpsert->pUpsertSet,0), + sqlite3ExprDup(db,pUpsert->pUpsertWhere,0), OE_Abort, 0, 0, pUpsert); + VdbeNoopComment((v, "End DO UPDATE of UPSERT")); +} + +#endif /* SQLITE_OMIT_UPSERT */ + +/************** End of upsert.c **********************************************/ +/************** Begin file vacuum.c ******************************************/ +/* +** 2003 April 6 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code used to implement the VACUUM command. +** +** Most of the code in this file may be omitted by defining the +** SQLITE_OMIT_VACUUM macro. +*/ +/* #include "sqliteInt.h" */ +/* #include "vdbeInt.h" */ + +#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) + +/* +** Execute zSql on database db. +** +** If zSql returns rows, then each row will have exactly one +** column. (This will only happen if zSql begins with "SELECT".) +** Take each row of result and call execSql() again recursively. +** +** The execSqlF() routine does the same thing, except it accepts +** a format string as its third argument +*/ +static int execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){ + sqlite3_stmt *pStmt; + int rc; + + /* printf("SQL: [%s]\n", zSql); fflush(stdout); */ + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + if( rc!=SQLITE_OK ) return rc; + while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){ + const char *zSubSql = (const char*)sqlite3_column_text(pStmt,0); + assert( sqlite3_strnicmp(zSql,"SELECT",6)==0 ); + /* The secondary SQL must be one of CREATE TABLE, CREATE INDEX, + ** or INSERT. Historically there have been attacks that first + ** corrupt the sqlite_schema.sql field with other kinds of statements + ** then run VACUUM to get those statements to execute at inappropriate + ** times. */ + if( zSubSql + && (strncmp(zSubSql,"CRE",3)==0 || strncmp(zSubSql,"INS",3)==0) + ){ + rc = execSql(db, pzErrMsg, zSubSql); + if( rc!=SQLITE_OK ) break; + } + } + assert( rc!=SQLITE_ROW ); + if( rc==SQLITE_DONE ) rc = SQLITE_OK; + if( rc ){ + sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db)); + } + (void)sqlite3_finalize(pStmt); + return rc; +} +static int execSqlF(sqlite3 *db, char **pzErrMsg, const char *zSql, ...){ + char *z; + va_list ap; + int rc; + va_start(ap, zSql); + z = sqlite3VMPrintf(db, zSql, ap); + va_end(ap); + if( z==0 ) return SQLITE_NOMEM; + rc = execSql(db, pzErrMsg, z); + sqlite3DbFree(db, z); + return rc; +} + +/* +** The VACUUM command is used to clean up the database, +** collapse free space, etc. It is modelled after the VACUUM command +** in PostgreSQL. The VACUUM command works as follows: +** +** (1) Create a new transient database file +** (2) Copy all content from the database being vacuumed into +** the new transient database file +** (3) Copy content from the transient database back into the +** original database. +** +** The transient database requires temporary disk space approximately +** equal to the size of the original database. The copy operation of +** step (3) requires additional temporary disk space approximately equal +** to the size of the original database for the rollback journal. +** Hence, temporary disk space that is approximately 2x the size of the +** original database is required. Every page of the database is written +** approximately 3 times: Once for step (2) and twice for step (3). +** Two writes per page are required in step (3) because the original +** database content must be written into the rollback journal prior to +** overwriting the database with the vacuumed content. +** +** Only 1x temporary space and only 1x writes would be required if +** the copy of step (3) were replaced by deleting the original database +** and renaming the transient database as the original. But that will +** not work if other processes are attached to the original database. +** And a power loss in between deleting the original and renaming the +** transient would cause the database file to appear to be deleted +** following reboot. +*/ +SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm, Expr *pInto){ + Vdbe *v = sqlite3GetVdbe(pParse); + int iDb = 0; + if( v==0 ) goto build_vacuum_end; + if( pParse->nErr ) goto build_vacuum_end; + if( pNm ){ +#ifndef SQLITE_BUG_COMPATIBLE_20160819 + /* Default behavior: Report an error if the argument to VACUUM is + ** not recognized */ + iDb = sqlite3TwoPartName(pParse, pNm, pNm, &pNm); + if( iDb<0 ) goto build_vacuum_end; +#else + /* When SQLITE_BUG_COMPATIBLE_20160819 is defined, unrecognized arguments + ** to VACUUM are silently ignored. This is a back-out of a bug fix that + ** occurred on 2016-08-19 (https://sqlite.org/src/info/083f9e6270). + ** The buggy behavior is required for binary compatibility with some + ** legacy applications. */ + iDb = sqlite3FindDb(pParse->db, pNm); + if( iDb<0 ) iDb = 0; +#endif + } + if( iDb!=1 ){ + int iIntoReg = 0; + if( pInto && sqlite3ResolveSelfReference(pParse,0,0,pInto,0)==0 ){ + iIntoReg = ++pParse->nMem; + sqlite3ExprCode(pParse, pInto, iIntoReg); + } + sqlite3VdbeAddOp2(v, OP_Vacuum, iDb, iIntoReg); + sqlite3VdbeUsesBtree(v, iDb); + } +build_vacuum_end: + sqlite3ExprDelete(pParse->db, pInto); + return; +} + +/* +** This routine implements the OP_Vacuum opcode of the VDBE. +*/ +SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( + char **pzErrMsg, /* Write error message here */ + sqlite3 *db, /* Database connection */ + int iDb, /* Which attached DB to vacuum */ + sqlite3_value *pOut /* Write results here, if not NULL. VACUUM INTO */ +){ + int rc = SQLITE_OK; /* Return code from service routines */ + Btree *pMain; /* The database being vacuumed */ + Btree *pTemp; /* The temporary database we vacuum into */ + u32 saved_mDbFlags; /* Saved value of db->mDbFlags */ + u64 saved_flags; /* Saved value of db->flags */ + i64 saved_nChange; /* Saved value of db->nChange */ + i64 saved_nTotalChange; /* Saved value of db->nTotalChange */ + u32 saved_openFlags; /* Saved value of db->openFlags */ + u8 saved_mTrace; /* Saved trace settings */ + Db *pDb = 0; /* Database to detach at end of vacuum */ + int isMemDb; /* True if vacuuming a :memory: database */ + int nRes; /* Bytes of reserved space at the end of each page */ + int nDb; /* Number of attached databases */ + const char *zDbMain; /* Schema name of database to vacuum */ + const char *zOut; /* Name of output file */ + u32 pgflags = PAGER_SYNCHRONOUS_OFF; /* sync flags for output db */ + u64 iRandom; /* Random value used for zDbVacuum[] */ + char zDbVacuum[42]; /* Name of the ATTACH-ed database used for vacuum */ + + + if( !db->autoCommit ){ + sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction"); + return SQLITE_ERROR; /* IMP: R-12218-18073 */ + } + if( db->nVdbeActive>1 ){ + sqlite3SetString(pzErrMsg, db,"cannot VACUUM - SQL statements in progress"); + return SQLITE_ERROR; /* IMP: R-15610-35227 */ + } + saved_openFlags = db->openFlags; + if( pOut ){ + if( sqlite3_value_type(pOut)!=SQLITE_TEXT ){ + sqlite3SetString(pzErrMsg, db, "non-text filename"); + return SQLITE_ERROR; + } + zOut = (const char*)sqlite3_value_text(pOut); + db->openFlags &= ~SQLITE_OPEN_READONLY; + db->openFlags |= SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE; + }else{ + zOut = ""; + } + + /* Save the current value of the database flags so that it can be + ** restored before returning. Then set the writable-schema flag, and + ** disable CHECK and foreign key constraints. */ + saved_flags = db->flags; + saved_mDbFlags = db->mDbFlags; + saved_nChange = db->nChange; + saved_nTotalChange = db->nTotalChange; + saved_mTrace = db->mTrace; + db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_Comments + | SQLITE_AttachCreate | SQLITE_AttachWrite; + db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum; + db->flags &= ~(u64)(SQLITE_ForeignKeys | SQLITE_ReverseOrder + | SQLITE_Defensive | SQLITE_CountRows); + db->mTrace = 0; + + zDbMain = db->aDb[iDb].zDbSName; + pMain = db->aDb[iDb].pBt; + isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain)); + + /* Attach the temporary database as 'vacuum_XXXXXX'. The synchronous pragma + ** can be set to 'off' for this file, as it is not recovered if a crash + ** occurs anyway. The integrity of the database is maintained by a + ** (possibly synchronous) transaction opened on the main database before + ** sqlite3BtreeCopyFile() is called. + ** + ** An optimization would be to use a non-journaled pager. + ** (Later:) I tried setting "PRAGMA vacuum_XXXXXX.journal_mode=OFF" but + ** that actually made the VACUUM run slower. Very little journalling + ** actually occurs when doing a vacuum since the vacuum_db is initially + ** empty. Only the journal header is written. Apparently it takes more + ** time to parse and run the PRAGMA to turn journalling off than it does + ** to write the journal header file. + */ + sqlite3_randomness(sizeof(iRandom),&iRandom); + sqlite3_snprintf(sizeof(zDbVacuum), zDbVacuum, "vacuum_%016llx", iRandom); + nDb = db->nDb; + rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS %s", zOut, zDbVacuum); + db->openFlags = saved_openFlags; + if( rc!=SQLITE_OK ) goto end_of_vacuum; + assert( (db->nDb-1)==nDb ); + pDb = &db->aDb[nDb]; + assert( strcmp(pDb->zDbSName,zDbVacuum)==0 ); + pTemp = pDb->pBt; + nRes = sqlite3BtreeGetRequestedReserve(pMain); + if( pOut ){ + sqlite3_file *id = sqlite3PagerFile(sqlite3BtreePager(pTemp)); + i64 sz = 0; + const char *zFilename; + if( id->pMethods!=0 && (sqlite3OsFileSize(id, &sz)!=SQLITE_OK || sz>0) ){ + rc = SQLITE_ERROR; + sqlite3SetString(pzErrMsg, db, "output file already exists"); + goto end_of_vacuum; + } + db->mDbFlags |= DBFLAG_VacuumInto; + + /* For a VACUUM INTO, the pager-flags are set to the same values as + ** they are for the database being vacuumed, except that PAGER_CACHESPILL + ** is always set. */ + pgflags = db->aDb[iDb].safety_level | (db->flags & PAGER_FLAGS_MASK); + + /* If the VACUUM INTO target file is a URI filename and if the + ** "reserve=N" query parameter is present, reset the reserve to the + ** amount specified, if the amount is within range */ + zFilename = sqlite3BtreeGetFilename(pTemp); + if( ALWAYS(zFilename) ){ + int nNew = (int)sqlite3_uri_int64(zFilename, "reserve", nRes); + if( nNew>=0 && nNew<=255 ) nRes = nNew; + } + } + + sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size); + sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0)); + sqlite3BtreeSetPagerFlags(pTemp, pgflags|PAGER_CACHESPILL); + + /* Begin a transaction and take an exclusive lock on the main database + ** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below, + ** to ensure that we do not try to change the page-size on a WAL database. + */ + rc = execSql(db, pzErrMsg, "BEGIN"); + if( rc!=SQLITE_OK ) goto end_of_vacuum; + rc = sqlite3BtreeBeginTrans(pMain, pOut==0 ? 2 : 0, 0); + if( rc!=SQLITE_OK ) goto end_of_vacuum; + + /* Do not attempt to change the page size for a WAL database */ + if( sqlite3PagerGetJournalMode(sqlite3BtreePager(pMain)) + ==PAGER_JOURNALMODE_WAL + && pOut==0 + ){ + db->nextPagesize = 0; + } + + if( sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain), nRes, 0) + || (!isMemDb && sqlite3BtreeSetPageSize(pTemp, db->nextPagesize, nRes, 0)) + || NEVER(db->mallocFailed) + ){ + rc = SQLITE_NOMEM_BKPT; + goto end_of_vacuum; + } + +#ifndef SQLITE_OMIT_AUTOVACUUM + sqlite3BtreeSetAutoVacuum(pTemp, db->nextAutovac>=0 ? db->nextAutovac : + sqlite3BtreeGetAutoVacuum(pMain)); +#endif + + /* Query the schema of the main database. Create a mirror schema + ** in the temporary database. + */ + db->init.iDb = nDb; /* force new CREATE statements into vacuum_db */ + rc = execSqlF(db, pzErrMsg, + "SELECT sql FROM \"%w\".sqlite_schema" + " WHERE type='table'AND name<>'sqlite_sequence'" + " AND coalesce(rootpage,1)>0", + zDbMain + ); + if( rc!=SQLITE_OK ) goto end_of_vacuum; + rc = execSqlF(db, pzErrMsg, + "SELECT sql FROM \"%w\".sqlite_schema" + " WHERE type='index'", + zDbMain + ); + if( rc!=SQLITE_OK ) goto end_of_vacuum; + db->init.iDb = 0; + + /* Loop through the tables in the main database. For each, do + ** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy + ** the contents to the temporary database. + */ + rc = execSqlF(db, pzErrMsg, + "SELECT'INSERT INTO %s.'||quote(name)" + "||' SELECT*FROM\"%w\".'||quote(name)" + "FROM %s.sqlite_schema " + "WHERE type='table'AND coalesce(rootpage,1)>0", + zDbVacuum, zDbMain, zDbVacuum + ); + assert( (db->mDbFlags & DBFLAG_Vacuum)!=0 ); + db->mDbFlags &= ~DBFLAG_Vacuum; + if( rc!=SQLITE_OK ) goto end_of_vacuum; + + /* Copy the triggers, views, and virtual tables from the main database + ** over to the temporary database. None of these objects has any + ** associated storage, so all we have to do is copy their entries + ** from the schema table. + */ + rc = execSqlF(db, pzErrMsg, + "INSERT INTO %s.sqlite_schema" + " SELECT*FROM \"%w\".sqlite_schema" + " WHERE type IN('view','trigger')" + " OR(type='table'AND rootpage=0)", + zDbVacuum, zDbMain + ); + if( rc ) goto end_of_vacuum; + + /* At this point, there is a write transaction open on both the + ** vacuum database and the main database. Assuming no error occurs, + ** both transactions are closed by this block - the main database + ** transaction by sqlite3BtreeCopyFile() and the other by an explicit + ** call to sqlite3BtreeCommit(). + */ + { + u32 meta; + int i; + + /* This array determines which meta meta values are preserved in the + ** vacuum. Even entries are the meta value number and odd entries + ** are an increment to apply to the meta value after the vacuum. + ** The increment is used to increase the schema cookie so that other + ** connections to the same database will know to reread the schema. + */ + static const unsigned char aCopy[] = { + BTREE_SCHEMA_VERSION, 1, /* Add one to the old schema cookie */ + BTREE_DEFAULT_CACHE_SIZE, 0, /* Preserve the default page cache size */ + BTREE_TEXT_ENCODING, 0, /* Preserve the text encoding */ + BTREE_USER_VERSION, 0, /* Preserve the user version */ + BTREE_APPLICATION_ID, 0, /* Preserve the application id */ + }; + + assert( SQLITE_TXN_WRITE==sqlite3BtreeTxnState(pTemp) ); + assert( pOut!=0 || SQLITE_TXN_WRITE==sqlite3BtreeTxnState(pMain) ); + + /* Copy Btree meta values */ + for(i=0; iflags */ + db->init.iDb = 0; + db->mDbFlags = saved_mDbFlags; + db->flags = saved_flags; + db->nChange = saved_nChange; + db->nTotalChange = saved_nTotalChange; + db->mTrace = saved_mTrace; + sqlite3BtreeSetPageSize(pMain, -1, 0, 1); + + /* Currently there is an SQL level transaction open on the vacuum + ** database. No locks are held on any other files (since the main file + ** was committed at the btree level). So it safe to end the transaction + ** by manually setting the autoCommit flag to true and detaching the + ** vacuum database. The vacuum_db journal file is deleted when the pager + ** is closed by the DETACH. + */ + db->autoCommit = 1; + + if( pDb ){ + sqlite3BtreeClose(pDb->pBt); + pDb->pBt = 0; + pDb->pSchema = 0; + } + + /* This both clears the schemas and reduces the size of the db->aDb[] + ** array. */ + sqlite3ResetAllSchemasOfConnection(db); + + return rc; +} + +#endif /* SQLITE_OMIT_VACUUM && SQLITE_OMIT_ATTACH */ + +/************** End of vacuum.c **********************************************/ +/************** Begin file vtab.c ********************************************/ +/* +** 2006 June 10 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code used to help implement virtual tables. +*/ +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* #include "sqliteInt.h" */ + +/* +** Before a virtual table xCreate() or xConnect() method is invoked, the +** sqlite3.pVtabCtx member variable is set to point to an instance of +** this struct allocated on the stack. It is used by the implementation of +** the sqlite3_declare_vtab() and sqlite3_vtab_config() APIs, both of which +** are invoked only from within xCreate and xConnect methods. +*/ +struct VtabCtx { + VTable *pVTable; /* The virtual table being constructed */ + Table *pTab; /* The Table object to which the virtual table belongs */ + VtabCtx *pPrior; /* Parent context (if any) */ + int bDeclared; /* True after sqlite3_declare_vtab() is called */ +}; + +/* +** Construct and install a Module object for a virtual table. When this +** routine is called, it is guaranteed that all appropriate locks are held +** and the module is not already part of the connection. +** +** If there already exists a module with zName, replace it with the new one. +** If pModule==0, then delete the module zName if it exists. +*/ +SQLITE_PRIVATE Module *sqlite3VtabCreateModule( + sqlite3 *db, /* Database in which module is registered */ + const char *zName, /* Name assigned to this module */ + const sqlite3_module *pModule, /* The definition of the module */ + void *pAux, /* Context pointer for xCreate/xConnect */ + void (*xDestroy)(void *) /* Module destructor function */ +){ + Module *pMod; + Module *pDel; + char *zCopy; + if( pModule==0 ){ + zCopy = (char*)zName; + pMod = 0; + }else{ + int nName = sqlite3Strlen30(zName); + pMod = (Module *)sqlite3Malloc(sizeof(Module) + nName + 1); + if( pMod==0 ){ + sqlite3OomFault(db); + return 0; + } + zCopy = (char *)(&pMod[1]); + memcpy(zCopy, zName, nName+1); + pMod->zName = zCopy; + pMod->pModule = pModule; + pMod->pAux = pAux; + pMod->xDestroy = xDestroy; + pMod->pEpoTab = 0; + pMod->nRefModule = 1; + } + pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod); + if( pDel ){ + if( pDel==pMod ){ + sqlite3OomFault(db); + sqlite3DbFree(db, pDel); + pMod = 0; + }else{ + sqlite3VtabEponymousTableClear(db, pDel); + sqlite3VtabModuleUnref(db, pDel); + } + } + return pMod; +} + +/* +** The actual function that does the work of creating a new module. +** This function implements the sqlite3_create_module() and +** sqlite3_create_module_v2() interfaces. +*/ +static int createModule( + sqlite3 *db, /* Database in which module is registered */ + const char *zName, /* Name assigned to this module */ + const sqlite3_module *pModule, /* The definition of the module */ + void *pAux, /* Context pointer for xCreate/xConnect */ + void (*xDestroy)(void *) /* Module destructor function */ +){ + int rc = SQLITE_OK; + + sqlite3_mutex_enter(db->mutex); + (void)sqlite3VtabCreateModule(db, zName, pModule, pAux, xDestroy); + rc = sqlite3ApiExit(db, rc); + if( rc!=SQLITE_OK && xDestroy ) xDestroy(pAux); + sqlite3_mutex_leave(db->mutex); + return rc; +} + + +/* +** External API function used to create a new virtual-table module. +*/ +SQLITE_API int sqlite3_create_module( + sqlite3 *db, /* Database in which module is registered */ + const char *zName, /* Name assigned to this module */ + const sqlite3_module *pModule, /* The definition of the module */ + void *pAux /* Context pointer for xCreate/xConnect */ +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; +#endif + return createModule(db, zName, pModule, pAux, 0); +} + +/* +** External API function used to create a new virtual-table module. +*/ +SQLITE_API int sqlite3_create_module_v2( + sqlite3 *db, /* Database in which module is registered */ + const char *zName, /* Name assigned to this module */ + const sqlite3_module *pModule, /* The definition of the module */ + void *pAux, /* Context pointer for xCreate/xConnect */ + void (*xDestroy)(void *) /* Module destructor function */ +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; +#endif + return createModule(db, zName, pModule, pAux, xDestroy); +} + +/* +** External API to drop all virtual-table modules, except those named +** on the azNames list. +*/ +SQLITE_API int sqlite3_drop_modules(sqlite3 *db, const char** azNames){ + HashElem *pThis, *pNext; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + for(pThis=sqliteHashFirst(&db->aModule); pThis; pThis=pNext){ + Module *pMod = (Module*)sqliteHashData(pThis); + pNext = sqliteHashNext(pThis); + if( azNames ){ + int ii; + for(ii=0; azNames[ii]!=0 && strcmp(azNames[ii],pMod->zName)!=0; ii++){} + if( azNames[ii]!=0 ) continue; + } + createModule(db, pMod->zName, 0, 0, 0); + } + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + +/* +** Decrement the reference count on a Module object. Destroy the +** module when the reference count reaches zero. +*/ +SQLITE_PRIVATE void sqlite3VtabModuleUnref(sqlite3 *db, Module *pMod){ + assert( pMod->nRefModule>0 ); + pMod->nRefModule--; + if( pMod->nRefModule==0 ){ + if( pMod->xDestroy ){ + pMod->xDestroy(pMod->pAux); + } + assert( pMod->pEpoTab==0 ); + sqlite3DbFree(db, pMod); + } +} + +/* +** Lock the virtual table so that it cannot be disconnected. +** Locks nest. Every lock should have a corresponding unlock. +** If an unlock is omitted, resources leaks will occur. +** +** If a disconnect is attempted while a virtual table is locked, +** the disconnect is deferred until all locks have been removed. +*/ +SQLITE_PRIVATE void sqlite3VtabLock(VTable *pVTab){ + pVTab->nRef++; +} + + +/* +** pTab is a pointer to a Table structure representing a virtual-table. +** Return a pointer to the VTable object used by connection db to access +** this virtual-table, if one has been created, or NULL otherwise. +*/ +SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3 *db, Table *pTab){ + VTable *pVtab; + assert( IsVirtual(pTab) ); + for(pVtab=pTab->u.vtab.p; pVtab && pVtab->db!=db; pVtab=pVtab->pNext); + return pVtab; +} + +/* +** Decrement the ref-count on a virtual table object. When the ref-count +** reaches zero, call the xDisconnect() method to delete the object. +*/ +SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *pVTab){ + sqlite3 *db = pVTab->db; + + assert( db ); + assert( pVTab->nRef>0 ); + assert( db->eOpenState==SQLITE_STATE_OPEN + || db->eOpenState==SQLITE_STATE_ZOMBIE ); + + pVTab->nRef--; + if( pVTab->nRef==0 ){ + sqlite3_vtab *p = pVTab->pVtab; + if( p ){ + p->pModule->xDisconnect(p); + } + sqlite3VtabModuleUnref(pVTab->db, pVTab->pMod); + sqlite3DbFree(db, pVTab); + } +} + +/* +** Table p is a virtual table. This function moves all elements in the +** p->u.vtab.p list to the sqlite3.pDisconnect lists of their associated +** database connections to be disconnected at the next opportunity. +** Except, if argument db is not NULL, then the entry associated with +** connection db is left in the p->u.vtab.p list. +*/ +static VTable *vtabDisconnectAll(sqlite3 *db, Table *p){ + VTable *pRet = 0; + VTable *pVTable; + + assert( IsVirtual(p) ); + pVTable = p->u.vtab.p; + p->u.vtab.p = 0; + + /* Assert that the mutex (if any) associated with the BtShared database + ** that contains table p is held by the caller. See header comments + ** above function sqlite3VtabUnlockList() for an explanation of why + ** this makes it safe to access the sqlite3.pDisconnect list of any + ** database connection that may have an entry in the p->u.vtab.p list. + */ + assert( db==0 || sqlite3SchemaMutexHeld(db, 0, p->pSchema) ); + + while( pVTable ){ + sqlite3 *db2 = pVTable->db; + VTable *pNext = pVTable->pNext; + assert( db2 ); + if( db2==db ){ + pRet = pVTable; + p->u.vtab.p = pRet; + pRet->pNext = 0; + }else{ + pVTable->pNext = db2->pDisconnect; + db2->pDisconnect = pVTable; + } + pVTable = pNext; + } + + assert( !db || pRet ); + return pRet; +} + +/* +** Table *p is a virtual table. This function removes the VTable object +** for table *p associated with database connection db from the linked +** list in p->pVTab. It also decrements the VTable ref count. This is +** used when closing database connection db to free all of its VTable +** objects without disturbing the rest of the Schema object (which may +** be being used by other shared-cache connections). +*/ +SQLITE_PRIVATE void sqlite3VtabDisconnect(sqlite3 *db, Table *p){ + VTable **ppVTab; + + assert( IsVirtual(p) ); + assert( sqlite3BtreeHoldsAllMutexes(db) ); + assert( sqlite3_mutex_held(db->mutex) ); + + for(ppVTab=&p->u.vtab.p; *ppVTab; ppVTab=&(*ppVTab)->pNext){ + if( (*ppVTab)->db==db ){ + VTable *pVTab = *ppVTab; + *ppVTab = pVTab->pNext; + sqlite3VtabUnlock(pVTab); + break; + } + } +} + + +/* +** Disconnect all the virtual table objects in the sqlite3.pDisconnect list. +** +** This function may only be called when the mutexes associated with all +** shared b-tree databases opened using connection db are held by the +** caller. This is done to protect the sqlite3.pDisconnect list. The +** sqlite3.pDisconnect list is accessed only as follows: +** +** 1) By this function. In this case, all BtShared mutexes and the mutex +** associated with the database handle itself must be held. +** +** 2) By function vtabDisconnectAll(), when it adds a VTable entry to +** the sqlite3.pDisconnect list. In this case either the BtShared mutex +** associated with the database the virtual table is stored in is held +** or, if the virtual table is stored in a non-sharable database, then +** the database handle mutex is held. +** +** As a result, a sqlite3.pDisconnect cannot be accessed simultaneously +** by multiple threads. It is thread-safe. +*/ +SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3 *db){ + VTable *p = db->pDisconnect; + + assert( sqlite3BtreeHoldsAllMutexes(db) ); + assert( sqlite3_mutex_held(db->mutex) ); + + if( p ){ + db->pDisconnect = 0; + do { + VTable *pNext = p->pNext; + sqlite3VtabUnlock(p); + p = pNext; + }while( p ); + } +} + +/* +** Clear any and all virtual-table information from the Table record. +** This routine is called, for example, just before deleting the Table +** record. +** +** Since it is a virtual-table, the Table structure contains a pointer +** to the head of a linked list of VTable structures. Each VTable +** structure is associated with a single sqlite3* user of the schema. +** The reference count of the VTable structure associated with database +** connection db is decremented immediately (which may lead to the +** structure being xDisconnected and free). Any other VTable structures +** in the list are moved to the sqlite3.pDisconnect list of the associated +** database connection. +*/ +SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table *p){ + assert( IsVirtual(p) ); + assert( db!=0 ); + if( db->pnBytesFreed==0 ) vtabDisconnectAll(0, p); + if( p->u.vtab.azArg ){ + int i; + for(i=0; iu.vtab.nArg; i++){ + if( i!=1 ) sqlite3DbFree(db, p->u.vtab.azArg[i]); + } + sqlite3DbFree(db, p->u.vtab.azArg); + } +} + +/* +** Add a new module argument to pTable->u.vtab.azArg[]. +** The string is not copied - the pointer is stored. The +** string will be freed automatically when the table is +** deleted. +*/ +static void addModuleArgument(Parse *pParse, Table *pTable, char *zArg){ + sqlite3_int64 nBytes; + char **azModuleArg; + sqlite3 *db = pParse->db; + + assert( IsVirtual(pTable) ); + nBytes = sizeof(char *)*(2+pTable->u.vtab.nArg); + if( pTable->u.vtab.nArg+3>=db->aLimit[SQLITE_LIMIT_COLUMN] ){ + sqlite3ErrorMsg(pParse, "too many columns on %s", pTable->zName); + } + azModuleArg = sqlite3DbRealloc(db, pTable->u.vtab.azArg, nBytes); + if( azModuleArg==0 ){ + sqlite3DbFree(db, zArg); + }else{ + int i = pTable->u.vtab.nArg++; + azModuleArg[i] = zArg; + azModuleArg[i+1] = 0; + pTable->u.vtab.azArg = azModuleArg; + } +} + +/* +** The parser calls this routine when it first sees a CREATE VIRTUAL TABLE +** statement. The module name has been parsed, but the optional list +** of parameters that follow the module name are still pending. +*/ +SQLITE_PRIVATE void sqlite3VtabBeginParse( + Parse *pParse, /* Parsing context */ + Token *pName1, /* Name of new table, or database name */ + Token *pName2, /* Name of new table or NULL */ + Token *pModuleName, /* Name of the module for the virtual table */ + int ifNotExists /* No error if the table already exists */ +){ + Table *pTable; /* The new virtual table */ + sqlite3 *db; /* Database connection */ + + sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, ifNotExists); + pTable = pParse->pNewTable; + if( pTable==0 ) return; + assert( 0==pTable->pIndex ); + pTable->eTabType = TABTYP_VTAB; + + db = pParse->db; + + assert( pTable->u.vtab.nArg==0 ); + addModuleArgument(pParse, pTable, sqlite3NameFromToken(db, pModuleName)); + addModuleArgument(pParse, pTable, 0); + addModuleArgument(pParse, pTable, sqlite3DbStrDup(db, pTable->zName)); + assert( (pParse->sNameToken.z==pName2->z && pName2->z!=0) + || (pParse->sNameToken.z==pName1->z && pName2->z==0) + ); + pParse->sNameToken.n = (int)( + &pModuleName->z[pModuleName->n] - pParse->sNameToken.z + ); + +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Creating a virtual table invokes the authorization callback twice. + ** The first invocation, to obtain permission to INSERT a row into the + ** sqlite_schema table, has already been made by sqlite3StartTable(). + ** The second call, to obtain permission to create the table, is made now. + */ + if( pTable->u.vtab.azArg ){ + int iDb = sqlite3SchemaToIndex(db, pTable->pSchema); + assert( iDb>=0 ); /* The database the table is being created in */ + sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName, + pTable->u.vtab.azArg[0], pParse->db->aDb[iDb].zDbSName); + } +#endif +} + +/* +** This routine takes the module argument that has been accumulating +** in pParse->zArg[] and appends it to the list of arguments on the +** virtual table currently under construction in pParse->pTable. +*/ +static void addArgumentToVtab(Parse *pParse){ + if( pParse->sArg.z && pParse->pNewTable ){ + const char *z = (const char*)pParse->sArg.z; + int n = pParse->sArg.n; + sqlite3 *db = pParse->db; + addModuleArgument(pParse, pParse->pNewTable, sqlite3DbStrNDup(db, z, n)); + } +} + +/* +** The parser calls this routine after the CREATE VIRTUAL TABLE statement +** has been completely parsed. +*/ +SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ + Table *pTab = pParse->pNewTable; /* The table being constructed */ + sqlite3 *db = pParse->db; /* The database connection */ + + if( pTab==0 ) return; + assert( IsVirtual(pTab) ); + addArgumentToVtab(pParse); + pParse->sArg.z = 0; + if( pTab->u.vtab.nArg<1 ) return; + + /* If the CREATE VIRTUAL TABLE statement is being entered for the + ** first time (in other words if the virtual table is actually being + ** created now instead of just being read out of sqlite_schema) then + ** do additional initialization work and store the statement text + ** in the sqlite_schema table. + */ + if( !db->init.busy ){ + char *zStmt; + char *zWhere; + int iDb; + int iReg; + Vdbe *v; + + sqlite3MayAbort(pParse); + + /* Compute the complete text of the CREATE VIRTUAL TABLE statement */ + if( pEnd ){ + pParse->sNameToken.n = (int)(pEnd->z - pParse->sNameToken.z) + pEnd->n; + } + zStmt = sqlite3MPrintf(db, "CREATE VIRTUAL TABLE %T", &pParse->sNameToken); + + /* A slot for the record has already been allocated in the + ** schema table. We just need to update that slot with all + ** the information we've collected. + ** + ** The VM register number pParse->u1.cr.regRowid holds the rowid of an + ** entry in the sqlite_schema table that was created for this vtab + ** by sqlite3StartTable(). + */ + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( pParse->isCreate ); + sqlite3NestedParse(pParse, + "UPDATE %Q." LEGACY_SCHEMA_TABLE " " + "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q " + "WHERE rowid=#%d", + db->aDb[iDb].zDbSName, + pTab->zName, + pTab->zName, + zStmt, + pParse->u1.cr.regRowid + ); + v = sqlite3GetVdbe(pParse); + sqlite3ChangeCookie(pParse, iDb); + + sqlite3VdbeAddOp0(v, OP_Expire); + zWhere = sqlite3MPrintf(db, "name=%Q AND sql=%Q", pTab->zName, zStmt); + sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere, 0); + sqlite3DbFree(db, zStmt); + + iReg = ++pParse->nMem; + sqlite3VdbeLoadString(v, iReg, pTab->zName); + sqlite3VdbeAddOp2(v, OP_VCreate, iDb, iReg); + }else{ + /* If we are rereading the sqlite_schema table create the in-memory + ** record of the table. */ + Table *pOld; + Schema *pSchema = pTab->pSchema; + const char *zName = pTab->zName; + assert( zName!=0 ); + sqlite3MarkAllShadowTablesOf(db, pTab); + pOld = sqlite3HashInsert(&pSchema->tblHash, zName, pTab); + if( pOld ){ + sqlite3OomFault(db); + assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */ + return; + } + pParse->pNewTable = 0; + } +} + +/* +** The parser calls this routine when it sees the first token +** of an argument to the module name in a CREATE VIRTUAL TABLE statement. +*/ +SQLITE_PRIVATE void sqlite3VtabArgInit(Parse *pParse){ + addArgumentToVtab(pParse); + pParse->sArg.z = 0; + pParse->sArg.n = 0; +} + +/* +** The parser calls this routine for each token after the first token +** in an argument to the module name in a CREATE VIRTUAL TABLE statement. +*/ +SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse *pParse, Token *p){ + Token *pArg = &pParse->sArg; + if( pArg->z==0 ){ + pArg->z = p->z; + pArg->n = p->n; + }else{ + assert(pArg->z <= p->z); + pArg->n = (int)(&p->z[p->n] - pArg->z); + } +} + +/* +** Invoke a virtual table constructor (either xCreate or xConnect). The +** pointer to the function to invoke is passed as the fourth parameter +** to this procedure. +*/ +static int vtabCallConstructor( + sqlite3 *db, + Table *pTab, + Module *pMod, + int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**), + char **pzErr +){ + VtabCtx sCtx; + VTable *pVTable; + int rc; + const char *const*azArg; + int nArg = pTab->u.vtab.nArg; + char *zErr = 0; + char *zModuleName; + int iDb; + VtabCtx *pCtx; + + assert( IsVirtual(pTab) ); + azArg = (const char *const*)pTab->u.vtab.azArg; + + /* Check that the virtual-table is not already being initialized */ + for(pCtx=db->pVtabCtx; pCtx; pCtx=pCtx->pPrior){ + if( pCtx->pTab==pTab ){ + *pzErr = sqlite3MPrintf(db, + "vtable constructor called recursively: %s", pTab->zName + ); + return SQLITE_LOCKED; + } + } + + zModuleName = sqlite3DbStrDup(db, pTab->zName); + if( !zModuleName ){ + return SQLITE_NOMEM_BKPT; + } + + pVTable = sqlite3MallocZero(sizeof(VTable)); + if( !pVTable ){ + sqlite3OomFault(db); + sqlite3DbFree(db, zModuleName); + return SQLITE_NOMEM_BKPT; + } + pVTable->db = db; + pVTable->pMod = pMod; + pVTable->eVtabRisk = SQLITE_VTABRISK_Normal; + + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + pTab->u.vtab.azArg[1] = db->aDb[iDb].zDbSName; + + /* Invoke the virtual table constructor */ + assert( &db->pVtabCtx ); + assert( xConstruct ); + sCtx.pTab = pTab; + sCtx.pVTable = pVTable; + sCtx.pPrior = db->pVtabCtx; + sCtx.bDeclared = 0; + db->pVtabCtx = &sCtx; + pTab->nTabRef++; + rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); + assert( pTab!=0 ); + assert( pTab->nTabRef>1 || rc!=SQLITE_OK ); + sqlite3DeleteTable(db, pTab); + db->pVtabCtx = sCtx.pPrior; + if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); + assert( sCtx.pTab==pTab ); + + if( SQLITE_OK!=rc ){ + if( zErr==0 ){ + *pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName); + }else { + *pzErr = sqlite3MPrintf(db, "%s", zErr); + sqlite3_free(zErr); + } + sqlite3DbFree(db, pVTable); + }else if( ALWAYS(pVTable->pVtab) ){ + /* Justification of ALWAYS(): A correct vtab constructor must allocate + ** the sqlite3_vtab object if successful. */ + memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0])); + pVTable->pVtab->pModule = pMod->pModule; + pMod->nRefModule++; + pVTable->nRef = 1; + if( sCtx.bDeclared==0 ){ + const char *zFormat = "vtable constructor did not declare schema: %s"; + *pzErr = sqlite3MPrintf(db, zFormat, zModuleName); + sqlite3VtabUnlock(pVTable); + rc = SQLITE_ERROR; + }else{ + int iCol; + u16 oooHidden = 0; + /* If everything went according to plan, link the new VTable structure + ** into the linked list headed by pTab->u.vtab.p. Then loop through the + ** columns of the table to see if any of them contain the token "hidden". + ** If so, set the Column COLFLAG_HIDDEN flag and remove the token from + ** the type string. */ + pVTable->pNext = pTab->u.vtab.p; + pTab->u.vtab.p = pVTable; + + for(iCol=0; iColnCol; iCol++){ + char *zType = sqlite3ColumnType(&pTab->aCol[iCol], ""); + int nType; + int i = 0; + nType = sqlite3Strlen30(zType); + for(i=0; i0 ){ + assert(zType[i-1]==' '); + zType[i-1] = '\0'; + } + pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN; + pTab->tabFlags |= TF_HasHidden; + oooHidden = TF_OOOHidden; + }else{ + pTab->tabFlags |= oooHidden; + } + } + } + } + + sqlite3DbFree(db, zModuleName); + return rc; +} + +/* +** This function is invoked by the parser to call the xConnect() method +** of the virtual table pTab. If an error occurs, an error code is returned +** and an error left in pParse. +** +** This call is a no-op if table pTab is not a virtual table. +*/ +SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){ + sqlite3 *db = pParse->db; + const char *zMod; + Module *pMod; + int rc; + + assert( pTab ); + assert( IsVirtual(pTab) ); + if( sqlite3GetVTable(db, pTab) ){ + return SQLITE_OK; + } + + /* Locate the required virtual table module */ + zMod = pTab->u.vtab.azArg[0]; + pMod = (Module*)sqlite3HashFind(&db->aModule, zMod); + + if( !pMod ){ + const char *zModule = pTab->u.vtab.azArg[0]; + sqlite3ErrorMsg(pParse, "no such module: %s", zModule); + rc = SQLITE_ERROR; + }else{ + char *zErr = 0; + rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xConnect, &zErr); + if( rc!=SQLITE_OK ){ + sqlite3ErrorMsg(pParse, "%s", zErr); + pParse->rc = rc; + } + sqlite3DbFree(db, zErr); + } + + return rc; +} +/* +** Grow the db->aVTrans[] array so that there is room for at least one +** more v-table. Return SQLITE_NOMEM if a malloc fails, or SQLITE_OK otherwise. +*/ +static int growVTrans(sqlite3 *db){ + const int ARRAY_INCR = 5; + + /* Grow the sqlite3.aVTrans array if required */ + if( (db->nVTrans%ARRAY_INCR)==0 ){ + VTable **aVTrans; + sqlite3_int64 nBytes = sizeof(sqlite3_vtab*)* + ((sqlite3_int64)db->nVTrans + ARRAY_INCR); + aVTrans = sqlite3DbRealloc(db, (void *)db->aVTrans, nBytes); + if( !aVTrans ){ + return SQLITE_NOMEM_BKPT; + } + memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR); + db->aVTrans = aVTrans; + } + + return SQLITE_OK; +} + +/* +** Add the virtual table pVTab to the array sqlite3.aVTrans[]. Space should +** have already been reserved using growVTrans(). +*/ +static void addToVTrans(sqlite3 *db, VTable *pVTab){ + /* Add pVtab to the end of sqlite3.aVTrans */ + db->aVTrans[db->nVTrans++] = pVTab; + sqlite3VtabLock(pVTab); +} + +/* +** This function is invoked by the vdbe to call the xCreate method +** of the virtual table named zTab in database iDb. +** +** If an error occurs, *pzErr is set to point to an English language +** description of the error and an SQLITE_XXX error code is returned. +** In this case the caller must call sqlite3DbFree(db, ) on *pzErr. +*/ +SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){ + int rc = SQLITE_OK; + Table *pTab; + Module *pMod; + const char *zMod; + + pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName); + assert( pTab && IsVirtual(pTab) && !pTab->u.vtab.p ); + + /* Locate the required virtual table module */ + zMod = pTab->u.vtab.azArg[0]; + pMod = (Module*)sqlite3HashFind(&db->aModule, zMod); + + /* If the module has been registered and includes a Create method, + ** invoke it now. If the module has not been registered, return an + ** error. Otherwise, do nothing. + */ + if( pMod==0 || pMod->pModule->xCreate==0 || pMod->pModule->xDestroy==0 ){ + *pzErr = sqlite3MPrintf(db, "no such module: %s", zMod); + rc = SQLITE_ERROR; + }else{ + rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xCreate, pzErr); + } + + /* Justification of ALWAYS(): The xConstructor method is required to + ** create a valid sqlite3_vtab if it returns SQLITE_OK. */ + if( rc==SQLITE_OK && ALWAYS(sqlite3GetVTable(db, pTab)) ){ + rc = growVTrans(db); + if( rc==SQLITE_OK ){ + addToVTrans(db, sqlite3GetVTable(db, pTab)); + } + } + + return rc; +} + +/* +** This function is used to set the schema of a virtual table. It is only +** valid to call this function from within the xCreate() or xConnect() of a +** virtual table module. +*/ +SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ + VtabCtx *pCtx; + int rc = SQLITE_OK; + Table *pTab; + Parse sParse; + int initBusy; + int i; + const unsigned char *z; + static const u8 aKeyword[] = { TK_CREATE, TK_TABLE, 0 }; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zCreateTable==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + + /* Verify that the first two keywords in the CREATE TABLE statement + ** really are "CREATE" and "TABLE". If this is not the case, then + ** sqlite3_declare_vtab() is being misused. + */ + z = (const unsigned char*)zCreateTable; + for(i=0; aKeyword[i]; i++){ + int tokenType = 0; + do{ + z += sqlite3GetToken(z, &tokenType); + }while( tokenType==TK_SPACE || tokenType==TK_COMMENT ); + if( tokenType!=aKeyword[i] ){ + sqlite3ErrorWithMsg(db, SQLITE_ERROR, "syntax error"); + return SQLITE_ERROR; + } + } + + sqlite3_mutex_enter(db->mutex); + pCtx = db->pVtabCtx; + if( !pCtx || pCtx->bDeclared ){ + sqlite3Error(db, SQLITE_MISUSE_BKPT); + sqlite3_mutex_leave(db->mutex); + return SQLITE_MISUSE_BKPT; + } + + pTab = pCtx->pTab; + assert( IsVirtual(pTab) ); + + sqlite3ParseObjectInit(&sParse, db); + sParse.eParseMode = PARSE_MODE_DECLARE_VTAB; + sParse.disableTriggers = 1; + /* We should never be able to reach this point while loading the + ** schema. Nevertheless, defend against that (turn off db->init.busy) + ** in case a bug arises. */ + assert( db->init.busy==0 ); + initBusy = db->init.busy; + db->init.busy = 0; + sParse.nQueryLoop = 1; + if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable) ){ + assert( sParse.pNewTable!=0 ); + assert( !db->mallocFailed ); + assert( IsOrdinaryTable(sParse.pNewTable) ); + assert( sParse.zErrMsg==0 ); + if( !pTab->aCol ){ + Table *pNew = sParse.pNewTable; + Index *pIdx; + pTab->aCol = pNew->aCol; + assert( IsOrdinaryTable(pNew) ); + sqlite3ExprListDelete(db, pNew->u.tab.pDfltList); + pTab->nNVCol = pTab->nCol = pNew->nCol; + pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid); + pNew->nCol = 0; + pNew->aCol = 0; + assert( pTab->pIndex==0 ); + assert( HasRowid(pNew) || sqlite3PrimaryKeyIndex(pNew)!=0 ); + if( !HasRowid(pNew) + && pCtx->pVTable->pMod->pModule->xUpdate!=0 + && sqlite3PrimaryKeyIndex(pNew)->nKeyCol!=1 + ){ + /* WITHOUT ROWID virtual tables must either be read-only (xUpdate==0) + ** or else must have a single-column PRIMARY KEY */ + rc = SQLITE_ERROR; + } + pIdx = pNew->pIndex; + if( pIdx ){ + assert( pIdx->pNext==0 ); + pTab->pIndex = pIdx; + pNew->pIndex = 0; + pIdx->pTable = pTab; + } + } + pCtx->bDeclared = 1; + }else{ + sqlite3ErrorWithMsg(db, SQLITE_ERROR, + (sParse.zErrMsg ? "%s" : 0), sParse.zErrMsg); + sqlite3DbFree(db, sParse.zErrMsg); + rc = SQLITE_ERROR; + } + sParse.eParseMode = PARSE_MODE_NORMAL; + + if( sParse.pVdbe ){ + sqlite3VdbeFinalize(sParse.pVdbe); + } + sqlite3DeleteTable(db, sParse.pNewTable); + sqlite3ParseObjectReset(&sParse); + db->init.busy = initBusy; + + assert( (rc&0xff)==rc ); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** This function is invoked by the vdbe to call the xDestroy method +** of the virtual table named zTab in database iDb. This occurs +** when a DROP TABLE is mentioned. +** +** This call is a no-op if zTab is not a virtual table. +*/ +SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){ + int rc = SQLITE_OK; + Table *pTab; + + pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName); + if( ALWAYS(pTab!=0) + && ALWAYS(IsVirtual(pTab)) + && ALWAYS(pTab->u.vtab.p!=0) + ){ + VTable *p; + int (*xDestroy)(sqlite3_vtab *); + for(p=pTab->u.vtab.p; p; p=p->pNext){ + assert( p->pVtab ); + if( p->pVtab->nRef>0 ){ + return SQLITE_LOCKED; + } + } + p = vtabDisconnectAll(db, pTab); + xDestroy = p->pMod->pModule->xDestroy; + if( xDestroy==0 ) xDestroy = p->pMod->pModule->xDisconnect; + assert( xDestroy!=0 ); + pTab->nTabRef++; + rc = xDestroy(p->pVtab); + /* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */ + if( rc==SQLITE_OK ){ + assert( pTab->u.vtab.p==p && p->pNext==0 ); + p->pVtab = 0; + pTab->u.vtab.p = 0; + sqlite3VtabUnlock(p); + } + sqlite3DeleteTable(db, pTab); + } + + return rc; +} + +/* +** This function invokes either the xRollback or xCommit method +** of each of the virtual tables in the sqlite3.aVTrans array. The method +** called is identified by the second argument, "offset", which is +** the offset of the method to call in the sqlite3_module structure. +** +** The array is cleared after invoking the callbacks. +*/ +static void callFinaliser(sqlite3 *db, int offset){ + int i; + if( db->aVTrans ){ + VTable **aVTrans = db->aVTrans; + db->aVTrans = 0; + for(i=0; inVTrans; i++){ + VTable *pVTab = aVTrans[i]; + sqlite3_vtab *p = pVTab->pVtab; + if( p ){ + int (*x)(sqlite3_vtab *); + x = *(int (**)(sqlite3_vtab *))((char *)p->pModule + offset); + if( x ) x(p); + } + pVTab->iSavepoint = 0; + sqlite3VtabUnlock(pVTab); + } + sqlite3DbFree(db, aVTrans); + db->nVTrans = 0; + } +} + +/* +** Invoke the xSync method of all virtual tables in the sqlite3.aVTrans +** array. Return the error code for the first error that occurs, or +** SQLITE_OK if all xSync operations are successful. +** +** If an error message is available, leave it in p->zErrMsg. +*/ +SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, Vdbe *p){ + int i; + int rc = SQLITE_OK; + VTable **aVTrans = db->aVTrans; + + db->aVTrans = 0; + for(i=0; rc==SQLITE_OK && inVTrans; i++){ + int (*x)(sqlite3_vtab *); + sqlite3_vtab *pVtab = aVTrans[i]->pVtab; + if( pVtab && (x = pVtab->pModule->xSync)!=0 ){ + rc = x(pVtab); + sqlite3VtabImportErrmsg(p, pVtab); + } + } + db->aVTrans = aVTrans; + return rc; +} + +/* +** Invoke the xRollback method of all virtual tables in the +** sqlite3.aVTrans array. Then clear the array itself. +*/ +SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db){ + callFinaliser(db, offsetof(sqlite3_module,xRollback)); + return SQLITE_OK; +} + +/* +** Invoke the xCommit method of all virtual tables in the +** sqlite3.aVTrans array. Then clear the array itself. +*/ +SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db){ + callFinaliser(db, offsetof(sqlite3_module,xCommit)); + return SQLITE_OK; +} + +/* +** If the virtual table pVtab supports the transaction interface +** (xBegin/xRollback/xCommit and optionally xSync) and a transaction is +** not currently open, invoke the xBegin method now. +** +** If the xBegin call is successful, place the sqlite3_vtab pointer +** in the sqlite3.aVTrans array. +*/ +SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *db, VTable *pVTab){ + int rc = SQLITE_OK; + const sqlite3_module *pModule; + + /* Special case: If db->aVTrans is NULL and db->nVTrans is greater + ** than zero, then this function is being called from within a + ** virtual module xSync() callback. It is illegal to write to + ** virtual module tables in this case, so return SQLITE_LOCKED. + */ + if( sqlite3VtabInSync(db) ){ + return SQLITE_LOCKED; + } + if( !pVTab ){ + return SQLITE_OK; + } + pModule = pVTab->pVtab->pModule; + + if( pModule->xBegin ){ + int i; + + /* If pVtab is already in the aVTrans array, return early */ + for(i=0; inVTrans; i++){ + if( db->aVTrans[i]==pVTab ){ + return SQLITE_OK; + } + } + + /* Invoke the xBegin method. If successful, add the vtab to the + ** sqlite3.aVTrans[] array. */ + rc = growVTrans(db); + if( rc==SQLITE_OK ){ + rc = pModule->xBegin(pVTab->pVtab); + if( rc==SQLITE_OK ){ + int iSvpt = db->nStatement + db->nSavepoint; + addToVTrans(db, pVTab); + if( iSvpt && pModule->xSavepoint ){ + pVTab->iSavepoint = iSvpt; + rc = pModule->xSavepoint(pVTab->pVtab, iSvpt-1); + } + } + } + } + return rc; +} + +/* +** Invoke either the xSavepoint, xRollbackTo or xRelease method of all +** virtual tables that currently have an open transaction. Pass iSavepoint +** as the second argument to the virtual table method invoked. +** +** If op is SAVEPOINT_BEGIN, the xSavepoint method is invoked. If it is +** SAVEPOINT_ROLLBACK, the xRollbackTo method. Otherwise, if op is +** SAVEPOINT_RELEASE, then the xRelease method of each virtual table with +** an open transaction is invoked. +** +** If any virtual table method returns an error code other than SQLITE_OK, +** processing is abandoned and the error returned to the caller of this +** function immediately. If all calls to virtual table methods are successful, +** SQLITE_OK is returned. +*/ +SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){ + int rc = SQLITE_OK; + + assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN ); + assert( iSavepoint>=-1 ); + if( db->aVTrans ){ + int i; + for(i=0; rc==SQLITE_OK && inVTrans; i++){ + VTable *pVTab = db->aVTrans[i]; + const sqlite3_module *pMod = pVTab->pMod->pModule; + if( pVTab->pVtab && pMod->iVersion>=2 ){ + int (*xMethod)(sqlite3_vtab *, int); + sqlite3VtabLock(pVTab); + switch( op ){ + case SAVEPOINT_BEGIN: + xMethod = pMod->xSavepoint; + pVTab->iSavepoint = iSavepoint+1; + break; + case SAVEPOINT_ROLLBACK: + xMethod = pMod->xRollbackTo; + break; + default: + xMethod = pMod->xRelease; + break; + } + if( xMethod && pVTab->iSavepoint>iSavepoint ){ + u64 savedFlags = (db->flags & SQLITE_Defensive); + db->flags &= ~(u64)SQLITE_Defensive; + rc = xMethod(pVTab->pVtab, iSavepoint); + db->flags |= savedFlags; + } + sqlite3VtabUnlock(pVTab); + } + } + } + return rc; +} + +/* +** The first parameter (pDef) is a function implementation. The +** second parameter (pExpr) is the first argument to this function. +** If pExpr is a column in a virtual table, then let the virtual +** table implementation have an opportunity to overload the function. +** +** This routine is used to allow virtual table implementations to +** overload MATCH, LIKE, GLOB, and REGEXP operators. +** +** Return either the pDef argument (indicating no change) or a +** new FuncDef structure that is marked as ephemeral using the +** SQLITE_FUNC_EPHEM flag. +*/ +SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction( + sqlite3 *db, /* Database connection for reporting malloc problems */ + FuncDef *pDef, /* Function to possibly overload */ + int nArg, /* Number of arguments to the function */ + Expr *pExpr /* First argument to the function */ +){ + Table *pTab; + sqlite3_vtab *pVtab; + sqlite3_module *pMod; + void (*xSFunc)(sqlite3_context*,int,sqlite3_value**) = 0; + void *pArg = 0; + FuncDef *pNew; + int rc = 0; + + /* Check to see the left operand is a column in a virtual table */ + if( NEVER(pExpr==0) ) return pDef; + if( pExpr->op!=TK_COLUMN ) return pDef; + assert( ExprUseYTab(pExpr) ); + pTab = pExpr->y.pTab; + if( NEVER(pTab==0) ) return pDef; + if( !IsVirtual(pTab) ) return pDef; + pVtab = sqlite3GetVTable(db, pTab)->pVtab; + assert( pVtab!=0 ); + assert( pVtab->pModule!=0 ); + pMod = (sqlite3_module *)pVtab->pModule; + if( pMod->xFindFunction==0 ) return pDef; + + /* Call the xFindFunction method on the virtual table implementation + ** to see if the implementation wants to overload this function. + ** + ** Though undocumented, we have historically always invoked xFindFunction + ** with an all lower-case function name. Continue in this tradition to + ** avoid any chance of an incompatibility. + */ +#ifdef SQLITE_DEBUG + { + int i; + for(i=0; pDef->zName[i]; i++){ + unsigned char x = (unsigned char)pDef->zName[i]; + assert( x==sqlite3UpperToLower[x] ); + } + } +#endif + rc = pMod->xFindFunction(pVtab, nArg, pDef->zName, &xSFunc, &pArg); + if( rc==0 ){ + return pDef; + } + + /* Create a new ephemeral function definition for the overloaded + ** function */ + pNew = sqlite3DbMallocZero(db, sizeof(*pNew) + + sqlite3Strlen30(pDef->zName) + 1); + if( pNew==0 ){ + return pDef; + } + *pNew = *pDef; + pNew->zName = (const char*)&pNew[1]; + memcpy((char*)&pNew[1], pDef->zName, sqlite3Strlen30(pDef->zName)+1); + pNew->xSFunc = xSFunc; + pNew->pUserData = pArg; + pNew->funcFlags |= SQLITE_FUNC_EPHEM; + return pNew; +} + +/* +** Make sure virtual table pTab is contained in the pParse->apVirtualLock[] +** array so that an OP_VBegin will get generated for it. Add pTab to the +** array if it is missing. If pTab is already in the array, this routine +** is a no-op. +*/ +SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + int i, n; + Table **apVtabLock; + + assert( IsVirtual(pTab) ); + for(i=0; inVtabLock; i++){ + if( pTab==pToplevel->apVtabLock[i] ) return; + } + n = (pToplevel->nVtabLock+1)*sizeof(pToplevel->apVtabLock[0]); + apVtabLock = sqlite3Realloc(pToplevel->apVtabLock, n); + if( apVtabLock ){ + pToplevel->apVtabLock = apVtabLock; + pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab; + }else{ + sqlite3OomFault(pToplevel->db); + } +} + +/* +** Check to see if virtual table module pMod can be have an eponymous +** virtual table instance. If it can, create one if one does not already +** exist. Return non-zero if either the eponymous virtual table instance +** exists when this routine returns or if an attempt to create it failed +** and an error message was left in pParse. +** +** An eponymous virtual table instance is one that is named after its +** module, and more importantly, does not require a CREATE VIRTUAL TABLE +** statement in order to come into existence. Eponymous virtual table +** instances always exist. They cannot be DROP-ed. +** +** Any virtual table module for which xConnect and xCreate are the same +** method can have an eponymous virtual table instance. +*/ +SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){ + const sqlite3_module *pModule = pMod->pModule; + Table *pTab; + char *zErr = 0; + int rc; + sqlite3 *db = pParse->db; + if( pMod->pEpoTab ) return 1; + if( pModule->xCreate!=0 && pModule->xCreate!=pModule->xConnect ) return 0; + pTab = sqlite3DbMallocZero(db, sizeof(Table)); + if( pTab==0 ) return 0; + pTab->zName = sqlite3DbStrDup(db, pMod->zName); + if( pTab->zName==0 ){ + sqlite3DbFree(db, pTab); + return 0; + } + pMod->pEpoTab = pTab; + pTab->nTabRef = 1; + pTab->eTabType = TABTYP_VTAB; + pTab->pSchema = db->aDb[0].pSchema; + assert( pTab->u.vtab.nArg==0 ); + pTab->iPKey = -1; + pTab->tabFlags |= TF_Eponymous; + addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName)); + addModuleArgument(pParse, pTab, 0); + addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName)); + db->nSchemaLock++; + rc = vtabCallConstructor(db, pTab, pMod, pModule->xConnect, &zErr); + db->nSchemaLock--; + if( rc ){ + sqlite3ErrorMsg(pParse, "%s", zErr); + pParse->rc = rc; + sqlite3DbFree(db, zErr); + sqlite3VtabEponymousTableClear(db, pMod); + } + return 1; +} + +/* +** Erase the eponymous virtual table instance associated with +** virtual table module pMod, if it exists. +*/ +SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3 *db, Module *pMod){ + Table *pTab = pMod->pEpoTab; + if( pTab!=0 ){ + /* Mark the table as Ephemeral prior to deleting it, so that the + ** sqlite3DeleteTable() routine will know that it is not stored in + ** the schema. */ + pTab->tabFlags |= TF_Ephemeral; + sqlite3DeleteTable(db, pTab); + pMod->pEpoTab = 0; + } +} + +/* +** Return the ON CONFLICT resolution mode in effect for the virtual +** table update operation currently in progress. +** +** The results of this routine are undefined unless it is called from +** within an xUpdate method. +*/ +SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *db){ + static const unsigned char aMap[] = { + SQLITE_ROLLBACK, SQLITE_ABORT, SQLITE_FAIL, SQLITE_IGNORE, SQLITE_REPLACE + }; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + assert( OE_Rollback==1 && OE_Abort==2 && OE_Fail==3 ); + assert( OE_Ignore==4 && OE_Replace==5 ); + assert( db->vtabOnConflict>=1 && db->vtabOnConflict<=5 ); + return (int)aMap[db->vtabOnConflict-1]; +} + +/* +** Call from within the xCreate() or xConnect() methods to provide +** the SQLite core with additional information about the behavior +** of the virtual table being implemented. +*/ +SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){ + va_list ap; + int rc = SQLITE_OK; + VtabCtx *p; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + p = db->pVtabCtx; + if( !p ){ + rc = SQLITE_MISUSE_BKPT; + }else{ + assert( p->pTab==0 || IsVirtual(p->pTab) ); + va_start(ap, op); + switch( op ){ + case SQLITE_VTAB_CONSTRAINT_SUPPORT: { + p->pVTable->bConstraint = (u8)va_arg(ap, int); + break; + } + case SQLITE_VTAB_INNOCUOUS: { + p->pVTable->eVtabRisk = SQLITE_VTABRISK_Low; + break; + } + case SQLITE_VTAB_DIRECTONLY: { + p->pVTable->eVtabRisk = SQLITE_VTABRISK_High; + break; + } + case SQLITE_VTAB_USES_ALL_SCHEMAS: { + p->pVTable->bAllSchemas = 1; + break; + } + default: { + rc = SQLITE_MISUSE_BKPT; + break; + } + } + va_end(ap); + } + + if( rc!=SQLITE_OK ) sqlite3Error(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +/************** End of vtab.c ************************************************/ +/************** Begin file wherecode.c ***************************************/ +/* +** 2015-06-06 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This module contains C code that generates VDBE code used to process +** the WHERE clause of SQL statements. +** +** This file was split off from where.c on 2015-06-06 in order to reduce the +** size of where.c and make it easier to edit. This file contains the routines +** that actually generate the bulk of the WHERE loop code. The original where.c +** file retains the code that does query planning and analysis. +*/ +/* #include "sqliteInt.h" */ +/************** Include whereInt.h in the middle of wherecode.c **************/ +/************** Begin file whereInt.h ****************************************/ +/* +** 2013-11-12 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains structure and macro definitions for the query +** planner logic in "where.c". These definitions are broken out into +** a separate source file for easier editing. +*/ +#ifndef SQLITE_WHEREINT_H +#define SQLITE_WHEREINT_H + + +/* Forward references +*/ +typedef struct WhereClause WhereClause; +typedef struct WhereMaskSet WhereMaskSet; +typedef struct WhereOrInfo WhereOrInfo; +typedef struct WhereAndInfo WhereAndInfo; +typedef struct WhereLevel WhereLevel; +typedef struct WhereLoop WhereLoop; +typedef struct WherePath WherePath; +typedef struct WhereTerm WhereTerm; +typedef struct WhereLoopBuilder WhereLoopBuilder; +typedef struct WhereScan WhereScan; +typedef struct WhereOrCost WhereOrCost; +typedef struct WhereOrSet WhereOrSet; +typedef struct WhereMemBlock WhereMemBlock; +typedef struct WhereRightJoin WhereRightJoin; + +/* +** This object is a header on a block of allocated memory that will be +** automatically freed when its WInfo object is destructed. +*/ +struct WhereMemBlock { + WhereMemBlock *pNext; /* Next block in the chain */ + u64 sz; /* Bytes of space */ +}; + +/* +** Extra information attached to a WhereLevel that is a RIGHT JOIN. +*/ +struct WhereRightJoin { + int iMatch; /* Cursor used to determine prior matched rows */ + int regBloom; /* Bloom filter for iRJMatch */ + int regReturn; /* Return register for the interior subroutine */ + int addrSubrtn; /* Starting address for the interior subroutine */ + int endSubrtn; /* The last opcode in the interior subroutine */ +}; + +/* +** This object contains information needed to implement a single nested +** loop in WHERE clause. +** +** Contrast this object with WhereLoop. This object describes the +** implementation of the loop. WhereLoop describes the algorithm. +** This object contains a pointer to the WhereLoop algorithm as one of +** its elements. +** +** The WhereInfo object contains a single instance of this object for +** each term in the FROM clause (which is to say, for each of the +** nested loops as implemented). The order of WhereLevel objects determines +** the loop nested order, with WhereInfo.a[0] being the outer loop and +** WhereInfo.a[WhereInfo.nLevel-1] being the inner loop. +*/ +struct WhereLevel { + int iLeftJoin; /* Memory cell used to implement LEFT OUTER JOIN */ + int iTabCur; /* The VDBE cursor used to access the table */ + int iIdxCur; /* The VDBE cursor used to access pIdx */ + int addrBrk; /* Jump here to break out of the loop */ + int addrHalt; /* Abort the query due to empty table or similar */ + int addrNxt; /* Jump here to start the next IN combination */ + int addrSkip; /* Jump here for next iteration of skip-scan */ + int addrCont; /* Jump here to continue with the next loop cycle */ + int addrFirst; /* First instruction of interior of the loop */ + int addrBody; /* Beginning of the body of this loop */ + int regBignull; /* big-null flag reg. True if a NULL-scan is needed */ + int addrBignull; /* Jump here for next part of big-null scan */ +#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS + u32 iLikeRepCntr; /* LIKE range processing counter register (times 2) */ + int addrLikeRep; /* LIKE range processing address */ +#endif + int regFilter; /* Bloom filter */ + WhereRightJoin *pRJ; /* Extra information for RIGHT JOIN */ + u8 iFrom; /* Which entry in the FROM clause */ + u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */ + int p1, p2; /* Operands of the opcode used to end the loop */ + union { /* Information that depends on pWLoop->wsFlags */ + struct { + int nIn; /* Number of entries in aInLoop[] */ + struct InLoop { + int iCur; /* The VDBE cursor used by this IN operator */ + int addrInTop; /* Top of the IN loop */ + int iBase; /* Base register of multi-key index record */ + int nPrefix; /* Number of prior entries in the key */ + u8 eEndLoopOp; /* IN Loop terminator. OP_Next or OP_Prev */ + } *aInLoop; /* Information about each nested IN operator */ + } in; /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */ + Index *pCoveringIdx; /* Possible covering index for WHERE_MULTI_OR */ + } u; + struct WhereLoop *pWLoop; /* The selected WhereLoop object */ + Bitmask notReady; /* FROM entries not usable at this level */ +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + int addrVisit; /* Address at which row is visited */ +#endif +}; + +/* +** Each instance of this object represents an algorithm for evaluating one +** term of a join. Every term of the FROM clause will have at least +** one corresponding WhereLoop object (unless INDEXED BY constraints +** prevent a query solution - which is an error) and many terms of the +** FROM clause will have multiple WhereLoop objects, each describing a +** potential way of implementing that FROM-clause term, together with +** dependencies and cost estimates for using the chosen algorithm. +** +** Query planning consists of building up a collection of these WhereLoop +** objects, then computing a particular sequence of WhereLoop objects, with +** one WhereLoop object per FROM clause term, that satisfy all dependencies +** and that minimize the overall cost. +*/ +struct WhereLoop { + Bitmask prereq; /* Bitmask of other loops that must run first */ + Bitmask maskSelf; /* Bitmask identifying table iTab */ +#ifdef SQLITE_DEBUG + char cId; /* Symbolic ID of this loop for debugging use */ +#endif + u8 iTab; /* Position in FROM clause of table for this loop */ + u8 iSortIdx; /* Sorting index number. 0==None */ + LogEst rSetup; /* One-time setup cost (ex: create transient index) */ + LogEst rRun; /* Cost of running each loop */ + LogEst nOut; /* Estimated number of output rows */ + union { + struct { /* Information for internal btree tables */ + u16 nEq; /* Number of equality constraints */ + u16 nBtm; /* Size of BTM vector */ + u16 nTop; /* Size of TOP vector */ + u16 nDistinctCol; /* Index columns used to sort for DISTINCT */ + Index *pIndex; /* Index used, or NULL */ + ExprList *pOrderBy; /* ORDER BY clause if this is really a subquery */ + } btree; + struct { /* Information for virtual tables */ + int idxNum; /* Index number */ + u32 needFree : 1; /* True if sqlite3_free(idxStr) is needed */ + u32 bOmitOffset : 1; /* True to let virtual table handle offset */ + u32 bIdxNumHex : 1; /* Show idxNum as hex in EXPLAIN QUERY PLAN */ + i8 isOrdered; /* True if satisfies ORDER BY */ + u16 omitMask; /* Terms that may be omitted */ + char *idxStr; /* Index identifier string */ + u32 mHandleIn; /* Terms to handle as IN(...) instead of == */ + } vtab; + } u; + u32 wsFlags; /* WHERE_* flags describing the plan */ + u16 nLTerm; /* Number of entries in aLTerm[] */ + u16 nSkip; /* Number of NULL aLTerm[] entries */ + /**** whereLoopXfer() copies fields above ***********************/ +# define WHERE_LOOP_XFER_SZ offsetof(WhereLoop,nLSlot) + u16 nLSlot; /* Number of slots allocated for aLTerm[] */ +#ifdef WHERETRACE_ENABLED + LogEst rStarDelta; /* Cost delta due to star-schema heuristic. Not + ** initialized unless pWInfo->bStarUsed */ +#endif + WhereTerm **aLTerm; /* WhereTerms used */ + WhereLoop *pNextLoop; /* Next WhereLoop object in the WhereClause */ + WhereTerm *aLTermSpace[3]; /* Initial aLTerm[] space */ +}; + +/* This object holds the prerequisites and the cost of running a +** subquery on one operand of an OR operator in the WHERE clause. +** See WhereOrSet for additional information +*/ +struct WhereOrCost { + Bitmask prereq; /* Prerequisites */ + LogEst rRun; /* Cost of running this subquery */ + LogEst nOut; /* Number of outputs for this subquery */ +}; + +/* The WhereOrSet object holds a set of possible WhereOrCosts that +** correspond to the subquery(s) of OR-clause processing. Only the +** best N_OR_COST elements are retained. +*/ +#define N_OR_COST 3 +struct WhereOrSet { + u16 n; /* Number of valid a[] entries */ + WhereOrCost a[N_OR_COST]; /* Set of best costs */ +}; + +/* +** Each instance of this object holds a sequence of WhereLoop objects +** that implement some or all of a query plan. +** +** Think of each WhereLoop object as a node in a graph with arcs +** showing dependencies and costs for travelling between nodes. (That is +** not a completely accurate description because WhereLoop costs are a +** vector, not a scalar, and because dependencies are many-to-one, not +** one-to-one as are graph nodes. But it is a useful visualization aid.) +** Then a WherePath object is a path through the graph that visits some +** or all of the WhereLoop objects once. +** +** The "solver" works by creating the N best WherePath objects of length +** 1. Then using those as a basis to compute the N best WherePath objects +** of length 2. And so forth until the length of WherePaths equals the +** number of nodes in the FROM clause. The best (lowest cost) WherePath +** at the end is the chosen query plan. +*/ +struct WherePath { + Bitmask maskLoop; /* Bitmask of all WhereLoop objects in this path */ + Bitmask revLoop; /* aLoop[]s that should be reversed for ORDER BY */ + LogEst nRow; /* Estimated number of rows generated by this path */ + LogEst rCost; /* Total cost of this path */ + LogEst rUnsort; /* Total cost of this path ignoring sorting costs */ + i8 isOrdered; /* No. of ORDER BY terms satisfied. -1 for unknown */ + WhereLoop **aLoop; /* Array of WhereLoop objects implementing this path */ +}; + +/* +** The query generator uses an array of instances of this structure to +** help it analyze the subexpressions of the WHERE clause. Each WHERE +** clause subexpression is separated from the others by AND operators, +** usually, or sometimes subexpressions separated by OR. +** +** All WhereTerms are collected into a single WhereClause structure. +** The following identity holds: +** +** WhereTerm.pWC->a[WhereTerm.idx] == WhereTerm +** +** When a term is of the form: +** +** X +** +** where X is a column name and is one of certain operators, +** then WhereTerm.leftCursor and WhereTerm.u.leftColumn record the +** cursor number and column number for X. WhereTerm.eOperator records +** the using a bitmask encoding defined by WO_xxx below. The +** use of a bitmask encoding for the operator allows us to search +** quickly for terms that match any of several different operators. +** +** A WhereTerm might also be two or more subterms connected by OR: +** +** (t1.X ) OR (t1.Y ) OR .... +** +** In this second case, wtFlag has the TERM_ORINFO bit set and eOperator==WO_OR +** and the WhereTerm.u.pOrInfo field points to auxiliary information that +** is collected about the OR clause. +** +** If a term in the WHERE clause does not match either of the two previous +** categories, then eOperator==0. The WhereTerm.pExpr field is still set +** to the original subexpression content and wtFlags is set up appropriately +** but no other fields in the WhereTerm object are meaningful. +** +** When eOperator!=0, prereqRight and prereqAll record sets of cursor numbers, +** but they do so indirectly. A single WhereMaskSet structure translates +** cursor number into bits and the translated bit is stored in the prereq +** fields. The translation is used in order to maximize the number of +** bits that will fit in a Bitmask. The VDBE cursor numbers might be +** spread out over the non-negative integers. For example, the cursor +** numbers might be 3, 8, 9, 10, 20, 23, 41, and 45. The WhereMaskSet +** translates these sparse cursor numbers into consecutive integers +** beginning with 0 in order to make the best possible use of the available +** bits in the Bitmask. So, in the example above, the cursor numbers +** would be mapped into integers 0 through 7. +** +** The number of terms in a join is limited by the number of bits +** in prereqRight and prereqAll. The default is 64 bits, hence SQLite +** is only able to process joins with 64 or fewer tables. +*/ +struct WhereTerm { + Expr *pExpr; /* Pointer to the subexpression that is this term */ + WhereClause *pWC; /* The clause this term is part of */ + LogEst truthProb; /* Probability of truth for this expression */ + u16 wtFlags; /* TERM_xxx bit flags. See below */ + u16 eOperator; /* A WO_xx value describing */ + u8 nChild; /* Number of children that must disable us */ + u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */ + int iParent; /* Disable pWC->a[iParent] when this term disabled */ + int leftCursor; /* Cursor number of X in "X " */ +#ifdef SQLITE_DEBUG + int iTerm; /* Which WhereTerm is this, for debug purposes */ +#endif + union { + struct { + int leftColumn; /* Column number of X in "X " */ + int iField; /* Field in (?,?,?) IN (SELECT...) vector */ + } x; /* Opcode other than OP_OR or OP_AND */ + WhereOrInfo *pOrInfo; /* Extra information if (eOperator & WO_OR)!=0 */ + WhereAndInfo *pAndInfo; /* Extra information if (eOperator& WO_AND)!=0 */ + } u; + Bitmask prereqRight; /* Bitmask of tables used by pExpr->pRight */ + Bitmask prereqAll; /* Bitmask of tables referenced by pExpr */ +}; + +/* +** Allowed values of WhereTerm.wtFlags +*/ +#define TERM_DYNAMIC 0x0001 /* Need to call sqlite3ExprDelete(db, pExpr) */ +#define TERM_VIRTUAL 0x0002 /* Added by the optimizer. Do not code */ +#define TERM_CODED 0x0004 /* This term is already coded */ +#define TERM_COPIED 0x0008 /* Has a child */ +#define TERM_ORINFO 0x0010 /* Need to free the WhereTerm.u.pOrInfo object */ +#define TERM_ANDINFO 0x0020 /* Need to free the WhereTerm.u.pAndInfo obj */ +#define TERM_OK 0x0040 /* Used during OR-clause processing */ +#define TERM_VNULL 0x0080 /* Manufactured x>NULL or x<=NULL term */ +#define TERM_LIKEOPT 0x0100 /* Virtual terms from the LIKE optimization */ +#define TERM_LIKECOND 0x0200 /* Conditionally this LIKE operator term */ +#define TERM_LIKE 0x0400 /* The original LIKE operator */ +#define TERM_IS 0x0800 /* Term.pExpr is an IS operator */ +#define TERM_VARSELECT 0x1000 /* Term.pExpr contains a correlated sub-query */ +#define TERM_HEURTRUTH 0x2000 /* Heuristic truthProb used */ +#ifdef SQLITE_ENABLE_STAT4 +# define TERM_HIGHTRUTH 0x4000 /* Term excludes few rows */ +#else +# define TERM_HIGHTRUTH 0 /* Only used with STAT4 */ +#endif +#define TERM_SLICE 0x8000 /* One slice of a row-value/vector comparison */ + +/* +** An instance of the WhereScan object is used as an iterator for locating +** terms in the WHERE clause that are useful to the query planner. +*/ +struct WhereScan { + WhereClause *pOrigWC; /* Original, innermost WhereClause */ + WhereClause *pWC; /* WhereClause currently being scanned */ + const char *zCollName; /* Required collating sequence, if not NULL */ + Expr *pIdxExpr; /* Search for this index expression */ + int k; /* Resume scanning at this->pWC->a[this->k] */ + u32 opMask; /* Acceptable operators */ + char idxaff; /* Must match this affinity, if zCollName!=NULL */ + unsigned char iEquiv; /* Current slot in aiCur[] and aiColumn[] */ + unsigned char nEquiv; /* Number of entries in aiCur[] and aiColumn[] */ + int aiCur[11]; /* Cursors in the equivalence class */ + i16 aiColumn[11]; /* Corresponding column number in the eq-class */ +}; + +/* +** An instance of the following structure holds all information about a +** WHERE clause. Mostly this is a container for one or more WhereTerms. +** +** Explanation of pOuter: For a WHERE clause of the form +** +** a AND ((b AND c) OR (d AND e)) AND f +** +** There are separate WhereClause objects for the whole clause and for +** the subclauses "(b AND c)" and "(d AND e)". The pOuter field of the +** subclauses points to the WhereClause object for the whole clause. +*/ +struct WhereClause { + WhereInfo *pWInfo; /* WHERE clause processing context */ + WhereClause *pOuter; /* Outer conjunction */ + u8 op; /* Split operator. TK_AND or TK_OR */ + u8 hasOr; /* True if any a[].eOperator is WO_OR */ + int nTerm; /* Number of terms */ + int nSlot; /* Number of entries in a[] */ + int nBase; /* Number of terms through the last non-Virtual */ + WhereTerm *a; /* Each a[] describes a term of the WHERE clause */ +#if defined(SQLITE_SMALL_STACK) + WhereTerm aStatic[1]; /* Initial static space for a[] */ +#else + WhereTerm aStatic[8]; /* Initial static space for a[] */ +#endif +}; + +/* +** A WhereTerm with eOperator==WO_OR has its u.pOrInfo pointer set to +** a dynamically allocated instance of the following structure. +*/ +struct WhereOrInfo { + WhereClause wc; /* Decomposition into subterms */ + Bitmask indexable; /* Bitmask of all indexable tables in the clause */ +}; + +/* +** A WhereTerm with eOperator==WO_AND has its u.pAndInfo pointer set to +** a dynamically allocated instance of the following structure. +*/ +struct WhereAndInfo { + WhereClause wc; /* The subexpression broken out */ +}; + +/* +** An instance of the following structure keeps track of a mapping +** between VDBE cursor numbers and bits of the bitmasks in WhereTerm. +** +** The VDBE cursor numbers are small integers contained in +** SrcItem.iCursor and Expr.iTable fields. For any given WHERE +** clause, the cursor numbers might not begin with 0 and they might +** contain gaps in the numbering sequence. But we want to make maximum +** use of the bits in our bitmasks. This structure provides a mapping +** from the sparse cursor numbers into consecutive integers beginning +** with 0. +** +** If WhereMaskSet.ix[A]==B it means that The A-th bit of a Bitmask +** corresponds VDBE cursor number B. The A-th bit of a bitmask is 1<3, 5->1, 8->2, 29->0, +** 57->5, 73->4. Or one of 719 other combinations might be used. It +** does not really matter. What is important is that sparse cursor +** numbers all get mapped into bit numbers that begin with 0 and contain +** no gaps. +*/ +struct WhereMaskSet { + int bVarSelect; /* Used by sqlite3WhereExprUsage() */ + int n; /* Number of assigned cursor values */ + int ix[BMS]; /* Cursor assigned to each bit */ +}; + +/* +** This object is a convenience wrapper holding all information needed +** to construct WhereLoop objects for a particular query. +*/ +struct WhereLoopBuilder { + WhereInfo *pWInfo; /* Information about this WHERE */ + WhereClause *pWC; /* WHERE clause terms */ + WhereLoop *pNew; /* Template WhereLoop */ + WhereOrSet *pOrSet; /* Record best loops here, if not NULL */ +#ifdef SQLITE_ENABLE_STAT4 + UnpackedRecord *pRec; /* Probe for stat4 (if required) */ + int nRecValid; /* Number of valid fields currently in pRec */ +#endif + unsigned char bldFlags1; /* First set of SQLITE_BLDF_* flags */ + unsigned char bldFlags2; /* Second set of SQLITE_BLDF_* flags */ + unsigned int iPlanLimit; /* Search limiter */ +}; + +/* Allowed values for WhereLoopBuider.bldFlags */ +#define SQLITE_BLDF1_INDEXED 0x0001 /* An index is used */ +#define SQLITE_BLDF1_UNIQUE 0x0002 /* All keys of a UNIQUE index used */ + +#define SQLITE_BLDF2_2NDPASS 0x0004 /* Second builder pass needed */ + +/* The WhereLoopBuilder.iPlanLimit is used to limit the number of +** index+constraint combinations the query planner will consider for a +** particular query. If this parameter is unlimited, then certain +** pathological queries can spend excess time in the sqlite3WhereBegin() +** routine. The limit is high enough that is should not impact real-world +** queries. +** +** SQLITE_QUERY_PLANNER_LIMIT is the baseline limit. The limit is +** increased by SQLITE_QUERY_PLANNER_LIMIT_INCR before each term of the FROM +** clause is processed, so that every table in a join is guaranteed to be +** able to propose a some index+constraint combinations even if the initial +** baseline limit was exhausted by prior tables of the join. +*/ +#ifndef SQLITE_QUERY_PLANNER_LIMIT +# define SQLITE_QUERY_PLANNER_LIMIT 20000 +#endif +#ifndef SQLITE_QUERY_PLANNER_LIMIT_INCR +# define SQLITE_QUERY_PLANNER_LIMIT_INCR 1000 +#endif + +/* +** The WHERE clause processing routine has two halves. The +** first part does the start of the WHERE loop and the second +** half does the tail of the WHERE loop. An instance of +** this structure is returned by the first half and passed +** into the second half to give some continuity. +** +** An instance of this object holds the complete state of the query +** planner. +*/ +struct WhereInfo { + Parse *pParse; /* Parsing and code generating context */ + SrcList *pTabList; /* List of tables in the join */ + ExprList *pOrderBy; /* The ORDER BY clause or NULL */ + ExprList *pResultSet; /* Result set of the query */ +#if WHERETRACE_ENABLED + Expr *pWhere; /* The complete WHERE clause */ +#endif + Select *pSelect; /* The entire SELECT statement containing WHERE */ + int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */ + int iContinue; /* Jump here to continue with next record */ + int iBreak; /* Jump here to break out of the loop */ + int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */ + u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */ + LogEst iLimit; /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */ + u8 nLevel; /* Number of nested loop */ + i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */ + u8 eOnePass; /* ONEPASS_OFF, or _SINGLE, or _MULTI */ + u8 eDistinct; /* One of the WHERE_DISTINCT_* values */ + unsigned bDeferredSeek :1; /* Uses OP_DeferredSeek */ + unsigned untestedTerms :1; /* Not all WHERE terms resolved by outer loop */ + unsigned bOrderedInnerLoop:1;/* True if only the inner-most loop is ordered */ + unsigned sorted :1; /* True if really sorted (not just grouped) */ + unsigned bStarDone :1; /* True if check for star-query is complete */ + unsigned bStarUsed :1; /* True if star-query heuristic is used */ + LogEst nRowOut; /* Estimated number of output rows */ +#ifdef WHERETRACE_ENABLED + LogEst rTotalCost; /* Total cost of the solution */ +#endif + int iTop; /* The very beginning of the WHERE loop */ + int iEndWhere; /* End of the WHERE clause itself */ + WhereLoop *pLoops; /* List of all WhereLoop objects */ + WhereMemBlock *pMemToFree;/* Memory to free when this object destroyed */ + Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ + WhereClause sWC; /* Decomposition of the WHERE clause */ + WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */ + WhereLevel a[FLEXARRAY]; /* Information about each nest loop in WHERE */ +}; + +/* +** The size (in bytes) of a WhereInfo object that holds N WhereLevels. +*/ +#define SZ_WHEREINFO(N) ROUND8(offsetof(WhereInfo,a)+(N)*sizeof(WhereLevel)) + +/* +** Private interfaces - callable only by other where.c routines. +** +** where.c: +*/ +SQLITE_PRIVATE Bitmask sqlite3WhereGetMask(WhereMaskSet*,int); +#ifdef WHERETRACE_ENABLED +SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC); +SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm); +SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause *pWC); +#endif +SQLITE_PRIVATE WhereTerm *sqlite3WhereFindTerm( + WhereClause *pWC, /* The WHERE clause to be searched */ + int iCur, /* Cursor number of LHS */ + int iColumn, /* Column number of LHS */ + Bitmask notReady, /* RHS must not overlap with this mask */ + u32 op, /* Mask of WO_xx values describing operator */ + Index *pIdx /* Must be compatible with this index, if not NULL */ +); +SQLITE_PRIVATE void *sqlite3WhereMalloc(WhereInfo *pWInfo, u64 nByte); +SQLITE_PRIVATE void *sqlite3WhereRealloc(WhereInfo *pWInfo, void *pOld, u64 nByte); + +/* wherecode.c: */ +#ifndef SQLITE_OMIT_EXPLAIN +SQLITE_PRIVATE int sqlite3WhereExplainOneScan( + Parse *pParse, /* Parse context */ + SrcList *pTabList, /* Table list this loop refers to */ + WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ + u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ +); +SQLITE_PRIVATE int sqlite3WhereExplainBloomFilter( + const Parse *pParse, /* Parse context */ + const WhereInfo *pWInfo, /* WHERE clause */ + const WhereLevel *pLevel /* Bloom filter on this level */ +); +SQLITE_PRIVATE void sqlite3WhereAddExplainText( + Parse *pParse, /* Parse context */ + int addr, + SrcList *pTabList, /* Table list this loop refers to */ + WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ + u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ +); +#else +# define sqlite3WhereExplainOneScan(u,v,w,x) 0 +# define sqlite3WhereExplainBloomFilter(u,v,w) 0 +# define sqlite3WhereAddExplainText(u,v,w,x,y) +#endif /* SQLITE_OMIT_EXPLAIN */ +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS +SQLITE_PRIVATE void sqlite3WhereAddScanStatus( + Vdbe *v, /* Vdbe to add scanstatus entry to */ + SrcList *pSrclist, /* FROM clause pLvl reads data from */ + WhereLevel *pLvl, /* Level to add scanstatus() entry for */ + int addrExplain /* Address of OP_Explain (or 0) */ +); +#else +# define sqlite3WhereAddScanStatus(a, b, c, d) ((void)d) +#endif +SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( + Parse *pParse, /* Parsing context */ + Vdbe *v, /* Prepared statement under construction */ + WhereInfo *pWInfo, /* Complete information about the WHERE clause */ + int iLevel, /* Which level of pWInfo->a[] should be coded */ + WhereLevel *pLevel, /* The current level pointer */ + Bitmask notReady /* Which tables are currently available */ +); +SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( + WhereInfo *pWInfo, + int iLevel, + WhereLevel *pLevel +); + +/* whereexpr.c: */ +SQLITE_PRIVATE void sqlite3WhereClauseInit(WhereClause*,WhereInfo*); +SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause*); +SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause*,Expr*,u8); +SQLITE_PRIVATE void sqlite3WhereAddLimit(WhereClause*, Select*); +SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*); +SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet*, Expr*); +SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*); +SQLITE_PRIVATE void sqlite3WhereExprAnalyze(SrcList*, WhereClause*); +SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*); + + + + + +/* +** Bitmasks for the operators on WhereTerm objects. These are all +** operators that are of interest to the query planner. An +** OR-ed combination of these values can be used when searching for +** particular WhereTerms within a WhereClause. +** +** Value constraints: +** WO_EQ == SQLITE_INDEX_CONSTRAINT_EQ +** WO_LT == SQLITE_INDEX_CONSTRAINT_LT +** WO_LE == SQLITE_INDEX_CONSTRAINT_LE +** WO_GT == SQLITE_INDEX_CONSTRAINT_GT +** WO_GE == SQLITE_INDEX_CONSTRAINT_GE +*/ +#define WO_IN 0x0001 +#define WO_EQ 0x0002 +#define WO_LT (WO_EQ<<(TK_LT-TK_EQ)) +#define WO_LE (WO_EQ<<(TK_LE-TK_EQ)) +#define WO_GT (WO_EQ<<(TK_GT-TK_EQ)) +#define WO_GE (WO_EQ<<(TK_GE-TK_EQ)) +#define WO_AUX 0x0040 /* Op useful to virtual tables only */ +#define WO_IS 0x0080 +#define WO_ISNULL 0x0100 +#define WO_OR 0x0200 /* Two or more OR-connected terms */ +#define WO_AND 0x0400 /* Two or more AND-connected terms */ +#define WO_EQUIV 0x0800 /* Of the form A==B, both columns */ +#define WO_NOOP 0x1000 /* This term does not restrict search space */ +#define WO_ROWVAL 0x2000 /* A row-value term */ + +#define WO_ALL 0x3fff /* Mask of all possible WO_* values */ +#define WO_SINGLE 0x01ff /* Mask of all non-compound WO_* values */ + +/* +** These are definitions of bits in the WhereLoop.wsFlags field. +** The particular combination of bits in each WhereLoop help to +** determine the algorithm that WhereLoop represents. +*/ +#define WHERE_COLUMN_EQ 0x00000001 /* x=EXPR */ +#define WHERE_COLUMN_RANGE 0x00000002 /* xEXPR */ +#define WHERE_COLUMN_IN 0x00000004 /* x IN (...) */ +#define WHERE_COLUMN_NULL 0x00000008 /* x IS NULL */ +#define WHERE_CONSTRAINT 0x0000000f /* Any of the WHERE_COLUMN_xxx values */ +#define WHERE_TOP_LIMIT 0x00000010 /* xEXPR or x>=EXPR constraint */ +#define WHERE_BOTH_LIMIT 0x00000030 /* Both x>EXPR and xaiColumn[i]; + if( i==XN_EXPR ) return ""; + if( i==XN_ROWID ) return "rowid"; + return pIdx->pTable->aCol[i].zCnName; +} + +/* +** This routine is a helper for explainIndexRange() below +** +** pStr holds the text of an expression that we are building up one term +** at a time. This routine adds a new term to the end of the expression. +** Terms are separated by AND so add the "AND" text for second and subsequent +** terms only. +*/ +static void explainAppendTerm( + StrAccum *pStr, /* The text expression being built */ + Index *pIdx, /* Index to read column names from */ + int nTerm, /* Number of terms */ + int iTerm, /* Zero-based index of first term. */ + int bAnd, /* Non-zero to append " AND " */ + const char *zOp /* Name of the operator */ +){ + int i; + + assert( nTerm>=1 ); + if( bAnd ) sqlite3_str_append(pStr, " AND ", 5); + + if( nTerm>1 ) sqlite3_str_append(pStr, "(", 1); + for(i=0; i1 ) sqlite3_str_append(pStr, ")", 1); + + sqlite3_str_append(pStr, zOp, 1); + + if( nTerm>1 ) sqlite3_str_append(pStr, "(", 1); + for(i=0; i1 ) sqlite3_str_append(pStr, ")", 1); +} + +/* +** Argument pLevel describes a strategy for scanning table pTab. This +** function appends text to pStr that describes the subset of table +** rows scanned by the strategy in the form of an SQL expression. +** +** For example, if the query: +** +** SELECT * FROM t1 WHERE a=1 AND b>2; +** +** is run and there is an index on (a, b), then this function returns a +** string similar to: +** +** "a=? AND b>?" +*/ +static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){ + Index *pIndex = pLoop->u.btree.pIndex; + u16 nEq = pLoop->u.btree.nEq; + u16 nSkip = pLoop->nSkip; + int i, j; + + if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return; + sqlite3_str_append(pStr, " (", 2); + for(i=0; i=nSkip ? "%s=?" : "ANY(%s)", z); + } + + j = i; + if( pLoop->wsFlags&WHERE_BTM_LIMIT ){ + explainAppendTerm(pStr, pIndex, pLoop->u.btree.nBtm, j, i, ">"); + i = 1; + } + if( pLoop->wsFlags&WHERE_TOP_LIMIT ){ + explainAppendTerm(pStr, pIndex, pLoop->u.btree.nTop, j, i, "<"); + } + sqlite3_str_append(pStr, ")", 1); +} + +/* +** This function sets the P4 value of an existing OP_Explain opcode to +** text describing the loop in pLevel. If the OP_Explain opcode already has +** a P4 value, it is freed before it is overwritten. +*/ +SQLITE_PRIVATE void sqlite3WhereAddExplainText( + Parse *pParse, /* Parse context */ + int addr, /* Address of OP_Explain opcode */ + SrcList *pTabList, /* Table list this loop refers to */ + WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ + u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ +){ +#if !defined(SQLITE_DEBUG) + if( sqlite3ParseToplevel(pParse)->explain==2 || IS_STMT_SCANSTATUS(pParse->db) ) +#endif + { + VdbeOp *pOp = sqlite3VdbeGetOp(pParse->pVdbe, addr); + SrcItem *pItem = &pTabList->a[pLevel->iFrom]; + sqlite3 *db = pParse->db; /* Database handle */ + int isSearch; /* True for a SEARCH. False for SCAN. */ + WhereLoop *pLoop; /* The controlling WhereLoop object */ + u32 flags; /* Flags that describe this loop */ +#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_EXPLAIN) + char *zMsg; /* Text to add to EQP output */ +#endif + StrAccum str; /* EQP output string */ + char zBuf[100]; /* Initial space for EQP output string */ + + if( db->mallocFailed ) return; + + pLoop = pLevel->pWLoop; + flags = pLoop->wsFlags; + + isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 + || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0)) + || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX)); + + sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH); + str.printfFlags = SQLITE_PRINTF_INTERNAL; + sqlite3_str_appendf(&str, "%s %S%s", + isSearch ? "SEARCH" : "SCAN", + pItem, + pItem->fg.fromExists ? " EXISTS" : ""); + if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){ + const char *zFmt = 0; + Index *pIdx; + + assert( pLoop->u.btree.pIndex!=0 ); + pIdx = pLoop->u.btree.pIndex; + assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) ); + if( !HasRowid(pItem->pSTab) && IsPrimaryKeyIndex(pIdx) ){ + if( isSearch ){ + zFmt = "PRIMARY KEY"; + } + }else if( flags & WHERE_PARTIALIDX ){ + zFmt = "AUTOMATIC PARTIAL COVERING INDEX"; + }else if( flags & WHERE_AUTO_INDEX ){ + zFmt = "AUTOMATIC COVERING INDEX"; + }else if( flags & (WHERE_IDX_ONLY|WHERE_EXPRIDX) ){ + zFmt = "COVERING INDEX %s"; + }else{ + zFmt = "INDEX %s"; + } + if( zFmt ){ + sqlite3_str_append(&str, " USING ", 7); + sqlite3_str_appendf(&str, zFmt, pIdx->zName); + explainIndexRange(&str, pLoop); + } + }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){ + char cRangeOp; +#if 0 /* Better output, but breaks many tests */ + const Table *pTab = pItem->pTab; + const char *zRowid = pTab->iPKey>=0 ? pTab->aCol[pTab->iPKey].zCnName: + "rowid"; +#else + const char *zRowid = "rowid"; +#endif + sqlite3_str_appendf(&str, " USING INTEGER PRIMARY KEY (%s", zRowid); + if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){ + cRangeOp = '='; + }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){ + sqlite3_str_appendf(&str, ">? AND %s", zRowid); + cRangeOp = '<'; + }else if( flags&WHERE_BTM_LIMIT ){ + cRangeOp = '>'; + }else{ + assert( flags&WHERE_TOP_LIMIT); + cRangeOp = '<'; + } + sqlite3_str_appendf(&str, "%c?)", cRangeOp); + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + else if( (flags & WHERE_VIRTUALTABLE)!=0 ){ + sqlite3_str_appendall(&str, " VIRTUAL TABLE INDEX "); + sqlite3_str_appendf(&str, + pLoop->u.vtab.bIdxNumHex ? "0x%x:%s" : "%d:%s", + pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr); + } +#endif + if( pItem->fg.jointype & JT_LEFT ){ + sqlite3_str_appendf(&str, " LEFT-JOIN"); + } +#ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS + if( pLoop->nOut>=10 ){ + sqlite3_str_appendf(&str, " (~%llu rows)", + sqlite3LogEstToInt(pLoop->nOut)); + }else{ + sqlite3_str_append(&str, " (~1 row)", 9); + } +#endif +#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_EXPLAIN) + zMsg = sqlite3StrAccumFinish(&str); + sqlite3ExplainBreakpoint("",zMsg); +#endif + + assert( pOp->opcode==OP_Explain ); + assert( pOp->p4type==P4_DYNAMIC || pOp->p4.z==0 ); + sqlite3DbFree(db, pOp->p4.z); + pOp->p4type = P4_DYNAMIC; + pOp->p4.z = sqlite3StrAccumFinish(&str); + } +} + + +/* +** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN +** command, or if stmt_scanstatus_v2() stats are enabled, or if SQLITE_DEBUG +** was defined at compile-time. If it is not a no-op, a single OP_Explain +** opcode is added to the output to describe the table scan strategy in pLevel. +** +** If an OP_Explain opcode is added to the VM, its address is returned. +** Otherwise, if no OP_Explain is coded, zero is returned. +*/ +SQLITE_PRIVATE int sqlite3WhereExplainOneScan( + Parse *pParse, /* Parse context */ + SrcList *pTabList, /* Table list this loop refers to */ + WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ + u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ +){ + int ret = 0; +#if !defined(SQLITE_DEBUG) + if( sqlite3ParseToplevel(pParse)->explain==2 || IS_STMT_SCANSTATUS(pParse->db) ) +#endif + { + if( (pLevel->pWLoop->wsFlags & WHERE_MULTI_OR)==0 + && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0 + ){ + Vdbe *v = pParse->pVdbe; + int addr = sqlite3VdbeCurrentAddr(v); + ret = sqlite3VdbeAddOp3( + v, OP_Explain, addr, pParse->addrExplain, pLevel->pWLoop->rRun + ); + sqlite3WhereAddExplainText(pParse, addr, pTabList, pLevel, wctrlFlags); + } + } + return ret; +} + +/* +** Add a single OP_Explain opcode that describes a Bloom filter. +** +** Or if not processing EXPLAIN QUERY PLAN and not in a SQLITE_DEBUG and/or +** SQLITE_ENABLE_STMT_SCANSTATUS build, then OP_Explain opcodes are not +** required and this routine is a no-op. +** +** If an OP_Explain opcode is added to the VM, its address is returned. +** Otherwise, if no OP_Explain is coded, zero is returned. +*/ +SQLITE_PRIVATE int sqlite3WhereExplainBloomFilter( + const Parse *pParse, /* Parse context */ + const WhereInfo *pWInfo, /* WHERE clause */ + const WhereLevel *pLevel /* Bloom filter on this level */ +){ + int ret = 0; + SrcItem *pItem = &pWInfo->pTabList->a[pLevel->iFrom]; + Vdbe *v = pParse->pVdbe; /* VM being constructed */ + sqlite3 *db = pParse->db; /* Database handle */ + char *zMsg; /* Text to add to EQP output */ + int i; /* Loop counter */ + WhereLoop *pLoop; /* The where loop */ + StrAccum str; /* EQP output string */ + char zBuf[100]; /* Initial space for EQP output string */ + + sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH); + str.printfFlags = SQLITE_PRINTF_INTERNAL; + sqlite3_str_appendf(&str, "BLOOM FILTER ON %S (", pItem); + pLoop = pLevel->pWLoop; + if( pLoop->wsFlags & WHERE_IPK ){ + const Table *pTab = pItem->pSTab; + if( pTab->iPKey>=0 ){ + sqlite3_str_appendf(&str, "%s=?", pTab->aCol[pTab->iPKey].zCnName); + }else{ + sqlite3_str_appendf(&str, "rowid=?"); + } + }else{ + for(i=pLoop->nSkip; iu.btree.nEq; i++){ + const char *z = explainIndexColumnName(pLoop->u.btree.pIndex, i); + if( i>pLoop->nSkip ) sqlite3_str_append(&str, " AND ", 5); + sqlite3_str_appendf(&str, "%s=?", z); + } + } + sqlite3_str_append(&str, ")", 1); + zMsg = sqlite3StrAccumFinish(&str); + ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v), + pParse->addrExplain, 0, zMsg,P4_DYNAMIC); + + sqlite3VdbeScanStatus(v, sqlite3VdbeCurrentAddr(v)-1, 0, 0, 0, 0); + return ret; +} +#endif /* SQLITE_OMIT_EXPLAIN */ + +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS +/* +** Configure the VM passed as the first argument with an +** sqlite3_stmt_scanstatus() entry corresponding to the scan used to +** implement level pLvl. Argument pSrclist is a pointer to the FROM +** clause that the scan reads data from. +** +** If argument addrExplain is not 0, it must be the address of an +** OP_Explain instruction that describes the same loop. +*/ +SQLITE_PRIVATE void sqlite3WhereAddScanStatus( + Vdbe *v, /* Vdbe to add scanstatus entry to */ + SrcList *pSrclist, /* FROM clause pLvl reads data from */ + WhereLevel *pLvl, /* Level to add scanstatus() entry for */ + int addrExplain /* Address of OP_Explain (or 0) */ +){ + if( IS_STMT_SCANSTATUS( sqlite3VdbeDb(v) ) ){ + const char *zObj = 0; + WhereLoop *pLoop = pLvl->pWLoop; + int wsFlags = pLoop->wsFlags; + int viaCoroutine = 0; + + if( (wsFlags & WHERE_VIRTUALTABLE)==0 && pLoop->u.btree.pIndex!=0 ){ + zObj = pLoop->u.btree.pIndex->zName; + }else{ + zObj = pSrclist->a[pLvl->iFrom].zName; + viaCoroutine = pSrclist->a[pLvl->iFrom].fg.viaCoroutine; + } + sqlite3VdbeScanStatus( + v, addrExplain, pLvl->addrBody, pLvl->addrVisit, pLoop->nOut, zObj + ); + + if( viaCoroutine==0 ){ + if( (wsFlags & (WHERE_MULTI_OR|WHERE_AUTO_INDEX))==0 ){ + sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iTabCur); + } + if( wsFlags & WHERE_INDEXED ){ + sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iIdxCur); + } + }else{ + int addr; + VdbeOp *pOp; + assert( pSrclist->a[pLvl->iFrom].fg.isSubquery ); + addr = pSrclist->a[pLvl->iFrom].u4.pSubq->addrFillSub; + pOp = sqlite3VdbeGetOp(v, addr-1); + assert( sqlite3VdbeDb(v)->mallocFailed || pOp->opcode==OP_InitCoroutine ); + assert( sqlite3VdbeDb(v)->mallocFailed || pOp->p2>addr ); + sqlite3VdbeScanStatusRange(v, addrExplain, addr, pOp->p2-1); + } + } +} +#endif + + +/* +** Disable a term in the WHERE clause. Except, do not disable the term +** if it controls a LEFT OUTER JOIN and it did not originate in the ON +** or USING clause of that join. +** +** Consider the term t2.z='ok' in the following queries: +** +** (1) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x WHERE t2.z='ok' +** (2) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x AND t2.z='ok' +** (3) SELECT * FROM t1, t2 WHERE t1.a=t2.x AND t2.z='ok' +** +** The t2.z='ok' is disabled in the in (2) because it originates +** in the ON clause. The term is disabled in (3) because it is not part +** of a LEFT OUTER JOIN. In (1), the term is not disabled. +** +** Disabling a term causes that term to not be tested in the inner loop +** of the join. Disabling is an optimization. When terms are satisfied +** by indices, we disable them to prevent redundant tests in the inner +** loop. We would get the correct results if nothing were ever disabled, +** but joins might run a little slower. The trick is to disable as much +** as we can without disabling too much. If we disabled in (1), we'd get +** the wrong answer. See ticket #813. +** +** If all the children of a term are disabled, then that term is also +** automatically disabled. In this way, terms get disabled if derived +** virtual terms are tested first. For example: +** +** x GLOB 'abc*' AND x>='abc' AND x<'acd' +** \___________/ \______/ \_____/ +** parent child1 child2 +** +** Only the parent term was in the original WHERE clause. The child1 +** and child2 terms were added by the LIKE optimization. If both of +** the virtual child terms are valid, then testing of the parent can be +** skipped. +** +** Usually the parent term is marked as TERM_CODED. But if the parent +** term was originally TERM_LIKE, then the parent gets TERM_LIKECOND instead. +** The TERM_LIKECOND marking indicates that the term should be coded inside +** a conditional such that is only evaluated on the second pass of a +** LIKE-optimization loop, when scanning BLOBs instead of strings. +*/ +static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){ + int nLoop = 0; + assert( pTerm!=0 ); + while( (pTerm->wtFlags & TERM_CODED)==0 + && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_OuterON)) + && (pLevel->notReady & pTerm->prereqAll)==0 + ){ + if( nLoop && (pTerm->wtFlags & TERM_LIKE)!=0 ){ + pTerm->wtFlags |= TERM_LIKECOND; + }else{ + pTerm->wtFlags |= TERM_CODED; + } +#ifdef WHERETRACE_ENABLED + if( (sqlite3WhereTrace & 0x4001)==0x4001 ){ + sqlite3DebugPrintf("DISABLE-"); + sqlite3WhereTermPrint(pTerm, (int)(pTerm - (pTerm->pWC->a))); + } +#endif + if( pTerm->iParent<0 ) break; + pTerm = &pTerm->pWC->a[pTerm->iParent]; + assert( pTerm!=0 ); + pTerm->nChild--; + if( pTerm->nChild!=0 ) break; + nLoop++; + } +} + +/* +** Code an OP_Affinity opcode to apply the column affinity string zAff +** to the n registers starting at base. +** +** As an optimization, SQLITE_AFF_BLOB and SQLITE_AFF_NONE entries (which +** are no-ops) at the beginning and end of zAff are ignored. If all entries +** in zAff are SQLITE_AFF_BLOB or SQLITE_AFF_NONE, then no code gets generated. +** +** This routine makes its own copy of zAff so that the caller is free +** to modify zAff after this routine returns. +*/ +static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){ + Vdbe *v = pParse->pVdbe; + if( zAff==0 ){ + assert( pParse->db->mallocFailed ); + return; + } + assert( v!=0 ); + + /* Adjust base and n to skip over SQLITE_AFF_BLOB and SQLITE_AFF_NONE + ** entries at the beginning and end of the affinity string. + */ + assert( SQLITE_AFF_NONE0 && zAff[0]<=SQLITE_AFF_BLOB ){ + n--; + base++; + zAff++; + } + while( n>1 && zAff[n-1]<=SQLITE_AFF_BLOB ){ + n--; + } + + /* Code the OP_Affinity opcode if there is anything left to do. */ + if( n>0 ){ + sqlite3VdbeAddOp4(v, OP_Affinity, base, n, 0, zAff, n); + } +} + +/* +** Expression pRight, which is the RHS of a comparison operation, is +** either a vector of n elements or, if n==1, a scalar expression. +** Before the comparison operation, affinity zAff is to be applied +** to the pRight values. This function modifies characters within the +** affinity string to SQLITE_AFF_BLOB if either: +** +** * the comparison will be performed with no affinity, or +** * the affinity change in zAff is guaranteed not to change the value. +*/ +static void updateRangeAffinityStr( + Expr *pRight, /* RHS of comparison */ + int n, /* Number of vector elements in comparison */ + char *zAff /* Affinity string to modify */ +){ + int i; + for(i=0; ia[].u.x.iOrderByCol values might be incorrect because +** columns might have been rearranged in the result set. This routine +** fixes them up. +** +** pEList is the new result set. The pEList->a[].u.x.iOrderByCol values +** contain the *old* locations of each expression. This is a temporary +** use of u.x.iOrderByCol, not its intended use. The caller must reset +** u.x.iOrderByCol back to zero for all entries in pEList before the +** caller returns. +** +** This routine changes pOrderBy->a[].u.x.iOrderByCol values from +** pEList->a[N].u.x.iOrderByCol into N+1. (The "+1" is because of the 1-based +** indexing used by iOrderByCol.) Or if no match, iOrderByCol is set to zero. +*/ +static void adjustOrderByCol(ExprList *pOrderBy, ExprList *pEList){ + int i, j; + if( pOrderBy==0 ) return; + for(i=0; inExpr; i++){ + int t = pOrderBy->a[i].u.x.iOrderByCol; + if( t==0 ) continue; + for(j=0; jnExpr; j++){ + if( pEList->a[j].u.x.iOrderByCol==t ){ + pOrderBy->a[i].u.x.iOrderByCol = j+1; + break; + } + } + if( j>=pEList->nExpr ){ + pOrderBy->a[i].u.x.iOrderByCol = 0; + } + } +} + + +/* +** pX is an expression of the form: (vector) IN (SELECT ...) +** In other words, it is a vector IN operator with a SELECT clause on the +** RHS. But not all terms in the vector are indexable and the terms might +** not be in the correct order for indexing. +** +** This routine makes a copy of the input pX expression and then adjusts +** the vector on the LHS with corresponding changes to the SELECT so that +** the vector contains only index terms and those terms are in the correct +** order. The modified IN expression is returned. The caller is responsible +** for deleting the returned expression. +** +** Example: +** +** CREATE TABLE t1(a,b,c,d,e,f); +** CREATE INDEX t1x1 ON t1(e,c); +** SELECT * FROM t1 WHERE (a,b,c,d,e) IN (SELECT v,w,x,y,z FROM t2) +** \_______________________________________/ +** The pX expression +** +** Since only columns e and c can be used with the index, in that order, +** the modified IN expression that is returned will be: +** +** (e,c) IN (SELECT z,x FROM t2) +** +** The reduced pX is different from the original (obviously) and thus is +** only used for indexing, to improve performance. The original unaltered +** IN expression must also be run on each output row for correctness. +*/ +static Expr *removeUnindexableInClauseTerms( + Parse *pParse, /* The parsing context */ + int iEq, /* Look at loop terms starting here */ + WhereLoop *pLoop, /* The current loop */ + Expr *pX /* The IN expression to be reduced */ +){ + sqlite3 *db = pParse->db; + Select *pSelect; /* Pointer to the SELECT on the RHS */ + Expr *pNew; + pNew = sqlite3ExprDup(db, pX, 0); + if( db->mallocFailed==0 ){ + for(pSelect=pNew->x.pSelect; pSelect; pSelect=pSelect->pPrior){ + ExprList *pOrigRhs; /* Original unmodified RHS */ + ExprList *pOrigLhs = 0; /* Original unmodified LHS */ + ExprList *pRhs = 0; /* New RHS after modifications */ + ExprList *pLhs = 0; /* New LHS after mods */ + int i; /* Loop counter */ + + assert( ExprUseXSelect(pNew) ); + pOrigRhs = pSelect->pEList; + assert( pNew->pLeft!=0 ); + assert( ExprUseXList(pNew->pLeft) ); + if( pSelect==pNew->x.pSelect ){ + pOrigLhs = pNew->pLeft->x.pList; + } + for(i=iEq; inLTerm; i++){ + if( pLoop->aLTerm[i]->pExpr==pX ){ + int iField; + assert( (pLoop->aLTerm[i]->eOperator & (WO_OR|WO_AND))==0 ); + iField = pLoop->aLTerm[i]->u.x.iField - 1; + if( NEVER(pOrigRhs->a[iField].pExpr==0) ){ + continue; /* Duplicate PK column */ + } + pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr); + pOrigRhs->a[iField].pExpr = 0; + if( pRhs ) pRhs->a[pRhs->nExpr-1].u.x.iOrderByCol = iField+1; + if( pOrigLhs ){ + assert( pOrigLhs->a[iField].pExpr!=0 ); + pLhs = sqlite3ExprListAppend(pParse,pLhs,pOrigLhs->a[iField].pExpr); + pOrigLhs->a[iField].pExpr = 0; + } + } + } + sqlite3ExprListDelete(db, pOrigRhs); + if( pOrigLhs ){ + sqlite3ExprListDelete(db, pOrigLhs); + pNew->pLeft->x.pList = pLhs; + } + pSelect->pEList = pRhs; + pSelect->selId = ++pParse->nSelect; /* Req'd for SubrtnSig validity */ + if( pLhs && pLhs->nExpr==1 ){ + /* Take care here not to generate a TK_VECTOR containing only a + ** single value. Since the parser never creates such a vector, some + ** of the subroutines do not handle this case. */ + Expr *p = pLhs->a[0].pExpr; + pLhs->a[0].pExpr = 0; + sqlite3ExprDelete(db, pNew->pLeft); + pNew->pLeft = p; + } + + /* If either the ORDER BY clause or the GROUP BY clause contains + ** references to result-set columns, those references might now be + ** obsolete. So fix them up. + */ + assert( pRhs!=0 || db->mallocFailed ); + if( pRhs ){ + adjustOrderByCol(pSelect->pOrderBy, pRhs); + adjustOrderByCol(pSelect->pGroupBy, pRhs); + for(i=0; inExpr; i++) pRhs->a[i].u.x.iOrderByCol = 0; + } + +#if 0 + printf("For indexing, change the IN expr:\n"); + sqlite3TreeViewExpr(0, pX, 0); + printf("Into:\n"); + sqlite3TreeViewExpr(0, pNew, 0); +#endif + } + } + return pNew; +} + + +#ifndef SQLITE_OMIT_SUBQUERY +/* +** Generate code for a single X IN (....) term of the WHERE clause. +** +** This is a special-case of codeEqualityTerm() that works for IN operators +** only. It is broken out into a subroutine because this case is +** uncommon and by splitting it off into a subroutine, the common case +** runs faster. +** +** The current value for the constraint is left in register iTarget. +** This routine sets up a loop that will iterate over all values of X. +*/ +static SQLITE_NOINLINE void codeINTerm( + Parse *pParse, /* The parsing context */ + WhereTerm *pTerm, /* The term of the WHERE clause to be coded */ + WhereLevel *pLevel, /* The level of the FROM clause we are working on */ + int iEq, /* Index of the equality term within this level */ + int bRev, /* True for reverse-order IN operations */ + int iTarget /* Attempt to leave results in this register */ +){ + Expr *pX = pTerm->pExpr; + int eType = IN_INDEX_NOOP; + int iTab; + struct InLoop *pIn; + WhereLoop *pLoop = pLevel->pWLoop; + Vdbe *v = pParse->pVdbe; + int i; + int nEq = 0; + int *aiMap = 0; + + if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 + && pLoop->u.btree.pIndex!=0 + && pLoop->u.btree.pIndex->aSortOrder[iEq] + ){ + testcase( iEq==0 ); + testcase( bRev ); + bRev = !bRev; + } + assert( pX->op==TK_IN ); + + for(i=0; iaLTerm[i] && pLoop->aLTerm[i]->pExpr==pX ){ + disableTerm(pLevel, pTerm); + return; + } + } + for(i=iEq; inLTerm; i++){ + assert( pLoop->aLTerm[i]!=0 ); + if( pLoop->aLTerm[i]->pExpr==pX ) nEq++; + } + + iTab = 0; + if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){ + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); + }else{ + sqlite3 *db = pParse->db; + Expr *pXMod = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); + if( !db->mallocFailed ){ + aiMap = (int*)sqlite3DbMallocZero(db, sizeof(int)*nEq); + eType = sqlite3FindInIndex(pParse, pXMod, IN_INDEX_LOOP, 0, aiMap, &iTab); + } + sqlite3ExprDelete(db, pXMod); + } + + if( eType==IN_INDEX_INDEX_DESC ){ + testcase( bRev ); + bRev = !bRev; + } + sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0); + VdbeCoverageIf(v, bRev); + VdbeCoverageIf(v, !bRev); + + assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 ); + pLoop->wsFlags |= WHERE_IN_ABLE; + if( pLevel->u.in.nIn==0 ){ + pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse); + } + if( iEq>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 ){ + pLoop->wsFlags |= WHERE_IN_EARLYOUT; + } + + i = pLevel->u.in.nIn; + pLevel->u.in.nIn += nEq; + pLevel->u.in.aInLoop = + sqlite3WhereRealloc(pTerm->pWC->pWInfo, + pLevel->u.in.aInLoop, + sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn); + pIn = pLevel->u.in.aInLoop; + if( pIn ){ + int iMap = 0; /* Index in aiMap[] */ + pIn += i; + for(i=iEq; inLTerm; i++){ + if( pLoop->aLTerm[i]->pExpr==pX ){ + int iOut = iTarget + i - iEq; + if( eType==IN_INDEX_ROWID ){ + pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut); + }else{ + int iCol = aiMap ? aiMap[iMap++] : 0; + pIn->addrInTop = sqlite3VdbeAddOp3(v,OP_Column,iTab, iCol, iOut); + } + sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v); + if( i==iEq ){ + pIn->iCur = iTab; + pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next; + if( iEq>0 ){ + pIn->iBase = iTarget - i; + pIn->nPrefix = i; + }else{ + pIn->nPrefix = 0; + } + }else{ + pIn->eEndLoopOp = OP_Noop; + } + pIn++; + } + } + testcase( iEq>0 + && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 + && (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ); + if( iEq>0 + && (pLoop->wsFlags & (WHERE_IN_SEEKSCAN|WHERE_VIRTUALTABLE))==0 + ){ + sqlite3VdbeAddOp3(v, OP_SeekHit, pLevel->iIdxCur, 0, iEq); + } + }else{ + pLevel->u.in.nIn = 0; + } + sqlite3DbFree(pParse->db, aiMap); +} +#endif + + +/* +** Generate code for a single equality term of the WHERE clause. An equality +** term can be either X=expr or X IN (...). pTerm is the term to be +** coded. +** +** The current value for the constraint is left in a register, the index +** of which is returned. An attempt is made store the result in iTarget but +** this is only guaranteed for TK_ISNULL and TK_IN constraints. If the +** constraint is a TK_EQ or TK_IS, then the current value might be left in +** some other register and it is the caller's responsibility to compensate. +** +** For a constraint of the form X=expr, the expression is evaluated in +** straight-line code. For constraints of the form X IN (...) +** this routine sets up a loop that will iterate over all values of X. +*/ +static int codeEqualityTerm( + Parse *pParse, /* The parsing context */ + WhereTerm *pTerm, /* The term of the WHERE clause to be coded */ + WhereLevel *pLevel, /* The level of the FROM clause we are working on */ + int iEq, /* Index of the equality term within this level */ + int bRev, /* True for reverse-order IN operations */ + int iTarget /* Attempt to leave results in this register */ +){ + Expr *pX = pTerm->pExpr; + int iReg; /* Register holding results */ + + assert( pLevel->pWLoop->aLTerm[iEq]==pTerm ); + assert( iTarget>0 ); + if( pX->op==TK_EQ || pX->op==TK_IS ){ + iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget); + }else if( pX->op==TK_ISNULL ){ + iReg = iTarget; + sqlite3VdbeAddOp2(pParse->pVdbe, OP_Null, 0, iReg); +#ifndef SQLITE_OMIT_SUBQUERY + }else{ + assert( pX->op==TK_IN ); + iReg = iTarget; + codeINTerm(pParse, pTerm, pLevel, iEq, bRev, iTarget); +#endif + } + + /* As an optimization, try to disable the WHERE clause term that is + ** driving the index as it will always be true. The correct answer is + ** obtained regardless, but we might get the answer with fewer CPU cycles + ** by omitting the term. + ** + ** But do not disable the term unless we are certain that the term is + ** not a transitive constraint. For an example of where that does not + ** work, see https://sqlite.org/forum/forumpost/eb8613976a (2021-05-04) + */ + if( (pLevel->pWLoop->wsFlags & WHERE_TRANSCONS)==0 + || (pTerm->eOperator & WO_EQUIV)==0 + ){ + disableTerm(pLevel, pTerm); + } + + return iReg; +} + +/* +** Generate code that will evaluate all == and IN constraints for an +** index scan. +** +** For example, consider table t1(a,b,c,d,e,f) with index i1(a,b,c). +** Suppose the WHERE clause is this: a==5 AND b IN (1,2,3) AND c>5 AND c<10 +** The index has as many as three equality constraints, but in this +** example, the third "c" value is an inequality. So only two +** constraints are coded. This routine will generate code to evaluate +** a==5 and b IN (1,2,3). The current values for a and b will be stored +** in consecutive registers and the index of the first register is returned. +** +** In the example above nEq==2. But this subroutine works for any value +** of nEq including 0. If nEq==0, this routine is nearly a no-op. +** The only thing it does is allocate the pLevel->iMem memory cell and +** compute the affinity string. +** +** The nExtraReg parameter is 0 or 1. It is 0 if all WHERE clause constraints +** are == or IN and are covered by the nEq. nExtraReg is 1 if there is +** an inequality constraint (such as the "c>=5 AND c<10" in the example) that +** occurs after the nEq quality constraints. +** +** This routine allocates a range of nEq+nExtraReg memory cells and returns +** the index of the first memory cell in that range. The code that +** calls this routine will use that memory range to store keys for +** start and termination conditions of the loop. +** key value of the loop. If one or more IN operators appear, then +** this routine allocates an additional nEq memory cells for internal +** use. +** +** Before returning, *pzAff is set to point to a buffer containing a +** copy of the column affinity string of the index allocated using +** sqlite3DbMalloc(). Except, entries in the copy of the string associated +** with equality constraints that use BLOB or NONE affinity are set to +** SQLITE_AFF_BLOB. This is to deal with SQL such as the following: +** +** CREATE TABLE t1(a TEXT PRIMARY KEY, b); +** SELECT ... FROM t1 AS t2, t1 WHERE t1.a = t2.b; +** +** In the example above, the index on t1(a) has TEXT affinity. But since +** the right hand side of the equality constraint (t2.b) has BLOB/NONE affinity, +** no conversion should be attempted before using a t2.b value as part of +** a key to search the index. Hence the first byte in the returned affinity +** string in this example would be set to SQLITE_AFF_BLOB. +*/ +static int codeAllEqualityTerms( + Parse *pParse, /* Parsing context */ + WhereLevel *pLevel, /* Which nested loop of the FROM we are coding */ + int bRev, /* Reverse the order of IN operators */ + int nExtraReg, /* Number of extra registers to allocate */ + char **pzAff /* OUT: Set to point to affinity string */ +){ + u16 nEq; /* The number of == or IN constraints to code */ + u16 nSkip; /* Number of left-most columns to skip */ + Vdbe *v = pParse->pVdbe; /* The vm under construction */ + Index *pIdx; /* The index being used for this loop */ + WhereTerm *pTerm; /* A single constraint term */ + WhereLoop *pLoop; /* The WhereLoop object */ + int j; /* Loop counter */ + int regBase; /* Base register */ + int nReg; /* Number of registers to allocate */ + char *zAff; /* Affinity string to return */ + + /* This module is only called on query plans that use an index. */ + pLoop = pLevel->pWLoop; + assert( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ); + nEq = pLoop->u.btree.nEq; + nSkip = pLoop->nSkip; + pIdx = pLoop->u.btree.pIndex; + assert( pIdx!=0 ); + + /* Figure out how many memory cells we will need then allocate them. + */ + regBase = pParse->nMem + 1; + nReg = nEq + nExtraReg; + pParse->nMem += nReg; + + zAff = sqlite3DbStrDup(pParse->db,sqlite3IndexAffinityStr(pParse->db,pIdx)); + assert( zAff!=0 || pParse->db->mallocFailed ); + + if( nSkip ){ + int iIdxCur = pLevel->iIdxCur; + sqlite3VdbeAddOp3(v, OP_Null, 0, regBase, regBase+nSkip-1); + sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur); + VdbeCoverageIf(v, bRev==0); + VdbeCoverageIf(v, bRev!=0); + VdbeComment((v, "begin skip-scan on %s", pIdx->zName)); + j = sqlite3VdbeAddOp0(v, OP_Goto); + assert( pLevel->addrSkip==0 ); + pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT), + iIdxCur, 0, regBase, nSkip); + VdbeCoverageIf(v, bRev==0); + VdbeCoverageIf(v, bRev!=0); + sqlite3VdbeJumpHere(v, j); + for(j=0; jaiColumn[j]==XN_EXPR ); + VdbeComment((v, "%s", explainIndexColumnName(pIdx, j))); + } + } + + /* Evaluate the equality constraints + */ + assert( zAff==0 || (int)strlen(zAff)>=nEq ); + for(j=nSkip; jaLTerm[j]; + assert( pTerm!=0 ); + /* The following testcase is true for indices with redundant columns. + ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */ + testcase( (pTerm->wtFlags & TERM_CODED)!=0 ); + testcase( pTerm->wtFlags & TERM_VIRTUAL ); + r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, regBase+j); + if( r1!=regBase+j ){ + if( nReg==1 ){ + sqlite3ReleaseTempReg(pParse, regBase); + regBase = r1; + }else{ + sqlite3VdbeAddOp2(v, OP_Copy, r1, regBase+j); + } + } + if( pTerm->eOperator & WO_IN ){ + if( pTerm->pExpr->flags & EP_xIsSelect ){ + /* No affinity ever needs to be (or should be) applied to a value + ** from the RHS of an "? IN (SELECT ...)" expression. The + ** sqlite3FindInIndex() routine has already ensured that the + ** affinity of the comparison has been applied to the value. */ + if( zAff ) zAff[j] = SQLITE_AFF_BLOB; + } + }else if( (pTerm->eOperator & WO_ISNULL)==0 ){ + Expr *pRight = pTerm->pExpr->pRight; + if( (pTerm->wtFlags & TERM_IS)==0 && sqlite3ExprCanBeNull(pRight) ){ + sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk); + VdbeCoverage(v); + } + if( pParse->nErr==0 ){ + assert( pParse->db->mallocFailed==0 ); + if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_BLOB ){ + zAff[j] = SQLITE_AFF_BLOB; + } + if( sqlite3ExprNeedsNoAffinityChange(pRight, zAff[j]) ){ + zAff[j] = SQLITE_AFF_BLOB; + } + } + } + } + *pzAff = zAff; + return regBase; +} + +#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS +/* +** If the most recently coded instruction is a constant range constraint +** (a string literal) that originated from the LIKE optimization, then +** set P3 and P5 on the OP_String opcode so that the string will be cast +** to a BLOB at appropriate times. +** +** The LIKE optimization trys to evaluate "x LIKE 'abc%'" as a range +** expression: "x>='ABC' AND x<'abd'". But this requires that the range +** scan loop run twice, once for strings and a second time for BLOBs. +** The OP_String opcodes on the second pass convert the upper and lower +** bound string constants to blobs. This routine makes the necessary changes +** to the OP_String opcodes for that to happen. +** +** Except, of course, if SQLITE_LIKE_DOESNT_MATCH_BLOBS is defined, then +** only the one pass through the string space is required, so this routine +** becomes a no-op. +*/ +static void whereLikeOptimizationStringFixup( + Vdbe *v, /* prepared statement under construction */ + WhereLevel *pLevel, /* The loop that contains the LIKE operator */ + WhereTerm *pTerm /* The upper or lower bound just coded */ +){ + if( pTerm->wtFlags & TERM_LIKEOPT ){ + VdbeOp *pOp; + assert( pLevel->iLikeRepCntr>0 ); + pOp = sqlite3VdbeGetLastOp(v); + assert( pOp!=0 ); + assert( pOp->opcode==OP_String8 + || pTerm->pWC->pWInfo->pParse->db->mallocFailed ); + pOp->p3 = (int)(pLevel->iLikeRepCntr>>1); /* Register holding counter */ + pOp->p5 = (u8)(pLevel->iLikeRepCntr&1); /* ASC or DESC */ + } +} +#else +# define whereLikeOptimizationStringFixup(A,B,C) +#endif + +#ifdef SQLITE_ENABLE_CURSOR_HINTS +/* +** Information is passed from codeCursorHint() down to individual nodes of +** the expression tree (by sqlite3WalkExpr()) using an instance of this +** structure. +*/ +struct CCurHint { + int iTabCur; /* Cursor for the main table */ + int iIdxCur; /* Cursor for the index, if pIdx!=0. Unused otherwise */ + Index *pIdx; /* The index used to access the table */ +}; + +/* +** This function is called for every node of an expression that is a candidate +** for a cursor hint on an index cursor. For TK_COLUMN nodes that reference +** the table CCurHint.iTabCur, verify that the same column can be +** accessed through the index. If it cannot, then set pWalker->eCode to 1. +*/ +static int codeCursorHintCheckExpr(Walker *pWalker, Expr *pExpr){ + struct CCurHint *pHint = pWalker->u.pCCurHint; + assert( pHint->pIdx!=0 ); + if( pExpr->op==TK_COLUMN + && pExpr->iTable==pHint->iTabCur + && sqlite3TableColumnToIndex(pHint->pIdx, pExpr->iColumn)<0 + ){ + pWalker->eCode = 1; + } + return WRC_Continue; +} + +/* +** Test whether or not expression pExpr, which was part of a WHERE clause, +** should be included in the cursor-hint for a table that is on the rhs +** of a LEFT JOIN. Set Walker.eCode to non-zero before returning if the +** expression is not suitable. +** +** An expression is unsuitable if it might evaluate to non NULL even if +** a TK_COLUMN node that does affect the value of the expression is set +** to NULL. For example: +** +** col IS NULL +** col IS NOT NULL +** coalesce(col, 1) +** CASE WHEN col THEN 0 ELSE 1 END +*/ +static int codeCursorHintIsOrFunction(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_IS + || pExpr->op==TK_ISNULL || pExpr->op==TK_ISNOT + || pExpr->op==TK_NOTNULL || pExpr->op==TK_CASE + ){ + pWalker->eCode = 1; + }else if( pExpr->op==TK_FUNCTION ){ + int d1; + char d2[4]; + if( 0==sqlite3IsLikeFunction(pWalker->pParse->db, pExpr, &d1, d2) ){ + pWalker->eCode = 1; + } + } + + return WRC_Continue; +} + + +/* +** This function is called on every node of an expression tree used as an +** argument to the OP_CursorHint instruction. If the node is a TK_COLUMN +** that accesses any table other than the one identified by +** CCurHint.iTabCur, then do the following: +** +** 1) allocate a register and code an OP_Column instruction to read +** the specified column into the new register, and +** +** 2) transform the expression node to a TK_REGISTER node that reads +** from the newly populated register. +** +** Also, if the node is a TK_COLUMN that does access the table identified +** by pCCurHint.iTabCur, and an index is being used (which we will +** know because CCurHint.pIdx!=0) then transform the TK_COLUMN into +** an access of the index rather than the original table. +*/ +static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){ + int rc = WRC_Continue; + int reg; + struct CCurHint *pHint = pWalker->u.pCCurHint; + if( pExpr->op==TK_COLUMN ){ + if( pExpr->iTable!=pHint->iTabCur ){ + reg = ++pWalker->pParse->nMem; /* Register for column value */ + reg = sqlite3ExprCodeTarget(pWalker->pParse, pExpr, reg); + pExpr->op = TK_REGISTER; + pExpr->iTable = reg; + }else if( pHint->pIdx!=0 ){ + pExpr->iTable = pHint->iIdxCur; + pExpr->iColumn = sqlite3TableColumnToIndex(pHint->pIdx, pExpr->iColumn); + assert( pExpr->iColumn>=0 ); + } + }else if( pExpr->pAggInfo ){ + rc = WRC_Prune; + reg = ++pWalker->pParse->nMem; /* Register for column value */ + reg = sqlite3ExprCodeTarget(pWalker->pParse, pExpr, reg); + pExpr->op = TK_REGISTER; + pExpr->iTable = reg; + }else if( pExpr->op==TK_TRUEFALSE ){ + /* Do not walk disabled expressions. tag-20230504-1 */ + return WRC_Prune; + } + return rc; +} + +/* +** Insert an OP_CursorHint instruction if it is appropriate to do so. +*/ +static void codeCursorHint( + SrcItem *pTabItem, /* FROM clause item */ + WhereInfo *pWInfo, /* The where clause */ + WhereLevel *pLevel, /* Which loop to provide hints for */ + WhereTerm *pEndRange /* Hint this end-of-scan boundary term if not NULL */ +){ + Parse *pParse = pWInfo->pParse; + sqlite3 *db = pParse->db; + Vdbe *v = pParse->pVdbe; + Expr *pExpr = 0; + WhereLoop *pLoop = pLevel->pWLoop; + int iCur; + WhereClause *pWC; + WhereTerm *pTerm; + int i, j; + struct CCurHint sHint; + Walker sWalker; + + if( OptimizationDisabled(db, SQLITE_CursorHints) ) return; + iCur = pLevel->iTabCur; + assert( iCur==pWInfo->pTabList->a[pLevel->iFrom].iCursor ); + sHint.iTabCur = iCur; + sHint.iIdxCur = pLevel->iIdxCur; + sHint.pIdx = pLoop->u.btree.pIndex; + memset(&sWalker, 0, sizeof(sWalker)); + sWalker.pParse = pParse; + sWalker.u.pCCurHint = &sHint; + pWC = &pWInfo->sWC; + for(i=0; inBase; i++){ + pTerm = &pWC->a[i]; + if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; + if( pTerm->prereqAll & pLevel->notReady ) continue; + + /* Any terms specified as part of the ON(...) clause for any LEFT + ** JOIN for which the current table is not the rhs are omitted + ** from the cursor-hint. + ** + ** If this table is the rhs of a LEFT JOIN, "IS" or "IS NULL" terms + ** that were specified as part of the WHERE clause must be excluded. + ** This is to address the following: + ** + ** SELECT ... t1 LEFT JOIN t2 ON (t1.a=t2.b) WHERE t2.c IS NULL; + ** + ** Say there is a single row in t2 that matches (t1.a=t2.b), but its + ** t2.c values is not NULL. If the (t2.c IS NULL) constraint is + ** pushed down to the cursor, this row is filtered out, causing + ** SQLite to synthesize a row of NULL values. Which does match the + ** WHERE clause, and so the query returns a row. Which is incorrect. + ** + ** For the same reason, WHERE terms such as: + ** + ** WHERE 1 = (t2.c IS NULL) + ** + ** are also excluded. See codeCursorHintIsOrFunction() for details. + */ + if( pTabItem->fg.jointype & JT_LEFT ){ + Expr *pExpr = pTerm->pExpr; + if( !ExprHasProperty(pExpr, EP_OuterON) + || pExpr->w.iJoin!=pTabItem->iCursor + ){ + sWalker.eCode = 0; + sWalker.xExprCallback = codeCursorHintIsOrFunction; + sqlite3WalkExpr(&sWalker, pTerm->pExpr); + if( sWalker.eCode ) continue; + } + }else{ + if( ExprHasProperty(pTerm->pExpr, EP_OuterON) ) continue; + } + + /* All terms in pWLoop->aLTerm[] except pEndRange are used to initialize + ** the cursor. These terms are not needed as hints for a pure range + ** scan (that has no == terms) so omit them. */ + if( pLoop->u.btree.nEq==0 && pTerm!=pEndRange ){ + for(j=0; jnLTerm && pLoop->aLTerm[j]!=pTerm; j++){} + if( jnLTerm ) continue; + } + + /* No subqueries or non-deterministic functions allowed */ + if( sqlite3ExprContainsSubquery(pTerm->pExpr) ) continue; + + /* For an index scan, make sure referenced columns are actually in + ** the index. */ + if( sHint.pIdx!=0 ){ + sWalker.eCode = 0; + sWalker.xExprCallback = codeCursorHintCheckExpr; + sqlite3WalkExpr(&sWalker, pTerm->pExpr); + if( sWalker.eCode ) continue; + } + + /* If we survive all prior tests, that means this term is worth hinting */ + pExpr = sqlite3ExprAnd(pParse, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0)); + } + if( pExpr!=0 ){ + sWalker.xExprCallback = codeCursorHintFixExpr; + if( pParse->nErr==0 ) sqlite3WalkExpr(&sWalker, pExpr); + sqlite3VdbeAddOp4(v, OP_CursorHint, + (sHint.pIdx ? sHint.iIdxCur : sHint.iTabCur), 0, 0, + (const char*)pExpr, P4_EXPR); + } +} +#else +# define codeCursorHint(A,B,C,D) /* No-op */ +#endif /* SQLITE_ENABLE_CURSOR_HINTS */ + +/* +** Cursor iCur is open on an intkey b-tree (a table). Register iRowid contains +** a rowid value just read from cursor iIdxCur, open on index pIdx. This +** function generates code to do a deferred seek of cursor iCur to the +** rowid stored in register iRowid. +** +** Normally, this is just: +** +** OP_DeferredSeek $iCur $iRowid +** +** Which causes a seek on $iCur to the row with rowid $iRowid. +** +** However, if the scan currently being coded is a branch of an OR-loop and +** the statement currently being coded is a SELECT, then additional information +** is added that might allow OP_Column to omit the seek and instead do its +** lookup on the index, thus avoiding an expensive seek operation. To +** enable this optimization, the P3 of OP_DeferredSeek is set to iIdxCur +** and P4 is set to an array of integers containing one entry for each column +** in the table. For each table column, if the column is the i'th +** column of the index, then the corresponding array entry is set to (i+1). +** If the column does not appear in the index at all, the array entry is set +** to 0. The OP_Column opcode can check this array to see if the column it +** wants is in the index and if it is, it will substitute the index cursor +** and column number and continue with those new values, rather than seeking +** the table cursor. +*/ +static void codeDeferredSeek( + WhereInfo *pWInfo, /* Where clause context */ + Index *pIdx, /* Index scan is using */ + int iCur, /* Cursor for IPK b-tree */ + int iIdxCur /* Index cursor */ +){ + Parse *pParse = pWInfo->pParse; /* Parse context */ + Vdbe *v = pParse->pVdbe; /* Vdbe to generate code within */ + + assert( iIdxCur>0 ); + assert( pIdx->aiColumn[pIdx->nColumn-1]==-1 ); + + pWInfo->bDeferredSeek = 1; + sqlite3VdbeAddOp3(v, OP_DeferredSeek, iIdxCur, 0, iCur); + if( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN)) + && DbMaskAllZero(sqlite3ParseToplevel(pParse)->writeMask) + ){ + int i; + Table *pTab = pIdx->pTable; + u32 *ai = (u32*)sqlite3DbMallocZero(pParse->db, sizeof(u32)*(pTab->nCol+1)); + if( ai ){ + ai[0] = pTab->nCol; + for(i=0; inColumn-1; i++){ + int x1, x2; + assert( pIdx->aiColumn[i]nCol ); + x1 = pIdx->aiColumn[i]; + x2 = sqlite3TableColumnToStorage(pTab, x1); + testcase( x1!=x2 ); + if( x1>=0 ) ai[x2+1] = i+1; + } + sqlite3VdbeChangeP4(v, -1, (char*)ai, P4_INTARRAY); + } + } +} + +/* +** If the expression passed as the second argument is a vector, generate +** code to write the first nReg elements of the vector into an array +** of registers starting with iReg. +** +** If the expression is not a vector, then nReg must be passed 1. In +** this case, generate code to evaluate the expression and leave the +** result in register iReg. +*/ +static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){ + assert( nReg>0 ); + if( p && sqlite3ExprIsVector(p) ){ +#ifndef SQLITE_OMIT_SUBQUERY + if( ExprUseXSelect(p) ){ + Vdbe *v = pParse->pVdbe; + int iSelect; + assert( p->op==TK_SELECT ); + iSelect = sqlite3CodeSubselect(pParse, p); + sqlite3VdbeAddOp3(v, OP_Copy, iSelect, iReg, nReg-1); + }else +#endif + { + int i; + const ExprList *pList; + assert( ExprUseXList(p) ); + pList = p->x.pList; + assert( nReg<=pList->nExpr ); + for(i=0; ia[i].pExpr, iReg+i); + } + } + }else{ + assert( nReg==1 || pParse->nErr ); + sqlite3ExprCode(pParse, p, iReg); + } +} + +/* +** The pTruth expression is always true because it is the WHERE clause +** a partial index that is driving a query loop. Look through all of the +** WHERE clause terms on the query, and if any of those terms must be +** true because pTruth is true, then mark those WHERE clause terms as +** coded. +*/ +static void whereApplyPartialIndexConstraints( + Expr *pTruth, + int iTabCur, + WhereClause *pWC +){ + int i; + WhereTerm *pTerm; + while( pTruth->op==TK_AND ){ + whereApplyPartialIndexConstraints(pTruth->pLeft, iTabCur, pWC); + pTruth = pTruth->pRight; + } + for(i=0, pTerm=pWC->a; inTerm; i++, pTerm++){ + Expr *pExpr; + if( pTerm->wtFlags & TERM_CODED ) continue; + pExpr = pTerm->pExpr; + if( sqlite3ExprCompare(0, pExpr, pTruth, iTabCur)==0 ){ + pTerm->wtFlags |= TERM_CODED; + } + } +} + +/* +** This routine is called right after An OP_Filter has been generated and +** before the corresponding index search has been performed. This routine +** checks to see if there are additional Bloom filters in inner loops that +** can be checked prior to doing the index lookup. If there are available +** inner-loop Bloom filters, then evaluate those filters now, before the +** index lookup. The idea is that a Bloom filter check is way faster than +** an index lookup, and the Bloom filter might return false, meaning that +** the index lookup can be skipped. +** +** We know that an inner loop uses a Bloom filter because it has the +** WhereLevel.regFilter set. If an inner-loop Bloom filter is checked, +** then clear the WhereLevel.regFilter value to prevent the Bloom filter +** from being checked a second time when the inner loop is evaluated. +*/ +static SQLITE_NOINLINE void filterPullDown( + Parse *pParse, /* Parsing context */ + WhereInfo *pWInfo, /* Complete information about the WHERE clause */ + int iLevel, /* Which level of pWInfo->a[] should be coded */ + int addrNxt, /* Jump here to bypass inner loops */ + Bitmask notReady /* Loops that are not ready */ +){ + int saved_addrBrk; + while( ++iLevel < pWInfo->nLevel ){ + WhereLevel *pLevel = &pWInfo->a[iLevel]; + WhereLoop *pLoop = pLevel->pWLoop; + if( pLevel->regFilter==0 ) continue; + if( pLevel->pWLoop->nSkip ) continue; + /* ,--- Because sqlite3ConstructBloomFilter() has will not have set + ** vvvvv--' pLevel->regFilter if this were true. */ + if( NEVER(pLoop->prereq & notReady) ) continue; + saved_addrBrk = pLevel->addrBrk; + pLevel->addrBrk = addrNxt; + if( pLoop->wsFlags & WHERE_IPK ){ + WhereTerm *pTerm = pLoop->aLTerm[0]; + int regRowid; + assert( pTerm!=0 ); + assert( pTerm->pExpr!=0 ); + testcase( pTerm->wtFlags & TERM_VIRTUAL ); + regRowid = sqlite3GetTempReg(pParse); + regRowid = codeEqualityTerm(pParse, pTerm, pLevel, 0, 0, regRowid); + sqlite3VdbeAddOp2(pParse->pVdbe, OP_MustBeInt, regRowid, addrNxt); + VdbeCoverage(pParse->pVdbe); + sqlite3VdbeAddOp4Int(pParse->pVdbe, OP_Filter, pLevel->regFilter, + addrNxt, regRowid, 1); + VdbeCoverage(pParse->pVdbe); + }else{ + u16 nEq = pLoop->u.btree.nEq; + int r1; + char *zStartAff; + + assert( pLoop->wsFlags & WHERE_INDEXED ); + assert( (pLoop->wsFlags & WHERE_COLUMN_IN)==0 ); + r1 = codeAllEqualityTerms(pParse,pLevel,0,0,&zStartAff); + codeApplyAffinity(pParse, r1, nEq, zStartAff); + sqlite3DbFree(pParse->db, zStartAff); + sqlite3VdbeAddOp4Int(pParse->pVdbe, OP_Filter, pLevel->regFilter, + addrNxt, r1, nEq); + VdbeCoverage(pParse->pVdbe); + } + pLevel->regFilter = 0; + pLevel->addrBrk = saved_addrBrk; + } +} + +/* +** Loop pLoop is a WHERE_INDEXED level that uses at least one IN(...) +** operator. Return true if level pLoop is guaranteed to visit only one +** row for each key generated for the index. +*/ +static int whereLoopIsOneRow(WhereLoop *pLoop){ + if( pLoop->u.btree.pIndex->onError + && pLoop->nSkip==0 + && pLoop->u.btree.nEq==pLoop->u.btree.pIndex->nKeyCol + ){ + int ii; + for(ii=0; iiu.btree.nEq; ii++){ + if( pLoop->aLTerm[ii]->eOperator & (WO_IS|WO_ISNULL) ){ + return 0; + } + } + return 1; + } + return 0; +} + +/* +** Generate code for the start of the iLevel-th loop in the WHERE clause +** implementation described by pWInfo. +*/ +SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( + Parse *pParse, /* Parsing context */ + Vdbe *v, /* Prepared statement under construction */ + WhereInfo *pWInfo, /* Complete information about the WHERE clause */ + int iLevel, /* Which level of pWInfo->a[] should be coded */ + WhereLevel *pLevel, /* The current level pointer */ + Bitmask notReady /* Which tables are currently available */ +){ + int j, k; /* Loop counters */ + int iCur; /* The VDBE cursor for the table */ + int addrNxt; /* Where to jump to continue with the next IN case */ + int bRev; /* True if we need to scan in reverse order */ + WhereLoop *pLoop; /* The WhereLoop object being coded */ + WhereClause *pWC; /* Decomposition of the entire WHERE clause */ + WhereTerm *pTerm; /* A WHERE clause term */ + sqlite3 *db; /* Database connection */ + SrcItem *pTabItem; /* FROM clause term being coded */ + int addrBrk; /* Jump here to break out of the loop */ + int addrCont; /* Jump here to continue with next cycle */ + int iRowidReg = 0; /* Rowid is stored in this register, if not zero */ + int iReleaseReg = 0; /* Temp register to free before returning */ + Index *pIdx = 0; /* Index used by loop (if any) */ + int iLoop; /* Iteration of constraint generator loop */ + + pWC = &pWInfo->sWC; + db = pParse->db; + pLoop = pLevel->pWLoop; + pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; + iCur = pTabItem->iCursor; + pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); + bRev = (pWInfo->revMask>>iLevel)&1; + VdbeModuleComment((v, "Begin WHERE-loop%d: %s", + iLevel, pTabItem->pSTab->zName)); +#if WHERETRACE_ENABLED /* 0x4001 */ + if( sqlite3WhereTrace & 0x1 ){ + sqlite3DebugPrintf("Coding level %d of %d: notReady=%llx iFrom=%d\n", + iLevel, pWInfo->nLevel, (u64)notReady, pLevel->iFrom); + if( sqlite3WhereTrace & 0x1000 ){ + sqlite3WhereLoopPrint(pLoop, pWC); + } + } + if( (sqlite3WhereTrace & 0x4001)==0x4001 ){ + if( iLevel==0 ){ + sqlite3DebugPrintf("WHERE clause being coded:\n"); + sqlite3TreeViewExpr(0, pWInfo->pWhere, 0); + } + sqlite3DebugPrintf("All WHERE-clause terms before coding:\n"); + sqlite3WhereClausePrint(pWC); + } +#endif + + /* Create labels for the "break" and "continue" instructions + ** for the current loop. Jump to addrBrk to break out of a loop. + ** Jump to cont to go immediately to the next iteration of the + ** loop. + ** + ** When there is an IN operator, we also have a "addrNxt" label that + ** means to continue with the next IN value combination. When + ** there are no IN operators in the constraints, the "addrNxt" label + ** is the same as "addrBrk". + */ + addrBrk = pLevel->addrNxt = pLevel->addrBrk; + addrCont = pLevel->addrCont = sqlite3VdbeMakeLabel(pParse); + + /* If this is the right table of a LEFT OUTER JOIN, allocate and + ** initialize a memory cell that records if this table matches any + ** row of the left table of the join. + */ + assert( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN)) + || pLevel->iFrom>0 || (pTabItem[0].fg.jointype & JT_LEFT)==0 + ); + if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){ + pLevel->iLeftJoin = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin); + VdbeComment((v, "init LEFT JOIN match flag")); + } + + /* Special case of a FROM clause subquery implemented as a co-routine */ + if( pTabItem->fg.viaCoroutine ){ + int regYield; + Subquery *pSubq; + assert( pTabItem->fg.isSubquery && pTabItem->u4.pSubq!=0 ); + pSubq = pTabItem->u4.pSubq; + regYield = pSubq->regReturn; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSubq->addrFillSub); + pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk); + VdbeCoverage(v); + VdbeComment((v, "next row of %s", pTabItem->pSTab->zName)); + pLevel->op = OP_Goto; + }else + +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){ + /* Case 1: The table is a virtual-table. Use the VFilter and VNext + ** to access the data. + */ + int iReg; /* P3 Value for OP_VFilter */ + int addrNotFound; + int nConstraint = pLoop->nLTerm; + + iReg = sqlite3GetTempRange(pParse, nConstraint+2); + addrNotFound = pLevel->addrBrk; + for(j=0; jaLTerm[j]; + if( NEVER(pTerm==0) ) continue; + if( pTerm->eOperator & WO_IN ){ + if( SMASKBIT32(j) & pLoop->u.vtab.mHandleIn ){ + int iTab = pParse->nTab++; + int iCache = ++pParse->nMem; + sqlite3CodeRhsOfIN(pParse, pTerm->pExpr, iTab, 0); + sqlite3VdbeAddOp3(v, OP_VInitIn, iTab, iTarget, iCache); + }else{ + codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget); + addrNotFound = pLevel->addrNxt; + } + }else{ + Expr *pRight = pTerm->pExpr->pRight; + codeExprOrVector(pParse, pRight, iTarget, 1); + if( pTerm->eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET + && pLoop->u.vtab.bOmitOffset + ){ + assert( pTerm->eOperator==WO_AUX ); + assert( pWInfo->pSelect!=0 ); + assert( pWInfo->pSelect->iOffset>0 ); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pWInfo->pSelect->iOffset); + VdbeComment((v,"Zero OFFSET counter")); + } + } + } + sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg); + sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1); + /* The instruction immediately prior to OP_VFilter must be an OP_Integer + ** that sets the "argc" value for xVFilter. This is necessary for + ** resolveP2() to work correctly. See tag-20250207a. */ + sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg, + pLoop->u.vtab.idxStr, + pLoop->u.vtab.needFree ? P4_DYNAMIC : P4_STATIC); + VdbeCoverage(v); + pLoop->u.vtab.needFree = 0; + /* An OOM inside of AddOp4(OP_VFilter) instruction above might have freed + ** the u.vtab.idxStr. NULL it out to prevent a use-after-free */ + if( db->mallocFailed ) pLoop->u.vtab.idxStr = 0; + pLevel->p1 = iCur; + pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext; + pLevel->p2 = sqlite3VdbeCurrentAddr(v); + assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 ); + + for(j=0; jaLTerm[j]; + if( j<16 && (pLoop->u.vtab.omitMask>>j)&1 ){ + disableTerm(pLevel, pTerm); + continue; + } + if( (pTerm->eOperator & WO_IN)!=0 + && (SMASKBIT32(j) & pLoop->u.vtab.mHandleIn)==0 + && !db->mallocFailed + ){ + Expr *pCompare; /* The comparison operator */ + Expr *pRight; /* RHS of the comparison */ + VdbeOp *pOp; /* Opcode to access the value of the IN constraint */ + int iIn; /* IN loop corresponding to the j-th constraint */ + + /* Reload the constraint value into reg[iReg+j+2]. The same value + ** was loaded into the same register prior to the OP_VFilter, but + ** the xFilter implementation might have changed the datatype or + ** encoding of the value in the register, so it *must* be reloaded. + */ + for(iIn=0; ALWAYS(iInu.in.nIn); iIn++){ + pOp = sqlite3VdbeGetOp(v, pLevel->u.in.aInLoop[iIn].addrInTop); + if( (pOp->opcode==OP_Column && pOp->p3==iReg+j+2) + || (pOp->opcode==OP_Rowid && pOp->p2==iReg+j+2) + ){ + testcase( pOp->opcode==OP_Rowid ); + sqlite3VdbeAddOp3(v, pOp->opcode, pOp->p1, pOp->p2, pOp->p3); + break; + } + } + + /* Generate code that will continue to the next row if + ** the IN constraint is not satisfied + */ + pCompare = sqlite3PExpr(pParse, TK_EQ, 0, 0); + if( !db->mallocFailed ){ + int iFld = pTerm->u.x.iField; + Expr *pLeft = pTerm->pExpr->pLeft; + assert( pLeft!=0 ); + if( iFld>0 ){ + assert( pLeft->op==TK_VECTOR ); + assert( ExprUseXList(pLeft) ); + assert( iFld<=pLeft->x.pList->nExpr ); + pCompare->pLeft = pLeft->x.pList->a[iFld-1].pExpr; + }else{ + pCompare->pLeft = pLeft; + } + pCompare->pRight = pRight = sqlite3Expr(db, TK_REGISTER, 0); + if( pRight ){ + pRight->iTable = iReg+j+2; + sqlite3ExprIfFalse( + pParse, pCompare, pLevel->addrCont, SQLITE_JUMPIFNULL + ); + } + pCompare->pLeft = 0; + } + sqlite3ExprDelete(db, pCompare); + } + } + + /* These registers need to be preserved in case there is an IN operator + ** loop. So we could deallocate the registers here (and potentially + ** reuse them later) if (pLoop->wsFlags & WHERE_IN_ABLE)==0. But it seems + ** simpler and safer to simply not reuse the registers. + ** + ** sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2); + */ + }else +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + + if( (pLoop->wsFlags & WHERE_IPK)!=0 + && (pLoop->wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_EQ))!=0 + ){ + /* Case 2: We can directly reference a single row using an + ** equality comparison against the ROWID field. Or + ** we reference multiple rows using a "rowid IN (...)" + ** construct. + */ + assert( pLoop->u.btree.nEq==1 ); + pTerm = pLoop->aLTerm[0]; + assert( pTerm!=0 ); + assert( pTerm->pExpr!=0 ); + testcase( pTerm->wtFlags & TERM_VIRTUAL ); + iReleaseReg = ++pParse->nMem; + iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg); + if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg); + addrNxt = pLevel->addrNxt; + if( pLevel->regFilter ){ + sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt); + VdbeCoverage(v); + sqlite3VdbeAddOp4Int(v, OP_Filter, pLevel->regFilter, addrNxt, + iRowidReg, 1); + VdbeCoverage(v); + filterPullDown(pParse, pWInfo, iLevel, addrNxt, notReady); + } + sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg); + VdbeCoverage(v); + pLevel->op = OP_Noop; + }else if( (pLoop->wsFlags & WHERE_IPK)!=0 + && (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0 + ){ + /* Case 3: We have an inequality comparison against the ROWID field. + */ + int testOp = OP_Noop; + int start; + int memEndValue = 0; + WhereTerm *pStart, *pEnd; + + j = 0; + pStart = pEnd = 0; + if( pLoop->wsFlags & WHERE_BTM_LIMIT ) pStart = pLoop->aLTerm[j++]; + if( pLoop->wsFlags & WHERE_TOP_LIMIT ) pEnd = pLoop->aLTerm[j++]; + assert( pStart!=0 || pEnd!=0 ); + if( bRev ){ + pTerm = pStart; + pStart = pEnd; + pEnd = pTerm; + } + codeCursorHint(pTabItem, pWInfo, pLevel, pEnd); + if( pStart ){ + Expr *pX; /* The expression that defines the start bound */ + int r1, rTemp; /* Registers for holding the start boundary */ + int op; /* Cursor seek operation */ + + /* The following constant maps TK_xx codes into corresponding + ** seek opcodes. It depends on a particular ordering of TK_xx + */ + const u8 aMoveOp[] = { + /* TK_GT */ OP_SeekGT, + /* TK_LE */ OP_SeekLE, + /* TK_LT */ OP_SeekLT, + /* TK_GE */ OP_SeekGE + }; + assert( TK_LE==TK_GT+1 ); /* Make sure the ordering.. */ + assert( TK_LT==TK_GT+2 ); /* ... of the TK_xx values... */ + assert( TK_GE==TK_GT+3 ); /* ... is correct. */ + + assert( (pStart->wtFlags & TERM_VNULL)==0 ); + testcase( pStart->wtFlags & TERM_VIRTUAL ); + pX = pStart->pExpr; + assert( pX!=0 ); + testcase( pStart->leftCursor!=iCur ); /* transitive constraints */ + if( sqlite3ExprIsVector(pX->pRight) ){ + r1 = rTemp = sqlite3GetTempReg(pParse); + codeExprOrVector(pParse, pX->pRight, r1, 1); + testcase( pX->op==TK_GT ); + testcase( pX->op==TK_GE ); + testcase( pX->op==TK_LT ); + testcase( pX->op==TK_LE ); + op = aMoveOp[((pX->op - TK_GT - 1) & 0x3) | 0x1]; + assert( pX->op!=TK_GT || op==OP_SeekGE ); + assert( pX->op!=TK_GE || op==OP_SeekGE ); + assert( pX->op!=TK_LT || op==OP_SeekLE ); + assert( pX->op!=TK_LE || op==OP_SeekLE ); + }else{ + r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp); + disableTerm(pLevel, pStart); + op = aMoveOp[(pX->op - TK_GT)]; + } + sqlite3VdbeAddOp3(v, op, iCur, addrBrk, r1); + VdbeComment((v, "pk")); + VdbeCoverageIf(v, pX->op==TK_GT); + VdbeCoverageIf(v, pX->op==TK_LE); + VdbeCoverageIf(v, pX->op==TK_LT); + VdbeCoverageIf(v, pX->op==TK_GE); + sqlite3ReleaseTempReg(pParse, rTemp); + }else{ + sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, pLevel->addrHalt); + VdbeCoverageIf(v, bRev==0); + VdbeCoverageIf(v, bRev!=0); + } + if( pEnd ){ + Expr *pX; + pX = pEnd->pExpr; + assert( pX!=0 ); + assert( (pEnd->wtFlags & TERM_VNULL)==0 ); + testcase( pEnd->leftCursor!=iCur ); /* Transitive constraints */ + testcase( pEnd->wtFlags & TERM_VIRTUAL ); + memEndValue = ++pParse->nMem; + codeExprOrVector(pParse, pX->pRight, memEndValue, 1); + if( 0==sqlite3ExprIsVector(pX->pRight) + && (pX->op==TK_LT || pX->op==TK_GT) + ){ + testOp = bRev ? OP_Le : OP_Ge; + }else{ + testOp = bRev ? OP_Lt : OP_Gt; + } + if( 0==sqlite3ExprIsVector(pX->pRight) ){ + disableTerm(pLevel, pEnd); + } + } + start = sqlite3VdbeCurrentAddr(v); + pLevel->op = bRev ? OP_Prev : OP_Next; + pLevel->p1 = iCur; + pLevel->p2 = start; + assert( pLevel->p5==0 ); + if( testOp!=OP_Noop ){ + iRowidReg = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg); + sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg); + VdbeCoverageIf(v, testOp==OP_Le); + VdbeCoverageIf(v, testOp==OP_Lt); + VdbeCoverageIf(v, testOp==OP_Ge); + VdbeCoverageIf(v, testOp==OP_Gt); + sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL); + } + }else if( pLoop->wsFlags & WHERE_INDEXED ){ + /* Case 4: Search using an index. + ** + ** The WHERE clause may contain zero or more equality + ** terms ("==" or "IN" or "IS" operators) that refer to the N + ** left-most columns of the index. It may also contain + ** inequality constraints (>, <, >= or <=) on the indexed + ** column that immediately follows the N equalities. Only + ** the right-most column can be an inequality - the rest must + ** use the "==", "IN", or "IS" operators. For example, if the + ** index is on (x,y,z), then the following clauses are all + ** optimized: + ** + ** x=5 + ** x=5 AND y=10 + ** x=5 AND y<10 + ** x=5 AND y>5 AND y<10 + ** x=5 AND y=5 AND z<=10 + ** + ** The z<10 term of the following cannot be used, only + ** the x=5 term: + ** + ** x=5 AND z<10 + ** + ** N may be zero if there are inequality constraints. + ** If there are no inequality constraints, then N is at + ** least one. + ** + ** This case is also used when there are no WHERE clause + ** constraints but an index is selected anyway, in order + ** to force the output order to conform to an ORDER BY. + */ + static const u8 aStartOp[] = { + 0, + 0, + OP_Rewind, /* 2: (!start_constraints && startEq && !bRev) */ + OP_Last, /* 3: (!start_constraints && startEq && bRev) */ + OP_SeekGT, /* 4: (start_constraints && !startEq && !bRev) */ + OP_SeekLT, /* 5: (start_constraints && !startEq && bRev) */ + OP_SeekGE, /* 6: (start_constraints && startEq && !bRev) */ + OP_SeekLE /* 7: (start_constraints && startEq && bRev) */ + }; + static const u8 aEndOp[] = { + OP_IdxGE, /* 0: (end_constraints && !bRev && !endEq) */ + OP_IdxGT, /* 1: (end_constraints && !bRev && endEq) */ + OP_IdxLE, /* 2: (end_constraints && bRev && !endEq) */ + OP_IdxLT, /* 3: (end_constraints && bRev && endEq) */ + }; + u16 nEq = pLoop->u.btree.nEq; /* Number of == or IN terms */ + u16 nBtm = pLoop->u.btree.nBtm; /* Length of BTM vector */ + u16 nTop = pLoop->u.btree.nTop; /* Length of TOP vector */ + int regBase; /* Base register holding constraint values */ + WhereTerm *pRangeStart = 0; /* Inequality constraint at range start */ + WhereTerm *pRangeEnd = 0; /* Inequality constraint at range end */ + int startEq; /* True if range start uses ==, >= or <= */ + int endEq; /* True if range end uses ==, >= or <= */ + int start_constraints; /* Start of range is constrained */ + int nConstraint; /* Number of constraint terms */ + int iIdxCur; /* The VDBE cursor for the index */ + int nExtraReg = 0; /* Number of extra registers needed */ + int op; /* Instruction opcode */ + char *zStartAff; /* Affinity for start of range constraint */ + char *zEndAff = 0; /* Affinity for end of range constraint */ + u8 bSeekPastNull = 0; /* True to seek past initial nulls */ + u8 bStopAtNull = 0; /* Add condition to terminate at NULLs */ + int omitTable; /* True if we use the index only */ + int regBignull = 0; /* big-null flag register */ + int addrSeekScan = 0; /* Opcode of the OP_SeekScan, if any */ + + pIdx = pLoop->u.btree.pIndex; + iIdxCur = pLevel->iIdxCur; + assert( nEq>=pLoop->nSkip ); + + /* Find any inequality constraint terms for the start and end + ** of the range. + */ + j = nEq; + if( pLoop->wsFlags & WHERE_BTM_LIMIT ){ + pRangeStart = pLoop->aLTerm[j++]; + nExtraReg = MAX(nExtraReg, pLoop->u.btree.nBtm); + /* Like optimization range constraints always occur in pairs */ + assert( (pRangeStart->wtFlags & TERM_LIKEOPT)==0 || + (pLoop->wsFlags & WHERE_TOP_LIMIT)!=0 ); + } + if( pLoop->wsFlags & WHERE_TOP_LIMIT ){ + pRangeEnd = pLoop->aLTerm[j++]; + nExtraReg = MAX(nExtraReg, pLoop->u.btree.nTop); +#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS + if( (pRangeEnd->wtFlags & TERM_LIKEOPT)!=0 ){ + assert( pRangeStart!=0 ); /* LIKE opt constraints */ + assert( pRangeStart->wtFlags & TERM_LIKEOPT ); /* occur in pairs */ + pLevel->iLikeRepCntr = (u32)++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 1, (int)pLevel->iLikeRepCntr); + VdbeComment((v, "LIKE loop counter")); + pLevel->addrLikeRep = sqlite3VdbeCurrentAddr(v); + /* iLikeRepCntr actually stores 2x the counter register number. The + ** bottom bit indicates whether the search order is ASC or DESC. */ + testcase( bRev ); + testcase( pIdx->aSortOrder[nEq]==SQLITE_SO_DESC ); + assert( (bRev & ~1)==0 ); + pLevel->iLikeRepCntr <<=1; + pLevel->iLikeRepCntr |= bRev ^ (pIdx->aSortOrder[nEq]==SQLITE_SO_DESC); + } +#endif + if( pRangeStart==0 ){ + j = pIdx->aiColumn[nEq]; + if( (j>=0 && pIdx->pTable->aCol[j].notNull==0) || j==XN_EXPR ){ + bSeekPastNull = 1; + } + } + } + assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 ); + + /* If the WHERE_BIGNULL_SORT flag is set, then index column nEq uses + ** a non-default "big-null" sort (either ASC NULLS LAST or DESC NULLS + ** FIRST). In both cases separate ordered scans are made of those + ** index entries for which the column is null and for those for which + ** it is not. For an ASC sort, the non-NULL entries are scanned first. + ** For DESC, NULL entries are scanned first. + */ + if( (pLoop->wsFlags & (WHERE_TOP_LIMIT|WHERE_BTM_LIMIT))==0 + && (pLoop->wsFlags & WHERE_BIGNULL_SORT)!=0 + ){ + assert( bSeekPastNull==0 && nExtraReg==0 && nBtm==0 && nTop==0 ); + assert( pRangeEnd==0 && pRangeStart==0 ); + testcase( pLoop->nSkip>0 ); + nExtraReg = 1; + bSeekPastNull = 1; + pLevel->regBignull = regBignull = ++pParse->nMem; + if( pLevel->iLeftJoin ){ + sqlite3VdbeAddOp2(v, OP_Integer, 0, regBignull); + } + pLevel->addrBignull = sqlite3VdbeMakeLabel(pParse); + } + + /* If we are doing a reverse order scan on an ascending index, or + ** a forward order scan on a descending index, interchange the + ** start and end terms (pRangeStart and pRangeEnd). + */ + if( (nEqnColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC)) ){ + SWAP(WhereTerm *, pRangeEnd, pRangeStart); + SWAP(u8, bSeekPastNull, bStopAtNull); + SWAP(u8, nBtm, nTop); + } + + if( iLevel>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)!=0 ){ + /* In case OP_SeekScan is used, ensure that the index cursor does not + ** point to a valid row for the first iteration of this loop. */ + sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur); + } + + /* Generate code to evaluate all constraint terms using == or IN + ** and store the values of those terms in an array of registers + ** starting at regBase. + */ + codeCursorHint(pTabItem, pWInfo, pLevel, pRangeEnd); + regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff); + assert( zStartAff==0 || sqlite3Strlen30(zStartAff)>=nEq ); + if( zStartAff && nTop ){ + zEndAff = sqlite3DbStrDup(db, &zStartAff[nEq]); + } + addrNxt = (regBignull ? pLevel->addrBignull : pLevel->addrNxt); + + testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 ); + testcase( pRangeStart && (pRangeStart->eOperator & WO_GE)!=0 ); + testcase( pRangeEnd && (pRangeEnd->eOperator & WO_LE)!=0 ); + testcase( pRangeEnd && (pRangeEnd->eOperator & WO_GE)!=0 ); + startEq = !pRangeStart || pRangeStart->eOperator & (WO_LE|WO_GE); + endEq = !pRangeEnd || pRangeEnd->eOperator & (WO_LE|WO_GE); + start_constraints = pRangeStart || nEq>0; + + /* Seek the index cursor to the start of the range. */ + nConstraint = nEq; + if( pRangeStart ){ + Expr *pRight = pRangeStart->pExpr->pRight; + codeExprOrVector(pParse, pRight, regBase+nEq, nBtm); + whereLikeOptimizationStringFixup(v, pLevel, pRangeStart); + if( (pRangeStart->wtFlags & TERM_VNULL)==0 + && sqlite3ExprCanBeNull(pRight) + ){ + sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt); + VdbeCoverage(v); + } + if( zStartAff ){ + updateRangeAffinityStr(pRight, nBtm, &zStartAff[nEq]); + } + nConstraint += nBtm; + testcase( pRangeStart->wtFlags & TERM_VIRTUAL ); + if( sqlite3ExprIsVector(pRight)==0 ){ + disableTerm(pLevel, pRangeStart); + }else{ + startEq = 1; + } + bSeekPastNull = 0; + }else if( bSeekPastNull ){ + startEq = 0; + sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); + start_constraints = 1; + nConstraint++; + }else if( regBignull ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); + start_constraints = 1; + nConstraint++; + } + codeApplyAffinity(pParse, regBase, nConstraint - bSeekPastNull, zStartAff); + if( pLoop->nSkip>0 && nConstraint==pLoop->nSkip ){ + /* The skip-scan logic inside the call to codeAllEqualityConstraints() + ** above has already left the cursor sitting on the correct row, + ** so no further seeking is needed */ + }else{ + if( regBignull ){ + sqlite3VdbeAddOp2(v, OP_Integer, 1, regBignull); + VdbeComment((v, "NULL-scan pass ctr")); + } + if( pLevel->regFilter ){ + sqlite3VdbeAddOp4Int(v, OP_Filter, pLevel->regFilter, addrNxt, + regBase, nEq); + VdbeCoverage(v); + filterPullDown(pParse, pWInfo, iLevel, addrNxt, notReady); + } + + op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev]; + assert( op!=0 ); + if( (pLoop->wsFlags & WHERE_IN_SEEKSCAN)!=0 && op==OP_SeekGE ){ + assert( regBignull==0 ); + /* TUNING: The OP_SeekScan opcode seeks to reduce the number + ** of expensive seek operations by replacing a single seek with + ** 1 or more step operations. The question is, how many steps + ** should we try before giving up and going with a seek. The cost + ** of a seek is proportional to the logarithm of the of the number + ** of entries in the tree, so basing the number of steps to try + ** on the estimated number of rows in the btree seems like a good + ** guess. */ + addrSeekScan = sqlite3VdbeAddOp1(v, OP_SeekScan, + (pIdx->aiRowLogEst[0]+9)/10); + if( pRangeStart || pRangeEnd ){ + sqlite3VdbeChangeP5(v, 1); + sqlite3VdbeChangeP2(v, addrSeekScan, sqlite3VdbeCurrentAddr(v)+1); + addrSeekScan = 0; + } + VdbeCoverage(v); + } + sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); + VdbeCoverage(v); + VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind ); + VdbeCoverageIf(v, op==OP_Last); testcase( op==OP_Last ); + VdbeCoverageIf(v, op==OP_SeekGT); testcase( op==OP_SeekGT ); + VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE ); + VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE ); + VdbeCoverageIf(v, op==OP_SeekLT); testcase( op==OP_SeekLT ); + + assert( bSeekPastNull==0 || bStopAtNull==0 ); + if( regBignull ){ + assert( bSeekPastNull==1 || bStopAtNull==1 ); + assert( bSeekPastNull==!bStopAtNull ); + assert( bStopAtNull==startEq ); + sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2); + op = aStartOp[(nConstraint>1)*4 + 2 + bRev]; + sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, + nConstraint-startEq); + VdbeCoverage(v); + VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind ); + VdbeCoverageIf(v, op==OP_Last); testcase( op==OP_Last ); + VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE ); + VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE ); + assert( op==OP_Rewind || op==OP_Last || op==OP_SeekGE || op==OP_SeekLE); + } + } + + /* Load the value for the inequality constraint at the end of the + ** range (if any). + */ + nConstraint = nEq; + assert( pLevel->p2==0 ); + if( pRangeEnd ){ + Expr *pRight = pRangeEnd->pExpr->pRight; + assert( addrSeekScan==0 ); + codeExprOrVector(pParse, pRight, regBase+nEq, nTop); + whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd); + if( (pRangeEnd->wtFlags & TERM_VNULL)==0 + && sqlite3ExprCanBeNull(pRight) + ){ + sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt); + VdbeCoverage(v); + } + if( zEndAff ){ + updateRangeAffinityStr(pRight, nTop, zEndAff); + codeApplyAffinity(pParse, regBase+nEq, nTop, zEndAff); + }else{ + assert( pParse->db->mallocFailed ); + } + nConstraint += nTop; + testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); + + if( sqlite3ExprIsVector(pRight)==0 ){ + disableTerm(pLevel, pRangeEnd); + }else{ + endEq = 1; + } + }else if( bStopAtNull ){ + if( regBignull==0 ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); + endEq = 0; + } + nConstraint++; + } + if( zStartAff ) sqlite3DbNNFreeNN(db, zStartAff); + if( zEndAff ) sqlite3DbNNFreeNN(db, zEndAff); + + /* Top of the loop body */ + pLevel->p2 = sqlite3VdbeCurrentAddr(v); + + /* Check if the index cursor is past the end of the range. */ + if( nConstraint ){ + if( regBignull ){ + /* Except, skip the end-of-range check while doing the NULL-scan */ + sqlite3VdbeAddOp2(v, OP_IfNot, regBignull, sqlite3VdbeCurrentAddr(v)+3); + VdbeComment((v, "If NULL-scan 2nd pass")); + VdbeCoverage(v); + } + op = aEndOp[bRev*2 + endEq]; + sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); + testcase( op==OP_IdxGT ); VdbeCoverageIf(v, op==OP_IdxGT ); + testcase( op==OP_IdxGE ); VdbeCoverageIf(v, op==OP_IdxGE ); + testcase( op==OP_IdxLT ); VdbeCoverageIf(v, op==OP_IdxLT ); + testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); + if( addrSeekScan ) sqlite3VdbeJumpHere(v, addrSeekScan); + } + if( regBignull ){ + /* During a NULL-scan, check to see if we have reached the end of + ** the NULLs */ + assert( bSeekPastNull==!bStopAtNull ); + assert( bSeekPastNull+bStopAtNull==1 ); + assert( nConstraint+bSeekPastNull>0 ); + sqlite3VdbeAddOp2(v, OP_If, regBignull, sqlite3VdbeCurrentAddr(v)+2); + VdbeComment((v, "If NULL-scan 1st pass")); + VdbeCoverage(v); + op = aEndOp[bRev*2 + bSeekPastNull]; + sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, + nConstraint+bSeekPastNull); + testcase( op==OP_IdxGT ); VdbeCoverageIf(v, op==OP_IdxGT ); + testcase( op==OP_IdxGE ); VdbeCoverageIf(v, op==OP_IdxGE ); + testcase( op==OP_IdxLT ); VdbeCoverageIf(v, op==OP_IdxLT ); + testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); + } + + if( (pLoop->wsFlags & WHERE_IN_EARLYOUT)!=0 ){ + sqlite3VdbeAddOp3(v, OP_SeekHit, iIdxCur, nEq, nEq); + } + + /* Seek the table cursor, if required */ + omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0 + && (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))==0; + if( omitTable ){ + /* pIdx is a covering index. No need to access the main table. */ + }else if( HasRowid(pIdx->pTable) ){ + codeDeferredSeek(pWInfo, pIdx, iCur, iIdxCur); + }else if( iCur!=iIdxCur ){ + Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable); + iRowidReg = sqlite3GetTempRange(pParse, pPk->nKeyCol); + for(j=0; jnKeyCol; j++){ + k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]); + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, iRowidReg+j); + } + sqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont, + iRowidReg, pPk->nKeyCol); VdbeCoverage(v); + } + + if( pLevel->iLeftJoin==0 ){ + /* If a partial index is driving the loop, try to eliminate WHERE clause + ** terms from the query that must be true due to the WHERE clause of + ** the partial index. This optimization does not work on an outer join, + ** as shown by: + ** + ** 2019-11-02 ticket 623eff57e76d45f6 (LEFT JOIN) + ** 2025-05-29 forum post 7dee41d32506c4ae (RIGHT JOIN) + */ + if( pIdx->pPartIdxWhere && pLevel->pRJ==0 ){ + whereApplyPartialIndexConstraints(pIdx->pPartIdxWhere, iCur, pWC); + } + }else{ + testcase( pIdx->pPartIdxWhere ); + /* The following assert() is not a requirement, merely an observation: + ** The OR-optimization doesn't work for the right hand table of + ** a LEFT JOIN: */ + assert( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))==0 ); + } + + /* Record the instruction used to terminate the loop. */ + if( (pLoop->wsFlags & WHERE_ONEROW) + || (pLevel->u.in.nIn && regBignull==0 && whereLoopIsOneRow(pLoop)) + ){ + pLevel->op = OP_Noop; + }else if( bRev ){ + pLevel->op = OP_Prev; + }else{ + pLevel->op = OP_Next; + } + pLevel->p1 = iIdxCur; + pLevel->p3 = (pLoop->wsFlags&WHERE_UNQ_WANTED)!=0 ? 1:0; + if( (pLoop->wsFlags & WHERE_CONSTRAINT)==0 ){ + pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; + }else{ + assert( pLevel->p5==0 ); + } + if( omitTable ) pIdx = 0; + }else + +#ifndef SQLITE_OMIT_OR_OPTIMIZATION + if( pLoop->wsFlags & WHERE_MULTI_OR ){ + /* Case 5: Two or more separately indexed terms connected by OR + ** + ** Example: + ** + ** CREATE TABLE t1(a,b,c,d); + ** CREATE INDEX i1 ON t1(a); + ** CREATE INDEX i2 ON t1(b); + ** CREATE INDEX i3 ON t1(c); + ** + ** SELECT * FROM t1 WHERE a=5 OR b=7 OR (c=11 AND d=13) + ** + ** In the example, there are three indexed terms connected by OR. + ** The top of the loop looks like this: + ** + ** Null 1 # Zero the rowset in reg 1 + ** + ** Then, for each indexed term, the following. The arguments to + ** RowSetTest are such that the rowid of the current row is inserted + ** into the RowSet. If it is already present, control skips the + ** Gosub opcode and jumps straight to the code generated by WhereEnd(). + ** + ** sqlite3WhereBegin() + ** RowSetTest # Insert rowid into rowset + ** Gosub 2 A + ** sqlite3WhereEnd() + ** + ** Following the above, code to terminate the loop. Label A, the target + ** of the Gosub above, jumps to the instruction right after the Goto. + ** + ** Null 1 # Zero the rowset in reg 1 + ** Goto B # The loop is finished. + ** + ** A: # Return data, whatever. + ** + ** Return 2 # Jump back to the Gosub + ** + ** B: + ** + ** Added 2014-05-26: If the table is a WITHOUT ROWID table, then + ** use an ephemeral index instead of a RowSet to record the primary + ** keys of the rows we have already seen. + ** + */ + WhereClause *pOrWc; /* The OR-clause broken out into subterms */ + SrcList *pOrTab; /* Shortened table list or OR-clause generation */ + Index *pCov = 0; /* Potential covering index (or NULL) */ + int iCovCur = pParse->nTab++; /* Cursor used for index scans (if any) */ + + int regReturn = ++pParse->nMem; /* Register used with OP_Gosub */ + int regRowset = 0; /* Register for RowSet object */ + int regRowid = 0; /* Register holding rowid */ + int iLoopBody = sqlite3VdbeMakeLabel(pParse);/* Start of loop body */ + int iRetInit; /* Address of regReturn init */ + int untestedTerms = 0; /* Some terms not completely tested */ + int ii; /* Loop counter */ + Expr *pAndExpr = 0; /* An ".. AND (...)" expression */ + Table *pTab = pTabItem->pSTab; + + pTerm = pLoop->aLTerm[0]; + assert( pTerm!=0 ); + assert( pTerm->eOperator & WO_OR ); + assert( (pTerm->wtFlags & TERM_ORINFO)!=0 ); + pOrWc = &pTerm->u.pOrInfo->wc; + pLevel->op = OP_Return; + pLevel->p1 = regReturn; + + /* Set up a new SrcList in pOrTab containing the table being scanned + ** by this loop in the a[0] slot and all notReady tables in a[1..] slots. + ** This becomes the SrcList in the recursive call to sqlite3WhereBegin(). + */ + if( pWInfo->nLevel>1 || pTabItem->fg.fromExists ){ + int nNotReady; /* The number of notReady tables */ + SrcItem *origSrc; /* Original list of tables */ + nNotReady = pWInfo->nLevel - iLevel - 1; + pOrTab = sqlite3DbMallocRawNN(db, SZ_SRCLIST(nNotReady+1)); + if( pOrTab==0 ) return notReady; + pOrTab->nAlloc = (u8)(nNotReady + 1); + pOrTab->nSrc = pOrTab->nAlloc; + memcpy(pOrTab->a, pTabItem, sizeof(*pTabItem)); + origSrc = pWInfo->pTabList->a; + for(k=1; k<=nNotReady; k++){ + memcpy(&pOrTab->a[k], &origSrc[pLevel[k].iFrom], sizeof(pOrTab->a[k])); + } + + /* Clear the fromExists flag on the OR-optimized table entry so that + ** the calls to sqlite3WhereEnd() do not code early-exits after the + ** first row is visited. The early exit applies to this table's + ** overall loop - including the multiple OR branches and any WHERE + ** conditions not passed to the sub-loops - not to the sub-loops. */ + pOrTab->a[0].fg.fromExists = 0; + }else{ + pOrTab = pWInfo->pTabList; + } + + /* Initialize the rowset register to contain NULL. An SQL NULL is + ** equivalent to an empty rowset. Or, create an ephemeral index + ** capable of holding primary keys in the case of a WITHOUT ROWID. + ** + ** Also initialize regReturn to contain the address of the instruction + ** immediately following the OP_Return at the bottom of the loop. This + ** is required in a few obscure LEFT JOIN cases where control jumps + ** over the top of the loop into the body of it. In this case the + ** correct response for the end-of-loop code (the OP_Return) is to + ** fall through to the next instruction, just as an OP_Next does if + ** called on an uninitialized cursor. + */ + if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ + if( HasRowid(pTab) ){ + regRowset = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset); + }else{ + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + regRowset = pParse->nTab++; + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, regRowset, pPk->nKeyCol); + sqlite3VdbeSetP4KeyInfo(pParse, pPk); + } + regRowid = ++pParse->nMem; + } + iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn); + + /* If the original WHERE clause is z of the form: (x1 OR x2 OR ...) AND y + ** Then for every term xN, evaluate as the subexpression: xN AND y + ** That way, terms in y that are factored into the disjunction will + ** be picked up by the recursive calls to sqlite3WhereBegin() below. + ** + ** Actually, each subexpression is converted to "xN AND w" where w is + ** the "interesting" terms of z - terms that did not originate in the + ** ON or USING clause of a LEFT JOIN, and terms that are usable as + ** indices. + ** + ** This optimization also only applies if the (x1 OR x2 OR ...) term + ** is not contained in the ON clause of a LEFT JOIN. + ** See ticket http://sqlite.org/src/info/f2369304e4 + ** + ** 2022-02-04: Do not push down slices of a row-value comparison. + ** In other words, "w" or "y" may not be a slice of a vector. Otherwise, + ** the initialization of the right-hand operand of the vector comparison + ** might not occur, or might occur only in an OR branch that is not + ** taken. dbsqlfuzz 80a9fade844b4fb43564efc972bcb2c68270f5d1. + ** + ** 2022-03-03: Do not push down expressions that involve subqueries. + ** The subquery might get coded as a subroutine. Any table-references + ** in the subquery might be resolved to index-references for the index on + ** the OR branch in which the subroutine is coded. But if the subroutine + ** is invoked from a different OR branch that uses a different index, such + ** index-references will not work. tag-20220303a + ** https://sqlite.org/forum/forumpost/36937b197273d403 + */ + if( pWC->nTerm>1 ){ + int iTerm; + for(iTerm=0; iTermnTerm; iTerm++){ + Expr *pExpr = pWC->a[iTerm].pExpr; + if( &pWC->a[iTerm] == pTerm ) continue; + testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL ); + testcase( pWC->a[iTerm].wtFlags & TERM_CODED ); + testcase( pWC->a[iTerm].wtFlags & TERM_SLICE ); + if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED|TERM_SLICE))!=0 ){ + continue; + } + if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue; + if( ExprHasProperty(pExpr, EP_Subquery) ) continue; /* tag-20220303a */ + pExpr = sqlite3ExprDup(db, pExpr, 0); + pAndExpr = sqlite3ExprAnd(pParse, pAndExpr, pExpr); + } + if( pAndExpr ){ + /* The extra 0x10000 bit on the opcode is masked off and does not + ** become part of the new Expr.op. However, it does make the + ** op==TK_AND comparison inside of sqlite3PExpr() false, and this + ** prevents sqlite3PExpr() from applying the AND short-circuit + ** optimization, which we do not want here. */ + pAndExpr = sqlite3PExpr(pParse, TK_AND|0x10000, 0, pAndExpr); + } + } + + /* Run a separate WHERE clause for each term of the OR clause. After + ** eliminating duplicates from other WHERE clauses, the action for each + ** sub-WHERE clause is to to invoke the main loop body as a subroutine. + */ + ExplainQueryPlan((pParse, 1, "MULTI-INDEX OR")); + for(ii=0; iinTerm; ii++){ + WhereTerm *pOrTerm = &pOrWc->a[ii]; + if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){ + WhereInfo *pSubWInfo; /* Info for single OR-term scan */ + Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */ + Expr *pDelete; /* Local copy of OR clause term */ + int jmp1 = 0; /* Address of jump operation */ + testcase( (pTabItem[0].fg.jointype & JT_LEFT)!=0 + && !ExprHasProperty(pOrExpr, EP_OuterON) + ); /* See TH3 vtab25.400 and ticket 614b25314c766238 */ + pDelete = pOrExpr = sqlite3ExprDup(db, pOrExpr, 0); + if( db->mallocFailed ){ + sqlite3ExprDelete(db, pDelete); + continue; + } + if( pAndExpr ){ + pAndExpr->pLeft = pOrExpr; + pOrExpr = pAndExpr; + } + /* Loop through table entries that match term pOrTerm. */ + ExplainQueryPlan((pParse, 1, "INDEX %d", ii+1)); + WHERETRACE(0xffffffff, ("Subplan for OR-clause:\n")); + pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, 0, + WHERE_OR_SUBCLAUSE, iCovCur); + assert( pSubWInfo || pParse->nErr ); + if( pSubWInfo ){ + WhereLoop *pSubLoop; + int addrExplain = sqlite3WhereExplainOneScan( + pParse, pOrTab, &pSubWInfo->a[0], 0 + ); + sqlite3WhereAddScanStatus(v, pOrTab, &pSubWInfo->a[0], addrExplain); + + /* This is the sub-WHERE clause body. First skip over + ** duplicate rows from prior sub-WHERE clauses, and record the + ** rowid (or PRIMARY KEY) for the current row so that the same + ** row will be skipped in subsequent sub-WHERE clauses. + */ + if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ + int iSet = ((ii==pOrWc->nTerm-1)?-1:ii); + if( HasRowid(pTab) ){ + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, regRowid); + jmp1 = sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, 0, + regRowid, iSet); + VdbeCoverage(v); + }else{ + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + int nPk = pPk->nKeyCol; + int iPk; + int r; + + /* Read the PK into an array of temp registers. */ + r = sqlite3GetTempRange(pParse, nPk); + for(iPk=0; iPkaiColumn[iPk]; + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+iPk); + } + + /* Check if the temp table already contains this key. If so, + ** the row has already been included in the result set and + ** can be ignored (by jumping past the Gosub below). Otherwise, + ** insert the key into the temp table and proceed with processing + ** the row. + ** + ** Use some of the same optimizations as OP_RowSetTest: If iSet + ** is zero, assume that the key cannot already be present in + ** the temp table. And if iSet is -1, assume that there is no + ** need to insert the key into the temp table, as it will never + ** be tested for. */ + if( iSet ){ + jmp1 = sqlite3VdbeAddOp4Int(v, OP_Found, regRowset, 0, r, nPk); + VdbeCoverage(v); + } + if( iSet>=0 ){ + sqlite3VdbeAddOp3(v, OP_MakeRecord, r, nPk, regRowid); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, regRowset, regRowid, + r, nPk); + if( iSet ) sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + } + + /* Release the array of temp registers */ + sqlite3ReleaseTempRange(pParse, r, nPk); + } + } + + /* Invoke the main loop body as a subroutine */ + sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody); + + /* Jump here (skipping the main loop body subroutine) if the + ** current sub-WHERE row is a duplicate from prior sub-WHEREs. */ + if( jmp1 ) sqlite3VdbeJumpHere(v, jmp1); + + /* The pSubWInfo->untestedTerms flag means that this OR term + ** contained one or more AND term from a notReady table. The + ** terms from the notReady table could not be tested and will + ** need to be tested later. + */ + if( pSubWInfo->untestedTerms ) untestedTerms = 1; + + /* If all of the OR-connected terms are optimized using the same + ** index, and the index is opened using the same cursor number + ** by each call to sqlite3WhereBegin() made by this loop, it may + ** be possible to use that index as a covering index. + ** + ** If the call to sqlite3WhereBegin() above resulted in a scan that + ** uses an index, and this is either the first OR-connected term + ** processed or the index is the same as that used by all previous + ** terms, set pCov to the candidate covering index. Otherwise, set + ** pCov to NULL to indicate that no candidate covering index will + ** be available. + */ + pSubLoop = pSubWInfo->a[0].pWLoop; + assert( (pSubLoop->wsFlags & WHERE_AUTO_INDEX)==0 ); + if( (pSubLoop->wsFlags & WHERE_INDEXED)!=0 + && (ii==0 || pSubLoop->u.btree.pIndex==pCov) + && (HasRowid(pTab) || !IsPrimaryKeyIndex(pSubLoop->u.btree.pIndex)) + ){ + assert( pSubWInfo->a[0].iIdxCur==iCovCur ); + pCov = pSubLoop->u.btree.pIndex; + }else{ + pCov = 0; + } + if( sqlite3WhereUsesDeferredSeek(pSubWInfo) ){ + pWInfo->bDeferredSeek = 1; + } + + /* Finish the loop through table entries that match term pOrTerm. */ + sqlite3WhereEnd(pSubWInfo); + ExplainQueryPlanPop(pParse); + } + sqlite3ExprDelete(db, pDelete); + } + } + ExplainQueryPlanPop(pParse); + assert( pLevel->pWLoop==pLoop ); + assert( (pLoop->wsFlags & WHERE_MULTI_OR)!=0 ); + assert( (pLoop->wsFlags & WHERE_IN_ABLE)==0 ); + pLevel->u.pCoveringIdx = pCov; + if( pCov ) pLevel->iIdxCur = iCovCur; + if( pAndExpr ){ + pAndExpr->pLeft = 0; + sqlite3ExprDelete(db, pAndExpr); + } + sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v)); + sqlite3VdbeGoto(v, pLevel->addrBrk); + sqlite3VdbeResolveLabel(v, iLoopBody); + + /* Set the P2 operand of the OP_Return opcode that will end the current + ** loop to point to this spot, which is the top of the next containing + ** loop. The byte-code formatter will use that P2 value as a hint to + ** indent everything in between the this point and the final OP_Return. + ** See tag-20220407a in vdbe.c and shell.c */ + assert( pLevel->op==OP_Return ); + pLevel->p2 = sqlite3VdbeCurrentAddr(v); + + if( pWInfo->pTabList!=pOrTab ){ sqlite3DbFreeNN(db, pOrTab); } + if( !untestedTerms ) disableTerm(pLevel, pTerm); + }else +#endif /* SQLITE_OMIT_OR_OPTIMIZATION */ + + { + /* Case 6: There is no usable index. We must do a complete + ** scan of the entire table. + */ + static const u8 aStep[] = { OP_Next, OP_Prev }; + static const u8 aStart[] = { OP_Rewind, OP_Last }; + assert( bRev==0 || bRev==1 ); + if( pTabItem->fg.isRecursive ){ + /* Tables marked isRecursive have only a single row that is stored in + ** a pseudo-cursor. No need to Rewind or Next such cursors. */ + pLevel->op = OP_Noop; + }else{ + codeCursorHint(pTabItem, pWInfo, pLevel, 0); + pLevel->op = aStep[bRev]; + pLevel->p1 = iCur; + pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev],iCur,pLevel->addrHalt); + VdbeCoverageIf(v, bRev==0); + VdbeCoverageIf(v, bRev!=0); + pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; + } + } + +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + pLevel->addrVisit = sqlite3VdbeCurrentAddr(v); +#endif + + /* Insert code to test every subexpression that can be completely + ** computed using the current set of tables. + ** + ** This loop may run between one and three times, depending on the + ** constraints to be generated. The value of stack variable iLoop + ** determines the constraints coded by each iteration, as follows: + ** + ** iLoop==1: Code only expressions that are entirely covered by pIdx. + ** iLoop==2: Code remaining expressions that do not contain correlated + ** sub-queries. + ** iLoop==3: Code all remaining expressions. + ** + ** An effort is made to skip unnecessary iterations of the loop. + ** + ** This optimization of causing simple query restrictions to occur before + ** more complex one is call the "push-down" optimization in MySQL. Here + ** in SQLite, the name is "MySQL push-down", since there is also another + ** totally unrelated optimization called "WHERE-clause push-down". + ** Sometimes the qualifier is omitted, resulting in an ambiguity, so beware. + */ + iLoop = (pIdx ? 1 : 2); + do{ + int iNext = 0; /* Next value for iLoop */ + for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){ + Expr *pE; + int skipLikeAddr = 0; + testcase( pTerm->wtFlags & TERM_VIRTUAL ); + testcase( pTerm->wtFlags & TERM_CODED ); + if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; + if( (pTerm->prereqAll & pLevel->notReady)!=0 ){ + testcase( pWInfo->untestedTerms==0 + && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 ); + pWInfo->untestedTerms = 1; + continue; + } + pE = pTerm->pExpr; + assert( pE!=0 ); + if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT) ){ + if( !ExprHasProperty(pE,EP_OuterON|EP_InnerON) ){ + /* Defer processing WHERE clause constraints until after outer + ** join processing. tag-20220513a */ + continue; + }else if( (pTabItem->fg.jointype & JT_LEFT)==JT_LEFT + && !ExprHasProperty(pE,EP_OuterON) ){ + continue; + }else{ + Bitmask m = sqlite3WhereGetMask(&pWInfo->sMaskSet, pE->w.iJoin); + if( m & pLevel->notReady ){ + /* An ON clause that is not ripe */ + continue; + } + } + } + if( iLoop==1 && !sqlite3ExprCoveredByIndex(pE, pLevel->iTabCur, pIdx) ){ + iNext = 2; + continue; + } + if( iLoop<3 && (pTerm->wtFlags & TERM_VARSELECT) ){ + if( iNext==0 ) iNext = 3; + continue; + } + + if( (pTerm->wtFlags & TERM_LIKECOND)!=0 ){ + /* If the TERM_LIKECOND flag is set, that means that the range search + ** is sufficient to guarantee that the LIKE operator is true, so we + ** can skip the call to the like(A,B) function. But this only works + ** for strings. So do not skip the call to the function on the pass + ** that compares BLOBs. */ +#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS + continue; +#else + u32 x = pLevel->iLikeRepCntr; + if( x>0 ){ + skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)?OP_IfNot:OP_If,(int)(x>>1)); + VdbeCoverageIf(v, (x&1)==1); + VdbeCoverageIf(v, (x&1)==0); + } +#endif + } +#ifdef WHERETRACE_ENABLED /* 0xffffffff */ + if( sqlite3WhereTrace ){ + VdbeNoopComment((v, "WhereTerm[%d] (%p) priority=%d", + pWC->nTerm-j, pTerm, iLoop)); + } + if( sqlite3WhereTrace & 0x4000 ){ + sqlite3DebugPrintf("Coding auxiliary constraint:\n"); + sqlite3WhereTermPrint(pTerm, pWC->nTerm-j); + } +#endif + sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL); + if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr); + pTerm->wtFlags |= TERM_CODED; + } + iLoop = iNext; + }while( iLoop>0 ); + + /* Insert code to test for implied constraints based on transitivity + ** of the "==" operator. + ** + ** Example: If the WHERE clause contains "t1.a=t2.b" and "t2.b=123" + ** and we are coding the t1 loop and the t2 loop has not yet coded, + ** then we cannot use the "t1.a=t2.b" constraint, but we can code + ** the implied "t1.a=123" constraint. + */ + for(pTerm=pWC->a, j=pWC->nBase; j>0; j--, pTerm++){ + Expr *pE, sEAlt; + WhereTerm *pAlt; + if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; + if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue; + if( (pTerm->eOperator & WO_EQUIV)==0 ) continue; + if( pTerm->leftCursor!=iCur ) continue; + if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT) ) continue; + pE = pTerm->pExpr; +#ifdef WHERETRACE_ENABLED /* 0x4001 */ + if( (sqlite3WhereTrace & 0x4001)==0x4001 ){ + sqlite3DebugPrintf("Coding transitive constraint:\n"); + sqlite3WhereTermPrint(pTerm, pWC->nTerm-j); + } +#endif + assert( !ExprHasProperty(pE, EP_OuterON) ); + assert( (pTerm->prereqRight & pLevel->notReady)!=0 ); + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); + pAlt = sqlite3WhereFindTerm(pWC, iCur, pTerm->u.x.leftColumn, notReady, + WO_EQ|WO_IN|WO_IS, 0); + if( pAlt==0 ) continue; + if( pAlt->wtFlags & (TERM_CODED) ) continue; + if( ExprHasProperty(pAlt->pExpr, EP_Collate) ) continue; + if( (pAlt->eOperator & WO_IN) + && ExprUseXSelect(pAlt->pExpr) + && (pAlt->pExpr->x.pSelect->pEList->nExpr>1) + ){ + continue; + } + testcase( pAlt->eOperator & WO_EQ ); + testcase( pAlt->eOperator & WO_IS ); + testcase( pAlt->eOperator & WO_IN ); + VdbeModuleComment((v, "begin transitive constraint")); + sEAlt = *pAlt->pExpr; + sEAlt.pLeft = pE->pLeft; + sqlite3ExprIfFalse(pParse, &sEAlt, addrCont, SQLITE_JUMPIFNULL); + pAlt->wtFlags |= TERM_CODED; + } + + /* For a RIGHT OUTER JOIN, record the fact that the current row has + ** been matched at least once. + */ + if( pLevel->pRJ ){ + Table *pTab; + int nPk; + int r; + int jmp1 = 0; + WhereRightJoin *pRJ = pLevel->pRJ; + + /* pTab is the right-hand table of the RIGHT JOIN. Generate code that + ** will record that the current row of that table has been matched at + ** least once. This is accomplished by storing the PK for the row in + ** both the iMatch index and the regBloom Bloom filter. + */ + pTab = pWInfo->pTabList->a[pLevel->iFrom].pSTab; + if( HasRowid(pTab) ){ + r = sqlite3GetTempRange(pParse, 2); + sqlite3ExprCodeGetColumnOfTable(v, pTab, pLevel->iTabCur, -1, r+1); + nPk = 1; + }else{ + int iPk; + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + nPk = pPk->nKeyCol; + r = sqlite3GetTempRange(pParse, nPk+1); + for(iPk=0; iPkaiColumn[iPk]; + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+1+iPk); + } + } + jmp1 = sqlite3VdbeAddOp4Int(v, OP_Found, pRJ->iMatch, 0, r+1, nPk); + VdbeCoverage(v); + VdbeComment((v, "match against %s", pTab->zName)); + sqlite3VdbeAddOp3(v, OP_MakeRecord, r+1, nPk, r); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pRJ->iMatch, r, r+1, nPk); + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pRJ->regBloom, 0, r+1, nPk); + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + sqlite3VdbeJumpHere(v, jmp1); + sqlite3ReleaseTempRange(pParse, r, nPk+1); + } + + /* For a LEFT OUTER JOIN, generate code that will record the fact that + ** at least one row of the right table has matched the left table. + */ + if( pLevel->iLeftJoin ){ + pLevel->addrFirst = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin); + VdbeComment((v, "record LEFT JOIN hit")); + if( pLevel->pRJ==0 ){ + goto code_outer_join_constraints; /* WHERE clause constraints */ + } + } + + if( pLevel->pRJ ){ + /* Create a subroutine used to process all interior loops and code + ** of the RIGHT JOIN. During normal operation, the subroutine will + ** be in-line with the rest of the code. But at the end, a separate + ** loop will run that invokes this subroutine for unmatched rows + ** of pTab, with all tables to left begin set to NULL. + */ + WhereRightJoin *pRJ = pLevel->pRJ; + sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pRJ->regReturn); + pRJ->addrSubrtn = sqlite3VdbeCurrentAddr(v); + assert( pParse->withinRJSubrtn < 255 ); + pParse->withinRJSubrtn++; + + /* WHERE clause constraints must be deferred until after outer join + ** row elimination has completed, since WHERE clause constraints apply + ** to the results of the OUTER JOIN. The following loop generates the + ** appropriate WHERE clause constraint checks. tag-20220513a. + */ + code_outer_join_constraints: + for(pTerm=pWC->a, j=0; jnBase; j++, pTerm++){ + testcase( pTerm->wtFlags & TERM_VIRTUAL ); + testcase( pTerm->wtFlags & TERM_CODED ); + if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; + if( (pTerm->prereqAll & pLevel->notReady)!=0 ){ + assert( pWInfo->untestedTerms ); + continue; + } + if( pTabItem->fg.jointype & JT_LTORJ ) continue; + assert( pTerm->pExpr ); + sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); + pTerm->wtFlags |= TERM_CODED; + } + } + +#if WHERETRACE_ENABLED /* 0x4001 */ + if( sqlite3WhereTrace & 0x4000 ){ + sqlite3DebugPrintf("All WHERE-clause terms after coding level %d:\n", + iLevel); + sqlite3WhereClausePrint(pWC); + } + if( sqlite3WhereTrace & 0x1 ){ + sqlite3DebugPrintf("End Coding level %d: notReady=%llx\n", + iLevel, (u64)pLevel->notReady); + } +#endif + return pLevel->notReady; +} + +/* +** Generate the code for the loop that finds all non-matched terms +** for a RIGHT JOIN. +*/ +SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( + WhereInfo *pWInfo, + int iLevel, + WhereLevel *pLevel +){ + Parse *pParse = pWInfo->pParse; + Vdbe *v = pParse->pVdbe; + WhereRightJoin *pRJ = pLevel->pRJ; + Expr *pSubWhere = 0; + WhereClause *pWC = &pWInfo->sWC; + WhereInfo *pSubWInfo; + WhereLoop *pLoop = pLevel->pWLoop; + SrcItem *pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; + SrcList *pFrom; + union { + SrcList sSrc; + u8 fromSpace[SZ_SRCLIST_1]; + } uSrc; + Bitmask mAll = 0; + int k; + + ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pSTab->zName)); + sqlite3VdbeNoJumpsOutsideSubrtn(v, pRJ->addrSubrtn, pRJ->endSubrtn, + pRJ->regReturn); + for(k=0; ka[k].pWLoop->iTab == pWInfo->a[k].iFrom ); + pRight = &pWInfo->pTabList->a[pWInfo->a[k].iFrom]; + mAll |= pWInfo->a[k].pWLoop->maskSelf; + if( pRight->fg.viaCoroutine ){ + Subquery *pSubq; + assert( pRight->fg.isSubquery && pRight->u4.pSubq!=0 ); + pSubq = pRight->u4.pSubq; + assert( pSubq->pSelect!=0 && pSubq->pSelect->pEList!=0 ); + sqlite3VdbeAddOp3( + v, OP_Null, 0, pSubq->regResult, + pSubq->regResult + pSubq->pSelect->pEList->nExpr-1 + ); + } + sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur); + iIdxCur = pWInfo->a[k].iIdxCur; + if( iIdxCur ){ + sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur); + } + } + if( (pTabItem->fg.jointype & JT_LTORJ)==0 ){ + mAll |= pLoop->maskSelf; + for(k=0; knTerm; k++){ + WhereTerm *pTerm = &pWC->a[k]; + if( (pTerm->wtFlags & (TERM_VIRTUAL|TERM_SLICE))!=0 + && pTerm->eOperator!=WO_ROWVAL + ){ + break; + } + if( pTerm->prereqAll & ~mAll ) continue; + if( ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON) ) continue; + pSubWhere = sqlite3ExprAnd(pParse, pSubWhere, + sqlite3ExprDup(pParse->db, pTerm->pExpr, 0)); + } + } + if( pLevel->iIdxCur ){ + /* pSubWhere may contain expressions that read from an index on the + ** table on the RHS of the right join. All such expressions first test + ** if the index is pointing at a NULL row, and if so, read from the + ** table cursor instead. So ensure that the index cursor really is + ** pointing at a NULL row here, so that no values are read from it during + ** the scan of the RHS of the RIGHT join below. */ + sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur); + } + pFrom = &uSrc.sSrc; + pFrom->nSrc = 1; + pFrom->nAlloc = 1; + memcpy(&pFrom->a[0], pTabItem, sizeof(SrcItem)); + pFrom->a[0].fg.jointype = 0; + assert( pParse->withinRJSubrtn < 100 ); + pParse->withinRJSubrtn++; + pSubWInfo = sqlite3WhereBegin(pParse, pFrom, pSubWhere, 0, 0, 0, + WHERE_RIGHT_JOIN, 0); + if( pSubWInfo ){ + int iCur = pLevel->iTabCur; + int r = ++pParse->nMem; + int nPk; + int jmp; + int addrCont = sqlite3WhereContinueLabel(pSubWInfo); + Table *pTab = pTabItem->pSTab; + if( HasRowid(pTab) ){ + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, r); + nPk = 1; + }else{ + int iPk; + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + nPk = pPk->nKeyCol; + pParse->nMem += nPk - 1; + for(iPk=0; iPkaiColumn[iPk]; + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+iPk); + } + } + jmp = sqlite3VdbeAddOp4Int(v, OP_Filter, pRJ->regBloom, 0, r, nPk); + VdbeCoverage(v); + sqlite3VdbeAddOp4Int(v, OP_Found, pRJ->iMatch, addrCont, r, nPk); + VdbeCoverage(v); + sqlite3VdbeJumpHere(v, jmp); + sqlite3VdbeAddOp2(v, OP_Gosub, pRJ->regReturn, pRJ->addrSubrtn); + sqlite3WhereEnd(pSubWInfo); + } + sqlite3ExprDelete(pParse->db, pSubWhere); + ExplainQueryPlanPop(pParse); + assert( pParse->withinRJSubrtn>0 ); + pParse->withinRJSubrtn--; +} + +/************** End of wherecode.c *******************************************/ +/************** Begin file whereexpr.c ***************************************/ +/* +** 2015-06-08 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This module contains C code that generates VDBE code used to process +** the WHERE clause of SQL statements. +** +** This file was originally part of where.c but was split out to improve +** readability and editability. This file contains utility routines for +** analyzing Expr objects in the WHERE clause. +*/ +/* #include "sqliteInt.h" */ +/* #include "whereInt.h" */ + +/* Forward declarations */ +static void exprAnalyze(SrcList*, WhereClause*, int); + +/* +** Deallocate all memory associated with a WhereOrInfo object. +*/ +static void whereOrInfoDelete(sqlite3 *db, WhereOrInfo *p){ + sqlite3WhereClauseClear(&p->wc); + sqlite3DbFree(db, p); +} + +/* +** Deallocate all memory associated with a WhereAndInfo object. +*/ +static void whereAndInfoDelete(sqlite3 *db, WhereAndInfo *p){ + sqlite3WhereClauseClear(&p->wc); + sqlite3DbFree(db, p); +} + +/* +** Add a single new WhereTerm entry to the WhereClause object pWC. +** The new WhereTerm object is constructed from Expr p and with wtFlags. +** The index in pWC->a[] of the new WhereTerm is returned on success. +** 0 is returned if the new WhereTerm could not be added due to a memory +** allocation error. The memory allocation failure will be recorded in +** the db->mallocFailed flag so that higher-level functions can detect it. +** +** This routine will increase the size of the pWC->a[] array as necessary. +** +** If the wtFlags argument includes TERM_DYNAMIC, then responsibility +** for freeing the expression p is assumed by the WhereClause object pWC. +** This is true even if this routine fails to allocate a new WhereTerm. +** +** WARNING: This routine might reallocate the space used to store +** WhereTerms. All pointers to WhereTerms should be invalidated after +** calling this routine. Such pointers may be reinitialized by referencing +** the pWC->a[] array. +*/ +static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){ + WhereTerm *pTerm; + int idx; + testcase( wtFlags & TERM_VIRTUAL ); + if( pWC->nTerm>=pWC->nSlot ){ + WhereTerm *pOld = pWC->a; + sqlite3 *db = pWC->pWInfo->pParse->db; + pWC->a = sqlite3WhereMalloc(pWC->pWInfo, sizeof(pWC->a[0])*pWC->nSlot*2 ); + if( pWC->a==0 ){ + if( wtFlags & TERM_DYNAMIC ){ + sqlite3ExprDelete(db, p); + } + pWC->a = pOld; + return 0; + } + memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm); + pWC->nSlot = pWC->nSlot*2; + } + pTerm = &pWC->a[idx = pWC->nTerm++]; + if( (wtFlags & TERM_VIRTUAL)==0 ) pWC->nBase = pWC->nTerm; + if( p && ExprHasProperty(p, EP_Unlikely) ){ + pTerm->truthProb = sqlite3LogEst(p->iTable) - 270; + }else{ + pTerm->truthProb = 1; + } + pTerm->pExpr = sqlite3ExprSkipCollateAndLikely(p); + pTerm->wtFlags = wtFlags; + pTerm->pWC = pWC; + pTerm->iParent = -1; + memset(&pTerm->eOperator, 0, + sizeof(WhereTerm) - offsetof(WhereTerm,eOperator)); + return idx; +} + +/* +** Return TRUE if the given operator is one of the operators that is +** allowed for an indexable WHERE clause term. The allowed operators are +** "=", "<", ">", "<=", ">=", "IN", "IS", and "IS NULL" +*/ +static int allowedOp(int op){ + assert( TK_GT>TK_EQ && TK_GTTK_EQ && TK_LTTK_EQ && TK_LETK_GE ) return 0; + if( op>=TK_EQ ) return 1; + return op==TK_IN || op==TK_ISNULL || op==TK_IS; +} + +/* +** Commute a comparison operator. Expressions of the form "X op Y" +** are converted into "Y op X". +*/ +static u16 exprCommute(Parse *pParse, Expr *pExpr){ + if( pExpr->pLeft->op==TK_VECTOR + || pExpr->pRight->op==TK_VECTOR + || sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight) != + sqlite3BinaryCompareCollSeq(pParse, pExpr->pRight, pExpr->pLeft) + ){ + pExpr->flags ^= EP_Commuted; + } + SWAP(Expr*,pExpr->pRight,pExpr->pLeft); + if( pExpr->op>=TK_GT ){ + assert( TK_LT==TK_GT+2 ); + assert( TK_GE==TK_LE+2 ); + assert( TK_GT>TK_EQ ); + assert( TK_GTop>=TK_GT && pExpr->op<=TK_GE ); + pExpr->op = ((pExpr->op-TK_GT)^2)+TK_GT; + } + return 0; +} + +/* +** Translate from TK_xx operator to WO_xx bitmask. +*/ +static u16 operatorMask(int op){ + u16 c; + assert( allowedOp(op) ); + if( op>=TK_EQ ){ + assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff ); + c = (u16)(WO_EQ<<(op-TK_EQ)); + }else if( op==TK_IN ){ + c = WO_IN; + }else if( op==TK_ISNULL ){ + c = WO_ISNULL; + }else{ + assert( op==TK_IS ); + c = WO_IS; + } + assert( op!=TK_ISNULL || c==WO_ISNULL ); + assert( op!=TK_IN || c==WO_IN ); + assert( op!=TK_EQ || c==WO_EQ ); + assert( op!=TK_LT || c==WO_LT ); + assert( op!=TK_LE || c==WO_LE ); + assert( op!=TK_GT || c==WO_GT ); + assert( op!=TK_GE || c==WO_GE ); + assert( op!=TK_IS || c==WO_IS ); + return c; +} + + +#ifndef SQLITE_OMIT_LIKE_OPTIMIZATION +/* +** Check to see if the given expression is a LIKE or GLOB operator that +** can be optimized using inequality constraints. Return TRUE if it is +** so and false if not. +** +** In order for the operator to be optimizible, the RHS must be a string +** literal that does not begin with a wildcard. The LHS must be a column +** that may only be NULL, a string, or a BLOB, never a number. (This means +** that virtual tables cannot participate in the LIKE optimization.) The +** collating sequence for the column on the LHS must be appropriate for +** the operator. +*/ +static int isLikeOrGlob( + Parse *pParse, /* Parsing and code generating context */ + Expr *pExpr, /* Test this expression */ + Expr **ppPrefix, /* Pointer to TK_STRING expression with pattern prefix */ + int *pisComplete, /* True if the only wildcard is % in the last character */ + int *pnoCase /* True if uppercase is equivalent to lowercase */ +){ + const u8 *z = 0; /* String on RHS of LIKE operator */ + Expr *pRight, *pLeft; /* Right and left size of LIKE operator */ + ExprList *pList; /* List of operands to the LIKE operator */ + u8 c; /* One character in z[] */ + int cnt; /* Number of non-wildcard prefix characters */ + u8 wc[4]; /* Wildcard characters */ + sqlite3 *db = pParse->db; /* Database connection */ + sqlite3_value *pVal = 0; + int op; /* Opcode of pRight */ + int rc; /* Result code to return */ + + if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, (char*)wc) ){ + return 0; + } +#ifdef SQLITE_EBCDIC + if( *pnoCase ) return 0; +#endif + assert( ExprUseXList(pExpr) ); + pList = pExpr->x.pList; + pLeft = pList->a[1].pExpr; + + pRight = sqlite3ExprSkipCollate(pList->a[0].pExpr); + op = pRight->op; + if( op==TK_VARIABLE && (db->flags & SQLITE_EnableQPSG)==0 ){ + Vdbe *pReprepare = pParse->pReprepare; + int iCol = pRight->iColumn; + pVal = sqlite3VdbeGetBoundValue(pReprepare, iCol, SQLITE_AFF_BLOB); + if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){ + z = sqlite3_value_text(pVal); + } + sqlite3VdbeSetVarmask(pParse->pVdbe, iCol); + assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER ); + }else if( op==TK_STRING ){ + assert( !ExprHasProperty(pRight, EP_IntValue) ); + z = (u8*)pRight->u.zToken; + } + if( z ){ + /* Count the number of prefix bytes prior to the first wildcard, + ** U+fffd character, or malformed utf-8. If the underlying database + ** has a UTF16LE encoding, then only consider ASCII characters. Note that + ** the encoding of z[] is UTF8 - we are dealing with only UTF8 here in this + ** code, but the database engine itself might be processing content using a + ** different encoding. */ + cnt = 0; + while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){ + cnt++; + if( c==wc[3] && z[cnt]>0 && z[cnt]<0x80 ){ + cnt++; + }else if( c>=0x80 ){ + const u8 *z2 = z+cnt-1; + if( c==0xff || sqlite3Utf8Read(&z2)==0xfffd /* bad utf-8 */ + || ENC(db)==SQLITE_UTF16LE + ){ + cnt--; + break; + }else{ + cnt = (int)(z2-z); + } + } + } + + /* The optimization is possible only if (1) the pattern does not begin + ** with a wildcard and if (2) the non-wildcard prefix does not end with + ** an (illegal 0xff) character, or (3) the pattern does not consist of + ** a single escape character. The second condition is necessary so + ** that we can increment the prefix key to find an upper bound for the + ** range search. The third is because the caller assumes that the pattern + ** consists of at least one character after all escapes have been + ** removed. */ + if( (cnt>1 || (cnt>0 && z[0]!=wc[3])) && ALWAYS(255!=(u8)z[cnt-1]) ){ + Expr *pPrefix; + + /* A "complete" match if the pattern ends with "*" or "%" */ + *pisComplete = c==wc[0] && z[cnt+1]==0 && ENC(db)!=SQLITE_UTF16LE; + + /* Get the pattern prefix. Remove all escapes from the prefix. */ + pPrefix = sqlite3Expr(db, TK_STRING, (char*)z); + if( pPrefix ){ + int iFrom, iTo; + char *zNew; + assert( !ExprHasProperty(pPrefix, EP_IntValue) ); + zNew = pPrefix->u.zToken; + zNew[cnt] = 0; + for(iFrom=iTo=0; iFrom0 ); + + /* If the LHS is not an ordinary column with TEXT affinity, then the + ** pattern prefix boundaries (both the start and end boundaries) must + ** not look like a number. Otherwise the pattern might be treated as + ** a number, which will invalidate the LIKE optimization. + ** + ** Getting this right has been a persistent source of bugs in the + ** LIKE optimization. See, for example: + ** 2018-09-10 https://sqlite.org/src/info/c94369cae9b561b1 + ** 2019-05-02 https://sqlite.org/src/info/b043a54c3de54b28 + ** 2019-06-10 https://sqlite.org/src/info/fd76310a5e843e07 + ** 2019-06-14 https://sqlite.org/src/info/ce8717f0885af975 + ** 2019-09-03 https://sqlite.org/src/info/0f0428096f17252a + */ + if( pLeft->op!=TK_COLUMN + || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT + || (ALWAYS( ExprUseYTab(pLeft) ) + && ALWAYS(pLeft->y.pTab) + && IsVirtual(pLeft->y.pTab)) /* Might be numeric */ + ){ + int isNum; + double rDummy; + assert( zNew[iTo]==0 ); + isNum = sqlite3AtoF(zNew, &rDummy); + if( isNum<=0 ){ + if( iTo==1 && zNew[0]=='-' ){ + isNum = +1; + }else{ + zNew[iTo-1]++; + isNum = sqlite3AtoF(zNew, &rDummy); + zNew[iTo-1]--; + } + } + if( isNum>0 ){ + sqlite3ExprDelete(db, pPrefix); + sqlite3ValueFree(pVal); + return 0; + } + } + } + *ppPrefix = pPrefix; + + /* If the RHS pattern is a bound parameter, make arrangements to + ** reprepare the statement when that parameter is rebound */ + if( op==TK_VARIABLE ){ + Vdbe *v = pParse->pVdbe; + sqlite3VdbeSetVarmask(v, pRight->iColumn); + assert( !ExprHasProperty(pRight, EP_IntValue) ); + if( *pisComplete && pRight->u.zToken[1] ){ + /* If the rhs of the LIKE expression is a variable, and the current + ** value of the variable means there is no need to invoke the LIKE + ** function, then no OP_Variable will be added to the program. + ** This causes problems for the sqlite3_bind_parameter_name() + ** API. To work around them, add a dummy OP_Variable here. + */ + int r1 = sqlite3GetTempReg(pParse); + sqlite3ExprCodeTarget(pParse, pRight, r1); + sqlite3VdbeChangeP3(v, sqlite3VdbeCurrentAddr(v)-1, 0); + sqlite3ReleaseTempReg(pParse, r1); + } + } + }else{ + z = 0; + } + } + + rc = (z!=0); + sqlite3ValueFree(pVal); + return rc; +} +#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */ + +/* +** If pExpr is one of "like", "glob", "match", or "regexp", then +** return the corresponding SQLITE_INDEX_CONSTRAINT_xxxx value. +** If not, return 0. +** +** pExpr is guaranteed to be a TK_FUNCTION. +*/ +SQLITE_PRIVATE int sqlite3ExprIsLikeOperator(const Expr *pExpr){ + static const struct { + const char *zOp; + unsigned char eOp; + } aOp[] = { + { "match", SQLITE_INDEX_CONSTRAINT_MATCH }, + { "glob", SQLITE_INDEX_CONSTRAINT_GLOB }, + { "like", SQLITE_INDEX_CONSTRAINT_LIKE }, + { "regexp", SQLITE_INDEX_CONSTRAINT_REGEXP } + }; + int i; + assert( pExpr->op==TK_FUNCTION ); + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + for(i=0; iu.zToken, aOp[i].zOp)==0 ){ + return aOp[i].eOp; + } + } + return 0; +} + + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Check to see if the pExpr expression is a form that needs to be passed +** to the xBestIndex method of virtual tables. Forms of interest include: +** +** Expression Virtual Table Operator +** ----------------------- --------------------------------- +** 1. column MATCH expr SQLITE_INDEX_CONSTRAINT_MATCH +** 2. column GLOB expr SQLITE_INDEX_CONSTRAINT_GLOB +** 3. column LIKE expr SQLITE_INDEX_CONSTRAINT_LIKE +** 4. column REGEXP expr SQLITE_INDEX_CONSTRAINT_REGEXP +** 5. column != expr SQLITE_INDEX_CONSTRAINT_NE +** 6. expr != column SQLITE_INDEX_CONSTRAINT_NE +** 7. column IS NOT expr SQLITE_INDEX_CONSTRAINT_ISNOT +** 8. expr IS NOT column SQLITE_INDEX_CONSTRAINT_ISNOT +** 9. column IS NOT NULL SQLITE_INDEX_CONSTRAINT_ISNOTNULL +** +** In every case, "column" must be a column of a virtual table. If there +** is a match, set *ppLeft to the "column" expression, set *ppRight to the +** "expr" expression (even though in forms (6) and (8) the column is on the +** right and the expression is on the left). Also set *peOp2 to the +** appropriate virtual table operator. The return value is 1 or 2 if there +** is a match. The usual return is 1, but if the RHS is also a column +** of virtual table in forms (5) or (7) then return 2. +** +** If the expression matches none of the patterns above, return 0. +*/ +static int isAuxiliaryVtabOperator( + sqlite3 *db, /* Parsing context */ + Expr *pExpr, /* Test this expression */ + unsigned char *peOp2, /* OUT: 0 for MATCH, or else an op2 value */ + Expr **ppLeft, /* Column expression to left of MATCH/op2 */ + Expr **ppRight /* Expression to left of MATCH/op2 */ +){ + if( pExpr->op==TK_FUNCTION ){ + ExprList *pList; + Expr *pCol; /* Column reference */ + int i; + + assert( ExprUseXList(pExpr) ); + pList = pExpr->x.pList; + if( pList==0 || pList->nExpr!=2 ){ + return 0; + } + + /* Built-in operators MATCH, GLOB, LIKE, and REGEXP attach to a + ** virtual table on their second argument, which is the same as + ** the left-hand side operand in their in-fix form. + ** + ** vtab_column MATCH expression + ** MATCH(expression,vtab_column) + */ + pCol = pList->a[1].pExpr; + assert( pCol->op!=TK_COLUMN || (ExprUseYTab(pCol) && pCol->y.pTab!=0) ); + if( ExprIsVtab(pCol) && (i = sqlite3ExprIsLikeOperator(pExpr))!=0 ){ + *peOp2 = i; + *ppRight = pList->a[0].pExpr; + *ppLeft = pCol; + return 1; + } + + /* We can also match against the first column of overloaded + ** functions where xFindFunction returns a value of at least + ** SQLITE_INDEX_CONSTRAINT_FUNCTION. + ** + ** OVERLOADED(vtab_column,expression) + ** + ** Historically, xFindFunction expected to see lower-case function + ** names. But for this use case, xFindFunction is expected to deal + ** with function names in an arbitrary case. + */ + pCol = pList->a[0].pExpr; + assert( pCol->op!=TK_COLUMN || ExprUseYTab(pCol) ); + assert( pCol->op!=TK_COLUMN || (ExprUseYTab(pCol) && pCol->y.pTab!=0) ); + if( ExprIsVtab(pCol) ){ + sqlite3_vtab *pVtab; + sqlite3_module *pMod; + void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**); + void *pNotUsed; + pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab; + assert( pVtab!=0 ); + assert( pVtab->pModule!=0 ); + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + pMod = (sqlite3_module *)pVtab->pModule; + if( pMod->xFindFunction!=0 ){ + i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed); + if( i>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){ + *peOp2 = i; + *ppRight = pList->a[1].pExpr; + *ppLeft = pCol; + return 1; + } + } + } + }else if( pExpr->op>=TK_EQ ){ + /* Comparison operators are a common case. Save a few comparisons for + ** that common case by terminating early. */ + assert( TK_NE < TK_EQ ); + assert( TK_ISNOT < TK_EQ ); + assert( TK_NOTNULL < TK_EQ ); + return 0; + }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){ + int res = 0; + Expr *pLeft = pExpr->pLeft; + Expr *pRight = pExpr->pRight; + assert( pLeft->op!=TK_COLUMN || (ExprUseYTab(pLeft) && pLeft->y.pTab!=0) ); + if( ExprIsVtab(pLeft) ){ + res++; + } + assert( pRight==0 || pRight->op!=TK_COLUMN + || (ExprUseYTab(pRight) && pRight->y.pTab!=0) ); + if( pRight && ExprIsVtab(pRight) ){ + res++; + SWAP(Expr*, pLeft, pRight); + } + *ppLeft = pLeft; + *ppRight = pRight; + if( pExpr->op==TK_NE ) *peOp2 = SQLITE_INDEX_CONSTRAINT_NE; + if( pExpr->op==TK_ISNOT ) *peOp2 = SQLITE_INDEX_CONSTRAINT_ISNOT; + if( pExpr->op==TK_NOTNULL ) *peOp2 = SQLITE_INDEX_CONSTRAINT_ISNOTNULL; + return res; + } + return 0; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +/* +** If the pBase expression originated in the ON or USING clause of +** a join, then transfer the appropriate markings over to derived. +*/ +static void transferJoinMarkings(Expr *pDerived, Expr *pBase){ + if( pDerived && ExprHasProperty(pBase, EP_OuterON|EP_InnerON) ){ + pDerived->flags |= pBase->flags & (EP_OuterON|EP_InnerON); + pDerived->w.iJoin = pBase->w.iJoin; + } +} + +/* +** Mark term iChild as being a child of term iParent +*/ +static void markTermAsChild(WhereClause *pWC, int iChild, int iParent){ + pWC->a[iChild].iParent = iParent; + pWC->a[iChild].truthProb = pWC->a[iParent].truthProb; + assert( pWC->a[iParent].nChild < UMXV(pWC->a[0].nChild) ); + pWC->a[iParent].nChild++; + testcase( pWC->a[iParent].nChild == UMXV(pWC->a[0].nChild) ); + +} + +/* +** Return the N-th AND-connected subterm of pTerm. Or if pTerm is not +** a conjunction, then return just pTerm when N==0. If N is exceeds +** the number of available subterms, return NULL. +*/ +static WhereTerm *whereNthSubterm(WhereTerm *pTerm, int N){ + if( pTerm->eOperator!=WO_AND ){ + return N==0 ? pTerm : 0; + } + if( Nu.pAndInfo->wc.nTerm ){ + return &pTerm->u.pAndInfo->wc.a[N]; + } + return 0; +} + +/* +** Subterms pOne and pTwo are contained within WHERE clause pWC. The +** two subterms are in disjunction - they are OR-ed together. +** +** If these two terms are both of the form: "A op B" with the same +** A and B values but different operators and if the operators are +** compatible (if one is = and the other is <, for example) then +** add a new virtual AND term to pWC that is the combination of the +** two. +** +** Some examples: +** +** x x<=y +** x=y OR x=y --> x=y +** x<=y OR x x<=y +** +** The following is NOT generated: +** +** xy --> x!=y +*/ +static void whereCombineDisjuncts( + SrcList *pSrc, /* the FROM clause */ + WhereClause *pWC, /* The complete WHERE clause */ + WhereTerm *pOne, /* First disjunct */ + WhereTerm *pTwo /* Second disjunct */ +){ + u16 eOp = pOne->eOperator | pTwo->eOperator; + sqlite3 *db; /* Database connection (for malloc) */ + Expr *pNew; /* New virtual expression */ + int op; /* Operator for the combined expression */ + int idxNew; /* Index in pWC of the next virtual term */ + Expr *pA, *pB; /* Expressions associated with pOne and pTwo */ + + if( (pOne->wtFlags | pTwo->wtFlags) & TERM_VNULL ) return; + if( (pOne->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE))==0 ) return; + if( (pTwo->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE))==0 ) return; + if( (eOp & (WO_EQ|WO_LT|WO_LE))!=eOp + && (eOp & (WO_EQ|WO_GT|WO_GE))!=eOp ) return; + pA = pOne->pExpr; + pB = pTwo->pExpr; + assert( pA->pLeft!=0 && pA->pRight!=0 ); + assert( pB->pLeft!=0 && pB->pRight!=0 ); + if( sqlite3ExprCompare(0,pA->pLeft, pB->pLeft, -1) ) return; + if( sqlite3ExprCompare(0,pA->pRight, pB->pRight,-1) ) return; + if( ExprHasProperty(pA,EP_Commuted)!=ExprHasProperty(pB,EP_Commuted) ){ + return; + } + /* If we reach this point, it means the two subterms can be combined */ + if( (eOp & (eOp-1))!=0 ){ + if( eOp & (WO_LT|WO_LE) ){ + eOp = WO_LE; + }else{ + assert( eOp & (WO_GT|WO_GE) ); + eOp = WO_GE; + } + } + db = pWC->pWInfo->pParse->db; + pNew = sqlite3ExprDup(db, pA, 0); + if( pNew==0 ) return; + for(op=TK_EQ; eOp!=(WO_EQ<<(op-TK_EQ)); op++){ assert( opop = op; + idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC); + exprAnalyze(pSrc, pWC, idxNew); +} + +#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY) +/* +** Analyze a term that consists of two or more OR-connected +** subterms. So in: +** +** ... WHERE (a=5) AND (b=7 OR c=9 OR d=13) AND (d=13) +** ^^^^^^^^^^^^^^^^^^^^ +** +** This routine analyzes terms such as the middle term in the above example. +** A WhereOrTerm object is computed and attached to the term under +** analysis, regardless of the outcome of the analysis. Hence: +** +** WhereTerm.wtFlags |= TERM_ORINFO +** WhereTerm.u.pOrInfo = a dynamically allocated WhereOrTerm object +** +** The term being analyzed must have two or more of OR-connected subterms. +** A single subterm might be a set of AND-connected sub-subterms. +** Examples of terms under analysis: +** +** (A) t1.x=t2.y OR t1.x=t2.z OR t1.y=15 OR t1.z=t3.a+5 +** (B) x=expr1 OR expr2=x OR x=expr3 +** (C) t1.x=t2.y OR (t1.x=t2.z AND t1.y=15) +** (D) x=expr1 OR (y>11 AND y<22 AND z LIKE '*hello*') +** (E) (p.a=1 AND q.b=2 AND r.c=3) OR (p.x=4 AND q.y=5 AND r.z=6) +** (F) x>A OR (x=A AND y>=B) +** +** CASE 1: +** +** If all subterms are of the form T.C=expr for some single column of C and +** a single table T (as shown in example B above) then create a new virtual +** term that is an equivalent IN expression. In other words, if the term +** being analyzed is: +** +** x = expr1 OR expr2 = x OR x = expr3 +** +** then create a new virtual term like this: +** +** x IN (expr1,expr2,expr3) +** +** CASE 2: +** +** If there are exactly two disjuncts and one side has x>A and the other side +** has x=A (for the same x and A) then add a new virtual conjunct term to the +** WHERE clause of the form "x>=A". Example: +** +** x>A OR (x=A AND y>B) adds: x>=A +** +** The added conjunct can sometimes be helpful in query planning. +** +** CASE 3: +** +** If all subterms are indexable by a single table T, then set +** +** WhereTerm.eOperator = WO_OR +** WhereTerm.u.pOrInfo->indexable |= the cursor number for table T +** +** A subterm is "indexable" if it is of the form +** "T.C " where C is any column of table T and +** is one of "=", "<", "<=", ">", ">=", "IS NULL", or "IN". +** A subterm is also indexable if it is an AND of two or more +** subsubterms at least one of which is indexable. Indexable AND +** subterms have their eOperator set to WO_AND and they have +** u.pAndInfo set to a dynamically allocated WhereAndTerm object. +** +** From another point of view, "indexable" means that the subterm could +** potentially be used with an index if an appropriate index exists. +** This analysis does not consider whether or not the index exists; that +** is decided elsewhere. This analysis only looks at whether subterms +** appropriate for indexing exist. +** +** All examples A through E above satisfy case 3. But if a term +** also satisfies case 1 (such as B) we know that the optimizer will +** always prefer case 1, so in that case we pretend that case 3 is not +** satisfied. +** +** It might be the case that multiple tables are indexable. For example, +** (E) above is indexable on tables P, Q, and R. +** +** Terms that satisfy case 3 are candidates for lookup by using +** separate indices to find rowids for each subterm and composing +** the union of all rowids using a RowSet object. This is similar +** to "bitmap indices" in other database engines. +** +** OTHERWISE: +** +** If none of cases 1, 2, or 3 apply, then leave the eOperator set to +** zero. This term is not useful for search. +*/ +static void exprAnalyzeOrTerm( + SrcList *pSrc, /* the FROM clause */ + WhereClause *pWC, /* the complete WHERE clause */ + int idxTerm /* Index of the OR-term to be analyzed */ +){ + WhereInfo *pWInfo = pWC->pWInfo; /* WHERE clause processing context */ + Parse *pParse = pWInfo->pParse; /* Parser context */ + sqlite3 *db = pParse->db; /* Database connection */ + WhereTerm *pTerm = &pWC->a[idxTerm]; /* The term to be analyzed */ + Expr *pExpr = pTerm->pExpr; /* The expression of the term */ + int i; /* Loop counters */ + WhereClause *pOrWc; /* Breakup of pTerm into subterms */ + WhereTerm *pOrTerm; /* A Sub-term within the pOrWc */ + WhereOrInfo *pOrInfo; /* Additional information associated with pTerm */ + Bitmask chngToIN; /* Tables that might satisfy case 1 */ + Bitmask indexable; /* Tables that are indexable, satisfying case 2 */ + + /* + ** Break the OR clause into its separate subterms. The subterms are + ** stored in a WhereClause structure containing within the WhereOrInfo + ** object that is attached to the original OR clause term. + */ + assert( (pTerm->wtFlags & (TERM_DYNAMIC|TERM_ORINFO|TERM_ANDINFO))==0 ); + assert( pExpr->op==TK_OR ); + pTerm->u.pOrInfo = pOrInfo = sqlite3DbMallocZero(db, sizeof(*pOrInfo)); + if( pOrInfo==0 ) return; + pTerm->wtFlags |= TERM_ORINFO; + pOrWc = &pOrInfo->wc; + memset(pOrWc->aStatic, 0, sizeof(pOrWc->aStatic)); + sqlite3WhereClauseInit(pOrWc, pWInfo); + sqlite3WhereSplit(pOrWc, pExpr, TK_OR); + sqlite3WhereExprAnalyze(pSrc, pOrWc); + if( db->mallocFailed ) return; + assert( pOrWc->nTerm>=2 ); + + /* + ** Compute the set of tables that might satisfy cases 1 or 3. + */ + indexable = ~(Bitmask)0; + chngToIN = ~(Bitmask)0; + for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0 && indexable; i--, pOrTerm++){ + if( (pOrTerm->eOperator & WO_SINGLE)==0 ){ + WhereAndInfo *pAndInfo; + assert( (pOrTerm->wtFlags & (TERM_ANDINFO|TERM_ORINFO))==0 ); + chngToIN = 0; + pAndInfo = sqlite3DbMallocRawNN(db, sizeof(*pAndInfo)); + if( pAndInfo ){ + WhereClause *pAndWC; + WhereTerm *pAndTerm; + int j; + Bitmask b = 0; + pOrTerm->u.pAndInfo = pAndInfo; + pOrTerm->wtFlags |= TERM_ANDINFO; + pOrTerm->eOperator = WO_AND; + pOrTerm->leftCursor = -1; + pAndWC = &pAndInfo->wc; + memset(pAndWC->aStatic, 0, sizeof(pAndWC->aStatic)); + sqlite3WhereClauseInit(pAndWC, pWC->pWInfo); + sqlite3WhereSplit(pAndWC, pOrTerm->pExpr, TK_AND); + sqlite3WhereExprAnalyze(pSrc, pAndWC); + pAndWC->pOuter = pWC; + if( !db->mallocFailed ){ + for(j=0, pAndTerm=pAndWC->a; jnTerm; j++, pAndTerm++){ + assert( pAndTerm->pExpr ); + if( allowedOp(pAndTerm->pExpr->op) + || pAndTerm->eOperator==WO_AUX + ){ + b |= sqlite3WhereGetMask(&pWInfo->sMaskSet, pAndTerm->leftCursor); + } + } + } + indexable &= b; + } + }else if( pOrTerm->wtFlags & TERM_COPIED ){ + /* Skip this term for now. We revisit it when we process the + ** corresponding TERM_VIRTUAL term */ + }else{ + Bitmask b; + b = sqlite3WhereGetMask(&pWInfo->sMaskSet, pOrTerm->leftCursor); + if( pOrTerm->wtFlags & TERM_VIRTUAL ){ + WhereTerm *pOther = &pOrWc->a[pOrTerm->iParent]; + b |= sqlite3WhereGetMask(&pWInfo->sMaskSet, pOther->leftCursor); + } + indexable &= b; + if( (pOrTerm->eOperator & WO_EQ)==0 ){ + chngToIN = 0; + }else{ + chngToIN &= b; + } + } + } + + /* + ** Record the set of tables that satisfy case 3. The set might be + ** empty. + */ + pOrInfo->indexable = indexable; + pTerm->eOperator = WO_OR; + pTerm->leftCursor = -1; + if( indexable ){ + pWC->hasOr = 1; + } + + /* For a two-way OR, attempt to implementation case 2. + */ + if( indexable && pOrWc->nTerm==2 ){ + int iOne = 0; + WhereTerm *pOne; + while( (pOne = whereNthSubterm(&pOrWc->a[0],iOne++))!=0 ){ + int iTwo = 0; + WhereTerm *pTwo; + while( (pTwo = whereNthSubterm(&pOrWc->a[1],iTwo++))!=0 ){ + whereCombineDisjuncts(pSrc, pWC, pOne, pTwo); + } + } + } + + /* + ** chngToIN holds a set of tables that *might* satisfy case 1. But + ** we have to do some additional checking to see if case 1 really + ** is satisfied. + ** + ** chngToIN will hold either 0, 1, or 2 bits. The 0-bit case means + ** that there is no possibility of transforming the OR clause into an + ** IN operator because one or more terms in the OR clause contain + ** something other than == on a column in the single table. The 1-bit + ** case means that every term of the OR clause is of the form + ** "table.column=expr" for some single table. The one bit that is set + ** will correspond to the common table. We still need to check to make + ** sure the same column is used on all terms. The 2-bit case is when + ** the all terms are of the form "table1.column=table2.column". It + ** might be possible to form an IN operator with either table1.column + ** or table2.column as the LHS if either is common to every term of + ** the OR clause. + ** + ** Note that terms of the form "table.column1=table.column2" (the + ** same table on both sizes of the ==) cannot be optimized. + */ + if( chngToIN ){ + int okToChngToIN = 0; /* True if the conversion to IN is valid */ + int iColumn = -1; /* Column index on lhs of IN operator */ + int iCursor = -1; /* Table cursor common to all terms */ + int j = 0; /* Loop counter */ + + /* Search for a table and column that appears on one side or the + ** other of the == operator in every subterm. That table and column + ** will be recorded in iCursor and iColumn. There might not be any + ** such table and column. Set okToChngToIN if an appropriate table + ** and column is found but leave okToChngToIN false if not found. + */ + for(j=0; j<2 && !okToChngToIN; j++){ + Expr *pLeft = 0; + pOrTerm = pOrWc->a; + for(i=pOrWc->nTerm-1; i>=0; i--, pOrTerm++){ + assert( pOrTerm->eOperator & WO_EQ ); + pOrTerm->wtFlags &= ~TERM_OK; + if( pOrTerm->leftCursor==iCursor ){ + /* This is the 2-bit case and we are on the second iteration and + ** current term is from the first iteration. So skip this term. */ + assert( j==1 ); + continue; + } + if( (chngToIN & sqlite3WhereGetMask(&pWInfo->sMaskSet, + pOrTerm->leftCursor))==0 ){ + /* This term must be of the form t1.a==t2.b where t2 is in the + ** chngToIN set but t1 is not. This term will be either preceded + ** or followed by an inverted copy (t2.b==t1.a). Skip this term + ** and use its inversion. */ + testcase( pOrTerm->wtFlags & TERM_COPIED ); + testcase( pOrTerm->wtFlags & TERM_VIRTUAL ); + assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) ); + continue; + } + assert( (pOrTerm->eOperator & (WO_OR|WO_AND))==0 ); + iColumn = pOrTerm->u.x.leftColumn; + iCursor = pOrTerm->leftCursor; + pLeft = pOrTerm->pExpr->pLeft; + break; + } + if( i<0 ){ + /* No candidate table+column was found. This can only occur + ** on the second iteration */ + assert( j==1 ); + assert( IsPowerOfTwo(chngToIN) ); + assert( chngToIN==sqlite3WhereGetMask(&pWInfo->sMaskSet, iCursor) ); + break; + } + testcase( j==1 ); + + /* We have found a candidate table and column. Check to see if that + ** table and column is common to every term in the OR clause */ + okToChngToIN = 1; + for(; i>=0 && okToChngToIN; i--, pOrTerm++){ + assert( pOrTerm->eOperator & WO_EQ ); + assert( (pOrTerm->eOperator & (WO_OR|WO_AND))==0 ); + if( pOrTerm->leftCursor!=iCursor ){ + pOrTerm->wtFlags &= ~TERM_OK; + }else if( pOrTerm->u.x.leftColumn!=iColumn || (iColumn==XN_EXPR + && sqlite3ExprCompare(pParse, pOrTerm->pExpr->pLeft, pLeft, -1) + )){ + okToChngToIN = 0; + }else{ + int affLeft, affRight; + /* If the right-hand side is also a column, then the affinities + ** of both right and left sides must be such that no type + ** conversions are required on the right. (Ticket #2249) + */ + affRight = sqlite3ExprAffinity(pOrTerm->pExpr->pRight); + affLeft = sqlite3ExprAffinity(pOrTerm->pExpr->pLeft); + if( affRight!=0 && affRight!=affLeft ){ + okToChngToIN = 0; + }else{ + pOrTerm->wtFlags |= TERM_OK; + } + } + } + } + + /* At this point, okToChngToIN is true if original pTerm satisfies + ** case 1. In that case, construct a new virtual term that is + ** pTerm converted into an IN operator. + */ + if( okToChngToIN ){ + Expr *pDup; /* A transient duplicate expression */ + ExprList *pList = 0; /* The RHS of the IN operator */ + Expr *pLeft = 0; /* The LHS of the IN operator */ + Expr *pNew; /* The complete IN operator */ + + for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0; i--, pOrTerm++){ + if( (pOrTerm->wtFlags & TERM_OK)==0 ) continue; + assert( pOrTerm->eOperator & WO_EQ ); + assert( (pOrTerm->eOperator & (WO_OR|WO_AND))==0 ); + assert( pOrTerm->leftCursor==iCursor ); + assert( pOrTerm->u.x.leftColumn==iColumn ); + pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0); + pList = sqlite3ExprListAppend(pWInfo->pParse, pList, pDup); + pLeft = pOrTerm->pExpr->pLeft; + } + assert( pLeft!=0 ); + pDup = sqlite3ExprDup(db, pLeft, 0); + pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0); + if( pNew ){ + int idxNew; + transferJoinMarkings(pNew, pExpr); + assert( ExprUseXList(pNew) ); + pNew->x.pList = pList; + idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC); + testcase( idxNew==0 ); + exprAnalyze(pSrc, pWC, idxNew); + /* pTerm = &pWC->a[idxTerm]; // would be needed if pTerm where reused */ + markTermAsChild(pWC, idxNew, idxTerm); + }else{ + sqlite3ExprListDelete(db, pList); + } + } + } +} +#endif /* !SQLITE_OMIT_OR_OPTIMIZATION && !SQLITE_OMIT_SUBQUERY */ + +/* +** We already know that pExpr is a binary operator where both operands are +** column references. This routine checks to see if pExpr is an equivalence +** relation: +** 1. The SQLITE_Transitive optimization must be enabled +** 2. Must be either an == or an IS operator +** 3. Not originating in the ON clause of an OUTER JOIN +** 4. The operator is not IS or else the query does not contain RIGHT JOIN +** 5. The affinities of A and B must be compatible +** 6. Both operands use the same collating sequence, and they must not +** use explicit COLLATE clauses. +** If this routine returns TRUE, that means that the RHS can be substituted +** for the LHS anyplace else in the WHERE clause where the LHS column occurs. +** This is an optimization. No harm comes from returning 0. But if 1 is +** returned when it should not be, then incorrect answers might result. +*/ +static int termIsEquivalence(Parse *pParse, Expr *pExpr, SrcList *pSrc){ + char aff1, aff2; + if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; /* (1) */ + if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; /* (2) */ + if( ExprHasProperty(pExpr, EP_OuterON|EP_Collate) ) return 0; /* (3) */ + assert( pSrc!=0 ); + if( pExpr->op==TK_IS + && pSrc->nSrc>=2 + && (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 + ){ + return 0; /* (4) */ + } + aff1 = sqlite3ExprAffinity(pExpr->pLeft); + aff2 = sqlite3ExprAffinity(pExpr->pRight); + if( aff1!=aff2 + && (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2)) + ){ + return 0; /* (5) */ + } + if( !sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight) ){ + return 0; /* (6) */ + } + return 1; +} + +/* +** Recursively walk the expressions of a SELECT statement and generate +** a bitmask indicating which tables are used in that expression +** tree. +*/ +static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){ + Bitmask mask = 0; + while( pS ){ + SrcList *pSrc = pS->pSrc; + mask |= sqlite3WhereExprListUsage(pMaskSet, pS->pEList); + mask |= sqlite3WhereExprListUsage(pMaskSet, pS->pGroupBy); + mask |= sqlite3WhereExprListUsage(pMaskSet, pS->pOrderBy); + mask |= sqlite3WhereExprUsage(pMaskSet, pS->pWhere); + mask |= sqlite3WhereExprUsage(pMaskSet, pS->pHaving); + if( ALWAYS(pSrc!=0) ){ + int i; + for(i=0; inSrc; i++){ + if( pSrc->a[i].fg.isSubquery ){ + mask |= exprSelectUsage(pMaskSet, pSrc->a[i].u4.pSubq->pSelect); + } + if( pSrc->a[i].fg.isUsing==0 ){ + mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].u3.pOn); + } + if( pSrc->a[i].fg.isTabFunc ){ + mask |= sqlite3WhereExprListUsage(pMaskSet, pSrc->a[i].u1.pFuncArg); + } + } + } + pS = pS->pPrior; + } + return mask; +} + +/* +** Expression pExpr is one operand of a comparison operator that might +** be useful for indexing. This routine checks to see if pExpr appears +** in any index. Return TRUE (1) if pExpr is an indexed term and return +** FALSE (0) if not. If TRUE is returned, also set aiCurCol[0] to the cursor +** number of the table that is indexed and aiCurCol[1] to the column number +** of the column that is indexed, or XN_EXPR (-2) if an expression is being +** indexed. +** +** If pExpr is a TK_COLUMN column reference, then this routine always returns +** true even if that particular column is not indexed, because the column +** might be added to an automatic index later. +*/ +static SQLITE_NOINLINE int exprMightBeIndexed2( + SrcList *pFrom, /* The FROM clause */ + int *aiCurCol, /* Write the referenced table cursor and column here */ + Expr *pExpr, /* An operand of a comparison operator */ + int j /* Start looking with the j-th pFrom entry */ +){ + Index *pIdx; + int i; + int iCur; + do{ + iCur = pFrom->a[j].iCursor; + for(pIdx=pFrom->a[j].pSTab->pIndex; pIdx; pIdx=pIdx->pNext){ + if( pIdx->aColExpr==0 ) continue; + for(i=0; inKeyCol; i++){ + if( pIdx->aiColumn[i]!=XN_EXPR ) continue; + assert( pIdx->bHasExpr ); + if( sqlite3ExprCompareSkip(pExpr,pIdx->aColExpr->a[i].pExpr,iCur)==0 + && !sqlite3ExprIsConstant(0,pIdx->aColExpr->a[i].pExpr) + ){ + aiCurCol[0] = iCur; + aiCurCol[1] = XN_EXPR; + return 1; + } + } + } + }while( ++j < pFrom->nSrc ); + return 0; +} +static int exprMightBeIndexed( + SrcList *pFrom, /* The FROM clause */ + int *aiCurCol, /* Write the referenced table cursor & column here */ + Expr *pExpr, /* An operand of a comparison operator */ + int op /* The specific comparison operator */ +){ + int i; + + /* If this expression is a vector to the left or right of a + ** inequality constraint (>, <, >= or <=), perform the processing + ** on the first element of the vector. */ + assert( TK_GT+1==TK_LE && TK_GT+2==TK_LT && TK_GT+3==TK_GE ); + assert( TK_ISop==TK_VECTOR && (op>=TK_GT && ALWAYS(op<=TK_GE)) ){ + assert( ExprUseXList(pExpr) ); + pExpr = pExpr->x.pList->a[0].pExpr; + } + + if( pExpr->op==TK_COLUMN ){ + aiCurCol[0] = pExpr->iTable; + aiCurCol[1] = pExpr->iColumn; + return 1; + } + + for(i=0; inSrc; i++){ + Index *pIdx; + for(pIdx=pFrom->a[i].pSTab->pIndex; pIdx; pIdx=pIdx->pNext){ + if( pIdx->aColExpr ){ + return exprMightBeIndexed2(pFrom,aiCurCol,pExpr,i); + } + } + } + return 0; +} + + +/* +** The input to this routine is an WhereTerm structure with only the +** "pExpr" field filled in. The job of this routine is to analyze the +** subexpression and populate all the other fields of the WhereTerm +** structure. +** +** If the expression is of the form " X" it gets commuted +** to the standard form of "X ". +** +** If the expression is of the form "X Y" where both X and Y are +** columns, then the original expression is unchanged and a new virtual +** term of the form "Y X" is added to the WHERE clause and +** analyzed separately. The original term is marked with TERM_COPIED +** and the new term is marked with TERM_DYNAMIC (because it's pExpr +** needs to be freed with the WhereClause) and TERM_VIRTUAL (because it +** is a commuted copy of a prior term.) The original term has nChild=1 +** and the copy has idxParent set to the index of the original term. +*/ +static void exprAnalyze( + SrcList *pSrc, /* the FROM clause */ + WhereClause *pWC, /* the WHERE clause */ + int idxTerm /* Index of the term to be analyzed */ +){ + WhereInfo *pWInfo = pWC->pWInfo; /* WHERE clause processing context */ + WhereTerm *pTerm; /* The term to be analyzed */ + WhereMaskSet *pMaskSet; /* Set of table index masks */ + Expr *pExpr; /* The expression to be analyzed */ + Bitmask prereqLeft; /* Prerequisites of the pExpr->pLeft */ + Bitmask prereqAll; /* Prerequisites of pExpr */ + Bitmask extraRight = 0; /* Extra dependencies on LEFT JOIN */ + Expr *pStr1 = 0; /* RHS of LIKE/GLOB operator */ + int isComplete = 0; /* RHS of LIKE/GLOB ends with wildcard */ + int noCase = 0; /* uppercase equivalent to lowercase */ + int op; /* Top-level operator. pExpr->op */ + Parse *pParse = pWInfo->pParse; /* Parsing context */ + sqlite3 *db = pParse->db; /* Database connection */ + unsigned char eOp2 = 0; /* op2 value for LIKE/REGEXP/GLOB */ + int nLeft; /* Number of elements on left side vector */ + + if( db->mallocFailed ){ + return; + } + assert( pWC->nTerm > idxTerm ); + pTerm = &pWC->a[idxTerm]; +#ifdef SQLITE_DEBUG + pTerm->iTerm = idxTerm; +#endif + pMaskSet = &pWInfo->sMaskSet; + pExpr = pTerm->pExpr; + assert( pExpr!=0 ); /* Because malloc() has not failed */ + assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE ); + pMaskSet->bVarSelect = 0; + prereqLeft = sqlite3WhereExprUsage(pMaskSet, pExpr->pLeft); + op = pExpr->op; + if( op==TK_IN ){ + assert( pExpr->pRight==0 ); + if( sqlite3ExprCheckIN(pParse, pExpr) ) return; + if( ExprUseXSelect(pExpr) ){ + pTerm->prereqRight = exprSelectUsage(pMaskSet, pExpr->x.pSelect); + }else{ + pTerm->prereqRight = sqlite3WhereExprListUsage(pMaskSet, pExpr->x.pList); + } + prereqAll = prereqLeft | pTerm->prereqRight; + }else{ + pTerm->prereqRight = sqlite3WhereExprUsage(pMaskSet, pExpr->pRight); + if( pExpr->pLeft==0 + || ExprHasProperty(pExpr, EP_xIsSelect|EP_IfNullRow) + || pExpr->x.pList!=0 + ){ + prereqAll = sqlite3WhereExprUsageNN(pMaskSet, pExpr); + }else{ + prereqAll = prereqLeft | pTerm->prereqRight; + } + } + if( pMaskSet->bVarSelect ) pTerm->wtFlags |= TERM_VARSELECT; + +#ifdef SQLITE_DEBUG + if( prereqAll!=sqlite3WhereExprUsageNN(pMaskSet, pExpr) ){ + printf("\n*** Incorrect prereqAll computed for:\n"); + sqlite3TreeViewExpr(0,pExpr,0); + assert( 0 ); + } +#endif + + if( ExprHasProperty(pExpr, EP_OuterON|EP_InnerON) ){ + Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->w.iJoin); + if( ExprHasProperty(pExpr, EP_OuterON) ){ + prereqAll |= x; + extraRight = x-1; /* ON clause terms may not be used with an index + ** on left table of a LEFT JOIN. Ticket #3015 */ + }else if( (prereqAll>>1)>=x ){ + ExprClearProperty(pExpr, EP_InnerON); + } + } + pTerm->prereqAll = prereqAll; + pTerm->leftCursor = -1; + pTerm->iParent = -1; + pTerm->eOperator = 0; + if( allowedOp(op) ){ + int aiCurCol[2]; + Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft); + Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight); + u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV; + + if( pTerm->u.x.iField>0 ){ + assert( op==TK_IN ); + assert( pLeft->op==TK_VECTOR ); + assert( ExprUseXList(pLeft) ); + pLeft = pLeft->x.pList->a[pTerm->u.x.iField-1].pExpr; + } + + if( exprMightBeIndexed(pSrc, aiCurCol, pLeft, op) ){ + pTerm->leftCursor = aiCurCol[0]; + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); + pTerm->u.x.leftColumn = aiCurCol[1]; + pTerm->eOperator = operatorMask(op) & opMask; + } + if( op==TK_IS ) pTerm->wtFlags |= TERM_IS; + if( pRight + && exprMightBeIndexed(pSrc, aiCurCol, pRight, op) + && !ExprHasProperty(pRight, EP_FixedCol) + ){ + WhereTerm *pNew; + Expr *pDup; + u16 eExtraOp = 0; /* Extra bits for pNew->eOperator */ + assert( pTerm->u.x.iField==0 ); + if( pTerm->leftCursor>=0 ){ + int idxNew; + pDup = sqlite3ExprDup(db, pExpr, 0); + if( db->mallocFailed ){ + sqlite3ExprDelete(db, pDup); + return; + } + idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC); + if( idxNew==0 ) return; + pNew = &pWC->a[idxNew]; + markTermAsChild(pWC, idxNew, idxTerm); + if( op==TK_IS ) pNew->wtFlags |= TERM_IS; + pTerm = &pWC->a[idxTerm]; + pTerm->wtFlags |= TERM_COPIED; + assert( pWInfo->pTabList!=0 ); + if( termIsEquivalence(pParse, pDup, pWInfo->pTabList) ){ + pTerm->eOperator |= WO_EQUIV; + eExtraOp = WO_EQUIV; + } + }else{ + pDup = pExpr; + pNew = pTerm; + } + pNew->wtFlags |= exprCommute(pParse, pDup); + pNew->leftCursor = aiCurCol[0]; + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); + pNew->u.x.leftColumn = aiCurCol[1]; + testcase( (prereqLeft | extraRight) != prereqLeft ); + pNew->prereqRight = prereqLeft | extraRight; + pNew->prereqAll = prereqAll; + pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask; + }else + if( op==TK_ISNULL + && !ExprHasProperty(pExpr,EP_OuterON) + && 0==sqlite3ExprCanBeNull(pLeft) + ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + pExpr->op = TK_TRUEFALSE; /* See tag-20230504-1 */ + pExpr->u.zToken = "false"; + ExprSetProperty(pExpr, EP_IsFalse); + pTerm->prereqAll = 0; + pTerm->eOperator = 0; + } + } + +#ifndef SQLITE_OMIT_BETWEEN_OPTIMIZATION + /* If a term is the BETWEEN operator, create two new virtual terms + ** that define the range that the BETWEEN implements. For example: + ** + ** a BETWEEN b AND c + ** + ** is converted into: + ** + ** (a BETWEEN b AND c) AND (a>=b) AND (a<=c) + ** + ** The two new terms are added onto the end of the WhereClause object. + ** The new terms are "dynamic" and are children of the original BETWEEN + ** term. That means that if the BETWEEN term is coded, the children are + ** skipped. Or, if the children are satisfied by an index, the original + ** BETWEEN term is skipped. + */ + else if( pExpr->op==TK_BETWEEN && pWC->op==TK_AND ){ + ExprList *pList; + int i; + static const u8 ops[] = {TK_GE, TK_LE}; + assert( ExprUseXList(pExpr) ); + pList = pExpr->x.pList; + assert( pList!=0 ); + assert( pList->nExpr==2 ); + assert( pWC->a[idxTerm].nChild==0 ); + for(i=0; i<2; i++){ + Expr *pNewExpr; + int idxNew; + pNewExpr = sqlite3PExpr(pParse, ops[i], + sqlite3ExprDup(db, pExpr->pLeft, 0), + sqlite3ExprDup(db, pList->a[i].pExpr, 0)); + transferJoinMarkings(pNewExpr, pExpr); + idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); + testcase( idxNew==0 ); + exprAnalyze(pSrc, pWC, idxNew); + pTerm = &pWC->a[idxTerm]; + markTermAsChild(pWC, idxNew, idxTerm); + } + } +#endif /* SQLITE_OMIT_BETWEEN_OPTIMIZATION */ + +#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY) + /* Analyze a term that is composed of two or more subterms connected by + ** an OR operator. + */ + else if( pExpr->op==TK_OR && !ExprHasProperty(pExpr, EP_Collate) ){ + assert( pWC->op==TK_AND ); + exprAnalyzeOrTerm(pSrc, pWC, idxTerm); + pTerm = &pWC->a[idxTerm]; + } +#endif /* SQLITE_OMIT_OR_OPTIMIZATION */ + /* The form "x IS NOT NULL" can sometimes be evaluated more efficiently + ** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a + ** virtual term of that form. + ** + ** The virtual term must be tagged with TERM_VNULL. + */ + else if( pExpr->op==TK_NOTNULL ){ + if( pExpr->pLeft->op==TK_COLUMN + && pExpr->pLeft->iColumn>=0 + && !ExprHasProperty(pExpr, EP_OuterON) + ){ + Expr *pNewExpr; + Expr *pLeft = pExpr->pLeft; + int idxNew; + WhereTerm *pNewTerm; + + pNewExpr = sqlite3PExpr(pParse, TK_GT, + sqlite3ExprDup(db, pLeft, 0), + sqlite3ExprAlloc(db, TK_NULL, 0, 0)); + + idxNew = whereClauseInsert(pWC, pNewExpr, + TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL); + if( idxNew ){ + pNewTerm = &pWC->a[idxNew]; + pNewTerm->prereqRight = 0; + pNewTerm->leftCursor = pLeft->iTable; + pNewTerm->u.x.leftColumn = pLeft->iColumn; + pNewTerm->eOperator = WO_GT; + markTermAsChild(pWC, idxNew, idxTerm); + pTerm = &pWC->a[idxTerm]; + pTerm->wtFlags |= TERM_COPIED; + pNewTerm->prereqAll = pTerm->prereqAll; + } + } + } + + +#ifndef SQLITE_OMIT_LIKE_OPTIMIZATION + /* Add constraints to reduce the search space on a LIKE or GLOB + ** operator. + ** + ** A like pattern of the form "x LIKE 'aBc%'" is changed into constraints + ** + ** x>='ABC' AND x<'abd' AND x LIKE 'aBc%' + ** + ** The last character of the prefix "abc" is incremented to form the + ** termination condition "abd". If case is not significant (the default + ** for LIKE) then the lower-bound is made all uppercase and the upper- + ** bound is made all lowercase so that the bounds also work when comparing + ** BLOBs. + */ + else if( pExpr->op==TK_FUNCTION + && pWC->op==TK_AND + && isLikeOrGlob(pParse, pExpr, &pStr1, &isComplete, &noCase) + ){ + Expr *pLeft; /* LHS of LIKE/GLOB operator */ + Expr *pStr2; /* Copy of pStr1 - RHS of LIKE/GLOB operator */ + Expr *pNewExpr1; + Expr *pNewExpr2; + int idxNew1; + int idxNew2; + const char *zCollSeqName; /* Name of collating sequence */ + const u16 wtFlags = TERM_LIKEOPT | TERM_VIRTUAL | TERM_DYNAMIC; + + assert( ExprUseXList(pExpr) ); + pLeft = pExpr->x.pList->a[1].pExpr; + pStr2 = sqlite3ExprDup(db, pStr1, 0); + assert( pStr1==0 || !ExprHasProperty(pStr1, EP_IntValue) ); + assert( pStr2==0 || !ExprHasProperty(pStr2, EP_IntValue) ); + + + /* Convert the lower bound to upper-case and the upper bound to + ** lower-case (upper-case is less than lower-case in ASCII) so that + ** the range constraints also work for BLOBs + */ + if( noCase && !pParse->db->mallocFailed ){ + int i; + char c; + pTerm->wtFlags |= TERM_LIKE; + for(i=0; (c = pStr1->u.zToken[i])!=0; i++){ + pStr1->u.zToken[i] = sqlite3Toupper(c); + pStr2->u.zToken[i] = sqlite3Tolower(c); + } + } + + if( !db->mallocFailed ){ + u8 *pC; /* Last character before the first wildcard */ + pC = (u8*)&pStr2->u.zToken[sqlite3Strlen30(pStr2->u.zToken)-1]; + if( noCase ){ + /* The point is to increment the last character before the first + ** wildcard. But if we increment '@', that will push it into the + ** alphabetic range where case conversions will mess up the + ** inequality. To avoid this, make sure to also run the full + ** LIKE on all candidate expressions by clearing the isComplete flag + */ + if( *pC=='A'-1 ) isComplete = 0; + *pC = sqlite3UpperToLower[*pC]; + } + + /* Increment the value of the last utf8 character in the prefix. */ + while( *pC==0xBF && pC>(u8*)pStr2->u.zToken ){ + *pC = 0x80; + pC--; + } + assert( *pC!=0xFF ); /* isLikeOrGlob() guarantees this */ + (*pC)++; + } + zCollSeqName = noCase ? "NOCASE" : sqlite3StrBINARY; + pNewExpr1 = sqlite3ExprDup(db, pLeft, 0); + pNewExpr1 = sqlite3PExpr(pParse, TK_GE, + sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName), + pStr1); + transferJoinMarkings(pNewExpr1, pExpr); + idxNew1 = whereClauseInsert(pWC, pNewExpr1, wtFlags); + testcase( idxNew1==0 ); + pNewExpr2 = sqlite3ExprDup(db, pLeft, 0); + pNewExpr2 = sqlite3PExpr(pParse, TK_LT, + sqlite3ExprAddCollateString(pParse,pNewExpr2,zCollSeqName), + pStr2); + transferJoinMarkings(pNewExpr2, pExpr); + idxNew2 = whereClauseInsert(pWC, pNewExpr2, wtFlags); + testcase( idxNew2==0 ); + exprAnalyze(pSrc, pWC, idxNew1); + exprAnalyze(pSrc, pWC, idxNew2); + pTerm = &pWC->a[idxTerm]; + if( isComplete ){ + markTermAsChild(pWC, idxNew1, idxTerm); + markTermAsChild(pWC, idxNew2, idxTerm); + } + } +#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */ + + /* If there is a vector == or IS term - e.g. "(a, b) == (?, ?)" - create + ** new terms for each component comparison - "a = ?" and "b = ?". The + ** new terms completely replace the original vector comparison, which is + ** no longer used. + ** + ** This is only required if at least one side of the comparison operation + ** is not a sub-select. + ** + ** tag-20220128a + */ + if( (pExpr->op==TK_EQ || pExpr->op==TK_IS) + && (nLeft = sqlite3ExprVectorSize(pExpr->pLeft))>1 + && sqlite3ExprVectorSize(pExpr->pRight)==nLeft + && ( (pExpr->pLeft->flags & EP_xIsSelect)==0 + || (pExpr->pRight->flags & EP_xIsSelect)==0) + && pWC->op==TK_AND + ){ + int i; + for(i=0; ipLeft, i, nLeft); + Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i, nLeft); + + pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight); + transferJoinMarkings(pNew, pExpr); + idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC|TERM_SLICE); + exprAnalyze(pSrc, pWC, idxNew); + } + pTerm = &pWC->a[idxTerm]; + pTerm->wtFlags |= TERM_CODED|TERM_VIRTUAL; /* Disable the original */ + pTerm->eOperator = WO_ROWVAL; + } + + /* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create + ** a virtual term for each vector component. The expression object + ** used by each such virtual term is pExpr (the full vector IN(...) + ** expression). The WhereTerm.u.x.iField variable identifies the index within + ** the vector on the LHS that the virtual term represents. + ** + ** This only works if the RHS is a simple SELECT (not a compound) that does + ** not use window functions. + */ + else if( pExpr->op==TK_IN + && pTerm->u.x.iField==0 + && pExpr->pLeft->op==TK_VECTOR + && ALWAYS( ExprUseXSelect(pExpr) ) + && (pExpr->x.pSelect->pPrior==0 || (pExpr->x.pSelect->selFlags & SF_Values)) +#ifndef SQLITE_OMIT_WINDOWFUNC + && pExpr->x.pSelect->pWin==0 +#endif + && pWC->op==TK_AND + && pExpr->x.pSelect->pEList->nExpr <= UMXV(pTerm->nChild) + /* ^-- See bug 2026-06-04T10:00:49Z */ + ){ + int i; + assert( pTerm->nChild==0 ); + for(i=0; ipLeft); i++){ + int idxNew; + idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL|TERM_SLICE); + pWC->a[idxNew].u.x.iField = i+1; + exprAnalyze(pSrc, pWC, idxNew); + markTermAsChild(pWC, idxNew, idxTerm); + } + } + +#ifndef SQLITE_OMIT_VIRTUALTABLE + /* Add a WO_AUX auxiliary term to the constraint set if the + ** current expression is of the form "column OP expr" where OP + ** is an operator that gets passed into virtual tables but which is + ** not normally optimized for ordinary tables. In other words, OP + ** is one of MATCH, LIKE, GLOB, REGEXP, !=, IS, IS NOT, or NOT NULL. + ** This information is used by the xBestIndex methods of + ** virtual tables. The native query optimizer does not attempt + ** to do anything with MATCH functions. + */ + else if( pWC->op==TK_AND ){ + Expr *pRight = 0, *pLeft = 0; + int res = isAuxiliaryVtabOperator(db, pExpr, &eOp2, &pLeft, &pRight); + while( res-- > 0 ){ + int idxNew; + WhereTerm *pNewTerm; + Bitmask prereqColumn, prereqExpr; + + prereqExpr = sqlite3WhereExprUsage(pMaskSet, pRight); + prereqColumn = sqlite3WhereExprUsage(pMaskSet, pLeft); + if( (prereqExpr & prereqColumn)==0 ){ + Expr *pNewExpr; + pNewExpr = sqlite3PExpr(pParse, TK_MATCH, + 0, sqlite3ExprDup(db, pRight, 0)); + if( ExprHasProperty(pExpr, EP_OuterON) && pNewExpr ){ + ExprSetProperty(pNewExpr, EP_OuterON); + pNewExpr->w.iJoin = pExpr->w.iJoin; + } + idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); + testcase( idxNew==0 ); + pNewTerm = &pWC->a[idxNew]; + pNewTerm->prereqRight = prereqExpr | extraRight; + pNewTerm->leftCursor = pLeft->iTable; + pNewTerm->u.x.leftColumn = pLeft->iColumn; + pNewTerm->eOperator = WO_AUX; + pNewTerm->eMatchOp = eOp2; + markTermAsChild(pWC, idxNew, idxTerm); + pTerm = &pWC->a[idxTerm]; + pTerm->wtFlags |= TERM_COPIED; + pNewTerm->prereqAll = pTerm->prereqAll; + } + SWAP(Expr*, pLeft, pRight); + } + } +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + + /* Prevent ON clause terms of a LEFT JOIN from being used to drive + ** an index for tables to the left of the join. + */ + testcase( pTerm!=&pWC->a[idxTerm] ); + pTerm = &pWC->a[idxTerm]; + pTerm->prereqRight |= extraRight; +} + +/*************************************************************************** +** Routines with file scope above. Interface to the rest of the where.c +** subsystem follows. +***************************************************************************/ + +/* +** This routine identifies subexpressions in the WHERE clause where +** each subexpression is separated by the AND operator or some other +** operator specified in the op parameter. The WhereClause structure +** is filled with pointers to subexpressions. For example: +** +** WHERE a=='hello' AND coalesce(b,11)<10 AND (c+12!=d OR c==22) +** \________/ \_______________/ \________________/ +** slot[0] slot[1] slot[2] +** +** The original WHERE clause in pExpr is unaltered. All this routine +** does is make slot[] entries point to substructure within pExpr. +** +** In the previous sentence and in the diagram, "slot[]" refers to +** the WhereClause.a[] array. The slot[] array grows as needed to contain +** all terms of the WHERE clause. +*/ +SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause *pWC, Expr *pExpr, u8 op){ + Expr *pE2 = sqlite3ExprSkipCollateAndLikely(pExpr); + pWC->op = op; + assert( pE2!=0 || pExpr==0 ); + if( pE2==0 ) return; + if( pE2->op!=op ){ + whereClauseInsert(pWC, pExpr, 0); + }else{ + sqlite3WhereSplit(pWC, pE2->pLeft, op); + sqlite3WhereSplit(pWC, pE2->pRight, op); + } +} + +/* +** Add either a LIMIT (if eMatchOp==SQLITE_INDEX_CONSTRAINT_LIMIT) or +** OFFSET (if eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET) term to the +** where-clause passed as the first argument. The value for the term +** is found in register iReg. +** +** In the common case where the value is a simple integer +** (example: "LIMIT 5 OFFSET 10") then the expression codes as a +** TK_INTEGER so that it will be available to sqlite3_vtab_rhs_value(). +** If not, then it codes as a TK_REGISTER expression. +*/ +static void whereAddLimitExpr( + WhereClause *pWC, /* Add the constraint to this WHERE clause */ + int iReg, /* Register that will hold value of the limit/offset */ + Expr *pExpr, /* Expression that defines the limit/offset */ + int iCsr, /* Cursor to which the constraint applies */ + int eMatchOp /* SQLITE_INDEX_CONSTRAINT_LIMIT or _OFFSET */ +){ + Parse *pParse = pWC->pWInfo->pParse; + sqlite3 *db = pParse->db; + Expr *pNew; + int iVal = 0; + + if( sqlite3ExprIsInteger(pExpr, &iVal, pParse) && iVal>=0 ){ + Expr *pVal = sqlite3ExprInt32(db, iVal); + if( pVal==0 ) return; + pNew = sqlite3PExpr(pParse, TK_MATCH, 0, pVal); + }else{ + Expr *pVal = sqlite3ExprAlloc(db, TK_REGISTER, 0, 0); + if( pVal==0 ) return; + pVal->iTable = iReg; + pNew = sqlite3PExpr(pParse, TK_MATCH, 0, pVal); + } + if( pNew ){ + WhereTerm *pTerm; + int idx; + idx = whereClauseInsert(pWC, pNew, TERM_DYNAMIC|TERM_VIRTUAL); + pTerm = &pWC->a[idx]; + pTerm->leftCursor = iCsr; + pTerm->eOperator = WO_AUX; + pTerm->eMatchOp = eMatchOp; + } +} + +/* +** Possibly add terms corresponding to the LIMIT and OFFSET clauses of the +** SELECT statement passed as the second argument. These terms are only +** added if: +** +** 1. The SELECT statement has a LIMIT clause, and +** 2. The SELECT statement is not an aggregate or DISTINCT query, and +** 3. The SELECT statement has exactly one object in its FROM clause, and +** that object is a virtual table, and +** 4. There are no terms in the WHERE clause that will not be passed +** to the virtual table xBestIndex method. +** 5. The ORDER BY clause, if any, will be made available to the xBestIndex +** method. +** +** LIMIT and OFFSET terms are ignored by most of the planner code. They +** exist only so that they may be passed to the xBestIndex method of the +** single virtual table in the FROM clause of the SELECT. +*/ +SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3WhereAddLimit(WhereClause *pWC, Select *p){ + assert( p!=0 && p->pLimit!=0 ); /* 1 -- checked by caller */ + if( p->pGroupBy==0 + && (p->selFlags & (SF_Distinct|SF_Aggregate))==0 /* 2 */ + && (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pSTab)) /* 3 */ + ){ + ExprList *pOrderBy = p->pOrderBy; + int iCsr = p->pSrc->a[0].iCursor; + int ii; + + /* Check condition (4). Return early if it is not met. */ + for(ii=0; iinTerm; ii++){ + if( pWC->a[ii].wtFlags & TERM_CODED ){ + /* This term is a vector operation that has been decomposed into + ** other, subsequent terms. It can be ignored. See tag-20220128a */ + assert( pWC->a[ii].wtFlags & TERM_VIRTUAL ); + assert( pWC->a[ii].eOperator==WO_ROWVAL ); + continue; + } + if( pWC->a[ii].nChild ){ + /* If this term has child terms, then they are also part of the + ** pWC->a[] array. So this term can be ignored, as a LIMIT clause + ** will only be added if each of the child terms passes the + ** (leftCursor==iCsr) test below. */ + continue; + } + if( pWC->a[ii].leftCursor==iCsr && pWC->a[ii].prereqRight==0 ) continue; + + /* If this term has a parent with exactly one child, and the parent will + ** be passed through to xBestIndex, then this term can be ignored. */ + if( pWC->a[ii].iParent>=0 ){ + WhereTerm *pParent = &pWC->a[ pWC->a[ii].iParent ]; + if( pParent->leftCursor==iCsr + && pParent->prereqRight==0 + && pParent->nChild==1 + ){ + continue; + } + } + + /* This term will not be passed through. Do not add a LIMIT clause. */ + return; + } + + /* Check condition (5). Return early if it is not met. */ + if( pOrderBy ){ + for(ii=0; iinExpr; ii++){ + Expr *pExpr = pOrderBy->a[ii].pExpr; + if( pExpr->op!=TK_COLUMN ) return; + if( pExpr->iTable!=iCsr ) return; + if( pOrderBy->a[ii].fg.sortFlags & KEYINFO_ORDER_BIGNULL ) return; + } + } + + /* All conditions are met. Add the terms to the where-clause object. */ + assert( p->pLimit->op==TK_LIMIT ); + if( p->iOffset!=0 && (p->selFlags & SF_Compound)==0 ){ + whereAddLimitExpr(pWC, p->iOffset, p->pLimit->pRight, + iCsr, SQLITE_INDEX_CONSTRAINT_OFFSET); + } + if( p->iOffset==0 || (p->selFlags & SF_Compound)==0 ){ + whereAddLimitExpr(pWC, p->iLimit, p->pLimit->pLeft, + iCsr, SQLITE_INDEX_CONSTRAINT_LIMIT); + } + } +} + +/* +** Initialize a preallocated WhereClause structure. +*/ +SQLITE_PRIVATE void sqlite3WhereClauseInit( + WhereClause *pWC, /* The WhereClause to be initialized */ + WhereInfo *pWInfo /* The WHERE processing context */ +){ + pWC->pWInfo = pWInfo; + pWC->hasOr = 0; + pWC->pOuter = 0; + pWC->nTerm = 0; + pWC->nBase = 0; + pWC->nSlot = ArraySize(pWC->aStatic); + pWC->a = pWC->aStatic; +} + +/* +** Deallocate a WhereClause structure. The WhereClause structure +** itself is not freed. This routine is the inverse of +** sqlite3WhereClauseInit(). +*/ +SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause *pWC){ + sqlite3 *db = pWC->pWInfo->pParse->db; + assert( pWC->nTerm>=pWC->nBase ); + if( pWC->nTerm>0 ){ + WhereTerm *a = pWC->a; + WhereTerm *aLast = &pWC->a[pWC->nTerm-1]; +#ifdef SQLITE_DEBUG + int i; + /* Verify that every term past pWC->nBase is virtual */ + for(i=pWC->nBase; inTerm; i++){ + assert( (pWC->a[i].wtFlags & TERM_VIRTUAL)!=0 ); + } +#endif + while(1){ + assert( a->eMatchOp==0 || a->eOperator==WO_AUX ); + if( a->wtFlags & TERM_DYNAMIC ){ + sqlite3ExprDelete(db, a->pExpr); + } + if( a->wtFlags & (TERM_ORINFO|TERM_ANDINFO) ){ + if( a->wtFlags & TERM_ORINFO ){ + assert( (a->wtFlags & TERM_ANDINFO)==0 ); + whereOrInfoDelete(db, a->u.pOrInfo); + }else{ + assert( (a->wtFlags & TERM_ANDINFO)!=0 ); + whereAndInfoDelete(db, a->u.pAndInfo); + } + } + if( a==aLast ) break; + a++; + } + } +} + + +/* +** These routines walk (recursively) an expression tree and generate +** a bitmask indicating which tables are used in that expression +** tree. +** +** sqlite3WhereExprUsage(MaskSet, Expr) -> +** +** Return a Bitmask of all tables referenced by Expr. Expr can be +** be NULL, in which case 0 is returned. +** +** sqlite3WhereExprUsageNN(MaskSet, Expr) -> +** +** Same as sqlite3WhereExprUsage() except that Expr must not be +** NULL. The "NN" suffix on the name stands for "Not Null". +** +** sqlite3WhereExprListUsage(MaskSet, ExprList) -> +** +** Return a Bitmask of all tables referenced by every expression +** in the expression list ExprList. ExprList can be NULL, in which +** case 0 is returned. +** +** sqlite3WhereExprUsageFull(MaskSet, ExprList) -> +** +** Internal use only. Called only by sqlite3WhereExprUsageNN() for +** complex expressions that require pushing register values onto +** the stack. Many calls to sqlite3WhereExprUsageNN() do not need +** the more complex analysis done by this routine. Hence, the +** computations done by this routine are broken out into a separate +** "no-inline" function to avoid the stack push overhead in the +** common case where it is not needed. +*/ +static SQLITE_NOINLINE Bitmask sqlite3WhereExprUsageFull( + WhereMaskSet *pMaskSet, + Expr *p +){ + Bitmask mask; + mask = (p->op==TK_IF_NULL_ROW) ? sqlite3WhereGetMask(pMaskSet, p->iTable) : 0; + if( p->pLeft ) mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pLeft); + if( p->pRight ){ + mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pRight); + assert( p->x.pList==0 ); + }else if( ExprUseXSelect(p) ){ + if( ExprHasProperty(p, EP_VarSelect) ) pMaskSet->bVarSelect = 1; + mask |= exprSelectUsage(pMaskSet, p->x.pSelect); + }else if( p->x.pList ){ + mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList); + } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( (p->op==TK_FUNCTION || p->op==TK_AGG_FUNCTION) && ExprUseYWin(p) ){ + assert( p->y.pWin!=0 ); + mask |= sqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pPartition); + mask |= sqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pOrderBy); + mask |= sqlite3WhereExprUsage(pMaskSet, p->y.pWin->pFilter); + } +#endif + return mask; +} +SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet *pMaskSet, Expr *p){ + if( p->op==TK_COLUMN && !ExprHasProperty(p, EP_FixedCol) ){ + return sqlite3WhereGetMask(pMaskSet, p->iTable); + }else if( ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){ + assert( p->op!=TK_IF_NULL_ROW ); + return 0; + } + return sqlite3WhereExprUsageFull(pMaskSet, p); +} +SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){ + return p ? sqlite3WhereExprUsageNN(pMaskSet,p) : 0; +} +SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet *pMaskSet, ExprList *pList){ + int i; + Bitmask mask = 0; + if( pList ){ + for(i=0; inExpr; i++){ + mask |= sqlite3WhereExprUsage(pMaskSet, pList->a[i].pExpr); + } + } + return mask; +} + + +/* +** Call exprAnalyze on all terms in a WHERE clause. +** +** Note that exprAnalyze() might add new virtual terms onto the +** end of the WHERE clause. We do not want to analyze these new +** virtual terms, so start analyzing at the end and work forward +** so that the added virtual terms are never processed. +*/ +SQLITE_PRIVATE void sqlite3WhereExprAnalyze( + SrcList *pTabList, /* the FROM clause */ + WhereClause *pWC /* the WHERE clause to be analyzed */ +){ + int i; + for(i=pWC->nTerm-1; i>=0; i--){ + exprAnalyze(pTabList, pWC, i); + } +} + +/* +** For table-valued-functions, transform the function arguments into +** new WHERE clause terms. +** +** Each function argument translates into an equality constraint against +** a HIDDEN column in the table. +*/ +SQLITE_PRIVATE void sqlite3WhereTabFuncArgs( + Parse *pParse, /* Parsing context */ + SrcItem *pItem, /* The FROM clause term to process */ + WhereClause *pWC /* Xfer function arguments to here */ +){ + Table *pTab; + int j, k; + ExprList *pArgs; + Expr *pColRef; + Expr *pTerm; + if( pItem->fg.isTabFunc==0 ) return; + pTab = pItem->pSTab; + assert( pTab!=0 ); + pArgs = pItem->u1.pFuncArg; + if( pArgs==0 ) return; + for(j=k=0; jnExpr; j++){ + Expr *pRhs; + u32 joinType; + while( knCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;} + if( k>=pTab->nCol ){ + sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d", + pTab->zName, j); + return; + } + pColRef = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0); + if( pColRef==0 ) return; + pColRef->iTable = pItem->iCursor; + pColRef->iColumn = k++; + assert( ExprUseYTab(pColRef) ); + pColRef->y.pTab = pTab; + pItem->colUsed |= sqlite3ExprColUsed(pColRef); + pRhs = sqlite3PExpr(pParse, TK_UPLUS, + sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0); + pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs); + if( pItem->fg.jointype & (JT_LEFT|JT_RIGHT) ){ + testcase( pItem->fg.jointype & JT_LEFT ); /* testtag-20230227a */ + testcase( pItem->fg.jointype & JT_RIGHT ); /* testtag-20230227b */ + joinType = EP_OuterON; + }else{ + testcase( pItem->fg.jointype & JT_LTORJ ); /* testtag-20230227c */ + joinType = EP_InnerON; + } + sqlite3SetJoinExpr(pTerm, pItem->iCursor, joinType); + whereClauseInsert(pWC, pTerm, TERM_DYNAMIC); + } +} + +/************** End of whereexpr.c *******************************************/ +/************** Begin file where.c *******************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This module contains C code that generates VDBE code used to process +** the WHERE clause of SQL statements. This module is responsible for +** generating the code that loops through a table looking for applicable +** rows. Indices are selected and used to speed the search when doing +** so is applicable. Because this module is responsible for selecting +** indices, you might also think of this module as the "query optimizer". +*/ +/* #include "sqliteInt.h" */ +/* #include "whereInt.h" */ + +/* +** Extra information appended to the end of sqlite3_index_info but not +** visible to the xBestIndex function, at least not directly. The +** sqlite3_vtab_collation() interface knows how to reach it, however. +** +** This object is not an API and can be changed from one release to the +** next. As long as allocateIndexInfo() and sqlite3_vtab_collation() +** agree on the structure, all will be well. +*/ +typedef struct HiddenIndexInfo HiddenIndexInfo; +struct HiddenIndexInfo { + WhereClause *pWC; /* The Where clause being analyzed */ + Parse *pParse; /* The parsing context */ + int eDistinct; /* Value to return from sqlite3_vtab_distinct() */ + u32 mIn; /* Mask of terms that are IN (...) */ + u32 mHandleIn; /* Terms that vtab will handle as IN (...) */ + sqlite3_value *aRhs[FLEXARRAY]; /* RHS values for constraints. MUST BE LAST + ** Extra space is allocated to hold up + ** to nTerm such values */ +}; + +/* Size (in bytes) of a HiddenIndeInfo object sufficient to hold as +** many as N constraints */ +#define SZ_HIDDENINDEXINFO(N) \ + (offsetof(HiddenIndexInfo,aRhs) + (N)*sizeof(sqlite3_value*)) + +/* Forward declaration of methods */ +static int whereLoopResize(sqlite3*, WhereLoop*, int); + +/* +** Return the estimated number of output rows from a WHERE clause +*/ +SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo *pWInfo){ + return pWInfo->nRowOut; +} + +/* +** Return one of the WHERE_DISTINCT_xxxxx values to indicate how this +** WHERE clause returns outputs for DISTINCT processing. +*/ +SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo *pWInfo){ + return pWInfo->eDistinct; +} + +/* +** Return the number of ORDER BY terms that are satisfied by the +** WHERE clause. A return of 0 means that the output must be +** completely sorted. A return equal to the number of ORDER BY +** terms means that no sorting is needed at all. A return that +** is positive but less than the number of ORDER BY terms means that +** block sorting is required. +*/ +SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo *pWInfo){ + return pWInfo->nOBSat<0 ? 0 : pWInfo->nOBSat; +} + +/* +** In the ORDER BY LIMIT optimization, if the inner-most loop is known +** to emit rows in increasing order, and if the last row emitted by the +** inner-most loop did not fit within the sorter, then we can skip all +** subsequent rows for the current iteration of the inner loop (because they +** will not fit in the sorter either) and continue with the second inner +** loop - the loop immediately outside the inner-most. +** +** When a row does not fit in the sorter (because the sorter already +** holds LIMIT+OFFSET rows that are smaller), then a jump is made to the +** label returned by this function. +** +** If the ORDER BY LIMIT optimization applies, the jump destination should +** be the continuation for the second-inner-most loop. If the ORDER BY +** LIMIT optimization does not apply, then the jump destination should +** be the continuation for the inner-most loop. +** +** It is always safe for this routine to return the continuation of the +** inner-most loop, in the sense that a correct answer will result. +** Returning the continuation the second inner loop is an optimization +** that might make the code run a little faster, but should not change +** the final answer. +*/ +SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo *pWInfo){ + WhereLevel *pInner; + if( !pWInfo->bOrderedInnerLoop ){ + /* The ORDER BY LIMIT optimization does not apply. Jump to the + ** continuation of the inner-most loop. */ + return pWInfo->iContinue; + } + pInner = &pWInfo->a[pWInfo->nLevel-1]; + assert( pInner->addrNxt!=0 ); + return pInner->pRJ ? pWInfo->iContinue : pInner->addrNxt; +} + +/* +** While generating code for the min/max optimization, after handling +** the aggregate-step call to min() or max(), check to see if any +** additional looping is required. If the output order is such that +** we are certain that the correct answer has already been found, then +** code an OP_Goto to by pass subsequent processing. +** +** Any extra OP_Goto that is coded here is an optimization. The +** correct answer should be obtained regardless. This OP_Goto just +** makes the answer appear faster. +*/ +SQLITE_PRIVATE void sqlite3WhereMinMaxOptEarlyOut(Vdbe *v, WhereInfo *pWInfo){ + WhereLevel *pInner; + int i; + if( !pWInfo->bOrderedInnerLoop ) return; + if( pWInfo->nOBSat==0 ) return; + for(i=pWInfo->nLevel-1; i>=0; i--){ + pInner = &pWInfo->a[i]; + if( (pInner->pWLoop->wsFlags & WHERE_COLUMN_IN)!=0 ){ + sqlite3VdbeGoto(v, pInner->addrNxt); + return; + } + } + sqlite3VdbeGoto(v, pWInfo->iBreak); +} + +/* +** Return the VDBE address or label to jump to in order to continue +** immediately with the next row of a WHERE clause. +*/ +SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo *pWInfo){ + assert( pWInfo->iContinue!=0 ); + return pWInfo->iContinue; +} + +/* +** Return the VDBE address or label to jump to in order to break +** out of a WHERE loop. +*/ +SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo *pWInfo){ + return pWInfo->iBreak; +} + +/* +** Return ONEPASS_OFF (0) if an UPDATE or DELETE statement is unable to +** operate directly on the rowids returned by a WHERE clause. Return +** ONEPASS_SINGLE (1) if the statement can operation directly because only +** a single row is to be changed. Return ONEPASS_MULTI (2) if the one-pass +** optimization can be used on multiple +** +** If the ONEPASS optimization is used (if this routine returns true) +** then also write the indices of open cursors used by ONEPASS +** into aiCur[0] and aiCur[1]. iaCur[0] gets the cursor of the data +** table and iaCur[1] gets the cursor used by an auxiliary index. +** Either value may be -1, indicating that cursor is not used. +** Any cursors returned will have been opened for writing. +** +** aiCur[0] and aiCur[1] both get -1 if the where-clause logic is +** unable to use the ONEPASS optimization. +*/ +SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo *pWInfo, int *aiCur){ + memcpy(aiCur, pWInfo->aiCurOnePass, sizeof(int)*2); +#ifdef WHERETRACE_ENABLED + if( sqlite3WhereTrace && pWInfo->eOnePass!=ONEPASS_OFF ){ + sqlite3DebugPrintf("%s cursors: %d %d\n", + pWInfo->eOnePass==ONEPASS_SINGLE ? "ONEPASS_SINGLE" : "ONEPASS_MULTI", + aiCur[0], aiCur[1]); + } +#endif + return pWInfo->eOnePass; +} + +/* +** Return TRUE if the WHERE loop uses the OP_DeferredSeek opcode to move +** the data cursor to the row selected by the index cursor. +*/ +SQLITE_PRIVATE int sqlite3WhereUsesDeferredSeek(WhereInfo *pWInfo){ + return pWInfo->bDeferredSeek; +} + +/* +** Move the content of pSrc into pDest +*/ +static void whereOrMove(WhereOrSet *pDest, WhereOrSet *pSrc){ + pDest->n = pSrc->n; + memcpy(pDest->a, pSrc->a, pDest->n*sizeof(pDest->a[0])); +} + +/* +** Try to insert a new prerequisite/cost entry into the WhereOrSet pSet. +** +** The new entry might overwrite an existing entry, or it might be +** appended, or it might be discarded. Do whatever is the right thing +** so that pSet keeps the N_OR_COST best entries seen so far. +*/ +static int whereOrInsert( + WhereOrSet *pSet, /* The WhereOrSet to be updated */ + Bitmask prereq, /* Prerequisites of the new entry */ + LogEst rRun, /* Run-cost of the new entry */ + LogEst nOut /* Number of outputs for the new entry */ +){ + u16 i; + WhereOrCost *p; + for(i=pSet->n, p=pSet->a; i>0; i--, p++){ + if( rRun<=p->rRun && (prereq & p->prereq)==prereq ){ + goto whereOrInsert_done; + } + if( p->rRun<=rRun && (p->prereq & prereq)==p->prereq ){ + return 0; + } + } + if( pSet->na[pSet->n++]; + p->nOut = nOut; + }else{ + p = pSet->a; + for(i=1; in; i++){ + if( p->rRun>pSet->a[i].rRun ) p = pSet->a + i; + } + if( p->rRun<=rRun ) return 0; + } +whereOrInsert_done: + p->prereq = prereq; + p->rRun = rRun; + if( p->nOut>nOut ) p->nOut = nOut; + return 1; +} + +/* +** Return the bitmask for the given cursor number. Return 0 if +** iCursor is not in the set. +*/ +SQLITE_PRIVATE Bitmask sqlite3WhereGetMask(WhereMaskSet *pMaskSet, int iCursor){ + int i; + assert( pMaskSet->n<=(int)sizeof(Bitmask)*8 ); + assert( pMaskSet->n>0 || pMaskSet->ix[0]<0 ); + assert( iCursor>=-1 ); + if( pMaskSet->ix[0]==iCursor ){ + return 1; + } + for(i=1; in; i++){ + if( pMaskSet->ix[i]==iCursor ){ + return MASKBIT(i); + } + } + return 0; +} + +/* Allocate memory that is automatically freed when pWInfo is freed. +*/ +SQLITE_PRIVATE void *sqlite3WhereMalloc(WhereInfo *pWInfo, u64 nByte){ + WhereMemBlock *pBlock; + pBlock = sqlite3DbMallocRawNN(pWInfo->pParse->db, nByte+sizeof(*pBlock)); + if( pBlock ){ + pBlock->pNext = pWInfo->pMemToFree; + pBlock->sz = nByte; + pWInfo->pMemToFree = pBlock; + pBlock++; + } + return (void*)pBlock; +} +SQLITE_PRIVATE void *sqlite3WhereRealloc(WhereInfo *pWInfo, void *pOld, u64 nByte){ + void *pNew = sqlite3WhereMalloc(pWInfo, nByte); + if( pNew && pOld ){ + WhereMemBlock *pOldBlk = (WhereMemBlock*)pOld; + pOldBlk--; + assert( pOldBlk->szsz); + } + return pNew; +} + +/* +** Create a new mask for cursor iCursor. +** +** There is one cursor per table in the FROM clause. The number of +** tables in the FROM clause is limited by a test early in the +** sqlite3WhereBegin() routine. So we know that the pMaskSet->ix[] +** array will never overflow. +*/ +static void createMask(WhereMaskSet *pMaskSet, int iCursor){ + assert( pMaskSet->n < ArraySize(pMaskSet->ix) ); + pMaskSet->ix[pMaskSet->n++] = iCursor; +} + +/* +** If the right-hand branch of the expression is a TK_COLUMN, then return +** a pointer to the right-hand branch. Otherwise, return NULL. +*/ +static Expr *whereRightSubexprIsColumn(Expr *p){ + p = sqlite3ExprSkipCollateAndLikely(p->pRight); + if( ALWAYS(p!=0) && p->op==TK_COLUMN && !ExprHasProperty(p, EP_FixedCol) ){ + return p; + } + return 0; +} + +/* +** Term pTerm is guaranteed to be a WO_IN term. It may be a component term +** of a vector IN expression of the form "(x, y, ...) IN (SELECT ...)". +** This function checks to see if the term is compatible with an index +** column with affinity idxaff (one of the SQLITE_AFF_XYZ values). If so, +** it returns a pointer to the name of the collation sequence (e.g. "BINARY" +** or "NOCASE") used by the comparison in pTerm. If it is not compatible +** with affinity idxaff, NULL is returned. +*/ +static SQLITE_NOINLINE const char *indexInAffinityOk( + Parse *pParse, + WhereTerm *pTerm, + u8 idxaff +){ + Expr *pX = pTerm->pExpr; + Expr inexpr; + + assert( pTerm->eOperator & WO_IN ); + + if( sqlite3ExprIsVector(pX->pLeft) ){ + int iField = pTerm->u.x.iField - 1; + inexpr.flags = 0; + inexpr.op = TK_EQ; + inexpr.pLeft = pX->pLeft->x.pList->a[iField].pExpr; + assert( ExprUseXSelect(pX) ); + inexpr.pRight = pX->x.pSelect->pEList->a[iField].pExpr; + pX = &inexpr; + } + + if( sqlite3IndexAffinityOk(pX, idxaff) ){ + CollSeq *pRet = sqlite3ExprCompareCollSeq(pParse, pX); + return pRet ? pRet->zName : sqlite3StrBINARY; + } + return 0; +} + +/* +** Advance to the next WhereTerm that matches according to the criteria +** established when the pScan object was initialized by whereScanInit(). +** Return NULL if there are no more matching WhereTerms. +*/ +static WhereTerm *whereScanNext(WhereScan *pScan){ + int iCur; /* The cursor on the LHS of the term */ + i16 iColumn; /* The column on the LHS of the term. -1 for IPK */ + Expr *pX; /* An expression being tested */ + WhereClause *pWC; /* Shorthand for pScan->pWC */ + WhereTerm *pTerm; /* The term being tested */ + int k = pScan->k; /* Where to start scanning */ + + assert( pScan->iEquiv<=pScan->nEquiv ); + pWC = pScan->pWC; + while(1){ + iColumn = pScan->aiColumn[pScan->iEquiv-1]; + iCur = pScan->aiCur[pScan->iEquiv-1]; + assert( pWC!=0 ); + assert( iCur>=0 ); + do{ + for(pTerm=pWC->a+k; knTerm; k++, pTerm++){ + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 || pTerm->leftCursor<0 ); + if( pTerm->leftCursor==iCur + && pTerm->u.x.leftColumn==iColumn + && (iColumn!=XN_EXPR + || sqlite3ExprCompareSkip(pTerm->pExpr->pLeft, + pScan->pIdxExpr,iCur)==0) + && (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_OuterON)) + ){ + if( (pTerm->eOperator & WO_EQUIV)!=0 + && pScan->nEquivaiCur) + && (pX = whereRightSubexprIsColumn(pTerm->pExpr))!=0 + ){ + int j; + for(j=0; jnEquiv; j++){ + if( pScan->aiCur[j]==pX->iTable + && pScan->aiColumn[j]==pX->iColumn ){ + break; + } + } + if( j==pScan->nEquiv ){ + pScan->aiCur[j] = pX->iTable; + pScan->aiColumn[j] = pX->iColumn; + pScan->nEquiv++; + } + } + if( (pTerm->eOperator & pScan->opMask)!=0 ){ + /* Verify the affinity and collating sequence match */ + if( pScan->zCollName && (pTerm->eOperator & WO_ISNULL)==0 ){ + const char *zCollName; + Parse *pParse = pWC->pWInfo->pParse; + pX = pTerm->pExpr; + + if( (pTerm->eOperator & WO_IN) ){ + zCollName = indexInAffinityOk(pParse, pTerm, pScan->idxaff); + if( !zCollName ) continue; + }else{ + CollSeq *pColl; + if( !sqlite3IndexAffinityOk(pX, pScan->idxaff) ){ + continue; + } + assert(pX->pLeft); + pColl = sqlite3ExprCompareCollSeq(pParse, pX); + zCollName = pColl ? pColl->zName : sqlite3StrBINARY; + } + + if( sqlite3StrICmp(zCollName, pScan->zCollName) ){ + continue; + } + } + if( (pTerm->eOperator & (WO_EQ|WO_IS))!=0 + && (pX = pTerm->pExpr->pRight, ALWAYS(pX!=0)) + && pX->op==TK_COLUMN + && pX->iTable==pScan->aiCur[0] + && pX->iColumn==pScan->aiColumn[0] + ){ + testcase( pTerm->eOperator & WO_IS ); + continue; + } + pScan->pWC = pWC; + pScan->k = k+1; +#ifdef WHERETRACE_ENABLED + if( (sqlite3WhereTrace & 0x20000)!=0 && pScan->nEquiv>1 ){ + int ii; + sqlite3DebugPrintf("EQUIVALENT TO {%d:%d} (due to TERM-%d):", + pScan->aiCur[0], pScan->aiColumn[0], pTerm->iTerm); + for(ii=1; iinEquiv; ii++){ + sqlite3DebugPrintf(" {%d:%d}", + pScan->aiCur[ii], pScan->aiColumn[ii]); + } + sqlite3DebugPrintf("\n"); + } +#endif + return pTerm; + } + } + } + pWC = pWC->pOuter; + k = 0; + }while( pWC!=0 ); + if( pScan->iEquiv>=pScan->nEquiv ) break; + pWC = pScan->pOrigWC; + k = 0; + pScan->iEquiv++; + } + return 0; +} + +/* +** This is whereScanInit() for the case of an index on an expression. +** It is factored out into a separate tail-recursion subroutine so that +** the normal whereScanInit() routine, which is a high-runner, does not +** need to push registers onto the stack as part of its prologue. +*/ +static SQLITE_NOINLINE WhereTerm *whereScanInitIndexExpr(WhereScan *pScan){ + pScan->idxaff = sqlite3ExprAffinity(pScan->pIdxExpr); + return whereScanNext(pScan); +} + +/* +** Initialize a WHERE clause scanner object. Return a pointer to the +** first match. Return NULL if there are no matches. +** +** The scanner will be searching the WHERE clause pWC. It will look +** for terms of the form "X " where X is column iColumn of table +** iCur. Or if pIdx!=0 then X is column iColumn of index pIdx. pIdx +** must be one of the indexes of table iCur. +** +** The must be one of the operators described by opMask. +** +** If the search is for X and the WHERE clause contains terms of the +** form X=Y then this routine might also return terms of the form +** "Y ". The number of levels of transitivity is limited, +** but is enough to handle most commonly occurring SQL statements. +** +** If X is not the INTEGER PRIMARY KEY then X must be compatible with +** index pIdx. +*/ +static WhereTerm *whereScanInit( + WhereScan *pScan, /* The WhereScan object being initialized */ + WhereClause *pWC, /* The WHERE clause to be scanned */ + int iCur, /* Cursor to scan for */ + int iColumn, /* Column to scan for */ + u32 opMask, /* Operator(s) to scan for */ + Index *pIdx /* Must be compatible with this index */ +){ + pScan->pOrigWC = pWC; + pScan->pWC = pWC; + pScan->pIdxExpr = 0; + pScan->idxaff = 0; + pScan->zCollName = 0; + pScan->opMask = opMask; + pScan->k = 0; + pScan->aiCur[0] = iCur; + pScan->nEquiv = 1; + pScan->iEquiv = 1; + if( pIdx ){ + int j = iColumn; + iColumn = pIdx->aiColumn[j]; + if( iColumn==pIdx->pTable->iPKey ){ + iColumn = XN_ROWID; + }else if( iColumn>=0 ){ + pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity; + pScan->zCollName = pIdx->azColl[j]; + }else if( iColumn==XN_EXPR ){ + pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr; + pScan->zCollName = pIdx->azColl[j]; + pScan->aiColumn[0] = XN_EXPR; + return whereScanInitIndexExpr(pScan); + } + }else if( iColumn==XN_EXPR ){ + return 0; + } + pScan->aiColumn[0] = iColumn; + return whereScanNext(pScan); +} + +/* +** Search for a term in the WHERE clause that is of the form "X " +** where X is a reference to the iColumn of table iCur or of index pIdx +** if pIdx!=0 and is one of the WO_xx operator codes specified by +** the op parameter. Return a pointer to the term. Return 0 if not found. +** +** If pIdx!=0 then it must be one of the indexes of table iCur. +** Search for terms matching the iColumn-th column of pIdx +** rather than the iColumn-th column of table iCur. +** +** The term returned might by Y= if there is another constraint in +** the WHERE clause that specifies that X=Y. Any such constraints will be +** identified by the WO_EQUIV bit in the pTerm->eOperator field. The +** aiCur[]/iaColumn[] arrays hold X and all its equivalents. There are 11 +** slots in aiCur[]/aiColumn[] so that means we can look for X plus up to 10 +** other equivalent values. Hence a search for X will return if X=A1 +** and A1=A2 and A2=A3 and ... and A9=A10 and A10=. +** +** If there are multiple terms in the WHERE clause of the form "X " +** then try for the one with no dependencies on - in other words where +** is a constant expression of some kind. Only return entries of +** the form "X Y" where Y is a column in another table if no terms of +** the form "X " exist. If no terms with a constant RHS +** exist, try to return a term that does not use WO_EQUIV. +*/ +SQLITE_PRIVATE WhereTerm *sqlite3WhereFindTerm( + WhereClause *pWC, /* The WHERE clause to be searched */ + int iCur, /* Cursor number of LHS */ + int iColumn, /* Column number of LHS */ + Bitmask notReady, /* RHS must not overlap with this mask */ + u32 op, /* Mask of WO_xx values describing operator */ + Index *pIdx /* Must be compatible with this index, if not NULL */ +){ + WhereTerm *pResult = 0; + WhereTerm *p; + WhereScan scan; + + p = whereScanInit(&scan, pWC, iCur, iColumn, op, pIdx); + op &= WO_EQ|WO_IS; + while( p ){ + if( (p->prereqRight & notReady)==0 ){ + if( p->prereqRight==0 && (p->eOperator&op)!=0 ){ + testcase( p->eOperator & WO_IS ); + return p; + } + if( pResult==0 ) pResult = p; + } + p = whereScanNext(&scan); + } + return pResult; +} + +/* +** This function searches pList for an entry that matches the iCol-th column +** of index pIdx. +** +** If such an expression is found, its index in pList->a[] is returned. If +** no expression is found, -1 is returned. +*/ +static int findIndexCol( + Parse *pParse, /* Parse context */ + ExprList *pList, /* Expression list to search */ + int iBase, /* Cursor for table associated with pIdx */ + Index *pIdx, /* Index to match column of */ + int iCol /* Column of index to match */ +){ + int i; + const char *zColl = pIdx->azColl[iCol]; + + for(i=0; inExpr; i++){ + Expr *p = sqlite3ExprSkipCollateAndLikely(pList->a[i].pExpr); + if( ALWAYS(p!=0) + && (p->op==TK_COLUMN || p->op==TK_AGG_COLUMN) + && p->iColumn==pIdx->aiColumn[iCol] + && p->iTable==iBase + ){ + CollSeq *pColl = sqlite3ExprNNCollSeq(pParse, pList->a[i].pExpr); + if( 0==sqlite3StrICmp(pColl->zName, zColl) ){ + return i; + } + } + } + + return -1; +} + +/* +** Return TRUE if the iCol-th column of index pIdx is NOT NULL +*/ +static int indexColumnNotNull(Index *pIdx, int iCol){ + int j; + assert( pIdx!=0 ); + assert( iCol>=0 && iColnColumn ); + j = pIdx->aiColumn[iCol]; + if( j>=0 ){ + return pIdx->pTable->aCol[j].notNull; + }else if( j==(-1) ){ + return 1; + }else{ + assert( j==(-2) ); + return 0; /* Assume an indexed expression can always yield a NULL */ + + } +} + +/* +** Return true if the DISTINCT expression-list passed as the third argument +** is redundant. +** +** A DISTINCT list is redundant if any subset of the columns in the +** DISTINCT list are collectively unique and individually non-null. +*/ +static int isDistinctRedundant( + Parse *pParse, /* Parsing context */ + SrcList *pTabList, /* The FROM clause */ + WhereClause *pWC, /* The WHERE clause */ + ExprList *pDistinct /* The result set that needs to be DISTINCT */ +){ + Table *pTab; + Index *pIdx; + int i; + int iBase; + + /* If there is more than one table or sub-select in the FROM clause of + ** this query, then it will not be possible to show that the DISTINCT + ** clause is redundant. */ + if( pTabList->nSrc!=1 ) return 0; + iBase = pTabList->a[0].iCursor; + pTab = pTabList->a[0].pSTab; + + /* If any of the expressions is an IPK column on table iBase, then return + ** true. Note: The (p->iTable==iBase) part of this test may be false if the + ** current SELECT is a correlated sub-query. + */ + for(i=0; inExpr; i++){ + Expr *p = sqlite3ExprSkipCollateAndLikely(pDistinct->a[i].pExpr); + if( NEVER(p==0) ) continue; + if( p->op!=TK_COLUMN && p->op!=TK_AGG_COLUMN ) continue; + if( p->iTable==iBase && p->iColumn<0 ) return 1; + } + + /* Loop through all indices on the table, checking each to see if it makes + ** the DISTINCT qualifier redundant. It does so if: + ** + ** 1. The index is itself UNIQUE, and + ** + ** 2. All of the columns in the index are either part of the pDistinct + ** list, or else the WHERE clause contains a term of the form "col=X", + ** where X is a constant value. The collation sequences of the + ** comparison and select-list expressions must match those of the index. + ** + ** 3. All of those index columns for which the WHERE clause does not + ** contain a "col=X" term are subject to a NOT NULL constraint. + */ + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + if( !IsUniqueIndex(pIdx) ) continue; + if( pIdx->pPartIdxWhere ) continue; + for(i=0; inKeyCol; i++){ + if( 0==sqlite3WhereFindTerm(pWC, iBase, i, ~(Bitmask)0, WO_EQ, pIdx) ){ + if( findIndexCol(pParse, pDistinct, iBase, pIdx, i)<0 ) break; + if( indexColumnNotNull(pIdx, i)==0 ) break; + } + } + if( i==pIdx->nKeyCol ){ + /* This index implies that the DISTINCT qualifier is redundant. */ + return 1; + } + } + + return 0; +} + + +/* +** Estimate the logarithm of the input value to base 2. +*/ +static LogEst estLog(LogEst N){ + return N<=10 ? 0 : sqlite3LogEst(N) - 33; +} + +/* +** Convert OP_Column opcodes to OP_Copy in previously generated code. +** +** This routine runs over generated VDBE code and translates OP_Column +** opcodes into OP_Copy when the table is being accessed via co-routine +** instead of via table lookup. +** +** If the iAutoidxCur is not zero, then any OP_Rowid instructions on +** cursor iTabCur are transformed into OP_Sequence opcode for the +** iAutoidxCur cursor, in order to generate unique rowids for the +** automatic index being generated. +*/ +static void translateColumnToCopy( + Parse *pParse, /* Parsing context */ + int iStart, /* Translate from this opcode to the end */ + int iTabCur, /* OP_Column/OP_Rowid references to this table */ + int iRegister, /* The first column is in this register */ + int iAutoidxCur /* If non-zero, cursor of autoindex being generated */ +){ + Vdbe *v = pParse->pVdbe; + VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart); + int iEnd = sqlite3VdbeCurrentAddr(v); + if( pParse->db->mallocFailed ) return; +#ifdef SQLITE_DEBUG + if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ + printf("CHECKING for column-to-copy on cursor %d for %d..%d\n", + iTabCur, iStart, iEnd); + } +#endif + for(; iStartp1!=iTabCur ) continue; + if( pOp->opcode==OP_Column ){ +#ifdef SQLITE_DEBUG + if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ + printf("TRANSLATE OP_Column to OP_Copy at %d\n", iStart); + } +#endif + pOp->opcode = OP_Copy; + pOp->p1 = pOp->p2 + iRegister; + pOp->p2 = pOp->p3; + pOp->p3 = 0; + pOp->p5 = 2; /* Cause the MEM_Subtype flag to be cleared */ + }else if( pOp->opcode==OP_Rowid ){ +#ifdef SQLITE_DEBUG + if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ + printf("TRANSLATE OP_Rowid to OP_Sequence at %d\n", iStart); + } +#endif + pOp->opcode = OP_Sequence; + pOp->p1 = iAutoidxCur; +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + if( iAutoidxCur==0 ){ + pOp->opcode = OP_Null; + pOp->p3 = 0; + } +#endif + } + } +} + +/* +** Two routines for printing the content of an sqlite3_index_info +** structure. Used for testing and debugging only. If neither +** SQLITE_TEST or SQLITE_DEBUG are defined, then these routines +** are no-ops. +*/ +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(WHERETRACE_ENABLED) +static void whereTraceIndexInfoInputs( + sqlite3_index_info *p, /* The IndexInfo object */ + Table *pTab /* The TABLE that is the virtual table */ +){ + int i; + if( (sqlite3WhereTrace & 0x10)==0 ) return; + sqlite3DebugPrintf("sqlite3_index_info inputs for %s:\n", pTab->zName); + for(i=0; inConstraint; i++){ + sqlite3DebugPrintf( + " constraint[%d]: col=%d termid=%d op=%d usabled=%d collseq=%s\n", + i, + p->aConstraint[i].iColumn, + p->aConstraint[i].iTermOffset, + p->aConstraint[i].op, + p->aConstraint[i].usable, + sqlite3_vtab_collation(p,i)); + } + for(i=0; inOrderBy; i++){ + sqlite3DebugPrintf(" orderby[%d]: col=%d desc=%d\n", + i, + p->aOrderBy[i].iColumn, + p->aOrderBy[i].desc); + } +} +static void whereTraceIndexInfoOutputs( + sqlite3_index_info *p, /* The IndexInfo object */ + Table *pTab /* The TABLE that is the virtual table */ +){ + int i; + if( (sqlite3WhereTrace & 0x10)==0 ) return; + sqlite3DebugPrintf("sqlite3_index_info outputs for %s:\n", pTab->zName); + for(i=0; inConstraint; i++){ + sqlite3DebugPrintf(" usage[%d]: argvIdx=%d omit=%d\n", + i, + p->aConstraintUsage[i].argvIndex, + p->aConstraintUsage[i].omit); + } + sqlite3DebugPrintf(" idxNum=%d\n", p->idxNum); + sqlite3DebugPrintf(" idxStr=%s\n", p->idxStr); + sqlite3DebugPrintf(" orderByConsumed=%d\n", p->orderByConsumed); + sqlite3DebugPrintf(" estimatedCost=%g\n", p->estimatedCost); + sqlite3DebugPrintf(" estimatedRows=%lld\n", p->estimatedRows); +} +#else +#define whereTraceIndexInfoInputs(A,B) +#define whereTraceIndexInfoOutputs(A,B) +#endif + +/* +** We know that pSrc is an operand of an outer join. Return true if +** pTerm is a constraint that is compatible with that join. +** +** pTerm must be EP_OuterON if pSrc is the right operand of an +** outer join. pTerm can be either EP_OuterON or EP_InnerON if pSrc +** is the left operand of a RIGHT join. +** +** See https://sqlite.org/forum/forumpost/206d99a16dd9212f +** for an example of a WHERE clause constraints that may not be used on +** the right table of a RIGHT JOIN because the constraint implies a +** not-NULL condition on the left table of the RIGHT JOIN. +*/ +static int constraintCompatibleWithOuterJoin( + const WhereTerm *pTerm, /* WHERE clause term to check */ + const SrcItem *pSrc /* Table we are trying to access */ +){ + assert( (pSrc->fg.jointype&(JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ); /* By caller */ + testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT ); + testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ ); + testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) ) + testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) ); + if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON) + || pTerm->pExpr->w.iJoin != pSrc->iCursor + ){ + return 0; + } + if( (pSrc->fg.jointype & (JT_LEFT|JT_RIGHT))!=0 + && NEVER(ExprHasProperty(pTerm->pExpr, EP_InnerON)) + ){ + return 0; + } + return 1; +} + +#ifndef SQLITE_OMIT_AUTOMATIC_INDEX +/* +** Return true if column iCol of table pTab seem like it might be a +** good column to use as part of a query-time index. +** +** Current algorithm (subject to improvement!): +** +** 1. If iCol is already the left-most column of some other index, +** then return false. +** +** 2. If iCol is part of an existing index that has an aiRowLogEst of +** more than 20, then return false. +** +** 3. If no disqualifying conditions above are found, return true. +** +** 2025-01-03: I experimented with a new rule that returns false if the +** the datatype of the column is "BOOLEAN". This did not improve +** performance on any queries at hand, but it did burn CPU cycles, so the +** idea was not committed. +*/ +static SQLITE_NOINLINE int columnIsGoodIndexCandidate( + const Table *pTab, + int iCol +){ + const Index *pIdx; + for(pIdx = pTab->pIndex; pIdx!=0; pIdx=pIdx->pNext){ + int j; + for(j=0; jnKeyCol; j++){ + if( pIdx->aiColumn[j]==iCol ){ + if( j==0 ) return 0; + if( pIdx->hasStat1 && pIdx->aiRowLogEst[j+1]>20 ) return 0; + break; + } + } + } + return 1; +} +#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ + + + +#ifndef SQLITE_OMIT_AUTOMATIC_INDEX +/* +** Return TRUE if the WHERE clause term pTerm is of a form where it +** could be used with an index to access pSrc, assuming an appropriate +** index existed. +*/ +static int termCanDriveIndex( + const WhereTerm *pTerm, /* WHERE clause term to check */ + const SrcItem *pSrc, /* Table we are trying to access */ + const Bitmask notReady /* Tables in outer loops of the join */ +){ + char aff; + int leftCol; + + if( pTerm->leftCursor!=pSrc->iCursor ) return 0; + if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0; + assert( (pSrc->fg.jointype & JT_RIGHT)==0 ); + if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 + && !constraintCompatibleWithOuterJoin(pTerm,pSrc) + ){ + return 0; /* See https://sqlite.org/forum/forumpost/51e6959f61 */ + } + if( (pTerm->prereqRight & notReady)!=0 ) return 0; + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); + leftCol = pTerm->u.x.leftColumn; + if( leftCol<0 ) return 0; + aff = pSrc->pSTab->aCol[leftCol].affinity; + if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0; + testcase( pTerm->pExpr->op==TK_IS ); + return columnIsGoodIndexCandidate(pSrc->pSTab, leftCol); +} +#endif + + +#ifndef SQLITE_OMIT_AUTOMATIC_INDEX + +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS +/* +** Argument pIdx represents an automatic index that the current statement +** will create and populate. Add an OP_Explain with text of the form: +** +** CREATE AUTOMATIC INDEX ON
    () [WHERE ] +** +** This is only required if sqlite3_stmt_scanstatus() is enabled, to +** associate an SQLITE_SCANSTAT_NCYCLE and SQLITE_SCANSTAT_NLOOP +** values with. In order to avoid breaking legacy code and test cases, +** the OP_Explain is not added if this is an EXPLAIN QUERY PLAN command. +*/ +static void explainAutomaticIndex( + Parse *pParse, + Index *pIdx, /* Automatic index to explain */ + int bPartial, /* True if pIdx is a partial index */ + int *pAddrExplain /* OUT: Address of OP_Explain */ +){ + if( IS_STMT_SCANSTATUS(pParse->db) && pParse->explain!=2 ){ + Table *pTab = pIdx->pTable; + const char *zSep = ""; + char *zText = 0; + int ii = 0; + sqlite3_str *pStr = sqlite3_str_new(pParse->db); + sqlite3_str_appendf(pStr,"CREATE AUTOMATIC INDEX ON %s(", pTab->zName); + assert( pIdx->nColumn>1 ); + assert( pIdx->aiColumn[pIdx->nColumn-1]==XN_ROWID || !HasRowid(pTab) ); + for(ii=0; ii<(pIdx->nColumn-1); ii++){ + const char *zName = 0; + int iCol = pIdx->aiColumn[ii]; + + zName = pTab->aCol[iCol].zCnName; + sqlite3_str_appendf(pStr, "%s%s", zSep, zName); + zSep = ", "; + } + zText = sqlite3_str_finish(pStr); + if( zText==0 ){ + sqlite3OomFault(pParse->db); + }else{ + *pAddrExplain = sqlite3VdbeExplain( + pParse, 0, "%s)%s", zText, (bPartial ? " WHERE " : "") + ); + sqlite3_free(zText); + } + } +} +#else +# define explainAutomaticIndex(a,b,c,d) +#endif + +/* +** Generate code to construct the Index object for an automatic index +** and to set up the WhereLevel object pLevel so that the code generator +** makes use of the automatic index. +*/ +static SQLITE_NOINLINE void constructAutomaticIndex( + Parse *pParse, /* The parsing context */ + WhereClause *pWC, /* The WHERE clause */ + const Bitmask notReady, /* Mask of cursors that are not available */ + WhereLevel *pLevel /* Write new index here */ +){ + int nKeyCol; /* Number of columns in the constructed index */ + WhereTerm *pTerm; /* A single term of the WHERE clause */ + WhereTerm *pWCEnd; /* End of pWC->a[] */ + Index *pIdx; /* Object describing the transient index */ + Vdbe *v; /* Prepared statement under construction */ + int addrInit; /* Address of the initialization bypass jump */ + Table *pTable; /* The table being indexed */ + int addrTop; /* Top of the index fill loop */ + int regRecord; /* Register holding an index record */ + int n; /* Column counter */ + int i; /* Loop counter */ + int mxBitCol; /* Maximum column in pSrc->colUsed */ + CollSeq *pColl; /* Collating sequence to on a column */ + WhereLoop *pLoop; /* The Loop object */ + char *zNotUsed; /* Extra space on the end of pIdx */ + Bitmask idxCols; /* Bitmap of columns used for indexing */ + Bitmask extraCols; /* Bitmap of additional columns */ + u8 sentWarning = 0; /* True if a warning has been issued */ + u8 useBloomFilter = 0; /* True to also add a Bloom filter */ + Expr *pPartial = 0; /* Partial Index Expression */ + int iContinue = 0; /* Jump here to skip excluded rows */ + SrcList *pTabList; /* The complete FROM clause */ + SrcItem *pSrc; /* The FROM clause term to get the next index */ + int addrCounter = 0; /* Address where integer counter is initialized */ + int regBase; /* Array of registers where record is assembled */ +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + int addrExp = 0; /* Address of OP_Explain */ +#endif + + /* Generate code to skip over the creation and initialization of the + ** transient index on 2nd and subsequent iterations of the loop. */ + v = pParse->pVdbe; + assert( v!=0 ); + addrInit = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + + /* Count the number of columns that will be added to the index + ** and used to match WHERE clause constraints */ + nKeyCol = 0; + pTabList = pWC->pWInfo->pTabList; + pSrc = &pTabList->a[pLevel->iFrom]; + pTable = pSrc->pSTab; + pWCEnd = &pWC->a[pWC->nTerm]; + pLoop = pLevel->pWLoop; + idxCols = 0; + for(pTerm=pWC->a; pTermpExpr; + /* Make the automatic index a partial index if there are terms in the + ** WHERE clause (or the ON clause of a LEFT join) that constrain which + ** rows of the target table (pSrc) that can be used. */ + if( (pTerm->wtFlags & TERM_VIRTUAL)==0 + && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, pLevel->iFrom, 0) + ){ + pPartial = sqlite3ExprAnd(pParse, pPartial, + sqlite3ExprDup(pParse->db, pExpr, 0)); + } + if( termCanDriveIndex(pTerm, pSrc, notReady) ){ + int iCol; + Bitmask cMask; + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); + iCol = pTerm->u.x.leftColumn; + cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol); + testcase( iCol==BMS ); + testcase( iCol==BMS-1 ); + if( !sentWarning ){ + sqlite3_log(SQLITE_WARNING_AUTOINDEX, + "automatic index on %s(%s)", pTable->zName, + pTable->aCol[iCol].zCnName); + sentWarning = 1; + } + if( (idxCols & cMask)==0 ){ + if( whereLoopResize(pParse->db, pLoop, nKeyCol+1) ){ + goto end_auto_index_create; + } + pLoop->aLTerm[nKeyCol++] = pTerm; + idxCols |= cMask; + } + } + } + assert( nKeyCol>0 || pParse->db->mallocFailed ); + pLoop->u.btree.nEq = pLoop->nLTerm = nKeyCol; + pLoop->wsFlags = WHERE_COLUMN_EQ | WHERE_IDX_ONLY | WHERE_INDEXED + | WHERE_AUTO_INDEX; + + /* Count the number of additional columns needed to create a + ** covering index. A "covering index" is an index that contains all + ** columns that are needed by the query. With a covering index, the + ** original table never needs to be accessed. Automatic indices must + ** be a covering index because the index will not be updated if the + ** original table changes and the index and table cannot both be used + ** if they go out of sync. + */ + if( IsView(pTable) ){ + extraCols = ALLBITS & ~idxCols; + }else{ + extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1)); + } + if( !HasRowid(pTable) ){ + /* For WITHOUT ROWID tables, ensure that all PRIMARY KEY columns are + ** either in the idxCols mask or in the extraCols mask */ + for(i=0; inCol; i++){ + if( (pTable->aCol[i].colFlags & COLFLAG_PRIMKEY)==0 ) continue; + if( i>=BMS-1 ){ + extraCols |= MASKBIT(BMS-1); + break; + } + if( idxCols & MASKBIT(i) ) continue; + extraCols |= MASKBIT(i); + } + } + mxBitCol = MIN(BMS-1,pTable->nCol); + testcase( pTable->nCol==BMS-1 ); + testcase( pTable->nCol==BMS-2 ); + for(i=0; icolUsed & MASKBIT(BMS-1) ){ + nKeyCol += pTable->nCol - BMS + 1; + } + + /* Construct the Index object to describe this index */ + assert( nKeyCol <= pTable->nCol + MAX(0, pTable->nCol - BMS + 1) ); + /* ^-- This guarantees that the number of index columns will fit in the u16 */ + pIdx = sqlite3AllocateIndexObject(pParse->db, nKeyCol+HasRowid(pTable), + 0, &zNotUsed); + if( pIdx==0 ) goto end_auto_index_create; + pLoop->u.btree.pIndex = pIdx; + pIdx->zName = "auto-index"; + pIdx->pTable = pTable; + n = 0; + idxCols = 0; + for(pTerm=pWC->a; pTermeOperator & (WO_OR|WO_AND))==0 ); + iCol = pTerm->u.x.leftColumn; + cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol); + testcase( iCol==BMS-1 ); + testcase( iCol==BMS ); + if( (idxCols & cMask)==0 ){ + Expr *pX = pTerm->pExpr; + idxCols |= cMask; + pIdx->aiColumn[n] = pTerm->u.x.leftColumn; + pColl = sqlite3ExprCompareCollSeq(pParse, pX); + assert( pColl!=0 || pParse->nErr>0 ); /* TH3 collate01.800 */ + pIdx->azColl[n] = pColl ? pColl->zName : sqlite3StrBINARY; + n++; + if( ALWAYS(pX->pLeft!=0) + && sqlite3ExprAffinity(pX->pLeft)!=SQLITE_AFF_TEXT + ){ + /* TUNING: only use a Bloom filter on an automatic index + ** if one or more key columns has the ability to hold numeric + ** values, since strings all have the same hash in the Bloom + ** filter implementation and hence a Bloom filter on a text column + ** is not usually helpful. */ + useBloomFilter = 1; + } + } + } + } + assert( (u32)n==pLoop->u.btree.nEq ); + + /* Add additional columns needed to make the automatic index into + ** a covering index */ + for(i=0; iaiColumn[n] = i; + pIdx->azColl[n] = sqlite3StrBINARY; + n++; + } + } + if( pSrc->colUsed & MASKBIT(BMS-1) ){ + for(i=BMS-1; inCol; i++){ + pIdx->aiColumn[n] = i; + pIdx->azColl[n] = sqlite3StrBINARY; + n++; + } + } + assert( n==nKeyCol ); + if( HasRowid(pTable) ){ + pIdx->aiColumn[n] = XN_ROWID; + pIdx->azColl[n] = sqlite3StrBINARY; + } + + /* Create the automatic index */ + explainAutomaticIndex(pParse, pIdx, pPartial!=0, &addrExp); + assert( pLevel->iIdxCur>=0 ); + pLevel->iIdxCur = pParse->nTab++; + sqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1); + sqlite3VdbeSetP4KeyInfo(pParse, pIdx); + VdbeComment((v, "for %s", pTable->zName)); + if( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) && useBloomFilter ){ + sqlite3WhereExplainBloomFilter(pParse, pWC->pWInfo, pLevel); + pLevel->regFilter = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Blob, 10000, pLevel->regFilter); + } + + /* Fill the automatic index with content */ + assert( pSrc == &pWC->pWInfo->pTabList->a[pLevel->iFrom] ); + if( pSrc->fg.viaCoroutine ){ + int regYield; + Subquery *pSubq; + assert( pSrc->fg.isSubquery ); + pSubq = pSrc->u4.pSubq; + assert( pSubq!=0 ); + regYield = pSubq->regReturn; + addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0); + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSubq->addrFillSub); + addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield); + VdbeCoverage(v); + VdbeComment((v, "next row of %s", pSrc->pSTab->zName)); + }else{ + assert( pLevel->addrHalt ); + addrTop = sqlite3VdbeAddOp2(v, OP_Rewind,pLevel->iTabCur,pLevel->addrHalt); + VdbeCoverage(v); + } + if( pPartial ){ + iContinue = sqlite3VdbeMakeLabel(pParse); + sqlite3ExprIfFalse(pParse, pPartial, iContinue, SQLITE_JUMPIFNULL); + pLoop->wsFlags |= WHERE_PARTIALIDX; + } + regRecord = sqlite3GetTempReg(pParse); + regBase = sqlite3GenerateIndexKey( + pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0 + ); + if( pLevel->regFilter ){ + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, + regBase, pLoop->u.btree.nEq); + } + sqlite3VdbeScanStatusCounters(v, addrExp, addrExp, sqlite3VdbeCurrentAddr(v)); + sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord); + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue); + if( pSrc->fg.viaCoroutine ){ + assert( pSrc->fg.isSubquery && pSrc->u4.pSubq!=0 ); + sqlite3VdbeChangeP2(v, addrCounter, regBase+n); + testcase( pParse->db->mallocFailed ); + assert( pLevel->iIdxCur>0 ); + translateColumnToCopy(pParse, addrTop, pLevel->iTabCur, + pSrc->u4.pSubq->regResult, pLevel->iIdxCur); + sqlite3VdbeGoto(v, addrTop); + pSrc->fg.viaCoroutine = 0; + sqlite3VdbeJumpHere(v, addrTop); + }else{ + sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v); + sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX); + if( (pSrc->fg.jointype & JT_LEFT)!=0 ){ + sqlite3VdbeJumpHere(v, addrTop); + } + } + sqlite3ReleaseTempReg(pParse, regRecord); + + /* Jump here when skipping the initialization */ + sqlite3VdbeJumpHere(v, addrInit); + sqlite3VdbeScanStatusRange(v, addrExp, addrExp, -1); + +end_auto_index_create: + sqlite3ExprDelete(pParse->db, pPartial); +} +#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ + +/* +** Generate bytecode that will initialize a Bloom filter that is appropriate +** for pLevel. +** +** If there are inner loops within pLevel that have the WHERE_BLOOMFILTER +** flag set, initialize a Bloomfilter for them as well. Except don't do +** this recursive initialization if the SQLITE_BloomPulldown optimization has +** been turned off. +** +** When the Bloom filter is initialized, the WHERE_BLOOMFILTER flag is cleared +** from the loop, but the regFilter value is set to a register that implements +** the Bloom filter. When regFilter is positive, the +** sqlite3WhereCodeOneLoopStart() will generate code to test the Bloom filter +** and skip the subsequence B-Tree seek if the Bloom filter indicates that +** no matching rows exist. +** +** This routine may only be called if it has previously been determined that +** the loop would benefit from a Bloom filter, and the WHERE_BLOOMFILTER bit +** is set. +*/ +static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( + WhereInfo *pWInfo, /* The WHERE clause */ + int iLevel, /* Index in pWInfo->a[] that is pLevel */ + WhereLevel *pLevel, /* Make a Bloom filter for this FROM term */ + Bitmask notReady /* Loops that are not ready */ +){ + int addrOnce; /* Address of opening OP_Once */ + int addrTop; /* Address of OP_Rewind */ + int addrCont; /* Jump here to skip a row */ + const WhereTerm *pTerm; /* For looping over WHERE clause terms */ + const WhereTerm *pWCEnd; /* Last WHERE clause term */ + Parse *pParse = pWInfo->pParse; /* Parsing context */ + Vdbe *v = pParse->pVdbe; /* VDBE under construction */ + WhereLoop *pLoop = pLevel->pWLoop; /* The loop being coded */ + int iCur; /* Cursor for table getting the filter */ + IndexedExpr *saved_pIdxEpr; /* saved copy of Parse.pIdxEpr */ + IndexedExpr *saved_pIdxPartExpr; /* saved copy of Parse.pIdxPartExpr */ + + saved_pIdxEpr = pParse->pIdxEpr; + saved_pIdxPartExpr = pParse->pIdxPartExpr; + pParse->pIdxEpr = 0; + pParse->pIdxPartExpr = 0; + + assert( pLoop!=0 ); + assert( v!=0 ); + assert( pLoop->wsFlags & WHERE_BLOOMFILTER ); + assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 ); + + addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + do{ + const SrcList *pTabList; + const SrcItem *pItem; + const Table *pTab; + u64 sz; + int iSrc; + sqlite3WhereExplainBloomFilter(pParse, pWInfo, pLevel); + addrCont = sqlite3VdbeMakeLabel(pParse); + iCur = pLevel->iTabCur; + pLevel->regFilter = ++pParse->nMem; + + /* The Bloom filter is a Blob held in a register. Initialize it + ** to zero-filled blob of at least 80K bits, but maybe more if the + ** estimated size of the table is larger. We could actually + ** measure the size of the table at run-time using OP_Count with + ** P3==1 and use that value to initialize the blob. But that makes + ** testing complicated. By basing the blob size on the value in the + ** sqlite_stat1 table, testing is much easier. + */ + pTabList = pWInfo->pTabList; + iSrc = pLevel->iFrom; + pItem = &pTabList->a[iSrc]; + assert( pItem!=0 ); + pTab = pItem->pSTab; + assert( pTab!=0 ); + sz = sqlite3LogEstToInt(pTab->nRowLogEst); + if( sz<10000 ){ + sz = 10000; + }else if( sz>10000000 ){ + sz = 10000000; + } + sqlite3VdbeAddOp2(v, OP_Blob, (int)sz, pLevel->regFilter); + + addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v); + pWCEnd = &pWInfo->sWC.a[pWInfo->sWC.nTerm]; + for(pTerm=pWInfo->sWC.a; pTermpExpr; + if( (pTerm->wtFlags & TERM_VIRTUAL)==0 + && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, iSrc, 0) + ){ + sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); + } + } + if( pLoop->wsFlags & WHERE_IPK ){ + int r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_Rowid, iCur, r1); + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, r1, 1); + sqlite3ReleaseTempReg(pParse, r1); + }else{ + Index *pIdx = pLoop->u.btree.pIndex; + int n = pLoop->u.btree.nEq; + int r1 = sqlite3GetTempRange(pParse, n); + int jj; + for(jj=0; jjpTable==pItem->pSTab ); + sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iCur, jj, r1+jj); + } + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, r1, n); + sqlite3ReleaseTempRange(pParse, r1, n); + } + sqlite3VdbeResolveLabel(v, addrCont); + sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); + VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addrTop); + pLoop->wsFlags &= ~WHERE_BLOOMFILTER; + if( OptimizationDisabled(pParse->db, SQLITE_BloomPulldown) ) break; + while( ++iLevel < pWInfo->nLevel ){ + const SrcItem *pTabItem; + pLevel = &pWInfo->a[iLevel]; + pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; + if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ) ) continue; + pLoop = pLevel->pWLoop; + if( NEVER(pLoop==0) ) continue; + if( pLoop->prereq & notReady ) continue; + if( (pLoop->wsFlags & (WHERE_BLOOMFILTER|WHERE_COLUMN_IN)) + ==WHERE_BLOOMFILTER + ){ + /* This is a candidate for bloom-filter pull-down (early evaluation). + ** The test that WHERE_COLUMN_IN is omitted is important, as we are + ** not able to do early evaluation of bloom filters that make use of + ** the IN operator */ + break; + } + } + }while( iLevel < pWInfo->nLevel ); + sqlite3VdbeJumpHere(v, addrOnce); + pParse->pIdxEpr = saved_pIdxEpr; + pParse->pIdxPartExpr = saved_pIdxPartExpr; +} + + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Return term iTerm of the WhereClause passed as the first argument. Terms +** are numbered from 0 upwards, starting with the terms in pWC->a[], then +** those in pWC->pOuter->a[] (if any), and so on. +*/ +static WhereTerm *termFromWhereClause(WhereClause *pWC, int iTerm){ + WhereClause *p; + for(p=pWC; p; p=p->pOuter){ + if( iTermnTerm ) return &p->a[iTerm]; + iTerm -= p->nTerm; + } + return 0; +} + +/* +** Allocate and populate an sqlite3_index_info structure. It is the +** responsibility of the caller to eventually release the structure +** by passing the pointer returned by this function to freeIndexInfo(). +*/ +static sqlite3_index_info *allocateIndexInfo( + WhereInfo *pWInfo, /* The WHERE clause */ + WhereClause *pWC, /* The WHERE clause being analyzed */ + Bitmask mUnusable, /* Ignore terms with these prereqs */ + SrcItem *pSrc, /* The FROM clause term that is the vtab */ + u16 *pmNoOmit /* Mask of terms not to omit */ +){ + int i, j; + int nTerm; + Parse *pParse = pWInfo->pParse; + struct sqlite3_index_constraint *pIdxCons; + struct sqlite3_index_orderby *pIdxOrderBy; + struct sqlite3_index_constraint_usage *pUsage; + struct HiddenIndexInfo *pHidden; + WhereTerm *pTerm; + int nOrderBy; + sqlite3_index_info *pIdxInfo; + u16 mNoOmit = 0; + const Table *pTab; + int eDistinct = 0; + ExprList *pOrderBy = pWInfo->pOrderBy; + WhereClause *p; + + assert( pSrc!=0 ); + pTab = pSrc->pSTab; + assert( pTab!=0 ); + assert( IsVirtual(pTab) ); + + /* Find all WHERE clause constraints referring to this virtual table. + ** Mark each term with the TERM_OK flag. Set nTerm to the number of + ** terms found. + */ + for(p=pWC, nTerm=0; p; p=p->pOuter){ + for(i=0, pTerm=p->a; inTerm; i++, pTerm++){ + pTerm->wtFlags &= ~TERM_OK; + if( pTerm->leftCursor != pSrc->iCursor ) continue; + if( pTerm->prereqRight & mUnusable ) continue; + assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) ); + testcase( pTerm->eOperator & WO_IN ); + testcase( pTerm->eOperator & WO_ISNULL ); + testcase( pTerm->eOperator & WO_IS ); + testcase( pTerm->eOperator & WO_ALL ); + if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue; + if( pTerm->wtFlags & TERM_VNULL ) continue; + + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); + assert( pTerm->u.x.leftColumn>=XN_ROWID ); + assert( pTerm->u.x.leftColumnnCol ); + if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 + && !constraintCompatibleWithOuterJoin(pTerm,pSrc) + ){ + continue; + } + nTerm++; + pTerm->wtFlags |= TERM_OK; + } + } + + /* If the ORDER BY clause contains only columns in the current + ** virtual table then allocate space for the aOrderBy part of + ** the sqlite3_index_info structure. + */ + nOrderBy = 0; + if( pOrderBy ){ + int n = pOrderBy->nExpr; + for(i=0; ia[i].pExpr; + Expr *pE2; + + /* Skip over constant terms in the ORDER BY clause */ + if( sqlite3ExprIsConstant(0, pExpr) ){ + continue; + } + + /* Virtual tables are unable to deal with NULLS FIRST */ + if( pOrderBy->a[i].fg.sortFlags & KEYINFO_ORDER_BIGNULL ) break; + + /* First case - a direct column references without a COLLATE operator */ + if( pExpr->op==TK_COLUMN && pExpr->iTable==pSrc->iCursor ){ + assert( pExpr->iColumn>=XN_ROWID && pExpr->iColumnnCol ); + continue; + } + + /* 2nd case - a column reference with a COLLATE operator. Only match + ** of the COLLATE operator matches the collation of the column. */ + if( pExpr->op==TK_COLLATE + && (pE2 = pExpr->pLeft)->op==TK_COLUMN + && pE2->iTable==pSrc->iCursor + ){ + const char *zColl; /* The collating sequence name */ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + assert( pExpr->u.zToken!=0 ); + assert( pE2->iColumn>=XN_ROWID && pE2->iColumnnCol ); + pExpr->iColumn = pE2->iColumn; + if( pE2->iColumn<0 ) continue; /* Collseq does not matter for rowid */ + zColl = sqlite3ColumnColl(&pTab->aCol[pE2->iColumn]); + if( zColl==0 ) zColl = sqlite3StrBINARY; + if( sqlite3_stricmp(pExpr->u.zToken, zColl)==0 ) continue; + } + + /* No matches cause a break out of the loop */ + break; + } + if( i==n ){ + int bSortByGroup = (pWInfo->wctrlFlags & WHERE_SORTBYGROUP)!=0; + nOrderBy = n; + if( (pWInfo->wctrlFlags & WHERE_DISTINCTBY) && !pSrc->fg.rowidUsed ){ + eDistinct = 2 + bSortByGroup; + }else if( pWInfo->wctrlFlags & WHERE_GROUPBY ){ + eDistinct = 1 - bSortByGroup; + }else if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){ + eDistinct = 3; + } + } + } + + /* Allocate the sqlite3_index_info structure + */ + pIdxInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo) + + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm + + sizeof(*pIdxOrderBy)*nOrderBy + + SZ_HIDDENINDEXINFO(nTerm) ); + if( pIdxInfo==0 ){ + sqlite3ErrorMsg(pParse, "out of memory"); + return 0; + } + pHidden = (struct HiddenIndexInfo*)&pIdxInfo[1]; + pIdxCons = (struct sqlite3_index_constraint*)&pHidden->aRhs[nTerm]; + pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm]; + pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy]; + pIdxInfo->aConstraint = pIdxCons; + pIdxInfo->aOrderBy = pIdxOrderBy; + pIdxInfo->aConstraintUsage = pUsage; + pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed; + if( HasRowid(pTab)==0 ){ + /* Ensure that all bits associated with PK columns are set. This is to + ** ensure they are available for cases like RIGHT joins or OR loops. */ + Index *pPk = sqlite3PrimaryKeyIndex((Table*)pTab); + assert( pPk!=0 ); + for(i=0; inKeyCol; i++){ + int iCol = pPk->aiColumn[i]; + assert( iCol>=0 ); + if( iCol>=BMS-1 ) iCol = BMS-1; + pIdxInfo->colUsed |= MASKBIT(iCol); + } + } + pHidden->pWC = pWC; + pHidden->pParse = pParse; + pHidden->eDistinct = eDistinct; + pHidden->mIn = 0; + for(p=pWC, i=j=0; p; p=p->pOuter){ + int nLast = i+p->nTerm;; + for(pTerm=p->a; iwtFlags & TERM_OK)==0 ) continue; + pIdxCons[j].iColumn = pTerm->u.x.leftColumn; + pIdxCons[j].iTermOffset = i; + op = pTerm->eOperator & WO_ALL; + if( op==WO_IN ){ + if( (pTerm->wtFlags & TERM_SLICE)==0 ){ + pHidden->mIn |= SMASKBIT32(j); + } + op = WO_EQ; + } + if( op==WO_AUX ){ + pIdxCons[j].op = pTerm->eMatchOp; + }else if( op & (WO_ISNULL|WO_IS) ){ + if( op==WO_ISNULL ){ + pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_ISNULL; + }else{ + pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_IS; + } + }else{ + pIdxCons[j].op = (u8)op; + /* The direct assignment in the previous line is possible only because + ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The + ** following asserts verify this fact. */ + assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ ); + assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT ); + assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE ); + assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT ); + assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE ); + assert( pTerm->eOperator&(WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_AUX) ); + + if( op & (WO_LT|WO_LE|WO_GT|WO_GE) + && sqlite3ExprIsVector(pTerm->pExpr->pRight) + ){ + testcase( j!=i ); + if( j<16 ) mNoOmit |= (1 << j); + if( op==WO_LT ) pIdxCons[j].op = WO_LE; + if( op==WO_GT ) pIdxCons[j].op = WO_GE; + } + } + + j++; + } + } + assert( j==nTerm ); + pIdxInfo->nConstraint = j; + for(i=j=0; ia[i].pExpr; + if( sqlite3ExprIsConstant(0, pExpr) ) continue; + assert( pExpr->op==TK_COLUMN + || (pExpr->op==TK_COLLATE && pExpr->pLeft->op==TK_COLUMN + && pExpr->iColumn==pExpr->pLeft->iColumn) ); + pIdxOrderBy[j].iColumn = pExpr->iColumn; + pIdxOrderBy[j].desc = pOrderBy->a[i].fg.sortFlags & KEYINFO_ORDER_DESC; + j++; + } + pIdxInfo->nOrderBy = j; + + *pmNoOmit = mNoOmit; + return pIdxInfo; +} + +/* +** Free and zero the sqlite3_index_info.idxStr value if needed. +*/ +static void freeIdxStr(sqlite3_index_info *pIdxInfo){ + if( pIdxInfo->needToFreeIdxStr ){ + sqlite3_free(pIdxInfo->idxStr); + pIdxInfo->idxStr = 0; + pIdxInfo->needToFreeIdxStr = 0; + } +} + +/* +** Free an sqlite3_index_info structure allocated by allocateIndexInfo() +** and possibly modified by xBestIndex methods. +*/ +static void freeIndexInfo(sqlite3 *db, sqlite3_index_info *pIdxInfo){ + HiddenIndexInfo *pHidden; + int i; + assert( pIdxInfo!=0 ); + pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; + assert( pHidden->pParse!=0 ); + assert( pHidden->pParse->db==db ); + for(i=0; inConstraint; i++){ + sqlite3ValueFree(pHidden->aRhs[i]); /* IMP: R-14553-25174 */ + pHidden->aRhs[i] = 0; + } + freeIdxStr(pIdxInfo); + sqlite3DbFree(db, pIdxInfo); +} + +/* +** The table object reference passed as the second argument to this function +** must represent a virtual table. This function invokes the xBestIndex() +** method of the virtual table with the sqlite3_index_info object that +** comes in as the 3rd argument to this function. +** +** If an error occurs, pParse is populated with an error message and an +** appropriate error code is returned. A return of SQLITE_CONSTRAINT from +** xBestIndex is not considered an error. SQLITE_CONSTRAINT indicates that +** the current configuration of "unusable" flags in sqlite3_index_info can +** not result in a valid plan. +** +** Whether or not an error is returned, it is the responsibility of the +** caller to eventually free p->idxStr if p->needToFreeIdxStr indicates +** that this is required. +*/ +static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ + int rc; + sqlite3_vtab *pVtab; + + assert( IsVirtual(pTab) ); + pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab; + whereTraceIndexInfoInputs(p, pTab); + pParse->db->nSchemaLock++; + rc = pVtab->pModule->xBestIndex(pVtab, p); + pParse->db->nSchemaLock--; + whereTraceIndexInfoOutputs(p, pTab); + + if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){ + if( rc==SQLITE_NOMEM ){ + sqlite3OomFault(pParse->db); + }else if( !pVtab->zErrMsg ){ + sqlite3ErrorMsg(pParse, "%s", sqlite3ErrStr(rc)); + }else{ + sqlite3ErrorMsg(pParse, "%s", pVtab->zErrMsg); + } + } + if( pTab->u.vtab.p->bAllSchemas ){ + sqlite3VtabUsesAllSchemas(pParse); + } + sqlite3_free(pVtab->zErrMsg); + pVtab->zErrMsg = 0; + return rc; +} +#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */ + +#ifdef SQLITE_ENABLE_STAT4 +/* +** Estimate the location of a particular key among all keys in an +** index. Store the results in aStat as follows: +** +** aStat[0] Est. number of rows less than pRec +** aStat[1] Est. number of rows equal to pRec +** +** Return the index of the sample that is the smallest sample that +** is greater than or equal to pRec. Note that this index is not an index +** into the aSample[] array - it is an index into a virtual set of samples +** based on the contents of aSample[] and the number of fields in record +** pRec. +*/ +static int whereKeyStats( + Parse *pParse, /* Database connection */ + Index *pIdx, /* Index to consider domain of */ + UnpackedRecord *pRec, /* Vector of values to consider */ + int roundUp, /* Round up if true. Round down if false */ + tRowcnt *aStat /* OUT: stats written here */ +){ + IndexSample *aSample = pIdx->aSample; + int iCol; /* Index of required stats in anEq[] etc. */ + int i; /* Index of first sample >= pRec */ + int iSample; /* Smallest sample larger than or equal to pRec */ + int iMin = 0; /* Smallest sample not yet tested */ + int iTest; /* Next sample to test */ + int res; /* Result of comparison operation */ + int nField; /* Number of fields in pRec */ + tRowcnt iLower = 0; /* anLt[] + anEq[] of largest sample pRec is > */ + +#ifndef SQLITE_DEBUG + UNUSED_PARAMETER( pParse ); +#endif + assert( pRec!=0 ); + assert( pIdx->nSample>0 ); + assert( pRec->nField>0 ); + + + /* Do a binary search to find the first sample greater than or equal + ** to pRec. If pRec contains a single field, the set of samples to search + ** is simply the aSample[] array. If the samples in aSample[] contain more + ** than one fields, all fields following the first are ignored. + ** + ** If pRec contains N fields, where N is more than one, then as well as the + ** samples in aSample[] (truncated to N fields), the search also has to + ** consider prefixes of those samples. For example, if the set of samples + ** in aSample is: + ** + ** aSample[0] = (a, 5) + ** aSample[1] = (a, 10) + ** aSample[2] = (b, 5) + ** aSample[3] = (c, 100) + ** aSample[4] = (c, 105) + ** + ** Then the search space should ideally be the samples above and the + ** unique prefixes [a], [b] and [c]. But since that is hard to organize, + ** the code actually searches this set: + ** + ** 0: (a) + ** 1: (a, 5) + ** 2: (a, 10) + ** 3: (a, 10) + ** 4: (b) + ** 5: (b, 5) + ** 6: (c) + ** 7: (c, 100) + ** 8: (c, 105) + ** 9: (c, 105) + ** + ** For each sample in the aSample[] array, N samples are present in the + ** effective sample array. In the above, samples 0 and 1 are based on + ** sample aSample[0]. Samples 2 and 3 on aSample[1] etc. + ** + ** Often, sample i of each block of N effective samples has (i+1) fields. + ** Except, each sample may be extended to ensure that it is greater than or + ** equal to the previous sample in the array. For example, in the above, + ** sample 2 is the first sample of a block of N samples, so at first it + ** appears that it should be 1 field in size. However, that would make it + ** smaller than sample 1, so the binary search would not work. As a result, + ** it is extended to two fields. The duplicates that this creates do not + ** cause any problems. + */ + if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){ + nField = pIdx->nKeyCol; + }else{ + nField = pIdx->nColumn; + } + nField = MIN(pRec->nField, nField); + iCol = 0; + iSample = pIdx->nSample * nField; + do{ + int iSamp; /* Index in aSample[] of test sample */ + int n; /* Number of fields in test sample */ + + iTest = (iMin+iSample)/2; + iSamp = iTest / nField; + if( iSamp>0 ){ + /* The proposed effective sample is a prefix of sample aSample[iSamp]. + ** Specifically, the shortest prefix of at least (1 + iTest%nField) + ** fields that is greater than the previous effective sample. */ + for(n=(iTest % nField) + 1; nnField = n; + res = sqlite3VdbeRecordCompare(aSample[iSamp].n, aSample[iSamp].p, pRec); + if( res<0 ){ + iLower = aSample[iSamp].anLt[n-1] + aSample[iSamp].anEq[n-1]; + iMin = iTest+1; + }else if( res==0 && ndb->mallocFailed==0 ){ + if( res==0 ){ + /* If (res==0) is true, then pRec must be equal to sample i. */ + assert( inSample ); + assert( iCol==nField-1 ); + pRec->nField = nField; + assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec) + || pParse->db->mallocFailed + ); + }else{ + /* Unless i==pIdx->nSample, indicating that pRec is larger than + ** all samples in the aSample[] array, pRec must be smaller than the + ** (iCol+1) field prefix of sample i. */ + assert( i<=pIdx->nSample && i>=0 ); + pRec->nField = iCol+1; + assert( i==pIdx->nSample + || sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)>0 + || pParse->db->mallocFailed ); + + /* if i==0 and iCol==0, then record pRec is smaller than all samples + ** in the aSample[] array. Otherwise, if (iCol>0) then pRec must + ** be greater than or equal to the (iCol) field prefix of sample i. + ** If (i>0), then pRec must also be greater than sample (i-1). */ + if( iCol>0 ){ + pRec->nField = iCol; + assert( sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)<=0 + || pParse->db->mallocFailed || CORRUPT_DB ); + } + if( i>0 ){ + pRec->nField = nField; + assert( sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0 + || pParse->db->mallocFailed || CORRUPT_DB ); + } + } + } +#endif /* ifdef SQLITE_DEBUG */ + + if( res==0 ){ + /* Record pRec is equal to sample i */ + assert( iCol==nField-1 ); + aStat[0] = aSample[i].anLt[iCol]; + aStat[1] = aSample[i].anEq[iCol]; + }else{ + /* At this point, the (iCol+1) field prefix of aSample[i] is the first + ** sample that is greater than pRec. Or, if i==pIdx->nSample then pRec + ** is larger than all samples in the array. */ + tRowcnt iUpper, iGap; + if( i>=pIdx->nSample ){ + iUpper = pIdx->nRowEst0; + }else{ + iUpper = aSample[i].anLt[iCol]; + } + + if( iLower>=iUpper ){ + iGap = 0; + }else{ + iGap = iUpper - iLower; + } + if( roundUp ){ + iGap = (iGap*2)/3; + }else{ + iGap = iGap/3; + } + aStat[0] = iLower + iGap; + aStat[1] = pIdx->aAvgEq[nField-1]; + } + + /* Restore the pRec->nField value before returning. */ + pRec->nField = nField; + return i; +} +#endif /* SQLITE_ENABLE_STAT4 */ + +/* +** If it is not NULL, pTerm is a term that provides an upper or lower +** bound on a range scan. Without considering pTerm, it is estimated +** that the scan will visit nNew rows. This function returns the number +** estimated to be visited after taking pTerm into account. +** +** If the user explicitly specified a likelihood() value for this term, +** then the return value is the likelihood multiplied by the number of +** input rows. Otherwise, this function assumes that an "IS NOT NULL" term +** has a likelihood of 0.50, and any other term a likelihood of 0.25. +*/ +static LogEst whereRangeAdjust(WhereTerm *pTerm, LogEst nNew){ + LogEst nRet = nNew; + if( pTerm ){ + if( pTerm->truthProb<=0 ){ + nRet += pTerm->truthProb; + }else if( (pTerm->wtFlags & TERM_VNULL)==0 ){ + nRet -= 20; assert( 20==sqlite3LogEst(4) ); + } + } + return nRet; +} + + +#ifdef SQLITE_ENABLE_STAT4 +/* +** Return the affinity for a single column of an index. +*/ +SQLITE_PRIVATE char sqlite3IndexColumnAffinity(sqlite3 *db, Index *pIdx, int iCol){ + assert( iCol>=0 && iColnColumn ); + if( !pIdx->zColAff ){ + if( sqlite3IndexAffinityStr(db, pIdx)==0 ) return SQLITE_AFF_BLOB; + } + assert( pIdx->zColAff[iCol]!=0 ); + return pIdx->zColAff[iCol]; +} +#endif + + +#ifdef SQLITE_ENABLE_STAT4 +/* +** This function is called to estimate the number of rows visited by a +** range-scan on a skip-scan index. For example: +** +** CREATE INDEX i1 ON t1(a, b, c); +** SELECT * FROM t1 WHERE a=? AND c BETWEEN ? AND ?; +** +** Value pLoop->nOut is currently set to the estimated number of rows +** visited for scanning (a=? AND b=?). This function reduces that estimate +** by some factor to account for the (c BETWEEN ? AND ?) expression based +** on the stat4 data for the index. this scan will be performed multiple +** times (once for each (a,b) combination that matches a=?) is dealt with +** by the caller. +** +** It does this by scanning through all stat4 samples, comparing values +** extracted from pLower and pUpper with the corresponding column in each +** sample. If L and U are the number of samples found to be less than or +** equal to the values extracted from pLower and pUpper respectively, and +** N is the total number of samples, the pLoop->nOut value is adjusted +** as follows: +** +** nOut = nOut * ( min(U - L, 1) / N ) +** +** If pLower is NULL, or a value cannot be extracted from the term, L is +** set to zero. If pUpper is NULL, or a value cannot be extracted from it, +** U is set to N. +** +** Normally, this function sets *pbDone to 1 before returning. However, +** if no value can be extracted from either pLower or pUpper (and so the +** estimate of the number of rows delivered remains unchanged), *pbDone +** is left as is. +** +** If an error occurs, an SQLite error code is returned. Otherwise, +** SQLITE_OK. +*/ +static int whereRangeSkipScanEst( + Parse *pParse, /* Parsing & code generating context */ + WhereTerm *pLower, /* Lower bound on the range. ex: "x>123" Might be NULL */ + WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */ + WhereLoop *pLoop, /* Update the .nOut value of this loop */ + int *pbDone /* Set to true if at least one expr. value extracted */ +){ + Index *p = pLoop->u.btree.pIndex; + int nEq = pLoop->u.btree.nEq; + sqlite3 *db = pParse->db; + int nLower = -1; + int nUpper = p->nSample+1; + int rc = SQLITE_OK; + u8 aff = sqlite3IndexColumnAffinity(db, p, nEq); + CollSeq *pColl; + + sqlite3_value *p1 = 0; /* Value extracted from pLower */ + sqlite3_value *p2 = 0; /* Value extracted from pUpper */ + sqlite3_value *pVal = 0; /* Value extracted from record */ + + pColl = sqlite3LocateCollSeq(pParse, p->azColl[nEq]); + if( pLower ){ + rc = sqlite3Stat4ValueFromExpr(pParse, pLower->pExpr->pRight, aff, &p1); + nLower = 0; + } + if( pUpper && rc==SQLITE_OK ){ + rc = sqlite3Stat4ValueFromExpr(pParse, pUpper->pExpr->pRight, aff, &p2); + nUpper = p2 ? 0 : p->nSample; + } + + if( p1 || p2 ){ + int i; + int nDiff; + for(i=0; rc==SQLITE_OK && inSample; i++){ + rc = sqlite3Stat4Column(db, p->aSample[i].p, p->aSample[i].n, nEq, &pVal); + if( rc==SQLITE_OK && p1 ){ + int res = sqlite3MemCompare(p1, pVal, pColl); + if( res>=0 ) nLower++; + } + if( rc==SQLITE_OK && p2 ){ + int res = sqlite3MemCompare(p2, pVal, pColl); + if( res>=0 ) nUpper++; + } + } + nDiff = (nUpper - nLower); + if( nDiff<=0 ) nDiff = 1; + + /* If there is both an upper and lower bound specified, and the + ** comparisons indicate that they are close together, use the fallback + ** method (assume that the scan visits 1/64 of the rows) for estimating + ** the number of rows visited. Otherwise, estimate the number of rows + ** using the method described in the header comment for this function. */ + if( nDiff!=1 || pUpper==0 || pLower==0 ){ + int nAdjust = (sqlite3LogEst(p->nSample) - sqlite3LogEst(nDiff)); + pLoop->nOut -= nAdjust; + *pbDone = 1; + WHERETRACE(0x20, ("range skip-scan regions: %u..%u adjust=%d est=%d\n", + nLower, nUpper, nAdjust*-1, pLoop->nOut)); + } + + }else{ + assert( *pbDone==0 ); + } + + sqlite3ValueFree(p1); + sqlite3ValueFree(p2); + sqlite3ValueFree(pVal); + + return rc; +} +#endif /* SQLITE_ENABLE_STAT4 */ + +/* +** This function is used to estimate the number of rows that will be visited +** by scanning an index for a range of values. The range may have an upper +** bound, a lower bound, or both. The WHERE clause terms that set the upper +** and lower bounds are represented by pLower and pUpper respectively. For +** example, assuming that index p is on t1(a): +** +** ... FROM t1 WHERE a > ? AND a < ? ... +** |_____| |_____| +** | | +** pLower pUpper +** +** If either of the upper or lower bound is not present, then NULL is passed in +** place of the corresponding WhereTerm. +** +** The value in (pBuilder->pNew->u.btree.nEq) is the number of the index +** column subject to the range constraint. Or, equivalently, the number of +** equality constraints optimized by the proposed index scan. For example, +** assuming index p is on t1(a, b), and the SQL query is: +** +** ... FROM t1 WHERE a = ? AND b > ? AND b < ? ... +** +** then nEq is set to 1 (as the range restricted column, b, is the second +** left-most column of the index). Or, if the query is: +** +** ... FROM t1 WHERE a > ? AND a < ? ... +** +** then nEq is set to 0. +** +** When this function is called, *pnOut is set to the sqlite3LogEst() of the +** number of rows that the index scan is expected to visit without +** considering the range constraints. If nEq is 0, then *pnOut is the number of +** rows in the index. Assuming no error occurs, *pnOut is adjusted (reduced) +** to account for the range constraints pLower and pUpper. +** +** In the absence of sqlite_stat4 ANALYZE data, or if such data cannot be +** used, a single range inequality reduces the search space by a factor of 4. +** and a pair of constraints (x>? AND x123" Might be NULL */ + WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */ + WhereLoop *pLoop /* Modify the .nOut and maybe .rRun fields */ +){ + int rc = SQLITE_OK; + int nOut = pLoop->nOut; + LogEst nNew; + +#ifdef SQLITE_ENABLE_STAT4 + Index *p = pLoop->u.btree.pIndex; + int nEq = pLoop->u.btree.nEq; + + if( p->nSample>0 && ALWAYS(nEqnSampleCol) + && OptimizationEnabled(pParse->db, SQLITE_Stat4) + ){ + if( nEq==pBuilder->nRecValid ){ + UnpackedRecord *pRec = pBuilder->pRec; + tRowcnt a[2]; + int nBtm = pLoop->u.btree.nBtm; + int nTop = pLoop->u.btree.nTop; + + /* Variable iLower will be set to the estimate of the number of rows in + ** the index that are less than the lower bound of the range query. The + ** lower bound being the concatenation of $P and $L, where $P is the + ** key-prefix formed by the nEq values matched against the nEq left-most + ** columns of the index, and $L is the value in pLower. + ** + ** Or, if pLower is NULL or $L cannot be extracted from it (because it + ** is not a simple variable or literal value), the lower bound of the + ** range is $P. Due to a quirk in the way whereKeyStats() works, even + ** if $L is available, whereKeyStats() is called for both ($P) and + ** ($P:$L) and the larger of the two returned values is used. + ** + ** Similarly, iUpper is to be set to the estimate of the number of rows + ** less than the upper bound of the range query. Where the upper bound + ** is either ($P) or ($P:$U). Again, even if $U is available, both values + ** of iUpper are requested of whereKeyStats() and the smaller used. + ** + ** The number of rows between the two bounds is then just iUpper-iLower. + */ + tRowcnt iLower; /* Rows less than the lower bound */ + tRowcnt iUpper; /* Rows less than the upper bound */ + int iLwrIdx = -2; /* aSample[] for the lower bound */ + int iUprIdx = -1; /* aSample[] for the upper bound */ + + if( pRec ){ + testcase( pRec->nField!=pBuilder->nRecValid ); + pRec->nField = pBuilder->nRecValid; + } + /* Determine iLower and iUpper using ($P) only. */ + if( nEq==0 ){ + iLower = 0; + iUpper = p->nRowEst0; + }else{ + /* Note: this call could be optimized away - since the same values must + ** have been requested when testing key $P in whereEqualScanEst(). */ + whereKeyStats(pParse, p, pRec, 0, a); + iLower = a[0]; + iUpper = a[0] + a[1]; + } + + assert( pLower==0 || (pLower->eOperator & (WO_GT|WO_GE))!=0 ); + assert( pUpper==0 || (pUpper->eOperator & (WO_LT|WO_LE))!=0 ); + assert( p->aSortOrder!=0 ); + if( p->aSortOrder[nEq] ){ + /* The roles of pLower and pUpper are swapped for a DESC index */ + SWAP(WhereTerm*, pLower, pUpper); + SWAP(int, nBtm, nTop); + } + + /* If possible, improve on the iLower estimate using ($P:$L). */ + if( pLower ){ + int n; /* Values extracted from pExpr */ + Expr *pExpr = pLower->pExpr->pRight; + rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, nBtm, nEq, &n); + if( rc==SQLITE_OK && n ){ + tRowcnt iNew; + u16 mask = WO_GT|WO_LE; + if( sqlite3ExprVectorSize(pExpr)>n ) mask = (WO_LE|WO_LT); + iLwrIdx = whereKeyStats(pParse, p, pRec, 0, a); + iNew = a[0] + ((pLower->eOperator & mask) ? a[1] : 0); + if( iNew>iLower ) iLower = iNew; + nOut--; + pLower = 0; + } + } + + /* If possible, improve on the iUpper estimate using ($P:$U). */ + if( pUpper ){ + int n; /* Values extracted from pExpr */ + Expr *pExpr = pUpper->pExpr->pRight; + rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, nTop, nEq, &n); + if( rc==SQLITE_OK && n ){ + tRowcnt iNew; + u16 mask = WO_GT|WO_LE; + if( sqlite3ExprVectorSize(pExpr)>n ) mask = (WO_LE|WO_LT); + iUprIdx = whereKeyStats(pParse, p, pRec, 1, a); + iNew = a[0] + ((pUpper->eOperator & mask) ? a[1] : 0); + if( iNewpRec = pRec; + if( rc==SQLITE_OK ){ + if( iUpper>iLower ){ + nNew = sqlite3LogEst(iUpper - iLower); + /* TUNING: If both iUpper and iLower are derived from the same + ** sample, then assume they are 4x more selective. This brings + ** the estimated selectivity more in line with what it would be + ** if estimated without the use of STAT4 tables. */ + if( iLwrIdx==iUprIdx ){ nNew -= 20; } + assert( 20==sqlite3LogEst(4) ); + }else{ + nNew = 10; assert( 10==sqlite3LogEst(2) ); + } + if( nNewwtFlags & TERM_VNULL)==0 || pParse->nErr>0 ); + nNew = whereRangeAdjust(pLower, nOut); + nNew = whereRangeAdjust(pUpper, nNew); + + /* TUNING: If there is both an upper and lower limit and neither limit + ** has an application-defined likelihood(), assume the range is + ** reduced by an additional 75%. This means that, by default, an open-ended + ** range query (e.g. col > ?) is assumed to match 1/4 of the rows in the + ** index. While a closed range (e.g. col BETWEEN ? AND ?) is estimated to + ** match 1/64 of the index. */ + if( pLower && pLower->truthProb>0 && pUpper && pUpper->truthProb>0 ){ + nNew -= 20; + } + + nOut -= (pLower!=0) + (pUpper!=0); + if( nNew<10 ) nNew = 10; + if( nNewnOut>nOut ){ + WHERETRACE(0x20,("Range scan lowers nOut from %d to %d\n", + pLoop->nOut, nOut)); + } +#endif + pLoop->nOut = (LogEst)nOut; + return rc; +} + +#ifdef SQLITE_ENABLE_STAT4 +/* +** Estimate the number of rows that will be returned based on +** an equality constraint x=VALUE and where that VALUE occurs in +** the histogram data. This only works when x is the left-most +** column of an index and sqlite_stat4 histogram data is available +** for that index. When pExpr==NULL that means the constraint is +** "x IS NULL" instead of "x=VALUE". +** +** Write the estimated row count into *pnRow and return SQLITE_OK. +** If unable to make an estimate, leave *pnRow unchanged and return +** non-zero. +** +** This routine can fail if it is unable to load a collating sequence +** required for string comparison, or if unable to allocate memory +** for a UTF conversion required for comparison. The error is stored +** in the pParse structure. +*/ +static int whereEqualScanEst( + Parse *pParse, /* Parsing & code generating context */ + WhereLoopBuilder *pBuilder, + Expr *pExpr, /* Expression for VALUE in the x=VALUE constraint */ + tRowcnt *pnRow /* Write the revised row estimate here */ +){ + Index *p = pBuilder->pNew->u.btree.pIndex; + int nEq = pBuilder->pNew->u.btree.nEq; + UnpackedRecord *pRec = pBuilder->pRec; + int rc; /* Subfunction return code */ + tRowcnt a[2]; /* Statistics */ + int bOk; + + assert( nEq>=1 ); + assert( nEq<=p->nColumn ); + assert( p->aSample!=0 ); + assert( p->nSample>0 ); + assert( pBuilder->nRecValidnRecValid<(nEq-1) ){ + return SQLITE_NOTFOUND; + } + + /* This is an optimization only. The call to sqlite3Stat4ProbeSetValue() + ** below would return the same value. */ + if( nEq>=p->nColumn ){ + *pnRow = 1; + return SQLITE_OK; + } + + rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, 1, nEq-1, &bOk); + pBuilder->pRec = pRec; + if( rc!=SQLITE_OK ) return rc; + if( bOk==0 ) return SQLITE_NOTFOUND; + pBuilder->nRecValid = nEq; + + whereKeyStats(pParse, p, pRec, 0, a); + WHERETRACE(0x20,("equality scan regions %s(%d): %d\n", + p->zName, nEq-1, (int)a[1])); + *pnRow = a[1]; + + return rc; +} +#endif /* SQLITE_ENABLE_STAT4 */ + +#ifdef SQLITE_ENABLE_STAT4 +/* +** Estimate the number of rows that will be returned based on +** an IN constraint where the right-hand side of the IN operator +** is a list of values. Example: +** +** WHERE x IN (1,2,3,4) +** +** Write the estimated row count into *pnRow and return SQLITE_OK. +** If unable to make an estimate, leave *pnRow unchanged and return +** non-zero. +** +** This routine can fail if it is unable to load a collating sequence +** required for string comparison, or if unable to allocate memory +** for a UTF conversion required for comparison. The error is stored +** in the pParse structure. +*/ +static int whereInScanEst( + Parse *pParse, /* Parsing & code generating context */ + WhereLoopBuilder *pBuilder, + ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */ + tRowcnt *pnRow /* Write the revised row estimate here */ +){ + Index *p = pBuilder->pNew->u.btree.pIndex; + i64 nRow0 = sqlite3LogEstToInt(p->aiRowLogEst[0]); + int nRecValid = pBuilder->nRecValid; + int rc = SQLITE_OK; /* Subfunction return code */ + tRowcnt nEst; /* Number of rows for a single term */ + tRowcnt nRowEst = 0; /* New estimate of the number of rows */ + int i; /* Loop counter */ + + assert( p->aSample!=0 ); + for(i=0; rc==SQLITE_OK && inExpr; i++){ + nEst = nRow0; + rc = whereEqualScanEst(pParse, pBuilder, pList->a[i].pExpr, &nEst); + nRowEst += nEst; + pBuilder->nRecValid = nRecValid; + } + + if( rc==SQLITE_OK ){ + if( nRowEst > (tRowcnt)nRow0 ) nRowEst = nRow0; + *pnRow = nRowEst; + WHERETRACE(0x20,("IN row estimate: est=%d\n", nRowEst)); + } + assert( pBuilder->nRecValid==nRecValid ); + return rc; +} +#endif /* SQLITE_ENABLE_STAT4 */ + + +#if defined(WHERETRACE_ENABLED) || defined(SQLITE_DEBUG) +/* +** Print the content of a WhereTerm object +*/ +SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){ + if( pTerm==0 ){ + sqlite3DebugPrintf("TERM-%-3d NULL\n", iTerm); + }else{ + char zType[8]; + char zLeft[50]; + memcpy(zType, "....", 5); + if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V'; + if( pTerm->eOperator & WO_EQUIV ) zType[1] = 'E'; + if( ExprHasProperty(pTerm->pExpr, EP_OuterON) ) zType[2] = 'L'; + if( pTerm->wtFlags & TERM_CODED ) zType[3] = 'C'; + if( pTerm->eOperator & WO_SINGLE ){ + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); + sqlite3_snprintf(sizeof(zLeft),zLeft,"left={%d:%d}", + pTerm->leftCursor, pTerm->u.x.leftColumn); + }else if( (pTerm->eOperator & WO_OR)!=0 && pTerm->u.pOrInfo!=0 ){ + sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%llx", + pTerm->u.pOrInfo->indexable); + }else{ + sqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor); + } + iTerm = pTerm->iTerm = MAX(iTerm,pTerm->iTerm); + sqlite3DebugPrintf( + "TERM-%-3d %p %s %-12s op=%03x wtFlags=%04x", + iTerm, pTerm, zType, zLeft, pTerm->eOperator, pTerm->wtFlags); + /* The 0x10000 .wheretrace flag causes extra information to be + ** shown about each Term */ + if( sqlite3WhereTrace & 0x10000 ){ + sqlite3DebugPrintf(" prob=%-3d prereq=%llx,%llx", + pTerm->truthProb, (u64)pTerm->prereqAll, (u64)pTerm->prereqRight); + } + if( (pTerm->eOperator & (WO_OR|WO_AND))==0 && pTerm->u.x.iField ){ + sqlite3DebugPrintf(" iField=%d", pTerm->u.x.iField); + } + if( pTerm->iParent>=0 ){ + sqlite3DebugPrintf(" iParent=%d", pTerm->iParent); + } + sqlite3DebugPrintf("\n"); + sqlite3TreeViewExpr(0, pTerm->pExpr, 0); + } +} +SQLITE_PRIVATE void sqlite3ShowWhereTerm(WhereTerm *pTerm){ + sqlite3WhereTermPrint(pTerm, 0); +} +#endif + +#ifdef WHERETRACE_ENABLED +/* +** Show the complete content of a WhereClause +*/ +SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC){ + int i; + for(i=0; inTerm; i++){ + sqlite3WhereTermPrint(&pWC->a[i], i); + } +} +#endif + +#ifdef WHERETRACE_ENABLED +/* +** Print a WhereLoop object for debugging purposes +** +** Format example: +** +** .--- Position in WHERE clause rSetup, rRun, nOut ---. +** | | +** | .--- selfMask nTerm ------. | +** | | | | +** | | .-- prereq Idx wsFlags----. | | +** | | | Name | | | +** | | | __|__ nEq ---. ___|__ | __|__ +** | / \ / \ / \ | / \ / \ / \ +** 1.002.001 t2.t2xy 2 f 010241 N 2 cost 0,56,31 +*/ +SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause *pWC){ + WhereInfo *pWInfo; + if( pWC ){ + int nb; + SrcItem *pItem; + Table *pTab; + Bitmask mAll; + + pWInfo = pWC->pWInfo; + nb = 1+(pWInfo->pTabList->nSrc+3)/4; + pItem = pWInfo->pTabList->a + p->iTab; + pTab = pItem->pSTab; + mAll = (((Bitmask)1)<<(nb*4)) - 1; + sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, + p->iTab, nb, p->maskSelf, nb, p->prereq & mAll); + sqlite3DebugPrintf(" %12s", + pItem->zAlias ? pItem->zAlias : pTab->zName); + }else{ + pWInfo = 0; + sqlite3DebugPrintf("%c%2d.%03llx.%03llx %c%d", + p->cId, p->iTab, p->maskSelf, p->prereq & 0xfff, p->cId, p->iTab); + } + if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){ + const char *zName; + if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){ + if( strncmp(zName, "sqlite_autoindex_", 17)==0 ){ + int i = sqlite3Strlen30(zName) - 1; + while( zName[i]!='_' ) i--; + zName += i; + } + sqlite3DebugPrintf(".%-16s %2d", zName, p->u.btree.nEq); + }else{ + sqlite3DebugPrintf("%20s",""); + } + }else{ + char *z; + if( p->u.vtab.idxStr ){ + z = sqlite3_mprintf("(%d,\"%s\",%#x)", + p->u.vtab.idxNum, p->u.vtab.idxStr, p->u.vtab.omitMask); + }else{ + z = sqlite3_mprintf("(%d,%x)", p->u.vtab.idxNum, p->u.vtab.omitMask); + } + sqlite3DebugPrintf(" %-19s", z); + sqlite3_free(z); + } + if( p->wsFlags & WHERE_SKIPSCAN ){ + sqlite3DebugPrintf(" f %06x %d-%d", p->wsFlags, p->nLTerm,p->nSkip); + }else{ + sqlite3DebugPrintf(" f %06x N %d", p->wsFlags, p->nLTerm); + } + if( pWInfo && pWInfo->bStarUsed && p->rStarDelta!=0 ){ + sqlite3DebugPrintf(" cost %d,%d,%d delta=%d\n", + p->rSetup, p->rRun, p->nOut, p->rStarDelta); + }else{ + sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut); + } + if( p->nLTerm && (sqlite3WhereTrace & 0x4000)!=0 ){ + int i; + for(i=0; inLTerm; i++){ + sqlite3WhereTermPrint(p->aLTerm[i], i); + } + } +} +SQLITE_PRIVATE void sqlite3ShowWhereLoop(const WhereLoop *p){ + if( p ) sqlite3WhereLoopPrint(p, 0); +} +SQLITE_PRIVATE void sqlite3ShowWhereLoopList(const WhereLoop *p){ + while( p ){ + sqlite3ShowWhereLoop(p); + p = p->pNextLoop; + } +} +#endif + +/* +** Convert bulk memory into a valid WhereLoop that can be passed +** to whereLoopClear harmlessly. +*/ +static void whereLoopInit(WhereLoop *p){ + p->aLTerm = p->aLTermSpace; + p->nLTerm = 0; + p->nLSlot = ArraySize(p->aLTermSpace); + p->wsFlags = 0; +} + +/* +** Clear the WhereLoop.u union. Leave WhereLoop.pLTerm intact. +*/ +static void whereLoopClearUnion(sqlite3 *db, WhereLoop *p){ + if( p->wsFlags & (WHERE_VIRTUALTABLE|WHERE_AUTO_INDEX) ){ + if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 && p->u.vtab.needFree ){ + sqlite3_free(p->u.vtab.idxStr); + p->u.vtab.needFree = 0; + p->u.vtab.idxStr = 0; + }else if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && p->u.btree.pIndex!=0 ){ + sqlite3DbFree(db, p->u.btree.pIndex->zColAff); + sqlite3DbFreeNN(db, p->u.btree.pIndex); + p->u.btree.pIndex = 0; + } + } +} + +/* +** Deallocate internal memory used by a WhereLoop object. Leave the +** object in an initialized state, as if it had been newly allocated. +*/ +static void whereLoopClear(sqlite3 *db, WhereLoop *p){ + if( p->aLTerm!=p->aLTermSpace ){ + sqlite3DbFreeNN(db, p->aLTerm); + p->aLTerm = p->aLTermSpace; + p->nLSlot = ArraySize(p->aLTermSpace); + } + whereLoopClearUnion(db, p); + p->nLTerm = 0; + p->wsFlags = 0; +} + +/* +** Increase the memory allocation for pLoop->aLTerm[] to be at least n. +*/ +static int whereLoopResize(sqlite3 *db, WhereLoop *p, int n){ + WhereTerm **paNew; + if( p->nLSlot>=n ) return SQLITE_OK; + n = (n+7)&~7; + paNew = sqlite3DbMallocRawNN(db, sizeof(p->aLTerm[0])*n); + if( paNew==0 ) return SQLITE_NOMEM_BKPT; + memcpy(paNew, p->aLTerm, sizeof(p->aLTerm[0])*p->nLSlot); + if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFreeNN(db, p->aLTerm); + p->aLTerm = paNew; + p->nLSlot = n; + return SQLITE_OK; +} + +/* +** Transfer content from the second pLoop into the first. +*/ +static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){ + whereLoopClearUnion(db, pTo); + if( pFrom->nLTerm > pTo->nLSlot + && whereLoopResize(db, pTo, pFrom->nLTerm) + ){ + memset(pTo, 0, WHERE_LOOP_XFER_SZ); + return SQLITE_NOMEM_BKPT; + } + memcpy(pTo, pFrom, WHERE_LOOP_XFER_SZ); + memcpy(pTo->aLTerm, pFrom->aLTerm, pTo->nLTerm*sizeof(pTo->aLTerm[0])); + if( pFrom->wsFlags & WHERE_VIRTUALTABLE ){ + pFrom->u.vtab.needFree = 0; + }else if( (pFrom->wsFlags & WHERE_AUTO_INDEX)!=0 ){ + pFrom->u.btree.pIndex = 0; + } + return SQLITE_OK; +} + +/* +** Delete a WhereLoop object +*/ +static void whereLoopDelete(sqlite3 *db, WhereLoop *p){ + assert( db!=0 ); + whereLoopClear(db, p); + sqlite3DbNNFreeNN(db, p); +} + +/* +** Free a WhereInfo structure +*/ +static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ + assert( pWInfo!=0 ); + assert( db!=0 ); + sqlite3WhereClauseClear(&pWInfo->sWC); + while( pWInfo->pLoops ){ + WhereLoop *p = pWInfo->pLoops; + pWInfo->pLoops = p->pNextLoop; + whereLoopDelete(db, p); + } + while( pWInfo->pMemToFree ){ + WhereMemBlock *pNext = pWInfo->pMemToFree->pNext; + sqlite3DbNNFreeNN(db, pWInfo->pMemToFree); + pWInfo->pMemToFree = pNext; + } + sqlite3DbNNFreeNN(db, pWInfo); +} + +/* +** Return TRUE if X is a proper subset of Y but is of equal or less cost. +** In other words, return true if all constraints of X are also part of Y +** and Y has additional constraints that might speed the search that X lacks +** but the cost of running X is not more than the cost of running Y. +** +** In other words, return true if the cost relationship between X and Y +** is inverted and needs to be adjusted. +** +** Case 1: +** +** (1a) X and Y use the same index. +** (1b) X has fewer == terms than Y +** (1c) Neither X nor Y use skip-scan +** (1d) X does not have a a greater cost than Y +** +** Case 2: +** +** (2a) X has the same or lower cost, or returns the same or fewer rows, +** than Y. +** (2b) X uses fewer WHERE clause terms than Y +** (2c) Every WHERE clause term used by X is also used by Y +** (2d) X skips at least as many columns as Y +** (2e) If X is a covering index, than Y is too +*/ +static int whereLoopCheaperProperSubset( + const WhereLoop *pX, /* First WhereLoop to compare */ + const WhereLoop *pY /* Compare against this WhereLoop */ +){ + int i, j; + if( pX->rRun>pY->rRun && pX->nOut>pY->nOut ) return 0; /* (1d) and (2a) */ + assert( (pX->wsFlags & WHERE_VIRTUALTABLE)==0 ); + assert( (pY->wsFlags & WHERE_VIRTUALTABLE)==0 ); + if( pX->u.btree.nEq < pY->u.btree.nEq /* (1b) */ + && pX->u.btree.pIndex==pY->u.btree.pIndex /* (1a) */ + && pX->nSkip==0 && pY->nSkip==0 /* (1c) */ + ){ + return 1; /* Case 1 is true */ + } + if( pX->nLTerm-pX->nSkip >= pY->nLTerm-pY->nSkip ){ + return 0; /* (2b) */ + } + if( pY->nSkip > pX->nSkip ) return 0; /* (2d) */ + for(i=pX->nLTerm-1; i>=0; i--){ + if( pX->aLTerm[i]==0 ) continue; + for(j=pY->nLTerm-1; j>=0; j--){ + if( pY->aLTerm[j]==pX->aLTerm[i] ) break; + } + if( j<0 ) return 0; /* (2c) */ + } + if( (pX->wsFlags&WHERE_IDX_ONLY)!=0 + && (pY->wsFlags&WHERE_IDX_ONLY)==0 ){ + return 0; /* (2e) */ + } + return 1; /* Case 2 is true */ +} + +/* +** Try to adjust the cost and number of output rows of WhereLoop pTemplate +** upwards or downwards so that: +** +** (1) pTemplate costs less than any other WhereLoops that are a proper +** subset of pTemplate +** +** (2) pTemplate costs more than any other WhereLoops for which pTemplate +** is a proper subset. +** +** To say "WhereLoop X is a proper subset of Y" means that X uses fewer +** WHERE clause terms than Y and that every WHERE clause term used by X is +** also used by Y. +*/ +static void whereLoopAdjustCost(const WhereLoop *p, WhereLoop *pTemplate){ + if( (pTemplate->wsFlags & WHERE_INDEXED)==0 ) return; + for(; p; p=p->pNextLoop){ + if( p->iTab!=pTemplate->iTab ) continue; + if( (p->wsFlags & WHERE_INDEXED)==0 ) continue; + if( whereLoopCheaperProperSubset(p, pTemplate) ){ + /* Adjust pTemplate cost downward so that it is cheaper than its + ** subset p. */ + WHERETRACE(0x80,("subset cost adjustment %d,%d to %d,%d\n", + pTemplate->rRun, pTemplate->nOut, + MIN(p->rRun, pTemplate->rRun), + MIN(p->nOut - 1, pTemplate->nOut))); + pTemplate->rRun = MIN(p->rRun, pTemplate->rRun); + pTemplate->nOut = MIN(p->nOut - 1, pTemplate->nOut); + }else if( whereLoopCheaperProperSubset(pTemplate, p) ){ + /* Adjust pTemplate cost upward so that it is costlier than p since + ** pTemplate is a proper subset of p */ + WHERETRACE(0x80,("subset cost adjustment %d,%d to %d,%d\n", + pTemplate->rRun, pTemplate->nOut, + MAX(p->rRun, pTemplate->rRun), + MAX(p->nOut + 1, pTemplate->nOut))); + pTemplate->rRun = MAX(p->rRun, pTemplate->rRun); + pTemplate->nOut = MAX(p->nOut + 1, pTemplate->nOut); + } + } +} + +/* +** Search the list of WhereLoops in *ppPrev looking for one that can be +** replaced by pTemplate. +** +** Return NULL if pTemplate does not belong on the WhereLoop list. +** In other words if pTemplate ought to be dropped from further consideration. +** +** If pX is a WhereLoop that pTemplate can replace, then return the +** link that points to pX. +** +** If pTemplate cannot replace any existing element of the list but needs +** to be added to the list as a new entry, then return a pointer to the +** tail of the list. +*/ +static WhereLoop **whereLoopFindLesser( + WhereLoop **ppPrev, + const WhereLoop *pTemplate +){ + WhereLoop *p; + for(p=(*ppPrev); p; ppPrev=&p->pNextLoop, p=*ppPrev){ + if( p->iTab!=pTemplate->iTab || p->iSortIdx!=pTemplate->iSortIdx ){ + /* If either the iTab or iSortIdx values for two WhereLoop are different + ** then those WhereLoops need to be considered separately. Neither is + ** a candidate to replace the other. */ + continue; + } + /* In the current implementation, the rSetup value is either zero + ** or the cost of building an automatic index (NlogN) and the NlogN + ** is the same for compatible WhereLoops. */ + assert( p->rSetup==0 || pTemplate->rSetup==0 + || p->rSetup==pTemplate->rSetup ); + + /* whereLoopAddBtree() always generates and inserts the automatic index + ** case first. Hence compatible candidate WhereLoops never have a larger + ** rSetup. Call this SETUP-INVARIANT */ + assert( p->rSetup>=pTemplate->rSetup ); + + /* Any loop using an application-defined index (or PRIMARY KEY or + ** UNIQUE constraint) with one or more == constraints is better + ** than an automatic index. Unless it is a skip-scan. */ + if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 + && (pTemplate->nSkip)==0 + && (pTemplate->wsFlags & WHERE_INDEXED)!=0 + && (pTemplate->wsFlags & WHERE_COLUMN_EQ)!=0 + && (p->prereq & pTemplate->prereq)==pTemplate->prereq + ){ + break; + } + + /* If existing WhereLoop p is better than pTemplate, pTemplate can be + ** discarded. WhereLoop p is better if: + ** (1) p has no more dependencies than pTemplate, and + ** (2) p has an equal or lower cost than pTemplate + */ + if( (p->prereq & pTemplate->prereq)==p->prereq /* (1) */ + && p->rSetup<=pTemplate->rSetup /* (2a) */ + && p->rRun<=pTemplate->rRun /* (2b) */ + && p->nOut<=pTemplate->nOut /* (2c) */ + ){ + return 0; /* Discard pTemplate */ + } + + /* If pTemplate is always better than p, then cause p to be overwritten + ** with pTemplate. pTemplate is better than p if: + ** (1) pTemplate has no more dependencies than p, and + ** (2) pTemplate has an equal or lower cost than p. + */ + if( (p->prereq & pTemplate->prereq)==pTemplate->prereq /* (1) */ + && p->rRun>=pTemplate->rRun /* (2a) */ + && p->nOut>=pTemplate->nOut /* (2b) */ + ){ + assert( p->rSetup>=pTemplate->rSetup ); /* SETUP-INVARIANT above */ + break; /* Cause p to be overwritten by pTemplate */ + } + } + return ppPrev; +} + +/* +** Insert or replace a WhereLoop entry using the template supplied. +** +** An existing WhereLoop entry might be overwritten if the new template +** is better and has fewer dependencies. Or the template will be ignored +** and no insert will occur if an existing WhereLoop is faster and has +** fewer dependencies than the template. Otherwise a new WhereLoop is +** added based on the template. +** +** If pBuilder->pOrSet is not NULL then we care about only the +** prerequisites and rRun and nOut costs of the N best loops. That +** information is gathered in the pBuilder->pOrSet object. This special +** processing mode is used only for OR clause processing. +** +** When accumulating multiple loops (when pBuilder->pOrSet is NULL) we +** still might overwrite similar loops with the new template if the +** new template is better. Loops may be overwritten if the following +** conditions are met: +** +** (1) They have the same iTab. +** (2) They have the same iSortIdx. +** (3) The template has same or fewer dependencies than the current loop +** (4) The template has the same or lower cost than the current loop +*/ +static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ + WhereLoop **ppPrev, *p; + WhereInfo *pWInfo = pBuilder->pWInfo; + sqlite3 *db = pWInfo->pParse->db; + int rc; + + /* Stop the search once we hit the query planner search limit */ + if( pBuilder->iPlanLimit==0 ){ + WHERETRACE(0xffffffff,("=== query planner search limit reached ===\n")); + if( pBuilder->pOrSet ) pBuilder->pOrSet->n = 0; + return SQLITE_DONE; + } + pBuilder->iPlanLimit--; + + whereLoopAdjustCost(pWInfo->pLoops, pTemplate); + + /* If pBuilder->pOrSet is defined, then only keep track of the costs + ** and prereqs. + */ + if( pBuilder->pOrSet!=0 ){ + if( pTemplate->nLTerm ){ +#if WHERETRACE_ENABLED + u16 n = pBuilder->pOrSet->n; + int x = +#endif + whereOrInsert(pBuilder->pOrSet, pTemplate->prereq, pTemplate->rRun, + pTemplate->nOut); +#if WHERETRACE_ENABLED /* 0x8 */ + if( sqlite3WhereTrace & 0x8 ){ + sqlite3DebugPrintf(x?" or-%d: ":" or-X: ", n); + sqlite3WhereLoopPrint(pTemplate, pBuilder->pWC); + } +#endif + } + return SQLITE_OK; + } + + /* Look for an existing WhereLoop to replace with pTemplate + */ + ppPrev = whereLoopFindLesser(&pWInfo->pLoops, pTemplate); + + if( ppPrev==0 ){ + /* There already exists a WhereLoop on the list that is better + ** than pTemplate, so just ignore pTemplate */ +#if WHERETRACE_ENABLED /* 0x8 */ + if( sqlite3WhereTrace & 0x8 ){ + sqlite3DebugPrintf(" skip: "); + sqlite3WhereLoopPrint(pTemplate, pBuilder->pWC); + } +#endif + return SQLITE_OK; + }else{ + p = *ppPrev; + } + + /* If we reach this point it means that either p[] should be overwritten + ** with pTemplate[] if p[] exists, or if p==NULL then allocate a new + ** WhereLoop and insert it. + */ +#if WHERETRACE_ENABLED /* 0x8 */ + if( sqlite3WhereTrace & 0x8 ){ + if( p!=0 ){ + sqlite3DebugPrintf("replace: "); + sqlite3WhereLoopPrint(p, pBuilder->pWC); + sqlite3DebugPrintf(" with: "); + }else{ + sqlite3DebugPrintf(" add: "); + } + sqlite3WhereLoopPrint(pTemplate, pBuilder->pWC); + } +#endif + if( p==0 ){ + /* Allocate a new WhereLoop to add to the end of the list */ + *ppPrev = p = sqlite3DbMallocRawNN(db, sizeof(WhereLoop)); + if( p==0 ) return SQLITE_NOMEM_BKPT; + whereLoopInit(p); + p->pNextLoop = 0; + }else{ + /* We will be overwriting WhereLoop p[]. But before we do, first + ** go through the rest of the list and delete any other entries besides + ** p[] that are also supplanted by pTemplate */ + WhereLoop **ppTail = &p->pNextLoop; + WhereLoop *pToDel; + while( *ppTail ){ + ppTail = whereLoopFindLesser(ppTail, pTemplate); + if( ppTail==0 ) break; + pToDel = *ppTail; + if( pToDel==0 ) break; + *ppTail = pToDel->pNextLoop; +#if WHERETRACE_ENABLED /* 0x8 */ + if( sqlite3WhereTrace & 0x8 ){ + sqlite3DebugPrintf(" delete: "); + sqlite3WhereLoopPrint(pToDel, pBuilder->pWC); + } +#endif + whereLoopDelete(db, pToDel); + } + } + rc = whereLoopXfer(db, p, pTemplate); + if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){ + Index *pIndex = p->u.btree.pIndex; + if( pIndex && pIndex->idxType==SQLITE_IDXTYPE_IPK ){ + p->u.btree.pIndex = 0; + } + } + return rc; +} + +/* +** Callback for estLikePatternLength(). +** +** If this node is a string literal that is longer pWalker->sz, then set +** pWalker->sz to the byte length of that string literal. +** +** pWalker->eCode indicates how to count characters: +** +** eCode==0 Count as a GLOB pattern +** eCode==1 Count as a LIKE pattern +*/ +static int exprNodePatternLengthEst(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_STRING ){ + int sz = 0; /* Pattern size in bytes */ + u8 *z = (u8*)pExpr->u.zToken; /* The pattern */ + u8 c; /* Next character of the pattern */ + u8 c1, c2, c3; /* Wildcards */ + if( pWalker->eCode ){ + c1 = '%'; + c2 = '_'; + c3 = 0; + }else{ + c1 = '*'; + c2 = '?'; + c3 = '['; + } + while( (c = *(z++))!=0 ){ + if( c==c3 ){ + if( *z ) z++; + while( *z && *z!=']' ) z++; + }else if( c!=c1 && c!=c2 ){ + sz++; + } + } + if( sz>pWalker->u.sz ) pWalker->u.sz = sz; + } + return WRC_Continue; +} + +/* +** Return the length of the longest string literal in the given +** expression. +** +** eCode indicates how to count characters: +** +** eCode==0 Count as a GLOB pattern +** eCode==1 Count as a LIKE pattern +*/ +static int estLikePatternLength(Expr *p, u16 eCode){ + Walker w; + w.u.sz = 0; + w.eCode = eCode; + w.xExprCallback = exprNodePatternLengthEst; + w.xSelectCallback = sqlite3SelectWalkFail; +#ifdef SQLITE_DEBUG + w.xSelectCallback2 = sqlite3SelectWalkAssert2; +#endif + sqlite3WalkExpr(&w, p); + return w.u.sz; +} + +/* +** Adjust the WhereLoop.nOut value downward to account for terms of the +** WHERE clause that reference the loop but which are not used by an +** index. +* +** For every WHERE clause term that is not used by the index +** and which has a truth probability assigned by one of the likelihood(), +** likely(), or unlikely() SQL functions, reduce the estimated number +** of output rows by the probability specified. +** +** TUNING: For every WHERE clause term that is not used by the index +** and which does not have an assigned truth probability, heuristics +** described below are used to try to estimate the truth probability. +** TODO --> Perhaps this is something that could be improved by better +** table statistics. +** +** Heuristic 1: Estimate the truth probability as 93.75%. The 93.75% +** value corresponds to -1 in LogEst notation, so this means decrement +** the WhereLoop.nOut field for every such WHERE clause term. +** +** Heuristic 2: If there exists one or more WHERE clause terms of the +** form "x==EXPR" and EXPR is not a constant 0 or 1, then make sure the +** final output row estimate is no greater than 1/4 of the total number +** of rows in the table. In other words, assume that x==EXPR will filter +** out at least 3 out of 4 rows. If EXPR is -1 or 0 or 1, then maybe the +** "x" column is boolean or else -1 or 0 or 1 is a common default value +** on the "x" column and so in that case only cap the output row estimate +** at 1/2 instead of 1/4. +** +** Heuristic 3: If there is a LIKE or GLOB (or REGEXP or MATCH) operator +** with a large constant pattern, then reduce the size of the search +** space according to the length of the pattern, under the theory that +** longer patterns are less likely to match. This heuristic was added +** to give better output-row count estimates when preparing queries for +** the Join-Order Benchmarks. See forum thread 2026-01-30T09:57:54z +*/ +static void whereLoopOutputAdjust( + WhereClause *pWC, /* The WHERE clause */ + WhereLoop *pLoop, /* The loop to adjust downward */ + LogEst nRow /* Number of rows in the entire table */ +){ + WhereTerm *pTerm, *pX; + Bitmask notAllowed = ~(pLoop->prereq|pLoop->maskSelf); + int i, j; + LogEst iReduce = 0; /* pLoop->nOut should not exceed nRow-iReduce */ + + assert( (pLoop->wsFlags & WHERE_AUTO_INDEX)==0 ); + for(i=pWC->nBase, pTerm=pWC->a; i>0; i--, pTerm++){ + assert( pTerm!=0 ); + if( (pTerm->prereqAll & notAllowed)!=0 ) continue; + if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue; + if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) continue; + for(j=pLoop->nLTerm-1; j>=0; j--){ + pX = pLoop->aLTerm[j]; + if( pX==0 ) continue; + if( pX==pTerm ) break; + if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break; + } + if( j<0 ){ + sqlite3ProgressCheck(pWC->pWInfo->pParse); + if( pLoop->maskSelf==pTerm->prereqAll ){ + /* If there are extra terms in the WHERE clause not used by an index + ** that depend only on the table being scanned, and that will tend to + ** cause many rows to be omitted, then mark that table as + ** "self-culling". + ** + ** 2022-03-24: Self-culling only applies if either the extra terms + ** are straight comparison operators that are non-true with NULL + ** operand, or if the loop is not an OUTER JOIN. + */ + if( (pTerm->eOperator & 0x3f)!=0 + || (pWC->pWInfo->pTabList->a[pLoop->iTab].fg.jointype + & (JT_LEFT|JT_LTORJ))==0 + ){ + pLoop->wsFlags |= WHERE_SELFCULL; + } + } + if( pTerm->truthProb<=0 ){ + /* If a truth probability is specified using the likelihood() hints, + ** then use the probability provided by the application. */ + pLoop->nOut += pTerm->truthProb; + }else{ + /* In the absence of explicit truth probabilities, use heuristics to + ** guess a reasonable truth probability. */ + Expr *pOpExpr = pTerm->pExpr; + pLoop->nOut--; + if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 + && (pTerm->wtFlags & TERM_HIGHTRUTH)==0 /* tag-20200224-1 */ + ){ + Expr *pRight = pOpExpr->pRight; + int k = 0; + testcase( pOpExpr->op==TK_IS ); + if( sqlite3ExprIsInteger(pRight, &k, 0) && k>=(-1) && k<=1 ){ + k = 10; + }else{ + k = 20; + } + if( iReducewtFlags |= TERM_HEURTRUTH; + iReduce = k; + } + }else + if( ExprHasProperty(pOpExpr, EP_InfixFunc) + && pOpExpr->op==TK_FUNCTION + ){ + int eOp; + assert( ExprUseXList(pOpExpr) ); + assert( pOpExpr->x.pList->nExpr>=2 ); + eOp = sqlite3ExprIsLikeOperator(pOpExpr); + if( ALWAYS(eOp>0) ){ + int szPattern; + Expr *pRHS = pOpExpr->x.pList->a[0].pExpr; + eOp = eOp==SQLITE_INDEX_CONSTRAINT_LIKE; + szPattern = estLikePatternLength(pRHS, eOp); + if( szPattern>0 ){ + pLoop->nOut -= szPattern*2; + } + } + } + } + } + } + if( pLoop->nOut > nRow-iReduce ){ + pLoop->nOut = nRow - iReduce; + } +} + +/* +** Term pTerm is a vector range comparison operation. The first comparison +** in the vector can be optimized using column nEq of the index. This +** function returns the total number of vector elements that can be used +** as part of the range comparison. +** +** For example, if the query is: +** +** WHERE a = ? AND (b, c, d) > (?, ?, ?) +** +** and the index: +** +** CREATE INDEX ... ON (a, b, c, d, e) +** +** then this function would be invoked with nEq=1. The value returned in +** this case is 3. +*/ +static int whereRangeVectorLen( + Parse *pParse, /* Parsing context */ + int iCur, /* Cursor open on pIdx */ + Index *pIdx, /* The index to be used for a inequality constraint */ + int nEq, /* Number of prior equality constraints on same index */ + WhereTerm *pTerm /* The vector inequality constraint */ +){ + int nCmp = sqlite3ExprVectorSize(pTerm->pExpr->pLeft); + int i; + + nCmp = MIN(nCmp, (pIdx->nColumn - nEq)); + for(i=1; ipExpr->pLeft) ); + pLhs = pTerm->pExpr->pLeft->x.pList->a[i].pExpr; + pRhs = pTerm->pExpr->pRight; + if( ExprUseXSelect(pRhs) ){ + pRhs = pRhs->x.pSelect->pEList->a[i].pExpr; + }else{ + pRhs = pRhs->x.pList->a[i].pExpr; + } + + /* Check that the LHS of the comparison is a column reference to + ** the right column of the right source table. And that the sort + ** order of the index column is the same as the sort order of the + ** leftmost index column. */ + if( pLhs->op!=TK_COLUMN + || pLhs->iTable!=iCur + || pLhs->iColumn!=pIdx->aiColumn[i+nEq] + || pIdx->aSortOrder[i+nEq]!=pIdx->aSortOrder[nEq] + ){ + break; + } + + testcase( pLhs->iColumn==XN_ROWID ); + aff = sqlite3CompareAffinity(pRhs, sqlite3ExprAffinity(pLhs)); + idxaff = sqlite3TableColumnAffinity(pIdx->pTable, pLhs->iColumn); + if( aff!=idxaff ) break; + + if( ExprHasProperty(pTerm->pExpr, EP_Commuted) ) SWAP(Expr*, pRhs, pLhs); + pColl = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); + if( pColl==0 ) break; + if( sqlite3StrICmp(pColl->zName, pIdx->azColl[i+nEq]) ) break; + } + return i; +} + +/* +** Adjust the cost C by the costMult factor T. This only occurs if +** compiled with -DSQLITE_ENABLE_COSTMULT +*/ +#ifdef SQLITE_ENABLE_COSTMULT +# define ApplyCostMultiplier(C,T) C += T +#else +# define ApplyCostMultiplier(C,T) +#endif + +/* +** We have so far matched pBuilder->pNew->u.btree.nEq terms of the +** index pIndex. Try to match one more. +** +** When this function is called, pBuilder->pNew->nOut contains the +** number of rows expected to be visited by filtering using the nEq +** terms only. If it is modified, this value is restored before this +** function returns. +** +** If pProbe->idxType==SQLITE_IDXTYPE_IPK, that means pIndex is +** a fake index used for the INTEGER PRIMARY KEY. +*/ +static int whereLoopAddBtreeIndex( + WhereLoopBuilder *pBuilder, /* The WhereLoop factory */ + SrcItem *pSrc, /* FROM clause term being analyzed */ + Index *pProbe, /* An index on pSrc */ + LogEst nInMul /* log(Number of iterations due to IN) */ +){ + WhereInfo *pWInfo = pBuilder->pWInfo; /* WHERE analyze context */ + Parse *pParse = pWInfo->pParse; /* Parsing context */ + sqlite3 *db = pParse->db; /* Database connection malloc context */ + WhereLoop *pNew; /* Template WhereLoop under construction */ + WhereTerm *pTerm; /* A WhereTerm under consideration */ + int opMask; /* Valid operators for constraints */ + WhereScan scan; /* Iterator for WHERE terms */ + Bitmask saved_prereq; /* Original value of pNew->prereq */ + u16 saved_nLTerm; /* Original value of pNew->nLTerm */ + u16 saved_nEq; /* Original value of pNew->u.btree.nEq */ + u16 saved_nBtm; /* Original value of pNew->u.btree.nBtm */ + u16 saved_nTop; /* Original value of pNew->u.btree.nTop */ + u16 saved_nSkip; /* Original value of pNew->nSkip */ + u32 saved_wsFlags; /* Original value of pNew->wsFlags */ + LogEst saved_nOut; /* Original value of pNew->nOut */ + int rc = SQLITE_OK; /* Return code */ + LogEst rSize; /* Number of rows in the table */ + LogEst rLogSize; /* Logarithm of table size */ + WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */ + + pNew = pBuilder->pNew; + assert( db->mallocFailed==0 || pParse->nErr>0 ); + if( pParse->nErr ){ + return pParse->rc; + } + WHERETRACE(0x800, ("BEGIN %s.addBtreeIdx(%s), nEq=%d, nSkip=%d, rRun=%d\n", + pProbe->pTable->zName,pProbe->zName, + pNew->u.btree.nEq, pNew->nSkip, pNew->rRun)); + + assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 ); + assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 ); + if( pNew->wsFlags & WHERE_BTM_LIMIT ){ + opMask = WO_LT|WO_LE; + }else{ + assert( pNew->u.btree.nBtm==0 ); + opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS; + } + if( pProbe->bUnordered ){ + opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE); + } + + assert( pNew->u.btree.nEqnColumn ); + assert( pNew->u.btree.nEqnKeyCol + || pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY ); + + saved_nEq = pNew->u.btree.nEq; + saved_nBtm = pNew->u.btree.nBtm; + saved_nTop = pNew->u.btree.nTop; + saved_nSkip = pNew->nSkip; + saved_nLTerm = pNew->nLTerm; + saved_wsFlags = pNew->wsFlags; + saved_prereq = pNew->prereq; + saved_nOut = pNew->nOut; + pTerm = whereScanInit(&scan, pBuilder->pWC, pSrc->iCursor, saved_nEq, + opMask, pProbe); + pNew->rSetup = 0; + rSize = pProbe->aiRowLogEst[0]; + rLogSize = estLog(rSize); + for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){ + u16 eOp = pTerm->eOperator; /* Shorthand for pTerm->eOperator */ + LogEst rCostIdx; + LogEst nOutUnadjusted; /* nOut before IN() and WHERE adjustments */ + int nIn = 0; +#ifdef SQLITE_ENABLE_STAT4 + int nRecValid = pBuilder->nRecValid; +#endif + if( (eOp==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0) + && indexColumnNotNull(pProbe, saved_nEq) + ){ + continue; /* ignore IS [NOT] NULL constraints on NOT NULL columns */ + } + if( pTerm->prereqRight & pNew->maskSelf ) continue; + + /* Do not allow the upper bound of a LIKE optimization range constraint + ** to mix with a lower range bound from some other source */ + if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue; + + if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 + && !constraintCompatibleWithOuterJoin(pTerm,pSrc) + ){ + continue; + } + if( IsUniqueIndex(pProbe) && saved_nEq==pProbe->nKeyCol-1 ){ + pBuilder->bldFlags1 |= SQLITE_BLDF1_UNIQUE; + }else{ + pBuilder->bldFlags1 |= SQLITE_BLDF1_INDEXED; + } + pNew->wsFlags = saved_wsFlags; + pNew->u.btree.nEq = saved_nEq; + pNew->u.btree.nBtm = saved_nBtm; + pNew->u.btree.nTop = saved_nTop; + pNew->nLTerm = saved_nLTerm; + if( pNew->nLTerm>=pNew->nLSlot + && whereLoopResize(db, pNew, pNew->nLTerm+1) + ){ + break; /* OOM while trying to enlarge the pNew->aLTerm array */ + } + pNew->aLTerm[pNew->nLTerm++] = pTerm; + pNew->prereq = (saved_prereq | pTerm->prereqRight) & ~pNew->maskSelf; + + assert( nInMul==0 + || (pNew->wsFlags & WHERE_COLUMN_NULL)!=0 + || (pNew->wsFlags & WHERE_COLUMN_IN)!=0 + || (pNew->wsFlags & WHERE_SKIPSCAN)!=0 + ); + + if( eOp & WO_IN ){ + Expr *pExpr = pTerm->pExpr; + if( ExprUseXSelect(pExpr) ){ + /* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */ + int i; + int bRedundant = 0; + nIn = 46; assert( 46==sqlite3LogEst(25) ); + + /* The expression may actually be of the form (x, y) IN (SELECT...). + ** In this case there is a separate term for each of (x) and (y). + ** However, the nIn multiplier should only be applied once, not once + ** for each such term. The following loop checks that pTerm is the + ** first such term in use, and sets nIn back to 0 if it is not. */ + for(i=0; inLTerm-1; i++){ + if( pNew->aLTerm[i] && pNew->aLTerm[i]->pExpr==pExpr ){ + nIn = 0; + if( pNew->aLTerm[i]->u.x.iField == pTerm->u.x.iField ){ + /* Detect when two or more columns of an index match the same + ** column of a vector IN operater, and avoid adding the column + ** to the WhereLoop more than once. See tag-20250707-01 + ** in test/rowvalue.test */ + bRedundant = 1; + } + } + } + if( bRedundant ){ + pNew->nLTerm--; + continue; + } + }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){ + /* "x IN (value, value, ...)" */ + nIn = sqlite3LogEst(pExpr->x.pList->nExpr); + } + if( pProbe->hasStat1 && rLogSize>=10 ){ + LogEst M, logK, x; + /* Let: + ** N = the total number of rows in the table + ** K = the number of entries on the RHS of the IN operator + ** M = the number of rows in the table that match terms to the + ** to the left in the same index. If the IN operator is on + ** the left-most index column, M==N. + ** + ** Given the definitions above, it is better to omit the IN operator + ** from the index lookup and instead do a scan of the M elements, + ** testing each scanned row against the IN operator separately, if: + ** + ** M*log(K) < K*log(N) + ** + ** Our estimates for M, K, and N might be inaccurate, so we build in + ** a safety margin of 2 (LogEst: 10) that favors using the IN operator + ** with the index, as using an index has better worst-case behavior. + ** If we do not have real sqlite_stat1 data, always prefer to use + ** the index. Do not bother with this optimization on very small + ** tables (less than 2 rows) as it is pointless in that case. + */ + M = pProbe->aiRowLogEst[saved_nEq]; + logK = estLog(nIn); + /* TUNING v----- 10 to bias toward indexed IN */ + x = M + logK + 10 - (nIn + rLogSize); + if( x>=0 ){ + WHERETRACE(0x40, + ("IN operator (N=%d M=%d logK=%d nIn=%d rLogSize=%d x=%d) " + "prefers indexed lookup\n", + saved_nEq, M, logK, nIn, rLogSize, x)); + }else if( nInMul<2 && OptimizationEnabled(db, SQLITE_SeekScan) ){ + WHERETRACE(0x40, + ("IN operator (N=%d M=%d logK=%d nIn=%d rLogSize=%d x=%d" + " nInMul=%d) prefers skip-scan\n", + saved_nEq, M, logK, nIn, rLogSize, x, nInMul)); + pNew->wsFlags |= WHERE_IN_SEEKSCAN; + }else{ + WHERETRACE(0x40, + ("IN operator (N=%d M=%d logK=%d nIn=%d rLogSize=%d x=%d" + " nInMul=%d) prefers normal scan\n", + saved_nEq, M, logK, nIn, rLogSize, x, nInMul)); + continue; + } + } + pNew->wsFlags |= WHERE_COLUMN_IN; + }else if( eOp & (WO_EQ|WO_IS) ){ + int iCol = pProbe->aiColumn[saved_nEq]; + pNew->wsFlags |= WHERE_COLUMN_EQ; + assert( saved_nEq==pNew->u.btree.nEq ); + if( iCol==XN_ROWID + || (iCol>=0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1) + ){ + if( iCol==XN_ROWID || pProbe->uniqNotNull + || (pProbe->nKeyCol==1 && pProbe->onError && (eOp & WO_EQ)) + ){ + pNew->wsFlags |= WHERE_ONEROW; + }else{ + pNew->wsFlags |= WHERE_UNQ_WANTED; + } + } + if( scan.iEquiv>1 ) pNew->wsFlags |= WHERE_TRANSCONS; + }else if( eOp & WO_ISNULL ){ + pNew->wsFlags |= WHERE_COLUMN_NULL; + }else{ + int nVecLen = whereRangeVectorLen( + pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm + ); + if( eOp & (WO_GT|WO_GE) ){ + testcase( eOp & WO_GT ); + testcase( eOp & WO_GE ); + pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT; + pNew->u.btree.nBtm = nVecLen; + pBtm = pTerm; + pTop = 0; + if( pTerm->wtFlags & TERM_LIKEOPT ){ + /* Range constraints that come from the LIKE optimization are + ** always used in pairs. */ + pTop = &pTerm[1]; + assert( (pTop-(pTerm->pWC->a))pWC->nTerm ); + assert( pTop->wtFlags & TERM_LIKEOPT ); + assert( pTop->eOperator==WO_LT ); + if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ + pNew->aLTerm[pNew->nLTerm++] = pTop; + pNew->wsFlags |= WHERE_TOP_LIMIT; + pNew->u.btree.nTop = 1; + } + }else{ + assert( eOp & (WO_LT|WO_LE) ); + testcase( eOp & WO_LT ); + testcase( eOp & WO_LE ); + pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT; + pNew->u.btree.nTop = nVecLen; + pTop = pTerm; + pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ? + pNew->aLTerm[pNew->nLTerm-2] : 0; + } + } + + /* At this point pNew->nOut is set to the number of rows expected to + ** be visited by the index scan before considering term pTerm, or the + ** values of nIn and nInMul. In other words, assuming that all + ** "x IN(...)" terms are replaced with "x = ?". This block updates + ** the value of pNew->nOut to account for pTerm (but not nIn/nInMul). */ + assert( pNew->nOut==saved_nOut ); + if( pNew->wsFlags & WHERE_COLUMN_RANGE ){ + /* Adjust nOut using stat4 data. Or, if there is no stat4 + ** data, using some other estimate. */ + whereRangeScanEst(pParse, pBuilder, pBtm, pTop, pNew); + }else{ + int nEq = ++pNew->u.btree.nEq; + assert( eOp & (WO_ISNULL|WO_EQ|WO_IN|WO_IS) ); + + assert( pNew->nOut==saved_nOut ); + if( pTerm->truthProb<=0 && pProbe->aiColumn[saved_nEq]>=0 ){ + assert( (eOp & WO_IN) || nIn==0 ); + testcase( eOp & WO_IN ); + pNew->nOut += pTerm->truthProb; + pNew->nOut -= nIn; + }else{ +#ifdef SQLITE_ENABLE_STAT4 + tRowcnt nOut = 0; + if( nInMul==0 + && pProbe->nSample + && ALWAYS(pNew->u.btree.nEq<=pProbe->nSampleCol) + && ((eOp & WO_IN)==0 || ExprUseXList(pTerm->pExpr)) + && OptimizationEnabled(db, SQLITE_Stat4) + ){ + Expr *pExpr = pTerm->pExpr; + if( (eOp & (WO_EQ|WO_ISNULL|WO_IS))!=0 ){ + testcase( eOp & WO_EQ ); + testcase( eOp & WO_IS ); + testcase( eOp & WO_ISNULL ); + rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut); + }else{ + rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut); + } + if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; + if( rc!=SQLITE_OK ) break; /* Jump out of the pTerm loop */ + if( nOut ){ + pNew->nOut = sqlite3LogEst(nOut); + if( nEq==1 + /* TUNING: Mark terms as "low selectivity" if they seem likely + ** to be true for half or more of the rows in the table. + ** See tag-202002240-1 */ + && pNew->nOut+10 > pProbe->aiRowLogEst[0] + ){ +#if WHERETRACE_ENABLED /* 0x01 */ + if( sqlite3WhereTrace & 0x20 ){ + sqlite3DebugPrintf( + "STAT4 determines term has low selectivity:\n"); + sqlite3WhereTermPrint(pTerm, 999); + } +#endif + pTerm->wtFlags |= TERM_HIGHTRUTH; + if( pTerm->wtFlags & TERM_HEURTRUTH ){ + /* If the term has previously been used with an assumption of + ** higher selectivity, then set the flag to rerun the + ** loop computations. */ + pBuilder->bldFlags2 |= SQLITE_BLDF2_2NDPASS; + } + } + if( pNew->nOut>saved_nOut ) pNew->nOut = saved_nOut; + pNew->nOut -= nIn; + } + } + if( nOut==0 ) +#endif + { + pNew->nOut += (pProbe->aiRowLogEst[nEq] - pProbe->aiRowLogEst[nEq-1]); + if( eOp & WO_ISNULL ){ + /* TUNING: If there is no likelihood() value, assume that a + ** "col IS NULL" expression matches twice as many rows + ** as (col=?). */ + pNew->nOut += 10; + } + } + } + } + + /* Set rCostIdx to the estimated cost of visiting selected rows in the + ** index. The estimate is the sum of two values: + ** 1. The cost of doing one search-by-key to find the first matching + ** entry + ** 2. Stepping forward in the index pNew->nOut times to find all + ** additional matching entries. + */ + assert( pSrc->pSTab->szTabRow>0 ); + if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){ + /* The pProbe->szIdxRow is low for an IPK table since the interior + ** pages are small. Thus szIdxRow gives a good estimate of seek cost. + ** But the leaf pages are full-size, so pProbe->szIdxRow would badly + ** under-estimate the scanning cost. */ + rCostIdx = pNew->nOut + 16; + }else{ + rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pSTab->szTabRow; + } + rCostIdx = sqlite3LogEstAdd(rLogSize, rCostIdx); + + /* Estimate the cost of running the loop. If all data is coming + ** from the index, then this is just the cost of doing the index + ** lookup and scan. But if some data is coming out of the main table, + ** we also have to add in the cost of doing pNew->nOut searches to + ** locate the row in the main table that corresponds to the index entry. + */ + pNew->rRun = rCostIdx; + if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK|WHERE_EXPRIDX))==0 ){ + pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16); + } + ApplyCostMultiplier(pNew->rRun, pProbe->pTable->costMult); + + nOutUnadjusted = pNew->nOut; + pNew->rRun += nInMul + nIn; + pNew->nOut += nInMul + nIn; + whereLoopOutputAdjust(pBuilder->pWC, pNew, rSize); + if( pSrc->fg.fromExists ) pNew->nOut = 0; + rc = whereLoopInsert(pBuilder, pNew); + + if( pNew->wsFlags & WHERE_COLUMN_RANGE ){ + pNew->nOut = saved_nOut; + }else{ + pNew->nOut = nOutUnadjusted; + } + + if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 + && pNew->u.btree.nEqnColumn + && (pNew->u.btree.nEqnKeyCol || + pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY) + ){ + if( pNew->u.btree.nEq>3 ){ + sqlite3ProgressCheck(pParse); + } + whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn); + } + pNew->nOut = saved_nOut; +#ifdef SQLITE_ENABLE_STAT4 + pBuilder->nRecValid = nRecValid; +#endif + } + pNew->prereq = saved_prereq; + pNew->u.btree.nEq = saved_nEq; + pNew->u.btree.nBtm = saved_nBtm; + pNew->u.btree.nTop = saved_nTop; + pNew->nSkip = saved_nSkip; + pNew->wsFlags = saved_wsFlags; + pNew->nOut = saved_nOut; + pNew->nLTerm = saved_nLTerm; + + /* Consider using a skip-scan if there are no WHERE clause constraints + ** available for the left-most terms of the index, and if the average + ** number of repeats in the left-most terms is at least 18. + ** + ** The magic number 18 is selected on the basis that scanning 17 rows + ** is almost always quicker than an index seek (even though if the index + ** contains fewer than 2^17 rows we assume otherwise in other parts of + ** the code). And, even if it is not, it should not be too much slower. + ** On the other hand, the extra seeks could end up being significantly + ** more expensive. */ + assert( 42==sqlite3LogEst(18) ); + if( saved_nEq==saved_nSkip + && saved_nEq+1nKeyCol + && saved_nEq==pNew->nLTerm + && pProbe->noSkipScan==0 + && pProbe->hasStat1!=0 + && OptimizationEnabled(db, SQLITE_SkipScan) + && pProbe->aiRowLogEst[saved_nEq+1]>=42 /* TUNING: Minimum for skip-scan */ + && pSrc->fg.fromExists==0 + && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK + ){ + LogEst nIter; + pNew->u.btree.nEq++; + pNew->nSkip++; + pNew->aLTerm[pNew->nLTerm++] = 0; + pNew->wsFlags |= WHERE_SKIPSCAN; + nIter = pProbe->aiRowLogEst[saved_nEq] - pProbe->aiRowLogEst[saved_nEq+1]; + pNew->nOut -= nIter; + /* TUNING: Because uncertainties in the estimates for skip-scan queries, + ** add a 1.375 fudge factor to make skip-scan slightly less likely. */ + nIter += 5; + whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter + nInMul); + pNew->nOut = saved_nOut; + pNew->u.btree.nEq = saved_nEq; + pNew->nSkip = saved_nSkip; + pNew->wsFlags = saved_wsFlags; + } + + WHERETRACE(0x800, ("END %s.addBtreeIdx(%s), nEq=%d, rc=%d\n", + pProbe->pTable->zName, pProbe->zName, saved_nEq, rc)); + return rc; +} + +/* +** Return True if it is possible that pIndex might be useful in +** implementing the ORDER BY clause in pBuilder. +** +** Return False if pBuilder does not contain an ORDER BY clause or +** if there is no way for pIndex to be useful in implementing that +** ORDER BY clause. +*/ +static int indexMightHelpWithOrderBy( + WhereLoopBuilder *pBuilder, + Index *pIndex, + int iCursor +){ + ExprList *pOB; + ExprList *aColExpr; + int ii, jj; + + if( pIndex->bUnordered ) return 0; + if( (pOB = pBuilder->pWInfo->pOrderBy)==0 ) return 0; + for(ii=0; iinExpr; ii++){ + Expr *pExpr = sqlite3ExprSkipCollateAndLikely(pOB->a[ii].pExpr); + if( NEVER(pExpr==0) ) continue; + if( (pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN) + && pExpr->iTable==iCursor + ){ + if( pExpr->iColumn<0 ) return 1; + for(jj=0; jjnKeyCol; jj++){ + if( pExpr->iColumn==pIndex->aiColumn[jj] ) return 1; + } + }else if( (aColExpr = pIndex->aColExpr)!=0 ){ + for(jj=0; jjnKeyCol; jj++){ + if( pIndex->aiColumn[jj]!=XN_EXPR ) continue; + if( sqlite3ExprCompareSkip(pExpr,aColExpr->a[jj].pExpr,iCursor)==0 ){ + return 1; + } + } + } + } + return 0; +} + +/* Check to see if a partial index with pPartIndexWhere can be used +** in the current query. Return true if it can be and false if not. +*/ +static int whereUsablePartialIndex( + int iTab, /* The table for which we want an index */ + u8 jointype, /* The JT_* flags on the join */ + WhereClause *pWC, /* The WHERE clause of the query */ + Expr *pWhere /* The WHERE clause from the partial index */ +){ + int i; + WhereTerm *pTerm; + Parse *pParse; + + if( jointype & JT_LTORJ ) return 0; + pParse = pWC->pWInfo->pParse; + while( pWhere->op==TK_AND ){ + if( !whereUsablePartialIndex(iTab,jointype,pWC,pWhere->pLeft) ) return 0; + pWhere = pWhere->pRight; + } + for(i=0, pTerm=pWC->a; inTerm; i++, pTerm++){ + Expr *pExpr; + pExpr = pTerm->pExpr; + if( (!ExprHasProperty(pExpr, EP_OuterON) || pExpr->w.iJoin==iTab) + && ((jointype & JT_OUTER)==0 || ExprHasProperty(pExpr, EP_OuterON)) + && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab) + && !sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, -1) + && (pTerm->wtFlags & TERM_VNULL)==0 + ){ + return 1; + } + } + return 0; +} + +/* +** pIdx is an index containing expressions. Check it see if any of the +** expressions in the index match the pExpr expression. +*/ +static int exprIsCoveredByIndex( + const Expr *pExpr, + const Index *pIdx, + int iTabCur +){ + int i; + for(i=0; inColumn; i++){ + if( pIdx->aiColumn[i]==XN_EXPR + && sqlite3ExprCompare(0, pExpr, pIdx->aColExpr->a[i].pExpr, iTabCur)==0 + ){ + return 1; + } + } + return 0; +} + +/* +** Structure passed to the whereIsCoveringIndex Walker callback. +*/ +typedef struct CoveringIndexCheck CoveringIndexCheck; +struct CoveringIndexCheck { + Index *pIdx; /* The index */ + int iTabCur; /* Cursor number for the corresponding table */ + u8 bExpr; /* Uses an indexed expression */ + u8 bUnidx; /* Uses an unindexed column not within an indexed expr */ +}; + +/* +** Information passed in is pWalk->u.pCovIdxCk. Call it pCk. +** +** If the Expr node references the table with cursor pCk->iTabCur, then +** make sure that column is covered by the index pCk->pIdx. We know that +** all columns less than 63 (really BMS-1) are covered, so we don't need +** to check them. But we do need to check any column at 63 or greater. +** +** If the index does not cover the column, then set pWalk->eCode to +** non-zero and return WRC_Abort to stop the search. +** +** If this node does not disprove that the index can be a covering index, +** then just return WRC_Continue, to continue the search. +** +** If pCk->pIdx contains indexed expressions and one of those expressions +** matches pExpr, then prune the search. +*/ +static int whereIsCoveringIndexWalkCallback(Walker *pWalk, Expr *pExpr){ + int i; /* Loop counter */ + const Index *pIdx; /* The index of interest */ + const i16 *aiColumn; /* Columns contained in the index */ + u16 nColumn; /* Number of columns in the index */ + CoveringIndexCheck *pCk; /* Info about this search */ + + pCk = pWalk->u.pCovIdxCk; + pIdx = pCk->pIdx; + if( (pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN) ){ + /* if( pExpr->iColumn<(BMS-1) && pIdx->bHasExpr==0 ) return WRC_Continue;*/ + if( pExpr->iTable!=pCk->iTabCur ) return WRC_Continue; + pIdx = pWalk->u.pCovIdxCk->pIdx; + aiColumn = pIdx->aiColumn; + nColumn = pIdx->nColumn; + for(i=0; iiColumn ) return WRC_Continue; + } + pCk->bUnidx = 1; + return WRC_Abort; + }else if( pIdx->bHasExpr + && exprIsCoveredByIndex(pExpr, pIdx, pWalk->u.pCovIdxCk->iTabCur) ){ + pCk->bExpr = 1; + return WRC_Prune; + } + return WRC_Continue; +} + + +/* +** pIdx is an index that covers all of the low-number columns used by +** pWInfo->pSelect (columns from 0 through 62) or an index that has +** expressions terms. Hence, we cannot determine whether or not it is +** a covering index by using the colUsed bitmasks. We have to do a search +** to see if the index is covering. This routine does that search. +** +** The return value is one of these: +** +** 0 The index is definitely not a covering index +** +** WHERE_IDX_ONLY The index is definitely a covering index +** +** WHERE_EXPRIDX The index is likely a covering index, but it is +** difficult to determine precisely because of the +** expressions that are indexed. Score it as a +** covering index, but still keep the main table open +** just in case we need it. +** +** This routine is an optimization. It is always safe to return zero. +** But returning one of the other two values when zero should have been +** returned can lead to incorrect bytecode and assertion faults. +*/ +static SQLITE_NOINLINE u32 whereIsCoveringIndex( + WhereInfo *pWInfo, /* The WHERE clause context */ + Index *pIdx, /* Index that is being tested */ + int iTabCur /* Cursor for the table being indexed */ +){ + int i, rc; + struct CoveringIndexCheck ck; + Walker w; + if( pWInfo->pSelect==0 ){ + /* We don't have access to the full query, so we cannot check to see + ** if pIdx is covering. Assume it is not. */ + return 0; + } + if( pIdx->bHasExpr==0 ){ + for(i=0; inColumn; i++){ + if( pIdx->aiColumn[i]>=BMS-1 ) break; + } + if( i>=pIdx->nColumn ){ + /* pIdx does not index any columns greater than 62, but we know from + ** colMask that columns greater than 62 are used, so this is not a + ** covering index */ + return 0; + } + } + ck.pIdx = pIdx; + ck.iTabCur = iTabCur; + ck.bExpr = 0; + ck.bUnidx = 0; + memset(&w, 0, sizeof(w)); + w.xExprCallback = whereIsCoveringIndexWalkCallback; + w.xSelectCallback = sqlite3SelectWalkNoop; + w.u.pCovIdxCk = &ck; + sqlite3WalkSelect(&w, pWInfo->pSelect); + if( ck.bUnidx ){ + rc = 0; + }else if( ck.bExpr ){ + rc = WHERE_EXPRIDX; + }else{ + rc = WHERE_IDX_ONLY; + } + return rc; +} + +/* +** This is an sqlite3ParserAddCleanup() callback that is invoked to +** free the Parse->pIdxEpr list when the Parse object is destroyed. +*/ +static void whereIndexedExprCleanup(sqlite3 *db, void *pObject){ + IndexedExpr **pp = (IndexedExpr**)pObject; + while( *pp!=0 ){ + IndexedExpr *p = *pp; + *pp = p->pIENext; + sqlite3ExprDelete(db, p->pExpr); + sqlite3DbFreeNN(db, p); + } +} + +/* +** This function is called for a partial index - one with a WHERE clause - in +** two scenarios. In both cases, it determines whether or not the WHERE +** clause on the index implies that a column of the table may be safely +** replaced by a constant expression. For example, in the following +** SELECT: +** +** CREATE INDEX i1 ON t1(b, c) WHERE a=; +** SELECT a, b, c FROM t1 WHERE a= AND b=?; +** +** The "a" in the select-list may be replaced by , iff: +** +** (a) is a constant expression, and +** (b) The (a=) comparison uses the BINARY collation sequence, and +** (c) Column "a" has an affinity other than NONE or BLOB. +** +** If argument pItem is NULL, then pMask must not be NULL. In this case this +** function is being called as part of determining whether or not pIdx +** is a covering index. This function clears any bits in (*pMask) +** corresponding to columns that may be replaced by constants as described +** above. +** +** Otherwise, if pItem is not NULL, then this function is being called +** as part of coding a loop that uses index pIdx. In this case, add entries +** to the Parse.pIdxPartExpr list for each column that can be replaced +** by a constant. +*/ +static void wherePartIdxExpr( + Parse *pParse, /* Parse context */ + Index *pIdx, /* Partial index being processed */ + Expr *pPart, /* WHERE clause being processed */ + Bitmask *pMask, /* Mask to clear bits in */ + int iIdxCur, /* Cursor number for index */ + SrcItem *pItem /* The FROM clause entry for the table */ +){ + assert( pItem==0 || (pItem->fg.jointype & JT_RIGHT)==0 ); + assert( (pItem==0 || pMask==0) && (pMask!=0 || pItem!=0) ); + + if( pPart->op==TK_AND ){ + wherePartIdxExpr(pParse, pIdx, pPart->pRight, pMask, iIdxCur, pItem); + pPart = pPart->pLeft; + } + + if( (pPart->op==TK_EQ || pPart->op==TK_IS) ){ + Expr *pLeft = pPart->pLeft; + Expr *pRight = pPart->pRight; + u8 aff; + + if( pLeft->op!=TK_COLUMN ) return; + if( !sqlite3ExprIsConstant(0, pRight) ) return; + if( !sqlite3IsBinary(sqlite3ExprCompareCollSeq(pParse, pPart)) ) return; + if( pLeft->iColumn<0 ) return; + aff = pIdx->pTable->aCol[pLeft->iColumn].affinity; + if( aff>=SQLITE_AFF_TEXT ){ + if( pItem ){ + sqlite3 *db = pParse->db; + IndexedExpr *p = (IndexedExpr*)sqlite3DbMallocRaw(db, sizeof(*p)); + if( p ){ + int bNullRow = (pItem->fg.jointype&(JT_LEFT|JT_LTORJ))!=0; + p->pExpr = sqlite3ExprDup(db, pRight, 0); + p->iDataCur = pItem->iCursor; + p->iIdxCur = iIdxCur; + p->iIdxCol = pLeft->iColumn; + p->bMaybeNullRow = bNullRow; + p->pIENext = pParse->pIdxPartExpr; + p->aff = aff; + pParse->pIdxPartExpr = p; + if( p->pIENext==0 ){ + void *pArg = (void*)&pParse->pIdxPartExpr; + sqlite3ParserAddCleanup(pParse, whereIndexedExprCleanup, pArg); + } + } + }else if( pLeft->iColumn<(BMS-1) ){ + *pMask &= ~((Bitmask)1 << pLeft->iColumn); + } + } + } +} + + +/* +** Add all WhereLoop objects for a single table of the join where the table +** is identified by pBuilder->pNew->iTab. That table is guaranteed to be +** a b-tree table, not a virtual table. +** +** The costs (WhereLoop.rRun) of the b-tree loops added by this function +** are calculated as follows: +** +** For a full scan, assuming the table (or index) contains nRow rows: +** +** cost = nRow * 3.0 // full-table scan +** cost = nRow * K // scan of covering index +** cost = nRow * (K+3.0) // scan of non-covering index +** +** where K is a value between 1.1 and 3.0 set based on the relative +** estimated average size of the index and table records. +** +** For an index scan, where nVisit is the number of index rows visited +** by the scan, and nSeek is the number of seek operations required on +** the index b-tree: +** +** cost = nSeek * (log(nRow) + K * nVisit) // covering index +** cost = nSeek * (log(nRow) + (K+3.0) * nVisit) // non-covering index +** +** Normally, nSeek is 1. nSeek values greater than 1 come about if the +** WHERE clause includes "x IN (....)" terms used in place of "x=?". Or when +** implicit "x IN (SELECT x FROM tbl)" terms are added for skip-scans. +** +** The estimated values (nRow, nVisit, nSeek) often contain a large amount +** of uncertainty. For this reason, scoring is designed to pick plans that +** "do the least harm" if the estimates are inaccurate. For example, a +** log(nRow) factor is omitted from a non-covering index scan in order to +** bias the scoring in favor of using an index, since the worst-case +** performance of using an index is far better than the worst-case performance +** of a full table scan. +*/ +static int whereLoopAddBtree( + WhereLoopBuilder *pBuilder, /* WHERE clause information */ + Bitmask mPrereq /* Extra prerequisites for using this table */ +){ + WhereInfo *pWInfo; /* WHERE analysis context */ + Index *pProbe; /* An index we are evaluating */ + Index sPk; /* A fake index object for the primary key */ + LogEst aiRowEstPk[2]; /* The aiRowLogEst[] value for the sPk index */ + i16 aiColumnPk = -1; /* The aColumn[] value for the sPk index */ + SrcList *pTabList; /* The FROM clause */ + SrcItem *pSrc; /* The FROM clause btree term to add */ + WhereLoop *pNew; /* Template WhereLoop object */ + int rc = SQLITE_OK; /* Return code */ + int iSortIdx = 1; /* Index number */ + int b; /* A boolean value */ + LogEst rSize; /* number of rows in the table */ + WhereClause *pWC; /* The parsed WHERE clause */ + Table *pTab; /* Table being queried */ + + pNew = pBuilder->pNew; + pWInfo = pBuilder->pWInfo; + pTabList = pWInfo->pTabList; + pSrc = pTabList->a + pNew->iTab; + pTab = pSrc->pSTab; + pWC = pBuilder->pWC; + assert( !IsVirtual(pSrc->pSTab) ); + + if( pSrc->fg.isIndexedBy ){ + assert( pSrc->fg.isCte==0 ); + /* An INDEXED BY clause specifies a particular index to use */ + pProbe = pSrc->u2.pIBIndex; + }else if( !HasRowid(pTab) ){ + pProbe = pTab->pIndex; + }else{ + /* There is no INDEXED BY clause. Create a fake Index object in local + ** variable sPk to represent the rowid primary key index. Make this + ** fake index the first in a chain of Index objects with all of the real + ** indices to follow */ + Index *pFirst; /* First of real indices on the table */ + memset(&sPk, 0, sizeof(Index)); + sPk.nKeyCol = 1; + sPk.nColumn = 1; + sPk.aiColumn = &aiColumnPk; + sPk.aiRowLogEst = aiRowEstPk; + sPk.onError = OE_Replace; + sPk.pTable = pTab; + sPk.szIdxRow = 3; /* TUNING: Interior rows of IPK table are very small */ + sPk.idxType = SQLITE_IDXTYPE_IPK; + aiRowEstPk[0] = pTab->nRowLogEst; + aiRowEstPk[1] = 0; + pFirst = pSrc->pSTab->pIndex; + if( pSrc->fg.notIndexed==0 ){ + /* The real indices of the table are only considered if the + ** NOT INDEXED qualifier is omitted from the FROM clause */ + sPk.pNext = pFirst; + } + pProbe = &sPk; + } + rSize = pTab->nRowLogEst; + +#ifndef SQLITE_OMIT_AUTOMATIC_INDEX + /* Automatic indexes */ + if( !pBuilder->pOrSet /* Not part of an OR optimization */ + && (pWInfo->wctrlFlags & (WHERE_RIGHT_JOIN|WHERE_OR_SUBCLAUSE))==0 + && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0 + && !pSrc->fg.isIndexedBy /* Has no INDEXED BY clause */ + && !pSrc->fg.notIndexed /* Has no NOT INDEXED clause */ + && !pSrc->fg.isCorrelated /* Not a correlated subquery */ + && !pSrc->fg.isRecursive /* Not a recursive common table expression. */ + && (pSrc->fg.jointype & JT_RIGHT)==0 /* Not the right tab of a RIGHT JOIN */ + ){ + /* Generate auto-index WhereLoops */ + LogEst rLogSize; /* Logarithm of the number of rows in the table */ + WhereTerm *pTerm; + WhereTerm *pWCEnd = pWC->a + pWC->nTerm; + rLogSize = estLog(rSize); + for(pTerm=pWC->a; rc==SQLITE_OK && pTermprereqRight & pNew->maskSelf ) continue; + if( termCanDriveIndex(pTerm, pSrc, 0) ){ + pNew->u.btree.nEq = 1; + pNew->nSkip = 0; + pNew->u.btree.pIndex = 0; + pNew->nLTerm = 1; + pNew->aLTerm[0] = pTerm; + /* TUNING: One-time cost for computing the automatic index is + ** estimated to be X*N*log2(N) where N is the number of rows in + ** the table being indexed and where X is 7 (LogEst=28) for normal + ** tables or 0.5 (LogEst=-10) for views and subqueries. The value + ** of X is smaller for views and subqueries so that the query planner + ** will be more aggressive about generating automatic indexes for + ** those objects, since there is no opportunity to add schema + ** indexes on subqueries and views. */ + pNew->rSetup = rLogSize + rSize; + if( !IsView(pTab) && (pTab->tabFlags & TF_Ephemeral)==0 ){ + pNew->rSetup += 28; + }else{ + pNew->rSetup -= 25; /* Greatly reduced setup cost for auto indexes + ** on ephemeral materializations of views */ + } + ApplyCostMultiplier(pNew->rSetup, pTab->costMult); + if( pNew->rSetup<0 ) pNew->rSetup = 0; + /* TUNING: Each index lookup yields 20 rows in the table. This + ** is more than the usual guess of 10 rows, since we have no way + ** of knowing how selective the index will ultimately be. It would + ** not be unreasonable to make this value much larger. */ + pNew->nOut = 43; assert( 43==sqlite3LogEst(20) ); + pNew->rRun = sqlite3LogEstAdd(rLogSize,pNew->nOut); + pNew->wsFlags = WHERE_AUTO_INDEX; + pNew->prereq = mPrereq | pTerm->prereqRight; + rc = whereLoopInsert(pBuilder, pNew); + } + } + } +#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ + + /* Loop over all indices. If there was an INDEXED BY clause, then only + ** consider index pProbe. */ + for(; rc==SQLITE_OK && pProbe; + pProbe=(pSrc->fg.isIndexedBy ? 0 : pProbe->pNext), iSortIdx++ + ){ + if( pProbe->pPartIdxWhere!=0 + && !whereUsablePartialIndex(pSrc->iCursor, pSrc->fg.jointype, pWC, + pProbe->pPartIdxWhere) + ){ + testcase( pNew->iTab!=pSrc->iCursor ); /* See ticket [98d973b8f5] */ + continue; /* Partial index inappropriate for this query */ + } + if( pProbe->bNoQuery ) continue; + rSize = pProbe->aiRowLogEst[0]; + pNew->u.btree.nEq = 0; + pNew->u.btree.nBtm = 0; + pNew->u.btree.nTop = 0; + pNew->u.btree.nDistinctCol = 0; + pNew->nSkip = 0; + pNew->nLTerm = 0; + pNew->iSortIdx = 0; + pNew->rSetup = 0; + pNew->prereq = mPrereq; + pNew->nOut = rSize; + pNew->u.btree.pIndex = pProbe; + pNew->u.btree.pOrderBy = 0; + b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor); + + /* The ONEPASS_DESIRED flags never occurs together with ORDER BY */ + assert( (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || b==0 ); + if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){ + /* Integer primary key index */ + pNew->wsFlags = WHERE_IPK; + + /* Full table scan */ + pNew->iSortIdx = b ? iSortIdx : 0; + /* TUNING: Cost of full table scan is 3.0*N. The 3.0 factor is an + ** extra cost designed to discourage the use of full table scans, + ** since index lookups have better worst-case performance if our + ** stat guesses are wrong. Reduce the 3.0 penalty slightly + ** (to 2.75) if we have valid STAT4 information for the table. + ** At 2.75, a full table scan is preferred over using an index on + ** a column with just two distinct values where each value has about + ** an equal number of appearances. Without STAT4 data, we still want + ** to use an index in that case, since the constraint might be for + ** the scarcer of the two values, and in that case an index lookup is + ** better. + */ +#ifdef SQLITE_ENABLE_STAT4 + pNew->rRun = rSize + 16 - 2*((pTab->tabFlags & TF_HasStat4)!=0); +#else + pNew->rRun = rSize + 16; +#endif + ApplyCostMultiplier(pNew->rRun, pTab->costMult); + whereLoopOutputAdjust(pWC, pNew, rSize); + if( pSrc->fg.isSubquery ){ + if( pSrc->fg.viaCoroutine ) pNew->wsFlags |= WHERE_COROUTINE; + /* Do not set btree.pOrderBy for a recursive CTE. In this case + ** the ORDER BY clause does not determine the overall order that + ** rows are emitted from the CTE in. */ + if( (pSrc->u4.pSubq->pSelect->selFlags & SF_Recursive)==0 ){ + pNew->u.btree.pOrderBy = pSrc->u4.pSubq->pSelect->pOrderBy; + } + }else if( pSrc->fg.fromExists ){ + pNew->nOut = 0; + } + rc = whereLoopInsert(pBuilder, pNew); + pNew->nOut = rSize; + if( rc ) break; + }else{ + Bitmask m; + if( pProbe->isCovering ){ + m = 0; + pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED; + }else{ + m = pSrc->colUsed & pProbe->colNotIdxed; + if( pProbe->pPartIdxWhere ){ + wherePartIdxExpr( + pWInfo->pParse, pProbe, pProbe->pPartIdxWhere, &m, 0, 0 + ); + } + pNew->wsFlags = WHERE_INDEXED; + if( m==TOPBIT || (pProbe->bHasExpr && !pProbe->bHasVCol && m!=0) ){ + u32 isCov = whereIsCoveringIndex(pWInfo, pProbe, pSrc->iCursor); + if( isCov==0 ){ + WHERETRACE(0x200, + ("-> %s is not a covering index" + " according to whereIsCoveringIndex()\n", pProbe->zName)); + assert( m!=0 ); + }else{ + m = 0; + pNew->wsFlags |= isCov; + if( isCov & WHERE_IDX_ONLY ){ + WHERETRACE(0x200, + ("-> %s is a covering expression index" + " according to whereIsCoveringIndex()\n", pProbe->zName)); + }else{ + assert( isCov==WHERE_EXPRIDX ); + WHERETRACE(0x200, + ("-> %s might be a covering expression index" + " according to whereIsCoveringIndex()\n", pProbe->zName)); + } + } + }else if( m==0 + && (HasRowid(pTab) || pWInfo->pSelect!=0 || sqlite3FaultSim(700)) + ){ + WHERETRACE(0x200, + ("-> %s is a covering index according to bitmasks\n", + pProbe->zName, m==0 ? "is" : "is not")); + pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED; + } + } + + /* Full scan via index */ + if( b + || !HasRowid(pTab) + || pProbe->pPartIdxWhere!=0 + || pSrc->fg.isIndexedBy + || ( m==0 + && pProbe->bUnordered==0 + && (pProbe->szIdxRowszTabRow) + && (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 + && sqlite3GlobalConfig.bUseCis + && OptimizationEnabled(pWInfo->pParse->db, SQLITE_CoverIdxScan) + ) + ){ + pNew->iSortIdx = b ? iSortIdx : 0; + + /* The cost of visiting the index rows is N*K, where K is + ** between 1.1 and 3.0, depending on the relative sizes of the + ** index and table rows. */ + pNew->rRun = rSize + 1 + (15*pProbe->szIdxRow)/pTab->szTabRow; + if( m!=0 ){ + /* If this is a non-covering index scan, add in the cost of + ** doing table lookups. The cost will be 3x the number of + ** lookups. Take into account WHERE clause terms that can be + ** satisfied using just the index, and that do not require a + ** table lookup. */ + LogEst nLookup = rSize + 16; /* Base cost: N*3 */ + int ii; + int iCur = pSrc->iCursor; + WhereClause *pWC2 = &pWInfo->sWC; + for(ii=0; iinTerm; ii++){ + WhereTerm *pTerm = &pWC2->a[ii]; + if( !sqlite3ExprCoveredByIndex(pTerm->pExpr, iCur, pProbe) ){ + break; + } + /* pTerm can be evaluated using just the index. So reduce + ** the expected number of table lookups accordingly */ + if( pTerm->truthProb<=0 ){ + nLookup += pTerm->truthProb; + }else{ + nLookup--; + if( pTerm->eOperator & (WO_EQ|WO_IS) ) nLookup -= 19; + } + } + + pNew->rRun = sqlite3LogEstAdd(pNew->rRun, nLookup); + } + ApplyCostMultiplier(pNew->rRun, pTab->costMult); + whereLoopOutputAdjust(pWC, pNew, rSize); + if( (pSrc->fg.jointype & JT_RIGHT)!=0 && pProbe->aColExpr ){ + /* Do not do an SCAN of a index-on-expression in a RIGHT JOIN + ** because the cursor used to access the index might not be + ** positioned to the correct row during the right-join no-match + ** loop. */ + }else{ + if( pSrc->fg.fromExists ) pNew->nOut = 0; + rc = whereLoopInsert(pBuilder, pNew); + } + pNew->nOut = rSize; + if( rc ) break; + } + } + + pBuilder->bldFlags1 = 0; + rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0); + if( pBuilder->bldFlags1==SQLITE_BLDF1_INDEXED ){ + /* If a non-unique index is used, or if a prefix of the key for + ** unique index is used (making the index functionally non-unique) + ** then the sqlite_stat1 data becomes important for scoring the + ** plan */ + pTab->tabFlags |= TF_MaybeReanalyze; + } +#ifdef SQLITE_ENABLE_STAT4 + sqlite3Stat4ProbeFree(pBuilder->pRec); + pBuilder->nRecValid = 0; + pBuilder->pRec = 0; +#endif + } + return rc; +} + +#ifndef SQLITE_OMIT_VIRTUALTABLE + +/* +** Return true if pTerm is a virtual table LIMIT or OFFSET term. +*/ +static int isLimitTerm(WhereTerm *pTerm){ + assert( pTerm->eOperator==WO_AUX || pTerm->eMatchOp==0 ); + return pTerm->eMatchOp>=SQLITE_INDEX_CONSTRAINT_LIMIT + && pTerm->eMatchOp<=SQLITE_INDEX_CONSTRAINT_OFFSET; +} + +/* +** Return true if the first nCons constraints in the pUsage array are +** marked as in-use (have argvIndex>0). False otherwise. +*/ +static int allConstraintsUsed( + struct sqlite3_index_constraint_usage *aUsage, + int nCons +){ + int ii; + for(ii=0; iipNew->iTab. This +** function marks a subset of those constraints usable, invokes the +** xBestIndex method and adds the returned plan to pBuilder. +** +** A constraint is marked usable if: +** +** * Argument mUsable indicates that its prerequisites are available, and +** +** * It is not one of the operators specified in the mExclude mask passed +** as the fourth argument (which in practice is either WO_IN or 0). +** +** Argument mPrereq is a mask of tables that must be scanned before the +** virtual table in question. These are added to the plans prerequisites +** before it is added to pBuilder. +** +** Output parameter *pbIn is set to true if the plan added to pBuilder +** uses one or more WO_IN terms, or false otherwise. +*/ +static int whereLoopAddVirtualOne( + WhereLoopBuilder *pBuilder, + Bitmask mPrereq, /* Mask of tables that must be used. */ + Bitmask mUsable, /* Mask of usable tables */ + u16 mExclude, /* Exclude terms using these operators */ + sqlite3_index_info *pIdxInfo, /* Populated object for xBestIndex */ + u16 mNoOmit, /* Do not omit these constraints */ + int *pbIn, /* OUT: True if plan uses an IN(...) op */ + int *pbRetryLimit /* OUT: Retry without LIMIT/OFFSET */ +){ + WhereClause *pWC = pBuilder->pWC; + HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; + struct sqlite3_index_constraint *pIdxCons; + struct sqlite3_index_constraint_usage *pUsage = pIdxInfo->aConstraintUsage; + int i; + int mxTerm; + int rc = SQLITE_OK; + WhereLoop *pNew = pBuilder->pNew; + Parse *pParse = pBuilder->pWInfo->pParse; + SrcItem *pSrc = &pBuilder->pWInfo->pTabList->a[pNew->iTab]; + int nConstraint = pIdxInfo->nConstraint; + + assert( (mUsable & mPrereq)==mPrereq ); + *pbIn = 0; + pNew->prereq = mPrereq; + + /* Set the usable flag on the subset of constraints identified by + ** arguments mUsable and mExclude. */ + pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; + for(i=0; iiTermOffset); + pIdxCons->usable = 0; + if( (pTerm->prereqRight & mUsable)==pTerm->prereqRight + && (pTerm->eOperator & mExclude)==0 + && (pbRetryLimit || !isLimitTerm(pTerm)) + ){ + pIdxCons->usable = 1; + } + } + + /* Initialize the output fields of the sqlite3_index_info structure */ + memset(pUsage, 0, sizeof(pUsage[0])*nConstraint); + assert( pIdxInfo->needToFreeIdxStr==0 ); + pIdxInfo->idxStr = 0; + pIdxInfo->idxNum = 0; + pIdxInfo->orderByConsumed = 0; + pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2; + pIdxInfo->estimatedRows = 25; + pIdxInfo->idxFlags = 0; + pHidden->mHandleIn = 0; + + /* Invoke the virtual table xBestIndex() method */ + rc = vtabBestIndex(pParse, pSrc->pSTab, pIdxInfo); + if( rc ){ + if( rc==SQLITE_CONSTRAINT ){ + /* If the xBestIndex method returns SQLITE_CONSTRAINT, that means + ** that the particular combination of parameters provided is unusable. + ** Make no entries in the loop table. + */ + WHERETRACE(0xffffffff, (" ^^^^--- non-viable plan rejected!\n")); + freeIdxStr(pIdxInfo); + return SQLITE_OK; + } + return rc; + } + + mxTerm = -1; + assert( pNew->nLSlot>=nConstraint ); + memset(pNew->aLTerm, 0, sizeof(pNew->aLTerm[0])*nConstraint ); + memset(&pNew->u.vtab, 0, sizeof(pNew->u.vtab)); + pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; + for(i=0; i=0 ){ + WhereTerm *pTerm; + int j = pIdxCons->iTermOffset; + if( iTerm>=nConstraint + || j<0 + || (pTerm = termFromWhereClause(pWC, j))==0 + || pNew->aLTerm[iTerm]!=0 + || pIdxCons->usable==0 + ){ + sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pSTab->zName); + freeIdxStr(pIdxInfo); + return SQLITE_ERROR; + } + testcase( iTerm==nConstraint-1 ); + testcase( j==0 ); + testcase( j==pWC->nTerm-1 ); + pNew->prereq |= pTerm->prereqRight; + assert( iTermnLSlot ); + pNew->aLTerm[iTerm] = pTerm; + if( iTerm>mxTerm ) mxTerm = iTerm; + testcase( iTerm==15 ); + testcase( iTerm==16 ); + if( pUsage[i].omit ){ + if( i<16 && ((1<u.vtab.omitMask |= 1<eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET ){ + pNew->u.vtab.bOmitOffset = 1; + } + } + if( SMASKBIT32(i) & pHidden->mHandleIn ){ + pNew->u.vtab.mHandleIn |= MASKBIT32(iTerm); + }else if( (pTerm->eOperator & WO_IN)!=0 ){ + /* A virtual table that is constrained by an IN clause may not + ** consume the ORDER BY clause because (1) the order of IN terms + ** is not necessarily related to the order of output terms and + ** (2) Multiple outputs from a single IN value will not merge + ** together. */ + pIdxInfo->orderByConsumed = 0; + pIdxInfo->idxFlags &= ~SQLITE_INDEX_SCAN_UNIQUE; + *pbIn = 1; assert( (mExclude & WO_IN)==0 ); + } + + /* Unless pbRetryLimit is non-NULL, there should be no LIMIT/OFFSET + ** terms. And if there are any, they should follow all other terms. */ + assert( pbRetryLimit || !isLimitTerm(pTerm) ); + assert( !isLimitTerm(pTerm) || i>=nConstraint-2 ); + assert( !isLimitTerm(pTerm) || i==nConstraint-1 || isLimitTerm(pTerm+1) ); + + if( isLimitTerm(pTerm) && (*pbIn || !allConstraintsUsed(pUsage, i)) ){ + /* If there is an IN(...) term handled as an == (separate call to + ** xFilter for each value on the RHS of the IN) and a LIMIT or + ** OFFSET term handled as well, the plan is unusable. Similarly, + ** if there is a LIMIT/OFFSET and there are other unused terms, + ** the plan cannot be used. In these cases set variable *pbRetryLimit + ** to true to tell the caller to retry with LIMIT and OFFSET + ** disabled. */ + freeIdxStr(pIdxInfo); + *pbRetryLimit = 1; + return SQLITE_OK; + } + } + } + + pNew->nLTerm = mxTerm+1; + for(i=0; i<=mxTerm; i++){ + if( pNew->aLTerm[i]==0 ){ + /* The non-zero argvIdx values must be contiguous. Raise an + ** error if they are not */ + sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pSTab->zName); + freeIdxStr(pIdxInfo); + return SQLITE_ERROR; + } + } + assert( pNew->nLTerm<=pNew->nLSlot ); + pNew->u.vtab.idxNum = pIdxInfo->idxNum; + pNew->u.vtab.needFree = pIdxInfo->needToFreeIdxStr; + pIdxInfo->needToFreeIdxStr = 0; + pNew->u.vtab.idxStr = pIdxInfo->idxStr; + pNew->u.vtab.isOrdered = (i8)(pIdxInfo->orderByConsumed ? + pIdxInfo->nOrderBy : 0); + pNew->u.vtab.bIdxNumHex = (pIdxInfo->idxFlags&SQLITE_INDEX_SCAN_HEX)!=0; + pNew->rSetup = 0; + pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost); + pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows); + + /* Set the WHERE_ONEROW flag if the xBestIndex() method indicated + ** that the scan will visit at most one row. Clear it otherwise. */ + if( pIdxInfo->idxFlags & SQLITE_INDEX_SCAN_UNIQUE ){ + pNew->wsFlags |= WHERE_ONEROW; + }else{ + pNew->wsFlags &= ~WHERE_ONEROW; + } + rc = whereLoopInsert(pBuilder, pNew); + if( pNew->u.vtab.needFree ){ + sqlite3_free(pNew->u.vtab.idxStr); + pNew->u.vtab.needFree = 0; + } + WHERETRACE(0xffffffff, (" bIn=%d prereqIn=%04llx prereqOut=%04llx\n", + *pbIn, (sqlite3_uint64)mPrereq, + (sqlite3_uint64)(pNew->prereq & ~mPrereq))); + + return rc; +} + +/* +** Return the collating sequence for a constraint passed into xBestIndex. +** +** pIdxInfo must be an sqlite3_index_info structure passed into xBestIndex. +** This routine depends on there being a HiddenIndexInfo structure immediately +** following the sqlite3_index_info structure. +** +** Return a pointer to the collation name: +** +** 1. If there is an explicit COLLATE operator on the constraint, return it. +** +** 2. Else, if the column has an alternative collation, return that. +** +** 3. Otherwise, return "BINARY". +*/ +SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int iCons){ + HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; + const char *zRet = 0; + if( iCons>=0 && iConsnConstraint ){ + CollSeq *pC = 0; + int iTerm = pIdxInfo->aConstraint[iCons].iTermOffset; + Expr *pX = termFromWhereClause(pHidden->pWC, iTerm)->pExpr; + if( pX->pLeft ){ + pC = sqlite3ExprCompareCollSeq(pHidden->pParse, pX); + } + zRet = (pC ? pC->zName : sqlite3StrBINARY); + } + return zRet; +} + +/* +** Return true if constraint iCons is really an IN(...) constraint, or +** false otherwise. If iCons is an IN(...) constraint, set (if bHandle!=0) +** or clear (if bHandle==0) the flag to handle it using an iterator. +*/ +SQLITE_API int sqlite3_vtab_in(sqlite3_index_info *pIdxInfo, int iCons, int bHandle){ + HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; + u32 m = SMASKBIT32(iCons); + if( m & pHidden->mIn ){ + if( bHandle==0 ){ + pHidden->mHandleIn &= ~m; + }else if( bHandle>0 ){ + pHidden->mHandleIn |= m; + } + return 1; + } + return 0; +} + +/* +** This interface is callable from within the xBestIndex callback only. +** +** If possible, set (*ppVal) to point to an object containing the value +** on the right-hand-side of constraint iCons. +*/ +SQLITE_API int sqlite3_vtab_rhs_value( + sqlite3_index_info *pIdxInfo, /* Copy of first argument to xBestIndex */ + int iCons, /* Constraint for which RHS is wanted */ + sqlite3_value **ppVal /* Write value extracted here */ +){ + HiddenIndexInfo *pH = (HiddenIndexInfo*)&pIdxInfo[1]; + sqlite3_value *pVal = 0; + int rc = SQLITE_OK; + if( iCons<0 || iCons>=pIdxInfo->nConstraint ){ + rc = SQLITE_MISUSE_BKPT; /* EV: R-30545-25046 */ + }else{ + if( pH->aRhs[iCons]==0 ){ + WhereTerm *pTerm = termFromWhereClause( + pH->pWC, pIdxInfo->aConstraint[iCons].iTermOffset + ); + rc = sqlite3ValueFromExpr( + pH->pParse->db, pTerm->pExpr->pRight, ENC(pH->pParse->db), + SQLITE_AFF_BLOB, &pH->aRhs[iCons] + ); + testcase( rc!=SQLITE_OK ); + } + pVal = pH->aRhs[iCons]; + } + *ppVal = pVal; + + if( rc==SQLITE_OK && pVal==0 ){ /* IMP: R-19933-32160 */ + rc = SQLITE_NOTFOUND; /* IMP: R-36424-56542 */ + } + + return rc; +} + +/* +** Return true if ORDER BY clause may be handled as DISTINCT. +*/ +SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info *pIdxInfo){ + HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; + assert( pHidden->eDistinct>=0 && pHidden->eDistinct<=3 ); + return pHidden->eDistinct; +} + +/* +** Cause the prepared statement that is associated with a call to +** xBestIndex to potentially use all schemas. If the statement being +** prepared is read-only, then just start read transactions on all +** schemas. But if this is a write operation, start writes on all +** schemas. +** +** This is used by the (built-in) sqlite_dbpage virtual table. +*/ +SQLITE_PRIVATE void sqlite3VtabUsesAllSchemas(Parse *pParse){ + int nDb = pParse->db->nDb; + int i; + for(i=0; iwriteMask) ){ + for(i=0; ipNew->iTab. That table is guaranteed to be a virtual table. +** +** If there are no LEFT or CROSS JOIN joins in the query, both mPrereq and +** mUnusable are set to 0. Otherwise, mPrereq is a mask of all FROM clause +** entries that occur before the virtual table in the FROM clause and are +** separated from it by at least one LEFT or CROSS JOIN. Similarly, the +** mUnusable mask contains all FROM clause entries that occur after the +** virtual table and are separated from it by at least one LEFT or +** CROSS JOIN. +** +** For example, if the query were: +** +** ... FROM t1, t2 LEFT JOIN t3, t4, vt CROSS JOIN t5, t6; +** +** then mPrereq corresponds to (t1, t2) and mUnusable to (t5, t6). +** +** All the tables in mPrereq must be scanned before the current virtual +** table. So any terms for which all prerequisites are satisfied by +** mPrereq may be specified as "usable" in all calls to xBestIndex. +** Conversely, all tables in mUnusable must be scanned after the current +** virtual table, so any terms for which the prerequisites overlap with +** mUnusable should always be configured as "not-usable" for xBestIndex. +*/ +static int whereLoopAddVirtual( + WhereLoopBuilder *pBuilder, /* WHERE clause information */ + Bitmask mPrereq, /* Tables that must be scanned before this one */ + Bitmask mUnusable /* Tables that must be scanned after this one */ +){ + int rc = SQLITE_OK; /* Return code */ + WhereInfo *pWInfo; /* WHERE analysis context */ + Parse *pParse; /* The parsing context */ + WhereClause *pWC; /* The WHERE clause */ + SrcItem *pSrc; /* The FROM clause term to search */ + sqlite3_index_info *p; /* Object to pass to xBestIndex() */ + int nConstraint; /* Number of constraints in p */ + int bIn; /* True if plan uses IN(...) operator */ + WhereLoop *pNew; + Bitmask mBest; /* Tables used by best possible plan */ + u16 mNoOmit; + int bRetry = 0; /* True to retry with LIMIT/OFFSET disabled */ + + assert( (mPrereq & mUnusable)==0 ); + pWInfo = pBuilder->pWInfo; + pParse = pWInfo->pParse; + pWC = pBuilder->pWC; + pNew = pBuilder->pNew; + pSrc = &pWInfo->pTabList->a[pNew->iTab]; + assert( IsVirtual(pSrc->pSTab) ); + p = allocateIndexInfo(pWInfo, pWC, mUnusable, pSrc, &mNoOmit); + if( p==0 ) return SQLITE_NOMEM_BKPT; + pNew->rSetup = 0; + pNew->wsFlags = WHERE_VIRTUALTABLE; + pNew->nLTerm = 0; + pNew->u.vtab.needFree = 0; + nConstraint = p->nConstraint; + if( whereLoopResize(pParse->db, pNew, nConstraint) ){ + freeIndexInfo(pParse->db, p); + return SQLITE_NOMEM_BKPT; + } + + /* First call xBestIndex() with all constraints usable. */ + WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pSTab->zName)); + WHERETRACE(0x800, (" VirtualOne: all usable\n")); + rc = whereLoopAddVirtualOne( + pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, &bRetry + ); + if( bRetry ){ + assert( rc==SQLITE_OK ); + rc = whereLoopAddVirtualOne( + pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, 0 + ); + } + + /* If the call to xBestIndex() with all terms enabled produced a plan + ** that does not require any source tables (IOW: a plan with mBest==0) + ** and does not use an IN(...) operator, then there is no point in making + ** any further calls to xBestIndex() since they will all return the same + ** result (if the xBestIndex() implementation is sane). */ + if( rc==SQLITE_OK && ((mBest = (pNew->prereq & ~mPrereq))!=0 || bIn) ){ + int seenZero = 0; /* True if a plan with no prereqs seen */ + int seenZeroNoIN = 0; /* Plan with no prereqs and no IN(...) seen */ + Bitmask mPrev = 0; + Bitmask mBestNoIn = 0; + + /* If the plan produced by the earlier call uses an IN(...) term, call + ** xBestIndex again, this time with IN(...) terms disabled. */ + if( bIn ){ + WHERETRACE(0x800, (" VirtualOne: all usable w/o IN\n")); + rc = whereLoopAddVirtualOne( + pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn, 0); + assert( bIn==0 ); + mBestNoIn = pNew->prereq & ~mPrereq; + if( mBestNoIn==0 ){ + seenZero = 1; + seenZeroNoIN = 1; + } + } + + /* Call xBestIndex once for each distinct value of (prereqRight & ~mPrereq) + ** in the set of terms that apply to the current virtual table. */ + while( rc==SQLITE_OK ){ + int i; + Bitmask mNext = ALLBITS; + assert( mNext>0 ); + for(i=0; iaConstraint[i].iTermOffset; + Bitmask mThis = termFromWhereClause(pWC, iTerm)->prereqRight & ~mPrereq; + if( mThis>mPrev && mThisprereq==mPrereq ){ + seenZero = 1; + if( bIn==0 ) seenZeroNoIN = 1; + } + } + + /* If the calls to xBestIndex() in the above loop did not find a plan + ** that requires no source tables at all (i.e. one guaranteed to be + ** usable), make a call here with all source tables disabled */ + if( rc==SQLITE_OK && seenZero==0 ){ + WHERETRACE(0x800, (" VirtualOne: all disabled\n")); + rc = whereLoopAddVirtualOne( + pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn, 0); + if( bIn==0 ) seenZeroNoIN = 1; + } + + /* If the calls to xBestIndex() have so far failed to find a plan + ** that requires no source tables at all and does not use an IN(...) + ** operator, make a final call to obtain one here. */ + if( rc==SQLITE_OK && seenZeroNoIN==0 ){ + WHERETRACE(0x800, (" VirtualOne: all disabled and w/o IN\n")); + rc = whereLoopAddVirtualOne( + pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn, 0); + } + } + + freeIndexInfo(pParse->db, p); + WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pSTab->zName, rc)); + return rc; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +/* +** Add WhereLoop entries to handle OR terms. This works for either +** btrees or virtual tables. +*/ +static int whereLoopAddOr( + WhereLoopBuilder *pBuilder, + Bitmask mPrereq, + Bitmask mUnusable +){ + WhereInfo *pWInfo = pBuilder->pWInfo; + WhereClause *pWC; + WhereLoop *pNew; + WhereTerm *pTerm, *pWCEnd; + int rc = SQLITE_OK; + int iCur; + WhereClause tempWC; + WhereLoopBuilder sSubBuild; + WhereOrSet sSum, sCur; + SrcItem *pItem; + + pWC = pBuilder->pWC; + pWCEnd = pWC->a + pWC->nTerm; + pNew = pBuilder->pNew; + memset(&sSum, 0, sizeof(sSum)); + pItem = pWInfo->pTabList->a + pNew->iTab; + iCur = pItem->iCursor; + + /* The multi-index OR optimization does not work for RIGHT and FULL JOIN */ + if( pItem->fg.jointype & JT_RIGHT ) return SQLITE_OK; + + for(pTerm=pWC->a; pTermeOperator & WO_OR)!=0 + && (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0 + ){ + WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc; + WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm]; + WhereTerm *pOrTerm; + int once = 1; + int i, j; + + sSubBuild = *pBuilder; + sSubBuild.pOrSet = &sCur; + + WHERETRACE(0x400, ("Begin processing OR-clause %p\n", pTerm)); + for(pOrTerm=pOrWC->a; pOrTermeOperator & WO_AND)!=0 ){ + sSubBuild.pWC = &pOrTerm->u.pAndInfo->wc; + }else if( pOrTerm->leftCursor==iCur ){ + tempWC.pWInfo = pWC->pWInfo; + tempWC.pOuter = pWC; + tempWC.op = TK_AND; + tempWC.nTerm = 1; + tempWC.nBase = 1; + tempWC.a = pOrTerm; + sSubBuild.pWC = &tempWC; + }else{ + continue; + } + sCur.n = 0; +#ifdef WHERETRACE_ENABLED + WHERETRACE(0x400, ("OR-term %d of %p has %d subterms:\n", + (int)(pOrTerm-pOrWC->a), pTerm, sSubBuild.pWC->nTerm)); + if( sqlite3WhereTrace & 0x20000 ){ + sqlite3WhereClausePrint(sSubBuild.pWC); + } +#endif +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pItem->pSTab) ){ + rc = whereLoopAddVirtual(&sSubBuild, mPrereq, mUnusable); + }else +#endif + { + rc = whereLoopAddBtree(&sSubBuild, mPrereq); + } + if( rc==SQLITE_OK ){ + rc = whereLoopAddOr(&sSubBuild, mPrereq, mUnusable); + } + testcase( rc==SQLITE_NOMEM && sCur.n>0 ); + testcase( rc==SQLITE_DONE ); + if( sCur.n==0 ){ + sSum.n = 0; + break; + }else if( once ){ + whereOrMove(&sSum, &sCur); + once = 0; + }else{ + WhereOrSet sPrev; + whereOrMove(&sPrev, &sSum); + sSum.n = 0; + for(i=0; inLTerm = 1; + pNew->aLTerm[0] = pTerm; + pNew->wsFlags = WHERE_MULTI_OR; + pNew->rSetup = 0; + pNew->iSortIdx = 0; + memset(&pNew->u, 0, sizeof(pNew->u)); + for(i=0; rc==SQLITE_OK && irRun = sSum.a[i].rRun + 1; + pNew->nOut = sSum.a[i].nOut; + pNew->prereq = sSum.a[i].prereq; + rc = whereLoopInsert(pBuilder, pNew); + } + WHERETRACE(0x400, ("End processing OR-clause %p\n", pTerm)); + } + } + return rc; +} + +/* +** Add all WhereLoop objects for all tables +*/ +static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ + WhereInfo *pWInfo = pBuilder->pWInfo; + Bitmask mPrereq = 0; + Bitmask mPrior = 0; + int iTab; + SrcList *pTabList = pWInfo->pTabList; + SrcItem *pItem; + SrcItem *pEnd = &pTabList->a[pWInfo->nLevel]; + sqlite3 *db = pWInfo->pParse->db; + int rc = SQLITE_OK; + int bFirstPastRJ = 0; + int hasRightCrossJoin = 0; + WhereLoop *pNew; + + + /* Loop over the tables in the join, from left to right */ + pNew = pBuilder->pNew; + + /* Verify that pNew has already been initialized */ + assert( pNew->nLTerm==0 ); + assert( pNew->wsFlags==0 ); + assert( pNew->nLSlot>=ArraySize(pNew->aLTermSpace) ); + assert( pNew->aLTerm!=0 ); + + pBuilder->iPlanLimit = SQLITE_QUERY_PLANNER_LIMIT; + for(iTab=0, pItem=pTabList->a; pItemiTab = iTab; + pBuilder->iPlanLimit += SQLITE_QUERY_PLANNER_LIMIT_INCR; + pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor); + if( bFirstPastRJ + || (pItem->fg.jointype & (JT_OUTER|JT_CROSS|JT_LTORJ))!=0 + ){ + /* Add prerequisites to prevent reordering of FROM clause terms + ** across CROSS joins and outer joins. The bFirstPastRJ boolean + ** prevents the right operand of a RIGHT JOIN from being swapped with + ** other elements even further to the right. + ** + ** The hasRightCrossJoin flag prevent FROM-clause terms from moving + ** from the right side of a LEFT JOIN or CROSS JOIN over to the + ** left side of that same join. This is a required restriction in + ** the case of LEFT JOIN - an incorrect answer may results if it is + ** not enforced. This restriction is not required for CROSS JOIN. + ** It is provided merely as a means of controlling join order, under + ** the theory that no real-world queries that care about performance + ** actually use the CROSS JOIN syntax. + */ + if( pItem->fg.jointype & (JT_LTORJ|JT_CROSS) ){ + testcase( pItem->fg.jointype & JT_LTORJ ); + testcase( pItem->fg.jointype & JT_CROSS ); + hasRightCrossJoin = 1; + } + mPrereq |= mPrior; + bFirstPastRJ = (pItem->fg.jointype & JT_RIGHT)!=0; + }else if( pItem->fg.fromExists ){ + /* joins that result from the EXISTS-to-JOIN optimization should not + ** be moved to the left of any of their dependencies */ + WhereClause *pWC = &pWInfo->sWC; + WhereTerm *pTerm; + int i; + for(i=pWC->nBase, pTerm=pWC->a; i>0; i--, pTerm++){ + if( (pNew->maskSelf & pTerm->prereqAll)!=0 ){ + mPrereq |= (pTerm->prereqAll & (pNew->maskSelf-1)); + } + } + }else if( !hasRightCrossJoin ){ + mPrereq = 0; + } +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pItem->pSTab) ){ + SrcItem *p; + for(p=&pItem[1]; pfg.jointype & (JT_OUTER|JT_CROSS)) ){ + mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor); + } + } + rc = whereLoopAddVirtual(pBuilder, mPrereq, mUnusable); + }else +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + { + rc = whereLoopAddBtree(pBuilder, mPrereq); + } + if( rc==SQLITE_OK && pBuilder->pWC->hasOr ){ + rc = whereLoopAddOr(pBuilder, mPrereq, mUnusable); + } + mPrior |= pNew->maskSelf; + if( rc || db->mallocFailed ){ + if( rc==SQLITE_DONE ){ + /* We hit the query planner search limit set by iPlanLimit */ + sqlite3_log(SQLITE_WARNING, "abbreviated query algorithm search"); + rc = SQLITE_OK; + }else{ + break; + } + } + } + + whereLoopClear(db, pNew); + return rc; +} + +/* Implementation of the order-by-subquery optimization: +** +** WhereLoop pLoop, which the iLoop-th term of the nested loop, is really +** a subquery or CTE that has an ORDER BY clause. See if any of the terms +** in the subquery ORDER BY clause will satisfy pOrderBy from the outer +** query. Mark off all satisfied terms (by setting bits in *pOBSat) and +** return TRUE if they do. If not, return false. +** +** Example: +** +** CREATE TABLE t1(a,b,c, PRIMARY KEY(a,b)); +** CREATE TABLE t2(x,y); +** WITH t3(p,q) AS MATERIALIZED (SELECT x+y, x-y FROM t2 ORDER BY x+y) +** SELECT * FROM t3 JOIN t1 ON a=q ORDER BY p, b; +** +** The CTE named "t3" comes out in the natural order of "p", so the first +** first them of "ORDER BY p,b" is satisfied by a sequential scan of "t3" +** and sorting only needs to occur on the second term "b". +** +** Limitations: +** +** (1) The optimization is not applied if the outer ORDER BY contains +** a COLLATE clause. The optimization might be applied if the +** outer ORDER BY uses NULLS FIRST, NULLS LAST, ASC, and/or DESC as +** long as the subquery ORDER BY does the same. But if the +** outer ORDER BY uses COLLATE, even a redundant COLLATE, the +** optimization is bypassed. +** +** (2) The subquery ORDER BY terms must exactly match subquery result +** columns, including any COLLATE annotations. This routine relies +** on iOrderByCol to do matching between order by terms and result +** columns, and iOrderByCol will not be set if the result column +** and ORDER BY collations differ. +** +** (3) The subquery and outer ORDER BY can be in opposite directions as +** long as the subquery is materialized. If the subquery is +** implemented as a co-routine, the sort orders must be in the same +** direction because there is no way to run a co-routine backwards. +*/ +static SQLITE_NOINLINE int wherePathMatchSubqueryOB( + WhereInfo *pWInfo, /* The WHERE clause */ + WhereLoop *pLoop, /* The nested loop term that is a subquery */ + int iLoop, /* Which level of the nested loop. 0==outermost */ + int iCur, /* Cursor used by the this loop */ + ExprList *pOrderBy, /* The ORDER BY clause on the whole query */ + Bitmask *pRevMask, /* When loops need to go in reverse order */ + Bitmask *pOBSat /* Which terms of pOrderBy are satisfied so far */ +){ + int iOB; /* Index into pOrderBy->a[] */ + int jSub; /* Index into pSubOB->a[] */ + u8 rev = 0; /* True if iOB and jSub sort in opposite directions */ + u8 revIdx = 0; /* Sort direction for jSub */ + Expr *pOBExpr; /* Current term of outer ORDER BY */ + ExprList *pSubOB; /* Complete ORDER BY on the subquery */ + + pSubOB = pLoop->u.btree.pOrderBy; + assert( pSubOB!=0 ); + for(iOB=0; (MASKBIT(iOB) & *pOBSat)!=0; iOB++){} + for(jSub=0; jSubnExpr && iOBnExpr; jSub++, iOB++){ + if( pSubOB->a[jSub].u.x.iOrderByCol==0 ) break; + pOBExpr = pOrderBy->a[iOB].pExpr; + if( pOBExpr->op!=TK_COLUMN && pOBExpr->op!=TK_AGG_COLUMN ) break; + if( pOBExpr->iTable!=iCur ) break; + if( pOBExpr->iColumn!=pSubOB->a[jSub].u.x.iOrderByCol-1 ) break; + if( (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){ + u8 sfOB = pOrderBy->a[iOB].fg.sortFlags; /* sortFlags for iOB */ + u8 sfSub = pSubOB->a[jSub].fg.sortFlags; /* sortFlags for jSub */ + if( (sfSub & KEYINFO_ORDER_BIGNULL) != (sfOB & KEYINFO_ORDER_BIGNULL) ){ + break; + } + revIdx = sfSub & KEYINFO_ORDER_DESC; + if( jSub>0 ){ + if( (rev^revIdx)!=(sfOB & KEYINFO_ORDER_DESC) ){ + break; + } + }else{ + rev = revIdx ^ (sfOB & KEYINFO_ORDER_DESC); + if( rev ){ + if( (pLoop->wsFlags & WHERE_COROUTINE)!=0 ){ + /* Cannot run a co-routine in reverse order */ + break; + } + *pRevMask |= MASKBIT(iLoop); + } + } + } + *pOBSat |= MASKBIT(iOB); + } + return jSub>0; +} + +/* +** Examine a WherePath (with the addition of the extra WhereLoop of the 6th +** parameters) to see if it outputs rows in the requested ORDER BY +** (or GROUP BY) without requiring a separate sort operation. Return N: +** +** N>0: N terms of the ORDER BY clause are satisfied +** N==0: No terms of the ORDER BY clause are satisfied +** N<0: Unknown yet how many terms of ORDER BY might be satisfied. +** +** Note that processing for WHERE_GROUPBY and WHERE_DISTINCTBY is not as +** strict. With GROUP BY and DISTINCT the only requirement is that +** equivalent rows appear immediately adjacent to one another. GROUP BY +** and DISTINCT do not require rows to appear in any particular order as long +** as equivalent rows are grouped together. Thus for GROUP BY and DISTINCT +** the pOrderBy terms can be matched in any order. With ORDER BY, the +** pOrderBy terms must be matched in strict left-to-right order. +*/ +static i8 wherePathSatisfiesOrderBy( + WhereInfo *pWInfo, /* The WHERE clause */ + ExprList *pOrderBy, /* ORDER BY or GROUP BY or DISTINCT clause to check */ + WherePath *pPath, /* The WherePath to check */ + u16 wctrlFlags, /* WHERE_GROUPBY or _DISTINCTBY or _ORDERBY_LIMIT */ + u16 nLoop, /* Number of entries in pPath->aLoop[] */ + WhereLoop *pLast, /* Add this WhereLoop to the end of pPath->aLoop[] */ + Bitmask *pRevMask /* OUT: Mask of WhereLoops to run in reverse order */ +){ + u8 revSet; /* True if rev is known */ + u8 rev; /* Composite sort order */ + u8 revIdx; /* Index sort order */ + u8 isOrderDistinct; /* All prior WhereLoops are order-distinct */ + u8 distinctColumns; /* True if the loop has UNIQUE NOT NULL columns */ + u8 isMatch; /* iColumn matches a term of the ORDER BY clause */ + u16 eqOpMask; /* Allowed equality operators */ + u16 nKeyCol; /* Number of key columns in pIndex */ + u16 nColumn; /* Total number of ordered columns in the index */ + u16 nOrderBy; /* Number terms in the ORDER BY clause */ + int iLoop; /* Index of WhereLoop in pPath being processed */ + int i, j; /* Loop counters */ + int iCur; /* Cursor number for current WhereLoop */ + int iColumn; /* A column number within table iCur */ + WhereLoop *pLoop = 0; /* Current WhereLoop being processed. */ + WhereTerm *pTerm; /* A single term of the WHERE clause */ + Expr *pOBExpr; /* An expression from the ORDER BY clause */ + CollSeq *pColl; /* COLLATE function from an ORDER BY clause term */ + Index *pIndex; /* The index associated with pLoop */ + sqlite3 *db = pWInfo->pParse->db; /* Database connection */ + Bitmask obSat = 0; /* Mask of ORDER BY terms satisfied so far */ + Bitmask obDone; /* Mask of all ORDER BY terms */ + Bitmask orderDistinctMask; /* Mask of all well-ordered loops */ + Bitmask ready; /* Mask of inner loops */ + + /* + ** We say the WhereLoop is "one-row" if it generates no more than one + ** row of output. A WhereLoop is one-row if all of the following are true: + ** (a) All index columns match with WHERE_COLUMN_EQ. + ** (b) The index is unique + ** Any WhereLoop with an WHERE_COLUMN_EQ constraint on the rowid is one-row. + ** Every one-row WhereLoop will have the WHERE_ONEROW bit set in wsFlags. + ** + ** We say the WhereLoop is "order-distinct" if the set of columns from + ** that WhereLoop that are in the ORDER BY clause are different for every + ** row of the WhereLoop. Every one-row WhereLoop is automatically + ** order-distinct. A WhereLoop that has no columns in the ORDER BY clause + ** is not order-distinct. To be order-distinct is not quite the same as being + ** UNIQUE since a UNIQUE column or index can have multiple rows that + ** are NULL and NULL values are equivalent for the purpose of order-distinct. + ** To be order-distinct, the columns must be UNIQUE and NOT NULL. + ** + ** The rowid for a table is always UNIQUE and NOT NULL so whenever the + ** rowid appears in the ORDER BY clause, the corresponding WhereLoop is + ** automatically order-distinct. + */ + + assert( pOrderBy!=0 ); + if( nLoop && OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ) return 0; + + nOrderBy = pOrderBy->nExpr; + testcase( nOrderBy==BMS-1 ); + if( nOrderBy>BMS-1 ) return 0; /* Cannot optimize overly large ORDER BYs */ + isOrderDistinct = 1; + obDone = MASKBIT(nOrderBy)-1; + orderDistinctMask = 0; + ready = 0; + eqOpMask = WO_EQ | WO_IS | WO_ISNULL; + if( wctrlFlags & (WHERE_ORDERBY_LIMIT|WHERE_ORDERBY_MAX|WHERE_ORDERBY_MIN) ){ + eqOpMask |= WO_IN; + } + for(iLoop=0; isOrderDistinct && obSat0 ) ready |= pLoop->maskSelf; + if( iLoopaLoop[iLoop]; + if( wctrlFlags & WHERE_ORDERBY_LIMIT ) continue; + }else{ + pLoop = pLast; + } + if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){ + if( pLoop->u.vtab.isOrdered && pWInfo->pOrderBy==pOrderBy ){ + obSat = obDone; + }else{ + /* No further ORDER BY terms may be matched. So this call should + ** return >=0, not -1. Clear isOrderDistinct to ensure it does so. */ + isOrderDistinct = 0; + } + break; + } + iCur = pWInfo->pTabList->a[pLoop->iTab].iCursor; + + /* Mark off any ORDER BY term X that is a column in the table of + ** the current loop for which there is term in the WHERE + ** clause of the form X IS NULL or X=? that reference only outer + ** loops. + */ + for(i=0; ia[i].pExpr); + if( NEVER(pOBExpr==0) ) continue; + if( pOBExpr->op!=TK_COLUMN && pOBExpr->op!=TK_AGG_COLUMN ) continue; + if( pOBExpr->iTable!=iCur ) continue; + pTerm = sqlite3WhereFindTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn, + ~ready, eqOpMask, 0); + if( pTerm==0 ) continue; + if( pTerm->eOperator==WO_IN ){ + /* IN terms are only valid for sorting in the ORDER BY LIMIT + ** optimization, and then only if they are actually used + ** by the query plan */ + assert( wctrlFlags & + (WHERE_ORDERBY_LIMIT|WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX) ); + for(j=0; jnLTerm && pTerm!=pLoop->aLTerm[j]; j++){} + if( j>=pLoop->nLTerm ) continue; + } + if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 && pOBExpr->iColumn>=0 ){ + Parse *pParse = pWInfo->pParse; + CollSeq *pColl1 = sqlite3ExprNNCollSeq(pParse, pOrderBy->a[i].pExpr); + CollSeq *pColl2 = sqlite3ExprCompareCollSeq(pParse, pTerm->pExpr); + assert( pColl1 ); + if( pColl2==0 || sqlite3StrICmp(pColl1->zName, pColl2->zName) ){ + continue; + } + testcase( pTerm->pExpr->op==TK_IS ); + } + obSat |= MASKBIT(i); + } + + if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){ + if( pLoop->wsFlags & WHERE_IPK ){ + if( pLoop->u.btree.pOrderBy + && OptimizationEnabled(db, SQLITE_OrderBySubq) + && wherePathMatchSubqueryOB(pWInfo,pLoop,iLoop,iCur, + pOrderBy,pRevMask, &obSat) + ){ + nColumn = 0; + isOrderDistinct = 0; + }else{ + nColumn = 1; + } + pIndex = 0; + nKeyCol = 0; + }else if( (pIndex = pLoop->u.btree.pIndex)==0 || pIndex->bUnordered ){ + return 0; + }else{ + nKeyCol = pIndex->nKeyCol; + nColumn = pIndex->nColumn; + assert( nColumn==nKeyCol+1 || !HasRowid(pIndex->pTable) ); + assert( pIndex->aiColumn[nColumn-1]==XN_ROWID + || !HasRowid(pIndex->pTable)); + /* All relevant terms of the index must also be non-NULL in order + ** for isOrderDistinct to be true. So the isOrderDistinct value + ** computed here might be a false positive. Corrections will be + ** made at tag-20210426-1 below */ + isOrderDistinct = IsUniqueIndex(pIndex) + && (pLoop->wsFlags & WHERE_SKIPSCAN)==0; + } + + /* Loop through all columns of the index and deal with the ones + ** that are not constrained by == or IN. + */ + rev = revSet = 0; + distinctColumns = 0; + for(j=0; j=pLoop->u.btree.nEq + || (pLoop->aLTerm[j]==0)==(jnSkip) + ); + if( ju.btree.nEq && j>=pLoop->nSkip ){ + u16 eOp = pLoop->aLTerm[j]->eOperator; + + /* Skip over == and IS and ISNULL terms. (Also skip IN terms when + ** doing WHERE_ORDERBY_LIMIT processing). Except, IS and ISNULL + ** terms imply that the index is not UNIQUE NOT NULL in which case + ** the loop need to be marked as not order-distinct because it can + ** have repeated NULL rows. + ** + ** If the current term is a column of an ((?,?) IN (SELECT...)) + ** expression for which the SELECT returns more than one column, + ** check that it is the only column used by this loop. Otherwise, + ** if it is one of two or more, none of the columns can be + ** considered to match an ORDER BY term. + */ + if( (eOp & eqOpMask)!=0 ){ + if( eOp & (WO_ISNULL|WO_IS) ){ + testcase( eOp & WO_ISNULL ); + testcase( eOp & WO_IS ); + testcase( isOrderDistinct ); + isOrderDistinct = 0; + } + continue; + }else if( ALWAYS(eOp & WO_IN) ){ + /* ALWAYS() justification: eOp is an equality operator due to the + ** ju.btree.nEq constraint above. Any equality other + ** than WO_IN is captured by the previous "if". So this one + ** always has to be WO_IN. */ + Expr *pX = pLoop->aLTerm[j]->pExpr; + for(i=j+1; iu.btree.nEq; i++){ + if( pLoop->aLTerm[i]->pExpr==pX ){ + assert( (pLoop->aLTerm[i]->eOperator & WO_IN) ); + bOnce = 0; + break; + } + } + } + } + + /* Get the column number in the table (iColumn) and sort order + ** (revIdx) for the j-th column of the index. + */ + if( pIndex ){ + iColumn = pIndex->aiColumn[j]; + revIdx = pIndex->aSortOrder[j] & KEYINFO_ORDER_DESC; + if( iColumn==pIndex->pTable->iPKey ) iColumn = XN_ROWID; + }else{ + iColumn = XN_ROWID; + revIdx = 0; + } + + /* An unconstrained column that might be NULL means that this + ** WhereLoop is not well-ordered. tag-20210426-1 + */ + if( isOrderDistinct ){ + if( iColumn>=0 + && j>=pLoop->u.btree.nEq + && pIndex->pTable->aCol[iColumn].notNull==0 + ){ + isOrderDistinct = 0; + } + if( iColumn==XN_EXPR ){ + isOrderDistinct = 0; + } + } + + /* Find the ORDER BY term that corresponds to the j-th column + ** of the index and mark that ORDER BY term having been satisfied. + */ + isMatch = 0; + for(i=0; bOnce && ia[i].pExpr); + testcase( wctrlFlags & WHERE_GROUPBY ); + testcase( wctrlFlags & WHERE_DISTINCTBY ); + if( NEVER(pOBExpr==0) ) continue; + if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0; + if( iColumn>=XN_ROWID ){ + if( pOBExpr->op!=TK_COLUMN && pOBExpr->op!=TK_AGG_COLUMN ) continue; + if( pOBExpr->iTable!=iCur ) continue; + if( pOBExpr->iColumn!=iColumn ) continue; + }else{ + Expr *pIxExpr = pIndex->aColExpr->a[j].pExpr; + if( sqlite3ExprCompareSkip(pOBExpr, pIxExpr, iCur) ){ + continue; + } + } + if( iColumn!=XN_ROWID ){ + pColl = sqlite3ExprNNCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr); + if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue; + } + if( wctrlFlags & WHERE_DISTINCTBY ){ + pLoop->u.btree.nDistinctCol = j+1; + } + isMatch = 1; + break; + } + if( isMatch && (wctrlFlags & WHERE_GROUPBY)==0 ){ + /* Make sure the sort order is compatible in an ORDER BY clause. + ** Sort order is irrelevant for a GROUP BY clause. */ + if( revSet ){ + if( (rev ^ revIdx) + != (pOrderBy->a[i].fg.sortFlags&KEYINFO_ORDER_DESC) + ){ + isMatch = 0; + } + }else{ + rev = revIdx ^ (pOrderBy->a[i].fg.sortFlags & KEYINFO_ORDER_DESC); + if( rev ) *pRevMask |= MASKBIT(iLoop); + revSet = 1; + } + } + if( isMatch && (pOrderBy->a[i].fg.sortFlags & KEYINFO_ORDER_BIGNULL) ){ + if( j==pLoop->u.btree.nEq ){ + pLoop->wsFlags |= WHERE_BIGNULL_SORT; + }else{ + isMatch = 0; + } + } + if( isMatch ){ + if( iColumn==XN_ROWID ){ + testcase( distinctColumns==0 ); + distinctColumns = 1; + } + obSat |= MASKBIT(i); + }else{ + /* No match found */ + if( j==0 || jmaskSelf; + for(i=0; ia[i].pExpr; + mTerm = sqlite3WhereExprUsage(&pWInfo->sMaskSet,p); + if( mTerm==0 && !sqlite3ExprIsConstant(0,p) ) continue; + if( (mTerm&~orderDistinctMask)==0 ){ + obSat |= MASKBIT(i); + } + } + } + } /* End the loop over all WhereLoops from outer-most down to inner-most */ + if( obSat==obDone ) return (i8)nOrderBy; + if( !isOrderDistinct ){ + for(i=nOrderBy-1; i>0; i--){ + Bitmask m = ALWAYS(iwctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY) ); + assert( pWInfo->wctrlFlags & WHERE_SORTBYGROUP ); + return pWInfo->sorted; +} + +#ifdef WHERETRACE_ENABLED +/* For debugging use only: */ +static const char *wherePathName(WherePath *pPath, int nLoop, WhereLoop *pLast){ + static char zName[65]; + int i; + for(i=0; iaLoop[i]->cId; } + if( pLast ) zName[i++] = pLast->cId; + zName[i] = 0; + return zName; +} +#endif + +/* +** Return the cost of sorting nRow rows, assuming that the keys have +** nOrderby columns and that the first nSorted columns are already in +** order. +*/ +static LogEst whereSortingCost( + WhereInfo *pWInfo, /* Query planning context */ + LogEst nRow, /* Estimated number of rows to sort */ + int nOrderBy, /* Number of ORDER BY clause terms */ + int nSorted /* Number of initial ORDER BY terms naturally in order */ +){ + /* Estimated cost of a full external sort, where N is + ** the number of rows to sort is: + ** + ** cost = (K * N * log(N)). + ** + ** Or, if the order-by clause has X terms but only the last Y + ** terms are out of order, then block-sorting will reduce the + ** sorting cost to: + ** + ** cost = (K * N * log(N)) * (Y/X) + ** + ** The constant K is at least 2.0 but will be larger if there are a + ** large number of columns to be sorted, as the sorting time is + ** proportional to the amount of content to be sorted. The algorithm + ** does not currently distinguish between fat columns (BLOBs and TEXTs) + ** and skinny columns (INTs). It just uses the number of columns as + ** an approximation for the row width. + ** + ** And extra factor of 2.0 or 3.0 is added to the sorting cost if the sort + ** is built using OP_IdxInsert and OP_Sort rather than with OP_SorterInsert. + */ + LogEst rSortCost, nCol; + assert( pWInfo->pSelect!=0 ); + assert( pWInfo->pSelect->pEList!=0 ); + /* TUNING: sorting cost proportional to the number of output columns: */ + nCol = sqlite3LogEst((pWInfo->pSelect->pEList->nExpr+59)/30); + rSortCost = nRow + nCol; + if( nSorted>0 ){ + /* Scale the result by (Y/X) */ + rSortCost += sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66; + } + + /* Multiple by log(M) where M is the number of output rows. + ** Use the LIMIT for M if it is smaller. Or if this sort is for + ** a DISTINCT operator, M will be the number of distinct output + ** rows, so fudge it downwards a bit. + */ + if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 ){ + rSortCost += 10; /* TUNING: Extra 2.0x if using LIMIT */ + if( nSorted!=0 ){ + rSortCost += 6; /* TUNING: Extra 1.5x if also using partial sort */ + } + if( pWInfo->iLimitiLimit; + } + }else if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT) ){ + /* TUNING: In the sort for a DISTINCT operator, assume that the DISTINCT + ** reduces the number of output rows by a factor of 2 */ + if( nRow>10 ){ nRow -= 10; assert( 10==sqlite3LogEst(2) ); } + } + rSortCost += estLog(nRow); + return rSortCost; +} + +/* +** Compute the maximum number of paths in the solver algorithm, for +** queries that have three or more terms in the FROM clause. Queries with +** two or fewer FROM clause terms are handled by the caller. +** +** Query planning is NP-hard. We must limit the number of paths at +** each step of the solver search algorithm to avoid exponential behavior. +** +** The value returned is a tuning parameter. Currently the value is: +** +** 18 for star queries +** 12 otherwise +** +** For the purposes of this heuristic, a star-query is defined as a query +** with a central "fact" table that is joined against multiple +** "dimension" tables, subject to the following constraints: +** +** (aa) Only a five-way or larger join is considered for this +** optimization. If there are fewer than four terms in the FROM +** clause, this heuristic does not apply. +** +** (bb) The join between the fact table and the dimension tables must +** be an INNER join. CROSS and OUTER JOINs do not qualify. +** +** (cc) A table must have 3 or more dimension tables in order to be +** considered a fact table. (Was 4 prior to 2026-02-10.) +** +** (dd) A table that is a self-join cannot be a dimension table. +** Dimension tables are joined against fact tables. +** +** SIDE EFFECT: (and really the whole point of this subroutine) +** +** If pWInfo describes a star-query, then the cost for SCANs of dimension +** WhereLoops is increased to be slightly larger than the cost of a SCAN +** in the fact table. Only SCAN costs are increased. SEARCH costs are +** unchanged. This heuristic helps keep fact tables in outer loops. Without +** this heuristic, paths with fact tables in outer loops tend to get pruned +** by the mxChoice limit on the number of paths, resulting in poor query +** plans. See the starschema1.test test module for examples of queries +** that need this heuristic to find good query plans. +** +** This heuristic can be completely disabled, so that no query is +** considered a star-query, using SQLITE_TESTCTRL_OPTIMIZATION to +** disable the SQLITE_StarQuery optimization. In the CLI, the command +** to do that is: ".testctrl opt -starquery". +** +** HISTORICAL NOTES: +** +** This optimization was first added on 2024-05-09 by check-in 38db9b5c83d. +** The original optimization reduced the cost and output size estimate for +** fact tables to help them move to outer loops. But months later (as people +** started upgrading) performance regression reports started caming in, +** including: +** +** forum post b18ef983e68d06d1 (2024-12-21) +** forum post 0025389d0860af82 (2025-01-14) +** forum post d87570a145599033 (2025-01-17) +** +** To address these, the criteria for a star-query was tightened to exclude +** cases where the fact and dimensions are separated by an outer join, and +** the affect of star-schema detection was changed to increase the rRun cost +** on just full table scans of dimension tables, rather than reducing costs +** in the all access methods of the fact table. +*/ +static int computeMxChoice(WhereInfo *pWInfo){ + int nLoop = pWInfo->nLevel; /* Number of terms in the join */ + WhereLoop *pWLoop; /* For looping over WhereLoops */ + +#ifdef SQLITE_DEBUG + /* The star-query detection code below makes use of the following + ** properties of the WhereLoop list, so verify them before + ** continuing: + ** (1) .maskSelf is the bitmask corresponding to .iTab + ** (2) The WhereLoop list is in ascending .iTab order + */ + for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){ + assert( pWLoop->maskSelf==MASKBIT(pWLoop->iTab) ); + assert( pWLoop->pNextLoop==0 || pWLoop->iTab<=pWLoop->pNextLoop->iTab ); + } +#endif /* SQLITE_DEBUG */ + + if( nLoop>=4 /* Constraint (aa) */ + && !pWInfo->bStarDone + && OptimizationEnabled(pWInfo->pParse->db, SQLITE_StarQuery) + ){ + SrcItem *aFromTabs; /* All terms of the FROM clause */ + int iFromIdx; /* Term of FROM clause is the candidate fact-table */ + Bitmask m; /* Bitmask for candidate fact-table */ + Bitmask mSelfJoin = 0; /* Tables that cannot be dimension tables */ + WhereLoop *pStart; /* Where to start searching for dimension-tables */ + + pWInfo->bStarDone = 1; /* Only do this computation once */ + + /* Look for fact tables with three or more dimensions where the + ** dimension tables are not separately from the fact tables by an outer + ** or cross join. Adjust cost weights if found. + */ + assert( !pWInfo->bStarUsed ); + aFromTabs = pWInfo->pTabList->a; + pStart = pWInfo->pLoops; + for(iFromIdx=0, m=1; iFromIdxfg.jointype & (JT_OUTER|JT_CROSS))!=0 ){ + /* If the candidate fact-table is the right table of an outer join + ** restrict the search for dimension-tables to be tables to the right + ** of the fact-table. Constraint (bb) */ + if( iFromIdx+3 > nLoop ){ + break; /* ^-- Impossible to reach nDep>=2 - Constraint (cc) */ + } + while( pStart && pStart->iTab<=iFromIdx ){ + pStart = pStart->pNextLoop; + } + } + for(pWLoop=pStart; pWLoop; pWLoop=pWLoop->pNextLoop){ + if( (aFromTabs[pWLoop->iTab].fg.jointype & (JT_OUTER|JT_CROSS))!=0 ){ + break; /* Constraint (bb) */ + } + if( (pWLoop->prereq & m)!=0 /* pWInfo depends on iFromIdx */ + && (pWLoop->maskSelf & mSeen)==0 /* pWInfo not already a dependency */ + && (pWLoop->maskSelf & mSelfJoin)==0 /* Not a self-join */ + ){ + if( aFromTabs[pWLoop->iTab].pSTab==pFactTab->pSTab ){ + mSelfJoin |= m; + }else{ + nDep++; + mSeen |= pWLoop->maskSelf; + } + } + } + if( nDep<=2 ){ + continue; /* Constraint (cc) */ + } + + /* If we reach this point, it means that pFactTab is a fact table + ** with four or more dimensions connected by inner joins. Proceed + ** to make cost adjustments. */ + +#ifdef WHERETRACE_ENABLED + /* Make sure rStarDelta values are initialized */ + if( !pWInfo->bStarUsed ){ + for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){ + pWLoop->rStarDelta = 0; + } + } +#endif +#ifdef WHERETRACE_ENABLED /* 0x80000 */ + if( sqlite3WhereTrace & 0x80000 ){ + Bitmask mShow = mSeen; + sqlite3DebugPrintf("Fact table %s(%d), dimensions:", + pFactTab->zAlias ? pFactTab->zAlias : pFactTab->pSTab->zName, + iFromIdx); + for(pWLoop=pStart; pWLoop; pWLoop=pWLoop->pNextLoop){ + if( mShow & pWLoop->maskSelf ){ + SrcItem *pDim = aFromTabs + pWLoop->iTab; + mShow &= ~pWLoop->maskSelf; + sqlite3DebugPrintf(" %s(%d)", + pDim->zAlias ? pDim->zAlias: pDim->pSTab->zName, pWLoop->iTab); + } + } + sqlite3DebugPrintf("\n"); + } +#endif + pWInfo->bStarUsed = 1; + + /* Compute the maximum cost of any WhereLoop for the + ** fact table plus one epsilon */ + mxRun = LOGEST_MIN; + for(pWLoop=pStart; pWLoop; pWLoop=pWLoop->pNextLoop){ + if( pWLoop->iTabiTab>iFromIdx ) break; + if( pWLoop->rRun>mxRun ) mxRun = pWLoop->rRun; + } + if( ALWAYS(mxRunpNextLoop){ + if( (pWLoop->maskSelf & mSeen)==0 ) continue; + if( pWLoop->nLTerm ) continue; + if( pWLoop->rRuniTab; + sqlite3DebugPrintf( + "Increase SCAN cost of %s to %d\n", + pDim->zAlias ? pDim->zAlias: pDim->pSTab->zName, mxRun + ); + } + pWLoop->rStarDelta = mxRun - pWLoop->rRun; +#endif /* WHERETRACE_ENABLED */ + pWLoop->rRun = mxRun; + } + } + } +#ifdef WHERETRACE_ENABLED /* 0x80000 */ + if( (sqlite3WhereTrace & 0x80000)!=0 && pWInfo->bStarUsed ){ + sqlite3DebugPrintf("WhereLoops changed by star-query heuristic:\n"); + for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){ + if( pWLoop->rStarDelta ){ + sqlite3WhereLoopPrint(pWLoop, &pWInfo->sWC); + } + } + } +#endif + } + return pWInfo->bStarUsed ? 18 : 12; +} + +/* +** Two WhereLoop objects, pCandidate and pBaseline, are known to have the +** same cost. Look deep into each to see if pCandidate is even slightly +** better than pBaseline. Return false if it is, if pCandidate is is preferred. +** Return true if pBaseline is preferred or if we cannot tell the difference. +** +** Result Meaning +** -------- ---------------------------------------------------------- +** true We cannot tell the difference in pCandidate and pBaseline +** false pCandidate seems like a better choice than pBaseline +*/ +static SQLITE_NOINLINE int whereLoopIsNoBetter( + const WhereLoop *pCandidate, + const WhereLoop *pBaseline +){ + if( (pCandidate->wsFlags & WHERE_INDEXED)==0 ) return 1; + if( (pBaseline->wsFlags & WHERE_INDEXED)==0 ) return 1; + if( pCandidate->u.btree.pIndex->szIdxRow < + pBaseline->u.btree.pIndex->szIdxRow ) return 0; + return 1; +} + +/* +** Given the list of WhereLoop objects at pWInfo->pLoops, this routine +** attempts to find the lowest cost path that visits each WhereLoop +** once. This path is then loaded into the pWInfo->a[].pWLoop fields. +** +** Assume that the total number of output rows that will need to be sorted +** will be nRowEst (in the 10*log2 representation). Or, ignore sorting +** costs if nRowEst==0. +** +** Return SQLITE_OK on success or SQLITE_NOMEM of a memory allocation +** error occurs. +*/ +static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ + int mxChoice; /* Maximum number of simultaneous paths tracked */ + int nLoop; /* Number of terms in the join */ + Parse *pParse; /* Parsing context */ + int iLoop; /* Loop counter over the terms of the join */ + int ii, jj; /* Loop counters */ + int mxI = 0; /* Index of next entry to replace */ + int nOrderBy; /* Number of ORDER BY clause terms */ + LogEst mxCost = 0; /* Maximum cost of a set of paths */ + LogEst mxUnsort = 0; /* Maximum unsorted cost of a set of path */ + int nTo, nFrom; /* Number of valid entries in aTo[] and aFrom[] */ + WherePath *aFrom; /* All nFrom paths at the previous level */ + WherePath *aTo; /* The nTo best paths at the current level */ + WherePath *pFrom; /* An element of aFrom[] that we are working on */ + WherePath *pTo; /* An element of aTo[] that we are working on */ + WhereLoop *pWLoop; /* One of the WhereLoop objects */ + WhereLoop **pX; /* Used to divy up the pSpace memory */ + LogEst *aSortCost = 0; /* Sorting and partial sorting costs */ + char *pSpace; /* Temporary memory used by this routine */ + int nSpace; /* Bytes of space allocated at pSpace */ + + pParse = pWInfo->pParse; + nLoop = pWInfo->nLevel; + WHERETRACE(0x002, ("---- begin solver. (nRowEst=%d, nQueryLoop=%d)\n", + nRowEst, pParse->nQueryLoop)); + /* TUNING: mxChoice is the maximum number of possible paths to preserve + ** at each step. Based on the number of loops in the FROM clause: + ** + ** nLoop mxChoice + ** ----- -------- + ** 1 1 // the most common case + ** 2 5 + ** 3+ 12 or 18 // see computeMxChoice() + */ + if( nLoop<=1 ){ + mxChoice = 1; + }else if( nLoop==2 ){ + mxChoice = 5; + }else if( pParse->nErr ){ + mxChoice = 1; + }else{ + mxChoice = computeMxChoice(pWInfo); + } + assert( nLoop<=pWInfo->pTabList->nSrc ); + + /* If nRowEst is zero and there is an ORDER BY clause, ignore it. In this + ** case the purpose of this call is to estimate the number of rows returned + ** by the overall query. Once this estimate has been obtained, the caller + ** will invoke this function a second time, passing the estimate as the + ** nRowEst parameter. */ + if( pWInfo->pOrderBy==0 || nRowEst==0 ){ + nOrderBy = 0; + }else{ + nOrderBy = pWInfo->pOrderBy->nExpr; + } + + /* Allocate and initialize space for aTo, aFrom and aSortCost[] */ + nSpace = (sizeof(WherePath)+sizeof(WhereLoop*)*nLoop)*mxChoice*2; + nSpace += sizeof(LogEst) * nOrderBy; + pSpace = sqlite3StackAllocRawNN(pParse->db, nSpace); + if( pSpace==0 ) return SQLITE_NOMEM_BKPT; + aTo = (WherePath*)pSpace; + aFrom = aTo+mxChoice; + memset(aFrom, 0, sizeof(aFrom[0])); + pX = (WhereLoop**)(aFrom+mxChoice); + for(ii=mxChoice*2, pFrom=aTo; ii>0; ii--, pFrom++, pX += nLoop){ + pFrom->aLoop = pX; + } + if( nOrderBy ){ + /* If there is an ORDER BY clause and it is not being ignored, set up + ** space for the aSortCost[] array. Each element of the aSortCost array + ** is either zero - meaning it has not yet been initialized - or the + ** cost of sorting nRowEst rows of data where the first X terms of + ** the ORDER BY clause are already in order, where X is the array + ** index. */ + aSortCost = (LogEst*)pX; + memset(aSortCost, 0, sizeof(LogEst) * nOrderBy); + } + assert( aSortCost==0 || &pSpace[nSpace]==(char*)&aSortCost[nOrderBy] ); + assert( aSortCost!=0 || &pSpace[nSpace]==(char*)pX ); + + /* Seed the search with a single WherePath containing zero WhereLoops. + ** + ** TUNING: Do not let the number of iterations go above 28. If the cost + ** of computing an automatic index is not paid back within the first 28 + ** rows, then do not use the automatic index. */ + aFrom[0].nRow = MIN(pParse->nQueryLoop, 48); assert( 48==sqlite3LogEst(28) ); + nFrom = 1; + assert( aFrom[0].isOrdered==0 ); + if( nOrderBy ){ + /* If nLoop is zero, then there are no FROM terms in the query. Since + ** in this case the query may return a maximum of one row, the results + ** are already in the requested order. Set isOrdered to nOrderBy to + ** indicate this. Or, if nLoop is greater than zero, set isOrdered to + ** -1, indicating that the result set may or may not be ordered, + ** depending on the loops added to the current plan. */ + aFrom[0].isOrdered = nLoop>0 ? -1 : nOrderBy; + } + + /* Compute successively longer WherePaths using the previous generation + ** of WherePaths as the basis for the next. Keep track of the mxChoice + ** best paths at each generation */ + for(iLoop=0; iLooppLoops; pWLoop; pWLoop=pWLoop->pNextLoop){ + LogEst nOut; /* Rows visited by (pFrom+pWLoop) */ + LogEst rCost; /* Cost of path (pFrom+pWLoop) */ + LogEst rUnsort; /* Unsorted cost of (pFrom+pWLoop) */ + i8 isOrdered; /* isOrdered for (pFrom+pWLoop) */ + Bitmask maskNew; /* Mask of src visited by (..) */ + Bitmask revMask; /* Mask of rev-order loops for (..) */ + + if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue; + if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue; + if( (pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 && pFrom->nRow<3 ){ + /* Do not use an automatic index if the this loop is expected + ** to run less than 1.25 times. It is tempting to also exclude + ** automatic index usage on an outer loop, but sometimes an automatic + ** index is useful in the outer loop of a correlated subquery. */ + assert( 10==sqlite3LogEst(2) ); + continue; + } + + /* At this point, pWLoop is a candidate to be the next loop. + ** Compute its cost */ + rUnsort = pWLoop->rRun + pFrom->nRow; + if( pWLoop->rSetup ){ + rUnsort = sqlite3LogEstAdd(pWLoop->rSetup, rUnsort); + } + rUnsort = sqlite3LogEstAdd(rUnsort, pFrom->rUnsort); + nOut = pFrom->nRow + pWLoop->nOut; + maskNew = pFrom->maskLoop | pWLoop->maskSelf; + isOrdered = pFrom->isOrdered; + if( isOrdered<0 ){ + revMask = 0; + isOrdered = wherePathSatisfiesOrderBy(pWInfo, + pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags, + iLoop, pWLoop, &revMask); + }else{ + revMask = pFrom->revLoop; + } + if( isOrdered>=0 && isOrdered=0, or + ** (C) ordering does not matter because this is the last round + ** of the solver. + ** + ** The term "((pTo->isOrdered^isOrdered)&0x80)==0" is equivalent + ** to (pTo->isOrdered==(-1))==(isOrdered==(-1))" for the range + ** of legal values for isOrdered, -1..64. + */ + testcase( nTo==0 ); + for(jj=0, pTo=aTo; jjmaskLoop==maskNew + && ( ((pTo->isOrdered^isOrdered)&0x80)==0 || iLoop==nLoop-1 ) + ){ + testcase( jj==nTo-1 ); + break; + } + } + if( jj>=nTo ){ + /* None of the existing best-so-far paths match the candidate. */ + if( nTo>=mxChoice + && (rCost>mxCost || (rCost==mxCost && rUnsort>=mxUnsort)) + ){ + /* The current candidate is no better than any of the mxChoice + ** paths currently in the best-so-far buffer. So discard + ** this candidate as not viable. */ +#ifdef WHERETRACE_ENABLED /* 0x4 */ + if( sqlite3WhereTrace&0x4 ){ + sqlite3DebugPrintf("Skip %s cost=%-3d,%3d,%3d order=%c\n", + wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsort, + isOrdered>=0 ? isOrdered+'0' : '?'); + } +#endif + continue; + } + /* If we reach this points it means that the new candidate path + ** needs to be added to the set of best-so-far paths. */ + if( nTo=0 ? isOrdered+'0' : '?'); + } +#endif + }else{ + /* Control reaches here if best-so-far path pTo=aTo[jj] covers the + ** same set of loops and has the same isOrdered setting as the + ** candidate path. Check to see if the candidate should replace + ** pTo or if the candidate should be skipped. + ** + ** The conditional is an expanded vector comparison equivalent to: + ** (pTo->rCost,pTo->nRow,pTo->rUnsort) <= (rCost,nOut,rUnsort) + */ + if( (pTo->rCostrCost==rCost && pTo->nRowrCost==rCost && pTo->nRow==nOut && pTo->rUnsortrCost==rCost && pTo->nRow==nOut && pTo->rUnsort==rUnsort + && whereLoopIsNoBetter(pWLoop, pTo->aLoop[iLoop]) ) + ){ +#ifdef WHERETRACE_ENABLED /* 0x4 */ + if( sqlite3WhereTrace&0x4 ){ + sqlite3DebugPrintf( + "Skip %s cost=%-3d,%3d,%3d order=%c", + wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsort, + isOrdered>=0 ? isOrdered+'0' : '?'); + sqlite3DebugPrintf(" vs %s cost=%-3d,%3d,%3d order=%c\n", + wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow, + pTo->rUnsort, pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?'); + } +#endif + /* Discard the candidate path from further consideration */ + testcase( pTo->rCost==rCost ); + continue; + } + testcase( pTo->rCost==rCost+1 ); + /* Control reaches here if the candidate path is better than the + ** pTo path. Replace pTo with the candidate. */ +#ifdef WHERETRACE_ENABLED /* 0x4 */ + if( sqlite3WhereTrace&0x4 ){ + sqlite3DebugPrintf( + "Update %s cost=%-3d,%3d,%3d order=%c", + wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsort, + isOrdered>=0 ? isOrdered+'0' : '?'); + sqlite3DebugPrintf(" was %s cost=%-3d,%3d,%3d order=%c\n", + wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow, + pTo->rUnsort, pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?'); + } +#endif + } + /* pWLoop is a winner. Add it to the set of best so far */ + pTo->maskLoop = pFrom->maskLoop | pWLoop->maskSelf; + pTo->revLoop = revMask; + pTo->nRow = nOut; + pTo->rCost = rCost; + pTo->rUnsort = rUnsort; + pTo->isOrdered = isOrdered; + memcpy(pTo->aLoop, pFrom->aLoop, sizeof(WhereLoop*)*iLoop); + pTo->aLoop[iLoop] = pWLoop; + if( nTo>=mxChoice ){ + mxI = 0; + mxCost = aTo[0].rCost; + mxUnsort = aTo[0].nRow; + for(jj=1, pTo=&aTo[1]; jjrCost>mxCost + || (pTo->rCost==mxCost && pTo->rUnsort>mxUnsort) + ){ + mxCost = pTo->rCost; + mxUnsort = pTo->rUnsort; + mxI = jj; + } + } + } + } + } + +#ifdef WHERETRACE_ENABLED /* >=2 */ + if( sqlite3WhereTrace & 0x02 ){ + LogEst rMin, rFloor = 0; + int nDone = 0; + int nProgress; + sqlite3DebugPrintf("---- after round %d ----\n", iLoop); + do{ + nProgress = 0; + rMin = 0x7fff; + for(ii=0, pTo=aTo; iirCost>rFloor && pTo->rCostrCost; + } + for(ii=0, pTo=aTo; iirCost==rMin ){ + sqlite3DebugPrintf(" %s cost=%-3d nrow=%-3d order=%c", + wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow, + pTo->isOrdered>=0 ? (pTo->isOrdered+'0') : '?'); + if( pTo->isOrdered>0 ){ + sqlite3DebugPrintf(" rev=0x%llx\n", pTo->revLoop); + }else{ + sqlite3DebugPrintf("\n"); + } + nDone++; + nProgress++; + } + } + rFloor = rMin; + }while( nDone0 ); + } +#endif + + /* Swap the roles of aFrom and aTo for the next generation */ + pFrom = aTo; + aTo = aFrom; + aFrom = pFrom; + nFrom = nTo; + } + + if( nFrom==0 ){ + sqlite3ErrorMsg(pParse, "no query solution"); + sqlite3StackFreeNN(pParse->db, pSpace); + return SQLITE_ERROR; + } + + /* Only one path is available, which is the best path */ + assert( nFrom==1 ); + pFrom = aFrom; + + assert( pWInfo->nLevel==nLoop ); + /* Load the lowest cost path into pWInfo */ + for(iLoop=0; iLoopa + iLoop; + pLevel->pWLoop = pWLoop = pFrom->aLoop[iLoop]; + pLevel->iFrom = pWLoop->iTab; + pLevel->iTabCur = pWInfo->pTabList->a[pLevel->iFrom].iCursor; + } + if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)!=0 + && (pWInfo->wctrlFlags & WHERE_DISTINCTBY)==0 + && pWInfo->eDistinct==WHERE_DISTINCT_NOOP + && nRowEst + ){ + Bitmask notUsed; + int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pResultSet, pFrom, + WHERE_DISTINCTBY, nLoop-1, pFrom->aLoop[nLoop-1], ¬Used); + if( rc==pWInfo->pResultSet->nExpr ){ + pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; + } + } + pWInfo->bOrderedInnerLoop = 0; + if( pWInfo->pOrderBy ){ + pWInfo->nOBSat = pFrom->isOrdered; + if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){ + if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){ + pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; + } + /* vvv--- See check-in [12ad822d9b827777] on 2023-03-16 ---vvv */ + assert( pWInfo->pSelect->pOrderBy==0 + || pWInfo->nOBSat <= pWInfo->pSelect->pOrderBy->nExpr ); + }else{ + pWInfo->revMask = pFrom->revLoop; + if( pWInfo->nOBSat<=0 ){ + pWInfo->nOBSat = 0; + if( nLoop>0 ){ + u32 wsFlags = pFrom->aLoop[nLoop-1]->wsFlags; + if( (wsFlags & WHERE_ONEROW)==0 + && (wsFlags&(WHERE_IPK|WHERE_COLUMN_IN))!=(WHERE_IPK|WHERE_COLUMN_IN) + ){ + Bitmask m = 0; + int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, pFrom, + WHERE_ORDERBY_LIMIT, nLoop-1, pFrom->aLoop[nLoop-1], &m); + testcase( wsFlags & WHERE_IPK ); + testcase( wsFlags & WHERE_COLUMN_IN ); + if( rc==pWInfo->pOrderBy->nExpr ){ + pWInfo->bOrderedInnerLoop = 1; + pWInfo->revMask = m; + } + } + } + }else if( nLoop + && pWInfo->nOBSat==1 + && (pWInfo->wctrlFlags & (WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX))!=0 + ){ + pWInfo->bOrderedInnerLoop = 1; + } + } + if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP) + && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr && nLoop>0 + ){ + Bitmask revMask = 0; + int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, + pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], &revMask + ); + assert( pWInfo->sorted==0 ); + if( nOrder==pWInfo->pOrderBy->nExpr ){ + pWInfo->sorted = 1; + pWInfo->revMask = revMask; + } + } + } + + pWInfo->nRowOut = pFrom->nRow; +#ifdef WHERETRACE_ENABLED + pWInfo->rTotalCost = pFrom->rCost; +#endif + + /* Free temporary memory and return success */ + sqlite3StackFreeNN(pParse->db, pSpace); + return SQLITE_OK; +} + +/* +** This routine implements a heuristic designed to improve query planning. +** This routine is called in between the first and second call to +** wherePathSolver(). Hence the name "Interstage" "Heuristic". +** +** The first call to wherePathSolver() (hereafter just "solver()") computes +** the best path without regard to the order of the outputs. The second call +** to the solver() builds upon the first call to try to find an alternative +** path that satisfies the ORDER BY clause. +** +** This routine looks at the results of the first solver() run, and for +** every FROM clause term in the resulting query plan that uses an equality +** constraint against an index, disable other WhereLoops for that same +** FROM clause term that would try to do a full-table scan. This prevents +** an index search from being converted into a full-table scan in order to +** satisfy an ORDER BY clause, since even though we might get slightly better +** performance using the full-scan without sorting if the output size +** estimates are very precise, we might also get severe performance +** degradation using the full-scan if the output size estimate is too large. +** It is better to err on the side of caution. +** +** Except, if the first solver() call generated a full-table scan in an outer +** loop then stop this analysis at the first full-scan, since the second +** solver() run might try to swap that full-scan for another in order to +** get the output into the correct order. In other words, we allow a +** rewrite like this: +** +** First Solver() Second Solver() +** |-- SCAN t1 |-- SCAN t2 +** |-- SEARCH t2 `-- SEARCH t1 +** `-- SORT USING B-TREE +** +** The purpose of this routine is to disallow rewrites such as: +** +** First Solver() Second Solver() +** |-- SEARCH t1 |-- SCAN t2 <--- bad! +** |-- SEARCH t2 `-- SEARCH t1 +** `-- SORT USING B-TREE +** +** See test cases in test/whereN.test for the real-world query that +** originally provoked this heuristic. +*/ +static SQLITE_NOINLINE void whereInterstageHeuristic(WhereInfo *pWInfo){ + int i; +#ifdef WHERETRACE_ENABLED + int once = 0; +#endif + for(i=0; inLevel; i++){ + WhereLoop *p = pWInfo->a[i].pWLoop; + if( p==0 ) break; + if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 ){ + /* Treat a vtab scan as similar to a full-table scan */ + break; + } + if( (p->wsFlags & (WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_IN))!=0 ){ + u8 iTab = p->iTab; + WhereLoop *pLoop; + for(pLoop=pWInfo->pLoops; pLoop; pLoop=pLoop->pNextLoop){ + if( pLoop->iTab!=iTab ) continue; + if( (pLoop->wsFlags & (WHERE_CONSTRAINT|WHERE_AUTO_INDEX))!=0 ){ + /* Auto-index and index-constrained loops allowed to remain */ + continue; + } +#ifdef WHERETRACE_ENABLED + if( sqlite3WhereTrace & 0x80 ){ + if( once==0 ){ + sqlite3DebugPrintf("Loops disabled by interstage heuristic:\n"); + once = 1; + } + sqlite3WhereLoopPrint(pLoop, &pWInfo->sWC); + } +#endif /* WHERETRACE_ENABLED */ + pLoop->prereq = ALLBITS; /* Prevent 2nd solver() from using this one */ + } + }else{ + break; + } + } +} + +/* +** Most queries use only a single table (they are not joins) and have +** simple == constraints against indexed fields. This routine attempts +** to plan those simple cases using much less ceremony than the +** general-purpose query planner, and thereby yield faster sqlite3_prepare() +** times for the common case. +** +** Return non-zero on success, if this query can be handled by this +** no-frills query planner. Return zero if this query needs the +** general-purpose query planner. +*/ +static int whereShortCut(WhereLoopBuilder *pBuilder){ + WhereInfo *pWInfo; + SrcItem *pItem; + WhereClause *pWC; + WhereTerm *pTerm; + WhereLoop *pLoop; + int iCur; + int j; + Table *pTab; + Index *pIdx; + WhereScan scan; + + pWInfo = pBuilder->pWInfo; + if( pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE ) return 0; + assert( pWInfo->pTabList->nSrc>=1 ); + pItem = pWInfo->pTabList->a; + pTab = pItem->pSTab; + if( IsVirtual(pTab) ) return 0; + if( pItem->fg.isIndexedBy || pItem->fg.notIndexed ){ + testcase( pItem->fg.isIndexedBy ); + testcase( pItem->fg.notIndexed ); + return 0; + } + iCur = pItem->iCursor; + pWC = &pWInfo->sWC; + pLoop = pBuilder->pNew; + pLoop->wsFlags = 0; + pLoop->nSkip = 0; + pTerm = whereScanInit(&scan, pWC, iCur, -1, WO_EQ|WO_IS, 0); + while( pTerm && pTerm->prereqRight ) pTerm = whereScanNext(&scan); + if( pTerm ){ + testcase( pTerm->eOperator & WO_IS ); + pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW; + pLoop->aLTerm[0] = pTerm; + pLoop->nLTerm = 1; + pLoop->u.btree.nEq = 1; + /* TUNING: Cost of a rowid lookup is 10 */ + pLoop->rRun = 33; /* 33==sqlite3LogEst(10) */ + }else{ + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + int opMask; + assert( pLoop->aLTermSpace==pLoop->aLTerm ); + if( !IsUniqueIndex(pIdx) + || pIdx->pPartIdxWhere!=0 + || pIdx->nKeyCol>ArraySize(pLoop->aLTermSpace) + ) continue; + opMask = pIdx->uniqNotNull ? (WO_EQ|WO_IS) : WO_EQ; + for(j=0; jnKeyCol; j++){ + pTerm = whereScanInit(&scan, pWC, iCur, j, opMask, pIdx); + while( pTerm && pTerm->prereqRight ) pTerm = whereScanNext(&scan); + if( pTerm==0 ) break; + testcase( pTerm->eOperator & WO_IS ); + pLoop->aLTerm[j] = pTerm; + } + if( j!=pIdx->nKeyCol ) continue; + pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW|WHERE_INDEXED; + if( pIdx->isCovering || (pItem->colUsed & pIdx->colNotIdxed)==0 ){ + pLoop->wsFlags |= WHERE_IDX_ONLY; + } + pLoop->nLTerm = j; + pLoop->u.btree.nEq = j; + pLoop->u.btree.pIndex = pIdx; + /* TUNING: Cost of a unique index lookup is 15 */ + pLoop->rRun = 39; /* 39==sqlite3LogEst(15) */ + break; + } + } + if( pLoop->wsFlags ){ + pLoop->nOut = (LogEst)1; + pWInfo->a[0].pWLoop = pLoop; + assert( pWInfo->sMaskSet.n==1 && iCur==pWInfo->sMaskSet.ix[0] ); + pLoop->maskSelf = 1; /* sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); */ + pWInfo->a[0].iTabCur = iCur; + pWInfo->nRowOut = 1; + if( pWInfo->pOrderBy ) pWInfo->nOBSat = pWInfo->pOrderBy->nExpr; + if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){ + pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; + } + if( scan.iEquiv>1 ) pLoop->wsFlags |= WHERE_TRANSCONS; +#ifdef SQLITE_DEBUG + pLoop->cId = '0'; +#endif +#ifdef WHERETRACE_ENABLED + if( sqlite3WhereTrace & 0x02 ){ + sqlite3DebugPrintf("whereShortCut() used to compute solution\n"); + } +#endif + return 1; + } + return 0; +} + +/* +** Helper function for exprIsDeterministic(). +*/ +static int exprNodeIsDeterministic(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_FUNCTION && ExprHasProperty(pExpr, EP_ConstFunc)==0 ){ + pWalker->eCode = 0; + return WRC_Abort; + } + return WRC_Continue; +} + +/* +** Return true if the expression contains no non-deterministic SQL +** functions. Do not consider non-deterministic SQL functions that are +** part of sub-select statements. +*/ +static int exprIsDeterministic(Expr *p){ + Walker w; + memset(&w, 0, sizeof(w)); + w.eCode = 1; + w.xExprCallback = exprNodeIsDeterministic; + w.xSelectCallback = sqlite3SelectWalkFail; + sqlite3WalkExpr(&w, p); + return w.eCode; +} + + +#ifdef WHERETRACE_ENABLED +/* +** Display all WhereLoops in pWInfo +*/ +static void showAllWhereLoops(WhereInfo *pWInfo, WhereClause *pWC){ + if( sqlite3WhereTrace ){ /* Display all of the WhereLoop objects */ + WhereLoop *p; + int i; + static const char zLabel[] = "0123456789abcdefghijklmnopqrstuvwyxz" + "ABCDEFGHIJKLMNOPQRSTUVWYXZ"; + for(p=pWInfo->pLoops, i=0; p; p=p->pNextLoop, i++){ + p->cId = zLabel[i%(sizeof(zLabel)-1)]; + sqlite3WhereLoopPrint(p, pWC); + } + } +} +# define WHERETRACE_ALL_LOOPS(W,C) showAllWhereLoops(W,C) +#else +# define WHERETRACE_ALL_LOOPS(W,C) +#endif + +/* Attempt to omit tables from a join that do not affect the result. +** For a table to not affect the result, the following must be true: +** +** 1) The query must not be an aggregate. +** 2) The table must be the RHS of a LEFT JOIN. +** 3) Either the query must be DISTINCT, or else the ON or USING clause +** must contain a constraint that limits the scan of the table to +** at most a single row. +** 4) The table must not be referenced by any part of the query apart +** from its own USING or ON clause. +** 5) The table must not have an inner-join ON or USING clause if there is +** a RIGHT JOIN anywhere in the query. Otherwise the ON/USING clause +** might move from the right side to the left side of the RIGHT JOIN. +** Note: Due to (2), this condition can only arise if the table is +** the right-most table of a subquery that was flattened into the +** main query and that subquery was the right-hand operand of an +** inner join that held an ON or USING clause. +** 6) The ORDER BY clause has 63 or fewer terms +** 7) The omit-noop-join optimization is enabled. +** +** Items (1), (6), and (7) are checked by the caller. +** +** For example, given: +** +** CREATE TABLE t1(ipk INTEGER PRIMARY KEY, v1); +** CREATE TABLE t2(ipk INTEGER PRIMARY KEY, v2); +** CREATE TABLE t3(ipk INTEGER PRIMARY KEY, v3); +** +** then table t2 can be omitted from the following: +** +** SELECT v1, v3 FROM t1 +** LEFT JOIN t2 ON (t1.ipk=t2.ipk) +** LEFT JOIN t3 ON (t1.ipk=t3.ipk) +** +** or from: +** +** SELECT DISTINCT v1, v3 FROM t1 +** LEFT JOIN t2 +** LEFT JOIN t3 ON (t1.ipk=t3.ipk) +*/ +static SQLITE_NOINLINE Bitmask whereOmitNoopJoin( + WhereInfo *pWInfo, + Bitmask notReady +){ + int i; + Bitmask tabUsed; + int hasRightJoin; + + /* Preconditions checked by the caller */ + assert( pWInfo->nLevel>=2 ); + assert( OptimizationEnabled(pWInfo->pParse->db, SQLITE_OmitNoopJoin) ); + + /* These two preconditions checked by the caller combine to guarantee + ** condition (1) of the header comment */ + assert( pWInfo->pResultSet!=0 ); + assert( 0==(pWInfo->wctrlFlags & WHERE_AGG_DISTINCT) ); + + tabUsed = sqlite3WhereExprListUsage(&pWInfo->sMaskSet, pWInfo->pResultSet); + if( pWInfo->pOrderBy ){ + tabUsed |= sqlite3WhereExprListUsage(&pWInfo->sMaskSet, pWInfo->pOrderBy); + } + hasRightJoin = (pWInfo->pTabList->a[0].fg.jointype & JT_LTORJ)!=0; + for(i=pWInfo->nLevel-1; i>=1; i--){ + WhereTerm *pTerm, *pEnd; + SrcItem *pItem; + WhereLoop *pLoop; + Bitmask m1; + pLoop = pWInfo->a[i].pWLoop; + pItem = &pWInfo->pTabList->a[pLoop->iTab]; + if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ) continue; + if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)==0 + && (pLoop->wsFlags & WHERE_ONEROW)==0 + ){ + continue; + } + if( (tabUsed & pLoop->maskSelf)!=0 ) continue; + pEnd = pWInfo->sWC.a + pWInfo->sWC.nTerm; + for(pTerm=pWInfo->sWC.a; pTermprereqAll & pLoop->maskSelf)!=0 ){ + if( !ExprHasProperty(pTerm->pExpr, EP_OuterON) + || pTerm->pExpr->w.iJoin!=pItem->iCursor + ){ + break; + } + } + if( hasRightJoin + && ExprHasProperty(pTerm->pExpr, EP_InnerON) + && NEVER(pTerm->pExpr->w.iJoin==pItem->iCursor) + ){ + break; /* restriction (5) */ + } + } + if( pTerm omit unused FROM-clause term %c\n",pLoop->cId)); + m1 = MASKBIT(i)-1; + testcase( ((pWInfo->revMask>>1) & ~m1)!=0 ); + pWInfo->revMask = (m1 & pWInfo->revMask) | ((pWInfo->revMask>>1) & ~m1); + notReady &= ~pLoop->maskSelf; + for(pTerm=pWInfo->sWC.a; pTermprereqAll & pLoop->maskSelf)!=0 ){ + pTerm->wtFlags |= TERM_CODED; + pTerm->prereqAll = 0; + } + } + if( i!=pWInfo->nLevel-1 ){ + int nByte = (pWInfo->nLevel-1-i) * sizeof(WhereLevel); + memmove(&pWInfo->a[i], &pWInfo->a[i+1], nByte); + } + pWInfo->nLevel--; + assert( pWInfo->nLevel>0 ); + } + return notReady; +} + +/* +** Check to see if there are any SEARCH loops that might benefit from +** using a Bloom filter. Consider a Bloom filter if: +** +** (1) The SEARCH happens more than N times where N is the number +** of rows in the table that is being considered for the Bloom +** filter. +** (2) Some searches are expected to find zero rows. (This is determined +** by the WHERE_SELFCULL flag on the term.) +** (3) Bloom-filter processing is not disabled. (Checked by the +** caller.) +** (4) The size of the table being searched is known by ANALYZE. +** +** This block of code merely checks to see if a Bloom filter would be +** appropriate, and if so sets the WHERE_BLOOMFILTER flag on the +** WhereLoop. The implementation of the Bloom filter comes further +** down where the code for each WhereLoop is generated. +*/ +static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful( + const WhereInfo *pWInfo +){ + int i; + LogEst nSearch = 0; + + assert( pWInfo->nLevel>=2 ); + assert( OptimizationEnabled(pWInfo->pParse->db, SQLITE_BloomFilter) ); + for(i=0; inLevel; i++){ + WhereLoop *pLoop = pWInfo->a[i].pWLoop; + const unsigned int reqFlags = (WHERE_SELFCULL|WHERE_COLUMN_EQ); + SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab]; + Table *pTab = pItem->pSTab; + if( (pTab->tabFlags & TF_HasStat1)==0 ) break; + pTab->tabFlags |= TF_MaybeReanalyze; + if( i>=1 + && (pLoop->wsFlags & reqFlags)==reqFlags + /* vvvvvv--- Always the case if WHERE_COLUMN_EQ is defined */ + && ALWAYS((pLoop->wsFlags & (WHERE_IPK|WHERE_INDEXED))!=0) + ){ + if( nSearch > pTab->nRowLogEst ){ + testcase( pItem->fg.jointype & JT_LEFT ); + pLoop->wsFlags |= WHERE_BLOOMFILTER; + pLoop->wsFlags &= ~WHERE_IDX_ONLY; + WHERETRACE(0xffffffff, ( + "-> use Bloom-filter on loop %c because there are ~%.1e " + "lookups into %s which has only ~%.1e rows\n", + pLoop->cId, (double)sqlite3LogEstToInt(nSearch), pTab->zName, + (double)sqlite3LogEstToInt(pTab->nRowLogEst))); + } + } + nSearch += pLoop->nOut; + } +} + +/* +** The index pIdx is used by a query and contains one or more expressions. +** In other words pIdx is an index on an expression. iIdxCur is the cursor +** number for the index and iDataCur is the cursor number for the corresponding +** table. +** +** This routine adds IndexedExpr entries to the Parse->pIdxEpr field for +** each of the expressions in the index so that the expression code generator +** will know to replace occurrences of the indexed expression with +** references to the corresponding column of the index. +*/ +static SQLITE_NOINLINE void whereAddIndexedExpr( + Parse *pParse, /* Add IndexedExpr entries to pParse->pIdxEpr */ + Index *pIdx, /* The index-on-expression that contains the expressions */ + int iIdxCur, /* Cursor number for pIdx */ + SrcItem *pTabItem /* The FROM clause entry for the table */ +){ + int i; + IndexedExpr *p; + Table *pTab; + assert( pIdx->bHasExpr ); + pTab = pIdx->pTable; + for(i=0; inColumn; i++){ + Expr *pExpr; + int j = pIdx->aiColumn[i]; + if( j==XN_EXPR ){ + pExpr = pIdx->aColExpr->a[i].pExpr; + }else if( j>=0 && (pTab->aCol[j].colFlags & COLFLAG_VIRTUAL)!=0 ){ + pExpr = sqlite3ColumnExpr(pTab, &pTab->aCol[j]); + }else{ + continue; + } + if( sqlite3ExprIsConstant(0,pExpr) ) continue; + p = sqlite3DbMallocRaw(pParse->db, sizeof(IndexedExpr)); + if( p==0 ) break; + p->pIENext = pParse->pIdxEpr; +#ifdef WHERETRACE_ENABLED + if( sqlite3WhereTrace & 0x200 ){ + sqlite3DebugPrintf("New pParse->pIdxEpr term {%d,%d}\n", iIdxCur, i); + if( sqlite3WhereTrace & 0x5000 ) sqlite3ShowExpr(pExpr); + } +#endif + p->pExpr = sqlite3ExprDup(pParse->db, pExpr, 0); + p->iDataCur = pTabItem->iCursor; + p->iIdxCur = iIdxCur; + p->iIdxCol = i; + p->bMaybeNullRow = (pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0; + if( sqlite3IndexAffinityStr(pParse->db, pIdx) ){ + p->aff = pIdx->zColAff[i]; + } +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + p->zIdxName = pIdx->zName; +#endif + pParse->pIdxEpr = p; + if( p->pIENext==0 ){ + void *pArg = (void*)&pParse->pIdxEpr; + sqlite3ParserAddCleanup(pParse, whereIndexedExprCleanup, pArg); + } + } +} + +/* +** Set the reverse-scan order mask to one for all tables in the query +** with the exception of MATERIALIZED common table expressions that have +** their own internal ORDER BY clauses. +** +** This implements the PRAGMA reverse_unordered_selects=ON setting. +** (Also SQLITE_DBCONFIG_REVERSE_SCANORDER). +*/ +static SQLITE_NOINLINE void whereReverseScanOrder(WhereInfo *pWInfo){ + int ii; + for(ii=0; iipTabList->nSrc; ii++){ + SrcItem *pItem = &pWInfo->pTabList->a[ii]; + if( !pItem->fg.isCte + || pItem->u2.pCteUse->eM10d!=M10d_Yes + || NEVER(pItem->fg.isSubquery==0) + || pItem->u4.pSubq->pSelect->pOrderBy==0 + ){ + pWInfo->revMask |= MASKBIT(ii); + } + } +} + +/* +** Generate the beginning of the loop used for WHERE clause processing. +** The return value is a pointer to an opaque structure that contains +** information needed to terminate the loop. Later, the calling routine +** should invoke sqlite3WhereEnd() with the return value of this function +** in order to complete the WHERE clause processing. +** +** If an error occurs, this routine returns NULL. +** +** The basic idea is to do a nested loop, one loop for each table in +** the FROM clause of a select. (INSERT and UPDATE statements are the +** same as a SELECT with only a single table in the FROM clause.) For +** example, if the SQL is this: +** +** SELECT * FROM t1, t2, t3 WHERE ...; +** +** Then the code generated is conceptually like the following: +** +** foreach row1 in t1 do \ Code generated +** foreach row2 in t2 do |-- by sqlite3WhereBegin() +** foreach row3 in t3 do / +** ... +** end \ Code generated +** end |-- by sqlite3WhereEnd() +** end / +** +** Note that the loops might not be nested in the order in which they +** appear in the FROM clause if a different order is better able to make +** use of indices. Note also that when the IN operator appears in +** the WHERE clause, it might result in additional nested loops for +** scanning through all values on the right-hand side of the IN. +** +** There are Btree cursors associated with each table. t1 uses cursor +** number pTabList->a[0].iCursor. t2 uses the cursor pTabList->a[1].iCursor. +** And so forth. This routine generates code to open those VDBE cursors +** and sqlite3WhereEnd() generates the code to close them. +** +** The code that sqlite3WhereBegin() generates leaves the cursors named +** in pTabList pointing at their appropriate entries. The [...] code +** can use OP_Column and OP_Rowid opcodes on these cursors to extract +** data from the various tables of the loop. +** +** If the WHERE clause is empty, the foreach loops must each scan their +** entire tables. Thus a three-way join is an O(N^3) operation. But if +** the tables have indices and there are terms in the WHERE clause that +** refer to those indices, a complete table scan can be avoided and the +** code will run much faster. Most of the work of this routine is checking +** to see if there are indices that can be used to speed up the loop. +** +** Terms of the WHERE clause are also used to limit which rows actually +** make it to the "..." in the middle of the loop. After each "foreach", +** terms of the WHERE clause that use only terms in that loop and outer +** loops are evaluated and if false a jump is made around all subsequent +** inner loops (or around the "..." if the test occurs within the inner- +** most loop) +** +** OUTER JOINS +** +** An outer join of tables t1 and t2 is conceptually coded as follows: +** +** foreach row1 in t1 do +** flag = 0 +** foreach row2 in t2 do +** start: +** ... +** flag = 1 +** end +** if flag==0 then +** move the row2 cursor to a null row +** goto start +** fi +** end +** +** ORDER BY CLAUSE PROCESSING +** +** pOrderBy is a pointer to the ORDER BY clause (or the GROUP BY clause +** if the WHERE_GROUPBY flag is set in wctrlFlags) of a SELECT statement +** if there is one. If there is no ORDER BY clause or if this routine +** is called from an UPDATE or DELETE statement, then pOrderBy is NULL. +** +** The iIdxCur parameter is the cursor number of an index. If +** WHERE_OR_SUBCLAUSE is set, iIdxCur is the cursor number of an index +** to use for OR clause processing. The WHERE clause should use this +** specific cursor. If WHERE_ONEPASS_DESIRED is set, then iIdxCur is +** the first cursor in an array of cursors for all indices. iIdxCur should +** be used to compute the appropriate cursor depending on which index is +** used. +*/ +SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( + Parse *pParse, /* The parser context */ + SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */ + Expr *pWhere, /* The WHERE clause */ + ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */ + ExprList *pResultSet, /* Query result set. Req'd for DISTINCT */ + Select *pSelect, /* The entire SELECT statement */ + u16 wctrlFlags, /* The WHERE_* flags defined in sqliteInt.h */ + int iAuxArg /* If WHERE_OR_SUBCLAUSE is set, index cursor number + ** If WHERE_USE_LIMIT, then the limit amount */ +){ + int nByteWInfo; /* Num. bytes allocated for WhereInfo struct */ + int nTabList; /* Number of elements in pTabList */ + WhereInfo *pWInfo; /* Will become the return value of this function */ + Vdbe *v = pParse->pVdbe; /* The virtual database engine */ + Bitmask notReady; /* Cursors that are not yet positioned */ + WhereLoopBuilder sWLB; /* The WhereLoop builder */ + WhereMaskSet *pMaskSet; /* The expression mask set */ + WhereLevel *pLevel; /* A single level in pWInfo->a[] */ + WhereLoop *pLoop; /* Pointer to a single WhereLoop object */ + int ii; /* Loop counter */ + sqlite3 *db; /* Database connection */ + int rc; /* Return code */ + u8 bFordelete = 0; /* OPFLAG_FORDELETE or zero, as appropriate */ + + assert( (wctrlFlags & WHERE_ONEPASS_MULTIROW)==0 || ( + (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 + && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0 + )); + + /* Only one of WHERE_OR_SUBCLAUSE or WHERE_USE_LIMIT */ + assert( (wctrlFlags & WHERE_OR_SUBCLAUSE)==0 + || (wctrlFlags & WHERE_USE_LIMIT)==0 ); + + /* Variable initialization */ + db = pParse->db; + memset(&sWLB, 0, sizeof(sWLB)); + + /* An ORDER/GROUP BY clause of more than 63 terms cannot be optimized */ + testcase( pOrderBy && pOrderBy->nExpr==BMS-1 ); + if( pOrderBy && pOrderBy->nExpr>=BMS ){ + pOrderBy = 0; + wctrlFlags &= ~WHERE_WANT_DISTINCT; + wctrlFlags |= WHERE_KEEP_ALL_JOINS; /* Disable omit-noop-join opt */ + } + + /* The number of tables in the FROM clause is limited by the number of + ** bits in a Bitmask + */ + testcase( pTabList->nSrc==BMS ); + if( pTabList->nSrc>BMS ){ + sqlite3ErrorMsg(pParse, "at most %d tables in a join", BMS); + return 0; + } + + /* This function normally generates a nested loop for all tables in + ** pTabList. But if the WHERE_OR_SUBCLAUSE flag is set, then we should + ** only generate code for the first table in pTabList and assume that + ** any cursors associated with subsequent tables are uninitialized. + */ + nTabList = (wctrlFlags & WHERE_OR_SUBCLAUSE) ? 1 : pTabList->nSrc; + + /* Allocate and initialize the WhereInfo structure that will become the + ** return value. A single allocation is used to store the WhereInfo + ** struct, the contents of WhereInfo.a[], the WhereClause structure + ** and the WhereMaskSet structure. Since WhereClause contains an 8-byte + ** field (type Bitmask) it must be aligned on an 8-byte boundary on + ** some architectures. Hence the ROUND8() below. + */ + nByteWInfo = SZ_WHEREINFO(nTabList); + pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop)); + if( db->mallocFailed ){ + sqlite3DbFree(db, pWInfo); + pWInfo = 0; + goto whereBeginError; + } + pWInfo->pParse = pParse; + pWInfo->pTabList = pTabList; + pWInfo->pOrderBy = pOrderBy; +#if WHERETRACE_ENABLED + pWInfo->pWhere = pWhere; +#endif + pWInfo->pResultSet = pResultSet; + pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1; + pWInfo->nLevel = nTabList; + pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(pParse); + pWInfo->wctrlFlags = wctrlFlags; + pWInfo->iLimit = iAuxArg; + pWInfo->savedNQueryLoop = pParse->nQueryLoop; + pWInfo->pSelect = pSelect; + memset(&pWInfo->nOBSat, 0, + offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat)); + memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel)); + assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */ + pMaskSet = &pWInfo->sMaskSet; + pMaskSet->n = 0; + pMaskSet->ix[0] = -99; /* Initialize ix[0] to a value that can never be + ** a valid cursor number, to avoid an initial + ** test for pMaskSet->n==0 in sqlite3WhereGetMask() */ + sWLB.pWInfo = pWInfo; + sWLB.pWC = &pWInfo->sWC; + sWLB.pNew = (WhereLoop*)(((char*)pWInfo)+nByteWInfo); + assert( EIGHT_BYTE_ALIGNMENT(sWLB.pNew) ); + whereLoopInit(sWLB.pNew); +#ifdef SQLITE_DEBUG + sWLB.pNew->cId = '*'; +#endif + + /* Split the WHERE clause into separate subexpressions where each + ** subexpression is separated by an AND operator. + */ + sqlite3WhereClauseInit(&pWInfo->sWC, pWInfo); + sqlite3WhereSplit(&pWInfo->sWC, pWhere, TK_AND); + + /* Special case: No FROM clause + */ + if( nTabList==0 ){ + if( pOrderBy ) pWInfo->nOBSat = pOrderBy->nExpr; + if( (wctrlFlags & WHERE_WANT_DISTINCT)!=0 + && OptimizationEnabled(db, SQLITE_DistinctOpt) + ){ + pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; + } + if( ALWAYS(pWInfo->pSelect) + && (pWInfo->pSelect->selFlags & SF_MultiValue)==0 + ){ + ExplainQueryPlan((pParse, 0, "SCAN CONSTANT ROW")); + } + }else{ + /* Assign a bit from the bitmask to every term in the FROM clause. + ** + ** The N-th term of the FROM clause is assigned a bitmask of 1<nSrc tables in + ** pTabList, not just the first nTabList tables. nTabList is normally + ** equal to pTabList->nSrc but might be shortened to 1 if the + ** WHERE_OR_SUBCLAUSE flag is set. + */ + ii = 0; + do{ + createMask(pMaskSet, pTabList->a[ii].iCursor); + sqlite3WhereTabFuncArgs(pParse, &pTabList->a[ii], &pWInfo->sWC); + }while( (++ii)nSrc ); + #ifdef SQLITE_DEBUG + { + Bitmask mx = 0; + for(ii=0; iinSrc; ii++){ + Bitmask m = sqlite3WhereGetMask(pMaskSet, pTabList->a[ii].iCursor); + assert( m>=mx ); + mx = m; + } + } + #endif + } + + /* Analyze all of the subexpressions. */ + sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC); + if( pSelect && pSelect->pLimit ){ + sqlite3WhereAddLimit(&pWInfo->sWC, pSelect); + } + if( pParse->nErr ) goto whereBeginError; + + /* The False-WHERE-Term-Bypass optimization: + ** + ** If there are WHERE terms that are false, then no rows will be output, + ** so skip over all of the code generated here. + ** + ** Conditions: + ** + ** (1) The WHERE term must not refer to any tables in the join. + ** (2) The term must not come from an ON clause on the + ** right-hand side of a LEFT or FULL JOIN. + ** (3) The term must not come from an ON clause, or there must be + ** no RIGHT or FULL OUTER joins in pTabList. + ** (4) If the expression contains non-deterministic functions + ** that are not within a sub-select. This is not required + ** for correctness but rather to preserves SQLite's legacy + ** behaviour in the following two cases: + ** + ** WHERE random()>0; -- eval random() once per row + ** WHERE (SELECT random())>0; -- eval random() just once overall + ** + ** Note that the Where term need not be a constant in order for this + ** optimization to apply, though it does need to be constant relative to + ** the current subquery (condition 1). The term might include variables + ** from outer queries so that the value of the term changes from one + ** invocation of the current subquery to the next. + */ + for(ii=0; iinBase; ii++){ + WhereTerm *pT = &sWLB.pWC->a[ii]; /* A term of the WHERE clause */ + Expr *pX; /* The expression of pT */ + if( pT->wtFlags & TERM_VIRTUAL ) continue; + pX = pT->pExpr; + assert( pX!=0 ); + assert( pT->prereqAll!=0 || !ExprHasProperty(pX, EP_OuterON) ); + if( pT->prereqAll==0 /* Conditions (1) and (2) */ + && (nTabList==0 || exprIsDeterministic(pX)) /* Condition (4) */ + && !(ExprHasProperty(pX, EP_InnerON) /* Condition (3) */ + && (pTabList->a[0].fg.jointype & JT_LTORJ)!=0 ) + ){ + sqlite3ExprIfFalse(pParse, pX, pWInfo->iBreak, SQLITE_JUMPIFNULL); + pT->wtFlags |= TERM_CODED; + } + } + + if( wctrlFlags & WHERE_WANT_DISTINCT ){ + if( OptimizationDisabled(db, SQLITE_DistinctOpt) ){ + /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via + ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */ + wctrlFlags &= ~WHERE_WANT_DISTINCT; + pWInfo->wctrlFlags &= ~WHERE_WANT_DISTINCT; + }else if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){ + /* The DISTINCT marking is pointless. Ignore it. */ + pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; + }else if( pOrderBy==0 ){ + /* Try to ORDER BY the result set to make distinct processing easier */ + pWInfo->wctrlFlags |= WHERE_DISTINCTBY; + pWInfo->pOrderBy = pResultSet; + } + } + + /* Construct the WhereLoop objects */ +#if defined(WHERETRACE_ENABLED) + if( sqlite3WhereTrace & 0xffffffff ){ + sqlite3DebugPrintf("*** Optimizer Start *** (wctrlFlags: 0x%x",wctrlFlags); + if( wctrlFlags & WHERE_USE_LIMIT ){ + sqlite3DebugPrintf(", limit: %d", iAuxArg); + } + sqlite3DebugPrintf(")\n"); + if( sqlite3WhereTrace & 0x8000 ){ + Select sSelect; + memset(&sSelect, 0, sizeof(sSelect)); + sSelect.selFlags = SF_WhereBegin; + sSelect.pSrc = pTabList; + sSelect.pWhere = pWhere; + sSelect.pOrderBy = pOrderBy; + sSelect.pEList = pResultSet; + sqlite3TreeViewSelect(0, &sSelect, 0); + } + if( sqlite3WhereTrace & 0x4000 ){ /* Display all WHERE clause terms */ + sqlite3DebugPrintf("---- WHERE clause at start of analysis:\n"); + sqlite3WhereClausePrint(sWLB.pWC); + } + } +#endif + + if( nTabList!=1 || whereShortCut(&sWLB)==0 ){ + rc = whereLoopAddAll(&sWLB); + if( rc ) goto whereBeginError; + +#ifdef SQLITE_ENABLE_STAT4 + /* If one or more WhereTerm.truthProb values were used in estimating + ** loop parameters, but then those truthProb values were subsequently + ** changed based on STAT4 information while computing subsequent loops, + ** then we need to rerun the whole loop building process so that all + ** loops will be built using the revised truthProb values. */ + if( sWLB.bldFlags2 & SQLITE_BLDF2_2NDPASS ){ + WHERETRACE_ALL_LOOPS(pWInfo, sWLB.pWC); + WHERETRACE(0xffffffff, + ("**** Redo all loop computations due to" + " TERM_HIGHTRUTH changes ****\n")); + while( pWInfo->pLoops ){ + WhereLoop *p = pWInfo->pLoops; + pWInfo->pLoops = p->pNextLoop; + whereLoopDelete(db, p); + } + rc = whereLoopAddAll(&sWLB); + if( rc ) goto whereBeginError; + } +#endif + WHERETRACE_ALL_LOOPS(pWInfo, sWLB.pWC); + + wherePathSolver(pWInfo, 0); + if( db->mallocFailed ) goto whereBeginError; + if( pWInfo->pOrderBy ){ + whereInterstageHeuristic(pWInfo); + wherePathSolver(pWInfo, pWInfo->nRowOut<0 ? 1 : pWInfo->nRowOut+1); + if( db->mallocFailed ) goto whereBeginError; + } + + /* TUNING: Assume that a DISTINCT clause on a subquery reduces + ** the output size by a factor of 8 (LogEst -30). Search for + ** tag-20250414a to see other cases. + */ + if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)!=0 ){ + WHERETRACE(0x0080,("nRowOut reduced from %d to %d due to DISTINCT\n", + pWInfo->nRowOut, pWInfo->nRowOut-30)); + pWInfo->nRowOut -= 30; + } + + } + assert( pWInfo->pTabList!=0 ); + if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){ + whereReverseScanOrder(pWInfo); + } + if( pParse->nErr ){ + goto whereBeginError; + } + assert( db->mallocFailed==0 ); +#ifdef WHERETRACE_ENABLED + if( sqlite3WhereTrace ){ + sqlite3DebugPrintf("---- Solution cost=%d, nRow=%d", + pWInfo->rTotalCost, pWInfo->nRowOut); + if( pWInfo->nOBSat>0 ){ + sqlite3DebugPrintf(" ORDERBY=%d,0x%llx", pWInfo->nOBSat, pWInfo->revMask); + } + switch( pWInfo->eDistinct ){ + case WHERE_DISTINCT_UNIQUE: { + sqlite3DebugPrintf(" DISTINCT=unique"); + break; + } + case WHERE_DISTINCT_ORDERED: { + sqlite3DebugPrintf(" DISTINCT=ordered"); + break; + } + case WHERE_DISTINCT_UNORDERED: { + sqlite3DebugPrintf(" DISTINCT=unordered"); + break; + } + } + sqlite3DebugPrintf("\n"); + for(ii=0; iinLevel; ii++){ + sqlite3WhereLoopPrint(pWInfo->a[ii].pWLoop, sWLB.pWC); + } + } +#endif + + /* Attempt to omit tables from a join that do not affect the result. + ** See the comment on whereOmitNoopJoin() for further information. + ** + ** This query optimization is factored out into a separate "no-inline" + ** procedure to keep the sqlite3WhereBegin() procedure from becoming + ** too large. If sqlite3WhereBegin() becomes too large, that prevents + ** some C-compiler optimizers from in-lining the + ** sqlite3WhereCodeOneLoopStart() procedure, and it is important to + ** in-line sqlite3WhereCodeOneLoopStart() for performance reasons. + */ + notReady = ~(Bitmask)0; + if( pWInfo->nLevel>=2 /* Must be a join, or this opt8n is pointless */ + && pResultSet!=0 /* Condition (1) */ + && 0==(wctrlFlags & (WHERE_AGG_DISTINCT|WHERE_KEEP_ALL_JOINS)) /* (1),(6) */ + && OptimizationEnabled(db, SQLITE_OmitNoopJoin) /* (7) */ + ){ + notReady = whereOmitNoopJoin(pWInfo, notReady); + nTabList = pWInfo->nLevel; + assert( nTabList>0 ); + } + + /* Check to see if there are any SEARCH loops that might benefit from + ** using a Bloom filter. + */ + if( pWInfo->nLevel>=2 + && OptimizationEnabled(db, SQLITE_BloomFilter) + ){ + whereCheckIfBloomFilterIsUseful(pWInfo); + } + +#if defined(WHERETRACE_ENABLED) + if( sqlite3WhereTrace & 0x4000 ){ /* Display all terms of the WHERE clause */ + sqlite3DebugPrintf("---- WHERE clause at end of analysis:\n"); + sqlite3WhereClausePrint(sWLB.pWC); + } + WHERETRACE(0xffffffff,("*** Optimizer Finished ***\n")); +#endif + pWInfo->pParse->nQueryLoop += pWInfo->nRowOut; + + /* If the caller is an UPDATE or DELETE statement that is requesting + ** to use a one-pass algorithm, determine if this is appropriate. + ** + ** A one-pass approach can be used if the caller has requested one + ** and either (a) the scan visits at most one row or (b) each + ** of the following are true: + ** + ** * the caller has indicated that a one-pass approach can be used + ** with multiple rows (by setting WHERE_ONEPASS_MULTIROW), and + ** * the table is not a virtual table, and + ** * either the scan does not use the OR optimization or the caller + ** is a DELETE operation (WHERE_DUPLICATES_OK is only specified + ** for DELETE). + ** + ** The last qualification is because an UPDATE statement uses + ** WhereInfo.aiCurOnePass[1] to determine whether or not it really can + ** use a one-pass approach, and this is not set accurately for scans + ** that use the OR optimization. + */ + assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 ); + if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){ + int wsFlags = pWInfo->a[0].pWLoop->wsFlags; + int bOnerow = (wsFlags & WHERE_ONEROW)!=0; + assert( !(wsFlags&WHERE_VIRTUALTABLE) || IsVirtual(pTabList->a[0].pSTab) ); + if( bOnerow || ( + 0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW) + && !IsVirtual(pTabList->a[0].pSTab) + && (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK)) + && OptimizationEnabled(db, SQLITE_OnePass) + )){ + pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI; + if( HasRowid(pTabList->a[0].pSTab) && (wsFlags & WHERE_IDX_ONLY) ){ + if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){ + bFordelete = OPFLAG_FORDELETE; + } + pWInfo->a[0].pWLoop->wsFlags = (wsFlags & ~WHERE_IDX_ONLY); + } + } + } + + /* Open all tables in the pTabList and any indices selected for + ** searching those tables. + */ + for(ii=0, pLevel=pWInfo->a; iia[pLevel->iFrom]; + pTab = pTabItem->pSTab; + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + pLoop = pLevel->pWLoop; + pLevel->addrBrk = sqlite3VdbeMakeLabel(pParse); + if( ii==0 || (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){ + pLevel->addrHalt = pLevel->addrBrk; + }else if( pWInfo->a[ii-1].pRJ ){ + pLevel->addrHalt = pWInfo->a[ii-1].addrBrk; + }else{ + pLevel->addrHalt = pWInfo->a[ii-1].addrHalt; + } + if( (pTab->tabFlags & TF_Ephemeral)!=0 || IsView(pTab) ){ + /* Do nothing */ + }else +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){ + const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); + int iCur = pTabItem->iCursor; + sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB); + }else if( IsVirtual(pTab) ){ + /* noop */ + }else +#endif + if( ((pLoop->wsFlags & WHERE_IDX_ONLY)==0 + && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0) + || (pTabItem->fg.jointype & (JT_LTORJ|JT_RIGHT))!=0 + ){ + int op = OP_OpenRead; + if( pWInfo->eOnePass!=ONEPASS_OFF ){ + op = OP_OpenWrite; + pWInfo->aiCurOnePass[0] = pTabItem->iCursor; + }; + sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op); + assert( pTabItem->iCursor==pLevel->iTabCur ); + testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS-1 ); + testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS ); + if( pWInfo->eOnePass==ONEPASS_OFF + && pTab->nColtabFlags & (TF_HasGenerated|TF_WithoutRowid))==0 + && (pLoop->wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))==0 + ){ + /* If we know that only a prefix of the record will be used, + ** it is advantageous to reduce the "column count" field in + ** the P4 operand of the OP_OpenRead/Write opcode. */ + Bitmask b = pTabItem->colUsed; + int n = 0; + for(; b; b=b>>1, n++){} + sqlite3VdbeChangeP4(v, -1, SQLITE_INT_TO_PTR(n), P4_INT32); + assert( n<=pTab->nCol ); + } +#ifdef SQLITE_ENABLE_CURSOR_HINTS + if( pLoop->u.btree.pIndex!=0 && (pTab->tabFlags & TF_WithoutRowid)==0 ){ + sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ|bFordelete); + }else +#endif + { + sqlite3VdbeChangeP5(v, bFordelete); + } +#ifdef SQLITE_ENABLE_COLUMN_USED_MASK + sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, pTabItem->iCursor, 0, 0, + (const u8*)&pTabItem->colUsed, P4_INT64); +#endif + if( ii>=2 + && (pTabItem[0].fg.jointype & (JT_LTORJ|JT_LEFT))==0 + && pLevel->addrHalt==pWInfo->a[0].addrHalt + ){ + sqlite3VdbeAddOp2(v, OP_IfEmpty, pTabItem->iCursor, pWInfo->iBreak); + VdbeCoverage(v); + } + }else{ + sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); + } + if( pLoop->wsFlags & WHERE_INDEXED ){ + Index *pIx = pLoop->u.btree.pIndex; + int iIndexCur; + int op = OP_OpenRead; + /* iAuxArg is always set to a positive value if ONEPASS is possible */ + assert( iAuxArg!=0 || (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 ); + if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIx) + && (wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 + ){ + /* This is one term of an OR-optimization using the PRIMARY KEY of a + ** WITHOUT ROWID table. No need for a separate index */ + iIndexCur = pLevel->iTabCur; + op = 0; + }else if( pWInfo->eOnePass!=ONEPASS_OFF ){ + Index *pJ = pTabItem->pSTab->pIndex; + iIndexCur = iAuxArg; + assert( wctrlFlags & WHERE_ONEPASS_DESIRED ); + while( ALWAYS(pJ) && pJ!=pIx ){ + iIndexCur++; + pJ = pJ->pNext; + } + op = OP_OpenWrite; + pWInfo->aiCurOnePass[1] = iIndexCur; + }else if( iAuxArg && (wctrlFlags & WHERE_OR_SUBCLAUSE)!=0 ){ + iIndexCur = iAuxArg; + op = OP_ReopenIdx; + }else{ + iIndexCur = pParse->nTab++; + if( pIx->bHasExpr && OptimizationEnabled(db, SQLITE_IndexedExpr) ){ + whereAddIndexedExpr(pParse, pIx, iIndexCur, pTabItem); + } + if( pIx->pPartIdxWhere && (pTabItem->fg.jointype & JT_RIGHT)==0 ){ + wherePartIdxExpr( + pParse, pIx, pIx->pPartIdxWhere, 0, iIndexCur, pTabItem + ); + } + } + pLevel->iIdxCur = iIndexCur; + assert( pIx!=0 ); + assert( pIx->pSchema==pTab->pSchema ); + assert( iIndexCur>=0 ); + if( op ){ + sqlite3VdbeAddOp3(v, op, iIndexCur, pIx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIx); + if( (pLoop->wsFlags & WHERE_CONSTRAINT)!=0 + && (pLoop->wsFlags & (WHERE_COLUMN_RANGE|WHERE_SKIPSCAN))==0 + && (pLoop->wsFlags & WHERE_BIGNULL_SORT)==0 + && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 + && (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0 + && pWInfo->eDistinct!=WHERE_DISTINCT_ORDERED + ){ + sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ); + } + VdbeComment((v, "%s", pIx->zName)); +#ifdef SQLITE_ENABLE_COLUMN_USED_MASK + { + u64 colUsed = 0; + int ii, jj; + for(ii=0; iinColumn; ii++){ + jj = pIx->aiColumn[ii]; + if( jj<0 ) continue; + if( jj>63 ) jj = 63; + if( (pTabItem->colUsed & MASKBIT(jj))==0 ) continue; + colUsed |= ((u64)1)<<(ii<63 ? ii : 63); + } + sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, iIndexCur, 0, 0, + (u8*)&colUsed, P4_INT64); + } +#endif /* SQLITE_ENABLE_COLUMN_USED_MASK */ + } + } + if( iDb>=0 ) sqlite3CodeVerifySchema(pParse, iDb); + if( (pTabItem->fg.jointype & JT_RIGHT)!=0 + && (pLevel->pRJ = sqlite3WhereMalloc(pWInfo, sizeof(WhereRightJoin)))!=0 + ){ + WhereRightJoin *pRJ = pLevel->pRJ; + pRJ->iMatch = pParse->nTab++; + pRJ->regBloom = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Blob, 65536, pRJ->regBloom); + pRJ->regReturn = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Null, 0, pRJ->regReturn); + assert( pTab==pTabItem->pSTab ); + if( HasRowid(pTab) ){ + KeyInfo *pInfo; + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRJ->iMatch, 1); + pInfo = sqlite3KeyInfoAlloc(pParse->db, 1, 0); + if( pInfo ){ + pInfo->aColl[0] = 0; + pInfo->aSortFlags[0] = 0; + sqlite3VdbeAppendP4(v, pInfo, P4_KEYINFO); + } + }else{ + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRJ->iMatch, pPk->nKeyCol); + sqlite3VdbeSetP4KeyInfo(pParse, pPk); + } + pLoop->wsFlags &= ~WHERE_IDX_ONLY; + /* The nature of RIGHT JOIN processing is such that it messes up + ** the output order. So omit any ORDER BY/GROUP BY elimination + ** optimizations. We need to do an actual sort for RIGHT JOIN. */ + pWInfo->nOBSat = 0; + pWInfo->eDistinct = WHERE_DISTINCT_UNORDERED; + } + } + pWInfo->iTop = sqlite3VdbeCurrentAddr(v); + if( db->mallocFailed ) goto whereBeginError; + + /* Generate the code to do the search. Each iteration of the for + ** loop below generates code for a single nested loop of the VM + ** program. + */ + for(ii=0; iinErr ) goto whereBeginError; + pLevel = &pWInfo->a[ii]; + wsFlags = pLevel->pWLoop->wsFlags; + pSrc = &pTabList->a[pLevel->iFrom]; + if( pSrc->fg.isMaterialized ){ + Subquery *pSubq; + int iOnce = 0; + assert( pSrc->fg.isSubquery ); + pSubq = pSrc->u4.pSubq; + if( pSrc->fg.isCorrelated==0 ){ + iOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + }else{ + iOnce = 0; + } + sqlite3VdbeAddOp2(v, OP_Gosub, pSubq->regReturn, pSubq->addrFillSub); + VdbeComment((v, "materialize %!S", pSrc)); + if( iOnce ) sqlite3VdbeJumpHere(v, iOnce); + } + assert( pTabList == pWInfo->pTabList ); + if( (wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))!=0 ){ + if( (wsFlags & WHERE_AUTO_INDEX)!=0 ){ +#ifndef SQLITE_OMIT_AUTOMATIC_INDEX + constructAutomaticIndex(pParse, &pWInfo->sWC, notReady, pLevel); +#endif + }else{ + sqlite3ConstructBloomFilter(pWInfo, ii, pLevel, notReady); + } + if( db->mallocFailed ) goto whereBeginError; + } + addrExplain = sqlite3WhereExplainOneScan( + pParse, pTabList, pLevel, wctrlFlags + ); + pLevel->addrBody = sqlite3VdbeCurrentAddr(v); + notReady = sqlite3WhereCodeOneLoopStart(pParse,v,pWInfo,ii,pLevel,notReady); + pWInfo->iContinue = pLevel->addrCont; + if( (wsFlags&WHERE_MULTI_OR)==0 && (wctrlFlags&WHERE_OR_SUBCLAUSE)==0 ){ + sqlite3WhereAddScanStatus(v, pTabList, pLevel, addrExplain); + } + } + + /* Done. */ + VdbeModuleComment((v, "Begin WHERE-core")); + pWInfo->iEndWhere = sqlite3VdbeCurrentAddr(v); + return pWInfo; + + /* Jump here if malloc fails */ +whereBeginError: + if( pWInfo ){ + pParse->nQueryLoop = pWInfo->savedNQueryLoop; + whereInfoFree(db, pWInfo); + } +#ifdef WHERETRACE_ENABLED + /* Prevent harmless compiler warnings about debugging routines + ** being declared but never used */ + sqlite3ShowWhereLoopList(0); +#endif /* WHERETRACE_ENABLED */ + return 0; +} + +/* +** Part of sqlite3WhereEnd() will rewrite opcodes to reference the +** index rather than the main table. In SQLITE_DEBUG mode, we want +** to trace those changes if PRAGMA vdbe_addoptrace=on. This routine +** does that. +*/ +#ifndef SQLITE_DEBUG +# define OpcodeRewriteTrace(D,K,P) /* no-op */ +#else +# define OpcodeRewriteTrace(D,K,P) sqlite3WhereOpcodeRewriteTrace(D,K,P) + static void sqlite3WhereOpcodeRewriteTrace( + sqlite3 *db, + int pc, + VdbeOp *pOp + ){ + if( (db->flags & SQLITE_VdbeAddopTrace)==0 ) return; + sqlite3VdbePrintOp(0, pc, pOp); + sqlite3ShowWhereTerm(0); /* So compiler won't complain about unused func */ + } +#endif + +/* +** Generate the end of the WHERE loop. See comments on +** sqlite3WhereBegin() for additional information. +*/ +SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ + Parse *pParse = pWInfo->pParse; + Vdbe *v = pParse->pVdbe; + int i; + WhereLevel *pLevel; + WhereLoop *pLoop; + SrcList *pTabList = pWInfo->pTabList; + sqlite3 *db = pParse->db; + int iEnd = sqlite3VdbeCurrentAddr(v); + int nRJ = 0; +#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT + int addrSeek = 0; +#endif + + /* Generate loop termination code. + */ + VdbeModuleComment((v, "End WHERE-core")); + for(i=pWInfo->nLevel-1; i>=0; i--){ + int addr; + pLevel = &pWInfo->a[i]; + if( pLevel->pRJ ){ + /* Terminate the subroutine that forms the interior of the loop of + ** the RIGHT JOIN table */ + WhereRightJoin *pRJ = pLevel->pRJ; + sqlite3VdbeResolveLabel(v, pLevel->addrCont); + /* Replace addrCont with a new label that will never be used, just so + ** the subsequent call to resolve pLevel->addrCont will have something + ** to resolve. */ + pLevel->addrCont = sqlite3VdbeMakeLabel(pParse); + pRJ->endSubrtn = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp3(v, OP_Return, pRJ->regReturn, pRJ->addrSubrtn, 1); + VdbeCoverage(v); + nRJ++; + } + pLoop = pLevel->pWLoop; + if( pLevel->op!=OP_Noop ){ +#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT + Index *pIdx; + int n; + if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED + && i==pWInfo->nLevel-1 /* Ticket [ef9318757b152e3] 2017-10-21 */ + && (pLoop->wsFlags & WHERE_INDEXED)!=0 + && (pIdx = pLoop->u.btree.pIndex)->hasStat1 + && (n = pLoop->u.btree.nDistinctCol)>0 + && pIdx->aiRowLogEst[n]>=36 + ){ + int r1 = pParse->nMem+1; + int j, op; + int addrIfNull = 0; /* Init to avoid false-positive compiler warning */ + if( pLevel->iLeftJoin ){ + addrIfNull = sqlite3VdbeAddOp2(v, OP_IfNullRow, pLevel->iIdxCur, r1); + } + for(j=0; jiIdxCur, j, r1+j); + } + pParse->nMem += n+1; + op = pLevel->op==OP_Prev ? OP_SeekLT : OP_SeekGT; + addrSeek = sqlite3VdbeAddOp4Int(v, op, pLevel->iIdxCur, 0, r1, n); + VdbeCoverageIf(v, op==OP_SeekLT); + VdbeCoverageIf(v, op==OP_SeekGT); + sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2); + if( pLevel->iLeftJoin ){ + sqlite3VdbeJumpHere(v, addrIfNull); + } + } +#endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */ + } + if( pTabList->a[pLevel->iFrom].fg.fromExists ){ + /* This is an EXISTS-to-JOIN optimization loop. If this loop sees a + ** successful row, it should break out of itself. */ + sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk); + VdbeComment((v, "EXISTS break %d", i)); + } + sqlite3VdbeResolveLabel(v, pLevel->addrCont); + if( pLevel->op!=OP_Noop ){ + sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3); + sqlite3VdbeChangeP5(v, pLevel->p5); + VdbeCoverage(v); + VdbeCoverageIf(v, pLevel->op==OP_Next); + VdbeCoverageIf(v, pLevel->op==OP_Prev); + VdbeCoverageIf(v, pLevel->op==OP_VNext); + if( pLevel->regBignull ){ + sqlite3VdbeResolveLabel(v, pLevel->addrBignull); + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, pLevel->regBignull, pLevel->p2-1); + VdbeCoverage(v); + } +#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT + if( addrSeek ){ + sqlite3VdbeJumpHere(v, addrSeek); + addrSeek = 0; + } +#endif + } + if( (pLoop->wsFlags & WHERE_IN_ABLE)!=0 && pLevel->u.in.nIn>0 ){ + struct InLoop *pIn; + int j; + sqlite3VdbeResolveLabel(v, pLevel->addrNxt); + for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){ + assert( sqlite3VdbeGetOp(v, pIn->addrInTop+1)->opcode==OP_IsNull + || pParse->db->mallocFailed ); + sqlite3VdbeJumpHere(v, pIn->addrInTop+1); + if( pIn->eEndLoopOp!=OP_Noop ){ + if( pIn->nPrefix ){ + int bEarlyOut = + (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 + && (pLoop->wsFlags & WHERE_IN_EARLYOUT)!=0; + if( pLevel->iLeftJoin ){ + /* For LEFT JOIN queries, cursor pIn->iCur may not have been + ** opened yet. This occurs for WHERE clauses such as + ** "a = ? AND b IN (...)", where the index is on (a, b). If + ** the RHS of the (a=?) is NULL, then the "b IN (...)" may + ** never have been coded, but the body of the loop run to + ** return the null-row. So, if the cursor is not open yet, + ** jump over the OP_Next or OP_Prev instruction about to + ** be coded. */ + sqlite3VdbeAddOp2(v, OP_IfNotOpen, pIn->iCur, + sqlite3VdbeCurrentAddr(v) + 2 + bEarlyOut); + VdbeCoverage(v); + } + if( bEarlyOut ){ + sqlite3VdbeAddOp4Int(v, OP_IfNoHope, pLevel->iIdxCur, + sqlite3VdbeCurrentAddr(v)+2, + pIn->iBase, pIn->nPrefix); + VdbeCoverage(v); + /* Retarget the OP_IsNull against the left operand of IN so + ** it jumps past the OP_IfNoHope. This is because the + ** OP_IsNull also bypasses the OP_Affinity opcode that is + ** required by OP_IfNoHope. */ + sqlite3VdbeJumpHere(v, pIn->addrInTop+1); + } + } + sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop); + VdbeCoverage(v); + VdbeCoverageIf(v, pIn->eEndLoopOp==OP_Prev); + VdbeCoverageIf(v, pIn->eEndLoopOp==OP_Next); + } + sqlite3VdbeJumpHere(v, pIn->addrInTop-1); + } + } + sqlite3VdbeResolveLabel(v, pLevel->addrBrk); + if( pLevel->pRJ ){ + sqlite3VdbeAddOp3(v, OP_Return, pLevel->pRJ->regReturn, 0, 1); + VdbeCoverage(v); + } + if( pLevel->addrSkip ){ + sqlite3VdbeGoto(v, pLevel->addrSkip); + VdbeComment((v, "next skip-scan on %s", pLoop->u.btree.pIndex->zName)); + sqlite3VdbeJumpHere(v, pLevel->addrSkip); + sqlite3VdbeJumpHere(v, pLevel->addrSkip-2); + } +#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS + if( pLevel->addrLikeRep ){ + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, (int)(pLevel->iLikeRepCntr>>1), + pLevel->addrLikeRep); + VdbeCoverage(v); + } +#endif + if( pLevel->iLeftJoin ){ + int ws = pLoop->wsFlags; + addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v); + assert( (ws & WHERE_IDX_ONLY)==0 || (ws & WHERE_INDEXED)!=0 ); + if( (ws & WHERE_IDX_ONLY)==0 ){ + SrcItem *pSrc = &pTabList->a[pLevel->iFrom]; + assert( pLevel->iTabCur==pSrc->iCursor ); + if( pSrc->fg.viaCoroutine ){ + int m, n; + assert( pSrc->fg.isSubquery ); + n = pSrc->u4.pSubq->regResult; + assert( pSrc->pSTab!=0 ); + m = pSrc->pSTab->nCol; + sqlite3VdbeAddOp3(v, OP_Null, 0, n, n+m-1); + } + sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur); + } + if( (ws & WHERE_INDEXED) + || ((ws & WHERE_MULTI_OR) && pLevel->u.pCoveringIdx) + ){ + if( ws & WHERE_MULTI_OR ){ + Index *pIx = pLevel->u.pCoveringIdx; + int iDb = sqlite3SchemaToIndex(db, pIx->pSchema); + sqlite3VdbeAddOp3(v, OP_ReopenIdx, pLevel->iIdxCur, pIx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIx); + } + sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur); + } + if( pLevel->op==OP_Return ){ + sqlite3VdbeAddOp2(v, OP_Gosub, pLevel->p1, pLevel->addrFirst); + }else{ + sqlite3VdbeGoto(v, pLevel->addrFirst); + } + sqlite3VdbeJumpHere(v, addr); + } + VdbeModuleComment((v, "End WHERE-loop%d: %s", i, + pWInfo->pTabList->a[pLevel->iFrom].pSTab->zName)); + } + + assert( pWInfo->nLevel<=pTabList->nSrc ); + for(i=0, pLevel=pWInfo->a; inLevel; i++, pLevel++){ + int k, last; + VdbeOp *pOp, *pLastOp; + Index *pIdx = 0; + SrcItem *pTabItem = &pTabList->a[pLevel->iFrom]; + Table *pTab = pTabItem->pSTab; + assert( pTab!=0 ); + pLoop = pLevel->pWLoop; + + /* Do RIGHT JOIN processing. Generate code that will output the + ** unmatched rows of the right operand of the RIGHT JOIN with + ** all of the columns of the left operand set to NULL. + */ + if( pLevel->pRJ ){ + sqlite3WhereRightJoinLoop(pWInfo, i, pLevel); + continue; + } + + /* For a co-routine, change all OP_Column references to the table of + ** the co-routine into OP_Copy of result contained in a register. + ** OP_Rowid becomes OP_Null. + */ + if( pTabItem->fg.viaCoroutine ){ + testcase( pParse->db->mallocFailed ); + assert( pTabItem->fg.isSubquery ); + assert( pTabItem->u4.pSubq->regResult>=0 ); + translateColumnToCopy(pParse, pLevel->addrBody, pLevel->iTabCur, + pTabItem->u4.pSubq->regResult, 0); + continue; + } + + /* If this scan uses an index, make VDBE code substitutions to read data + ** from the index instead of from the table where possible. In some cases + ** this optimization prevents the table from ever being read, which can + ** yield a significant performance boost. + ** + ** Calls to the code generator in between sqlite3WhereBegin and + ** sqlite3WhereEnd will have created code that references the table + ** directly. This loop scans all that code looking for opcodes + ** that reference the table and converts them into opcodes that + ** reference the index. + */ + if( pLoop->wsFlags & (WHERE_INDEXED|WHERE_IDX_ONLY) ){ + pIdx = pLoop->u.btree.pIndex; + }else if( pLoop->wsFlags & WHERE_MULTI_OR ){ + pIdx = pLevel->u.pCoveringIdx; + } + if( pIdx + && !db->mallocFailed + ){ + if( pWInfo->eOnePass==ONEPASS_OFF || !HasRowid(pIdx->pTable) ){ + last = iEnd; + }else{ + last = pWInfo->iEndWhere; + } + if( pIdx->bHasExpr ){ + IndexedExpr *p = pParse->pIdxEpr; + while( p ){ + if( p->iIdxCur==pLevel->iIdxCur ){ +#ifdef WHERETRACE_ENABLED + if( sqlite3WhereTrace & 0x200 ){ + sqlite3DebugPrintf("Disable pParse->pIdxEpr term {%d,%d}\n", + p->iIdxCur, p->iIdxCol); + if( sqlite3WhereTrace & 0x5000 ) sqlite3ShowExpr(p->pExpr); + } +#endif + p->iDataCur = -1; + p->iIdxCur = -1; + } + p = p->pIENext; + } + } + k = pLevel->addrBody + 1; +#ifdef SQLITE_DEBUG + if( db->flags & SQLITE_VdbeAddopTrace ){ + printf("TRANSLATE cursor %d->%d in opcode range %d..%d\n", + pLevel->iTabCur, pLevel->iIdxCur, k, last-1); + } + /* Proof that the "+1" on the k value above is safe */ + pOp = sqlite3VdbeGetOp(v, k - 1); + assert( pOp->opcode!=OP_Column || pOp->p1!=pLevel->iTabCur ); + assert( pOp->opcode!=OP_Rowid || pOp->p1!=pLevel->iTabCur ); + assert( pOp->opcode!=OP_IfNullRow || pOp->p1!=pLevel->iTabCur ); +#endif + pOp = sqlite3VdbeGetOp(v, k); + pLastOp = pOp + (last - k); + assert( pOp<=pLastOp ); + do{ + if( pOp->p1!=pLevel->iTabCur ){ + /* no-op */ + }else if( pOp->opcode==OP_Column +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC + || pOp->opcode==OP_Offset +#endif + ){ + int x = pOp->p2; + assert( pIdx->pTable==pTab ); +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC + if( pOp->opcode==OP_Offset ){ + /* Do not need to translate the column number */ + }else +#endif + if( !HasRowid(pTab) ){ + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + x = pPk->aiColumn[x]; + assert( x>=0 ); + }else{ + testcase( x!=sqlite3StorageColumnToTable(pTab,x) ); + x = sqlite3StorageColumnToTable(pTab,x); + } + x = sqlite3TableColumnToIndex(pIdx, x); + if( x>=0 ){ + pOp->p2 = x; + pOp->p1 = pLevel->iIdxCur; + OpcodeRewriteTrace(db, k, pOp); + }else if( pLoop->wsFlags & (WHERE_IDX_ONLY|WHERE_EXPRIDX) ){ + if( pLoop->wsFlags & WHERE_IDX_ONLY ){ + /* An error. pLoop is supposed to be a covering index loop, + ** and yet the VM code refers to a column of the table that + ** is not part of the index. */ + sqlite3ErrorMsg(pParse, "internal query planner error"); + pParse->rc = SQLITE_INTERNAL; + }else{ + /* The WHERE_EXPRIDX flag is set by the planner when it is likely + ** that pLoop is a covering index loop, but it is not possible + ** to be 100% sure. In this case, any OP_Explain opcode + ** corresponding to this loop describes the index as a "COVERING + ** INDEX". But, pOp proves that pLoop is not actually a covering + ** index loop. So clear the WHERE_EXPRIDX flag and rewrite the + ** text that accompanies the OP_Explain opcode, if any. */ + pLoop->wsFlags &= ~WHERE_EXPRIDX; + sqlite3WhereAddExplainText(pParse, + pLevel->addrBody-1, + pTabList, + pLevel, + pWInfo->wctrlFlags + ); + } + } + }else if( pOp->opcode==OP_Rowid ){ + pOp->p1 = pLevel->iIdxCur; + pOp->opcode = OP_IdxRowid; + OpcodeRewriteTrace(db, k, pOp); + }else if( pOp->opcode==OP_IfNullRow ){ + pOp->p1 = pLevel->iIdxCur; + OpcodeRewriteTrace(db, k, pOp); + } +#ifdef SQLITE_DEBUG + k++; +#endif + }while( (++pOp)flags & SQLITE_VdbeAddopTrace ) printf("TRANSLATE complete\n"); +#endif + } + } + + /* The "break" point is here, just past the end of the outer loop. + ** Set it. + */ + sqlite3VdbeResolveLabel(v, pWInfo->iBreak); + + /* Final cleanup + */ + pParse->nQueryLoop = pWInfo->savedNQueryLoop; + whereInfoFree(db, pWInfo); + pParse->withinRJSubrtn -= nRJ; + return; +} + +/************** End of where.c ***********************************************/ +/************** Begin file window.c ******************************************/ +/* +** 2018 May 08 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +*/ +/* #include "sqliteInt.h" */ + +#ifndef SQLITE_OMIT_WINDOWFUNC + +/* +** SELECT REWRITING +** +** Any SELECT statement that contains one or more window functions in +** either the select list or ORDER BY clause (the only two places window +** functions may be used) is transformed by function sqlite3WindowRewrite() +** in order to support window function processing. For example, with the +** schema: +** +** CREATE TABLE t1(a, b, c, d, e, f, g); +** +** the statement: +** +** SELECT a+1, max(b) OVER (PARTITION BY c ORDER BY d) FROM t1 ORDER BY e; +** +** is transformed to: +** +** SELECT a+1, max(b) OVER (PARTITION BY c ORDER BY d) FROM ( +** SELECT a, e, c, d, b FROM t1 ORDER BY c, d +** ) ORDER BY e; +** +** The flattening optimization is disabled when processing this transformed +** SELECT statement. This allows the implementation of the window function +** (in this case max()) to process rows sorted in order of (c, d), which +** makes things easier for obvious reasons. More generally: +** +** * FROM, WHERE, GROUP BY and HAVING clauses are all moved to +** the sub-query. +** +** * ORDER BY, LIMIT and OFFSET remain part of the parent query. +** +** * Terminals from each of the expression trees that make up the +** select-list and ORDER BY expressions in the parent query are +** selected by the sub-query. For the purposes of the transformation, +** terminals are column references and aggregate functions. +** +** If there is more than one window function in the SELECT that uses +** the same window declaration (the OVER bit), then a single scan may +** be used to process more than one window function. For example: +** +** SELECT max(b) OVER (PARTITION BY c ORDER BY d), +** min(e) OVER (PARTITION BY c ORDER BY d) +** FROM t1; +** +** is transformed in the same way as the example above. However: +** +** SELECT max(b) OVER (PARTITION BY c ORDER BY d), +** min(e) OVER (PARTITION BY a ORDER BY b) +** FROM t1; +** +** Must be transformed to: +** +** SELECT max(b) OVER (PARTITION BY c ORDER BY d) FROM ( +** SELECT e, min(e) OVER (PARTITION BY a ORDER BY b), c, d, b FROM +** SELECT a, e, c, d, b FROM t1 ORDER BY a, b +** ) ORDER BY c, d +** ) ORDER BY e; +** +** so that both min() and max() may process rows in the order defined by +** their respective window declarations. +** +** INTERFACE WITH SELECT.C +** +** When processing the rewritten SELECT statement, code in select.c calls +** sqlite3WhereBegin() to begin iterating through the results of the +** sub-query, which is always implemented as a co-routine. It then calls +** sqlite3WindowCodeStep() to process rows and finish the scan by calling +** sqlite3WhereEnd(). +** +** sqlite3WindowCodeStep() generates VM code so that, for each row returned +** by the sub-query a sub-routine (OP_Gosub) coded by select.c is invoked. +** When the sub-routine is invoked: +** +** * The results of all window-functions for the row are stored +** in the associated Window.regResult registers. +** +** * The required terminal values are stored in the current row of +** temp table Window.iEphCsr. +** +** In some cases, depending on the window frame and the specific window +** functions invoked, sqlite3WindowCodeStep() caches each entire partition +** in a temp table before returning any rows. In other cases it does not. +** This detail is encapsulated within this file, the code generated by +** select.c is the same in either case. +** +** BUILT-IN WINDOW FUNCTIONS +** +** This implementation features the following built-in window functions: +** +** row_number() +** rank() +** dense_rank() +** percent_rank() +** cume_dist() +** ntile(N) +** lead(expr [, offset [, default]]) +** lag(expr [, offset [, default]]) +** first_value(expr) +** last_value(expr) +** nth_value(expr, N) +** +** These are the same built-in window functions supported by Postgres. +** Although the behaviour of aggregate window functions (functions that +** can be used as either aggregates or window functions) allows them to +** be implemented using an API, built-in window functions are much more +** esoteric. Additionally, some window functions (e.g. nth_value()) +** may only be implemented by caching the entire partition in memory. +** As such, some built-in window functions use the same API as aggregate +** window functions and some are implemented directly using VDBE +** instructions. Additionally, for those functions that use the API, the +** window frame is sometimes modified before the SELECT statement is +** rewritten. For example, regardless of the specified window frame, the +** row_number() function always uses: +** +** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +** +** See sqlite3WindowUpdate() for details. +** +** As well as some of the built-in window functions, aggregate window +** functions min() and max() are implemented using VDBE instructions if +** the start of the window frame is declared as anything other than +** UNBOUNDED PRECEDING. +*/ + +/* +** Implementation of built-in window function row_number(). Assumes that the +** window frame has been coerced to: +** +** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +*/ +static void row_numberStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ) (*p)++; + UNUSED_PARAMETER(nArg); + UNUSED_PARAMETER(apArg); +} +static void row_numberValueFunc(sqlite3_context *pCtx){ + i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + sqlite3_result_int64(pCtx, (p ? *p : 0)); +} + +/* +** Context object type used by rank(), dense_rank(), percent_rank() and +** cume_dist(). +*/ +struct CallCount { + i64 nValue; + i64 nStep; + i64 nTotal; +}; + +/* +** Implementation of built-in window function dense_rank(). Assumes that +** the window frame has been set to: +** +** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +*/ +static void dense_rankStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct CallCount *p; + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ) p->nStep = 1; + UNUSED_PARAMETER(nArg); + UNUSED_PARAMETER(apArg); +} +static void dense_rankValueFunc(sqlite3_context *pCtx){ + struct CallCount *p; + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + if( p->nStep ){ + p->nValue++; + p->nStep = 0; + } + sqlite3_result_int64(pCtx, p->nValue); + } +} + +/* +** Implementation of built-in window function nth_value(). This +** implementation is used in "slow mode" only - when the EXCLUDE clause +** is not set to the default value "NO OTHERS". +*/ +struct NthValueCtx { + i64 nStep; + sqlite3_value *pValue; +}; +static void nth_valueStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct NthValueCtx *p; + p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + i64 iVal; + switch( sqlite3_value_numeric_type(apArg[1]) ){ + case SQLITE_INTEGER: + iVal = sqlite3_value_int64(apArg[1]); + break; + case SQLITE_FLOAT: { + double fVal = sqlite3_value_double(apArg[1]); + if( sqlite3RealToI64(fVal)!=fVal ) goto error_out; + iVal = (i64)fVal; + break; + } + default: + goto error_out; + } + if( iVal<=0 ) goto error_out; + + p->nStep++; + if( iVal==p->nStep ){ + p->pValue = sqlite3_value_dup(apArg[0]); + if( !p->pValue ){ + sqlite3_result_error_nomem(pCtx); + } + } + } + UNUSED_PARAMETER(nArg); + UNUSED_PARAMETER(apArg); + return; + + error_out: + sqlite3_result_error( + pCtx, "second argument to nth_value must be a positive integer", -1 + ); +} +static void nth_valueFinalizeFunc(sqlite3_context *pCtx){ + struct NthValueCtx *p; + p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, 0); + if( p && p->pValue ){ + sqlite3_result_value(pCtx, p->pValue); + sqlite3_value_free(p->pValue); + p->pValue = 0; + } +} +#define nth_valueInvFunc noopStepFunc +#define nth_valueValueFunc noopValueFunc + +static void first_valueStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct NthValueCtx *p; + p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p && p->pValue==0 ){ + p->pValue = sqlite3_value_dup(apArg[0]); + if( !p->pValue ){ + sqlite3_result_error_nomem(pCtx); + } + } + UNUSED_PARAMETER(nArg); + UNUSED_PARAMETER(apArg); +} +static void first_valueFinalizeFunc(sqlite3_context *pCtx){ + struct NthValueCtx *p; + p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p && p->pValue ){ + sqlite3_result_value(pCtx, p->pValue); + sqlite3_value_free(p->pValue); + p->pValue = 0; + } +} +#define first_valueInvFunc noopStepFunc +#define first_valueValueFunc noopValueFunc + +/* +** Implementation of built-in window function rank(). Assumes that +** the window frame has been set to: +** +** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +*/ +static void rankStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct CallCount *p; + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + p->nStep++; + if( p->nValue==0 ){ + p->nValue = p->nStep; + } + } + UNUSED_PARAMETER(nArg); + UNUSED_PARAMETER(apArg); +} +static void rankValueFunc(sqlite3_context *pCtx){ + struct CallCount *p; + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + sqlite3_result_int64(pCtx, p->nValue); + p->nValue = 0; + } +} + +/* +** Implementation of built-in window function percent_rank(). Assumes that +** the window frame has been set to: +** +** GROUPS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING +*/ +static void percent_rankStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct CallCount *p; + UNUSED_PARAMETER(nArg); assert( nArg==0 ); + UNUSED_PARAMETER(apArg); + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + p->nTotal++; + } +} +static void percent_rankInvFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct CallCount *p; + UNUSED_PARAMETER(nArg); assert( nArg==0 ); + UNUSED_PARAMETER(apArg); + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + p->nStep++; +} +static void percent_rankValueFunc(sqlite3_context *pCtx){ + struct CallCount *p; + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + p->nValue = p->nStep; + if( p->nTotal>1 ){ + double r = (double)p->nValue / (double)(p->nTotal-1); + sqlite3_result_double(pCtx, r); + }else{ + sqlite3_result_double(pCtx, 0.0); + } + } +} +#define percent_rankFinalizeFunc percent_rankValueFunc + +/* +** Implementation of built-in window function cume_dist(). Assumes that +** the window frame has been set to: +** +** GROUPS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING +*/ +static void cume_distStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct CallCount *p; + UNUSED_PARAMETER(nArg); assert( nArg==0 ); + UNUSED_PARAMETER(apArg); + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + p->nTotal++; + } +} +static void cume_distInvFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct CallCount *p; + UNUSED_PARAMETER(nArg); assert( nArg==0 ); + UNUSED_PARAMETER(apArg); + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + p->nStep++; +} +static void cume_distValueFunc(sqlite3_context *pCtx){ + struct CallCount *p; + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, 0); + if( p ){ + double r = (double)(p->nStep) / (double)(p->nTotal); + sqlite3_result_double(pCtx, r); + } +} +#define cume_distFinalizeFunc cume_distValueFunc + +/* +** Context object for ntile() window function. +*/ +struct NtileCtx { + i64 nTotal; /* Total rows in partition */ + i64 nParam; /* Parameter passed to ntile(N) */ + i64 iRow; /* Current row */ +}; + +/* +** Implementation of ntile(). This assumes that the window frame has +** been coerced to: +** +** ROWS CURRENT ROW AND UNBOUNDED FOLLOWING +*/ +static void ntileStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct NtileCtx *p; + assert( nArg==1 ); UNUSED_PARAMETER(nArg); + p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + if( p->nTotal==0 ){ + p->nParam = sqlite3_value_int64(apArg[0]); + if( p->nParam<=0 ){ + sqlite3_result_error( + pCtx, "argument of ntile must be a positive integer", -1 + ); + } + } + p->nTotal++; + } +} +static void ntileInvFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct NtileCtx *p; + assert( nArg==1 ); UNUSED_PARAMETER(nArg); + UNUSED_PARAMETER(apArg); + p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + p->iRow++; +} +static void ntileValueFunc(sqlite3_context *pCtx){ + struct NtileCtx *p; + p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p && p->nParam>0 ){ + int nSize = (p->nTotal / p->nParam); + if( nSize==0 ){ + sqlite3_result_int64(pCtx, p->iRow+1); + }else{ + i64 nLarge = p->nTotal - p->nParam*nSize; + i64 iSmall = nLarge*(nSize+1); + i64 iRow = p->iRow; + + assert( (nLarge*(nSize+1) + (p->nParam-nLarge)*nSize)==p->nTotal ); + + if( iRowpVal); + p->pVal = sqlite3_value_dup(apArg[0]); + if( p->pVal==0 ){ + sqlite3_result_error_nomem(pCtx); + }else{ + p->nVal++; + } + } +} +static void last_valueInvFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct LastValueCtx *p; + UNUSED_PARAMETER(nArg); + UNUSED_PARAMETER(apArg); + p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( ALWAYS(p) ){ + p->nVal--; + if( p->nVal==0 ){ + sqlite3_value_free(p->pVal); + p->pVal = 0; + } + } +} +static void last_valueValueFunc(sqlite3_context *pCtx){ + struct LastValueCtx *p; + p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, 0); + if( p && p->pVal ){ + sqlite3_result_value(pCtx, p->pVal); + } +} +static void last_valueFinalizeFunc(sqlite3_context *pCtx){ + struct LastValueCtx *p; + p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p && p->pVal ){ + sqlite3_result_value(pCtx, p->pVal); + sqlite3_value_free(p->pVal); + p->pVal = 0; + } +} + +/* +** Static names for the built-in window function names. These static +** names are used, rather than string literals, so that FuncDef objects +** can be associated with a particular window function by direct +** comparison of the zName pointer. Example: +** +** if( pFuncDef->zName==row_valueName ){ ... } +*/ +static const char row_numberName[] = "row_number"; +static const char dense_rankName[] = "dense_rank"; +static const char rankName[] = "rank"; +static const char percent_rankName[] = "percent_rank"; +static const char cume_distName[] = "cume_dist"; +static const char ntileName[] = "ntile"; +static const char last_valueName[] = "last_value"; +static const char nth_valueName[] = "nth_value"; +static const char first_valueName[] = "first_value"; +static const char leadName[] = "lead"; +static const char lagName[] = "lag"; + +/* +** No-op implementations of xStep() and xFinalize(). Used as place-holders +** for built-in window functions that never call those interfaces. +** +** The noopValueFunc() is called but is expected to do nothing. The +** noopStepFunc() is never called, and so it is marked with NO_TEST to +** let the test coverage routine know not to expect this function to be +** invoked. +*/ +static void noopStepFunc( /*NO_TEST*/ + sqlite3_context *p, /*NO_TEST*/ + int n, /*NO_TEST*/ + sqlite3_value **a /*NO_TEST*/ +){ /*NO_TEST*/ + UNUSED_PARAMETER(p); /*NO_TEST*/ + UNUSED_PARAMETER(n); /*NO_TEST*/ + UNUSED_PARAMETER(a); /*NO_TEST*/ + assert(0); /*NO_TEST*/ +} /*NO_TEST*/ +static void noopValueFunc(sqlite3_context *p){ UNUSED_PARAMETER(p); /*no-op*/ } + +/* Window functions that use all window interfaces: xStep, xFinal, +** xValue, and xInverse */ +#define WINDOWFUNCALL(name,nArg,extra) { \ + nArg, (SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \ + name ## StepFunc, name ## FinalizeFunc, name ## ValueFunc, \ + name ## InvFunc, name ## Name, {0} \ +} + +/* Window functions that are implemented using bytecode and thus have +** no-op routines for their methods */ +#define WINDOWFUNCNOOP(name,nArg,extra) { \ + nArg, (SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \ + noopStepFunc, noopValueFunc, noopValueFunc, \ + noopStepFunc, name ## Name, {0} \ +} + +/* Window functions that use all window interfaces: xStep, the +** same routine for xFinalize and xValue and which never call +** xInverse. */ +#define WINDOWFUNCX(name,nArg,extra) { \ + nArg, (SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \ + name ## StepFunc, name ## ValueFunc, name ## ValueFunc, \ + noopStepFunc, name ## Name, {0} \ +} + + +/* +** Register those built-in window functions that are not also aggregates. +*/ +SQLITE_PRIVATE void sqlite3WindowFunctions(void){ + static FuncDef aWindowFuncs[] = { + WINDOWFUNCX(row_number, 0, 0), + WINDOWFUNCX(dense_rank, 0, 0), + WINDOWFUNCX(rank, 0, 0), + WINDOWFUNCALL(percent_rank, 0, 0), + WINDOWFUNCALL(cume_dist, 0, 0), + WINDOWFUNCALL(ntile, 1, 0), + WINDOWFUNCALL(last_value, 1, 0), + WINDOWFUNCALL(nth_value, 2, 0), + WINDOWFUNCALL(first_value, 1, 0), + WINDOWFUNCNOOP(lead, 1, 0), + WINDOWFUNCNOOP(lead, 2, 0), + WINDOWFUNCNOOP(lead, 3, 0), + WINDOWFUNCNOOP(lag, 1, 0), + WINDOWFUNCNOOP(lag, 2, 0), + WINDOWFUNCNOOP(lag, 3, 0), + }; + sqlite3InsertBuiltinFuncs(aWindowFuncs, ArraySize(aWindowFuncs)); +} + +static Window *windowFind(Parse *pParse, Window *pList, const char *zName){ + Window *p; + for(p=pList; p; p=p->pNextWin){ + if( sqlite3StrICmp(p->zName, zName)==0 ) break; + } + if( p==0 ){ + sqlite3ErrorMsg(pParse, "no such window: %s", zName); + } + return p; +} + +/* +** This function is called immediately after resolving the function name +** for a window function within a SELECT statement. Argument pList is a +** linked list of WINDOW definitions for the current SELECT statement. +** Argument pFunc is the function definition just resolved and pWin +** is the Window object representing the associated OVER clause. This +** function updates the contents of pWin as follows: +** +** * If the OVER clause referred to a named window (as in "max(x) OVER win"), +** search list pList for a matching WINDOW definition, and update pWin +** accordingly. If no such WINDOW clause can be found, leave an error +** in pParse. +** +** * If the function is a built-in window function that requires the +** window to be coerced (see "BUILT-IN WINDOW FUNCTIONS" at the top +** of this file), pWin is updated here. +*/ +SQLITE_PRIVATE void sqlite3WindowUpdate( + Parse *pParse, + Window *pList, /* List of named windows for this SELECT */ + Window *pWin, /* Window frame to update */ + FuncDef *pFunc /* Window function definition */ +){ + if( pWin->zName && pWin->eFrmType==0 ){ + Window *p = windowFind(pParse, pList, pWin->zName); + if( p==0 ) return; + pWin->pPartition = sqlite3ExprListDup(pParse->db, p->pPartition, 0); + pWin->pOrderBy = sqlite3ExprListDup(pParse->db, p->pOrderBy, 0); + pWin->pStart = sqlite3ExprDup(pParse->db, p->pStart, 0); + pWin->pEnd = sqlite3ExprDup(pParse->db, p->pEnd, 0); + pWin->eStart = p->eStart; + pWin->eEnd = p->eEnd; + pWin->eFrmType = p->eFrmType; + pWin->eExclude = p->eExclude; + }else{ + sqlite3WindowChain(pParse, pWin, pList); + } + if( (pWin->eFrmType==TK_RANGE) + && (pWin->pStart || pWin->pEnd) + && (pWin->pOrderBy==0 || pWin->pOrderBy->nExpr!=1) + ){ + sqlite3ErrorMsg(pParse, + "RANGE with offset PRECEDING/FOLLOWING requires one ORDER BY expression" + ); + }else + if( pFunc->funcFlags & SQLITE_FUNC_WINDOW ){ + sqlite3 *db = pParse->db; + if( pWin->pFilter ){ + sqlite3ErrorMsg(pParse, + "FILTER clause may only be used with aggregate window functions" + ); + }else{ + struct WindowUpdate { + const char *zFunc; + int eFrmType; + int eStart; + int eEnd; + } aUp[] = { + { row_numberName, TK_ROWS, TK_UNBOUNDED, TK_CURRENT }, + { dense_rankName, TK_RANGE, TK_UNBOUNDED, TK_CURRENT }, + { rankName, TK_RANGE, TK_UNBOUNDED, TK_CURRENT }, + { percent_rankName, TK_GROUPS, TK_CURRENT, TK_UNBOUNDED }, + { cume_distName, TK_GROUPS, TK_FOLLOWING, TK_UNBOUNDED }, + { ntileName, TK_ROWS, TK_CURRENT, TK_UNBOUNDED }, + { leadName, TK_ROWS, TK_UNBOUNDED, TK_UNBOUNDED }, + { lagName, TK_ROWS, TK_UNBOUNDED, TK_CURRENT }, + }; + int i; + for(i=0; izName==aUp[i].zFunc ){ + sqlite3ExprDelete(db, pWin->pStart); + sqlite3ExprDelete(db, pWin->pEnd); + pWin->pEnd = pWin->pStart = 0; + pWin->eFrmType = aUp[i].eFrmType; + pWin->eStart = aUp[i].eStart; + pWin->eEnd = aUp[i].eEnd; + pWin->eExclude = 0; + if( pWin->eStart==TK_FOLLOWING ){ + pWin->pStart = sqlite3ExprInt32(db, 1); + } + break; + } + } + } + } + pWin->pWFunc = pFunc; +} + +/* +** Context object passed through sqlite3WalkExprList() to +** selectWindowRewriteExprCb() by selectWindowRewriteEList(). +*/ +typedef struct WindowRewrite WindowRewrite; +struct WindowRewrite { + Window *pWin; + SrcList *pSrc; + ExprList *pSub; + Table *pTab; + Select *pSubSelect; /* Current sub-select, if any */ +}; + +/* +** Callback function used by selectWindowRewriteEList(). If necessary, +** this function appends to the output expression-list and updates +** expression (*ppExpr) in place. +*/ +static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){ + struct WindowRewrite *p = pWalker->u.pRewrite; + Parse *pParse = pWalker->pParse; + assert( p!=0 ); + assert( p->pWin!=0 ); + + /* If this function is being called from within a scalar sub-select + ** that used by the SELECT statement being processed, only process + ** TK_COLUMN expressions that refer to it (the outer SELECT). Do + ** not process aggregates or window functions at all, as they belong + ** to the scalar sub-select. */ + if( p->pSubSelect ){ + if( pExpr->op!=TK_COLUMN ){ + return WRC_Continue; + }else{ + int nSrc = p->pSrc->nSrc; + int i; + for(i=0; iiTable==p->pSrc->a[i].iCursor ) break; + } + if( i==nSrc ) return WRC_Continue; + } + } + + switch( pExpr->op ){ + + case TK_FUNCTION: + if( !ExprHasProperty(pExpr, EP_WinFunc) ){ + break; + }else{ + Window *pWin; + for(pWin=p->pWin; pWin; pWin=pWin->pNextWin){ + if( pExpr->y.pWin==pWin ){ + assert( pWin->pOwner==pExpr ); + return WRC_Prune; + } + } + } + /* no break */ deliberate_fall_through + + case TK_IF_NULL_ROW: + case TK_AGG_FUNCTION: + case TK_COLUMN: { + int iCol = -1; + if( pParse->db->mallocFailed ) return WRC_Abort; + if( p->pSub ){ + int i; + for(i=0; ipSub->nExpr; i++){ + if( 0==sqlite3ExprCompare(0, p->pSub->a[i].pExpr, pExpr, -1) ){ + iCol = i; + break; + } + } + } + if( iCol<0 ){ + Expr *pDup = sqlite3ExprDup(pParse->db, pExpr, 0); + if( pDup && pDup->op==TK_AGG_FUNCTION ) pDup->op = TK_FUNCTION; + p->pSub = sqlite3ExprListAppend(pParse, p->pSub, pDup); + } + if( p->pSub ){ + int f = pExpr->flags & EP_Collate; + assert( ExprHasProperty(pExpr, EP_Static)==0 ); + ExprSetProperty(pExpr, EP_Static); + sqlite3ExprDelete(pParse->db, pExpr); + ExprClearProperty(pExpr, EP_Static); + memset(pExpr, 0, sizeof(Expr)); + + pExpr->op = TK_COLUMN; + pExpr->iColumn = (iCol<0 ? p->pSub->nExpr-1: iCol); + pExpr->iTable = p->pWin->iEphCsr; + pExpr->y.pTab = p->pTab; + pExpr->flags = f; + } + if( pParse->db->mallocFailed ) return WRC_Abort; + break; + } + + default: /* no-op */ + break; + } + + return WRC_Continue; +} +static int selectWindowRewriteSelectCb(Walker *pWalker, Select *pSelect){ + struct WindowRewrite *p = pWalker->u.pRewrite; + Select *pSave = p->pSubSelect; + if( pSave==pSelect ){ + return WRC_Continue; + }else{ + p->pSubSelect = pSelect; + sqlite3WalkSelect(pWalker, pSelect); + p->pSubSelect = pSave; + } + return WRC_Prune; +} + + +/* +** Iterate through each expression in expression-list pEList. For each: +** +** * TK_COLUMN, +** * aggregate function, or +** * window function with a Window object that is not a member of the +** Window list passed as the second argument (pWin). +** +** Append the node to output expression-list (*ppSub). And replace it +** with a TK_COLUMN that reads the (N-1)th element of table +** pWin->iEphCsr, where N is the number of elements in (*ppSub) after +** appending the new one. +*/ +static void selectWindowRewriteEList( + Parse *pParse, + Window *pWin, + SrcList *pSrc, + ExprList *pEList, /* Rewrite expressions in this list */ + Table *pTab, + ExprList **ppSub /* IN/OUT: Sub-select expression-list */ +){ + Walker sWalker; + WindowRewrite sRewrite; + + assert( pWin!=0 ); + memset(&sWalker, 0, sizeof(Walker)); + memset(&sRewrite, 0, sizeof(WindowRewrite)); + + sRewrite.pSub = *ppSub; + sRewrite.pWin = pWin; + sRewrite.pSrc = pSrc; + sRewrite.pTab = pTab; + + sWalker.pParse = pParse; + sWalker.xExprCallback = selectWindowRewriteExprCb; + sWalker.xSelectCallback = selectWindowRewriteSelectCb; + sWalker.u.pRewrite = &sRewrite; + + (void)sqlite3WalkExprList(&sWalker, pEList); + + *ppSub = sRewrite.pSub; +} + +/* +** Append a copy of each expression in expression-list pAppend to +** expression list pList. Return a pointer to the result list. +*/ +static ExprList *exprListAppendList( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* List to which to append. Might be NULL */ + ExprList *pAppend, /* List of values to append. Might be NULL */ + int bIntToNull +){ + if( pAppend ){ + int i; + int nInit = pList ? pList->nExpr : 0; + for(i=0; inExpr; i++){ + sqlite3 *db = pParse->db; + Expr *pDup = sqlite3ExprDup(db, pAppend->a[i].pExpr, 0); + if( db->mallocFailed ){ + sqlite3ExprDelete(db, pDup); + break; + } + if( bIntToNull ){ + int iDummy; + Expr *pSub; + pSub = sqlite3ExprSkipCollateAndLikely(pDup); + if( sqlite3ExprIsInteger(pSub, &iDummy, 0) ){ + pSub->op = TK_NULL; + pSub->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse); + pSub->u.zToken = 0; + } + } + pList = sqlite3ExprListAppend(pParse, pList, pDup); + if( pList ) pList->a[nInit+i].fg.sortFlags = pAppend->a[i].fg.sortFlags; + } + } + return pList; +} + +/* +** When rewriting a query, if the new subquery in the FROM clause +** contains TK_AGG_FUNCTION nodes that refer to an outer query, +** then we have to increase the Expr->op2 values of those nodes +** due to the extra subquery layer that was added. +** +** See also the incrAggDepth() routine in resolve.c +*/ +static int sqlite3WindowExtraAggFuncDepth(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_AGG_FUNCTION + && pExpr->op2>=pWalker->walkerDepth + ){ + pExpr->op2++; + } + return WRC_Continue; +} + +static int disallowAggregatesInOrderByCb(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_AGG_FUNCTION && pExpr->pAggInfo==0 ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3ErrorMsg(pWalker->pParse, + "misuse of aggregate: %s()", pExpr->u.zToken); + } + return WRC_Continue; +} + +/* +** If the SELECT statement passed as the second argument does not invoke +** any SQL window functions, this function is a no-op. Otherwise, it +** rewrites the SELECT statement so that window function xStep functions +** are invoked in the correct order as described under "SELECT REWRITING" +** at the top of this file. +*/ +SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ + int rc = SQLITE_OK; + if( p->pWin + && p->pPrior==0 + && ALWAYS((p->selFlags & SF_WinRewrite)==0) + && ALWAYS(!IN_RENAME_OBJECT) + ){ + Vdbe *v = sqlite3GetVdbe(pParse); + sqlite3 *db = pParse->db; + Select *pSub = 0; /* The subquery */ + SrcList *pSrc = p->pSrc; + Expr *pWhere = p->pWhere; + ExprList *pGroupBy = p->pGroupBy; + Expr *pHaving = p->pHaving; + ExprList *pSort = 0; + + ExprList *pSublist = 0; /* Expression list for sub-query */ + Window *pMWin = p->pWin; /* Main window object */ + Window *pWin; /* Window object iterator */ + Table *pTab; + Walker w; + + u32 selFlags = p->selFlags; + + pTab = sqlite3DbMallocZero(db, sizeof(Table)); + if( pTab==0 ){ + return sqlite3ErrorToParser(db, SQLITE_NOMEM); + } + sqlite3AggInfoPersistWalkerInit(&w, pParse); + sqlite3WalkSelect(&w, p); + if( (p->selFlags & SF_Aggregate)==0 ){ + w.xExprCallback = disallowAggregatesInOrderByCb; + w.xSelectCallback = 0; + sqlite3WalkExprList(&w, p->pOrderBy); + } + + p->pSrc = 0; + p->pWhere = 0; + p->pGroupBy = 0; + p->pHaving = 0; + p->selFlags &= ~(u32)SF_Aggregate; + p->selFlags |= SF_WinRewrite; + + /* Create the ORDER BY clause for the sub-select. This is the concatenation + ** of the window PARTITION and ORDER BY clauses. Then, if this makes it + ** redundant, remove the ORDER BY from the parent SELECT. */ + pSort = exprListAppendList(pParse, 0, pMWin->pPartition, 1); + pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy, 1); + if( pSort && p->pOrderBy && p->pOrderBy->nExpr<=pSort->nExpr ){ + int nSave = pSort->nExpr; + pSort->nExpr = p->pOrderBy->nExpr; + if( sqlite3ExprListCompare(pSort, p->pOrderBy, -1)==0 ){ + sqlite3ExprListDelete(db, p->pOrderBy); + p->pOrderBy = 0; + } + pSort->nExpr = nSave; + } + + /* Assign a cursor number for the ephemeral table used to buffer rows. + ** The OpenEphemeral instruction is coded later, after it is known how + ** many columns the table will have. */ + pMWin->iEphCsr = pParse->nTab++; + pParse->nTab += 3; + + selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, pTab, &pSublist); + selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, pTab, &pSublist); + pMWin->nBufferCol = (pSublist ? pSublist->nExpr : 0); + + /* Append the PARTITION BY and ORDER BY expressions to the to the + ** sub-select expression list. They are required to figure out where + ** boundaries for partitions and sets of peer rows lie. */ + pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition, 0); + pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy, 0); + + /* Append the arguments passed to each window function to the + ** sub-select expression list. Also allocate two registers for each + ** window function - one for the accumulator, another for interim + ** results. */ + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + ExprList *pArgs; + assert( ExprUseXList(pWin->pOwner) ); + assert( pWin->pWFunc!=0 ); + pArgs = pWin->pOwner->x.pList; + if( pWin->pWFunc->funcFlags & SQLITE_SUBTYPE ){ + selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist); + pWin->iArgCol = (pSublist ? pSublist->nExpr : 0); + pWin->bExprArgs = 1; + }else{ + pWin->iArgCol = (pSublist ? pSublist->nExpr : 0); + pSublist = exprListAppendList(pParse, pSublist, pArgs, 0); + } + if( pWin->pFilter ){ + Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0); + pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter); + } + pWin->regAccum = ++pParse->nMem; + pWin->regResult = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); + } + + /* If there is no ORDER BY or PARTITION BY clause, and the window + ** function accepts zero arguments, and there are no other columns + ** selected (e.g. "SELECT row_number() OVER () FROM t1"), it is possible + ** that pSublist is still NULL here. Add a constant expression here to + ** keep everything legal in this case. + */ + if( pSublist==0 ){ + pSublist = sqlite3ExprListAppend(pParse, 0, sqlite3ExprInt32(db, 0)); + } + + pSub = sqlite3SelectNew( + pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0 + ); + TREETRACE(0x40,pParse,pSub, + ("New window-function subquery in FROM clause of (%u/%p)\n", + p->selId, p)); + p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); + assert( pSub!=0 || p->pSrc==0 ); /* Due to db->mallocFailed test inside + ** of sqlite3DbMallocRawNN() called from + ** sqlite3SrcListAppend() */ + if( p->pSrc==0 ){ + sqlite3SelectDelete(db, pSub); + }else if( sqlite3SrcItemAttachSubquery(pParse, &p->pSrc->a[0], pSub, 0) ){ + Table *pTab2; + p->pSrc->a[0].fg.isCorrelated = 1; + sqlite3SrcListAssignCursors(pParse, p->pSrc); + pSub->selFlags |= SF_Expanded|SF_OrderByReqd; + pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE); + pSub->selFlags |= (selFlags & SF_Aggregate); + if( pTab2==0 ){ + /* Might actually be some other kind of error, but in that case + ** pParse->nErr will be set, so if SQLITE_NOMEM is set, we will get + ** the correct error message regardless. */ + rc = SQLITE_NOMEM; + }else{ + memcpy(pTab, pTab2, sizeof(Table)); + pTab->tabFlags |= TF_Ephemeral; + p->pSrc->a[0].pSTab = pTab; + pTab = pTab2; + memset(&w, 0, sizeof(w)); + w.xExprCallback = sqlite3WindowExtraAggFuncDepth; + w.xSelectCallback = sqlite3WalkerDepthIncrease; + w.xSelectCallback2 = sqlite3WalkerDepthDecrease; + sqlite3WalkSelect(&w, pSub); + } + } + if( db->mallocFailed ) rc = SQLITE_NOMEM; + + /* Defer deleting the temporary table pTab because if an error occurred, + ** there could still be references to that table embedded in the + ** result-set or ORDER BY clause of the SELECT statement p. */ + sqlite3ParserAddCleanup(pParse, sqlite3DbFree, pTab); + } + + assert( rc==SQLITE_OK || pParse->nErr!=0 ); + return rc; +} + +/* +** Unlink the Window object from the Select to which it is attached, +** if it is attached. +*/ +SQLITE_PRIVATE void sqlite3WindowUnlinkFromSelect(Window *p){ + if( p->ppThis ){ + *p->ppThis = p->pNextWin; + if( p->pNextWin ) p->pNextWin->ppThis = p->ppThis; + p->ppThis = 0; + } +} + +/* +** Free the Window object passed as the second argument. +*/ +SQLITE_PRIVATE void sqlite3WindowDelete(sqlite3 *db, Window *p){ + if( p ){ + sqlite3WindowUnlinkFromSelect(p); + sqlite3ExprDelete(db, p->pFilter); + sqlite3ExprListDelete(db, p->pPartition); + sqlite3ExprListDelete(db, p->pOrderBy); + sqlite3ExprDelete(db, p->pEnd); + sqlite3ExprDelete(db, p->pStart); + sqlite3DbFree(db, p->zName); + sqlite3DbFree(db, p->zBase); + sqlite3DbFree(db, p); + } +} + +/* +** Free the linked list of Window objects starting at the second argument. +*/ +SQLITE_PRIVATE void sqlite3WindowListDelete(sqlite3 *db, Window *p){ + while( p ){ + Window *pNext = p->pNextWin; + sqlite3WindowDelete(db, p); + p = pNext; + } +} + +/* +** The argument expression is an PRECEDING or FOLLOWING offset. The +** value should be a non-negative integer. If the value is not a +** constant, change it to NULL. The fact that it is then a non-negative +** integer will be caught later. But it is important not to leave +** variable values in the expression tree. +*/ +static Expr *sqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){ + if( 0==sqlite3ExprIsConstant(0,pExpr) ){ + if( IN_RENAME_OBJECT ) sqlite3RenameExprUnmap(pParse, pExpr); + sqlite3ExprDelete(pParse->db, pExpr); + pExpr = sqlite3ExprAlloc(pParse->db, TK_NULL, 0, 0); + } + return pExpr; +} + +/* +** Allocate and return a new Window object describing a Window Definition. +*/ +SQLITE_PRIVATE Window *sqlite3WindowAlloc( + Parse *pParse, /* Parsing context */ + int eType, /* Frame type. TK_RANGE, TK_ROWS, TK_GROUPS, or 0 */ + int eStart, /* Start type: CURRENT, PRECEDING, FOLLOWING, UNBOUNDED */ + Expr *pStart, /* Start window size if TK_PRECEDING or FOLLOWING */ + int eEnd, /* End type: CURRENT, FOLLOWING, TK_UNBOUNDED, PRECEDING */ + Expr *pEnd, /* End window size if TK_FOLLOWING or PRECEDING */ + u8 eExclude /* EXCLUDE clause */ +){ + Window *pWin = 0; + int bImplicitFrame = 0; + + /* Parser assures the following: */ + assert( eType==0 || eType==TK_RANGE || eType==TK_ROWS || eType==TK_GROUPS ); + assert( eStart==TK_CURRENT || eStart==TK_PRECEDING + || eStart==TK_UNBOUNDED || eStart==TK_FOLLOWING ); + assert( eEnd==TK_CURRENT || eEnd==TK_FOLLOWING + || eEnd==TK_UNBOUNDED || eEnd==TK_PRECEDING ); + assert( (eStart==TK_PRECEDING || eStart==TK_FOLLOWING)==(pStart!=0) ); + assert( (eEnd==TK_FOLLOWING || eEnd==TK_PRECEDING)==(pEnd!=0) ); + + if( eType==0 ){ + bImplicitFrame = 1; + eType = TK_RANGE; + } + + /* Additionally, the + ** starting boundary type may not occur earlier in the following list than + ** the ending boundary type: + ** + ** UNBOUNDED PRECEDING + ** PRECEDING + ** CURRENT ROW + ** FOLLOWING + ** UNBOUNDED FOLLOWING + ** + ** The parser ensures that "UNBOUNDED PRECEDING" cannot be used as an ending + ** boundary, and than "UNBOUNDED FOLLOWING" cannot be used as a starting + ** frame boundary. + */ + if( (eStart==TK_CURRENT && eEnd==TK_PRECEDING) + || (eStart==TK_FOLLOWING && (eEnd==TK_PRECEDING || eEnd==TK_CURRENT)) + ){ + sqlite3ErrorMsg(pParse, "unsupported frame specification"); + goto windowAllocErr; + } + + pWin = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); + if( pWin==0 ) goto windowAllocErr; + pWin->eFrmType = eType; + pWin->eStart = eStart; + pWin->eEnd = eEnd; + if( eExclude==0 && OptimizationDisabled(pParse->db, SQLITE_WindowFunc) ){ + eExclude = TK_NO; + } + pWin->eExclude = eExclude; + pWin->bImplicitFrame = bImplicitFrame; + pWin->pEnd = sqlite3WindowOffsetExpr(pParse, pEnd); + pWin->pStart = sqlite3WindowOffsetExpr(pParse, pStart); + return pWin; + +windowAllocErr: + sqlite3ExprDelete(pParse->db, pEnd); + sqlite3ExprDelete(pParse->db, pStart); + return 0; +} + +/* +** Attach PARTITION and ORDER BY clauses pPartition and pOrderBy to window +** pWin. Also, if parameter pBase is not NULL, set pWin->zBase to the +** equivalent nul-terminated string. +*/ +SQLITE_PRIVATE Window *sqlite3WindowAssemble( + Parse *pParse, + Window *pWin, + ExprList *pPartition, + ExprList *pOrderBy, + Token *pBase +){ + if( pWin ){ + pWin->pPartition = pPartition; + pWin->pOrderBy = pOrderBy; + if( pBase ){ + pWin->zBase = sqlite3DbStrNDup(pParse->db, pBase->z, pBase->n); + } + }else{ + sqlite3ExprListDelete(pParse->db, pPartition); + sqlite3ExprListDelete(pParse->db, pOrderBy); + } + return pWin; +} + +/* +** Window *pWin has just been created from a WINDOW clause. Token pBase +** is the base window. Earlier windows from the same WINDOW clause are +** stored in the linked list starting at pWin->pNextWin. This function +** either updates *pWin according to the base specification, or else +** leaves an error in pParse. +*/ +SQLITE_PRIVATE void sqlite3WindowChain(Parse *pParse, Window *pWin, Window *pList){ + if( pWin->zBase ){ + sqlite3 *db = pParse->db; + Window *pExist = windowFind(pParse, pList, pWin->zBase); + if( pExist ){ + const char *zErr = 0; + /* Check for errors */ + if( pWin->pPartition ){ + zErr = "PARTITION clause"; + }else if( pExist->pOrderBy && pWin->pOrderBy ){ + zErr = "ORDER BY clause"; + }else if( pExist->bImplicitFrame==0 ){ + zErr = "frame specification"; + } + if( zErr ){ + sqlite3ErrorMsg(pParse, + "cannot override %s of window: %s", zErr, pWin->zBase + ); + }else{ + pWin->pPartition = sqlite3ExprListDup(db, pExist->pPartition, 0); + if( pExist->pOrderBy ){ + assert( pWin->pOrderBy==0 ); + pWin->pOrderBy = sqlite3ExprListDup(db, pExist->pOrderBy, 0); + } + sqlite3DbFree(db, pWin->zBase); + pWin->zBase = 0; + } + } + } +} + +/* +** Attach window object pWin to expression p. +*/ +SQLITE_PRIVATE void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){ + if( p ){ + assert( p->op==TK_FUNCTION ); + assert( pWin ); + assert( ExprIsFullSize(p) ); + p->y.pWin = pWin; + ExprSetProperty(p, EP_WinFunc|EP_FullSize); + pWin->pOwner = p; + if( (p->flags & EP_Distinct) && pWin->eFrmType!=TK_FILTER ){ + sqlite3ErrorMsg(pParse, + "DISTINCT is not supported for window functions" + ); + } + }else{ + sqlite3WindowDelete(pParse->db, pWin); + } +} + +/* +** Possibly link window pWin into the list at pSel->pWin (window functions +** to be processed as part of SELECT statement pSel). The window is linked +** in if either (a) there are no other windows already linked to this +** SELECT, or (b) the windows already linked use a compatible window frame. +*/ +SQLITE_PRIVATE void sqlite3WindowLink(Select *pSel, Window *pWin){ + if( pSel ){ + if( 0==pSel->pWin || 0==sqlite3WindowCompare(0, pSel->pWin, pWin, 0) ){ + pWin->pNextWin = pSel->pWin; + if( pSel->pWin ){ + pSel->pWin->ppThis = &pWin->pNextWin; + } + pSel->pWin = pWin; + pWin->ppThis = &pSel->pWin; + }else{ + if( sqlite3ExprListCompare(pWin->pPartition, pSel->pWin->pPartition,-1) ){ + pSel->selFlags |= SF_MultiPart; + } + } + } +} + +/* +** Return 0 if the two window objects are identical, 1 if they are +** different, or 2 if it cannot be determined if the objects are identical +** or not. Identical window objects can be processed in a single scan. +*/ +SQLITE_PRIVATE int sqlite3WindowCompare( + const Parse *pParse, + const Window *p1, + const Window *p2, + int bFilter +){ + int res; + if( NEVER(p1==0) || NEVER(p2==0) ) return 1; + if( p1->eFrmType!=p2->eFrmType ) return 1; + if( p1->eStart!=p2->eStart ) return 1; + if( p1->eEnd!=p2->eEnd ) return 1; + if( p1->eExclude!=p2->eExclude ) return 1; + if( sqlite3ExprCompare(pParse, p1->pStart, p2->pStart, -1) ) return 1; + if( sqlite3ExprCompare(pParse, p1->pEnd, p2->pEnd, -1) ) return 1; + if( (res = sqlite3ExprListCompare(p1->pPartition, p2->pPartition, -1)) ){ + return res; + } + if( (res = sqlite3ExprListCompare(p1->pOrderBy, p2->pOrderBy, -1)) ){ + return res; + } + if( bFilter ){ + if( (res = sqlite3ExprCompare(pParse, p1->pFilter, p2->pFilter, -1)) ){ + return res; + } + } + return 0; +} + + +/* +** This is called by code in select.c before it calls sqlite3WhereBegin() +** to begin iterating through the sub-query results. It is used to allocate +** and initialize registers and cursors used by sqlite3WindowCodeStep(). +*/ +SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse *pParse, Select *pSelect){ + Window *pWin; + int nEphExpr; + Window *pMWin; + Vdbe *v; + + assert( pSelect->pSrc->a[0].fg.isSubquery ); + nEphExpr = pSelect->pSrc->a[0].u4.pSubq->pSelect->pEList->nExpr; + pMWin = pSelect->pWin; + v = sqlite3GetVdbe(pParse); + + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, nEphExpr); + sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr); + sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+2, pMWin->iEphCsr); + sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+3, pMWin->iEphCsr); + + /* Allocate registers to use for PARTITION BY values, if any. Initialize + ** said registers to NULL. */ + if( pMWin->pPartition ){ + int nExpr = pMWin->pPartition->nExpr; + pMWin->regPart = pParse->nMem+1; + pParse->nMem += nExpr; + sqlite3VdbeAddOp3(v, OP_Null, 0, pMWin->regPart, pMWin->regPart+nExpr-1); + } + + pMWin->regOne = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regOne); + + if( pMWin->eExclude ){ + pMWin->regStartRowid = ++pParse->nMem; + pMWin->regEndRowid = ++pParse->nMem; + pMWin->csrApp = pParse->nTab++; + sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regStartRowid); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pMWin->regEndRowid); + sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->csrApp, pMWin->iEphCsr); + return; + } + + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + FuncDef *p = pWin->pWFunc; + if( (p->funcFlags & SQLITE_FUNC_MINMAX) && pWin->eStart!=TK_UNBOUNDED ){ + /* The inline versions of min() and max() require a single ephemeral + ** table and 3 registers. The registers are used as follows: + ** + ** regApp+0: slot to copy min()/max() argument to for MakeRecord + ** regApp+1: integer value used to ensure keys are unique + ** regApp+2: output of MakeRecord + */ + ExprList *pList; + KeyInfo *pKeyInfo; + assert( ExprUseXList(pWin->pOwner) ); + pList = pWin->pOwner->x.pList; + pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0); + pWin->csrApp = pParse->nTab++; + pWin->regApp = pParse->nMem+1; + pParse->nMem += 3; + if( pKeyInfo && pWin->pWFunc->zName[1]=='i' ){ + assert( pKeyInfo->aSortFlags[0]==0 ); + pKeyInfo->aSortFlags[0] = KEYINFO_ORDER_DESC; + } + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2); + sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1); + } + else if( p->zName==nth_valueName || p->zName==first_valueName ){ + /* Allocate two registers at pWin->regApp. These will be used to + ** store the start and end index of the current frame. */ + pWin->regApp = pParse->nMem+1; + pWin->csrApp = pParse->nTab++; + pParse->nMem += 2; + sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr); + } + else if( p->zName==leadName || p->zName==lagName ){ + pWin->csrApp = pParse->nTab++; + sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr); + } + } +} + +#define WINDOW_STARTING_INT 0 +#define WINDOW_ENDING_INT 1 +#define WINDOW_NTH_VALUE_INT 2 +#define WINDOW_STARTING_NUM 3 +#define WINDOW_ENDING_NUM 4 + +/* +** A "PRECEDING " (eCond==0) or "FOLLOWING " (eCond==1) or the +** value of the second argument to nth_value() (eCond==2) has just been +** evaluated and the result left in register reg. This function generates VM +** code to check that the value is a non-negative integer and throws an +** exception if it is not. +*/ +static void windowCheckValue(Parse *pParse, int reg, int eCond){ + static const char *azErr[] = { + "frame starting offset must be a non-negative integer", + "frame ending offset must be a non-negative integer", + "second argument to nth_value must be a positive integer", + "frame starting offset must be a non-negative number", + "frame ending offset must be a non-negative number", + }; + static int aOp[] = { OP_Ge, OP_Ge, OP_Gt, OP_Ge, OP_Ge }; + Vdbe *v = sqlite3GetVdbe(pParse); + int regZero = sqlite3GetTempReg(pParse); + assert( eCond>=0 && eCond=WINDOW_STARTING_NUM ){ + int regString = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC); + sqlite3VdbeAddOp3(v, OP_Ge, regString, sqlite3VdbeCurrentAddr(v)+2, reg); + sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC|SQLITE_JUMPIFNULL); + VdbeCoverage(v); + assert( eCond==3 || eCond==4 ); + VdbeCoverageIf(v, eCond==3); + VdbeCoverageIf(v, eCond==4); + }else{ + sqlite3VdbeAddOp2(v, OP_MustBeInt, reg, sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); + assert( eCond==0 || eCond==1 || eCond==2 ); + VdbeCoverageIf(v, eCond==0); + VdbeCoverageIf(v, eCond==1); + VdbeCoverageIf(v, eCond==2); + } + sqlite3VdbeAddOp3(v, aOp[eCond], regZero, sqlite3VdbeCurrentAddr(v)+2, reg); + sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC); + VdbeCoverageNeverNullIf(v, eCond==0); /* NULL case captured by */ + VdbeCoverageNeverNullIf(v, eCond==1); /* the OP_MustBeInt */ + VdbeCoverageNeverNullIf(v, eCond==2); + VdbeCoverageNeverNullIf(v, eCond==3); /* NULL case caught by */ + VdbeCoverageNeverNullIf(v, eCond==4); /* the OP_Ge */ + sqlite3MayAbort(pParse); + sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_ERROR, OE_Abort); + sqlite3VdbeAppendP4(v, (void*)azErr[eCond], P4_STATIC); + sqlite3ReleaseTempReg(pParse, regZero); +} + +/* +** Return the number of arguments passed to the window-function associated +** with the object passed as the only argument to this function. +*/ +static int windowArgCount(Window *pWin){ + const ExprList *pList; + assert( ExprUseXList(pWin->pOwner) ); + pList = pWin->pOwner->x.pList; + return (pList ? pList->nExpr : 0); +} + +typedef struct WindowCodeArg WindowCodeArg; +typedef struct WindowCsrAndReg WindowCsrAndReg; + +/* +** See comments above struct WindowCodeArg. +*/ +struct WindowCsrAndReg { + int csr; /* Cursor number */ + int reg; /* First in array of peer values */ +}; + +/* +** A single instance of this structure is allocated on the stack by +** sqlite3WindowCodeStep() and a pointer to it passed to the various helper +** routines. This is to reduce the number of arguments required by each +** helper function. +** +** regArg: +** Each window function requires an accumulator register (just as an +** ordinary aggregate function does). This variable is set to the first +** in an array of accumulator registers - one for each window function +** in the WindowCodeArg.pMWin list. +** +** eDelete: +** The window functions implementation sometimes caches the input rows +** that it processes in a temporary table. If it is not zero, this +** variable indicates when rows may be removed from the temp table (in +** order to reduce memory requirements - it would always be safe just +** to leave them there). Possible values for eDelete are: +** +** WINDOW_RETURN_ROW: +** An input row can be discarded after it is returned to the caller. +** +** WINDOW_AGGINVERSE: +** An input row can be discarded after the window functions xInverse() +** callbacks have been invoked in it. +** +** WINDOW_AGGSTEP: +** An input row can be discarded after the window functions xStep() +** callbacks have been invoked in it. +** +** start,current,end +** Consider a window-frame similar to the following: +** +** (ORDER BY a, b GROUPS BETWEEN 2 PRECEDING AND 2 FOLLOWING) +** +** The windows functions implementation caches the input rows in a temp +** table, sorted by "a, b" (it actually populates the cache lazily, and +** aggressively removes rows once they are no longer required, but that's +** a mere detail). It keeps three cursors open on the temp table. One +** (current) that points to the next row to return to the query engine +** once its window function values have been calculated. Another (end) +** points to the next row to call the xStep() method of each window function +** on (so that it is 2 groups ahead of current). And a third (start) that +** points to the next row to call the xInverse() method of each window +** function on. +** +** Each cursor (start, current and end) consists of a VDBE cursor +** (WindowCsrAndReg.csr) and an array of registers (starting at +** WindowCodeArg.reg) that always contains a copy of the peer values +** read from the corresponding cursor. +** +** Depending on the window-frame in question, all three cursors may not +** be required. In this case both WindowCodeArg.csr and reg are set to +** 0. +*/ +struct WindowCodeArg { + Parse *pParse; /* Parse context */ + Window *pMWin; /* First in list of functions being processed */ + Vdbe *pVdbe; /* VDBE object */ + int addrGosub; /* OP_Gosub to this address to return one row */ + int regGosub; /* Register used with OP_Gosub(addrGosub) */ + int regArg; /* First in array of accumulator registers */ + int eDelete; /* See above */ + int regRowid; + + WindowCsrAndReg start; + WindowCsrAndReg current; + WindowCsrAndReg end; +}; + +/* +** Generate VM code to read the window frames peer values from cursor csr into +** an array of registers starting at reg. +*/ +static void windowReadPeerValues( + WindowCodeArg *p, + int csr, + int reg +){ + Window *pMWin = p->pMWin; + ExprList *pOrderBy = pMWin->pOrderBy; + if( pOrderBy ){ + Vdbe *v = sqlite3GetVdbe(p->pParse); + ExprList *pPart = pMWin->pPartition; + int iColOff = pMWin->nBufferCol + (pPart ? pPart->nExpr : 0); + int i; + for(i=0; inExpr; i++){ + sqlite3VdbeAddOp3(v, OP_Column, csr, iColOff+i, reg+i); + } + } +} + +/* +** Generate VM code to invoke either xStep() (if bInverse is 0) or +** xInverse (if bInverse is non-zero) for each window function in the +** linked list starting at pMWin. Or, for built-in window functions +** that do not use the standard function API, generate the required +** inline VM code. +** +** If argument csr is greater than or equal to 0, then argument reg is +** the first register in an array of registers guaranteed to be large +** enough to hold the array of arguments for each function. In this case +** the arguments are extracted from the current row of csr into the +** array of registers before invoking OP_AggStep or OP_AggInverse +** +** Or, if csr is less than zero, then the array of registers at reg is +** already populated with all columns from the current row of the sub-query. +** +** If argument regPartSize is non-zero, then it is a register containing the +** number of rows in the current partition. +*/ +static void windowAggStep( + WindowCodeArg *p, + Window *pMWin, /* Linked list of window functions */ + int csr, /* Read arguments from this cursor */ + int bInverse, /* True to invoke xInverse instead of xStep */ + int reg /* Array of registers */ +){ + Parse *pParse = p->pParse; + Vdbe *v = sqlite3GetVdbe(pParse); + Window *pWin; + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + FuncDef *pFunc = pWin->pWFunc; + int regArg; + int nArg = pWin->bExprArgs ? 0 : windowArgCount(pWin); + int i; + int addrIf = 0; + + assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED ); + + /* All OVER clauses in the same window function aggregate step must + ** be the same. */ + assert( pWin==pMWin || sqlite3WindowCompare(pParse,pWin,pMWin,0)!=1 ); + + for(i=0; izName!=nth_valueName ){ + sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i); + }else{ + sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+i, reg+i); + } + } + regArg = reg; + + if( pWin->pFilter ){ + int regTmp; + assert( ExprUseXList(pWin->pOwner) ); + assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr ); + assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 ); + regTmp = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp); + addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1); + VdbeCoverage(v); + sqlite3ReleaseTempReg(pParse, regTmp); + } + + if( pMWin->regStartRowid==0 + && (pFunc->funcFlags & SQLITE_FUNC_MINMAX) + && (pWin->eStart!=TK_UNBOUNDED) + ){ + int addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regArg); + VdbeCoverage(v); + if( bInverse==0 ){ + sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1, 1); + sqlite3VdbeAddOp2(v, OP_SCopy, regArg, pWin->regApp); + sqlite3VdbeAddOp3(v, OP_MakeRecord, pWin->regApp, 2, pWin->regApp+2); + sqlite3VdbeAddOp2(v, OP_IdxInsert, pWin->csrApp, pWin->regApp+2); + }else{ + sqlite3VdbeAddOp4Int(v, OP_SeekGE, pWin->csrApp, 0, regArg, 1); + VdbeCoverageNeverTaken(v); + sqlite3VdbeAddOp1(v, OP_Delete, pWin->csrApp); + sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); + } + sqlite3VdbeJumpHere(v, addrIsNull); + }else if( pWin->regApp ){ + assert( pWin->pFilter==0 ); + assert( pFunc->zName==nth_valueName + || pFunc->zName==first_valueName + ); + assert( bInverse==0 || bInverse==1 ); + sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1); + }else if( pFunc->xSFunc!=noopStepFunc ){ + if( pWin->bExprArgs ){ + int iOp = sqlite3VdbeCurrentAddr(v); + int iEnd; + + assert( ExprUseXList(pWin->pOwner) ); + nArg = pWin->pOwner->x.pList->nExpr; + regArg = sqlite3GetTempRange(pParse, nArg); + sqlite3ExprCodeExprList(pParse, pWin->pOwner->x.pList, regArg, 0, 0); + + for(iEnd=sqlite3VdbeCurrentAddr(v); iOpopcode==OP_Column && pOp->p1==pMWin->iEphCsr ){ + pOp->p1 = csr; + } + } + } + if( pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ + CollSeq *pColl; + assert( nArg>0 ); + assert( ExprUseXList(pWin->pOwner) ); + pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr); + sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ); + } + sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep, + bInverse, regArg, pWin->regAccum); + sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, (u16)nArg); + if( pWin->bExprArgs ){ + sqlite3ReleaseTempRange(pParse, regArg, nArg); + } + } + + if( addrIf ) sqlite3VdbeJumpHere(v, addrIf); + } +} + +/* +** Values that may be passed as the second argument to windowCodeOp(). +*/ +#define WINDOW_RETURN_ROW 1 +#define WINDOW_AGGINVERSE 2 +#define WINDOW_AGGSTEP 3 + +/* +** Generate VM code to invoke either xValue() (bFin==0) or xFinalize() +** (bFin==1) for each window function in the linked list starting at +** pMWin. Or, for built-in window-functions that do not use the standard +** API, generate the equivalent VM code. +*/ +static void windowAggFinal(WindowCodeArg *p, int bFin){ + Parse *pParse = p->pParse; + Window *pMWin = p->pMWin; + Vdbe *v = sqlite3GetVdbe(pParse); + Window *pWin; + + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + if( pMWin->regStartRowid==0 + && (pWin->pWFunc->funcFlags & SQLITE_FUNC_MINMAX) + && (pWin->eStart!=TK_UNBOUNDED) + ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult); + sqlite3VdbeAddOp1(v, OP_Last, pWin->csrApp); + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_Column, pWin->csrApp, 0, pWin->regResult); + sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); + }else if( pWin->regApp ){ + assert( pMWin->regStartRowid==0 ); + }else{ + int nArg = windowArgCount(pWin); + if( bFin ){ + sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, nArg); + sqlite3VdbeAppendP4(v, pWin->pWFunc, P4_FUNCDEF); + sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult); + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); + }else{ + sqlite3VdbeAddOp3(v, OP_AggValue,pWin->regAccum,nArg,pWin->regResult); + sqlite3VdbeAppendP4(v, pWin->pWFunc, P4_FUNCDEF); + } + } + } +} + +/* +** Generate code to calculate the current values of all window functions in the +** p->pMWin list by doing a full scan of the current window frame. Store the +** results in the Window.regResult registers, ready to return the upper +** layer. +*/ +static void windowFullScan(WindowCodeArg *p){ + Window *pWin; + Parse *pParse = p->pParse; + Window *pMWin = p->pMWin; + Vdbe *v = p->pVdbe; + + int regCRowid = 0; /* Current rowid value */ + int regCPeer = 0; /* Current peer values */ + int regRowid = 0; /* AggStep rowid value */ + int regPeer = 0; /* AggStep peer values */ + + int nPeer; + int lblNext; + int lblBrk; + int addrNext; + int csr; + + VdbeModuleComment((v, "windowFullScan begin")); + + assert( pMWin!=0 ); + csr = pMWin->csrApp; + nPeer = (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0); + + lblNext = sqlite3VdbeMakeLabel(pParse); + lblBrk = sqlite3VdbeMakeLabel(pParse); + + regCRowid = sqlite3GetTempReg(pParse); + regRowid = sqlite3GetTempReg(pParse); + if( nPeer ){ + regCPeer = sqlite3GetTempRange(pParse, nPeer); + regPeer = sqlite3GetTempRange(pParse, nPeer); + } + + sqlite3VdbeAddOp2(v, OP_Rowid, pMWin->iEphCsr, regCRowid); + windowReadPeerValues(p, pMWin->iEphCsr, regCPeer); + + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); + } + + sqlite3VdbeAddOp3(v, OP_SeekGE, csr, lblBrk, pMWin->regStartRowid); + VdbeCoverage(v); + addrNext = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_Rowid, csr, regRowid); + sqlite3VdbeAddOp3(v, OP_Gt, pMWin->regEndRowid, lblBrk, regRowid); + VdbeCoverageNeverNull(v); + + if( pMWin->eExclude==TK_CURRENT ){ + sqlite3VdbeAddOp3(v, OP_Eq, regCRowid, lblNext, regRowid); + VdbeCoverageNeverNull(v); + }else if( pMWin->eExclude!=TK_NO ){ + int addr; + int addrEq = 0; + KeyInfo *pKeyInfo = 0; + + if( pMWin->pOrderBy ){ + pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pMWin->pOrderBy, 0, 0); + } + if( pMWin->eExclude==TK_TIES ){ + addrEq = sqlite3VdbeAddOp3(v, OP_Eq, regCRowid, 0, regRowid); + VdbeCoverageNeverNull(v); + } + if( pKeyInfo ){ + windowReadPeerValues(p, csr, regPeer); + sqlite3VdbeAddOp3(v, OP_Compare, regPeer, regCPeer, nPeer); + sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO); + addr = sqlite3VdbeCurrentAddr(v)+1; + sqlite3VdbeAddOp3(v, OP_Jump, addr, lblNext, addr); + VdbeCoverageEqNe(v); + }else{ + sqlite3VdbeAddOp2(v, OP_Goto, 0, lblNext); + } + if( addrEq ) sqlite3VdbeJumpHere(v, addrEq); + } + + windowAggStep(p, pMWin, csr, 0, p->regArg); + + sqlite3VdbeResolveLabel(v, lblNext); + sqlite3VdbeAddOp2(v, OP_Next, csr, addrNext); + VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addrNext-1); + sqlite3VdbeJumpHere(v, addrNext+1); + sqlite3ReleaseTempReg(pParse, regRowid); + sqlite3ReleaseTempReg(pParse, regCRowid); + if( nPeer ){ + sqlite3ReleaseTempRange(pParse, regPeer, nPeer); + sqlite3ReleaseTempRange(pParse, regCPeer, nPeer); + } + + windowAggFinal(p, 1); + VdbeModuleComment((v, "windowFullScan end")); +} + +/* +** Invoke the sub-routine at regGosub (generated by code in select.c) to +** return the current row of Window.iEphCsr. If all window functions are +** aggregate window functions that use the standard API, a single +** OP_Gosub instruction is all that this routine generates. Extra VM code +** for per-row processing is only generated for the following built-in window +** functions: +** +** nth_value() +** first_value() +** lag() +** lead() +*/ +static void windowReturnOneRow(WindowCodeArg *p){ + Window *pMWin = p->pMWin; + Vdbe *v = p->pVdbe; + + if( pMWin->regStartRowid ){ + windowFullScan(p); + }else{ + Parse *pParse = p->pParse; + Window *pWin; + + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + FuncDef *pFunc = pWin->pWFunc; + assert( ExprUseXList(pWin->pOwner) ); + if( pFunc->zName==nth_valueName + || pFunc->zName==first_valueName + ){ + int csr = pWin->csrApp; + int lbl = sqlite3VdbeMakeLabel(pParse); + int tmpReg = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult); + + if( pFunc->zName==nth_valueName ){ + sqlite3VdbeAddOp3(v, OP_Column,pMWin->iEphCsr,pWin->iArgCol+1,tmpReg); + windowCheckValue(pParse, tmpReg, 2); + }else{ + sqlite3VdbeAddOp2(v, OP_Integer, 1, tmpReg); + } + sqlite3VdbeAddOp3(v, OP_Add, tmpReg, pWin->regApp, tmpReg); + sqlite3VdbeAddOp3(v, OP_Gt, pWin->regApp+1, lbl, tmpReg); + VdbeCoverageNeverNull(v); + sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, 0, tmpReg); + VdbeCoverageNeverTaken(v); + sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult); + sqlite3VdbeResolveLabel(v, lbl); + sqlite3ReleaseTempReg(pParse, tmpReg); + } + else if( pFunc->zName==leadName || pFunc->zName==lagName ){ + int nArg = pWin->pOwner->x.pList->nExpr; + int csr = pWin->csrApp; + int lbl = sqlite3VdbeMakeLabel(pParse); + int tmpReg = sqlite3GetTempReg(pParse); + int iEph = pMWin->iEphCsr; + + if( nArg<3 ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult); + }else{ + sqlite3VdbeAddOp3(v, OP_Column, iEph,pWin->iArgCol+2,pWin->regResult); + } + sqlite3VdbeAddOp2(v, OP_Rowid, iEph, tmpReg); + if( nArg<2 ){ + int val = (pFunc->zName==leadName ? 1 : -1); + sqlite3VdbeAddOp2(v, OP_AddImm, tmpReg, val); + }else{ + int op = (pFunc->zName==leadName ? OP_Add : OP_Subtract); + int tmpReg2 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+1, tmpReg2); + sqlite3VdbeAddOp3(v, op, tmpReg2, tmpReg, tmpReg); + sqlite3ReleaseTempReg(pParse, tmpReg2); + } + + sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, lbl, tmpReg); + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult); + sqlite3VdbeResolveLabel(v, lbl); + sqlite3ReleaseTempReg(pParse, tmpReg); + } + } + } + sqlite3VdbeAddOp2(v, OP_Gosub, p->regGosub, p->addrGosub); +} + +/* +** Generate code to set the accumulator register for each window function +** in the linked list passed as the second argument to NULL. And perform +** any equivalent initialization required by any built-in window functions +** in the list. +*/ +static int windowInitAccum(Parse *pParse, Window *pMWin){ + Vdbe *v = sqlite3GetVdbe(pParse); + int regArg; + int nArg = 0; + Window *pWin; + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + FuncDef *pFunc = pWin->pWFunc; + assert( pWin->regAccum ); + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); + nArg = MAX(nArg, windowArgCount(pWin)); + if( pMWin->regStartRowid==0 ){ + if( pFunc->zName==nth_valueName || pFunc->zName==first_valueName ){ + sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1); + } + + if( (pFunc->funcFlags & SQLITE_FUNC_MINMAX) && pWin->csrApp ){ + assert( pWin->eStart!=TK_UNBOUNDED ); + sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1); + } + } + } + regArg = pParse->nMem+1; + pParse->nMem += nArg; + return regArg; +} + +/* +** Return true if the current frame should be cached in the ephemeral table, +** even if there are no xInverse() calls required. +*/ +static int windowCacheFrame(Window *pMWin){ + Window *pWin; + if( pMWin->regStartRowid ) return 1; + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + FuncDef *pFunc = pWin->pWFunc; + if( (pFunc->zName==nth_valueName) + || (pFunc->zName==first_valueName) + || (pFunc->zName==leadName) + || (pFunc->zName==lagName) + ){ + return 1; + } + } + return 0; +} + +/* +** regOld and regNew are each the first register in an array of size +** pOrderBy->nExpr. This function generates code to compare the two +** arrays of registers using the collation sequences and other comparison +** parameters specified by pOrderBy. +** +** If the two arrays are not equal, the contents of regNew is copied to +** regOld and control falls through. Otherwise, if the contents of the arrays +** are equal, an OP_Goto is executed. The address of the OP_Goto is returned. +*/ +static void windowIfNewPeer( + Parse *pParse, + ExprList *pOrderBy, + int regNew, /* First in array of new values */ + int regOld, /* First in array of old values */ + int addr /* Jump here */ +){ + Vdbe *v = sqlite3GetVdbe(pParse); + if( pOrderBy ){ + int nVal = pOrderBy->nExpr; + KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0); + sqlite3VdbeAddOp3(v, OP_Compare, regOld, regNew, nVal); + sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO); + sqlite3VdbeAddOp3(v, OP_Jump, + sqlite3VdbeCurrentAddr(v)+1, addr, sqlite3VdbeCurrentAddr(v)+1 + ); + VdbeCoverageEqNe(v); + sqlite3VdbeAddOp3(v, OP_Copy, regNew, regOld, nVal-1); + }else{ + sqlite3VdbeAddOp2(v, OP_Goto, 0, addr); + } +} + +/* +** This function is called as part of generating VM programs for RANGE +** offset PRECEDING/FOLLOWING frame boundaries. Assuming "ASC" order for +** the ORDER BY term in the window, and that argument op is OP_Ge, it generates +** code equivalent to: +** +** if( csr1.peerVal + regVal >= csr2.peerVal ) goto lbl; +** +** The value of parameter op may also be OP_Gt or OP_Le. In these cases the +** operator in the above pseudo-code is replaced with ">" or "<=", respectively. +** +** If the sort-order for the ORDER BY term in the window is DESC, then the +** comparison is reversed. Instead of adding regVal to csr1.peerVal, it is +** subtracted. And the comparison operator is inverted to - ">=" becomes "<=", +** ">" becomes "<", and so on. So, with DESC sort order, if the argument op +** is OP_Ge, the generated code is equivalent to: +** +** if( csr1.peerVal - regVal <= csr2.peerVal ) goto lbl; +** +** A special type of arithmetic is used such that if csr1.peerVal is not +** a numeric type (real or integer), then the result of the addition +** or subtraction is a a copy of csr1.peerVal. +*/ +static void windowCodeRangeTest( + WindowCodeArg *p, + int op, /* OP_Ge, OP_Gt, or OP_Le */ + int csr1, /* Cursor number for cursor 1 */ + int regVal, /* Register containing non-negative number */ + int csr2, /* Cursor number for cursor 2 */ + int lbl /* Jump destination if condition is true */ +){ + Parse *pParse = p->pParse; + Vdbe *v = sqlite3GetVdbe(pParse); + ExprList *pOrderBy = p->pMWin->pOrderBy; /* ORDER BY clause for window */ + int reg1 = sqlite3GetTempReg(pParse); /* Reg. for csr1.peerVal+regVal */ + int reg2 = sqlite3GetTempReg(pParse); /* Reg. for csr2.peerVal */ + int regString = ++pParse->nMem; /* Reg. for constant value '' */ + int arith = OP_Add; /* OP_Add or OP_Subtract */ + int addrGe; /* Jump destination */ + int addrDone = sqlite3VdbeMakeLabel(pParse); /* Address past OP_Ge */ + CollSeq *pColl; + + /* Read the peer-value from each cursor into a register */ + windowReadPeerValues(p, csr1, reg1); + windowReadPeerValues(p, csr2, reg2); + + assert( op==OP_Ge || op==OP_Gt || op==OP_Le ); + assert( pOrderBy && pOrderBy->nExpr==1 ); + if( pOrderBy->a[0].fg.sortFlags & KEYINFO_ORDER_DESC ){ + switch( op ){ + case OP_Ge: op = OP_Le; break; + case OP_Gt: op = OP_Lt; break; + default: assert( op==OP_Le ); op = OP_Ge; break; + } + arith = OP_Subtract; + } + + VdbeModuleComment((v, "CodeRangeTest: if( R%d %s R%d %s R%d ) goto lbl", + reg1, (arith==OP_Add ? "+" : "-"), regVal, + ((op==OP_Ge) ? ">=" : (op==OP_Le) ? "<=" : (op==OP_Gt) ? ">" : "<"), reg2 + )); + + /* If the BIGNULL flag is set for the ORDER BY, then it is required to + ** consider NULL values to be larger than all other values, instead of + ** the usual smaller. The VDBE opcodes OP_Ge and so on do not handle this + ** (and adding that capability causes a performance regression), so + ** instead if the BIGNULL flag is set then cases where either reg1 or + ** reg2 are NULL are handled separately in the following block. The code + ** generated is equivalent to: + ** + ** if( reg1 IS NULL ){ + ** if( op==OP_Ge ) goto lbl; + ** if( op==OP_Gt && reg2 IS NOT NULL ) goto lbl; + ** if( op==OP_Le && reg2 IS NULL ) goto lbl; + ** }else if( reg2 IS NULL ){ + ** if( op==OP_Le ) goto lbl; + ** } + ** + ** Additionally, if either reg1 or reg2 are NULL but the jump to lbl is + ** not taken, control jumps over the comparison operator coded below this + ** block. */ + if( pOrderBy->a[0].fg.sortFlags & KEYINFO_ORDER_BIGNULL ){ + /* This block runs if reg1 contains a NULL. */ + int addr = sqlite3VdbeAddOp1(v, OP_NotNull, reg1); VdbeCoverage(v); + switch( op ){ + case OP_Ge: + sqlite3VdbeAddOp2(v, OP_Goto, 0, lbl); + break; + case OP_Gt: + sqlite3VdbeAddOp2(v, OP_NotNull, reg2, lbl); + VdbeCoverage(v); + break; + case OP_Le: + sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); + VdbeCoverage(v); + break; + default: assert( op==OP_Lt ); /* no-op */ break; + } + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrDone); + + /* This block runs if reg1 is not NULL, but reg2 is. */ + sqlite3VdbeJumpHere(v, addr); + sqlite3VdbeAddOp2(v, OP_IsNull, reg2, + (op==OP_Gt || op==OP_Ge) ? addrDone : lbl); + VdbeCoverage(v); + } + + /* Register reg1 currently contains csr1.peerVal (the peer-value from csr1). + ** This block adds (or subtracts for DESC) the numeric value in regVal + ** from it. Or, if reg1 is not numeric (it is a NULL, a text value or a blob), + ** then leave reg1 as it is. In pseudo-code, this is implemented as: + ** + ** if( reg1>='' ) goto addrGe; + ** reg1 = reg1 +/- regVal + ** addrGe: + ** + ** Since all strings and blobs are greater-than-or-equal-to an empty string, + ** the add/subtract is skipped for these, as required. If reg1 is a NULL, + ** then the arithmetic is performed, but since adding or subtracting from + ** NULL is always NULL anyway, this case is handled as required too. */ + sqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC); + addrGe = sqlite3VdbeAddOp3(v, OP_Ge, regString, 0, reg1); + VdbeCoverage(v); + if( (op==OP_Ge && arith==OP_Add) || (op==OP_Le && arith==OP_Subtract) ){ + sqlite3VdbeAddOp3(v, op, reg2, lbl, reg1); VdbeCoverage(v); + } + sqlite3VdbeAddOp3(v, arith, regVal, reg1, reg1); + sqlite3VdbeJumpHere(v, addrGe); + + /* Compare registers reg2 and reg1, taking the jump if required. Note that + ** control skips over this test if the BIGNULL flag is set and either + ** reg1 or reg2 contain a NULL value. */ + sqlite3VdbeAddOp3(v, op, reg2, lbl, reg1); VdbeCoverage(v); + pColl = sqlite3ExprNNCollSeq(pParse, pOrderBy->a[0].pExpr); + sqlite3VdbeAppendP4(v, (void*)pColl, P4_COLLSEQ); + sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); + sqlite3VdbeResolveLabel(v, addrDone); + + assert( op==OP_Ge || op==OP_Gt || op==OP_Lt || op==OP_Le ); + testcase(op==OP_Ge); VdbeCoverageIf(v, op==OP_Ge); + testcase(op==OP_Lt); VdbeCoverageIf(v, op==OP_Lt); + testcase(op==OP_Le); VdbeCoverageIf(v, op==OP_Le); + testcase(op==OP_Gt); VdbeCoverageIf(v, op==OP_Gt); + sqlite3ReleaseTempReg(pParse, reg1); + sqlite3ReleaseTempReg(pParse, reg2); + + VdbeModuleComment((v, "CodeRangeTest: end")); +} + +/* +** Helper function for sqlite3WindowCodeStep(). Each call to this function +** generates VM code for a single RETURN_ROW, AGGSTEP or AGGINVERSE +** operation. Refer to the header comment for sqlite3WindowCodeStep() for +** details. +*/ +static int windowCodeOp( + WindowCodeArg *p, /* Context object */ + int op, /* WINDOW_RETURN_ROW, AGGSTEP or AGGINVERSE */ + int regCountdown, /* Register for OP_IfPos countdown */ + int jumpOnEof /* Jump here if stepped cursor reaches EOF */ +){ + int csr, reg; + Parse *pParse = p->pParse; + Window *pMWin = p->pMWin; + int ret = 0; + Vdbe *v = p->pVdbe; + int addrContinue = 0; + int bPeer = (pMWin->eFrmType!=TK_ROWS); + + int lblDone = sqlite3VdbeMakeLabel(pParse); + int addrNextRange = 0; + + /* Special case - WINDOW_AGGINVERSE is always a no-op if the frame + ** starts with UNBOUNDED PRECEDING. */ + if( op==WINDOW_AGGINVERSE && pMWin->eStart==TK_UNBOUNDED ){ + assert( regCountdown==0 && jumpOnEof==0 ); + return 0; + } + + if( regCountdown>0 ){ + if( pMWin->eFrmType==TK_RANGE ){ + addrNextRange = sqlite3VdbeCurrentAddr(v); + assert( op==WINDOW_AGGINVERSE || op==WINDOW_AGGSTEP ); + if( op==WINDOW_AGGINVERSE ){ + if( pMWin->eStart==TK_FOLLOWING ){ + windowCodeRangeTest( + p, OP_Le, p->current.csr, regCountdown, p->start.csr, lblDone + ); + }else{ + windowCodeRangeTest( + p, OP_Ge, p->start.csr, regCountdown, p->current.csr, lblDone + ); + } + }else{ + windowCodeRangeTest( + p, OP_Gt, p->end.csr, regCountdown, p->current.csr, lblDone + ); + } + }else{ + sqlite3VdbeAddOp3(v, OP_IfPos, regCountdown, lblDone, 1); + VdbeCoverage(v); + } + } + + if( op==WINDOW_RETURN_ROW && pMWin->regStartRowid==0 ){ + windowAggFinal(p, 0); + } + addrContinue = sqlite3VdbeCurrentAddr(v); + + /* If this is a (RANGE BETWEEN a FOLLOWING AND b FOLLOWING) or + ** (RANGE BETWEEN b PRECEDING AND a PRECEDING) frame, ensure the + ** start cursor does not advance past the end cursor within the + ** temporary table. It otherwise might, if (a>b). Also ensure that, + ** if the input cursor is still finding new rows, that the end + ** cursor does not go past it to EOF. */ + if( pMWin->eStart==pMWin->eEnd && regCountdown + && pMWin->eFrmType==TK_RANGE + ){ + int regRowid1 = sqlite3GetTempReg(pParse); + int regRowid2 = sqlite3GetTempReg(pParse); + if( op==WINDOW_AGGINVERSE ){ + sqlite3VdbeAddOp2(v, OP_Rowid, p->start.csr, regRowid1); + sqlite3VdbeAddOp2(v, OP_Rowid, p->end.csr, regRowid2); + sqlite3VdbeAddOp3(v, OP_Ge, regRowid2, lblDone, regRowid1); + VdbeCoverage(v); + }else if( p->regRowid ){ + sqlite3VdbeAddOp2(v, OP_Rowid, p->end.csr, regRowid1); + sqlite3VdbeAddOp3(v, OP_Ge, p->regRowid, lblDone, regRowid1); + VdbeCoverageNeverNull(v); + } + sqlite3ReleaseTempReg(pParse, regRowid1); + sqlite3ReleaseTempReg(pParse, regRowid2); + assert( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_FOLLOWING ); + } + + switch( op ){ + case WINDOW_RETURN_ROW: + csr = p->current.csr; + reg = p->current.reg; + windowReturnOneRow(p); + break; + + case WINDOW_AGGINVERSE: + csr = p->start.csr; + reg = p->start.reg; + if( pMWin->regStartRowid ){ + assert( pMWin->regEndRowid ); + sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regStartRowid, 1); + }else{ + windowAggStep(p, pMWin, csr, 1, p->regArg); + } + break; + + default: + assert( op==WINDOW_AGGSTEP ); + csr = p->end.csr; + reg = p->end.reg; + if( pMWin->regStartRowid ){ + assert( pMWin->regEndRowid ); + sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regEndRowid, 1); + }else{ + windowAggStep(p, pMWin, csr, 0, p->regArg); + } + break; + } + + if( op==p->eDelete ){ + sqlite3VdbeAddOp1(v, OP_Delete, csr); + sqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION); + } + + if( jumpOnEof ){ + sqlite3VdbeAddOp2(v, OP_Next, csr, sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); + ret = sqlite3VdbeAddOp0(v, OP_Goto); + }else{ + sqlite3VdbeAddOp2(v, OP_Next, csr, sqlite3VdbeCurrentAddr(v)+1+bPeer); + VdbeCoverage(v); + if( bPeer ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, lblDone); + } + } + + if( bPeer ){ + int nReg = (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0); + int regTmp = (nReg ? sqlite3GetTempRange(pParse, nReg) : 0); + windowReadPeerValues(p, csr, regTmp); + windowIfNewPeer(pParse, pMWin->pOrderBy, regTmp, reg, addrContinue); + sqlite3ReleaseTempRange(pParse, regTmp, nReg); + } + + if( addrNextRange ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNextRange); + } + sqlite3VdbeResolveLabel(v, lblDone); + return ret; +} + + +/* +** Allocate and return a duplicate of the Window object indicated by the +** third argument. Set the Window.pOwner field of the new object to +** pOwner. +*/ +SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){ + Window *pNew = 0; + if( ALWAYS(p) ){ + pNew = sqlite3DbMallocZero(db, sizeof(Window)); + if( pNew ){ + pNew->zName = sqlite3DbStrDup(db, p->zName); + pNew->zBase = sqlite3DbStrDup(db, p->zBase); + pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0); + pNew->pWFunc = p->pWFunc; + pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0); + pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0); + pNew->eFrmType = p->eFrmType; + pNew->eEnd = p->eEnd; + pNew->eStart = p->eStart; + pNew->eExclude = p->eExclude; + pNew->regResult = p->regResult; + pNew->regAccum = p->regAccum; + pNew->iArgCol = p->iArgCol; + pNew->iEphCsr = p->iEphCsr; + pNew->bExprArgs = p->bExprArgs; + pNew->pStart = sqlite3ExprDup(db, p->pStart, 0); + pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0); + pNew->pOwner = pOwner; + pNew->bImplicitFrame = p->bImplicitFrame; + } + } + return pNew; +} + +/* +** Return a copy of the linked list of Window objects passed as the +** second argument. +*/ +SQLITE_PRIVATE Window *sqlite3WindowListDup(sqlite3 *db, Window *p){ + Window *pWin; + Window *pRet = 0; + Window **pp = &pRet; + + for(pWin=p; pWin; pWin=pWin->pNextWin){ + *pp = sqlite3WindowDup(db, 0, pWin); + if( *pp==0 ) break; + pp = &((*pp)->pNextWin); + } + + return pRet; +} + +/* +** Return true if it can be determined at compile time that expression +** pExpr evaluates to a value that, when cast to an integer, is greater +** than zero. False otherwise. +** +** If an OOM error occurs, this function sets the Parse.db.mallocFailed +** flag and returns zero. +*/ +static int windowExprGtZero(Parse *pParse, Expr *pExpr){ + int ret = 0; + sqlite3 *db = pParse->db; + sqlite3_value *pVal = 0; + sqlite3ValueFromExpr(db, pExpr, db->enc, SQLITE_AFF_NUMERIC, &pVal); + if( pVal && sqlite3_value_int(pVal)>0 ){ + ret = 1; + } + sqlite3ValueFree(pVal); + return ret; +} + +/* +** sqlite3WhereBegin() has already been called for the SELECT statement +** passed as the second argument when this function is invoked. It generates +** code to populate the Window.regResult register for each window function +** and invoke the sub-routine at instruction addrGosub once for each row. +** sqlite3WhereEnd() is always called before returning. +** +** This function handles several different types of window frames, which +** require slightly different processing. The following pseudo code is +** used to implement window frames of the form: +** +** ROWS BETWEEN PRECEDING AND FOLLOWING +** +** Other window frame types use variants of the following: +** +** ... loop started by sqlite3WhereBegin() ... +** if( new partition ){ +** Gosub flush +** } +** Insert new row into eph table. +** +** if( first row of partition ){ +** // Rewind three cursors, all open on the eph table. +** Rewind(csrEnd); +** Rewind(csrStart); +** Rewind(csrCurrent); +** +** regEnd = // FOLLOWING expression +** regStart = // PRECEDING expression +** }else{ +** // First time this branch is taken, the eph table contains two +** // rows. The first row in the partition, which all three cursors +** // currently point to, and the following row. +** AGGSTEP +** if( (regEnd--)<=0 ){ +** RETURN_ROW +** if( (regStart--)<=0 ){ +** AGGINVERSE +** } +** } +** } +** } +** flush: +** AGGSTEP +** while( 1 ){ +** RETURN ROW +** if( csrCurrent is EOF ) break; +** if( (regStart--)<=0 ){ +** AggInverse(csrStart) +** Next(csrStart) +** } +** } +** +** The pseudo-code above uses the following shorthand: +** +** AGGSTEP: invoke the aggregate xStep() function for each window function +** with arguments read from the current row of cursor csrEnd, then +** step cursor csrEnd forward one row (i.e. sqlite3BtreeNext()). +** +** RETURN_ROW: return a row to the caller based on the contents of the +** current row of csrCurrent and the current state of all +** aggregates. Then step cursor csrCurrent forward one row. +** +** AGGINVERSE: invoke the aggregate xInverse() function for each window +** functions with arguments read from the current row of cursor +** csrStart. Then step csrStart forward one row. +** +** There are two other ROWS window frames that are handled significantly +** differently from the above - "BETWEEN PRECEDING AND PRECEDING" +** and "BETWEEN FOLLOWING AND FOLLOWING". These are special +** cases because they change the order in which the three cursors (csrStart, +** csrCurrent and csrEnd) iterate through the ephemeral table. Cases that +** use UNBOUNDED or CURRENT ROW are much simpler variations on one of these +** three. +** +** ROWS BETWEEN PRECEDING AND PRECEDING +** +** ... loop started by sqlite3WhereBegin() ... +** if( new partition ){ +** Gosub flush +** } +** Insert new row into eph table. +** if( first row of partition ){ +** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent) +** regEnd = +** regStart = +** }else{ +** if( (regEnd--)<=0 ){ +** AGGSTEP +** } +** RETURN_ROW +** if( (regStart--)<=0 ){ +** AGGINVERSE +** } +** } +** } +** flush: +** if( (regEnd--)<=0 ){ +** AGGSTEP +** } +** RETURN_ROW +** +** +** ROWS BETWEEN FOLLOWING AND FOLLOWING +** +** ... loop started by sqlite3WhereBegin() ... +** if( new partition ){ +** Gosub flush +** } +** Insert new row into eph table. +** if( first row of partition ){ +** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent) +** regEnd = +** regStart = regEnd - +** }else{ +** AGGSTEP +** if( (regEnd--)<=0 ){ +** RETURN_ROW +** } +** if( (regStart--)<=0 ){ +** AGGINVERSE +** } +** } +** } +** flush: +** AGGSTEP +** while( 1 ){ +** if( (regEnd--)<=0 ){ +** RETURN_ROW +** if( eof ) break; +** } +** if( (regStart--)<=0 ){ +** AGGINVERSE +** if( eof ) break +** } +** } +** while( !eof csrCurrent ){ +** RETURN_ROW +** } +** +** For the most part, the patterns above are adapted to support UNBOUNDED by +** assuming that it is equivalent to "infinity PRECEDING/FOLLOWING" and +** CURRENT ROW by assuming that it is equivalent to "0 PRECEDING/FOLLOWING". +** This is optimized of course - branches that will never be taken and +** conditions that are always true are omitted from the VM code. The only +** exceptional case is: +** +** ROWS BETWEEN FOLLOWING AND UNBOUNDED FOLLOWING +** +** ... loop started by sqlite3WhereBegin() ... +** if( new partition ){ +** Gosub flush +** } +** Insert new row into eph table. +** if( first row of partition ){ +** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent) +** regStart = +** }else{ +** AGGSTEP +** } +** } +** flush: +** AGGSTEP +** while( 1 ){ +** if( (regStart--)<=0 ){ +** AGGINVERSE +** if( eof ) break +** } +** RETURN_ROW +** } +** while( !eof csrCurrent ){ +** RETURN_ROW +** } +** +** Also requiring special handling are the cases: +** +** ROWS BETWEEN PRECEDING AND PRECEDING +** ROWS BETWEEN FOLLOWING AND FOLLOWING +** +** when (expr1 < expr2). This is detected at runtime, not by this function. +** To handle this case, the pseudo-code programs depicted above are modified +** slightly to be: +** +** ... loop started by sqlite3WhereBegin() ... +** if( new partition ){ +** Gosub flush +** } +** Insert new row into eph table. +** if( first row of partition ){ +** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent) +** regEnd = +** regStart = +** if( regEnd < regStart ){ +** RETURN_ROW +** delete eph table contents +** continue +** } +** ... +** +** The new "continue" statement in the above jumps to the next iteration +** of the outer loop - the one started by sqlite3WhereBegin(). +** +** The various GROUPS cases are implemented using the same patterns as +** ROWS. The VM code is modified slightly so that: +** +** 1. The else branch in the main loop is only taken if the row just +** added to the ephemeral table is the start of a new group. In +** other words, it becomes: +** +** ... loop started by sqlite3WhereBegin() ... +** if( new partition ){ +** Gosub flush +** } +** Insert new row into eph table. +** if( first row of partition ){ +** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent) +** regEnd = +** regStart = +** }else if( new group ){ +** ... +** } +** } +** +** 2. Instead of processing a single row, each RETURN_ROW, AGGSTEP or +** AGGINVERSE step processes the current row of the relevant cursor and +** all subsequent rows belonging to the same group. +** +** RANGE window frames are a little different again. As for GROUPS, the +** main loop runs once per group only. And RETURN_ROW, AGGSTEP and AGGINVERSE +** deal in groups instead of rows. As for ROWS and GROUPS, there are three +** basic cases: +** +** RANGE BETWEEN PRECEDING AND FOLLOWING +** +** ... loop started by sqlite3WhereBegin() ... +** if( new partition ){ +** Gosub flush +** } +** Insert new row into eph table. +** if( first row of partition ){ +** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent) +** regEnd = +** regStart = +** }else{ +** AGGSTEP +** while( (csrCurrent.key + regEnd) < csrEnd.key ){ +** RETURN_ROW +** while( csrStart.key + regStart) < csrCurrent.key ){ +** AGGINVERSE +** } +** } +** } +** } +** flush: +** AGGSTEP +** while( 1 ){ +** RETURN ROW +** if( csrCurrent is EOF ) break; +** while( csrStart.key + regStart) < csrCurrent.key ){ +** AGGINVERSE +** } +** } +** } +** +** In the above notation, "csr.key" means the current value of the ORDER BY +** expression (there is only ever 1 for a RANGE that uses an FOLLOWING +** or PRECEDING AND PRECEDING +** +** ... loop started by sqlite3WhereBegin() ... +** if( new partition ){ +** Gosub flush +** } +** Insert new row into eph table. +** if( first row of partition ){ +** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent) +** regEnd = +** regStart = +** }else{ +** while( (csrEnd.key + regEnd) <= csrCurrent.key ){ +** AGGSTEP +** } +** while( (csrStart.key + regStart) < csrCurrent.key ){ +** AGGINVERSE +** } +** RETURN_ROW +** } +** } +** flush: +** while( (csrEnd.key + regEnd) <= csrCurrent.key ){ +** AGGSTEP +** } +** while( (csrStart.key + regStart) < csrCurrent.key ){ +** AGGINVERSE +** } +** RETURN_ROW +** +** RANGE BETWEEN FOLLOWING AND FOLLOWING +** +** ... loop started by sqlite3WhereBegin() ... +** if( new partition ){ +** Gosub flush +** } +** Insert new row into eph table. +** if( first row of partition ){ +** Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent) +** regEnd = +** regStart = +** }else{ +** AGGSTEP +** while( (csrCurrent.key + regEnd) < csrEnd.key ){ +** while( (csrCurrent.key + regStart) > csrStart.key ){ +** AGGINVERSE +** } +** RETURN_ROW +** } +** } +** } +** flush: +** AGGSTEP +** while( 1 ){ +** while( (csrCurrent.key + regStart) > csrStart.key ){ +** AGGINVERSE +** if( eof ) break "while( 1 )" loop. +** } +** RETURN_ROW +** } +** while( !eof csrCurrent ){ +** RETURN_ROW +** } +** +** The text above leaves out many details. Refer to the code and comments +** below for a more complete picture. +*/ +SQLITE_PRIVATE void sqlite3WindowCodeStep( + Parse *pParse, /* Parse context */ + Select *p, /* Rewritten SELECT statement */ + WhereInfo *pWInfo, /* Context returned by sqlite3WhereBegin() */ + int regGosub, /* Register for OP_Gosub */ + int addrGosub /* OP_Gosub here to return each row */ +){ + Window *pMWin = p->pWin; + ExprList *pOrderBy = pMWin->pOrderBy; + Vdbe *v = sqlite3GetVdbe(pParse); + int csrWrite; /* Cursor used to write to eph. table */ + int csrInput = p->pSrc->a[0].iCursor; /* Cursor of sub-select */ + int nInput = p->pSrc->a[0].pSTab->nCol; /* Number of cols returned by sub */ + int iInput; /* To iterate through sub cols */ + int addrNe; /* Address of OP_Ne */ + int addrGosubFlush = 0; /* Address of OP_Gosub to flush: */ + int addrInteger = 0; /* Address of OP_Integer */ + int addrEmpty; /* Address of OP_Rewind in flush: */ + int regNew; /* Array of registers holding new input row */ + int regRecord; /* regNew array in record form */ + int regNewPeer = 0; /* Peer values for new row (part of regNew) */ + int regPeer = 0; /* Peer values for current row */ + int regFlushPart = 0; /* Register for "Gosub flush_partition" */ + WindowCodeArg s; /* Context object for sub-routines */ + int lblWhereEnd; /* Label just before sqlite3WhereEnd() code */ + int regStart = 0; /* Value of PRECEDING */ + int regEnd = 0; /* Value of FOLLOWING */ + + assert( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_CURRENT + || pMWin->eStart==TK_FOLLOWING || pMWin->eStart==TK_UNBOUNDED + ); + assert( pMWin->eEnd==TK_FOLLOWING || pMWin->eEnd==TK_CURRENT + || pMWin->eEnd==TK_UNBOUNDED || pMWin->eEnd==TK_PRECEDING + ); + assert( pMWin->eExclude==0 || pMWin->eExclude==TK_CURRENT + || pMWin->eExclude==TK_GROUP || pMWin->eExclude==TK_TIES + || pMWin->eExclude==TK_NO + ); + + lblWhereEnd = sqlite3VdbeMakeLabel(pParse); + + /* Fill in the context object */ + memset(&s, 0, sizeof(WindowCodeArg)); + s.pParse = pParse; + s.pMWin = pMWin; + s.pVdbe = v; + s.regGosub = regGosub; + s.addrGosub = addrGosub; + s.current.csr = pMWin->iEphCsr; + csrWrite = s.current.csr+1; + s.start.csr = s.current.csr+2; + s.end.csr = s.current.csr+3; + + /* Figure out when rows may be deleted from the ephemeral table. There + ** are four options - they may never be deleted (eDelete==0), they may + ** be deleted as soon as they are no longer part of the window frame + ** (eDelete==WINDOW_AGGINVERSE), they may be deleted as after the row + ** has been returned to the caller (WINDOW_RETURN_ROW), or they may + ** be deleted after they enter the frame (WINDOW_AGGSTEP). */ + switch( pMWin->eStart ){ + case TK_FOLLOWING: + if( pMWin->eFrmType!=TK_RANGE + && windowExprGtZero(pParse, pMWin->pStart) + ){ + s.eDelete = WINDOW_RETURN_ROW; + } + break; + case TK_UNBOUNDED: + if( windowCacheFrame(pMWin)==0 ){ + if( pMWin->eEnd==TK_PRECEDING ){ + if( pMWin->eFrmType!=TK_RANGE + && windowExprGtZero(pParse, pMWin->pEnd) + ){ + s.eDelete = WINDOW_AGGSTEP; + } + }else{ + s.eDelete = WINDOW_RETURN_ROW; + } + } + break; + default: + s.eDelete = WINDOW_AGGINVERSE; + break; + } + + /* Allocate registers for the array of values from the sub-query, the + ** same values in record form, and the rowid used to insert said record + ** into the ephemeral table. */ + regNew = pParse->nMem+1; + pParse->nMem += nInput; + regRecord = ++pParse->nMem; + s.regRowid = ++pParse->nMem; + + /* If the window frame contains an " PRECEDING" or " FOLLOWING" + ** clause, allocate registers to store the results of evaluating each + ** . */ + if( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_FOLLOWING ){ + regStart = ++pParse->nMem; + } + if( pMWin->eEnd==TK_PRECEDING || pMWin->eEnd==TK_FOLLOWING ){ + regEnd = ++pParse->nMem; + } + + /* If this is not a "ROWS BETWEEN ..." frame, then allocate arrays of + ** registers to store copies of the ORDER BY expressions (peer values) + ** for the main loop, and for each cursor (start, current and end). */ + if( pMWin->eFrmType!=TK_ROWS ){ + int nPeer = (pOrderBy ? pOrderBy->nExpr : 0); + regNewPeer = regNew + pMWin->nBufferCol; + if( pMWin->pPartition ) regNewPeer += pMWin->pPartition->nExpr; + regPeer = pParse->nMem+1; pParse->nMem += nPeer; + s.start.reg = pParse->nMem+1; pParse->nMem += nPeer; + s.current.reg = pParse->nMem+1; pParse->nMem += nPeer; + s.end.reg = pParse->nMem+1; pParse->nMem += nPeer; + } + + /* Load the column values for the row returned by the sub-select + ** into an array of registers starting at regNew. Assemble them into + ** a record in register regRecord. */ + for(iInput=0; iInputpPartition ){ + int addr; + ExprList *pPart = pMWin->pPartition; + int nPart = pPart->nExpr; + int regNewPart = regNew + pMWin->nBufferCol; + KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0); + + regFlushPart = ++pParse->nMem; + addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart, nPart); + sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO); + sqlite3VdbeAddOp3(v, OP_Jump, addr+2, addr+4, addr+2); + VdbeCoverageEqNe(v); + addrGosubFlush = sqlite3VdbeAddOp1(v, OP_Gosub, regFlushPart); + VdbeComment((v, "call flush_partition")); + sqlite3VdbeAddOp3(v, OP_Copy, regNewPart, pMWin->regPart, nPart-1); + } + + /* Insert the new row into the ephemeral table */ + sqlite3VdbeAddOp2(v, OP_NewRowid, csrWrite, s.regRowid); + sqlite3VdbeAddOp3(v, OP_Insert, csrWrite, regRecord, s.regRowid); + addrNe = sqlite3VdbeAddOp3(v, OP_Ne, pMWin->regOne, 0, s.regRowid); + VdbeCoverageNeverNull(v); + + /* This block is run for the first row of each partition */ + s.regArg = windowInitAccum(pParse, pMWin); + + if( regStart ){ + sqlite3ExprCode(pParse, pMWin->pStart, regStart); + windowCheckValue(pParse, regStart, 0 + (pMWin->eFrmType==TK_RANGE?3:0)); + } + if( regEnd ){ + sqlite3ExprCode(pParse, pMWin->pEnd, regEnd); + windowCheckValue(pParse, regEnd, 1 + (pMWin->eFrmType==TK_RANGE?3:0)); + } + + if( pMWin->eFrmType!=TK_RANGE && pMWin->eStart==pMWin->eEnd && regStart ){ + int op = ((pMWin->eStart==TK_FOLLOWING) ? OP_Ge : OP_Le); + int addrGe = sqlite3VdbeAddOp3(v, op, regStart, 0, regEnd); + VdbeCoverageNeverNullIf(v, op==OP_Ge); /* NeverNull because bound */ + VdbeCoverageNeverNullIf(v, op==OP_Le); /* values previously checked */ + windowAggFinal(&s, 0); + sqlite3VdbeAddOp1(v, OP_Rewind, s.current.csr); + windowReturnOneRow(&s); + sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr); + sqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd); + sqlite3VdbeJumpHere(v, addrGe); + } + if( pMWin->eStart==TK_FOLLOWING && pMWin->eFrmType!=TK_RANGE && regEnd ){ + assert( pMWin->eEnd==TK_FOLLOWING ); + sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regStart); + } + + if( pMWin->eStart!=TK_UNBOUNDED ){ + sqlite3VdbeAddOp1(v, OP_Rewind, s.start.csr); + } + sqlite3VdbeAddOp1(v, OP_Rewind, s.current.csr); + sqlite3VdbeAddOp1(v, OP_Rewind, s.end.csr); + if( regPeer && pOrderBy ){ + sqlite3VdbeAddOp3(v, OP_Copy, regNewPeer, regPeer, pOrderBy->nExpr-1); + sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.start.reg, pOrderBy->nExpr-1); + sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.current.reg, pOrderBy->nExpr-1); + sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.end.reg, pOrderBy->nExpr-1); + } + + sqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd); + + sqlite3VdbeJumpHere(v, addrNe); + + /* Beginning of the block executed for the second and subsequent rows. */ + if( regPeer ){ + windowIfNewPeer(pParse, pOrderBy, regNewPeer, regPeer, lblWhereEnd); + } + if( pMWin->eStart==TK_FOLLOWING ){ + windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0); + if( pMWin->eEnd!=TK_UNBOUNDED ){ + if( pMWin->eFrmType==TK_RANGE ){ + int lbl = sqlite3VdbeMakeLabel(pParse); + int addrNext = sqlite3VdbeCurrentAddr(v); + windowCodeRangeTest(&s, OP_Ge, s.current.csr, regEnd, s.end.csr, lbl); + windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0); + windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext); + sqlite3VdbeResolveLabel(v, lbl); + }else{ + windowCodeOp(&s, WINDOW_RETURN_ROW, regEnd, 0); + windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0); + } + } + }else + if( pMWin->eEnd==TK_PRECEDING ){ + int bRPS = (pMWin->eStart==TK_PRECEDING && pMWin->eFrmType==TK_RANGE); + windowCodeOp(&s, WINDOW_AGGSTEP, regEnd, 0); + if( bRPS ) windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0); + windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0); + if( !bRPS ) windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0); + }else{ + int addr = 0; + windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0); + if( pMWin->eEnd!=TK_UNBOUNDED ){ + if( pMWin->eFrmType==TK_RANGE ){ + int lbl = 0; + addr = sqlite3VdbeCurrentAddr(v); + if( regEnd ){ + lbl = sqlite3VdbeMakeLabel(pParse); + windowCodeRangeTest(&s, OP_Ge, s.current.csr, regEnd, s.end.csr, lbl); + } + windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0); + windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0); + if( regEnd ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, addr); + sqlite3VdbeResolveLabel(v, lbl); + } + }else{ + if( regEnd ){ + addr = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0, 1); + VdbeCoverage(v); + } + windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0); + windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0); + if( regEnd ) sqlite3VdbeJumpHere(v, addr); + } + } + } + + /* End of the main input loop */ + sqlite3VdbeResolveLabel(v, lblWhereEnd); + sqlite3WhereEnd(pWInfo); + + /* Fall through */ + if( pMWin->pPartition ){ + addrInteger = sqlite3VdbeAddOp2(v, OP_Integer, 0, regFlushPart); + sqlite3VdbeJumpHere(v, addrGosubFlush); + } + + s.regRowid = 0; + addrEmpty = sqlite3VdbeAddOp1(v, OP_Rewind, csrWrite); + VdbeCoverage(v); + if( pMWin->eEnd==TK_PRECEDING ){ + int bRPS = (pMWin->eStart==TK_PRECEDING && pMWin->eFrmType==TK_RANGE); + windowCodeOp(&s, WINDOW_AGGSTEP, regEnd, 0); + if( bRPS ) windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0); + windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0); + }else if( pMWin->eStart==TK_FOLLOWING ){ + int addrStart; + int addrBreak1; + int addrBreak2; + int addrBreak3; + windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0); + if( pMWin->eFrmType==TK_RANGE ){ + addrStart = sqlite3VdbeCurrentAddr(v); + addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 1); + addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1); + }else + if( pMWin->eEnd==TK_UNBOUNDED ){ + addrStart = sqlite3VdbeCurrentAddr(v); + addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, regStart, 1); + addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, 0, 1); + }else{ + assert( pMWin->eEnd==TK_FOLLOWING ); + /* assert( regStart>=0 ); + ** regEnd = regEnd - regStart; + ** regStart = 0; */ + sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regEnd); + sqlite3VdbeAddOp2(v, OP_Integer, 0, regStart); + + addrStart = sqlite3VdbeCurrentAddr(v); + addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, regEnd, 1); + addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 1); + } + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart); + sqlite3VdbeJumpHere(v, addrBreak2); + addrStart = sqlite3VdbeCurrentAddr(v); + addrBreak3 = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart); + sqlite3VdbeJumpHere(v, addrBreak1); + sqlite3VdbeJumpHere(v, addrBreak3); + }else{ + int addrBreak; + int addrStart; + windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0); + addrStart = sqlite3VdbeCurrentAddr(v); + addrBreak = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1); + windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart); + sqlite3VdbeJumpHere(v, addrBreak); + } + sqlite3VdbeJumpHere(v, addrEmpty); + + sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr); + if( pMWin->pPartition ){ + if( pMWin->regStartRowid ){ + sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regStartRowid); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pMWin->regEndRowid); + } + sqlite3VdbeChangeP1(v, addrInteger, sqlite3VdbeCurrentAddr(v)); + sqlite3VdbeAddOp1(v, OP_Return, regFlushPart); + } +} + +#endif /* SQLITE_OMIT_WINDOWFUNC */ + +/************** End of window.c **********************************************/ +/************** Begin file parse.c *******************************************/ +/* This file is automatically generated by Lemon from input grammar +** source file "parse.y". +*/ +/* +** 2001-09-15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains SQLite's SQL parser. +** +** The canonical source code to this file ("parse.y") is a Lemon grammar +** file that specifies the input grammar and actions to take while parsing. +** That input file is processed by Lemon to generate a C-language +** implementation of a parser for the given grammar. You might be reading +** this comment as part of the translated C-code. Edits should be made +** to the original parse.y sources. +*/ + +/* #include "sqliteInt.h" */ + +/* +** Verify that the pParse->isCreate field is set +*/ +#define ASSERT_IS_CREATE assert(pParse->isCreate) + +/* +** Disable all error recovery processing in the parser push-down +** automaton. +*/ +#define YYNOERRORRECOVERY 1 + +/* +** Make yytestcase() the same as testcase() +*/ +#define yytestcase(X) testcase(X) + +/* +** Indicate that sqlite3ParserFree() will never be called with a null +** pointer. +*/ +#define YYPARSEFREENEVERNULL 1 + +/* +** In the amalgamation, the parse.c file generated by lemon and the +** tokenize.c file are concatenated. In that case, sqlite3RunParser() +** has access to the the size of the yyParser object and so the parser +** engine can be allocated from stack. In that case, only the +** sqlite3ParserInit() and sqlite3ParserFinalize() routines are invoked +** and the sqlite3ParserAlloc() and sqlite3ParserFree() routines can be +** omitted. +*/ +#ifdef SQLITE_AMALGAMATION +# define sqlite3Parser_ENGINEALWAYSONSTACK 1 +#endif + +/* +** Alternative datatype for the argument to the malloc() routine passed +** into sqlite3ParserAlloc(). The default is size_t. +*/ +#define YYMALLOCARGTYPE u64 + +/* +** An instance of the following structure describes the event of a +** TRIGGER. "a" is the event type, one of TK_UPDATE, TK_INSERT, +** TK_DELETE, or TK_INSTEAD. If the event is of the form +** +** UPDATE ON (a,b,c) +** +** Then the "b" IdList records the list "a,b,c". +*/ +struct TrigEvent { int a; IdList * b; }; + +struct FrameBound { int eType; Expr *pExpr; }; + +/* +** Generate a syntax error +*/ +static void parserSyntaxError(Parse *pParse, Token *p){ + sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", p); +} + +/* +** Disable lookaside memory allocation for objects that might be +** shared across database connections. +*/ +static void disableLookaside(Parse *pParse){ + sqlite3 *db = pParse->db; + pParse->disableLookaside++; +#ifdef SQLITE_DEBUG + pParse->isCreate = 1; +#endif + memset(&pParse->u1.cr, 0, sizeof(pParse->u1.cr)); + DisableLookaside; +} + +#if !defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) \ + && defined(SQLITE_UDL_CAPABLE_PARSER) +/* +** Issue an error message if an ORDER BY or LIMIT clause occurs on an +** UPDATE or DELETE statement. +*/ +static void updateDeleteLimitError( + Parse *pParse, + ExprList *pOrderBy, + Expr *pLimit +){ + if( pOrderBy ){ + sqlite3ErrorMsg(pParse, "syntax error near \"ORDER BY\""); + }else{ + sqlite3ErrorMsg(pParse, "syntax error near \"LIMIT\""); + } + sqlite3ExprListDelete(pParse->db, pOrderBy); + sqlite3ExprDelete(pParse->db, pLimit); +} +#endif /* SQLITE_ENABLE_UPDATE_DELETE_LIMIT */ + + + /* + ** For a compound SELECT statement, make sure p->pPrior->pNext==p for + ** all elements in the list. And make sure list length does not exceed + ** SQLITE_LIMIT_COMPOUND_SELECT. + */ + static void parserDoubleLinkSelect(Parse *pParse, Select *p){ + assert( p!=0 ); + if( p->pPrior ){ + Select *pNext = 0, *pLoop = p; + int mxSelect, cnt = 1; + while(1){ + pLoop->pNext = pNext; + pLoop->selFlags |= SF_Compound; + pNext = pLoop; + pLoop = pLoop->pPrior; + if( pLoop==0 ) break; + cnt++; + if( pLoop->pOrderBy || pLoop->pLimit ){ + sqlite3ErrorMsg(pParse,"%s clause should come after %s not before", + pLoop->pOrderBy!=0 ? "ORDER BY" : "LIMIT", + sqlite3SelectOpName(pNext->op)); + break; + } + } + if( (p->selFlags & (SF_MultiValue|SF_Values))==0 + && (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 + && cnt>mxSelect + ){ + sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); + } + } + } + + /* Attach a With object describing the WITH clause to a Select + ** object describing the query for which the WITH clause is a prefix. + */ + static Select *attachWithToSelect(Parse *pParse, Select *pSelect, With *pWith){ + if( pSelect ){ + pSelect->pWith = pWith; + parserDoubleLinkSelect(pParse, pSelect); + }else{ + sqlite3WithDelete(pParse->db, pWith); + } + return pSelect; + } + + /* Memory allocator for parser stack resizing. This is a thin wrapper around + ** sqlite3_realloc() that includes a call to sqlite3FaultSim() to facilitate + ** testing. + */ + static void *parserStackRealloc( + void *pOld, /* Prior allocation */ + sqlite3_uint64 newSize, /* Requested new alloation size */ + Parse *pParse /* Parsing context */ + ){ + void *p = sqlite3FaultSim(700) ? 0 : sqlite3_realloc(pOld, newSize); + if( p==0 ) sqlite3OomFault(pParse->db); + return p; + } + static void parserStackFree(void *pOld, Parse *pParse){ + (void)pParse; + sqlite3_free(pOld); + } + + /* Return an integer that is the maximum allowed stack size */ + static int parserStackSizeLimit(Parse *pParse){ + return pParse->db->aLimit[SQLITE_LIMIT_PARSER_DEPTH]; + } + + + /* Construct a new Expr object from a single token */ + static Expr *tokenExpr(Parse *pParse, int op, Token t){ + Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1); + if( p ){ + /* memset(p, 0, sizeof(Expr)); */ + p->op = (u8)op; + p->affExpr = 0; + p->flags = EP_Leaf; + ExprClearVVAProperties(p); + /* p->iAgg = -1; // Not required */ + p->pLeft = p->pRight = 0; + p->pAggInfo = 0; + memset(&p->x, 0, sizeof(p->x)); + memset(&p->y, 0, sizeof(p->y)); + p->op2 = 0; + p->iTable = 0; + p->iColumn = 0; + p->u.zToken = (char*)&p[1]; + memcpy(p->u.zToken, t.z, t.n); + p->u.zToken[t.n] = 0; + p->w.iOfst = (int)(t.z - pParse->zTail); + if( sqlite3Isquote(p->u.zToken[0]) ){ + sqlite3DequoteExpr(p); + } +#if SQLITE_MAX_EXPR_DEPTH>0 + p->nHeight = 1; +#endif + if( IN_RENAME_OBJECT ){ + return (Expr*)sqlite3RenameTokenMap(pParse, (void*)p, &t); + } + } + return p; + } + + + /* Create a TK_ISNULL or TK_NOTNULL expression, perhaps optimized to + ** to TK_TRUEFALSE, if possible */ + static Expr *sqlite3PExprIsNull( + Parse *pParse, /* Parsing context */ + int op, /* TK_ISNULL or TK_NOTNULL */ + Expr *pLeft /* Operand */ + ){ + Expr *p = pLeft; + assert( op==TK_ISNULL || op==TK_NOTNULL ); + assert( pLeft!=0 ); + while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ + p = p->pLeft; + assert( p!=0 ); + } + switch( p->op ){ + case TK_INTEGER: + case TK_STRING: + case TK_FLOAT: + case TK_BLOB: + sqlite3ExprDeferredDelete(pParse, pLeft); + return sqlite3ExprInt32(pParse->db, op==TK_NOTNULL); + default: + break; + } + return sqlite3PExpr(pParse, op, pLeft, 0); + } + + /* Create a TK_IS or TK_ISNOT operator, perhaps optimized to + ** TK_ISNULL or TK_NOTNULL or TK_TRUEFALSE. */ + static Expr *sqlite3PExprIs( + Parse *pParse, /* Parsing context */ + int op, /* TK_IS or TK_ISNOT */ + Expr *pLeft, /* Left operand */ + Expr *pRight /* Right operand */ + ){ + if( pRight && pRight->op==TK_NULL ){ + sqlite3ExprDeferredDelete(pParse, pRight); + return sqlite3PExprIsNull(pParse, op==TK_IS ? TK_ISNULL : TK_NOTNULL, pLeft); + } + return sqlite3PExpr(pParse, op, pLeft, pRight); + } + + /* Add a single new term to an ExprList that is used to store a + ** list of identifiers. Report an error if the ID list contains + ** a COLLATE clause or an ASC or DESC keyword, except ignore the + ** error while parsing a legacy schema. + */ + static ExprList *parserAddExprIdListTerm( + Parse *pParse, + ExprList *pPrior, + Token *pIdToken, + int hasCollate, + int sortOrder + ){ + ExprList *p = sqlite3ExprListAppend(pParse, pPrior, 0); + if( (hasCollate || sortOrder!=SQLITE_SO_UNDEFINED) + && pParse->db->init.busy==0 + ){ + sqlite3ErrorMsg(pParse, "syntax error after column name \"%.*s\"", + pIdToken->n, pIdToken->z); + } + sqlite3ExprListSetName(pParse, p, pIdToken, 1); + return p; + } + +#if TK_SPAN>255 +# error too many tokens in the grammar +#endif +/**************** End of %include directives **********************************/ +/* These constants specify the various numeric values for terminal symbols. +***************** Begin token definitions *************************************/ +#ifndef TK_SEMI +#define TK_SEMI 1 +#define TK_EXPLAIN 2 +#define TK_QUERY 3 +#define TK_PLAN 4 +#define TK_BEGIN 5 +#define TK_TRANSACTION 6 +#define TK_DEFERRED 7 +#define TK_IMMEDIATE 8 +#define TK_EXCLUSIVE 9 +#define TK_COMMIT 10 +#define TK_END 11 +#define TK_ROLLBACK 12 +#define TK_SAVEPOINT 13 +#define TK_RELEASE 14 +#define TK_TO 15 +#define TK_TABLE 16 +#define TK_CREATE 17 +#define TK_IF 18 +#define TK_NOT 19 +#define TK_EXISTS 20 +#define TK_TEMP 21 +#define TK_LP 22 +#define TK_RP 23 +#define TK_AS 24 +#define TK_COMMA 25 +#define TK_WITHOUT 26 +#define TK_ABORT 27 +#define TK_ACTION 28 +#define TK_AFTER 29 +#define TK_ANALYZE 30 +#define TK_ASC 31 +#define TK_ATTACH 32 +#define TK_BEFORE 33 +#define TK_BY 34 +#define TK_CASCADE 35 +#define TK_CAST 36 +#define TK_CONFLICT 37 +#define TK_DATABASE 38 +#define TK_DESC 39 +#define TK_DETACH 40 +#define TK_EACH 41 +#define TK_FAIL 42 +#define TK_OR 43 +#define TK_AND 44 +#define TK_IS 45 +#define TK_ISNOT 46 +#define TK_MATCH 47 +#define TK_LIKE_KW 48 +#define TK_BETWEEN 49 +#define TK_IN 50 +#define TK_ISNULL 51 +#define TK_NOTNULL 52 +#define TK_NE 53 +#define TK_EQ 54 +#define TK_GT 55 +#define TK_LE 56 +#define TK_LT 57 +#define TK_GE 58 +#define TK_ESCAPE 59 +#define TK_ID 60 +#define TK_COLUMNKW 61 +#define TK_DO 62 +#define TK_FOR 63 +#define TK_IGNORE 64 +#define TK_INITIALLY 65 +#define TK_INSTEAD 66 +#define TK_NO 67 +#define TK_KEY 68 +#define TK_OF 69 +#define TK_OFFSET 70 +#define TK_PRAGMA 71 +#define TK_RAISE 72 +#define TK_RECURSIVE 73 +#define TK_REPLACE 74 +#define TK_RESTRICT 75 +#define TK_ROW 76 +#define TK_ROWS 77 +#define TK_TRIGGER 78 +#define TK_VACUUM 79 +#define TK_VIEW 80 +#define TK_VIRTUAL 81 +#define TK_WITH 82 +#define TK_NULLS 83 +#define TK_FIRST 84 +#define TK_LAST 85 +#define TK_CURRENT 86 +#define TK_FOLLOWING 87 +#define TK_PARTITION 88 +#define TK_PRECEDING 89 +#define TK_RANGE 90 +#define TK_UNBOUNDED 91 +#define TK_EXCLUDE 92 +#define TK_GROUPS 93 +#define TK_OTHERS 94 +#define TK_TIES 95 +#define TK_GENERATED 96 +#define TK_ALWAYS 97 +#define TK_MATERIALIZED 98 +#define TK_REINDEX 99 +#define TK_RENAME 100 +#define TK_CTIME_KW 101 +#define TK_ANY 102 +#define TK_BITAND 103 +#define TK_BITOR 104 +#define TK_LSHIFT 105 +#define TK_RSHIFT 106 +#define TK_PLUS 107 +#define TK_MINUS 108 +#define TK_STAR 109 +#define TK_SLASH 110 +#define TK_REM 111 +#define TK_CONCAT 112 +#define TK_PTR 113 +#define TK_COLLATE 114 +#define TK_BITNOT 115 +#define TK_ON 116 +#define TK_INDEXED 117 +#define TK_STRING 118 +#define TK_JOIN_KW 119 +#define TK_CONSTRAINT 120 +#define TK_DEFAULT 121 +#define TK_NULL 122 +#define TK_PRIMARY 123 +#define TK_UNIQUE 124 +#define TK_CHECK 125 +#define TK_REFERENCES 126 +#define TK_AUTOINCR 127 +#define TK_INSERT 128 +#define TK_DELETE 129 +#define TK_UPDATE 130 +#define TK_SET 131 +#define TK_DEFERRABLE 132 +#define TK_FOREIGN 133 +#define TK_DROP 134 +#define TK_UNION 135 +#define TK_ALL 136 +#define TK_EXCEPT 137 +#define TK_INTERSECT 138 +#define TK_SELECT 139 +#define TK_VALUES 140 +#define TK_DISTINCT 141 +#define TK_DOT 142 +#define TK_FROM 143 +#define TK_JOIN 144 +#define TK_USING 145 +#define TK_ORDER 146 +#define TK_GROUP 147 +#define TK_HAVING 148 +#define TK_LIMIT 149 +#define TK_WHERE 150 +#define TK_RETURNING 151 +#define TK_INTO 152 +#define TK_NOTHING 153 +#define TK_FLOAT 154 +#define TK_BLOB 155 +#define TK_INTEGER 156 +#define TK_VARIABLE 157 +#define TK_CASE 158 +#define TK_WHEN 159 +#define TK_THEN 160 +#define TK_ELSE 161 +#define TK_INDEX 162 +#define TK_ALTER 163 +#define TK_ADD 164 +#define TK_WINDOW 165 +#define TK_OVER 166 +#define TK_FILTER 167 +#define TK_COLUMN 168 +#define TK_AGG_FUNCTION 169 +#define TK_AGG_COLUMN 170 +#define TK_TRUEFALSE 171 +#define TK_FUNCTION 172 +#define TK_UPLUS 173 +#define TK_UMINUS 174 +#define TK_TRUTH 175 +#define TK_REGISTER 176 +#define TK_VECTOR 177 +#define TK_SELECT_COLUMN 178 +#define TK_IF_NULL_ROW 179 +#define TK_ASTERISK 180 +#define TK_SPAN 181 +#define TK_ERROR 182 +#define TK_QNUMBER 183 +#define TK_SPACE 184 +#define TK_COMMENT 185 +#define TK_ILLEGAL 186 +#endif +/**************** End token definitions ***************************************/ + +/* The next sections is a series of control #defines. +** various aspects of the generated parser. +** YYCODETYPE is the data type used to store the integer codes +** that represent terminal and non-terminal symbols. +** "unsigned char" is used if there are fewer than +** 256 symbols. Larger types otherwise. +** YYNOCODE is a number of type YYCODETYPE that is not used for +** any terminal or nonterminal symbol. +** YYFALLBACK If defined, this indicates that one or more tokens +** (also known as: "terminal symbols") have fall-back +** values which should be used if the original symbol +** would not parse. This permits keywords to sometimes +** be used as identifiers, for example. +** YYACTIONTYPE is the data type used for "action codes" - numbers +** that indicate what to do in response to the next +** token. +** sqlite3ParserTOKENTYPE is the data type used for minor type for terminal +** symbols. Background: A "minor type" is a semantic +** value associated with a terminal or non-terminal +** symbols. For example, for an "ID" terminal symbol, +** the minor type might be the name of the identifier. +** Each non-terminal can have a different minor type. +** Terminal symbols all have the same minor type, though. +** This macros defines the minor type for terminal +** symbols. +** YYMINORTYPE is the data type used for all minor types. +** This is typically a union of many types, one of +** which is sqlite3ParserTOKENTYPE. The entry in the union +** for terminal symbols is called "yy0". +** YYSTACKDEPTH is the maximum depth of the parser's stack. If +** zero the stack is dynamically sized using realloc() +** sqlite3ParserARG_SDECL A static variable declaration for the %extra_argument +** sqlite3ParserARG_PDECL A parameter declaration for the %extra_argument +** sqlite3ParserARG_PARAM Code to pass %extra_argument as a subroutine parameter +** sqlite3ParserARG_STORE Code to store %extra_argument into yypParser +** sqlite3ParserARG_FETCH Code to extract %extra_argument from yypParser +** sqlite3ParserCTX_* As sqlite3ParserARG_ except for %extra_context +** YYREALLOC Name of the realloc() function to use +** YYFREE Name of the free() function to use +** YYDYNSTACK True if stack space should be extended on heap +** YYERRORSYMBOL is the code number of the error symbol. If not +** defined, then do no error processing. +** YYNSTATE the combined number of states. +** YYNRULE the number of rules in the grammar +** YYNTOKEN Number of terminal symbols +** YY_MAX_SHIFT Maximum value for shift actions +** YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions +** YY_MAX_SHIFTREDUCE Maximum value for shift-reduce actions +** YY_ERROR_ACTION The yy_action[] code for syntax error +** YY_ACCEPT_ACTION The yy_action[] code for accept +** YY_NO_ACTION The yy_action[] code for no-op +** YY_MIN_REDUCE Minimum value for reduce actions +** YY_MAX_REDUCE Maximum value for reduce actions +** YY_MIN_DSTRCTR Minimum symbol value that has a destructor +** YY_MAX_DSTRCTR Maximum symbol value that has a destructor +*/ +#ifndef INTERFACE +# define INTERFACE 1 +#endif +/************* Begin control #defines *****************************************/ +#define YYCODETYPE unsigned short int +#define YYNOCODE 322 +#define YYACTIONTYPE unsigned short int +#define YYWILDCARD 102 +#define sqlite3ParserTOKENTYPE Token +typedef union { + int yyinit; + sqlite3ParserTOKENTYPE yy0; + ExprList* yy14; + With* yy59; + Cte* yy67; + Upsert* yy122; + IdList* yy132; + int yy144; + const char* yy168; + SrcList* yy203; + Window* yy211; + OnOrUsing yy269; + struct TrigEvent yy286; + struct {int value; int mask;} yy383; + u32 yy391; + TriggerStep* yy427; + Expr* yy454; + u8 yy462; + struct FrameBound yy509; + Select* yy555; +} YYMINORTYPE; +#ifndef YYSTACKDEPTH +#define YYSTACKDEPTH 50 +#endif +#define sqlite3ParserARG_SDECL +#define sqlite3ParserARG_PDECL +#define sqlite3ParserARG_PARAM +#define sqlite3ParserARG_FETCH +#define sqlite3ParserARG_STORE +#undef YYREALLOC +#define YYREALLOC parserStackRealloc +#undef YYFREE +#define YYFREE parserStackFree +#undef YYDYNSTACK +#define YYDYNSTACK 1 +#undef YYSIZELIMIT +#define YYSIZELIMIT parserStackSizeLimit +#define sqlite3ParserCTX(P) ((P)->pParse) +#define sqlite3ParserCTX_SDECL Parse *pParse; +#define sqlite3ParserCTX_PDECL ,Parse *pParse +#define sqlite3ParserCTX_PARAM ,pParse +#define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse; +#define sqlite3ParserCTX_STORE yypParser->pParse=pParse; +#undef YYERRORSYMBOL +#undef YYERRSYMDT +#undef YYFALLBACK +#define YYFALLBACK 1 +#define YYNSTATE 600 +#define YYNRULE 412 +#define YYNRULE_WITH_ACTION 348 +#define YYNTOKEN 187 +#define YY_MAX_SHIFT 599 +#define YY_MIN_SHIFTREDUCE 867 +#define YY_MAX_SHIFTREDUCE 1278 +#define YY_ERROR_ACTION 1279 +#define YY_ACCEPT_ACTION 1280 +#define YY_NO_ACTION 1281 +#define YY_MIN_REDUCE 1282 +#define YY_MAX_REDUCE 1693 +#define YY_MIN_DSTRCTR 206 +#define YY_MAX_DSTRCTR 319 +/************* End control #defines *******************************************/ +#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) + +/* Define the yytestcase() macro to be a no-op if is not already defined +** otherwise. +** +** Applications can choose to define yytestcase() in the %include section +** to a macro that can assist in verifying code coverage. For production +** code the yytestcase() macro should be turned off. But it is useful +** for testing. +*/ +#ifndef yytestcase +# define yytestcase(X) +#endif + +/* Macro to determine if stack space has the ability to grow using +** heap memory. +*/ +#if YYSTACKDEPTH<=0 || YYDYNSTACK +# define YYGROWABLESTACK 1 +#else +# define YYGROWABLESTACK 0 +#endif + +/* Guarantee a minimum number of initial stack slots. +*/ +#if YYSTACKDEPTH<=0 +# undef YYSTACKDEPTH +# define YYSTACKDEPTH 2 /* Need a minimum stack size */ +#endif + + +/* Next are the tables used to determine what action to take based on the +** current state and lookahead token. These tables are used to implement +** functions that take a state number and lookahead value and return an +** action integer. +** +** Suppose the action integer is N. Then the action is determined as +** follows +** +** 0 <= N <= YY_MAX_SHIFT Shift N. That is, push the lookahead +** token onto the stack and goto state N. +** +** N between YY_MIN_SHIFTREDUCE Shift to an arbitrary state then +** and YY_MAX_SHIFTREDUCE reduce by rule N-YY_MIN_SHIFTREDUCE. +** +** N == YY_ERROR_ACTION A syntax error has occurred. +** +** N == YY_ACCEPT_ACTION The parser accepts its input. +** +** N == YY_NO_ACTION No such action. Denotes unused +** slots in the yy_action[] table. +** +** N between YY_MIN_REDUCE Reduce by rule N-YY_MIN_REDUCE +** and YY_MAX_REDUCE +** +** The action table is constructed as a single large table named yy_action[]. +** Given state S and lookahead X, the action is computed as either: +** +** (A) N = yy_action[ yy_shift_ofst[S] + X ] +** (B) N = yy_default[S] +** +** The (A) formula is preferred. The B formula is used instead if +** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X. +** +** The formulas above are for computing the action when the lookahead is +** a terminal symbol. If the lookahead is a non-terminal (as occurs after +** a reduce action) then the yy_reduce_ofst[] array is used in place of +** the yy_shift_ofst[] array. +** +** The following are the tables generated in this section: +** +** yy_action[] A single table containing all actions. +** yy_lookahead[] A table containing the lookahead for each entry in +** yy_action. Used to detect hash collisions. +** yy_shift_ofst[] For each state, the offset into yy_action for +** shifting terminals. +** yy_reduce_ofst[] For each state, the offset into yy_action for +** shifting non-terminals after a reduce. +** yy_default[] Default action for each state. +** +*********** Begin parsing tables **********************************************/ +#define YY_ACTTAB_COUNT (2379) +static const YYACTIONTYPE yy_action[] = { + /* 0 */ 134, 131, 238, 290, 290, 1353, 593, 1332, 478, 1606, + /* 10 */ 593, 1315, 593, 7, 593, 1353, 590, 593, 579, 424, + /* 20 */ 1566, 134, 131, 238, 1318, 541, 478, 477, 575, 84, + /* 30 */ 84, 1005, 303, 84, 84, 51, 51, 63, 63, 1006, + /* 40 */ 84, 84, 498, 141, 142, 93, 442, 1254, 1254, 1085, + /* 50 */ 1088, 1075, 1075, 139, 139, 140, 140, 140, 140, 424, + /* 60 */ 296, 296, 498, 296, 296, 567, 553, 296, 296, 1306, + /* 70 */ 574, 1358, 1358, 590, 542, 579, 590, 574, 579, 548, + /* 80 */ 590, 1304, 579, 141, 142, 93, 576, 1254, 1254, 1085, + /* 90 */ 1088, 1075, 1075, 139, 139, 140, 140, 140, 140, 399, + /* 100 */ 478, 395, 6, 138, 138, 138, 138, 137, 137, 136, + /* 110 */ 136, 136, 135, 132, 463, 44, 342, 593, 305, 1127, + /* 120 */ 1280, 1, 1, 599, 2, 1284, 598, 1200, 1284, 1200, + /* 130 */ 330, 424, 158, 330, 1613, 158, 390, 116, 308, 1366, + /* 140 */ 51, 51, 1366, 138, 138, 138, 138, 137, 137, 136, + /* 150 */ 136, 136, 135, 132, 463, 141, 142, 93, 515, 1254, + /* 160 */ 1254, 1085, 1088, 1075, 1075, 139, 139, 140, 140, 140, + /* 170 */ 140, 1230, 329, 584, 296, 296, 212, 296, 296, 568, + /* 180 */ 568, 488, 143, 1072, 1072, 1086, 1089, 590, 1195, 579, + /* 190 */ 590, 340, 579, 140, 140, 140, 140, 133, 392, 564, + /* 200 */ 536, 1195, 250, 425, 1195, 250, 137, 137, 136, 136, + /* 210 */ 136, 135, 132, 463, 291, 138, 138, 138, 138, 137, + /* 220 */ 137, 136, 136, 136, 135, 132, 463, 966, 1230, 1231, + /* 230 */ 1230, 412, 965, 467, 412, 424, 467, 489, 357, 1611, + /* 240 */ 391, 138, 138, 138, 138, 137, 137, 136, 136, 136, + /* 250 */ 135, 132, 463, 463, 134, 131, 238, 555, 1076, 141, + /* 260 */ 142, 93, 593, 1254, 1254, 1085, 1088, 1075, 1075, 139, + /* 270 */ 139, 140, 140, 140, 140, 1317, 134, 131, 238, 424, + /* 280 */ 549, 1597, 1531, 333, 97, 83, 83, 140, 140, 140, + /* 290 */ 140, 138, 138, 138, 138, 137, 137, 136, 136, 136, + /* 300 */ 135, 132, 463, 141, 142, 93, 1657, 1254, 1254, 1085, + /* 310 */ 1088, 1075, 1075, 139, 139, 140, 140, 140, 140, 138, + /* 320 */ 138, 138, 138, 137, 137, 136, 136, 136, 135, 132, + /* 330 */ 463, 591, 1230, 958, 958, 138, 138, 138, 138, 137, + /* 340 */ 137, 136, 136, 136, 135, 132, 463, 44, 398, 547, + /* 350 */ 1306, 136, 136, 136, 135, 132, 463, 386, 593, 442, + /* 360 */ 595, 145, 595, 138, 138, 138, 138, 137, 137, 136, + /* 370 */ 136, 136, 135, 132, 463, 500, 1230, 112, 550, 460, + /* 380 */ 459, 51, 51, 424, 296, 296, 479, 334, 1259, 1230, + /* 390 */ 1231, 1230, 1599, 1261, 388, 312, 444, 590, 246, 579, + /* 400 */ 546, 1260, 271, 235, 329, 584, 551, 141, 142, 93, + /* 410 */ 429, 1254, 1254, 1085, 1088, 1075, 1075, 139, 139, 140, + /* 420 */ 140, 140, 140, 22, 22, 1230, 1262, 424, 1262, 216, + /* 430 */ 296, 296, 98, 1230, 1231, 1230, 264, 884, 45, 528, + /* 440 */ 525, 524, 1041, 590, 1269, 579, 421, 420, 393, 523, + /* 450 */ 44, 141, 142, 93, 498, 1254, 1254, 1085, 1088, 1075, + /* 460 */ 1075, 139, 139, 140, 140, 140, 140, 138, 138, 138, + /* 470 */ 138, 137, 137, 136, 136, 136, 135, 132, 463, 593, + /* 480 */ 1611, 561, 1230, 1231, 1230, 23, 264, 515, 200, 528, + /* 490 */ 525, 524, 127, 585, 509, 4, 355, 487, 506, 523, + /* 500 */ 593, 498, 84, 84, 134, 131, 238, 329, 584, 588, + /* 510 */ 1627, 138, 138, 138, 138, 137, 137, 136, 136, 136, + /* 520 */ 135, 132, 463, 19, 19, 435, 1230, 1460, 297, 297, + /* 530 */ 311, 424, 1565, 464, 1631, 599, 2, 1284, 437, 574, + /* 540 */ 1107, 590, 330, 579, 158, 582, 489, 357, 573, 593, + /* 550 */ 592, 1366, 409, 1274, 1230, 141, 142, 93, 1364, 1254, + /* 560 */ 1254, 1085, 1088, 1075, 1075, 139, 139, 140, 140, 140, + /* 570 */ 140, 389, 84, 84, 1062, 567, 1230, 313, 1523, 593, + /* 580 */ 125, 125, 970, 1230, 1231, 1230, 296, 296, 126, 46, + /* 590 */ 464, 594, 464, 296, 296, 1050, 1230, 218, 439, 590, + /* 600 */ 1604, 579, 84, 84, 7, 403, 590, 515, 579, 325, + /* 610 */ 417, 1230, 1231, 1230, 250, 138, 138, 138, 138, 137, + /* 620 */ 137, 136, 136, 136, 135, 132, 463, 1050, 1050, 1052, + /* 630 */ 1053, 35, 1275, 1230, 1231, 1230, 424, 1370, 993, 574, + /* 640 */ 371, 414, 274, 412, 1597, 467, 1302, 552, 451, 590, + /* 650 */ 543, 579, 1530, 1230, 1231, 1230, 1214, 201, 409, 1174, + /* 660 */ 141, 142, 93, 223, 1254, 1254, 1085, 1088, 1075, 1075, + /* 670 */ 139, 139, 140, 140, 140, 140, 296, 296, 1250, 593, + /* 680 */ 424, 296, 296, 236, 529, 296, 296, 515, 100, 590, + /* 690 */ 1600, 579, 48, 1605, 590, 1230, 579, 7, 590, 577, + /* 700 */ 579, 904, 84, 84, 141, 142, 93, 496, 1254, 1254, + /* 710 */ 1085, 1088, 1075, 1075, 139, 139, 140, 140, 140, 140, + /* 720 */ 138, 138, 138, 138, 137, 137, 136, 136, 136, 135, + /* 730 */ 132, 463, 1365, 1230, 296, 296, 1250, 115, 1275, 326, + /* 740 */ 233, 539, 1062, 40, 282, 127, 585, 590, 4, 579, + /* 750 */ 329, 584, 1230, 1231, 1230, 1598, 593, 388, 904, 1051, + /* 760 */ 1356, 1356, 588, 1050, 138, 138, 138, 138, 137, 137, + /* 770 */ 136, 136, 136, 135, 132, 463, 185, 593, 1230, 19, + /* 780 */ 19, 1230, 971, 1597, 424, 1651, 464, 129, 908, 1195, + /* 790 */ 1230, 1231, 1230, 1325, 443, 1050, 1050, 1052, 582, 1603, + /* 800 */ 149, 149, 1195, 7, 5, 1195, 1687, 410, 141, 142, + /* 810 */ 93, 1536, 1254, 1254, 1085, 1088, 1075, 1075, 139, 139, + /* 820 */ 140, 140, 140, 140, 1214, 397, 593, 1062, 424, 1536, + /* 830 */ 1538, 50, 901, 125, 125, 1230, 1231, 1230, 1230, 1231, + /* 840 */ 1230, 126, 1230, 464, 594, 464, 515, 1230, 1050, 84, + /* 850 */ 84, 3, 141, 142, 93, 924, 1254, 1254, 1085, 1088, + /* 860 */ 1075, 1075, 139, 139, 140, 140, 140, 140, 138, 138, + /* 870 */ 138, 138, 137, 137, 136, 136, 136, 135, 132, 463, + /* 880 */ 1050, 1050, 1052, 1053, 35, 442, 457, 532, 433, 1230, + /* 890 */ 1062, 1361, 540, 540, 1598, 925, 388, 7, 1129, 1230, + /* 900 */ 1231, 1230, 1129, 1536, 1230, 1231, 1230, 1051, 570, 1214, + /* 910 */ 593, 1050, 138, 138, 138, 138, 137, 137, 136, 136, + /* 920 */ 136, 135, 132, 463, 6, 185, 1195, 1230, 231, 593, + /* 930 */ 382, 992, 424, 151, 151, 510, 1213, 557, 482, 1195, + /* 940 */ 381, 160, 1195, 1050, 1050, 1052, 1230, 1231, 1230, 422, + /* 950 */ 593, 447, 84, 84, 593, 217, 141, 142, 93, 593, + /* 960 */ 1254, 1254, 1085, 1088, 1075, 1075, 139, 139, 140, 140, + /* 970 */ 140, 140, 1214, 19, 19, 593, 424, 19, 19, 442, + /* 980 */ 1063, 442, 19, 19, 1230, 1231, 1230, 515, 445, 458, + /* 990 */ 1597, 386, 315, 1175, 1685, 556, 1685, 450, 84, 84, + /* 1000 */ 141, 142, 93, 505, 1254, 1254, 1085, 1088, 1075, 1075, + /* 1010 */ 139, 139, 140, 140, 140, 140, 138, 138, 138, 138, + /* 1020 */ 137, 137, 136, 136, 136, 135, 132, 463, 442, 1147, + /* 1030 */ 454, 1597, 362, 1041, 593, 462, 1460, 1233, 47, 1393, + /* 1040 */ 324, 565, 565, 115, 1148, 449, 7, 460, 459, 307, + /* 1050 */ 375, 354, 593, 113, 593, 329, 584, 19, 19, 1149, + /* 1060 */ 138, 138, 138, 138, 137, 137, 136, 136, 136, 135, + /* 1070 */ 132, 463, 209, 1173, 563, 19, 19, 19, 19, 49, + /* 1080 */ 424, 944, 1175, 1686, 1046, 1686, 218, 355, 484, 343, + /* 1090 */ 210, 945, 569, 562, 1262, 1233, 1262, 490, 314, 423, + /* 1100 */ 424, 1598, 1206, 388, 141, 142, 93, 440, 1254, 1254, + /* 1110 */ 1085, 1088, 1075, 1075, 139, 139, 140, 140, 140, 140, + /* 1120 */ 352, 316, 531, 316, 141, 142, 93, 549, 1254, 1254, + /* 1130 */ 1085, 1088, 1075, 1075, 139, 139, 140, 140, 140, 140, + /* 1140 */ 446, 10, 1598, 274, 388, 915, 281, 299, 383, 534, + /* 1150 */ 378, 533, 269, 593, 1206, 587, 587, 587, 374, 293, + /* 1160 */ 1579, 991, 1173, 302, 138, 138, 138, 138, 137, 137, + /* 1170 */ 136, 136, 136, 135, 132, 463, 53, 53, 520, 1250, + /* 1180 */ 593, 1147, 1576, 431, 138, 138, 138, 138, 137, 137, + /* 1190 */ 136, 136, 136, 135, 132, 463, 1148, 301, 593, 1577, + /* 1200 */ 593, 1307, 431, 54, 54, 593, 268, 593, 461, 461, + /* 1210 */ 461, 1149, 347, 492, 424, 135, 132, 463, 1146, 1195, + /* 1220 */ 474, 68, 68, 69, 69, 550, 332, 287, 21, 21, + /* 1230 */ 55, 55, 1195, 581, 424, 1195, 309, 1250, 141, 142, + /* 1240 */ 93, 119, 1254, 1254, 1085, 1088, 1075, 1075, 139, 139, + /* 1250 */ 140, 140, 140, 140, 593, 237, 480, 1476, 141, 142, + /* 1260 */ 93, 593, 1254, 1254, 1085, 1088, 1075, 1075, 139, 139, + /* 1270 */ 140, 140, 140, 140, 344, 430, 346, 70, 70, 494, + /* 1280 */ 991, 1132, 1132, 512, 56, 56, 1269, 593, 268, 593, + /* 1290 */ 369, 374, 593, 481, 215, 384, 1624, 481, 138, 138, + /* 1300 */ 138, 138, 137, 137, 136, 136, 136, 135, 132, 463, + /* 1310 */ 71, 71, 72, 72, 225, 73, 73, 593, 138, 138, + /* 1320 */ 138, 138, 137, 137, 136, 136, 136, 135, 132, 463, + /* 1330 */ 586, 431, 593, 872, 873, 874, 593, 911, 593, 1602, + /* 1340 */ 74, 74, 593, 7, 1460, 242, 593, 306, 424, 1578, + /* 1350 */ 472, 306, 364, 219, 367, 75, 75, 430, 345, 57, + /* 1360 */ 57, 58, 58, 432, 187, 59, 59, 593, 424, 61, + /* 1370 */ 61, 1475, 141, 142, 93, 123, 1254, 1254, 1085, 1088, + /* 1380 */ 1075, 1075, 139, 139, 140, 140, 140, 140, 424, 570, + /* 1390 */ 62, 62, 141, 142, 93, 911, 1254, 1254, 1085, 1088, + /* 1400 */ 1075, 1075, 139, 139, 140, 140, 140, 140, 161, 384, + /* 1410 */ 1624, 1474, 141, 130, 93, 441, 1254, 1254, 1085, 1088, + /* 1420 */ 1075, 1075, 139, 139, 140, 140, 140, 140, 267, 266, + /* 1430 */ 265, 1460, 138, 138, 138, 138, 137, 137, 136, 136, + /* 1440 */ 136, 135, 132, 463, 593, 1336, 593, 1269, 1460, 384, + /* 1450 */ 1624, 231, 138, 138, 138, 138, 137, 137, 136, 136, + /* 1460 */ 136, 135, 132, 463, 593, 163, 593, 76, 76, 77, + /* 1470 */ 77, 593, 138, 138, 138, 138, 137, 137, 136, 136, + /* 1480 */ 136, 135, 132, 463, 475, 593, 483, 78, 78, 20, + /* 1490 */ 20, 1249, 424, 491, 79, 79, 495, 422, 295, 235, + /* 1500 */ 1574, 38, 511, 896, 422, 335, 240, 422, 147, 147, + /* 1510 */ 112, 593, 424, 593, 101, 222, 991, 142, 93, 455, + /* 1520 */ 1254, 1254, 1085, 1088, 1075, 1075, 139, 139, 140, 140, + /* 1530 */ 140, 140, 593, 39, 148, 148, 80, 80, 93, 551, + /* 1540 */ 1254, 1254, 1085, 1088, 1075, 1075, 139, 139, 140, 140, + /* 1550 */ 140, 140, 328, 923, 922, 64, 64, 502, 1656, 1005, + /* 1560 */ 933, 896, 124, 422, 121, 254, 593, 1006, 593, 226, + /* 1570 */ 593, 127, 585, 164, 4, 16, 138, 138, 138, 138, + /* 1580 */ 137, 137, 136, 136, 136, 135, 132, 463, 588, 81, + /* 1590 */ 81, 65, 65, 82, 82, 593, 138, 138, 138, 138, + /* 1600 */ 137, 137, 136, 136, 136, 135, 132, 463, 593, 226, + /* 1610 */ 237, 966, 464, 593, 298, 593, 965, 593, 66, 66, + /* 1620 */ 593, 1170, 593, 411, 582, 353, 469, 115, 593, 471, + /* 1630 */ 169, 173, 173, 593, 44, 991, 174, 174, 89, 89, + /* 1640 */ 67, 67, 593, 85, 85, 150, 150, 1114, 1043, 593, + /* 1650 */ 273, 86, 86, 1062, 593, 503, 171, 171, 593, 125, + /* 1660 */ 125, 497, 593, 273, 336, 152, 152, 126, 1335, 464, + /* 1670 */ 594, 464, 146, 146, 1050, 593, 545, 172, 172, 593, + /* 1680 */ 1054, 165, 165, 256, 339, 156, 156, 127, 585, 1586, + /* 1690 */ 4, 329, 584, 499, 358, 273, 115, 348, 155, 155, + /* 1700 */ 930, 931, 153, 153, 588, 1114, 1050, 1050, 1052, 1053, + /* 1710 */ 35, 1554, 521, 593, 270, 1008, 1009, 9, 593, 372, + /* 1720 */ 593, 115, 593, 168, 593, 115, 593, 1110, 464, 270, + /* 1730 */ 996, 964, 273, 129, 1645, 1214, 154, 154, 1054, 1404, + /* 1740 */ 582, 88, 88, 90, 90, 87, 87, 52, 52, 60, + /* 1750 */ 60, 1405, 504, 537, 559, 1179, 961, 507, 129, 558, + /* 1760 */ 127, 585, 1126, 4, 1126, 1125, 894, 1125, 162, 1062, + /* 1770 */ 963, 359, 129, 1401, 363, 125, 125, 588, 366, 368, + /* 1780 */ 370, 1349, 1334, 126, 1333, 464, 594, 464, 377, 387, + /* 1790 */ 1050, 1391, 1414, 1618, 1459, 1387, 1399, 208, 580, 1464, + /* 1800 */ 1314, 464, 243, 516, 1305, 1293, 1384, 1292, 1294, 1638, + /* 1810 */ 288, 170, 228, 582, 12, 408, 321, 322, 241, 323, + /* 1820 */ 245, 1446, 1050, 1050, 1052, 1053, 35, 559, 304, 350, + /* 1830 */ 351, 501, 560, 127, 585, 1441, 4, 1451, 1434, 310, + /* 1840 */ 1450, 526, 1062, 1332, 415, 380, 232, 1527, 125, 125, + /* 1850 */ 588, 1214, 1396, 356, 1526, 583, 126, 1397, 464, 594, + /* 1860 */ 464, 1641, 535, 1050, 1581, 1395, 1269, 1583, 1582, 213, + /* 1870 */ 402, 277, 214, 227, 464, 1573, 239, 1571, 1266, 1394, + /* 1880 */ 434, 198, 100, 224, 96, 183, 582, 191, 485, 193, + /* 1890 */ 486, 194, 195, 196, 519, 1050, 1050, 1052, 1053, 35, + /* 1900 */ 559, 113, 252, 413, 1447, 558, 493, 13, 1455, 416, + /* 1910 */ 1453, 1452, 14, 202, 1521, 1062, 1532, 508, 258, 106, + /* 1920 */ 514, 125, 125, 99, 1214, 1543, 289, 260, 206, 126, + /* 1930 */ 365, 464, 594, 464, 361, 517, 1050, 261, 448, 1295, + /* 1940 */ 262, 418, 1352, 1351, 108, 1350, 1655, 1654, 1343, 915, + /* 1950 */ 419, 1322, 233, 452, 319, 379, 1321, 453, 1623, 320, + /* 1960 */ 1320, 275, 1653, 544, 276, 1609, 1608, 1342, 1050, 1050, + /* 1970 */ 1052, 1053, 35, 1630, 1218, 466, 385, 456, 300, 1419, + /* 1980 */ 144, 1418, 570, 407, 407, 406, 284, 404, 11, 1508, + /* 1990 */ 881, 396, 120, 127, 585, 394, 4, 1214, 327, 114, + /* 2000 */ 1375, 1374, 220, 247, 400, 338, 401, 554, 42, 1224, + /* 2010 */ 588, 596, 283, 337, 285, 286, 188, 597, 1290, 1285, + /* 2020 */ 175, 1558, 176, 1559, 1557, 1556, 159, 317, 229, 177, + /* 2030 */ 868, 230, 91, 465, 464, 221, 331, 468, 1165, 470, + /* 2040 */ 473, 94, 244, 95, 249, 189, 582, 1124, 1122, 341, + /* 2050 */ 427, 190, 178, 1249, 179, 43, 192, 947, 349, 428, + /* 2060 */ 1138, 197, 251, 180, 181, 436, 102, 182, 438, 103, + /* 2070 */ 104, 199, 248, 1140, 253, 1062, 105, 255, 1137, 166, + /* 2080 */ 24, 125, 125, 257, 1264, 273, 360, 513, 259, 126, + /* 2090 */ 15, 464, 594, 464, 204, 883, 1050, 518, 263, 373, + /* 2100 */ 381, 92, 585, 1130, 4, 203, 205, 426, 107, 522, + /* 2110 */ 25, 26, 329, 584, 913, 572, 527, 376, 588, 926, + /* 2120 */ 530, 109, 184, 318, 167, 110, 27, 538, 1050, 1050, + /* 2130 */ 1052, 1053, 35, 1211, 1091, 17, 476, 111, 1181, 234, + /* 2140 */ 292, 1180, 464, 294, 207, 994, 129, 1201, 272, 1000, + /* 2150 */ 28, 1197, 29, 30, 582, 1199, 1205, 1214, 31, 1204, + /* 2160 */ 32, 1186, 41, 566, 33, 1105, 211, 8, 115, 1092, + /* 2170 */ 1090, 1094, 34, 278, 578, 1095, 117, 122, 118, 1145, + /* 2180 */ 36, 18, 128, 1062, 1055, 895, 957, 37, 589, 125, + /* 2190 */ 125, 279, 186, 280, 1646, 157, 405, 126, 1220, 464, + /* 2200 */ 594, 464, 1218, 466, 1050, 1219, 300, 1281, 1281, 1281, + /* 2210 */ 1281, 407, 407, 406, 284, 404, 1281, 1281, 881, 1281, + /* 2220 */ 300, 1281, 1281, 571, 1281, 407, 407, 406, 284, 404, + /* 2230 */ 1281, 247, 881, 338, 1281, 1281, 1050, 1050, 1052, 1053, + /* 2240 */ 35, 337, 1281, 1281, 1281, 247, 1281, 338, 1281, 1281, + /* 2250 */ 1281, 1281, 1281, 1281, 1281, 337, 1281, 1281, 1281, 1281, + /* 2260 */ 1281, 1281, 1281, 1281, 1281, 1214, 1281, 1281, 1281, 1281, + /* 2270 */ 1281, 1281, 249, 1281, 1281, 1281, 1281, 1281, 1281, 1281, + /* 2280 */ 178, 1281, 1281, 43, 1281, 1281, 249, 1281, 1281, 1281, + /* 2290 */ 1281, 1281, 1281, 1281, 178, 1281, 1281, 43, 1281, 1281, + /* 2300 */ 248, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, + /* 2310 */ 1281, 1281, 1281, 1281, 248, 1281, 1281, 1281, 1281, 1281, + /* 2320 */ 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, + /* 2330 */ 1281, 1281, 1281, 1281, 1281, 426, 1281, 1281, 1281, 1281, + /* 2340 */ 329, 584, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 426, + /* 2350 */ 1281, 1281, 1281, 1281, 329, 584, 1281, 1281, 1281, 1281, + /* 2360 */ 1281, 1281, 1281, 1281, 476, 1281, 1281, 1281, 1281, 1281, + /* 2370 */ 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 476, +}; +static const YYCODETYPE yy_lookahead[] = { + /* 0 */ 277, 278, 279, 241, 242, 225, 195, 227, 195, 312, + /* 10 */ 195, 218, 195, 316, 195, 235, 254, 195, 256, 19, + /* 20 */ 297, 277, 278, 279, 218, 206, 213, 214, 206, 218, + /* 30 */ 219, 31, 206, 218, 219, 218, 219, 218, 219, 39, + /* 40 */ 218, 219, 195, 43, 44, 45, 195, 47, 48, 49, + /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 19, + /* 60 */ 241, 242, 195, 241, 242, 195, 255, 241, 242, 195, + /* 70 */ 255, 237, 238, 254, 255, 256, 254, 255, 256, 264, + /* 80 */ 254, 207, 256, 43, 44, 45, 264, 47, 48, 49, + /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 251, + /* 100 */ 287, 253, 215, 103, 104, 105, 106, 107, 108, 109, + /* 110 */ 110, 111, 112, 113, 114, 82, 265, 195, 271, 11, + /* 120 */ 187, 188, 189, 190, 191, 192, 190, 87, 192, 89, + /* 130 */ 197, 19, 199, 197, 317, 199, 319, 25, 271, 206, + /* 140 */ 218, 219, 206, 103, 104, 105, 106, 107, 108, 109, + /* 150 */ 110, 111, 112, 113, 114, 43, 44, 45, 195, 47, + /* 160 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + /* 170 */ 58, 60, 139, 140, 241, 242, 289, 241, 242, 309, + /* 180 */ 310, 294, 70, 47, 48, 49, 50, 254, 77, 256, + /* 190 */ 254, 195, 256, 55, 56, 57, 58, 59, 221, 88, + /* 200 */ 109, 90, 269, 240, 93, 269, 107, 108, 109, 110, + /* 210 */ 111, 112, 113, 114, 215, 103, 104, 105, 106, 107, + /* 220 */ 108, 109, 110, 111, 112, 113, 114, 136, 117, 118, + /* 230 */ 119, 298, 141, 300, 298, 19, 300, 129, 130, 317, + /* 240 */ 318, 103, 104, 105, 106, 107, 108, 109, 110, 111, + /* 250 */ 112, 113, 114, 114, 277, 278, 279, 146, 122, 43, + /* 260 */ 44, 45, 195, 47, 48, 49, 50, 51, 52, 53, + /* 270 */ 54, 55, 56, 57, 58, 218, 277, 278, 279, 19, + /* 280 */ 19, 195, 286, 23, 68, 218, 219, 55, 56, 57, + /* 290 */ 58, 103, 104, 105, 106, 107, 108, 109, 110, 111, + /* 300 */ 112, 113, 114, 43, 44, 45, 232, 47, 48, 49, + /* 310 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 103, + /* 320 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + /* 330 */ 114, 135, 60, 137, 138, 103, 104, 105, 106, 107, + /* 340 */ 108, 109, 110, 111, 112, 113, 114, 82, 281, 206, + /* 350 */ 195, 109, 110, 111, 112, 113, 114, 195, 195, 195, + /* 360 */ 205, 22, 207, 103, 104, 105, 106, 107, 108, 109, + /* 370 */ 110, 111, 112, 113, 114, 195, 60, 116, 117, 107, + /* 380 */ 108, 218, 219, 19, 241, 242, 121, 23, 116, 117, + /* 390 */ 118, 119, 306, 121, 308, 206, 234, 254, 15, 256, + /* 400 */ 195, 129, 259, 260, 139, 140, 145, 43, 44, 45, + /* 410 */ 200, 47, 48, 49, 50, 51, 52, 53, 54, 55, + /* 420 */ 56, 57, 58, 218, 219, 60, 154, 19, 156, 265, + /* 430 */ 241, 242, 24, 117, 118, 119, 120, 21, 73, 123, + /* 440 */ 124, 125, 74, 254, 61, 256, 107, 108, 221, 133, + /* 450 */ 82, 43, 44, 45, 195, 47, 48, 49, 50, 51, + /* 460 */ 52, 53, 54, 55, 56, 57, 58, 103, 104, 105, + /* 470 */ 106, 107, 108, 109, 110, 111, 112, 113, 114, 195, + /* 480 */ 317, 318, 117, 118, 119, 22, 120, 195, 22, 123, + /* 490 */ 124, 125, 19, 20, 284, 22, 128, 81, 288, 133, + /* 500 */ 195, 195, 218, 219, 277, 278, 279, 139, 140, 36, + /* 510 */ 195, 103, 104, 105, 106, 107, 108, 109, 110, 111, + /* 520 */ 112, 113, 114, 218, 219, 62, 60, 195, 241, 242, + /* 530 */ 271, 19, 240, 60, 189, 190, 191, 192, 233, 255, + /* 540 */ 124, 254, 197, 256, 199, 72, 129, 130, 264, 195, + /* 550 */ 195, 206, 22, 23, 60, 43, 44, 45, 206, 47, + /* 560 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + /* 570 */ 58, 195, 218, 219, 101, 195, 60, 271, 162, 195, + /* 580 */ 107, 108, 109, 117, 118, 119, 241, 242, 115, 73, + /* 590 */ 117, 118, 119, 241, 242, 122, 60, 195, 266, 254, + /* 600 */ 312, 256, 218, 219, 316, 203, 254, 195, 256, 255, + /* 610 */ 208, 117, 118, 119, 269, 103, 104, 105, 106, 107, + /* 620 */ 108, 109, 110, 111, 112, 113, 114, 154, 155, 156, + /* 630 */ 157, 158, 102, 117, 118, 119, 19, 242, 144, 255, + /* 640 */ 23, 206, 24, 298, 195, 300, 206, 195, 264, 254, + /* 650 */ 206, 256, 240, 117, 118, 119, 183, 22, 22, 23, + /* 660 */ 43, 44, 45, 151, 47, 48, 49, 50, 51, 52, + /* 670 */ 53, 54, 55, 56, 57, 58, 241, 242, 60, 195, + /* 680 */ 19, 241, 242, 195, 23, 241, 242, 195, 152, 254, + /* 690 */ 310, 256, 243, 312, 254, 60, 256, 316, 254, 206, + /* 700 */ 256, 60, 218, 219, 43, 44, 45, 272, 47, 48, + /* 710 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + /* 720 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + /* 730 */ 113, 114, 240, 60, 241, 242, 118, 25, 102, 255, + /* 740 */ 166, 167, 101, 22, 26, 19, 20, 254, 22, 256, + /* 750 */ 139, 140, 117, 118, 119, 306, 195, 308, 117, 118, + /* 760 */ 237, 238, 36, 122, 103, 104, 105, 106, 107, 108, + /* 770 */ 109, 110, 111, 112, 113, 114, 195, 195, 60, 218, + /* 780 */ 219, 60, 109, 195, 19, 217, 60, 25, 23, 77, + /* 790 */ 117, 118, 119, 225, 233, 154, 155, 156, 72, 312, + /* 800 */ 218, 219, 90, 316, 22, 93, 303, 304, 43, 44, + /* 810 */ 45, 195, 47, 48, 49, 50, 51, 52, 53, 54, + /* 820 */ 55, 56, 57, 58, 183, 195, 195, 101, 19, 213, + /* 830 */ 214, 243, 23, 107, 108, 117, 118, 119, 117, 118, + /* 840 */ 119, 115, 60, 117, 118, 119, 195, 60, 122, 218, + /* 850 */ 219, 22, 43, 44, 45, 35, 47, 48, 49, 50, + /* 860 */ 51, 52, 53, 54, 55, 56, 57, 58, 103, 104, + /* 870 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + /* 880 */ 154, 155, 156, 157, 158, 195, 255, 67, 195, 60, + /* 890 */ 101, 240, 311, 312, 306, 75, 308, 316, 29, 117, + /* 900 */ 118, 119, 33, 287, 117, 118, 119, 118, 146, 183, + /* 910 */ 195, 122, 103, 104, 105, 106, 107, 108, 109, 110, + /* 920 */ 111, 112, 113, 114, 215, 195, 77, 60, 25, 195, + /* 930 */ 122, 144, 19, 218, 219, 66, 23, 88, 246, 90, + /* 940 */ 132, 25, 93, 154, 155, 156, 117, 118, 119, 257, + /* 950 */ 195, 131, 218, 219, 195, 265, 43, 44, 45, 195, + /* 960 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 970 */ 57, 58, 183, 218, 219, 195, 19, 218, 219, 195, + /* 980 */ 23, 195, 218, 219, 117, 118, 119, 195, 233, 255, + /* 990 */ 195, 195, 233, 22, 23, 146, 25, 233, 218, 219, + /* 1000 */ 43, 44, 45, 294, 47, 48, 49, 50, 51, 52, + /* 1010 */ 53, 54, 55, 56, 57, 58, 103, 104, 105, 106, + /* 1020 */ 107, 108, 109, 110, 111, 112, 113, 114, 195, 12, + /* 1030 */ 234, 195, 240, 74, 195, 255, 195, 60, 243, 262, + /* 1040 */ 263, 311, 312, 25, 27, 19, 316, 107, 108, 265, + /* 1050 */ 24, 265, 195, 150, 195, 139, 140, 218, 219, 42, + /* 1060 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + /* 1070 */ 113, 114, 233, 102, 67, 218, 219, 218, 219, 243, + /* 1080 */ 19, 64, 22, 23, 23, 25, 195, 128, 129, 130, + /* 1090 */ 233, 74, 233, 86, 154, 118, 156, 130, 265, 208, + /* 1100 */ 19, 306, 95, 308, 43, 44, 45, 266, 47, 48, + /* 1110 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + /* 1120 */ 153, 230, 96, 232, 43, 44, 45, 19, 47, 48, + /* 1130 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + /* 1140 */ 114, 22, 306, 24, 308, 127, 120, 121, 122, 123, + /* 1150 */ 124, 125, 126, 195, 147, 212, 213, 214, 132, 23, + /* 1160 */ 195, 25, 102, 100, 103, 104, 105, 106, 107, 108, + /* 1170 */ 109, 110, 111, 112, 113, 114, 218, 219, 19, 60, + /* 1180 */ 195, 12, 210, 211, 103, 104, 105, 106, 107, 108, + /* 1190 */ 109, 110, 111, 112, 113, 114, 27, 134, 195, 195, + /* 1200 */ 195, 210, 211, 218, 219, 195, 47, 195, 212, 213, + /* 1210 */ 214, 42, 16, 130, 19, 112, 113, 114, 23, 77, + /* 1220 */ 195, 218, 219, 218, 219, 117, 163, 164, 218, 219, + /* 1230 */ 218, 219, 90, 64, 19, 93, 153, 118, 43, 44, + /* 1240 */ 45, 160, 47, 48, 49, 50, 51, 52, 53, 54, + /* 1250 */ 55, 56, 57, 58, 195, 119, 272, 276, 43, 44, + /* 1260 */ 45, 195, 47, 48, 49, 50, 51, 52, 53, 54, + /* 1270 */ 55, 56, 57, 58, 78, 116, 80, 218, 219, 116, + /* 1280 */ 144, 128, 129, 130, 218, 219, 61, 195, 47, 195, + /* 1290 */ 16, 132, 195, 263, 195, 314, 315, 267, 103, 104, + /* 1300 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + /* 1310 */ 218, 219, 218, 219, 151, 218, 219, 195, 103, 104, + /* 1320 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + /* 1330 */ 210, 211, 195, 7, 8, 9, 195, 60, 195, 312, + /* 1340 */ 218, 219, 195, 316, 195, 120, 195, 263, 19, 195, + /* 1350 */ 125, 267, 78, 24, 80, 218, 219, 116, 162, 218, + /* 1360 */ 219, 218, 219, 301, 302, 218, 219, 195, 19, 218, + /* 1370 */ 219, 276, 43, 44, 45, 160, 47, 48, 49, 50, + /* 1380 */ 51, 52, 53, 54, 55, 56, 57, 58, 19, 146, + /* 1390 */ 218, 219, 43, 44, 45, 118, 47, 48, 49, 50, + /* 1400 */ 51, 52, 53, 54, 55, 56, 57, 58, 165, 314, + /* 1410 */ 315, 276, 43, 44, 45, 266, 47, 48, 49, 50, + /* 1420 */ 51, 52, 53, 54, 55, 56, 57, 58, 128, 129, + /* 1430 */ 130, 195, 103, 104, 105, 106, 107, 108, 109, 110, + /* 1440 */ 111, 112, 113, 114, 195, 228, 195, 61, 195, 314, + /* 1450 */ 315, 25, 103, 104, 105, 106, 107, 108, 109, 110, + /* 1460 */ 111, 112, 113, 114, 195, 22, 195, 218, 219, 218, + /* 1470 */ 219, 195, 103, 104, 105, 106, 107, 108, 109, 110, + /* 1480 */ 111, 112, 113, 114, 195, 195, 246, 218, 219, 218, + /* 1490 */ 219, 25, 19, 246, 218, 219, 246, 257, 259, 260, + /* 1500 */ 195, 22, 266, 60, 257, 195, 120, 257, 218, 219, + /* 1510 */ 116, 195, 19, 195, 150, 151, 25, 44, 45, 266, + /* 1520 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 1530 */ 57, 58, 195, 54, 218, 219, 218, 219, 45, 145, + /* 1540 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 1550 */ 57, 58, 246, 121, 122, 218, 219, 19, 23, 31, + /* 1560 */ 25, 118, 159, 257, 161, 24, 195, 39, 195, 143, + /* 1570 */ 195, 19, 20, 22, 22, 24, 103, 104, 105, 106, + /* 1580 */ 107, 108, 109, 110, 111, 112, 113, 114, 36, 218, + /* 1590 */ 219, 218, 219, 218, 219, 195, 103, 104, 105, 106, + /* 1600 */ 107, 108, 109, 110, 111, 112, 113, 114, 195, 143, + /* 1610 */ 119, 136, 60, 195, 22, 195, 141, 195, 218, 219, + /* 1620 */ 195, 23, 195, 25, 72, 23, 131, 25, 195, 134, + /* 1630 */ 23, 218, 219, 195, 82, 144, 218, 219, 218, 219, + /* 1640 */ 218, 219, 195, 218, 219, 218, 219, 60, 23, 195, + /* 1650 */ 25, 218, 219, 101, 195, 117, 218, 219, 195, 107, + /* 1660 */ 108, 23, 195, 25, 195, 218, 219, 115, 228, 117, + /* 1670 */ 118, 119, 218, 219, 122, 195, 19, 218, 219, 195, + /* 1680 */ 60, 218, 219, 142, 195, 218, 219, 19, 20, 195, + /* 1690 */ 22, 139, 140, 23, 23, 25, 25, 195, 218, 219, + /* 1700 */ 7, 8, 218, 219, 36, 118, 154, 155, 156, 157, + /* 1710 */ 158, 195, 23, 195, 25, 84, 85, 49, 195, 23, + /* 1720 */ 195, 25, 195, 23, 195, 25, 195, 23, 60, 25, + /* 1730 */ 23, 23, 25, 25, 142, 183, 218, 219, 118, 195, + /* 1740 */ 72, 218, 219, 218, 219, 218, 219, 218, 219, 218, + /* 1750 */ 219, 195, 195, 146, 86, 98, 23, 195, 25, 91, + /* 1760 */ 19, 20, 154, 22, 156, 154, 23, 156, 25, 101, + /* 1770 */ 23, 195, 25, 195, 195, 107, 108, 36, 195, 195, + /* 1780 */ 195, 195, 228, 115, 195, 117, 118, 119, 195, 195, + /* 1790 */ 122, 261, 195, 321, 195, 195, 195, 258, 238, 195, + /* 1800 */ 195, 60, 299, 291, 195, 195, 258, 195, 195, 195, + /* 1810 */ 290, 244, 216, 72, 245, 193, 258, 258, 299, 258, + /* 1820 */ 299, 274, 154, 155, 156, 157, 158, 86, 247, 295, + /* 1830 */ 248, 295, 91, 19, 20, 270, 22, 274, 270, 248, + /* 1840 */ 274, 222, 101, 227, 274, 221, 231, 221, 107, 108, + /* 1850 */ 36, 183, 262, 247, 221, 283, 115, 262, 117, 118, + /* 1860 */ 119, 198, 116, 122, 220, 262, 61, 220, 220, 251, + /* 1870 */ 247, 142, 251, 245, 60, 202, 299, 202, 38, 262, + /* 1880 */ 202, 22, 152, 151, 296, 43, 72, 236, 18, 239, + /* 1890 */ 202, 239, 239, 239, 18, 154, 155, 156, 157, 158, + /* 1900 */ 86, 150, 201, 248, 275, 91, 248, 273, 236, 248, + /* 1910 */ 275, 275, 273, 236, 248, 101, 286, 202, 201, 159, + /* 1920 */ 63, 107, 108, 296, 183, 293, 202, 201, 22, 115, + /* 1930 */ 202, 117, 118, 119, 292, 223, 122, 201, 65, 202, + /* 1940 */ 201, 223, 220, 220, 22, 220, 226, 226, 229, 127, + /* 1950 */ 223, 220, 166, 24, 285, 220, 222, 114, 315, 285, + /* 1960 */ 220, 202, 220, 307, 92, 320, 320, 229, 154, 155, + /* 1970 */ 156, 157, 158, 0, 1, 2, 223, 83, 5, 268, + /* 1980 */ 149, 268, 146, 10, 11, 12, 13, 14, 22, 280, + /* 1990 */ 17, 202, 159, 19, 20, 251, 22, 183, 282, 148, + /* 2000 */ 252, 252, 250, 30, 249, 32, 248, 147, 25, 13, + /* 2010 */ 36, 204, 196, 40, 196, 6, 302, 194, 194, 194, + /* 2020 */ 209, 215, 209, 215, 215, 215, 224, 224, 216, 209, + /* 2030 */ 4, 216, 215, 3, 60, 22, 122, 19, 122, 19, + /* 2040 */ 125, 22, 15, 22, 71, 16, 72, 23, 23, 140, + /* 2050 */ 305, 152, 79, 25, 131, 82, 143, 20, 16, 305, + /* 2060 */ 1, 143, 145, 131, 131, 62, 54, 131, 37, 54, + /* 2070 */ 54, 152, 99, 117, 34, 101, 54, 24, 1, 5, + /* 2080 */ 22, 107, 108, 116, 76, 25, 162, 41, 142, 115, + /* 2090 */ 24, 117, 118, 119, 116, 20, 122, 19, 126, 23, + /* 2100 */ 132, 19, 20, 69, 22, 69, 22, 134, 22, 68, + /* 2110 */ 22, 22, 139, 140, 60, 141, 68, 24, 36, 28, + /* 2120 */ 97, 22, 37, 68, 23, 150, 34, 22, 154, 155, + /* 2130 */ 156, 157, 158, 23, 23, 22, 163, 25, 23, 142, + /* 2140 */ 23, 98, 60, 23, 22, 144, 25, 76, 34, 117, + /* 2150 */ 34, 89, 34, 34, 72, 87, 76, 183, 34, 94, + /* 2160 */ 34, 23, 22, 24, 34, 23, 25, 44, 25, 23, + /* 2170 */ 23, 23, 22, 22, 25, 11, 143, 25, 143, 23, + /* 2180 */ 22, 22, 22, 101, 23, 23, 136, 22, 25, 107, + /* 2190 */ 108, 142, 25, 142, 142, 23, 15, 115, 1, 117, + /* 2200 */ 118, 119, 1, 2, 122, 1, 5, 322, 322, 322, + /* 2210 */ 322, 10, 11, 12, 13, 14, 322, 322, 17, 322, + /* 2220 */ 5, 322, 322, 141, 322, 10, 11, 12, 13, 14, + /* 2230 */ 322, 30, 17, 32, 322, 322, 154, 155, 156, 157, + /* 2240 */ 158, 40, 322, 322, 322, 30, 322, 32, 322, 322, + /* 2250 */ 322, 322, 322, 322, 322, 40, 322, 322, 322, 322, + /* 2260 */ 322, 322, 322, 322, 322, 183, 322, 322, 322, 322, + /* 2270 */ 322, 322, 71, 322, 322, 322, 322, 322, 322, 322, + /* 2280 */ 79, 322, 322, 82, 322, 322, 71, 322, 322, 322, + /* 2290 */ 322, 322, 322, 322, 79, 322, 322, 82, 322, 322, + /* 2300 */ 99, 322, 322, 322, 322, 322, 322, 322, 322, 322, + /* 2310 */ 322, 322, 322, 322, 99, 322, 322, 322, 322, 322, + /* 2320 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, + /* 2330 */ 322, 322, 322, 322, 322, 134, 322, 322, 322, 322, + /* 2340 */ 139, 140, 322, 322, 322, 322, 322, 322, 322, 134, + /* 2350 */ 322, 322, 322, 322, 139, 140, 322, 322, 322, 322, + /* 2360 */ 322, 322, 322, 322, 163, 322, 322, 322, 322, 322, + /* 2370 */ 322, 322, 322, 322, 322, 322, 322, 322, 163, 322, + /* 2380 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, + /* 2390 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, + /* 2400 */ 322, 322, 322, 322, 322, 322, 322, 322, 187, 187, + /* 2410 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2420 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2430 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2440 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2450 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2460 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2470 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2480 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2490 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2500 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2510 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2520 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2530 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2540 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2550 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + /* 2560 */ 187, 187, 187, 187, 187, 187, +}; +#define YY_SHIFT_COUNT (599) +#define YY_SHIFT_MIN (0) +#define YY_SHIFT_MAX (2215) +static const unsigned short int yy_shift_ofst[] = { + /* 0 */ 2201, 1973, 2215, 1552, 1552, 33, 368, 1668, 1741, 1814, + /* 10 */ 726, 726, 726, 265, 33, 33, 33, 33, 33, 0, + /* 20 */ 0, 216, 1349, 726, 726, 726, 726, 726, 726, 726, + /* 30 */ 726, 726, 726, 726, 726, 726, 726, 726, 272, 272, + /* 40 */ 111, 111, 316, 365, 516, 867, 867, 916, 916, 916, + /* 50 */ 916, 40, 112, 260, 364, 408, 512, 617, 661, 765, + /* 60 */ 809, 913, 957, 1061, 1081, 1195, 1215, 1329, 1349, 1349, + /* 70 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, + /* 80 */ 1349, 1349, 1349, 1349, 1349, 1349, 1369, 1349, 1473, 1493, + /* 90 */ 1493, 473, 1974, 2082, 726, 726, 726, 726, 726, 726, + /* 100 */ 726, 726, 726, 726, 726, 726, 726, 726, 726, 726, + /* 110 */ 726, 726, 726, 726, 726, 726, 726, 726, 726, 726, + /* 120 */ 726, 726, 726, 726, 726, 726, 726, 726, 726, 726, + /* 130 */ 726, 726, 726, 726, 726, 726, 726, 726, 726, 726, + /* 140 */ 726, 726, 726, 726, 726, 726, 138, 232, 232, 232, + /* 150 */ 232, 232, 232, 232, 188, 99, 242, 718, 416, 1159, + /* 160 */ 867, 867, 940, 940, 867, 1103, 417, 574, 574, 574, + /* 170 */ 611, 139, 139, 2379, 2379, 1026, 1026, 1026, 536, 466, + /* 180 */ 466, 466, 466, 1017, 1017, 849, 718, 971, 1060, 867, + /* 190 */ 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, + /* 200 */ 867, 867, 867, 867, 867, 867, 867, 867, 261, 712, + /* 210 */ 712, 867, 108, 1142, 1142, 977, 1108, 1108, 977, 977, + /* 220 */ 1243, 2379, 2379, 2379, 2379, 2379, 2379, 2379, 641, 789, + /* 230 */ 789, 635, 366, 721, 673, 782, 494, 787, 829, 867, + /* 240 */ 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, + /* 250 */ 959, 867, 867, 867, 867, 867, 867, 867, 867, 867, + /* 260 */ 867, 867, 867, 867, 867, 820, 820, 820, 867, 867, + /* 270 */ 867, 1136, 867, 867, 867, 1119, 1007, 867, 1169, 867, + /* 280 */ 867, 867, 867, 867, 867, 867, 867, 1225, 1153, 869, + /* 290 */ 196, 618, 618, 618, 618, 1491, 196, 196, 91, 339, + /* 300 */ 1326, 1386, 383, 1163, 1364, 1426, 1364, 1538, 903, 1163, + /* 310 */ 1163, 903, 1163, 1426, 1538, 1018, 1535, 1241, 1528, 1528, + /* 320 */ 1528, 1394, 1394, 1394, 1394, 762, 762, 1403, 1466, 1475, + /* 330 */ 1551, 1746, 1805, 1746, 1746, 1729, 1729, 1840, 1840, 1729, + /* 340 */ 1730, 1732, 1859, 1842, 1870, 1870, 1870, 1870, 1729, 1876, + /* 350 */ 1751, 1732, 1732, 1751, 1859, 1842, 1751, 1842, 1751, 1729, + /* 360 */ 1876, 1760, 1857, 1729, 1876, 1906, 1729, 1876, 1729, 1876, + /* 370 */ 1906, 1746, 1746, 1746, 1873, 1922, 1922, 1906, 1746, 1822, + /* 380 */ 1746, 1873, 1746, 1746, 1786, 1929, 1843, 1843, 1906, 1729, + /* 390 */ 1872, 1872, 1894, 1894, 1831, 1836, 1966, 1729, 1833, 1831, + /* 400 */ 1851, 1860, 1751, 1983, 1996, 1996, 2009, 2009, 2009, 2379, + /* 410 */ 2379, 2379, 2379, 2379, 2379, 2379, 2379, 2379, 2379, 2379, + /* 420 */ 2379, 2379, 2379, 2379, 136, 1063, 1196, 530, 636, 1274, + /* 430 */ 1300, 1443, 1598, 1495, 1479, 967, 1083, 1602, 463, 1625, + /* 440 */ 1638, 1670, 1541, 1671, 1689, 1696, 1277, 1432, 1693, 808, + /* 450 */ 1700, 1607, 1657, 1587, 1704, 1707, 1631, 1708, 1733, 1608, + /* 460 */ 1611, 1743, 1747, 1620, 1592, 2026, 2030, 2013, 1914, 2018, + /* 470 */ 1916, 2020, 2019, 2021, 1915, 2027, 2029, 2024, 2025, 1909, + /* 480 */ 1899, 1923, 2028, 2028, 1913, 2037, 1917, 2042, 2059, 1918, + /* 490 */ 1932, 2028, 1933, 2003, 2031, 2028, 1919, 2012, 2015, 2016, + /* 500 */ 2022, 1936, 1956, 2040, 2053, 2077, 2074, 2058, 1967, 1924, + /* 510 */ 2034, 2060, 2036, 2008, 2046, 1946, 1978, 2066, 2075, 2078, + /* 520 */ 1968, 1972, 2084, 2041, 2086, 2088, 2076, 2089, 2048, 2054, + /* 530 */ 2093, 2023, 2091, 2099, 2055, 2085, 2101, 2092, 1975, 2105, + /* 540 */ 2110, 2111, 2112, 2115, 2113, 2043, 1997, 2117, 2120, 2032, + /* 550 */ 2114, 2122, 2001, 2121, 2116, 2118, 2119, 2124, 2062, 2071, + /* 560 */ 2068, 2123, 2080, 2065, 2126, 2138, 2140, 2139, 2141, 2143, + /* 570 */ 2130, 2033, 2035, 2142, 2121, 2146, 2147, 2148, 2150, 2149, + /* 580 */ 2152, 2156, 2151, 2164, 2158, 2159, 2161, 2162, 2160, 2165, + /* 590 */ 2163, 2050, 2049, 2051, 2052, 2167, 2172, 2181, 2197, 2204, +}; +#define YY_REDUCE_COUNT (423) +#define YY_REDUCE_MIN (-303) +#define YY_REDUCE_MAX (1825) +static const short yy_reduce_ofst[] = { + /* 0 */ -67, 345, -64, -178, -181, 143, 435, -78, -183, 163, + /* 10 */ -185, 284, 384, -174, 189, 352, 440, 444, 493, -23, + /* 20 */ 227, -277, -1, 305, 561, 755, 759, 764, -189, 839, + /* 30 */ 857, 354, 484, 859, 631, 67, 734, 780, -187, 616, + /* 40 */ 581, 730, 891, 449, 588, 795, 836, -238, 287, -238, + /* 50 */ 287, -256, -256, -256, -256, -256, -256, -256, -256, -256, + /* 60 */ -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, + /* 70 */ -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, + /* 80 */ -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, + /* 90 */ -256, 205, 582, 715, 958, 985, 1003, 1005, 1010, 1012, + /* 100 */ 1059, 1066, 1092, 1094, 1097, 1122, 1137, 1141, 1143, 1147, + /* 110 */ 1151, 1172, 1249, 1251, 1269, 1271, 1276, 1290, 1316, 1318, + /* 120 */ 1337, 1371, 1373, 1375, 1400, 1413, 1418, 1420, 1422, 1425, + /* 130 */ 1427, 1433, 1438, 1447, 1454, 1459, 1463, 1467, 1480, 1484, + /* 140 */ 1518, 1523, 1525, 1527, 1529, 1531, -256, -256, -256, -256, + /* 150 */ -256, -256, -256, -256, -256, -256, -256, 155, 210, -220, + /* 160 */ 86, -130, 943, 996, 402, -256, -113, 981, 1095, 1135, + /* 170 */ 395, -256, -256, -256, -256, 568, 568, 568, -4, -153, + /* 180 */ -133, 259, 306, -166, 523, -303, -126, 503, 503, -37, + /* 190 */ -149, 164, 690, 292, 412, 492, 651, 784, 332, 786, + /* 200 */ 841, 1149, 833, 1236, 792, 162, 796, 1253, 777, 288, + /* 210 */ 381, 380, 709, 487, 1027, 972, 1030, 1084, 991, 1120, + /* 220 */ -152, 1062, 692, 1240, 1247, 1250, 1239, 1306, -207, -194, + /* 230 */ 57, 180, 74, 315, 355, 376, 452, 488, 630, 693, + /* 240 */ 965, 1004, 1025, 1099, 1154, 1289, 1305, 1310, 1469, 1489, + /* 250 */ 984, 1494, 1502, 1516, 1544, 1556, 1557, 1562, 1576, 1578, + /* 260 */ 1579, 1583, 1584, 1585, 1586, 1217, 1440, 1554, 1589, 1593, + /* 270 */ 1594, 1530, 1597, 1599, 1600, 1539, 1472, 1601, 1560, 1604, + /* 280 */ 355, 1605, 1609, 1610, 1612, 1613, 1614, 1503, 1512, 1520, + /* 290 */ 1567, 1548, 1558, 1559, 1561, 1530, 1567, 1567, 1569, 1596, + /* 300 */ 1622, 1519, 1521, 1547, 1565, 1581, 1568, 1534, 1582, 1563, + /* 310 */ 1566, 1591, 1570, 1606, 1536, 1619, 1615, 1616, 1624, 1626, + /* 320 */ 1633, 1590, 1595, 1603, 1617, 1618, 1621, 1572, 1623, 1628, + /* 330 */ 1663, 1644, 1577, 1647, 1648, 1673, 1675, 1588, 1627, 1678, + /* 340 */ 1630, 1629, 1634, 1651, 1650, 1652, 1653, 1654, 1688, 1701, + /* 350 */ 1655, 1635, 1636, 1658, 1639, 1672, 1661, 1677, 1666, 1715, + /* 360 */ 1717, 1632, 1642, 1724, 1726, 1712, 1728, 1736, 1737, 1739, + /* 370 */ 1718, 1722, 1723, 1725, 1719, 1720, 1721, 1727, 1731, 1734, + /* 380 */ 1735, 1738, 1740, 1742, 1643, 1656, 1669, 1674, 1753, 1759, + /* 390 */ 1645, 1646, 1711, 1713, 1748, 1744, 1709, 1789, 1716, 1749, + /* 400 */ 1752, 1755, 1758, 1807, 1816, 1818, 1823, 1824, 1825, 1745, + /* 410 */ 1754, 1714, 1811, 1806, 1808, 1809, 1810, 1813, 1802, 1803, + /* 420 */ 1812, 1815, 1817, 1820, +}; +static const YYACTIONTYPE yy_default[] = { + /* 0 */ 1691, 1691, 1691, 1516, 1279, 1392, 1279, 1279, 1279, 1279, + /* 10 */ 1516, 1516, 1516, 1279, 1279, 1279, 1279, 1279, 1279, 1422, + /* 20 */ 1422, 1568, 1312, 1279, 1279, 1279, 1279, 1279, 1279, 1279, + /* 30 */ 1279, 1279, 1279, 1279, 1279, 1515, 1279, 1279, 1279, 1279, + /* 40 */ 1607, 1607, 1279, 1279, 1279, 1279, 1279, 1592, 1591, 1279, + /* 50 */ 1279, 1279, 1431, 1279, 1279, 1279, 1438, 1279, 1279, 1279, + /* 60 */ 1279, 1279, 1517, 1518, 1279, 1279, 1279, 1279, 1567, 1569, + /* 70 */ 1533, 1445, 1444, 1443, 1442, 1551, 1410, 1436, 1429, 1433, + /* 80 */ 1512, 1513, 1511, 1670, 1518, 1517, 1279, 1432, 1480, 1496, + /* 90 */ 1479, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, + /* 100 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, + /* 110 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, + /* 120 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, + /* 130 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, + /* 140 */ 1279, 1279, 1279, 1279, 1279, 1279, 1488, 1495, 1494, 1493, + /* 150 */ 1502, 1492, 1489, 1482, 1481, 1483, 1484, 1303, 1300, 1354, + /* 160 */ 1279, 1279, 1279, 1279, 1279, 1485, 1312, 1473, 1472, 1471, + /* 170 */ 1279, 1499, 1486, 1498, 1497, 1575, 1644, 1643, 1534, 1279, + /* 180 */ 1279, 1279, 1279, 1279, 1279, 1607, 1279, 1279, 1279, 1279, + /* 190 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, + /* 200 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1412, 1607, + /* 210 */ 1607, 1279, 1312, 1607, 1607, 1308, 1413, 1413, 1308, 1308, + /* 220 */ 1416, 1587, 1383, 1383, 1383, 1383, 1392, 1383, 1279, 1279, + /* 230 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, + /* 240 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1572, 1570, 1279, + /* 250 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, + /* 260 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, + /* 270 */ 1279, 1279, 1279, 1279, 1279, 1388, 1279, 1279, 1279, 1279, + /* 280 */ 1279, 1279, 1279, 1279, 1279, 1279, 1637, 1683, 1279, 1546, + /* 290 */ 1368, 1388, 1388, 1388, 1388, 1390, 1369, 1367, 1382, 1313, + /* 300 */ 1286, 1683, 1683, 1448, 1437, 1389, 1437, 1680, 1435, 1448, + /* 310 */ 1448, 1435, 1448, 1389, 1680, 1329, 1659, 1324, 1422, 1422, + /* 320 */ 1422, 1412, 1412, 1412, 1412, 1416, 1416, 1514, 1389, 1382, + /* 330 */ 1279, 1355, 1683, 1355, 1355, 1398, 1398, 1682, 1682, 1398, + /* 340 */ 1534, 1667, 1457, 1357, 1363, 1363, 1363, 1363, 1398, 1297, + /* 350 */ 1435, 1667, 1667, 1435, 1457, 1357, 1435, 1357, 1435, 1398, + /* 360 */ 1297, 1550, 1678, 1398, 1297, 1524, 1398, 1297, 1398, 1297, + /* 370 */ 1524, 1355, 1355, 1355, 1344, 1279, 1279, 1524, 1355, 1329, + /* 380 */ 1355, 1344, 1355, 1355, 1625, 1279, 1528, 1528, 1524, 1398, + /* 390 */ 1617, 1617, 1425, 1425, 1430, 1416, 1519, 1398, 1279, 1430, + /* 400 */ 1428, 1426, 1435, 1347, 1640, 1640, 1636, 1636, 1636, 1688, + /* 410 */ 1688, 1587, 1652, 1312, 1312, 1312, 1312, 1652, 1331, 1331, + /* 420 */ 1313, 1313, 1312, 1652, 1279, 1279, 1279, 1279, 1279, 1279, + /* 430 */ 1279, 1647, 1279, 1279, 1535, 1279, 1279, 1279, 1279, 1279, + /* 440 */ 1279, 1279, 1402, 1279, 1279, 1279, 1279, 1279, 1279, 1279, + /* 450 */ 1279, 1279, 1593, 1279, 1279, 1279, 1279, 1279, 1279, 1279, + /* 460 */ 1279, 1279, 1279, 1279, 1462, 1279, 1282, 1584, 1279, 1279, + /* 470 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, + /* 480 */ 1279, 1279, 1439, 1440, 1279, 1279, 1279, 1279, 1279, 1279, + /* 490 */ 1279, 1454, 1279, 1279, 1279, 1449, 1279, 1279, 1279, 1279, + /* 500 */ 1279, 1279, 1279, 1279, 1403, 1279, 1279, 1279, 1279, 1279, + /* 510 */ 1279, 1549, 1548, 1279, 1279, 1400, 1279, 1279, 1279, 1279, + /* 520 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1327, + /* 530 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, + /* 540 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, + /* 550 */ 1279, 1279, 1279, 1427, 1279, 1279, 1279, 1279, 1279, 1279, + /* 560 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1622, 1417, + /* 570 */ 1279, 1279, 1279, 1279, 1671, 1279, 1279, 1279, 1279, 1377, + /* 580 */ 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, + /* 590 */ 1663, 1371, 1463, 1279, 1466, 1301, 1279, 1291, 1279, 1279, +}; +/********** End of lemon-generated parsing tables *****************************/ + +/* The next table maps tokens (terminal symbols) into fallback tokens. +** If a construct like the following: +** +** %fallback ID X Y Z. +** +** appears in the grammar, then ID becomes a fallback token for X, Y, +** and Z. Whenever one of the tokens X, Y, or Z is input to the parser +** but it does not parse, the type of the token is changed to ID and +** the parse is retried before an error is thrown. +** +** This feature can be used, for example, to cause some keywords in a language +** to revert to identifiers if they keyword does not apply in the context where +** it appears. +*/ +#ifdef YYFALLBACK +static const YYCODETYPE yyFallback[] = { + 0, /* $ => nothing */ + 0, /* SEMI => nothing */ + 60, /* EXPLAIN => ID */ + 60, /* QUERY => ID */ + 60, /* PLAN => ID */ + 60, /* BEGIN => ID */ + 0, /* TRANSACTION => nothing */ + 60, /* DEFERRED => ID */ + 60, /* IMMEDIATE => ID */ + 60, /* EXCLUSIVE => ID */ + 0, /* COMMIT => nothing */ + 60, /* END => ID */ + 60, /* ROLLBACK => ID */ + 60, /* SAVEPOINT => ID */ + 60, /* RELEASE => ID */ + 0, /* TO => nothing */ + 0, /* TABLE => nothing */ + 0, /* CREATE => nothing */ + 60, /* IF => ID */ + 0, /* NOT => nothing */ + 0, /* EXISTS => nothing */ + 60, /* TEMP => ID */ + 0, /* LP => nothing */ + 0, /* RP => nothing */ + 0, /* AS => nothing */ + 0, /* COMMA => nothing */ + 60, /* WITHOUT => ID */ + 60, /* ABORT => ID */ + 60, /* ACTION => ID */ + 60, /* AFTER => ID */ + 60, /* ANALYZE => ID */ + 60, /* ASC => ID */ + 60, /* ATTACH => ID */ + 60, /* BEFORE => ID */ + 60, /* BY => ID */ + 60, /* CASCADE => ID */ + 60, /* CAST => ID */ + 60, /* CONFLICT => ID */ + 60, /* DATABASE => ID */ + 60, /* DESC => ID */ + 60, /* DETACH => ID */ + 60, /* EACH => ID */ + 60, /* FAIL => ID */ + 0, /* OR => nothing */ + 0, /* AND => nothing */ + 0, /* IS => nothing */ + 0, /* ISNOT => nothing */ + 60, /* MATCH => ID */ + 60, /* LIKE_KW => ID */ + 0, /* BETWEEN => nothing */ + 0, /* IN => nothing */ + 0, /* ISNULL => nothing */ + 0, /* NOTNULL => nothing */ + 0, /* NE => nothing */ + 0, /* EQ => nothing */ + 0, /* GT => nothing */ + 0, /* LE => nothing */ + 0, /* LT => nothing */ + 0, /* GE => nothing */ + 0, /* ESCAPE => nothing */ + 0, /* ID => nothing */ + 60, /* COLUMNKW => ID */ + 60, /* DO => ID */ + 60, /* FOR => ID */ + 60, /* IGNORE => ID */ + 60, /* INITIALLY => ID */ + 60, /* INSTEAD => ID */ + 60, /* NO => ID */ + 60, /* KEY => ID */ + 60, /* OF => ID */ + 60, /* OFFSET => ID */ + 60, /* PRAGMA => ID */ + 60, /* RAISE => ID */ + 60, /* RECURSIVE => ID */ + 60, /* REPLACE => ID */ + 60, /* RESTRICT => ID */ + 60, /* ROW => ID */ + 60, /* ROWS => ID */ + 60, /* TRIGGER => ID */ + 60, /* VACUUM => ID */ + 60, /* VIEW => ID */ + 60, /* VIRTUAL => ID */ + 60, /* WITH => ID */ + 60, /* NULLS => ID */ + 60, /* FIRST => ID */ + 60, /* LAST => ID */ + 60, /* CURRENT => ID */ + 60, /* FOLLOWING => ID */ + 60, /* PARTITION => ID */ + 60, /* PRECEDING => ID */ + 60, /* RANGE => ID */ + 60, /* UNBOUNDED => ID */ + 60, /* EXCLUDE => ID */ + 60, /* GROUPS => ID */ + 60, /* OTHERS => ID */ + 60, /* TIES => ID */ + 60, /* GENERATED => ID */ + 60, /* ALWAYS => ID */ + 60, /* MATERIALIZED => ID */ + 60, /* REINDEX => ID */ + 60, /* RENAME => ID */ + 60, /* CTIME_KW => ID */ + 0, /* ANY => nothing */ + 0, /* BITAND => nothing */ + 0, /* BITOR => nothing */ + 0, /* LSHIFT => nothing */ + 0, /* RSHIFT => nothing */ + 0, /* PLUS => nothing */ + 0, /* MINUS => nothing */ + 0, /* STAR => nothing */ + 0, /* SLASH => nothing */ + 0, /* REM => nothing */ + 0, /* CONCAT => nothing */ + 0, /* PTR => nothing */ + 0, /* COLLATE => nothing */ + 0, /* BITNOT => nothing */ + 0, /* ON => nothing */ + 0, /* INDEXED => nothing */ + 0, /* STRING => nothing */ + 0, /* JOIN_KW => nothing */ + 0, /* CONSTRAINT => nothing */ + 0, /* DEFAULT => nothing */ + 0, /* NULL => nothing */ + 0, /* PRIMARY => nothing */ + 0, /* UNIQUE => nothing */ + 0, /* CHECK => nothing */ + 0, /* REFERENCES => nothing */ + 0, /* AUTOINCR => nothing */ + 0, /* INSERT => nothing */ + 0, /* DELETE => nothing */ + 0, /* UPDATE => nothing */ + 0, /* SET => nothing */ + 0, /* DEFERRABLE => nothing */ + 0, /* FOREIGN => nothing */ + 0, /* DROP => nothing */ + 0, /* UNION => nothing */ + 0, /* ALL => nothing */ + 0, /* EXCEPT => nothing */ + 0, /* INTERSECT => nothing */ + 0, /* SELECT => nothing */ + 0, /* VALUES => nothing */ + 0, /* DISTINCT => nothing */ + 0, /* DOT => nothing */ + 0, /* FROM => nothing */ + 0, /* JOIN => nothing */ + 0, /* USING => nothing */ + 0, /* ORDER => nothing */ + 0, /* GROUP => nothing */ + 0, /* HAVING => nothing */ + 0, /* LIMIT => nothing */ + 0, /* WHERE => nothing */ + 0, /* RETURNING => nothing */ + 0, /* INTO => nothing */ + 0, /* NOTHING => nothing */ + 0, /* FLOAT => nothing */ + 0, /* BLOB => nothing */ + 0, /* INTEGER => nothing */ + 0, /* VARIABLE => nothing */ + 0, /* CASE => nothing */ + 0, /* WHEN => nothing */ + 0, /* THEN => nothing */ + 0, /* ELSE => nothing */ + 0, /* INDEX => nothing */ + 0, /* ALTER => nothing */ + 0, /* ADD => nothing */ + 0, /* WINDOW => nothing */ + 0, /* OVER => nothing */ + 0, /* FILTER => nothing */ + 0, /* COLUMN => nothing */ + 0, /* AGG_FUNCTION => nothing */ + 0, /* AGG_COLUMN => nothing */ + 0, /* TRUEFALSE => nothing */ + 0, /* FUNCTION => nothing */ + 0, /* UPLUS => nothing */ + 0, /* UMINUS => nothing */ + 0, /* TRUTH => nothing */ + 0, /* REGISTER => nothing */ + 0, /* VECTOR => nothing */ + 0, /* SELECT_COLUMN => nothing */ + 0, /* IF_NULL_ROW => nothing */ + 0, /* ASTERISK => nothing */ + 0, /* SPAN => nothing */ + 0, /* ERROR => nothing */ + 0, /* QNUMBER => nothing */ + 0, /* SPACE => nothing */ + 0, /* COMMENT => nothing */ + 0, /* ILLEGAL => nothing */ +}; +#endif /* YYFALLBACK */ + +/* The following structure represents a single element of the +** parser's stack. Information stored includes: +** +** + The state number for the parser at this level of the stack. +** +** + The value of the token stored at this level of the stack. +** (In other words, the "major" token.) +** +** + The semantic value stored at this level of the stack. This is +** the information used by the action routines in the grammar. +** It is sometimes called the "minor" token. +** +** After the "shift" half of a SHIFTREDUCE action, the stateno field +** actually contains the reduce action for the second half of the +** SHIFTREDUCE. +*/ +struct yyStackEntry { + YYACTIONTYPE stateno; /* The state-number, or reduce action in SHIFTREDUCE */ + YYCODETYPE major; /* The major token value. This is the code + ** number for the token at this stack level */ + YYMINORTYPE minor; /* The user-supplied minor token value. This + ** is the value of the token */ +}; +typedef struct yyStackEntry yyStackEntry; + +/* The state of the parser is completely contained in an instance of +** the following structure */ +struct yyParser { + yyStackEntry *yytos; /* Pointer to top element of the stack */ +#ifdef YYTRACKMAXSTACKDEPTH + int yyhwm; /* High-water mark of the stack */ +#endif +#ifndef YYNOERRORRECOVERY + int yyerrcnt; /* Shifts left before out of the error */ +#endif + sqlite3ParserARG_SDECL /* A place to hold %extra_argument */ + sqlite3ParserCTX_SDECL /* A place to hold %extra_context */ + yyStackEntry *yystackEnd; /* Last entry in the stack */ + yyStackEntry *yystack; /* The parser stack */ + yyStackEntry yystk0[YYSTACKDEPTH]; /* Initial stack space */ +}; +typedef struct yyParser yyParser; + +/* #include */ +#ifndef NDEBUG +/* #include */ +static FILE *yyTraceFILE = 0; +static char *yyTracePrompt = 0; +#endif /* NDEBUG */ + +#ifndef NDEBUG +/* +** Turn parser tracing on by giving a stream to which to write the trace +** and a prompt to preface each trace message. Tracing is turned off +** by making either argument NULL +** +** Inputs: +**
      +**
    • A FILE* to which trace output should be written. +** If NULL, then tracing is turned off. +**
    • A prefix string written at the beginning of every +** line of trace output. If NULL, then tracing is +** turned off. +**
    +** +** Outputs: +** None. +*/ +SQLITE_PRIVATE void sqlite3ParserTrace(FILE *TraceFILE, char *zTracePrompt){ + yyTraceFILE = TraceFILE; + yyTracePrompt = zTracePrompt; + if( yyTraceFILE==0 ) yyTracePrompt = 0; + else if( yyTracePrompt==0 ) yyTraceFILE = 0; +} +#endif /* NDEBUG */ + +#if defined(YYCOVERAGE) || !defined(NDEBUG) +/* For tracing shifts, the names of all terminals and nonterminals +** are required. The following table supplies these names */ +static const char *const yyTokenName[] = { + /* 0 */ "$", + /* 1 */ "SEMI", + /* 2 */ "EXPLAIN", + /* 3 */ "QUERY", + /* 4 */ "PLAN", + /* 5 */ "BEGIN", + /* 6 */ "TRANSACTION", + /* 7 */ "DEFERRED", + /* 8 */ "IMMEDIATE", + /* 9 */ "EXCLUSIVE", + /* 10 */ "COMMIT", + /* 11 */ "END", + /* 12 */ "ROLLBACK", + /* 13 */ "SAVEPOINT", + /* 14 */ "RELEASE", + /* 15 */ "TO", + /* 16 */ "TABLE", + /* 17 */ "CREATE", + /* 18 */ "IF", + /* 19 */ "NOT", + /* 20 */ "EXISTS", + /* 21 */ "TEMP", + /* 22 */ "LP", + /* 23 */ "RP", + /* 24 */ "AS", + /* 25 */ "COMMA", + /* 26 */ "WITHOUT", + /* 27 */ "ABORT", + /* 28 */ "ACTION", + /* 29 */ "AFTER", + /* 30 */ "ANALYZE", + /* 31 */ "ASC", + /* 32 */ "ATTACH", + /* 33 */ "BEFORE", + /* 34 */ "BY", + /* 35 */ "CASCADE", + /* 36 */ "CAST", + /* 37 */ "CONFLICT", + /* 38 */ "DATABASE", + /* 39 */ "DESC", + /* 40 */ "DETACH", + /* 41 */ "EACH", + /* 42 */ "FAIL", + /* 43 */ "OR", + /* 44 */ "AND", + /* 45 */ "IS", + /* 46 */ "ISNOT", + /* 47 */ "MATCH", + /* 48 */ "LIKE_KW", + /* 49 */ "BETWEEN", + /* 50 */ "IN", + /* 51 */ "ISNULL", + /* 52 */ "NOTNULL", + /* 53 */ "NE", + /* 54 */ "EQ", + /* 55 */ "GT", + /* 56 */ "LE", + /* 57 */ "LT", + /* 58 */ "GE", + /* 59 */ "ESCAPE", + /* 60 */ "ID", + /* 61 */ "COLUMNKW", + /* 62 */ "DO", + /* 63 */ "FOR", + /* 64 */ "IGNORE", + /* 65 */ "INITIALLY", + /* 66 */ "INSTEAD", + /* 67 */ "NO", + /* 68 */ "KEY", + /* 69 */ "OF", + /* 70 */ "OFFSET", + /* 71 */ "PRAGMA", + /* 72 */ "RAISE", + /* 73 */ "RECURSIVE", + /* 74 */ "REPLACE", + /* 75 */ "RESTRICT", + /* 76 */ "ROW", + /* 77 */ "ROWS", + /* 78 */ "TRIGGER", + /* 79 */ "VACUUM", + /* 80 */ "VIEW", + /* 81 */ "VIRTUAL", + /* 82 */ "WITH", + /* 83 */ "NULLS", + /* 84 */ "FIRST", + /* 85 */ "LAST", + /* 86 */ "CURRENT", + /* 87 */ "FOLLOWING", + /* 88 */ "PARTITION", + /* 89 */ "PRECEDING", + /* 90 */ "RANGE", + /* 91 */ "UNBOUNDED", + /* 92 */ "EXCLUDE", + /* 93 */ "GROUPS", + /* 94 */ "OTHERS", + /* 95 */ "TIES", + /* 96 */ "GENERATED", + /* 97 */ "ALWAYS", + /* 98 */ "MATERIALIZED", + /* 99 */ "REINDEX", + /* 100 */ "RENAME", + /* 101 */ "CTIME_KW", + /* 102 */ "ANY", + /* 103 */ "BITAND", + /* 104 */ "BITOR", + /* 105 */ "LSHIFT", + /* 106 */ "RSHIFT", + /* 107 */ "PLUS", + /* 108 */ "MINUS", + /* 109 */ "STAR", + /* 110 */ "SLASH", + /* 111 */ "REM", + /* 112 */ "CONCAT", + /* 113 */ "PTR", + /* 114 */ "COLLATE", + /* 115 */ "BITNOT", + /* 116 */ "ON", + /* 117 */ "INDEXED", + /* 118 */ "STRING", + /* 119 */ "JOIN_KW", + /* 120 */ "CONSTRAINT", + /* 121 */ "DEFAULT", + /* 122 */ "NULL", + /* 123 */ "PRIMARY", + /* 124 */ "UNIQUE", + /* 125 */ "CHECK", + /* 126 */ "REFERENCES", + /* 127 */ "AUTOINCR", + /* 128 */ "INSERT", + /* 129 */ "DELETE", + /* 130 */ "UPDATE", + /* 131 */ "SET", + /* 132 */ "DEFERRABLE", + /* 133 */ "FOREIGN", + /* 134 */ "DROP", + /* 135 */ "UNION", + /* 136 */ "ALL", + /* 137 */ "EXCEPT", + /* 138 */ "INTERSECT", + /* 139 */ "SELECT", + /* 140 */ "VALUES", + /* 141 */ "DISTINCT", + /* 142 */ "DOT", + /* 143 */ "FROM", + /* 144 */ "JOIN", + /* 145 */ "USING", + /* 146 */ "ORDER", + /* 147 */ "GROUP", + /* 148 */ "HAVING", + /* 149 */ "LIMIT", + /* 150 */ "WHERE", + /* 151 */ "RETURNING", + /* 152 */ "INTO", + /* 153 */ "NOTHING", + /* 154 */ "FLOAT", + /* 155 */ "BLOB", + /* 156 */ "INTEGER", + /* 157 */ "VARIABLE", + /* 158 */ "CASE", + /* 159 */ "WHEN", + /* 160 */ "THEN", + /* 161 */ "ELSE", + /* 162 */ "INDEX", + /* 163 */ "ALTER", + /* 164 */ "ADD", + /* 165 */ "WINDOW", + /* 166 */ "OVER", + /* 167 */ "FILTER", + /* 168 */ "COLUMN", + /* 169 */ "AGG_FUNCTION", + /* 170 */ "AGG_COLUMN", + /* 171 */ "TRUEFALSE", + /* 172 */ "FUNCTION", + /* 173 */ "UPLUS", + /* 174 */ "UMINUS", + /* 175 */ "TRUTH", + /* 176 */ "REGISTER", + /* 177 */ "VECTOR", + /* 178 */ "SELECT_COLUMN", + /* 179 */ "IF_NULL_ROW", + /* 180 */ "ASTERISK", + /* 181 */ "SPAN", + /* 182 */ "ERROR", + /* 183 */ "QNUMBER", + /* 184 */ "SPACE", + /* 185 */ "COMMENT", + /* 186 */ "ILLEGAL", + /* 187 */ "input", + /* 188 */ "cmdlist", + /* 189 */ "ecmd", + /* 190 */ "cmdx", + /* 191 */ "explain", + /* 192 */ "cmd", + /* 193 */ "transtype", + /* 194 */ "trans_opt", + /* 195 */ "nm", + /* 196 */ "savepoint_opt", + /* 197 */ "create_table", + /* 198 */ "create_table_args", + /* 199 */ "createkw", + /* 200 */ "temp", + /* 201 */ "ifnotexists", + /* 202 */ "dbnm", + /* 203 */ "columnlist", + /* 204 */ "conslist_opt", + /* 205 */ "table_option_set", + /* 206 */ "select", + /* 207 */ "table_option", + /* 208 */ "columnname", + /* 209 */ "carglist", + /* 210 */ "typetoken", + /* 211 */ "typename", + /* 212 */ "signed", + /* 213 */ "plus_num", + /* 214 */ "minus_num", + /* 215 */ "scanpt", + /* 216 */ "scantok", + /* 217 */ "ccons", + /* 218 */ "term", + /* 219 */ "expr", + /* 220 */ "onconf", + /* 221 */ "sortorder", + /* 222 */ "autoinc", + /* 223 */ "eidlist_opt", + /* 224 */ "refargs", + /* 225 */ "defer_subclause", + /* 226 */ "generated", + /* 227 */ "refarg", + /* 228 */ "refact", + /* 229 */ "init_deferred_pred_opt", + /* 230 */ "conslist", + /* 231 */ "tconscomma", + /* 232 */ "tcons", + /* 233 */ "sortlist", + /* 234 */ "eidlist", + /* 235 */ "defer_subclause_opt", + /* 236 */ "orconf", + /* 237 */ "resolvetype", + /* 238 */ "raisetype", + /* 239 */ "ifexists", + /* 240 */ "fullname", + /* 241 */ "selectnowith", + /* 242 */ "oneselect", + /* 243 */ "wqlist", + /* 244 */ "multiselect_op", + /* 245 */ "distinct", + /* 246 */ "selcollist", + /* 247 */ "from", + /* 248 */ "where_opt", + /* 249 */ "groupby_opt", + /* 250 */ "having_opt", + /* 251 */ "orderby_opt", + /* 252 */ "limit_opt", + /* 253 */ "window_clause", + /* 254 */ "values", + /* 255 */ "nexprlist", + /* 256 */ "mvalues", + /* 257 */ "sclp", + /* 258 */ "as", + /* 259 */ "seltablist", + /* 260 */ "stl_prefix", + /* 261 */ "joinop", + /* 262 */ "on_using", + /* 263 */ "indexed_by", + /* 264 */ "exprlist", + /* 265 */ "xfullname", + /* 266 */ "idlist", + /* 267 */ "indexed_opt", + /* 268 */ "nulls", + /* 269 */ "with", + /* 270 */ "where_opt_ret", + /* 271 */ "setlist", + /* 272 */ "insert_cmd", + /* 273 */ "idlist_opt", + /* 274 */ "upsert", + /* 275 */ "returning", + /* 276 */ "filter_over", + /* 277 */ "likeop", + /* 278 */ "between_op", + /* 279 */ "in_op", + /* 280 */ "paren_exprlist", + /* 281 */ "case_operand", + /* 282 */ "case_exprlist", + /* 283 */ "case_else", + /* 284 */ "uniqueflag", + /* 285 */ "collate", + /* 286 */ "vinto", + /* 287 */ "nmnum", + /* 288 */ "trigger_decl", + /* 289 */ "trigger_cmd_list", + /* 290 */ "trigger_time", + /* 291 */ "trigger_event", + /* 292 */ "foreach_clause", + /* 293 */ "when_clause", + /* 294 */ "trigger_cmd", + /* 295 */ "tridxby", + /* 296 */ "database_kw_opt", + /* 297 */ "key_opt", + /* 298 */ "alter_add", + /* 299 */ "kwcolumn_opt", + /* 300 */ "create_vtab", + /* 301 */ "vtabarglist", + /* 302 */ "vtabarg", + /* 303 */ "vtabargtoken", + /* 304 */ "lp", + /* 305 */ "anylist", + /* 306 */ "wqitem", + /* 307 */ "wqas", + /* 308 */ "withnm", + /* 309 */ "windowdefn_list", + /* 310 */ "windowdefn", + /* 311 */ "window", + /* 312 */ "frame_opt", + /* 313 */ "part_opt", + /* 314 */ "filter_clause", + /* 315 */ "over_clause", + /* 316 */ "range_or_rows", + /* 317 */ "frame_bound", + /* 318 */ "frame_bound_s", + /* 319 */ "frame_bound_e", + /* 320 */ "frame_exclude_opt", + /* 321 */ "frame_exclude", +}; +#endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ + +#ifndef NDEBUG +/* For tracing reduce actions, the names of all rules are required. +*/ +static const char *const yyRuleName[] = { + /* 0 */ "explain ::= EXPLAIN", + /* 1 */ "explain ::= EXPLAIN QUERY PLAN", + /* 2 */ "cmdx ::= cmd", + /* 3 */ "cmd ::= BEGIN transtype trans_opt", + /* 4 */ "transtype ::=", + /* 5 */ "transtype ::= DEFERRED", + /* 6 */ "transtype ::= IMMEDIATE", + /* 7 */ "transtype ::= EXCLUSIVE", + /* 8 */ "cmd ::= COMMIT|END trans_opt", + /* 9 */ "cmd ::= ROLLBACK trans_opt", + /* 10 */ "cmd ::= SAVEPOINT nm", + /* 11 */ "cmd ::= RELEASE savepoint_opt nm", + /* 12 */ "cmd ::= ROLLBACK trans_opt TO savepoint_opt nm", + /* 13 */ "create_table ::= createkw temp TABLE ifnotexists nm dbnm", + /* 14 */ "createkw ::= CREATE", + /* 15 */ "ifnotexists ::=", + /* 16 */ "ifnotexists ::= IF NOT EXISTS", + /* 17 */ "temp ::= TEMP", + /* 18 */ "temp ::=", + /* 19 */ "create_table_args ::= LP columnlist conslist_opt RP table_option_set", + /* 20 */ "create_table_args ::= AS select", + /* 21 */ "table_option_set ::=", + /* 22 */ "table_option_set ::= table_option_set COMMA table_option", + /* 23 */ "table_option ::= WITHOUT nm", + /* 24 */ "table_option ::= nm", + /* 25 */ "columnname ::= nm typetoken", + /* 26 */ "typetoken ::=", + /* 27 */ "typetoken ::= typename LP signed RP", + /* 28 */ "typetoken ::= typename LP signed COMMA signed RP", + /* 29 */ "typename ::= typename ID|STRING", + /* 30 */ "scanpt ::=", + /* 31 */ "scantok ::=", + /* 32 */ "ccons ::= CONSTRAINT nm", + /* 33 */ "ccons ::= DEFAULT scantok term", + /* 34 */ "ccons ::= DEFAULT LP expr RP", + /* 35 */ "ccons ::= DEFAULT PLUS scantok term", + /* 36 */ "ccons ::= DEFAULT MINUS scantok term", + /* 37 */ "ccons ::= DEFAULT scantok ID|INDEXED", + /* 38 */ "ccons ::= NOT NULL onconf", + /* 39 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc", + /* 40 */ "ccons ::= UNIQUE onconf", + /* 41 */ "ccons ::= CHECK LP expr RP", + /* 42 */ "ccons ::= REFERENCES nm eidlist_opt refargs", + /* 43 */ "ccons ::= defer_subclause", + /* 44 */ "ccons ::= COLLATE ID|STRING", + /* 45 */ "generated ::= LP expr RP", + /* 46 */ "generated ::= LP expr RP ID", + /* 47 */ "autoinc ::=", + /* 48 */ "autoinc ::= AUTOINCR", + /* 49 */ "refargs ::=", + /* 50 */ "refargs ::= refargs refarg", + /* 51 */ "refarg ::= MATCH nm", + /* 52 */ "refarg ::= ON INSERT refact", + /* 53 */ "refarg ::= ON DELETE refact", + /* 54 */ "refarg ::= ON UPDATE refact", + /* 55 */ "refact ::= SET NULL", + /* 56 */ "refact ::= SET DEFAULT", + /* 57 */ "refact ::= CASCADE", + /* 58 */ "refact ::= RESTRICT", + /* 59 */ "refact ::= NO ACTION", + /* 60 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt", + /* 61 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt", + /* 62 */ "init_deferred_pred_opt ::=", + /* 63 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED", + /* 64 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE", + /* 65 */ "conslist_opt ::=", + /* 66 */ "tconscomma ::= COMMA", + /* 67 */ "tcons ::= CONSTRAINT nm", + /* 68 */ "tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf", + /* 69 */ "tcons ::= UNIQUE LP sortlist RP onconf", + /* 70 */ "tcons ::= CHECK LP expr RP onconf", + /* 71 */ "tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt", + /* 72 */ "defer_subclause_opt ::=", + /* 73 */ "onconf ::=", + /* 74 */ "onconf ::= ON CONFLICT resolvetype", + /* 75 */ "orconf ::=", + /* 76 */ "orconf ::= OR resolvetype", + /* 77 */ "resolvetype ::= IGNORE", + /* 78 */ "resolvetype ::= REPLACE", + /* 79 */ "cmd ::= DROP TABLE ifexists fullname", + /* 80 */ "ifexists ::= IF EXISTS", + /* 81 */ "ifexists ::=", + /* 82 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select", + /* 83 */ "cmd ::= DROP VIEW ifexists fullname", + /* 84 */ "cmd ::= select", + /* 85 */ "select ::= WITH wqlist selectnowith", + /* 86 */ "select ::= WITH RECURSIVE wqlist selectnowith", + /* 87 */ "select ::= selectnowith", + /* 88 */ "selectnowith ::= selectnowith multiselect_op oneselect", + /* 89 */ "multiselect_op ::= UNION", + /* 90 */ "multiselect_op ::= UNION ALL", + /* 91 */ "multiselect_op ::= EXCEPT|INTERSECT", + /* 92 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt", + /* 93 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt", + /* 94 */ "values ::= VALUES LP nexprlist RP", + /* 95 */ "oneselect ::= mvalues", + /* 96 */ "mvalues ::= values COMMA LP nexprlist RP", + /* 97 */ "mvalues ::= mvalues COMMA LP nexprlist RP", + /* 98 */ "distinct ::= DISTINCT", + /* 99 */ "distinct ::= ALL", + /* 100 */ "distinct ::=", + /* 101 */ "sclp ::=", + /* 102 */ "selcollist ::= sclp scanpt expr scanpt as", + /* 103 */ "selcollist ::= sclp scanpt STAR", + /* 104 */ "selcollist ::= sclp scanpt nm DOT STAR", + /* 105 */ "as ::= AS nm", + /* 106 */ "as ::=", + /* 107 */ "from ::=", + /* 108 */ "from ::= FROM seltablist", + /* 109 */ "stl_prefix ::= seltablist joinop", + /* 110 */ "stl_prefix ::=", + /* 111 */ "seltablist ::= stl_prefix nm dbnm as on_using", + /* 112 */ "seltablist ::= stl_prefix nm dbnm as indexed_by on_using", + /* 113 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using", + /* 114 */ "seltablist ::= stl_prefix LP select RP as on_using", + /* 115 */ "seltablist ::= stl_prefix LP seltablist RP as on_using", + /* 116 */ "dbnm ::=", + /* 117 */ "dbnm ::= DOT nm", + /* 118 */ "fullname ::= nm", + /* 119 */ "fullname ::= nm DOT nm", + /* 120 */ "xfullname ::= nm", + /* 121 */ "xfullname ::= nm DOT nm", + /* 122 */ "xfullname ::= nm AS nm", + /* 123 */ "xfullname ::= nm DOT nm AS nm", + /* 124 */ "joinop ::= COMMA|JOIN", + /* 125 */ "joinop ::= JOIN_KW JOIN", + /* 126 */ "joinop ::= JOIN_KW nm JOIN", + /* 127 */ "joinop ::= JOIN_KW nm nm JOIN", + /* 128 */ "on_using ::= ON expr", + /* 129 */ "on_using ::= USING LP idlist RP", + /* 130 */ "on_using ::=", + /* 131 */ "indexed_opt ::=", + /* 132 */ "indexed_by ::= INDEXED BY nm", + /* 133 */ "indexed_by ::= NOT INDEXED", + /* 134 */ "orderby_opt ::=", + /* 135 */ "orderby_opt ::= ORDER BY sortlist", + /* 136 */ "sortlist ::= sortlist COMMA expr sortorder nulls", + /* 137 */ "sortlist ::= expr sortorder nulls", + /* 138 */ "sortorder ::= ASC", + /* 139 */ "sortorder ::= DESC", + /* 140 */ "sortorder ::=", + /* 141 */ "nulls ::= NULLS FIRST", + /* 142 */ "nulls ::= NULLS LAST", + /* 143 */ "nulls ::=", + /* 144 */ "groupby_opt ::=", + /* 145 */ "groupby_opt ::= GROUP BY nexprlist", + /* 146 */ "having_opt ::=", + /* 147 */ "having_opt ::= HAVING expr", + /* 148 */ "limit_opt ::=", + /* 149 */ "limit_opt ::= LIMIT expr", + /* 150 */ "limit_opt ::= LIMIT expr OFFSET expr", + /* 151 */ "limit_opt ::= LIMIT expr COMMA expr", + /* 152 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret", + /* 153 */ "where_opt ::=", + /* 154 */ "where_opt ::= WHERE expr", + /* 155 */ "where_opt_ret ::=", + /* 156 */ "where_opt_ret ::= WHERE expr", + /* 157 */ "where_opt_ret ::= RETURNING selcollist", + /* 158 */ "where_opt_ret ::= WHERE expr RETURNING selcollist", + /* 159 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret", + /* 160 */ "setlist ::= setlist COMMA nm EQ expr", + /* 161 */ "setlist ::= setlist COMMA LP idlist RP EQ expr", + /* 162 */ "setlist ::= nm EQ expr", + /* 163 */ "setlist ::= LP idlist RP EQ expr", + /* 164 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert", + /* 165 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning", + /* 166 */ "upsert ::=", + /* 167 */ "upsert ::= RETURNING selcollist", + /* 168 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert", + /* 169 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert", + /* 170 */ "upsert ::= ON CONFLICT DO NOTHING returning", + /* 171 */ "upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning", + /* 172 */ "returning ::= RETURNING selcollist", + /* 173 */ "insert_cmd ::= INSERT orconf", + /* 174 */ "insert_cmd ::= REPLACE", + /* 175 */ "idlist_opt ::=", + /* 176 */ "idlist_opt ::= LP idlist RP", + /* 177 */ "idlist ::= idlist COMMA nm", + /* 178 */ "idlist ::= nm", + /* 179 */ "expr ::= LP expr RP", + /* 180 */ "expr ::= ID|INDEXED|JOIN_KW", + /* 181 */ "expr ::= nm DOT nm", + /* 182 */ "expr ::= nm DOT nm DOT nm", + /* 183 */ "term ::= NULL|FLOAT|BLOB", + /* 184 */ "term ::= STRING", + /* 185 */ "term ::= INTEGER", + /* 186 */ "expr ::= VARIABLE", + /* 187 */ "expr ::= expr COLLATE ID|STRING", + /* 188 */ "expr ::= CAST LP expr AS typetoken RP", + /* 189 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP", + /* 190 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP", + /* 191 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP", + /* 192 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over", + /* 193 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over", + /* 194 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over", + /* 195 */ "term ::= CTIME_KW", + /* 196 */ "expr ::= LP nexprlist COMMA expr RP", + /* 197 */ "expr ::= expr AND expr", + /* 198 */ "expr ::= expr OR expr", + /* 199 */ "expr ::= expr LT|GT|GE|LE expr", + /* 200 */ "expr ::= expr EQ|NE expr", + /* 201 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", + /* 202 */ "expr ::= expr PLUS|MINUS expr", + /* 203 */ "expr ::= expr STAR|SLASH|REM expr", + /* 204 */ "expr ::= expr CONCAT expr", + /* 205 */ "likeop ::= NOT LIKE_KW|MATCH", + /* 206 */ "expr ::= expr likeop expr", + /* 207 */ "expr ::= expr likeop expr ESCAPE expr", + /* 208 */ "expr ::= expr ISNULL|NOTNULL", + /* 209 */ "expr ::= expr NOT NULL", + /* 210 */ "expr ::= expr IS expr", + /* 211 */ "expr ::= expr IS NOT expr", + /* 212 */ "expr ::= expr IS NOT DISTINCT FROM expr", + /* 213 */ "expr ::= expr IS DISTINCT FROM expr", + /* 214 */ "expr ::= NOT expr", + /* 215 */ "expr ::= BITNOT expr", + /* 216 */ "expr ::= PLUS|MINUS expr", + /* 217 */ "expr ::= expr PTR expr", + /* 218 */ "between_op ::= BETWEEN", + /* 219 */ "between_op ::= NOT BETWEEN", + /* 220 */ "expr ::= expr between_op expr AND expr", + /* 221 */ "in_op ::= IN", + /* 222 */ "in_op ::= NOT IN", + /* 223 */ "expr ::= expr in_op LP exprlist RP", + /* 224 */ "expr ::= LP select RP", + /* 225 */ "expr ::= expr in_op LP select RP", + /* 226 */ "expr ::= expr in_op nm dbnm paren_exprlist", + /* 227 */ "expr ::= EXISTS LP select RP", + /* 228 */ "expr ::= CASE case_operand case_exprlist case_else END", + /* 229 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", + /* 230 */ "case_exprlist ::= WHEN expr THEN expr", + /* 231 */ "case_else ::= ELSE expr", + /* 232 */ "case_else ::=", + /* 233 */ "case_operand ::=", + /* 234 */ "exprlist ::=", + /* 235 */ "nexprlist ::= nexprlist COMMA expr", + /* 236 */ "nexprlist ::= expr", + /* 237 */ "paren_exprlist ::=", + /* 238 */ "paren_exprlist ::= LP exprlist RP", + /* 239 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", + /* 240 */ "uniqueflag ::= UNIQUE", + /* 241 */ "uniqueflag ::=", + /* 242 */ "eidlist_opt ::=", + /* 243 */ "eidlist_opt ::= LP eidlist RP", + /* 244 */ "eidlist ::= eidlist COMMA nm collate sortorder", + /* 245 */ "eidlist ::= nm collate sortorder", + /* 246 */ "collate ::=", + /* 247 */ "collate ::= COLLATE ID|STRING", + /* 248 */ "cmd ::= DROP INDEX ifexists fullname", + /* 249 */ "cmd ::= VACUUM vinto", + /* 250 */ "cmd ::= VACUUM nm vinto", + /* 251 */ "vinto ::= INTO expr", + /* 252 */ "vinto ::=", + /* 253 */ "cmd ::= PRAGMA nm dbnm", + /* 254 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", + /* 255 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", + /* 256 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", + /* 257 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", + /* 258 */ "plus_num ::= PLUS INTEGER|FLOAT", + /* 259 */ "minus_num ::= MINUS INTEGER|FLOAT", + /* 260 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", + /* 261 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", + /* 262 */ "trigger_time ::= BEFORE|AFTER", + /* 263 */ "trigger_time ::= INSTEAD OF", + /* 264 */ "trigger_time ::=", + /* 265 */ "trigger_event ::= DELETE|INSERT", + /* 266 */ "trigger_event ::= UPDATE", + /* 267 */ "trigger_event ::= UPDATE OF idlist", + /* 268 */ "when_clause ::=", + /* 269 */ "when_clause ::= WHEN expr", + /* 270 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", + /* 271 */ "trigger_cmd_list ::= trigger_cmd SEMI", + /* 272 */ "tridxby ::= INDEXED BY nm", + /* 273 */ "tridxby ::= NOT INDEXED", + /* 274 */ "trigger_cmd ::= UPDATE orconf xfullname tridxby SET setlist from where_opt scanpt", + /* 275 */ "trigger_cmd ::= scanpt insert_cmd INTO xfullname idlist_opt select upsert scanpt", + /* 276 */ "trigger_cmd ::= DELETE FROM xfullname tridxby where_opt scanpt", + /* 277 */ "trigger_cmd ::= scanpt select scanpt", + /* 278 */ "expr ::= RAISE LP IGNORE RP", + /* 279 */ "expr ::= RAISE LP raisetype COMMA expr RP", + /* 280 */ "raisetype ::= ROLLBACK", + /* 281 */ "raisetype ::= ABORT", + /* 282 */ "raisetype ::= FAIL", + /* 283 */ "cmd ::= DROP TRIGGER ifexists fullname", + /* 284 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", + /* 285 */ "cmd ::= DETACH database_kw_opt expr", + /* 286 */ "key_opt ::=", + /* 287 */ "key_opt ::= KEY expr", + /* 288 */ "cmd ::= REINDEX", + /* 289 */ "cmd ::= REINDEX nm dbnm", + /* 290 */ "cmd ::= ANALYZE", + /* 291 */ "cmd ::= ANALYZE nm dbnm", + /* 292 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", + /* 293 */ "cmd ::= alter_add carglist", + /* 294 */ "alter_add ::= ALTER TABLE fullname ADD kwcolumn_opt nm typetoken", + /* 295 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm", + /* 296 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", + /* 297 */ "cmd ::= ALTER TABLE fullname DROP CONSTRAINT nm", + /* 298 */ "cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm DROP NOT NULL", + /* 299 */ "cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm SET NOT NULL onconf", + /* 300 */ "cmd ::= ALTER TABLE fullname ADD CONSTRAINT nm CHECK LP expr RP onconf", + /* 301 */ "cmd ::= ALTER TABLE fullname ADD CHECK LP expr RP onconf", + /* 302 */ "cmd ::= create_vtab", + /* 303 */ "cmd ::= create_vtab LP vtabarglist RP", + /* 304 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", + /* 305 */ "vtabarg ::=", + /* 306 */ "vtabargtoken ::= ANY", + /* 307 */ "vtabargtoken ::= lp anylist RP", + /* 308 */ "lp ::= LP", + /* 309 */ "with ::= WITH wqlist", + /* 310 */ "with ::= WITH RECURSIVE wqlist", + /* 311 */ "wqas ::= AS", + /* 312 */ "wqas ::= AS MATERIALIZED", + /* 313 */ "wqas ::= AS NOT MATERIALIZED", + /* 314 */ "wqitem ::= withnm eidlist_opt wqas LP select RP", + /* 315 */ "withnm ::= nm", + /* 316 */ "wqlist ::= wqitem", + /* 317 */ "wqlist ::= wqlist COMMA wqitem", + /* 318 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", + /* 319 */ "windowdefn ::= nm AS LP window RP", + /* 320 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", + /* 321 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", + /* 322 */ "window ::= ORDER BY sortlist frame_opt", + /* 323 */ "window ::= nm ORDER BY sortlist frame_opt", + /* 324 */ "window ::= nm frame_opt", + /* 325 */ "frame_opt ::=", + /* 326 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", + /* 327 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", + /* 328 */ "range_or_rows ::= RANGE|ROWS|GROUPS", + /* 329 */ "frame_bound_s ::= frame_bound", + /* 330 */ "frame_bound_s ::= UNBOUNDED PRECEDING", + /* 331 */ "frame_bound_e ::= frame_bound", + /* 332 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", + /* 333 */ "frame_bound ::= expr PRECEDING|FOLLOWING", + /* 334 */ "frame_bound ::= CURRENT ROW", + /* 335 */ "frame_exclude_opt ::=", + /* 336 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", + /* 337 */ "frame_exclude ::= NO OTHERS", + /* 338 */ "frame_exclude ::= CURRENT ROW", + /* 339 */ "frame_exclude ::= GROUP|TIES", + /* 340 */ "window_clause ::= WINDOW windowdefn_list", + /* 341 */ "filter_over ::= filter_clause over_clause", + /* 342 */ "filter_over ::= over_clause", + /* 343 */ "filter_over ::= filter_clause", + /* 344 */ "over_clause ::= OVER LP window RP", + /* 345 */ "over_clause ::= OVER nm", + /* 346 */ "filter_clause ::= FILTER LP WHERE expr RP", + /* 347 */ "term ::= QNUMBER", + /* 348 */ "input ::= cmdlist", + /* 349 */ "cmdlist ::= cmdlist ecmd", + /* 350 */ "cmdlist ::= ecmd", + /* 351 */ "ecmd ::= SEMI", + /* 352 */ "ecmd ::= cmdx SEMI", + /* 353 */ "ecmd ::= explain cmdx SEMI", + /* 354 */ "trans_opt ::=", + /* 355 */ "trans_opt ::= TRANSACTION", + /* 356 */ "trans_opt ::= TRANSACTION nm", + /* 357 */ "savepoint_opt ::= SAVEPOINT", + /* 358 */ "savepoint_opt ::=", + /* 359 */ "cmd ::= create_table create_table_args", + /* 360 */ "table_option_set ::= table_option", + /* 361 */ "columnlist ::= columnlist COMMA columnname carglist", + /* 362 */ "columnlist ::= columnname carglist", + /* 363 */ "nm ::= ID|INDEXED|JOIN_KW", + /* 364 */ "nm ::= STRING", + /* 365 */ "typetoken ::= typename", + /* 366 */ "typename ::= ID|STRING", + /* 367 */ "signed ::= plus_num", + /* 368 */ "signed ::= minus_num", + /* 369 */ "carglist ::= carglist ccons", + /* 370 */ "carglist ::=", + /* 371 */ "ccons ::= NULL onconf", + /* 372 */ "ccons ::= GENERATED ALWAYS AS generated", + /* 373 */ "ccons ::= AS generated", + /* 374 */ "conslist_opt ::= COMMA conslist", + /* 375 */ "conslist ::= conslist tconscomma tcons", + /* 376 */ "conslist ::= tcons", + /* 377 */ "tconscomma ::=", + /* 378 */ "defer_subclause_opt ::= defer_subclause", + /* 379 */ "resolvetype ::= raisetype", + /* 380 */ "selectnowith ::= oneselect", + /* 381 */ "oneselect ::= values", + /* 382 */ "sclp ::= selcollist COMMA", + /* 383 */ "as ::= ID|STRING", + /* 384 */ "indexed_opt ::= indexed_by", + /* 385 */ "returning ::=", + /* 386 */ "expr ::= term", + /* 387 */ "likeop ::= LIKE_KW|MATCH", + /* 388 */ "case_operand ::= expr", + /* 389 */ "exprlist ::= nexprlist", + /* 390 */ "nmnum ::= plus_num", + /* 391 */ "nmnum ::= nm", + /* 392 */ "nmnum ::= ON", + /* 393 */ "nmnum ::= DELETE", + /* 394 */ "nmnum ::= DEFAULT", + /* 395 */ "plus_num ::= INTEGER|FLOAT", + /* 396 */ "foreach_clause ::=", + /* 397 */ "foreach_clause ::= FOR EACH ROW", + /* 398 */ "tridxby ::=", + /* 399 */ "database_kw_opt ::= DATABASE", + /* 400 */ "database_kw_opt ::=", + /* 401 */ "kwcolumn_opt ::=", + /* 402 */ "kwcolumn_opt ::= COLUMNKW", + /* 403 */ "vtabarglist ::= vtabarg", + /* 404 */ "vtabarglist ::= vtabarglist COMMA vtabarg", + /* 405 */ "vtabarg ::= vtabarg vtabargtoken", + /* 406 */ "anylist ::=", + /* 407 */ "anylist ::= anylist LP anylist RP", + /* 408 */ "anylist ::= anylist ANY", + /* 409 */ "with ::=", + /* 410 */ "windowdefn_list ::= windowdefn", + /* 411 */ "window ::= frame_opt", +}; +#endif /* NDEBUG */ + + +#if YYGROWABLESTACK +/* +** Try to increase the size of the parser stack. Return the number +** of errors. Return 0 on success. +*/ +static int yyGrowStack(yyParser *p){ + int oldSize = 1 + (int)(p->yystackEnd - p->yystack); + int newSize; + int idx; + yyStackEntry *pNew; +#ifdef YYSIZELIMIT + int nLimit = YYSIZELIMIT(sqlite3ParserCTX(p)); +#endif + + newSize = oldSize*2 + 100; +#ifdef YYSIZELIMIT + if( newSize>nLimit ){ + newSize = nLimit; + if( newSize<=oldSize ) return 1; + } +#endif + idx = (int)(p->yytos - p->yystack); + if( p->yystack==p->yystk0 ){ + pNew = YYREALLOC(0, newSize*sizeof(pNew[0]), sqlite3ParserCTX(p)); + if( pNew==0 ) return 1; + memcpy(pNew, p->yystack, oldSize*sizeof(pNew[0])); + }else{ + pNew = YYREALLOC(p->yystack, newSize*sizeof(pNew[0]), sqlite3ParserCTX(p)); + if( pNew==0 ) return 1; + } + p->yystack = pNew; + p->yytos = &p->yystack[idx]; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sStack grows from %d to %d entries.\n", + yyTracePrompt, oldSize, newSize); + } +#endif + p->yystackEnd = &p->yystack[newSize-1]; + return 0; +} +#endif /* YYGROWABLESTACK */ + +#if !YYGROWABLESTACK +/* For builds that do no have a growable stack, yyGrowStack always +** returns an error. +*/ +# define yyGrowStack(X) 1 +#endif + +/* Datatype of the argument to the memory allocated passed as the +** second argument to sqlite3ParserAlloc() below. This can be changed by +** putting an appropriate #define in the %include section of the input +** grammar. +*/ +#ifndef YYMALLOCARGTYPE +# define YYMALLOCARGTYPE size_t +#endif + +/* Initialize a new parser that has already been allocated. +*/ +SQLITE_PRIVATE void sqlite3ParserInit(void *yypRawParser sqlite3ParserCTX_PDECL){ + yyParser *yypParser = (yyParser*)yypRawParser; + sqlite3ParserCTX_STORE +#ifdef YYTRACKMAXSTACKDEPTH + yypParser->yyhwm = 0; +#endif + yypParser->yystack = yypParser->yystk0; + yypParser->yystackEnd = &yypParser->yystack[YYSTACKDEPTH-1]; +#ifndef YYNOERRORRECOVERY + yypParser->yyerrcnt = -1; +#endif + yypParser->yytos = yypParser->yystack; + yypParser->yystack[0].stateno = 0; + yypParser->yystack[0].major = 0; +} + +#ifndef sqlite3Parser_ENGINEALWAYSONSTACK +/* +** This function allocates a new parser. +** The only argument is a pointer to a function which works like +** malloc. +** +** Inputs: +** A pointer to the function used to allocate memory. +** +** Outputs: +** A pointer to a parser. This pointer is used in subsequent calls +** to sqlite3Parser and sqlite3ParserFree. +*/ +SQLITE_PRIVATE void *sqlite3ParserAlloc(void *(*mallocProc)(YYMALLOCARGTYPE) sqlite3ParserCTX_PDECL){ + yyParser *yypParser; + yypParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) ); + if( yypParser ){ + sqlite3ParserCTX_STORE + sqlite3ParserInit(yypParser sqlite3ParserCTX_PARAM); + } + return (void*)yypParser; +} +#endif /* sqlite3Parser_ENGINEALWAYSONSTACK */ + + +/* The following function deletes the "minor type" or semantic value +** associated with a symbol. The symbol can be either a terminal +** or nonterminal. "yymajor" is the symbol code, and "yypminor" is +** a pointer to the value to be deleted. The code used to do the +** deletions is derived from the %destructor and/or %token_destructor +** directives of the input grammar. +*/ +static void yy_destructor( + yyParser *yypParser, /* The parser */ + YYCODETYPE yymajor, /* Type code for object to destroy */ + YYMINORTYPE *yypminor /* The object to be destroyed */ +){ + sqlite3ParserARG_FETCH + sqlite3ParserCTX_FETCH + switch( yymajor ){ + /* Here is inserted the actions which take place when a + ** terminal or non-terminal is destroyed. This can happen + ** when the symbol is popped from the stack during a + ** reduce or during error processing or when a parser is + ** being destroyed before it is finished parsing. + ** + ** Note: during a reduce, the only symbols destroyed are those + ** which appear on the RHS of the rule, but which are *not* used + ** inside the C code. + */ +/********* Begin destructor definitions ***************************************/ + case 206: /* select */ + case 241: /* selectnowith */ + case 242: /* oneselect */ + case 254: /* values */ + case 256: /* mvalues */ +{ +sqlite3SelectDelete(pParse->db, (yypminor->yy555)); +} + break; + case 218: /* term */ + case 219: /* expr */ + case 248: /* where_opt */ + case 250: /* having_opt */ + case 270: /* where_opt_ret */ + case 281: /* case_operand */ + case 283: /* case_else */ + case 286: /* vinto */ + case 293: /* when_clause */ + case 297: /* key_opt */ + case 314: /* filter_clause */ +{ +sqlite3ExprDelete(pParse->db, (yypminor->yy454)); +} + break; + case 223: /* eidlist_opt */ + case 233: /* sortlist */ + case 234: /* eidlist */ + case 246: /* selcollist */ + case 249: /* groupby_opt */ + case 251: /* orderby_opt */ + case 255: /* nexprlist */ + case 257: /* sclp */ + case 264: /* exprlist */ + case 271: /* setlist */ + case 280: /* paren_exprlist */ + case 282: /* case_exprlist */ + case 313: /* part_opt */ +{ +sqlite3ExprListDelete(pParse->db, (yypminor->yy14)); +} + break; + case 240: /* fullname */ + case 247: /* from */ + case 259: /* seltablist */ + case 260: /* stl_prefix */ + case 265: /* xfullname */ +{ +sqlite3SrcListDelete(pParse->db, (yypminor->yy203)); +} + break; + case 243: /* wqlist */ +{ +sqlite3WithDelete(pParse->db, (yypminor->yy59)); +} + break; + case 253: /* window_clause */ + case 309: /* windowdefn_list */ +{ +sqlite3WindowListDelete(pParse->db, (yypminor->yy211)); +} + break; + case 266: /* idlist */ + case 273: /* idlist_opt */ +{ +sqlite3IdListDelete(pParse->db, (yypminor->yy132)); +} + break; + case 276: /* filter_over */ + case 310: /* windowdefn */ + case 311: /* window */ + case 312: /* frame_opt */ + case 315: /* over_clause */ +{ +sqlite3WindowDelete(pParse->db, (yypminor->yy211)); +} + break; + case 289: /* trigger_cmd_list */ + case 294: /* trigger_cmd */ +{ +sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy427)); +} + break; + case 291: /* trigger_event */ +{ +sqlite3IdListDelete(pParse->db, (yypminor->yy286).b); +} + break; + case 317: /* frame_bound */ + case 318: /* frame_bound_s */ + case 319: /* frame_bound_e */ +{ +sqlite3ExprDelete(pParse->db, (yypminor->yy509).pExpr); +} + break; +/********* End destructor definitions *****************************************/ + default: break; /* If no destructor action specified: do nothing */ + } +} + +/* +** Pop the parser's stack once. +** +** If there is a destructor routine associated with the token which +** is popped from the stack, then call it. +*/ +static void yy_pop_parser_stack(yyParser *pParser){ + yyStackEntry *yytos; + assert( pParser->yytos!=0 ); + assert( pParser->yytos > pParser->yystack ); + yytos = pParser->yytos--; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sPopping %s\n", + yyTracePrompt, + yyTokenName[yytos->major]); + } +#endif + yy_destructor(pParser, yytos->major, &yytos->minor); +} + +/* +** Clear all secondary memory allocations from the parser +*/ +SQLITE_PRIVATE void sqlite3ParserFinalize(void *p){ + yyParser *pParser = (yyParser*)p; + + /* In-lined version of calling yy_pop_parser_stack() for each + ** element left in the stack */ + yyStackEntry *yytos = pParser->yytos; + while( yytos>pParser->yystack ){ +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sPopping %s\n", + yyTracePrompt, + yyTokenName[yytos->major]); + } +#endif + if( yytos->major>=YY_MIN_DSTRCTR ){ + yy_destructor(pParser, yytos->major, &yytos->minor); + } + yytos--; + } + +#if YYGROWABLESTACK + if( pParser->yystack!=pParser->yystk0 ){ + YYFREE(pParser->yystack, sqlite3ParserCTX(pParser)); + } +#endif +} + +#ifndef sqlite3Parser_ENGINEALWAYSONSTACK +/* +** Deallocate and destroy a parser. Destructors are called for +** all stack elements before shutting the parser down. +** +** If the YYPARSEFREENEVERNULL macro exists (for example because it +** is defined in a %include section of the input grammar) then it is +** assumed that the input pointer is never NULL. +*/ +SQLITE_PRIVATE void sqlite3ParserFree( + void *p, /* The parser to be deleted */ + void (*freeProc)(void*) /* Function used to reclaim memory */ +){ +#ifndef YYPARSEFREENEVERNULL + if( p==0 ) return; +#endif + sqlite3ParserFinalize(p); + (*freeProc)(p); +} +#endif /* sqlite3Parser_ENGINEALWAYSONSTACK */ + +/* +** Return the peak depth of the stack for a parser. +*/ +#ifdef YYTRACKMAXSTACKDEPTH +SQLITE_PRIVATE int sqlite3ParserStackPeak(void *p){ + yyParser *pParser = (yyParser*)p; + return pParser->yyhwm; +} +#endif + +/* This array of booleans keeps track of the parser statement +** coverage. The element yycoverage[X][Y] is set when the parser +** is in state X and has a lookahead token Y. In a well-tested +** systems, every element of this matrix should end up being set. +*/ +#if defined(YYCOVERAGE) +static unsigned char yycoverage[YYNSTATE][YYNTOKEN]; +#endif + +/* +** Write into out a description of every state/lookahead combination that +** +** (1) has not been used by the parser, and +** (2) is not a syntax error. +** +** Return the number of missed state/lookahead combinations. +*/ +#if defined(YYCOVERAGE) +SQLITE_PRIVATE int sqlite3ParserCoverage(FILE *out){ + int stateno, iLookAhead, i; + int nMissed = 0; + for(stateno=0; statenoYY_MAX_SHIFT ) return stateno; + assert( stateno <= YY_SHIFT_COUNT ); +#if defined(YYCOVERAGE) + yycoverage[stateno][iLookAhead] = 1; +#endif + do{ + i = yy_shift_ofst[stateno]; + assert( i>=0 ); + assert( i<=YY_ACTTAB_COUNT ); + assert( i+YYNTOKEN<=(int)YY_NLOOKAHEAD ); + assert( iLookAhead!=YYNOCODE ); + assert( iLookAhead < YYNTOKEN ); + i += iLookAhead; + assert( i<(int)YY_NLOOKAHEAD ); + if( yy_lookahead[i]!=iLookAhead ){ +#ifdef YYFALLBACK + YYCODETYPE iFallback; /* Fallback token */ + assert( iLookAhead %s\n", + yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); + } +#endif + assert( yyFallback[iFallback]==0 ); /* Fallback loop must terminate */ + iLookAhead = iFallback; + continue; + } +#endif +#ifdef YYWILDCARD + { + int j = i - iLookAhead + YYWILDCARD; + assert( j<(int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])) ); + if( yy_lookahead[j]==YYWILDCARD && iLookAhead>0 ){ +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n", + yyTracePrompt, yyTokenName[iLookAhead], + yyTokenName[YYWILDCARD]); + } +#endif /* NDEBUG */ + return yy_action[j]; + } + } +#endif /* YYWILDCARD */ + return yy_default[stateno]; + }else{ + assert( i>=0 && i<(int)(sizeof(yy_action)/sizeof(yy_action[0])) ); + return yy_action[i]; + } + }while(1); +} + +/* +** Find the appropriate action for a parser given the non-terminal +** look-ahead token iLookAhead. +*/ +static YYACTIONTYPE yy_find_reduce_action( + YYACTIONTYPE stateno, /* Current state number */ + YYCODETYPE iLookAhead /* The look-ahead token */ +){ + int i; +#ifdef YYERRORSYMBOL + if( stateno>YY_REDUCE_COUNT ){ + return yy_default[stateno]; + } +#else + assert( stateno<=YY_REDUCE_COUNT ); +#endif + i = yy_reduce_ofst[stateno]; + assert( iLookAhead!=YYNOCODE ); + i += iLookAhead; +#ifdef YYERRORSYMBOL + if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){ + return yy_default[stateno]; + } +#else + assert( i>=0 && iyytos>yypParser->yystack ) yy_pop_parser_stack(yypParser); + /* Here code is inserted which will execute if the parser + ** stack every overflows */ +/******** Begin %stack_overflow code ******************************************/ + + if( pParse->nErr==0 ) sqlite3ErrorMsg(pParse, "Recursion limit"); +/******** End %stack_overflow code ********************************************/ + sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument var */ + sqlite3ParserCTX_STORE +} + +/* +** Print tracing information for a SHIFT action +*/ +#ifndef NDEBUG +static void yyTraceShift(yyParser *yypParser, int yyNewState, const char *zTag){ + if( yyTraceFILE ){ + if( yyNewStateyytos->major], + yyNewState); + }else{ + fprintf(yyTraceFILE,"%s%s '%s', pending reduce %d\n", + yyTracePrompt, zTag, yyTokenName[yypParser->yytos->major], + yyNewState - YY_MIN_REDUCE); + } + } +} +#else +# define yyTraceShift(X,Y,Z) +#endif + +/* +** Perform a shift action. +*/ +static void yy_shift( + yyParser *yypParser, /* The parser to be shifted */ + YYACTIONTYPE yyNewState, /* The new state to shift in */ + YYCODETYPE yyMajor, /* The major token to shift in */ + sqlite3ParserTOKENTYPE yyMinor /* The minor token to shift in */ +){ + yyStackEntry *yytos; + yypParser->yytos++; +#ifdef YYTRACKMAXSTACKDEPTH + if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){ + yypParser->yyhwm++; + assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack) ); + } +#endif + yytos = yypParser->yytos; + if( yytos>yypParser->yystackEnd ){ + if( yyGrowStack(yypParser) ){ + yypParser->yytos--; + yyStackOverflow(yypParser); + return; + } + yytos = yypParser->yytos; + assert( yytos <= yypParser->yystackEnd ); + } + if( yyNewState > YY_MAX_SHIFT ){ + yyNewState += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE; + } + yytos->stateno = yyNewState; + yytos->major = yyMajor; + yytos->minor.yy0 = yyMinor; + yyTraceShift(yypParser, yyNewState, "Shift"); +} + +/* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side +** of that rule */ +static const YYCODETYPE yyRuleInfoLhs[] = { + 191, /* (0) explain ::= EXPLAIN */ + 191, /* (1) explain ::= EXPLAIN QUERY PLAN */ + 190, /* (2) cmdx ::= cmd */ + 192, /* (3) cmd ::= BEGIN transtype trans_opt */ + 193, /* (4) transtype ::= */ + 193, /* (5) transtype ::= DEFERRED */ + 193, /* (6) transtype ::= IMMEDIATE */ + 193, /* (7) transtype ::= EXCLUSIVE */ + 192, /* (8) cmd ::= COMMIT|END trans_opt */ + 192, /* (9) cmd ::= ROLLBACK trans_opt */ + 192, /* (10) cmd ::= SAVEPOINT nm */ + 192, /* (11) cmd ::= RELEASE savepoint_opt nm */ + 192, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ + 197, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */ + 199, /* (14) createkw ::= CREATE */ + 201, /* (15) ifnotexists ::= */ + 201, /* (16) ifnotexists ::= IF NOT EXISTS */ + 200, /* (17) temp ::= TEMP */ + 200, /* (18) temp ::= */ + 198, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_option_set */ + 198, /* (20) create_table_args ::= AS select */ + 205, /* (21) table_option_set ::= */ + 205, /* (22) table_option_set ::= table_option_set COMMA table_option */ + 207, /* (23) table_option ::= WITHOUT nm */ + 207, /* (24) table_option ::= nm */ + 208, /* (25) columnname ::= nm typetoken */ + 210, /* (26) typetoken ::= */ + 210, /* (27) typetoken ::= typename LP signed RP */ + 210, /* (28) typetoken ::= typename LP signed COMMA signed RP */ + 211, /* (29) typename ::= typename ID|STRING */ + 215, /* (30) scanpt ::= */ + 216, /* (31) scantok ::= */ + 217, /* (32) ccons ::= CONSTRAINT nm */ + 217, /* (33) ccons ::= DEFAULT scantok term */ + 217, /* (34) ccons ::= DEFAULT LP expr RP */ + 217, /* (35) ccons ::= DEFAULT PLUS scantok term */ + 217, /* (36) ccons ::= DEFAULT MINUS scantok term */ + 217, /* (37) ccons ::= DEFAULT scantok ID|INDEXED */ + 217, /* (38) ccons ::= NOT NULL onconf */ + 217, /* (39) ccons ::= PRIMARY KEY sortorder onconf autoinc */ + 217, /* (40) ccons ::= UNIQUE onconf */ + 217, /* (41) ccons ::= CHECK LP expr RP */ + 217, /* (42) ccons ::= REFERENCES nm eidlist_opt refargs */ + 217, /* (43) ccons ::= defer_subclause */ + 217, /* (44) ccons ::= COLLATE ID|STRING */ + 226, /* (45) generated ::= LP expr RP */ + 226, /* (46) generated ::= LP expr RP ID */ + 222, /* (47) autoinc ::= */ + 222, /* (48) autoinc ::= AUTOINCR */ + 224, /* (49) refargs ::= */ + 224, /* (50) refargs ::= refargs refarg */ + 227, /* (51) refarg ::= MATCH nm */ + 227, /* (52) refarg ::= ON INSERT refact */ + 227, /* (53) refarg ::= ON DELETE refact */ + 227, /* (54) refarg ::= ON UPDATE refact */ + 228, /* (55) refact ::= SET NULL */ + 228, /* (56) refact ::= SET DEFAULT */ + 228, /* (57) refact ::= CASCADE */ + 228, /* (58) refact ::= RESTRICT */ + 228, /* (59) refact ::= NO ACTION */ + 225, /* (60) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ + 225, /* (61) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ + 229, /* (62) init_deferred_pred_opt ::= */ + 229, /* (63) init_deferred_pred_opt ::= INITIALLY DEFERRED */ + 229, /* (64) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ + 204, /* (65) conslist_opt ::= */ + 231, /* (66) tconscomma ::= COMMA */ + 232, /* (67) tcons ::= CONSTRAINT nm */ + 232, /* (68) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ + 232, /* (69) tcons ::= UNIQUE LP sortlist RP onconf */ + 232, /* (70) tcons ::= CHECK LP expr RP onconf */ + 232, /* (71) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ + 235, /* (72) defer_subclause_opt ::= */ + 220, /* (73) onconf ::= */ + 220, /* (74) onconf ::= ON CONFLICT resolvetype */ + 236, /* (75) orconf ::= */ + 236, /* (76) orconf ::= OR resolvetype */ + 237, /* (77) resolvetype ::= IGNORE */ + 237, /* (78) resolvetype ::= REPLACE */ + 192, /* (79) cmd ::= DROP TABLE ifexists fullname */ + 239, /* (80) ifexists ::= IF EXISTS */ + 239, /* (81) ifexists ::= */ + 192, /* (82) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ + 192, /* (83) cmd ::= DROP VIEW ifexists fullname */ + 192, /* (84) cmd ::= select */ + 206, /* (85) select ::= WITH wqlist selectnowith */ + 206, /* (86) select ::= WITH RECURSIVE wqlist selectnowith */ + 206, /* (87) select ::= selectnowith */ + 241, /* (88) selectnowith ::= selectnowith multiselect_op oneselect */ + 244, /* (89) multiselect_op ::= UNION */ + 244, /* (90) multiselect_op ::= UNION ALL */ + 244, /* (91) multiselect_op ::= EXCEPT|INTERSECT */ + 242, /* (92) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ + 242, /* (93) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ + 254, /* (94) values ::= VALUES LP nexprlist RP */ + 242, /* (95) oneselect ::= mvalues */ + 256, /* (96) mvalues ::= values COMMA LP nexprlist RP */ + 256, /* (97) mvalues ::= mvalues COMMA LP nexprlist RP */ + 245, /* (98) distinct ::= DISTINCT */ + 245, /* (99) distinct ::= ALL */ + 245, /* (100) distinct ::= */ + 257, /* (101) sclp ::= */ + 246, /* (102) selcollist ::= sclp scanpt expr scanpt as */ + 246, /* (103) selcollist ::= sclp scanpt STAR */ + 246, /* (104) selcollist ::= sclp scanpt nm DOT STAR */ + 258, /* (105) as ::= AS nm */ + 258, /* (106) as ::= */ + 247, /* (107) from ::= */ + 247, /* (108) from ::= FROM seltablist */ + 260, /* (109) stl_prefix ::= seltablist joinop */ + 260, /* (110) stl_prefix ::= */ + 259, /* (111) seltablist ::= stl_prefix nm dbnm as on_using */ + 259, /* (112) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ + 259, /* (113) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ + 259, /* (114) seltablist ::= stl_prefix LP select RP as on_using */ + 259, /* (115) seltablist ::= stl_prefix LP seltablist RP as on_using */ + 202, /* (116) dbnm ::= */ + 202, /* (117) dbnm ::= DOT nm */ + 240, /* (118) fullname ::= nm */ + 240, /* (119) fullname ::= nm DOT nm */ + 265, /* (120) xfullname ::= nm */ + 265, /* (121) xfullname ::= nm DOT nm */ + 265, /* (122) xfullname ::= nm AS nm */ + 265, /* (123) xfullname ::= nm DOT nm AS nm */ + 261, /* (124) joinop ::= COMMA|JOIN */ + 261, /* (125) joinop ::= JOIN_KW JOIN */ + 261, /* (126) joinop ::= JOIN_KW nm JOIN */ + 261, /* (127) joinop ::= JOIN_KW nm nm JOIN */ + 262, /* (128) on_using ::= ON expr */ + 262, /* (129) on_using ::= USING LP idlist RP */ + 262, /* (130) on_using ::= */ + 267, /* (131) indexed_opt ::= */ + 263, /* (132) indexed_by ::= INDEXED BY nm */ + 263, /* (133) indexed_by ::= NOT INDEXED */ + 251, /* (134) orderby_opt ::= */ + 251, /* (135) orderby_opt ::= ORDER BY sortlist */ + 233, /* (136) sortlist ::= sortlist COMMA expr sortorder nulls */ + 233, /* (137) sortlist ::= expr sortorder nulls */ + 221, /* (138) sortorder ::= ASC */ + 221, /* (139) sortorder ::= DESC */ + 221, /* (140) sortorder ::= */ + 268, /* (141) nulls ::= NULLS FIRST */ + 268, /* (142) nulls ::= NULLS LAST */ + 268, /* (143) nulls ::= */ + 249, /* (144) groupby_opt ::= */ + 249, /* (145) groupby_opt ::= GROUP BY nexprlist */ + 250, /* (146) having_opt ::= */ + 250, /* (147) having_opt ::= HAVING expr */ + 252, /* (148) limit_opt ::= */ + 252, /* (149) limit_opt ::= LIMIT expr */ + 252, /* (150) limit_opt ::= LIMIT expr OFFSET expr */ + 252, /* (151) limit_opt ::= LIMIT expr COMMA expr */ + 192, /* (152) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ + 248, /* (153) where_opt ::= */ + 248, /* (154) where_opt ::= WHERE expr */ + 270, /* (155) where_opt_ret ::= */ + 270, /* (156) where_opt_ret ::= WHERE expr */ + 270, /* (157) where_opt_ret ::= RETURNING selcollist */ + 270, /* (158) where_opt_ret ::= WHERE expr RETURNING selcollist */ + 192, /* (159) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ + 271, /* (160) setlist ::= setlist COMMA nm EQ expr */ + 271, /* (161) setlist ::= setlist COMMA LP idlist RP EQ expr */ + 271, /* (162) setlist ::= nm EQ expr */ + 271, /* (163) setlist ::= LP idlist RP EQ expr */ + 192, /* (164) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + 192, /* (165) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ + 274, /* (166) upsert ::= */ + 274, /* (167) upsert ::= RETURNING selcollist */ + 274, /* (168) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ + 274, /* (169) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ + 274, /* (170) upsert ::= ON CONFLICT DO NOTHING returning */ + 274, /* (171) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ + 275, /* (172) returning ::= RETURNING selcollist */ + 272, /* (173) insert_cmd ::= INSERT orconf */ + 272, /* (174) insert_cmd ::= REPLACE */ + 273, /* (175) idlist_opt ::= */ + 273, /* (176) idlist_opt ::= LP idlist RP */ + 266, /* (177) idlist ::= idlist COMMA nm */ + 266, /* (178) idlist ::= nm */ + 219, /* (179) expr ::= LP expr RP */ + 219, /* (180) expr ::= ID|INDEXED|JOIN_KW */ + 219, /* (181) expr ::= nm DOT nm */ + 219, /* (182) expr ::= nm DOT nm DOT nm */ + 218, /* (183) term ::= NULL|FLOAT|BLOB */ + 218, /* (184) term ::= STRING */ + 218, /* (185) term ::= INTEGER */ + 219, /* (186) expr ::= VARIABLE */ + 219, /* (187) expr ::= expr COLLATE ID|STRING */ + 219, /* (188) expr ::= CAST LP expr AS typetoken RP */ + 219, /* (189) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ + 219, /* (190) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */ + 219, /* (191) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ + 219, /* (192) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ + 219, /* (193) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */ + 219, /* (194) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ + 218, /* (195) term ::= CTIME_KW */ + 219, /* (196) expr ::= LP nexprlist COMMA expr RP */ + 219, /* (197) expr ::= expr AND expr */ + 219, /* (198) expr ::= expr OR expr */ + 219, /* (199) expr ::= expr LT|GT|GE|LE expr */ + 219, /* (200) expr ::= expr EQ|NE expr */ + 219, /* (201) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ + 219, /* (202) expr ::= expr PLUS|MINUS expr */ + 219, /* (203) expr ::= expr STAR|SLASH|REM expr */ + 219, /* (204) expr ::= expr CONCAT expr */ + 277, /* (205) likeop ::= NOT LIKE_KW|MATCH */ + 219, /* (206) expr ::= expr likeop expr */ + 219, /* (207) expr ::= expr likeop expr ESCAPE expr */ + 219, /* (208) expr ::= expr ISNULL|NOTNULL */ + 219, /* (209) expr ::= expr NOT NULL */ + 219, /* (210) expr ::= expr IS expr */ + 219, /* (211) expr ::= expr IS NOT expr */ + 219, /* (212) expr ::= expr IS NOT DISTINCT FROM expr */ + 219, /* (213) expr ::= expr IS DISTINCT FROM expr */ + 219, /* (214) expr ::= NOT expr */ + 219, /* (215) expr ::= BITNOT expr */ + 219, /* (216) expr ::= PLUS|MINUS expr */ + 219, /* (217) expr ::= expr PTR expr */ + 278, /* (218) between_op ::= BETWEEN */ + 278, /* (219) between_op ::= NOT BETWEEN */ + 219, /* (220) expr ::= expr between_op expr AND expr */ + 279, /* (221) in_op ::= IN */ + 279, /* (222) in_op ::= NOT IN */ + 219, /* (223) expr ::= expr in_op LP exprlist RP */ + 219, /* (224) expr ::= LP select RP */ + 219, /* (225) expr ::= expr in_op LP select RP */ + 219, /* (226) expr ::= expr in_op nm dbnm paren_exprlist */ + 219, /* (227) expr ::= EXISTS LP select RP */ + 219, /* (228) expr ::= CASE case_operand case_exprlist case_else END */ + 282, /* (229) case_exprlist ::= case_exprlist WHEN expr THEN expr */ + 282, /* (230) case_exprlist ::= WHEN expr THEN expr */ + 283, /* (231) case_else ::= ELSE expr */ + 283, /* (232) case_else ::= */ + 281, /* (233) case_operand ::= */ + 264, /* (234) exprlist ::= */ + 255, /* (235) nexprlist ::= nexprlist COMMA expr */ + 255, /* (236) nexprlist ::= expr */ + 280, /* (237) paren_exprlist ::= */ + 280, /* (238) paren_exprlist ::= LP exprlist RP */ + 192, /* (239) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + 284, /* (240) uniqueflag ::= UNIQUE */ + 284, /* (241) uniqueflag ::= */ + 223, /* (242) eidlist_opt ::= */ + 223, /* (243) eidlist_opt ::= LP eidlist RP */ + 234, /* (244) eidlist ::= eidlist COMMA nm collate sortorder */ + 234, /* (245) eidlist ::= nm collate sortorder */ + 285, /* (246) collate ::= */ + 285, /* (247) collate ::= COLLATE ID|STRING */ + 192, /* (248) cmd ::= DROP INDEX ifexists fullname */ + 192, /* (249) cmd ::= VACUUM vinto */ + 192, /* (250) cmd ::= VACUUM nm vinto */ + 286, /* (251) vinto ::= INTO expr */ + 286, /* (252) vinto ::= */ + 192, /* (253) cmd ::= PRAGMA nm dbnm */ + 192, /* (254) cmd ::= PRAGMA nm dbnm EQ nmnum */ + 192, /* (255) cmd ::= PRAGMA nm dbnm LP nmnum RP */ + 192, /* (256) cmd ::= PRAGMA nm dbnm EQ minus_num */ + 192, /* (257) cmd ::= PRAGMA nm dbnm LP minus_num RP */ + 213, /* (258) plus_num ::= PLUS INTEGER|FLOAT */ + 214, /* (259) minus_num ::= MINUS INTEGER|FLOAT */ + 192, /* (260) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + 288, /* (261) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + 290, /* (262) trigger_time ::= BEFORE|AFTER */ + 290, /* (263) trigger_time ::= INSTEAD OF */ + 290, /* (264) trigger_time ::= */ + 291, /* (265) trigger_event ::= DELETE|INSERT */ + 291, /* (266) trigger_event ::= UPDATE */ + 291, /* (267) trigger_event ::= UPDATE OF idlist */ + 293, /* (268) when_clause ::= */ + 293, /* (269) when_clause ::= WHEN expr */ + 289, /* (270) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + 289, /* (271) trigger_cmd_list ::= trigger_cmd SEMI */ + 295, /* (272) tridxby ::= INDEXED BY nm */ + 295, /* (273) tridxby ::= NOT INDEXED */ + 294, /* (274) trigger_cmd ::= UPDATE orconf xfullname tridxby SET setlist from where_opt scanpt */ + 294, /* (275) trigger_cmd ::= scanpt insert_cmd INTO xfullname idlist_opt select upsert scanpt */ + 294, /* (276) trigger_cmd ::= DELETE FROM xfullname tridxby where_opt scanpt */ + 294, /* (277) trigger_cmd ::= scanpt select scanpt */ + 219, /* (278) expr ::= RAISE LP IGNORE RP */ + 219, /* (279) expr ::= RAISE LP raisetype COMMA expr RP */ + 238, /* (280) raisetype ::= ROLLBACK */ + 238, /* (281) raisetype ::= ABORT */ + 238, /* (282) raisetype ::= FAIL */ + 192, /* (283) cmd ::= DROP TRIGGER ifexists fullname */ + 192, /* (284) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + 192, /* (285) cmd ::= DETACH database_kw_opt expr */ + 297, /* (286) key_opt ::= */ + 297, /* (287) key_opt ::= KEY expr */ + 192, /* (288) cmd ::= REINDEX */ + 192, /* (289) cmd ::= REINDEX nm dbnm */ + 192, /* (290) cmd ::= ANALYZE */ + 192, /* (291) cmd ::= ANALYZE nm dbnm */ + 192, /* (292) cmd ::= ALTER TABLE fullname RENAME TO nm */ + 192, /* (293) cmd ::= alter_add carglist */ + 298, /* (294) alter_add ::= ALTER TABLE fullname ADD kwcolumn_opt nm typetoken */ + 192, /* (295) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + 192, /* (296) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + 192, /* (297) cmd ::= ALTER TABLE fullname DROP CONSTRAINT nm */ + 192, /* (298) cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm DROP NOT NULL */ + 192, /* (299) cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm SET NOT NULL onconf */ + 192, /* (300) cmd ::= ALTER TABLE fullname ADD CONSTRAINT nm CHECK LP expr RP onconf */ + 192, /* (301) cmd ::= ALTER TABLE fullname ADD CHECK LP expr RP onconf */ + 192, /* (302) cmd ::= create_vtab */ + 192, /* (303) cmd ::= create_vtab LP vtabarglist RP */ + 300, /* (304) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 302, /* (305) vtabarg ::= */ + 303, /* (306) vtabargtoken ::= ANY */ + 303, /* (307) vtabargtoken ::= lp anylist RP */ + 304, /* (308) lp ::= LP */ + 269, /* (309) with ::= WITH wqlist */ + 269, /* (310) with ::= WITH RECURSIVE wqlist */ + 307, /* (311) wqas ::= AS */ + 307, /* (312) wqas ::= AS MATERIALIZED */ + 307, /* (313) wqas ::= AS NOT MATERIALIZED */ + 306, /* (314) wqitem ::= withnm eidlist_opt wqas LP select RP */ + 308, /* (315) withnm ::= nm */ + 243, /* (316) wqlist ::= wqitem */ + 243, /* (317) wqlist ::= wqlist COMMA wqitem */ + 309, /* (318) windowdefn_list ::= windowdefn_list COMMA windowdefn */ + 310, /* (319) windowdefn ::= nm AS LP window RP */ + 311, /* (320) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + 311, /* (321) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + 311, /* (322) window ::= ORDER BY sortlist frame_opt */ + 311, /* (323) window ::= nm ORDER BY sortlist frame_opt */ + 311, /* (324) window ::= nm frame_opt */ + 312, /* (325) frame_opt ::= */ + 312, /* (326) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + 312, /* (327) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + 316, /* (328) range_or_rows ::= RANGE|ROWS|GROUPS */ + 318, /* (329) frame_bound_s ::= frame_bound */ + 318, /* (330) frame_bound_s ::= UNBOUNDED PRECEDING */ + 319, /* (331) frame_bound_e ::= frame_bound */ + 319, /* (332) frame_bound_e ::= UNBOUNDED FOLLOWING */ + 317, /* (333) frame_bound ::= expr PRECEDING|FOLLOWING */ + 317, /* (334) frame_bound ::= CURRENT ROW */ + 320, /* (335) frame_exclude_opt ::= */ + 320, /* (336) frame_exclude_opt ::= EXCLUDE frame_exclude */ + 321, /* (337) frame_exclude ::= NO OTHERS */ + 321, /* (338) frame_exclude ::= CURRENT ROW */ + 321, /* (339) frame_exclude ::= GROUP|TIES */ + 253, /* (340) window_clause ::= WINDOW windowdefn_list */ + 276, /* (341) filter_over ::= filter_clause over_clause */ + 276, /* (342) filter_over ::= over_clause */ + 276, /* (343) filter_over ::= filter_clause */ + 315, /* (344) over_clause ::= OVER LP window RP */ + 315, /* (345) over_clause ::= OVER nm */ + 314, /* (346) filter_clause ::= FILTER LP WHERE expr RP */ + 218, /* (347) term ::= QNUMBER */ + 187, /* (348) input ::= cmdlist */ + 188, /* (349) cmdlist ::= cmdlist ecmd */ + 188, /* (350) cmdlist ::= ecmd */ + 189, /* (351) ecmd ::= SEMI */ + 189, /* (352) ecmd ::= cmdx SEMI */ + 189, /* (353) ecmd ::= explain cmdx SEMI */ + 194, /* (354) trans_opt ::= */ + 194, /* (355) trans_opt ::= TRANSACTION */ + 194, /* (356) trans_opt ::= TRANSACTION nm */ + 196, /* (357) savepoint_opt ::= SAVEPOINT */ + 196, /* (358) savepoint_opt ::= */ + 192, /* (359) cmd ::= create_table create_table_args */ + 205, /* (360) table_option_set ::= table_option */ + 203, /* (361) columnlist ::= columnlist COMMA columnname carglist */ + 203, /* (362) columnlist ::= columnname carglist */ + 195, /* (363) nm ::= ID|INDEXED|JOIN_KW */ + 195, /* (364) nm ::= STRING */ + 210, /* (365) typetoken ::= typename */ + 211, /* (366) typename ::= ID|STRING */ + 212, /* (367) signed ::= plus_num */ + 212, /* (368) signed ::= minus_num */ + 209, /* (369) carglist ::= carglist ccons */ + 209, /* (370) carglist ::= */ + 217, /* (371) ccons ::= NULL onconf */ + 217, /* (372) ccons ::= GENERATED ALWAYS AS generated */ + 217, /* (373) ccons ::= AS generated */ + 204, /* (374) conslist_opt ::= COMMA conslist */ + 230, /* (375) conslist ::= conslist tconscomma tcons */ + 230, /* (376) conslist ::= tcons */ + 231, /* (377) tconscomma ::= */ + 235, /* (378) defer_subclause_opt ::= defer_subclause */ + 237, /* (379) resolvetype ::= raisetype */ + 241, /* (380) selectnowith ::= oneselect */ + 242, /* (381) oneselect ::= values */ + 257, /* (382) sclp ::= selcollist COMMA */ + 258, /* (383) as ::= ID|STRING */ + 267, /* (384) indexed_opt ::= indexed_by */ + 275, /* (385) returning ::= */ + 219, /* (386) expr ::= term */ + 277, /* (387) likeop ::= LIKE_KW|MATCH */ + 281, /* (388) case_operand ::= expr */ + 264, /* (389) exprlist ::= nexprlist */ + 287, /* (390) nmnum ::= plus_num */ + 287, /* (391) nmnum ::= nm */ + 287, /* (392) nmnum ::= ON */ + 287, /* (393) nmnum ::= DELETE */ + 287, /* (394) nmnum ::= DEFAULT */ + 213, /* (395) plus_num ::= INTEGER|FLOAT */ + 292, /* (396) foreach_clause ::= */ + 292, /* (397) foreach_clause ::= FOR EACH ROW */ + 295, /* (398) tridxby ::= */ + 296, /* (399) database_kw_opt ::= DATABASE */ + 296, /* (400) database_kw_opt ::= */ + 299, /* (401) kwcolumn_opt ::= */ + 299, /* (402) kwcolumn_opt ::= COLUMNKW */ + 301, /* (403) vtabarglist ::= vtabarg */ + 301, /* (404) vtabarglist ::= vtabarglist COMMA vtabarg */ + 302, /* (405) vtabarg ::= vtabarg vtabargtoken */ + 305, /* (406) anylist ::= */ + 305, /* (407) anylist ::= anylist LP anylist RP */ + 305, /* (408) anylist ::= anylist ANY */ + 269, /* (409) with ::= */ + 309, /* (410) windowdefn_list ::= windowdefn */ + 311, /* (411) window ::= frame_opt */ +}; + +/* For rule J, yyRuleInfoNRhs[J] contains the negative of the number +** of symbols on the right-hand side of that rule. */ +static const signed char yyRuleInfoNRhs[] = { + -1, /* (0) explain ::= EXPLAIN */ + -3, /* (1) explain ::= EXPLAIN QUERY PLAN */ + -1, /* (2) cmdx ::= cmd */ + -3, /* (3) cmd ::= BEGIN transtype trans_opt */ + 0, /* (4) transtype ::= */ + -1, /* (5) transtype ::= DEFERRED */ + -1, /* (6) transtype ::= IMMEDIATE */ + -1, /* (7) transtype ::= EXCLUSIVE */ + -2, /* (8) cmd ::= COMMIT|END trans_opt */ + -2, /* (9) cmd ::= ROLLBACK trans_opt */ + -2, /* (10) cmd ::= SAVEPOINT nm */ + -3, /* (11) cmd ::= RELEASE savepoint_opt nm */ + -5, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ + -6, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */ + -1, /* (14) createkw ::= CREATE */ + 0, /* (15) ifnotexists ::= */ + -3, /* (16) ifnotexists ::= IF NOT EXISTS */ + -1, /* (17) temp ::= TEMP */ + 0, /* (18) temp ::= */ + -5, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_option_set */ + -2, /* (20) create_table_args ::= AS select */ + 0, /* (21) table_option_set ::= */ + -3, /* (22) table_option_set ::= table_option_set COMMA table_option */ + -2, /* (23) table_option ::= WITHOUT nm */ + -1, /* (24) table_option ::= nm */ + -2, /* (25) columnname ::= nm typetoken */ + 0, /* (26) typetoken ::= */ + -4, /* (27) typetoken ::= typename LP signed RP */ + -6, /* (28) typetoken ::= typename LP signed COMMA signed RP */ + -2, /* (29) typename ::= typename ID|STRING */ + 0, /* (30) scanpt ::= */ + 0, /* (31) scantok ::= */ + -2, /* (32) ccons ::= CONSTRAINT nm */ + -3, /* (33) ccons ::= DEFAULT scantok term */ + -4, /* (34) ccons ::= DEFAULT LP expr RP */ + -4, /* (35) ccons ::= DEFAULT PLUS scantok term */ + -4, /* (36) ccons ::= DEFAULT MINUS scantok term */ + -3, /* (37) ccons ::= DEFAULT scantok ID|INDEXED */ + -3, /* (38) ccons ::= NOT NULL onconf */ + -5, /* (39) ccons ::= PRIMARY KEY sortorder onconf autoinc */ + -2, /* (40) ccons ::= UNIQUE onconf */ + -4, /* (41) ccons ::= CHECK LP expr RP */ + -4, /* (42) ccons ::= REFERENCES nm eidlist_opt refargs */ + -1, /* (43) ccons ::= defer_subclause */ + -2, /* (44) ccons ::= COLLATE ID|STRING */ + -3, /* (45) generated ::= LP expr RP */ + -4, /* (46) generated ::= LP expr RP ID */ + 0, /* (47) autoinc ::= */ + -1, /* (48) autoinc ::= AUTOINCR */ + 0, /* (49) refargs ::= */ + -2, /* (50) refargs ::= refargs refarg */ + -2, /* (51) refarg ::= MATCH nm */ + -3, /* (52) refarg ::= ON INSERT refact */ + -3, /* (53) refarg ::= ON DELETE refact */ + -3, /* (54) refarg ::= ON UPDATE refact */ + -2, /* (55) refact ::= SET NULL */ + -2, /* (56) refact ::= SET DEFAULT */ + -1, /* (57) refact ::= CASCADE */ + -1, /* (58) refact ::= RESTRICT */ + -2, /* (59) refact ::= NO ACTION */ + -3, /* (60) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ + -2, /* (61) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ + 0, /* (62) init_deferred_pred_opt ::= */ + -2, /* (63) init_deferred_pred_opt ::= INITIALLY DEFERRED */ + -2, /* (64) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ + 0, /* (65) conslist_opt ::= */ + -1, /* (66) tconscomma ::= COMMA */ + -2, /* (67) tcons ::= CONSTRAINT nm */ + -7, /* (68) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ + -5, /* (69) tcons ::= UNIQUE LP sortlist RP onconf */ + -5, /* (70) tcons ::= CHECK LP expr RP onconf */ + -10, /* (71) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ + 0, /* (72) defer_subclause_opt ::= */ + 0, /* (73) onconf ::= */ + -3, /* (74) onconf ::= ON CONFLICT resolvetype */ + 0, /* (75) orconf ::= */ + -2, /* (76) orconf ::= OR resolvetype */ + -1, /* (77) resolvetype ::= IGNORE */ + -1, /* (78) resolvetype ::= REPLACE */ + -4, /* (79) cmd ::= DROP TABLE ifexists fullname */ + -2, /* (80) ifexists ::= IF EXISTS */ + 0, /* (81) ifexists ::= */ + -9, /* (82) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ + -4, /* (83) cmd ::= DROP VIEW ifexists fullname */ + -1, /* (84) cmd ::= select */ + -3, /* (85) select ::= WITH wqlist selectnowith */ + -4, /* (86) select ::= WITH RECURSIVE wqlist selectnowith */ + -1, /* (87) select ::= selectnowith */ + -3, /* (88) selectnowith ::= selectnowith multiselect_op oneselect */ + -1, /* (89) multiselect_op ::= UNION */ + -2, /* (90) multiselect_op ::= UNION ALL */ + -1, /* (91) multiselect_op ::= EXCEPT|INTERSECT */ + -9, /* (92) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ + -10, /* (93) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ + -4, /* (94) values ::= VALUES LP nexprlist RP */ + -1, /* (95) oneselect ::= mvalues */ + -5, /* (96) mvalues ::= values COMMA LP nexprlist RP */ + -5, /* (97) mvalues ::= mvalues COMMA LP nexprlist RP */ + -1, /* (98) distinct ::= DISTINCT */ + -1, /* (99) distinct ::= ALL */ + 0, /* (100) distinct ::= */ + 0, /* (101) sclp ::= */ + -5, /* (102) selcollist ::= sclp scanpt expr scanpt as */ + -3, /* (103) selcollist ::= sclp scanpt STAR */ + -5, /* (104) selcollist ::= sclp scanpt nm DOT STAR */ + -2, /* (105) as ::= AS nm */ + 0, /* (106) as ::= */ + 0, /* (107) from ::= */ + -2, /* (108) from ::= FROM seltablist */ + -2, /* (109) stl_prefix ::= seltablist joinop */ + 0, /* (110) stl_prefix ::= */ + -5, /* (111) seltablist ::= stl_prefix nm dbnm as on_using */ + -6, /* (112) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ + -8, /* (113) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ + -6, /* (114) seltablist ::= stl_prefix LP select RP as on_using */ + -6, /* (115) seltablist ::= stl_prefix LP seltablist RP as on_using */ + 0, /* (116) dbnm ::= */ + -2, /* (117) dbnm ::= DOT nm */ + -1, /* (118) fullname ::= nm */ + -3, /* (119) fullname ::= nm DOT nm */ + -1, /* (120) xfullname ::= nm */ + -3, /* (121) xfullname ::= nm DOT nm */ + -3, /* (122) xfullname ::= nm AS nm */ + -5, /* (123) xfullname ::= nm DOT nm AS nm */ + -1, /* (124) joinop ::= COMMA|JOIN */ + -2, /* (125) joinop ::= JOIN_KW JOIN */ + -3, /* (126) joinop ::= JOIN_KW nm JOIN */ + -4, /* (127) joinop ::= JOIN_KW nm nm JOIN */ + -2, /* (128) on_using ::= ON expr */ + -4, /* (129) on_using ::= USING LP idlist RP */ + 0, /* (130) on_using ::= */ + 0, /* (131) indexed_opt ::= */ + -3, /* (132) indexed_by ::= INDEXED BY nm */ + -2, /* (133) indexed_by ::= NOT INDEXED */ + 0, /* (134) orderby_opt ::= */ + -3, /* (135) orderby_opt ::= ORDER BY sortlist */ + -5, /* (136) sortlist ::= sortlist COMMA expr sortorder nulls */ + -3, /* (137) sortlist ::= expr sortorder nulls */ + -1, /* (138) sortorder ::= ASC */ + -1, /* (139) sortorder ::= DESC */ + 0, /* (140) sortorder ::= */ + -2, /* (141) nulls ::= NULLS FIRST */ + -2, /* (142) nulls ::= NULLS LAST */ + 0, /* (143) nulls ::= */ + 0, /* (144) groupby_opt ::= */ + -3, /* (145) groupby_opt ::= GROUP BY nexprlist */ + 0, /* (146) having_opt ::= */ + -2, /* (147) having_opt ::= HAVING expr */ + 0, /* (148) limit_opt ::= */ + -2, /* (149) limit_opt ::= LIMIT expr */ + -4, /* (150) limit_opt ::= LIMIT expr OFFSET expr */ + -4, /* (151) limit_opt ::= LIMIT expr COMMA expr */ + -6, /* (152) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ + 0, /* (153) where_opt ::= */ + -2, /* (154) where_opt ::= WHERE expr */ + 0, /* (155) where_opt_ret ::= */ + -2, /* (156) where_opt_ret ::= WHERE expr */ + -2, /* (157) where_opt_ret ::= RETURNING selcollist */ + -4, /* (158) where_opt_ret ::= WHERE expr RETURNING selcollist */ + -9, /* (159) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ + -5, /* (160) setlist ::= setlist COMMA nm EQ expr */ + -7, /* (161) setlist ::= setlist COMMA LP idlist RP EQ expr */ + -3, /* (162) setlist ::= nm EQ expr */ + -5, /* (163) setlist ::= LP idlist RP EQ expr */ + -7, /* (164) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + -8, /* (165) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ + 0, /* (166) upsert ::= */ + -2, /* (167) upsert ::= RETURNING selcollist */ + -12, /* (168) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ + -9, /* (169) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ + -5, /* (170) upsert ::= ON CONFLICT DO NOTHING returning */ + -8, /* (171) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ + -2, /* (172) returning ::= RETURNING selcollist */ + -2, /* (173) insert_cmd ::= INSERT orconf */ + -1, /* (174) insert_cmd ::= REPLACE */ + 0, /* (175) idlist_opt ::= */ + -3, /* (176) idlist_opt ::= LP idlist RP */ + -3, /* (177) idlist ::= idlist COMMA nm */ + -1, /* (178) idlist ::= nm */ + -3, /* (179) expr ::= LP expr RP */ + -1, /* (180) expr ::= ID|INDEXED|JOIN_KW */ + -3, /* (181) expr ::= nm DOT nm */ + -5, /* (182) expr ::= nm DOT nm DOT nm */ + -1, /* (183) term ::= NULL|FLOAT|BLOB */ + -1, /* (184) term ::= STRING */ + -1, /* (185) term ::= INTEGER */ + -1, /* (186) expr ::= VARIABLE */ + -3, /* (187) expr ::= expr COLLATE ID|STRING */ + -6, /* (188) expr ::= CAST LP expr AS typetoken RP */ + -5, /* (189) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ + -8, /* (190) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */ + -4, /* (191) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ + -6, /* (192) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ + -9, /* (193) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */ + -5, /* (194) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ + -1, /* (195) term ::= CTIME_KW */ + -5, /* (196) expr ::= LP nexprlist COMMA expr RP */ + -3, /* (197) expr ::= expr AND expr */ + -3, /* (198) expr ::= expr OR expr */ + -3, /* (199) expr ::= expr LT|GT|GE|LE expr */ + -3, /* (200) expr ::= expr EQ|NE expr */ + -3, /* (201) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ + -3, /* (202) expr ::= expr PLUS|MINUS expr */ + -3, /* (203) expr ::= expr STAR|SLASH|REM expr */ + -3, /* (204) expr ::= expr CONCAT expr */ + -2, /* (205) likeop ::= NOT LIKE_KW|MATCH */ + -3, /* (206) expr ::= expr likeop expr */ + -5, /* (207) expr ::= expr likeop expr ESCAPE expr */ + -2, /* (208) expr ::= expr ISNULL|NOTNULL */ + -3, /* (209) expr ::= expr NOT NULL */ + -3, /* (210) expr ::= expr IS expr */ + -4, /* (211) expr ::= expr IS NOT expr */ + -6, /* (212) expr ::= expr IS NOT DISTINCT FROM expr */ + -5, /* (213) expr ::= expr IS DISTINCT FROM expr */ + -2, /* (214) expr ::= NOT expr */ + -2, /* (215) expr ::= BITNOT expr */ + -2, /* (216) expr ::= PLUS|MINUS expr */ + -3, /* (217) expr ::= expr PTR expr */ + -1, /* (218) between_op ::= BETWEEN */ + -2, /* (219) between_op ::= NOT BETWEEN */ + -5, /* (220) expr ::= expr between_op expr AND expr */ + -1, /* (221) in_op ::= IN */ + -2, /* (222) in_op ::= NOT IN */ + -5, /* (223) expr ::= expr in_op LP exprlist RP */ + -3, /* (224) expr ::= LP select RP */ + -5, /* (225) expr ::= expr in_op LP select RP */ + -5, /* (226) expr ::= expr in_op nm dbnm paren_exprlist */ + -4, /* (227) expr ::= EXISTS LP select RP */ + -5, /* (228) expr ::= CASE case_operand case_exprlist case_else END */ + -5, /* (229) case_exprlist ::= case_exprlist WHEN expr THEN expr */ + -4, /* (230) case_exprlist ::= WHEN expr THEN expr */ + -2, /* (231) case_else ::= ELSE expr */ + 0, /* (232) case_else ::= */ + 0, /* (233) case_operand ::= */ + 0, /* (234) exprlist ::= */ + -3, /* (235) nexprlist ::= nexprlist COMMA expr */ + -1, /* (236) nexprlist ::= expr */ + 0, /* (237) paren_exprlist ::= */ + -3, /* (238) paren_exprlist ::= LP exprlist RP */ + -12, /* (239) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + -1, /* (240) uniqueflag ::= UNIQUE */ + 0, /* (241) uniqueflag ::= */ + 0, /* (242) eidlist_opt ::= */ + -3, /* (243) eidlist_opt ::= LP eidlist RP */ + -5, /* (244) eidlist ::= eidlist COMMA nm collate sortorder */ + -3, /* (245) eidlist ::= nm collate sortorder */ + 0, /* (246) collate ::= */ + -2, /* (247) collate ::= COLLATE ID|STRING */ + -4, /* (248) cmd ::= DROP INDEX ifexists fullname */ + -2, /* (249) cmd ::= VACUUM vinto */ + -3, /* (250) cmd ::= VACUUM nm vinto */ + -2, /* (251) vinto ::= INTO expr */ + 0, /* (252) vinto ::= */ + -3, /* (253) cmd ::= PRAGMA nm dbnm */ + -5, /* (254) cmd ::= PRAGMA nm dbnm EQ nmnum */ + -6, /* (255) cmd ::= PRAGMA nm dbnm LP nmnum RP */ + -5, /* (256) cmd ::= PRAGMA nm dbnm EQ minus_num */ + -6, /* (257) cmd ::= PRAGMA nm dbnm LP minus_num RP */ + -2, /* (258) plus_num ::= PLUS INTEGER|FLOAT */ + -2, /* (259) minus_num ::= MINUS INTEGER|FLOAT */ + -5, /* (260) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + -11, /* (261) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + -1, /* (262) trigger_time ::= BEFORE|AFTER */ + -2, /* (263) trigger_time ::= INSTEAD OF */ + 0, /* (264) trigger_time ::= */ + -1, /* (265) trigger_event ::= DELETE|INSERT */ + -1, /* (266) trigger_event ::= UPDATE */ + -3, /* (267) trigger_event ::= UPDATE OF idlist */ + 0, /* (268) when_clause ::= */ + -2, /* (269) when_clause ::= WHEN expr */ + -3, /* (270) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + -2, /* (271) trigger_cmd_list ::= trigger_cmd SEMI */ + -3, /* (272) tridxby ::= INDEXED BY nm */ + -2, /* (273) tridxby ::= NOT INDEXED */ + -9, /* (274) trigger_cmd ::= UPDATE orconf xfullname tridxby SET setlist from where_opt scanpt */ + -8, /* (275) trigger_cmd ::= scanpt insert_cmd INTO xfullname idlist_opt select upsert scanpt */ + -6, /* (276) trigger_cmd ::= DELETE FROM xfullname tridxby where_opt scanpt */ + -3, /* (277) trigger_cmd ::= scanpt select scanpt */ + -4, /* (278) expr ::= RAISE LP IGNORE RP */ + -6, /* (279) expr ::= RAISE LP raisetype COMMA expr RP */ + -1, /* (280) raisetype ::= ROLLBACK */ + -1, /* (281) raisetype ::= ABORT */ + -1, /* (282) raisetype ::= FAIL */ + -4, /* (283) cmd ::= DROP TRIGGER ifexists fullname */ + -6, /* (284) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + -3, /* (285) cmd ::= DETACH database_kw_opt expr */ + 0, /* (286) key_opt ::= */ + -2, /* (287) key_opt ::= KEY expr */ + -1, /* (288) cmd ::= REINDEX */ + -3, /* (289) cmd ::= REINDEX nm dbnm */ + -1, /* (290) cmd ::= ANALYZE */ + -3, /* (291) cmd ::= ANALYZE nm dbnm */ + -6, /* (292) cmd ::= ALTER TABLE fullname RENAME TO nm */ + -2, /* (293) cmd ::= alter_add carglist */ + -7, /* (294) alter_add ::= ALTER TABLE fullname ADD kwcolumn_opt nm typetoken */ + -6, /* (295) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + -8, /* (296) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + -6, /* (297) cmd ::= ALTER TABLE fullname DROP CONSTRAINT nm */ + -9, /* (298) cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm DROP NOT NULL */ + -10, /* (299) cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm SET NOT NULL onconf */ + -11, /* (300) cmd ::= ALTER TABLE fullname ADD CONSTRAINT nm CHECK LP expr RP onconf */ + -9, /* (301) cmd ::= ALTER TABLE fullname ADD CHECK LP expr RP onconf */ + -1, /* (302) cmd ::= create_vtab */ + -4, /* (303) cmd ::= create_vtab LP vtabarglist RP */ + -8, /* (304) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 0, /* (305) vtabarg ::= */ + -1, /* (306) vtabargtoken ::= ANY */ + -3, /* (307) vtabargtoken ::= lp anylist RP */ + -1, /* (308) lp ::= LP */ + -2, /* (309) with ::= WITH wqlist */ + -3, /* (310) with ::= WITH RECURSIVE wqlist */ + -1, /* (311) wqas ::= AS */ + -2, /* (312) wqas ::= AS MATERIALIZED */ + -3, /* (313) wqas ::= AS NOT MATERIALIZED */ + -6, /* (314) wqitem ::= withnm eidlist_opt wqas LP select RP */ + -1, /* (315) withnm ::= nm */ + -1, /* (316) wqlist ::= wqitem */ + -3, /* (317) wqlist ::= wqlist COMMA wqitem */ + -3, /* (318) windowdefn_list ::= windowdefn_list COMMA windowdefn */ + -5, /* (319) windowdefn ::= nm AS LP window RP */ + -5, /* (320) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + -6, /* (321) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + -4, /* (322) window ::= ORDER BY sortlist frame_opt */ + -5, /* (323) window ::= nm ORDER BY sortlist frame_opt */ + -2, /* (324) window ::= nm frame_opt */ + 0, /* (325) frame_opt ::= */ + -3, /* (326) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + -6, /* (327) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + -1, /* (328) range_or_rows ::= RANGE|ROWS|GROUPS */ + -1, /* (329) frame_bound_s ::= frame_bound */ + -2, /* (330) frame_bound_s ::= UNBOUNDED PRECEDING */ + -1, /* (331) frame_bound_e ::= frame_bound */ + -2, /* (332) frame_bound_e ::= UNBOUNDED FOLLOWING */ + -2, /* (333) frame_bound ::= expr PRECEDING|FOLLOWING */ + -2, /* (334) frame_bound ::= CURRENT ROW */ + 0, /* (335) frame_exclude_opt ::= */ + -2, /* (336) frame_exclude_opt ::= EXCLUDE frame_exclude */ + -2, /* (337) frame_exclude ::= NO OTHERS */ + -2, /* (338) frame_exclude ::= CURRENT ROW */ + -1, /* (339) frame_exclude ::= GROUP|TIES */ + -2, /* (340) window_clause ::= WINDOW windowdefn_list */ + -2, /* (341) filter_over ::= filter_clause over_clause */ + -1, /* (342) filter_over ::= over_clause */ + -1, /* (343) filter_over ::= filter_clause */ + -4, /* (344) over_clause ::= OVER LP window RP */ + -2, /* (345) over_clause ::= OVER nm */ + -5, /* (346) filter_clause ::= FILTER LP WHERE expr RP */ + -1, /* (347) term ::= QNUMBER */ + -1, /* (348) input ::= cmdlist */ + -2, /* (349) cmdlist ::= cmdlist ecmd */ + -1, /* (350) cmdlist ::= ecmd */ + -1, /* (351) ecmd ::= SEMI */ + -2, /* (352) ecmd ::= cmdx SEMI */ + -3, /* (353) ecmd ::= explain cmdx SEMI */ + 0, /* (354) trans_opt ::= */ + -1, /* (355) trans_opt ::= TRANSACTION */ + -2, /* (356) trans_opt ::= TRANSACTION nm */ + -1, /* (357) savepoint_opt ::= SAVEPOINT */ + 0, /* (358) savepoint_opt ::= */ + -2, /* (359) cmd ::= create_table create_table_args */ + -1, /* (360) table_option_set ::= table_option */ + -4, /* (361) columnlist ::= columnlist COMMA columnname carglist */ + -2, /* (362) columnlist ::= columnname carglist */ + -1, /* (363) nm ::= ID|INDEXED|JOIN_KW */ + -1, /* (364) nm ::= STRING */ + -1, /* (365) typetoken ::= typename */ + -1, /* (366) typename ::= ID|STRING */ + -1, /* (367) signed ::= plus_num */ + -1, /* (368) signed ::= minus_num */ + -2, /* (369) carglist ::= carglist ccons */ + 0, /* (370) carglist ::= */ + -2, /* (371) ccons ::= NULL onconf */ + -4, /* (372) ccons ::= GENERATED ALWAYS AS generated */ + -2, /* (373) ccons ::= AS generated */ + -2, /* (374) conslist_opt ::= COMMA conslist */ + -3, /* (375) conslist ::= conslist tconscomma tcons */ + -1, /* (376) conslist ::= tcons */ + 0, /* (377) tconscomma ::= */ + -1, /* (378) defer_subclause_opt ::= defer_subclause */ + -1, /* (379) resolvetype ::= raisetype */ + -1, /* (380) selectnowith ::= oneselect */ + -1, /* (381) oneselect ::= values */ + -2, /* (382) sclp ::= selcollist COMMA */ + -1, /* (383) as ::= ID|STRING */ + -1, /* (384) indexed_opt ::= indexed_by */ + 0, /* (385) returning ::= */ + -1, /* (386) expr ::= term */ + -1, /* (387) likeop ::= LIKE_KW|MATCH */ + -1, /* (388) case_operand ::= expr */ + -1, /* (389) exprlist ::= nexprlist */ + -1, /* (390) nmnum ::= plus_num */ + -1, /* (391) nmnum ::= nm */ + -1, /* (392) nmnum ::= ON */ + -1, /* (393) nmnum ::= DELETE */ + -1, /* (394) nmnum ::= DEFAULT */ + -1, /* (395) plus_num ::= INTEGER|FLOAT */ + 0, /* (396) foreach_clause ::= */ + -3, /* (397) foreach_clause ::= FOR EACH ROW */ + 0, /* (398) tridxby ::= */ + -1, /* (399) database_kw_opt ::= DATABASE */ + 0, /* (400) database_kw_opt ::= */ + 0, /* (401) kwcolumn_opt ::= */ + -1, /* (402) kwcolumn_opt ::= COLUMNKW */ + -1, /* (403) vtabarglist ::= vtabarg */ + -3, /* (404) vtabarglist ::= vtabarglist COMMA vtabarg */ + -2, /* (405) vtabarg ::= vtabarg vtabargtoken */ + 0, /* (406) anylist ::= */ + -4, /* (407) anylist ::= anylist LP anylist RP */ + -2, /* (408) anylist ::= anylist ANY */ + 0, /* (409) with ::= */ + -1, /* (410) windowdefn_list ::= windowdefn */ + -1, /* (411) window ::= frame_opt */ +}; + +static void yy_accept(yyParser*); /* Forward Declaration */ + +/* +** Perform a reduce action and the shift that must immediately +** follow the reduce. +** +** The yyLookahead and yyLookaheadToken parameters provide reduce actions +** access to the lookahead token (if any). The yyLookahead will be YYNOCODE +** if the lookahead token has already been consumed. As this procedure is +** only called from one place, optimizing compilers will in-line it, which +** means that the extra parameters have no performance impact. +*/ +static YYACTIONTYPE yy_reduce( + yyParser *yypParser, /* The parser */ + unsigned int yyruleno, /* Number of the rule by which to reduce */ + int yyLookahead, /* Lookahead token, or YYNOCODE if none */ + sqlite3ParserTOKENTYPE yyLookaheadToken /* Value of the lookahead token */ + sqlite3ParserCTX_PDECL /* %extra_context */ +){ + int yygoto; /* The next state */ + YYACTIONTYPE yyact; /* The next action */ + yyStackEntry *yymsp; /* The top of the parser's stack */ + int yysize; /* Amount to pop the stack */ + sqlite3ParserARG_FETCH + (void)yyLookahead; + (void)yyLookaheadToken; + yymsp = yypParser->yytos; + + switch( yyruleno ){ + /* Beginning here are the reduction cases. A typical example + ** follows: + ** case 0: + ** #line + ** { ... } // User supplied code + ** #line + ** break; + */ +/********** Begin reduce actions **********************************************/ + YYMINORTYPE yylhsminor; + case 0: /* explain ::= EXPLAIN */ +{ if( pParse->pReprepare==0 ) pParse->explain = 1; } + break; + case 1: /* explain ::= EXPLAIN QUERY PLAN */ +{ if( pParse->pReprepare==0 ) pParse->explain = 2; } + break; + case 2: /* cmdx ::= cmd */ +{ sqlite3FinishCoding(pParse); } + break; + case 3: /* cmd ::= BEGIN transtype trans_opt */ +{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy144);} + break; + case 4: /* transtype ::= */ +{yymsp[1].minor.yy144 = TK_DEFERRED;} + break; + case 5: /* transtype ::= DEFERRED */ + case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6); + case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7); + case 328: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==328); +{yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-X*/} + break; + case 8: /* cmd ::= COMMIT|END trans_opt */ + case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9); +{sqlite3EndTransaction(pParse,yymsp[-1].major);} + break; + case 10: /* cmd ::= SAVEPOINT nm */ +{ + sqlite3Savepoint(pParse, SAVEPOINT_BEGIN, &yymsp[0].minor.yy0); +} + break; + case 11: /* cmd ::= RELEASE savepoint_opt nm */ +{ + sqlite3Savepoint(pParse, SAVEPOINT_RELEASE, &yymsp[0].minor.yy0); +} + break; + case 12: /* cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ +{ + sqlite3Savepoint(pParse, SAVEPOINT_ROLLBACK, &yymsp[0].minor.yy0); +} + break; + case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */ +{ + sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy144,0,0,yymsp[-2].minor.yy144); +} + break; + case 14: /* createkw ::= CREATE */ +{ + disableLookaside(pParse); +} + break; + case 15: /* ifnotexists ::= */ + case 18: /* temp ::= */ yytestcase(yyruleno==18); + case 47: /* autoinc ::= */ yytestcase(yyruleno==47); + case 62: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==62); + case 72: /* defer_subclause_opt ::= */ yytestcase(yyruleno==72); + case 81: /* ifexists ::= */ yytestcase(yyruleno==81); + case 100: /* distinct ::= */ yytestcase(yyruleno==100); + case 246: /* collate ::= */ yytestcase(yyruleno==246); +{yymsp[1].minor.yy144 = 0;} + break; + case 16: /* ifnotexists ::= IF NOT EXISTS */ +{yymsp[-2].minor.yy144 = 1;} + break; + case 17: /* temp ::= TEMP */ +{yymsp[0].minor.yy144 = pParse->db->init.busy==0;} + break; + case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_option_set */ +{ + sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy391,0); +} + break; + case 20: /* create_table_args ::= AS select */ +{ + sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy555); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy555); +} + break; + case 21: /* table_option_set ::= */ +{yymsp[1].minor.yy391 = 0;} + break; + case 22: /* table_option_set ::= table_option_set COMMA table_option */ +{yylhsminor.yy391 = yymsp[-2].minor.yy391|yymsp[0].minor.yy391;} + yymsp[-2].minor.yy391 = yylhsminor.yy391; + break; + case 23: /* table_option ::= WITHOUT nm */ +{ + if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){ + yymsp[-1].minor.yy391 = TF_WithoutRowid | TF_NoVisibleRowid; + }else{ + yymsp[-1].minor.yy391 = 0; + sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); + } +} + break; + case 24: /* table_option ::= nm */ +{ + if( yymsp[0].minor.yy0.n==6 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"strict",6)==0 ){ + yylhsminor.yy391 = TF_Strict; + }else{ + yylhsminor.yy391 = 0; + sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); + } +} + yymsp[0].minor.yy391 = yylhsminor.yy391; + break; + case 25: /* columnname ::= nm typetoken */ +{sqlite3AddColumn(pParse,yymsp[-1].minor.yy0,yymsp[0].minor.yy0);} + break; + case 26: /* typetoken ::= */ + case 65: /* conslist_opt ::= */ yytestcase(yyruleno==65); + case 106: /* as ::= */ yytestcase(yyruleno==106); +{yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = 0;} + break; + case 27: /* typetoken ::= typename LP signed RP */ +{ + yymsp[-3].minor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z); +} + break; + case 28: /* typetoken ::= typename LP signed COMMA signed RP */ +{ + yymsp[-5].minor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z); +} + break; + case 29: /* typename ::= typename ID|STRING */ +{yymsp[-1].minor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);} + break; + case 30: /* scanpt ::= */ +{ + assert( yyLookahead!=YYNOCODE ); + yymsp[1].minor.yy168 = yyLookaheadToken.z; +} + break; + case 31: /* scantok ::= */ +{ + assert( yyLookahead!=YYNOCODE ); + yymsp[1].minor.yy0 = yyLookaheadToken; +} + break; + case 32: /* ccons ::= CONSTRAINT nm */ + case 67: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==67); +{ASSERT_IS_CREATE; pParse->u1.cr.constraintName = yymsp[0].minor.yy0;} + break; + case 33: /* ccons ::= DEFAULT scantok term */ +{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy454,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} + break; + case 34: /* ccons ::= DEFAULT LP expr RP */ +{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy454,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);} + break; + case 35: /* ccons ::= DEFAULT PLUS scantok term */ +{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy454,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} + break; + case 36: /* ccons ::= DEFAULT MINUS scantok term */ +{ + Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy454, 0); + sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]); +} + break; + case 37: /* ccons ::= DEFAULT scantok ID|INDEXED */ +{ + Expr *p = tokenExpr(pParse, TK_STRING, yymsp[0].minor.yy0); + if( p ){ + sqlite3ExprIdToTrueFalse(p); + testcase( p->op==TK_TRUEFALSE && sqlite3ExprTruthValue(p) ); + } + sqlite3AddDefaultValue(pParse,p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.z+yymsp[0].minor.yy0.n); +} + break; + case 38: /* ccons ::= NOT NULL onconf */ +{sqlite3AddNotNull(pParse, yymsp[0].minor.yy144);} + break; + case 39: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */ +{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy144,yymsp[0].minor.yy144,yymsp[-2].minor.yy144);} + break; + case 40: /* ccons ::= UNIQUE onconf */ +{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy144,0,0,0,0, + SQLITE_IDXTYPE_UNIQUE);} + break; + case 41: /* ccons ::= CHECK LP expr RP */ +{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy454,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);} + break; + case 42: /* ccons ::= REFERENCES nm eidlist_opt refargs */ +{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy14,yymsp[0].minor.yy144);} + break; + case 43: /* ccons ::= defer_subclause */ +{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy144);} + break; + case 44: /* ccons ::= COLLATE ID|STRING */ +{sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);} + break; + case 45: /* generated ::= LP expr RP */ +{sqlite3AddGenerated(pParse,yymsp[-1].minor.yy454,0);} + break; + case 46: /* generated ::= LP expr RP ID */ +{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy454,&yymsp[0].minor.yy0);} + break; + case 48: /* autoinc ::= AUTOINCR */ +{yymsp[0].minor.yy144 = 1;} + break; + case 49: /* refargs ::= */ +{ yymsp[1].minor.yy144 = OE_None*0x0101; /* EV: R-19803-45884 */} + break; + case 50: /* refargs ::= refargs refarg */ +{ yymsp[-1].minor.yy144 = (yymsp[-1].minor.yy144 & ~yymsp[0].minor.yy383.mask) | yymsp[0].minor.yy383.value; } + break; + case 51: /* refarg ::= MATCH nm */ +{ yymsp[-1].minor.yy383.value = 0; yymsp[-1].minor.yy383.mask = 0x000000; } + break; + case 52: /* refarg ::= ON INSERT refact */ +{ yymsp[-2].minor.yy383.value = 0; yymsp[-2].minor.yy383.mask = 0x000000; } + break; + case 53: /* refarg ::= ON DELETE refact */ +{ yymsp[-2].minor.yy383.value = yymsp[0].minor.yy144; yymsp[-2].minor.yy383.mask = 0x0000ff; } + break; + case 54: /* refarg ::= ON UPDATE refact */ +{ yymsp[-2].minor.yy383.value = yymsp[0].minor.yy144<<8; yymsp[-2].minor.yy383.mask = 0x00ff00; } + break; + case 55: /* refact ::= SET NULL */ +{ yymsp[-1].minor.yy144 = OE_SetNull; /* EV: R-33326-45252 */} + break; + case 56: /* refact ::= SET DEFAULT */ +{ yymsp[-1].minor.yy144 = OE_SetDflt; /* EV: R-33326-45252 */} + break; + case 57: /* refact ::= CASCADE */ +{ yymsp[0].minor.yy144 = OE_Cascade; /* EV: R-33326-45252 */} + break; + case 58: /* refact ::= RESTRICT */ +{ yymsp[0].minor.yy144 = OE_Restrict; /* EV: R-33326-45252 */} + break; + case 59: /* refact ::= NO ACTION */ +{ yymsp[-1].minor.yy144 = OE_None; /* EV: R-33326-45252 */} + break; + case 60: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ +{yymsp[-2].minor.yy144 = 0;} + break; + case 61: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ + case 76: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==76); + case 173: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==173); +{yymsp[-1].minor.yy144 = yymsp[0].minor.yy144;} + break; + case 63: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ + case 80: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==80); + case 219: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==219); + case 222: /* in_op ::= NOT IN */ yytestcase(yyruleno==222); + case 247: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==247); +{yymsp[-1].minor.yy144 = 1;} + break; + case 64: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ +{yymsp[-1].minor.yy144 = 0;} + break; + case 66: /* tconscomma ::= COMMA */ +{ASSERT_IS_CREATE; pParse->u1.cr.constraintName.n = 0;} + break; + case 68: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ +{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy14,yymsp[0].minor.yy144,yymsp[-2].minor.yy144,0);} + break; + case 69: /* tcons ::= UNIQUE LP sortlist RP onconf */ +{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy14,yymsp[0].minor.yy144,0,0,0,0, + SQLITE_IDXTYPE_UNIQUE);} + break; + case 70: /* tcons ::= CHECK LP expr RP onconf */ +{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy454,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);} + break; + case 71: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ +{ + sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy14, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy14, yymsp[-1].minor.yy144); + sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy144); +} + break; + case 73: /* onconf ::= */ + case 75: /* orconf ::= */ yytestcase(yyruleno==75); +{yymsp[1].minor.yy144 = OE_Default;} + break; + case 74: /* onconf ::= ON CONFLICT resolvetype */ +{yymsp[-2].minor.yy144 = yymsp[0].minor.yy144;} + break; + case 77: /* resolvetype ::= IGNORE */ +{yymsp[0].minor.yy144 = OE_Ignore;} + break; + case 78: /* resolvetype ::= REPLACE */ + case 174: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==174); +{yymsp[0].minor.yy144 = OE_Replace;} + break; + case 79: /* cmd ::= DROP TABLE ifexists fullname */ +{ + sqlite3DropTable(pParse, yymsp[0].minor.yy203, 0, yymsp[-1].minor.yy144); +} + break; + case 82: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ +{ + sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy14, yymsp[0].minor.yy555, yymsp[-7].minor.yy144, yymsp[-5].minor.yy144); +} + break; + case 83: /* cmd ::= DROP VIEW ifexists fullname */ +{ + sqlite3DropTable(pParse, yymsp[0].minor.yy203, 1, yymsp[-1].minor.yy144); +} + break; + case 84: /* cmd ::= select */ +{ + SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0, 0}; + if( (pParse->db->mDbFlags & DBFLAG_EncodingFixed)!=0 + || sqlite3ReadSchema(pParse)==SQLITE_OK + ){ + sqlite3Select(pParse, yymsp[0].minor.yy555, &dest); + } + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy555); +} + break; + case 85: /* select ::= WITH wqlist selectnowith */ +{yymsp[-2].minor.yy555 = attachWithToSelect(pParse,yymsp[0].minor.yy555,yymsp[-1].minor.yy59);} + break; + case 86: /* select ::= WITH RECURSIVE wqlist selectnowith */ +{yymsp[-3].minor.yy555 = attachWithToSelect(pParse,yymsp[0].minor.yy555,yymsp[-1].minor.yy59);} + break; + case 87: /* select ::= selectnowith */ +{ + Select *p = yymsp[0].minor.yy555; + if( p ){ + parserDoubleLinkSelect(pParse, p); + } +} + break; + case 88: /* selectnowith ::= selectnowith multiselect_op oneselect */ +{ + Select *pRhs = yymsp[0].minor.yy555; + Select *pLhs = yymsp[-2].minor.yy555; + if( pRhs && pRhs->pPrior ){ + SrcList *pFrom; + Token x; + x.n = 0; + parserDoubleLinkSelect(pParse, pRhs); + pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0); + pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0); + } + if( pRhs ){ + pRhs->op = (u8)yymsp[-1].minor.yy144; + pRhs->pPrior = pLhs; + if( ALWAYS(pLhs) ) pLhs->selFlags &= ~(u32)SF_MultiValue; + pRhs->selFlags &= ~(u32)SF_MultiValue; + if( yymsp[-1].minor.yy144!=TK_ALL ) pParse->hasCompound = 1; + }else{ + sqlite3SelectDelete(pParse->db, pLhs); + } + yymsp[-2].minor.yy555 = pRhs; +} + break; + case 89: /* multiselect_op ::= UNION */ + case 91: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==91); +{yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-OP*/} + break; + case 90: /* multiselect_op ::= UNION ALL */ +{yymsp[-1].minor.yy144 = TK_ALL;} + break; + case 92: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ +{ + yymsp[-8].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy14,yymsp[-5].minor.yy203,yymsp[-4].minor.yy454,yymsp[-3].minor.yy14,yymsp[-2].minor.yy454,yymsp[-1].minor.yy14,yymsp[-7].minor.yy144,yymsp[0].minor.yy454); +} + break; + case 93: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ +{ + yymsp[-9].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy14,yymsp[-6].minor.yy203,yymsp[-5].minor.yy454,yymsp[-4].minor.yy14,yymsp[-3].minor.yy454,yymsp[-1].minor.yy14,yymsp[-8].minor.yy144,yymsp[0].minor.yy454); + if( yymsp[-9].minor.yy555 ){ + yymsp[-9].minor.yy555->pWinDefn = yymsp[-2].minor.yy211; + }else{ + sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy211); + } +} + break; + case 94: /* values ::= VALUES LP nexprlist RP */ +{ + yymsp[-3].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values,0); +} + break; + case 95: /* oneselect ::= mvalues */ +{ + sqlite3MultiValuesEnd(pParse, yymsp[0].minor.yy555); +} + break; + case 96: /* mvalues ::= values COMMA LP nexprlist RP */ + case 97: /* mvalues ::= mvalues COMMA LP nexprlist RP */ yytestcase(yyruleno==97); +{ + yymsp[-4].minor.yy555 = sqlite3MultiValues(pParse, yymsp[-4].minor.yy555, yymsp[-1].minor.yy14); +} + break; + case 98: /* distinct ::= DISTINCT */ +{yymsp[0].minor.yy144 = SF_Distinct;} + break; + case 99: /* distinct ::= ALL */ +{yymsp[0].minor.yy144 = SF_All;} + break; + case 101: /* sclp ::= */ + case 134: /* orderby_opt ::= */ yytestcase(yyruleno==134); + case 144: /* groupby_opt ::= */ yytestcase(yyruleno==144); + case 234: /* exprlist ::= */ yytestcase(yyruleno==234); + case 237: /* paren_exprlist ::= */ yytestcase(yyruleno==237); + case 242: /* eidlist_opt ::= */ yytestcase(yyruleno==242); +{yymsp[1].minor.yy14 = 0;} + break; + case 102: /* selcollist ::= sclp scanpt expr scanpt as */ +{ + yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy14, yymsp[-2].minor.yy454); + if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy14, &yymsp[0].minor.yy0, 1); + sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy14,yymsp[-3].minor.yy168,yymsp[-1].minor.yy168); +} + break; + case 103: /* selcollist ::= sclp scanpt STAR */ +{ + Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0); + sqlite3ExprSetErrorOffset(p, (int)(yymsp[0].minor.yy0.z - pParse->zTail)); + yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy14, p); +} + break; + case 104: /* selcollist ::= sclp scanpt nm DOT STAR */ +{ + Expr *pRight, *pLeft, *pDot; + pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0); + sqlite3ExprSetErrorOffset(pRight, (int)(yymsp[0].minor.yy0.z - pParse->zTail)); + pLeft = tokenExpr(pParse, TK_ID, yymsp[-2].minor.yy0); + pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); + yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, pDot); +} + break; + case 105: /* as ::= AS nm */ + case 117: /* dbnm ::= DOT nm */ yytestcase(yyruleno==117); + case 258: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==258); + case 259: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==259); +{yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;} + break; + case 107: /* from ::= */ + case 110: /* stl_prefix ::= */ yytestcase(yyruleno==110); +{yymsp[1].minor.yy203 = 0;} + break; + case 108: /* from ::= FROM seltablist */ +{ + yymsp[-1].minor.yy203 = yymsp[0].minor.yy203; + sqlite3SrcListShiftJoinType(pParse,yymsp[-1].minor.yy203); +} + break; + case 109: /* stl_prefix ::= seltablist joinop */ +{ + if( ALWAYS(yymsp[-1].minor.yy203 && yymsp[-1].minor.yy203->nSrc>0) ) yymsp[-1].minor.yy203->a[yymsp[-1].minor.yy203->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy144; +} + break; + case 111: /* seltablist ::= stl_prefix nm dbnm as on_using */ +{ + yymsp[-4].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-4].minor.yy203,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269); +} + break; + case 112: /* seltablist ::= stl_prefix nm dbnm as indexed_by on_using */ +{ + yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,0,&yymsp[0].minor.yy269); + sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy203, &yymsp[-1].minor.yy0); +} + break; + case 113: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */ +{ + yymsp[-7].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-7].minor.yy203,&yymsp[-6].minor.yy0,&yymsp[-5].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269); + sqlite3SrcListFuncArgs(pParse, yymsp[-7].minor.yy203, yymsp[-3].minor.yy14); +} + break; + case 114: /* seltablist ::= stl_prefix LP select RP as on_using */ +{ + yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,yymsp[-3].minor.yy555,&yymsp[0].minor.yy269); + } + break; + case 115: /* seltablist ::= stl_prefix LP seltablist RP as on_using */ +{ + if( yymsp[-5].minor.yy203==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy269.pOn==0 && yymsp[0].minor.yy269.pUsing==0 ){ + yymsp[-5].minor.yy203 = yymsp[-3].minor.yy203; + }else if( ALWAYS(yymsp[-3].minor.yy203!=0) && yymsp[-3].minor.yy203->nSrc==1 ){ + yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269); + if( yymsp[-5].minor.yy203 ){ + SrcItem *pNew = &yymsp[-5].minor.yy203->a[yymsp[-5].minor.yy203->nSrc-1]; + SrcItem *pOld = yymsp[-3].minor.yy203->a; + assert( pOld->fg.fixedSchema==0 ); + pNew->zName = pOld->zName; + assert( pOld->fg.fixedSchema==0 ); + if( pOld->fg.isSubquery ){ + pNew->fg.isSubquery = 1; + pNew->u4.pSubq = pOld->u4.pSubq; + pOld->u4.pSubq = 0; + pOld->fg.isSubquery = 0; + assert( pNew->u4.pSubq!=0 && pNew->u4.pSubq->pSelect!=0 ); + if( (pNew->u4.pSubq->pSelect->selFlags & SF_NestedFrom)!=0 ){ + pNew->fg.isNestedFrom = 1; + } + }else{ + pNew->u4.zDatabase = pOld->u4.zDatabase; + pOld->u4.zDatabase = 0; + } + if( pOld->fg.isTabFunc ){ + pNew->u1.pFuncArg = pOld->u1.pFuncArg; + pOld->u1.pFuncArg = 0; + pOld->fg.isTabFunc = 0; + pNew->fg.isTabFunc = 1; + } + pOld->zName = 0; + } + sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy203); + }else{ + Select *pSubquery; + sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy203); + pSubquery = sqlite3SelectNew(pParse,0,yymsp[-3].minor.yy203,0,0,0,0,SF_NestedFrom,0); + yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,pSubquery,&yymsp[0].minor.yy269); + } + } + break; + case 116: /* dbnm ::= */ + case 131: /* indexed_opt ::= */ yytestcase(yyruleno==131); +{yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;} + break; + case 118: /* fullname ::= nm */ + case 120: /* xfullname ::= nm */ yytestcase(yyruleno==120); +{ + yylhsminor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); + if( IN_RENAME_OBJECT && yylhsminor.yy203 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy203->a[0].zName, &yymsp[0].minor.yy0); +} + yymsp[0].minor.yy203 = yylhsminor.yy203; + break; + case 119: /* fullname ::= nm DOT nm */ + case 121: /* xfullname ::= nm DOT nm */ yytestcase(yyruleno==121); +{ + yylhsminor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); + if( IN_RENAME_OBJECT && yylhsminor.yy203 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy203->a[0].zName, &yymsp[0].minor.yy0); +} + yymsp[-2].minor.yy203 = yylhsminor.yy203; + break; + case 122: /* xfullname ::= nm AS nm */ +{ + yylhsminor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); + if( yylhsminor.yy203 ){ + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenMap(pParse, yylhsminor.yy203->a[0].zName, &yymsp[-2].minor.yy0); + }else{ + yylhsminor.yy203->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); + } + } +} + yymsp[-2].minor.yy203 = yylhsminor.yy203; + break; + case 123: /* xfullname ::= nm DOT nm AS nm */ +{ + yylhsminor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); + if( yylhsminor.yy203 ){ + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenMap(pParse, yylhsminor.yy203->a[0].zName, &yymsp[-2].minor.yy0); + }else{ + yylhsminor.yy203->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); + } + } +} + yymsp[-4].minor.yy203 = yylhsminor.yy203; + break; + case 124: /* joinop ::= COMMA|JOIN */ +{ yymsp[0].minor.yy144 = JT_INNER; } + break; + case 125: /* joinop ::= JOIN_KW JOIN */ +{yymsp[-1].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} + break; + case 126: /* joinop ::= JOIN_KW nm JOIN */ +{yymsp[-2].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} + break; + case 127: /* joinop ::= JOIN_KW nm nm JOIN */ +{yymsp[-3].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} + break; + case 128: /* on_using ::= ON expr */ +{yymsp[-1].minor.yy269.pOn = yymsp[0].minor.yy454; yymsp[-1].minor.yy269.pUsing = 0;} + break; + case 129: /* on_using ::= USING LP idlist RP */ +{yymsp[-3].minor.yy269.pOn = 0; yymsp[-3].minor.yy269.pUsing = yymsp[-1].minor.yy132;} + break; + case 130: /* on_using ::= */ +{yymsp[1].minor.yy269.pOn = 0; yymsp[1].minor.yy269.pUsing = 0;} + break; + case 132: /* indexed_by ::= INDEXED BY nm */ +{yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;} + break; + case 133: /* indexed_by ::= NOT INDEXED */ +{yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;} + break; + case 135: /* orderby_opt ::= ORDER BY sortlist */ + case 145: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==145); +{yymsp[-2].minor.yy14 = yymsp[0].minor.yy14;} + break; + case 136: /* sortlist ::= sortlist COMMA expr sortorder nulls */ +{ + yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14,yymsp[-2].minor.yy454); + sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy14,yymsp[-1].minor.yy144,yymsp[0].minor.yy144); +} + break; + case 137: /* sortlist ::= expr sortorder nulls */ +{ + yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy454); /*A-overwrites-Y*/ + sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy14,yymsp[-1].minor.yy144,yymsp[0].minor.yy144); +} + break; + case 138: /* sortorder ::= ASC */ +{yymsp[0].minor.yy144 = SQLITE_SO_ASC;} + break; + case 139: /* sortorder ::= DESC */ +{yymsp[0].minor.yy144 = SQLITE_SO_DESC;} + break; + case 140: /* sortorder ::= */ + case 143: /* nulls ::= */ yytestcase(yyruleno==143); +{yymsp[1].minor.yy144 = SQLITE_SO_UNDEFINED;} + break; + case 141: /* nulls ::= NULLS FIRST */ +{yymsp[-1].minor.yy144 = SQLITE_SO_ASC;} + break; + case 142: /* nulls ::= NULLS LAST */ +{yymsp[-1].minor.yy144 = SQLITE_SO_DESC;} + break; + case 146: /* having_opt ::= */ + case 148: /* limit_opt ::= */ yytestcase(yyruleno==148); + case 153: /* where_opt ::= */ yytestcase(yyruleno==153); + case 155: /* where_opt_ret ::= */ yytestcase(yyruleno==155); + case 232: /* case_else ::= */ yytestcase(yyruleno==232); + case 233: /* case_operand ::= */ yytestcase(yyruleno==233); + case 252: /* vinto ::= */ yytestcase(yyruleno==252); +{yymsp[1].minor.yy454 = 0;} + break; + case 147: /* having_opt ::= HAVING expr */ + case 154: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==154); + case 156: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==156); + case 231: /* case_else ::= ELSE expr */ yytestcase(yyruleno==231); + case 251: /* vinto ::= INTO expr */ yytestcase(yyruleno==251); +{yymsp[-1].minor.yy454 = yymsp[0].minor.yy454;} + break; + case 149: /* limit_opt ::= LIMIT expr */ +{yymsp[-1].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy454,0);} + break; + case 150: /* limit_opt ::= LIMIT expr OFFSET expr */ +{yymsp[-3].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);} + break; + case 151: /* limit_opt ::= LIMIT expr COMMA expr */ +{yymsp[-3].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy454,yymsp[-2].minor.yy454);} + break; + case 152: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ +{ + sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy203, &yymsp[-1].minor.yy0); + sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy203,yymsp[0].minor.yy454,0,0); +} + break; + case 157: /* where_opt_ret ::= RETURNING selcollist */ +{sqlite3AddReturning(pParse,yymsp[0].minor.yy14); yymsp[-1].minor.yy454 = 0;} + break; + case 158: /* where_opt_ret ::= WHERE expr RETURNING selcollist */ +{sqlite3AddReturning(pParse,yymsp[0].minor.yy14); yymsp[-3].minor.yy454 = yymsp[-2].minor.yy454;} + break; + case 159: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ +{ + sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy203, &yymsp[-4].minor.yy0); + sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy14,"set list"); + if( yymsp[-1].minor.yy203 ){ + SrcList *pFromClause = yymsp[-1].minor.yy203; + if( pFromClause->nSrc>1 ){ + Select *pSubquery; + Token as; + pSubquery = sqlite3SelectNew(pParse,0,pFromClause,0,0,0,0,SF_NestedFrom,0); + as.n = 0; + as.z = 0; + pFromClause = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&as,pSubquery,0); + } + yymsp[-5].minor.yy203 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy203, pFromClause); + } + sqlite3Update(pParse,yymsp[-5].minor.yy203,yymsp[-2].minor.yy14,yymsp[0].minor.yy454,yymsp[-6].minor.yy144,0,0,0); +} + break; + case 160: /* setlist ::= setlist COMMA nm EQ expr */ +{ + yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy14, yymsp[0].minor.yy454); + sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy14, &yymsp[-2].minor.yy0, 1); +} + break; + case 161: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ +{ + yymsp[-6].minor.yy14 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy14, yymsp[-3].minor.yy132, yymsp[0].minor.yy454); +} + break; + case 162: /* setlist ::= nm EQ expr */ +{ + yylhsminor.yy14 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy454); + sqlite3ExprListSetName(pParse, yylhsminor.yy14, &yymsp[-2].minor.yy0, 1); +} + yymsp[-2].minor.yy14 = yylhsminor.yy14; + break; + case 163: /* setlist ::= LP idlist RP EQ expr */ +{ + yymsp[-4].minor.yy14 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy132, yymsp[0].minor.yy454); +} + break; + case 164: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ +{ + sqlite3Insert(pParse, yymsp[-3].minor.yy203, yymsp[-1].minor.yy555, yymsp[-2].minor.yy132, yymsp[-5].minor.yy144, yymsp[0].minor.yy122); +} + break; + case 165: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ +{ + sqlite3Insert(pParse, yymsp[-4].minor.yy203, 0, yymsp[-3].minor.yy132, yymsp[-6].minor.yy144, 0); +} + break; + case 166: /* upsert ::= */ +{ yymsp[1].minor.yy122 = 0; } + break; + case 167: /* upsert ::= RETURNING selcollist */ +{ yymsp[-1].minor.yy122 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy14); } + break; + case 168: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ +{ yymsp[-11].minor.yy122 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy14,yymsp[-6].minor.yy454,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454,yymsp[0].minor.yy122);} + break; + case 169: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ +{ yymsp[-8].minor.yy122 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy14,yymsp[-3].minor.yy454,0,0,yymsp[0].minor.yy122); } + break; + case 170: /* upsert ::= ON CONFLICT DO NOTHING returning */ +{ yymsp[-4].minor.yy122 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); } + break; + case 171: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ +{ yymsp[-7].minor.yy122 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454,0);} + break; + case 172: /* returning ::= RETURNING selcollist */ +{sqlite3AddReturning(pParse,yymsp[0].minor.yy14);} + break; + case 175: /* idlist_opt ::= */ +{yymsp[1].minor.yy132 = 0;} + break; + case 176: /* idlist_opt ::= LP idlist RP */ +{yymsp[-2].minor.yy132 = yymsp[-1].minor.yy132;} + break; + case 177: /* idlist ::= idlist COMMA nm */ +{yymsp[-2].minor.yy132 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy132,&yymsp[0].minor.yy0);} + break; + case 178: /* idlist ::= nm */ +{yymsp[0].minor.yy132 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} + break; + case 179: /* expr ::= LP expr RP */ +{yymsp[-2].minor.yy454 = yymsp[-1].minor.yy454;} + break; + case 180: /* expr ::= ID|INDEXED|JOIN_KW */ +{yymsp[0].minor.yy454=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} + break; + case 181: /* expr ::= nm DOT nm */ +{ + Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0); + Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); + yylhsminor.yy454 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); +} + yymsp[-2].minor.yy454 = yylhsminor.yy454; + break; + case 182: /* expr ::= nm DOT nm DOT nm */ +{ + Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-4].minor.yy0); + Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0); + Expr *temp3 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); + Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3); + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, 0, temp1); + } + yylhsminor.yy454 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); +} + yymsp[-4].minor.yy454 = yylhsminor.yy454; + break; + case 183: /* term ::= NULL|FLOAT|BLOB */ + case 184: /* term ::= STRING */ yytestcase(yyruleno==184); +{yymsp[0].minor.yy454=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} + break; + case 185: /* term ::= INTEGER */ +{ + int iValue; + if( sqlite3GetInt32(yymsp[0].minor.yy0.z, &iValue)==0 ){ + yylhsminor.yy454 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 0); + }else{ + yylhsminor.yy454 = sqlite3ExprInt32(pParse->db, iValue); + } + if( yylhsminor.yy454 ) yylhsminor.yy454->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail); +} + yymsp[0].minor.yy454 = yylhsminor.yy454; + break; + case 186: /* expr ::= VARIABLE */ +{ + if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){ + u32 n = yymsp[0].minor.yy0.n; + yymsp[0].minor.yy454 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); + sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy454, n); + }else{ + /* When doing a nested parse, one can include terms in an expression + ** that look like this: #1 #2 ... These terms refer to registers + ** in the virtual machine. #N is the N-th register. */ + Token t = yymsp[0].minor.yy0; /*A-overwrites-X*/ + assert( t.n>=2 ); + if( pParse->nested==0 ){ + parserSyntaxError(pParse, &t); + yymsp[0].minor.yy454 = 0; + }else{ + yymsp[0].minor.yy454 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); + if( yymsp[0].minor.yy454 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy454->iTable); + } + } +} + break; + case 187: /* expr ::= expr COLLATE ID|STRING */ +{ + yymsp[-2].minor.yy454 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy454, &yymsp[0].minor.yy0, 1); +} + break; + case 188: /* expr ::= CAST LP expr AS typetoken RP */ +{ + yymsp[-5].minor.yy454 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); + sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy454, yymsp[-3].minor.yy454, 0); +} + break; + case 189: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */ +{ + yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy144); +} + yymsp[-4].minor.yy454 = yylhsminor.yy454; + break; + case 190: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */ +{ + yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-4].minor.yy14, &yymsp[-7].minor.yy0, yymsp[-5].minor.yy144); + sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy454, yymsp[-1].minor.yy14); +} + yymsp[-7].minor.yy454 = yylhsminor.yy454; + break; + case 191: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP */ +{ + yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); +} + yymsp[-3].minor.yy454 = yylhsminor.yy454; + break; + case 192: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */ +{ + yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy14, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy144); + sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211); +} + yymsp[-5].minor.yy454 = yylhsminor.yy454; + break; + case 193: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */ +{ + yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-5].minor.yy14, &yymsp[-8].minor.yy0, yymsp[-6].minor.yy144); + sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211); + sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy454, yymsp[-2].minor.yy14); +} + yymsp[-8].minor.yy454 = yylhsminor.yy454; + break; + case 194: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */ +{ + yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); + sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211); +} + yymsp[-4].minor.yy454 = yylhsminor.yy454; + break; + case 195: /* term ::= CTIME_KW */ +{ + yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); +} + yymsp[0].minor.yy454 = yylhsminor.yy454; + break; + case 196: /* expr ::= LP nexprlist COMMA expr RP */ +{ + ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy14, yymsp[-1].minor.yy454); + yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); + if( yymsp[-4].minor.yy454 ){ + int i; + yymsp[-4].minor.yy454->x.pList = pList; + for(i=0; inExpr; i++){ + assert( pList->a[i].pExpr!=0 ); + yymsp[-4].minor.yy454->flags |= pList->a[i].pExpr->flags & EP_Propagate; + } + }else{ + sqlite3ExprListDelete(pParse->db, pList); + } +} + break; + case 197: /* expr ::= expr AND expr */ +{yymsp[-2].minor.yy454=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);} + break; + case 198: /* expr ::= expr OR expr */ + case 199: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==199); + case 200: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==200); + case 201: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==201); + case 202: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==202); + case 203: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==203); + case 204: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==204); +{yymsp[-2].minor.yy454=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);} + break; + case 205: /* likeop ::= NOT LIKE_KW|MATCH */ +{yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/} + break; + case 206: /* expr ::= expr likeop expr */ +{ + ExprList *pList; + int bNot = yymsp[-1].minor.yy0.n & 0x80000000; + yymsp[-1].minor.yy0.n &= 0x7fffffff; + pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy454); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy454); + yymsp[-2].minor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); + if( bNot ) yymsp[-2].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy454, 0); + if( yymsp[-2].minor.yy454 ) yymsp[-2].minor.yy454->flags |= EP_InfixFunc; +} + break; + case 207: /* expr ::= expr likeop expr ESCAPE expr */ +{ + ExprList *pList; + int bNot = yymsp[-3].minor.yy0.n & 0x80000000; + yymsp[-3].minor.yy0.n &= 0x7fffffff; + pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy454); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy454); + yymsp[-4].minor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); + if( bNot ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0); + if( yymsp[-4].minor.yy454 ) yymsp[-4].minor.yy454->flags |= EP_InfixFunc; +} + break; + case 208: /* expr ::= expr ISNULL|NOTNULL */ +{yymsp[-1].minor.yy454 = sqlite3PExprIsNull(pParse,yymsp[0].major,yymsp[-1].minor.yy454);} + break; + case 209: /* expr ::= expr NOT NULL */ +{yymsp[-2].minor.yy454 = sqlite3PExprIsNull(pParse,TK_NOTNULL,yymsp[-2].minor.yy454);} + break; + case 210: /* expr ::= expr IS expr */ +{ + yymsp[-2].minor.yy454 = sqlite3PExprIs(pParse, TK_IS, yymsp[-2].minor.yy454, yymsp[0].minor.yy454); +} + break; + case 211: /* expr ::= expr IS NOT expr */ +{ + yymsp[-3].minor.yy454 = sqlite3PExprIs(pParse, TK_ISNOT, yymsp[-3].minor.yy454, yymsp[0].minor.yy454); +} + break; + case 212: /* expr ::= expr IS NOT DISTINCT FROM expr */ +{ + yymsp[-5].minor.yy454 = sqlite3PExprIs(pParse, TK_IS, yymsp[-5].minor.yy454, yymsp[0].minor.yy454); +} + break; + case 213: /* expr ::= expr IS DISTINCT FROM expr */ +{ + yymsp[-4].minor.yy454 = sqlite3PExprIs(pParse, TK_ISNOT, yymsp[-4].minor.yy454, yymsp[0].minor.yy454); +} + break; + case 214: /* expr ::= NOT expr */ + case 215: /* expr ::= BITNOT expr */ yytestcase(yyruleno==215); +{yymsp[-1].minor.yy454 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy454, 0);/*A-overwrites-B*/} + break; + case 216: /* expr ::= PLUS|MINUS expr */ +{ + Expr *p = yymsp[0].minor.yy454; + u8 op = yymsp[-1].major + (TK_UPLUS-TK_PLUS); + assert( TK_UPLUS>TK_PLUS ); + assert( TK_UMINUS == TK_MINUS + (TK_UPLUS - TK_PLUS) ); + if( p && p->op==TK_UPLUS ){ + p->op = op; + yymsp[-1].minor.yy454 = p; + }else{ + yymsp[-1].minor.yy454 = sqlite3PExpr(pParse, op, p, 0); + /*A-overwrites-B*/ + } +} + break; + case 217: /* expr ::= expr PTR expr */ +{ + ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy454); + pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy454); + yylhsminor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); +} + yymsp[-2].minor.yy454 = yylhsminor.yy454; + break; + case 218: /* between_op ::= BETWEEN */ + case 221: /* in_op ::= IN */ yytestcase(yyruleno==221); +{yymsp[0].minor.yy144 = 0;} + break; + case 220: /* expr ::= expr between_op expr AND expr */ +{ + ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy454); + yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy454, 0); + if( yymsp[-4].minor.yy454 ){ + yymsp[-4].minor.yy454->x.pList = pList; + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy454); + }else{ + sqlite3ExprListDelete(pParse->db, pList); + } + if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0); +} + break; + case 223: /* expr ::= expr in_op LP exprlist RP */ +{ + if( yymsp[-1].minor.yy14==0 ){ + /* Expressions of the form + ** + ** expr1 IN () + ** expr1 NOT IN () + ** + ** simplify to constants 0 (false) and 1 (true), respectively. + ** + ** Except, do not apply this optimization if expr1 contains a function + ** because that function might be an aggregate (we don't know yet whether + ** it is or not) and if it is an aggregate, that could change the meaning + ** of the whole query. + */ + Expr *pB = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy144 ? "true" : "false"); + if( pB ) sqlite3ExprIdToTrueFalse(pB); + if( !ExprHasProperty(yymsp[-4].minor.yy454, EP_HasFunc) ){ + sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy454); + yymsp[-4].minor.yy454 = pB; + }else{ + yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, yymsp[-3].minor.yy144 ? TK_OR : TK_AND, pB, yymsp[-4].minor.yy454); + } + }else{ + Expr *pRHS = yymsp[-1].minor.yy14->a[0].pExpr; + if( yymsp[-1].minor.yy14->nExpr==1 && sqlite3ExprIsConstant(pParse,pRHS) && yymsp[-4].minor.yy454->op!=TK_VECTOR ){ + yymsp[-1].minor.yy14->a[0].pExpr = 0; + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14); + pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0); + yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy454, pRHS); + }else if( yymsp[-1].minor.yy14->nExpr==1 && pRHS->op==TK_SELECT ){ + yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, pRHS->x.pSelect); + pRHS->x.pSelect = 0; + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14); + }else{ + yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0); + if( yymsp[-4].minor.yy454==0 ){ + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14); + }else if( yymsp[-4].minor.yy454->pLeft->op==TK_VECTOR ){ + int nExpr = yymsp[-4].minor.yy454->pLeft->x.pList->nExpr; + Select *pSelectRHS = sqlite3ExprListToValues(pParse, nExpr, yymsp[-1].minor.yy14); + if( pSelectRHS ){ + parserDoubleLinkSelect(pParse, pSelectRHS); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, pSelectRHS); + } + }else{ + yymsp[-4].minor.yy454->x.pList = yymsp[-1].minor.yy14; + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy454); + } + } + if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0); + } + } + break; + case 224: /* expr ::= LP select RP */ +{ + yymsp[-2].minor.yy454 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); + sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy454, yymsp[-1].minor.yy555); + } + break; + case 225: /* expr ::= expr in_op LP select RP */ +{ + yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, yymsp[-1].minor.yy555); + if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0); + } + break; + case 226: /* expr ::= expr in_op nm dbnm paren_exprlist */ +{ + SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); + Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0); + if( yymsp[0].minor.yy14 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy14); + yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, pSelect); + if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0); + } + break; + case 227: /* expr ::= EXISTS LP select RP */ +{ + Expr *p; + p = yymsp[-3].minor.yy454 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); + sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy555); + } + break; + case 228: /* expr ::= CASE case_operand case_exprlist case_else END */ +{ + yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy454, 0); + if( yymsp[-4].minor.yy454 ){ + yymsp[-4].minor.yy454->x.pList = yymsp[-1].minor.yy454 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454) : yymsp[-2].minor.yy14; + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy454); + }else{ + sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy14); + sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy454); + } +} + break; + case 229: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ +{ + yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, yymsp[-2].minor.yy454); + yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, yymsp[0].minor.yy454); +} + break; + case 230: /* case_exprlist ::= WHEN expr THEN expr */ +{ + yymsp[-3].minor.yy14 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454); + yymsp[-3].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy14, yymsp[0].minor.yy454); +} + break; + case 235: /* nexprlist ::= nexprlist COMMA expr */ +{yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[0].minor.yy454);} + break; + case 236: /* nexprlist ::= expr */ +{yymsp[0].minor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy454); /*A-overwrites-Y*/} + break; + case 238: /* paren_exprlist ::= LP exprlist RP */ + case 243: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==243); +{yymsp[-2].minor.yy14 = yymsp[-1].minor.yy14;} + break; + case 239: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ +{ + sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, + sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy14, yymsp[-10].minor.yy144, + &yymsp[-11].minor.yy0, yymsp[0].minor.yy454, SQLITE_SO_ASC, yymsp[-8].minor.yy144, SQLITE_IDXTYPE_APPDEF); + if( IN_RENAME_OBJECT && pParse->pNewIndex ){ + sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0); + } +} + break; + case 240: /* uniqueflag ::= UNIQUE */ + case 281: /* raisetype ::= ABORT */ yytestcase(yyruleno==281); +{yymsp[0].minor.yy144 = OE_Abort;} + break; + case 241: /* uniqueflag ::= */ +{yymsp[1].minor.yy144 = OE_None;} + break; + case 244: /* eidlist ::= eidlist COMMA nm collate sortorder */ +{ + yymsp[-4].minor.yy14 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy14, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy144, yymsp[0].minor.yy144); +} + break; + case 245: /* eidlist ::= nm collate sortorder */ +{ + yymsp[-2].minor.yy14 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy144, yymsp[0].minor.yy144); /*A-overwrites-Y*/ +} + break; + case 248: /* cmd ::= DROP INDEX ifexists fullname */ +{sqlite3DropIndex(pParse, yymsp[0].minor.yy203, yymsp[-1].minor.yy144);} + break; + case 249: /* cmd ::= VACUUM vinto */ +{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy454);} + break; + case 250: /* cmd ::= VACUUM nm vinto */ +{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy454);} + break; + case 253: /* cmd ::= PRAGMA nm dbnm */ +{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} + break; + case 254: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ +{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);} + break; + case 255: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ +{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);} + break; + case 256: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ +{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);} + break; + case 257: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ +{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);} + break; + case 260: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ +{ + Token all; + all.z = yymsp[-3].minor.yy0.z; + all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n; + sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy427, &all); +} + break; + case 261: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ +{ + sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy144, yymsp[-4].minor.yy286.a, yymsp[-4].minor.yy286.b, yymsp[-2].minor.yy203, yymsp[0].minor.yy454, yymsp[-10].minor.yy144, yymsp[-8].minor.yy144); + yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/ +#ifdef SQLITE_DEBUG + assert( pParse->isCreate ); /* Set by createkw reduce action */ + pParse->isCreate = 0; /* But, should not be set for CREATE TRIGGER */ +#endif +} + break; + case 262: /* trigger_time ::= BEFORE|AFTER */ +{ yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-X*/ } + break; + case 263: /* trigger_time ::= INSTEAD OF */ +{ yymsp[-1].minor.yy144 = TK_INSTEAD;} + break; + case 264: /* trigger_time ::= */ +{ yymsp[1].minor.yy144 = TK_BEFORE; } + break; + case 265: /* trigger_event ::= DELETE|INSERT */ + case 266: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==266); +{yymsp[0].minor.yy286.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy286.b = 0;} + break; + case 267: /* trigger_event ::= UPDATE OF idlist */ +{yymsp[-2].minor.yy286.a = TK_UPDATE; yymsp[-2].minor.yy286.b = yymsp[0].minor.yy132;} + break; + case 268: /* when_clause ::= */ + case 286: /* key_opt ::= */ yytestcase(yyruleno==286); +{ yymsp[1].minor.yy454 = 0; } + break; + case 269: /* when_clause ::= WHEN expr */ + case 287: /* key_opt ::= KEY expr */ yytestcase(yyruleno==287); +{ yymsp[-1].minor.yy454 = yymsp[0].minor.yy454; } + break; + case 270: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ +{ + yymsp[-2].minor.yy427->pLast->pNext = yymsp[-1].minor.yy427; + yymsp[-2].minor.yy427->pLast = yymsp[-1].minor.yy427; +} + break; + case 271: /* trigger_cmd_list ::= trigger_cmd SEMI */ +{ + yymsp[-1].minor.yy427->pLast = yymsp[-1].minor.yy427; +} + break; + case 272: /* tridxby ::= INDEXED BY nm */ +{ + sqlite3ErrorMsg(pParse, + "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " + "within triggers"); +} + break; + case 273: /* tridxby ::= NOT INDEXED */ +{ + sqlite3ErrorMsg(pParse, + "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " + "within triggers"); +} + break; + case 274: /* trigger_cmd ::= UPDATE orconf xfullname tridxby SET setlist from where_opt scanpt */ +{yylhsminor.yy427 = sqlite3TriggerUpdateStep(pParse, yymsp[-6].minor.yy203, yymsp[-2].minor.yy203, yymsp[-3].minor.yy14, yymsp[-1].minor.yy454, yymsp[-7].minor.yy144, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy168);} + yymsp[-8].minor.yy427 = yylhsminor.yy427; + break; + case 275: /* trigger_cmd ::= scanpt insert_cmd INTO xfullname idlist_opt select upsert scanpt */ +{ + yylhsminor.yy427 = sqlite3TriggerInsertStep(pParse,yymsp[-4].minor.yy203,yymsp[-3].minor.yy132,yymsp[-2].minor.yy555,yymsp[-6].minor.yy144,yymsp[-1].minor.yy122,yymsp[-7].minor.yy168,yymsp[0].minor.yy168);/*yylhsminor.yy427-overwrites-yymsp[-6].minor.yy144*/ +} + yymsp[-7].minor.yy427 = yylhsminor.yy427; + break; + case 276: /* trigger_cmd ::= DELETE FROM xfullname tridxby where_opt scanpt */ +{yylhsminor.yy427 = sqlite3TriggerDeleteStep(pParse, yymsp[-3].minor.yy203, yymsp[-1].minor.yy454, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy168);} + yymsp[-5].minor.yy427 = yylhsminor.yy427; + break; + case 277: /* trigger_cmd ::= scanpt select scanpt */ +{yylhsminor.yy427 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy555, yymsp[-2].minor.yy168, yymsp[0].minor.yy168); /*yylhsminor.yy427-overwrites-yymsp[-1].minor.yy555*/} + yymsp[-2].minor.yy427 = yylhsminor.yy427; + break; + case 278: /* expr ::= RAISE LP IGNORE RP */ +{ + yymsp[-3].minor.yy454 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); + if( yymsp[-3].minor.yy454 ){ + yymsp[-3].minor.yy454->affExpr = OE_Ignore; + } +} + break; + case 279: /* expr ::= RAISE LP raisetype COMMA expr RP */ +{ + yymsp[-5].minor.yy454 = sqlite3PExpr(pParse, TK_RAISE, yymsp[-1].minor.yy454, 0); + if( yymsp[-5].minor.yy454 ) { + yymsp[-5].minor.yy454->affExpr = (char)yymsp[-3].minor.yy144; + } +} + break; + case 280: /* raisetype ::= ROLLBACK */ +{yymsp[0].minor.yy144 = OE_Rollback;} + break; + case 282: /* raisetype ::= FAIL */ +{yymsp[0].minor.yy144 = OE_Fail;} + break; + case 283: /* cmd ::= DROP TRIGGER ifexists fullname */ +{ + sqlite3DropTrigger(pParse,yymsp[0].minor.yy203,yymsp[-1].minor.yy144); +} + break; + case 284: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ +{ + sqlite3Attach(pParse, yymsp[-3].minor.yy454, yymsp[-1].minor.yy454, yymsp[0].minor.yy454); +} + break; + case 285: /* cmd ::= DETACH database_kw_opt expr */ +{ + sqlite3Detach(pParse, yymsp[0].minor.yy454); +} + break; + case 288: /* cmd ::= REINDEX */ +{sqlite3Reindex(pParse, 0, 0);} + break; + case 289: /* cmd ::= REINDEX nm dbnm */ +{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} + break; + case 290: /* cmd ::= ANALYZE */ +{sqlite3Analyze(pParse, 0, 0);} + break; + case 291: /* cmd ::= ANALYZE nm dbnm */ +{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} + break; + case 292: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ +{ + sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy203,&yymsp[0].minor.yy0); +} + break; + case 293: /* cmd ::= alter_add carglist */ +{ + yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n; + sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0); +} + break; + case 294: /* alter_add ::= ALTER TABLE fullname ADD kwcolumn_opt nm typetoken */ +{ + disableLookaside(pParse); + sqlite3AlterBeginAddColumn(pParse, yymsp[-4].minor.yy203); + sqlite3AddColumn(pParse, yymsp[-1].minor.yy0, yymsp[0].minor.yy0); + yymsp[-6].minor.yy0 = yymsp[-1].minor.yy0; +} + break; + case 295: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ +{ + sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy203, &yymsp[0].minor.yy0); +} + break; + case 296: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ +{ + sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy203, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); +} + break; + case 297: /* cmd ::= ALTER TABLE fullname DROP CONSTRAINT nm */ +{ + sqlite3AlterDropConstraint(pParse, yymsp[-3].minor.yy203, &yymsp[0].minor.yy0, 0); +} + break; + case 298: /* cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm DROP NOT NULL */ +{ + sqlite3AlterDropConstraint(pParse, yymsp[-6].minor.yy203, 0, &yymsp[-3].minor.yy0); +} + break; + case 299: /* cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm SET NOT NULL onconf */ +{ + sqlite3AlterSetNotNull(pParse, yymsp[-7].minor.yy203, &yymsp[-4].minor.yy0, &yymsp[-2].minor.yy0); +} + break; + case 300: /* cmd ::= ALTER TABLE fullname ADD CONSTRAINT nm CHECK LP expr RP onconf */ +{ + sqlite3AlterAddConstraint(pParse, yymsp[-8].minor.yy203, &yymsp[-6].minor.yy0, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy0.z+1, (yymsp[-1].minor.yy0.z-yymsp[-3].minor.yy0.z-1), yymsp[-2].minor.yy454); +} + break; + case 301: /* cmd ::= ALTER TABLE fullname ADD CHECK LP expr RP onconf */ +{ + sqlite3AlterAddConstraint(pParse, yymsp[-6].minor.yy203, &yymsp[-4].minor.yy0, 0, yymsp[-3].minor.yy0.z+1, (yymsp[-1].minor.yy0.z-yymsp[-3].minor.yy0.z-1), yymsp[-2].minor.yy454); +} + break; + case 302: /* cmd ::= create_vtab */ +{sqlite3VtabFinishParse(pParse,0);} + break; + case 303: /* cmd ::= create_vtab LP vtabarglist RP */ +{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} + break; + case 304: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ +{ + sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy144); +} + break; + case 305: /* vtabarg ::= */ +{sqlite3VtabArgInit(pParse);} + break; + case 306: /* vtabargtoken ::= ANY */ + case 307: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==307); + case 308: /* lp ::= LP */ yytestcase(yyruleno==308); +{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} + break; + case 309: /* with ::= WITH wqlist */ + case 310: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==310); +{ sqlite3WithPush(pParse, yymsp[0].minor.yy59, 1); } + break; + case 311: /* wqas ::= AS */ +{yymsp[0].minor.yy462 = M10d_Any;} + break; + case 312: /* wqas ::= AS MATERIALIZED */ +{yymsp[-1].minor.yy462 = M10d_Yes;} + break; + case 313: /* wqas ::= AS NOT MATERIALIZED */ +{yymsp[-2].minor.yy462 = M10d_No;} + break; + case 314: /* wqitem ::= withnm eidlist_opt wqas LP select RP */ +{ + yymsp[-5].minor.yy67 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy14, yymsp[-1].minor.yy555, yymsp[-3].minor.yy462); /*A-overwrites-X*/ +} + break; + case 315: /* withnm ::= nm */ +{pParse->bHasWith = 1;} + break; + case 316: /* wqlist ::= wqitem */ +{ + yymsp[0].minor.yy59 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy67); /*A-overwrites-X*/ +} + break; + case 317: /* wqlist ::= wqlist COMMA wqitem */ +{ + yymsp[-2].minor.yy59 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy59, yymsp[0].minor.yy67); +} + break; + case 318: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ +{ + assert( yymsp[0].minor.yy211!=0 ); + sqlite3WindowChain(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy211); + yymsp[0].minor.yy211->pNextWin = yymsp[-2].minor.yy211; + yylhsminor.yy211 = yymsp[0].minor.yy211; +} + yymsp[-2].minor.yy211 = yylhsminor.yy211; + break; + case 319: /* windowdefn ::= nm AS LP window RP */ +{ + if( ALWAYS(yymsp[-1].minor.yy211) ){ + yymsp[-1].minor.yy211->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n); + } + yylhsminor.yy211 = yymsp[-1].minor.yy211; +} + yymsp[-4].minor.yy211 = yylhsminor.yy211; + break; + case 320: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ +{ + yymsp[-4].minor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy14, yymsp[-1].minor.yy14, 0); +} + break; + case 321: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ +{ + yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy14, yymsp[-1].minor.yy14, &yymsp[-5].minor.yy0); +} + yymsp[-5].minor.yy211 = yylhsminor.yy211; + break; + case 322: /* window ::= ORDER BY sortlist frame_opt */ +{ + yymsp[-3].minor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, yymsp[-1].minor.yy14, 0); +} + break; + case 323: /* window ::= nm ORDER BY sortlist frame_opt */ +{ + yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0); +} + yymsp[-4].minor.yy211 = yylhsminor.yy211; + break; + case 324: /* window ::= nm frame_opt */ +{ + yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, 0, &yymsp[-1].minor.yy0); +} + yymsp[-1].minor.yy211 = yylhsminor.yy211; + break; + case 325: /* frame_opt ::= */ +{ + yymsp[1].minor.yy211 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0); +} + break; + case 326: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ +{ + yylhsminor.yy211 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy144, yymsp[-1].minor.yy509.eType, yymsp[-1].minor.yy509.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy462); +} + yymsp[-2].minor.yy211 = yylhsminor.yy211; + break; + case 327: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ +{ + yylhsminor.yy211 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy144, yymsp[-3].minor.yy509.eType, yymsp[-3].minor.yy509.pExpr, yymsp[-1].minor.yy509.eType, yymsp[-1].minor.yy509.pExpr, yymsp[0].minor.yy462); +} + yymsp[-5].minor.yy211 = yylhsminor.yy211; + break; + case 329: /* frame_bound_s ::= frame_bound */ + case 331: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==331); +{yylhsminor.yy509 = yymsp[0].minor.yy509;} + yymsp[0].minor.yy509 = yylhsminor.yy509; + break; + case 330: /* frame_bound_s ::= UNBOUNDED PRECEDING */ + case 332: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==332); + case 334: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==334); +{yylhsminor.yy509.eType = yymsp[-1].major; yylhsminor.yy509.pExpr = 0;} + yymsp[-1].minor.yy509 = yylhsminor.yy509; + break; + case 333: /* frame_bound ::= expr PRECEDING|FOLLOWING */ +{yylhsminor.yy509.eType = yymsp[0].major; yylhsminor.yy509.pExpr = yymsp[-1].minor.yy454;} + yymsp[-1].minor.yy509 = yylhsminor.yy509; + break; + case 335: /* frame_exclude_opt ::= */ +{yymsp[1].minor.yy462 = 0;} + break; + case 336: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ +{yymsp[-1].minor.yy462 = yymsp[0].minor.yy462;} + break; + case 337: /* frame_exclude ::= NO OTHERS */ + case 338: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==338); +{yymsp[-1].minor.yy462 = yymsp[-1].major; /*A-overwrites-X*/} + break; + case 339: /* frame_exclude ::= GROUP|TIES */ +{yymsp[0].minor.yy462 = yymsp[0].major; /*A-overwrites-X*/} + break; + case 340: /* window_clause ::= WINDOW windowdefn_list */ +{ yymsp[-1].minor.yy211 = yymsp[0].minor.yy211; } + break; + case 341: /* filter_over ::= filter_clause over_clause */ +{ + if( yymsp[0].minor.yy211 ){ + yymsp[0].minor.yy211->pFilter = yymsp[-1].minor.yy454; + }else{ + sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy454); + } + yylhsminor.yy211 = yymsp[0].minor.yy211; +} + yymsp[-1].minor.yy211 = yylhsminor.yy211; + break; + case 342: /* filter_over ::= over_clause */ +{ + yylhsminor.yy211 = yymsp[0].minor.yy211; +} + yymsp[0].minor.yy211 = yylhsminor.yy211; + break; + case 343: /* filter_over ::= filter_clause */ +{ + yylhsminor.yy211 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); + if( yylhsminor.yy211 ){ + yylhsminor.yy211->eFrmType = TK_FILTER; + yylhsminor.yy211->pFilter = yymsp[0].minor.yy454; + }else{ + sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy454); + } +} + yymsp[0].minor.yy211 = yylhsminor.yy211; + break; + case 344: /* over_clause ::= OVER LP window RP */ +{ + yymsp[-3].minor.yy211 = yymsp[-1].minor.yy211; + assert( yymsp[-3].minor.yy211!=0 ); +} + break; + case 345: /* over_clause ::= OVER nm */ +{ + yymsp[-1].minor.yy211 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); + if( yymsp[-1].minor.yy211 ){ + yymsp[-1].minor.yy211->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n); + } +} + break; + case 346: /* filter_clause ::= FILTER LP WHERE expr RP */ +{ yymsp[-4].minor.yy454 = yymsp[-1].minor.yy454; } + break; + case 347: /* term ::= QNUMBER */ +{ + yylhsminor.yy454=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); + sqlite3DequoteNumber(pParse, yylhsminor.yy454); +} + yymsp[0].minor.yy454 = yylhsminor.yy454; + break; + default: + /* (348) input ::= cmdlist */ yytestcase(yyruleno==348); + /* (349) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==349); + /* (350) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=350); + /* (351) ecmd ::= SEMI */ yytestcase(yyruleno==351); + /* (352) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==352); + /* (353) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=353); + /* (354) trans_opt ::= */ yytestcase(yyruleno==354); + /* (355) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==355); + /* (356) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==356); + /* (357) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==357); + /* (358) savepoint_opt ::= */ yytestcase(yyruleno==358); + /* (359) cmd ::= create_table create_table_args */ yytestcase(yyruleno==359); + /* (360) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=360); + /* (361) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==361); + /* (362) columnlist ::= columnname carglist */ yytestcase(yyruleno==362); + /* (363) nm ::= ID|INDEXED|JOIN_KW */ yytestcase(yyruleno==363); + /* (364) nm ::= STRING */ yytestcase(yyruleno==364); + /* (365) typetoken ::= typename */ yytestcase(yyruleno==365); + /* (366) typename ::= ID|STRING */ yytestcase(yyruleno==366); + /* (367) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=367); + /* (368) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=368); + /* (369) carglist ::= carglist ccons */ yytestcase(yyruleno==369); + /* (370) carglist ::= */ yytestcase(yyruleno==370); + /* (371) ccons ::= NULL onconf */ yytestcase(yyruleno==371); + /* (372) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==372); + /* (373) ccons ::= AS generated */ yytestcase(yyruleno==373); + /* (374) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==374); + /* (375) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==375); + /* (376) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=376); + /* (377) tconscomma ::= */ yytestcase(yyruleno==377); + /* (378) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=378); + /* (379) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=379); + /* (380) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=380); + /* (381) oneselect ::= values */ yytestcase(yyruleno==381); + /* (382) sclp ::= selcollist COMMA */ yytestcase(yyruleno==382); + /* (383) as ::= ID|STRING */ yytestcase(yyruleno==383); + /* (384) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=384); + /* (385) returning ::= */ yytestcase(yyruleno==385); + /* (386) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=386); + /* (387) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==387); + /* (388) case_operand ::= expr */ yytestcase(yyruleno==388); + /* (389) exprlist ::= nexprlist */ yytestcase(yyruleno==389); + /* (390) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=390); + /* (391) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=391); + /* (392) nmnum ::= ON */ yytestcase(yyruleno==392); + /* (393) nmnum ::= DELETE */ yytestcase(yyruleno==393); + /* (394) nmnum ::= DEFAULT */ yytestcase(yyruleno==394); + /* (395) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==395); + /* (396) foreach_clause ::= */ yytestcase(yyruleno==396); + /* (397) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==397); + /* (398) tridxby ::= */ yytestcase(yyruleno==398); + /* (399) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==399); + /* (400) database_kw_opt ::= */ yytestcase(yyruleno==400); + /* (401) kwcolumn_opt ::= */ yytestcase(yyruleno==401); + /* (402) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==402); + /* (403) vtabarglist ::= vtabarg */ yytestcase(yyruleno==403); + /* (404) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==404); + /* (405) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==405); + /* (406) anylist ::= */ yytestcase(yyruleno==406); + /* (407) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==407); + /* (408) anylist ::= anylist ANY */ yytestcase(yyruleno==408); + /* (409) with ::= */ yytestcase(yyruleno==409); + /* (410) windowdefn_list ::= windowdefn (OPTIMIZED OUT) */ assert(yyruleno!=410); + /* (411) window ::= frame_opt (OPTIMIZED OUT) */ assert(yyruleno!=411); + break; +/********** End reduce actions ************************************************/ + }; + assert( yyrulenoYY_MAX_SHIFT && yyact<=YY_MAX_SHIFTREDUCE) ); + + /* It is not possible for a REDUCE to be followed by an error */ + assert( yyact!=YY_ERROR_ACTION ); + + yymsp += yysize+1; + yypParser->yytos = yymsp; + yymsp->stateno = (YYACTIONTYPE)yyact; + yymsp->major = (YYCODETYPE)yygoto; + yyTraceShift(yypParser, yyact, "... then shift"); + return yyact; +} + +/* +** The following code executes when the parse fails +*/ +#ifndef YYNOERRORRECOVERY +static void yy_parse_failed( + yyParser *yypParser /* The parser */ +){ + sqlite3ParserARG_FETCH + sqlite3ParserCTX_FETCH +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); + } +#endif + while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser); + /* Here code is inserted which will be executed whenever the + ** parser fails */ +/************ Begin %parse_failure code ***************************************/ +/************ End %parse_failure code *****************************************/ + sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */ + sqlite3ParserCTX_STORE +} +#endif /* YYNOERRORRECOVERY */ + +/* +** The following code executes when a syntax error first occurs. +*/ +static void yy_syntax_error( + yyParser *yypParser, /* The parser */ + int yymajor, /* The major type of the error token */ + sqlite3ParserTOKENTYPE yyminor /* The minor type of the error token */ +){ + sqlite3ParserARG_FETCH + sqlite3ParserCTX_FETCH +#define TOKEN yyminor +/************ Begin %syntax_error code ****************************************/ + + UNUSED_PARAMETER(yymajor); /* Silence some compiler warnings */ + if( TOKEN.z[0] ){ + parserSyntaxError(pParse, &TOKEN); + }else{ + sqlite3ErrorMsg(pParse, "incomplete input"); + } +/************ End %syntax_error code ******************************************/ + sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */ + sqlite3ParserCTX_STORE +} + +/* +** The following is executed when the parser accepts +*/ +static void yy_accept( + yyParser *yypParser /* The parser */ +){ + sqlite3ParserARG_FETCH + sqlite3ParserCTX_FETCH +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); + } +#endif +#ifndef YYNOERRORRECOVERY + yypParser->yyerrcnt = -1; +#endif + assert( yypParser->yytos==yypParser->yystack ); + /* Here code is inserted which will be executed whenever the + ** parser accepts */ +/*********** Begin %parse_accept code *****************************************/ +/*********** End %parse_accept code *******************************************/ + sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */ + sqlite3ParserCTX_STORE +} + +/* The main parser program. +** The first argument is a pointer to a structure obtained from +** "sqlite3ParserAlloc" which describes the current state of the parser. +** The second argument is the major token number. The third is +** the minor token. The fourth optional argument is whatever the +** user wants (and specified in the grammar) and is available for +** use by the action routines. +** +** Inputs: +**
      +**
    • A pointer to the parser (an opaque structure.) +**
    • The major token number. +**
    • The minor token number. +**
    • An option argument of a grammar-specified type. +**
    +** +** Outputs: +** None. +*/ +SQLITE_PRIVATE void sqlite3Parser( + void *yyp, /* The parser */ + int yymajor, /* The major token code number */ + sqlite3ParserTOKENTYPE yyminor /* The value for the token */ + sqlite3ParserARG_PDECL /* Optional %extra_argument parameter */ +){ + YYMINORTYPE yyminorunion; + YYACTIONTYPE yyact; /* The parser action. */ +#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) + int yyendofinput; /* True if we are at the end of input */ +#endif +#ifdef YYERRORSYMBOL + int yyerrorhit = 0; /* True if yymajor has invoked an error */ +#endif + yyParser *yypParser = (yyParser*)yyp; /* The parser */ + sqlite3ParserCTX_FETCH + sqlite3ParserARG_STORE + + assert( yypParser->yytos!=0 ); +#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) + yyendofinput = (yymajor==0); +#endif + + yyact = yypParser->yytos->stateno; +#ifndef NDEBUG + if( yyTraceFILE ){ + if( yyact < YY_MIN_REDUCE ){ + fprintf(yyTraceFILE,"%sInput '%s' in state %d\n", + yyTracePrompt,yyTokenName[yymajor],yyact); + }else{ + fprintf(yyTraceFILE,"%sInput '%s' with pending reduce %d\n", + yyTracePrompt,yyTokenName[yymajor],yyact-YY_MIN_REDUCE); + } + } +#endif + + while(1){ /* Exit by "break" */ + assert( yypParser->yytos>=yypParser->yystack ); + assert( yyact==yypParser->yytos->stateno ); + yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact); + if( yyact >= YY_MIN_REDUCE ){ + unsigned int yyruleno = yyact - YY_MIN_REDUCE; /* Reduce by this rule */ +#ifndef NDEBUG + assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ); + if( yyTraceFILE ){ + int yysize = yyRuleInfoNRhs[yyruleno]; + if( yysize ){ + fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", + yyTracePrompt, + yyruleno, yyRuleName[yyruleno], + yyrulenoyytos[yysize].stateno); + }else{ + fprintf(yyTraceFILE, "%sReduce %d [%s]%s.\n", + yyTracePrompt, yyruleno, yyRuleName[yyruleno], + yyrulenoyytos - yypParser->yystack)>yypParser->yyhwm ){ + yypParser->yyhwm++; + assert( yypParser->yyhwm == + (int)(yypParser->yytos - yypParser->yystack)); + } +#endif + if( yypParser->yytos>=yypParser->yystackEnd ){ + if( yyGrowStack(yypParser) ){ + yyStackOverflow(yypParser); + break; + } + } + } + yyact = yy_reduce(yypParser,yyruleno,yymajor,yyminor sqlite3ParserCTX_PARAM); + }else if( yyact <= YY_MAX_SHIFTREDUCE ){ + yy_shift(yypParser,yyact,(YYCODETYPE)yymajor,yyminor); +#ifndef YYNOERRORRECOVERY + yypParser->yyerrcnt--; +#endif + break; + }else if( yyact==YY_ACCEPT_ACTION ){ + yypParser->yytos--; + yy_accept(yypParser); + return; + }else{ + assert( yyact == YY_ERROR_ACTION ); + yyminorunion.yy0 = yyminor; +#ifdef YYERRORSYMBOL + int yymx; +#endif +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt); + } +#endif +#ifdef YYERRORSYMBOL + /* A syntax error has occurred. + ** The response to an error depends upon whether or not the + ** grammar defines an error token "ERROR". + ** + ** This is what we do if the grammar does define ERROR: + ** + ** * Call the %syntax_error function. + ** + ** * Begin popping the stack until we enter a state where + ** it is legal to shift the error symbol, then shift + ** the error symbol. + ** + ** * Set the error count to three. + ** + ** * Begin accepting and shifting new tokens. No new error + ** processing will occur until three tokens have been + ** shifted successfully. + ** + */ + if( yypParser->yyerrcnt<0 ){ + yy_syntax_error(yypParser,yymajor,yyminor); + } + yymx = yypParser->yytos->major; + if( yymx==YYERRORSYMBOL || yyerrorhit ){ +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sDiscard input token %s\n", + yyTracePrompt,yyTokenName[yymajor]); + } +#endif + yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion); + yymajor = YYNOCODE; + }else{ + while( yypParser->yytos > yypParser->yystack ){ + yyact = yy_find_reduce_action(yypParser->yytos->stateno, + YYERRORSYMBOL); + if( yyact<=YY_MAX_SHIFTREDUCE ) break; + yy_pop_parser_stack(yypParser); + } + if( yypParser->yytos <= yypParser->yystack || yymajor==0 ){ + yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); + yy_parse_failed(yypParser); +#ifndef YYNOERRORRECOVERY + yypParser->yyerrcnt = -1; +#endif + yymajor = YYNOCODE; + }else if( yymx!=YYERRORSYMBOL ){ + yy_shift(yypParser,yyact,YYERRORSYMBOL,yyminor); + } + } + yypParser->yyerrcnt = 3; + yyerrorhit = 1; + if( yymajor==YYNOCODE ) break; + yyact = yypParser->yytos->stateno; +#elif defined(YYNOERRORRECOVERY) + /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to + ** do any kind of error recovery. Instead, simply invoke the syntax + ** error routine and continue going as if nothing had happened. + ** + ** Applications can set this macro (for example inside %include) if + ** they intend to abandon the parse upon the first syntax error seen. + */ + yy_syntax_error(yypParser,yymajor, yyminor); + yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); + break; +#else /* YYERRORSYMBOL is not defined */ + /* This is what we do if the grammar does not define ERROR: + ** + ** * Report an error message, and throw away the input token. + ** + ** * If the input token is $, then fail the parse. + ** + ** As before, subsequent error messages are suppressed until + ** three input tokens have been successfully shifted. + */ + if( yypParser->yyerrcnt<=0 ){ + yy_syntax_error(yypParser,yymajor, yyminor); + } + yypParser->yyerrcnt = 3; + yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); + if( yyendofinput ){ + yy_parse_failed(yypParser); +#ifndef YYNOERRORRECOVERY + yypParser->yyerrcnt = -1; +#endif + } + break; +#endif + } + } +#ifndef NDEBUG + if( yyTraceFILE ){ + yyStackEntry *i; + char cDiv = '['; + fprintf(yyTraceFILE,"%sReturn. Stack=",yyTracePrompt); + for(i=&yypParser->yystack[1]; i<=yypParser->yytos; i++){ + fprintf(yyTraceFILE,"%c%s", cDiv, yyTokenName[i->major]); + cDiv = ' '; + } + fprintf(yyTraceFILE,"]\n"); + } +#endif + return; +} + +/* +** Return the fallback token corresponding to canonical token iToken, or +** 0 if iToken has no fallback. +*/ +SQLITE_PRIVATE int sqlite3ParserFallback(int iToken){ +#ifdef YYFALLBACK + assert( iToken<(int)(sizeof(yyFallback)/sizeof(yyFallback[0])) ); + return yyFallback[iToken]; +#else + (void)iToken; + return 0; +#endif +} + +/************** End of parse.c ***********************************************/ +/************** Begin file tokenize.c ****************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** An tokenizer for SQL +** +** This file contains C code that splits an SQL input string up into +** individual tokens and sends those tokens one-by-one over to the +** parser for analysis. +*/ +/* #include "sqliteInt.h" */ +/* #include */ + +/* Character classes for tokenizing +** +** In the sqlite3GetToken() function, a switch() on aiClass[c] is implemented +** using a lookup table, whereas a switch() directly on c uses a binary search. +** The lookup table is much faster. To maximize speed, and to ensure that +** a lookup table is used, all of the classes need to be small integers and +** all of them need to be used within the switch. +*/ +#define CC_X 0 /* The letter 'x', or start of BLOB literal */ +#define CC_KYWD0 1 /* First letter of a keyword */ +#define CC_KYWD 2 /* Alphabetics or '_'. Usable in a keyword */ +#define CC_DIGIT 3 /* Digits */ +#define CC_DOLLAR 4 /* '$' */ +#define CC_VARALPHA 5 /* '@', '#', ':'. Alphabetic SQL variables */ +#define CC_VARNUM 6 /* '?'. Numeric SQL variables */ +#define CC_SPACE 7 /* Space characters */ +#define CC_QUOTE 8 /* '"', '\'', or '`'. String literals, quoted ids */ +#define CC_QUOTE2 9 /* '['. [...] style quoted ids */ +#define CC_PIPE 10 /* '|'. Bitwise OR or concatenate */ +#define CC_MINUS 11 /* '-'. Minus or SQL-style comment */ +#define CC_LT 12 /* '<'. Part of < or <= or <> */ +#define CC_GT 13 /* '>'. Part of > or >= */ +#define CC_EQ 14 /* '='. Part of = or == */ +#define CC_BANG 15 /* '!'. Part of != */ +#define CC_SLASH 16 /* '/'. / or c-style comment */ +#define CC_LP 17 /* '(' */ +#define CC_RP 18 /* ')' */ +#define CC_SEMI 19 /* ';' */ +#define CC_PLUS 20 /* '+' */ +#define CC_STAR 21 /* '*' */ +#define CC_PERCENT 22 /* '%' */ +#define CC_COMMA 23 /* ',' */ +#define CC_AND 24 /* '&' */ +#define CC_TILDA 25 /* '~' */ +#define CC_DOT 26 /* '.' */ +#define CC_ID 27 /* unicode characters usable in IDs */ +#define CC_ILLEGAL 28 /* Illegal character */ +#define CC_NUL 29 /* 0x00 */ +#define CC_BOM 30 /* First byte of UTF8 BOM: 0xEF 0xBB 0xBF */ + +static const unsigned char aiClass[] = { +#ifdef SQLITE_ASCII +/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */ +/* 0x */ 29, 28, 28, 28, 28, 28, 28, 28, 28, 7, 7, 28, 7, 7, 28, 28, +/* 1x */ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +/* 2x */ 7, 15, 8, 5, 4, 22, 24, 8, 17, 18, 21, 20, 23, 11, 26, 16, +/* 3x */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 19, 12, 14, 13, 6, +/* 4x */ 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* 5x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 9, 28, 28, 28, 2, +/* 6x */ 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* 7x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 28, 10, 28, 25, 28, +/* 8x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* 9x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* Ax */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* Bx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* Cx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* Dx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* Ex */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 30, +/* Fx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27 +#endif +#ifdef SQLITE_EBCDIC +/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */ +/* 0x */ 29, 28, 28, 28, 28, 7, 28, 28, 28, 28, 28, 28, 7, 7, 28, 28, +/* 1x */ 28, 28, 28, 28, 28, 7, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +/* 2x */ 28, 28, 28, 28, 28, 7, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +/* 3x */ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +/* 4x */ 7, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 26, 12, 17, 20, 10, +/* 5x */ 24, 28, 28, 28, 28, 28, 28, 28, 28, 28, 15, 4, 21, 18, 19, 28, +/* 6x */ 11, 16, 28, 28, 28, 28, 28, 28, 28, 28, 28, 23, 22, 2, 13, 6, +/* 7x */ 28, 28, 28, 28, 28, 28, 28, 28, 28, 8, 5, 5, 5, 8, 14, 8, +/* 8x */ 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 28, 28, 28, 28, 28, 28, +/* 9x */ 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 28, 28, 28, 28, 28, 28, +/* Ax */ 28, 25, 1, 1, 1, 1, 1, 0, 2, 2, 28, 28, 28, 28, 28, 28, +/* Bx */ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 9, 28, 28, 28, 28, 28, +/* Cx */ 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 28, 28, 28, 28, 28, 28, +/* Dx */ 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 28, 28, 28, 28, 28, 28, +/* Ex */ 28, 28, 1, 1, 1, 1, 1, 0, 2, 2, 28, 28, 28, 28, 28, 28, +/* Fx */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 28, 28, 28, 28, 28, 28, +#endif +}; + +/* +** The charMap() macro maps alphabetic characters (only) into their +** lower-case ASCII equivalent. On ASCII machines, this is just +** an upper-to-lower case map. On EBCDIC machines we also need +** to adjust the encoding. The mapping is only valid for alphabetics +** which are the only characters for which this feature is used. +** +** Used by keywordhash.h +*/ +#ifdef SQLITE_ASCII +# define charMap(X) sqlite3UpperToLower[(unsigned char)X] +#endif +#ifdef SQLITE_EBCDIC +# define charMap(X) ebcdicToAscii[(unsigned char)X] +const unsigned char ebcdicToAscii[] = { +/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 3x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 5x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, /* 6x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7x */ + 0, 97, 98, 99,100,101,102,103,104,105, 0, 0, 0, 0, 0, 0, /* 8x */ + 0,106,107,108,109,110,111,112,113,114, 0, 0, 0, 0, 0, 0, /* 9x */ + 0, 0,115,116,117,118,119,120,121,122, 0, 0, 0, 0, 0, 0, /* Ax */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Bx */ + 0, 97, 98, 99,100,101,102,103,104,105, 0, 0, 0, 0, 0, 0, /* Cx */ + 0,106,107,108,109,110,111,112,113,114, 0, 0, 0, 0, 0, 0, /* Dx */ + 0, 0,115,116,117,118,119,120,121,122, 0, 0, 0, 0, 0, 0, /* Ex */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Fx */ +}; +#endif + +/* +** The sqlite3KeywordCode function looks up an identifier to determine if +** it is a keyword. If it is a keyword, the token code of that keyword is +** returned. If the input is not a keyword, TK_ID is returned. +** +** The implementation of this routine was generated by a program, +** mkkeywordhash.c, located in the tool subdirectory of the distribution. +** The output of the mkkeywordhash.c program is written into a file +** named keywordhash.h and then included into this source file by +** the #include below. +*/ +/************** Include keywordhash.h in the middle of tokenize.c ************/ +/************** Begin file keywordhash.h *************************************/ +/***** This file contains automatically generated code ****** +** +** The code in this file has been automatically generated by +** +** sqlite/tool/mkkeywordhash.c +** +** The code in this file implements a function that determines whether +** or not a given identifier is really an SQL keyword. The same thing +** might be implemented more directly using a hand-written hash table. +** But by using this automatically generated code, the size of the code +** is substantially reduced. This is important for embedded applications +** on platforms with limited memory. +*/ +/* Hash score: 231 */ +/* zKWText[] encodes 1007 bytes of keyword text in 667 bytes */ +/* REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECT */ +/* ABLEFTHENDEFERRABLELSEXCLUDELETEMPORARYISNULLSAVEPOINTERSECT */ +/* IESNOTNULLIKEXCEPTRANSACTIONATURALTERAISEXCLUSIVEXISTS */ +/* CONSTRAINTOFFSETRIGGERANGENERATEDETACHAVINGLOBEGINNEREFERENCES */ +/* UNIQUERYWITHOUTERELEASEATTACHBETWEENOTHINGROUPSCASCADEFAULT */ +/* CASECOLLATECREATECURRENT_DATEIMMEDIATEJOINSERTMATCHPLANALYZE */ +/* PRAGMATERIALIZEDEFERREDISTINCTUPDATEVALUESVIRTUALWAYSWHENWHERE */ +/* CURSIVEABORTAFTERENAMEANDROPARTITIONAUTOINCREMENTCASTCOLUMN */ +/* COMMITCONFLICTCROSSCURRENT_TIMESTAMPRECEDINGFAILASTFILTER */ +/* EPLACEFIRSTFOLLOWINGFROMFULLIMITIFORDERESTRICTOTHERSOVER */ +/* ETURNINGRIGHTROLLBACKROWSUNBOUNDEDUNIONUSINGVACUUMVIEWINDOWBY */ +/* INITIALLYPRIMARY */ +static const char zKWText[666] = { + 'R','E','I','N','D','E','X','E','D','E','S','C','A','P','E','A','C','H', + 'E','C','K','E','Y','B','E','F','O','R','E','I','G','N','O','R','E','G', + 'E','X','P','L','A','I','N','S','T','E','A','D','D','A','T','A','B','A', + 'S','E','L','E','C','T','A','B','L','E','F','T','H','E','N','D','E','F', + 'E','R','R','A','B','L','E','L','S','E','X','C','L','U','D','E','L','E', + 'T','E','M','P','O','R','A','R','Y','I','S','N','U','L','L','S','A','V', + 'E','P','O','I','N','T','E','R','S','E','C','T','I','E','S','N','O','T', + 'N','U','L','L','I','K','E','X','C','E','P','T','R','A','N','S','A','C', + 'T','I','O','N','A','T','U','R','A','L','T','E','R','A','I','S','E','X', + 'C','L','U','S','I','V','E','X','I','S','T','S','C','O','N','S','T','R', + 'A','I','N','T','O','F','F','S','E','T','R','I','G','G','E','R','A','N', + 'G','E','N','E','R','A','T','E','D','E','T','A','C','H','A','V','I','N', + 'G','L','O','B','E','G','I','N','N','E','R','E','F','E','R','E','N','C', + 'E','S','U','N','I','Q','U','E','R','Y','W','I','T','H','O','U','T','E', + 'R','E','L','E','A','S','E','A','T','T','A','C','H','B','E','T','W','E', + 'E','N','O','T','H','I','N','G','R','O','U','P','S','C','A','S','C','A', + 'D','E','F','A','U','L','T','C','A','S','E','C','O','L','L','A','T','E', + 'C','R','E','A','T','E','C','U','R','R','E','N','T','_','D','A','T','E', + 'I','M','M','E','D','I','A','T','E','J','O','I','N','S','E','R','T','M', + 'A','T','C','H','P','L','A','N','A','L','Y','Z','E','P','R','A','G','M', + 'A','T','E','R','I','A','L','I','Z','E','D','E','F','E','R','R','E','D', + 'I','S','T','I','N','C','T','U','P','D','A','T','E','V','A','L','U','E', + 'S','V','I','R','T','U','A','L','W','A','Y','S','W','H','E','N','W','H', + 'E','R','E','C','U','R','S','I','V','E','A','B','O','R','T','A','F','T', + 'E','R','E','N','A','M','E','A','N','D','R','O','P','A','R','T','I','T', + 'I','O','N','A','U','T','O','I','N','C','R','E','M','E','N','T','C','A', + 'S','T','C','O','L','U','M','N','C','O','M','M','I','T','C','O','N','F', + 'L','I','C','T','C','R','O','S','S','C','U','R','R','E','N','T','_','T', + 'I','M','E','S','T','A','M','P','R','E','C','E','D','I','N','G','F','A', + 'I','L','A','S','T','F','I','L','T','E','R','E','P','L','A','C','E','F', + 'I','R','S','T','F','O','L','L','O','W','I','N','G','F','R','O','M','F', + 'U','L','L','I','M','I','T','I','F','O','R','D','E','R','E','S','T','R', + 'I','C','T','O','T','H','E','R','S','O','V','E','R','E','T','U','R','N', + 'I','N','G','R','I','G','H','T','R','O','L','L','B','A','C','K','R','O', + 'W','S','U','N','B','O','U','N','D','E','D','U','N','I','O','N','U','S', + 'I','N','G','V','A','C','U','U','M','V','I','E','W','I','N','D','O','W', + 'B','Y','I','N','I','T','I','A','L','L','Y','P','R','I','M','A','R','Y', +}; +/* aKWHash[i] is the hash value for the i-th keyword */ +static const unsigned char aKWHash[127] = { + 84, 92, 134, 82, 105, 29, 0, 0, 94, 0, 85, 72, 0, + 53, 35, 86, 15, 0, 42, 97, 54, 89, 135, 19, 0, 0, + 140, 0, 40, 129, 0, 22, 107, 0, 9, 0, 0, 123, 80, + 0, 78, 6, 0, 65, 103, 147, 0, 136, 115, 0, 0, 48, + 0, 90, 24, 0, 17, 0, 27, 70, 23, 26, 5, 60, 142, + 110, 122, 0, 73, 91, 71, 145, 61, 120, 74, 0, 49, 0, + 11, 41, 0, 113, 0, 0, 0, 109, 10, 111, 116, 125, 14, + 50, 124, 0, 100, 0, 18, 121, 144, 56, 130, 139, 88, 83, + 37, 30, 126, 0, 0, 108, 51, 131, 128, 0, 34, 0, 0, + 132, 0, 98, 38, 39, 0, 20, 45, 117, 93, +}; +/* aKWNext[] forms the hash collision chain. If aKWHash[i]==0 +** then the i-th keyword has no more hash collisions. Otherwise, +** the next keyword with the same hash is aKWHash[i]-1. */ +static const unsigned char aKWNext[148] = {0, + 0, 0, 0, 0, 4, 0, 43, 0, 0, 106, 114, 0, 0, + 0, 2, 0, 0, 143, 0, 0, 0, 13, 0, 0, 0, 0, + 141, 0, 0, 119, 52, 0, 0, 137, 12, 0, 0, 62, 0, + 138, 0, 133, 0, 0, 36, 0, 0, 28, 77, 0, 0, 0, + 0, 59, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 69, 0, 0, 0, 0, 0, 146, 3, 0, 58, 0, 1, + 75, 0, 0, 0, 31, 0, 0, 0, 0, 0, 127, 0, 104, + 0, 64, 66, 63, 0, 0, 0, 0, 0, 46, 0, 16, 8, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 101, 0, + 112, 21, 7, 67, 0, 79, 96, 118, 0, 0, 68, 0, 0, + 99, 44, 0, 55, 0, 76, 0, 95, 32, 33, 57, 25, 0, + 102, 0, 0, 87, +}; +/* aKWLen[i] is the length (in bytes) of the i-th keyword */ +static const unsigned char aKWLen[148] = {0, + 7, 7, 5, 4, 6, 4, 5, 3, 6, 7, 3, 6, 6, + 7, 7, 3, 8, 2, 6, 5, 4, 4, 3, 10, 4, 7, + 6, 9, 4, 2, 6, 5, 9, 9, 4, 7, 3, 2, 4, + 4, 6, 11, 6, 2, 7, 5, 5, 9, 6, 10, 4, 6, + 2, 3, 7, 5, 9, 6, 6, 4, 5, 5, 10, 6, 5, + 7, 4, 5, 7, 6, 7, 7, 6, 5, 7, 3, 7, 4, + 7, 6, 12, 9, 4, 6, 5, 4, 7, 6, 12, 8, 8, + 2, 6, 6, 7, 6, 4, 5, 9, 5, 5, 6, 3, 4, + 9, 13, 2, 2, 4, 6, 6, 8, 5, 17, 12, 7, 9, + 4, 4, 6, 7, 5, 9, 4, 4, 5, 2, 5, 8, 6, + 4, 9, 5, 8, 4, 3, 9, 5, 5, 6, 4, 6, 2, + 2, 9, 3, 7, +}; +/* aKWOffset[i] is the index into zKWText[] of the start of +** the text for the i-th keyword. */ +static const unsigned short int aKWOffset[148] = {0, + 0, 2, 2, 8, 9, 14, 16, 20, 23, 25, 25, 29, 33, + 36, 41, 46, 48, 53, 54, 59, 62, 65, 67, 69, 78, 81, + 86, 90, 90, 94, 99, 101, 105, 111, 119, 123, 123, 123, 126, + 129, 132, 137, 142, 146, 147, 152, 156, 160, 168, 174, 181, 184, + 184, 187, 189, 195, 198, 206, 211, 216, 219, 222, 226, 236, 239, + 244, 244, 248, 252, 259, 265, 271, 277, 277, 283, 284, 288, 295, + 299, 306, 312, 324, 333, 335, 341, 346, 348, 355, 359, 370, 377, + 378, 385, 391, 397, 402, 408, 412, 415, 424, 429, 433, 439, 441, + 444, 453, 455, 457, 466, 470, 476, 482, 490, 495, 495, 495, 511, + 520, 523, 527, 532, 539, 544, 553, 557, 560, 565, 567, 571, 579, + 585, 588, 597, 602, 610, 610, 614, 623, 628, 633, 639, 642, 645, + 648, 650, 655, 659, +}; +/* aKWCode[i] is the parser symbol code for the i-th keyword */ +static const unsigned char aKWCode[148] = {0, + TK_REINDEX, TK_INDEXED, TK_INDEX, TK_DESC, TK_ESCAPE, + TK_EACH, TK_CHECK, TK_KEY, TK_BEFORE, TK_FOREIGN, + TK_FOR, TK_IGNORE, TK_LIKE_KW, TK_EXPLAIN, TK_INSTEAD, + TK_ADD, TK_DATABASE, TK_AS, TK_SELECT, TK_TABLE, + TK_JOIN_KW, TK_THEN, TK_END, TK_DEFERRABLE, TK_ELSE, + TK_EXCLUDE, TK_DELETE, TK_TEMP, TK_TEMP, TK_OR, + TK_ISNULL, TK_NULLS, TK_SAVEPOINT, TK_INTERSECT, TK_TIES, + TK_NOTNULL, TK_NOT, TK_NO, TK_NULL, TK_LIKE_KW, + TK_EXCEPT, TK_TRANSACTION,TK_ACTION, TK_ON, TK_JOIN_KW, + TK_ALTER, TK_RAISE, TK_EXCLUSIVE, TK_EXISTS, TK_CONSTRAINT, + TK_INTO, TK_OFFSET, TK_OF, TK_SET, TK_TRIGGER, + TK_RANGE, TK_GENERATED, TK_DETACH, TK_HAVING, TK_LIKE_KW, + TK_BEGIN, TK_JOIN_KW, TK_REFERENCES, TK_UNIQUE, TK_QUERY, + TK_WITHOUT, TK_WITH, TK_JOIN_KW, TK_RELEASE, TK_ATTACH, + TK_BETWEEN, TK_NOTHING, TK_GROUPS, TK_GROUP, TK_CASCADE, + TK_ASC, TK_DEFAULT, TK_CASE, TK_COLLATE, TK_CREATE, + TK_CTIME_KW, TK_IMMEDIATE, TK_JOIN, TK_INSERT, TK_MATCH, + TK_PLAN, TK_ANALYZE, TK_PRAGMA, TK_MATERIALIZED, TK_DEFERRED, + TK_DISTINCT, TK_IS, TK_UPDATE, TK_VALUES, TK_VIRTUAL, + TK_ALWAYS, TK_WHEN, TK_WHERE, TK_RECURSIVE, TK_ABORT, + TK_AFTER, TK_RENAME, TK_AND, TK_DROP, TK_PARTITION, + TK_AUTOINCR, TK_TO, TK_IN, TK_CAST, TK_COLUMNKW, + TK_COMMIT, TK_CONFLICT, TK_JOIN_KW, TK_CTIME_KW, TK_CTIME_KW, + TK_CURRENT, TK_PRECEDING, TK_FAIL, TK_LAST, TK_FILTER, + TK_REPLACE, TK_FIRST, TK_FOLLOWING, TK_FROM, TK_JOIN_KW, + TK_LIMIT, TK_IF, TK_ORDER, TK_RESTRICT, TK_OTHERS, + TK_OVER, TK_RETURNING, TK_JOIN_KW, TK_ROLLBACK, TK_ROWS, + TK_ROW, TK_UNBOUNDED, TK_UNION, TK_USING, TK_VACUUM, + TK_VIEW, TK_WINDOW, TK_DO, TK_BY, TK_INITIALLY, + TK_ALL, TK_PRIMARY, +}; +/* Hash table decoded: +** 0: INSERT +** 1: IS +** 2: ROLLBACK TRIGGER +** 3: IMMEDIATE +** 4: PARTITION +** 5: TEMP +** 6: +** 7: +** 8: VALUES WITHOUT +** 9: +** 10: MATCH +** 11: NOTHING +** 12: +** 13: OF +** 14: TIES IGNORE +** 15: PLAN +** 16: INSTEAD INDEXED +** 17: +** 18: TRANSACTION RIGHT +** 19: WHEN +** 20: SET HAVING +** 21: MATERIALIZED IF +** 22: ROWS +** 23: SELECT +** 24: +** 25: +** 26: VACUUM SAVEPOINT +** 27: +** 28: LIKE UNION VIRTUAL REFERENCES +** 29: RESTRICT +** 30: +** 31: THEN REGEXP +** 32: TO +** 33: +** 34: BEFORE +** 35: +** 36: +** 37: FOLLOWING COLLATE CASCADE +** 38: CREATE +** 39: +** 40: CASE REINDEX +** 41: EACH +** 42: +** 43: QUERY +** 44: AND ADD +** 45: PRIMARY ANALYZE +** 46: +** 47: ROW ASC DETACH +** 48: CURRENT_TIME CURRENT_DATE +** 49: +** 50: +** 51: EXCLUSIVE TEMPORARY +** 52: +** 53: DEFERRED +** 54: DEFERRABLE +** 55: +** 56: DATABASE +** 57: +** 58: DELETE VIEW GENERATED +** 59: ATTACH +** 60: END +** 61: EXCLUDE +** 62: ESCAPE DESC +** 63: GLOB +** 64: WINDOW ELSE +** 65: COLUMN +** 66: FIRST +** 67: +** 68: GROUPS ALL +** 69: DISTINCT DROP KEY +** 70: BETWEEN +** 71: INITIALLY +** 72: BEGIN +** 73: FILTER CHECK ACTION +** 74: GROUP INDEX +** 75: +** 76: EXISTS DEFAULT +** 77: +** 78: FOR CURRENT_TIMESTAMP +** 79: EXCEPT +** 80: +** 81: CROSS +** 82: +** 83: +** 84: +** 85: CAST +** 86: FOREIGN AUTOINCREMENT +** 87: COMMIT +** 88: CURRENT AFTER ALTER +** 89: FULL FAIL CONFLICT +** 90: EXPLAIN +** 91: CONSTRAINT +** 92: FROM ALWAYS +** 93: +** 94: ABORT +** 95: +** 96: AS DO +** 97: REPLACE WITH RELEASE +** 98: BY RENAME +** 99: RANGE RAISE +** 100: OTHERS +** 101: USING NULLS +** 102: PRAGMA +** 103: JOIN ISNULL OFFSET +** 104: NOT +** 105: OR LAST LEFT +** 106: LIMIT +** 107: +** 108: +** 109: IN +** 110: INTO +** 111: OVER RECURSIVE +** 112: ORDER OUTER +** 113: +** 114: INTERSECT UNBOUNDED +** 115: +** 116: +** 117: RETURNING ON +** 118: +** 119: WHERE +** 120: NO INNER +** 121: NULL +** 122: +** 123: TABLE +** 124: NATURAL NOTNULL +** 125: PRECEDING +** 126: UPDATE UNIQUE +*/ +/* Check to see if z[0..n-1] is a keyword. If it is, write the +** parser symbol code for that keyword into *pType. Always +** return the integer n (the length of the token). */ +static i64 keywordCode(const char *z, i64 n, int *pType){ + i64 i, j; + const char *zKW; + assert( n>=2 ); + i = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n*1) % 127; + for(i=(int)aKWHash[i]; i>0; i=aKWNext[i]){ + if( aKWLen[i]!=n ) continue; + zKW = &zKWText[aKWOffset[i]]; +#ifdef SQLITE_ASCII + if( (z[0]&~0x20)!=zKW[0] ) continue; + if( (z[1]&~0x20)!=zKW[1] ) continue; + j = 2; + while( j=2 ) keywordCode((char*)z, n, &id); + return id; +} +#define SQLITE_N_KEYWORD 147 +SQLITE_API int sqlite3_keyword_name(int i,const char **pzName,int *pnName){ + if( i<0 || i>=SQLITE_N_KEYWORD ) return SQLITE_ERROR; + i++; + *pzName = zKWText + aKWOffset[i]; + *pnName = aKWLen[i]; + return SQLITE_OK; +} +SQLITE_API int sqlite3_keyword_count(void){ return SQLITE_N_KEYWORD; } +SQLITE_API int sqlite3_keyword_check(const char *zName, int nName){ + return TK_ID!=sqlite3KeywordCode((const u8*)zName, nName); +} + +/************** End of keywordhash.h *****************************************/ +/************** Continuing where we left off in tokenize.c *******************/ + + +/* +** If X is a character that can be used in an identifier then +** IdChar(X) will be true. Otherwise it is false. +** +** For ASCII, any character with the high-order bit set is +** allowed in an identifier. For 7-bit characters, +** sqlite3IsIdChar[X] must be 1. +** +** For EBCDIC, the rules are more complex but have the same +** end result. +** +** Ticket #1066. the SQL standard does not allow '$' in the +** middle of identifiers. But many SQL implementations do. +** SQLite will allow '$' in identifiers for compatibility. +** But the feature is undocumented. +*/ +#ifdef SQLITE_ASCII +#define IdChar(C) ((sqlite3CtypeMap[(unsigned char)C]&0x46)!=0) +#endif +#ifdef SQLITE_EBCDIC +SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[] = { +/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */ + 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 4x */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, /* 5x */ + 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, /* 6x */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, /* 7x */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, /* 8x */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, /* 9x */ + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, /* Ax */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* Bx */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Cx */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Dx */ + 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Ex */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, /* Fx */ +}; +#define IdChar(C) (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40])) +#endif + +/* Make the IdChar function accessible from ctime.c and alter.c */ +SQLITE_PRIVATE int sqlite3IsIdChar(u8 c){ return IdChar(c); } + +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** Return the id of the next token in string (*pz). Before returning, set +** (*pz) to point to the byte following the parsed token. +*/ +static int getToken(const unsigned char **pz){ + const unsigned char *z = *pz; + int t; /* Token type to return */ + do { + z += sqlite3GetToken(z, &t); + }while( t==TK_SPACE || t==TK_COMMENT ); + if( t==TK_ID + || t==TK_STRING + || t==TK_JOIN_KW + || t==TK_WINDOW + || t==TK_OVER + || sqlite3ParserFallback(t)==TK_ID + ){ + t = TK_ID; + } + *pz = z; + return t; +} + +/* +** The following three functions are called immediately after the tokenizer +** reads the keywords WINDOW, OVER and FILTER, respectively, to determine +** whether the token should be treated as a keyword or an SQL identifier. +** This cannot be handled by the usual lemon %fallback method, due to +** the ambiguity in some constructions. e.g. +** +** SELECT sum(x) OVER ... +** +** In the above, "OVER" might be a keyword, or it might be an alias for the +** sum(x) expression. If a "%fallback ID OVER" directive were added to +** grammar, then SQLite would always treat "OVER" as an alias, making it +** impossible to call a window-function without a FILTER clause. +** +** WINDOW is treated as a keyword if: +** +** * the following token is an identifier, or a keyword that can fallback +** to being an identifier, and +** * the token after than one is TK_AS. +** +** OVER is a keyword if: +** +** * the previous token was TK_RP, and +** * the next token is either TK_LP or an identifier. +** +** FILTER is a keyword if: +** +** * the previous token was TK_RP, and +** * the next token is TK_LP. +*/ +static int analyzeWindowKeyword(const unsigned char *z){ + int t; + t = getToken(&z); + if( t!=TK_ID ) return TK_ID; + t = getToken(&z); + if( t!=TK_AS ) return TK_ID; + return TK_WINDOW; +} +static int analyzeOverKeyword(const unsigned char *z, int lastToken){ + if( lastToken==TK_RP ){ + int t = getToken(&z); + if( t==TK_LP || t==TK_ID ) return TK_OVER; + } + return TK_ID; +} +static int analyzeFilterKeyword(const unsigned char *z, int lastToken){ + if( lastToken==TK_RP && getToken(&z)==TK_LP ){ + return TK_FILTER; + } + return TK_ID; +} +#endif /* SQLITE_OMIT_WINDOWFUNC */ + +/* +** Return the length (in bytes) of the token that begins at z[0]. +** Store the token type in *tokenType before returning. +*/ +SQLITE_PRIVATE i64 sqlite3GetToken(const unsigned char *z, int *tokenType){ + i64 i; + int c; + switch( aiClass[*z] ){ /* Switch on the character-class of the first byte + ** of the token. See the comment on the CC_ defines + ** above. */ + case CC_SPACE: { + testcase( z[0]==' ' ); + testcase( z[0]=='\t' ); + testcase( z[0]=='\n' ); + testcase( z[0]=='\f' ); + testcase( z[0]=='\r' ); + for(i=1; sqlite3Isspace(z[i]); i++){} + *tokenType = TK_SPACE; + return i; + } + case CC_MINUS: { + if( z[1]=='-' ){ + for(i=2; (c=z[i])!=0 && c!='\n'; i++){} + *tokenType = TK_COMMENT; + return i; + }else if( z[1]=='>' ){ + *tokenType = TK_PTR; + return 2 + (z[2]=='>'); + } + *tokenType = TK_MINUS; + return 1; + } + case CC_LP: { + *tokenType = TK_LP; + return 1; + } + case CC_RP: { + *tokenType = TK_RP; + return 1; + } + case CC_SEMI: { + *tokenType = TK_SEMI; + return 1; + } + case CC_PLUS: { + *tokenType = TK_PLUS; + return 1; + } + case CC_STAR: { + *tokenType = TK_STAR; + return 1; + } + case CC_SLASH: { + if( z[1]!='*' || z[2]==0 ){ + *tokenType = TK_SLASH; + return 1; + } + for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){} + if( c ) i++; + *tokenType = TK_COMMENT; + return i; + } + case CC_PERCENT: { + *tokenType = TK_REM; + return 1; + } + case CC_EQ: { + *tokenType = TK_EQ; + return 1 + (z[1]=='='); + } + case CC_LT: { + if( (c=z[1])=='=' ){ + *tokenType = TK_LE; + return 2; + }else if( c=='>' ){ + *tokenType = TK_NE; + return 2; + }else if( c=='<' ){ + *tokenType = TK_LSHIFT; + return 2; + }else{ + *tokenType = TK_LT; + return 1; + } + } + case CC_GT: { + if( (c=z[1])=='=' ){ + *tokenType = TK_GE; + return 2; + }else if( c=='>' ){ + *tokenType = TK_RSHIFT; + return 2; + }else{ + *tokenType = TK_GT; + return 1; + } + } + case CC_BANG: { + if( z[1]!='=' ){ + *tokenType = TK_ILLEGAL; + return 1; + }else{ + *tokenType = TK_NE; + return 2; + } + } + case CC_PIPE: { + if( z[1]!='|' ){ + *tokenType = TK_BITOR; + return 1; + }else{ + *tokenType = TK_CONCAT; + return 2; + } + } + case CC_COMMA: { + *tokenType = TK_COMMA; + return 1; + } + case CC_AND: { + *tokenType = TK_BITAND; + return 1; + } + case CC_TILDA: { + *tokenType = TK_BITNOT; + return 1; + } + case CC_QUOTE: { + int delim = z[0]; + testcase( delim=='`' ); + testcase( delim=='\'' ); + testcase( delim=='"' ); + for(i=1; (c=z[i])!=0; i++){ + if( c==delim ){ + if( z[i+1]==delim ){ + i++; + }else{ + break; + } + } + } + if( c=='\'' ){ + *tokenType = TK_STRING; + return i+1; + }else if( c!=0 ){ + *tokenType = TK_ID; + return i+1; + }else{ + *tokenType = TK_ILLEGAL; + return i; + } + } + case CC_DOT: { +#ifndef SQLITE_OMIT_FLOATING_POINT + if( !sqlite3Isdigit(z[1]) ) +#endif + { + *tokenType = TK_DOT; + return 1; + } + /* If the next character is a digit, this is a floating point + ** number that begins with ".". Fall thru into the next case */ + /* no break */ deliberate_fall_through + } + case CC_DIGIT: { + testcase( z[0]=='0' ); testcase( z[0]=='1' ); testcase( z[0]=='2' ); + testcase( z[0]=='3' ); testcase( z[0]=='4' ); testcase( z[0]=='5' ); + testcase( z[0]=='6' ); testcase( z[0]=='7' ); testcase( z[0]=='8' ); + testcase( z[0]=='9' ); testcase( z[0]=='.' ); + *tokenType = TK_INTEGER; +#ifndef SQLITE_OMIT_HEX_INTEGER + if( z[0]=='0' && (z[1]=='x' || z[1]=='X') && sqlite3Isxdigit(z[2]) ){ + for(i=3; 1; i++){ + if( sqlite3Isxdigit(z[i])==0 ){ + if( z[i]==SQLITE_DIGIT_SEPARATOR ){ + *tokenType = TK_QNUMBER; + }else{ + break; + } + } + } + }else +#endif + { + for(i=0; 1; i++){ + if( sqlite3Isdigit(z[i])==0 ){ + if( z[i]==SQLITE_DIGIT_SEPARATOR ){ + *tokenType = TK_QNUMBER; + }else{ + break; + } + } + } +#ifndef SQLITE_OMIT_FLOATING_POINT + if( z[i]=='.' ){ + if( *tokenType==TK_INTEGER ) *tokenType = TK_FLOAT; + for(i++; 1; i++){ + if( sqlite3Isdigit(z[i])==0 ){ + if( z[i]==SQLITE_DIGIT_SEPARATOR ){ + *tokenType = TK_QNUMBER; + }else{ + break; + } + } + } + } + if( (z[i]=='e' || z[i]=='E') && + ( sqlite3Isdigit(z[i+1]) + || ((z[i+1]=='+' || z[i+1]=='-') && sqlite3Isdigit(z[i+2])) + ) + ){ + if( *tokenType==TK_INTEGER ) *tokenType = TK_FLOAT; + for(i+=2; 1; i++){ + if( sqlite3Isdigit(z[i])==0 ){ + if( z[i]==SQLITE_DIGIT_SEPARATOR ){ + *tokenType = TK_QNUMBER; + }else{ + break; + } + } + } + } +#endif + } + while( IdChar(z[i]) ){ + *tokenType = TK_ILLEGAL; + i++; + } + return i; + } + case CC_QUOTE2: { + for(i=1, c=z[0]; c!=']' && (c=z[i])!=0; i++){} + *tokenType = c==']' ? TK_ID : TK_ILLEGAL; + return i; + } + case CC_VARNUM: { + *tokenType = TK_VARIABLE; + for(i=1; sqlite3Isdigit(z[i]); i++){} + return i; + } + case CC_DOLLAR: + case CC_VARALPHA: { + i64 n = 0; + testcase( z[0]=='$' ); testcase( z[0]=='@' ); + testcase( z[0]==':' ); testcase( z[0]=='#' ); + *tokenType = TK_VARIABLE; + for(i=1; (c=z[i])!=0; i++){ + if( IdChar(c) ){ + n++; +#ifndef SQLITE_OMIT_TCL_VARIABLE + }else if( c=='(' && n>0 ){ + do{ + i++; + }while( (c=z[i])!=0 && !sqlite3Isspace(c) && c!=')' ); + if( c==')' ){ + i++; + }else{ + *tokenType = TK_ILLEGAL; + } + break; + }else if( c==':' && z[i+1]==':' ){ + i++; +#endif + }else{ + break; + } + } + if( n==0 ) *tokenType = TK_ILLEGAL; + return i; + } + case CC_KYWD0: { + if( aiClass[z[1]]>CC_KYWD ){ i = 1; break; } + for(i=2; aiClass[z[i]]<=CC_KYWD; i++){} + if( IdChar(z[i]) ){ + /* This token started out using characters that can appear in keywords, + ** but z[i] is a character not allowed within keywords, so this must + ** be an identifier instead */ + i++; + break; + } + *tokenType = TK_ID; + return keywordCode((char*)z, i, tokenType); + } + case CC_X: { +#ifndef SQLITE_OMIT_BLOB_LITERAL + testcase( z[0]=='x' ); testcase( z[0]=='X' ); + if( z[1]=='\'' ){ + *tokenType = TK_BLOB; + for(i=2; sqlite3Isxdigit(z[i]); i++){} + if( z[i]!='\'' || i%2 ){ + *tokenType = TK_ILLEGAL; + while( z[i] && z[i]!='\'' ){ i++; } + } + if( z[i] ) i++; + return i; + } +#endif + /* If it is not a BLOB literal, then it must be an ID, since no + ** SQL keywords start with the letter 'x'. Fall through */ + /* no break */ deliberate_fall_through + } + case CC_KYWD: + case CC_ID: { + i = 1; + break; + } + case CC_BOM: { + if( z[1]==0xbb && z[2]==0xbf ){ + *tokenType = TK_SPACE; + return 3; + } + i = 1; + break; + } + case CC_NUL: { + *tokenType = TK_ILLEGAL; + return 0; + } + default: { + *tokenType = TK_ILLEGAL; + return 1; + } + } + while( IdChar(z[i]) ){ i++; } + *tokenType = TK_ID; + return i; +} + +/* +** Run the parser on the given SQL string. +*/ +SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){ + int nErr = 0; /* Number of errors encountered */ + void *pEngine; /* The LEMON-generated LALR(1) parser */ + i64 n = 0; /* Length of the next token token */ + int tokenType; /* type of the next token */ + int lastTokenParsed = -1; /* type of the previous token */ + sqlite3 *db = pParse->db; /* The database connection */ + i64 mxSqlLen; /* Max length of an SQL string */ + Parse *pParentParse = 0; /* Outer parse context, if any */ +#ifdef sqlite3Parser_ENGINEALWAYSONSTACK + yyParser sEngine; /* Space to hold the Lemon-generated Parser object */ +#endif + VVA_ONLY( u8 startedWithOom = db->mallocFailed ); + + assert( zSql!=0 ); + mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; + if( db->nVdbeActive==0 ){ + AtomicStore(&db->u1.isInterrupted, 0); + } + pParse->rc = SQLITE_OK; + pParse->zTail = zSql; +#ifdef SQLITE_DEBUG + if( db->flags & SQLITE_ParserTrace ){ + printf("parser: [[[%s]]]\n", zSql); + sqlite3ParserTrace(stdout, "parser: "); + }else{ + sqlite3ParserTrace(0, 0); + } +#endif +#ifdef sqlite3Parser_ENGINEALWAYSONSTACK + pEngine = &sEngine; + sqlite3ParserInit(pEngine, pParse); +#else + pEngine = sqlite3ParserAlloc(sqlite3Malloc, pParse); + if( pEngine==0 ){ + sqlite3OomFault(db); + return SQLITE_NOMEM_BKPT; + } +#endif + assert( pParse->pNewTable==0 ); + assert( pParse->pNewTrigger==0 ); + assert( pParse->nVar==0 ); + assert( pParse->pVList==0 ); + pParentParse = db->pParse; + db->pParse = pParse; + while( 1 ){ + n = sqlite3GetToken((u8*)zSql, &tokenType); + mxSqlLen -= n; + if( mxSqlLen<0 ){ + pParse->rc = SQLITE_TOOBIG; + pParse->nErr++; + break; + } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( tokenType>=TK_WINDOW ){ + assert( tokenType==TK_SPACE || tokenType==TK_OVER || tokenType==TK_FILTER + || tokenType==TK_ILLEGAL || tokenType==TK_WINDOW + || tokenType==TK_QNUMBER || tokenType==TK_COMMENT + ); +#else + if( tokenType>=TK_SPACE ){ + assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL + || tokenType==TK_QNUMBER || tokenType==TK_COMMENT + ); +#endif /* SQLITE_OMIT_WINDOWFUNC */ + if( AtomicLoad(&db->u1.isInterrupted) ){ + pParse->rc = SQLITE_INTERRUPT; + pParse->nErr++; + break; + } + if( tokenType==TK_SPACE ){ + zSql += n; + continue; + } + if( zSql[0]==0 ){ + /* Upon reaching the end of input, call the parser two more times + ** with tokens TK_SEMI and 0, in that order. */ + if( lastTokenParsed==TK_SEMI ){ + tokenType = 0; + }else if( lastTokenParsed==0 ){ + break; + }else{ + tokenType = TK_SEMI; + } + n = 0; +#ifndef SQLITE_OMIT_WINDOWFUNC + }else if( tokenType==TK_WINDOW ){ + assert( n==6 ); + tokenType = analyzeWindowKeyword((const u8*)&zSql[6]); + }else if( tokenType==TK_OVER ){ + assert( n==4 ); + tokenType = analyzeOverKeyword((const u8*)&zSql[4], lastTokenParsed); + }else if( tokenType==TK_FILTER ){ + assert( n==6 ); + tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed); +#endif /* SQLITE_OMIT_WINDOWFUNC */ + }else if( tokenType==TK_COMMENT + && (db->init.busy || (db->flags & SQLITE_Comments)!=0) + ){ + /* Ignore SQL comments if either (1) we are reparsing the schema or + ** (2) SQLITE_DBCONFIG_ENABLE_COMMENTS is turned on (the default). */ + zSql += n; + continue; + }else if( tokenType!=TK_QNUMBER ){ + Token x; + x.z = zSql; + x.n = (u32)n; + sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"", &x); + break; + } + } + pParse->sLastToken.z = zSql; + pParse->sLastToken.n = (u32)n; + sqlite3Parser(pEngine, tokenType, pParse->sLastToken); + lastTokenParsed = tokenType; + zSql += n; + assert( db->mallocFailed==0 || pParse->rc!=SQLITE_OK || startedWithOom ); + if( pParse->rc!=SQLITE_OK ) break; + } + assert( nErr==0 ); +#ifdef YYTRACKMAXSTACKDEPTH + sqlite3_mutex_enter(sqlite3MallocMutex()); + sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK, + sqlite3ParserStackPeak(pEngine) + ); + sqlite3_mutex_leave(sqlite3MallocMutex()); +#endif /* YYDEBUG */ +#ifdef sqlite3Parser_ENGINEALWAYSONSTACK + sqlite3ParserFinalize(pEngine); +#else + sqlite3ParserFree(pEngine, sqlite3_free); +#endif + if( db->mallocFailed ){ + pParse->rc = SQLITE_NOMEM_BKPT; + } + if( pParse->zErrMsg || (pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE) ){ + if( pParse->zErrMsg==0 ){ + pParse->zErrMsg = sqlite3DbStrDup(db, sqlite3ErrStr(pParse->rc)); + } + if( (pParse->prepFlags & SQLITE_PREPARE_DONT_LOG)==0 ){ + sqlite3_log(pParse->rc, "%s in \"%s\"", pParse->zErrMsg, pParse->zTail); + } + nErr++; + } + pParse->zTail = zSql; +#ifndef SQLITE_OMIT_VIRTUALTABLE + sqlite3_free(pParse->apVtabLock); +#endif + + if( pParse->pNewTable && !IN_SPECIAL_PARSE ){ + /* If the pParse->declareVtab flag is set, do not delete any table + ** structure built up in pParse->pNewTable. The calling code (see vtab.c) + ** will take responsibility for freeing the Table structure. + */ + sqlite3DeleteTable(db, pParse->pNewTable); + } + if( pParse->pNewTrigger && !IN_RENAME_OBJECT ){ + sqlite3DeleteTrigger(db, pParse->pNewTrigger); + } + if( pParse->pVList ) sqlite3DbNNFreeNN(db, pParse->pVList); + db->pParse = pParentParse; + assert( nErr==0 || pParse->rc!=SQLITE_OK ); + return nErr; +} + + +#ifdef SQLITE_ENABLE_NORMALIZE +/* +** Insert a single space character into pStr if the current string +** ends with an identifier +*/ +static void addSpaceSeparator(sqlite3_str *pStr){ + if( pStr->nChar && sqlite3IsIdChar(pStr->zText[pStr->nChar-1]) ){ + sqlite3_str_append(pStr, " ", 1); + } +} + +/* +** Compute a normalization of the SQL given by zSql[0..nSql-1]. Return +** the normalization in space obtained from sqlite3DbMalloc(). Or return +** NULL if anything goes wrong or if zSql is NULL. +*/ +SQLITE_PRIVATE char *sqlite3Normalize( + Vdbe *pVdbe, /* VM being reprepared */ + const char *zSql /* The original SQL string */ +){ + sqlite3 *db; /* The database connection */ + int i; /* Next unread byte of zSql[] */ + i64 n; /* length of current token */ + int tokenType; /* type of current token */ + int prevType = 0; /* Previous non-whitespace token */ + int nParen; /* Number of nested levels of parentheses */ + int iStartIN; /* Start of RHS of IN operator in z[] */ + int nParenAtIN; /* Value of nParent at start of RHS of IN operator */ + u32 j; /* Bytes of normalized SQL generated so far */ + sqlite3_str *pStr; /* The normalized SQL string under construction */ + + db = sqlite3VdbeDb(pVdbe); + tokenType = -1; + nParen = iStartIN = nParenAtIN = 0; + pStr = sqlite3_str_new(db); + assert( pStr!=0 ); /* sqlite3_str_new() never returns NULL */ + for(i=0; zSql[i] && pStr->accError==0; i+=n){ + if( tokenType!=TK_SPACE ){ + prevType = tokenType; + } + n = sqlite3GetToken((unsigned char*)zSql+i, &tokenType); + if( NEVER(n<=0) ) break; + switch( tokenType ){ + case TK_COMMENT: + case TK_SPACE: { + break; + } + case TK_NULL: { + if( prevType==TK_IS || prevType==TK_NOT ){ + sqlite3_str_append(pStr, " NULL", 5); + break; + } + /* no break */ deliberate_fall_through + } + case TK_STRING: + case TK_INTEGER: + case TK_FLOAT: + case TK_VARIABLE: + case TK_BLOB: { + sqlite3_str_append(pStr, "?", 1); + break; + } + case TK_LP: { + nParen++; + if( prevType==TK_IN ){ + iStartIN = pStr->nChar; + nParenAtIN = nParen; + } + sqlite3_str_append(pStr, "(", 1); + break; + } + case TK_RP: { + if( iStartIN>0 && nParen==nParenAtIN ){ + assert( pStr->nChar>=(u32)iStartIN ); + pStr->nChar = iStartIN+1; + sqlite3_str_append(pStr, "?,?,?", 5); + iStartIN = 0; + } + nParen--; + sqlite3_str_append(pStr, ")", 1); + break; + } + case TK_ID: { + iStartIN = 0; + j = pStr->nChar; + if( sqlite3Isquote(zSql[i]) ){ + char *zId = sqlite3DbStrNDup(db, zSql+i, n); + int nId; + int eType = 0; + if( zId==0 ) break; + sqlite3Dequote(zId); + if( zSql[i]=='"' && sqlite3VdbeUsesDoubleQuotedString(pVdbe, zId) ){ + sqlite3_str_append(pStr, "?", 1); + sqlite3DbFree(db, zId); + break; + } + nId = sqlite3Strlen30(zId); + if( sqlite3GetToken((u8*)zId, &eType)==nId && eType==TK_ID ){ + addSpaceSeparator(pStr); + sqlite3_str_append(pStr, zId, nId); + }else{ + sqlite3_str_appendf(pStr, "\"%w\"", zId); + } + sqlite3DbFree(db, zId); + }else{ + addSpaceSeparator(pStr); + sqlite3_str_append(pStr, zSql+i, n); + } + while( jnChar ){ + pStr->zText[j] = sqlite3Tolower(pStr->zText[j]); + j++; + } + break; + } + case TK_SELECT: { + iStartIN = 0; + /* no break */ deliberate_fall_through + } + default: { + if( sqlite3IsIdChar(zSql[i]) ) addSpaceSeparator(pStr); + j = pStr->nChar; + sqlite3_str_append(pStr, zSql+i, n); + while( jnChar ){ + pStr->zText[j] = sqlite3Toupper(pStr->zText[j]); + j++; + } + break; + } + } + } + if( tokenType!=TK_SEMI ) sqlite3_str_append(pStr, ";", 1); + return sqlite3_str_finish(pStr); +} +#endif /* SQLITE_ENABLE_NORMALIZE */ + +/************** End of tokenize.c ********************************************/ +/************** Begin file complete.c ****************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** An tokenizer for SQL +** +** This file contains C code that implements the sqlite3_complete() API. +** This code used to be part of the tokenizer.c source file. But by +** separating it out, the code will be automatically omitted from +** static links that do not use it. +*/ +/* #include "sqliteInt.h" */ +#ifndef SQLITE_OMIT_COMPLETE + +/* +** This is defined in tokenize.c. We just have to import the definition. +*/ +#ifndef SQLITE_AMALGAMATION +#ifdef SQLITE_ASCII +#define IdChar(C) ((sqlite3CtypeMap[(unsigned char)C]&0x46)!=0) +#endif +#ifdef SQLITE_EBCDIC +SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[]; +#define IdChar(C) (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40])) +#endif +#endif /* SQLITE_AMALGAMATION */ + + +/* +** Token types used by the sqlite3_complete() routine. See the header +** comments on that procedure for additional information. +*/ +#define tkSEMI 0 +#define tkWS 1 +#define tkOTHER 2 +#ifndef SQLITE_OMIT_TRIGGER +#define tkEXPLAIN 3 +#define tkCREATE 4 +#define tkTEMP 5 +#define tkTRIGGER 6 +#define tkEND 7 +#endif + +/* +** Return TRUE if the given SQL string ends in a semicolon. +** +** Special handling is require for CREATE TRIGGER statements. +** Whenever the CREATE TRIGGER keywords are seen, the statement +** must end with ";END;". +** +** This implementation uses a state machine with 8 states: +** +** (0) INVALID We have not yet seen a non-whitespace character. +** +** (1) START At the beginning or end of an SQL statement. This routine +** returns 1 if it ends in the START state and 0 if it ends +** in any other state. +** +** (2) NORMAL We are in the middle of statement which ends with a single +** semicolon. +** +** (3) EXPLAIN The keyword EXPLAIN has been seen at the beginning of +** a statement. +** +** (4) CREATE The keyword CREATE has been seen at the beginning of a +** statement, possibly preceded by EXPLAIN and/or followed by +** TEMP or TEMPORARY +** +** (5) TRIGGER We are in the middle of a trigger definition that must be +** ended by a semicolon, the keyword END, and another semicolon. +** +** (6) SEMI We've seen the first semicolon in the ";END;" that occurs at +** the end of a trigger definition. +** +** (7) END We've seen the ";END" of the ";END;" that occurs at the end +** of a trigger definition. +** +** Transitions between states above are determined by tokens extracted +** from the input. The following tokens are significant: +** +** (0) tkSEMI A semicolon. +** (1) tkWS Whitespace. +** (2) tkOTHER Any other SQL token. +** (3) tkEXPLAIN The "explain" keyword. +** (4) tkCREATE The "create" keyword. +** (5) tkTEMP The "temp" or "temporary" keyword. +** (6) tkTRIGGER The "trigger" keyword. +** (7) tkEND The "end" keyword. +** +** Whitespace never causes a state transition and is always ignored. +** This means that a SQL string of all whitespace is invalid. +** +** If we compile with SQLITE_OMIT_TRIGGER, all of the computation needed +** to recognize the end of a trigger can be omitted. All we have to do +** is look for a semicolon that is not part of an string or comment. +*/ +SQLITE_API int sqlite3_complete(const char *zSql){ + u8 state = 0; /* Current state, using numbers defined in header comment */ + u8 token; /* Value of the next token */ + +#ifndef SQLITE_OMIT_TRIGGER + /* A complex statement machine used to detect the end of a CREATE TRIGGER + ** statement. This is the normal case. + */ + static const u8 trans[8][8] = { + /* Token: */ + /* State: ** SEMI WS OTHER EXPLAIN CREATE TEMP TRIGGER END */ + /* 0 INVALID: */ { 1, 0, 2, 3, 4, 2, 2, 2, }, + /* 1 START: */ { 1, 1, 2, 3, 4, 2, 2, 2, }, + /* 2 NORMAL: */ { 1, 2, 2, 2, 2, 2, 2, 2, }, + /* 3 EXPLAIN: */ { 1, 3, 3, 2, 4, 2, 2, 2, }, + /* 4 CREATE: */ { 1, 4, 2, 2, 2, 4, 5, 2, }, + /* 5 TRIGGER: */ { 6, 5, 5, 5, 5, 5, 5, 5, }, + /* 6 SEMI: */ { 6, 6, 5, 5, 5, 5, 5, 7, }, + /* 7 END: */ { 1, 7, 5, 5, 5, 5, 5, 5, }, + }; +#else + /* If triggers are not supported by this compile then the statement machine + ** used to detect the end of a statement is much simpler + */ + static const u8 trans[3][3] = { + /* Token: */ + /* State: ** SEMI WS OTHER */ + /* 0 INVALID: */ { 1, 0, 2, }, + /* 1 START: */ { 1, 1, 2, }, + /* 2 NORMAL: */ { 1, 2, 2, }, + }; +#endif /* SQLITE_OMIT_TRIGGER */ + +#ifdef SQLITE_ENABLE_API_ARMOR + if( zSql==0 ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + + while( *zSql ){ + switch( *zSql ){ + case ';': { /* A semicolon */ + token = tkSEMI; + break; + } + case ' ': + case '\r': + case '\t': + case '\n': + case '\f': { /* White space is ignored */ + token = tkWS; + break; + } + case '/': { /* C-style comments */ + if( zSql[1]!='*' ){ + token = tkOTHER; + break; + } + zSql += 2; + while( zSql[0] && (zSql[0]!='*' || zSql[1]!='/') ){ zSql++; } + if( zSql[0]==0 ) return 0; + zSql++; + token = tkWS; + break; + } + case '-': { /* SQL-style comments from "--" to end of line */ + if( zSql[1]!='-' ){ + token = tkOTHER; + break; + } + while( *zSql && *zSql!='\n' ){ zSql++; } + if( *zSql==0 ) return state==1; + token = tkWS; + break; + } + case '[': { /* Microsoft-style identifiers in [...] */ + zSql++; + while( *zSql && *zSql!=']' ){ zSql++; } + if( *zSql==0 ) return 0; + token = tkOTHER; + break; + } + case '`': /* Grave-accent quoted symbols used by MySQL */ + case '"': /* single- and double-quoted strings */ + case '\'': { + int c = *zSql; + zSql++; + while( *zSql && *zSql!=c ){ zSql++; } + if( *zSql==0 ) return 0; + token = tkOTHER; + break; + } + default: { +#ifdef SQLITE_EBCDIC + unsigned char c; +#endif + if( IdChar((u8)*zSql) ){ + /* Keywords and unquoted identifiers */ + int nId; + for(nId=1; IdChar(zSql[nId]); nId++){} +#ifdef SQLITE_OMIT_TRIGGER + token = tkOTHER; +#else + switch( *zSql ){ + case 'c': case 'C': { + if( nId==6 && sqlite3StrNICmp(zSql, "create", 6)==0 ){ + token = tkCREATE; + }else{ + token = tkOTHER; + } + break; + } + case 't': case 'T': { + if( nId==7 && sqlite3StrNICmp(zSql, "trigger", 7)==0 ){ + token = tkTRIGGER; + }else if( nId==4 && sqlite3StrNICmp(zSql, "temp", 4)==0 ){ + token = tkTEMP; + }else if( nId==9 && sqlite3StrNICmp(zSql, "temporary", 9)==0 ){ + token = tkTEMP; + }else{ + token = tkOTHER; + } + break; + } + case 'e': case 'E': { + if( nId==3 && sqlite3StrNICmp(zSql, "end", 3)==0 ){ + token = tkEND; + }else +#ifndef SQLITE_OMIT_EXPLAIN + if( nId==7 && sqlite3StrNICmp(zSql, "explain", 7)==0 ){ + token = tkEXPLAIN; + }else +#endif + { + token = tkOTHER; + } + break; + } + default: { + token = tkOTHER; + break; + } + } +#endif /* SQLITE_OMIT_TRIGGER */ + zSql += nId-1; + }else{ + /* Operators and special symbols */ + token = tkOTHER; + } + break; + } + } + state = trans[state][token]; + zSql++; + } + return state==1; +} + +#ifndef SQLITE_OMIT_UTF16 +/* +** This routine is the same as the sqlite3_complete() routine described +** above, except that the parameter is required to be UTF-16 encoded, not +** UTF-8. +*/ +SQLITE_API int sqlite3_complete16(const void *zSql){ + sqlite3_value *pVal; + char const *zSql8; + int rc; + +#ifndef SQLITE_OMIT_AUTOINIT + rc = sqlite3_initialize(); + if( rc ) return rc; +#endif + pVal = sqlite3ValueNew(0); + sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC); + zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8); + if( zSql8 ){ + rc = sqlite3_complete(zSql8); + }else{ + rc = SQLITE_NOMEM_BKPT; + } + sqlite3ValueFree(pVal); + return rc & 0xff; +} +#endif /* SQLITE_OMIT_UTF16 */ +#endif /* SQLITE_OMIT_COMPLETE */ + +/************** End of complete.c ********************************************/ +/************** Begin file main.c ********************************************/ +/* +** 2001 September 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** Main file for the SQLite library. The routines in this file +** implement the programmer interface to the library. Routines in +** other files are for internal use by SQLite and should not be +** accessed by users of the library. +*/ +/* #include "sqliteInt.h" */ + +#ifdef SQLITE_ENABLE_FTS3 +/************** Include fts3.h in the middle of main.c ***********************/ +/************** Begin file fts3.h ********************************************/ +/* +** 2006 Oct 10 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This header file is used by programs that want to link against the +** FTS3 library. All it does is declare the sqlite3Fts3Init() interface. +*/ +/* #include "sqlite3.h" */ + +#if 0 +extern "C" { +#endif /* __cplusplus */ + +SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db); + +#if 0 +} /* extern "C" */ +#endif /* __cplusplus */ + +/************** End of fts3.h ************************************************/ +/************** Continuing where we left off in main.c ***********************/ +#endif +#ifdef SQLITE_ENABLE_RTREE +/************** Include rtree.h in the middle of main.c **********************/ +/************** Begin file rtree.h *******************************************/ +/* +** 2008 May 26 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This header file is used by programs that want to link against the +** RTREE library. All it does is declare the sqlite3RtreeInit() interface. +*/ +/* #include "sqlite3.h" */ + +#ifdef SQLITE_OMIT_VIRTUALTABLE +# undef SQLITE_ENABLE_RTREE +#endif + +#if 0 +extern "C" { +#endif /* __cplusplus */ + +SQLITE_PRIVATE int sqlite3RtreeInit(sqlite3 *db); + +#if 0 +} /* extern "C" */ +#endif /* __cplusplus */ + +/************** End of rtree.h ***********************************************/ +/************** Continuing where we left off in main.c ***********************/ +#endif +#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS) +/************** Include sqliteicu.h in the middle of main.c ******************/ +/************** Begin file sqliteicu.h ***************************************/ +/* +** 2008 May 26 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This header file is used by programs that want to link against the +** ICU extension. All it does is declare the sqlite3IcuInit() interface. +*/ +/* #include "sqlite3.h" */ + +#if 0 +extern "C" { +#endif /* __cplusplus */ + +SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db); + +#if 0 +} /* extern "C" */ +#endif /* __cplusplus */ + +/************** End of sqliteicu.h *******************************************/ +/************** Continuing where we left off in main.c ***********************/ +#endif + +/* +** This is an extension initializer that is a no-op and always +** succeeds, except that it fails if the fault-simulation is set +** to 500. +*/ +static int sqlite3TestExtInit(sqlite3 *db){ + (void)db; + return sqlite3FaultSim(500); +} + + +/* +** Forward declarations of external module initializer functions +** for modules that need them. +*/ +#ifdef SQLITE_ENABLE_FTS5 +SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3*); +#endif +#ifdef SQLITE_ENABLE_STMTVTAB +SQLITE_PRIVATE int sqlite3StmtVtabInit(sqlite3*); +#endif +#ifdef SQLITE_EXTRA_AUTOEXT +int SQLITE_EXTRA_AUTOEXT(sqlite3*); +#endif +/* +** An array of pointers to extension initializer functions for +** built-in extensions. +*/ +static int (*const sqlite3BuiltinExtensions[])(sqlite3*) = { +#ifdef SQLITE_ENABLE_FTS3 + sqlite3Fts3Init, +#endif +#ifdef SQLITE_ENABLE_FTS5 + sqlite3Fts5Init, +#endif +#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS) + sqlite3IcuInit, +#endif +#ifdef SQLITE_ENABLE_RTREE + sqlite3RtreeInit, +#endif +#ifdef SQLITE_ENABLE_DBPAGE_VTAB + sqlite3DbpageRegister, +#endif +#ifdef SQLITE_ENABLE_DBSTAT_VTAB + sqlite3DbstatRegister, +#endif + sqlite3TestExtInit, +#ifdef SQLITE_ENABLE_STMTVTAB + sqlite3StmtVtabInit, +#endif +#ifdef SQLITE_ENABLE_BYTECODE_VTAB + sqlite3VdbeBytecodeVtabInit, +#endif +#ifdef SQLITE_EXTRA_AUTOEXT + SQLITE_EXTRA_AUTOEXT, +#endif +}; + +#ifndef SQLITE_AMALGAMATION +/* IMPLEMENTATION-OF: R-46656-45156 The sqlite3_version[] string constant +** contains the text of SQLITE_VERSION macro. +*/ +SQLITE_API const char sqlite3_version[] = SQLITE_VERSION; +#endif + +/* IMPLEMENTATION-OF: R-53536-42575 The sqlite3_libversion() function returns +** a pointer to the to the sqlite3_version[] string constant. +*/ +SQLITE_API const char *sqlite3_libversion(void){ return sqlite3_version; } + +/* IMPLEMENTATION-OF: R-25063-23286 The sqlite3_sourceid() function returns a +** pointer to a string constant whose value is the same as the +** SQLITE_SOURCE_ID C preprocessor macro. Except if SQLite is built using +** an edited copy of the amalgamation, then the last four characters of +** the hash might be different from SQLITE_SOURCE_ID. +*/ +/* SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } */ + +/* IMPLEMENTATION-OF: R-35210-63508 The sqlite3_libversion_number() function +** returns an integer equal to SQLITE_VERSION_NUMBER. +*/ +SQLITE_API int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; } + +/* IMPLEMENTATION-OF: R-20790-14025 The sqlite3_threadsafe() function returns +** zero if and only if SQLite was compiled with mutexing code omitted due to +** the SQLITE_THREADSAFE compile-time option being set to 0. +*/ +SQLITE_API int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; } + +/* +** When compiling the test fixture or with debugging enabled (on Win32), +** this variable being set to non-zero will cause OSTRACE macros to emit +** extra diagnostic information. +*/ +#ifdef SQLITE_HAVE_OS_TRACE +# ifndef SQLITE_DEBUG_OS_TRACE +# define SQLITE_DEBUG_OS_TRACE 0 +# endif + int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; +#endif + +#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE) +/* +** If the following function pointer is not NULL and if +** SQLITE_ENABLE_IOTRACE is enabled, then messages describing +** I/O active are written using this function. These messages +** are intended for debugging activity only. +*/ +SQLITE_API void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...) = 0; +#endif + +/* +** If the following global variable points to a string which is the +** name of a directory, then that directory will be used to store +** temporary files. +** +** See also the "PRAGMA temp_store_directory" SQL command. +*/ +SQLITE_API char *sqlite3_temp_directory = 0; + +/* +** If the following global variable points to a string which is the +** name of a directory, then that directory will be used to store +** all database files specified with a relative pathname. +** +** See also the "PRAGMA data_store_directory" SQL command. +*/ +SQLITE_API char *sqlite3_data_directory = 0; + +/* +** Initialize SQLite. +** +** This routine must be called to initialize the memory allocation, +** VFS, and mutex subsystems prior to doing any serious work with +** SQLite. But as long as you do not compile with SQLITE_OMIT_AUTOINIT +** this routine will be called automatically by key routines such as +** sqlite3_open(). +** +** This routine is a no-op except on its very first call for the process, +** or for the first call after a call to sqlite3_shutdown. +** +** The first thread to call this routine runs the initialization to +** completion. If subsequent threads call this routine before the first +** thread has finished the initialization process, then the subsequent +** threads must block until the first thread finishes with the initialization. +** +** The first thread might call this routine recursively. Recursive +** calls to this routine should not block, of course. Otherwise the +** initialization process would never complete. +** +** Let X be the first thread to enter this routine. Let Y be some other +** thread. Then while the initial invocation of this routine by X is +** incomplete, it is required that: +** +** * Calls to this routine from Y must block until the outer-most +** call by X completes. +** +** * Recursive calls to this routine from thread X return immediately +** without blocking. +*/ +SQLITE_API int sqlite3_initialize(void){ + MUTEX_LOGIC( sqlite3_mutex *pMainMtx; ) /* The main static mutex */ + int rc; /* Result code */ +#ifdef SQLITE_EXTRA_INIT + int bRunExtraInit = 0; /* Extra initialization needed */ +#endif + +#ifdef SQLITE_OMIT_WSD + rc = sqlite3_wsd_init(4096, 24); + if( rc!=SQLITE_OK ){ + return rc; + } +#endif + + /* If the following assert() fails on some obscure processor/compiler + ** combination, the work-around is to set the correct pointer + ** size at compile-time using -DSQLITE_PTRSIZE=n compile-time option */ + assert( SQLITE_PTRSIZE==sizeof(char*) ); + + /* If SQLite is already completely initialized, then this call + ** to sqlite3_initialize() should be a no-op. But the initialization + ** must be complete. So isInit must not be set until the very end + ** of this routine. + */ + if( sqlite3GlobalConfig.isInit ){ + sqlite3MemoryBarrier(); + return SQLITE_OK; + } + + /* Make sure the mutex subsystem is initialized. If unable to + ** initialize the mutex subsystem, return early with the error. + ** If the system is so sick that we are unable to allocate a mutex, + ** there is not much SQLite is going to be able to do. + ** + ** The mutex subsystem must take care of serializing its own + ** initialization. + */ + rc = sqlite3MutexInit(); + if( rc ) return rc; + + /* Initialize the malloc() system and the recursive pInitMutex mutex. + ** This operation is protected by the STATIC_MAIN mutex. Note that + ** MutexAlloc() is called for a static mutex prior to initializing the + ** malloc subsystem - this implies that the allocation of a static + ** mutex must not require support from the malloc subsystem. + */ + MUTEX_LOGIC( pMainMtx = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); ) + sqlite3_mutex_enter(pMainMtx); + sqlite3GlobalConfig.isMutexInit = 1; + if( !sqlite3GlobalConfig.isMallocInit ){ + rc = sqlite3MallocInit(); + } + if( rc==SQLITE_OK ){ + sqlite3GlobalConfig.isMallocInit = 1; + if( !sqlite3GlobalConfig.pInitMutex ){ + sqlite3GlobalConfig.pInitMutex = + sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); + if( sqlite3GlobalConfig.bCoreMutex && !sqlite3GlobalConfig.pInitMutex ){ + rc = SQLITE_NOMEM_BKPT; + } + } + } + if( rc==SQLITE_OK ){ + sqlite3GlobalConfig.nRefInitMutex++; + } + sqlite3_mutex_leave(pMainMtx); + + /* If rc is not SQLITE_OK at this point, then either the malloc + ** subsystem could not be initialized or the system failed to allocate + ** the pInitMutex mutex. Return an error in either case. */ + if( rc!=SQLITE_OK ){ + return rc; + } + + /* Do the rest of the initialization under the recursive mutex so + ** that we will be able to handle recursive calls into + ** sqlite3_initialize(). The recursive calls normally come through + ** sqlite3_os_init() when it invokes sqlite3_vfs_register(), but other + ** recursive calls might also be possible. + ** + ** IMPLEMENTATION-OF: R-00140-37445 SQLite automatically serializes calls + ** to the xInit method, so the xInit method need not be threadsafe. + ** + ** The following mutex is what serializes access to the appdef pcache xInit + ** methods. The sqlite3_pcache_methods.xInit() all is embedded in the + ** call to sqlite3PcacheInitialize(). + */ + sqlite3_mutex_enter(sqlite3GlobalConfig.pInitMutex); + if( sqlite3GlobalConfig.isInit==0 && sqlite3GlobalConfig.inProgress==0 ){ + sqlite3GlobalConfig.inProgress = 1; +#ifdef SQLITE_ENABLE_SQLLOG + { + extern void sqlite3_init_sqllog(void); + sqlite3_init_sqllog(); + } +#endif + memset(&sqlite3BuiltinFunctions, 0, sizeof(sqlite3BuiltinFunctions)); + sqlite3RegisterBuiltinFunctions(); + if( sqlite3GlobalConfig.isPCacheInit==0 ){ + rc = sqlite3PcacheInitialize(); + } + if( rc==SQLITE_OK ){ + sqlite3GlobalConfig.isPCacheInit = 1; + rc = sqlite3OsInit(); + } +#ifndef SQLITE_OMIT_DESERIALIZE + if( rc==SQLITE_OK ){ + rc = sqlite3MemdbInit(); + } +#endif + if( rc==SQLITE_OK ){ + sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage, + sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage); +#ifdef SQLITE_EXTRA_INIT_MUTEXED + { + int SQLITE_EXTRA_INIT_MUTEXED(const char*); + rc = SQLITE_EXTRA_INIT_MUTEXED(0); + } +#endif + } + if( rc==SQLITE_OK ){ + sqlite3MemoryBarrier(); + sqlite3GlobalConfig.isInit = 1; +#ifdef SQLITE_EXTRA_INIT + bRunExtraInit = 1; +#endif + } + sqlite3GlobalConfig.inProgress = 0; + } + sqlite3_mutex_leave(sqlite3GlobalConfig.pInitMutex); + + /* Go back under the static mutex and clean up the recursive + ** mutex to prevent a resource leak. + */ + sqlite3_mutex_enter(pMainMtx); + sqlite3GlobalConfig.nRefInitMutex--; + if( sqlite3GlobalConfig.nRefInitMutex<=0 ){ + assert( sqlite3GlobalConfig.nRefInitMutex==0 ); + sqlite3_mutex_free(sqlite3GlobalConfig.pInitMutex); + sqlite3GlobalConfig.pInitMutex = 0; + } + sqlite3_mutex_leave(pMainMtx); + + /* The following is just a sanity check to make sure SQLite has + ** been compiled correctly. It is important to run this code, but + ** we don't want to run it too often and soak up CPU cycles for no + ** reason. So we run it once during initialization. + */ +#ifndef NDEBUG +#ifndef SQLITE_OMIT_FLOATING_POINT + /* This section of code's only "output" is via assert() statements. */ + if( rc==SQLITE_OK ){ + u64 x = (((u64)1)<<63)-1; + double y; + assert(sizeof(x)==8); + assert(sizeof(x)==sizeof(y)); + memcpy(&y, &x, 8); + assert( sqlite3IsNaN(y) ); + } +#endif +#endif + + /* Do extra initialization steps requested by the SQLITE_EXTRA_INIT + ** compile-time option. + */ +#ifdef SQLITE_EXTRA_INIT + if( bRunExtraInit ){ + int SQLITE_EXTRA_INIT(const char*); + rc = SQLITE_EXTRA_INIT(0); + } +#endif + return rc; +} + +/* +** Undo the effects of sqlite3_initialize(). Must not be called while +** there are outstanding database connections or memory allocations or +** while any part of SQLite is otherwise in use in any thread. This +** routine is not threadsafe. But it is safe to invoke this routine +** on when SQLite is already shut down. If SQLite is already shut down +** when this routine is invoked, then this routine is a harmless no-op. +*/ +SQLITE_API int sqlite3_shutdown(void){ +#ifdef SQLITE_OMIT_WSD + int rc = sqlite3_wsd_init(4096, 24); + if( rc!=SQLITE_OK ){ + return rc; + } +#endif + + if( sqlite3GlobalConfig.isInit ){ +#ifdef SQLITE_EXTRA_SHUTDOWN + void SQLITE_EXTRA_SHUTDOWN(void); + SQLITE_EXTRA_SHUTDOWN(); +#endif + sqlite3_os_end(); + sqlite3_reset_auto_extension(); + sqlite3GlobalConfig.isInit = 0; + } + if( sqlite3GlobalConfig.isPCacheInit ){ + sqlite3PcacheShutdown(); + sqlite3GlobalConfig.isPCacheInit = 0; + } + if( sqlite3GlobalConfig.isMallocInit ){ + sqlite3MallocEnd(); + sqlite3GlobalConfig.isMallocInit = 0; + +#ifndef SQLITE_OMIT_SHUTDOWN_DIRECTORIES + /* The heap subsystem has now been shutdown and these values are supposed + ** to be NULL or point to memory that was obtained from sqlite3_malloc(), + ** which would rely on that heap subsystem; therefore, make sure these + ** values cannot refer to heap memory that was just invalidated when the + ** heap subsystem was shutdown. This is only done if the current call to + ** this function resulted in the heap subsystem actually being shutdown. + */ + sqlite3_data_directory = 0; + sqlite3_temp_directory = 0; +#endif + } + if( sqlite3GlobalConfig.isMutexInit ){ + sqlite3MutexEnd(); + sqlite3GlobalConfig.isMutexInit = 0; + } + + return SQLITE_OK; +} + +/* +** This API allows applications to modify the global configuration of +** the SQLite library at run-time. +** +** This routine should only be called when there are no outstanding +** database connections or memory allocations. This routine is not +** threadsafe. Failure to heed these warnings can lead to unpredictable +** behavior. +*/ +SQLITE_API int sqlite3_config(int op, ...){ + va_list ap; + int rc = SQLITE_OK; + + /* sqlite3_config() normally returns SQLITE_MISUSE if it is invoked while + ** the SQLite library is in use. Except, a few selected opcodes + ** are allowed. + */ + if( sqlite3GlobalConfig.isInit ){ + static const u64 mAnytimeConfigOption = 0 + | MASKBIT64( SQLITE_CONFIG_LOG ) + | MASKBIT64( SQLITE_CONFIG_PCACHE_HDRSZ ) + ; + if( op<0 || op>63 || (MASKBIT64(op) & mAnytimeConfigOption)==0 ){ + return SQLITE_MISUSE_BKPT; + } + testcase( op==SQLITE_CONFIG_LOG ); + testcase( op==SQLITE_CONFIG_PCACHE_HDRSZ ); + } + + va_start(ap, op); + switch( op ){ + + /* Mutex configuration options are only available in a threadsafe + ** compile. + */ +#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-54466-46756 */ + case SQLITE_CONFIG_SINGLETHREAD: { + /* EVIDENCE-OF: R-02748-19096 This option sets the threading mode to + ** Single-thread. */ + sqlite3GlobalConfig.bCoreMutex = 0; /* Disable mutex on core */ + sqlite3GlobalConfig.bFullMutex = 0; /* Disable mutex on connections */ + break; + } +#endif +#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-20520-54086 */ + case SQLITE_CONFIG_MULTITHREAD: { + /* EVIDENCE-OF: R-14374-42468 This option sets the threading mode to + ** Multi-thread. */ + sqlite3GlobalConfig.bCoreMutex = 1; /* Enable mutex on core */ + sqlite3GlobalConfig.bFullMutex = 0; /* Disable mutex on connections */ + break; + } +#endif +#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-59593-21810 */ + case SQLITE_CONFIG_SERIALIZED: { + /* EVIDENCE-OF: R-41220-51800 This option sets the threading mode to + ** Serialized. */ + sqlite3GlobalConfig.bCoreMutex = 1; /* Enable mutex on core */ + sqlite3GlobalConfig.bFullMutex = 1; /* Enable mutex on connections */ + break; + } +#endif +#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-63666-48755 */ + case SQLITE_CONFIG_MUTEX: { + /* Specify an alternative mutex implementation */ + sqlite3GlobalConfig.mutex = *va_arg(ap, sqlite3_mutex_methods*); + break; + } +#endif +#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-14450-37597 */ + case SQLITE_CONFIG_GETMUTEX: { + /* Retrieve the current mutex implementation */ + *va_arg(ap, sqlite3_mutex_methods*) = sqlite3GlobalConfig.mutex; + break; + } +#endif + + case SQLITE_CONFIG_MALLOC: { + /* EVIDENCE-OF: R-55594-21030 The SQLITE_CONFIG_MALLOC option takes a + ** single argument which is a pointer to an instance of the + ** sqlite3_mem_methods structure. The argument specifies alternative + ** low-level memory allocation routines to be used in place of the memory + ** allocation routines built into SQLite. */ + sqlite3GlobalConfig.m = *va_arg(ap, sqlite3_mem_methods*); + break; + } + case SQLITE_CONFIG_GETMALLOC: { + /* EVIDENCE-OF: R-51213-46414 The SQLITE_CONFIG_GETMALLOC option takes a + ** single argument which is a pointer to an instance of the + ** sqlite3_mem_methods structure. The sqlite3_mem_methods structure is + ** filled with the currently defined memory allocation routines. */ + if( sqlite3GlobalConfig.m.xMalloc==0 ) sqlite3MemSetDefault(); + *va_arg(ap, sqlite3_mem_methods*) = sqlite3GlobalConfig.m; + break; + } + case SQLITE_CONFIG_MEMSTATUS: { + assert( !sqlite3GlobalConfig.isInit ); /* Cannot change at runtime */ + /* EVIDENCE-OF: R-61275-35157 The SQLITE_CONFIG_MEMSTATUS option takes + ** single argument of type int, interpreted as a boolean, which enables + ** or disables the collection of memory allocation statistics. */ + sqlite3GlobalConfig.bMemstat = va_arg(ap, int); + break; + } + case SQLITE_CONFIG_SMALL_MALLOC: { + sqlite3GlobalConfig.bSmallMalloc = va_arg(ap, int); + break; + } + case SQLITE_CONFIG_PAGECACHE: { + /* EVIDENCE-OF: R-18761-36601 There are three arguments to + ** SQLITE_CONFIG_PAGECACHE: A pointer to 8-byte aligned memory (pMem), + ** the size of each page cache line (sz), and the number of cache lines + ** (N). */ + sqlite3GlobalConfig.pPage = va_arg(ap, void*); + sqlite3GlobalConfig.szPage = va_arg(ap, int); + sqlite3GlobalConfig.nPage = va_arg(ap, int); + break; + } + case SQLITE_CONFIG_PCACHE_HDRSZ: { + /* EVIDENCE-OF: R-39100-27317 The SQLITE_CONFIG_PCACHE_HDRSZ option takes + ** a single parameter which is a pointer to an integer and writes into + ** that integer the number of extra bytes per page required for each page + ** in SQLITE_CONFIG_PAGECACHE. */ + *va_arg(ap, int*) = + sqlite3HeaderSizeBtree() + + sqlite3HeaderSizePcache() + + sqlite3HeaderSizePcache1(); + break; + } + + case SQLITE_CONFIG_PCACHE: { + /* no-op */ + break; + } + case SQLITE_CONFIG_GETPCACHE: { + /* now an error */ + rc = SQLITE_ERROR; + break; + } + + case SQLITE_CONFIG_PCACHE2: { + /* EVIDENCE-OF: R-63325-48378 The SQLITE_CONFIG_PCACHE2 option takes a + ** single argument which is a pointer to an sqlite3_pcache_methods2 + ** object. This object specifies the interface to a custom page cache + ** implementation. */ + sqlite3GlobalConfig.pcache2 = *va_arg(ap, sqlite3_pcache_methods2*); + break; + } + case SQLITE_CONFIG_GETPCACHE2: { + /* EVIDENCE-OF: R-22035-46182 The SQLITE_CONFIG_GETPCACHE2 option takes a + ** single argument which is a pointer to an sqlite3_pcache_methods2 + ** object. SQLite copies of the current page cache implementation into + ** that object. */ + if( sqlite3GlobalConfig.pcache2.xInit==0 ){ + sqlite3PCacheSetDefault(); + } + *va_arg(ap, sqlite3_pcache_methods2*) = sqlite3GlobalConfig.pcache2; + break; + } + +/* EVIDENCE-OF: R-06626-12911 The SQLITE_CONFIG_HEAP option is only +** available if SQLite is compiled with either SQLITE_ENABLE_MEMSYS3 or +** SQLITE_ENABLE_MEMSYS5 and returns SQLITE_ERROR if invoked otherwise. */ +#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) + case SQLITE_CONFIG_HEAP: { + /* EVIDENCE-OF: R-19854-42126 There are three arguments to + ** SQLITE_CONFIG_HEAP: An 8-byte aligned pointer to the memory, the + ** number of bytes in the memory buffer, and the minimum allocation size. + */ + sqlite3GlobalConfig.pHeap = va_arg(ap, void*); + sqlite3GlobalConfig.nHeap = va_arg(ap, int); + sqlite3GlobalConfig.mnReq = va_arg(ap, int); + + if( sqlite3GlobalConfig.mnReq<1 ){ + sqlite3GlobalConfig.mnReq = 1; + }else if( sqlite3GlobalConfig.mnReq>(1<<12) ){ + /* cap min request size at 2^12 */ + sqlite3GlobalConfig.mnReq = (1<<12); + } + + if( sqlite3GlobalConfig.pHeap==0 ){ + /* EVIDENCE-OF: R-49920-60189 If the first pointer (the memory pointer) + ** is NULL, then SQLite reverts to using its default memory allocator + ** (the system malloc() implementation), undoing any prior invocation of + ** SQLITE_CONFIG_MALLOC. + ** + ** Setting sqlite3GlobalConfig.m to all zeros will cause malloc to + ** revert to its default implementation when sqlite3_initialize() is run + */ + memset(&sqlite3GlobalConfig.m, 0, sizeof(sqlite3GlobalConfig.m)); + }else{ + /* EVIDENCE-OF: R-61006-08918 If the memory pointer is not NULL then the + ** alternative memory allocator is engaged to handle all of SQLites + ** memory allocation needs. */ +#ifdef SQLITE_ENABLE_MEMSYS3 + sqlite3GlobalConfig.m = *sqlite3MemGetMemsys3(); +#endif +#ifdef SQLITE_ENABLE_MEMSYS5 + sqlite3GlobalConfig.m = *sqlite3MemGetMemsys5(); +#endif + } + break; + } +#endif + + case SQLITE_CONFIG_LOOKASIDE: { + sqlite3GlobalConfig.szLookaside = va_arg(ap, int); + sqlite3GlobalConfig.nLookaside = va_arg(ap, int); + break; + } + + /* Record a pointer to the logger function and its first argument. + ** The default is NULL. Logging is disabled if the function pointer is + ** NULL. + */ + case SQLITE_CONFIG_LOG: { + /* MSVC is picky about pulling func ptrs from va lists. + ** http://support.microsoft.com/kb/47961 + ** sqlite3GlobalConfig.xLog = va_arg(ap, void(*)(void*,int,const char*)); + */ + typedef void(*LOGFUNC_t)(void*,int,const char*); + LOGFUNC_t xLog = va_arg(ap, LOGFUNC_t); + void *pLogArg = va_arg(ap, void*); + AtomicStore(&sqlite3GlobalConfig.xLog, xLog); + AtomicStore(&sqlite3GlobalConfig.pLogArg, pLogArg); + break; + } + + /* EVIDENCE-OF: R-55548-33817 The compile-time setting for URI filenames + ** can be changed at start-time using the + ** sqlite3_config(SQLITE_CONFIG_URI,1) or + ** sqlite3_config(SQLITE_CONFIG_URI,0) configuration calls. + */ + case SQLITE_CONFIG_URI: { + /* EVIDENCE-OF: R-25451-61125 The SQLITE_CONFIG_URI option takes a single + ** argument of type int. If non-zero, then URI handling is globally + ** enabled. If the parameter is zero, then URI handling is globally + ** disabled. */ + int bOpenUri = va_arg(ap, int); + AtomicStore(&sqlite3GlobalConfig.bOpenUri, bOpenUri); + break; + } + + case SQLITE_CONFIG_COVERING_INDEX_SCAN: { + /* EVIDENCE-OF: R-36592-02772 The SQLITE_CONFIG_COVERING_INDEX_SCAN + ** option takes a single integer argument which is interpreted as a + ** boolean in order to enable or disable the use of covering indices for + ** full table scans in the query optimizer. */ + sqlite3GlobalConfig.bUseCis = va_arg(ap, int); + break; + } + +#ifdef SQLITE_ENABLE_SQLLOG + case SQLITE_CONFIG_SQLLOG: { + typedef void(*SQLLOGFUNC_t)(void*, sqlite3*, const char*, int); + sqlite3GlobalConfig.xSqllog = va_arg(ap, SQLLOGFUNC_t); + sqlite3GlobalConfig.pSqllogArg = va_arg(ap, void *); + break; + } +#endif + + case SQLITE_CONFIG_MMAP_SIZE: { + /* EVIDENCE-OF: R-58063-38258 SQLITE_CONFIG_MMAP_SIZE takes two 64-bit + ** integer (sqlite3_int64) values that are the default mmap size limit + ** (the default setting for PRAGMA mmap_size) and the maximum allowed + ** mmap size limit. */ + sqlite3_int64 szMmap = va_arg(ap, sqlite3_int64); + sqlite3_int64 mxMmap = va_arg(ap, sqlite3_int64); + /* EVIDENCE-OF: R-53367-43190 If either argument to this option is + ** negative, then that argument is changed to its compile-time default. + ** + ** EVIDENCE-OF: R-34993-45031 The maximum allowed mmap size will be + ** silently truncated if necessary so that it does not exceed the + ** compile-time maximum mmap size set by the SQLITE_MAX_MMAP_SIZE + ** compile-time option. + */ + if( mxMmap<0 || mxMmap>SQLITE_MAX_MMAP_SIZE ){ + mxMmap = SQLITE_MAX_MMAP_SIZE; + } + if( szMmap<0 ) szMmap = SQLITE_DEFAULT_MMAP_SIZE; + if( szMmap>mxMmap) szMmap = mxMmap; + sqlite3GlobalConfig.mxMmap = mxMmap; + sqlite3GlobalConfig.szMmap = szMmap; + break; + } + +#if SQLITE_OS_WIN && defined(SQLITE_WIN32_MALLOC) /* IMP: R-04780-55815 */ + case SQLITE_CONFIG_WIN32_HEAPSIZE: { + /* EVIDENCE-OF: R-34926-03360 SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit + ** unsigned integer value that specifies the maximum size of the created + ** heap. */ + sqlite3GlobalConfig.nHeap = va_arg(ap, int); + break; + } +#endif + + case SQLITE_CONFIG_PMASZ: { + sqlite3GlobalConfig.szPma = va_arg(ap, unsigned int); + break; + } + + case SQLITE_CONFIG_STMTJRNL_SPILL: { + sqlite3GlobalConfig.nStmtSpill = va_arg(ap, int); + break; + } + +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + case SQLITE_CONFIG_SORTERREF_SIZE: { + int iVal = va_arg(ap, int); + if( iVal<0 ){ + iVal = SQLITE_DEFAULT_SORTERREF_SIZE; + } + sqlite3GlobalConfig.szSorterRef = (u32)iVal; + break; + } +#endif /* SQLITE_ENABLE_SORTER_REFERENCES */ + +#ifndef SQLITE_OMIT_DESERIALIZE + case SQLITE_CONFIG_MEMDB_MAXSIZE: { + sqlite3GlobalConfig.mxMemdbSize = va_arg(ap, sqlite3_int64); + break; + } +#endif /* SQLITE_OMIT_DESERIALIZE */ + + case SQLITE_CONFIG_ROWID_IN_VIEW: { + int *pVal = va_arg(ap,int*); +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + if( 0==*pVal ) sqlite3GlobalConfig.mNoVisibleRowid = TF_NoVisibleRowid; + if( 1==*pVal ) sqlite3GlobalConfig.mNoVisibleRowid = 0; + *pVal = (sqlite3GlobalConfig.mNoVisibleRowid==0); +#else + *pVal = 0; +#endif + break; + } + + default: { + rc = SQLITE_ERROR; + break; + } + } + va_end(ap); + return rc; +} + +/* +** Set up the lookaside buffers for a database connection. +** Return SQLITE_OK on success. +** If lookaside is already active, return SQLITE_BUSY. +** +** The sz parameter is the number of bytes in each lookaside slot. +** The cnt parameter is the number of slots. If pBuf is NULL the +** space for the lookaside memory is obtained from sqlite3_malloc() +** or similar. If pBuf is not NULL then it is sz*cnt bytes of memory +** to use for the lookaside memory. +*/ +static int setupLookaside( + sqlite3 *db, /* Database connection being configured */ + void *pBuf, /* Memory to use for lookaside. May be NULL */ + int sz, /* Desired size of each lookaside memory slot */ + int cnt /* Number of slots to allocate */ +){ +#ifndef SQLITE_OMIT_LOOKASIDE + void *pStart; /* Start of the lookaside buffer */ + sqlite3_int64 szAlloc; /* Total space set aside for lookaside memory */ + int nBig; /* Number of full-size slots */ + int nSm; /* Number smaller LOOKASIDE_SMALL-byte slots */ + + if( sqlite3LookasideUsed(db,0)>0 ){ + return SQLITE_BUSY; + } + /* Free any existing lookaside buffer for this handle before + ** allocating a new one so we don't have to have space for + ** both at the same time. + */ + if( db->lookaside.bMalloced ){ + sqlite3_free(db->lookaside.pStart); + } + /* The size of a lookaside slot after ROUNDDOWN8 needs to be larger + ** than a pointer and small enough to fit in a u16. + */ + sz = ROUNDDOWN8(sz); + if( sz<=(int)sizeof(LookasideSlot*) ) sz = 0; + if( sz>65528 ) sz = 65528; + /* Count must be at least 1 to be useful, but not so large as to use + ** more than 0x7fff0000 total bytes for lookaside. */ + if( cnt<1 ) cnt = 0; + if( sz>0 && cnt>(0x7fff0000/sz) ) cnt = 0x7fff0000/sz; + szAlloc = (i64)sz*(i64)cnt; + if( szAlloc==0 ){ + sz = 0; + pStart = 0; + }else if( pBuf==0 ){ + sqlite3BeginBenignMalloc(); + pStart = sqlite3Malloc( szAlloc ); + sqlite3EndBenignMalloc(); + if( pStart ) szAlloc = sqlite3MallocSize(pStart); + }else{ + pStart = pBuf; + } +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + if( sz>=LOOKASIDE_SMALL*3 ){ + nBig = szAlloc/(3*LOOKASIDE_SMALL+sz); + nSm = (szAlloc - (i64)sz*(i64)nBig)/LOOKASIDE_SMALL; + }else if( sz>=LOOKASIDE_SMALL*2 ){ + nBig = szAlloc/(LOOKASIDE_SMALL+sz); + nSm = (szAlloc - (i64)sz*(i64)nBig)/LOOKASIDE_SMALL; + }else +#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ + if( sz>0 ){ + nBig = szAlloc/sz; + nSm = 0; + }else{ + nBig = nSm = 0; + } + db->lookaside.pStart = pStart; + db->lookaside.pInit = 0; + db->lookaside.pFree = 0; + db->lookaside.sz = (u16)sz; + db->lookaside.szTrue = (u16)sz; + if( pStart ){ + int i; + LookasideSlot *p; + assert( sz > (int)sizeof(LookasideSlot*) ); + p = (LookasideSlot*)pStart; + for(i=0; ipNext = db->lookaside.pInit; + db->lookaside.pInit = p; + p = (LookasideSlot*)&((u8*)p)[sz]; + } +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + db->lookaside.pSmallInit = 0; + db->lookaside.pSmallFree = 0; + db->lookaside.pMiddle = p; + for(i=0; ipNext = db->lookaside.pSmallInit; + db->lookaside.pSmallInit = p; + p = (LookasideSlot*)&((u8*)p)[LOOKASIDE_SMALL]; + } +#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ + assert( ((uptr)p)<=szAlloc + (uptr)pStart ); + db->lookaside.pEnd = p; + db->lookaside.bDisable = 0; + db->lookaside.bMalloced = pBuf==0 ?1:0; + db->lookaside.nSlot = nBig+nSm; + }else{ + db->lookaside.pStart = 0; +#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE + db->lookaside.pSmallInit = 0; + db->lookaside.pSmallFree = 0; + db->lookaside.pMiddle = 0; +#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ + db->lookaside.pEnd = 0; + db->lookaside.bDisable = 1; + db->lookaside.sz = 0; + db->lookaside.bMalloced = 0; + db->lookaside.nSlot = 0; + } + db->lookaside.pTrueEnd = db->lookaside.pEnd; + assert( sqlite3LookasideUsed(db,0)==0 ); +#endif /* SQLITE_OMIT_LOOKASIDE */ + return SQLITE_OK; +} + +/* +** Return the mutex associated with a database connection. +*/ +SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + return db->mutex; +} + +/* +** Free up as much memory as we can from the given database +** connection. +*/ +SQLITE_API int sqlite3_db_release_memory(sqlite3 *db){ + int i; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + sqlite3BtreeEnterAll(db); + for(i=0; inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt ){ + Pager *pPager = sqlite3BtreePager(pBt); + sqlite3PagerShrink(pPager); + } + } + sqlite3BtreeLeaveAll(db); + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + +/* +** Flush any dirty pages in the pager-cache for any attached database +** to disk. +*/ +SQLITE_API int sqlite3_db_cacheflush(sqlite3 *db){ + int i; + int rc = SQLITE_OK; + int bSeenBusy = 0; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + sqlite3BtreeEnterAll(db); + for(i=0; rc==SQLITE_OK && inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt && sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ){ + Pager *pPager = sqlite3BtreePager(pBt); + rc = sqlite3PagerFlush(pPager); + if( rc==SQLITE_BUSY ){ + bSeenBusy = 1; + rc = SQLITE_OK; + } + } + } + sqlite3BtreeLeaveAll(db); + sqlite3_mutex_leave(db->mutex); + return ((rc==SQLITE_OK && bSeenBusy) ? SQLITE_BUSY : rc); +} + +/* +** Configuration settings for an individual database connection +*/ +SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){ + va_list ap; + int rc; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + va_start(ap, op); + switch( op ){ + case SQLITE_DBCONFIG_MAINDBNAME: { + /* IMP: R-06824-28531 */ + /* IMP: R-36257-52125 */ + db->aDb[0].zDbSName = va_arg(ap,char*); + rc = SQLITE_OK; + break; + } + case SQLITE_DBCONFIG_LOOKASIDE: { + void *pBuf = va_arg(ap, void*); /* IMP: R-26835-10964 */ + int sz = va_arg(ap, int); /* IMP: R-47871-25994 */ + int cnt = va_arg(ap, int); /* IMP: R-04460-53386 */ + rc = setupLookaside(db, pBuf, sz, cnt); + break; + } + case SQLITE_DBCONFIG_FP_DIGITS: { + int nIn = va_arg(ap, int); + int *pOut = va_arg(ap, int*); + if( nIn>3 && nIn<24 ) db->nFpDigit = (u8)nIn; + if( pOut ) *pOut = db->nFpDigit; + rc = SQLITE_OK; + break; + } + default: { + static const struct { + int op; /* The opcode */ + u64 mask; /* Mask of the bit in sqlite3.flags to set/clear */ + } aFlagOp[] = { + { SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys }, + { SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger }, + { SQLITE_DBCONFIG_ENABLE_VIEW, SQLITE_EnableView }, + { SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer }, + { SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension }, + { SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, SQLITE_NoCkptOnClose }, + { SQLITE_DBCONFIG_ENABLE_QPSG, SQLITE_EnableQPSG }, + { SQLITE_DBCONFIG_TRIGGER_EQP, SQLITE_TriggerEQP }, + { SQLITE_DBCONFIG_RESET_DATABASE, SQLITE_ResetDatabase }, + { SQLITE_DBCONFIG_DEFENSIVE, SQLITE_Defensive }, + { SQLITE_DBCONFIG_WRITABLE_SCHEMA, SQLITE_WriteSchema| + SQLITE_NoSchemaError }, + { SQLITE_DBCONFIG_LEGACY_ALTER_TABLE, SQLITE_LegacyAlter }, + { SQLITE_DBCONFIG_DQS_DDL, SQLITE_DqsDDL }, + { SQLITE_DBCONFIG_DQS_DML, SQLITE_DqsDML }, + { SQLITE_DBCONFIG_LEGACY_FILE_FORMAT, SQLITE_LegacyFileFmt }, + { SQLITE_DBCONFIG_TRUSTED_SCHEMA, SQLITE_TrustedSchema }, + { SQLITE_DBCONFIG_STMT_SCANSTATUS, SQLITE_StmtScanStatus }, + { SQLITE_DBCONFIG_REVERSE_SCANORDER, SQLITE_ReverseOrder }, + { SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE, SQLITE_AttachCreate }, + { SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE, SQLITE_AttachWrite }, + { SQLITE_DBCONFIG_ENABLE_COMMENTS, SQLITE_Comments }, + }; + unsigned int i; + rc = SQLITE_ERROR; /* IMP: R-42790-23372 */ + for(i=0; iflags; + if( onoff>0 ){ + db->flags |= aFlagOp[i].mask; + }else if( onoff==0 ){ + db->flags &= ~(u64)aFlagOp[i].mask; + } + if( oldFlags!=db->flags ){ + sqlite3ExpirePreparedStatements(db, 0); + } + if( pRes ){ + *pRes = (db->flags & aFlagOp[i].mask)!=0; + } + rc = SQLITE_OK; + break; + } + } + break; + } + } + va_end(ap); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** This is the default collating function named "BINARY" which is always +** available. +*/ +static int binCollFunc( + void *NotUsed, + int nKey1, const void *pKey1, + int nKey2, const void *pKey2 +){ + int rc, n; + UNUSED_PARAMETER(NotUsed); + n = nKey1xCmp!=binCollFunc || strcmp(p->zName,"BINARY")==0 ); + return p==0 || p->xCmp==binCollFunc; +} + +/* +** Another built-in collating sequence: NOCASE. +** +** This collating sequence is intended to be used for "case independent +** comparison". SQLite's knowledge of upper and lower case equivalents +** extends only to the 26 characters used in the English language. +** +** At the moment there is only a UTF-8 implementation. +*/ +static int nocaseCollatingFunc( + void *NotUsed, + int nKey1, const void *pKey1, + int nKey2, const void *pKey2 +){ + int r = sqlite3StrNICmp( + (const char *)pKey1, (const char *)pKey2, (nKey1mutex); + iRet = db->lastRowid; + sqlite3_mutex_leave(db->mutex); + return iRet; +} + +/* +** Set the value returned by the sqlite3_last_insert_rowid() API function. +*/ +SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3 *db, sqlite3_int64 iRowid){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return; + } +#endif + sqlite3_mutex_enter(db->mutex); + db->lastRowid = iRowid; + sqlite3_mutex_leave(db->mutex); +} + +/* +** Return the number of changes in the most recent call to sqlite3_exec(). +*/ +SQLITE_API sqlite3_int64 sqlite3_changes64(sqlite3 *db){ + i64 iRet; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + iRet = db->nChange; + sqlite3_mutex_leave(db->mutex); + return iRet; +} +SQLITE_API int sqlite3_changes(sqlite3 *db){ + return (int)sqlite3_changes64(db); +} + +/* +** Return the number of changes since the database handle was opened. +*/ +SQLITE_API sqlite3_int64 sqlite3_total_changes64(sqlite3 *db){ + i64 iRet; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + iRet = db->nTotalChange; + sqlite3_mutex_leave(db->mutex); + return iRet; +} +SQLITE_API int sqlite3_total_changes(sqlite3 *db){ + return (int)sqlite3_total_changes64(db); +} + +/* +** Close all open savepoints. This function only manipulates fields of the +** database handle object, it does not close any savepoints that may be open +** at the b-tree/pager level. +*/ +SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *db){ + while( db->pSavepoint ){ + Savepoint *pTmp = db->pSavepoint; + db->pSavepoint = pTmp->pNext; + sqlite3DbFree(db, pTmp); + } + db->nSavepoint = 0; + db->nStatement = 0; + db->isTransactionSavepoint = 0; +} + +/* +** Invoke the destructor function associated with FuncDef p, if any. Except, +** if this is not the last copy of the function, do not invoke it. Multiple +** copies of a single function are created when create_function() is called +** with SQLITE_ANY as the encoding. +*/ +static void functionDestroy(sqlite3 *db, FuncDef *p){ + FuncDestructor *pDestructor; + assert( (p->funcFlags & SQLITE_FUNC_BUILTIN)==0 ); + pDestructor = p->u.pDestructor; + if( pDestructor ){ + pDestructor->nRef--; + if( pDestructor->nRef==0 ){ + pDestructor->xDestroy(pDestructor->pUserData); + sqlite3DbFree(db, pDestructor); + } + } +} + +/* +** Disconnect all sqlite3_vtab objects that belong to database connection +** db. This is called when db is being closed. +*/ +static void disconnectAllVtab(sqlite3 *db){ +#ifndef SQLITE_OMIT_VIRTUALTABLE + int i; + HashElem *p; + sqlite3BtreeEnterAll(db); + for(i=0; inDb; i++){ + Schema *pSchema = db->aDb[i].pSchema; + if( pSchema ){ + for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){ + Table *pTab = (Table *)sqliteHashData(p); + if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab); + } + } + } + for(p=sqliteHashFirst(&db->aModule); p; p=sqliteHashNext(p)){ + Module *pMod = (Module *)sqliteHashData(p); + if( pMod->pEpoTab ){ + sqlite3VtabDisconnect(db, pMod->pEpoTab); + } + } + sqlite3VtabUnlockList(db); + sqlite3BtreeLeaveAll(db); +#else + UNUSED_PARAMETER(db); +#endif +} + +/* +** Return TRUE if database connection db has unfinalized prepared +** statements or unfinished sqlite3_backup objects. +*/ +static int connectionIsBusy(sqlite3 *db){ + int j; + assert( sqlite3_mutex_held(db->mutex) ); + if( db->pVdbe ) return 1; + for(j=0; jnDb; j++){ + Btree *pBt = db->aDb[j].pBt; + if( pBt && sqlite3BtreeIsInBackup(pBt) ) return 1; + } + return 0; +} + +/* +** Close an existing SQLite database +*/ +static int sqlite3Close(sqlite3 *db, int forceZombie){ + if( !db ){ + /* EVIDENCE-OF: R-63257-11740 Calling sqlite3_close() or + ** sqlite3_close_v2() with a NULL pointer argument is a harmless no-op. */ + return SQLITE_OK; + } + if( !sqlite3SafetyCheckSickOrOk(db) ){ + return SQLITE_MISUSE_BKPT; + } + sqlite3_mutex_enter(db->mutex); + if( db->mTrace & SQLITE_TRACE_CLOSE ){ + db->trace.xV2(SQLITE_TRACE_CLOSE, db->pTraceArg, db, 0); + } + + /* Force xDisconnect calls on all virtual tables */ + disconnectAllVtab(db); + + /* If a transaction is open, the disconnectAllVtab() call above + ** will not have called the xDisconnect() method on any virtual + ** tables in the db->aVTrans[] array. The following sqlite3VtabRollback() + ** call will do so. We need to do this before the check for active + ** SQL statements below, as the v-table implementation may be storing + ** some prepared statements internally. + */ + sqlite3VtabRollback(db); + + /* Legacy behavior (sqlite3_close() behavior) is to return + ** SQLITE_BUSY if the connection can not be closed immediately. + */ + if( !forceZombie && connectionIsBusy(db) ){ + sqlite3ErrorWithMsg(db, SQLITE_BUSY, "unable to close due to unfinalized " + "statements or unfinished backups"); + sqlite3_mutex_leave(db->mutex); + return SQLITE_BUSY; + } + +#ifdef SQLITE_ENABLE_SQLLOG + if( sqlite3GlobalConfig.xSqllog ){ + /* Closing the handle. Fourth parameter is passed the value 2. */ + sqlite3GlobalConfig.xSqllog(sqlite3GlobalConfig.pSqllogArg, db, 0, 2); + } +#endif + + while( db->pDbData ){ + DbClientData *p = db->pDbData; + db->pDbData = p->pNext; + assert( p->pData!=0 ); + if( p->xDestructor ) p->xDestructor(p->pData); + sqlite3_free(p); + } + + /* Convert the connection into a zombie and then close it. + */ + db->eOpenState = SQLITE_STATE_ZOMBIE; + sqlite3LeaveMutexAndCloseZombie(db); + return SQLITE_OK; +} + +/* +** Return the transaction state for a single databse, or the maximum +** transaction state over all attached databases if zSchema is null. +*/ +SQLITE_API int sqlite3_txn_state(sqlite3 *db, const char *zSchema){ + int iDb, nDb; + int iTxn = -1; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return -1; + } +#endif + sqlite3_mutex_enter(db->mutex); + if( zSchema ){ + nDb = iDb = sqlite3FindDbName(db, zSchema); + if( iDb<0 ) nDb--; + }else{ + iDb = 0; + nDb = db->nDb-1; + } + for(; iDb<=nDb; iDb++){ + Btree *pBt = db->aDb[iDb].pBt; + int x = pBt!=0 ? sqlite3BtreeTxnState(pBt) : SQLITE_TXN_NONE; + if( x>iTxn ) iTxn = x; + } + sqlite3_mutex_leave(db->mutex); + return iTxn; +} + +/* +** Two variations on the public interface for closing a database +** connection. The sqlite3_close() version returns SQLITE_BUSY and +** leaves the connection open if there are unfinalized prepared +** statements or unfinished sqlite3_backups. The sqlite3_close_v2() +** version forces the connection to become a zombie if there are +** unclosed resources, and arranges for deallocation when the last +** prepare statement or sqlite3_backup closes. +*/ +SQLITE_API int sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); } +SQLITE_API int sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); } + + +/* +** Close the mutex on database connection db. +** +** Furthermore, if database connection db is a zombie (meaning that there +** has been a prior call to sqlite3_close(db) or sqlite3_close_v2(db)) and +** every sqlite3_stmt has now been finalized and every sqlite3_backup has +** finished, then free all resources. +*/ +SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){ + HashElem *i; /* Hash table iterator */ + int j; + + /* If there are outstanding sqlite3_stmt or sqlite3_backup objects + ** or if the connection has not yet been closed by sqlite3_close_v2(), + ** then just leave the mutex and return. + */ + if( db->eOpenState!=SQLITE_STATE_ZOMBIE || connectionIsBusy(db) ){ + sqlite3_mutex_leave(db->mutex); + return; + } + + /* If we reach this point, it means that the database connection has + ** closed all sqlite3_stmt and sqlite3_backup objects and has been + ** passed to sqlite3_close (meaning that it is a zombie). Therefore, + ** go ahead and free all resources. + */ + + /* If a transaction is open, roll it back. This also ensures that if + ** any database schemas have been modified by an uncommitted transaction + ** they are reset. And that the required b-tree mutex is held to make + ** the pager rollback and schema reset an atomic operation. */ + sqlite3RollbackAll(db, SQLITE_OK); + + /* Free any outstanding Savepoint structures. */ + sqlite3CloseSavepoints(db); + + /* Close all database connections */ + for(j=0; jnDb; j++){ + struct Db *pDb = &db->aDb[j]; + if( pDb->pBt ){ + sqlite3BtreeClose(pDb->pBt); + pDb->pBt = 0; + if( j!=1 ){ + pDb->pSchema = 0; + } + } + } + /* Clear the TEMP schema separately and last */ + if( db->aDb[1].pSchema ){ + sqlite3SchemaClear(db->aDb[1].pSchema); + assert( db->aDb[1].pSchema->trigHash.count==0 ); + } + sqlite3VtabUnlockList(db); + + /* Free up the array of auxiliary databases */ + sqlite3CollapseDatabaseArray(db); + assert( db->nDb<=2 ); + assert( db->aDb==db->aDbStatic ); + + /* Tell the code in notify.c that the connection no longer holds any + ** locks and does not require any further unlock-notify callbacks. + */ + sqlite3ConnectionClosed(db); + + for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){ + FuncDef *pNext, *p; + p = sqliteHashData(i); + do{ + functionDestroy(db, p); + pNext = p->pNext; + sqlite3DbFree(db, p); + p = pNext; + }while( p ); + } + sqlite3HashClear(&db->aFunc); + for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){ + CollSeq *pColl = (CollSeq *)sqliteHashData(i); + /* Invoke any destructors registered for collation sequence user data. */ + for(j=0; j<3; j++){ + if( pColl[j].xDel ){ + pColl[j].xDel(pColl[j].pUser); + } + } + sqlite3DbFree(db, pColl); + } + sqlite3HashClear(&db->aCollSeq); +#ifndef SQLITE_OMIT_VIRTUALTABLE + for(i=sqliteHashFirst(&db->aModule); i; i=sqliteHashNext(i)){ + Module *pMod = (Module *)sqliteHashData(i); + sqlite3VtabEponymousTableClear(db, pMod); + sqlite3VtabModuleUnref(db, pMod); + } + sqlite3HashClear(&db->aModule); +#endif + + sqlite3Error(db, SQLITE_OK); /* Deallocates any cached error strings. */ + sqlite3ValueFree(db->pErr); + sqlite3CloseExtensions(db); + + db->eOpenState = SQLITE_STATE_ERROR; + + /* The temp-database schema is allocated differently from the other schema + ** objects (using sqliteMalloc() directly, instead of sqlite3BtreeSchema()). + ** So it needs to be freed here. Todo: Why not roll the temp schema into + ** the same sqliteMalloc() as the one that allocates the database + ** structure? + */ + sqlite3DbFree(db, db->aDb[1].pSchema); + if( db->xAutovacDestr ){ + db->xAutovacDestr(db->pAutovacPagesArg); + } + sqlite3_mutex_leave(db->mutex); + db->eOpenState = SQLITE_STATE_CLOSED; + sqlite3_mutex_free(db->mutex); + assert( sqlite3LookasideUsed(db,0)==0 ); + if( db->lookaside.bMalloced ){ + sqlite3_free(db->lookaside.pStart); + } + sqlite3_free(db); +} + +/* +** Rollback all database files. If tripCode is not SQLITE_OK, then +** any write cursors are invalidated ("tripped" - as in "tripping a circuit +** breaker") and made to return tripCode if there are any further +** attempts to use that cursor. Read cursors remain open and valid +** but are "saved" in case the table pages are moved around. +*/ +SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){ + int i; + int inTrans = 0; + int schemaChange; + assert( sqlite3_mutex_held(db->mutex) ); + sqlite3BeginBenignMalloc(); + + /* Obtain all b-tree mutexes before making any calls to BtreeRollback(). + ** This is important in case the transaction being rolled back has + ** modified the database schema. If the b-tree mutexes are not taken + ** here, then another shared-cache connection might sneak in between + ** the database rollback and schema reset, which can cause false + ** corruption reports in some cases. */ + sqlite3BtreeEnterAll(db); + schemaChange = (db->mDbFlags & DBFLAG_SchemaChange)!=0 && db->init.busy==0; + + for(i=0; inDb; i++){ + Btree *p = db->aDb[i].pBt; + if( p ){ + if( sqlite3BtreeTxnState(p)==SQLITE_TXN_WRITE ){ + inTrans = 1; + } + sqlite3BtreeRollback(p, tripCode, !schemaChange); + } + } + sqlite3VtabRollback(db); + sqlite3EndBenignMalloc(); + + if( schemaChange ){ + sqlite3ExpirePreparedStatements(db, 0); + sqlite3ResetAllSchemasOfConnection(db); + } + sqlite3BtreeLeaveAll(db); + + /* Any deferred constraint violations have now been resolved. */ + db->nDeferredCons = 0; + db->nDeferredImmCons = 0; + db->flags &= ~(u64)(SQLITE_DeferFKs|SQLITE_CorruptRdOnly); + + /* If one has been configured, invoke the rollback-hook callback */ + if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){ + db->xRollbackCallback(db->pRollbackArg); + } +} + +/* +** Return a static string containing the name corresponding to the error code +** specified in the argument. +*/ +#if defined(SQLITE_NEED_ERR_NAME) +SQLITE_PRIVATE const char *sqlite3ErrName(int rc){ + const char *zName = 0; + int i, origRc = rc; + for(i=0; i<2 && zName==0; i++, rc &= 0xff){ + switch( rc ){ + case SQLITE_OK: zName = "SQLITE_OK"; break; + case SQLITE_ERROR: zName = "SQLITE_ERROR"; break; + case SQLITE_ERROR_SNAPSHOT: zName = "SQLITE_ERROR_SNAPSHOT"; break; + case SQLITE_ERROR_RETRY: zName = "SQLITE_ERROR_RETRY"; break; + case SQLITE_ERROR_MISSING_COLLSEQ: + zName = "SQLITE_ERROR_MISSING_COLLSEQ"; break; + case SQLITE_INTERNAL: zName = "SQLITE_INTERNAL"; break; + case SQLITE_PERM: zName = "SQLITE_PERM"; break; + case SQLITE_ABORT: zName = "SQLITE_ABORT"; break; + case SQLITE_ABORT_ROLLBACK: zName = "SQLITE_ABORT_ROLLBACK"; break; + case SQLITE_BUSY: zName = "SQLITE_BUSY"; break; + case SQLITE_BUSY_RECOVERY: zName = "SQLITE_BUSY_RECOVERY"; break; + case SQLITE_BUSY_SNAPSHOT: zName = "SQLITE_BUSY_SNAPSHOT"; break; + case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break; + case SQLITE_LOCKED_SHAREDCACHE: zName = "SQLITE_LOCKED_SHAREDCACHE";break; + case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break; + case SQLITE_READONLY: zName = "SQLITE_READONLY"; break; + case SQLITE_READONLY_RECOVERY: zName = "SQLITE_READONLY_RECOVERY"; break; + case SQLITE_READONLY_CANTINIT: zName = "SQLITE_READONLY_CANTINIT"; break; + case SQLITE_READONLY_ROLLBACK: zName = "SQLITE_READONLY_ROLLBACK"; break; + case SQLITE_READONLY_DBMOVED: zName = "SQLITE_READONLY_DBMOVED"; break; + case SQLITE_READONLY_DIRECTORY: zName = "SQLITE_READONLY_DIRECTORY";break; + case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break; + case SQLITE_IOERR: zName = "SQLITE_IOERR"; break; + case SQLITE_IOERR_READ: zName = "SQLITE_IOERR_READ"; break; + case SQLITE_IOERR_SHORT_READ: zName = "SQLITE_IOERR_SHORT_READ"; break; + case SQLITE_IOERR_WRITE: zName = "SQLITE_IOERR_WRITE"; break; + case SQLITE_IOERR_FSYNC: zName = "SQLITE_IOERR_FSYNC"; break; + case SQLITE_IOERR_DIR_FSYNC: zName = "SQLITE_IOERR_DIR_FSYNC"; break; + case SQLITE_IOERR_TRUNCATE: zName = "SQLITE_IOERR_TRUNCATE"; break; + case SQLITE_IOERR_FSTAT: zName = "SQLITE_IOERR_FSTAT"; break; + case SQLITE_IOERR_UNLOCK: zName = "SQLITE_IOERR_UNLOCK"; break; + case SQLITE_IOERR_RDLOCK: zName = "SQLITE_IOERR_RDLOCK"; break; + case SQLITE_IOERR_DELETE: zName = "SQLITE_IOERR_DELETE"; break; + case SQLITE_IOERR_NOMEM: zName = "SQLITE_IOERR_NOMEM"; break; + case SQLITE_IOERR_ACCESS: zName = "SQLITE_IOERR_ACCESS"; break; + case SQLITE_IOERR_CHECKRESERVEDLOCK: + zName = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break; + case SQLITE_IOERR_LOCK: zName = "SQLITE_IOERR_LOCK"; break; + case SQLITE_IOERR_CLOSE: zName = "SQLITE_IOERR_CLOSE"; break; + case SQLITE_IOERR_DIR_CLOSE: zName = "SQLITE_IOERR_DIR_CLOSE"; break; + case SQLITE_IOERR_SHMOPEN: zName = "SQLITE_IOERR_SHMOPEN"; break; + case SQLITE_IOERR_SHMSIZE: zName = "SQLITE_IOERR_SHMSIZE"; break; + case SQLITE_IOERR_SHMLOCK: zName = "SQLITE_IOERR_SHMLOCK"; break; + case SQLITE_IOERR_SHMMAP: zName = "SQLITE_IOERR_SHMMAP"; break; + case SQLITE_IOERR_SEEK: zName = "SQLITE_IOERR_SEEK"; break; + case SQLITE_IOERR_DELETE_NOENT: zName = "SQLITE_IOERR_DELETE_NOENT";break; + case SQLITE_IOERR_MMAP: zName = "SQLITE_IOERR_MMAP"; break; + case SQLITE_IOERR_GETTEMPPATH: zName = "SQLITE_IOERR_GETTEMPPATH"; break; + case SQLITE_IOERR_CONVPATH: zName = "SQLITE_IOERR_CONVPATH"; break; + case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break; + case SQLITE_CORRUPT_VTAB: zName = "SQLITE_CORRUPT_VTAB"; break; + case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break; + case SQLITE_FULL: zName = "SQLITE_FULL"; break; + case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break; + case SQLITE_CANTOPEN_NOTEMPDIR: zName = "SQLITE_CANTOPEN_NOTEMPDIR";break; + case SQLITE_CANTOPEN_ISDIR: zName = "SQLITE_CANTOPEN_ISDIR"; break; + case SQLITE_CANTOPEN_FULLPATH: zName = "SQLITE_CANTOPEN_FULLPATH"; break; + case SQLITE_CANTOPEN_CONVPATH: zName = "SQLITE_CANTOPEN_CONVPATH"; break; + case SQLITE_CANTOPEN_SYMLINK: zName = "SQLITE_CANTOPEN_SYMLINK"; break; + case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break; + case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break; + case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break; + case SQLITE_TOOBIG: zName = "SQLITE_TOOBIG"; break; + case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break; + case SQLITE_CONSTRAINT_UNIQUE: zName = "SQLITE_CONSTRAINT_UNIQUE"; break; + case SQLITE_CONSTRAINT_TRIGGER: zName = "SQLITE_CONSTRAINT_TRIGGER";break; + case SQLITE_CONSTRAINT_FOREIGNKEY: + zName = "SQLITE_CONSTRAINT_FOREIGNKEY"; break; + case SQLITE_CONSTRAINT_CHECK: zName = "SQLITE_CONSTRAINT_CHECK"; break; + case SQLITE_CONSTRAINT_PRIMARYKEY: + zName = "SQLITE_CONSTRAINT_PRIMARYKEY"; break; + case SQLITE_CONSTRAINT_NOTNULL: zName = "SQLITE_CONSTRAINT_NOTNULL";break; + case SQLITE_CONSTRAINT_COMMITHOOK: + zName = "SQLITE_CONSTRAINT_COMMITHOOK"; break; + case SQLITE_CONSTRAINT_VTAB: zName = "SQLITE_CONSTRAINT_VTAB"; break; + case SQLITE_CONSTRAINT_FUNCTION: + zName = "SQLITE_CONSTRAINT_FUNCTION"; break; + case SQLITE_CONSTRAINT_ROWID: zName = "SQLITE_CONSTRAINT_ROWID"; break; + case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break; + case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break; + case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break; + case SQLITE_AUTH: zName = "SQLITE_AUTH"; break; + case SQLITE_FORMAT: zName = "SQLITE_FORMAT"; break; + case SQLITE_RANGE: zName = "SQLITE_RANGE"; break; + case SQLITE_NOTADB: zName = "SQLITE_NOTADB"; break; + case SQLITE_ROW: zName = "SQLITE_ROW"; break; + case SQLITE_NOTICE: zName = "SQLITE_NOTICE"; break; + case SQLITE_NOTICE_RECOVER_WAL: zName = "SQLITE_NOTICE_RECOVER_WAL";break; + case SQLITE_NOTICE_RECOVER_ROLLBACK: + zName = "SQLITE_NOTICE_RECOVER_ROLLBACK"; break; + case SQLITE_NOTICE_RBU: zName = "SQLITE_NOTICE_RBU"; break; + case SQLITE_WARNING: zName = "SQLITE_WARNING"; break; + case SQLITE_WARNING_AUTOINDEX: zName = "SQLITE_WARNING_AUTOINDEX"; break; + case SQLITE_DONE: zName = "SQLITE_DONE"; break; + } + } + if( zName==0 ){ + static char zBuf[50]; + sqlite3_snprintf(sizeof(zBuf), zBuf, "SQLITE_UNKNOWN(%d)", origRc); + zName = zBuf; + } + return zName; +} +#endif + +/* +** Return a static string that describes the kind of error specified in the +** argument. +*/ +SQLITE_PRIVATE const char *sqlite3ErrStr(int rc){ + static const char* const aMsg[] = { + /* SQLITE_OK */ "not an error", + /* SQLITE_ERROR */ "SQL logic error", + /* SQLITE_INTERNAL */ 0, + /* SQLITE_PERM */ "access permission denied", + /* SQLITE_ABORT */ "query aborted", + /* SQLITE_BUSY */ "database is locked", + /* SQLITE_LOCKED */ "database table is locked", + /* SQLITE_NOMEM */ "out of memory", + /* SQLITE_READONLY */ "attempt to write a readonly database", + /* SQLITE_INTERRUPT */ "interrupted", + /* SQLITE_IOERR */ "disk I/O error", + /* SQLITE_CORRUPT */ "database disk image is malformed", + /* SQLITE_NOTFOUND */ "unknown operation", + /* SQLITE_FULL */ "database or disk is full", + /* SQLITE_CANTOPEN */ "unable to open database file", + /* SQLITE_PROTOCOL */ "locking protocol", + /* SQLITE_EMPTY */ 0, + /* SQLITE_SCHEMA */ "database schema has changed", + /* SQLITE_TOOBIG */ "string or blob too big", + /* SQLITE_CONSTRAINT */ "constraint failed", + /* SQLITE_MISMATCH */ "datatype mismatch", + /* SQLITE_MISUSE */ "bad parameter or other API misuse", +#ifdef SQLITE_DISABLE_LFS + /* SQLITE_NOLFS */ "large file support is disabled", +#else + /* SQLITE_NOLFS */ 0, +#endif + /* SQLITE_AUTH */ "authorization denied", + /* SQLITE_FORMAT */ 0, + /* SQLITE_RANGE */ "column index out of range", + /* SQLITE_NOTADB */ "file is not a database", + /* SQLITE_NOTICE */ "notification message", + /* SQLITE_WARNING */ "warning message", + }; + const char *zErr = "unknown error"; + switch( rc ){ + case SQLITE_ABORT_ROLLBACK: { + zErr = "abort due to ROLLBACK"; + break; + } + case SQLITE_ROW: { + zErr = "another row available"; + break; + } + case SQLITE_DONE: { + zErr = "no more rows available"; + break; + } + default: { + rc &= 0xff; + if( ALWAYS(rc>=0) && rcbusyTimeout; + int delay, prior; + + assert( count>=0 ); + if( count < NDELAY ){ + delay = delays[count]; + prior = totals[count]; + }else{ + delay = delays[NDELAY-1]; + prior = totals[NDELAY-1] + delay*(count-(NDELAY-1)); + } + if( prior + delay > tmout ){ + delay = tmout - prior; + if( delay<=0 ) return 0; + } + sqlite3OsSleep(db->pVfs, delay*1000); + return 1; +#else + /* This case for unix systems that lack usleep() support. Sleeping + ** must be done in increments of whole seconds */ + sqlite3 *db = (sqlite3 *)ptr; + int tmout = ((sqlite3 *)ptr)->busyTimeout; + if( (count+1)*1000 > tmout ){ + return 0; + } + sqlite3OsSleep(db->pVfs, 1000000); + return 1; +#endif +} + +/* +** Invoke the given busy handler. +** +** This routine is called when an operation failed to acquire a +** lock on VFS file pFile. +** +** If this routine returns non-zero, the lock is retried. If it +** returns 0, the operation aborts with an SQLITE_BUSY error. +*/ +SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p){ + int rc; + if( p->xBusyHandler==0 || p->nBusy<0 ) return 0; + rc = p->xBusyHandler(p->pBusyArg, p->nBusy); + if( rc==0 ){ + p->nBusy = -1; + }else{ + p->nBusy++; + } + return rc; +} + +/* +** This routine sets the busy callback for an Sqlite database to the +** given callback function with the given argument. +*/ +SQLITE_API int sqlite3_busy_handler( + sqlite3 *db, + int (*xBusy)(void*,int), + void *pArg +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + db->busyHandler.xBusyHandler = xBusy; + db->busyHandler.pBusyArg = pArg; + db->busyHandler.nBusy = 0; + db->busyTimeout = 0; +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + db->setlkTimeout = 0; +#endif + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK +/* +** This routine sets the progress callback for an Sqlite database to the +** given callback function with the given argument. The progress callback will +** be invoked every nOps opcodes. +*/ +SQLITE_API void sqlite3_progress_handler( + sqlite3 *db, + int nOps, + int (*xProgress)(void*), + void *pArg +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return; + } +#endif + sqlite3_mutex_enter(db->mutex); + if( nOps>0 ){ + db->xProgress = xProgress; + db->nProgressOps = (unsigned)nOps; + db->pProgressArg = pArg; + }else{ + db->xProgress = 0; + db->nProgressOps = 0; + db->pProgressArg = 0; + } + sqlite3_mutex_leave(db->mutex); +} +#endif + + +/* +** This routine installs a default busy handler that waits for the +** specified number of milliseconds before returning 0. +*/ +SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + if( ms>0 ){ + sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback, + (void*)db); + db->busyTimeout = ms; +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + db->setlkTimeout = ms; +#endif + }else{ + sqlite3_busy_handler(db, 0, 0); + } + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + +/* +** Set the setlk timeout value. +*/ +SQLITE_API int sqlite3_setlk_timeout(sqlite3 *db, int ms, int flags){ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + int iDb; + int bBOC = ((flags & SQLITE_SETLK_BLOCK_ON_CONNECT) ? 1 : 0); +#endif +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + if( ms<-1 ) return SQLITE_RANGE; +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + sqlite3_mutex_enter(db->mutex); + db->setlkTimeout = ms; + db->setlkFlags = flags; + sqlite3BtreeEnterAll(db); + for(iDb=0; iDbnDb; iDb++){ + Btree *pBt = db->aDb[iDb].pBt; + if( pBt ){ + sqlite3_file *fd = sqlite3PagerFile(sqlite3BtreePager(pBt)); + sqlite3OsFileControlHint(fd, SQLITE_FCNTL_BLOCK_ON_CONNECT, (void*)&bBOC); + } + } + sqlite3BtreeLeaveAll(db); + sqlite3_mutex_leave(db->mutex); +#endif +#if !defined(SQLITE_ENABLE_API_ARMOR) && !defined(SQLITE_ENABLE_SETLK_TIMEOUT) + UNUSED_PARAMETER(db); + UNUSED_PARAMETER(flags); +#endif + return SQLITE_OK; +} + +/* +** Cause any pending operation to stop at its earliest opportunity. +*/ +SQLITE_API void sqlite3_interrupt(sqlite3 *db){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) + && (db==0 || db->eOpenState!=SQLITE_STATE_ZOMBIE) + ){ + (void)SQLITE_MISUSE_BKPT; + return; + } +#endif + AtomicStore(&db->u1.isInterrupted, 1); +} + +/* +** Return true or false depending on whether or not an interrupt is +** pending on connection db. +*/ +SQLITE_API int sqlite3_is_interrupted(sqlite3 *db){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) + && (db==0 || db->eOpenState!=SQLITE_STATE_ZOMBIE) + ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + return AtomicLoad(&db->u1.isInterrupted)!=0; +} + +/* +** This function is exactly the same as sqlite3_create_function(), except +** that it is designed to be called by internal code. The difference is +** that if a malloc() fails in sqlite3_create_function(), an error code +** is returned and the mallocFailed flag cleared. +*/ +SQLITE_PRIVATE int sqlite3CreateFunc( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int enc, + void *pUserData, + void (*xSFunc)(sqlite3_context*,int,sqlite3_value **), + void (*xStep)(sqlite3_context*,int,sqlite3_value **), + void (*xFinal)(sqlite3_context*), + void (*xValue)(sqlite3_context*), + void (*xInverse)(sqlite3_context*,int,sqlite3_value **), + FuncDestructor *pDestructor +){ + FuncDef *p; + int extraFlags; + + assert( sqlite3_mutex_held(db->mutex) ); + assert( xValue==0 || xSFunc==0 ); + if( zFunctionName==0 /* Must have a valid name */ + || (xSFunc!=0 && xFinal!=0) /* Not both xSFunc and xFinal */ + || ((xFinal==0)!=(xStep==0)) /* Both or neither of xFinal and xStep */ + || ((xValue==0)!=(xInverse==0)) /* Both or neither of xValue, xInverse */ + || (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) + || (255funcFlags & SQLITE_FUNC_ENCMASK)==(u32)enc && p->nArg==nArg ){ + if( db->nVdbeActive ){ + sqlite3ErrorWithMsg(db, SQLITE_BUSY, + "unable to delete/modify user-function due to active statements"); + assert( !db->mallocFailed ); + return SQLITE_BUSY; + }else{ + sqlite3ExpirePreparedStatements(db, 0); + } + }else if( xSFunc==0 && xFinal==0 ){ + /* Trying to delete a function that does not exist. This is a no-op. + ** https://sqlite.org/forum/forumpost/726219164b */ + return SQLITE_OK; + } + + p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 1); + assert(p || db->mallocFailed); + if( !p ){ + return SQLITE_NOMEM_BKPT; + } + + /* If an older version of the function with a configured destructor is + ** being replaced invoke the destructor function here. */ + functionDestroy(db, p); + + if( pDestructor ){ + pDestructor->nRef++; + } + p->u.pDestructor = pDestructor; + p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags; + testcase( p->funcFlags & SQLITE_DETERMINISTIC ); + testcase( p->funcFlags & SQLITE_DIRECTONLY ); + p->xSFunc = xSFunc ? xSFunc : xStep; + p->xFinalize = xFinal; + p->xValue = xValue; + p->xInverse = xInverse; + p->pUserData = pUserData; + p->nArg = (u16)nArg; + return SQLITE_OK; +} + +/* +** Worker function used by utf-8 APIs that create new functions: +** +** sqlite3_create_function() +** sqlite3_create_function_v2() +** sqlite3_create_window_function() +*/ +static int createFunctionApi( + sqlite3 *db, + const char *zFunc, + int nArg, + int enc, + void *p, + void (*xSFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void (*xValue)(sqlite3_context*), + void (*xInverse)(sqlite3_context*,int,sqlite3_value**), + void(*xDestroy)(void*) +){ + int rc = SQLITE_ERROR; + FuncDestructor *pArg = 0; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + return SQLITE_MISUSE_BKPT; + } +#endif + sqlite3_mutex_enter(db->mutex); + if( xDestroy ){ + pArg = (FuncDestructor *)sqlite3Malloc(sizeof(FuncDestructor)); + if( !pArg ){ + sqlite3OomFault(db); + xDestroy(p); + goto out; + } + pArg->nRef = 0; + pArg->xDestroy = xDestroy; + pArg->pUserData = p; + } + rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, + xSFunc, xStep, xFinal, xValue, xInverse, pArg + ); + if( pArg && pArg->nRef==0 ){ + assert( rc!=SQLITE_OK || (xStep==0 && xFinal==0) ); + xDestroy(p); + sqlite3_free(pArg); + } + + out: + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Create new user functions. +*/ +SQLITE_API int sqlite3_create_function( + sqlite3 *db, + const char *zFunc, + int nArg, + int enc, + void *p, + void (*xSFunc)(sqlite3_context*,int,sqlite3_value **), + void (*xStep)(sqlite3_context*,int,sqlite3_value **), + void (*xFinal)(sqlite3_context*) +){ + return createFunctionApi(db, zFunc, nArg, enc, p, xSFunc, xStep, + xFinal, 0, 0, 0); +} +SQLITE_API int sqlite3_create_function_v2( + sqlite3 *db, + const char *zFunc, + int nArg, + int enc, + void *p, + void (*xSFunc)(sqlite3_context*,int,sqlite3_value **), + void (*xStep)(sqlite3_context*,int,sqlite3_value **), + void (*xFinal)(sqlite3_context*), + void (*xDestroy)(void *) +){ + return createFunctionApi(db, zFunc, nArg, enc, p, xSFunc, xStep, + xFinal, 0, 0, xDestroy); +} +SQLITE_API int sqlite3_create_window_function( + sqlite3 *db, + const char *zFunc, + int nArg, + int enc, + void *p, + void (*xStep)(sqlite3_context*,int,sqlite3_value **), + void (*xFinal)(sqlite3_context*), + void (*xValue)(sqlite3_context*), + void (*xInverse)(sqlite3_context*,int,sqlite3_value **), + void (*xDestroy)(void *) +){ + return createFunctionApi(db, zFunc, nArg, enc, p, 0, xStep, + xFinal, xValue, xInverse, xDestroy); +} + +#ifndef SQLITE_OMIT_UTF16 +SQLITE_API int sqlite3_create_function16( + sqlite3 *db, + const void *zFunctionName, + int nArg, + int eTextRep, + void *p, + void (*xSFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +){ + int rc; + char *zFunc8; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zFunctionName==0 ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + assert( !db->mallocFailed ); + zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE); + rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xSFunc,xStep,xFinal,0,0,0); + sqlite3DbFree(db, zFunc8); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} +#endif + + +/* +** The following is the implementation of an SQL function that always +** fails with an error message stating that the function is used in the +** wrong context. The sqlite3_overload_function() API might construct +** SQL function that use this routine so that the functions will exist +** for name resolution but are actually overloaded by the xFindFunction +** method of virtual tables. +*/ +static void sqlite3InvalidFunction( + sqlite3_context *context, /* The function calling context */ + int NotUsed, /* Number of arguments to the function */ + sqlite3_value **NotUsed2 /* Value of each argument */ +){ + const char *zName = (const char*)sqlite3_user_data(context); + char *zErr; + UNUSED_PARAMETER2(NotUsed, NotUsed2); + zErr = sqlite3_mprintf( + "unable to use function %s in the requested context", zName); + sqlite3_result_error(context, zErr, -1); + sqlite3_free(zErr); +} + +/* +** Declare that a function has been overloaded by a virtual table. +** +** If the function already exists as a regular global function, then +** this routine is a no-op. If the function does not exist, then create +** a new one that always throws a run-time error. +** +** When virtual tables intend to provide an overloaded function, they +** should call this routine to make sure the global function exists. +** A global function must exist in order for name resolution to work +** properly. +*/ +SQLITE_API int sqlite3_overload_function( + sqlite3 *db, + const char *zName, + int nArg +){ + int rc; + char *zCopy; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zName==0 || nArg<-2 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + sqlite3_mutex_enter(db->mutex); + rc = sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)!=0; + sqlite3_mutex_leave(db->mutex); + if( rc ) return SQLITE_OK; + zCopy = sqlite3_mprintf("%s", zName); + if( zCopy==0 ) return SQLITE_NOMEM; + return sqlite3_create_function_v2(db, zName, nArg, SQLITE_UTF8, + zCopy, sqlite3InvalidFunction, 0, 0, sqlite3_free); +} + +#ifndef SQLITE_OMIT_TRACE +/* +** Register a trace function. The pArg from the previously registered trace +** is returned. +** +** A NULL trace function means that no tracing is executes. A non-NULL +** trace is a pointer to a function that is invoked at the start of each +** SQL statement. +*/ +#ifndef SQLITE_OMIT_DEPRECATED +SQLITE_API void *sqlite3_trace(sqlite3 *db, void(*xTrace)(void*,const char*), void *pArg){ + void *pOld; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + pOld = db->pTraceArg; + db->mTrace = xTrace ? SQLITE_TRACE_LEGACY : 0; + db->trace.xLegacy = xTrace; + db->pTraceArg = pArg; + sqlite3_mutex_leave(db->mutex); + return pOld; +} +#endif /* SQLITE_OMIT_DEPRECATED */ + +/* Register a trace callback using the version-2 interface. +*/ +SQLITE_API int sqlite3_trace_v2( + sqlite3 *db, /* Trace this connection */ + unsigned mTrace, /* Mask of events to be traced */ + int(*xTrace)(unsigned,void*,void*,void*), /* Callback to invoke */ + void *pArg /* Context */ +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + return SQLITE_MISUSE_BKPT; + } +#endif + sqlite3_mutex_enter(db->mutex); + if( mTrace==0 ) xTrace = 0; + if( xTrace==0 ) mTrace = 0; + db->mTrace = mTrace; + db->trace.xV2 = xTrace; + db->pTraceArg = pArg; + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + +#ifndef SQLITE_OMIT_DEPRECATED +/* +** Register a profile function. The pArg from the previously registered +** profile function is returned. +** +** A NULL profile function means that no profiling is executes. A non-NULL +** profile is a pointer to a function that is invoked at the conclusion of +** each SQL statement that is run. +*/ +SQLITE_API void *sqlite3_profile( + sqlite3 *db, + void (*xProfile)(void*,const char*,sqlite_uint64), + void *pArg +){ + void *pOld; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + pOld = db->pProfileArg; + db->xProfile = xProfile; + db->pProfileArg = pArg; + db->mTrace &= SQLITE_TRACE_NONLEGACY_MASK; + if( db->xProfile ) db->mTrace |= SQLITE_TRACE_XPROFILE; + sqlite3_mutex_leave(db->mutex); + return pOld; +} +#endif /* SQLITE_OMIT_DEPRECATED */ +#endif /* SQLITE_OMIT_TRACE */ + +/* +** Register a function to be invoked when a transaction commits. +** If the invoked function returns non-zero, then the commit becomes a +** rollback. +*/ +SQLITE_API void *sqlite3_commit_hook( + sqlite3 *db, /* Attach the hook to this database */ + int (*xCallback)(void*), /* Function to invoke on each commit */ + void *pArg /* Argument to the function */ +){ + void *pOld; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + pOld = db->pCommitArg; + db->xCommitCallback = xCallback; + db->pCommitArg = pArg; + sqlite3_mutex_leave(db->mutex); + return pOld; +} + +/* +** Register a callback to be invoked each time a row is updated, +** inserted or deleted using this database connection. +*/ +SQLITE_API void *sqlite3_update_hook( + sqlite3 *db, /* Attach the hook to this database */ + void (*xCallback)(void*,int,char const *,char const *,sqlite_int64), + void *pArg /* Argument to the function */ +){ + void *pRet; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + pRet = db->pUpdateArg; + db->xUpdateCallback = xCallback; + db->pUpdateArg = pArg; + sqlite3_mutex_leave(db->mutex); + return pRet; +} + +/* +** Register a callback to be invoked each time a transaction is rolled +** back by this database connection. +*/ +SQLITE_API void *sqlite3_rollback_hook( + sqlite3 *db, /* Attach the hook to this database */ + void (*xCallback)(void*), /* Callback function */ + void *pArg /* Argument to the function */ +){ + void *pRet; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + pRet = db->pRollbackArg; + db->xRollbackCallback = xCallback; + db->pRollbackArg = pArg; + sqlite3_mutex_leave(db->mutex); + return pRet; +} + +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +/* +** Register a callback to be invoked each time a row is updated, +** inserted or deleted using this database connection. +*/ +SQLITE_API void *sqlite3_preupdate_hook( + sqlite3 *db, /* Attach the hook to this database */ + void(*xCallback)( /* Callback function */ + void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64), + void *pArg /* First callback argument */ +){ + void *pRet; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( db==0 ){ + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + pRet = db->pPreUpdateArg; + db->xPreUpdateCallback = xCallback; + db->pPreUpdateArg = pArg; + sqlite3_mutex_leave(db->mutex); + return pRet; +} +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ + +/* +** Register a function to be invoked prior to each autovacuum that +** determines the number of pages to vacuum. +*/ +SQLITE_API int sqlite3_autovacuum_pages( + sqlite3 *db, /* Attach the hook to this database */ + unsigned int (*xCallback)(void*,const char*,u32,u32,u32), + void *pArg, /* Argument to the function */ + void (*xDestructor)(void*) /* Destructor for pArg */ +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + if( xDestructor ) xDestructor(pArg); + return SQLITE_MISUSE_BKPT; + } +#endif + sqlite3_mutex_enter(db->mutex); + if( db->xAutovacDestr ){ + db->xAutovacDestr(db->pAutovacPagesArg); + } + db->xAutovacPages = xCallback; + db->pAutovacPagesArg = pArg; + db->xAutovacDestr = xDestructor; + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + + +#ifndef SQLITE_OMIT_WAL +/* +** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint(). +** Invoke sqlite3_wal_checkpoint if the number of frames in the log file +** is greater than sqlite3.pWalArg cast to an integer (the value configured by +** wal_autocheckpoint()). +*/ +SQLITE_PRIVATE int sqlite3WalDefaultHook( + void *pClientData, /* Argument */ + sqlite3 *db, /* Connection */ + const char *zDb, /* Database */ + int nFrame /* Size of WAL */ +){ + if( nFrame>=SQLITE_PTR_TO_INT(pClientData) ){ + sqlite3BeginBenignMalloc(); + sqlite3_wal_checkpoint(db, zDb); + sqlite3EndBenignMalloc(); + } + return SQLITE_OK; +} +#endif /* SQLITE_OMIT_WAL */ + +/* +** Configure an sqlite3_wal_hook() callback to automatically checkpoint +** a database after committing a transaction if there are nFrame or +** more frames in the log file. Passing zero or a negative value as the +** nFrame parameter disables automatic checkpoints entirely. +** +** The callback registered by this function replaces any existing callback +** registered using sqlite3_wal_hook(). Likewise, registering a callback +** using sqlite3_wal_hook() disables the automatic checkpoint mechanism +** configured by this function. +*/ +SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){ +#ifdef SQLITE_OMIT_WAL + UNUSED_PARAMETER(db); + UNUSED_PARAMETER(nFrame); +#else +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + if( nFrame>0 ){ + sqlite3_wal_hook(db, sqlite3WalDefaultHook, SQLITE_INT_TO_PTR(nFrame)); + }else{ + sqlite3_wal_hook(db, 0, 0); + } +#endif + return SQLITE_OK; +} + +/* +** Register a callback to be invoked each time a transaction is written +** into the write-ahead-log by this database connection. +*/ +SQLITE_API void *sqlite3_wal_hook( + sqlite3 *db, /* Attach the hook to this db handle */ + int(*xCallback)(void *, sqlite3*, const char*, int), + void *pArg /* First argument passed to xCallback() */ +){ +#ifndef SQLITE_OMIT_WAL + void *pRet; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + pRet = db->pWalArg; + db->xWalCallback = xCallback; + db->pWalArg = pArg; + sqlite3_mutex_leave(db->mutex); + return pRet; +#else + UNUSED_PARAMETER(db); + UNUSED_PARAMETER(xCallback); + UNUSED_PARAMETER(pArg); + return 0; +#endif +} + +/* +** Checkpoint database zDb. +*/ +SQLITE_API int sqlite3_wal_checkpoint_v2( + sqlite3 *db, /* Database handle */ + const char *zDb, /* Name of attached database (or NULL) */ + int eMode, /* SQLITE_CHECKPOINT_* value */ + int *pnLog, /* OUT: Size of WAL log in frames */ + int *pnCkpt /* OUT: Total number of frames checkpointed */ +){ +#ifdef SQLITE_OMIT_WAL + UNUSED_PARAMETER(db); + UNUSED_PARAMETER(zDb); + UNUSED_PARAMETER(eMode); + UNUSED_PARAMETER(pnLog); + UNUSED_PARAMETER(pnCkpt); + return SQLITE_OK; +#else + int rc; /* Return code */ + int iDb; /* Schema to checkpoint */ + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + + /* Initialize the output variables to -1 in case an error occurs. */ + if( pnLog ) *pnLog = -1; + if( pnCkpt ) *pnCkpt = -1; + + assert( SQLITE_CHECKPOINT_NOOP==-1 ); + assert( SQLITE_CHECKPOINT_PASSIVE==0 ); + assert( SQLITE_CHECKPOINT_FULL==1 ); + assert( SQLITE_CHECKPOINT_RESTART==2 ); + assert( SQLITE_CHECKPOINT_TRUNCATE==3 ); + if( eModeSQLITE_CHECKPOINT_TRUNCATE ){ + /* EVIDENCE-OF: R-03996-12088 The M parameter must be a valid checkpoint + ** mode: */ + return SQLITE_MISUSE_BKPT; + } + + sqlite3_mutex_enter(db->mutex); + if( zDb && zDb[0] ){ + iDb = sqlite3FindDbName(db, zDb); + }else{ + iDb = SQLITE_MAX_DB; /* This means process all schemas */ + } + if( iDb<0 ){ + rc = SQLITE_ERROR; + sqlite3ErrorWithMsg(db, SQLITE_ERROR, "unknown database: %s", zDb); + }else{ + db->busyHandler.nBusy = 0; + rc = sqlite3Checkpoint(db, iDb, eMode, pnLog, pnCkpt); + sqlite3Error(db, rc); + } + rc = sqlite3ApiExit(db, rc); + + /* If there are no active statements, clear the interrupt flag at this + ** point. */ + if( db->nVdbeActive==0 ){ + AtomicStore(&db->u1.isInterrupted, 0); + } + + sqlite3_mutex_leave(db->mutex); + return rc; +#endif +} + + +/* +** Checkpoint database zDb. If zDb is NULL, or if the buffer zDb points +** to contains a zero-length string, all attached databases are +** checkpointed. +*/ +SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){ + /* EVIDENCE-OF: R-41613-20553 The sqlite3_wal_checkpoint(D,X) is equivalent to + ** sqlite3_wal_checkpoint_v2(D,X,SQLITE_CHECKPOINT_PASSIVE,0,0). */ + return sqlite3_wal_checkpoint_v2(db,zDb,SQLITE_CHECKPOINT_PASSIVE,0,0); +} + +#ifndef SQLITE_OMIT_WAL +/* +** Run a checkpoint on database iDb. This is a no-op if database iDb is +** not currently open in WAL mode. +** +** If a transaction is open on the database being checkpointed, this +** function returns SQLITE_LOCKED and a checkpoint is not attempted. If +** an error occurs while running the checkpoint, an SQLite error code is +** returned (i.e. SQLITE_IOERR). Otherwise, SQLITE_OK. +** +** The mutex on database handle db should be held by the caller. The mutex +** associated with the specific b-tree being checkpointed is taken by +** this function while the checkpoint is running. +** +** If iDb is passed SQLITE_MAX_DB then all attached databases are +** checkpointed. If an error is encountered it is returned immediately - +** no attempt is made to checkpoint any remaining databases. +** +** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL, RESTART +** or TRUNCATE. +*/ +SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3 *db, int iDb, int eMode, int *pnLog, int *pnCkpt){ + int rc = SQLITE_OK; /* Return code */ + int i; /* Used to iterate through attached dbs */ + int bBusy = 0; /* True if SQLITE_BUSY has been encountered */ + + assert( sqlite3_mutex_held(db->mutex) ); + assert( !pnLog || *pnLog==-1 ); + assert( !pnCkpt || *pnCkpt==-1 ); + testcase( iDb==SQLITE_MAX_ATTACHED ); /* See forum post a006d86f72 */ + testcase( iDb==SQLITE_MAX_DB ); + + for(i=0; inDb && rc==SQLITE_OK; i++){ + if( i==iDb || iDb==SQLITE_MAX_DB ){ + rc = sqlite3BtreeCheckpoint(db->aDb[i].pBt, eMode, pnLog, pnCkpt); + pnLog = 0; + pnCkpt = 0; + if( rc==SQLITE_BUSY ){ + bBusy = 1; + rc = SQLITE_OK; + } + } + } + + return (rc==SQLITE_OK && bBusy) ? SQLITE_BUSY : rc; +} +#endif /* SQLITE_OMIT_WAL */ + +/* +** This function returns true if main-memory should be used instead of +** a temporary file for transient pager files and statement journals. +** The value returned depends on the value of db->temp_store (runtime +** parameter) and the compile time value of SQLITE_TEMP_STORE. The +** following table describes the relationship between these two values +** and this functions return value. +** +** SQLITE_TEMP_STORE db->temp_store Location of temporary database +** ----------------- -------------- ------------------------------ +** 0 any file (return 0) +** 1 1 file (return 0) +** 1 2 memory (return 1) +** 1 0 file (return 0) +** 2 1 file (return 0) +** 2 2 memory (return 1) +** 2 0 memory (return 1) +** 3 any memory (return 1) +*/ +SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3 *db){ +#if SQLITE_TEMP_STORE==1 + return ( db->temp_store==2 ); +#endif +#if SQLITE_TEMP_STORE==2 + return ( db->temp_store!=1 ); +#endif +#if SQLITE_TEMP_STORE==3 + UNUSED_PARAMETER(db); + return 1; +#endif +#if SQLITE_TEMP_STORE<1 || SQLITE_TEMP_STORE>3 + UNUSED_PARAMETER(db); + return 0; +#endif +} + +/* +** Return UTF-8 encoded English language explanation of the most recent +** error. +*/ +SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){ + const char *z; + if( !db ){ + return sqlite3ErrStr(SQLITE_NOMEM_BKPT); + } + if( !sqlite3SafetyCheckSickOrOk(db) ){ + return sqlite3ErrStr(SQLITE_MISUSE_BKPT); + } + sqlite3_mutex_enter(db->mutex); + if( db->mallocFailed ){ + z = sqlite3ErrStr(SQLITE_NOMEM_BKPT); + }else{ + testcase( db->pErr==0 ); + z = db->errCode ? (char*)sqlite3_value_text(db->pErr) : 0; + assert( !db->mallocFailed ); + if( z==0 ){ + z = sqlite3ErrStr(db->errCode); + } + } + sqlite3_mutex_leave(db->mutex); + return z; +} + +/* +** Set the error code and error message associated with the database handle. +** +** This routine is intended to be called by outside extensions (ex: the +** Session extension). Internal logic should invoke sqlite3Error() or +** sqlite3ErrorWithMsg() directly. +*/ +SQLITE_API int sqlite3_set_errmsg(sqlite3 *db, int errcode, const char *zMsg){ + int rc = SQLITE_OK; + if( !sqlite3SafetyCheckOk(db) ){ + return SQLITE_MISUSE_BKPT; + } + sqlite3_mutex_enter(db->mutex); + if( zMsg ){ + sqlite3ErrorWithMsg(db, errcode, "%s", zMsg); + }else{ + sqlite3Error(db, errcode); + } + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Return the byte offset of the most recent error +*/ +SQLITE_API int sqlite3_error_offset(sqlite3 *db){ + int iOffset = -1; + if( db && sqlite3SafetyCheckSickOrOk(db) ){ + sqlite3_mutex_enter(db->mutex); + if( db->errCode ){ + iOffset = db->errByteOffset; + } + sqlite3_mutex_leave(db->mutex); + } + return iOffset; +} + +#ifndef SQLITE_OMIT_UTF16 +/* +** Return UTF-16 encoded English language explanation of the most recent +** error. +*/ +SQLITE_API const void *sqlite3_errmsg16(sqlite3 *db){ + static const u16 outOfMem[] = { + 'o', 'u', 't', ' ', 'o', 'f', ' ', 'm', 'e', 'm', 'o', 'r', 'y', 0 + }; + static const u16 misuse[] = { + 'b', 'a', 'd', ' ', 'p', 'a', 'r', 'a', 'm', 'e', 't', 'e', 'r', ' ', + 'o', 'r', ' ', 'o', 't', 'h', 'e', 'r', ' ', 'A', 'P', 'I', ' ', + 'm', 'i', 's', 'u', 's', 'e', 0 + }; + + const void *z; + if( !db ){ + return (void *)outOfMem; + } + if( !sqlite3SafetyCheckSickOrOk(db) ){ + return (void *)misuse; + } + sqlite3_mutex_enter(db->mutex); + if( db->mallocFailed ){ + z = (void *)outOfMem; + }else{ + z = sqlite3_value_text16(db->pErr); + if( z==0 ){ + sqlite3ErrorWithMsg(db, db->errCode, sqlite3ErrStr(db->errCode)); + z = sqlite3_value_text16(db->pErr); + } + /* A malloc() may have failed within the call to sqlite3_value_text16() + ** above. If this is the case, then the db->mallocFailed flag needs to + ** be cleared before returning. Do this directly, instead of via + ** sqlite3ApiExit(), to avoid setting the database handle error message. + */ + sqlite3OomClear(db); + } + sqlite3_mutex_leave(db->mutex); + return z; +} +#endif /* SQLITE_OMIT_UTF16 */ + +/* +** Return the most recent error code generated by an SQLite routine. If NULL is +** passed to this function, we assume a malloc() failed during sqlite3_open(). +*/ +SQLITE_API int sqlite3_errcode(sqlite3 *db){ + int iRet; + if( !db ) return SQLITE_NOMEM_BKPT; + if( !sqlite3SafetyCheckSickOrOk(db) ){ + return SQLITE_MISUSE_BKPT; + } + sqlite3_mutex_enter(db->mutex); + if( db->mallocFailed ){ + iRet = SQLITE_NOMEM_BKPT; + }else{ + iRet = db->errCode & db->errMask; + } + sqlite3_mutex_leave(db->mutex); + return iRet; +} +SQLITE_API int sqlite3_extended_errcode(sqlite3 *db){ + int iRet; + if( !db ) return SQLITE_NOMEM_BKPT; + if( !sqlite3SafetyCheckSickOrOk(db) ){ + return SQLITE_MISUSE_BKPT; + } + sqlite3_mutex_enter(db->mutex); + if( db->mallocFailed ){ + iRet = SQLITE_NOMEM_BKPT; + }else{ + iRet = db->errCode; + } + sqlite3_mutex_leave(db->mutex); + return iRet; +} +SQLITE_API int sqlite3_system_errno(sqlite3 *db){ + int iRet = 0; + if( db ){ + sqlite3_mutex_enter(db->mutex); + iRet = db->iSysErrno; + sqlite3_mutex_leave(db->mutex); + } + return iRet; +} + +/* +** Return a string that describes the kind of error specified in the +** argument. For now, this simply calls the internal sqlite3ErrStr() +** function. +*/ +SQLITE_API const char *sqlite3_errstr(int rc){ + return sqlite3ErrStr(rc); +} + +/* +** Create a new collating function for database "db". The name is zName +** and the encoding is enc. +*/ +static int createCollation( + sqlite3* db, + const char *zName, + u8 enc, + void* pCtx, + int(*xCompare)(void*,int,const void*,int,const void*), + void(*xDel)(void*) +){ + CollSeq *pColl; + int enc2; + + assert( sqlite3_mutex_held(db->mutex) ); + + /* If SQLITE_UTF16 is specified as the encoding type, transform this + ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the + ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally. + */ + enc2 = enc; + testcase( enc2==SQLITE_UTF16 ); + testcase( enc2==SQLITE_UTF16_ALIGNED ); + if( enc2==SQLITE_UTF16 || enc2==SQLITE_UTF16_ALIGNED ){ + enc2 = SQLITE_UTF16NATIVE; + } + if( enc2SQLITE_UTF16BE ){ + return SQLITE_MISUSE_BKPT; + } + + /* Check if this call is removing or replacing an existing collation + ** sequence. If so, and there are active VMs, return busy. If there + ** are no active VMs, invalidate any pre-compiled statements. + */ + pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 0); + if( pColl && pColl->xCmp ){ + if( db->nVdbeActive ){ + sqlite3ErrorWithMsg(db, SQLITE_BUSY, + "unable to delete/modify collation sequence due to active statements"); + return SQLITE_BUSY; + } + sqlite3ExpirePreparedStatements(db, 0); + + /* If collation sequence pColl was created directly by a call to + ** sqlite3_create_collation, and not generated by synthCollSeq(), + ** then any copies made by synthCollSeq() need to be invalidated. + ** Also, collation destructor - CollSeq.xDel() - function may need + ** to be called. + */ + if( (pColl->enc & ~SQLITE_UTF16_ALIGNED)==enc2 ){ + CollSeq *aColl = sqlite3HashFind(&db->aCollSeq, zName); + int j; + for(j=0; j<3; j++){ + CollSeq *p = &aColl[j]; + if( p->enc==pColl->enc ){ + if( p->xDel ){ + p->xDel(p->pUser); + } + p->xCmp = 0; + } + } + } + } + + pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 1); + if( pColl==0 ) return SQLITE_NOMEM_BKPT; + pColl->xCmp = xCompare; + pColl->pUser = pCtx; + pColl->xDel = xDel; + pColl->enc = (u8)(enc2 | (enc & SQLITE_UTF16_ALIGNED)); + sqlite3Error(db, SQLITE_OK); + return SQLITE_OK; +} + + +/* +** This array defines hard upper bounds on limit values. The +** initializer must be kept in sync with the SQLITE_LIMIT_* +** #defines in sqlite3.h. +*/ +static const int aHardLimit[] = { + SQLITE_MAX_LENGTH, + SQLITE_MAX_SQL_LENGTH, + SQLITE_MAX_COLUMN, + SQLITE_MAX_EXPR_DEPTH, + SQLITE_MAX_COMPOUND_SELECT, + SQLITE_MAX_VDBE_OP, + SQLITE_MAX_FUNCTION_ARG, + SQLITE_MAX_ATTACHED, + SQLITE_MAX_LIKE_PATTERN_LENGTH, + SQLITE_MAX_VARIABLE_NUMBER, /* IMP: R-38091-32352 */ + SQLITE_MAX_TRIGGER_DEPTH, + SQLITE_MAX_WORKER_THREADS, + SQLITE_MAX_PARSER_DEPTH, +}; + +/* +** Make sure the hard limits are set to reasonable values +*/ +#if SQLITE_MAX_LENGTH<100 +# error SQLITE_MAX_LENGTH must be at least 100 +#endif +#if SQLITE_MAX_SQL_LENGTH<100 +# error SQLITE_MAX_SQL_LENGTH must be at least 100 +#endif +#if SQLITE_MAX_SQL_LENGTH>SQLITE_MAX_LENGTH +# error SQLITE_MAX_SQL_LENGTH must not be greater than SQLITE_MAX_LENGTH +#endif +#if SQLITE_MAX_SQL_LENGTH>2147482624 /* 1024 less than 2^31 */ +# error SQLITE_MAX_SQL_LENGTH must not be greater than 2147482624 +#endif +#if SQLITE_MAX_COMPOUND_SELECT<2 +# error SQLITE_MAX_COMPOUND_SELECT must be at least 2 +#endif +#if SQLITE_MAX_VDBE_OP<40 +# error SQLITE_MAX_VDBE_OP must be at least 40 +#endif +#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>32767 +# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 32767 +#endif +#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>125 +# error SQLITE_MAX_ATTACHED must be between 0 and 125 +#endif +#if SQLITE_MAX_LIKE_PATTERN_LENGTH<1 +# error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1 +#endif +#if SQLITE_MAX_COLUMN>32767 +# error SQLITE_MAX_COLUMN must not exceed 32767 +#endif +#if SQLITE_MAX_TRIGGER_DEPTH<1 +# error SQLITE_MAX_TRIGGER_DEPTH must be at least 1 +#endif +#if SQLITE_MAX_WORKER_THREADS<0 || SQLITE_MAX_WORKER_THREADS>50 +# error SQLITE_MAX_WORKER_THREADS must be between 0 and 50 +#endif + + +/* +** Change the value of a limit. Report the old value. +** If an invalid limit index is supplied, report -1. +** Make no changes but still report the old value if the +** new limit is negative. +** +** A new lower limit does not shrink existing constructs. +** It merely prevents new constructs that exceed the limit +** from forming. +*/ +SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ + int oldLimit; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return -1; + } +#endif + + /* EVIDENCE-OF: R-30189-54097 For each limit category SQLITE_LIMIT_NAME + ** there is a hard upper bound set at compile-time by a C preprocessor + ** macro called SQLITE_MAX_NAME. (The "_LIMIT_" in the name is changed to + ** "_MAX_".) + */ + assert( aHardLimit[SQLITE_LIMIT_LENGTH]==SQLITE_MAX_LENGTH ); + assert( aHardLimit[SQLITE_LIMIT_SQL_LENGTH]==SQLITE_MAX_SQL_LENGTH ); + assert( aHardLimit[SQLITE_LIMIT_COLUMN]==SQLITE_MAX_COLUMN ); + assert( aHardLimit[SQLITE_LIMIT_EXPR_DEPTH]==SQLITE_MAX_EXPR_DEPTH ); + assert( aHardLimit[SQLITE_LIMIT_PARSER_DEPTH]==SQLITE_MAX_PARSER_DEPTH ); + assert( aHardLimit[SQLITE_LIMIT_COMPOUND_SELECT]==SQLITE_MAX_COMPOUND_SELECT); + assert( aHardLimit[SQLITE_LIMIT_VDBE_OP]==SQLITE_MAX_VDBE_OP ); + assert( aHardLimit[SQLITE_LIMIT_FUNCTION_ARG]==SQLITE_MAX_FUNCTION_ARG ); + assert( aHardLimit[SQLITE_LIMIT_ATTACHED]==SQLITE_MAX_ATTACHED ); + assert( aHardLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]== + SQLITE_MAX_LIKE_PATTERN_LENGTH ); + assert( aHardLimit[SQLITE_LIMIT_VARIABLE_NUMBER]==SQLITE_MAX_VARIABLE_NUMBER); + assert( aHardLimit[SQLITE_LIMIT_TRIGGER_DEPTH]==SQLITE_MAX_TRIGGER_DEPTH ); + assert( aHardLimit[SQLITE_LIMIT_WORKER_THREADS]==SQLITE_MAX_WORKER_THREADS ); + assert( SQLITE_LIMIT_PARSER_DEPTH==(SQLITE_N_LIMIT-1) ); + + + if( limitId<0 || limitId>=SQLITE_N_LIMIT ){ + return -1; + } + sqlite3_mutex_enter(db->mutex); + oldLimit = db->aLimit[limitId]; + if( newLimit>=0 ){ /* IMP: R-52476-28732 */ + if( newLimit>aHardLimit[limitId] ){ + newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */ + }else if( newLimitaLimit[limitId] = newLimit; + } + sqlite3_mutex_leave(db->mutex); + return oldLimit; /* IMP: R-53341-35419 */ +} + +/* +** This function is used to parse both URIs and non-URI filenames passed by the +** user to API functions sqlite3_open() or sqlite3_open_v2(), and for database +** URIs specified as part of ATTACH statements. +** +** The first argument to this function is the name of the VFS to use (or +** a NULL to signify the default VFS) if the URI does not contain a "vfs=xxx" +** query parameter. The second argument contains the URI (or non-URI filename) +** itself. When this function is called the *pFlags variable should contain +** the default flags to open the database handle with. The value stored in +** *pFlags may be updated before returning if the URI filename contains +** "cache=xxx" or "mode=xxx" query parameters. +** +** If successful, SQLITE_OK is returned. In this case *ppVfs is set to point to +** the VFS that should be used to open the database file. *pzFile is set to +** point to a buffer containing the name of the file to open. The value +** stored in *pzFile is a database name acceptable to sqlite3_uri_parameter() +** and is in the same format as names created using sqlite3_create_filename(). +** The caller must invoke sqlite3_free_filename() (not sqlite3_free()!) on +** the value returned in *pzFile to avoid a memory leak. +** +** If an error occurs, then an SQLite error code is returned and *pzErrMsg +** may be set to point to a buffer containing an English language error +** message. It is the responsibility of the caller to eventually release +** this buffer by calling sqlite3_free(). +*/ +SQLITE_PRIVATE int sqlite3ParseUri( + const char *zDefaultVfs, /* VFS to use if no "vfs=xxx" query option */ + const char *zUri, /* Nul-terminated URI to parse */ + unsigned int *pFlags, /* IN/OUT: SQLITE_OPEN_XXX flags */ + sqlite3_vfs **ppVfs, /* OUT: VFS to use */ + char **pzFile, /* OUT: Filename component of URI */ + char **pzErrMsg /* OUT: Error message (if rc!=SQLITE_OK) */ +){ + int rc = SQLITE_OK; + unsigned int flags = *pFlags; + const char *zVfs = zDefaultVfs; + char *zFile; + char c; + i64 nUri = strlen(zUri); + + assert( *pzErrMsg==0 ); + + if( ((flags & SQLITE_OPEN_URI) /* IMP: R-48725-32206 */ + || AtomicLoad(&sqlite3GlobalConfig.bOpenUri)) /* IMP: R-51689-46548 */ + && nUri>=5 && memcmp(zUri, "file:", 5)==0 /* IMP: R-57884-37496 */ + ){ + char *zOpt; + int eState; /* Parser state when parsing URI */ + i64 iIn; /* Input character index */ + i64 iOut = 0; /* Output character index */ + u64 nByte = nUri+8; /* Bytes of space to allocate */ + + /* Make sure the SQLITE_OPEN_URI flag is set to indicate to the VFS xOpen + ** method that there may be extra parameters following the file-name. */ + flags |= SQLITE_OPEN_URI; + + for(iIn=0; iIn=0 && octet<256 ); + if( octet==0 ){ +#ifndef SQLITE_ENABLE_URI_00_ERROR + /* This branch is taken when "%00" appears within the URI. In this + ** case we ignore all text in the remainder of the path, name or + ** value currently being parsed. So ignore the current character + ** and skip to the next "?", "=" or "&", as appropriate. */ + while( (c = zUri[iIn])!=0 && c!='#' + && (eState!=0 || c!='?') + && (eState!=1 || (c!='=' && c!='&')) + && (eState!=2 || c!='&') + ){ + iIn++; + } + continue; +#else + /* If ENABLE_URI_00_ERROR is defined, "%00" in a URI is an error. */ + *pzErrMsg = sqlite3_mprintf("unexpected %%00 in uri"); + rc = SQLITE_ERROR; + goto parse_uri_out; +#endif + } + c = octet; + }else if( eState==1 && (c=='&' || c=='=') ){ + if( zFile[iOut-1]==0 ){ + /* An empty option name. Ignore this option altogether. */ + while( zUri[iIn] && zUri[iIn]!='#' && zUri[iIn-1]!='&' ) iIn++; + continue; + } + if( c=='&' ){ + zFile[iOut++] = '\0'; + }else{ + eState = 2; + } + c = 0; + }else if( (eState==0 && c=='?') || (eState==2 && c=='&') ){ + c = 0; + eState = 1; + } + zFile[iOut++] = c; + } + if( eState==1 ) zFile[iOut++] = '\0'; + memset(zFile+iOut, 0, 4); /* end-of-options + empty journal filenames */ + + /* Check if there were any options specified that should be interpreted + ** here. Options that are interpreted here include "vfs" and those that + ** correspond to flags that may be passed to the sqlite3_open_v2() + ** method. */ + zOpt = &zFile[strlen(zFile)+1]; + while( zOpt[0] ){ + i64 nOpt = strlen(zOpt); + char *zVal = &zOpt[nOpt+1]; + i64 nVal = strlen(zVal); + + if( nOpt==3 && memcmp("vfs", zOpt, 3)==0 ){ + zVfs = zVal; + }else{ + struct OpenMode { + const char *z; + int mode; + } *aMode = 0; + char *zModeType = 0; + int mask = 0; + int limit = 0; + + if( nOpt==5 && memcmp("cache", zOpt, 5)==0 ){ + static struct OpenMode aCacheMode[] = { + { "shared", SQLITE_OPEN_SHAREDCACHE }, + { "private", SQLITE_OPEN_PRIVATECACHE }, + { 0, 0 } + }; + + mask = SQLITE_OPEN_SHAREDCACHE|SQLITE_OPEN_PRIVATECACHE; + aMode = aCacheMode; + limit = mask; + zModeType = "cache"; + } + if( nOpt==4 && memcmp("mode", zOpt, 4)==0 ){ + static struct OpenMode aOpenMode[] = { + { "ro", SQLITE_OPEN_READONLY }, + { "rw", SQLITE_OPEN_READWRITE }, + { "rwc", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE }, + { "memory", SQLITE_OPEN_MEMORY }, + { 0, 0 } + }; + + mask = SQLITE_OPEN_READONLY | SQLITE_OPEN_READWRITE + | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY; + aMode = aOpenMode; + limit = mask & flags; + zModeType = "access"; + } + + if( aMode ){ + int i; + int mode = 0; + for(i=0; aMode[i].z; i++){ + const char *z = aMode[i].z; + if( nVal==(i64)strlen(z) && 0==memcmp(zVal, z, nVal) ){ + mode = aMode[i].mode; + break; + } + } + if( mode==0 ){ + *pzErrMsg = sqlite3_mprintf("no such %s mode: %s", zModeType, zVal); + rc = SQLITE_ERROR; + goto parse_uri_out; + } + if( (mode & ~SQLITE_OPEN_MEMORY)>limit ){ + *pzErrMsg = sqlite3_mprintf("%s mode not allowed: %s", + zModeType, zVal); + rc = SQLITE_PERM; + goto parse_uri_out; + } + flags = (flags & ~mask) | mode; + } + } + + zOpt = &zVal[nVal+1]; + } + + }else{ + zFile = sqlite3_malloc64(nUri+8); + if( !zFile ) return SQLITE_NOMEM_BKPT; + memset(zFile, 0, 4); + zFile += 4; + if( nUri ){ + memcpy(zFile, zUri, nUri); + } + memset(zFile+nUri, 0, 4); + flags &= ~SQLITE_OPEN_URI; + } + + *ppVfs = sqlite3_vfs_find(zVfs); + if( *ppVfs==0 ){ + *pzErrMsg = sqlite3_mprintf("no such vfs: %s", zVfs); + rc = SQLITE_ERROR; + } + parse_uri_out: + if( rc!=SQLITE_OK ){ + sqlite3_free_filename(zFile); + zFile = 0; + } + *pFlags = flags; + *pzFile = zFile; + return rc; +} + +/* +** This routine does the core work of extracting URI parameters from a +** database filename for the sqlite3_uri_parameter() interface. +*/ +static const char *uriParameter(const char *zFilename, const char *zParam){ + zFilename += sqlite3Strlen30(zFilename) + 1; + while( ALWAYS(zFilename!=0) && zFilename[0] ){ + int x = strcmp(zFilename, zParam); + zFilename += sqlite3Strlen30(zFilename) + 1; + if( x==0 ) return zFilename; + zFilename += sqlite3Strlen30(zFilename) + 1; + } + return 0; +} + + + +/* +** This routine does the work of opening a database on behalf of +** sqlite3_open() and sqlite3_open16(). The database filename "zFilename" +** is UTF-8 encoded. +*/ +static int openDatabase( + const char *zFilename, /* Database filename UTF-8 encoded */ + sqlite3 **ppDb, /* OUT: Returned database handle */ + unsigned int flags, /* Operational flags */ + const char *zVfs /* Name of the VFS to use */ +){ + sqlite3 *db; /* Store allocated handle here */ + int rc; /* Return code */ + int isThreadsafe; /* True for threadsafe connections */ + char *zOpen = 0; /* Filename argument to pass to BtreeOpen() */ + char *zErrMsg = 0; /* Error message from sqlite3ParseUri() */ + int i; /* Loop counter */ + +#ifdef SQLITE_ENABLE_API_ARMOR + if( ppDb==0 ) return SQLITE_MISUSE_BKPT; +#endif + *ppDb = 0; +#ifndef SQLITE_OMIT_AUTOINIT + rc = sqlite3_initialize(); + if( rc ) return rc; +#endif + + if( sqlite3GlobalConfig.bCoreMutex==0 ){ + isThreadsafe = 0; + }else if( flags & SQLITE_OPEN_NOMUTEX ){ + isThreadsafe = 0; + }else if( flags & SQLITE_OPEN_FULLMUTEX ){ + isThreadsafe = 1; + }else{ + isThreadsafe = sqlite3GlobalConfig.bFullMutex; + } + + if( flags & SQLITE_OPEN_PRIVATECACHE ){ + flags &= ~SQLITE_OPEN_SHAREDCACHE; + }else if( sqlite3GlobalConfig.sharedCacheEnabled ){ + flags |= SQLITE_OPEN_SHAREDCACHE; + } + + /* Remove harmful bits from the flags parameter + ** + ** The SQLITE_OPEN_NOMUTEX and SQLITE_OPEN_FULLMUTEX flags were + ** dealt with in the previous code block. Besides these, the only + ** valid input flags for sqlite3_open_v2() are SQLITE_OPEN_READONLY, + ** SQLITE_OPEN_READWRITE, SQLITE_OPEN_CREATE, SQLITE_OPEN_SHAREDCACHE, + ** SQLITE_OPEN_PRIVATECACHE, SQLITE_OPEN_EXRESCODE, and some reserved + ** bits. Silently mask off all other flags. + */ + flags &= ~( SQLITE_OPEN_DELETEONCLOSE | + SQLITE_OPEN_EXCLUSIVE | + SQLITE_OPEN_MAIN_DB | + SQLITE_OPEN_TEMP_DB | + SQLITE_OPEN_TRANSIENT_DB | + SQLITE_OPEN_MAIN_JOURNAL | + SQLITE_OPEN_TEMP_JOURNAL | + SQLITE_OPEN_SUBJOURNAL | + SQLITE_OPEN_SUPER_JOURNAL | + SQLITE_OPEN_NOMUTEX | + SQLITE_OPEN_FULLMUTEX | + SQLITE_OPEN_WAL + ); + + /* Allocate the sqlite data structure */ + db = sqlite3MallocZero( sizeof(sqlite3) ); + if( db==0 ) goto opendb_out; + if( isThreadsafe +#if defined(SQLITE_THREAD_MISUSE_WARNINGS) + || sqlite3GlobalConfig.bCoreMutex +#endif + ){ + db->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); + if( db->mutex==0 ){ + sqlite3_free(db); + db = 0; + goto opendb_out; + } + if( isThreadsafe==0 ){ + sqlite3MutexWarnOnContention(db->mutex); + } + } + sqlite3_mutex_enter(db->mutex); + db->errMask = (flags & SQLITE_OPEN_EXRESCODE)!=0 ? 0xffffffff : 0xff; + db->nDb = 2; + db->eOpenState = SQLITE_STATE_BUSY; + db->aDb = db->aDbStatic; + db->lookaside.bDisable = 1; + db->lookaside.sz = 0; + db->nFpDigit = 17; + + assert( sizeof(db->aLimit)==sizeof(aHardLimit) ); + memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); + db->aLimit[SQLITE_LIMIT_WORKER_THREADS] = SQLITE_DEFAULT_WORKER_THREADS; + db->autoCommit = 1; + db->nextAutovac = -1; + db->szMmap = sqlite3GlobalConfig.szMmap; + db->nextPagesize = 0; + db->init.azInit = sqlite3StdType; /* Any array of string ptrs will do */ +#ifdef SQLITE_ENABLE_SORTER_MMAP + /* Beginning with version 3.37.0, using the VFS xFetch() API to memory-map + ** the temporary files used to do external sorts (see code in vdbesort.c) + ** is disabled. It can still be used either by defining + ** SQLITE_ENABLE_SORTER_MMAP at compile time or by using the + ** SQLITE_TESTCTRL_SORTER_MMAP test-control at runtime. */ + db->nMaxSorterMmap = 0x7FFFFFFF; +#endif + db->flags |= SQLITE_ShortColNames + | SQLITE_EnableTrigger + | SQLITE_EnableView + | SQLITE_CacheSpill + | SQLITE_AttachCreate + | SQLITE_AttachWrite + | SQLITE_Comments +#if !defined(SQLITE_TRUSTED_SCHEMA) || SQLITE_TRUSTED_SCHEMA+0!=0 + | SQLITE_TrustedSchema +#endif +/* The SQLITE_DQS compile-time option determines the default settings +** for SQLITE_DBCONFIG_DQS_DDL and SQLITE_DBCONFIG_DQS_DML. +** +** SQLITE_DQS SQLITE_DBCONFIG_DQS_DDL SQLITE_DBCONFIG_DQS_DML +** ---------- ----------------------- ----------------------- +** undefined on on +** 3 on on +** 2 on off +** 1 off on +** 0 off off +** +** Legacy behavior is 3 (double-quoted string literals are allowed anywhere) +** and so that is the default. But developers are encouraged to use +** -DSQLITE_DQS=0 (best) or -DSQLITE_DQS=1 (second choice) if possible. +*/ +#if !defined(SQLITE_DQS) +# define SQLITE_DQS 3 +#endif +#if (SQLITE_DQS&1)==1 + | SQLITE_DqsDML +#endif +#if (SQLITE_DQS&2)==2 + | SQLITE_DqsDDL +#endif + +#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX + | SQLITE_AutoIndex +#endif +#if SQLITE_DEFAULT_CKPTFULLFSYNC + | SQLITE_CkptFullFSync +#endif +#if SQLITE_DEFAULT_FILE_FORMAT<4 + | SQLITE_LegacyFileFmt +#endif +#ifdef SQLITE_ENABLE_LOAD_EXTENSION + | SQLITE_LoadExtension +#endif +#if SQLITE_DEFAULT_RECURSIVE_TRIGGERS + | SQLITE_RecTriggers +#endif +#if defined(SQLITE_DEFAULT_FOREIGN_KEYS) && SQLITE_DEFAULT_FOREIGN_KEYS + | SQLITE_ForeignKeys +#endif +#if defined(SQLITE_REVERSE_UNORDERED_SELECTS) + | SQLITE_ReverseOrder +#endif +#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK) + | SQLITE_CellSizeCk +#endif +#if defined(SQLITE_ENABLE_FTS3_TOKENIZER) + | SQLITE_Fts3Tokenizer +#endif +#if defined(SQLITE_ENABLE_QPSG) + | SQLITE_EnableQPSG +#endif +#if defined(SQLITE_DEFAULT_DEFENSIVE) + | SQLITE_Defensive +#endif +#if defined(SQLITE_DEFAULT_LEGACY_ALTER_TABLE) + | SQLITE_LegacyAlter +#endif +#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) + | SQLITE_StmtScanStatus +#endif + ; + sqlite3HashInit(&db->aCollSeq); +#ifndef SQLITE_OMIT_VIRTUALTABLE + sqlite3HashInit(&db->aModule); +#endif + + /* Add the default collation sequence BINARY. BINARY works for both UTF-8 + ** and UTF-16, so add a version for each to avoid any unnecessary + ** conversions. The only error that can occur here is a malloc() failure. + ** + ** EVIDENCE-OF: R-52786-44878 SQLite defines three built-in collating + ** functions: + */ + createCollation(db, sqlite3StrBINARY, SQLITE_UTF8, 0, binCollFunc, 0); + createCollation(db, sqlite3StrBINARY, SQLITE_UTF16BE, 0, binCollFunc, 0); + createCollation(db, sqlite3StrBINARY, SQLITE_UTF16LE, 0, binCollFunc, 0); + createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0); + createCollation(db, "RTRIM", SQLITE_UTF8, 0, rtrimCollFunc, 0); + if( db->mallocFailed ){ + goto opendb_out; + } + +#if SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL) + /* Process magic filenames ":localStorage:" and ":sessionStorage:" */ + if( zFilename && zFilename[0]==':' ){ + if( strcmp(zFilename, ":localStorage:")==0 ){ + zFilename = "file:local?vfs=kvvfs"; + flags |= SQLITE_OPEN_URI; + }else if( strcmp(zFilename, ":sessionStorage:")==0 ){ + zFilename = "file:session?vfs=kvvfs"; + flags |= SQLITE_OPEN_URI; + } + } +#endif /* SQLITE_OS_UNIX && defined(SQLITE_OS_KV_OPTIONAL) */ + + /* Parse the filename/URI argument + ** + ** Only allow sensible combinations of bits in the flags argument. + ** Throw an error if any non-sense combination is used. If we + ** do not block illegal combinations here, it could trigger + ** assert() statements in deeper layers. Sensible combinations + ** are: + ** + ** 1: SQLITE_OPEN_READONLY + ** 2: SQLITE_OPEN_READWRITE + ** 6: SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE + */ + db->openFlags = flags; + assert( SQLITE_OPEN_READONLY == 0x01 ); + assert( SQLITE_OPEN_READWRITE == 0x02 ); + assert( SQLITE_OPEN_CREATE == 0x04 ); + testcase( (1<<(flags&7))==0x02 ); /* READONLY */ + testcase( (1<<(flags&7))==0x04 ); /* READWRITE */ + testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */ + if( ((1<<(flags&7)) & 0x46)==0 ){ + rc = SQLITE_MISUSE_BKPT; /* IMP: R-18321-05872 */ + }else{ + if( zFilename==0 ) zFilename = ":memory:"; + rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg); + } + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); + sqlite3ErrorWithMsg(db, rc, zErrMsg ? "%s" : 0, zErrMsg); + sqlite3_free(zErrMsg); + goto opendb_out; + } + assert( db->pVfs!=0 ); +#if SQLITE_OS_KV || defined(SQLITE_OS_KV_OPTIONAL) + if( sqlite3_stricmp(db->pVfs->zName, "kvvfs")==0 ){ + db->temp_store = 2; + } +#endif + + /* Open the backend database driver */ + rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, 0, + flags | SQLITE_OPEN_MAIN_DB); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_IOERR_NOMEM ){ + rc = SQLITE_NOMEM_BKPT; + } + sqlite3Error(db, rc); + goto opendb_out; + } + sqlite3BtreeEnter(db->aDb[0].pBt); + db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt); + if( !db->mallocFailed ){ + sqlite3SetTextEncoding(db, SCHEMA_ENC(db)); + } + sqlite3BtreeLeave(db->aDb[0].pBt); + db->aDb[1].pSchema = sqlite3SchemaGet(db, 0); + + /* The default safety_level for the main database is FULL; for the temp + ** database it is OFF. This matches the pager layer defaults. + */ + db->aDb[0].zDbSName = "main"; + db->aDb[0].safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1; + db->aDb[1].zDbSName = "temp"; + db->aDb[1].safety_level = PAGER_SYNCHRONOUS_OFF; + + db->eOpenState = SQLITE_STATE_OPEN; + if( db->mallocFailed ){ + goto opendb_out; + } + + /* Register all built-in functions, but do not attempt to read the + ** database schema yet. This is delayed until the first time the database + ** is accessed. + */ + sqlite3Error(db, SQLITE_OK); + sqlite3RegisterPerConnectionBuiltinFunctions(db); + rc = sqlite3_errcode(db); + + + /* Load compiled-in extensions */ + for(i=0; rc==SQLITE_OK && imDbFlags |= DBFLAG_InternalFunc; +#endif + + /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking + ** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking + ** mode. Doing nothing at all also makes NORMAL the default. + */ +#ifdef SQLITE_DEFAULT_LOCKING_MODE + db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE; + sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt), + SQLITE_DEFAULT_LOCKING_MODE); +#endif + + if( rc ) sqlite3Error(db, rc); + + /* Enable the lookaside-malloc subsystem */ + setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside, + sqlite3GlobalConfig.nLookaside); + + sqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_WAL_AUTOCHECKPOINT); + +opendb_out: + if( db ){ + assert( db->mutex!=0 || isThreadsafe==0 + || sqlite3GlobalConfig.bFullMutex==0 ); + sqlite3_mutex_leave(db->mutex); + } + rc = sqlite3_errcode(db); + assert( db!=0 || (rc&0xff)==SQLITE_NOMEM ); + if( (rc&0xff)==SQLITE_NOMEM ){ + sqlite3_close(db); + db = 0; + }else if( rc!=SQLITE_OK ){ + db->eOpenState = SQLITE_STATE_SICK; + } + *ppDb = db; +#ifdef SQLITE_ENABLE_SQLLOG + if( sqlite3GlobalConfig.xSqllog ){ + /* Opening a db handle. Fourth parameter is passed 0. */ + void *pArg = sqlite3GlobalConfig.pSqllogArg; + sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0); + } +#endif + sqlite3_free_filename(zOpen); + return rc; +} + + +/* +** Open a new database handle. +*/ +SQLITE_API int sqlite3_open( + const char *zFilename, + sqlite3 **ppDb +){ + return openDatabase(zFilename, ppDb, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0); +} +SQLITE_API int sqlite3_open_v2( + const char *filename, /* Database filename (UTF-8) */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs /* Name of VFS module to use */ +){ + return openDatabase(filename, ppDb, (unsigned int)flags, zVfs); +} + +#ifndef SQLITE_OMIT_UTF16 +/* +** Open a new database handle. +*/ +SQLITE_API int sqlite3_open16( + const void *zFilename, + sqlite3 **ppDb +){ + char const *zFilename8; /* zFilename encoded in UTF-8 instead of UTF-16 */ + sqlite3_value *pVal; + int rc; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( ppDb==0 ) return SQLITE_MISUSE_BKPT; +#endif + *ppDb = 0; +#ifndef SQLITE_OMIT_AUTOINIT + rc = sqlite3_initialize(); + if( rc ) return rc; +#endif + if( zFilename==0 ) zFilename = "\000\000"; + pVal = sqlite3ValueNew(0); + sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC); + zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8); + if( zFilename8 ){ + rc = openDatabase(zFilename8, ppDb, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0); + assert( *ppDb || rc==SQLITE_NOMEM ); + if( rc==SQLITE_OK && !DbHasProperty(*ppDb, 0, DB_SchemaLoaded) ){ + SCHEMA_ENC(*ppDb) = ENC(*ppDb) = SQLITE_UTF16NATIVE; + } + }else{ + rc = SQLITE_NOMEM_BKPT; + } + sqlite3ValueFree(pVal); + + return rc & 0xff; +} +#endif /* SQLITE_OMIT_UTF16 */ + +/* +** Register a new collation sequence with the database handle db. +*/ +SQLITE_API int sqlite3_create_collation( + sqlite3* db, + const char *zName, + int enc, + void* pCtx, + int(*xCompare)(void*,int,const void*,int,const void*) +){ + return sqlite3_create_collation_v2(db, zName, enc, pCtx, xCompare, 0); +} + +/* +** Register a new collation sequence with the database handle db. +*/ +SQLITE_API int sqlite3_create_collation_v2( + sqlite3* db, + const char *zName, + int enc, + void* pCtx, + int(*xCompare)(void*,int,const void*,int,const void*), + void(*xDel)(void*) +){ + int rc; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + assert( !db->mallocFailed ); + rc = createCollation(db, zName, (u8)enc, pCtx, xCompare, xDel); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +#ifndef SQLITE_OMIT_UTF16 +/* +** Register a new collation sequence with the database handle db. +*/ +SQLITE_API int sqlite3_create_collation16( + sqlite3* db, + const void *zName, + int enc, + void* pCtx, + int(*xCompare)(void*,int,const void*,int,const void*) +){ + int rc = SQLITE_OK; + char *zName8; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + assert( !db->mallocFailed ); + zName8 = sqlite3Utf16to8(db, zName, -1, SQLITE_UTF16NATIVE); + if( zName8 ){ + rc = createCollation(db, zName8, (u8)enc, pCtx, xCompare, 0); + sqlite3DbFree(db, zName8); + } + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} +#endif /* SQLITE_OMIT_UTF16 */ + +/* +** Register a collation sequence factory callback with the database handle +** db. Replace any previously installed collation sequence factory. +*/ +SQLITE_API int sqlite3_collation_needed( + sqlite3 *db, + void *pCollNeededArg, + void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*) +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + db->xCollNeeded = xCollNeeded; + db->xCollNeeded16 = 0; + db->pCollNeededArg = pCollNeededArg; + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + +#ifndef SQLITE_OMIT_UTF16 +/* +** Register a collation sequence factory callback with the database handle +** db. Replace any previously installed collation sequence factory. +*/ +SQLITE_API int sqlite3_collation_needed16( + sqlite3 *db, + void *pCollNeededArg, + void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*) +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + db->xCollNeeded = 0; + db->xCollNeeded16 = xCollNeeded16; + db->pCollNeededArg = pCollNeededArg; + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} +#endif /* SQLITE_OMIT_UTF16 */ + +/* +** Find existing client data. +*/ +SQLITE_API void *sqlite3_get_clientdata(sqlite3 *db, const char *zName){ + DbClientData *p; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !zName || !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + for(p=db->pDbData; p; p=p->pNext){ + if( strcmp(p->zName, zName)==0 ){ + void *pResult = p->pData; + sqlite3_mutex_leave(db->mutex); + return pResult; + } + } + sqlite3_mutex_leave(db->mutex); + return 0; +} + +/* +** Add new client data to a database connection. +*/ +SQLITE_API int sqlite3_set_clientdata( + sqlite3 *db, /* Attach client data to this connection */ + const char *zName, /* Name of the client data */ + void *pData, /* The client data itself */ + void (*xDestructor)(void*) /* Destructor */ +){ + DbClientData *p, **pp; + sqlite3_mutex_enter(db->mutex); + pp = &db->pDbData; + for(p=db->pDbData; p && strcmp(p->zName,zName); p=p->pNext){ + pp = &p->pNext; + } + if( p ){ + assert( p->pData!=0 ); + if( p->xDestructor ) p->xDestructor(p->pData); + if( pData==0 ){ + *pp = p->pNext; + sqlite3_free(p); + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; + } + }else if( pData==0 ){ + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; + }else{ + size_t n = strlen(zName); + p = sqlite3_malloc64( SZ_DBCLIENTDATA(n+1) ); + if( p==0 ){ + if( xDestructor ) xDestructor(pData); + sqlite3_mutex_leave(db->mutex); + return SQLITE_NOMEM; + } + memcpy(p->zName, zName, n+1); + p->pNext = db->pDbData; + db->pDbData = p; + } + p->pData = pData; + p->xDestructor = xDestructor; + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + + +#ifndef SQLITE_OMIT_DEPRECATED +/* +** This function is now an anachronism. It used to be used to recover from a +** malloc() failure, but SQLite now does this automatically. +*/ +SQLITE_API int sqlite3_global_recover(void){ + return SQLITE_OK; +} +#endif + +/* +** Test to see whether or not the database connection is in autocommit +** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on +** by default. Autocommit is disabled by a BEGIN statement and reenabled +** by the next COMMIT or ROLLBACK. +*/ +SQLITE_API int sqlite3_get_autocommit(sqlite3 *db){ + int iRet; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + iRet = db->autoCommit; + sqlite3_mutex_leave(db->mutex); + return iRet; +} + +/* +** The following routines are substitutes for constants SQLITE_CORRUPT, +** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_NOMEM and possibly other error +** constants. They serve two purposes: +** +** 1. Serve as a convenient place to set a breakpoint in a debugger +** to detect when version error conditions occurs. +** +** 2. Invoke sqlite3_log() to provide the source code location where +** a low-level error is first detected. +*/ +SQLITE_PRIVATE int sqlite3ReportError(int iErr, int lineno, const char *zType){ + sqlite3_log(iErr, "%s at line %d of [%.10s]", + zType, lineno, 20+sqlite3_sourceid()); + return iErr; +} +SQLITE_PRIVATE int sqlite3CorruptError(int lineno){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + return sqlite3ReportError(SQLITE_CORRUPT, lineno, "database corruption"); +} +SQLITE_PRIVATE int sqlite3MisuseError(int lineno){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + return sqlite3ReportError(SQLITE_MISUSE, lineno, "misuse"); +} +SQLITE_PRIVATE int sqlite3CantopenError(int lineno){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + return sqlite3ReportError(SQLITE_CANTOPEN, lineno, "cannot open file"); +} +#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_CORRUPT_PGNO) +SQLITE_PRIVATE int sqlite3CorruptPgnoError(int lineno, Pgno pgno){ + char zMsg[100]; + sqlite3_snprintf(sizeof(zMsg), zMsg, "database corruption page %d", pgno); + testcase( sqlite3GlobalConfig.xLog!=0 ); + return sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg); +} +#endif +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3NomemError(int lineno){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + return sqlite3ReportError(SQLITE_NOMEM, lineno, "OOM"); +} +SQLITE_PRIVATE int sqlite3IoerrnomemError(int lineno){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + return sqlite3ReportError(SQLITE_IOERR_NOMEM, lineno, "I/O OOM error"); +} +#endif + +#ifndef SQLITE_OMIT_DEPRECATED +/* +** This is a convenience routine that makes sure that all thread-specific +** data for this thread has been deallocated. +** +** SQLite no longer uses thread-specific data so this routine is now a +** no-op. It is retained for historical compatibility. +*/ +SQLITE_API void sqlite3_thread_cleanup(void){ +} +#endif + +/* +** Return meta information about a specific column of a database table. +** See comment in sqlite3.h (sqlite.h.in) for details. +*/ +SQLITE_API int sqlite3_table_column_metadata( + sqlite3 *db, /* Connection handle */ + const char *zDbName, /* Database name or NULL */ + const char *zTableName, /* Table name */ + const char *zColumnName, /* Column name */ + char const **pzDataType, /* OUTPUT: Declared data type */ + char const **pzCollSeq, /* OUTPUT: Collation sequence name */ + int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ + int *pPrimaryKey, /* OUTPUT: True if column part of PK */ + int *pAutoinc /* OUTPUT: True if column is auto-increment */ +){ + int rc; + char *zErrMsg = 0; + Table *pTab = 0; + Column *pCol = 0; + int iCol = 0; + char const *zDataType = 0; + char const *zCollSeq = 0; + int notnull = 0; + int primarykey = 0; + int autoinc = 0; + + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zTableName==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + + /* Ensure the database schema has been loaded */ + sqlite3_mutex_enter(db->mutex); + sqlite3BtreeEnterAll(db); + rc = sqlite3Init(db, &zErrMsg); + if( SQLITE_OK!=rc ){ + goto error_out; + } + + /* Locate the table in question */ + pTab = sqlite3FindTable(db, zTableName, zDbName); + if( !pTab || IsView(pTab) ){ + pTab = 0; + goto error_out; + } + + /* Find the column for which info is requested */ + if( zColumnName==0 ){ + /* Query for existence of table only */ + }else{ + iCol = sqlite3ColumnIndex(pTab, zColumnName); + if( iCol>=0 ){ + pCol = &pTab->aCol[iCol]; + }else{ + if( HasRowid(pTab) && sqlite3IsRowid(zColumnName) ){ + iCol = pTab->iPKey; + pCol = iCol>=0 ? &pTab->aCol[iCol] : 0; + }else{ + pTab = 0; + goto error_out; + } + } + } + + /* The following block stores the meta information that will be returned + ** to the caller in local variables zDataType, zCollSeq, notnull, primarykey + ** and autoinc. At this point there are two possibilities: + ** + ** 1. The specified column name was rowid", "oid" or "_rowid_" + ** and there is no explicitly declared IPK column. + ** + ** 2. The table is not a view and the column name identified an + ** explicitly declared column. Copy meta information from *pCol. + */ + if( pCol ){ + zDataType = sqlite3ColumnType(pCol,0); + zCollSeq = sqlite3ColumnColl(pCol); + notnull = pCol->notNull!=0; + primarykey = (pCol->colFlags & COLFLAG_PRIMKEY)!=0; + autoinc = pTab->iPKey==iCol && (pTab->tabFlags & TF_Autoincrement)!=0; + }else{ + zDataType = "INTEGER"; + primarykey = 1; + } + if( !zCollSeq ){ + zCollSeq = sqlite3StrBINARY; + } + +error_out: + sqlite3BtreeLeaveAll(db); + + /* Whether the function call succeeded or failed, set the output parameters + ** to whatever their local counterparts contain. If an error did occur, + ** this has the effect of zeroing all output parameters. + */ + if( pzDataType ) *pzDataType = zDataType; + if( pzCollSeq ) *pzCollSeq = zCollSeq; + if( pNotNull ) *pNotNull = notnull; + if( pPrimaryKey ) *pPrimaryKey = primarykey; + if( pAutoinc ) *pAutoinc = autoinc; + + if( SQLITE_OK==rc && !pTab ){ + sqlite3DbFree(db, zErrMsg); + zErrMsg = sqlite3MPrintf(db, "no such table column: %s.%s", zTableName, + zColumnName); + rc = SQLITE_ERROR; + } + sqlite3ErrorWithMsg(db, rc, (zErrMsg?"%s":0), zErrMsg); + sqlite3DbFree(db, zErrMsg); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Sleep for a little while. Return the amount of time slept. +*/ +SQLITE_API int sqlite3_sleep(int ms){ + sqlite3_vfs *pVfs; + int rc; + pVfs = sqlite3_vfs_find(0); + if( pVfs==0 ) return 0; + + /* This function works in milliseconds, but the underlying OsSleep() + ** API uses microseconds. Hence the 1000's. + */ + rc = (sqlite3OsSleep(pVfs, ms<0 ? 0 : 1000*ms)/1000); + return rc; +} + +/* +** Enable or disable the extended result codes. +*/ +SQLITE_API int sqlite3_extended_result_codes(sqlite3 *db, int onoff){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + db->errMask = onoff ? 0xffffffff : 0xff; + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + +/* +** Invoke the xFileControl method on a particular database. +*/ +SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){ + int rc = SQLITE_ERROR; + Btree *pBtree; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + pBtree = sqlite3DbNameToBtree(db, zDbName); + if( pBtree ){ + Pager *pPager; + sqlite3_file *fd; + sqlite3BtreeEnter(pBtree); + pPager = sqlite3BtreePager(pBtree); + assert( pPager!=0 ); + fd = sqlite3PagerFile(pPager); + assert( fd!=0 ); + if( op==SQLITE_FCNTL_FILE_POINTER ){ + *(sqlite3_file**)pArg = fd; + rc = SQLITE_OK; + }else if( op==SQLITE_FCNTL_VFS_POINTER ){ + *(sqlite3_vfs**)pArg = sqlite3PagerVfs(pPager); + rc = SQLITE_OK; + }else if( op==SQLITE_FCNTL_JOURNAL_POINTER ){ + *(sqlite3_file**)pArg = sqlite3PagerJrnlFile(pPager); + rc = SQLITE_OK; + }else if( op==SQLITE_FCNTL_DATA_VERSION ){ + *(unsigned int*)pArg = sqlite3PagerDataVersion(pPager); + rc = SQLITE_OK; + }else if( op==SQLITE_FCNTL_RESERVE_BYTES ){ + int iNew = *(int*)pArg; + *(int*)pArg = sqlite3BtreeGetRequestedReserve(pBtree); + if( iNew>=0 && iNew<=255 ){ + sqlite3BtreeSetPageSize(pBtree, 0, iNew, 0); + } + rc = SQLITE_OK; + }else if( op==SQLITE_FCNTL_RESET_CACHE ){ + sqlite3BtreeClearCache(pBtree); + rc = SQLITE_OK; + }else{ + int nSave = db->busyHandler.nBusy; + rc = sqlite3OsFileControl(fd, op, pArg); + db->busyHandler.nBusy = nSave; + } + sqlite3BtreeLeave(pBtree); + } + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** Interface to the testing logic. +*/ +SQLITE_API int sqlite3_test_control(int op, ...){ + int rc = 0; +#ifdef SQLITE_UNTESTABLE + UNUSED_PARAMETER(op); +#else + va_list ap; + va_start(ap, op); + switch( op ){ + + /* + ** Save the current state of the PRNG. + */ + case SQLITE_TESTCTRL_PRNG_SAVE: { + sqlite3PrngSaveState(); + break; + } + + /* + ** Restore the state of the PRNG to the last state saved using + ** PRNG_SAVE. If PRNG_SAVE has never before been called, then + ** this verb acts like PRNG_RESET. + */ + case SQLITE_TESTCTRL_PRNG_RESTORE: { + sqlite3PrngRestoreState(); + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED, int x, sqlite3 *db); + ** + ** Control the seed for the pseudo-random number generator (PRNG) that + ** is built into SQLite. Cases: + ** + ** x!=0 && db!=0 Seed the PRNG to the current value of the + ** schema cookie in the main database for db, or + ** x if the schema cookie is zero. This case + ** is convenient to use with database fuzzers + ** as it allows the fuzzer some control over the + ** the PRNG seed. + ** + ** x!=0 && db==0 Seed the PRNG to the value of x. + ** + ** x==0 && db==0 Revert to default behavior of using the + ** xRandomness method on the primary VFS. + ** + ** This test-control also resets the PRNG so that the new seed will + ** be used for the next call to sqlite3_randomness(). + */ +#ifndef SQLITE_OMIT_WSD + case SQLITE_TESTCTRL_PRNG_SEED: { + int x = va_arg(ap, int); + int y; + sqlite3 *db = va_arg(ap, sqlite3*); + assert( db==0 || db->aDb[0].pSchema!=0 ); + if( db && (y = db->aDb[0].pSchema->schema_cookie)!=0 ){ x = y; } + sqlite3Config.iPrngSeed = x; + sqlite3_randomness(0,0); + break; + } +#endif + + /* sqlite3_test_control(SQLITE_TESTCTRL_FK_NO_ACTION, sqlite3 *db, int b); + ** + ** If b is true, then activate the SQLITE_FkNoAction setting. If b is + ** false then clear that setting. If the SQLITE_FkNoAction setting is + ** enabled, all foreign key ON DELETE and ON UPDATE actions behave as if + ** they were NO ACTION, regardless of how they are defined. + ** + ** NB: One must usually run "PRAGMA writable_schema=RESET" after + ** using this test-control, before it will take full effect. failing + ** to reset the schema can result in some unexpected behavior. + */ + case SQLITE_TESTCTRL_FK_NO_ACTION: { + sqlite3 *db = va_arg(ap, sqlite3*); + int b = va_arg(ap, int); + if( b ){ + db->flags |= SQLITE_FkNoAction; + }else{ + db->flags &= ~SQLITE_FkNoAction; + } + break; + } + + /* + ** sqlite3_test_control(BITVEC_TEST, size, program) + ** + ** Run a test against a Bitvec object of size. The program argument + ** is an array of integers that defines the test. Return -1 on a + ** memory allocation error, 0 on success, or non-zero for an error. + ** See the sqlite3BitvecBuiltinTest() for additional information. + */ + case SQLITE_TESTCTRL_BITVEC_TEST: { + int sz = va_arg(ap, int); + int *aProg = va_arg(ap, int*); + rc = sqlite3BitvecBuiltinTest(sz, aProg); + break; + } + + /* + ** sqlite3_test_control(FAULT_INSTALL, xCallback) + ** + ** Arrange to invoke xCallback() whenever sqlite3FaultSim() is called, + ** if xCallback is not NULL. + ** + ** As a test of the fault simulator mechanism itself, sqlite3FaultSim(0) + ** is called immediately after installing the new callback and the return + ** value from sqlite3FaultSim(0) becomes the return from + ** sqlite3_test_control(). + */ + case SQLITE_TESTCTRL_FAULT_INSTALL: { + /* A bug in MSVC prevents it from understanding pointers to functions + ** types in the second argument to va_arg(). Work around the problem + ** using a typedef. + ** http://support.microsoft.com/kb/47961 <-- dead hyperlink + ** Search at http://web.archive.org/ to find the 2015-03-16 archive + ** of the link above to see the original text. + ** sqlite3GlobalConfig.xTestCallback = va_arg(ap, int(*)(int)); + */ + typedef int(*sqlite3FaultFuncType)(int); + sqlite3GlobalConfig.xTestCallback = va_arg(ap, sqlite3FaultFuncType); + rc = sqlite3FaultSim(0); + break; + } + + /* + ** sqlite3_test_control(BENIGN_MALLOC_HOOKS, xBegin, xEnd) + ** + ** Register hooks to call to indicate which malloc() failures + ** are benign. + */ + case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: { + typedef void (*void_function)(void); + void_function xBenignBegin; + void_function xBenignEnd; + xBenignBegin = va_arg(ap, void_function); + xBenignEnd = va_arg(ap, void_function); + sqlite3BenignMallocHooks(xBenignBegin, xBenignEnd); + break; + } + + /* + ** sqlite3_test_control(SQLITE_TESTCTRL_PENDING_BYTE, unsigned int X) + ** + ** Set the PENDING byte to the value in the argument, if X>0. + ** Make no changes if X==0. Return the value of the pending byte + ** as it existing before this routine was called. + ** + ** IMPORTANT: Changing the PENDING byte from 0x40000000 results in + ** an incompatible database file format. Changing the PENDING byte + ** while any database connection is open results in undefined and + ** deleterious behavior. + */ + case SQLITE_TESTCTRL_PENDING_BYTE: { + rc = PENDING_BYTE; +#ifndef SQLITE_OMIT_WSD + { + unsigned int newVal = va_arg(ap, unsigned int); + if( newVal ) sqlite3PendingByte = newVal; + } +#endif + break; + } + + /* + ** sqlite3_test_control(SQLITE_TESTCTRL_ASSERT, int X) + ** + ** This action provides a run-time test to see whether or not + ** assert() was enabled at compile-time. If X is true and assert() + ** is enabled, then the return value is true. If X is true and + ** assert() is disabled, then the return value is zero. If X is + ** false and assert() is enabled, then the assertion fires and the + ** process aborts. If X is false and assert() is disabled, then the + ** return value is zero. + */ + case SQLITE_TESTCTRL_ASSERT: { + volatile int x = 0; + assert( /*side-effects-ok*/ (x = va_arg(ap,int))!=0 ); + rc = x; +#if defined(SQLITE_DEBUG) + /* Invoke these debugging routines so that the compiler does not + ** issue "defined but not used" warnings. */ + if( x==9999 ){ + sqlite3ShowExpr(0); + sqlite3ShowExprList(0); + sqlite3ShowIdList(0); + sqlite3ShowSrcList(0); + sqlite3ShowWith(0); + sqlite3ShowUpsert(0); +#ifndef SQLITE_OMIT_TRIGGER + sqlite3ShowTriggerStep(0); + sqlite3ShowTriggerStepList(0); + sqlite3ShowTrigger(0); + sqlite3ShowTriggerList(0); +#endif +#ifndef SQLITE_OMIT_WINDOWFUNC + sqlite3ShowWindow(0); + sqlite3ShowWinFunc(0); +#endif + sqlite3ShowSelect(0); + } +#endif + break; + } + + + /* + ** sqlite3_test_control(SQLITE_TESTCTRL_ALWAYS, int X) + ** + ** This action provides a run-time test to see how the ALWAYS and + ** NEVER macros were defined at compile-time. + ** + ** The return value is ALWAYS(X) if X is true, or 0 if X is false. + ** + ** The recommended test is X==2. If the return value is 2, that means + ** ALWAYS() and NEVER() are both no-op pass-through macros, which is the + ** default setting. If the return value is 1, then ALWAYS() is either + ** hard-coded to true or else it asserts if its argument is false. + ** The first behavior (hard-coded to true) is the case if + ** SQLITE_TESTCTRL_ASSERT shows that assert() is disabled and the second + ** behavior (assert if the argument to ALWAYS() is false) is the case if + ** SQLITE_TESTCTRL_ASSERT shows that assert() is enabled. + ** + ** The run-time test procedure might look something like this: + ** + ** if( sqlite3_test_control(SQLITE_TESTCTRL_ALWAYS, 2)==2 ){ + ** // ALWAYS() and NEVER() are no-op pass-through macros + ** }else if( sqlite3_test_control(SQLITE_TESTCTRL_ASSERT, 1) ){ + ** // ALWAYS(x) asserts that x is true. NEVER(x) asserts x is false. + ** }else{ + ** // ALWAYS(x) is a constant 1. NEVER(x) is a constant 0. + ** } + */ + case SQLITE_TESTCTRL_ALWAYS: { + int x = va_arg(ap,int); + rc = x ? ALWAYS(x) : 0; + break; + } + + /* + ** sqlite3_test_control(SQLITE_TESTCTRL_BYTEORDER); + ** + ** The integer returned reveals the byte-order of the computer on which + ** SQLite is running: + ** + ** 1 big-endian, determined at run-time + ** 10 little-endian, determined at run-time + ** 432101 big-endian, determined at compile-time + ** 123410 little-endian, determined at compile-time + */ + case SQLITE_TESTCTRL_BYTEORDER: { + rc = SQLITE_BYTEORDER*100 + SQLITE_LITTLEENDIAN*10 + SQLITE_BIGENDIAN; + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, sqlite3 *db, int N) + ** + ** Enable or disable various optimizations for testing purposes. The + ** argument N is a bitmask of optimizations to be disabled. For normal + ** operation N should be 0. The idea is that a test program (like the + ** SQL Logic Test or SLT test module) can run the same SQL multiple times + ** with various optimizations disabled to verify that the same answer + ** is obtained in every case. + */ + case SQLITE_TESTCTRL_OPTIMIZATIONS: { + sqlite3 *db = va_arg(ap, sqlite3*); + db->dbOptFlags = va_arg(ap, u32); + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_GETOPT, sqlite3 *db, int *N) + ** + ** Write the current optimization settings into *N. A zero bit means that + ** the optimization is on, and a 1 bit means that the optimization is off. + */ + case SQLITE_TESTCTRL_GETOPT: { + sqlite3 *db = va_arg(ap, sqlite3*); + int *pN = va_arg(ap, int*); + *pN = db->dbOptFlags; + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, onoff, xAlt); + ** + ** If parameter onoff is 1, subsequent calls to localtime() fail. + ** If 2, then invoke xAlt() instead of localtime(). If 0, normal + ** processing. + ** + ** xAlt arguments are void pointers, but they really want to be: + ** + ** int xAlt(const time_t*, struct tm*); + ** + ** xAlt should write results in to struct tm object of its 2nd argument + ** and return zero on success, or return non-zero on failure. + */ + case SQLITE_TESTCTRL_LOCALTIME_FAULT: { + sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int); + if( sqlite3GlobalConfig.bLocaltimeFault==2 ){ + typedef int(*sqlite3LocaltimeType)(const void*,void*); + sqlite3GlobalConfig.xAltLocaltime = va_arg(ap, sqlite3LocaltimeType); + }else{ + sqlite3GlobalConfig.xAltLocaltime = 0; + } + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, sqlite3*); + ** + ** Toggle the ability to use internal functions on or off for + ** the database connection given in the argument. + */ + case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: { + sqlite3 *db = va_arg(ap, sqlite3*); + db->mDbFlags ^= DBFLAG_InternalFunc; + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int); + ** + ** Set or clear a flag that indicates that the database file is always well- + ** formed and never corrupt. This flag is clear by default, indicating that + ** database files might have arbitrary corruption. Setting the flag during + ** testing causes certain assert() statements in the code to be activated + ** that demonstrate invariants on well-formed database files. + */ + case SQLITE_TESTCTRL_NEVER_CORRUPT: { + sqlite3GlobalConfig.neverCorrupt = va_arg(ap, int); + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS, int); + ** + ** Set or clear a flag that causes SQLite to verify that type, name, + ** and tbl_name fields of the sqlite_schema table. This is normally + ** on, but it is sometimes useful to turn it off for testing. + ** + ** 2020-07-22: Disabling EXTRA_SCHEMA_CHECKS also disables the + ** verification of rootpage numbers when parsing the schema. This + ** is useful to make it easier to reach strange internal error states + ** during testing. The EXTRA_SCHEMA_CHECKS setting is always enabled + ** in production. + */ + case SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS: { + sqlite3GlobalConfig.bExtraSchemaChecks = va_arg(ap, int); + break; + } + + /* Set the threshold at which OP_Once counters reset back to zero. + ** By default this is 0x7ffffffe (over 2 billion), but that value is + ** too big to test in a reasonable amount of time, so this control is + ** provided to set a small and easily reachable reset value. + */ + case SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD: { + sqlite3GlobalConfig.iOnceResetThreshold = va_arg(ap, int); + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, xCallback, ptr); + ** + ** Set the VDBE coverage callback function to xCallback with context + ** pointer ptr. + */ + case SQLITE_TESTCTRL_VDBE_COVERAGE: { +#ifdef SQLITE_VDBE_COVERAGE + typedef void (*branch_callback)(void*,unsigned int, + unsigned char,unsigned char); + sqlite3GlobalConfig.xVdbeBranch = va_arg(ap,branch_callback); + sqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*); +#endif + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_SORTER_MMAP, db, nMax); */ + case SQLITE_TESTCTRL_SORTER_MMAP: { + sqlite3 *db = va_arg(ap, sqlite3*); + db->nMaxSorterMmap = va_arg(ap, int); + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_ISINIT); + ** + ** Return SQLITE_OK if SQLite has been initialized and SQLITE_ERROR if + ** not. + */ + case SQLITE_TESTCTRL_ISINIT: { + if( sqlite3GlobalConfig.isInit==0 ) rc = SQLITE_ERROR; + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, dbName, mode, tnum); + ** + ** This test control is used to create imposter tables. "db" is a pointer + ** to the database connection. dbName is the database name (ex: "main" or + ** "temp") which will receive the imposter. "mode" turns imposter mode on + ** or off. mode==0 means imposter mode is off. mode==1 means imposter mode + ** is on. mode==2 means imposter mode is on but results in an imposter + ** table that is read-only unless writable_schema is on. "tnum" is the + ** root page of the b-tree to which the imposter table should connect. + ** + ** Enable imposter mode only when the schema has already been parsed. Then + ** run a single CREATE TABLE statement to construct the imposter table in + ** the parsed schema. Then turn imposter mode back off again. + ** + ** If onOff==0 and tnum>0 then reset the schema for all databases, causing + ** the schema to be reparsed the next time it is needed. This has the + ** effect of erasing all imposter tables. + */ + case SQLITE_TESTCTRL_IMPOSTER: { + sqlite3 *db = va_arg(ap, sqlite3*); + int iDb; + sqlite3_mutex_enter(db->mutex); + iDb = sqlite3FindDbName(db, va_arg(ap,const char*)); + if( iDb>=0 ){ + db->init.iDb = iDb; + db->init.busy = db->init.imposterTable = va_arg(ap,int); + db->init.newTnum = va_arg(ap,int); + if( db->init.busy==0 && db->init.newTnum>0 ){ + sqlite3ResetAllSchemasOfConnection(db); + } + } + sqlite3_mutex_leave(db->mutex); + break; + } + +#if defined(YYCOVERAGE) + /* sqlite3_test_control(SQLITE_TESTCTRL_PARSER_COVERAGE, FILE *out) + ** + ** This test control (only available when SQLite is compiled with + ** -DYYCOVERAGE) writes a report onto "out" that shows all + ** state/lookahead combinations in the parser state machine + ** which are never exercised. If any state is missed, make the + ** return code SQLITE_ERROR. + */ + case SQLITE_TESTCTRL_PARSER_COVERAGE: { + FILE *out = va_arg(ap, FILE*); + if( sqlite3ParserCoverage(out) ) rc = SQLITE_ERROR; + break; + } +#endif /* defined(YYCOVERAGE) */ + + /* sqlite3_test_control(SQLITE_TESTCTRL_RESULT_INTREAL, sqlite3_context*); + ** + ** This test-control causes the most recent sqlite3_result_int64() value + ** to be interpreted as a MEM_IntReal instead of as an MEM_Int. Normally, + ** MEM_IntReal values only arise during an INSERT operation of integer + ** values into a REAL column, so they can be challenging to test. This + ** test-control enables us to write an intreal() SQL function that can + ** inject an intreal() value at arbitrary places in an SQL statement, + ** for testing purposes. + */ + case SQLITE_TESTCTRL_RESULT_INTREAL: { + sqlite3_context *pCtx = va_arg(ap, sqlite3_context*); + sqlite3ResultIntReal(pCtx); + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_SEEK_COUNT, + ** sqlite3 *db, // Database connection + ** u64 *pnSeek // Write seek count here + ** ); + ** + ** This test-control queries the seek-counter on the "main" database + ** file. The seek-counter is written into *pnSeek and is then reset. + ** The seek-count is only available if compiled with SQLITE_DEBUG. + */ + case SQLITE_TESTCTRL_SEEK_COUNT: { + sqlite3 *db = va_arg(ap, sqlite3*); + u64 *pn = va_arg(ap, sqlite3_uint64*); + *pn = sqlite3BtreeSeekCount(db->aDb->pBt); + (void)db; /* Silence harmless unused variable warning */ + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, op, ptr) + ** + ** "ptr" is a pointer to a u32. + ** + ** op==0 Store the current sqlite3TreeTrace in *ptr + ** op==1 Set sqlite3TreeTrace to the value *ptr + ** op==2 Store the current sqlite3WhereTrace in *ptr + ** op==3 Set sqlite3WhereTrace to the value *ptr + */ + case SQLITE_TESTCTRL_TRACEFLAGS: { + int opTrace = va_arg(ap, int); + u32 *ptr = va_arg(ap, u32*); + switch( opTrace ){ + case 0: *ptr = sqlite3TreeTrace; break; + case 1: sqlite3TreeTrace = *ptr; break; + case 2: *ptr = sqlite3WhereTrace; break; + case 3: sqlite3WhereTrace = *ptr; break; + } + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_LOGEST, + ** double fIn, // Input value + ** int *pLogEst, // sqlite3LogEstFromDouble(fIn) + ** u64 *pInt, // sqlite3LogEstToInt(*pLogEst) + ** int *pLogEst2 // sqlite3LogEst(*pInt) + ** ); + ** + ** Test access for the LogEst conversion routines. + */ + case SQLITE_TESTCTRL_LOGEST: { + double rIn = va_arg(ap, double); + LogEst rLogEst = sqlite3LogEstFromDouble(rIn); + int *pI1 = va_arg(ap,int*); + u64 *pU64 = va_arg(ap,u64*); + int *pI2 = va_arg(ap,int*); + *pI1 = rLogEst; + *pU64 = sqlite3LogEstToInt(rLogEst); + *pI2 = sqlite3LogEst(*pU64); + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_ATOF, const char *z, double *p); + ** + ** Test access to the sqlite3AtoF() routine. + */ + case SQLITE_TESTCTRL_ATOF: { + const char *z = va_arg(ap,const char*); + double *pR = va_arg(ap,double*); + rc = sqlite3AtoF(z,pR); + break; + } + +#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD) + /* sqlite3_test_control(SQLITE_TESTCTRL_TUNE, id, *piValue) + ** + ** If "id" is an integer between 1 and SQLITE_NTUNE then set the value + ** of the id-th tuning parameter to *piValue. If "id" is between -1 + ** and -SQLITE_NTUNE, then write the current value of the (-id)-th + ** tuning parameter into *piValue. + ** + ** Tuning parameters are for use during transient development builds, + ** to help find the best values for constants in the query planner. + ** Access tuning parameters using the Tuning(ID) macro. Set the + ** parameters in the CLI using ".testctrl tune ID VALUE". + ** + ** Transient use only. Tuning parameters should not be used in + ** checked-in code. + */ + case SQLITE_TESTCTRL_TUNE: { + int id = va_arg(ap, int); + int *piValue = va_arg(ap, int*); + if( id>0 && id<=SQLITE_NTUNE ){ + Tuning(id) = *piValue; + }else if( id<0 && id>=-SQLITE_NTUNE ){ + *piValue = Tuning(-id); + }else{ + rc = SQLITE_NOTFOUND; + } + break; + } +#endif + + /* sqlite3_test_control(SQLITE_TESTCTRL_JSON_SELFCHECK, &onOff); + ** + ** Activate or deactivate validation of JSONB that is generated from + ** text. Off by default, as the validation is slow. Validation is + ** only available if compiled using SQLITE_DEBUG. + ** + ** If onOff is initially 1, then turn it on. If onOff is initially + ** off, turn it off. If onOff is initially -1, then change onOff + ** to be the current setting. + */ + case SQLITE_TESTCTRL_JSON_SELFCHECK: { +#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD) + int *pOnOff = va_arg(ap, int*); + if( *pOnOff<0 ){ + *pOnOff = sqlite3Config.bJsonSelfcheck; + }else{ + sqlite3Config.bJsonSelfcheck = (u8)((*pOnOff)&0xff); + } +#endif + break; + } + } + va_end(ap); +#endif /* SQLITE_UNTESTABLE */ + return rc; +} + +/* +** The Pager stores the Database filename, Journal filename, and WAL filename +** consecutively in memory, in that order. The database filename is prefixed +** by four zero bytes. Locate the start of the database filename by searching +** backwards for the first byte following four consecutive zero bytes. +** +** This only works if the filename passed in was obtained from the Pager. +*/ +static const char *databaseName(const char *zName){ + while( zName[-1]!=0 || zName[-2]!=0 || zName[-3]!=0 || zName[-4]!=0 ){ + zName--; + } + return zName; +} + +/* +** Append text z[] to the end of p[]. Return a pointer to the first +** character after then zero terminator on the new text in p[]. +*/ +static char *appendText(char *p, const char *z){ + size_t n = strlen(z); + memcpy(p, z, n+1); + return p+n+1; +} + +/* +** Allocate memory to hold names for a database, journal file, WAL file, +** and query parameters. The pointer returned is valid for use by +** sqlite3_filename_database() and sqlite3_uri_parameter() and related +** functions. +** +** Memory layout must be compatible with that generated by the pager +** and expected by sqlite3_uri_parameter() and databaseName(). +*/ +SQLITE_API const char *sqlite3_create_filename( + const char *zDatabase, + const char *zJournal, + const char *zWal, + int nParam, + const char **azParam +){ + sqlite3_int64 nByte; + int i; + char *pResult, *p; + nByte = strlen(zDatabase) + strlen(zJournal) + strlen(zWal) + 10; + for(i=0; i0 ){ + zFilename += sqlite3Strlen30(zFilename) + 1; + zFilename += sqlite3Strlen30(zFilename) + 1; + } + return zFilename[0] ? zFilename : 0; +} + +/* +** Return a boolean value for a query parameter. +*/ +SQLITE_API int sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){ + const char *z = sqlite3_uri_parameter(zFilename, zParam); + bDflt = bDflt!=0; + return z ? sqlite3GetBoolean(z, bDflt) : bDflt; +} + +/* +** Return a 64-bit integer value for a query parameter. +*/ +SQLITE_API sqlite3_int64 sqlite3_uri_int64( + const char *zFilename, /* Filename as passed to xOpen */ + const char *zParam, /* URI parameter sought */ + sqlite3_int64 bDflt /* return if parameter is missing */ +){ + const char *z = sqlite3_uri_parameter(zFilename, zParam); + sqlite3_int64 v; + if( z && sqlite3DecOrHexToI64(z, &v)==0 ){ + bDflt = v; + } + return bDflt; +} + +/* +** Translate a filename that was handed to a VFS routine into the corresponding +** database, journal, or WAL file. +** +** It is an error to pass this routine a filename string that was not +** passed into the VFS from the SQLite core. Doing so is similar to +** passing free() a pointer that was not obtained from malloc() - it is +** an error that we cannot easily detect but that will likely cause memory +** corruption. +*/ +SQLITE_API const char *sqlite3_filename_database(const char *zFilename){ + if( zFilename==0 ) return 0; + return databaseName(zFilename); +} +SQLITE_API const char *sqlite3_filename_journal(const char *zFilename){ + if( zFilename==0 ) return 0; + zFilename = databaseName(zFilename); + zFilename += sqlite3Strlen30(zFilename) + 1; + while( ALWAYS(zFilename) && zFilename[0] ){ + zFilename += sqlite3Strlen30(zFilename) + 1; + zFilename += sqlite3Strlen30(zFilename) + 1; + } + return zFilename + 1; +} +SQLITE_API const char *sqlite3_filename_wal(const char *zFilename){ +#ifdef SQLITE_OMIT_WAL + UNUSED_PARAMETER(zFilename); + return 0; +#else + zFilename = sqlite3_filename_journal(zFilename); + if( zFilename ) zFilename += sqlite3Strlen30(zFilename) + 1; + return zFilename; +#endif +} + +/* +** Return the Btree pointer identified by zDbName. Return NULL if not found. +*/ +SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){ + int iDb = zDbName ? sqlite3FindDbName(db, zDbName) : 0; + return iDb<0 ? 0 : db->aDb[iDb].pBt; +} + +/* +** Return the name of the N-th database schema. Return NULL if N is out +** of range. +*/ +SQLITE_API const char *sqlite3_db_name(sqlite3 *db, int N){ + const char *zRet = 0; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + if( N>=0 && NnDb ){ + zRet = db->aDb[N].zDbSName; + } + sqlite3_mutex_leave(db->mutex); + return zRet; +} + +/* +** Return the filename of the database associated with a database +** connection. +*/ +SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){ + Btree *pBt; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + pBt = sqlite3DbNameToBtree(db, zDbName); + return pBt ? sqlite3BtreeGetFilename(pBt) : 0; +} + +/* +** Return 1 if database is read-only or 0 if read/write. Return -1 if +** no such database exists. +*/ +SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){ + Btree *pBt; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return -1; + } +#endif + pBt = sqlite3DbNameToBtree(db, zDbName); + return pBt ? sqlite3BtreeIsReadonly(pBt) : -1; +} + +#ifdef SQLITE_ENABLE_SNAPSHOT +/* +** Obtain a snapshot handle for the snapshot of database zDb currently +** being read by handle db. +*/ +SQLITE_API int sqlite3_snapshot_get( + sqlite3 *db, + const char *zDb, + sqlite3_snapshot **ppSnapshot +){ + int rc = SQLITE_ERROR; +#ifndef SQLITE_OMIT_WAL + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + return SQLITE_MISUSE_BKPT; + } +#endif + sqlite3_mutex_enter(db->mutex); + + if( db->autoCommit==0 ){ + int iDb = sqlite3FindDbName(db, zDb); + if( iDb==0 || iDb>1 ){ + Btree *pBt = db->aDb[iDb].pBt; + if( SQLITE_TXN_WRITE!=sqlite3BtreeTxnState(pBt) ){ + Pager *pPager = sqlite3BtreePager(pBt); + i64 dummy = 0; + sqlite3PagerSnapshotOpen(pPager, (sqlite3_snapshot*)&dummy); + rc = sqlite3BtreeBeginTrans(pBt, 0, 0); + sqlite3PagerSnapshotOpen(pPager, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot); + } + } + } + } + + sqlite3_mutex_leave(db->mutex); +#endif /* SQLITE_OMIT_WAL */ + return rc; +} + +/* +** Open a read-transaction on the snapshot identified by pSnapshot. +*/ +SQLITE_API int sqlite3_snapshot_open( + sqlite3 *db, + const char *zDb, + sqlite3_snapshot *pSnapshot +){ + int rc = SQLITE_ERROR; +#ifndef SQLITE_OMIT_WAL + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + return SQLITE_MISUSE_BKPT; + } +#endif + sqlite3_mutex_enter(db->mutex); + if( db->autoCommit==0 ){ + int iDb; + iDb = sqlite3FindDbName(db, zDb); + if( iDb==0 || iDb>1 ){ + Btree *pBt = db->aDb[iDb].pBt; + if( sqlite3BtreeTxnState(pBt)!=SQLITE_TXN_WRITE ){ + Pager *pPager = sqlite3BtreePager(pBt); + int bUnlock = 0; + if( sqlite3BtreeTxnState(pBt)!=SQLITE_TXN_NONE ){ + if( db->nVdbeActive==0 ){ + rc = sqlite3PagerSnapshotCheck(pPager, pSnapshot); + if( rc==SQLITE_OK ){ + bUnlock = 1; + rc = sqlite3BtreeCommit(pBt); + } + } + }else{ + rc = SQLITE_OK; + } + if( rc==SQLITE_OK ){ + rc = sqlite3PagerSnapshotOpen(pPager, pSnapshot); + } + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeBeginTrans(pBt, 0, 0); + sqlite3PagerSnapshotOpen(pPager, 0); + } + if( bUnlock ){ + sqlite3PagerSnapshotUnlock(pPager); + } + } + } + } + + sqlite3_mutex_leave(db->mutex); +#endif /* SQLITE_OMIT_WAL */ + return rc; +} + +/* +** Recover as many snapshots as possible from the wal file associated with +** schema zDb of database db. +*/ +SQLITE_API int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb){ + int rc = SQLITE_ERROR; +#ifndef SQLITE_OMIT_WAL + int iDb; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + return SQLITE_MISUSE_BKPT; + } +#endif + + sqlite3_mutex_enter(db->mutex); + iDb = sqlite3FindDbName(db, zDb); + if( iDb==0 || iDb>1 ){ + Btree *pBt = db->aDb[iDb].pBt; + if( SQLITE_TXN_NONE==sqlite3BtreeTxnState(pBt) ){ + rc = sqlite3BtreeBeginTrans(pBt, 0, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3PagerSnapshotRecover(sqlite3BtreePager(pBt)); + sqlite3BtreeCommit(pBt); + } + } + } + sqlite3_mutex_leave(db->mutex); +#endif /* SQLITE_OMIT_WAL */ + return rc; +} + +/* +** Free a snapshot handle obtained from sqlite3_snapshot_get(). +*/ +SQLITE_API void sqlite3_snapshot_free(sqlite3_snapshot *pSnapshot){ + sqlite3_free(pSnapshot); +} +#endif /* SQLITE_ENABLE_SNAPSHOT */ + +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS +/* +** Given the name of a compile-time option, return true if that option +** was used and false if not. +** +** The name can optionally begin with "SQLITE_" but the "SQLITE_" prefix +** is not required for a match. +*/ +SQLITE_API int sqlite3_compileoption_used(const char *zOptName){ + int i, n; + int nOpt; + const char **azCompileOpt; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( zOptName==0 ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + + azCompileOpt = sqlite3CompileOptions(&nOpt); + + if( sqlite3StrNICmp(zOptName, "SQLITE_", 7)==0 ) zOptName += 7; + n = sqlite3Strlen30(zOptName); + + /* Since nOpt is normally in single digits, a linear search is + ** adequate. No need for a binary search. */ + for(i=0; i=0 && NpNextBlocked){ + int seen = 0; + sqlite3 *p2; + + /* Verify property (1) */ + assert( p->pUnlockConnection || p->pBlockingConnection ); + + /* Verify property (2) */ + for(p2=sqlite3BlockedList; p2!=p; p2=p2->pNextBlocked){ + if( p2->xUnlockNotify==p->xUnlockNotify ) seen = 1; + assert( p2->xUnlockNotify==p->xUnlockNotify || !seen ); + assert( db==0 || p->pUnlockConnection!=db ); + assert( db==0 || p->pBlockingConnection!=db ); + } + } +} +#else +# define checkListProperties(x) +#endif + +/* +** Remove connection db from the blocked connections list. If connection +** db is not currently a part of the list, this function is a no-op. +*/ +static void removeFromBlockedList(sqlite3 *db){ + sqlite3 **pp; + assertMutexHeld(); + for(pp=&sqlite3BlockedList; *pp; pp = &(*pp)->pNextBlocked){ + if( *pp==db ){ + *pp = (*pp)->pNextBlocked; + break; + } + } +} + +/* +** Add connection db to the blocked connections list. It is assumed +** that it is not already a part of the list. +*/ +static void addToBlockedList(sqlite3 *db){ + sqlite3 **pp; + assertMutexHeld(); + for( + pp=&sqlite3BlockedList; + *pp && (*pp)->xUnlockNotify!=db->xUnlockNotify; + pp=&(*pp)->pNextBlocked + ); + db->pNextBlocked = *pp; + *pp = db; +} + +/* +** Obtain the STATIC_MAIN mutex. +*/ +static void enterMutex(void){ + sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN)); + checkListProperties(0); +} + +/* +** Release the STATIC_MAIN mutex. +*/ +static void leaveMutex(void){ + assertMutexHeld(); + checkListProperties(0); + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN)); +} + +/* +** Register an unlock-notify callback. +** +** This is called after connection "db" has attempted some operation +** but has received an SQLITE_LOCKED error because another connection +** (call it pOther) in the same process was busy using the same shared +** cache. pOther is found by looking at db->pBlockingConnection. +** +** If there is no blocking connection, the callback is invoked immediately, +** before this routine returns. +** +** If pOther is already blocked on db, then report SQLITE_LOCKED, to indicate +** a deadlock. +** +** Otherwise, make arrangements to invoke xNotify when pOther drops +** its locks. +** +** Each call to this routine overrides any prior callbacks registered +** on the same "db". If xNotify==0 then any prior callbacks are immediately +** cancelled. +*/ +SQLITE_API int sqlite3_unlock_notify( + sqlite3 *db, + void (*xNotify)(void **, int), + void *pArg +){ + int rc = SQLITE_OK; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + enterMutex(); + + if( xNotify==0 ){ + removeFromBlockedList(db); + db->pBlockingConnection = 0; + db->pUnlockConnection = 0; + db->xUnlockNotify = 0; + db->pUnlockArg = 0; + }else if( 0==db->pBlockingConnection ){ + /* The blocking transaction has been concluded. Or there never was a + ** blocking transaction. In either case, invoke the notify callback + ** immediately. + */ + xNotify(&pArg, 1); + }else{ + sqlite3 *p; + + for(p=db->pBlockingConnection; p && p!=db; p=p->pUnlockConnection){} + if( p ){ + rc = SQLITE_LOCKED; /* Deadlock detected. */ + }else{ + db->pUnlockConnection = db->pBlockingConnection; + db->xUnlockNotify = xNotify; + db->pUnlockArg = pArg; + removeFromBlockedList(db); + addToBlockedList(db); + } + } + + leaveMutex(); + assert( !db->mallocFailed ); + sqlite3ErrorWithMsg(db, rc, (rc?"database is deadlocked":0)); + sqlite3_mutex_leave(db->mutex); + return rc; +} + +/* +** This function is called while stepping or preparing a statement +** associated with connection db. The operation will return SQLITE_LOCKED +** to the user because it requires a lock that will not be available +** until connection pBlocker concludes its current transaction. +*/ +SQLITE_PRIVATE void sqlite3ConnectionBlocked(sqlite3 *db, sqlite3 *pBlocker){ + enterMutex(); + if( db->pBlockingConnection==0 && db->pUnlockConnection==0 ){ + addToBlockedList(db); + } + db->pBlockingConnection = pBlocker; + leaveMutex(); +} + +/* +** This function is called when +** the transaction opened by database db has just finished. Locks held +** by database connection db have been released. +** +** This function loops through each entry in the blocked connections +** list and does the following: +** +** 1) If the sqlite3.pBlockingConnection member of a list entry is +** set to db, then set pBlockingConnection=0. +** +** 2) If the sqlite3.pUnlockConnection member of a list entry is +** set to db, then invoke the configured unlock-notify callback and +** set pUnlockConnection=0. +** +** 3) If the two steps above mean that pBlockingConnection==0 and +** pUnlockConnection==0, remove the entry from the blocked connections +** list. +*/ +SQLITE_PRIVATE void sqlite3ConnectionUnlocked(sqlite3 *db){ + void (*xUnlockNotify)(void **, int) = 0; /* Unlock-notify cb to invoke */ + int nArg = 0; /* Number of entries in aArg[] */ + sqlite3 **pp; /* Iterator variable */ + void **aArg; /* Arguments to the unlock callback */ + void **aDyn = 0; /* Dynamically allocated space for aArg[] */ + void *aStatic[16]; /* Starter space for aArg[]. No malloc required */ + + aArg = aStatic; + enterMutex(); /* Enter STATIC_MAIN mutex */ + + /* This loop runs once for each entry in the blocked-connections list. */ + for(pp=&sqlite3BlockedList; *pp; /* no-op */ ){ + sqlite3 *p = *pp; + + /* Step 1. */ + if( p->pBlockingConnection==db ){ + p->pBlockingConnection = 0; + } + + /* Step 2. */ + if( p->pUnlockConnection==db ){ + assert( p->xUnlockNotify ); + if( p->xUnlockNotify!=xUnlockNotify && nArg!=0 ){ + xUnlockNotify(aArg, nArg); + nArg = 0; + } + + sqlite3BeginBenignMalloc(); + assert( aArg==aDyn || (aDyn==0 && aArg==aStatic) ); + assert( nArg<=(int)ArraySize(aStatic) || aArg==aDyn ); + if( (!aDyn && nArg==(int)ArraySize(aStatic)) + || (aDyn && nArg==(int)(sqlite3MallocSize(aDyn)/sizeof(void*))) + ){ + /* The aArg[] array needs to grow. */ + void **pNew = (void **)sqlite3Malloc(nArg*sizeof(void *)*2); + if( pNew ){ + memcpy(pNew, aArg, nArg*sizeof(void *)); + sqlite3_free(aDyn); + aDyn = aArg = pNew; + }else{ + /* This occurs when the array of context pointers that need to + ** be passed to the unlock-notify callback is larger than the + ** aStatic[] array allocated on the stack and the attempt to + ** allocate a larger array from the heap has failed. + ** + ** This is a difficult situation to handle. Returning an error + ** code to the caller is insufficient, as even if an error code + ** is returned the transaction on connection db will still be + ** closed and the unlock-notify callbacks on blocked connections + ** will go unissued. This might cause the application to wait + ** indefinitely for an unlock-notify callback that will never + ** arrive. + ** + ** Instead, invoke the unlock-notify callback with the context + ** array already accumulated. We can then clear the array and + ** begin accumulating any further context pointers without + ** requiring any dynamic allocation. This is sub-optimal because + ** it means that instead of one callback with a large array of + ** context pointers the application will receive two or more + ** callbacks with smaller arrays of context pointers, which will + ** reduce the applications ability to prioritize multiple + ** connections. But it is the best that can be done under the + ** circumstances. + */ + xUnlockNotify(aArg, nArg); + nArg = 0; + } + } + sqlite3EndBenignMalloc(); + + aArg[nArg++] = p->pUnlockArg; + xUnlockNotify = p->xUnlockNotify; + p->pUnlockConnection = 0; + p->xUnlockNotify = 0; + p->pUnlockArg = 0; + } + + /* Step 3. */ + if( p->pBlockingConnection==0 && p->pUnlockConnection==0 ){ + /* Remove connection p from the blocked connections list. */ + *pp = p->pNextBlocked; + p->pNextBlocked = 0; + }else{ + pp = &p->pNextBlocked; + } + } + + if( nArg!=0 ){ + xUnlockNotify(aArg, nArg); + } + sqlite3_free(aDyn); + leaveMutex(); /* Leave STATIC_MAIN mutex */ +} + +/* +** This is called when the database connection passed as an argument is +** being closed. The connection is removed from the blocked list. +*/ +SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db){ + sqlite3ConnectionUnlocked(db); + enterMutex(); + removeFromBlockedList(db); + checkListProperties(db); + leaveMutex(); +} +#endif + +/************** End of notify.c **********************************************/ +/************** Begin file fts3.c ********************************************/ +/* +** 2006 Oct 10 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This is an SQLite module implementing full-text search. +*/ + +/* +** The code in this file is only compiled if: +** +** * The FTS3 module is being built as an extension +** (in which case SQLITE_CORE is not defined), or +** +** * The FTS3 module is being built into the core of +** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). +*/ + +/* The full-text index is stored in a series of b+tree (-like) +** structures called segments which map terms to doclists. The +** structures are like b+trees in layout, but are constructed from the +** bottom up in optimal fashion and are not updatable. Since trees +** are built from the bottom up, things will be described from the +** bottom up. +** +** +**** Varints **** +** The basic unit of encoding is a variable-length integer called a +** varint. We encode variable-length integers in little-endian order +** using seven bits * per byte as follows: +** +** KEY: +** A = 0xxxxxxx 7 bits of data and one flag bit +** B = 1xxxxxxx 7 bits of data and one flag bit +** +** 7 bits - A +** 14 bits - BA +** 21 bits - BBA +** and so on. +** +** This is similar in concept to how sqlite encodes "varints" but +** the encoding is not the same. SQLite varints are big-endian +** are are limited to 9 bytes in length whereas FTS3 varints are +** little-endian and can be up to 10 bytes in length (in theory). +** +** Example encodings: +** +** 1: 0x01 +** 127: 0x7f +** 128: 0x81 0x00 +** +** +**** Document lists **** +** A doclist (document list) holds a docid-sorted list of hits for a +** given term. Doclists hold docids and associated token positions. +** A docid is the unique integer identifier for a single document. +** A position is the index of a word within the document. The first +** word of the document has a position of 0. +** +** FTS3 used to optionally store character offsets using a compile-time +** option. But that functionality is no longer supported. +** +** A doclist is stored like this: +** +** array { +** varint docid; (delta from previous doclist) +** array { (position list for column 0) +** varint position; (2 more than the delta from previous position) +** } +** array { +** varint POS_COLUMN; (marks start of position list for new column) +** varint column; (index of new column) +** array { +** varint position; (2 more than the delta from previous position) +** } +** } +** varint POS_END; (marks end of positions for this document. +** } +** +** Here, array { X } means zero or more occurrences of X, adjacent in +** memory. A "position" is an index of a token in the token stream +** generated by the tokenizer. Note that POS_END and POS_COLUMN occur +** in the same logical place as the position element, and act as sentinels +** ending a position list array. POS_END is 0. POS_COLUMN is 1. +** The positions numbers are not stored literally but rather as two more +** than the difference from the prior position, or the just the position plus +** 2 for the first position. Example: +** +** label: A B C D E F G H I J K +** value: 123 5 9 1 1 14 35 0 234 72 0 +** +** The 123 value is the first docid. For column zero in this document +** there are two matches at positions 3 and 10 (5-2 and 9-2+3). The 1 +** at D signals the start of a new column; the 1 at E indicates that the +** new column is column number 1. There are two positions at 12 and 45 +** (14-2 and 35-2+12). The 0 at H indicate the end-of-document. The +** 234 at I is the delta to next docid (357). It has one position 70 +** (72-2) and then terminates with the 0 at K. +** +** A "position-list" is the list of positions for multiple columns for +** a single docid. A "column-list" is the set of positions for a single +** column. Hence, a position-list consists of one or more column-lists, +** a document record consists of a docid followed by a position-list and +** a doclist consists of one or more document records. +** +** A bare doclist omits the position information, becoming an +** array of varint-encoded docids. +** +**** Segment leaf nodes **** +** Segment leaf nodes store terms and doclists, ordered by term. Leaf +** nodes are written using LeafWriter, and read using LeafReader (to +** iterate through a single leaf node's data) and LeavesReader (to +** iterate through a segment's entire leaf layer). Leaf nodes have +** the format: +** +** varint iHeight; (height from leaf level, always 0) +** varint nTerm; (length of first term) +** char pTerm[nTerm]; (content of first term) +** varint nDoclist; (length of term's associated doclist) +** char pDoclist[nDoclist]; (content of doclist) +** array { +** (further terms are delta-encoded) +** varint nPrefix; (length of prefix shared with previous term) +** varint nSuffix; (length of unshared suffix) +** char pTermSuffix[nSuffix];(unshared suffix of next term) +** varint nDoclist; (length of term's associated doclist) +** char pDoclist[nDoclist]; (content of doclist) +** } +** +** Here, array { X } means zero or more occurrences of X, adjacent in +** memory. +** +** Leaf nodes are broken into blocks which are stored contiguously in +** the %_segments table in sorted order. This means that when the end +** of a node is reached, the next term is in the node with the next +** greater node id. +** +** New data is spilled to a new leaf node when the current node +** exceeds LEAF_MAX bytes (default 2048). New data which itself is +** larger than STANDALONE_MIN (default 1024) is placed in a standalone +** node (a leaf node with a single term and doclist). The goal of +** these settings is to pack together groups of small doclists while +** making it efficient to directly access large doclists. The +** assumption is that large doclists represent terms which are more +** likely to be query targets. +** +** TODO(shess) It may be useful for blocking decisions to be more +** dynamic. For instance, it may make more sense to have a 2.5k leaf +** node rather than splitting into 2k and .5k nodes. My intuition is +** that this might extend through 2x or 4x the pagesize. +** +** +**** Segment interior nodes **** +** Segment interior nodes store blockids for subtree nodes and terms +** to describe what data is stored by the each subtree. Interior +** nodes are written using InteriorWriter, and read using +** InteriorReader. InteriorWriters are created as needed when +** SegmentWriter creates new leaf nodes, or when an interior node +** itself grows too big and must be split. The format of interior +** nodes: +** +** varint iHeight; (height from leaf level, always >0) +** varint iBlockid; (block id of node's leftmost subtree) +** optional { +** varint nTerm; (length of first term) +** char pTerm[nTerm]; (content of first term) +** array { +** (further terms are delta-encoded) +** varint nPrefix; (length of shared prefix with previous term) +** varint nSuffix; (length of unshared suffix) +** char pTermSuffix[nSuffix]; (unshared suffix of next term) +** } +** } +** +** Here, optional { X } means an optional element, while array { X } +** means zero or more occurrences of X, adjacent in memory. +** +** An interior node encodes n terms separating n+1 subtrees. The +** subtree blocks are contiguous, so only the first subtree's blockid +** is encoded. The subtree at iBlockid will contain all terms less +** than the first term encoded (or all terms if no term is encoded). +** Otherwise, for terms greater than or equal to pTerm[i] but less +** than pTerm[i+1], the subtree for that term will be rooted at +** iBlockid+i. Interior nodes only store enough term data to +** distinguish adjacent children (if the rightmost term of the left +** child is "something", and the leftmost term of the right child is +** "wicked", only "w" is stored). +** +** New data is spilled to a new interior node at the same height when +** the current node exceeds INTERIOR_MAX bytes (default 2048). +** INTERIOR_MIN_TERMS (default 7) keeps large terms from monopolizing +** interior nodes and making the tree too skinny. The interior nodes +** at a given height are naturally tracked by interior nodes at +** height+1, and so on. +** +** +**** Segment directory **** +** The segment directory in table %_segdir stores meta-information for +** merging and deleting segments, and also the root node of the +** segment's tree. +** +** The root node is the top node of the segment's tree after encoding +** the entire segment, restricted to ROOT_MAX bytes (default 1024). +** This could be either a leaf node or an interior node. If the top +** node requires more than ROOT_MAX bytes, it is flushed to %_segments +** and a new root interior node is generated (which should always fit +** within ROOT_MAX because it only needs space for 2 varints, the +** height and the blockid of the previous root). +** +** The meta-information in the segment directory is: +** level - segment level (see below) +** idx - index within level +** - (level,idx uniquely identify a segment) +** start_block - first leaf node +** leaves_end_block - last leaf node +** end_block - last block (including interior nodes) +** root - contents of root node +** +** If the root node is a leaf node, then start_block, +** leaves_end_block, and end_block are all 0. +** +** +**** Segment merging **** +** To amortize update costs, segments are grouped into levels and +** merged in batches. Each increase in level represents exponentially +** more documents. +** +** New documents (actually, document updates) are tokenized and +** written individually (using LeafWriter) to a level 0 segment, with +** incrementing idx. When idx reaches MERGE_COUNT (default 16), all +** level 0 segments are merged into a single level 1 segment. Level 1 +** is populated like level 0, and eventually MERGE_COUNT level 1 +** segments are merged to a single level 2 segment (representing +** MERGE_COUNT^2 updates), and so on. +** +** A segment merge traverses all segments at a given level in +** parallel, performing a straightforward sorted merge. Since segment +** leaf nodes are written in to the %_segments table in order, this +** merge traverses the underlying sqlite disk structures efficiently. +** After the merge, all segment blocks from the merged level are +** deleted. +** +** MERGE_COUNT controls how often we merge segments. 16 seems to be +** somewhat of a sweet spot for insertion performance. 32 and 64 show +** very similar performance numbers to 16 on insertion, though they're +** a tiny bit slower (perhaps due to more overhead in merge-time +** sorting). 8 is about 20% slower than 16, 4 about 50% slower than +** 16, 2 about 66% slower than 16. +** +** At query time, high MERGE_COUNT increases the number of segments +** which need to be scanned and merged. For instance, with 100k docs +** inserted: +** +** MERGE_COUNT segments +** 16 25 +** 8 12 +** 4 10 +** 2 6 +** +** This appears to have only a moderate impact on queries for very +** frequent terms (which are somewhat dominated by segment merge +** costs), and infrequent and non-existent terms still seem to be fast +** even with many segments. +** +** TODO(shess) That said, it would be nice to have a better query-side +** argument for MERGE_COUNT of 16. Also, it is possible/likely that +** optimizations to things like doclist merging will swing the sweet +** spot around. +** +** +** +**** Handling of deletions and updates **** +** Since we're using a segmented structure, with no docid-oriented +** index into the term index, we clearly cannot simply update the term +** index when a document is deleted or updated. For deletions, we +** write an empty doclist (varint(docid) varint(POS_END)), for updates +** we simply write the new doclist. Segment merges overwrite older +** data for a particular docid with newer data, so deletes or updates +** will eventually overtake the earlier data and knock it out. The +** query logic likewise merges doclists so that newer data knocks out +** older data. +*/ + +/************** Include fts3Int.h in the middle of fts3.c ********************/ +/************** Begin file fts3Int.h *****************************************/ +/* +** 2009 Nov 12 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +*/ +#ifndef _FTSINT_H +#define _FTSINT_H + +/* +** Activate assert() only if SQLITE_TEST is enabled. +*/ +#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) +# define NDEBUG 1 +#endif + +/* #include */ +/* #include */ +/* #include */ +/* #include */ +/* #include */ +/* #include */ + +/* FTS3/FTS4 require virtual tables */ +#ifdef SQLITE_OMIT_VIRTUALTABLE +# undef SQLITE_ENABLE_FTS3 +# undef SQLITE_ENABLE_FTS4 +#endif + +/* +** FTS4 is really an extension for FTS3. It is enabled using the +** SQLITE_ENABLE_FTS3 macro. But to avoid confusion we also all +** the SQLITE_ENABLE_FTS4 macro to serve as an alisse for SQLITE_ENABLE_FTS3. +*/ +#if defined(SQLITE_ENABLE_FTS4) && !defined(SQLITE_ENABLE_FTS3) +# define SQLITE_ENABLE_FTS3 +#endif + +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* If not building as part of the core, include sqlite3ext.h. */ +#ifndef SQLITE_CORE +/* # include "sqlite3ext.h" */ +SQLITE_EXTENSION_INIT3 +#endif + +/* #include "sqlite3.h" */ +/************** Include fts3_tokenizer.h in the middle of fts3Int.h **********/ +/************** Begin file fts3_tokenizer.h **********************************/ +/* +** 2006 July 10 +** +** The author disclaims copyright to this source code. +** +************************************************************************* +** Defines the interface to tokenizers used by fulltext-search. There +** are three basic components: +** +** sqlite3_tokenizer_module is a singleton defining the tokenizer +** interface functions. This is essentially the class structure for +** tokenizers. +** +** sqlite3_tokenizer is used to define a particular tokenizer, perhaps +** including customization information defined at creation time. +** +** sqlite3_tokenizer_cursor is generated by a tokenizer to generate +** tokens from a particular input. +*/ +#ifndef _FTS3_TOKENIZER_H_ +#define _FTS3_TOKENIZER_H_ + +/* TODO(shess) Only used for SQLITE_OK and SQLITE_DONE at this time. +** If tokenizers are to be allowed to call sqlite3_*() functions, then +** we will need a way to register the API consistently. +*/ +/* #include "sqlite3.h" */ + +/* +** Structures used by the tokenizer interface. When a new tokenizer +** implementation is registered, the caller provides a pointer to +** an sqlite3_tokenizer_module containing pointers to the callback +** functions that make up an implementation. +** +** When an fts3 table is created, it passes any arguments passed to +** the tokenizer clause of the CREATE VIRTUAL TABLE statement to the +** sqlite3_tokenizer_module.xCreate() function of the requested tokenizer +** implementation. The xCreate() function in turn returns an +** sqlite3_tokenizer structure representing the specific tokenizer to +** be used for the fts3 table (customized by the tokenizer clause arguments). +** +** To tokenize an input buffer, the sqlite3_tokenizer_module.xOpen() +** method is called. It returns an sqlite3_tokenizer_cursor object +** that may be used to tokenize a specific input buffer based on +** the tokenization rules supplied by a specific sqlite3_tokenizer +** object. +*/ +typedef struct sqlite3_tokenizer_module sqlite3_tokenizer_module; +typedef struct sqlite3_tokenizer sqlite3_tokenizer; +typedef struct sqlite3_tokenizer_cursor sqlite3_tokenizer_cursor; + +struct sqlite3_tokenizer_module { + + /* + ** Structure version. Should always be set to 0 or 1. + */ + int iVersion; + + /* + ** Create a new tokenizer. The values in the argv[] array are the + ** arguments passed to the "tokenizer" clause of the CREATE VIRTUAL + ** TABLE statement that created the fts3 table. For example, if + ** the following SQL is executed: + ** + ** CREATE .. USING fts3( ... , tokenizer arg1 arg2) + ** + ** then argc is set to 2, and the argv[] array contains pointers + ** to the strings "arg1" and "arg2". + ** + ** This method should return either SQLITE_OK (0), or an SQLite error + ** code. If SQLITE_OK is returned, then *ppTokenizer should be set + ** to point at the newly created tokenizer structure. The generic + ** sqlite3_tokenizer.pModule variable should not be initialized by + ** this callback. The caller will do so. + */ + int (*xCreate)( + int argc, /* Size of argv array */ + const char *const*argv, /* Tokenizer argument strings */ + sqlite3_tokenizer **ppTokenizer /* OUT: Created tokenizer */ + ); + + /* + ** Destroy an existing tokenizer. The fts3 module calls this method + ** exactly once for each successful call to xCreate(). + */ + int (*xDestroy)(sqlite3_tokenizer *pTokenizer); + + /* + ** Create a tokenizer cursor to tokenize an input buffer. The caller + ** is responsible for ensuring that the input buffer remains valid + ** until the cursor is closed (using the xClose() method). + */ + int (*xOpen)( + sqlite3_tokenizer *pTokenizer, /* Tokenizer object */ + const char *pInput, int nBytes, /* Input buffer */ + sqlite3_tokenizer_cursor **ppCursor /* OUT: Created tokenizer cursor */ + ); + + /* + ** Destroy an existing tokenizer cursor. The fts3 module calls this + ** method exactly once for each successful call to xOpen(). + */ + int (*xClose)(sqlite3_tokenizer_cursor *pCursor); + + /* + ** Retrieve the next token from the tokenizer cursor pCursor. This + ** method should either return SQLITE_OK and set the values of the + ** "OUT" variables identified below, or SQLITE_DONE to indicate that + ** the end of the buffer has been reached, or an SQLite error code. + ** + ** *ppToken should be set to point at a buffer containing the + ** normalized version of the token (i.e. after any case-folding and/or + ** stemming has been performed). *pnBytes should be set to the length + ** of this buffer in bytes. The input text that generated the token is + ** identified by the byte offsets returned in *piStartOffset and + ** *piEndOffset. *piStartOffset should be set to the index of the first + ** byte of the token in the input buffer. *piEndOffset should be set + ** to the index of the first byte just past the end of the token in + ** the input buffer. + ** + ** The buffer *ppToken is set to point at is managed by the tokenizer + ** implementation. It is only required to be valid until the next call + ** to xNext() or xClose(). + */ + /* TODO(shess) current implementation requires pInput to be + ** nul-terminated. This should either be fixed, or pInput/nBytes + ** should be converted to zInput. + */ + int (*xNext)( + sqlite3_tokenizer_cursor *pCursor, /* Tokenizer cursor */ + const char **ppToken, int *pnBytes, /* OUT: Normalized text for token */ + int *piStartOffset, /* OUT: Byte offset of token in input buffer */ + int *piEndOffset, /* OUT: Byte offset of end of token in input buffer */ + int *piPosition /* OUT: Number of tokens returned before this one */ + ); + + /*********************************************************************** + ** Methods below this point are only available if iVersion>=1. + */ + + /* + ** Configure the language id of a tokenizer cursor. + */ + int (*xLanguageid)(sqlite3_tokenizer_cursor *pCsr, int iLangid); +}; + +struct sqlite3_tokenizer { + const sqlite3_tokenizer_module *pModule; /* The module for this tokenizer */ + /* Tokenizer implementations will typically add additional fields */ +}; + +struct sqlite3_tokenizer_cursor { + sqlite3_tokenizer *pTokenizer; /* Tokenizer for this cursor. */ + /* Tokenizer implementations will typically add additional fields */ +}; + +int fts3_global_term_cnt(int iTerm, int iCol); +int fts3_term_cnt(int iTerm, int iCol); + + +#endif /* _FTS3_TOKENIZER_H_ */ + +/************** End of fts3_tokenizer.h **************************************/ +/************** Continuing where we left off in fts3Int.h ********************/ +/************** Include fts3_hash.h in the middle of fts3Int.h ***************/ +/************** Begin file fts3_hash.h ***************************************/ +/* +** 2001 September 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This is the header file for the generic hash-table implementation +** used in SQLite. We've modified it slightly to serve as a standalone +** hash table implementation for the full-text indexing module. +** +*/ +#ifndef _FTS3_HASH_H_ +#define _FTS3_HASH_H_ + +/* Forward declarations of structures. */ +typedef struct Fts3Hash Fts3Hash; +typedef struct Fts3HashElem Fts3HashElem; + +/* A complete hash table is an instance of the following structure. +** The internals of this structure are intended to be opaque -- client +** code should not attempt to access or modify the fields of this structure +** directly. Change this structure only by using the routines below. +** However, many of the "procedures" and "functions" for modifying and +** accessing this structure are really macros, so we can't really make +** this structure opaque. +*/ +struct Fts3Hash { + char keyClass; /* HASH_INT, _POINTER, _STRING, _BINARY */ + char copyKey; /* True if copy of key made on insert */ + int count; /* Number of entries in this table */ + Fts3HashElem *first; /* The first element of the array */ + int htsize; /* Number of buckets in the hash table */ + struct _fts3ht { /* the hash table */ + int count; /* Number of entries with this hash */ + Fts3HashElem *chain; /* Pointer to first entry with this hash */ + } *ht; +}; + +/* Each element in the hash table is an instance of the following +** structure. All elements are stored on a single doubly-linked list. +** +** Again, this structure is intended to be opaque, but it can't really +** be opaque because it is used by macros. +*/ +struct Fts3HashElem { + Fts3HashElem *next, *prev; /* Next and previous elements in the table */ + void *data; /* Data associated with this element */ + void *pKey; int nKey; /* Key associated with this element */ +}; + +/* +** There are 2 different modes of operation for a hash table: +** +** FTS3_HASH_STRING pKey points to a string that is nKey bytes long +** (including the null-terminator, if any). Case +** is respected in comparisons. +** +** FTS3_HASH_BINARY pKey points to binary data nKey bytes long. +** memcmp() is used to compare keys. +** +** A copy of the key is made if the copyKey parameter to fts3HashInit is 1. +*/ +#define FTS3_HASH_STRING 1 +#define FTS3_HASH_BINARY 2 + +/* +** Access routines. To delete, insert a NULL pointer. +*/ +SQLITE_PRIVATE void sqlite3Fts3HashInit(Fts3Hash *pNew, char keyClass, char copyKey); +SQLITE_PRIVATE void *sqlite3Fts3HashInsert(Fts3Hash*, const void *pKey, int nKey, void *pData); +SQLITE_PRIVATE void *sqlite3Fts3HashFind(const Fts3Hash*, const void *pKey, int nKey); +SQLITE_PRIVATE void sqlite3Fts3HashClear(Fts3Hash*); +SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem(const Fts3Hash *, const void *, int); + +/* +** Shorthand for the functions above +*/ +#define fts3HashInit sqlite3Fts3HashInit +#define fts3HashInsert sqlite3Fts3HashInsert +#define fts3HashFind sqlite3Fts3HashFind +#define fts3HashClear sqlite3Fts3HashClear +#define fts3HashFindElem sqlite3Fts3HashFindElem + +/* +** Macros for looping over all elements of a hash table. The idiom is +** like this: +** +** Fts3Hash h; +** Fts3HashElem *p; +** ... +** for(p=fts3HashFirst(&h); p; p=fts3HashNext(p)){ +** SomeStructure *pData = fts3HashData(p); +** // do something with pData +** } +*/ +#define fts3HashFirst(H) ((H)->first) +#define fts3HashNext(E) ((E)->next) +#define fts3HashData(E) ((E)->data) +#define fts3HashKey(E) ((E)->pKey) +#define fts3HashKeysize(E) ((E)->nKey) + +/* +** Number of entries in a hash table +*/ +#define fts3HashCount(H) ((H)->count) + +#endif /* _FTS3_HASH_H_ */ + +/************** End of fts3_hash.h *******************************************/ +/************** Continuing where we left off in fts3Int.h ********************/ + +/* +** This constant determines the maximum depth of an FTS expression tree +** that the library will create and use. FTS uses recursion to perform +** various operations on the query tree, so the disadvantage of a large +** limit is that it may allow very large queries to use large amounts +** of stack space (perhaps causing a stack overflow). +*/ +#ifndef SQLITE_FTS3_MAX_EXPR_DEPTH +# define SQLITE_FTS3_MAX_EXPR_DEPTH 12 +#endif + + +/* +** This constant controls how often segments are merged. Once there are +** FTS3_MERGE_COUNT segments of level N, they are merged into a single +** segment of level N+1. +*/ +#define FTS3_MERGE_COUNT 16 + +/* +** This is the maximum amount of data (in bytes) to store in the +** Fts3Table.pendingTerms hash table. Normally, the hash table is +** populated as documents are inserted/updated/deleted in a transaction +** and used to create a new segment when the transaction is committed. +** However if this limit is reached midway through a transaction, a new +** segment is created and the hash table cleared immediately. +*/ +#define FTS3_MAX_PENDING_DATA (1*1024*1024) + +/* +** Macro to return the number of elements in an array. SQLite has a +** similar macro called ArraySize(). Use a different name to avoid +** a collision when building an amalgamation with built-in FTS3. +*/ +#define SizeofArray(X) ((int)(sizeof(X)/sizeof(X[0]))) + + +#ifndef MIN +# define MIN(x,y) ((x)<(y)?(x):(y)) +#endif +#ifndef MAX +# define MAX(x,y) ((x)>(y)?(x):(y)) +#endif + +/* +** Maximum length of a varint encoded integer. The varint format is different +** from that used by SQLite, so the maximum length is 10, not 9. +*/ +#define FTS3_VARINT_MAX 10 + +#define FTS3_BUFFER_PADDING 8 + +/* +** FTS4 virtual tables may maintain multiple indexes - one index of all terms +** in the document set and zero or more prefix indexes. All indexes are stored +** as one or more b+-trees in the %_segments and %_segdir tables. +** +** It is possible to determine which index a b+-tree belongs to based on the +** value stored in the "%_segdir.level" column. Given this value L, the index +** that the b+-tree belongs to is (L<<10). In other words, all b+-trees with +** level values between 0 and 1023 (inclusive) belong to index 0, all levels +** between 1024 and 2047 to index 1, and so on. +** +** It is considered impossible for an index to use more than 1024 levels. In +** theory though this may happen, but only after at least +** (FTS3_MERGE_COUNT^1024) separate flushes of the pending-terms tables. +*/ +#define FTS3_SEGDIR_MAXLEVEL 1024 +#define FTS3_SEGDIR_MAXLEVEL_STR "1024" + +/* +** The testcase() macro is only used by the amalgamation. If undefined, +** make it a no-op. +*/ +#ifndef testcase +# define testcase(X) +#endif + +/* +** Terminator values for position-lists and column-lists. +*/ +#define POS_COLUMN (1) /* Column-list terminator */ +#define POS_END (0) /* Position-list terminator */ + +/* +** The assert_fts3_nc() macro is similar to the assert() macro, except that it +** is used for assert() conditions that are true only if it can be +** guranteed that the database is not corrupt. +*/ +#ifdef SQLITE_DEBUG +SQLITE_API extern int sqlite3_fts3_may_be_corrupt; +# define assert_fts3_nc(x) assert(sqlite3_fts3_may_be_corrupt || (x)) +#else +# define assert_fts3_nc(x) assert(x) +#endif + +/* +** This section provides definitions to allow the +** FTS3 extension to be compiled outside of the +** amalgamation. +*/ +#ifndef SQLITE_AMALGAMATION +/* +** Macros indicating that conditional expressions are always true or +** false. +*/ +#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST) +# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1 +#endif +#if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS) +# define ALWAYS(X) (1) +# define NEVER(X) (0) +#elif !defined(NDEBUG) +# define ALWAYS(X) ((X)?1:(assert(0),0)) +# define NEVER(X) ((X)?(assert(0),1):0) +#else +# define ALWAYS(X) (X) +# define NEVER(X) (X) +#endif + +/* +** Internal types used by SQLite. +*/ +typedef unsigned char u8; /* 1-byte (or larger) unsigned integer */ +typedef short int i16; /* 2-byte (or larger) signed integer */ +typedef unsigned int u32; /* 4-byte unsigned integer */ +typedef sqlite3_uint64 u64; /* 8-byte unsigned integer */ +typedef sqlite3_int64 i64; /* 8-byte signed integer */ + +/* +** Macro used to suppress compiler warnings for unused parameters. +*/ +#define UNUSED_PARAMETER(x) (void)(x) + +/* +** The TESTONLY macro is used to enclose variable declarations or +** other bits of code that are needed to support the arguments +** within testcase() and assert() macros. +*/ +#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) +# define TESTONLY(X) X +#else +# define TESTONLY(X) +#endif + +#define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) +#define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) + +#if !defined(deliberate_fall_through) +# if defined(__has_attribute) +# if __has_attribute(fallthrough) +# define deliberate_fall_through __attribute__((fallthrough)); +# endif +# endif +#endif +#if !defined(deliberate_fall_through) +# define deliberate_fall_through +#endif + +/* +** Macros needed to provide flexible arrays in a portable way +*/ +#ifndef offsetof +# define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) +#endif +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define FLEXARRAY +#else +# define FLEXARRAY 1 +#endif + + +#endif /* SQLITE_AMALGAMATION */ + +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3Fts3Corrupt(void); +# define FTS_CORRUPT_VTAB sqlite3Fts3Corrupt() +#else +# define FTS_CORRUPT_VTAB SQLITE_CORRUPT_VTAB +#endif + +typedef struct Fts3Table Fts3Table; +typedef struct Fts3Cursor Fts3Cursor; +typedef struct Fts3Expr Fts3Expr; +typedef struct Fts3Phrase Fts3Phrase; +typedef struct Fts3PhraseToken Fts3PhraseToken; + +typedef struct Fts3Doclist Fts3Doclist; +typedef struct Fts3SegFilter Fts3SegFilter; +typedef struct Fts3DeferredToken Fts3DeferredToken; +typedef struct Fts3SegReader Fts3SegReader; +typedef struct Fts3MultiSegReader Fts3MultiSegReader; + +typedef struct MatchinfoBuffer MatchinfoBuffer; + +/* +** A connection to a fulltext index is an instance of the following +** structure. The xCreate and xConnect methods create an instance +** of this structure and xDestroy and xDisconnect free that instance. +** All other methods receive a pointer to the structure as one of their +** arguments. +*/ +struct Fts3Table { + sqlite3_vtab base; /* Base class used by SQLite core */ + sqlite3 *db; /* The database connection */ + const char *zDb; /* logical database name */ + const char *zName; /* virtual table name */ + int nColumn; /* number of named columns in virtual table */ + char **azColumn; /* column names. malloced */ + u8 *abNotindexed; /* True for 'notindexed' columns */ + sqlite3_tokenizer *pTokenizer; /* tokenizer for inserts and queries */ + char *zContentTbl; /* content=xxx option, or NULL */ + char *zLanguageid; /* languageid=xxx option, or NULL */ + int nAutoincrmerge; /* Value configured by 'automerge' */ + u32 nLeafAdd; /* Number of leaf blocks added this trans */ + int bLock; /* Used to prevent recursive content= tbls */ + + /* Precompiled statements used by the implementation. Each of these + ** statements is run and reset within a single virtual table API call. + */ + sqlite3_stmt *aStmt[40]; + sqlite3_stmt *pSeekStmt; /* Cache for fts3CursorSeekStmt() */ + + char *zReadExprlist; + char *zWriteExprlist; + + int nNodeSize; /* Soft limit for node size */ + u8 bFts4; /* True for FTS4, false for FTS3 */ + u8 bHasStat; /* True if %_stat table exists (2==unknown) */ + u8 bHasDocsize; /* True if %_docsize table exists */ + u8 bDescIdx; /* True if doclists are in reverse order */ + u8 bIgnoreSavepoint; /* True to ignore xSavepoint invocations */ + int nPgsz; /* Page size for host database */ + char *zSegmentsTbl; /* Name of %_segments table */ + sqlite3_blob *pSegments; /* Blob handle open on %_segments table */ + int iSavepoint; + + /* + ** The following array of hash tables is used to buffer pending index + ** updates during transactions. All pending updates buffered at any one + ** time must share a common language-id (see the FTS4 langid= feature). + ** The current language id is stored in variable iPrevLangid. + ** + ** A single FTS4 table may have multiple full-text indexes. For each index + ** there is an entry in the aIndex[] array. Index 0 is an index of all the + ** terms that appear in the document set. Each subsequent index in aIndex[] + ** is an index of prefixes of a specific length. + ** + ** Variable nPendingData contains an estimate the memory consumed by the + ** pending data structures, including hash table overhead, but not including + ** malloc overhead. When nPendingData exceeds nMaxPendingData, all hash + ** tables are flushed to disk. Variable iPrevDocid is the docid of the most + ** recently inserted record. + */ + int nIndex; /* Size of aIndex[] */ + struct Fts3Index { + int nPrefix; /* Prefix length (0 for main terms index) */ + Fts3Hash hPending; /* Pending terms table for this index */ + } *aIndex; + int nMaxPendingData; /* Max pending data before flush to disk */ + int nPendingData; /* Current bytes of pending data */ + sqlite_int64 iPrevDocid; /* Docid of most recently inserted document */ + int iPrevLangid; /* Langid of recently inserted document */ + int bPrevDelete; /* True if last operation was a delete */ + +#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) + /* State variables used for validating that the transaction control + ** methods of the virtual table are called at appropriate times. These + ** values do not contribute to FTS functionality; they are used for + ** verifying the operation of the SQLite core. + */ + int inTransaction; /* True after xBegin but before xCommit/xRollback */ + int mxSavepoint; /* Largest valid xSavepoint integer */ +#endif + +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + /* True to disable the incremental doclist optimization. This is controlled + ** by special insert command 'test-no-incr-doclist'. */ + int bNoIncrDoclist; + + /* Number of segments in a level */ + int nMergeCount; +#endif +}; + +/* Macro to find the number of segments to merge */ +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) +# define MergeCount(P) ((P)->nMergeCount) +#else +# define MergeCount(P) FTS3_MERGE_COUNT +#endif + +/* +** When the core wants to read from the virtual table, it creates a +** virtual table cursor (an instance of the following structure) using +** the xOpen method. Cursors are destroyed using the xClose method. +*/ +struct Fts3Cursor { + sqlite3_vtab_cursor base; /* Base class used by SQLite core */ + i16 eSearch; /* Search strategy (see below) */ + u8 isEof; /* True if at End Of Results */ + u8 isRequireSeek; /* True if must seek pStmt to %_content row */ + u8 bSeekStmt; /* True if pStmt is a seek */ + sqlite3_stmt *pStmt; /* Prepared statement in use by the cursor */ + Fts3Expr *pExpr; /* Parsed MATCH query string */ + int iLangid; /* Language being queried for */ + int nPhrase; /* Number of matchable phrases in query */ + Fts3DeferredToken *pDeferred; /* Deferred search tokens, if any */ + sqlite3_int64 iPrevId; /* Previous id read from aDoclist */ + char *pNextId; /* Pointer into the body of aDoclist */ + char *aDoclist; /* List of docids for full-text queries */ + int nDoclist; /* Size of buffer at aDoclist */ + u8 bDesc; /* True to sort in descending order */ + int eEvalmode; /* An FTS3_EVAL_XX constant */ + int nRowAvg; /* Average size of database rows, in pages */ + sqlite3_int64 nDoc; /* Documents in table */ + i64 iMinDocid; /* Minimum docid to return */ + i64 iMaxDocid; /* Maximum docid to return */ + int isMatchinfoNeeded; /* True when aMatchinfo[] needs filling in */ + MatchinfoBuffer *pMIBuffer; /* Buffer for matchinfo data */ +}; + +#define FTS3_EVAL_FILTER 0 +#define FTS3_EVAL_NEXT 1 +#define FTS3_EVAL_MATCHINFO 2 + +/* +** The Fts3Cursor.eSearch member is always set to one of the following. +** Actually, Fts3Cursor.eSearch can be greater than or equal to +** FTS3_FULLTEXT_SEARCH. If so, then Fts3Cursor.eSearch - 2 is the index +** of the column to be searched. For example, in +** +** CREATE VIRTUAL TABLE ex1 USING fts3(a,b,c,d); +** SELECT docid FROM ex1 WHERE b MATCH 'one two three'; +** +** Because the LHS of the MATCH operator is 2nd column "b", +** Fts3Cursor.eSearch will be set to FTS3_FULLTEXT_SEARCH+1. (+0 for a, +** +1 for b, +2 for c, +3 for d.) If the LHS of MATCH were "ex1" +** indicating that all columns should be searched, +** then eSearch would be set to FTS3_FULLTEXT_SEARCH+4. +*/ +#define FTS3_FULLSCAN_SEARCH 0 /* Linear scan of %_content table */ +#define FTS3_DOCID_SEARCH 1 /* Lookup by rowid on %_content table */ +#define FTS3_FULLTEXT_SEARCH 2 /* Full-text index search */ + +/* +** The lower 16-bits of the sqlite3_index_info.idxNum value set by +** the xBestIndex() method contains the Fts3Cursor.eSearch value described +** above. The upper 16-bits contain a combination of the following +** bits, used to describe extra constraints on full-text searches. +*/ +#define FTS3_HAVE_LANGID 0x00010000 /* languageid=? */ +#define FTS3_HAVE_DOCID_GE 0x00020000 /* docid>=? */ +#define FTS3_HAVE_DOCID_LE 0x00040000 /* docid<=? */ + +struct Fts3Doclist { + char *aAll; /* Array containing doclist (or NULL) */ + int nAll; /* Size of a[] in bytes */ + char *pNextDocid; /* Pointer to next docid */ + + sqlite3_int64 iDocid; /* Current docid (if pList!=0) */ + int bFreeList; /* True if pList should be sqlite3_free()d */ + char *pList; /* Pointer to position list following iDocid */ + int nList; /* Length of position list */ +}; + +/* +** A "phrase" is a sequence of one or more tokens that must match in +** sequence. A single token is the base case and the most common case. +** For a sequence of tokens contained in double-quotes (i.e. "one two three") +** nToken will be the number of tokens in the string. +*/ +struct Fts3PhraseToken { + char *z; /* Text of the token */ + int n; /* Number of bytes in buffer z */ + int isPrefix; /* True if token ends with a "*" character */ + int bFirst; /* True if token must appear at position 0 */ + + /* Variables above this point are populated when the expression is + ** parsed (by code in fts3_expr.c). Below this point the variables are + ** used when evaluating the expression. */ + Fts3DeferredToken *pDeferred; /* Deferred token object for this token */ + Fts3MultiSegReader *pSegcsr; /* Segment-reader for this token */ +}; + +struct Fts3Phrase { + /* Cache of doclist for this phrase. */ + Fts3Doclist doclist; + int bIncr; /* True if doclist is loaded incrementally */ + int iDoclistToken; + + /* Used by sqlite3Fts3EvalPhrasePoslist() if this is a descendent of an + ** OR condition. */ + char *pOrPoslist; + i64 iOrDocid; + + /* Variables below this point are populated by fts3_expr.c when parsing + ** a MATCH expression. Everything above is part of the evaluation phase. + */ + int nToken; /* Number of tokens in the phrase */ + int iColumn; /* Index of column this phrase must match */ + Fts3PhraseToken aToken[FLEXARRAY]; /* One for each token in the phrase */ +}; + +/* Size (in bytes) of an Fts3Phrase object large enough to hold N tokens */ +#define SZ_FTS3PHRASE(N) \ + (offsetof(Fts3Phrase,aToken)+(N)*sizeof(Fts3PhraseToken)) + +/* +** A tree of these objects forms the RHS of a MATCH operator. +** +** If Fts3Expr.eType is FTSQUERY_PHRASE and isLoaded is true, then aDoclist +** points to a malloced buffer, size nDoclist bytes, containing the results +** of this phrase query in FTS3 doclist format. As usual, the initial +** "Length" field found in doclists stored on disk is omitted from this +** buffer. +** +** Variable aMI is used only for FTSQUERY_NEAR nodes to store the global +** matchinfo data. If it is not NULL, it points to an array of size nCol*3, +** where nCol is the number of columns in the queried FTS table. The array +** is populated as follows: +** +** aMI[iCol*3 + 0] = Undefined +** aMI[iCol*3 + 1] = Number of occurrences +** aMI[iCol*3 + 2] = Number of rows containing at least one instance +** +** The aMI array is allocated using sqlite3_malloc(). It should be freed +** when the expression node is. +*/ +struct Fts3Expr { + int eType; /* One of the FTSQUERY_XXX values defined below */ + int nNear; /* Valid if eType==FTSQUERY_NEAR */ + Fts3Expr *pParent; /* pParent->pLeft==this or pParent->pRight==this */ + Fts3Expr *pLeft; /* Left operand */ + Fts3Expr *pRight; /* Right operand */ + Fts3Phrase *pPhrase; /* Valid if eType==FTSQUERY_PHRASE */ + + /* The following are used by the fts3_eval.c module. */ + sqlite3_int64 iDocid; /* Current docid */ + u8 bEof; /* True this expression is at EOF already */ + u8 bStart; /* True if iDocid is valid */ + u8 bDeferred; /* True if this expression is entirely deferred */ + + /* The following are used by the fts3_snippet.c module. */ + int iPhrase; /* Index of this phrase in matchinfo() results */ + u32 *aMI; /* See above */ +}; + +/* +** Candidate values for Fts3Query.eType. Note that the order of the first +** four values is in order of precedence when parsing expressions. For +** example, the following: +** +** "a OR b AND c NOT d NEAR e" +** +** is equivalent to: +** +** "a OR (b AND (c NOT (d NEAR e)))" +*/ +#define FTSQUERY_NEAR 1 +#define FTSQUERY_NOT 2 +#define FTSQUERY_AND 3 +#define FTSQUERY_OR 4 +#define FTSQUERY_PHRASE 5 + + +/* fts3_write.c */ +SQLITE_PRIVATE int sqlite3Fts3UpdateMethod(sqlite3_vtab*,int,sqlite3_value**,sqlite3_int64*); +SQLITE_PRIVATE int sqlite3Fts3PendingTermsFlush(Fts3Table *); +SQLITE_PRIVATE void sqlite3Fts3PendingTermsClear(Fts3Table *); +SQLITE_PRIVATE int sqlite3Fts3Optimize(Fts3Table *); +SQLITE_PRIVATE int sqlite3Fts3SegReaderNew(int, int, sqlite3_int64, + sqlite3_int64, sqlite3_int64, const char *, int, Fts3SegReader**); +SQLITE_PRIVATE int sqlite3Fts3SegReaderPending( + Fts3Table*,int,const char*,int,int,Fts3SegReader**); +SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3SegReader *); +SQLITE_PRIVATE int sqlite3Fts3AllSegdirs(Fts3Table*, int, int, int, sqlite3_stmt **); +SQLITE_PRIVATE int sqlite3Fts3ReadBlock(Fts3Table*, sqlite3_int64, char **, int*, int*); + +SQLITE_PRIVATE int sqlite3Fts3SelectDoctotal(Fts3Table *, sqlite3_stmt **); +SQLITE_PRIVATE int sqlite3Fts3SelectDocsize(Fts3Table *, sqlite3_int64, sqlite3_stmt **); + +#ifndef SQLITE_DISABLE_FTS4_DEFERRED +SQLITE_PRIVATE void sqlite3Fts3FreeDeferredTokens(Fts3Cursor *); +SQLITE_PRIVATE int sqlite3Fts3DeferToken(Fts3Cursor *, Fts3PhraseToken *, int); +SQLITE_PRIVATE int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *); +SQLITE_PRIVATE void sqlite3Fts3FreeDeferredDoclists(Fts3Cursor *); +SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *); +#else +# define sqlite3Fts3FreeDeferredTokens(x) +# define sqlite3Fts3DeferToken(x,y,z) SQLITE_OK +# define sqlite3Fts3CacheDeferredDoclists(x) SQLITE_OK +# define sqlite3Fts3FreeDeferredDoclists(x) +# define sqlite3Fts3DeferredTokenList(x,y,z) SQLITE_OK +#endif + +SQLITE_PRIVATE void sqlite3Fts3SegmentsClose(Fts3Table *); +SQLITE_PRIVATE int sqlite3Fts3MaxLevel(Fts3Table *, int *); + +/* Special values interpreted by sqlite3SegReaderCursor() */ +#define FTS3_SEGCURSOR_PENDING -1 +#define FTS3_SEGCURSOR_ALL -2 + +SQLITE_PRIVATE int sqlite3Fts3SegReaderStart(Fts3Table*, Fts3MultiSegReader*, Fts3SegFilter*); +SQLITE_PRIVATE int sqlite3Fts3SegReaderStep(Fts3Table *, Fts3MultiSegReader *); +SQLITE_PRIVATE void sqlite3Fts3SegReaderFinish(Fts3MultiSegReader *); + +SQLITE_PRIVATE int sqlite3Fts3SegReaderCursor(Fts3Table *, + int, int, int, const char *, int, int, int, Fts3MultiSegReader *); + +/* Flags allowed as part of the 4th argument to SegmentReaderIterate() */ +#define FTS3_SEGMENT_REQUIRE_POS 0x00000001 +#define FTS3_SEGMENT_IGNORE_EMPTY 0x00000002 +#define FTS3_SEGMENT_COLUMN_FILTER 0x00000004 +#define FTS3_SEGMENT_PREFIX 0x00000008 +#define FTS3_SEGMENT_SCAN 0x00000010 +#define FTS3_SEGMENT_FIRST 0x00000020 + +/* Type passed as 4th argument to SegmentReaderIterate() */ +struct Fts3SegFilter { + const char *zTerm; + int nTerm; + int iCol; + int flags; +}; + +struct Fts3MultiSegReader { + /* Used internally by sqlite3Fts3SegReaderXXX() calls */ + Fts3SegReader **apSegment; /* Array of Fts3SegReader objects */ + int nSegment; /* Size of apSegment array */ + int nAdvance; /* How many seg-readers to advance */ + Fts3SegFilter *pFilter; /* Pointer to filter object */ + char *aBuffer; /* Buffer to merge doclists in */ + i64 nBuffer; /* Allocated size of aBuffer[] in bytes */ + + int iColFilter; /* If >=0, filter for this column */ + int bRestart; + + /* Used by fts3.c only. */ + int nCost; /* Cost of running iterator */ + int bLookup; /* True if a lookup of a single entry. */ + + /* Output values. Valid only after Fts3SegReaderStep() returns SQLITE_ROW. */ + char *zTerm; /* Pointer to term buffer */ + int nTerm; /* Size of zTerm in bytes */ + char *aDoclist; /* Pointer to doclist buffer */ + int nDoclist; /* Size of aDoclist[] in bytes */ +}; + +SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table*,int,int); + +#define fts3GetVarint32(p, piVal) ( \ + (*(u8*)(p)&0x80) ? sqlite3Fts3GetVarint32(p, piVal) : (*piVal=*(u8*)(p), 1) \ +) + +SQLITE_PRIVATE int sqlite3Fts3PrepareStmt( + Fts3Table *p, /* Prepare for this connection */ + const char *zSql, /* SQL to prepare */ + int bPersist, /* True to set SQLITE_PREPARE_PERSISTENT */ + int bAllowVtab, /* True to omit SQLITE_PREPARE_NO_VTAB */ + sqlite3_stmt **pp /* OUT: Prepared statement */ +); + + +/* fts3.c */ +SQLITE_PRIVATE void sqlite3Fts3ErrMsg(char**,const char*,...); +SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *, sqlite3_int64); +SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *, sqlite_int64 *); +SQLITE_PRIVATE int sqlite3Fts3GetVarintU(const char *, sqlite_uint64 *); +SQLITE_PRIVATE int sqlite3Fts3GetVarintBounded(const char*,const char*,sqlite3_int64*); +SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *, int *); +SQLITE_PRIVATE int sqlite3Fts3VarintLen(sqlite3_uint64); +SQLITE_PRIVATE void sqlite3Fts3Dequote(char *); +SQLITE_PRIVATE void sqlite3Fts3DoclistPrev(int,char*,int,char**,sqlite3_int64*,int*,u8*); +SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *); +SQLITE_PRIVATE int sqlite3Fts3FirstFilter(sqlite3_int64, char *, int, char *); +SQLITE_PRIVATE void sqlite3Fts3CreateStatTable(int*, Fts3Table*); +SQLITE_PRIVATE int sqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc); +SQLITE_PRIVATE int sqlite3Fts3ReadInt(const char *z, int *pnOut); + +/* fts3_tokenizer.c */ +SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *, int *); +SQLITE_PRIVATE int sqlite3Fts3InitHashTable(sqlite3 *, Fts3Hash *, const char *); +SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, const char *, + sqlite3_tokenizer **, char ** +); +SQLITE_PRIVATE int sqlite3Fts3IsIdChar(char); + +/* fts3_snippet.c */ +SQLITE_PRIVATE void sqlite3Fts3Offsets(sqlite3_context*, Fts3Cursor*); +SQLITE_PRIVATE void sqlite3Fts3Snippet(sqlite3_context *, Fts3Cursor *, const char *, + const char *, const char *, int, int +); +SQLITE_PRIVATE void sqlite3Fts3Matchinfo(sqlite3_context *, Fts3Cursor *, const char *); +SQLITE_PRIVATE void sqlite3Fts3MIBufferFree(MatchinfoBuffer *p); + +/* fts3_expr.c */ +SQLITE_PRIVATE int sqlite3Fts3ExprParse(sqlite3_tokenizer *, int, + char **, int, int, int, const char *, int, Fts3Expr **, char ** +); +SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *); +#ifdef SQLITE_TEST +SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash*); +SQLITE_PRIVATE int sqlite3Fts3InitTerm(sqlite3 *db); +#endif +SQLITE_PRIVATE void *sqlite3Fts3MallocZero(i64 nByte); + +SQLITE_PRIVATE int sqlite3Fts3OpenTokenizer(sqlite3_tokenizer *, int, const char *, int, + sqlite3_tokenizer_cursor ** +); + +/* fts3_aux.c */ +SQLITE_PRIVATE int sqlite3Fts3InitAux(sqlite3 *db); + +SQLITE_PRIVATE void sqlite3Fts3EvalPhraseCleanup(Fts3Phrase *); + +SQLITE_PRIVATE int sqlite3Fts3MsrIncrStart( + Fts3Table*, Fts3MultiSegReader*, int, const char*, int); +SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext( + Fts3Table *, Fts3MultiSegReader *, sqlite3_int64 *, char **, int *); +SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(Fts3Cursor *, Fts3Expr *, int iCol, char **); +SQLITE_PRIVATE int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *); +SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr); +SQLITE_PRIVATE int sqlite3Fts3MsrCancel(Fts3Cursor*, Fts3Expr*); + +/* fts3_tokenize_vtab.c */ +SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *, void(*xDestroy)(void*)); + +/* fts3_unicode2.c (functions generated by parsing unicode text files) */ +#ifndef SQLITE_DISABLE_FTS3_UNICODE +SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int, int); +SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int); +SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int); +#endif + +SQLITE_PRIVATE int sqlite3Fts3ExprIterate(Fts3Expr*, int (*x)(Fts3Expr*,int,void*), void*); + +SQLITE_PRIVATE int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk); + +#endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */ +#endif /* _FTSINT_H */ + +/************** End of fts3Int.h *********************************************/ +/************** Continuing where we left off in fts3.c ***********************/ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +#if defined(SQLITE_ENABLE_FTS3) && !defined(SQLITE_CORE) +# define SQLITE_CORE 1 +#endif + + +/* #include "fts3.h" */ +#ifndef SQLITE_CORE +/* # include "sqlite3ext.h" */ + SQLITE_EXTENSION_INIT1 +#endif + + +/* +** Assume any b-tree layer with more levels than this is corrupt. +*/ +#define FTS3_MAX_BTREE_HEIGHT 48 + +typedef struct Fts3HashWrapper Fts3HashWrapper; +struct Fts3HashWrapper { + Fts3Hash hash; /* Hash table */ + int nRef; /* Number of pointers to this object */ +}; + +static int fts3EvalNext(Fts3Cursor *pCsr); +static int fts3EvalStart(Fts3Cursor *pCsr); +static int fts3TermSegReaderCursor( + Fts3Cursor *, const char *, int, int, Fts3MultiSegReader **); + +/* +** This variable is set to false when running tests for which the on disk +** structures should not be corrupt. Otherwise, true. If it is false, extra +** assert() conditions in the fts3 code are activated - conditions that are +** only true if it is guaranteed that the fts3 database is not corrupt. +*/ +#ifdef SQLITE_DEBUG +SQLITE_API int sqlite3_fts3_may_be_corrupt = 1; +#endif + +/* +** Write a 64-bit variable-length integer to memory starting at p[0]. +** The length of data written will be between 1 and FTS3_VARINT_MAX bytes. +** The number of bytes written is returned. +*/ +SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *p, sqlite_int64 v){ + unsigned char *q = (unsigned char *) p; + sqlite_uint64 vu = v; + do{ + *q++ = (unsigned char) ((vu & 0x7f) | 0x80); + vu >>= 7; + }while( vu!=0 ); + q[-1] &= 0x7f; /* turn off high bit in final byte */ + assert( q - (unsigned char *)p <= FTS3_VARINT_MAX ); + return (int) (q - (unsigned char *)p); +} + +#define GETVARINT_STEP(v, ptr, shift, mask1, mask2, var, ret) \ + v = (v & mask1) | ( (*(const unsigned char*)(ptr++)) << shift ); \ + if( (v & mask2)==0 ){ var = v; return ret; } +#define GETVARINT_INIT(v, ptr, shift, mask1, mask2, var, ret) \ + v = (*ptr++); \ + if( (v & mask2)==0 ){ var = v; return ret; } + +SQLITE_PRIVATE int sqlite3Fts3GetVarintU(const char *pBuf, sqlite_uint64 *v){ + const unsigned char *p = (const unsigned char*)pBuf; + const unsigned char *pStart = p; + u32 a; + u64 b; + int shift; + + GETVARINT_INIT(a, p, 0, 0x00, 0x80, *v, 1); + GETVARINT_STEP(a, p, 7, 0x7F, 0x4000, *v, 2); + GETVARINT_STEP(a, p, 14, 0x3FFF, 0x200000, *v, 3); + GETVARINT_STEP(a, p, 21, 0x1FFFFF, 0x10000000, *v, 4); + b = (a & 0x0FFFFFFF ); + + for(shift=28; shift<=63; shift+=7){ + u64 c = *p++; + b += (c&0x7F) << shift; + if( (c & 0x80)==0 ) break; + } + *v = b; + return (int)(p - pStart); +} + +/* +** Read a 64-bit variable-length integer from memory starting at p[0]. +** Return the number of bytes read, or 0 on error. +** The value is stored in *v. +*/ +SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *pBuf, sqlite_int64 *v){ + return sqlite3Fts3GetVarintU(pBuf, (sqlite3_uint64*)v); +} + +/* +** Read a 64-bit variable-length integer from memory starting at p[0] and +** not extending past pEnd[-1]. +** Return the number of bytes read, or 0 on error. +** The value is stored in *v. +*/ +SQLITE_PRIVATE int sqlite3Fts3GetVarintBounded( + const char *pBuf, + const char *pEnd, + sqlite_int64 *v +){ + const unsigned char *p = (const unsigned char*)pBuf; + const unsigned char *pStart = p; + const unsigned char *pX = (const unsigned char*)pEnd; + u64 b = 0; + int shift; + for(shift=0; shift<=63; shift+=7){ + u64 c = p=0 ); + return 5; +} + +/* +** Return the number of bytes required to encode v as a varint +*/ +SQLITE_PRIVATE int sqlite3Fts3VarintLen(sqlite3_uint64 v){ + int i = 0; + do{ + i++; + v >>= 7; + }while( v!=0 ); + return i; +} + +/* +** Convert an SQL-style quoted string into a normal string by removing +** the quote characters. The conversion is done in-place. If the +** input does not begin with a quote character, then this routine +** is a no-op. +** +** Examples: +** +** "abc" becomes abc +** 'xyz' becomes xyz +** [pqr] becomes pqr +** `mno` becomes mno +** +*/ +SQLITE_PRIVATE void sqlite3Fts3Dequote(char *z){ + char quote; /* Quote character (if any ) */ + + quote = z[0]; + if( quote=='[' || quote=='\'' || quote=='"' || quote=='`' ){ + int iIn = 1; /* Index of next byte to read from input */ + int iOut = 0; /* Index of next byte to write to output */ + + /* If the first byte was a '[', then the close-quote character is a ']' */ + if( quote=='[' ) quote = ']'; + + while( z[iIn] ){ + if( z[iIn]==quote ){ + if( z[iIn+1]!=quote ) break; + z[iOut++] = quote; + iIn += 2; + }else{ + z[iOut++] = z[iIn++]; + } + } + z[iOut] = '\0'; + } +} + +/* +** Read a single varint from the doclist at *pp and advance *pp to point +** to the first byte past the end of the varint. Add the value of the varint +** to *pVal. +*/ +static void fts3GetDeltaVarint(char **pp, sqlite3_int64 *pVal){ + sqlite3_int64 iVal; + *pp += sqlite3Fts3GetVarint(*pp, &iVal); + *pVal += iVal; +} + +/* +** When this function is called, *pp points to the first byte following a +** varint that is part of a doclist (or position-list, or any other list +** of varints). This function moves *pp to point to the start of that varint, +** and sets *pVal by the varint value. +** +** Argument pStart points to the first byte of the doclist that the +** varint is part of. +*/ +static void fts3GetReverseVarint( + char **pp, + char *pStart, + sqlite3_int64 *pVal +){ + sqlite3_int64 iVal; + char *p; + + /* Pointer p now points at the first byte past the varint we are + ** interested in. So, unless the doclist is corrupt, the 0x80 bit is + ** clear on character p[-1]. */ + for(p = (*pp)-2; p>=pStart && *p&0x80; p--); + p++; + *pp = p; + + sqlite3Fts3GetVarint(p, &iVal); + *pVal = iVal; +} + +/* +** The xDisconnect() virtual table method. +*/ +static int fts3DisconnectMethod(sqlite3_vtab *pVtab){ + Fts3Table *p = (Fts3Table *)pVtab; + int i; + + assert( p->nPendingData==0 ); + assert( p->pSegments==0 ); + + /* Free any prepared statements held */ + sqlite3_finalize(p->pSeekStmt); + for(i=0; iaStmt); i++){ + sqlite3_finalize(p->aStmt[i]); + } + sqlite3_free(p->zSegmentsTbl); + sqlite3_free(p->zReadExprlist); + sqlite3_free(p->zWriteExprlist); + sqlite3_free(p->zContentTbl); + sqlite3_free(p->zLanguageid); + + /* Invoke the tokenizer destructor to free the tokenizer. */ + p->pTokenizer->pModule->xDestroy(p->pTokenizer); + + sqlite3_free(p); + return SQLITE_OK; +} + +/* +** Write an error message into *pzErr +*/ +SQLITE_PRIVATE void sqlite3Fts3ErrMsg(char **pzErr, const char *zFormat, ...){ + va_list ap; + sqlite3_free(*pzErr); + va_start(ap, zFormat); + *pzErr = sqlite3_vmprintf(zFormat, ap); + va_end(ap); +} + +/* +** Construct one or more SQL statements from the format string given +** and then evaluate those statements. The success code is written +** into *pRc. +** +** If *pRc is initially non-zero then this routine is a no-op. +*/ +static void fts3DbExec( + int *pRc, /* Success code */ + sqlite3 *db, /* Database in which to run SQL */ + const char *zFormat, /* Format string for SQL */ + ... /* Arguments to the format string */ +){ + va_list ap; + char *zSql; + if( *pRc ) return; + va_start(ap, zFormat); + zSql = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + if( zSql==0 ){ + *pRc = SQLITE_NOMEM; + }else{ + *pRc = sqlite3_exec(db, zSql, 0, 0, 0); + sqlite3_free(zSql); + } +} + +/* +** The xDestroy() virtual table method. +*/ +static int fts3DestroyMethod(sqlite3_vtab *pVtab){ + Fts3Table *p = (Fts3Table *)pVtab; + int rc = SQLITE_OK; /* Return code */ + const char *zDb = p->zDb; /* Name of database (e.g. "main", "temp") */ + sqlite3 *db = p->db; /* Database handle */ + + /* Drop the shadow tables */ + fts3DbExec(&rc, db, + "DROP TABLE IF EXISTS %Q.'%q_segments';" + "DROP TABLE IF EXISTS %Q.'%q_segdir';" + "DROP TABLE IF EXISTS %Q.'%q_docsize';" + "DROP TABLE IF EXISTS %Q.'%q_stat';" + "%s DROP TABLE IF EXISTS %Q.'%q_content';", + zDb, p->zName, + zDb, p->zName, + zDb, p->zName, + zDb, p->zName, + (p->zContentTbl ? "--" : ""), zDb,p->zName + ); + + /* If everything has worked, invoke fts3DisconnectMethod() to free the + ** memory associated with the Fts3Table structure and return SQLITE_OK. + ** Otherwise, return an SQLite error code. + */ + return (rc==SQLITE_OK ? fts3DisconnectMethod(pVtab) : rc); +} + + +/* +** Invoke sqlite3_declare_vtab() to declare the schema for the FTS3 table +** passed as the first argument. This is done as part of the xConnect() +** and xCreate() methods. +** +** If *pRc is non-zero when this function is called, it is a no-op. +** Otherwise, if an error occurs, an SQLite error code is stored in *pRc +** before returning. +*/ +static void fts3DeclareVtab(int *pRc, Fts3Table *p){ + if( *pRc==SQLITE_OK ){ + int i; /* Iterator variable */ + int rc; /* Return code */ + char *zSql; /* SQL statement passed to declare_vtab() */ + char *zCols; /* List of user defined columns */ + const char *zLanguageid; + + zLanguageid = (p->zLanguageid ? p->zLanguageid : "__langid"); + sqlite3_vtab_config(p->db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); + sqlite3_vtab_config(p->db, SQLITE_VTAB_INNOCUOUS); + + /* Create a list of user columns for the virtual table */ + zCols = sqlite3_mprintf("%Q, ", p->azColumn[0]); + for(i=1; zCols && inColumn; i++){ + zCols = sqlite3_mprintf("%z%Q, ", zCols, p->azColumn[i]); + } + + /* Create the whole "CREATE TABLE" statement to pass to SQLite */ + zSql = sqlite3_mprintf( + "CREATE TABLE x(%s %Q HIDDEN, docid HIDDEN, %Q HIDDEN)", + zCols, p->zName, zLanguageid + ); + if( !zCols || !zSql ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_declare_vtab(p->db, zSql); + } + + sqlite3_free(zSql); + sqlite3_free(zCols); + *pRc = rc; + } +} + +/* +** Create the %_stat table if it does not already exist. +*/ +SQLITE_PRIVATE void sqlite3Fts3CreateStatTable(int *pRc, Fts3Table *p){ + fts3DbExec(pRc, p->db, + "CREATE TABLE IF NOT EXISTS %Q.'%q_stat'" + "(id INTEGER PRIMARY KEY, value BLOB);", + p->zDb, p->zName + ); + if( (*pRc)==SQLITE_OK ) p->bHasStat = 1; +} + +/* +** Create the backing store tables (%_content, %_segments and %_segdir) +** required by the FTS3 table passed as the only argument. This is done +** as part of the vtab xCreate() method. +** +** If the p->bHasDocsize boolean is true (indicating that this is an +** FTS4 table, not an FTS3 table) then also create the %_docsize and +** %_stat tables required by FTS4. +*/ +static int fts3CreateTables(Fts3Table *p){ + int rc = SQLITE_OK; /* Return code */ + int i; /* Iterator variable */ + sqlite3 *db = p->db; /* The database connection */ + + if( p->zContentTbl==0 ){ + const char *zLanguageid = p->zLanguageid; + char *zContentCols; /* Columns of %_content table */ + + /* Create a list of user columns for the content table */ + zContentCols = sqlite3_mprintf("docid INTEGER PRIMARY KEY"); + for(i=0; zContentCols && inColumn; i++){ + char *z = p->azColumn[i]; + zContentCols = sqlite3_mprintf("%z, 'c%d%q'", zContentCols, i, z); + } + if( zLanguageid && zContentCols ){ + zContentCols = sqlite3_mprintf("%z, langid", zContentCols, zLanguageid); + } + if( zContentCols==0 ) rc = SQLITE_NOMEM; + + /* Create the content table */ + fts3DbExec(&rc, db, + "CREATE TABLE %Q.'%q_content'(%s)", + p->zDb, p->zName, zContentCols + ); + sqlite3_free(zContentCols); + } + + /* Create other tables */ + fts3DbExec(&rc, db, + "CREATE TABLE %Q.'%q_segments'(blockid INTEGER PRIMARY KEY, block BLOB);", + p->zDb, p->zName + ); + fts3DbExec(&rc, db, + "CREATE TABLE %Q.'%q_segdir'(" + "level INTEGER," + "idx INTEGER," + "start_block INTEGER," + "leaves_end_block INTEGER," + "end_block INTEGER," + "root BLOB," + "PRIMARY KEY(level, idx)" + ");", + p->zDb, p->zName + ); + if( p->bHasDocsize ){ + fts3DbExec(&rc, db, + "CREATE TABLE %Q.'%q_docsize'(docid INTEGER PRIMARY KEY, size BLOB);", + p->zDb, p->zName + ); + } + assert( p->bHasStat==p->bFts4 ); + if( p->bHasStat ){ + sqlite3Fts3CreateStatTable(&rc, p); + } + return rc; +} + +/* +** Store the current database page-size in bytes in p->nPgsz. +** +** If *pRc is non-zero when this function is called, it is a no-op. +** Otherwise, if an error occurs, an SQLite error code is stored in *pRc +** before returning. +*/ +static void fts3DatabasePageSize(int *pRc, Fts3Table *p){ + if( *pRc==SQLITE_OK ){ + int rc; /* Return code */ + char *zSql; /* SQL text "PRAGMA %Q.page_size" */ + sqlite3_stmt *pStmt; /* Compiled "PRAGMA %Q.page_size" statement */ + + zSql = sqlite3_mprintf("PRAGMA %Q.page_size", p->zDb); + if( !zSql ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0); + if( rc==SQLITE_OK ){ + sqlite3_step(pStmt); + p->nPgsz = sqlite3_column_int(pStmt, 0); + rc = sqlite3_finalize(pStmt); + }else if( rc==SQLITE_AUTH ){ + p->nPgsz = 1024; + rc = SQLITE_OK; + } + } + assert( p->nPgsz>0 || rc!=SQLITE_OK ); + sqlite3_free(zSql); + *pRc = rc; + } +} + +/* +** "Special" FTS4 arguments are column specifications of the following form: +** +** = +** +** There may not be whitespace surrounding the "=" character. The +** term may be quoted, but the may not. +*/ +static int fts3IsSpecialColumn( + const char *z, + int *pnKey, + char **pzValue +){ + char *zValue; + const char *zCsr = z; + + while( *zCsr!='=' ){ + if( *zCsr=='\0' ) return 0; + zCsr++; + } + + *pnKey = (int)(zCsr-z); + zValue = sqlite3_mprintf("%s", &zCsr[1]); + if( zValue ){ + sqlite3Fts3Dequote(zValue); + } + *pzValue = zValue; + return 1; +} + +/* +** Append the output of a printf() style formatting to an existing string. +*/ +static void fts3Appendf( + int *pRc, /* IN/OUT: Error code */ + char **pz, /* IN/OUT: Pointer to string buffer */ + const char *zFormat, /* Printf format string to append */ + ... /* Arguments for printf format string */ +){ + if( *pRc==SQLITE_OK ){ + va_list ap; + char *z; + va_start(ap, zFormat); + z = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + if( z && *pz ){ + char *z2 = sqlite3_mprintf("%s%s", *pz, z); + sqlite3_free(z); + z = z2; + } + if( z==0 ) *pRc = SQLITE_NOMEM; + sqlite3_free(*pz); + *pz = z; + } +} + +/* +** Return a copy of input string zInput enclosed in double-quotes (") and +** with all double quote characters escaped. For example: +** +** fts3QuoteId("un \"zip\"") -> "un \"\"zip\"\"" +** +** The pointer returned points to memory obtained from sqlite3_malloc(). It +** is the callers responsibility to call sqlite3_free() to release this +** memory. +*/ +static char *fts3QuoteId(char const *zInput){ + sqlite3_int64 nRet; + char *zRet; + nRet = 2 + (int)strlen(zInput)*2 + 1; + zRet = sqlite3_malloc64(nRet); + if( zRet ){ + int i; + char *z = zRet; + *(z++) = '"'; + for(i=0; zInput[i]; i++){ + if( zInput[i]=='"' ) *(z++) = '"'; + *(z++) = zInput[i]; + } + *(z++) = '"'; + *(z++) = '\0'; + } + return zRet; +} + +/* +** Return a list of comma separated SQL expressions and a FROM clause that +** could be used in a SELECT statement such as the following: +** +** SELECT FROM %_content AS x ... +** +** to return the docid, followed by each column of text data in order +** from left to write. If parameter zFunc is not NULL, then instead of +** being returned directly each column of text data is passed to an SQL +** function named zFunc first. For example, if zFunc is "unzip" and the +** table has the three user-defined columns "a", "b", and "c", the following +** string is returned: +** +** "docid, unzip(x.'a'), unzip(x.'b'), unzip(x.'c') FROM %_content AS x" +** +** The pointer returned points to a buffer allocated by sqlite3_malloc(). It +** is the responsibility of the caller to eventually free it. +** +** If *pRc is not SQLITE_OK when this function is called, it is a no-op (and +** a NULL pointer is returned). Otherwise, if an OOM error is encountered +** by this function, NULL is returned and *pRc is set to SQLITE_NOMEM. If +** no error occurs, *pRc is left unmodified. +*/ +static char *fts3ReadExprList(Fts3Table *p, const char *zFunc, int *pRc){ + char *zRet = 0; + char *zFree = 0; + char *zFunction; + int i; + + if( p->zContentTbl==0 ){ + if( !zFunc ){ + zFunction = ""; + }else{ + zFree = zFunction = fts3QuoteId(zFunc); + } + fts3Appendf(pRc, &zRet, "docid"); + for(i=0; inColumn; i++){ + fts3Appendf(pRc, &zRet, ",%s(x.'c%d%q')", zFunction, i, p->azColumn[i]); + } + if( p->zLanguageid ){ + fts3Appendf(pRc, &zRet, ", x.%Q", "langid"); + } + sqlite3_free(zFree); + }else{ + fts3Appendf(pRc, &zRet, "rowid"); + for(i=0; inColumn; i++){ + fts3Appendf(pRc, &zRet, ", x.'%q'", p->azColumn[i]); + } + if( p->zLanguageid ){ + fts3Appendf(pRc, &zRet, ", x.%Q", p->zLanguageid); + } + } + fts3Appendf(pRc, &zRet, " FROM '%q'.'%q%s' AS x", + p->zDb, + (p->zContentTbl ? p->zContentTbl : p->zName), + (p->zContentTbl ? "" : "_content") + ); + return zRet; +} + +/* +** Return a list of N comma separated question marks, where N is the number +** of columns in the %_content table (one for the docid plus one for each +** user-defined text column). +** +** If argument zFunc is not NULL, then all but the first question mark +** is preceded by zFunc and an open bracket, and followed by a closed +** bracket. For example, if zFunc is "zip" and the FTS3 table has three +** user-defined text columns, the following string is returned: +** +** "?, zip(?), zip(?), zip(?)" +** +** The pointer returned points to a buffer allocated by sqlite3_malloc(). It +** is the responsibility of the caller to eventually free it. +** +** If *pRc is not SQLITE_OK when this function is called, it is a no-op (and +** a NULL pointer is returned). Otherwise, if an OOM error is encountered +** by this function, NULL is returned and *pRc is set to SQLITE_NOMEM. If +** no error occurs, *pRc is left unmodified. +*/ +static char *fts3WriteExprList(Fts3Table *p, const char *zFunc, int *pRc){ + char *zRet = 0; + char *zFree = 0; + char *zFunction; + int i; + + if( !zFunc ){ + zFunction = ""; + }else{ + zFree = zFunction = fts3QuoteId(zFunc); + } + fts3Appendf(pRc, &zRet, "?"); + for(i=0; inColumn; i++){ + fts3Appendf(pRc, &zRet, ",%s(?)", zFunction); + } + if( p->zLanguageid ){ + fts3Appendf(pRc, &zRet, ", ?"); + } + sqlite3_free(zFree); + return zRet; +} + +/* +** Buffer z contains a positive integer value encoded as utf-8 text. +** Decode this value and store it in *pnOut, returning the number of bytes +** consumed. If an overflow error occurs return a negative value. +*/ +SQLITE_PRIVATE int sqlite3Fts3ReadInt(const char *z, int *pnOut){ + u64 iVal = 0; + int i; + for(i=0; z[i]>='0' && z[i]<='9'; i++){ + iVal = iVal*10 + (z[i] - '0'); + if( iVal>0x7FFFFFFF ) return -1; + } + *pnOut = (int)iVal; + return i; +} + +/* +** This function interprets the string at (*pp) as a non-negative integer +** value. It reads the integer and sets *pnOut to the value read, then +** sets *pp to point to the byte immediately following the last byte of +** the integer value. +** +** Only decimal digits ('0'..'9') may be part of an integer value. +** +** If *pp does not being with a decimal digit SQLITE_ERROR is returned and +** the output value undefined. Otherwise SQLITE_OK is returned. +** +** This function is used when parsing the "prefix=" FTS4 parameter. +*/ +static int fts3GobbleInt(const char **pp, int *pnOut){ + const int MAX_NPREFIX = 10000000; + int nInt = 0; /* Output value */ + int nByte; + nByte = sqlite3Fts3ReadInt(*pp, &nInt); + if( nInt>MAX_NPREFIX ){ + nInt = 0; + } + if( nByte==0 ){ + return SQLITE_ERROR; + } + *pnOut = nInt; + *pp += nByte; + return SQLITE_OK; +} + +/* +** This function is called to allocate an array of Fts3Index structures +** representing the indexes maintained by the current FTS table. FTS tables +** always maintain the main "terms" index, but may also maintain one or +** more "prefix" indexes, depending on the value of the "prefix=" parameter +** (if any) specified as part of the CREATE VIRTUAL TABLE statement. +** +** Argument zParam is passed the value of the "prefix=" option if one was +** specified, or NULL otherwise. +** +** If no error occurs, SQLITE_OK is returned and *apIndex set to point to +** the allocated array. *pnIndex is set to the number of elements in the +** array. If an error does occur, an SQLite error code is returned. +** +** Regardless of whether or not an error is returned, it is the responsibility +** of the caller to call sqlite3_free() on the output array to free it. +*/ +static int fts3PrefixParameter( + const char *zParam, /* ABC in prefix=ABC parameter to parse */ + int *pnIndex, /* OUT: size of *apIndex[] array */ + struct Fts3Index **apIndex /* OUT: Array of indexes for this table */ +){ + struct Fts3Index *aIndex; /* Allocated array */ + int nIndex = 1; /* Number of entries in array */ + + if( zParam && zParam[0] ){ + const char *p; + nIndex++; + for(p=zParam; *p; p++){ + if( *p==',' ) nIndex++; + } + } + + aIndex = sqlite3_malloc64(sizeof(struct Fts3Index) * nIndex); + *apIndex = aIndex; + if( !aIndex ){ + return SQLITE_NOMEM; + } + + memset(aIndex, 0, sizeof(struct Fts3Index) * nIndex); + if( zParam ){ + const char *p = zParam; + int i; + for(i=1; i=0 ); + if( nPrefix==0 ){ + nIndex--; + i--; + }else{ + aIndex[i].nPrefix = nPrefix; + } + p++; + } + } + + *pnIndex = nIndex; + return SQLITE_OK; +} + +/* +** This function is called when initializing an FTS4 table that uses the +** content=xxx option. It determines the number of and names of the columns +** of the new FTS4 table. +** +** The third argument passed to this function is the value passed to the +** config=xxx option (i.e. "xxx"). This function queries the database for +** a table of that name. If found, the output variables are populated +** as follows: +** +** *pnCol: Set to the number of columns table xxx has, +** +** *pnStr: Set to the total amount of space required to store a copy +** of each columns name, including the nul-terminator. +** +** *pazCol: Set to point to an array of *pnCol strings. Each string is +** the name of the corresponding column in table xxx. The array +** and its contents are allocated using a single allocation. It +** is the responsibility of the caller to free this allocation +** by eventually passing the *pazCol value to sqlite3_free(). +** +** If the table cannot be found, an error code is returned and the output +** variables are undefined. Or, if an OOM is encountered, SQLITE_NOMEM is +** returned (and the output variables are undefined). +*/ +static int fts3ContentColumns( + sqlite3 *db, /* Database handle */ + const char *zDb, /* Name of db (i.e. "main", "temp" etc.) */ + const char *zTbl, /* Name of content table */ + const char ***pazCol, /* OUT: Malloc'd array of column names */ + int *pnCol, /* OUT: Size of array *pazCol */ + int *pnStr, /* OUT: Bytes of string content */ + char **pzErr /* OUT: error message */ +){ + int rc = SQLITE_OK; /* Return code */ + char *zSql; /* "SELECT *" statement on zTbl */ + sqlite3_stmt *pStmt = 0; /* Compiled version of zSql */ + + zSql = sqlite3_mprintf("SELECT * FROM %Q.%Q", zDb, zTbl); + if( !zSql ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); + if( rc!=SQLITE_OK ){ + sqlite3Fts3ErrMsg(pzErr, "%s", sqlite3_errmsg(db)); + } + } + sqlite3_free(zSql); + + if( rc==SQLITE_OK ){ + const char **azCol; /* Output array */ + sqlite3_int64 nStr = 0; /* Size of all column names (incl. 0x00) */ + int nCol; /* Number of table columns */ + int i; /* Used to iterate through columns */ + + /* Loop through the returned columns. Set nStr to the number of bytes of + ** space required to store a copy of each column name, including the + ** nul-terminator byte. */ + nCol = sqlite3_column_count(pStmt); + for(i=0; i module name ("fts3" or "fts4") +** argv[1] -> database name +** argv[2] -> table name +** argv[...] -> "column name" and other module argument fields. +*/ +static int fts3InitVtab( + int isCreate, /* True for xCreate, false for xConnect */ + sqlite3 *db, /* The SQLite database connection */ + void *pAux, /* Hash table containing tokenizers */ + int argc, /* Number of elements in argv array */ + const char * const *argv, /* xCreate/xConnect argument array */ + sqlite3_vtab **ppVTab, /* Write the resulting vtab structure here */ + char **pzErr /* Write any error message here */ +){ + Fts3Hash *pHash = &((Fts3HashWrapper*)pAux)->hash; + Fts3Table *p = 0; /* Pointer to allocated vtab */ + int rc = SQLITE_OK; /* Return code */ + int i; /* Iterator variable */ + sqlite3_int64 nByte; /* Size of allocation used for *p */ + int iCol; /* Column index */ + int nString = 0; /* Bytes required to hold all column names */ + int nCol = 0; /* Number of columns in the FTS table */ + char *zCsr; /* Space for holding column names */ + int nDb; /* Bytes required to hold database name */ + int nName; /* Bytes required to hold table name */ + int isFts4 = (argv[0][3]=='4'); /* True for FTS4, false for FTS3 */ + const char **aCol; /* Array of column names */ + sqlite3_tokenizer *pTokenizer = 0; /* Tokenizer for this table */ + + int nIndex = 0; /* Size of aIndex[] array */ + struct Fts3Index *aIndex = 0; /* Array of indexes for this table */ + + /* The results of parsing supported FTS4 key=value options: */ + int bNoDocsize = 0; /* True to omit %_docsize table */ + int bDescIdx = 0; /* True to store descending indexes */ + char *zPrefix = 0; /* Prefix parameter value (or NULL) */ + char *zCompress = 0; /* compress=? parameter (or NULL) */ + char *zUncompress = 0; /* uncompress=? parameter (or NULL) */ + char *zContent = 0; /* content=? parameter (or NULL) */ + char *zLanguageid = 0; /* languageid=? parameter (or NULL) */ + char **azNotindexed = 0; /* The set of notindexed= columns */ + int nNotindexed = 0; /* Size of azNotindexed[] array */ + + assert( strlen(argv[0])==4 ); + assert( (sqlite3_strnicmp(argv[0], "fts4", 4)==0 && isFts4) + || (sqlite3_strnicmp(argv[0], "fts3", 4)==0 && !isFts4) + ); + + nDb = (int)strlen(argv[1]) + 1; + nName = (int)strlen(argv[2]) + 1; + + nByte = sizeof(const char *) * (argc-2); + aCol = (const char **)sqlite3_malloc64(nByte); + if( aCol ){ + memset((void*)aCol, 0, nByte); + azNotindexed = (char **)sqlite3_malloc64(nByte); + } + if( azNotindexed ){ + memset(azNotindexed, 0, nByte); + } + if( !aCol || !azNotindexed ){ + rc = SQLITE_NOMEM; + goto fts3_init_out; + } + + /* Loop through all of the arguments passed by the user to the FTS3/4 + ** module (i.e. all the column names and special arguments). This loop + ** does the following: + ** + ** + Figures out the number of columns the FTSX table will have, and + ** the number of bytes of space that must be allocated to store copies + ** of the column names. + ** + ** + If there is a tokenizer specification included in the arguments, + ** initializes the tokenizer pTokenizer. + */ + for(i=3; rc==SQLITE_OK && i8 + && 0==sqlite3_strnicmp(z, "tokenize", 8) + && 0==sqlite3Fts3IsIdChar(z[8]) + ){ + rc = sqlite3Fts3InitTokenizer(pHash, &z[9], &pTokenizer, pzErr); + } + + /* Check if it is an FTS4 special argument. */ + else if( isFts4 && fts3IsSpecialColumn(z, &nKey, &zVal) ){ + struct Fts4Option { + const char *zOpt; + int nOpt; + } aFts4Opt[] = { + { "matchinfo", 9 }, /* 0 -> MATCHINFO */ + { "prefix", 6 }, /* 1 -> PREFIX */ + { "compress", 8 }, /* 2 -> COMPRESS */ + { "uncompress", 10 }, /* 3 -> UNCOMPRESS */ + { "order", 5 }, /* 4 -> ORDER */ + { "content", 7 }, /* 5 -> CONTENT */ + { "languageid", 10 }, /* 6 -> LANGUAGEID */ + { "notindexed", 10 } /* 7 -> NOTINDEXED */ + }; + + int iOpt; + if( !zVal ){ + rc = SQLITE_NOMEM; + }else{ + for(iOpt=0; iOptnOpt && !sqlite3_strnicmp(z, pOp->zOpt, pOp->nOpt) ){ + break; + } + } + switch( iOpt ){ + case 0: /* MATCHINFO */ + if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){ + sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal); + rc = SQLITE_ERROR; + } + bNoDocsize = 1; + break; + + case 1: /* PREFIX */ + sqlite3_free(zPrefix); + zPrefix = zVal; + zVal = 0; + break; + + case 2: /* COMPRESS */ + sqlite3_free(zCompress); + zCompress = zVal; + zVal = 0; + break; + + case 3: /* UNCOMPRESS */ + sqlite3_free(zUncompress); + zUncompress = zVal; + zVal = 0; + break; + + case 4: /* ORDER */ + if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3)) + && (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4)) + ){ + sqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal); + rc = SQLITE_ERROR; + } + bDescIdx = (zVal[0]=='d' || zVal[0]=='D'); + break; + + case 5: /* CONTENT */ + sqlite3_free(zContent); + zContent = zVal; + zVal = 0; + break; + + case 6: /* LANGUAGEID */ + assert( iOpt==6 ); + sqlite3_free(zLanguageid); + zLanguageid = zVal; + zVal = 0; + break; + + case 7: /* NOTINDEXED */ + azNotindexed[nNotindexed++] = zVal; + zVal = 0; + break; + + default: + assert( iOpt==SizeofArray(aFts4Opt) ); + sqlite3Fts3ErrMsg(pzErr, "unrecognized parameter: %s", z); + rc = SQLITE_ERROR; + break; + } + sqlite3_free(zVal); + } + } + + /* Otherwise, the argument is a column name. */ + else { + nString += (int)(strlen(z) + 1); + aCol[nCol++] = z; + } + } + + /* If a content=xxx option was specified, the following: + ** + ** 1. Ignore any compress= and uncompress= options. + ** + ** 2. If no column names were specified as part of the CREATE VIRTUAL + ** TABLE statement, use all columns from the content table. + */ + if( rc==SQLITE_OK && zContent ){ + sqlite3_free(zCompress); + sqlite3_free(zUncompress); + zCompress = 0; + zUncompress = 0; + if( nCol==0 ){ + sqlite3_free((void*)aCol); + aCol = 0; + rc = fts3ContentColumns(db, argv[1], zContent,&aCol,&nCol,&nString,pzErr); + + /* If a languageid= option was specified, remove the language id + ** column from the aCol[] array. */ + if( rc==SQLITE_OK && zLanguageid ){ + int j; + for(j=0; jdb = db; + p->nColumn = nCol; + p->nPendingData = 0; + p->azColumn = (char **)&p[1]; + p->pTokenizer = pTokenizer; + p->nMaxPendingData = FTS3_MAX_PENDING_DATA; + p->bHasDocsize = (isFts4 && bNoDocsize==0); + p->bHasStat = (u8)isFts4; + p->bFts4 = (u8)isFts4; + p->bDescIdx = (u8)bDescIdx; + p->nAutoincrmerge = 0xff; /* 0xff means setting unknown */ + p->zContentTbl = zContent; + p->zLanguageid = zLanguageid; + zContent = 0; + zLanguageid = 0; + TESTONLY( p->inTransaction = -1 ); + TESTONLY( p->mxSavepoint = -1 ); + + p->aIndex = (struct Fts3Index *)&p->azColumn[nCol]; + memcpy(p->aIndex, aIndex, sizeof(struct Fts3Index) * nIndex); + p->nIndex = nIndex; + for(i=0; iaIndex[i].hPending, FTS3_HASH_STRING, 1); + } + p->abNotindexed = (u8 *)&p->aIndex[nIndex]; + + /* Fill in the zName and zDb fields of the vtab structure. */ + zCsr = (char *)&p->abNotindexed[nCol]; + p->zName = zCsr; + memcpy(zCsr, argv[2], nName); + zCsr += nName; + p->zDb = zCsr; + memcpy(zCsr, argv[1], nDb); + zCsr += nDb; + + /* Fill in the azColumn array */ + for(iCol=0; iCol0 ){ + memcpy(zCsr, z, n); + } + zCsr[n] = '\0'; + sqlite3Fts3Dequote(zCsr); + p->azColumn[iCol] = zCsr; + zCsr += n+1; + assert( zCsr <= &((char *)p)[nByte] ); + } + + /* Fill in the abNotindexed array */ + for(iCol=0; iColazColumn[iCol]); + for(i=0; iazColumn[iCol], zNot, n) + ){ + p->abNotindexed[iCol] = 1; + sqlite3_free(zNot); + azNotindexed[i] = 0; + } + } + } + for(i=0; izReadExprlist = fts3ReadExprList(p, zUncompress, &rc); + p->zWriteExprlist = fts3WriteExprList(p, zCompress, &rc); + if( rc!=SQLITE_OK ) goto fts3_init_out; + + /* If this is an xCreate call, create the underlying tables in the + ** database. TODO: For xConnect(), it could verify that said tables exist. + */ + if( isCreate ){ + rc = fts3CreateTables(p); + } + + /* Check to see if a legacy fts3 table has been "upgraded" by the + ** addition of a %_stat table so that it can use incremental merge. + */ + if( !isFts4 && !isCreate ){ + p->bHasStat = 2; + } + + /* Figure out the page-size for the database. This is required in order to + ** estimate the cost of loading large doclists from the database. */ + fts3DatabasePageSize(&rc, p); + p->nNodeSize = p->nPgsz-35; + +#if defined(SQLITE_DEBUG)||defined(SQLITE_TEST) + p->nMergeCount = FTS3_MERGE_COUNT; +#endif + + /* Declare the table schema to SQLite. */ + fts3DeclareVtab(&rc, p); + +fts3_init_out: + sqlite3_free(zPrefix); + sqlite3_free(aIndex); + sqlite3_free(zCompress); + sqlite3_free(zUncompress); + sqlite3_free(zContent); + sqlite3_free(zLanguageid); + for(i=0; ipModule->xDestroy(pTokenizer); + } + }else{ + assert( p->pSegments==0 ); + *ppVTab = &p->base; + } + return rc; +} + +/* +** The xConnect() and xCreate() methods for the virtual table. All the +** work is done in function fts3InitVtab(). +*/ +static int fts3ConnectMethod( + sqlite3 *db, /* Database connection */ + void *pAux, /* Pointer to tokenizer hash table */ + int argc, /* Number of elements in argv array */ + const char * const *argv, /* xCreate/xConnect argument array */ + sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ + char **pzErr /* OUT: sqlite3_malloc'd error message */ +){ + return fts3InitVtab(0, db, pAux, argc, argv, ppVtab, pzErr); +} +static int fts3CreateMethod( + sqlite3 *db, /* Database connection */ + void *pAux, /* Pointer to tokenizer hash table */ + int argc, /* Number of elements in argv array */ + const char * const *argv, /* xCreate/xConnect argument array */ + sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ + char **pzErr /* OUT: sqlite3_malloc'd error message */ +){ + return fts3InitVtab(1, db, pAux, argc, argv, ppVtab, pzErr); +} + +/* +** Set the pIdxInfo->estimatedRows variable to nRow. Unless this +** extension is currently being used by a version of SQLite too old to +** support estimatedRows. In that case this function is a no-op. +*/ +static void fts3SetEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){ +#if SQLITE_VERSION_NUMBER>=3008002 + if( sqlite3_libversion_number()>=3008002 ){ + pIdxInfo->estimatedRows = nRow; + } +#endif +} + +/* +** Set the SQLITE_INDEX_SCAN_UNIQUE flag in pIdxInfo->flags. Unless this +** extension is currently being used by a version of SQLite too old to +** support index-info flags. In that case this function is a no-op. +*/ +static void fts3SetUniqueFlag(sqlite3_index_info *pIdxInfo){ +#if SQLITE_VERSION_NUMBER>=3008012 + if( sqlite3_libversion_number()>=3008012 ){ + pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_UNIQUE; + } +#endif +} + +/* +** Implementation of the xBestIndex method for FTS3 tables. There +** are three possible strategies, in order of preference: +** +** 1. Direct lookup by rowid or docid. +** 2. Full-text search using a MATCH operator on a non-docid column. +** 3. Linear scan of %_content table. +*/ +static int fts3BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ + Fts3Table *p = (Fts3Table *)pVTab; + int i; /* Iterator variable */ + int iCons = -1; /* Index of constraint to use */ + + int iLangidCons = -1; /* Index of langid=x constraint, if present */ + int iDocidGe = -1; /* Index of docid>=x constraint, if present */ + int iDocidLe = -1; /* Index of docid<=x constraint, if present */ + int iIdx; + + if( p->bLock ){ + return SQLITE_ERROR; + } + + /* By default use a full table scan. This is an expensive option, + ** so search through the constraints to see if a more efficient + ** strategy is possible. + */ + pInfo->idxNum = FTS3_FULLSCAN_SEARCH; + pInfo->estimatedCost = 5000000; + for(i=0; inConstraint; i++){ + int bDocid; /* True if this constraint is on docid */ + struct sqlite3_index_constraint *pCons = &pInfo->aConstraint[i]; + if( pCons->usable==0 ){ + if( pCons->op==SQLITE_INDEX_CONSTRAINT_MATCH ){ + /* There exists an unusable MATCH constraint. This means that if + ** the planner does elect to use the results of this call as part + ** of the overall query plan the user will see an "unable to use + ** function MATCH in the requested context" error. To discourage + ** this, return a very high cost here. */ + pInfo->idxNum = FTS3_FULLSCAN_SEARCH; + pInfo->estimatedCost = 1e50; + fts3SetEstimatedRows(pInfo, ((sqlite3_int64)1) << 50); + return SQLITE_OK; + } + continue; + } + + bDocid = (pCons->iColumn<0 || pCons->iColumn==p->nColumn+1); + + /* A direct lookup on the rowid or docid column. Assign a cost of 1.0. */ + if( iCons<0 && pCons->op==SQLITE_INDEX_CONSTRAINT_EQ && bDocid ){ + pInfo->idxNum = FTS3_DOCID_SEARCH; + pInfo->estimatedCost = 1.0; + iCons = i; + } + + /* A MATCH constraint. Use a full-text search. + ** + ** If there is more than one MATCH constraint available, use the first + ** one encountered. If there is both a MATCH constraint and a direct + ** rowid/docid lookup, prefer the MATCH strategy. This is done even + ** though the rowid/docid lookup is faster than a MATCH query, selecting + ** it would lead to an "unable to use function MATCH in the requested + ** context" error. + */ + if( pCons->op==SQLITE_INDEX_CONSTRAINT_MATCH + && pCons->iColumn>=0 && pCons->iColumn<=p->nColumn + ){ + pInfo->idxNum = FTS3_FULLTEXT_SEARCH + pCons->iColumn; + pInfo->estimatedCost = 2.0; + iCons = i; + } + + /* Equality constraint on the langid column */ + if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ + && pCons->iColumn==p->nColumn + 2 + ){ + iLangidCons = i; + } + + if( bDocid ){ + switch( pCons->op ){ + case SQLITE_INDEX_CONSTRAINT_GE: + case SQLITE_INDEX_CONSTRAINT_GT: + iDocidGe = i; + break; + + case SQLITE_INDEX_CONSTRAINT_LE: + case SQLITE_INDEX_CONSTRAINT_LT: + iDocidLe = i; + break; + } + } + } + + /* If using a docid=? or rowid=? strategy, set the UNIQUE flag. */ + if( pInfo->idxNum==FTS3_DOCID_SEARCH ) fts3SetUniqueFlag(pInfo); + + iIdx = 1; + if( iCons>=0 ){ + pInfo->aConstraintUsage[iCons].argvIndex = iIdx++; + pInfo->aConstraintUsage[iCons].omit = 1; + } + if( iLangidCons>=0 ){ + pInfo->idxNum |= FTS3_HAVE_LANGID; + pInfo->aConstraintUsage[iLangidCons].argvIndex = iIdx++; + } + if( iDocidGe>=0 ){ + pInfo->idxNum |= FTS3_HAVE_DOCID_GE; + pInfo->aConstraintUsage[iDocidGe].argvIndex = iIdx++; + } + if( iDocidLe>=0 ){ + pInfo->idxNum |= FTS3_HAVE_DOCID_LE; + pInfo->aConstraintUsage[iDocidLe].argvIndex = iIdx++; + } + + /* Regardless of the strategy selected, FTS can deliver rows in rowid (or + ** docid) order. Both ascending and descending are possible. + */ + if( pInfo->nOrderBy==1 ){ + struct sqlite3_index_orderby *pOrder = &pInfo->aOrderBy[0]; + if( pOrder->iColumn<0 || pOrder->iColumn==p->nColumn+1 ){ + if( pOrder->desc ){ + pInfo->idxStr = "DESC"; + }else{ + pInfo->idxStr = "ASC"; + } + pInfo->orderByConsumed = 1; + } + } + + assert( p->pSegments==0 ); + return SQLITE_OK; +} + +/* +** Implementation of xOpen method. +*/ +static int fts3OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ + sqlite3_vtab_cursor *pCsr; /* Allocated cursor */ + + UNUSED_PARAMETER(pVTab); + + /* Allocate a buffer large enough for an Fts3Cursor structure. If the + ** allocation succeeds, zero it and return SQLITE_OK. Otherwise, + ** if the allocation fails, return SQLITE_NOMEM. + */ + *ppCsr = pCsr = (sqlite3_vtab_cursor *)sqlite3_malloc(sizeof(Fts3Cursor)); + if( !pCsr ){ + return SQLITE_NOMEM; + } + memset(pCsr, 0, sizeof(Fts3Cursor)); + return SQLITE_OK; +} + +/* +** Finalize the statement handle at pCsr->pStmt. +** +** Or, if that statement handle is one created by fts3CursorSeekStmt(), +** and the Fts3Table.pSeekStmt slot is currently NULL, save the statement +** pointer there instead of finalizing it. +*/ +static void fts3CursorFinalizeStmt(Fts3Cursor *pCsr){ + if( pCsr->bSeekStmt ){ + Fts3Table *p = (Fts3Table *)pCsr->base.pVtab; + if( p->pSeekStmt==0 ){ + p->pSeekStmt = pCsr->pStmt; + sqlite3_reset(pCsr->pStmt); + pCsr->pStmt = 0; + } + pCsr->bSeekStmt = 0; + } + sqlite3_finalize(pCsr->pStmt); +} + +/* +** Free all resources currently held by the cursor passed as the only +** argument. +*/ +static void fts3ClearCursor(Fts3Cursor *pCsr){ + fts3CursorFinalizeStmt(pCsr); + sqlite3Fts3FreeDeferredTokens(pCsr); + sqlite3_free(pCsr->aDoclist); + sqlite3Fts3MIBufferFree(pCsr->pMIBuffer); + sqlite3Fts3ExprFree(pCsr->pExpr); + memset(&(&pCsr->base)[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor)); +} + +/* +** Close the cursor. For additional information see the documentation +** on the xClose method of the virtual table interface. +*/ +static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){ + Fts3Cursor *pCsr = (Fts3Cursor *)pCursor; + assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 ); + fts3ClearCursor(pCsr); + assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 ); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +/* +** If pCsr->pStmt has not been prepared (i.e. if pCsr->pStmt==0), then +** compose and prepare an SQL statement of the form: +** +** "SELECT FROM %_content WHERE rowid = ?" +** +** (or the equivalent for a content=xxx table) and set pCsr->pStmt to +** it. If an error occurs, return an SQLite error code. +*/ +static int fts3CursorSeekStmt(Fts3Cursor *pCsr){ + int rc = SQLITE_OK; + if( pCsr->pStmt==0 ){ + Fts3Table *p = (Fts3Table *)pCsr->base.pVtab; + char *zSql; + if( p->pSeekStmt ){ + pCsr->pStmt = p->pSeekStmt; + p->pSeekStmt = 0; + }else{ + zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist); + if( !zSql ) return SQLITE_NOMEM; + p->bLock++; + rc = sqlite3Fts3PrepareStmt(p, zSql, 1, 1, &pCsr->pStmt); + p->bLock--; + sqlite3_free(zSql); + } + if( rc==SQLITE_OK ) pCsr->bSeekStmt = 1; + } + return rc; +} + +/* +** Position the pCsr->pStmt statement so that it is on the row +** of the %_content table that contains the last match. Return +** SQLITE_OK on success. +*/ +static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){ + int rc = SQLITE_OK; + if( pCsr->isRequireSeek ){ + rc = fts3CursorSeekStmt(pCsr); + if( rc==SQLITE_OK ){ + Fts3Table *pTab = (Fts3Table*)pCsr->base.pVtab; + pTab->bLock++; + sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId); + pCsr->isRequireSeek = 0; + if( SQLITE_ROW==sqlite3_step(pCsr->pStmt) ){ + pTab->bLock--; + return SQLITE_OK; + }else{ + pTab->bLock--; + rc = sqlite3_reset(pCsr->pStmt); + if( rc==SQLITE_OK && ((Fts3Table *)pCsr->base.pVtab)->zContentTbl==0 ){ + /* If no row was found and no error has occurred, then the %_content + ** table is missing a row that is present in the full-text index. + ** The data structures are corrupt. */ + rc = FTS_CORRUPT_VTAB; + pCsr->isEof = 1; + } + } + } + } + + if( rc!=SQLITE_OK && pContext ){ + sqlite3_result_error_code(pContext, rc); + } + return rc; +} + +/* +** This function is used to process a single interior node when searching +** a b-tree for a term or term prefix. The node data is passed to this +** function via the zNode/nNode parameters. The term to search for is +** passed in zTerm/nTerm. +** +** If piFirst is not NULL, then this function sets *piFirst to the blockid +** of the child node that heads the sub-tree that may contain the term. +** +** If piLast is not NULL, then *piLast is set to the right-most child node +** that heads a sub-tree that may contain a term for which zTerm/nTerm is +** a prefix. +** +** If an OOM error occurs, SQLITE_NOMEM is returned. Otherwise, SQLITE_OK. +*/ +static int fts3ScanInteriorNode( + const char *zTerm, /* Term to select leaves for */ + int nTerm, /* Size of term zTerm in bytes */ + const char *zNode, /* Buffer containing segment interior node */ + int nNode, /* Size of buffer at zNode */ + sqlite3_int64 *piFirst, /* OUT: Selected child node */ + sqlite3_int64 *piLast /* OUT: Selected child node */ +){ + int rc = SQLITE_OK; /* Return code */ + const char *zCsr = zNode; /* Cursor to iterate through node */ + const char *zEnd = &zCsr[nNode];/* End of interior node buffer */ + char *zBuffer = 0; /* Buffer to load terms into */ + i64 nAlloc = 0; /* Size of allocated buffer */ + int isFirstTerm = 1; /* True when processing first term on page */ + u64 iChild; /* Block id of child node to descend to */ + int nBuffer = 0; /* Total term size */ + + /* Skip over the 'height' varint that occurs at the start of every + ** interior node. Then load the blockid of the left-child of the b-tree + ** node into variable iChild. + ** + ** Even if the data structure on disk is corrupted, this (reading two + ** varints from the buffer) does not risk an overread. If zNode is a + ** root node, then the buffer comes from a SELECT statement. SQLite does + ** not make this guarantee explicitly, but in practice there are always + ** either more than 20 bytes of allocated space following the nNode bytes of + ** contents, or two zero bytes. Or, if the node is read from the %_segments + ** table, then there are always 20 bytes of zeroed padding following the + ** nNode bytes of content (see sqlite3Fts3ReadBlock() for details). + */ + zCsr += sqlite3Fts3GetVarintU(zCsr, &iChild); + zCsr += sqlite3Fts3GetVarintU(zCsr, &iChild); + if( zCsr>zEnd ){ + return FTS_CORRUPT_VTAB; + } + + while( zCsrnBuffer ){ + rc = FTS_CORRUPT_VTAB; + goto finish_scan; + } + } + isFirstTerm = 0; + zCsr += fts3GetVarint32(zCsr, &nSuffix); + + assert( nPrefix>=0 && nSuffix>=0 ); + if( nPrefix>zCsr-zNode || nSuffix>zEnd-zCsr || nSuffix==0 ){ + rc = FTS_CORRUPT_VTAB; + goto finish_scan; + } + if( (i64)nPrefix+nSuffix>nAlloc ){ + char *zNew; + nAlloc = ((i64)nPrefix+nSuffix) * 2; + zNew = (char *)sqlite3_realloc64(zBuffer, nAlloc); + if( !zNew ){ + rc = SQLITE_NOMEM; + goto finish_scan; + } + zBuffer = zNew; + } + assert( zBuffer ); + memcpy(&zBuffer[nPrefix], zCsr, nSuffix); + nBuffer = nPrefix + nSuffix; + zCsr += nSuffix; + + /* Compare the term we are searching for with the term just loaded from + ** the interior node. If the specified term is greater than or equal + ** to the term from the interior node, then all terms on the sub-tree + ** headed by node iChild are smaller than zTerm. No need to search + ** iChild. + ** + ** If the interior node term is larger than the specified term, then + ** the tree headed by iChild may contain the specified term. + */ + cmp = memcmp(zTerm, zBuffer, (nBuffer>nTerm ? nTerm : nBuffer)); + if( piFirst && (cmp<0 || (cmp==0 && nBuffer>nTerm)) ){ + *piFirst = (i64)iChild; + piFirst = 0; + } + + if( piLast && cmp<0 ){ + *piLast = (i64)iChild; + piLast = 0; + } + + iChild++; + }; + + if( piFirst ) *piFirst = (i64)iChild; + if( piLast ) *piLast = (i64)iChild; + + finish_scan: + sqlite3_free(zBuffer); + return rc; +} + + +/* +** The buffer pointed to by argument zNode (size nNode bytes) contains an +** interior node of a b-tree segment. The zTerm buffer (size nTerm bytes) +** contains a term. This function searches the sub-tree headed by the zNode +** node for the range of leaf nodes that may contain the specified term +** or terms for which the specified term is a prefix. +** +** If piLeaf is not NULL, then *piLeaf is set to the blockid of the +** left-most leaf node in the tree that may contain the specified term. +** If piLeaf2 is not NULL, then *piLeaf2 is set to the blockid of the +** right-most leaf node that may contain a term for which the specified +** term is a prefix. +** +** It is possible that the range of returned leaf nodes does not contain +** the specified term or any terms for which it is a prefix. However, if the +** segment does contain any such terms, they are stored within the identified +** range. Because this function only inspects interior segment nodes (and +** never loads leaf nodes into memory), it is not possible to be sure. +** +** If an error occurs, an error code other than SQLITE_OK is returned. +*/ +static int fts3SelectLeaf( + Fts3Table *p, /* Virtual table handle */ + const char *zTerm, /* Term to select leaves for */ + int nTerm, /* Size of term zTerm in bytes */ + const char *zNode, /* Buffer containing segment interior node */ + int nNode, /* Size of buffer at zNode */ + sqlite3_int64 *piLeaf, /* Selected leaf node */ + sqlite3_int64 *piLeaf2 /* Selected leaf node */ +){ + int rc = SQLITE_OK; /* Return code */ + int iHeight; /* Height of this node in tree */ + + assert( piLeaf || piLeaf2 ); + + fts3GetVarint32(zNode, &iHeight); + if( iHeight>FTS3_MAX_BTREE_HEIGHT ){ + rc = FTS_CORRUPT_VTAB; + }else{ + rc = fts3ScanInteriorNode(zTerm, nTerm, zNode, nNode, piLeaf, piLeaf2); + } + assert_fts3_nc( !piLeaf2 || !piLeaf || rc!=SQLITE_OK || (*piLeaf<=*piLeaf2) ); + + if( rc==SQLITE_OK && iHeight>1 ){ + char *zBlob = 0; /* Blob read from %_segments table */ + int nBlob = 0; /* Size of zBlob in bytes */ + + if( piLeaf && piLeaf2 && (*piLeaf!=*piLeaf2) ){ + rc = sqlite3Fts3ReadBlock(p, *piLeaf, &zBlob, &nBlob, 0); + if( rc==SQLITE_OK ){ + rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, 0); + } + sqlite3_free(zBlob); + piLeaf = 0; + zBlob = 0; + } + + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3ReadBlock(p, piLeaf?*piLeaf:*piLeaf2, &zBlob, &nBlob, 0); + } + if( rc==SQLITE_OK ){ + int iNewHeight = 0; + fts3GetVarint32(zBlob, &iNewHeight); + if( iNewHeight>=iHeight ){ + rc = FTS_CORRUPT_VTAB; + }else{ + rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, piLeaf2); + } + } + sqlite3_free(zBlob); + } + + return rc; +} + +/* +** This function is used to create delta-encoded serialized lists of FTS3 +** varints. Each call to this function appends a single varint to a list. +*/ +static void fts3PutDeltaVarint( + char **pp, /* IN/OUT: Output pointer */ + sqlite3_int64 *piPrev, /* IN/OUT: Previous value written to list */ + sqlite3_int64 iVal /* Write this value to the list */ +){ + assert_fts3_nc( iVal-*piPrev > 0 || (*piPrev==0 && iVal==0) ); + if( iVal-(*piPrev)>=0 ){ + /* Refuse to write a negative delta integer. This only happens with a + ** corrupt db (see the assert above) and can cause buffer overwrites + ** in some cases. */ + *pp += sqlite3Fts3PutVarint(*pp, iVal-*piPrev); + *piPrev = iVal; + } +} + +/* +** When this function is called, *ppPoslist is assumed to point to the +** start of a position-list. After it returns, *ppPoslist points to the +** first byte after the position-list. +** +** A position list is list of positions (delta encoded) and columns for +** a single document record of a doclist. So, in other words, this +** routine advances *ppPoslist so that it points to the next docid in +** the doclist, or to the first byte past the end of the doclist. +** +** If pp is not NULL, then the contents of the position list are copied +** to *pp. *pp is set to point to the first byte past the last byte copied +** before this function returns. +*/ +static void fts3PoslistCopy(char **pp, char **ppPoslist){ + char *pEnd = *ppPoslist; + char c = 0; + + /* The end of a position list is marked by a zero encoded as an FTS3 + ** varint. A single POS_END (0) byte. Except, if the 0 byte is preceded by + ** a byte with the 0x80 bit set, then it is not a varint 0, but the tail + ** of some other, multi-byte, value. + ** + ** The following while-loop moves pEnd to point to the first byte that is not + ** immediately preceded by a byte with the 0x80 bit set. Then increments + ** pEnd once more so that it points to the byte immediately following the + ** last byte in the position-list. + */ + while( *pEnd | c ){ + c = *pEnd++ & 0x80; + testcase( c!=0 && (*pEnd)==0 ); + } + pEnd++; /* Advance past the POS_END terminator byte */ + + if( pp ){ + int n = (int)(pEnd - *ppPoslist); + char *p = *pp; + memcpy(p, *ppPoslist, n); + p += n; + *pp = p; + } + *ppPoslist = pEnd; +} + +/* +** When this function is called, *ppPoslist is assumed to point to the +** start of a column-list. After it returns, *ppPoslist points to the +** to the terminator (POS_COLUMN or POS_END) byte of the column-list. +** +** A column-list is list of delta-encoded positions for a single column +** within a single document within a doclist. +** +** The column-list is terminated either by a POS_COLUMN varint (1) or +** a POS_END varint (0). This routine leaves *ppPoslist pointing to +** the POS_COLUMN or POS_END that terminates the column-list. +** +** If pp is not NULL, then the contents of the column-list are copied +** to *pp. *pp is set to point to the first byte past the last byte copied +** before this function returns. The POS_COLUMN or POS_END terminator +** is not copied into *pp. +*/ +static void fts3ColumnlistCopy(char **pp, char **ppPoslist){ + char *pEnd = *ppPoslist; + char c = 0; + + /* A column-list is terminated by either a 0x01 or 0x00 byte that is + ** not part of a multi-byte varint. + */ + while( 0xFE & (*pEnd | c) ){ + c = *pEnd++ & 0x80; + testcase( c!=0 && ((*pEnd)&0xfe)==0 ); + } + if( pp ){ + int n = (int)(pEnd - *ppPoslist); + char *p = *pp; + memcpy(p, *ppPoslist, n); + p += n; + *pp = p; + } + *ppPoslist = pEnd; +} + +/* +** Value used to signify the end of an position-list. This must be +** as large or larger than any value that might appear on the +** position-list, even a position list that has been corrupted. +*/ +#define POSITION_LIST_END LARGEST_INT64 + +/* +** This function is used to help parse position-lists. When this function is +** called, *pp may point to the start of the next varint in the position-list +** being parsed, or it may point to 1 byte past the end of the position-list +** (in which case **pp will be a terminator bytes POS_END (0) or +** (1)). +** +** If *pp points past the end of the current position-list, set *pi to +** POSITION_LIST_END and return. Otherwise, read the next varint from *pp, +** increment the current value of *pi by the value read, and set *pp to +** point to the next value before returning. +** +** Before calling this routine *pi must be initialized to the value of +** the previous position, or zero if we are reading the first position +** in the position-list. Because positions are delta-encoded, the value +** of the previous position is needed in order to compute the value of +** the next position. +*/ +static void fts3ReadNextPos( + char **pp, /* IN/OUT: Pointer into position-list buffer */ + sqlite3_int64 *pi /* IN/OUT: Value read from position-list */ +){ + if( (**pp)&0xFE ){ + int iVal; + *pp += fts3GetVarint32((*pp), &iVal); + *pi += iVal; + *pi -= 2; + }else{ + *pi = POSITION_LIST_END; + } +} + +/* +** If parameter iCol is not 0, write an POS_COLUMN (1) byte followed by +** the value of iCol encoded as a varint to *pp. This will start a new +** column list. +** +** Set *pp to point to the byte just after the last byte written before +** returning (do not modify it if iCol==0). Return the total number of bytes +** written (0 if iCol==0). +*/ +static int fts3PutColNumber(char **pp, int iCol){ + int n = 0; /* Number of bytes written */ + if( iCol ){ + char *p = *pp; /* Output pointer */ + n = 1 + sqlite3Fts3PutVarint(&p[1], iCol); + *p = 0x01; + *pp = &p[n]; + } + return n; +} + +/* +** Compute the union of two position lists. The output written +** into *pp contains all positions of both *pp1 and *pp2 in sorted +** order and with any duplicates removed. All pointers are +** updated appropriately. The caller is responsible for insuring +** that there is enough space in *pp to hold the complete output. +*/ +static int fts3PoslistMerge( + char **pp, /* Output buffer */ + char **pp1, /* Left input list */ + char **pp2 /* Right input list */ +){ + char *p = *pp; + char *p1 = *pp1; + char *p2 = *pp2; + + while( *p1 || *p2 ){ + int iCol1; /* The current column index in pp1 */ + int iCol2; /* The current column index in pp2 */ + + if( *p1==POS_COLUMN ){ + fts3GetVarint32(&p1[1], &iCol1); + if( iCol1==0 ) return FTS_CORRUPT_VTAB; + } + else if( *p1==POS_END ) iCol1 = 0x7fffffff; + else iCol1 = 0; + + if( *p2==POS_COLUMN ){ + fts3GetVarint32(&p2[1], &iCol2); + if( iCol2==0 ) return FTS_CORRUPT_VTAB; + } + else if( *p2==POS_END ) iCol2 = 0x7fffffff; + else iCol2 = 0; + + if( iCol1==iCol2 ){ + sqlite3_int64 i1 = 0; /* Last position from pp1 */ + sqlite3_int64 i2 = 0; /* Last position from pp2 */ + sqlite3_int64 iPrev = 0; + int n = fts3PutColNumber(&p, iCol1); + p1 += n; + p2 += n; + + /* At this point, both p1 and p2 point to the start of column-lists + ** for the same column (the column with index iCol1 and iCol2). + ** A column-list is a list of non-negative delta-encoded varints, each + ** incremented by 2 before being stored. Each list is terminated by a + ** POS_END (0) or POS_COLUMN (1). The following block merges the two lists + ** and writes the results to buffer p. p is left pointing to the byte + ** after the list written. No terminator (POS_END or POS_COLUMN) is + ** written to the output. + */ + fts3GetDeltaVarint(&p1, &i1); + fts3GetDeltaVarint(&p2, &i2); + if( i1<2 || i2<2 ){ + break; + } + do { + fts3PutDeltaVarint(&p, &iPrev, (i1pos(*pp1) && pos(*pp2)-pos(*pp1)<=nToken). i.e. +** when the *pp1 token appears before the *pp2 token, but not more than nToken +** slots before it. +** +** e.g. nToken==1 searches for adjacent positions. +*/ +static int fts3PoslistPhraseMerge( + char **pp, /* IN/OUT: Preallocated output buffer */ + int nToken, /* Maximum difference in token positions */ + int isSaveLeft, /* Save the left position */ + int isExact, /* If *pp1 is exactly nTokens before *pp2 */ + char **pp1, /* IN/OUT: Left input list */ + char **pp2 /* IN/OUT: Right input list */ +){ + char *p = *pp; + char *p1 = *pp1; + char *p2 = *pp2; + int iCol1 = 0; + int iCol2 = 0; + + /* Never set both isSaveLeft and isExact for the same invocation. */ + assert( isSaveLeft==0 || isExact==0 ); + + assert_fts3_nc( p!=0 && *p1!=0 && *p2!=0 ); + if( *p1==POS_COLUMN ){ + p1++; + p1 += fts3GetVarint32(p1, &iCol1); + /* iCol1==0 indicates corruption. Column 0 does not have a POS_COLUMN + ** entry, so this is actually end-of-doclist. */ + if( iCol1==0 ) return 0; + } + if( *p2==POS_COLUMN ){ + p2++; + p2 += fts3GetVarint32(p2, &iCol2); + /* As above, iCol2==0 indicates corruption. */ + if( iCol2==0 ) return 0; + } + + while( 1 ){ + if( iCol1==iCol2 ){ + char *pSave = p; + sqlite3_int64 iPrev = 0; + sqlite3_int64 iPos1 = 0; + sqlite3_int64 iPos2 = 0; + + if( iCol1 ){ + *p++ = POS_COLUMN; + p += sqlite3Fts3PutVarint(p, iCol1); + } + + fts3GetDeltaVarint(&p1, &iPos1); iPos1 -= 2; + fts3GetDeltaVarint(&p2, &iPos2); iPos2 -= 2; + if( iPos1<0 || iPos2<0 ) break; + + while( 1 ){ + if( iPos2==iPos1+nToken + || (isExact==0 && iPos2>iPos1 && iPos2<=iPos1+nToken) + ){ + sqlite3_int64 iSave; + iSave = isSaveLeft ? iPos1 : iPos2; + fts3PutDeltaVarint(&p, &iPrev, iSave+2); iPrev -= 2; + pSave = 0; + assert( p ); + } + if( (!isSaveLeft && iPos2<=(iPos1+nToken)) || iPos2<=iPos1 ){ + if( (*p2&0xFE)==0 ) break; + fts3GetDeltaVarint(&p2, &iPos2); iPos2 -= 2; + }else{ + if( (*p1&0xFE)==0 ) break; + fts3GetDeltaVarint(&p1, &iPos1); iPos1 -= 2; + } + } + + if( pSave ){ + assert( pp && p ); + p = pSave; + } + + fts3ColumnlistCopy(0, &p1); + fts3ColumnlistCopy(0, &p2); + assert( (*p1&0xFE)==0 && (*p2&0xFE)==0 ); + if( 0==*p1 || 0==*p2 ) break; + + p1++; + p1 += fts3GetVarint32(p1, &iCol1); + p2++; + p2 += fts3GetVarint32(p2, &iCol2); + } + + /* Advance pointer p1 or p2 (whichever corresponds to the smaller of + ** iCol1 and iCol2) so that it points to either the 0x00 that marks the + ** end of the position list, or the 0x01 that precedes the next + ** column-number in the position list. + */ + else if( iCol1=pEnd ){ + *pp = 0; + }else{ + u64 iVal; + *pp += sqlite3Fts3GetVarintU(*pp, &iVal); + if( bDescIdx ){ + *pVal = (i64)((u64)*pVal - iVal); + }else{ + *pVal = (i64)((u64)*pVal + iVal); + } + } +} + +/* +** This function is used to write a single varint to a buffer. The varint +** is written to *pp. Before returning, *pp is set to point 1 byte past the +** end of the value written. +** +** If *pbFirst is zero when this function is called, the value written to +** the buffer is that of parameter iVal. +** +** If *pbFirst is non-zero when this function is called, then the value +** written is either (iVal-*piPrev) (if bDescIdx is zero) or (*piPrev-iVal) +** (if bDescIdx is non-zero). +** +** Before returning, this function always sets *pbFirst to 1 and *piPrev +** to the value of parameter iVal. +*/ +static void fts3PutDeltaVarint3( + char **pp, /* IN/OUT: Output pointer */ + int bDescIdx, /* True for descending docids */ + sqlite3_int64 *piPrev, /* IN/OUT: Previous value written to list */ + int *pbFirst, /* IN/OUT: True after first int written */ + sqlite3_int64 iVal /* Write this value to the list */ +){ + sqlite3_uint64 iWrite; + if( bDescIdx==0 || *pbFirst==0 ){ + assert_fts3_nc( *pbFirst==0 || iVal>=*piPrev ); + iWrite = (u64)iVal - (u64)*piPrev; + }else{ + assert_fts3_nc( *piPrev>=iVal ); + iWrite = (u64)*piPrev - (u64)iVal; + } + assert( *pbFirst || *piPrev==0 ); + assert_fts3_nc( *pbFirst==0 || iWrite>0 ); + *pp += sqlite3Fts3PutVarint(*pp, iWrite); + *piPrev = iVal; + *pbFirst = 1; +} + + +/* +** This macro is used by various functions that merge doclists. The two +** arguments are 64-bit docid values. If the value of the stack variable +** bDescDoclist is 0 when this macro is invoked, then it returns (i1-i2). +** Otherwise, (i2-i1). +** +** Using this makes it easier to write code that can merge doclists that are +** sorted in either ascending or descending order. +*/ +/* #define DOCID_CMP(i1, i2) ((bDescDoclist?-1:1) * (i64)((u64)i1-i2)) */ +#define DOCID_CMP(i1, i2) ((bDescDoclist?-1:1) * (i1>i2?1:((i1==i2)?0:-1))) + +/* +** This function does an "OR" merge of two doclists (output contains all +** positions contained in either argument doclist). If the docids in the +** input doclists are sorted in ascending order, parameter bDescDoclist +** should be false. If they are sorted in ascending order, it should be +** passed a non-zero value. +** +** If no error occurs, *paOut is set to point at an sqlite3_malloc'd buffer +** containing the output doclist and SQLITE_OK is returned. In this case +** *pnOut is set to the number of bytes in the output doclist. +** +** If an error occurs, an SQLite error code is returned. The output values +** are undefined in this case. +*/ +static int fts3DoclistOrMerge( + int bDescDoclist, /* True if arguments are desc */ + char *a1, int n1, /* First doclist */ + char *a2, int n2, /* Second doclist */ + char **paOut, int *pnOut /* OUT: Malloc'd doclist */ +){ + int rc = SQLITE_OK; + sqlite3_int64 i1 = 0; + sqlite3_int64 i2 = 0; + sqlite3_int64 iPrev = 0; + char *pEnd1 = &a1[n1]; + char *pEnd2 = &a2[n2]; + char *p1 = a1; + char *p2 = a2; + char *p; + char *aOut; + int bFirstOut = 0; + + *paOut = 0; + *pnOut = 0; + + /* Allocate space for the output. Both the input and output doclists + ** are delta encoded. If they are in ascending order (bDescDoclist==0), + ** then the first docid in each list is simply encoded as a varint. For + ** each subsequent docid, the varint stored is the difference between the + ** current and previous docid (a positive number - since the list is in + ** ascending order). + ** + ** The first docid written to the output is therefore encoded using the + ** same number of bytes as it is in whichever of the input lists it is + ** read from. And each subsequent docid read from the same input list + ** consumes either the same or less bytes as it did in the input (since + ** the difference between it and the previous value in the output must + ** be a positive value less than or equal to the delta value read from + ** the input list). The same argument applies to all but the first docid + ** read from the 'other' list. And to the contents of all position lists + ** that will be copied and merged from the input to the output. + ** + ** However, if the first docid copied to the output is a negative number, + ** then the encoding of the first docid from the 'other' input list may + ** be larger in the output than it was in the input (since the delta value + ** may be a larger positive integer than the actual docid). + ** + ** The space required to store the output is therefore the sum of the + ** sizes of the two inputs, plus enough space for exactly one of the input + ** docids to grow. + ** + ** A symmetric argument may be made if the doclists are in descending + ** order. + */ + aOut = sqlite3_malloc64((i64)n1+n2+FTS3_VARINT_MAX-1+FTS3_BUFFER_PADDING); + if( !aOut ) return SQLITE_NOMEM; + + p = aOut; + fts3GetDeltaVarint3(&p1, pEnd1, 0, &i1); + fts3GetDeltaVarint3(&p2, pEnd2, 0, &i2); + while( p1 || p2 ){ + sqlite3_int64 iDiff = DOCID_CMP(i1, i2); + + if( p2 && p1 && iDiff==0 ){ + fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i1); + rc = fts3PoslistMerge(&p, &p1, &p2); + if( rc ) break; + fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1); + fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2); + }else if( !p2 || (p1 && iDiff<0) ){ + fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i1); + fts3PoslistCopy(&p, &p1); + fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1); + }else{ + fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i2); + fts3PoslistCopy(&p, &p2); + fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2); + } + + assert( (p-aOut)<=((p1?(p1-a1):n1)+(p2?(p2-a2):n2)+FTS3_VARINT_MAX-1) ); + } + + if( rc!=SQLITE_OK ){ + sqlite3_free(aOut); + p = aOut = 0; + }else{ + assert( (p-aOut)<=n1+n2+FTS3_VARINT_MAX-1 ); + memset(&aOut[(p-aOut)], 0, FTS3_BUFFER_PADDING); + } + *paOut = aOut; + *pnOut = (int)(p-aOut); + return rc; +} + +/* +** This function does a "phrase" merge of two doclists. In a phrase merge, +** the output contains a copy of each position from the right-hand input +** doclist for which there is a position in the left-hand input doclist +** exactly nDist tokens before it. +** +** If the docids in the input doclists are sorted in ascending order, +** parameter bDescDoclist should be false. If they are sorted in ascending +** order, it should be passed a non-zero value. +** +** The right-hand input doclist is overwritten by this function. +*/ +static int fts3DoclistPhraseMerge( + int bDescDoclist, /* True if arguments are desc */ + int nDist, /* Distance from left to right (1=adjacent) */ + char *aLeft, int nLeft, /* Left doclist */ + char **paRight, int *pnRight /* IN/OUT: Right/output doclist */ +){ + sqlite3_int64 i1 = 0; + sqlite3_int64 i2 = 0; + sqlite3_int64 iPrev = 0; + char *aRight = *paRight; + char *pEnd1 = &aLeft[nLeft]; + char *pEnd2 = &aRight[*pnRight]; + char *p1 = aLeft; + char *p2 = aRight; + char *p; + int bFirstOut = 0; + char *aOut; + + assert( nDist>0 ); + if( bDescDoclist ){ + aOut = sqlite3_malloc64((sqlite3_int64)*pnRight + FTS3_VARINT_MAX); + if( aOut==0 ) return SQLITE_NOMEM; + }else{ + aOut = aRight; + } + p = aOut; + + fts3GetDeltaVarint3(&p1, pEnd1, 0, &i1); + fts3GetDeltaVarint3(&p2, pEnd2, 0, &i2); + + while( p1 && p2 ){ + sqlite3_int64 iDiff = DOCID_CMP(i1, i2); + if( iDiff==0 ){ + char *pSave = p; + sqlite3_int64 iPrevSave = iPrev; + int bFirstOutSave = bFirstOut; + + fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i1); + if( 0==fts3PoslistPhraseMerge(&p, nDist, 0, 1, &p1, &p2) ){ + p = pSave; + iPrev = iPrevSave; + bFirstOut = bFirstOutSave; + } + fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1); + fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2); + }else if( iDiff<0 ){ + fts3PoslistCopy(0, &p1); + fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1); + }else{ + fts3PoslistCopy(0, &p2); + fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2); + } + } + + *pnRight = (int)(p - aOut); + if( bDescDoclist ){ + sqlite3_free(aRight); + *paRight = aOut; + } + + return SQLITE_OK; +} + +/* +** Argument pList points to a position list nList bytes in size. This +** function checks to see if the position list contains any entries for +** a token in position 0 (of any column). If so, it writes argument iDelta +** to the output buffer pOut, followed by a position list consisting only +** of the entries from pList at position 0, and terminated by an 0x00 byte. +** The value returned is the number of bytes written to pOut (if any). +*/ +SQLITE_PRIVATE int sqlite3Fts3FirstFilter( + sqlite3_int64 iDelta, /* Varint that may be written to pOut */ + char *pList, /* Position list (no 0x00 term) */ + int nList, /* Size of pList in bytes */ + char *pOut /* Write output here */ +){ + int nOut = 0; + int bWritten = 0; /* True once iDelta has been written */ + char *p = pList; + char *pEnd = &pList[nList]; + + if( *p!=0x01 ){ + if( *p==0x02 ){ + nOut += sqlite3Fts3PutVarint(&pOut[nOut], iDelta); + pOut[nOut++] = 0x02; + bWritten = 1; + } + fts3ColumnlistCopy(0, &p); + } + + while( paaOutput); i++){ + if( pTS->aaOutput[i] ){ + if( !aOut ){ + aOut = pTS->aaOutput[i]; + nOut = pTS->anOutput[i]; + pTS->aaOutput[i] = 0; + }else{ + int nNew; + char *aNew; + + int rc = fts3DoclistOrMerge(p->bDescIdx, + pTS->aaOutput[i], pTS->anOutput[i], aOut, nOut, &aNew, &nNew + ); + if( rc!=SQLITE_OK ){ + sqlite3_free(aOut); + return rc; + } + + sqlite3_free(pTS->aaOutput[i]); + sqlite3_free(aOut); + pTS->aaOutput[i] = 0; + aOut = aNew; + nOut = nNew; + } + } + } + + pTS->aaOutput[0] = aOut; + pTS->anOutput[0] = nOut; + return SQLITE_OK; +} + +/* +** Merge the doclist aDoclist/nDoclist into the TermSelect object passed +** as the first argument. The merge is an "OR" merge (see function +** fts3DoclistOrMerge() for details). +** +** This function is called with the doclist for each term that matches +** a queried prefix. It merges all these doclists into one, the doclist +** for the specified prefix. Since there can be a very large number of +** doclists to merge, the merging is done pair-wise using the TermSelect +** object. +** +** This function returns SQLITE_OK if the merge is successful, or an +** SQLite error code (SQLITE_NOMEM) if an error occurs. +*/ +static int fts3TermSelectMerge( + Fts3Table *p, /* FTS table handle */ + TermSelect *pTS, /* TermSelect object to merge into */ + char *aDoclist, /* Pointer to doclist */ + int nDoclist /* Size of aDoclist in bytes */ +){ + if( pTS->aaOutput[0]==0 ){ + /* If this is the first term selected, copy the doclist to the output + ** buffer using memcpy(). + ** + ** Add FTS3_VARINT_MAX bytes of unused space to the end of the + ** allocation. This is so as to ensure that the buffer is big enough + ** to hold the current doclist AND'd with any other doclist. If the + ** doclists are stored in order=ASC order, this padding would not be + ** required (since the size of [doclistA AND doclistB] is always less + ** than or equal to the size of [doclistA] in that case). But this is + ** not true for order=DESC. For example, a doclist containing (1, -1) + ** may be smaller than (-1), as in the first example the -1 may be stored + ** as a single-byte delta, whereas in the second it must be stored as a + ** FTS3_VARINT_MAX byte varint. + ** + ** Similar padding is added in the fts3DoclistOrMerge() function. + */ + pTS->aaOutput[0] = sqlite3_malloc64((i64)nDoclist + FTS3_VARINT_MAX + 1); + pTS->anOutput[0] = nDoclist; + if( pTS->aaOutput[0] ){ + memcpy(pTS->aaOutput[0], aDoclist, nDoclist); + memset(&pTS->aaOutput[0][nDoclist], 0, FTS3_VARINT_MAX); + }else{ + return SQLITE_NOMEM; + } + }else{ + char *aMerge = aDoclist; + int nMerge = nDoclist; + int iOut; + + for(iOut=0; iOutaaOutput); iOut++){ + if( pTS->aaOutput[iOut]==0 ){ + assert( iOut>0 ); + pTS->aaOutput[iOut] = aMerge; + pTS->anOutput[iOut] = nMerge; + break; + }else{ + char *aNew; + int nNew; + + int rc = fts3DoclistOrMerge(p->bDescIdx, aMerge, nMerge, + pTS->aaOutput[iOut], pTS->anOutput[iOut], &aNew, &nNew + ); + if( rc!=SQLITE_OK ){ + if( aMerge!=aDoclist ) sqlite3_free(aMerge); + return rc; + } + + if( aMerge!=aDoclist ) sqlite3_free(aMerge); + sqlite3_free(pTS->aaOutput[iOut]); + pTS->aaOutput[iOut] = 0; + + aMerge = aNew; + nMerge = nNew; + if( (iOut+1)==SizeofArray(pTS->aaOutput) ){ + pTS->aaOutput[iOut] = aMerge; + pTS->anOutput[iOut] = nMerge; + } + } + } + } + return SQLITE_OK; +} + +/* +** Append SegReader object pNew to the end of the pCsr->apSegment[] array. +*/ +static int fts3SegReaderCursorAppend( + Fts3MultiSegReader *pCsr, + Fts3SegReader *pNew +){ + if( (pCsr->nSegment%16)==0 ){ + Fts3SegReader **apNew; + sqlite3_int64 nByte = (pCsr->nSegment + 16)*sizeof(Fts3SegReader*); + apNew = (Fts3SegReader **)sqlite3_realloc64(pCsr->apSegment, nByte); + if( !apNew ){ + sqlite3Fts3SegReaderFree(pNew); + return SQLITE_NOMEM; + } + pCsr->apSegment = apNew; + } + pCsr->apSegment[pCsr->nSegment++] = pNew; + return SQLITE_OK; +} + +/* +** Add seg-reader objects to the Fts3MultiSegReader object passed as the +** 8th argument. +** +** This function returns SQLITE_OK if successful, or an SQLite error code +** otherwise. +*/ +static int fts3SegReaderCursor( + Fts3Table *p, /* FTS3 table handle */ + int iLangid, /* Language id */ + int iIndex, /* Index to search (from 0 to p->nIndex-1) */ + int iLevel, /* Level of segments to scan */ + const char *zTerm, /* Term to query for */ + int nTerm, /* Size of zTerm in bytes */ + int isPrefix, /* True for a prefix search */ + int isScan, /* True to scan from zTerm to EOF */ + Fts3MultiSegReader *pCsr /* Cursor object to populate */ +){ + int rc = SQLITE_OK; /* Error code */ + sqlite3_stmt *pStmt = 0; /* Statement to iterate through segments */ + int rc2; /* Result of sqlite3_reset() */ + + /* If iLevel is less than 0 and this is not a scan, include a seg-reader + ** for the pending-terms. If this is a scan, then this call must be being + ** made by an fts4aux module, not an FTS table. In this case calling + ** Fts3SegReaderPending might segfault, as the data structures used by + ** fts4aux are not completely populated. So it's easiest to filter these + ** calls out here. */ + if( iLevel<0 && p->aIndex && p->iPrevLangid==iLangid ){ + Fts3SegReader *pSeg = 0; + rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix||isScan, &pSeg); + if( rc==SQLITE_OK && pSeg ){ + rc = fts3SegReaderCursorAppend(pCsr, pSeg); + } + } + + if( iLevel!=FTS3_SEGCURSOR_PENDING ){ + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3AllSegdirs(p, iLangid, iIndex, iLevel, &pStmt); + } + + while( rc==SQLITE_OK && SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){ + Fts3SegReader *pSeg = 0; + + /* Read the values returned by the SELECT into local variables. */ + sqlite3_int64 iStartBlock = sqlite3_column_int64(pStmt, 1); + sqlite3_int64 iLeavesEndBlock = sqlite3_column_int64(pStmt, 2); + sqlite3_int64 iEndBlock = sqlite3_column_int64(pStmt, 3); + int nRoot = sqlite3_column_bytes(pStmt, 4); + char const *zRoot = sqlite3_column_blob(pStmt, 4); + + /* If zTerm is not NULL, and this segment is not stored entirely on its + ** root node, the range of leaves scanned can be reduced. Do this. */ + if( iStartBlock && zTerm && zRoot ){ + sqlite3_int64 *pi = (isPrefix ? &iLeavesEndBlock : 0); + rc = fts3SelectLeaf(p, zTerm, nTerm, zRoot, nRoot, &iStartBlock, pi); + if( rc!=SQLITE_OK ) goto finished; + if( isPrefix==0 && isScan==0 ) iLeavesEndBlock = iStartBlock; + } + + rc = sqlite3Fts3SegReaderNew(pCsr->nSegment+1, + (isPrefix==0 && isScan==0), + iStartBlock, iLeavesEndBlock, + iEndBlock, zRoot, nRoot, &pSeg + ); + if( rc!=SQLITE_OK ) goto finished; + rc = fts3SegReaderCursorAppend(pCsr, pSeg); + } + } + + finished: + rc2 = sqlite3_reset(pStmt); + if( rc==SQLITE_DONE ) rc = rc2; + + return rc; +} + +/* +** Set up a cursor object for iterating through a full-text index or a +** single level therein. +*/ +SQLITE_PRIVATE int sqlite3Fts3SegReaderCursor( + Fts3Table *p, /* FTS3 table handle */ + int iLangid, /* Language-id to search */ + int iIndex, /* Index to search (from 0 to p->nIndex-1) */ + int iLevel, /* Level of segments to scan */ + const char *zTerm, /* Term to query for */ + int nTerm, /* Size of zTerm in bytes */ + int isPrefix, /* True for a prefix search */ + int isScan, /* True to scan from zTerm to EOF */ + Fts3MultiSegReader *pCsr /* Cursor object to populate */ +){ + assert( iIndex>=0 && iIndexnIndex ); + assert( iLevel==FTS3_SEGCURSOR_ALL + || iLevel==FTS3_SEGCURSOR_PENDING + || iLevel>=0 + ); + assert( iLevelbase.pVtab; + + if( isPrefix ){ + for(i=1; bFound==0 && inIndex; i++){ + if( p->aIndex[i].nPrefix==nTerm ){ + bFound = 1; + rc = sqlite3Fts3SegReaderCursor(p, pCsr->iLangid, + i, FTS3_SEGCURSOR_ALL, zTerm, nTerm, 0, 0, pSegcsr + ); + pSegcsr->bLookup = 1; + } + } + + for(i=1; bFound==0 && inIndex; i++){ + if( p->aIndex[i].nPrefix==nTerm+1 ){ + bFound = 1; + rc = sqlite3Fts3SegReaderCursor(p, pCsr->iLangid, + i, FTS3_SEGCURSOR_ALL, zTerm, nTerm, 1, 0, pSegcsr + ); + if( rc==SQLITE_OK ){ + rc = fts3SegReaderCursorAddZero( + p, pCsr->iLangid, zTerm, nTerm, pSegcsr + ); + } + } + } + } + + if( bFound==0 ){ + rc = sqlite3Fts3SegReaderCursor(p, pCsr->iLangid, + 0, FTS3_SEGCURSOR_ALL, zTerm, nTerm, isPrefix, 0, pSegcsr + ); + pSegcsr->bLookup = !isPrefix; + } + } + + *ppSegcsr = pSegcsr; + return rc; +} + +/* +** Free an Fts3MultiSegReader allocated by fts3TermSegReaderCursor(). +*/ +static void fts3SegReaderCursorFree(Fts3MultiSegReader *pSegcsr){ + sqlite3Fts3SegReaderFinish(pSegcsr); + sqlite3_free(pSegcsr); +} + +/* +** This function retrieves the doclist for the specified term (or term +** prefix) from the database. +*/ +static int fts3TermSelect( + Fts3Table *p, /* Virtual table handle */ + Fts3PhraseToken *pTok, /* Token to query for */ + int iColumn, /* Column to query (or -ve for all columns) */ + int *pnOut, /* OUT: Size of buffer at *ppOut */ + char **ppOut /* OUT: Malloced result buffer */ +){ + int rc; /* Return code */ + Fts3MultiSegReader *pSegcsr; /* Seg-reader cursor for this term */ + TermSelect tsc; /* Object for pair-wise doclist merging */ + Fts3SegFilter filter; /* Segment term filter configuration */ + + pSegcsr = pTok->pSegcsr; + memset(&tsc, 0, sizeof(TermSelect)); + + filter.flags = FTS3_SEGMENT_IGNORE_EMPTY | FTS3_SEGMENT_REQUIRE_POS + | (pTok->isPrefix ? FTS3_SEGMENT_PREFIX : 0) + | (pTok->bFirst ? FTS3_SEGMENT_FIRST : 0) + | (iColumnnColumn ? FTS3_SEGMENT_COLUMN_FILTER : 0); + filter.iCol = iColumn; + filter.zTerm = pTok->z; + filter.nTerm = pTok->n; + + rc = sqlite3Fts3SegReaderStart(p, pSegcsr, &filter); + while( SQLITE_OK==rc + && SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, pSegcsr)) + ){ + rc = fts3TermSelectMerge(p, &tsc, pSegcsr->aDoclist, pSegcsr->nDoclist); + } + + if( rc==SQLITE_OK ){ + rc = fts3TermSelectFinishMerge(p, &tsc); + } + if( rc==SQLITE_OK ){ + *ppOut = tsc.aaOutput[0]; + *pnOut = tsc.anOutput[0]; + }else{ + int i; + for(i=0; ipSegcsr = 0; + return rc; +} + +/* +** This function counts the total number of docids in the doclist stored +** in buffer aList[], size nList bytes. +** +** If the isPoslist argument is true, then it is assumed that the doclist +** contains a position-list following each docid. Otherwise, it is assumed +** that the doclist is simply a list of docids stored as delta encoded +** varints. +*/ +static int fts3DoclistCountDocids(char *aList, int nList){ + int nDoc = 0; /* Return value */ + if( aList ){ + char *aEnd = &aList[nList]; /* Pointer to one byte after EOF */ + char *p = aList; /* Cursor */ + while( peSearch==FTS3_DOCID_SEARCH || pCsr->eSearch==FTS3_FULLSCAN_SEARCH ){ + Fts3Table *pTab = (Fts3Table*)pCursor->pVtab; + pTab->bLock++; + if( SQLITE_ROW!=sqlite3_step(pCsr->pStmt) ){ + pCsr->isEof = 1; + rc = sqlite3_reset(pCsr->pStmt); + }else{ + pCsr->iPrevId = sqlite3_column_int64(pCsr->pStmt, 0); + rc = SQLITE_OK; + } + pTab->bLock--; + }else{ + rc = fts3EvalNext((Fts3Cursor *)pCursor); + } + assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 ); + return rc; +} + +/* +** If the numeric type of argument pVal is "integer", then return it +** converted to a 64-bit signed integer. Otherwise, return a copy of +** the second parameter, iDefault. +*/ +static sqlite3_int64 fts3DocidRange(sqlite3_value *pVal, i64 iDefault){ + if( pVal ){ + int eType = sqlite3_value_numeric_type(pVal); + if( eType==SQLITE_INTEGER ){ + return sqlite3_value_int64(pVal); + } + } + return iDefault; +} + +/* +** This is the xFilter interface for the virtual table. See +** the virtual table xFilter method documentation for additional +** information. +** +** If idxNum==FTS3_FULLSCAN_SEARCH then do a full table scan against +** the %_content table. +** +** If idxNum==FTS3_DOCID_SEARCH then do a docid lookup for a single entry +** in the %_content table. +** +** If idxNum>=FTS3_FULLTEXT_SEARCH then use the full text index. The +** column on the left-hand side of the MATCH operator is column +** number idxNum-FTS3_FULLTEXT_SEARCH, 0 indexed. argv[0] is the right-hand +** side of the MATCH operator. +*/ +static int fts3FilterMethod( + sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ + int idxNum, /* Strategy index */ + const char *idxStr, /* Unused */ + int nVal, /* Number of elements in apVal */ + sqlite3_value **apVal /* Arguments for the indexing scheme */ +){ + int rc = SQLITE_OK; + char *zSql; /* SQL statement used to access %_content */ + int eSearch; + Fts3Table *p = (Fts3Table *)pCursor->pVtab; + Fts3Cursor *pCsr = (Fts3Cursor *)pCursor; + + sqlite3_value *pCons = 0; /* The MATCH or rowid constraint, if any */ + sqlite3_value *pLangid = 0; /* The "langid = ?" constraint, if any */ + sqlite3_value *pDocidGe = 0; /* The "docid >= ?" constraint, if any */ + sqlite3_value *pDocidLe = 0; /* The "docid <= ?" constraint, if any */ + int iIdx; + + UNUSED_PARAMETER(idxStr); + UNUSED_PARAMETER(nVal); + + if( p->bLock ){ + return SQLITE_ERROR; + } + + eSearch = (idxNum & 0x0000FFFF); + assert( eSearch>=0 && eSearch<=(FTS3_FULLTEXT_SEARCH+p->nColumn) ); + assert( p->pSegments==0 ); + + /* Collect arguments into local variables */ + iIdx = 0; + if( eSearch!=FTS3_FULLSCAN_SEARCH ) pCons = apVal[iIdx++]; + if( idxNum & FTS3_HAVE_LANGID ) pLangid = apVal[iIdx++]; + if( idxNum & FTS3_HAVE_DOCID_GE ) pDocidGe = apVal[iIdx++]; + if( idxNum & FTS3_HAVE_DOCID_LE ) pDocidLe = apVal[iIdx++]; + assert( iIdx==nVal ); + + /* In case the cursor has been used before, clear it now. */ + fts3ClearCursor(pCsr); + + /* Set the lower and upper bounds on docids to return */ + pCsr->iMinDocid = fts3DocidRange(pDocidGe, SMALLEST_INT64); + pCsr->iMaxDocid = fts3DocidRange(pDocidLe, LARGEST_INT64); + + if( idxStr ){ + pCsr->bDesc = (idxStr[0]=='D'); + }else{ + pCsr->bDesc = p->bDescIdx; + } + pCsr->eSearch = (i16)eSearch; + + if( eSearch!=FTS3_DOCID_SEARCH && eSearch!=FTS3_FULLSCAN_SEARCH ){ + int iCol = eSearch-FTS3_FULLTEXT_SEARCH; + const char *zQuery = (const char *)sqlite3_value_text(pCons); + + if( zQuery==0 && sqlite3_value_type(pCons)!=SQLITE_NULL ){ + return SQLITE_NOMEM; + } + + pCsr->iLangid = 0; + if( pLangid ) pCsr->iLangid = sqlite3_value_int(pLangid); + + assert( p->base.zErrMsg==0 ); + rc = sqlite3Fts3ExprParse(p->pTokenizer, pCsr->iLangid, + p->azColumn, p->bFts4, p->nColumn, iCol, zQuery, -1, &pCsr->pExpr, + &p->base.zErrMsg + ); + if( rc!=SQLITE_OK ){ + return rc; + } + + rc = fts3EvalStart(pCsr); + sqlite3Fts3SegmentsClose(p); + if( rc!=SQLITE_OK ) return rc; + pCsr->pNextId = pCsr->aDoclist; + pCsr->iPrevId = 0; + } + + /* Compile a SELECT statement for this cursor. For a full-table-scan, the + ** statement loops through all rows of the %_content table. For a + ** full-text query or docid lookup, the statement retrieves a single + ** row by docid. + */ + if( eSearch==FTS3_FULLSCAN_SEARCH ){ + if( pDocidGe || pDocidLe ){ + zSql = sqlite3_mprintf( + "SELECT %s WHERE rowid BETWEEN %lld AND %lld ORDER BY rowid %s", + p->zReadExprlist, pCsr->iMinDocid, pCsr->iMaxDocid, + (pCsr->bDesc ? "DESC" : "ASC") + ); + }else{ + zSql = sqlite3_mprintf("SELECT %s ORDER BY rowid %s", + p->zReadExprlist, (pCsr->bDesc ? "DESC" : "ASC") + ); + } + if( zSql ){ + p->bLock++; + rc = sqlite3Fts3PrepareStmt(p, zSql, 1, 1, &pCsr->pStmt); + p->bLock--; + sqlite3_free(zSql); + }else{ + rc = SQLITE_NOMEM; + } + }else if( eSearch==FTS3_DOCID_SEARCH ){ + rc = fts3CursorSeekStmt(pCsr); + if( rc==SQLITE_OK ){ + rc = sqlite3_bind_value(pCsr->pStmt, 1, pCons); + } + } + if( rc!=SQLITE_OK ) return rc; + + return fts3NextMethod(pCursor); +} + +/* +** This is the xEof method of the virtual table. SQLite calls this +** routine to find out if it has reached the end of a result set. +*/ +static int fts3EofMethod(sqlite3_vtab_cursor *pCursor){ + Fts3Cursor *pCsr = (Fts3Cursor*)pCursor; + if( pCsr->isEof ){ + fts3ClearCursor(pCsr); + pCsr->isEof = 1; + } + return pCsr->isEof; +} + +/* +** This is the xRowid method. The SQLite core calls this routine to +** retrieve the rowid for the current row of the result set. fts3 +** exposes %_content.docid as the rowid for the virtual table. The +** rowid should be written to *pRowid. +*/ +static int fts3RowidMethod(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ + Fts3Cursor *pCsr = (Fts3Cursor *) pCursor; + *pRowid = pCsr->iPrevId; + return SQLITE_OK; +} + +/* +** This is the xColumn method, called by SQLite to request a value from +** the row that the supplied cursor currently points to. +** +** If: +** +** (iCol < p->nColumn) -> The value of the iCol'th user column. +** (iCol == p->nColumn) -> Magic column with the same name as the table. +** (iCol == p->nColumn+1) -> Docid column +** (iCol == p->nColumn+2) -> Langid column +*/ +static int fts3ColumnMethod( + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ + sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */ + int iCol /* Index of column to read value from */ +){ + int rc = SQLITE_OK; /* Return Code */ + Fts3Cursor *pCsr = (Fts3Cursor *) pCursor; + Fts3Table *p = (Fts3Table *)pCursor->pVtab; + + /* The column value supplied by SQLite must be in range. */ + assert( iCol>=0 && iCol<=p->nColumn+2 ); + + switch( iCol-p->nColumn ){ + case 0: + /* The special 'table-name' column */ + sqlite3_result_pointer(pCtx, pCsr, "fts3cursor", 0); + break; + + case 1: + /* The docid column */ + sqlite3_result_int64(pCtx, pCsr->iPrevId); + break; + + case 2: + if( pCsr->pExpr ){ + sqlite3_result_int64(pCtx, pCsr->iLangid); + break; + }else if( p->zLanguageid==0 ){ + sqlite3_result_int(pCtx, 0); + break; + }else{ + iCol = p->nColumn; + /* no break */ deliberate_fall_through + } + + default: + /* A user column. Or, if this is a full-table scan, possibly the + ** language-id column. Seek the cursor. */ + rc = fts3CursorSeek(0, pCsr); + if( rc==SQLITE_OK && sqlite3_data_count(pCsr->pStmt)-1>iCol ){ + sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1)); + } + break; + } + + assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 ); + return rc; +} + +/* +** This function is the implementation of the xUpdate callback used by +** FTS3 virtual tables. It is invoked by SQLite each time a row is to be +** inserted, updated or deleted. +*/ +static int fts3UpdateMethod( + sqlite3_vtab *pVtab, /* Virtual table handle */ + int nArg, /* Size of argument array */ + sqlite3_value **apVal, /* Array of arguments */ + sqlite_int64 *pRowid /* OUT: The affected (or effected) rowid */ +){ + return sqlite3Fts3UpdateMethod(pVtab, nArg, apVal, pRowid); +} + +/* +** Implementation of xSync() method. Flush the contents of the pending-terms +** hash-table to the database. +*/ +static int fts3SyncMethod(sqlite3_vtab *pVtab){ + + /* Following an incremental-merge operation, assuming that the input + ** segments are not completely consumed (the usual case), they are updated + ** in place to remove the entries that have already been merged. This + ** involves updating the leaf block that contains the smallest unmerged + ** entry and each block (if any) between the leaf and the root node. So + ** if the height of the input segment b-trees is N, and input segments + ** are merged eight at a time, updating the input segments at the end + ** of an incremental-merge requires writing (8*(1+N)) blocks. N is usually + ** small - often between 0 and 2. So the overhead of the incremental + ** merge is somewhere between 8 and 24 blocks. To avoid this overhead + ** dwarfing the actual productive work accomplished, the incremental merge + ** is only attempted if it will write at least 64 leaf blocks. Hence + ** nMinMerge. + ** + ** Of course, updating the input segments also involves deleting a bunch + ** of blocks from the segments table. But this is not considered overhead + ** as it would also be required by a crisis-merge that used the same input + ** segments. + */ + const u32 nMinMerge = 64; /* Minimum amount of incr-merge work to do */ + + Fts3Table *p = (Fts3Table*)pVtab; + int rc; + i64 iLastRowid = sqlite3_last_insert_rowid(p->db); + + rc = sqlite3Fts3PendingTermsFlush(p); + if( rc==SQLITE_OK + && p->nLeafAdd>(nMinMerge/16) + && p->nAutoincrmerge && p->nAutoincrmerge!=0xff + ){ + int mxLevel = 0; /* Maximum relative level value in db */ + int A; /* Incr-merge parameter A */ + + rc = sqlite3Fts3MaxLevel(p, &mxLevel); + assert( rc==SQLITE_OK || mxLevel==0 ); + A = p->nLeafAdd * mxLevel; + A += (A/2); + if( A>(int)nMinMerge ) rc = sqlite3Fts3Incrmerge(p, A, p->nAutoincrmerge); + } + sqlite3Fts3SegmentsClose(p); + sqlite3_set_last_insert_rowid(p->db, iLastRowid); + return rc; +} + +/* +** If it is currently unknown whether or not the FTS table has an %_stat +** table (if p->bHasStat==2), attempt to determine this (set p->bHasStat +** to 0 or 1). Return SQLITE_OK if successful, or an SQLite error code +** if an error occurs. +*/ +static int fts3SetHasStat(Fts3Table *p){ + int rc = SQLITE_OK; + if( p->bHasStat==2 ){ + char *zTbl = sqlite3_mprintf("%s_stat", p->zName); + if( zTbl ){ + int res = sqlite3_table_column_metadata(p->db, p->zDb, zTbl, 0,0,0,0,0,0); + sqlite3_free(zTbl); + p->bHasStat = (res==SQLITE_OK); + }else{ + rc = SQLITE_NOMEM; + } + } + return rc; +} + +/* +** Implementation of xBegin() method. +*/ +static int fts3BeginMethod(sqlite3_vtab *pVtab){ + Fts3Table *p = (Fts3Table*)pVtab; + int rc; + UNUSED_PARAMETER(pVtab); + assert( p->pSegments==0 ); + assert( p->nPendingData==0 ); + assert( p->inTransaction!=1 ); + p->nLeafAdd = 0; + rc = fts3SetHasStat(p); +#ifdef SQLITE_DEBUG + if( rc==SQLITE_OK ){ + p->inTransaction = 1; + p->mxSavepoint = -1; + } +#endif + return rc; +} + +/* +** Implementation of xCommit() method. This is a no-op. The contents of +** the pending-terms hash-table have already been flushed into the database +** by fts3SyncMethod(). +*/ +static int fts3CommitMethod(sqlite3_vtab *pVtab){ + TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); + UNUSED_PARAMETER(pVtab); + assert( p->nPendingData==0 ); + assert( p->inTransaction!=0 ); + assert( p->pSegments==0 ); + TESTONLY( p->inTransaction = 0 ); + TESTONLY( p->mxSavepoint = -1; ); + return SQLITE_OK; +} + +/* +** Implementation of xRollback(). Discard the contents of the pending-terms +** hash-table. Any changes made to the database are reverted by SQLite. +*/ +static int fts3RollbackMethod(sqlite3_vtab *pVtab){ + Fts3Table *p = (Fts3Table*)pVtab; + sqlite3Fts3PendingTermsClear(p); + assert( p->inTransaction!=0 ); + TESTONLY( p->inTransaction = 0 ); + TESTONLY( p->mxSavepoint = -1; ); + return SQLITE_OK; +} + +/* +** When called, *ppPoslist must point to the byte immediately following the +** end of a position-list. i.e. ( (*ppPoslist)[-1]==POS_END ). This function +** moves *ppPoslist so that it instead points to the first byte of the +** same position list. +*/ +static void fts3ReversePoslist(char *pStart, char **ppPoslist){ + char *p = &(*ppPoslist)[-2]; + char c = 0; + + /* Skip backwards passed any trailing 0x00 bytes added by NearTrim() */ + while( p>pStart && (c=*p--)==0 ); + + /* Search backwards for a varint with value zero (the end of the previous + ** poslist). This is an 0x00 byte preceded by some byte that does not + ** have the 0x80 bit set. */ + while( p>pStart && (*p & 0x80) | c ){ + c = *p--; + } + assert( p==pStart || c==0 ); + + /* At this point p points to that preceding byte without the 0x80 bit + ** set. So to find the start of the poslist, skip forward 2 bytes then + ** over a varint. + ** + ** Normally. The other case is that p==pStart and the poslist to return + ** is the first in the doclist. In this case do not skip forward 2 bytes. + ** The second part of the if condition (c==0 && *ppPoslist>&p[2]) + ** is required for cases where the first byte of a doclist and the + ** doclist is empty. For example, if the first docid is 10, a doclist + ** that begins with: + ** + ** 0x0A 0x00 + */ + if( p>pStart || (c==0 && *ppPoslist>&p[2]) ){ p = &p[2]; } + while( *p++&0x80 ); + *ppPoslist = p; +} + +/* +** Helper function used by the implementation of the overloaded snippet(), +** offsets() and optimize() SQL functions. +** +** If the value passed as the third argument is a blob of size +** sizeof(Fts3Cursor*), then the blob contents are copied to the +** output variable *ppCsr and SQLITE_OK is returned. Otherwise, an error +** message is written to context pContext and SQLITE_ERROR returned. The +** string passed via zFunc is used as part of the error message. +*/ +static int fts3FunctionArg( + sqlite3_context *pContext, /* SQL function call context */ + const char *zFunc, /* Function name */ + sqlite3_value *pVal, /* argv[0] passed to function */ + Fts3Cursor **ppCsr /* OUT: Store cursor handle here */ +){ + int rc; + *ppCsr = (Fts3Cursor*)sqlite3_value_pointer(pVal, "fts3cursor"); + if( (*ppCsr)!=0 ){ + rc = SQLITE_OK; + }else{ + char *zErr = sqlite3_mprintf("illegal first argument to %s", zFunc); + sqlite3_result_error(pContext, zErr, -1); + sqlite3_free(zErr); + rc = SQLITE_ERROR; + } + return rc; +} + +/* +** Implementation of the snippet() function for FTS3 +*/ +static void fts3SnippetFunc( + sqlite3_context *pContext, /* SQLite function call context */ + int nVal, /* Size of apVal[] array */ + sqlite3_value **apVal /* Array of arguments */ +){ + Fts3Cursor *pCsr; /* Cursor handle passed through apVal[0] */ + const char *zStart = ""; + const char *zEnd = ""; + const char *zEllipsis = "..."; + int iCol = -1; + int nToken = 15; /* Default number of tokens in snippet */ + + /* There must be at least one argument passed to this function (otherwise + ** the non-overloaded version would have been called instead of this one). + */ + assert( nVal>=1 ); + + if( nVal>6 ){ + sqlite3_result_error(pContext, + "wrong number of arguments to function snippet()", -1); + return; + } + if( fts3FunctionArg(pContext, "snippet", apVal[0], &pCsr) ) return; + + switch( nVal ){ + case 6: nToken = sqlite3_value_int(apVal[5]); + /* no break */ deliberate_fall_through + case 5: iCol = sqlite3_value_int(apVal[4]); + /* no break */ deliberate_fall_through + case 4: zEllipsis = (const char*)sqlite3_value_text(apVal[3]); + /* no break */ deliberate_fall_through + case 3: zEnd = (const char*)sqlite3_value_text(apVal[2]); + /* no break */ deliberate_fall_through + case 2: zStart = (const char*)sqlite3_value_text(apVal[1]); + } + if( !zEllipsis || !zEnd || !zStart ){ + sqlite3_result_error_nomem(pContext); + }else if( nToken==0 ){ + sqlite3_result_text(pContext, "", -1, SQLITE_STATIC); + }else if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){ + sqlite3Fts3Snippet(pContext, pCsr, zStart, zEnd, zEllipsis, iCol, nToken); + } +} + +/* +** Implementation of the offsets() function for FTS3 +*/ +static void fts3OffsetsFunc( + sqlite3_context *pContext, /* SQLite function call context */ + int nVal, /* Size of argument array */ + sqlite3_value **apVal /* Array of arguments */ +){ + Fts3Cursor *pCsr; /* Cursor handle passed through apVal[0] */ + + UNUSED_PARAMETER(nVal); + + assert( nVal==1 ); + if( fts3FunctionArg(pContext, "offsets", apVal[0], &pCsr) ) return; + assert( pCsr ); + if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){ + sqlite3Fts3Offsets(pContext, pCsr); + } +} + +/* +** Implementation of the special optimize() function for FTS3. This +** function merges all segments in the database to a single segment. +** Example usage is: +** +** SELECT optimize(t) FROM t LIMIT 1; +** +** where 't' is the name of an FTS3 table. +*/ +static void fts3OptimizeFunc( + sqlite3_context *pContext, /* SQLite function call context */ + int nVal, /* Size of argument array */ + sqlite3_value **apVal /* Array of arguments */ +){ + int rc; /* Return code */ + Fts3Table *p; /* Virtual table handle */ + Fts3Cursor *pCursor; /* Cursor handle passed through apVal[0] */ + + UNUSED_PARAMETER(nVal); + + assert( nVal==1 ); + if( fts3FunctionArg(pContext, "optimize", apVal[0], &pCursor) ) return; + p = (Fts3Table *)pCursor->base.pVtab; + assert( p ); + + rc = sqlite3Fts3Optimize(p); + + switch( rc ){ + case SQLITE_OK: + sqlite3_result_text(pContext, "Index optimized", -1, SQLITE_STATIC); + break; + case SQLITE_DONE: + sqlite3_result_text(pContext, "Index already optimal", -1, SQLITE_STATIC); + break; + default: + sqlite3_result_error_code(pContext, rc); + break; + } +} + +/* +** Implementation of the matchinfo() function for FTS3 +*/ +static void fts3MatchinfoFunc( + sqlite3_context *pContext, /* SQLite function call context */ + int nVal, /* Size of argument array */ + sqlite3_value **apVal /* Array of arguments */ +){ + Fts3Cursor *pCsr; /* Cursor handle passed through apVal[0] */ + assert( nVal==1 || nVal==2 ); + if( SQLITE_OK==fts3FunctionArg(pContext, "matchinfo", apVal[0], &pCsr) ){ + const char *zArg = 0; + if( nVal>1 ){ + zArg = (const char *)sqlite3_value_text(apVal[1]); + } + sqlite3Fts3Matchinfo(pContext, pCsr, zArg); + } +} + +/* +** This routine implements the xFindFunction method for the FTS3 +** virtual table. +*/ +static int fts3FindFunctionMethod( + sqlite3_vtab *pVtab, /* Virtual table handle */ + int nArg, /* Number of SQL function arguments */ + const char *zName, /* Name of SQL function */ + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */ + void **ppArg /* Unused */ +){ + struct Overloaded { + const char *zName; + void (*xFunc)(sqlite3_context*,int,sqlite3_value**); + } aOverload[] = { + { "snippet", fts3SnippetFunc }, + { "offsets", fts3OffsetsFunc }, + { "optimize", fts3OptimizeFunc }, + { "matchinfo", fts3MatchinfoFunc }, + }; + int i; /* Iterator variable */ + + UNUSED_PARAMETER(pVtab); + UNUSED_PARAMETER(nArg); + UNUSED_PARAMETER(ppArg); + + for(i=0; idb; /* Database connection */ + int rc; /* Return Code */ + + /* At this point it must be known if the %_stat table exists or not. + ** So bHasStat may not be 2. */ + rc = fts3SetHasStat(p); + + /* As it happens, the pending terms table is always empty here. This is + ** because an "ALTER TABLE RENAME TABLE" statement inside a transaction + ** always opens a savepoint transaction. And the xSavepoint() method + ** flushes the pending terms table. But leave the (no-op) call to + ** PendingTermsFlush() in in case that changes. + */ + assert( p->nPendingData==0 ); + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3PendingTermsFlush(p); + } + + p->bIgnoreSavepoint = 1; + + if( p->zContentTbl==0 ){ + fts3DbExec(&rc, db, + "ALTER TABLE %Q.'%q_content' RENAME TO '%q_content';", + p->zDb, p->zName, zName + ); + } + + if( p->bHasDocsize ){ + fts3DbExec(&rc, db, + "ALTER TABLE %Q.'%q_docsize' RENAME TO '%q_docsize';", + p->zDb, p->zName, zName + ); + } + if( p->bHasStat ){ + fts3DbExec(&rc, db, + "ALTER TABLE %Q.'%q_stat' RENAME TO '%q_stat';", + p->zDb, p->zName, zName + ); + } + fts3DbExec(&rc, db, + "ALTER TABLE %Q.'%q_segments' RENAME TO '%q_segments';", + p->zDb, p->zName, zName + ); + fts3DbExec(&rc, db, + "ALTER TABLE %Q.'%q_segdir' RENAME TO '%q_segdir';", + p->zDb, p->zName, zName + ); + + p->bIgnoreSavepoint = 0; + return rc; +} + +/* +** The xSavepoint() method. +** +** Flush the contents of the pending-terms table to disk. +*/ +static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ + int rc = SQLITE_OK; + Fts3Table *pTab = (Fts3Table*)pVtab; + assert( pTab->inTransaction ); + assert( pTab->mxSavepoint<=iSavepoint ); + TESTONLY( pTab->mxSavepoint = iSavepoint ); + + if( pTab->bIgnoreSavepoint==0 ){ + if( fts3HashCount(&pTab->aIndex[0].hPending)>0 ){ + char *zSql = sqlite3_mprintf("INSERT INTO %Q.%Q(%Q) VALUES('flush')", + pTab->zDb, pTab->zName, pTab->zName + ); + if( zSql ){ + pTab->bIgnoreSavepoint = 1; + rc = sqlite3_exec(pTab->db, zSql, 0, 0, 0); + pTab->bIgnoreSavepoint = 0; + sqlite3_free(zSql); + }else{ + rc = SQLITE_NOMEM; + } + } + if( rc==SQLITE_OK ){ + pTab->iSavepoint = iSavepoint+1; + } + } + return rc; +} + +/* +** The xRelease() method. +** +** This is a no-op. +*/ +static int fts3ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ + Fts3Table *pTab = (Fts3Table*)pVtab; + assert( pTab->inTransaction ); + assert( pTab->mxSavepoint >= iSavepoint ); + TESTONLY( pTab->mxSavepoint = iSavepoint-1 ); + pTab->iSavepoint = iSavepoint; + return SQLITE_OK; +} + +/* +** The xRollbackTo() method. +** +** Discard the contents of the pending terms table. +*/ +static int fts3RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ + Fts3Table *pTab = (Fts3Table*)pVtab; + UNUSED_PARAMETER(iSavepoint); + assert( pTab->inTransaction ); + TESTONLY( pTab->mxSavepoint = iSavepoint ); + if( (iSavepoint+1)<=pTab->iSavepoint ){ + sqlite3Fts3PendingTermsClear(pTab); + } + return SQLITE_OK; +} + +/* +** Return true if zName is the extension on one of the shadow tables used +** by this module. +*/ +static int fts3ShadowName(const char *zName){ + static const char *azName[] = { + "content", "docsize", "segdir", "segments", "stat", + }; + unsigned int i; + for(i=0; izErrMsg==0 || rc!=SQLITE_OK ); + assert( rc!=SQLITE_CORRUPT_VTAB ); + if( rc==SQLITE_ERROR || (rc&0xFF)==SQLITE_CORRUPT ){ + *pzErr = sqlite3_mprintf("unable to validate the inverted index for" + " FTS%d table %s.%s: %s", + p->bFts4 ? 4 : 3, zSchema, zTabname, sqlite3_errstr(rc)); + if( *pzErr ) rc = SQLITE_OK; + }else if( rc==SQLITE_OK && bOk==0 ){ + *pzErr = sqlite3_mprintf("malformed inverted index for FTS%d table %s.%s", + p->bFts4 ? 4 : 3, zSchema, zTabname); + if( *pzErr==0 ) rc = SQLITE_NOMEM; + } + sqlite3Fts3SegmentsClose(p); + return rc; +} + + + +static const sqlite3_module fts3Module = { + /* iVersion */ 4, + /* xCreate */ fts3CreateMethod, + /* xConnect */ fts3ConnectMethod, + /* xBestIndex */ fts3BestIndexMethod, + /* xDisconnect */ fts3DisconnectMethod, + /* xDestroy */ fts3DestroyMethod, + /* xOpen */ fts3OpenMethod, + /* xClose */ fts3CloseMethod, + /* xFilter */ fts3FilterMethod, + /* xNext */ fts3NextMethod, + /* xEof */ fts3EofMethod, + /* xColumn */ fts3ColumnMethod, + /* xRowid */ fts3RowidMethod, + /* xUpdate */ fts3UpdateMethod, + /* xBegin */ fts3BeginMethod, + /* xSync */ fts3SyncMethod, + /* xCommit */ fts3CommitMethod, + /* xRollback */ fts3RollbackMethod, + /* xFindFunction */ fts3FindFunctionMethod, + /* xRename */ fts3RenameMethod, + /* xSavepoint */ fts3SavepointMethod, + /* xRelease */ fts3ReleaseMethod, + /* xRollbackTo */ fts3RollbackToMethod, + /* xShadowName */ fts3ShadowName, + /* xIntegrity */ fts3IntegrityMethod, +}; + +/* +** This function is registered as the module destructor (called when an +** FTS3 enabled database connection is closed). It frees the memory +** allocated for the tokenizer hash table. +*/ +static void hashDestroy(void *p){ + Fts3HashWrapper *pHash = (Fts3HashWrapper *)p; + pHash->nRef--; + if( pHash->nRef<=0 ){ + sqlite3Fts3HashClear(&pHash->hash); + sqlite3_free(pHash); + } +} + +/* +** The fts3 built-in tokenizers - "simple", "porter" and "icu"- are +** implemented in files fts3_tokenizer1.c, fts3_porter.c and fts3_icu.c +** respectively. The following three forward declarations are for functions +** declared in these files used to retrieve the respective implementations. +** +** Calling sqlite3Fts3SimpleTokenizerModule() sets the value pointed +** to by the argument to point to the "simple" tokenizer implementation. +** And so on. +*/ +SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule); +SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule); +#ifndef SQLITE_DISABLE_FTS3_UNICODE +SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const**ppModule); +#endif +#ifdef SQLITE_ENABLE_ICU +SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule); +#endif + +/* +** Initialize the fts3 extension. If this extension is built as part +** of the sqlite library, then this function is called directly by +** SQLite. If fts3 is built as a dynamically loadable extension, this +** function is called by the sqlite3_extension_init() entry point. +*/ +SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){ + int rc = SQLITE_OK; + Fts3HashWrapper *pHash = 0; + const sqlite3_tokenizer_module *pSimple = 0; + const sqlite3_tokenizer_module *pPorter = 0; +#ifndef SQLITE_DISABLE_FTS3_UNICODE + const sqlite3_tokenizer_module *pUnicode = 0; +#endif + +#ifdef SQLITE_ENABLE_ICU + const sqlite3_tokenizer_module *pIcu = 0; + sqlite3Fts3IcuTokenizerModule(&pIcu); +#endif + +#ifndef SQLITE_DISABLE_FTS3_UNICODE + sqlite3Fts3UnicodeTokenizer(&pUnicode); +#endif + +#ifdef SQLITE_TEST + rc = sqlite3Fts3InitTerm(db); + if( rc!=SQLITE_OK ) return rc; +#endif + + rc = sqlite3Fts3InitAux(db); + if( rc!=SQLITE_OK ) return rc; + + sqlite3Fts3SimpleTokenizerModule(&pSimple); + sqlite3Fts3PorterTokenizerModule(&pPorter); + + /* Allocate and initialize the hash-table used to store tokenizers. */ + pHash = sqlite3_malloc(sizeof(Fts3HashWrapper)); + if( !pHash ){ + rc = SQLITE_NOMEM; + }else{ + sqlite3Fts3HashInit(&pHash->hash, FTS3_HASH_STRING, 1); + pHash->nRef = 0; + } + + /* Load the built-in tokenizers into the hash table */ + if( rc==SQLITE_OK ){ + if( sqlite3Fts3HashInsert(&pHash->hash, "simple", 7, (void *)pSimple) + || sqlite3Fts3HashInsert(&pHash->hash, "porter", 7, (void *)pPorter) + +#ifndef SQLITE_DISABLE_FTS3_UNICODE + || sqlite3Fts3HashInsert(&pHash->hash, "unicode61", 10, (void *)pUnicode) +#endif +#ifdef SQLITE_ENABLE_ICU + || (pIcu && sqlite3Fts3HashInsert(&pHash->hash, "icu", 4, (void *)pIcu)) +#endif + ){ + rc = SQLITE_NOMEM; + } + } + +#ifdef SQLITE_TEST + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3ExprInitTestInterface(db, &pHash->hash); + } +#endif + + /* Create the virtual table wrapper around the hash-table and overload + ** the four scalar functions. If this is successful, register the + ** module with sqlite. + */ + if( SQLITE_OK==rc + && SQLITE_OK==(rc=sqlite3Fts3InitHashTable(db,&pHash->hash,"fts3_tokenizer")) + && SQLITE_OK==(rc = sqlite3_overload_function(db, "snippet", -1)) + && SQLITE_OK==(rc = sqlite3_overload_function(db, "offsets", 1)) + && SQLITE_OK==(rc = sqlite3_overload_function(db, "matchinfo", 1)) + && SQLITE_OK==(rc = sqlite3_overload_function(db, "matchinfo", 2)) + && SQLITE_OK==(rc = sqlite3_overload_function(db, "optimize", 1)) + ){ + pHash->nRef++; + rc = sqlite3_create_module_v2( + db, "fts3", &fts3Module, (void *)pHash, hashDestroy + ); + if( rc==SQLITE_OK ){ + pHash->nRef++; + rc = sqlite3_create_module_v2( + db, "fts4", &fts3Module, (void *)pHash, hashDestroy + ); + } + if( rc==SQLITE_OK ){ + pHash->nRef++; + rc = sqlite3Fts3InitTok(db, (void *)pHash, hashDestroy); + } + return rc; + } + + + /* An error has occurred. Delete the hash table and return the error code. */ + assert( rc!=SQLITE_OK ); + if( pHash ){ + sqlite3Fts3HashClear(&pHash->hash); + sqlite3_free(pHash); + } + return rc; +} + +/* +** Allocate an Fts3MultiSegReader for each token in the expression headed +** by pExpr. +** +** An Fts3SegReader object is a cursor that can seek or scan a range of +** entries within a single segment b-tree. An Fts3MultiSegReader uses multiple +** Fts3SegReader objects internally to provide an interface to seek or scan +** within the union of all segments of a b-tree. Hence the name. +** +** If the allocated Fts3MultiSegReader just seeks to a single entry in a +** segment b-tree (if the term is not a prefix or it is a prefix for which +** there exists prefix b-tree of the right length) then it may be traversed +** and merged incrementally. Otherwise, it has to be merged into an in-memory +** doclist and then traversed. +*/ +static void fts3EvalAllocateReaders( + Fts3Cursor *pCsr, /* FTS cursor handle */ + Fts3Expr *pExpr, /* Allocate readers for this expression */ + int *pnToken, /* OUT: Total number of tokens in phrase. */ + int *pnOr, /* OUT: Total number of OR nodes in expr. */ + int *pRc /* IN/OUT: Error code */ +){ + if( pExpr && SQLITE_OK==*pRc ){ + if( pExpr->eType==FTSQUERY_PHRASE ){ + int i; + int nToken = pExpr->pPhrase->nToken; + *pnToken += nToken; + for(i=0; ipPhrase->aToken[i]; + int rc = fts3TermSegReaderCursor(pCsr, + pToken->z, pToken->n, pToken->isPrefix, &pToken->pSegcsr + ); + if( rc!=SQLITE_OK ){ + *pRc = rc; + return; + } + } + assert( pExpr->pPhrase->iDoclistToken==0 ); + pExpr->pPhrase->iDoclistToken = -1; + }else{ + *pnOr += (pExpr->eType==FTSQUERY_OR); + fts3EvalAllocateReaders(pCsr, pExpr->pLeft, pnToken, pnOr, pRc); + fts3EvalAllocateReaders(pCsr, pExpr->pRight, pnToken, pnOr, pRc); + } + } +} + +/* +** Arguments pList/nList contain the doclist for token iToken of phrase p. +** It is merged into the main doclist stored in p->doclist.aAll/nAll. +** +** This function assumes that pList points to a buffer allocated using +** sqlite3_malloc(). This function takes responsibility for eventually +** freeing the buffer. +** +** SQLITE_OK is returned if successful, or SQLITE_NOMEM if an error occurs. +*/ +static int fts3EvalPhraseMergeToken( + Fts3Table *pTab, /* FTS Table pointer */ + Fts3Phrase *p, /* Phrase to merge pList/nList into */ + int iToken, /* Token pList/nList corresponds to */ + char *pList, /* Pointer to doclist */ + int nList /* Number of bytes in pList */ +){ + int rc = SQLITE_OK; + assert( iToken!=p->iDoclistToken ); + + if( pList==0 ){ + sqlite3_free(p->doclist.aAll); + p->doclist.aAll = 0; + p->doclist.nAll = 0; + } + + else if( p->iDoclistToken<0 ){ + p->doclist.aAll = pList; + p->doclist.nAll = nList; + } + + else if( p->doclist.aAll==0 ){ + sqlite3_free(pList); + } + + else { + char *pLeft; + char *pRight; + int nLeft; + int nRight; + int nDiff; + + if( p->iDoclistTokendoclist.aAll; + nLeft = p->doclist.nAll; + pRight = pList; + nRight = nList; + nDiff = iToken - p->iDoclistToken; + }else{ + pRight = p->doclist.aAll; + nRight = p->doclist.nAll; + pLeft = pList; + nLeft = nList; + nDiff = p->iDoclistToken - iToken; + } + + rc = fts3DoclistPhraseMerge( + pTab->bDescIdx, nDiff, pLeft, nLeft, &pRight, &nRight + ); + sqlite3_free(pLeft); + p->doclist.aAll = pRight; + p->doclist.nAll = nRight; + } + + if( iToken>p->iDoclistToken ) p->iDoclistToken = iToken; + return rc; +} + +/* +** Load the doclist for phrase p into p->doclist.aAll/nAll. The loaded doclist +** does not take deferred tokens into account. +** +** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code. +*/ +static int fts3EvalPhraseLoad( + Fts3Cursor *pCsr, /* FTS Cursor handle */ + Fts3Phrase *p /* Phrase object */ +){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int iToken; + int rc = SQLITE_OK; + + for(iToken=0; rc==SQLITE_OK && iTokennToken; iToken++){ + Fts3PhraseToken *pToken = &p->aToken[iToken]; + assert( pToken->pDeferred==0 || pToken->pSegcsr==0 ); + + if( pToken->pSegcsr ){ + int nThis = 0; + char *pThis = 0; + rc = fts3TermSelect(pTab, pToken, p->iColumn, &nThis, &pThis); + if( rc==SQLITE_OK ){ + rc = fts3EvalPhraseMergeToken(pTab, p, iToken, pThis, nThis); + } + } + assert( pToken->pSegcsr==0 ); + } + + return rc; +} + +#ifndef SQLITE_DISABLE_FTS4_DEFERRED +/* +** This function is called on each phrase after the position lists for +** any deferred tokens have been loaded into memory. It updates the phrases +** current position list to include only those positions that are really +** instances of the phrase (after considering deferred tokens). If this +** means that the phrase does not appear in the current row, doclist.pList +** and doclist.nList are both zeroed. +** +** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code. +*/ +static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){ + int iToken; /* Used to iterate through phrase tokens */ + char *aPoslist = 0; /* Position list for deferred tokens */ + int nPoslist = 0; /* Number of bytes in aPoslist */ + int iPrev = -1; /* Token number of previous deferred token */ + char *aFree = (pPhrase->doclist.bFreeList ? pPhrase->doclist.pList : 0); + + for(iToken=0; iTokennToken; iToken++){ + Fts3PhraseToken *pToken = &pPhrase->aToken[iToken]; + Fts3DeferredToken *pDeferred = pToken->pDeferred; + + if( pDeferred ){ + char *pList; + int nList; + int rc = sqlite3Fts3DeferredTokenList(pDeferred, &pList, &nList); + if( rc!=SQLITE_OK ) return rc; + + if( pList==0 ){ + sqlite3_free(aPoslist); + sqlite3_free(aFree); + pPhrase->doclist.pList = 0; + pPhrase->doclist.nList = 0; + return SQLITE_OK; + + }else if( aPoslist==0 ){ + aPoslist = pList; + nPoslist = nList; + + }else{ + char *aOut = pList; + char *p1 = aPoslist; + char *p2 = aOut; + + assert( iPrev>=0 ); + fts3PoslistPhraseMerge(&aOut, iToken-iPrev, 0, 1, &p1, &p2); + sqlite3_free(aPoslist); + aPoslist = pList; + nPoslist = (int)(aOut - aPoslist); + if( nPoslist==0 ){ + sqlite3_free(aPoslist); + sqlite3_free(aFree); + pPhrase->doclist.pList = 0; + pPhrase->doclist.nList = 0; + return SQLITE_OK; + } + } + iPrev = iToken; + } + } + + if( iPrev>=0 ){ + int nMaxUndeferred = pPhrase->iDoclistToken; + if( nMaxUndeferred<0 ){ + pPhrase->doclist.pList = aPoslist; + pPhrase->doclist.nList = nPoslist; + pPhrase->doclist.iDocid = pCsr->iPrevId; + pPhrase->doclist.bFreeList = 1; + }else{ + int nDistance; + char *p1; + char *p2; + char *aOut; + i64 nAlloc = (i64)nPoslist*2 + FTS3_BUFFER_PADDING; + + if( nMaxUndeferred>iPrev ){ + p1 = aPoslist; + p2 = pPhrase->doclist.pList; + nDistance = nMaxUndeferred - iPrev; + }else{ + p1 = pPhrase->doclist.pList; + p2 = aPoslist; + nDistance = iPrev - nMaxUndeferred; + } + + aOut = (char *)sqlite3Fts3MallocZero(nAlloc); + if( !aOut ){ + sqlite3_free(aPoslist); + return SQLITE_NOMEM; + } + + pPhrase->doclist.pList = aOut; + assert( p1 && p2 ); + if( fts3PoslistPhraseMerge(&aOut, nDistance, 0, 1, &p1, &p2) ){ + pPhrase->doclist.bFreeList = 1; + pPhrase->doclist.nList = (int)(aOut - pPhrase->doclist.pList); + }else{ + sqlite3_free(aOut); + pPhrase->doclist.pList = 0; + pPhrase->doclist.nList = 0; + } + sqlite3_free(aPoslist); + } + } + + if( pPhrase->doclist.pList!=aFree ) sqlite3_free(aFree); + return SQLITE_OK; +} +#endif /* SQLITE_DISABLE_FTS4_DEFERRED */ + +/* +** Maximum number of tokens a phrase may have to be considered for the +** incremental doclists strategy. +*/ +#define MAX_INCR_PHRASE_TOKENS 4 + +/* +** This function is called for each Fts3Phrase in a full-text query +** expression to initialize the mechanism for returning rows. Once this +** function has been called successfully on an Fts3Phrase, it may be +** used with fts3EvalPhraseNext() to iterate through the matching docids. +** +** If parameter bOptOk is true, then the phrase may (or may not) use the +** incremental loading strategy. Otherwise, the entire doclist is loaded into +** memory within this call. +** +** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code. +*/ +static int fts3EvalPhraseStart(Fts3Cursor *pCsr, int bOptOk, Fts3Phrase *p){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int rc = SQLITE_OK; /* Error code */ + int i; + + /* Determine if doclists may be loaded from disk incrementally. This is + ** possible if the bOptOk argument is true, the FTS doclists will be + ** scanned in forward order, and the phrase consists of + ** MAX_INCR_PHRASE_TOKENS or fewer tokens, none of which are are "^first" + ** tokens or prefix tokens that cannot use a prefix-index. */ + int bHaveIncr = 0; + int bIncrOk = (bOptOk + && pCsr->bDesc==pTab->bDescIdx + && p->nToken<=MAX_INCR_PHRASE_TOKENS && p->nToken>0 +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + && pTab->bNoIncrDoclist==0 +#endif + ); + for(i=0; bIncrOk==1 && inToken; i++){ + Fts3PhraseToken *pToken = &p->aToken[i]; + if( pToken->bFirst || (pToken->pSegcsr!=0 && !pToken->pSegcsr->bLookup) ){ + bIncrOk = 0; + } + if( pToken->pSegcsr ) bHaveIncr = 1; + } + + if( bIncrOk && bHaveIncr ){ + /* Use the incremental approach. */ + int iCol = (p->iColumn >= pTab->nColumn ? -1 : p->iColumn); + for(i=0; rc==SQLITE_OK && inToken; i++){ + Fts3PhraseToken *pToken = &p->aToken[i]; + Fts3MultiSegReader *pSegcsr = pToken->pSegcsr; + if( pSegcsr ){ + rc = sqlite3Fts3MsrIncrStart(pTab, pSegcsr, iCol, pToken->z, pToken->n); + } + } + p->bIncr = 1; + }else{ + /* Load the full doclist for the phrase into memory. */ + rc = fts3EvalPhraseLoad(pCsr, p); + p->bIncr = 0; + } + + assert( rc!=SQLITE_OK || p->nToken<1 || p->aToken[0].pSegcsr==0 || p->bIncr ); + return rc; +} + +/* +** This function is used to iterate backwards (from the end to start) +** through doclists. It is used by this module to iterate through phrase +** doclists in reverse and by the fts3_write.c module to iterate through +** pending-terms lists when writing to databases with "order=desc". +** +** The doclist may be sorted in ascending (parameter bDescIdx==0) or +** descending (parameter bDescIdx==1) order of docid. Regardless, this +** function iterates from the end of the doclist to the beginning. +*/ +SQLITE_PRIVATE void sqlite3Fts3DoclistPrev( + int bDescIdx, /* True if the doclist is desc */ + char *aDoclist, /* Pointer to entire doclist */ + int nDoclist, /* Length of aDoclist in bytes */ + char **ppIter, /* IN/OUT: Iterator pointer */ + sqlite3_int64 *piDocid, /* IN/OUT: Docid pointer */ + int *pnList, /* OUT: List length pointer */ + u8 *pbEof /* OUT: End-of-file flag */ +){ + char *p = *ppIter; + + assert( nDoclist>0 ); + assert( *pbEof==0 ); + assert_fts3_nc( p || *piDocid==0 ); + assert( !p || (p>aDoclist && p<&aDoclist[nDoclist]) ); + + if( p==0 ){ + sqlite3_int64 iDocid = 0; + char *pNext = 0; + char *pDocid = aDoclist; + char *pEnd = &aDoclist[nDoclist]; + int iMul = 1; + + while( pDocid0 ); + assert( *pbEof==0 ); + assert_fts3_nc( p || *piDocid==0 ); + assert( !p || (p>=aDoclist && p<=&aDoclist[nDoclist]) ); + + if( p==0 ){ + p = aDoclist; + p += sqlite3Fts3GetVarint(p, piDocid); + }else{ + fts3PoslistCopy(0, &p); + while( p<&aDoclist[nDoclist] && *p==0 ) p++; + if( p>=&aDoclist[nDoclist] ){ + *pbEof = 1; + }else{ + sqlite3_int64 iVar; + p += sqlite3Fts3GetVarint(p, &iVar); + *piDocid += ((bDescIdx ? -1 : 1) * iVar); + } + } + + *ppIter = p; +} + +/* +** Advance the iterator pDL to the next entry in pDL->aAll/nAll. Set *pbEof +** to true if EOF is reached. +*/ +static void fts3EvalDlPhraseNext( + Fts3Table *pTab, + Fts3Doclist *pDL, + u8 *pbEof +){ + char *pIter; /* Used to iterate through aAll */ + char *pEnd; /* 1 byte past end of aAll */ + + if( pDL->pNextDocid ){ + pIter = pDL->pNextDocid; + assert( pDL->aAll!=0 || pIter==0 ); + }else{ + pIter = pDL->aAll; + } + + if( pIter==0 || pIter>=(pEnd = pDL->aAll + pDL->nAll) ){ + /* We have already reached the end of this doclist. EOF. */ + *pbEof = 1; + }else{ + sqlite3_int64 iDelta; + pIter += sqlite3Fts3GetVarint(pIter, &iDelta); + if( pTab->bDescIdx==0 || pDL->pNextDocid==0 ){ + pDL->iDocid += iDelta; + }else{ + pDL->iDocid -= iDelta; + } + pDL->pList = pIter; + fts3PoslistCopy(0, &pIter); + pDL->nList = (int)(pIter - pDL->pList); + + /* pIter now points just past the 0x00 that terminates the position- + ** list for document pDL->iDocid. However, if this position-list was + ** edited in place by fts3EvalNearTrim(), then pIter may not actually + ** point to the start of the next docid value. The following line deals + ** with this case by advancing pIter past the zero-padding added by + ** fts3EvalNearTrim(). */ + while( pIterpNextDocid = pIter; + assert( pIter>=&pDL->aAll[pDL->nAll] || *pIter ); + *pbEof = 0; + } +} + +/* +** Helper type used by fts3EvalIncrPhraseNext() and incrPhraseTokenNext(). +*/ +typedef struct TokenDoclist TokenDoclist; +struct TokenDoclist { + int bIgnore; + sqlite3_int64 iDocid; + char *pList; + int nList; +}; + +/* +** Token pToken is an incrementally loaded token that is part of a +** multi-token phrase. Advance it to the next matching document in the +** database and populate output variable *p with the details of the new +** entry. Or, if the iterator has reached EOF, set *pbEof to true. +** +** If an error occurs, return an SQLite error code. Otherwise, return +** SQLITE_OK. +*/ +static int incrPhraseTokenNext( + Fts3Table *pTab, /* Virtual table handle */ + Fts3Phrase *pPhrase, /* Phrase to advance token of */ + int iToken, /* Specific token to advance */ + TokenDoclist *p, /* OUT: Docid and doclist for new entry */ + u8 *pbEof /* OUT: True if iterator is at EOF */ +){ + int rc = SQLITE_OK; + + if( pPhrase->iDoclistToken==iToken ){ + assert( p->bIgnore==0 ); + assert( pPhrase->aToken[iToken].pSegcsr==0 ); + fts3EvalDlPhraseNext(pTab, &pPhrase->doclist, pbEof); + p->pList = pPhrase->doclist.pList; + p->nList = pPhrase->doclist.nList; + p->iDocid = pPhrase->doclist.iDocid; + }else{ + Fts3PhraseToken *pToken = &pPhrase->aToken[iToken]; + assert( pToken->pDeferred==0 ); + assert( pToken->pSegcsr || pPhrase->iDoclistToken>=0 ); + if( pToken->pSegcsr ){ + assert( p->bIgnore==0 ); + rc = sqlite3Fts3MsrIncrNext( + pTab, pToken->pSegcsr, &p->iDocid, &p->pList, &p->nList + ); + if( p->pList==0 ) *pbEof = 1; + }else{ + p->bIgnore = 1; + } + } + + return rc; +} + + +/* +** The phrase iterator passed as the second argument: +** +** * features at least one token that uses an incremental doclist, and +** +** * does not contain any deferred tokens. +** +** Advance it to the next matching document in the database and populate +** the Fts3Doclist.pList and nList fields. +** +** If there is no "next" entry and no error occurs, then *pbEof is set to +** 1 before returning. Otherwise, if no error occurs and the iterator is +** successfully advanced, *pbEof is set to 0. +** +** If an error occurs, return an SQLite error code. Otherwise, return +** SQLITE_OK. +*/ +static int fts3EvalIncrPhraseNext( + Fts3Cursor *pCsr, /* FTS Cursor handle */ + Fts3Phrase *p, /* Phrase object to advance to next docid */ + u8 *pbEof /* OUT: Set to 1 if EOF */ +){ + int rc = SQLITE_OK; + Fts3Doclist *pDL = &p->doclist; + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + u8 bEof = 0; + + /* This is only called if it is guaranteed that the phrase has at least + ** one incremental token. In which case the bIncr flag is set. */ + assert( p->bIncr==1 ); + + if( p->nToken==1 ){ + rc = sqlite3Fts3MsrIncrNext(pTab, p->aToken[0].pSegcsr, + &pDL->iDocid, &pDL->pList, &pDL->nList + ); + if( pDL->pList==0 ) bEof = 1; + }else{ + int bDescDoclist = pCsr->bDesc; + struct TokenDoclist a[MAX_INCR_PHRASE_TOKENS]; + + memset(a, 0, sizeof(a)); + assert( p->nToken<=MAX_INCR_PHRASE_TOKENS ); + assert( p->iDoclistTokennToken && bEof==0; i++){ + rc = incrPhraseTokenNext(pTab, p, i, &a[i], &bEof); + if( a[i].bIgnore==0 && (bMaxSet==0 || DOCID_CMP(iMax, a[i].iDocid)<0) ){ + iMax = a[i].iDocid; + bMaxSet = 1; + } + } + assert( rc!=SQLITE_OK || (p->nToken>=1 && a[p->nToken-1].bIgnore==0) ); + assert( rc!=SQLITE_OK || bMaxSet ); + + /* Keep advancing iterators until they all point to the same document */ + for(i=0; inToken; i++){ + while( rc==SQLITE_OK && bEof==0 + && a[i].bIgnore==0 && DOCID_CMP(a[i].iDocid, iMax)<0 + ){ + rc = incrPhraseTokenNext(pTab, p, i, &a[i], &bEof); + if( DOCID_CMP(a[i].iDocid, iMax)>0 ){ + iMax = a[i].iDocid; + i = 0; + } + } + } + + /* Check if the current entries really are a phrase match */ + if( bEof==0 ){ + int nList = 0; + int nByte = a[p->nToken-1].nList; + char *aDoclist = sqlite3_malloc64((i64)nByte+FTS3_BUFFER_PADDING); + if( !aDoclist ) return SQLITE_NOMEM; + memcpy(aDoclist, a[p->nToken-1].pList, nByte+1); + memset(&aDoclist[nByte], 0, FTS3_BUFFER_PADDING); + + for(i=0; i<(p->nToken-1); i++){ + if( a[i].bIgnore==0 ){ + char *pL = a[i].pList; + char *pR = aDoclist; + char *pOut = aDoclist; + int nDist = p->nToken-1-i; + int res = fts3PoslistPhraseMerge(&pOut, nDist, 0, 1, &pL, &pR); + if( res==0 ) break; + nList = (int)(pOut - aDoclist); + } + } + if( i==(p->nToken-1) ){ + pDL->iDocid = iMax; + pDL->pList = aDoclist; + pDL->nList = nList; + pDL->bFreeList = 1; + break; + } + sqlite3_free(aDoclist); + } + } + } + + *pbEof = bEof; + return rc; +} + +/* +** Attempt to move the phrase iterator to point to the next matching docid. +** If an error occurs, return an SQLite error code. Otherwise, return +** SQLITE_OK. +** +** If there is no "next" entry and no error occurs, then *pbEof is set to +** 1 before returning. Otherwise, if no error occurs and the iterator is +** successfully advanced, *pbEof is set to 0. +*/ +static int fts3EvalPhraseNext( + Fts3Cursor *pCsr, /* FTS Cursor handle */ + Fts3Phrase *p, /* Phrase object to advance to next docid */ + u8 *pbEof /* OUT: Set to 1 if EOF */ +){ + int rc = SQLITE_OK; + Fts3Doclist *pDL = &p->doclist; + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + + if( p->bIncr ){ + rc = fts3EvalIncrPhraseNext(pCsr, p, pbEof); + }else if( pCsr->bDesc!=pTab->bDescIdx && pDL->nAll ){ + sqlite3Fts3DoclistPrev(pTab->bDescIdx, pDL->aAll, pDL->nAll, + &pDL->pNextDocid, &pDL->iDocid, &pDL->nList, pbEof + ); + pDL->pList = pDL->pNextDocid; + }else{ + fts3EvalDlPhraseNext(pTab, pDL, pbEof); + } + + return rc; +} + +/* +** +** If *pRc is not SQLITE_OK when this function is called, it is a no-op. +** Otherwise, fts3EvalPhraseStart() is called on all phrases within the +** expression. Also the Fts3Expr.bDeferred variable is set to true for any +** expressions for which all descendent tokens are deferred. +** +** If parameter bOptOk is zero, then it is guaranteed that the +** Fts3Phrase.doclist.aAll/nAll variables contain the entire doclist for +** each phrase in the expression (subject to deferred token processing). +** Or, if bOptOk is non-zero, then one or more tokens within the expression +** may be loaded incrementally, meaning doclist.aAll/nAll is not available. +** +** If an error occurs within this function, *pRc is set to an SQLite error +** code before returning. +*/ +static void fts3EvalStartReaders( + Fts3Cursor *pCsr, /* FTS Cursor handle */ + Fts3Expr *pExpr, /* Expression to initialize phrases in */ + int *pRc /* IN/OUT: Error code */ +){ + if( pExpr && SQLITE_OK==*pRc ){ + if( pExpr->eType==FTSQUERY_PHRASE ){ + int nToken = pExpr->pPhrase->nToken; + if( nToken ){ + int i; + for(i=0; ipPhrase->aToken[i].pDeferred==0 ) break; + } + pExpr->bDeferred = (i==nToken); + } + *pRc = fts3EvalPhraseStart(pCsr, 1, pExpr->pPhrase); + }else{ + fts3EvalStartReaders(pCsr, pExpr->pLeft, pRc); + fts3EvalStartReaders(pCsr, pExpr->pRight, pRc); + pExpr->bDeferred = (pExpr->pLeft->bDeferred && pExpr->pRight->bDeferred); + } + } +} + +/* +** An array of the following structures is assembled as part of the process +** of selecting tokens to defer before the query starts executing (as part +** of the xFilter() method). There is one element in the array for each +** token in the FTS expression. +** +** Tokens are divided into AND/NEAR clusters. All tokens in a cluster belong +** to phrases that are connected only by AND and NEAR operators (not OR or +** NOT). When determining tokens to defer, each AND/NEAR cluster is considered +** separately. The root of a tokens AND/NEAR cluster is stored in +** Fts3TokenAndCost.pRoot. +*/ +typedef struct Fts3TokenAndCost Fts3TokenAndCost; +struct Fts3TokenAndCost { + Fts3Phrase *pPhrase; /* The phrase the token belongs to */ + int iToken; /* Position of token in phrase */ + Fts3PhraseToken *pToken; /* The token itself */ + Fts3Expr *pRoot; /* Root of NEAR/AND cluster */ + int nOvfl; /* Number of overflow pages to load doclist */ + int iCol; /* The column the token must match */ +}; + +/* +** This function is used to populate an allocated Fts3TokenAndCost array. +** +** If *pRc is not SQLITE_OK when this function is called, it is a no-op. +** Otherwise, if an error occurs during execution, *pRc is set to an +** SQLite error code. +*/ +static void fts3EvalTokenCosts( + Fts3Cursor *pCsr, /* FTS Cursor handle */ + Fts3Expr *pRoot, /* Root of current AND/NEAR cluster */ + Fts3Expr *pExpr, /* Expression to consider */ + Fts3TokenAndCost **ppTC, /* Write new entries to *(*ppTC)++ */ + Fts3Expr ***ppOr, /* Write new OR root to *(*ppOr)++ */ + int *pRc /* IN/OUT: Error code */ +){ + if( *pRc==SQLITE_OK ){ + if( pExpr->eType==FTSQUERY_PHRASE ){ + Fts3Phrase *pPhrase = pExpr->pPhrase; + int i; + for(i=0; *pRc==SQLITE_OK && inToken; i++){ + Fts3TokenAndCost *pTC = (*ppTC)++; + pTC->pPhrase = pPhrase; + pTC->iToken = i; + pTC->pRoot = pRoot; + pTC->pToken = &pPhrase->aToken[i]; + pTC->iCol = pPhrase->iColumn; + *pRc = sqlite3Fts3MsrOvfl(pCsr, pTC->pToken->pSegcsr, &pTC->nOvfl); + } + }else if( pExpr->eType!=FTSQUERY_NOT ){ + assert( pExpr->eType==FTSQUERY_OR + || pExpr->eType==FTSQUERY_AND + || pExpr->eType==FTSQUERY_NEAR + ); + assert( pExpr->pLeft && pExpr->pRight ); + if( pExpr->eType==FTSQUERY_OR ){ + pRoot = pExpr->pLeft; + **ppOr = pRoot; + (*ppOr)++; + } + fts3EvalTokenCosts(pCsr, pRoot, pExpr->pLeft, ppTC, ppOr, pRc); + if( pExpr->eType==FTSQUERY_OR ){ + pRoot = pExpr->pRight; + **ppOr = pRoot; + (*ppOr)++; + } + fts3EvalTokenCosts(pCsr, pRoot, pExpr->pRight, ppTC, ppOr, pRc); + } + } +} + +/* +** Determine the average document (row) size in pages. If successful, +** write this value to *pnPage and return SQLITE_OK. Otherwise, return +** an SQLite error code. +** +** The average document size in pages is calculated by first calculating +** determining the average size in bytes, B. If B is less than the amount +** of data that will fit on a single leaf page of an intkey table in +** this database, then the average docsize is 1. Otherwise, it is 1 plus +** the number of overflow pages consumed by a record B bytes in size. +*/ +static int fts3EvalAverageDocsize(Fts3Cursor *pCsr, int *pnPage){ + int rc = SQLITE_OK; + if( pCsr->nRowAvg==0 ){ + /* The average document size, which is required to calculate the cost + ** of each doclist, has not yet been determined. Read the required + ** data from the %_stat table to calculate it. + ** + ** Entry 0 of the %_stat table is a blob containing (nCol+1) FTS3 + ** varints, where nCol is the number of columns in the FTS3 table. + ** The first varint is the number of documents currently stored in + ** the table. The following nCol varints contain the total amount of + ** data stored in all rows of each column of the table, from left + ** to right. + */ + Fts3Table *p = (Fts3Table*)pCsr->base.pVtab; + sqlite3_stmt *pStmt; + sqlite3_int64 nDoc = 0; + sqlite3_int64 nByte = 0; + const char *pEnd; + const char *a; + + rc = sqlite3Fts3SelectDoctotal(p, &pStmt); + if( rc!=SQLITE_OK ) return rc; + a = sqlite3_column_blob(pStmt, 0); + testcase( a==0 ); /* If %_stat.value set to X'' */ + if( a ){ + pEnd = &a[sqlite3_column_bytes(pStmt, 0)]; + a += sqlite3Fts3GetVarintBounded(a, pEnd, &nDoc); + while( anDoc = nDoc; + pCsr->nRowAvg = (int)(((nByte / nDoc) + p->nPgsz) / p->nPgsz); + assert( pCsr->nRowAvg>0 ); + rc = sqlite3_reset(pStmt); + } + + *pnPage = pCsr->nRowAvg; + return rc; +} + +/* +** This function is called to select the tokens (if any) that will be +** deferred. The array aTC[] has already been populated when this is +** called. +** +** This function is called once for each AND/NEAR cluster in the +** expression. Each invocation determines which tokens to defer within +** the cluster with root node pRoot. See comments above the definition +** of struct Fts3TokenAndCost for more details. +** +** If no error occurs, SQLITE_OK is returned and sqlite3Fts3DeferToken() +** called on each token to defer. Otherwise, an SQLite error code is +** returned. +*/ +static int fts3EvalSelectDeferred( + Fts3Cursor *pCsr, /* FTS Cursor handle */ + Fts3Expr *pRoot, /* Consider tokens with this root node */ + Fts3TokenAndCost *aTC, /* Array of expression tokens and costs */ + int nTC /* Number of entries in aTC[] */ +){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int nDocSize = 0; /* Number of pages per doc loaded */ + int rc = SQLITE_OK; /* Return code */ + int ii; /* Iterator variable for various purposes */ + int nOvfl = 0; /* Total overflow pages used by doclists */ + int nToken = 0; /* Total number of tokens in cluster */ + + int nMinEst = 0; /* The minimum count for any phrase so far. */ + int nLoad4 = 1; /* (Phrases that will be loaded)^4. */ + + /* Tokens are never deferred for FTS tables created using the content=xxx + ** option. The reason being that it is not guaranteed that the content + ** table actually contains the same data as the index. To prevent this from + ** causing any problems, the deferred token optimization is completely + ** disabled for content=xxx tables. */ + if( pTab->zContentTbl ){ + return SQLITE_OK; + } + + /* Count the tokens in this AND/NEAR cluster. If none of the doclists + ** associated with the tokens spill onto overflow pages, or if there is + ** only 1 token, exit early. No tokens to defer in this case. */ + for(ii=0; ii0 ); + + + /* Iterate through all tokens in this AND/NEAR cluster, in ascending order + ** of the number of overflow pages that will be loaded by the pager layer + ** to retrieve the entire doclist for the token from the full-text index. + ** Load the doclists for tokens that are either: + ** + ** a. The cheapest token in the entire query (i.e. the one visited by the + ** first iteration of this loop), or + ** + ** b. Part of a multi-token phrase. + ** + ** After each token doclist is loaded, merge it with the others from the + ** same phrase and count the number of documents that the merged doclist + ** contains. Set variable "nMinEst" to the smallest number of documents in + ** any phrase doclist for which 1 or more token doclists have been loaded. + ** Let nOther be the number of other phrases for which it is certain that + ** one or more tokens will not be deferred. + ** + ** Then, for each token, defer it if loading the doclist would result in + ** loading N or more overflow pages into memory, where N is computed as: + ** + ** (nMinEst + 4^nOther - 1) / (4^nOther) + */ + for(ii=0; iinOvfl) + ){ + pTC = &aTC[iTC]; + } + } + assert( pTC ); + + if( ii && pTC->nOvfl>=((nMinEst+(nLoad4/4)-1)/(nLoad4/4))*nDocSize ){ + /* The number of overflow pages to load for this (and therefore all + ** subsequent) tokens is greater than the estimated number of pages + ** that will be loaded if all subsequent tokens are deferred. + */ + Fts3PhraseToken *pToken = pTC->pToken; + rc = sqlite3Fts3DeferToken(pCsr, pToken, pTC->iCol); + fts3SegReaderCursorFree(pToken->pSegcsr); + pToken->pSegcsr = 0; + }else{ + /* Set nLoad4 to the value of (4^nOther) for the next iteration of the + ** for-loop. Except, limit the value to 2^24 to prevent it from + ** overflowing the 32-bit integer it is stored in. */ + if( ii<12 ) nLoad4 = nLoad4*4; + + if( ii==0 || (pTC->pPhrase->nToken>1 && ii!=nToken-1) ){ + /* Either this is the cheapest token in the entire query, or it is + ** part of a multi-token phrase. Either way, the entire doclist will + ** (eventually) be loaded into memory. It may as well be now. */ + Fts3PhraseToken *pToken = pTC->pToken; + int nList = 0; + char *pList = 0; + rc = fts3TermSelect(pTab, pToken, pTC->iCol, &nList, &pList); + assert( rc==SQLITE_OK || pList==0 ); + if( rc==SQLITE_OK ){ + rc = fts3EvalPhraseMergeToken( + pTab, pTC->pPhrase, pTC->iToken,pList,nList + ); + } + if( rc==SQLITE_OK ){ + int nCount; + nCount = fts3DoclistCountDocids( + pTC->pPhrase->doclist.aAll, pTC->pPhrase->doclist.nAll + ); + if( ii==0 || nCountpToken = 0; + } + + return rc; +} + +/* +** This function is called from within the xFilter method. It initializes +** the full-text query currently stored in pCsr->pExpr. To iterate through +** the results of a query, the caller does: +** +** fts3EvalStart(pCsr); +** while( 1 ){ +** fts3EvalNext(pCsr); +** if( pCsr->bEof ) break; +** ... return row pCsr->iPrevId to the caller ... +** } +*/ +static int fts3EvalStart(Fts3Cursor *pCsr){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int rc = SQLITE_OK; + int nToken = 0; + int nOr = 0; + + /* Allocate a MultiSegReader for each token in the expression. */ + fts3EvalAllocateReaders(pCsr, pCsr->pExpr, &nToken, &nOr, &rc); + + /* Determine which, if any, tokens in the expression should be deferred. */ +#ifndef SQLITE_DISABLE_FTS4_DEFERRED + if( rc==SQLITE_OK && nToken>1 && pTab->bFts4 ){ + Fts3TokenAndCost *aTC; + aTC = (Fts3TokenAndCost *)sqlite3_malloc64( + sizeof(Fts3TokenAndCost) * nToken + + sizeof(Fts3Expr *) * nOr * 2 + ); + + if( !aTC ){ + rc = SQLITE_NOMEM; + }else{ + Fts3Expr **apOr = (Fts3Expr **)&aTC[nToken]; + int ii; + Fts3TokenAndCost *pTC = aTC; + Fts3Expr **ppOr = apOr; + + fts3EvalTokenCosts(pCsr, 0, pCsr->pExpr, &pTC, &ppOr, &rc); + nToken = (int)(pTC-aTC); + nOr = (int)(ppOr-apOr); + + if( rc==SQLITE_OK ){ + rc = fts3EvalSelectDeferred(pCsr, 0, aTC, nToken); + for(ii=0; rc==SQLITE_OK && iipExpr, &rc); + return rc; +} + +/* +** Invalidate the current position list for phrase pPhrase. +*/ +static void fts3EvalInvalidatePoslist(Fts3Phrase *pPhrase){ + if( pPhrase->doclist.bFreeList ){ + sqlite3_free(pPhrase->doclist.pList); + } + pPhrase->doclist.pList = 0; + pPhrase->doclist.nList = 0; + pPhrase->doclist.bFreeList = 0; +} + +/* +** This function is called to edit the position list associated with +** the phrase object passed as the fifth argument according to a NEAR +** condition. For example: +** +** abc NEAR/5 "def ghi" +** +** Parameter nNear is passed the NEAR distance of the expression (5 in +** the example above). When this function is called, *paPoslist points to +** the position list, and *pnToken is the number of phrase tokens in the +** phrase on the other side of the NEAR operator to pPhrase. For example, +** if pPhrase refers to the "def ghi" phrase, then *paPoslist points to +** the position list associated with phrase "abc". +** +** All positions in the pPhrase position list that are not sufficiently +** close to a position in the *paPoslist position list are removed. If this +** leaves 0 positions, zero is returned. Otherwise, non-zero. +** +** Before returning, *paPoslist is set to point to the position lsit +** associated with pPhrase. And *pnToken is set to the number of tokens in +** pPhrase. +*/ +static int fts3EvalNearTrim( + int nNear, /* NEAR distance. As in "NEAR/nNear". */ + char *aTmp, /* Temporary space to use */ + char **paPoslist, /* IN/OUT: Position list */ + int *pnToken, /* IN/OUT: Tokens in phrase of *paPoslist */ + Fts3Phrase *pPhrase /* The phrase object to trim the doclist of */ +){ + int nParam1 = nNear + pPhrase->nToken; + int nParam2 = nNear + *pnToken; + int nNew; + char *p2; + char *pOut; + int res; + + assert( pPhrase->doclist.pList ); + + p2 = pOut = pPhrase->doclist.pList; + res = fts3PoslistNearMerge( + &pOut, aTmp, nParam1, nParam2, paPoslist, &p2 + ); + if( res ){ + nNew = (int)(pOut - pPhrase->doclist.pList) - 1; + assert_fts3_nc( nNew<=pPhrase->doclist.nList && nNew>0 ); + if( nNew>=0 && nNew<=pPhrase->doclist.nList ){ + assert( pPhrase->doclist.pList[nNew]=='\0' ); + memset(&pPhrase->doclist.pList[nNew], 0, pPhrase->doclist.nList - nNew); + pPhrase->doclist.nList = nNew; + } + *paPoslist = pPhrase->doclist.pList; + *pnToken = pPhrase->nToken; + } + + return res; +} + +/* +** This function is a no-op if *pRc is other than SQLITE_OK when it is called. +** Otherwise, it advances the expression passed as the second argument to +** point to the next matching row in the database. Expressions iterate through +** matching rows in docid order. Ascending order if Fts3Cursor.bDesc is zero, +** or descending if it is non-zero. +** +** If an error occurs, *pRc is set to an SQLite error code. Otherwise, if +** successful, the following variables in pExpr are set: +** +** Fts3Expr.bEof (non-zero if EOF - there is no next row) +** Fts3Expr.iDocid (valid if bEof==0. The docid of the next row) +** +** If the expression is of type FTSQUERY_PHRASE, and the expression is not +** at EOF, then the following variables are populated with the position list +** for the phrase for the visited row: +** +** FTs3Expr.pPhrase->doclist.nList (length of pList in bytes) +** FTs3Expr.pPhrase->doclist.pList (pointer to position list) +** +** It says above that this function advances the expression to the next +** matching row. This is usually true, but there are the following exceptions: +** +** 1. Deferred tokens are not taken into account. If a phrase consists +** entirely of deferred tokens, it is assumed to match every row in +** the db. In this case the position-list is not populated at all. +** +** Or, if a phrase contains one or more deferred tokens and one or +** more non-deferred tokens, then the expression is advanced to the +** next possible match, considering only non-deferred tokens. In other +** words, if the phrase is "A B C", and "B" is deferred, the expression +** is advanced to the next row that contains an instance of "A * C", +** where "*" may match any single token. The position list in this case +** is populated as for "A * C" before returning. +** +** 2. NEAR is treated as AND. If the expression is "x NEAR y", it is +** advanced to point to the next row that matches "x AND y". +** +** See sqlite3Fts3EvalTestDeferred() for details on testing if a row is +** really a match, taking into account deferred tokens and NEAR operators. +*/ +static void fts3EvalNextRow( + Fts3Cursor *pCsr, /* FTS Cursor handle */ + Fts3Expr *pExpr, /* Expr. to advance to next matching row */ + int *pRc /* IN/OUT: Error code */ +){ + if( *pRc==SQLITE_OK && pExpr->bEof==0 ){ + int bDescDoclist = pCsr->bDesc; /* Used by DOCID_CMP() macro */ + pExpr->bStart = 1; + + switch( pExpr->eType ){ + case FTSQUERY_NEAR: + case FTSQUERY_AND: { + Fts3Expr *pLeft = pExpr->pLeft; + Fts3Expr *pRight = pExpr->pRight; + assert( !pLeft->bDeferred || !pRight->bDeferred ); + + if( pLeft->bDeferred ){ + /* LHS is entirely deferred. So we assume it matches every row. + ** Advance the RHS iterator to find the next row visited. */ + fts3EvalNextRow(pCsr, pRight, pRc); + pExpr->iDocid = pRight->iDocid; + pExpr->bEof = pRight->bEof; + }else if( pRight->bDeferred ){ + /* RHS is entirely deferred. So we assume it matches every row. + ** Advance the LHS iterator to find the next row visited. */ + fts3EvalNextRow(pCsr, pLeft, pRc); + pExpr->iDocid = pLeft->iDocid; + pExpr->bEof = pLeft->bEof; + }else{ + /* Neither the RHS or LHS are deferred. */ + fts3EvalNextRow(pCsr, pLeft, pRc); + fts3EvalNextRow(pCsr, pRight, pRc); + while( !pLeft->bEof && !pRight->bEof && *pRc==SQLITE_OK ){ + sqlite3_int64 iDiff = DOCID_CMP(pLeft->iDocid, pRight->iDocid); + if( iDiff==0 ) break; + if( iDiff<0 ){ + fts3EvalNextRow(pCsr, pLeft, pRc); + }else{ + fts3EvalNextRow(pCsr, pRight, pRc); + } + } + pExpr->iDocid = pLeft->iDocid; + pExpr->bEof = (pLeft->bEof || pRight->bEof); + if( pExpr->eType==FTSQUERY_NEAR && pExpr->bEof ){ + assert( pRight->eType==FTSQUERY_PHRASE ); + if( pRight->pPhrase->doclist.aAll ){ + Fts3Doclist *pDl = &pRight->pPhrase->doclist; + while( *pRc==SQLITE_OK && pRight->bEof==0 ){ + memset(pDl->pList, 0, pDl->nList); + fts3EvalNextRow(pCsr, pRight, pRc); + } + } + if( pLeft->pPhrase && pLeft->pPhrase->doclist.aAll ){ + Fts3Doclist *pDl = &pLeft->pPhrase->doclist; + while( *pRc==SQLITE_OK && pLeft->bEof==0 ){ + memset(pDl->pList, 0, pDl->nList); + fts3EvalNextRow(pCsr, pLeft, pRc); + } + } + pRight->bEof = pLeft->bEof = 1; + } + } + break; + } + + case FTSQUERY_OR: { + Fts3Expr *pLeft = pExpr->pLeft; + Fts3Expr *pRight = pExpr->pRight; + sqlite3_int64 iCmp = DOCID_CMP(pLeft->iDocid, pRight->iDocid); + + assert_fts3_nc( pLeft->bStart || pLeft->iDocid==pRight->iDocid ); + assert_fts3_nc( pRight->bStart || pLeft->iDocid==pRight->iDocid ); + + if( pRight->bEof || (pLeft->bEof==0 && iCmp<0) ){ + fts3EvalNextRow(pCsr, pLeft, pRc); + }else if( pLeft->bEof || iCmp>0 ){ + fts3EvalNextRow(pCsr, pRight, pRc); + }else{ + fts3EvalNextRow(pCsr, pLeft, pRc); + fts3EvalNextRow(pCsr, pRight, pRc); + } + + pExpr->bEof = (pLeft->bEof && pRight->bEof); + iCmp = DOCID_CMP(pLeft->iDocid, pRight->iDocid); + if( pRight->bEof || (pLeft->bEof==0 && iCmp<0) ){ + pExpr->iDocid = pLeft->iDocid; + }else{ + pExpr->iDocid = pRight->iDocid; + } + + break; + } + + case FTSQUERY_NOT: { + Fts3Expr *pLeft = pExpr->pLeft; + Fts3Expr *pRight = pExpr->pRight; + + if( pRight->bStart==0 ){ + fts3EvalNextRow(pCsr, pRight, pRc); + assert( *pRc!=SQLITE_OK || pRight->bStart ); + } + + fts3EvalNextRow(pCsr, pLeft, pRc); + if( pLeft->bEof==0 ){ + while( !*pRc + && !pRight->bEof + && DOCID_CMP(pLeft->iDocid, pRight->iDocid)>0 + ){ + fts3EvalNextRow(pCsr, pRight, pRc); + } + } + pExpr->iDocid = pLeft->iDocid; + pExpr->bEof = pLeft->bEof; + break; + } + + default: { + Fts3Phrase *pPhrase = pExpr->pPhrase; + fts3EvalInvalidatePoslist(pPhrase); + *pRc = fts3EvalPhraseNext(pCsr, pPhrase, &pExpr->bEof); + pExpr->iDocid = pPhrase->doclist.iDocid; + break; + } + } + } +} + +/* +** If *pRc is not SQLITE_OK, or if pExpr is not the root node of a NEAR +** cluster, then this function returns 1 immediately. +** +** Otherwise, it checks if the current row really does match the NEAR +** expression, using the data currently stored in the position lists +** (Fts3Expr->pPhrase.doclist.pList/nList) for each phrase in the expression. +** +** If the current row is a match, the position list associated with each +** phrase in the NEAR expression is edited in place to contain only those +** phrase instances sufficiently close to their peers to satisfy all NEAR +** constraints. In this case it returns 1. If the NEAR expression does not +** match the current row, 0 is returned. The position lists may or may not +** be edited if 0 is returned. +*/ +static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){ + int res = 1; + + /* The following block runs if pExpr is the root of a NEAR query. + ** For example, the query: + ** + ** "w" NEAR "x" NEAR "y" NEAR "z" + ** + ** which is represented in tree form as: + ** + ** | + ** +--NEAR--+ <-- root of NEAR query + ** | | + ** +--NEAR--+ "z" + ** | | + ** +--NEAR--+ "y" + ** | | + ** "w" "x" + ** + ** The right-hand child of a NEAR node is always a phrase. The + ** left-hand child may be either a phrase or a NEAR node. There are + ** no exceptions to this - it's the way the parser in fts3_expr.c works. + */ + if( *pRc==SQLITE_OK + && pExpr->eType==FTSQUERY_NEAR + && (pExpr->pParent==0 || pExpr->pParent->eType!=FTSQUERY_NEAR) + ){ + Fts3Expr *p; + sqlite3_int64 nTmp = 0; /* Bytes of temp space */ + char *aTmp; /* Temp space for PoslistNearMerge() */ + + /* Allocate temporary working space. */ + for(p=pExpr; p->pLeft; p=p->pLeft){ + assert( p->pRight->pPhrase->doclist.nList>0 ); + nTmp += p->pRight->pPhrase->doclist.nList; + } + nTmp += p->pPhrase->doclist.nList; + aTmp = sqlite3_malloc64(nTmp*2 + FTS3_VARINT_MAX); + if( !aTmp ){ + *pRc = SQLITE_NOMEM; + res = 0; + }else{ + char *aPoslist = p->pPhrase->doclist.pList; + int nToken = p->pPhrase->nToken; + + for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){ + Fts3Phrase *pPhrase = p->pRight->pPhrase; + int nNear = p->nNear; + res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase); + } + + aPoslist = pExpr->pRight->pPhrase->doclist.pList; + nToken = pExpr->pRight->pPhrase->nToken; + for(p=pExpr->pLeft; p && res; p=p->pLeft){ + int nNear; + Fts3Phrase *pPhrase; + assert( p->pParent && p->pParent->pLeft==p ); + nNear = p->pParent->nNear; + pPhrase = ( + p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase + ); + res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase); + } + } + + sqlite3_free(aTmp); + } + + return res; +} + +/* +** This function is a helper function for sqlite3Fts3EvalTestDeferred(). +** Assuming no error occurs or has occurred, It returns non-zero if the +** expression passed as the second argument matches the row that pCsr +** currently points to, or zero if it does not. +** +** If *pRc is not SQLITE_OK when this function is called, it is a no-op. +** If an error occurs during execution of this function, *pRc is set to +** the appropriate SQLite error code. In this case the returned value is +** undefined. +*/ +static int fts3EvalTestExpr( + Fts3Cursor *pCsr, /* FTS cursor handle */ + Fts3Expr *pExpr, /* Expr to test. May or may not be root. */ + int *pRc /* IN/OUT: Error code */ +){ + int bHit = 1; /* Return value */ + if( *pRc==SQLITE_OK ){ + switch( pExpr->eType ){ + case FTSQUERY_NEAR: + case FTSQUERY_AND: + bHit = ( + fts3EvalTestExpr(pCsr, pExpr->pLeft, pRc) + && fts3EvalTestExpr(pCsr, pExpr->pRight, pRc) + && fts3EvalNearTest(pExpr, pRc) + ); + + /* If the NEAR expression does not match any rows, zero the doclist for + ** all phrases involved in the NEAR. This is because the snippet(), + ** offsets() and matchinfo() functions are not supposed to recognize + ** any instances of phrases that are part of unmatched NEAR queries. + ** For example if this expression: + ** + ** ... MATCH 'a OR (b NEAR c)' + ** + ** is matched against a row containing: + ** + ** 'a b d e' + ** + ** then any snippet() should ony highlight the "a" term, not the "b" + ** (as "b" is part of a non-matching NEAR clause). + */ + if( bHit==0 + && pExpr->eType==FTSQUERY_NEAR + && (pExpr->pParent==0 || pExpr->pParent->eType!=FTSQUERY_NEAR) + ){ + Fts3Expr *p; + for(p=pExpr; p->pPhrase==0; p=p->pLeft){ + if( p->pRight->iDocid==pCsr->iPrevId ){ + fts3EvalInvalidatePoslist(p->pRight->pPhrase); + } + } + if( p->iDocid==pCsr->iPrevId ){ + fts3EvalInvalidatePoslist(p->pPhrase); + } + } + + break; + + case FTSQUERY_OR: { + int bHit1 = fts3EvalTestExpr(pCsr, pExpr->pLeft, pRc); + int bHit2 = fts3EvalTestExpr(pCsr, pExpr->pRight, pRc); + bHit = bHit1 || bHit2; + break; + } + + case FTSQUERY_NOT: + bHit = ( + fts3EvalTestExpr(pCsr, pExpr->pLeft, pRc) + && !fts3EvalTestExpr(pCsr, pExpr->pRight, pRc) + ); + break; + + default: { +#ifndef SQLITE_DISABLE_FTS4_DEFERRED + if( pCsr->pDeferred && (pExpr->bDeferred || ( + pExpr->iDocid==pCsr->iPrevId && pExpr->pPhrase->doclist.pList + ))){ + Fts3Phrase *pPhrase = pExpr->pPhrase; + if( pExpr->bDeferred ){ + fts3EvalInvalidatePoslist(pPhrase); + } + *pRc = fts3EvalDeferredPhrase(pCsr, pPhrase); + bHit = (pPhrase->doclist.pList!=0); + pExpr->iDocid = pCsr->iPrevId; + }else +#endif + { + bHit = ( + pExpr->bEof==0 && pExpr->iDocid==pCsr->iPrevId + && pExpr->pPhrase->doclist.nList>0 + ); + } + break; + } + } + } + return bHit; +} + +/* +** This function is called as the second part of each xNext operation when +** iterating through the results of a full-text query. At this point the +** cursor points to a row that matches the query expression, with the +** following caveats: +** +** * Up until this point, "NEAR" operators in the expression have been +** treated as "AND". +** +** * Deferred tokens have not yet been considered. +** +** If *pRc is not SQLITE_OK when this function is called, it immediately +** returns 0. Otherwise, it tests whether or not after considering NEAR +** operators and deferred tokens the current row is still a match for the +** expression. It returns 1 if both of the following are true: +** +** 1. *pRc is SQLITE_OK when this function returns, and +** +** 2. After scanning the current FTS table row for the deferred tokens, +** it is determined that the row does *not* match the query. +** +** Or, if no error occurs and it seems the current row does match the FTS +** query, return 0. +*/ +SQLITE_PRIVATE int sqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc){ + int rc = *pRc; + int bMiss = 0; + if( rc==SQLITE_OK ){ + + /* If there are one or more deferred tokens, load the current row into + ** memory and scan it to determine the position list for each deferred + ** token. Then, see if this row is really a match, considering deferred + ** tokens and NEAR operators (neither of which were taken into account + ** earlier, by fts3EvalNextRow()). + */ + if( pCsr->pDeferred ){ + rc = fts3CursorSeek(0, pCsr); + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3CacheDeferredDoclists(pCsr); + } + } + bMiss = (0==fts3EvalTestExpr(pCsr, pCsr->pExpr, &rc)); + + /* Free the position-lists accumulated for each deferred token above. */ + sqlite3Fts3FreeDeferredDoclists(pCsr); + *pRc = rc; + } + return (rc==SQLITE_OK && bMiss); +} + +/* +** Advance to the next document that matches the FTS expression in +** Fts3Cursor.pExpr. +*/ +static int fts3EvalNext(Fts3Cursor *pCsr){ + int rc = SQLITE_OK; /* Return Code */ + Fts3Expr *pExpr = pCsr->pExpr; + assert( pCsr->isEof==0 ); + if( pExpr==0 ){ + pCsr->isEof = 1; + }else{ + do { + if( pCsr->isRequireSeek==0 ){ + sqlite3_reset(pCsr->pStmt); + } + assert( sqlite3_data_count(pCsr->pStmt)==0 ); + fts3EvalNextRow(pCsr, pExpr, &rc); + pCsr->isEof = pExpr->bEof; + pCsr->isRequireSeek = 1; + pCsr->isMatchinfoNeeded = 1; + pCsr->iPrevId = pExpr->iDocid; + }while( pCsr->isEof==0 && sqlite3Fts3EvalTestDeferred(pCsr, &rc) ); + } + + /* Check if the cursor is past the end of the docid range specified + ** by Fts3Cursor.iMinDocid/iMaxDocid. If so, set the EOF flag. */ + if( rc==SQLITE_OK && ( + (pCsr->bDesc==0 && pCsr->iPrevId>pCsr->iMaxDocid) + || (pCsr->bDesc!=0 && pCsr->iPrevIdiMinDocid) + )){ + pCsr->isEof = 1; + } + + return rc; +} + +/* +** Restart iteration for expression pExpr so that the next call to +** fts3EvalNext() visits the first row. Do not allow incremental +** loading or merging of phrase doclists for this iteration. +** +** If *pRc is other than SQLITE_OK when this function is called, it is +** a no-op. If an error occurs within this function, *pRc is set to an +** SQLite error code before returning. +*/ +static void fts3EvalRestart( + Fts3Cursor *pCsr, + Fts3Expr *pExpr, + int *pRc +){ + if( pExpr && *pRc==SQLITE_OK ){ + Fts3Phrase *pPhrase = pExpr->pPhrase; + + if( pPhrase ){ + fts3EvalInvalidatePoslist(pPhrase); + if( pPhrase->bIncr ){ + int i; + for(i=0; inToken; i++){ + Fts3PhraseToken *pToken = &pPhrase->aToken[i]; + assert( pToken->pDeferred==0 ); + if( pToken->pSegcsr ){ + sqlite3Fts3MsrIncrRestart(pToken->pSegcsr); + } + } + *pRc = fts3EvalPhraseStart(pCsr, 0, pPhrase); + } + pPhrase->doclist.pNextDocid = 0; + pPhrase->doclist.iDocid = 0; + pPhrase->pOrPoslist = 0; + } + + pExpr->iDocid = 0; + pExpr->bEof = 0; + pExpr->bStart = 0; + + fts3EvalRestart(pCsr, pExpr->pLeft, pRc); + fts3EvalRestart(pCsr, pExpr->pRight, pRc); + } +} + +/* +** Expression node pExpr is an MSR phrase. This function restarts pExpr +** so that it is a regular phrase query, not an MSR. SQLITE_OK is returned +** if successful, or an SQLite error code otherwise. +*/ +SQLITE_PRIVATE int sqlite3Fts3MsrCancel(Fts3Cursor *pCsr, Fts3Expr *pExpr){ + int rc = SQLITE_OK; + if( pExpr->bEof==0 ){ + i64 iDocid = pExpr->iDocid; + fts3EvalRestart(pCsr, pExpr, &rc); + while( rc==SQLITE_OK && pExpr->iDocid!=iDocid ){ + fts3EvalNextRow(pCsr, pExpr, &rc); + if( pExpr->bEof ) rc = FTS_CORRUPT_VTAB; + } + } + return rc; +} + +/* +** After allocating the Fts3Expr.aMI[] array for each phrase in the +** expression rooted at pExpr, the cursor iterates through all rows matched +** by pExpr, calling this function for each row. This function increments +** the values in Fts3Expr.aMI[] according to the position-list currently +** found in Fts3Expr.pPhrase->doclist.pList for each of the phrase +** expression nodes. +*/ +static void fts3EvalUpdateCounts(Fts3Expr *pExpr, int nCol){ + if( pExpr ){ + Fts3Phrase *pPhrase = pExpr->pPhrase; + if( pPhrase && pPhrase->doclist.pList ){ + int iCol = 0; + char *p = pPhrase->doclist.pList; + + do{ + u8 c = 0; + int iCnt = 0; + while( 0xFE & (*p | c) ){ + if( (c&0x80)==0 ) iCnt++; + c = *p++ & 0x80; + } + + /* aMI[iCol*3 + 1] = Number of occurrences + ** aMI[iCol*3 + 2] = Number of rows containing at least one instance + */ + pExpr->aMI[iCol*3 + 1] += iCnt; + pExpr->aMI[iCol*3 + 2] += (iCnt>0); + if( *p==0x00 ) break; + p++; + p += fts3GetVarint32(p, &iCol); + }while( iColpLeft, nCol); + fts3EvalUpdateCounts(pExpr->pRight, nCol); + } +} + +/* +** This is an sqlite3Fts3ExprIterate() callback. If the Fts3Expr.aMI[] array +** has not yet been allocated, allocate and zero it. Otherwise, just zero +** it. +*/ +static int fts3AllocateMSI(Fts3Expr *pExpr, int iPhrase, void *pCtx){ + Fts3Table *pTab = (Fts3Table*)pCtx; + UNUSED_PARAMETER(iPhrase); + if( pExpr->aMI==0 ){ + pExpr->aMI = (u32 *)sqlite3_malloc64(pTab->nColumn * 3 * sizeof(u32)); + if( pExpr->aMI==0 ) return SQLITE_NOMEM; + } + memset(pExpr->aMI, 0, pTab->nColumn * 3 * sizeof(u32)); + return SQLITE_OK; +} + +/* +** Expression pExpr must be of type FTSQUERY_PHRASE. +** +** If it is not already allocated and populated, this function allocates and +** populates the Fts3Expr.aMI[] array for expression pExpr. If pExpr is part +** of a NEAR expression, then it also allocates and populates the same array +** for all other phrases that are part of the NEAR expression. +** +** SQLITE_OK is returned if the aMI[] array is successfully allocated and +** populated. Otherwise, if an error occurs, an SQLite error code is returned. +*/ +static int fts3EvalGatherStats( + Fts3Cursor *pCsr, /* Cursor object */ + Fts3Expr *pExpr /* FTSQUERY_PHRASE expression */ +){ + int rc = SQLITE_OK; /* Return code */ + + assert( pExpr->eType==FTSQUERY_PHRASE ); + if( pExpr->aMI==0 ){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + Fts3Expr *pRoot; /* Root of NEAR expression */ + + sqlite3_int64 iPrevId = pCsr->iPrevId; + sqlite3_int64 iDocid; + u8 bEof; + + /* Find the root of the NEAR expression */ + pRoot = pExpr; + while( pRoot->pParent + && (pRoot->pParent->eType==FTSQUERY_NEAR || pRoot->bDeferred) + ){ + pRoot = pRoot->pParent; + } + iDocid = pRoot->iDocid; + bEof = pRoot->bEof; + assert( pRoot->bStart ); + + /* Allocate space for the aMSI[] array of each FTSQUERY_PHRASE node */ + rc = sqlite3Fts3ExprIterate(pRoot, fts3AllocateMSI, (void*)pTab); + if( rc!=SQLITE_OK ) return rc; + fts3EvalRestart(pCsr, pRoot, &rc); + + while( pCsr->isEof==0 && rc==SQLITE_OK ){ + + do { + /* Ensure the %_content statement is reset. */ + if( pCsr->isRequireSeek==0 ) sqlite3_reset(pCsr->pStmt); + assert( sqlite3_data_count(pCsr->pStmt)==0 ); + + /* Advance to the next document */ + fts3EvalNextRow(pCsr, pRoot, &rc); + pCsr->isEof = pRoot->bEof; + pCsr->isRequireSeek = 1; + pCsr->isMatchinfoNeeded = 1; + pCsr->iPrevId = pRoot->iDocid; + }while( pCsr->isEof==0 + && pRoot->eType==FTSQUERY_NEAR + && sqlite3Fts3EvalTestDeferred(pCsr, &rc) + ); + + if( rc==SQLITE_OK && pCsr->isEof==0 ){ + fts3EvalUpdateCounts(pRoot, pTab->nColumn); + } + } + + pCsr->isEof = 0; + pCsr->iPrevId = iPrevId; + + if( bEof ){ + pRoot->bEof = bEof; + }else{ + /* Caution: pRoot may iterate through docids in ascending or descending + ** order. For this reason, even though it seems more defensive, the + ** do loop can not be written: + ** + ** do {...} while( pRoot->iDocidbEof==0 ); + if( pRoot->bEof ) rc = FTS_CORRUPT_VTAB; + }while( pRoot->iDocid!=iDocid && rc==SQLITE_OK ); + } + } + return rc; +} + +/* +** This function is used by the matchinfo() module to query a phrase +** expression node for the following information: +** +** 1. The total number of occurrences of the phrase in each column of +** the FTS table (considering all rows), and +** +** 2. For each column, the number of rows in the table for which the +** column contains at least one instance of the phrase. +** +** If no error occurs, SQLITE_OK is returned and the values for each column +** written into the array aiOut as follows: +** +** aiOut[iCol*3 + 1] = Number of occurrences +** aiOut[iCol*3 + 2] = Number of rows containing at least one instance +** +** Caveats: +** +** * If a phrase consists entirely of deferred tokens, then all output +** values are set to the number of documents in the table. In other +** words we assume that very common tokens occur exactly once in each +** column of each row of the table. +** +** * If a phrase contains some deferred tokens (and some non-deferred +** tokens), count the potential occurrence identified by considering +** the non-deferred tokens instead of actual phrase occurrences. +** +** * If the phrase is part of a NEAR expression, then only phrase instances +** that meet the NEAR constraint are included in the counts. +*/ +SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats( + Fts3Cursor *pCsr, /* FTS cursor handle */ + Fts3Expr *pExpr, /* Phrase expression */ + u32 *aiOut /* Array to write results into (see above) */ +){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int rc = SQLITE_OK; + int iCol; + + if( pExpr->bDeferred && pExpr->pParent->eType!=FTSQUERY_NEAR ){ + assert( pCsr->nDoc>0 ); + for(iCol=0; iColnColumn; iCol++){ + aiOut[iCol*3 + 1] = (u32)pCsr->nDoc; + aiOut[iCol*3 + 2] = (u32)pCsr->nDoc; + } + }else{ + rc = fts3EvalGatherStats(pCsr, pExpr); + if( rc==SQLITE_OK ){ + assert( pExpr->aMI ); + for(iCol=0; iColnColumn; iCol++){ + aiOut[iCol*3 + 1] = pExpr->aMI[iCol*3 + 1]; + aiOut[iCol*3 + 2] = pExpr->aMI[iCol*3 + 2]; + } + } + } + + return rc; +} + +/* +** The expression pExpr passed as the second argument to this function +** must be of type FTSQUERY_PHRASE. +** +** The returned value is either NULL or a pointer to a buffer containing +** a position-list indicating the occurrences of the phrase in column iCol +** of the current row. +** +** More specifically, the returned buffer contains 1 varint for each +** occurrence of the phrase in the column, stored using the normal (delta+2) +** compression and is terminated by either an 0x01 or 0x00 byte. For example, +** if the requested column contains "a b X c d X X" and the position-list +** for 'X' is requested, the buffer returned may contain: +** +** 0x04 0x05 0x03 0x01 or 0x04 0x05 0x03 0x00 +** +** This function works regardless of whether or not the phrase is deferred, +** incremental, or neither. +*/ +SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist( + Fts3Cursor *pCsr, /* FTS3 cursor object */ + Fts3Expr *pExpr, /* Phrase to return doclist for */ + int iCol, /* Column to return position list for */ + char **ppOut /* OUT: Pointer to position list */ +){ + Fts3Phrase *pPhrase = pExpr->pPhrase; + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + char *pIter; + int iThis; + sqlite3_int64 iDocid; + + /* If this phrase is applies specifically to some column other than + ** column iCol, return a NULL pointer. */ + *ppOut = 0; + assert( iCol>=0 && iColnColumn ); + if( (pPhrase->iColumnnColumn && pPhrase->iColumn!=iCol) ){ + return SQLITE_OK; + } + + iDocid = pExpr->iDocid; + pIter = pPhrase->doclist.pList; + if( iDocid!=pCsr->iPrevId || pExpr->bEof ){ + int rc = SQLITE_OK; + int bDescDoclist = pTab->bDescIdx; /* For DOCID_CMP macro */ + int bOr = 0; + u8 bTreeEof = 0; + Fts3Expr *p; /* Used to iterate from pExpr to root */ + Fts3Expr *pNear; /* Most senior NEAR ancestor (or pExpr) */ + Fts3Expr *pRun; /* Closest non-deferred ancestor of pNear */ + int bMatch; + + /* Check if this phrase descends from an OR expression node. If not, + ** return NULL. Otherwise, the entry that corresponds to docid + ** pCsr->iPrevId may lie earlier in the doclist buffer. Or, if the + ** tree that the node is part of has been marked as EOF, but the node + ** itself is not EOF, then it may point to an earlier entry. */ + pNear = pExpr; + for(p=pExpr->pParent; p; p=p->pParent){ + if( p->eType==FTSQUERY_OR ) bOr = 1; + if( p->eType==FTSQUERY_NEAR ) pNear = p; + if( p->bEof ) bTreeEof = 1; + } + if( bOr==0 ) return SQLITE_OK; + pRun = pNear; + while( pRun->bDeferred ){ + assert( pRun->pParent ); + pRun = pRun->pParent; + } + + /* This is the descendent of an OR node. In this case we cannot use + ** an incremental phrase. Load the entire doclist for the phrase + ** into memory in this case. */ + if( pPhrase->bIncr ){ + int bEofSave = pRun->bEof; + fts3EvalRestart(pCsr, pRun, &rc); + while( rc==SQLITE_OK && !pRun->bEof ){ + fts3EvalNextRow(pCsr, pRun, &rc); + if( bEofSave==0 && pRun->iDocid==iDocid ) break; + } + assert( rc!=SQLITE_OK || pPhrase->bIncr==0 ); + if( rc==SQLITE_OK && pRun->bEof!=bEofSave ){ + rc = FTS_CORRUPT_VTAB; + } + } + if( bTreeEof ){ + while( rc==SQLITE_OK && !pRun->bEof ){ + fts3EvalNextRow(pCsr, pRun, &rc); + } + } + if( rc!=SQLITE_OK ) return rc; + + bMatch = 1; + for(p=pNear; p; p=p->pLeft){ + u8 bEof = 0; + Fts3Expr *pTest = p; + Fts3Phrase *pPh; + assert( pTest->eType==FTSQUERY_NEAR || pTest->eType==FTSQUERY_PHRASE ); + if( pTest->eType==FTSQUERY_NEAR ) pTest = pTest->pRight; + assert( pTest->eType==FTSQUERY_PHRASE ); + pPh = pTest->pPhrase; + + pIter = pPh->pOrPoslist; + iDocid = pPh->iOrDocid; + if( pCsr->bDesc==bDescDoclist ){ + bEof = !pPh->doclist.nAll || + (pIter >= (pPh->doclist.aAll + pPh->doclist.nAll)); + while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){ + sqlite3Fts3DoclistNext( + bDescDoclist, pPh->doclist.aAll, pPh->doclist.nAll, + &pIter, &iDocid, &bEof + ); + } + }else{ + bEof = !pPh->doclist.nAll || (pIter && pIter<=pPh->doclist.aAll); + while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){ + int dummy; + sqlite3Fts3DoclistPrev( + bDescDoclist, pPh->doclist.aAll, pPh->doclist.nAll, + &pIter, &iDocid, &dummy, &bEof + ); + } + } + pPh->pOrPoslist = pIter; + pPh->iOrDocid = iDocid; + if( bEof || iDocid!=pCsr->iPrevId ) bMatch = 0; + } + + if( bMatch ){ + pIter = pPhrase->pOrPoslist; + }else{ + pIter = 0; + } + } + if( pIter==0 ) return SQLITE_OK; + + if( *pIter==0x01 ){ + pIter++; + pIter += fts3GetVarint32(pIter, &iThis); + }else{ + iThis = 0; + } + while( iThisdoclist, and +** * any Fts3MultiSegReader objects held by phrase tokens. +*/ +SQLITE_PRIVATE void sqlite3Fts3EvalPhraseCleanup(Fts3Phrase *pPhrase){ + if( pPhrase ){ + int i; + sqlite3_free(pPhrase->doclist.aAll); + fts3EvalInvalidatePoslist(pPhrase); + memset(&pPhrase->doclist, 0, sizeof(Fts3Doclist)); + for(i=0; inToken; i++){ + fts3SegReaderCursorFree(pPhrase->aToken[i].pSegcsr); + pPhrase->aToken[i].pSegcsr = 0; + } + } +} + + +/* +** Return SQLITE_CORRUPT_VTAB. +*/ +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3Fts3Corrupt(){ + return SQLITE_CORRUPT_VTAB; +} +#endif + +#if !defined(SQLITE_CORE) +/* +** Initialize API pointer table, if required. +*/ +#ifdef _WIN32 +__declspec(dllexport) +#endif +SQLITE_API int sqlite3_fts3_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + SQLITE_EXTENSION_INIT2(pApi) + return sqlite3Fts3Init(db); +} +#endif + +#endif + +/************** End of fts3.c ************************************************/ +/************** Begin file fts3_aux.c ****************************************/ +/* +** 2011 Jan 27 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +*/ +/* #include "fts3Int.h" */ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include */ +/* #include */ + +typedef struct Fts3auxTable Fts3auxTable; +typedef struct Fts3auxCursor Fts3auxCursor; + +struct Fts3auxTable { + sqlite3_vtab base; /* Base class used by SQLite core */ + Fts3Table *pFts3Tab; +}; + +struct Fts3auxCursor { + sqlite3_vtab_cursor base; /* Base class used by SQLite core */ + Fts3MultiSegReader csr; /* Must be right after "base" */ + Fts3SegFilter filter; + char *zStop; + int nStop; /* Byte-length of string zStop */ + int iLangid; /* Language id to query */ + int isEof; /* True if cursor is at EOF */ + sqlite3_int64 iRowid; /* Current rowid */ + + int iCol; /* Current value of 'col' column */ + int nStat; /* Size of aStat[] array */ + struct Fts3auxColstats { + sqlite3_int64 nDoc; /* 'documents' values for current csr row */ + sqlite3_int64 nOcc; /* 'occurrences' values for current csr row */ + } *aStat; +}; + +/* +** Schema of the terms table. +*/ +#define FTS3_AUX_SCHEMA \ + "CREATE TABLE x(term, col, documents, occurrences, languageid HIDDEN)" + +/* +** This function does all the work for both the xConnect and xCreate methods. +** These tables have no persistent representation of their own, so xConnect +** and xCreate are identical operations. +*/ +static int fts3auxConnectMethod( + sqlite3 *db, /* Database connection */ + void *pUnused, /* Unused */ + int argc, /* Number of elements in argv array */ + const char * const *argv, /* xCreate/xConnect argument array */ + sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ + char **pzErr /* OUT: sqlite3_malloc'd error message */ +){ + char const *zDb; /* Name of database (e.g. "main") */ + char const *zFts3; /* Name of fts3 table */ + int nDb; /* Result of strlen(zDb) */ + int nFts3; /* Result of strlen(zFts3) */ + sqlite3_int64 nByte; /* Bytes of space to allocate here */ + int rc; /* value returned by declare_vtab() */ + Fts3auxTable *p; /* Virtual table object to return */ + + UNUSED_PARAMETER(pUnused); + + /* The user should invoke this in one of two forms: + ** + ** CREATE VIRTUAL TABLE xxx USING fts4aux(fts4-table); + ** CREATE VIRTUAL TABLE xxx USING fts4aux(fts4-table-db, fts4-table); + */ + if( argc!=4 && argc!=5 ) goto bad_args; + + zDb = argv[1]; + nDb = (int)strlen(zDb); + if( argc==5 ){ + if( nDb==4 && 0==sqlite3_strnicmp("temp", zDb, 4) ){ + zDb = argv[3]; + nDb = (int)strlen(zDb); + zFts3 = argv[4]; + }else{ + goto bad_args; + } + }else{ + zFts3 = argv[3]; + } + nFts3 = (int)strlen(zFts3); + + rc = sqlite3_declare_vtab(db, FTS3_AUX_SCHEMA); + if( rc!=SQLITE_OK ) return rc; + + nByte = sizeof(Fts3auxTable) + sizeof(Fts3Table) + nDb + nFts3 + 2; + p = (Fts3auxTable *)sqlite3_malloc64(nByte); + if( !p ) return SQLITE_NOMEM; + memset(p, 0, nByte); + + p->pFts3Tab = (Fts3Table *)&p[1]; + p->pFts3Tab->zDb = (char *)&p->pFts3Tab[1]; + p->pFts3Tab->zName = &p->pFts3Tab->zDb[nDb+1]; + p->pFts3Tab->db = db; + p->pFts3Tab->nIndex = 1; + + memcpy((char *)p->pFts3Tab->zDb, zDb, nDb); + memcpy((char *)p->pFts3Tab->zName, zFts3, nFts3); + sqlite3Fts3Dequote((char *)p->pFts3Tab->zName); + + *ppVtab = (sqlite3_vtab *)p; + return SQLITE_OK; + + bad_args: + sqlite3Fts3ErrMsg(pzErr, "invalid arguments to fts4aux constructor"); + return SQLITE_ERROR; +} + +/* +** This function does the work for both the xDisconnect and xDestroy methods. +** These tables have no persistent representation of their own, so xDisconnect +** and xDestroy are identical operations. +*/ +static int fts3auxDisconnectMethod(sqlite3_vtab *pVtab){ + Fts3auxTable *p = (Fts3auxTable *)pVtab; + Fts3Table *pFts3 = p->pFts3Tab; + int i; + + /* Free any prepared statements held */ + for(i=0; iaStmt); i++){ + sqlite3_finalize(pFts3->aStmt[i]); + } + sqlite3_free(pFts3->zSegmentsTbl); + sqlite3_free(p); + return SQLITE_OK; +} + +#define FTS4AUX_EQ_CONSTRAINT 1 +#define FTS4AUX_GE_CONSTRAINT 2 +#define FTS4AUX_LE_CONSTRAINT 4 + +/* +** xBestIndex - Analyze a WHERE and ORDER BY clause. +*/ +static int fts3auxBestIndexMethod( + sqlite3_vtab *pVTab, + sqlite3_index_info *pInfo +){ + int i; + int iEq = -1; + int iGe = -1; + int iLe = -1; + int iLangid = -1; + int iNext = 1; /* Next free argvIndex value */ + + UNUSED_PARAMETER(pVTab); + + /* This vtab delivers always results in "ORDER BY term ASC" order. */ + if( pInfo->nOrderBy==1 + && pInfo->aOrderBy[0].iColumn==0 + && pInfo->aOrderBy[0].desc==0 + ){ + pInfo->orderByConsumed = 1; + } + + /* Search for equality and range constraints on the "term" column. + ** And equality constraints on the hidden "languageid" column. */ + for(i=0; inConstraint; i++){ + if( pInfo->aConstraint[i].usable ){ + int op = pInfo->aConstraint[i].op; + int iCol = pInfo->aConstraint[i].iColumn; + + if( iCol==0 ){ + if( op==SQLITE_INDEX_CONSTRAINT_EQ ) iEq = i; + if( op==SQLITE_INDEX_CONSTRAINT_LT ) iLe = i; + if( op==SQLITE_INDEX_CONSTRAINT_LE ) iLe = i; + if( op==SQLITE_INDEX_CONSTRAINT_GT ) iGe = i; + if( op==SQLITE_INDEX_CONSTRAINT_GE ) iGe = i; + } + if( iCol==4 ){ + if( op==SQLITE_INDEX_CONSTRAINT_EQ ) iLangid = i; + } + } + } + + if( iEq>=0 ){ + pInfo->idxNum = FTS4AUX_EQ_CONSTRAINT; + pInfo->aConstraintUsage[iEq].argvIndex = iNext++; + pInfo->estimatedCost = 5; + }else{ + pInfo->idxNum = 0; + pInfo->estimatedCost = 20000; + if( iGe>=0 ){ + pInfo->idxNum += FTS4AUX_GE_CONSTRAINT; + pInfo->aConstraintUsage[iGe].argvIndex = iNext++; + pInfo->estimatedCost /= 2; + } + if( iLe>=0 ){ + pInfo->idxNum += FTS4AUX_LE_CONSTRAINT; + pInfo->aConstraintUsage[iLe].argvIndex = iNext++; + pInfo->estimatedCost /= 2; + } + } + if( iLangid>=0 ){ + pInfo->aConstraintUsage[iLangid].argvIndex = iNext++; + pInfo->estimatedCost--; + } + + return SQLITE_OK; +} + +/* +** xOpen - Open a cursor. +*/ +static int fts3auxOpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ + Fts3auxCursor *pCsr; /* Pointer to cursor object to return */ + + UNUSED_PARAMETER(pVTab); + + pCsr = (Fts3auxCursor *)sqlite3_malloc(sizeof(Fts3auxCursor)); + if( !pCsr ) return SQLITE_NOMEM; + memset(pCsr, 0, sizeof(Fts3auxCursor)); + + *ppCsr = (sqlite3_vtab_cursor *)pCsr; + return SQLITE_OK; +} + +/* +** xClose - Close a cursor. +*/ +static int fts3auxCloseMethod(sqlite3_vtab_cursor *pCursor){ + Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab; + Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; + + sqlite3Fts3SegmentsClose(pFts3); + sqlite3Fts3SegReaderFinish(&pCsr->csr); + sqlite3_free((void *)pCsr->filter.zTerm); + sqlite3_free(pCsr->zStop); + sqlite3_free(pCsr->aStat); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +static int fts3auxGrowStatArray(Fts3auxCursor *pCsr, int nSize){ + if( nSize>pCsr->nStat ){ + struct Fts3auxColstats *aNew; + aNew = (struct Fts3auxColstats *)sqlite3_realloc64(pCsr->aStat, + sizeof(struct Fts3auxColstats) * nSize + ); + if( aNew==0 ) return SQLITE_NOMEM; + memset(&aNew[pCsr->nStat], 0, + sizeof(struct Fts3auxColstats) * (nSize - pCsr->nStat) + ); + pCsr->aStat = aNew; + pCsr->nStat = nSize; + } + return SQLITE_OK; +} + +/* +** xNext - Advance the cursor to the next row, if any. +*/ +static int fts3auxNextMethod(sqlite3_vtab_cursor *pCursor){ + Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; + Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab; + int rc; + + /* Increment our pretend rowid value. */ + pCsr->iRowid++; + + for(pCsr->iCol++; pCsr->iColnStat; pCsr->iCol++){ + if( pCsr->aStat[pCsr->iCol].nDoc>0 ) return SQLITE_OK; + } + + rc = sqlite3Fts3SegReaderStep(pFts3, &pCsr->csr); + if( rc==SQLITE_ROW ){ + int i = 0; + int nDoclist = pCsr->csr.nDoclist; + char *aDoclist = pCsr->csr.aDoclist; + int iCol; + + int eState = 0; + + if( pCsr->zStop ){ + int n = (pCsr->nStopcsr.nTerm) ? pCsr->nStop : pCsr->csr.nTerm; + int mc = memcmp(pCsr->zStop, pCsr->csr.zTerm, n); + if( mc<0 || (mc==0 && pCsr->csr.nTerm>pCsr->nStop) ){ + pCsr->isEof = 1; + return SQLITE_OK; + } + } + + if( fts3auxGrowStatArray(pCsr, 2) ) return SQLITE_NOMEM; + memset(pCsr->aStat, 0, sizeof(struct Fts3auxColstats) * pCsr->nStat); + iCol = 0; + rc = SQLITE_OK; + + while( iaStat[0].nDoc++; + eState = 1; + iCol = 0; + break; + + /* State 1. In this state we are expecting either a 1, indicating + ** that the following integer will be a column number, or the + ** start of a position list for column 0. + ** + ** The only difference between state 1 and state 2 is that if the + ** integer encountered in state 1 is not 0 or 1, then we need to + ** increment the column 0 "nDoc" count for this term. + */ + case 1: + assert( iCol==0 ); + if( v>1 ){ + pCsr->aStat[1].nDoc++; + } + eState = 2; + /* no break */ deliberate_fall_through + + case 2: + if( v==0 ){ /* 0x00. Next integer will be a docid. */ + eState = 0; + }else if( v==1 ){ /* 0x01. Next integer will be a column number. */ + eState = 3; + }else{ /* 2 or greater. A position. */ + pCsr->aStat[iCol+1].nOcc++; + pCsr->aStat[0].nOcc++; + } + break; + + /* State 3. The integer just read is a column number. */ + default: assert( eState==3 ); + iCol = (int)v; + if( iCol<1 || iCol>(pFts3->nColumn+1) ){ + rc = SQLITE_CORRUPT_VTAB; + break; + } + if( fts3auxGrowStatArray(pCsr, iCol+2) ) return SQLITE_NOMEM; + pCsr->aStat[iCol+1].nDoc++; + eState = 2; + break; + } + } + + pCsr->iCol = 0; + }else{ + pCsr->isEof = 1; + } + return rc; +} + +/* +** xFilter - Initialize a cursor to point at the start of its data. +*/ +static int fts3auxFilterMethod( + sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ + int idxNum, /* Strategy index */ + const char *idxStr, /* Unused */ + int nVal, /* Number of elements in apVal */ + sqlite3_value **apVal /* Arguments for the indexing scheme */ +){ + Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; + Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab; + int rc; + int isScan = 0; + int iLangVal = 0; /* Language id to query */ + + int iEq = -1; /* Index of term=? value in apVal */ + int iGe = -1; /* Index of term>=? value in apVal */ + int iLe = -1; /* Index of term<=? value in apVal */ + int iLangid = -1; /* Index of languageid=? value in apVal */ + int iNext = 0; + + UNUSED_PARAMETER(nVal); + UNUSED_PARAMETER(idxStr); + + assert( idxStr==0 ); + assert( idxNum==FTS4AUX_EQ_CONSTRAINT || idxNum==0 + || idxNum==FTS4AUX_LE_CONSTRAINT || idxNum==FTS4AUX_GE_CONSTRAINT + || idxNum==(FTS4AUX_LE_CONSTRAINT|FTS4AUX_GE_CONSTRAINT) + ); + + if( idxNum==FTS4AUX_EQ_CONSTRAINT ){ + iEq = iNext++; + }else{ + isScan = 1; + if( idxNum & FTS4AUX_GE_CONSTRAINT ){ + iGe = iNext++; + } + if( idxNum & FTS4AUX_LE_CONSTRAINT ){ + iLe = iNext++; + } + } + if( iNextfilter.zTerm); + sqlite3Fts3SegReaderFinish(&pCsr->csr); + sqlite3_free((void *)pCsr->filter.zTerm); + sqlite3_free(pCsr->aStat); + sqlite3_free(pCsr->zStop); + memset(&pCsr->csr, 0, ((u8*)&pCsr[1]) - (u8*)&pCsr->csr); + + pCsr->filter.flags = FTS3_SEGMENT_REQUIRE_POS|FTS3_SEGMENT_IGNORE_EMPTY; + if( isScan ) pCsr->filter.flags |= FTS3_SEGMENT_SCAN; + + if( iEq>=0 || iGe>=0 ){ + const unsigned char *zStr = sqlite3_value_text(apVal[0]); + assert( (iEq==0 && iGe==-1) || (iEq==-1 && iGe==0) ); + if( zStr ){ + pCsr->filter.zTerm = sqlite3_mprintf("%s", zStr); + if( pCsr->filter.zTerm==0 ) return SQLITE_NOMEM; + pCsr->filter.nTerm = (int)strlen(pCsr->filter.zTerm); + } + } + + if( iLe>=0 ){ + pCsr->zStop = sqlite3_mprintf("%s", sqlite3_value_text(apVal[iLe])); + if( pCsr->zStop==0 ) return SQLITE_NOMEM; + pCsr->nStop = (int)strlen(pCsr->zStop); + } + + if( iLangid>=0 ){ + iLangVal = sqlite3_value_int(apVal[iLangid]); + + /* If the user specified a negative value for the languageid, use zero + ** instead. This works, as the "languageid=?" constraint will also + ** be tested by the VDBE layer. The test will always be false (since + ** this module will not return a row with a negative languageid), and + ** so the overall query will return zero rows. */ + if( iLangVal<0 ) iLangVal = 0; + } + pCsr->iLangid = iLangVal; + + rc = sqlite3Fts3SegReaderCursor(pFts3, iLangVal, 0, FTS3_SEGCURSOR_ALL, + pCsr->filter.zTerm, pCsr->filter.nTerm, 0, isScan, &pCsr->csr + ); + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3SegReaderStart(pFts3, &pCsr->csr, &pCsr->filter); + } + + if( rc==SQLITE_OK ) rc = fts3auxNextMethod(pCursor); + return rc; +} + +/* +** xEof - Return true if the cursor is at EOF, or false otherwise. +*/ +static int fts3auxEofMethod(sqlite3_vtab_cursor *pCursor){ + Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; + return pCsr->isEof; +} + +/* +** xColumn - Return a column value. +*/ +static int fts3auxColumnMethod( + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ + sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */ + int iCol /* Index of column to read value from */ +){ + Fts3auxCursor *p = (Fts3auxCursor *)pCursor; + + assert( p->isEof==0 ); + switch( iCol ){ + case 0: /* term */ + sqlite3_result_text(pCtx, p->csr.zTerm, p->csr.nTerm, SQLITE_TRANSIENT); + break; + + case 1: /* col */ + if( p->iCol ){ + sqlite3_result_int(pCtx, p->iCol-1); + }else{ + sqlite3_result_text(pCtx, "*", -1, SQLITE_STATIC); + } + break; + + case 2: /* documents */ + sqlite3_result_int64(pCtx, p->aStat[p->iCol].nDoc); + break; + + case 3: /* occurrences */ + sqlite3_result_int64(pCtx, p->aStat[p->iCol].nOcc); + break; + + default: /* languageid */ + assert( iCol==4 ); + sqlite3_result_int(pCtx, p->iLangid); + break; + } + + return SQLITE_OK; +} + +/* +** xRowid - Return the current rowid for the cursor. +*/ +static int fts3auxRowidMethod( + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ + sqlite_int64 *pRowid /* OUT: Rowid value */ +){ + Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; + *pRowid = pCsr->iRowid; + return SQLITE_OK; +} + +/* +** Register the fts3aux module with database connection db. Return SQLITE_OK +** if successful or an error code if sqlite3_create_module() fails. +*/ +SQLITE_PRIVATE int sqlite3Fts3InitAux(sqlite3 *db){ + static const sqlite3_module fts3aux_module = { + 0, /* iVersion */ + fts3auxConnectMethod, /* xCreate */ + fts3auxConnectMethod, /* xConnect */ + fts3auxBestIndexMethod, /* xBestIndex */ + fts3auxDisconnectMethod, /* xDisconnect */ + fts3auxDisconnectMethod, /* xDestroy */ + fts3auxOpenMethod, /* xOpen */ + fts3auxCloseMethod, /* xClose */ + fts3auxFilterMethod, /* xFilter */ + fts3auxNextMethod, /* xNext */ + fts3auxEofMethod, /* xEof */ + fts3auxColumnMethod, /* xColumn */ + fts3auxRowidMethod, /* xRowid */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindFunction */ + 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ + }; + int rc; /* Return code */ + + rc = sqlite3_create_module(db, "fts4aux", &fts3aux_module, 0); + return rc; +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_aux.c ********************************************/ +/************** Begin file fts3_expr.c ***************************************/ +/* +** 2008 Nov 28 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This module contains code that implements a parser for fts3 query strings +** (the right-hand argument to the MATCH operator). Because the supported +** syntax is relatively simple, the whole tokenizer/parser system is +** hand-coded. +*/ +/* #include "fts3Int.h" */ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* +** By default, this module parses the legacy syntax that has been +** traditionally used by fts3. Or, if SQLITE_ENABLE_FTS3_PARENTHESIS +** is defined, then it uses the new syntax. The differences between +** the new and the old syntaxes are: +** +** a) The new syntax supports parenthesis. The old does not. +** +** b) The new syntax supports the AND and NOT operators. The old does not. +** +** c) The old syntax supports the "-" token qualifier. This is not +** supported by the new syntax (it is replaced by the NOT operator). +** +** d) When using the old syntax, the OR operator has a greater precedence +** than an implicit AND. When using the new, both implicity and explicit +** AND operators have a higher precedence than OR. +** +** If compiled with SQLITE_TEST defined, then this module exports the +** symbol "int sqlite3_fts3_enable_parentheses". Setting this variable +** to zero causes the module to use the old syntax. If it is set to +** non-zero the new syntax is activated. This is so both syntaxes can +** be tested using a single build of testfixture. +** +** The following describes the syntax supported by the fts3 MATCH +** operator in a similar format to that used by the lemon parser +** generator. This module does not use actually lemon, it uses a +** custom parser. +** +** query ::= andexpr (OR andexpr)*. +** +** andexpr ::= notexpr (AND? notexpr)*. +** +** notexpr ::= nearexpr (NOT nearexpr|-TOKEN)*. +** notexpr ::= LP query RP. +** +** nearexpr ::= phrase (NEAR distance_opt nearexpr)*. +** +** distance_opt ::= . +** distance_opt ::= / INTEGER. +** +** phrase ::= TOKEN. +** phrase ::= COLUMN:TOKEN. +** phrase ::= "TOKEN TOKEN TOKEN...". +*/ + +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_fts3_enable_parentheses = 0; +#else +# ifdef SQLITE_ENABLE_FTS3_PARENTHESIS +# define sqlite3_fts3_enable_parentheses 1 +# else +# define sqlite3_fts3_enable_parentheses 0 +# endif +#endif + +/* +** Default span for NEAR operators. +*/ +#define SQLITE_FTS3_DEFAULT_NEAR_PARAM 10 + +/* #include */ +/* #include */ + +/* +** isNot: +** This variable is used by function getNextNode(). When getNextNode() is +** called, it sets ParseContext.isNot to true if the 'next node' is a +** FTSQUERY_PHRASE with a unary "-" attached to it. i.e. "mysql" in the +** FTS3 query "sqlite -mysql". Otherwise, ParseContext.isNot is set to +** zero. +*/ +typedef struct ParseContext ParseContext; +struct ParseContext { + sqlite3_tokenizer *pTokenizer; /* Tokenizer module */ + int iLangid; /* Language id used with tokenizer */ + const char **azCol; /* Array of column names for fts3 table */ + int bFts4; /* True to allow FTS4-only syntax */ + int nCol; /* Number of entries in azCol[] */ + int iDefaultCol; /* Default column to query */ + int isNot; /* True if getNextNode() sees a unary - */ + sqlite3_context *pCtx; /* Write error message here */ + int nNest; /* Number of nested brackets */ +}; + +/* +** This function is equivalent to the standard isspace() function. +** +** The standard isspace() can be awkward to use safely, because although it +** is defined to accept an argument of type int, its behavior when passed +** an integer that falls outside of the range of the unsigned char type +** is undefined (and sometimes, "undefined" means segfault). This wrapper +** is defined to accept an argument of type char, and always returns 0 for +** any values that fall outside of the range of the unsigned char type (i.e. +** negative values). +*/ +static int fts3isspace(char c){ + return c==' ' || c=='\t' || c=='\n' || c=='\r' || c=='\v' || c=='\f'; +} + +/* +** Allocate nByte bytes of memory using sqlite3_malloc(). If successful, +** zero the memory before returning a pointer to it. If unsuccessful, +** return NULL. +*/ +SQLITE_PRIVATE void *sqlite3Fts3MallocZero(sqlite3_int64 nByte){ + void *pRet = sqlite3_malloc64(nByte); + if( pRet ) memset(pRet, 0, nByte); + return pRet; +} + +SQLITE_PRIVATE int sqlite3Fts3OpenTokenizer( + sqlite3_tokenizer *pTokenizer, + int iLangid, + const char *z, + int n, + sqlite3_tokenizer_cursor **ppCsr +){ + sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; + sqlite3_tokenizer_cursor *pCsr = 0; + int rc; + + rc = pModule->xOpen(pTokenizer, z, n, &pCsr); + assert( rc==SQLITE_OK || pCsr==0 ); + if( rc==SQLITE_OK ){ + pCsr->pTokenizer = pTokenizer; + if( pModule->iVersion>=1 ){ + rc = pModule->xLanguageid(pCsr, iLangid); + if( rc!=SQLITE_OK ){ + pModule->xClose(pCsr); + pCsr = 0; + } + } + } + *ppCsr = pCsr; + return rc; +} + +/* +** Function getNextNode(), which is called by fts3ExprParse(), may itself +** call fts3ExprParse(). So this forward declaration is required. +*/ +static int fts3ExprParse(ParseContext *, const char *, int, Fts3Expr **, int *); + +/* +** Search buffer z[], size n, for a '"' character. Or, if enable_parenthesis +** is defined, search for '(' and ')' as well. Return the index of the first +** such character in the buffer. If there is no such character, return -1. +*/ +static int findBarredChar(const char *z, int n){ + int ii; + for(ii=0; iipTokenizer; + sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; + int rc; + sqlite3_tokenizer_cursor *pCursor; + Fts3Expr *pRet = 0; + + *pnConsumed = n; + rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, n, &pCursor); + if( rc==SQLITE_OK ){ + const char *zToken; + int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0; + sqlite3_int64 nByte; /* total space to allocate */ + + rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition); + if( rc==SQLITE_OK ){ + /* Check that this tokenization did not gobble up any " characters. Or, + ** if enable_parenthesis is true, that it did not gobble up any + ** open or close parenthesis characters either. If it did, call + ** getNextToken() again, but pass only that part of the input buffer + ** up to the first such character. */ + int iBarred = findBarredChar(z, iEnd); + if( iBarred>=0 ){ + pModule->xClose(pCursor); + return getNextToken(pParse, iCol, z, iBarred, ppExpr, pnConsumed); + } + + nByte = sizeof(Fts3Expr) + SZ_FTS3PHRASE(1) + nToken; + pRet = (Fts3Expr *)sqlite3Fts3MallocZero(nByte); + if( !pRet ){ + rc = SQLITE_NOMEM; + }else{ + pRet->eType = FTSQUERY_PHRASE; + pRet->pPhrase = (Fts3Phrase *)&pRet[1]; + pRet->pPhrase->nToken = 1; + pRet->pPhrase->iColumn = iCol; + pRet->pPhrase->aToken[0].n = nToken; + pRet->pPhrase->aToken[0].z = (char*)&pRet->pPhrase->aToken[1]; + memcpy(pRet->pPhrase->aToken[0].z, zToken, nToken); + + if( iEndpPhrase->aToken[0].isPrefix = 1; + iEnd++; + } + + while( 1 ){ + if( !sqlite3_fts3_enable_parentheses + && iStart>0 && z[iStart-1]=='-' + ){ + pParse->isNot = 1; + iStart--; + }else if( pParse->bFts4 && iStart>0 && z[iStart-1]=='^' ){ + pRet->pPhrase->aToken[0].bFirst = 1; + iStart--; + }else{ + break; + } + } + + } + *pnConsumed = iEnd; + }else if( n && rc==SQLITE_DONE ){ + int iBarred = findBarredChar(z, n); + if( iBarred>=0 ){ + *pnConsumed = iBarred; + } + rc = SQLITE_OK; + } + + pModule->xClose(pCursor); + } + + *ppExpr = pRet; + return rc; +} + + +/* +** Enlarge a memory allocation. If an out-of-memory allocation occurs, +** then free the old allocation. +*/ +static void *fts3ReallocOrFree(void *pOrig, sqlite3_int64 nNew){ + void *pRet = sqlite3_realloc64(pOrig, nNew); + if( !pRet ){ + sqlite3_free(pOrig); + } + return pRet; +} + +/* +** Buffer zInput, length nInput, contains the contents of a quoted string +** that appeared as part of an fts3 query expression. Neither quote character +** is included in the buffer. This function attempts to tokenize the entire +** input buffer and create an Fts3Expr structure of type FTSQUERY_PHRASE +** containing the results. +** +** If successful, SQLITE_OK is returned and *ppExpr set to point at the +** allocated Fts3Expr structure. Otherwise, either SQLITE_NOMEM (out of memory +** error) or SQLITE_ERROR (tokenization error) is returned and *ppExpr set +** to 0. +*/ +static int getNextString( + ParseContext *pParse, /* fts3 query parse context */ + const char *zInput, int nInput, /* Input string */ + Fts3Expr **ppExpr /* OUT: expression */ +){ + sqlite3_tokenizer *pTokenizer = pParse->pTokenizer; + sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; + int rc; + Fts3Expr *p = 0; + sqlite3_tokenizer_cursor *pCursor = 0; + char *zTemp = 0; + i64 nTemp = 0; + + const int nSpace = sizeof(Fts3Expr) + SZ_FTS3PHRASE(1); + int nToken = 0; + + /* The final Fts3Expr data structure, including the Fts3Phrase, + ** Fts3PhraseToken structures token buffers are all stored as a single + ** allocation so that the expression can be freed with a single call to + ** sqlite3_free(). Setting this up requires a two pass approach. + ** + ** The first pass, in the block below, uses a tokenizer cursor to iterate + ** through the tokens in the expression. This pass uses fts3ReallocOrFree() + ** to assemble data in two dynamic buffers: + ** + ** Buffer p: Points to the Fts3Expr structure, followed by the Fts3Phrase + ** structure, followed by the array of Fts3PhraseToken + ** structures. This pass only populates the Fts3PhraseToken array. + ** + ** Buffer zTemp: Contains copies of all tokens. + ** + ** The second pass, in the block that begins "if( rc==SQLITE_DONE )" below, + ** appends buffer zTemp to buffer p, and fills in the Fts3Expr and Fts3Phrase + ** structures. + */ + rc = sqlite3Fts3OpenTokenizer( + pTokenizer, pParse->iLangid, zInput, nInput, &pCursor); + if( rc==SQLITE_OK ){ + int ii; + for(ii=0; rc==SQLITE_OK; ii++){ + const char *zByte; + int nByte = 0, iBegin = 0, iEnd = 0, iPos = 0; + rc = pModule->xNext(pCursor, &zByte, &nByte, &iBegin, &iEnd, &iPos); + if( rc==SQLITE_OK ){ + Fts3PhraseToken *pToken; + + p = fts3ReallocOrFree(p, nSpace + ii*sizeof(Fts3PhraseToken)); + zTemp = fts3ReallocOrFree(zTemp, nTemp + nByte); + if( !zTemp || !p ){ + rc = SQLITE_NOMEM; + goto getnextstring_out; + } + + assert( nToken==ii ); + pToken = &((Fts3Phrase *)(&p[1]))->aToken[ii]; + memset(pToken, 0, sizeof(Fts3PhraseToken)); + + memcpy(&zTemp[nTemp], zByte, nByte); + nTemp += nByte; + + pToken->n = nByte; + pToken->isPrefix = (iEndbFirst = (iBegin>0 && zInput[iBegin-1]=='^'); + nToken = ii+1; + } + } + } + + if( rc==SQLITE_DONE ){ + int jj; + char *zBuf = 0; + + p = fts3ReallocOrFree(p, nSpace + nToken*sizeof(Fts3PhraseToken) + nTemp); + if( !p ){ + rc = SQLITE_NOMEM; + goto getnextstring_out; + } + memset(p, 0, (char *)&(((Fts3Phrase *)&p[1])->aToken[0])-(char *)p); + p->eType = FTSQUERY_PHRASE; + p->pPhrase = (Fts3Phrase *)&p[1]; + p->pPhrase->iColumn = pParse->iDefaultCol; + p->pPhrase->nToken = nToken; + + zBuf = (char *)&p->pPhrase->aToken[nToken]; + assert( nTemp==0 || zTemp ); + if( zTemp ){ + memcpy(zBuf, zTemp, nTemp); + } + + for(jj=0; jjpPhrase->nToken; jj++){ + p->pPhrase->aToken[jj].z = zBuf; + zBuf += p->pPhrase->aToken[jj].n; + } + rc = SQLITE_OK; + } + + getnextstring_out: + if( pCursor ){ + pModule->xClose(pCursor); + } + sqlite3_free(zTemp); + if( rc!=SQLITE_OK ){ + sqlite3_free(p); + p = 0; + } + *ppExpr = p; + return rc; +} + +/* +** The output variable *ppExpr is populated with an allocated Fts3Expr +** structure, or set to 0 if the end of the input buffer is reached. +** +** Returns an SQLite error code. SQLITE_OK if everything works, SQLITE_NOMEM +** if a malloc failure occurs, or SQLITE_ERROR if a parse error is encountered. +** If SQLITE_ERROR is returned, pContext is populated with an error message. +*/ +static int getNextNode( + ParseContext *pParse, /* fts3 query parse context */ + const char *z, int n, /* Input string */ + Fts3Expr **ppExpr, /* OUT: expression */ + int *pnConsumed /* OUT: Number of bytes consumed */ +){ + static const struct Fts3Keyword { + char *z; /* Keyword text */ + unsigned char n; /* Length of the keyword */ + unsigned char parenOnly; /* Only valid in paren mode */ + unsigned char eType; /* Keyword code */ + } aKeyword[] = { + { "OR" , 2, 0, FTSQUERY_OR }, + { "AND", 3, 1, FTSQUERY_AND }, + { "NOT", 3, 1, FTSQUERY_NOT }, + { "NEAR", 4, 0, FTSQUERY_NEAR } + }; + int ii; + int iCol; + int iColLen; + int rc; + Fts3Expr *pRet = 0; + + const char *zInput = z; + int nInput = n; + + pParse->isNot = 0; + + /* Skip over any whitespace before checking for a keyword, an open or + ** close bracket, or a quoted string. + */ + while( nInput>0 && fts3isspace(*zInput) ){ + nInput--; + zInput++; + } + if( nInput==0 ){ + return SQLITE_DONE; + } + + /* See if we are dealing with a keyword. */ + for(ii=0; ii<(int)(sizeof(aKeyword)/sizeof(struct Fts3Keyword)); ii++){ + const struct Fts3Keyword *pKey = &aKeyword[ii]; + + if( (pKey->parenOnly & ~sqlite3_fts3_enable_parentheses)!=0 ){ + continue; + } + + if( nInput>=pKey->n && 0==memcmp(zInput, pKey->z, pKey->n) ){ + int nNear = SQLITE_FTS3_DEFAULT_NEAR_PARAM; + int nKey = pKey->n; + char cNext; + + /* If this is a "NEAR" keyword, check for an explicit nearness. */ + if( pKey->eType==FTSQUERY_NEAR ){ + assert( nKey==4 ); + if( zInput[4]=='/' && zInput[5]>='0' && zInput[5]<='9' ){ + nKey += 1+sqlite3Fts3ReadInt(&zInput[nKey+1], &nNear); + if( nNear>=1000000000 ) nNear = 1000000000; + } + } + + /* At this point this is probably a keyword. But for that to be true, + ** the next byte must contain either whitespace, an open or close + ** parenthesis, a quote character, or EOF. + */ + cNext = zInput[nKey]; + if( fts3isspace(cNext) + || cNext=='"' || cNext=='(' || cNext==')' || cNext==0 + ){ + pRet = (Fts3Expr *)sqlite3Fts3MallocZero(sizeof(Fts3Expr)); + if( !pRet ){ + return SQLITE_NOMEM; + } + pRet->eType = pKey->eType; + pRet->nNear = nNear; + *ppExpr = pRet; + *pnConsumed = (int)((zInput - z) + nKey); + return SQLITE_OK; + } + + /* Turns out that wasn't a keyword after all. This happens if the + ** user has supplied a token such as "ORacle". Continue. + */ + } + } + + /* See if we are dealing with a quoted phrase. If this is the case, then + ** search for the closing quote and pass the whole string to getNextString() + ** for processing. This is easy to do, as fts3 has no syntax for escaping + ** a quote character embedded in a string. + */ + if( *zInput=='"' ){ + for(ii=1; iinNest++; +#if !defined(SQLITE_MAX_EXPR_DEPTH) + if( pParse->nNest>1000 ) return SQLITE_ERROR; +#elif SQLITE_MAX_EXPR_DEPTH>0 + if( pParse->nNest>SQLITE_MAX_EXPR_DEPTH ) return SQLITE_ERROR; +#endif + rc = fts3ExprParse(pParse, zInput+1, nInput-1, ppExpr, &nConsumed); + *pnConsumed = (int)(zInput - z) + 1 + nConsumed; + return rc; + }else if( *zInput==')' ){ + pParse->nNest--; + *pnConsumed = (int)((zInput - z) + 1); + *ppExpr = 0; + return SQLITE_DONE; + } + } + + /* If control flows to this point, this must be a regular token, or + ** the end of the input. Read a regular token using the sqlite3_tokenizer + ** interface. Before doing so, figure out if there is an explicit + ** column specifier for the token. + ** + ** TODO: Strangely, it is not possible to associate a column specifier + ** with a quoted phrase, only with a single token. Not sure if this was + ** an implementation artifact or an intentional decision when fts3 was + ** first implemented. Whichever it was, this module duplicates the + ** limitation. + */ + iCol = pParse->iDefaultCol; + iColLen = 0; + for(ii=0; iinCol; ii++){ + const char *zStr = pParse->azCol[ii]; + int nStr = (int)strlen(zStr); + if( nInput>nStr && zInput[nStr]==':' + && sqlite3_strnicmp(zStr, zInput, nStr)==0 + ){ + iCol = ii; + iColLen = (int)((zInput - z) + nStr + 1); + break; + } + } + rc = getNextToken(pParse, iCol, &z[iColLen], n-iColLen, ppExpr, pnConsumed); + *pnConsumed += iColLen; + return rc; +} + +/* +** The argument is an Fts3Expr structure for a binary operator (any type +** except an FTSQUERY_PHRASE). Return an integer value representing the +** precedence of the operator. Lower values have a higher precedence (i.e. +** group more tightly). For example, in the C language, the == operator +** groups more tightly than ||, and would therefore have a higher precedence. +** +** When using the new fts3 query syntax (when SQLITE_ENABLE_FTS3_PARENTHESIS +** is defined), the order of the operators in precedence from highest to +** lowest is: +** +** NEAR +** NOT +** AND (including implicit ANDs) +** OR +** +** Note that when using the old query syntax, the OR operator has a higher +** precedence than the AND operator. +*/ +static int opPrecedence(Fts3Expr *p){ + assert( p->eType!=FTSQUERY_PHRASE ); + if( sqlite3_fts3_enable_parentheses ){ + return p->eType; + }else if( p->eType==FTSQUERY_NEAR ){ + return 1; + }else if( p->eType==FTSQUERY_OR ){ + return 2; + } + assert( p->eType==FTSQUERY_AND ); + return 3; +} + +/* +** Argument ppHead contains a pointer to the current head of a query +** expression tree being parsed. pPrev is the expression node most recently +** inserted into the tree. This function adds pNew, which is always a binary +** operator node, into the expression tree based on the relative precedence +** of pNew and the existing nodes of the tree. This may result in the head +** of the tree changing, in which case *ppHead is set to the new root node. +*/ +static void insertBinaryOperator( + Fts3Expr **ppHead, /* Pointer to the root node of a tree */ + Fts3Expr *pPrev, /* Node most recently inserted into the tree */ + Fts3Expr *pNew /* New binary node to insert into expression tree */ +){ + Fts3Expr *pSplit = pPrev; + while( pSplit->pParent && opPrecedence(pSplit->pParent)<=opPrecedence(pNew) ){ + pSplit = pSplit->pParent; + } + + if( pSplit->pParent ){ + assert( pSplit->pParent->pRight==pSplit ); + pSplit->pParent->pRight = pNew; + pNew->pParent = pSplit->pParent; + }else{ + *ppHead = pNew; + } + pNew->pLeft = pSplit; + pSplit->pParent = pNew; +} + +/* +** Parse the fts3 query expression found in buffer z, length n. This function +** returns either when the end of the buffer is reached or an unmatched +** closing bracket - ')' - is encountered. +** +** If successful, SQLITE_OK is returned, *ppExpr is set to point to the +** parsed form of the expression and *pnConsumed is set to the number of +** bytes read from buffer z. Otherwise, *ppExpr is set to 0 and SQLITE_NOMEM +** (out of memory error) or SQLITE_ERROR (parse error) is returned. +*/ +static int fts3ExprParse( + ParseContext *pParse, /* fts3 query parse context */ + const char *z, int n, /* Text of MATCH query */ + Fts3Expr **ppExpr, /* OUT: Parsed query structure */ + int *pnConsumed /* OUT: Number of bytes consumed */ +){ + Fts3Expr *pRet = 0; + Fts3Expr *pPrev = 0; + Fts3Expr *pNotBranch = 0; /* Only used in legacy parse mode */ + int nIn = n; + const char *zIn = z; + int rc = SQLITE_OK; + int isRequirePhrase = 1; + + while( rc==SQLITE_OK ){ + Fts3Expr *p = 0; + int nByte = 0; + + rc = getNextNode(pParse, zIn, nIn, &p, &nByte); + assert( nByte>0 || (rc!=SQLITE_OK && p==0) ); + if( rc==SQLITE_OK ){ + if( p ){ + int isPhrase; + + if( !sqlite3_fts3_enable_parentheses + && p->eType==FTSQUERY_PHRASE && pParse->isNot + ){ + /* Create an implicit NOT operator. */ + Fts3Expr *pNot = sqlite3Fts3MallocZero(sizeof(Fts3Expr)); + if( !pNot ){ + sqlite3Fts3ExprFree(p); + rc = SQLITE_NOMEM; + goto exprparse_out; + } + pNot->eType = FTSQUERY_NOT; + pNot->pRight = p; + p->pParent = pNot; + if( pNotBranch ){ + pNot->pLeft = pNotBranch; + pNotBranch->pParent = pNot; + } + pNotBranch = pNot; + p = pPrev; + }else{ + int eType = p->eType; + isPhrase = (eType==FTSQUERY_PHRASE || p->pLeft); + + /* The isRequirePhrase variable is set to true if a phrase or + ** an expression contained in parenthesis is required. If a + ** binary operator (AND, OR, NOT or NEAR) is encountered when + ** isRequirePhrase is set, this is a syntax error. + */ + if( !isPhrase && isRequirePhrase ){ + sqlite3Fts3ExprFree(p); + rc = SQLITE_ERROR; + goto exprparse_out; + } + + if( isPhrase && !isRequirePhrase ){ + /* Insert an implicit AND operator. */ + Fts3Expr *pAnd; + assert( pRet && pPrev ); + pAnd = sqlite3Fts3MallocZero(sizeof(Fts3Expr)); + if( !pAnd ){ + sqlite3Fts3ExprFree(p); + rc = SQLITE_NOMEM; + goto exprparse_out; + } + pAnd->eType = FTSQUERY_AND; + insertBinaryOperator(&pRet, pPrev, pAnd); + pPrev = pAnd; + } + + /* This test catches attempts to make either operand of a NEAR + ** operator something other than a phrase. For example, either of + ** the following: + ** + ** (bracketed expression) NEAR phrase + ** phrase NEAR (bracketed expression) + ** + ** Return an error in either case. + */ + if( pPrev && ( + (eType==FTSQUERY_NEAR && !isPhrase && pPrev->eType!=FTSQUERY_PHRASE) + || (eType!=FTSQUERY_PHRASE && isPhrase && pPrev->eType==FTSQUERY_NEAR) + )){ + sqlite3Fts3ExprFree(p); + rc = SQLITE_ERROR; + goto exprparse_out; + } + + if( isPhrase ){ + if( pRet ){ + assert( pPrev && pPrev->pLeft && pPrev->pRight==0 ); + pPrev->pRight = p; + p->pParent = pPrev; + }else{ + pRet = p; + } + }else{ + insertBinaryOperator(&pRet, pPrev, p); + } + isRequirePhrase = !isPhrase; + } + pPrev = p; + } + assert( nByte>0 ); + } + assert( rc!=SQLITE_OK || (nByte>0 && nByte<=nIn) ); + nIn -= nByte; + zIn += nByte; + } + + if( rc==SQLITE_DONE && pRet && isRequirePhrase ){ + rc = SQLITE_ERROR; + } + + if( rc==SQLITE_DONE ){ + rc = SQLITE_OK; + if( !sqlite3_fts3_enable_parentheses && pNotBranch ){ + if( !pRet ){ + rc = SQLITE_ERROR; + }else{ + Fts3Expr *pIter = pNotBranch; + while( pIter->pLeft ){ + pIter = pIter->pLeft; + } + pIter->pLeft = pRet; + pRet->pParent = pIter; + pRet = pNotBranch; + } + } + } + *pnConsumed = n - nIn; + +exprparse_out: + if( rc!=SQLITE_OK ){ + sqlite3Fts3ExprFree(pRet); + sqlite3Fts3ExprFree(pNotBranch); + pRet = 0; + } + *ppExpr = pRet; + return rc; +} + +/* +** Return SQLITE_ERROR if the maximum depth of the expression tree passed +** as the only argument is more than nMaxDepth. +*/ +static int fts3ExprCheckDepth(Fts3Expr *p, int nMaxDepth){ + int rc = SQLITE_OK; + if( p ){ + if( nMaxDepth<0 ){ + rc = SQLITE_TOOBIG; + }else{ + rc = fts3ExprCheckDepth(p->pLeft, nMaxDepth-1); + if( rc==SQLITE_OK ){ + rc = fts3ExprCheckDepth(p->pRight, nMaxDepth-1); + } + } + } + return rc; +} + +/* +** This function attempts to transform the expression tree at (*pp) to +** an equivalent but more balanced form. The tree is modified in place. +** If successful, SQLITE_OK is returned and (*pp) set to point to the +** new root expression node. +** +** nMaxDepth is the maximum allowable depth of the balanced sub-tree. +** +** Otherwise, if an error occurs, an SQLite error code is returned and +** expression (*pp) freed. +*/ +static int fts3ExprBalance(Fts3Expr **pp, int nMaxDepth){ + int rc = SQLITE_OK; /* Return code */ + Fts3Expr *pRoot = *pp; /* Initial root node */ + Fts3Expr *pFree = 0; /* List of free nodes. Linked by pParent. */ + int eType = pRoot->eType; /* Type of node in this tree */ + + if( nMaxDepth==0 ){ + rc = SQLITE_ERROR; + } + + if( rc==SQLITE_OK ){ + if( (eType==FTSQUERY_AND || eType==FTSQUERY_OR) ){ + Fts3Expr **apLeaf; + apLeaf = (Fts3Expr **)sqlite3_malloc64(sizeof(Fts3Expr *) * nMaxDepth); + if( 0==apLeaf ){ + rc = SQLITE_NOMEM; + }else{ + memset(apLeaf, 0, sizeof(Fts3Expr *) * nMaxDepth); + } + + if( rc==SQLITE_OK ){ + int i; + Fts3Expr *p; + + /* Set $p to point to the left-most leaf in the tree of eType nodes. */ + for(p=pRoot; p->eType==eType; p=p->pLeft){ + assert( p->pParent==0 || p->pParent->pLeft==p ); + assert( p->pLeft && p->pRight ); + } + + /* This loop runs once for each leaf in the tree of eType nodes. */ + while( 1 ){ + int iLvl; + Fts3Expr *pParent = p->pParent; /* Current parent of p */ + + assert( pParent==0 || pParent->pLeft==p ); + p->pParent = 0; + if( pParent ){ + pParent->pLeft = 0; + }else{ + pRoot = 0; + } + rc = fts3ExprBalance(&p, nMaxDepth-1); + if( rc!=SQLITE_OK ) break; + + for(iLvl=0; p && iLvlpLeft = apLeaf[iLvl]; + pFree->pRight = p; + pFree->pLeft->pParent = pFree; + pFree->pRight->pParent = pFree; + + p = pFree; + pFree = pFree->pParent; + p->pParent = 0; + apLeaf[iLvl] = 0; + } + } + if( p ){ + sqlite3Fts3ExprFree(p); + rc = SQLITE_TOOBIG; + break; + } + + /* If that was the last leaf node, break out of the loop */ + if( pParent==0 ) break; + + /* Set $p to point to the next leaf in the tree of eType nodes */ + for(p=pParent->pRight; p->eType==eType; p=p->pLeft); + + /* Remove pParent from the original tree. */ + assert( pParent->pParent==0 || pParent->pParent->pLeft==pParent ); + pParent->pRight->pParent = pParent->pParent; + if( pParent->pParent ){ + pParent->pParent->pLeft = pParent->pRight; + }else{ + assert( pParent==pRoot ); + pRoot = pParent->pRight; + } + + /* Link pParent into the free node list. It will be used as an + ** internal node of the new tree. */ + pParent->pParent = pFree; + pFree = pParent; + } + + if( rc==SQLITE_OK ){ + p = 0; + for(i=0; ipParent = 0; + }else{ + assert( pFree!=0 ); + pFree->pRight = p; + pFree->pLeft = apLeaf[i]; + pFree->pLeft->pParent = pFree; + pFree->pRight->pParent = pFree; + + p = pFree; + pFree = pFree->pParent; + p->pParent = 0; + } + } + } + pRoot = p; + }else{ + /* An error occurred. Delete the contents of the apLeaf[] array + ** and pFree list. Everything else is cleaned up by the call to + ** sqlite3Fts3ExprFree(pRoot) below. */ + Fts3Expr *pDel; + for(i=0; ipParent; + sqlite3_free(pDel); + } + } + + assert( pFree==0 ); + sqlite3_free( apLeaf ); + } + }else if( eType==FTSQUERY_NOT ){ + Fts3Expr *pLeft = pRoot->pLeft; + Fts3Expr *pRight = pRoot->pRight; + + pRoot->pLeft = 0; + pRoot->pRight = 0; + pLeft->pParent = 0; + pRight->pParent = 0; + + rc = fts3ExprBalance(&pLeft, nMaxDepth-1); + if( rc==SQLITE_OK ){ + rc = fts3ExprBalance(&pRight, nMaxDepth-1); + } + + if( rc!=SQLITE_OK ){ + sqlite3Fts3ExprFree(pRight); + sqlite3Fts3ExprFree(pLeft); + }else{ + assert( pLeft && pRight ); + pRoot->pLeft = pLeft; + pLeft->pParent = pRoot; + pRoot->pRight = pRight; + pRight->pParent = pRoot; + } + } + } + + if( rc!=SQLITE_OK ){ + sqlite3Fts3ExprFree(pRoot); + pRoot = 0; + } + *pp = pRoot; + return rc; +} + +/* +** This function is similar to sqlite3Fts3ExprParse(), with the following +** differences: +** +** 1. It does not do expression rebalancing. +** 2. It does not check that the expression does not exceed the +** maximum allowable depth. +** 3. Even if it fails, *ppExpr may still be set to point to an +** expression tree. It should be deleted using sqlite3Fts3ExprFree() +** in this case. +*/ +static int fts3ExprParseUnbalanced( + sqlite3_tokenizer *pTokenizer, /* Tokenizer module */ + int iLangid, /* Language id for tokenizer */ + char **azCol, /* Array of column names for fts3 table */ + int bFts4, /* True to allow FTS4-only syntax */ + int nCol, /* Number of entries in azCol[] */ + int iDefaultCol, /* Default column to query */ + const char *z, int n, /* Text of MATCH query */ + Fts3Expr **ppExpr /* OUT: Parsed query structure */ +){ + int nParsed; + int rc; + ParseContext sParse; + + memset(&sParse, 0, sizeof(ParseContext)); + sParse.pTokenizer = pTokenizer; + sParse.iLangid = iLangid; + sParse.azCol = (const char **)azCol; + sParse.nCol = nCol; + sParse.iDefaultCol = iDefaultCol; + sParse.bFts4 = bFts4; + if( z==0 ){ + *ppExpr = 0; + return SQLITE_OK; + } + if( n<0 ){ + n = (int)strlen(z); + } + rc = fts3ExprParse(&sParse, z, n, ppExpr, &nParsed); + assert( rc==SQLITE_OK || *ppExpr==0 ); + + /* Check for mismatched parenthesis */ + if( rc==SQLITE_OK && sParse.nNest ){ + rc = SQLITE_ERROR; + } + + return rc; +} + +/* +** Parameters z and n contain a pointer to and length of a buffer containing +** an fts3 query expression, respectively. This function attempts to parse the +** query expression and create a tree of Fts3Expr structures representing the +** parsed expression. If successful, *ppExpr is set to point to the head +** of the parsed expression tree and SQLITE_OK is returned. If an error +** occurs, either SQLITE_NOMEM (out-of-memory error) or SQLITE_ERROR (parse +** error) is returned and *ppExpr is set to 0. +** +** If parameter n is a negative number, then z is assumed to point to a +** nul-terminated string and the length is determined using strlen(). +** +** The first parameter, pTokenizer, is passed the fts3 tokenizer module to +** use to normalize query tokens while parsing the expression. The azCol[] +** array, which is assumed to contain nCol entries, should contain the names +** of each column in the target fts3 table, in order from left to right. +** Column names must be nul-terminated strings. +** +** The iDefaultCol parameter should be passed the index of the table column +** that appears on the left-hand-side of the MATCH operator (the default +** column to match against for tokens for which a column name is not explicitly +** specified as part of the query string), or -1 if tokens may by default +** match any table column. +*/ +SQLITE_PRIVATE int sqlite3Fts3ExprParse( + sqlite3_tokenizer *pTokenizer, /* Tokenizer module */ + int iLangid, /* Language id for tokenizer */ + char **azCol, /* Array of column names for fts3 table */ + int bFts4, /* True to allow FTS4-only syntax */ + int nCol, /* Number of entries in azCol[] */ + int iDefaultCol, /* Default column to query */ + const char *z, int n, /* Text of MATCH query */ + Fts3Expr **ppExpr, /* OUT: Parsed query structure */ + char **pzErr /* OUT: Error message (sqlite3_malloc) */ +){ + int rc = fts3ExprParseUnbalanced( + pTokenizer, iLangid, azCol, bFts4, nCol, iDefaultCol, z, n, ppExpr + ); + + /* Rebalance the expression. And check that its depth does not exceed + ** SQLITE_FTS3_MAX_EXPR_DEPTH. */ + if( rc==SQLITE_OK && *ppExpr ){ + rc = fts3ExprBalance(ppExpr, SQLITE_FTS3_MAX_EXPR_DEPTH); + if( rc==SQLITE_OK ){ + rc = fts3ExprCheckDepth(*ppExpr, SQLITE_FTS3_MAX_EXPR_DEPTH); + } + } + + if( rc!=SQLITE_OK ){ + sqlite3Fts3ExprFree(*ppExpr); + *ppExpr = 0; + if( rc==SQLITE_TOOBIG ){ + sqlite3Fts3ErrMsg(pzErr, + "FTS expression tree is too large (maximum depth %d)", + SQLITE_FTS3_MAX_EXPR_DEPTH + ); + rc = SQLITE_ERROR; + }else if( rc==SQLITE_ERROR ){ + sqlite3Fts3ErrMsg(pzErr, "malformed MATCH expression: [%s]", z); + } + } + + return rc; +} + +/* +** Free a single node of an expression tree. +*/ +static void fts3FreeExprNode(Fts3Expr *p){ + assert( p->eType==FTSQUERY_PHRASE || p->pPhrase==0 ); + sqlite3Fts3EvalPhraseCleanup(p->pPhrase); + sqlite3_free(p->aMI); + sqlite3_free(p); +} + +/* +** Free a parsed fts3 query expression allocated by sqlite3Fts3ExprParse(). +** +** This function would be simpler if it recursively called itself. But +** that would mean passing a sufficiently large expression to ExprParse() +** could cause a stack overflow. +*/ +SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *pDel){ + Fts3Expr *p; + assert( pDel==0 || pDel->pParent==0 ); + for(p=pDel; p && (p->pLeft||p->pRight); p=(p->pLeft ? p->pLeft : p->pRight)){ + assert( p->pParent==0 || p==p->pParent->pRight || p==p->pParent->pLeft ); + } + while( p ){ + Fts3Expr *pParent = p->pParent; + fts3FreeExprNode(p); + if( pParent && p==pParent->pLeft && pParent->pRight ){ + p = pParent->pRight; + while( p && (p->pLeft || p->pRight) ){ + assert( p==p->pParent->pRight || p==p->pParent->pLeft ); + p = (p->pLeft ? p->pLeft : p->pRight); + } + }else{ + p = pParent; + } + } +} + +/**************************************************************************** +***************************************************************************** +** Everything after this point is just test code. +*/ + +#ifdef SQLITE_TEST + +/* #include */ + +/* +** Return a pointer to a buffer containing a text representation of the +** expression passed as the first argument. The buffer is obtained from +** sqlite3_malloc(). It is the responsibility of the caller to use +** sqlite3_free() to release the memory. If an OOM condition is encountered, +** NULL is returned. +** +** If the second argument is not NULL, then its contents are prepended to +** the returned expression text and then freed using sqlite3_free(). +*/ +static char *exprToString(Fts3Expr *pExpr, char *zBuf){ + if( pExpr==0 ){ + return sqlite3_mprintf(""); + } + switch( pExpr->eType ){ + case FTSQUERY_PHRASE: { + Fts3Phrase *pPhrase = pExpr->pPhrase; + int i; + zBuf = sqlite3_mprintf( + "%zPHRASE %d 0", zBuf, pPhrase->iColumn); + for(i=0; zBuf && inToken; i++){ + zBuf = sqlite3_mprintf("%z %.*s%s", zBuf, + pPhrase->aToken[i].n, pPhrase->aToken[i].z, + (pPhrase->aToken[i].isPrefix?"+":"") + ); + } + return zBuf; + } + + case FTSQUERY_NEAR: + zBuf = sqlite3_mprintf("%zNEAR/%d ", zBuf, pExpr->nNear); + break; + case FTSQUERY_NOT: + zBuf = sqlite3_mprintf("%zNOT ", zBuf); + break; + case FTSQUERY_AND: + zBuf = sqlite3_mprintf("%zAND ", zBuf); + break; + case FTSQUERY_OR: + zBuf = sqlite3_mprintf("%zOR ", zBuf); + break; + } + + if( zBuf ) zBuf = sqlite3_mprintf("%z{", zBuf); + if( zBuf ) zBuf = exprToString(pExpr->pLeft, zBuf); + if( zBuf ) zBuf = sqlite3_mprintf("%z} {", zBuf); + + if( zBuf ) zBuf = exprToString(pExpr->pRight, zBuf); + if( zBuf ) zBuf = sqlite3_mprintf("%z}", zBuf); + + return zBuf; +} + +/* +** This is the implementation of a scalar SQL function used to test the +** expression parser. It should be called as follows: +** +** fts3_exprtest(, , , ...); +** +** The first argument, , is the name of the fts3 tokenizer used +** to parse the query expression (see README.tokenizers). The second argument +** is the query expression to parse. Each subsequent argument is the name +** of a column of the fts3 table that the query expression may refer to. +** For example: +** +** SELECT fts3_exprtest('simple', 'Bill col2:Bloggs', 'col1', 'col2'); +*/ +static void fts3ExprTestCommon( + int bRebalance, + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + sqlite3_tokenizer *pTokenizer = 0; + int rc; + char **azCol = 0; + const char *zExpr; + int nExpr; + int nCol; + int ii; + Fts3Expr *pExpr; + char *zBuf = 0; + Fts3Hash *pHash = (Fts3Hash*)sqlite3_user_data(context); + const char *zTokenizer = 0; + char *zErr = 0; + + if( argc<3 ){ + sqlite3_result_error(context, + "Usage: fts3_exprtest(tokenizer, expr, col1, ...", -1 + ); + return; + } + + zTokenizer = (const char*)sqlite3_value_text(argv[0]); + rc = sqlite3Fts3InitTokenizer(pHash, zTokenizer, &pTokenizer, &zErr); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_NOMEM ){ + sqlite3_result_error_nomem(context); + }else{ + sqlite3_result_error(context, zErr, -1); + } + sqlite3_free(zErr); + return; + } + + zExpr = (const char *)sqlite3_value_text(argv[1]); + nExpr = sqlite3_value_bytes(argv[1]); + nCol = argc-2; + azCol = (char **)sqlite3_malloc64(nCol*sizeof(char *)); + if( !azCol ){ + sqlite3_result_error_nomem(context); + goto exprtest_out; + } + for(ii=0; iipModule->xDestroy(pTokenizer); + } + sqlite3_free(azCol); +} + +static void fts3ExprTest( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + fts3ExprTestCommon(0, context, argc, argv); +} +static void fts3ExprTestRebalance( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + fts3ExprTestCommon(1, context, argc, argv); +} + +/* +** Register the query expression parser test function fts3_exprtest() +** with database connection db. +*/ +SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash *pHash){ + int rc = sqlite3_create_function( + db, "fts3_exprtest", -1, SQLITE_UTF8, (void*)pHash, fts3ExprTest, 0, 0 + ); + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "fts3_exprtest_rebalance", + -1, SQLITE_UTF8, (void*)pHash, fts3ExprTestRebalance, 0, 0 + ); + } + return rc; +} + +#endif +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_expr.c *******************************************/ +/************** Begin file fts3_hash.c ***************************************/ +/* +** 2001 September 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This is the implementation of generic hash-tables used in SQLite. +** We've modified it slightly to serve as a standalone hash table +** implementation for the full-text indexing module. +*/ + +/* +** The code in this file is only compiled if: +** +** * The FTS3 module is being built as an extension +** (in which case SQLITE_CORE is not defined), or +** +** * The FTS3 module is being built into the core of +** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). +*/ +/* #include "fts3Int.h" */ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include */ +/* #include */ +/* #include */ + +/* #include "fts3_hash.h" */ + +/* +** Malloc and Free functions +*/ +static void *fts3HashMalloc(sqlite3_int64 n){ + void *p = sqlite3_malloc64(n); + if( p ){ + memset(p, 0, n); + } + return p; +} +static void fts3HashFree(void *p){ + sqlite3_free(p); +} + +/* Turn bulk memory into a hash table object by initializing the +** fields of the Hash structure. +** +** "pNew" is a pointer to the hash table that is to be initialized. +** keyClass is one of the constants +** FTS3_HASH_BINARY or FTS3_HASH_STRING. The value of keyClass +** determines what kind of key the hash table will use. "copyKey" is +** true if the hash table should make its own private copy of keys and +** false if it should just use the supplied pointer. +*/ +SQLITE_PRIVATE void sqlite3Fts3HashInit(Fts3Hash *pNew, char keyClass, char copyKey){ + assert( pNew!=0 ); + assert( keyClass>=FTS3_HASH_STRING && keyClass<=FTS3_HASH_BINARY ); + pNew->keyClass = keyClass; + pNew->copyKey = copyKey; + pNew->first = 0; + pNew->count = 0; + pNew->htsize = 0; + pNew->ht = 0; +} + +/* Remove all entries from a hash table. Reclaim all memory. +** Call this routine to delete a hash table or to reset a hash table +** to the empty state. +*/ +SQLITE_PRIVATE void sqlite3Fts3HashClear(Fts3Hash *pH){ + Fts3HashElem *elem; /* For looping over all elements of the table */ + + assert( pH!=0 ); + elem = pH->first; + pH->first = 0; + fts3HashFree(pH->ht); + pH->ht = 0; + pH->htsize = 0; + while( elem ){ + Fts3HashElem *next_elem = elem->next; + if( pH->copyKey && elem->pKey ){ + fts3HashFree(elem->pKey); + } + fts3HashFree(elem); + elem = next_elem; + } + pH->count = 0; +} + +/* +** Hash and comparison functions when the mode is FTS3_HASH_STRING +*/ +static int fts3StrHash(const void *pKey, int nKey){ + const char *z = (const char *)pKey; + unsigned h = 0; + if( nKey<=0 ) nKey = (int) strlen(z); + while( nKey > 0 ){ + h = (h<<3) ^ h ^ *z++; + nKey--; + } + return (int)(h & 0x7fffffff); +} +static int fts3StrCompare(const void *pKey1, int n1, const void *pKey2, int n2){ + if( n1!=n2 ) return 1; + return strncmp((const char*)pKey1,(const char*)pKey2,n1); +} + +/* +** Hash and comparison functions when the mode is FTS3_HASH_BINARY +*/ +static int fts3BinHash(const void *pKey, int nKey){ + int h = 0; + const char *z = (const char *)pKey; + while( nKey-- > 0 ){ + h = (h<<3) ^ h ^ *(z++); + } + return h & 0x7fffffff; +} +static int fts3BinCompare(const void *pKey1, int n1, const void *pKey2, int n2){ + if( n1!=n2 ) return 1; + return memcmp(pKey1,pKey2,n1); +} + +/* +** Return a pointer to the appropriate hash function given the key class. +** +** The C syntax in this function definition may be unfamilar to some +** programmers, so we provide the following additional explanation: +** +** The name of the function is "ftsHashFunction". The function takes a +** single parameter "keyClass". The return value of ftsHashFunction() +** is a pointer to another function. Specifically, the return value +** of ftsHashFunction() is a pointer to a function that takes two parameters +** with types "const void*" and "int" and returns an "int". +*/ +static int (*ftsHashFunction(int keyClass))(const void*,int){ + if( keyClass==FTS3_HASH_STRING ){ + return &fts3StrHash; + }else{ + assert( keyClass==FTS3_HASH_BINARY ); + return &fts3BinHash; + } +} + +/* +** Return a pointer to the appropriate hash function given the key class. +** +** For help in interpreted the obscure C code in the function definition, +** see the header comment on the previous function. +*/ +static int (*ftsCompareFunction(int keyClass))(const void*,int,const void*,int){ + if( keyClass==FTS3_HASH_STRING ){ + return &fts3StrCompare; + }else{ + assert( keyClass==FTS3_HASH_BINARY ); + return &fts3BinCompare; + } +} + +/* Link an element into the hash table +*/ +static void fts3HashInsertElement( + Fts3Hash *pH, /* The complete hash table */ + struct _fts3ht *pEntry, /* The entry into which pNew is inserted */ + Fts3HashElem *pNew /* The element to be inserted */ +){ + Fts3HashElem *pHead; /* First element already in pEntry */ + pHead = pEntry->chain; + if( pHead ){ + pNew->next = pHead; + pNew->prev = pHead->prev; + if( pHead->prev ){ pHead->prev->next = pNew; } + else { pH->first = pNew; } + pHead->prev = pNew; + }else{ + pNew->next = pH->first; + if( pH->first ){ pH->first->prev = pNew; } + pNew->prev = 0; + pH->first = pNew; + } + pEntry->count++; + pEntry->chain = pNew; +} + + +/* Resize the hash table so that it contains "new_size" buckets. +** "new_size" must be a power of 2. The hash table might fail +** to resize if sqliteMalloc() fails. +** +** Return non-zero if a memory allocation error occurs. +*/ +static int fts3Rehash(Fts3Hash *pH, int new_size){ + struct _fts3ht *new_ht; /* The new hash table */ + Fts3HashElem *elem, *next_elem; /* For looping over existing elements */ + int (*xHash)(const void*,int); /* The hash function */ + + assert( (new_size & (new_size-1))==0 ); + new_ht = (struct _fts3ht *)fts3HashMalloc( new_size*sizeof(struct _fts3ht) ); + if( new_ht==0 ) return 1; + fts3HashFree(pH->ht); + pH->ht = new_ht; + pH->htsize = new_size; + xHash = ftsHashFunction(pH->keyClass); + for(elem=pH->first, pH->first=0; elem; elem = next_elem){ + int h = (*xHash)(elem->pKey, elem->nKey) & (new_size-1); + next_elem = elem->next; + fts3HashInsertElement(pH, &new_ht[h], elem); + } + return 0; +} + +/* This function (for internal use only) locates an element in an +** hash table that matches the given key. The hash for this key has +** already been computed and is passed as the 4th parameter. +*/ +static Fts3HashElem *fts3FindElementByHash( + const Fts3Hash *pH, /* The pH to be searched */ + const void *pKey, /* The key we are searching for */ + int nKey, + int h /* The hash for this key. */ +){ + Fts3HashElem *elem; /* Used to loop thru the element list */ + int count; /* Number of elements left to test */ + int (*xCompare)(const void*,int,const void*,int); /* comparison function */ + + if( pH->ht ){ + struct _fts3ht *pEntry = &pH->ht[h]; + elem = pEntry->chain; + count = pEntry->count; + xCompare = ftsCompareFunction(pH->keyClass); + while( count-- && elem ){ + if( (*xCompare)(elem->pKey,elem->nKey,pKey,nKey)==0 ){ + return elem; + } + elem = elem->next; + } + } + return 0; +} + +/* Remove a single entry from the hash table given a pointer to that +** element and a hash on the element's key. +*/ +static void fts3RemoveElementByHash( + Fts3Hash *pH, /* The pH containing "elem" */ + Fts3HashElem* elem, /* The element to be removed from the pH */ + int h /* Hash value for the element */ +){ + struct _fts3ht *pEntry; + if( elem->prev ){ + elem->prev->next = elem->next; + }else{ + pH->first = elem->next; + } + if( elem->next ){ + elem->next->prev = elem->prev; + } + pEntry = &pH->ht[h]; + if( pEntry->chain==elem ){ + pEntry->chain = elem->next; + } + pEntry->count--; + if( pEntry->count<=0 ){ + pEntry->chain = 0; + } + if( pH->copyKey && elem->pKey ){ + fts3HashFree(elem->pKey); + } + fts3HashFree( elem ); + pH->count--; + if( pH->count<=0 ){ + assert( pH->first==0 ); + assert( pH->count==0 ); + fts3HashClear(pH); + } +} + +SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem( + const Fts3Hash *pH, + const void *pKey, + int nKey +){ + int h; /* A hash on key */ + int (*xHash)(const void*,int); /* The hash function */ + + if( pH==0 || pH->ht==0 ) return 0; + xHash = ftsHashFunction(pH->keyClass); + assert( xHash!=0 ); + h = (*xHash)(pKey,nKey); + assert( (pH->htsize & (pH->htsize-1))==0 ); + return fts3FindElementByHash(pH,pKey,nKey, h & (pH->htsize-1)); +} + +/* +** Attempt to locate an element of the hash table pH with a key +** that matches pKey,nKey. Return the data for this element if it is +** found, or NULL if there is no match. +*/ +SQLITE_PRIVATE void *sqlite3Fts3HashFind(const Fts3Hash *pH, const void *pKey, int nKey){ + Fts3HashElem *pElem; /* The element that matches key (if any) */ + + pElem = sqlite3Fts3HashFindElem(pH, pKey, nKey); + return pElem ? pElem->data : 0; +} + +/* Insert an element into the hash table pH. The key is pKey,nKey +** and the data is "data". +** +** If no element exists with a matching key, then a new +** element is created. A copy of the key is made if the copyKey +** flag is set. NULL is returned. +** +** If another element already exists with the same key, then the +** new data replaces the old data and the old data is returned. +** The key is not copied in this instance. If a malloc fails, then +** the new data is returned and the hash table is unchanged. +** +** If the "data" parameter to this function is NULL, then the +** element corresponding to "key" is removed from the hash table. +*/ +SQLITE_PRIVATE void *sqlite3Fts3HashInsert( + Fts3Hash *pH, /* The hash table to insert into */ + const void *pKey, /* The key */ + int nKey, /* Number of bytes in the key */ + void *data /* The data */ +){ + int hraw; /* Raw hash value of the key */ + int h; /* the hash of the key modulo hash table size */ + Fts3HashElem *elem; /* Used to loop thru the element list */ + Fts3HashElem *new_elem; /* New element added to the pH */ + int (*xHash)(const void*,int); /* The hash function */ + + assert( pH!=0 ); + xHash = ftsHashFunction(pH->keyClass); + assert( xHash!=0 ); + hraw = (*xHash)(pKey, nKey); + assert( (pH->htsize & (pH->htsize-1))==0 ); + h = hraw & (pH->htsize-1); + elem = fts3FindElementByHash(pH,pKey,nKey,h); + if( elem ){ + void *old_data = elem->data; + if( data==0 ){ + fts3RemoveElementByHash(pH,elem,h); + }else{ + elem->data = data; + } + return old_data; + } + if( data==0 ) return 0; + if( (pH->htsize==0 && fts3Rehash(pH,8)) + || (pH->count>=pH->htsize && fts3Rehash(pH, pH->htsize*2)) + ){ + pH->count = 0; + return data; + } + assert( pH->htsize>0 ); + new_elem = (Fts3HashElem*)fts3HashMalloc( sizeof(Fts3HashElem) ); + if( new_elem==0 ) return data; + if( pH->copyKey && pKey!=0 ){ + new_elem->pKey = fts3HashMalloc( nKey ); + if( new_elem->pKey==0 ){ + fts3HashFree(new_elem); + return data; + } + memcpy((void*)new_elem->pKey, pKey, nKey); + }else{ + new_elem->pKey = (void*)pKey; + } + new_elem->nKey = nKey; + pH->count++; + assert( pH->htsize>0 ); + assert( (pH->htsize & (pH->htsize-1))==0 ); + h = hraw & (pH->htsize-1); + fts3HashInsertElement(pH, &pH->ht[h], new_elem); + new_elem->data = data; + return 0; +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_hash.c *******************************************/ +/************** Begin file fts3_porter.c *************************************/ +/* +** 2006 September 30 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** Implementation of the full-text-search tokenizer that implements +** a Porter stemmer. +*/ + +/* +** The code in this file is only compiled if: +** +** * The FTS3 module is being built as an extension +** (in which case SQLITE_CORE is not defined), or +** +** * The FTS3 module is being built into the core of +** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). +*/ +/* #include "fts3Int.h" */ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include */ +/* #include */ +/* #include */ +/* #include */ + +/* #include "fts3_tokenizer.h" */ + +/* +** Class derived from sqlite3_tokenizer +*/ +typedef struct porter_tokenizer { + sqlite3_tokenizer base; /* Base class */ +} porter_tokenizer; + +/* +** Class derived from sqlite3_tokenizer_cursor +*/ +typedef struct porter_tokenizer_cursor { + sqlite3_tokenizer_cursor base; + const char *zInput; /* input we are tokenizing */ + int nInput; /* size of the input */ + int iOffset; /* current position in zInput */ + int iToken; /* index of next token to be returned */ + char *zToken; /* storage for current token */ + int nAllocated; /* space allocated to zToken buffer */ +} porter_tokenizer_cursor; + + +/* +** Create a new tokenizer instance. +*/ +static int porterCreate( + int argc, const char * const *argv, + sqlite3_tokenizer **ppTokenizer +){ + porter_tokenizer *t; + + UNUSED_PARAMETER(argc); + UNUSED_PARAMETER(argv); + + t = (porter_tokenizer *) sqlite3_malloc(sizeof(*t)); + if( t==NULL ) return SQLITE_NOMEM; + memset(t, 0, sizeof(*t)); + *ppTokenizer = &t->base; + return SQLITE_OK; +} + +/* +** Destroy a tokenizer +*/ +static int porterDestroy(sqlite3_tokenizer *pTokenizer){ + sqlite3_free(pTokenizer); + return SQLITE_OK; +} + +/* +** Prepare to begin tokenizing a particular string. The input +** string to be tokenized is zInput[0..nInput-1]. A cursor +** used to incrementally tokenize this string is returned in +** *ppCursor. +*/ +static int porterOpen( + sqlite3_tokenizer *pTokenizer, /* The tokenizer */ + const char *zInput, int nInput, /* String to be tokenized */ + sqlite3_tokenizer_cursor **ppCursor /* OUT: Tokenization cursor */ +){ + porter_tokenizer_cursor *c; + + UNUSED_PARAMETER(pTokenizer); + + c = (porter_tokenizer_cursor *) sqlite3_malloc(sizeof(*c)); + if( c==NULL ) return SQLITE_NOMEM; + + c->zInput = zInput; + if( zInput==0 ){ + c->nInput = 0; + }else if( nInput<0 ){ + c->nInput = (int)strlen(zInput); + }else{ + c->nInput = nInput; + } + c->iOffset = 0; /* start tokenizing at the beginning */ + c->iToken = 0; + c->zToken = NULL; /* no space allocated, yet. */ + c->nAllocated = 0; + + *ppCursor = &c->base; + return SQLITE_OK; +} + +/* +** Close a tokenization cursor previously opened by a call to +** porterOpen() above. +*/ +static int porterClose(sqlite3_tokenizer_cursor *pCursor){ + porter_tokenizer_cursor *c = (porter_tokenizer_cursor *) pCursor; + sqlite3_free(c->zToken); + sqlite3_free(c); + return SQLITE_OK; +} +/* +** Vowel or consonant +*/ +static const char cType[] = { + 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 2, 1 +}; + +/* +** isConsonant() and isVowel() determine if their first character in +** the string they point to is a consonant or a vowel, according +** to Porter ruls. +** +** A consonate is any letter other than 'a', 'e', 'i', 'o', or 'u'. +** 'Y' is a consonant unless it follows another consonant, +** in which case it is a vowel. +** +** In these routine, the letters are in reverse order. So the 'y' rule +** is that 'y' is a consonant unless it is followed by another +** consonent. +*/ +static int isVowel(const char*); +static int isConsonant(const char *z){ + int j; + char x = *z; + if( x==0 ) return 0; + assert( x>='a' && x<='z' ); + j = cType[x-'a']; + if( j<2 ) return j; + return z[1]==0 || isVowel(z + 1); +} +static int isVowel(const char *z){ + int j; + char x = *z; + if( x==0 ) return 0; + assert( x>='a' && x<='z' ); + j = cType[x-'a']; + if( j<2 ) return 1-j; + return isConsonant(z + 1); +} + +/* +** Let any sequence of one or more vowels be represented by V and let +** C be sequence of one or more consonants. Then every word can be +** represented as: +** +** [C] (VC){m} [V] +** +** In prose: A word is an optional consonant followed by zero or +** vowel-consonant pairs followed by an optional vowel. "m" is the +** number of vowel consonant pairs. This routine computes the value +** of m for the first i bytes of a word. +** +** Return true if the m-value for z is 1 or more. In other words, +** return true if z contains at least one vowel that is followed +** by a consonant. +** +** In this routine z[] is in reverse order. So we are really looking +** for an instance of a consonant followed by a vowel. +*/ +static int m_gt_0(const char *z){ + while( isVowel(z) ){ z++; } + if( *z==0 ) return 0; + while( isConsonant(z) ){ z++; } + return *z!=0; +} + +/* Like mgt0 above except we are looking for a value of m which is +** exactly 1 +*/ +static int m_eq_1(const char *z){ + while( isVowel(z) ){ z++; } + if( *z==0 ) return 0; + while( isConsonant(z) ){ z++; } + if( *z==0 ) return 0; + while( isVowel(z) ){ z++; } + if( *z==0 ) return 1; + while( isConsonant(z) ){ z++; } + return *z==0; +} + +/* Like mgt0 above except we are looking for a value of m>1 instead +** or m>0 +*/ +static int m_gt_1(const char *z){ + while( isVowel(z) ){ z++; } + if( *z==0 ) return 0; + while( isConsonant(z) ){ z++; } + if( *z==0 ) return 0; + while( isVowel(z) ){ z++; } + if( *z==0 ) return 0; + while( isConsonant(z) ){ z++; } + return *z!=0; +} + +/* +** Return TRUE if there is a vowel anywhere within z[0..n-1] +*/ +static int hasVowel(const char *z){ + while( isConsonant(z) ){ z++; } + return *z!=0; +} + +/* +** Return TRUE if the word ends in a double consonant. +** +** The text is reversed here. So we are really looking at +** the first two characters of z[]. +*/ +static int doubleConsonant(const char *z){ + return isConsonant(z) && z[0]==z[1]; +} + +/* +** Return TRUE if the word ends with three letters which +** are consonant-vowel-consonent and where the final consonant +** is not 'w', 'x', or 'y'. +** +** The word is reversed here. So we are really checking the +** first three letters and the first one cannot be in [wxy]. +*/ +static int star_oh(const char *z){ + return + isConsonant(z) && + z[0]!='w' && z[0]!='x' && z[0]!='y' && + isVowel(z+1) && + isConsonant(z+2); +} + +/* +** If the word ends with zFrom and xCond() is true for the stem +** of the word that precedes the zFrom ending, then change the +** ending to zTo. +** +** The input word *pz and zFrom are both in reverse order. zTo +** is in normal order. +** +** Return TRUE if zFrom matches. Return FALSE if zFrom does not +** match. Not that TRUE is returned even if xCond() fails and +** no substitution occurs. +*/ +static int stem( + char **pz, /* The word being stemmed (Reversed) */ + const char *zFrom, /* If the ending matches this... (Reversed) */ + const char *zTo, /* ... change the ending to this (not reversed) */ + int (*xCond)(const char*) /* Condition that must be true */ +){ + char *z = *pz; + while( *zFrom && *zFrom==*z ){ z++; zFrom++; } + if( *zFrom!=0 ) return 0; + if( xCond && !xCond(z) ) return 1; + while( *zTo ){ + *(--z) = *(zTo++); + } + *pz = z; + return 1; +} + +/* +** This is the fallback stemmer used when the porter stemmer is +** inappropriate. The input word is copied into the output with +** US-ASCII case folding. If the input word is too long (more +** than 20 bytes if it contains no digits or more than 6 bytes if +** it contains digits) then word is truncated to 20 or 6 bytes +** by taking 10 or 3 bytes from the beginning and end. +*/ +static void copy_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){ + int i, mx, j; + int hasDigit = 0; + for(i=0; i='A' && c<='Z' ){ + zOut[i] = c - 'A' + 'a'; + }else{ + if( c>='0' && c<='9' ) hasDigit = 1; + zOut[i] = c; + } + } + mx = hasDigit ? 3 : 10; + if( nIn>mx*2 ){ + for(j=mx, i=nIn-mx; i=(int)sizeof(zReverse)-7 ){ + /* The word is too big or too small for the porter stemmer. + ** Fallback to the copy stemmer */ + copy_stemmer(zIn, nIn, zOut, pnOut); + return; + } + for(i=0, j=sizeof(zReverse)-6; i='A' && c<='Z' ){ + zReverse[j] = c + 'a' - 'A'; + }else if( c>='a' && c<='z' ){ + zReverse[j] = c; + }else{ + /* The use of a character not in [a-zA-Z] means that we fallback + ** to the copy stemmer */ + copy_stemmer(zIn, nIn, zOut, pnOut); + return; + } + } + memset(&zReverse[sizeof(zReverse)-5], 0, 5); + z = &zReverse[j+1]; + + + /* Step 1a */ + if( z[0]=='s' ){ + if( + !stem(&z, "sess", "ss", 0) && + !stem(&z, "sei", "i", 0) && + !stem(&z, "ss", "ss", 0) + ){ + z++; + } + } + + /* Step 1b */ + z2 = z; + if( stem(&z, "dee", "ee", m_gt_0) ){ + /* Do nothing. The work was all in the test */ + }else if( + (stem(&z, "gni", "", hasVowel) || stem(&z, "de", "", hasVowel)) + && z!=z2 + ){ + if( stem(&z, "ta", "ate", 0) || + stem(&z, "lb", "ble", 0) || + stem(&z, "zi", "ize", 0) ){ + /* Do nothing. The work was all in the test */ + }else if( doubleConsonant(z) && (*z!='l' && *z!='s' && *z!='z') ){ + z++; + }else if( m_eq_1(z) && star_oh(z) ){ + *(--z) = 'e'; + } + } + + /* Step 1c */ + if( z[0]=='y' && hasVowel(z+1) ){ + z[0] = 'i'; + } + + /* Step 2 */ + switch( z[1] ){ + case 'a': + if( !stem(&z, "lanoita", "ate", m_gt_0) ){ + stem(&z, "lanoit", "tion", m_gt_0); + } + break; + case 'c': + if( !stem(&z, "icne", "ence", m_gt_0) ){ + stem(&z, "icna", "ance", m_gt_0); + } + break; + case 'e': + stem(&z, "rezi", "ize", m_gt_0); + break; + case 'g': + stem(&z, "igol", "log", m_gt_0); + break; + case 'l': + if( !stem(&z, "ilb", "ble", m_gt_0) + && !stem(&z, "illa", "al", m_gt_0) + && !stem(&z, "iltne", "ent", m_gt_0) + && !stem(&z, "ile", "e", m_gt_0) + ){ + stem(&z, "ilsuo", "ous", m_gt_0); + } + break; + case 'o': + if( !stem(&z, "noitazi", "ize", m_gt_0) + && !stem(&z, "noita", "ate", m_gt_0) + ){ + stem(&z, "rota", "ate", m_gt_0); + } + break; + case 's': + if( !stem(&z, "msila", "al", m_gt_0) + && !stem(&z, "ssenevi", "ive", m_gt_0) + && !stem(&z, "ssenluf", "ful", m_gt_0) + ){ + stem(&z, "ssensuo", "ous", m_gt_0); + } + break; + case 't': + if( !stem(&z, "itila", "al", m_gt_0) + && !stem(&z, "itivi", "ive", m_gt_0) + ){ + stem(&z, "itilib", "ble", m_gt_0); + } + break; + } + + /* Step 3 */ + switch( z[0] ){ + case 'e': + if( !stem(&z, "etaci", "ic", m_gt_0) + && !stem(&z, "evita", "", m_gt_0) + ){ + stem(&z, "ezila", "al", m_gt_0); + } + break; + case 'i': + stem(&z, "itici", "ic", m_gt_0); + break; + case 'l': + if( !stem(&z, "laci", "ic", m_gt_0) ){ + stem(&z, "luf", "", m_gt_0); + } + break; + case 's': + stem(&z, "ssen", "", m_gt_0); + break; + } + + /* Step 4 */ + switch( z[1] ){ + case 'a': + if( z[0]=='l' && m_gt_1(z+2) ){ + z += 2; + } + break; + case 'c': + if( z[0]=='e' && z[2]=='n' && (z[3]=='a' || z[3]=='e') && m_gt_1(z+4) ){ + z += 4; + } + break; + case 'e': + if( z[0]=='r' && m_gt_1(z+2) ){ + z += 2; + } + break; + case 'i': + if( z[0]=='c' && m_gt_1(z+2) ){ + z += 2; + } + break; + case 'l': + if( z[0]=='e' && z[2]=='b' && (z[3]=='a' || z[3]=='i') && m_gt_1(z+4) ){ + z += 4; + } + break; + case 'n': + if( z[0]=='t' ){ + if( z[2]=='a' ){ + if( m_gt_1(z+3) ){ + z += 3; + } + }else if( z[2]=='e' ){ + if( !stem(&z, "tneme", "", m_gt_1) + && !stem(&z, "tnem", "", m_gt_1) + ){ + stem(&z, "tne", "", m_gt_1); + } + } + } + break; + case 'o': + if( z[0]=='u' ){ + if( m_gt_1(z+2) ){ + z += 2; + } + }else if( z[3]=='s' || z[3]=='t' ){ + stem(&z, "noi", "", m_gt_1); + } + break; + case 's': + if( z[0]=='m' && z[2]=='i' && m_gt_1(z+3) ){ + z += 3; + } + break; + case 't': + if( !stem(&z, "eta", "", m_gt_1) ){ + stem(&z, "iti", "", m_gt_1); + } + break; + case 'u': + if( z[0]=='s' && z[2]=='o' && m_gt_1(z+3) ){ + z += 3; + } + break; + case 'v': + case 'z': + if( z[0]=='e' && z[2]=='i' && m_gt_1(z+3) ){ + z += 3; + } + break; + } + + /* Step 5a */ + if( z[0]=='e' ){ + if( m_gt_1(z+1) ){ + z++; + }else if( m_eq_1(z+1) && !star_oh(z+1) ){ + z++; + } + } + + /* Step 5b */ + if( m_gt_1(z) && z[0]=='l' && z[1]=='l' ){ + z++; + } + + /* z[] is now the stemmed word in reverse order. Flip it back + ** around into forward order and return. + */ + *pnOut = i = (int)strlen(z); + zOut[i] = 0; + while( *z ){ + zOut[--i] = *(z++); + } +} + +/* +** Characters that can be part of a token. We assume any character +** whose value is greater than 0x80 (any UTF character) can be +** part of a token. In other words, delimiters all must have +** values of 0x7f or lower. +*/ +static const char porterIdChar[] = { +/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 5x */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6x */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 7x */ +}; +#define isDelim(C) (((ch=C)&0x80)==0 && (ch<0x30 || !porterIdChar[ch-0x30])) + +/* +** Extract the next token from a tokenization cursor. The cursor must +** have been opened by a prior call to porterOpen(). +*/ +static int porterNext( + sqlite3_tokenizer_cursor *pCursor, /* Cursor returned by porterOpen */ + const char **pzToken, /* OUT: *pzToken is the token text */ + int *pnBytes, /* OUT: Number of bytes in token */ + int *piStartOffset, /* OUT: Starting offset of token */ + int *piEndOffset, /* OUT: Ending offset of token */ + int *piPosition /* OUT: Position integer of token */ +){ + porter_tokenizer_cursor *c = (porter_tokenizer_cursor *) pCursor; + const char *z = c->zInput; + + while( c->iOffsetnInput ){ + int iStartOffset, ch; + + /* Scan past delimiter characters */ + while( c->iOffsetnInput && isDelim(z[c->iOffset]) ){ + c->iOffset++; + } + + /* Count non-delimiter characters. */ + iStartOffset = c->iOffset; + while( c->iOffsetnInput && !isDelim(z[c->iOffset]) ){ + c->iOffset++; + } + + if( c->iOffset>iStartOffset ){ + int n = c->iOffset-iStartOffset; + if( n>c->nAllocated ){ + char *pNew; + c->nAllocated = n+20; + pNew = sqlite3_realloc64(c->zToken, c->nAllocated); + if( !pNew ) return SQLITE_NOMEM; + c->zToken = pNew; + } + porter_stemmer(&z[iStartOffset], n, c->zToken, pnBytes); + *pzToken = c->zToken; + *piStartOffset = iStartOffset; + *piEndOffset = c->iOffset; + *piPosition = c->iToken++; + return SQLITE_OK; + } + } + return SQLITE_DONE; +} + +/* +** The set of routines that implement the porter-stemmer tokenizer +*/ +static const sqlite3_tokenizer_module porterTokenizerModule = { + 0, + porterCreate, + porterDestroy, + porterOpen, + porterClose, + porterNext, + 0 +}; + +/* +** Allocate a new porter tokenizer. Return a pointer to the new +** tokenizer in *ppModule +*/ +SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule( + sqlite3_tokenizer_module const**ppModule +){ + *ppModule = &porterTokenizerModule; +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_porter.c *****************************************/ +/************** Begin file fts3_tokenizer.c **********************************/ +/* +** 2007 June 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This is part of an SQLite module implementing full-text search. +** This particular file implements the generic tokenizer interface. +*/ + +/* +** The code in this file is only compiled if: +** +** * The FTS3 module is being built as an extension +** (in which case SQLITE_CORE is not defined), or +** +** * The FTS3 module is being built into the core of +** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). +*/ +/* #include "fts3Int.h" */ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include */ +/* #include */ + +/* +** Return true if the two-argument version of fts3_tokenizer() +** has been activated via a prior call to sqlite3_db_config(db, +** SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, 1, 0); +*/ +static int fts3TokenizerEnabled(sqlite3_context *context){ + sqlite3 *db = sqlite3_context_db_handle(context); + int isEnabled = 0; + sqlite3_db_config(db,SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER,-1,&isEnabled); + return isEnabled; +} + +/* +** Implementation of the SQL scalar function for accessing the underlying +** hash table. This function may be called as follows: +** +** SELECT (); +** SELECT (, ); +** +** where is the name passed as the second argument +** to the sqlite3Fts3InitHashTable() function (e.g. 'fts3_tokenizer'). +** +** If the argument is specified, it must be a blob value +** containing a pointer to be stored as the hash data corresponding +** to the string . If is not specified, then +** the string must already exist in the has table. Otherwise, +** an error is returned. +** +** Whether or not the argument is specified, the value returned +** is a blob containing the pointer stored as the hash data corresponding +** to string (after the hash-table is updated, if applicable). +*/ +static void fts3TokenizerFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + Fts3Hash *pHash; + void *pPtr = 0; + const unsigned char *zName; + int nName; + + assert( argc==1 || argc==2 ); + + pHash = (Fts3Hash *)sqlite3_user_data(context); + + zName = sqlite3_value_text(argv[0]); + nName = sqlite3_value_bytes(argv[0])+1; + + if( argc==2 ){ + if( fts3TokenizerEnabled(context) || sqlite3_value_frombind(argv[1]) ){ + void *pOld; + int n = sqlite3_value_bytes(argv[1]); + if( zName==0 || n!=sizeof(pPtr) ){ + sqlite3_result_error(context, "argument type mismatch", -1); + return; + } + pPtr = *(void **)sqlite3_value_blob(argv[1]); + pOld = sqlite3Fts3HashInsert(pHash, (void *)zName, nName, pPtr); + if( pOld==pPtr ){ + sqlite3_result_error(context, "out of memory", -1); + } + }else{ + sqlite3_result_error(context, "fts3tokenize disabled", -1); + return; + } + }else{ + if( zName ){ + pPtr = sqlite3Fts3HashFind(pHash, zName, nName); + } + if( !pPtr ){ + char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName); + sqlite3_result_error(context, zErr, -1); + sqlite3_free(zErr); + return; + } + } + if( fts3TokenizerEnabled(context) || sqlite3_value_frombind(argv[0]) ){ + sqlite3_result_blob(context, (void *)&pPtr, sizeof(pPtr), SQLITE_TRANSIENT); + } +} + +SQLITE_PRIVATE int sqlite3Fts3IsIdChar(char c){ + static const char isFtsIdChar[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */ + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 5x */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6x */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 7x */ + }; + return (c&0x80 || isFtsIdChar[(int)(c)]); +} + +SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *zStr, int *pn){ + const char *z1; + const char *z2 = 0; + + /* Find the start of the next token. */ + z1 = zStr; + while( z2==0 ){ + char c = *z1; + switch( c ){ + case '\0': return 0; /* No more tokens here */ + case '\'': + case '"': + case '`': { + z2 = z1; + while( *++z2 && (*z2!=c || *++z2==c) ); + break; + } + case '[': + z2 = &z1[1]; + while( *z2 && z2[0]!=']' ) z2++; + if( *z2 ) z2++; + break; + + default: + if( sqlite3Fts3IsIdChar(*z1) ){ + z2 = &z1[1]; + while( sqlite3Fts3IsIdChar(*z2) ) z2++; + }else{ + z1++; + } + } + } + + *pn = (int)(z2-z1); + return z1; +} + +SQLITE_PRIVATE int sqlite3Fts3InitTokenizer( + Fts3Hash *pHash, /* Tokenizer hash table */ + const char *zArg, /* Tokenizer name */ + sqlite3_tokenizer **ppTok, /* OUT: Tokenizer (if applicable) */ + char **pzErr /* OUT: Set to malloced error message */ +){ + int rc; + char *z = (char *)zArg; + int n = 0; + char *zCopy; + char *zEnd; /* Pointer to nul-term of zCopy */ + sqlite3_tokenizer_module *m; + + zCopy = sqlite3_mprintf("%s", zArg); + if( !zCopy ) return SQLITE_NOMEM; + zEnd = &zCopy[strlen(zCopy)]; + + z = (char *)sqlite3Fts3NextToken(zCopy, &n); + if( z==0 ){ + assert( n==0 ); + z = zCopy; + } + z[n] = '\0'; + sqlite3Fts3Dequote(z); + + m = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash,z,(int)strlen(z)+1); + if( !m ){ + sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", z); + rc = SQLITE_ERROR; + }else{ + char const **aArg = 0; + int iArg = 0; + z = &z[n+1]; + while( zxCreate(iArg, aArg, ppTok); + assert( rc!=SQLITE_OK || *ppTok ); + if( rc!=SQLITE_OK ){ + sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer"); + }else{ + (*ppTok)->pModule = m; + } + sqlite3_free((void *)aArg); + } + + sqlite3_free(zCopy); + return rc; +} + + +#ifdef SQLITE_TEST + +#include "tclsqlite.h" +/* #include */ + +/* +** Implementation of a special SQL scalar function for testing tokenizers +** designed to be used in concert with the Tcl testing framework. This +** function must be called with two or more arguments: +** +** SELECT (, ..., ); +** +** where is the name passed as the second argument +** to the sqlite3Fts3InitHashTable() function (e.g. 'fts3_tokenizer') +** concatenated with the string '_test' (e.g. 'fts3_tokenizer_test'). +** +** The return value is a string that may be interpreted as a Tcl +** list. For each token in the , three elements are +** added to the returned list. The first is the token position, the +** second is the token text (folded, stemmed, etc.) and the third is the +** substring of associated with the token. For example, +** using the built-in "simple" tokenizer: +** +** SELECT fts_tokenizer_test('simple', 'I don't see how'); +** +** will return the string: +** +** "{0 i I 1 dont don't 2 see see 3 how how}" +** +*/ +static void testFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + Fts3Hash *pHash; + sqlite3_tokenizer_module *p; + sqlite3_tokenizer *pTokenizer = 0; + sqlite3_tokenizer_cursor *pCsr = 0; + + const char *zErr = 0; + + const char *zName; + int nName; + const char *zInput; + int nInput; + + const char *azArg[64]; + + const char *zToken; + int nToken = 0; + int iStart = 0; + int iEnd = 0; + int iPos = 0; + int i; + + Tcl_Obj *pRet; + + if( argc<2 ){ + sqlite3_result_error(context, "insufficient arguments", -1); + return; + } + + nName = sqlite3_value_bytes(argv[0]); + zName = (const char *)sqlite3_value_text(argv[0]); + nInput = sqlite3_value_bytes(argv[argc-1]); + zInput = (const char *)sqlite3_value_text(argv[argc-1]); + + pHash = (Fts3Hash *)sqlite3_user_data(context); + p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1); + + if( !p ){ + char *zErr2 = sqlite3_mprintf("unknown tokenizer: %s", zName); + sqlite3_result_error(context, zErr2, -1); + sqlite3_free(zErr2); + return; + } + + pRet = Tcl_NewObj(); + Tcl_IncrRefCount(pRet); + + for(i=1; ixCreate(argc-2, azArg, &pTokenizer) ){ + zErr = "error in xCreate()"; + goto finish; + } + pTokenizer->pModule = p; + if( sqlite3Fts3OpenTokenizer(pTokenizer, 0, zInput, nInput, &pCsr) ){ + zErr = "error in xOpen()"; + goto finish; + } + + while( SQLITE_OK==p->xNext(pCsr, &zToken, &nToken, &iStart, &iEnd, &iPos) ){ + Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(iPos)); + Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zToken, nToken)); + zToken = &zInput[iStart]; + nToken = iEnd-iStart; + Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zToken, nToken)); + } + + if( SQLITE_OK!=p->xClose(pCsr) ){ + zErr = "error in xClose()"; + goto finish; + } + if( SQLITE_OK!=p->xDestroy(pTokenizer) ){ + zErr = "error in xDestroy()"; + goto finish; + } + +finish: + if( zErr ){ + sqlite3_result_error(context, zErr, -1); + }else{ + sqlite3_result_text(context, Tcl_GetString(pRet), -1, SQLITE_TRANSIENT); + } + Tcl_DecrRefCount(pRet); +} + +static +int registerTokenizer( + sqlite3 *db, + char *zName, + const sqlite3_tokenizer_module *p +){ + int rc; + sqlite3_stmt *pStmt; + const char zSql[] = "SELECT fts3_tokenizer(?, ?)"; + + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + + sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC); + sqlite3_bind_blob(pStmt, 2, &p, sizeof(p), SQLITE_STATIC); + sqlite3_step(pStmt); + + return sqlite3_finalize(pStmt); +} + + +static +int queryTokenizer( + sqlite3 *db, + char *zName, + const sqlite3_tokenizer_module **pp +){ + int rc; + sqlite3_stmt *pStmt; + const char zSql[] = "SELECT fts3_tokenizer(?)"; + + *pp = 0; + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + + sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC); + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB + && sqlite3_column_bytes(pStmt, 0)==sizeof(*pp) + ){ + memcpy((void *)pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp)); + } + } + + return sqlite3_finalize(pStmt); +} + +SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule); + +/* +** Implementation of the scalar function fts3_tokenizer_internal_test(). +** This function is used for testing only, it is not included in the +** build unless SQLITE_TEST is defined. +** +** The purpose of this is to test that the fts3_tokenizer() function +** can be used as designed by the C-code in the queryTokenizer and +** registerTokenizer() functions above. These two functions are repeated +** in the README.tokenizer file as an example, so it is important to +** test them. +** +** To run the tests, evaluate the fts3_tokenizer_internal_test() scalar +** function with no arguments. An assert() will fail if a problem is +** detected. i.e.: +** +** SELECT fts3_tokenizer_internal_test(); +** +*/ +static void intTestFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int rc; + const sqlite3_tokenizer_module *p1; + const sqlite3_tokenizer_module *p2; + sqlite3 *db = (sqlite3 *)sqlite3_user_data(context); + + UNUSED_PARAMETER(argc); + UNUSED_PARAMETER(argv); + + /* Test the query function */ + sqlite3Fts3SimpleTokenizerModule(&p1); + rc = queryTokenizer(db, "simple", &p2); + assert( rc==SQLITE_OK ); + assert( p1==p2 ); + rc = queryTokenizer(db, "nosuchtokenizer", &p2); + assert( rc==SQLITE_ERROR ); + assert( p2==0 ); + assert( 0==strcmp(sqlite3_errmsg(db), "unknown tokenizer: nosuchtokenizer") ); + + /* Test the storage function */ + if( fts3TokenizerEnabled(context) ){ + rc = registerTokenizer(db, "nosuchtokenizer", p1); + assert( rc==SQLITE_OK ); + rc = queryTokenizer(db, "nosuchtokenizer", &p2); + assert( rc==SQLITE_OK ); + assert( p2==p1 ); + } + + sqlite3_result_text(context, "ok", -1, SQLITE_STATIC); +} + +#endif + +/* +** Set up SQL objects in database db used to access the contents of +** the hash table pointed to by argument pHash. The hash table must +** been initialized to use string keys, and to take a private copy +** of the key when a value is inserted. i.e. by a call similar to: +** +** sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1); +** +** This function adds a scalar function (see header comment above +** fts3TokenizerFunc() in this file for details) and, if ENABLE_TABLE is +** defined at compilation time, a temporary virtual table (see header +** comment above struct HashTableVtab) to the database schema. Both +** provide read/write access to the contents of *pHash. +** +** The third argument to this function, zName, is used as the name +** of both the scalar and, if created, the virtual table. +*/ +SQLITE_PRIVATE int sqlite3Fts3InitHashTable( + sqlite3 *db, + Fts3Hash *pHash, + const char *zName +){ + int rc = SQLITE_OK; + void *p = (void *)pHash; + const int any = SQLITE_UTF8|SQLITE_DIRECTONLY; + +#ifdef SQLITE_TEST + char *zTest = 0; + char *zTest2 = 0; + void *pdb = (void *)db; + zTest = sqlite3_mprintf("%s_test", zName); + zTest2 = sqlite3_mprintf("%s_internal_test", zName); + if( !zTest || !zTest2 ){ + rc = SQLITE_NOMEM; + } +#endif + + if( SQLITE_OK==rc ){ + rc = sqlite3_create_function(db, zName, 1, any, p, fts3TokenizerFunc, 0, 0); + } + if( SQLITE_OK==rc ){ + rc = sqlite3_create_function(db, zName, 2, any, p, fts3TokenizerFunc, 0, 0); + } +#ifdef SQLITE_TEST + if( SQLITE_OK==rc ){ + rc = sqlite3_create_function(db, zTest, -1, any, p, testFunc, 0, 0); + } + if( SQLITE_OK==rc ){ + rc = sqlite3_create_function(db, zTest2, 0, any, pdb, intTestFunc, 0, 0); + } +#endif + +#ifdef SQLITE_TEST + sqlite3_free(zTest); + sqlite3_free(zTest2); +#endif + + return rc; +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_tokenizer.c **************************************/ +/************** Begin file fts3_tokenizer1.c *********************************/ +/* +** 2006 Oct 10 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** Implementation of the "simple" full-text-search tokenizer. +*/ + +/* +** The code in this file is only compiled if: +** +** * The FTS3 module is being built as an extension +** (in which case SQLITE_CORE is not defined), or +** +** * The FTS3 module is being built into the core of +** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). +*/ +/* #include "fts3Int.h" */ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include */ +/* #include */ +/* #include */ +/* #include */ + +/* #include "fts3_tokenizer.h" */ + +typedef struct simple_tokenizer { + sqlite3_tokenizer base; + char delim[128]; /* flag ASCII delimiters */ +} simple_tokenizer; + +typedef struct simple_tokenizer_cursor { + sqlite3_tokenizer_cursor base; + const char *pInput; /* input we are tokenizing */ + int nBytes; /* size of the input */ + int iOffset; /* current position in pInput */ + int iToken; /* index of next token to be returned */ + char *pToken; /* storage for current token */ + int nTokenAllocated; /* space allocated to zToken buffer */ +} simple_tokenizer_cursor; + + +static int simpleDelim(simple_tokenizer *t, unsigned char c){ + return c<0x80 && t->delim[c]; +} +static int fts3_isalnum(int x){ + return (x>='0' && x<='9') || (x>='A' && x<='Z') || (x>='a' && x<='z'); +} + +/* +** Create a new tokenizer instance. +*/ +static int simpleCreate( + int argc, const char * const *argv, + sqlite3_tokenizer **ppTokenizer +){ + simple_tokenizer *t; + + t = (simple_tokenizer *) sqlite3_malloc(sizeof(*t)); + if( t==NULL ) return SQLITE_NOMEM; + memset(t, 0, sizeof(*t)); + + /* TODO(shess) Delimiters need to remain the same from run to run, + ** else we need to reindex. One solution would be a meta-table to + ** track such information in the database, then we'd only want this + ** information on the initial create. + */ + if( argc>1 ){ + int i, n = (int)strlen(argv[1]); + for(i=0; i=0x80 ){ + sqlite3_free(t); + return SQLITE_ERROR; + } + t->delim[ch] = 1; + } + } else { + /* Mark non-alphanumeric ASCII characters as delimiters */ + int i; + for(i=1; i<0x80; i++){ + t->delim[i] = !fts3_isalnum(i) ? -1 : 0; + } + } + + *ppTokenizer = &t->base; + return SQLITE_OK; +} + +/* +** Destroy a tokenizer +*/ +static int simpleDestroy(sqlite3_tokenizer *pTokenizer){ + sqlite3_free(pTokenizer); + return SQLITE_OK; +} + +/* +** Prepare to begin tokenizing a particular string. The input +** string to be tokenized is pInput[0..nBytes-1]. A cursor +** used to incrementally tokenize this string is returned in +** *ppCursor. +*/ +static int simpleOpen( + sqlite3_tokenizer *pTokenizer, /* The tokenizer */ + const char *pInput, int nBytes, /* String to be tokenized */ + sqlite3_tokenizer_cursor **ppCursor /* OUT: Tokenization cursor */ +){ + simple_tokenizer_cursor *c; + + UNUSED_PARAMETER(pTokenizer); + + c = (simple_tokenizer_cursor *) sqlite3_malloc(sizeof(*c)); + if( c==NULL ) return SQLITE_NOMEM; + + c->pInput = pInput; + if( pInput==0 ){ + c->nBytes = 0; + }else if( nBytes<0 ){ + c->nBytes = (int)strlen(pInput); + }else{ + c->nBytes = nBytes; + } + c->iOffset = 0; /* start tokenizing at the beginning */ + c->iToken = 0; + c->pToken = NULL; /* no space allocated, yet. */ + c->nTokenAllocated = 0; + + *ppCursor = &c->base; + return SQLITE_OK; +} + +/* +** Close a tokenization cursor previously opened by a call to +** simpleOpen() above. +*/ +static int simpleClose(sqlite3_tokenizer_cursor *pCursor){ + simple_tokenizer_cursor *c = (simple_tokenizer_cursor *) pCursor; + sqlite3_free(c->pToken); + sqlite3_free(c); + return SQLITE_OK; +} + +/* +** Extract the next token from a tokenization cursor. The cursor must +** have been opened by a prior call to simpleOpen(). +*/ +static int simpleNext( + sqlite3_tokenizer_cursor *pCursor, /* Cursor returned by simpleOpen */ + const char **ppToken, /* OUT: *ppToken is the token text */ + int *pnBytes, /* OUT: Number of bytes in token */ + int *piStartOffset, /* OUT: Starting offset of token */ + int *piEndOffset, /* OUT: Ending offset of token */ + int *piPosition /* OUT: Position integer of token */ +){ + simple_tokenizer_cursor *c = (simple_tokenizer_cursor *) pCursor; + simple_tokenizer *t = (simple_tokenizer *) pCursor->pTokenizer; + unsigned char *p = (unsigned char *)c->pInput; + + while( c->iOffsetnBytes ){ + int iStartOffset; + + /* Scan past delimiter characters */ + while( c->iOffsetnBytes && simpleDelim(t, p[c->iOffset]) ){ + c->iOffset++; + } + + /* Count non-delimiter characters. */ + iStartOffset = c->iOffset; + while( c->iOffsetnBytes && !simpleDelim(t, p[c->iOffset]) ){ + c->iOffset++; + } + + if( c->iOffset>iStartOffset ){ + int i, n = c->iOffset-iStartOffset; + if( n>c->nTokenAllocated ){ + char *pNew; + c->nTokenAllocated = n+20; + pNew = sqlite3_realloc64(c->pToken, c->nTokenAllocated); + if( !pNew ) return SQLITE_NOMEM; + c->pToken = pNew; + } + for(i=0; ipToken[i] = (char)((ch>='A' && ch<='Z') ? ch-'A'+'a' : ch); + } + *ppToken = c->pToken; + *pnBytes = n; + *piStartOffset = iStartOffset; + *piEndOffset = c->iOffset; + *piPosition = c->iToken++; + + return SQLITE_OK; + } + } + return SQLITE_DONE; +} + +/* +** The set of routines that implement the simple tokenizer +*/ +static const sqlite3_tokenizer_module simpleTokenizerModule = { + 0, + simpleCreate, + simpleDestroy, + simpleOpen, + simpleClose, + simpleNext, + 0, +}; + +/* +** Allocate a new simple tokenizer. Return a pointer to the new +** tokenizer in *ppModule +*/ +SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule( + sqlite3_tokenizer_module const**ppModule +){ + *ppModule = &simpleTokenizerModule; +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_tokenizer1.c *************************************/ +/************** Begin file fts3_tokenize_vtab.c ******************************/ +/* +** 2013 Apr 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains code for the "fts3tokenize" virtual table module. +** An fts3tokenize virtual table is created as follows: +** +** CREATE VIRTUAL TABLE USING fts3tokenize( +** , , ... +** ); +** +** The table created has the following schema: +** +** CREATE TABLE (input, token, start, end, position) +** +** When queried, the query must include a WHERE clause of type: +** +** input = +** +** The virtual table module tokenizes this , using the FTS3 +** tokenizer specified by the arguments to the CREATE VIRTUAL TABLE +** statement and returns one row for each token in the result. With +** fields set as follows: +** +** input: Always set to a copy of +** token: A token from the input. +** start: Byte offset of the token within the input . +** end: Byte offset of the byte immediately following the end of the +** token within the input string. +** pos: Token offset of token within input. +** +*/ +/* #include "fts3Int.h" */ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include */ +/* #include */ + +typedef struct Fts3tokTable Fts3tokTable; +typedef struct Fts3tokCursor Fts3tokCursor; + +/* +** Virtual table structure. +*/ +struct Fts3tokTable { + sqlite3_vtab base; /* Base class used by SQLite core */ + const sqlite3_tokenizer_module *pMod; + sqlite3_tokenizer *pTok; +}; + +/* +** Virtual table cursor structure. +*/ +struct Fts3tokCursor { + sqlite3_vtab_cursor base; /* Base class used by SQLite core */ + char *zInput; /* Input string */ + sqlite3_tokenizer_cursor *pCsr; /* Cursor to iterate through zInput */ + int iRowid; /* Current 'rowid' value */ + const char *zToken; /* Current 'token' value */ + int nToken; /* Size of zToken in bytes */ + int iStart; /* Current 'start' value */ + int iEnd; /* Current 'end' value */ + int iPos; /* Current 'pos' value */ +}; + +/* +** Query FTS for the tokenizer implementation named zName. +*/ +static int fts3tokQueryTokenizer( + Fts3Hash *pHash, + const char *zName, + const sqlite3_tokenizer_module **pp, + char **pzErr +){ + sqlite3_tokenizer_module *p; + int nName = (int)strlen(zName); + + p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1); + if( !p ){ + sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", zName); + return SQLITE_ERROR; + } + + *pp = p; + return SQLITE_OK; +} + +/* +** The second argument, argv[], is an array of pointers to nul-terminated +** strings. This function makes a copy of the array and strings into a +** single block of memory. It then dequotes any of the strings that appear +** to be quoted. +** +** If successful, output parameter *pazDequote is set to point at the +** array of dequoted strings and SQLITE_OK is returned. The caller is +** responsible for eventually calling sqlite3_free() to free the array +** in this case. Or, if an error occurs, an SQLite error code is returned. +** The final value of *pazDequote is undefined in this case. +*/ +static int fts3tokDequoteArray( + int argc, /* Number of elements in argv[] */ + const char * const *argv, /* Input array */ + char ***pazDequote /* Output array */ +){ + int rc = SQLITE_OK; /* Return code */ + if( argc==0 ){ + *pazDequote = 0; + }else{ + int i; + int nByte = 0; + char **azDequote; + + for(i=0; i1 ) azArg = (const char * const *)&azDequote[1]; + rc = pMod->xCreate((nDequote>1 ? nDequote-1 : 0), azArg, &pTok); + } + + if( rc==SQLITE_OK ){ + pTab = (Fts3tokTable *)sqlite3_malloc(sizeof(Fts3tokTable)); + if( pTab==0 ){ + rc = SQLITE_NOMEM; + } + } + + if( rc==SQLITE_OK ){ + memset(pTab, 0, sizeof(Fts3tokTable)); + pTab->pMod = pMod; + pTab->pTok = pTok; + *ppVtab = &pTab->base; + }else{ + if( pTok ){ + pMod->xDestroy(pTok); + } + } + + sqlite3_free(azDequote); + return rc; +} + +/* +** This function does the work for both the xDisconnect and xDestroy methods. +** These tables have no persistent representation of their own, so xDisconnect +** and xDestroy are identical operations. +*/ +static int fts3tokDisconnectMethod(sqlite3_vtab *pVtab){ + Fts3tokTable *pTab = (Fts3tokTable *)pVtab; + + pTab->pMod->xDestroy(pTab->pTok); + sqlite3_free(pTab); + return SQLITE_OK; +} + +/* +** xBestIndex - Analyze a WHERE and ORDER BY clause. +*/ +static int fts3tokBestIndexMethod( + sqlite3_vtab *pVTab, + sqlite3_index_info *pInfo +){ + int i; + UNUSED_PARAMETER(pVTab); + + for(i=0; inConstraint; i++){ + if( pInfo->aConstraint[i].usable + && pInfo->aConstraint[i].iColumn==0 + && pInfo->aConstraint[i].op==SQLITE_INDEX_CONSTRAINT_EQ + ){ + pInfo->idxNum = 1; + pInfo->aConstraintUsage[i].argvIndex = 1; + pInfo->aConstraintUsage[i].omit = 1; + pInfo->estimatedCost = 1; + return SQLITE_OK; + } + } + + pInfo->idxNum = 0; + assert( pInfo->estimatedCost>1000000.0 ); + + return SQLITE_OK; +} + +/* +** xOpen - Open a cursor. +*/ +static int fts3tokOpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ + Fts3tokCursor *pCsr; + UNUSED_PARAMETER(pVTab); + + pCsr = (Fts3tokCursor *)sqlite3_malloc(sizeof(Fts3tokCursor)); + if( pCsr==0 ){ + return SQLITE_NOMEM; + } + memset(pCsr, 0, sizeof(Fts3tokCursor)); + + *ppCsr = (sqlite3_vtab_cursor *)pCsr; + return SQLITE_OK; +} + +/* +** Reset the tokenizer cursor passed as the only argument. As if it had +** just been returned by fts3tokOpenMethod(). +*/ +static void fts3tokResetCursor(Fts3tokCursor *pCsr){ + if( pCsr->pCsr ){ + Fts3tokTable *pTab = (Fts3tokTable *)(pCsr->base.pVtab); + pTab->pMod->xClose(pCsr->pCsr); + pCsr->pCsr = 0; + } + sqlite3_free(pCsr->zInput); + pCsr->zInput = 0; + pCsr->zToken = 0; + pCsr->nToken = 0; + pCsr->iStart = 0; + pCsr->iEnd = 0; + pCsr->iPos = 0; + pCsr->iRowid = 0; +} + +/* +** xClose - Close a cursor. +*/ +static int fts3tokCloseMethod(sqlite3_vtab_cursor *pCursor){ + Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; + + fts3tokResetCursor(pCsr); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +/* +** xNext - Advance the cursor to the next row, if any. +*/ +static int fts3tokNextMethod(sqlite3_vtab_cursor *pCursor){ + Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; + Fts3tokTable *pTab = (Fts3tokTable *)(pCursor->pVtab); + int rc; /* Return code */ + + pCsr->iRowid++; + rc = pTab->pMod->xNext(pCsr->pCsr, + &pCsr->zToken, &pCsr->nToken, + &pCsr->iStart, &pCsr->iEnd, &pCsr->iPos + ); + + if( rc!=SQLITE_OK ){ + fts3tokResetCursor(pCsr); + if( rc==SQLITE_DONE ) rc = SQLITE_OK; + } + + return rc; +} + +/* +** xFilter - Initialize a cursor to point at the start of its data. +*/ +static int fts3tokFilterMethod( + sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ + int idxNum, /* Strategy index */ + const char *idxStr, /* Unused */ + int nVal, /* Number of elements in apVal */ + sqlite3_value **apVal /* Arguments for the indexing scheme */ +){ + int rc = SQLITE_ERROR; + Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; + Fts3tokTable *pTab = (Fts3tokTable *)(pCursor->pVtab); + UNUSED_PARAMETER(idxStr); + UNUSED_PARAMETER(nVal); + + fts3tokResetCursor(pCsr); + if( idxNum==1 ){ + const char *zByte = (const char *)sqlite3_value_text(apVal[0]); + sqlite3_int64 nByte = sqlite3_value_bytes(apVal[0]); + pCsr->zInput = sqlite3_malloc64(nByte+1); + if( pCsr->zInput==0 ){ + rc = SQLITE_NOMEM; + }else{ + if( nByte>0 ) memcpy(pCsr->zInput, zByte, nByte); + pCsr->zInput[nByte] = 0; + rc = pTab->pMod->xOpen(pTab->pTok, pCsr->zInput, nByte, &pCsr->pCsr); + if( rc==SQLITE_OK ){ + pCsr->pCsr->pTokenizer = pTab->pTok; + } + } + } + + if( rc!=SQLITE_OK ) return rc; + return fts3tokNextMethod(pCursor); +} + +/* +** xEof - Return true if the cursor is at EOF, or false otherwise. +*/ +static int fts3tokEofMethod(sqlite3_vtab_cursor *pCursor){ + Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; + return (pCsr->zToken==0); +} + +/* +** xColumn - Return a column value. +*/ +static int fts3tokColumnMethod( + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ + sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */ + int iCol /* Index of column to read value from */ +){ + Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; + + /* CREATE TABLE x(input, token, start, end, position) */ + switch( iCol ){ + case 0: + sqlite3_result_text(pCtx, pCsr->zInput, -1, SQLITE_TRANSIENT); + break; + case 1: + sqlite3_result_text(pCtx, pCsr->zToken, pCsr->nToken, SQLITE_TRANSIENT); + break; + case 2: + sqlite3_result_int(pCtx, pCsr->iStart); + break; + case 3: + sqlite3_result_int(pCtx, pCsr->iEnd); + break; + default: + assert( iCol==4 ); + sqlite3_result_int(pCtx, pCsr->iPos); + break; + } + return SQLITE_OK; +} + +/* +** xRowid - Return the current rowid for the cursor. +*/ +static int fts3tokRowidMethod( + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ + sqlite_int64 *pRowid /* OUT: Rowid value */ +){ + Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; + *pRowid = (sqlite3_int64)pCsr->iRowid; + return SQLITE_OK; +} + +/* +** Register the fts3tok module with database connection db. Return SQLITE_OK +** if successful or an error code if sqlite3_create_module() fails. +*/ +SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash, void(*xDestroy)(void*)){ + static const sqlite3_module fts3tok_module = { + 0, /* iVersion */ + fts3tokConnectMethod, /* xCreate */ + fts3tokConnectMethod, /* xConnect */ + fts3tokBestIndexMethod, /* xBestIndex */ + fts3tokDisconnectMethod, /* xDisconnect */ + fts3tokDisconnectMethod, /* xDestroy */ + fts3tokOpenMethod, /* xOpen */ + fts3tokCloseMethod, /* xClose */ + fts3tokFilterMethod, /* xFilter */ + fts3tokNextMethod, /* xNext */ + fts3tokEofMethod, /* xEof */ + fts3tokColumnMethod, /* xColumn */ + fts3tokRowidMethod, /* xRowid */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindFunction */ + 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ + }; + int rc; /* Return code */ + + rc = sqlite3_create_module_v2( + db, "fts3tokenize", &fts3tok_module, (void*)pHash, xDestroy + ); + return rc; +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_tokenize_vtab.c **********************************/ +/************** Begin file fts3_write.c **************************************/ +/* +** 2009 Oct 23 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file is part of the SQLite FTS3 extension module. Specifically, +** this file contains code to insert, update and delete rows from FTS3 +** tables. It also contains code to merge FTS3 b-tree segments. Some +** of the sub-routines used to merge segments are also used by the query +** code in fts3.c. +*/ + +/* #include "fts3Int.h" */ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include */ +/* #include */ +/* #include */ +/* #include */ + +#define FTS_MAX_APPENDABLE_HEIGHT 16 + +/* +** When full-text index nodes are loaded from disk, the buffer that they +** are loaded into has the following number of bytes of padding at the end +** of it. i.e. if a full-text index node is 900 bytes in size, then a buffer +** of 920 bytes is allocated for it. +** +** This means that if we have a pointer into a buffer containing node data, +** it is always safe to read up to two varints from it without risking an +** overread, even if the node data is corrupted. +*/ +#define FTS3_NODE_PADDING (FTS3_VARINT_MAX*2) + +/* +** Under certain circumstances, b-tree nodes (doclists) can be loaded into +** memory incrementally instead of all at once. This can be a big performance +** win (reduced IO and CPU) if SQLite stops calling the virtual table xNext() +** method before retrieving all query results (as may happen, for example, +** if a query has a LIMIT clause). +** +** Incremental loading is used for b-tree nodes FTS3_NODE_CHUNK_THRESHOLD +** bytes and larger. Nodes are loaded in chunks of FTS3_NODE_CHUNKSIZE bytes. +** The code is written so that the hard lower-limit for each of these values +** is 1. Clearly such small values would be inefficient, but can be useful +** for testing purposes. +** +** If this module is built with SQLITE_TEST defined, these constants may +** be overridden at runtime for testing purposes. File fts3_test.c contains +** a Tcl interface to read and write the values. +*/ +#ifdef SQLITE_TEST +int test_fts3_node_chunksize = (4*1024); +int test_fts3_node_chunk_threshold = (4*1024)*4; +# define FTS3_NODE_CHUNKSIZE test_fts3_node_chunksize +# define FTS3_NODE_CHUNK_THRESHOLD test_fts3_node_chunk_threshold +#else +# define FTS3_NODE_CHUNKSIZE (4*1024) +# define FTS3_NODE_CHUNK_THRESHOLD (FTS3_NODE_CHUNKSIZE*4) +#endif + +/* +** The values that may be meaningfully bound to the :1 parameter in +** statements SQL_REPLACE_STAT and SQL_SELECT_STAT. +*/ +#define FTS_STAT_DOCTOTAL 0 +#define FTS_STAT_INCRMERGEHINT 1 +#define FTS_STAT_AUTOINCRMERGE 2 + +/* +** If FTS_LOG_MERGES is defined, call sqlite3_log() to report each automatic +** and incremental merge operation that takes place. This is used for +** debugging FTS only, it should not usually be turned on in production +** systems. +*/ +#ifdef FTS3_LOG_MERGES +static void fts3LogMerge(int nMerge, sqlite3_int64 iAbsLevel){ + sqlite3_log(SQLITE_OK, "%d-way merge from level %d", nMerge, (int)iAbsLevel); +} +#else +#define fts3LogMerge(x, y) +#endif + + +typedef struct PendingList PendingList; +typedef struct SegmentNode SegmentNode; +typedef struct SegmentWriter SegmentWriter; + +/* +** An instance of the following data structure is used to build doclists +** incrementally. See function fts3PendingListAppend() for details. +*/ +struct PendingList { + sqlite3_int64 nData; + char *aData; + sqlite3_int64 nSpace; + sqlite3_int64 iLastDocid; + sqlite3_int64 iLastCol; + sqlite3_int64 iLastPos; +}; + + +/* +** Each cursor has a (possibly empty) linked list of the following objects. +*/ +struct Fts3DeferredToken { + Fts3PhraseToken *pToken; /* Pointer to corresponding expr token */ + int iCol; /* Column token must occur in */ + Fts3DeferredToken *pNext; /* Next in list of deferred tokens */ + PendingList *pList; /* Doclist is assembled here */ +}; + +/* +** An instance of this structure is used to iterate through the terms on +** a contiguous set of segment b-tree leaf nodes. Although the details of +** this structure are only manipulated by code in this file, opaque handles +** of type Fts3SegReader* are also used by code in fts3.c to iterate through +** terms when querying the full-text index. See functions: +** +** sqlite3Fts3SegReaderNew() +** sqlite3Fts3SegReaderFree() +** sqlite3Fts3SegReaderIterate() +** +** Methods used to manipulate Fts3SegReader structures: +** +** fts3SegReaderNext() +** fts3SegReaderFirstDocid() +** fts3SegReaderNextDocid() +*/ +struct Fts3SegReader { + int iIdx; /* Index within level, or 0x7FFFFFFF for PT */ + u8 bLookup; /* True for a lookup only */ + u8 rootOnly; /* True for a root-only reader */ + + sqlite3_int64 iStartBlock; /* Rowid of first leaf block to traverse */ + sqlite3_int64 iLeafEndBlock; /* Rowid of final leaf block to traverse */ + sqlite3_int64 iEndBlock; /* Rowid of final block in segment (or 0) */ + sqlite3_int64 iCurrentBlock; /* Current leaf block (or 0) */ + + char *aNode; /* Pointer to node data (or NULL) */ + int nNode; /* Size of buffer at aNode (or 0) */ + int nPopulate; /* If >0, bytes of buffer aNode[] loaded */ + sqlite3_blob *pBlob; /* If not NULL, blob handle to read node */ + + Fts3HashElem **ppNextElem; + + /* Variables set by fts3SegReaderNext(). These may be read directly + ** by the caller. They are valid from the time SegmentReaderNew() returns + ** until SegmentReaderNext() returns something other than SQLITE_OK + ** (i.e. SQLITE_DONE). + */ + int nTerm; /* Number of bytes in current term */ + char *zTerm; /* Pointer to current term */ + int nTermAlloc; /* Allocated size of zTerm buffer */ + char *aDoclist; /* Pointer to doclist of current entry */ + int nDoclist; /* Size of doclist in current entry */ + + /* The following variables are used by fts3SegReaderNextDocid() to iterate + ** through the current doclist (aDoclist/nDoclist). + */ + char *pOffsetList; + int nOffsetList; /* For descending pending seg-readers only */ + sqlite3_int64 iDocid; +}; + +#define fts3SegReaderIsPending(p) ((p)->ppNextElem!=0) +#define fts3SegReaderIsRootOnly(p) ((p)->rootOnly!=0) + +/* +** An instance of this structure is used to create a segment b-tree in the +** database. The internal details of this type are only accessed by the +** following functions: +** +** fts3SegWriterAdd() +** fts3SegWriterFlush() +** fts3SegWriterFree() +*/ +struct SegmentWriter { + SegmentNode *pTree; /* Pointer to interior tree structure */ + sqlite3_int64 iFirst; /* First slot in %_segments written */ + sqlite3_int64 iFree; /* Next free slot in %_segments */ + char *zTerm; /* Pointer to previous term buffer */ + int nTerm; /* Number of bytes in zTerm */ + int nMalloc; /* Size of malloc'd buffer at zMalloc */ + char *zMalloc; /* Malloc'd space (possibly) used for zTerm */ + int nSize; /* Size of allocation at aData */ + int nData; /* Bytes of data in aData */ + char *aData; /* Pointer to block from malloc() */ + i64 nLeafData; /* Number of bytes of leaf data written */ +}; + +/* +** Type SegmentNode is used by the following three functions to create +** the interior part of the segment b+-tree structures (everything except +** the leaf nodes). These functions and type are only ever used by code +** within the fts3SegWriterXXX() family of functions described above. +** +** fts3NodeAddTerm() +** fts3NodeWrite() +** fts3NodeFree() +** +** When a b+tree is written to the database (either as a result of a merge +** or the pending-terms table being flushed), leaves are written into the +** database file as soon as they are completely populated. The interior of +** the tree is assembled in memory and written out only once all leaves have +** been populated and stored. This is Ok, as the b+-tree fanout is usually +** very large, meaning that the interior of the tree consumes relatively +** little memory. +*/ +struct SegmentNode { + SegmentNode *pParent; /* Parent node (or NULL for root node) */ + SegmentNode *pRight; /* Pointer to right-sibling */ + SegmentNode *pLeftmost; /* Pointer to left-most node of this depth */ + int nEntry; /* Number of terms written to node so far */ + char *zTerm; /* Pointer to previous term buffer */ + int nTerm; /* Number of bytes in zTerm */ + int nMalloc; /* Size of malloc'd buffer at zMalloc */ + char *zMalloc; /* Malloc'd space (possibly) used for zTerm */ + int nData; /* Bytes of valid data so far */ + char *aData; /* Node data */ +}; + +/* +** Valid values for the second argument to fts3SqlStmt(). +*/ +#define SQL_DELETE_CONTENT 0 +#define SQL_IS_EMPTY 1 +#define SQL_DELETE_ALL_CONTENT 2 +#define SQL_DELETE_ALL_SEGMENTS 3 +#define SQL_DELETE_ALL_SEGDIR 4 +#define SQL_DELETE_ALL_DOCSIZE 5 +#define SQL_DELETE_ALL_STAT 6 +#define SQL_SELECT_CONTENT_BY_ROWID 7 +#define SQL_NEXT_SEGMENT_INDEX 8 +#define SQL_INSERT_SEGMENTS 9 +#define SQL_NEXT_SEGMENTS_ID 10 +#define SQL_INSERT_SEGDIR 11 +#define SQL_SELECT_LEVEL 12 +#define SQL_SELECT_LEVEL_RANGE 13 +#define SQL_SELECT_LEVEL_COUNT 14 +#define SQL_SELECT_SEGDIR_MAX_LEVEL 15 +#define SQL_DELETE_SEGDIR_LEVEL 16 +#define SQL_DELETE_SEGMENTS_RANGE 17 +#define SQL_CONTENT_INSERT 18 +#define SQL_DELETE_DOCSIZE 19 +#define SQL_REPLACE_DOCSIZE 20 +#define SQL_SELECT_DOCSIZE 21 +#define SQL_SELECT_STAT 22 +#define SQL_REPLACE_STAT 23 + +#define SQL_SELECT_ALL_PREFIX_LEVEL 24 +#define SQL_DELETE_ALL_TERMS_SEGDIR 25 +#define SQL_DELETE_SEGDIR_RANGE 26 +#define SQL_SELECT_ALL_LANGID 27 +#define SQL_FIND_MERGE_LEVEL 28 +#define SQL_MAX_LEAF_NODE_ESTIMATE 29 +#define SQL_DELETE_SEGDIR_ENTRY 30 +#define SQL_SHIFT_SEGDIR_ENTRY 31 +#define SQL_SELECT_SEGDIR 32 +#define SQL_CHOMP_SEGDIR 33 +#define SQL_SEGMENT_IS_APPENDABLE 34 +#define SQL_SELECT_INDEXES 35 +#define SQL_SELECT_MXLEVEL 36 + +#define SQL_SELECT_LEVEL_RANGE2 37 +#define SQL_UPDATE_LEVEL_IDX 38 +#define SQL_UPDATE_LEVEL 39 + +/* +** Wrapper around sqlite3_prepare_v3() to ensure that SQLITE_PREPARE_FROM_DDL +** is always set. +*/ +SQLITE_PRIVATE int sqlite3Fts3PrepareStmt( + Fts3Table *p, /* Prepare for this connection */ + const char *zSql, /* SQL to prepare */ + int bPersist, /* True to set SQLITE_PREPARE_PERSISTENT */ + int bAllowVtab, /* True to omit SQLITE_PREPARE_NO_VTAB */ + sqlite3_stmt **pp /* OUT: Prepared statement */ +){ + int f = SQLITE_PREPARE_FROM_DDL + |((bAllowVtab==0) ? SQLITE_PREPARE_NO_VTAB : 0) + |(bPersist ? SQLITE_PREPARE_PERSISTENT : 0); + + return sqlite3_prepare_v3(p->db, zSql, -1, f, pp, NULL); +} + +/* +** This function is used to obtain an SQLite prepared statement handle +** for the statement identified by the second argument. If successful, +** *pp is set to the requested statement handle and SQLITE_OK returned. +** Otherwise, an SQLite error code is returned and *pp is set to 0. +** +** If argument apVal is not NULL, then it must point to an array with +** at least as many entries as the requested statement has bound +** parameters. The values are bound to the statements parameters before +** returning. +*/ +static int fts3SqlStmt( + Fts3Table *p, /* Virtual table handle */ + int eStmt, /* One of the SQL_XXX constants above */ + sqlite3_stmt **pp, /* OUT: Statement handle */ + sqlite3_value **apVal /* Values to bind to statement */ +){ + const char *azSql[] = { +/* 0 */ "DELETE FROM %Q.'%q_content' WHERE rowid = ?", +/* 1 */ "SELECT NOT EXISTS(SELECT docid FROM %Q.'%q_content' WHERE rowid!=?)", +/* 2 */ "DELETE FROM %Q.'%q_content'", +/* 3 */ "DELETE FROM %Q.'%q_segments'", +/* 4 */ "DELETE FROM %Q.'%q_segdir'", +/* 5 */ "DELETE FROM %Q.'%q_docsize'", +/* 6 */ "DELETE FROM %Q.'%q_stat'", +/* 7 */ "SELECT %s WHERE rowid=?", +/* 8 */ "SELECT (SELECT max(idx) FROM %Q.'%q_segdir' WHERE level = ?) + 1", +/* 9 */ "REPLACE INTO %Q.'%q_segments'(blockid, block) VALUES(?, ?)", +/* 10 */ "SELECT coalesce((SELECT max(blockid) FROM %Q.'%q_segments') + 1, 1)", +/* 11 */ "REPLACE INTO %Q.'%q_segdir' VALUES(?,?,?,?,?,?)", + + /* Return segments in order from oldest to newest.*/ +/* 12 */ "SELECT idx, start_block, leaves_end_block, end_block, root " + "FROM %Q.'%q_segdir' WHERE level = ? ORDER BY idx ASC", +/* 13 */ "SELECT idx, start_block, leaves_end_block, end_block, root " + "FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?" + "ORDER BY level DESC, idx ASC", + +/* 14 */ "SELECT count(*) FROM %Q.'%q_segdir' WHERE level = ?", +/* 15 */ "SELECT max(level) FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?", + +/* 16 */ "DELETE FROM %Q.'%q_segdir' WHERE level = ?", +/* 17 */ "DELETE FROM %Q.'%q_segments' WHERE blockid BETWEEN ? AND ?", +/* 18 */ "INSERT INTO %Q.'%q_content' VALUES(%s)", +/* 19 */ "DELETE FROM %Q.'%q_docsize' WHERE docid = ?", +/* 20 */ "REPLACE INTO %Q.'%q_docsize' VALUES(?,?)", +/* 21 */ "SELECT size FROM %Q.'%q_docsize' WHERE docid=?", +/* 22 */ "SELECT value FROM %Q.'%q_stat' WHERE id=?", +/* 23 */ "REPLACE INTO %Q.'%q_stat' VALUES(?,?)", +/* 24 */ "", +/* 25 */ "", + +/* 26 */ "DELETE FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?", +/* 27 */ "SELECT ? UNION SELECT level / (1024 * ?) FROM %Q.'%q_segdir'", + +/* This statement is used to determine which level to read the input from +** when performing an incremental merge. It returns the absolute level number +** of the oldest level in the db that contains at least ? segments. Or, +** if no level in the FTS index contains more than ? segments, the statement +** returns zero rows. */ +/* 28 */ "SELECT level, count(*) AS cnt FROM %Q.'%q_segdir' " + " GROUP BY level HAVING cnt>=?" + " ORDER BY (level %% 1024) ASC, 2 DESC LIMIT 1", + +/* Estimate the upper limit on the number of leaf nodes in a new segment +** created by merging the oldest :2 segments from absolute level :1. See +** function sqlite3Fts3Incrmerge() for details. */ +/* 29 */ "SELECT 2 * total(1 + leaves_end_block - start_block) " + " FROM (SELECT * FROM %Q.'%q_segdir' " + " WHERE level = ? ORDER BY idx ASC LIMIT ?" + " )", + +/* SQL_DELETE_SEGDIR_ENTRY +** Delete the %_segdir entry on absolute level :1 with index :2. */ +/* 30 */ "DELETE FROM %Q.'%q_segdir' WHERE level = ? AND idx = ?", + +/* SQL_SHIFT_SEGDIR_ENTRY +** Modify the idx value for the segment with idx=:3 on absolute level :2 +** to :1. */ +/* 31 */ "UPDATE %Q.'%q_segdir' SET idx = ? WHERE level=? AND idx=?", + +/* SQL_SELECT_SEGDIR +** Read a single entry from the %_segdir table. The entry from absolute +** level :1 with index value :2. */ +/* 32 */ "SELECT idx, start_block, leaves_end_block, end_block, root " + "FROM %Q.'%q_segdir' WHERE level = ? AND idx = ?", + +/* SQL_CHOMP_SEGDIR +** Update the start_block (:1) and root (:2) fields of the %_segdir +** entry located on absolute level :3 with index :4. */ +/* 33 */ "UPDATE %Q.'%q_segdir' SET start_block = ?, root = ?" + "WHERE level = ? AND idx = ?", + +/* SQL_SEGMENT_IS_APPENDABLE +** Return a single row if the segment with end_block=? is appendable. Or +** no rows otherwise. */ +/* 34 */ "SELECT 1 FROM %Q.'%q_segments' WHERE blockid=? AND block IS NULL", + +/* SQL_SELECT_INDEXES +** Return the list of valid segment indexes for absolute level ? */ +/* 35 */ "SELECT idx FROM %Q.'%q_segdir' WHERE level=? ORDER BY 1 ASC", + +/* SQL_SELECT_MXLEVEL +** Return the largest relative level in the FTS index or indexes. */ +/* 36 */ "SELECT max( level %% 1024 ) FROM %Q.'%q_segdir'", + + /* Return segments in order from oldest to newest.*/ +/* 37 */ "SELECT level, idx, end_block " + "FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ? " + "ORDER BY level DESC, idx ASC", + + /* Update statements used while promoting segments */ +/* 38 */ "UPDATE OR FAIL %Q.'%q_segdir' SET level=-1,idx=? " + "WHERE level=? AND idx=?", +/* 39 */ "UPDATE OR FAIL %Q.'%q_segdir' SET level=? WHERE level=-1" + + }; + int rc = SQLITE_OK; + sqlite3_stmt *pStmt; + + assert( SizeofArray(azSql)==SizeofArray(p->aStmt) ); + assert( eStmt=0 ); + + pStmt = p->aStmt[eStmt]; + if( !pStmt ){ + int bAllowVtab = 0; + char *zSql; + if( eStmt==SQL_CONTENT_INSERT ){ + zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName, p->zWriteExprlist); + }else if( eStmt==SQL_SELECT_CONTENT_BY_ROWID ){ + bAllowVtab = 1; + zSql = sqlite3_mprintf(azSql[eStmt], p->zReadExprlist); + }else{ + zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName); + } + if( !zSql ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3Fts3PrepareStmt(p, zSql, 1, bAllowVtab, &pStmt); + sqlite3_free(zSql); + assert( rc==SQLITE_OK || pStmt==0 ); + p->aStmt[eStmt] = pStmt; + } + } + if( apVal ){ + int i; + int nParam = sqlite3_bind_parameter_count(pStmt); + for(i=0; rc==SQLITE_OK && inPendingData==0 ){ + sqlite3_stmt *pStmt; + rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_LEVEL, &pStmt, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_null(pStmt, 1); + sqlite3_step(pStmt); + rc = sqlite3_reset(pStmt); + } + } + + return rc; +} + +/* +** FTS maintains a separate indexes for each language-id (a 32-bit integer). +** Within each language id, a separate index is maintained to store the +** document terms, and each configured prefix size (configured the FTS +** "prefix=" option). And each index consists of multiple levels ("relative +** levels"). +** +** All three of these values (the language id, the specific index and the +** level within the index) are encoded in 64-bit integer values stored +** in the %_segdir table on disk. This function is used to convert three +** separate component values into the single 64-bit integer value that +** can be used to query the %_segdir table. +** +** Specifically, each language-id/index combination is allocated 1024 +** 64-bit integer level values ("absolute levels"). The main terms index +** for language-id 0 is allocate values 0-1023. The first prefix index +** (if any) for language-id 0 is allocated values 1024-2047. And so on. +** Language 1 indexes are allocated immediately following language 0. +** +** So, for a system with nPrefix prefix indexes configured, the block of +** absolute levels that corresponds to language-id iLangid and index +** iIndex starts at absolute level ((iLangid * (nPrefix+1) + iIndex) * 1024). +*/ +static sqlite3_int64 getAbsoluteLevel( + Fts3Table *p, /* FTS3 table handle */ + int iLangid, /* Language id */ + int iIndex, /* Index in p->aIndex[] */ + int iLevel /* Level of segments */ +){ + sqlite3_int64 iBase; /* First absolute level for iLangid/iIndex */ + assert_fts3_nc( iLangid>=0 ); + assert( p->nIndex>0 ); + assert( iIndex>=0 && iIndexnIndex ); + + iBase = ((sqlite3_int64)iLangid * p->nIndex + iIndex) * FTS3_SEGDIR_MAXLEVEL; + return iBase + iLevel; +} + +/* +** Set *ppStmt to a statement handle that may be used to iterate through +** all rows in the %_segdir table, from oldest to newest. If successful, +** return SQLITE_OK. If an error occurs while preparing the statement, +** return an SQLite error code. +** +** There is only ever one instance of this SQL statement compiled for +** each FTS3 table. +** +** The statement returns the following columns from the %_segdir table: +** +** 0: idx +** 1: start_block +** 2: leaves_end_block +** 3: end_block +** 4: root +*/ +SQLITE_PRIVATE int sqlite3Fts3AllSegdirs( + Fts3Table *p, /* FTS3 table */ + int iLangid, /* Language being queried */ + int iIndex, /* Index for p->aIndex[] */ + int iLevel, /* Level to select (relative level) */ + sqlite3_stmt **ppStmt /* OUT: Compiled statement */ +){ + int rc; + sqlite3_stmt *pStmt = 0; + + assert( iLevel==FTS3_SEGCURSOR_ALL || iLevel>=0 ); + assert( iLevel=0 && iIndexnIndex ); + + if( iLevel<0 ){ + /* "SELECT * FROM %_segdir WHERE level BETWEEN ? AND ? ORDER BY ..." */ + rc = fts3SqlStmt(p, SQL_SELECT_LEVEL_RANGE, &pStmt, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pStmt, 1, getAbsoluteLevel(p, iLangid, iIndex, 0)); + sqlite3_bind_int64(pStmt, 2, + getAbsoluteLevel(p, iLangid, iIndex, FTS3_SEGDIR_MAXLEVEL-1) + ); + } + }else{ + /* "SELECT * FROM %_segdir WHERE level = ? ORDER BY ..." */ + rc = fts3SqlStmt(p, SQL_SELECT_LEVEL, &pStmt, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pStmt, 1, getAbsoluteLevel(p, iLangid, iIndex,iLevel)); + } + } + *ppStmt = pStmt; + return rc; +} + + +/* +** Append a single varint to a PendingList buffer. SQLITE_OK is returned +** if successful, or an SQLite error code otherwise. +** +** This function also serves to allocate the PendingList structure itself. +** For example, to create a new PendingList structure containing two +** varints: +** +** PendingList *p = 0; +** fts3PendingListAppendVarint(&p, 1); +** fts3PendingListAppendVarint(&p, 2); +*/ +static int fts3PendingListAppendVarint( + PendingList **pp, /* IN/OUT: Pointer to PendingList struct */ + sqlite3_int64 i /* Value to append to data */ +){ + PendingList *p = *pp; + + /* Allocate or grow the PendingList as required. */ + if( !p ){ + p = sqlite3_malloc64(sizeof(*p) + 100); + if( !p ){ + return SQLITE_NOMEM; + } + p->nSpace = 100; + p->aData = (char *)&p[1]; + p->nData = 0; + } + else if( p->nData+FTS3_VARINT_MAX+1>p->nSpace ){ + i64 nNew = p->nSpace * 2; + p = sqlite3_realloc64(p, sizeof(*p) + nNew); + if( !p ){ + sqlite3_free(*pp); + *pp = 0; + return SQLITE_NOMEM; + } + p->nSpace = (int)nNew; + p->aData = (char *)&p[1]; + } + + /* Append the new serialized varint to the end of the list. */ + p->nData += sqlite3Fts3PutVarint(&p->aData[p->nData], i); + p->aData[p->nData] = '\0'; + *pp = p; + return SQLITE_OK; +} + +/* +** Add a docid/column/position entry to a PendingList structure. Non-zero +** is returned if the structure is sqlite3_realloced as part of adding +** the entry. Otherwise, zero. +** +** If an OOM error occurs, *pRc is set to SQLITE_NOMEM before returning. +** Zero is always returned in this case. Otherwise, if no OOM error occurs, +** it is set to SQLITE_OK. +*/ +static int fts3PendingListAppend( + PendingList **pp, /* IN/OUT: PendingList structure */ + sqlite3_int64 iDocid, /* Docid for entry to add */ + sqlite3_int64 iCol, /* Column for entry to add */ + sqlite3_int64 iPos, /* Position of term for entry to add */ + int *pRc /* OUT: Return code */ +){ + PendingList *p = *pp; + int rc = SQLITE_OK; + + assert( !p || p->iLastDocid<=iDocid ); + + if( !p || p->iLastDocid!=iDocid ){ + u64 iDelta = (u64)iDocid - (u64)(p ? p->iLastDocid : 0); + if( p ){ + assert( p->nDatanSpace ); + assert( p->aData[p->nData]==0 ); + p->nData++; + } + if( SQLITE_OK!=(rc = fts3PendingListAppendVarint(&p, iDelta)) ){ + goto pendinglistappend_out; + } + p->iLastCol = -1; + p->iLastPos = 0; + p->iLastDocid = iDocid; + } + if( iCol>0 && p->iLastCol!=iCol ){ + if( SQLITE_OK!=(rc = fts3PendingListAppendVarint(&p, 1)) + || SQLITE_OK!=(rc = fts3PendingListAppendVarint(&p, iCol)) + ){ + goto pendinglistappend_out; + } + p->iLastCol = iCol; + p->iLastPos = 0; + } + if( iCol>=0 ){ + assert( iPos>p->iLastPos || (iPos==0 && p->iLastPos==0) ); + rc = fts3PendingListAppendVarint(&p, 2+iPos-p->iLastPos); + if( rc==SQLITE_OK ){ + p->iLastPos = iPos; + } + } + + pendinglistappend_out: + *pRc = rc; + if( p!=*pp ){ + *pp = p; + return 1; + } + return 0; +} + +/* +** Free a PendingList object allocated by fts3PendingListAppend(). +*/ +static void fts3PendingListDelete(PendingList *pList){ + sqlite3_free(pList); +} + +/* +** Add an entry to one of the pending-terms hash tables. +*/ +static int fts3PendingTermsAddOne( + Fts3Table *p, + int iCol, + int iPos, + Fts3Hash *pHash, /* Pending terms hash table to add entry to */ + const char *zToken, + int nToken +){ + PendingList *pList; + int rc = SQLITE_OK; + + pList = (PendingList *)fts3HashFind(pHash, zToken, nToken); + if( pList ){ + assert( (i64)pList->nData+(i64)nToken+(i64)sizeof(Fts3HashElem) + <= (i64)p->nPendingData ); + p->nPendingData -= (int)(pList->nData + nToken + sizeof(Fts3HashElem)); + } + if( fts3PendingListAppend(&pList, p->iPrevDocid, iCol, iPos, &rc) ){ + if( pList==fts3HashInsert(pHash, zToken, nToken, pList) ){ + /* Malloc failed while inserting the new entry. This can only + ** happen if there was no previous entry for this token. + */ + assert( 0==fts3HashFind(pHash, zToken, nToken) ); + sqlite3_free(pList); + rc = SQLITE_NOMEM; + } + } + if( rc==SQLITE_OK ){ + assert( (i64)p->nPendingData + pList->nData + nToken + + sizeof(Fts3HashElem) <= 0x3fffffff ); + p->nPendingData += (int)(pList->nData + nToken + sizeof(Fts3HashElem)); + } + return rc; +} + +/* +** Tokenize the nul-terminated string zText and add all tokens to the +** pending-terms hash-table. The docid used is that currently stored in +** p->iPrevDocid, and the column is specified by argument iCol. +** +** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code. +*/ +static int fts3PendingTermsAdd( + Fts3Table *p, /* Table into which text will be inserted */ + int iLangid, /* Language id to use */ + const char *zText, /* Text of document to be inserted */ + int iCol, /* Column into which text is being inserted */ + u32 *pnWord /* IN/OUT: Incr. by number tokens inserted */ +){ + int rc; + int iStart = 0; + int iEnd = 0; + int iPos = 0; + int nWord = 0; + + char const *zToken; + int nToken = 0; + + sqlite3_tokenizer *pTokenizer = p->pTokenizer; + sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; + sqlite3_tokenizer_cursor *pCsr; + int (*xNext)(sqlite3_tokenizer_cursor *pCursor, + const char**,int*,int*,int*,int*); + + assert( pTokenizer && pModule ); + + /* If the user has inserted a NULL value, this function may be called with + ** zText==0. In this case, add zero token entries to the hash table and + ** return early. */ + if( zText==0 ){ + *pnWord = 0; + return SQLITE_OK; + } + + rc = sqlite3Fts3OpenTokenizer(pTokenizer, iLangid, zText, -1, &pCsr); + if( rc!=SQLITE_OK ){ + return rc; + } + + xNext = pModule->xNext; + while( SQLITE_OK==rc + && SQLITE_OK==(rc = xNext(pCsr, &zToken, &nToken, &iStart, &iEnd, &iPos)) + ){ + int i; + if( iPos>=nWord ) nWord = iPos+1; + + /* Positions cannot be negative; we use -1 as a terminator internally. + ** Tokens must have a non-zero length. + */ + if( iPos<0 || !zToken || nToken<=0 ){ + rc = SQLITE_ERROR; + break; + } + + /* Add the term to the terms index */ + rc = fts3PendingTermsAddOne( + p, iCol, iPos, &p->aIndex[0].hPending, zToken, nToken + ); + + /* Add the term to each of the prefix indexes that it is not too + ** short for. */ + for(i=1; rc==SQLITE_OK && inIndex; i++){ + struct Fts3Index *pIndex = &p->aIndex[i]; + if( nTokennPrefix ) continue; + rc = fts3PendingTermsAddOne( + p, iCol, iPos, &pIndex->hPending, zToken, pIndex->nPrefix + ); + } + } + + pModule->xClose(pCsr); + *pnWord += nWord; + return (rc==SQLITE_DONE ? SQLITE_OK : rc); +} + +/* +** Calling this function indicates that subsequent calls to +** fts3PendingTermsAdd() are to add term/position-list pairs for the +** contents of the document with docid iDocid. +*/ +static int fts3PendingTermsDocid( + Fts3Table *p, /* Full-text table handle */ + int bDelete, /* True if this op is a delete */ + int iLangid, /* Language id of row being written */ + sqlite_int64 iDocid /* Docid of row being written */ +){ + assert( iLangid>=0 ); + assert( bDelete==1 || bDelete==0 ); + + /* TODO(shess) Explore whether partially flushing the buffer on + ** forced-flush would provide better performance. I suspect that if + ** we ordered the doclists by size and flushed the largest until the + ** buffer was half empty, that would let the less frequent terms + ** generate longer doclists. + */ + if( iDocidiPrevDocid + || (iDocid==p->iPrevDocid && p->bPrevDelete==0) + || p->iPrevLangid!=iLangid + || p->nPendingData>p->nMaxPendingData + ){ + int rc = sqlite3Fts3PendingTermsFlush(p); + if( rc!=SQLITE_OK ) return rc; + } + p->iPrevDocid = iDocid; + p->iPrevLangid = iLangid; + p->bPrevDelete = bDelete; + return SQLITE_OK; +} + +/* +** Discard the contents of the pending-terms hash tables. +*/ +SQLITE_PRIVATE void sqlite3Fts3PendingTermsClear(Fts3Table *p){ + int i; + for(i=0; inIndex; i++){ + Fts3HashElem *pElem; + Fts3Hash *pHash = &p->aIndex[i].hPending; + for(pElem=fts3HashFirst(pHash); pElem; pElem=fts3HashNext(pElem)){ + PendingList *pList = (PendingList *)fts3HashData(pElem); + fts3PendingListDelete(pList); + } + fts3HashClear(pHash); + } + p->nPendingData = 0; +} + +/* +** This function is called by the xUpdate() method as part of an INSERT +** operation. It adds entries for each term in the new record to the +** pendingTerms hash table. +** +** Argument apVal is the same as the similarly named argument passed to +** fts3InsertData(). Parameter iDocid is the docid of the new row. +*/ +static int fts3InsertTerms( + Fts3Table *p, + int iLangid, + sqlite3_value **apVal, + u32 *aSz +){ + int i; /* Iterator variable */ + for(i=2; inColumn+2; i++){ + int iCol = i-2; + if( p->abNotindexed[iCol]==0 ){ + const char *zText = (const char *)sqlite3_value_text(apVal[i]); + int rc = fts3PendingTermsAdd(p, iLangid, zText, iCol, &aSz[iCol]); + if( rc!=SQLITE_OK ){ + return rc; + } + aSz[p->nColumn] += sqlite3_value_bytes(apVal[i]); + } + } + return SQLITE_OK; +} + +/* +** This function is called by the xUpdate() method for an INSERT operation. +** The apVal parameter is passed a copy of the apVal argument passed by +** SQLite to the xUpdate() method. i.e: +** +** apVal[0] Not used for INSERT. +** apVal[1] rowid +** apVal[2] Left-most user-defined column +** ... +** apVal[p->nColumn+1] Right-most user-defined column +** apVal[p->nColumn+2] Hidden column with same name as table +** apVal[p->nColumn+3] Hidden "docid" column (alias for rowid) +** apVal[p->nColumn+4] Hidden languageid column +*/ +static int fts3InsertData( + Fts3Table *p, /* Full-text table */ + sqlite3_value **apVal, /* Array of values to insert */ + sqlite3_int64 *piDocid /* OUT: Docid for row just inserted */ +){ + int rc; /* Return code */ + sqlite3_stmt *pContentInsert; /* INSERT INTO %_content VALUES(...) */ + + if( p->zContentTbl ){ + sqlite3_value *pRowid = apVal[p->nColumn+3]; + if( sqlite3_value_type(pRowid)==SQLITE_NULL ){ + pRowid = apVal[1]; + } + if( sqlite3_value_type(pRowid)!=SQLITE_INTEGER ){ + return SQLITE_CONSTRAINT; + } + *piDocid = sqlite3_value_int64(pRowid); + return SQLITE_OK; + } + + /* Locate the statement handle used to insert data into the %_content + ** table. The SQL for this statement is: + ** + ** INSERT INTO %_content VALUES(?, ?, ?, ...) + ** + ** The statement features N '?' variables, where N is the number of user + ** defined columns in the FTS3 table, plus one for the docid field. + */ + rc = fts3SqlStmt(p, SQL_CONTENT_INSERT, &pContentInsert, &apVal[1]); + if( rc==SQLITE_OK && p->zLanguageid ){ + rc = sqlite3_bind_int( + pContentInsert, p->nColumn+2, + sqlite3_value_int(apVal[p->nColumn+4]) + ); + } + if( rc!=SQLITE_OK ) return rc; + + /* There is a quirk here. The users INSERT statement may have specified + ** a value for the "rowid" field, for the "docid" field, or for both. + ** Which is a problem, since "rowid" and "docid" are aliases for the + ** same value. For example: + ** + ** INSERT INTO fts3tbl(rowid, docid) VALUES(1, 2); + ** + ** In FTS3, this is an error. It is an error to specify non-NULL values + ** for both docid and some other rowid alias. + */ + if( SQLITE_NULL!=sqlite3_value_type(apVal[3+p->nColumn]) ){ + if( SQLITE_NULL==sqlite3_value_type(apVal[0]) + && SQLITE_NULL!=sqlite3_value_type(apVal[1]) + ){ + /* A rowid/docid conflict. */ + return SQLITE_ERROR; + } + rc = sqlite3_bind_value(pContentInsert, 1, apVal[3+p->nColumn]); + if( rc!=SQLITE_OK ) return rc; + } + + /* Execute the statement to insert the record. Set *piDocid to the + ** new docid value. + */ + sqlite3_step(pContentInsert); + rc = sqlite3_reset(pContentInsert); + + *piDocid = sqlite3_last_insert_rowid(p->db); + return rc; +} + + + +/* +** Remove all data from the FTS3 table. Clear the hash table containing +** pending terms. +*/ +static int fts3DeleteAll(Fts3Table *p, int bContent){ + int rc = SQLITE_OK; /* Return code */ + + /* Discard the contents of the pending-terms hash table. */ + sqlite3Fts3PendingTermsClear(p); + + /* Delete everything from the shadow tables. Except, leave %_content as + ** is if bContent is false. */ + assert( p->zContentTbl==0 || bContent==0 ); + if( bContent ) fts3SqlExec(&rc, p, SQL_DELETE_ALL_CONTENT, 0); + fts3SqlExec(&rc, p, SQL_DELETE_ALL_SEGMENTS, 0); + fts3SqlExec(&rc, p, SQL_DELETE_ALL_SEGDIR, 0); + if( p->bHasDocsize ){ + fts3SqlExec(&rc, p, SQL_DELETE_ALL_DOCSIZE, 0); + } + if( p->bHasStat ){ + fts3SqlExec(&rc, p, SQL_DELETE_ALL_STAT, 0); + } + return rc; +} + +/* +** +*/ +static int langidFromSelect(Fts3Table *p, sqlite3_stmt *pSelect){ + int iLangid = 0; + if( p->zLanguageid ) iLangid = sqlite3_column_int(pSelect, p->nColumn+1); + return iLangid; +} + +/* +** The first element in the apVal[] array is assumed to contain the docid +** (an integer) of a row about to be deleted. Remove all terms from the +** full-text index. +*/ +static void fts3DeleteTerms( + int *pRC, /* Result code */ + Fts3Table *p, /* The FTS table to delete from */ + sqlite3_value *pRowid, /* The docid to be deleted */ + u32 *aSz, /* Sizes of deleted document written here */ + int *pbFound /* OUT: Set to true if row really does exist */ +){ + int rc; + sqlite3_stmt *pSelect; + + assert( *pbFound==0 ); + if( *pRC ) return; + rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pSelect, &pRowid); + if( rc==SQLITE_OK ){ + if( SQLITE_ROW==sqlite3_step(pSelect) ){ + int i; + int iLangid = langidFromSelect(p, pSelect); + i64 iDocid = sqlite3_column_int64(pSelect, 0); + rc = fts3PendingTermsDocid(p, 1, iLangid, iDocid); + for(i=1; rc==SQLITE_OK && i<=p->nColumn; i++){ + int iCol = i-1; + if( p->abNotindexed[iCol]==0 ){ + const char *zText = (const char *)sqlite3_column_text(pSelect, i); + rc = fts3PendingTermsAdd(p, iLangid, zText, -1, &aSz[iCol]); + aSz[p->nColumn] += sqlite3_column_bytes(pSelect, i); + } + } + if( rc!=SQLITE_OK ){ + sqlite3_reset(pSelect); + *pRC = rc; + return; + } + *pbFound = 1; + } + rc = sqlite3_reset(pSelect); + }else{ + sqlite3_reset(pSelect); + } + *pRC = rc; +} + +/* +** Forward declaration to account for the circular dependency between +** functions fts3SegmentMerge() and fts3AllocateSegdirIdx(). +*/ +static int fts3SegmentMerge(Fts3Table *, int, int, int); + +/* +** This function allocates a new level iLevel index in the segdir table. +** Usually, indexes are allocated within a level sequentially starting +** with 0, so the allocated index is one greater than the value returned +** by: +** +** SELECT max(idx) FROM %_segdir WHERE level = :iLevel +** +** However, if there are already FTS3_MERGE_COUNT indexes at the requested +** level, they are merged into a single level (iLevel+1) segment and the +** allocated index is 0. +** +** If successful, *piIdx is set to the allocated index slot and SQLITE_OK +** returned. Otherwise, an SQLite error code is returned. +*/ +static int fts3AllocateSegdirIdx( + Fts3Table *p, + int iLangid, /* Language id */ + int iIndex, /* Index for p->aIndex */ + int iLevel, + int *piIdx +){ + int rc; /* Return Code */ + sqlite3_stmt *pNextIdx; /* Query for next idx at level iLevel */ + int iNext = 0; /* Result of query pNextIdx */ + + assert( iLangid>=0 ); + assert( p->nIndex>=1 ); + + /* Set variable iNext to the next available segdir index at level iLevel. */ + rc = fts3SqlStmt(p, SQL_NEXT_SEGMENT_INDEX, &pNextIdx, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64( + pNextIdx, 1, getAbsoluteLevel(p, iLangid, iIndex, iLevel) + ); + if( SQLITE_ROW==sqlite3_step(pNextIdx) ){ + iNext = sqlite3_column_int(pNextIdx, 0); + } + rc = sqlite3_reset(pNextIdx); + } + + if( rc==SQLITE_OK ){ + /* If iNext is FTS3_MERGE_COUNT, indicating that level iLevel is already + ** full, merge all segments in level iLevel into a single iLevel+1 + ** segment and allocate (newly freed) index 0 at level iLevel. Otherwise, + ** if iNext is less than FTS3_MERGE_COUNT, allocate index iNext. + */ + if( iNext>=MergeCount(p) ){ + fts3LogMerge(16, getAbsoluteLevel(p, iLangid, iIndex, iLevel)); + rc = fts3SegmentMerge(p, iLangid, iIndex, iLevel); + *piIdx = 0; + }else{ + *piIdx = iNext; + } + } + + return rc; +} + +/* +** The %_segments table is declared as follows: +** +** CREATE TABLE %_segments(blockid INTEGER PRIMARY KEY, block BLOB) +** +** This function reads data from a single row of the %_segments table. The +** specific row is identified by the iBlockid parameter. If paBlob is not +** NULL, then a buffer is allocated using sqlite3_malloc() and populated +** with the contents of the blob stored in the "block" column of the +** identified table row is. Whether or not paBlob is NULL, *pnBlob is set +** to the size of the blob in bytes before returning. +** +** If an error occurs, or the table does not contain the specified row, +** an SQLite error code is returned. Otherwise, SQLITE_OK is returned. If +** paBlob is non-NULL, then it is the responsibility of the caller to +** eventually free the returned buffer. +** +** This function may leave an open sqlite3_blob* handle in the +** Fts3Table.pSegments variable. This handle is reused by subsequent calls +** to this function. The handle may be closed by calling the +** sqlite3Fts3SegmentsClose() function. Reusing a blob handle is a handy +** performance improvement, but the blob handle should always be closed +** before control is returned to the user (to prevent a lock being held +** on the database file for longer than necessary). Thus, any virtual table +** method (xFilter etc.) that may directly or indirectly call this function +** must call sqlite3Fts3SegmentsClose() before returning. +*/ +SQLITE_PRIVATE int sqlite3Fts3ReadBlock( + Fts3Table *p, /* FTS3 table handle */ + sqlite3_int64 iBlockid, /* Access the row with blockid=$iBlockid */ + char **paBlob, /* OUT: Blob data in malloc'd buffer */ + int *pnBlob, /* OUT: Size of blob data */ + int *pnLoad /* OUT: Bytes actually loaded */ +){ + int rc; /* Return code */ + + /* pnBlob must be non-NULL. paBlob may be NULL or non-NULL. */ + assert( pnBlob ); + + if( p->pSegments ){ + rc = sqlite3_blob_reopen(p->pSegments, iBlockid); + }else{ + if( 0==p->zSegmentsTbl ){ + p->zSegmentsTbl = sqlite3_mprintf("%s_segments", p->zName); + if( 0==p->zSegmentsTbl ) return SQLITE_NOMEM; + } + rc = sqlite3_blob_open( + p->db, p->zDb, p->zSegmentsTbl, "block", iBlockid, 0, &p->pSegments + ); + } + + if( rc==SQLITE_OK ){ + int nByte = sqlite3_blob_bytes(p->pSegments); + *pnBlob = nByte; + if( paBlob ){ + char *aByte = sqlite3_malloc64((i64)nByte + FTS3_NODE_PADDING); + if( !aByte ){ + rc = SQLITE_NOMEM; + }else{ + if( pnLoad && nByte>(FTS3_NODE_CHUNK_THRESHOLD) ){ + nByte = FTS3_NODE_CHUNKSIZE; + *pnLoad = nByte; + } + rc = sqlite3_blob_read(p->pSegments, aByte, nByte, 0); + memset(&aByte[nByte], 0, FTS3_NODE_PADDING); + if( rc!=SQLITE_OK ){ + sqlite3_free(aByte); + aByte = 0; + } + } + *paBlob = aByte; + } + }else if( rc==SQLITE_ERROR ){ + rc = FTS_CORRUPT_VTAB; + } + + return rc; +} + +/* +** Close the blob handle at p->pSegments, if it is open. See comments above +** the sqlite3Fts3ReadBlock() function for details. +*/ +SQLITE_PRIVATE void sqlite3Fts3SegmentsClose(Fts3Table *p){ + sqlite3_blob_close(p->pSegments); + p->pSegments = 0; +} + +static int fts3SegReaderIncrRead(Fts3SegReader *pReader){ + int nRead; /* Number of bytes to read */ + int rc; /* Return code */ + + nRead = MIN(pReader->nNode - pReader->nPopulate, FTS3_NODE_CHUNKSIZE); + rc = sqlite3_blob_read( + pReader->pBlob, + &pReader->aNode[pReader->nPopulate], + nRead, + pReader->nPopulate + ); + + if( rc==SQLITE_OK ){ + pReader->nPopulate += nRead; + memset(&pReader->aNode[pReader->nPopulate], 0, FTS3_NODE_PADDING); + if( pReader->nPopulate==pReader->nNode ){ + sqlite3_blob_close(pReader->pBlob); + pReader->pBlob = 0; + pReader->nPopulate = 0; + } + } + return rc; +} + +static int fts3SegReaderRequire(Fts3SegReader *pReader, char *pFrom, int nByte){ + int rc = SQLITE_OK; + assert( !pReader->pBlob + || (pFrom>=pReader->aNode && pFrom<&pReader->aNode[pReader->nNode]) + ); + while( pReader->pBlob && rc==SQLITE_OK + && (pFrom - pReader->aNode + nByte)>pReader->nPopulate + ){ + rc = fts3SegReaderIncrRead(pReader); + } + return rc; +} + +/* +** Set an Fts3SegReader cursor to point at EOF. +*/ +static void fts3SegReaderSetEof(Fts3SegReader *pSeg){ + if( !fts3SegReaderIsRootOnly(pSeg) ){ + sqlite3_free(pSeg->aNode); + sqlite3_blob_close(pSeg->pBlob); + pSeg->pBlob = 0; + } + pSeg->aNode = 0; +} + +/* +** Move the iterator passed as the first argument to the next term in the +** segment. If successful, SQLITE_OK is returned. If there is no next term, +** SQLITE_DONE. Otherwise, an SQLite error code. +*/ +static int fts3SegReaderNext( + Fts3Table *p, + Fts3SegReader *pReader, + int bIncr +){ + int rc; /* Return code of various sub-routines */ + char *pNext; /* Cursor variable */ + int nPrefix; /* Number of bytes in term prefix */ + int nSuffix; /* Number of bytes in term suffix */ + + if( !pReader->aDoclist ){ + pNext = pReader->aNode; + }else{ + pNext = &pReader->aDoclist[pReader->nDoclist]; + } + + if( !pNext || pNext>=&pReader->aNode[pReader->nNode] ){ + + if( fts3SegReaderIsPending(pReader) ){ + Fts3HashElem *pElem = *(pReader->ppNextElem); + sqlite3_free(pReader->aNode); + pReader->aNode = 0; + if( pElem ){ + char *aCopy; + PendingList *pList = (PendingList *)fts3HashData(pElem); + int nCopy = pList->nData+1; + + int nTerm = fts3HashKeysize(pElem); + if( (nTerm+1)>pReader->nTermAlloc ){ + sqlite3_free(pReader->zTerm); + pReader->zTerm = (char*)sqlite3_malloc64(((i64)nTerm+1)*2); + if( !pReader->zTerm ) return SQLITE_NOMEM; + pReader->nTermAlloc = (nTerm+1)*2; + } + memcpy(pReader->zTerm, fts3HashKey(pElem), nTerm); + pReader->zTerm[nTerm] = '\0'; + pReader->nTerm = nTerm; + + aCopy = (char*)sqlite3_malloc64(nCopy); + if( !aCopy ) return SQLITE_NOMEM; + memcpy(aCopy, pList->aData, nCopy); + pReader->nNode = pReader->nDoclist = nCopy; + pReader->aNode = pReader->aDoclist = aCopy; + pReader->ppNextElem++; + assert( pReader->aNode ); + } + return SQLITE_OK; + } + + fts3SegReaderSetEof(pReader); + + /* If iCurrentBlock>=iLeafEndBlock, this is an EOF condition. All leaf + ** blocks have already been traversed. */ +#ifdef CORRUPT_DB + assert( pReader->iCurrentBlock<=pReader->iLeafEndBlock || CORRUPT_DB ); +#endif + if( pReader->iCurrentBlock>=pReader->iLeafEndBlock ){ + return SQLITE_OK; + } + + rc = sqlite3Fts3ReadBlock( + p, ++pReader->iCurrentBlock, &pReader->aNode, &pReader->nNode, + (bIncr ? &pReader->nPopulate : 0) + ); + if( rc!=SQLITE_OK ) return rc; + assert( pReader->pBlob==0 ); + if( bIncr && pReader->nPopulatenNode ){ + pReader->pBlob = p->pSegments; + p->pSegments = 0; + } + pNext = pReader->aNode; + } + + assert( !fts3SegReaderIsPending(pReader) ); + + rc = fts3SegReaderRequire(pReader, pNext, FTS3_VARINT_MAX*2); + if( rc!=SQLITE_OK ) return rc; + + /* Because of the FTS3_NODE_PADDING bytes of padding, the following is + ** safe (no risk of overread) even if the node data is corrupted. */ + pNext += fts3GetVarint32(pNext, &nPrefix); + pNext += fts3GetVarint32(pNext, &nSuffix); + if( nSuffix<=0 + || (&pReader->aNode[pReader->nNode] - pNext)pReader->nTerm + ){ + return FTS_CORRUPT_VTAB; + } + + /* Both nPrefix and nSuffix were read by fts3GetVarint32() and so are + ** between 0 and 0x7FFFFFFF. But the sum of the two may cause integer + ** overflow - hence the (i64) casts. */ + if( (i64)nPrefix+nSuffix>(i64)pReader->nTermAlloc ){ + i64 nNew = ((i64)nPrefix+nSuffix)*2; + char *zNew = sqlite3_realloc64(pReader->zTerm, nNew); + if( !zNew ){ + return SQLITE_NOMEM; + } + pReader->zTerm = zNew; + pReader->nTermAlloc = nNew; + } + + rc = fts3SegReaderRequire(pReader, pNext, nSuffix+FTS3_VARINT_MAX); + if( rc!=SQLITE_OK ) return rc; + + memcpy(&pReader->zTerm[nPrefix], pNext, nSuffix); + pReader->nTerm = nPrefix+nSuffix; + pNext += nSuffix; + pNext += fts3GetVarint32(pNext, &pReader->nDoclist); + pReader->aDoclist = pNext; + pReader->pOffsetList = 0; + + /* Check that the doclist does not appear to extend past the end of the + ** b-tree node. And that the final byte of the doclist is 0x00. If either + ** of these statements is untrue, then the data structure is corrupt. + */ + if( pReader->nDoclist > pReader->nNode-(pReader->aDoclist-pReader->aNode) + || (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1]) + || pReader->nDoclist==0 + ){ + return FTS_CORRUPT_VTAB; + } + return SQLITE_OK; +} + +/* +** Set the SegReader to point to the first docid in the doclist associated +** with the current term. +*/ +static int fts3SegReaderFirstDocid(Fts3Table *pTab, Fts3SegReader *pReader){ + int rc = SQLITE_OK; + assert( pReader->aDoclist ); + assert( !pReader->pOffsetList ); + if( pTab->bDescIdx && fts3SegReaderIsPending(pReader) ){ + u8 bEof = 0; + pReader->iDocid = 0; + pReader->nOffsetList = 0; + sqlite3Fts3DoclistPrev(0, + pReader->aDoclist, pReader->nDoclist, &pReader->pOffsetList, + &pReader->iDocid, &pReader->nOffsetList, &bEof + ); + }else{ + rc = fts3SegReaderRequire(pReader, pReader->aDoclist, FTS3_VARINT_MAX); + if( rc==SQLITE_OK ){ + int n = sqlite3Fts3GetVarint(pReader->aDoclist, &pReader->iDocid); + pReader->pOffsetList = &pReader->aDoclist[n]; + } + } + return rc; +} + +/* +** Advance the SegReader to point to the next docid in the doclist +** associated with the current term. +** +** If arguments ppOffsetList and pnOffsetList are not NULL, then +** *ppOffsetList is set to point to the first column-offset list +** in the doclist entry (i.e. immediately past the docid varint). +** *pnOffsetList is set to the length of the set of column-offset +** lists, not including the nul-terminator byte. For example: +*/ +static int fts3SegReaderNextDocid( + Fts3Table *pTab, + Fts3SegReader *pReader, /* Reader to advance to next docid */ + char **ppOffsetList, /* OUT: Pointer to current position-list */ + int *pnOffsetList /* OUT: Length of *ppOffsetList in bytes */ +){ + int rc = SQLITE_OK; + char *p = pReader->pOffsetList; + char c = 0; + + assert( p ); + + if( pTab->bDescIdx && fts3SegReaderIsPending(pReader) ){ + /* A pending-terms seg-reader for an FTS4 table that uses order=desc. + ** Pending-terms doclists are always built up in ascending order, so + ** we have to iterate through them backwards here. */ + u8 bEof = 0; + if( ppOffsetList ){ + *ppOffsetList = pReader->pOffsetList; + *pnOffsetList = pReader->nOffsetList - 1; + } + sqlite3Fts3DoclistPrev(0, + pReader->aDoclist, pReader->nDoclist, &p, &pReader->iDocid, + &pReader->nOffsetList, &bEof + ); + if( bEof ){ + pReader->pOffsetList = 0; + }else{ + pReader->pOffsetList = p; + } + }else{ + char *pEnd = &pReader->aDoclist[pReader->nDoclist]; + + /* Pointer p currently points at the first byte of an offset list. The + ** following block advances it to point one byte past the end of + ** the same offset list. */ + while( 1 ){ + + /* The following line of code (and the "p++" below the while() loop) is + ** normally all that is required to move pointer p to the desired + ** position. The exception is if this node is being loaded from disk + ** incrementally and pointer "p" now points to the first byte past + ** the populated part of pReader->aNode[]. + */ + while( *p | c ) c = *p++ & 0x80; + assert( *p==0 ); + + if( pReader->pBlob==0 || p<&pReader->aNode[pReader->nPopulate] ) break; + rc = fts3SegReaderIncrRead(pReader); + if( rc!=SQLITE_OK ) return rc; + } + p++; + + /* If required, populate the output variables with a pointer to and the + ** size of the previous offset-list. + */ + if( ppOffsetList ){ + *ppOffsetList = pReader->pOffsetList; + *pnOffsetList = (int)(p - pReader->pOffsetList - 1); + } + + /* List may have been edited in place by fts3EvalNearTrim() */ + while( p=pEnd ){ + pReader->pOffsetList = 0; + }else{ + rc = fts3SegReaderRequire(pReader, p, FTS3_VARINT_MAX); + if( rc==SQLITE_OK ){ + u64 iDelta; + pReader->pOffsetList = p + sqlite3Fts3GetVarintU(p, &iDelta); + if( pTab->bDescIdx ){ + pReader->iDocid = (i64)((u64)pReader->iDocid - iDelta); + }else{ + pReader->iDocid = (i64)((u64)pReader->iDocid + iDelta); + } + } + } + } + + return rc; +} + + +SQLITE_PRIVATE int sqlite3Fts3MsrOvfl( + Fts3Cursor *pCsr, + Fts3MultiSegReader *pMsr, + int *pnOvfl +){ + Fts3Table *p = (Fts3Table*)pCsr->base.pVtab; + int nOvfl = 0; + int ii; + int rc = SQLITE_OK; + int pgsz = p->nPgsz; + + assert( p->bFts4 ); + assert( pgsz>0 ); + + for(ii=0; rc==SQLITE_OK && iinSegment; ii++){ + Fts3SegReader *pReader = pMsr->apSegment[ii]; + if( !fts3SegReaderIsPending(pReader) + && !fts3SegReaderIsRootOnly(pReader) + ){ + sqlite3_int64 jj; + for(jj=pReader->iStartBlock; jj<=pReader->iLeafEndBlock; jj++){ + int nBlob; + rc = sqlite3Fts3ReadBlock(p, jj, 0, &nBlob, 0); + if( rc!=SQLITE_OK ) break; + if( (nBlob+35)>pgsz ){ + nOvfl += (nBlob + 34)/pgsz; + } + } + } + } + *pnOvfl = nOvfl; + return rc; +} + +/* +** Free all allocations associated with the iterator passed as the +** second argument. +*/ +SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3SegReader *pReader){ + if( pReader ){ + sqlite3_free(pReader->zTerm); + if( !fts3SegReaderIsRootOnly(pReader) ){ + sqlite3_free(pReader->aNode); + } + sqlite3_blob_close(pReader->pBlob); + } + sqlite3_free(pReader); +} + +/* +** Allocate a new SegReader object. +*/ +SQLITE_PRIVATE int sqlite3Fts3SegReaderNew( + int iAge, /* Segment "age". */ + int bLookup, /* True for a lookup only */ + sqlite3_int64 iStartLeaf, /* First leaf to traverse */ + sqlite3_int64 iEndLeaf, /* Final leaf to traverse */ + sqlite3_int64 iEndBlock, /* Final block of segment */ + const char *zRoot, /* Buffer containing root node */ + int nRoot, /* Size of buffer containing root node */ + Fts3SegReader **ppReader /* OUT: Allocated Fts3SegReader */ +){ + Fts3SegReader *pReader; /* Newly allocated SegReader object */ + int nExtra = 0; /* Bytes to allocate segment root node */ + + assert( zRoot!=0 || nRoot==0 ); +#ifdef CORRUPT_DB + assert( zRoot!=0 || CORRUPT_DB ); +#endif + + if( iStartLeaf==0 ){ + if( iEndLeaf!=0 ) return FTS_CORRUPT_VTAB; + nExtra = nRoot + FTS3_NODE_PADDING; + } + + pReader = (Fts3SegReader *)sqlite3_malloc64(sizeof(Fts3SegReader) + nExtra); + if( !pReader ){ + return SQLITE_NOMEM; + } + memset(pReader, 0, sizeof(Fts3SegReader)); + pReader->iIdx = iAge; + pReader->bLookup = bLookup!=0; + pReader->iStartBlock = iStartLeaf; + pReader->iLeafEndBlock = iEndLeaf; + pReader->iEndBlock = iEndBlock; + + if( nExtra ){ + /* The entire segment is stored in the root node. */ + pReader->aNode = (char *)&pReader[1]; + pReader->rootOnly = 1; + pReader->nNode = nRoot; + if( nRoot ) memcpy(pReader->aNode, zRoot, nRoot); + memset(&pReader->aNode[nRoot], 0, FTS3_NODE_PADDING); + }else{ + pReader->iCurrentBlock = iStartLeaf-1; + } + *ppReader = pReader; + return SQLITE_OK; +} + +/* +** This is a comparison function used as a qsort() callback when sorting +** an array of pending terms by term. This occurs as part of flushing +** the contents of the pending-terms hash table to the database. +*/ +static int SQLITE_CDECL fts3CompareElemByTerm( + const void *lhs, + const void *rhs +){ + char *z1 = fts3HashKey(*(Fts3HashElem **)lhs); + char *z2 = fts3HashKey(*(Fts3HashElem **)rhs); + int n1 = fts3HashKeysize(*(Fts3HashElem **)lhs); + int n2 = fts3HashKeysize(*(Fts3HashElem **)rhs); + + int n = (n1aIndex */ + const char *zTerm, /* Term to search for */ + int nTerm, /* Size of buffer zTerm */ + int bPrefix, /* True for a prefix iterator */ + Fts3SegReader **ppReader /* OUT: SegReader for pending-terms */ +){ + Fts3SegReader *pReader = 0; /* Fts3SegReader object to return */ + Fts3HashElem *pE; /* Iterator variable */ + Fts3HashElem **aElem = 0; /* Array of term hash entries to scan */ + int nElem = 0; /* Size of array at aElem */ + int rc = SQLITE_OK; /* Return Code */ + Fts3Hash *pHash; + + pHash = &p->aIndex[iIndex].hPending; + if( bPrefix ){ + int nAlloc = 0; /* Size of allocated array at aElem */ + + for(pE=fts3HashFirst(pHash); pE; pE=fts3HashNext(pE)){ + char *zKey = (char *)fts3HashKey(pE); + int nKey = fts3HashKeysize(pE); + if( nTerm==0 || (nKey>=nTerm && 0==memcmp(zKey, zTerm, nTerm)) ){ + if( nElem==nAlloc ){ + Fts3HashElem **aElem2; + nAlloc += 16; + aElem2 = (Fts3HashElem **)sqlite3_realloc64( + aElem, nAlloc*sizeof(Fts3HashElem *) + ); + if( !aElem2 ){ + rc = SQLITE_NOMEM; + nElem = 0; + break; + } + aElem = aElem2; + } + + aElem[nElem++] = pE; + } + } + + /* If more than one term matches the prefix, sort the Fts3HashElem + ** objects in term order using qsort(). This uses the same comparison + ** callback as is used when flushing terms to disk. + */ + if( nElem>1 ){ + qsort(aElem, nElem, sizeof(Fts3HashElem *), fts3CompareElemByTerm); + } + + }else{ + /* The query is a simple term lookup that matches at most one term in + ** the index. All that is required is a straight hash-lookup. + ** + ** Because the stack address of pE may be accessed via the aElem pointer + ** below, the "Fts3HashElem *pE" must be declared so that it is valid + ** within this entire function, not just this "else{...}" block. + */ + pE = fts3HashFindElem(pHash, zTerm, nTerm); + if( pE ){ + aElem = &pE; + nElem = 1; + } + } + + if( nElem>0 ){ + sqlite3_int64 nByte; + nByte = sizeof(Fts3SegReader) + (nElem+1)*sizeof(Fts3HashElem *); + pReader = (Fts3SegReader *)sqlite3_malloc64(nByte); + if( !pReader ){ + rc = SQLITE_NOMEM; + }else{ + memset(pReader, 0, nByte); + pReader->iIdx = 0x7FFFFFFF; + pReader->ppNextElem = (Fts3HashElem **)&pReader[1]; + memcpy(pReader->ppNextElem, aElem, nElem*sizeof(Fts3HashElem *)); + } + } + + if( bPrefix ){ + sqlite3_free(aElem); + } + *ppReader = pReader; + return rc; +} + +/* +** Compare the entries pointed to by two Fts3SegReader structures. +** Comparison is as follows: +** +** 1) EOF is greater than not EOF. +** +** 2) The current terms (if any) are compared using memcmp(). If one +** term is a prefix of another, the longer term is considered the +** larger. +** +** 3) By segment age. An older segment is considered larger. +*/ +static int fts3SegReaderCmp(Fts3SegReader *pLhs, Fts3SegReader *pRhs){ + int rc; + if( pLhs->aNode && pRhs->aNode ){ + int rc2 = pLhs->nTerm - pRhs->nTerm; + if( rc2<0 ){ + rc = memcmp(pLhs->zTerm, pRhs->zTerm, pLhs->nTerm); + }else{ + rc = memcmp(pLhs->zTerm, pRhs->zTerm, pRhs->nTerm); + } + if( rc==0 ){ + rc = rc2; + } + }else{ + rc = (pLhs->aNode==0) - (pRhs->aNode==0); + } + if( rc==0 ){ + rc = pRhs->iIdx - pLhs->iIdx; + } + assert_fts3_nc( rc!=0 ); + return rc; +} + +/* +** A different comparison function for SegReader structures. In this +** version, it is assumed that each SegReader points to an entry in +** a doclist for identical terms. Comparison is made as follows: +** +** 1) EOF (end of doclist in this case) is greater than not EOF. +** +** 2) By current docid. +** +** 3) By segment age. An older segment is considered larger. +*/ +static int fts3SegReaderDoclistCmp(Fts3SegReader *pLhs, Fts3SegReader *pRhs){ + int rc = (pLhs->pOffsetList==0)-(pRhs->pOffsetList==0); + if( rc==0 ){ + if( pLhs->iDocid==pRhs->iDocid ){ + rc = pRhs->iIdx - pLhs->iIdx; + }else{ + rc = (pLhs->iDocid > pRhs->iDocid) ? 1 : -1; + } + } + assert( pLhs->aNode && pRhs->aNode ); + return rc; +} +static int fts3SegReaderDoclistCmpRev(Fts3SegReader *pLhs, Fts3SegReader *pRhs){ + int rc = (pLhs->pOffsetList==0)-(pRhs->pOffsetList==0); + if( rc==0 ){ + if( pLhs->iDocid==pRhs->iDocid ){ + rc = pRhs->iIdx - pLhs->iIdx; + }else{ + rc = (pLhs->iDocid < pRhs->iDocid) ? 1 : -1; + } + } + assert( pLhs->aNode && pRhs->aNode ); + return rc; +} + +/* +** Compare the term that the Fts3SegReader object passed as the first argument +** points to with the term specified by arguments zTerm and nTerm. +** +** If the pSeg iterator is already at EOF, return 0. Otherwise, return +** -ve if the pSeg term is less than zTerm/nTerm, 0 if the two terms are +** equal, or +ve if the pSeg term is greater than zTerm/nTerm. +*/ +static int fts3SegReaderTermCmp( + Fts3SegReader *pSeg, /* Segment reader object */ + const char *zTerm, /* Term to compare to */ + int nTerm /* Size of term zTerm in bytes */ +){ + int res = 0; + if( pSeg->aNode ){ + if( pSeg->nTerm>nTerm ){ + res = memcmp(pSeg->zTerm, zTerm, nTerm); + }else{ + res = memcmp(pSeg->zTerm, zTerm, pSeg->nTerm); + } + if( res==0 ){ + res = pSeg->nTerm-nTerm; + } + } + return res; +} + +/* +** Argument apSegment is an array of nSegment elements. It is known that +** the final (nSegment-nSuspect) members are already in sorted order +** (according to the comparison function provided). This function shuffles +** the array around until all entries are in sorted order. +*/ +static void fts3SegReaderSort( + Fts3SegReader **apSegment, /* Array to sort entries of */ + int nSegment, /* Size of apSegment array */ + int nSuspect, /* Unsorted entry count */ + int (*xCmp)(Fts3SegReader *, Fts3SegReader *) /* Comparison function */ +){ + int i; /* Iterator variable */ + + assert( nSuspect<=nSegment ); + + if( nSuspect==nSegment ) nSuspect--; + for(i=nSuspect-1; i>=0; i--){ + int j; + for(j=i; j<(nSegment-1); j++){ + Fts3SegReader *pTmp; + if( xCmp(apSegment[j], apSegment[j+1])<0 ) break; + pTmp = apSegment[j+1]; + apSegment[j+1] = apSegment[j]; + apSegment[j] = pTmp; + } + } + +#ifndef NDEBUG + /* Check that the list really is sorted now. */ + for(i=0; i<(nSuspect-1); i++){ + assert( xCmp(apSegment[i], apSegment[i+1])<0 ); + } +#endif +} + +/* +** Insert a record into the %_segments table. +*/ +static int fts3WriteSegment( + Fts3Table *p, /* Virtual table handle */ + sqlite3_int64 iBlock, /* Block id for new block */ + char *z, /* Pointer to buffer containing block data */ + int n /* Size of buffer z in bytes */ +){ + sqlite3_stmt *pStmt; + int rc = fts3SqlStmt(p, SQL_INSERT_SEGMENTS, &pStmt, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pStmt, 1, iBlock); + sqlite3_bind_blob(pStmt, 2, z, n, SQLITE_STATIC); + sqlite3_step(pStmt); + rc = sqlite3_reset(pStmt); + sqlite3_bind_null(pStmt, 2); + } + return rc; +} + +/* +** Find the largest relative level number in the table. If successful, set +** *pnMax to this value and return SQLITE_OK. Otherwise, if an error occurs, +** set *pnMax to zero and return an SQLite error code. +*/ +SQLITE_PRIVATE int sqlite3Fts3MaxLevel(Fts3Table *p, int *pnMax){ + int rc; + int mxLevel = 0; + sqlite3_stmt *pStmt = 0; + + rc = fts3SqlStmt(p, SQL_SELECT_MXLEVEL, &pStmt, 0); + if( rc==SQLITE_OK ){ + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + mxLevel = sqlite3_column_int(pStmt, 0); + } + rc = sqlite3_reset(pStmt); + } + *pnMax = mxLevel; + return rc; +} + +/* +** Insert a record into the %_segdir table. +*/ +static int fts3WriteSegdir( + Fts3Table *p, /* Virtual table handle */ + sqlite3_int64 iLevel, /* Value for "level" field (absolute level) */ + int iIdx, /* Value for "idx" field */ + sqlite3_int64 iStartBlock, /* Value for "start_block" field */ + sqlite3_int64 iLeafEndBlock, /* Value for "leaves_end_block" field */ + sqlite3_int64 iEndBlock, /* Value for "end_block" field */ + sqlite3_int64 nLeafData, /* Bytes of leaf data in segment */ + char *zRoot, /* Blob value for "root" field */ + int nRoot /* Number of bytes in buffer zRoot */ +){ + sqlite3_stmt *pStmt; + int rc = fts3SqlStmt(p, SQL_INSERT_SEGDIR, &pStmt, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pStmt, 1, iLevel); + sqlite3_bind_int(pStmt, 2, iIdx); + sqlite3_bind_int64(pStmt, 3, iStartBlock); + sqlite3_bind_int64(pStmt, 4, iLeafEndBlock); + if( nLeafData==0 ){ + sqlite3_bind_int64(pStmt, 5, iEndBlock); + }else{ + char *zEnd = sqlite3_mprintf("%lld %lld", iEndBlock, nLeafData); + if( !zEnd ) return SQLITE_NOMEM; + sqlite3_bind_text(pStmt, 5, zEnd, -1, sqlite3_free); + } + sqlite3_bind_blob(pStmt, 6, zRoot, nRoot, SQLITE_STATIC); + sqlite3_step(pStmt); + rc = sqlite3_reset(pStmt); + sqlite3_bind_null(pStmt, 6); + } + return rc; +} + +/* +** Return the size of the common prefix (if any) shared by zPrev and +** zNext, in bytes. For example, +** +** fts3PrefixCompress("abc", 3, "abcdef", 6) // returns 3 +** fts3PrefixCompress("abX", 3, "abcdef", 6) // returns 2 +** fts3PrefixCompress("abX", 3, "Xbcdef", 6) // returns 0 +*/ +static int fts3PrefixCompress( + const char *zPrev, /* Buffer containing previous term */ + int nPrev, /* Size of buffer zPrev in bytes */ + const char *zNext, /* Buffer containing next term */ + int nNext /* Size of buffer zNext in bytes */ +){ + int n; + for(n=0; nnData; /* Current size of node in bytes */ + int nReq = nData; /* Required space after adding zTerm */ + int nPrefix; /* Number of bytes of prefix compression */ + int nSuffix; /* Suffix length */ + + nPrefix = fts3PrefixCompress(pTree->zTerm, pTree->nTerm, zTerm, nTerm); + nSuffix = nTerm-nPrefix; + + /* If nSuffix is zero or less, then zTerm/nTerm must be a prefix of + ** pWriter->zTerm/pWriter->nTerm. i.e. must be equal to or less than when + ** compared with BINARY collation. This indicates corruption. */ + if( nSuffix<=0 ) return FTS_CORRUPT_VTAB; + + nReq += sqlite3Fts3VarintLen(nPrefix)+sqlite3Fts3VarintLen(nSuffix)+nSuffix; + if( nReq<=p->nNodeSize || !pTree->zTerm ){ + + if( nReq>p->nNodeSize ){ + /* An unusual case: this is the first term to be added to the node + ** and the static node buffer (p->nNodeSize bytes) is not large + ** enough. Use a separately malloced buffer instead This wastes + ** p->nNodeSize bytes, but since this scenario only comes about when + ** the database contain two terms that share a prefix of almost 2KB, + ** this is not expected to be a serious problem. + */ + assert( pTree->aData==(char *)&pTree[1] ); + pTree->aData = (char *)sqlite3_malloc64(nReq); + if( !pTree->aData ){ + return SQLITE_NOMEM; + } + } + + if( pTree->zTerm ){ + /* There is no prefix-length field for first term in a node */ + nData += sqlite3Fts3PutVarint(&pTree->aData[nData], nPrefix); + } + + nData += sqlite3Fts3PutVarint(&pTree->aData[nData], nSuffix); + memcpy(&pTree->aData[nData], &zTerm[nPrefix], nSuffix); + pTree->nData = nData + nSuffix; + pTree->nEntry++; + + if( isCopyTerm ){ + if( pTree->nMalloczMalloc, (i64)nTerm*2); + if( !zNew ){ + return SQLITE_NOMEM; + } + pTree->nMalloc = nTerm*2; + pTree->zMalloc = zNew; + } + pTree->zTerm = pTree->zMalloc; + memcpy(pTree->zTerm, zTerm, nTerm); + pTree->nTerm = nTerm; + }else{ + pTree->zTerm = (char *)zTerm; + pTree->nTerm = nTerm; + } + return SQLITE_OK; + } + } + + /* If control flows to here, it was not possible to append zTerm to the + ** current node. Create a new node (a right-sibling of the current node). + ** If this is the first node in the tree, the term is added to it. + ** + ** Otherwise, the term is not added to the new node, it is left empty for + ** now. Instead, the term is inserted into the parent of pTree. If pTree + ** has no parent, one is created here. + */ + pNew = (SegmentNode *)sqlite3_malloc64(sizeof(SegmentNode) + p->nNodeSize); + if( !pNew ){ + return SQLITE_NOMEM; + } + memset(pNew, 0, sizeof(SegmentNode)); + pNew->nData = 1 + FTS3_VARINT_MAX; + pNew->aData = (char *)&pNew[1]; + + if( pTree ){ + SegmentNode *pParent = pTree->pParent; + rc = fts3NodeAddTerm(p, &pParent, isCopyTerm, zTerm, nTerm); + if( pTree->pParent==0 ){ + pTree->pParent = pParent; + } + pTree->pRight = pNew; + pNew->pLeftmost = pTree->pLeftmost; + pNew->pParent = pParent; + pNew->zMalloc = pTree->zMalloc; + pNew->nMalloc = pTree->nMalloc; + pTree->zMalloc = 0; + }else{ + pNew->pLeftmost = pNew; + rc = fts3NodeAddTerm(p, &pNew, isCopyTerm, zTerm, nTerm); + } + + *ppTree = pNew; + return rc; +} + +/* +** Helper function for fts3NodeWrite(). +*/ +static int fts3TreeFinishNode( + SegmentNode *pTree, + int iHeight, + sqlite3_int64 iLeftChild +){ + int nStart; + assert( iHeight>=1 && iHeight<128 ); + nStart = FTS3_VARINT_MAX - sqlite3Fts3VarintLen(iLeftChild); + pTree->aData[nStart] = (char)iHeight; + sqlite3Fts3PutVarint(&pTree->aData[nStart+1], iLeftChild); + return nStart; +} + +/* +** Write the buffer for the segment node pTree and all of its peers to the +** database. Then call this function recursively to write the parent of +** pTree and its peers to the database. +** +** Except, if pTree is a root node, do not write it to the database. Instead, +** set output variables *paRoot and *pnRoot to contain the root node. +** +** If successful, SQLITE_OK is returned and output variable *piLast is +** set to the largest blockid written to the database (or zero if no +** blocks were written to the db). Otherwise, an SQLite error code is +** returned. +*/ +static int fts3NodeWrite( + Fts3Table *p, /* Virtual table handle */ + SegmentNode *pTree, /* SegmentNode handle */ + int iHeight, /* Height of this node in tree */ + sqlite3_int64 iLeaf, /* Block id of first leaf node */ + sqlite3_int64 iFree, /* Block id of next free slot in %_segments */ + sqlite3_int64 *piLast, /* OUT: Block id of last entry written */ + char **paRoot, /* OUT: Data for root node */ + int *pnRoot /* OUT: Size of root node in bytes */ +){ + int rc = SQLITE_OK; + + if( !pTree->pParent ){ + /* Root node of the tree. */ + int nStart = fts3TreeFinishNode(pTree, iHeight, iLeaf); + *piLast = iFree-1; + *pnRoot = pTree->nData - nStart; + *paRoot = &pTree->aData[nStart]; + }else{ + SegmentNode *pIter; + sqlite3_int64 iNextFree = iFree; + sqlite3_int64 iNextLeaf = iLeaf; + for(pIter=pTree->pLeftmost; pIter && rc==SQLITE_OK; pIter=pIter->pRight){ + int nStart = fts3TreeFinishNode(pIter, iHeight, iNextLeaf); + int nWrite = pIter->nData - nStart; + + rc = fts3WriteSegment(p, iNextFree, &pIter->aData[nStart], nWrite); + iNextFree++; + iNextLeaf += (pIter->nEntry+1); + } + if( rc==SQLITE_OK ){ + assert( iNextLeaf==iFree ); + rc = fts3NodeWrite( + p, pTree->pParent, iHeight+1, iFree, iNextFree, piLast, paRoot, pnRoot + ); + } + } + + return rc; +} + +/* +** Free all memory allocations associated with the tree pTree. +*/ +static void fts3NodeFree(SegmentNode *pTree){ + if( pTree ){ + SegmentNode *p = pTree->pLeftmost; + fts3NodeFree(p->pParent); + while( p ){ + SegmentNode *pRight = p->pRight; + if( p->aData!=(char *)&p[1] ){ + sqlite3_free(p->aData); + } + assert( pRight==0 || p->zMalloc==0 ); + sqlite3_free(p->zMalloc); + sqlite3_free(p); + p = pRight; + } + } +} + +/* +** Add a term to the segment being constructed by the SegmentWriter object +** *ppWriter. When adding the first term to a segment, *ppWriter should +** be passed NULL. This function will allocate a new SegmentWriter object +** and return it via the input/output variable *ppWriter in this case. +** +** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code. +*/ +static int fts3SegWriterAdd( + Fts3Table *p, /* Virtual table handle */ + SegmentWriter **ppWriter, /* IN/OUT: SegmentWriter handle */ + int isCopyTerm, /* True if buffer zTerm must be copied */ + const char *zTerm, /* Pointer to buffer containing term */ + int nTerm, /* Size of term in bytes */ + const char *aDoclist, /* Pointer to buffer containing doclist */ + int nDoclist /* Size of doclist in bytes */ +){ + int nPrefix; /* Size of term prefix in bytes */ + int nSuffix; /* Size of term suffix in bytes */ + i64 nReq; /* Number of bytes required on leaf page */ + int nData; + SegmentWriter *pWriter = *ppWriter; + + if( !pWriter ){ + int rc; + sqlite3_stmt *pStmt; + + /* Allocate the SegmentWriter structure */ + pWriter = (SegmentWriter *)sqlite3_malloc64(sizeof(SegmentWriter)); + if( !pWriter ) return SQLITE_NOMEM; + memset(pWriter, 0, sizeof(SegmentWriter)); + *ppWriter = pWriter; + + /* Allocate a buffer in which to accumulate data */ + pWriter->aData = (char *)sqlite3_malloc64(p->nNodeSize); + if( !pWriter->aData ) return SQLITE_NOMEM; + pWriter->nSize = p->nNodeSize; + + /* Find the next free blockid in the %_segments table */ + rc = fts3SqlStmt(p, SQL_NEXT_SEGMENTS_ID, &pStmt, 0); + if( rc!=SQLITE_OK ) return rc; + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + pWriter->iFree = sqlite3_column_int64(pStmt, 0); + pWriter->iFirst = pWriter->iFree; + } + rc = sqlite3_reset(pStmt); + if( rc!=SQLITE_OK ) return rc; + } + nData = pWriter->nData; + + nPrefix = fts3PrefixCompress(pWriter->zTerm, pWriter->nTerm, zTerm, nTerm); + nSuffix = nTerm-nPrefix; + + /* If nSuffix is zero or less, then zTerm/nTerm must be a prefix of + ** pWriter->zTerm/pWriter->nTerm. i.e. must be equal to or less than when + ** compared with BINARY collation. This indicates corruption. */ + if( nSuffix<=0 ) return FTS_CORRUPT_VTAB; + + /* Figure out how many bytes are required by this new entry */ + nReq = sqlite3Fts3VarintLen(nPrefix) + /* varint containing prefix size */ + sqlite3Fts3VarintLen(nSuffix) + /* varint containing suffix size */ + nSuffix + /* Term suffix */ + sqlite3Fts3VarintLen(nDoclist) + /* Size of doclist */ + nDoclist; /* Doclist data */ + + if( nData>0 && nData+nReq>p->nNodeSize ){ + int rc; + + /* The current leaf node is full. Write it out to the database. */ + if( pWriter->iFree==LARGEST_INT64 ) return FTS_CORRUPT_VTAB; + rc = fts3WriteSegment(p, pWriter->iFree++, pWriter->aData, nData); + if( rc!=SQLITE_OK ) return rc; + p->nLeafAdd++; + + /* Add the current term to the interior node tree. The term added to + ** the interior tree must: + ** + ** a) be greater than the largest term on the leaf node just written + ** to the database (still available in pWriter->zTerm), and + ** + ** b) be less than or equal to the term about to be added to the new + ** leaf node (zTerm/nTerm). + ** + ** In other words, it must be the prefix of zTerm 1 byte longer than + ** the common prefix (if any) of zTerm and pWriter->zTerm. + */ + assert( nPrefixpTree, isCopyTerm, zTerm, nPrefix+1); + if( rc!=SQLITE_OK ) return rc; + + nData = 0; + pWriter->nTerm = 0; + + nPrefix = 0; + nSuffix = nTerm; + nReq = 1 + /* varint containing prefix size */ + sqlite3Fts3VarintLen(nTerm) + /* varint containing suffix size */ + nTerm + /* Term suffix */ + sqlite3Fts3VarintLen(nDoclist) + /* Size of doclist */ + nDoclist; /* Doclist data */ + } + + /* Increase the total number of bytes written to account for the new entry. */ + pWriter->nLeafData += nReq; + + /* If the buffer currently allocated is too small for this entry, realloc + ** the buffer to make it large enough. + */ + if( nReq>pWriter->nSize ){ + char *aNew = sqlite3_realloc64(pWriter->aData, nReq); + if( !aNew ) return SQLITE_NOMEM; + pWriter->aData = aNew; + pWriter->nSize = nReq; + } + assert( nData+nReq<=pWriter->nSize ); + + /* Append the prefix-compressed term and doclist to the buffer. */ + nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nPrefix); + nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nSuffix); + assert( nSuffix>0 ); + memcpy(&pWriter->aData[nData], &zTerm[nPrefix], nSuffix); + nData += nSuffix; + nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nDoclist); + assert( nDoclist>0 ); + memcpy(&pWriter->aData[nData], aDoclist, nDoclist); + pWriter->nData = nData + nDoclist; + + /* Save the current term so that it can be used to prefix-compress the next. + ** If the isCopyTerm parameter is true, then the buffer pointed to by + ** zTerm is transient, so take a copy of the term data. Otherwise, just + ** store a copy of the pointer. + */ + if( isCopyTerm ){ + if( nTerm>pWriter->nMalloc ){ + char *zNew = sqlite3_realloc64(pWriter->zMalloc, (i64)nTerm*2); + if( !zNew ){ + return SQLITE_NOMEM; + } + pWriter->nMalloc = nTerm*2; + pWriter->zMalloc = zNew; + pWriter->zTerm = zNew; + } + assert( pWriter->zTerm==pWriter->zMalloc ); + assert( nTerm>0 ); + memcpy(pWriter->zTerm, zTerm, nTerm); + }else{ + pWriter->zTerm = (char *)zTerm; + } + pWriter->nTerm = nTerm; + + return SQLITE_OK; +} + +/* +** Flush all data associated with the SegmentWriter object pWriter to the +** database. This function must be called after all terms have been added +** to the segment using fts3SegWriterAdd(). If successful, SQLITE_OK is +** returned. Otherwise, an SQLite error code. +*/ +static int fts3SegWriterFlush( + Fts3Table *p, /* Virtual table handle */ + SegmentWriter *pWriter, /* SegmentWriter to flush to the db */ + sqlite3_int64 iLevel, /* Value for 'level' column of %_segdir */ + int iIdx /* Value for 'idx' column of %_segdir */ +){ + int rc; /* Return code */ + if( pWriter->pTree ){ + sqlite3_int64 iLast = 0; /* Largest block id written to database */ + sqlite3_int64 iLastLeaf; /* Largest leaf block id written to db */ + char *zRoot = NULL; /* Pointer to buffer containing root node */ + int nRoot = 0; /* Size of buffer zRoot */ + + iLastLeaf = pWriter->iFree; + rc = fts3WriteSegment(p, pWriter->iFree++, pWriter->aData, pWriter->nData); + if( rc==SQLITE_OK ){ + rc = fts3NodeWrite(p, pWriter->pTree, 1, + pWriter->iFirst, pWriter->iFree, &iLast, &zRoot, &nRoot); + } + if( rc==SQLITE_OK ){ + rc = fts3WriteSegdir(p, iLevel, iIdx, + pWriter->iFirst, iLastLeaf, iLast, pWriter->nLeafData, zRoot, nRoot); + } + }else{ + /* The entire tree fits on the root node. Write it to the segdir table. */ + rc = fts3WriteSegdir(p, iLevel, iIdx, + 0, 0, 0, pWriter->nLeafData, pWriter->aData, pWriter->nData); + } + p->nLeafAdd++; + return rc; +} + +/* +** Release all memory held by the SegmentWriter object passed as the +** first argument. +*/ +static void fts3SegWriterFree(SegmentWriter *pWriter){ + if( pWriter ){ + sqlite3_free(pWriter->aData); + sqlite3_free(pWriter->zMalloc); + fts3NodeFree(pWriter->pTree); + sqlite3_free(pWriter); + } +} + +/* +** The first value in the apVal[] array is assumed to contain an integer. +** This function tests if there exist any documents with docid values that +** are different from that integer. i.e. if deleting the document with docid +** pRowid would mean the FTS3 table were empty. +** +** If successful, *pisEmpty is set to true if the table is empty except for +** document pRowid, or false otherwise, and SQLITE_OK is returned. If an +** error occurs, an SQLite error code is returned. +*/ +static int fts3IsEmpty(Fts3Table *p, sqlite3_value *pRowid, int *pisEmpty){ + sqlite3_stmt *pStmt; + int rc; + if( p->zContentTbl ){ + /* If using the content=xxx option, assume the table is never empty */ + *pisEmpty = 0; + rc = SQLITE_OK; + }else{ + rc = fts3SqlStmt(p, SQL_IS_EMPTY, &pStmt, &pRowid); + if( rc==SQLITE_OK ){ + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + *pisEmpty = sqlite3_column_int(pStmt, 0); + } + rc = sqlite3_reset(pStmt); + } + } + return rc; +} + +/* +** Set *pnMax to the largest segment level in the database for the index +** iIndex. +** +** Segment levels are stored in the 'level' column of the %_segdir table. +** +** Return SQLITE_OK if successful, or an SQLite error code if not. +*/ +static int fts3SegmentMaxLevel( + Fts3Table *p, + int iLangid, + int iIndex, + sqlite3_int64 *pnMax +){ + sqlite3_stmt *pStmt; + int rc; + assert( iIndex>=0 && iIndexnIndex ); + + /* Set pStmt to the compiled version of: + ** + ** SELECT max(level) FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ? + ** + ** (1024 is actually the value of macro FTS3_SEGDIR_PREFIXLEVEL_STR). + */ + rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR_MAX_LEVEL, &pStmt, 0); + if( rc!=SQLITE_OK ) return rc; + sqlite3_bind_int64(pStmt, 1, getAbsoluteLevel(p, iLangid, iIndex, 0)); + sqlite3_bind_int64(pStmt, 2, + getAbsoluteLevel(p, iLangid, iIndex, FTS3_SEGDIR_MAXLEVEL-1) + ); + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + *pnMax = sqlite3_column_int64(pStmt, 0); + } + return sqlite3_reset(pStmt); +} + +/* +** iAbsLevel is an absolute level that may be assumed to exist within +** the database. This function checks if it is the largest level number +** within its index. Assuming no error occurs, *pbMax is set to 1 if +** iAbsLevel is indeed the largest level, or 0 otherwise, and SQLITE_OK +** is returned. If an error occurs, an error code is returned and the +** final value of *pbMax is undefined. +*/ +static int fts3SegmentIsMaxLevel(Fts3Table *p, i64 iAbsLevel, int *pbMax){ + + /* Set pStmt to the compiled version of: + ** + ** SELECT max(level) FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ? + ** + ** (1024 is actually the value of macro FTS3_SEGDIR_PREFIXLEVEL_STR). + */ + sqlite3_stmt *pStmt; + int rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR_MAX_LEVEL, &pStmt, 0); + if( rc!=SQLITE_OK ) return rc; + sqlite3_bind_int64(pStmt, 1, iAbsLevel+1); + sqlite3_bind_int64(pStmt, 2, + (((u64)iAbsLevel/FTS3_SEGDIR_MAXLEVEL)+1) * FTS3_SEGDIR_MAXLEVEL + ); + + *pbMax = 0; + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + *pbMax = sqlite3_column_type(pStmt, 0)==SQLITE_NULL; + } + return sqlite3_reset(pStmt); +} + +/* +** Delete all entries in the %_segments table associated with the segment +** opened with seg-reader pSeg. This function does not affect the contents +** of the %_segdir table. +*/ +static int fts3DeleteSegment( + Fts3Table *p, /* FTS table handle */ + Fts3SegReader *pSeg /* Segment to delete */ +){ + int rc = SQLITE_OK; /* Return code */ + if( pSeg->iStartBlock ){ + sqlite3_stmt *pDelete; /* SQL statement to delete rows */ + rc = fts3SqlStmt(p, SQL_DELETE_SEGMENTS_RANGE, &pDelete, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pDelete, 1, pSeg->iStartBlock); + sqlite3_bind_int64(pDelete, 2, pSeg->iEndBlock); + sqlite3_step(pDelete); + rc = sqlite3_reset(pDelete); + } + } + return rc; +} + +/* +** This function is used after merging multiple segments into a single large +** segment to delete the old, now redundant, segment b-trees. Specifically, +** it: +** +** 1) Deletes all %_segments entries for the segments associated with +** each of the SegReader objects in the array passed as the third +** argument, and +** +** 2) deletes all %_segdir entries with level iLevel, or all %_segdir +** entries regardless of level if (iLevel<0). +** +** SQLITE_OK is returned if successful, otherwise an SQLite error code. +*/ +static int fts3DeleteSegdir( + Fts3Table *p, /* Virtual table handle */ + int iLangid, /* Language id */ + int iIndex, /* Index for p->aIndex */ + int iLevel, /* Level of %_segdir entries to delete */ + Fts3SegReader **apSegment, /* Array of SegReader objects */ + int nReader /* Size of array apSegment */ +){ + int rc = SQLITE_OK; /* Return Code */ + int i; /* Iterator variable */ + sqlite3_stmt *pDelete = 0; /* SQL statement to delete rows */ + + for(i=0; rc==SQLITE_OK && i=0 || iLevel==FTS3_SEGCURSOR_ALL ); + if( iLevel==FTS3_SEGCURSOR_ALL ){ + rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_RANGE, &pDelete, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pDelete, 1, getAbsoluteLevel(p, iLangid, iIndex, 0)); + sqlite3_bind_int64(pDelete, 2, + getAbsoluteLevel(p, iLangid, iIndex, FTS3_SEGDIR_MAXLEVEL-1) + ); + } + }else{ + rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_LEVEL, &pDelete, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64( + pDelete, 1, getAbsoluteLevel(p, iLangid, iIndex, iLevel) + ); + } + } + + if( rc==SQLITE_OK ){ + sqlite3_step(pDelete); + rc = sqlite3_reset(pDelete); + } + + return rc; +} + +/* +** When this function is called, buffer *ppList (size *pnList bytes) contains +** a position list that may (or may not) feature multiple columns. This +** function adjusts the pointer *ppList and the length *pnList so that they +** identify the subset of the position list that corresponds to column iCol. +** +** If there are no entries in the input position list for column iCol, then +** *pnList is set to zero before returning. +** +** If parameter bZero is non-zero, then any part of the input list following +** the end of the output list is zeroed before returning. +*/ +static void fts3ColumnFilter( + int iCol, /* Column to filter on */ + int bZero, /* Zero out anything following *ppList */ + char **ppList, /* IN/OUT: Pointer to position list */ + int *pnList /* IN/OUT: Size of buffer *ppList in bytes */ +){ + char *pList = *ppList; + int nList = *pnList; + char *pEnd = &pList[nList]; + int iCurrent = 0; + char *p = pList; + + assert( iCol>=0 ); + while( 1 ){ + char c = 0; + while( p0){ + memset(&pList[nList], 0, pEnd - &pList[nList]); + } + *ppList = pList; + *pnList = nList; +} + +/* +** Cache data in the Fts3MultiSegReader.aBuffer[] buffer (overwriting any +** existing data). Grow the buffer if required. +** +** If successful, return SQLITE_OK. Otherwise, if an OOM error is encountered +** trying to resize the buffer, return SQLITE_NOMEM. +*/ +static int fts3MsrBufferData( + Fts3MultiSegReader *pMsr, /* Multi-segment-reader handle */ + char *pList, + i64 nList +){ + if( (nList+FTS3_NODE_PADDING)>pMsr->nBuffer ){ + char *pNew; + int nNew = nList*2 + FTS3_NODE_PADDING; + pNew = (char *)sqlite3_realloc64(pMsr->aBuffer, nNew); + if( !pNew ) return SQLITE_NOMEM; + pMsr->aBuffer = pNew; + pMsr->nBuffer = nNew; + } + + assert( nList>0 ); + memcpy(pMsr->aBuffer, pList, nList); + memset(&pMsr->aBuffer[nList], 0, FTS3_NODE_PADDING); + return SQLITE_OK; +} + +SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext( + Fts3Table *p, /* Virtual table handle */ + Fts3MultiSegReader *pMsr, /* Multi-segment-reader handle */ + sqlite3_int64 *piDocid, /* OUT: Docid value */ + char **paPoslist, /* OUT: Pointer to position list */ + int *pnPoslist /* OUT: Size of position list in bytes */ +){ + int nMerge = pMsr->nAdvance; + Fts3SegReader **apSegment = pMsr->apSegment; + int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = ( + p->bDescIdx ? fts3SegReaderDoclistCmpRev : fts3SegReaderDoclistCmp + ); + + if( nMerge==0 ){ + *paPoslist = 0; + return SQLITE_OK; + } + + while( 1 ){ + Fts3SegReader *pSeg; + pSeg = pMsr->apSegment[0]; + + if( pSeg->pOffsetList==0 ){ + *paPoslist = 0; + break; + }else{ + int rc; + char *pList; + int nList; + int j; + sqlite3_int64 iDocid = apSegment[0]->iDocid; + + rc = fts3SegReaderNextDocid(p, apSegment[0], &pList, &nList); + j = 1; + while( rc==SQLITE_OK + && jpOffsetList + && apSegment[j]->iDocid==iDocid + ){ + rc = fts3SegReaderNextDocid(p, apSegment[j], 0, 0); + j++; + } + if( rc!=SQLITE_OK ) return rc; + fts3SegReaderSort(pMsr->apSegment, nMerge, j, xCmp); + + if( nList>0 && fts3SegReaderIsPending(apSegment[0]) ){ + rc = fts3MsrBufferData(pMsr, pList, (i64)nList+1); + if( rc!=SQLITE_OK ) return rc; + assert( (pMsr->aBuffer[nList] & 0xFE)==0x00 ); + pList = pMsr->aBuffer; + } + + if( pMsr->iColFilter>=0 ){ + fts3ColumnFilter(pMsr->iColFilter, 1, &pList, &nList); + } + + if( nList>0 ){ + *paPoslist = pList; + *piDocid = iDocid; + *pnPoslist = nList; + break; + } + } + } + + return SQLITE_OK; +} + +static int fts3SegReaderStart( + Fts3Table *p, /* Virtual table handle */ + Fts3MultiSegReader *pCsr, /* Cursor object */ + const char *zTerm, /* Term searched for (or NULL) */ + int nTerm /* Length of zTerm in bytes */ +){ + int i; + int nSeg = pCsr->nSegment; + + /* If the Fts3SegFilter defines a specific term (or term prefix) to search + ** for, then advance each segment iterator until it points to a term of + ** equal or greater value than the specified term. This prevents many + ** unnecessary merge/sort operations for the case where single segment + ** b-tree leaf nodes contain more than one term. + */ + for(i=0; pCsr->bRestart==0 && inSegment; i++){ + int res = 0; + Fts3SegReader *pSeg = pCsr->apSegment[i]; + do { + int rc = fts3SegReaderNext(p, pSeg, 0); + if( rc!=SQLITE_OK ) return rc; + }while( zTerm && (res = fts3SegReaderTermCmp(pSeg, zTerm, nTerm))<0 ); + + if( pSeg->bLookup && res!=0 ){ + fts3SegReaderSetEof(pSeg); + } + } + fts3SegReaderSort(pCsr->apSegment, nSeg, nSeg, fts3SegReaderCmp); + + return SQLITE_OK; +} + +SQLITE_PRIVATE int sqlite3Fts3SegReaderStart( + Fts3Table *p, /* Virtual table handle */ + Fts3MultiSegReader *pCsr, /* Cursor object */ + Fts3SegFilter *pFilter /* Restrictions on range of iteration */ +){ + pCsr->pFilter = pFilter; + return fts3SegReaderStart(p, pCsr, pFilter->zTerm, pFilter->nTerm); +} + +SQLITE_PRIVATE int sqlite3Fts3MsrIncrStart( + Fts3Table *p, /* Virtual table handle */ + Fts3MultiSegReader *pCsr, /* Cursor object */ + int iCol, /* Column to match on. */ + const char *zTerm, /* Term to iterate through a doclist for */ + int nTerm /* Number of bytes in zTerm */ +){ + int i; + int rc; + int nSegment = pCsr->nSegment; + int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = ( + p->bDescIdx ? fts3SegReaderDoclistCmpRev : fts3SegReaderDoclistCmp + ); + + assert( pCsr->pFilter==0 ); + assert( zTerm && nTerm>0 ); + + /* Advance each segment iterator until it points to the term zTerm/nTerm. */ + rc = fts3SegReaderStart(p, pCsr, zTerm, nTerm); + if( rc!=SQLITE_OK ) return rc; + + /* Determine how many of the segments actually point to zTerm/nTerm. */ + for(i=0; iapSegment[i]; + if( !pSeg->aNode || fts3SegReaderTermCmp(pSeg, zTerm, nTerm) ){ + break; + } + } + pCsr->nAdvance = i; + + /* Advance each of the segments to point to the first docid. */ + for(i=0; inAdvance; i++){ + rc = fts3SegReaderFirstDocid(p, pCsr->apSegment[i]); + if( rc!=SQLITE_OK ) return rc; + } + fts3SegReaderSort(pCsr->apSegment, i, i, xCmp); + + assert( iCol<0 || iColnColumn ); + pCsr->iColFilter = iCol; + + return SQLITE_OK; +} + +/* +** This function is called on a MultiSegReader that has been started using +** sqlite3Fts3MsrIncrStart(). One or more calls to MsrIncrNext() may also +** have been made. Calling this function puts the MultiSegReader in such +** a state that if the next two calls are: +** +** sqlite3Fts3SegReaderStart() +** sqlite3Fts3SegReaderStep() +** +** then the entire doclist for the term is available in +** MultiSegReader.aDoclist/nDoclist. +*/ +SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr){ + int i; /* Used to iterate through segment-readers */ + + assert( pCsr->zTerm==0 ); + assert( pCsr->nTerm==0 ); + assert( pCsr->aDoclist==0 ); + assert( pCsr->nDoclist==0 ); + + pCsr->nAdvance = 0; + pCsr->bRestart = 1; + for(i=0; inSegment; i++){ + pCsr->apSegment[i]->pOffsetList = 0; + pCsr->apSegment[i]->nOffsetList = 0; + pCsr->apSegment[i]->iDocid = 0; + } + + return SQLITE_OK; +} + +static int fts3GrowSegReaderBuffer(Fts3MultiSegReader *pCsr, i64 nReq){ + if( nReq>pCsr->nBuffer ){ + char *aNew; + pCsr->nBuffer = nReq*2; + aNew = sqlite3_realloc64(pCsr->aBuffer, pCsr->nBuffer); + if( !aNew ){ + return SQLITE_NOMEM; + } + pCsr->aBuffer = aNew; + } + return SQLITE_OK; +} + + +SQLITE_PRIVATE int sqlite3Fts3SegReaderStep( + Fts3Table *p, /* Virtual table handle */ + Fts3MultiSegReader *pCsr /* Cursor object */ +){ + int rc = SQLITE_OK; + + int isIgnoreEmpty = (pCsr->pFilter->flags & FTS3_SEGMENT_IGNORE_EMPTY); + int isRequirePos = (pCsr->pFilter->flags & FTS3_SEGMENT_REQUIRE_POS); + int isColFilter = (pCsr->pFilter->flags & FTS3_SEGMENT_COLUMN_FILTER); + int isPrefix = (pCsr->pFilter->flags & FTS3_SEGMENT_PREFIX); + int isScan = (pCsr->pFilter->flags & FTS3_SEGMENT_SCAN); + int isFirst = (pCsr->pFilter->flags & FTS3_SEGMENT_FIRST); + + Fts3SegReader **apSegment = pCsr->apSegment; + int nSegment = pCsr->nSegment; + Fts3SegFilter *pFilter = pCsr->pFilter; + int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = ( + p->bDescIdx ? fts3SegReaderDoclistCmpRev : fts3SegReaderDoclistCmp + ); + + if( pCsr->nSegment==0 ) return SQLITE_OK; + + do { + int nMerge; + int i; + + /* Advance the first pCsr->nAdvance entries in the apSegment[] array + ** forward. Then sort the list in order of current term again. + */ + for(i=0; inAdvance; i++){ + Fts3SegReader *pSeg = apSegment[i]; + if( pSeg->bLookup ){ + fts3SegReaderSetEof(pSeg); + }else{ + rc = fts3SegReaderNext(p, pSeg, 0); + } + if( rc!=SQLITE_OK ) return rc; + } + fts3SegReaderSort(apSegment, nSegment, pCsr->nAdvance, fts3SegReaderCmp); + pCsr->nAdvance = 0; + + /* If all the seg-readers are at EOF, we're finished. return SQLITE_OK. */ + assert( rc==SQLITE_OK ); + if( apSegment[0]->aNode==0 ) break; + + pCsr->nTerm = apSegment[0]->nTerm; + pCsr->zTerm = apSegment[0]->zTerm; + + /* If this is a prefix-search, and if the term that apSegment[0] points + ** to does not share a suffix with pFilter->zTerm/nTerm, then all + ** required callbacks have been made. In this case exit early. + ** + ** Similarly, if this is a search for an exact match, and the first term + ** of segment apSegment[0] is not a match, exit early. + */ + if( pFilter->zTerm && !isScan ){ + if( pCsr->nTermnTerm + || (!isPrefix && pCsr->nTerm>pFilter->nTerm) + || memcmp(pCsr->zTerm, pFilter->zTerm, pFilter->nTerm) + ){ + break; + } + } + + nMerge = 1; + while( nMergeaNode + && apSegment[nMerge]->nTerm==pCsr->nTerm + && 0==memcmp(pCsr->zTerm, apSegment[nMerge]->zTerm, pCsr->nTerm) + ){ + nMerge++; + } + + assert( isIgnoreEmpty || (isRequirePos && !isColFilter) ); + if( nMerge==1 + && !isIgnoreEmpty + && !isFirst + && (p->bDescIdx==0 || fts3SegReaderIsPending(apSegment[0])==0) + ){ + pCsr->nDoclist = apSegment[0]->nDoclist; + if( fts3SegReaderIsPending(apSegment[0]) ){ + rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist, + (i64)pCsr->nDoclist); + pCsr->aDoclist = pCsr->aBuffer; + }else{ + pCsr->aDoclist = apSegment[0]->aDoclist; + } + if( rc==SQLITE_OK ) rc = SQLITE_ROW; + }else{ + int nDoclist = 0; /* Size of doclist */ + sqlite3_int64 iPrev = 0; /* Previous docid stored in doclist */ + + /* The current term of the first nMerge entries in the array + ** of Fts3SegReader objects is the same. The doclists must be merged + ** and a single term returned with the merged doclist. + */ + for(i=0; ipOffsetList ){ + int j; /* Number of segments that share a docid */ + char *pList = 0; + int nList = 0; + int nByte; + sqlite3_int64 iDocid = apSegment[0]->iDocid; + fts3SegReaderNextDocid(p, apSegment[0], &pList, &nList); + j = 1; + while( jpOffsetList + && apSegment[j]->iDocid==iDocid + ){ + fts3SegReaderNextDocid(p, apSegment[j], 0, 0); + j++; + } + + if( isColFilter ){ + fts3ColumnFilter(pFilter->iCol, 0, &pList, &nList); + } + + if( !isIgnoreEmpty || nList>0 ){ + + /* Calculate the 'docid' delta value to write into the merged + ** doclist. */ + sqlite3_int64 iDelta; + if( p->bDescIdx && nDoclist>0 ){ + if( iPrev<=iDocid ) return FTS_CORRUPT_VTAB; + iDelta = (i64)((u64)iPrev - (u64)iDocid); + }else{ + if( nDoclist>0 && iPrev>=iDocid ) return FTS_CORRUPT_VTAB; + iDelta = (i64)((u64)iDocid - (u64)iPrev); + } + + nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0); + + rc = fts3GrowSegReaderBuffer(pCsr, + (i64)nByte+nDoclist+FTS3_NODE_PADDING); + if( rc ) return rc; + + if( isFirst ){ + char *a = &pCsr->aBuffer[nDoclist]; + int nWrite; + + nWrite = sqlite3Fts3FirstFilter(iDelta, pList, nList, a); + if( nWrite ){ + iPrev = iDocid; + nDoclist += nWrite; + } + }else{ + nDoclist += sqlite3Fts3PutVarint(&pCsr->aBuffer[nDoclist], iDelta); + iPrev = iDocid; + if( isRequirePos ){ + memcpy(&pCsr->aBuffer[nDoclist], pList, nList); + nDoclist += nList; + pCsr->aBuffer[nDoclist++] = '\0'; + } + } + } + + fts3SegReaderSort(apSegment, nMerge, j, xCmp); + } + if( nDoclist>0 ){ + rc = fts3GrowSegReaderBuffer(pCsr, (i64)nDoclist+FTS3_NODE_PADDING); + if( rc ) return rc; + memset(&pCsr->aBuffer[nDoclist], 0, FTS3_NODE_PADDING); + pCsr->aDoclist = pCsr->aBuffer; + pCsr->nDoclist = nDoclist; + rc = SQLITE_ROW; + } + } + pCsr->nAdvance = nMerge; + }while( rc==SQLITE_OK ); + + return rc; +} + + +SQLITE_PRIVATE void sqlite3Fts3SegReaderFinish( + Fts3MultiSegReader *pCsr /* Cursor object */ +){ + if( pCsr ){ + int i; + for(i=0; inSegment; i++){ + sqlite3Fts3SegReaderFree(pCsr->apSegment[i]); + } + sqlite3_free(pCsr->apSegment); + sqlite3_free(pCsr->aBuffer); + + pCsr->nSegment = 0; + pCsr->apSegment = 0; + pCsr->aBuffer = 0; + } +} + +/* +** Decode the "end_block" field, selected by column iCol of the SELECT +** statement passed as the first argument. +** +** The "end_block" field may contain either an integer, or a text field +** containing the text representation of two non-negative integers separated +** by one or more space (0x20) characters. In the first case, set *piEndBlock +** to the integer value and *pnByte to zero before returning. In the second, +** set *piEndBlock to the first value and *pnByte to the second. +*/ +static void fts3ReadEndBlockField( + sqlite3_stmt *pStmt, + int iCol, + i64 *piEndBlock, + i64 *pnByte +){ + const unsigned char *zText = sqlite3_column_text(pStmt, iCol); + if( zText ){ + int i; + int iMul = 1; + u64 iVal = 0; + for(i=0; zText[i]>='0' && zText[i]<='9'; i++){ + iVal = iVal*10 + (zText[i] - '0'); + } + *piEndBlock = (i64)iVal; + while( zText[i]==' ' ) i++; + iVal = 0; + if( zText[i]=='-' ){ + i++; + iMul = -1; + } + for(/* no-op */; zText[i]>='0' && zText[i]<='9'; i++){ + iVal = iVal*10 + (zText[i] - '0'); + } + + /* This if() clause is just to avoid an integer overflow. The record is + ** corrupt in this case. */ + if( (i64)iVal==SMALLEST_INT64 ) iMul = 1; + *pnByte = ((i64)iVal * (i64)iMul); + } +} + + +/* +** A segment of size nByte bytes has just been written to absolute level +** iAbsLevel. Promote any segments that should be promoted as a result. +*/ +static int fts3PromoteSegments( + Fts3Table *p, /* FTS table handle */ + sqlite3_int64 iAbsLevel, /* Absolute level just updated */ + sqlite3_int64 nByte /* Size of new segment at iAbsLevel */ +){ + int rc = SQLITE_OK; + sqlite3_stmt *pRange; + + rc = fts3SqlStmt(p, SQL_SELECT_LEVEL_RANGE2, &pRange, 0); + + if( rc==SQLITE_OK ){ + int bOk = 0; + i64 iLast = (iAbsLevel/FTS3_SEGDIR_MAXLEVEL + 1) * FTS3_SEGDIR_MAXLEVEL - 1; + i64 nLimit = (nByte*3)/2; + + /* Loop through all entries in the %_segdir table corresponding to + ** segments in this index on levels greater than iAbsLevel. If there is + ** at least one such segment, and it is possible to determine that all + ** such segments are smaller than nLimit bytes in size, they will be + ** promoted to level iAbsLevel. */ + sqlite3_bind_int64(pRange, 1, iAbsLevel+1); + sqlite3_bind_int64(pRange, 2, iLast); + while( SQLITE_ROW==sqlite3_step(pRange) ){ + i64 nSize = 0, dummy; + fts3ReadEndBlockField(pRange, 2, &dummy, &nSize); + if( nSize<=0 || nSize>nLimit ){ + /* If nSize==0, then the %_segdir.end_block field does not not + ** contain a size value. This happens if it was written by an + ** old version of FTS. In this case it is not possible to determine + ** the size of the segment, and so segment promotion does not + ** take place. */ + bOk = 0; + break; + } + bOk = 1; + } + rc = sqlite3_reset(pRange); + + if( bOk ){ + int iIdx = 0; + sqlite3_stmt *pUpdate1 = 0; + sqlite3_stmt *pUpdate2 = 0; + + if( rc==SQLITE_OK ){ + rc = fts3SqlStmt(p, SQL_UPDATE_LEVEL_IDX, &pUpdate1, 0); + } + if( rc==SQLITE_OK ){ + rc = fts3SqlStmt(p, SQL_UPDATE_LEVEL, &pUpdate2, 0); + } + + if( rc==SQLITE_OK ){ + + /* Loop through all %_segdir entries for segments in this index with + ** levels equal to or greater than iAbsLevel. As each entry is visited, + ** updated it to set (level = -1) and (idx = N), where N is 0 for the + ** oldest segment in the range, 1 for the next oldest, and so on. + ** + ** In other words, move all segments being promoted to level -1, + ** setting the "idx" fields as appropriate to keep them in the same + ** order. The contents of level -1 (which is never used, except + ** transiently here), will be moved back to level iAbsLevel below. */ + sqlite3_bind_int64(pRange, 1, iAbsLevel); + while( SQLITE_ROW==sqlite3_step(pRange) ){ + sqlite3_bind_int(pUpdate1, 1, iIdx++); + sqlite3_bind_int(pUpdate1, 2, sqlite3_column_int(pRange, 0)); + sqlite3_bind_int(pUpdate1, 3, sqlite3_column_int(pRange, 1)); + sqlite3_step(pUpdate1); + rc = sqlite3_reset(pUpdate1); + if( rc!=SQLITE_OK ){ + sqlite3_reset(pRange); + break; + } + } + } + if( rc==SQLITE_OK ){ + rc = sqlite3_reset(pRange); + } + + /* Move level -1 to level iAbsLevel */ + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pUpdate2, 1, iAbsLevel); + sqlite3_step(pUpdate2); + rc = sqlite3_reset(pUpdate2); + } + } + } + + + return rc; +} + +/* +** Merge all level iLevel segments in the database into a single +** iLevel+1 segment. Or, if iLevel<0, merge all segments into a +** single segment with a level equal to the numerically largest level +** currently present in the database. +** +** If this function is called with iLevel<0, but there is only one +** segment in the database, SQLITE_DONE is returned immediately. +** Otherwise, if successful, SQLITE_OK is returned. If an error occurs, +** an SQLite error code is returned. +*/ +static int fts3SegmentMerge( + Fts3Table *p, + int iLangid, /* Language id to merge */ + int iIndex, /* Index in p->aIndex[] to merge */ + int iLevel /* Level to merge */ +){ + int rc; /* Return code */ + int iIdx = 0; /* Index of new segment */ + sqlite3_int64 iNewLevel = 0; /* Level/index to create new segment at */ + SegmentWriter *pWriter = 0; /* Used to write the new, merged, segment */ + Fts3SegFilter filter; /* Segment term filter condition */ + Fts3MultiSegReader csr; /* Cursor to iterate through level(s) */ + int bIgnoreEmpty = 0; /* True to ignore empty segments */ + i64 iMaxLevel = 0; /* Max level number for this index/langid */ + + assert( iLevel==FTS3_SEGCURSOR_ALL + || iLevel==FTS3_SEGCURSOR_PENDING + || iLevel>=0 + ); + assert( iLevel=0 && iIndexnIndex ); + + rc = sqlite3Fts3SegReaderCursor(p, iLangid, iIndex, iLevel, 0, 0, 1, 0, &csr); + if( rc!=SQLITE_OK || csr.nSegment==0 ) goto finished; + + if( iLevel!=FTS3_SEGCURSOR_PENDING ){ + rc = fts3SegmentMaxLevel(p, iLangid, iIndex, &iMaxLevel); + if( rc!=SQLITE_OK ) goto finished; + } + + if( iLevel==FTS3_SEGCURSOR_ALL ){ + /* This call is to merge all segments in the database to a single + ** segment. The level of the new segment is equal to the numerically + ** greatest segment level currently present in the database for this + ** index. The idx of the new segment is always 0. */ + if( csr.nSegment==1 && 0==fts3SegReaderIsPending(csr.apSegment[0]) ){ + rc = SQLITE_DONE; + goto finished; + } + iNewLevel = iMaxLevel; + bIgnoreEmpty = 1; + + }else{ + /* This call is to merge all segments at level iLevel. find the next + ** available segment index at level iLevel+1. The call to + ** fts3AllocateSegdirIdx() will merge the segments at level iLevel+1 to + ** a single iLevel+2 segment if necessary. */ + assert( FTS3_SEGCURSOR_PENDING==-1 ); + iNewLevel = getAbsoluteLevel(p, iLangid, iIndex, iLevel+1); + rc = fts3AllocateSegdirIdx(p, iLangid, iIndex, iLevel+1, &iIdx); + bIgnoreEmpty = (iLevel!=FTS3_SEGCURSOR_PENDING) && (iNewLevel>iMaxLevel); + } + if( rc!=SQLITE_OK ) goto finished; + + assert( csr.nSegment>0 ); + assert_fts3_nc( iNewLevel>=getAbsoluteLevel(p, iLangid, iIndex, 0) ); + assert_fts3_nc( + iNewLevelnLeafData); + } + } + } + + finished: + fts3SegWriterFree(pWriter); + sqlite3Fts3SegReaderFinish(&csr); + return rc; +} + + +/* +** Flush the contents of pendingTerms to level 0 segments. +*/ +SQLITE_PRIVATE int sqlite3Fts3PendingTermsFlush(Fts3Table *p){ + int rc = SQLITE_OK; + int i; + + for(i=0; rc==SQLITE_OK && inIndex; i++){ + rc = fts3SegmentMerge(p, p->iPrevLangid, i, FTS3_SEGCURSOR_PENDING); + if( rc==SQLITE_DONE ) rc = SQLITE_OK; + } + + /* Determine the auto-incr-merge setting if unknown. If enabled, + ** estimate the number of leaf blocks of content to be written + */ + if( rc==SQLITE_OK && p->bHasStat + && p->nAutoincrmerge==0xff && p->nLeafAdd>0 + ){ + sqlite3_stmt *pStmt = 0; + rc = fts3SqlStmt(p, SQL_SELECT_STAT, &pStmt, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int(pStmt, 1, FTS_STAT_AUTOINCRMERGE); + rc = sqlite3_step(pStmt); + if( rc==SQLITE_ROW ){ + p->nAutoincrmerge = sqlite3_column_int(pStmt, 0); + if( p->nAutoincrmerge==1 ) p->nAutoincrmerge = 8; + }else if( rc==SQLITE_DONE ){ + p->nAutoincrmerge = 0; + } + rc = sqlite3_reset(pStmt); + } + } + + if( rc==SQLITE_OK ){ + sqlite3Fts3PendingTermsClear(p); + } + return rc; +} + +/* +** Encode N integers as varints into a blob. +*/ +static void fts3EncodeIntArray( + int N, /* The number of integers to encode */ + u32 *a, /* The integer values */ + char *zBuf, /* Write the BLOB here */ + int *pNBuf /* Write number of bytes if zBuf[] used here */ +){ + int i, j; + for(i=j=0; iiPrevDocid. The sizes are encoded as +** a blob of varints. +*/ +static void fts3InsertDocsize( + int *pRC, /* Result code */ + Fts3Table *p, /* Table into which to insert */ + u32 *aSz /* Sizes of each column, in tokens */ +){ + char *pBlob; /* The BLOB encoding of the document size */ + int nBlob; /* Number of bytes in the BLOB */ + sqlite3_stmt *pStmt; /* Statement used to insert the encoding */ + int rc; /* Result code from subfunctions */ + + if( *pRC ) return; + pBlob = sqlite3_malloc64( 10*(sqlite3_int64)p->nColumn ); + if( pBlob==0 ){ + *pRC = SQLITE_NOMEM; + return; + } + fts3EncodeIntArray(p->nColumn, aSz, pBlob, &nBlob); + rc = fts3SqlStmt(p, SQL_REPLACE_DOCSIZE, &pStmt, 0); + if( rc ){ + sqlite3_free(pBlob); + *pRC = rc; + return; + } + sqlite3_bind_int64(pStmt, 1, p->iPrevDocid); + sqlite3_bind_blob(pStmt, 2, pBlob, nBlob, sqlite3_free); + sqlite3_step(pStmt); + *pRC = sqlite3_reset(pStmt); +} + +/* +** Record 0 of the %_stat table contains a blob consisting of N varints, +** where N is the number of user defined columns in the fts3 table plus +** two. If nCol is the number of user defined columns, then values of the +** varints are set as follows: +** +** Varint 0: Total number of rows in the table. +** +** Varint 1..nCol: For each column, the total number of tokens stored in +** the column for all rows of the table. +** +** Varint 1+nCol: The total size, in bytes, of all text values in all +** columns of all rows of the table. +** +*/ +static void fts3UpdateDocTotals( + int *pRC, /* The result code */ + Fts3Table *p, /* Table being updated */ + u32 *aSzIns, /* Size increases */ + u32 *aSzDel, /* Size decreases */ + int nChng /* Change in the number of documents */ +){ + char *pBlob; /* Storage for BLOB written into %_stat */ + int nBlob; /* Size of BLOB written into %_stat */ + u32 *a; /* Array of integers that becomes the BLOB */ + sqlite3_stmt *pStmt; /* Statement for reading and writing */ + int i; /* Loop counter */ + int rc; /* Result code from subfunctions */ + + const int nStat = p->nColumn+2; + + if( *pRC ) return; + a = sqlite3_malloc64( (sizeof(u32)+10)*(sqlite3_int64)nStat ); + if( a==0 ){ + *pRC = SQLITE_NOMEM; + return; + } + pBlob = (char*)&a[nStat]; + rc = fts3SqlStmt(p, SQL_SELECT_STAT, &pStmt, 0); + if( rc ){ + sqlite3_free(a); + *pRC = rc; + return; + } + sqlite3_bind_int(pStmt, 1, FTS_STAT_DOCTOTAL); + if( sqlite3_step(pStmt)==SQLITE_ROW ){ + fts3DecodeIntArray(nStat, a, + sqlite3_column_blob(pStmt, 0), + sqlite3_column_bytes(pStmt, 0)); + }else{ + memset(a, 0, sizeof(u32)*(nStat) ); + } + rc = sqlite3_reset(pStmt); + if( rc!=SQLITE_OK ){ + sqlite3_free(a); + *pRC = rc; + return; + } + if( nChng<0 && a[0]<(u32)(-nChng) ){ + a[0] = 0; + }else{ + a[0] += nChng; + } + for(i=0; inColumn+1; i++){ + u32 x = a[i+1]; + if( x+aSzIns[i] < aSzDel[i] ){ + x = 0; + }else{ + x = x + aSzIns[i] - aSzDel[i]; + } + a[i+1] = x; + } + fts3EncodeIntArray(nStat, a, pBlob, &nBlob); + rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pStmt, 0); + if( rc ){ + sqlite3_free(a); + *pRC = rc; + return; + } + sqlite3_bind_int(pStmt, 1, FTS_STAT_DOCTOTAL); + sqlite3_bind_blob(pStmt, 2, pBlob, nBlob, SQLITE_STATIC); + sqlite3_step(pStmt); + *pRC = sqlite3_reset(pStmt); + sqlite3_bind_null(pStmt, 2); + sqlite3_free(a); +} + +/* +** Merge the entire database so that there is one segment for each +** iIndex/iLangid combination. +*/ +static int fts3DoOptimize(Fts3Table *p, int bReturnDone){ + int bSeenDone = 0; + int rc; + sqlite3_stmt *pAllLangid = 0; + + rc = sqlite3Fts3PendingTermsFlush(p); + if( rc==SQLITE_OK ){ + rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0); + } + if( rc==SQLITE_OK ){ + int rc2; + sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid); + sqlite3_bind_int(pAllLangid, 2, p->nIndex); + while( sqlite3_step(pAllLangid)==SQLITE_ROW ){ + int i; + int iLangid = sqlite3_column_int(pAllLangid, 0); + for(i=0; rc==SQLITE_OK && inIndex; i++){ + rc = fts3SegmentMerge(p, iLangid, i, FTS3_SEGCURSOR_ALL); + if( rc==SQLITE_DONE ){ + bSeenDone = 1; + rc = SQLITE_OK; + } + } + } + rc2 = sqlite3_reset(pAllLangid); + if( rc==SQLITE_OK ) rc = rc2; + } + + sqlite3Fts3SegmentsClose(p); + + return (rc==SQLITE_OK && bReturnDone && bSeenDone) ? SQLITE_DONE : rc; +} + +/* +** This function is called when the user executes the following statement: +** +** INSERT INTO () VALUES('rebuild'); +** +** The entire FTS index is discarded and rebuilt. If the table is one +** created using the content=xxx option, then the new index is based on +** the current contents of the xxx table. Otherwise, it is rebuilt based +** on the contents of the %_content table. +*/ +static int fts3DoRebuild(Fts3Table *p){ + int rc; /* Return Code */ + + rc = fts3DeleteAll(p, 0); + if( rc==SQLITE_OK ){ + u32 *aSz = 0; + u32 *aSzIns = 0; + u32 *aSzDel = 0; + sqlite3_stmt *pStmt = 0; + int nEntry = 0; + + /* Compose and prepare an SQL statement to loop through the content table */ + char *zSql = sqlite3_mprintf("SELECT %s" , p->zReadExprlist); + if( !zSql ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3Fts3PrepareStmt(p, zSql, 0, 1, &pStmt); + sqlite3_free(zSql); + } + + if( rc==SQLITE_OK ){ + sqlite3_int64 nByte = sizeof(u32) * ((sqlite3_int64)p->nColumn+1)*3; + aSz = (u32 *)sqlite3_malloc64(nByte); + if( aSz==0 ){ + rc = SQLITE_NOMEM; + }else{ + memset(aSz, 0, nByte); + aSzIns = &aSz[p->nColumn+1]; + aSzDel = &aSzIns[p->nColumn+1]; + } + } + + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + int iCol; + int iLangid = langidFromSelect(p, pStmt); + rc = fts3PendingTermsDocid(p, 0, iLangid, sqlite3_column_int64(pStmt, 0)); + memset(aSz, 0, sizeof(aSz[0]) * (p->nColumn+1)); + for(iCol=0; rc==SQLITE_OK && iColnColumn; iCol++){ + if( p->abNotindexed[iCol]==0 ){ + const char *z = (const char *) sqlite3_column_text(pStmt, iCol+1); + rc = fts3PendingTermsAdd(p, iLangid, z, iCol, &aSz[iCol]); + aSz[p->nColumn] += sqlite3_column_bytes(pStmt, iCol+1); + } + } + if( p->bHasDocsize ){ + fts3InsertDocsize(&rc, p, aSz); + } + if( rc!=SQLITE_OK ){ + sqlite3_finalize(pStmt); + pStmt = 0; + }else{ + nEntry++; + for(iCol=0; iCol<=p->nColumn; iCol++){ + aSzIns[iCol] += aSz[iCol]; + } + } + } + if( p->bFts4 ){ + fts3UpdateDocTotals(&rc, p, aSzIns, aSzDel, nEntry); + } + sqlite3_free(aSz); + + if( pStmt ){ + int rc2 = sqlite3_finalize(pStmt); + if( rc==SQLITE_OK ){ + rc = rc2; + } + } + } + + return rc; +} + + +/* +** This function opens a cursor used to read the input data for an +** incremental merge operation. Specifically, it opens a cursor to scan +** the oldest nSeg segments (idx=0 through idx=(nSeg-1)) in absolute +** level iAbsLevel. +*/ +static int fts3IncrmergeCsr( + Fts3Table *p, /* FTS3 table handle */ + sqlite3_int64 iAbsLevel, /* Absolute level to open */ + int nSeg, /* Number of segments to merge */ + Fts3MultiSegReader *pCsr /* Cursor object to populate */ +){ + int rc; /* Return Code */ + sqlite3_stmt *pStmt = 0; /* Statement used to read %_segdir entry */ + sqlite3_int64 nByte; /* Bytes allocated at pCsr->apSegment[] */ + + /* Allocate space for the Fts3MultiSegReader.aCsr[] array */ + memset(pCsr, 0, sizeof(*pCsr)); + nByte = sizeof(Fts3SegReader *) * nSeg; + pCsr->apSegment = (Fts3SegReader **)sqlite3_malloc64(nByte); + + if( pCsr->apSegment==0 ){ + rc = SQLITE_NOMEM; + }else{ + memset(pCsr->apSegment, 0, nByte); + rc = fts3SqlStmt(p, SQL_SELECT_LEVEL, &pStmt, 0); + } + if( rc==SQLITE_OK ){ + int i; + int rc2; + sqlite3_bind_int64(pStmt, 1, iAbsLevel); + assert( pCsr->nSegment==0 ); + for(i=0; rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW && iapSegment[i] + ); + pCsr->nSegment++; + } + rc2 = sqlite3_reset(pStmt); + if( rc==SQLITE_OK ) rc = rc2; + } + + return rc; +} + +typedef struct IncrmergeWriter IncrmergeWriter; +typedef struct NodeWriter NodeWriter; +typedef struct Blob Blob; +typedef struct NodeReader NodeReader; + +/* +** An instance of the following structure is used as a dynamic buffer +** to build up nodes or other blobs of data in. +** +** The function blobGrowBuffer() is used to extend the allocation. +*/ +struct Blob { + char *a; /* Pointer to allocation */ + int n; /* Number of valid bytes of data in a[] */ + int nAlloc; /* Allocated size of a[] (nAlloc>=n) */ +}; + +/* +** This structure is used to build up buffers containing segment b-tree +** nodes (blocks). +*/ +struct NodeWriter { + sqlite3_int64 iBlock; /* Current block id */ + Blob key; /* Last key written to the current block */ + Blob block; /* Current block image */ +}; + +/* +** An object of this type contains the state required to create or append +** to an appendable b-tree segment. +*/ +struct IncrmergeWriter { + i64 nLeafEst; /* Space allocated for leaf blocks */ + i64 nWork; /* Number of leaf pages flushed */ + sqlite3_int64 iAbsLevel; /* Absolute level of input segments */ + int iIdx; /* Index of *output* segment in iAbsLevel+1 */ + sqlite3_int64 iStart; /* Block number of first allocated block */ + sqlite3_int64 iEnd; /* Block number of last allocated block */ + sqlite3_int64 nLeafData; /* Bytes of leaf page data so far */ + u8 bNoLeafData; /* If true, store 0 for segment size */ + NodeWriter aNodeWriter[FTS_MAX_APPENDABLE_HEIGHT]; +}; + +/* +** An object of the following type is used to read data from a single +** FTS segment node. See the following functions: +** +** nodeReaderInit() +** nodeReaderNext() +** nodeReaderRelease() +*/ +struct NodeReader { + const char *aNode; + int nNode; + int iOff; /* Current offset within aNode[] */ + + /* Output variables. Containing the current node entry. */ + sqlite3_int64 iChild; /* Pointer to child node */ + Blob term; /* Current term */ + const char *aDoclist; /* Pointer to doclist */ + int nDoclist; /* Size of doclist in bytes */ +}; + +/* +** If *pRc is not SQLITE_OK when this function is called, it is a no-op. +** Otherwise, if the allocation at pBlob->a is not already at least nMin +** bytes in size, extend (realloc) it to be so. +** +** If an OOM error occurs, set *pRc to SQLITE_NOMEM and leave pBlob->a +** unmodified. Otherwise, if the allocation succeeds, update pBlob->nAlloc +** to reflect the new size of the pBlob->a[] buffer. +*/ +static void blobGrowBuffer(Blob *pBlob, int nMin, int *pRc){ + if( *pRc==SQLITE_OK && nMin>pBlob->nAlloc ){ + int nAlloc = nMin; + char *a = (char *)sqlite3_realloc64(pBlob->a, nAlloc); + if( a ){ + pBlob->nAlloc = nAlloc; + pBlob->a = a; + }else{ + *pRc = SQLITE_NOMEM; + } + } +} + +/* +** Attempt to advance the node-reader object passed as the first argument to +** the next entry on the node. +** +** Return an error code if an error occurs (SQLITE_NOMEM is possible). +** Otherwise return SQLITE_OK. If there is no next entry on the node +** (e.g. because the current entry is the last) set NodeReader->aNode to +** NULL to indicate EOF. Otherwise, populate the NodeReader structure output +** variables for the new entry. +*/ +static int nodeReaderNext(NodeReader *p){ + int bFirst = (p->term.n==0); /* True for first term on the node */ + int nPrefix = 0; /* Bytes to copy from previous term */ + int nSuffix = 0; /* Bytes to append to the prefix */ + int rc = SQLITE_OK; /* Return code */ + + assert( p->aNode ); + if( p->iChild && bFirst==0 ) p->iChild++; + if( p->iOff>=p->nNode ){ + /* EOF */ + p->aNode = 0; + }else{ + if( bFirst==0 ){ + p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nPrefix); + } + p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix); + + if( nPrefix>p->term.n || nSuffix>p->nNode-p->iOff || nSuffix==0 ){ + return FTS_CORRUPT_VTAB; + } + blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc); + if( rc==SQLITE_OK && ALWAYS(p->term.a!=0) ){ + memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix); + p->term.n = nPrefix+nSuffix; + p->iOff += nSuffix; + if( p->iChild==0 ){ + p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist); + if( (p->nNode-p->iOff)nDoclist ){ + return FTS_CORRUPT_VTAB; + } + p->aDoclist = &p->aNode[p->iOff]; + p->iOff += p->nDoclist; + } + } + } + + assert_fts3_nc( p->iOff<=p->nNode ); + return rc; +} + +/* +** Release all dynamic resources held by node-reader object *p. +*/ +static void nodeReaderRelease(NodeReader *p){ + sqlite3_free(p->term.a); +} + +/* +** Initialize a node-reader object to read the node in buffer aNode/nNode. +** +** If successful, SQLITE_OK is returned and the NodeReader object set to +** point to the first entry on the node (if any). Otherwise, an SQLite +** error code is returned. +*/ +static int nodeReaderInit(NodeReader *p, const char *aNode, int nNode){ + memset(p, 0, sizeof(NodeReader)); + p->aNode = aNode; + p->nNode = nNode; + + /* Figure out if this is a leaf or an internal node. */ + if( aNode && aNode[0] ){ + /* An internal node. */ + p->iOff = 1 + sqlite3Fts3GetVarint(&p->aNode[1], &p->iChild); + }else{ + p->iOff = 1; + } + + return aNode ? nodeReaderNext(p) : SQLITE_OK; +} + +/* +** This function is called while writing an FTS segment each time a leaf o +** node is finished and written to disk. The key (zTerm/nTerm) is guaranteed +** to be greater than the largest key on the node just written, but smaller +** than or equal to the first key that will be written to the next leaf +** node. +** +** The block id of the leaf node just written to disk may be found in +** (pWriter->aNodeWriter[0].iBlock) when this function is called. +*/ +static int fts3IncrmergePush( + Fts3Table *p, /* Fts3 table handle */ + IncrmergeWriter *pWriter, /* Writer object */ + const char *zTerm, /* Term to write to internal node */ + int nTerm /* Bytes at zTerm */ +){ + sqlite3_int64 iPtr = pWriter->aNodeWriter[0].iBlock; + int iLayer; + + assert( nTerm>0 ); + for(iLayer=1; ALWAYS(iLayeraNodeWriter[iLayer]; + int rc = SQLITE_OK; + int nPrefix; + int nSuffix; + int nSpace; + + /* Figure out how much space the key will consume if it is written to + ** the current node of layer iLayer. Due to the prefix compression, + ** the space required changes depending on which node the key is to + ** be added to. */ + nPrefix = fts3PrefixCompress(pNode->key.a, pNode->key.n, zTerm, nTerm); + nSuffix = nTerm - nPrefix; + if(nSuffix<=0 ) return FTS_CORRUPT_VTAB; + nSpace = sqlite3Fts3VarintLen(nPrefix); + nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix; + + if( pNode->key.n==0 || (pNode->block.n + nSpace)<=p->nNodeSize ){ + /* If the current node of layer iLayer contains zero keys, or if adding + ** the key to it will not cause it to grow to larger than nNodeSize + ** bytes in size, write the key here. */ + + Blob *pBlk = &pNode->block; + if( pBlk->n==0 ){ + blobGrowBuffer(pBlk, p->nNodeSize, &rc); + if( rc==SQLITE_OK ){ + pBlk->a[0] = (char)iLayer; + pBlk->n = 1 + sqlite3Fts3PutVarint(&pBlk->a[1], iPtr); + } + } + blobGrowBuffer(pBlk, pBlk->n + nSpace, &rc); + blobGrowBuffer(&pNode->key, nTerm, &rc); + + if( rc==SQLITE_OK ){ + if( pNode->key.n ){ + pBlk->n += sqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nPrefix); + } + pBlk->n += sqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nSuffix); + assert( nPrefix+nSuffix<=nTerm ); + assert( nPrefix>=0 ); + memcpy(&pBlk->a[pBlk->n], &zTerm[nPrefix], nSuffix); + pBlk->n += nSuffix; + + memcpy(pNode->key.a, zTerm, nTerm); + pNode->key.n = nTerm; + } + }else{ + /* Otherwise, flush the current node of layer iLayer to disk. + ** Then allocate a new, empty sibling node. The key will be written + ** into the parent of this node. */ + rc = fts3WriteSegment(p, pNode->iBlock, pNode->block.a, pNode->block.n); + + assert( pNode->block.nAlloc>=p->nNodeSize ); + pNode->block.a[0] = (char)iLayer; + pNode->block.n = 1 + sqlite3Fts3PutVarint(&pNode->block.a[1], iPtr+1); + + iNextPtr = pNode->iBlock; + pNode->iBlock++; + pNode->key.n = 0; + } + + if( rc!=SQLITE_OK || iNextPtr==0 ) return rc; + iPtr = iNextPtr; + } + + assert( 0 ); + return 0; +} + +/* +** Append a term and (optionally) doclist to the FTS segment node currently +** stored in blob *pNode. The node need not contain any terms, but the +** header must be written before this function is called. +** +** A node header is a single 0x00 byte for a leaf node, or a height varint +** followed by the left-hand-child varint for an internal node. +** +** The term to be appended is passed via arguments zTerm/nTerm. For a +** leaf node, the doclist is passed as aDoclist/nDoclist. For an internal +** node, both aDoclist and nDoclist must be passed 0. +** +** If the size of the value in blob pPrev is zero, then this is the first +** term written to the node. Otherwise, pPrev contains a copy of the +** previous term. Before this function returns, it is updated to contain a +** copy of zTerm/nTerm. +** +** It is assumed that the buffer associated with pNode is already large +** enough to accommodate the new entry. The buffer associated with pPrev +** is extended by this function if required. +** +** If an error (i.e. OOM condition) occurs, an SQLite error code is +** returned. Otherwise, SQLITE_OK. +*/ +static int fts3AppendToNode( + Blob *pNode, /* Current node image to append to */ + Blob *pPrev, /* Buffer containing previous term written */ + const char *zTerm, /* New term to write */ + int nTerm, /* Size of zTerm in bytes */ + const char *aDoclist, /* Doclist (or NULL) to write */ + int nDoclist /* Size of aDoclist in bytes */ +){ + int rc = SQLITE_OK; /* Return code */ + int bFirst = (pPrev->n==0); /* True if this is the first term written */ + int nPrefix; /* Size of term prefix in bytes */ + int nSuffix; /* Size of term suffix in bytes */ + + /* Node must have already been started. There must be a doclist for a + ** leaf node, and there must not be a doclist for an internal node. */ + assert( pNode->n>0 ); + assert_fts3_nc( (pNode->a[0]=='\0')==(aDoclist!=0) ); + + blobGrowBuffer(pPrev, nTerm, &rc); + if( rc!=SQLITE_OK ) return rc; + assert( pPrev!=0 ); + assert( pPrev->a!=0 ); + + nPrefix = fts3PrefixCompress(pPrev->a, pPrev->n, zTerm, nTerm); + nSuffix = nTerm - nPrefix; + if( nSuffix<=0 ) return FTS_CORRUPT_VTAB; + memcpy(pPrev->a, zTerm, nTerm); + pPrev->n = nTerm; + + if( bFirst==0 ){ + pNode->n += sqlite3Fts3PutVarint(&pNode->a[pNode->n], nPrefix); + } + pNode->n += sqlite3Fts3PutVarint(&pNode->a[pNode->n], nSuffix); + memcpy(&pNode->a[pNode->n], &zTerm[nPrefix], nSuffix); + pNode->n += nSuffix; + + if( aDoclist ){ + pNode->n += sqlite3Fts3PutVarint(&pNode->a[pNode->n], nDoclist); + memcpy(&pNode->a[pNode->n], aDoclist, nDoclist); + pNode->n += nDoclist; + } + + assert( pNode->n<=pNode->nAlloc ); + + return SQLITE_OK; +} + +/* +** Append the current term and doclist pointed to by cursor pCsr to the +** appendable b-tree segment opened for writing by pWriter. +** +** Return SQLITE_OK if successful, or an SQLite error code otherwise. +*/ +static int fts3IncrmergeAppend( + Fts3Table *p, /* Fts3 table handle */ + IncrmergeWriter *pWriter, /* Writer object */ + Fts3MultiSegReader *pCsr /* Cursor containing term and doclist */ +){ + const char *zTerm = pCsr->zTerm; + int nTerm = pCsr->nTerm; + const char *aDoclist = pCsr->aDoclist; + int nDoclist = pCsr->nDoclist; + int rc = SQLITE_OK; /* Return code */ + int nSpace; /* Total space in bytes required on leaf */ + int nPrefix; /* Size of prefix shared with previous term */ + int nSuffix; /* Size of suffix (nTerm - nPrefix) */ + NodeWriter *pLeaf; /* Object used to write leaf nodes */ + + pLeaf = &pWriter->aNodeWriter[0]; + nPrefix = fts3PrefixCompress(pLeaf->key.a, pLeaf->key.n, zTerm, nTerm); + nSuffix = nTerm - nPrefix; + if(nSuffix<=0 ) return FTS_CORRUPT_VTAB; + + nSpace = sqlite3Fts3VarintLen(nPrefix); + nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix; + nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist; + + /* If the current block is not empty, and if adding this term/doclist + ** to the current block would make it larger than Fts3Table.nNodeSize bytes, + ** and if there is still room for another leaf page, write this block out to + ** the database. */ + if( pLeaf->block.n>0 + && (pLeaf->block.n + nSpace)>p->nNodeSize + && pLeaf->iBlock < (pWriter->iStart + pWriter->nLeafEst) + ){ + rc = fts3WriteSegment(p, pLeaf->iBlock, pLeaf->block.a, pLeaf->block.n); + pWriter->nWork++; + + /* Add the current term to the parent node. The term added to the + ** parent must: + ** + ** a) be greater than the largest term on the leaf node just written + ** to the database (still available in pLeaf->key), and + ** + ** b) be less than or equal to the term about to be added to the new + ** leaf node (zTerm/nTerm). + ** + ** In other words, it must be the prefix of zTerm 1 byte longer than + ** the common prefix (if any) of zTerm and pWriter->zTerm. + */ + if( rc==SQLITE_OK ){ + rc = fts3IncrmergePush(p, pWriter, zTerm, nPrefix+1); + } + + /* Advance to the next output block */ + pLeaf->iBlock++; + pLeaf->key.n = 0; + pLeaf->block.n = 0; + + nSuffix = nTerm; + nSpace = 1; + nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix; + nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist; + } + + pWriter->nLeafData += nSpace; + blobGrowBuffer(&pLeaf->block, pLeaf->block.n + nSpace, &rc); + if( rc==SQLITE_OK ){ + if( pLeaf->block.n==0 ){ + pLeaf->block.n = 1; + pLeaf->block.a[0] = '\0'; + } + rc = fts3AppendToNode( + &pLeaf->block, &pLeaf->key, zTerm, nTerm, aDoclist, nDoclist + ); + } + + return rc; +} + +/* +** This function is called to release all dynamic resources held by the +** merge-writer object pWriter, and if no error has occurred, to flush +** all outstanding node buffers held by pWriter to disk. +** +** If *pRc is not SQLITE_OK when this function is called, then no attempt +** is made to write any data to disk. Instead, this function serves only +** to release outstanding resources. +** +** Otherwise, if *pRc is initially SQLITE_OK and an error occurs while +** flushing buffers to disk, *pRc is set to an SQLite error code before +** returning. +*/ +static void fts3IncrmergeRelease( + Fts3Table *p, /* FTS3 table handle */ + IncrmergeWriter *pWriter, /* Merge-writer object */ + int *pRc /* IN/OUT: Error code */ +){ + int i; /* Used to iterate through non-root layers */ + int iRoot; /* Index of root in pWriter->aNodeWriter */ + NodeWriter *pRoot; /* NodeWriter for root node */ + int rc = *pRc; /* Error code */ + + /* Set iRoot to the index in pWriter->aNodeWriter[] of the output segment + ** root node. If the segment fits entirely on a single leaf node, iRoot + ** will be set to 0. If the root node is the parent of the leaves, iRoot + ** will be 1. And so on. */ + for(iRoot=FTS_MAX_APPENDABLE_HEIGHT-1; iRoot>=0; iRoot--){ + NodeWriter *pNode = &pWriter->aNodeWriter[iRoot]; + if( pNode->block.n>0 ) break; + assert( *pRc || pNode->block.nAlloc==0 ); + assert( *pRc || pNode->key.nAlloc==0 ); + sqlite3_free(pNode->block.a); + sqlite3_free(pNode->key.a); + } + + /* Empty output segment. This is a no-op. */ + if( iRoot<0 ) return; + + /* The entire output segment fits on a single node. Normally, this means + ** the node would be stored as a blob in the "root" column of the %_segdir + ** table. However, this is not permitted in this case. The problem is that + ** space has already been reserved in the %_segments table, and so the + ** start_block and end_block fields of the %_segdir table must be populated. + ** And, by design or by accident, released versions of FTS cannot handle + ** segments that fit entirely on the root node with start_block!=0. + ** + ** Instead, create a synthetic root node that contains nothing but a + ** pointer to the single content node. So that the segment consists of a + ** single leaf and a single interior (root) node. + ** + ** Todo: Better might be to defer allocating space in the %_segments + ** table until we are sure it is needed. + */ + if( iRoot==0 ){ + Blob *pBlock = &pWriter->aNodeWriter[1].block; + blobGrowBuffer(pBlock, 1 + FTS3_VARINT_MAX, &rc); + if( rc==SQLITE_OK ){ + pBlock->a[0] = 0x01; + pBlock->n = 1 + sqlite3Fts3PutVarint( + &pBlock->a[1], pWriter->aNodeWriter[0].iBlock + ); + } + iRoot = 1; + } + pRoot = &pWriter->aNodeWriter[iRoot]; + + /* Flush all currently outstanding nodes to disk. */ + for(i=0; iaNodeWriter[i]; + if( pNode->block.n>0 && rc==SQLITE_OK ){ + rc = fts3WriteSegment(p, pNode->iBlock, pNode->block.a, pNode->block.n); + } + sqlite3_free(pNode->block.a); + sqlite3_free(pNode->key.a); + } + + /* Write the %_segdir record. */ + if( rc==SQLITE_OK ){ + rc = fts3WriteSegdir(p, + pWriter->iAbsLevel+1, /* level */ + pWriter->iIdx, /* idx */ + pWriter->iStart, /* start_block */ + pWriter->aNodeWriter[0].iBlock, /* leaves_end_block */ + pWriter->iEnd, /* end_block */ + (pWriter->bNoLeafData==0 ? pWriter->nLeafData : 0), /* end_block */ + pRoot->block.a, pRoot->block.n /* root */ + ); + } + sqlite3_free(pRoot->block.a); + sqlite3_free(pRoot->key.a); + + *pRc = rc; +} + +/* +** Compare the term in buffer zLhs (size in bytes nLhs) with that in +** zRhs (size in bytes nRhs) using memcmp. If one term is a prefix of +** the other, it is considered to be smaller than the other. +** +** Return -ve if zLhs is smaller than zRhs, 0 if it is equal, or +ve +** if it is greater. +*/ +static int fts3TermCmp( + const char *zLhs, int nLhs, /* LHS of comparison */ + const char *zRhs, int nRhs /* RHS of comparison */ +){ + int nCmp = MIN(nLhs, nRhs); + int res; + + if( nCmp && ALWAYS(zLhs) && ALWAYS(zRhs) ){ + res = memcmp(zLhs, zRhs, nCmp); + }else{ + res = 0; + } + if( res==0 ) res = nLhs - nRhs; + + return res; +} + + +/* +** Query to see if the entry in the %_segments table with blockid iEnd is +** NULL. If no error occurs and the entry is NULL, set *pbRes 1 before +** returning. Otherwise, set *pbRes to 0. +** +** Or, if an error occurs while querying the database, return an SQLite +** error code. The final value of *pbRes is undefined in this case. +** +** This is used to test if a segment is an "appendable" segment. If it +** is, then a NULL entry has been inserted into the %_segments table +** with blockid %_segdir.end_block. +*/ +static int fts3IsAppendable(Fts3Table *p, sqlite3_int64 iEnd, int *pbRes){ + int bRes = 0; /* Result to set *pbRes to */ + sqlite3_stmt *pCheck = 0; /* Statement to query database with */ + int rc; /* Return code */ + + rc = fts3SqlStmt(p, SQL_SEGMENT_IS_APPENDABLE, &pCheck, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pCheck, 1, iEnd); + if( SQLITE_ROW==sqlite3_step(pCheck) ) bRes = 1; + rc = sqlite3_reset(pCheck); + } + + *pbRes = bRes; + return rc; +} + +/* +** This function is called when initializing an incremental-merge operation. +** It checks if the existing segment with index value iIdx at absolute level +** (iAbsLevel+1) can be appended to by the incremental merge. If it can, the +** merge-writer object *pWriter is initialized to write to it. +** +** An existing segment can be appended to by an incremental merge if: +** +** * It was initially created as an appendable segment (with all required +** space pre-allocated), and +** +** * The first key read from the input (arguments zKey and nKey) is +** greater than the largest key currently stored in the potential +** output segment. +*/ +static int fts3IncrmergeLoad( + Fts3Table *p, /* Fts3 table handle */ + sqlite3_int64 iAbsLevel, /* Absolute level of input segments */ + int iIdx, /* Index of candidate output segment */ + const char *zKey, /* First key to write */ + int nKey, /* Number of bytes in nKey */ + IncrmergeWriter *pWriter /* Populate this object */ +){ + int rc; /* Return code */ + sqlite3_stmt *pSelect = 0; /* SELECT to read %_segdir entry */ + + rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR, &pSelect, 0); + if( rc==SQLITE_OK ){ + sqlite3_int64 iStart = 0; /* Value of %_segdir.start_block */ + sqlite3_int64 iLeafEnd = 0; /* Value of %_segdir.leaves_end_block */ + sqlite3_int64 iEnd = 0; /* Value of %_segdir.end_block */ + const char *aRoot = 0; /* Pointer to %_segdir.root buffer */ + int nRoot = 0; /* Size of aRoot[] in bytes */ + int rc2; /* Return code from sqlite3_reset() */ + int bAppendable = 0; /* Set to true if segment is appendable */ + + /* Read the %_segdir entry for index iIdx absolute level (iAbsLevel+1) */ + sqlite3_bind_int64(pSelect, 1, iAbsLevel+1); + sqlite3_bind_int(pSelect, 2, iIdx); + if( sqlite3_step(pSelect)==SQLITE_ROW ){ + iStart = sqlite3_column_int64(pSelect, 1); + iLeafEnd = sqlite3_column_int64(pSelect, 2); + fts3ReadEndBlockField(pSelect, 3, &iEnd, &pWriter->nLeafData); + if( pWriter->nLeafData<0 ){ + pWriter->nLeafData = pWriter->nLeafData * -1; + } + pWriter->bNoLeafData = (pWriter->nLeafData==0); + nRoot = sqlite3_column_bytes(pSelect, 4); + aRoot = sqlite3_column_blob(pSelect, 4); + if( aRoot==0 ){ + sqlite3_reset(pSelect); + return nRoot ? SQLITE_NOMEM : FTS_CORRUPT_VTAB; + } + }else{ + return sqlite3_reset(pSelect); + } + + /* Check for the zero-length marker in the %_segments table */ + rc = fts3IsAppendable(p, iEnd, &bAppendable); + + /* Check that zKey/nKey is larger than the largest key the candidate */ + if( rc==SQLITE_OK && bAppendable ){ + char *aLeaf = 0; + int nLeaf = 0; + + rc = sqlite3Fts3ReadBlock(p, iLeafEnd, &aLeaf, &nLeaf, 0); + if( rc==SQLITE_OK ){ + NodeReader reader; + for(rc = nodeReaderInit(&reader, aLeaf, nLeaf); + rc==SQLITE_OK && reader.aNode; + rc = nodeReaderNext(&reader) + ){ + assert( reader.aNode ); + } + if( fts3TermCmp(zKey, nKey, reader.term.a, reader.term.n)<=0 ){ + bAppendable = 0; + } + nodeReaderRelease(&reader); + } + sqlite3_free(aLeaf); + } + + if( rc==SQLITE_OK && bAppendable ){ + /* It is possible to append to this segment. Set up the IncrmergeWriter + ** object to do so. */ + int i; + int nHeight = (int)aRoot[0]; + NodeWriter *pNode; + if( nHeight<1 || nHeight>=FTS_MAX_APPENDABLE_HEIGHT ){ + sqlite3_reset(pSelect); + return FTS_CORRUPT_VTAB; + } + + pWriter->nLeafEst = (int)(((iEnd - iStart)+1)/FTS_MAX_APPENDABLE_HEIGHT); + pWriter->iStart = iStart; + pWriter->iEnd = iEnd; + pWriter->iAbsLevel = iAbsLevel; + pWriter->iIdx = iIdx; + + for(i=nHeight+1; iaNodeWriter[i].iBlock = pWriter->iStart + i*pWriter->nLeafEst; + } + + pNode = &pWriter->aNodeWriter[nHeight]; + pNode->iBlock = pWriter->iStart + pWriter->nLeafEst*nHeight; + blobGrowBuffer(&pNode->block, + MAX(nRoot, p->nNodeSize)+FTS3_NODE_PADDING, &rc + ); + if( rc==SQLITE_OK ){ + memcpy(pNode->block.a, aRoot, nRoot); + pNode->block.n = nRoot; + memset(&pNode->block.a[nRoot], 0, FTS3_NODE_PADDING); + } + + for(i=nHeight; i>=0 && rc==SQLITE_OK; i--){ + NodeReader reader; + memset(&reader, 0, sizeof(reader)); + pNode = &pWriter->aNodeWriter[i]; + + if( pNode->block.a){ + rc = nodeReaderInit(&reader, pNode->block.a, pNode->block.n); + while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader); + blobGrowBuffer(&pNode->key, reader.term.n, &rc); + if( rc==SQLITE_OK ){ + assert_fts3_nc( reader.term.n>0 || reader.aNode==0 ); + if( reader.term.n>0 ){ + memcpy(pNode->key.a, reader.term.a, reader.term.n); + } + pNode->key.n = reader.term.n; + if( i>0 ){ + char *aBlock = 0; + int nBlock = 0; + pNode = &pWriter->aNodeWriter[i-1]; + pNode->iBlock = reader.iChild; + rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock,0); + blobGrowBuffer(&pNode->block, + MAX(nBlock, p->nNodeSize)+FTS3_NODE_PADDING, &rc + ); + if( rc==SQLITE_OK ){ + memcpy(pNode->block.a, aBlock, nBlock); + pNode->block.n = nBlock; + memset(&pNode->block.a[nBlock], 0, FTS3_NODE_PADDING); + } + sqlite3_free(aBlock); + } + } + } + nodeReaderRelease(&reader); + } + } + + rc2 = sqlite3_reset(pSelect); + if( rc==SQLITE_OK ) rc = rc2; + } + + return rc; +} + +/* +** Determine the largest segment index value that exists within absolute +** level iAbsLevel+1. If no error occurs, set *piIdx to this value plus +** one before returning SQLITE_OK. Or, if there are no segments at all +** within level iAbsLevel, set *piIdx to zero. +** +** If an error occurs, return an SQLite error code. The final value of +** *piIdx is undefined in this case. +*/ +static int fts3IncrmergeOutputIdx( + Fts3Table *p, /* FTS Table handle */ + sqlite3_int64 iAbsLevel, /* Absolute index of input segments */ + int *piIdx /* OUT: Next free index at iAbsLevel+1 */ +){ + int rc; + sqlite3_stmt *pOutputIdx = 0; /* SQL used to find output index */ + + rc = fts3SqlStmt(p, SQL_NEXT_SEGMENT_INDEX, &pOutputIdx, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pOutputIdx, 1, iAbsLevel+1); + sqlite3_step(pOutputIdx); + *piIdx = sqlite3_column_int(pOutputIdx, 0); + rc = sqlite3_reset(pOutputIdx); + } + + return rc; +} + +/* +** Allocate an appendable output segment on absolute level iAbsLevel+1 +** with idx value iIdx. +** +** In the %_segdir table, a segment is defined by the values in three +** columns: +** +** start_block +** leaves_end_block +** end_block +** +** When an appendable segment is allocated, it is estimated that the +** maximum number of leaf blocks that may be required is the sum of the +** number of leaf blocks consumed by the input segments, plus the number +** of input segments, multiplied by two. This value is stored in stack +** variable nLeafEst. +** +** A total of 16*nLeafEst blocks are allocated when an appendable segment +** is created ((1 + end_block - start_block)==16*nLeafEst). The contiguous +** array of leaf nodes starts at the first block allocated. The array +** of interior nodes that are parents of the leaf nodes start at block +** (start_block + (1 + end_block - start_block) / 16). And so on. +** +** In the actual code below, the value "16" is replaced with the +** pre-processor macro FTS_MAX_APPENDABLE_HEIGHT. +*/ +static int fts3IncrmergeWriter( + Fts3Table *p, /* Fts3 table handle */ + sqlite3_int64 iAbsLevel, /* Absolute level of input segments */ + int iIdx, /* Index of new output segment */ + Fts3MultiSegReader *pCsr, /* Cursor that data will be read from */ + IncrmergeWriter *pWriter /* Populate this object */ +){ + int rc; /* Return Code */ + int i; /* Iterator variable */ + i64 nLeafEst = 0; /* Blocks allocated for leaf nodes */ + sqlite3_stmt *pLeafEst = 0; /* SQL used to determine nLeafEst */ + sqlite3_stmt *pFirstBlock = 0; /* SQL used to determine first block */ + + /* Calculate nLeafEst. */ + rc = fts3SqlStmt(p, SQL_MAX_LEAF_NODE_ESTIMATE, &pLeafEst, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pLeafEst, 1, iAbsLevel); + sqlite3_bind_int64(pLeafEst, 2, pCsr->nSegment); + if( SQLITE_ROW==sqlite3_step(pLeafEst) ){ + nLeafEst = sqlite3_column_int64(pLeafEst, 0); + } + rc = sqlite3_reset(pLeafEst); + } + if( rc!=SQLITE_OK ) return rc; + + /* Calculate the first block to use in the output segment */ + rc = fts3SqlStmt(p, SQL_NEXT_SEGMENTS_ID, &pFirstBlock, 0); + if( rc==SQLITE_OK ){ + if( SQLITE_ROW==sqlite3_step(pFirstBlock) ){ + pWriter->iStart = sqlite3_column_int64(pFirstBlock, 0); + pWriter->iEnd = pWriter->iStart - 1; + pWriter->iEnd += nLeafEst * FTS_MAX_APPENDABLE_HEIGHT; + } + rc = sqlite3_reset(pFirstBlock); + } + if( rc!=SQLITE_OK ) return rc; + + /* Insert the marker in the %_segments table to make sure nobody tries + ** to steal the space just allocated. This is also used to identify + ** appendable segments. */ + rc = fts3WriteSegment(p, pWriter->iEnd, 0, 0); + if( rc!=SQLITE_OK ) return rc; + + pWriter->iAbsLevel = iAbsLevel; + pWriter->nLeafEst = nLeafEst; + pWriter->iIdx = iIdx; + + /* Set up the array of NodeWriter objects */ + for(i=0; iaNodeWriter[i].iBlock = pWriter->iStart + i*pWriter->nLeafEst; + } + return SQLITE_OK; +} + +/* +** Remove an entry from the %_segdir table. This involves running the +** following two statements: +** +** DELETE FROM %_segdir WHERE level = :iAbsLevel AND idx = :iIdx +** UPDATE %_segdir SET idx = idx - 1 WHERE level = :iAbsLevel AND idx > :iIdx +** +** The DELETE statement removes the specific %_segdir level. The UPDATE +** statement ensures that the remaining segments have contiguously allocated +** idx values. +*/ +static int fts3RemoveSegdirEntry( + Fts3Table *p, /* FTS3 table handle */ + sqlite3_int64 iAbsLevel, /* Absolute level to delete from */ + int iIdx /* Index of %_segdir entry to delete */ +){ + int rc; /* Return code */ + sqlite3_stmt *pDelete = 0; /* DELETE statement */ + + rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_ENTRY, &pDelete, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pDelete, 1, iAbsLevel); + sqlite3_bind_int(pDelete, 2, iIdx); + sqlite3_step(pDelete); + rc = sqlite3_reset(pDelete); + } + + return rc; +} + +/* +** One or more segments have just been removed from absolute level iAbsLevel. +** Update the 'idx' values of the remaining segments in the level so that +** the idx values are a contiguous sequence starting from 0. +*/ +static int fts3RepackSegdirLevel( + Fts3Table *p, /* FTS3 table handle */ + sqlite3_int64 iAbsLevel /* Absolute level to repack */ +){ + int rc; /* Return code */ + int *aIdx = 0; /* Array of remaining idx values */ + int nIdx = 0; /* Valid entries in aIdx[] */ + int nAlloc = 0; /* Allocated size of aIdx[] */ + int i; /* Iterator variable */ + sqlite3_stmt *pSelect = 0; /* Select statement to read idx values */ + sqlite3_stmt *pUpdate = 0; /* Update statement to modify idx values */ + + rc = fts3SqlStmt(p, SQL_SELECT_INDEXES, &pSelect, 0); + if( rc==SQLITE_OK ){ + int rc2; + sqlite3_bind_int64(pSelect, 1, iAbsLevel); + while( SQLITE_ROW==sqlite3_step(pSelect) ){ + if( nIdx>=nAlloc ){ + int *aNew; + nAlloc += 16; + aNew = sqlite3_realloc64(aIdx, nAlloc*sizeof(int)); + if( !aNew ){ + rc = SQLITE_NOMEM; + break; + } + aIdx = aNew; + } + aIdx[nIdx++] = sqlite3_column_int(pSelect, 0); + } + rc2 = sqlite3_reset(pSelect); + if( rc==SQLITE_OK ) rc = rc2; + } + + if( rc==SQLITE_OK ){ + rc = fts3SqlStmt(p, SQL_SHIFT_SEGDIR_ENTRY, &pUpdate, 0); + } + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pUpdate, 2, iAbsLevel); + } + + assert( p->bIgnoreSavepoint==0 ); + p->bIgnoreSavepoint = 1; + for(i=0; rc==SQLITE_OK && ibIgnoreSavepoint = 0; + + sqlite3_free(aIdx); + return rc; +} + +static void fts3StartNode(Blob *pNode, int iHeight, sqlite3_int64 iChild){ + pNode->a[0] = (char)iHeight; + if( iChild ){ + assert( pNode->nAlloc>=1+sqlite3Fts3VarintLen(iChild) ); + pNode->n = 1 + sqlite3Fts3PutVarint(&pNode->a[1], iChild); + }else{ + assert( pNode->nAlloc>=1 ); + pNode->n = 1; + } +} + +/* +** The first two arguments are a pointer to and the size of a segment b-tree +** node. The node may be a leaf or an internal node. +** +** This function creates a new node image in blob object *pNew by copying +** all terms that are greater than or equal to zTerm/nTerm (for leaf nodes) +** or greater than zTerm/nTerm (for internal nodes) from aNode/nNode. +*/ +static int fts3TruncateNode( + const char *aNode, /* Current node image */ + int nNode, /* Size of aNode in bytes */ + Blob *pNew, /* OUT: Write new node image here */ + const char *zTerm, /* Omit all terms smaller than this */ + int nTerm, /* Size of zTerm in bytes */ + sqlite3_int64 *piBlock /* OUT: Block number in next layer down */ +){ + NodeReader reader; /* Reader object */ + Blob prev = {0, 0, 0}; /* Previous term written to new node */ + int rc = SQLITE_OK; /* Return code */ + int bLeaf; /* True for a leaf node */ + + if( nNode<1 ) return FTS_CORRUPT_VTAB; + bLeaf = aNode[0]=='\0'; + + /* Allocate required output space */ + blobGrowBuffer(pNew, nNode, &rc); + if( rc!=SQLITE_OK ) return rc; + pNew->n = 0; + + /* Populate new node buffer */ + for(rc = nodeReaderInit(&reader, aNode, nNode); + rc==SQLITE_OK && reader.aNode; + rc = nodeReaderNext(&reader) + ){ + if( pNew->n==0 ){ + int res = fts3TermCmp(reader.term.a, reader.term.n, zTerm, nTerm); + if( res<0 || (bLeaf==0 && res==0) ) continue; + fts3StartNode(pNew, (int)aNode[0], reader.iChild); + *piBlock = reader.iChild; + } + rc = fts3AppendToNode( + pNew, &prev, reader.term.a, reader.term.n, + reader.aDoclist, reader.nDoclist + ); + if( rc!=SQLITE_OK ) break; + } + if( pNew->n==0 ){ + fts3StartNode(pNew, (int)aNode[0], reader.iChild); + *piBlock = reader.iChild; + } + assert( pNew->n<=pNew->nAlloc ); + + nodeReaderRelease(&reader); + sqlite3_free(prev.a); + return rc; +} + +/* +** Remove all terms smaller than zTerm/nTerm from segment iIdx in absolute +** level iAbsLevel. This may involve deleting entries from the %_segments +** table, and modifying existing entries in both the %_segments and %_segdir +** tables. +** +** SQLITE_OK is returned if the segment is updated successfully. Or an +** SQLite error code otherwise. +*/ +static int fts3TruncateSegment( + Fts3Table *p, /* FTS3 table handle */ + sqlite3_int64 iAbsLevel, /* Absolute level of segment to modify */ + int iIdx, /* Index within level of segment to modify */ + const char *zTerm, /* Remove terms smaller than this */ + int nTerm /* Number of bytes in buffer zTerm */ +){ + int rc = SQLITE_OK; /* Return code */ + Blob root = {0,0,0}; /* New root page image */ + Blob block = {0,0,0}; /* Buffer used for any other block */ + sqlite3_int64 iBlock = 0; /* Block id */ + sqlite3_int64 iNewStart = 0; /* New value for iStartBlock */ + sqlite3_int64 iOldStart = 0; /* Old value for iStartBlock */ + sqlite3_stmt *pFetch = 0; /* Statement used to fetch segdir */ + + rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR, &pFetch, 0); + if( rc==SQLITE_OK ){ + int rc2; /* sqlite3_reset() return code */ + sqlite3_bind_int64(pFetch, 1, iAbsLevel); + sqlite3_bind_int(pFetch, 2, iIdx); + if( SQLITE_ROW==sqlite3_step(pFetch) ){ + const char *aRoot = sqlite3_column_blob(pFetch, 4); + int nRoot = sqlite3_column_bytes(pFetch, 4); + iOldStart = sqlite3_column_int64(pFetch, 1); + rc = fts3TruncateNode(aRoot, nRoot, &root, zTerm, nTerm, &iBlock); + } + rc2 = sqlite3_reset(pFetch); + if( rc==SQLITE_OK ) rc = rc2; + } + + while( rc==SQLITE_OK && iBlock ){ + char *aBlock = 0; + int nBlock = 0; + iNewStart = iBlock; + + rc = sqlite3Fts3ReadBlock(p, iBlock, &aBlock, &nBlock, 0); + if( rc==SQLITE_OK ){ + rc = fts3TruncateNode(aBlock, nBlock, &block, zTerm, nTerm, &iBlock); + } + if( rc==SQLITE_OK ){ + rc = fts3WriteSegment(p, iNewStart, block.a, block.n); + } + sqlite3_free(aBlock); + } + + /* Variable iNewStart now contains the first valid leaf node. */ + if( rc==SQLITE_OK && iNewStart ){ + sqlite3_stmt *pDel = 0; + rc = fts3SqlStmt(p, SQL_DELETE_SEGMENTS_RANGE, &pDel, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pDel, 1, iOldStart); + sqlite3_bind_int64(pDel, 2, iNewStart-1); + sqlite3_step(pDel); + rc = sqlite3_reset(pDel); + } + } + + if( rc==SQLITE_OK ){ + sqlite3_stmt *pChomp = 0; + rc = fts3SqlStmt(p, SQL_CHOMP_SEGDIR, &pChomp, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pChomp, 1, iNewStart); + sqlite3_bind_blob(pChomp, 2, root.a, root.n, SQLITE_STATIC); + sqlite3_bind_int64(pChomp, 3, iAbsLevel); + sqlite3_bind_int(pChomp, 4, iIdx); + sqlite3_step(pChomp); + rc = sqlite3_reset(pChomp); + sqlite3_bind_null(pChomp, 2); + } + } + + sqlite3_free(root.a); + sqlite3_free(block.a); + return rc; +} + +/* +** This function is called after an incrmental-merge operation has run to +** merge (or partially merge) two or more segments from absolute level +** iAbsLevel. +** +** Each input segment is either removed from the db completely (if all of +** its data was copied to the output segment by the incrmerge operation) +** or modified in place so that it no longer contains those entries that +** have been duplicated in the output segment. +*/ +static int fts3IncrmergeChomp( + Fts3Table *p, /* FTS table handle */ + sqlite3_int64 iAbsLevel, /* Absolute level containing segments */ + Fts3MultiSegReader *pCsr, /* Chomp all segments opened by this cursor */ + int *pnRem /* Number of segments not deleted */ +){ + int i; + int nRem = 0; + int rc = SQLITE_OK; + + for(i=pCsr->nSegment-1; i>=0 && rc==SQLITE_OK; i--){ + Fts3SegReader *pSeg = 0; + int j; + + /* Find the Fts3SegReader object with Fts3SegReader.iIdx==i. It is hiding + ** somewhere in the pCsr->apSegment[] array. */ + for(j=0; ALWAYS(jnSegment); j++){ + pSeg = pCsr->apSegment[j]; + if( pSeg->iIdx==i ) break; + } + assert( jnSegment && pSeg->iIdx==i ); + + if( pSeg->aNode==0 ){ + /* Seg-reader is at EOF. Remove the entire input segment. */ + rc = fts3DeleteSegment(p, pSeg); + if( rc==SQLITE_OK ){ + rc = fts3RemoveSegdirEntry(p, iAbsLevel, pSeg->iIdx); + } + *pnRem = 0; + }else{ + /* The incremental merge did not copy all the data from this + ** segment to the upper level. The segment is modified in place + ** so that it contains no keys smaller than zTerm/nTerm. */ + const char *zTerm = pSeg->zTerm; + int nTerm = pSeg->nTerm; + rc = fts3TruncateSegment(p, iAbsLevel, pSeg->iIdx, zTerm, nTerm); + nRem++; + } + } + + if( rc==SQLITE_OK && nRem!=pCsr->nSegment ){ + rc = fts3RepackSegdirLevel(p, iAbsLevel); + } + + *pnRem = nRem; + return rc; +} + +/* +** Store an incr-merge hint in the database. +*/ +static int fts3IncrmergeHintStore(Fts3Table *p, Blob *pHint){ + sqlite3_stmt *pReplace = 0; + int rc; /* Return code */ + + rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pReplace, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int(pReplace, 1, FTS_STAT_INCRMERGEHINT); + sqlite3_bind_blob(pReplace, 2, pHint->a, pHint->n, SQLITE_STATIC); + sqlite3_step(pReplace); + rc = sqlite3_reset(pReplace); + sqlite3_bind_null(pReplace, 2); + } + + return rc; +} + +/* +** Load an incr-merge hint from the database. The incr-merge hint, if one +** exists, is stored in the rowid==1 row of the %_stat table. +** +** If successful, populate blob *pHint with the value read from the %_stat +** table and return SQLITE_OK. Otherwise, if an error occurs, return an +** SQLite error code. +*/ +static int fts3IncrmergeHintLoad(Fts3Table *p, Blob *pHint){ + sqlite3_stmt *pSelect = 0; + int rc; + + pHint->n = 0; + rc = fts3SqlStmt(p, SQL_SELECT_STAT, &pSelect, 0); + if( rc==SQLITE_OK ){ + int rc2; + sqlite3_bind_int(pSelect, 1, FTS_STAT_INCRMERGEHINT); + if( SQLITE_ROW==sqlite3_step(pSelect) ){ + const char *aHint = sqlite3_column_blob(pSelect, 0); + int nHint = sqlite3_column_bytes(pSelect, 0); + if( aHint ){ + blobGrowBuffer(pHint, nHint, &rc); + if( rc==SQLITE_OK ){ + if( ALWAYS(pHint->a!=0) ) memcpy(pHint->a, aHint, nHint); + pHint->n = nHint; + } + } + } + rc2 = sqlite3_reset(pSelect); + if( rc==SQLITE_OK ) rc = rc2; + } + + return rc; +} + +/* +** If *pRc is not SQLITE_OK when this function is called, it is a no-op. +** Otherwise, append an entry to the hint stored in blob *pHint. Each entry +** consists of two varints, the absolute level number of the input segments +** and the number of input segments. +** +** If successful, leave *pRc set to SQLITE_OK and return. If an error occurs, +** set *pRc to an SQLite error code before returning. +*/ +static void fts3IncrmergeHintPush( + Blob *pHint, /* Hint blob to append to */ + i64 iAbsLevel, /* First varint to store in hint */ + int nInput, /* Second varint to store in hint */ + int *pRc /* IN/OUT: Error code */ +){ + blobGrowBuffer(pHint, pHint->n + 2*FTS3_VARINT_MAX, pRc); + if( *pRc==SQLITE_OK ){ + pHint->n += sqlite3Fts3PutVarint(&pHint->a[pHint->n], iAbsLevel); + pHint->n += sqlite3Fts3PutVarint(&pHint->a[pHint->n], (i64)nInput); + } +} + +/* +** Read the last entry (most recently pushed) from the hint blob *pHint +** and then remove the entry. Write the two values read to *piAbsLevel and +** *pnInput before returning. +** +** If no error occurs, return SQLITE_OK. If the hint blob in *pHint does +** not contain at least two valid varints, return SQLITE_CORRUPT_VTAB. +*/ +static int fts3IncrmergeHintPop(Blob *pHint, i64 *piAbsLevel, int *pnInput){ + const int nHint = pHint->n; + int i; + + i = pHint->n-1; + if( (pHint->a[i] & 0x80) ) return FTS_CORRUPT_VTAB; + while( i>0 && (pHint->a[i-1] & 0x80) ) i--; + if( i==0 ) return FTS_CORRUPT_VTAB; + i--; + while( i>0 && (pHint->a[i-1] & 0x80) ) i--; + + pHint->n = i; + i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel); + i += fts3GetVarint32(&pHint->a[i], pnInput); + assert( i<=nHint ); + if( i!=nHint ) return FTS_CORRUPT_VTAB; + + return SQLITE_OK; +} + + +/* +** Attempt an incremental merge that writes nMerge leaf blocks. +** +** Incremental merges happen nMin segments at a time. The segments +** to be merged are the nMin oldest segments (the ones with the smallest +** values for the _segdir.idx field) in the highest level that contains +** at least nMin segments. Multiple merges might occur in an attempt to +** write the quota of nMerge leaf blocks. +*/ +SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ + int rc; /* Return code */ + int nRem = nMerge; /* Number of leaf pages yet to be written */ + Fts3MultiSegReader *pCsr; /* Cursor used to read input data */ + Fts3SegFilter *pFilter; /* Filter used with cursor pCsr */ + IncrmergeWriter *pWriter; /* Writer object */ + int nSeg = 0; /* Number of input segments */ + sqlite3_int64 iAbsLevel = 0; /* Absolute level number to work on */ + Blob hint = {0, 0, 0}; /* Hint read from %_stat table */ + int bDirtyHint = 0; /* True if blob 'hint' has been modified */ + + /* Allocate space for the cursor, filter and writer objects */ + const int nAlloc = sizeof(*pCsr) + sizeof(*pFilter) + sizeof(*pWriter); + pWriter = (IncrmergeWriter *)sqlite3_malloc64(nAlloc); + if( !pWriter ) return SQLITE_NOMEM; + pFilter = (Fts3SegFilter *)&pWriter[1]; + pCsr = (Fts3MultiSegReader *)&pFilter[1]; + + rc = fts3IncrmergeHintLoad(p, &hint); + while( rc==SQLITE_OK && nRem>0 ){ + const i64 nMod = FTS3_SEGDIR_MAXLEVEL * p->nIndex; + sqlite3_stmt *pFindLevel = 0; /* SQL used to determine iAbsLevel */ + int bUseHint = 0; /* True if attempting to append */ + int iIdx = 0; /* Largest idx in level (iAbsLevel+1) */ + + /* Search the %_segdir table for the absolute level with the smallest + ** relative level number that contains at least nMin segments, if any. + ** If one is found, set iAbsLevel to the absolute level number and + ** nSeg to nMin. If no level with at least nMin segments can be found, + ** set nSeg to -1. + */ + rc = fts3SqlStmt(p, SQL_FIND_MERGE_LEVEL, &pFindLevel, 0); + sqlite3_bind_int(pFindLevel, 1, MAX(2, nMin)); + if( sqlite3_step(pFindLevel)==SQLITE_ROW ){ + iAbsLevel = sqlite3_column_int64(pFindLevel, 0); + nSeg = sqlite3_column_int(pFindLevel, 1); + assert( nSeg>=2 ); + }else{ + nSeg = -1; + } + rc = sqlite3_reset(pFindLevel); + + /* If the hint read from the %_stat table is not empty, check if the + ** last entry in it specifies a relative level smaller than or equal + ** to the level identified by the block above (if any). If so, this + ** iteration of the loop will work on merging at the hinted level. + */ + if( rc==SQLITE_OK && hint.n ){ + int nHint = hint.n; + sqlite3_int64 iHintAbsLevel = 0; /* Hint level */ + int nHintSeg = 0; /* Hint number of segments */ + + rc = fts3IncrmergeHintPop(&hint, &iHintAbsLevel, &nHintSeg); + if( nSeg<0 || (iAbsLevel % nMod) >= (iHintAbsLevel % nMod) ){ + /* Based on the scan in the block above, it is known that there + ** are no levels with a relative level smaller than that of + ** iAbsLevel with more than nSeg segments, or if nSeg is -1, + ** no levels with more than nMin segments. Use this to limit the + ** value of nHintSeg to avoid a large memory allocation in case the + ** merge-hint is corrupt*/ + iAbsLevel = iHintAbsLevel; + nSeg = MIN(MAX(nMin,nSeg), nHintSeg); + bUseHint = 1; + bDirtyHint = 1; + }else{ + /* This undoes the effect of the HintPop() above - so that no entry + ** is removed from the hint blob. */ + hint.n = nHint; + } + } + + /* If nSeg is less that zero, then there is no level with at least + ** nMin segments and no hint in the %_stat table. No work to do. + ** Exit early in this case. */ + if( nSeg<=0 ) break; + + assert( nMod<=0x7FFFFFFF ); + if( iAbsLevel<0 || iAbsLevel>(nMod<<32) ){ + rc = FTS_CORRUPT_VTAB; + break; + } + + /* Open a cursor to iterate through the contents of the oldest nSeg + ** indexes of absolute level iAbsLevel. If this cursor is opened using + ** the 'hint' parameters, it is possible that there are less than nSeg + ** segments available in level iAbsLevel. In this case, no work is + ** done on iAbsLevel - fall through to the next iteration of the loop + ** to start work on some other level. */ + memset(pWriter, 0, nAlloc); + pFilter->flags = FTS3_SEGMENT_REQUIRE_POS; + + if( rc==SQLITE_OK ){ + rc = fts3IncrmergeOutputIdx(p, iAbsLevel, &iIdx); + assert( bUseHint==1 || bUseHint==0 ); + if( iIdx==0 || (bUseHint && iIdx==1) ){ + int bIgnore = 0; + rc = fts3SegmentIsMaxLevel(p, iAbsLevel+1, &bIgnore); + if( bIgnore ){ + pFilter->flags |= FTS3_SEGMENT_IGNORE_EMPTY; + } + } + } + + if( rc==SQLITE_OK ){ + rc = fts3IncrmergeCsr(p, iAbsLevel, nSeg, pCsr); + } + if( SQLITE_OK==rc && pCsr->nSegment==nSeg + && SQLITE_OK==(rc = sqlite3Fts3SegReaderStart(p, pCsr, pFilter)) + ){ + int bEmpty = 0; + rc = sqlite3Fts3SegReaderStep(p, pCsr); + if( rc==SQLITE_OK ){ + bEmpty = 1; + }else if( rc!=SQLITE_ROW ){ + sqlite3Fts3SegReaderFinish(pCsr); + break; + } + if( bUseHint && iIdx>0 ){ + const char *zKey = pCsr->zTerm; + int nKey = pCsr->nTerm; + rc = fts3IncrmergeLoad(p, iAbsLevel, iIdx-1, zKey, nKey, pWriter); + }else{ + rc = fts3IncrmergeWriter(p, iAbsLevel, iIdx, pCsr, pWriter); + } + + if( rc==SQLITE_OK && pWriter->nLeafEst ){ + fts3LogMerge(nSeg, iAbsLevel); + if( bEmpty==0 ){ + do { + rc = fts3IncrmergeAppend(p, pWriter, pCsr); + if( rc==SQLITE_OK ) rc = sqlite3Fts3SegReaderStep(p, pCsr); + if( pWriter->nWork>=nRem && rc==SQLITE_ROW ) rc = SQLITE_OK; + }while( rc==SQLITE_ROW ); + } + + /* Update or delete the input segments */ + if( rc==SQLITE_OK ){ + nRem -= (1 + pWriter->nWork); + rc = fts3IncrmergeChomp(p, iAbsLevel, pCsr, &nSeg); + if( nSeg!=0 ){ + bDirtyHint = 1; + fts3IncrmergeHintPush(&hint, iAbsLevel, nSeg, &rc); + } + } + } + + if( nSeg!=0 ){ + pWriter->nLeafData = pWriter->nLeafData * -1; + } + fts3IncrmergeRelease(p, pWriter, &rc); + if( nSeg==0 && pWriter->bNoLeafData==0 ){ + fts3PromoteSegments(p, iAbsLevel+1, pWriter->nLeafData); + } + } + + sqlite3Fts3SegReaderFinish(pCsr); + } + + /* Write the hint values into the %_stat table for the next incr-merger */ + if( bDirtyHint && rc==SQLITE_OK ){ + rc = fts3IncrmergeHintStore(p, &hint); + } + + sqlite3_free(pWriter); + sqlite3_free(hint.a); + return rc; +} + +/* +** Convert the text beginning at *pz into an integer and return +** its value. Advance *pz to point to the first character past +** the integer. +** +** This function used for parameters to merge= and incrmerge= +** commands. +*/ +static int fts3Getint(const char **pz){ + const char *z = *pz; + int i = 0; + while( (*z)>='0' && (*z)<='9' && i<214748363 ) i = 10*i + *(z++) - '0'; + *pz = z; + return i; +} + +/* +** Process statements of the form: +** +** INSERT INTO table(table) VALUES('merge=A,B'); +** +** A and B are integers that decode to be the number of leaf pages +** written for the merge, and the minimum number of segments on a level +** before it will be selected for a merge, respectively. +*/ +static int fts3DoIncrmerge( + Fts3Table *p, /* FTS3 table handle */ + const char *zParam /* Nul-terminated string containing "A,B" */ +){ + int rc; + int nMin = (MergeCount(p) / 2); + int nMerge = 0; + const char *z = zParam; + + /* Read the first integer value */ + nMerge = fts3Getint(&z); + + /* If the first integer value is followed by a ',', read the second + ** integer value. */ + if( z[0]==',' && z[1]!='\0' ){ + z++; + nMin = fts3Getint(&z); + } + + if( z[0]!='\0' || nMin<2 ){ + rc = SQLITE_ERROR; + }else{ + rc = SQLITE_OK; + if( !p->bHasStat ){ + assert( p->bFts4==0 ); + sqlite3Fts3CreateStatTable(&rc, p); + } + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3Incrmerge(p, nMerge, nMin); + } + sqlite3Fts3SegmentsClose(p); + } + return rc; +} + +/* +** Process statements of the form: +** +** INSERT INTO table(table) VALUES('automerge=X'); +** +** where X is an integer. X==0 means to turn automerge off. X!=0 means +** turn it on. The setting is persistent. +*/ +static int fts3DoAutoincrmerge( + Fts3Table *p, /* FTS3 table handle */ + const char *zParam /* Nul-terminated string containing boolean */ +){ + int rc = SQLITE_OK; + sqlite3_stmt *pStmt = 0; + p->nAutoincrmerge = fts3Getint(&zParam); + if( p->nAutoincrmerge==1 || p->nAutoincrmerge>MergeCount(p) ){ + p->nAutoincrmerge = 8; + } + if( !p->bHasStat ){ + assert( p->bFts4==0 ); + sqlite3Fts3CreateStatTable(&rc, p); + if( rc ) return rc; + } + rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pStmt, 0); + if( rc ) return rc; + sqlite3_bind_int(pStmt, 1, FTS_STAT_AUTOINCRMERGE); + sqlite3_bind_int(pStmt, 2, p->nAutoincrmerge); + sqlite3_step(pStmt); + rc = sqlite3_reset(pStmt); + return rc; +} + +/* +** Return a 64-bit checksum for the FTS index entry specified by the +** arguments to this function. +*/ +static u64 fts3ChecksumEntry( + const char *zTerm, /* Pointer to buffer containing term */ + int nTerm, /* Size of zTerm in bytes */ + int iLangid, /* Language id for current row */ + int iIndex, /* Index (0..Fts3Table.nIndex-1) */ + i64 iDocid, /* Docid for current row. */ + int iCol, /* Column number */ + int iPos /* Position */ +){ + int i; + u64 ret = (u64)iDocid; + + ret += (ret<<3) + iLangid; + ret += (ret<<3) + iIndex; + ret += (ret<<3) + iCol; + ret += (ret<<3) + iPos; + for(i=0; inIndex-1) */ + int *pRc /* OUT: Return code */ +){ + Fts3SegFilter filter; + Fts3MultiSegReader csr; + int rc; + u64 cksum = 0; + + if( *pRc ) return 0; + + memset(&filter, 0, sizeof(filter)); + memset(&csr, 0, sizeof(csr)); + filter.flags = FTS3_SEGMENT_REQUIRE_POS|FTS3_SEGMENT_IGNORE_EMPTY; + filter.flags |= FTS3_SEGMENT_SCAN; + + rc = sqlite3Fts3SegReaderCursor( + p, iLangid, iIndex, FTS3_SEGCURSOR_ALL, 0, 0, 0, 1,&csr + ); + if( rc==SQLITE_OK ){ + rc = sqlite3Fts3SegReaderStart(p, &csr, &filter); + } + + if( rc==SQLITE_OK ){ + while( SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, &csr)) ){ + char *pCsr = csr.aDoclist; + char *pEnd = &pCsr[csr.nDoclist]; + + i64 iDocid = 0; + i64 iCol = 0; + u64 iPos = 0; + + pCsr += sqlite3Fts3GetVarint(pCsr, &iDocid); + while( pCsrbDescIdx ){ + iDocid = (i64)((u64)iDocid - iVal); + }else{ + iDocid = (i64)((u64)iDocid + iVal); + } + } + }else{ + iPos += (iVal - 2); + cksum = cksum ^ fts3ChecksumEntry( + csr.zTerm, csr.nTerm, iLangid, iIndex, iDocid, + (int)iCol, (int)iPos + ); + } + } + } + } + } + sqlite3Fts3SegReaderFinish(&csr); + + *pRc = rc; + return cksum; +} + +/* +** Check if the contents of the FTS index match the current contents of the +** content table. If no error occurs and the contents do match, set *pbOk +** to true and return SQLITE_OK. Or if the contents do not match, set *pbOk +** to false before returning. +** +** If an error occurs (e.g. an OOM or IO error), return an SQLite error +** code. The final value of *pbOk is undefined in this case. +*/ +SQLITE_PRIVATE int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk){ + int rc = SQLITE_OK; /* Return code */ + u64 cksum1 = 0; /* Checksum based on FTS index contents */ + u64 cksum2 = 0; /* Checksum based on %_content contents */ + sqlite3_stmt *pAllLangid = 0; /* Statement to return all language-ids */ + + /* This block calculates the checksum according to the FTS index. */ + rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0); + if( rc==SQLITE_OK ){ + int rc2; + sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid); + sqlite3_bind_int(pAllLangid, 2, p->nIndex); + while( rc==SQLITE_OK && sqlite3_step(pAllLangid)==SQLITE_ROW ){ + int iLangid = sqlite3_column_int(pAllLangid, 0); + int i; + for(i=0; inIndex; i++){ + cksum1 = cksum1 ^ fts3ChecksumIndex(p, iLangid, i, &rc); + } + } + rc2 = sqlite3_reset(pAllLangid); + if( rc==SQLITE_OK ) rc = rc2; + } + + /* This block calculates the checksum according to the %_content table */ + if( rc==SQLITE_OK ){ + sqlite3_tokenizer_module const *pModule = p->pTokenizer->pModule; + sqlite3_stmt *pStmt = 0; + char *zSql; + + zSql = sqlite3_mprintf("SELECT %s" , p->zReadExprlist); + if( !zSql ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3Fts3PrepareStmt(p, zSql, 0, 1, &pStmt); + sqlite3_free(zSql); + } + + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + i64 iDocid = sqlite3_column_int64(pStmt, 0); + int iLang = langidFromSelect(p, pStmt); + int iCol; + + for(iCol=0; rc==SQLITE_OK && iColnColumn; iCol++){ + if( p->abNotindexed[iCol]==0 ){ + const char *zText = (const char *)sqlite3_column_text(pStmt, iCol+1); + sqlite3_tokenizer_cursor *pT = 0; + + rc = sqlite3Fts3OpenTokenizer(p->pTokenizer, iLang, zText, -1, &pT); + while( rc==SQLITE_OK ){ + char const *zToken; /* Buffer containing token */ + int nToken = 0; /* Number of bytes in token */ + int iDum1 = 0, iDum2 = 0; /* Dummy variables */ + int iPos = 0; /* Position of token in zText */ + + rc = pModule->xNext(pT, &zToken, &nToken, &iDum1, &iDum2, &iPos); + if( rc==SQLITE_OK ){ + int i; + cksum2 = cksum2 ^ fts3ChecksumEntry( + zToken, nToken, iLang, 0, iDocid, iCol, iPos + ); + for(i=1; inIndex; i++){ + if( p->aIndex[i].nPrefix<=nToken ){ + cksum2 = cksum2 ^ fts3ChecksumEntry( + zToken, p->aIndex[i].nPrefix, iLang, i, iDocid, iCol, iPos + ); + } + } + } + } + if( pT ) pModule->xClose(pT); + if( rc==SQLITE_DONE ) rc = SQLITE_OK; + } + } + } + + sqlite3_finalize(pStmt); + } + + if( rc==SQLITE_CORRUPT_VTAB ){ + rc = SQLITE_OK; + *pbOk = 0; + }else{ + *pbOk = (rc==SQLITE_OK && cksum1==cksum2); + } + return rc; +} + +/* +** Run the integrity-check. If no error occurs and the current contents of +** the FTS index are correct, return SQLITE_OK. Or, if the contents of the +** FTS index are incorrect, return SQLITE_CORRUPT_VTAB. +** +** Or, if an error (e.g. an OOM or IO error) occurs, return an SQLite +** error code. +** +** The integrity-check works as follows. For each token and indexed token +** prefix in the document set, a 64-bit checksum is calculated (by code +** in fts3ChecksumEntry()) based on the following: +** +** + The index number (0 for the main index, 1 for the first prefix +** index etc.), +** + The token (or token prefix) text itself, +** + The language-id of the row it appears in, +** + The docid of the row it appears in, +** + The column it appears in, and +** + The tokens position within that column. +** +** The checksums for all entries in the index are XORed together to create +** a single checksum for the entire index. +** +** The integrity-check code calculates the same checksum in two ways: +** +** 1. By scanning the contents of the FTS index, and +** 2. By scanning and tokenizing the content table. +** +** If the two checksums are identical, the integrity-check is deemed to have +** passed. +*/ +static int fts3DoIntegrityCheck( + Fts3Table *p /* FTS3 table handle */ +){ + int rc; + int bOk = 0; + rc = sqlite3Fts3IntegrityCheck(p, &bOk); + if( rc==SQLITE_OK && bOk==0 ) rc = FTS_CORRUPT_VTAB; + return rc; +} + +/* +** Handle a 'special' INSERT of the form: +** +** "INSERT INTO tbl(tbl) VALUES()" +** +** Argument pVal contains the result of . Currently the only +** meaningful value to insert is the text 'optimize'. +*/ +static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){ + int rc = SQLITE_ERROR; /* Return Code */ + const char *zVal = (const char *)sqlite3_value_text(pVal); + int nVal = sqlite3_value_bytes(pVal); + + if( !zVal ){ + return SQLITE_NOMEM; + }else if( nVal==8 && 0==sqlite3_strnicmp(zVal, "optimize", 8) ){ + rc = fts3DoOptimize(p, 0); + }else if( nVal==7 && 0==sqlite3_strnicmp(zVal, "rebuild", 7) ){ + rc = fts3DoRebuild(p); + }else if( nVal==15 && 0==sqlite3_strnicmp(zVal, "integrity-check", 15) ){ + rc = fts3DoIntegrityCheck(p); + }else if( nVal>6 && 0==sqlite3_strnicmp(zVal, "merge=", 6) ){ + rc = fts3DoIncrmerge(p, &zVal[6]); + }else if( nVal>10 && 0==sqlite3_strnicmp(zVal, "automerge=", 10) ){ + rc = fts3DoAutoincrmerge(p, &zVal[10]); + }else if( nVal==5 && 0==sqlite3_strnicmp(zVal, "flush", 5) ){ + rc = sqlite3Fts3PendingTermsFlush(p); + } +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) + else{ + int v; + if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){ + v = atoi(&zVal[9]); + if( v>=24 && v<=p->nPgsz-35 ) p->nNodeSize = v; + rc = SQLITE_OK; + }else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 11) ){ + v = atoi(&zVal[11]); + if( v>=64 && v<=FTS3_MAX_PENDING_DATA ) p->nMaxPendingData = v; + rc = SQLITE_OK; + }else if( nVal>21 && 0==sqlite3_strnicmp(zVal,"test-no-incr-doclist=",21) ){ + p->bNoIncrDoclist = atoi(&zVal[21]); + rc = SQLITE_OK; + }else if( nVal>11 && 0==sqlite3_strnicmp(zVal,"mergecount=",11) ){ + v = atoi(&zVal[11]); + if( v>=4 && v<=FTS3_MERGE_COUNT && (v&1)==0 ) p->nMergeCount = v; + rc = SQLITE_OK; + } + } +#endif + return rc; +} + +#ifndef SQLITE_DISABLE_FTS4_DEFERRED +/* +** Delete all cached deferred doclists. Deferred doclists are cached +** (allocated) by the sqlite3Fts3CacheDeferredDoclists() function. +*/ +SQLITE_PRIVATE void sqlite3Fts3FreeDeferredDoclists(Fts3Cursor *pCsr){ + Fts3DeferredToken *pDef; + for(pDef=pCsr->pDeferred; pDef; pDef=pDef->pNext){ + fts3PendingListDelete(pDef->pList); + pDef->pList = 0; + } +} + +/* +** Free all entries in the pCsr->pDeffered list. Entries are added to +** this list using sqlite3Fts3DeferToken(). +*/ +SQLITE_PRIVATE void sqlite3Fts3FreeDeferredTokens(Fts3Cursor *pCsr){ + Fts3DeferredToken *pDef; + Fts3DeferredToken *pNext; + for(pDef=pCsr->pDeferred; pDef; pDef=pNext){ + pNext = pDef->pNext; + fts3PendingListDelete(pDef->pList); + sqlite3_free(pDef); + } + pCsr->pDeferred = 0; +} + +/* +** Generate deferred-doclists for all tokens in the pCsr->pDeferred list +** based on the row that pCsr currently points to. +** +** A deferred-doclist is like any other doclist with position information +** included, except that it only contains entries for a single row of the +** table, not for all rows. +*/ +SQLITE_PRIVATE int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *pCsr){ + int rc = SQLITE_OK; /* Return code */ + if( pCsr->pDeferred ){ + int i; /* Used to iterate through table columns */ + sqlite3_int64 iDocid; /* Docid of the row pCsr points to */ + Fts3DeferredToken *pDef; /* Used to iterate through deferred tokens */ + + Fts3Table *p = (Fts3Table *)pCsr->base.pVtab; + sqlite3_tokenizer *pT = p->pTokenizer; + sqlite3_tokenizer_module const *pModule = pT->pModule; + + assert( pCsr->isRequireSeek==0 ); + iDocid = sqlite3_column_int64(pCsr->pStmt, 0); + + for(i=0; inColumn && rc==SQLITE_OK; i++){ + if( p->abNotindexed[i]==0 ){ + const char *zText = (const char *)sqlite3_column_text(pCsr->pStmt, i+1); + sqlite3_tokenizer_cursor *pTC = 0; + + rc = sqlite3Fts3OpenTokenizer(pT, pCsr->iLangid, zText, -1, &pTC); + while( rc==SQLITE_OK ){ + char const *zToken; /* Buffer containing token */ + int nToken = 0; /* Number of bytes in token */ + int iDum1 = 0, iDum2 = 0; /* Dummy variables */ + int iPos = 0; /* Position of token in zText */ + + rc = pModule->xNext(pTC, &zToken, &nToken, &iDum1, &iDum2, &iPos); + for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){ + Fts3PhraseToken *pPT = pDef->pToken; + if( (pDef->iCol>=p->nColumn || pDef->iCol==i) + && (pPT->bFirst==0 || iPos==0) + && (pPT->n==nToken || (pPT->isPrefix && pPT->nz, pPT->n)) + ){ + fts3PendingListAppend(&pDef->pList, iDocid, i, iPos, &rc); + } + } + } + if( pTC ) pModule->xClose(pTC); + if( rc==SQLITE_DONE ) rc = SQLITE_OK; + } + } + + for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){ + if( pDef->pList ){ + rc = fts3PendingListAppendVarint(&pDef->pList, 0); + } + } + } + + return rc; +} + +SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList( + Fts3DeferredToken *p, + char **ppData, + int *pnData +){ + char *pRet; + int nSkip; + sqlite3_int64 dummy; + + *ppData = 0; + *pnData = 0; + + if( p->pList==0 ){ + return SQLITE_OK; + } + + pRet = (char *)sqlite3_malloc64(p->pList->nData); + if( !pRet ) return SQLITE_NOMEM; + + nSkip = sqlite3Fts3GetVarint(p->pList->aData, &dummy); + *pnData = p->pList->nData - nSkip; + *ppData = pRet; + + memcpy(pRet, &p->pList->aData[nSkip], *pnData); + return SQLITE_OK; +} + +/* +** Add an entry for token pToken to the pCsr->pDeferred list. +*/ +SQLITE_PRIVATE int sqlite3Fts3DeferToken( + Fts3Cursor *pCsr, /* Fts3 table cursor */ + Fts3PhraseToken *pToken, /* Token to defer */ + int iCol /* Column that token must appear in (or -1) */ +){ + Fts3DeferredToken *pDeferred; + pDeferred = sqlite3_malloc64(sizeof(*pDeferred)); + if( !pDeferred ){ + return SQLITE_NOMEM; + } + memset(pDeferred, 0, sizeof(*pDeferred)); + pDeferred->pToken = pToken; + pDeferred->pNext = pCsr->pDeferred; + pDeferred->iCol = iCol; + pCsr->pDeferred = pDeferred; + + assert( pToken->pDeferred==0 ); + pToken->pDeferred = pDeferred; + + return SQLITE_OK; +} +#endif + +/* +** SQLite value pRowid contains the rowid of a row that may or may not be +** present in the FTS3 table. If it is, delete it and adjust the contents +** of subsidiary data structures accordingly. +*/ +static int fts3DeleteByRowid( + Fts3Table *p, + sqlite3_value *pRowid, + int *pnChng, /* IN/OUT: Decrement if row is deleted */ + u32 *aSzDel +){ + int rc = SQLITE_OK; /* Return code */ + int bFound = 0; /* True if *pRowid really is in the table */ + + fts3DeleteTerms(&rc, p, pRowid, aSzDel, &bFound); + if( bFound && rc==SQLITE_OK ){ + int isEmpty = 0; /* Deleting *pRowid leaves the table empty */ + rc = fts3IsEmpty(p, pRowid, &isEmpty); + if( rc==SQLITE_OK ){ + if( isEmpty ){ + /* Deleting this row means the whole table is empty. In this case + ** delete the contents of all three tables and throw away any + ** data in the pendingTerms hash table. */ + rc = fts3DeleteAll(p, 1); + *pnChng = 0; + memset(aSzDel, 0, sizeof(u32) * (p->nColumn+1) * 2); + }else{ + *pnChng = *pnChng - 1; + if( p->zContentTbl==0 ){ + fts3SqlExec(&rc, p, SQL_DELETE_CONTENT, &pRowid); + } + if( p->bHasDocsize ){ + fts3SqlExec(&rc, p, SQL_DELETE_DOCSIZE, &pRowid); + } + } + } + } + + return rc; +} + +/* +** This function does the work for the xUpdate method of FTS3 virtual +** tables. The schema of the virtual table being: +** +** CREATE TABLE
    ( +** , +**
    HIDDEN, +** docid HIDDEN, +** HIDDEN +** ); +** +** +*/ +SQLITE_PRIVATE int sqlite3Fts3UpdateMethod( + sqlite3_vtab *pVtab, /* FTS3 vtab object */ + int nArg, /* Size of argument array */ + sqlite3_value **apVal, /* Array of arguments */ + sqlite_int64 *pRowid /* OUT: The affected (or effected) rowid */ +){ + Fts3Table *p = (Fts3Table *)pVtab; + int rc = SQLITE_OK; /* Return Code */ + u32 *aSzIns = 0; /* Sizes of inserted documents */ + u32 *aSzDel = 0; /* Sizes of deleted documents */ + int nChng = 0; /* Net change in number of documents */ + int bInsertDone = 0; + + /* At this point it must be known if the %_stat table exists or not. + ** So bHasStat may not be 2. */ + assert( p->bHasStat==0 || p->bHasStat==1 ); + + assert( p->pSegments==0 ); + assert( + nArg==1 /* DELETE operations */ + || nArg==(2 + p->nColumn + 3) /* INSERT or UPDATE operations */ + ); + + /* Check for a "special" INSERT operation. One of the form: + ** + ** INSERT INTO xyz(xyz) VALUES('command'); + */ + if( nArg>1 + && sqlite3_value_type(apVal[0])==SQLITE_NULL + && sqlite3_value_type(apVal[p->nColumn+2])!=SQLITE_NULL + ){ + rc = fts3SpecialInsert(p, apVal[p->nColumn+2]); + goto update_out; + } + + if( nArg>1 && sqlite3_value_int(apVal[2 + p->nColumn + 2])<0 ){ + rc = SQLITE_CONSTRAINT; + goto update_out; + } + + /* Allocate space to hold the change in document sizes */ + aSzDel = sqlite3_malloc64(sizeof(aSzDel[0])*((sqlite3_int64)p->nColumn+1)*2); + if( aSzDel==0 ){ + rc = SQLITE_NOMEM; + goto update_out; + } + aSzIns = &aSzDel[p->nColumn+1]; + memset(aSzDel, 0, sizeof(aSzDel[0])*(p->nColumn+1)*2); + + rc = fts3Writelock(p); + if( rc!=SQLITE_OK ) goto update_out; + + /* If this is an INSERT operation, or an UPDATE that modifies the rowid + ** value, then this operation requires constraint handling. + ** + ** If the on-conflict mode is REPLACE, this means that the existing row + ** should be deleted from the database before inserting the new row. Or, + ** if the on-conflict mode is other than REPLACE, then this method must + ** detect the conflict and return SQLITE_CONSTRAINT before beginning to + ** modify the database file. + */ + if( nArg>1 && p->zContentTbl==0 ){ + /* Find the value object that holds the new rowid value. */ + sqlite3_value *pNewRowid = apVal[3+p->nColumn]; + if( sqlite3_value_type(pNewRowid)==SQLITE_NULL ){ + pNewRowid = apVal[1]; + } + + if( sqlite3_value_type(pNewRowid)!=SQLITE_NULL && ( + sqlite3_value_type(apVal[0])==SQLITE_NULL + || sqlite3_value_int64(apVal[0])!=sqlite3_value_int64(pNewRowid) + )){ + /* The new rowid is not NULL (in this case the rowid will be + ** automatically assigned and there is no chance of a conflict), and + ** the statement is either an INSERT or an UPDATE that modifies the + ** rowid column. So if the conflict mode is REPLACE, then delete any + ** existing row with rowid=pNewRowid. + ** + ** Or, if the conflict mode is not REPLACE, insert the new record into + ** the %_content table. If we hit the duplicate rowid constraint (or any + ** other error) while doing so, return immediately. + ** + ** This branch may also run if pNewRowid contains a value that cannot + ** be losslessly converted to an integer. In this case, the eventual + ** call to fts3InsertData() (either just below or further on in this + ** function) will return SQLITE_MISMATCH. If fts3DeleteByRowid is + ** invoked, it will delete zero rows (since no row will have + ** docid=$pNewRowid if $pNewRowid is not an integer value). + */ + if( sqlite3_vtab_on_conflict(p->db)==SQLITE_REPLACE ){ + rc = fts3DeleteByRowid(p, pNewRowid, &nChng, aSzDel); + }else{ + rc = fts3InsertData(p, apVal, pRowid); + bInsertDone = 1; + } + } + } + if( rc!=SQLITE_OK ){ + goto update_out; + } + + /* If this is a DELETE or UPDATE operation, remove the old record. */ + if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){ + assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER ); + rc = fts3DeleteByRowid(p, apVal[0], &nChng, aSzDel); + } + + /* If this is an INSERT or UPDATE operation, insert the new record. */ + if( nArg>1 && rc==SQLITE_OK ){ + int iLangid = sqlite3_value_int(apVal[2 + p->nColumn + 2]); + if( bInsertDone==0 ){ + rc = fts3InsertData(p, apVal, pRowid); + if( rc==SQLITE_CONSTRAINT && p->zContentTbl==0 ){ + rc = FTS_CORRUPT_VTAB; + } + } + if( rc==SQLITE_OK ){ + rc = fts3PendingTermsDocid(p, 0, iLangid, *pRowid); + } + if( rc==SQLITE_OK ){ + assert( p->iPrevDocid==*pRowid ); + rc = fts3InsertTerms(p, iLangid, apVal, aSzIns); + } + if( p->bHasDocsize ){ + fts3InsertDocsize(&rc, p, aSzIns); + } + nChng++; + } + + if( p->bFts4 ){ + fts3UpdateDocTotals(&rc, p, aSzIns, aSzDel, nChng); + } + + update_out: + sqlite3_free(aSzDel); + sqlite3Fts3SegmentsClose(p); + return rc; +} + +/* +** Flush any data in the pending-terms hash table to disk. If successful, +** merge all segments in the database (including the new segment, if +** there was any data to flush) into a single segment. +*/ +SQLITE_PRIVATE int sqlite3Fts3Optimize(Fts3Table *p){ + int rc; + rc = sqlite3_exec(p->db, "SAVEPOINT fts3", 0, 0, 0); + if( rc==SQLITE_OK ){ + rc = fts3DoOptimize(p, 1); + if( rc==SQLITE_OK || rc==SQLITE_DONE ){ + int rc2 = sqlite3_exec(p->db, "RELEASE fts3", 0, 0, 0); + if( rc2!=SQLITE_OK ) rc = rc2; + }else{ + sqlite3_exec(p->db, "ROLLBACK TO fts3", 0, 0, 0); + sqlite3_exec(p->db, "RELEASE fts3", 0, 0, 0); + } + } + sqlite3Fts3SegmentsClose(p); + return rc; +} + +#endif + +/************** End of fts3_write.c ******************************************/ +/************** Begin file fts3_snippet.c ************************************/ +/* +** 2009 Oct 23 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +*/ + +/* #include "fts3Int.h" */ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include */ +/* #include */ + +/* +** Characters that may appear in the second argument to matchinfo(). +*/ +#define FTS3_MATCHINFO_NPHRASE 'p' /* 1 value */ +#define FTS3_MATCHINFO_NCOL 'c' /* 1 value */ +#define FTS3_MATCHINFO_NDOC 'n' /* 1 value */ +#define FTS3_MATCHINFO_AVGLENGTH 'a' /* nCol values */ +#define FTS3_MATCHINFO_LENGTH 'l' /* nCol values */ +#define FTS3_MATCHINFO_LCS 's' /* nCol values */ +#define FTS3_MATCHINFO_HITS 'x' /* 3*nCol*nPhrase values */ +#define FTS3_MATCHINFO_LHITS 'y' /* nCol*nPhrase values */ +#define FTS3_MATCHINFO_LHITS_BM 'b' /* nCol*nPhrase values */ + +/* +** The default value for the second argument to matchinfo(). +*/ +#define FTS3_MATCHINFO_DEFAULT "pcx" + + +/* +** Used as an sqlite3Fts3ExprIterate() context when loading phrase doclists to +** Fts3Expr.aDoclist[]/nDoclist. +*/ +typedef struct LoadDoclistCtx LoadDoclistCtx; +struct LoadDoclistCtx { + Fts3Cursor *pCsr; /* FTS3 Cursor */ + int nPhrase; /* Number of phrases seen so far */ + int nToken; /* Number of tokens seen so far */ +}; + +/* +** The following types are used as part of the implementation of the +** fts3BestSnippet() routine. +*/ +typedef struct SnippetIter SnippetIter; +typedef struct SnippetPhrase SnippetPhrase; +typedef struct SnippetFragment SnippetFragment; + +struct SnippetIter { + Fts3Cursor *pCsr; /* Cursor snippet is being generated from */ + int iCol; /* Extract snippet from this column */ + int nSnippet; /* Requested snippet length (in tokens) */ + int nPhrase; /* Number of phrases in query */ + SnippetPhrase *aPhrase; /* Array of size nPhrase */ + int iCurrent; /* First token of current snippet */ +}; + +struct SnippetPhrase { + int nToken; /* Number of tokens in phrase */ + char *pList; /* Pointer to start of phrase position list */ + i64 iHead; /* Next value in position list */ + char *pHead; /* Position list data following iHead */ + i64 iTail; /* Next value in trailing position list */ + char *pTail; /* Position list data following iTail */ +}; + +struct SnippetFragment { + int iCol; /* Column snippet is extracted from */ + int iPos; /* Index of first token in snippet */ + u64 covered; /* Mask of query phrases covered */ + u64 hlmask; /* Mask of snippet terms to highlight */ +}; + +/* +** This type is used as an sqlite3Fts3ExprIterate() context object while +** accumulating the data returned by the matchinfo() function. +*/ +typedef struct MatchInfo MatchInfo; +struct MatchInfo { + Fts3Cursor *pCursor; /* FTS3 Cursor */ + int nCol; /* Number of columns in table */ + int nPhrase; /* Number of matchable phrases in query */ + sqlite3_int64 nDoc; /* Number of docs in database */ + char flag; + u32 *aMatchinfo; /* Pre-allocated buffer */ +}; + +/* +** An instance of this structure is used to manage a pair of buffers, each +** (nElem * sizeof(u32)) bytes in size. See the MatchinfoBuffer code below +** for details. +*/ +struct MatchinfoBuffer { + u8 aRef[3]; + int nElem; + int bGlobal; /* Set if global data is loaded */ + char *zMatchinfo; + u32 aMI[FLEXARRAY]; +}; + +/* Size (in bytes) of a MatchinfoBuffer sufficient for N elements */ +#define SZ_MATCHINFOBUFFER(N) \ + (offsetof(MatchinfoBuffer,aMI)+(((N)+1)/2)*sizeof(u64)) + + +/* +** The snippet() and offsets() functions both return text values. An instance +** of the following structure is used to accumulate those values while the +** functions are running. See fts3StringAppend() for details. +*/ +typedef struct StrBuffer StrBuffer; +struct StrBuffer { + char *z; /* Pointer to buffer containing string */ + int n; /* Length of z in bytes (excl. nul-term) */ + int nAlloc; /* Allocated size of buffer z in bytes */ +}; + + +/************************************************************************* +** Start of MatchinfoBuffer code. +*/ + +/* +** Allocate a two-slot MatchinfoBuffer object. +*/ +static MatchinfoBuffer *fts3MIBufferNew(size_t nElem, const char *zMatchinfo){ + MatchinfoBuffer *pRet; + sqlite3_int64 nByte = sizeof(u32) * (2*(sqlite3_int64)nElem + 1) + + SZ_MATCHINFOBUFFER(1); + sqlite3_int64 nStr = strlen(zMatchinfo); + + pRet = sqlite3Fts3MallocZero(nByte + nStr+1); + if( pRet ){ + pRet->aMI[0] = (u8*)(&pRet->aMI[1]) - (u8*)pRet; + pRet->aMI[1+nElem] = pRet->aMI[0] + + sizeof(u32)*((int)nElem+1); + pRet->nElem = (int)nElem; + pRet->zMatchinfo = ((char*)pRet) + nByte; + memcpy(pRet->zMatchinfo, zMatchinfo, nStr+1); + pRet->aRef[0] = 1; + } + + return pRet; +} + +static void fts3MIBufferFree(void *p){ + MatchinfoBuffer *pBuf = (MatchinfoBuffer*)((u8*)p - ((u32*)p)[-1]); + + assert( (u32*)p==&pBuf->aMI[1] + || (u32*)p==&pBuf->aMI[pBuf->nElem+2] + ); + if( (u32*)p==&pBuf->aMI[1] ){ + pBuf->aRef[1] = 0; + }else{ + pBuf->aRef[2] = 0; + } + + if( pBuf->aRef[0]==0 && pBuf->aRef[1]==0 && pBuf->aRef[2]==0 ){ + sqlite3_free(pBuf); + } +} + +static void (*fts3MIBufferAlloc(MatchinfoBuffer *p, u32 **paOut))(void*){ + void (*xRet)(void*) = 0; + u32 *aOut = 0; + + if( p->aRef[1]==0 ){ + p->aRef[1] = 1; + aOut = &p->aMI[1]; + xRet = fts3MIBufferFree; + } + else if( p->aRef[2]==0 ){ + p->aRef[2] = 1; + aOut = &p->aMI[p->nElem+2]; + xRet = fts3MIBufferFree; + }else{ + aOut = (u32*)sqlite3_malloc64(p->nElem * sizeof(u32)); + if( aOut ){ + xRet = sqlite3_free; + if( p->bGlobal ) memcpy(aOut, &p->aMI[1], p->nElem*sizeof(u32)); + } + } + + *paOut = aOut; + return xRet; +} + +static void fts3MIBufferSetGlobal(MatchinfoBuffer *p){ + p->bGlobal = 1; + memcpy(&p->aMI[2+p->nElem], &p->aMI[1], p->nElem*sizeof(u32)); +} + +/* +** Free a MatchinfoBuffer object allocated using fts3MIBufferNew() +*/ +SQLITE_PRIVATE void sqlite3Fts3MIBufferFree(MatchinfoBuffer *p){ + if( p ){ + assert( p->aRef[0]==1 ); + p->aRef[0] = 0; + if( p->aRef[0]==0 && p->aRef[1]==0 && p->aRef[2]==0 ){ + sqlite3_free(p); + } + } +} + +/* +** End of MatchinfoBuffer code. +*************************************************************************/ + + +/* +** This function is used to help iterate through a position-list. A position +** list is a list of unique integers, sorted from smallest to largest. Each +** element of the list is represented by an FTS3 varint that takes the value +** of the difference between the current element and the previous one plus +** two. For example, to store the position-list: +** +** 4 9 113 +** +** the three varints: +** +** 6 7 106 +** +** are encoded. +** +** When this function is called, *pp points to the start of an element of +** the list. *piPos contains the value of the previous entry in the list. +** After it returns, *piPos contains the value of the next element of the +** list and *pp is advanced to the following varint. +*/ +static void fts3GetDeltaPosition(char **pp, i64 *piPos){ + int iVal; + *pp += fts3GetVarint32(*pp, &iVal); + *piPos += (iVal-2); +} + +/* +** Helper function for sqlite3Fts3ExprIterate() (see below). +*/ +static int fts3ExprIterate2( + Fts3Expr *pExpr, /* Expression to iterate phrases of */ + int *piPhrase, /* Pointer to phrase counter */ + int (*x)(Fts3Expr*,int,void*), /* Callback function to invoke for phrases */ + void *pCtx /* Second argument to pass to callback */ +){ + int rc; /* Return code */ + int eType = pExpr->eType; /* Type of expression node pExpr */ + + if( eType!=FTSQUERY_PHRASE ){ + assert( pExpr->pLeft && pExpr->pRight ); + rc = fts3ExprIterate2(pExpr->pLeft, piPhrase, x, pCtx); + if( rc==SQLITE_OK && eType!=FTSQUERY_NOT ){ + rc = fts3ExprIterate2(pExpr->pRight, piPhrase, x, pCtx); + } + }else{ + rc = x(pExpr, *piPhrase, pCtx); + (*piPhrase)++; + } + return rc; +} + +/* +** Iterate through all phrase nodes in an FTS3 query, except those that +** are part of a sub-tree that is the right-hand-side of a NOT operator. +** For each phrase node found, the supplied callback function is invoked. +** +** If the callback function returns anything other than SQLITE_OK, +** the iteration is abandoned and the error code returned immediately. +** Otherwise, SQLITE_OK is returned after a callback has been made for +** all eligible phrase nodes. +*/ +SQLITE_PRIVATE int sqlite3Fts3ExprIterate( + Fts3Expr *pExpr, /* Expression to iterate phrases of */ + int (*x)(Fts3Expr*,int,void*), /* Callback function to invoke for phrases */ + void *pCtx /* Second argument to pass to callback */ +){ + int iPhrase = 0; /* Variable used as the phrase counter */ + return fts3ExprIterate2(pExpr, &iPhrase, x, pCtx); +} + +/* +** This is an sqlite3Fts3ExprIterate() callback used while loading the +** doclists for each phrase into Fts3Expr.aDoclist[]/nDoclist. See also +** fts3ExprLoadDoclists(). +*/ +static int fts3ExprLoadDoclistsCb(Fts3Expr *pExpr, int iPhrase, void *ctx){ + int rc = SQLITE_OK; + Fts3Phrase *pPhrase = pExpr->pPhrase; + LoadDoclistCtx *p = (LoadDoclistCtx *)ctx; + + UNUSED_PARAMETER(iPhrase); + + p->nPhrase++; + p->nToken += pPhrase->nToken; + + return rc; +} + +/* +** Load the doclists for each phrase in the query associated with FTS3 cursor +** pCsr. +** +** If pnPhrase is not NULL, then *pnPhrase is set to the number of matchable +** phrases in the expression (all phrases except those directly or +** indirectly descended from the right-hand-side of a NOT operator). If +** pnToken is not NULL, then it is set to the number of tokens in all +** matchable phrases of the expression. +*/ +static int fts3ExprLoadDoclists( + Fts3Cursor *pCsr, /* Fts3 cursor for current query */ + int *pnPhrase, /* OUT: Number of phrases in query */ + int *pnToken /* OUT: Number of tokens in query */ +){ + int rc; /* Return Code */ + LoadDoclistCtx sCtx = {0,0,0}; /* Context for sqlite3Fts3ExprIterate() */ + sCtx.pCsr = pCsr; + rc = sqlite3Fts3ExprIterate(pCsr->pExpr,fts3ExprLoadDoclistsCb,(void*)&sCtx); + if( pnPhrase ) *pnPhrase = sCtx.nPhrase; + if( pnToken ) *pnToken = sCtx.nToken; + return rc; +} + +static int fts3ExprPhraseCountCb(Fts3Expr *pExpr, int iPhrase, void *ctx){ + (*(int *)ctx)++; + pExpr->iPhrase = iPhrase; + return SQLITE_OK; +} +static int fts3ExprPhraseCount(Fts3Expr *pExpr){ + int nPhrase = 0; + (void)sqlite3Fts3ExprIterate(pExpr, fts3ExprPhraseCountCb, (void *)&nPhrase); + return nPhrase; +} + +/* +** Advance the position list iterator specified by the first two +** arguments so that it points to the first element with a value greater +** than or equal to parameter iNext. +*/ +static void fts3SnippetAdvance(char **ppIter, i64 *piIter, int iNext){ + char *pIter = *ppIter; + if( pIter ){ + i64 iIter = *piIter; + + while( iIteriCurrent<0 ){ + /* The SnippetIter object has just been initialized. The first snippet + ** candidate always starts at offset 0 (even if this candidate has a + ** score of 0.0). + */ + pIter->iCurrent = 0; + + /* Advance the 'head' iterator of each phrase to the first offset that + ** is greater than or equal to (iNext+nSnippet). + */ + for(i=0; inPhrase; i++){ + SnippetPhrase *pPhrase = &pIter->aPhrase[i]; + fts3SnippetAdvance(&pPhrase->pHead, &pPhrase->iHead, pIter->nSnippet); + } + }else{ + int iStart; + int iEnd = 0x7FFFFFFF; + + for(i=0; inPhrase; i++){ + SnippetPhrase *pPhrase = &pIter->aPhrase[i]; + if( pPhrase->pHead && pPhrase->iHeadiHead; + } + } + if( iEnd==0x7FFFFFFF ){ + return 1; + } + + assert( pIter->nSnippet>=0 ); + pIter->iCurrent = iStart = iEnd - pIter->nSnippet + 1; + for(i=0; inPhrase; i++){ + SnippetPhrase *pPhrase = &pIter->aPhrase[i]; + fts3SnippetAdvance(&pPhrase->pHead, &pPhrase->iHead, iEnd+1); + fts3SnippetAdvance(&pPhrase->pTail, &pPhrase->iTail, iStart); + } + } + + return 0; +} + +/* +** Retrieve information about the current candidate snippet of snippet +** iterator pIter. +*/ +static void fts3SnippetDetails( + SnippetIter *pIter, /* Snippet iterator */ + u64 mCovered, /* Bitmask of phrases already covered */ + int *piToken, /* OUT: First token of proposed snippet */ + int *piScore, /* OUT: "Score" for this snippet */ + u64 *pmCover, /* OUT: Bitmask of phrases covered */ + u64 *pmHighlight /* OUT: Bitmask of terms to highlight */ +){ + int iStart = pIter->iCurrent; /* First token of snippet */ + int iScore = 0; /* Score of this snippet */ + int i; /* Loop counter */ + u64 mCover = 0; /* Mask of phrases covered by this snippet */ + u64 mHighlight = 0; /* Mask of tokens to highlight in snippet */ + + for(i=0; inPhrase; i++){ + SnippetPhrase *pPhrase = &pIter->aPhrase[i]; + if( pPhrase->pTail ){ + char *pCsr = pPhrase->pTail; + i64 iCsr = pPhrase->iTail; + + while( iCsr<(iStart+pIter->nSnippet) && iCsr>=iStart ){ + int j; + u64 mPhrase = (u64)1 << (i%64); + u64 mPos = (u64)1 << (iCsr - iStart); + assert( iCsr>=iStart && (iCsr - iStart)<=64 ); + assert( i>=0 ); + if( (mCover|mCovered)&mPhrase ){ + iScore++; + }else{ + iScore += 1000; + } + mCover |= mPhrase; + + for(j=0; jnToken && jnSnippet; j++){ + mHighlight |= (mPos>>j); + } + + if( 0==(*pCsr & 0x0FE) ) break; + fts3GetDeltaPosition(&pCsr, &iCsr); + } + } + } + + /* Set the output variables before returning. */ + *piToken = iStart; + *piScore = iScore; + *pmCover = mCover; + *pmHighlight = mHighlight; +} + +/* +** This function is an sqlite3Fts3ExprIterate() callback used by +** fts3BestSnippet(). Each invocation populates an element of the +** SnippetIter.aPhrase[] array. +*/ +static int fts3SnippetFindPositions(Fts3Expr *pExpr, int iPhrase, void *ctx){ + SnippetIter *p = (SnippetIter *)ctx; + SnippetPhrase *pPhrase = &p->aPhrase[iPhrase]; + char *pCsr; + int rc; + + pPhrase->nToken = pExpr->pPhrase->nToken; + rc = sqlite3Fts3EvalPhrasePoslist(p->pCsr, pExpr, p->iCol, &pCsr); + assert( rc==SQLITE_OK || pCsr==0 ); + if( pCsr ){ + i64 iFirst = 0; + pPhrase->pList = pCsr; + fts3GetDeltaPosition(&pCsr, &iFirst); + if( iFirst<0 ){ + rc = FTS_CORRUPT_VTAB; + }else{ + pPhrase->pHead = pCsr; + pPhrase->pTail = pCsr; + pPhrase->iHead = iFirst; + pPhrase->iTail = iFirst; + } + }else{ + assert( rc!=SQLITE_OK || ( + pPhrase->pList==0 && pPhrase->pHead==0 && pPhrase->pTail==0 + )); + } + + return rc; +} + +/* +** Select the fragment of text consisting of nFragment contiguous tokens +** from column iCol that represent the "best" snippet. The best snippet +** is the snippet with the highest score, where scores are calculated +** by adding: +** +** (a) +1 point for each occurrence of a matchable phrase in the snippet. +** +** (b) +1000 points for the first occurrence of each matchable phrase in +** the snippet for which the corresponding mCovered bit is not set. +** +** The selected snippet parameters are stored in structure *pFragment before +** returning. The score of the selected snippet is stored in *piScore +** before returning. +*/ +static int fts3BestSnippet( + int nSnippet, /* Desired snippet length */ + Fts3Cursor *pCsr, /* Cursor to create snippet for */ + int iCol, /* Index of column to create snippet from */ + u64 mCovered, /* Mask of phrases already covered */ + u64 *pmSeen, /* IN/OUT: Mask of phrases seen */ + SnippetFragment *pFragment, /* OUT: Best snippet found */ + int *piScore /* OUT: Score of snippet pFragment */ +){ + int rc; /* Return Code */ + int nList; /* Number of phrases in expression */ + SnippetIter sIter; /* Iterates through snippet candidates */ + sqlite3_int64 nByte; /* Number of bytes of space to allocate */ + int iBestScore = -1; /* Best snippet score found so far */ + int i; /* Loop counter */ + + memset(&sIter, 0, sizeof(sIter)); + + /* Iterate through the phrases in the expression to count them. The same + ** callback makes sure the doclists are loaded for each phrase. + */ + rc = fts3ExprLoadDoclists(pCsr, &nList, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + + /* Now that it is known how many phrases there are, allocate and zero + ** the required space using malloc(). + */ + nByte = sizeof(SnippetPhrase) * nList; + sIter.aPhrase = (SnippetPhrase *)sqlite3Fts3MallocZero(nByte); + if( !sIter.aPhrase ){ + return SQLITE_NOMEM; + } + + /* Initialize the contents of the SnippetIter object. Then iterate through + ** the set of phrases in the expression to populate the aPhrase[] array. + */ + sIter.pCsr = pCsr; + sIter.iCol = iCol; + sIter.nSnippet = nSnippet; + sIter.nPhrase = nList; + sIter.iCurrent = -1; + rc = sqlite3Fts3ExprIterate( + pCsr->pExpr, fts3SnippetFindPositions, (void*)&sIter + ); + if( rc==SQLITE_OK ){ + + /* Set the *pmSeen output variable. */ + for(i=0; iiCol = iCol; + while( !fts3SnippetNextCandidate(&sIter) ){ + int iPos; + int iScore; + u64 mCover; + u64 mHighlite; + fts3SnippetDetails(&sIter, mCovered, &iPos, &iScore, &mCover,&mHighlite); + assert( iScore>=0 ); + if( iScore>iBestScore ){ + pFragment->iPos = iPos; + pFragment->hlmask = mHighlite; + pFragment->covered = mCover; + iBestScore = iScore; + } + } + + *piScore = iBestScore; + } + sqlite3_free(sIter.aPhrase); + return rc; +} + + +/* +** Append a string to the string-buffer passed as the first argument. +** +** If nAppend is negative, then the length of the string zAppend is +** determined using strlen(). +*/ +static int fts3StringAppend( + StrBuffer *pStr, /* Buffer to append to */ + const char *zAppend, /* Pointer to data to append to buffer */ + int nAppend /* Size of zAppend in bytes (or -1) */ +){ + if( nAppend<0 ){ + nAppend = (int)strlen(zAppend); + } + + /* If there is insufficient space allocated at StrBuffer.z, use realloc() + ** to grow the buffer until so that it is big enough to accommodate the + ** appended data. + */ + if( (i64)pStr->n+(i64)nAppend+1>=(i64)pStr->nAlloc ){ + i64 nAlloc = pStr->nAlloc+(i64)nAppend+100; + char *zNew = sqlite3_realloc64(pStr->z, nAlloc); + if( !zNew ){ + return SQLITE_NOMEM; + } + pStr->z = zNew; + pStr->nAlloc = nAlloc; + } + assert( pStr->z!=0 && (pStr->nAlloc >= pStr->n+nAppend+1) ); + + /* Append the data to the string buffer. */ + memcpy(&pStr->z[pStr->n], zAppend, nAppend); + pStr->n += nAppend; + pStr->z[pStr->n] = '\0'; + + return SQLITE_OK; +} + +/* +** The fts3BestSnippet() function often selects snippets that end with a +** query term. That is, the final term of the snippet is always a term +** that requires highlighting. For example, if 'X' is a highlighted term +** and '.' is a non-highlighted term, BestSnippet() may select: +** +** ........X.....X +** +** This function "shifts" the beginning of the snippet forward in the +** document so that there are approximately the same number of +** non-highlighted terms to the right of the final highlighted term as there +** are to the left of the first highlighted term. For example, to this: +** +** ....X.....X.... +** +** This is done as part of extracting the snippet text, not when selecting +** the snippet. Snippet selection is done based on doclists only, so there +** is no way for fts3BestSnippet() to know whether or not the document +** actually contains terms that follow the final highlighted term. +*/ +static int fts3SnippetShift( + Fts3Table *pTab, /* FTS3 table snippet comes from */ + int iLangid, /* Language id to use in tokenizing */ + int nSnippet, /* Number of tokens desired for snippet */ + const char *zDoc, /* Document text to extract snippet from */ + int nDoc, /* Size of buffer zDoc in bytes */ + int *piPos, /* IN/OUT: First token of snippet */ + u64 *pHlmask /* IN/OUT: Mask of tokens to highlight */ +){ + u64 hlmask = *pHlmask; /* Local copy of initial highlight-mask */ + + if( hlmask ){ + int nLeft; /* Tokens to the left of first highlight */ + int nRight; /* Tokens to the right of last highlight */ + int nDesired; /* Ideal number of tokens to shift forward */ + + for(nLeft=0; !(hlmask & ((u64)1 << nLeft)); nLeft++); + for(nRight=0; !(hlmask & ((u64)1 << (nSnippet-1-nRight))); nRight++); + assert( (nSnippet-1-nRight)<=63 && (nSnippet-1-nRight)>=0 ); + nDesired = (nLeft-nRight)/2; + + /* Ideally, the start of the snippet should be pushed forward in the + ** document nDesired tokens. This block checks if there are actually + ** nDesired tokens to the right of the snippet. If so, *piPos and + ** *pHlMask are updated to shift the snippet nDesired tokens to the + ** right. Otherwise, the snippet is shifted by the number of tokens + ** available. + */ + if( nDesired>0 ){ + int nShift; /* Number of tokens to shift snippet by */ + int iCurrent = 0; /* Token counter */ + int rc; /* Return Code */ + sqlite3_tokenizer_module *pMod; + sqlite3_tokenizer_cursor *pC; + pMod = (sqlite3_tokenizer_module *)pTab->pTokenizer->pModule; + + /* Open a cursor on zDoc/nDoc. Check if there are (nSnippet+nDesired) + ** or more tokens in zDoc/nDoc. + */ + rc = sqlite3Fts3OpenTokenizer(pTab->pTokenizer, iLangid, zDoc, nDoc, &pC); + if( rc!=SQLITE_OK ){ + return rc; + } + while( rc==SQLITE_OK && iCurrent<(nSnippet+nDesired) ){ + const char *ZDUMMY; int DUMMY1 = 0, DUMMY2 = 0, DUMMY3 = 0; + rc = pMod->xNext(pC, &ZDUMMY, &DUMMY1, &DUMMY2, &DUMMY3, &iCurrent); + } + pMod->xClose(pC); + if( rc!=SQLITE_OK && rc!=SQLITE_DONE ){ return rc; } + + nShift = (rc==SQLITE_DONE)+iCurrent-nSnippet; + assert( nShift<=nDesired ); + if( nShift>0 ){ + *piPos += nShift; + *pHlmask = hlmask >> nShift; + } + } + } + return SQLITE_OK; +} + +/* +** Extract the snippet text for fragment pFragment from cursor pCsr and +** append it to string buffer pOut. +*/ +static int fts3SnippetText( + Fts3Cursor *pCsr, /* FTS3 Cursor */ + SnippetFragment *pFragment, /* Snippet to extract */ + int iFragment, /* Fragment number */ + int isLast, /* True for final fragment in snippet */ + int nSnippet, /* Number of tokens in extracted snippet */ + const char *zOpen, /* String inserted before highlighted term */ + const char *zClose, /* String inserted after highlighted term */ + const char *zEllipsis, /* String inserted between snippets */ + StrBuffer *pOut /* Write output here */ +){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int rc; /* Return code */ + const char *zDoc; /* Document text to extract snippet from */ + int nDoc; /* Size of zDoc in bytes */ + int iCurrent = 0; /* Current token number of document */ + int iEnd = 0; /* Byte offset of end of current token */ + int isShiftDone = 0; /* True after snippet is shifted */ + int iPos = pFragment->iPos; /* First token of snippet */ + u64 hlmask = pFragment->hlmask; /* Highlight-mask for snippet */ + int iCol = pFragment->iCol+1; /* Query column to extract text from */ + sqlite3_tokenizer_module *pMod; /* Tokenizer module methods object */ + sqlite3_tokenizer_cursor *pC; /* Tokenizer cursor open on zDoc/nDoc */ + + zDoc = (const char *)sqlite3_column_text(pCsr->pStmt, iCol); + if( zDoc==0 ){ + if( sqlite3_column_type(pCsr->pStmt, iCol)!=SQLITE_NULL ){ + return SQLITE_NOMEM; + } + return SQLITE_OK; + } + nDoc = sqlite3_column_bytes(pCsr->pStmt, iCol); + + /* Open a token cursor on the document. */ + pMod = (sqlite3_tokenizer_module *)pTab->pTokenizer->pModule; + rc = sqlite3Fts3OpenTokenizer(pTab->pTokenizer, pCsr->iLangid, zDoc,nDoc,&pC); + if( rc!=SQLITE_OK ){ + return rc; + } + + while( rc==SQLITE_OK ){ + const char *ZDUMMY; /* Dummy argument used with tokenizer */ + int DUMMY1 = -1; /* Dummy argument used with tokenizer */ + int iBegin = 0; /* Offset in zDoc of start of token */ + int iFin = 0; /* Offset in zDoc of end of token */ + int isHighlight = 0; /* True for highlighted terms */ + + /* Variable DUMMY1 is initialized to a negative value above. Elsewhere + ** in the FTS code the variable that the third argument to xNext points to + ** is initialized to zero before the first (*but not necessarily + ** subsequent*) call to xNext(). This is done for a particular application + ** that needs to know whether or not the tokenizer is being used for + ** snippet generation or for some other purpose. + ** + ** Extreme care is required when writing code to depend on this + ** initialization. It is not a documented part of the tokenizer interface. + ** If a tokenizer is used directly by any code outside of FTS, this + ** convention might not be respected. */ + rc = pMod->xNext(pC, &ZDUMMY, &DUMMY1, &iBegin, &iFin, &iCurrent); + if( rc!=SQLITE_OK ){ + if( rc==SQLITE_DONE ){ + /* Special case - the last token of the snippet is also the last token + ** of the column. Append any punctuation that occurred between the end + ** of the previous token and the end of the document to the output. + ** Then break out of the loop. */ + rc = fts3StringAppend(pOut, &zDoc[iEnd], -1); + } + break; + } + if( iCurrentiLangid, nSnippet, &zDoc[iBegin], n, &iPos, &hlmask + ); + isShiftDone = 1; + + /* Now that the shift has been done, check if the initial "..." are + ** required. They are required if (a) this is not the first fragment, + ** or (b) this fragment does not begin at position 0 of its column. + */ + if( rc==SQLITE_OK ){ + if( iPos>0 || iFragment>0 ){ + rc = fts3StringAppend(pOut, zEllipsis, -1); + }else if( iBegin ){ + rc = fts3StringAppend(pOut, zDoc, iBegin); + } + } + if( rc!=SQLITE_OK || iCurrent=(iPos+nSnippet) ){ + if( isLast ){ + rc = fts3StringAppend(pOut, zEllipsis, -1); + } + break; + } + + /* Set isHighlight to true if this term should be highlighted. */ + isHighlight = (hlmask & ((u64)1 << (iCurrent-iPos)))!=0; + + if( iCurrent>iPos ) rc = fts3StringAppend(pOut, &zDoc[iEnd], iBegin-iEnd); + if( rc==SQLITE_OK && isHighlight ) rc = fts3StringAppend(pOut, zOpen, -1); + if( rc==SQLITE_OK ) rc = fts3StringAppend(pOut, &zDoc[iBegin], iFin-iBegin); + if( rc==SQLITE_OK && isHighlight ) rc = fts3StringAppend(pOut, zClose, -1); + + iEnd = iFin; + } + + pMod->xClose(pC); + return rc; +} + + +/* +** This function is used to count the entries in a column-list (a +** delta-encoded list of term offsets within a single column of a single +** row). When this function is called, *ppCollist should point to the +** beginning of the first varint in the column-list (the varint that +** contains the position of the first matching term in the column data). +** Before returning, *ppCollist is set to point to the first byte after +** the last varint in the column-list (either the 0x00 signifying the end +** of the position-list, or the 0x01 that precedes the column number of +** the next column in the position-list). +** +** The number of elements in the column-list is returned. +*/ +static int fts3ColumnlistCount(char **ppCollist){ + char *pEnd = *ppCollist; + char c = 0; + int nEntry = 0; + + /* A column-list is terminated by either a 0x01 or 0x00. */ + while( 0xFE & (*pEnd | c) ){ + c = *pEnd++ & 0x80; + if( !c ) nEntry++; + } + + *ppCollist = pEnd; + return nEntry; +} + +/* +** This function gathers 'y' or 'b' data for a single phrase. +*/ +static int fts3ExprLHits( + Fts3Expr *pExpr, /* Phrase expression node */ + MatchInfo *p /* Matchinfo context */ +){ + Fts3Table *pTab = (Fts3Table *)p->pCursor->base.pVtab; + int iStart; + Fts3Phrase *pPhrase = pExpr->pPhrase; + char *pIter = pPhrase->doclist.pList; + int iCol = 0; + + assert( p->flag==FTS3_MATCHINFO_LHITS_BM || p->flag==FTS3_MATCHINFO_LHITS ); + if( p->flag==FTS3_MATCHINFO_LHITS ){ + iStart = pExpr->iPhrase * p->nCol; + }else{ + iStart = pExpr->iPhrase * ((p->nCol + 31) / 32); + } + + if( pIter ) while( 1 ){ + int nHit = fts3ColumnlistCount(&pIter); + if( (pPhrase->iColumn>=pTab->nColumn || pPhrase->iColumn==iCol) ){ + if( p->flag==FTS3_MATCHINFO_LHITS ){ + p->aMatchinfo[iStart + iCol] = (u32)nHit; + }else if( nHit ){ + p->aMatchinfo[iStart + iCol/32] |= (1U << (iCol&0x1F)); + } + } + assert( *pIter==0x00 || *pIter==0x01 ); + if( *pIter!=0x01 ) break; + pIter++; + pIter += fts3GetVarint32(pIter, &iCol); + if( iCol>=p->nCol ) return FTS_CORRUPT_VTAB; + } + return SQLITE_OK; +} + +/* +** Gather the results for matchinfo directives 'y' and 'b'. +*/ +static int fts3ExprLHitGather( + Fts3Expr *pExpr, + MatchInfo *p +){ + int rc = SQLITE_OK; + assert( (pExpr->pLeft==0)==(pExpr->pRight==0) ); + if( pExpr->bEof==0 && pExpr->iDocid==p->pCursor->iPrevId ){ + if( pExpr->pLeft ){ + rc = fts3ExprLHitGather(pExpr->pLeft, p); + if( rc==SQLITE_OK ) rc = fts3ExprLHitGather(pExpr->pRight, p); + }else{ + rc = fts3ExprLHits(pExpr, p); + } + } + return rc; +} + +/* +** sqlite3Fts3ExprIterate() callback used to collect the "global" matchinfo +** stats for a single query. +** +** sqlite3Fts3ExprIterate() callback to load the 'global' elements of a +** FTS3_MATCHINFO_HITS matchinfo array. The global stats are those elements +** of the matchinfo array that are constant for all rows returned by the +** current query. +** +** Argument pCtx is actually a pointer to a struct of type MatchInfo. This +** function populates Matchinfo.aMatchinfo[] as follows: +** +** for(iCol=0; iColpCursor, pExpr, &p->aMatchinfo[3*iPhrase*p->nCol] + ); +} + +/* +** sqlite3Fts3ExprIterate() callback used to collect the "local" part of the +** FTS3_MATCHINFO_HITS array. The local stats are those elements of the +** array that are different for each row returned by the query. +*/ +static int fts3ExprLocalHitsCb( + Fts3Expr *pExpr, /* Phrase expression node */ + int iPhrase, /* Phrase number */ + void *pCtx /* Pointer to MatchInfo structure */ +){ + int rc = SQLITE_OK; + MatchInfo *p = (MatchInfo *)pCtx; + int iStart = iPhrase * p->nCol * 3; + int i; + + for(i=0; inCol && rc==SQLITE_OK; i++){ + char *pCsr; + rc = sqlite3Fts3EvalPhrasePoslist(p->pCursor, pExpr, i, &pCsr); + if( pCsr ){ + p->aMatchinfo[iStart+i*3] = fts3ColumnlistCount(&pCsr); + }else{ + p->aMatchinfo[iStart+i*3] = 0; + } + } + + return rc; +} + +static int fts3MatchinfoCheck( + Fts3Table *pTab, + char cArg, + char **pzErr +){ + if( (cArg==FTS3_MATCHINFO_NPHRASE) + || (cArg==FTS3_MATCHINFO_NCOL) + || (cArg==FTS3_MATCHINFO_NDOC && pTab->bFts4) + || (cArg==FTS3_MATCHINFO_AVGLENGTH && pTab->bFts4) + || (cArg==FTS3_MATCHINFO_LENGTH && pTab->bHasDocsize) + || (cArg==FTS3_MATCHINFO_LCS) + || (cArg==FTS3_MATCHINFO_HITS) + || (cArg==FTS3_MATCHINFO_LHITS) + || (cArg==FTS3_MATCHINFO_LHITS_BM) + ){ + return SQLITE_OK; + } + sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo request: %c", cArg); + return SQLITE_ERROR; +} + +static size_t fts3MatchinfoSize(MatchInfo *pInfo, char cArg){ + size_t nVal; /* Number of integers output by cArg */ + + switch( cArg ){ + case FTS3_MATCHINFO_NDOC: + case FTS3_MATCHINFO_NPHRASE: + case FTS3_MATCHINFO_NCOL: + nVal = 1; + break; + + case FTS3_MATCHINFO_AVGLENGTH: + case FTS3_MATCHINFO_LENGTH: + case FTS3_MATCHINFO_LCS: + nVal = pInfo->nCol; + break; + + case FTS3_MATCHINFO_LHITS: + nVal = (size_t)pInfo->nCol * pInfo->nPhrase; + break; + + case FTS3_MATCHINFO_LHITS_BM: + nVal = (size_t)pInfo->nPhrase * ((pInfo->nCol + 31) / 32); + break; + + default: + assert( cArg==FTS3_MATCHINFO_HITS ); + nVal = (size_t)pInfo->nCol * pInfo->nPhrase * 3; + break; + } + + return nVal; +} + +static int fts3MatchinfoSelectDoctotal( + Fts3Table *pTab, + sqlite3_stmt **ppStmt, + sqlite3_int64 *pnDoc, + const char **paLen, + const char **ppEnd +){ + sqlite3_stmt *pStmt; + const char *a; + const char *pEnd; + sqlite3_int64 nDoc; + int n; + + + if( !*ppStmt ){ + int rc = sqlite3Fts3SelectDoctotal(pTab, ppStmt); + if( rc!=SQLITE_OK ) return rc; + } + pStmt = *ppStmt; + assert( sqlite3_data_count(pStmt)==1 ); + + n = sqlite3_column_bytes(pStmt, 0); + a = sqlite3_column_blob(pStmt, 0); + if( a==0 ){ + return FTS_CORRUPT_VTAB; + } + pEnd = a + n; + a += sqlite3Fts3GetVarintBounded(a, pEnd, &nDoc); + if( nDoc<=0 || a>pEnd ){ + return FTS_CORRUPT_VTAB; + } + *pnDoc = nDoc; + + if( paLen ) *paLen = a; + if( ppEnd ) *ppEnd = pEnd; + return SQLITE_OK; +} + +/* +** An instance of the following structure is used to store state while +** iterating through a multi-column position-list corresponding to the +** hits for a single phrase on a single row in order to calculate the +** values for a matchinfo() FTS3_MATCHINFO_LCS request. +*/ +typedef struct LcsIterator LcsIterator; +struct LcsIterator { + Fts3Expr *pExpr; /* Pointer to phrase expression */ + int iPosOffset; /* Tokens count up to end of this phrase */ + char *pRead; /* Cursor used to iterate through aDoclist */ + int iPos; /* Current position */ +}; + +/* +** If LcsIterator.iCol is set to the following value, the iterator has +** finished iterating through all offsets for all columns. +*/ +#define LCS_ITERATOR_FINISHED 0x7FFFFFFF; + +static int fts3MatchinfoLcsCb( + Fts3Expr *pExpr, /* Phrase expression node */ + int iPhrase, /* Phrase number (numbered from zero) */ + void *pCtx /* Pointer to MatchInfo structure */ +){ + LcsIterator *aIter = (LcsIterator *)pCtx; + aIter[iPhrase].pExpr = pExpr; + return SQLITE_OK; +} + +/* +** Advance the iterator passed as an argument to the next position. Return +** 1 if the iterator is at EOF or if it now points to the start of the +** position list for the next column. +*/ +static int fts3LcsIteratorAdvance(LcsIterator *pIter){ + char *pRead; + sqlite3_int64 iRead; + int rc = 0; + + if( NEVER(pIter==0) ) return 1; + pRead = pIter->pRead; + pRead += sqlite3Fts3GetVarint(pRead, &iRead); + if( iRead==0 || iRead==1 ){ + pRead = 0; + rc = 1; + }else{ + pIter->iPos += (int)(iRead-2); + } + + pIter->pRead = pRead; + return rc; +} + +/* +** This function implements the FTS3_MATCHINFO_LCS matchinfo() flag. +** +** If the call is successful, the longest-common-substring lengths for each +** column are written into the first nCol elements of the pInfo->aMatchinfo[] +** array before returning. SQLITE_OK is returned in this case. +** +** Otherwise, if an error occurs, an SQLite error code is returned and the +** data written to the first nCol elements of pInfo->aMatchinfo[] is +** undefined. +*/ +static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){ + LcsIterator *aIter; + int i; + int iCol; + int nToken = 0; + int rc = SQLITE_OK; + + /* Allocate and populate the array of LcsIterator objects. The array + ** contains one element for each matchable phrase in the query. + **/ + aIter = sqlite3Fts3MallocZero(sizeof(LcsIterator) * pCsr->nPhrase); + if( !aIter ) return SQLITE_NOMEM; + (void)sqlite3Fts3ExprIterate(pCsr->pExpr, fts3MatchinfoLcsCb, (void*)aIter); + + for(i=0; inPhrase; i++){ + LcsIterator *pIter = &aIter[i]; + nToken -= pIter->pExpr->pPhrase->nToken; + pIter->iPosOffset = nToken; + } + + for(iCol=0; iColnCol; iCol++){ + int nLcs = 0; /* LCS value for this column */ + int nLive = 0; /* Number of iterators in aIter not at EOF */ + + for(i=0; inPhrase; i++){ + LcsIterator *pIt = &aIter[i]; + rc = sqlite3Fts3EvalPhrasePoslist(pCsr, pIt->pExpr, iCol, &pIt->pRead); + if( rc!=SQLITE_OK ) goto matchinfo_lcs_out; + if( pIt->pRead ){ + pIt->iPos = pIt->iPosOffset; + fts3LcsIteratorAdvance(pIt); + if( pIt->pRead==0 ){ + rc = FTS_CORRUPT_VTAB; + goto matchinfo_lcs_out; + } + nLive++; + } + } + + while( nLive>0 ){ + LcsIterator *pAdv = 0; /* The iterator to advance by one position */ + int nThisLcs = 0; /* LCS for the current iterator positions */ + + for(i=0; inPhrase; i++){ + LcsIterator *pIter = &aIter[i]; + if( pIter->pRead==0 ){ + /* This iterator is already at EOF for this column. */ + nThisLcs = 0; + }else{ + if( pAdv==0 || pIter->iPosiPos ){ + pAdv = pIter; + } + if( nThisLcs==0 || pIter->iPos==pIter[-1].iPos ){ + nThisLcs++; + }else{ + nThisLcs = 1; + } + if( nThisLcs>nLcs ) nLcs = nThisLcs; + } + } + if( fts3LcsIteratorAdvance(pAdv) ) nLive--; + } + + pInfo->aMatchinfo[iCol] = nLcs; + } + + matchinfo_lcs_out: + sqlite3_free(aIter); + return rc; +} + +/* +** Populate the buffer pInfo->aMatchinfo[] with an array of integers to +** be returned by the matchinfo() function. Argument zArg contains the +** format string passed as the second argument to matchinfo (or the +** default value "pcx" if no second argument was specified). The format +** string has already been validated and the pInfo->aMatchinfo[] array +** is guaranteed to be large enough for the output. +** +** If bGlobal is true, then populate all fields of the matchinfo() output. +** If it is false, then assume that those fields that do not change between +** rows (i.e. FTS3_MATCHINFO_NPHRASE, NCOL, NDOC, AVGLENGTH and part of HITS) +** have already been populated. +** +** Return SQLITE_OK if successful, or an SQLite error code if an error +** occurs. If a value other than SQLITE_OK is returned, the state the +** pInfo->aMatchinfo[] buffer is left in is undefined. +*/ +static int fts3MatchinfoValues( + Fts3Cursor *pCsr, /* FTS3 cursor object */ + int bGlobal, /* True to grab the global stats */ + MatchInfo *pInfo, /* Matchinfo context object */ + const char *zArg /* Matchinfo format string */ +){ + int rc = SQLITE_OK; + int i; + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + sqlite3_stmt *pSelect = 0; + + for(i=0; rc==SQLITE_OK && zArg[i]; i++){ + pInfo->flag = zArg[i]; + switch( zArg[i] ){ + case FTS3_MATCHINFO_NPHRASE: + if( bGlobal ) pInfo->aMatchinfo[0] = pInfo->nPhrase; + break; + + case FTS3_MATCHINFO_NCOL: + if( bGlobal ) pInfo->aMatchinfo[0] = pInfo->nCol; + break; + + case FTS3_MATCHINFO_NDOC: + if( bGlobal ){ + sqlite3_int64 nDoc = 0; + rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, 0, 0); + pInfo->aMatchinfo[0] = (u32)nDoc; + } + break; + + case FTS3_MATCHINFO_AVGLENGTH: + if( bGlobal ){ + sqlite3_int64 nDoc; /* Number of rows in table */ + const char *a; /* Aggregate column length array */ + const char *pEnd; /* First byte past end of length array */ + + rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, &a, &pEnd); + if( rc==SQLITE_OK ){ + int iCol; + for(iCol=0; iColnCol; iCol++){ + u32 iVal; + sqlite3_int64 nToken; + a += sqlite3Fts3GetVarint(a, &nToken); + if( a>pEnd ){ + rc = SQLITE_CORRUPT_VTAB; + break; + } + iVal = (u32)(((u32)(nToken&0xffffffff)+nDoc/2)/nDoc); + pInfo->aMatchinfo[iCol] = iVal; + } + } + } + break; + + case FTS3_MATCHINFO_LENGTH: { + sqlite3_stmt *pSelectDocsize = 0; + rc = sqlite3Fts3SelectDocsize(pTab, pCsr->iPrevId, &pSelectDocsize); + if( rc==SQLITE_OK ){ + int iCol; + const char *a = sqlite3_column_blob(pSelectDocsize, 0); + const char *pEnd = a + sqlite3_column_bytes(pSelectDocsize, 0); + for(iCol=0; iColnCol; iCol++){ + sqlite3_int64 nToken; + a += sqlite3Fts3GetVarintBounded(a, pEnd, &nToken); + if( a>pEnd ){ + rc = SQLITE_CORRUPT_VTAB; + break; + } + pInfo->aMatchinfo[iCol] = (u32)nToken; + } + } + sqlite3_reset(pSelectDocsize); + break; + } + + case FTS3_MATCHINFO_LCS: + rc = fts3ExprLoadDoclists(pCsr, 0, 0); + if( rc==SQLITE_OK ){ + rc = fts3MatchinfoLcs(pCsr, pInfo); + } + break; + + case FTS3_MATCHINFO_LHITS_BM: + case FTS3_MATCHINFO_LHITS: { + size_t nZero = fts3MatchinfoSize(pInfo, zArg[i]) * sizeof(u32); + memset(pInfo->aMatchinfo, 0, nZero); + rc = fts3ExprLHitGather(pCsr->pExpr, pInfo); + break; + } + + default: { + Fts3Expr *pExpr; + assert( zArg[i]==FTS3_MATCHINFO_HITS ); + pExpr = pCsr->pExpr; + rc = fts3ExprLoadDoclists(pCsr, 0, 0); + if( rc!=SQLITE_OK ) break; + if( bGlobal ){ + if( pCsr->pDeferred ){ + rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &pInfo->nDoc,0,0); + if( rc!=SQLITE_OK ) break; + } + rc = sqlite3Fts3ExprIterate(pExpr, fts3ExprGlobalHitsCb,(void*)pInfo); + sqlite3Fts3EvalTestDeferred(pCsr, &rc); + if( rc!=SQLITE_OK ) break; + } + (void)sqlite3Fts3ExprIterate(pExpr, fts3ExprLocalHitsCb,(void*)pInfo); + break; + } + } + + pInfo->aMatchinfo += fts3MatchinfoSize(pInfo, zArg[i]); + } + + sqlite3_reset(pSelect); + return rc; +} + + +/* +** Populate pCsr->aMatchinfo[] with data for the current row. The +** 'matchinfo' data is an array of 32-bit unsigned integers (C type u32). +*/ +static void fts3GetMatchinfo( + sqlite3_context *pCtx, /* Return results here */ + Fts3Cursor *pCsr, /* FTS3 Cursor object */ + const char *zArg /* Second argument to matchinfo() function */ +){ + MatchInfo sInfo; + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int rc = SQLITE_OK; + int bGlobal = 0; /* Collect 'global' stats as well as local */ + + u32 *aOut = 0; + void (*xDestroyOut)(void*) = 0; + + memset(&sInfo, 0, sizeof(MatchInfo)); + sInfo.pCursor = pCsr; + sInfo.nCol = pTab->nColumn; + + /* If there is cached matchinfo() data, but the format string for the + ** cache does not match the format string for this request, discard + ** the cached data. */ + if( pCsr->pMIBuffer && strcmp(pCsr->pMIBuffer->zMatchinfo, zArg) ){ + sqlite3Fts3MIBufferFree(pCsr->pMIBuffer); + pCsr->pMIBuffer = 0; + } + + /* If Fts3Cursor.pMIBuffer is NULL, then this is the first time the + ** matchinfo function has been called for this query. In this case + ** allocate the array used to accumulate the matchinfo data and + ** initialize those elements that are constant for every row. + */ + if( pCsr->pMIBuffer==0 ){ + size_t nMatchinfo = 0; /* Number of u32 elements in match-info */ + int i; /* Used to iterate through zArg */ + + /* Determine the number of phrases in the query */ + pCsr->nPhrase = fts3ExprPhraseCount(pCsr->pExpr); + sInfo.nPhrase = pCsr->nPhrase; + + /* Determine the number of integers in the buffer returned by this call. */ + for(i=0; zArg[i]; i++){ + char *zErr = 0; + if( fts3MatchinfoCheck(pTab, zArg[i], &zErr) ){ + sqlite3_result_error(pCtx, zErr, -1); + sqlite3_free(zErr); + return; + } + nMatchinfo += fts3MatchinfoSize(&sInfo, zArg[i]); + } + + /* Allocate space for Fts3Cursor.aMatchinfo[] and Fts3Cursor.zMatchinfo. */ + pCsr->pMIBuffer = fts3MIBufferNew(nMatchinfo, zArg); + if( !pCsr->pMIBuffer ) rc = SQLITE_NOMEM; + + pCsr->isMatchinfoNeeded = 1; + bGlobal = 1; + } + + if( rc==SQLITE_OK ){ + xDestroyOut = fts3MIBufferAlloc(pCsr->pMIBuffer, &aOut); + if( xDestroyOut==0 ){ + rc = SQLITE_NOMEM; + } + } + + if( rc==SQLITE_OK ){ + sInfo.aMatchinfo = aOut; + sInfo.nPhrase = pCsr->nPhrase; + rc = fts3MatchinfoValues(pCsr, bGlobal, &sInfo, zArg); + if( bGlobal ){ + fts3MIBufferSetGlobal(pCsr->pMIBuffer); + } + } + + if( rc!=SQLITE_OK ){ + sqlite3_result_error_code(pCtx, rc); + if( xDestroyOut ) xDestroyOut(aOut); + }else{ + int n = pCsr->pMIBuffer->nElem * sizeof(u32); + sqlite3_result_blob(pCtx, aOut, n, xDestroyOut); + } +} + +/* +** Implementation of snippet() function. +*/ +SQLITE_PRIVATE void sqlite3Fts3Snippet( + sqlite3_context *pCtx, /* SQLite function call context */ + Fts3Cursor *pCsr, /* Cursor object */ + const char *zStart, /* Snippet start text - "" */ + const char *zEnd, /* Snippet end text - "" */ + const char *zEllipsis, /* Snippet ellipsis text - "..." */ + int iCol, /* Extract snippet from this column */ + int nToken /* Approximate number of tokens in snippet */ +){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + int rc = SQLITE_OK; + int i; + StrBuffer res = {0, 0, 0}; + + /* The returned text includes up to four fragments of text extracted from + ** the data in the current row. The first iteration of the for(...) loop + ** below attempts to locate a single fragment of text nToken tokens in + ** size that contains at least one instance of all phrases in the query + ** expression that appear in the current row. If such a fragment of text + ** cannot be found, the second iteration of the loop attempts to locate + ** a pair of fragments, and so on. + */ + int nSnippet = 0; /* Number of fragments in this snippet */ + SnippetFragment aSnippet[4]; /* Maximum of 4 fragments per snippet */ + int nFToken = -1; /* Number of tokens in each fragment */ + + if( !pCsr->pExpr ){ + sqlite3_result_text(pCtx, "", 0, SQLITE_STATIC); + return; + } + + /* Limit the snippet length to 64 tokens. */ + if( nToken<-64 ) nToken = -64; + if( nToken>+64 ) nToken = +64; + + for(nSnippet=1; 1; nSnippet++){ + + int iSnip; /* Loop counter 0..nSnippet-1 */ + u64 mCovered = 0; /* Bitmask of phrases covered by snippet */ + u64 mSeen = 0; /* Bitmask of phrases seen by BestSnippet() */ + + if( nToken>=0 ){ + nFToken = (nToken+nSnippet-1) / nSnippet; + }else{ + nFToken = -1 * nToken; + } + + for(iSnip=0; iSnipnColumn; iRead++){ + SnippetFragment sF = {0, 0, 0, 0}; + int iS = 0; + if( iCol>=0 && iRead!=iCol ) continue; + + /* Find the best snippet of nFToken tokens in column iRead. */ + rc = fts3BestSnippet(nFToken, pCsr, iRead, mCovered, &mSeen, &sF, &iS); + if( rc!=SQLITE_OK ){ + goto snippet_out; + } + if( iS>iBestScore ){ + *pFragment = sF; + iBestScore = iS; + } + } + + mCovered |= pFragment->covered; + } + + /* If all query phrases seen by fts3BestSnippet() are present in at least + ** one of the nSnippet snippet fragments, break out of the loop. + */ + assert( (mCovered&mSeen)==mCovered ); + if( mSeen==mCovered || nSnippet==SizeofArray(aSnippet) ) break; + } + + assert( nFToken>0 ); + + for(i=0; ipCsr, pExpr, p->iCol, &pList); + nTerm = pExpr->pPhrase->nToken; + if( pList ){ + fts3GetDeltaPosition(&pList, &iPos); + assert_fts3_nc( iPos>=0 ); + } + + for(iTerm=0; iTermaTerm[p->iTerm++]; + pT->iOff = nTerm-iTerm-1; + pT->pList = pList; + pT->iPos = iPos; + } + + return rc; +} + +/* +** If expression pExpr is a phrase expression that uses an MSR query, +** restart it as a regular, non-incremental query. Return SQLITE_OK +** if successful, or an SQLite error code otherwise. +*/ +static int fts3ExprRestartIfCb(Fts3Expr *pExpr, int iPhrase, void *ctx){ + TermOffsetCtx *p = (TermOffsetCtx*)ctx; + int rc = SQLITE_OK; + UNUSED_PARAMETER(iPhrase); + if( pExpr->pPhrase && pExpr->pPhrase->bIncr ){ + rc = sqlite3Fts3MsrCancel(p->pCsr, pExpr); + pExpr->pPhrase->bIncr = 0; + } + return rc; +} + +/* +** Implementation of offsets() function. +*/ +SQLITE_PRIVATE void sqlite3Fts3Offsets( + sqlite3_context *pCtx, /* SQLite function call context */ + Fts3Cursor *pCsr /* Cursor object */ +){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + sqlite3_tokenizer_module const *pMod = pTab->pTokenizer->pModule; + int rc; /* Return Code */ + int nToken; /* Number of tokens in query */ + int iCol; /* Column currently being processed */ + StrBuffer res = {0, 0, 0}; /* Result string */ + TermOffsetCtx sCtx; /* Context for fts3ExprTermOffsetInit() */ + + if( !pCsr->pExpr ){ + sqlite3_result_text(pCtx, "", 0, SQLITE_STATIC); + return; + } + + memset(&sCtx, 0, sizeof(sCtx)); + assert( pCsr->isRequireSeek==0 ); + + /* Count the number of terms in the query */ + rc = fts3ExprLoadDoclists(pCsr, 0, &nToken); + if( rc!=SQLITE_OK ) goto offsets_out; + + /* Allocate the array of TermOffset iterators. */ + sCtx.aTerm = (TermOffset *)sqlite3Fts3MallocZero(sizeof(TermOffset)*nToken); + if( 0==sCtx.aTerm ){ + rc = SQLITE_NOMEM; + goto offsets_out; + } + sCtx.iDocid = pCsr->iPrevId; + sCtx.pCsr = pCsr; + + /* If a query restart will be required, do it here, rather than later of + ** after pointers to poslist buffers that may be invalidated by a restart + ** have been saved. */ + rc = sqlite3Fts3ExprIterate(pCsr->pExpr, fts3ExprRestartIfCb, (void*)&sCtx); + if( rc!=SQLITE_OK ) goto offsets_out; + + /* Loop through the table columns, appending offset information to + ** string-buffer res for each column. + */ + for(iCol=0; iColnColumn; iCol++){ + sqlite3_tokenizer_cursor *pC; /* Tokenizer cursor */ + const char *ZDUMMY; /* Dummy argument used with xNext() */ + int NDUMMY = 0; /* Dummy argument used with xNext() */ + int iStart = 0; + int iEnd = 0; + int iCurrent = 0; + const char *zDoc; + int nDoc; + + /* Initialize the contents of sCtx.aTerm[] for column iCol. This + ** operation may fail if the database contains corrupt records. + */ + sCtx.iCol = iCol; + sCtx.iTerm = 0; + rc = sqlite3Fts3ExprIterate( + pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx + ); + if( rc!=SQLITE_OK ) goto offsets_out; + + /* Retreive the text stored in column iCol. If an SQL NULL is stored + ** in column iCol, jump immediately to the next iteration of the loop. + ** If an OOM occurs while retrieving the data (this can happen if SQLite + ** needs to transform the data from utf-16 to utf-8), return SQLITE_NOMEM + ** to the caller. + */ + zDoc = (const char *)sqlite3_column_text(pCsr->pStmt, iCol+1); + nDoc = sqlite3_column_bytes(pCsr->pStmt, iCol+1); + if( zDoc==0 ){ + if( sqlite3_column_type(pCsr->pStmt, iCol+1)==SQLITE_NULL ){ + continue; + } + rc = SQLITE_NOMEM; + goto offsets_out; + } + + /* Initialize a tokenizer iterator to iterate through column iCol. */ + rc = sqlite3Fts3OpenTokenizer(pTab->pTokenizer, pCsr->iLangid, + zDoc, nDoc, &pC + ); + if( rc!=SQLITE_OK ) goto offsets_out; + + rc = pMod->xNext(pC, &ZDUMMY, &NDUMMY, &iStart, &iEnd, &iCurrent); + while( rc==SQLITE_OK ){ + int i; /* Used to loop through terms */ + int iMinPos = 0x7FFFFFFF; /* Position of next token */ + TermOffset *pTerm = 0; /* TermOffset associated with next token */ + + for(i=0; ipList && (pT->iPos-pT->iOff)iPos-pT->iOff; + pTerm = pT; + } + } + + if( !pTerm ){ + /* All offsets for this column have been gathered. */ + rc = SQLITE_DONE; + }else{ + assert_fts3_nc( iCurrent<=iMinPos ); + if( 0==(0xFE&*pTerm->pList) ){ + pTerm->pList = 0; + }else{ + fts3GetDeltaPosition(&pTerm->pList, &pTerm->iPos); + } + while( rc==SQLITE_OK && iCurrentxNext(pC, &ZDUMMY, &NDUMMY, &iStart, &iEnd, &iCurrent); + } + if( rc==SQLITE_OK ){ + char aBuffer[64]; + sqlite3_snprintf(sizeof(aBuffer), aBuffer, + "%d %d %d %d ", iCol, pTerm-sCtx.aTerm, iStart, iEnd-iStart + ); + rc = fts3StringAppend(&res, aBuffer, -1); + }else if( rc==SQLITE_DONE && pTab->zContentTbl==0 ){ + rc = FTS_CORRUPT_VTAB; + } + } + } + if( rc==SQLITE_DONE ){ + rc = SQLITE_OK; + } + + pMod->xClose(pC); + if( rc!=SQLITE_OK ) goto offsets_out; + } + + offsets_out: + sqlite3_free(sCtx.aTerm); + assert( rc!=SQLITE_DONE ); + sqlite3Fts3SegmentsClose(pTab); + if( rc!=SQLITE_OK ){ + sqlite3_result_error_code(pCtx, rc); + sqlite3_free(res.z); + }else{ + sqlite3_result_text(pCtx, res.z, res.n-1, sqlite3_free); + } + return; +} + +/* +** Implementation of matchinfo() function. +*/ +SQLITE_PRIVATE void sqlite3Fts3Matchinfo( + sqlite3_context *pContext, /* Function call context */ + Fts3Cursor *pCsr, /* FTS3 table cursor */ + const char *zArg /* Second arg to matchinfo() function */ +){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + const char *zFormat; + + if( zArg ){ + zFormat = zArg; + }else{ + zFormat = FTS3_MATCHINFO_DEFAULT; + } + + if( !pCsr->pExpr ){ + sqlite3_result_blob(pContext, "", 0, SQLITE_STATIC); + return; + }else{ + /* Retrieve matchinfo() data. */ + fts3GetMatchinfo(pContext, pCsr, zFormat); + sqlite3Fts3SegmentsClose(pTab); + } +} + +#endif + +/************** End of fts3_snippet.c ****************************************/ +/************** Begin file fts3_unicode.c ************************************/ +/* +** 2012 May 24 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** Implementation of the "unicode" full-text-search tokenizer. +*/ + +#ifndef SQLITE_DISABLE_FTS3_UNICODE + +/* #include "fts3Int.h" */ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) + +/* #include */ +/* #include */ +/* #include */ +/* #include */ + +/* #include "fts3_tokenizer.h" */ + +/* +** The following two macros - READ_UTF8 and WRITE_UTF8 - have been copied +** from the sqlite3 source file utf.c. If this file is compiled as part +** of the amalgamation, they are not required. +*/ +#ifndef SQLITE_AMALGAMATION + +static const unsigned char sqlite3Utf8Trans1[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00, +}; + +#define READ_UTF8(zIn, zTerm, c) \ + c = *(zIn++); \ + if( c>=0xc0 ){ \ + c = sqlite3Utf8Trans1[c-0xc0]; \ + while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \ + c = (c<<6) + (0x3f & *(zIn++)); \ + } \ + if( c<0x80 \ + || (c&0xFFFFF800)==0xD800 \ + || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \ + } + +#define WRITE_UTF8(zOut, c) { \ + if( c<0x00080 ){ \ + *zOut++ = (u8)(c&0xFF); \ + } \ + else if( c<0x00800 ){ \ + *zOut++ = 0xC0 + (u8)((c>>6)&0x1F); \ + *zOut++ = 0x80 + (u8)(c & 0x3F); \ + } \ + else if( c<0x10000 ){ \ + *zOut++ = 0xE0 + (u8)((c>>12)&0x0F); \ + *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \ + *zOut++ = 0x80 + (u8)(c & 0x3F); \ + }else{ \ + *zOut++ = 0xF0 + (u8)((c>>18) & 0x07); \ + *zOut++ = 0x80 + (u8)((c>>12) & 0x3F); \ + *zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \ + *zOut++ = 0x80 + (u8)(c & 0x3F); \ + } \ +} + +#endif /* ifndef SQLITE_AMALGAMATION */ + +typedef struct unicode_tokenizer unicode_tokenizer; +typedef struct unicode_cursor unicode_cursor; + +struct unicode_tokenizer { + sqlite3_tokenizer base; + int eRemoveDiacritic; + int nException; + int *aiException; +}; + +struct unicode_cursor { + sqlite3_tokenizer_cursor base; + const unsigned char *aInput; /* Input text being tokenized */ + int nInput; /* Size of aInput[] in bytes */ + int iOff; /* Current offset within aInput[] */ + int iToken; /* Index of next token to be returned */ + char *zToken; /* storage for current token */ + int nAlloc; /* space allocated at zToken */ +}; + + +/* +** Destroy a tokenizer allocated by unicodeCreate(). +*/ +static int unicodeDestroy(sqlite3_tokenizer *pTokenizer){ + if( pTokenizer ){ + unicode_tokenizer *p = (unicode_tokenizer *)pTokenizer; + sqlite3_free(p->aiException); + sqlite3_free(p); + } + return SQLITE_OK; +} + +/* +** As part of a tokenchars= or separators= option, the CREATE VIRTUAL TABLE +** statement has specified that the tokenizer for this table shall consider +** all characters in string zIn/nIn to be separators (if bAlnum==0) or +** token characters (if bAlnum==1). +** +** For each codepoint in the zIn/nIn string, this function checks if the +** sqlite3FtsUnicodeIsalnum() function already returns the desired result. +** If so, no action is taken. Otherwise, the codepoint is added to the +** unicode_tokenizer.aiException[] array. For the purposes of tokenization, +** the return value of sqlite3FtsUnicodeIsalnum() is inverted for all +** codepoints in the aiException[] array. +** +** If a standalone diacritic mark (one that sqlite3FtsUnicodeIsdiacritic() +** identifies as a diacritic) occurs in the zIn/nIn string it is ignored. +** It is not possible to change the behavior of the tokenizer with respect +** to these codepoints. +*/ +static int unicodeAddExceptions( + unicode_tokenizer *p, /* Tokenizer to add exceptions to */ + int bAlnum, /* Replace Isalnum() return value with this */ + const char *zIn, /* Array of characters to make exceptions */ + int nIn /* Length of z in bytes */ +){ + const unsigned char *z = (const unsigned char *)zIn; + const unsigned char *zTerm = &z[nIn]; + unsigned int iCode; + int nEntry = 0; + + assert( bAlnum==0 || bAlnum==1 ); + + while( zaiException,(p->nException+nEntry)*sizeof(int)); + if( aNew==0 ) return SQLITE_NOMEM; + nNew = p->nException; + + z = (const unsigned char *)zIn; + while( zi; j--) aNew[j] = aNew[j-1]; + aNew[i] = (int)iCode; + nNew++; + } + } + p->aiException = aNew; + p->nException = nNew; + } + + return SQLITE_OK; +} + +/* +** Return true if the p->aiException[] array contains the value iCode. +*/ +static int unicodeIsException(unicode_tokenizer *p, int iCode){ + if( p->nException>0 ){ + int *a = p->aiException; + int iLo = 0; + int iHi = p->nException-1; + + while( iHi>=iLo ){ + int iTest = (iHi + iLo) / 2; + if( iCode==a[iTest] ){ + return 1; + }else if( iCode>a[iTest] ){ + iLo = iTest+1; + }else{ + iHi = iTest-1; + } + } + } + + return 0; +} + +/* +** Return true if, for the purposes of tokenization, codepoint iCode is +** considered a token character (not a separator). +*/ +static int unicodeIsAlnum(unicode_tokenizer *p, int iCode){ + assert( (sqlite3FtsUnicodeIsalnum(iCode) & 0xFFFFFFFE)==0 ); + return sqlite3FtsUnicodeIsalnum(iCode) ^ unicodeIsException(p, iCode); +} + +/* +** Create a new tokenizer instance. +*/ +static int unicodeCreate( + int nArg, /* Size of array argv[] */ + const char * const *azArg, /* Tokenizer creation arguments */ + sqlite3_tokenizer **pp /* OUT: New tokenizer handle */ +){ + unicode_tokenizer *pNew; /* New tokenizer object */ + int i; + int rc = SQLITE_OK; + + pNew = (unicode_tokenizer *) sqlite3_malloc(sizeof(unicode_tokenizer)); + if( pNew==NULL ) return SQLITE_NOMEM; + memset(pNew, 0, sizeof(unicode_tokenizer)); + pNew->eRemoveDiacritic = 1; + + for(i=0; rc==SQLITE_OK && ieRemoveDiacritic = 1; + } + else if( n==19 && memcmp("remove_diacritics=0", z, 19)==0 ){ + pNew->eRemoveDiacritic = 0; + } + else if( n==19 && memcmp("remove_diacritics=2", z, 19)==0 ){ + pNew->eRemoveDiacritic = 2; + } + else if( n>=11 && memcmp("tokenchars=", z, 11)==0 ){ + rc = unicodeAddExceptions(pNew, 1, &z[11], n-11); + } + else if( n>=11 && memcmp("separators=", z, 11)==0 ){ + rc = unicodeAddExceptions(pNew, 0, &z[11], n-11); + } + else{ + /* Unrecognized argument */ + rc = SQLITE_ERROR; + } + } + + if( rc!=SQLITE_OK ){ + unicodeDestroy((sqlite3_tokenizer *)pNew); + pNew = 0; + } + *pp = (sqlite3_tokenizer *)pNew; + return rc; +} + +/* +** Prepare to begin tokenizing a particular string. The input +** string to be tokenized is pInput[0..nBytes-1]. A cursor +** used to incrementally tokenize this string is returned in +** *ppCursor. +*/ +static int unicodeOpen( + sqlite3_tokenizer *p, /* The tokenizer */ + const char *aInput, /* Input string */ + int nInput, /* Size of string aInput in bytes */ + sqlite3_tokenizer_cursor **pp /* OUT: New cursor object */ +){ + unicode_cursor *pCsr; + + pCsr = (unicode_cursor *)sqlite3_malloc(sizeof(unicode_cursor)); + if( pCsr==0 ){ + return SQLITE_NOMEM; + } + memset(pCsr, 0, sizeof(unicode_cursor)); + + pCsr->aInput = (const unsigned char *)aInput; + if( aInput==0 ){ + pCsr->nInput = 0; + pCsr->aInput = (const unsigned char*)""; + }else if( nInput<0 ){ + pCsr->nInput = (int)strlen(aInput); + }else{ + pCsr->nInput = nInput; + } + + *pp = &pCsr->base; + UNUSED_PARAMETER(p); + return SQLITE_OK; +} + +/* +** Close a tokenization cursor previously opened by a call to +** simpleOpen() above. +*/ +static int unicodeClose(sqlite3_tokenizer_cursor *pCursor){ + unicode_cursor *pCsr = (unicode_cursor *) pCursor; + sqlite3_free(pCsr->zToken); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +/* +** Extract the next token from a tokenization cursor. The cursor must +** have been opened by a prior call to simpleOpen(). +*/ +static int unicodeNext( + sqlite3_tokenizer_cursor *pC, /* Cursor returned by simpleOpen */ + const char **paToken, /* OUT: Token text */ + int *pnToken, /* OUT: Number of bytes at *paToken */ + int *piStart, /* OUT: Starting offset of token */ + int *piEnd, /* OUT: Ending offset of token */ + int *piPos /* OUT: Position integer of token */ +){ + unicode_cursor *pCsr = (unicode_cursor *)pC; + unicode_tokenizer *p = ((unicode_tokenizer *)pCsr->base.pTokenizer); + unsigned int iCode = 0; + char *zOut; + const unsigned char *z = &pCsr->aInput[pCsr->iOff]; + const unsigned char *zStart = z; + const unsigned char *zEnd; + const unsigned char *zTerm = &pCsr->aInput[pCsr->nInput]; + + /* Scan past any delimiter characters before the start of the next token. + ** Return SQLITE_DONE early if this takes us all the way to the end of + ** the input. */ + while( z=zTerm ) return SQLITE_DONE; + + zOut = pCsr->zToken; + do { + int iOut; + + /* Grow the output buffer if required. */ + if( (zOut-pCsr->zToken)>=(pCsr->nAlloc-4) ){ + char *zNew = sqlite3_realloc64(pCsr->zToken, pCsr->nAlloc+64); + if( !zNew ) return SQLITE_NOMEM; + zOut = &zNew[zOut - pCsr->zToken]; + pCsr->zToken = zNew; + pCsr->nAlloc += 64; + } + + /* Write the folded case of the last character read to the output */ + zEnd = z; + iOut = sqlite3FtsUnicodeFold((int)iCode, p->eRemoveDiacritic); + if( iOut ){ + WRITE_UTF8(zOut, iOut); + } + + /* If the cursor is not at EOF, read the next character */ + if( z>=zTerm ) break; + READ_UTF8(z, zTerm, iCode); + }while( unicodeIsAlnum(p, (int)iCode) + || sqlite3FtsUnicodeIsdiacritic((int)iCode) + ); + + /* Set the output variables and return. */ + pCsr->iOff = (int)(z - pCsr->aInput); + *paToken = pCsr->zToken; + *pnToken = (int)(zOut - pCsr->zToken); + *piStart = (int)(zStart - pCsr->aInput); + *piEnd = (int)(zEnd - pCsr->aInput); + *piPos = pCsr->iToken++; + return SQLITE_OK; +} + +/* +** Set *ppModule to a pointer to the sqlite3_tokenizer_module +** structure for the unicode tokenizer. +*/ +SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const **ppModule){ + static const sqlite3_tokenizer_module module = { + 0, + unicodeCreate, + unicodeDestroy, + unicodeOpen, + unicodeClose, + unicodeNext, + 0, + }; + *ppModule = &module; +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ +#endif /* ifndef SQLITE_DISABLE_FTS3_UNICODE */ + +/************** End of fts3_unicode.c ****************************************/ +/************** Begin file fts3_unicode2.c ***********************************/ +/* +** 2012-05-25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +*/ + +/* +** DO NOT EDIT THIS MACHINE GENERATED FILE. +*/ + +#ifndef SQLITE_DISABLE_FTS3_UNICODE +#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) + +/* #include */ + +/* +** Return true if the argument corresponds to a unicode codepoint +** classified as either a letter or a number. Otherwise false. +** +** The results are undefined if the value passed to this function +** is less than zero. +*/ +SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int c){ + /* Each unsigned integer in the following array corresponds to a contiguous + ** range of unicode codepoints that are not either letters or numbers (i.e. + ** codepoints for which this function should return 0). + ** + ** The most significant 22 bits in each 32-bit value contain the first + ** codepoint in the range. The least significant 10 bits are used to store + ** the size of the range (always at least 1). In other words, the value + ** ((C<<22) + N) represents a range of N codepoints starting with codepoint + ** C. It is not possible to represent a range larger than 1023 codepoints + ** using this format. + */ + static const unsigned int aEntry[] = { + 0x00000030, 0x0000E807, 0x00016C06, 0x0001EC2F, 0x0002AC07, + 0x0002D001, 0x0002D803, 0x0002EC01, 0x0002FC01, 0x00035C01, + 0x0003DC01, 0x000B0804, 0x000B480E, 0x000B9407, 0x000BB401, + 0x000BBC81, 0x000DD401, 0x000DF801, 0x000E1002, 0x000E1C01, + 0x000FD801, 0x00120808, 0x00156806, 0x00162402, 0x00163C01, + 0x00164437, 0x0017CC02, 0x00180005, 0x00181816, 0x00187802, + 0x00192C15, 0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F, + 0x001B9C07, 0x001BF402, 0x001C000E, 0x001C3C01, 0x001C4401, + 0x001CC01B, 0x001E980B, 0x001FAC09, 0x001FD804, 0x00205804, + 0x00206C09, 0x00209403, 0x0020A405, 0x0020C00F, 0x00216403, + 0x00217801, 0x0023901B, 0x00240004, 0x0024E803, 0x0024F812, + 0x00254407, 0x00258804, 0x0025C001, 0x00260403, 0x0026F001, + 0x0026F807, 0x00271C02, 0x00272C03, 0x00275C01, 0x00278802, + 0x0027C802, 0x0027E802, 0x00280403, 0x0028F001, 0x0028F805, + 0x00291C02, 0x00292C03, 0x00294401, 0x0029C002, 0x0029D401, + 0x002A0403, 0x002AF001, 0x002AF808, 0x002B1C03, 0x002B2C03, + 0x002B8802, 0x002BC002, 0x002C0403, 0x002CF001, 0x002CF807, + 0x002D1C02, 0x002D2C03, 0x002D5802, 0x002D8802, 0x002DC001, + 0x002E0801, 0x002EF805, 0x002F1803, 0x002F2804, 0x002F5C01, + 0x002FCC08, 0x00300403, 0x0030F807, 0x00311803, 0x00312804, + 0x00315402, 0x00318802, 0x0031FC01, 0x00320802, 0x0032F001, + 0x0032F807, 0x00331803, 0x00332804, 0x00335402, 0x00338802, + 0x00340802, 0x0034F807, 0x00351803, 0x00352804, 0x00355C01, + 0x00358802, 0x0035E401, 0x00360802, 0x00372801, 0x00373C06, + 0x00375801, 0x00376008, 0x0037C803, 0x0038C401, 0x0038D007, + 0x0038FC01, 0x00391C09, 0x00396802, 0x003AC401, 0x003AD006, + 0x003AEC02, 0x003B2006, 0x003C041F, 0x003CD00C, 0x003DC417, + 0x003E340B, 0x003E6424, 0x003EF80F, 0x003F380D, 0x0040AC14, + 0x00412806, 0x00415804, 0x00417803, 0x00418803, 0x00419C07, + 0x0041C404, 0x0042080C, 0x00423C01, 0x00426806, 0x0043EC01, + 0x004D740C, 0x004E400A, 0x00500001, 0x0059B402, 0x005A0001, + 0x005A6C02, 0x005BAC03, 0x005C4803, 0x005CC805, 0x005D4802, + 0x005DC802, 0x005ED023, 0x005F6004, 0x005F7401, 0x0060000F, + 0x0062A401, 0x0064800C, 0x0064C00C, 0x00650001, 0x00651002, + 0x0066C011, 0x00672002, 0x00677822, 0x00685C05, 0x00687802, + 0x0069540A, 0x0069801D, 0x0069FC01, 0x006A8007, 0x006AA006, + 0x006C0005, 0x006CD011, 0x006D6823, 0x006E0003, 0x006E840D, + 0x006F980E, 0x006FF004, 0x00709014, 0x0070EC05, 0x0071F802, + 0x00730008, 0x00734019, 0x0073B401, 0x0073C803, 0x00770027, + 0x0077F004, 0x007EF401, 0x007EFC03, 0x007F3403, 0x007F7403, + 0x007FB403, 0x007FF402, 0x00800065, 0x0081A806, 0x0081E805, + 0x00822805, 0x0082801A, 0x00834021, 0x00840002, 0x00840C04, + 0x00842002, 0x00845001, 0x00845803, 0x00847806, 0x00849401, + 0x00849C01, 0x0084A401, 0x0084B801, 0x0084E802, 0x00850005, + 0x00852804, 0x00853C01, 0x00864264, 0x00900027, 0x0091000B, + 0x0092704E, 0x00940200, 0x009C0475, 0x009E53B9, 0x00AD400A, + 0x00B39406, 0x00B3BC03, 0x00B3E404, 0x00B3F802, 0x00B5C001, + 0x00B5FC01, 0x00B7804F, 0x00B8C00C, 0x00BA001A, 0x00BA6C59, + 0x00BC00D6, 0x00BFC00C, 0x00C00005, 0x00C02019, 0x00C0A807, + 0x00C0D802, 0x00C0F403, 0x00C26404, 0x00C28001, 0x00C3EC01, + 0x00C64002, 0x00C6580A, 0x00C70024, 0x00C8001F, 0x00C8A81E, + 0x00C94001, 0x00C98020, 0x00CA2827, 0x00CB003F, 0x00CC0100, + 0x01370040, 0x02924037, 0x0293F802, 0x02983403, 0x0299BC10, + 0x029A7C01, 0x029BC008, 0x029C0017, 0x029C8002, 0x029E2402, + 0x02A00801, 0x02A01801, 0x02A02C01, 0x02A08C09, 0x02A0D804, + 0x02A1D004, 0x02A20002, 0x02A2D011, 0x02A33802, 0x02A38012, + 0x02A3E003, 0x02A4980A, 0x02A51C0D, 0x02A57C01, 0x02A60004, + 0x02A6CC1B, 0x02A77802, 0x02A8A40E, 0x02A90C01, 0x02A93002, + 0x02A97004, 0x02A9DC03, 0x02A9EC01, 0x02AAC001, 0x02AAC803, + 0x02AADC02, 0x02AAF802, 0x02AB0401, 0x02AB7802, 0x02ABAC07, + 0x02ABD402, 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02, + 0x037FFC01, 0x03EC7801, 0x03ECA401, 0x03EEC810, 0x03F4F802, + 0x03F7F002, 0x03F8001A, 0x03F88007, 0x03F8C023, 0x03F95013, + 0x03F9A004, 0x03FBFC01, 0x03FC040F, 0x03FC6807, 0x03FCEC06, + 0x03FD6C0B, 0x03FF8007, 0x03FFA007, 0x03FFE405, 0x04040003, + 0x0404DC09, 0x0405E411, 0x0406400C, 0x0407402E, 0x040E7C01, + 0x040F4001, 0x04215C01, 0x04247C01, 0x0424FC01, 0x04280403, + 0x04281402, 0x04283004, 0x0428E003, 0x0428FC01, 0x04294009, + 0x0429FC01, 0x042CE407, 0x04400003, 0x0440E016, 0x04420003, + 0x0442C012, 0x04440003, 0x04449C0E, 0x04450004, 0x04460003, + 0x0446CC0E, 0x04471404, 0x045AAC0D, 0x0491C004, 0x05BD442E, + 0x05BE3C04, 0x074000F6, 0x07440027, 0x0744A4B5, 0x07480046, + 0x074C0057, 0x075B0401, 0x075B6C01, 0x075BEC01, 0x075C5401, + 0x075CD401, 0x075D3C01, 0x075DBC01, 0x075E2401, 0x075EA401, + 0x075F0C01, 0x07BBC002, 0x07C0002C, 0x07C0C064, 0x07C2800F, + 0x07C2C40E, 0x07C3040F, 0x07C3440F, 0x07C4401F, 0x07C4C03C, + 0x07C5C02B, 0x07C7981D, 0x07C8402B, 0x07C90009, 0x07C94002, + 0x07CC0021, 0x07CCC006, 0x07CCDC46, 0x07CE0014, 0x07CE8025, + 0x07CF1805, 0x07CF8011, 0x07D0003F, 0x07D10001, 0x07D108B6, + 0x07D3E404, 0x07D4003E, 0x07D50004, 0x07D54018, 0x07D7EC46, + 0x07D9140B, 0x07DA0046, 0x07DC0074, 0x38000401, 0x38008060, + 0x380400F0, + }; + static const unsigned int aAscii[4] = { + 0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001, + }; + + if( (unsigned int)c<128 ){ + return ( (aAscii[c >> 5] & ((unsigned int)1 << (c & 0x001F)))==0 ); + }else if( (unsigned int)c<(1<<22) ){ + unsigned int key = (((unsigned int)c)<<10) | 0x000003FF; + int iRes = 0; + int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1; + int iLo = 0; + while( iHi>=iLo ){ + int iTest = (iHi + iLo) / 2; + if( key >= aEntry[iTest] ){ + iRes = iTest; + iLo = iTest+1; + }else{ + iHi = iTest-1; + } + } + assert( aEntry[0]=aEntry[iRes] ); + return (((unsigned int)c) >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF))); + } + return 1; +} + + +/* +** If the argument is a codepoint corresponding to a lowercase letter +** in the ASCII range with a diacritic added, return the codepoint +** of the ASCII letter only. For example, if passed 235 - "LATIN +** SMALL LETTER E WITH DIAERESIS" - return 65 ("LATIN SMALL LETTER +** E"). The resuls of passing a codepoint that corresponds to an +** uppercase letter are undefined. +*/ +static int remove_diacritic(int c, int bComplex){ + unsigned short aDia[] = { + 0, 1797, 1848, 1859, 1891, 1928, 1940, 1995, + 2024, 2040, 2060, 2110, 2168, 2206, 2264, 2286, + 2344, 2383, 2472, 2488, 2516, 2596, 2668, 2732, + 2782, 2842, 2894, 2954, 2984, 3000, 3028, 3336, + 3456, 3696, 3712, 3728, 3744, 3766, 3832, 3896, + 3912, 3928, 3944, 3968, 4008, 4040, 4056, 4106, + 4138, 4170, 4202, 4234, 4266, 4296, 4312, 4344, + 4408, 4424, 4442, 4472, 4488, 4504, 6148, 6198, + 6264, 6280, 6360, 6429, 6505, 6529, 61448, 61468, + 61512, 61534, 61592, 61610, 61642, 61672, 61688, 61704, + 61726, 61784, 61800, 61816, 61836, 61880, 61896, 61914, + 61948, 61998, 62062, 62122, 62154, 62184, 62200, 62218, + 62252, 62302, 62364, 62410, 62442, 62478, 62536, 62554, + 62584, 62604, 62640, 62648, 62656, 62664, 62730, 62766, + 62830, 62890, 62924, 62974, 63032, 63050, 63082, 63118, + 63182, 63242, 63274, 63310, 63368, 63390, + }; +#define HIBIT ((unsigned char)0x80) + unsigned char aChar[] = { + '\0', 'a', 'c', 'e', 'i', 'n', + 'o', 'u', 'y', 'y', 'a', 'c', + 'd', 'e', 'e', 'g', 'h', 'i', + 'j', 'k', 'l', 'n', 'o', 'r', + 's', 't', 'u', 'u', 'w', 'y', + 'z', 'o', 'u', 'a', 'i', 'o', + 'u', 'u'|HIBIT, 'a'|HIBIT, 'g', 'k', 'o', + 'o'|HIBIT, 'j', 'g', 'n', 'a'|HIBIT, 'a', + 'e', 'i', 'o', 'r', 'u', 's', + 't', 'h', 'a', 'e', 'o'|HIBIT, 'o', + 'o'|HIBIT, 'y', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', 'a', 'b', + 'c'|HIBIT, 'd', 'd', 'e'|HIBIT, 'e', 'e'|HIBIT, + 'f', 'g', 'h', 'h', 'i', 'i'|HIBIT, + 'k', 'l', 'l'|HIBIT, 'l', 'm', 'n', + 'o'|HIBIT, 'p', 'r', 'r'|HIBIT, 'r', 's', + 's'|HIBIT, 't', 'u', 'u'|HIBIT, 'v', 'w', + 'w', 'x', 'y', 'z', 'h', 't', + 'w', 'y', 'a', 'a'|HIBIT, 'a'|HIBIT, 'a'|HIBIT, + 'e', 'e'|HIBIT, 'e'|HIBIT, 'i', 'o', 'o'|HIBIT, + 'o'|HIBIT, 'o'|HIBIT, 'u', 'u'|HIBIT, 'u'|HIBIT, 'y', + }; + + unsigned int key = (((unsigned int)c)<<3) | 0x00000007; + int iRes = 0; + int iHi = sizeof(aDia)/sizeof(aDia[0]) - 1; + int iLo = 0; + while( iHi>=iLo ){ + int iTest = (iHi + iLo) / 2; + if( key >= aDia[iTest] ){ + iRes = iTest; + iLo = iTest+1; + }else{ + iHi = iTest-1; + } + } + assert( key>=aDia[iRes] ); + if( bComplex==0 && (aChar[iRes] & 0x80) ) return c; + return (c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : ((int)aChar[iRes] & 0x7F); +} + + +/* +** Return true if the argument interpreted as a unicode codepoint +** is a diacritical modifier character. +*/ +SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int c){ + unsigned int mask0 = 0x08029FDF; + unsigned int mask1 = 0x000361F8; + if( c<768 || c>817 ) return 0; + return (c < 768+32) ? + (mask0 & ((unsigned int)1 << (c-768))) : + (mask1 & ((unsigned int)1 << (c-768-32))); +} + + +/* +** Interpret the argument as a unicode codepoint. If the codepoint +** is an upper case character that has a lower case equivalent, +** return the codepoint corresponding to the lower case version. +** Otherwise, return a copy of the argument. +** +** The results are undefined if the value passed to this function +** is less than zero. +*/ +SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){ + /* Each entry in the following array defines a rule for folding a range + ** of codepoints to lower case. The rule applies to a range of nRange + ** codepoints starting at codepoint iCode. + ** + ** If the least significant bit in flags is clear, then the rule applies + ** to all nRange codepoints (i.e. all nRange codepoints are upper case and + ** need to be folded). Or, if it is set, then the rule only applies to + ** every second codepoint in the range, starting with codepoint C. + ** + ** The 7 most significant bits in flags are an index into the aiOff[] + ** array. If a specific codepoint C does require folding, then its lower + ** case equivalent is ((C + aiOff[flags>>1]) & 0xFFFF). + ** + ** The contents of this array are generated by parsing the CaseFolding.txt + ** file distributed as part of the "Unicode Character Database". See + ** http://www.unicode.org for details. + */ + static const struct TableEntry { + unsigned short iCode; + unsigned char flags; + unsigned char nRange; + } aEntry[] = { + {65, 14, 26}, {181, 64, 1}, {192, 14, 23}, + {216, 14, 7}, {256, 1, 48}, {306, 1, 6}, + {313, 1, 16}, {330, 1, 46}, {376, 116, 1}, + {377, 1, 6}, {383, 104, 1}, {385, 50, 1}, + {386, 1, 4}, {390, 44, 1}, {391, 0, 1}, + {393, 42, 2}, {395, 0, 1}, {398, 32, 1}, + {399, 38, 1}, {400, 40, 1}, {401, 0, 1}, + {403, 42, 1}, {404, 46, 1}, {406, 52, 1}, + {407, 48, 1}, {408, 0, 1}, {412, 52, 1}, + {413, 54, 1}, {415, 56, 1}, {416, 1, 6}, + {422, 60, 1}, {423, 0, 1}, {425, 60, 1}, + {428, 0, 1}, {430, 60, 1}, {431, 0, 1}, + {433, 58, 2}, {435, 1, 4}, {439, 62, 1}, + {440, 0, 1}, {444, 0, 1}, {452, 2, 1}, + {453, 0, 1}, {455, 2, 1}, {456, 0, 1}, + {458, 2, 1}, {459, 1, 18}, {478, 1, 18}, + {497, 2, 1}, {498, 1, 4}, {502, 122, 1}, + {503, 134, 1}, {504, 1, 40}, {544, 110, 1}, + {546, 1, 18}, {570, 70, 1}, {571, 0, 1}, + {573, 108, 1}, {574, 68, 1}, {577, 0, 1}, + {579, 106, 1}, {580, 28, 1}, {581, 30, 1}, + {582, 1, 10}, {837, 36, 1}, {880, 1, 4}, + {886, 0, 1}, {902, 18, 1}, {904, 16, 3}, + {908, 26, 1}, {910, 24, 2}, {913, 14, 17}, + {931, 14, 9}, {962, 0, 1}, {975, 4, 1}, + {976, 140, 1}, {977, 142, 1}, {981, 146, 1}, + {982, 144, 1}, {984, 1, 24}, {1008, 136, 1}, + {1009, 138, 1}, {1012, 130, 1}, {1013, 128, 1}, + {1015, 0, 1}, {1017, 152, 1}, {1018, 0, 1}, + {1021, 110, 3}, {1024, 34, 16}, {1040, 14, 32}, + {1120, 1, 34}, {1162, 1, 54}, {1216, 6, 1}, + {1217, 1, 14}, {1232, 1, 88}, {1329, 22, 38}, + {4256, 66, 38}, {4295, 66, 1}, {4301, 66, 1}, + {7680, 1, 150}, {7835, 132, 1}, {7838, 96, 1}, + {7840, 1, 96}, {7944, 150, 8}, {7960, 150, 6}, + {7976, 150, 8}, {7992, 150, 8}, {8008, 150, 6}, + {8025, 151, 8}, {8040, 150, 8}, {8072, 150, 8}, + {8088, 150, 8}, {8104, 150, 8}, {8120, 150, 2}, + {8122, 126, 2}, {8124, 148, 1}, {8126, 100, 1}, + {8136, 124, 4}, {8140, 148, 1}, {8152, 150, 2}, + {8154, 120, 2}, {8168, 150, 2}, {8170, 118, 2}, + {8172, 152, 1}, {8184, 112, 2}, {8186, 114, 2}, + {8188, 148, 1}, {8486, 98, 1}, {8490, 92, 1}, + {8491, 94, 1}, {8498, 12, 1}, {8544, 8, 16}, + {8579, 0, 1}, {9398, 10, 26}, {11264, 22, 47}, + {11360, 0, 1}, {11362, 88, 1}, {11363, 102, 1}, + {11364, 90, 1}, {11367, 1, 6}, {11373, 84, 1}, + {11374, 86, 1}, {11375, 80, 1}, {11376, 82, 1}, + {11378, 0, 1}, {11381, 0, 1}, {11390, 78, 2}, + {11392, 1, 100}, {11499, 1, 4}, {11506, 0, 1}, + {42560, 1, 46}, {42624, 1, 24}, {42786, 1, 14}, + {42802, 1, 62}, {42873, 1, 4}, {42877, 76, 1}, + {42878, 1, 10}, {42891, 0, 1}, {42893, 74, 1}, + {42896, 1, 4}, {42912, 1, 10}, {42922, 72, 1}, + {65313, 14, 26}, + }; + static const unsigned short aiOff[] = { + 1, 2, 8, 15, 16, 26, 28, 32, + 37, 38, 40, 48, 63, 64, 69, 71, + 79, 80, 116, 202, 203, 205, 206, 207, + 209, 210, 211, 213, 214, 217, 218, 219, + 775, 7264, 10792, 10795, 23228, 23256, 30204, 54721, + 54753, 54754, 54756, 54787, 54793, 54809, 57153, 57274, + 57921, 58019, 58363, 61722, 65268, 65341, 65373, 65406, + 65408, 65410, 65415, 65424, 65436, 65439, 65450, 65462, + 65472, 65476, 65478, 65480, 65482, 65488, 65506, 65511, + 65514, 65521, 65527, 65528, 65529, + }; + + int ret = c; + + assert( sizeof(unsigned short)==2 && sizeof(unsigned char)==1 ); + + if( c<128 ){ + if( c>='A' && c<='Z' ) ret = c + ('a' - 'A'); + }else if( c<65536 ){ + const struct TableEntry *p; + int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1; + int iLo = 0; + int iRes = -1; + + assert( c>aEntry[0].iCode ); + while( iHi>=iLo ){ + int iTest = (iHi + iLo) / 2; + int cmp = (c - aEntry[iTest].iCode); + if( cmp>=0 ){ + iRes = iTest; + iLo = iTest+1; + }else{ + iHi = iTest-1; + } + } + + assert( iRes>=0 && c>=aEntry[iRes].iCode ); + p = &aEntry[iRes]; + if( c<(p->iCode + p->nRange) && 0==(0x01 & p->flags & (p->iCode ^ c)) ){ + ret = (c + (aiOff[p->flags>>1])) & 0x0000FFFF; + assert( ret>0 ); + } + + if( eRemoveDiacritic ){ + ret = remove_diacritic(ret, eRemoveDiacritic==2); + } + } + + else if( c>=66560 && c<66600 ){ + ret = c + 40; + } + + return ret; +} +#endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */ +#endif /* !defined(SQLITE_DISABLE_FTS3_UNICODE) */ + +/************** End of fts3_unicode2.c ***************************************/ +/************** Begin file json.c ********************************************/ +/* +** 2015-08-12 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** SQLite JSON functions. +** +** This file began as an extension in ext/misc/json1.c in 2015. That +** extension proved so useful that it has now been moved into the core. +** +** The original design stored all JSON as pure text, canonical RFC-8259. +** Support for JSON-5 extensions was added with version 3.42.0 (2023-05-16). +** All generated JSON text still conforms strictly to RFC-8259, but text +** with JSON-5 extensions is accepted as input. +** +** Beginning with version 3.45.0 (circa 2024-01-01), these routines also +** accept BLOB values that have JSON encoded using a binary representation +** called "JSONB". The name JSONB comes from PostgreSQL, however the on-disk +** format for SQLite-JSONB is completely different and incompatible with +** PostgreSQL-JSONB. +** +** Decoding and interpreting JSONB is still O(N) where N is the size of +** the input, the same as text JSON. However, the constant of proportionality +** for JSONB is much smaller due to faster parsing. The size of each +** element in JSONB is encoded in its header, so there is no need to search +** for delimiters using persnickety syntax rules. JSONB seems to be about +** 3x faster than text JSON as a result. JSONB is also tends to be slightly +** smaller than text JSON, by 5% or 10%, but there are corner cases where +** JSONB can be slightly larger. So you are not far mistaken to say that +** a JSONB blob is the same size as the equivalent RFC-8259 text. +** +** +** THE JSONB ENCODING: +** +** Every JSON element is encoded in JSONB as a header and a payload. +** The header is between 1 and 9 bytes in size. The payload is zero +** or more bytes. +** +** The lower 4 bits of the first byte of the header determines the +** element type: +** +** 0: NULL +** 1: TRUE +** 2: FALSE +** 3: INT -- RFC-8259 integer literal +** 4: INT5 -- JSON5 integer literal +** 5: FLOAT -- RFC-8259 floating point literal +** 6: FLOAT5 -- JSON5 floating point literal +** 7: TEXT -- Text literal acceptable to both SQL and JSON +** 8: TEXTJ -- Text containing RFC-8259 escapes +** 9: TEXT5 -- Text containing JSON5 and/or RFC-8259 escapes +** 10: TEXTRAW -- Text containing unescaped syntax characters +** 11: ARRAY +** 12: OBJECT +** +** The other three possible values (13-15) are reserved for future +** enhancements. +** +** The upper 4 bits of the first byte determine the size of the header +** and sometimes also the size of the payload. If X is the first byte +** of the element and if X>>4 is between 0 and 11, then the payload +** will be that many bytes in size and the header is exactly one byte +** in size. Other four values for X>>4 (12-15) indicate that the header +** is more than one byte in size and that the payload size is determined +** by the remainder of the header, interpreted as a unsigned big-endian +** integer. +** +** Value of X>>4 Size integer Total header size +** ------------- -------------------- ----------------- +** 12 1 byte (0-255) 2 +** 13 2 byte (0-65535) 3 +** 14 4 byte (0-4294967295) 5 +** 15 8 byte (0-1.8e19) 9 +** +** The payload size need not be expressed in its minimal form. For example, +** if the payload size is 10, the size can be expressed in any of 5 different +** ways: (1) (X>>4)==10, (2) (X>>4)==12 following by one 0x0a byte, +** (3) (X>>4)==13 followed by 0x00 and 0x0a, (4) (X>>4)==14 followed by +** 0x00 0x00 0x00 0x0a, or (5) (X>>4)==15 followed by 7 bytes of 0x00 and +** a single byte of 0x0a. The shorter forms are preferred, of course, but +** sometimes when generating JSONB, the payload size is not known in advance +** and it is convenient to reserve sufficient header space to cover the +** largest possible payload size and then come back later and patch up +** the size when it becomes known, resulting in a non-minimal encoding. +** +** The value (X>>4)==15 is not actually used in the current implementation +** (as SQLite is currently unable to handle BLOBs larger than about 2GB) +** but is included in the design to allow for future enhancements. +** +** The payload follows the header. NULL, TRUE, and FALSE have no payload and +** their payload size must always be zero. The payload for INT, INT5, +** FLOAT, FLOAT5, TEXT, TEXTJ, TEXT5, and TEXTROW is text. Note that the +** "..." or '...' delimiters are omitted from the various text encodings. +** The payload for ARRAY and OBJECT is a list of additional elements that +** are the content for the array or object. The payload for an OBJECT +** must be an even number of elements. The first element of each pair is +** the label and must be of type TEXT, TEXTJ, TEXT5, or TEXTRAW. +** +** A valid JSONB blob consists of a single element, as described above. +** Usually this will be an ARRAY or OBJECT element which has many more +** elements as its content. But the overall blob is just a single element. +** +** Input validation for JSONB blobs simply checks that the element type +** code is between 0 and 12 and that the total size of the element +** (header plus payload) is the same as the size of the BLOB. If those +** checks are true, the BLOB is assumed to be JSONB and processing continues. +** Errors are only raised if some other miscoding is discovered during +** processing. +** +** Additional information can be found in the doc/jsonb.md file of the +** canonical SQLite source tree. +*/ +#ifndef SQLITE_OMIT_JSON +/* #include "sqliteInt.h" */ + +/* JSONB element types +*/ +#define JSONB_NULL 0 /* "null" */ +#define JSONB_TRUE 1 /* "true" */ +#define JSONB_FALSE 2 /* "false" */ +#define JSONB_INT 3 /* integer acceptable to JSON and SQL */ +#define JSONB_INT5 4 /* integer in 0x000 notation */ +#define JSONB_FLOAT 5 /* float acceptable to JSON and SQL */ +#define JSONB_FLOAT5 6 /* float with JSON5 extensions */ +#define JSONB_TEXT 7 /* Text compatible with both JSON and SQL */ +#define JSONB_TEXTJ 8 /* Text with JSON escapes */ +#define JSONB_TEXT5 9 /* Text with JSON-5 escape */ +#define JSONB_TEXTRAW 10 /* SQL text that needs escaping for JSON */ +#define JSONB_ARRAY 11 /* An array */ +#define JSONB_OBJECT 12 /* An object */ + +/* Human-readable names for the JSONB values. The index for each +** string must correspond to the JSONB_* integer above. +*/ +static const char * const jsonbType[] = { + "null", "true", "false", "integer", "integer", + "real", "real", "text", "text", "text", + "text", "array", "object", "", "", "", "" +}; + +/* +** Growing our own isspace() routine this way is twice as fast as +** the library isspace() function, resulting in a 7% overall performance +** increase for the text-JSON parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). +*/ +static const char jsonIsSpace[] = { +#ifdef SQLITE_ASCII +/*0 1 2 3 4 5 6 7 8 9 a b c d e f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, /* 0 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1 */ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 3 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 5 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7 */ + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* b */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* c */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* e */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* f */ +#endif +#ifdef SQLITE_EBCDIC +/*0 1 2 3 4 5 6 7 8 9 a b c d e f */ + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, /* 0 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1 */ + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 3 */ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 5 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7 */ + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* b */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* c */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* e */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* f */ +#endif + +}; +#define jsonIsspace(x) (jsonIsSpace[(unsigned char)x]) + +/* +** The set of all space characters recognized by jsonIsspace(). +** Useful as the second argument to strspn(). +*/ +#ifdef SQLITE_ASCII +static const char jsonSpaces[] = "\011\012\015\040"; +#endif +#ifdef SQLITE_EBCDIC +static const char jsonSpaces[] = "\005\045\015\100"; +#endif + + +/* +** Characters that are special to JSON. Control characters, +** '"' and '\\' and '\''. Actually, '\'' is not special to +** canonical JSON, but it is special in JSON-5, so we include +** it in the set of special characters. +*/ +static const char jsonIsOk[256] = { +#ifdef SQLITE_ASCII +/*0 1 2 3 4 5 6 7 8 9 a b c d e f */ + 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, /* 1 */ + 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, /* 2 */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 3 */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4 */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, /* 5 */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6 */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 7 */ + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 8 */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 9 */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* a */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* b */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* c */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* d */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* e */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* f */ +#endif +#ifdef SQLITE_EBCDIC +/*0 1 2 3 4 5 6 7 8 9 a b c d e f */ + 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, /* 1 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */ + 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, /* 3 */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4 */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 5 */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6 */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, /* 7 */ + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 8 */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 9 */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* a */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* b */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* c */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* d */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* e */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* f */ +#endif +}; + +/* Objects */ +typedef struct JsonCache JsonCache; +typedef struct JsonString JsonString; +typedef struct JsonParse JsonParse; + +/* +** Magic number used for the JSON parse cache in sqlite3_get_auxdata() +*/ +#define JSON_CACHE_ID (-429938) /* Cache entry */ +#define JSON_CACHE_SIZE 4 /* Max number of cache entries */ + +/* +** jsonUnescapeOneChar() returns this invalid code point if it encounters +** a syntax error. +*/ +#define JSON_INVALID_CHAR 0x99999 + +/* A cache mapping JSON text into JSONB blobs. +** +** Each cache entry is a JsonParse object with the following restrictions: +** +** * The bReadOnly flag must be set +** +** * The aBlob[] array must be owned by the JsonParse object. In other +** words, nBlobAlloc must be non-zero. +** +** * eEdit and delta must be zero. +** +** * zJson must be an RCStr. In other words bJsonIsRCStr must be true. +*/ +struct JsonCache { + sqlite3 *db; /* Database connection */ + int nUsed; /* Number of active entries in the cache */ + JsonParse *a[JSON_CACHE_SIZE]; /* One line for each cache entry */ +}; + +/* An instance of this object represents a JSON string +** under construction. Really, this is a generic string accumulator +** that can be and is used to create strings other than JSON. +** +** If the generated string is longer than will fit into the zSpace[] buffer, +** then it will be an RCStr string. This aids with caching of large +** JSON strings. +*/ +struct JsonString { + sqlite3_context *pCtx; /* Function context - put error messages here */ + char *zBuf; /* Append JSON content here */ + u64 nAlloc; /* Bytes of storage available in zBuf[] */ + u64 nUsed; /* Bytes of zBuf[] currently used */ + u8 bStatic; /* True if zBuf is static space */ + u8 eErr; /* True if an error has been encountered */ + char zSpace[100]; /* Initial static space */ +}; + +/* Allowed values for JsonString.eErr */ +#define JSTRING_OOM 0x01 /* Out of memory */ +#define JSTRING_MALFORMED 0x02 /* Malformed JSONB */ +#define JSTRING_TOODEEP 0x04 /* JSON nested too deep */ +#define JSTRING_ERR 0x08 /* Error already sent to sqlite3_result */ + +/* The "subtype" set for text JSON values passed through using +** sqlite3_result_subtype() and sqlite3_value_subtype(). +*/ +#define JSON_SUBTYPE 74 /* Ascii for "J" */ + +/* +** Bit values for the flags passed into various SQL function implementations +** via the sqlite3_user_data() value. +*/ +#define JSON_JSON 0x01 /* Result is always JSON */ +#define JSON_SQL 0x02 /* Result is always SQL */ +#define JSON_ABPATH 0x03 /* Allow abbreviated JSON path specs */ +#define JSON_ISSET 0x04 /* json_set(), not json_insert() */ +#define JSON_AINS 0x08 /* json_array_insert(), not json_insert() */ +#define JSON_BLOB 0x10 /* Use the BLOB output format */ + +#define JSON_INSERT_TYPE(X) (((X)&0xC)>>2) + + +/* A parsed JSON value. Lifecycle: +** +** 1. JSON comes in and is parsed into a JSONB value in aBlob. The +** original text is stored in zJson. This step is skipped if the +** input is JSONB instead of text JSON. +** +** 2. The aBlob[] array is searched using the JSON path notation, if needed. +** +** 3. Zero or more changes are made to aBlob[] (via json_remove() or +** json_replace() or json_patch() or similar). +** +** 4. New JSON text is generated from the aBlob[] for output. This step +** is skipped if the function is one of the jsonb_* functions that +** returns JSONB instead of text JSON. +*/ +struct JsonParse { + u8 *aBlob; /* JSONB representation of JSON value */ + u32 nBlob; /* Bytes of aBlob[] actually used */ + u32 nBlobAlloc; /* Bytes allocated to aBlob[]. 0 if aBlob is external */ + char *zJson; /* Json text used for parsing */ + sqlite3 *db; /* The database connection to which this object belongs */ + int nJson; /* Length of the zJson string in bytes */ + u32 nJPRef; /* Number of references to this object */ + u32 iErr; /* Error location in zJson[] */ + u16 iDepth; /* Nesting depth */ + u8 nErr; /* Number of errors seen */ + u8 oom; /* Set to true if out of memory */ + u8 bJsonIsRCStr; /* True if zJson is an RCStr */ + u8 hasNonstd; /* True if input uses non-standard features like JSON5 */ + u8 bReadOnly; /* Do not modify. */ + /* Search and edit information. See jsonLookupStep() */ + u8 eEdit; /* Edit operation to apply */ + int delta; /* Size change due to the edit */ + u32 nIns; /* Number of bytes to insert */ + u32 iLabel; /* Location of label if search landed on an object value */ + u8 *aIns; /* Content to be inserted */ +}; + +/* Allowed values for JsonParse.eEdit */ +#define JEDIT_DEL 1 /* Delete if exists */ +#define JEDIT_REPL 2 /* Overwrite if exists */ +#define JEDIT_INS 3 /* Insert if not exists */ +#define JEDIT_SET 4 /* Insert or overwrite */ +#define JEDIT_AINS 5 /* array_insert() */ + +/* +** Maximum nesting depth of JSON for this implementation. +** +** This limit is needed to avoid a stack overflow in the recursive +** descent parser. A depth of 1000 is far deeper than any sane JSON +** should go. Historical note: This limit was 2000 prior to version 3.42.0 +*/ +#ifndef SQLITE_JSON_MAX_DEPTH +# define JSON_MAX_DEPTH 1000 +#else +# define JSON_MAX_DEPTH SQLITE_JSON_MAX_DEPTH +#endif + +/* +** Allowed values for the flgs argument to jsonParseFuncArg(); +*/ +#define JSON_EDITABLE 0x01 /* Generate a writable JsonParse object */ +#define JSON_KEEPERROR 0x02 /* Return non-NULL even if there is an error */ + +/************************************************************************** +** Forward references +**************************************************************************/ +static void jsonReturnStringAsBlob(JsonString*); +static int jsonArgIsJsonb(sqlite3_value *pJson, JsonParse *p); +static u32 jsonTranslateBlobToText(JsonParse*,u32,JsonString*); +static void jsonReturnParse(sqlite3_context*,JsonParse*); +static JsonParse *jsonParseFuncArg(sqlite3_context*,sqlite3_value*,u32); +static void jsonParseFree(JsonParse*); +static u32 jsonbPayloadSize(const JsonParse*, u32, u32*); +static u32 jsonUnescapeOneChar(const char*, u32, u32*); + +/************************************************************************** +** Utility routines for dealing with JsonCache objects +**************************************************************************/ + +/* +** Free a JsonCache object. +*/ +static void jsonCacheDelete(JsonCache *p){ + int i; + for(i=0; inUsed; i++){ + jsonParseFree(p->a[i]); + } + sqlite3DbFree(p->db, p); +} +static void jsonCacheDeleteGeneric(void *p){ + jsonCacheDelete((JsonCache*)p); +} + +/* +** Insert a new entry into the cache. If the cache is full, expel +** the least recently used entry. Return SQLITE_OK on success or a +** result code otherwise. +** +** Cache entries are stored in age order, oldest first. +*/ +static int jsonCacheInsert( + sqlite3_context *ctx, /* The SQL statement context holding the cache */ + JsonParse *pParse /* The parse object to be added to the cache */ +){ + JsonCache *p; + + assert( pParse->zJson!=0 ); + assert( pParse->bJsonIsRCStr ); + assert( pParse->delta==0 ); + p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID); + if( p==0 ){ + sqlite3 *db = sqlite3_context_db_handle(ctx); + p = sqlite3DbMallocZero(db, sizeof(*p)); + if( p==0 ) return SQLITE_NOMEM; + p->db = db; + sqlite3_set_auxdata(ctx, JSON_CACHE_ID, p, jsonCacheDeleteGeneric); + p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID); + if( p==0 ) return SQLITE_NOMEM; + } + if( p->nUsed >= JSON_CACHE_SIZE ){ + jsonParseFree(p->a[0]); + memmove(p->a, &p->a[1], (JSON_CACHE_SIZE-1)*sizeof(p->a[0])); + p->nUsed = JSON_CACHE_SIZE-1; + } + assert( pParse->nBlobAlloc>0 ); + pParse->eEdit = 0; + pParse->nJPRef++; + pParse->bReadOnly = 1; + p->a[p->nUsed] = pParse; + p->nUsed++; + return SQLITE_OK; +} + +/* +** Search for a cached translation the json text supplied by pArg. Return +** the JsonParse object if found. Return NULL if not found. +** +** When a match if found, the matching entry is moved to become the +** most-recently used entry if it isn't so already. +** +** The JsonParse object returned still belongs to the Cache and might +** be deleted at any moment. If the caller wants the JsonParse to +** linger, it needs to increment the nPJRef reference counter. +*/ +static JsonParse *jsonCacheSearch( + sqlite3_context *ctx, /* The SQL statement context holding the cache */ + sqlite3_value *pArg /* Function argument containing SQL text */ +){ + JsonCache *p; + int i; + const char *zJson; + int nJson; + + if( sqlite3_value_type(pArg)!=SQLITE_TEXT ){ + return 0; + } + zJson = (const char*)sqlite3_value_text(pArg); + if( zJson==0 ) return 0; + nJson = sqlite3_value_bytes(pArg); + + p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID); + if( p==0 ){ + return 0; + } + for(i=0; inUsed; i++){ + if( p->a[i]->zJson==zJson ) break; + } + if( i>=p->nUsed ){ + for(i=0; inUsed; i++){ + if( p->a[i]->nJson!=nJson ) continue; + if( memcmp(p->a[i]->zJson, zJson, nJson)==0 ) break; + } + } + if( inUsed ){ + if( inUsed-1 ){ + /* Make the matching entry the most recently used entry */ + JsonParse *tmp = p->a[i]; + memmove(&p->a[i], &p->a[i+1], (p->nUsed-i-1)*sizeof(tmp)); + p->a[p->nUsed-1] = tmp; + i = p->nUsed - 1; + } + assert( p->a[i]->delta==0 ); + return p->a[i]; + }else{ + return 0; + } +} + +/************************************************************************** +** Utility routines for dealing with JsonString objects +**************************************************************************/ + +/* Turn uninitialized bulk memory into a valid JsonString object +** holding a zero-length string. +*/ +static void jsonStringZero(JsonString *p){ + p->zBuf = p->zSpace; + p->nAlloc = sizeof(p->zSpace); + p->nUsed = 0; + p->bStatic = 1; +} + +/* Initialize the JsonString object +*/ +static void jsonStringInit(JsonString *p, sqlite3_context *pCtx){ + p->pCtx = pCtx; + p->eErr = 0; + jsonStringZero(p); +} + +/* Free all allocated memory and reset the JsonString object back to its +** initial state. +*/ +static void jsonStringReset(JsonString *p){ + if( !p->bStatic ) sqlite3RCStrUnref(p->zBuf); + jsonStringZero(p); +} + +/* Report an out-of-memory (OOM) condition +*/ +static void jsonStringOom(JsonString *p){ + p->eErr |= JSTRING_OOM; + if( p->pCtx ) sqlite3_result_error_nomem(p->pCtx); + jsonStringReset(p); +} + +/* Report JSON nested too deep +*/ +static void jsonStringTooDeep(JsonString *p){ + p->eErr |= JSTRING_TOODEEP; + assert( p->pCtx!=0 ); + sqlite3_result_error(p->pCtx, "JSON nested too deep", -1); + jsonStringReset(p); +} + +/* Enlarge pJson->zBuf so that it can hold at least N more bytes. +** Return zero on success. Return non-zero on an OOM error +*/ +static int jsonStringGrow(JsonString *p, u32 N){ + u64 nTotal = NnAlloc ? p->nAlloc*2 : p->nAlloc+N+10; + char *zNew; + if( p->bStatic ){ + if( p->eErr ) return 1; + zNew = sqlite3RCStrNew(nTotal); + if( zNew==0 ){ + jsonStringOom(p); + return SQLITE_NOMEM; + } + memcpy(zNew, p->zBuf, (size_t)p->nUsed); + p->zBuf = zNew; + p->bStatic = 0; + }else{ + p->zBuf = sqlite3RCStrResize(p->zBuf, nTotal); + if( p->zBuf==0 ){ + p->eErr |= JSTRING_OOM; + jsonStringZero(p); + return SQLITE_NOMEM; + } + } + p->nAlloc = nTotal; + return SQLITE_OK; +} + +/* Append N bytes from zIn onto the end of the JsonString string. +*/ +static SQLITE_NOINLINE void jsonStringExpandAndAppend( + JsonString *p, + const char *zIn, + u32 N +){ + assert( N>0 ); + if( jsonStringGrow(p,N) ) return; + memcpy(p->zBuf+p->nUsed, zIn, N); + p->nUsed += N; +} +static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){ + if( N==0 ) return; + if( N+p->nUsed >= p->nAlloc ){ + jsonStringExpandAndAppend(p,zIn,N); + }else{ + memcpy(p->zBuf+p->nUsed, zIn, N); + p->nUsed += N; + } +} +static void jsonAppendRawNZ(JsonString *p, const char *zIn, u32 N){ + assert( N>0 ); + if( N+p->nUsed >= p->nAlloc ){ + jsonStringExpandAndAppend(p,zIn,N); + }else{ + memcpy(p->zBuf+p->nUsed, zIn, N); + p->nUsed += N; + } +} + +/* Append formatted text (not to exceed N bytes) to the JsonString. +*/ +static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){ + va_list ap; + if( (p->nUsed + N >= p->nAlloc) && jsonStringGrow(p, N) ) return; + va_start(ap, zFormat); + sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap); + va_end(ap); + p->nUsed += (int)strlen(p->zBuf+p->nUsed); +} + +/* Append a single character +*/ +static SQLITE_NOINLINE void jsonAppendCharExpand(JsonString *p, char c){ + if( jsonStringGrow(p,1) ) return; + p->zBuf[p->nUsed++] = c; +} +static void jsonAppendChar(JsonString *p, char c){ + if( p->nUsed>=p->nAlloc ){ + jsonAppendCharExpand(p,c); + }else{ + p->zBuf[p->nUsed++] = c; + } +} + +/* Remove a single character from the end of the string +*/ +static void jsonStringTrimOneChar(JsonString *p){ + if( p->eErr==0 ){ + assert( p->nUsed>0 ); + p->nUsed--; + } +} + + +/* Make sure there is a zero terminator on p->zBuf[] +** +** Return true on success. Return false if an OOM prevents this +** from happening. +*/ +static int jsonStringTerminate(JsonString *p){ + jsonAppendChar(p, 0); + jsonStringTrimOneChar(p); + return p->eErr==0; +} + +/* Append a comma separator to the output buffer, if the previous +** character is not '[' or '{'. +*/ +static void jsonAppendSeparator(JsonString *p){ + char c; + if( p->nUsed==0 ) return; + c = p->zBuf[p->nUsed-1]; + if( c=='[' || c=='{' ) return; + jsonAppendChar(p, ','); +} + +/* c is a control character. Append the canonical JSON representation +** of that control character to p. +** +** This routine assumes that the output buffer has already been enlarged +** sufficiently to hold the worst-case encoding plus a nul terminator. +*/ +static void jsonAppendControlChar(JsonString *p, u8 c){ + static const char aSpecial[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + assert( sizeof(aSpecial)==32 ); + assert( aSpecial['\b']=='b' ); + assert( aSpecial['\f']=='f' ); + assert( aSpecial['\n']=='n' ); + assert( aSpecial['\r']=='r' ); + assert( aSpecial['\t']=='t' ); + assert( c>=0 && cnUsed+7 <= p->nAlloc ); + if( aSpecial[c] ){ + p->zBuf[p->nUsed] = '\\'; + p->zBuf[p->nUsed+1] = aSpecial[c]; + p->nUsed += 2; + }else{ + p->zBuf[p->nUsed] = '\\'; + p->zBuf[p->nUsed+1] = 'u'; + p->zBuf[p->nUsed+2] = '0'; + p->zBuf[p->nUsed+3] = '0'; + p->zBuf[p->nUsed+4] = "0123456789abcdef"[c>>4]; + p->zBuf[p->nUsed+5] = "0123456789abcdef"[c&0xf]; + p->nUsed += 6; + } +} + +/* Append the N-byte string in zIn to the end of the JsonString string +** under construction. Enclose the string in double-quotes ("...") and +** escape any double-quotes or backslash characters contained within the +** string. +** +** This routine is a high-runner. There is a measurable performance +** increase associated with unwinding the jsonIsOk[] loop. +*/ +static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ + u32 k; + u8 c; + const u8 *z = (const u8*)zIn; + if( z==0 ) return; + if( (N+p->nUsed+2 >= p->nAlloc) && jsonStringGrow(p,N+2)!=0 ) return; + p->zBuf[p->nUsed++] = '"'; + while( 1 /*exit-by-break*/ ){ + k = 0; + /* The following while() is the 4-way unwound equivalent of + ** + ** while( k=N ){ + while( k=N ){ + if( k>0 ){ + memcpy(&p->zBuf[p->nUsed], z, k); + p->nUsed += k; + } + break; + } + if( k>0 ){ + memcpy(&p->zBuf[p->nUsed], z, k); + p->nUsed += k; + z += k; + N -= k; + } + c = z[0]; + if( c=='"' || c=='\\' ){ + if( (p->nUsed+N+3 > p->nAlloc) && jsonStringGrow(p,N+3)!=0 ) return; + p->zBuf[p->nUsed++] = '\\'; + p->zBuf[p->nUsed++] = c; + }else if( c=='\'' ){ + p->zBuf[p->nUsed++] = c; + }else{ + if( (p->nUsed+N+7 > p->nAlloc) && jsonStringGrow(p,N+7)!=0 ) return; + jsonAppendControlChar(p, c); + } + z++; + N--; + } + p->zBuf[p->nUsed++] = '"'; + assert( p->nUsednAlloc ); +} + +/* +** Append an sqlite3_value (such as a function parameter) to the JSON +** string under construction in p. +*/ +static void jsonAppendSqlValue( + JsonString *p, /* Append to this JSON string */ + sqlite3_value *pValue /* Value to append */ +){ + switch( sqlite3_value_type(pValue) ){ + case SQLITE_NULL: { + jsonAppendRawNZ(p, "null", 4); + break; + } + case SQLITE_FLOAT: { + jsonPrintf(100, p, "%!0.17g", sqlite3_value_double(pValue)); + break; + } + case SQLITE_INTEGER: { + const char *z = (const char*)sqlite3_value_text(pValue); + u32 n = (u32)sqlite3_value_bytes(pValue); + jsonAppendRaw(p, z, n); + break; + } + case SQLITE_TEXT: { + const char *z = (const char*)sqlite3_value_text(pValue); + u32 n = (u32)sqlite3_value_bytes(pValue); + if( sqlite3_value_subtype(pValue)==JSON_SUBTYPE ){ + jsonAppendRaw(p, z, n); + }else{ + jsonAppendString(p, z, n); + } + break; + } + default: { + JsonParse px; + memset(&px, 0, sizeof(px)); + if( jsonArgIsJsonb(pValue, &px) ){ + jsonTranslateBlobToText(&px, 0, p); + }else if( p->eErr==0 ){ + sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1); + p->eErr = JSTRING_ERR; + jsonStringReset(p); + } + break; + } + } +} + +/* Make the text in p (which is probably a generated JSON text string) +** the result of the SQL function. +** +** The JsonString is reset. +** +** If pParse and ctx are both non-NULL, then the SQL string in p is +** loaded into the zJson field of the pParse object as a RCStr and the +** pParse is added to the cache. +*/ +static void jsonReturnString( + JsonString *p, /* String to return */ + JsonParse *pParse, /* JSONB source or NULL */ + sqlite3_context *ctx /* Where to cache */ +){ + assert( (pParse!=0)==(ctx!=0) ); + assert( ctx==0 || ctx==p->pCtx ); + jsonStringTerminate(p); + if( p->eErr==0 ){ + int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(p->pCtx)); + if( flags & JSON_BLOB ){ + jsonReturnStringAsBlob(p); + }else if( p->bStatic ){ + sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, + SQLITE_TRANSIENT, SQLITE_UTF8); + }else{ + if( pParse && pParse->bJsonIsRCStr==0 && pParse->nBlobAlloc>0 ){ + int rc; + pParse->zJson = sqlite3RCStrRef(p->zBuf); + pParse->nJson = p->nUsed; + pParse->bJsonIsRCStr = 1; + rc = jsonCacheInsert(ctx, pParse); + if( rc==SQLITE_NOMEM ){ + sqlite3_result_error_nomem(ctx); + jsonStringReset(p); + return; + } + } + sqlite3_result_text64(p->pCtx, sqlite3RCStrRef(p->zBuf), p->nUsed, + sqlite3RCStrUnref, + SQLITE_UTF8); + } + }else if( p->eErr & JSTRING_OOM ){ + sqlite3_result_error_nomem(p->pCtx); + }else if( p->eErr & JSTRING_TOODEEP ){ + /* error already in p->pCtx */ + }else if( p->eErr & JSTRING_MALFORMED ){ + sqlite3_result_error(p->pCtx, "malformed JSON", -1); + } + jsonStringReset(p); +} + +/************************************************************************** +** Utility routines for dealing with JsonParse objects +**************************************************************************/ + +/* +** Reclaim all memory allocated by a JsonParse object. But do not +** delete the JsonParse object itself. +*/ +static void jsonParseReset(JsonParse *pParse){ + assert( pParse->nJPRef<=1 ); + if( pParse->bJsonIsRCStr ){ + sqlite3RCStrUnref(pParse->zJson); + pParse->zJson = 0; + pParse->nJson = 0; + pParse->bJsonIsRCStr = 0; + } + if( pParse->nBlobAlloc ){ + sqlite3DbFree(pParse->db, pParse->aBlob); + pParse->aBlob = 0; + pParse->nBlob = 0; + pParse->nBlobAlloc = 0; + } +} + +/* +** Decrement the reference count on the JsonParse object. When the +** count reaches zero, free the object. +*/ +static void jsonParseFree(JsonParse *pParse){ + if( pParse ){ + if( pParse->nJPRef>1 ){ + pParse->nJPRef--; + }else{ + jsonParseReset(pParse); + sqlite3DbFree(pParse->db, pParse); + } + } +} + +/************************************************************************** +** Utility routines for the JSON text parser +**************************************************************************/ + +/* +** Translate a single byte of Hex into an integer. +** This routine only gives a correct answer if h really is a valid hexadecimal +** character: 0..9a..fA..F. But unlike sqlite3HexToInt(), it does not +** assert() if the digit is not hex. +*/ +static u8 jsonHexToInt(int h){ +#ifdef SQLITE_ASCII + h += 9*(1&(h>>6)); +#endif +#ifdef SQLITE_EBCDIC + h += 9*(1&~(h>>4)); +#endif + return (u8)(h & 0xf); +} + +/* +** Convert a 4-byte hex string into an integer +*/ +static u32 jsonHexToInt4(const char *z){ + u32 v; + v = (jsonHexToInt(z[0])<<12) + + (jsonHexToInt(z[1])<<8) + + (jsonHexToInt(z[2])<<4) + + jsonHexToInt(z[3]); + return v; +} + +/* +** Return true if z[] begins with 2 (or more) hexadecimal digits +*/ +static int jsonIs2Hex(const char *z){ + return sqlite3Isxdigit(z[0]) && sqlite3Isxdigit(z[1]); +} + +/* +** Return true if z[] begins with 4 (or more) hexadecimal digits +*/ +static int jsonIs4Hex(const char *z){ + return jsonIs2Hex(z) && jsonIs2Hex(&z[2]); +} + +/* +** Return the number of bytes of JSON5 whitespace at the beginning of +** the input string z[]. +** +** JSON5 whitespace consists of any of the following characters: +** +** Unicode UTF-8 Name +** U+0009 09 horizontal tab +** U+000a 0a line feed +** U+000b 0b vertical tab +** U+000c 0c form feed +** U+000d 0d carriage return +** U+0020 20 space +** U+00a0 c2 a0 non-breaking space +** U+1680 e1 9a 80 ogham space mark +** U+2000 e2 80 80 en quad +** U+2001 e2 80 81 em quad +** U+2002 e2 80 82 en space +** U+2003 e2 80 83 em space +** U+2004 e2 80 84 three-per-em space +** U+2005 e2 80 85 four-per-em space +** U+2006 e2 80 86 six-per-em space +** U+2007 e2 80 87 figure space +** U+2008 e2 80 88 punctuation space +** U+2009 e2 80 89 thin space +** U+200a e2 80 8a hair space +** U+2028 e2 80 a8 line separator +** U+2029 e2 80 a9 paragraph separator +** U+202f e2 80 af narrow no-break space (NNBSP) +** U+205f e2 81 9f medium mathematical space (MMSP) +** U+3000 e3 80 80 ideographical space +** U+FEFF ef bb bf byte order mark +** +** In addition, comments between '/', '*' and '*', '/' and +** from '/', '/' to end-of-line are also considered to be whitespace. +*/ +static int json5Whitespace(const char *zIn){ + int n = 0; + const u8 *z = (u8*)zIn; + while( 1 /*exit by "goto whitespace_done"*/ ){ + switch( z[n] ){ + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x20: { + n++; + break; + } + case '/': { + if( z[n+1]=='*' && z[n+2]!=0 ){ + int j; + for(j=n+3; z[j]!='/' || z[j-1]!='*'; j++){ + if( z[j]==0 ) goto whitespace_done; + } + n = j+1; + break; + }else if( z[n+1]=='/' ){ + int j; + char c; + for(j=n+2; (c = z[j])!=0; j++){ + if( c=='\n' || c=='\r' ) break; + if( 0xe2==(u8)c && 0x80==(u8)z[j+1] + && (0xa8==(u8)z[j+2] || 0xa9==(u8)z[j+2]) + ){ + j += 2; + break; + } + } + n = j; + if( z[n] ) n++; + break; + } + goto whitespace_done; + } + case 0xc2: { + if( z[n+1]==0xa0 ){ + n += 2; + break; + } + goto whitespace_done; + } + case 0xe1: { + if( z[n+1]==0x9a && z[n+2]==0x80 ){ + n += 3; + break; + } + goto whitespace_done; + } + case 0xe2: { + if( z[n+1]==0x80 ){ + u8 c = z[n+2]; + if( c<0x80 ) goto whitespace_done; + if( c<=0x8a || c==0xa8 || c==0xa9 || c==0xaf ){ + n += 3; + break; + } + }else if( z[n+1]==0x81 && z[n+2]==0x9f ){ + n += 3; + break; + } + goto whitespace_done; + } + case 0xe3: { + if( z[n+1]==0x80 && z[n+2]==0x80 ){ + n += 3; + break; + } + goto whitespace_done; + } + case 0xef: { + if( z[n+1]==0xbb && z[n+2]==0xbf ){ + n += 3; + break; + } + goto whitespace_done; + } + default: { + goto whitespace_done; + } + } + } + whitespace_done: + return n; +} + +/* +** Extra floating-point literals to allow in JSON. +*/ +static const struct NanInfName { + char c1; + char c2; + char n; + char eType; + char nRepl; + char *zMatch; + char *zRepl; +} aNanInfName[] = { + { 'i', 'I', 3, JSONB_FLOAT, 7, "inf", "9.0e999" }, + { 'i', 'I', 8, JSONB_FLOAT, 7, "infinity", "9.0e999" }, + { 'n', 'N', 3, JSONB_NULL, 4, "NaN", "null" }, + { 'q', 'Q', 4, JSONB_NULL, 4, "QNaN", "null" }, + { 's', 'S', 4, JSONB_NULL, 4, "SNaN", "null" }, +}; + + +/* +** Report the wrong number of arguments for json_insert(), json_replace() +** or json_set(). +*/ +static void jsonWrongNumArgs( + sqlite3_context *pCtx, + const char *zFuncName +){ + char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments", + zFuncName); + sqlite3_result_error(pCtx, zMsg, -1); + sqlite3_free(zMsg); +} + +/**************************************************************************** +** Utility routines for dealing with the binary BLOB representation of JSON +****************************************************************************/ + +/* +** Expand pParse->aBlob so that it holds at least N bytes. +** +** Return the number of errors. +*/ +static int jsonBlobExpand(JsonParse *pParse, u32 N){ + u8 *aNew; + u64 t; + assert( N>pParse->nBlobAlloc ); + if( pParse->nBlobAlloc==0 ){ + t = 100; + }else{ + t = pParse->nBlobAlloc*2; + } + if( tdb, pParse->aBlob, t); + if( aNew==0 ){ pParse->oom = 1; return 1; } + assert( t<0x7fffffff ); + pParse->aBlob = aNew; + pParse->nBlobAlloc = (u32)t; + return 0; +} + +/* +** If pParse->aBlob is not previously editable (because it is taken +** from sqlite3_value_blob(), as indicated by the fact that +** pParse->nBlobAlloc==0 and pParse->nBlob>0) then make it editable +** by making a copy into space obtained from malloc. +** +** Return true on success. Return false on OOM. +*/ +static int jsonBlobMakeEditable(JsonParse *pParse, u32 nExtra){ + u8 *aOld; + u32 nSize; + assert( !pParse->bReadOnly ); + if( pParse->oom ) return 0; + if( pParse->nBlobAlloc>0 ) return 1; + aOld = pParse->aBlob; + nSize = pParse->nBlob + nExtra; + pParse->aBlob = 0; + if( jsonBlobExpand(pParse, nSize) ){ + return 0; + } + assert( pParse->nBlobAlloc >= pParse->nBlob + nExtra ); + memcpy(pParse->aBlob, aOld, pParse->nBlob); + return 1; +} + +/* Expand pParse->aBlob and append one bytes. +*/ +static SQLITE_NOINLINE void jsonBlobExpandAndAppendOneByte( + JsonParse *pParse, + u8 c +){ + jsonBlobExpand(pParse, pParse->nBlob+1); + if( pParse->oom==0 ){ + assert( pParse->nBlob+1<=pParse->nBlobAlloc ); + pParse->aBlob[pParse->nBlob++] = c; + } +} + +/* Append a single character. +*/ +static void jsonBlobAppendOneByte(JsonParse *pParse, u8 c){ + if( pParse->nBlob >= pParse->nBlobAlloc ){ + jsonBlobExpandAndAppendOneByte(pParse, c); + }else{ + pParse->aBlob[pParse->nBlob++] = c; + } +} + +/* Slow version of jsonBlobAppendNode() that first resizes the +** pParse->aBlob structure. +*/ +static void jsonBlobAppendNode(JsonParse*,u8,u64,const void*); +static SQLITE_NOINLINE void jsonBlobExpandAndAppendNode( + JsonParse *pParse, + u8 eType, + u64 szPayload, + const void *aPayload +){ + if( jsonBlobExpand(pParse, pParse->nBlob+szPayload+9) ) return; + jsonBlobAppendNode(pParse, eType, szPayload, aPayload); +} + + +/* Append a node type byte together with the payload size and +** possibly also the payload. +** +** If aPayload is not NULL, then it is a pointer to the payload which +** is also appended. If aPayload is NULL, the pParse->aBlob[] array +** is resized (if necessary) so that it is big enough to hold the +** payload, but the payload is not appended and pParse->nBlob is left +** pointing to where the first byte of payload will eventually be. +*/ +static void jsonBlobAppendNode( + JsonParse *pParse, /* The JsonParse object under construction */ + u8 eType, /* Node type. One of JSONB_* */ + u64 szPayload, /* Number of bytes of payload */ + const void *aPayload /* The payload. Might be NULL */ +){ + u8 *a; + if( pParse->nBlob+szPayload+9 > pParse->nBlobAlloc ){ + jsonBlobExpandAndAppendNode(pParse,eType,szPayload,aPayload); + return; + } + assert( pParse->aBlob!=0 ); + a = &pParse->aBlob[pParse->nBlob]; + if( szPayload<=11 ){ + a[0] = eType | (szPayload<<4); + pParse->nBlob += 1; + }else if( szPayload<=0xff ){ + a[0] = eType | 0xc0; + a[1] = szPayload & 0xff; + pParse->nBlob += 2; + }else if( szPayload<=0xffff ){ + a[0] = eType | 0xd0; + a[1] = (szPayload >> 8) & 0xff; + a[2] = szPayload & 0xff; + pParse->nBlob += 3; + }else{ + a[0] = eType | 0xe0; + a[1] = (szPayload >> 24) & 0xff; + a[2] = (szPayload >> 16) & 0xff; + a[3] = (szPayload >> 8) & 0xff; + a[4] = szPayload & 0xff; + pParse->nBlob += 5; + } + if( aPayload ){ + pParse->nBlob += szPayload; + memcpy(&pParse->aBlob[pParse->nBlob-szPayload], aPayload, szPayload); + } +} + +/* Change the payload size for the node at index i to be szPayload. +*/ +static int jsonBlobChangePayloadSize( + JsonParse *pParse, + u32 i, + u32 szPayload +){ + u8 *a; + u8 szType; + u8 nExtra; + u8 nNeeded; + int delta; + if( pParse->oom ) return 0; + a = &pParse->aBlob[i]; + szType = a[0]>>4; + if( szType<=11 ){ + nExtra = 0; + }else if( szType==12 ){ + nExtra = 1; + }else if( szType==13 ){ + nExtra = 2; + }else if( szType==14 ){ + nExtra = 4; + }else{ + nExtra = 8; + } + if( szPayload<=11 ){ + nNeeded = 0; + }else if( szPayload<=0xff ){ + nNeeded = 1; + }else if( szPayload<=0xffff ){ + nNeeded = 2; + }else{ + nNeeded = 4; + } + delta = nNeeded - nExtra; + if( delta ){ + u32 newSize = pParse->nBlob + delta; + if( delta>0 ){ + if( newSize>pParse->nBlobAlloc && jsonBlobExpand(pParse, newSize) ){ + return 0; /* OOM error. Error state recorded in pParse->oom. */ + } + a = &pParse->aBlob[i]; + memmove(&a[1+delta], &a[1], pParse->nBlob - (i+1)); + }else{ + memmove(&a[1], &a[1-delta], pParse->nBlob - (i+1-delta)); + } + pParse->nBlob = newSize; + } + if( nNeeded==0 ){ + a[0] = (a[0] & 0x0f) | (szPayload<<4); + }else if( nNeeded==1 ){ + a[0] = (a[0] & 0x0f) | 0xc0; + a[1] = szPayload & 0xff; + }else if( nNeeded==2 ){ + a[0] = (a[0] & 0x0f) | 0xd0; + a[1] = (szPayload >> 8) & 0xff; + a[2] = szPayload & 0xff; + }else{ + a[0] = (a[0] & 0x0f) | 0xe0; + a[1] = (szPayload >> 24) & 0xff; + a[2] = (szPayload >> 16) & 0xff; + a[3] = (szPayload >> 8) & 0xff; + a[4] = szPayload & 0xff; + } + return delta; +} + +/* +** If z[0] is 'u' and is followed by exactly 4 hexadecimal character, +** then set *pOp to JSONB_TEXTJ and return true. If not, do not make +** any changes to *pOp and return false. +*/ +static int jsonIs4HexB(const char *z, int *pOp){ + if( z[0]!='u' ) return 0; + if( !jsonIs4Hex(&z[1]) ) return 0; + *pOp = JSONB_TEXTJ; + return 1; +} + +/* +** Check a single element of the JSONB in pParse for validity. +** +** The element to be checked starts at offset i and must end at on the +** last byte before iEnd. +** +** Return 0 if everything is correct. Return the 1-based byte offset of the +** error if a problem is detected. (In other words, if the error is at offset +** 0, return 1). +*/ +static u32 jsonbValidityCheck( + const JsonParse *pParse, /* Input JSONB. Only aBlob and nBlob are used */ + u32 i, /* Start of element as pParse->aBlob[i] */ + u32 iEnd, /* One more than the last byte of the element */ + u32 iDepth /* Current nesting depth */ +){ + u32 n, sz, j, k; + const u8 *z; + u8 x; + if( iDepth>JSON_MAX_DEPTH ) return i+1; + sz = 0; + n = jsonbPayloadSize(pParse, i, &sz); + if( NEVER(n==0) ) return i+1; /* Checked by caller */ + if( NEVER(i+n+sz!=iEnd) ) return i+1; /* Checked by caller */ + z = pParse->aBlob; + x = z[i] & 0x0f; + switch( x ){ + case JSONB_NULL: + case JSONB_TRUE: + case JSONB_FALSE: { + return n+sz==1 ? 0 : i+1; + } + case JSONB_INT: { + if( sz<1 ) return i+1; + j = i+n; + if( z[j]=='-' ){ + j++; + if( sz<2 ) return i+1; + } + k = i+n+sz; + while( jk ) return j+1; + if( z[j+1]!='.' && z[j+1]!='e' && z[j+1]!='E' ) return j+1; + j++; + } + for(; j0 ) return j+1; + if( x==JSONB_FLOAT && (j==k-1 || !sqlite3Isdigit(z[j+1])) ){ + return j+1; + } + seen = 1; + continue; + } + if( z[j]=='e' || z[j]=='E' ){ + if( seen==2 ) return j+1; + if( j==k-1 ) return j+1; + if( z[j+1]=='+' || z[j+1]=='-' ){ + j++; + if( j==k-1 ) return j+1; + } + seen = 2; + continue; + } + return j+1; + } + if( seen==0 ) return i+1; + return 0; + } + case JSONB_TEXT: { + j = i+n; + k = j+sz; + while( j=k ){ + return j+1; + }else if( strchr("\"\\/bfnrt",z[j+1])!=0 ){ + j++; + }else if( z[j+1]=='u' ){ + if( j+5>=k ) return j+1; + if( !jsonIs4Hex((const char*)&z[j+2]) ) return j+1; + j++; + }else if( x!=JSONB_TEXT5 ){ + return j+1; + }else{ + u32 c = 0; + u32 szC = jsonUnescapeOneChar((const char*)&z[j], k-j, &c); + if( c==JSON_INVALID_CHAR ) return j+1; + j += szC - 1; + } + } + j++; + } + return 0; + } + case JSONB_TEXTRAW: { + return 0; + } + case JSONB_ARRAY: { + u32 sub; + j = i+n; + k = j+sz; + while( jk ) return j+1; + sub = jsonbValidityCheck(pParse, j, j+n+sz, iDepth+1); + if( sub ) return sub; + j += n + sz; + } + assert( j==k ); + return 0; + } + case JSONB_OBJECT: { + u32 cnt = 0; + u32 sub; + j = i+n; + k = j+sz; + while( jk ) return j+1; + if( (cnt & 1)==0 ){ + x = z[j] & 0x0f; + if( xJSONB_TEXTRAW ) return j+1; + } + sub = jsonbValidityCheck(pParse, j, j+n+sz, iDepth+1); + if( sub ) return sub; + cnt++; + j += n + sz; + } + assert( j==k ); + if( (cnt & 1)!=0 ) return j+1; + return 0; + } + default: { + return i+1; + } + } +} + +/* +** Translate a single element of JSON text at pParse->zJson[i] into +** its equivalent binary JSONB representation. Append the translation into +** pParse->aBlob[] beginning at pParse->nBlob. The size of +** pParse->aBlob[] is increased as necessary. +** +** Return the index of the first character past the end of the element parsed, +** or one of the following special result codes: +** +** 0 End of input +** -1 Syntax error or OOM +** -2 '}' seen \ +** -3 ']' seen \___ For these returns, pParse->iErr is set to +** -4 ',' seen / the index in zJson[] of the seen character +** -5 ':' seen / +*/ +static int jsonTranslateTextToBlob(JsonParse *pParse, u32 i){ + char c; + u32 j; + u32 iThis, iStart; + int x; + u8 t; + const char *z = pParse->zJson; +json_parse_restart: + switch( (u8)z[i] ){ + case '{': { + /* Parse object */ + iThis = pParse->nBlob; + jsonBlobAppendNode(pParse, JSONB_OBJECT, pParse->nJson-i, 0); + if( ++pParse->iDepth > JSON_MAX_DEPTH ){ + pParse->iErr = i; + return -1; + } + iStart = pParse->nBlob; + for(j=i+1;;j++){ + u32 iBlob = pParse->nBlob; + x = jsonTranslateTextToBlob(pParse, j); + if( x<=0 ){ + int op; + if( x==(-2) ){ + j = pParse->iErr; + if( pParse->nBlob!=(u32)iStart ) pParse->hasNonstd = 1; + break; + } + j += json5Whitespace(&z[j]); + op = JSONB_TEXT; + if( sqlite3JsonId1(z[j]) + || (z[j]=='\\' && jsonIs4HexB(&z[j+1], &op)) + ){ + int k = j+1; + while( (sqlite3JsonId2(z[k]) && json5Whitespace(&z[k])==0) + || (z[k]=='\\' && jsonIs4HexB(&z[k+1], &op)) + ){ + k++; + } + assert( iBlob==pParse->nBlob ); + jsonBlobAppendNode(pParse, op, k-j, &z[j]); + pParse->hasNonstd = 1; + x = k; + }else{ + if( x!=-1 ) pParse->iErr = j; + return -1; + } + } + if( pParse->oom ) return -1; + t = pParse->aBlob[iBlob] & 0x0f; + if( tJSONB_TEXTRAW ){ + pParse->iErr = j; + return -1; + } + j = x; + if( z[j]==':' ){ + j++; + }else{ + if( jsonIsspace(z[j]) ){ + /* strspn() is not helpful here */ + do{ j++; }while( jsonIsspace(z[j]) ); + if( z[j]==':' ){ + j++; + goto parse_object_value; + } + } + x = jsonTranslateTextToBlob(pParse, j); + if( x!=(-5) ){ + if( x!=(-1) ) pParse->iErr = j; + return -1; + } + j = pParse->iErr+1; + } + parse_object_value: + x = jsonTranslateTextToBlob(pParse, j); + if( x<=0 ){ + if( x!=(-1) ) pParse->iErr = j; + return -1; + } + j = x; + if( z[j]==',' ){ + continue; + }else if( z[j]=='}' ){ + break; + }else{ + if( jsonIsspace(z[j]) ){ + j += 1 + (u32)strspn(&z[j+1], jsonSpaces); + if( z[j]==',' ){ + continue; + }else if( z[j]=='}' ){ + break; + } + } + x = jsonTranslateTextToBlob(pParse, j); + if( x==(-4) ){ + j = pParse->iErr; + continue; + } + if( x==(-2) ){ + j = pParse->iErr; + break; + } + } + pParse->iErr = j; + return -1; + } + jsonBlobChangePayloadSize(pParse, iThis, pParse->nBlob - iStart); + pParse->iDepth--; + return j+1; + } + case '[': { + /* Parse array */ + iThis = pParse->nBlob; + assert( i<=(u32)pParse->nJson ); + jsonBlobAppendNode(pParse, JSONB_ARRAY, pParse->nJson - i, 0); + iStart = pParse->nBlob; + if( pParse->oom ) return -1; + if( ++pParse->iDepth > JSON_MAX_DEPTH ){ + pParse->iErr = i; + return -1; + } + for(j=i+1;;j++){ + x = jsonTranslateTextToBlob(pParse, j); + if( x<=0 ){ + if( x==(-3) ){ + j = pParse->iErr; + if( pParse->nBlob!=iStart ) pParse->hasNonstd = 1; + break; + } + if( x!=(-1) ) pParse->iErr = j; + return -1; + } + j = x; + if( z[j]==',' ){ + continue; + }else if( z[j]==']' ){ + break; + }else{ + if( jsonIsspace(z[j]) ){ + j += 1 + (u32)strspn(&z[j+1], jsonSpaces); + if( z[j]==',' ){ + continue; + }else if( z[j]==']' ){ + break; + } + } + x = jsonTranslateTextToBlob(pParse, j); + if( x==(-4) ){ + j = pParse->iErr; + continue; + } + if( x==(-3) ){ + j = pParse->iErr; + break; + } + } + pParse->iErr = j; + return -1; + } + jsonBlobChangePayloadSize(pParse, iThis, pParse->nBlob - iStart); + pParse->iDepth--; + return j+1; + } + case '\'': { + u8 opcode; + char cDelim; + pParse->hasNonstd = 1; + opcode = JSONB_TEXT; + goto parse_string; + case '"': + /* Parse string */ + opcode = JSONB_TEXT; + parse_string: + cDelim = z[i]; + j = i+1; + while( 1 /*exit-by-break*/ ){ + if( jsonIsOk[(u8)z[j]] ){ + if( !jsonIsOk[(u8)z[j+1]] ){ + j += 1; + }else if( !jsonIsOk[(u8)z[j+2]] ){ + j += 2; + }else{ + j += 3; + continue; + } + } + c = z[j]; + if( c==cDelim ){ + break; + }else if( c=='\\' ){ + c = z[++j]; + if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f' + || c=='n' || c=='r' || c=='t' + || (c=='u' && jsonIs4Hex(&z[j+1])) ){ + if( opcode==JSONB_TEXT ) opcode = JSONB_TEXTJ; + }else if( c=='\'' || c=='v' || c=='\n' +#ifdef SQLITE_BUG_COMPATIBLE_20250510 + || (c=='0') /* Legacy bug compatible */ +#else + || (c=='0' && !sqlite3Isdigit(z[j+1])) /* Correct implementation */ +#endif + || (0xe2==(u8)c && 0x80==(u8)z[j+1] + && (0xa8==(u8)z[j+2] || 0xa9==(u8)z[j+2])) + || (c=='x' && jsonIs2Hex(&z[j+1])) ){ + opcode = JSONB_TEXT5; + pParse->hasNonstd = 1; + }else if( c=='\r' ){ + if( z[j+1]=='\n' ) j++; + opcode = JSONB_TEXT5; + pParse->hasNonstd = 1; + }else{ + pParse->iErr = j; + return -1; + } + }else if( c<=0x1f ){ + if( c==0 ){ + pParse->iErr = j; + return -1; + } + /* Control characters are not allowed in canonical JSON string + ** literals, but are allowed in JSON5 string literals. */ + opcode = JSONB_TEXT5; + pParse->hasNonstd = 1; + }else if( c=='"' ){ + opcode = JSONB_TEXT5; + } + j++; + } + jsonBlobAppendNode(pParse, opcode, j-1-i, &z[i+1]); + return j+1; + } + case 't': { + if( strncmp(z+i,"true",4)==0 && !sqlite3Isalnum(z[i+4]) ){ + jsonBlobAppendOneByte(pParse, JSONB_TRUE); + return i+4; + } + pParse->iErr = i; + return -1; + } + case 'f': { + if( strncmp(z+i,"false",5)==0 && !sqlite3Isalnum(z[i+5]) ){ + jsonBlobAppendOneByte(pParse, JSONB_FALSE); + return i+5; + } + pParse->iErr = i; + return -1; + } + case '+': { + u8 seenE; + pParse->hasNonstd = 1; + t = 0x00; /* Bit 0x01: JSON5. Bit 0x02: FLOAT */ + goto parse_number; + case '.': + if( sqlite3Isdigit(z[i+1]) ){ + pParse->hasNonstd = 1; + t = 0x03; /* Bit 0x01: JSON5. Bit 0x02: FLOAT */ + seenE = 0; + goto parse_number_2; + } + pParse->iErr = i; + return -1; + case '-': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + /* Parse number */ + t = 0x00; /* Bit 0x01: JSON5. Bit 0x02: FLOAT */ + parse_number: + seenE = 0; + assert( '-' < '0' ); + assert( '+' < '0' ); + assert( '.' < '0' ); + c = z[i]; + + if( c<='0' ){ + if( c=='0' ){ + if( (z[i+1]=='x' || z[i+1]=='X') && sqlite3Isxdigit(z[i+2]) ){ + assert( t==0x00 ); + pParse->hasNonstd = 1; + t = 0x01; + for(j=i+3; sqlite3Isxdigit(z[j]); j++){} + goto parse_number_finish; + }else if( sqlite3Isdigit(z[i+1]) ){ + pParse->iErr = i+1; + return -1; + } + }else{ + if( !sqlite3Isdigit(z[i+1]) ){ + /* JSON5 allows for "+Infinity" and "-Infinity" using exactly + ** that case. SQLite also allows these in any case and it allows + ** "+inf" and "-inf". */ + if( (z[i+1]=='I' || z[i+1]=='i') + && sqlite3StrNICmp(&z[i+1], "inf",3)==0 + ){ + pParse->hasNonstd = 1; + if( z[i]=='-' ){ + jsonBlobAppendNode(pParse, JSONB_FLOAT, 6, "-9e999"); + }else{ + jsonBlobAppendNode(pParse, JSONB_FLOAT, 5, "9e999"); + } + return i + (sqlite3StrNICmp(&z[i+4],"inity",5)==0 ? 9 : 4); + } + if( z[i+1]=='.' ){ + pParse->hasNonstd = 1; + t |= 0x01; + goto parse_number_2; + } + pParse->iErr = i; + return -1; + } + if( z[i+1]=='0' ){ + if( sqlite3Isdigit(z[i+2]) ){ + pParse->iErr = i+1; + return -1; + }else if( (z[i+2]=='x' || z[i+2]=='X') && sqlite3Isxdigit(z[i+3]) ){ + pParse->hasNonstd = 1; + t |= 0x01; + for(j=i+4; sqlite3Isxdigit(z[j]); j++){} + goto parse_number_finish; + } + } + } + } + + parse_number_2: + for(j=i+1;; j++){ + c = z[j]; + if( sqlite3Isdigit(c) ) continue; + if( c=='.' ){ + if( (t & 0x02)!=0 ){ + pParse->iErr = j; + return -1; + } + t |= 0x02; + continue; + } + if( c=='e' || c=='E' ){ + if( z[j-1]<'0' ){ + if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){ + pParse->hasNonstd = 1; + t |= 0x01; + }else{ + pParse->iErr = j; + return -1; + } + } + if( seenE ){ + pParse->iErr = j; + return -1; + } + t |= 0x02; + seenE = 1; + c = z[j+1]; + if( c=='+' || c=='-' ){ + j++; + c = z[j+1]; + } + if( c<'0' || c>'9' ){ + pParse->iErr = j; + return -1; + } + continue; + } + break; + } + if( z[j-1]<'0' ){ + if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){ + pParse->hasNonstd = 1; + t |= 0x01; + }else{ + pParse->iErr = j; + return -1; + } + } + parse_number_finish: + assert( JSONB_INT+0x01==JSONB_INT5 ); + assert( JSONB_FLOAT+0x01==JSONB_FLOAT5 ); + assert( JSONB_INT+0x02==JSONB_FLOAT ); + if( z[i]=='+' ) i++; + jsonBlobAppendNode(pParse, JSONB_INT+t, j-i, &z[i]); + return j; + } + case '}': { + pParse->iErr = i; + return -2; /* End of {...} */ + } + case ']': { + pParse->iErr = i; + return -3; /* End of [...] */ + } + case ',': { + pParse->iErr = i; + return -4; /* List separator */ + } + case ':': { + pParse->iErr = i; + return -5; /* Object label/value separator */ + } + case 0: { + return 0; /* End of file */ + } + case 0x09: + case 0x0a: + case 0x0d: + case 0x20: { + i += 1 + (u32)strspn(&z[i+1], jsonSpaces); + goto json_parse_restart; + } + case 0x0b: + case 0x0c: + case '/': + case 0xc2: + case 0xe1: + case 0xe2: + case 0xe3: + case 0xef: { + j = json5Whitespace(&z[i]); + if( j>0 ){ + i += j; + pParse->hasNonstd = 1; + goto json_parse_restart; + } + pParse->iErr = i; + return -1; + } + case 'n': { + if( strncmp(z+i,"null",4)==0 && !sqlite3Isalnum(z[i+4]) ){ + jsonBlobAppendOneByte(pParse, JSONB_NULL); + return i+4; + } + /* fall-through into the default case that checks for NaN */ + /* no break */ deliberate_fall_through + } + default: { + u32 k; + int nn; + c = z[i]; + for(k=0; khasNonstd = 1; + return i + nn; + } + pParse->iErr = i; + return -1; /* Syntax error */ + } + } /* End switch(z[i]) */ +} + + +/* +** Parse a complete JSON string. Return 0 on success or non-zero if there +** are any errors. If an error occurs, free all memory held by pParse, +** but not pParse itself. +** +** pParse must be initialized to an empty parse object prior to calling +** this routine. +*/ +static int jsonConvertTextToBlob( + JsonParse *pParse, /* Initialize and fill this JsonParse object */ + sqlite3_context *pCtx /* Report errors here */ +){ + int i; + const char *zJson = pParse->zJson; + i = jsonTranslateTextToBlob(pParse, 0); + if( pParse->oom ) i = -1; + if( i>0 ){ +#ifdef SQLITE_DEBUG + assert( pParse->iDepth==0 ); + if( sqlite3Config.bJsonSelfcheck ){ + assert( jsonbValidityCheck(pParse, 0, pParse->nBlob, 0)==0 ); + } +#endif + while( jsonIsspace(zJson[i]) ) i++; + if( zJson[i] ){ + i += json5Whitespace(&zJson[i]); + if( zJson[i] ){ + if( pCtx ) sqlite3_result_error(pCtx, "malformed JSON", -1); + jsonParseReset(pParse); + return 1; + } + pParse->hasNonstd = 1; + } + } + if( i<=0 ){ + if( pCtx!=0 ){ + if( pParse->oom ){ + sqlite3_result_error_nomem(pCtx); + }else{ + sqlite3_result_error(pCtx, "malformed JSON", -1); + } + } + jsonParseReset(pParse); + return 1; + } + return 0; +} + +/* +** The input string pStr is a well-formed JSON text string. Convert +** this into the JSONB format and make it the return value of the +** SQL function. +*/ +static void jsonReturnStringAsBlob(JsonString *pStr){ + JsonParse px; + assert( pStr->eErr==0 ); + memset(&px, 0, sizeof(px)); + px.zJson = pStr->zBuf; + px.nJson = pStr->nUsed; + px.db = sqlite3_context_db_handle(pStr->pCtx); + (void)jsonTranslateTextToBlob(&px, 0); + if( px.oom ){ + sqlite3DbFree(px.db, px.aBlob); + sqlite3_result_error_nomem(pStr->pCtx); + }else{ + assert( px.nBlobAlloc>0 ); + assert( !px.bReadOnly ); + sqlite3_result_blob(pStr->pCtx, px.aBlob, px.nBlob, SQLITE_DYNAMIC); + } +} + +/* The byte at index i is a node type-code. This routine +** determines the payload size for that node and writes that +** payload size in to *pSz. It returns the offset from i to the +** beginning of the payload. Return 0 on error. +*/ +static u32 jsonbPayloadSize(const JsonParse *pParse, u32 i, u32 *pSz){ + u8 x; + u32 sz; + u32 n; + if( i>=pParse->nBlob ){ + *pSz = 0; + return 0; + }else if( (x = pParse->aBlob[i]>>4)<=11 ){ + sz = x; + n = 1; + }else if( x==12 ){ + if( i+1>=pParse->nBlob ){ + *pSz = 0; + return 0; + } + sz = pParse->aBlob[i+1]; + n = 2; + }else if( x==13 ){ + if( i+2>=pParse->nBlob ){ + *pSz = 0; + return 0; + } + sz = (pParse->aBlob[i+1]<<8) + pParse->aBlob[i+2]; + n = 3; + }else if( x==14 ){ + if( i+4>=pParse->nBlob ){ + *pSz = 0; + return 0; + } + sz = ((u32)pParse->aBlob[i+1]<<24) + (pParse->aBlob[i+2]<<16) + + (pParse->aBlob[i+3]<<8) + pParse->aBlob[i+4]; + n = 5; + }else{ + if( i+8>=pParse->nBlob + || pParse->aBlob[i+1]!=0 + || pParse->aBlob[i+2]!=0 + || pParse->aBlob[i+3]!=0 + || pParse->aBlob[i+4]!=0 + ){ + *pSz = 0; + return 0; + } + sz = ((u32)pParse->aBlob[i+5]<<24) + (pParse->aBlob[i+6]<<16) + + (pParse->aBlob[i+7]<<8) + pParse->aBlob[i+8]; + n = 9; + } + if( (i64)i+sz+n > pParse->nBlob + && (i64)i+sz+n > pParse->nBlob-pParse->delta + ){ + *pSz = 0; + return 0; + } + *pSz = sz; + return n; +} + + +/* +** Translate the binary JSONB representation of JSON beginning at +** pParse->aBlob[i] into a JSON text string. Append the JSON +** text onto the end of pOut. Return the index in pParse->aBlob[] +** of the first byte past the end of the element that is translated. +** +** If an error is detected in the BLOB input, the pOut->eErr flag +** might get set to JSTRING_MALFORMED. But not all BLOB input errors +** are detected. So a malformed JSONB input might either result +** in an error, or in incorrect JSON. +** +** The pOut->eErr JSTRING_OOM flag is set on a OOM. +*/ +static u32 jsonTranslateBlobToText( + JsonParse *pParse, /* the complete parse of the JSON */ + u32 i, /* Start rendering at this index */ + JsonString *pOut /* Write JSON here */ +){ + u32 sz, n, j, iEnd; + + n = jsonbPayloadSize(pParse, i, &sz); + if( n==0 ){ + pOut->eErr |= JSTRING_MALFORMED; + return pParse->nBlob+1; + } + switch( pParse->aBlob[i] & 0x0f ){ + case JSONB_NULL: { + jsonAppendRawNZ(pOut, "null", 4); + return i+1; + } + case JSONB_TRUE: { + jsonAppendRawNZ(pOut, "true", 4); + return i+1; + } + case JSONB_FALSE: { + jsonAppendRawNZ(pOut, "false", 5); + return i+1; + } + case JSONB_INT: + case JSONB_FLOAT: { + if( sz==0 ) goto malformed_jsonb; + jsonAppendRaw(pOut, (const char*)&pParse->aBlob[i+n], sz); + break; + } + case JSONB_INT5: { /* Integer literal in hexadecimal notation */ + u32 k = 2; + sqlite3_uint64 u = 0; + const char *zIn = (const char*)&pParse->aBlob[i+n]; + int bOverflow = 0; + if( sz==0 ) goto malformed_jsonb; + if( zIn[0]=='-' ){ + jsonAppendChar(pOut, '-'); + k++; + }else if( zIn[0]=='+' ){ + k++; + } + for(; keErr |= JSTRING_MALFORMED; + break; + }else if( (u>>60)!=0 ){ + bOverflow = 1; + }else{ + u = u*16 + sqlite3HexToInt(zIn[k]); + } + } + jsonPrintf(100,pOut,bOverflow?"9.0e999":"%llu", u); + break; + } + case JSONB_FLOAT5: { /* Float literal missing digits beside "." */ + u32 k = 0; + const char *zIn = (const char*)&pParse->aBlob[i+n]; + if( sz==0 ) goto malformed_jsonb; + if( zIn[0]=='-' ){ + jsonAppendChar(pOut, '-'); + if( sz<=1 ) goto malformed_jsonb; + k = 1; + } + if( zIn[k]=='.' ){ + jsonAppendChar(pOut, '0'); + } + for(; knUsed+sz+2<=pOut->nAlloc || jsonStringGrow(pOut, sz+2)==0 ){ + pOut->zBuf[pOut->nUsed] = '"'; + memcpy(pOut->zBuf+pOut->nUsed+1,(const char*)&pParse->aBlob[i+n],sz); + pOut->zBuf[pOut->nUsed+sz+1] = '"'; + pOut->nUsed += sz+2; + } + break; + } + case JSONB_TEXT5: { + const char *zIn; + u32 k; + u32 sz2 = sz; + zIn = (const char*)&pParse->aBlob[i+n]; + jsonAppendChar(pOut, '"'); + while( sz2>0 ){ + for(k=0; k0 ){ + jsonAppendRawNZ(pOut, zIn, k); + if( k>=sz2 ){ + break; + } + zIn += k; + sz2 -= k; + } + if( zIn[0]=='"' ){ + jsonAppendRawNZ(pOut, "\\\"", 2); + zIn++; + sz2--; + continue; + } + if( zIn[0]<=0x1f ){ + if( pOut->nUsed+7>pOut->nAlloc && jsonStringGrow(pOut,7) ) break; + jsonAppendControlChar(pOut, zIn[0]); + zIn++; + sz2--; + continue; + } + assert( zIn[0]=='\\' ); + assert( sz2>=1 ); + if( sz2<2 ){ + pOut->eErr |= JSTRING_MALFORMED; + break; + } + switch( (u8)zIn[1] ){ + case '\'': + jsonAppendChar(pOut, '\''); + break; + case 'v': + jsonAppendRawNZ(pOut, "\\u000b", 6); + break; + case 'x': + if( sz2<4 ){ + pOut->eErr |= JSTRING_MALFORMED; + sz2 = 2; + break; + } + jsonAppendRawNZ(pOut, "\\u00", 4); + jsonAppendRawNZ(pOut, &zIn[2], 2); + zIn += 2; + sz2 -= 2; + break; + case '0': + jsonAppendRawNZ(pOut, "\\u0000", 6); + break; + case '\r': + if( sz2>2 && zIn[2]=='\n' ){ + zIn++; + sz2--; + } + break; + case '\n': + break; + case 0xe2: + /* '\' followed by either U+2028 or U+2029 is ignored as + ** whitespace. Not that in UTF8, U+2028 is 0xe2 0x80 0x29. + ** U+2029 is the same except for the last byte */ + if( sz2<4 + || 0x80!=(u8)zIn[2] + || (0xa8!=(u8)zIn[3] && 0xa9!=(u8)zIn[3]) + ){ + pOut->eErr |= JSTRING_MALFORMED; + sz2 = 2; + break; + } + zIn += 2; + sz2 -= 2; + break; + default: + jsonAppendRawNZ(pOut, zIn, 2); + break; + } + assert( sz2>=2 ); + zIn += 2; + sz2 -= 2; + } + jsonAppendChar(pOut, '"'); + break; + } + case JSONB_TEXTRAW: { + jsonAppendString(pOut, (const char*)&pParse->aBlob[i+n], sz); + break; + } + case JSONB_ARRAY: { + jsonAppendChar(pOut, '['); + j = i+n; + iEnd = j+sz; + if( ++pParse->iDepth > JSON_MAX_DEPTH ){ + jsonStringTooDeep(pOut); + } + while( jeErr==0 ){ + j = jsonTranslateBlobToText(pParse, j, pOut); + jsonAppendChar(pOut, ','); + } + pParse->iDepth--; + if( j>iEnd ) pOut->eErr |= JSTRING_MALFORMED; + if( sz>0 ) jsonStringTrimOneChar(pOut); + jsonAppendChar(pOut, ']'); + break; + } + case JSONB_OBJECT: { + int x = 0; + jsonAppendChar(pOut, '{'); + j = i+n; + iEnd = j+sz; + if( ++pParse->iDepth > JSON_MAX_DEPTH ){ + jsonStringTooDeep(pOut); + } + while( jeErr==0 ){ + j = jsonTranslateBlobToText(pParse, j, pOut); + jsonAppendChar(pOut, (x++ & 1) ? ',' : ':'); + } + pParse->iDepth--; + if( (x & 1)!=0 || j>iEnd ) pOut->eErr |= JSTRING_MALFORMED; + if( sz>0 ) jsonStringTrimOneChar(pOut); + jsonAppendChar(pOut, '}'); + break; + } + + default: { + malformed_jsonb: + pOut->eErr |= JSTRING_MALFORMED; + break; + } + } + return i+n+sz; +} + +/* Context for recursion of json_pretty() +*/ +typedef struct JsonPretty JsonPretty; +struct JsonPretty { + JsonParse *pParse; /* The BLOB being rendered */ + JsonString *pOut; /* Generate pretty output into this string */ + const char *zIndent; /* Use this text for indentation */ + u32 szIndent; /* Bytes in zIndent[] */ + u32 nIndent; /* Current level of indentation */ +}; + +/* Append indentation to the pretty JSON under construction */ +static void jsonPrettyIndent(JsonPretty *pPretty){ + u32 jj; + for(jj=0; jjnIndent; jj++){ + jsonAppendRaw(pPretty->pOut, pPretty->zIndent, pPretty->szIndent); + } +} + +/* +** Translate the binary JSONB representation of JSON beginning at +** pParse->aBlob[i] into a JSON text string. Append the JSON +** text onto the end of pOut. Return the index in pParse->aBlob[] +** of the first byte past the end of the element that is translated. +** +** This is a variant of jsonTranslateBlobToText() that "pretty-prints" +** the output. Extra whitespace is inserted to make the JSON easier +** for humans to read. +** +** If an error is detected in the BLOB input, the pOut->eErr flag +** might get set to JSTRING_MALFORMED. But not all BLOB input errors +** are detected. So a malformed JSONB input might either result +** in an error, or in incorrect JSON. +** +** The pOut->eErr JSTRING_OOM flag is set on a OOM. +*/ +static u32 jsonTranslateBlobToPrettyText( + JsonPretty *pPretty, /* Pretty-printing context */ + u32 i /* Start rendering at this index */ +){ + u32 sz, n, j, iEnd; + JsonParse *pParse = pPretty->pParse; + JsonString *pOut = pPretty->pOut; + n = jsonbPayloadSize(pParse, i, &sz); + if( n==0 ){ + pOut->eErr |= JSTRING_MALFORMED; + return pParse->nBlob+1; + } + switch( pParse->aBlob[i] & 0x0f ){ + case JSONB_ARRAY: { + j = i+n; + iEnd = j+sz; + jsonAppendChar(pOut, '['); + if( jnIndent++; + if( pPretty->nIndent >= JSON_MAX_DEPTH ){ + jsonStringTooDeep(pOut); + } + while( pOut->eErr==0 ){ + jsonPrettyIndent(pPretty); + j = jsonTranslateBlobToPrettyText(pPretty, j); + if( j>=iEnd ) break; + jsonAppendRawNZ(pOut, ",\n", 2); + } + jsonAppendChar(pOut, '\n'); + pPretty->nIndent--; + jsonPrettyIndent(pPretty); + } + jsonAppendChar(pOut, ']'); + i = iEnd; + break; + } + case JSONB_OBJECT: { + j = i+n; + iEnd = j+sz; + jsonAppendChar(pOut, '{'); + if( jnIndent++; + if( pPretty->nIndent >= JSON_MAX_DEPTH ){ + jsonStringTooDeep(pOut); + } + pParse->iDepth = pPretty->nIndent; + while( pOut->eErr==0 ){ + jsonPrettyIndent(pPretty); + j = jsonTranslateBlobToText(pParse, j, pOut); + if( j>iEnd ){ + pOut->eErr |= JSTRING_MALFORMED; + break; + } + jsonAppendRawNZ(pOut, ": ", 2); + j = jsonTranslateBlobToPrettyText(pPretty, j); + if( j>=iEnd ) break; + jsonAppendRawNZ(pOut, ",\n", 2); + } + jsonAppendChar(pOut, '\n'); + pPretty->nIndent--; + jsonPrettyIndent(pPretty); + } + jsonAppendChar(pOut, '}'); + i = iEnd; + break; + } + default: { + i = jsonTranslateBlobToText(pParse, i, pOut); + break; + } + } + return i; +} + +/* +** Given that a JSONB_ARRAY object starts at offset i, return +** the number of entries in that array. +*/ +static u32 jsonbArrayCount(JsonParse *pParse, u32 iRoot){ + u32 n, sz, i, iEnd; + u32 k = 0; + n = jsonbPayloadSize(pParse, iRoot, &sz); + iEnd = iRoot+n+sz; + for(i=iRoot+n; n>0 && idelta. +*/ +static void jsonAfterEditSizeAdjust(JsonParse *pParse, u32 iRoot){ + u32 sz = 0; + u32 nBlob; + assert( pParse->delta!=0 ); + assert( pParse->nBlobAlloc >= pParse->nBlob ); + nBlob = pParse->nBlob; + pParse->nBlob = pParse->nBlobAlloc; + (void)jsonbPayloadSize(pParse, iRoot, &sz); + pParse->nBlob = nBlob; + sz += pParse->delta; + pParse->delta += jsonBlobChangePayloadSize(pParse, iRoot, sz); +} + +/* +** If the JSONB at aIns[0..nIns-1] can be expanded (by denormalizing the +** size field) by d bytes, then write the expansion into aOut[] and +** return true. In this way, an overwrite happens without changing the +** size of the JSONB, which reduces memcpy() operations and also make it +** faster and easier to update the B-Tree entry that contains the JSONB +** in the database. +** +** If the expansion of aIns[] by d bytes cannot be (easily) accomplished +** then return false. +** +** The d parameter is guaranteed to be between 1 and 8. +** +** This routine is an optimization. A correct answer is obtained if it +** always leaves the output unchanged and returns false. +*/ +static int jsonBlobOverwrite( + u8 *aOut, /* Overwrite here */ + const u8 *aIns, /* New content */ + u32 nIns, /* Bytes of new content */ + u32 d /* Need to expand new content by this much */ +){ + u32 szPayload; /* Bytes of payload */ + u32 i; /* New header size, after expansion & a loop counter */ + u8 szHdr; /* Size of header before expansion */ + + /* Lookup table for finding the upper 4 bits of the first byte of the + ** expanded aIns[], based on the size of the expanded aIns[] header: + ** + ** 2 3 4 5 6 7 8 9 */ + static const u8 aType[] = { 0xc0, 0xd0, 0, 0xe0, 0, 0, 0, 0xf0 }; + + if( (aIns[0]&0x0f)<=2 ) return 0; /* Cannot enlarge NULL, true, false */ + switch( aIns[0]>>4 ){ + default: { /* aIns[] header size 1 */ + if( ((1<=2 && i<=9 && aType[i-2]!=0 ); + aOut[0] = (aIns[0] & 0x0f) | aType[i-2]; + memcpy(&aOut[i], &aIns[szHdr], nIns-szHdr); + szPayload = nIns - szHdr; + while( 1/*edit-by-break*/ ){ + i--; + aOut[i] = szPayload & 0xff; + if( i==1 ) break; + szPayload >>= 8; + } + assert( (szPayload>>8)==0 ); + return 1; +} + +/* +** Modify the JSONB blob at pParse->aBlob by removing nDel bytes of +** content beginning at iDel, and replacing them with nIns bytes of +** content given by aIns. +** +** nDel may be zero, in which case no bytes are removed. But iDel is +** still important as new bytes will be insert beginning at iDel. +** +** aIns may be zero, in which case space is created to hold nIns bytes +** beginning at iDel, but that space is uninitialized. +** +** Set pParse->oom if an OOM occurs. +*/ +static void jsonBlobEdit( + JsonParse *pParse, /* The JSONB to be modified is in pParse->aBlob */ + u32 iDel, /* First byte to be removed */ + u32 nDel, /* Number of bytes to remove */ + const u8 *aIns, /* Content to insert */ + u32 nIns /* Bytes of content to insert */ +){ + i64 d = (i64)nIns - (i64)nDel; + assert( pParse->nBlob >= (u64)iDel + (u64)nDel ); + if( d<0 && d>=(-8) && aIns!=0 + && jsonBlobOverwrite(&pParse->aBlob[iDel], aIns, nIns, (int)-d) + ){ + return; + } + if( d!=0 ){ + if( pParse->nBlob + d > pParse->nBlobAlloc ){ + jsonBlobExpand(pParse, pParse->nBlob+d); + if( pParse->oom ) return; + } + memmove(&pParse->aBlob[iDel+nIns], + &pParse->aBlob[iDel+nDel], + pParse->nBlob - (iDel+nDel)); + pParse->nBlob += d; + pParse->delta += d; + } + if( nIns && aIns ){ + memcpy(&pParse->aBlob[iDel], aIns, nIns); + } +} + +/* +** Return the number of escaped newlines to be ignored. +** An escaped newline is a one of the following byte sequences: +** +** 0x5c 0x0a +** 0x5c 0x0d +** 0x5c 0x0d 0x0a +** 0x5c 0xe2 0x80 0xa8 +** 0x5c 0xe2 0x80 0xa9 +*/ +static u32 jsonBytesToBypass(const char *z, u32 n){ + u32 i = 0; + while( i+10 ); + assert( z[0]=='\\' ); + if( n<2 ){ + *piOut = JSON_INVALID_CHAR; + return n; + } + switch( (u8)z[1] ){ + case 'u': { + u32 v, vlo; + if( n<6 ){ + *piOut = JSON_INVALID_CHAR; + return n; + } + v = jsonHexToInt4(&z[2]); + if( (v & 0xfc00)==0xd800 + && n>=12 + && z[6]=='\\' + && z[7]=='u' + && ((vlo = jsonHexToInt4(&z[8]))&0xfc00)==0xdc00 + ){ + *piOut = ((v&0x3ff)<<10) + (vlo&0x3ff) + 0x10000; + return 12; + }else{ + *piOut = v; + return 6; + } + } + case 'b': { *piOut = '\b'; return 2; } + case 'f': { *piOut = '\f'; return 2; } + case 'n': { *piOut = '\n'; return 2; } + case 'r': { *piOut = '\r'; return 2; } + case 't': { *piOut = '\t'; return 2; } + case 'v': { *piOut = '\v'; return 2; } + case '0': { + /* JSON5 requires that the \0 escape not be followed by a digit. + ** But SQLite did not enforce this restriction in versions 3.42.0 + ** through 3.49.2. That was a bug. But some applications might have + ** come to depend on that bug. Use the SQLITE_BUG_COMPATIBLE_20250510 + ** option to restore the old buggy behavior. */ +#ifdef SQLITE_BUG_COMPATIBLE_20250510 + /* Legacy bug-compatible behavior */ + *piOut = 0; +#else + /* Correct behavior */ + *piOut = (n>2 && sqlite3Isdigit(z[2])) ? JSON_INVALID_CHAR : 0; +#endif + return 2; + } + case '\'': + case '"': + case '/': + case '\\':{ *piOut = z[1]; return 2; } + case 'x': { + if( n<4 ){ + *piOut = JSON_INVALID_CHAR; + return n; + } + *piOut = (jsonHexToInt(z[2])<<4) | jsonHexToInt(z[3]); + return 4; + } + case 0xe2: + case '\r': + case '\n': { + u32 nSkip = jsonBytesToBypass(z, n); + if( nSkip==0 ){ + *piOut = JSON_INVALID_CHAR; + return n; + }else if( nSkip==n ){ + *piOut = 0; + return n; + }else if( z[nSkip]=='\\' ){ + return nSkip + jsonUnescapeOneChar(&z[nSkip], n-nSkip, piOut); + }else{ + int sz = sqlite3Utf8ReadLimited((u8*)&z[nSkip], n-nSkip, piOut); + return nSkip + sz; + } + } + default: { + *piOut = JSON_INVALID_CHAR; + return 2; + } + } +} + + +/* +** Compare two object labels. Return 1 if they are equal and +** 0 if they differ. +** +** In this version, we know that one or the other or both of the +** two comparands contains an escape sequence. +*/ +static SQLITE_NOINLINE int jsonLabelCompareEscaped( + const char *zLeft, /* The left label */ + u32 nLeft, /* Size of the left label in bytes */ + int rawLeft, /* True if zLeft contains no escapes */ + const char *zRight, /* The right label */ + u32 nRight, /* Size of the right label in bytes */ + int rawRight /* True if zRight is escape-free */ +){ + u32 cLeft, cRight; + assert( rawLeft==0 || rawRight==0 ); + while( 1 /*exit-by-return*/ ){ + if( nLeft==0 ){ + cLeft = 0; + }else if( rawLeft || zLeft[0]!='\\' ){ + cLeft = ((u8*)zLeft)[0]; + if( cLeft>=0xc0 ){ + int sz = sqlite3Utf8ReadLimited((u8*)zLeft, nLeft, &cLeft); + zLeft += sz; + nLeft -= sz; + }else{ + zLeft++; + nLeft--; + } + }else{ + u32 n = jsonUnescapeOneChar(zLeft, nLeft, &cLeft); + zLeft += n; + assert( n<=nLeft ); + nLeft -= n; + } + if( nRight==0 ){ + cRight = 0; + }else if( rawRight || zRight[0]!='\\' ){ + cRight = ((u8*)zRight)[0]; + if( cRight>=0xc0 ){ + int sz = sqlite3Utf8ReadLimited((u8*)zRight, nRight, &cRight); + zRight += sz; + nRight -= sz; + }else{ + zRight++; + nRight--; + } + }else{ + u32 n = jsonUnescapeOneChar(zRight, nRight, &cRight); + zRight += n; + assert( n<=nRight ); + nRight -= n; + } + if( cLeft!=cRight ) return 0; + if( cLeft==0 ) return 1; + } +} + +/* +** Compare two object labels. Return 1 if they are equal and +** 0 if they differ. Return -1 if an OOM occurs. +*/ +static int jsonLabelCompare( + const char *zLeft, /* The left label */ + u32 nLeft, /* Size of the left label in bytes */ + int rawLeft, /* True if zLeft contains no escapes */ + const char *zRight, /* The right label */ + u32 nRight, /* Size of the right label in bytes */ + int rawRight /* True if zRight is escape-free */ +){ + if( rawLeft && rawRight ){ + /* Simpliest case: Neither label contains escapes. A simple + ** memcmp() is sufficient. */ + if( nLeft!=nRight ) return 0; + return memcmp(zLeft, zRight, nLeft)==0; + }else{ + return jsonLabelCompareEscaped(zLeft, nLeft, rawLeft, + zRight, nRight, rawRight); + } +} + +/* +** Error returns from jsonLookupStep() +*/ +#define JSON_LOOKUP_ERROR 0xffffffff +#define JSON_LOOKUP_NOTFOUND 0xfffffffe +#define JSON_LOOKUP_NOTARRAY 0xfffffffd +#define JSON_LOOKUP_TOODEEP 0xfffffffc +#define JSON_LOOKUP_PATHERROR 0xfffffffb +#define JSON_LOOKUP_ISERROR(x) ((x)>=JSON_LOOKUP_PATHERROR) + +/* Forward declaration */ +static u32 jsonLookupStep(JsonParse*,u32,const char*,u32); + + +/* This helper routine for jsonLookupStep() populates pIns with +** binary data that is to be inserted into pParse. +** +** In the common case, pIns just points to pParse->aIns and pParse->nIns. +** But if the zPath of the original edit operation includes path elements +** that go deeper, additional substructure must be created. +** +** For example: +** +** json_insert('{}', '$.a.b.c', 123); +** +** The search stops at '$.a' But additional substructure must be +** created for the ".b.c" part of the patch so that the final result +** is: {"a":{"b":{"c"::123}}}. This routine populates pIns with +** the binary equivalent of {"b":{"c":123}} so that it can be inserted. +** +** The caller is responsible for resetting pIns when it has finished +** using the substructure. +*/ +static u32 jsonCreateEditSubstructure( + JsonParse *pParse, /* The original JSONB that is being edited */ + JsonParse *pIns, /* Populate this with the blob data to insert */ + const char *zTail /* Tail of the path that determines substructure */ +){ + static const u8 emptyObject[] = { JSONB_ARRAY, JSONB_OBJECT }; + int rc; + memset(pIns, 0, sizeof(*pIns)); + pIns->db = pParse->db; + if( zTail[0]==0 ){ + /* No substructure. Just insert what is given in pParse. */ + pIns->aBlob = pParse->aIns; + pIns->nBlob = pParse->nIns; + rc = 0; + }else{ + /* Construct the binary substructure */ + pIns->nBlob = 1; + pIns->aBlob = (u8*)&emptyObject[zTail[0]=='.']; + pIns->eEdit = pParse->eEdit; + pIns->nIns = pParse->nIns; + pIns->aIns = pParse->aIns; + pIns->iDepth = pParse->iDepth+1; + if( pIns->iDepth >= JSON_MAX_DEPTH ){ + return JSON_LOOKUP_TOODEEP; + } + rc = jsonLookupStep(pIns, 0, zTail, 0); + pParse->iDepth--; + pParse->oom |= pIns->oom; + } + return rc; /* Error code only */ +} + +/* +** Search along zPath to find the Json element specified. Return an +** index into pParse->aBlob[] for the start of that element's value. +** +** If the value found by this routine is the value half of label/value pair +** within an object, then set pPath->iLabel to the start of the corresponding +** label, before returning. +** +** Return one of the JSON_LOOKUP error codes if problems are seen. +** +** This routine will also modify the blob. If pParse->eEdit is one of +** JEDIT_DEL, JEDIT_REPL, JEDIT_INS, JEDIT_SET, or JEDIT_AINS, then changes +** might be made to the selected value. If an edit is performed, then the +** return value does not necessarily point to the select element. If an edit +** is performed, the return value is only useful for detecting error +** conditions. +*/ +static u32 jsonLookupStep( + JsonParse *pParse, /* The JSON to search */ + u32 iRoot, /* Begin the search at this element of aBlob[] */ + const char *zPath, /* The path to search */ + u32 iLabel /* Label if iRoot is a value of in an object */ +){ + u32 i, j, k, nKey, sz, n, iEnd, rc; + const char *zKey; + u8 x; + + if( zPath[0]==0 ){ + if( pParse->eEdit && jsonBlobMakeEditable(pParse, pParse->nIns) ){ + n = jsonbPayloadSize(pParse, iRoot, &sz); + sz += n; + if( pParse->eEdit==JEDIT_DEL ){ + if( iLabel>0 ){ + sz += iRoot - iLabel; + iRoot = iLabel; + } + jsonBlobEdit(pParse, iRoot, sz, 0, 0); + }else if( pParse->eEdit==JEDIT_INS ){ + /* Already exists, so json_insert() is a no-op */ + }else if( pParse->eEdit==JEDIT_AINS ){ + /* json_array_insert() */ + if( zPath[-1]!=']' ){ + return JSON_LOOKUP_NOTARRAY; + }else{ + jsonBlobEdit(pParse, iRoot, 0, pParse->aIns, pParse->nIns); + } + }else{ + /* json_set() or json_replace() */ + jsonBlobEdit(pParse, iRoot, sz, pParse->aIns, pParse->nIns); + } + } + pParse->iLabel = iLabel; + return iRoot; + } + if( zPath[0]=='.' ){ + int rawKey = 1; + x = pParse->aBlob[iRoot]; + zPath++; + if( zPath[0]=='"' ){ + zKey = zPath + 1; + for(i=1; zPath[i] && zPath[i]!='"'; i++){ + if( zPath[i]=='\\' && zPath[i+1]!=0 ) i++; + } + nKey = i-1; + if( zPath[i] ){ + i++; + }else{ + return JSON_LOOKUP_PATHERROR; + } + testcase( nKey==0 ); + rawKey = memchr(zKey, '\\', nKey)==0; + }else{ + zKey = zPath; + for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){} + nKey = i; + if( nKey==0 ){ + return JSON_LOOKUP_PATHERROR; + } + } + if( (x & 0x0f)!=JSONB_OBJECT ) return JSON_LOOKUP_NOTFOUND; + n = jsonbPayloadSize(pParse, iRoot, &sz); + j = iRoot + n; /* j is the index of a label */ + iEnd = j+sz; + while( jaBlob[j] & 0x0f; + if( xJSONB_TEXTRAW ) return JSON_LOOKUP_ERROR; + n = jsonbPayloadSize(pParse, j, &sz); + if( n==0 ) return JSON_LOOKUP_ERROR; + k = j+n; /* k is the index of the label text */ + if( k+sz>=iEnd ) return JSON_LOOKUP_ERROR; + zLabel = (const char*)&pParse->aBlob[k]; + rawLabel = x==JSONB_TEXT || x==JSONB_TEXTRAW; + if( jsonLabelCompare(zKey, nKey, rawKey, zLabel, sz, rawLabel) ){ + u32 v = k+sz; /* v is the index of the value */ + if( ((pParse->aBlob[v])&0x0f)>JSONB_OBJECT ) return JSON_LOOKUP_ERROR; + n = jsonbPayloadSize(pParse, v, &sz); + if( n==0 || v+n+sz>iEnd ) return JSON_LOOKUP_ERROR; + assert( j>0 ); + if( ++pParse->iDepth >= JSON_MAX_DEPTH ){ + return JSON_LOOKUP_TOODEEP; + } + rc = jsonLookupStep(pParse, v, &zPath[i], j); + pParse->iDepth--; + if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot); + return rc; + } + j = k+sz; + if( ((pParse->aBlob[j])&0x0f)>JSONB_OBJECT ) return JSON_LOOKUP_ERROR; + n = jsonbPayloadSize(pParse, j, &sz); + if( n==0 ) return JSON_LOOKUP_ERROR; + j += n+sz; + } + if( j>iEnd ) return JSON_LOOKUP_ERROR; + if( pParse->eEdit>=JEDIT_INS ){ + u32 nIns; /* Total bytes to insert (label+value) */ + JsonParse v; /* BLOB encoding of the value to be inserted */ + JsonParse ix; /* Header of the label to be inserted */ + testcase( pParse->eEdit==JEDIT_INS ); + testcase( pParse->eEdit==JEDIT_SET ); + testcase( pParse->eEdit==JEDIT_AINS ); + if( pParse->eEdit==JEDIT_AINS && sqlite3_strglob("*]",&zPath[i])!=0 ){ + return JSON_LOOKUP_NOTARRAY; + } + memset(&ix, 0, sizeof(ix)); + ix.db = pParse->db; + jsonBlobAppendNode(&ix, rawKey?JSONB_TEXTRAW:JSONB_TEXT5, nKey, 0); + pParse->oom |= ix.oom; + rc = jsonCreateEditSubstructure(pParse, &v, &zPath[i]); + if( !JSON_LOOKUP_ISERROR(rc) + && jsonBlobMakeEditable(pParse, ix.nBlob+nKey+v.nBlob) + ){ + assert( !pParse->oom ); + nIns = ix.nBlob + nKey + v.nBlob; + jsonBlobEdit(pParse, j, 0, 0, nIns); + if( !pParse->oom ){ + assert( pParse->aBlob!=0 ); /* Because pParse->oom!=0 */ + assert( ix.aBlob!=0 ); /* Because pPasre->oom!=0 */ + memcpy(&pParse->aBlob[j], ix.aBlob, ix.nBlob); + k = j + ix.nBlob; + memcpy(&pParse->aBlob[k], zKey, nKey); + k += nKey; + memcpy(&pParse->aBlob[k], v.aBlob, v.nBlob); + if( ALWAYS(pParse->delta) ) jsonAfterEditSizeAdjust(pParse, iRoot); + } + } + jsonParseReset(&v); + jsonParseReset(&ix); + return rc; + } + }else if( zPath[0]=='[' ){ + u64 kk = 0; + x = pParse->aBlob[iRoot] & 0x0f; + if( x!=JSONB_ARRAY ) return JSON_LOOKUP_NOTFOUND; + n = jsonbPayloadSize(pParse, iRoot, &sz); + i = 1; + while( sqlite3Isdigit(zPath[i]) ){ + if( kk<0xffffffff ) kk = kk*10 + zPath[i] - '0'; + /* ^^^^^^^^^^--- Allow kk to be bigger than any JSON array so that + ** we get NOTFOUND instead of PATHERROR, without overflowing kk. */ + i++; + } + if( i<2 || zPath[i]!=']' ){ + if( zPath[1]=='#' ){ + kk = jsonbArrayCount(pParse, iRoot); + i = 2; + if( zPath[2]=='-' && sqlite3Isdigit(zPath[3]) ){ + u64 nn = 0; + i = 3; + do{ + if( nn<0xffffffff ) nn = nn*10 + zPath[i] - '0'; + /* ^^^^^^^^^^--- Allow nn to be bigger than any JSON array to + ** get NOTFOUND instead of PATHERROR, without overflowing nn. */ + i++; + }while( sqlite3Isdigit(zPath[i]) ); + if( nn>kk ) return JSON_LOOKUP_NOTFOUND; + kk -= nn; + } + if( zPath[i]!=']' ){ + return JSON_LOOKUP_PATHERROR; + } + }else{ + return JSON_LOOKUP_PATHERROR; + } + } + j = iRoot+n; + iEnd = j+sz; + while( jiDepth >= JSON_MAX_DEPTH ){ + return JSON_LOOKUP_TOODEEP; + } + rc = jsonLookupStep(pParse, j, &zPath[i+1], 0); + pParse->iDepth--; + if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot); + return rc; + } + kk--; + n = jsonbPayloadSize(pParse, j, &sz); + if( n==0 ) return JSON_LOOKUP_ERROR; + j += n+sz; + } + if( j>iEnd ) return JSON_LOOKUP_ERROR; + if( kk>0 ) return JSON_LOOKUP_NOTFOUND; + if( pParse->eEdit>=JEDIT_INS ){ + JsonParse v; + testcase( pParse->eEdit==JEDIT_INS ); + testcase( pParse->eEdit==JEDIT_AINS ); + testcase( pParse->eEdit==JEDIT_SET ); + rc = jsonCreateEditSubstructure(pParse, &v, &zPath[i+1]); + if( !JSON_LOOKUP_ISERROR(rc) + && jsonBlobMakeEditable(pParse, v.nBlob) + ){ + assert( !pParse->oom ); + jsonBlobEdit(pParse, j, 0, v.aBlob, v.nBlob); + } + jsonParseReset(&v); + if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot); + return rc; + } + }else{ + return JSON_LOOKUP_PATHERROR; + } + return JSON_LOOKUP_NOTFOUND; +} + +/* +** Convert a JSON BLOB into text and make that text the return value +** of an SQL function. +*/ +static void jsonReturnTextJsonFromBlob( + sqlite3_context *ctx, + const u8 *aBlob, + u32 nBlob +){ + JsonParse x; + JsonString s; + + if( NEVER(aBlob==0) ) return; + memset(&x, 0, sizeof(x)); + x.aBlob = (u8*)aBlob; + x.nBlob = nBlob; + jsonStringInit(&s, ctx); + jsonTranslateBlobToText(&x, 0, &s); + jsonReturnString(&s, 0, 0); +} + + +/* +** Return the value of the BLOB node at index i. +** +** If the value is a primitive, return it as an SQL value. +** If the value is an array or object, return it as either +** JSON text or the BLOB encoding, depending on the eMode flag +** as follows: +** +** eMode==0 JSONB if the JSON_B flag is set in userdata or +** text if the JSON_B flag is omitted from userdata. +** +** eMode==1 Text +** +** eMode==2 JSONB +*/ +static void jsonReturnFromBlob( + JsonParse *pParse, /* Complete JSON parse tree */ + u32 i, /* Index of the node */ + sqlite3_context *pCtx, /* Return value for this function */ + int eMode /* Format of return: text of JSONB */ +){ + u32 n, sz; + int rc; + sqlite3 *db = sqlite3_context_db_handle(pCtx); + + assert( eMode>=0 && eMode<=2 ); + n = jsonbPayloadSize(pParse, i, &sz); + if( n==0 ){ + sqlite3_result_error(pCtx, "malformed JSON", -1); + return; + } + switch( pParse->aBlob[i] & 0x0f ){ + case JSONB_NULL: { + if( sz ) goto returnfromblob_malformed; + sqlite3_result_null(pCtx); + break; + } + case JSONB_TRUE: { + if( sz ) goto returnfromblob_malformed; + sqlite3_result_int(pCtx, 1); + break; + } + case JSONB_FALSE: { + if( sz ) goto returnfromblob_malformed; + sqlite3_result_int(pCtx, 0); + break; + } + case JSONB_INT5: + case JSONB_INT: { + sqlite3_int64 iRes = 0; + char *z; + int bNeg = 0; + char x; + if( sz==0 ) goto returnfromblob_malformed; + x = (char)pParse->aBlob[i+n]; + if( x=='-' ){ + if( sz<2 ) goto returnfromblob_malformed; + n++; + sz--; + bNeg = 1; + } + z = sqlite3DbStrNDup(db, (const char*)&pParse->aBlob[i+n], (int)sz); + if( z==0 ) goto returnfromblob_oom; + rc = sqlite3DecOrHexToI64(z, &iRes); + sqlite3DbFree(db, z); + if( rc==0 ){ + if( iRes<0 ){ + /* A hexadecimal literal with 16 significant digits and with the + ** high-order bit set is a negative integer in SQLite (and hence + ** iRes comes back as negative) but should be interpreted as a + ** positive value if it occurs within JSON. The value is too + ** large to appear as an SQLite integer so it must be converted + ** into floating point. */ + double r; + r = (double)*(sqlite3_uint64*)&iRes; + sqlite3_result_double(pCtx, bNeg ? -r : r); + }else{ + sqlite3_result_int64(pCtx, bNeg ? -iRes : iRes); + } + }else if( rc==3 && bNeg ){ + sqlite3_result_int64(pCtx, SMALLEST_INT64); + }else if( rc==1 ){ + goto returnfromblob_malformed; + }else{ + if( bNeg ){ n--; sz++; } + goto to_double; + } + break; + } + case JSONB_FLOAT5: + case JSONB_FLOAT: { + double r; + char *z; + if( sz==0 ) goto returnfromblob_malformed; + to_double: + z = sqlite3DbStrNDup(db, (const char*)&pParse->aBlob[i+n], (int)sz); + if( z==0 ) goto returnfromblob_oom; + rc = sqlite3AtoF(z, &r); + sqlite3DbFree(db, z); + if( rc<=0 ) goto returnfromblob_malformed; + sqlite3_result_double(pCtx, r); + break; + } + case JSONB_TEXTRAW: + case JSONB_TEXT: { + sqlite3_result_text(pCtx, (char*)&pParse->aBlob[i+n], sz, + SQLITE_TRANSIENT); + break; + } + case JSONB_TEXT5: + case JSONB_TEXTJ: { + /* Translate JSON formatted string into raw text */ + u32 iIn, iOut; + const char *z; + char *zOut; + u32 nOut = sz; + z = (const char*)&pParse->aBlob[i+n]; + zOut = sqlite3DbMallocRaw(db, ((u64)nOut)+1); + if( zOut==0 ) goto returnfromblob_oom; + for(iIn=iOut=0; iIn=2 ); + zOut[iOut++] = (char)(0xc0 | (v>>6)); + zOut[iOut++] = 0x80 | (v&0x3f); + }else if( v<0x10000 ){ + assert( szEscape>=3 ); + zOut[iOut++] = 0xe0 | (v>>12); + zOut[iOut++] = 0x80 | ((v>>6)&0x3f); + zOut[iOut++] = 0x80 | (v&0x3f); + }else if( v==JSON_INVALID_CHAR ){ + /* Silently ignore illegal unicode */ + }else{ + assert( szEscape>=4 ); + zOut[iOut++] = 0xf0 | (v>>18); + zOut[iOut++] = 0x80 | ((v>>12)&0x3f); + zOut[iOut++] = 0x80 | ((v>>6)&0x3f); + zOut[iOut++] = 0x80 | (v&0x3f); + } + iIn += szEscape - 1; + }else{ + zOut[iOut++] = c; + } + } /* end for() */ + assert( iOut<=nOut ); + zOut[iOut] = 0; + sqlite3_result_text(pCtx, zOut, iOut, SQLITE_DYNAMIC); + break; + } + case JSONB_ARRAY: + case JSONB_OBJECT: { + if( eMode==0 ){ + if( (SQLITE_PTR_TO_INT(sqlite3_user_data(pCtx)) & JSON_BLOB)!=0 ){ + eMode = 2; + }else{ + eMode = 1; + } + } + if( eMode==2 ){ + sqlite3_result_blob(pCtx, &pParse->aBlob[i], sz+n, SQLITE_TRANSIENT); + }else{ + jsonReturnTextJsonFromBlob(pCtx, &pParse->aBlob[i], sz+n); + } + break; + } + default: { + goto returnfromblob_malformed; + } + } + return; + +returnfromblob_oom: + sqlite3_result_error_nomem(pCtx); + return; + +returnfromblob_malformed: + sqlite3_result_error(pCtx, "malformed JSON", -1); + return; +} + +/* +** pArg is a function argument that might be an SQL value or a JSON +** value. Figure out what it is and encode it as a JSONB blob. +** Return the results in pParse. +** +** pParse is uninitialized upon entry. This routine will handle the +** initialization of pParse. The result will be contained in +** pParse->aBlob and pParse->nBlob. pParse->aBlob might be dynamically +** allocated (if pParse->nBlobAlloc is greater than zero) in which case +** the caller is responsible for freeing the space allocated to pParse->aBlob +** when it has finished with it. Or pParse->aBlob might be a static string +** or a value obtained from sqlite3_value_blob(pArg). +** +** If the argument is a BLOB that is clearly not a JSONB, then this +** function might set an error message in ctx and return non-zero. +** It might also set an error message and return non-zero on an OOM error. +*/ +static int jsonFunctionArgToBlob( + sqlite3_context *ctx, + sqlite3_value *pArg, + JsonParse *pParse +){ + int eType = sqlite3_value_type(pArg); + static u8 aNull[] = { 0x00 }; + memset(pParse, 0, sizeof(pParse[0])); + pParse->db = sqlite3_context_db_handle(ctx); + switch( eType ){ + default: { + pParse->aBlob = aNull; + pParse->nBlob = 1; + return 0; + } + case SQLITE_BLOB: { + if( !jsonArgIsJsonb(pArg, pParse) ){ + sqlite3_result_error(ctx, "JSON cannot hold BLOB values", -1); + return 1; + } + break; + } + case SQLITE_TEXT: { + const char *zJson = (const char*)sqlite3_value_text(pArg); + int nJson = sqlite3_value_bytes(pArg); + if( zJson==0 ) return 1; + if( sqlite3_value_subtype(pArg)==JSON_SUBTYPE ){ + pParse->zJson = (char*)zJson; + pParse->nJson = nJson; + if( jsonConvertTextToBlob(pParse, ctx) ){ + sqlite3_result_error(ctx, "malformed JSON", -1); + sqlite3DbFree(pParse->db, pParse->aBlob); + memset(pParse, 0, sizeof(pParse[0])); + return 1; + } + }else{ + jsonBlobAppendNode(pParse, JSONB_TEXTRAW, nJson, zJson); + } + break; + } + case SQLITE_FLOAT: { + double r = sqlite3_value_double(pArg); + if( NEVER(sqlite3IsNaN(r)) ){ + jsonBlobAppendNode(pParse, JSONB_NULL, 0, 0); + }else{ + int n = sqlite3_value_bytes(pArg); + const char *z = (const char*)sqlite3_value_text(pArg); + if( z==0 ) return 1; + if( z[0]=='I' ){ + jsonBlobAppendNode(pParse, JSONB_FLOAT, 5, "9e999"); + }else if( z[0]=='-' && z[1]=='I' ){ + jsonBlobAppendNode(pParse, JSONB_FLOAT, 6, "-9e999"); + }else{ + jsonBlobAppendNode(pParse, JSONB_FLOAT, n, z); + } + } + break; + } + case SQLITE_INTEGER: { + int n = sqlite3_value_bytes(pArg); + const char *z = (const char*)sqlite3_value_text(pArg); + if( z==0 ) return 1; + jsonBlobAppendNode(pParse, JSONB_INT, n, z); + break; + } + } + if( pParse->oom ){ + sqlite3_result_error_nomem(ctx); + return 1; + }else{ + return 0; + } +} + +/* +** Generate a path error. +** +** The specifics of the error are determined by the rc argument. +** +** rc error +** ----------------- ---------------------- +** JSON_LOOKUP_ARRAY "not an array" +** JSON_LOOKUP_TOODEEP "JSON nested too deep" +** JSON_LOOKUP_ERROR "malformed JSON" +** otherwise... "bad JSON path" +** +** If ctx is not NULL then push the error message into ctx and return NULL. +** If ctx is NULL, then return the text of the error message. +*/ +static char *jsonBadPathError( + sqlite3_context *ctx, /* The function call containing the error */ + const char *zPath, /* The path with the problem */ + int rc /* Maybe JSON_LOOKUP_NOTARRAY */ +){ + char *zMsg; + if( rc==(int)JSON_LOOKUP_NOTARRAY ){ + zMsg = sqlite3_mprintf("not an array element: %Q", zPath); + }else if( rc==(int)JSON_LOOKUP_ERROR ){ + zMsg = sqlite3_mprintf("malformed JSON"); + }else if( rc==(int)JSON_LOOKUP_TOODEEP ){ + zMsg = sqlite3_mprintf("JSON path too deep"); + }else{ + zMsg = sqlite3_mprintf("bad JSON path: %Q", zPath); + } + if( ctx==0 ) return zMsg; + if( zMsg ){ + sqlite3_result_error(ctx, zMsg, -1); + sqlite3_free(zMsg); + }else{ + sqlite3_result_error_nomem(ctx); + } + return 0; +} + +/* argv[0] is a BLOB that seems likely to be a JSONB. Subsequent +** arguments come in pairs where each pair contains a JSON path and +** content to insert or set at that patch. Do the updates +** and return the result. +** +** The specific operation is determined by eEdit, which can be one +** of JEDIT_INS, JEDIT_REPL, JEDIT_SET, or JEDIT_AINS. +*/ +static void jsonInsertIntoBlob( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv, + int eEdit /* JEDIT_INS, JEDIT_REPL, JEDIT_SET, JEDIT_AINS */ +){ + int i; + u32 rc = 0; + const char *zPath = 0; + int flgs; + JsonParse *p; + JsonParse ax; + + assert( (argc&1)==1 ); + flgs = argc==1 ? 0 : JSON_EDITABLE; + p = jsonParseFuncArg(ctx, argv[0], flgs); + if( p==0 ) return; + for(i=1; inBlob, ax.aBlob, ax.nBlob); + } + rc = 0; + }else{ + p->eEdit = eEdit; + p->nIns = ax.nBlob; + p->aIns = ax.aBlob; + p->delta = 0; + p->iDepth = 0; + rc = jsonLookupStep(p, 0, zPath+1, 0); + } + jsonParseReset(&ax); + if( rc==JSON_LOOKUP_NOTFOUND ) continue; + if( JSON_LOOKUP_ISERROR(rc) ) goto jsonInsertIntoBlob_patherror; + } + jsonReturnParse(ctx, p); + jsonParseFree(p); + return; + +jsonInsertIntoBlob_patherror: + jsonParseFree(p); + jsonBadPathError(ctx, zPath, rc); + return; +} + +/* +** If pArg is a blob that seems like a JSONB blob, then initialize +** p to point to that JSONB and return TRUE. If pArg does not seem like +** a JSONB blob, then return FALSE. +** +** For small BLOBs (having no more than 7 bytes of payload) a full +** validity check is done. So for small BLOBs this routine only returns +** true if the value is guaranteed to be a valid JSONB. For larger BLOBs +** (8 byte or more of payload) only the size of the outermost element is +** checked to verify that the BLOB is superficially valid JSONB. +** +** A full JSONB validation is done on smaller BLOBs because those BLOBs might +** also be text JSON that has been incorrectly cast into a BLOB. +** (See tag-20240123-a and https://sqlite.org/forum/forumpost/012136abd5) +** If the BLOB is 9 bytes are larger, then it is not possible for the +** superficial size check done here to pass if the input is really text +** JSON so we do not need to look deeper in that case. +** +** Why we only need to do full JSONB validation for smaller BLOBs: +** +** The first byte of valid JSON text must be one of: '{', '[', '"', ' ', '\n', +** '\r', '\t', '-', or a digit '0' through '9'. Of these, only a subset +** can also be the first byte of JSONB: '{', '[', and digits '3' +** through '9'. In every one of those cases, the payload size is 7 bytes +** or less. So if we do full JSONB validation for every BLOB where the +** payload is less than 7 bytes, we will never get a false positive for +** JSONB on an input that is really text JSON. +*/ +static int jsonArgIsJsonb(sqlite3_value *pArg, JsonParse *p){ + u32 n, sz = 0; + u8 c; + if( sqlite3_value_type(pArg)!=SQLITE_BLOB ) return 0; + p->aBlob = (u8*)sqlite3_value_blob(pArg); + p->nBlob = (u32)sqlite3_value_bytes(pArg); + if( p->nBlob>0 + && ALWAYS(p->aBlob!=0) + && ((c = p->aBlob[0]) & 0x0f)<=JSONB_OBJECT + && (n = jsonbPayloadSize(p, 0, &sz))>0 + && sz+n==p->nBlob + && ((c & 0x0f)>JSONB_FALSE || sz==0) + && (sz>7 + || (c!=0x7b && c!=0x5b && !sqlite3Isdigit(c)) + || jsonbValidityCheck(p, 0, p->nBlob, 1)==0) + ){ + return 1; + } + p->aBlob = 0; + p->nBlob = 0; + return 0; +} + +/* +** Generate a JsonParse object, containing valid JSONB in aBlob and nBlob, +** from the SQL function argument pArg. Return a pointer to the new +** JsonParse object. +** +** Ownership of the new JsonParse object is passed to the caller. The +** caller should invoke jsonParseFree() on the return value when it +** has finished using it. +** +** If any errors are detected, an appropriate error messages is set +** using sqlite3_result_error() or the equivalent and this routine +** returns NULL. This routine also returns NULL if the pArg argument +** is an SQL NULL value, but no error message is set in that case. This +** is so that SQL functions that are given NULL arguments will return +** a NULL value. +*/ +static JsonParse *jsonParseFuncArg( + sqlite3_context *ctx, + sqlite3_value *pArg, + u32 flgs +){ + int eType; /* Datatype of pArg */ + JsonParse *p = 0; /* Value to be returned */ + JsonParse *pFromCache = 0; /* Value taken from cache */ + sqlite3 *db; /* The database connection */ + + assert( ctx!=0 ); + eType = sqlite3_value_type(pArg); + if( eType==SQLITE_NULL ){ + return 0; + } + pFromCache = jsonCacheSearch(ctx, pArg); + if( pFromCache ){ + pFromCache->nJPRef++; + if( (flgs & JSON_EDITABLE)==0 ){ + return pFromCache; + } + } + db = sqlite3_context_db_handle(ctx); +rebuild_from_cache: + p = sqlite3DbMallocZero(db, sizeof(*p)); + if( p==0 ) goto json_pfa_oom; + memset(p, 0, sizeof(*p)); + p->db = db; + p->nJPRef = 1; + if( pFromCache!=0 ){ + u32 nBlob = pFromCache->nBlob; + p->aBlob = sqlite3DbMallocRaw(db, nBlob); + if( p->aBlob==0 ) goto json_pfa_oom; + memcpy(p->aBlob, pFromCache->aBlob, nBlob); + p->nBlobAlloc = p->nBlob = nBlob; + p->hasNonstd = pFromCache->hasNonstd; + jsonParseFree(pFromCache); + return p; + } + if( eType==SQLITE_BLOB ){ + if( jsonArgIsJsonb(pArg,p) ){ + if( (flgs & JSON_EDITABLE)!=0 && jsonBlobMakeEditable(p, 0)==0 ){ + goto json_pfa_oom; + } + return p; + } + /* If the blob is not valid JSONB, fall through into trying to cast + ** the blob into text which is then interpreted as JSON. (tag-20240123-a) + ** + ** This goes against all historical documentation about how the SQLite + ** JSON functions were suppose to work. From the beginning, blob was + ** reserved for expansion and a blob value should have raised an error. + ** But it did not, due to a bug. And many applications came to depend + ** upon this buggy behavior, especially when using the CLI and reading + ** JSON text using readfile(), which returns a blob. For this reason + ** we will continue to support the bug moving forward. + ** See for example https://sqlite.org/forum/forumpost/012136abd5292b8d + */ + } + p->zJson = (char*)sqlite3_value_text(pArg); + p->nJson = sqlite3_value_bytes(pArg); + if( db->mallocFailed ) goto json_pfa_oom; + if( p->nJson==0 ) goto json_pfa_malformed; + assert( p->zJson!=0 ); + if( jsonConvertTextToBlob(p, (flgs & JSON_KEEPERROR) ? 0 : ctx) ){ + if( flgs & JSON_KEEPERROR ){ + p->nErr = 1; + return p; + }else{ + jsonParseFree(p); + return 0; + } + }else{ + int isRCStr = sqlite3ValueIsOfClass(pArg, sqlite3RCStrUnref); + int rc; + if( !isRCStr ){ + char *zNew = sqlite3RCStrNew( p->nJson ); + if( zNew==0 ) goto json_pfa_oom; + memcpy(zNew, p->zJson, p->nJson); + p->zJson = zNew; + p->zJson[p->nJson] = 0; + }else{ + sqlite3RCStrRef(p->zJson); + } + p->bJsonIsRCStr = 1; + rc = jsonCacheInsert(ctx, p); + if( rc==SQLITE_NOMEM ) goto json_pfa_oom; + if( flgs & JSON_EDITABLE ){ + pFromCache = p; + p = 0; + goto rebuild_from_cache; + } + } + return p; + +json_pfa_malformed: + if( flgs & JSON_KEEPERROR ){ + p->nErr = 1; + return p; + }else{ + jsonParseFree(p); + sqlite3_result_error(ctx, "malformed JSON", -1); + return 0; + } + +json_pfa_oom: + jsonParseFree(pFromCache); + jsonParseFree(p); + sqlite3_result_error_nomem(ctx); + return 0; +} + +/* +** Make the return value of a JSON function either the raw JSONB blob +** or make it JSON text, depending on whether the JSON_BLOB flag is +** set on the function. +*/ +static void jsonReturnParse( + sqlite3_context *ctx, + JsonParse *p +){ + int flgs; + if( p->oom ){ + sqlite3_result_error_nomem(ctx); + return; + } + flgs = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + if( flgs & JSON_BLOB ){ + if( p->nBlobAlloc>0 && !p->bReadOnly ){ + sqlite3_result_blob(ctx, p->aBlob, p->nBlob, SQLITE_DYNAMIC); + p->nBlobAlloc = 0; + }else{ + sqlite3_result_blob(ctx, p->aBlob, p->nBlob, SQLITE_TRANSIENT); + } + }else{ + JsonString s; + jsonStringInit(&s, ctx); + p->delta = 0; + jsonTranslateBlobToText(p, 0, &s); + jsonReturnString(&s, p, ctx); + sqlite3_result_subtype(ctx, JSON_SUBTYPE); + } +} + +/**************************************************************************** +** SQL functions used for testing and debugging +****************************************************************************/ + +#if SQLITE_DEBUG +/* +** Decode JSONB bytes in aBlob[] starting at iStart through but not +** including iEnd. Indent the +** content by nIndent spaces. +*/ +static void jsonDebugPrintBlob( + JsonParse *pParse, /* JSON content */ + u32 iStart, /* Start rendering here */ + u32 iEnd, /* Do not render this byte or any byte after this one */ + int nIndent, /* Indent by this many spaces */ + sqlite3_str *pOut /* Generate output into this sqlite3_str object */ +){ + while( iStartaBlob[iStart] & 0x0f; + u32 savedNBlob = pParse->nBlob; + sqlite3_str_appendf(pOut, "%5d:%*s", iStart, nIndent, ""); + if( pParse->nBlobAlloc>pParse->nBlob ){ + pParse->nBlob = pParse->nBlobAlloc; + } + nn = n = jsonbPayloadSize(pParse, iStart, &sz); + if( nn==0 ) nn = 1; + if( sz>0 && xaBlob[iStart+i]); + } + if( n==0 ){ + sqlite3_str_appendf(pOut, " ERROR invalid node size\n"); + iStart = n==0 ? iStart+1 : iEnd; + continue; + } + pParse->nBlob = savedNBlob; + if( iStart+n+sz>iEnd ){ + iEnd = iStart+n+sz; + if( iEnd>pParse->nBlob ){ + if( pParse->nBlobAlloc>0 && iEnd>pParse->nBlobAlloc ){ + iEnd = pParse->nBlobAlloc; + }else{ + iEnd = pParse->nBlob; + } + } + } + sqlite3_str_appendall(pOut," <-- "); + switch( x ){ + case JSONB_NULL: sqlite3_str_appendall(pOut,"null"); break; + case JSONB_TRUE: sqlite3_str_appendall(pOut,"true"); break; + case JSONB_FALSE: sqlite3_str_appendall(pOut,"false"); break; + case JSONB_INT: sqlite3_str_appendall(pOut,"int"); break; + case JSONB_INT5: sqlite3_str_appendall(pOut,"int5"); break; + case JSONB_FLOAT: sqlite3_str_appendall(pOut,"float"); break; + case JSONB_FLOAT5: sqlite3_str_appendall(pOut,"float5"); break; + case JSONB_TEXT: sqlite3_str_appendall(pOut,"text"); break; + case JSONB_TEXTJ: sqlite3_str_appendall(pOut,"textj"); break; + case JSONB_TEXT5: sqlite3_str_appendall(pOut,"text5"); break; + case JSONB_TEXTRAW: sqlite3_str_appendall(pOut,"textraw"); break; + case JSONB_ARRAY: { + sqlite3_str_appendf(pOut,"array, %u bytes\n", sz); + jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2, pOut); + showContent = 0; + break; + } + case JSONB_OBJECT: { + sqlite3_str_appendf(pOut, "object, %u bytes\n", sz); + jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2, pOut); + showContent = 0; + break; + } + default: { + sqlite3_str_appendall(pOut, "ERROR: unknown node type\n"); + showContent = 0; + break; + } + } + if( showContent ){ + if( sz==0 && x<=JSONB_FALSE ){ + sqlite3_str_append(pOut, "\n", 1); + }else{ + u32 j; + sqlite3_str_appendall(pOut, ": \""); + for(j=iStart+n; jaBlob[j]; + if( c<0x20 || c>=0x7f ) c = '.'; + sqlite3_str_append(pOut, (char*)&c, 1); + } + sqlite3_str_append(pOut, "\"\n", 2); + } + } + iStart += n + sz; + } +} +static void jsonShowParse(JsonParse *pParse){ + sqlite3_str out; + char zBuf[1000]; + if( pParse==0 ){ + printf("NULL pointer\n"); + return; + }else{ + printf("nBlobAlloc = %u\n", pParse->nBlobAlloc); + printf("nBlob = %u\n", pParse->nBlob); + printf("delta = %d\n", pParse->delta); + if( pParse->nBlob==0 ) return; + printf("content (bytes 0..%u):\n", pParse->nBlob-1); + } + sqlite3StrAccumInit(&out, 0, zBuf, sizeof(zBuf), 1000000); + jsonDebugPrintBlob(pParse, 0, pParse->nBlob, 0, &out); + printf("%s", sqlite3_str_value(&out)); + sqlite3_str_reset(&out); +} +#endif /* SQLITE_DEBUG */ + +#ifdef SQLITE_DEBUG +/* +** SQL function: json_parse(JSON) +** +** Parse JSON using jsonParseFuncArg(). Return text that is a +** human-readable dump of the binary JSONB for the input parameter. +*/ +static void jsonParseFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonParse *p; /* The parse */ + sqlite3_str out; + + assert( argc>=1 ); + sqlite3StrAccumInit(&out, 0, 0, 0, 1000000); + p = jsonParseFuncArg(ctx, argv[0], 0); + if( p==0 ) return; + if( argc==1 ){ + jsonDebugPrintBlob(p, 0, p->nBlob, 0, &out); + sqlite3_result_text64(ctx,out.zText,out.nChar,SQLITE_TRANSIENT,SQLITE_UTF8); + }else{ + jsonShowParse(p); + } + jsonParseFree(p); + sqlite3_str_reset(&out); +} +#endif /* SQLITE_DEBUG */ + +/**************************************************************************** +** Scalar SQL function implementations +****************************************************************************/ + +/* +** Implementation of the json_quote(VALUE) function. Return a JSON value +** corresponding to the SQL value input. Mostly this means putting +** double-quotes around strings and returning the unquoted string "null" +** when given a NULL input. +*/ +static void jsonQuoteFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonString jx; + UNUSED_PARAMETER(argc); + + jsonStringInit(&jx, ctx); + jsonAppendSqlValue(&jx, argv[0]); + jsonReturnString(&jx, 0, 0); + sqlite3_result_subtype(ctx, JSON_SUBTYPE); +} + +/* +** Implementation of the json_array(VALUE,...) function. Return a JSON +** array that contains all values given in arguments. Or if any argument +** is a BLOB, throw an error. +*/ +static void jsonArrayFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + int i; + JsonString jx; + + jsonStringInit(&jx, ctx); + jsonAppendChar(&jx, '['); + for(i=0; iaBlob[i] & 0x0f)==JSONB_ARRAY ){ + cnt = jsonbArrayCount(p, i); + } + if( !eErr ) sqlite3_result_int64(ctx, cnt); + jsonParseFree(p); +} + +/* True if the string is all alphanumerics and underscores */ +static int jsonAllAlphanum(const char *z, int n){ + int i; + for(i=0; i"(JSON,PATH) +** "->>"(JSON,PATH) +** +** Return the element described by PATH. Return NULL if that PATH element +** is not found. +** +** If JSON_JSON is set or if more that one PATH argument is supplied then +** always return a JSON representation of the result. If JSON_SQL is set, +** then always return an SQL representation of the result. If neither flag +** is present and argc==2, then return JSON for objects and arrays and SQL +** for all other values. +** +** When multiple PATH arguments are supplied, the result is a JSON array +** containing the result of each PATH. +** +** Abbreviated JSON path expressions are allows if JSON_ABPATH, for +** compatibility with PG. +*/ +static void jsonExtractFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonParse *p = 0; /* The parse */ + int flags; /* Flags associated with the function */ + int i; /* Loop counter */ + JsonString jx; /* String for array result */ + + if( argc<2 ) return; + p = jsonParseFuncArg(ctx, argv[0], 0); + if( p==0 ) return; + flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + jsonStringInit(&jx, ctx); + if( argc>2 ){ + jsonAppendChar(&jx, '['); + } + for(i=1; i and ->> operators accept abbreviated PATH arguments. This + ** is mostly for compatibility with PostgreSQL, but also for + ** convenience. + ** + ** NUMBER ==> $[NUMBER] // PG compatible + ** LABEL ==> $.LABEL // PG compatible + ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience + ** + ** Updated 2024-05-27: If the NUMBER is negative, then PG counts from + ** the right of the array. Hence for negative NUMBER: + ** + ** NUMBER ==> $[#NUMBER] // PG compatible + */ + jsonStringInit(&jx, ctx); + if( sqlite3_value_type(argv[i])==SQLITE_INTEGER ){ + jsonAppendRawNZ(&jx, "[", 1); + if( zPath[0]=='-' ) jsonAppendRawNZ(&jx,"#",1); + jsonAppendRaw(&jx, zPath, nPath); + jsonAppendRawNZ(&jx, "]", 2); + }else if( jsonAllAlphanum(zPath, nPath) ){ + jsonAppendRawNZ(&jx, ".", 1); + jsonAppendRaw(&jx, zPath, nPath); + }else if( zPath[0]=='[' && nPath>=3 && zPath[nPath-1]==']' ){ + jsonAppendRaw(&jx, zPath, nPath); + }else{ + jsonAppendRawNZ(&jx, ".\"", 2); + jsonAppendRaw(&jx, zPath, nPath); + jsonAppendRawNZ(&jx, "\"", 1); + } + jsonStringTerminate(&jx); + j = jsonLookupStep(p, 0, jx.zBuf, 0); + jsonStringReset(&jx); + }else{ + jsonBadPathError(ctx, zPath, 0); + goto json_extract_error; + } + if( jnBlob ){ + if( argc==2 ){ + if( flags & JSON_JSON ){ + jsonStringInit(&jx, ctx); + jsonTranslateBlobToText(p, j, &jx); + jsonReturnString(&jx, 0, 0); + jsonStringReset(&jx); + assert( (flags & JSON_BLOB)==0 ); + sqlite3_result_subtype(ctx, JSON_SUBTYPE); + }else{ + jsonReturnFromBlob(p, j, ctx, 0); + if( (flags & (JSON_SQL|JSON_BLOB))==0 + && (p->aBlob[j]&0x0f)>=JSONB_ARRAY + ){ + sqlite3_result_subtype(ctx, JSON_SUBTYPE); + } + } + }else{ + jsonAppendSeparator(&jx); + jsonTranslateBlobToText(p, j, &jx); + } + }else if( j==JSON_LOOKUP_NOTFOUND ){ + if( argc==2 ){ + goto json_extract_error; /* Return NULL if not found */ + }else{ + jsonAppendSeparator(&jx); + jsonAppendRawNZ(&jx, "null", 4); + } + }else{ + jsonBadPathError(ctx, zPath, j); + goto json_extract_error; + } + } + if( argc>2 ){ + jsonAppendChar(&jx, ']'); + jsonReturnString(&jx, 0, 0); + if( (flags & JSON_BLOB)==0 ){ + sqlite3_result_subtype(ctx, JSON_SUBTYPE); + } + } +json_extract_error: + jsonStringReset(&jx); + jsonParseFree(p); + return; +} + +/* +** Return codes for jsonMergePatch() +*/ +#define JSON_MERGE_OK 0 /* Success */ +#define JSON_MERGE_BADTARGET 1 /* Malformed TARGET blob */ +#define JSON_MERGE_BADPATCH 2 /* Malformed PATCH blob */ +#define JSON_MERGE_OOM 3 /* Out-of-memory condition */ +#define JSON_MERGE_TOODEEP 4 /* Nested too deep */ + +/* +** RFC-7396 MergePatch for two JSONB blobs. +** +** pTarget is the target. pPatch is the patch. The target is updated +** in place. The patch is read-only. +** +** The original RFC-7396 algorithm is this: +** +** define MergePatch(Target, Patch): +** if Patch is an Object: +** if Target is not an Object: +** Target = {} # Ignore the contents and set it to an empty Object +** for each Name/Value pair in Patch: +** if Value is null: +** if Name exists in Target: +** remove the Name/Value pair from Target +** else: +** Target[Name] = MergePatch(Target[Name], Value) +** return Target +** else: +** return Patch +** +** Here is an equivalent algorithm restructured to show the actual +** implementation: +** +** 01 define MergePatch(Target, Patch): +** 02 if Patch is not an Object: +** 03 return Patch +** 04 else: // if Patch is an Object +** 05 if Target is not an Object: +** 06 Target = {} +** 07 for each Name/Value pair in Patch: +** 08 if Name exists in Target: +** 09 if Value is null: +** 10 remove the Name/Value pair from Target +** 11 else +** 12 Target[name] = MergePatch(Target[Name], Value) +** 13 else if Value is not NULL: +** 14 if Value is not an Object: +** 15 Target[name] = Value +** 16 else: +** 17 Target[name] = MergePatch('{}',value) +** 18 return Target +** | +** ^---- Line numbers referenced in comments in the implementation +*/ +static int jsonMergePatch( + JsonParse *pTarget, /* The JSON parser that contains the TARGET */ + u32 iTarget, /* Index of TARGET in pTarget->aBlob[] */ + const JsonParse *pPatch, /* The PATCH */ + u32 iPatch, /* Index of PATCH in pPatch->aBlob[] */ + u32 iDepth /* Nesting depth */ +){ + u8 x; /* Type of a single node */ + u32 n, sz=0; /* Return values from jsonbPayloadSize() */ + u32 iTCursor; /* Cursor position while scanning the target object */ + u32 iTStart; /* First label in the target object */ + u32 iTEndBE; /* Original first byte past end of target, before edit */ + u32 iTEnd; /* Current first byte past end of target */ + u8 eTLabel; /* Node type of the target label */ + u32 iTLabel = 0; /* Index of the label */ + u32 nTLabel = 0; /* Header size in bytes for the target label */ + u32 szTLabel = 0; /* Size of the target label payload */ + u32 iTValue = 0; /* Index of the target value */ + u32 nTValue = 0; /* Header size of the target value */ + u32 szTValue = 0; /* Payload size for the target value */ + + u32 iPCursor; /* Cursor position while scanning the patch */ + u32 iPEnd; /* First byte past the end of the patch */ + u8 ePLabel; /* Node type of the patch label */ + u32 iPLabel; /* Start of patch label */ + u32 nPLabel; /* Size of header on the patch label */ + u32 szPLabel; /* Payload size of the patch label */ + u32 iPValue; /* Start of patch value */ + u32 nPValue; /* Header size for the patch value */ + u32 szPValue; /* Payload size of the patch value */ + + assert( iTarget>=0 && iTargetnBlob ); + assert( iPatch>=0 && iPatchnBlob ); + x = pPatch->aBlob[iPatch] & 0x0f; + if( x!=JSONB_OBJECT ){ /* Algorithm line 02 */ + u32 szPatch; /* Total size of the patch, header+payload */ + u32 szTarget; /* Total size of the target, header+payload */ + n = jsonbPayloadSize(pPatch, iPatch, &sz); + szPatch = n+sz; + sz = 0; + n = jsonbPayloadSize(pTarget, iTarget, &sz); + szTarget = n+sz; + jsonBlobEdit(pTarget, iTarget, szTarget, pPatch->aBlob+iPatch, szPatch); + return pTarget->oom ? JSON_MERGE_OOM : JSON_MERGE_OK; /* Line 03 */ + } + x = pTarget->aBlob[iTarget] & 0x0f; + if( x!=JSONB_OBJECT ){ /* Algorithm line 05 */ + n = jsonbPayloadSize(pTarget, iTarget, &sz); + jsonBlobEdit(pTarget, iTarget+n, sz, 0, 0); + x = pTarget->aBlob[iTarget]; + pTarget->aBlob[iTarget] = (x & 0xf0) | JSONB_OBJECT; + } + n = jsonbPayloadSize(pPatch, iPatch, &sz); + if( NEVER(n==0) ) return JSON_MERGE_BADPATCH; + iPCursor = iPatch+n; + iPEnd = iPCursor+sz; + n = jsonbPayloadSize(pTarget, iTarget, &sz); + if( NEVER(n==0) ) return JSON_MERGE_BADTARGET; + iTStart = iTarget+n; + iTEndBE = iTStart+sz; + + while( iPCursoraBlob[iPCursor] & 0x0f; + if( ePLabelJSONB_TEXTRAW ){ + return JSON_MERGE_BADPATCH; + } + nPLabel = jsonbPayloadSize(pPatch, iPCursor, &szPLabel); + if( nPLabel==0 ) return JSON_MERGE_BADPATCH; + iPValue = iPCursor + nPLabel + szPLabel; + if( iPValue>=iPEnd ) return JSON_MERGE_BADPATCH; + nPValue = jsonbPayloadSize(pPatch, iPValue, &szPValue); + if( nPValue==0 ) return JSON_MERGE_BADPATCH; + iPCursor = iPValue + nPValue + szPValue; + if( iPCursor>iPEnd ) return JSON_MERGE_BADPATCH; + + iTCursor = iTStart; + iTEnd = iTEndBE + pTarget->delta; + while( iTCursoraBlob[iTCursor] & 0x0f; + if( eTLabelJSONB_TEXTRAW ){ + return JSON_MERGE_BADTARGET; + } + nTLabel = jsonbPayloadSize(pTarget, iTCursor, &szTLabel); + if( nTLabel==0 ) return JSON_MERGE_BADTARGET; + iTValue = iTLabel + nTLabel + szTLabel; + if( iTValue>=iTEnd ) return JSON_MERGE_BADTARGET; + nTValue = jsonbPayloadSize(pTarget, iTValue, &szTValue); + if( nTValue==0 ) return JSON_MERGE_BADTARGET; + if( iTValue + nTValue + szTValue > iTEnd ) return JSON_MERGE_BADTARGET; + isEqual = jsonLabelCompare( + (const char*)&pPatch->aBlob[iPLabel+nPLabel], + szPLabel, + (ePLabel==JSONB_TEXT || ePLabel==JSONB_TEXTRAW), + (const char*)&pTarget->aBlob[iTLabel+nTLabel], + szTLabel, + (eTLabel==JSONB_TEXT || eTLabel==JSONB_TEXTRAW)); + if( isEqual ) break; + iTCursor = iTValue + nTValue + szTValue; + } + x = pPatch->aBlob[iPValue] & 0x0f; + if( iTCursoroom) ) return JSON_MERGE_OOM; + }else{ + /* Algorithm line 12 */ + int rc, savedDelta = pTarget->delta; + pTarget->delta = 0; + if( iDepth>=JSON_MAX_DEPTH ) return JSON_MERGE_TOODEEP; + rc = jsonMergePatch(pTarget, iTValue, pPatch, iPValue, iDepth+1); + if( rc ) return rc; + pTarget->delta += savedDelta; + } + }else if( x>0 ){ /* Algorithm line 13 */ + /* No match and patch value is not NULL */ + u32 szNew = szPLabel+nPLabel; + if( (pPatch->aBlob[iPValue] & 0x0f)!=JSONB_OBJECT ){ /* Line 14 */ + jsonBlobEdit(pTarget, iTEnd, 0, 0, szPValue+nPValue+szNew); + if( pTarget->oom ) return JSON_MERGE_OOM; + memcpy(&pTarget->aBlob[iTEnd], &pPatch->aBlob[iPLabel], szNew); + memcpy(&pTarget->aBlob[iTEnd+szNew], + &pPatch->aBlob[iPValue], szPValue+nPValue); + }else{ + int rc, savedDelta; + jsonBlobEdit(pTarget, iTEnd, 0, 0, szNew+1); + if( pTarget->oom ) return JSON_MERGE_OOM; + memcpy(&pTarget->aBlob[iTEnd], &pPatch->aBlob[iPLabel], szNew); + pTarget->aBlob[iTEnd+szNew] = 0x00; + savedDelta = pTarget->delta; + pTarget->delta = 0; + if( iDepth>=JSON_MAX_DEPTH ) return JSON_MERGE_TOODEEP; + rc = jsonMergePatch(pTarget, iTEnd+szNew,pPatch,iPValue,iDepth+1); + if( rc ) return rc; + pTarget->delta += savedDelta; + } + } + } + if( pTarget->delta ) jsonAfterEditSizeAdjust(pTarget, iTarget); + return pTarget->oom ? JSON_MERGE_OOM : JSON_MERGE_OK; +} + + +/* +** Implementation of the json_mergepatch(JSON1,JSON2) function. Return a JSON +** object that is the result of running the RFC 7396 MergePatch() algorithm +** on the two arguments. +*/ +static void jsonPatchFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonParse *pTarget; /* The TARGET */ + JsonParse *pPatch; /* The PATCH */ + int rc; /* Result code */ + + UNUSED_PARAMETER(argc); + assert( argc==2 ); + pTarget = jsonParseFuncArg(ctx, argv[0], JSON_EDITABLE); + if( pTarget==0 ) return; + pPatch = jsonParseFuncArg(ctx, argv[1], 0); + if( pPatch ){ + rc = jsonMergePatch(pTarget, 0, pPatch, 0, 0); + if( rc==JSON_MERGE_OK ){ + jsonReturnParse(ctx, pTarget); + }else if( rc==JSON_MERGE_OOM ){ + sqlite3_result_error_nomem(ctx); + }else if( rc==JSON_MERGE_TOODEEP ){ + sqlite3_result_error(ctx, "JSON nested too deep", -1); + }else{ + sqlite3_result_error(ctx, "malformed JSON", -1); + } + jsonParseFree(pPatch); + } + jsonParseFree(pTarget); +} + + +/* +** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON +** object that contains all name/value given in arguments. Or if any name +** is not a string or if any value is a BLOB, throw an error. +*/ +static void jsonObjectFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + int i; + JsonString jx; + const char *z; + u32 n; + + if( argc&1 ){ + sqlite3_result_error(ctx, "json_object() requires an even number " + "of arguments", -1); + return; + } + jsonStringInit(&jx, ctx); + jsonAppendChar(&jx, '{'); + for(i=0; i1 ? JSON_EDITABLE : 0); + if( p==0 ) return; + for(i=1; ieEdit = JEDIT_DEL; + p->delta = 0; + rc = jsonLookupStep(p, 0, zPath+1, 0); + if( JSON_LOOKUP_ISERROR(rc) ){ + if( rc==JSON_LOOKUP_NOTFOUND ){ + continue; /* No-op */ + }else{ + jsonBadPathError(ctx, zPath, rc); + } + goto json_remove_done; + } + } + jsonReturnParse(ctx, p); + jsonParseFree(p); + return; + +json_remove_patherror: + jsonBadPathError(ctx, zPath, 0); + +json_remove_done: + jsonParseFree(p); + return; +} + +/* +** json_replace(JSON, PATH, VALUE, ...) +** +** Replace the value at PATH with VALUE. If PATH does not already exist, +** this routine is a no-op. If JSON or PATH is malformed, throw an error. +*/ +static void jsonReplaceFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + if( argc<1 ) return; + if( (argc&1)==0 ) { + jsonWrongNumArgs(ctx, "replace"); + return; + } + jsonInsertIntoBlob(ctx, argc, argv, JEDIT_REPL); +} + + +/* +** json_set(JSON, PATH, VALUE, ...) +** +** Set the value at PATH to VALUE. Create the PATH if it does not already +** exist. Overwrite existing values that do exist. +** If JSON or PATH is malformed, throw an error. +** +** json_insert(JSON, PATH, VALUE, ...) +** +** Create PATH and initialize it to VALUE. If PATH already exists, this +** routine is a no-op. If JSON or PATH is malformed, throw an error. +*/ +static void jsonSetFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + int eInsType = JSON_INSERT_TYPE(flags); + static const char *azInsType[] = { "insert", "set", "array_insert" }; + static const u8 aEditType[] = { JEDIT_INS, JEDIT_SET, JEDIT_AINS }; + + if( argc<1 ) return; + assert( eInsType>=0 && eInsType<=2 ); + if( (argc&1)==0 ) { + jsonWrongNumArgs(ctx, azInsType[eInsType]); + return; + } + jsonInsertIntoBlob(ctx, argc, argv, aEditType[eInsType]); +} + +/* +** json_type(JSON) +** json_type(JSON, PATH) +** +** Return the top-level "type" of a JSON string. json_type() raises an +** error if either the JSON or PATH inputs are not well-formed. +*/ +static void jsonTypeFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonParse *p; /* The parse */ + const char *zPath = 0; + u32 i; + + p = jsonParseFuncArg(ctx, argv[0], 0); + if( p==0 ) return; + if( argc==2 ){ + zPath = (const char*)sqlite3_value_text(argv[1]); + if( zPath==0 ) goto json_type_done; + if( zPath[0]!='$' ){ + jsonBadPathError(ctx, zPath, 0); + goto json_type_done; + } + i = jsonLookupStep(p, 0, zPath+1, 0); + if( JSON_LOOKUP_ISERROR(i) ){ + if( i==JSON_LOOKUP_NOTFOUND ){ + /* no-op */ + }else{ + jsonBadPathError(ctx, zPath, i); + } + goto json_type_done; + } + }else{ + i = 0; + } + sqlite3_result_text(ctx, jsonbType[p->aBlob[i]&0x0f], -1, SQLITE_STATIC); +json_type_done: + jsonParseFree(p); +} + +/* +** json_pretty(JSON) +** json_pretty(JSON, INDENT) +** +** Return text that is a pretty-printed rendering of the input JSON. +** If the argument is not valid JSON, return NULL. +** +** The INDENT argument is text that is used for indentation. If omitted, +** it defaults to four spaces (the same as PostgreSQL). +*/ +static void jsonPrettyFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonString s; /* The output string */ + JsonPretty x; /* Pretty printing context */ + + memset(&x, 0, sizeof(x)); + x.pParse = jsonParseFuncArg(ctx, argv[0], 0); + if( x.pParse==0 ) return; + x.pOut = &s; + jsonStringInit(&s, ctx); + if( argc==1 || (x.zIndent = (const char*)sqlite3_value_text(argv[1]))==0 ){ + x.zIndent = " "; + x.szIndent = 4; + }else{ + x.szIndent = (u32)strlen(x.zIndent); + } + jsonTranslateBlobToPrettyText(&x, 0); + jsonReturnString(&s, 0, 0); + jsonParseFree(x.pParse); +} + +/* +** json_valid(JSON) +** json_valid(JSON, FLAGS) +** +** Check the JSON argument to see if it is well-formed. The FLAGS argument +** encodes the various constraints on what is meant by "well-formed": +** +** 0x01 Canonical RFC-8259 JSON text +** 0x02 JSON text with optional JSON-5 extensions +** 0x04 Superficially appears to be JSONB +** 0x08 Strictly well-formed JSONB +** +** If the FLAGS argument is omitted, it defaults to 1. Useful values for +** FLAGS include: +** +** 1 Strict canonical JSON text +** 2 JSON text perhaps with JSON-5 extensions +** 4 Superficially appears to be JSONB +** 5 Canonical JSON text or superficial JSONB +** 6 JSON-5 text or superficial JSONB +** 8 Strict JSONB +** 9 Canonical JSON text or strict JSONB +** 10 JSON-5 text or strict JSONB +** +** Other flag combinations are redundant. For example, every canonical +** JSON text is also well-formed JSON-5 text, so FLAG values 2 and 3 +** are the same. Similarly, any input that passes a strict JSONB validation +** will also pass the superficial validation so 12 through 15 are the same +** as 8 through 11 respectively. +** +** This routine runs in linear time to validate text and when doing strict +** JSONB validation. Superficial JSONB validation is constant time, +** assuming the BLOB is already in memory. The performance advantage +** of superficial JSONB validation is why that option is provided. +** Application developers can choose to do fast superficial validation or +** slower strict validation, according to their specific needs. +** +** Only the lower four bits of the FLAGS argument are currently used. +** Higher bits are reserved for future expansion. To facilitate +** compatibility, the current implementation raises an error if any bit +** in FLAGS is set other than the lower four bits. +** +** The original circa 2015 implementation of the JSON routines in +** SQLite only supported canonical RFC-8259 JSON text and the json_valid() +** function only accepted one argument. That is why the default value +** for the FLAGS argument is 1, since FLAGS=1 causes this routine to only +** recognize canonical RFC-8259 JSON text as valid. The extra FLAGS +** argument was added when the JSON routines were extended to support +** JSON5-like extensions and binary JSONB stored in BLOBs. +** +** Return Values: +** +** * Raise an error if FLAGS is outside the range of 1 to 15. +** * Return NULL if the input is NULL +** * Return 1 if the input is well-formed. +** * Return 0 if the input is not well-formed. +*/ +static void jsonValidFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonParse *p; /* The parse */ + u8 flags = 1; + u8 res = 0; + if( argc==2 ){ + i64 f = sqlite3_value_int64(argv[1]); + if( f<1 || f>15 ){ + sqlite3_result_error(ctx, "FLAGS parameter to json_valid() must be" + " between 1 and 15", -1); + return; + } + flags = f & 0x0f; + } + switch( sqlite3_value_type(argv[0]) ){ + case SQLITE_NULL: { +#ifdef SQLITE_LEGACY_JSON_VALID + /* Incorrect legacy behavior was to return FALSE for a NULL input */ + sqlite3_result_int(ctx, 0); +#endif + return; + } + case SQLITE_BLOB: { + JsonParse py; + memset(&py, 0, sizeof(py)); + if( jsonArgIsJsonb(argv[0], &py) ){ + if( flags & 0x04 ){ + /* Superficial checking only - accomplished by the + ** jsonArgIsJsonb() call above. */ + res = 1; + }else if( flags & 0x08 ){ + /* Strict checking. Check by translating BLOB->TEXT->BLOB. If + ** no errors occur, call that a "strict check". */ + res = 0==jsonbValidityCheck(&py, 0, py.nBlob, 1); + } + break; + } + /* Fall through into interpreting the input as text. See note + ** above at tag-20240123-a. */ + /* no break */ deliberate_fall_through + } + default: { + JsonParse px; + if( (flags & 0x3)==0 ) break; + memset(&px, 0, sizeof(px)); + + p = jsonParseFuncArg(ctx, argv[0], JSON_KEEPERROR); + if( p ){ + if( p->oom ){ + sqlite3_result_error_nomem(ctx); + }else if( p->nErr ){ + /* no-op */ + }else if( (flags & 0x02)!=0 || p->hasNonstd==0 ){ + res = 1; + } + jsonParseFree(p); + }else{ + sqlite3_result_error_nomem(ctx); + } + break; + } + } + sqlite3_result_int(ctx, res); +} + +/* +** json_error_position(JSON) +** +** If the argument is NULL, return NULL +** +** If the argument is BLOB, do a full validity check and return non-zero +** if the check fails. The return value is the approximate 1-based offset +** to the byte of the element that contains the first error. +** +** Otherwise interpret the argument is TEXT (even if it is numeric) and +** return the 1-based character position for where the parser first recognized +** that the input was not valid JSON, or return 0 if the input text looks +** ok. JSON-5 extensions are accepted. +*/ +static void jsonErrorFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + i64 iErrPos = 0; /* Error position to be returned */ + JsonParse s; + + assert( argc==1 ); + UNUSED_PARAMETER(argc); + memset(&s, 0, sizeof(s)); + s.db = sqlite3_context_db_handle(ctx); + if( jsonArgIsJsonb(argv[0], &s) ){ + iErrPos = (i64)jsonbValidityCheck(&s, 0, s.nBlob, 1); + }else{ + s.zJson = (char*)sqlite3_value_text(argv[0]); + if( s.zJson==0 ) return; /* NULL input or OOM */ + s.nJson = sqlite3_value_bytes(argv[0]); + if( jsonConvertTextToBlob(&s,0) ){ + if( s.oom ){ + iErrPos = -1; + }else{ + /* Convert byte-offset s.iErr into a character offset */ + u32 k; + assert( s.zJson!=0 ); /* Because s.oom is false */ + for(k=0; kzBuf==0 ){ + jsonStringInit(pStr, ctx); + jsonAppendChar(pStr, '['); + }else if( pStr->nUsed>1 ){ + jsonAppendChar(pStr, ','); + } + pStr->pCtx = ctx; + jsonAppendSqlValue(pStr, argv[0]); + } +} +static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){ + JsonString *pStr; + int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); + if( pStr ){ + pStr->pCtx = ctx; + jsonAppendRawNZ(pStr, "]", 2); + jsonStringTrimOneChar(pStr); + if( pStr->eErr ){ + jsonReturnString(pStr, 0, 0); + return; + }else if( flags & JSON_BLOB ){ + jsonReturnStringAsBlob(pStr); + if( isFinal ){ + if( !pStr->bStatic ) sqlite3RCStrUnref(pStr->zBuf); + }else{ + jsonStringTrimOneChar(pStr); + } + return; + }else if( isFinal ){ + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, + pStr->bStatic ? SQLITE_TRANSIENT : + sqlite3RCStrUnref); + pStr->bStatic = 1; + }else{ + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); + jsonStringTrimOneChar(pStr); + } + }else if( flags & JSON_BLOB ){ + static const u8 emptyArray = 0x0b; + sqlite3_result_blob(ctx, &emptyArray, 1, SQLITE_STATIC); + }else{ + sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC); + } + sqlite3_result_subtype(ctx, JSON_SUBTYPE); +} +static void jsonArrayValue(sqlite3_context *ctx){ + jsonArrayCompute(ctx, 0); +} +static void jsonArrayFinal(sqlite3_context *ctx){ + jsonArrayCompute(ctx, 1); +} + +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** This method works for both json_group_array() and json_group_object(). +** It works by removing the first element of the group by searching forward +** to the first comma (",") that is not within a string and deleting all +** text through that comma. +*/ +static void jsonGroupInverse( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + unsigned int i; + int inStr = 0; + int nNest = 0; + char *z; + char c; + JsonString *pStr; + UNUSED_PARAMETER(argc); + UNUSED_PARAMETER(argv); + pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); + /* pStr is always non-NULL since jsonArrayStep() or jsonObjectStep() will + ** always have been called to initialize it */ + if( NEVER(!pStr) ) return; + z = pStr->zBuf; + for(i=1; inUsed && ((c = z[i])!=',' || inStr || nNest); i++){ + if( c=='"' ){ + inStr = !inStr; + }else if( c=='\\' ){ + i++; + }else if( !inStr ){ + if( c=='{' || c=='[' ) nNest++; + if( c=='}' || c==']' ) nNest--; + } + } + if( inUsed ){ + pStr->nUsed -= i; + memmove(&z[1], &z[i+1], (size_t)pStr->nUsed-1); + z[pStr->nUsed] = 0; + }else{ + pStr->nUsed = 1; + } +} +#else +# define jsonGroupInverse 0 +#endif + + +/* +** json_group_obj(NAME,VALUE) +** +** Return a JSON object composed of all names and values in the aggregate. +** +** Rows for which NAME is NULL do not result in a new entry. However, we +** do initially insert a "@" entry into the growing string for each null entry +** and change the first character of the string to "@" to signal that the +** string contains null entries. The "@" markers are needed in order to +** correctly process xInverse() requests. The initial "@" is converted +** back into "{" and the "@" null values are removed by jsonObjectCompute(). +*/ +static void jsonObjectStep( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonString *pStr; + const char *z; + u32 n; + UNUSED_PARAMETER(argc); + pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); + if( pStr ){ + z = (const char*)sqlite3_value_text(argv[0]); + n = sqlite3Strlen30(z); + if( pStr->zBuf==0 ){ + jsonStringInit(pStr, ctx); + jsonAppendChar(pStr, '{'); + }else if( pStr->nUsed>1 ){ + jsonAppendChar(pStr, ','); + } + pStr->pCtx = ctx; + if( z!=0 ){ + jsonAppendString(pStr, z, n); + jsonAppendChar(pStr, ':'); + jsonAppendSqlValue(pStr, argv[1]); + }else{ + pStr->zBuf[0] = '@'; + jsonAppendRawNZ(pStr, "@", 1); + } + } +} +static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ + JsonString *pStr; + int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); + if( pStr ){ + JsonString *pOgStr = pStr; + JsonString tmpStr; + jsonAppendRawNZ(pOgStr, "}", 2); /* Ensure it is zero-terminated */ + jsonStringTrimOneChar(pOgStr); /* Remove the zero terminator */ + pStr->pCtx = ctx; + if( pStr->eErr ){ + jsonReturnString(pStr, 0, 0); + return; + } + if( pStr->zBuf[0]!='{' ){ + /* The string contains null entries that need to be removed */ + u64 i, j; + int inStr = 0; + if( !isFinal ){ + /* Work with a temporary copy of the string if this is not the + ** final result */ + jsonStringInit(&tmpStr, ctx); + jsonAppendRawNZ(&tmpStr, pStr->zBuf, pStr->nUsed+1); + pStr = &tmpStr; + if( pStr->eErr ){ + jsonReturnString(pStr, 0, 0); + return; + } + jsonStringTrimOneChar(pStr); /* Remove zero terminator */ + } + /* Fix up the string by changing the initial "@" flag back to + ** to "{" and removing all subsequence "@" entries, with their + ** associated comma delimeters. */ + pStr->zBuf[0] = '{'; + for(i=j=1; inUsed; i++){ + char c = pStr->zBuf[i]; + if( c=='"' ){ + inStr = !inStr; + pStr->zBuf[j++] = '"'; + }else if( c=='\\' ){ + pStr->zBuf[j++] = '\\'; + pStr->zBuf[j++] = pStr->zBuf[++i]; + }else if( c=='@' && !inStr ){ + assert( i+1nUsed ); + if( pStr->zBuf[i+1]==',' ){ + i++; + }else if( pStr->zBuf[j-1]==',' ){ + j--; + } + }else{ + pStr->zBuf[j++] = c; + } + } + pStr->zBuf[j] = 0; /* Restore zero terminator */ + pStr->nUsed = j; /* Truncate the string */ + } + if( flags & JSON_BLOB ){ + jsonReturnStringAsBlob(pStr); + if( isFinal ){ + if( !pStr->bStatic ) sqlite3RCStrUnref(pStr->zBuf); + }else{ + jsonStringTrimOneChar(pOgStr); + } + }else if( isFinal ){ + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, + pStr->bStatic ? SQLITE_TRANSIENT : + sqlite3RCStrUnref); + pStr->bStatic = 1; + }else{ + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); + jsonStringTrimOneChar(pOgStr); + } + if( pStr!=pOgStr ) jsonStringReset(pStr); + }else if( flags & JSON_BLOB ){ + static const unsigned char emptyObject = 0x0c; + sqlite3_result_blob(ctx, &emptyObject, 1, SQLITE_STATIC); + }else{ + sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC); + } + sqlite3_result_subtype(ctx, JSON_SUBTYPE); +} +static void jsonObjectValue(sqlite3_context *ctx){ + jsonObjectCompute(ctx, 0); +} +static void jsonObjectFinal(sqlite3_context *ctx){ + jsonObjectCompute(ctx, 1); +} + + + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/**************************************************************************** +** The json_each virtual table +****************************************************************************/ +typedef struct JsonParent JsonParent; +struct JsonParent { + u32 iHead; /* Start of object or array */ + u32 iValue; /* Start of the value */ + u32 iEnd; /* First byte past the end */ + u32 nPath; /* Length of path */ + i64 iKey; /* Key for JSONB_ARRAY */ +}; + +typedef struct JsonEachCursor JsonEachCursor; +struct JsonEachCursor { + sqlite3_vtab_cursor base; /* Base class - must be first */ + u32 iRowid; /* The rowid */ + u32 i; /* Index in sParse.aBlob[] of current row */ + u32 iEnd; /* EOF when i equals or exceeds this value */ + u32 nRoot; /* Size of the root path in bytes */ + u8 eType; /* Type of the container for element i */ + u8 bRecursive; /* True for json_tree(). False for json_each() */ + u8 eMode; /* 1 for json_each(). 2 for jsonb_each() */ + u32 nParent; /* Current nesting depth */ + u32 nParentAlloc; /* Space allocated for aParent[] */ + JsonParent *aParent; /* Parent elements of i */ + sqlite3 *db; /* Database connection */ + JsonString path; /* Current path */ + JsonParse sParse; /* Parse of the input JSON */ +}; +typedef struct JsonEachConnection JsonEachConnection; +struct JsonEachConnection { + sqlite3_vtab base; /* Base class - must be first */ + sqlite3 *db; /* Database connection */ + u8 eMode; /* 1 for json_each(). 2 for jsonb_each() */ + u8 bRecursive; /* True for json_tree(). False for json_each() */ +}; + + +/* Constructor for the json_each virtual table */ +static int jsonEachConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + JsonEachConnection *pNew; + int rc; + +/* Column numbers */ +#define JEACH_KEY 0 +#define JEACH_VALUE 1 +#define JEACH_TYPE 2 +#define JEACH_ATOM 3 +#define JEACH_ID 4 +#define JEACH_PARENT 5 +#define JEACH_FULLKEY 6 +#define JEACH_PATH 7 +/* The xBestIndex method assumes that the JSON and ROOT columns are +** the last two columns in the table. Should this ever changes, be +** sure to update the xBestIndex method. */ +#define JEACH_JSON 8 +#define JEACH_ROOT 9 + + UNUSED_PARAMETER(pzErr); + UNUSED_PARAMETER(argv); + UNUSED_PARAMETER(argc); + UNUSED_PARAMETER(pAux); + rc = sqlite3_declare_vtab(db, + "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path," + "json HIDDEN,root HIDDEN)"); + if( rc==SQLITE_OK ){ + pNew = (JsonEachConnection*)sqlite3DbMallocZero(db, sizeof(*pNew)); + *ppVtab = (sqlite3_vtab*)pNew; + if( pNew==0 ) return SQLITE_NOMEM; + sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); + pNew->db = db; + pNew->eMode = argv[0][4]=='b' ? 2 : 1; + pNew->bRecursive = argv[0][4+pNew->eMode]=='t'; + } + return rc; +} + +/* destructor for json_each virtual table */ +static int jsonEachDisconnect(sqlite3_vtab *pVtab){ + JsonEachConnection *p = (JsonEachConnection*)pVtab; + sqlite3DbFree(p->db, pVtab); + return SQLITE_OK; +} + +/* constructor for a JsonEachCursor object for json_each()/json_tree(). */ +static int jsonEachOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ + JsonEachConnection *pVtab = (JsonEachConnection*)p; + JsonEachCursor *pCur; + + UNUSED_PARAMETER(p); + pCur = sqlite3DbMallocZero(pVtab->db, sizeof(*pCur)); + if( pCur==0 ) return SQLITE_NOMEM; + pCur->db = pVtab->db; + pCur->eMode = pVtab->eMode; + pCur->bRecursive = pVtab->bRecursive; + jsonStringZero(&pCur->path); + *ppCursor = &pCur->base; + return SQLITE_OK; +} + +/* Reset a JsonEachCursor back to its original state. Free any memory +** held. */ +static void jsonEachCursorReset(JsonEachCursor *p){ + jsonParseReset(&p->sParse); + jsonStringReset(&p->path); + sqlite3DbFree(p->db, p->aParent); + p->iRowid = 0; + p->i = 0; + p->aParent = 0; + p->nParent = 0; + p->nParentAlloc = 0; + p->iEnd = 0; + p->eType = 0; +} + +/* Destructor for a jsonEachCursor object */ +static int jsonEachClose(sqlite3_vtab_cursor *cur){ + JsonEachCursor *p = (JsonEachCursor*)cur; + jsonEachCursorReset(p); + + sqlite3DbFree(p->db, cur); + return SQLITE_OK; +} + +/* Return TRUE if the jsonEachCursor object has been advanced off the end +** of the JSON object */ +static int jsonEachEof(sqlite3_vtab_cursor *cur){ + JsonEachCursor *p = (JsonEachCursor*)cur; + return p->i >= p->iEnd; +} + +/* +** If the cursor is currently pointing at the label of a object entry, +** then return the index of the value. For all other cases, return the +** current pointer position, which is the value. +*/ +static int jsonSkipLabel(JsonEachCursor *p){ + if( p->eType==JSONB_OBJECT ){ + u32 sz = 0; + u32 n = jsonbPayloadSize(&p->sParse, p->i, &sz); + sz += p->i + n; + if( sz >= p->sParse.nBlob ) sz = p->i; + return sz; + }else{ + return p->i; + } +} + +/* +** Append the path name for the current element. +*/ +static void jsonAppendPathName(JsonEachCursor *p){ + assert( p->nParent>0 ); + assert( p->eType==JSONB_ARRAY || p->eType==JSONB_OBJECT ); + if( p->eType==JSONB_ARRAY ){ + jsonPrintf(30, &p->path, "[%lld]", p->aParent[p->nParent-1].iKey); + }else{ + u32 n, sz = 0, k, i; + const char *z; + int needQuote = 0; + n = jsonbPayloadSize(&p->sParse, p->i, &sz); + k = p->i + n; + z = (const char*)&p->sParse.aBlob[k]; + if( sz==0 || !sqlite3Isalpha(z[0]) ){ + needQuote = 1; + }else{ + for(i=0; ipath,".\"%.*s\"", sz, z); + }else{ + jsonPrintf(sz+2,&p->path,".%.*s", sz, z); + } + } +} + +/* Advance the cursor to the next element for json_tree() */ +static int jsonEachNext(sqlite3_vtab_cursor *cur){ + JsonEachCursor *p = (JsonEachCursor*)cur; + int rc = SQLITE_OK; + if( p->bRecursive ){ + u8 x; + u8 levelChange = 0; + u32 n, sz = 0; + u32 i = jsonSkipLabel(p); + x = p->sParse.aBlob[i] & 0x0f; + n = jsonbPayloadSize(&p->sParse, i, &sz); + if( x==JSONB_OBJECT || x==JSONB_ARRAY ){ + JsonParent *pParent; + if( p->nParent>=p->nParentAlloc ){ + JsonParent *pNew; + u64 nNew; + nNew = p->nParentAlloc*2 + 3; + pNew = sqlite3DbRealloc(p->db, p->aParent, sizeof(JsonParent)*nNew); + if( pNew==0 ) return SQLITE_NOMEM; + p->nParentAlloc = (u32)nNew; + p->aParent = pNew; + } + levelChange = 1; + pParent = &p->aParent[p->nParent]; + pParent->iHead = p->i; + pParent->iValue = i; + pParent->iEnd = i + n + sz; + pParent->iKey = -1; + pParent->nPath = (u32)p->path.nUsed; + if( p->eType && p->nParent ){ + jsonAppendPathName(p); + if( p->path.eErr ) rc = SQLITE_NOMEM; + } + p->nParent++; + p->i = i + n; + }else{ + p->i = i + n + sz; + } + while( p->nParent>0 && p->i >= p->aParent[p->nParent-1].iEnd ){ + p->nParent--; + p->path.nUsed = p->aParent[p->nParent].nPath; + levelChange = 1; + } + if( levelChange ){ + if( p->nParent>0 ){ + JsonParent *pParent = &p->aParent[p->nParent-1]; + u32 iVal = pParent->iValue; + p->eType = p->sParse.aBlob[iVal] & 0x0f; + }else{ + p->eType = 0; + } + } + }else{ + u32 n, sz = 0; + u32 i = jsonSkipLabel(p); + n = jsonbPayloadSize(&p->sParse, i, &sz); + p->i = i + n + sz; + } + if( p->eType==JSONB_ARRAY && p->nParent ){ + p->aParent[p->nParent-1].iKey++; + } + p->iRowid++; + return rc; +} + +/* Length of the path for rowid==0 in bRecursive mode. +*/ +static int jsonEachPathLength(JsonEachCursor *p){ + u32 n = p->path.nUsed; + char *z = p->path.zBuf; + if( p->iRowid==0 && p->bRecursive && n>=2 ){ + while( n>1 ){ + n--; + if( z[n]=='[' || z[n]=='.' ){ + u32 x, sz = 0; + char cSaved = z[n]; + z[n] = 0; + assert( p->sParse.eEdit==0 ); + x = jsonLookupStep(&p->sParse, 0, z+1, 0); + z[n] = cSaved; + if( JSON_LOOKUP_ISERROR(x) ) continue; + if( x + jsonbPayloadSize(&p->sParse, x, &sz) == p->i ) break; + } + } + } + return n; +} + +/* Return the value of a column */ +static int jsonEachColumn( + sqlite3_vtab_cursor *cur, /* The cursor */ + sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ + int iColumn /* Which column to return */ +){ + JsonEachCursor *p = (JsonEachCursor*)cur; + switch( iColumn ){ + case JEACH_KEY: { + if( p->nParent==0 ){ + u32 n, j; + if( p->nRoot==1 ) break; + j = jsonEachPathLength(p); + n = p->nRoot - j; + if( n==0 ){ + break; + }else if( p->path.zBuf[j]=='[' ){ + i64 x; + sqlite3Atoi64(&p->path.zBuf[j+1], &x, n-1, SQLITE_UTF8); + sqlite3_result_int64(ctx, x); + }else if( p->path.zBuf[j+1]=='"' ){ + sqlite3_result_text(ctx, &p->path.zBuf[j+2], n-3, SQLITE_TRANSIENT); + }else{ + sqlite3_result_text(ctx, &p->path.zBuf[j+1], n-1, SQLITE_TRANSIENT); + } + break; + } + if( p->eType==JSONB_OBJECT ){ + jsonReturnFromBlob(&p->sParse, p->i, ctx, 1); + }else{ + assert( p->eType==JSONB_ARRAY ); + sqlite3_result_int64(ctx, p->aParent[p->nParent-1].iKey); + } + break; + } + case JEACH_VALUE: { + u32 i = jsonSkipLabel(p); + jsonReturnFromBlob(&p->sParse, i, ctx, p->eMode); + if( (p->sParse.aBlob[i] & 0x0f)>=JSONB_ARRAY ){ + sqlite3_result_subtype(ctx, JSON_SUBTYPE); + } + break; + } + case JEACH_TYPE: { + u32 i = jsonSkipLabel(p); + u8 eType = p->sParse.aBlob[i] & 0x0f; + sqlite3_result_text(ctx, jsonbType[eType], -1, SQLITE_STATIC); + break; + } + case JEACH_ATOM: { + u32 i = jsonSkipLabel(p); + if( (p->sParse.aBlob[i] & 0x0f)sParse, i, ctx, 1); + } + break; + } + case JEACH_ID: { + sqlite3_result_int64(ctx, (sqlite3_int64)p->i); + break; + } + case JEACH_PARENT: { + if( p->nParent>0 && p->bRecursive ){ + sqlite3_result_int64(ctx, p->aParent[p->nParent-1].iHead); + } + break; + } + case JEACH_FULLKEY: { + u64 nBase = p->path.nUsed; + if( p->nParent ) jsonAppendPathName(p); + sqlite3_result_text64(ctx, p->path.zBuf, p->path.nUsed, + SQLITE_TRANSIENT, SQLITE_UTF8); + p->path.nUsed = nBase; + break; + } + case JEACH_PATH: { + u32 n = jsonEachPathLength(p); + sqlite3_result_text64(ctx, p->path.zBuf, n, + SQLITE_TRANSIENT, SQLITE_UTF8); + break; + } + default: { + sqlite3_result_text(ctx, p->path.zBuf, p->nRoot, SQLITE_STATIC); + break; + } + case JEACH_JSON: { + if( p->sParse.zJson==0 ){ + sqlite3_result_blob(ctx, p->sParse.aBlob, p->sParse.nBlob, + SQLITE_TRANSIENT); + }else{ + sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_TRANSIENT); + } + break; + } + } + return SQLITE_OK; +} + +/* Return the current rowid value */ +static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ + JsonEachCursor *p = (JsonEachCursor*)cur; + *pRowid = p->iRowid; + return SQLITE_OK; +} + +/* The query strategy is to look for an equality constraint on the json +** column. Without such a constraint, the table cannot operate. idxNum is +** 1 if the constraint is found, 3 if the constraint and zRoot are found, +** and 0 otherwise. +*/ +static int jsonEachBestIndex( + sqlite3_vtab *tab, + sqlite3_index_info *pIdxInfo +){ + int i; /* Loop counter or computed array index */ + int aIdx[2]; /* Index of constraints for JSON and ROOT */ + int unusableMask = 0; /* Mask of unusable JSON and ROOT constraints */ + int idxMask = 0; /* Mask of usable == constraints JSON and ROOT */ + const struct sqlite3_index_constraint *pConstraint; + + /* This implementation assumes that JSON and ROOT are the last two + ** columns in the table */ + assert( JEACH_ROOT == JEACH_JSON+1 ); + UNUSED_PARAMETER(tab); + aIdx[0] = aIdx[1] = -1; + pConstraint = pIdxInfo->aConstraint; + for(i=0; inConstraint; i++, pConstraint++){ + int iCol; + int iMask; + if( pConstraint->iColumn < JEACH_JSON ) continue; + iCol = pConstraint->iColumn - JEACH_JSON; + assert( iCol==0 || iCol==1 ); + testcase( iCol==0 ); + iMask = 1 << iCol; + if( pConstraint->usable==0 ){ + unusableMask |= iMask; + }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){ + aIdx[iCol] = i; + idxMask |= iMask; + } + } + if( pIdxInfo->nOrderBy>0 + && pIdxInfo->aOrderBy[0].iColumn<0 + && pIdxInfo->aOrderBy[0].desc==0 + ){ + pIdxInfo->orderByConsumed = 1; + } + + if( (unusableMask & ~idxMask)!=0 ){ + /* If there are any unusable constraints on JSON or ROOT, then reject + ** this entire plan */ + return SQLITE_CONSTRAINT; + } + if( aIdx[0]<0 ){ + /* No JSON input. Leave estimatedCost at the huge value that it was + ** initialized to to discourage the query planner from selecting this + ** plan. */ + pIdxInfo->idxNum = 0; + }else{ + pIdxInfo->estimatedCost = 1.0; + i = aIdx[0]; + pIdxInfo->aConstraintUsage[i].argvIndex = 1; + pIdxInfo->aConstraintUsage[i].omit = 1; + if( aIdx[1]<0 ){ + pIdxInfo->idxNum = 1; /* Only JSON supplied. Plan 1 */ + }else{ + i = aIdx[1]; + pIdxInfo->aConstraintUsage[i].argvIndex = 2; + pIdxInfo->aConstraintUsage[i].omit = 1; + pIdxInfo->idxNum = 3; /* Both JSON and ROOT are supplied. Plan 3 */ + } + } + return SQLITE_OK; +} + +/* Start a search on a new JSON string */ +static int jsonEachFilter( + sqlite3_vtab_cursor *cur, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + JsonEachCursor *p = (JsonEachCursor*)cur; + const char *zRoot = 0; + u32 i, n, sz; + + UNUSED_PARAMETER(idxStr); + UNUSED_PARAMETER(argc); + jsonEachCursorReset(p); + if( idxNum==0 ) return SQLITE_OK; + memset(&p->sParse, 0, sizeof(p->sParse)); + p->sParse.nJPRef = 1; + p->sParse.db = p->db; + if( jsonArgIsJsonb(argv[0], &p->sParse) ){ + /* We have JSONB */ + }else{ + p->sParse.zJson = (char*)sqlite3_value_text(argv[0]); + p->sParse.nJson = sqlite3_value_bytes(argv[0]); + if( p->sParse.zJson==0 ){ + p->i = p->iEnd = 0; + return SQLITE_OK; + } + if( jsonConvertTextToBlob(&p->sParse, 0) ){ + if( p->sParse.oom ){ + return SQLITE_NOMEM; + } + goto json_each_malformed_input; + } + } + if( idxNum==3 ){ + zRoot = (const char*)sqlite3_value_text(argv[1]); + if( zRoot==0 ) return SQLITE_OK; + if( zRoot[0]!='$' ){ + sqlite3_free(cur->pVtab->zErrMsg); + cur->pVtab->zErrMsg = jsonBadPathError(0, zRoot, 0); + jsonEachCursorReset(p); + return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; + } + p->nRoot = sqlite3Strlen30(zRoot); + if( zRoot[1]==0 ){ + i = p->i = 0; + p->eType = 0; + }else{ + i = jsonLookupStep(&p->sParse, 0, zRoot+1, 0); + if( JSON_LOOKUP_ISERROR(i) ){ + if( i==JSON_LOOKUP_NOTFOUND ){ + p->i = 0; + p->eType = 0; + p->iEnd = 0; + return SQLITE_OK; + } + sqlite3_free(cur->pVtab->zErrMsg); + cur->pVtab->zErrMsg = jsonBadPathError(0, zRoot, 0); + jsonEachCursorReset(p); + return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; + } + if( p->sParse.iLabel ){ + p->i = p->sParse.iLabel; + p->eType = JSONB_OBJECT; + }else{ + p->i = i; + p->eType = JSONB_ARRAY; + } + } + jsonAppendRaw(&p->path, zRoot, p->nRoot); + }else{ + i = p->i = 0; + p->eType = 0; + p->nRoot = 1; + jsonAppendRaw(&p->path, "$", 1); + } + p->nParent = 0; + n = jsonbPayloadSize(&p->sParse, i, &sz); + p->iEnd = i+n+sz; + if( (p->sParse.aBlob[i] & 0x0f)>=JSONB_ARRAY && !p->bRecursive ){ + p->i = i + n; + p->eType = p->sParse.aBlob[i] & 0x0f; + p->aParent = sqlite3DbMallocZero(p->db, sizeof(JsonParent)); + if( p->aParent==0 ) return SQLITE_NOMEM; + p->nParent = 1; + p->nParentAlloc = 1; + p->aParent[0].iKey = 0; + p->aParent[0].iEnd = p->iEnd; + p->aParent[0].iHead = p->i; + p->aParent[0].iValue = i; + } + return SQLITE_OK; + +json_each_malformed_input: + sqlite3_free(cur->pVtab->zErrMsg); + cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON"); + jsonEachCursorReset(p); + return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; +} + +/* The methods of the json_each virtual table */ +static sqlite3_module jsonEachModule = { + 0, /* iVersion */ + 0, /* xCreate */ + jsonEachConnect, /* xConnect */ + jsonEachBestIndex, /* xBestIndex */ + jsonEachDisconnect, /* xDisconnect */ + 0, /* xDestroy */ + jsonEachOpen, /* xOpen - open a cursor */ + jsonEachClose, /* xClose - close a cursor */ + jsonEachFilter, /* xFilter - configure scan constraints */ + jsonEachNext, /* xNext - advance a cursor */ + jsonEachEof, /* xEof - check for end of scan */ + jsonEachColumn, /* xColumn - read data */ + jsonEachRowid, /* xRowid - read data */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ +}; +#endif /* SQLITE_OMIT_VIRTUALTABLE */ +#endif /* !defined(SQLITE_OMIT_JSON) */ + +/* +** Register JSON functions. +*/ +SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void){ +#ifndef SQLITE_OMIT_JSON + static FuncDef aJsonFunc[] = { + /* sqlite3_result_subtype() ----, ,--- sqlite3_value_subtype() */ + /* | | */ + /* Uses cache ------, | | ,---- Returns JSONB */ + /* | | | | */ + /* Number of arguments ---, | | | | ,--- Flags */ + /* | | | | | | */ + JFUNCTION(json, 1,1,1, 0,0,0, jsonRemoveFunc), + JFUNCTION(jsonb, 1,1,0, 0,1,0, jsonRemoveFunc), + JFUNCTION(json_array, -1,0,1, 1,0,0, jsonArrayFunc), + JFUNCTION(jsonb_array, -1,0,1, 1,1,0, jsonArrayFunc), + JFUNCTION(json_array_insert, -1,1,1, 1,0,JSON_AINS, jsonSetFunc), + JFUNCTION(jsonb_array_insert,-1,1,0, 1,1,JSON_AINS, jsonSetFunc), + JFUNCTION(json_array_length, 1,1,0, 0,0,0, jsonArrayLengthFunc), + JFUNCTION(json_array_length, 2,1,0, 0,0,0, jsonArrayLengthFunc), + JFUNCTION(json_error_position,1,1,0, 0,0,0, jsonErrorFunc), + JFUNCTION(json_extract, -1,1,1, 0,0,0, jsonExtractFunc), + JFUNCTION(jsonb_extract, -1,1,0, 0,1,0, jsonExtractFunc), + JFUNCTION(->, 2,1,1, 0,0,JSON_JSON, jsonExtractFunc), + JFUNCTION(->>, 2,1,0, 0,0,JSON_SQL, jsonExtractFunc), + JFUNCTION(json_insert, -1,1,1, 1,0,0, jsonSetFunc), + JFUNCTION(jsonb_insert, -1,1,0, 1,1,0, jsonSetFunc), + JFUNCTION(json_object, -1,0,1, 1,0,0, jsonObjectFunc), + JFUNCTION(jsonb_object, -1,0,1, 1,1,0, jsonObjectFunc), + JFUNCTION(json_patch, 2,1,1, 0,0,0, jsonPatchFunc), + JFUNCTION(jsonb_patch, 2,1,0, 0,1,0, jsonPatchFunc), + JFUNCTION(json_pretty, 1,1,0, 0,0,0, jsonPrettyFunc), + JFUNCTION(json_pretty, 2,1,0, 0,0,0, jsonPrettyFunc), + JFUNCTION(json_quote, 1,0,1, 1,0,0, jsonQuoteFunc), + JFUNCTION(json_remove, -1,1,1, 0,0,0, jsonRemoveFunc), + JFUNCTION(jsonb_remove, -1,1,0, 0,1,0, jsonRemoveFunc), + JFUNCTION(json_replace, -1,1,1, 1,0,0, jsonReplaceFunc), + JFUNCTION(jsonb_replace, -1,1,0, 1,1,0, jsonReplaceFunc), + JFUNCTION(json_set, -1,1,1, 1,0,JSON_ISSET, jsonSetFunc), + JFUNCTION(jsonb_set, -1,1,0, 1,1,JSON_ISSET, jsonSetFunc), + JFUNCTION(json_type, 1,1,0, 0,0,0, jsonTypeFunc), + JFUNCTION(json_type, 2,1,0, 0,0,0, jsonTypeFunc), + JFUNCTION(json_valid, 1,1,0, 0,0,0, jsonValidFunc), + JFUNCTION(json_valid, 2,1,0, 0,0,0, jsonValidFunc), +#if SQLITE_DEBUG + JFUNCTION(json_parse, 1,1,0, 0,0,0, jsonParseFunc), +#endif + WAGGREGATE(json_group_array, 1, 0, 0, + jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse, + SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8| + SQLITE_DETERMINISTIC), + WAGGREGATE(jsonb_group_array, 1, JSON_BLOB, 0, + jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse, + SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC), + WAGGREGATE(json_group_object, 2, 0, 0, + jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse, + SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC), + WAGGREGATE(jsonb_group_object,2, JSON_BLOB, 0, + jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse, + SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8| + SQLITE_DETERMINISTIC) + }; + sqlite3InsertBuiltinFuncs(aJsonFunc, ArraySize(aJsonFunc)); +#endif +} + +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON) +/* +** Register the JSON table-valued function named zName and return a +** pointer to its Module object. Return NULL if something goes wrong. +*/ +SQLITE_PRIVATE Module *sqlite3JsonVtabRegister(sqlite3 *db, const char *zName){ + unsigned int i; + static const char *azModule[] = { + "json_each", "json_tree", "jsonb_each", "jsonb_tree" + }; + assert( sqlite3HashFind(&db->aModule, zName)==0 ); + for(i=0; i */ + +/* +** If building separately, we will need some setup that is normally +** found in sqliteInt.h +*/ +#if !defined(SQLITE_AMALGAMATION) +#include "sqlite3rtree.h" +typedef sqlite3_int64 i64; +typedef sqlite3_uint64 u64; +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) +# define NDEBUG 1 +#endif +#if defined(NDEBUG) && defined(SQLITE_DEBUG) +# undef NDEBUG +#endif +#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST) +# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1 +#endif +#if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS) +# define ALWAYS(X) (1) +# define NEVER(X) (0) +#elif !defined(NDEBUG) +# define ALWAYS(X) ((X)?1:(assert(0),0)) +# define NEVER(X) ((X)?(assert(0),1):0) +#else +# define ALWAYS(X) (X) +# define NEVER(X) (X) +#endif +#ifndef offsetof +# define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) +#endif +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define FLEXARRAY +#else +# define FLEXARRAY 1 +#endif +#endif /* !defined(SQLITE_AMALGAMATION) */ + +/* Macro to check for 4-byte alignment. Only used inside of assert() */ +#ifdef SQLITE_DEBUG +# define FOUR_BYTE_ALIGNED(X) ((((char*)(X) - (char*)0) & 3)==0) +#endif + +/* #include */ +/* #include */ +/* #include */ +/* #include */ + +/* The following macro is used to suppress compiler warnings. +*/ +#ifndef UNUSED_PARAMETER +# define UNUSED_PARAMETER(x) (void)(x) +#endif + +typedef struct Rtree Rtree; +typedef struct RtreeCursor RtreeCursor; +typedef struct RtreeNode RtreeNode; +typedef struct RtreeCell RtreeCell; +typedef struct RtreeConstraint RtreeConstraint; +typedef struct RtreeMatchArg RtreeMatchArg; +typedef struct RtreeGeomCallback RtreeGeomCallback; +typedef union RtreeCoord RtreeCoord; +typedef struct RtreeSearchPoint RtreeSearchPoint; + +/* The rtree may have between 1 and RTREE_MAX_DIMENSIONS dimensions. */ +#define RTREE_MAX_DIMENSIONS 5 + +/* Maximum number of auxiliary columns */ +#define RTREE_MAX_AUX_COLUMN 100 + +/* Size of hash table Rtree.aHash. This hash table is not expected to +** ever contain very many entries, so a fixed number of buckets is +** used. +*/ +#define HASHSIZE 97 + +/* The xBestIndex method of this virtual table requires an estimate of +** the number of rows in the virtual table to calculate the costs of +** various strategies. If possible, this estimate is loaded from the +** sqlite_stat1 table (with RTREE_MIN_ROWEST as a hard-coded minimum). +** Otherwise, if no sqlite_stat1 entry is available, use +** RTREE_DEFAULT_ROWEST. +*/ +#define RTREE_DEFAULT_ROWEST 1048576 +#define RTREE_MIN_ROWEST 100 + +/* +** An rtree virtual-table object. +*/ +struct Rtree { + sqlite3_vtab base; /* Base class. Must be first */ + sqlite3 *db; /* Host database connection */ + int iNodeSize; /* Size in bytes of each node in the node table */ + u8 nDim; /* Number of dimensions */ + u8 nDim2; /* Twice the number of dimensions */ + u8 eCoordType; /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */ + u8 nBytesPerCell; /* Bytes consumed per cell */ + u8 inWrTrans; /* True if inside write transaction */ + u16 nAux; /* # of auxiliary columns in %_rowid */ +#ifdef SQLITE_ENABLE_GEOPOLY + u8 nAuxNotNull; /* Number of initial not-null aux columns */ +#endif +#ifdef SQLITE_DEBUG + u8 bCorrupt; /* Shadow table corruption detected */ +#endif + int iDepth; /* Current depth of the r-tree structure */ + char *zDb; /* Name of database containing r-tree table */ + char *zName; /* Name of r-tree table */ + char *zNodeName; /* Name of the %_node table */ + u32 nBusy; /* Current number of users of this structure */ + i64 nRowEst; /* Estimated number of rows in this table */ + u32 nCursor; /* Number of open cursors */ + u32 nNodeRef; /* Number RtreeNodes with positive nRef */ + char *zReadAuxSql; /* SQL for statement to read aux data */ + + /* List of nodes removed during a CondenseTree operation. List is + ** linked together via the pointer normally used for hash chains - + ** RtreeNode.pNext. RtreeNode.iNode stores the depth of the sub-tree + ** headed by the node (leaf nodes have RtreeNode.iNode==0). + */ + RtreeNode *pDeleted; + + /* Blob I/O on xxx_node */ + sqlite3_blob *pNodeBlob; + + /* Statements to read/write/delete a record from xxx_node */ + sqlite3_stmt *pWriteNode; + sqlite3_stmt *pDeleteNode; + + /* Statements to read/write/delete a record from xxx_rowid */ + sqlite3_stmt *pReadRowid; + sqlite3_stmt *pWriteRowid; + sqlite3_stmt *pDeleteRowid; + + /* Statements to read/write/delete a record from xxx_parent */ + sqlite3_stmt *pReadParent; + sqlite3_stmt *pWriteParent; + sqlite3_stmt *pDeleteParent; + + /* Statement for writing to the "aux:" fields, if there are any */ + sqlite3_stmt *pWriteAux; + + RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */ +}; + +/* Possible values for Rtree.eCoordType: */ +#define RTREE_COORD_REAL32 0 +#define RTREE_COORD_INT32 1 + +/* +** If SQLITE_RTREE_INT_ONLY is defined, then this virtual table will +** only deal with integer coordinates. No floating point operations +** will be done. +*/ +#ifdef SQLITE_RTREE_INT_ONLY + typedef sqlite3_int64 RtreeDValue; /* High accuracy coordinate */ + typedef int RtreeValue; /* Low accuracy coordinate */ +# define RTREE_ZERO 0 +#else + typedef double RtreeDValue; /* High accuracy coordinate */ + typedef float RtreeValue; /* Low accuracy coordinate */ +# define RTREE_ZERO 0.0 +#endif + +/* +** Set the Rtree.bCorrupt flag +*/ +#ifdef SQLITE_DEBUG +# define RTREE_IS_CORRUPT(X) ((X)->bCorrupt = 1) +#else +# define RTREE_IS_CORRUPT(X) +#endif + +/* +** When doing a search of an r-tree, instances of the following structure +** record intermediate results from the tree walk. +** +** The id is always a node-id. For iLevel>=1 the id is the node-id of +** the node that the RtreeSearchPoint represents. When iLevel==0, however, +** the id is of the parent node and the cell that RtreeSearchPoint +** represents is the iCell-th entry in the parent node. +*/ +struct RtreeSearchPoint { + RtreeDValue rScore; /* The score for this node. Smallest goes first. */ + sqlite3_int64 id; /* Node ID */ + u8 iLevel; /* 0=entries. 1=leaf node. 2+ for higher */ + u8 eWithin; /* PARTLY_WITHIN or FULLY_WITHIN */ + u8 iCell; /* Cell index within the node */ +}; + +/* +** The minimum number of cells allowed for a node is a third of the +** maximum. In Gutman's notation: +** +** m = M/3 +** +** If an R*-tree "Reinsert" operation is required, the same number of +** cells are removed from the overfull node and reinserted into the tree. +*/ +#define RTREE_MINCELLS(p) ((((p)->iNodeSize-4)/(p)->nBytesPerCell)/3) +#define RTREE_REINSERT(p) RTREE_MINCELLS(p) +#define RTREE_MAXCELLS 51 + +/* +** The smallest possible node-size is (512-64)==448 bytes. And the largest +** supported cell size is 48 bytes (8 byte rowid + ten 4 byte coordinates). +** Therefore all non-root nodes must contain at least 3 entries. Since +** 3^40 is greater than 2^64, an r-tree structure always has a depth of +** 40 or less. +*/ +#define RTREE_MAX_DEPTH 40 + + +/* +** Number of entries in the cursor RtreeNode cache. The first entry is +** used to cache the RtreeNode for RtreeCursor.sPoint. The remaining +** entries cache the RtreeNode for the first elements of the priority queue. +*/ +#define RTREE_CACHE_SZ 5 + +/* +** An rtree cursor object. +*/ +struct RtreeCursor { + sqlite3_vtab_cursor base; /* Base class. Must be first */ + u8 atEOF; /* True if at end of search */ + u8 bPoint; /* True if sPoint is valid */ + u8 bAuxValid; /* True if pReadAux is valid */ + int iStrategy; /* Copy of idxNum search parameter */ + int nConstraint; /* Number of entries in aConstraint */ + RtreeConstraint *aConstraint; /* Search constraints. */ + int nPointAlloc; /* Number of slots allocated for aPoint[] */ + int nPoint; /* Number of slots used in aPoint[] */ + int mxLevel; /* iLevel value for root of the tree */ + RtreeSearchPoint *aPoint; /* Priority queue for search points */ + sqlite3_stmt *pReadAux; /* Statement to read aux-data */ + RtreeSearchPoint sPoint; /* Cached next search point */ + RtreeNode *aNode[RTREE_CACHE_SZ]; /* Rtree node cache */ + u32 anQueue[RTREE_MAX_DEPTH+2]; /* Number of queued entries by iLevel */ +}; + +/* Return the Rtree of a RtreeCursor */ +#define RTREE_OF_CURSOR(X) ((Rtree*)((X)->base.pVtab)) + +/* +** A coordinate can be either a floating point number or a integer. All +** coordinates within a single R-Tree are always of the same time. +*/ +union RtreeCoord { + RtreeValue f; /* Floating point value */ + int i; /* Integer value */ + u32 u; /* Unsigned for byte-order conversions */ +}; + +/* +** The argument is an RtreeCoord. Return the value stored within the RtreeCoord +** formatted as a RtreeDValue (double or int64). This macro assumes that local +** variable pRtree points to the Rtree structure associated with the +** RtreeCoord. +*/ +#ifdef SQLITE_RTREE_INT_ONLY +# define DCOORD(coord) ((RtreeDValue)coord.i) +#else +# define DCOORD(coord) ( \ + (pRtree->eCoordType==RTREE_COORD_REAL32) ? \ + ((double)coord.f) : \ + ((double)coord.i) \ + ) +#endif + +/* +** A search constraint. +*/ +struct RtreeConstraint { + int iCoord; /* Index of constrained coordinate */ + int op; /* Constraining operation */ + union { + RtreeDValue rValue; /* Constraint value. */ + int (*xGeom)(sqlite3_rtree_geometry*,int,RtreeDValue*,int*); + int (*xQueryFunc)(sqlite3_rtree_query_info*); + } u; + sqlite3_rtree_query_info *pInfo; /* xGeom and xQueryFunc argument */ +}; + +/* Possible values for RtreeConstraint.op */ +#define RTREE_EQ 0x41 /* A */ +#define RTREE_LE 0x42 /* B */ +#define RTREE_LT 0x43 /* C */ +#define RTREE_GE 0x44 /* D */ +#define RTREE_GT 0x45 /* E */ +#define RTREE_MATCH 0x46 /* F: Old-style sqlite3_rtree_geometry_callback() */ +#define RTREE_QUERY 0x47 /* G: New-style sqlite3_rtree_query_callback() */ + +/* Special operators available only on cursors. Needs to be consecutive +** with the normal values above, but must be less than RTREE_MATCH. These +** are used in the cursor for contraints such as x=NULL (RTREE_FALSE) or +** x<'xyz' (RTREE_TRUE) */ +#define RTREE_TRUE 0x3f /* ? */ +#define RTREE_FALSE 0x40 /* @ */ + +/* +** An rtree structure node. +*/ +struct RtreeNode { + RtreeNode *pParent; /* Parent node */ + i64 iNode; /* The node number */ + int nRef; /* Number of references to this node */ + int isDirty; /* True if the node needs to be written to disk */ + u8 *zData; /* Content of the node, as should be on disk */ + RtreeNode *pNext; /* Next node in this hash collision chain */ +}; + +/* Return the number of cells in a node */ +#define NCELL(pNode) readInt16(&(pNode)->zData[2]) + +/* +** A single cell from a node, deserialized +*/ +struct RtreeCell { + i64 iRowid; /* Node or entry ID */ + RtreeCoord aCoord[RTREE_MAX_DIMENSIONS*2]; /* Bounding box coordinates */ +}; + + +/* +** This object becomes the sqlite3_user_data() for the SQL functions +** that are created by sqlite3_rtree_geometry_callback() and +** sqlite3_rtree_query_callback() and which appear on the right of MATCH +** operators in order to constrain a search. +** +** xGeom and xQueryFunc are the callback functions. Exactly one of +** xGeom and xQueryFunc fields is non-NULL, depending on whether the +** SQL function was created using sqlite3_rtree_geometry_callback() or +** sqlite3_rtree_query_callback(). +** +** This object is deleted automatically by the destructor mechanism in +** sqlite3_create_function_v2(). +*/ +struct RtreeGeomCallback { + int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*); + int (*xQueryFunc)(sqlite3_rtree_query_info*); + void (*xDestructor)(void*); + void *pContext; +}; + +/* +** An instance of this structure (in the form of a BLOB) is returned by +** the SQL functions that sqlite3_rtree_geometry_callback() and +** sqlite3_rtree_query_callback() create, and is read as the right-hand +** operand to the MATCH operator of an R-Tree. +*/ +struct RtreeMatchArg { + u32 iSize; /* Size of this object */ + RtreeGeomCallback cb; /* Info about the callback functions */ + int nParam; /* Number of parameters to the SQL function */ + sqlite3_value **apSqlParam; /* Original SQL parameter values */ + RtreeDValue aParam[FLEXARRAY]; /* Values for parameters to the SQL function */ +}; + +/* Size of an RtreeMatchArg object with N parameters */ +#define SZ_RTREEMATCHARG(N) \ + (offsetof(RtreeMatchArg,aParam)+(N)*sizeof(RtreeDValue)) + +#ifndef MAX +# define MAX(x,y) ((x) < (y) ? (y) : (x)) +#endif +#ifndef MIN +# define MIN(x,y) ((x) > (y) ? (y) : (x)) +#endif + +/* What version of GCC is being used. 0 means GCC is not being used . +** Note that the GCC_VERSION macro will also be set correctly when using +** clang, since clang works hard to be gcc compatible. So the gcc +** optimizations will also work when compiling with clang. +*/ +#ifndef GCC_VERSION +#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC) +# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__) +#else +# define GCC_VERSION 0 +#endif +#endif + +/* The testcase() macro should already be defined in the amalgamation. If +** it is not, make it a no-op. +*/ +#ifndef SQLITE_AMALGAMATION +# if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG) + unsigned int sqlite3RtreeTestcase = 0; +# define testcase(X) if( X ){ sqlite3RtreeTestcase += __LINE__; } +# else +# define testcase(X) +# endif +#endif + +/* +** Make sure that the compiler intrinsics we desire are enabled when +** compiling with an appropriate version of MSVC unless prevented by +** the SQLITE_DISABLE_INTRINSIC define. +*/ +#if !defined(SQLITE_DISABLE_INTRINSIC) +# if defined(_MSC_VER) && _MSC_VER>=1400 +# if !defined(_WIN32_WCE) +/* # include */ +# pragma intrinsic(_byteswap_ulong) +# pragma intrinsic(_byteswap_uint64) +# else +/* # include */ +# endif +# endif +#endif + +/* +** Macros to determine whether the machine is big or little endian, +** and whether or not that determination is run-time or compile-time. +** +** For best performance, an attempt is made to guess at the byte-order +** using C-preprocessor macros. If that is unsuccessful, or if +** -DSQLITE_RUNTIME_BYTEORDER=1 is set, then byte-order is determined +** at run-time. +*/ +#ifndef SQLITE_BYTEORDER /* Replicate changes at tag-20230904a */ +# if defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__ +# define SQLITE_BYTEORDER 4321 +# elif defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ +# define SQLITE_BYTEORDER 1234 +# elif defined(__BIG_ENDIAN__) && __BIG_ENDIAN__==1 +# define SQLITE_BYTEORDER 4321 +# elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ + defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ + defined(__ARMEL__) || defined(__AARCH64EL__) || defined(_M_ARM64) +# define SQLITE_BYTEORDER 1234 +# elif defined(sparc) || defined(__ARMEB__) || defined(__AARCH64EB__) +# define SQLITE_BYTEORDER 4321 +# else +# define SQLITE_BYTEORDER 0 +# endif +#endif + + +/* What version of MSVC is being used. 0 means MSVC is not being used */ +#ifndef MSVC_VERSION +#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC) +# define MSVC_VERSION _MSC_VER +#else +# define MSVC_VERSION 0 +#endif +#endif + +/* +** Functions to deserialize a 16 bit integer, 32 bit real number and +** 64 bit integer. The deserialized value is returned. +*/ +static int readInt16(u8 *p){ + return (p[0]<<8) + p[1]; +} +static void readCoord(u8 *p, RtreeCoord *pCoord){ + assert( FOUR_BYTE_ALIGNED(p) ); +#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 + pCoord->u = _byteswap_ulong(*(u32*)p); +#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 + pCoord->u = __builtin_bswap32(*(u32*)p); +#elif SQLITE_BYTEORDER==4321 + pCoord->u = *(u32*)p; +#else + pCoord->u = ( + (((u32)p[0]) << 24) + + (((u32)p[1]) << 16) + + (((u32)p[2]) << 8) + + (((u32)p[3]) << 0) + ); +#endif +} +static i64 readInt64(u8 *p){ +#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 + u64 x; + memcpy(&x, p, 8); + return (i64)_byteswap_uint64(x); +#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 + u64 x; + memcpy(&x, p, 8); + return (i64)__builtin_bswap64(x); +#elif SQLITE_BYTEORDER==4321 + i64 x; + memcpy(&x, p, 8); + return x; +#else + return (i64)( + (((u64)p[0]) << 56) + + (((u64)p[1]) << 48) + + (((u64)p[2]) << 40) + + (((u64)p[3]) << 32) + + (((u64)p[4]) << 24) + + (((u64)p[5]) << 16) + + (((u64)p[6]) << 8) + + (((u64)p[7]) << 0) + ); +#endif +} + +/* +** Functions to serialize a 16 bit integer, 32 bit real number and +** 64 bit integer. The value returned is the number of bytes written +** to the argument buffer (always 2, 4 and 8 respectively). +*/ +static void writeInt16(u8 *p, int i){ + p[0] = (i>> 8)&0xFF; + p[1] = (i>> 0)&0xFF; +} +static int writeCoord(u8 *p, RtreeCoord *pCoord){ + u32 i; + assert( FOUR_BYTE_ALIGNED(p) ); + assert( sizeof(RtreeCoord)==4 ); + assert( sizeof(u32)==4 ); +#if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 + i = __builtin_bswap32(pCoord->u); + memcpy(p, &i, 4); +#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 + i = _byteswap_ulong(pCoord->u); + memcpy(p, &i, 4); +#elif SQLITE_BYTEORDER==4321 + i = pCoord->u; + memcpy(p, &i, 4); +#else + i = pCoord->u; + p[0] = (i>>24)&0xFF; + p[1] = (i>>16)&0xFF; + p[2] = (i>> 8)&0xFF; + p[3] = (i>> 0)&0xFF; +#endif + return 4; +} +static int writeInt64(u8 *p, i64 i){ +#if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 + i = (i64)__builtin_bswap64((u64)i); + memcpy(p, &i, 8); +#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 + i = (i64)_byteswap_uint64((u64)i); + memcpy(p, &i, 8); +#elif SQLITE_BYTEORDER==4321 + memcpy(p, &i, 8); +#else + p[0] = (i>>56)&0xFF; + p[1] = (i>>48)&0xFF; + p[2] = (i>>40)&0xFF; + p[3] = (i>>32)&0xFF; + p[4] = (i>>24)&0xFF; + p[5] = (i>>16)&0xFF; + p[6] = (i>> 8)&0xFF; + p[7] = (i>> 0)&0xFF; +#endif + return 8; +} + +/* +** Increment the reference count of node p. +*/ +static void nodeReference(RtreeNode *p){ + if( p ){ + assert( p->nRef>0 ); + p->nRef++; + } +} + +/* +** Clear the content of node p (set all bytes to 0x00). +*/ +static void nodeZero(Rtree *pRtree, RtreeNode *p){ + memset(&p->zData[2], 0, pRtree->iNodeSize-2); + p->isDirty = 1; +} + +/* +** Given a node number iNode, return the corresponding key to use +** in the Rtree.aHash table. +*/ +static unsigned int nodeHash(i64 iNode){ + return ((unsigned)iNode) % HASHSIZE; +} + +/* +** Search the node hash table for node iNode. If found, return a pointer +** to it. Otherwise, return 0. +*/ +static RtreeNode *nodeHashLookup(Rtree *pRtree, i64 iNode){ + RtreeNode *p; + for(p=pRtree->aHash[nodeHash(iNode)]; p && p->iNode!=iNode; p=p->pNext); + return p; +} + +/* +** Add node pNode to the node hash table. +*/ +static void nodeHashInsert(Rtree *pRtree, RtreeNode *pNode){ + int iHash; + assert( pNode->pNext==0 ); + iHash = nodeHash(pNode->iNode); + pNode->pNext = pRtree->aHash[iHash]; + pRtree->aHash[iHash] = pNode; +} + +/* +** Remove node pNode from the node hash table. +*/ +static void nodeHashDelete(Rtree *pRtree, RtreeNode *pNode){ + RtreeNode **pp; + if( pNode->iNode!=0 ){ + pp = &pRtree->aHash[nodeHash(pNode->iNode)]; + for( ; (*pp)!=pNode; pp = &(*pp)->pNext){ assert(*pp); } + *pp = pNode->pNext; + pNode->pNext = 0; + } +} + +/* +** Allocate and return new r-tree node. Initially, (RtreeNode.iNode==0), +** indicating that node has not yet been assigned a node number. It is +** assigned a node number when nodeWrite() is called to write the +** node contents out to the database. +*/ +static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){ + RtreeNode *pNode; + pNode = (RtreeNode *)sqlite3_malloc64(sizeof(RtreeNode) + pRtree->iNodeSize); + if( pNode ){ + memset(pNode, 0, sizeof(RtreeNode) + pRtree->iNodeSize); + pNode->zData = (u8 *)&pNode[1]; + pNode->nRef = 1; + pRtree->nNodeRef++; + pNode->pParent = pParent; + pNode->isDirty = 1; + nodeReference(pParent); + } + return pNode; +} + +/* +** Clear the Rtree.pNodeBlob object +*/ +static void nodeBlobReset(Rtree *pRtree){ + sqlite3_blob *pBlob = pRtree->pNodeBlob; + pRtree->pNodeBlob = 0; + sqlite3_blob_close(pBlob); +} + +/* +** Obtain a reference to an r-tree node. +*/ +static int nodeAcquire( + Rtree *pRtree, /* R-tree structure */ + i64 iNode, /* Node number to load */ + RtreeNode *pParent, /* Either the parent node or NULL */ + RtreeNode **ppNode /* OUT: Acquired node */ +){ + int rc = SQLITE_OK; + RtreeNode *pNode = 0; + + /* Check if the requested node is already in the hash table. If so, + ** increase its reference count and return it. + */ + if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){ + if( pParent && ALWAYS(pParent!=pNode->pParent) ){ + RTREE_IS_CORRUPT(pRtree); + return SQLITE_CORRUPT_VTAB; + } + pNode->nRef++; + *ppNode = pNode; + return SQLITE_OK; + } + + if( pRtree->pNodeBlob ){ + sqlite3_blob *pBlob = pRtree->pNodeBlob; + pRtree->pNodeBlob = 0; + rc = sqlite3_blob_reopen(pBlob, iNode); + pRtree->pNodeBlob = pBlob; + if( rc ){ + nodeBlobReset(pRtree); + if( rc==SQLITE_NOMEM ) return SQLITE_NOMEM; + } + } + if( pRtree->pNodeBlob==0 ){ + rc = sqlite3_blob_open(pRtree->db, pRtree->zDb, pRtree->zNodeName, + "data", iNode, 0, + &pRtree->pNodeBlob); + } + if( rc ){ + *ppNode = 0; + /* If unable to open an sqlite3_blob on the desired row, that can only + ** be because the shadow tables hold erroneous data. */ + if( rc==SQLITE_ERROR ){ + rc = SQLITE_CORRUPT_VTAB; + RTREE_IS_CORRUPT(pRtree); + } + }else if( iNode<=0 ){ + RTREE_IS_CORRUPT(pRtree); + rc = SQLITE_CORRUPT_VTAB; + }else if( pRtree->iNodeSize==sqlite3_blob_bytes(pRtree->pNodeBlob) ){ + pNode = (RtreeNode *)sqlite3_malloc64(sizeof(RtreeNode)+pRtree->iNodeSize); + if( !pNode ){ + rc = SQLITE_NOMEM; + }else{ + pNode->pParent = pParent; + pNode->zData = (u8 *)&pNode[1]; + pNode->nRef = 1; + pRtree->nNodeRef++; + pNode->iNode = iNode; + pNode->isDirty = 0; + pNode->pNext = 0; + rc = sqlite3_blob_read(pRtree->pNodeBlob, pNode->zData, + pRtree->iNodeSize, 0); + } + } + + /* If the root node was just loaded, set pRtree->iDepth to the height + ** of the r-tree structure. A height of zero means all data is stored on + ** the root node. A height of one means the children of the root node + ** are the leaves, and so on. If the depth as specified on the root node + ** is greater than RTREE_MAX_DEPTH, the r-tree structure must be corrupt. + */ + if( rc==SQLITE_OK && pNode && iNode==1 ){ + pRtree->iDepth = readInt16(pNode->zData); + if( pRtree->iDepth>=RTREE_MAX_DEPTH ){ + rc = SQLITE_CORRUPT_VTAB; + RTREE_IS_CORRUPT(pRtree); + } + } + + /* If no error has occurred so far, check if the "number of entries" + ** field on the node is too large. If so, set the return code to + ** SQLITE_CORRUPT_VTAB. + */ + if( pNode && rc==SQLITE_OK ){ + if( NCELL(pNode)>((pRtree->iNodeSize-4)/pRtree->nBytesPerCell) ){ + rc = SQLITE_CORRUPT_VTAB; + RTREE_IS_CORRUPT(pRtree); + } + } + + if( rc==SQLITE_OK ){ + if( pNode!=0 ){ + nodeReference(pParent); + nodeHashInsert(pRtree, pNode); + }else{ + rc = SQLITE_CORRUPT_VTAB; + RTREE_IS_CORRUPT(pRtree); + } + *ppNode = pNode; + }else{ + nodeBlobReset(pRtree); + if( pNode ){ + pRtree->nNodeRef--; + sqlite3_free(pNode); + } + *ppNode = 0; + } + + return rc; +} + +/* +** Overwrite cell iCell of node pNode with the contents of pCell. +*/ +static void nodeOverwriteCell( + Rtree *pRtree, /* The overall R-Tree */ + RtreeNode *pNode, /* The node into which the cell is to be written */ + RtreeCell *pCell, /* The cell to write */ + int iCell /* Index into pNode into which pCell is written */ +){ + int ii; + u8 *p = &pNode->zData[4 + pRtree->nBytesPerCell*iCell]; + p += writeInt64(p, pCell->iRowid); + for(ii=0; iinDim2; ii++){ + p += writeCoord(p, &pCell->aCoord[ii]); + } + pNode->isDirty = 1; +} + +/* +** Remove the cell with index iCell from node pNode. +*/ +static void nodeDeleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell){ + u8 *pDst = &pNode->zData[4 + pRtree->nBytesPerCell*iCell]; + u8 *pSrc = &pDst[pRtree->nBytesPerCell]; + int nByte = (NCELL(pNode) - iCell - 1) * pRtree->nBytesPerCell; + memmove(pDst, pSrc, nByte); + writeInt16(&pNode->zData[2], NCELL(pNode)-1); + pNode->isDirty = 1; +} + +/* +** Insert the contents of cell pCell into node pNode. If the insert +** is successful, return SQLITE_OK. +** +** If there is not enough free space in pNode, return SQLITE_FULL. +*/ +static int nodeInsertCell( + Rtree *pRtree, /* The overall R-Tree */ + RtreeNode *pNode, /* Write new cell into this node */ + RtreeCell *pCell /* The cell to be inserted */ +){ + int nCell; /* Current number of cells in pNode */ + int nMaxCell; /* Maximum number of cells for pNode */ + + nMaxCell = (pRtree->iNodeSize-4)/pRtree->nBytesPerCell; + nCell = NCELL(pNode); + + assert( nCell<=nMaxCell ); + if( nCellzData[2], nCell+1); + pNode->isDirty = 1; + } + + return (nCell==nMaxCell); +} + +/* +** If the node is dirty, write it out to the database. +*/ +static int nodeWrite(Rtree *pRtree, RtreeNode *pNode){ + int rc = SQLITE_OK; + if( pNode->isDirty ){ + sqlite3_stmt *p = pRtree->pWriteNode; + if( pNode->iNode ){ + sqlite3_bind_int64(p, 1, pNode->iNode); + }else{ + sqlite3_bind_null(p, 1); + } + sqlite3_bind_blob(p, 2, pNode->zData, pRtree->iNodeSize, SQLITE_STATIC); + sqlite3_step(p); + pNode->isDirty = 0; + rc = sqlite3_reset(p); + sqlite3_bind_null(p, 2); + if( pNode->iNode==0 && rc==SQLITE_OK ){ + pNode->iNode = sqlite3_last_insert_rowid(pRtree->db); + nodeHashInsert(pRtree, pNode); + } + } + return rc; +} + +/* +** Release a reference to a node. If the node is dirty and the reference +** count drops to zero, the node data is written to the database. +*/ +static int nodeRelease(Rtree *pRtree, RtreeNode *pNode){ + int rc = SQLITE_OK; + if( pNode ){ + assert( pNode->nRef>0 ); + assert( pRtree->nNodeRef>0 ); + pNode->nRef--; + if( pNode->nRef==0 ){ + pRtree->nNodeRef--; + if( pNode->iNode==1 ){ + pRtree->iDepth = -1; + } + if( pNode->pParent ){ + rc = nodeRelease(pRtree, pNode->pParent); + } + if( rc==SQLITE_OK ){ + rc = nodeWrite(pRtree, pNode); + } + nodeHashDelete(pRtree, pNode); + sqlite3_free(pNode); + } + } + return rc; +} + +/* +** Return the 64-bit integer value associated with cell iCell of +** node pNode. If pNode is a leaf node, this is a rowid. If it is +** an internal node, then the 64-bit integer is a child page number. +*/ +static i64 nodeGetRowid( + Rtree *pRtree, /* The overall R-Tree */ + RtreeNode *pNode, /* The node from which to extract the ID */ + int iCell /* The cell index from which to extract the ID */ +){ + assert( iCellzData[4 + pRtree->nBytesPerCell*iCell]); +} + +/* +** Return coordinate iCoord from cell iCell in node pNode. +*/ +static void nodeGetCoord( + Rtree *pRtree, /* The overall R-Tree */ + RtreeNode *pNode, /* The node from which to extract a coordinate */ + int iCell, /* The index of the cell within the node */ + int iCoord, /* Which coordinate to extract */ + RtreeCoord *pCoord /* OUT: Space to write result to */ +){ + assert( iCellzData[12 + pRtree->nBytesPerCell*iCell + 4*iCoord], pCoord); +} + +/* +** Deserialize cell iCell of node pNode. Populate the structure pointed +** to by pCell with the results. +*/ +static void nodeGetCell( + Rtree *pRtree, /* The overall R-Tree */ + RtreeNode *pNode, /* The node containing the cell to be read */ + int iCell, /* Index of the cell within the node */ + RtreeCell *pCell /* OUT: Write the cell contents here */ +){ + u8 *pData; + RtreeCoord *pCoord; + int ii = 0; + pCell->iRowid = nodeGetRowid(pRtree, pNode, iCell); + pData = pNode->zData + (12 + pRtree->nBytesPerCell*iCell); + pCoord = pCell->aCoord; + do{ + readCoord(pData, &pCoord[ii]); + readCoord(pData+4, &pCoord[ii+1]); + pData += 8; + ii += 2; + }while( iinDim2 ); +} + + +/* Forward declaration for the function that does the work of +** the virtual table module xCreate() and xConnect() methods. +*/ +static int rtreeInit( + sqlite3 *, void *, int, const char *const*, sqlite3_vtab **, char **, int +); + +/* +** Rtree virtual table module xCreate method. +*/ +static int rtreeCreate( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + return rtreeInit(db, pAux, argc, argv, ppVtab, pzErr, 1); +} + +/* +** Rtree virtual table module xConnect method. +*/ +static int rtreeConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + return rtreeInit(db, pAux, argc, argv, ppVtab, pzErr, 0); +} + +/* +** Increment the r-tree reference count. +*/ +static void rtreeReference(Rtree *pRtree){ + pRtree->nBusy++; +} + +/* +** Decrement the r-tree reference count. When the reference count reaches +** zero the structure is deleted. +*/ +static void rtreeRelease(Rtree *pRtree){ + pRtree->nBusy--; + if( pRtree->nBusy==0 ){ + pRtree->inWrTrans = 0; + assert( pRtree->nCursor==0 ); + nodeBlobReset(pRtree); + if( pRtree->nNodeRef ){ + int i; + assert( pRtree->bCorrupt ); + for(i=0; iaHash[i] ){ + RtreeNode *pNext = pRtree->aHash[i]->pNext; + sqlite3_free(pRtree->aHash[i]); + pRtree->aHash[i] = pNext; + } + } + } + sqlite3_finalize(pRtree->pWriteNode); + sqlite3_finalize(pRtree->pDeleteNode); + sqlite3_finalize(pRtree->pReadRowid); + sqlite3_finalize(pRtree->pWriteRowid); + sqlite3_finalize(pRtree->pDeleteRowid); + sqlite3_finalize(pRtree->pReadParent); + sqlite3_finalize(pRtree->pWriteParent); + sqlite3_finalize(pRtree->pDeleteParent); + sqlite3_finalize(pRtree->pWriteAux); + sqlite3_free(pRtree->zReadAuxSql); + sqlite3_free(pRtree); + } +} + +/* +** Rtree virtual table module xDisconnect method. +*/ +static int rtreeDisconnect(sqlite3_vtab *pVtab){ + rtreeRelease((Rtree *)pVtab); + return SQLITE_OK; +} + +/* +** Rtree virtual table module xDestroy method. +*/ +static int rtreeDestroy(sqlite3_vtab *pVtab){ + Rtree *pRtree = (Rtree *)pVtab; + int rc; + char *zCreate = sqlite3_mprintf( + "DROP TABLE '%q'.'%q_node';" + "DROP TABLE '%q'.'%q_rowid';" + "DROP TABLE '%q'.'%q_parent';", + pRtree->zDb, pRtree->zName, + pRtree->zDb, pRtree->zName, + pRtree->zDb, pRtree->zName + ); + if( !zCreate ){ + rc = SQLITE_NOMEM; + }else{ + nodeBlobReset(pRtree); + rc = sqlite3_exec(pRtree->db, zCreate, 0, 0, 0); + sqlite3_free(zCreate); + } + if( rc==SQLITE_OK ){ + rtreeRelease(pRtree); + } + + return rc; +} + +/* +** Rtree virtual table module xOpen method. +*/ +static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ + int rc = SQLITE_NOMEM; + Rtree *pRtree = (Rtree *)pVTab; + RtreeCursor *pCsr; + + pCsr = (RtreeCursor *)sqlite3_malloc64(sizeof(RtreeCursor)); + if( pCsr ){ + memset(pCsr, 0, sizeof(RtreeCursor)); + pCsr->base.pVtab = pVTab; + rc = SQLITE_OK; + pRtree->nCursor++; + } + *ppCursor = (sqlite3_vtab_cursor *)pCsr; + + return rc; +} + + +/* +** Reset a cursor back to its initial state. +*/ +static void resetCursor(RtreeCursor *pCsr){ + Rtree *pRtree = (Rtree *)(pCsr->base.pVtab); + int ii; + sqlite3_stmt *pStmt; + if( pCsr->aConstraint ){ + int i; /* Used to iterate through constraint array */ + for(i=0; inConstraint; i++){ + sqlite3_rtree_query_info *pInfo = pCsr->aConstraint[i].pInfo; + if( pInfo ){ + if( pInfo->xDelUser ) pInfo->xDelUser(pInfo->pUser); + sqlite3_free(pInfo); + } + } + sqlite3_free(pCsr->aConstraint); + pCsr->aConstraint = 0; + } + for(ii=0; iiaNode[ii]); + sqlite3_free(pCsr->aPoint); + pStmt = pCsr->pReadAux; + memset(pCsr, 0, sizeof(RtreeCursor)); + pCsr->base.pVtab = (sqlite3_vtab*)pRtree; + pCsr->pReadAux = pStmt; + + /* The following will only fail if the previous sqlite3_step() call failed, + ** in which case the error has already been caught. This statement never + ** encounters an error within an sqlite3_column_xxx() function, as it + ** calls sqlite3_column_value(), which does not use malloc(). So it is safe + ** to ignore the error code here. */ + sqlite3_reset(pStmt); +} + +/* +** Rtree virtual table module xClose method. +*/ +static int rtreeClose(sqlite3_vtab_cursor *cur){ + Rtree *pRtree = (Rtree *)(cur->pVtab); + RtreeCursor *pCsr = (RtreeCursor *)cur; + assert( pRtree->nCursor>0 ); + resetCursor(pCsr); + sqlite3_finalize(pCsr->pReadAux); + sqlite3_free(pCsr); + pRtree->nCursor--; + if( pRtree->nCursor==0 && pRtree->inWrTrans==0 ){ + nodeBlobReset(pRtree); + } + return SQLITE_OK; +} + +/* +** Rtree virtual table module xEof method. +** +** Return non-zero if the cursor does not currently point to a valid +** record (i.e if the scan has finished), or zero otherwise. +*/ +static int rtreeEof(sqlite3_vtab_cursor *cur){ + RtreeCursor *pCsr = (RtreeCursor *)cur; + return pCsr->atEOF; +} + +/* +** Convert raw bits from the on-disk RTree record into a coordinate value. +** The on-disk format is big-endian and needs to be converted for little- +** endian platforms. The on-disk record stores integer coordinates if +** eInt is true and it stores 32-bit floating point records if eInt is +** false. a[] is the four bytes of the on-disk record to be decoded. +** Store the results in "r". +** +** There are five versions of this macro. The last one is generic. The +** other four are various architectures-specific optimizations. +*/ +#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 +#define RTREE_DECODE_COORD(eInt, a, r) { \ + RtreeCoord c; /* Coordinate decoded */ \ + c.u = _byteswap_ulong(*(u32*)a); \ + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ +} +#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 +#define RTREE_DECODE_COORD(eInt, a, r) { \ + RtreeCoord c; /* Coordinate decoded */ \ + c.u = __builtin_bswap32(*(u32*)a); \ + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ +} +#elif SQLITE_BYTEORDER==1234 +#define RTREE_DECODE_COORD(eInt, a, r) { \ + RtreeCoord c; /* Coordinate decoded */ \ + memcpy(&c.u,a,4); \ + c.u = ((c.u>>24)&0xff)|((c.u>>8)&0xff00)| \ + ((c.u&0xff)<<24)|((c.u&0xff00)<<8); \ + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ +} +#elif SQLITE_BYTEORDER==4321 +#define RTREE_DECODE_COORD(eInt, a, r) { \ + RtreeCoord c; /* Coordinate decoded */ \ + memcpy(&c.u,a,4); \ + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ +} +#else +#define RTREE_DECODE_COORD(eInt, a, r) { \ + RtreeCoord c; /* Coordinate decoded */ \ + c.u = ((u32)a[0]<<24) + ((u32)a[1]<<16) \ + +((u32)a[2]<<8) + a[3]; \ + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ +} +#endif + +/* +** Check the RTree node or entry given by pCellData and p against the MATCH +** constraint pConstraint. +*/ +static int rtreeCallbackConstraint( + RtreeConstraint *pConstraint, /* The constraint to test */ + int eInt, /* True if RTree holding integer coordinates */ + u8 *pCellData, /* Raw cell content */ + RtreeSearchPoint *pSearch, /* Container of this cell */ + sqlite3_rtree_dbl *prScore, /* OUT: score for the cell */ + int *peWithin /* OUT: visibility of the cell */ +){ + sqlite3_rtree_query_info *pInfo = pConstraint->pInfo; /* Callback info */ + int nCoord = pInfo->nCoord; /* No. of coordinates */ + int rc; /* Callback return code */ + RtreeCoord c; /* Translator union */ + sqlite3_rtree_dbl aCoord[RTREE_MAX_DIMENSIONS*2]; /* Decoded coordinates */ + + assert( pConstraint->op==RTREE_MATCH || pConstraint->op==RTREE_QUERY ); + assert( nCoord==2 || nCoord==4 || nCoord==6 || nCoord==8 || nCoord==10 ); + + if( pConstraint->op==RTREE_QUERY && pSearch->iLevel==1 ){ + pInfo->iRowid = readInt64(pCellData); + } + pCellData += 8; +#ifndef SQLITE_RTREE_INT_ONLY + if( eInt==0 ){ + switch( nCoord ){ + case 10: readCoord(pCellData+36, &c); aCoord[9] = c.f; + readCoord(pCellData+32, &c); aCoord[8] = c.f; + case 8: readCoord(pCellData+28, &c); aCoord[7] = c.f; + readCoord(pCellData+24, &c); aCoord[6] = c.f; + case 6: readCoord(pCellData+20, &c); aCoord[5] = c.f; + readCoord(pCellData+16, &c); aCoord[4] = c.f; + case 4: readCoord(pCellData+12, &c); aCoord[3] = c.f; + readCoord(pCellData+8, &c); aCoord[2] = c.f; + default: readCoord(pCellData+4, &c); aCoord[1] = c.f; + readCoord(pCellData, &c); aCoord[0] = c.f; + } + }else +#endif + { + switch( nCoord ){ + case 10: readCoord(pCellData+36, &c); aCoord[9] = c.i; + readCoord(pCellData+32, &c); aCoord[8] = c.i; + case 8: readCoord(pCellData+28, &c); aCoord[7] = c.i; + readCoord(pCellData+24, &c); aCoord[6] = c.i; + case 6: readCoord(pCellData+20, &c); aCoord[5] = c.i; + readCoord(pCellData+16, &c); aCoord[4] = c.i; + case 4: readCoord(pCellData+12, &c); aCoord[3] = c.i; + readCoord(pCellData+8, &c); aCoord[2] = c.i; + default: readCoord(pCellData+4, &c); aCoord[1] = c.i; + readCoord(pCellData, &c); aCoord[0] = c.i; + } + } + if( pConstraint->op==RTREE_MATCH ){ + int eWithin = 0; + rc = pConstraint->u.xGeom((sqlite3_rtree_geometry*)pInfo, + nCoord, aCoord, &eWithin); + if( eWithin==0 ) *peWithin = NOT_WITHIN; + *prScore = RTREE_ZERO; + }else{ + pInfo->aCoord = aCoord; + pInfo->iLevel = pSearch->iLevel - 1; + pInfo->rScore = pInfo->rParentScore = pSearch->rScore; + pInfo->eWithin = pInfo->eParentWithin = pSearch->eWithin; + rc = pConstraint->u.xQueryFunc(pInfo); + if( pInfo->eWithin<*peWithin ) *peWithin = pInfo->eWithin; + if( pInfo->rScore<*prScore || *prScorerScore; + } + } + return rc; +} + +/* +** Check the internal RTree node given by pCellData against constraint p. +** If this constraint cannot be satisfied by any child within the node, +** set *peWithin to NOT_WITHIN. +*/ +static void rtreeNonleafConstraint( + RtreeConstraint *p, /* The constraint to test */ + int eInt, /* True if RTree holds integer coordinates */ + u8 *pCellData, /* Raw cell content as appears on disk */ + int *peWithin /* Adjust downward, as appropriate */ +){ + sqlite3_rtree_dbl val; /* Coordinate value convert to a double */ + + /* p->iCoord might point to either a lower or upper bound coordinate + ** in a coordinate pair. But make pCellData point to the lower bound. + */ + pCellData += 8 + 4*(p->iCoord&0xfe); + + assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE + || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE + || p->op==RTREE_FALSE ); + assert( FOUR_BYTE_ALIGNED(pCellData) ); + switch( p->op ){ + case RTREE_TRUE: return; /* Always satisfied */ + case RTREE_FALSE: break; /* Never satisfied */ + case RTREE_EQ: + RTREE_DECODE_COORD(eInt, pCellData, val); + /* val now holds the lower bound of the coordinate pair */ + if( p->u.rValue>=val ){ + pCellData += 4; + RTREE_DECODE_COORD(eInt, pCellData, val); + /* val now holds the upper bound of the coordinate pair */ + if( p->u.rValue<=val ) return; + } + break; + case RTREE_LE: + case RTREE_LT: + RTREE_DECODE_COORD(eInt, pCellData, val); + /* val now holds the lower bound of the coordinate pair */ + if( p->u.rValue>=val ) return; + break; + + default: + pCellData += 4; + RTREE_DECODE_COORD(eInt, pCellData, val); + /* val now holds the upper bound of the coordinate pair */ + if( p->u.rValue<=val ) return; + break; + } + *peWithin = NOT_WITHIN; +} + +/* +** Check the leaf RTree cell given by pCellData against constraint p. +** If this constraint is not satisfied, set *peWithin to NOT_WITHIN. +** If the constraint is satisfied, leave *peWithin unchanged. +** +** The constraint is of the form: xN op $val +** +** The op is given by p->op. The xN is p->iCoord-th coordinate in +** pCellData. $val is given by p->u.rValue. +*/ +static void rtreeLeafConstraint( + RtreeConstraint *p, /* The constraint to test */ + int eInt, /* True if RTree holds integer coordinates */ + u8 *pCellData, /* Raw cell content as appears on disk */ + int *peWithin /* Adjust downward, as appropriate */ +){ + RtreeDValue xN; /* Coordinate value converted to a double */ + + assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE + || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE + || p->op==RTREE_FALSE ); + pCellData += 8 + p->iCoord*4; + assert( FOUR_BYTE_ALIGNED(pCellData) ); + RTREE_DECODE_COORD(eInt, pCellData, xN); + switch( p->op ){ + case RTREE_TRUE: return; /* Always satisfied */ + case RTREE_FALSE: break; /* Never satisfied */ + case RTREE_LE: if( xN <= p->u.rValue ) return; break; + case RTREE_LT: if( xN < p->u.rValue ) return; break; + case RTREE_GE: if( xN >= p->u.rValue ) return; break; + case RTREE_GT: if( xN > p->u.rValue ) return; break; + default: if( xN == p->u.rValue ) return; break; + } + *peWithin = NOT_WITHIN; +} + +/* +** One of the cells in node pNode is guaranteed to have a 64-bit +** integer value equal to iRowid. Return the index of this cell. +*/ +static int nodeRowidIndex( + Rtree *pRtree, + RtreeNode *pNode, + i64 iRowid, + int *piIndex +){ + int ii; + int nCell = NCELL(pNode); + assert( nCell<65536 && nCell>=0 ); + for(ii=0; iipParent; + if( ALWAYS(pParent) ){ + return nodeRowidIndex(pRtree, pParent, pNode->iNode, piIndex); + }else{ + *piIndex = -1; + return SQLITE_OK; + } +} + +/* +** Compare two search points. Return negative, zero, or positive if the first +** is less than, equal to, or greater than the second. +** +** The rScore is the primary key. Smaller rScore values come first. +** If the rScore is a tie, then use iLevel as the tie breaker with smaller +** iLevel values coming first. In this way, if rScore is the same for all +** SearchPoints, then iLevel becomes the deciding factor and the result +** is a depth-first search, which is the desired default behavior. +*/ +static int rtreeSearchPointCompare( + const RtreeSearchPoint *pA, + const RtreeSearchPoint *pB +){ + if( pA->rScorerScore ) return -1; + if( pA->rScore>pB->rScore ) return +1; + if( pA->iLeveliLevel ) return -1; + if( pA->iLevel>pB->iLevel ) return +1; + return 0; +} + +/* +** Interchange two search points in a cursor. +*/ +static void rtreeSearchPointSwap(RtreeCursor *p, int i, int j){ + RtreeSearchPoint t = p->aPoint[i]; + assert( iaPoint[i] = p->aPoint[j]; + p->aPoint[j] = t; + i++; j++; + if( i=RTREE_CACHE_SZ ){ + nodeRelease(RTREE_OF_CURSOR(p), p->aNode[i]); + p->aNode[i] = 0; + }else{ + RtreeNode *pTemp = p->aNode[i]; + p->aNode[i] = p->aNode[j]; + p->aNode[j] = pTemp; + } + } +} + +/* +** Return the search point with the lowest current score. +*/ +static RtreeSearchPoint *rtreeSearchPointFirst(RtreeCursor *pCur){ + return pCur->bPoint ? &pCur->sPoint : pCur->nPoint ? pCur->aPoint : 0; +} + +/* +** Get the RtreeNode for the search point with the lowest score. +*/ +static RtreeNode *rtreeNodeOfFirstSearchPoint(RtreeCursor *pCur, int *pRC){ + sqlite3_int64 id; + int ii = 1 - pCur->bPoint; + assert( ii==0 || ii==1 ); + assert( pCur->bPoint || pCur->nPoint ); + if( pCur->aNode[ii]==0 ){ + assert( pRC!=0 ); + id = ii ? pCur->aPoint[0].id : pCur->sPoint.id; + *pRC = nodeAcquire(RTREE_OF_CURSOR(pCur), id, 0, &pCur->aNode[ii]); + } + return pCur->aNode[ii]; +} + +/* +** Push a new element onto the priority queue +*/ +static RtreeSearchPoint *rtreeEnqueue( + RtreeCursor *pCur, /* The cursor */ + RtreeDValue rScore, /* Score for the new search point */ + u8 iLevel /* Level for the new search point */ +){ + int i, j; + RtreeSearchPoint *pNew; + if( pCur->nPoint>=pCur->nPointAlloc ){ + int nNew = pCur->nPointAlloc*2 + 8; + pNew = sqlite3_realloc64(pCur->aPoint, nNew*sizeof(pCur->aPoint[0])); + if( pNew==0 ) return 0; + pCur->aPoint = pNew; + pCur->nPointAlloc = nNew; + } + i = pCur->nPoint++; + pNew = pCur->aPoint + i; + pNew->rScore = rScore; + pNew->iLevel = iLevel; + assert( iLevel<=RTREE_MAX_DEPTH ); + while( i>0 ){ + RtreeSearchPoint *pParent; + j = (i-1)/2; + pParent = pCur->aPoint + j; + if( rtreeSearchPointCompare(pNew, pParent)>=0 ) break; + rtreeSearchPointSwap(pCur, j, i); + i = j; + pNew = pParent; + } + return pNew; +} + +/* +** Allocate a new RtreeSearchPoint and return a pointer to it. Return +** NULL if malloc fails. +*/ +static RtreeSearchPoint *rtreeSearchPointNew( + RtreeCursor *pCur, /* The cursor */ + RtreeDValue rScore, /* Score for the new search point */ + u8 iLevel /* Level for the new search point */ +){ + RtreeSearchPoint *pNew, *pFirst; + pFirst = rtreeSearchPointFirst(pCur); + pCur->anQueue[iLevel]++; + if( pFirst==0 + || pFirst->rScore>rScore + || (pFirst->rScore==rScore && pFirst->iLevel>iLevel) + ){ + if( pCur->bPoint ){ + int ii; + pNew = rtreeEnqueue(pCur, rScore, iLevel); + if( pNew==0 ) return 0; + ii = (int)(pNew - pCur->aPoint) + 1; + assert( ii==1 ); + if( ALWAYS(iiaNode[ii]==0 ); + pCur->aNode[ii] = pCur->aNode[0]; + }else{ + nodeRelease(RTREE_OF_CURSOR(pCur), pCur->aNode[0]); + } + pCur->aNode[0] = 0; + *pNew = pCur->sPoint; + } + pCur->sPoint.rScore = rScore; + pCur->sPoint.iLevel = iLevel; + pCur->bPoint = 1; + return &pCur->sPoint; + }else{ + return rtreeEnqueue(pCur, rScore, iLevel); + } +} + +#if 0 +/* Tracing routines for the RtreeSearchPoint queue */ +static void tracePoint(RtreeSearchPoint *p, int idx, RtreeCursor *pCur){ + if( idx<0 ){ printf(" s"); }else{ printf("%2d", idx); } + printf(" %d.%05lld.%02d %g %d", + p->iLevel, p->id, p->iCell, p->rScore, p->eWithin + ); + idx++; + if( idxaNode[idx]); + }else{ + printf("\n"); + } +} +static void traceQueue(RtreeCursor *pCur, const char *zPrefix){ + int ii; + printf("=== %9s ", zPrefix); + if( pCur->bPoint ){ + tracePoint(&pCur->sPoint, -1, pCur); + } + for(ii=0; iinPoint; ii++){ + if( ii>0 || pCur->bPoint ) printf(" "); + tracePoint(&pCur->aPoint[ii], ii, pCur); + } +} +# define RTREE_QUEUE_TRACE(A,B) traceQueue(A,B) +#else +# define RTREE_QUEUE_TRACE(A,B) /* no-op */ +#endif + +/* Remove the search point with the lowest current score. +*/ +static void rtreeSearchPointPop(RtreeCursor *p){ + int i, j, k, n; + i = 1 - p->bPoint; + assert( i==0 || i==1 ); + if( p->aNode[i] ){ + nodeRelease(RTREE_OF_CURSOR(p), p->aNode[i]); + p->aNode[i] = 0; + } + if( p->bPoint ){ + p->anQueue[p->sPoint.iLevel]--; + p->bPoint = 0; + }else if( ALWAYS(p->nPoint) ){ + p->anQueue[p->aPoint[0].iLevel]--; + n = --p->nPoint; + p->aPoint[0] = p->aPoint[n]; + if( naNode[1] = p->aNode[n+1]; + p->aNode[n+1] = 0; + } + i = 0; + while( (j = i*2+1)aPoint[k], &p->aPoint[j])<0 ){ + if( rtreeSearchPointCompare(&p->aPoint[k], &p->aPoint[i])<0 ){ + rtreeSearchPointSwap(p, i, k); + i = k; + }else{ + break; + } + }else{ + if( rtreeSearchPointCompare(&p->aPoint[j], &p->aPoint[i])<0 ){ + rtreeSearchPointSwap(p, i, j); + i = j; + }else{ + break; + } + } + } + } +} + + +/* +** Continue the search on cursor pCur until the front of the queue +** contains an entry suitable for returning as a result-set row, +** or until the RtreeSearchPoint queue is empty, indicating that the +** query has completed. +*/ +static int rtreeStepToLeaf(RtreeCursor *pCur){ + RtreeSearchPoint *p; + Rtree *pRtree = RTREE_OF_CURSOR(pCur); + RtreeNode *pNode; + int eWithin; + int rc = SQLITE_OK; + int nCell; + int nConstraint = pCur->nConstraint; + int ii; + int eInt; + RtreeSearchPoint x; + + eInt = pRtree->eCoordType==RTREE_COORD_INT32; + while( (p = rtreeSearchPointFirst(pCur))!=0 && p->iLevel>0 ){ + u8 *pCellData; + pNode = rtreeNodeOfFirstSearchPoint(pCur, &rc); + if( rc ) return rc; + nCell = NCELL(pNode); + if( nCell>RTREE_MAXCELLS ){ + RTREE_IS_CORRUPT(pRtree); + return SQLITE_CORRUPT_VTAB; + } + pCellData = pNode->zData + (4+pRtree->nBytesPerCell*p->iCell); + while( p->iCellaConstraint + ii; + if( pConstraint->op>=RTREE_MATCH ){ + rc = rtreeCallbackConstraint(pConstraint, eInt, pCellData, p, + &rScore, &eWithin); + if( rc ) return rc; + }else if( p->iLevel==1 ){ + rtreeLeafConstraint(pConstraint, eInt, pCellData, &eWithin); + }else{ + rtreeNonleafConstraint(pConstraint, eInt, pCellData, &eWithin); + } + if( eWithin==NOT_WITHIN ){ + p->iCell++; + pCellData += pRtree->nBytesPerCell; + break; + } + } + if( eWithin==NOT_WITHIN ) continue; + p->iCell++; + x.iLevel = p->iLevel - 1; + if( x.iLevel ){ + x.id = readInt64(pCellData); + for(ii=0; iinPoint; ii++){ + if( pCur->aPoint[ii].id==x.id ){ + RTREE_IS_CORRUPT(pRtree); + return SQLITE_CORRUPT_VTAB; + } + } + x.iCell = 0; + }else{ + x.id = p->id; + x.iCell = p->iCell - 1; + } + if( p->iCell>=nCell ){ + RTREE_QUEUE_TRACE(pCur, "POP-S:"); + rtreeSearchPointPop(pCur); + } + if( rScoreeWithin = (u8)eWithin; + p->id = x.id; + p->iCell = x.iCell; + RTREE_QUEUE_TRACE(pCur, "PUSH-S:"); + break; + } + if( p->iCell>=nCell ){ + RTREE_QUEUE_TRACE(pCur, "POP-Se:"); + rtreeSearchPointPop(pCur); + } + } + pCur->atEOF = p==0; + return SQLITE_OK; +} + +/* +** Rtree virtual table module xNext method. +*/ +static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){ + RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; + int rc = SQLITE_OK; + + /* Move to the next entry that matches the configured constraints. */ + RTREE_QUEUE_TRACE(pCsr, "POP-Nx:"); + if( pCsr->bAuxValid ){ + pCsr->bAuxValid = 0; + sqlite3_reset(pCsr->pReadAux); + } + rtreeSearchPointPop(pCsr); + rc = rtreeStepToLeaf(pCsr); + return rc; +} + +/* +** Rtree virtual table module xRowid method. +*/ +static int rtreeRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){ + RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; + RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr); + int rc = SQLITE_OK; + RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); + if( rc==SQLITE_OK && ALWAYS(p) ){ + if( p->iCell>=NCELL(pNode) ){ + rc = SQLITE_ABORT; + }else{ + *pRowid = nodeGetRowid(RTREE_OF_CURSOR(pCsr), pNode, p->iCell); + } + } + return rc; +} + +/* +** Rtree virtual table module xColumn method. +*/ +static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ + Rtree *pRtree = (Rtree *)cur->pVtab; + RtreeCursor *pCsr = (RtreeCursor *)cur; + RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr); + RtreeCoord c; + int rc = SQLITE_OK; + RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); + + if( rc ) return rc; + if( NEVER(p==0) ) return SQLITE_OK; + if( p->iCell>=NCELL(pNode) ) return SQLITE_ABORT; + if( i==0 ){ + sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell)); + }else if( i<=pRtree->nDim2 ){ + nodeGetCoord(pRtree, pNode, p->iCell, i-1, &c); +#ifndef SQLITE_RTREE_INT_ONLY + if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ + sqlite3_result_double(ctx, c.f); + }else +#endif + { + assert( pRtree->eCoordType==RTREE_COORD_INT32 ); + sqlite3_result_int(ctx, c.i); + } + }else{ + if( !pCsr->bAuxValid ){ + if( pCsr->pReadAux==0 ){ + rc = sqlite3_prepare_v3(pRtree->db, pRtree->zReadAuxSql, -1, 0, + &pCsr->pReadAux, 0); + if( rc ) return rc; + } + sqlite3_bind_int64(pCsr->pReadAux, 1, + nodeGetRowid(pRtree, pNode, p->iCell)); + rc = sqlite3_step(pCsr->pReadAux); + if( rc==SQLITE_ROW ){ + pCsr->bAuxValid = 1; + }else{ + sqlite3_reset(pCsr->pReadAux); + if( rc==SQLITE_DONE ) rc = SQLITE_OK; + return rc; + } + } + sqlite3_result_value(ctx, + sqlite3_column_value(pCsr->pReadAux, i - pRtree->nDim2 + 1)); + } + return SQLITE_OK; +} + +/* +** Use nodeAcquire() to obtain the leaf node containing the record with +** rowid iRowid. If successful, set *ppLeaf to point to the node and +** return SQLITE_OK. If there is no such record in the table, set +** *ppLeaf to 0 and return SQLITE_OK. If an error occurs, set *ppLeaf +** to zero and return an SQLite error code. +*/ +static int findLeafNode( + Rtree *pRtree, /* RTree to search */ + i64 iRowid, /* The rowid searching for */ + RtreeNode **ppLeaf, /* Write the node here */ + sqlite3_int64 *piNode /* Write the node-id here */ +){ + int rc; + *ppLeaf = 0; + sqlite3_bind_int64(pRtree->pReadRowid, 1, iRowid); + if( sqlite3_step(pRtree->pReadRowid)==SQLITE_ROW ){ + i64 iNode = sqlite3_column_int64(pRtree->pReadRowid, 0); + if( piNode ) *piNode = iNode; + rc = nodeAcquire(pRtree, iNode, 0, ppLeaf); + sqlite3_reset(pRtree->pReadRowid); + }else{ + rc = sqlite3_reset(pRtree->pReadRowid); + } + return rc; +} + +/* +** This function is called to configure the RtreeConstraint object passed +** as the second argument for a MATCH constraint. The value passed as the +** first argument to this function is the right-hand operand to the MATCH +** operator. +*/ +static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){ + RtreeMatchArg *pBlob, *pSrc; /* BLOB returned by geometry function */ + sqlite3_rtree_query_info *pInfo; /* Callback information */ + + pSrc = sqlite3_value_pointer(pValue, "RtreeMatchArg"); + if( pSrc==0 ) return SQLITE_ERROR; + pInfo = (sqlite3_rtree_query_info*) + sqlite3_malloc64( sizeof(*pInfo)+pSrc->iSize ); + if( !pInfo ) return SQLITE_NOMEM; + memset(pInfo, 0, sizeof(*pInfo)); + pBlob = (RtreeMatchArg*)&pInfo[1]; + memcpy(pBlob, pSrc, pSrc->iSize); + pInfo->pContext = pBlob->cb.pContext; + pInfo->nParam = pBlob->nParam; + pInfo->aParam = pBlob->aParam; + pInfo->apSqlParam = pBlob->apSqlParam; + + if( pBlob->cb.xGeom ){ + pCons->u.xGeom = pBlob->cb.xGeom; + }else{ + pCons->op = RTREE_QUERY; + pCons->u.xQueryFunc = pBlob->cb.xQueryFunc; + } + pCons->pInfo = pInfo; + return SQLITE_OK; +} + +SQLITE_PRIVATE int sqlite3IntFloatCompare(i64,double); + +/* +** Rtree virtual table module xFilter method. +*/ +static int rtreeFilter( + sqlite3_vtab_cursor *pVtabCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + Rtree *pRtree = (Rtree *)pVtabCursor->pVtab; + RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; + RtreeNode *pRoot = 0; + int ii; + int rc = SQLITE_OK; + int iCell = 0; + + rtreeReference(pRtree); + + /* Reset the cursor to the same state as rtreeOpen() leaves it in. */ + resetCursor(pCsr); + + pCsr->iStrategy = idxNum; + if( idxNum==1 ){ + /* Special case - lookup by rowid. */ + RtreeNode *pLeaf; /* Leaf on which the required cell resides */ + RtreeSearchPoint *p; /* Search point for the leaf */ + i64 iRowid = sqlite3_value_int64(argv[0]); + i64 iNode = 0; + int eType = sqlite3_value_numeric_type(argv[0]); + if( eType==SQLITE_INTEGER + || (eType==SQLITE_FLOAT + && 0==sqlite3IntFloatCompare(iRowid,sqlite3_value_double(argv[0]))) + ){ + rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode); + }else{ + rc = SQLITE_OK; + pLeaf = 0; + } + if( rc==SQLITE_OK && pLeaf!=0 ){ + p = rtreeSearchPointNew(pCsr, RTREE_ZERO, 0); + assert( p!=0 ); /* Always returns pCsr->sPoint */ + pCsr->aNode[0] = pLeaf; + p->id = iNode; + p->eWithin = PARTLY_WITHIN; + rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &iCell); + p->iCell = (u8)iCell; + RTREE_QUEUE_TRACE(pCsr, "PUSH-F1:"); + }else{ + pCsr->atEOF = 1; + } + }else{ + /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array + ** with the configured constraints. + */ + rc = nodeAcquire(pRtree, 1, 0, &pRoot); + if( rc==SQLITE_OK && argc>0 ){ + pCsr->aConstraint = sqlite3_malloc64(sizeof(RtreeConstraint)*argc); + pCsr->nConstraint = argc; + if( !pCsr->aConstraint ){ + rc = SQLITE_NOMEM; + }else{ + memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*argc); + memset(pCsr->anQueue, 0, sizeof(u32)*(pRtree->iDepth + 1)); + assert( (idxStr==0 && argc==0) + || (idxStr && (int)strlen(idxStr)==argc*2) ); + for(ii=0; iiaConstraint[ii]; + int eType = sqlite3_value_numeric_type(argv[ii]); + p->op = idxStr[ii*2]; + p->iCoord = idxStr[ii*2+1]-'0'; + if( p->op>=RTREE_MATCH ){ + /* A MATCH operator. The right-hand-side must be a blob that + ** can be cast into an RtreeMatchArg object. One created using + ** an sqlite3_rtree_geometry_callback() SQL user function. + */ + rc = deserializeGeometry(argv[ii], p); + if( rc!=SQLITE_OK ){ + break; + } + p->pInfo->nCoord = pRtree->nDim2; + p->pInfo->anQueue = pCsr->anQueue; + p->pInfo->mxLevel = pRtree->iDepth + 1; + }else if( eType==SQLITE_INTEGER ){ + sqlite3_int64 iVal = sqlite3_value_int64(argv[ii]); +#ifdef SQLITE_RTREE_INT_ONLY + p->u.rValue = iVal; +#else + p->u.rValue = (double)iVal; + if( iVal>=((sqlite3_int64)1)<<48 + || iVal<=-(((sqlite3_int64)1)<<48) + ){ + if( p->op==RTREE_LT ) p->op = RTREE_LE; + if( p->op==RTREE_GT ) p->op = RTREE_GE; + } +#endif + }else if( eType==SQLITE_FLOAT ){ +#ifdef SQLITE_RTREE_INT_ONLY + p->u.rValue = sqlite3_value_int64(argv[ii]); +#else + p->u.rValue = sqlite3_value_double(argv[ii]); +#endif + }else{ + p->u.rValue = RTREE_ZERO; + if( eType==SQLITE_NULL ){ + p->op = RTREE_FALSE; + }else if( p->op==RTREE_LT || p->op==RTREE_LE ){ + p->op = RTREE_TRUE; + }else{ + p->op = RTREE_FALSE; + } + } + } + } + } + if( rc==SQLITE_OK ){ + RtreeSearchPoint *pNew; + assert( pCsr->bPoint==0 ); /* Due to the resetCursor() call above */ + pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, (u8)(pRtree->iDepth+1)); + if( NEVER(pNew==0) ){ /* Because pCsr->bPoint was FALSE */ + return SQLITE_NOMEM; + } + pNew->id = 1; + pNew->iCell = 0; + pNew->eWithin = PARTLY_WITHIN; + assert( pCsr->bPoint==1 ); + pCsr->aNode[0] = pRoot; + pRoot = 0; + RTREE_QUEUE_TRACE(pCsr, "PUSH-Fm:"); + rc = rtreeStepToLeaf(pCsr); + } + } + + nodeRelease(pRtree, pRoot); + rtreeRelease(pRtree); + return rc; +} + +/* +** Rtree virtual table module xBestIndex method. There are three +** table scan strategies to choose from (in order from most to +** least desirable): +** +** idxNum idxStr Strategy +** ------------------------------------------------ +** 1 Unused Direct lookup by rowid. +** 2 See below R-tree query or full-table scan. +** ------------------------------------------------ +** +** If strategy 1 is used, then idxStr is not meaningful. If strategy +** 2 is used, idxStr is formatted to contain 2 bytes for each +** constraint used. The first two bytes of idxStr correspond to +** the constraint in sqlite3_index_info.aConstraintUsage[] with +** (argvIndex==1) etc. +** +** The first of each pair of bytes in idxStr identifies the constraint +** operator as follows: +** +** Operator Byte Value +** ---------------------- +** = 0x41 ('A') +** <= 0x42 ('B') +** < 0x43 ('C') +** >= 0x44 ('D') +** > 0x45 ('E') +** MATCH 0x46 ('F') +** ---------------------- +** +** The second of each pair of bytes identifies the coordinate column +** to which the constraint applies. The leftmost coordinate column +** is 'a', the second from the left 'b' etc. +*/ +static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ + Rtree *pRtree = (Rtree*)tab; + int rc = SQLITE_OK; + int ii; + int bMatch = 0; /* True if there exists a MATCH constraint */ + i64 nRow; /* Estimated rows returned by this scan */ + + int iIdx = 0; + char zIdxStr[RTREE_MAX_DIMENSIONS*8+1]; + memset(zIdxStr, 0, sizeof(zIdxStr)); + + /* Check if there exists a MATCH constraint - even an unusable one. If there + ** is, do not consider the lookup-by-rowid plan as using such a plan would + ** require the VDBE to evaluate the MATCH constraint, which is not currently + ** possible. */ + for(ii=0; iinConstraint; ii++){ + if( pIdxInfo->aConstraint[ii].op==SQLITE_INDEX_CONSTRAINT_MATCH ){ + bMatch = 1; + } + } + + assert( pIdxInfo->idxStr==0 ); + for(ii=0; iinConstraint && iIdx<(int)(sizeof(zIdxStr)-1); ii++){ + struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii]; + + if( bMatch==0 && p->usable + && p->iColumn<=0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ + ){ + /* We have an equality constraint on the rowid. Use strategy 1. */ + int jj; + for(jj=0; jjaConstraintUsage[jj].argvIndex = 0; + pIdxInfo->aConstraintUsage[jj].omit = 0; + } + pIdxInfo->idxNum = 1; + pIdxInfo->aConstraintUsage[ii].argvIndex = 1; + pIdxInfo->aConstraintUsage[jj].omit = 1; + + /* This strategy involves a two rowid lookups on an B-Tree structures + ** and then a linear search of an R-Tree node. This should be + ** considered almost as quick as a direct rowid lookup (for which + ** sqlite uses an internal cost of 0.0). It is expected to return + ** a single row. + */ + pIdxInfo->estimatedCost = 30.0; + pIdxInfo->estimatedRows = 1; + pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE; + return SQLITE_OK; + } + + if( p->usable + && ((p->iColumn>0 && p->iColumn<=pRtree->nDim2) + || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) + ){ + u8 op; + u8 doOmit = 1; + switch( p->op ){ + case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; doOmit = 0; break; + case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; doOmit = 0; break; + case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break; + case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; doOmit = 0; break; + case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break; + case SQLITE_INDEX_CONSTRAINT_MATCH: op = RTREE_MATCH; break; + default: op = 0; break; + } + if( op ){ + zIdxStr[iIdx++] = op; + zIdxStr[iIdx++] = (char)(p->iColumn - 1 + '0'); + pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2); + pIdxInfo->aConstraintUsage[ii].omit = doOmit; + } + } + } + + pIdxInfo->idxNum = 2; + pIdxInfo->needToFreeIdxStr = 1; + if( iIdx>0 ){ + pIdxInfo->idxStr = sqlite3_malloc( iIdx+1 ); + if( pIdxInfo->idxStr==0 ){ + return SQLITE_NOMEM; + } + memcpy(pIdxInfo->idxStr, zIdxStr, iIdx+1); + } + + nRow = pRtree->nRowEst >> (iIdx/2); + pIdxInfo->estimatedCost = (double)6.0 * (double)nRow; + pIdxInfo->estimatedRows = nRow; + + return rc; +} + +/* +** Return the N-dimensional volume of the cell stored in *p. +*/ +static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){ + RtreeDValue area = (RtreeDValue)1; + assert( pRtree->nDim>=1 && pRtree->nDim<=5 ); +#ifndef SQLITE_RTREE_INT_ONLY + if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ + switch( pRtree->nDim ){ + case 5: area = p->aCoord[9].f - p->aCoord[8].f; + case 4: area *= p->aCoord[7].f - p->aCoord[6].f; + case 3: area *= p->aCoord[5].f - p->aCoord[4].f; + case 2: area *= p->aCoord[3].f - p->aCoord[2].f; + default: area *= p->aCoord[1].f - p->aCoord[0].f; + } + }else +#endif + { + switch( pRtree->nDim ){ + case 5: area = (i64)p->aCoord[9].i - (i64)p->aCoord[8].i; + case 4: area *= (i64)p->aCoord[7].i - (i64)p->aCoord[6].i; + case 3: area *= (i64)p->aCoord[5].i - (i64)p->aCoord[4].i; + case 2: area *= (i64)p->aCoord[3].i - (i64)p->aCoord[2].i; + default: area *= (i64)p->aCoord[1].i - (i64)p->aCoord[0].i; + } + } + return area; +} + +/* +** Return the margin length of cell p. The margin length is the sum +** of the objects size in each dimension. +*/ +static RtreeDValue cellMargin(Rtree *pRtree, RtreeCell *p){ + RtreeDValue margin = 0; + int ii = pRtree->nDim2 - 2; + do{ + margin += (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])); + ii -= 2; + }while( ii>=0 ); + return margin; +} + +/* +** Store the union of cells p1 and p2 in p1. +*/ +static void cellUnion(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){ + int ii = 0; + if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ + do{ + p1->aCoord[ii].f = MIN(p1->aCoord[ii].f, p2->aCoord[ii].f); + p1->aCoord[ii+1].f = MAX(p1->aCoord[ii+1].f, p2->aCoord[ii+1].f); + ii += 2; + }while( iinDim2 ); + }else{ + do{ + p1->aCoord[ii].i = MIN(p1->aCoord[ii].i, p2->aCoord[ii].i); + p1->aCoord[ii+1].i = MAX(p1->aCoord[ii+1].i, p2->aCoord[ii+1].i); + ii += 2; + }while( iinDim2 ); + } +} + +/* +** Return true if the area covered by p2 is a subset of the area covered +** by p1. False otherwise. +*/ +static int cellContains(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){ + int ii; + if( pRtree->eCoordType==RTREE_COORD_INT32 ){ + for(ii=0; iinDim2; ii+=2){ + RtreeCoord *a1 = &p1->aCoord[ii]; + RtreeCoord *a2 = &p2->aCoord[ii]; + if( a2[0].ia1[1].i ) return 0; + } + }else{ + for(ii=0; iinDim2; ii+=2){ + RtreeCoord *a1 = &p1->aCoord[ii]; + RtreeCoord *a2 = &p2->aCoord[ii]; + if( a2[0].fa1[1].f ) return 0; + } + } + return 1; +} + +static RtreeDValue cellOverlap( + Rtree *pRtree, + RtreeCell *p, + RtreeCell *aCell, + int nCell +){ + int ii; + RtreeDValue overlap = RTREE_ZERO; + for(ii=0; iinDim2; jj+=2){ + RtreeDValue x1, x2; + x1 = MAX(DCOORD(p->aCoord[jj]), DCOORD(aCell[ii].aCoord[jj])); + x2 = MIN(DCOORD(p->aCoord[jj+1]), DCOORD(aCell[ii].aCoord[jj+1])); + if( x2iDepth-iHeight); ii++){ + int iCell; + sqlite3_int64 iBest = 0; + int bFound = 0; + RtreeDValue fMinGrowth = RTREE_ZERO; + RtreeDValue fMinArea = RTREE_ZERO; + int nCell = NCELL(pNode); + RtreeNode *pChild = 0; + + /* First check to see if there is are any cells in pNode that completely + ** contains pCell. If two or more cells in pNode completely contain pCell + ** then pick the smallest. + */ + for(iCell=0; iCellpParent ){ + RtreeNode *pParent = p->pParent; + RtreeCell cell; + int iCell; + + cnt++; + if( cnt>100 ){ + RTREE_IS_CORRUPT(pRtree); + return SQLITE_CORRUPT_VTAB; + } + rc = nodeParentIndex(pRtree, p, &iCell); + if( NEVER(rc!=SQLITE_OK) ){ + RTREE_IS_CORRUPT(pRtree); + return SQLITE_CORRUPT_VTAB; + } + + nodeGetCell(pRtree, pParent, iCell, &cell); + if( !cellContains(pRtree, &cell, pCell) ){ + cellUnion(pRtree, &cell, pCell); + nodeOverwriteCell(pRtree, pParent, &cell, iCell); + } + + p = pParent; + } + return SQLITE_OK; +} + +/* +** Write mapping (iRowid->iNode) to the _rowid table. +*/ +static int rowidWrite(Rtree *pRtree, sqlite3_int64 iRowid, sqlite3_int64 iNode){ + sqlite3_bind_int64(pRtree->pWriteRowid, 1, iRowid); + sqlite3_bind_int64(pRtree->pWriteRowid, 2, iNode); + sqlite3_step(pRtree->pWriteRowid); + return sqlite3_reset(pRtree->pWriteRowid); +} + +/* +** Write mapping (iNode->iPar) to the _parent table. +*/ +static int parentWrite(Rtree *pRtree, sqlite3_int64 iNode, sqlite3_int64 iPar){ + sqlite3_bind_int64(pRtree->pWriteParent, 1, iNode); + sqlite3_bind_int64(pRtree->pWriteParent, 2, iPar); + sqlite3_step(pRtree->pWriteParent); + return sqlite3_reset(pRtree->pWriteParent); +} + +static int rtreeInsertCell(Rtree *, RtreeNode *, RtreeCell *, int); + + + +/* +** Arguments aIdx, aCell and aSpare all point to arrays of size +** nIdx. The aIdx array contains the set of integers from 0 to +** (nIdx-1) in no particular order. This function sorts the values +** in aIdx according to dimension iDim of the cells in aCell. The +** minimum value of dimension iDim is considered first, the +** maximum used to break ties. +** +** The aSpare array is used as temporary working space by the +** sorting algorithm. +*/ +static void SortByDimension( + Rtree *pRtree, + int *aIdx, + int nIdx, + int iDim, + RtreeCell *aCell, + int *aSpare +){ + if( nIdx>1 ){ + + int iLeft = 0; + int iRight = 0; + + int nLeft = nIdx/2; + int nRight = nIdx-nLeft; + int *aLeft = aIdx; + int *aRight = &aIdx[nLeft]; + + SortByDimension(pRtree, aLeft, nLeft, iDim, aCell, aSpare); + SortByDimension(pRtree, aRight, nRight, iDim, aCell, aSpare); + + memcpy(aSpare, aLeft, sizeof(int)*nLeft); + aLeft = aSpare; + while( iLeftnDim+1)*(sizeof(int*)+nCell*sizeof(int)); + + aaSorted = (int **)sqlite3_malloc64(nByte); + if( !aaSorted ){ + return SQLITE_NOMEM; + } + + aSpare = &((int *)&aaSorted[pRtree->nDim])[pRtree->nDim*nCell]; + memset(aaSorted, 0, nByte); + for(ii=0; iinDim; ii++){ + int jj; + aaSorted[ii] = &((int *)&aaSorted[pRtree->nDim])[ii*nCell]; + for(jj=0; jjnDim; ii++){ + RtreeDValue margin = RTREE_ZERO; + RtreeDValue fBestOverlap = RTREE_ZERO; + RtreeDValue fBestArea = RTREE_ZERO; + int iBestLeft = 0; + int nLeft; + + for( + nLeft=RTREE_MINCELLS(pRtree); + nLeft<=(nCell-RTREE_MINCELLS(pRtree)); + nLeft++ + ){ + RtreeCell left; + RtreeCell right; + int kk; + RtreeDValue overlap; + RtreeDValue area; + + memcpy(&left, &aCell[aaSorted[ii][0]], sizeof(RtreeCell)); + memcpy(&right, &aCell[aaSorted[ii][nCell-1]], sizeof(RtreeCell)); + for(kk=1; kk<(nCell-1); kk++){ + if( kk0 ){ + RtreeNode *pChild = nodeHashLookup(pRtree, iRowid); + RtreeNode *p; + for(p=pNode; p; p=p->pParent){ + if( p==pChild ) return SQLITE_CORRUPT_VTAB; + } + if( pChild ){ + nodeRelease(pRtree, pChild->pParent); + nodeReference(pNode); + pChild->pParent = pNode; + } + } + if( NEVER(pNode==0) ) return SQLITE_ERROR; + return xSetMapping(pRtree, iRowid, pNode->iNode); +} + +static int SplitNode( + Rtree *pRtree, + RtreeNode *pNode, + RtreeCell *pCell, + int iHeight +){ + int i; + int newCellIsRight = 0; + + int rc = SQLITE_OK; + int nCell = NCELL(pNode); + RtreeCell *aCell; + int *aiUsed; + + RtreeNode *pLeft = 0; + RtreeNode *pRight = 0; + + RtreeCell leftbbox; + RtreeCell rightbbox; + + /* Allocate an array and populate it with a copy of pCell and + ** all cells from node pLeft. Then zero the original node. + */ + aCell = sqlite3_malloc64((sizeof(RtreeCell)+sizeof(int))*(nCell+1)); + if( !aCell ){ + rc = SQLITE_NOMEM; + goto splitnode_out; + } + aiUsed = (int *)&aCell[nCell+1]; + memset(aiUsed, 0, sizeof(int)*(nCell+1)); + for(i=0; iiNode==1 ){ + pRight = nodeNew(pRtree, pNode); + pLeft = nodeNew(pRtree, pNode); + pRtree->iDepth++; + pNode->isDirty = 1; + writeInt16(pNode->zData, pRtree->iDepth); + }else{ + pLeft = pNode; + pRight = nodeNew(pRtree, pLeft->pParent); + pLeft->nRef++; + } + + if( !pLeft || !pRight ){ + rc = SQLITE_NOMEM; + goto splitnode_out; + } + + memset(pLeft->zData, 0, pRtree->iNodeSize); + memset(pRight->zData, 0, pRtree->iNodeSize); + + rc = splitNodeStartree(pRtree, aCell, nCell, pLeft, pRight, + &leftbbox, &rightbbox); + if( rc!=SQLITE_OK ){ + goto splitnode_out; + } + + /* Ensure both child nodes have node numbers assigned to them by calling + ** nodeWrite(). Node pRight always needs a node number, as it was created + ** by nodeNew() above. But node pLeft sometimes already has a node number. + ** In this case avoid the all to nodeWrite(). + */ + if( SQLITE_OK!=(rc = nodeWrite(pRtree, pRight)) + || (0==pLeft->iNode && SQLITE_OK!=(rc = nodeWrite(pRtree, pLeft))) + ){ + goto splitnode_out; + } + + rightbbox.iRowid = pRight->iNode; + leftbbox.iRowid = pLeft->iNode; + + if( pNode->iNode==1 ){ + rc = rtreeInsertCell(pRtree, pLeft->pParent, &leftbbox, iHeight+1); + if( rc!=SQLITE_OK ){ + goto splitnode_out; + } + }else{ + RtreeNode *pParent = pLeft->pParent; + int iCell; + rc = nodeParentIndex(pRtree, pLeft, &iCell); + if( ALWAYS(rc==SQLITE_OK) ){ + nodeOverwriteCell(pRtree, pParent, &leftbbox, iCell); + rc = AdjustTree(pRtree, pParent, &leftbbox); + assert( rc==SQLITE_OK ); + } + if( NEVER(rc!=SQLITE_OK) ){ + goto splitnode_out; + } + } + if( (rc = rtreeInsertCell(pRtree, pRight->pParent, &rightbbox, iHeight+1)) ){ + goto splitnode_out; + } + + for(i=0; iiRowid ){ + newCellIsRight = 1; + } + if( rc!=SQLITE_OK ){ + goto splitnode_out; + } + } + if( pNode->iNode==1 ){ + for(i=0; iiRowid, pLeft, iHeight); + } + +splitnode_out: + nodeRelease(pRtree, pRight); + nodeRelease(pRtree, pLeft); + sqlite3_free(aCell); + return rc; +} + +/* +** If node pLeaf is not the root of the r-tree and its pParent pointer is +** still NULL, load all ancestor nodes of pLeaf into memory and populate +** the pLeaf->pParent chain all the way up to the root node. +** +** This operation is required when a row is deleted (or updated - an update +** is implemented as a delete followed by an insert). SQLite provides the +** rowid of the row to delete, which can be used to find the leaf on which +** the entry resides (argument pLeaf). Once the leaf is located, this +** function is called to determine its ancestry. +*/ +static int fixLeafParent(Rtree *pRtree, RtreeNode *pLeaf){ + int rc = SQLITE_OK; + RtreeNode *pChild = pLeaf; + while( rc==SQLITE_OK && pChild->iNode!=1 && pChild->pParent==0 ){ + int rc2 = SQLITE_OK; /* sqlite3_reset() return code */ + sqlite3_bind_int64(pRtree->pReadParent, 1, pChild->iNode); + rc = sqlite3_step(pRtree->pReadParent); + if( rc==SQLITE_ROW ){ + RtreeNode *pTest; /* Used to test for reference loops */ + i64 iNode; /* Node number of parent node */ + + /* Before setting pChild->pParent, test that we are not creating a + ** loop of references (as we would if, say, pChild==pParent). We don't + ** want to do this as it leads to a memory leak when trying to delete + ** the referenced counted node structures. + */ + iNode = sqlite3_column_int64(pRtree->pReadParent, 0); + for(pTest=pLeaf; pTest && pTest->iNode!=iNode; pTest=pTest->pParent); + if( pTest==0 ){ + rc2 = nodeAcquire(pRtree, iNode, 0, &pChild->pParent); + } + } + rc = sqlite3_reset(pRtree->pReadParent); + if( rc==SQLITE_OK ) rc = rc2; + if( rc==SQLITE_OK && !pChild->pParent ){ + RTREE_IS_CORRUPT(pRtree); + rc = SQLITE_CORRUPT_VTAB; + } + pChild = pChild->pParent; + } + return rc; +} + +static int deleteCell(Rtree *, RtreeNode *, int, int); + +static int removeNode(Rtree *pRtree, RtreeNode *pNode, int iHeight){ + int rc; + int rc2; + RtreeNode *pParent = 0; + int iCell; + + assert( pNode->nRef==1 ); + + /* Remove the entry in the parent cell. */ + rc = nodeParentIndex(pRtree, pNode, &iCell); + if( rc==SQLITE_OK ){ + pParent = pNode->pParent; + pNode->pParent = 0; + rc = deleteCell(pRtree, pParent, iCell, iHeight+1); + testcase( rc!=SQLITE_OK ); + } + rc2 = nodeRelease(pRtree, pParent); + if( rc==SQLITE_OK ){ + rc = rc2; + } + if( rc!=SQLITE_OK ){ + return rc; + } + + /* Remove the xxx_node entry. */ + sqlite3_bind_int64(pRtree->pDeleteNode, 1, pNode->iNode); + sqlite3_step(pRtree->pDeleteNode); + if( SQLITE_OK!=(rc = sqlite3_reset(pRtree->pDeleteNode)) ){ + return rc; + } + + /* Remove the xxx_parent entry. */ + sqlite3_bind_int64(pRtree->pDeleteParent, 1, pNode->iNode); + sqlite3_step(pRtree->pDeleteParent); + if( SQLITE_OK!=(rc = sqlite3_reset(pRtree->pDeleteParent)) ){ + return rc; + } + + /* Remove the node from the in-memory hash table and link it into + ** the Rtree.pDeleted list. Its contents will be re-inserted later on. + */ + nodeHashDelete(pRtree, pNode); + pNode->iNode = iHeight; + pNode->pNext = pRtree->pDeleted; + pNode->nRef++; + pRtree->pDeleted = pNode; + + return SQLITE_OK; +} + +static int fixBoundingBox(Rtree *pRtree, RtreeNode *pNode){ + RtreeNode *pParent = pNode->pParent; + int rc = SQLITE_OK; + if( pParent ){ + int ii; + int nCell = NCELL(pNode); + RtreeCell box; /* Bounding box for pNode */ + nodeGetCell(pRtree, pNode, 0, &box); + for(ii=1; iiiNode; + rc = nodeParentIndex(pRtree, pNode, &ii); + if( rc==SQLITE_OK ){ + nodeOverwriteCell(pRtree, pParent, &box, ii); + rc = fixBoundingBox(pRtree, pParent); + } + } + return rc; +} + +/* +** Delete the cell at index iCell of node pNode. After removing the +** cell, adjust the r-tree data structure if required. +*/ +static int deleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell, int iHeight){ + RtreeNode *pParent; + int rc; + + if( SQLITE_OK!=(rc = fixLeafParent(pRtree, pNode)) ){ + return rc; + } + + /* Remove the cell from the node. This call just moves bytes around + ** the in-memory node image, so it cannot fail. + */ + nodeDeleteCell(pRtree, pNode, iCell); + + /* If the node is not the tree root and now has less than the minimum + ** number of cells, remove it from the tree. Otherwise, update the + ** cell in the parent node so that it tightly contains the updated + ** node. + */ + pParent = pNode->pParent; + assert( pParent || pNode->iNode==1 ); + if( pParent ){ + if( NCELL(pNode)0 ){ + RtreeNode *pChild = nodeHashLookup(pRtree, pCell->iRowid); + if( pChild ){ + nodeRelease(pRtree, pChild->pParent); + nodeReference(pNode); + pChild->pParent = pNode; + } + } + if( nodeInsertCell(pRtree, pNode, pCell) ){ + rc = SplitNode(pRtree, pNode, pCell, iHeight); + }else{ + rc = AdjustTree(pRtree, pNode, pCell); + if( rc==SQLITE_OK ){ + if( iHeight==0 ){ + rc = rowidWrite(pRtree, pCell->iRowid, pNode->iNode); + }else{ + rc = parentWrite(pRtree, pCell->iRowid, pNode->iNode); + } + } + } + return rc; +} + +static int reinsertNodeContent(Rtree *pRtree, RtreeNode *pNode){ + int ii; + int rc = SQLITE_OK; + int nCell = NCELL(pNode); + + for(ii=0; rc==SQLITE_OK && iiiNode currently contains + ** the height of the sub-tree headed by the cell. + */ + rc = ChooseLeaf(pRtree, &cell, (int)pNode->iNode, &pInsert); + if( rc==SQLITE_OK ){ + int rc2; + rc = rtreeInsertCell(pRtree, pInsert, &cell, (int)pNode->iNode); + rc2 = nodeRelease(pRtree, pInsert); + if( rc==SQLITE_OK ){ + rc = rc2; + } + } + } + return rc; +} + +/* +** Select a currently unused rowid for a new r-tree record. +*/ +static int rtreeNewRowid(Rtree *pRtree, i64 *piRowid){ + int rc; + sqlite3_bind_null(pRtree->pWriteRowid, 1); + sqlite3_bind_null(pRtree->pWriteRowid, 2); + sqlite3_step(pRtree->pWriteRowid); + rc = sqlite3_reset(pRtree->pWriteRowid); + *piRowid = sqlite3_last_insert_rowid(pRtree->db); + return rc; +} + +/* +** Remove the entry with rowid=iDelete from the r-tree structure. +*/ +static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){ + int rc; /* Return code */ + RtreeNode *pLeaf = 0; /* Leaf node containing record iDelete */ + int iCell; /* Index of iDelete cell in pLeaf */ + RtreeNode *pRoot = 0; /* Root node of rtree structure */ + + + /* Obtain a reference to the root node to initialize Rtree.iDepth */ + rc = nodeAcquire(pRtree, 1, 0, &pRoot); + + /* Obtain a reference to the leaf node that contains the entry + ** about to be deleted. + */ + if( rc==SQLITE_OK ){ + rc = findLeafNode(pRtree, iDelete, &pLeaf, 0); + } + +#ifdef CORRUPT_DB + assert( pLeaf!=0 || rc!=SQLITE_OK || CORRUPT_DB ); +#endif + + /* Delete the cell in question from the leaf node. */ + if( rc==SQLITE_OK && pLeaf ){ + int rc2; + rc = nodeRowidIndex(pRtree, pLeaf, iDelete, &iCell); + if( rc==SQLITE_OK ){ + rc = deleteCell(pRtree, pLeaf, iCell, 0); + } + rc2 = nodeRelease(pRtree, pLeaf); + if( rc==SQLITE_OK ){ + rc = rc2; + } + } + + /* Delete the corresponding entry in the _rowid table. */ + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pRtree->pDeleteRowid, 1, iDelete); + sqlite3_step(pRtree->pDeleteRowid); + rc = sqlite3_reset(pRtree->pDeleteRowid); + } + + /* Check if the root node now has exactly one child. If so, remove + ** it, schedule the contents of the child for reinsertion and + ** reduce the tree height by one. + ** + ** This is equivalent to copying the contents of the child into + ** the root node (the operation that Gutman's paper says to perform + ** in this scenario). + */ + if( rc==SQLITE_OK && pRtree->iDepth>0 && NCELL(pRoot)==1 ){ + int rc2; + RtreeNode *pChild = 0; + i64 iChild = nodeGetRowid(pRtree, pRoot, 0); + rc = nodeAcquire(pRtree, iChild, pRoot, &pChild); /* tag-20210916a */ + if( rc==SQLITE_OK ){ + rc = removeNode(pRtree, pChild, pRtree->iDepth-1); + } + rc2 = nodeRelease(pRtree, pChild); + if( rc==SQLITE_OK ) rc = rc2; + if( rc==SQLITE_OK ){ + pRtree->iDepth--; + writeInt16(pRoot->zData, pRtree->iDepth); + pRoot->isDirty = 1; + } + } + + /* Re-insert the contents of any underfull nodes removed from the tree. */ + for(pLeaf=pRtree->pDeleted; pLeaf; pLeaf=pRtree->pDeleted){ + if( rc==SQLITE_OK ){ + rc = reinsertNodeContent(pRtree, pLeaf); + } + pRtree->pDeleted = pLeaf->pNext; + pRtree->nNodeRef--; + sqlite3_free(pLeaf); + } + + /* Release the reference to the root node. */ + if( rc==SQLITE_OK ){ + rc = nodeRelease(pRtree, pRoot); + }else{ + nodeRelease(pRtree, pRoot); + } + + return rc; +} + +/* +** Rounding constants for float->double conversion. +*/ +#define RNDTOWARDS (1.0 - 1.0/8388608.0) /* Round towards zero */ +#define RNDAWAY (1.0 + 1.0/8388608.0) /* Round away from zero */ + +#if !defined(SQLITE_RTREE_INT_ONLY) +/* +** Convert an sqlite3_value into an RtreeValue (presumably a float) +** while taking care to round toward negative or positive, respectively. +*/ +static RtreeValue rtreeValueDown(sqlite3_value *v){ + double d = sqlite3_value_double(v); + float f = (float)d; + if( f>d ){ + f = (float)(d*(d<0 ? RNDAWAY : RNDTOWARDS)); + } + return f; +} +static RtreeValue rtreeValueUp(sqlite3_value *v){ + double d = sqlite3_value_double(v); + float f = (float)d; + if( fbase.zErrMsg) to an appropriate value and returns +** SQLITE_CONSTRAINT. +** +** Parameter iCol is the index of the leftmost column involved in the +** constraint failure. If it is 0, then the constraint that failed is +** the unique constraint on the id column. Otherwise, it is the rtree +** (c1<=c2) constraint on columns iCol and iCol+1 that has failed. +** +** If an OOM occurs, SQLITE_NOMEM is returned instead of SQLITE_CONSTRAINT. +*/ +static int rtreeConstraintError(Rtree *pRtree, int iCol){ + sqlite3_stmt *pStmt = 0; + char *zSql; + int rc; + + assert( iCol==0 || iCol%2 ); + zSql = sqlite3_mprintf("SELECT * FROM %Q.%Q", pRtree->zDb, pRtree->zName); + if( zSql ){ + rc = sqlite3_prepare_v2(pRtree->db, zSql, -1, &pStmt, 0); + }else{ + rc = SQLITE_NOMEM; + } + sqlite3_free(zSql); + + if( rc==SQLITE_OK ){ + if( iCol==0 ){ + const char *zCol = sqlite3_column_name(pStmt, 0); + pRtree->base.zErrMsg = sqlite3_mprintf( + "UNIQUE constraint failed: %s.%s", pRtree->zName, zCol + ); + }else{ + const char *zCol1 = sqlite3_column_name(pStmt, iCol); + const char *zCol2 = sqlite3_column_name(pStmt, iCol+1); + pRtree->base.zErrMsg = sqlite3_mprintf( + "rtree constraint failed: %s.(%s<=%s)", pRtree->zName, zCol1, zCol2 + ); + } + } + + sqlite3_finalize(pStmt); + return (rc==SQLITE_OK ? SQLITE_CONSTRAINT : rc); +} + + + +/* +** The xUpdate method for rtree module virtual tables. +*/ +static int rtreeUpdate( + sqlite3_vtab *pVtab, + int nData, + sqlite3_value **aData, + sqlite_int64 *pRowid +){ + Rtree *pRtree = (Rtree *)pVtab; + int rc = SQLITE_OK; + RtreeCell cell; /* New cell to insert if nData>1 */ + int bHaveRowid = 0; /* Set to 1 after new rowid is determined */ + + if( pRtree->nNodeRef ){ + /* Unable to write to the btree while another cursor is reading from it, + ** since the write might do a rebalance which would disrupt the read + ** cursor. */ + return SQLITE_LOCKED_VTAB; + } + rtreeReference(pRtree); + assert(nData>=1); + + memset(&cell, 0, sizeof(cell)); + + /* Constraint handling. A write operation on an r-tree table may return + ** SQLITE_CONSTRAINT for two reasons: + ** + ** 1. A duplicate rowid value, or + ** 2. The supplied data violates the "x2>=x1" constraint. + ** + ** In the first case, if the conflict-handling mode is REPLACE, then + ** the conflicting row can be removed before proceeding. In the second + ** case, SQLITE_CONSTRAINT must be returned regardless of the + ** conflict-handling mode specified by the user. + */ + if( nData>1 ){ + int ii; + int nn = nData - 4; + + if( nn > pRtree->nDim2 ) nn = pRtree->nDim2; + /* Populate the cell.aCoord[] array. The first coordinate is aData[3]. + ** + ** NB: nData can only be less than nDim*2+3 if the rtree is mis-declared + ** with "column" that are interpreted as table constraints. + ** Example: CREATE VIRTUAL TABLE bad USING rtree(x,y,CHECK(y>5)); + ** This problem was discovered after years of use, so we silently ignore + ** these kinds of misdeclared tables to avoid breaking any legacy. + */ + +#ifndef SQLITE_RTREE_INT_ONLY + if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ + for(ii=0; iicell.aCoord[ii+1].f ){ + rc = rtreeConstraintError(pRtree, ii+1); + goto constraint; + } + } + }else +#endif + { + for(ii=0; iicell.aCoord[ii+1].i ){ + rc = rtreeConstraintError(pRtree, ii+1); + goto constraint; + } + } + } + + /* If a rowid value was supplied, check if it is already present in + ** the table. If so, the constraint has failed. */ + if( sqlite3_value_type(aData[2])!=SQLITE_NULL ){ + cell.iRowid = sqlite3_value_int64(aData[2]); + if( sqlite3_value_type(aData[0])==SQLITE_NULL + || sqlite3_value_int64(aData[0])!=cell.iRowid + ){ + int steprc; + sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid); + steprc = sqlite3_step(pRtree->pReadRowid); + rc = sqlite3_reset(pRtree->pReadRowid); + if( SQLITE_ROW==steprc ){ + if( sqlite3_vtab_on_conflict(pRtree->db)==SQLITE_REPLACE ){ + rc = rtreeDeleteRowid(pRtree, cell.iRowid); + }else{ + rc = rtreeConstraintError(pRtree, 0); + goto constraint; + } + } + } + bHaveRowid = 1; + } + } + + /* If aData[0] is not an SQL NULL value, it is the rowid of a + ** record to delete from the r-tree table. The following block does + ** just that. + */ + if( sqlite3_value_type(aData[0])!=SQLITE_NULL ){ + rc = rtreeDeleteRowid(pRtree, sqlite3_value_int64(aData[0])); + } + + /* If the aData[] array contains more than one element, elements + ** (aData[2]..aData[argc-1]) contain a new record to insert into + ** the r-tree structure. + */ + if( rc==SQLITE_OK && nData>1 ){ + /* Insert the new record into the r-tree */ + RtreeNode *pLeaf = 0; + + /* Figure out the rowid of the new row. */ + if( bHaveRowid==0 ){ + rc = rtreeNewRowid(pRtree, &cell.iRowid); + } + *pRowid = cell.iRowid; + + if( rc==SQLITE_OK ){ + rc = ChooseLeaf(pRtree, &cell, 0, &pLeaf); + } + if( rc==SQLITE_OK ){ + int rc2; + rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0); + rc2 = nodeRelease(pRtree, pLeaf); + if( rc==SQLITE_OK ){ + rc = rc2; + } + } + if( rc==SQLITE_OK && pRtree->nAux ){ + sqlite3_stmt *pUp = pRtree->pWriteAux; + int jj; + sqlite3_bind_int64(pUp, 1, *pRowid); + for(jj=0; jjnAux; jj++){ + sqlite3_bind_value(pUp, jj+2, aData[pRtree->nDim2+3+jj]); + } + sqlite3_step(pUp); + rc = sqlite3_reset(pUp); + } + } + +constraint: + rtreeRelease(pRtree); + return rc; +} + +/* +** Called when a transaction starts. +*/ +static int rtreeBeginTransaction(sqlite3_vtab *pVtab){ + Rtree *pRtree = (Rtree *)pVtab; + assert( pRtree->inWrTrans==0 ); + pRtree->inWrTrans = 1; + return SQLITE_OK; +} + +/* +** Called when a transaction completes (either by COMMIT or ROLLBACK). +** The sqlite3_blob object should be released at this point. +*/ +static int rtreeEndTransaction(sqlite3_vtab *pVtab){ + Rtree *pRtree = (Rtree *)pVtab; + pRtree->inWrTrans = 0; + nodeBlobReset(pRtree); + return SQLITE_OK; +} +static int rtreeRollback(sqlite3_vtab *pVtab){ + return rtreeEndTransaction(pVtab); +} + +/* +** The xRename method for rtree module virtual tables. +*/ +static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){ + Rtree *pRtree = (Rtree *)pVtab; + int rc = SQLITE_NOMEM; + char *zSql = sqlite3_mprintf( + "ALTER TABLE %Q.'%q_node' RENAME TO \"%w_node\";" + "ALTER TABLE %Q.'%q_parent' RENAME TO \"%w_parent\";" + "ALTER TABLE %Q.'%q_rowid' RENAME TO \"%w_rowid\";" + , pRtree->zDb, pRtree->zName, zNewName + , pRtree->zDb, pRtree->zName, zNewName + , pRtree->zDb, pRtree->zName, zNewName + ); + if( zSql ){ + nodeBlobReset(pRtree); + rc = sqlite3_exec(pRtree->db, zSql, 0, 0, 0); + sqlite3_free(zSql); + } + return rc; +} + +/* +** The xSavepoint method. +** +** This module does not need to do anything to support savepoints. However, +** it uses this hook to close any open blob handle. This is done because a +** DROP TABLE command - which fortunately always opens a savepoint - cannot +** succeed if there are any open blob handles. i.e. if the blob handle were +** not closed here, the following would fail: +** +** BEGIN; +** INSERT INTO rtree... +** DROP TABLE ; -- Would fail with SQLITE_LOCKED +** COMMIT; +*/ +static int rtreeSavepoint(sqlite3_vtab *pVtab, int iSavepoint){ + Rtree *pRtree = (Rtree *)pVtab; + u8 iwt = pRtree->inWrTrans; + UNUSED_PARAMETER(iSavepoint); + pRtree->inWrTrans = 0; + nodeBlobReset(pRtree); + pRtree->inWrTrans = iwt; + return SQLITE_OK; +} + +/* +** This function populates the pRtree->nRowEst variable with an estimate +** of the number of rows in the virtual table. If possible, this is based +** on sqlite_stat1 data. Otherwise, use RTREE_DEFAULT_ROWEST. +*/ +static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){ + const char *zFmt = "SELECT stat FROM %Q.sqlite_stat1 WHERE tbl = '%q_rowid'"; + char *zSql; + sqlite3_stmt *p; + int rc; + i64 nRow = RTREE_MIN_ROWEST; + + rc = sqlite3_table_column_metadata( + db, pRtree->zDb, "sqlite_stat1",0,0,0,0,0,0 + ); + if( rc!=SQLITE_OK ){ + pRtree->nRowEst = RTREE_DEFAULT_ROWEST; + return rc==SQLITE_ERROR ? SQLITE_OK : rc; + } + zSql = sqlite3_mprintf(zFmt, pRtree->zDb, pRtree->zName); + if( zSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare_v2(db, zSql, -1, &p, 0); + if( rc==SQLITE_OK ){ + if( sqlite3_step(p)==SQLITE_ROW ) nRow = sqlite3_column_int64(p, 0); + rc = sqlite3_finalize(p); + } + sqlite3_free(zSql); + } + pRtree->nRowEst = MAX(nRow, RTREE_MIN_ROWEST); + return rc; +} + + +/* +** Return true if zName is the extension on one of the shadow tables used +** by this module. +*/ +static int rtreeShadowName(const char *zName){ + static const char *azName[] = { + "node", "parent", "rowid" + }; + unsigned int i; + for(i=0; idb = db; + + if( isCreate ){ + char *zCreate; + sqlite3_str *p = sqlite3_str_new(db); + int ii; + sqlite3_str_appendf(p, + "CREATE TABLE \"%w\".\"%w_rowid\"(rowid INTEGER PRIMARY KEY,nodeno", + zDb, zPrefix); + for(ii=0; iinAux; ii++){ + sqlite3_str_appendf(p,",a%d",ii); + } + sqlite3_str_appendf(p, + ");CREATE TABLE \"%w\".\"%w_node\"(nodeno INTEGER PRIMARY KEY,data);", + zDb, zPrefix); + sqlite3_str_appendf(p, + "CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY,parentnode);", + zDb, zPrefix); + sqlite3_str_appendf(p, + "INSERT INTO \"%w\".\"%w_node\"VALUES(1,zeroblob(%d))", + zDb, zPrefix, pRtree->iNodeSize); + zCreate = sqlite3_str_finish(p); + if( !zCreate ){ + return SQLITE_NOMEM; + } + rc = sqlite3_exec(db, zCreate, 0, 0, 0); + sqlite3_free(zCreate); + if( rc!=SQLITE_OK ){ + return rc; + } + } + + appStmt[0] = &pRtree->pWriteNode; + appStmt[1] = &pRtree->pDeleteNode; + appStmt[2] = &pRtree->pReadRowid; + appStmt[3] = &pRtree->pWriteRowid; + appStmt[4] = &pRtree->pDeleteRowid; + appStmt[5] = &pRtree->pReadParent; + appStmt[6] = &pRtree->pWriteParent; + appStmt[7] = &pRtree->pDeleteParent; + + rc = rtreeQueryStat1(db, pRtree); + for(i=0; inAux==0 ){ + zFormat = azSql[i]; + }else { + /* An UPSERT is very slightly slower than REPLACE, but it is needed + ** if there are auxiliary columns */ + zFormat = "INSERT INTO\"%w\".\"%w_rowid\"(rowid,nodeno)VALUES(?1,?2)" + "ON CONFLICT(rowid)DO UPDATE SET nodeno=excluded.nodeno"; + } + zSql = sqlite3_mprintf(zFormat, zDb, zPrefix); + if( zSql ){ + rc = sqlite3_prepare_v3(db, zSql, -1, f, appStmt[i], 0); + }else{ + rc = SQLITE_NOMEM; + } + sqlite3_free(zSql); + } + if( pRtree->nAux && rc!=SQLITE_NOMEM ){ + pRtree->zReadAuxSql = sqlite3_mprintf( + "SELECT * FROM \"%w\".\"%w_rowid\" WHERE rowid=?1", + zDb, zPrefix); + if( pRtree->zReadAuxSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + sqlite3_str *p = sqlite3_str_new(db); + int ii; + char *zSql; + sqlite3_str_appendf(p, "UPDATE \"%w\".\"%w_rowid\"SET ", zDb, zPrefix); + for(ii=0; iinAux; ii++){ + if( ii ) sqlite3_str_append(p, ",", 1); +#ifdef SQLITE_ENABLE_GEOPOLY + if( iinAuxNotNull ){ + sqlite3_str_appendf(p,"a%d=coalesce(?%d,a%d)",ii,ii+2,ii); + }else +#endif + { + sqlite3_str_appendf(p,"a%d=?%d",ii,ii+2); + } + } + sqlite3_str_appendf(p, " WHERE rowid=?1"); + zSql = sqlite3_str_finish(p); + if( zSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare_v3(db, zSql, -1, f, &pRtree->pWriteAux, 0); + sqlite3_free(zSql); + } + } + } + + return rc; +} + +/* +** The second argument to this function contains the text of an SQL statement +** that returns a single integer value. The statement is compiled and executed +** using database connection db. If successful, the integer value returned +** is written to *piVal and SQLITE_OK returned. Otherwise, an SQLite error +** code is returned and the value of *piVal after returning is not defined. +*/ +static int getIntFromStmt(sqlite3 *db, const char *zSql, int *piVal){ + int rc = SQLITE_NOMEM; + if( zSql ){ + sqlite3_stmt *pStmt = 0; + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + if( rc==SQLITE_OK ){ + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + *piVal = sqlite3_column_int(pStmt, 0); + } + rc = sqlite3_finalize(pStmt); + } + } + return rc; +} + +/* +** This function is called from within the xConnect() or xCreate() method to +** determine the node-size used by the rtree table being created or connected +** to. If successful, pRtree->iNodeSize is populated and SQLITE_OK returned. +** Otherwise, an SQLite error code is returned. +** +** If this function is being called as part of an xConnect(), then the rtree +** table already exists. In this case the node-size is determined by inspecting +** the root node of the tree. +** +** Otherwise, for an xCreate(), use 64 bytes less than the database page-size. +** This ensures that each node is stored on a single database page. If the +** database page-size is so large that more than RTREE_MAXCELLS entries +** would fit in a single node, use a smaller node-size. +*/ +static int getNodeSize( + sqlite3 *db, /* Database handle */ + Rtree *pRtree, /* Rtree handle */ + int isCreate, /* True for xCreate, false for xConnect */ + char **pzErr /* OUT: Error message, if any */ +){ + int rc; + char *zSql; + if( isCreate ){ + int iPageSize = 0; + zSql = sqlite3_mprintf("PRAGMA %Q.page_size", pRtree->zDb); + rc = getIntFromStmt(db, zSql, &iPageSize); + if( rc==SQLITE_OK ){ + pRtree->iNodeSize = iPageSize-64; + if( (4+pRtree->nBytesPerCell*RTREE_MAXCELLS)iNodeSize ){ + pRtree->iNodeSize = 4+pRtree->nBytesPerCell*RTREE_MAXCELLS; + } + }else{ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + } + }else{ + zSql = sqlite3_mprintf( + "SELECT length(data) FROM '%q'.'%q_node' WHERE nodeno = 1", + pRtree->zDb, pRtree->zName + ); + rc = getIntFromStmt(db, zSql, &pRtree->iNodeSize); + if( rc!=SQLITE_OK ){ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + }else if( pRtree->iNodeSize<(512-64) ){ + rc = SQLITE_CORRUPT_VTAB; + RTREE_IS_CORRUPT(pRtree); + *pzErr = sqlite3_mprintf("undersize RTree blobs in \"%q_node\"", + pRtree->zName); + } + } + + sqlite3_free(zSql); + return rc; +} + +/* +** Return the length of a token +*/ +static int rtreeTokenLength(const char *z){ + int dummy = 0; + return sqlite3GetToken((const unsigned char*)z,&dummy); +} + +/* +** This function is the implementation of both the xConnect and xCreate +** methods of the r-tree virtual table. +** +** argv[0] -> module name +** argv[1] -> database name +** argv[2] -> table name +** argv[...] -> column names... +*/ +static int rtreeInit( + sqlite3 *db, /* Database connection */ + void *pAux, /* One of the RTREE_COORD_* constants */ + int argc, const char *const*argv, /* Parameters to CREATE TABLE statement */ + sqlite3_vtab **ppVtab, /* OUT: New virtual table */ + char **pzErr, /* OUT: Error message, if any */ + int isCreate /* True for xCreate, false for xConnect */ +){ + int rc = SQLITE_OK; + Rtree *pRtree; + int nDb; /* Length of string argv[1] */ + int nName; /* Length of string argv[2] */ + int eCoordType = (pAux ? RTREE_COORD_INT32 : RTREE_COORD_REAL32); + sqlite3_str *pSql; + char *zSql; + int ii = 4; + int iErr; + + const char *aErrMsg[] = { + 0, /* 0 */ + "Wrong number of columns for an rtree table", /* 1 */ + "Too few columns for an rtree table", /* 2 */ + "Too many columns for an rtree table", /* 3 */ + "Auxiliary rtree columns must be last" /* 4 */ + }; + + assert( RTREE_MAX_AUX_COLUMN<256 ); + if( argc<6 || argc>RTREE_MAX_AUX_COLUMN+3 ){ + *pzErr = sqlite3_mprintf("%s", aErrMsg[2 + (argc>=6)]); + return SQLITE_ERROR; + } + + sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); + sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); + + + /* Allocate the sqlite3_vtab structure */ + nDb = (int)strlen(argv[1]); + nName = (int)strlen(argv[2]); + pRtree = (Rtree *)sqlite3_malloc64(sizeof(Rtree)+nDb+nName*2+8); + if( !pRtree ){ + return SQLITE_NOMEM; + } + memset(pRtree, 0, sizeof(Rtree)+nDb+nName*2+8); + pRtree->nBusy = 1; + pRtree->base.pModule = &rtreeModule; + pRtree->zDb = (char *)&pRtree[1]; + pRtree->zName = &pRtree->zDb[nDb+1]; + pRtree->zNodeName = &pRtree->zName[nName+1]; + pRtree->eCoordType = (u8)eCoordType; + memcpy(pRtree->zDb, argv[1], nDb); + memcpy(pRtree->zName, argv[2], nName); + memcpy(pRtree->zNodeName, argv[2], nName); + memcpy(&pRtree->zNodeName[nName], "_node", 6); + + + /* Create/Connect to the underlying relational database schema. If + ** that is successful, call sqlite3_declare_vtab() to configure + ** the r-tree table schema. + */ + pSql = sqlite3_str_new(db); + sqlite3_str_appendf(pSql, "CREATE TABLE x(%.*s INT", + rtreeTokenLength(argv[3]), argv[3]); + for(ii=4; iinAux++; + sqlite3_str_appendf(pSql, ",%.*s", rtreeTokenLength(zArg+1), zArg+1); + }else if( pRtree->nAux>0 ){ + break; + }else{ + static const char *azFormat[] = {",%.*s REAL", ",%.*s INT"}; + pRtree->nDim2++; + sqlite3_str_appendf(pSql, azFormat[eCoordType], + rtreeTokenLength(zArg), zArg); + } + } + sqlite3_str_appendf(pSql, ");"); + zSql = sqlite3_str_finish(pSql); + if( !zSql ){ + rc = SQLITE_NOMEM; + }else if( iinDim = pRtree->nDim2/2; + if( pRtree->nDim<1 ){ + iErr = 2; + }else if( pRtree->nDim2>RTREE_MAX_DIMENSIONS*2 ){ + iErr = 3; + }else if( pRtree->nDim2 % 2 ){ + iErr = 1; + }else{ + iErr = 0; + } + if( iErr ){ + *pzErr = sqlite3_mprintf("%s", aErrMsg[iErr]); + goto rtreeInit_fail; + } + pRtree->nBytesPerCell = 8 + pRtree->nDim2*4; + + /* Figure out the node size to use. */ + rc = getNodeSize(db, pRtree, isCreate, pzErr); + if( rc ) goto rtreeInit_fail; + rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate); + if( rc ){ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + goto rtreeInit_fail; + } + + *ppVtab = (sqlite3_vtab *)pRtree; + return SQLITE_OK; + +rtreeInit_fail: + if( rc==SQLITE_OK ) rc = SQLITE_ERROR; + assert( *ppVtab==0 ); + assert( pRtree->nBusy==1 ); + rtreeRelease(pRtree); + return rc; +} + + +/* +** Implementation of a scalar function that decodes r-tree nodes to +** human readable strings. This can be used for debugging and analysis. +** +** The scalar function takes two arguments: (1) the number of dimensions +** to the rtree (between 1 and 5, inclusive) and (2) a blob of data containing +** an r-tree node. For a two-dimensional r-tree structure called "rt", to +** deserialize all nodes, a statement like: +** +** SELECT rtreenode(2, data) FROM rt_node; +** +** The human readable string takes the form of a Tcl list with one +** entry for each cell in the r-tree node. Each entry is itself a +** list, containing the 8-byte rowid/pageno followed by the +** *2 coordinates. +*/ +static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ + RtreeNode node; + Rtree tree; + int ii; + int nData; + int errCode; + sqlite3_str *pOut; + + UNUSED_PARAMETER(nArg); + memset(&node, 0, sizeof(RtreeNode)); + memset(&tree, 0, sizeof(Rtree)); + tree.nDim = (u8)sqlite3_value_int(apArg[0]); + if( tree.nDim<1 || tree.nDim>5 ) return; + tree.nDim2 = tree.nDim*2; + tree.nBytesPerCell = 8 + 8 * tree.nDim; + node.zData = (u8 *)sqlite3_value_blob(apArg[1]); + if( node.zData==0 ) return; + nData = sqlite3_value_bytes(apArg[1]); + if( nData<4 ) return; + if( nData<4+NCELL(&node)*tree.nBytesPerCell ) return; + + pOut = sqlite3_str_new(0); + for(ii=0; ii0 ) sqlite3_str_append(pOut, " ", 1); + sqlite3_str_appendf(pOut, "{%lld", cell.iRowid); + for(jj=0; jjrc==SQLITE_OK ) pCheck->rc = rc; +} + +/* +** The second and subsequent arguments to this function are a format string +** and printf style arguments. This function formats the string and attempts +** to compile it as an SQL statement. +** +** If successful, a pointer to the new SQL statement is returned. Otherwise, +** NULL is returned and an error code left in RtreeCheck.rc. +*/ +static sqlite3_stmt *rtreeCheckPrepare( + RtreeCheck *pCheck, /* RtreeCheck object */ + const char *zFmt, ... /* Format string and trailing args */ +){ + va_list ap; + char *z; + sqlite3_stmt *pRet = 0; + + va_start(ap, zFmt); + z = sqlite3_vmprintf(zFmt, ap); + + if( pCheck->rc==SQLITE_OK ){ + if( z==0 ){ + pCheck->rc = SQLITE_NOMEM; + }else{ + pCheck->rc = sqlite3_prepare_v2(pCheck->db, z, -1, &pRet, 0); + } + } + + sqlite3_free(z); + va_end(ap); + return pRet; +} + +/* +** The second and subsequent arguments to this function are a printf() +** style format string and arguments. This function formats the string and +** appends it to the report being accumulated in pCheck. +*/ +static void rtreeCheckAppendMsg(RtreeCheck *pCheck, const char *zFmt, ...){ + va_list ap; + va_start(ap, zFmt); + if( pCheck->rc==SQLITE_OK && pCheck->nErrrc = SQLITE_NOMEM; + }else{ + pCheck->zReport = sqlite3_mprintf("%z%s%z", + pCheck->zReport, (pCheck->zReport ? "\n" : ""), z + ); + if( pCheck->zReport==0 ){ + pCheck->rc = SQLITE_NOMEM; + } + } + pCheck->nErr++; + } + va_end(ap); +} + +/* +** This function is a no-op if there is already an error code stored +** in the RtreeCheck object indicated by the first argument. NULL is +** returned in this case. +** +** Otherwise, the contents of rtree table node iNode are loaded from +** the database and copied into a buffer obtained from sqlite3_malloc(). +** If no error occurs, a pointer to the buffer is returned and (*pnNode) +** is set to the size of the buffer in bytes. +** +** Or, if an error does occur, NULL is returned and an error code left +** in the RtreeCheck object. The final value of *pnNode is undefined in +** this case. +*/ +static u8 *rtreeCheckGetNode(RtreeCheck *pCheck, i64 iNode, int *pnNode){ + u8 *pRet = 0; /* Return value */ + + if( pCheck->rc==SQLITE_OK && pCheck->pGetNode==0 ){ + pCheck->pGetNode = rtreeCheckPrepare(pCheck, + "SELECT data FROM %Q.'%q_node' WHERE nodeno=?", + pCheck->zDb, pCheck->zTab + ); + } + + if( pCheck->rc==SQLITE_OK ){ + sqlite3_bind_int64(pCheck->pGetNode, 1, iNode); + if( sqlite3_step(pCheck->pGetNode)==SQLITE_ROW ){ + int nNode = sqlite3_column_bytes(pCheck->pGetNode, 0); + const u8 *pNode = (const u8*)sqlite3_column_blob(pCheck->pGetNode, 0); + pRet = sqlite3_malloc64(nNode); + if( pRet==0 ){ + pCheck->rc = SQLITE_NOMEM; + }else{ + memcpy(pRet, pNode, nNode); + *pnNode = nNode; + } + } + rtreeCheckReset(pCheck, pCheck->pGetNode); + if( pCheck->rc==SQLITE_OK && pRet==0 ){ + rtreeCheckAppendMsg(pCheck, "Node %lld missing from database", iNode); + } + } + + return pRet; +} + +/* +** This function is used to check that the %_parent (if bLeaf==0) or %_rowid +** (if bLeaf==1) table contains a specified entry. The schemas of the +** two tables are: +** +** CREATE TABLE %_parent(nodeno INTEGER PRIMARY KEY, parentnode INTEGER) +** CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER, ...) +** +** In both cases, this function checks that there exists an entry with +** IPK value iKey and the second column set to iVal. +** +*/ +static void rtreeCheckMapping( + RtreeCheck *pCheck, /* RtreeCheck object */ + int bLeaf, /* True for a leaf cell, false for interior */ + i64 iKey, /* Key for mapping */ + i64 iVal /* Expected value for mapping */ +){ + int rc; + sqlite3_stmt *pStmt; + const char *azSql[2] = { + "SELECT parentnode FROM %Q.'%q_parent' WHERE nodeno=?1", + "SELECT nodeno FROM %Q.'%q_rowid' WHERE rowid=?1" + }; + + assert( bLeaf==0 || bLeaf==1 ); + if( pCheck->aCheckMapping[bLeaf]==0 ){ + pCheck->aCheckMapping[bLeaf] = rtreeCheckPrepare(pCheck, + azSql[bLeaf], pCheck->zDb, pCheck->zTab + ); + } + if( pCheck->rc!=SQLITE_OK ) return; + + pStmt = pCheck->aCheckMapping[bLeaf]; + sqlite3_bind_int64(pStmt, 1, iKey); + rc = sqlite3_step(pStmt); + if( rc==SQLITE_DONE ){ + rtreeCheckAppendMsg(pCheck, "Mapping (%lld -> %lld) missing from %s table", + iKey, iVal, (bLeaf ? "%_rowid" : "%_parent") + ); + }else if( rc==SQLITE_ROW ){ + i64 ii = sqlite3_column_int64(pStmt, 0); + if( ii!=iVal ){ + rtreeCheckAppendMsg(pCheck, + "Found (%lld -> %lld) in %s table, expected (%lld -> %lld)", + iKey, ii, (bLeaf ? "%_rowid" : "%_parent"), iKey, iVal + ); + } + } + rtreeCheckReset(pCheck, pStmt); +} + +/* +** Argument pCell points to an array of coordinates stored on an rtree page. +** This function checks that the coordinates are internally consistent (no +** x1>x2 conditions) and adds an error message to the RtreeCheck object +** if they are not. +** +** Additionally, if pParent is not NULL, then it is assumed to point to +** the array of coordinates on the parent page that bound the page +** containing pCell. In this case it is also verified that the two +** sets of coordinates are mutually consistent and an error message added +** to the RtreeCheck object if they are not. +*/ +static void rtreeCheckCellCoord( + RtreeCheck *pCheck, + i64 iNode, /* Node id to use in error messages */ + int iCell, /* Cell number to use in error messages */ + u8 *pCell, /* Pointer to cell coordinates */ + u8 *pParent /* Pointer to parent coordinates */ +){ + RtreeCoord c1, c2; + RtreeCoord p1, p2; + int i; + + for(i=0; inDim; i++){ + readCoord(&pCell[4*2*i], &c1); + readCoord(&pCell[4*(2*i + 1)], &c2); + + /* printf("%e, %e\n", c1.u.f, c2.u.f); */ + if( pCheck->bInt ? c1.i>c2.i : c1.f>c2.f ){ + rtreeCheckAppendMsg(pCheck, + "Dimension %d of cell %d on node %lld is corrupt", i, iCell, iNode + ); + } + + if( pParent ){ + readCoord(&pParent[4*2*i], &p1); + readCoord(&pParent[4*(2*i + 1)], &p2); + + if( (pCheck->bInt ? c1.ibInt ? c2.i>p2.i : c2.f>p2.f) + ){ + rtreeCheckAppendMsg(pCheck, + "Dimension %d of cell %d on node %lld is corrupt relative to parent" + , i, iCell, iNode + ); + } + } + } +} + +/* +** Run rtreecheck() checks on node iNode, which is at depth iDepth within +** the r-tree structure. Argument aParent points to the array of coordinates +** that bound node iNode on the parent node. +** +** If any problems are discovered, an error message is appended to the +** report accumulated in the RtreeCheck object. +*/ +static void rtreeCheckNode( + RtreeCheck *pCheck, + int iDepth, /* Depth of iNode (0==leaf) */ + u8 *aParent, /* Buffer containing parent coords */ + i64 iNode /* Node to check */ +){ + u8 *aNode = 0; + int nNode = 0; + + assert( iNode==1 || aParent!=0 ); + assert( pCheck->nDim>0 ); + + aNode = rtreeCheckGetNode(pCheck, iNode, &nNode); + if( aNode ){ + if( nNode<4 ){ + rtreeCheckAppendMsg(pCheck, + "Node %lld is too small (%d bytes)", iNode, nNode + ); + }else{ + int nCell; /* Number of cells on page */ + int i; /* Used to iterate through cells */ + if( aParent==0 ){ + iDepth = readInt16(aNode); + if( iDepth>RTREE_MAX_DEPTH ){ + rtreeCheckAppendMsg(pCheck, "Rtree depth out of range (%d)", iDepth); + sqlite3_free(aNode); + return; + } + } + nCell = readInt16(&aNode[2]); + if( (4 + nCell*(8 + pCheck->nDim*2*4))>nNode ){ + rtreeCheckAppendMsg(pCheck, + "Node %lld is too small for cell count of %d (%d bytes)", + iNode, nCell, nNode + ); + }else{ + for(i=0; inDim*2*4)]; + i64 iVal = readInt64(pCell); + rtreeCheckCellCoord(pCheck, iNode, i, &pCell[8], aParent); + + if( iDepth>0 ){ + rtreeCheckMapping(pCheck, 0, iVal, iNode); + rtreeCheckNode(pCheck, iDepth-1, &pCell[8], iVal); + pCheck->nNonLeaf++; + }else{ + rtreeCheckMapping(pCheck, 1, iVal, iNode); + pCheck->nLeaf++; + } + } + } + } + sqlite3_free(aNode); + } +} + +/* +** The second argument to this function must be either "_rowid" or +** "_parent". This function checks that the number of entries in the +** %_rowid or %_parent table is exactly nExpect. If not, it adds +** an error message to the report in the RtreeCheck object indicated +** by the first argument. +*/ +static void rtreeCheckCount(RtreeCheck *pCheck, const char *zTbl, i64 nExpect){ + if( pCheck->rc==SQLITE_OK ){ + sqlite3_stmt *pCount; + pCount = rtreeCheckPrepare(pCheck, "SELECT count(*) FROM %Q.'%q%s'", + pCheck->zDb, pCheck->zTab, zTbl + ); + if( pCount ){ + if( sqlite3_step(pCount)==SQLITE_ROW ){ + i64 nActual = sqlite3_column_int64(pCount, 0); + if( nActual!=nExpect ){ + rtreeCheckAppendMsg(pCheck, "Wrong number of entries in %%%s table" + " - expected %lld, actual %lld" , zTbl, nExpect, nActual + ); + } + } + pCheck->rc = sqlite3_finalize(pCount); + } + } +} + +/* +** This function does the bulk of the work for the rtree integrity-check. +** It is called by rtreecheck(), which is the SQL function implementation. +*/ +static int rtreeCheckTable( + sqlite3 *db, /* Database handle to access db through */ + const char *zDb, /* Name of db ("main", "temp" etc.) */ + const char *zTab, /* Name of rtree table to check */ + char **pzReport /* OUT: sqlite3_malloc'd report text */ +){ + RtreeCheck check; /* Common context for various routines */ + sqlite3_stmt *pStmt = 0; /* Used to find column count of rtree table */ + int nAux = 0; /* Number of extra columns. */ + + /* Initialize the context object */ + memset(&check, 0, sizeof(check)); + check.db = db; + check.zDb = zDb; + check.zTab = zTab; + + /* Find the number of auxiliary columns */ + pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.'%q_rowid'", zDb, zTab); + if( pStmt ){ + nAux = sqlite3_column_count(pStmt) - 2; + sqlite3_finalize(pStmt); + }else + if( check.rc!=SQLITE_NOMEM ){ + check.rc = SQLITE_OK; + } + + /* Find number of dimensions in the rtree table. */ + pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.%Q", zDb, zTab); + if( pStmt ){ + int rc; + check.nDim = (sqlite3_column_count(pStmt) - 1 - nAux) / 2; + if( check.nDim<1 ){ + rtreeCheckAppendMsg(&check, "Schema corrupt or not an rtree"); + }else if( SQLITE_ROW==sqlite3_step(pStmt) ){ + check.bInt = (sqlite3_column_type(pStmt, 1)==SQLITE_INTEGER); + } + rc = sqlite3_finalize(pStmt); + if( rc!=SQLITE_CORRUPT ) check.rc = rc; + } + + /* Do the actual integrity-check */ + if( check.nDim>=1 ){ + if( check.rc==SQLITE_OK ){ + rtreeCheckNode(&check, 0, 0, 1); + } + rtreeCheckCount(&check, "_rowid", check.nLeaf); + rtreeCheckCount(&check, "_parent", check.nNonLeaf); + } + + /* Finalize SQL statements used by the integrity-check */ + sqlite3_finalize(check.pGetNode); + sqlite3_finalize(check.aCheckMapping[0]); + sqlite3_finalize(check.aCheckMapping[1]); + + *pzReport = check.zReport; + return check.rc; +} + +/* +** Implementation of the xIntegrity method for Rtree. +*/ +static int rtreeIntegrity( + sqlite3_vtab *pVtab, /* The virtual table to check */ + const char *zSchema, /* Schema in which the virtual table lives */ + const char *zName, /* Name of the virtual table */ + int isQuick, /* True for a quick_check */ + char **pzErr /* Write results here */ +){ + Rtree *pRtree = (Rtree*)pVtab; + int rc; + assert( pzErr!=0 && *pzErr==0 ); + UNUSED_PARAMETER(zSchema); + UNUSED_PARAMETER(zName); + UNUSED_PARAMETER(isQuick); + rc = rtreeCheckTable(pRtree->db, pRtree->zDb, pRtree->zName, pzErr); + if( rc==SQLITE_OK && *pzErr ){ + *pzErr = sqlite3_mprintf("In RTree %s.%s:\n%z", + pRtree->zDb, pRtree->zName, *pzErr); + if( (*pzErr)==0 ) rc = SQLITE_NOMEM; + } + return rc; +} + +/* +** Usage: +** +** rtreecheck(); +** rtreecheck(, ); +** +** Invoking this SQL function runs an integrity-check on the named rtree +** table. The integrity-check verifies the following: +** +** 1. For each cell in the r-tree structure (%_node table), that: +** +** a) for each dimension, (coord1 <= coord2). +** +** b) unless the cell is on the root node, that the cell is bounded +** by the parent cell on the parent node. +** +** c) for leaf nodes, that there is an entry in the %_rowid +** table corresponding to the cell's rowid value that +** points to the correct node. +** +** d) for cells on non-leaf nodes, that there is an entry in the +** %_parent table mapping from the cell's child node to the +** node that it resides on. +** +** 2. That there are the same number of entries in the %_rowid table +** as there are leaf cells in the r-tree structure, and that there +** is a leaf cell that corresponds to each entry in the %_rowid table. +** +** 3. That there are the same number of entries in the %_parent table +** as there are non-leaf cells in the r-tree structure, and that +** there is a non-leaf cell that corresponds to each entry in the +** %_parent table. +*/ +static void rtreecheck( + sqlite3_context *ctx, + int nArg, + sqlite3_value **apArg +){ + if( nArg!=1 && nArg!=2 ){ + sqlite3_result_error(ctx, + "wrong number of arguments to function rtreecheck()", -1 + ); + }else{ + int rc; + char *zReport = 0; + const char *zDb = (const char*)sqlite3_value_text(apArg[0]); + const char *zTab; + if( nArg==1 ){ + zTab = zDb; + zDb = "main"; + }else{ + zTab = (const char*)sqlite3_value_text(apArg[1]); + } + rc = rtreeCheckTable(sqlite3_context_db_handle(ctx), zDb, zTab, &zReport); + if( rc==SQLITE_OK ){ + sqlite3_result_text(ctx, zReport ? zReport : "ok", -1, SQLITE_TRANSIENT); + }else{ + sqlite3_result_error_code(ctx, rc); + } + sqlite3_free(zReport); + } +} + +/* Conditionally include the geopoly code */ +#ifdef SQLITE_ENABLE_GEOPOLY +/************** Include geopoly.c in the middle of rtree.c *******************/ +/************** Begin file geopoly.c *****************************************/ +/* +** 2018-05-25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file implements an alternative R-Tree virtual table that +** uses polygons to express the boundaries of 2-dimensional objects. +** +** This file is #include-ed onto the end of "rtree.c" so that it has +** access to all of the R-Tree internals. +*/ +/* #include */ + +/* Enable -DGEOPOLY_ENABLE_DEBUG for debugging facilities */ +#ifdef GEOPOLY_ENABLE_DEBUG + static int geo_debug = 0; +# define GEODEBUG(X) if(geo_debug)printf X +#else +# define GEODEBUG(X) +#endif + +/* Character class routines */ +#ifdef sqlite3Isdigit + /* Use the SQLite core versions if this routine is part of the + ** SQLite amalgamation */ +# define safe_isdigit(x) sqlite3Isdigit(x) +# define safe_isalnum(x) sqlite3Isalnum(x) +# define safe_isxdigit(x) sqlite3Isxdigit(x) +#else + /* Use the standard library for separate compilation */ +#include /* amalgamator: keep */ +# define safe_isdigit(x) isdigit((unsigned char)(x)) +# define safe_isalnum(x) isalnum((unsigned char)(x)) +# define safe_isxdigit(x) isxdigit((unsigned char)(x)) +#endif + +#ifndef JSON_NULL /* The following stuff repeats things found in json1 */ +/* +** Growing our own isspace() routine this way is twice as fast as +** the library isspace() function. +*/ +static const char geopolyIsSpace[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 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, + 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, 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, 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, +}; +#define fast_isspace(x) (geopolyIsSpace[(unsigned char)x]) +#endif /* JSON NULL - back to original code */ + +/* Compiler and version */ +#ifndef GCC_VERSION +#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC) +# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__) +#else +# define GCC_VERSION 0 +#endif +#endif +#ifndef MSVC_VERSION +#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC) +# define MSVC_VERSION _MSC_VER +#else +# define MSVC_VERSION 0 +#endif +#endif + +/* Datatype for coordinates +*/ +typedef float GeoCoord; + +/* +** Internal representation of a polygon. +** +** The polygon consists of a sequence of vertexes. There is a line +** segment between each pair of vertexes, and one final segment from +** the last vertex back to the first. (This differs from the GeoJSON +** standard in which the final vertex is a repeat of the first.) +** +** The polygon follows the right-hand rule. The area to the right of +** each segment is "outside" and the area to the left is "inside". +** +** The on-disk representation consists of a 4-byte header followed by +** the values. The 4-byte header is: +** +** encoding (1 byte) 0=big-endian, 1=little-endian +** nvertex (3 bytes) Number of vertexes as a big-endian integer +** +** Enough space is allocated for 4 coordinates, to work around over-zealous +** warnings coming from some compiler (notably, clang). In reality, the size +** of each GeoPoly memory allocate is adjusted as necessary so that the +** GeoPoly.a[] array at the end is the appropriate size. +*/ +typedef struct GeoPoly GeoPoly; +struct GeoPoly { + int nVertex; /* Number of vertexes */ + unsigned char hdr[4]; /* Header for on-disk representation */ + GeoCoord a[8]; /* 2*nVertex values. X (longitude) first, then Y */ +}; + +/* The size of a memory allocation needed for a GeoPoly object sufficient +** to hold N coordinate pairs. +*/ +#define GEOPOLY_SZ(N) (sizeof(GeoPoly) + sizeof(GeoCoord)*2*((N)-4)) + +/* Macros to access coordinates of a GeoPoly. +** We have to use these macros, rather than just say p->a[i] in order +** to silence (incorrect) UBSAN warnings if the array index is too large. +*/ +#define GeoX(P,I) (((GeoCoord*)(P)->a)[(I)*2]) +#define GeoY(P,I) (((GeoCoord*)(P)->a)[(I)*2+1]) + + +/* +** State of a parse of a GeoJSON input. +*/ +typedef struct GeoParse GeoParse; +struct GeoParse { + const unsigned char *z; /* Unparsed input */ + int nVertex; /* Number of vertexes in a[] */ + int nAlloc; /* Space allocated to a[] */ + int nErr; /* Number of errors encountered */ + GeoCoord *a; /* Array of vertexes. From sqlite3_malloc64() */ +}; + +/* Do a 4-byte byte swap */ +static void geopolySwab32(unsigned char *a){ + unsigned char t = a[0]; + a[0] = a[3]; + a[3] = t; + t = a[1]; + a[1] = a[2]; + a[2] = t; +} + +/* Skip whitespace. Return the next non-whitespace character. */ +static char geopolySkipSpace(GeoParse *p){ + while( fast_isspace(p->z[0]) ) p->z++; + return p->z[0]; +} + +/* Parse out a number. Write the value into *pVal if pVal!=0. +** return non-zero on success and zero if the next token is not a number. +*/ +static int geopolyParseNumber(GeoParse *p, GeoCoord *pVal){ + char c = geopolySkipSpace(p); + const unsigned char *z = p->z; + int j = 0; + int seenDP = 0; + int seenE = 0; + if( c=='-' ){ + j = 1; + c = z[j]; + } + if( c=='0' && z[j+1]>='0' && z[j+1]<='9' ) return 0; + for(;; j++){ + c = z[j]; + if( safe_isdigit(c) ) continue; + if( c=='.' ){ + if( z[j-1]=='-' ) return 0; + if( seenDP ) return 0; + seenDP = 1; + continue; + } + if( c=='e' || c=='E' ){ + if( z[j-1]<'0' ) return 0; + if( seenE ) return -1; + seenDP = seenE = 1; + c = z[j+1]; + if( c=='+' || c=='-' ){ + j++; + c = z[j+1]; + } + if( c<'0' || c>'9' ) return 0; + continue; + } + break; + } + if( z[j-1]<'0' ) return 0; + if( pVal ){ +#ifdef SQLITE_AMALGAMATION + /* The sqlite3AtoF() routine is much much faster than atof(), if it + ** is available */ + double r; + (void)sqlite3AtoF((const char*)p->z, &r); + *pVal = r; +#else + *pVal = (GeoCoord)atof((const char*)p->z); +#endif + } + p->z += j; + return 1; +} + +/* +** If the input is a well-formed JSON array of coordinates with at least +** four coordinates and where each coordinate is itself a two-value array, +** then convert the JSON into a GeoPoly object and return a pointer to +** that object. +** +** If any error occurs, return NULL. +*/ +static GeoPoly *geopolyParseJson(const unsigned char *z, int *pRc){ + GeoParse s; + int rc = SQLITE_OK; + memset(&s, 0, sizeof(s)); + s.z = z; + if( geopolySkipSpace(&s)=='[' ){ + s.z++; + while( geopolySkipSpace(&s)=='[' ){ + int ii = 0; + char c; + s.z++; + if( s.nVertex>=s.nAlloc ){ + GeoCoord *aNew; + s.nAlloc = s.nAlloc*2 + 16; + aNew = sqlite3_realloc64(s.a, s.nAlloc*sizeof(GeoCoord)*2 ); + if( aNew==0 ){ + rc = SQLITE_NOMEM; + s.nErr++; + break; + } + s.a = aNew; + } + while( geopolyParseNumber(&s, ii<=1 ? &s.a[s.nVertex*2+ii] : 0) ){ + ii++; + if( ii==2 ) s.nVertex++; + c = geopolySkipSpace(&s); + s.z++; + if( c==',' ) continue; + if( c==']' && ii>=2 ) break; + s.nErr++; + rc = SQLITE_ERROR; + goto parse_json_err; + } + if( geopolySkipSpace(&s)==',' ){ + s.z++; + continue; + } + break; + } + if( geopolySkipSpace(&s)==']' + && s.nVertex>=4 + && s.a[0]==s.a[s.nVertex*2-2] + && s.a[1]==s.a[s.nVertex*2-1] + && (s.z++, geopolySkipSpace(&s)==0) + ){ + GeoPoly *pOut; + int x = 1; + s.nVertex--; /* Remove the redundant vertex at the end */ + pOut = sqlite3_malloc64( GEOPOLY_SZ((sqlite3_int64)s.nVertex) ); + x = 1; + if( pOut==0 ) goto parse_json_err; + pOut->nVertex = s.nVertex; + memcpy(pOut->a, s.a, s.nVertex*2*sizeof(GeoCoord)); + pOut->hdr[0] = *(unsigned char*)&x; + pOut->hdr[1] = (s.nVertex>>16)&0xff; + pOut->hdr[2] = (s.nVertex>>8)&0xff; + pOut->hdr[3] = s.nVertex&0xff; + sqlite3_free(s.a); + if( pRc ) *pRc = SQLITE_OK; + return pOut; + }else{ + s.nErr++; + rc = SQLITE_ERROR; + } + } +parse_json_err: + if( pRc ) *pRc = rc; + sqlite3_free(s.a); + return 0; +} + +/* +** Given a function parameter, try to interpret it as a polygon, either +** in the binary format or JSON text. Compute a GeoPoly object and +** return a pointer to that object. Or if the input is not a well-formed +** polygon, put an error message in sqlite3_context and return NULL. +*/ +static GeoPoly *geopolyFuncParam( + sqlite3_context *pCtx, /* Context for error messages */ + sqlite3_value *pVal, /* The value to decode */ + int *pRc /* Write error here */ +){ + GeoPoly *p = 0; + int nByte; + testcase( pCtx==0 ); + if( sqlite3_value_type(pVal)==SQLITE_BLOB + && (nByte = sqlite3_value_bytes(pVal))>=(int)(4+6*sizeof(GeoCoord)) + ){ + const unsigned char *a = sqlite3_value_blob(pVal); + int nVertex; + if( a==0 ){ + if( pCtx ) sqlite3_result_error_nomem(pCtx); + return 0; + } + nVertex = (a[1]<<16) + (a[2]<<8) + a[3]; + if( (a[0]==0 || a[0]==1) + && (nVertex*2*sizeof(GeoCoord) + 4)==(unsigned int)nByte + ){ + p = sqlite3_malloc64( sizeof(*p) + (nVertex-1)*2*sizeof(GeoCoord) ); + if( p==0 ){ + if( pRc ) *pRc = SQLITE_NOMEM; + if( pCtx ) sqlite3_result_error_nomem(pCtx); + }else{ + int x = 1; + p->nVertex = nVertex; + memcpy(p->hdr, a, nByte); + if( a[0] != *(unsigned char*)&x ){ + int ii; + for(ii=0; iihdr[0] ^= 1; + } + } + } + if( pRc ) *pRc = SQLITE_OK; + return p; + }else if( sqlite3_value_type(pVal)==SQLITE_TEXT ){ + const unsigned char *zJson = sqlite3_value_text(pVal); + if( zJson==0 ){ + if( pRc ) *pRc = SQLITE_NOMEM; + return 0; + } + return geopolyParseJson(zJson, pRc); + }else{ + if( pRc ) *pRc = SQLITE_ERROR; + return 0; + } +} + +/* +** Implementation of the geopoly_blob(X) function. +** +** If the input is a well-formed Geopoly BLOB or JSON string +** then return the BLOB representation of the polygon. Otherwise +** return NULL. +*/ +static void geopolyBlobFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p = geopolyFuncParam(context, argv[0], 0); + (void)argc; + if( p ){ + sqlite3_result_blob(context, p->hdr, + 4+8*p->nVertex, SQLITE_TRANSIENT); + sqlite3_free(p); + } +} + +/* +** SQL function: geopoly_json(X) +** +** Interpret X as a polygon and render it as a JSON array +** of coordinates. Or, if X is not a valid polygon, return NULL. +*/ +static void geopolyJsonFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p = geopolyFuncParam(context, argv[0], 0); + (void)argc; + if( p ){ + sqlite3 *db = sqlite3_context_db_handle(context); + sqlite3_str *x = sqlite3_str_new(db); + int i; + sqlite3_str_append(x, "[", 1); + for(i=0; inVertex; i++){ + sqlite3_str_appendf(x, "[%!g,%!g],", GeoX(p,i), GeoY(p,i)); + } + sqlite3_str_appendf(x, "[%!g,%!g]]", GeoX(p,0), GeoY(p,0)); + sqlite3_result_text(context, sqlite3_str_finish(x), -1, sqlite3_free); + sqlite3_free(p); + } +} + +/* +** SQL function: geopoly_svg(X, ....) +** +** Interpret X as a polygon and render it as a SVG . +** Additional arguments are added as attributes to the . +*/ +static void geopolySvgFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p; + if( argc<1 ) return; + p = geopolyFuncParam(context, argv[0], 0); + if( p ){ + sqlite3 *db = sqlite3_context_db_handle(context); + sqlite3_str *x = sqlite3_str_new(db); + int i; + char cSep = '\''; + sqlite3_str_appendf(x, ""); + sqlite3_result_text(context, sqlite3_str_finish(x), -1, sqlite3_free); + sqlite3_free(p); + } +} + +/* +** SQL Function: geopoly_xform(poly, A, B, C, D, E, F) +** +** Transform and/or translate a polygon as follows: +** +** x1 = A*x0 + B*y0 + E +** y1 = C*x0 + D*y0 + F +** +** For a translation: +** +** geopoly_xform(poly, 1, 0, 0, 1, x-offset, y-offset) +** +** Rotate by R around the point (0,0): +** +** geopoly_xform(poly, cos(R), sin(R), -sin(R), cos(R), 0, 0) +*/ +static void geopolyXformFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p = geopolyFuncParam(context, argv[0], 0); + double A = sqlite3_value_double(argv[1]); + double B = sqlite3_value_double(argv[2]); + double C = sqlite3_value_double(argv[3]); + double D = sqlite3_value_double(argv[4]); + double E = sqlite3_value_double(argv[5]); + double F = sqlite3_value_double(argv[6]); + GeoCoord x1, y1, x0, y0; + int ii; + (void)argc; + if( p ){ + for(ii=0; iinVertex; ii++){ + x0 = GeoX(p,ii); + y0 = GeoY(p,ii); + x1 = (GeoCoord)(A*x0 + B*y0 + E); + y1 = (GeoCoord)(C*x0 + D*y0 + F); + GeoX(p,ii) = x1; + GeoY(p,ii) = y1; + } + sqlite3_result_blob(context, p->hdr, + 4+8*p->nVertex, SQLITE_TRANSIENT); + sqlite3_free(p); + } +} + +/* +** Compute the area enclosed by the polygon. +** +** This routine can also be used to detect polygons that rotate in +** the wrong direction. Polygons are suppose to be counter-clockwise (CCW). +** This routine returns a negative value for clockwise (CW) polygons. +*/ +static double geopolyArea(GeoPoly *p){ + double rArea = 0.0; + int ii; + for(ii=0; iinVertex-1; ii++){ + rArea += (GeoX(p,ii) - GeoX(p,ii+1)) /* (x0 - x1) */ + * (GeoY(p,ii) + GeoY(p,ii+1)) /* (y0 + y1) */ + * 0.5; + } + rArea += (GeoX(p,ii) - GeoX(p,0)) /* (xN - x0) */ + * (GeoY(p,ii) + GeoY(p,0)) /* (yN + y0) */ + * 0.5; + return rArea; +} + +/* +** Implementation of the geopoly_area(X) function. +** +** If the input is a well-formed Geopoly BLOB then return the area +** enclosed by the polygon. If the polygon circulates clockwise instead +** of counterclockwise (as it should) then return the negative of the +** enclosed area. Otherwise return NULL. +*/ +static void geopolyAreaFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p = geopolyFuncParam(context, argv[0], 0); + (void)argc; + if( p ){ + sqlite3_result_double(context, geopolyArea(p)); + sqlite3_free(p); + } +} + +/* +** Implementation of the geopoly_ccw(X) function. +** +** If the rotation of polygon X is clockwise (incorrect) instead of +** counter-clockwise (the correct winding order according to RFC7946) +** then reverse the order of the vertexes in polygon X. +** +** In other words, this routine returns a CCW polygon regardless of the +** winding order of its input. +** +** Use this routine to sanitize historical inputs that that sometimes +** contain polygons that wind in the wrong direction. +*/ +static void geopolyCcwFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p = geopolyFuncParam(context, argv[0], 0); + (void)argc; + if( p ){ + if( geopolyArea(p)<0.0 ){ + int ii, jj; + for(ii=1, jj=p->nVertex-1; iihdr, + 4+8*p->nVertex, SQLITE_TRANSIENT); + sqlite3_free(p); + } +} + +#define GEOPOLY_PI 3.1415926535897932385 + +/* Fast approximation for sine(X) for X between -0.5*pi and 2*pi +*/ +static double geopolySine(double r){ + assert( r>=-0.5*GEOPOLY_PI && r<=2.0*GEOPOLY_PI ); + if( r>=1.5*GEOPOLY_PI ){ + r -= 2.0*GEOPOLY_PI; + } + if( r>=0.5*GEOPOLY_PI ){ + return -geopolySine(r-GEOPOLY_PI); + }else{ + double r2 = r*r; + double r3 = r2*r; + double r5 = r3*r2; + return 0.9996949*r - 0.1656700*r3 + 0.0075134*r5; + } +} + +/* +** Function: geopoly_regular(X,Y,R,N) +** +** Construct a simple, convex, regular polygon centered at X, Y +** with circumradius R and with N sides. +*/ +static void geopolyRegularFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + double x = sqlite3_value_double(argv[0]); + double y = sqlite3_value_double(argv[1]); + double r = sqlite3_value_double(argv[2]); + int n = sqlite3_value_int(argv[3]); + int i; + GeoPoly *p; + (void)argc; + + if( n<3 || r<=0.0 ) return; + if( n>1000 ) n = 1000; + p = sqlite3_malloc64( sizeof(*p) + (n-1)*2*sizeof(GeoCoord) ); + if( p==0 ){ + sqlite3_result_error_nomem(context); + return; + } + i = 1; + p->hdr[0] = *(unsigned char*)&i; + p->hdr[1] = 0; + p->hdr[2] = (n>>8)&0xff; + p->hdr[3] = n&0xff; + for(i=0; ihdr, 4+8*n, SQLITE_TRANSIENT); + sqlite3_free(p); +} + +/* +** If pPoly is a polygon, compute its bounding box. Then: +** +** (1) if aCoord!=0 store the bounding box in aCoord, returning NULL +** (2) otherwise, compute a GeoPoly for the bounding box and return the +** new GeoPoly +** +** If pPoly is NULL but aCoord is not NULL, then compute a new GeoPoly from +** the bounding box in aCoord and return a pointer to that GeoPoly. +*/ +static GeoPoly *geopolyBBox( + sqlite3_context *context, /* For recording the error */ + sqlite3_value *pPoly, /* The polygon */ + RtreeCoord *aCoord, /* Results here */ + int *pRc /* Error code here */ +){ + GeoPoly *pOut = 0; + GeoPoly *p; + float mnX, mxX, mnY, mxY; + if( pPoly==0 && aCoord!=0 ){ + p = 0; + mnX = aCoord[0].f; + mxX = aCoord[1].f; + mnY = aCoord[2].f; + mxY = aCoord[3].f; + goto geopolyBboxFill; + }else{ + p = geopolyFuncParam(context, pPoly, pRc); + } + if( p ){ + int ii; + mnX = mxX = GeoX(p,0); + mnY = mxY = GeoY(p,0); + for(ii=1; iinVertex; ii++){ + double r = GeoX(p,ii); + if( rmxX ) mxX = (float)r; + r = GeoY(p,ii); + if( rmxY ) mxY = (float)r; + } + if( pRc ) *pRc = SQLITE_OK; + if( aCoord==0 ){ + geopolyBboxFill: + pOut = sqlite3_realloc64(p, GEOPOLY_SZ(4)); + if( pOut==0 ){ + sqlite3_free(p); + if( context ) sqlite3_result_error_nomem(context); + if( pRc ) *pRc = SQLITE_NOMEM; + return 0; + } + pOut->nVertex = 4; + ii = 1; + pOut->hdr[0] = *(unsigned char*)ⅈ + pOut->hdr[1] = 0; + pOut->hdr[2] = 0; + pOut->hdr[3] = 4; + GeoX(pOut,0) = mnX; + GeoY(pOut,0) = mnY; + GeoX(pOut,1) = mxX; + GeoY(pOut,1) = mnY; + GeoX(pOut,2) = mxX; + GeoY(pOut,2) = mxY; + GeoX(pOut,3) = mnX; + GeoY(pOut,3) = mxY; + }else{ + sqlite3_free(p); + aCoord[0].f = mnX; + aCoord[1].f = mxX; + aCoord[2].f = mnY; + aCoord[3].f = mxY; + } + }else if( aCoord ){ + memset(aCoord, 0, sizeof(RtreeCoord)*4); + } + return pOut; +} + +/* +** Implementation of the geopoly_bbox(X) SQL function. +*/ +static void geopolyBBoxFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p = geopolyBBox(context, argv[0], 0, 0); + (void)argc; + if( p ){ + sqlite3_result_blob(context, p->hdr, + 4+8*p->nVertex, SQLITE_TRANSIENT); + sqlite3_free(p); + } +} + +/* +** State vector for the geopoly_group_bbox() aggregate function. +*/ +typedef struct GeoBBox GeoBBox; +struct GeoBBox { + int isInit; + RtreeCoord a[4]; +}; + + +/* +** Implementation of the geopoly_group_bbox(X) aggregate SQL function. +*/ +static void geopolyBBoxStep( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + RtreeCoord a[4]; + int rc = SQLITE_OK; + (void)argc; + (void)geopolyBBox(context, argv[0], a, &rc); + if( rc==SQLITE_OK ){ + GeoBBox *pBBox; + pBBox = (GeoBBox*)sqlite3_aggregate_context(context, sizeof(*pBBox)); + if( pBBox==0 ) return; + if( pBBox->isInit==0 ){ + pBBox->isInit = 1; + memcpy(pBBox->a, a, sizeof(RtreeCoord)*4); + }else{ + if( a[0].f < pBBox->a[0].f ) pBBox->a[0] = a[0]; + if( a[1].f > pBBox->a[1].f ) pBBox->a[1] = a[1]; + if( a[2].f < pBBox->a[2].f ) pBBox->a[2] = a[2]; + if( a[3].f > pBBox->a[3].f ) pBBox->a[3] = a[3]; + } + } +} +static void geopolyBBoxFinal( + sqlite3_context *context +){ + GeoPoly *p; + GeoBBox *pBBox; + pBBox = (GeoBBox*)sqlite3_aggregate_context(context, 0); + if( pBBox==0 ) return; + p = geopolyBBox(context, 0, pBBox->a, 0); + if( p ){ + sqlite3_result_blob(context, p->hdr, + 4+8*p->nVertex, SQLITE_TRANSIENT); + sqlite3_free(p); + } +} + + +/* +** Determine if point (x0,y0) is beneath line segment (x1,y1)->(x2,y2). +** Returns: +** +** +2 x0,y0 is on the line segment +** +** +1 x0,y0 is beneath line segment +** +** 0 x0,y0 is not on or beneath the line segment or the line segment +** is vertical and x0,y0 is not on the line segment +** +** The left-most coordinate min(x1,x2) is not considered to be part of +** the line segment for the purposes of this analysis. +*/ +static int pointBeneathLine( + double x0, double y0, + double x1, double y1, + double x2, double y2 +){ + double y; + if( x0==x1 && y0==y1 ) return 2; + if( x1x2 ) return 0; + }else if( x1>x2 ){ + if( x0<=x2 || x0>x1 ) return 0; + }else{ + /* Vertical line segment */ + if( x0!=x1 ) return 0; + if( y0y1 && y0>y2 ) return 0; + return 2; + } + y = y1 + (y2-y1)*(x0-x1)/(x2-x1); + if( y0==y ) return 2; + if( y0nVertex-1; ii++){ + v = pointBeneathLine(x0,y0,GeoX(p1,ii), GeoY(p1,ii), + GeoX(p1,ii+1),GeoY(p1,ii+1)); + if( v==2 ) break; + cnt += v; + } + if( v!=2 ){ + v = pointBeneathLine(x0,y0,GeoX(p1,ii), GeoY(p1,ii), + GeoX(p1,0), GeoY(p1,0)); + } + if( v==2 ){ + sqlite3_result_int(context, 1); + }else if( ((v+cnt)&1)==0 ){ + sqlite3_result_int(context, 0); + }else{ + sqlite3_result_int(context, 2); + } + sqlite3_free(p1); +} + +/* Forward declaration */ +static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2); + +/* +** SQL function: geopoly_within(P1,P2) +** +** Return +2 if P1 and P2 are the same polygon +** Return +1 if P2 is contained within P1 +** Return 0 if any part of P2 is on the outside of P1 +** +*/ +static void geopolyWithinFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0); + GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0); + (void)argc; + if( p1 && p2 ){ + int x = geopolyOverlap(p1, p2); + if( x<0 ){ + sqlite3_result_error_nomem(context); + }else{ + sqlite3_result_int(context, x==2 ? 1 : x==4 ? 2 : 0); + } + } + sqlite3_free(p1); + sqlite3_free(p2); +} + +/* Objects used by the overlap algorithm. */ +typedef struct GeoEvent GeoEvent; +typedef struct GeoSegment GeoSegment; +typedef struct GeoOverlap GeoOverlap; +struct GeoEvent { + double x; /* X coordinate at which event occurs */ + int eType; /* 0 for ADD, 1 for REMOVE */ + GeoSegment *pSeg; /* The segment to be added or removed */ + GeoEvent *pNext; /* Next event in the sorted list */ +}; +struct GeoSegment { + double C, B; /* y = C*x + B */ + double y; /* Current y value */ + float y0; /* Initial y value */ + unsigned char side; /* 1 for p1, 2 for p2 */ + unsigned int idx; /* Which segment within the side */ + GeoSegment *pNext; /* Next segment in a list sorted by y */ +}; +struct GeoOverlap { + GeoEvent *aEvent; /* Array of all events */ + GeoSegment *aSegment; /* Array of all segments */ + int nEvent; /* Number of events */ + int nSegment; /* Number of segments */ +}; + +/* +** Add a single segment and its associated events. +*/ +static void geopolyAddOneSegment( + GeoOverlap *p, + GeoCoord x0, + GeoCoord y0, + GeoCoord x1, + GeoCoord y1, + unsigned char side, + unsigned int idx +){ + GeoSegment *pSeg; + GeoEvent *pEvent; + if( x0==x1 ) return; /* Ignore vertical segments */ + if( x0>x1 ){ + GeoCoord t = x0; + x0 = x1; + x1 = t; + t = y0; + y0 = y1; + y1 = t; + } + pSeg = p->aSegment + p->nSegment; + p->nSegment++; + pSeg->C = (y1-y0)/(x1-x0); + pSeg->B = y1 - x1*pSeg->C; + pSeg->y0 = y0; + pSeg->side = side; + pSeg->idx = idx; + pEvent = p->aEvent + p->nEvent; + p->nEvent++; + pEvent->x = x0; + pEvent->eType = 0; + pEvent->pSeg = pSeg; + pEvent = p->aEvent + p->nEvent; + p->nEvent++; + pEvent->x = x1; + pEvent->eType = 1; + pEvent->pSeg = pSeg; +} + + + +/* +** Insert all segments and events for polygon pPoly. +*/ +static void geopolyAddSegments( + GeoOverlap *p, /* Add segments to this Overlap object */ + GeoPoly *pPoly, /* Take all segments from this polygon */ + unsigned char side /* The side of pPoly */ +){ + unsigned int i; + GeoCoord *x; + for(i=0; i<(unsigned)pPoly->nVertex-1; i++){ + x = &GeoX(pPoly,i); + geopolyAddOneSegment(p, x[0], x[1], x[2], x[3], side, i); + } + x = &GeoX(pPoly,i); + geopolyAddOneSegment(p, x[0], x[1], pPoly->a[0], pPoly->a[1], side, i); +} + +/* +** Merge two lists of sorted events by X coordinate +*/ +static GeoEvent *geopolyEventMerge(GeoEvent *pLeft, GeoEvent *pRight){ + GeoEvent head, *pLast; + head.pNext = 0; + pLast = &head; + while( pRight && pLeft ){ + if( pRight->x <= pLeft->x ){ + pLast->pNext = pRight; + pLast = pRight; + pRight = pRight->pNext; + }else{ + pLast->pNext = pLeft; + pLast = pLeft; + pLeft = pLeft->pNext; + } + } + pLast->pNext = pRight ? pRight : pLeft; + return head.pNext; +} + +/* +** Sort an array of nEvent event objects into a list. +*/ +static GeoEvent *geopolySortEventsByX(GeoEvent *aEvent, int nEvent){ + int mx = 0; + int i, j; + GeoEvent *p; + GeoEvent *a[50]; + for(i=0; ipNext = 0; + for(j=0; j=mx ) mx = j+1; + } + p = 0; + for(i=0; iy - pLeft->y; + if( r==0.0 ) r = pRight->C - pLeft->C; + if( r<0.0 ){ + pLast->pNext = pRight; + pLast = pRight; + pRight = pRight->pNext; + }else{ + pLast->pNext = pLeft; + pLast = pLeft; + pLeft = pLeft->pNext; + } + } + pLast->pNext = pRight ? pRight : pLeft; + return head.pNext; +} + +/* +** Sort a list of GeoSegments in order of increasing Y and in the event of +** a tie, increasing C (slope). +*/ +static GeoSegment *geopolySortSegmentsByYAndC(GeoSegment *pList){ + int mx = 0; + int i; + GeoSegment *p; + GeoSegment *a[50]; + while( pList ){ + p = pList; + pList = pList->pNext; + p->pNext = 0; + for(i=0; i=mx ) mx = i+1; + } + p = 0; + for(i=0; inVertex + p2->nVertex + 2; + GeoOverlap *p; + sqlite3_int64 nByte; + GeoEvent *pThisEvent; + double rX; + int rc = 0; + int needSort = 0; + GeoSegment *pActive = 0; + GeoSegment *pSeg; + unsigned char aOverlap[4]; + + nByte = sizeof(GeoEvent)*nVertex*2 + + sizeof(GeoSegment)*nVertex + + sizeof(GeoOverlap); + p = sqlite3_malloc64( nByte ); + if( p==0 ) return -1; + p->aEvent = (GeoEvent*)&p[1]; + p->aSegment = (GeoSegment*)&p->aEvent[nVertex*2]; + p->nEvent = p->nSegment = 0; + geopolyAddSegments(p, p1, 1); + geopolyAddSegments(p, p2, 2); + pThisEvent = geopolySortEventsByX(p->aEvent, p->nEvent); + rX = pThisEvent && pThisEvent->x==0.0 ? -1.0 : 0.0; + memset(aOverlap, 0, sizeof(aOverlap)); + while( pThisEvent ){ + if( pThisEvent->x!=rX ){ + GeoSegment *pPrev = 0; + int iMask = 0; + GEODEBUG(("Distinct X: %g\n", pThisEvent->x)); + rX = pThisEvent->x; + if( needSort ){ + GEODEBUG(("SORT\n")); + pActive = geopolySortSegmentsByYAndC(pActive); + needSort = 0; + } + for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){ + if( pPrev ){ + if( pPrev->y!=pSeg->y ){ + GEODEBUG(("MASK: %d\n", iMask)); + aOverlap[iMask] = 1; + } + } + iMask ^= pSeg->side; + pPrev = pSeg; + } + pPrev = 0; + for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){ + double y = pSeg->C*rX + pSeg->B; + GEODEBUG(("Segment %d.%d %g->%g\n", pSeg->side, pSeg->idx, pSeg->y, y)); + pSeg->y = y; + if( pPrev ){ + if( pPrev->y>pSeg->y && pPrev->side!=pSeg->side ){ + rc = 1; + GEODEBUG(("Crossing: %d.%d and %d.%d\n", + pPrev->side, pPrev->idx, + pSeg->side, pSeg->idx)); + goto geopolyOverlapDone; + }else if( pPrev->y!=pSeg->y ){ + GEODEBUG(("MASK: %d\n", iMask)); + aOverlap[iMask] = 1; + } + } + iMask ^= pSeg->side; + pPrev = pSeg; + } + } + GEODEBUG(("%s %d.%d C=%g B=%g\n", + pThisEvent->eType ? "RM " : "ADD", + pThisEvent->pSeg->side, pThisEvent->pSeg->idx, + pThisEvent->pSeg->C, + pThisEvent->pSeg->B)); + if( pThisEvent->eType==0 ){ + /* Add a segment */ + pSeg = pThisEvent->pSeg; + pSeg->y = pSeg->y0; + pSeg->pNext = pActive; + pActive = pSeg; + needSort = 1; + }else{ + /* Remove a segment */ + if( pActive==pThisEvent->pSeg ){ + pActive = ALWAYS(pActive) ? pActive->pNext : 0; + }else{ + for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){ + if( pSeg->pNext==pThisEvent->pSeg ){ + pSeg->pNext = ALWAYS(pSeg->pNext) ? pSeg->pNext->pNext : 0; + break; + } + } + } + } + pThisEvent = pThisEvent->pNext; + } + if( aOverlap[3]==0 ){ + rc = 0; + }else if( aOverlap[1]!=0 && aOverlap[2]==0 ){ + rc = 3; + }else if( aOverlap[1]==0 && aOverlap[2]!=0 ){ + rc = 2; + }else if( aOverlap[1]==0 && aOverlap[2]==0 ){ + rc = 4; + }else{ + rc = 1; + } + +geopolyOverlapDone: + sqlite3_free(p); + return rc; +} + +/* +** SQL function: geopoly_overlap(P1,P2) +** +** Determine whether or not P1 and P2 overlap. Return value: +** +** 0 The two polygons are disjoint +** 1 They overlap +** 2 P1 is completely contained within P2 +** 3 P2 is completely contained within P1 +** 4 P1 and P2 are the same polygon +** NULL Either P1 or P2 or both are not valid polygons +*/ +static void geopolyOverlapFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0); + GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0); + (void)argc; + if( p1 && p2 ){ + int x = geopolyOverlap(p1, p2); + if( x<0 ){ + sqlite3_result_error_nomem(context); + }else{ + sqlite3_result_int(context, x); + } + } + sqlite3_free(p1); + sqlite3_free(p2); +} + +/* +** Enable or disable debugging output +*/ +static void geopolyDebugFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + (void)context; + (void)argc; +#ifdef GEOPOLY_ENABLE_DEBUG + geo_debug = sqlite3_value_int(argv[0]); +#else + (void)argv; +#endif +} + +/* +** This function is the implementation of both the xConnect and xCreate +** methods of the geopoly virtual table. +** +** argv[0] -> module name +** argv[1] -> database name +** argv[2] -> table name +** argv[...] -> column names... +*/ +static int geopolyInit( + sqlite3 *db, /* Database connection */ + void *pAux, /* One of the RTREE_COORD_* constants */ + int argc, const char *const*argv, /* Parameters to CREATE TABLE statement */ + sqlite3_vtab **ppVtab, /* OUT: New virtual table */ + char **pzErr, /* OUT: Error message, if any */ + int isCreate /* True for xCreate, false for xConnect */ +){ + int rc = SQLITE_OK; + Rtree *pRtree; + sqlite3_int64 nDb; /* Length of string argv[1] */ + sqlite3_int64 nName; /* Length of string argv[2] */ + sqlite3_str *pSql; + char *zSql; + int ii; + (void)pAux; + + if( argc>=RTREE_MAX_AUX_COLUMN+4 ){ + *pzErr = sqlite3_mprintf("Too many columns for a geopoly table"); + return SQLITE_ERROR; + } + + sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); + sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); + + /* Allocate the sqlite3_vtab structure */ + nDb = strlen(argv[1]); + nName = strlen(argv[2]); + pRtree = (Rtree *)sqlite3_malloc64(sizeof(Rtree)+nDb+nName*2+8); + if( !pRtree ){ + return SQLITE_NOMEM; + } + memset(pRtree, 0, sizeof(Rtree)+nDb+nName*2+8); + pRtree->nBusy = 1; + pRtree->base.pModule = &rtreeModule; + pRtree->zDb = (char *)&pRtree[1]; + pRtree->zName = &pRtree->zDb[nDb+1]; + pRtree->zNodeName = &pRtree->zName[nName+1]; + pRtree->eCoordType = RTREE_COORD_REAL32; + pRtree->nDim = 2; + pRtree->nDim2 = 4; + memcpy(pRtree->zDb, argv[1], nDb); + memcpy(pRtree->zName, argv[2], nName); + memcpy(pRtree->zNodeName, argv[2], nName); + memcpy(&pRtree->zNodeName[nName], "_node", 6); + + + /* Create/Connect to the underlying relational database schema. If + ** that is successful, call sqlite3_declare_vtab() to configure + ** the r-tree table schema. + */ + pSql = sqlite3_str_new(db); + sqlite3_str_appendf(pSql, "CREATE TABLE x(_shape"); + pRtree->nAux = 1; /* Add one for _shape */ + pRtree->nAuxNotNull = 1; /* The _shape column is always not-null */ + for(ii=3; iinAux++; + sqlite3_str_appendf(pSql, ",%s", argv[ii]); + } + sqlite3_str_appendf(pSql, ");"); + zSql = sqlite3_str_finish(pSql); + if( !zSql ){ + rc = SQLITE_NOMEM; + }else if( SQLITE_OK!=(rc = sqlite3_declare_vtab(db, zSql)) ){ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + } + sqlite3_free(zSql); + if( rc ) goto geopolyInit_fail; + pRtree->nBytesPerCell = 8 + pRtree->nDim2*4; + + /* Figure out the node size to use. */ + rc = getNodeSize(db, pRtree, isCreate, pzErr); + if( rc ) goto geopolyInit_fail; + rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate); + if( rc ){ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + goto geopolyInit_fail; + } + + *ppVtab = (sqlite3_vtab *)pRtree; + return SQLITE_OK; + +geopolyInit_fail: + if( rc==SQLITE_OK ) rc = SQLITE_ERROR; + assert( *ppVtab==0 ); + assert( pRtree->nBusy==1 ); + rtreeRelease(pRtree); + return rc; +} + + +/* +** GEOPOLY virtual table module xCreate method. +*/ +static int geopolyCreate( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + return geopolyInit(db, pAux, argc, argv, ppVtab, pzErr, 1); +} + +/* +** GEOPOLY virtual table module xConnect method. +*/ +static int geopolyConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + return geopolyInit(db, pAux, argc, argv, ppVtab, pzErr, 0); +} + + +/* +** GEOPOLY virtual table module xFilter method. +** +** Query plans: +** +** 1 rowid lookup +** 2 search for objects overlapping the same bounding box +** that contains polygon argv[0] +** 3 search for objects overlapping the same bounding box +** that contains polygon argv[0] +** 4 full table scan +*/ +static int geopolyFilter( + sqlite3_vtab_cursor *pVtabCursor, /* The cursor to initialize */ + int idxNum, /* Query plan */ + const char *idxStr, /* Not Used */ + int argc, sqlite3_value **argv /* Parameters to the query plan */ +){ + Rtree *pRtree = (Rtree *)pVtabCursor->pVtab; + RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; + RtreeNode *pRoot = 0; + int rc = SQLITE_OK; + int iCell = 0; + (void)idxStr; + + rtreeReference(pRtree); + + /* Reset the cursor to the same state as rtreeOpen() leaves it in. */ + resetCursor(pCsr); + + pCsr->iStrategy = idxNum; + if( idxNum==1 ){ + /* Special case - lookup by rowid. */ + RtreeNode *pLeaf; /* Leaf on which the required cell resides */ + RtreeSearchPoint *p; /* Search point for the leaf */ + i64 iRowid = sqlite3_value_int64(argv[0]); + i64 iNode = 0; + rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode); + if( rc==SQLITE_OK && pLeaf!=0 ){ + p = rtreeSearchPointNew(pCsr, RTREE_ZERO, 0); + assert( p!=0 ); /* Always returns pCsr->sPoint */ + pCsr->aNode[0] = pLeaf; + p->id = iNode; + p->eWithin = PARTLY_WITHIN; + rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &iCell); + p->iCell = (u8)iCell; + RTREE_QUEUE_TRACE(pCsr, "PUSH-F1:"); + }else{ + pCsr->atEOF = 1; + } + }else{ + /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array + ** with the configured constraints. + */ + rc = nodeAcquire(pRtree, 1, 0, &pRoot); + if( rc==SQLITE_OK && idxNum<=3 ){ + RtreeCoord bbox[4]; + RtreeConstraint *p; + assert( argc==1 ); + assert( argv[0]!=0 ); + geopolyBBox(0, argv[0], bbox, &rc); + if( rc ){ + goto geopoly_filter_end; + } + pCsr->aConstraint = p = sqlite3_malloc(sizeof(RtreeConstraint)*4); + pCsr->nConstraint = 4; + if( p==0 ){ + rc = SQLITE_NOMEM; + }else{ + memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*4); + memset(pCsr->anQueue, 0, sizeof(u32)*(pRtree->iDepth + 1)); + if( idxNum==2 ){ + /* Overlap query */ + p->op = 'B'; + p->iCoord = 0; + p->u.rValue = bbox[1].f; + p++; + p->op = 'D'; + p->iCoord = 1; + p->u.rValue = bbox[0].f; + p++; + p->op = 'B'; + p->iCoord = 2; + p->u.rValue = bbox[3].f; + p++; + p->op = 'D'; + p->iCoord = 3; + p->u.rValue = bbox[2].f; + }else{ + /* Within query */ + p->op = 'D'; + p->iCoord = 0; + p->u.rValue = bbox[0].f; + p++; + p->op = 'B'; + p->iCoord = 1; + p->u.rValue = bbox[1].f; + p++; + p->op = 'D'; + p->iCoord = 2; + p->u.rValue = bbox[2].f; + p++; + p->op = 'B'; + p->iCoord = 3; + p->u.rValue = bbox[3].f; + } + } + } + if( rc==SQLITE_OK ){ + RtreeSearchPoint *pNew; + pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, (u8)(pRtree->iDepth+1)); + if( pNew==0 ){ + rc = SQLITE_NOMEM; + goto geopoly_filter_end; + } + pNew->id = 1; + pNew->iCell = 0; + pNew->eWithin = PARTLY_WITHIN; + assert( pCsr->bPoint==1 ); + pCsr->aNode[0] = pRoot; + pRoot = 0; + RTREE_QUEUE_TRACE(pCsr, "PUSH-Fm:"); + rc = rtreeStepToLeaf(pCsr); + } + } + +geopoly_filter_end: + nodeRelease(pRtree, pRoot); + rtreeRelease(pRtree); + return rc; +} + +/* +** Rtree virtual table module xBestIndex method. There are three +** table scan strategies to choose from (in order from most to +** least desirable): +** +** idxNum idxStr Strategy +** ------------------------------------------------ +** 1 "rowid" Direct lookup by rowid. +** 2 "rtree" R-tree overlap query using geopoly_overlap() +** 3 "rtree" R-tree within query using geopoly_within() +** 4 "fullscan" full-table scan. +** ------------------------------------------------ +*/ +static int geopolyBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ + int ii; + int iRowidTerm = -1; + int iFuncTerm = -1; + int idxNum = 0; + (void)tab; + + for(ii=0; iinConstraint; ii++){ + struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii]; + if( !p->usable ) continue; + if( p->iColumn<0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){ + iRowidTerm = ii; + break; + } + if( p->iColumn==0 && p->op>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){ + /* p->op==SQLITE_INDEX_CONSTRAINT_FUNCTION for geopoly_overlap() + ** p->op==(SQLITE_INDEX_CONTRAINT_FUNCTION+1) for geopoly_within(). + ** See geopolyFindFunction() */ + iFuncTerm = ii; + idxNum = p->op - SQLITE_INDEX_CONSTRAINT_FUNCTION + 2; + } + } + + if( iRowidTerm>=0 ){ + pIdxInfo->idxNum = 1; + pIdxInfo->idxStr = "rowid"; + pIdxInfo->aConstraintUsage[iRowidTerm].argvIndex = 1; + pIdxInfo->aConstraintUsage[iRowidTerm].omit = 1; + pIdxInfo->estimatedCost = 30.0; + pIdxInfo->estimatedRows = 1; + pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE; + return SQLITE_OK; + } + if( iFuncTerm>=0 ){ + pIdxInfo->idxNum = idxNum; + pIdxInfo->idxStr = "rtree"; + pIdxInfo->aConstraintUsage[iFuncTerm].argvIndex = 1; + pIdxInfo->aConstraintUsage[iFuncTerm].omit = 0; + pIdxInfo->estimatedCost = 300.0; + pIdxInfo->estimatedRows = 10; + return SQLITE_OK; + } + pIdxInfo->idxNum = 4; + pIdxInfo->idxStr = "fullscan"; + pIdxInfo->estimatedCost = 3000000.0; + pIdxInfo->estimatedRows = 100000; + return SQLITE_OK; +} + + +/* +** GEOPOLY virtual table module xColumn method. +*/ +static int geopolyColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ + Rtree *pRtree = (Rtree *)cur->pVtab; + RtreeCursor *pCsr = (RtreeCursor *)cur; + RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr); + int rc = SQLITE_OK; + RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); + + if( rc ) return rc; + if( p==0 ) return SQLITE_OK; + if( i==0 && sqlite3_vtab_nochange(ctx) ) return SQLITE_OK; + if( i<=pRtree->nAux ){ + if( !pCsr->bAuxValid ){ + if( pCsr->pReadAux==0 ){ + rc = sqlite3_prepare_v3(pRtree->db, pRtree->zReadAuxSql, -1, 0, + &pCsr->pReadAux, 0); + if( rc ) return rc; + } + sqlite3_bind_int64(pCsr->pReadAux, 1, + nodeGetRowid(pRtree, pNode, p->iCell)); + rc = sqlite3_step(pCsr->pReadAux); + if( rc==SQLITE_ROW ){ + pCsr->bAuxValid = 1; + }else{ + sqlite3_reset(pCsr->pReadAux); + if( rc==SQLITE_DONE ) rc = SQLITE_OK; + return rc; + } + } + sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pReadAux, i+2)); + } + return SQLITE_OK; +} + + +/* +** The xUpdate method for GEOPOLY module virtual tables. +** +** For DELETE: +** +** argv[0] = the rowid to be deleted +** +** For INSERT: +** +** argv[0] = SQL NULL +** argv[1] = rowid to insert, or an SQL NULL to select automatically +** argv[2] = _shape column +** argv[3] = first application-defined column.... +** +** For UPDATE: +** +** argv[0] = rowid to modify. Never NULL +** argv[1] = rowid after the change. Never NULL +** argv[2] = new value for _shape +** argv[3] = new value for first application-defined column.... +*/ +static int geopolyUpdate( + sqlite3_vtab *pVtab, + int nData, + sqlite3_value **aData, + sqlite_int64 *pRowid +){ + Rtree *pRtree = (Rtree *)pVtab; + int rc = SQLITE_OK; + RtreeCell cell; /* New cell to insert if nData>1 */ + i64 oldRowid; /* The old rowid */ + int oldRowidValid; /* True if oldRowid is valid */ + i64 newRowid; /* The new rowid */ + int newRowidValid; /* True if newRowid is valid */ + int coordChange = 0; /* Change in coordinates */ + + if( pRtree->nNodeRef ){ + /* Unable to write to the btree while another cursor is reading from it, + ** since the write might do a rebalance which would disrupt the read + ** cursor. */ + return SQLITE_LOCKED_VTAB; + } + rtreeReference(pRtree); + assert(nData>=1); + + oldRowidValid = sqlite3_value_type(aData[0])!=SQLITE_NULL;; + oldRowid = oldRowidValid ? sqlite3_value_int64(aData[0]) : 0; + newRowidValid = nData>1 && sqlite3_value_type(aData[1])!=SQLITE_NULL; + newRowid = newRowidValid ? sqlite3_value_int64(aData[1]) : 0; + cell.iRowid = newRowid; + + if( nData>1 /* not a DELETE */ + && (!oldRowidValid /* INSERT */ + || !sqlite3_value_nochange(aData[2]) /* UPDATE _shape */ + || oldRowid!=newRowid) /* Rowid change */ + ){ + assert( aData[2]!=0 ); + geopolyBBox(0, aData[2], cell.aCoord, &rc); + if( rc ){ + if( rc==SQLITE_ERROR ){ + pVtab->zErrMsg = + sqlite3_mprintf("_shape does not contain a valid polygon"); + } + goto geopoly_update_end; + } + coordChange = 1; + + /* If a rowid value was supplied, check if it is already present in + ** the table. If so, the constraint has failed. */ + if( newRowidValid && (!oldRowidValid || oldRowid!=newRowid) ){ + int steprc; + sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid); + steprc = sqlite3_step(pRtree->pReadRowid); + rc = sqlite3_reset(pRtree->pReadRowid); + if( SQLITE_ROW==steprc ){ + if( sqlite3_vtab_on_conflict(pRtree->db)==SQLITE_REPLACE ){ + rc = rtreeDeleteRowid(pRtree, cell.iRowid); + }else{ + rc = rtreeConstraintError(pRtree, 0); + } + } + } + } + + /* If aData[0] is not an SQL NULL value, it is the rowid of a + ** record to delete from the r-tree table. The following block does + ** just that. + */ + if( rc==SQLITE_OK && (nData==1 || (coordChange && oldRowidValid)) ){ + rc = rtreeDeleteRowid(pRtree, oldRowid); + } + + /* If the aData[] array contains more than one element, elements + ** (aData[2]..aData[argc-1]) contain a new record to insert into + ** the r-tree structure. + */ + if( rc==SQLITE_OK && nData>1 && coordChange ){ + /* Insert the new record into the r-tree */ + RtreeNode *pLeaf = 0; + if( !newRowidValid ){ + rc = rtreeNewRowid(pRtree, &cell.iRowid); + } + *pRowid = cell.iRowid; + if( rc==SQLITE_OK ){ + rc = ChooseLeaf(pRtree, &cell, 0, &pLeaf); + } + if( rc==SQLITE_OK ){ + int rc2; + rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0); + rc2 = nodeRelease(pRtree, pLeaf); + if( rc==SQLITE_OK ){ + rc = rc2; + } + } + } + + /* Change the data */ + if( rc==SQLITE_OK && nData>1 ){ + sqlite3_stmt *pUp = pRtree->pWriteAux; + int jj; + int nChange = 0; + sqlite3_bind_int64(pUp, 1, cell.iRowid); + assert( pRtree->nAux>=1 ); + if( sqlite3_value_nochange(aData[2]) ){ + sqlite3_bind_null(pUp, 2); + }else{ + GeoPoly *p = 0; + if( sqlite3_value_type(aData[2])==SQLITE_TEXT + && (p = geopolyFuncParam(0, aData[2], &rc))!=0 + && rc==SQLITE_OK + ){ + sqlite3_bind_blob(pUp, 2, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT); + }else{ + sqlite3_bind_value(pUp, 2, aData[2]); + } + sqlite3_free(p); + nChange = 1; + } + for(jj=1; jjxDestructor ) pInfo->xDestructor(pInfo->pContext); + sqlite3_free(p); +} + +/* +** This routine frees the BLOB that is returned by geomCallback(). +*/ +static void rtreeMatchArgFree(void *pArg){ + int i; + RtreeMatchArg *p = (RtreeMatchArg*)pArg; + for(i=0; inParam; i++){ + sqlite3_value_free(p->apSqlParam[i]); + } + sqlite3_free(p); +} + +/* +** Each call to sqlite3_rtree_geometry_callback() or +** sqlite3_rtree_query_callback() creates an ordinary SQLite +** scalar function that is implemented by this routine. +** +** All this function does is construct an RtreeMatchArg object that +** contains the geometry-checking callback routines and a list of +** parameters to this function, then return that RtreeMatchArg object +** as a BLOB. +** +** The R-Tree MATCH operator will read the returned BLOB, deserialize +** the RtreeMatchArg object, and use the RtreeMatchArg object to figure +** out which elements of the R-Tree should be returned by the query. +*/ +static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){ + RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx); + RtreeMatchArg *pBlob; + sqlite3_int64 nBlob; + int memErr = 0; + + nBlob = SZ_RTREEMATCHARG(nArg) + nArg*sizeof(sqlite3_value*); + pBlob = (RtreeMatchArg *)sqlite3_malloc64(nBlob); + if( !pBlob ){ + sqlite3_result_error_nomem(ctx); + }else{ + int i; + pBlob->iSize = nBlob; + pBlob->cb = pGeomCtx[0]; + pBlob->apSqlParam = (sqlite3_value**)&pBlob->aParam[nArg]; + pBlob->nParam = nArg; + for(i=0; iapSqlParam[i] = sqlite3_value_dup(aArg[i]); + if( pBlob->apSqlParam[i]==0 ) memErr = 1; +#ifdef SQLITE_RTREE_INT_ONLY + pBlob->aParam[i] = sqlite3_value_int64(aArg[i]); +#else + pBlob->aParam[i] = sqlite3_value_double(aArg[i]); +#endif + } + if( memErr ){ + sqlite3_result_error_nomem(ctx); + rtreeMatchArgFree(pBlob); + }else{ + sqlite3_result_pointer(ctx, pBlob, "RtreeMatchArg", rtreeMatchArgFree); + } + } +} + +/* +** Register a new geometry function for use with the r-tree MATCH operator. +*/ +SQLITE_API int sqlite3_rtree_geometry_callback( + sqlite3 *db, /* Register SQL function on this connection */ + const char *zGeom, /* Name of the new SQL function */ + int (*xGeom)(sqlite3_rtree_geometry*,int,RtreeDValue*,int*), /* Callback */ + void *pContext /* Extra data associated with the callback */ +){ + RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */ + + /* Allocate and populate the context object. */ + pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback)); + if( !pGeomCtx ) return SQLITE_NOMEM; + pGeomCtx->xGeom = xGeom; + pGeomCtx->xQueryFunc = 0; + pGeomCtx->xDestructor = 0; + pGeomCtx->pContext = pContext; + return sqlite3_create_function_v2(db, zGeom, -1, SQLITE_ANY, + (void *)pGeomCtx, geomCallback, 0, 0, rtreeFreeCallback + ); +} + +/* +** Register a new 2nd-generation geometry function for use with the +** r-tree MATCH operator. +*/ +SQLITE_API int sqlite3_rtree_query_callback( + sqlite3 *db, /* Register SQL function on this connection */ + const char *zQueryFunc, /* Name of new SQL function */ + int (*xQueryFunc)(sqlite3_rtree_query_info*), /* Callback */ + void *pContext, /* Extra data passed into the callback */ + void (*xDestructor)(void*) /* Destructor for the extra data */ +){ + RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */ + + /* Allocate and populate the context object. */ + pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback)); + if( !pGeomCtx ){ + if( xDestructor ) xDestructor(pContext); + return SQLITE_NOMEM; + } + pGeomCtx->xGeom = 0; + pGeomCtx->xQueryFunc = xQueryFunc; + pGeomCtx->xDestructor = xDestructor; + pGeomCtx->pContext = pContext; + return sqlite3_create_function_v2(db, zQueryFunc, -1, SQLITE_ANY, + (void *)pGeomCtx, geomCallback, 0, 0, rtreeFreeCallback + ); +} + +#ifndef SQLITE_CORE +#ifdef _WIN32 +__declspec(dllexport) +#endif +SQLITE_API int sqlite3_rtree_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + SQLITE_EXTENSION_INIT2(pApi) + return sqlite3RtreeInit(db); +} +#endif + +#endif + +/************** End of rtree.c ***********************************************/ +/************** Begin file icu.c *********************************************/ +/* +** 2007 May 6 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** $Id: icu.c,v 1.7 2007/12/13 21:54:11 drh Exp $ +** +** This file implements an integration between the ICU library +** ("International Components for Unicode", an open-source library +** for handling unicode data) and SQLite. The integration uses +** ICU to provide the following to SQLite: +** +** * An implementation of the SQL regexp() function (and hence REGEXP +** operator) using the ICU uregex_XX() APIs. +** +** * Implementations of the SQL scalar upper() and lower() functions +** for case mapping. +** +** * Integration of ICU and SQLite collation sequences. +** +** * An implementation of the LIKE operator that uses ICU to +** provide case-independent matching. +*/ + +#if !defined(SQLITE_CORE) \ + || defined(SQLITE_ENABLE_ICU) \ + || defined(SQLITE_ENABLE_ICU_COLLATIONS) + +/* Include ICU headers */ +#include +#include +#include +#include + +/* #include */ + +#ifndef SQLITE_CORE +/* #include "sqlite3ext.h" */ + SQLITE_EXTENSION_INIT1 +#else +/* #include "sqlite3.h" */ +#endif + +/* +** This function is called when an ICU function called from within +** the implementation of an SQL scalar function returns an error. +** +** The scalar function context passed as the first argument is +** loaded with an error message based on the following two args. +*/ +static void icuFunctionError( + sqlite3_context *pCtx, /* SQLite scalar function context */ + const char *zName, /* Name of ICU function that failed */ + UErrorCode e /* Error code returned by ICU function */ +){ + char zBuf[128]; + sqlite3_snprintf(128, zBuf, "ICU error: %s(): %s", zName, u_errorName(e)); + zBuf[127] = '\0'; + sqlite3_result_error(pCtx, zBuf, -1); +} + +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) + +/* +** Maximum length (in bytes) of the pattern in a LIKE or GLOB +** operator. +*/ +#ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH +# define SQLITE_MAX_LIKE_PATTERN_LENGTH 50000 +#endif + +/* +** Version of sqlite3_free() that is always a function, never a macro. +*/ +static void xFree(void *p){ + sqlite3_free(p); +} + +/* +** This lookup table is used to help decode the first byte of +** a multi-byte UTF8 character. It is copied here from SQLite source +** code file utf8.c. +*/ +static const unsigned char icuUtf8Trans1[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00, +}; + +#define SQLITE_ICU_READ_UTF8(zIn, c) \ + c = *(zIn++); \ + if( c>=0xc0 ){ \ + c = icuUtf8Trans1[c-0xc0]; \ + while( (*zIn & 0xc0)==0x80 ){ \ + c = (c<<6) + (0x3f & *(zIn++)); \ + } \ + } + +#define SQLITE_ICU_SKIP_UTF8(zIn) \ + assert( *zIn ); \ + if( *(zIn++)>=0xc0 ){ \ + while( (*zIn & 0xc0)==0x80 ){zIn++;} \ + } + + +/* +** Compare two UTF-8 strings for equality where the first string is +** a "LIKE" expression. Return true (1) if they are the same and +** false (0) if they are different. +*/ +static int icuLikeCompare( + const uint8_t *zPattern, /* LIKE pattern */ + const uint8_t *zString, /* The UTF-8 string to compare against */ + const UChar32 uEsc /* The escape character */ +){ + static const uint32_t MATCH_ONE = (uint32_t)'_'; + static const uint32_t MATCH_ALL = (uint32_t)'%'; + + int prevEscape = 0; /* True if the previous character was uEsc */ + + while( 1 ){ + + /* Read (and consume) the next character from the input pattern. */ + uint32_t uPattern; + SQLITE_ICU_READ_UTF8(zPattern, uPattern); + if( uPattern==0 ) break; + + /* There are now 4 possibilities: + ** + ** 1. uPattern is an unescaped match-all character "%", + ** 2. uPattern is an unescaped match-one character "_", + ** 3. uPattern is an unescaped escape character, or + ** 4. uPattern is to be handled as an ordinary character + */ + if( uPattern==MATCH_ALL && !prevEscape && uPattern!=(uint32_t)uEsc ){ + /* Case 1. */ + uint8_t c; + + /* Skip any MATCH_ALL or MATCH_ONE characters that follow a + ** MATCH_ALL. For each MATCH_ONE, skip one character in the + ** test string. + */ + while( (c=*zPattern) == MATCH_ALL || c == MATCH_ONE ){ + if( c==MATCH_ONE ){ + if( *zString==0 ) return 0; + SQLITE_ICU_SKIP_UTF8(zString); + } + zPattern++; + } + + if( *zPattern==0 ) return 1; + + while( *zString ){ + if( icuLikeCompare(zPattern, zString, uEsc) ){ + return 1; + } + SQLITE_ICU_SKIP_UTF8(zString); + } + return 0; + + }else if( uPattern==MATCH_ONE && !prevEscape && uPattern!=(uint32_t)uEsc ){ + /* Case 2. */ + if( *zString==0 ) return 0; + SQLITE_ICU_SKIP_UTF8(zString); + + }else if( uPattern==(uint32_t)uEsc && !prevEscape ){ + /* Case 3. */ + prevEscape = 1; + + }else{ + /* Case 4. */ + uint32_t uString; + SQLITE_ICU_READ_UTF8(zString, uString); + uString = (uint32_t)u_foldCase((UChar32)uString, U_FOLD_CASE_DEFAULT); + uPattern = (uint32_t)u_foldCase((UChar32)uPattern, U_FOLD_CASE_DEFAULT); + if( uString!=uPattern ){ + return 0; + } + prevEscape = 0; + } + } + + return *zString==0; +} + +/* +** Implementation of the like() SQL function. This function implements +** the build-in LIKE operator. The first argument to the function is the +** pattern and the second argument is the string. So, the SQL statements: +** +** A LIKE B +** +** is implemented as like(B, A). If there is an escape character E, +** +** A LIKE B ESCAPE E +** +** is mapped to like(B, A, E). +*/ +static void icuLikeFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const unsigned char *zA = sqlite3_value_text(argv[0]); + const unsigned char *zB = sqlite3_value_text(argv[1]); + UChar32 uEsc = 0; + + /* Limit the length of the LIKE or GLOB pattern to avoid problems + ** of deep recursion and N*N behavior in patternCompare(). + */ + if( sqlite3_value_bytes(argv[0])>SQLITE_MAX_LIKE_PATTERN_LENGTH ){ + sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1); + return; + } + + + if( argc==3 ){ + /* The escape character string must consist of a single UTF-8 character. + ** Otherwise, return an error. + */ + int nE= sqlite3_value_bytes(argv[2]); + const unsigned char *zE = sqlite3_value_text(argv[2]); + int i = 0; + if( zE==0 ) return; + U8_NEXT(zE, i, nE, uEsc); + if( i!=nE){ + sqlite3_result_error(context, + "ESCAPE expression must be a single character", -1); + return; + } + } + + if( zA && zB ){ + sqlite3_result_int(context, icuLikeCompare(zA, zB, uEsc)); + } +} + +/* +** Function to delete compiled regexp objects. Registered as +** a destructor function with sqlite3_set_auxdata(). +*/ +static void icuRegexpDelete(void *p){ + URegularExpression *pExpr = (URegularExpression *)p; + uregex_close(pExpr); +} + +/* +** Implementation of SQLite REGEXP operator. This scalar function takes +** two arguments. The first is a regular expression pattern to compile +** the second is a string to match against that pattern. If either +** argument is an SQL NULL, then NULL Is returned. Otherwise, the result +** is 1 if the string matches the pattern, or 0 otherwise. +** +** SQLite maps the regexp() function to the regexp() operator such +** that the following two are equivalent: +** +** zString REGEXP zPattern +** regexp(zPattern, zString) +** +** Uses the following ICU regexp APIs: +** +** uregex_open() +** uregex_matches() +** uregex_close() +*/ +static void icuRegexpFunc(sqlite3_context *p, int nArg, sqlite3_value **apArg){ + UErrorCode status = U_ZERO_ERROR; + URegularExpression *pExpr; + UBool res; + const UChar *zString = sqlite3_value_text16(apArg[1]); + + (void)nArg; /* Unused parameter */ + + /* If the left hand side of the regexp operator is NULL, + ** then the result is also NULL. + */ + if( !zString ){ + return; + } + + pExpr = sqlite3_get_auxdata(p, 0); + if( !pExpr ){ + const UChar *zPattern = sqlite3_value_text16(apArg[0]); + if( !zPattern ){ + return; + } + pExpr = uregex_open(zPattern, -1, 0, 0, &status); + + if( U_SUCCESS(status) ){ + sqlite3_set_auxdata(p, 0, pExpr, icuRegexpDelete); + pExpr = sqlite3_get_auxdata(p, 0); + } + if( !pExpr ){ + icuFunctionError(p, "uregex_open", status); + return; + } + } + + /* Configure the text that the regular expression operates on. */ + uregex_setText(pExpr, zString, -1, &status); + if( !U_SUCCESS(status) ){ + icuFunctionError(p, "uregex_setText", status); + return; + } + + /* Attempt the match */ + res = uregex_matches(pExpr, 0, &status); + if( !U_SUCCESS(status) ){ + icuFunctionError(p, "uregex_matches", status); + return; + } + + /* Set the text that the regular expression operates on to a NULL + ** pointer. This is not really necessary, but it is tidier than + ** leaving the regular expression object configured with an invalid + ** pointer after this function returns. + */ + uregex_setText(pExpr, 0, 0, &status); + + /* Return 1 or 0. */ + sqlite3_result_int(p, res ? 1 : 0); +} + +/* +** Implementations of scalar functions for case mapping - upper() and +** lower(). Function upper() converts its input to upper-case (ABC). +** Function lower() converts to lower-case (abc). +** +** ICU provides two types of case mapping, "general" case mapping and +** "language specific". Refer to ICU documentation for the differences +** between the two. +** +** To utilise "general" case mapping, the upper() or lower() scalar +** functions are invoked with one argument: +** +** upper('ABC') -> 'abc' +** lower('abc') -> 'ABC' +** +** To access ICU "language specific" case mapping, upper() or lower() +** should be invoked with two arguments. The second argument is the name +** of the locale to use. Passing an empty string ("") or SQL NULL value +** as the second argument is the same as invoking the 1 argument version +** of upper() or lower(). +** +** lower('I', 'en_us') -> 'i' +** lower('I', 'tr_tr') -> '\u131' (small dotless i) +** +** http://www.icu-project.org/userguide/posix.html#case_mappings +*/ +static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){ + const UChar *zInput; /* Pointer to input string */ + UChar *zOutput = 0; /* Pointer to output buffer */ + int nInput; /* Size of utf-16 input string in bytes */ + sqlite3_int64 nOut; /* Size of output buffer in bytes */ + int cnt; + int bToUpper; /* True for toupper(), false for tolower() */ + UErrorCode status; + const char *zLocale = 0; + + assert(nArg==1 || nArg==2); + bToUpper = (sqlite3_user_data(p)!=0); + if( nArg==2 ){ + zLocale = (const char *)sqlite3_value_text(apArg[1]); + } + + zInput = sqlite3_value_text16(apArg[0]); + if( !zInput ){ + return; + } + nOut = nInput = sqlite3_value_bytes16(apArg[0]); + if( nOut==0 ){ + sqlite3_result_text16(p, "", 0, SQLITE_STATIC); + return; + } + + for(cnt=0; cnt<2; cnt++){ + UChar *zNew = sqlite3_realloc64(zOutput, nOut); + if( zNew==0 ){ + sqlite3_free(zOutput); + sqlite3_result_error_nomem(p); + return; + } + zOutput = zNew; + status = U_ZERO_ERROR; + if( bToUpper ){ + nOut = 2LL*u_strToUpper(zOutput,nOut/2,zInput,nInput/2,zLocale,&status); + }else{ + nOut = 2LL*u_strToLower(zOutput,nOut/2,zInput,nInput/2,zLocale,&status); + } + + if( U_SUCCESS(status) ){ + sqlite3_result_text16(p, zOutput, nOut, xFree); + }else if( status==U_BUFFER_OVERFLOW_ERROR ){ + assert( cnt==0 ); + continue; + }else{ + icuFunctionError(p, bToUpper ? "u_strToUpper" : "u_strToLower", status); + } + return; + } + assert( 0 ); /* Unreachable */ +} + +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) */ + +/* +** Collation sequence destructor function. The pCtx argument points to +** a UCollator structure previously allocated using ucol_open(). +*/ +static void icuCollationDel(void *pCtx){ + UCollator *p = (UCollator *)pCtx; + ucol_close(p); +} + +/* +** Collation sequence comparison function. The pCtx argument points to +** a UCollator structure previously allocated using ucol_open(). +*/ +static int icuCollationColl( + void *pCtx, + int nLeft, + const void *zLeft, + int nRight, + const void *zRight +){ + UCollationResult res; + UCollator *p = (UCollator *)pCtx; + res = ucol_strcoll(p, (UChar *)zLeft, nLeft/2, (UChar *)zRight, nRight/2); + switch( res ){ + case UCOL_LESS: return -1; + case UCOL_GREATER: return +1; + case UCOL_EQUAL: return 0; + } + assert(!"Unexpected return value from ucol_strcoll()"); + return 0; +} + +/* +** Implementation of the scalar function icu_load_collation(). +** +** This scalar function is used to add ICU collation based collation +** types to an SQLite database connection. It is intended to be called +** as follows: +** +** SELECT icu_load_collation(, ); +** +** Where is a string containing an ICU locale identifier (i.e. +** "en_AU", "tr_TR" etc.) and is the name of the +** collation sequence to create. +*/ +static void icuLoadCollation( + sqlite3_context *p, + int nArg, + sqlite3_value **apArg +){ + sqlite3 *db = (sqlite3 *)sqlite3_user_data(p); + UErrorCode status = U_ZERO_ERROR; + const char *zLocale; /* Locale identifier - (eg. "jp_JP") */ + const char *zName; /* SQL Collation sequence name (eg. "japanese") */ + UCollator *pUCollator; /* ICU library collation object */ + int rc; /* Return code from sqlite3_create_collation_x() */ + + assert(nArg==2 || nArg==3); + (void)nArg; /* Unused parameter */ + zLocale = (const char *)sqlite3_value_text(apArg[0]); + zName = (const char *)sqlite3_value_text(apArg[1]); + + if( !zLocale || !zName ){ + return; + } + + pUCollator = ucol_open(zLocale, &status); + if( !U_SUCCESS(status) ){ + icuFunctionError(p, "ucol_open", status); + return; + } + assert(p); + if(nArg==3){ + const char *zOption = (const char*)sqlite3_value_text(apArg[2]); + static const struct { + const char *zName; + UColAttributeValue val; + } aStrength[] = { + { "PRIMARY", UCOL_PRIMARY }, + { "SECONDARY", UCOL_SECONDARY }, + { "TERTIARY", UCOL_TERTIARY }, + { "DEFAULT", UCOL_DEFAULT_STRENGTH }, + { "QUARTERNARY", UCOL_QUATERNARY }, + { "IDENTICAL", UCOL_IDENTICAL }, + }; + unsigned int i; + for(i=0; i=sizeof(aStrength)/sizeof(aStrength[0]) ){ + sqlite3_str *pStr = sqlite3_str_new(sqlite3_context_db_handle(p)); + sqlite3_str_appendf(pStr, + "unknown collation strength \"%s\" - should be one of:", + zOption); + for(i=0; izName, p->nArg, p->enc, + p->iContext ? (void*)db : (void*)0, + p->xFunc, 0, 0 + ); + } + + return rc; +} + +#ifndef SQLITE_CORE +#ifdef _WIN32 +__declspec(dllexport) +#endif +SQLITE_API int sqlite3_icu_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + SQLITE_EXTENSION_INIT2(pApi) + return sqlite3IcuInit(db); +} +#endif + +#endif + +/************** End of icu.c *************************************************/ +/************** Begin file fts3_icu.c ****************************************/ +/* +** 2007 June 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file implements a tokenizer for fts3 based on the ICU library. +*/ +/* #include "fts3Int.h" */ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) +#ifdef SQLITE_ENABLE_ICU + +/* #include */ +/* #include */ +/* #include "fts3_tokenizer.h" */ + +#include +/* #include */ +/* #include */ +#include + +typedef struct IcuTokenizer IcuTokenizer; +typedef struct IcuCursor IcuCursor; + +struct IcuTokenizer { + sqlite3_tokenizer base; + char *zLocale; +}; + +struct IcuCursor { + sqlite3_tokenizer_cursor base; + + UBreakIterator *pIter; /* ICU break-iterator object */ + int nChar; /* Number of UChar elements in pInput */ + UChar *aChar; /* Copy of input using utf-16 encoding */ + int *aOffset; /* Offsets of each character in utf-8 input */ + + int nBuffer; + char *zBuffer; + + int iToken; +}; + +/* +** Create a new tokenizer instance. +*/ +static int icuCreate( + int argc, /* Number of entries in argv[] */ + const char * const *argv, /* Tokenizer creation arguments */ + sqlite3_tokenizer **ppTokenizer /* OUT: Created tokenizer */ +){ + IcuTokenizer *p; + int n = 0; + + if( argc>0 ){ + n = strlen(argv[0])+1; + } + p = (IcuTokenizer *)sqlite3_malloc64(sizeof(IcuTokenizer)+n); + if( !p ){ + return SQLITE_NOMEM; + } + memset(p, 0, sizeof(IcuTokenizer)); + + if( n ){ + p->zLocale = (char *)&p[1]; + memcpy(p->zLocale, argv[0], n); + } + + *ppTokenizer = (sqlite3_tokenizer *)p; + + return SQLITE_OK; +} + +/* +** Destroy a tokenizer +*/ +static int icuDestroy(sqlite3_tokenizer *pTokenizer){ + IcuTokenizer *p = (IcuTokenizer *)pTokenizer; + sqlite3_free(p); + return SQLITE_OK; +} + +/* +** Prepare to begin tokenizing a particular string. The input +** string to be tokenized is pInput[0..nBytes-1]. A cursor +** used to incrementally tokenize this string is returned in +** *ppCursor. +*/ +static int icuOpen( + sqlite3_tokenizer *pTokenizer, /* The tokenizer */ + const char *zInput, /* Input string */ + int nInput, /* Length of zInput in bytes */ + sqlite3_tokenizer_cursor **ppCursor /* OUT: Tokenization cursor */ +){ + IcuTokenizer *p = (IcuTokenizer *)pTokenizer; + IcuCursor *pCsr; + + const int32_t opt = U_FOLD_CASE_DEFAULT; + UErrorCode status = U_ZERO_ERROR; + int nChar; + + UChar32 c; + int iInput = 0; + int iOut = 0; + + *ppCursor = 0; + + if( zInput==0 ){ + nInput = 0; + zInput = ""; + }else if( nInput<0 ){ + nInput = strlen(zInput); + } + nChar = nInput+1; + pCsr = (IcuCursor *)sqlite3_malloc64( + sizeof(IcuCursor) + /* IcuCursor */ + ((nChar+3)&~3) * sizeof(UChar) + /* IcuCursor.aChar[] */ + (nChar+1) * sizeof(int) /* IcuCursor.aOffset[] */ + ); + if( !pCsr ){ + return SQLITE_NOMEM; + } + memset(pCsr, 0, sizeof(IcuCursor)); + pCsr->aChar = (UChar *)&pCsr[1]; + pCsr->aOffset = (int *)&pCsr->aChar[(nChar+3)&~3]; + + pCsr->aOffset[iOut] = iInput; + U8_NEXT(zInput, iInput, nInput, c); + while( c>0 ){ + int isError = 0; + c = u_foldCase(c, opt); + U16_APPEND(pCsr->aChar, iOut, nChar, c, isError); + if( isError ){ + sqlite3_free(pCsr); + return SQLITE_ERROR; + } + pCsr->aOffset[iOut] = iInput; + + if( iInputpIter = ubrk_open(UBRK_WORD, p->zLocale, pCsr->aChar, iOut, &status); + if( !U_SUCCESS(status) ){ + sqlite3_free(pCsr); + return SQLITE_ERROR; + } + pCsr->nChar = iOut; + + ubrk_first(pCsr->pIter); + *ppCursor = (sqlite3_tokenizer_cursor *)pCsr; + return SQLITE_OK; +} + +/* +** Close a tokenization cursor previously opened by a call to icuOpen(). +*/ +static int icuClose(sqlite3_tokenizer_cursor *pCursor){ + IcuCursor *pCsr = (IcuCursor *)pCursor; + ubrk_close(pCsr->pIter); + sqlite3_free(pCsr->zBuffer); + sqlite3_free(pCsr); + return SQLITE_OK; +} + +/* +** Extract the next token from a tokenization cursor. +*/ +static int icuNext( + sqlite3_tokenizer_cursor *pCursor, /* Cursor returned by simpleOpen */ + const char **ppToken, /* OUT: *ppToken is the token text */ + int *pnBytes, /* OUT: Number of bytes in token */ + int *piStartOffset, /* OUT: Starting offset of token */ + int *piEndOffset, /* OUT: Ending offset of token */ + int *piPosition /* OUT: Position integer of token */ +){ + IcuCursor *pCsr = (IcuCursor *)pCursor; + + int iStart = 0; + int iEnd = 0; + int nByte = 0; + + while( iStart==iEnd ){ + UChar32 c; + + iStart = ubrk_current(pCsr->pIter); + iEnd = ubrk_next(pCsr->pIter); + if( iEnd==UBRK_DONE ){ + return SQLITE_DONE; + } + + while( iStartaChar, iWhite, pCsr->nChar, c); + if( u_isspace(c) ){ + iStart = iWhite; + }else{ + break; + } + } + assert(iStart<=iEnd); + } + + do { + UErrorCode status = U_ZERO_ERROR; + if( nByte ){ + char *zNew = sqlite3_realloc(pCsr->zBuffer, nByte); + if( !zNew ){ + return SQLITE_NOMEM; + } + pCsr->zBuffer = zNew; + pCsr->nBuffer = nByte; + } + + u_strToUTF8( + pCsr->zBuffer, pCsr->nBuffer, &nByte, /* Output vars */ + &pCsr->aChar[iStart], iEnd-iStart, /* Input vars */ + &status /* Output success/failure */ + ); + } while( nByte>pCsr->nBuffer ); + + *ppToken = pCsr->zBuffer; + *pnBytes = nByte; + *piStartOffset = pCsr->aOffset[iStart]; + *piEndOffset = pCsr->aOffset[iEnd]; + *piPosition = pCsr->iToken++; + + return SQLITE_OK; +} + +/* +** The set of routines that implement the simple tokenizer +*/ +static const sqlite3_tokenizer_module icuTokenizerModule = { + 0, /* iVersion */ + icuCreate, /* xCreate */ + icuDestroy, /* xCreate */ + icuOpen, /* xOpen */ + icuClose, /* xClose */ + icuNext, /* xNext */ + 0, /* xLanguageid */ +}; + +/* +** Set *ppModule to point at the implementation of the ICU tokenizer. +*/ +SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule( + sqlite3_tokenizer_module const**ppModule +){ + *ppModule = &icuTokenizerModule; +} + +#endif /* defined(SQLITE_ENABLE_ICU) */ +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ + +/************** End of fts3_icu.c ********************************************/ +/************** Begin file sqlite3rbu.c **************************************/ +/* +** 2014 August 30 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** +** OVERVIEW +** +** The RBU extension requires that the RBU update be packaged as an +** SQLite database. The tables it expects to find are described in +** sqlite3rbu.h. Essentially, for each table xyz in the target database +** that the user wishes to write to, a corresponding data_xyz table is +** created in the RBU database and populated with one row for each row to +** update, insert or delete from the target table. +** +** The update proceeds in three stages: +** +** 1) The database is updated. The modified database pages are written +** to a *-oal file. A *-oal file is just like a *-wal file, except +** that it is named "-oal" instead of "-wal". +** Because regular SQLite clients do not look for file named +** "-oal", they go on using the original database in +** rollback mode while the *-oal file is being generated. +** +** During this stage RBU does not update the database by writing +** directly to the target tables. Instead it creates "imposter" +** tables using the SQLITE_TESTCTRL_IMPOSTER interface that it uses +** to update each b-tree individually. All updates required by each +** b-tree are completed before moving on to the next, and all +** updates are done in sorted key order. +** +** 2) The "-oal" file is moved to the equivalent "-wal" +** location using a call to rename(2). Before doing this the RBU +** module takes an EXCLUSIVE lock on the database file, ensuring +** that there are no other active readers. +** +** Once the EXCLUSIVE lock is released, any other database readers +** detect the new *-wal file and read the database in wal mode. At +** this point they see the new version of the database - including +** the updates made as part of the RBU update. +** +** 3) The new *-wal file is checkpointed. This proceeds in the same way +** as a regular database checkpoint, except that a single frame is +** checkpointed each time sqlite3rbu_step() is called. If the RBU +** handle is closed before the entire *-wal file is checkpointed, +** the checkpoint progress is saved in the RBU database and the +** checkpoint can be resumed by another RBU client at some point in +** the future. +** +** POTENTIAL PROBLEMS +** +** The rename() call might not be portable. And RBU is not currently +** syncing the directory after renaming the file. +** +** When state is saved, any commit to the *-oal file and the commit to +** the RBU update database are not atomic. So if the power fails at the +** wrong moment they might get out of sync. As the main database will be +** committed before the RBU update database this will likely either just +** pass unnoticed, or result in SQLITE_CONSTRAINT errors (due to UNIQUE +** constraint violations). +** +** If some client does modify the target database mid RBU update, or some +** other error occurs, the RBU extension will keep throwing errors. It's +** not really clear how to get out of this state. The system could just +** by delete the RBU update database and *-oal file and have the device +** download the update again and start over. +** +** At present, for an UPDATE, both the new.* and old.* records are +** collected in the rbu_xyz table. And for both UPDATEs and DELETEs all +** fields are collected. This means we're probably writing a lot more +** data to disk when saving the state of an ongoing update to the RBU +** update database than is strictly necessary. +** +*/ + +/* #include */ +/* #include */ +/* #include */ + +/* #include "sqlite3.h" */ + +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU) +/************** Include sqlite3rbu.h in the middle of sqlite3rbu.c ***********/ +/************** Begin file sqlite3rbu.h **************************************/ +/* +** 2014 August 30 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains the public interface for the RBU extension. +*/ + +/* +** SUMMARY +** +** Writing a transaction containing a large number of operations on +** b-tree indexes that are collectively larger than the available cache +** memory can be very inefficient. +** +** The problem is that in order to update a b-tree, the leaf page (at least) +** containing the entry being inserted or deleted must be modified. If the +** working set of leaves is larger than the available cache memory, then a +** single leaf that is modified more than once as part of the transaction +** may be loaded from or written to the persistent media multiple times. +** Additionally, because the index updates are likely to be applied in +** random order, access to pages within the database is also likely to be in +** random order, which is itself quite inefficient. +** +** One way to improve the situation is to sort the operations on each index +** by index key before applying them to the b-tree. This leads to an IO +** pattern that resembles a single linear scan through the index b-tree, +** and all but guarantees each modified leaf page is loaded and stored +** exactly once. SQLite uses this trick to improve the performance of +** CREATE INDEX commands. This extension allows it to be used to improve +** the performance of large transactions on existing databases. +** +** Additionally, this extension allows the work involved in writing the +** large transaction to be broken down into sub-transactions performed +** sequentially by separate processes. This is useful if the system cannot +** guarantee that a single update process will run for long enough to apply +** the entire update, for example because the update is being applied on a +** mobile device that is frequently rebooted. Even after the writer process +** has committed one or more sub-transactions, other database clients continue +** to read from the original database snapshot. In other words, partially +** applied transactions are not visible to other clients. +** +** "RBU" stands for "Resumable Bulk Update". As in a large database update +** transmitted via a wireless network to a mobile device. A transaction +** applied using this extension is hence referred to as an "RBU update". +** +** +** LIMITATIONS +** +** An "RBU update" transaction is subject to the following limitations: +** +** * The transaction must consist of INSERT, UPDATE and DELETE operations +** only. +** +** * INSERT statements may not use any default values. +** +** * UPDATE and DELETE statements must identify their target rows by +** non-NULL PRIMARY KEY values. Rows with NULL values stored in PRIMARY +** KEY fields may not be updated or deleted. If the table being written +** has no PRIMARY KEY, affected rows must be identified by rowid. +** +** * UPDATE statements may not modify PRIMARY KEY columns. +** +** * No triggers will be fired. +** +** * No foreign key violations are detected or reported. +** +** * CHECK constraints are not enforced. +** +** * No constraint handling mode except for "OR ROLLBACK" is supported. +** +** +** PREPARATION +** +** An "RBU update" is stored as a separate SQLite database. A database +** containing an RBU update is an "RBU database". For each table in the +** target database to be updated, the RBU database should contain a table +** named "data_" containing the same set of columns as the +** target table, and one more - "rbu_control". The data_% table should +** have no PRIMARY KEY or UNIQUE constraints, but each column should have +** the same type as the corresponding column in the target database. +** The "rbu_control" column should have no type at all. For example, if +** the target database contains: +** +** CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c UNIQUE); +** +** Then the RBU database should contain: +** +** CREATE TABLE data_t1(a INTEGER, b TEXT, c, rbu_control); +** +** The order of the columns in the data_% table does not matter. +** +** Instead of a regular table, the RBU database may also contain virtual +** tables or views named using the data_ naming scheme. +** +** Instead of the plain data_ naming scheme, RBU database tables +** may also be named data_, where is any sequence +** of zero or more numeric characters (0-9). This can be significant because +** tables within the RBU database are always processed in order sorted by +** name. By judicious selection of the portion of the names +** of the RBU tables the user can therefore control the order in which they +** are processed. This can be useful, for example, to ensure that "external +** content" FTS4 tables are updated before their underlying content tables. +** +** If the target database table is a virtual table or a table that has no +** PRIMARY KEY declaration, the data_% table must also contain a column +** named "rbu_rowid". This column is mapped to the table's implicit primary +** key column - "rowid". Virtual tables for which the "rowid" column does +** not function like a primary key value cannot be updated using RBU. For +** example, if the target db contains either of the following: +** +** CREATE VIRTUAL TABLE x1 USING fts3(a, b); +** CREATE TABLE x1(a, b) +** +** then the RBU database should contain: +** +** CREATE TABLE data_x1(a, b, rbu_rowid, rbu_control); +** +** All non-hidden columns (i.e. all columns matched by "SELECT *") of the +** target table must be present in the input table. For virtual tables, +** hidden columns are optional - they are updated by RBU if present in +** the input table, or not otherwise. For example, to write to an fts4 +** table with a hidden languageid column such as: +** +** CREATE VIRTUAL TABLE ft1 USING fts4(a, b, languageid='langid'); +** +** Either of the following input table schemas may be used: +** +** CREATE TABLE data_ft1(a, b, langid, rbu_rowid, rbu_control); +** CREATE TABLE data_ft1(a, b, rbu_rowid, rbu_control); +** +** For each row to INSERT into the target database as part of the RBU +** update, the corresponding data_% table should contain a single record +** with the "rbu_control" column set to contain integer value 0. The +** other columns should be set to the values that make up the new record +** to insert. +** +** If the target database table has an INTEGER PRIMARY KEY, it is not +** possible to insert a NULL value into the IPK column. Attempting to +** do so results in an SQLITE_MISMATCH error. +** +** For each row to DELETE from the target database as part of the RBU +** update, the corresponding data_% table should contain a single record +** with the "rbu_control" column set to contain integer value 1. The +** real primary key values of the row to delete should be stored in the +** corresponding columns of the data_% table. The values stored in the +** other columns are not used. +** +** For each row to UPDATE from the target database as part of the RBU +** update, the corresponding data_% table should contain a single record +** with the "rbu_control" column set to contain a value of type text. +** The real primary key values identifying the row to update should be +** stored in the corresponding columns of the data_% table row, as should +** the new values of all columns being update. The text value in the +** "rbu_control" column must contain the same number of characters as +** there are columns in the target database table, and must consist entirely +** of 'x' and '.' characters (or in some special cases 'd' - see below). For +** each column that is being updated, the corresponding character is set to +** 'x'. For those that remain as they are, the corresponding character of the +** rbu_control value should be set to '.'. For example, given the tables +** above, the update statement: +** +** UPDATE t1 SET c = 'usa' WHERE a = 4; +** +** is represented by the data_t1 row created by: +** +** INSERT INTO data_t1(a, b, c, rbu_control) VALUES(4, NULL, 'usa', '..x'); +** +** Instead of an 'x' character, characters of the rbu_control value specified +** for UPDATEs may also be set to 'd'. In this case, instead of updating the +** target table with the value stored in the corresponding data_% column, the +** user-defined SQL function "rbu_delta()" is invoked and the result stored in +** the target table column. rbu_delta() is invoked with two arguments - the +** original value currently stored in the target table column and the +** value specified in the data_xxx table. +** +** For example, this row: +** +** INSERT INTO data_t1(a, b, c, rbu_control) VALUES(4, NULL, 'usa', '..d'); +** +** is similar to an UPDATE statement such as: +** +** UPDATE t1 SET c = rbu_delta(c, 'usa') WHERE a = 4; +** +** Finally, if an 'f' character appears in place of a 'd' or 's' in an +** ota_control string, the contents of the data_xxx table column is assumed +** to be a "fossil delta" - a patch to be applied to a blob value in the +** format used by the fossil source-code management system. In this case +** the existing value within the target database table must be of type BLOB. +** It is replaced by the result of applying the specified fossil delta to +** itself. +** +** If the target database table is a virtual table or a table with no PRIMARY +** KEY, the rbu_control value should not include a character corresponding +** to the rbu_rowid value. For example, this: +** +** INSERT INTO data_ft1(a, b, rbu_rowid, rbu_control) +** VALUES(NULL, 'usa', 12, '.x'); +** +** causes a result similar to: +** +** UPDATE ft1 SET b = 'usa' WHERE rowid = 12; +** +** The data_xxx tables themselves should have no PRIMARY KEY declarations. +** However, RBU is more efficient if reading the rows in from each data_xxx +** table in "rowid" order is roughly the same as reading them sorted by +** the PRIMARY KEY of the corresponding target database table. In other +** words, rows should be sorted using the destination table PRIMARY KEY +** fields before they are inserted into the data_xxx tables. +** +** USAGE +** +** The API declared below allows an application to apply an RBU update +** stored on disk to an existing target database. Essentially, the +** application: +** +** 1) Opens an RBU handle using the sqlite3rbu_open() function. +** +** 2) Registers any required virtual table modules with the database +** handle returned by sqlite3rbu_db(). Also, if required, register +** the rbu_delta() implementation. +** +** 3) Calls the sqlite3rbu_step() function one or more times on +** the new handle. Each call to sqlite3rbu_step() performs a single +** b-tree operation, so thousands of calls may be required to apply +** a complete update. +** +** 4) Calls sqlite3rbu_close() to close the RBU update handle. If +** sqlite3rbu_step() has been called enough times to completely +** apply the update to the target database, then the RBU database +** is marked as fully applied. Otherwise, the state of the RBU +** update application is saved in the RBU database for later +** resumption. +** +** See comments below for more detail on APIs. +** +** If an update is only partially applied to the target database by the +** time sqlite3rbu_close() is called, various state information is saved +** within the RBU database. This allows subsequent processes to automatically +** resume the RBU update from where it left off. +** +** To remove all RBU extension state information, returning an RBU database +** to its original contents, it is sufficient to drop all tables that begin +** with the prefix "rbu_" +** +** DATABASE LOCKING +** +** An RBU update may not be applied to a database in WAL mode. Attempting +** to do so is an error (SQLITE_ERROR). +** +** While an RBU handle is open, a SHARED lock may be held on the target +** database file. This means it is possible for other clients to read the +** database, but not to write it. +** +** If an RBU update is started and then suspended before it is completed, +** then an external client writes to the database, then attempting to resume +** the suspended RBU update is also an error (SQLITE_BUSY). +*/ + +#ifndef _SQLITE3RBU_H +#define _SQLITE3RBU_H + +/* #include "sqlite3.h" ** Required for error code definitions ** */ + +#if 0 +extern "C" { +#endif + +typedef struct sqlite3rbu sqlite3rbu; + +/* +** Open an RBU handle. +** +** Argument zTarget is the path to the target database. Argument zRbu is +** the path to the RBU database. Each call to this function must be matched +** by a call to sqlite3rbu_close(). When opening the databases, RBU passes +** the SQLITE_CONFIG_URI flag to sqlite3_open_v2(). So if either zTarget +** or zRbu begin with "file:", it will be interpreted as an SQLite +** database URI, not a regular file name. +** +** If the zState argument is passed a NULL value, the RBU extension stores +** the current state of the update (how many rows have been updated, which +** indexes are yet to be updated etc.) within the RBU database itself. This +** can be convenient, as it means that the RBU application does not need to +** organize removing a separate state file after the update is concluded. +** Or, if zState is non-NULL, it must be a path to a database file in which +** the RBU extension can store the state of the update. +** +** When resuming an RBU update, the zState argument must be passed the same +** value as when the RBU update was started. +** +** Once the RBU update is finished, the RBU extension does not +** automatically remove any zState database file, even if it created it. +** +** By default, RBU uses the default VFS to access the files on disk. To +** use a VFS other than the default, an SQLite "file:" URI containing a +** "vfs=..." option may be passed as the zTarget option. +** +** IMPORTANT NOTE FOR ZIPVFS USERS: The RBU extension works with all of +** SQLite's built-in VFSs, including the multiplexor VFS. However it does +** not work out of the box with zipvfs. Refer to the comment describing +** the zipvfs_create_vfs() API below for details on using RBU with zipvfs. +*/ +SQLITE_API sqlite3rbu *sqlite3rbu_open( + const char *zTarget, + const char *zRbu, + const char *zState +); + +/* +** Open an RBU handle to perform an RBU vacuum on database file zTarget. +** An RBU vacuum is similar to SQLite's built-in VACUUM command, except +** that it can be suspended and resumed like an RBU update. +** +** The second argument to this function identifies a database in which +** to store the state of the RBU vacuum operation if it is suspended. The +** first time sqlite3rbu_vacuum() is called, to start an RBU vacuum +** operation, the state database should either not exist or be empty +** (contain no tables). If an RBU vacuum is suspended by calling +** sqlite3rbu_close() on the RBU handle before sqlite3rbu_step() has +** returned SQLITE_DONE, the vacuum state is stored in the state database. +** The vacuum can be resumed by calling this function to open a new RBU +** handle specifying the same target and state databases. +** +** If the second argument passed to this function is NULL, then the +** name of the state database is "-vacuum", where +** is the name of the target database file. In this case, on UNIX, if the +** state database is not already present in the file-system, it is created +** with the same permissions as the target db is made. +** +** With an RBU vacuum, it is an SQLITE_MISUSE error if the name of the +** state database ends with "-vactmp". This name is reserved for internal +** use. +** +** This function does not delete the state database after an RBU vacuum +** is completed, even if it created it. However, if the call to +** sqlite3rbu_close() returns any value other than SQLITE_OK, the contents +** of the state tables within the state database are zeroed. This way, +** the next call to sqlite3rbu_vacuum() opens a handle that starts a +** new RBU vacuum operation. +** +** As with sqlite3rbu_open(), Zipvfs users should refer to the comment +** describing the sqlite3rbu_create_vfs() API function below for +** a description of the complications associated with using RBU with +** zipvfs databases. +*/ +SQLITE_API sqlite3rbu *sqlite3rbu_vacuum( + const char *zTarget, + const char *zState +); + +/* +** Configure a limit for the amount of temp space that may be used by +** the RBU handle passed as the first argument. The new limit is specified +** in bytes by the second parameter. If it is positive, the limit is updated. +** If the second parameter to this function is passed zero, then the limit +** is removed entirely. If the second parameter is negative, the limit is +** not modified (this is useful for querying the current limit). +** +** In all cases the returned value is the current limit in bytes (zero +** indicates unlimited). +** +** If the temp space limit is exceeded during operation, an SQLITE_FULL +** error is returned. +*/ +SQLITE_API sqlite3_int64 sqlite3rbu_temp_size_limit(sqlite3rbu*, sqlite3_int64); + +/* +** Return the current amount of temp file space, in bytes, currently used by +** the RBU handle passed as the only argument. +*/ +SQLITE_API sqlite3_int64 sqlite3rbu_temp_size(sqlite3rbu*); + +/* +** Internally, each RBU connection uses a separate SQLite database +** connection to access the target and rbu update databases. This +** API allows the application direct access to these database handles. +** +** The first argument passed to this function must be a valid, open, RBU +** handle. The second argument should be passed zero to access the target +** database handle, or non-zero to access the rbu update database handle. +** Accessing the underlying database handles may be useful in the +** following scenarios: +** +** * If any target tables are virtual tables, it may be necessary to +** call sqlite3_create_module() on the target database handle to +** register the required virtual table implementations. +** +** * If the data_xxx tables in the RBU source database are virtual +** tables, the application may need to call sqlite3_create_module() on +** the rbu update db handle to any required virtual table +** implementations. +** +** * If the application uses the "rbu_delta()" feature described above, +** it must use sqlite3_create_function() or similar to register the +** rbu_delta() implementation with the target database handle. +** +** If an error has occurred, either while opening or stepping the RBU object, +** this function may return NULL. The error code and message may be collected +** when sqlite3rbu_close() is called. +** +** Database handles returned by this function remain valid until the next +** call to any sqlite3rbu_xxx() function other than sqlite3rbu_db(). +*/ +SQLITE_API sqlite3 *sqlite3rbu_db(sqlite3rbu*, int bRbu); + +/* +** Do some work towards applying the RBU update to the target db. +** +** Return SQLITE_DONE if the update has been completely applied, or +** SQLITE_OK if no error occurs but there remains work to do to apply +** the RBU update. If an error does occur, some other error code is +** returned. +** +** Once a call to sqlite3rbu_step() has returned a value other than +** SQLITE_OK, all subsequent calls on the same RBU handle are no-ops +** that immediately return the same value. +*/ +SQLITE_API int sqlite3rbu_step(sqlite3rbu *pRbu); + +/* +** Force RBU to save its state to disk. +** +** If a power failure or application crash occurs during an update, following +** system recovery RBU may resume the update from the point at which the state +** was last saved. In other words, from the most recent successful call to +** sqlite3rbu_close() or this function. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +*/ +SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *pRbu); + +/* +** Close an RBU handle. +** +** If the RBU update has been completely applied, mark the RBU database +** as fully applied. Otherwise, assuming no error has occurred, save the +** current state of the RBU update application to the RBU database. +** +** If an error has already occurred as part of an sqlite3rbu_step() +** or sqlite3rbu_open() call, or if one occurs within this function, an +** SQLite error code is returned. Additionally, if pzErrmsg is not NULL, +** *pzErrmsg may be set to point to a buffer containing a utf-8 formatted +** English language error message. It is the responsibility of the caller to +** eventually free any such buffer using sqlite3_free(). +** +** Otherwise, if no error occurs, this function returns SQLITE_OK if the +** update has been partially applied, or SQLITE_DONE if it has been +** completely applied. +*/ +SQLITE_API int sqlite3rbu_close(sqlite3rbu *pRbu, char **pzErrmsg); + +/* +** Return the total number of key-value operations (inserts, deletes or +** updates) that have been performed on the target database since the +** current RBU update was started. +*/ +SQLITE_API sqlite3_int64 sqlite3rbu_progress(sqlite3rbu *pRbu); + +/* +** Obtain permyriadage (permyriadage is to 10000 as percentage is to 100) +** progress indications for the two stages of an RBU update. This API may +** be useful for driving GUI progress indicators and similar. +** +** An RBU update is divided into two stages: +** +** * Stage 1, in which changes are accumulated in an oal/wal file, and +** * Stage 2, in which the contents of the wal file are copied into the +** main database. +** +** The update is visible to non-RBU clients during stage 2. During stage 1 +** non-RBU reader clients may see the original database. +** +** If this API is called during stage 2 of the update, output variable +** (*pnOne) is set to 10000 to indicate that stage 1 has finished and (*pnTwo) +** to a value between 0 and 10000 to indicate the permyriadage progress of +** stage 2. A value of 5000 indicates that stage 2 is half finished, +** 9000 indicates that it is 90% finished, and so on. +** +** If this API is called during stage 1 of the update, output variable +** (*pnTwo) is set to 0 to indicate that stage 2 has not yet started. The +** value to which (*pnOne) is set depends on whether or not the RBU +** database contains an "rbu_count" table. The rbu_count table, if it +** exists, must contain the same columns as the following: +** +** CREATE TABLE rbu_count(tbl TEXT PRIMARY KEY, cnt INTEGER) WITHOUT ROWID; +** +** There must be one row in the table for each source (data_xxx) table within +** the RBU database. The 'tbl' column should contain the name of the source +** table. The 'cnt' column should contain the number of rows within the +** source table. +** +** If the rbu_count table is present and populated correctly and this +** API is called during stage 1, the *pnOne output variable is set to the +** permyriadage progress of the same stage. If the rbu_count table does +** not exist, then (*pnOne) is set to -1 during stage 1. If the rbu_count +** table exists but is not correctly populated, the value of the *pnOne +** output variable during stage 1 is undefined. +*/ +SQLITE_API void sqlite3rbu_bp_progress(sqlite3rbu *pRbu, int *pnOne, int*pnTwo); + +/* +** Obtain an indication as to the current stage of an RBU update or vacuum. +** This function always returns one of the SQLITE_RBU_STATE_XXX constants +** defined in this file. Return values should be interpreted as follows: +** +** SQLITE_RBU_STATE_OAL: +** RBU is currently building a *-oal file. The next call to sqlite3rbu_step() +** may either add further data to the *-oal file, or compute data that will +** be added by a subsequent call. +** +** SQLITE_RBU_STATE_MOVE: +** RBU has finished building the *-oal file. The next call to sqlite3rbu_step() +** will move the *-oal file to the equivalent *-wal path. If the current +** operation is an RBU update, then the updated version of the database +** file will become visible to ordinary SQLite clients following the next +** call to sqlite3rbu_step(). +** +** SQLITE_RBU_STATE_CHECKPOINT: +** RBU is currently performing an incremental checkpoint. The next call to +** sqlite3rbu_step() will copy a page of data from the *-wal file into +** the target database file. +** +** SQLITE_RBU_STATE_DONE: +** The RBU operation has finished. Any subsequent calls to sqlite3rbu_step() +** will immediately return SQLITE_DONE. +** +** SQLITE_RBU_STATE_ERROR: +** An error has occurred. Any subsequent calls to sqlite3rbu_step() will +** immediately return the SQLite error code associated with the error. +*/ +#define SQLITE_RBU_STATE_OAL 1 +#define SQLITE_RBU_STATE_MOVE 2 +#define SQLITE_RBU_STATE_CHECKPOINT 3 +#define SQLITE_RBU_STATE_DONE 4 +#define SQLITE_RBU_STATE_ERROR 5 + +SQLITE_API int sqlite3rbu_state(sqlite3rbu *pRbu); + +/* +** As part of applying an RBU update or performing an RBU vacuum operation, +** the system must at one point move the *-oal file to the equivalent *-wal +** path. Normally, it does this by invoking POSIX function rename(2) directly. +** Except on WINCE platforms, where it uses win32 API MoveFileW(). This +** function may be used to register a callback that the RBU module will invoke +** instead of one of these APIs. +** +** If a callback is registered with an RBU handle, it invokes it instead +** of rename(2) when it needs to move a file within the file-system. The +** first argument passed to the xRename() callback is a copy of the second +** argument (pArg) passed to this function. The second is the full path +** to the file to move and the third the full path to which it should be +** moved. The callback function should return SQLITE_OK to indicate +** success. If an error occurs, it should return an SQLite error code. +** In this case the RBU operation will be abandoned and the error returned +** to the RBU user. +** +** Passing a NULL pointer in place of the xRename argument to this function +** restores the default behaviour. +*/ +SQLITE_API void sqlite3rbu_rename_handler( + sqlite3rbu *pRbu, + void *pArg, + int (*xRename)(void *pArg, const char *zOld, const char *zNew) +); + + +/* +** Create an RBU VFS named zName that accesses the underlying file-system +** via existing VFS zParent. Or, if the zParent parameter is passed NULL, +** then the new RBU VFS uses the default system VFS to access the file-system. +** The new object is registered as a non-default VFS with SQLite before +** returning. +** +** Part of the RBU implementation uses a custom VFS object. Usually, this +** object is created and deleted automatically by RBU. +** +** The exception is for applications that also use zipvfs. In this case, +** the custom VFS must be explicitly created by the user before the RBU +** handle is opened. The RBU VFS should be installed so that the zipvfs +** VFS uses the RBU VFS, which in turn uses any other VFS layers in use +** (for example multiplexor) to access the file-system. For example, +** to assemble an RBU enabled VFS stack that uses both zipvfs and +** multiplexor (error checking omitted): +** +** // Create a VFS named "multiplex" (not the default). +** sqlite3_multiplex_initialize(0, 0); +** +** // Create an rbu VFS named "rbu" that uses multiplexor. If the +** // second argument were replaced with NULL, the "rbu" VFS would +** // access the file-system via the system default VFS, bypassing the +** // multiplexor. +** sqlite3rbu_create_vfs("rbu", "multiplex"); +** +** // Create a zipvfs VFS named "zipvfs" that uses rbu. +** zipvfs_create_vfs_v3("zipvfs", "rbu", 0, xCompressorAlgorithmDetector); +** +** // Make zipvfs the default VFS. +** sqlite3_vfs_register(sqlite3_vfs_find("zipvfs"), 1); +** +** Because the default VFS created above includes a RBU functionality, it +** may be used by RBU clients. Attempting to use RBU with a zipvfs VFS stack +** that does not include the RBU layer results in an error. +** +** The overhead of adding the "rbu" VFS to the system is negligible for +** non-RBU users. There is no harm in an application accessing the +** file-system via "rbu" all the time, even if it only uses RBU functionality +** occasionally. +*/ +SQLITE_API int sqlite3rbu_create_vfs(const char *zName, const char *zParent); + +/* +** Deregister and destroy an RBU vfs created by an earlier call to +** sqlite3rbu_create_vfs(). +** +** VFS objects are not reference counted. If a VFS object is destroyed +** before all database handles that use it have been closed, the results +** are undefined. +*/ +SQLITE_API void sqlite3rbu_destroy_vfs(const char *zName); + +#if 0 +} /* end of the 'extern "C"' block */ +#endif + +#endif /* _SQLITE3RBU_H */ + +/************** End of sqlite3rbu.h ******************************************/ +/************** Continuing where we left off in sqlite3rbu.c *****************/ + +#if defined(_WIN32_WCE) +/* #include "windows.h" */ +#endif + +/* Maximum number of prepared UPDATE statements held by this module */ +#define SQLITE_RBU_UPDATE_CACHESIZE 16 + +/* Delta checksums disabled by default. Compile with -DRBU_ENABLE_DELTA_CKSUM +** to enable checksum verification. +*/ +#ifndef RBU_ENABLE_DELTA_CKSUM +# define RBU_ENABLE_DELTA_CKSUM 0 +#endif + +/* +** Swap two objects of type TYPE. +*/ +#if !defined(SQLITE_AMALGAMATION) +# define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;} +#endif + +/* +** Name of the URI option that causes RBU to take an exclusive lock as +** part of the incremental checkpoint operation. +*/ +#define RBU_EXCLUSIVE_CHECKPOINT "rbu_exclusive_checkpoint" + + +/* +** The rbu_state table is used to save the state of a partially applied +** update so that it can be resumed later. The table consists of integer +** keys mapped to values as follows: +** +** RBU_STATE_STAGE: +** May be set to integer values 1, 2, 4 or 5. As follows: +** 1: the *-rbu file is currently under construction. +** 2: the *-rbu file has been constructed, but not yet moved +** to the *-wal path. +** 4: the checkpoint is underway. +** 5: the rbu update has been checkpointed. +** +** RBU_STATE_TBL: +** Only valid if STAGE==1. The target database name of the table +** currently being written. +** +** RBU_STATE_IDX: +** Only valid if STAGE==1. The target database name of the index +** currently being written, or NULL if the main table is currently being +** updated. +** +** RBU_STATE_ROW: +** Only valid if STAGE==1. Number of rows already processed for the current +** table/index. +** +** RBU_STATE_PROGRESS: +** Trbul number of sqlite3rbu_step() calls made so far as part of this +** rbu update. +** +** RBU_STATE_CKPT: +** Valid if STAGE==4. The 64-bit checksum associated with the wal-index +** header created by recovering the *-wal file. This is used to detect +** cases when another client appends frames to the *-wal file in the +** middle of an incremental checkpoint (an incremental checkpoint cannot +** be continued if this happens). +** +** RBU_STATE_COOKIE: +** Valid if STAGE==1. The current change-counter cookie value in the +** target db file. +** +** RBU_STATE_OALSZ: +** Valid if STAGE==1. The size in bytes of the *-oal file. +** +** RBU_STATE_DATATBL: +** Only valid if STAGE==1. The RBU database name of the table +** currently being read. +*/ +#define RBU_STATE_STAGE 1 +#define RBU_STATE_TBL 2 +#define RBU_STATE_IDX 3 +#define RBU_STATE_ROW 4 +#define RBU_STATE_PROGRESS 5 +#define RBU_STATE_CKPT 6 +#define RBU_STATE_COOKIE 7 +#define RBU_STATE_OALSZ 8 +#define RBU_STATE_PHASEONESTEP 9 +#define RBU_STATE_DATATBL 10 + +#define RBU_STAGE_OAL 1 +#define RBU_STAGE_MOVE 2 +#define RBU_STAGE_CAPTURE 3 +#define RBU_STAGE_CKPT 4 +#define RBU_STAGE_DONE 5 + + +#define RBU_CREATE_STATE \ + "CREATE TABLE IF NOT EXISTS %s.rbu_state(k INTEGER PRIMARY KEY, v)" + +typedef struct RbuFrame RbuFrame; +typedef struct RbuObjIter RbuObjIter; +typedef struct RbuState RbuState; +typedef struct RbuSpan RbuSpan; +typedef struct rbu_vfs rbu_vfs; +typedef struct rbu_file rbu_file; +typedef struct RbuUpdateStmt RbuUpdateStmt; + +#if !defined(SQLITE_AMALGAMATION) +typedef unsigned int u32; +typedef unsigned short u16; +typedef unsigned char u8; +typedef sqlite3_int64 i64; +typedef sqlite3_uint64 u64; +#endif + +/* +** These values must match the values defined in wal.c for the equivalent +** locks. These are not magic numbers as they are part of the SQLite file +** format. +*/ +#define WAL_LOCK_WRITE 0 +#define WAL_LOCK_CKPT 1 +#define WAL_LOCK_READ0 3 + +#define SQLITE_FCNTL_RBUCNT 5149216 + +/* +** A structure to store values read from the rbu_state table in memory. +*/ +struct RbuState { + int eStage; + char *zTbl; + char *zDataTbl; + char *zIdx; + i64 iWalCksum; + int nRow; + i64 nProgress; + u32 iCookie; + i64 iOalSz; + i64 nPhaseOneStep; +}; + +struct RbuUpdateStmt { + char *zMask; /* Copy of update mask used with pUpdate */ + sqlite3_stmt *pUpdate; /* Last update statement (or NULL) */ + RbuUpdateStmt *pNext; +}; + +struct RbuSpan { + const char *zSpan; + int nSpan; +}; + +/* +** An iterator of this type is used to iterate through all objects in +** the target database that require updating. For each such table, the +** iterator visits, in order: +** +** * the table itself, +** * each index of the table (zero or more points to visit), and +** * a special "cleanup table" state. +** +** abIndexed: +** If the table has no indexes on it, abIndexed is set to NULL. Otherwise, +** it points to an array of flags nTblCol elements in size. The flag is +** set for each column that is either a part of the PK or a part of an +** index. Or clear otherwise. +** +** If there are one or more partial indexes on the table, all fields of +** this array set set to 1. This is because in that case, the module has +** no way to tell which fields will be required to add and remove entries +** from the partial indexes. +** +*/ +struct RbuObjIter { + sqlite3_stmt *pTblIter; /* Iterate through tables */ + sqlite3_stmt *pIdxIter; /* Index iterator */ + int nTblCol; /* Size of azTblCol[] array */ + char **azTblCol; /* Array of unquoted target column names */ + char **azTblType; /* Array of target column types */ + int *aiSrcOrder; /* src table col -> target table col */ + u8 *abTblPk; /* Array of flags, set on target PK columns */ + u8 *abNotNull; /* Array of flags, set on NOT NULL columns */ + u8 *abIndexed; /* Array of flags, set on indexed & PK cols */ + int eType; /* Table type - an RBU_PK_XXX value */ + + /* Output variables. zTbl==0 implies EOF. */ + int bCleanup; /* True in "cleanup" state */ + const char *zTbl; /* Name of target db table */ + const char *zDataTbl; /* Name of rbu db table (or null) */ + const char *zIdx; /* Name of target db index (or null) */ + int iTnum; /* Root page of current object */ + int iPkTnum; /* If eType==EXTERNAL, root of PK index */ + int bUnique; /* Current index is unique */ + int nIndex; /* Number of aux. indexes on table zTbl */ + + /* Statements created by rbuObjIterPrepareAll() */ + int nCol; /* Number of columns in current object */ + sqlite3_stmt *pSelect; /* Source data */ + sqlite3_stmt *pInsert; /* Statement for INSERT operations */ + sqlite3_stmt *pDelete; /* Statement for DELETE ops */ + sqlite3_stmt *pTmpInsert; /* Insert into rbu_tmp_$zDataTbl */ + int nIdxCol; + RbuSpan *aIdxCol; + char *zIdxSql; + + /* Last UPDATE used (for PK b-tree updates only), or NULL. */ + RbuUpdateStmt *pRbuUpdate; +}; + +/* +** Values for RbuObjIter.eType +** +** 0: Table does not exist (error) +** 1: Table has an implicit rowid. +** 2: Table has an explicit IPK column. +** 3: Table has an external PK index. +** 4: Table is WITHOUT ROWID. +** 5: Table is a virtual table. +*/ +#define RBU_PK_NOTABLE 0 +#define RBU_PK_NONE 1 +#define RBU_PK_IPK 2 +#define RBU_PK_EXTERNAL 3 +#define RBU_PK_WITHOUT_ROWID 4 +#define RBU_PK_VTAB 5 + + +/* +** Within the RBU_STAGE_OAL stage, each call to sqlite3rbu_step() performs +** one of the following operations. +*/ +#define RBU_INSERT 1 /* Insert on a main table b-tree */ +#define RBU_DELETE 2 /* Delete a row from a main table b-tree */ +#define RBU_REPLACE 3 /* Delete and then insert a row */ +#define RBU_IDX_DELETE 4 /* Delete a row from an aux. index b-tree */ +#define RBU_IDX_INSERT 5 /* Insert on an aux. index b-tree */ + +#define RBU_UPDATE 6 /* Update a row in a main table b-tree */ + +/* +** A single step of an incremental checkpoint - frame iWalFrame of the wal +** file should be copied to page iDbPage of the database file. +*/ +struct RbuFrame { + u32 iDbPage; + u32 iWalFrame; +}; + +#ifndef UNUSED_PARAMETER +/* +** The following macros are used to suppress compiler warnings and to +** make it clear to human readers when a function parameter is deliberately +** left unused within the body of a function. This usually happens when +** a function is called via a function pointer. For example the +** implementation of an SQL aggregate step callback may not use the +** parameter indicating the number of arguments passed to the aggregate, +** if it knows that this is enforced elsewhere. +** +** When a function parameter is not used at all within the body of a function, +** it is generally named "NotUsed" or "NotUsed2" to make things even clearer. +** However, these macros may also be used to suppress warnings related to +** parameters that may or may not be used depending on compilation options. +** For example those parameters only used in assert() statements. In these +** cases the parameters are named as per the usual conventions. +*/ +#define UNUSED_PARAMETER(x) (void)(x) +#define UNUSED_PARAMETER2(x,y) UNUSED_PARAMETER(x),UNUSED_PARAMETER(y) +#endif + +/* +** RBU handle. +** +** nPhaseOneStep: +** If the RBU database contains an rbu_count table, this value is set to +** a running estimate of the number of b-tree operations required to +** finish populating the *-oal file. This allows the sqlite3_bp_progress() +** API to calculate the permyriadage progress of populating the *-oal file +** using the formula: +** +** permyriadage = (10000 * nProgress) / nPhaseOneStep +** +** nPhaseOneStep is initialized to the sum of: +** +** nRow * (nIndex + 1) +** +** for all source tables in the RBU database, where nRow is the number +** of rows in the source table and nIndex the number of indexes on the +** corresponding target database table. +** +** This estimate is accurate if the RBU update consists entirely of +** INSERT operations. However, it is inaccurate if: +** +** * the RBU update contains any UPDATE operations. If the PK specified +** for an UPDATE operation does not exist in the target table, then +** no b-tree operations are required on index b-trees. Or if the +** specified PK does exist, then (nIndex*2) such operations are +** required (one delete and one insert on each index b-tree). +** +** * the RBU update contains any DELETE operations for which the specified +** PK does not exist. In this case no operations are required on index +** b-trees. +** +** * the RBU update contains REPLACE operations. These are similar to +** UPDATE operations. +** +** nPhaseOneStep is updated to account for the conditions above during the +** first pass of each source table. The updated nPhaseOneStep value is +** stored in the rbu_state table if the RBU update is suspended. +*/ +struct sqlite3rbu { + int eStage; /* Value of RBU_STATE_STAGE field */ + sqlite3 *dbMain; /* target database handle */ + sqlite3 *dbRbu; /* rbu database handle */ + char *zTarget; /* Path to target db */ + char *zRbu; /* Path to rbu db */ + char *zState; /* Path to state db (or NULL if zRbu) */ + char zStateDb[5]; /* Db name for state ("stat" or "main") */ + int rc; /* Value returned by last rbu_step() call */ + char *zErrmsg; /* Error message if rc!=SQLITE_OK */ + int nStep; /* Rows processed for current object */ + sqlite3_int64 nProgress; /* Rows processed for all objects */ + RbuObjIter objiter; /* Iterator for skipping through tbl/idx */ + const char *zVfsName; /* Name of automatically created rbu vfs */ + rbu_file *pTargetFd; /* File handle open on target db */ + int nPagePerSector; /* Pages per sector for pTargetFd */ + i64 iOalSz; + i64 nPhaseOneStep; + void *pRenameArg; + int (*xRename)(void*, const char*, const char*); + + /* The following state variables are used as part of the incremental + ** checkpoint stage (eStage==RBU_STAGE_CKPT). See comments surrounding + ** function rbuSetupCheckpoint() for details. */ + u32 iMaxFrame; /* Largest iWalFrame value in aFrame[] */ + u32 mLock; + int nFrame; /* Entries in aFrame[] array */ + int nFrameAlloc; /* Allocated size of aFrame[] array */ + RbuFrame *aFrame; + int pgsz; + u8 *aBuf; + i64 iWalCksum; + i64 szTemp; /* Current size of all temp files in use */ + i64 szTempLimit; /* Total size limit for temp files */ + + /* Used in RBU vacuum mode only */ + int nRbu; /* Number of RBU VFS in the stack */ + rbu_file *pRbuFd; /* Fd for main db of dbRbu */ +}; + +/* +** An rbu VFS is implemented using an instance of this structure. +** +** Variable pRbu is only non-NULL for automatically created RBU VFS objects. +** It is NULL for RBU VFS objects created explicitly using +** sqlite3rbu_create_vfs(). It is used to track the total amount of temp +** space used by the RBU handle. +*/ +struct rbu_vfs { + sqlite3_vfs base; /* rbu VFS shim methods */ + sqlite3_vfs *pRealVfs; /* Underlying VFS */ + sqlite3_mutex *mutex; /* Mutex to protect pMain */ + sqlite3rbu *pRbu; /* Owner RBU object */ + rbu_file *pMain; /* List of main db files */ + rbu_file *pMainRbu; /* List of main db files with pRbu!=0 */ +}; + +/* +** Each file opened by an rbu VFS is represented by an instance of +** the following structure. +** +** If this is a temporary file (pRbu!=0 && flags&DELETE_ON_CLOSE), variable +** "sz" is set to the current size of the database file. +*/ +struct rbu_file { + sqlite3_file base; /* sqlite3_file methods */ + sqlite3_file *pReal; /* Underlying file handle */ + rbu_vfs *pRbuVfs; /* Pointer to the rbu_vfs object */ + sqlite3rbu *pRbu; /* Pointer to rbu object (rbu target only) */ + i64 sz; /* Size of file in bytes (temp only) */ + + int openFlags; /* Flags this file was opened with */ + u32 iCookie; /* Cookie value for main db files */ + u8 iWriteVer; /* "write-version" value for main db files */ + u8 bNolock; /* True to fail EXCLUSIVE locks */ + + int nShm; /* Number of entries in apShm[] array */ + char **apShm; /* Array of mmap'd *-shm regions */ + char *zDel; /* Delete this when closing file */ + + const char *zWal; /* Wal filename for this main db file */ + rbu_file *pWalFd; /* Wal file descriptor for this main db */ + rbu_file *pMainNext; /* Next MAIN_DB file */ + rbu_file *pMainRbuNext; /* Next MAIN_DB file with pRbu!=0 */ +}; + +/* +** True for an RBU vacuum handle, or false otherwise. +*/ +#define rbuIsVacuum(p) ((p)->zTarget==0) + + +/************************************************************************* +** The following three functions, found below: +** +** rbuDeltaGetInt() +** rbuDeltaChecksum() +** rbuDeltaApply() +** +** are lifted from the fossil source code (http://fossil-scm.org). They +** are used to implement the scalar SQL function rbu_fossil_delta(). +*/ + +/* +** Read bytes from *pz and convert them into a positive integer. When +** finished, leave *pz pointing to the first character past the end of +** the integer. The *pLen parameter holds the length of the string +** in *pz and is decremented once for each character in the integer. +*/ +static unsigned int rbuDeltaGetInt(const char **pz, int *pLen){ + static const signed char zValue[] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, 36, + -1, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, -1, -1, -1, 63, -1, + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }; + unsigned int v = 0; + int c; + unsigned char *z = (unsigned char*)*pz; + unsigned char *zEnd = z + (*pLen); + while( z=0 ){ + v = (v<<6) + c; + z++; + } + + *pLen -= (int)(z - (unsigned char*)*pz); + *pz = (char*)z; + return v; +} + +#if RBU_ENABLE_DELTA_CKSUM +/* +** Compute a 32-bit checksum on the N-byte buffer. Return the result. +*/ +static unsigned int rbuDeltaChecksum(const char *zIn, size_t N){ + const unsigned char *z = (const unsigned char *)zIn; + unsigned sum0 = 0; + unsigned sum1 = 0; + unsigned sum2 = 0; + unsigned sum3 = 0; + while(N >= 16){ + sum0 += ((unsigned)z[0] + z[4] + z[8] + z[12]); + sum1 += ((unsigned)z[1] + z[5] + z[9] + z[13]); + sum2 += ((unsigned)z[2] + z[6] + z[10]+ z[14]); + sum3 += ((unsigned)z[3] + z[7] + z[11]+ z[15]); + z += 16; + N -= 16; + } + while(N >= 4){ + sum0 += z[0]; + sum1 += z[1]; + sum2 += z[2]; + sum3 += z[3]; + z += 4; + N -= 4; + } + sum3 += (sum2 << 8) + (sum1 << 16) + (sum0 << 24); + switch(N){ + case 3: sum3 += (z[2] << 8); + case 2: sum3 += (z[1] << 16); + case 1: sum3 += (z[0] << 24); + default: ; + } + return sum3; +} +#endif + +/* +** Apply a delta. +** +** The output buffer should be big enough to hold the whole output +** file and a NUL terminator at the end. The delta_output_size() +** routine will determine this size for you. +** +** The delta string should be null-terminated. But the delta string +** may contain embedded NUL characters (if the input and output are +** binary files) so we also have to pass in the length of the delta in +** the lenDelta parameter. +** +** This function returns the size of the output file in bytes (excluding +** the final NUL terminator character). Except, if the delta string is +** malformed or intended for use with a source file other than zSrc, +** then this routine returns -1. +** +** Refer to the delta_create() documentation above for a description +** of the delta file format. +*/ +static int rbuDeltaApply( + const char *zSrc, /* The source or pattern file */ + int lenSrc, /* Length of the source file */ + const char *zDelta, /* Delta to apply to the pattern */ + int lenDelta, /* Length of the delta */ + char *zOut /* Write the output into this preallocated buffer */ +){ + sqlite3_uint64 limit; + sqlite3_uint64 total = 0; +#if RBU_ENABLE_DELTA_CKSUM + char *zOrigOut = zOut; +#endif + + limit = rbuDeltaGetInt(&zDelta, &lenDelta); + if( lenDelta<=0 || *zDelta!='\n' ){ + /* ERROR: size integer not terminated by "\n" */ + return -1; + } + zDelta++; lenDelta--; /* Skip the \n */ + while( lenDelta>0 && zDelta[0] ){ + unsigned int cnt, ofst; + cnt = rbuDeltaGetInt(&zDelta, &lenDelta); + if( lenDelta<=0 ) return -1; + switch( zDelta[0] ){ + case '@': { + zDelta++; lenDelta--; + ofst = rbuDeltaGetInt(&zDelta, &lenDelta); + if( lenDelta>0 && zDelta[0]!=',' ){ + /* ERROR: copy command not terminated by ',' */ + return -1; + } + zDelta++; lenDelta--; + total += cnt; + if( total>limit ){ + /* ERROR: copy exceeds output file size */ + return -1; + } + if( (u64)ofst+(u64)cnt > (u64)lenSrc ){ + /* ERROR: copy extends past end of input */ + return -1; + } + memcpy(zOut, &zSrc[ofst], cnt); + zOut += cnt; + break; + } + case ':': { + zDelta++; lenDelta--; + total += cnt; + if( total>limit ){ + /* ERROR: insert command gives an output larger than predicted */ + return -1; + } + if( cnt>lenDelta ){ + /* ERROR: insert count exceeds size of delta */ + return -1; + } + memcpy(zOut, zDelta, cnt); + zOut += cnt; + zDelta += cnt; + lenDelta -= cnt; + break; + } + case ';': { + zDelta++; lenDelta--; + zOut[0] = 0; +#if RBU_ENABLE_DELTA_CKSUM + if( cnt!=rbuDeltaChecksum(zOrigOut, total) ){ + /* ERROR: bad checksum */ + return -1; + } +#endif + if( total!=limit ){ + /* ERROR: generated size does not match predicted size */ + return -1; + } + return total; + } + default: { + /* ERROR: unknown delta operator */ + return -1; + } + } + } + /* ERROR: unterminated delta */ + return -1; +} + +static int rbuDeltaOutputSize(const char *zDelta, int lenDelta){ + int size; + size = rbuDeltaGetInt(&zDelta, &lenDelta); + if( lenDelta<=0 || *zDelta!='\n' ){ + /* ERROR: size integer not terminated by "\n" */ + return -1; + } + return size; +} + +/* +** End of code taken from fossil. +*************************************************************************/ + +/* +** Implementation of SQL scalar function rbu_fossil_delta(). +** +** This function applies a fossil delta patch to a blob. Exactly two +** arguments must be passed to this function. The first is the blob to +** patch and the second the patch to apply. If no error occurs, this +** function returns the patched blob. +*/ +static void rbuFossilDeltaFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const char *aDelta; + int nDelta; + const char *aOrig; + int nOrig; + + int nOut; + int nOut2; + char *aOut; + + assert( argc==2 ); + UNUSED_PARAMETER(argc); + + nOrig = sqlite3_value_bytes(argv[0]); + aOrig = (const char*)sqlite3_value_blob(argv[0]); + nDelta = sqlite3_value_bytes(argv[1]); + aDelta = (const char*)sqlite3_value_blob(argv[1]); + + /* Figure out the size of the output */ + nOut = rbuDeltaOutputSize(aDelta, nDelta); + if( nOut<0 ){ + sqlite3_result_error(context, "corrupt fossil delta", -1); + return; + } + + aOut = sqlite3_malloc64((i64)nOut+1); + if( aOut==0 ){ + sqlite3_result_error_nomem(context); + }else{ + nOut2 = rbuDeltaApply(aOrig, nOrig, aDelta, nDelta, aOut); + if( nOut2!=nOut ){ + sqlite3_free(aOut); + sqlite3_result_error(context, "corrupt fossil delta", -1); + }else{ + sqlite3_result_blob(context, aOut, nOut, sqlite3_free); + } + } +} + + +/* +** Prepare the SQL statement in buffer zSql against database handle db. +** If successful, set *ppStmt to point to the new statement and return +** SQLITE_OK. +** +** Otherwise, if an error does occur, set *ppStmt to NULL and return +** an SQLite error code. Additionally, set output variable *pzErrmsg to +** point to a buffer containing an error message. It is the responsibility +** of the caller to (eventually) free this buffer using sqlite3_free(). +*/ +static int prepareAndCollectError( + sqlite3 *db, + sqlite3_stmt **ppStmt, + char **pzErrmsg, + const char *zSql +){ + int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0); + if( rc!=SQLITE_OK ){ + *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + *ppStmt = 0; + } + return rc; +} + +/* +** Reset the SQL statement passed as the first argument. Return a copy +** of the value returned by sqlite3_reset(). +** +** If an error has occurred, then set *pzErrmsg to point to a buffer +** containing an error message. It is the responsibility of the caller +** to eventually free this buffer using sqlite3_free(). +*/ +static int resetAndCollectError(sqlite3_stmt *pStmt, char **pzErrmsg){ + int rc = sqlite3_reset(pStmt); + if( rc!=SQLITE_OK ){ + *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(sqlite3_db_handle(pStmt))); + } + return rc; +} + +/* +** Unless it is NULL, argument zSql points to a buffer allocated using +** sqlite3_malloc containing an SQL statement. This function prepares the SQL +** statement against database db and frees the buffer. If statement +** compilation is successful, *ppStmt is set to point to the new statement +** handle and SQLITE_OK is returned. +** +** Otherwise, if an error occurs, *ppStmt is set to NULL and an error code +** returned. In this case, *pzErrmsg may also be set to point to an error +** message. It is the responsibility of the caller to free this error message +** buffer using sqlite3_free(). +** +** If argument zSql is NULL, this function assumes that an OOM has occurred. +** In this case SQLITE_NOMEM is returned and *ppStmt set to NULL. +*/ +static int prepareFreeAndCollectError( + sqlite3 *db, + sqlite3_stmt **ppStmt, + char **pzErrmsg, + char *zSql +){ + int rc; + assert( *pzErrmsg==0 ); + if( zSql==0 ){ + rc = SQLITE_NOMEM; + *ppStmt = 0; + }else{ + rc = prepareAndCollectError(db, ppStmt, pzErrmsg, zSql); + sqlite3_free(zSql); + } + return rc; +} + +/* +** Free the RbuObjIter.azTblCol[] and RbuObjIter.abTblPk[] arrays allocated +** by an earlier call to rbuObjIterCacheTableInfo(). +*/ +static void rbuObjIterFreeCols(RbuObjIter *pIter){ + int i; + for(i=0; inTblCol; i++){ + sqlite3_free(pIter->azTblCol[i]); + sqlite3_free(pIter->azTblType[i]); + } + sqlite3_free(pIter->azTblCol); + pIter->azTblCol = 0; + pIter->azTblType = 0; + pIter->aiSrcOrder = 0; + pIter->abTblPk = 0; + pIter->abNotNull = 0; + pIter->nTblCol = 0; + pIter->eType = 0; /* Invalid value */ +} + +/* +** Finalize all statements and free all allocations that are specific to +** the current object (table/index pair). +*/ +static void rbuObjIterClearStatements(RbuObjIter *pIter){ + RbuUpdateStmt *pUp; + + sqlite3_finalize(pIter->pSelect); + sqlite3_finalize(pIter->pInsert); + sqlite3_finalize(pIter->pDelete); + sqlite3_finalize(pIter->pTmpInsert); + pUp = pIter->pRbuUpdate; + while( pUp ){ + RbuUpdateStmt *pTmp = pUp->pNext; + sqlite3_finalize(pUp->pUpdate); + sqlite3_free(pUp); + pUp = pTmp; + } + sqlite3_free(pIter->aIdxCol); + sqlite3_free(pIter->zIdxSql); + + pIter->pSelect = 0; + pIter->pInsert = 0; + pIter->pDelete = 0; + pIter->pRbuUpdate = 0; + pIter->pTmpInsert = 0; + pIter->nCol = 0; + pIter->nIdxCol = 0; + pIter->aIdxCol = 0; + pIter->zIdxSql = 0; +} + +/* +** Clean up any resources allocated as part of the iterator object passed +** as the only argument. +*/ +static void rbuObjIterFinalize(RbuObjIter *pIter){ + rbuObjIterClearStatements(pIter); + sqlite3_finalize(pIter->pTblIter); + sqlite3_finalize(pIter->pIdxIter); + rbuObjIterFreeCols(pIter); + memset(pIter, 0, sizeof(RbuObjIter)); +} + +/* +** Advance the iterator to the next position. +** +** If no error occurs, SQLITE_OK is returned and the iterator is left +** pointing to the next entry. Otherwise, an error code and message is +** left in the RBU handle passed as the first argument. A copy of the +** error code is returned. +*/ +static int rbuObjIterNext(sqlite3rbu *p, RbuObjIter *pIter){ + int rc = p->rc; + if( rc==SQLITE_OK ){ + + /* Free any SQLite statements used while processing the previous object */ + rbuObjIterClearStatements(pIter); + if( pIter->zIdx==0 ){ + rc = sqlite3_exec(p->dbMain, + "DROP TRIGGER IF EXISTS temp.rbu_insert_tr;" + "DROP TRIGGER IF EXISTS temp.rbu_update1_tr;" + "DROP TRIGGER IF EXISTS temp.rbu_update2_tr;" + "DROP TRIGGER IF EXISTS temp.rbu_delete_tr;" + , 0, 0, &p->zErrmsg + ); + } + + if( rc==SQLITE_OK ){ + if( pIter->bCleanup ){ + rbuObjIterFreeCols(pIter); + pIter->bCleanup = 0; + rc = sqlite3_step(pIter->pTblIter); + if( rc!=SQLITE_ROW ){ + rc = resetAndCollectError(pIter->pTblIter, &p->zErrmsg); + pIter->zTbl = 0; + pIter->zDataTbl = 0; + }else{ + pIter->zTbl = (const char*)sqlite3_column_text(pIter->pTblIter, 0); + pIter->zDataTbl = (const char*)sqlite3_column_text(pIter->pTblIter,1); + rc = (pIter->zDataTbl && pIter->zTbl) ? SQLITE_OK : SQLITE_NOMEM; + } + }else{ + if( pIter->zIdx==0 ){ + sqlite3_stmt *pIdx = pIter->pIdxIter; + rc = sqlite3_bind_text(pIdx, 1, pIter->zTbl, -1, SQLITE_STATIC); + } + if( rc==SQLITE_OK ){ + rc = sqlite3_step(pIter->pIdxIter); + if( rc!=SQLITE_ROW ){ + rc = resetAndCollectError(pIter->pIdxIter, &p->zErrmsg); + pIter->bCleanup = 1; + pIter->zIdx = 0; + }else{ + pIter->zIdx = (const char*)sqlite3_column_text(pIter->pIdxIter, 0); + pIter->iTnum = sqlite3_column_int(pIter->pIdxIter, 1); + pIter->bUnique = sqlite3_column_int(pIter->pIdxIter, 2); + rc = pIter->zIdx ? SQLITE_OK : SQLITE_NOMEM; + } + } + } + } + } + + if( rc!=SQLITE_OK ){ + rbuObjIterFinalize(pIter); + p->rc = rc; + } + return rc; +} + + +/* +** The implementation of the rbu_target_name() SQL function. This function +** accepts one or two arguments. The first argument is the name of a table - +** the name of a table in the RBU database. The second, if it is present, is 1 +** for a view or 0 for a table. +** +** For a non-vacuum RBU handle, if the table name matches the pattern: +** +** data[0-9]_ +** +** where is any sequence of 1 or more characters, is returned. +** Otherwise, if the only argument does not match the above pattern, an SQL +** NULL is returned. +** +** "data_t1" -> "t1" +** "data0123_t2" -> "t2" +** "dataAB_t3" -> NULL +** +** For an rbu vacuum handle, a copy of the first argument is returned if +** the second argument is either missing or 0 (not a view). +*/ +static void rbuTargetNameFunc( + sqlite3_context *pCtx, + int argc, + sqlite3_value **argv +){ + sqlite3rbu *p = sqlite3_user_data(pCtx); + const char *zIn; + assert( argc==1 || argc==2 ); + + zIn = (const char*)sqlite3_value_text(argv[0]); + if( zIn ){ + if( rbuIsVacuum(p) ){ + assert( argc==2 || argc==1 ); + if( argc==1 || 0==sqlite3_value_int(argv[1]) ){ + sqlite3_result_text(pCtx, zIn, -1, SQLITE_STATIC); + } + }else{ + if( strlen(zIn)>4 && memcmp("data", zIn, 4)==0 ){ + int i; + for(i=4; zIn[i]>='0' && zIn[i]<='9'; i++); + if( zIn[i]=='_' && zIn[i+1] ){ + sqlite3_result_text(pCtx, &zIn[i+1], -1, SQLITE_STATIC); + } + } + } + } +} + +/* +** Initialize the iterator structure passed as the second argument. +** +** If no error occurs, SQLITE_OK is returned and the iterator is left +** pointing to the first entry. Otherwise, an error code and message is +** left in the RBU handle passed as the first argument. A copy of the +** error code is returned. +*/ +static int rbuObjIterFirst(sqlite3rbu *p, RbuObjIter *pIter){ + int rc; + memset(pIter, 0, sizeof(RbuObjIter)); + + rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pTblIter, &p->zErrmsg, + sqlite3_mprintf( + "SELECT rbu_target_name(name, type='view') AS target, name " + "FROM sqlite_schema " + "WHERE type IN ('table', 'view') AND target IS NOT NULL " + " %s " + "ORDER BY name" + , rbuIsVacuum(p) ? "AND rootpage!=0 AND rootpage IS NOT NULL" : "")); + + if( rc==SQLITE_OK ){ + rc = prepareAndCollectError(p->dbMain, &pIter->pIdxIter, &p->zErrmsg, + "SELECT name, rootpage, sql IS NULL OR substr(8, 6)=='UNIQUE' " + " FROM main.sqlite_schema " + " WHERE type='index' AND tbl_name = ?" + ); + } + + pIter->bCleanup = 1; + p->rc = rc; + return rbuObjIterNext(p, pIter); +} + +/* +** This is a wrapper around "sqlite3_mprintf(zFmt, ...)". If an OOM occurs, +** an error code is stored in the RBU handle passed as the first argument. +** +** If an error has already occurred (p->rc is already set to something other +** than SQLITE_OK), then this function returns NULL without modifying the +** stored error code. In this case it still calls sqlite3_free() on any +** printf() parameters associated with %z conversions. +*/ +static char *rbuMPrintf(sqlite3rbu *p, const char *zFmt, ...){ + char *zSql = 0; + va_list ap; + va_start(ap, zFmt); + zSql = sqlite3_vmprintf(zFmt, ap); + if( p->rc==SQLITE_OK ){ + if( zSql==0 ) p->rc = SQLITE_NOMEM; + }else{ + sqlite3_free(zSql); + zSql = 0; + } + va_end(ap); + return zSql; +} + +/* +** Argument zFmt is a sqlite3_mprintf() style format string. The trailing +** arguments are the usual subsitution values. This function performs +** the printf() style substitutions and executes the result as an SQL +** statement on the RBU handles database. +** +** If an error occurs, an error code and error message is stored in the +** RBU handle. If an error has already occurred when this function is +** called, it is a no-op. +*/ +static int rbuMPrintfExec(sqlite3rbu *p, sqlite3 *db, const char *zFmt, ...){ + va_list ap; + char *zSql; + va_start(ap, zFmt); + zSql = sqlite3_vmprintf(zFmt, ap); + if( p->rc==SQLITE_OK ){ + if( zSql==0 ){ + p->rc = SQLITE_NOMEM; + }else{ + p->rc = sqlite3_exec(db, zSql, 0, 0, &p->zErrmsg); + } + } + sqlite3_free(zSql); + va_end(ap); + return p->rc; +} + +/* +** Attempt to allocate and return a pointer to a zeroed block of nByte +** bytes. +** +** If an error (i.e. an OOM condition) occurs, return NULL and leave an +** error code in the rbu handle passed as the first argument. Or, if an +** error has already occurred when this function is called, return NULL +** immediately without attempting the allocation or modifying the stored +** error code. +*/ +static void *rbuMalloc(sqlite3rbu *p, sqlite3_int64 nByte){ + void *pRet = 0; + if( p->rc==SQLITE_OK ){ + assert( nByte>0 ); + pRet = sqlite3_malloc64(nByte); + if( pRet==0 ){ + p->rc = SQLITE_NOMEM; + }else{ + memset(pRet, 0, nByte); + } + } + return pRet; +} + + +/* +** Allocate and zero the pIter->azTblCol[] and abTblPk[] arrays so that +** there is room for at least nCol elements. If an OOM occurs, store an +** error code in the RBU handle passed as the first argument. +*/ +static void rbuAllocateIterArrays(sqlite3rbu *p, RbuObjIter *pIter, int nCol){ + sqlite3_int64 nByte = (2*sizeof(char*) + sizeof(int) + 3*sizeof(u8)) * nCol; + char **azNew; + + azNew = (char**)rbuMalloc(p, nByte); + if( azNew ){ + pIter->azTblCol = azNew; + pIter->azTblType = &azNew[nCol]; + pIter->aiSrcOrder = (int*)&pIter->azTblType[nCol]; + pIter->abTblPk = (u8*)&pIter->aiSrcOrder[nCol]; + pIter->abNotNull = (u8*)&pIter->abTblPk[nCol]; + pIter->abIndexed = (u8*)&pIter->abNotNull[nCol]; + } +} + +/* +** The first argument must be a nul-terminated string. This function +** returns a copy of the string in memory obtained from sqlite3_malloc(). +** It is the responsibility of the caller to eventually free this memory +** using sqlite3_free(). +** +** If an OOM condition is encountered when attempting to allocate memory, +** output variable (*pRc) is set to SQLITE_NOMEM before returning. Otherwise, +** if the allocation succeeds, (*pRc) is left unchanged. +*/ +static char *rbuStrndup(const char *zStr, int *pRc){ + char *zRet = 0; + + if( *pRc==SQLITE_OK ){ + if( zStr ){ + size_t nCopy = strlen(zStr) + 1; + zRet = (char*)sqlite3_malloc64(nCopy); + if( zRet ){ + memcpy(zRet, zStr, nCopy); + }else{ + *pRc = SQLITE_NOMEM; + } + } + } + + return zRet; +} + +/* +** Finalize the statement passed as the second argument. +** +** If the sqlite3_finalize() call indicates that an error occurs, and the +** rbu handle error code is not already set, set the error code and error +** message accordingly. +*/ +static void rbuFinalize(sqlite3rbu *p, sqlite3_stmt *pStmt){ + sqlite3 *db = sqlite3_db_handle(pStmt); + int rc = sqlite3_finalize(pStmt); + if( p->rc==SQLITE_OK && rc!=SQLITE_OK ){ + p->rc = rc; + p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + } +} + +/* Determine the type of a table. +** +** peType is of type (int*), a pointer to an output parameter of type +** (int). This call sets the output parameter as follows, depending +** on the type of the table specified by parameters dbName and zTbl. +** +** RBU_PK_NOTABLE: No such table. +** RBU_PK_NONE: Table has an implicit rowid. +** RBU_PK_IPK: Table has an explicit IPK column. +** RBU_PK_EXTERNAL: Table has an external PK index. +** RBU_PK_WITHOUT_ROWID: Table is WITHOUT ROWID. +** RBU_PK_VTAB: Table is a virtual table. +** +** Argument *piPk is also of type (int*), and also points to an output +** parameter. Unless the table has an external primary key index +** (i.e. unless *peType is set to 3), then *piPk is set to zero. Or, +** if the table does have an external primary key index, then *piPk +** is set to the root page number of the primary key index before +** returning. +** +** ALGORITHM: +** +** if( no entry exists in sqlite_schema ){ +** return RBU_PK_NOTABLE +** }else if( sql for the entry starts with "CREATE VIRTUAL" ){ +** return RBU_PK_VTAB +** }else if( "PRAGMA index_list()" for the table contains a "pk" index ){ +** if( the index that is the pk exists in sqlite_schema ){ +** *piPK = rootpage of that index. +** return RBU_PK_EXTERNAL +** }else{ +** return RBU_PK_WITHOUT_ROWID +** } +** }else if( "PRAGMA table_info()" lists one or more "pk" columns ){ +** return RBU_PK_IPK +** }else{ +** return RBU_PK_NONE +** } +*/ +static void rbuTableType( + sqlite3rbu *p, + const char *zTab, + int *peType, + int *piTnum, + int *piPk +){ + /* + ** 0) SELECT count(*) FROM sqlite_schema where name=%Q AND IsVirtual(%Q) + ** 1) PRAGMA index_list = ? + ** 2) SELECT count(*) FROM sqlite_schema where name=%Q + ** 3) PRAGMA table_info = ? + */ + sqlite3_stmt *aStmt[4] = {0, 0, 0, 0}; + + *peType = RBU_PK_NOTABLE; + *piPk = 0; + + assert( p->rc==SQLITE_OK ); + p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[0], &p->zErrmsg, + sqlite3_mprintf( + "SELECT " + " (sql COLLATE nocase BETWEEN 'CREATE VIRTUAL' AND 'CREATE VIRTUAM')," + " rootpage" + " FROM sqlite_schema" + " WHERE name=%Q", zTab + )); + if( p->rc!=SQLITE_OK || sqlite3_step(aStmt[0])!=SQLITE_ROW ){ + /* Either an error, or no such table. */ + goto rbuTableType_end; + } + if( sqlite3_column_int(aStmt[0], 0) ){ + *peType = RBU_PK_VTAB; /* virtual table */ + goto rbuTableType_end; + } + *piTnum = sqlite3_column_int(aStmt[0], 1); + + p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[1], &p->zErrmsg, + sqlite3_mprintf("PRAGMA index_list=%Q",zTab) + ); + if( p->rc ) goto rbuTableType_end; + while( sqlite3_step(aStmt[1])==SQLITE_ROW ){ + const u8 *zOrig = sqlite3_column_text(aStmt[1], 3); + const u8 *zIdx = sqlite3_column_text(aStmt[1], 1); + if( zOrig && zIdx && zOrig[0]=='p' ){ + p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[2], &p->zErrmsg, + sqlite3_mprintf( + "SELECT rootpage FROM sqlite_schema WHERE name = %Q", zIdx + )); + if( p->rc==SQLITE_OK ){ + if( sqlite3_step(aStmt[2])==SQLITE_ROW ){ + *piPk = sqlite3_column_int(aStmt[2], 0); + *peType = RBU_PK_EXTERNAL; + }else{ + *peType = RBU_PK_WITHOUT_ROWID; + } + } + goto rbuTableType_end; + } + } + + p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[3], &p->zErrmsg, + sqlite3_mprintf("PRAGMA table_info=%Q",zTab) + ); + if( p->rc==SQLITE_OK ){ + while( sqlite3_step(aStmt[3])==SQLITE_ROW ){ + if( sqlite3_column_int(aStmt[3],5)>0 ){ + *peType = RBU_PK_IPK; /* explicit IPK column */ + goto rbuTableType_end; + } + } + *peType = RBU_PK_NONE; + } + +rbuTableType_end: { + unsigned int i; + for(i=0; iabIndexed[] array. +*/ +static void rbuObjIterCacheIndexedCols(sqlite3rbu *p, RbuObjIter *pIter){ + sqlite3_stmt *pList = 0; + int bIndex = 0; + + if( p->rc==SQLITE_OK ){ + memcpy(pIter->abIndexed, pIter->abTblPk, sizeof(u8)*pIter->nTblCol); + p->rc = prepareFreeAndCollectError(p->dbMain, &pList, &p->zErrmsg, + sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl) + ); + } + + pIter->nIndex = 0; + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pList) ){ + const char *zIdx = (const char*)sqlite3_column_text(pList, 1); + int bPartial = sqlite3_column_int(pList, 4); + sqlite3_stmt *pXInfo = 0; + if( zIdx==0 ) break; + if( bPartial ){ + memset(pIter->abIndexed, 0x01, sizeof(u8)*pIter->nTblCol); + } + p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, + sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx) + ); + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ + int iCid = sqlite3_column_int(pXInfo, 1); + if( iCid>=0 ) pIter->abIndexed[iCid] = 1; + if( iCid==-2 ){ + memset(pIter->abIndexed, 0x01, sizeof(u8)*pIter->nTblCol); + } + } + rbuFinalize(p, pXInfo); + bIndex = 1; + pIter->nIndex++; + } + + if( pIter->eType==RBU_PK_WITHOUT_ROWID ){ + /* "PRAGMA index_list" includes the main PK b-tree */ + pIter->nIndex--; + } + + rbuFinalize(p, pList); + if( bIndex==0 ) pIter->abIndexed = 0; +} + + +/* +** If they are not already populated, populate the pIter->azTblCol[], +** pIter->abTblPk[], pIter->nTblCol and pIter->bRowid variables according to +** the table (not index) that the iterator currently points to. +** +** Return SQLITE_OK if successful, or an SQLite error code otherwise. If +** an error does occur, an error code and error message are also left in +** the RBU handle. +*/ +static int rbuObjIterCacheTableInfo(sqlite3rbu *p, RbuObjIter *pIter){ + if( pIter->azTblCol==0 ){ + sqlite3_stmt *pStmt = 0; + int nCol = 0; + int i; /* for() loop iterator variable */ + int bRbuRowid = 0; /* If input table has column "rbu_rowid" */ + int iOrder = 0; + int iTnum = 0; + + /* Figure out the type of table this step will deal with. */ + assert( pIter->eType==0 ); + rbuTableType(p, pIter->zTbl, &pIter->eType, &iTnum, &pIter->iPkTnum); + if( p->rc==SQLITE_OK && pIter->eType==RBU_PK_NOTABLE ){ + p->rc = SQLITE_ERROR; + p->zErrmsg = sqlite3_mprintf("no such table: %s", pIter->zTbl); + } + if( p->rc ) return p->rc; + if( pIter->zIdx==0 ) pIter->iTnum = iTnum; + + assert( pIter->eType==RBU_PK_NONE || pIter->eType==RBU_PK_IPK + || pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_WITHOUT_ROWID + || pIter->eType==RBU_PK_VTAB + ); + + /* Populate the azTblCol[] and nTblCol variables based on the columns + ** of the input table. Ignore any input table columns that begin with + ** "rbu_". */ + p->rc = prepareFreeAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg, + sqlite3_mprintf("SELECT * FROM '%q'", pIter->zDataTbl) + ); + if( p->rc==SQLITE_OK ){ + nCol = sqlite3_column_count(pStmt); + rbuAllocateIterArrays(p, pIter, nCol); + } + for(i=0; p->rc==SQLITE_OK && irc); + pIter->aiSrcOrder[pIter->nTblCol] = pIter->nTblCol; + pIter->azTblCol[pIter->nTblCol++] = zCopy; + } + else if( 0==sqlite3_stricmp("rbu_rowid", zName) ){ + bRbuRowid = 1; + } + } + sqlite3_finalize(pStmt); + pStmt = 0; + + if( p->rc==SQLITE_OK + && rbuIsVacuum(p)==0 + && bRbuRowid!=(pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE) + ){ + p->rc = SQLITE_ERROR; + p->zErrmsg = sqlite3_mprintf( + "table %q %s rbu_rowid column", pIter->zDataTbl, + (bRbuRowid ? "may not have" : "requires") + ); + } + + /* Check that all non-HIDDEN columns in the destination table are also + ** present in the input table. Populate the abTblPk[], azTblType[] and + ** aiTblOrder[] arrays at the same time. */ + if( p->rc==SQLITE_OK ){ + p->rc = prepareFreeAndCollectError(p->dbMain, &pStmt, &p->zErrmsg, + sqlite3_mprintf("PRAGMA table_info(%Q)", pIter->zTbl) + ); + } + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + const char *zName = (const char*)sqlite3_column_text(pStmt, 1); + if( zName==0 ) break; /* An OOM - finalize() below returns S_NOMEM */ + for(i=iOrder; inTblCol; i++){ + if( 0==strcmp(zName, pIter->azTblCol[i]) ) break; + } + if( i==pIter->nTblCol ){ + p->rc = SQLITE_ERROR; + p->zErrmsg = sqlite3_mprintf("column missing from %q: %s", + pIter->zDataTbl, zName + ); + }else{ + int iPk = sqlite3_column_int(pStmt, 5); + int bNotNull = sqlite3_column_int(pStmt, 3); + const char *zType = (const char*)sqlite3_column_text(pStmt, 2); + + if( i!=iOrder ){ + SWAP(int, pIter->aiSrcOrder[i], pIter->aiSrcOrder[iOrder]); + SWAP(char*, pIter->azTblCol[i], pIter->azTblCol[iOrder]); + } + + pIter->azTblType[iOrder] = rbuStrndup(zType, &p->rc); + assert( iPk>=0 ); + pIter->abTblPk[iOrder] = (u8)iPk; + pIter->abNotNull[iOrder] = (u8)bNotNull || (iPk!=0); + iOrder++; + } + } + + rbuFinalize(p, pStmt); + rbuObjIterCacheIndexedCols(p, pIter); + assert( pIter->eType!=RBU_PK_VTAB || pIter->abIndexed==0 ); + assert( pIter->eType!=RBU_PK_VTAB || pIter->nIndex==0 ); + } + + return p->rc; +} + +/* +** This function constructs and returns a pointer to a nul-terminated +** string containing some SQL clause or list based on one or more of the +** column names currently stored in the pIter->azTblCol[] array. +*/ +static char *rbuObjIterGetCollist( + sqlite3rbu *p, /* RBU object */ + RbuObjIter *pIter /* Object iterator for column names */ +){ + char *zList = 0; + const char *zSep = ""; + int i; + for(i=0; inTblCol; i++){ + const char *z = pIter->azTblCol[i]; + zList = rbuMPrintf(p, "%z%s\"%w\"", zList, zSep, z); + zSep = ", "; + } + return zList; +} + +/* +** Return a comma separated list of the quoted PRIMARY KEY column names, +** in order, for the current table. Before each column name, add the text +** zPre. After each column name, add the zPost text. Use zSeparator as +** the separator text (usually ", "). +*/ +static char *rbuObjIterGetPkList( + sqlite3rbu *p, /* RBU object */ + RbuObjIter *pIter, /* Object iterator for column names */ + const char *zPre, /* Before each quoted column name */ + const char *zSeparator, /* Separator to use between columns */ + const char *zPost /* After each quoted column name */ +){ + int iPk = 1; + char *zRet = 0; + const char *zSep = ""; + while( 1 ){ + int i; + for(i=0; inTblCol; i++){ + if( (int)pIter->abTblPk[i]==iPk ){ + const char *zCol = pIter->azTblCol[i]; + zRet = rbuMPrintf(p, "%z%s%s\"%w\"%s", zRet, zSep, zPre, zCol, zPost); + zSep = zSeparator; + break; + } + } + if( i==pIter->nTblCol ) break; + iPk++; + } + return zRet; +} + +/* +** This function is called as part of restarting an RBU vacuum within +** stage 1 of the process (while the *-oal file is being built) while +** updating a table (not an index). The table may be a rowid table or +** a WITHOUT ROWID table. It queries the target database to find the +** largest key that has already been written to the target table and +** constructs a WHERE clause that can be used to extract the remaining +** rows from the source table. For a rowid table, the WHERE clause +** is of the form: +** +** "WHERE _rowid_ > ?" +** +** and for WITHOUT ROWID tables: +** +** "WHERE (key1, key2) > (?, ?)" +** +** Instead of "?" placeholders, the actual WHERE clauses created by +** this function contain literal SQL values. +*/ +static char *rbuVacuumTableStart( + sqlite3rbu *p, /* RBU handle */ + RbuObjIter *pIter, /* RBU iterator object */ + int bRowid, /* True for a rowid table */ + const char *zWrite /* Target table name prefix */ +){ + sqlite3_stmt *pMax = 0; + char *zRet = 0; + if( bRowid ){ + p->rc = prepareFreeAndCollectError(p->dbMain, &pMax, &p->zErrmsg, + sqlite3_mprintf( + "SELECT max(_rowid_) FROM \"%s%w\"", zWrite, pIter->zTbl + ) + ); + if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){ + sqlite3_int64 iMax = sqlite3_column_int64(pMax, 0); + zRet = rbuMPrintf(p, " WHERE _rowid_ > %lld ", iMax); + } + rbuFinalize(p, pMax); + }else{ + char *zOrder = rbuObjIterGetPkList(p, pIter, "", ", ", " DESC"); + char *zSelect = rbuObjIterGetPkList(p, pIter, "quote(", "||','||", ")"); + char *zList = rbuObjIterGetPkList(p, pIter, "", ", ", ""); + + if( p->rc==SQLITE_OK ){ + p->rc = prepareFreeAndCollectError(p->dbMain, &pMax, &p->zErrmsg, + sqlite3_mprintf( + "SELECT %s FROM \"%s%w\" ORDER BY %s LIMIT 1", + zSelect, zWrite, pIter->zTbl, zOrder + ) + ); + if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){ + const char *zVal = (const char*)sqlite3_column_text(pMax, 0); + zRet = rbuMPrintf(p, " WHERE (%s) > (%s) ", zList, zVal); + } + rbuFinalize(p, pMax); + } + + sqlite3_free(zOrder); + sqlite3_free(zSelect); + sqlite3_free(zList); + } + return zRet; +} + +/* +** This function is called as part of restating an RBU vacuum when the +** current operation is writing content to an index. If possible, it +** queries the target index b-tree for the largest key already written to +** it, then composes and returns an expression that can be used in a WHERE +** clause to select the remaining required rows from the source table. +** It is only possible to return such an expression if: +** +** * The index contains no DESC columns, and +** * The last key written to the index before the operation was +** suspended does not contain any NULL values. +** +** The expression is of the form: +** +** (index-field1, index-field2, ...) > (?, ?, ...) +** +** except that the "?" placeholders are replaced with literal values. +** +** If the expression cannot be created, NULL is returned. In this case, +** the caller has to use an OFFSET clause to extract only the required +** rows from the sourct table, just as it does for an RBU update operation. +*/ +static char *rbuVacuumIndexStart( + sqlite3rbu *p, /* RBU handle */ + RbuObjIter *pIter /* RBU iterator object */ +){ + char *zOrder = 0; + char *zLhs = 0; + char *zSelect = 0; + char *zVector = 0; + char *zRet = 0; + int bFailed = 0; + const char *zSep = ""; + int iCol = 0; + sqlite3_stmt *pXInfo = 0; + + p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, + sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", pIter->zIdx) + ); + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ + int iCid = sqlite3_column_int(pXInfo, 1); + const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4); + const char *zCol; + if( sqlite3_column_int(pXInfo, 3) ){ + bFailed = 1; + break; + } + + if( iCid<0 ){ + if( pIter->eType==RBU_PK_IPK ){ + int i; + for(i=0; pIter->abTblPk[i]==0; i++); + assert( inTblCol ); + zCol = pIter->azTblCol[i]; + }else{ + zCol = "_rowid_"; + } + }else{ + zCol = pIter->azTblCol[iCid]; + } + + zLhs = rbuMPrintf(p, "%z%s \"%w\" COLLATE %Q", + zLhs, zSep, zCol, zCollate + ); + zOrder = rbuMPrintf(p, "%z%s \"rbu_imp_%d%w\" COLLATE %Q DESC", + zOrder, zSep, iCol, zCol, zCollate + ); + zSelect = rbuMPrintf(p, "%z%s quote(\"rbu_imp_%d%w\")", + zSelect, zSep, iCol, zCol + ); + zSep = ", "; + iCol++; + } + rbuFinalize(p, pXInfo); + if( bFailed ) goto index_start_out; + + if( p->rc==SQLITE_OK ){ + sqlite3_stmt *pSel = 0; + + p->rc = prepareFreeAndCollectError(p->dbMain, &pSel, &p->zErrmsg, + sqlite3_mprintf("SELECT %s FROM \"rbu_imp_%w\" ORDER BY %s LIMIT 1", + zSelect, pIter->zTbl, zOrder + ) + ); + if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSel) ){ + zSep = ""; + for(iCol=0; iColnCol; iCol++){ + const char *zQuoted = (const char*)sqlite3_column_text(pSel, iCol); + if( zQuoted==0 ){ + p->rc = SQLITE_NOMEM; + }else if( zQuoted[0]=='N' ){ + bFailed = 1; + break; + } + zVector = rbuMPrintf(p, "%z%s%s", zVector, zSep, zQuoted); + zSep = ", "; + } + + if( !bFailed ){ + zRet = rbuMPrintf(p, "(%s) > (%s)", zLhs, zVector); + } + } + rbuFinalize(p, pSel); + } + + index_start_out: + sqlite3_free(zOrder); + sqlite3_free(zSelect); + sqlite3_free(zVector); + sqlite3_free(zLhs); + return zRet; +} + +/* +** This function is used to create a SELECT list (the list of SQL +** expressions that follows a SELECT keyword) for a SELECT statement +** used to read from an data_xxx or rbu_tmp_xxx table while updating the +** index object currently indicated by the iterator object passed as the +** second argument. A "PRAGMA index_xinfo = " statement is used +** to obtain the required information. +** +** If the index is of the following form: +** +** CREATE INDEX i1 ON t1(c, b COLLATE nocase); +** +** and "t1" is a table with an explicit INTEGER PRIMARY KEY column +** "ipk", the returned string is: +** +** "`c` COLLATE 'BINARY', `b` COLLATE 'NOCASE', `ipk` COLLATE 'BINARY'" +** +** As well as the returned string, three other malloc'd strings are +** returned via output parameters. As follows: +** +** pzImposterCols: ... +** pzImposterPk: ... +** pzWhere: ... +*/ +static char *rbuObjIterGetIndexCols( + sqlite3rbu *p, /* RBU object */ + RbuObjIter *pIter, /* Object iterator for column names */ + char **pzImposterCols, /* OUT: Columns for imposter table */ + char **pzImposterPk, /* OUT: Imposter PK clause */ + char **pzWhere, /* OUT: WHERE clause */ + int *pnBind /* OUT: Trbul number of columns */ +){ + int rc = p->rc; /* Error code */ + int rc2; /* sqlite3_finalize() return code */ + char *zRet = 0; /* String to return */ + char *zImpCols = 0; /* String to return via *pzImposterCols */ + char *zImpPK = 0; /* String to return via *pzImposterPK */ + char *zWhere = 0; /* String to return via *pzWhere */ + int nBind = 0; /* Value to return via *pnBind */ + const char *zCom = ""; /* Set to ", " later on */ + const char *zAnd = ""; /* Set to " AND " later on */ + sqlite3_stmt *pXInfo = 0; /* PRAGMA index_xinfo = ? */ + + if( rc==SQLITE_OK ){ + assert( p->zErrmsg==0 ); + rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, + sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", pIter->zIdx) + ); + } + + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ + int iCid = sqlite3_column_int(pXInfo, 1); + int bDesc = sqlite3_column_int(pXInfo, 3); + const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4); + const char *zCol = 0; + const char *zType; + + if( iCid==-2 ){ + int iSeq = sqlite3_column_int(pXInfo, 0); + zRet = sqlite3_mprintf("%z%s(%.*s) COLLATE %Q", zRet, zCom, + pIter->aIdxCol[iSeq].nSpan, pIter->aIdxCol[iSeq].zSpan, zCollate + ); + zType = ""; + }else { + if( iCid<0 ){ + /* An integer primary key. If the table has an explicit IPK, use + ** its name. Otherwise, use "rbu_rowid". */ + if( pIter->eType==RBU_PK_IPK ){ + int i; + for(i=0; pIter->abTblPk[i]==0; i++); + assert( inTblCol ); + zCol = pIter->azTblCol[i]; + }else if( rbuIsVacuum(p) ){ + zCol = "_rowid_"; + }else{ + zCol = "rbu_rowid"; + } + zType = "INTEGER"; + }else{ + zCol = pIter->azTblCol[iCid]; + zType = pIter->azTblType[iCid]; + } + zRet = sqlite3_mprintf("%z%s\"%w\" COLLATE %Q", zRet, zCom,zCol,zCollate); + } + + if( pIter->bUnique==0 || sqlite3_column_int(pXInfo, 5) ){ + const char *zOrder = (bDesc ? " DESC" : ""); + zImpPK = sqlite3_mprintf("%z%s\"rbu_imp_%d%w\"%s", + zImpPK, zCom, nBind, zCol, zOrder + ); + } + zImpCols = sqlite3_mprintf("%z%s\"rbu_imp_%d%w\" %s COLLATE %Q", + zImpCols, zCom, nBind, zCol, zType, zCollate + ); + zWhere = sqlite3_mprintf( + "%z%s\"rbu_imp_%d%w\" IS ?", zWhere, zAnd, nBind, zCol + ); + if( zRet==0 || zImpPK==0 || zImpCols==0 || zWhere==0 ) rc = SQLITE_NOMEM; + zCom = ", "; + zAnd = " AND "; + nBind++; + } + + rc2 = sqlite3_finalize(pXInfo); + if( rc==SQLITE_OK ) rc = rc2; + + if( rc!=SQLITE_OK ){ + sqlite3_free(zRet); + sqlite3_free(zImpCols); + sqlite3_free(zImpPK); + sqlite3_free(zWhere); + zRet = 0; + zImpCols = 0; + zImpPK = 0; + zWhere = 0; + p->rc = rc; + } + + *pzImposterCols = zImpCols; + *pzImposterPk = zImpPK; + *pzWhere = zWhere; + *pnBind = nBind; + return zRet; +} + +/* +** Assuming the current table columns are "a", "b" and "c", and the zObj +** paramter is passed "old", return a string of the form: +** +** "old.a, old.b, old.b" +** +** With the column names escaped. +** +** For tables with implicit rowids - RBU_PK_EXTERNAL and RBU_PK_NONE, append +** the text ", old._rowid_" to the returned value. +*/ +static char *rbuObjIterGetOldlist( + sqlite3rbu *p, + RbuObjIter *pIter, + const char *zObj +){ + char *zList = 0; + if( p->rc==SQLITE_OK && pIter->abIndexed ){ + const char *zS = ""; + int i; + for(i=0; inTblCol; i++){ + if( pIter->abIndexed[i] ){ + const char *zCol = pIter->azTblCol[i]; + zList = sqlite3_mprintf("%z%s%s.\"%w\"", zList, zS, zObj, zCol); + }else{ + zList = sqlite3_mprintf("%z%sNULL", zList, zS); + } + zS = ", "; + if( zList==0 ){ + p->rc = SQLITE_NOMEM; + break; + } + } + + /* For a table with implicit rowids, append "old._rowid_" to the list. */ + if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){ + zList = rbuMPrintf(p, "%z, %s._rowid_", zList, zObj); + } + } + return zList; +} + +/* +** Return an expression that can be used in a WHERE clause to match the +** primary key of the current table. For example, if the table is: +** +** CREATE TABLE t1(a, b, c, PRIMARY KEY(b, c)); +** +** Return the string: +** +** "b = ?1 AND c = ?2" +*/ +static char *rbuObjIterGetWhere( + sqlite3rbu *p, + RbuObjIter *pIter +){ + char *zList = 0; + if( pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE ){ + zList = rbuMPrintf(p, "_rowid_ = ?%d", pIter->nTblCol+1); + }else if( pIter->eType==RBU_PK_EXTERNAL ){ + const char *zSep = ""; + int i; + for(i=0; inTblCol; i++){ + if( pIter->abTblPk[i] ){ + zList = rbuMPrintf(p, "%z%sc%d=?%d", zList, zSep, i, i+1); + zSep = " AND "; + } + } + zList = rbuMPrintf(p, + "_rowid_ = (SELECT id FROM rbu_imposter2 WHERE %z)", zList + ); + + }else{ + const char *zSep = ""; + int i; + for(i=0; inTblCol; i++){ + if( pIter->abTblPk[i] ){ + const char *zCol = pIter->azTblCol[i]; + zList = rbuMPrintf(p, "%z%s\"%w\"=?%d", zList, zSep, zCol, i+1); + zSep = " AND "; + } + } + } + return zList; +} + +/* +** The SELECT statement iterating through the keys for the current object +** (p->objiter.pSelect) currently points to a valid row. However, there +** is something wrong with the rbu_control value in the rbu_control value +** stored in the (p->nCol+1)'th column. Set the error code and error message +** of the RBU handle to something reflecting this. +*/ +static void rbuBadControlError(sqlite3rbu *p){ + p->rc = SQLITE_ERROR; + p->zErrmsg = sqlite3_mprintf("invalid rbu_control value"); +} + + +/* +** Return a nul-terminated string containing the comma separated list of +** assignments that should be included following the "SET" keyword of +** an UPDATE statement used to update the table object that the iterator +** passed as the second argument currently points to if the rbu_control +** column of the data_xxx table entry is set to zMask. +** +** The memory for the returned string is obtained from sqlite3_malloc(). +** It is the responsibility of the caller to eventually free it using +** sqlite3_free(). +** +** If an OOM error is encountered when allocating space for the new +** string, an error code is left in the rbu handle passed as the first +** argument and NULL is returned. Or, if an error has already occurred +** when this function is called, NULL is returned immediately, without +** attempting the allocation or modifying the stored error code. +*/ +static char *rbuObjIterGetSetlist( + sqlite3rbu *p, + RbuObjIter *pIter, + const char *zMask +){ + char *zList = 0; + if( p->rc==SQLITE_OK ){ + int i; + + if( (int)strlen(zMask)!=pIter->nTblCol ){ + rbuBadControlError(p); + }else{ + const char *zSep = ""; + for(i=0; inTblCol; i++){ + char c = zMask[pIter->aiSrcOrder[i]]; + if( c=='x' ){ + zList = rbuMPrintf(p, "%z%s\"%w\"=?%d", + zList, zSep, pIter->azTblCol[i], i+1 + ); + zSep = ", "; + } + else if( c=='d' ){ + zList = rbuMPrintf(p, "%z%s\"%w\"=rbu_delta(\"%w\", ?%d)", + zList, zSep, pIter->azTblCol[i], pIter->azTblCol[i], i+1 + ); + zSep = ", "; + } + else if( c=='f' ){ + zList = rbuMPrintf(p, "%z%s\"%w\"=rbu_fossil_delta(\"%w\", ?%d)", + zList, zSep, pIter->azTblCol[i], pIter->azTblCol[i], i+1 + ); + zSep = ", "; + } + } + } + } + return zList; +} + +/* +** Return a nul-terminated string consisting of nByte comma separated +** "?" expressions. For example, if nByte is 3, return a pointer to +** a buffer containing the string "?,?,?". +** +** The memory for the returned string is obtained from sqlite3_malloc(). +** It is the responsibility of the caller to eventually free it using +** sqlite3_free(). +** +** If an OOM error is encountered when allocating space for the new +** string, an error code is left in the rbu handle passed as the first +** argument and NULL is returned. Or, if an error has already occurred +** when this function is called, NULL is returned immediately, without +** attempting the allocation or modifying the stored error code. +*/ +static char *rbuObjIterGetBindlist(sqlite3rbu *p, int nBind){ + char *zRet = 0; + sqlite3_int64 nByte = 2*(sqlite3_int64)nBind + 1; + + zRet = (char*)rbuMalloc(p, nByte); + if( zRet ){ + int i; + for(i=0; izIdx==0 ); + if( p->rc==SQLITE_OK ){ + const char *zSep = "PRIMARY KEY("; + sqlite3_stmt *pXList = 0; /* PRAGMA index_list = (pIter->zTbl) */ + sqlite3_stmt *pXInfo = 0; /* PRAGMA index_xinfo = */ + + p->rc = prepareFreeAndCollectError(p->dbMain, &pXList, &p->zErrmsg, + sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl) + ); + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXList) ){ + const char *zOrig = (const char*)sqlite3_column_text(pXList,3); + if( zOrig && strcmp(zOrig, "pk")==0 ){ + const char *zIdx = (const char*)sqlite3_column_text(pXList,1); + if( zIdx ){ + p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, + sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx) + ); + } + break; + } + } + rbuFinalize(p, pXList); + + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ + if( sqlite3_column_int(pXInfo, 5) ){ + /* int iCid = sqlite3_column_int(pXInfo, 0); */ + const char *zCol = (const char*)sqlite3_column_text(pXInfo, 2); + const char *zDesc = sqlite3_column_int(pXInfo, 3) ? " DESC" : ""; + z = rbuMPrintf(p, "%z%s\"%w\"%s", z, zSep, zCol, zDesc); + zSep = ", "; + } + } + z = rbuMPrintf(p, "%z)", z); + rbuFinalize(p, pXInfo); + } + return z; +} + +/* +** This function creates the second imposter table used when writing to +** a table b-tree where the table has an external primary key. If the +** iterator passed as the second argument does not currently point to +** a table (not index) with an external primary key, this function is a +** no-op. +** +** Assuming the iterator does point to a table with an external PK, this +** function creates a WITHOUT ROWID imposter table named "rbu_imposter2" +** used to access that PK index. For example, if the target table is +** declared as follows: +** +** CREATE TABLE t1(a, b TEXT, c REAL, PRIMARY KEY(b, c)); +** +** then the imposter table schema is: +** +** CREATE TABLE rbu_imposter2(c1 TEXT, c2 REAL, id INTEGER) WITHOUT ROWID; +** +*/ +static void rbuCreateImposterTable2(sqlite3rbu *p, RbuObjIter *pIter){ + if( p->rc==SQLITE_OK && pIter->eType==RBU_PK_EXTERNAL ){ + int tnum = pIter->iPkTnum; /* Root page of PK index */ + sqlite3_stmt *pQuery = 0; /* SELECT name ... WHERE rootpage = $tnum */ + const char *zIdx = 0; /* Name of PK index */ + sqlite3_stmt *pXInfo = 0; /* PRAGMA main.index_xinfo = $zIdx */ + const char *zComma = ""; + char *zCols = 0; /* Used to build up list of table cols */ + char *zPk = 0; /* Used to build up table PK declaration */ + + /* Figure out the name of the primary key index for the current table. + ** This is needed for the argument to "PRAGMA index_xinfo". Set + ** zIdx to point to a nul-terminated string containing this name. */ + p->rc = prepareAndCollectError(p->dbMain, &pQuery, &p->zErrmsg, + "SELECT name FROM sqlite_schema WHERE rootpage = ?" + ); + if( p->rc==SQLITE_OK ){ + sqlite3_bind_int(pQuery, 1, tnum); + if( SQLITE_ROW==sqlite3_step(pQuery) ){ + zIdx = (const char*)sqlite3_column_text(pQuery, 0); + } + } + if( zIdx ){ + p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, + sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx) + ); + } + rbuFinalize(p, pQuery); + + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ + int bKey = sqlite3_column_int(pXInfo, 5); + if( bKey ){ + int iCid = sqlite3_column_int(pXInfo, 1); + int bDesc = sqlite3_column_int(pXInfo, 3); + const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4); + zCols = rbuMPrintf(p, "%z%sc%d %s COLLATE %Q", zCols, zComma, + iCid, pIter->azTblType[iCid], zCollate + ); + zPk = rbuMPrintf(p, "%z%sc%d%s", zPk, zComma, iCid, bDesc?" DESC":""); + zComma = ", "; + } + } + zCols = rbuMPrintf(p, "%z, id INTEGER", zCols); + rbuFinalize(p, pXInfo); + + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1, tnum); + rbuMPrintfExec(p, p->dbMain, + "CREATE TABLE rbu_imposter2(%z, PRIMARY KEY(%z)) WITHOUT ROWID", + zCols, zPk + ); + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0); + } +} + +/* +** If an error has already occurred when this function is called, it +** immediately returns zero (without doing any work). Or, if an error +** occurs during the execution of this function, it sets the error code +** in the sqlite3rbu object indicated by the first argument and returns +** zero. +** +** The iterator passed as the second argument is guaranteed to point to +** a table (not an index) when this function is called. This function +** attempts to create any imposter table required to write to the main +** table b-tree of the table before returning. Non-zero is returned if +** an imposter table are created, or zero otherwise. +** +** An imposter table is required in all cases except RBU_PK_VTAB. Only +** virtual tables are written to directly. The imposter table has the +** same schema as the actual target table (less any UNIQUE constraints). +** More precisely, the "same schema" means the same columns, types, +** collation sequences. For tables that do not have an external PRIMARY +** KEY, it also means the same PRIMARY KEY declaration. +*/ +static void rbuCreateImposterTable(sqlite3rbu *p, RbuObjIter *pIter){ + if( p->rc==SQLITE_OK && pIter->eType!=RBU_PK_VTAB ){ + int tnum = pIter->iTnum; + const char *zComma = ""; + char *zSql = 0; + int iCol; + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1); + + for(iCol=0; p->rc==SQLITE_OK && iColnTblCol; iCol++){ + const char *zPk = ""; + const char *zCol = pIter->azTblCol[iCol]; + const char *zColl = 0; + + p->rc = sqlite3_table_column_metadata( + p->dbMain, "main", pIter->zTbl, zCol, 0, &zColl, 0, 0, 0 + ); + + if( pIter->eType==RBU_PK_IPK && pIter->abTblPk[iCol] ){ + /* If the target table column is an "INTEGER PRIMARY KEY", add + ** "PRIMARY KEY" to the imposter table column declaration. */ + zPk = "PRIMARY KEY "; + } + zSql = rbuMPrintf(p, "%z%s\"%w\" %s %sCOLLATE %Q%s", + zSql, zComma, zCol, pIter->azTblType[iCol], zPk, zColl, + (pIter->abNotNull[iCol] ? " NOT NULL" : "") + ); + zComma = ", "; + } + + if( pIter->eType==RBU_PK_WITHOUT_ROWID ){ + char *zPk = rbuWithoutRowidPK(p, pIter); + if( zPk ){ + zSql = rbuMPrintf(p, "%z, %z", zSql, zPk); + } + } + + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1, tnum); + rbuMPrintfExec(p, p->dbMain, "CREATE TABLE \"rbu_imp_%w\"(%z)%s", + pIter->zTbl, zSql, + (pIter->eType==RBU_PK_WITHOUT_ROWID ? " WITHOUT ROWID" : "") + ); + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0); + } +} + +/* +** Prepare a statement used to insert rows into the "rbu_tmp_xxx" table. +** Specifically a statement of the form: +** +** INSERT INTO rbu_tmp_xxx VALUES(?, ?, ? ...); +** +** The number of bound variables is equal to the number of columns in +** the target table, plus one (for the rbu_control column), plus one more +** (for the rbu_rowid column) if the target table is an implicit IPK or +** virtual table. +*/ +static void rbuObjIterPrepareTmpInsert( + sqlite3rbu *p, + RbuObjIter *pIter, + const char *zCollist, + const char *zRbuRowid +){ + int bRbuRowid = (pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE); + char *zBind = rbuObjIterGetBindlist(p, pIter->nTblCol + 1 + bRbuRowid); + if( zBind ){ + assert( pIter->pTmpInsert==0 ); + p->rc = prepareFreeAndCollectError( + p->dbRbu, &pIter->pTmpInsert, &p->zErrmsg, sqlite3_mprintf( + "INSERT INTO %s.'rbu_tmp_%q'(rbu_control,%s%s) VALUES(%z)", + p->zStateDb, pIter->zDataTbl, zCollist, zRbuRowid, zBind + )); + } +} + +static void rbuTmpInsertFunc( + sqlite3_context *pCtx, + int nVal, + sqlite3_value **apVal +){ + sqlite3rbu *p = sqlite3_user_data(pCtx); + int rc = SQLITE_OK; + int i; + + assert( sqlite3_value_int(apVal[0])!=0 + || p->objiter.eType==RBU_PK_EXTERNAL + || p->objiter.eType==RBU_PK_NONE + ); + if( sqlite3_value_int(apVal[0])!=0 ){ + p->nPhaseOneStep += p->objiter.nIndex; + } + + for(i=0; rc==SQLITE_OK && iobjiter.pTmpInsert, i+1, apVal[i]); + } + if( rc==SQLITE_OK ){ + sqlite3_step(p->objiter.pTmpInsert); + rc = sqlite3_reset(p->objiter.pTmpInsert); + } + + if( rc!=SQLITE_OK ){ + sqlite3_result_error_code(pCtx, rc); + } +} + +static char *rbuObjIterGetIndexWhere(sqlite3rbu *p, RbuObjIter *pIter){ + sqlite3_stmt *pStmt = 0; + int rc = p->rc; + char *zRet = 0; + + assert( pIter->zIdxSql==0 && pIter->nIdxCol==0 && pIter->aIdxCol==0 ); + + if( rc==SQLITE_OK ){ + rc = prepareAndCollectError(p->dbMain, &pStmt, &p->zErrmsg, + "SELECT trim(sql) FROM sqlite_schema WHERE type='index' AND name=?" + ); + } + if( rc==SQLITE_OK ){ + int rc2; + rc = sqlite3_bind_text(pStmt, 1, pIter->zIdx, -1, SQLITE_STATIC); + if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + char *zSql = (char*)sqlite3_column_text(pStmt, 0); + if( zSql ){ + pIter->zIdxSql = zSql = rbuStrndup(zSql, &rc); + } + if( zSql ){ + int nParen = 0; /* Number of open parenthesis */ + int i; + int iIdxCol = 0; + int nIdxAlloc = 0; + for(i=0; zSql[i]; i++){ + char c = zSql[i]; + + /* If necessary, grow the pIter->aIdxCol[] array */ + if( iIdxCol==nIdxAlloc ){ + RbuSpan *aIdxCol = (RbuSpan*)sqlite3_realloc64( + pIter->aIdxCol, nIdxAlloc*sizeof(RbuSpan) + 16*sizeof(RbuSpan) + ); + if( aIdxCol==0 ){ + rc = SQLITE_NOMEM; + break; + } + pIter->aIdxCol = aIdxCol; + nIdxAlloc += 16; + } + + if( c=='(' ){ + if( nParen==0 ){ + assert( iIdxCol==0 ); + pIter->aIdxCol[0].zSpan = &zSql[i+1]; + } + nParen++; + } + else if( c==')' ){ + nParen--; + if( nParen==0 ){ + int nSpan = (int)(&zSql[i] - pIter->aIdxCol[iIdxCol].zSpan); + pIter->aIdxCol[iIdxCol++].nSpan = nSpan; + i++; + break; + } + }else if( c==',' && nParen==1 ){ + int nSpan = (int)(&zSql[i] - pIter->aIdxCol[iIdxCol].zSpan); + pIter->aIdxCol[iIdxCol++].nSpan = nSpan; + pIter->aIdxCol[iIdxCol].zSpan = &zSql[i+1]; + }else if( c=='"' || c=='\'' || c=='`' ){ + for(i++; 1; i++){ + if( zSql[i]==c ){ + if( zSql[i+1]!=c ) break; + i++; + } + } + }else if( c=='[' ){ + for(i++; 1; i++){ + if( zSql[i]==']' ) break; + } + }else if( c=='-' && zSql[i+1]=='-' ){ + for(i=i+2; zSql[i] && zSql[i]!='\n'; i++); + if( zSql[i]=='\0' ) break; + }else if( c=='/' && zSql[i+1]=='*' ){ + for(i=i+2; zSql[i] && (zSql[i]!='*' || zSql[i+1]!='/'); i++); + if( zSql[i]=='\0' ) break; + i++; + } + } + if( zSql[i] ){ + zRet = rbuStrndup(&zSql[i], &rc); + } + pIter->nIdxCol = iIdxCol; + } + } + + rc2 = sqlite3_finalize(pStmt); + if( rc==SQLITE_OK ) rc = rc2; + } + + p->rc = rc; + return zRet; +} + +/* +** Ensure that the SQLite statement handles required to update the +** target database object currently indicated by the iterator passed +** as the second argument are available. +*/ +static int rbuObjIterPrepareAll( + sqlite3rbu *p, + RbuObjIter *pIter, + int nOffset /* Add "LIMIT -1 OFFSET $nOffset" to SELECT */ +){ + assert( pIter->bCleanup==0 ); + if( pIter->pSelect==0 && rbuObjIterCacheTableInfo(p, pIter)==SQLITE_OK ){ + const int tnum = pIter->iTnum; + char *zCollist = 0; /* List of indexed columns */ + char **pz = &p->zErrmsg; + const char *zIdx = pIter->zIdx; + char *zLimit = 0; + + if( nOffset ){ + zLimit = sqlite3_mprintf(" LIMIT -1 OFFSET %d", nOffset); + if( !zLimit ) p->rc = SQLITE_NOMEM; + } + + if( zIdx ){ + const char *zTbl = pIter->zTbl; + char *zImposterCols = 0; /* Columns for imposter table */ + char *zImposterPK = 0; /* Primary key declaration for imposter */ + char *zWhere = 0; /* WHERE clause on PK columns */ + char *zBind = 0; + char *zPart = 0; + int nBind = 0; + + assert( pIter->eType!=RBU_PK_VTAB ); + zPart = rbuObjIterGetIndexWhere(p, pIter); + zCollist = rbuObjIterGetIndexCols( + p, pIter, &zImposterCols, &zImposterPK, &zWhere, &nBind + ); + zBind = rbuObjIterGetBindlist(p, nBind); + + /* Create the imposter table used to write to this index. */ + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1); + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1,tnum); + rbuMPrintfExec(p, p->dbMain, + "CREATE TABLE \"rbu_imp_%w\"( %s, PRIMARY KEY( %s ) ) WITHOUT ROWID", + zTbl, zImposterCols, zImposterPK + ); + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0); + + /* Create the statement to insert index entries */ + pIter->nCol = nBind; + if( p->rc==SQLITE_OK ){ + p->rc = prepareFreeAndCollectError( + p->dbMain, &pIter->pInsert, &p->zErrmsg, + sqlite3_mprintf("INSERT INTO \"rbu_imp_%w\" VALUES(%s)", zTbl, zBind) + ); + } + + /* And to delete index entries */ + if( rbuIsVacuum(p)==0 && p->rc==SQLITE_OK ){ + p->rc = prepareFreeAndCollectError( + p->dbMain, &pIter->pDelete, &p->zErrmsg, + sqlite3_mprintf("DELETE FROM \"rbu_imp_%w\" WHERE %s", zTbl, zWhere) + ); + } + + /* Create the SELECT statement to read keys in sorted order */ + if( p->rc==SQLITE_OK ){ + char *zSql; + if( rbuIsVacuum(p) ){ + char *zStart = 0; + if( nOffset ){ + zStart = rbuVacuumIndexStart(p, pIter); + if( zStart ){ + sqlite3_free(zLimit); + zLimit = 0; + } + } + + zSql = sqlite3_mprintf( + "SELECT %s, 0 AS rbu_control FROM '%q' %s %s %s ORDER BY %s%s", + zCollist, + pIter->zDataTbl, + zPart, + (zStart ? (zPart ? "AND" : "WHERE") : ""), zStart, + zCollist, zLimit + ); + sqlite3_free(zStart); + }else + + if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){ + zSql = sqlite3_mprintf( + "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' %s ORDER BY %s%s", + zCollist, p->zStateDb, pIter->zDataTbl, + zPart, zCollist, zLimit + ); + }else{ + zSql = sqlite3_mprintf( + "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' %s " + "UNION ALL " + "SELECT %s, rbu_control FROM '%q' " + "%s %s typeof(rbu_control)='integer' AND rbu_control!=1 " + "ORDER BY %s%s", + zCollist, p->zStateDb, pIter->zDataTbl, zPart, + zCollist, pIter->zDataTbl, + zPart, + (zPart ? "AND" : "WHERE"), + zCollist, zLimit + ); + } + if( p->rc==SQLITE_OK ){ + p->rc = prepareFreeAndCollectError(p->dbRbu,&pIter->pSelect,pz,zSql); + }else{ + sqlite3_free(zSql); + } + } + + sqlite3_free(zImposterCols); + sqlite3_free(zImposterPK); + sqlite3_free(zWhere); + sqlite3_free(zBind); + sqlite3_free(zPart); + }else{ + int bRbuRowid = (pIter->eType==RBU_PK_VTAB) + ||(pIter->eType==RBU_PK_NONE) + ||(pIter->eType==RBU_PK_EXTERNAL && rbuIsVacuum(p)); + const char *zTbl = pIter->zTbl; /* Table this step applies to */ + const char *zWrite; /* Imposter table name */ + + char *zBindings = rbuObjIterGetBindlist(p, pIter->nTblCol + bRbuRowid); + char *zWhere = rbuObjIterGetWhere(p, pIter); + char *zOldlist = rbuObjIterGetOldlist(p, pIter, "old"); + char *zNewlist = rbuObjIterGetOldlist(p, pIter, "new"); + + zCollist = rbuObjIterGetCollist(p, pIter); + pIter->nCol = pIter->nTblCol; + + /* Create the imposter table or tables (if required). */ + rbuCreateImposterTable(p, pIter); + rbuCreateImposterTable2(p, pIter); + zWrite = (pIter->eType==RBU_PK_VTAB ? "" : "rbu_imp_"); + + /* Create the INSERT statement to write to the target PK b-tree */ + if( p->rc==SQLITE_OK ){ + p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pInsert, pz, + sqlite3_mprintf( + "INSERT INTO \"%s%w\"(%s%s) VALUES(%s)", + zWrite, zTbl, zCollist, (bRbuRowid ? ", _rowid_" : ""), zBindings + ) + ); + } + + /* Create the DELETE statement to write to the target PK b-tree. + ** Because it only performs INSERT operations, this is not required for + ** an rbu vacuum handle. */ + if( rbuIsVacuum(p)==0 && p->rc==SQLITE_OK ){ + p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pDelete, pz, + sqlite3_mprintf( + "DELETE FROM \"%s%w\" WHERE %s", zWrite, zTbl, zWhere + ) + ); + } + + if( rbuIsVacuum(p)==0 && pIter->abIndexed ){ + const char *zRbuRowid = ""; + if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){ + zRbuRowid = ", rbu_rowid"; + } + + /* Create the rbu_tmp_xxx table and the triggers to populate it. */ + rbuMPrintfExec(p, p->dbRbu, + "CREATE TABLE IF NOT EXISTS %s.'rbu_tmp_%q' AS " + "SELECT *%s FROM '%q' WHERE 0;" + , p->zStateDb, pIter->zDataTbl + , (pIter->eType==RBU_PK_EXTERNAL ? ", 0 AS rbu_rowid" : "") + , pIter->zDataTbl + ); + + rbuMPrintfExec(p, p->dbMain, + "CREATE TEMP TRIGGER rbu_delete_tr BEFORE DELETE ON \"%s%w\" " + "BEGIN " + " SELECT rbu_tmp_insert(3, %s);" + "END;" + + "CREATE TEMP TRIGGER rbu_update1_tr BEFORE UPDATE ON \"%s%w\" " + "BEGIN " + " SELECT rbu_tmp_insert(3, %s);" + "END;" + + "CREATE TEMP TRIGGER rbu_update2_tr AFTER UPDATE ON \"%s%w\" " + "BEGIN " + " SELECT rbu_tmp_insert(4, %s);" + "END;", + zWrite, zTbl, zOldlist, + zWrite, zTbl, zOldlist, + zWrite, zTbl, zNewlist + ); + + if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){ + rbuMPrintfExec(p, p->dbMain, + "CREATE TEMP TRIGGER rbu_insert_tr AFTER INSERT ON \"%s%w\" " + "BEGIN " + " SELECT rbu_tmp_insert(0, %s);" + "END;", + zWrite, zTbl, zNewlist + ); + } + + rbuObjIterPrepareTmpInsert(p, pIter, zCollist, zRbuRowid); + } + + /* Create the SELECT statement to read keys from data_xxx */ + if( p->rc==SQLITE_OK ){ + const char *zRbuRowid = ""; + char *zStart = 0; + char *zOrder = 0; + if( bRbuRowid ){ + zRbuRowid = rbuIsVacuum(p) ? ",_rowid_ " : ",rbu_rowid"; + } + + if( rbuIsVacuum(p) ){ + if( nOffset ){ + zStart = rbuVacuumTableStart(p, pIter, bRbuRowid, zWrite); + if( zStart ){ + sqlite3_free(zLimit); + zLimit = 0; + } + } + if( bRbuRowid ){ + zOrder = rbuMPrintf(p, "_rowid_"); + }else{ + zOrder = rbuObjIterGetPkList(p, pIter, "", ", ", ""); + } + } + + if( p->rc==SQLITE_OK ){ + p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, + sqlite3_mprintf( + "SELECT %s,%s rbu_control%s FROM '%q'%s %s %s %s", + zCollist, + (rbuIsVacuum(p) ? "0 AS " : ""), + zRbuRowid, + pIter->zDataTbl, (zStart ? zStart : ""), + (zOrder ? "ORDER BY" : ""), zOrder, + zLimit + ) + ); + } + sqlite3_free(zStart); + sqlite3_free(zOrder); + } + + sqlite3_free(zWhere); + sqlite3_free(zOldlist); + sqlite3_free(zNewlist); + sqlite3_free(zBindings); + } + sqlite3_free(zCollist); + sqlite3_free(zLimit); + } + + return p->rc; +} + +/* +** Set output variable *ppStmt to point to an UPDATE statement that may +** be used to update the imposter table for the main table b-tree of the +** table object that pIter currently points to, assuming that the +** rbu_control column of the data_xyz table contains zMask. +** +** If the zMask string does not specify any columns to update, then this +** is not an error. Output variable *ppStmt is set to NULL in this case. +*/ +static int rbuGetUpdateStmt( + sqlite3rbu *p, /* RBU handle */ + RbuObjIter *pIter, /* Object iterator */ + const char *zMask, /* rbu_control value ('x.x.') */ + sqlite3_stmt **ppStmt /* OUT: UPDATE statement handle */ +){ + RbuUpdateStmt **pp; + RbuUpdateStmt *pUp = 0; + int nUp = 0; + + /* In case an error occurs */ + *ppStmt = 0; + + /* Search for an existing statement. If one is found, shift it to the front + ** of the LRU queue and return immediately. Otherwise, leave nUp pointing + ** to the number of statements currently in the cache and pUp to the + ** last object in the list. */ + for(pp=&pIter->pRbuUpdate; *pp; pp=&((*pp)->pNext)){ + pUp = *pp; + if( strcmp(pUp->zMask, zMask)==0 ){ + *pp = pUp->pNext; + pUp->pNext = pIter->pRbuUpdate; + pIter->pRbuUpdate = pUp; + *ppStmt = pUp->pUpdate; + return SQLITE_OK; + } + nUp++; + } + assert( pUp==0 || pUp->pNext==0 ); + + if( nUp>=SQLITE_RBU_UPDATE_CACHESIZE ){ + for(pp=&pIter->pRbuUpdate; *pp!=pUp; pp=&((*pp)->pNext)); + *pp = 0; + sqlite3_finalize(pUp->pUpdate); + pUp->pUpdate = 0; + }else{ + pUp = (RbuUpdateStmt*)rbuMalloc(p, sizeof(RbuUpdateStmt)+pIter->nTblCol+1); + } + + if( pUp ){ + char *zWhere = rbuObjIterGetWhere(p, pIter); + char *zSet = rbuObjIterGetSetlist(p, pIter, zMask); + char *zUpdate = 0; + + pUp->zMask = (char*)&pUp[1]; + pUp->pNext = pIter->pRbuUpdate; + pIter->pRbuUpdate = pUp; + + if( zSet ){ + const char *zPrefix = ""; + assert( p->rc==SQLITE_OK ); + memcpy(pUp->zMask, zMask, pIter->nTblCol); + if( pIter->eType!=RBU_PK_VTAB ) zPrefix = "rbu_imp_"; + zUpdate = sqlite3_mprintf("UPDATE \"%s%w\" SET %s WHERE %s", + zPrefix, pIter->zTbl, zSet, zWhere + ); + p->rc = prepareFreeAndCollectError( + p->dbMain, &pUp->pUpdate, &p->zErrmsg, zUpdate + ); + *ppStmt = pUp->pUpdate; + } + sqlite3_free(zWhere); + sqlite3_free(zSet); + } + + return p->rc; +} + +static sqlite3 *rbuOpenDbhandle( + sqlite3rbu *p, + const char *zName, + int bUseVfs +){ + sqlite3 *db = 0; + if( p->rc==SQLITE_OK ){ + const int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_URI; + p->rc = sqlite3_open_v2(zName, &db, flags, bUseVfs ? p->zVfsName : 0); + if( p->rc ){ + p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + sqlite3_close(db); + db = 0; + } + } + return db; +} + +/* +** Free an RbuState object allocated by rbuLoadState(). +*/ +static void rbuFreeState(RbuState *p){ + if( p ){ + sqlite3_free(p->zTbl); + sqlite3_free(p->zDataTbl); + sqlite3_free(p->zIdx); + sqlite3_free(p); + } +} + +/* +** Allocate an RbuState object and load the contents of the rbu_state +** table into it. Return a pointer to the new object. It is the +** responsibility of the caller to eventually free the object using +** sqlite3_free(). +** +** If an error occurs, leave an error code and message in the rbu handle +** and return NULL. +*/ +static RbuState *rbuLoadState(sqlite3rbu *p){ + RbuState *pRet = 0; + sqlite3_stmt *pStmt = 0; + int rc; + int rc2; + + pRet = (RbuState*)rbuMalloc(p, sizeof(RbuState)); + if( pRet==0 ) return 0; + + rc = prepareFreeAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg, + sqlite3_mprintf("SELECT k, v FROM %s.rbu_state", p->zStateDb) + ); + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + switch( sqlite3_column_int(pStmt, 0) ){ + case RBU_STATE_STAGE: + pRet->eStage = sqlite3_column_int(pStmt, 1); + if( pRet->eStage!=RBU_STAGE_OAL + && pRet->eStage!=RBU_STAGE_MOVE + && pRet->eStage!=RBU_STAGE_CKPT + ){ + p->rc = SQLITE_CORRUPT; + } + break; + + case RBU_STATE_TBL: + pRet->zTbl = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc); + break; + + case RBU_STATE_IDX: + pRet->zIdx = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc); + break; + + case RBU_STATE_ROW: + pRet->nRow = sqlite3_column_int(pStmt, 1); + if( pRet->nRow<0 ){ + rc = SQLITE_CORRUPT; + } + break; + + case RBU_STATE_PROGRESS: + pRet->nProgress = sqlite3_column_int64(pStmt, 1); + break; + + case RBU_STATE_CKPT: + pRet->iWalCksum = sqlite3_column_int64(pStmt, 1); + break; + + case RBU_STATE_COOKIE: + pRet->iCookie = (u32)sqlite3_column_int64(pStmt, 1); + break; + + case RBU_STATE_OALSZ: + pRet->iOalSz = sqlite3_column_int64(pStmt, 1); + break; + + case RBU_STATE_PHASEONESTEP: + pRet->nPhaseOneStep = sqlite3_column_int64(pStmt, 1); + break; + + case RBU_STATE_DATATBL: + pRet->zDataTbl = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc); + break; + + default: + rc = SQLITE_CORRUPT; + break; + } + } + rc2 = sqlite3_finalize(pStmt); + if( rc==SQLITE_OK ) rc = rc2; + + p->rc = rc; + return pRet; +} + + +/* +** Open the database handle and attach the RBU database as "rbu". If an +** error occurs, leave an error code and message in the RBU handle. +** +** If argument dbMain is not NULL, then it is a database handle already +** open on the target database. Use this handle instead of opening a new +** one. +*/ +static void rbuOpenDatabase(sqlite3rbu *p, sqlite3 *dbMain, int *pbRetry){ + assert( p->rc || (p->dbMain==0 && p->dbRbu==0) ); + assert( p->rc || rbuIsVacuum(p) || p->zTarget!=0 ); + assert( dbMain==0 || rbuIsVacuum(p)==0 ); + + /* Open the RBU database */ + p->dbRbu = rbuOpenDbhandle(p, p->zRbu, 1); + p->dbMain = dbMain; + + if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){ + sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p); + if( p->zState==0 ){ + const char *zFile = sqlite3_db_filename(p->dbRbu, "main"); + p->zState = rbuMPrintf(p, "file:///%s-vacuum?modeof=%s", zFile, zFile); + } + } + + /* If using separate RBU and state databases, attach the state database to + ** the RBU db handle now. */ + if( p->zState ){ + rbuMPrintfExec(p, p->dbRbu, "ATTACH %Q AS stat", p->zState); + memcpy(p->zStateDb, "stat", 4); + }else{ + memcpy(p->zStateDb, "main", 4); + } + +#if 0 + if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){ + p->rc = sqlite3_exec(p->dbRbu, "BEGIN", 0, 0, 0); + } +#endif + + /* If it has not already been created, create the rbu_state table */ + rbuMPrintfExec(p, p->dbRbu, RBU_CREATE_STATE, p->zStateDb); + +#if 0 + if( rbuIsVacuum(p) ){ + if( p->rc==SQLITE_OK ){ + int rc2; + int bOk = 0; + sqlite3_stmt *pCnt = 0; + p->rc = prepareAndCollectError(p->dbRbu, &pCnt, &p->zErrmsg, + "SELECT count(*) FROM stat.sqlite_schema" + ); + if( p->rc==SQLITE_OK + && sqlite3_step(pCnt)==SQLITE_ROW + && 1==sqlite3_column_int(pCnt, 0) + ){ + bOk = 1; + } + rc2 = sqlite3_finalize(pCnt); + if( p->rc==SQLITE_OK ) p->rc = rc2; + + if( p->rc==SQLITE_OK && bOk==0 ){ + p->rc = SQLITE_ERROR; + p->zErrmsg = sqlite3_mprintf("invalid state database"); + } + + if( p->rc==SQLITE_OK ){ + p->rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, 0); + } + } + } +#endif + + if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){ + int bOpen = 0; + int rc; + p->nRbu = 0; + p->pRbuFd = 0; + rc = sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p); + if( rc!=SQLITE_NOTFOUND ) p->rc = rc; + if( p->eStage>=RBU_STAGE_MOVE ){ + bOpen = 1; + }else{ + RbuState *pState = rbuLoadState(p); + if( pState ){ + bOpen = (pState->eStage>=RBU_STAGE_MOVE); + rbuFreeState(pState); + } + } + if( bOpen ) p->dbMain = rbuOpenDbhandle(p, p->zRbu, p->nRbu<=1); + } + + p->eStage = 0; + if( p->rc==SQLITE_OK && p->dbMain==0 ){ + if( !rbuIsVacuum(p) ){ + p->dbMain = rbuOpenDbhandle(p, p->zTarget, 1); + }else if( p->pRbuFd->pWalFd ){ + if( pbRetry ){ + p->pRbuFd->bNolock = 0; + sqlite3_close(p->dbRbu); + sqlite3_close(p->dbMain); + p->dbMain = 0; + p->dbRbu = 0; + *pbRetry = 1; + return; + } + p->rc = SQLITE_ERROR; + p->zErrmsg = sqlite3_mprintf("cannot vacuum wal mode database"); + }else{ + char *zTarget; + char *zExtra = 0; + if( strlen(p->zRbu)>=5 && 0==memcmp("file:", p->zRbu, 5) ){ + zExtra = &p->zRbu[5]; + while( *zExtra ){ + if( *zExtra++=='?' ) break; + } + if( *zExtra=='\0' ) zExtra = 0; + } + + zTarget = sqlite3_mprintf("file:%s-vactmp?rbu_memory=1%s%s", + sqlite3_db_filename(p->dbRbu, "main"), + (zExtra==0 ? "" : "&"), (zExtra==0 ? "" : zExtra) + ); + + if( zTarget==0 ){ + p->rc = SQLITE_NOMEM; + return; + } + p->dbMain = rbuOpenDbhandle(p, zTarget, p->nRbu<=1); + sqlite3_free(zTarget); + } + } + + if( p->rc==SQLITE_OK ){ + p->rc = sqlite3_create_function(p->dbMain, + "rbu_tmp_insert", -1, SQLITE_UTF8, (void*)p, rbuTmpInsertFunc, 0, 0 + ); + } + + if( p->rc==SQLITE_OK ){ + p->rc = sqlite3_create_function(p->dbMain, + "rbu_fossil_delta", 2, SQLITE_UTF8, 0, rbuFossilDeltaFunc, 0, 0 + ); + } + + if( p->rc==SQLITE_OK ){ + p->rc = sqlite3_create_function(p->dbRbu, + "rbu_target_name", -1, SQLITE_UTF8, (void*)p, rbuTargetNameFunc, 0, 0 + ); + } + + if( p->rc==SQLITE_OK ){ + p->rc = sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_RBU, (void*)p); + } + rbuMPrintfExec(p, p->dbMain, "SELECT * FROM sqlite_schema"); + + /* Mark the database file just opened as an RBU target database. If + ** this call returns SQLITE_NOTFOUND, then the RBU vfs is not in use. + ** This is an error. */ + if( p->rc==SQLITE_OK ){ + p->rc = sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_RBU, (void*)p); + } + + if( p->rc==SQLITE_NOTFOUND ){ + p->rc = SQLITE_ERROR; + p->zErrmsg = sqlite3_mprintf("rbu vfs not found"); + } +} + +/* +** This routine is a copy of the sqlite3FileSuffix3() routine from the core. +** It is a no-op unless SQLITE_ENABLE_8_3_NAMES is defined. +** +** If SQLITE_ENABLE_8_3_NAMES is set at compile-time and if the database +** filename in zBaseFilename is a URI with the "8_3_names=1" parameter and +** if filename in z[] has a suffix (a.k.a. "extension") that is longer than +** three characters, then shorten the suffix on z[] to be the last three +** characters of the original suffix. +** +** If SQLITE_ENABLE_8_3_NAMES is set to 2 at compile-time, then always +** do the suffix shortening regardless of URI parameter. +** +** Examples: +** +** test.db-journal => test.nal +** test.db-wal => test.wal +** test.db-shm => test.shm +** test.db-mj7f3319fa => test.9fa +*/ +static void rbuFileSuffix3(const char *zBase, char *z){ +#ifdef SQLITE_ENABLE_8_3_NAMES +#if SQLITE_ENABLE_8_3_NAMES<2 + if( sqlite3_uri_boolean(zBase, "8_3_names", 0) ) +#endif + { + int i, sz; + sz = (int)strlen(z)&0xffffff; + for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){} + if( z[i]=='.' && sz>i+4 ) memmove(&z[i+1], &z[sz-3], 4); + } +#else + UNUSED_PARAMETER2(zBase,z); +#endif +} + +/* +** Return the current wal-index header checksum for the target database +** as a 64-bit integer. +** +** The checksum is store in the first page of xShmMap memory as an 8-byte +** blob starting at byte offset 40. +*/ +static i64 rbuShmChecksum(sqlite3rbu *p){ + i64 iRet = 0; + if( p->rc==SQLITE_OK ){ + sqlite3_file *pDb = p->pTargetFd->pReal; + u32 volatile *ptr; + p->rc = pDb->pMethods->xShmMap(pDb, 0, 32*1024, 0, (void volatile**)&ptr); + if( p->rc==SQLITE_OK ){ + iRet = (i64)(((u64)ptr[10] << 32) + ptr[11]); + } + } + return iRet; +} + +/* +** This function is called as part of initializing or reinitializing an +** incremental checkpoint. +** +** It populates the sqlite3rbu.aFrame[] array with the set of +** (wal frame -> db page) copy operations required to checkpoint the +** current wal file, and obtains the set of shm locks required to safely +** perform the copy operations directly on the file-system. +** +** If argument pState is not NULL, then the incremental checkpoint is +** being resumed. In this case, if the checksum of the wal-index-header +** following recovery is not the same as the checksum saved in the RbuState +** object, then the rbu handle is set to DONE state. This occurs if some +** other client appends a transaction to the wal file in the middle of +** an incremental checkpoint. +*/ +static void rbuSetupCheckpoint(sqlite3rbu *p, RbuState *pState){ + + /* If pState is NULL, then the wal file may not have been opened and + ** recovered. Running a read-statement here to ensure that doing so + ** does not interfere with the "capture" process below. */ + if( pState==0 ){ + p->eStage = 0; + if( p->rc==SQLITE_OK ){ + p->rc = sqlite3_exec(p->dbMain, "SELECT * FROM sqlite_schema", 0, 0, 0); + } + } + + /* Assuming no error has occurred, run a "restart" checkpoint with the + ** sqlite3rbu.eStage variable set to CAPTURE. This turns on the following + ** special behaviour in the rbu VFS: + ** + ** * If the exclusive shm WRITER or READ0 lock cannot be obtained, + ** the checkpoint fails with SQLITE_BUSY (normally SQLite would + ** proceed with running a passive checkpoint instead of failing). + ** + ** * Attempts to read from the *-wal file or write to the database file + ** do not perform any IO. Instead, the frame/page combinations that + ** would be read/written are recorded in the sqlite3rbu.aFrame[] + ** array. + ** + ** * Calls to xShmLock(UNLOCK) to release the exclusive shm WRITER, + ** READ0 and CHECKPOINT locks taken as part of the checkpoint are + ** no-ops. These locks will not be released until the connection + ** is closed. + ** + ** * Attempting to xSync() the database file causes an SQLITE_NOTICE + ** error. + ** + ** As a result, unless an error (i.e. OOM or SQLITE_BUSY) occurs, the + ** checkpoint below fails with SQLITE_NOTICE, and leaves the aFrame[] + ** array populated with a set of (frame -> page) mappings. Because the + ** WRITER, CHECKPOINT and READ0 locks are still held, it is safe to copy + ** data from the wal file into the database file according to the + ** contents of aFrame[]. + */ + if( p->rc==SQLITE_OK ){ + int rc2; + p->eStage = RBU_STAGE_CAPTURE; + rc2 = sqlite3_exec(p->dbMain, "PRAGMA main.wal_checkpoint=restart", 0, 0,0); + if( rc2!=SQLITE_NOTICE ) p->rc = rc2; + } + + if( p->rc==SQLITE_OK && p->nFrame>0 ){ + p->eStage = RBU_STAGE_CKPT; + p->nStep = (pState ? pState->nRow : 0); + p->aBuf = rbuMalloc(p, p->pgsz); + p->iWalCksum = rbuShmChecksum(p); + } + + if( p->rc==SQLITE_OK ){ + if( p->nFrame==0 || (pState && pState->iWalCksum!=p->iWalCksum) ){ + p->rc = SQLITE_DONE; + p->eStage = RBU_STAGE_DONE; + }else{ + int nSectorSize; + sqlite3_file *pDb = p->pTargetFd->pReal; + sqlite3_file *pWal = p->pTargetFd->pWalFd->pReal; + assert( p->nPagePerSector==0 ); + nSectorSize = pDb->pMethods->xSectorSize(pDb); + if( nSectorSize>p->pgsz ){ + p->nPagePerSector = nSectorSize / p->pgsz; + }else{ + p->nPagePerSector = 1; + } + + /* Call xSync() on the wal file. This causes SQLite to sync the + ** directory in which the target database and the wal file reside, in + ** case it has not been synced since the rename() call in + ** rbuMoveOalFile(). */ + p->rc = pWal->pMethods->xSync(pWal, SQLITE_SYNC_NORMAL); + } + } +} + +/* +** Called when iAmt bytes are read from offset iOff of the wal file while +** the rbu object is in capture mode. Record the frame number of the frame +** being read in the aFrame[] array. +*/ +static int rbuCaptureWalRead(sqlite3rbu *pRbu, i64 iOff, int iAmt){ + const u32 mReq = (1<mLock!=mReq ){ + pRbu->rc = SQLITE_BUSY; + return SQLITE_NOTICE_RBU; + } + + pRbu->pgsz = iAmt; + if( pRbu->nFrame==pRbu->nFrameAlloc ){ + int nNew = (pRbu->nFrameAlloc ? pRbu->nFrameAlloc : 64) * 2; + RbuFrame *aNew; + aNew = (RbuFrame*)sqlite3_realloc64(pRbu->aFrame, nNew * sizeof(RbuFrame)); + if( aNew==0 ) return SQLITE_NOMEM; + pRbu->aFrame = aNew; + pRbu->nFrameAlloc = nNew; + } + + iFrame = (u32)((iOff-32) / (i64)(iAmt+24)) + 1; + if( pRbu->iMaxFrame
  • IY>\[L_A -M=*H,T%HA_EQ#JJ-+(&7@E69WBK?!HS*%-]QNH6*$786_YOBQ2D/P9VIK,\(" -M`)TQ[_$U+'5FYSG3A6V=&"IC<"$M2N449*AI5)/CC?];BCXV%52L@/JFX@28N841C7]`#BIZ]&R>>9Q]#*H9'4H3HT@#1MHF -M7YZ'L>C-5#3XYB\!LFI/L_NJ%LLL'LT;8@*>152(F?#J:1W$<2&#KLNX8N@T -ML&9[VL99H<"68!2*7H,!EK)+$M86Y1T/[UI)R"!%`O@T-+_+_T4X^=D)@U=( -M\4DJ%<]$>>X3SJ&5GG6IV1VBEH$U]*L"7MQFO;7)&/X:DJHA(O#B0"2.$R"S -M?-@;-,*;E*PVO5\P-DRY`;9/[@2 -M[B%,/I'FB%I*E"&H`RJ!7:8#5">"_\V^G-%QV7\LF_?N![:S=%H@E#9*U:;# -M6E%2U'F09V;%!%!#`#7O>O$%=/^X4;ZYR56I@O6;T="J-@\YY$8$7NJ<4/4* -M[1>[?S"ZJHJF])CKA]K7-HV[6:Y%"+<2<$N-M\(^Z=].HX=I+`5,/U$)[GAD -M-^*"):<;=O^7,435AK@(9ZC<9<<%@EZW'!NC4\+R(;,V\=,C:"'T8//J) -MDO$1UEHBQ:=B@N!4J"W4*1FOZ]V-1.YG3!W?O+?IG>72B^J*C5&L<"(_%ISM -M?7VAYW3B7+)DCA:!'D:+KB4A4@1@R\$XB57-PY6,U!F:3*EL4(C+L&(2.&P= -MBYE[SQL<.@%1VO,-SEV%T'A2+/?>2A6OXS_H_.>3*OOU2X3H=5G*E"^2G_#PL_R=?VP.2*94EKL/D%3:\7=6&FB_.JEYWZ/0],2S-J -M=:Q>OZHG"S`FF9Z7/K6]0DN21,=!,!I?9.H%[MF>TY?LTPHT=#BIO$*76;WU -MYUA6,.VX:;6.UC\[O(M_H@=,I?4<4HU"-.JJDCS**(I]S?F:_C;9WWES]4@6 -M+6%)W:'E+;^,.@T'F2)]*J9&`/\FF9OM@-IG.S>?_%&)[]HPSJPOH6WAU',I -M:KFQMY+I3/CN[^$BOXFX"LN>O_:Y -M`5!2'(UZF>E^42CN1BZ[H3)<\XLPUJ[&7PD7L475@N3)_A+HM+JNST*02#^- -MEWYD"I'6;0^0C:^93=99Z'Y#]A"D%FF(1CZL[^XEE)?!J;<\(@AX^S!,UQ@U -M'H0$C>KEC-K\01NQ:/0B,W<<"B%5W?#6.73]& -M=5#%CQGTXS)U/[$--I"UY0!C\%\9$"]%>$(P^3I@ROTG&P95:O1[9G^=J@?*@R9@5-_ -M<@!IEECI()`LHWW+#OFOX8S8!6VWFF8]T-BA8[+E/^FMBT\2`3\F$<%[G0+Y -ML/N]M-CC%$46J,&@SM6.CGC[J%T;))7;56U_\J`W(1[2G^4KM2LH[9Y/`M5` -M=95WP#.W+T^E5/Y?SL\Z?LGP=W9$N$^P?:WM)TR7?WN>I&Y?!!)\^"AYNC57 -M%"8+<=1_Q:/]];UY("GLGSI:1F7JW\C-PL,.%U!IV%0T"@H.>_I[48>C:T\? -M)D[YO;5U8!N_!JZT,>PSO6)4`/97!:+WA])B@:19ARW]LPGNY-^'%^>F2S44 -MC0*!4]A*5"2R0!?K8&XZ\<]SH@*2^*_D:,PP, -M/*2T-XP.7"(F$N9^N/YXB$TIPF]_%F:ZTL_@O1'Z*+ZZ=/!30R[./&.:`"`G -M9!A*QZX?5%Y-$'_>>4K#]R4*/#=L7>&E!AS=RA<__0^ZE"!"BZOYO]Q'J-\U -MP!M@]T2LNHLWYSKTEG-&OK<,22^Q2QFT&_9[D4)@FRU`QO#*\OWMX?$ES7KN -MZN*P#2H4NI=19=/=.F>(X9G0Z=1R/3P*#&!G`&?*L/6 -MSJV`+:;LVCL*^#!R!RZ%9F)Q=A]?=!)R[B&`HYLS]">J#%G=[^VV^S;<"\LV -M)"EOB@&[I@3ZW-4.QDNH(>HI2[1/.&X]_[IAQD`VZ;!>2)%0<3E$4B\'DL!4 -M9QYY+*?:GK%HQL%^[3->I_K8_*7NW:SD#@8M-7@(\7O2:43UEYQX5>)^U(.U -M@I;7;Y?9\@(7/+U;]68RC@Q4TX!RB!/8`N[36*>M"X2@7[QH2-6IMN.ILL"T -M(Q',->\87=!3#N3+/S/%(:"]B>\U2'=`K6CR*_E/M?YIKUE0?CK!4D^@]B,7 -M_)TI9[QM>3,0=\)O"\^O04D^T$>Z$/O*(Y4NX1K:.0R6JO>\\J"'7\3@QCS' -M*SFNSJMF$Z$QV-M1$&-5AD)?S6-386YG:BR,*S/Z[CX[LV(@?;RA3(4!+8Y^ -MKF9Z`UUK\5FSA*?!J$!IJVC]4EP7:,BDC_V6R91-1/"J]0\0QEH2#YXU=`!$ -MIV&+-.\![?2<6?8X4Z!`>$`G,4*9_QY)T\@3N/3HK(:]^&5GK4X(:58V_Q8< -M`936BL/5*H#F(HTV?\_TUB,[K#A=6HA:)X@.;&1Z+FC*C!,)U4>6OWV]L"'D -MAW]`3_^7ID$P2A__MZF!4R;1@?5=!`'NS'6,L4EIN8*E8BK^=P)4 -M50UQ/H+!;E^(!A?\>'C3R86=S@5I,P/C2*,)DF][%?5ZFGL/:JLQFEF;GDJT -MX/Z](LU*EB6A+5'($?'[;$A[V/)Q!%@5PB6KTD/0S+E*AC%GL*"7 -MS*(5^^Y@!1D[@;]:Z7#7*%:6H=#>3(>OOK>A!88J>9ZBPR"G4W,P;X..N<46 -M+6'F).F?1/FE]0:S[AMPB5"DDRFSK/E6,?KJ+U4-W=:]:I6WY-`BR^+C$=`I -M;F@ZB'KDL=8;1'8SE3 -M:$B&R%E3J'&@FSI`_()GUV2T+:F/SW-*/T@UW?T!M`SR#CNLHIHLQ83IG54?-:?RVWTXE2E8$I>-V\?F:;_,P4E9]/U&(V+2TBX\ -M--9;AAX3#?M0V%^/63>%-)71EJVT^?#*6J]4%,Y8?&I*!%*'/GRJ1ZNR)Y'T -MKW&!M/*";N_0&X-1RK?GY;ZK"9C]:J!-S8:5;0+C>]8 -MWH2(YX!:OP29MU:_NL0H5$&"K=`K',&0=MR%A!:];=;!:MVTYLOYQN64L-"5-#\S`S\?[[]?N8L-F^+99KI?`)$=?5GM -MN?<9S-XTS5^4*(XM)6IMKZT= -M2_7('\!P1/_S[\EBKM>CE0E.-U;N\E=)9T+M)U];1`@TW#(H+$69R!Z5)1Z+ -MVCS*Z=&&$$RKLEK07C8?;E(T+;VI"FW\BR$54]C`&?7AT+3Y&+AL -M0_-LF&+7XZN/H3N.G@0`B:;';MT'368KDS5!+"-KRV%"K[^,(F -MZD&"%A/"1'7N)Y[*3"S.++'/H_0#@7"=%>!D6ZC]5=4:3\_"@<$(P%) -M=SW!M*P+L()5_J[A\#CU-CGIAC\OPQ#!8<8239S/%)_U/`WHHG?U(N#&P`U* -M#2]*RL:^M8J#8JX]IJV5BULX+'FT&I\;+E^5-_/?`D:+3O[4^'*7PT'M_,A= -M:#\ECNN9`"^86J#IIMFG57HQ<2EHG`!@$6Q'G&I3),#&F[3Q4`D'X[ZCOB(T4J[4H[:D]@X: -MJ8[QYYP+-&1M6I':3([Z(!NW7@D:.JT"K%,ZE@:U9%C*R+,GN$R`*;]9YF* -M]CMF'/FLS0,A?BL;*8 -MLUT>5($%P4JO;D4.*HR0*-K7K>'FOJ_G",PKSU)A0/5TT6<2L6#[L1::YJ%. -M0]+UX=W^*X0=>"Z![2QA)JYVDKHBMC5/+FG1U)[A_LUQK[),U,9/U>?T.Z`V -M!CQ^`M^.YR_\K2O3D?SQR4`J+:YX!2=6*0'N@E@YZ+H,`[%2ZVHSR"[YU),1 -MCD5TP,J/3\613.^ANW];?U[6](NP+>ALY%GP)HK_//"0*5.1:D=HX6IO=!;5 -M5+KQ!^&.^3A5:6)D>#40-^8C*;?&@FK0;Z>`^5INC(%H'/E#&4MAP=7H8@VT -MD*KXDW+6]7\`#3_6GFIEM-\K\L7WG7'C`8S -M/'Q"1R@I5ZE!=`[VK\;IL,=Z*CJ2DJ(B^CE82G0<1`WXH>KHF;CURSPB82=> -M40&)M.KW'C8SM6HSL':R5\Q3B1$^,53I3"+'CC*@[?.,#.7"Z:>A7,9'AM!? -MC8EVKS_Y0<@KQ9VZH*XN$PC?[]*R)E$`8*6UX0%#P7MS@=-VG#*(6^@K6A7- -MMZ3808:Z.%!/PK@["(]U^^G5@V0`@\0KB/'L#2_6D>/D38QXL%+.=[IOL:_7 -M5Q`OHK#O6-0-M8FVE^],'(-V97OT\C0_!CI+FF8W!0M<(*Y&4]Z16+1?*=S1 -MT4XB28+9R?UM=&,82LA_1/Y(JEQ@J,$<*LG+T.`MG=,35G4UL!O=K4L6&#X< -MTI?1]-*Y=4.O;$%A2,.8A"C[C$$76,GJM]E-%S^7M`5XKK0XCL^Y&)5$ -M-NE=1!BSGXP[S[RP7R'8)M>4EN[KDR`[.(,T"-A<`9IX87^5AL89Q='#)/C? -M"$5EW-.JQ81>!*E^H"!!"5R)2CK>F)'I[SB2TG66@!_'*W6X?D!V%F)H#D7W -MD/5'H'=H;CGZF&B.\/H%R)YS67K"5LL2>H2:QOB@%M*D`&JI`8%+;+5*-N -MD;D6(C>=_8`A>8<22XJ04PT\LHY28@DE`T$5DBV5]7>.PNE#+U;YLP,"L[[1 -M-+V(W9YN$H\_"'KJ>$D6-OJ!1S_?JY->,+Z@Z-R'5+M[T>GY&223QQA336[^ -M$#,-5* -MLH^715V1@Y;O463D"MB4+N#08$SC4#, -MFCMGH&UD\0@D+C?)#%5R0YCNL,+U&G\AI#/)<.,=(HYVS;U,9FBQZ6%,W)#/ -MWMH>J,7S5%'<$A!EI+B6-]^"V!=U=.B#I47T!3)G'.&"[)T:VEG/(^-*W9?.@?]-Y2.(>:V^LICJP"%+7%O)CB[I.-G$7: -M>T+;25TQ_C_]2)E3V1$9$0S_D!/VF%4H)D`;$Y!!`>8/M<<1HMT^LJM"\/2R -MRI)EEM+JLET[Z]1UZ>\MK/7UE'[UZ8[LOPZ?:NH,0T;XZ/42MDV`D@RPO7.? -M\:WF@,-T7MOTK7Q_I6M[+0N,N:]."D$:IEI@#1N=,X&\*DY0'DHSMHYYNL*K -ML"/LI/(45V?-?+'UM3458Y%6*$8#N'@S'F+SWCK3J:A> -MT^9>)[D)F4A+I<R3^CDR;S.O#+)OKR",:Q4/3_>(P4/`LFW`76F5V/'^6C+3YJ1#R=!; -M?TZ8'%=OJT#Y9H76(XCT@ -MPGB^.7%Q^QP4[]>KMP2GG<%('%4;7`O\)K"BS)BW[&0&O#&+OS,::=2Q\;#1 -MC\]+E*3PTH5CO3!L;$-YU.60CW_!U6S4&-9V_#I0L,C('OCGY[VZD"EC`:R[ -MY`;3=!SI[C2&DA])R[00/?##L6$LXEAVHNME-[W)3$+K*+JO<]NM1U&WX:'X -M%YT:T1+?=RNU2\>4T.NL)^\.KW?,$-0<1LQ3EPRO%+AE!G1YE>=4E!+;[`\R -MAFLS)=;9,E[J"&]$U3O=['3F1XBE#[?N\YU>>9;3:+DEGK2,JQM;"7%ZJ.&D -M[I)WVOP)3P-3=A0$B;Q&(%II5L4<:,,#JOP>BAG1T^24A*E2EVI$,]78"WIP -M[O%002;?S=#,,KB[5`$2+T[;>S4&^VGR-8G/I#UC2 -MBO&8.6&^4N4)86\0.BB-0>0.!YK]5E5+PVW)I_=5T^^\#J;`JY<85-G:)%*9 -M>39_XLPQ%9*HMX,GIWG#<+:3I%_:51C`I=)M56UQA)KW,NLB/P:Z9['W#ZD' -M'Z<^\"/D*I62$4L17#4%WIZU/LPJRD0";Q^5Y1^\H``"R5N`2VZK][S/CU)= -MV&:')YE*\31UVD;O8O-;T9GMYJR#X0`3\2'VU*J@0"$GC?2GN1MG5-'(35$; -M,A^#=X]764"N?@D$)^D44#E%?&F3P2?0HJ%>N&0L6P>O>-KLXK>E?O`;D5+] -M[HN#II.0)?OO08-ZZCY=KM,UJ5GN[LPM+%^0_^3JSPO)LV -MVZ/V"(K>#*O\Z['3`W%9J*H/=696XL6YR1,<**L^/("_@A#B>SE0@>D)'DUA -MIQH%"$^H7F=3Y#J24WD.W`3QYU>#UO<3!/Z3.3FLKR"VGKZ`4-H.I)+(O*=1 -MT+IPX$'_)J(*?(`AKO8^3.B>$QDWN]4-;IL$"/;O0*R-Q86% -M.Q\+T7+;\5 -M;-"+X"QURDN7E!KQD>'';W)5,AKX'V5GJ$8YL:3&]M4GDHAUF -MT?EBBSPN/HG)P*9:\J.B(R4@4=7T$!$CG6`AE^V['17WN16YI,`_,<(C%*K7 -M;+E@?8-25AM_7'"!VL#'TMYX]SYOH60KU3A\U5ZH''H>T87.^,_(GP6S_A`B -ME2-,*_G=JWUIA*4T`.][4.FE[^51R>.YD -M?^V,N/;%Y[-`5[UKW("==Q4OXWOGRQ.R_P4V[2&W[VFQMO:.XF421D-O,0.G -M-6Q(\OIU*"C5!?!P:V46L^.IE]O%EQ8!L",8XB;E-.-B?1O%`5$1GKXW@)?=,#3/<6&Q&=-M$N>G)GQ[(GQMIEX?,G)O0GJI1Y -M2G^FMU3#"EEC1.9C/9B3F=OL7AX8O&:]M)(^^2D$G\C6E64S]4W.G*RBG`I. -M@,,ZJ@89*4WQ(O?QIKF&X#]/;YGYE18D:T7/H?L)L0:F[`._Z"DODDE?.V]7 -M5C50PQ1TOT"=<(D5*FSH^^)D@>L9%J![G'OH%TVP,9/0`):&M,75)D?'LO(M -M1-;[A$83L3OP$DJ:PG<$/OUK2%,"NF[<)*9<7]7WZ66%C(.J$J?L2N[7^A%4 -MM_*-79QHKLQK!,4;7N^DD38&")[78FX@GJI)%\A3NEX2;F -MQ?KF,7Y":RD;(%@,X&/,NE=Q/0/>?4ZR"5?<+TQ.[RO^6"TGY\, -M]X+#:;4\-41?.,1#"_/DB]*J$]>P-1Y3RZFECLCMB7R&ETX+L^NA,87/X#'* -M@QJD\FVK0$OL=!H;Q*XIUCS!4U_7P,B1%R#CL%S>NX8XVE0`'BC -MG4?G!S:)#EPS'85_9M!LJ?QLA&H&4FZ=@K-FP,?D\!T\CR@8&0`6]?F-*=/7>N._J+7]U`VZ8-).OS$!IADF_(>@?RI:D[R`3@VG -M=5KBA,\S1))C?$+Y@A/X9+T>`<'+H"]&KD$9JI2?8:A*9L5\9']IM+T)A)A\ -MD.EI-6<"D?&/6U:L):2'-"V4*LB;"PX%36IM3'CNG(]OGXE(LJ5`GD`"<=DP -MT&?\+UNQ*G7-9)\8%EL-;]"UJ9+4+NPTET87O,DV.:^?Z>J&LV(B1#Y<\^8) -MZG-L5`XGI?5%I_]1T'<*\Y4\@(;0"],M6KA0&$&C5"Y_1-Y_3J]5SCO^MWZ& -M:L7`^_?@_L/E:'_"J,U`5WS[,3=ZHR@3S`&%9<#GKPOH1%1C=X%+6"H66)WS -M37YS6EP+T]8>Y;^E;!.[H$<,-D)1A-@%:>1U6R;J6$C3(?9_:4$,+ -M'?DP+86H$ZN!J2AOK`>/(6+M]KJ5(=54-:YYWOS2?D?J<\X[2>![F5\_5_2K -M5ZS9ZF,@+_IAY7]5\3%WH\@HRM./,P:&X!3H`=!)?$\ZUTL41T43;]:1R.G2 -MJHYOC;UJD_*U0,=ZW@3?W'@2>.S0ZVI29R*Z?MB*KF>U9VPCOGI?FKVW -MG#DOVXI%'!B,E5YFP3!1CDC?[8:4,8.&FD@721M*QCZ3F')>(4%($T0C,W^J -M\SR0R?RHM.J^%PL:Z>$FZ^.1O/49+B(9&%/Z=D].=H6WLOL -M]\@G#JFWBRO;7ND$Q[9^/2'GON$E=O5F)F%%T:6:=#43V=CTRJPG)][?Y+LD -MT.K2.4>4IXNQ3!.ULQ7=DY=HH'1`=A"59NIH2F>C]2\D9DT\5S)A#,'[X'/6 -M7:6H2W+L:K+F]X?A`WNGY0K1NBW7KAWLGR`W317)+ZO -M9G9A-&<@0"EI9!S@BA1^*,W@^/#6/(1'NFK@36;OF=7*]==TBU\!?>PNM>2G6#Q,L'1+3[MQERB%MS) -M:\Y%##(-P<'606QE:<'V-!0\ELQO83]I`2I1*_C^%@?VW+2\"GB]'&-53O." -M8(%9^N\4`6`]D\XBZFK-KBUAD":H?/Q'OD;DE$#B@#D+>9)H)!92IMIVQ<3[ -MS_G,"B;X`$L&R9[(J'$=7&],V9$;UV(K0(\%CVU!)F;KPEU#>ZARVZWX7@0% -MGJGN#R"27F>D.N2WP'G:RTF:RVW%#RSU.:M@#?\\!D-%+=%A3:1>N]*:AH*/ -MM6]+HZ<31SL;XC]J7IK#:)>4KGHHXVZ6@#6U?)*O -M>%!;;_\^A(8J!#R3+M8'=YE6<4P;;6$TC`XZI@F'N*P`=/[+/@2Z3FA6E@_) -M^@WA%D\'7$9W]IE9D(Y%708T4*/5Z%D]C&M,@_O$<^%*:*>\$,'?<7W)>R*S]!GU -MG!K"67!)I#@)%&MC%'2C)'Z=EJ'(US,$@:N'0%:(^]THC8EL\Q!K/TX-*'@G -M)0B%F,EL1B?7:47Z*M-.E^8=[)N6&\W(NY8M,.@(L`NG8KV_KH@CSAHT<7:" -M_LGA;G=A9I^)(U`.$/M;Y>;!G`?\<78Y_Y54[H.#("0: -MJ'<=&ZNMN%#!:/=/E;_@;G:%RJ73M/&-JU(?A&3.$<11+Y#[$%Y5BQ9:DSUR -M(%79+<_J2GT^/`B_!*_7AG^8!H1@@^(#M!MO"0G^P;O)(5J;-Y7OM_^Y1)-> -MZL:!OA/(`GSAGV:KJ4&T45;M- -M=0TWXWL:J32I)U -M+GIW:0SR9"JGC"L>1M+<\M]75(WQ::D2W0*12]]M72Y]7?;&/(D'!K'FYL(X -MYOLIV:P7M];XV-T':BUP'WES(17$K%-W:CR5];$'(7,1E9B*KG/M[AG==QUP -M\%:%/%M5JFF?11)W+Q)B_IBX8:FNB[H541<%[BDIM?C9'SP6U.8]HFD.GQ26 -M"X47_@&.R\?3(R]Q\0Q?W&^2C4M7$@UC"ME>9'KDH.=$,1Y)(KYP6M2M)5Q1 -M5U1DB;T%'R*3LB!9=(\3=0-UXZ?'6NL?"X+[JJG++`*+M=I_GJ,Z5+5G+X[L -MQD0RW83SE6`I"%YK+?=]0*_VG'KU5!OB/#C?D\M/YL'$D*NG3Z8;C7^5H9^H-7B(-)OZ&5!;`ADJ%N]BD1O@[2 -MB^N/_DM>2':)BBE8_VQENL-/>S><7]]P/8BO'\T=1I)?H=IZSGCF=H94NF&E -M[+A1<5$KT3?Z&VZ\!0-"0I-\KVP[KX8)0#3.6GVU*MFN2[!32F_Y23JPAIN -M*G?ZA"PL@2Q\XJ_HA"]::9K`E_L?3F6PS+?C#"^(\Z5)K#=6E`"2_@_ZS_T1AZ&SC;80L/9I%E^U'_AS&&J3/86DV.$M'9PJ.E6) -MJ/OLE%=CXP'Q84S57$VP8:\1[D.63YGWSN2MOK9D@:X%ETS+Z=2?J^YD,W"M -MP0T=H%H3-E&!Q#Z2VS#!^/U\D4?T_QT,UG;?1Y[`G!;Y;V,-&VUO:_.3L8'E -M4U]1SSO]'(]M)E+':W.EEEX4EA=ZE"RX(XZEIS9Z+9K7=IC."!+BZ3I2DQ_G -MUK$M$.4,$&=?$]8R`(YY]NOU-URQMH=IME]9LP+:RII<#EYL[$@[]V`E4/Y+;H+G/-[ -M54#!(H@"))?@*^M0O"@,.A*EOSOE",,"P5XW^U[:P3[WYJE4`!$/H"$"Y<088UIK\P@$ZF@;UQ&SFUT`X+V>"8.AV,OZ>CHGPK.RW'FPV2'D -M27ML'9NS%CS#@3K!P$R&^67]V\,RJE!<2ADDQMG-!T,5T9M6R,71$N^[O36$C?T@Y""SB/_>^W!0;GQ">,P -M/V37B4VG"?\0.PR5=[L=R##:D6`0]7]3X2WB09I)@@]!X6SQA/[F#BFD$^(9 -MF@!,`&7A8DP14/-YE/1$K!%*>;O+UY2/9IX2@WT35L##N$*80C>$.-*-$`:B -M*JMQ:TNT_'H@A"0TE_@+OJR%]VO[J34&:=L4W"'-Q/T]A]_22_^'?PK&QY_. -MOQIHY51P5OQCK^KA&S:1"^+763YYM@2-(O]2[D`'U+QF$>-/PG,N<15P3BM% -M69@0)+-_HG4&"8'5[ZDO&*286,TOOU$JIQCO0Z3Q=1NR_G7C[50&Y:1J>1_Q -M1AN4]L$5$G7_GWE7##C[D-;Q]6NX$ECR`FP;/4F!)B^Q4HM@]5AGLY49A7YP)XN@\R`[1>DX[NM?E?WO%*Y_Y?O[7->4W2*/+-EF,\M83B^#S;/]<&%ZD7&IB2S,Y) -M31MM"-SF(>\PT@$ZG5G<7*T$T)YUWC#N^"^B2(8[22*7T5V^9^[,C.*EC=8= -M0$K2FL(!>29M@H+XN;[UPT2VHA<=/F1F\_W^3TUR1J_0C^_2U+[:=K\#10-5G*R%['R#JU?*2'L8FGS91?4_J(_!$&-[CPK3PE!Z -MT@+M&[2Y?+E@!"*&U:GP;@JLT@W3NF-@'!\.6'4RU$'ZP$E_M+:YY3"H>GQ? -M"_SRI_EKLG,8#N<<0_OP"QN&!%"K%<-3TS&MB27"].>W4P,\Q3,Y=9VZCR5< -M`-_Z'TPBRJ((X9PMJLK5IEL`3M_2]^V-AX/(R)A>FQ`VPQ6JM%+(, -M%Q9]$5WVYS,0@8R0O#9$5]LDFF-`N6E\:"+<.2FTNEEH3%-\$RH4,3J@A+Y[ -M[4!.YB=3**S\I;\A"^>4UY1EHJL'-#>0RHC+HU4\/]9T<5.U1Y^W1975!'JX -M.O#6OO2T\``27W1CF"?1'L:=:FP!H*S4KGJ)E2AF]2HV@NWHX1*'K)U!6HZ! -MJ_Q%`A,8E]4'N!P#J\,X -M?5?J>GO(^+,C'F@MK#D,]M+X-0F.=[3KF,(K)0!BGW2V@D9_H.B4LX;,^J8% -M%AMUI$DHDDHG\+48:19$5?IG9W#>\WB$N3/F<,"1,&21LYE\,=!LVF2:?YJ]\"61UQ&`PKHR -M9MG[#3;_0LN.EM79V132((^9EJ_VETP802SZUI-;A5916+(>XBY,F)E$59V= -M-ZAP;&2V49D,\=]20USH[93IAP58PA>?-RXF(_N2@09A:9C@?LEJV"/GARLE -M1>#0K4R^RO]:86[2XC'SB#R+NL_P-<_=*:2@_*.[5+RG^KF4/0M]4U#V"U9C -M2-^;T$G@H4.UGM*120+VF,`AC(FHF>'1TW54X^=$6ZV` -MD@OL8!#^CFO,'Z)90*%`9Q5HOV%*-RUBH*LH/^'?'>I+VV2@I/L-ZJ*4^R8-6*$\T+'W6;< -MOU&"L^E#R_!8J_\V'HC%R;M"K@YS=]HO9+A_ -MMY2H)6LHZ;O_2`_XM)3S\Q-V=8%0/94HMZU_PD#&DZ@LD-^L6%`#SBO5BU?, -M`U@3!_"&I$A4&S3R,^[Z=2<.SU0XD(NFRK.`W8H=/:5TLO;?&"`5B[ -MQUA#/M>[&B$R[V'35M$,4!6NJRI3EP7VE+MNZ2&.C-9_ -MJ&*0AH"?CS#F:EV@VX3GS^K`'B->/)CPWGU@&F#U$7%@`.N:<""Y1<=>$-Z8 -MZ76$%09HT.D2@;AV(L>*4BGT\":Q@>\29+/4!YPKU)HB>?[31UE!Z>T?"C"I -MW*"!V]?W`28`PDP^R'67;)=6=$DCT<8$CU6R8&2];-8;;=3^-'%![*-J/PSB:Z%=*MA#ZISH -M<5$Y=+4M_8)H2#F*]"8Q_W8SF6ZPX>AU&L%FJ/N$$YGR!XPQ0(P1,-3T-11N -M.[RRO/1\UWUN@!.0.3$O_VT-F1P?'9L2`_RZT474/G=(B!;AD\"OCU#F-(V) -M&P= -MME;IJ4T;DK\-/V8LA_S5CMX1J;_<;+>!%$\W3O.*,(G'1)/PRB@[Z^M97!AZ -M1TQX-[_!1D!60*0G`P259&@*S3%?[%PO`,[,1V!2[W8Y -M^,?JX5%.:YV1IUZ2A\$"]?YHMHA6,.FJNK/=2+A*Y;.3Z81)'I*@0Q@I*IOM46,*=CI`I,PC58,AW:YYG",Y(6\8^C$RA -MN2>6>[,VDOHB=;-VS? -M&+55.G%=UB8@*$EPJMG"]"*#0/8/I5V"4FJ9)Z(34]?]1FSK7=(-+.\,C1]DB^(`IX+8`LT$YXF\;- -M$1%8Q]H:932D5?2)`T.-1.FZ1^OX88%_Z#1QAI-6475S^077DI^'JV881`#V -M*CC,L4Q@I[R_GV<\J0XPBYGW)4[$6XD9B\:OU;*Y10O$!')T3/1P%"?8.ZS1 -MB497$V)'WZ49UZH-[L87'&LE4!JS[L]OG<2B'NQVRFL@,VLL_1H;:V"U^$I+ -M/1F,!6:^;)1[+;7$MC%E=;+TUMQ_"G"6%7<_E.?XN:!XJ'7^^#@(SS]YVY@) -MI_9G2M[M`J!1RI`9PK,B9N*%A`4M"'W=H?9$FOWFA8P;[]7=1B[Y3K8[UAZQ -M^(V5HYH"_M(.%Y2%1G@@/-PVXI_`31&W0)O]-_ADK614ZRA?^';YO(;DE*'U -M/?1`BD]Z#A8FTF(&,#6A58LX0R^>TKD+J:&C#2$_74'VFZ0H[;1 -MCMU1>S$(QCQ:BWE7`8S\Q&I'A_NKTOH-9/A=(NAM=S-7Q^D;+_M"$BYH0K=N -MT$KP?E3#Q=7[(Q[3:K9Q=#\&Z$4AK*)=T5F_HM*7[*K5!NLBW,0NNFV3U*!W -M">4>NW4<]:R\O;,2&?"K7-"RP:::.K?_5-'QHGG][P$.O."IJRL$ZW=2]+'C -MN9!V1P!+8(BP8C!J^^9:IJR1!KC;3/KB&>4IGZ[I)2FY.";&HA%Q+%>JX;"` -MN)%E-]H(MJ;L^=#^K?=5T4!*$@"C#]!<$)N+`Y"4S1K4"*/1I3SCUE_UT6.. -MD18L"CWD`1(D@+PWVB2I?U,@VPPZI^EK3N).[I8NUQZ31`VB73-"G:M%V0IY -MU00]R-)@)EM#4;9%Y;$V;(T@OY-)R-R[@T`L`6>^X=O5+GYQ%T^I]V -MWG#7$P1'4B?R1KG43^IZHOF;5B%)DZSU2*(>GOWI3LV!+039^!@+A$'EO!G< -M4VMM10[5!_RK9X+_A8]7$9GC7]V.6OPT;0`3^B&*.\>.NB\=O%A-%T]7*24M -MFNQ@:/Q[^1\:@0<+I_X`:-R0##)*RK4F?L"[C&2.<":97#^*KMRR!"M[NROV -MR*GH;"T:I'$E!=547`?=%_D([<'.A79/LMSCV;%!JB@-T>+7YF+8\Q="[;35 -MY(N[@N=PT94,N?/2MDUFO=L_I==T[/M<_8*]H279\E#F2+#B8$7E#CO:N-#R -MKN(-AM$FL>'$=(86RAS_A(Z1:AI^IKM30%AZW6B?RJXCK;?:( -M`%C))V15$=G*K_*]AC/.OEKI=*5D#X3@7'DG.Y3;?]^)$"*1YAE0$A]RBD9C -MD^)63AP451A]VE03P$(^'[@1GL4"_9J]2Y5DU\X>3F5/Z2\?+K)_2M%8@W^# -M65H0SG';L`Z?"X9NT3'CU&=#HTT.N>-PP*1M1U>HIO,-D&U2`_NGR0EM8P0K:_OZQ\USZF`UC^ -MU_]7<":+UE'/$W.&Z4/U(2KBD!-!S+\MIQX6L!=H?[R_N-*C86/@T7JE<^3[ -M-P-D_L"#XH$W07QB\TYMA:)39V4`HO1@SA]AD4>+/\3E-"M9\E<7:^8@N=?W -M4+07J+_$S&'*7+;2T'HP1"Y=/XC13XX@`:!`H2YDW(R+H%T/9"!FP@0MP?C% -M)VA$$!)&[YY$,^WB]U0ESWAK&$;GE(U2Q41S!]+],)&LJV]!FR3=C-Q#L3`9 -M8,]GSU6#G'#I)Y1;B+E.AI*DN",*[H+'G47$&\2ZNPQH0@"+4:]5SP"4_0R56/C75PJUG45L02\8]]]ODG;][%YMDH4 -M+WDQ([%;/Y6?@1:92/1H7):("-QA'K(*$MYC;U,C&*H(#A_"P*GX61S -M>)J2WR\>I77Q%.^IUB"V@^I0S=C+3@HZ<)WAXM^^<0K:->WO=/G8E6`J.HD3 -M%8$4818T-,/RA6Q0B.)I:AV0K(\9O#B;-LYS.`B[[,"*"R<.&:,CW"=].]%I`2&LR*BB[=(H"L_K/KX#PVV%^>VT-H+M/M?]X -M%I/FQ5\,M=I\<7<-QX:,N8ZJG>)I'280QN>2WOQC!8O[T)U#0`O:8,Y5;&VV -ME$0+/JR"H-O4:XZ1,M@%],US]['@7(*I!`TZ(>R1_3`%,U:I;6ER*?BXX.S(B09?DFJ=4*'#!]:&M<'Q)X-_ -M&O=2AU;NJ[W7JF>LQ)P.70HL370-11X5#!(-P8HHM%'..O]$7QM#V\;DNS%% -M_]OXLY1+OGVUPO$_OV3='ODD"J)I-?)PN]QIP."61E,59\3RI8IDG<9ZYSY% -M[.67[(4P+0H8]PC-VU'JNWX6(8[U4QJ-O& -M8=R>B_IECZS@+UY6Y/U>)8AH00_<>72&NOQ<19";5S4@D",$%@>9=E>R1[LC -MO#\I>MV/0>O0P^,E"K8I;[?'V(L_G@ODAG.M:!%2+5+I$`0?;S_[%TK`X2JD -M^P*R:!)X!]NS.2_Q&_-0Y3@WMV\A+9.+CM7PR22&#OX[O6*?F -M*1K*71G6EI8^HV.BN-I_H8XY#&\CP?9V9>E/0")\@:73R/[ -M"F.2&(WKZ90T@\"*X_/G\+;%-\N6D*5I\.\71DHE>&C6[14`.XGHR-O;>SPS -M>*!)?^*JH`16PI[;YU&6V=N]`DFQ]N-VU4J=$` -M)(>N^SN!<>>C>R\8;7NP6,O9BND!$:-;.6-2V\VC(^,-EFS(PBCUW11Q)F?$49$?.XBQA -M_XJ`8JN(!;O_*P9?4:'9ND`\C9"([*9RR+./*-YO+:(?RNDBW^7FRAY8?7ZS -M&9#F]+[;LVWLU4W^QF[)7+Q#17S$!*3,(%]X9K%!I7SF_9E>"'G.!\'(P3GO -MBZB60T?WH;1$LZV:ZKU7F"\)T^/6%=5F](]^E@M;6K&YTPF*,^9MA@,/OYM( -M/@I:N_;6$3[EJ6:C^!KY0CC!CDJR2C!_Z6SV!+PV3,"[==OK*WXW7<$@?-,9 -M)F;9%^A?HT85O-CJ>%0OE9!DLPIS4K>C4+&>SA*?$4[X8!.G&NG -M0M;WFN>1[]![]8)2V4[LXNT\P31K,^?V#< -M((14)!&PV:;C^'S0IS2$36HSJIGB9#9J<+X!";:"%/TEXE#L<5/EEH.I?/Q_ -MPIMX!78M!14N,H'$/ZR -M6F>%-6TPD#[W<'<#.[#.L(?%9'&_X,)HN>#7`A%-T"D?/XM*QS2_UK"MY>E4)K)=JV-?9P><"YYHZ(? -MOE91PYT)FU#\P*@@&O>-&8:?"VU+"*V@/2__2S+LYGU$ -MDXHZK-8H!\E+8-EE)'.@Q\#/(0RKG+UU;Q#9A&FUVXI$O$];-#+IV$)&"\Z9 -M-E-I+OE?28I=@08GAQ"]KEMNR1BAS_N:$F#:;:,)G -M&+(\]#;!ZQ.Z59(XSV``7U2-,,VG69Q__/7OE6+L+\"NQX__VO_%.,SPI?$F -MEEJ0-1\8)N47EP,LF246LG]E:\'#8T`($W.6*A^A]C_-`/7CU_ED;F@.]VDF(K`M -M0=]I[IC;VMUYO/3@,Z"#Q`U^]2A,G#;WPIX86\^OV9/"T;.9I3*@Q,[5$,6W&L;;`YAH[B?1@\F@M=Z4B:KC`T*]7- -MG"410*M3-7(R6"OW1ADCD3*_6TR&JN=?S1%56:O0N[>P0JS6'2.Q"("DG)P^ -MNEE"E@Z!NIC?&8?E:P=%3YCV=P>9VZ6ND>8F^35FJUOY#/,-DM@.L"0WUO@] -MDZH%'P-)8MG6176;>IOOM#/2"QTI@9YW,^!4,SV_C>]X_+Y>8,-"L6DV)[K_# -M)G.M>.DE5G]%=M^8NHQWITR,PH<*)N)D$'F2C0_YT&U'^;#[?7#V=:_MWKZC -M^4R"RFBG.:7_^U-^5=\]L;8.)SNZ\04/[BQTJQOD\1BH`[I$B"5TXW -M&1UX!$G$B@?F,X39M`T/+3O+ZLV$J]>+MVX0JZ'*L$1/%>WL80E^7JZLXHS% -M>;"%>,;#]!*7$V70%1TWJZ'6N>0$C_TA`?TLJ3$'6BGN(]2?DM]NH[D[.!,$ -MGP-$!3U0YL60*ST"=EE&NQ5,+Y\9;/&,<_)_3WWOX(PE^I_YJ$3M$,>^@`J] -M0++!/9E!S3-GH4]%*';$F>+OFF`K.!L`56!-=%647O(W8KA;S"'KR=@)O5S1 -MW1S8B0MY#$@3G0=$R6$R>E*_;26UE7^F\!\8L'7O,J^\ESJ:)HG*FE/M%QPM -ML&M>Z&+>+)]U8DC(IT=^1?U[==9PV4[BEJ7QEWTJ_VY".R;G37[9IR;\T@\M -MO%)ANO_1Q2AI64-G<3F3X8QA5PO'@R%0#8$-0+:S-O0Y_E#JMF7,S>]X0$\\ -M[A>G#"!ZDM&)0J?R3V],,);DSP1&;[]P>A8%LS4;?T;X2WW`ET\.8XRSR.OQ -MS@:@VD0D0P:@(./94H'12FA4%NAR6GO"MJU,%HQK$Z7G>6Y5V5;2/Q,%+/U= -M73S**(-ZY[I^PUQ-K(S<0M>I(OTTR.\6568B:;+P$X4)Q+!'"CGZN+B.):7$?.1M- -M";O%!HHDXJGT^-Q39B^]FR*JZ1Q&-M%YG+$0.?]!33W;NEF41GN]D%`"<%)B)6O.FO` -M=?^SI?02;!>-3H3.,!QJ*:3U:-X]WO\)O:T&$`R^JIFBN2Z:]X"+$6(F%5K9 -MW_-+`U>T%4#6T*LN=-,1)8-T-(IV!@KXF[-;<&L7`#37/9ULV<]S04T'E*9U+^^L^1 -MBD[]*B;[R`218'6&2B2J;Y7__+F%F[KBO*V=]4)RR#'6P!PQ%C(L8G-W>IL@?',"? -M7OSZ@LL.FV;8W7>!?8OLGE/[;:-4KZ'Z?A+:VO>N_]\98=P"1?,";<_D#?7) -MH%8::F#>/IE5__@\L4<][9L*<8F]=>ST7<6>'M?*R@R=[KL(4"IY-=A$8,PK -M%]N2BT)1<$3J)P(O_+E&73N3=6]/]Q%T(:'X1B<]:)+WW4L0F;T\PX]M2+R, -MTT$I,YRTO:EX&NF9?31$?*2`\("G-N;UYD$CC$1R)_.F#34#EPXEK\2K4"@*/F[)=!H$2D86BH[:A?A\ -M/A6:7;H)-&SN5DQM71CE9C*`'91.4=3EZC]3\[Y&3BNCUZ'[>/GTX)=E=.FLRD$)@+4=ZHJ`M[C^`_J=WJN>]*L1H7P?F!+3[=<]*@ZY3QG@9_O -M[28AQ#M$))D-8OEN.7X\_DAUBW*;_Y'O$8(CIC5V_'O'$._P8#QC1O98'G`3 -MO'8&[<_)(%A4OJ0R:AA[*XG:/.*" -M/<4R#V=W,V+J=N..<;AP1HFFR';0CC%(+T4I_;R5Z.A!W[LQ+=^K\)J8>-T'<"DZ'.>I6XL+T/,2/MLF81+J^$EEV -M1/V&+JX?_?M)*-JGARXI,U#L$^[0(TWM05#!4KZ3-N%;Y_*F`9`1WE*/.10C -M6_G).-/.J)65E!>3EDZL09=A&IJ&?!N61TSOC&MMS1WG=X8X0(<0%K0UUDSU -M&P.X_$035BJ=E#7LX)`/554PCESNF14YOH+%N@JQPU/,PZKR*`3HPV'M^M"< -MWG@_/#099T9EI6>/@-ZM2*VU2V4Z9NUZ48]J,/?RW4;\6[OH(7;F*#P%<`V4 -M"N087*O'C!;*Z*"9U%,A"X#OBV$WE8ZS_ -MT0-U6FW:*49&Y/B8QFK,&,\2&[\1'S6FLUDN)3]1ITN\8(C:!LZ/Z4KX]`]9 -MM)>^G.%S[_6T>D)F@C-_K2DYLC&#`A*6V#A-:[8<=-+_Z1Y!"P\WM%LD"\BB7#32:*LPAV#TJST:46Q+;Y[LZ4-*B4[\$S -M23NZ"ZU()&5?J@+]0-)V/2!G28)^VV*;Y##S#BA$-(.]*H -M=,(0=4K9.8>5[&\#6F"U)JN4O##+6>/PHC2.(MP:1_X6B&I3A5:F&YHBL'XN -ML(=]2=,\K/YH^Y'"27ZB'K<@20QWQL/X(!*"*;]A4`@4< -MA)(ZXZ2X_9=I5$AR5KY#[M>\LT)0>V1>3(M;Q%H1MEJG'=5[E14:P\?EVRIS -MS[*5%H73O@N.\[BW>V3,2A./A72M0MZ(H8"@C!SL<`["A=_-K::!OWC"BEI6 -MVIZX#@#^)N4X7:=?D>UCS/*VY8ZY/ZBPW88MK"-1F,PU+9)GQ?;XK4LW)63@ -MDU%@$VD)_MG@2I@F^[*SZ\CJGX)0P5)Q7_Z%Q-W2NV8X>XOK:KH=PD\4..H& -M[+>!C20E(19_]A?>^W/SI5]EXZV3LM4?WW(Q;HJ/&@++Y]''^L#_R02*9,D< -MOI(`=O(N7=A11D>$]N_3MA\!;3+4U>^U5QIZ.A6D8B47=]Z:2NS=QB4OU=!V$`EF6Z+4O4@9R,*_DXR@;D>2<+TC7.>7/$_D,<#6 -ME=!I+LVWW?E3AFQ.RFVE113^"=`6;6Y@WP!S@)!.FFAO5TVZ>^O69=Z<3-P\ -M8QK697]:^<6U?)?WAI@!052IT`>]45#UW1"U>=\-SC?L6%QDITS/T[*EO_R$ -MQSX=>LUD^$ZJMY&:<+9JXZM-Y@%'%JTZ*&"MOS,9(W"JIJQ97]_D]F^&3E:/ -M8!&-@TET4V=ZG2X.NC]05B!%.U$):CCF4>]TNNRK:(+[_Q^&]XSN]OEHQ**` -M92\)]K'@S>NU*RX$+(_)+3@*WSNJ"JKREPYM3G&:X!"`!A8PT(YF&. -MW+R=(=I#$OASUD_]!;#F=^"P8))BWA''L_N7E&IQUMN1"TS:6@6U]C7;U^X4 -MZ-25($[+^,V&\M>$ZW1#%%I)Q53>S(KCE6![B\#B=N`F2@E,NR319*Z;*#E\ -M0^FK(.'P#;>=/IUF&UR;"^T#@A*#M]T.U`(!,9#[8E2M8T)5>6?<'.?-4>NM -M$1)Z\HH^FONCP33>E2N/$(HHTIZ/8S>_]_FQGN"BK8@"!2OCIRG*BT2"FMJV -MV(IU[)`O+E=$_*2ES#7-DK)ZV!:\+CL,Z&I0V.)QM!F\[1MZ!I'YHN'4ML@0 -MXCD:#2/3P4D*6)!_2T!+$"+,%\)3HH=T1G`H5O[_3E(Q1@'X%OX_8%0^@#NECNR1I+V`,5S($-@JEJ3[TQ/2ZN4/OT*N, -MF?*6,_\KIW%$J?V[="7[E -MHS&OA*OU+/5N+UM`Y&1<_OD:;Q!_XAZ.X?$'S_DSF*8$Q)U= -M[KG4<`IFK89"+V*E$;O2#J+/52KM+T1(TL@KU/%O\(:P<8A\DBB+&Y:/_N@E -MWJ;AX!)+%FRN$+/O9G[)N)BKWNQ[$WCV%U"L"2_:'%WO;$7/M?\7)+VXS$M? -MHF$O;1CY+PPW[BH!(4!ZU+[O%C=?WQ)GC^(1(CPPLF_3K7_'Q^))9L::`@ZJ -MUJK]U&"8`?0TLD.3BU^MFT5.>[PIX;9E.3P+$ZTJ -MV10)2\OA'%^"4Y?0TB_6PM!1/JA%*WHQP'R@X+IE9P4]9$/4G"/P -M\MJ-O\D+)^-UV$S8[N"CE9WHG#DIPK=JD&(ER3J4;S:CT#)!9ITV^FA&,(SE -MLGA9X<#'PDI01$V2$\X<;_50F]4E\GMU!+4JT`Y!S@@KTOYJFDS!)I\(??!*>=[H"ZL]%"C6L74:\,'>^[HOYQ(5(S4 -M,PQH:G!`"T.Y]IX,3('RK@G_]$D3W5$-30QHJ/VA_VQ75`"N)L\0WO90I@!# -MOV**Y%R7WZJCMTW/>PRH*D%$Q59(MS2=<9F<:I:_$'Y%D<9 -M'T>(ZGYLVGB#!_ME=W&W(>Y5K1AZ*BVM>Q^E#N^;%RG.NR-!/@#T[#E$F0Y[ -M]E<%^^=47,M>A3Z+2+791))J).F6)\M/KJ1%DD29$_$+FF]9^9.#0A-!Y!K9 -M.:^#2E$.6:4,":$895J[B+W<`4]6^+9PMM$D5PBTK*%*_J_N1[&CI1]M,W\A -MB#I!M3)@5R+A)$,SF6&`/@C9@41U9UF10(CG'QR%#S\K/4`K5EL-PF`DQ4CK -MJN=.34'8!!(_"*F4LFGPK>RBY_,.P;M*1#II=:SMF>/Y*452Y&3(`V(MX?*@ -ME::>%M#DEU6>8%Y$=RT)CJAN69/V;"3LJ=#7Q.Y7Q,*:,99\8&\^U$NV,=,W -M#A2]!@&S9P()=@SH6>LS)G;:2HY;EMO))JNYS(B6U%"B/F]:/,TQ\K[.,6(X9]!<;9?G]6KL*^/>=?)XU`SJ[6.Y&^C'P-LY -M;2E!^G+[K&+KGW=4K\:]+0PV4GTEV<&'+3'Z]%_;YU0FSV^=@5<4__5#'YC+ -M2:H((G+^_$JK2P/.M#`/=2LRVR*9%F%=SU_2\G1(7>QT? -M,&\,#J/PW<4L%1#7&76BG',UBTJ5$B>106GR]MH(-H+S^,7S6VTE\6XM\J?D -MF+]"8^?/;^Y=LE8T!372X:"-0CHY:^GT:IZ!11#>!!]_0G4S77CGOAX\`0DM -M9L#D!AP5`I=EV?CZW^P]'D.QME%XA!4VH]P%>*JX'H*89H6V-QW=1#"USHRY -M\U`'`)3QERRVC9G'201?X#JF'(F"R,M'7Z.-`4O4Z;P$+Q,?!A -M@JO13>Y;4VBN6B&55=[6*T]<3G@2S9+P(&[<%Q,KTTN%97<([/A,\@C -MC3Q[E[6KO2-D=,R4I7ED-VJ1SWE83#)..?6=L?@V+^29"=4:.!D8J[6,.E$9 -M[A;:'#2%'J6*C!=O\.'-+6&^0N`#Z -MD!BEJHCI`!<-J0)MNXK;CS>#3L(\FN:RP";L77SN-C2O!RCY+E;OOUNQ1U8* -MQN10)T$MMT9'GK:\,1II$Q%MTG)AJ,2:1%/^^<*,``#9?9"+]G\]NDV<%C=E -MO)+I^(2^("`$"C(,+O)^J['NF5(LVFO8!8`F=X%<@7QU^O_:2$K9?>-E]MU5 -M%$BZWQP$NM&X]PJYTR3'V4D6MXH$#NEDHN$E\12(-LW(@KB5!.MEG1@@%=[L -M46%)-U^0PBGWFW05QCL+^DFF%+PPL9SQ/@A)MCIH>$04:F3V!Q'KY`KR%@$Q -M.5]Y3GE3&S*=-<'-#=:57+6XGC?/QN/CC?/J%!#=!7:89UC9G8?%.9*1@ZCW -M(FBJ'A`$339^\_#W<4(G;Y2O_],"](U;5;HUT+U0WBI^'7P48TXM8YE3,?O; -M&!HAG.!H+?O:;(`1R]=$-]6(&WG;$P$!Q]7"(->2THC:6#+K5>MM,?6K[8KH -MWQD>U"'!>\OPG&6O'`/P=`3E+KEW;P3G\RT41>3#U3&;$]IV?2V?#_IG>O&@ -M#2/;]!5LB1P.T16%:6=A2BRLRTW!;'1[6B+MZ18[GY&(42LC]X:4:`2D[>ZO -M'GRRLCC9J>KOQE<=&WLFDZ8''1XV[LFM7JW6@5PQ)8MT$1+8#:1D>7!<)S[I -MIIG#HHQDRD]VAJZ9P#N#XN28*/EAZ/A'2+<.'7@^W/`A*)_>3%"JRY-9#J/W -M15*7$GY>^C_2Q82V%Q6)XEI%'F4C;)@F+Y&+I_L0G!"U3^8D8P=;XP%*&$-G -M1ST?!?YWS4RX6'F&P4S*&V->TL:\&)+CMDA\"ZQ1>A##X5[`6(,1=;]W?$=Y -MYON2GNNCQ*;GH6, -MU%[3]`8OJ;ZW]$C(/#YJ`6N8)>;\*N!$EPTZ]G3&WQ5BA&%(*F* -MX!^7^:-AL]*?`UOD-YO`LV#JTB[L?X[&\3$.YTZ+"&A9]@56@UEP:-+Q_P"# -M<"C_\2E%X**I"2ZQ!OLU9XCT*@F<49JL+Q`$MN1?*2`3ISHO"""WU!HU,HL< -M]?6BO6-,*D4E3;V-3Z!G_3[\''DT6&%-6M%&RVAI8:?='NQZ2R@)^\6X(V$2 -M\UI@@LE&.!SJEYJ+'1@<)C3VD'_S:YV@//H5Y`*,;U\9!5N8:5+0U+,!`@OW -MC1.K5'Z#09"+:@=)$2/"I@-YKJ0F:0RYH7KV35+#@3Q]PIQ*W,`7IZ;:=3>5 -MFC+#3X*G%Z=002!7JY7\?VR4UWAJP<>0WMJ&.]H#/%Q/#",6MC5D\_%MHKYL -M=X*2_VGW%<,A.5"_'>GFT.0M-8R'P&EW'.Y?`:@8=6BEIUF]6[^`6C7+ZX;Q -MX!*\JIG#"RR(#I$A3Z7[3P;^Y9(P"0YGV9Z+^K4/T=NR/C]RCGU5EVPD.4+0 -M,S$<5/^R8RYF$_$A]CT=6(7=ZTP7=UK&];CUO1[?T_:<@U1I46D\[6W]JP2X -M9C)YNMGXQB:?5,33%.#18J)X$/Z/?X/6,WWAHG7HD,I>H@33):L'W7&$\7LG -M9@C'DXN7=QP*ST^GK-\ZD='/;W'VLZ00&[FME5J98V0MX\RUB5?,A7%PE9UR -M!=(\&19A?6;\=V^93R=E__.OOD5G^"#Z4KX,5)482P0WWM)591LV8,KQ[R1& -MIX;%"=OFO5.BD-H8@*L,8*/HV?,9$((I;=`S3P51&DK"ZK>V9$)&'MQ"QRO: -M$59(;FB41/X8L4L=%B'?DO;1*74%"5S`*Y;`0O;]*5I -MEMU$HP2(T9IY\9^!^/OC:&[G3JEO,<;,!N8?Q]E.;)7E -M"\D0-F?&=U:X-]`PI9RY[W^#ZKYN7:V];)(<7$",#Q8>SU9;029:EYOVRV_3 -MG#2'645/XC$8;_R06!NXL9[H+^*21$F"#*&]IAI2YM)/2\FEAR73(%#G(2XK -MRT54X-RM\#I&N9LA`R54\)U,@)\G.Q%_M^!V+R-_5OB9_TW6Y6/25+6,;/'\=K!Z -MR;JFZ,)/C_KG/$E`GEJG#1_$Z/9/W=-0H.*]+Z&]2Q41>[-I3'^3L?^4;@TQ -MD)?$J0VDJ+)$=N1X%IGZYV+H8ISU:,B?* -M1"G>>L+GO;Z(2SOUG,^%DXCQEON=K,G/$G[II9RB32,KB/I7B4\=YD<%K'1FT,N1_,9Z&DS#N^PF7"]/`(/1R=12Q^/GU*C)::&M"A`+ -M/V3]4!Z'X%/N_=H58TV#&.:'ESU.MVVL")[IAF#>FA9NE%XF(NM0%EC@M1N0 -M,Z+U4G+5!0!=36S#MO<&V+]!6=_W+3:%4O_#$;].KETJE,&7JKP=/JW9J^&R -MP*7"*\,HXL#ET!3R_+_*=:A._W28C^A7'W'?;*FQ$NY5)8JJ]X+<P*6P1 -M:9)XO%>RE./I8F^>9_S8I=^FQZ%+AC?Q6+CA;%()T[!+-B+G^._);'Y?'UU" -MLHUK!^!R.O7AX[U[4&A..J&9["]_2&[;0)P_1&N?.C#'C^G:4@6UA;KE;O56 -M%7$V_HA21]5E790W2"K(BY6>\YI3\#HH5L[=D=%L"%;[CLQ>=_(7MLZ]N@<[ICG[[KZ6JV_$8@!0@;]S=/:%D0709T/V(2?$#;H4)\%[+R0$:U -M7;PF"1=A./?;_ME]6*<><)CLORU*-8.[(QPN6(-,G:U-5%"\N\S-_\5T7;OW -M2#6=.1B[]+L*C`=/R@4Y-YC'_2?B_4,D:!7GW'>H!]^Y7)`6TEJ9\G)0(^0I -MII:_V9S^.L)ND?=5*=.Y)?0/!MYV>F)/MT,T*)0WDKV@(6/6^GVM`)[`X-@? -MY?;4MRD-&RDTU6X"'"7I/!`S'L.9L=0;/KEF!"L'8NU/91&7%+X.Y5NJ\O/W -MANV+#KE!KRM0*Y8X5/`N*41(G)9!_%AB`U2ME5*FBG:_H`PK7;.VSY?0!E<\ -M&;$=OC_":R!P7>KW%(4'0+DY!I8R%$PYI\:G$37ROR8)=^ERDK9??12(">8* -M-R/+'!F'50U/-S/UI"'1RFH$#,'$5Y"RG6VB*-&0(H0E)_1%A__NZ;9\&]H@ -MSG^5SA/AL(K7_U5%HD>"0P+03N@-2;2F2,A^2\!,5D_]Q)0TT"=RGWST>KI< -MVDI,)1[F5T3+2M@WKG'Z[A@^`;,0'I=&I3UQJ/KU)E^#S8;:C!`M-`YJ,#0U -M9?V(/^.;=JW4=0&%X\XU\GR6682F?].3Q)R1F1YMCO:1C)E=*P](?^%I*.!:,20&O#6'L5ZM836X1U^*2& -MCUY\K6:?-00I1;>QGG-PG3)B4'A(C2,`Z-&[M&ZBGUU]3\*]241.3F`)-+W= -MYQRB+[9[]FV?AXEP>DGV\@PDQEJJ7/:!:E1+YZSU&*`]V@T@.%;1F2)O<-8L -MYU2^,+C\I)ICX[W_N/Z"C:]4(:=-8MQD&)^Y47`^C^K^^8ORO6.7-\^7)1EJ -M&G$"LO/H#6!F;?V, -MIH@>\BF:F19\^F")']X7=S+R\3?"`\K7G_-(0?`R\CK=! -ML6+#1+P3_;96[V\!B-&2J$&`:'P"[[9&`?;9"E48S)=*%@PRC;'EB?3,K*&N -M]\O!V]3_HX%P^2MX#Q0'_>\E"T!G`;'"G^AA3;M]\O8L`8>,ID#"-*7N##U< -M_8E>P/!X,&"!B`<;BL(9))VGKK4FTAWEMK:91TU+X@]F*CR_%K8A/@Y3+)_K\ZGM8?O_WUD -M=HD^C,`7./QP-&LL/*4.D[NY_V](GE"Z24IP32`FV9*-U;'*7DG<_M];";BM -MRCGZEG")\.J84JH/%57F'!J;5%]9.7BRIBJ8+6E^KP]#A$2CZ[P,$ -M($2(9W0;V%+^8L^RA)GJ/<>#.^_=QY)3`_'>,?6YP-9F*-Z9*\2M5$:A72N: -MF]*31":!95H"ZGKP_5I^0ALN75YZQQP`A$(\MKA>>"I+Z7$E.'AN/3*AVNY9 -M]1:M):`+DF4$Q-?PQ2%IH;OF7Z=`V((:5G/OO?8X%U\N-::4G+C+!''G:!_5 -MA4D='E)X1APVM()2^FW@J-M@?V01I890=A.QFEV/(^XU^"]7!3BO-ZI*FBQ` -M:+6\>PN0YPQ@-I6?F;K6U2W\!H2D_<7*-5LZK6%SK'R:QVJ<&@JS47_ZI18=^92&G0IJ60E&*%8(V" -MH64K%H5%C!A7+X?PHY54;&IYS@WH-A55C!M_N)+YR^]3!RUF,A?HK -ME`;A_P$0O'0]PO,_0L&:.;J&,?IFR/B#>!L=@-P!6S$X<1VG6V(RY_Z^UG!, -M$!Z!VI/M:`\7>R3'5,&X!%KP36-$3".J3-1P0TWY0H9D7GY8=',D -M39/K94W1H'6=$1;E)#TVSV!-EM6,$WOJ4-!.1J&44G=1G_I3K1*.,`00>(W/ -M%-/0=])"*A#S+Y[$D4BVR/HJ,A41WP"35CBI] -M`<(-CAG^!W*3[SJK'NN=Z07WHNMY'+W-)I$GT-A:X64H1Y07E#0%*;1(.C=7 -MKPYCSM_H@=?JRKH>-B\&9UUVRZ+!`.76`MD;;$`T5Y/F;0T>@T0VS -M3#U`,.8PDR#+EDS_19DA?!\OP*]4N.F(]G`@:Q/]"0=.1F!M&W[^"?\I!8MUX4*@:)SXL]Q2[/ -M=`+^*1(#>N^B6S%LHA_9_+I(6)`=<]^KZ^T2M]G5#D9QU7ZZ7TV6@I_R,$3P*YJO6!V2VJR0?,7VE -M$WTV8J9;7\P=A/(:DK19>*D3:!,RPZAM=B5"TRA4`9R;"[5G%2602K;.>C0` -M&;SY"8_#_53@.-25SO$@VBW(K/`NU!'^!^\I!B.V%6MK5-/('Z*Q3\58'@-" -MAUP"G"'G6@FPNS\^@FM:ERT&F8/IM,V=[,CPWX7!/S;XA+8AC6C>Q7/^APN"F@0W1#X!@I]"`I)!;E^L;_>X\48_=/L -M%OJ$I"!(<6R8+48??\UY/AKI'KG5,`(E-`"2S6CL&P55M@TP?M#'GS-!OAW5 -MYXI-*ZZ"31FH.YN$R)73F8,4\4TO96>X(\36=)EYQ#ERAM4AM69"`*2Z-H4M -M(*"G-MUCB^3TW!+)K6FN1;.N`',H./'HR&`#\N;!1=-OD45:F(/6(][)`!R1 -M#:J9XBYT4'I[$.OV*(0=-VPTJ@0>/(O460<2_^*`,BM_V"X'4XJ/X.FN&3:L -ML3R(E:N'<6/8AA0.;458&LI54>!K]K4$)#!W4WHY.FX*OW+"@` -MR_'N"NA!0\4=`^[[AT*B''J[(<@D4)@DX;6;W"UGI9YHQC*2S+ZV+Y.$MZOS -M_?4QKH#ZSA7[63-7<,0R8B4?'VG*5,B+TF;;J,>ZFL9>R(">4.PJ+%5.PR;* -M\$3PJ-9QTT/TWY;XC#:ODV:>$&A'MUZMKW-I>(CF3@+7O'#FK%-;;=MA'71+ -M+7B3G.)1%<;0`ZG(Z\K^E4W*+)(>)LS8QWUK-W/@@4(F9;2`,*O^N[%=6&.^ -M3@7`8OD.OPT(?! -M)B:L^8B7*K4/RT^(_6""/,02[S=N;D,6#X>H[?R&->X2T#86*N0!6*>CS!H0O),.:D)F@1, -M%I&D=*7ZM24NJF4)$.V/"EE]9PQ%XE&'-Y]JH$DTP9Q(K$0?!C`_2BFJ)9.G -MH!K.R`YZ$P:3^.HUD<\[9+L`'/92E$J1[)%[34>=`[O&=*(:M%W_2`,*A3)' -M=..*R<3S=&-H`,U"^-/<5XL(/A:CS3<\$T._]['%OXP6V2HB"J=]/:UZ5MX^ -MA(0[O-=EXE#(%'P0PH%=`<0W%>+)WQ/T3SKV5XM9-DV6M3I4)&<#H>F5P2J==+&C46=P -M!RAJ@=!L12/#_G5P<@@R[^P@H)8&`Q-T&! -MNUYU$Q\\3TN:.\U`.\5\[ZO[F/1^`+J>2U^._K0WNG^CU@EX:]MA?'][I'_Q -MF3KJ>`/`_'S!EM*HT<*JM*X7PH[6^:Z,!JO7(S=?X^T-M -MY5Y&*"4?_7>M9D7*22#Z-=*]C=7.U]E7#*+]@X8X=@3VJ7$<^*.E\YO]9;DO -M:&QA/77&ZS+"V2OQ$ER@>/A5U$RM4P)=""N&'TS/.[^K?/ZIE#Q3]5=LBFY/ -MW%!;`6B>&R^8$N7L*2#I"%^.A^VJX\\EPWG/#H-G(#%Y3/QD'3E1((__YX+% -M;2F7;/XYD^_P]L7ZT3`]R7:0$*BMT&M]AYU$8B+@#W"U,-3?$)P2_"34%;8& -MF(=!.':,\"HY!VP.?JRJ'W`3!O))^>0,=TW_W7.IS/+96YM=1`8]M*R.TG`M -MV,2-1_UZF%,YOX.*ZVVZER$L5"8TI*4BAY*TO$OWH/)+QL^1 -M^6+EMY/X3-DY>:?PT0A!<+BZ)J9KO+^Z@EKX6X>7Y8[HBO$KZ:0H3>%U"^VD -M\.B!J+WW?YP? -MQFCD\%F07'[TN)]P;VU'A$5F2:'1I&WJS[\^X?I$`,4:)+0!VX5Y$YV-"*9? -M70?3I`,4G2:'+OK^' -M:81@97C?*`)7#[)Q09@2WGX^Z",![3K947UI0LN(L!@"<5A.]EX7N0[;H -MZ//HCJ**P"506`L>B^$,5K?\#`WAWCC/1@F(!3SYWTSV=CUMVW<*`01OFTC` -M%P;=%3G2FD[Z,C)UF:?&>=*5[OTT.N5@S.CY/L5.E%0D`+NZY(#FQTE -M72).3^2,=*@:[96L/IT.\]>FU4I.12]G!76Z,Z[7EN57'"F)[#KEP&!SS#!R -MZUR;5Q`^_LVIO0S_#.26C7L_JMO>0F]S_T@1M\P"4W8%S9#ABR<@/N)L\8V2 -M%U"S?[^)=`/0+O^TKTCC[7@PCV(/>,"PK$T1NP#E)_0[T;8?/*#*E8D>9-L: -M(EHW^:\N+K[:!CJ!J3M1XQM%*IK+7^*_P[2!579%SE.R?6P84]4<&?WG6FGJ -MJ;+I6ZN4Y?P+%G.4$#T)/YZTHI`3<(G/_Q5WP"VOYT*"7#7T_<`X9ZZ2B^0S -M[H:0_[%]B%A2V%_;[_D7"3J0?R]2E_(I]]FW[#K]`*@497G3`E`U:J9-+3)4 -M?ZK5*.ZP^!,9PZNB,-SKVU=S8YGO64N!@7OI,"6^0Z*F.:N6-MB2[7S.%OU# -MJQ/R-\EX8;A:`/^%M+5>JVVL:#E$7@+^+]=Z]/9UOKWXQZ:/DK=65"4DHCVY -MM)PDD+XXHL.&.^^%M`A9)7/[H0^>0:F$!:UA!E'=[VVX`O9S4`P\ -M*-05(+EV\X]#T%YV',-'O:YAQP'\DE0!=R5@:`1LMO"&-`\<,1RS%!'Y@>,B -MV1RVHVEV%85UE\8H&:O$SJPPU,AM48LT525%`MN+8M':+8$`3OZS>_\XJW'XCJ&-PEP""8+6 -MY_W^$G."Q;S7;8K[;OCT/CP+/>P@A39_>"*'7?)P-QWN[0B;E]R(/H:PVN( -M`QSV=D@IQW6"8X_MCG;G]E.\0Q@U`@<;<53.=(1DAZQQP:,JI=`VT`ETLXV# -M&`LZ\685$P&E?R8W$"P[X3^V5846'=+:TK=**LZ&86"A>)"CA63RUCL73ZI> -M55_%SND6&1!5\^*8N)H;_87XBP8]YJB73^K)Y>``[269>+)8SUDGE`88>!Z@ -M6A!6["F<*H5",4-:V\/O!"&(7OSA]+V+T4CR6`(?]@&F$W>A3P67CYFU'$, -MJD`GB<%OBE2!HV'@$3`]#IFG%:P/Y$73+QG3?./)(V5L++V:!.72N\&@#4C9!6D"^T]YBQ$EDQ.8/96(!F!- -MHPF9QEFS/.-V)6$9L>N?(9LX_?))"-`=%'V\TS+RDO6\C`6(1:QM3GY>(-`/ -M[C:DWWB5\(?I&JC0`:Z -MI\8E[:XPNSYE'Q42&TJ6KF#9YI>T+*C@*6AQ)W^/,U/')Z!%IF?-VI4 -MJ>17PM<^8S"D]RU9=B.4GG*^Z'\2+SV%#WGJ_2BCEB`"ITK,+'%SLJ65JTQN -MI=^K!CL5VP%W1C$F>U[T/ZJ4R<]38/@"0HH&Z1F#[ZIGXMT&@%2I`:&\$%+R -MAU%1](2>+E2HNR#QN3&C,VA5[!NXLJH+=-ESG)$_M](I/AV)0:!'VQ(`H''Z -M\ZQR95Y\H7N))'9&J\<_LL.SML"A%0YG$2Q$FS,PE77VJ77.GO(=9-NZ[UO( -MJ#([B04'Y4T*Q/SB&*=S`6%P5/C<.IR'E(Z -M>_<1?Z%:'>JF=62SO8&RU_40\D$DDG;^3F[#G?\WN6%S2LO"$CKQ*57(E#I[ -M53HV[5?).`WH[PIB5U%P!?3I6#J;^P+GR)HI.)1*;U%,C4@2F+M+&I8W=>/J -MW`Y'/)K"2_S-0(`YY>R5C_&U8*/F;##]$&T["C'?:+0>&9.B:N.$(3?'@P)3 -MI$*%)/EJ@B1!V!D'4>XR\BD62:.\S%G98AMQNP5V7=A_ES]1*?7M%#K08&"+ -M,7H,RIK:MDPP4SK`*8H=CIXS!0'K(KC219*+S-LLD1[K#,PV8HS7EQY0'7%) -M6VI.LP%M+);-8\RU1]75ZZ]>'X&B2OT\A'GI\!F%*&QVIC9P*$];X^2LMI0A -MWO,WC==F!L<>1'>-YR`$&_N@U:5S]99DFMC*"N4+U2+&+5J"K9FT#U&)-^&!1=!R -M:37-X^ZU"J5`1KPL&MN1*16S`2#,-()4%BUT`:K3G$L[9G4I/D_^G:\5NM:B -M9.QNR2?KE50-?4YAG8UEX[^=CS1*<`E^5F!2D642C0";V\42S"_I!@%_&)9N -MW>7Q]X31-)?=,:TM,*:!PC6(=S\LD:G$C%E79>$H5DG]FEG@O85AK&+OP=!, -M+N0C$&1A93VOOM!#(][J3;$Y_JQP22P"./23+YT`*V'-J8M8=^[<25==$6U` -MK%:S74BA'+O$8EX.9'D^R0+S:\>E)@%%6)>64M]I/S"*TLJ -MXK+G*]8(1#3D:5(8JI'R(;/"PFCB2RUK-ER>!&?L"6[QQ]PR8Z>B?=/#E<;D -MV4"W$4/^UC*J;\TZ77XT`>3LUV*>YG.X?(U1(\RJ3#;WO";SO[8\@-NV4@,A -MNB=LS$T#_2][2MIJ+`]VMN_P8I%G.GNQS7+P!5^E8<'3FN)8J/[X`B+B7P5( -M<=FO'^1*^8B,G_":"T2)N8ME.7WZ0T6R,[P,@L6.`GEV!XE@64D7BK -MZ:$;P>I(I?YLXN3`?UK0`6&ST8B685JH3S^21!?Y8(1Y*91`MZEY!1GX?/," -M6]XIQ4$LKBH)9Y9D::$U27')@J2IN-]U=6+[]U[U^#2'BBMGQ=OCR3;;\>F= -MH87?>2$_6I8D+H&`"BN@=4!7@'3'KX[=^@3.+L@A\>]-:(-YV\4OT2=U#M1K -M1.S&$CB&EJFN.>7*&UNMQZYT=\CF)Y#ZI_XL2:[9<._AR2!)O@\;S78>`_QK -M_*3Z:#"B$I:W6A;H2::;9K//HVCN/H$=[W7]]??%JP&>TFY(`+T^F=!-7.9^ -M?(==07^Y8REU_FMP0(G!Q&T9?H)6=UV:G2GL$.J8![_&/Q7O[>HFK&]:WD09 -MK>K-8)K)0KU5-SKWSCMN`P&@^]JNA2"TQPY -MH,W>1MG469V(/!,I_)$2_5)+'QP[*C@?4-&"P8\_!V&*(--X";*;#)SA -M!($4QK&RPQ-;J:W-)`N_J^+/A_5H"@8J3*_O8^#6GHLU0P._YVG/YF=!/[;[7%D]41Y5.XZST/QL83P`M:@ -M<)WV==Q,)B'P:CZT(I).0H.71%!^X(?,5AXR(]TU>]8W5-O3#AH&9,::!LUW]>3KRC>&`S``09$1.\5$GJ("#.YU6<$3 -M0>(W4)Y$6MN-B[C&[&<*,(Y+KS?Z:M.615\;ONOBZ'O`PEPA2$I(8Q0'6Y+, -MTU'2F_\BT!TB&">8X"%\M2JNF6V=*@+/XRB,Y<+\'Z(@Q.:0\:S=`5LQA?;` -MAK"]DT];[6R^X.12V=9RM<7/'*J`B;?/:8>8XEX2`BX7=(HDO=]-%CTZ'Y$B -MT`#+5+=5Z'2R=!ES'4I&Q7+HDPK(;;C0/X3KZM&-HG)P-;V!X16?7K]UB!G- -MN$\4O&%39;2DN'5@]M%L_Q/_5,B81JE!VI/(UZ)4R>#W>Y5#6!9@Z)EZGLQRZ".PPZ"?;\A;?3>@6KI1?D;YSJEU;1I( -MQYD9H`^MEW,.<9NG;LUWLH@[/MP1">N>\S[15X27F]6]`3K1-*D.0!&JGD$M -M!3)_*IPB@;3YZUF"'?,X=16+UY_9`(WOR-5-HH:`A^1^OWW3_/`(QHCN+6\0 -M!5#UX-IYIZ_@D1/L5"%AGAIYIN1+_O@20C*]!_]*P3 -MS(49PTYZ+?-H>HYC(FUL.0_0*DZW";F!N$E\)(MTI8=+F"(WWD9!BINV3&Q9 -MZR8J=)ZHYZZ[H1&K'L+CT/\3FKR,8+N^@D.#OZSJ-[U\N&3; -MW!-)?P[?G\YB=3ZE_J8AC$*O`8S#YP;&#H]@_:?\@("K;PW/M62M-<69[&?4Q*5R -ML:)5[;NY7D5:%#BA_&,O:3;[&+JKGN4EAB/+\Z;"1Z -M()IZ?W438D:_/\;_O*?!+E>'^70S!.411_%H7E?K"-246@4J -MMK0OZM+!LFR%G#P,U%"<#4PSZ@S>N6$PR-0WQ5,.:1AF`+I#9^\".NZ/;BOV -M8H;*%@P9(2M'.]=5#^/]W0N\!^H#=G]T^=]'TPQ7P7.>)#DZ,Z(\;_,)H/C, -M2CY6>GP_A(AJA%[QK\ESIZOY@"9C1X/3LS<=4EW:V<\]SQ@]$M2HJ8"KM2"5 -MDO)A2F)-#*-PIK'7/WC$GA6._U,]W)E/@VL>C>83O=['VFEP4`^Q8#%#ZJ&4 -MB=J>UQJ%5/1D8J$9:_H]1ULIBK6J%E=B<:V0% -M?_>HEF01OCVDJ#W(,*APK!XQ'VFYH"#E0AEZ\#3K+%,DKK!C==^[5PMUE>'* -MY,1%*;$R6-Y#>P>S1S0._H@>]'ME5N48\B-7*6C0@):R47^H8?,D"9C1^38( -M_M<=PVKI/*;H,5W?"P&>J06TM$$:UE9F\+UN(MYKIJF9-8ZZ>U@<\U8^$&]5 -MLNL@\;#RM%.KHB2Q>KSW/YIX,S)3UT."R%@_XG4^LQ)&H!L&^JG58EFQR&Z' -M(_NLQ`!83-R7WK#Y?&<2*"]!:"RL)/9"CHV9-A0YX7`.^0\^AV&+HX!B-.4: -M(``^$CC2P<"N)M"ISGNG#["GPM$AK&*E7#6`PKB]NI_P7DN\WMF*`/N2[!.% -M.KQX7OEMF"V;E:WQ9(X(D]B?7SPTT=ISQ7CEYDF'A0\)R';^PFB:ZN=^'+=L -M7MZ&IJ=#(E),#ZYCSMF/HH9O<:@ZAXWX/I)&OX6%R0[``O/2^`ZAJA+QS-": -M9Z*T-AO\Q1D!#@E%6DP9,:QO[V?.+PH2!2IGU!2\H3(NB$OSR&D'^+B"W -M6O:BTZ@+WS(1>3YTWHB0"X3!;@.*B)X$F,@$(Y8"8KPH_?V=6"`@4:5!;;X5>-$ZP"RT>-E_YKZ.H^6UT05=`\G?28[B)2*ZTTNPY;QCRG%+'% -M&Y"T32<(WT%"`H\#=ITE"]9"L+M<&!A&$_61'F[%EY?M,B,F$K''\+K`Q,AL -M?;<'_"8GI:Z,-S2]0&=A<4*&X%^21#E[VS;>@A,3SB:QBIDODJ$@R#-:1`:( -MTE1=-,ZS/&>PJ0`4YH0=VGC%4D4=&=*:\NT0Q._&HLI,GMU^M<1W/0,S2J=U -M%TW#`+I++^P7;J0^:5W6L;WR_])>U']B]3WPP;1ZVBU!H10::E?^M2YRA#Y4 -M<`9$O8L?OZ>=0WH[C7Y?#RC"-XT\@OIE2L)-R+RH.!.T]":=BE;T&%%H[?_J18LGK/'F"NE::ZL>VS%E(F*"=2MK"[7^,R]I -MWA`KH]XI`<7\<=2M"W^SH2@/L(%;&O%Q/HY8!Q/J:5GYBZ)8E<>=F?<4-63J -MFPI&&XLB[6_S3(59C(AW?Y[A:!.7MQ./XO0U%G+R6*QC3SWUZ6==?4!*^_M- -M]:[OL+B^<>06?IZ@8A7>$"CQ+F`($9+2#KYNFTPJJ^74,CJF>X$/F-HD$+AW -MRP^Y5-O!%%POI'I+>W3HOE/,QFJ.W[7RQB9U3D'>0Y;OE5N=%+]$Q'"[8K5% -M6M02Z5SPZF05CK&B!^GJ5^(R#O$(6)O[_);"L+03G*T68!F).PJB8U%1J$AJ+U=K&77-.7^/3J6I(BFET2)W6)')Z$A4R!,"$IIR-5_6%%$B8# -MC4=Y?R2Q2^XDD`B&D?M`'!SW8]5J`B?^`BOD*O$='`6@AH!G.;('>E9$X5#_ -M_SXS4?U>TF:"]ZPW:%)GK9GEKZN1.;(<=()PU(=,*H5J2:Q:I"ZX_-[O'I6U -MH2US^(0\NI_B.U<2?G>C')QLIYFM>X.22YR.D_YZ?W!K8\9X9>(K$2,]\YA()M:\W%D=0R4Y,(24S*=(:FQ+]D-XLC!&O+17)V#EX -MI44#DAO28KR`-_G7"9K`V5ET,!HAL;"8A32Y6V;&52;MPR[_4@5O>-0H_JNB -MDM&YC$T.#\`_S9U:RS7)#]G%J$1@VRWIEPA+6+SCAG7.,G"6"-6_K6AYA!@#`[% -M[^X_&I_`79/>Q"KF@L^I5(XX8J-T_);%._<;J8%QI1;=ZKMA.'JCM5:-X/"& -M2@Y<+9Y$HV[2>F\4<U!!)4BE -MCR_*"XCH$9.>/40T,SIN=&7_D.X?B^/'0][JP)RQ&OK]F11O]UQ_U9]:\)$@ -MH%LZ3#THX0;?_LM0J>``[9$7D]A`KG*ORS1L/359:-7F,J\WLJEFV@:*7?UZA<)8[U2X*[ -M",=T"@5G4WO%.:S/)W3&$T(/YC#9U[%@C;86OY0DFQ4SSI=K#$HD1GKEIU45 -M>I44%!=0$WGK"@>=LJU@%<6O76V1NJ0))P`0G?T/Z>$)3]=2CO"*W.34_#-5Z7T`]_69N^(""YD_%^(W( -M&[*=V)RI0I(H-:/SX"FKG$Y**BUK.)03ATI\/[38"00D.HPX1',.5JK-T.V" -M[!HH_I>09,W(I^7XT2&6A3#V@);2WEL&2WQ.,Y!@K**U=.<:WN+-\R5SZZ7H -M.J#5VVME%U-96S:-="!FQ;L(6PY2\TQ-++E"FGH"5Q8X9MB5YY:4B4".QBYQ -MU<]!32VWOQ@R*'07S9AS3\@QQ]);[^(!-@Y/[)I/X>/7&X<%'A7N.OBL6STF\8\R>7?^SA@W\=(BK!+^SL>>QG][F_JDPLI5#/ -M*)U"&(ZI,K1BWL\;-*[F8D0LGN7>(LY[][1U=D/$8_?!:2<:.KT]M`)(O=$T -M]&T^J+%%:T6)\H&:GOSG>TG)*N&EI0_+[M6SA#2L#0MW0[4$3G6J$L.3X:+7 -M`$D4PY"ON09AFQL<9.HMC]2WHI&WSQ.!-#K3DNP"0 -MHGJ!7#!_]Y&WH3SK*XZR-S0I28510#JI99(98L#6(AY*^]ASDV3\G!9V@S(! -M6;5)R/R1>N8Q+UZR`H!J;($7'"9+M=(J_.'46=YM5^!?]$H"[*Y/!)FINFZ. -M9/-Z'NT1\@0=M9"B4";<;8^9?5N:X6`$OV@%_`PA%Y8]?KEU^ -M\[B`$&[8H%EGMQ,RY6)TWK"[KV$)KLYK^F3F/_5F"I\T_(G2+R:]N"8*ZD"^ -MV;A%)C(=S(OR>]7,T&2!066Z>GUN_YK8Z3Q$Y?AHCQ>%UDD)5!^VFZ=U^\J8 -M&S$[K4>$[#$4B,U]CUT2M?4@L5^/<$MJ&HMU.`\V%_*%BQ".K+N!(X]VS[51 -M`#5=-TI\-]R8V_@2)F_^?1.U]N?SM9G)Y?DBFL#NY2?T[8[1H#_[1G(ZI:?T -M5199AT$.J0!(J6Z!+#)FL1+:K3Z3%%K49O/T&V10GSQ9,7^K1136,@#SH^&# -M"J!4T2UTS+R3B)N?'[&%(_):--%,]6&Z2<,WLK@@A)XITN'**.,#AID&K_1_ -M_P]HGM#%"3M$;'M8"@T"H[DGAMP^])"[,#G#S5^&?XU;0H8L@[6T);:,PHA3 -MB@.O7/SIV:FOO^5QV$(!%3Z.]I0?'VD8TV/%1FCBF!=MA?G/:O))LHZ2?7PI -MC(F1G>3;/6H*&.!:K6FIFS["_($^B>/)@V2$D2.A,KEPN-+QF*JOE-SCDK3- -MR0>224E>F'SUIS)DR=[E317H"8HOP!"R%?1AE@.(`S^[BZJT0\)4M[-WG/=8 -MHU#G""J:>33P/*8US^]-CT.\L/Y]V'.7W>O-'G7ZSHV@]O[*DF\LF_U%42K> -M4Y&H0%>#=&7_=:ZP*A7)463,[!P+#.09XQ726/SF[9'572:0>3YMYZ%];0C4 -MNUV3WI`Z<:[@LAVV+FG'R;H:+4#@TF[%7C5H\:&P,@HMK>L0%"^E;_`J4O^= -M'NG:]SKCC,])0;(D\=%YN_7:_^M@M3F=!6[(P@L1<7')O*O7]QU/5T3,:'[, -M,#0?P?>:'#[X5K.3#*IE]^P[W]25GPP2.8[I!P.8Q"9*"\!Q90>\O5SP:MJ! -M]=-[*)3D"VB[?^S3W*'7[Y!L'77-($?:&;!Y?OVMAL5*/'KDD6&>T?]MB<52 -M""`@6766_S-S\ZMWM0N?Q)B'Y?4F3X&9!3#DIF^=K.(5,@)>B%A+W?L5BD&^ -M-FDW&E1P+XB`1Q^%[%:EO%J48&5ZX\'7=";`^A?#9G&.0C;(7Q=4=)49UR0K"*FJ[0O(_";U,@%@$#JNY4OTYEP@\Q&MTR1L9?( -MN,`P"-=KN%=9@)\[,D509*E_U@DF0*V6':7N$R.O26H/9+3+T6]HINW+1X7C -M".=3Q'K8YAQI@_.0]CYH7IO8I9>(=PWN;5[<)K[$LQULMBJ-*BPI286G=(L[ -M\J1_YI'F6N*WX_3V+MHA44$4AS;GO*%K:?.72?'68$_L19-CYF6`RVYO5J*; -MOXU9M()4F8K0U#^>.J=[=[3JT2F7(M(U;@SG6Y2QVTALZ)1M)`(&"10G!WH9 -MIWVI,EP/,G*%#ZKD+G,O"I3CV9@OGRH(:5?2\T`,1MW<&5FX24,G_=5-&C+) -M#(]Y+$)SI[6+VQI*AQ./GY\L7/&@8.?=@>EC::?8IO\5NH$`/G,U&F;;RYN2 -MG=]OGVWSFA<>7)=U):"-]3KL"#F@AE'/MAME#/>-!"E(+M)&7S;MX;LOZ?P& -MJ_X>LGF,?6WNZ-A2E)Y#/SM[S:8=\?4[LW5@34'-&DFQW.T1O019L&V2+!)? -M'_QNBN4N3Y&SJ'#1H.(S;\_"_8+Y=9EEO?3)(`]0<.HKT6U!N1LPO_]`20R^ -M%4#1"E<*HPO^D\VS`#W()HA]DXO-"*(O%66,S@?4,K44+)',16%*Q$G&*7(Y -M.^AY8A^/B-!`'+U"T>8G,V3WWP%2@F?L8:B2.#QWB#F>ICO7LNW?7Q=;GXA- -M='1?`T%+".?,,EJZ->!#43;)PVSJ!_7N*1*W\S`Z6"&YF -MXEIL'M0BW]][.7*=_1".[$;?OFAX$7H"3H" -M1>&/F$8#,"@$/M,YHU -M,5T(J!(ORA7X,K*28#K2O190J=X/+83IZ8Z9>:Q"(GZTND\J#U` -M?^BT`N?]O"11S*?P6*P[:O&+Y/X9UD(:=<0P705%B01;B&\;Y*8VS!?YYLE^ -M@`V-JF1KGQ'Y`P.OIPPC>UZ'TZ-HF@-%YAEEB&ZJS(RMZI_L31NOD:K,#Q!46#* -M0"]M3;(/6T%/8S&?'+GP@!9L7Z("8X7(=69E#,>7D%( -M&YP7GWC_H%3FP^5Z($,7Q`^R-.@Y_&"BOF43+TO%<'&*CSF7U]RK&PIXBGOP -MTJ%<4Q5%CO678YSH-A?E\[=N[)ZOZK9C0'1__GA01S@E">;.,2PR(-5^D+<3 -MC(RNI7AL<6Y9_8S56%]I49AIG#IM91KD-Q^P(D`4,8RX@:\&;+4L'``0I8J$ -M,NWV->8.'S^6FZ!N2P>P!!;2=^MX0]$Z7[UDZ9Q<;D-,WFH-0#N3FEKML>T& -M3.HX&)0?45]]R4&XE8M1,.K:I:#^TJKP03[[>DJ%$2T;/:?SC`:JT;ZQZE8] -ME2Y'W(43.>.8;!LOLNJ=-_J\_YJ9FG]H%[705H7?MJ8*D\V6CIS^SA#[W6JW -M^B==FZJ!U.T'?!S\%,D&>,4RRU=8:UGH87%@S9X!C`]5:3J$7%!IW.PR_PO' -M/+PWA;_!/JQ%V&G&EU",H(ZM/&P2I$%Z9]VAP7RA^;#)P+F,B28SU!BTTE3* -M&OG:*/11XF-0I.5>PUP@^559U(NY9$M+.4?<'6F]NW3T0EQ'-7K(8P`=TMFNRF-CIVQ!8[P>"PY-/:F9?^,U!+G=%4SW(M -M;WL>1]'"6$;J+*1=NC0MT*;SV/Y3)CU\S?0&K;_[?OK4_2UWC6.(BP60>MMZ -MM\8PV?\<&`1BU!,&9^RC!;(A2)"FQ:WXW^?-I@,ZC@@+ACFQGT:`W.EU`R@M -MQ@LTYN2A_Q4-0+:OEE*+^RC-C%W4HQ2_I^+*8[!M>(;\V>,DI>(AM`7)T-&XGN/D/G?)_)%^):'KOA` -MRTLB]@$4GU?:AMNRC220V(6K&&1K"W,_^1[W!6K,AN3*%38.G@/39)S?N;HD -M]XI.CW7G0UR"LIEHA-M:P3-B#PH<5)'+4[%8`\TG(.PS$^I'W%-##]AZ/4?:D7-CX%O3X&)J<^OE3'IS:2?4* -M/)!(9/]LN??79U)87F72=*7N+,I!.XR*YS'I"95I7EDCY":;+1\I5ARU]!HE -MD<#33@2[^G6`]W&,2:W-V+L;^?W7?S!HG51Y=X0$XPI -M,79@5L%C=8MRG'F#:D`MDP&KZ=&@O'OVH?]&`&!$WR2VJ*-P'I/$N!GA6U+& -M]!=\T$Y61=M3MUD-.-T^@5!YMR15$BLITBF6MW5\4RQ,^F:D6)';JUKO.4DV -MF&FK'<#&E>WD>?!>#;[`CGZ>7J9[G2!Q;QQU6JX1J=>-9I*(Z7?2V.2SZQX$ -M?OCHF.Z&-HU$*:JL>G$\C8.0+G]?A_)?GP;0KY?S!0JI*?][`Z/@NS6MY3RC -MNTF(7?V-B\16)8G+R)Q%.WHA*5\5SDX7`8=Z)8`PN*Y5JB,$BP_B"Q`(>)G4 -M;+KDL`7Z.AE9JRL#:IT;\+B'V!L=ZKX>AQND3M'J:!V__"2N%=]7(TX>,03U -M7??SN)P&$KA_B':^/Y??@W.P,8UD4,:!$ETA0S+QR;L60,'&G"J8^%@O)R@C -M379N:5'&`NDG5B'1>Z_V^3O^Z?;5AD_N7QU48B/-IHQ%0>I6&C_\Z7^(+>_' -MI\'3/B@[UR.;W,'\;)3PR^]SFMF!-47\.CM)'%"%!(3MJRMRKFM/41@Z -MR.6HK3N@8&9C&I]*0G"&[:]A;WZITP=@XIV]M1&.[%R/2F9!6D!O(^>`08W# -M#*A>XZ*S`_RO_E9&*;IJ6ED"&='+LB[W+[[9LA\#/_C3Z!T#8O2#PU/&VI>* -M\85Z@*O+)I5&HKL;_]&8?*5E'4-9H8#D_)O;[C06P):.]KS1>Y*=V.>3H0:' -M=M.>UP$+(JY0NVA]I!M'XS5X$J]AZ5'2>.OV)SY3-U1.7<.Y@/JC5$]\WS&I -MM31[*HAO]`(2M5:5_D!KX]S_)].OBV4/7=!<4U%#L7'?;22=+&"GP8O!NQU.^``>` -M)3L(X"&RR"YFO]*\_&*]U^^NM.W63F:P98>F/U6/$O%47CN3X?:%M@9QOSLQ._ -MC$&QWGW()+DJM)=#%/Y&6J4;2?`"HJ!7/01WJ=J[VK%?R][ZFM*KOMLR@N,`U&!H!TK>AS9A)#'+I>1%ECVNV -MRA=')L0@/AH^C-4?DKFN5A!\XCP-F)J/E2">Z\TX.L8]HH-/%PVCC,20P(1E -M+_=BU?!,`WYTFL].!(\P\L"H-:')MU>-5]+@3)]W#=%X&![!9V;,:3ETQ)+? -M*>%W9G`60#!@ZZI`8\_Z;[VS$_>3%P0:"-,CO47M0F4T\,TJV+F.DUKHBFRW] -MAM)WZ06\99T$D_D$>CJ4NVJK<#+X+$/>9/$WDF/3W+6\GK@/.PZZ`JV' -ML?Q7/E;W-<2"!)8@!#DBD^1J%J-@@/2;($G$_6].9!6K.DL=3:GMFNWI]Q"W2&@OYJ%(I$ -M\:)A@_B3T>U^)MD@MY"PV3/8`L>2#JLJ,R#T3V\%4:S'H6EQ,`_!IP<&0Z^7 -MJJV&&D<5=I9>OF'U0YTB1]*Q93*EJC[_7]\;(MX' -M41A()%T'N1$MBR;D"=8FS(DX4+W-Q>?T!X]KM./V59]'RSP+(@'-C-N):<.8 -MLVN72023VT@W/$W^@X.%K2Q2V8=_&ICVQS9\>1FW#-MAF"C30J(_99+B!+.: -M[6>2TIMUF1ZGEFSTZP$OIK\`C!SUP&J):HAI@*0B@G&4-&9(6K,>J7E:IT^'7]2:GQ[@- -MI3_7*C,^5>@@PBTW5N4"064.E:@P'*7KH.A+UQQC':O.-,-R4:GM)^KC#TZ! -MT_C&Q`N$N86S<9-WQ][J-M^=I7T+"'&GCD>0,KB._:N-!^>*$V1=QS'O@:C8 -M+\G3DA'8^KN_?G3A5Y$[3"7AAO,J:UUM(>@4$I!R\1%SEQ+ZVT1*#JB2_P=A -MQ^X<16]JTS.PNBM"H8(3>Y\IPBXXI38^I&Z<T_H'H.A3V;%2O -MGE(\MG&@C+X_.L\V`70OMXX>;0R4M.DWXTH_86BP9R\:`X\L/*WPR;I]P"53 -M*B.Z>..AJ;1AV9LJ8/V6'X61#3ZRG+NHS`N"JB%J7(_VB[A$7(/:VR&>\!M* -M[/"F$C0IS703TM@/P=6DF:J2[N&*/O-(@2BN`2I_!9WP6#D1BG+R;^9]-AA- -MQBVZ`M2QXI/7V,PLYFWC:V<<+%T$D.C^!%D+Z=5+JZ\1&8XVCY!`VO\"[TI" -M0QS27.%_9FGZ2&2EOK"NF:F'[`RA)) -M?YW2\<>!ZCC'-A"39]U$9`UUM4L.WFCW*\<\;XU8^C.:W_L]W@JF]%_7$4BY -M\Y"][)1P>0UA:@3$^Q8/L9.AC6@@PCMM;^Z:0ST/Q$HE0R+XV6GB\#M52'1T -MD\S0*[,)HD?MZRK@!H/^37`%"TX4Y+^7B#)32Z):8W7@)6,6R8:TT?41?6`U -M]?FV9,.R>A4U+AHLGUA7C`^>DY%!1479DM?\@\N=I>_=@<3_&R?1(.SU6`SMZ3?W -MLFG*YFT3,]9_HV^IOWVBN$CPU'3ZK;BO;[^+[\,_O1X`)S'0F_?W'G3H3K^* -M5)BKPVX!Z0'EWM4V#F^.&;BQ0N:?Z+1-*;MZ:*1CA!9%P8R%#2&Q"Q`X5K>7 -MD\@UR&\K]/>*4'L%N;K+DTMR93WL2DHB:8FJY-VHM")PZ[<6%5(JPC6>5G/W -M=^?\!]]*7FM%E1+;KZRAQ*1#Z'6%A8XRU`7+BZ8];O\7U9"2:*[OJ(-9GOP7 -M"IXI"U?-18LDHR54C\:[4EX\F,!TM0,DG@J1EAT1.YXF=,;,_6-7G$%0"&(` -MX!**LL]KC?++N*OJ)U%*IX`KJ(907PVC>_KB0^EPH>Q,!#TR9VV/3)-26O#M -MP,1;2@6>?"0PKS<&W^QR.L3+\8Q8LIPBLS$]!0SXHVD*7[YE(=/(#P!'OYO -MVN<\B!67APMBI,FKLOS%P_YZ-!NFLOQ$\4_:>)V@3HC>8[9Y.-"AC3J[KU$):K`PU" -M6:>VQD:^#J!7-7,AB7\\'E33R0.LAH.J/<<@/(`',8[8I4V?&XH,-LMRX^#0 -MA1I1K(,)-'9*H:6\\T5N*W=+QE491[NOW-Z9S]^2XTPNZKN1 -M>.$;&>25)FMI>>D5EJ7HNZA$7:U#KR_2F8^R(\1R#..K'^N\VN'^E<YX5>,#K3)S5#TQL>H'/CL.YF,A -MVY^<YO>`Y1_,34B7FDKHQ,W6_(W;M.)=ZI<3`9@SA'$HE.Y -M0/-BR7`QP/<.&/KSA<=(SO0E$+#5&)URQN2%?KOM7%O09U^=) -MF8,UR=-^E;!D)8J[E-`4FZP(\?W96?YF%W#;P.LU6N9N(*%/Z?CDPR(5P'Q% -MD89B+7,PNT<.P<11D/-UF5R.R<+=:7AE1<OFA_F(5W*Q4* -M1EWRBX<$``:*V",#H>:ZK?D,U?WK!@_=F_YYN,)Z-,[%=T4A-$;R$K;4EC3Y -MAC&_KZE#8O_6U6!I,G.C,E>D4'J^F9#4!TCQ7>=4ITQ%A)9$9GJ0W7^6&?U. -M-,H>ZJ\VWO36.53>N,/FF-\$:%!]G<\Y'("[,R*5W#W`:FFI^B(DK>MDG;]T -M[VEZD@WZWHIZ'OYV@]JP"9<.7*;W* -M9,#*M&[=BXFI9Q"8XW``MZ.M/$LH\A=>9BY*UB0!LO&*%#N/OL_5@(X/E:-L -MP.P;\`FI$A>T*-$41"K]>3BBVOPB&+YM59:@3X_YN/4EOQ!A5%.ZYC`][&N8 -MA-LW19H*P!5J^(7+U9&RU$]2;N)_OM@)IINUBI' -M-VE=>'T=Q'">7?_H5VN[#(3])WOQR$6T(0!7VHO5,L=(]TFA4%G+_U0GK)9= -M=R!.[9<:18X->$;/+SH#Z!K/[_=*D:C2MYV@&^OTD:4VBR0G/HI(4'H6.*92 -M5(:WX3:FW*'$08E;5?/CQ91_N^P#+W`UYWPS@^&$JN#NBIJY;4NQ^[QJ:AJA -MZCMX@&2F@/0"\KM;4U02-/*1OLF!<`63_J:_(L^A%=C1'W=!>.=?\'P)+W80=132^=M@&@*CLGA:L\%]8J[JJ`4&5(=*P8+*DF;B]G>*_V1C(_I95T->T2P4'B(?T -MU65X*ML$[+NN0>*8/@HAG?JZJ:*Z8H^2OH![[9)+5YD9'+1*]+*1=)%8?==< -MKM^]5_4P-*IB&D9.]:L=:/L3A8T\35:]`Q-I"GOO`;_M]@,1H$$+692KWAHZ -MSLR=YM*AG^/9.\.)O0EI2*7"#0ROU7\5:5Q"*)?<36S`%X-`&D%KGM+GC&H( -M'J"M5B)'O&GBQ&C0LKZK,LZ)CEZO+3R;L,0+>HWTL9P>\"_MR^5EL>U7HMS? -MB%7;T`$?X_M>R*BT8KDNWSSF4&@AWX."BN6A=@C1(`,R"?W;4/64F&><)/23 -M6%H6\]M,)R/TTUYM=_JI_=PJ::VT7'N`>>\4QU#@:9&FSB6^R -MO#V?B>U\DG0"J]$;H7\2T$);A64*]6J^KN&CK!81WF)C/O+9M7U]!9\^!57> -M5-3ER"<)""QYV`!&::8>OP<-T`A,IU#)$3QOS"B*:?XWG.R;'UDBR)75U_@A -M-5IQP3_"=C<#=Y9*1X\@=XE`2.$.N!FFJE<)J&\_,:TX=%.7 -M8$5LY1-K`6"T8-'U!;HC*J;>F"8@M$[[X2Z`-J,^+C^]['1YX!7E'H]T__4D -MXK2J(6IIN(67XSJG_[[T*>^W1X13RFH7^9ACK3[/D -MF*LK2Z(;CQFZID2,:71T^6@9:@>Z._%')-KC@R")Y6RZ$^<#U2&,#KJ2682/ -M:/9W(E`)@S-T+,.]FZDK2HGU$1K[CO_RXX.-T$UFS1?%FP/OH*9K4:`+O?&! -M=*MYKGEHE800U/X=V$5A,W\U\*S4'[C<87X:Q68UJ@.4#M!;[9"[/@\PG&G5 -M?"2K'K:@?SV))AO;**6$ABR\"V[^*-%J<"C4:(%Z/&2ESBX6,(2+(G4.!L+P -MN!E"I/^5RLJC2\]`O+3BC%68$M>K0&##=8D228%'"ZG@?3B2V(E2CLT^+2YY -M=P6)COTP*&$N[WKK^ZEZ&DEJV/^MQ0B;[-I/5Z9&)ZO=&LXB\-A[&V;'RB!P@+:Q;CQ`I\FL!5*=I'0N:["DY2#W/V.+Z:WEOE[?PB74(:0EF>:7UT$H;*;IQ9HN+IC:ZOW,*K/6 -M)CH[0OL+S5[@LH*U,T0=YM%2&<6KD:'ZBT0?R(*HEKNW4EY$S1)5)0;JI_1\ -MRO*($;C9IS>>B.'P'/7650.H,=.@49-A@LXSSH$4VR4 -M'B2^MO5'JC-)SKD$!W6Z?%S/OY/Z">>$!A)!W;K?O'-3C>1A%\5DQ!;5E#E#Z)4?10MM*&/I -M[<>WC`).4>/B-I?_/NH4YN^*Z:F?(#(N.[ZTY.D-DXL/= -M]^&<)%DK>O!%Q+T2)/,>3JE(-$CBT-Z(*%EK.9*H]`IJ4LCB,)?O-XCM*)@N -M:$?A2(,!D)U#NU4YK$G<\H^>LZ&7:Y*`N7!(?JV.H&MD.VX2E0QO>8;W9/\/ -MH4*IHS]VJJ3_X25$KEK\]&_B0_?G:S#6?WN83Y=:\G<5$KLEEGYY$\)I,WFL -MQ3WK:)ZF2'/<;([!\+A'A%'QW=+1,(Y>/[E(<(';5?2W+Z'&"GNLVF%(X[-- -MIG/L/D?&`]S3(`F7M?B[E[/,KV,YCF5+0![ST)?&;FW93!N/@<%.7\Z7D"Z5 -MU?*TS&G<2S??[\'[^'?9J'M;P>40".-!%)!@IJT^PHWPHXHVNU\?5,#]?4HH -M#K)@.X?)%]E6R_GY8(%9HM!QOMI7ZA>(GDD!NY-?7_.@IEL.$AFGN"-MMO%G -M2;1YV.7I6RF83-'J,:\Q5]74KZ2RT?V%%ND^NU-<.U5`CXFZ@5/Z?@+JG(R] -M@GQ]?0H3>.WT3+.O@4#8^,+QRJI5','KHK.X?B^5.[L+R2"36ED^HP0V!V#A -M869D8Y^.+:W)QQZL0>U[Q^6%_$W"2.CB9_6!-E$(5,%A0DVEM+88S$+X^2^@ -M]1`UE6&@/EOM&0J3NRHO9.^B95CRUYV(H9H#^]@S -M;#.S<[EL$D-OIH6F'-5J;%H;[X/2@)]#L)JC:"`87[<^XF09NJ"ITE"9\,(U -M;8NRLQQDOPOX($_V.53]P0ADZ'L0<"M6P#V\P8'[SM5-D6:^`CI+[(',C.#4 -M2I[M?D..J>.6;!2%\,/E6O1!._[7((,*SS3[T^G]W=:*W^5.(O87HAN8 -M[P+;_K"%X,`E1R?P7S>S8C^(,U=20>S>,G&=;->*N[XZ5<#2';AW@ZST[H@3 -MQR=FU89-+GX*X9GT?@P;EWZKF8/?3_O-QX!U;2>A[O<5&_85MXB'R6L4MHNU -M2X;0#7>,H[]J"UHT#C\OI`EG\%1W.-W@_9@\YCC\<Q -MY.E2HE"FL5ZJIRU&E:#!^A:CN&X^T\JE`L&6_.\LBK$`$T'?)WV-G[&`@+O- -M"H7@(=J>-U@'A=KY3CW`J?R%T2$(+/BA+_6]2)`,K?(CZ5'D*YB93V#L.W7)M95ED4ZK?)2910_+Z=(V,4LLZU>.4O2;DA -M+)44L;HCV*P9B).B&=!8T1?!U3TVBHH2U4"YX,M9=D?[%#!6WX'\<5@<9*M* -M%C"*7\1!=;*C(>X`YIM]6F-@6@5?5=@TF="FS[J]T\`U;FW$QZ)^,YNE_0D\ -M30?WIV3?Y-J?M^53@-G%U#[V;U+IH.H4>'IEA4Y0V\@$@?AZ -M/(2/5^FC(,4:BX!R$#NBJKE]P&6B&Z:O,N4%<\XGQS6B=ZYZ9_VUG58S,WI< -MW*;9^%-5P;5B`9%^X;=:"V[*"3-"+RD,,LNY"-H=KH^94%LJ=@`7>)MOWJ,N -M56J5B,2[&R?"6;L":09U14DKNV,R7*OLSK4#3]SJUFF[`#]>8 -M8BEM7F,2<)G?3QAX_U#=,;Q#F`&.&?L#P0`UD'EY02DCFXTWM71SZ@BQ8&XP -M=?>R%RD$`^?2M\^:\"7)7!63PC&(=B!I2XF%ICV[T)_*D(]IXXUY:I4_'@NQ -M@1/1V;@KI[=QS[&]PNH_^<%L52\R<7XIASA=CUG_OA=3;9WVY1B/LW7X'F:X -M)DT6I_*>37(.K(2MYDWFJ0VSG>I/(R>*C/80RDH2A(6T@Z:.#8NJC0<`SC+\6IIKMCB%83RW79 -MRC()2;XD*K)9^<\>YXX'MX<85X8CN;:+'\(,"X@Q&85@(ZF#T:MH^!L2[-8.++SUF(/XZZ"BQ$KLVNLJ -M)8,DD6"GI]NV=))<5/+\0EM>(N#OYM:F/3F/]*>2`>X6C6QG74NL`;7F+@TF -MO$J?"X(%$#PIQ#8=HOSK(U(?C7I$`<%VM[A&4K\V[]FOGUM;5I#A0:9"NMT5 -M/^CLGGOGF"R&A+Y*CC.=SMYLG.M&)W\/K,,"R4B2B]25YUYO'*T)::,K.I;. -MRLCY&Q!P,Z2!;1?:V'8"N^QHEE]+E#/"".4!_&'X -MHZ`?5(10\8N]$`NQT55#2%/_MACPQD_*7U30;(,?2=B( -MBOA4G?%I'-W'"8P,2(3U8@,63(@WT*%Q3D=6L>PRAP_.,GP=R_5DP7%/S.T6 -M#@ETVF1.6I4JL9`P6410YHH]X4'DI0:AA;Y]K1%/=-Z=$VF!B00`P]-AP798 -M*.M2/@Q";?JP>;%H#H`'ON[ZORZ10X(=3;4\5>]%'V.GXS,YQY-/V#(MP=?V?.V>6IPU]%+- -M^[&=N`>KN:2'&X<@B4'67V:H'SD#'=1E7"\FZVOY=6"N:BEZR?Q9<,V2SF!: -M<1O)EILE3):[7FH-.FU@<>-0*WK&&\SZA;*`@E6C'Z\+9_T3A#>.FFJY$K#; -M,"/R`,'+S5*#<5TVN5>7MD0")(;?4;N_)@YP]/)8R-Y^S^KT(NC2L=3.E7_X(T`@<6=E0!BJQ3#B8B+@5:DM -MN::R/!WNB0VWIO@Z=SH';(^YI^WAG&Y.&:LJ=`V;UX"1&C.V/& -M(9N;U[YC/&-/E8PQJT?;],^);H]2*A"]GAY^:^?/P+V6\2+7[UY7STZ_J0ZU -M/^%/A;GF?\[TE>31(A8;6BKK>K+\B.:N#NC.:ADUX)G26[+A0YKNVQS%+ -M6?UH*P3F/6-NTV>9>,(LCU>@S-[:_?>RVVM\)KK#ZOB9D,,*;UUS!P<_0$N@ -M:*N:%^$XZ/5K;O]"M_!'-F`8'*57CLF*W@K(FJ0X(P@%^@/`QX@V*3)[45J` -M75<7[*$PD-OEOZA:*;IKT[Q>%GZVDH>'_+@G(6F=XT86FO;JSN*QJ^[8+H=2 -M:+.@/ZVB;@4"Z$5L<7C^S9THZBX -M^(2C,N8\3Y/H]$E'+QITGF=!VD3ML2V^)%Y8B<+-UVS_D#*B<@WV57P"7XJX -MQMU!!*K*:DVU)^-*:#QA:N1\<3/I[[XIV=- -M4>7O69XC$FAG=]BU42R!3$'GTM4-3OP:%X_$PO`DS]A'#@"1-3J1:=Q9VQ-X -M$'+<=%E5U>/O"EIQ>2Z<.@4&>]5GMBPME2/([^]?U_;?<'ONU.U`#R*T6OT0 -M=\1[G>!`7^,P2<::$SB!8=9_2R7RLS`GQ"&)W>L?\I1O%O7PBM5-2K,`/]<^`(UF3PRT.^QA^&YP0 -M_JV22O&!(LK0$?-Q22MU\@D0DZ@>Q]RYXT#;^W?=AF!!NR=R5WKOZJ#59CU2 -M'*KX6V>N!$"Y*_Z;+N,$11"6$YWJJ.SL&9]1BEJ8RTFJE,K,^(T#/1J9*!;_ -M3P>TA+5C]"=0'%I&-./0P_I?WQ_!Z;Z(,[.UW$PI].N_-VX^&\\00VH'I4/%2(?>2)L?(4P*>@5RTTQ< -M+RBQ!FSZ)=]#Y?6:W)ZML"&ZCG+9_;]_>-8AEP;K8XL")(<_7!=?LN'9AR[( -M;,1N\AYE1MC+[4Y\>$=`YN@OF`U!6'`,_M9-6:+A;T-5C[5CXB-M?S=-BO4-\=? -M5MR,W[;8MRHR,,"GCW4IC!=4,)CCJRS7$]MF&>4T92UPBD#C6WK<$S#S*KE? -MR3C[9XPA.\W5)ZP=?U[M.[)2(VOMNDQ[LN6V -MGDTIKTI;RPMAXW:N,3HA<&;"CG^%[TQ!`\RINTIM7R/D6[W[]YL--:ZO-6]? -M!:-%4,:\\^59E7LU$4^+T>W_)?"M0%#BJ5/DC?H%6Q+B)%'_I\MV)+2B%8"! -M)&$>#'NAI3!M)PH.LU?QA/'8\&[7.>R\/J"`-BE>4+R&16>S.1*OR0&:LO@K -M-@4924$]_/W@V`W),G-Q+:(I]Z(\AR]9,VVX\.?^&&:=E'=X79YJ<#S3&Z9F -MB1!%9:P&V*]OOH7#JW8])&NBK*B)H(Y!S&H^"4"Y.FM];*=3;[J:J(O5'^^P -M$M(H)@?4N(?".*64@;#E@=?N0]N^PAW-K00O(OF_L_`6OH`?(KUACDG4P=_X -MZP>8?#Z.TC9R.G7-ZFGT90>4UJD4OS(F)5TC21F1TCN\HQ0-R"%(/E!JCLKC88-81&A&18J@)3:0O1[,5JKE6P$=WMJ$*YR^4=@L(!)LUJ\U:":_T>[]21 -M]H47^:Y;R&9(<^V&P0_)HG$OA;5B]#20X\_99'5"#8"A7#\\:;C&@&'BYZR< -MC30@S(TD%($'`/+(CJ^>2A$]>M%N.Z^%4CR+1/Q"?0`J81) -MS%RN>6)DKK^56.(4.LU+4Y]B/J_CQ0W\_9+V]JY=K>$NJ+HHZX\H1$M`_R<"T4@:R=FB"WW,EK_L26+1_N/X$1CJ*D>]CU!8[X[^'I19 -MLYY#H0M2H"$;J$@7GWBM_99Q<'ZR24FWE0P!)SHAX7S>6"X-`Y:ZBE^C[?K4 -M>%"S0EV]24?A?JO;A45^].#RYVV&AD_&DH.&4))Q^O>ERHGO(SH:[$(I,D9I -M46?_H+^Y-&JEIO$L:3#.Q^S*K*HC6PY98026$7CSZEO56(0^8YYIKL\WEYY- -M`H!S/W0M]_M/U@J\CE'/&$I/RGJ$MV,1X-IC0:'9_\G>H_J,-V%0($&94I,' -M/30Q=]$.M"/T98R[GGL:9U-1MY[@S7/'>9-5S=B\BZ0'(!\<2-Y^%DE;[<%Z -M4K*L3AD+\'+%]>?6/24Y_-[=IN&[_JLDD=9?N/[WU`#K`J'C3+V,<%OT;B:G -M;NB<+B.VMNL$A"#B>!P!I$06$R2*'K362Q':"?7G;NJQL!`8)%L%=4*[7SA]9,-@&C7S(?CI[7'B,8,9/S9AKC=>B!"=!_'?!F5SD`R`BZ.,XVC,\[)9OL&LXQ15:8@JV;)/)U_GA103L+ -M3QJOM"8GT5URW--"D_XNH')?U8C;W7[62-EKBY29BGR1#0"UBY8!6)1*#B1N -MPQBV'3J3Q55,<^+-6U^V/H1,='E*CW&5-0SO20RTFGKRXFX9O%Y\FM=+K[K0`P'36;/1[LS -M[NHM4Z='WCJ0C:L8?L1@I6?O>P;+4[7^S2EX+LK5B3-]VGW4?/H2'MWQ#(LX -MMOOHU1N!=U8X1L#6&+%PN -M,#5%0>X_#T'-S3*>+7N?MB(!;D-WL?BG:ZU0Z^I_0L!I[QT_0#[4%&V!X[H" -MS5J`^D<$Y"&,73Y+4F8C@T*QD/^-+_3FW"*@ZC8C!]@.'P[C,NDZ7(""8D+' -MR,0Z/.J:TZ>F>7B&I?GTI/*%MY7D+6S6K]+1!X7-R(7LIW%$ZW>]#-Y/%HI1 -M')%7!(/JD91+LOZ/I/9SOA.QSQ>*\S9D>=H-5AK]+0C6T`5:2>B:TR/\K*)> -M'F.]Y5+DKPTB/#ZO>G.:!\CX1.+N-?I_X=!%8K,V,3]*8AR"-DGY4UW$;;*& -M[/=,R;G>GR6*3,P(30AJ%DYYBI_W?^`"%T5A1511T]0R%N4_B?+;H8FN -M6S(,1J'F\A^0-E^CJ8OU/K^M"25?.9;G4X?>!-V#<5[$1Z\$*'O=HJ?D[ -MA"5EL:/`U`(PE9#$,"3^8`T@I^KG:#^&/JVE=B83%Q7(42@'"!E.#BT[7_19 -M!V'T1E^02A!*+2GFH'`:ZWAA4][8LBL8::[&&VZ$VJJ@KV6DUM77F\I$UU8^>/5Y(6MG7@;ZZ0_XP2I;^Z(P -M2;A:,,-U'`?9I4%GR)*!09S6;O2JJFA=PYBB>*&/\@E".6VH^)"D`C]&:$>< -MMLN_TZV1FLT0SJNG%X87O-B$'8G$=5\HT[C4*JN`4?GXUQ'[MIR.5L(+;3]% -MVGFG"]L!*(*IL"-1C)&$5T5/8\H[$WMJ@(V6/KM,;&TW$W[]518!2 -M1R)(*R&J']J-]DW0WRJK6Z"!V;CEC^5`SZD,:-3&[B1H;Z-!)"S -M=Y845?UF`]#70T\`6K6O(E<+;]:.;H!:`S]7T/\)$HC28+_>J1 -MJ2I[]ZLQ$KP`GCO0R/(\9E8_/_%ST\EF14E6W'=Q;GT)&3J7+T^1\1N.OA[> -M3F/8*5&T;%Y&^@?(FUNU%!/-X7(W#I!1,:+US"?HZ-+KH8&(.,P*JFY^>>3` -M7!FR9\*0D0CYJL&A3>G#X!&6&>I14A$]Q4WEQ<'@49[D.K(/=&:0>6EKYXY^ -M]?-YWSG\DH+0WIDL5B!3>?M+LN8&).DX`X'R$"CUQ2"V+F*=#LH2X,Q!MR+^ -MIU\@=VVES_B^,`*VS`="YOBQ4+Y2P-DF54[2Z8<(=HXZ^Y"):NI1]W8_8+!7 -MWZ5?S'T#)X0"_YV$H8%,SS\X(ORY(].1Z\IN,Y(<;U+O).P*SY?7)MB'%\_/ -M*HY;TE)(,.L^?(U)P17C@/VMX'V&E%9"4HWTY6PO>+@6P?E9TBVXWHU>5(O7 -MAH"W!R#Z?4GP\":UJFF-R'/.]K8\9QIC0@4;_JA0!ZJ>]Z_5MF_V=U5HG^<5BN96R0[>;7Z<*[:?8)$&(T$RSI<2PR$NGX -M@WWKUO:(I1@.?LW@18130693]1Q]K5$?@6706<2AV52Q##_+1X<,<8P80;"+ -M^E-=;T_LM?U# -M8200,/6<")HO\X00.BN-\=^V\9$4NYI*^!F)RIPOYP]N6>,/ -M9V -MRD"P_\WF#Q9>WW[K/\6RZR\S'&1RO+8L52XM^:1W;%O?/:$-#("/'='"B5M; -M0$IS`^R>$^A9KAA)7\?0Q.Q>V_'JJY0N.:/"U4'V;_7152[U1$2^T\VAWF7H -M<*M&J]$3,WJE%S-K.NN5#=@HTT?V-X]J/C=/;TE$;"+_D!])`Y5XZ$Q'8'>J -M)S\F(77SY[+P:?EX(#GWF[*QVA.E[R]^&15%IC0M1ZTWDC[\F2H!:4X')I6. -MVBDK:ZTD"#AHYGI9LO,\TK*J[U\W -M9DKQ"6VD>=W1R]8/)4E1[W1?#PFC5/N_F1(W..B9O-N'4%E5=K_/#:-(_][0 -M6J&;+PW`UH4Y")!YL?B0)#DX.CKM3^E15%-M- -MM0A,7X5L[]?S%DQ*1WS#VA^*N&.O`V-">,\S../,5)*#D>,N\[5:0HSP9DF2K;Q]6*6 -MHLHETHV8OU3(8F.C\NRK.N'E3^%2;%L&M@X2.I14QS5.2('0@DQ]R(K$! -M#LQ\!O4ZNLJ3C@G]R3!Y9Q3'!HY=GU,+]:EK5+=Z`S -M;CU9S%D\Q-LS@+W7&3?Z+KU'!IOG!*OS`_\KC$JPO7JI&N_Z_5#'M'6`S9$D> -M.G#QV9B2F(131/8G.-N$I`;6Z::F%IL&TIJ!M%,LM("RL#_@P3'MQF`.:5K(=2!8!,:&]ODT7M_16DZQ0?C9U]]9TL3YVZ=.R(PB`TVA1Y -M>FAV"=CL'2NX)>#3SOS"!0STW4JDJ0W$`:-0Y3CX/:[`0-[" -M(C!M?OR<8LP#U7I0R3XB'?_SI6(GJGNN6U%'H\@^,]-;:5E#",O1GPT0$T77 -M"9*!7R#U$S_=P/U$/^WL&/9SXN8*/<_(F4SF!!.F!C,#_H.--GN]RN37'!W@ -M_WO2KQ"^Z^8[@-F7A2:+700AP1#7VBT=NEN<^5[%'_^`_7#\#'7*AR,2).?RH`\E(PMU1/2%3_T$K0KA;TZ`(4".J1_ZZ:7^(Q6XS0/&D4 -M`;;BSTTDP@R<[I<%:/.1W6]G]GM9%43E"1$-62L7(`>)*/_RA+:XAT#8U0VT -M$"!=!X`OT"YET5=I5<'8\1:&D(/9+WK^(Q)NTHFSAG.+_,>B_8)_5U]"TK^S -M)V0@K@N;&^.\GV05G.(-TM45MMBPEW:,/ -MF*$&R^U$;KXT"IU:^FMI]AI!I6,N+'7SV/:/\;6.G)FGI(2X&^8#WCR,B$2\ -MA>EU#C^E_1U@-.MS]SS/^.JN?#G7()JTW>^9DW6U&[XO5`,SUC_A:^8H>OIUE)NY#ZB= -MEZJ83MS+3X<6+4\^T,K#ZQ&D7".DJ1&ARUIEE7+062P0^J/IES5?[;%&$0%> -MUYHN;(=BUFK,DS,2J<&`[)%3;LUL,\!3L,27_KQY;]PLY\.+V4?'`VP.P$E/ -M_E/\A0F1NC-#ZM,084#Y%26H^'*R^T]6-.5A/:CQC8["[GHD(TW -MY#JAQF\FPXIFBY,.>7Y!#,5NL>_&VQZM/="H&&-,@V.Q\EMZ;\R-%(-U\C@:ZB*@]F%6*[3";(4QQ+5!EB&2Z),$+H9]'G:V0O6CVD#VR10UW_J -MV^7!N$Q*"@S_`F5Q-JX8B\\R^1IIUMC<]_?(0]MV26*%"OLYYK9B8',&AUA`DDD2I0%N53YZ_(/8R:'M+W -MO)'E_\Q*H4_KNE"!VG$2.A>H_'BZ"+?W"14.+VD*KA.%FRHBQDW9%`MR"9X: -MMD/52QC^XN]+S,_%&R*<,50@G<'E*%-`2NRB;3[&2HF2$QV^5W9,,D-0''RX -M.1%&!%/XFF%;B?W5%KY<5`F*D85G]D(916(5:A'JO59]4UA,M-1PL@V+#[L; -M999@53!0W>.K\)6^ZE`E)9'[^>QIT\,2\E%LX%$LXR`B]'AI72U"8%9 -M,1ZJ@M9LNS(*Q?,2W=\TE:@_0SC)T,Z'`N'O4`9/T33Z<-2M;`1"R^C<"U+V -MP8WI%A?TX1EF_2PINZ2Z044,*D26PH0UGMMYN`VT -M8#P?\[.0;W+X(*1/FQ'^^8-FX0TRD>-SH'G$U-;3BW4-`"!\E-G@'3"KY;9* -M,TNTO$\WWFR8TPZ([F92@"&J/YB1BG=J0>NM__U(V-?9@,#-"F$4!"D$58BS -M$4G-9((./^Q&?AH_<.^S3@#'Q(C]B4;DXFJ&?U81`.#7C;!?2:9'O]OXI2"8 -M2^OUK8<[ZHK$UNBH1A?6''63##Q0YMR,94LE5D)L2Z=>-XPM()CK75`U].:< -M/_VL65O62!W*Z\.-H3&?B[?0X(Y5-;]^P>IW+,=STE-/Y?'I>U&8%GY7*8F/ -M/T&(;YAEOPJI_`CD'>_60PM$BP5942_X9P26_HGNMQA$6\'-1>71@K( -M$EG6%6A2DMR)'@0R;3J_*-X+`L1RC0<`,83U1.HWH;7_BB";G49-(8Z+(2M% -M`LS(,Y&*9"U5"2\^P<=;S>G+8$'YD_;Y)83HBHGRYL`.T%2KZZ,61J9T2O^< -M+\+HC"7`%PT#@>M6,$799?ZKE7>TZA5`G`,=**J586I/N4TQ.895$)1N28V8+@ -M6U\Y5_/[ZY5G>>EPG>QJEA3.>B;.(^YU6QF_ESI6O-X -M4'O$O'"9S+2_5)@3`9;[E?_AMNV+(SU_4KYX-GU.:95CB_!DN-TTPI??#J-B -M9^G5$2X7J$+<7IITB#*_C>.*:H/B,&%\%V=Y?('E>X61J[6M -M3/51"63[_/S"32^Z#3TUV7FGUX4]L$RPCW37C7!_*7+=?_0[.QC7H_L$.*:U -MHA0]``&:OBTD>+AHY4JIF+4FMSV=XNJ&&RR6M2(8R6AB,)_8NV57L,#]5F2Z -M&?(SC%?W@,37UWJTSH8NGTK<'):<*W*=;OK/FP7&$:.2<:WF)(!>Q19I,!_W#WH`Q#R.VCNNE'C)EZ+]\G*6RH'MZ$B9_ -M?A1'Z-)>QB'!1@_?;IP=RJV_M3U*AS%T9M -M:0N5#R1)F:O0\Q_Q!G[(YIYI,`R]0L4BL=O>3<9-O(YFMKW<75$$Q%[D'2@] -M89.W*?8:%I'#-F]/UBE[6XG<=0[7YZ9!FA'4DJ81F`7^=9]:9D/`9[-EBR4) -M"[]_#H;D`J9QM]WX.S*?#X@?$,P-.`(MKR]5+'*EC!H`HD]XNE12SB?.9 -MT;_V"+KZV@K^A*S^ZE)\CQ;P###&>.81;(^F/2=GT_O9(M2-.HS]&*]$:FP] -M4V9%,Z!Y`P%+W4_Y"M6Q;@U=1,$<8LM[NR]L8\R0<<_,NTC@>L^N3ZE('G*\ -MM)%]!;':JNA+(S"P;\A5O,P_1'TA]NK3SH($9[1X7?+%O;%33C`A`L)^.$_0 -MK6FXZA05B<6-)=S_REYFNBQ#U1R8N4?>8<=<-([EU`MZ%+4E@[Q-G-H0:R$4 -M8%@N*Y'*F@@WB/J*@'WY"UL8!Z#Q*K9?O-K^3CK9JHP0PR)Q*JP<>,@"B6(6 -MGM;?ZU:Y0DWSRS/`.)[EN'-P0R+=UQG:!ZS=COY@TEQA@XF/DS8S;G"]H?[# -M-3:3KE1)*[_>YI\"+*&DPMNC%M3WI@*/*A"J'WDQYV-N]PRBH&+U;<[;.'[^OT!@],)H_9)H&3:K5!KY&CC-=:.".]NU7 -M7D.R[KC4%\%X:9>FX:1D=V+WF3#^_%Q4'J/Y\!31'+KC4G&'W62]N_"U5_\0 -M%Y32R/6PU?0]1]$/^ -M!PTJ,XZP@\$[(7/8#A4GN%*N+K>'*VMJTX,#K-0(X]'Q\_4!^[U?Z_4[!!K?$&^,]Q49\WX&,A!4%:>O -M$S[7:KUH'Q#XWJ;]GA/Y1HR;]N`T#D_@1Z;2N7D6:K[R&/]D""HH%'_X=A`J -M*9)Z8,=`IAGR`P3=R!HYBOVDP>9*U$@79'C185C*LBMJ\JEJC5NBDJ1($]18SX -M(BG=5DA^U=9:R/O@X)[X7O>4%==3_YP4+7#?G!!TT7T[3H=BR3M05#?<9TCD -M0GUM+6IW+.\CZJ/LMBP-GCG$C?-2<-(?BV_]_E6&B[I4STA/ZBE,Q(!^S%ZK_Q2+P(T&DB -M(0=E.A!MTK\%%+'$MF81WL@N*C89\8WGEBE^D;HS-6%:N:RC,62/G%4>+99F -MZS[VG.L$PX<0^9\V))0X=!RF=XYV(6(:"IM"JYWR")3EM%7Z"]@--7D]R[/: -MA"2\-M#E_+/9+V"8`P4-T6<*S.RD3:%O^' -MD9&*17OESOJKWBK4'TN_GD1FF^(FY;T8Y$\FF"^=K+/L7$\[M_62-HK^!$AA -M50/SB+1FX;NX=0O5V1.8>`?G!-M!YB/'*TLX-+_(&X27(A'5U9G"E-^L@*C_ -MR+;+R2H"2LNJX.I0VCY%0&&)H57.GZ7O8Q7,_]A?6BW<)@D&98% -MLE;<(_+\#+P`73)'M!28P/G"S>87DL0ZNRAO>HJ$9QS-BG8RE`GY*%#"9\]5 -MK,MR1C/)_0:/[EZY7.)T/9Z2S`B%@2/%Z^M!;-F"%>CB#^C=TCNH+G="VAZ1 -M#5?KG0+\DV@W_8&\>S2JM)]RUGHKJ-6J!AA4T@K>&7=[5B_A1J3;=10#31K9] -M@G`PM=2=<@'BJU$)GY)F%O%OX,5E1?CREG;A?N.^=%Y,Q_HF".WHVZGA<%IK -MFR@SR%[3"#`P?;D^TANW;O*_,<#M[;VD>C>%+CA^B+?9.A/EB'I?WOC`=LM*&Z-/Z<;<'2I.*T_!N8' -MFKPA%-P>>%#RDQT&.Y('=A6#(]RUX2_0IVG"W.1#Z-L$`5\=L=S->1;0`8(1 -M2F6\EO&H@N!%5VKW*7\*\L^M;E`#JRP8PG(OG&)8X>F1VS,K9D"Z-FTQ5@$1 -M1J%*"_8LW-8Z4O0"\OE%J%>?V@X;1)TU'3,IS?@*>-8T0/N -M_]O,M!\Z,B3FILT23XTDBN,2809NO^LMT")]0][^-&BP2[8?T;TL:,N@TW%8 -M/.E@5K>W)\E,/=Q5`W`_.>#MF\/YYR@]<;!7,7V'00HZ-^>?6U0]BRO]*!O` -M1Z<#Q4V234LH&>:P1(-7:FA<5FZ1C9!C,A^0;^YF>DO<90\T)#BI%_#::EF- -MMC(52\:L<'TA@X7P4/#N>&D&C*J$AYG:1E,+LW[<.'C,+&=*DU.J5$`\ -M@*:NZ!!>-BK^@B==/;*/XH#^-K5&]%MFT?P/G$EKVH%7T.1;_N[W^@.K7[46 -MFK^-X&JU0ARF:-MVT4\?ML-;WGN/[Q*".DV,)IG)#G/&H/4IDI7E6WK?E>\) -M!SO5UAC]"),J"D,]D8'B.JV&9[0E:(DWO)?IK2=]QN%VWZU6PLGB1#H']PU* -M1C.,-M]O.1@2^T]_O\$G)=.K=-0.C[A_:?43 -M]&3WFTA<5MX=@J!@.AT]Q],^V1$(<;!&S51YX-3;@X+DWQ,QL],Q>'0@^6@Z -MFZ;D+'IU*FX87Y5C6N3W<"-L%(TTZ`L=<6;^3E0H\7XW=ULN2%;3^80ZTQHL -MLK`TM#`Y0O8_`BX0(EYEL8L(]*1M_9SU(2DQF01#Y9QGS>9*-;E+06EPD^!@ -MV9GHM*Z*[=[4'^?#]7\!:W9J*(ITL169HU\,]V!M(M^_,YDQX*7,? -MC\`1,'@XZ;":"<*18\T!W -M\/9$K@/M$*-Z2KP\2HG4$;1!V;'*4*S?)D%O<40].SZ+COKM*,>@Z+)38V2Q -M3:14SNWZV'2VQMS/PNM%,BSQC13:+>`VA%$U$2:E!'3VB0L@.])+`0E?K.MX -M'`4QGCE?RE$'^B`;LPB2YT>V+6''W./VT-X&R-$ -M]3\=]G*+,Y#P[Q5>CU=#FX!9($Z'8+EC=[%RM\"J>,=>T*B'TU4>.TU"/7Q` -M""=H!2==[/;8!%03IR_>E2075(>E-$\\G<%]%B^J\+.P2"562,?@5;%H20RK -M%'H?\H8F6IMVCR\7`VS;GN>"C+IKB-:S)4<-I27VE)WD*&-@G]C&9;.'J/G= -M(WR.(%IE(.:HR.MD`O4_Q:*>4I;MMO.$9G4C4Z66XALE%E^4M"PF!3N>Z\\6 -MG6W8-)S%+$**.;%DCGNCO_TO3L1/Q)8@FFS)NA@,":F(:#)7$M"\:3?1LD`; -MO\*N\*7IQH62>IEN\0X>G+O[*&3%":2\TO>NGX6Q?X!]1L83$HA-^PH=#J@& -M"\R2BQGE`K87!?]*I2AZWA`B;O1.LRWB'A,&2.+K[S;4ZE#Q4=M`16Y -MDS/36BO?EE:E!8$`]9RCW5.PD"ENR6WJ)*TMN7R@55A5Y.F_SIW7 -MDOTE$OEQH2Z?*+?L_7"3>,#&[:[LY5B*6-"HW2>Q6=YWM!?0IUKVR4Z.!?^MD\PBPE68!%A -MATX-+Z=^@O9D;>=RR.SP6Y4`4TU5!RRD`W[[C:*&Z#/X=V"$.)RM8H11>K45 -M\EQ#+(D%%WQ3W\,U])6$\B]]WE*!Y\9VQ)$'D8(;W:$L/T_QQZLWPB02F]2: -M->N'AW:MX;?+[&),N];=QV5V\4^C\O<7Y+?D,$_STZD`];8,[S\?AD]?22\_^X+L?+J^7*A8WS4!29TYA;JQ*6G2%7 -MFB4W^H9`%!1F/1-B0D>XN.R!?KJ;2 -M9+-/]V["32XEW@<"!ZWTDEJ(QDK=:WK?5$NB2S&+?UE3,)@FH5+FPML4PBN+ -M-.'(7CA9[VI=:.T'Q,U@OM`T)GHT]>BWT#7_8HE\V_VB\\N9A\$#WHZ)@=M< -M>M2ASZBS$[#M_RI%?WAWB#YMF1:6:@ZQ=.BPD*5I>'_?:=:?IWN709%[="C3S.2BH#Y=_#$TA -MX'&*>ENL>W`>.N*F@F.&H.EYR<].F[S51'+Q6J]XHT5HSE%!`KX@=:M\J2)G -M10,C:T+?DF4XC%`\$UUS2937&31GMF/<<3Q/#*3*]BBK7":>@;>77_)E5""BXUL%0DZI5 -MJ)!Y:-MM@L(DQ<:J(HNI[_Z7#M9":/VP.KUV$S&F&A%HCTV0"-)-4;@S.3=T -M[U(@E:IS`@R]MU*,\CW`*RGVO`.%GO7H*\W6FP2'YO:,KVZ02:4**0I0-297 -MN0]DM#.*7&;G8[68I1G7B*=K6M#73Z\,0DIUI!I4MS5/DJ+H/J)37%79AF#E -MOKNJN'VF[Z.,ZV:2I43S]PJ -MS>4\\T+K[&ZSDM'0P:,42KB#PXP]"!_6\!O65$CLFMFA8L/@>N=790)H`)4A -M)6"QQ7-BIR!Y6'`B$,PX/;*=Z?"NR*+21X.8IJI0,0>KE%K2V;XWXL)SN3,V -MQQY_'',@]LAQ%68?81N\TH@YF&I`$7PR]J`[??L#(D(O,]K6;F\>Z$_\X2=: -M1>#X4&9,0Q_.NA[^OQ9>D,%;'5'S&OB\JTI>'?T'I-.LYS-+KX"+"O*=%1)] -M)'TIDAP00U[[,%XP*^H"D@%6WO?W>3,X;@G5[=X3!WC=F)OMK!%&ZO+\LT@6 -M#":;;=S]6&]%FYS^GF7)Y$TCN\[0HG]1*G\8?["O_BN!,:S+YN_O'VFDOQ7%O(V"90N@X<7+Y(!E\=@"X'_.FXA`-^UUN>4?X -M-YD25KET3D&W.5GU[2C`2>'!>W)F'=E%_!WB^!;=()0V -MF7Y8EBYN(PT>*Z'LJM;*G[U+E:VM,[+_W# -M=;-G=9;1IO@YD9LU(:8Q10DK&@2C;A)$63*_`,WG*(Z7%6LL['YZ>:[_Z9XMIH(=?VF(G9R -M#WBS["`)JV,#1/DF"%G,CF""S%XUTBL\Z<=;_V?!`E*#HAM(#)L8F"2(I<^% -MK8!_`Q`IU2*\.D$X_352O#!)JLK0GGF%*A@`.F-ZX)?5HI%)(T#VU^RUB -M>/[/=DY\X[_0K1(Q2ONW\>6UL2%]Y8B,**LQDMEDYY#*"Y1$L,-'O-]>&)^^>_EDQ$EDYJQVZ/3]JG+1;>H5^YE1D8`&%8[ -MZPKK)\PH=*L%HV(GV*^=(D#"UY3MLN1_MMK7YO^;`@E5[.692RJ?0R3#/4QL -M)E,X93]..X9#,HD?;GDHHOQG=JOHX^0;)S2BMHDUR1^-L0\\?(B1>#^Y:<>NE/KP -MV]T)7."+9:.(>W!;_.2!\,S,=B&`\3KPJM,`>!4O_7D.]$%'^_`CV -M]3Y#VE9ME*BG5J!F^51[\UC;XQ@TI=K4D"_2J[::(;\*5:)ZR1EDS,05 -MG+<3_TZQ9`X!F%4%#K;\DF17Q'FM8*C0]5!@&NF'76B[:.+Z4NR_JE4U25^( -M;SX4)3HC..^VU@Q[(9D(7V0!FD%>7^G?(]Y9H- -M\Z:5DKJRQP6O!O8,PO,_BE>`C.^NF+O[OL`&'4I41HV))`*G2T=/!).\H%^6D?ZN\OKFHXB=91SUVA!I/7;D&N=Q_[,%]`".HC?Q'$R#-#J -MSGMO,5!29Q!K,7JY-0;BJ_%$I'F&J2B_4E#-5FD])JR\?0L;J^JSR&876%.; -MM17FZ.!<9X."%LU2B5N0>$+RP'GLZEY\\I:E,KII#W\TZ(BTDHJ(3LE80F>#>/NW]M\45+ -MM&K/?134?31\%>GL=E@T;TFV" -M+#"Y<^4;T):(M^(W*K$4H.S?T(.00%`OCQHPK890T65I5Z9RT=9JL"J=O<4<1&+]" -M9JM'1?K$^/1K9V5$E>YBR4VI/R-2_[JPT$"5DG5&3C3Q-7+8K`W8WR)82$QI -M=X5HFYZ>R7SPC%1$PH)^]D4&M(4V9OZ>2QS#YC=-<4$]D)0WF79I4KYZV_#A5),[ -ML8&_7&V@:>2%D6RC+0_0I"P1WU,T9P&LML'U$]WA_+PQBU56!YY4MF+9WM#A -M7ZR-*&RM;45N8&C%>T;)-)E^"=/!QB`N> -MN9JFQJ%0YHUAOGE35U7KY6D[D+AV?[LJG4`".9\;]J9AW.,38]$*/BD8I+9;QL&%'N-GRF!G1Q=EDTA4-RE\R;V%P*3, -ML4@VOEO#AKG2GRTIK<;9L#&X]WQA%!>>LLKOAP=>T:.G(X""AHK=RDMEHO<* -MI[*S7__./"+MR2KPHZ6,K>Q[>Q',G=TMUKJ^D5VB4.ILG6J#?'9\>FE&,2+. -MEFSUG[0@;:7[9;#,%AK&]O^XB0;?!;-@=05B[YV:U9+KGQ.'DT1S0/P#VD6= -MWXA[A8P=5ZR<:JNHCXP%DM<*YY\_'P]PTFX+)5(I]"UWM@/_Z"!9#>NW,P/A -MNYT?WYIBT/73L:$.J*>2$A$QR8/\6"SQN@DD.R=0[L0/J"2G6\M::MR:F2SM -M,7*;W_+G&EOF#'_,4S*N-L&J'?N%'TQF@Z[GV0"[MS&043\)*78I27;L>TTZ -MI2V!QJM/Z(?N+B3&L)MCWB-GH62SYV;[B\3L8R]0Z'$<3\&:F4;[QVS7#8"*@@_T$WAIDB@TEN*1E-*\H6D_Z4!<^9 -MY.Y]TVQA6*Z=!)!(,`[8VK@L&+C)<'4#`N^3R';4UP6%I6R5@X -M5$9^M@Y,!J)M=AP>?(,W/J:Y_7GR+*`H"*;98YO6NZ[`E*-6"1E)KP3Y-@2? -MQ\!0(5[CA$UH#,:"QN-#VL^WI:#=H[5(4R",%)?DU)5N&;L03O>D#D#M]?E5+GPP,T7V[-`J*%[CQ` -MQ5)VHN(:+*"][#CB+YW=DCPBIBK8BO"@E5V@R(W&OAD2$&:N.^F#$:26<-F\ -M*D_5B_1P>2)BW9AX&<4K>LB69EUBD(WY/15JD3N4SLR6%9&JH$5/2\=BAUW9T<$6*4[D^LK/IY4^4CO^.,0M\!#_I[(O+.NR -MME<1]8$8*,]MF?7'"L@/EEBL#4?] -M3N>7T/>`ZXJ<0K<802RR2+/(,^!&L]XADG1&?2V)#TD^:()@*&#-.XH6[W%W -M\QNQ*K]T0Q+]L210=UCH&1_G/H=[@E*,B>W%H=^4GY84V']L'6F1(AR(V-8` -MO.18%T5(<\RP$U -MH6,+W'`,]XR%:@\VU$,0\@K/E;>J02&$;N&['F^V8^S`3^Z_F]\V1SC\,[E5 -M)/N"6)'G"#Q9_-54=[C*H)_[&BB]][",DZQ]-F[0?_2Z+,L72QV6D=B9=/\@ -M9W[]@6O->CC!;[NXDIM>O1>4LAG?HXS<(@]233@R*`<0Y3*@6Y;^[7YE+K.& -M)^=1$B`D0]M=&B,?.[ZN>&2*@#4\&Z)?;TPP@6,U^G->4MP%='X2BU!=4%&U -MCE>R>KB7L'Z-@0%Z@5&JX5_[ONWMA=*+BG0/=KHKJL)TL3W"J%A\'S>D(RT24Y"EF_ESNP"A_.H -M7#?>VZR$-&89(\&3MF9ZL"P#>IT?WFKM&%1Q?(P>43!P.G$9.C/$+X9-050* -MDT>+=XD]9WK'JMVC,EH]OF)Y]";-NPV@--F#O3B='?9-Y\=2T9/K$=)3VN3+ -M[S5E^%B/NXA;0IF.98%N0`(Y4EUXUMW[$Q^N[;TT;'\(2@<[J6TOT/,B==I4 -M5\H+^ZHQ0$.+O$>O2:]D)7'02"R\9;O7IK=O',!9#QA@QN?QGBY/L,3`OH7K -M8^*@2Z]+#+^0#?N8+.;60K'1"0=\A:I44YQL?(N6VV-?+=`*64+#K18>!.?U -MO$#7""(GH=@+"'ZN<9R.?BA<)G)*\MWT3):PVXQPK7&']*S]M_J+XTS>!U_T -M=RS8A(GB"67Q)O]X1%S*2%[Q!1-ZQ8_G_00S%_.+@XZ8G*.Q/Z$PX_2A&STI -MGU[`3D3ZA#YK%;-^3B8JJ0D"PV6W.=)Z;O%BP@/=NIL8A$-%%M*B/N-@,.;Q -M"*1,*8-FP4HZ:9+LQ;NW>8JX3ZJ:-+`@'&IL2W`NYXD7W*+V*`?\.J1@KD&E -M5K1)8D5`I!Z9UHI0/X&P8RI7$2Q-S^CLL/Y9O12WS0DMO,]8P@I6?./R;T"0 -M/Q#0$U39Z8@W-E\E(BSNN&J#R$DFUYQ%@+$JRHB_T7MV-QZ^+DL(/3QM-75];;B%]8+HV+ -M7N?X;5DKZQ![/H"GM8X>!'/4?2DPU**>\D-F,P7M,FL^H'LO:E=6`;,)KBRN -M-PY)!LTE(AB)MKEIN]ZQUZ*ES&S8:S_/F?TA+)AY%,'KN+`4+;3(-JRA]*0; -M1`/[ZB,/YN/P/N36KE4O=AHVS+\8-YIA9 -M!;F=?/E"ZTM'%T1;Q3\=243!>X#G*N);^)SVZ[MG9\;W!98%O'XH8&I&&6`= -M>SCF9U.392IB6`4++],=;6$SGHBT`7&>J12XJ>!2]V9[?QLED.\\E7)6M6I& -M960WFU$2V>%[9$+OGI&4_3(IVI-PI>>96)(A5XQY2C2.!Q?BOTWC/)[1S!EF -MW6(%^U3FEQ>&"A.Z4X&#M_U%DXOU&;&K<`@IU?&?U!*":I:/'%+X:^@5%4^3$1ISD="7%.^,N=![=OEB^10_Y^'*FE($3?_G7V6*2D7;\9GFFMP62J2%L6_-("C=C/N.Y!N"GR&&)G'A:9D3>&[_ -MIR`^U2`6GOIEO6E0UG!O4T0+2<^#,$NFI+ZQT#*-X3I5W[NBG8% -M#^O;%]8M3T^`CS)`31H"F-3T'P3F)J/#+NLMVZ[Y"43<:&]XE(JA$C"H63,1 -M(T>"@P/6L"`_78Z.AG>T^T$A?S`3H&23 -M"F6H;=1\04JL2;GL\*8$#L.<0-OXXPH+"F:3]\<&\YEV+DY0CT:Y8),7>):2 -M;T`U4=#I)W4_\J/(6@S=DRKBQ@[1-MX]]6N6A)]+OXT;LUKRDVK@)?@L$/0N -M&,CVN$QY20A6"W7J5V$6S!SPU.4YANAXAJ1L%D@'KW3GK%DJP9_[YLJ=@TLV`]9B%[EM(3S*?E"?QZ9RK:.4W"53+)O77*C]_"W,=0)P?A_L5/['@5;I@VU((]\ -MI.L^7@NN7E_:W(\RAXK_Y76@9U'L'@K*ZK23L8FH9^/>Z-HY_E>*DG"L'G"# -MA-=N])W`N)Z(H?Y2";P+"N//?)@.KJ].=PRY01IX>BXR!]!JI*[2VSA(<3L5 -M:O3.X^7['(T$"XR0U:]W:KJR046U_23;&<8_C_!EM20P-<)Q#!YKIN=+W=\] -M;,.M57_'".19355V'KO)J9DE#5*AO`ZTI3EBE2!]\4!5>.OT?R.]&-QL-.#6 -M+P7Z6:H6QZF52SQ92EZL4GC='RN75)ICR^?J?NF=?I/&X\N,@[6<\0Y?+5(=WL4X>Q0`-/:;>]^W,V_GI);TBXR -M*"OON/=9FC9O/-#0K+T*@5?FT`48-/V:/HKGF.MQ",K!D^V-_$I/+$#9IWW; -M^_6M?L@6F7C$XT/%UZ@8L`'28I.-RNS2V.70;1T^7M/[_UGDJ!S<'(LDO&M_ -MD!C*"U.$J87*+0\!V3&<<20L@^VI'WH#YU7O#Q--7\L3@CS -M\,*=8TQPI;8HF\Z'5W!`X\OPQ[[%`B1RO+!YE\>KTC22Q^P1'&!'*$L80?8^ -M>:CB86/+X?.'<"CHDQG*-JU=PD_-[^GPN'-4V.20ZH/H/B_`(?&_=43K'0`I9IQ]VEP`?X -M6?YK9,;:6:QIJ#-`@U:+N!^MU:15QL?(QR!_Y\7GK-<0HQ8>:587QO@H2^`_ -M_AOE&VM/O..W*3_WS2,)GR1XF@G!P@"GPQ)>X-=!/6Y3\2I2ND;PS"4U+TAZUC'27\US(%T26XHV62;4-&0XJ$S. -MD:+9A=96.K..*VJY_9K9?55P_7';')0N1M]$'[HQ`XN:_2Y/8:M,Y&EE15R,S7OHS%/1>#?;:/3=%"TQJ!(6Z$?Y8., -MHH6LYE[^2;9R"3GL#0N-38@&ZH#V3*S@]2[V.,V)Y``!UP/GY&/>TY3)J)&O -MO6091MWP1]U%J/XXV_+=''O(O"/>%:`!1-T;CZG?<J)OJ -M*FKJ/6(KI'TK,6"M?<6YL)7^8=DV,Z'@1V3]7A4'-'[3#8X&PL`.QX5_B,,! -M6B/DOVLOUA8I@_1L6@^/E)D4J@(`>A*5;X?);>EP!MO1H6?G2S(I#BIJ::^2 -M<"R9/6H4"[22T^%RE$LSMJ\;B%C?[TD?!SG&+[X)XX^7_"6YJSD/]#RI)$VQ:T0GZ_3H:O9,?5E4-L"'`11[_G-"!]F68W5H+U= -MZ(+N&0PV-;(;^%.I2@SY`"?*Y3X*M'H?XV322(P2!P"#K4*A(R^_)(%*CU7L -M5^>P.^XP0>TFFO.6HL5$WVRKA96R(EG`]OG\[%`R[M"@F$IMV(19L3`;^!Z& -ME=)^._FNZ^<\1:1B[_NY?GF[#-X=$%LKCX$A]4\"!@ITJ8HML9C!RT.\PBBI -MK..E%QN=[&J_]X.\T1EY-<2<2+IO0_S/,"#E1\*EBB-B29%5LJ?CH\34(&'` -M,'!M9MVBY$5''*NZ;HW-V\I#``XYN\0OWF@?E\>K+>?SUOKC./>=&V7 -M;BKPA9@CW/`TF#SG**]3];H#'8K/1@^\N$D/6DX@JZ4>&=FWOVSH8MP=ZZ# -MG1MNRQ>S'FK$X,S9S&=@)%.<=F&I>Y8AW78I@RM$:6B3.UZ*3W.QA1_)9SSV -M`@:`M%4171MJ4\0:/HDZH5T5YH0;`?5-L+U)9]H9/%[/E.\Q= -MM!:GKW>M43%R,"8L)"1O/Y#!_O0'(*R/Z`#-YI@E#A*>6N0".6]@#ZVQE@E, -MMNOR:RH\;6`ATA6(A!YV7;R@I]OY593CK,;N[/<,T'_M7*TIK$%?UQT4$VL1 -M&,#%#[*C4XZO=[Z:_J,#;/;#*K]_SU_Z7/W@*34]3^Q+2,;N6_W(U$TNLV[W -M6VP&UBWKK+=.P%I$D=.W@#=\JR:__#>VGU3]+)Y5(19 -M(S!G^)!;L]>T=;=*^:0[JI7F:Y4@/Y'Y]S`F$IB0;3,1NX"-K;'8S#GA&`O] -M?M*EB*+F:5A6K.ZS,FA'AG.UZ7-44*O:*OV"31WV1FAB3!++0I;\6OA3K(`! -M(<9QQN[YZ&FF<>#AK_%]_/8FW'K5YR_T99_"1.VP:YE5@@F_6P(\KXP8\8\ZWCTYGFDS`8 -MR3I)YO_:D-GO/K1/,[N9H?>F5D>\CB]D)."<37$QGQ?:G4IMN;^[62,Q5`KE -ML1./K?:#_EP5=>$TAXF&6/.8*6LF\%I,ZMEB6NV$R9?&XQ>]1E"E\W5SSLL93)6%6@=.N"3S77--:8-8" -M#>-1BFPR5V.EC'7\=FX@6=682\$&+H8"N1O19HY+3O$E=E@FG1`I][0(1XR% -M^1N+*G3YL5Y]NV>&PK9FK(%[>2TP?1\Z@!J.;U5P;C4N;A])HC1,?)NU"?]- -M^..^-0T[[K0[P4F&N*"YH`K$]A/Y$?$;E7_WF^W -M*61Y!F?2-MT13?+&]/NK;?JNU%G3*S -M:N0S8F0N6F6K-ZVP+>H$/8',0&\]H..)M2/\0U)8:F8@9_4X8$W+*Y_!0:+* -MOEQN!LCC_FHEL'5!2"`1=WO.!@!N%QTI5YGMQ5FL!Z[1R(W.(R(*1ME->V)J -MFLIB/!_BN3?.A*U6^0A;9I))`:CI\\_W$7\GE/>AD+!A_TOSST**$\>MW!)4 -MM3GBQ+3\-82\*$\/9^BE(T"VHY5;Z5]^<1L[@O`HW[85U[6>QS^IB9<*RCZX -M%6L<>;QEC;M(T#P2:EBO#+E%3W3&RQL%1C@3EH?)]/M#UYJ]_"N=ZQ2>GD); -M6V7VCG./0K9`6JKIH=N>?"Y8-G1].7-+]`-"\R21_M#KJK243%K^FG?K",^1 -M0G&WDSI6#+X5YG[DX=J!YW\0HS5#5H_S$.'#C\8%RBX+"^8ZV0QPQ>K-1P3, -M)$K5[_]WC(@WR8'M0@B\[[W$3^JD=6.E%IT+^9T0#TXZ# -M$YNC4',23\+\PHT1AY^1.V!_N/D(G"U=RS=/0)X]LO$Q#@9`H3&!M!, -M_+R/$_,^:L%XU(7W8:8B6"RZRQRC[#/Z=F'2AT?(3ZFLMKP8.M,/B,NU4#:- -M+A'A7]>OKV$OZRBXPQ<([T"_T+-MD9(RAB@X,@J?':7FF'E[.]-X")GPXDWF -M)J`3!MHUG3#V#[0+L?(*<-B+&:_>"Y3X+.A;8A(_"-H&@H8>K1=)U+YMN8A! -MN?S:.K_(\4MJD1B*G#']1MX=%#2,8@CA#41$4]RC!A8N*Z'^>D9%"CFW"'"$8Q`U^&YC;&;W]`%C_LBN)$GWI9\'0P0M/=% -M=/7`^3-!ZEXDM(`\\YB/H9XB8&I>](<((NY@JBDZ=I'@*S-&3G28M6>2NSM; -M0>%X2-!P\$DOX?485FEWM5B++&0\Y^N,2P->XS^D,*W/0V<2,=)?5%4(63=# -MK'L=4YFI]^\+3[:])8J>E=)CZ1+1QIE"&44F?OEHVL(>^58[AF]"8)YD.EZ3 -MPYSK:U0P:DQ93R,_;RZN_:=1Z0!U3-D#4]M`,U-9O-?!^2/T9+)T8W*^!6M/:U,C%Q3<&'+=K4 -M5MHX8;G'H#DST/;JIX,.`7,P_8?B5K-2Z'O4;X#(X3Y[;YN6D*>GGJ%(PL2V -M-:!NBL_/VO<#9]B8)0N1:7D@'_R\2HVNL6ZLX'[7UJUY?.[%QH9X^R$GD-6< -M1^7%L0RMG6#PE<'[R(PG@HGDL6IBR)$\E+>/XIS]B$\X\#E))R7_S&6`"]IN -M6C2BNJMHC:<1ND(81*<*P[_R.Q`F-G0K[@!+(B[8OS*1S"=YE&*":I\4.2-A -M"1V]\JB*ZM%X[$\^3MT39`QU[#%@PE?-+V;]>MG*)C+_Y5;FKNL1!3H5!WSO -M*-CCWZ:V%GO(2P;[HP^J]M`MPWF6$I;WF$`))=C/CV,ZT$3X>5E2HO?\1L!; -M7N4A'.)5&&R0!MQ!N<]HX4KD[/+AE=F1_LS_,D+%-8SKE1K6657-L$8()^$6 -MY:/'X>K>ZN]GH+U!P\L./XV;1DAS+-,3I(_*.$@#%1(?/%ROX1;F5"8G57:4 -M>SWSJ9(5O:_<.ILS9+*URXQ`Z@[(4?+3:>_]#)ZMUYT*A+V5>P'<+NU\D=U- -MVKK;PQ.;$IV&B2A/L':HZJFTG6B>^JH?@QX50.=6B0<%P`BHH7L`PZ]U+OSM -M`O*H1:2,.U84]5>_]65=6!?G*?!)B)#`UNSL3)"[?+`6PC:AJNS@0$.%3^Z+?Y;1>#ID^*,\EC` -M+"7_>1>J -M<4;0VQR**])X_"W.0SC1:L!'HSF9N(RG)8YJO2%8.4-4L$!ZOWL]:U4V*+:% -MTF8D):4\!<*7P/_71IR^AMFG0GR8>M].Y4YAJW'UQ!XN&Z\0YL[=Z;Q<^5IF -MO@M._!&M/&GN]VI&(M4SA'(]5,*.;2MBP=Z8_#+K@-4`989YF1JXX4`1:>L; -M&@@;@EQ8LT_0W(]J^G=224D%.<:>$]'E(T'K.)H:@)+MQ_%@--U5[EG,MJJY -MW>6[8.07D]2#P5@L^PS!%W[I[6Y/J(27937I.3%_*[O>R7`^M -MUVN-T]&8:JR-<]+\4&&!L656UB_LM\+2FJ#<9_J*"[GG"DH*%0M33UC-K,VN -MLI)Y<1U^YXAAD_P4CA(&2SA_5V2>E_M5!7[)M2IXV@IQX\*F@B@0O-F>V1H= -M_[Z9;BFU\"?>[H$1,N^*C7?6M^"R-M>GD#F8$VZ8VRH"ZY>=M+Q$":":_^" -MC-(B:*;$PJJXY)=!3RIZ2K1#$D2*\V3NP+K4!Y7=J<=A.#F4-GC^,]_.L1NX -MZ(>B*[U&FC>)TFU)ZDFG42(+GT919+BC#LVQQ,KP$.A_U_A54G&4,#C]M'Z0 -M!M-3*\RZ/H;V[_.E3N"(:WOGMO5H.*?QDD]UH&P!A79\6H9VF+3\*VI>[`] -M1V/I/$*:_MRP#K7:3GN+HFR"8VX[5(%M6!04`6$>7_Z`2-C/V13!&0WV&@D; -M=/YC!!>1SZQU!.*481B]$L+Q)>POE;O5-!W[:6(]`M6*BVJ.'EF,8]$QA!:X\N8\<1 -M)+!6Q]5E6_+&E:1\Z*[*/:\CV/>DW;K:1'X\E`P*G?((*2FJF#'YC@H%QPNJFAJET7QM`=Y3&CS%`-6EQ7)*/_93HQX@D^'E6=+.R@QNZ8H?VS#;)00K3ZA$+JKESNM8,]W]]]4`7Z`T'_ -MF30QOT$Y!R@=1I74$8A\03H"#9[+5/$D8(0SE$ZRNA0)9O9$7C$1S3]^QY6X^R6FJU<>1-MW*(. -M1_I!(>I#+UJ;N@P%Y#XDQB>R7X\.%%0XRU/`CCI`JX..W:VFUP%/+/VY@#,W -MU4@8%V&..3H1<_E_W#9Z[ML+5B`ILVG&(OM^E[24#%3W^1=J98&P);>)<:>5\J -M;6!BP^0QG"XS)*UPJVAT_2"JQNFG-+>A:W)G""K>%[1\`&IM,=L0IXF9W$O%RV,Z>M8K?+/L=%9!405FI=QQMC"&:RQ+W"P@/DXFV([]0$FZ,N>PGBY4GK_UJR-;=$VUMP]K -M8WPJ@YA2AWIW*3=[[\],DKI)#L$GQ+^Q8-=Y_;$=VB3CNUXE;P)PGHFW*3"I -MAZ#+6T*.!;Q(>$.=%1*HLW9<[C=+:%YF&X1TH90?(F#V2B+'C,>48ARUK+;Y -M)PXMB7DF^I84+CB0MHIU5%L)#>V!SY(.0]"J@R_4<$$#E4XP/51!G-7N#?0S -MM16"=^8_E-^B(SQ>S;&H/M-YCR?>9F8_7H[VR7<_?'W*6&I:ZA19[ -M<^*TU"8;W_A*\&9 -M_*^V5M(EJR`[X@41;*0^P`&.^L&;KYI#D\>GAX;5VQFZ>@$CZC%O(_<%']6; -MBPFK[8FVCU#&*DE.U&AG)9@4K*Z6OOIKY9%M'E).J-7]R:G8KV#'MZV2!'DP -M7@RR]-@@7*QLT24\3=4FT'E03DA`/J"TQT^\G`R>3R*<_L:-_0,]?*!=[E1A -M^P2M56NN`&+.:[DS!PE?)PA#[E"^=C9/L].GLDLQ!2<(PYY46"U(G2[7SR'5 -M%X`W#2&T0MP;=IO1]MEL,73`9%OK&5I'2%=_&_$U=2S].CFQ\Y'23+VIJ]"Q:`88NI1FLW"9ZJP;0.&U[<-/ZF@Q[/ZQ.RHSI20;YI=GON*5,'J$LIW+H@S].[M9AM*&F9#!) -M^5RD5SX^9X!\&5"9M_;GM#CWW?'5,K9T*SBM;@X9$":MJ;P5>4_&CQW0)FE. -M&+-?U:A`4D%4B_^SL*+%=TF8C02\NG);P*D_?/[@A,\6<%X"[3I4+1F=625_ -MVI=PA`0PA:[/FQ$;:2ZC^A'@55CTZ>.@I:R_!32",\>4D":=.'8NH-\\74&" -M@&+_J*&9=^)A,J;`JAOSF3UI"SR+JJF`D8ITE*,V),=:N(\)D"_1XS/9G"N( -M7JMB!0QTB;=BA_>EY/)$`.`/]48TV4P2^_K*FWRY`%"S0R.IR?IWHBT/,8O3 -M=>6)ZA]AFN]=:K#BR^_^)4/_.:?^1K9_YVT,_X6\B22^A-R?Y+#A=?+>6UEJ -M#OVA,JR!#[X/!ISE^G)L.,=S3U#:KA^U< -M[Z,A1H(W]\JK94=^N\4+Q%O1[KYW7W([+V"`K+P'#:#'6H7B#B^Q@N"1"7"`AL -MM[M*#$,5PD!^G*)UWDH%Q$H&KW65Q-MJ%0U*PW1CG@$IQG+T-YQ.BODM#K.E -M%3RZM\%?K+CY1.<*NV=]D2[L4KG3_@33R?+,$%E"!W%%1:DA=^HQ:B-S`+0K -M=]2DK*F>W=B2&IXC)FRX0*&F3@B1F(5[0J1H:V9MS+'.X'N1;AT47RS\4`H6 -MU%DK*`&ROR7MXO59##%8A_;72]%Z/R&#-G% -M]Q''"FK\W$T@7";P6;KG[FDYVU94Y'(.9VB3&=7#[EL5]P026NT=[,>)E(?1 -M_OB`\WV6^&R5!77;'0;\J*"W?!Z'F2+#(0S6T`I/YS/B!^+)3.XE#3ZD- -MCG9N7R*,N,U@E9H*(+P_\KEO0H)F`6+YR$LW,/ -M_E[?/WP?NY0PQ\>@N"^)S/W-S9G<,J--D;4+UEFJ2B.<);SB2`1^)X?A^_"[ -M]EJ\1;R"Y0>Q7?SQ'DN`%67[)G&";(XKD?Z`]7JP5O[C?:IMO!QDB$[U'U=(W -ME[(_2`?MX4/J"GD40'90`@L,;(.O-X]$KO/U5'_DJ'=217!G%S$W1_VD.NF' -M<%EMO;08`GCTFB7&[9.A#R.@`Y`NI[`G^@:Q4"]@X<(DKEJH:8Q>=53E"(=$ -MZ--MB6$6(Z?,Z&ZT9C1_V!7-8)X(OJH#*0MAP1$F,0#D3K.J%HXIW(^[`,/8 -M;1'R_/8@4,8DU-H1J6R(1#+7="XG!P[,`:Y8'I/JF(J^$0#<9FF]!,2$(R<'NEMC=\:X(%.6X(?K"_Q< -M(F-D!J'>PO-K_\VZ%!#Q5MQY)G>:,`K:K$03Q74>]T2@UV,?I.6);IE=1L*` -M%*2B%_7GM"MA-]+IG'\"B$&[N>E?2%CU\)3>H>AVB87.4F`BCI(^-%/+3S&7 -MC^Y=%T'BO0%Q@RET2J[GI!TLUN/P)M[\Y5TDVSV@UN+E8]!@Z6M:;SF^V9U( -M>B&(?'ZOEBCY-0C-@$T;H[!"0A(]L@LY^*]GK-HY;LM]^M>A]1Z!`=\/Q+G. -MSDJUG+?M+\VG`"PH:5H9.&``*"'PT.QX$:?S\WVO27JN1*A6&4=JR,_BW-LQ -M>5H)\`\=K@GV%#2Y_?MAJJ8SWP;MZ]9C6>]HOP@2C+:FXT[(;H\*"\U+)3=5 -MQCCYD]*S)+X,* -MC)P!]PNIE3&RU\ETI>+:F5+0*WTC65HR3LI"K)G2P3$XQR`'4\**S -MI[RAQJD@$;FVZ:4NV>>K&T5R4*9\9B+XM0>'BW37FS-%B4E"7%M?5@8MP/S7 -M&IN+Z?G1Z;'7,/H>8+/FJ$>@&JU\KQU^N0L:S=4Z[[R?A&YX7-3?<;D][X\; -M%=")F!K*KSN1[?*5>S&M#,I!*14+6FLI^]A]GD7>\/8_72ZT.\QO%L"M%\O+ -M+^R>Z#\!)5#5%LT59CS3/VANJ&^FU'JB`Y?LE@HV -M)Q;YJN'7/P8^!^V3M_#]$C:1#YUTY2%0._]F[.M-,='="=!L.SWZ84Z&KCZ7QI@?MED(O#.-<'' -M:30RW4"/X'T4+&Y`QX,[<0Q%P*_P!`MT(6(-T[D2S?=)S$&`&!#(\/COOX^. -MDYQ0:N3>"&0I:ALC/XHD+\D6*F661QS=$(9P^Z)J+_XX#7:*1*/7F[S)"4_=G4 -MN.ZSMI%2"]H9G^T%[298=LF*ODMWA)FBX(^95G\W8 -M(@C,8ZW)8CYYE]9\+J9L_-,*[>*`B@73>'"CE'V[QT8#_\ULU]XV,ZBE=HAT -M[52T#:\"AV^`78VXC7]]C0=Z#ZI??"B/QC*=7J,0,)6A6F'H]&X*_"NO1).5 -M+2!T1\&183:\;ET/\W]#`X75":+0-(ZSOAI6K#!0CZD*U,C7]GK-\JDAE -M:LQ4!F7R3\_GH2S]I\[3WK;8SVI`%ARK,G8OH+Q:HDNA4ZJ:L++O%K-(G_@I -M]G7*5M0Q:[/-A-63W@D2G4E@=*C:D7`L!Y>YTV+46#/:5A7==/B-M2[GI8F3 -M8#>7C'YWMM%ZQ-$4^:OZ79TP[ALTFQ;QO(*+8?]TF$=1+"LV8[>+2_\X),84.-G4J5RY%ZEBHY[G'OXNB*4V%6J -M292Q)5($Z$N"79IO;7!B%!Y?'KE"\;]K_CKK*&ZCCH+ZF.M8TUU3PUE1:IO: -M2IA09OB"O,]D+!0VV$S\G;/B4!XN,`Z;">9]3?X%R]BU">G>W)YXN2L<:X!E -M;%#I:%DMM:O\U;]:%U^>)I/G;FPST2Z3^=7W:K>)"'^UXF9A)VV.&.`:J(NJ -M)Q>EJ(M)D?AK+;VV0PTJ,NC%\9\MDX)\U&'FTXUB[+X25Y$7&>G22Q/L3B6,/]@.1A[VG:!+?S^'WGR! -M!`8V@3J,L.$>L_X728&@]+KGIWW -M4752$>]_`4V!\^%J#GS2;9BP2,.-1./_13FHG3-/L"\!&\(1/OGUUDXHNJ&3 -M+9KI0]7"_P#_X$]YY!;[C12?M^V"2.E`#+9)GGN\MH%A;R;N`4*!TS.WG8HR -M7N+CDBVX_UYG`:5G$58\:V(J6OAPAW>D3A(YAXPJ>F=ME%&P*OSME#'6]O0B -M^4SU='FIWE55O=GH7D8W+26+V1O?(U60KH2'A7):#@J?/#/1%#N>XJ1*M,#[ -MKINMCMO6=228^06TE\29(5=QX2<[T+K#Q^C('0,7?]Y0^Q>KQB[=14U+)O#( -M*2=IQ1E9'\$*(R:K1?'P17B1B&%;:MR5%B$LSY$CRFU.QKM>9M\SE+47>LD. -M(]5G!TY^#"+Q$B(*\'(BB-BQ:ZTU\UJI&`:H^,FSW7_/%] -MQ6S/T\+*H6!D`D6/XU4%DO/?`<]U^=D?HYM?<'`(R`,9Y.T^U36X3OD>P!S5 -M;Y@0K)%V4X`Y"=2GT(U\^E@;R.ED5HZ'-9Z0Z+O'T*1M@"(/(AK)[-!R*[06 -M'*K.,X,7+]ZS`>;/:*HU:XVQ+L/#X.'4&':GJ7]XYR6.U[O7T9>:@MU4'&1= -M)U/+J'G_"X4LD\>/IZ33B^<#UB99@0Y?G_88W5-P)F;D(FBLHO@C`>&\IJ;6 -M*2&FP#%ENCY:%7,30D]VU:)R4'013@C^XW/9;`@1D$M"WK;"*3MGP_/:I?WD -M&\V!Y36EM?I@I\(^KA[5`M4ZV>88PMP/_"U*UDV)8V6YM'5W'4OP*DMFH^\= -M\8`H=J*"%=OJD@#E1(SO?GA3XS14/IMG7%M]&YWK^3@[+R*"$MJ]SBT+D\+# -M5T4S_W9L[>+AJOLH5=5^Q[Z/3[6;$!>64'(C)+/&\E+H,XX(L_YL^9\+"",% -M-ZRHQ!]*B@@NZ"VC;32;"Y;T"Z:8DEUPD#IH5'T*4MU>Y)&QW*V(12)A<[\> -M*6=;`A]3:FIKA440B,OC]6NE==IITR.EUQ74,4#FT[ZS][7:\%V_@0>9D5"_ -M@LU.4C,1XZ>!1QV5#98-B;I"3@`ZHG[\%-P?&:$(XVOKW.7S"B&W]8SC(G>0 -M'6VQ@+`8*W'J!LIC'PG[IF+LIJKC_D;!2O`%@2@MB*J,5?4:%H+\<7@*O7A[ -MVLSB&&I(J?\"U@R7:BOK*F7()G)[[S9E@FTI-O* -M)A34(5<7IN!FSE.N',!D/K[/,L9I3-**)7#2BF3BW,("EM3?N)+1GS*V3QFD -M-X*]CL)1RX0CM\F=?]QZ5J5TIHS_J0%6I1]%<[E[B"D6I,QC*$Z`RG*\CZJQ -M;L7O) -MY!4Z3F:ET%B>M&?$?W%8OL/+Y,3-_HR`LF8%%TENCH`'S7XDF[M_56(VZ:_LDC[@;J2H_XP`_L6O2SVXZ[V)6\"5YL$'G3TAZ -MS/X$./_16$&%"Q\B@BPJ5!\54BF85"!<)JI72;3L"\I:JAG2VAI.55)_MSLD -MRI8X`#Q,Y#SD_162__6!PSZ+J!KRQ)%T?9ON\YL;GV3QPB_8^!S`YK"H805D -M7.:H[IOYOIU%CR.@K\:L1F7A114()9^:'IJ&(**4)5*J$RZ'*[)],R90J](% -M"/0WN/:FE5D,H+(:UV(U6VW_D]L:*UVNCB'T#J6VO^\R[,/5WX%?GI`@3Q=P -M:14AQV6%[AEDC*L5`'BKNK'AJY,"U??E@`;.-FTUJ"!&?:;OSO7WM(,S'U`5RA?)83PY1.-UD%4LV3`B4\*OG -M.HT?_F1.[#6+FHI,>HVR.^ -M0#.%(?];$=O9*;7]OV*XX28V,%SLJ,&@A!+/S0Z_3:Q9]4O -M*3#((N;+(['Q=RBX+S[V(14I)]!4D?6!RJ>AX]TU189_,I:VE@`QZ"*X9.P( -M58<`,HL504T2PU171,!B<(D_"4\;CU"2$`CLQ,MC]:,21_;6B`57FS"G&M!O -ME_KIH"B$+IIKDYCE2HTFD>"FCW0@\0]OZE!=2?AA"#4_J41GK_5`ZTST;`;S -MJ7QWBB@ZEWE2%6OF^;,KU((SW>;;@R$[#?JWP:N#JS^CUH#>Q5&SR)W&[RY9 -M39:'588+\M$82W#IJ^_*'S,#T@[4G(M6\=9!I_8EI'U]Z&Z[C7+LL.%#X8Q' -M\Q$\3#V2W!^\]]4:1ORQ'@U04;[DL`FUD5*]&7<%"I4:A>*?#8KGA%D^>BV^ -ML4]E1]4_T&G`]W7+2!:]OD?818GWFL$,%>*:%G$68&S57HI`K^IH*&$6D9$O -M(6TA?7'_U3.\#$DW@929>*\&."Q)YP\*[6(^6EK7_S51Y#1+G,(`'JT2&Q4^ -MK2;DTG)E+CI#2TT2#5N_RO,G^?Z@=2%67Q;!R6EH\_S`5?C8I$N\90'0$.4B -MP`+H)TK8HUX0V`NB\5",#Z8F";/VQ`5DVCE+E`L'V///LP<6M`?LWP.;@>9! -MT:;XUK$`H(ZYC\H]F.#M^*G^MZ,I[;@[=<=:<#3[$\P%MU"8.K8Q1%R*$#L% -M`;O>RPG!@33J4Y:X1:\;^JB:N5AZ68VZK7COF6U3OXFM -M:>NG*2B%VE_Z]U:%2MP@V'>-7B9$HGD"E0]5BXH".(^0[F3XD"J58HM@/W*= -M^8E9'Y>'6X/\V[UG-%'HAT-Q$*'KU_V$H_S#\_H:'BPRT7@@CC"+K:88 -MR/9Y0M>%)]#F^7W7?S]]!DB@W;<1"GQN8:R9J67.O^8))#CK*1H24&B7X)I7 -M/.(S+QYTF&G=OH.#XEJFIS.\`O"?-5T?L1(6=E,]T&IL@P(@--4>&A\G:EC^*A^Z13G920:"E*$!1*^I_#ZH>#A%?L"+5K>CQ+-)Q#KCB4"VX -MFJ(:UIU3&O.:S_L#GZSQM$F4J -M!_JQE>I,@I*D[W'R:2FCK.AQ-?S3+!:OE)KP-7]+7`O\"CG[;8*?.G2M!"BTVX_,";()Q28QMJ'D,=937,7=P8?+%U6EPX73G%"I -MEV!E]Y)9"+7,[$L^=_2KP.OG0Y+L,JH6"EX?]7256M3W!>%-"((ELBW#,@W84L_S5D;'YF`&VD`<$NK]="T!Q;](V#HA]9/1\'J*]W?Q -M;'*9YO"!\&N):@*!L+N]@5!'8:\C*Y4^Z#>Z?PQN;N$$->J=:(W=AC0:FJ,+ -MMK,:H9N[(E=2G,$GN`%OGF2/0B"T"5&T-;MJL"-#H0@34%"X^RV<9LF$:PI2 -MS:O@V.$%-4150MI).;K-23TXVYLST>XJ1@(XN'S>T(N^[LT"/88HY7V6\A[@ -M41)T,E'S^[VU0`3H?:L,$.-TH#T;P68[-LOYK*H=>#[^Z"QA_V]00KRVDA\1 -M7+Q#=WQ9GS/_6ZIOH=GI=Q(H/[3:QQU`8\JU1]UZYY>8]/G/*W;=: -MGW8K2U`&W12J/\U]V=++B=)@-?I?`DRB:1X8R@,1\7+%N+&X*0XK$A3Y4&'Y -M"/X&3X,)HS@T'Q"_*'1)URL)P8_P@*=G"PD1)H3-TL$-G<259[$<:N7)4*6E -MJ[BR1OI$@+Z`I7N914>A+O(!`+S\EFH2Q4,LA<#<)`B2IB!,=PQKR9#[!$<- -M[W55^K_DD$_A6W>G.$%2FQM<(^P8`,VFP#&[,9!+O&`5P3-2_W(=TOMI7O%Y -M1&@<]D+]+077$N=41TZ6/JQJB\)?&F.6XNL$ID)`)T7HWG&`?*#K@O'Q#)"( -MNVU6,C[KMOH[F=C+1$\()3>4*_*=CK0?&U]5M -MR/\7$ -M_JHZ1WA+6CP9TW'MC",M&QHIN35FNBO59K8G9$UM:J<5)H3?R^&UAB'/YV=2 -M:<-X("=E&W^%E#S[G[$VAJ9U#QT3@/?KS]>,9U-F/^_L;P4-J'V2G$E:4MI. -MEA+:C[/?M:^O='>65>PRF>9X^@N1)S;#= -M=C%Y[A=A=ML58^Y[Y6A8LHU/8.R[9<$1`8XX(R%LR$TGA!ER'$*!)RJMF[BN -M0-^CI*!.%>[H%EA+:*`'(Q0=O31*^Q&9G"`WL;&)6_]?V4@X0`XY)G-&93AN -M]*C\^I6V-65;V7.H77\`L*-`CZ#!76PCCNZH<'ID7\33\,I*9H&`?^=Q2_`" -MT0#7]Z1*GHLP%L\$`BC6?Y!XJY#@/[9I66?3P.1J$CNG%K+^-<_@Z3+1PL5[ -MP783?"Z=4THC!/E[+*2R'EBL^;LC)E0@G-Y,<(SGDS='=5DF'!T^((XKH%[_%/T!1L -M#O0;:< -M)$P+-FR=0PR;SE[:1`B.?'OA%B>6(2*;Y5+:X/'!US8+Y"?V3@RN+F'YN7?_ -MUKZ]:\.T-;\27*/](M@PK+Y6^H*-"U-3%"&:RN>Q=JRP?LLKA(*_>.`FP[!= -MEG6,ZW)X9UUEG5^NFV/3\HD9NT@)T5:9P+C64;*K'L=HE -MON:F/$-GP1Z9R:JR-:A]>$68:^*2>Q*CV':&KS3V'MRZW/%I(/A= -MS?N(+4<^,WI,PZH>(OOC\6,[9>(\`B\=19.8SA-2TB@V`?5ZN%JWTUU_,C>_ -MX4KE+O`($X`E]#.)]-=B!.U2RPSY;?R%IA:)>B&2G'R,S\>I'@\:K)I$CD`] -M3;;&52OH-F))-<]-`A>4Y,A8WC&TH#X+]^G%U)2$+K -MV8(1);A[\4"(*`?FP!4#M8HX.].O?)%CUU"&]\A;:$)"`EK)<(RP3MP6R0#7 -M8OCX*R3G-"DM9\99^,W/V)*>8., -M!,AN?F`/O'A`C$F*GO&:ONOW3*"U63YB[=_`G>)"EDO_;*(%@Y-[F])*T>F)AX< -MUD>=2I\2%U?;^*W/E#5+[3JIAEP#>UPT8U!;`Q+.G(FS#Q0.5)&1CQTQB`/% -M((!^F`)D]R-4PG]K_3'K9E(C4GDGX&[G].]G>YJ!ZG.=5N^@U%_RNIQBV"V' -M@\(JMRF;J'LZHV2,_S2I5_Q/(6J&;@ME:*5[8]1CUG\1+.B/YT=Y%IQ%)G-( -MSZGMJ-Y$&JTX0P`+P/3T -ML)SG?**"49#))[$SLV3FJ,']5$7;SO!2@0311B$YL"$P&)4_EK];-PV!1YM$^JCV<@],S8Q%*][T45K(/,^%>J(\X,`07_<3\< -MPY/LVX?@/#T,ZFYV>,@R832 -M]+^-+'M4WB6U:7%%1'>;N^,0,X>,82TO>7,$.KNV3A,XY^L`T/ZLP)BV[V0N -MA/WJ,5,S*O"[8_Z-@\]]21X3ZC7RN507W6OO+!>IZ)8_8K:#MNZ!]@RL>^;8 -MQ_^4$6";8U^IUW"HK.L\DXYJF0]PYDCW)]N#`AYPKLJ5-C[E[TE^GF?ALS\" -M8*CV.$US$4]*_Z!WSMZ#LB1TO'V\"FE9020BV1ULBR*U>=^$[0W)R*8),T/M -M:5'LT./.4*5ZXTPJ-5,W1:N]WLQ@(6A4[2LB_7HQ@<)#FI63S>@Y"NL -MHD'&"DO)\[P\ALH7CIG!%,YR1KU$[9I,U7R>+;)O9OW4334PU+R6ZV);'"VE -M6V*R'%O"AJ\.O.CV`_PY+Y3GS+IZLXHD;E^5.3\Z?,;RV,]1@YA""\J3U%<* -MDV.PP*OKMU`-##^F3EO6,G/_1[3XC,/I+I+T_1.)3";R\ZB9">%&1L]9!]U7 -M2"T":*.\,X.+UK%WJPUO`Z\A],VN)XDF#/FS@P4EG:"GOJX7"ZP1\<^H#$%D -MKCIUD0>,BSOE'<5@!@>TIU3[F+MN:@JU9K\`[ARU@!@%;U.RDG=RO^#][5J] -MR;3I0X`'?/(%GH-&=@.S$BA\9,L)@;Y\!WNS'SHV;!FK!&X810@XH$'7[L$A -MT6/;A'N$&4DO6IN2YNPTFL$<^/2J!P$V`4Q!!:#_/8VSWX?.PZ1_R-6*=2E[ -MX!%@J/+'B[@'4IRYB\LAE9@7V0J#TG4[9/K8K&O*!,6EO[JV`"`.Q`XRCLWN -M=X\IX72+?P%OV^A%;Q,&H,"-1H-"=:D0A[[SU6G$I`>M2N=@6\K',.G7,^350[`B_.:1X\PJ)3R>%E+XINGGY^. -M\U760Z:-M_U3=6<#U5++7'*W(/WN2@UBT2A;@VRMBQ`TOTYY,_:1-@L!,9'7 -M)F$%H+K=`7!9]A8,KEQ$%M-1W@E6C?3H!29;H8&F_#W]M"H%7FFJUKM<\PPR -MY(-FU5AQW<.N/@^9]![FO)$99$(.L>*A80`<>F795T`G<($&:^C!)P*)K,%] -M^??6A0@MM=4STC5F)6:"]V3O:,QG2&A38J#;P7[5]%K?.7`5MMM'/;7E=XQ6 -MR1_ANOJYVS>PYT`5:T8EE2O.!#0;@TZ6;6&SJF,FA -MN08H[Y6!(,=Y\5UI>N)A+7=(KW@$HSWX6)+&R.%11'`[WAJUN%%(AHVK$X=) -MJS+<_\Z8OW&0965%+B`TXM/4T-3/Q1>8V;,07(Z)#15(=K)ECH"1=4?X?+4. -MM$^<87$BZ`R!!&RU[5S'GS0%]M2\*]U$I&1,5KS,#%X@65AF&C(($]Q0^G$6 -M"N>_6VQ7]19"O>]X]YT%Y+'KY;K$W\.!-]L\7-S^TN9?#MR.#A!2^JK=G.Q) -M%[N&R\TF2[B;/B*>&,DR6=:.C\DWQ<3(.3U?:%EB%S/:J7!)!@LVJ]/`2%-Q -M2,%B;]YK5RBFRA;ZIVI)5`%LO[<]#!;)-2*\_OV;QMUA.X"`>]=S5&_Y%&_[ -MD^[&T;UYFF249F#[B`M7#[J>TL_/1&4QNYNSJ25D%+W5#,G9)*47Z*4OF<5? -M_=AZ#1&3SB#*+-=O[3C>"F/HQ97-K.31M@B5T\P[W-6/O_ALM\&Y$?K'^VC[ -M2N8+:[^@F,Q1T3",I-^<.K>`@1G`;&Y@&=J0,F`7PT=B;V1RNPC5^)=J=XXZ -MG1,.G>JSJ!N,D_85Y#NSQ#%^VDS^'^`))"["_.L#JL:Q3M8;8?58J+,QV=@&AM,:3THYWFK?W8@Q@P99*G,0H/V -M2@NC#_3H>X=N"1:=MOF*/GR+)]-&E)(=5U1\T[?RTA2"1>:K4!T%I>M=[!#R -MG16C6ZL@%;&W'1HM!W\'T4X=.T]V>+JI"0`CVO]7[1'&:J3HL\9;=)!O^\<5 -MM40@:A"=WM+"*ED0!W8Z3J>-FQC[QNSA#D4\:S"0FZ!>*4/."_<$AI7'P@'- -M"Y*P$R(SF:S.],BKD(L<+#8QAR_T88FPSG#R!ZJK.NC3B<&62\TH':(#MS9- -MW#,LA$JP`FS`]*S;I%[%7Y]72QH/5'[&ANLLF%@G=_7S76@\YB'JVZ&YXL@: -ME0$+P=P:"[KNE/GTB)/Z9:S7+1(.J9;.F!X(S=[N0CW0%8UO)@9UQB*'9=/' -M6N*%C,?#F\+QSFZW5Z8/0CRISQFEMIC(\4O$[]=77=!.S`;$H6HU3'M789+_ -MZW=5U_W;0MQ_'_ZC7MHS]C4US6:=AI5XF* -MTV7A(_4F(5LZ'Z"4=2FH/)1JIX!8^HQJE)W2 -MG'%@+6:(@B>EC6HJV7(\[1UWF/0J-T3(N1W4VRZ6"J$ZMW'60^,PY4=9M3JH -M8[8@I)P0DN)+_Z50WQ(A@-F8#$`E4NS-B+0IICI0'`\4]K%!M -MC=E(RDH`W59\%39!LG53[*'5'?5-2;JN&:,]T`3]$0PT -M*07*"::M/KU -MS=NJ88KUG+Y'_I9`Y+>(_QA*T8HHD-P!$'HL'<(?VRSWPW?WWCY*6:N -M!2@GXG+X?-\GJOT;I+BQFB=1='*"!VC_ES1QM(&H?QB)*7F;!VX>L`)W0$K$ -M/CL#"4`RK,D'2O-@O.CZ$4P1Q6[V6XKI -M.0NC@>24RZY<&_E\K;1!B"L'4QH8SDS/*>R$6*N5U&CES=TM;_\&$DLKS.WN -M^A+MG@`Y'N#V\H'BKBJ/0SN34NQO588&SHTE$%."J+% -MAIBU_,WM?*EL5@5\JEMK(8SI+VRRXBPC2UR5$VO7H^$$Q04@08F@'@?"\7V_ -MEU1>R.8BC4W9>QT2H6.8;4'_"3%[?(Y9*I.X]&U1OT+5JJ"_'/+C"?@71H2K -MJJ2\M7*G*P]1:X&`*>+'`\[M_J^]6+M^C?8AWU0I"%AQ$$(0ZY(=<<1Y#)-^ -MX>6.N73IKY_(#\BT.^Z653($ZI[O7HLC,L'U4TM"Y*[N:N+XK(FX0:,PISM/ -M5R:=6JW66D&75H=56_3],);6+7&55V4:NAB6]=UOH//;OE02;.%TFINMWBR- -M$&N%&]P*A$VA3Y//!A&#XK5-DKRO##@.1G]>-0_"D5B;$4TP.^Y(O.`_VDV\ -MJ@2!L%<&3+<,6HI&X.FGIDUW1V\W,]IOJZL?&:]ZLDFB!HI';CP_^VH!1*T) -M[=QT&XVY&UZ\X1[X4LEU@D=YTHG/]?!'V75G@F51,%*(QA$>_SA77P9('0O! -MG;ZXX3GC",0?9B'!!>DVNY!Q*;D#;FV(O?.>4I:!?27KK,'0CDDP!-D@YQ\K -MCX@LX>$WN`;\O4QM1C\D+("/U;^R#$LQ-\!GI1>E^`;05X>L[#G@8>'8_M_R -M&>Q`QG59.6%9QGHV&48;#P12FD#:ZF0DG<[2N90HXO//+PP_`;[7_;A-0!#6 -M/YT")-O%)8;Z>E&R66[N6G(C06QE;LJK4%V,/A2*RZ`O*DZ4F8W-,)[)!]L$ -M-ERS)C\R.0HLVLZSUEPQ=!P4-N?][0,YQX9CS0>-N -MT;G3"=ELY8Z$Z]V&=[XUP>SH0U2S]ABM3W:78U<6,^BI7/.\*4>/#;8HS[E/ -MVF^RV(5#9Y<6FDV1J#V&Z("$9`9#G40?@NO?Z\2VK#S+VSDT"3;)VQ3U)/?G -M02*<+LF/@QY#FD*L%6:`DZ:OF;&2#"EA+EO$8E_M,Z(D.N -MH:N20%H'8KL)P\';QCZ54E%27#NLC2HC1\6R,$^P][JE,H(#(H?2?=Y4Q#@I\8;N8FX?_HRPNCIPG$M_D-IA5?6L9==5NFLDUX -MU;L.!/ML*VJ(EP(0[4D'^5AZ*[`VU=SC]L0K%:E_H>(B]%^%76A[(X3)[':H -M=G3_UM^,SO>TX_JBB2-X90?S@MCT -MM))F.P]XUGTP4AE(M5B;%[0EFXG,<:RU.,_&>!61NA3E#!.`7!3->O'R"J21 -M<];5SYBCU$%F54%)8=G\CK:W-DY0[S=V@H!L+!6L]H4>Q9(TPY`[KX(;Y0\% -M'YU'/EH6F/SW'Y$TE7H#\>)@^YZ(>H6#'V.W5PFN$&/',]-+PL2HY3V8U$+> -M[;>.TONE@2M6\<0*^V#L*ESXMTQA+CY&?"OL:;'0J\`F_73AK1-E1&K][=JN -M+YO_4>@1B8 -M:?1Q-E?Q9733X\)(9R+%X;YUCV7N]`?#UX=ERTXB=*QTX\A/]\W+647N_4"' -M8B>J4>1D*$523U)%NDYY0\];,#M03MZ^`TT:^W8W/;,<(B.>]!?*%\HT^H1D -ME\U]Z$T*SM5OJ,+&*!QE56^.X?RM4AW/3E_&W/-V.7`<#.H_D#L9(&FW*2.Q -M.]E`@<"N`MFT-9R3S]3`)CU=`8F07_7F]"WEH-0DN,F`<\,7#R).`7\``5ZK -M.BABYG-N"(HA'ZW]Z$H`%19/1SA!RJ"2!\%FZ)%B+V3=+3R#;8:M'GA]&._2%YWXW4RDQDUDR]M^0."R>9VV`#9\"QQR1K#!.^2-KO -M7VPQJCJQ;_60GXH -ML]XO-S?]$83?)S&D=*:Q;!@'3="(T_3!+?FLIB>I9J(-(:KG46&\MM(]L?B\ -MQL->P"$$41[XL$?H-A!P3%UP6K([-V6W%(L`SU>G^#=04'J#CE]`P8 -M^N+K[HZ"SN/!59,J+L>[FU+NN$K)UY>#:@QSUJ@-/0RA+K=%WY5VD[*Y7_7/ -MM$,L>D%6^_BV!KDF3MI_+`N4B$'#!`0&T(7\@]V>N$QV]KICPPAW0L&DM'\\ -M9!J$CW[U9JU(S-T4L87<&2P%[79+&A(;<(9C^2"+^S(3%!"4#1A2'M5R**)^ -M:BD]EG.'V5(INUK%]Y3A7>&],Z0QI:NWDWNINZ":T>'*)3&T&K'3Y41'WU/+ -MC6H&XMMXSM),%D:Z2QTD?.X8X5`QME\(4^?J%F,S[[I2H1_U@(2I'RFKC-*" -MAGG%&'Q/M)M1L^4K3Q6$*GC,B[A@K3/+EG3&OTBY6Q^/C0["N;-J6Y4[P=BQ -M*DF&;D6P,.-6=4ZQ;K_W-=#;6/\K:P6I/`N]&_<<$A4V$8H!L)%)85Z2L)\O -M`MHU?JPF)M]Y;`7,PUON2X'E'SY43S,R$@L'!'>6EX=B`6\X8@E?V#GO),K: -M_E??LA^`/<:$AB.@R=N6UD,="^XJRF"7XMAHS"X/[RFGZ6]6:X26 -MSX4)B)>+-9OS\:,ONTZ1UX3;W%`I:HY*0(1L5%(;#H!QLP:J:Z5J!%>)2SD`4! -M^+EBTV4.#[J&RW5#N#^%Q3WV.AL9B!D^BY`6A=:LFBJRYY;=*$\L0G/5#IE7 -MQJ2`YO2C5<],AA\251P6?,R3XV#8VP0Z&BDM8*_".-$9M.(R\_AI\WM&`MO] -MU'_.B[9=9#Q+<*WS,N/*,!)'#K'%<@25[G4W)/=4WH(THP^1T"G.V!G_S$0& -M86T9Y4C!]$ -ME9G1O*SF78W5GYXY9S+X45Z*6R49XE?[Q'ZDO -M-?6PZ4$_F5&C86BXZB\\Y1M,T:D)%BD,,%6V%(')YX%J7&CV+DJ0UM>DSI$N -MD#!^P4H*W%%ZRP#-W_E<5)+GC\(!`&00@_16KBLZ`?2 -M&61J\9KOF3BHHA/49CR-;:TN_O.;USQMER\"XQ-+\01G&=V%<.!'?@'N/;+- -M/6_LDP5OI*3?(L=`7*%M./F"+*C!'[U,3-/*MS099NKO4@`32S,(0ZB!N*9Q -MP!:F!B0%ZFHF8ST\2`.TQ*A>HAT33_U5_8BSY'C=J38E&I"/-9[^\*"C-<4>OC8`M0'?'J<:RU\YGH3+$>G5K_OWZ=V.,G/9N4?/L -MUL)`]DK`G>6EZN9 -MW$QFR%8E_Q1VB%ZU05#GAV?#HNT!N1=:PF)T[$<"0+]M&-3M_'NU?2_67G+$ -ME8<(FM?6T?KZO:+%T1KSQ'#J(262T:U)^2P;[3U.X!9BSSJ%HMGB)ZXH* -M0F<1'/:B[+^NQME"E+UE0>0X_NNE"(34)XI*I*9!5'$4?QWRVV9=+)3'=.J> -MQOYN1?/1;.-_K,S"QLZR3#I/(?X@CSZHK?ZIHLG1+LR?#V^)>SJU#7:Q87U? -M7F!QG"2R/:-47=O@N3MQLNL(QK&->9$R=<(Z$)4QJ#FZUE+9*!&:WHXI12WQ -M-R`E*"\)*06.V%1&0T4>B\63"K3XN1$5S[AOC?B%J! -ML797*ML7$G>E])VTE@C,%HVN1%K/Q$8&T4.L=UTST]O/M8`]]Y`S.RIO7#T! -M41IX_KA(&(O^A&R7-6<71KR\Y.^_>"B7S!F9S>/,J2#$QM6+6]K:&NW-)?>] -MSTGH(YN0+L1G5P1Y&%^_(9_/ZLCU6U@.R0L=^&&.#9HJ;G -M(.EDYK\(BU9PI_XM=H#=I<[4?(P5\0G>Q/W7311(]>2+ZJYT)(UM8G4:ZPHOK;,I89@E:4?U?-"?/$"E=-8>80(?M\@FIS92X'GHN(T3D),(M -M!9Y.]8J`)G*M>K!.)L:@_9$\=8;Q=W9=FQ.@OM1'IDP7L`MGL3\",\6EINQ0 -MPER:$(5M[FO;9HVAG;)@OLNE$LENQ^5<%6Y,WRF-;.`BLODNH+)ES[NHU('N -MT+[L0CV;P_%HI@U<^$!<1*Q_')3X"H:,XN#)3,<=5_B-00.T?GJ4A]"SYE_1 -M__E"]QS@IL'OO0E5Q-3$Y+3&A'^M#<`5,P8K`F4;5RFEEC$0.#5F@8.URN!] -MRFF&LJ?]U98#B?0=?31F-3IDC&T`3`:>F-5$@T,=ZY_@7;U^)`$TRHI`$=.' -M3;_Z$Y6=3:5^#WC2Q!C8BX=E,S'_/(2L#Y4''_[SW/6OG=4X>#8@R?N#AFS3 -MO@(>NZ[]UT-W[;Y]GP.B;Y`H$>?II-L=$%A9)IFEDE3@2`:0XN\X)#,K&)A+ -M=+;.;J&?$:X8'_+A?!.-0PE^_"@%]\#K1%]6UC]P0O0!;_TLGUI3N4]JCU\D -M[_(];:Z;N8)0?P>>DVPD?K#"+I6.TF[_)%Z8G)T-S=!!=<9%)D<&4BRBBZTS -M[@*[$=2W_:9J:"V@C&=V(1L>ZT\4+(=UPA]@PP#GAO(<^;;LYJJ3JO9&I$BP -ML,HH%_0S_D*:US)'\Y[K.EU&<61J*`6+?-_S<,\$`-FU5S@S#CXM$I&2C72:^YF&4E)P]0559#^(0:YK`V$>'FCE3;[\-YSHNS8=N;?0-J;5$ -M&'="N_$0-/S`Q333'I4RPNE<-7MWF[2W^EE'@?I:M__H2-5]T,P0 -MT-8HU6C?WJ<(@)$N2-O"<7*/T/\=27#ZF132"`>5/ZKTF0U6SLA[1PK$OAG' -M[O+F.,CFMDIPQ.!@@:M)3PM>B^-K\PV+2)R^I3=[]LTQH-0`!^H\;DMEY>`L -MUTI\#B9P$ICH8EK;C4VJ#NTX&EJ'&?]>[H"R"5`MXLNG5%&JJ;&'S6^P4X/2 -M]?)(SI?*G-%3;E1BS4*,B,>!ML1A**^Y[FRK"39ZM*QB8D=^.NU:%/XG[R(" -MD7.(!6<6RP>I.7``84&CS.3B\CHD>/]RS*FW#Q'Y!9AZ'OGS1E<^H*9?;_RJ -M_!BA4+*NX)R/`E7ENX@YJ:8E+^2,5``HYO\JN!))%EM*'77!,VS,T=5[V)O( -MKCKR*3:.&!/9JEMRX&8WKH.HA4JKS.V)?\Z#)G6+V6`?/:Z/-_SEH&@"`!XY= -M"A1.^OF`<*,$'YXP@=]D!RIBU*N_MYN#7&,&)I?FY:D$0JD*?[#%;Q@4G(^? -M$F"-ZT;;O\[U!L`@V*KPSBC@=IA#>[N'?!MS7)U3(_(/*E<-[G!=CN\;U/[4 -M0;NSN36"Y+8L[7E^R4ZEUM(E\O?;:%Z)^*QNXB%D5I)#/[4ZB.WUI#M?R -M;(_&UYVT)H*TX)IDD!*]/OF=>2?\84"XS\N01\"0__"8(O=1/<2R]L5ITPV#V]#A3XR'KKJ4IGR?![ -M_E!U1.")[Q0T1U&+*P#JA]27@)[O6IGG@O31EE3>_S8EF_H5Y`NMN*!#FDW -MSK&*=K(.)HD_@CSLB*'Y$K-7`*B=*$Z!S)%)_EFP`L(?9*0:A3NO(UU$K5VN -ML>1#N8W?YF)]R4M@+R$^*9>Y1I_]#H_8#9<)#38:NAXL&.QDF3'TZ`2`7>VB -M5L?^?KG@FF>"$YVI":Z_66!D9`^;?B(6.HL*"48ZVO07?PO4Q0=+^%2/O#LE -MJ70>NUC9$]27^CN)AOW":WAJ-$)37*D-/"8!$MV5&Y9^?RYC'XYEX:-.LN#8 -M'1YS.ZR(,7U]?[62V6WJ?!B"RTUG0VCJKADN-T47P^E_D6`R`2(&NJ,$M_GZ -MFG$RIOD%JT,5VP]B56B141&*C>BW:$M[5C[>&3)O."V<\SC -MN>Z\;?X;U:/>J5\0UID8&=C`L.Y*(*N*!:>\(\BQ0D$%5.5!"II^A8IM6,OF3H"HMJV[DR>-F88/ZLMY,2G -MKEB`?K");I1"._D%E>['V[7>>9V1G)?IT9@S@H>.+2X1^6C"FRY4R&P]E?E: -M'!X,#[[Y:1/+#183:\%ZF!SQLY1=XG!@=:SW+UI?3$L723DX2^5X? -ME_S#9K,U9K!VG.=#-1!IW_I\J(Y@=,A&W>A=V8!X@*"K:;TH*"IVZ086[W]D -M,]F1-`^DN'(2@9UD[@U"JA9'-F+Z\#?!#PS%GEM#ZO(X^EM&P5/V:A!+.5E; -M5>^.\M=>%7R;#B3FY_MKK:!NA&MHS.8,`]H2HZ\1#SPM#2_M37*LA!OQAL8_ -MZ%271L^@-X]?;]V=P$]#L4*:PHIGNQ?,%V\%A&7&F(ZUR\DQID7,UINU4)Z( -M5=M!0"UJJ,I0!UCJ@D:>PJW:5>AD2%-J1-'Y\>"*3GQ;HO\)8_9MX(YUB%=U9'*D8VCLW7\R94:F9LV!Q`K%M0JYBD6<:,=XL#V8Z6+PPR%C:/T!P.>9NG&A -ML(T?>FOV*5G^0G);9H>F?L"`?-4[8>Q>CG"LS_5`9K_DS;2Z)EGUG234_1SW -M\&(!#A0).:B&0#O+.YCB]E?1,`;9*GIS7[W6`:,&`#!BLT]\P8 -MNOJ2,3_CVN>X[E`1;<;SK>\N'A+#]E_4[V2#UF^G$@,XDML:ZCSJ$N`I]EOX -M22E?MO$B&YV*5%/)HFK12%I&=2^K\:5=ZRA8"11%0@H9%\@/Z$&30"?!U4-H -M+;>HI:*F"/A,:*@3""?S4FLCFL"W_?%U%OP1?@1X>U]2K><1("..XT@<8G?^ -M?5@6DL]9-\*(T=J;*8`Y63Z0TT;"`ZK*\ -M^X=ELA&UH9Z/AJZHOW!`76^N'V9!0PO1HF.D2Q_4F1ZKD>S+1!"4_R>WNZKL -M2@H\:A-OY6RDSR5Z0&$.MZB-?OS!S%*EGP'.*?=YCV!>&3"N"657G/A68;2R -MDO+'YQ="XY%``=*.]5Z#P]:]H@W!/X=QO3"J7K-F.(TAGR!_Y9>89#D.J_.T -M)BQ@;%.&+V=5?R08I=$8-(*2W]:ZQ-* -ME?R(K)\)X=SN#WJWQ-OU60_[=AJU52F-.,S&WZQ/=*XJ?E'8Q]=D*A9<23/8 -MB5:#GWA/Q,?8V/?#5$,'=FYF1<[&]HY93']P_%BN5GL>D9*^)GW_THRWK_QG -M&.5"9)C$)R;PV#?..\GU*2EJW`:I)R<]#3O8DS1H&`F=F3J^=Q'9$QP3U>LH -M(GB=Y2PP,Y@#QP]@A58VHM1>=B!&F>#\YW212[G,DH;TWRNCR"ACO$RIQ$6< -M"J8PK\=V,-)XHZ]8\<\'M`1\,;,4.DHEWNC@V\4S_59QEZ)UPAR;/ROQ`;6M -MS4PY/OG\A#VDA]W,2?KMB'\%#!Z\N60W -MQ9,=&OO_8JB2P0"221EAMC@DA^77LW/1VR((90_L&*&'R0`24/(5,A_4Q,-G -MR"J!Z$(M)OBKHO2#WK1E-F$.AG&"F8`Z`4ZP-_RG":O08"@%1UO.XZJC,/53 -MK@J/OC(XEOCX;0[ZYJ#Q?.%^6&7M2@JB3R%.ETDU5>P,"`:PH0&_TF8/2^XA -MY@%M?_H,U3-*"J2M\R0%1%O[5TZ)J9%KKI5)]%GM+2U`Z$;.,II&R77T4;"> -M3IW),EHOQ!12I;K\?`3OXM<555Z!WO/:O\ISV-H;_U,MG.2*.O#J,[9LYB)MD\!82JQ?6:7P6A:L&%^S[C]G*( -MH9D!TVK#[C$5'(K!NQ>04_1PPWGT/I5^AA5DP-QB='!=U6SGR0=)DV`1,>A6 -M5S;J')Z%#Q;Q)Q7Y<:WQ7Q*$SD1JFA]43!:+L -M0*^62Z7^LZJD%`$)!PUU$)GF/!;"`PY,*]C442I*YX2QO-X+F^A\T3^9?JSX -M[4G($;?*G>:<^VD9CCIH93AM6[X)'KM9["#0/S&PK2<6EB1O,`MU%'`HSVA: -M;@\-,F40"DLOTX3T868=X0A9%,HLY*8V#9_P.\Z%"J\9*$<&FW1)NVMZ'Q/& -M#K,7ESX^`Z+BA(Z.@&.!UCT?8ZA.#B#=Z^LOR.ZL=^U(57[>.L&8N26N4^@P -MP$L9B"=WIT)2L@R,U-K1`%M:JG#\T6E?1.SV4`HLWC!$1-0-'#WWO+&I>6": -MA%+``Y=;4?I;RZ7"[3-=[UC$2_SE -MBP'OIS,'%XP'X4W!1AZ:@W$Q^[G"5(S7=/V/93S<'L>_`8BU'7G3&[*W3\P) -M>;K7-W-A%7V=%\R>O.+^RQ"IGVV^@\[VSG5__B&I=*STC(.6WP43SISKWU;& -M2R:3(].0*M-<'3ZM"M/\X`+KFJ4&:1';B5:-6OG\+Y=2TVIUD\@@>BXS2XL! -MQ..P1Z!(2F]1L!TUI/5UCTKQI>."X02!%?GALVO#9>,ETZ&\1[Y'W6MOR)R2 -M1IL33@[1(T4LHO)!,0/;34C2B9%M,_-<\)7MS85C%?9(Q%*LA:9N/F24T$0[ -M+6[)>6R1CAWA7D&1QJ^J/)#P%MI7VT*>99)^;X`.V -M*RD2L0WUT$Z%#Y01/N;@V0QT&5A4EMT1OVFQAMUGEH4?6O*5_N86TP"8>4ZJ -M59=.&8T]OY<[VU?8@<\">T$5/XS3(:!4R[G9O5HYJD6^-'YO$R[HTV!R@N8Z -MBE;K3;PP#94M;=3]?8`_5LO*\GHJAD0FEO96*3'KK:<>:]-)8H@`0)! -M"$SSK;6*N`?6SQ!'GG=Z^*&3Z?)L\GL>/AM*L5"[2<`P`718@[6@*[`,5`?[ -M*U?UW]VA&.8PD9TQ9G>>J\G(&P`D*V(-KK4[Q95;;]O$TB=1@;+_ZG@:K>E? -MCL@AV4D$,972#WK/U`=,6\)3JSP+3:+G%`@T@<(%(+>&DX+%(-0D`$FUCLV_ -MDAS4)BU2L_0#D&A;NC!*9`V3X8MYXD`SULLM^?_B04-!50ULHI?X -M7T,/F\/KT;LOKQP -MC<7\H.G:B>O77CY#Y@YWYV27)$=-T4DG`0?=;$`0'@=#S`GOR>0#&\^NZU2T -M.VSU*"C8<6!X5G3#O6I.7E'3>>M2>EY__?BZ]6//,W3DGS^:$S<$JE`P[W2\ -M^(O97J9VV^UX1OY`1_ID6O1["Z0S38WH?%B'6W>=<1Q;J/CO,Q"ST!0KL)DH -MT.4A$I8"XM.(S4.VML/4813FC4UU+B)<70A\RBZ$S;^TY-BS=T$8=L&`YUIY -MRSN<(4;RE7M2`]SKD46[?A6K),(,?*?Y6NJH/T<=R:9-9A_6!W#TRNV?J4@$ -MT)700%=%Y9F,E,^Q5;H&<AF\B -M&(;B#(<(>H?.!C8V@&:+'WF#S[F2^VB`,JNVM5VGC`3@F(6.5EW;FSIV66&R -M$@*R':="^V^UF,.^CW1*=9-5[-A6W>IJ8<=%?X.MBV@#Z!EPR/FS$'(H)+0: -M-WUDV;AVBA4-R8QW`$E21*J3H%@Y.SCJ<@@,`,S4BE`IY-)+P5MIV]&?7A^< -M0?34(5T7&Z@G_K[=_U+J*T]0=^6IA+TB38>743JM5GI^NY+!#XGZ"*^7G[X7 -M01'HGH!QRX:_>AXGX!F6,>KJ!VX)M<$N;:.*Z,FAU7C"@Q?C._M-NND*)K9)A%>$(+H-ST?L;2U;P/2./^ -M.+I5_,BP!2_)+M4WS4Y,AJ7[A1H7*&,(E"]C;D\*3#,L)(9"?*Q"X@7Q"E(F<0_\+'"+^X37< -MPY$&<@61(`COJ-O.>I[)P%)B>$:W93UTX]O5?2->V:.-19H=`G'81OL]TW@"*MGX%,>.$+++U2HEA>YF+\[W=EBV!;X$[V\E1&>,5 -M>R`S^J_4K&@.KNO`]5]727E:JD@PL&:!Y -M4_DN%=O!"3%PRG>PM`KP'4'"(_UWBY,)<\.4K!7"U4(Q?2%U1.;44HK$KA@5 -MJ%!:>^8C`O5]C-<538-L!:%Q8XS6HS@>7&L<5TV1Y/^[:M#90[_5$28U$`7< -M5[\%M6]8EY_-O'/T&N->R4"3$UB,R'?,U0\1]&BKO=XZ3W>;&L#C,^8L>9_+U60:@;(LXRK5)[3Z>CQZI -M(!$[CINE,IY8\#;F9&0$`E"$ZFF_^'J*F$)\DT&8=N&D3J)/:H[8IG+4T+T5 -MCIM%6F,K``8V"D?0W)T1MI -M3H^4C+IP,P0RG:E79'4"B78]Y&UD.RBX.]CFP`87WEHG)3`"[*R6\VZ>BBH8 -MMJS1]XQMU]NDS$*[<236U*@VRK%9"_<4Q:75TS'SN:`U(3B,8S&R]&;F#G%G -MV?(J`4_3)%P+N:E\B26$^_M3P/I!+1#1`RM]@4-I6C`ZY/XHL'>799C3WXP$ -M[6045X8'8.EU\A1#C:CLE-"?\#+PB=NG8#G+NE85O-UMWC4I+._Z59F1*CQT -M^E6TXT94/RQ6-.&+:ILB(GCB1H^^T^,'UH8@%V1K5FS"8&T":9QO,!D5;.I0 -MD"^2)+LS?P>Y( -MXN$JE8'N*D!C2R)\\V=G]W%3HDF1CS7Z1Q[]3^A5Q=W%#>,>A:"MDV,E&>5= -M3ZASW"5R=8AOIS5%N0VI&J#0W>N`R;C9_Q-8XE.A]*OQ.7ILG.02-?R2_EVI -MC0P.=U3G:T(Z;^Z5P6T)WQ#8EOP&$OXV#[?V9I`NG*?!U;K]:E:5=?`Q*%H2 -M*_F=I%I\0>/=%.:CXS%JQFY`9]P%QJ*@0&P0.(]9O_E@.KV_H=V)P*Z]''(L -M@'JUOXHOH7M,ZI`=AL_2:=,!4*$E5Z;5;Y.3//'$`;Q49]-"3M?T31TLG^:] -MV`!\)#N']H:P+!A'E>YHARMR_EV$5-7Y$8MV^D>2-9K5:7%=8MB`\\Q]=(-5 -M6M"3O#\ZB\_%Q#=DX^JQB=:G"-'=V1<,6?R6:_ND/I*X/F]W?"OYDG&N9Q/# -MM(3/N*<%1;]W=+`UASYNAWG%Y4=\?C<,4CR>^R_WL6JPH^4VR91_MAFI!<*2 -MQ.SN=WH'%#7(:S93(3CC(:W,GP(C?N/$]UI5=!RG:OE%)KY!XOR=C/EVH -M>8`#PA$9L9EN5P -MWRJ<[@N=H_(='C@LRXSL`2Y+NKEAI?$Q\89)YNK9?.6/F!,O`MCQ>Z%7U?'#1FL/5=U(&0:WLKMQ02.$[D,^, -MV29KG'%XT>15[4^G(ZHIV;5ZS"B]'=TN/G3FU2%NPZ!2-5:M8_T8:FXRZ4%G -M5Y99X?'%R7^2$&2=G"*CXX%/RXE6K4OA7B.&"B`EJ&Z+'SI"#IHTE&IYPTAO -MC?N.P4!X96!?B\BWVI65M7N2MK*RP7$8SVP7OK/AMY(N.ZZF^+0P(ZG!?*P% -MK\L`C(QV6)21/H2NFU8>[=""6#RD;M7],?4D\PDV,JL\*U. -M_6GVP7EB_;&P2]LGLAV2HW@""!*YH=5`]O23J0:IT7FF3=BCQT,TS2%T#LHW -MR@FV^4(WT=CJH>)R2@(M*J<(WDDC43#(`SK@$;0DL4*)VWR1K[G7J"M)P^^L -M!M8CH?:@]R*;&Q\UELINMJWX;!2?_^P,*G+)Z)/#]K)N#(KX`Q;SN`M4LL>= -MC/1L^#!,\3S?\IQ>,,0^<^ADCE:3Y4T7[>8[WCP!X_76&G8S^H1URRH;#I=< -MW:$)DXS*7="F/9B3LN$:8]6*;#PO!8OK1C9ISM_$.M2()IA0]62FR`8"";ZL -M_RRXG`B)P](3[!3W/\-'LTFBJBX%0.>*)#4GH8@PG:;DP@F/G`'30'>BMH&> -M]3HEIUL92!2O9($'5_6.%8O$R)GX\#RG2ND`F1;)Z"ID4H#>Z\1HT8N+0U#G -MKMTEFN7]U.Z5:_^,E%UA):)'U)_^APY$]J&'U8I1HP8$1MQ[7/I5<7@$O] -MHK$\$8(!Z[2?8F9P52FP2H"T-N%&/EI4T@Z=%LHFW``4^!OPWLJ3&,0;>Y7* -M%]Q'HUS&C_NR=!TRE>S.1286ISJ* -MO4V94Z?,T9]*F%#'"+#O[E'/<:'3MZ]POX@B&I[3V<]]>SG?_%'6Y(L+52PM -M7J2V_4I65Z=7'*'G0)@P(]?7#6,)J]$8_"(["X/Q]A4]'640E42&I:"E+NZ$ -M;@4-UL6MDA,+AM6WK(WO=6CYL7OMLPX`39VWV.8ZCTNJLDA=V:,2M.9O] -MN;>'#PA@<98.CY0Y'YWAUGV7:T?D#XYX+U3CVJ^8ZN$YED1ACE"PQ^5Y1]/@A4PA(9MIA/V:N]R7X]C\#\V-J -M6.%1V*2?H*0@0Y7\'HS(*2:E*+L"?C;-15\)Y,$BK#SVC>XU"">S5Q`GI:`S8M]5H!,UWD -M6+"?L%T75F3<<-5U7(8HT!;DU@NDSS4]3)`X^T.US2=A6+(QASBS=$C;X3\/ -M"EZ":0TCI0_>VD"OY7'?%_NC!X)[T[IU.);=C>;0-&7):>.;I3L"AL8W8X\) -M97LF\%`K3E@`H7D'IGGS=*>!G%$[$+;Q#.X&1?WG"EB$85ZL$KR3:UC<**PN -M#2U8-]XC/?^LMI>VL=!VYGB%E)[M,)*TQ'!DBI>_$\*`>C7K6BKL"]FW]Z^/ -M%C?6K`I0`3)SP/CF[R])=WVUN8/O$A#:D35P%VYB;QI7XWPB"O@JCK"SZ"`U -MYMQ_ND;EW8MAX+@@:@6[?.^/*>G@>4^[N/;)0U.E%-#?_`;^1+IR>H>5E1TM')R%U` -M-/HD(,[T40E^`8;=K70*]![VC7K"X2RMMZ$E*RHBN#GB:HQ!Y<])W9Z+ZR%U -M6$B.C;Q0-+',SKFUU.6Q?N0X*HPC4UDN^5W52D1%701)BG+?\F\Z8)0,!>F) -M$._`%Y&S0[F,M+`N0,$]1.+8;35+Q=6^IG4I0+NHA'DN_,C5ZLG;BBCA?V6S -M:*32ME%R\5DEI$)]AGN03"7\LHS/_ -MW[!5=(=OGS1^E!7JH8QYLX$K"E/H?1R?DH3X53EIX2&\5>F.>4T53D,NZ^ZN -M4(E7^AWN/'+:MBI4=I$6WF?*]]>H7(0W,,HJ82IYOR5B&OCF5Y"-EJQ!8 -M^Y612[8T*D7TSNR9M[^N3`>U8\=,_>^`H_@'5P-&E;=OU;Q.AT:829WR0P), -M>P!T%IH0*>CU)@XQZ&%CG/P<_%I>SML74HV;B7C-(A#,1&(14HG6_RX`W6@F -ME>6UTWM\`\ -M"K'KK[2PJN`4'54,/=!S_B*="T61*%ZI"ZW1J,L==5(\BE7B+CE5F4KJXLEV%N:D4W^Y&40%F'L1AZ -M&W?+76EA^KQ=.-^E\';OU'NBDG1?!]S!X,!@TF!86U[XK)`7+-I$8^M;<3JM -MK?1HB#6HCS,W\&VG(VD/4I>/?*T<&XZ2&9WI^>+:NSQRJAU(S[[".-"CAE-E3I -MH<``N#=+WZ^0E;!W%15Y -MAR70;\82=<[(WEITB,P,HC_@H&NS!1!GM?]M;/O[]\VR:?L$3_E%%S(]_#)[ -MMO8U",*F;;$*G.TM!:WTO-2E"^0R\H'-PF#.0\F!I>B%E!CE![Q1!,';X_X7 -M#!6U&!_U[@KZ8RMK1F-Z!Z\Y*>AVV1UNYJ`1X^L)&OJ8+<[*V?0JUIK<'=WN -M&A`Z8$_P@4EIQE,8J1N1(*U]MO>6O_&)LQS4?*W[F&Z,8ZI1VRAM8,T3..!/ -M30(J.C@%>J9K&%@<.5\B;>5MWPD7@?ME[(ZGU5-K>"9)]D\6N&JT=)OL4ADM_FC.WK'07"-K\+XG( -M7AJF;&A"L5#`YD:]E0=Q0\KZAX23D1:;I2K(ER(3AX&`@J:GAV3KT:L+$VLN -M\P[)%SGLN7<[+\>4KA?*`2H/1VJ,(6C,1C*+J-I_H^SE,7ZUAAWU%MYG_`7, -M$=O2$I="__.$_B9>S<1/D,JLWW& -MG%"Z`SJ]F]WV8].\_8AMF)G4ONK0WO'V><2UK%OXW^!CT*[IL4M0Y"K&"F)X -M!W3QJNX)^A#[X"O\%'TG[$R%7_<@-[LG'E@;1N]*85W+'V'J5`1U<+]+>*H& -M(=3]`ZJUT,FPYMR9OV@7X#+)KMC[NI%?0$LAK@ -MO]X,W'F7DRN0B"Z]O&'T@I;JI4O]@&F`@A1T]IL?]VR6.5Z7R\&-N!0]OOAY -M\D3SJI+9JOZ"EZW-WV_&`B++D4%>(6V$I)@<"UY`.R2 -M9IRH^A-]FID0!.[][.ZD.AE[[,^(VUMS&D710"S]2U=D$$:FO/!P?IS3\>[YEIF6N?#'L:O2<0'0P_9N>7U.G!-BW]$W/:_Z>6LK<1=-6,]#V)3/DA`R6/!QP1B -M2AFK[VV`4([JAZP2M/@SOK7_A8E`F=%?3O7V8CP% -M^V:^BBHK?VVE&(Z38[`S32.X#*&*2>M!4FC7['*V9NR/6S)8DVK%+`PAG'AH -MS('NP%SG,&T;GZ@1YR3[RRK(YN#-=G?*2\O.N)FJ`D&35HY=VP&VJ9JQJF+# -MF7S.=]`'Z:/9S[]3!^3`S^$L('L$C+<34MTR$,J1B*V4A!(:"7F+)&1MS/QM -MDI&X@N39?R+$%=!SPU%>WQQ3G3K[LRYV]&R?EN`)K!"L#R0&S8_(SG@TU6BA -M:U;O_$@*3NS$Q4!#`ILZ&*8D=#7S^&;1\J*:SSHP'#A%N6(2%SQ;K;,\_?+2 -M\]%T>=]3DT!Z!`\RY%ANIO.G^<(QXAS,R`-^E9TM>>7!F%+45!D^$A5KA9=C -MUG:SA0-.?[KO:>9C5[[9NV`]=_^4Q@4UK_R0SPX#!:,H,O(&7* -MB^X2B1`IT>B^U*&+B.5F,^A-2]U6X`H9X*&;C&L31I;8>&<%Q.]9QO -M7G/9]:YP_0ZA2;F'B&?58=NT3H4$E/.L+8EZE)-S..A/K2CEKB1>H`S915C#=FXQ-G3B`4ZN_>32:CDMQ%7!&9!"J9:,"9, -M5S'?'/!#'U:"53QJV(O.I4Q/.F0.Z(<%+LM?UY_=]VY1F-Z^MU>I()OLRV9J -MO4:_GO_W7C*UVR8[$Q9KPS\LD7RX' -MR&O@B)8["LK[N<.8'`@%6_.9O$6)DFZJPK`3RGZ+@WT(M8X;^V@"R#VH -M_+0F&2D@10M=U<+DR -MV\"3S4QV_:X;FDY&5%]'<+]9TY+6X;&/N=N!^J5$">`M%MX0+1%R^6W&CH"Y -MTKQ5>[T'9N5MS*)O82S0^P;C(,>M>*AN7E=.HH,T/JV[]-_$"NBQ4GT)6B` -M&A'2)?]Z2LJ;WUZB'RW0LP$H%;B8KMP#--Y\EAB)FH`0YI2X`TE%I=WART\H -MY!.D5-*[ZX0+`^0?%!"'+X"Q-IQS1P>)4QAS@%]\:3^9"1)!DGY3`Z`1C&`? -M'"OMD^;#/0!E01`J_O/S*G$@NW"*M*TSWE##DDT6H_TCON'O5_QS>F7%JD2C -MB6VVBA"!:Q/+%!WC&AA6_]79$QZ<5. -MN0ZJDJM-<(%I5S1W`.15Y66A+0?SU8FDZ),[$&U'3CR6U0^LE(W8=[MC+0I'[#[6+'Y9A -MIN,O@/8B,A*'.J5*27&"[\%HI#I5:5B:"'/0Q[:9#P8-65TGKFTMB9%LO;@` -M[%-6T-\"BZ6\4K3WZN+EQY:WP/JYYG1RE,&&P+@<15X%< -M71`^)>1LUR\ATUDU9JQT/4E6A2=4_VQ$QZD%?R/^QQKTGPR.4L>UN%-P31"P -MY2V"UM/)NR30OC6](GT/1CA8'G!7)T,DJ%]A\!J8Q<'=9J/6*PA;V7P1%)3K -MTV>47$5.:V9SUBE$-3XH@"`8R'QV.945A=J:9YQ#0C3HS*<,=51"/6<8^?IXUWRS\AKL2CU-7$L%@CX2G#I&/`WF.["Z$N-/8IOJT'[XEAV.E.2W8F2V -M+^@*'H(BKR5#%BP9GHA5?^KP&R6/N%@`VO6CV&7RW?L3QPANXC`7G]Q(1F38 -M\9MU^[=N7Z7NL^,9"?!U4&H>7/JH$A?U9.LD%/-(<"?HO_%^ODFK)%X5:E+L -MBT"!ZGZ]J%S("?-+]KW%;V(E8Q]2W]J156M%G83?M6YI=.)5O0X)0$;ORA#W -M`!,L*87=-4WPN2$^YSEDGZ@V'EC*!IG*U\8=,,0BBP"WVC*H4/U,G)N=OZF& -M)LUMMB#*'"9V-(385$;P);59^"!S`%XABA"H-Q8R8\3QGY@1>AI+1BF[/?K^ -M\RIUL(XY!54"(D%\K'R-,9_M'\:M4QJV[)P\DF!`XKWV=@^`:,^_(TP@5LSA -MT[Y,[T98,@P5`4FW.>#%6P'"*7=RYT#;UQ<2^ST,GMZ^0X+*E$UX7<(V5%WO -M(-:5VO4Z4O5*49CPO$P1=811615VK,-+ECK6-!27"-2K?SJB!NDQ^W+%84>L -M4"\M^NT+W%3S![YX3!]79.NV9KA1I*Y?HYG3H\0'S5L=LE5Y9))[>T[2/4-U -M>0T/'!@4I[Z7-=V*&]&'>=U%GF/A+8%DW$WA9:YJSA%5J4@39V%_'F56*JT\N!9!)@RA9#G<)3Z;!2I[P$<++#" -M;5+I(&L=;`!E8^>47Q5S@%+6_M8U7X9FLQJ`AZP3JTE+:_^S`K&?L9`L_Z#V -M3AVKVMF!3(S%4F,/*$1?XLL_"ZKI;HL(;^^Q-=ON9DSO65E -MVF%#'R!XF'W`)_#7T9L(&2;5R*W\!#I*'U'7_RD[DW);A@UB2A4T/O'8+4"@KK(D.CG -MC:M!Z,\G-HQT*(^!<$MG0MJ(WR-==#3L#@G$11@:H:-B$&U$;"ZU; -M*`7%:,TM6_XV/T#XE/*-A/JA`T_;>CL+7+'^4-FFT%-04BZ+&#H(]^A'VHLT -M#/F+79W;>1A3DI?`!^J^B2,6/DK_*8",0H1H*P8X9)&`^KZOO[I!E0%T2NE\ -MAD$=W;=>4XX\#8^F[R>@:\YG3YWD8&+C2T>?6O]YM\KE_4X>IZ3J9'DZK)$3 -MK;S%<#':,N4IVP21FJ+NN+IK.&"B(7!#MV`^Z^2FG=SPZ`3DU(4B\-W5A^7R -MD[3A_JX"DDZSHC8>/+B5*+,V[K5^/3\H\,2DOL>>)]IK0OS`/^+\,8HXZ(E3:@B!SEE$_90EI67\>%&;4RSC37&QS\NJ!!.C1ER. -M"E@UC3F4FI:U?6.J%PTPR!O!2U2.`05Z._>"%!DQ58#53=S8H8;92 -M#F7;XH1`(,2).X>_5X,B@("CRVB\?;&_#SV:NRZD!A -M/47<8L2=-25E3"%$D]^@(CF5O5'N,HF3O"M*P_N,99E5A`L21ZO.[O;P!%,Z -MLJC609B0\VW1D0!;NVYV*1NM1LRD]1_+_1^WODEBT]=.! -M1JB?<6D<"*)YB:Y`%"L:3[L!-Z[LF8^GF$8((+#49%E8,4G]KJ3D:@'S:1]5Q.K?Y#:`R\V#BRL7H>#`#5D9`[A)$5"(8(KD!$W$VIS -MXD*YP9)JH#!K,>_@!05:<*]SD"5BOKX!&*%A=%_!@*/"6]N$+Y4;'Z.>7%;1 -MD8)O?&KP'^YWAG3#`VX_[_$X7C6SJK-_5_?P9_(/<*>$"S<63"8(1V(GN4FJ -MGZ=X:W*50+AHC=O(1WE`5X-(KEY`+^&Q$KS2'U(4S0"3>[+[I!7F&]A/[%?$ -M\/XV[-UQXA"9%"HF%J;.FG1[2T+V@G(*(2735#*V\,X4)?Y/?8>,+,EXZ,\` -MO[:0ABEK83N2Y-_,OU(KW.'_6,VO-VPM<48#FZ/`YI(6>\`" -MQ%_%BNK2]$)!R030G><(6";T\KK/M[8TLX($O?O)V`S_%=+NM:&-%.S7HA(> -M1P?Z)F)WC$M;&X;%=K`SSD:3"HN5(6OQ""LN$)_ -M/**$PI#26;MPE+S63*P!,)6QX)>4J@N<[MMU\3]J2+X5EG/U1?BI#\0QC6'C -M<7<3%W-C9SK5R?AKI^]G+#E`)8U\;27&*S#-`L25\1FKMX'PY58@R$J\BB.T -MN_9%9P#.))*RF<>^S!2CT=)OOPS+ZY\@(Y:'-*>(Q]5LRS[S]*0X'14LU/JP -M=FQ<&1G`]QIG+K7U]N7_#::&,*`T(5KXS\HZ1-@1D+\:OK/GF\_`;_(.D*]W -M,HZ?=E(#+_CDP>KJ]=$?Y+*Z)UV';=0FX*M(;M2R!^ZRF:EQPMU-Z6CEA$MN1=/IZ.-<_89G+$6M[U/Z('/K(.XV&W@AM -MU+5LMLVMA9WU=](2MPHSR-YWFCH]"1S>3ALR?KP#:=1MDP#HK*(/0^R6A)HB -M]MEVL`"5,ZV/!8OQR?HVY[LR]O5*(=8+?OBEV=^16R@Y[?U?QZA"@(3#5/7V -M4D>7G\\"G44&8+]0YNCT,.1'GB(!I]KK^?K"YV((RA(\JO?^-$4U9W[\?SAJ09=M -MAWRF)9O7M@+DHJ1[B12`]?-ST.T,WW??MF99(&`%6>+Y'EV?D)&7C\CBNWH$=+>2` -MA?91Y)FS6'2UOL&@&U1U-[%KQ*TE+"?`A%@!740NTDW?$1)JJC.(!Q>HY:O12!F6HOCCI)=A -MC+#.L$@AQY&Z*W4<__!TE)\B,J;#W8)M0>?S/^)ER`4[U8 -MK&T&TX/%>Y+:\VY.L`1VC5(5QZWX-.$!_Y&R^Z9DP"7H?1MUP:,>]\E`*VZO -M<70(\8TV`9]'5[+"W)2`VCR7/&^:RXRX_P7?_JV>L4*+/2N]FO0@DAZ5%TD* -M&ONJE*+>*XS%^C/X>(2D6G5HS^9O)G/YB9>W`UF')"Z>W( -MP#77(;@"[\S">P;V$1%%$#SV^"=A361S@C&_R0;8V=,0>08(QKW!PY]:F@;CU` -M5("$RD6,()0("8U/8LS$&&<3BAP,7FW_:;D\XZ;VQRN=>1O+'?.FD/-T';(@ -ML:=9!4%WZ97<5FSYO,;-19@,257ZTJG-D\ -M(1,]!O$JU[PENXVLM=_6H5:;S$LE`J.9<`+L1UI=JWYL+30HTWDE.60N0LN% -M*1U358B2KN(419ZF3??PH+4*KQVKD3<'C)RP->:I-!ZHD/FMI$;EHYY/:`6V -M-!O1+B>B:%!JP"?-%_-[2O;'MN:?.DY!C]CCT"/`6@B"(".\$BZR_\+\LL4*+D_@ -M>)C#SG5,8K=UI9)7Y@V&CPHFS%]P_:?"W^'?Z-+$.@:X9>J0Z4ZDZ5Y;U`VF -MX]/Z0A>2[R'>01DALCL)-(<(D7'<]B^-NWXKFN0]P&^?M*?U!1ET!VZ*S@(0 -M>`7]#Y^7D^>Y7EQBX`LV?9$6,4`V7-[7+IX+4.TZ$DK@=ZMF$ZI$2RQ?FH?. -M'J,B()3SI`HRV4>&;X_%F^5EE^R9#`[]U'VWW);@P.XX`0C1HHU%0[$O'C(+ -MM[*"0>HA=L>7;C%T\P_BD])$?)JS95T.3*=6AA./3511*U_T"9(F9GG*=Y$= -MM8B76'6KR]NK5?MO)4%2.7/AMO[D2/)2`"2:3HW#K9B!/>Q/KEU5'I@SW+L) -M'[KKSX3TNI&XZZ^@JCW025$A8.F;#1L<;FBJC+@[;228CUP@DU2#T$@^#)DL -M>TOYZHUZ#)3J:Z7VP#%^O0PVIG%_2EY)#!C<2"]@*H6V$_?PI(B9R1<]7ZGY -M+H\HCK.X'Y_#TAJ0]_N<=:W1*M]1J0%,?\!F-2H'D_&0D*.1;`R_@70]! -M:&`!I3=@C^/[CE3XX?:[RL[3*QJ\+N228"NRT./@ -M.6GI[GOV!\[_#G*>;-S&UD]C'&_$"UD$MD/G43XPM@*[6DOM99(GJR&.1XF= -M6Q+"(CC_H5&UI43R:_WE1%$G=R2M&*^YOX+:FRV`92`H'KW=""=H9F4*:&5K -MQ0.2*>TS1K>,MCW`01-$B]5B$9YTG&H::<%"5:+&"OMH\@+^S=M624+N]5#F -M&,2LEVPME%I@4*"A33R>;*0!$L$#*Y"LN`2Q69I+M;ZR90C+C@#E<7=MT'*\"\:F4_17$=J85YQ'\I&42-`8`L(J -M\ZW,L/Z#%O)J0^<,&^W"3[Z0GS7$/[P+R\$!5X4G(*_ -M8;(A\'15P"_M.[.('7&:U3GOB"BJO;2G8H\OH7M6XFS4&3QZ$Z?]5E-UX3-2 -MNCJMC4$?->+%BE6HQ%E!+3+^3J/M[#*)C@''.1WR\#?.V"O(R=1%(E;'].QA -M[]5/]>U;/2VQG,C,!"`!XQM&\;E3S8#%#!H=A?M2JMD>6,'1'=00F_H"@OI( -MFE&]+FX_Z2-=QL:#GHBPR#E"RNAKV"4F -M]SAJZ1EM<6(45NH1Z]#?B5";,+_ORQ:5O__8U(M_"V84F`H`RP4CL0E2!Z%47'=E>RC\*# -M6IB1XSS[$A6++03D -MLMO<+%[E:CTH$?L$_$+N@/(=&"!F4CN9>5LZ5]I8W_2J6*`3WE"D@F^TW7?L -M$RJ[2J&=HRA!?47F(,DOK,E3B32X&4TU4A<14C`9'J0(.=7;(3SF;86.[E#P -MF1:&\T:-CK$4@:P?\]Q\W/XM3IF+>-[&D9/,=+R,=9WW-CUN+PUUT_MM_Z)% -MN3V.\KOD^O9YB%S`E%G>[2MZQ-`EE -M>5,CS",B97]W^[U(3^`D`6#0,YK(_U),X%/X\=+H*$;6-5_G&BX9=M&$HO[H -MA3+Z<`<9E1`(`_?TP+-/9;7@UJ[NP$8'HPAM4`U/M6H!0S59#6U>-EPB47B4 -M%,RQ,$1+?`JDC_W!)WMU+7DR$G<>=+2>WH;D?`HUY(8DV"E5(3N>&.`O\&?< -M(7-292E71S97'#R\-NI`4RN"-`AD5TKJEU7P\E##=3%^P&JB?F,PMRIL3\/O -M0]`:ZO5_Y7,024U7#MO&Q!^6MM7;4/<9CV_%-^%):8R)L'XXWZ[.(!&(Q[G" -MRJ?ZH,7.&>XX$];&4<(H*/;5!HN8*[2/\3JA2\_J/1[/Z_<^/1?:V$^G.M_8 -M]JZ"3;?GW\48Q4_CBJI\AEO`7.8XZ#D?3PTW#[:<0D$C&F(N_$KCORAC#^), -M58F83\MQN>6?/*)-U<^LPSL66H9\?$7_@J>^2!F;)(UJO>95TUF[Z'HI]_7< -MP$M/##`YQ$2S[M_ZM]\>C>IV.@K=ZC&DYM$>(#%H%8_VNWU8"_/L.X,MGE@T/OIK; -M+DS/T3((70)2V;](KQ@W$VWC3&-G,4%QC!WRW%:XST#ZUODY&%X;_<#T`*E9 -M!QE.$M5#U!!20POLO&Q)P&%<9T#(=.B!_*;:#[*[?JE+AY9VS`FK)+B+X/3, -M9FQQ#3MACN.%F:J:'O67I2L4A7'\!?1`XA\[G"8;A_+/BY9^G&'T+9CF?V`R9SZO,62VR'U"D<5]A/D_PU;F6()`-1TFF:-D -M>0FH4!'LFF$P_#!GF.'//FYMN'YS\B=C\;+B*RCV0:!/C*[-J5S0.I:8O5;5 -M;J<]_<&,15@9WWZ*`/Q1M>8?&/A[0HK9B)?UE4)*4S0("<]\6.E6!YSRO_F.GV4PPL!*J:4Q6A2"TN@HG:^75$HP^ -M\B4`A2?\AP4^)$?=J4HDNGTF:RO4;=P[I;Z^<'0%<51+6>.*SL^`G9<,D+CK -MNS^H\2BNIY3^ELIE0(;U.N>0J0MRGJ?P#Q;;X&C_`5!+,@HT0V&)+*OSI3(! -M736:+TZGW_VE>1F?LNKY7KZXKY@A6F@?#Z%^G4A]6MXW743A&JO\BO6H(!X= -M+M>2:G<F[)[E6'N+0Q -M)!Q5L)D\Y-#U?C5MD+N.KMGN1=U)'U5=P*_2J>0TECPI;-'.'WYO*Z68LO)L0_M62_[+1:W(_M'2CYNQ^+(L'W&"D! -M)[^U96D#'6Q'P+/1FJ$O1G,IRB:^4DU)`-,4W]9 -M\<6``(G>KCN8VGN(UX'56S#B^,5YF4F=#JNG5^G$--H(B5*)OU4_VOA>+(T' -MRL0POK1Y1G$(\?[<.^Z4P'(TMKI`EXKR=&_KM(`,]CW']>9A9\[>\X%AP5D` -M'!2DBW3*3>J_8)_DUIU,_0),!?ZZ!%8%(RSEW?E-N#^4R:_9A9D_UF:=0K@B -MH0\YH*VD69'8ZB3#OCK3TWPJ'B-9 -MCWP]FR8'"5%%F<#:W16.%/B@?Z`2?"ES/JO0J;K=IN0*)^O\$_9#0M!K1GR! -M+6?W><%YD%^Y:(!Q^`TO+D0EE(Z[EKDRCM:/MW'P@CE531%*EEO`7HCNW]LD -M<".NV.C%JFO<9C."3B:W^2Z)",X\H#0[(4_K/R.Q1&Y/_OJD*;\)?BT_HU3B -M?ACC,0,U(BV<)\$3RHQ1CO7MJ)47KCBNR`;CKE%7/EJ32`K+SK\;J,0M&F4J -MV-#:@A`I1HHOQ#&B^N032X-)/JPZB)%4_+&@!:]=YGW\#'3JMH&D@XS@;0JE -M:.>-D(IF0GQ(.BZ81C2RD<4=GJ\2#B7B@U9EDZATH"9AG;QS.,!Y36!9XF3J -MWS?Q:7;<>P7=YQ9T& -M;F_+H^J'MLR!#_<*&/LM0#RH.<@'Z'AN1X20X)Z4N$)K9T#3]<#S/]K?HJ:K -M=^'`\'X;"*=_P]'3$8$OB-K,A!YM%:"1RWFLFC_)@FL%1Q!35B4U@Y_=C=@* -MJJ-A)`RVF9DITW-3-ITV;%JVZ"/5G*L"ITSD!T1LE\#$RB!\0!J0X^W$(XG/ -M':1G]*88Y@G+!>C/R[,^FN;>#Y0`_V7`DG'?%0*1-DIX>=0>&$M<>H<1%?'D -M8"`BXVW+B[H<'"ALVXE)*6.1H355MW@R"7K-/6Z1 -MVF;_X_$T;KZ9OP;^S>HD;7$EYS*/$.9.>@O3F:1/;6J!Q#*'0^R,B1G3(>QB -MRSJPC33'6&3Z]C`J2W8%41%!\H,C`%Z0V[C4+*#4LJ3'L"N5`YN_?'HLGR1_ -MN&QZ*CNB/EN*3[YY[:207/S9=Y>GWG,O2EA_VEBJB!1*(,W7R6NXH]BL'7Z( -MU^`"('I9/VDU;WX0G]<5YRWY>VQE:=[,&:9SU^0-;@4]WS&":JCF#7S#G[*N -MR+P>779Z_]NZ5-"*#92JE>W!/WO#3_YJ,#HM\4=*AT?0K&`RPO(%8*B_]$_: -M6F#0.M@IT9?:$G"B%/%1_`6&$O[>2)QVQ,0N(7=_JL-X-1L=+*<,B`P@/N+0 -M?0J^?XFI821QLFML\(P -M/$&DR31GO!AXP[U!9W%I[6F<9B/4;09.1JA4S!/0!U5O<6O8_K[--UO92C:' -M8V`ZQ1Y$<\;W7FD=&5?G&1>%>L*J[Z!9@X;FN/,1M*F>/.N5N!^Q.E2I/CB5@6[]*^6##2O@8 -MH+'5**'L=RSFLZRAD7)-T(TMM>K'($N-P^01`QIY%>6>''\".LWR&LK%L3/@ -M1H,?RU8C,P2X,N--O?`!M=9^%7%@B4.S>66^#9T),Q/>D_R`"Y(,\-`\F$49 -M^0H^%/&M;NJ>^4=[I,-[9W:X]NT/KP'&3Y$0\$:X=>*#6ESXK1.[Q2^\S'.XU\LO:J!Y@I4?FG-85"MTV>TBSLC['M\MH'1DG/L -MEPY$;[2H+:1#7A<]T^L'S''R14C2"",>3*@YY4)9<9K"-*\#^*1,?Q_QKJN$ -M%@#37'ICHTA88?1Z@O]XF+I9*S8).[BC/X)4LR\8(%1[FU&XV\"?:F9D] -M^_L6`2"OA'PGK+_YW@VU*YG/^Q%#YT]YK%QUHW]71.%L=SU3R!+*/$+$790SRCZ+8&IN:+& -M,G8/MJVX/.(-P5S0U/5KS7]O>/W%.,YW-[3AH+*8P'/Q%S_L`I_/;I@(&<*Y9+X]*E6F'GPSNU(6HPD;BXU``VGM; -MC=J<#CO"K9U:^*D"4_R77E_W"5M_"[+%^`T5X*HE2;*X?==HB3>G'4;I"^LW7C@ER^ -MQZQ.7;__IOBT'W$6VPM2!9EM^3.>BX#6P(_^@E-]^4WZ[P[<@S=JQN%$!K"\ -MYCDM=5BOUM/O:%XY9*$65F(IF8YN_!`NF`8Z,#Y.&`UBR/Y2=";ZLVM:T_B! -ME:?0;$CN&I/L;D(P+*GI6Y/$L-AH-]G!\P[N0)JM.^YO4]=U.+F-%_Y)M[,R4Y%_,DLY'"84-Q0T"`@$Z)#*)' -M@//XR"FNR^Z8")[FL&#.08E\I<;)M?3?I-M4@W63Y.K$QD->9C6^W!>"Z>UR -MU.7#MAJL4/ZM/P1`+'Y3Q6^H&!7>"#>J0_MR3EJ^ -M>)!*:29BK#U\R&3=0'/Z8:$)/N\3GH:!7^U:&F&WGW#:BR4AN)[5,/M<2Z/$ -M@OGN/_RF2+Z57*XKTD8+R)4S;M3W\1;9GM2)X"_C4V)WJ!JQ[.(QIQX8.@8? -MBY.8MU5%)]0'.GU&BUI\P`K,N\7+ -MZ+=DJ'Y6:\(^I80#T7#=1,.%A_>V]=!-YTK7M%:1N7#6]?B%&@[N!$[J6["! -M4G9R=`K%@T$E353#/J]3,_<92=3JU#9KNW)@&>E8)F/4`L:\^^0 -M[6``!3JP5`IJ=1DLHG6>7Q\"Q*@[5^&V-WKFXONH"I":LU"+\ICQU+&JQLBP -M^2%L,%DRHR3@O9N,Z:YX?)(SJM(X:YA$PB#,\^MH+COHP,%`_4C/%L -M$$]$[*.@-$LC6&+RRB7T*=D-B6K9::-1][*_RW6PPE"H9$X!P/S@^,R?.>=U -MFU1ZEKTI\KZG=B5!#,AV0/=Q@L%,3$U_^GQGP[7XASX@4V$/^F*VX@@G:]<# -MK=":`>S"&T[3!*R!7&`S2Z#;5@E'&"H#^+B -M4$R\\K6`DE]\Z@R92-T.K6<0[U49[C,\JPD"DN&)`O8/C``&1F@2:NCH4OMQ -MLN_;F7O7=HBSO]`/?=%N,2+W@N'7[ZMR8CO#`-^XL8R8J$W9B@MNSETW<'D[ -M.+[BR`C(/Z29C$A%H??9-W\VU&9QN@"J@O17SJ(YZTG-S&1*)?O_O@&%Z?L)>_J#S`PJ<.GJCUJRA?#-NP4=8Y -M=?E,H^8ED,3^Z2V`3=6TP[/-2A)K@V-L52G-GV0_^BRR@NQ0HIV6O>FL/JZN -M%9\1KY]E[#T/W#O'MFU[FW%"OV32>3&$ZH[7?OE>V"[Q.'LZ7-0^7\`DL^]) -M&)7X"&F*7_'R)L^"#0\T%@\68FX9VFR`.3]OX7?%C -MT,(I*YIDCOI<;E)^(/B3(Y;23Q1]^!Q']9J\$ME$C`;`1#IX!36E';JH";]\ -MD"H'K'V[V:/!'WSL%L/%W-2%D1(^[XW77F\&L<.'@]6UOC>?H.3XG51-5I)/ -M292V!29+UA7G0P&HGT/X\6S?L'#?'!5,'4YX5=>G>7!@2*O16*>.B7C>PTT/ -M'+:+/G:;&/Y2SQPBWVX9\Z^BYI9+!(*5VV/I95M&J3B4(8XFW`9/?%V-3B#; -MC3=:A;;4HUVP?<7ST1_?A.C[G:9&L'JDFL2/ORRG(T>RZ>"91\VY)1>1N0>EUMPW5!OJ_%(9ZS.>B! -MP0\[*`J7ZX=<:7;&K?./9`LH,V_FH7R1+85F.4)*3@@[!CJ^6!$_\ -MX_:`@4"&C:*-.SYNZL8G2!?\K$`V_`9$SB4^0GL2$7">4_WO[GA8AG3RU -M?2%?47@6:0X`6I/MQK\`K'UB)BE!7]%JQ*$\J\7[KONK\XRHYK0H<=;LI1[J -MTP8-K6`N.5`9/'XEPL8_E[OC:??8-%-`+@IWKIE.*\Y\L&@]+_YM_GQZ7!M4 -M-#@'W,5L8Y?JZ`E+/9D`D;1Z0_MD1PX@5"&0E5S**J$63D#"2'GKU#Q`/1A& -M`AGV(TNI0!OATXL$@0#S$`T#_UEDS_9]B391S?[][K-8+8O-ARZ@$C<.!I_G&?YPI`W_OR!^2RG -MQ&04UB=%^+EPKQ1!&,`G6!5:;V5'507BB_O9Q6D9^R&9WEP^_=\4+&CSH0>\ -ME?BJ;IJZ3RT"#0/W\&,-+E:-=O/DS_W2KSPADTKZB.021!D%4_;1,!,9`1KD -M_/GN6+U'1GO"Z>B0T2(!]`/*NELYV769024=)9Y_!67[#.JGTLU<^LTAW?PS -M;)^UES.MDFLIV$S(>&MKYC>S==16%3=9R+7&/6^Q1V0E!@[*:9^U;\<=Y0^* -M0EVH9@ZN&+?,BGV3%4/DQL6G%-`9T/F?NGH+9Z%^;YYQ(0]R_63R-G],D@%_ -M6I8:J=\X!Z/;G(RY4VTL>D='D1E?QS(Q18UC&8Q#0F`-=Z9`4>W,R?*YZ*6; -MG]F'=F/#T+$_^5>BTM+R_JR&*WIX`WH`A9)-5J7#^B\,6BHWF.4(*`5(8[!* -M!-M#,EH,[=ZA$0M,'$FREP90HDA?)TRS0K`+_PT)J:R>0\WK5_3,?,U4W:F) -MIP+V$GFK"3/P(*R8_,<6S$"'!-=<69FN*LQ6RMU)WX7ZAV8MO.=TLHA:!(NS -M!*46O)3V#N;YU@:F)WW\)7M-780O0H?BC(4?`WRO"R -MC4*?!`7(ZEU$9Z/OU_#'E'M3/KA&A&P/PSR\8'9GW("<+W50%M;T;,W6UWYI -M4[KSI;VEYX._D!YAHD])Y3M6>P6E-D@E)L&H3A.:(,&N>399%]-?= -M6W=H(W,NXDY!I(=;WBAFW>LEU6?V9MCDD>7A=:K7(R0A]C5Z30[\>0-'_*U( -M0+7Z4RG!];Y#(V;X*[EJRRE*5>,$W[=<:&7X.>+'`MUJA:I]NQJS=)">R3Q7 -M@+^<\GH.[&JIR/)$]GY0/RQ-00X)JS@+6'X.D-]ESNBK?0+.)H)KI(/N??!L -MN*Y:*L/TPSWB!BN_&YD>3>`9=?M`6? -M#!#,-WXSIFA19#6+SBW^,EL/G>X$G%0@/7F0!(#$"F=>A5"-&'8%?%^E^(@\ -MV^N;22V*N&)WIAFA[B.Q-IHR&,P"J=_VRY(:]Q-@0BZ!(4QE8QU8M]"N]233 -MFSHK7RKUVU-&G>@YT<>]NL"DD*1-)VSX@F9`A!+$JL%-YWV[Y+-F?:H-(>K,H>Z;AGM##46YA69`WT\#01:U,@3/L;NH5!Z"5:)<\YS(A5LJ1C'#^4`HV-Y-DI/!#G(:RD*#F,*V6:SM5Z#S\LD`G2 -MCJ7Z9*=5:3RYR\R#:\&?'3.7F1D*U;-J7H0[2K0,DYTVB?9M7FNG*50`0

    4-\0WRSA=.60Y:SER.<\Y-3H_.DPZ^3H7.QX[;SO@.P,\ -M,#TW/3X]6CUL/8X]SSW6/1P^*CY6/F(^`C\C/R\_4S]R/WH_A3^R/P```.`` -M`"`!```;,"0PK3#`,,DPZ3`&,0PQ'3$C,3`QF#'Q,?@Q_S$&,@TR%#(;,B(R -M*3)+,E(R63)@,H$-YDWH#>Y-\,WY#?K -M-_PW"3@>."4X,SA!.((XGSB].-`XW3CO.`$Y$#D@.34Y2CE9.68Y>CF'.9$Y -M"CL5.QP[*CO^.PT\'#PK/#H\M3S$/-,\XCQ?/7\]6#YH/F\^=#Y_/M,^W#[G -M/@P_%S\-2DU-#4_-4HU -M535@-6LU=C6!-8PUES6B-:TUN#7#-\U^C4%-A`V&S8F-C$V/#9' -M-E(V739H-G,V?C:)-K$VS3;?-OXV5C=L-Z\WQ#?M-RSF..=`YVCGJ.0$Z!CI".FPZACJ?.JLZMSHQ.ST[13M* -M.WT[BCN5.YH[ICNR.\0[T3OR._D[7SR3/-(\W#SQ//@\)3TY/9(]I#VU/<4] -MU3T//EX^!3\3/]\_`!`!`)@````#,!DP*#`V,$0P1#%+,6$Q9C%*,M4RL#._ -M,\,SQS/+,\\STS/7,]LSWS/C,^SZ//JX^ -M]S\````P`0`4````#S#*,#LQ0#&E,0```$`!`!@```!I,H0S)#6'-;PU$#9- -M-ETX`%`!`"`````E,4(Q6#%Q,9@VGS9_-X8W$SP:/%(]63T`8`$`#````-DZ -MJ#T`@`$`:````)LP^#:Z-^HWFCC<.%@Y.:\Q,3([ -M,D$R4#)O,I$RKS*Z,M,RYS+[,EDSC#.L,^HS!307-"LT/S13-&@T@32.-)LT -ML#34-.$T[C06-2(U+C4U-3PU2#5Q-7LUF#6H-;DUSS7A-?DU'#8B-CHV1S99 -M-FDVV382-R$W/3=*-U$W7S=K-W0WY#?T-_DW#CAK.+`XQ#C7./0X`3D).0\Y -M$SDS.4,Y5#HN.TL[6SMO.Y<[HCO..PH\.CQP/(@\DSRV/)`]RCW/_(_]S\`L`$`H`$```,P##`@,"@P -M-C`],$,P2S!2,%TP:#"),(\PM##F,`DQ&C$P,4$Q4C%E,7$QE3'_,0HR$3(9 -M,BDR-#)!,DXR6S)V,GXRE#*G,K4ROS+%,N(RZ#+T,OTR"3,6,R0S+C,_,T0S -M43-8,UXSV#,'-#$T2317-%TTG32Z-.PT_#0'-1,U3C5F-7,U>36,-9,UHC6N -M-;HUQC77-=TU\#7Z-1@V3C9B-G8VBS:4-K4VSC;T-@0W)C9-Y\WK#>U-[XWR3?=-^,WZ3<#.!$X%SAC.&PX..DX^3@$.0DY#CD5.24Y*SDV.4(Y63EL.7(Y@3F,.98YGSFM.;@Y -MQ#G-.=,YVSGF.?(Y_#D#.@DZ#SH>.BHZ-SI$.F#J%.K@ZS#K:.N8Z[#H( -M.Q([*#LP.S8[3#N8.P,\#CP6/#(\.3QS/)0\JCS`/-X\[CP*/28]0SUI/7`] -MNCW,G`RAS*D,KTRT3(-,QLS)C-',VHS>S.Y,\TS -M831L-(PTE32>-.$T7S5^-8XUG#7'-=(U^34$-C,V/#9"-DTV4S9X-GTVB#:4 -M-J(V!3<8-S0WFS>Z-]LW]S<#.`DX%C@D."\X0S@V.3TY0SE2.5LY93F+.9DY -MGSG@.?0Y"#I&/%8\#CT;/64]:3UM/7$]=3UY/7T]@3V%/8D]C3V1/94]F3TN -M/C0^1CY./EP^9SYL/G4^>SZ+/J4^Z3[W/@8_+3\R/SP_:3^=/ZH_LS_!/\<_ -MS3_6/^4_`-`!`#@"```3,#\P1#!;,'(PAC"O,+8POS"H,;(QSC'@,1,R*#(Y -M,D8R4C)C,G(RCC*<,J,RJ3*T,KTRS3+A,NDR0S-5,V(S:3-P,X,SC#.5,ZLS -MLS/.,],SWS/D,_$S`#09-!XT(S0H-"TT,C0Y-$`T1C1]-)HTJC2^-,@TW33Z -M-`4U,#4Y-58U7#62-9@UL37+-=PUYC7P-?LU(38G-BPV,C8X-DTV5C9>-F8V -M#=^-X0WDS>C -M-[`WQC=Q.'`YZSGQ.?/"@\,CP\/$8\4#Q: -M/&0\;CQX/((\C#R6/*`\JCRT/+X\R#S2/-P\YCSP//H\!#T./1@](CTL/38] -M0#U*/50]7CUH/74]@SV-/9<]H3VK/;4]OSW)/=,]X#WN/?@]!3X3/AT^)SXQ -M/CL^13Y//ED^8SYM/G<^@3Z+/I@^ICZP/KH^Q#[./M@^XC[L/OD^!S\1/QL_ -M)3\P/T`_1C]0/V(_?#^"/Y$_F#^A/Z<_K3^V/[T_Y#_Y/P#@`0#<`````#`& -M,!`P&3!-,&@PLS"Y,,DY]CD=.B4Z/CKH/!$]A3VS/<0]R3W. -M/>\]]#T!/F\^_#X@/S@_/C]5/W`_C3^B/[$_SC\`\`$`U````!`P'C`Y,$0P -MS##5,-TP)#$S,3HQ<#%Y,88QD3&:,:TQX3&,,JLRM3+&,NPR!#,*,U,S:#.# -M,X\SGC.G,[0SXS/K,P0T"C0Q-%$U)38X-K`VA#>7-[4WPS=Q.:@YKSFT.;@YO#G`.18Z6SI@.F0Z:#IL.LL\ -MZSPU/4T]4CV]/<`^T3X``````@`,````DC4````0`@!T````FC>>-Z(WIC>J -M-ZXWLC>V-[HWOC?"-\8WRC?.-](WUC?:-]XWXC?F-^HW[C?R-_8W^C?^-P(X -M!C@*.`XX$C@6.##U\/8`]UCT; -M/B`^)#XH/BP^`"`"`$P```!O,>C.`,YLSPS/7,_,S -M_3,'-!4T,#1!-*,T4#5H-6XUBS6P-6PWHSOY.YP]]3V$/M,^]S\````P`@"$ -M````=3*!,I@SP3/=,_TS"S02-!@T+31`-%0T8#2<-*PTPS3+-/4T$34@-2PU -M.C5<-6PU<35V-9TUIC6K-;`UU#7@->4UZC4.-AHV'S8D-DLV5S9<-F$VD3:9 -M-IXVKC:X-MTV[S;[-@4W%S<<-SPWH3>M-R4X/SA(.)-6(U9C5J -M-6XUC>!-XTWH#>E-[$WMC?'-S$X.#A* -M.%,XFSBM.+4XOSC(.-DXZS@&.48Y6#E>.7(YQCG0.=8YW#E'.E`ZB3J4.HD\ -MO#S!/.<]_STL/DP^7#YA/FL^<#Y[/H8^FC[K/H\_HC^Q/](_````@`(`Q``` -M`"LP-C"%,)TPYS!],90Q$C)6,F@RH3*F,L$RS3(!,Q0S43-@,V4S=C-\,X4U\C4#-@TV$S8G-C,VK#:U-N$VZC80.!8X*#AF.&PXF3@&.0PY -M?SF%.9LYB3J3.J`ZTSKE.A4[,CL].X\[ECO:._0[#CP^/'$\A#Q[/;$]SC[J -M/CH_BC^[/^L_`)`"`'@````V,#(Q1C'.,8#R0/)<\M3RA -M/KL^RC[8/N0^\#[^/@X_(S\Z/UT_@#^-/YL_J3^T/\H_WC_F/_$_`*`"`-`` -M```',$`P<#"+,,8P_3`/,44QZ-\HWX3?I-Q`X*3@X.$0X4CAT.(8XD3B6.)LX -MMCC`.-PXYSCL./$X##D6.3(Y/3E".4$Y[#GQ -M.?8Y%SHG.D,Z3CI3.E@ZBSJO.LLZUCK;.N`Z_CHA.RP[.3M..UD[;3MR.W<[ -MF3NG.[8[W3OO._L[6C[_/B8_D3^X/P"P`@"T````P3`[,4HQ7#%N,8HQJ#&R -M,<,QR#'=,1`R%S(>,B4R/S).,E@R93)O,G\RUS(/,RHS/#5I-8HUCS6B-;8U -MP378-0@V'38K-C0V:3:@-M8VZ39[-Z\WUC$Q\S$%,AI-^(W^#<9.)$X8#F4.P```-`"`!@```!J -M,]8SJ3NQ.^@[[SL9/P```.`"`&`````.,!8P33!4,%DSG3:D-JLVLC;]-AXW -M)3<[-U$W7C=C-W$W4SAR.'-4PZ_#H-.Q4[)3LV.YP[ISNR.[@[P3L#/"X\4SQ? -M/&L\?CR=/,@\X#PE/3$]/3U)/5P]@#T`/FL^>CZ9/N(^0S^>/P```!`#`%@` -M```,,"LP7#"Q,>LR!C,<,S(S.C.3-I8WIS>6.9PYH3FQ.<(Y;CIT.M8ZVSKM -M.@L['SLE.]D[H3R^/#(]3CWV/7@_@C^4/Z8_N#_*/]P_\3\````@`P!(```` -M23!3,&@P@S"@,,LP\#`%,24Q0C%4,6DQCS'C,?@Q6#)J,I\RL3+#,MTR^C(/ -M,R0S.3-4,V$S<3.!,Y$SH3.Q,P`P`P!0````8#)H,FPR<#)T,G@R?#*`,H0R -MB#*,,I`RG#*@,J0RJ#*L,K`RO#+`,L0RN#6\-<`UQ#7(-#1\-(`T:#9L-G`V=#8```!0`P`L`0```#4$ -M-40U2#50-5@U9#5H-6PU<#5T-7@U?#6`-80UH#6D-<@US#70-=0UZ#7L-?`U -M]#7X-OPV`#<$-P@W##<0-Q0W&#<<-R`W)##=\-X`WA#>(-XPWD#>4-Y@WG#>@-Z0W -MJ#>L-[`WM#>X-[PWP#?$-\@WS#?0-]0WV#?<-^`WY#?H-^PW\#?T-_@W_#<` -M.`0X"#@,.!`X%#@8.!PX(#@D."@X+#@P.#0X.#@\.$`X1#A(.$PX4#A4.%@X -M7#A@.&0X:#AL.'`X=#AX.'PX@#B$.)@_H#^H/ZP_L#^T/[@_O#_`/\0_S#_0 -M/]0_V#_`UY#7H->PU -M\#7T-?@U_#4`-@0V"#8,-A`V%#88-APV(#8D-B@V+#8P-C0V.#8\-D`V1#9( -M-DPV4#94-E@V7#9@-F0V:#9L-G`V=#9X-GPV@#:0/I0^F#ZP]]#W\/00^##X4/AP^)#XL/C0^/#Y$/DP^5#Y0Q[#'T -M,?PQ!#(,,A0R'#(D,BPR-#(\,D0R3#)4,EPR9#)L,G0R?#*$,HPRE#*<,J0R -MK#*T,KPRQ#+,,M0RW#+D,NPR]#+\,@0S##,4,QPS)#,L,S0S/#-$,TPS5#-< -M,V0S;#-T,WPSA#.,,Y0SG#.D,ZPSM#.\,\0SS#/4,]PSY#/L,_0S_#,$-`PT -M%#0<-"0T+#0T-#PT1#1,-%0T7#1D-&PT=#1\-(0TC#24-)PTI#2L-+0TO#3$ -M-,PTU#3<-.0T[#3T-/@^`#\(/Q`_&#\@/R@_,#\X/T`_2#]0/U@_8#]H/W`_ -M>#^`/X@_D#^8/Z`_J#^P/[@_P#_(/]`_V#_@/^@_\#_X/P"0`P"0`0```#`( -M,!`P&#`@,"@P,#`X,$`P2#!0,%@P8#!H,'`P>#"`,(@PD#"8,*`PJ#"P,+@P -MP##(,-`PV##@,.@P\##X,``Q"#$0,1@Q(#$H,3`Q.#%`,4@Q4#%8,6`Q:#%P -M,7@Q@#&(,9`QF#&@,:@QL#&X,<`QR#'0,=@QX#'H,?`Q^#$`,@@R$#(8,B`R -M*#(P,C@R0#)(,E`R6#)@,F@R<#)X,H`RB#*0,I@RH#*H,K`RN#+`,L@RT#+8 -M,N`RZ#+P,O@R`#,(,Q`S&#,@,R@S,#,X,T`S2#-0,U@S8#-H,W`S>#.`,X@S -MD#.8,Z`SJ#.P,[@SP#/(,]`SV#/@,^@S\#/X,P`T"#00-!@T(#0H-#`T.#1` -M-$@T4#18-&`T:#1P-'@T@#2(-)`TF#2@-*@TL#2X-,`TR#30--@TX#3H-/`T -M^#0`-0@U$#48-2`U*#4P-3@U0#5(-5`U6#5@-6@U<#5X-8`UB#60-9@UH#6H -M-;`UN#7`-<@UT#78->`UZ#7P-?@U`#8(-A`V````H`,`D`````HP#C`2,!8P -MG#FD.:PYM#F\.<0YS#G4.=PYY#GL.?0Y_#D$.@PZ%#H<.B0Z+#HT.CPZ1#I, -M.E0Z7#ID.FPZ=#I\.B`[)#LT.S@[0#M8.V@[;#M\.X`[B#N@.[`[M#O$.\@[ -MS#O4.^P[_#L`/!`\%#P8/!P\)#P\/$P\4#Q@/&0\:#QP/(@\````L`,`;`$` -M`&`Q;#&0,;`QN#'`,<@QT#'8,>`Q[#$,,A@R.#)$,F0R<#*0,IPRP#+@,N@R -M\#+X,@`S"#,0,Q@S)#-,,U0S7#-X,X`SB#.4,[0SO#/(,^@S]#,4-!PT*#1( -M-%`T7#1\-(0TD#2P-+PTW#3H-`@U$#4<-4`U8#5H-7`U>#6`-8@UE#6T-<`U -MX#7L-0PVX-D0V:#:(-I`VF#:@-J@VL#:X-L`VS#;L-@`W"#<0-Q@W'#$-Y`WF#>\-\0WS#?<-^PW]#<(.!`X*#@T.%0X8#B8.+@X -MU#C8./0X^#@4.1@Y(#DH.3`Y-#DX.4`Y5#EP.7@Y?#F8.:`YI#F\.<`YW#G@ -M.?`Y%#H@.B@Z5#I8.F`Z:#IP.G0Z?#J0.K`ZS#K0.O`Z^#K\.A@[.#M8.W@[ -MF#NX.]@[^#L8/#@\6#QX/)@\N#S8//@\!#T@Q]#$`,@PR&#(D,C`R -M/#)(,E0R8#)L,G@RA#*0,IPRJ#*T,L`RS#+8,N0R\#+\,@@S%#,@,RPS.#-$ -M,U`S7#-H,W0S@#.,,Y@SI#.P,[PSR#/4,^`S[#/X,P0T$#0<-"@T-#1`-$PT -M6#1D-'`T?#2(-)0TH#2L-+@TQ#30--PTZ#3T-``U##48-20U,#4\-4@U5#5@ -M-6PU>#6$-9`UG#6H-;0UP#7,-=@UY#7P-?@U##88-APV(#8D-B@V+#8P-C0V -M.#8\-D`V1#9(-DPV6#>(-Y@WJ#>X-\@WX#?L-_`W]#<0.!0X'#A`/5`]5#U8 -M/5P]8#UD/6@];#UP/70]@#V$/8@]C#V0/90]F#V#%\,8`QA#$````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````````````!287(A&@4*`04&``4!`8"``/4["1PH`@,+@P`$@P`@TF-(B(````QT97-T+G1X -;="YT>'0*`P),FW]/_;C7`3$R,QUW5E$#!00` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_solid.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar5_solid.rar.uu deleted file mode 100644 index f4d06c7a5..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_solid.rar.uu +++ /dev/null @@ -1,27 +0,0 @@ -begin 644 test_read_format_rar5_solid.rar -M4F%R(1H'`0`)[\AO"P$%!P0&`0&`@(``Y3=C#"8"`PNG`P2P":2#`LUPRGR` -M'0$(=&5S="YB:6X*`Q.+5ZQ;^!BM'LTUHP$H=E560?1@6-L,?'&,&#'QQBRR -MQC&63&#!9999#'QLLLF,8LD)\9"223XR$A)))(2?.222$(220A"220DDA"$O -M?GOFO?-:2EV7.C+W-]O[F][\UT:YS?7KE^_SOEJUK5:Z=?W.;K=OHWNY6]_X9H`$`!`-2EP'SS]?G[_;Z?/X_#W^[V^SU>GT>?S>7R>+ -MP]_O=SM]KL]CK]7J=+H\_G;O=;G<;?;;39[+8:_ -M7:S5:G4:?3:72:+0Z#/9S-YG,5V7RV5RE54U&3R./QV,IJ6DH\7B<1AL+A)^ -M>G9R;FIG`7^_7R]7F[W:Z7.Y7&WVVV2"H4:^RH@6WA;;=>TLP;<\(C9ES0)A -M"0S24<&6T))M+(Q2K/T7"3U5J_?EK'DC(E)6XI6X%+R18*3*BE"I[J5;*EH[ -MP6QEBW][+H7TO'+E]9@I29*@FBJYLM7.%Q9TO!/$]GRP-`590EM<.76HB_&* -M+!T99VD+ATI>NF*8QI9JG+CY`OEDBH:@M;4EW:HI:K+/UA=.M*3KB,S<;NDG -M`@,+@0$$@""D@P+&LA-^P!T!"71E_Z1)!;Q!;;KVH)@VYX1&S+F@3`$AFDHX,MH23:61C&_!'Q -MI+GZ`VDHC9ES0)?"0S24<&6T))M+(QC>@CXTESU`;241LRYH$O!(9I*.#+:$ -MDVED8I3OA=ECKEQN^6NQ;W5V$7ZXO7RXKWBXHW7_KC/PKJ>2!"<"`PN8``2` -M(*2#`LNO9O'`'0$)=&5S=#(N8FEN"@,3>E^L6RU4P_X4[XC_'\S\!M2\W-)P(#"Y@`!(`@I(," -M_TBD-L`=`0ET97-T-BYB:6X*`Q-?9ZQ;.X_4%T4*%6@`0`0`W[/C^B,#&;'\ -/IWQ'^/YGX!UW5E$#!00` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_stored.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar5_stored.rar.uu deleted file mode 100644 index 405b8795a..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_stored.rar.uu +++ /dev/null @@ -1,6 +0,0 @@ -begin 644 rar5_stored.rar -M4F%R(1H'`0`SDK7E"@$%!@`%`0&`@``X,`9C+`(#"YT`!)T`I(,"M$.@E8`` -M`0YH96QL;W=OPH@("`@<&%C:U]U=64@)&%R9W8*?0JEGN@6*`(#"ZX&!*X&I(,"GL1> -M?H```0IC96)U;&$N='AT"@,3V'*P6X;U-RQ#96)U;&$*"D-O(&EN;F5G;R!C -M96)U;&$N"D]N82!N:64@;6$@=V[$F71R>FYOQ9MC:2X*2F5S="!S;V+$A2!N -M82!WF5N:6$L -M"FUO9\6"86)Y('=E:G)Z9<2'('<@GEZ;F$@:2!D>FEK;\6;Q(<*;&5D=VEE('-K -MP[-RQ(4@<')Z>6MR>71A+`II;F9E2!C -M96)U;&$@='=OGEL:2!T2!BF-Z92P@;F5R=WDL(,6\><6">2P*Q9ML=7IY(&D@FT@9&]S:V]N8<6" -M;\6;8VDN"@HH5VESQ8)A=V$@4WIY;6)OP$``*,!``#-`0``^0$``"<"``!7`@``B0(` -M`+T"``#S`@``*P,``&4#``"A`P``WP,``!\$``!A!```I00``.L$```S!0`` -M?04``,D%```7!@``9P8``+D&```-!P``8P<``+L'```5"```<0@``,\(```O -M"0``D0D``/4)``!;"@``PPH``"T+``"9"P``!PP``'<,``#I#```70T``-,- -M``!+#@``Q0X``$$/``"_#P``/Q```,$0``!%$0``RQ$``%,2``#=$@``:1,` -M`/<3``"'%```&14``*T5``!#%@``VQ8``'47```1&```KQ@``$\9``#Q&0`` -ME1H``#L;``#C&P``C1P``#D=``#G'0``EQX``$D?``#]'P``LR```&LA```E -M(@``X2(``)\C``!?)```(24``.4E``"K)@````"K7P``Y6```"%B``!?8P``GV0` -M`.%E```E9P``:V@``+-I``#]:@``26P``)=M``#G;@``.7```(UQ``#C<@`` -M.W0``)5U``#Q=@``3W@``*]Y```1>P``=7P``-M]``!#?P``K8```!F"``"' -M@P``]X0``&F&``#=AP``4XD``,N*``!%C```P8T``#^/``"_D```09(``,63 -M``!+E0``TY8``%V8``#IF0``=YL```>=``"9G@``+:```,.A``!;HP``]:0` -M`)&F```OJ```SZD``'&K```5K0``NZX``&.P```-L@``N;,``&>U```7MP`` -MR;@``'VZ```SO```Z[T``*6_``!AP0``'\,``-_$``"AQ@``9<@``"O*``#S -MRP``O,``+7E``";YP``@^D``&WK``!9[0``1^\``#?Q```I\P``'?4` -M`!/W```+^0``!?L```']``#__@``_P`!``$#`0`%!0$`"P3 -M?8!``0AF:6QE+G1X=#$R,S0*8QI3.2T"`PT`!@CMPP)7C;=<`````(!``0MS -M>6UL:6YK+G1X=`P%`0`(9FEL92YT>'2.NOQU)`(#"``&`^W#`DF6MUP````` -M@$`!!V1IWMNP$+-5H*^@`!`$OOB]$````0"S5:*@`` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_win32.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar5_win32.rar.uu deleted file mode 100644 index 16d9fce1d..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_win32.rar.uu +++ /dev/null @@ -1,69 +0,0 @@ -begin 644 test_read_format_rar5_win32.rar -M4F%R(1H'`0#SX8+K"P$%!P`&`0&`@(``EV&"+"$"`PL`!0`0`````(````=T -M97-T9&ER"@,"5NNI_W0?[W -MVO?=>:\Z7^@`0`$`R""?GX]O7T\O'O[NSKZNGHY^7DX^+AX-_=W-K9U];5U- -M/2T,_-S,K)R,?&Q<3#P;^]O+NYN+>VM;2SLK&OKJVKJJFGI:2CHJ&@GYV'9T$&P`\Q!(R">9A6-`NFH9;8-YN'@X!@<@^N -M81.@IG88#P-MZ'N]AU?0C?Q80(T8,><*'DT)@V+XX.8Z'"($J>&%%CMC0_GQ -M4(!L(0T(A-(QG)`O)0`QGD%J)0(#"^L"!(`@(,:R$WZ``P`)=&5S=#$N8FEN -M"@,"$I6A@`U:U`'-\6<7#G7SNUN[YG1F[ -MO3O]%F,,Z?#,/6YOF>>GO;]_`_=OV`"`"`&PPZ<-FGU\_'O[>OIY^7CX=_=V -M]G7U=/1S\W+R5DY&/C8N)AX6#@ -M7]]>WEW=7-Q;VUK:6=E8V%?75M95U5344]-2TE'14-!/ST[.3FYH!9@!;-"-LC0$.A -M"U@6`X1/;5+3@AZ:F@%F`%LT(VB-`0Z$+6!8#A$UA]Z%,?GS*>SVE?X8*>=C -M4\-BG=.J=HXIZ?]R?M!(:PP')0(#"^L"!(`@(<7#G7SNUN[YG1F[ -MO3O]%F,,Z?#,/6YOF>>GO;]_`_=OV`"`"`&IATX;-/KY^/?V]?3S\O'P[^[M -M[.OJZ>CGYN7DX^+AX-_>W=S;VMG8U];5U-/2T=#/SLW,R\K)R,?&Q<3#PL'` -MO[Z]O+NZN;BWMK6TL[*QL*^NK:RKJJFHIZ:EI*.BH:"?GIV6E923 -MDI&0CXZ-C(N*B8B'AH6$@X*!@'_WO8_D*7"EJ_4J%`9V,`+9H1ND:`AT(6L" -MP'")[\[SO-RUK/'AS>Z]>]72\[VUGX; -MSPS6]^._Z+,89X_&9MAOF??:->O/X'?K\@`@`@!LK,L+N/CW]O7T\_+Q\._N -M[>SKZNGHY^;EY./BX>#?WMWFI:2CHJ&@GYZ=G)N:F9B7EI64 -MDY*1D(^.C8R+BHF(AX:%A(."@8!_?O_[[UOQB$^$)+[%!@ZJP@)I6!-DF59- -M,DTP85+::84MW9$H?1AV`=#$!-*P)L$RK!I@FF#"I;33"ENZ(E#Z,.@#H8@) -MI6!-UH>G1#RK4/$L0^/_<7F@SHER0)0(#"_<"!(`@(-0^Q!"` -M`P`)=&5S=#0N8FEN"@,"`HP9@0U:U`'/YW,!$&1552]7!7XDDDDDDDDDDDDD -MDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDG.\[SG-RUK/' -MASFZ]>]72\[VUGX;SPS6]^._Z+,89X_&9MAOF??:->O/X'?K\@`@`@!L*,KK -M*_'O[>OIY^7CX=_=V]G7U=/1S\W+R5DY&/C8N)AX6#@7]]>WEW=7-Q;VUK:6=E8V%?75M95U5344]-2TE'14-! -M/ST[.3$.%]B -M@P=380$TG`FR3*LFF2;D&$RVFF%+=@B4/HPP`=#$!-)P)KDRJYI<SKZNGHY^;EY./BX>#?WMWFI:2CHJ&@GYZ=G)N:F9B7EI64DY*1D(^.C8R+BHF(AX:%A(."@8!_? -MO_[[W'XXA.D)1LT$"OW!PR6LE*QQ<,847-+AIH@;:C`.CV[!$+6S=F"ILX9+ -M62E8XL&,*+&E@TT0-M1@'1[=`B%K9NC!4V<,EK)2L<5#&%%32H::(&VHP#H] -MN01"ULW)@J;.&2UDI6.*!C"BAI0--$#;48!T?G'][B''U_9#Z?:1^AHA[VM# -MT\$/*RH>)D0^/_<?EX^'?W= -MO9U]73T<_-R\G'QUL[&OK:NIIZ6CH9^=FYF7E9.1CXV+B8>%@X -M%_?7MY=W5S<6]M:VEG96-A7UU;65=54U%/34M)1T5#03\].SDW-3,Q+RTK*2 -MW((A:V;DP5-G#):R4K'%`QA10TH&FB!M -KJ,`Z/SC^]Q#CZ_LA]/M(_0T0][6AZ>"'E94/$R(?'_N'S0`==U91`P4$```` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_window_buf_and_size_desync.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar5_window_buf_and_size_desync.rar.uu deleted file mode 100644 index 9e7d20ff6..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_window_buf_and_size_desync.rar.uu +++ /dev/null @@ -1,11 +0,0 @@ -begin 644 test_read_format_rar5_window_buf_and_size_desync.rar -M4F%R(1H'`0`]/-[E`@$`_P$`1#[Z5P("`PL``BXB"?\`!(@B@0`)6.-AF?_1 -M^0DI&0GG(F%R(0<:)`!3@"KT`P+G(@O_X[\``#&``(?!!0$$[:L``$.M*E)A -MP0";/P1%``A*2DI*2DYQ<6TN9'%*2DI*2DI*``!DGNGIZ>8_^>GE/_``!. -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar_binary_data.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar_binary_data.rar.uu deleted file mode 100644 index 4d1cbd36d..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar_binary_data.rar.uu +++ /dev/null @@ -1,24041 +0,0 @@ -begin 644 - -M4F%R(1H'`,^0FQ_"3YH!RD,Z._X"C -M/3#[L-WCJ0?Q9",77X67HMV_1C2F(]0P@?Z"9RE>_0N+T*7C84;A.$^%HPA; -M/KUC-]:V(`P@K9E&,@HSQ]U%GA;<)"GN_\AU$IRQ\KUSU;63D\I.`4(_S07> -M>$9$ND1O4EV);?>1KZZW"N/>"ZG*OF:N2,7H]!YS]"['2*H#!:)Y59O#/R\` -MM5')`+4BR:67<3XVKC3Q7E>-;3[CX&%KM8F>0(%==8/R5-J:IG?W?5P"D>U= -M%!__'*.I(1-Y1FVS.%=5N,3+3$P[E0 -M30J[Y//-1_PYW"5":O`88AEH37"5D8`,8^C!Z[\7^I$,>`0%2:3IQ&`X?&:( -M(,!!%TMGR`#P>3]6F/8[X`.,^O!J!NG>1;V9&QO/*6!H15"H\[_27B^$5E)! -M773$UGJ>J\234H#^5=@E]=$4JQIC::ZU02/SA6V@$-41FXK>Y(W$"3_O0SF9 -MJ[>EGV^>OP@GM)&8B!"9)72FL`@A;:,@-!^4-X=65NE*$8S5/BKC`6[(AH;8)VO/U,KZZG6!VW_C1`%@3YH -M]G]K;?MK*%"J.4L?N!*76PBI$EN,RS)G>:8J1F"7(*!G;!*.?AAPV45D71.T"2"$Z&C'0>IQS->4S[HEPMZ_G`5'!0^0)F.8YV -MS!,*!XVJ3ZH'[Q,'"<2H3W._Y0\MBG(G=#8GL#0<[20A/G;@+Q%&4B^Q\X$E -MPZWD]J1,_@==SDD]&F;[*PUXIQ4NC!#S3'!;15_7P`U(*A.YD:F]TIXL?D:N -M,9LG5"_X#>1]3E23QD`GVQ8_2(O$>E#%[)$?MJ//V7.(?"+3X@F99&=%L&:B -M__]<*N??GVC52W1`I9T87);1!2MLR\O!G9R>N5MI3R1K@6*2M@)W4[/WQ"V[ -M>N(HLU;(A$4KST@UXM4"><",_U*+V5J#686%64H=%D#YV]UMY-=RJ\]+95N2 -M%%JU]F^[A,IK1/6;H^T=)!RVW1>)'>2VD0AQZEZ\]H%E!3M-^M,XYZK"W$]K -M#&"/?=O&F]KX`#<:@CH8@MP^1.#KXT!Q2XWC&HRE[:^A2&P!26IP*3!V"-1J -MQ9=!=>%;CHYSAC.W;F@$?36-+-+\M0/`3M@ -M!U-P0'^H??-M,%M=B&(P)+!#:28%<.9$-<8W5>MK!U)(!43<_TSSTSO% -MN)K"K`\J]FJ'TB35L*@/3ERCT`X0KH3-3.SK<,*YWC3F67EM>L,K>33;,^:8 -M;`E$ZUQG`1J$W]QRUG.,)<>B[2F4>XYS^+:DW+`N'-^L6^[/("-F.6RX^[*H -M3L3/P/W>C@#/>F?O"%4:E>V&G"6)29K!6Y_G"SD]WF^4N'P -M/8#B#@EG>I9S(TM+Z=A^_.EU.'UR;_ZS,80F2"FQ-X78_E*.C)VU(ZX^4"F3-CX*`J-US0G8R; -MW%@39U`!(D_T8U0>%`8H/JT_`$OMQ>GQ3%34E'NU#U9#'(V$"=775 -M;N]Y?6^FP/NZ;AXOR4/6YBH<\>S0JZ'.?$JQIH)KAE='5K0VR?*-3Y'K#_YX -M*F2:RW;UV,K[N<>3^L(VL@'J->$MJ0K5_>,,G>2\JG(3]H`HU(SPY@R2:0'0]VC1(D\EO)9CH">V!I -M!7[A\D]KI%UE7_A"VP)N]F9Y4$`W-'GLXUNP3PZ[_%4]HV/A.,+_[?!#O/5` -MOI1GNU?G<2HF5JI%L"`*Z4C'RI+5S$_7@1 -M%Y!*!Z -M[\6F^SMVP.NYW<03D2^<%Y&5<').^5!5+Y`\YTA&U+3]=(O)L%`%29]=R3I9 -ME>%`MZ7!5G$%AZO'6Y`V?#SUY*3%HH^%[/L0I)E@X51:1(,R]LM_-\_-$S8K -M;(W8HW<\9VVKS:;`S+#(7J$Y&295B_](,PRHB!.BF=00C?7N3&.1"^N,7@LPI@ADB8U<(7JQV"7UN">9?A -MBJ*Z&R,T%#TH4KSTRS=/&'ZB.KV_B<][@ZV+$6'\/\"PI]>-5'I`.QC1!:(A -MBGI]:/MP;\RE>+SXO?9../0H[HV.R$(.XOR:V?P/?QN^9M=`?YA/0L,[7423;2AW@."7:#=!CR9<6RF\M:)_AC35I91)4Z]>OA6ID%XDGU.MDA=&I-.!>T.Y -M):E2QJ(!GJ,YBL*CV__]ZW^NB+*9FB*BW?.2F!@9$)XD[@4\=]/3OF6&`XM, -M^Q!(\SR*.A<@:0K0Y7/O0/D[RGT&T#\^WM/>VMIT^?`LW'L-"6?>FU08*16P -M-1ME7]]KT(H"I&IX3>BV:4S8M&D?X^-+IHPON)R&'\6*AJYSIHAX"/ -MS]KU3*X=&M@78DOS73O=QI+DCLR3\SW][+5"'J`R'_='S_CPW11'= -M9*F'@3RCNU<$VXNGI^+/N]5,V9Z*;`/N#3E9\.#:3?(.]8[N)=`J@EMO++!^ -M%%#5U(Y",#-#R25FD/B4*N^SZ];>[1/?XT..1#$?L;HQ6,F(0:!G7N!`PAGP -MEGO^.]U=MF+$FKT9-ELHN!VVR%]".J*1)*8WG0&P2LDEZ(`=R']?Z?S+G24!A6 -M[PW]"D:S0M=]DND8WW('`(,(@")(GJ!7M6]4#/H`/$6,JX`<22S2$JOE_,#; -M87]/E[;TDE\:O3L75_XI;E8L.^2J_M*$8-8I>&_W8M22RW>`?TB:`&6?).,8 -M^.B,:8%_!_&.VW@2J7@X0USTY2IK!LFB#C;E%#.@75&&;"=&AH'\$/R7#W@F -MC\BD9D3P?`>FT=8%_2`5"ULZ*E`J`X#;0II@%@.))P\Z6?F?0%W/&[VJZUN/@9#N1T(P[1;F<"L!NB8F!$GFUV'7?E$%M6;EBC -M?C/+.W'9%)J+\+8[HVSF;05=RBG_OC+@_\[=HGS:IFKH<;O?XC/P*82F$QXQ -M<]EU!A49;_<'D_9-S`EC,$KJ1D+"?*IG;"IQ?XF7L$Z33#,N"98\N) -M/ZC<6ZUA>)>7^)3#"GU@5[!ZA:TX)49%U=BMN%F&,7_"<(BOL=E*]VD\T/3Y`WA?#F!9YD@C^[6B1(*/8MI=?KVAI=G#=;$LR=U? -MDV:Y_`;EC2RRYB,6H54!\[1H5K?83B3.@'"&4-H1QT:SVJ,N\V&T:\2WN6KV -MORFXI,E=;:552I;X\#QF386"&L+%G<*[30$87%'&"=F)H)GQ(GT2(M[`/T?_ -MP#=*K??&082="_G;)C%0FQ77`QQW\?F"5%<9[#\"KNP[#T#K.*W1Z.C($3Y+ -M'I$)P.D?=W[)#H(F]UG)'C`DILT7`J(;EUEP+*?8@[WM4 -M_*'\DT*72G9W2*!]#HVNT-P,""*0Z#48@4 -MSR.+=\CS6AS$#N:EQK0)NZ0=NJ"'\FWY]@>_D!F/L'MNG@>1`W)Z@KH/LG!S -M'8[L%V232-KRZF&%3,A[RA%6GW='`&0^@\,QZ7!R!!\&1S*KD7V -M8$;]$:C8$D4P+1(`4U.J:83`*T1FO`[T!=RI3$PS+]:(Q/-<:23M:3:;[B7^ -M9Q%*W>X==BY75JK#^$4)@H>-OPL[!VH@'XY7!@S&8[*>GJ/(BPA#,W4-71234 -MX-0-21@"2?@`/&AJY3MSM@1IS*_]_]1E7=,'H7WX:;EW]3_KFCDFJ!7_^V%U -MD&:WAYPNZ5_YN-S`&O8_HZ8:E%/QA2QV4*T9O0/VX5U<,&ZHNFHOO-29@SDC -M9BJ".0AAYSH."$FRY@6KAYX;"_+LY!LRS*HZB%-ISA(9$#637*/0G$$$U!,% -ME3AP^\V-`$(D>//3[@ETG+B,&+KNL(XY=)Q/-7\X+;#PU!`(RS'SI4AWH,SZ -MN=T`SIV[((A/,HI78I\-RSBR?KU5#>^`]L6OB^@U&S)8P73996!3G"F<9TWN -MES`%PU*U;B846?T*+)>^=%M5?/Z1:(GKBQ+RG\1,_7.@7B7FC(2)=?V7(N-8 -ML.V+V]>Z_TM6$R*A'\^J@BD=PD'O1,/IRUGJY<$*)9X?KN:W462LE:@M(D*+ -MGNGE(P%IJ;=!X4D5%VUH0A*&9`K<'HR:T+3)$!77\]W+!41VX>)>;SL_;"[4 -MG-*P#[SYO:^%QK(8UB;!:(5/UHJL\]3=CH#LE<2&N72&J@&#G.15U/C0L(`_0S[Z9H#T""-M'@^EH3PVG)/<-O'UT?CX<+VMU'M.^=?E[<*- -MK^>\,RS=2U+7])N-_[VL,>T=FSQYFQ#;M:E7)Z0J=;@^[_5I#T(]UXA>Z-_4 -M#[()K1:T%I+W'8`P,:4;,6O`=^(&*".'L/:!7223,>IRQ`@$-[:(SL>#9;=) -M;5:`3R?W].RN^VA)0?*PQ37<9+WS&&V\4JV-T$7SC%C;CS(A9ZJ13^VPXD28 -MUO^J/;]GBR2^^+>^%I"I^:(LZ03P.)RHDO4P7V:IQ@*TRD?*XB9MO)JBBO%< -MD\TH1S:8@]DMED'!0S!EQG5S;WM-6YZY##A3P#AQ\"*(@J")B]Z:#O8\`+]B -M_30TAI@I-#\WPQ@W9M6]RS3D%\*0@I^6#&GDK-/>J3FPJE&#X[I7I;S@(_[J2+2LGC*+9A:8>* -M(8T!=F$4XUYEG[X8RT[1,L@](8\5(-8(A%I$,"#U$A7ZDU**!N#H:\&W-DVO -M\G#<'HVX?JQ0J8"I4'`HZ9%[LG;N..8Y)9KB_W4.-_0O$E07`C77?`XNZ5Z! -M8P[&*NUEQWMO!U;7-5Z'5XCL/SU2)1S-Q%%PY^2C?V&K]#_`W43;QKK:$E6;/YD'&80NP3_KIW/>[[4X -M4=M)WW0\/U6`03C49S)4(@<33F>&?KG9H/.SBQAJ)K,#[UL??L#K2R$X)'Q$ -MLQ<'+*+=`4@[[^WB<].".>[NA>D:;HI-#PN++\>W_,2=JMKR8G-,7CJ2)PW3N+9G'0/.\-#<^!>+HA=K!61.^EL$U!C^)K@08DT<'<>MV -M7N!O7V5;DO2RI\.>Q@1L?[&6X3?'OR5FI!`:FCSF><('!96%WTX"66YW^/G9 -MQ[3ARQN?0NWQ@O:=H9>E,L!Z[%^`D,>49TCL@WGTE83Q_FJ=)G?+/3[GH2L> -M^I:\B`(L/NDWRM&&^O#[3^F0KJ&CP(H,0Y,=>RX*B1W-2"ESBI0O&@4;OO' -M7P9&/Q1`KZPSZ3JA[*WQ1*6?;2JBCH-E>="F5R\`7]%>S3 -MK:+ETPPE0RCMT8&RSGSLRJ#;(@K-35(YDO3< -MI:X(\8;(6(?0TA:)V,V+4![\<5I?U?9M@!G?!C8;38^ZY:+0@0V9\$)\\>[* -M\/<@ZQ!\$5AJ@E41=5LS:L-0#Z8]WLWG`T.Z$ZYLC#)AW0/1BH0P8')_NX'> -M/_;OY%[0&/%3(GYG-`*TS:QH6TI`:K9NX<&L'GGTZP^7W(P[B)BK?\HD['4! -MB8'-$:ZVWU$2W[AFB0$3`UH4)PTF<=IJP2V#U")`[D]"RD+X6A6O^LEWK(B= -MP=>S\L4XY:UQ*$C#P^T9QH`OH^?XDW!0^SL2/2.CC_8'Q`E49^@I^?TN@0YM -MF7]'(6+IXWK)C``P\M&H=,=;0`WJ:3U"8P+*4C_/>MZ(^'#DUR"4L(VN\R^L -MY8>/A -MC"&6T]CBGX"Q^T(*U&D1;82JL)6]U?6Z9H_\@1)*>Y[6[(@?C=!U/^+5+`>8 -M0:B1SX,)34/=X67F-?C"_##_:\>'1Q?Q[(`N*D50752V@2V6&?P\^JA"/BSL -M#EFT&H!1.$S+TYKARJW7]!T<8_?P&P`I`EX$#KTS"K?J%98($G1V\#U;R'R2YQO._->^(,WR!*WUD8XZ5IG\NVF=>6:_J5=;XIT+ -M^OQY\U!@^KT<7(!R(%E`.O:+/NLFSU\\G)"X/&]$`2@*>#)B5'5S:G*VY"\6 -MYV5"#Y'2;ZQ[04DLJ((I7OM'1XVR1(K)YSH?LTO-_@)C2@9"6!EY(?S)*Z.@ -MBD*`9?(0_*6((HLT>F29+F,BW7R6Y1MOHV27:',XW\DGSY45ZID`*@(A -M%N)[6C[R5/Y\W>F*D75TL@U-N'NJY3A(!*\4\C7Y3G4$SVT*YX$5;"`XKKO) -M!1R'6A^6X:U:A^@R%%.<&^#`2,K:LL+>Y(F40HZYN^A"BN: -M4@.`!D[L@X9OU`;B8MG^,D)3@&M>L%3,ZB%/Y6L;5H!KN)(/(H("1:_TU8&-3/)TF'^HHQ8`1\.`FI8GU9SUCI -M+\*F]:[X)Z3@L\^V)66=D!Y5J^9\K2L,#Q[;8Y\+G4ZE2ZLGFPFRO/Y8N>"] -MVQ74BS$X-=;C[UG/T/=Z[)S9X7DP'AHR690 -M!1J15IP6PT9PJ@)NGC,=(-O[4\M8MQZH1P.=$&ESSGN!^>3W7B211(T11X`O -M;D!7@9.Z+XY!O&U6!X_[IFSP,\A]:*Y!_JCVC0/[HH -MK;-0:'N"T\E6FUQ=PI]IFJ;1J0Z\96XNO>#-6+O'!M$!N3YV>]26( -M3J*4A-O/B:',7N?U0,0X7U&J.MI_I-$%P,EFXP'=5=K$ -MXJ;)6L^6/_?8J3G?B#OOXS[E*[7N(EL)X"PJ1X-,0+P)*I?=,,8]Z&Z1T,": -MA2M4K[R2,!B--=2TQCPZ;HD0Y[C$?0$=:EQCR';XTT/RZ(N=FK5'/4K4LV(> -MH*$J&JL@(>VOQB`UQ--DXZK*9#D.0R8D_XLZ!"5_X)0N>=$RDI<M14E00-6O4T0?LXMFM48&9,54%$N8="JS-T2P`- -M5X6>3*+D9SA9G:T5(_2JB?()M;<>(G,>1>Q2VRUR];;,;W$&;[]?\41QZ'O( -M$'5C8A1H;+S#>J6E$A\!SO,U]^/Z,B/C24&/T.:A2:Z71N"3((?CQCAVG8GU -M070P<%A/--_F3+$%@@K8\I>7;PLRQ?0B2'>6GD"*LCTG62DV?*H:_+) -M+;U,!:6H:TOML`-CD*K`LFEC'%L]5.7:ZH58':6;T?&XP\H3QO<*=J0[,R5> -M,)(0U94NPYU!C?UI<+NJY=2(*421XQ;A=5>IJ[+S1'5`'_>"C*A'>"19+4&' -M;:B[(K0,U;GW,`L!.DA09Q[C0R*L!GU8!=%6\M&UW"`1RA(H6,,0I5*V"\L$ -MA6^-7[D>QNOH0"YZMLM#^Y:`+V@'R?">O'LSR9X]:$N-`S?);%[#9?X*2#V! -MMDF6R#SS3H--B"P`&DY`:@UD"ZH`A.+PZ>K=8\NLW3#0R$"1BN7,TUA?X9A>9(P%W`Z*(0PFEF"`>&F+!*ZV_9LS -ME"QOZ38?S[27N/ENZ;73TWNRW<=;B7/@%!S'%UP-MQEM8"+(.>:F'Q94YX;_ -MV:L@B/)<)1XFM5FR95YN7:\`YO[6)8MOK#2P>ODA;N167(U6KX(P'I*LZ.CM -MR'OAS_>\QT4K?6H)$3VN06E(V'/IN`@)9E#-2HYRAX?ZZ^V'Q_1VI.25`Z@. -MEV0K>G:(E=WSDI^R<7TN'2\[S.99;F11+NHI54)3/M)8]Y.5OY@;KN> -MK2ECNDE_WJ&K_*?Y_B7&OX5)E1+[HG/E1(M\J6?)*L=*\TEH\TR#Z[3+<:^8 -M+]6/.@AG63B)Y[;X"'_T+=6((O&'>+>`V@\9^6$%3,1A_E:/%]0O5454))_- -MAYXDY&95UK?_T9J8855UN$"`([!L"";_=6EGG*?6QB&AD]XUI\3YWGB^5>KK -MVC_7K=SUP242V(Z5J9U2.]Q+5J.$]6I7Q&N]Q#S8X!&3MP9<2-,=M,CINTJ+ -MAK=[I@_K -M`9C2[6!D]L>*@72X_8[8#0DY@E2\2C=W(:2'\S]1CA#\*YWGQ&H!M)=3=BU& -M%IX>'-2,F5## -M\_$5O6ZNXD?Y&8#C5!EV`726O[A8F?J1S2>09Y,%[$<<53YO!P_(6AGM4#=& -MO[ZL'_0Y>O0TF=]D9.S_IO,S2"1'&95G093O6,RRG@`I[THCR31.\^^04%OI -M[5?<:-3C8/.H,"3!9DOA1U2:>2SY$A@!"'0;+-C^^3:AFE7>)CF\^PW.@6*J -MZYXIB/:0TGC0S4Q0NY>12ZD`XP4B#=%HP=&A_W1`($4Y[!_L^/5CIJTE%T)` -MY9G7D-:&(W7BW$19!?WHI(@BGOK;$DYB3K#&#-]]/ -M-N`#>X52'T751^A@!,N]Y?D;JW^8>'XM8CI/Z8Q+%*2K$Z[VY* -MB'*T`<(4AXAU@#WM\/^1&ET$0'"@0Q'?M58L5+TB+\;FG`O"$+(X#!\\AAUF%B;6U/"$>0G)69'5]&1`Z*O0X_:DII76)E*+98O\NI*'HK>$FQ\G&R>^%V(KP,>G?`I>$99!+0= -M&;K482>/#SV-?`1LA3LP8&"V`!;RT*?6Q2-^Q]&[ZH#):7#@D?\%GY/3H;Z0 -MK\C8_637'5\`%'J]\)C.KQX@7"-F$BR<#Q\3@2Q*G.+_S]&O19Z0%2^PDQ!@ -M'V,HX-L_'6RN8E_&#T6QEDJP,5C8SAG"\`X5@E?:G&SGD:-`BFT'9PYRKTP- -M>%AP-WTE*Z'(^>`2$:2"NIT+U_V`(SCM\/Y%>O3N//Z<7P1?O%7H%8.<*_. -MTK/;TX!DYS"6A7#0+5A_#<0YXYR,477$JH'%A+)-W6Z=AES71G=`2I`BNV,$C5UCPF> -MAT;S4#X#^`YQY<HS*R1J(7H'>H%GKZ>!DFH)U_FK;?ZM1(GF*\.HQW`?.Z9K;HNB"O -MJY4R6^;YSR:02O@E>WWE88?PU4D'S$[GVD.3QR[9^-/N#1\E(2$HM3U^KTSD -M:>C9R=F>YC!7,)4[/MROT@1X7%AWE`_XO/WS#<0JP'%'@<]5#3W_RLJ4H_%7 -M$+LM;\C[3R"_P6IS].G@;>(=_50UO0,V4C?`5BW!J1[M/(10W[Y<,_+!JLA, -MPA9XRX+!?[13631P:HD@9,36DB&/!1ZA7S74JZW_AAX;X'#LK6V[.C>H4O^O -M]E]/7AF%X^)3(89U>(JARM^+?FBKDVA0`:W^5X4*JP7)+.??!Q]VTE+O)IN@ -MDR#G6UN<'(+TX!U`;`#[VYZR#:+S:]'([8,YQ(AJSYHDAX/H;TIYRH[=%I3] -M&.2HVD1)+9^UU2C3CA`-(F0@Q+._=(N;8_X(\7"WYCK.K-V^;?2/EG+'-3'6 -M:3ZSC;+.18S63*CT:6)2"L'[12.5VTV7\*/4`32>J%A9U(Z*8>4@\1PJ]/S* -M7[EG"-BVP_)1*916COMMZFNL1F-P%HL0AJ[^7;[N"6U,`6$MRB'&GQ-,4 -M$I=P=5*B1!CR"!$F-=HS9D@]WL&2I5GED)*32$U`4P1]OT;MQ%T;?LK5`-&MU"[ -M+H!D"F*)*W'>>*4-0&32$ -M@DP!?-CL#9*!\>\*_YEL1&RVW"W-F6^?[GLG&9'YSW.].\W -M*7CFK$E'QNK_=A\^=,Y8"KFR#OG86K?;1F@`QM4\32U71*I6B#*1B)<7A_GF -MN@`(.DT-^1,_X"\JVNOS&^MR+]O^*-B(XBLS=SAX<9A.IP450:`]!X@:!V/W -M`*/\SJX0"60P=B^L4K$0&RHQ^B&W-$+!Z-73>J,"XJS&2^%BN5.VV4P6C;%!V"T -MH'34PO#[8667]A"..>2C[B4-..+.=3P4]!J+N`N^;E.X0J#`V:RXK#UHT]5L -MQ#3XTDJ@!["+U1.6<"BRS.)TD7GR(D'6VX47/7P=@L9HIT:^(.05T70&9&3N -M:E85CX>G>#8X7>R&9[(=JYXX<1*L359.7/=G[,1V(IE@_<3V/N3C76=%T\ZX -M37>_E)62XIM$V+Y3`0+O+4P`C<_ZT`BSO19"5><.T0+-.7$M*"O^71SD)((G -M#=Y`1E1CRA7"JS8F!+8NBZY.&EY)?830#A8/7/QJOZY2<,O?0V.4[FA==H45@2[?%'NQ;+V -M.%%@*5#8[^Z49]Q)*EQ?[\?C.-_I'M9(^P/WCNX(GT>J_ -M=18QC[#,L8(4D.LE.H8]0E7&))&AA2Y1+!&Z0/UY?Y:6NCAZN^R=T4\9?ZU_7P1=]V*&;LN)N! -M6R"\5$`WEW(K=[;0>6!/@[*AZ+=:;L+.![E;=D/3ZK@W4-B-(>:[B-*ASGF? -M:%]L)A/LN+>%N.B-XE0O'K[:A*?LH01X=:=2^1)'>U.!G?$?KEU+G):TK=BH -M?+M9Y$<4&$WH[=HOD*WU&`8^2A[IY?)0,HK*A?8< -MNVS?K&1Y6.+[2%\3C^X"J0G2E;?E-YP1W;$ZTS(.4I:1R],2,Z*,+6C)^2I=WQ;?%AF*9N -M!2M%R]J2Y&ZP*ZZ8H'E`4?5WD;ZWP(9?TE0U1BF&U(9]/]KHWR4B],KHIWP6 -M+N%`Z&RX0B$:S6)^E14:HI%`RU^"=OD/_)9N!ER,B)EA8=M?8(*[S??',LSUHZ.7_JGG6;;36O$9%L#BQ2PMNBL -MUOOA;!K5LU_OJ1TKV:"[;N,(EX+(,PLIV#@Y+,-.U^8(42U<1EURDWC]-;XW -M-^GI.)'31DVD\A4GHS=O&K8($E7Y7A244(H+)DSNU'%[!]@1-CDNR8=#TL<$ -MV/")>;]:*_S0A]Y"!LBWT[A>26!E)Y3L#[K@I1Q213'@X&DL:[W#E6?(">BJ -MRM"I<`:9V=^`'4F'G47'JO4OY8O\)`(Z3'RL-%,'`LE#I';?T(T:7?%(XI5& -M'G'A;O`E:1@8ISR+J:OTS9`S%%.LW9);0K"3I6.GQ7L85(AO-3LDM$I -M9U/P#^M>AA?A7<+<=V%?B=MW22G3(^Q;"^M3_=\0[":(#Z-Y%I=X;D1_90I; -M.#,<;=&O\L.[D(*V+%_6='O(Z%"T_YE=8R2YARW%!">;G)I-Y<.+2>$5.JID -M+RT5S368)IS/[D)1PN!W"2H\"F%\KR@=+!6$_^*5PWST3AOLD]2J8&CF%5V_ -M(7;,)WM.%L%(W9ATNI25!?_QA2?AD$W3+"0#_K4""Y'NZK?`='=;Q"O;MXP& -M2;M)1"AKYA@!&CUX1<]N:-F71S8&I7<8H'[(O9+JF9^ -M&:CR67=?H&PQ>,N=07B>&GB2^)AW70B_^M_$\20.<`".#;]--:32D:0YV6N# -M$UKA.(A@.0"49W!/)W2A.I%,,F6&!%LJ+UA]RK&WTZBJ!''6TDOY:M>^Q(>A -M@2NXO+\T]6X'[1\"`$>%E!UDHV&EKD(3_9""K!8!ZA?`,.6H3WQA>HO`M^AUSS7W?WA\? -M7)WL]5=;((S+.^(`D\'Q8_+XU[!9]LZ5*3`)3R>2WPT$.Z%MWGW3M:*6"$ZI -M@=Z1TP;9P$5`\C\JKLN5(\CXX_.PS37>.SYP-+F)(&:Y!3A%`_&31DX.6<6_ -MVT<1.4_=F/"C#VTJ0TF>S"CD:8E_K&&:N//%,3O,&S:[57F@XZ+:-!.=G^AX -M*)$:V@W;]@QQI_E -M-)<\*E0;S&`SU'4#.'*TM7,=J>4RFCGG57,M]3BG8>X=/:!R>?WU8;L274&_G-,CB@R5HY9;02!+5S8+F?@M]WDJG:/+6CA)W6PQ&, -MI[E?,T(*4?B:W0HS_MC#;FVAA=J5;2=BQLCN,MV_=6-AT,FIX8CB:>Q([P'Z -MTNC@EZ]6)L38L>&'_1')NDJ^Q9Q+78CH>!)=%K_I^*I-:68H&*V=XFCR0=@L -MRIK0A'F>/%M'#R`T6(SI4ADUGB=V[5TIC`B;[[=Z+]!RA2..9H -M!3^!XV)/W`7[1W0^LB;/C%=T_,H-Q?`<#!/ -M_2+QYR[X$5=M/YE`+WA8Z:`Z]7YN>;9(UHJH7ZS:]^QXQ-"51*.=6*=T+CCZ -M4V,KH7C+TV+TQSYG@1^/L1>^\R"*'`S.77]A&-,]SZ6B,4W$/MGR7.%IV%QC -M70[DZZHC&IBN<_]0]_`*MR_]N)9:/3KG)"0-.]WQKQ'.`$MX4&/6?EI_^`-0 -M$'L#/'B@LSNU6!C[&0J#O3@8I1&,3!%<\'ESTTV6]P6&&(DH-?J,=A]638MW -MF<,*:U$Q`YWYU8]DQ`M/KC3@DPVJK$@6H$+=-]M#^E[T<72D+]6D(&CL*>#J)!N\!7]MWZ>P\;G:%RYO$^O -MB^,;$WRF=4MKZ8K6./3!R[;EI->&>YWP^XC^%Q>F+8";-?7M6>ONZ! -M'R"*G(1*_<+U7?(;I>TP0>?=B((9OI-"-^3YX3[)];#T5HS?`YOGIY`&L=R] -MJ`@%Z(8[=V\\%GY(1L_/9?VF"X=34SQ]!]

    / -MC<`(M2A)9(3T.X[+\FCZGPH7-DMHOH,;Q$=551M-I7V;5155599%WY.7DIC' -MQG,-66XV=37UU;5-#XU%>;Z:QW#61(=T5%L:RNL,BT*G6MF.JQJMVBZH\$=_ -ME!4_&ILJC85F:+\-:W2TM-I-+W'T>ATE)H$\9Q#;*VRL[\^`3T0?V@8 -M;,!]:1T#]4">55:6(#^"]-5=:.U59UYAM2/]5UFOJ+2NL\D`9U`EHT6^QK01 -M@`X`O6Q`,5@!L$>5U<'=UNO:!&]H`="5**JU]G:;74:G5%AL2/\9C^&\/YLK -M`!Q6Z\/:LB]3G;@O=74+@ZJ+'86FS(>P[@>P+_`#8-V"#=&#HE.SOG1"_S\; -M#J^;PS5Z$_--4510F"$2-=+_58"&.Q6[`B-9?#[/QGMUI@UMJT%QH`P0=9U6 -M]G7AKP(/7;7)&=;.PKB1RUE&B+!_Z/]3^<;0`R1N)/"P_45<`^GXVVDCOGG0 -M17E9450;"B?B0_5+8%S55`HO.`_F/UGJ(0[W`=IICNK)(C8CKL+$>NQ$S[`/ -M010#^S%(Z2(K!>JD?&TXHC1L]GJ-)K-`[LOI!XC)9&5VMHJ:P@_DBX/3$X(T -MV8*X:T&4V&4H57X_^R-_@G;Y%@.[)Z#D>35IM*T^P*N%`S1T,7,9FAZ_L>P( -MO@(S9&&ZBLK&"U<[[(W@@SMDDGM%1:0VI%YH4EJ)O_MAXU5F`^@7V@7_XE)75`@<*)WLZ\0ZU];5+H^ -MB\,OX9QBSM+*7I/>2PH$>%F:6)Z\)E8N6#=@MJ`P84`KQ*_V(!FRK,U?/\4HLSSGK2.Y>C?4!U7UUIL]I92J!3[@.];V?=:/0=Q]%W -MPMD$QRE`]!GM@/\):(X>,W:&#&1J*[;5&XLLCA9'MB`\@OX3&!_('T*GN11A -M#]@.*_(D/G;O'+2YGDR_%69G+XV[=RLC^6:91.0_\,Q//XD^@.AC+-9850>3 -M(5DX\'R/C7GK:559?S]R8J46?E"?5?2`ZV`?R']U%F]%!!!\BKHNAI_F@V=1 -M5661:8_(FN:PG[@@_U_QPO$H3XRWPAZ`=5%2)ONBJ-30D!9,]*ZR>D^D%SH6 -MZH3V"'O7[C`$M@/D&9$3Y5F>;(FZ!A_,GE>S^A&[[)&3^9%LJ8>F?-$B!:E_ -MZNK=E6&B2E17+:4J3=%785)\@KP.A&%SSH5_P'^B:;J0&F)ROS2KL"@ -M?2PI:5U=1)1_L"2%_);D:5GOCLUN]!6:]=$NP5[=DR#^IM+._&SNOVPF"E>$ -MJ'>P!>K2PE3SP1VJ)=+Y_?E"WX:5EX_]I;O.4PJ>XM-@:Z%FCBH>KW"ZXRP< -MJ-IN,*!BTLDF2Q^^S1`OZ"BU.2>G'EDP;`D-BX[P.[T1G'8=AA7[O<5+W4+E -M=F*Y+J)YZ/7(V;*R6/X)PTE&\V*IL;0()FB*+:2?\2=X"N?Y55]+=MI7A:))_G:'Y%_>$'_`(YK@<.<`:.DB]@R="J>2>/W@?-*S^ -M\@_HB#2`Q16=>9QGY'#\B'6_0=X`2X0``W(0#BPKZUB1>5%\>F^&=C6@;[LZ -M7.TU-H-/W",.%(!3\H?PH#S9!-;7-//UA4M!\DJ!]JQ!L5/[N`=(:GQ19W)3 -MDJDV43G="`>@]4`M!16&2PHW -M6^//-!+'G\@)1_`SZ$SO\$:H5D45-B3^+Y+>23S6;<"?V@^3?GI$MFDOD:]P -M$B_[J1]HMD@+LJVIK42+#O8T3DT+^B1I:1*2R0R3!+`XEW]7\R9OJR]E/WZ4OL#=UE@+#=DQ]+JG.O -ME5]I#3=HJ"8>"&`ORBM`_^BV`ZP2K5;UYWAD.;%$3X6>S29]#WSW"H'06,_J -M*[!9OV&;;2]"T*!VA_^#!6`Q8)X\1&M@/-=A,7S?63\7:G9M9ZD_E?\OKJ,( -MYEI3"`EA0X(8*E*]P@73#%O*RQB_LZ^7KOYB/G>4+#?FB>+YHD)ZLI45[G)= -M+.08^6L$M'P[NBHC.,=*#Q&3XU^0-BR"&YE&CK"">+3:"O:';7\JWLJ`^R-= -M99%)?3$N"Q5#1#-F!^:BN20QID)WWEI7ADHC+23D3[`^6+N_3#`KN58!HUU5 -MOZEB8GL*5[?CQM*?IYHESP&A/RD\89.L%)M&VLH5FOA[M1+L9X#KY0LMW$-% -ML4)\L38JV6`.O&G<+=F7/C0F-KQUPN;NH^-B<2K2^(_*P:E -M2"C2](==*[];/+SJR7-+JZ46IPBK<'YA.RL>AVM50KA"-P/!$ZZHK-$\PQMV -MM\(HUN?F4D/23_*W_U%ETHOLO;S_"!8@.005#!):4+RP.$\C..D[U3&RJPDK -MFOL7E!\!VNR6_L@+LSRSQ7_SU#[Z[0Z73]OG:;"+$=L=@F+)^7-Y86-89UI#SQ -MD0L(K,CV2$ZOG=_(@;H\V%'A2A^@SWRU#*:">.G`E;LZ_"`9$YII.#9':64T -MAM'@?$]XOS7V6%2.4C/T*Z)/P?UMR34D.,BNX>Y&A8[C")N5&R(G@?_KP8$) -M[]7;@G;J25:T$]I=+J-)JF1_J&BV=_?O!:3F_*K^P146B#%,3+^(N64SWV5_5I_6[2651I*@W)FU^.!DC>V=H42TL3HW*X8;OLDQ -M.>[)9?)#V/F.*2X(JT5$B/=7^2W*DO[*J$-"7=K=U+R6'K@N=J(/[19-VZO7 -M@5A7Y6O-^6'W1:ISUK)\P%PW]3N&5U)1_R@#6(3XBNLAEP6KL!10UJ-! -M2#YD782SXD-;9[AJ4ZX&Q>J/""?35/B.T`ZK+%=L\2ZF@W-\IXE1K85U0(.Q -M'T%[6RF;`^97Q?W5ZJ:\B'TKWEDDM_?F<1>.2B8C@#W8,32+4SR)@E>_@42; -M>H%E="<_4<7MT=\.V3-DA?_9(+2-27=V4X;EIVU"UVX_VB;%,]I7#0-B,WJP -M#F743@O#5'G;!>__;GHW3=W]O'\+HL$5U*5#46)^M*_$LJV@[+C=M&TWPF'M -MD\I_('\J11,RUTRA&IPSL>63WV:+=I7$WYD*WO14F`;G9FX86R'_PM+Y9O\- -MFLSEE9FZ3FQETF@E^0"A+"K07Z^2?!#_3`Y<4FH[L4$TNGU`FW.UK;$.2J_, -MYM0#JM091<_(3#`(JSI_9#YKP/0W%4%^,8A2U8FK*4H[XP>%T%E]Y1)-T`E, -M,KS8K/V*A_SI>V%?VC7Y$39(@3+1@_V=D\J7-_O$YED>WN#;_C++?Z+*?5H* -M\!GW8K3#W!WZEU.25=OLR>9S3UE@:-H7B9J;38&K_3Y$?@^@C^!!NT!6:ZRC -M;#:6F4DFP7>?-B`(H'"7C_YL>WT`[>B[C4M7SDN-C9V=AFLKE=L/[*//SE;* -MOU]GMA-^LK?.F54:)%W\URZ%RM!:@-2G)#_@H/1#Y9HZY4PP/_[M]+#_@N@K -MBRKET/N41J4#B7:Q'=?2$9TL"#3C9H#)_M"DT[-#@4)FKKZI(KA;^*%JQM-I -MFEW"XOA_DO:)7S>O,BL`A>]J)+E/-Y#_W(NMX.^5!18Y6R%E&LRLIB?:;4Z6 -MFTG<:+NTK[H^Z*3\,1Z0[#N:VK6=\&C:EISEI7B_O_S3+Y#/:6DU/;]QJ,$` -MO'WUST//\8#NFSO:$S?8(`2O0IMKXX'CS_7A-ABJJO7[#8UNRKMFX6'>!`_; -M3:[;-;<.,]G]#HM'I,U2=QIM.!]YK4ZK64;Z5!TDZPL98#&3_B'64/_=()U* -M*JTMRG)'8#>WRC6H%PGX'YJ-H^S]0" -MNBPU%5VP*QWM:'`,6>TI-+GNV[M(GX?U^],F;D/RQTVD[?0/2O%\.%!O5IG\ -MP7;P[+,X\^Y6[V^OQT:`,1&M:U:0;^CD%JMKR9_/4[[KLAH\UD.WR3%496F/ -MM%?H/T!,AJZ+(;,?X0=+=MTU&4R'<#S[W`L\NZ(\EV@_/3R)>5H'P1O>],Q[ -MV=?M$6;P9ETLBRCIE"4D:K!(=Y0^;,#^B[5H$JY7@IT<"O_=]W*KRC`Q/IM/ -M.%_.I\)[]%;ZR8:Z]H.W0=:\_3/G5]Y+L@QVFT7=EH`_H"[NB^AM"'@_/PX$ -M5E;`')IYW=3465877ZF2%)M>'XJY6!BCYVOLLB]E\#2(>%U%NL:,.JVJ6D?" -MUHTD\EVA_LU*5#T8G%17&X3S<43%[-\'Q`AE>%_/+YP2"A1MP9G'D)Q\>_S= -M:#(97/Z33Z#/CL?=6\>59BT^^,NUCZ_W1IID3$_N4NCP -M^>`6?'SUU<,7.E5S3+Q%/:2@*.$-W1[RL%'#Y]?L!W!F(M?/R.LI??:42DB_ -M&7-91S\DN_725@F48T3O+Y,&O0CH$`4?&8:/2J/U/>49>C&UX. -MUH@B>@D"J>8UHSRM]-[^WQ^@!'5=\W!#95\OTF&^>K:ONV[?14U+H -M-89`&-49C(ERIMST`$6DUZ^]&VE?U=?_L(*35@X>^@SU,^K-!L-%LNVV?; -MV%+9TVXU?>ZPG7C.M=QJ:2D,5C:ZV+]%K;!7G%@*=R;$^;$&-V`N7]"*S;UE -M4X;@5']LPGDKJX)U,KE*ZMJ0F>*ZSHL#BG9B^QSDVO&8_?]9TNCU"YBCU#W[ -M[^U,5;S/6819%KXK[D_SI]2&]8IY,W6%CXI^HQ$79F5WHGI[S)*JBV8\:D4- -M8E?V0V>5R%6/\AI7D#%^:3OM[N$&\7B2M`.LDEA=GS3L^H,]DGTY2"M>=H+* -M8T5+2;7+]=FDL!R?.5;#>7-I_@G>JRQE)Y\]8#5SKOH92[BOM#./V,UG7O6Z$]A;48@31)E_]UP -M*V;`,]"OJ^;,%:W6DVE4$JSLZS9G#`[?8U%H4;^0 -M!MV?1LI_HI2OE?O7(DG[76];?_8MJ(:"E?95CY792JECK`)WD)8Y_BTG>1EF -MNRM->$5_-E)O^$V\78YOAD&W]EIJ1,HUYW49[2:1USVCSN -MGU&@IL[2:0,(2+Y\E6.HRG`8]KQ)-_,W[[=4#5Q#7]/"],OZ>TZI2/K##/J^`QUL< -M^^,5?]>AT:_@[E>.F?55NXWB9-KSBR3J_HC3%7V.R\_5P$.,VY],2OZN=^8I -M\[PV>>[/?$-QG&>7CM1!X()[W$.0UKU3GGOSN&^^7_W.U4KYO'&C\7__QTY/ -M.UM]**>(^6M3/)B?[;]D?L3UL!DF[7.K/ET3NTI1]H'O>A=N85E\[Y.;/0R>.A_(\5W@Y'<6XZK,IG>TT@NIZV#WJ4"]J;2MKJNB%F?W=&UZ/&KW&T%D( -MSN`=L:6(/Q?_3NRUV-97(Z,\+"NLTAXK3_Z6(\RA^GOL-5>?I3<"'[3]OE`O -MKZKVX\JS8A1')LETMW_=U%B/3<.;E>?TJJQ6)R'8K:HP]@:GU6#NI%AL90V( -MX!^\8$#,Q"N++Y3(2=EDBA^O!7ZMROYZ85&.;>=#]=N.+2LS"KC59V*G8MX] -M7E-N;[X.@[">[P7'$S##Y+[Z\#]!X8DPGV7!=Q3PEGZ/Y-B+S`V"Y7WU4RH8 -MYTS@A$[A\L^#D)[O.GDS!LIVF97W6L/XGF3_/>Q*T]9;Z]@[/I+S.6`RHYN\ -M4K=^(D(IE)=T-33SG';P5;AJSWSPS-,K"9OJF-[[`1=VTNZ(:1QT(K=@D-/V" -MIJE;Z9WGDWX%<>8W,8+#/YEY;9!8@%]B3Z?Z5Y;ER%`I'<]/+OLQ+S7'FJ]/ -MHR:Y$^P97[WV#&7E;^:7!2@M'3IZC_I9"_GEW2ZUL"2N&95EWKV'O-V)\>ZN -M%Q#5Y+N38K/9W66E.Q+(N>VP"]]!;_)_1#+1X)3H\*WW]K2Z?N5Y0"?UTF(. -M`P;!``#!``"```$"44^A\!DE/`"%P`(WC,$\)C("`PO.OP($N,4%[8,"ZY%O -JB(`%`1)E;&8M3&EN=7@M05)-=CRW#!V][-VM'MJ^^#686N9>>L\.7ZE#3!_/][K2S]G1DR+Z^7F8BN1X0 -M5C;9*7958_V2?B;;=J=N[KHV+"ZA!YHY#/G_C>:Y+\RFMN%A8]94O?OY_AM< -MPE=<8[N7Y/@&A*5GFV:9E;M&8JU!O/TIK!)5X(1%@FPVF'!BV@KI;P1X;E7% -MUF:9HH_W^02_+:F+$Y(@/'B`PID.TWYQE_\RLWU#)O3.[Q($`^A166GIT;W; -MTJ2BC%X%D3X'SO%DLWP[4Y@FL"%R-TR'QED.B&5!.:-0?\(Z*Y>@-Q\DTM%F$NB_) -MR2,7&FYP>)NZC>$5IF2H83OILZ:Z@5?,CH';."Z1XHD*/TW>0;:#%+'H].L@ -M]Y$F)>Z]H[`(+UQGS7TRO#-_QJ!U%RCGU1\95849&LP&15-H7.]MZ[78W*#A -M&G"U:H/3OF)^-H<4X%:Q^/'7#KVGX!=*N0!%4X-1'89S/0E)E,ZW!'')%(R( -MD].ET_+8,B]G5;8>I3T*8I8CH+E&UKAJ]WA;%(A/KO`R^M\ -,"^WWU!UW5E$#!00` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_block_size_is_too_small.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar5_block_size_is_too_small.rar.uu deleted file mode 100644 index 5cad2194e..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_block_size_is_too_small.rar.uu +++ /dev/null @@ -1,8 +0,0 @@ -begin 644 test_read_format_rar5_block_size_is_too_small.rar -M4F%R(1H'`0"-[P+2``+'(!P,("`@N`,!`B`@("`@("`@("`@("`@("#_("`@ -M("`@("`@("`@((:Q;2!4-'-^4B`!((WO`M(``O\@$/\@-R`@("`@("`@("`@ -M``X@("`@("`@____("`@("`@(/\@("`@("`@("`@("#_(+6U,2"UM;6UM[CU -M)B`@*(0G(`!.`#D\3R``(/__(,+_````-0#_($&%*/HE=C+N`"```"```"`D -J`)$#("#_("#__P`@__\@_R#_("`@("`@("#_("#__R`@(/__("#__R`" -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_compressed.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar5_compressed.rar.uu deleted file mode 100644 index f9f811c6d..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_compressed.rar.uu +++ /dev/null @@ -1,13 +0,0 @@ -begin 644 rar5_compressed.rar -M4F%R(1H'`0#SX8+K"P$%!P`&`0&`@(``B<9?VB8"`POI`@2P":2#`LUPRGR` -M!0$(=&5S="YB:6X*`Q.+5ZQ;^!BM'LKT90$G96!4'U5V7;^4DG')SV6660QP -MV663&,62$X9"223AD)"2220DXY))(0A))"$)))"22$(2$LVU;WM],PZ`?1T# -MKC^>NI_W0?[WVO?=>:\Z7^@`0`$`R""?GX]O7T\O'O[NSKZNGHY^7DX^+AX- -M_=W-K9U];5U-/2T,_-S,K)R,?&Q<3#P;^]O+NYN+>VM;2SLK&OKJVKJJFGI: -M2CHJ&@GYV'9T$&P`\Q!(R">9A6-`NFH9;8 -M-YN'@X!@<@^N81.@IG88#P-MZ'N]AU?0C?Q80(T8,><*'DT)@V+XX.8Z'"($ -?J>&%%CMC0_GQ4(!L(0T(A-(QG)`O)0`==U91`P4$```` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu deleted file mode 100644 index 34d8ce3f7..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu +++ /dev/null @@ -1,10 +0,0 @@ -begin 644 test_read_format_rar5_decode_number_out_of_bounds_read.rar -M4F%R(1H'`0!3@"KT`P+G(@(0("`@@`L!!"`@("`@(($D_[BJ2"!::7!)210V -M+0#ZF#)Q!`+>YPW_("`@("``_R````````````````````````````!__P`` -M``````!T72`@/EW_(/\@("`@("`@("`@("`@("`@("`@("`@("`@(/\@("`@ -M("`@("#_("`@("`@("`@("`@("`@("`@("`@("`@("#_("`@("`@("`@_R`@ -M("`@("`@("`@("`@("`@("`@("`@("`@_R`@("`@("`@(/\@("`@("`@("`@ -M("`@("`@("`@("`@("`@(/\@("`@("`@("#_("`@("`@("`@("`@("`@("`@ -E("`@("`@("#_("`@("`@("`@_R`@("`@("`@("`@("`@("`@(``` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_different_solid_window_size.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar5_different_solid_window_size.rar.uu deleted file mode 100644 index b131e6f00..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_different_solid_window_size.rar.uu +++ /dev/null @@ -1,73 +0,0 @@ -begin 644 test_read_format_rar5_different_solid_window_size.rar -M4F%R(1H'`0"-[P+2``'#M#P\7P$'`0"-[P+2``7#````1H68F`#___\````` -M```0^OKZ^OJ%F)B8F)A)`)@"F-(%87)4`,.T/#Q?`0\"T@`"QP\`"7(A -MFC$!$AHCTBT``B@A4F%2(1H'&.D````!`(WO`M(`!<-%````1A?'#P`)\"T@`"QP\`"7(AFC$! -M$AHCTBT``B@A4F%2(1H'&.D````!`(WO`M(`!<-%````1A?'#P`)7!E/6P*+@HN"BYT+G0@='G^6_]P9\"T@`"TGX!M,-'4CQ2:7`)20`&`````````(WO`M(``0!R(8WO`M(``0!R -M(8WO`M(``0!R(8WO`M(`M`%?C>\"T@`"TGX!M,-'4CQ:!@!I`'`)20`````` -M`(WO`M(``0!R(8WO`M(``0!R(8WO`M(``0!R(8WO`M(`M`%?C>^NT@`"TGX! -MM%)A\"T@`"PP<<@`<`_O__T?___^@@JP#_Q00``B$<`0(`#@`` -M`0``_@C2(`$>____"```_?__$`#_W5A04)#_!&R&;;%DS,RWL0!)`(/__P#_ -M`/\`^?__\&3/)#)(L0!)`#J#+O_______REH%PHHV#!="0"N)$%SF_J;$___ -M_YP#%9,I````_________Q/_____________________________________ -M_RC_____`P````````#_____*/]!04%!0=U891/_9?]0/2[_______\I:!<* -M*-@P70D`KB1!\"T@`````````````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_different_window_size.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar5_different_window_size.rar.uu deleted file mode 100644 index bb4c4a604..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_different_window_size.rar.uu +++ /dev/null @@ -1,675 +0,0 @@ -begin 600 test_read_format_rar5_different_window_size.rar -M4F%R(1H'`0"-[P+2``'#M#P\7P$'`0"-[P+2``7#`/KZ^OKZA5N8F)B8F)@` -MF`*8T@7"F!=A_________P$$_____________________R%285(A&@?_____ -M_________________V@`[E##M#P\7P$'`0"-[P+2``7"87)26`!W=%)A\"T@`"QP\)`'(A&@\"T@`" -MQP\`"7(AFC`!&B/2+0`"*"%285(A&@<8`0"-[P+2``7#10!A4B$:!Q@!`#)S -M-/_______U)A\"T@`"!QS1T='1T='1T='6T='1T='1T='1T='1 -MT='1T='1T='1T='1T=&UQX`.`"'X"/\E``*H'#`"`/+__TO__O_G*_____\` -M`"\O``#_02+M____`-X`_["&AFVQJ@,#45TW,?;V]@$``/____\3]O;V]O;_ -M_S\``/]!(.VG+R\``/]!(.T)__^PWOS_```O+S$``/8@[;L````````````` -M-3XR9%Q<7%Q<7%Q<7%Q<7%QZ7%PJ7%Q<7"]<7%Q<7%Q<7%Q<7%Q<7%Q<7%Q< -M7#)<7#9<,F1I9V5R=#4V,61I870]+@HN"G0@9&5V270@9&1I9V5S7%Q<7'=E -M9"XR9&EG97)T-38R9&EA=#TN"BX*="!D979)="!D9&EG97-T/2X*+@HN"@HF -M+BX**%)A\"T@`"!QS1T='1T='1T='6T='1T='1T='1T='1T='1 -MT='1T='1T='1T=&UQX`.`"'X"/\E``*H'#`"`/+__TO__O_G*_____\``"\O -M``#_02+M____`-X`_["&AFVQJ@,#45TW,?;V]@$````````3]O;V]O;__S\` -M`/]!(.VG+R\``/]!(.T)__^PWOS_```O+P```/8@[;L`````````````-38R -M9%Q<7%Q<7%Q<7%Q<7%QZ7%PJ7%Q<7"]<7%Q<7%Q<7%Q<7%Q<7%Q<7%Q<7#)< -M7#9<,F1I9V5R=#4V,61I870]+@HN"G0@9&5V270@9&1I9V5S7%Q<7'=E9"XR -M9&EG97)T-38R9&EA=#TN"BX*="!D979)="!D9&EG97-T/2X*+@HN"@HF+E)A -M\"T@`"PP<KJZNKJZNKJZNKJZNKJZNKJ -MZNKJZNKJZNKJZNKJZNKJZNKJZNKJZNKJZNKJZNK#P\/#P\/#P\/#R\-MP\/# -MP\/#P\/#P\/#P\/#P\/#`\"T@`#QP\`"2$:TB,M``(H(5)A4B$:!Q@!`(WO`M(`!0`````````````` -M`````````0``````_____P#_965E965E965E965E965E965E8'-T/2X*+@HN -M"C(P-S`W,&EA='EAEQ<*EQ<7%PO7%Q<7%Q<7%Q<7%Q<7%Q<7%Q<7%PR7%PV7#!D:6=E -M\"T@`%PP`:!P`$9P`` -M````````[P+2``+'#P`)`"X),AP`_0$`%___"0`N"3(<`/T!`!?__Q%287(A -M_Q%287(A&H\Q`"@HW,@```/V-[P+2 -M``+'`"X),1P`_0$`%___$5)A<@$`C>\"T@`%PP`:!P`$9P``````````[P+2 -M``+'#P`)`"X),AP`_0$`%___$5)A\"T@`#QP\`"2$:TB,M``DA -M&M(C+0`"*"%285(A&@<8`0"-[P+2``7#`!H'`/R8__]E965E965E965E965E -M965E965@6%R(0HN"@HF+B8N"B@*+@HN"BY0 -M7B]A,C5I-F1G97-T/2X*+@HN"@HF+BX*"@HF+BX**`HN"BX*+E!<-3,R-C)D -M+W-.="`@6W-T/3TN"BX*+@H*)BXN"B@*+@HN"BY07#4S,C8A(2$A(2$A(2$A -M(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A -M(2$A(2$A(2$A(2$A(2$A(2$A+@H*)BXN+EPV7#)D:6=E\"T@`%```` -M```````````````````!``````#_____```O+P``_T$@[?___[#>`/\`AH:Q -M;?;V]@.J_O;_S_\`Q+[?$?;?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?___?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_? -MW]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W]_?W_^[XP## -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````````````#_________ -M__________________________________________\````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````````"`````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````````````````````````````````+8````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````````````!287(A&@\"T@`%PF%R4E@`=W1287(A&@EFZ>45J>E"(8*1QP&#AP1O__`````!X````````````` -MNKJZNKJZN@'U``"R____`````!X```"````````````````````````````` -M`"Q!`````````"T`%0``:#H`6@$M\"T@`"PP<< -MP@2```#_;24``F<<`0(`#@```0!02P@#`"8F)@!`___/0T+_____\?__K2-T -M='3_______[______R9"____,3,U__\3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3 -M$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$R8J8BQB`/______0D)"0D)"0D)"0D)"0D)" -M0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D+;V]O;V]O;V]O;V]O;-C8V -M-C8V&4PA`C8V-C8V-C8V-C8V-C8V&4PA`C8V-C8V-C8V-C8V-C8H*"@H*"@H -M*"@H*"@H(1H'`0"-[P(H*"@H*"@V-C8V-C8V-C8V-I8V-C8V-C8V-MO;VP`` -M````````````````````````````V]O;V]L`VP````#;V]L`VR@H*"@H*#8V -M-C8V-C8V-C8VEC8V-C8V-C8VV]O;``````````````````````````````#; -MV]O;VP#;`````-O;VP#;``````````````````````!"0D)"0D)"0D)S0D)" -M0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0EU=75)A4B$:!V%R0D)"0D)"0D)" -M0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0MO;V]O;V]O; -MV]O;V]LV-C8V-C893"$"-C8V-C8V-C8V-C8V-C893"$"-C8V-C8V-C8V-C8V -M-B@H*"@H*"@H*"@H*"@A&@\" -M*"@H*"@H-C8V-C8V-C8V-C:6-C8V-C8V-C;;V]L````````````````````` -M`````````-O;V]O;`-L`````V]O;`-L``````````````````````$)"0D)" -M0D)"0G-"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"75U=4F%2(1H'87)" -M0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)" -MV]O;V]O;V]O;V]O;VS8V-C8V-AE,(0(V-C8V-C8V-C8V-C8V-AE,(0(V-C8V -M-C8V-C8V-C8V*"@H*"@H*"@H*"@H*"$:!P$`C>\"*"@H*"@H-C8V-C8V-C8V -M-C:6-C8V-C8V-C;;V]L``````````````````````````````-O;V]O;`-L` -M````V]O;`-LH*"@H*"@V-C8V-C8V-C8V-I8V-C8V-C8V-MO;VP`````````` -M````````````````````V]O;V]L`VP````#;V]L`VP`````````````````` -M````0D)"0D)"0D)"\"T@`%PT4```!&%<\"T@`%PF%R4E@`=W1287(A&@7EY0H```#EY>7EY>7EY>7EY>7EY>7EY>7EY>7E -MY>7EY>7EY>5W=V%R(2\O+R`N"@H*75U=75U9R,C(R,C(R,C(R,C(R"<.`'\` -M``I=70!=!UU=7=D`Y>7EY>7EY>7EY>7EY>7EY>7EY>7EY>7EY>7EY>7EY>7E -MY>7EY>7EY>7EY>7EY>7EY>7EY4$X.#@X]C@X+3@X.#@X.#@X.#@X.#@X.#@X -M.#@X.#@X.#@X.#@X.#@X.#@X.#@X.#@X.#AR.#@X.#@X.#@X.#@X.#@X.#@X -M.#@X./DX.#@X.#@X.#@X.#@X.#@X.#@X.#@X.#@X\"T@`%P_J%6YB8F)B8F`"8`IC2!<*8%V'_ -M________`03_____________________(5)A4B$:!___________________ -M____:`#N4,.T/#Q?`0\"T@`" -MQP\)`'(A&@\"T@`"QP\`"7(AFC`! -M&B/2+0`"*"%285(A&@<8`0"-[P+2``7#15\!!P$`C>\"T@`%PF%R4E@`=W12 -M87(A&@\"T@`%PP```$85!<)A -M\"T@`%PT4```!&%<\"T@`%PF%R4E@` -M=W1287(A&@`````````````+JZNKJZNKH!]0``LO___P`````>```` -M@``````````````````````````````L00`````````M`!4``&@Z`%H!+7-L -M-S8`R!$`````````XJ$`8VDP`#(`93$``/_______________P`````````` -M``H*"@H```!=75U=75U=75U=75U=75T````````````````````````````` -M``````!287(A&@7E"@```.7EY>7EY>7EY>7EY>7EY>7EY>7E -MY>7EY>7EY>7EY7=W87(A+R\O("X*"@I=75U=75G(R,C(R,C(R,C(R,C()PX` -M?P``"EU=`%T'75U=V0#EY>7EY>7EY>7EY>7EY>7EY>7EY>7EY>7EY>7EY>7E -MY>7EY>7EY>7EY>7EY>7EY>7EY>7E03@X.#CV.#@M.#@X.#@X.#@X.#@X.#@X -M.#@X.#@X.#@X.#@X.#@X.#@X.#@X.#@X.#@X.'(X.#@X.#@X.#@X.#@X.#@X -M.#@X.#@X^3@X.#@X.#@X.#@X.#@X.#@X.#@X.#@X.#AR.#@X=_[_________ -M&4PA`C8V-C8V-C8V-C8V-C8R&4PA`C8V-C8V-C8V-C8V-C8V-C8V-C8V"#8V -M-C:6-C8V-C8V-C;;V]O;V]O;V__;V]O;V]O;V]O;V]O;V]O;VS8V-C8V-C8V -M-C8V-C8V-@@V-C8VEC8V-C8V-C8VV]O;V]O;V]O;V]O;V]O;V]O;V]O;V]O; -MV]LV-C8V-C;;V]O;V]O;V]O;VUU=75U=75U=75U=75U=75U=75U=V]O;V]O; -MV]LV-C8V-C8V&4PA`C8V-C8V-C8V-MO;V]O;V]O;V]O;V]O;V]O;V]O;V]O; -MV]O;-C8V-C8V-AE,(0(V-C8V-C8V-C8V-C8V-AE,(0(V-C8V-C8V-C8V-C8V -M-C8V-C8V-C8V-C:6-C8V-C8V-C;;V]O;V]O;V]O;V]O;V]O;V]O;V]O;V]O; -MV]O;V]O;V]O;V]O;V]O;V]O;V]O;V]M"0D)"```````````````````````` -M``````````````````````````````````````````````````!"0D)"0D)" -M0D)S0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0EU=75)A4B$:!V%R0D)" -M0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0MO; -MV]O;V]O;V]O;V]LV-C8V-C893"$"-C8V-C8V-C8V-C8V-C893"$"-C8V-C8V -M-C8V-C8V-B@H*"@H*"@H*"@H*"@A&@\"*"@H*"@H-C8V-C8V-C8V-C:6-C8V-C8V -M-C;;V]L``````````````````````````````-O;V]O;`-L`````V]O;`-O_ -M____________________________________________________________ -M_____________________R8@)B8?)B8F)B8F)B8F)B8F)R8F```````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````````````````/8``)0X.#@X73@X..7EY>4*```` -MY>7EY>7EY>7EY>7EY>7EY>7EY>7EY>7EY>7EY>7E=W=A7EY>7EY>7E -MY>7EY>7EY>7EY>7EY>7EY>7EY>7EY>7EY>7EY>7EY>7EY>7EY>7EY>5!.#@X -M./8X."TX.#@X.#@X.#@X.#@X.#@X.#@X.#@X.#@X.#@X.#@X.#@X.#@X.#@X -M.#@X\"*"@H*"@H-C8V-C8V-C8V-C:6-C8V-C8V-C;;V]L````````````````` -M`````````````-O;V]O;`-L`````V]O;`-L``````````````````````$)" -M0D)"0D)"0G-"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"75U=4F%2(1H' -M87)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)" -M0D)"V]O;V]O;V]O;V]O;VS8V-C8V-AE,(0(V-C8V-C8V-C8V-C8V-AE,(0(V -M-C8V-C8V-C8V-C8V*"@H*"@H*"@H*"@H*"$:!P$`C>\"*"@H*"@H-C8V-C8V -M-C8V-C:6-C8V-C8V-C;;V]L``````````````````````````````-O;V]O; -M`-L`````V]O;`-LH*"@H*"@V-C8V-C8V-C8V-I8V-C8V-C8V-MO;VP`````` -M````````````````````````V]O;V]L`VP````#;V]L`VP`````````````` -M````````0D)"0D)"0D)"\"*"@H*"@H-C8V-C8V-C8V-C:6-C8V-C8V-C;;V]L````` -M`````````````````````````-O;V]O;`-L`````V]O;`-L"-C8V-C8V-C8V -M-C8V-B@H*"@H*"@H*"@H*"@A&@\"*"@H*"@H-C8V-C8V-C8V-C:6-C8V-C8V-C;; -MV]L``````````````````````````````-O;V]O;`-L`````V]O;`-O_____ -M____________________________________________________________ -M_________________R8@)B8?)B8F)B8F)B8F)B8F)R8F```````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````````````/8``)0X.#@X73@X..7EY>4*````Y>7E -MY>7EY>7EY>7EY>7EY>7EY>7EY>7EY>7EY>7E=W=A7EY>7EY>7EY>7E -MY>7EY>7EY>7EY>7EY>7EY>7EY>7EY>7EY>7EY>7EY>7EY>7EY>5!.#@X./8X -M."TX.#@X.#@X.#@X.#@X.#@X.#@X.#@X.#@X.#@X.#@X.#@X.#@X.#@X.#@X -M\" -M*"@H*"@H-C8V-C8V-C8V-C:6-C8V-C8V-C;;V]L````````````````````` -M`````````-O;V]O;`-L`````V]O;`-L``````````````````````$)"0D)" -M0D)"0G-"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"75U=4F%2(1H'87)" -M0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)"0D)" -MV]O;V]O;V]O;V]O;VS8V-C8V-AE,(0(V-C8V-C8V-C8V-C8V-AE,(0(V-C8V -M-C8V-C8V-C8V*"@H*"@H*"@H*"@H*"$:!P$`C>\"*"@H*"@H-C8V-C8V-C8V -M-C:6-C8V-C8V-C;;V]L``````````````````````````````-O;V]O;`-L` -M````V]O;`-LH*"@H*"@V-C8V-C8V-C8V-I8V-C8V-C8V-MO;VP`````````` -M````````````````````V]O;V]L`VP````#;V]L`VP`````````````````` -M````0D)"0D)"0D)"\"*"@H*"@H-C8V-C8V-C8V-C:6-C8V-C8V-C;;V]L````````` -@`````````````````````-O;V]O;`-L`````V]O;`-L` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_different_winsize_on_merge.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar5_different_winsize_on_merge.rar.uu deleted file mode 100644 index 85391fa4e..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_different_winsize_on_merge.rar.uu +++ /dev/null @@ -1,16 +0,0 @@ -begin 644 test_read_format_rar5_different_winsize_on_merge.rar.uu -M4F%R(1H'`0"-[P+2``+''QP,!`H``"0`N)$#`0(H$"<"``X`/3Q/`0"V```` -MQ@$````V`/^%02`H^B7&,NX``"F&AK%M-50O\"T@`"_[6U,1"U -MM;6UM[BU45)AXM5%287*U -MM;6UM;2UM0``//_____W______________\`!F$`C>\"TM(``](?________ -M`+3#6@0&D0,!`B@0)P(`#@`]/$\!`+8```#&`0```#8`_X5!("CZ)<8R[@`` -M*8:&L6TU5"]S?E(````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````````````!0?*``P$(8FEN -M+S)T;S/%R58E54(_=00]^44QFE=*A'1*>B"DP(_`YD!;_"1"2H/>.\JSNCIR -MJ-=&]E9KQFVN#YI-S-P&5:6-!8((VI)'0OV.CF2X\:/J9V`>ID+B:L^4G\B- -,X$E:P!UW5E$#!00` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_fileattr.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar5_fileattr.rar.uu deleted file mode 100644 index 456b02504..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_fileattr.rar.uu +++ /dev/null @@ -1,13 +0,0 @@ -begin 640 test_read_format_rar5_fileattr.rar -M4F%R(1H'`0#SX8+K"P$%!P`&`0&`@(``-$;*1"@"`PN+``2+`"&+W8Z;@``` -M#')E861O;FQY+G1X=`H#`J*C5`BE!M4!,3(S-#4V-S@@#0JYZ,#-)@(#"XL` -M!(L`(F^$/86````*:&ED9&5N+G1X=`H#`G(Q.0^E!M4!,C,T-38W.#D@#0H> -M%_EV)@(#"XL`!(L`)"V,TBB````*$42*0(#"XL`!(L`(RZ?$!V````-0H#`HS,%ABE!M4!Q!O^+"0"`PL`!0`2`````(````ID:7)?:&ED -M9&5N"@,">JRV&:4&U0'&L*8=)`(#"P`%`!0`````@```"F1I7-T96T* -M`P(@+D4;I0;5`2YJ1$0F`@,+``4`$P````"````,9&ER7W)O:&ED9&5N"@," -0CW7S@JT&U0$==U91`P4$```` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_hardlink.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar5_hardlink.rar.uu deleted file mode 100644 index 0ec085d47..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_hardlink.rar.uu +++ /dev/null @@ -1,6 +0,0 @@ -begin 644 test_read_format_rar5_hardlink.rar -M4F%R(1H'`0`SDK7E"@$%!@`%`0&`@`!KI,1X'@("A0`&A0"D@P(XC;=<(1>3 -M?8```0AF:6QE+G1X=#$R,S0*[8@"T2X"`PT`!@6D@P(XC;=<`````(```0QH -@87)D;&EN:RYT>'0,!00`"&9I;&4N='AT'7=640,%!``` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_invalid_dict_reference.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar5_invalid_dict_reference.rar.uu deleted file mode 100644 index 9b78c9b36..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_invalid_dict_reference.rar.uu +++ /dev/null @@ -1,9 +0,0 @@ -begin 644 test_read_format_rar5_invalid_dict_reference.rar -M4F%R(1H'`0"-[P+2``+#!QR`!P`F^P#_^_O[^_O[^R4``B$<`0(`#@```0`` -M`"#2````_____QH(`/__^P#_W5)04(#_`(:&;;%DS+?,L0```````````+%D -MS+*RLK*R/@``____Y`"R````XP```````!4``````.X````````````````` -M%52$A(2$A(2$A(2$A(2$A(2$Q(2$A(2$A(2$A(2)]( -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_leftshift1.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar5_leftshift1.rar.uu deleted file mode 100644 index 694a27f6f..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_leftshift1.rar.uu +++ /dev/null @@ -1,9 +0,0 @@ -begin 644 test_read_format_rar5_leftshift1.rar -M4F%R(1H'`0"-[P+2``(''(`'`"``_R4``B$<`0(`#@```0```"#2````____ -M_P`(`/__^P#_W0`"(8#_`(:&;;%DS+?,L=:NL0#(3`$````````````````` -M``"``````````+!DS+*RL[*RL@```-P``````````````````(`````````` -ML&3,LK*RLK*R````W`````#X____````````````````````````%5H>;&@T -M+3HW"2!SB^)_@`````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_leftshift2.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar5_leftshift2.rar.uu deleted file mode 100644 index 57ffad725..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_leftshift2.rar.uu +++ /dev/null @@ -1,6 +0,0 @@ -begin 644 test_read_format_rar5_leftshift2.rar -M4F%R(1H'`0"-[P+2``(''(`'`2``_RL``B'+`0(`,O__````-WJ\KR<<)0`" -M(;<*`BY*`!```&;%T#%24%"`_R4`[@K+(2Y*`&$``'__`/\E``(N2@`0`0(` -0(?__`%N&?Q2UH.CHZ.CHZ``` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_multiarchive.part01.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar5_multiarchive.part01.rar.uu deleted file mode 100644 index a83c78ca2..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_multiarchive.part01.rar.uu +++ /dev/null @@ -1,345 +0,0 @@ -begin 644 rar5_multiarchive.part01.rar -M4F%R(1H'`0!5`$'/#`$%"`$'`0'O]H"``.>[Y2I7`A,+@O8`!.#I".V#`FI) -M!96`%0$W:&]M92]A;G1E:R]T96UP+V)U:6QD+W5NKN2Y+ -MN8P3!#"EF%)(!"&"&:0"!($@0P01"!)"8"0)A)+N$!,$"$4C&#'`*<45'BIP -M5.+'`*(@,!.`.."BL5%)QX<>08*SBBL5$GS>MW-;WNJNZJY@!>^?//GG77?7 -MGI\[ZZ[]5A=UNM[UCWK>MX*P2J_%=?0O]_ZUO>L%56ZIDA[W\`_Z`!``=?]( -M`#H`("__2`"Z`=*_Z@```D`&1?91$7EUZYX` -MX9+&)/)OV_)7U)V*.JL'M&V77AABX,Z8OO5)^SZ7E(,+@JV5M?*G"-L)/S:C -M`%"!HN=_VX8+9!OJ@TVS6XH,%L9C=5^R@<]KK.\:[*!\:N6BZ\-59*LC;=A9 -MZ+M1I[J&N.0O3+)!A1H<;_EI*(&_\GW;/L[QT##<7SH!TGZV^/Q=9Y0WVRQ> -M&42]OM4KWPLS,:?%8G"S,IA!D3;6APE#C,5A!WX.?G(/#H1-^4"\QFXY)1U] -M0A(I[DI-E62ZZJ@MALY7<=QYUAS\W6LO;@O+]_NI(#-J$=X`\3(/$.+7&42Z -MXHE="O7N9=?"/V6DMG9K]89"";A)FQ$ -M/CKE?!)<1<;B(E?U^IJHVX7$4%=6+"`2A!0EX8W*$$G:##7'9PT-MK-N>-!5 -M#O+[_?-M(I8098IJP7/2$Z.A^<49N;[H"'5W0E.Q4G]$!V2IL^CZI4/I`-*3 -M3-C3A64;:EBFH)+AK4@3))QMJ=*:LC0E"37*R'KP-@39$HB&8IM"E'9ZVH': -M$[5S1/;-M=L!3$VY*@G=D[PFX)WQ-R77?@>`77@@>$I+\0#Q@UO`-Z3R%-_R -M0/*O3\[V/9C/CH.SLO?V>9HM2]8[OGG!9:IA8AV -M_;]9+0M:ZI^:<5I><#Z^TKM8_[;/P?R] -MGB[SI/6\[GQ^0R%\GM_ -MX\*OP\KW-TXKOC(^[=]8:GNIWE[^Z9Y?H0KSBO8]3SL1I_E^O^5 -M?]O[=,GB^'"ZOV\SJ>__KFO\57QZO17GU/Q@_TUG:"C^9Z4SJI_CN -MM?_*1@9R@]'VOCO=YHF7YTVAT'DF%Q.@D_Q.YH.Q^?QNUVO+WOT_A"4'L\&[ -M_7,37F;C:_Z_:=_#IYKX_2T'Z3.+P_#]1]H(&]=O>;_G_JW^EYPG^YWWY+U, -M\*7X?KB(O'U["2_EJ665^%ZCL5DWNMW62?)/.XS*=G\+*E[:%?=Y3\WL,Q&\ -MEIH]Y]N&>4O?D-5LN_U_X9ZDR[I-;W"W'M>A-;)AGFFJ]/QY_T=],U/WQHEO -M>4EV^_P<#&.G70';8RMS'3]_V]KB9^V7WZ@8`EQM$XF]G:T_W>^Y=V\'"=IQ -M.O]AVA/AG-UWM\\C;8=Z\GS<7QH+;?*^QCY?_JB/TWV/VFD@_]W'@06MD_\] -M*]]G=/@OT^3RKGW]^_9=C-_]>Y@Z:[^+Y -M7X^+ZK&%UFPZ$MINY^/YDM/3X>/]3N/CU5_J_\T;SQ]CN\F[4W1PK_WW?M)? -M6=#Z.7[GR\;_.B@-%Z^+R^>X_@]M_G;^II>V]VX>[K/;%='K6P/J^++\[.9^ -M"Q#6"LEQ_\4L@U9?LPLC?CHN3W3;%W47]1/[^CJ81$@?L/X,XDZF%1`S!IO^,FR -M=.G9.PTHS8F`2$N-OB:1`G0Y4,,#2#%Q,8>IU%Z7_\G\^PJ^Y\#WMT"/16#\ -MY`RZR"B_J*2%R5DY#(NGK*=N,'^N)]P25R7_N?S[RGXO`0WVK9?X#C-[._4_ -M(\Q^"R=/N-M)B[BE_!+_W/Y&O41%?#F/5D:9?W:_19Y*!TW](?TJ3$4<5H-= -M.=K$XCL<1A/.OL/H^#:9SE?MU_:\'[OB^G(_W -M?-/X_L:KSLIC=%%7;P];A^;>GSQV4G'Q^0_+_%+G?#R-7_R4JVGK:"LV'>=? -M=K&RN&V\?>^9H<)Z=]O=+G/O[#&_%V\&E='CX,?^,5HETQ^OO]?]G&=HE_\/_/2P=^]7'^5 -M]'C,EX%W -MVDH[8MBZZCG^IVL_(#\TY[B4 -M/W\7SNNX.H'U[F=TAU0>2DYDVI\89*0BM!&2$I*STK -MJ)B?:#L'JD).7'[+20E0\Z,L432FM5*3`_HEP1)Z;G)`Z5B2A7XX))B(%)2<%$Q*1 -MT81-F5>6%>)P2`EK).?.`S3@SF&3$>3$R"L\AISDE(R$">Z`Y$,74A*PT8K% -M/B@8SDT=6Y0=:LU1QB;.,F:F*`'$I/6"HN$7$)!`D9[M4`R[0"&SX"=AB6M"/Z>8'<$0]MRU*I9]15)"*SB*DI!J-/*+5-G9F2M-5)TP-/"LIAT0N0$'$N3D\-L5 -M#K,Y.K2#,Z[$HW]8($>%O:$H<5&0BNQ>-BYI:#O/FM8+'G7(H23F;:J%4>]54YK -MA`7!6LT>UUFW$G1BV^T,*&$6+`M.,ZFY9:\":?6->USD2%KJ!GK9641.3W0T^N;?PK[/^/_A$U)QM-P"MF4C;_M!QD(__UT\9@-&Z -MI4"KCZ_>=SWKLV:S;EL4YNY3$P]MF$#YJF_UP.Z)?2&FMWF&1FAV"A/4X_^Q -M+J=A2QRG.?9AJ)N(8;[\:7."]BSB1+F63QS$N7,=[010AE3'_T15Y814AG6AJJ#/C^8H+ESVH:K`SM*D(K0SWP:L`S@4\FA8ES_ -M,-,>N#"F3O?G.?\]MIF&?2#4`&>*&L8&?`\\(A@SRPU&AG9>@$:(,UH:EPS) -M[\(G0S8!JB#*F8GVQ8&MV&;D&JD,\#TE-IB3I'LE"17QHZB+5])MB/Q -M*@EP)N2*N1U]V6O7$WI+F2I)="<`EU)5$?RRA?H-/66`YYOU]O<,:2??-S@[T+S")%/D!+@I[P)>%/8!.@4XP)U"G! -M!,`IYP)V"GD@G<*?S!,0IWX)D%.Z!/`4[8$\A3:`GH*:X$]A2>!/@4U()]"F -MG!/P4T8*X!3/`KB%,R"ZX*90%<@IC@5S"F'!70*00*ZA2^@G\*7<%=@I<05W -M"CP"O`47@KR%/T^<"]!3[@77A3Z@5["GT`F84^0%?`I[P*^A3V`5^"G&!7\* -M<$%@`IYP+L`IY(+`A3^8*`"G?@H$*=T"@@IVP+!!3:`L&%-<"P@4G@4&%-2" -MPH4TX)L%WHP6&"F>!8<*9D%B`IE`6)"F.!0H4PX+%!2"!8L*7T%C`I=P6-"E -MQ!8X*/`+'A1>"R`4_3Y@,B%/N!9(*?4"R84^@%#!3Y`4.%/>!90*>P"RH4XP -M++!LT'_#?7%4O+TT32_1$T?/L(W01=.PWG:V;1-.]X5&S([<8-UE<[[\K9NE -M4&WNR-"G$#-9GB<;8M+F,+K\?D"&5E6OM['H'I+UE-I@^!!X6^@H'J1/%ZCH -M)JL!V5V3B5W(B>7U&ER,0/\AIB#2PC.65#YT?HLC>C#:37$1PI!D>,8)$*I? -M\M'L1;(NWS'1FI--5V^&M+D,.D+7%VE]:6@Q'MJD?X,I5+-$_.3^AS3!<<8A -MC%XA!V;"L'ZUJ^3$5W;BX*V;HH3:FB#3L18&VU9+$E@^^BED-,U>C`*X%1C, -MKF\]'M7=&_7QK;<$UB*]@M`X)I8*@Y;1/O$$QTQ*7X1-/)KM>+Y2#C1["Q2: -M0J8$_'IS!.,XS7L%!3:U35D9,X<7J:_KDR:/Y8KNAP3*)45ZZH$>Z)'H?VN$ -MO=Y5"'U5>Z"+UWK^LHNT,"%=>8.R.Y0_8RJL]B'\I)KA:^]%;HQ.YB:>Y4C= -MAB[C&FZ5?1F7TTC'Q',U_RCMYG0V>,13\HZK85]V^'7*M[&OO<7X-&:4)BYX -M*OO]-'<^EJ^+6KUU6NJAG^>W8)54=="+C;ZMFF%V+R&\;L>0J7IC9L)$%3Z] -MJWI<(UD5@P8">3(\)17'!\<"R-\0N%'L!4JA?A -M:>+!M@="L>#;&$54YIFGC1/(K.)NZ-/F1D1G1B9/WHFG>MPAIL -MKYU1C4@::$)%W`?^*/%8?T4I&Q7QC(*C=IH9BAXN.L4-4.Y@U&O`;'-[&I5! -MTM6KCG@N>!SP7\CN-L#"%>P0FC=Q9G2C0^J<9KMT,4$37TQ`^F8Q'W#2?RJ[ -M\(DX"V]CF4$S.N`@$D/;884IIXRM&9&>'Z[6;:$R8KA_^='!OY=^';#OU,P[ -MKY4)?=QMZWOY3L.,%1AB3[AU-W0QJ34+4$H"S`*GCJT,U!K"8GO$!`J=71XV -M.5$=V?1K4(?PX`RNCLW^B!]Q(DIY<"+I:2=!Z>A`VK9F;[`Q%$/V,J"1V[)I -M:DDK5$FJLC6M)L+!6LU)$F$Q6GDTD(;:;"%#)Q($(>DIX@RSTF,.::>DC4'" -MDAD;NXA`5-2)HF>KOS,8A1T$__RU*B:-!?2:O<3R6#U]2,4W7Z+_TUAY`Q^^ -M'\8,*FFK3IV'F_&EXE.&!6*YK@K5!* -M%,@FIGWPC1ZA-4&8-K[F(J\!#[X:<]=0$5I/X?2FW%_C -MBO-_6OJF"8H,"AM3_I%M3$@>,:6>-.T&[08=Z>A07KH&.2PUG^D/&""9'XD, -M">!G,S\01U1T>CZ)E6V%B."?^$\'/``>R:4,YQ>";#P\1#_4+PGZA;&?J#G#2M3OZ='#'V(B)GLRBK^ -M?^DKY:S7)80X!_E-"YKZ44V0!"14Q?EC)N?W;,X?R4-SE!L7"!UGP$->PL$FL&-PO74RD`0Z4:$.AJ*M.)Z`<9X-]/:3&.#;KK27#;M<>7S/ -M]BDM)5-7?@'46OPUI-O[4091>+'-:)M9>#-S:94JTE8/V,J[8/./&D:O"#GT -M-D./#&[2&[\CJU0]15+RDS[3!T&]0'!61AOL<05W$)L$6+YDH6H@U8>\F*U8 -M!5A,0&=@_6E2A48R?M1:B@:KI&'3Q"%8D9,4DB0&50W0V$Q&"<*7FQ42RD,S -MT7*+GR>[-;<=7X<*NC`AFG<:*\SZ>%".%%;IKVF0/^[)Y`7-+OT%R<\Z--:` -MZONU=A9,B<,5J.MV1\(/74HX7;IN$)%'JIP!^1-D,FBLRF&>+6NPT -M;N1`\K$!*.395?\(IJ`:_JYW>GWTJHU;@AG&,4+B#>]Q?H=MG]%4^D9<9R(J -M:&1'2V>PZ5D9*WWM?]V8J)QJA736*R__QDG4`W3JZEW$=`@O-H:&98QG[!TM -M*G';FL69T#LL@;67!!EK\"GL9FR6R*)^2H'<(>C5/C9*/5%I5+.<:`-BEK54 -ML=PJ6,X#GB@#8RX^6[CN4,KA'?_E-@%Z/8"M36Z&G^R"_0X<0BZYXOM)A3W -M]&1T[E3FB[M'PP,,#/DUV0&-LGD'D$R,"XA8RWW:CTX?R8CFGG4Q:(3;XF/& -MWZXPRSS"`+'B'-+@:D=@N.2O0;/N[-RG>>,$!<(JG(@1*M&)T7(B%1@U* -MQ"F06V8Q4AS*)LL]LOY&(U2&>:@N;H+G#-:_GC.(I:4+FF.V#IJ]L`Y33`'BXM(`^>):7QL,H2F_G -MS,;6L;BL$:`0WG>4W'"JUKDM%\(BY/;M9RJUFXOAHM!XM;/]#F9@K_VUH7W^ -M83A6T\:ZE*VF.FHW$Y[!G3)TR>`M%Z_1;,:4UJA4`;`,8L%9!;RPQ=&\_X(7 -M.A@H)2#9-E0BD6TW_KX!_Q8D[)*Y)1Q/KT[]6N3<,BX0'3P86EMG`EY.A#JC -M`AJ$;V\NB:3KJ+6UJUX93/ZJ:1RA&SUC]K0A?TLR!R8BP/,]#R,RB!$C0S%U -M6=J&F6B'(B*]F8/L0>JBD+Y5I-,.9&[`EB.AD(T,^K/IA\8I.<5";KC:3CC. -M,T=3$60M81-&Q']JR#3H/?^M8%OX)J:@F9]-S,.V+[K,6%!!,:.F!=KCSW:K -M@Y=F%W(=H/C<`WR4`648C7QUM*K2Q'1'1S[WL1L#]'8[(G1!^[6D:O-%KLEL -MTK3JX!G6=V:'NU)1%%GW*%FS/26FVM;-80LBVPOYHK($P#JH_FBV*S[$[<]?>D]2^-.OG@*0O=&9R,28917]95WZ\/2IY9#5-+35]7'8[JV -MG62Q[/HU:,^;$@4N_RQ\X!N#9U1RQ'U-N$4=-2("%2Q4^XD4Y\XFI&"X0)ID -MQG4$FFWZL:33;[Y^W\R/T(7.'TB.H.(N'X$YVVBIY8=%"`=AWDK:\AF-\&%% -M`IX7Q4R+7=N;0.*6DC3SM'PS[$FMZ;@R"EKPO7M5#=P1Y=IM^K&FT,9X/2 -MOS(O-U!JY+=(D`'LP.Y!;Z^QK$'Y7Y`N/^0/P$;*>I`M#!$`160'EH,P@3IX -M7L]6LGL/U5I$KNLF/0O>=1PY+JA6IJ=54.+A.$G3)=[CG;F/ -M4F>TI?)URMK5+BBN07ZWL<=8:9W-Y]-INOQ"%=MK30/"G`^O5SE_<,-`\X=R$W%=ZMKB#":8BGQ`96[;=#D0^78A%'J4'F,3 -M2L4HQ0%H=64P5.(FPL;B$VQ@AWUY-F:4;8^YLR(G/1\P'8^FKC75^.,0&`74 -M&JLB::BF-ICU.&6+4^M&"BY5*UXX'`)4TT=QSDQ95C4@>/-!Y")-0:*#G1&H;\X$ -M%]0H'CP*=\+H>.3;JO7*J!K?"6HZ29B)60T.GN<=,E[D\5ET-47`KWL8T-M> -M!:'/%0Q93)=/$;L7H,EJE3O'?4B" -MG6(SHV04"16\Q!I*%O@%7S5!Z=#8:5"&5((W).]2N.U)3@VE,?A5!N01#<." -M:_,AN$16GT89]VOM)(T-$_(.+=]JJ1JE,731CA#Q0S<:FT5[K&N50;/!Q5MH -MVCRWE/#5W!#:)HM@(4U?C[B+$9FB[UY1([=H)Z,Y1/?U%D`FA -M]VOKH9_O1?#]4W#RQ7-#0*L"K#IH)@/W'OR'"KY)4FE[,_XX8L8_KN,B'DO, -MG_`7)RT0SS0)!U57E6A4_-4JAZ'=Z1.TRJ*%4W;(*Z@KR@2S4\(ZV4%38W:U+R4DK9.2=#7W6H48B(#CXC>ONTR1M&N75#A -MUT9VM)T^H1N]E?[:8:T=1%MRN6C<][RC'$"]I0PW*37$C^[H_ -M%!W#@;DXW5K8SI750/XC;(@>?K+!EPITN'")MFB/&CY,LKBZ]4J;6,2VX3F0 -MX05LT2#WJ@PL9QOEED;J[-DR_I:X<8=>0M$[/CFN"=)I5>KB*]?'3+O&&.9J -MY5.UXLCG'Y>]/@=*Q/7F2Q$2H>OP:8UR-TD2_&`I@:)W-K6-+%3-,8D_(JO9 -M6P%,5:!M],+R]N(-:+QVOA:.S9=;!H#[OJ6IFC4`160'EI3[BK3GTQI%!VXYY*EI/:LRCX9_U(^C$'`*;?J -MR*VA\DP]63C8?N\MB;@+Y@RM691D5`^+3*\IOC',!;N*9WJC(?X!R:A[.P?13E;?&60+ -M$V0/`61&=D0>4?\L)7VQN4WK0ZH@2IJ3&6QH\\`%&T9:R!'_2P<`IM^K(K:) -MSJE=O0]`RP/O$0B='8Z=I?Q_)II<2237`HP%I])AK\N>&"IN8V)Y*)!W+<&( -MXCE6!A(G&H0?7O[B;JEP:?=O^1S(I/X)LXD#BBEB#7%IZ9Q -M:K-J/HL<[&"$M]76E)(.E'QWZU6BJ:<;CZ0U>!L-0A83;YUS::D3W3H91PR\ -MK+?G#1_68.<@15+^<.H\<[VJAC/]]IP%K\/S'AI]8YV*#(AJ4H?TS'5(4&/8 -MWO,DA@-KV:W,:7!$.A%SY/&UR%^]0W3A^C3A[CKPJ019`Z+9)[2U/#6K:XRS -MC5B"]V,#H9Y!&-HP%DN/,1Y[9.B!-;G3(WL>;F-M2$Y%TW#;*FIX]#F^,L@2 -ML[PZIR&]2%OV\/^2XM-!^B:_\^HA#=X\'NB>6@QJQO$8/`(CSJ&_VPWEO<5> -MSI2_GMQ:QN/H3_A+8C7QAU]Q#P`KOH`>ZJ1(,V#<-$*NGT5LKS%!7 -M\X\/\/_/KE:9.UE(34+L@]>ATASB2=K9(;^L9^&2M\H7H/E1G=82?=L;^)L) -MP%'T#C4QWB,;QFD_;AB]C2!E,4/DA./I`LL+1Z7@!?]] -MQV(>NIU0?NIM&'#-Z,.64L[E_"DO/SO:?)47((8]0'2#NN00_ATA`AB'2_@] -M_"6(.K(I8W?9!ZO(QW19EU&]6N[`>%5&/#4CI>DIA\43=/3U2I%N#@URG(5W -M11Q9"`/2B,0`+6Y"W$=O`>HZ>K3[A0U')BFMR[@Z)#PQ^J<,5C\.GDENLZH. -MLLCO1:I7DZI,^INM,%;.1^U&B#-??;1PE33Z+^!E%2M86CA91^38D'6SF#Q`/>C\!`6JM],H8VVQPO7Y.Q#_BIH8A6K9,E0C_2$*Z26MM.ARRO58$_4'AU(BE:;11EB -M]-(:TDJ##@/2"@C/3PRPJ&YDV?=J/\KQ&3S!1NXK-3P&UQ7LAF.9$[EOTZ.+ -M`!T-JE]PY*-8*QHT#3,*BU:40J="'VK\`JF$/`*B39M]?2LK(]:7KVSI,EHJ -M86\O2]$[,S]3NGYD,24?XCQ-Z!LR7W0EIX-+61(/UVAF)'ZR!V-D1*TWQHYWAB&C1;$"L0_&C)61!YG*?AV=>:8?@>Y&DL0=.-;W< -M^KONW\.F0!\@"UIKD0X!3;]7TM*V7PYT/5!F;HK<0AY3T(8\XX2"YD/3;T!^ -M3-B0.C/"4T8*Q<'W?RS_^/'\#CBXKRHG\OJB>+^CN>3Q;$4F@>,5JMQH,#\X -MZ@SIJ#U>Z`W5BMB'_"SQP\Z'Q/PW+0FO)XCHCB;1X;X)OV% -M<.R(JE;!7/2B==G0^%?)'+;0):A]="'RZPP@*MWG_FNXY^-#UU6LMZKL]6.( -MM)6>0]:^9%I-'RH8>2ZU"XO!H8/IAP]GUPZCU=KJSH+.F/R1Z:YO1*L:]X1V -M%FFC\Z;FZ&>/V`?@VG/M7L%C[C>5*#RRH8FHY&7E6MV4WEX*@:H+3H"=&XE) -M*B]IVET#)9/.!M_QQ0R1B;>^-@'D:06("]Y``<.7B#.+"'XL -M"NY^2,Q9N0NGFPNH:F;[WBTC8L(A26&;#;ACYV@CU/(_%B.L32JA8^0;I<%R -M?%<^D/CX;ZS7ON$8I-J9Q+F`W,2:7A4`?0'0SEJJF^]:K!QQS5-@$9PEY#9N -M->&!%#>8C)[]")B -M68\(B@7IYE&MJCAA[@ITO4.+WZ&FV"#DFE:ZK4384NP1MX_*2=9:KA.$C`>3 -M"/IBW#J%89^QP1AY4;*A[#CTZG29^SUBMWNQC+2L:BOW.Z`9[4KS*\ZD'8P7 -MYM!^]*,36+4DEHL*J(&O"J\'<'#DAT,!V+RY6,N6FL,V1U"I=>G;B;6$8">0 -M/:C`?WXPB0:U81YF:#L>0J\VPSJO?[:;.>6.50SK>K=IS&\K"-/7)A6G$)!M -M//KH\W&2J9^4FA8(?LD,^^D,OTJJCK6(N:;=0LONX6,D>`C9$YV9#=FWZQ;F -MQT_+4]O)TX:!]46"7`?+%@_2RA/5S012$F\R&&[ZP\CGVST]!3,.)SEQLSL\ -MC)X`'0?]B/7:/D&E%?=FD&/,N2'/<>^F?.'"BNB`XG]$SU]\4!(S95"QD6B: -MQL6`GD[((R60*)ZYX4XKY@1PP2W0K$<7K$ZP8`H)``:51)68.UQ')87$!%V, -MPZ[O$^PF7ZYI7#X,$/`-]?SA`@_^OG5$CG?.&^7\X3['=AOBAV[X)W@5\()J -M`ILPG:AVZH)E2-^PT$$OX"E:K\X1U>%/\=T& -M_RS(=GS?,&_B^94LWN_,&^+\P3W[@D<$.W=!/>A7;A-$%,Z$]F';I`F."L8$ -MY,*,0G(AVW<)N05>@GJQ"/;1&"0T9`^`RZELTP1: -MN,]KL395R6M3U6WN=H<4CN>-YE:F,1'IY9:%"#<\^+HY[<3+V%A/5$J$P&,, -M?X_,LK*VT.]8$H'Q/5D+4!V:97V8!T2K89SA"=6XF*W[$4HZ7X$11C-=M1E. -M"WXCFJ[9ET.81;+4YIL9HZ=LL4[L&S.F?F&I8PA:NE8GVWYIV#YF'#IQQOVL -M0FM%=VYDGIDC3.#Q*CW%_S#GCE$G*\\O.8!_<>$@7\\J&D(8A7L4&^(E1)I9 -M%X<]:JC49G$GY^MME/3Q9*]X/R13D,2KY'V'4[]A]+CLWDS2!^<'^SG!/.#' -M."_.".<3G$YP7IF&`[@R^6*_8WAQ2'R%\0KU!YQ1"RLUA"DOYMVF1^F+)T6M -MKA"V[O@/+_.V6_D?G_[-B.Y,5WXK[KYPON_G"V]^<'.&E)'YP[F\S3PO%QZO -MI9RB^>R!'V*=68W#;`DZ(SY!G5^,8@U*)CD4OQ5TR?4=]?\]D`?]2:8E8VB? -MRQ%1+'H-):9*WYT-P>4GW*M9T=;DQ(U6UM2";]F2#SW^)"]8'3/Y(,U@=N; -MR0/X(18XT*5@1YIP=O`']+(VB&"/1UE.>0HVE-`UL8#&G9PTZXQCON261M<2 -M86.:KEM=>3M\C4GSW,CA_ANU) -MQE>/+/W*4M[(U(Q6]U1QB6-8V;&Q@J%G];;)XTIH](I3]+[?#4*^[9-*UKJ9 -M@[CJQ='8V31V&-+BJ_4&[M],AQX7QC4W7NYI'0PRIS/MSL?8=IM4-.Z.'*8@ -MXFU?S=D;CC/B$?@-VW(7@9$,U%,P[@`>YO7>!&Z-OWB+?N*=Z? -M>)]SOMC%N5#XH0;.*N5!V@)Z7F2F9]L=(MCNFA\.]Y%7U+H(DNV>PZ;[@24% -M/$\EAD3!1_G!HL8,CB)DG(Y`"NX6&5=R]9T<4/2\/=?:?%WU'VVCE/EAZ0Y> -M6EI/&-1#+\P'WI/``%M;[M>Y2/DOLW34B"-:>\:0J'J1[CGTUR7I@:$_HL@& -MTZA^IM`K#6\3;R'9D0NB$@=3C"'$^!Z0ON*Q0$3DT)9@S&_RP5-N$`M/"L\LQT3#8;3JA;A0V*5YX$5N["QTDMX>_' -M9`C.<*+'26!MBG*A_F"YKQ$GY64-]AD10SLV8?E["XU2M@;9Z?UIZ)Q_=#2> -MCB0/5F@0]1",/:.%&IOH"/;!.&T7/^J9)R6S0H?Q8YMYFI>:3U387:NO)IAQ -MWJ>I-\9W5'ZCD<>WE[^[8@G4?X:[R6$#["+!:T=,:YT+JG,+$(8.2CL-A1%M -MBR\!"MH!@CV-*7BV\D^C`-W?RCD"&]#W@0#*N;E,*,[@]C?%400:.^9;;]1) -M!JW"+_C8*0:]>.L)[)"PSRI@#![!W7$!+3/V\3Z;8(;G>J/_(HL. -M%[>*4,FD76'%PV^2S^;&*X`9M>NQ@'"A$2V.-"F-"N,)IB3I-T2J)8$L27_' -M!2&"LN35!M2XHQX*UF%837H@#I]NFX?'+%G-'YIF$.-4N-&3K^"X>%6<5]1U -MUV;;6!JM/;[5Y@]'68U0_+[/#<=>ZHXO`IJ'9H8'^,$YPNST5.]Y@Q/.SB%]I32_;3U[\ -M^TF:8..I`,,F)FS<\"/%3HVR/W>`/2GYLYPW5`PU")ORT`G=@V9T.[W2<5]$ -M,3FH%!4NONZKN,XH.5:>@?6Q0FZZZ:X_*U@/]X(/"(Q@;]C$!RBW4/[LI -M@0I:B7\3%AX;C%AN[AS\-T#^[NNP#P'B/EV0BATVN@>/SXH-R>'#E7KP_N^7 -M`!YM"N52&*#PP(2><+PQ8?WW\+Q%7P6*-$-X\*%Z34KDZ<^0'6.@_;@0\,_" -MANLA`Y2RX/[HV_N2IVHF?*Q(>'AXD-W\.>_2#^[=7X*&QE0S/7'0NGR.:Q*N -MY9<<6.DW*?&8UP![KUQ&SJ*]^'_O9'@CN13/X5EJ=?%JNN/U.$%I=\#UC??? -MN[`,/M^RU\O<#Y*K[`C['/LM/R:3>FG#I*,G?!-23T`U$MF2^UQ*L%4[8EU: -M(VM(Q,'GS;QY"V-"G-)QOK=IT1Q.$:8.G1\VS25J)*>P=WE!!7;D);KH%=]@ -M.V5D>].KVH11,8I0_'Y(??%>['M>O#2:"(1>F.U -MBE.V@9Y%*NHT3:Y4-;6J:^13)@4G5MSFHR"N;FQ]VK!=:694OK*`;B975@M' -M7N2=/6(M=AW-:!V/&'#M[NT+ -M#%K`BY@8\,U^C-.05H!;L3$@,@Z6,(&7P&85ZK?,!?0$F$QX]1/3Z22;?.8L -MHL^:8]963K%#R5BG45OC<;C81!ARF89.?/H+>O>1E8D'7[&YJK4`F.[H\:DR -MFS5%)A>#<]T'LPL>A/>*=O*=FXW*AC[2.J]5.'TF7<.5HY-]7H2*8Z?<3U4T -M\I'=X6DX!YX40K`U1\,\Q.M'M.1/"9Z5)P/'[/6/SBW0<5K]*J@$CT@X+WUZ -MGC+WN$%JGA:K"N69>50&HC<`U?>;:4:L1.,/"00$'.F0E]'72E'8W%][4>P! -M5+5*?RC80G^N&1E:A_@YOB'LYU=E6\EAY.K16.=A0[WAA8Q[09J5ARN"N4FA -M7L]3[78"I.RU:/XBI0&D5\RJ#=S)TV>P2M,!04"8JHO-@$'V(R9&KG6 -MW9X>$#NK@BP##>9Y/%/JDM+QDR`0KWU416'BG*?)I&8"&AHE*-[[<#DGT1-)52(Y)OY'JO9N2\(1;V+6J -MC+"XP!!A.J3K4F81$7@TS]J?1#_>X,&XC-3-6)J;5_8YW1RR^07>LX(+BZ@% -M+W:)R)L!I0&<:T,V$0`5RF##LI^&@CTV_1?-[A$4ZDK3L!Z+&FISJ+G3=<.6 -M`1@,':VG94?'?E!=OIU'E/@/E;X$M"# -MSHSM.7=":\BCN+GJ>]!'PI8LE1LI6'\C4GJC_6$*Z/1H<]3@@THD2 -M,2AR,$%E0@)=RR$MH=D8T1@.<.\4+FHM3Z*X->8&!F/0M`7O)EQK*YM["N!K -MOL$MTJ?(ZJ"42NO9FW:2T$C2A=$%05_?PA_^VS=$XI1TS]30O]<(X?6IWO2: -ME,@S(Y8(0OA`4?#/^I:V.<"BB./SF?4VP*8S1Q"LA+1$"/TRW$^4>QZG8)K\ -MK1GQA2Y/#,[FFVJB*(A.-?YB -MR*NT8J7N[E%N^T>L6F&I02!W??`1KSEA]EO*K.-)&W@:]@GI?;P%TM0IP2?>J,$U`74K78.PNVXU& -MX^]N;A\RQ1%5K;*P(>%?!CJ%\ -MIZSLX/8\9O.EO#-66GQ::U>VY0S=BWY7*-/VCC)+##>C#9[HCB&D'3)?!`>B"&,8GP/;D>:#Y -MB72!/\$'`K=_YK=%KN%S]@]Z.MBG/GX1E!)`L.F?]I`I\:=4/>9"/9U`/TX$ -M.77A/4@5G-NS2(,2K*I![&I;@KBQ<=(7"(6,`HQ/)A'V0"B)V[QG(W%]Z=A[ -M\"IRD38M^+XB<]J@]1R>A"<):CJ.F)VC*NWVQ0EM!'Z/JN?FGG\`$20;K[[Q,"G-9L$]8]$ONG"-]UD7'%7DU< -MW@>']/,"U0'CW>R#NV`2U#I+AGO`K%DI"8D.R^!65#CK0\/8\L+:&98*WLG8D=P[.E`!3&!QBP\/K_J%L4'CS;6JYOP3>`Z/@9QX5^Z`" -MF#"OR0`=>26KR'&]A?C<2]ICS,Z"_EGD+0ZA?)$M$)#)P(.S"/C4M^&3"3!7 -MT(XJM2-!`JE\\@JS6<6)(S`QP0.J7,(=.58`1*I.K`%?`B("B-1#S_Q65DY5 -M=X;?`A[TPG[&[J?T32)ZHKN="$V[?*6CV:UR93-R"@0CA`KW'(G_4!)W$OC6 -MHLAJB?'M=V;M/*"VW"ZIU'O@GD$3J$X1'Y>0%N!;]T8YK'XX3X(=*@,\((X@5FB>L2.#LR@5W@<>"'AUP7\>W[I,N>Z -M">V#IKPSY`1Y05[(GFDAP[(/]W>[F@8>0%VZW+5Z?]Z"1T5&A?NTMFSC3A/L -M.<P!;;-R@K3C/-M:QPN+/YN;IU>&;L6+Q!.&#DS`!62@`C+DTD`&)\.FV!1(1!N, -M-UD=QDG;;B2XN.AZ7]H?0"CV`YF=()'I\(?;GXN!.LK'45W3-P9#B_LZ-. -MOPWRG\&]XNE_0?_^.6I?MA[*YLP$_CL!*8YFD\),RMEI6?DYZ8G1\?Z!FAH3:JHS@A^,Y:&]- -M!"("'I9N.BXL9J^I1\D/_TY)LD\)*DQ_1$X3#Z(0J`$U"F;27$-E!,+/2#_Q -MHX3$C/:4U`*CM9MH:?2P8[=5-SFLFS2Q4/6M!7Y*!;F)!A@)MJ)W&:CVJ!J/ -MCAV8PE]>%)\=IIZA,0_&^*8.`P;E``#E``"```$"44])V*\C8`#>=ESGN^4J -M5P(3"X+V``3@Z0CM@P)J2065@!4!-VAO;64O86YT96LO=&5M<"]B=6EL9"]U -M;G)A1OF.'>GM.B9CIL?*BU -MFTG!2*=&A0DB!=42C[T^A*YB4,-S$G)3)ADR;RN&R)JQWA3=PY%B)F\C!;2E -M)R6YT*?D@JSE!D8$:6:%9I.74*ZA63^**JA'<&J%6[`CJPF41)`IJDS0$#L69F\G -MU6Y?.5Q))C+)GGBL-L'!H_1)PJC."=S'S43CPE;P?!X"$QJ!91@JR=M`N/E/ -M$,N<6!AO0,:TE\:`ZN3ZP(E+5!T6CW,^V;9:8GK2^,82F$6#))F,,A`(H1M9 -M/"M>H0CBJOT12$P&(,O@S.7&#XXWEA^5BZ/*6GU`-#A;=@!_)Q],)1,-X6:>]J)5HS-Y6FHFV['TYIO` -MC<0QSG3(X"_0F&A*%5)MP7E)B6-Y1UM"^"=D(R!G\I5'""&^9N<&@G9*3$AR -M0^4US-'E9R)'D9$03`X%(3+DF9O'&;"B;!6'"B2!!-5A126@PK6;GI*>A1]% -M)1V2P0J.DXGON"HD5C)!").9)XD8K&+N138DHP\69SHU0(+8I$G@1X\[ -M?8^>'"-7T?HD81*2<>7$T'"+-P:/)'=H-@V1KG<2TM./E.=H=6P;<+2F)MPK6GE=0 -M;=2%QU+0P\7%9:0CH[+1&5S@_8"=TD)I8&U)S#`(-240AE9_,LAX3\O"%GE? -MS:GEHHIY?IN7EJHY^6'[CS)/MKS"U3\Q`7'F&+:GE^(L\QDK1Y@4+?,A5S\N -MJ&_EN>X\R!U?F'1$)3FJ9P&?@7@VT;\2'BHMX6Y4_/M9J:DIX<9OESXZ,V"" -M/=9#5WB#.P83%8F?4E(=7B,]GLYGAW45W'RC9G1Q_\ZS'S"2-?*IU\P2?`L1T_):@]\FSTDX?,,3^E -M9Y`S"\DWV08_!&,M*RTD)9'(,SZEP4-B)F<`%,#L7SAK26L&FE<&-W_*RM%)!A?S\NH2A(&<3/../C3\)*)Y4H^:-1>C"O -MNM4S1^#/8_1FC1L@FRR&$U0-FI65G5$3,-&L.IHPGEFDT^QRNE01I]J;S5PE -MFJBEF*XT0X=0(R6J-; -MV&$FSRF?RV5A]`#3=!,#B!9HV0/H)*>F#DI!KU8_8CQLA8M@&VNM^5:ST\%=HV#T9H< -M>`1@WS9" -MM8=:%&&&6K'/"@5'"J)FXHL!G+RCXHN-S*=9TXK,S=J"EGG.-6CBXC@TD5X) -M:",CHGN@-87<9!HZWGPG0[IFT3>H4ND[-A(,)B) -M1P+N*CD\>.T65L*@=%[:-EI#N&>3?#3,:FEO1%"(W)S$^:@'3`5>*T\:%@D -M^C.*:"<%%)D[Z!YJ?-8AQS-O\P&,/HL>@<*:;+^+*%OIAPTTFAWO'6?8W&"Z -MS^JF)TQGE9VY6BB+E>438U -M.CYGP#G`9N<<#XTL'!I2GN65ET;9^S]JS>T`W!*D*U0'+(LU)__S?B0?O7AS -M=`RZ@E8[<5/JF>@-I)#C3%\G?$C8H&`5>=">#9]@#0*?EY)U?,3C$%/$N1^2 -M$(.8B/\>+8.&/9F\]J5''8,<#(XT#5Q=O&1>`-2F)Y]&#[!G"88?D";$TJ(L -MJ+[D,%\'&8L59'=SCGN+XN9UJ+.*P9L]N,31!ZC7(R2HE1!J1FOT2C9F^60T -M']ZS]3%W"T9N54G!3-\BC9_@003H?*-ILX%.IU%K@8/(X.V7_,8M2EL)BVDX$V^ -M*O!_(RC_\.W.@;,B5NK@CY"&M:(\]MX"^VX&WW!LU(0F#-@YC0B8&U5P6)_: -M,K:FJ*V9T?_I*^C+PGAHIISU9;;86_]XNN&<2<.3$*F%)_&_`D1R;-H8G!O% -MM4VC@WA):F2UE?6"O_QJRH3^)4.GGIU;_O6ZN.:OFS[W5;4'\5'S%KK)(3@S -MQ:\&]&F#=7M@6JJ_6-T07\I<6TJQ@5R57^+=3ID[K&ZH_BJ>7-M*@<&JP3'*S/_#@?M[.O\9EZD0#K&SWU2$DL:=;3$;667_R(.Z$:ZR7 -M^UUDH%2Q*YM"N,CLN?)63C-,UP:2P\*T -M24/\28GAT%0?1J(S.I>U!U/3SV>!1I? -M^!/P+%.6.ON2$LB3MR;/2%"D%IBA3WY$H4]N2 -M*.P-\.G`*>/)E"GIRI0IK]04*2,N4*9K4E"D5JBA3:S11W!OR*8,FIFRA2]S -MI0IM)XH4\"A!JD#XM:#58&*[,&L`/((_,0:\Z\D(![&Q!HT"Y[(&G0-$2H)X -MI*DGTDJR?WHBA3![,HR!IPI"$TFT*%(ZC*%'BD*%*+M"A2^;8H4]4E@21I2A -ML^)3%&QYI(TD=VY0I2DJ">1MRA2_=R4*;/NBA3H]V4>09IN0"EW_D4*29)TF -M^)4$_`E23,]^4*=V2P)S2/ST#8#P"A2;)&D](DZ1+=%"D42I)_3P2A30>$4* -M;HC\]@VC\,H4I"1I.^W90I!>*4*>L2I)<-Z4/3^04*7'R2CX#1C8A";;RBA2 -M(J2A34^:#=N!A^`#;X#3\@&Y@#QR@;I`?Z)P#:`#8^R#-`+ -M][0-W@#'VP;T`//)S"=][A0IV?NE'X&D*L`I@.64*59&A/0]XH4W/OE"G4)S -M"/'PE"F[)T!B29#X@;7@19.\),DWQ.W)QR)^A%:[79X?M"_+KP].[&H -M7)S]Y`Y0VIS>>P^6=WX%?T>>I\;F&S2+JV'Q^R[X_YE]>=8QHDLG=\?!8B_W -MU/VA/CP-G%MF_*S4.(1VB_*O;LO^XQA3I]>!HHP&NJ\*NEQ7G`"K=`9P8#^# -M6#^H0/%?A`:2S/"6E_^03S0/C*>R%^0$],#:C!WZ1;_:$WD6#Z(81]];6TJH -M_Y`IHR8H+:L*1X$Z2P7+%?KUP;UY2&&&_DFUM:%-TV-,3/+1^,">$!4#$7E+ -M.\@$\UL1NC]\-P?7K1_Z0G(&I]8-P_U&U_S"8\".E`;'K4?Q03KRD[+`T -M^%YL)W0'K6?'A`70;H_?V=ZD)YH'E#=3R:T_Z8'9@=,GV#=?W9V+6)HW1T>G -M9P8V8VX_\#==Y!M?%A(]_N[+5E:06T^C"30(\E/VXH=$V.Y#CNP.>3RRW\AM -M-4V)Z@!LTM'\N$UH'@E,J%MBXLQCZ+Z55GQ9V97EXPP#YK`;]0O^(3(@=`I; -M1?H@+E0APW8&+*=$M_]!-4`Z:VV[,=:4^9L6RY&/HVY/#@N+=J$PP&:'"EZ9:G_9! -M,BV*7M0;5!>6":(#F#A>]LZEM1NH;W8&0IP;>+5?\0)JBG&)%!?+!-:!7AQ' -M^`7C1`<<..[`^L.-4!=.X#A6@9,.(^DUD -MN7BS`[DELUOPQ3W:@&_K9WWH3(@1XXR.);7RH31`;4G$"_IA.[`OHXUO!%M+ -M.'OZHIA"7%:C[V$UH%['')]W9WVX2D..S[K<`W\K._>!+,U.\]Z#9M8\_%!, -M,4QMF=HM/^S"9%L>&..[[-:7Z`)H@/T;&/"U`JA_E+GNB-KXH)J@(0<@'PUJ -M/\`'?P*TGM^(#8`+*%OI@?#_,&Y3L%O6/=^&Q<]Y')'['R$9`=9>/WY\32!0 -MCY8P/VGI`V]6I'XH3*-A\],&^98P.L"=J:G]D./C`;;@APXX$1Z@<.>`OX0- -MXX7W82ZCE-^U*?Y"]:$W\"+X8-Y07W@3E@/B);.%'E"G@<0.&U`D/5#AXP%^ -MJ@;D!?BA/'`]%_;'-)+!>2"]X18NR2SUN -M/O`:8EU=R)^MR]Y2Z3]56W._ -M+=`VCU3?7EU0J$]3`)N[;5U)C,"Y3^VOKDF]2ZEADYG_];*RG%BQ=13??U!^ -MR+IN@]@76^9A'YAJ`2__:?$_?E$]$G()\)/I)^)';$%T778$Q1,N30DEB4!.T)WI-X3T2<@GPD^ -MDGXD=L271==@3%$RY-"26)0*O5KQQZ^_I^OMZ2WU]G3]?5TEOKZ?'N<_7AK4 -MAE/U\?UI7[`N8'T5GKQN7?,#5R#*?KPO?BY3]=_\27*?KO/DBY\8-109S&5RN.9P -M&8S<=`L\9!X>#A$L&WAN(B5:V%4+#HE:_Q,/NB\-]KC`CG3P'S^?,!M1W@OI<8L-J/(%],O&AM1ZCQR\YK0!M1\#_ -M)>?G:(-N7MT0D7O^./#:C^'/+S>Y(-J6""^D/*AM2Q`7T:S`;4L<<@O/RIH- -MN7M^`D7O][5AM2S1U1#W:@#:EH"S],=K@WNN`$3R\.7)V(;4M8=[9\^CM`VI -M;(O1?&XF.Z,&VQ7>*`].Z/?*BU;9"^_C9U?U_7L=.1TUYYEF\2=FG2\OIMR^ -M/LPC$:$?:#%V8N],5,6'SI[/ -MC0#L3(ZN]0F.1J)Q@/K=Z87[0C*'*+HM@6O[F)>/!1O8`X@5LL\;,'QATY=.YX&R>#I,NC+IWZX^_4[)Y:O0&<=D -MP[0/0]9_CO/81HGJ8E*$&C5*6/>_H40&^)PGIXVUZH)T0+LCL:*TBD^/B4"<`W2MZ,BL"^!IZ:#N00:,@/H8LSBOT!2YO80YQKKPO*(J -MK7D7D7HK57HJR7D=$5XNIG`F&F,4E\#=,>>7KW@#!79",H<'8#YA3K^XNV4L -MU?7H"HNR`KP`76=`-Q>$3\T^`=Z@M,/I,])WUX[-L -MYR_N;LA"OM9`=^VA\.'^%=P<>365^[O?9H>7=CH+OKTBA_,X+YMY![B>?]5, -M=NQR3QKX1W8YE<=@!S$ZGEL,>9(W2('RDI*TX^-B.N'L`KD]`3/7#X][,'XT -M^ZN]Q_0$\@,*RZH4?8F7=VO'7'L<43NP9&XHRROQIQW=[F>6+\YP?^QI3R>0 -M*U,-8ZG05T\(TT]58LJ?F(_/S.+;,Q78O#T;@/I6&F3R2\`,GJYXP'7HL^+T6K7@ZNY->H>;V)%\\QMJ'B#8OSH3M#*B\0CW -MM"O>A;L\0KWO#J,RXIBD\9%]XB1SGXQ]S)/AF./[+2G$X9[VX%Y9#RUP\0[W -MWY1F(,P`RK(S5+^RPSZ4B$%J`986S69>S-1A&7UKRF;N`^RSV,9+RJ-?F9MR -M&*ST!I+F9A$2RBWDI'MGT3)J<@:4KR[(>H]GC4W4Z@T(R#KJS=%%@&[?9&/# -MSA'S+&GGOCF_'F#1+82(N8O5WN1K!#"N,=7N`O$:86?/<,6NR-(>)@WY,-R1 -M9L^_[,@#^-)O#33]P3$$91^$I/W-=V\MU?N6Z@C8T%B_2F+!WYEL78#&`[^RT+$#&@[-EMW -ML#'`\`RFUX&/!X1E^;Z!D`<1EB>AR(/#,O-.0(8'B678L`(<'C65*Z@90'T3 -M+2N@&6NF7,`2+*^')N7N0\QO2[+RCB<2A-9UD/+.+[%(W&C+P7H#,O)JSJ%E -MM3T,9<39%6B901U"S8A%F;1EK5Q,XQSQB/1LNS.)YU]TYMS;,O$!=D]_"4J& -M7>%6DNLU9FY$Z&8A'W:ALS=LO/.I^E0AV]92#(#3,C-?J65=9J0>.T`X#+3- -ME(H1NJ96!5IV.Q,)\=)AWYB<_.]V-6'Q$=% -MTZ^!G<:;O))\!`7MPWUP&=-,.IYEA]IORX8E_RQBD]WJYFETK -MYYJ#(9P-[V@MTN';(F7OZ#"=PIDY>K,'7&[O1T\>.\*?2P.5W7Y3T?&?`+Q= -MSS3W.G!^O!WOBGG[V#W(??0YA$KG\]`ZOKL8;23'6ZX(VB9L;KI#`"3]=="?=9W7&&NC(:ZXTX%1/^P, -M:A+@\T'KW^^FH75_NIID=YX,Y[WSLFP@9;V/MQ)UWAOAS8]SCNV-VFE>/=2G -MB7#LP6J.![P(U8+RPC(@O,![M_=>`_KD4%V]LQQN5[7OOYH5'3*'>@7/%IRX$I<\>5V'PF.ET@+Q$G#@I -MW:OS=PUDP!]/X+R\&6:](&>OZ`M.8W=_=QYO5O?S#5?=[N@ZWN/,AUWO![%0 -MKG#F6&[]?=#B[%C>,8O'D3]E!&#;QCGSZ$(#9&`;QCWS;E=B_7C)K^Y.!S;L -M!#O":2WM^*91X*[+Z3'B\96X'.[$XAF%_&<%2*"V9""QF@VSO&<7O;(F="V> -M#7*7@9]!N8LKN\`:#KOL/=%YHRMWB.1N/YSW).F&.2K\=+)-[0N3+B'`Y1&X -M)N9MFTSMGP+V/+ZMXE7H?#7!IT0[)?M24Z`:5^C4(& -M[/@$N\'-;\<[3*_>DP!JK9M][-"@OIUEG$TT.!M%_QD_HZ@4"A4'E/6\:Q16 -M.T!4/7&M3O0I/.WC$,,J\`-6)(5V1+TAS!D';(&KB=SHAEG8U8%\D)YH#1;L -M:JB][8S1M"[&J#O>N.O4PFM_.9`3KMM06S/+UKL=-$D'W/O";K-X'!:7B_LO -M">"2AUE[!-YAJ9AD`R*[+`GH8('8GOZ+Q"$>A5XZ6]FR.M3\DP'F;F\:]@8E^,^&S8WJ]L*PZH;X"]7VX>2>7"+@!/1JBQ"/K>$WV+TB2=ESNQ.B -MP_IQEZQ!IG+E#*6,L]Z[!AZ)QIEH'4"#?O[+D(X9*;UA@?;,H(7MK -MUB7HUJ6H1%?S3RHN\,*JG)-VYQB%>>O77<]!=AY'(!P`U?O]NP'ZG@WC.R*/;H2_5C`I^P:E`WZSJ!9 -M!J7)?\2R`'XI/3(;-!77,B[G29-X`>0VT)PWD![#="2^KP'Y$-`K40;'H2!= -MZI*U0&CPF37VN`*K)]$'T!S9B!-U&]%6[#7834_J`;$AO= -MW\-1SXD>>NX1O0VQ*LVW#:DC^=&LX&^`76!OEF,5VI7/N'&SK`-#->U2,>@. -MZ]`ID($&>' -M`QL])^Z4SQKAKYW+VFZ9OY\ -MY[OWMV.11!ZC3=A,-F#/M&%`4`9$1$,C5G!(:+TU=U>K-:T"0EB2Q8DLQ+-* -MU@D"U`M`(1KQ&G$EFI!BS,,U(0"2!"&AM@TC0V-FA8F#?4,$A#!@,2#HVQMH -M8-L.Z`&#?6/HD"T@(6@$:4N7$WGD3-55W=9F(TOO[A^;]YSWWX>\]^6:+J=$ -M3$Q$3$Q.BJJ\RZF?\E'\$\CR/(\B9B:K+PO.'.7R_F_/#B&AV,/'B^LDO/($B0M6"4'LW@YVC0#Y9`=8>G`3)+;"951^ -M`)>@0HB/DPWQJFW$4T86PQ['Z&ITX9"\)*<0$0EZA"HN0X;HIGB6Y( -M?`=(OZ0-*%THR:;#N33K[D1R_5X4:,1]M7A2![!PA:@S(G!VBBYZF(_8$^HZ -M0`TU^(EDRK\91.V6@`+K(DS\,!5!#@9K\_3B+J2=X'1L->OX2C2FM# -M?DE/EH;F+7,91SMGK*CW6!E]15"0"],)?T\Y+FM+RD-_U[E.0/3G=/%/YHEG -M9SGS0WRJD61A2SF:?E,H2K%),0+R2R1I\#V<)9C#Y0\E2_&"/WWZ$!]YF`<4=]2!86&YS/;$L&Y:*[TBB?[1ZJ.F$E@F?TK=SQ.W*C6JGR0!*U -MQ0ZY):^3"34F^WK"7DO"=?+$*+1)`(C%22FGU*2PN/4AC44TY+G15Y<)A3;U -MQ`=B:?O,0-T^(VY#\B3+_7"8J0=K&'B)*O]B'VY"J-)G[4/N:8';L4B37`F. -M9^Y&7(E?DRQ1IH*HZ98,CHI_]SU3^;)4J3FU\*4Y$JI-:DM/,@N;PT+7$7VR -M.6?JCIU+R,*P6?*3=GN422NR@I0YW'9$NICRG,RY1GX"@*^,*3::=LAE&WYX -M,3DTKW>@'^BKJ]`\B#`[-*Y&VTP(OY35([5`FNQ)=?(&RD8WV45'8!%6RE6/ -MNP7R8T)?MC&5P/O05_"57&#\=O2'`0R7H"0YPT=]O!2M5&'J6RK#G^$N3=@A -M,XDMZ5`_;JR6<:ISTDPAB.G$8Z`L]"3]`JZ$F)S/VSV->2O@L5Q`5,YS"28L -M(+Y5,WEVV)Y7[+$[9]TQQG3&ML08C_,!<7`I!_LLCG*@J:`J^^U0![*#RZZH -MZ\,+[3_A05/YV7566HJVIKD'$JK39B<^)R49>#`KHU50KB,&,@9]Q/=$=.4I -M!2P7[C5$NT=$_Q3*(A+J`IE+QX#IVNGHJK1V:8'")(-`]"+BIQ1+2UP._4"; -M/RM.E1B7)"`M_)BZ`(A^%MTG,FFW:S)._@U=2D]/B@)7([#KI'YCK(B=&,T -M8,,`4TA:ORBA-.?R0$:I++Y8!5V_E*(#B0"KM?*(4FR-3C>":>D9F6?:HMYQ -M!LTQEZTJD]@E\Y#*,82M]3%\J/(?%*)]S$4!7I5+^83../)"OL"0IZU`Y&`O -MD'RAC.<<;(O)P(G9,TGCJK%SZS]4PTI5F"OCKP3`$PJ#6*7[#_"LB.?[M9$\ -MA@'JE8;TNB_ZU"V)7V47OB=*2[XGG5*IA_C$$UI53GW -M[]=2XN?G$3L7[*VJ![J1AGV#7Y?K(O2-4H^ZB)PIZ=^R@N=JA8_V+]A'5*:2 -M`]@(J<_T2&!_#)41O3K,\VQ(W[OMV;MNHNQ#7LEW) -M4!C$-4[*(6TU!<=H5Y8GK"WC!%=J5]\=+F))6*.=P5XLGJRWC!%?;*\"F'G$ -M+#%SC;T3G8NH+>,$5UQ75D9HEZ^G+CL"N\D](6Z`BNJ*_O$7I+[Q<^L5KD[` -MMT!%697ETAWP+HG.%SB+V3^%E.K'^]"J[ -MF,<3QQ/^,7.EO67*38Y=.E[")9B=LB&77?LWR_N$BCE&G]*XH\>;1/CP7&J -MMF"!Z9IF=M#(FBZ?ITQL[\*FPM%9627U(IIAG4S3?Y"=T1-DPTL\(V$_]'Q3 -MA+5'&1OK-W'`%@8RS$_@'BG^'9->?Q#Y$\DR@=+4WVWQ5GR(>HJH)7`171$) -MPU"=.P0.QLHNE:N*V^18`IU&X?T2&[AHG*(<^_3`:A]+,T$S]D_1-]8D.244 -M7=%OW1:#_,&#?QJI9SDD*:CEEJC;77E";>#X-`\?CR8`K\P0/;Z9@LQ`85B_ -MT("4;7IHH]7IJ+06:7\WU*@#4$)9^4X9B`X?5T6C1.-);[JY^O>%.2(@EW"3 -M%XY@TQAV57V[,/BN<'L$BYS(G!)/H`8,0/1%-&VX]K/,)[1&_ODC",-GU::J?-/2JWZJ -M?(P[?JCK!\X]*NUZI6!OP^`*@:[B>S#E$3C!IZ*HM_=6E"9Q/VDY>BM%_V6+6Q(^02HF2&RI7_K%`%AI*JX'^)0U$)&& -M7C4!GZ)'\I+<5,7-E='.$P!2=;`/T7<3X:R'16:7LWU+#,B9(A_A268%]5-J -M;VS$XMO"U8@>L5]LWIV[:+VQ:\]"5`9ME)DXE8[[T='QI-[V+-L6E#YR8"$A3>@B[)JZ[4^$)PD/8%48(KO8L-FL%V^F3.D,D,\FTS -M$ZPXIW9:?ST-4!B-+3$Z=7\6>_(RL,GD<6A6@$AFC`OTZ9DXCQ$['/DK)I-O[8Y]@ -M"PD;*\0Y_.QE.-74;WS0UOV)CY`N9_"DP!8)&X?XA&_`+*`BZ$ -M=4T.?UH7K=)%IFK'?S$6`*]QEL.KBB`9Y0F@*F7]A)`[>+G24Y%UAVT]&@?T -M>,)C\M!I(LQ(M6/^GA5M>K(=XF=?]&"8UW1Q<@5\IAB8`L=)7<\/\HAI5:V# -MQ%_L@1IPBL\ZR2KB;^1XQABJP\^([]XS=O8P[`Z8J0EU_/Q;V])U\]%`%BV+ -MEBPN\(#DT+@E6)90UN8P\IV4J(1`]?3,$+BR>85R:S&/&,\1UFGG/MIF3&O& -ML4;$?*?WM@`[?3I+Q-R>465J3F -M$!#5BK\@\?*JN_8$=NG)1R+-#.K$!C'Q3?27V].XGNR2:7!=I11@N= -M)4[3`>BGV<[Z`%/-8A&XD0&.0O$0$H&0,U&0+>BJJY+_HB0-:<3>#/?=LT6S -MCP[_A\#N(PN5.9Q\I_-$J49T`YX;MG/+3SZSX7;%+?+3MDEZ_)!L=W*1U_%@ -MP*[FV]U\_BBP!8.2Q>0?XE#47T89=G`%T5DE]S#$=DE&9&'2(6S*O1*TE9_L -M6_^Y,8MX^5:L*_UFCOOV!CJRYL -MBL`4FQ9#^CN-0]RJ+'M:LYU*%R^=B\BTH'D<03`%@457DA`42*KPB6CC'*1J -M0:2+S9*WKYS4I$>J=L\G;C#L"/7E=M.U1B+[#MGD]E>'](19Y/6@)F+5NV;C -MG&BD(P"7GUX,G*':CZ-"YCF(O$1?>(L`4ZA;9BOL(#%(7F::,*-+_E)+EM5> -M[*Q,I\X&.(C)JH/B&#Y1%%36J(H -M'V)L7G^I -M?N$O\$KD-4K.IFND98`UALN<2[9RZ0VBN*:>C&"Z5)MOB7DYJ+^II.'"18`L -M`CW=/E4:=#B9YA+K#`5 -MP="_Q.EV69SB>^X:['[G2:"O5Y4E_&/?PZ,F`+!HW#^A15$:&_.=3*0M$)H( -M\YHS<[1&BKSVHW,)H%\^.=:DS_O=08HZ8[OHHOHY@_1S^$$KZ*O"BB_:4T:3_MH7IY=OC5N9I"?VV -MBE8N9@?T"*4>/8NI9FD!!#[`,FG&GLF(U2S*G^`0V#S^X5S^V@QIO#`]7G:T -MHUKIBQRK`^I",`D#`HSZ;FSKJ'0,8*3OFE6Z3$J0WG6IL.?+!+ZBCSW^ATJ6 -M8UC-"-.Q/@@,J2V&G//$>:=,KLXC8,S)^EP2_[I%)1Z$GG7&)_0KP?O>ZRG% -M//.Z]U`9K^VAR"P=0L<[(Y@[5'IW3XES@%E<&B]BT_#.C%RQSVY^-RFB#59* -MY')^TC86U.D"OJ7EQ%%9)>XAE7*N0<:SS[FO2+OE;N>W1U0MVP5_DX&!0LZXI-`DA/$0/NJ\)/ -M%OCE'G6RO0?T-PZ0^F,<8)_OO($N"5^P -M4,&"(Z::..,L<6M'^"(43Q#F<>W7\P>-:$(CKRC&'+;[Y&]$/#QQ+NRNSBH% -MZ9:X)EX?8-,7<1.<0Z);XP+S4Y?+CM!?'>X:G_:+\\Y:[=LP\<;X].6(=I>4 -MQHM"<$G+#NV?L/A83#K3-XXI'C/;V^1E23;O3:NP"/95V\T\+5Y%>17D5Y%> -M17A4>09O$4IVKMX)!67>*[=V5$HJ-*NW:D%ZO\KA%OD%X.W.G9)<^VTWC]?( -MN2HXW]:+>0IK>."Z%S[;#6H%[ZZ*EJ*'4E:V+A]A%6R,IKXJW)1.VBK9*'T\ -M5;)P^KBK%LMEU#I"6S4/8E:VB4)]R")0GW(HE"?9!$H3[(HE"?9)$H3[)HE"?91$H3[+7C;NR;[E -M)G=HA"?%L^BOLU!V)6^+9]%?K_U=I]4Q -M$#Y5>0L"XH0IM5XD8AT]>%""@2Q0H+PY.8*'B3D3`PAVR2_[")E3=O4T[PHQ -M?_9N)A(+_[5PD&`5&QGTA_H+9]HTQ?Z8A1?..3!0AVR3`)0B,"_JAX!T<^$T -M0@&\(=KHP==$UZ9&@P24(C!U\L==V$@P?QL`:#!)0B,'P43*H,$JE2,*_NI2 -M8629Z5H8QA8!B"A(,.<4OR@PR4(C#)0B,,E*CM;J)USF9-%(,3Q4 -M*6QA\@%P;ENUK<]S+GC1<)$S;EGD0E$8B9N`@K<@B<+`05N11-%`05L@B<=`05LBBZ*(!%;F933HC5P$%;/);^:R`@K=#>?LNBB`16Z*]]M&BW@(*W1J( -M[80$%;I'_5Q8$5:F@:U$>/`05BJ`16T*_<.BMZ^O8_S/2"@K3\2$2Z1T13$0 -MSIB22\2X?/&\A(6J2Z0M8B%!??DXQ'DCR?)@5XQ?=A$_2H<9J,8Q??91*Z"^ -M^TP[05R4/PC@/@=(G>IBT%>^<=\%P4%&FGIVR0EP%R+_71!WL$N -M@OR2Y%^27(O_QL`:"_)+D7Y:ORV@%'9I:GZ=#@%"8)=!@SBE^4&"27(P22Y& -M"6L(H-%:)A%"GB#"*$&6Z=!OCEO7J1'D)B>/B)!1>])@9+!?FN0F,,,\$]*_ -M1*FWLUE*X-'E#])+>%[4.T)1N$>K!%,Z_*^\*FWN5]G9Y'E#UB4;A'(],FEA->(!7+RY)M[M:[^ -M?1Y0]TDWKU(CV98M:67'^5H.;\R^S\N_(W^.Q$5<:WL$KSJ*;>]97=XA'E#[ -M4N4MZ]5QTT13[\=A-]\J;>_8.4H4>4/2(WUS<<(=^D4/9)-Z]2/V<.&5TJX[_Y2I70S -M))M_2RO2QJ/*$W,E,;A'[/5EBOJF&&;;^MG?=QZ/*'3$;XYN./F.I\^P*?6E -MRO^<:FW]K2I>11Y0_V(XARQ_A*T)TAY8Y%+V(<4+#"CG)>P#RB43"!GYB8"? -M7-&_UJGU*XF?(2)\`YY^08;533'^:.58"^*Z86O&V4%3R%G9>M#S!,B<8/3` -M%/'3)7@IHDV_OE^9R*/*%ZFDL1&]>J-`N6."*JTA,%,":*ZQAA(V_PR3>ISW(_)9S@XDQ!=Q+Y$#F7?2MY%8683O;4O$F$:F -M9\E>ONY2]I'0, -MI8B9T2/I20#$&5)L#R6D";%YIF#>)EDP/CZA,LQ2S!;30^*K]X>.0;48R$]W -MG"E%]"C=Z4X,37O%2,H8(WCE4OWS&I0A?9ISA$T5\>LI_?KRW,^_R*`Q_@<$ -MDB'`0Y"C\/L")NY5DCSI,P3>FZ!'@#L[L1'5[H"'.A4NA85YNH6T11)EC1R09)A5 -M(V):3B\2RO+BC$3C%W5.'WB6,N-I.)QMU#^-6.NZM"@8]O6?^@53Y.J0L21* -M"RPI:I$^@54;G5`AR-1F(3E",K,B=\NPK(C_8N@NW[=`4"+!DC=A$ -MX;*&(D7Z8=\E2_,?_0!`$;_IW_W@;I?^[*\*99%O -M\OJ@?XBIC]TQ_MUSO!N5GO`M%HEIJ5GW7++6:T#EEGD8+]&(8.ULVM#BP50CVA6A<^ -M'"`_C!\/5Z(J]9X1MGCSDUK -MZ.,VM,CE5CFJ#M/"S1#I[2F1PX@*R-(/U>L`;:@/'Y"3%";Y=/!?(+7M/$3V -M[3)1-D`%,]45-X2_ZU:84+%I0&`_U-I<`2:'N%I;NT`2=YD1Z\Z(6SN`Q*9I -M@)?2:3_-[(%TV$+TA"BA`''(5YBP=&0UP`F#,P"2=!# -M00++Y;K2NL$@\@'-MXPQ"TX[JA#1'?'T`+D2*^@:RJXB5PF9<0$L$L>`"/`- -M@4RSG6C:O.K3Q>U280(8>YYTZ"A',7\U&N>=%_8_BR?HJZGK;0!5#H=%9MX& -MRZBZ0(2_J+"I9AS&M#5T]/0Z3'8RFQF*Q%A3JTDSZL>E"?_&X-2F3$T82'Q_ -M"-9!(Q"Q;J0=.R@:$8MF;MX0LK.H$GJD0L4CF8&(/]KF)'34UEHJL:$ZL<,L -M;2G-ZCKTDC=%<%D8.V$%F>J+#T%755\B^KDH2!+-:'S;$VGH@#L1* -MF"#'\?/=]HY:M>]0L+D7?6.:#?B`]H5H/W++52SL5.5]:=8%W -MT`CE^V7Z5UGI<1Z^!=8B8-_UR_WB*Q!:#KHOA@%PR8B"OM0\]1W*KZQ:9V*9 -MA"!I[*T#T[@;,1.0=4J1-.+2^X`$(+CC"0]\E:I79I*V4SP'FN=B?1+GKM_ -MY#!?K^S&'09-@M9PB#9]I)"NMDZGP\X\.\%5'$V@!-P[A*(4SM7F#G]U@1ZO -MS,?(XDX2A.3("P&<`3>ZM%11G?T&*1'IJ#X`?.M`U(`_)X?DP\\T<->;/*Y -M2'YI^D8^:4C\A(##B0'4_DB`G"!;+.W?3V;N'D`:F$BB`?6J4!9&C7`HB;A9 -MT&X@2P[M`BEUT`='PX_/+7P%'>Q()4?D1U/3(C%Y<.*&Z>#ZB`&IK\M5KF-S -M$H&B]G%=Q.M,44C!3NCX.O2/T>&7:RN*^)$K"=3D6I`HX`]3#'P&2P-!X;D1 -MN>223X?DH[TN:.,"N="]`E1H(L"@AJ40LB?J/UZ)Z=`M<\8T2HE2('`,4VDD@J\$)F+*T!V04HP -M=)D#!,%>:UG@H][8C5%$'K4DN[O5!(J_+,64MFJQHN!?T\$5:&2J]"%QE$*[ -M?T!R72,$(^("S2=BT6,5F%NP\?1;XP*DU;/`6PQ*=8>S,5^`O#C\G@_G`[>9 -M`Y=K?GLE-5EUEU6A%*J1NU6\+M`=_B`K5<$5RFK3;YNLPR&@LWYP1E%*BVY` -M:N@/JM@]F%'<%<'XVAW>R4R5)B]&P,'?2A5ETP"N7=Z](T)1%_3%%NJ^9IIJ -MB,=-HKMNK9Y-S&=<\T5"W>)8SVKJD$ -MMJR6)7`.ZW:KJ>&(CO-FS5,$7MTW>#/&3:T\F#!BLLQ%Q)W8`)M?:I`7R_0# -M@ZP,N:A8K3^REFNF;<\]V[WJ$CSVBZ;4AF@IDR^?D(\BTKJ=ETD@^(',Z9K2 -MB;NSNHD%ESN"<`A#UX?NL$)%#JU<:OU%)YU@7S,&'X^MSAP3SNV$WO.ARIE3 -MN-P`8'[KE]=&PEM&)TO1SE+I7QM66TF>9;?W=%]L43,4*KANS,I-&\"=8=*M -M-^F"!%[/.C<5S-HJD7K1$IX)0<`H0CJW4<]HMACE^_7[-;!G8>BU#7Z[7,41 -M&[K6$]2,QP2#SR%N.`YA@53@FF>%Y6R"IL6(00#RFV3.K[:ZE-Y'H6+[H\S> -M>SUP*)+J_25ZFHSX.@]GD'P`#OKEKZ$.VJ5MQQP4PDWL*I13O# -M7(FSJ8T"J@U*I<8(YE@KF)9$V(0H#B>!7C7`<01^0+E3@'W -M>09?9!-`9@F`(\BP6U*FNPD;RG2'5&F,TF>0C)[?$'MHS@F$K+IP"1V%K -MK/*2%]]:;F&)TECX0;1D -M=X96![OS+-EY[RF\U^98-B9)7TBFABBGM4?F"O\*8V&5S9;K$+ZI"SNKVFT4 -MH()$;)>0&7($'AX,\+B)XJ'W?%?>EKCF`E4Q+U#(%^'7&.#5!9K9[L*:]*9V -M6)7#8M,-2D1N9G>5M4M.TX#?-D+2.DC2R*TJUHHJIH2QJSQ/!9"Q"8 -MM#81!Z?!YFS@0L?I$@RY4[OZX-9\O,2&13GZ/&KZ[KF,)(JS+2+3.X/U%@L+ -M;;P5IH8._R*P%9K2@6W]6"]P(KD!:MU;!!)S@K"@Z(,X[P+K[0`CC'G2G@YW -M5HOM!8\VD\D!7I#;8/]B/7P0!4(O`K`&9IB3"C#-BTCZ)(+,$I5@:S9;X@E/11< -MM'70B^I3Y`>E"#\?4H$70#(<]CE=^M,[D.^"9GA,P547UX0#LB#J>%7?KUH! -MG:\7$Z.M4ZQ9R9<2,.LH:XNT%YK!`#(>]J&R%"07\@W2]&>&)=9,/H12)KH) -MEB!$KAH(MP:,!]$+A%XT89IFYYRGS@P.0C0\S2V-58X/2@9L9ED\%_>&`R=8 -MB:5>H58,@(42H89](8,+'3;N]"UZ>\N>1['4BV6X6E0=%[.5##Z -ML2=Z17])-F]FB2[WGQ&Z(2^K=PQB?^69ECX*,A<,W+^W.+Q?TN)?;40"!"S9 -MUEUQ@28<80"-)QF1H^9/-WY4*)^#&#K#*JC0*LV#YU+3U:>.K1,O:` -M[21AH5NH?YR2MG.H"(,B('KQGH,!?;)SIG@GE886<>6AW/E;5'8&0OW$!D56 -ME$HS>,,G#9`@,@.X)P?4D,\[_6X%(>U!3]4(=W]H56Z(6G`42._FNI].#Z>G -MD:ID=_J9&G/XSZ\7\Y.(1I!)OP10=[FMRRLLLP9&57W"=M,8O-IN*!T6"!VAD>.%`,CN]5-*S[M8QY19YB0)L$9=C"7/ -MOY*B8.J,Y^[UJ>04&9OFIL_DU,_203O#B;PV]`9N$2NG!R*]68U-6],>ELXJ -M;D\094!/#8IK?QX7K4VI[VK5![$A:W=.;$M2-6\OB%+`FUA3D2_6^*=M)3^# -MV?N^FLW>D$(N8_>>$J^Q.[ZDW'(D+MWS1W"W)A3F>FU^B-,.Z+E?U0D\\+\> -M0K#*NA`S$^(1+7/O4B*T*!+X1)Z[A[=FYC3%H:ED1BYF+X%5C:!7-Q78Y*=W -MZTO)6-+GH'?J.0H]_(9=9,Q[E)K&CJ!G&@!YN*)C!M)9[51'6*R@I*+%Q.2O -M7S5KY@A/8Y.96'@@KQ0IN66*4W#P">!W,$%'DTRAUB952&!9B_=#D6-:^>RH -MQLKW>#";^29'4CK(S`G=WI77)N3O:(.8ZK)W1T9.[KQF$7)D("]*Q>U8CKF0 -MLL>7C[=-:*2"IA>9/E3SH5@O/,(G;P&Z_[A953,B,;^0F1A^AC?77("WZW`! -MSLXL%+IQ=U4K+D\U%.E-W+9IUCA.$NN+=0Y&[A)(CRE[3:)^MJ?V@GA3P@9V -MK'%\<1=8V66E9#"[U0Y`@!%>=JM.=:#1U267B^;5E(T/\((;8R#X8EQ\@.QD -M8QS>%%@P?P8?X(':+/O!BN(IR?%?HUZ1*G'D'G,T/D3M:#RH'.'(SE"6+$X@ -M8&*9-3B(4Y7K/F([IBB>F2[]$1N^6B@T9].*6E%[A"_"LXW'!2#5`6X`[UEY -M2TN[\G3]VM+.Y?(91W`R&5#_+90\`+-A.KWR2'`3BR\W2"HF]]I:&`D8@S!# -M\7MSYJMX!YK>OX:_1)1.!U>O21(<+BJI*.XF:6@H@92=QYU51S(VW/+U;3$5[KTN(70#`(#-WP.I86GE4K'-TJT\J]PP>A/*.8/>(`N -M@.E%K$8C%^GR`DQ\ADFSS-M_J3R6N&;P9:E*#/Y-DJ\Z#()O-2<`YLE$X!I: -M>YY?A+7HZL9A8ML'GJK33K%!2P.IH95&+_V)L6]82(R0#-P'M"HAZ^F=C>;M -M>B8A*)?@BV#S@8<]WU:1X\$V3#ODA7R&71=FM>3P[E`I&@H,U('HM5#K_S+N -M4%'81Z#IV@H.>N#0;2'@A($V8ME=TJ -M>]29$:EC[,MNN9@SN=QRB5%*QLQ%LVEC\Z=9^59R[)VX0?]3S@.63>8WF>-& -M#I?5;D*U7SV56'_FO=NZ@CGH']8KIQV+GZ5SU)CY#2W/GEOU'GD]RY[='!/H -MW0_U%TM<]2=_/N>.K?.N=XK%^"Q:K%TR?.Z&N=$L?X%$[P;GP#Y#2^3<0 -M^65D)(R+77LP-&3@_B:L^!SG]U@KPZO(I0VB:8K0OBKOIO1[$?YC67?32S24 -M\+A8K6+1X7X/"U>%_@8_O(SN^.1T;8?/[3P.PHF8RPN&QGU>;=8P8Z@.@7+ESM4T?6I?>#Y7U_7FC_>%_#_(JOVD+YS;;*X]_R2FV+[Q7ROI^N](' -MXO!+W^[*;$OMQ\U(_KU1WUNS+&R&<.B?">$6V -MQV*:*=IM'7-32_\FJ*[?_'+,UKYMTH^8A?E;54!1',K^F5_X[992'S?M1\QX -MS-$M]1^KT_\IO^4?YQK(^8[CP_IU'_^1U@/K[AL]/XGTZD#\93U!?>_7^Y)4 -M_YBW.SJVCKGI&Y'][_D5%*?G6PCYK#>+QNY)_Y'9I?7S)!O^/%1[_E?XYAHY -M'YYXH^8\?QOH.2#R5(/ME/3E]L/GDQ]>J.F/>SEW@'*T/@++\%/.I%QS;(=` -M$+/^=67;=?(O^8$ISU&.9S;LD[ -M^Y6=9L=)5)H9KJFKT%P/H_AV@8]@;Y'4H&$F'>0%3439ZFF@)&SM=!6@R`.[ -M&SFX\5HE:E-5DXJA!I\`=3@_`2BKTDP83]H]$/7E$C%B6'0.#H$=H*9K4SSL]+35`A3H7N6I>`JICP,V77J/@4QQPU..HY'4VAJ:H4V.*NPIJ^JJC3JKP[_#4@_5J<6L# -MRF/4B`5X"\V/$0)3,B=P?AOHIK:QT01?7'J5'F1AZDPM-H*BHL0]-R=+@"JH -M>(A(*R'^),M+T_$"'H&.&ANG4RL/PAP";A]IE*8K06-6J94SC4JF>Z=2I:[- -M28!GONAP>I_(:"#H2`?;:*HLZPXX-)P?=H*+=*,/?76AFY;&JT9A5`7A.J4$ -M%`U:WICU*TK4#.UJ:UQ;&M0@G2)8R6I9I3A2T$936%>)!I*.INC4UN^8U*DS -M"0*PP;#A5)J9H.NL%NK&Z=2HGC.IE49Q)H8K0G%/A503J8&*U*6U)=K:^G3, -MTGJ<$<9U):C4^2I2)75IFVRKQ0-'$"9BDM3<6L!-'J6I4R4::42"ID]37T5( -MTKQ-:E,0&-0I?71L5$FO8=)7@6+47@E%JI1D*9&B(+(52=3(&F.H$H_KEJ9& -M'X9N6EUJ\-C*H&3;&K>?[4Z"Y:D]TEJ53I44"-;)1YB:01=5C@2U>.-=HJ=) -MFL:GW3*`[JU*4U&A6"^M`[4JGG5.T`&EI8'P`R8U,-0T^M#/RFL`?-$X2H<)$?1V]VZH)"O8Q1P(.I$]&S=8J? -M`1BT.IZ812JFJJXR:0#%PI,CZGM]M3V2:7[.U8HK"314;$K/PIYLL=*9->8% -M_=^INCF>;T@F2KT2=4DI-(P7"`2-4C5.J6ZE$PHBJ%(D%!(#:AEF% -M9A)(6D4Z)VF@QQEJ#`-4)CJ`5U766=W -MZFKIH54PYCH@L!J;9:"F85AD]4I-3G20%R-$`4*=A<]K4ZX. -MO+1J]:2[=3?`R/`\J:VHLH["=0Y"3ZFU`Q:U-J`KI3UPD=:U9WIL?KHL;#MX -M;IU0MH[*%5KP.)W$5-=/FU+G6I^'A,..H`@2B9)Y62D;I7J4%'XG%X]E6=O0 -MI34!U>?BM759TI-FK.:?GNJ/?=VJC&W$)K**'MA7A89+$/%GPIV+"%A;L]52 -M2RK([>]JD,+Z6C`C##5(@JSU2*#,P3+:FJ'8U;%8IK54JNNV\;ZI%PH23<#3 -MH$QF*-+1W<1JC)II!5I4M^D:HF-:Q95G2(:`U,]#\07\86'35/475J@A2&J: -M8;'Y)6"DNP%ZHLX]8L[*%,*02RG",7&CLJLUS?F=56RRIE5-[EJB5 -M)FH\`HH&2R"3`VP.FI/5388NJ4A)[)-BP9%J\0N1N38!"@Z2K>*2JQ8!@L-! -M5IID#7*F9NB],HT&7-H/$9:;^T30,85813E"3(-``;2V%8J[T"1):.4:O6DC -MTDJO!4BPF-7-.J;4FY5FW435N"1:>LK:A1T':[T]J8"+AO(,PCU7Q[IU3YQ? -M<%,%$V^!DUH*T$SH#+*U8KTW7JK55H)&PN)T"O70I.2JJ/IWBJNCZJ5YX@9* -M.P)<32)2M9Z5-5?C&J>9':;FWONS51B,WU6R7&M5:N0'R364M*=+MHKQ=?F2 -ME=4VR3W$+H0HV;5RF41MFI(1VI9L6;,7'/1)H4.GUO,LCJMJV*;(DQMI+,5! -M$AMHJWN/#J(@Z3%5**=A4/0UN@KNF3`!,[-;5*)K4WC&K/KH*9K5A,,OQ9Z6 -M*2$-.BJ\+&,G-<<>UWPAF5Y&)$DR$ZJ*#6JP@E?(6%1D=H;/275A1%695/6* -MF8%5:6%A4IP(8;#VI4SC^J9DYDIM8*VD85^.DFFCXC1JW"3!'XDMSF*TL0EZ -MM!+"9SH9T20>Z=6F!MJN/TS!)W5JNU'40J#O@UJI/"FM-I7"G^HI&L/@FU&N -MW!D)-,[Z@FZ":`V_=F+KFKPUYT7TGP_72/697U#P]8*\*N&QJ[_ -M%;-]0\-3WU7PT%2,#_W1UO&?GK.C"S/SU?1@0FS -MO*.I\S\\KT879^>C$RX]`NN:9U7#T8O#/SZW -M1B\N,E+EU7IG5:71B]N+J^D#CB[;XX1U(%]<(ZD#CR[;]%O[A'"=?3?WN+&X -M7+MF"AT*=]F69I%>N6<*53>++')*GN].,PPC=E'O+W$W.D>S9$]@6=04W-0_ -M77:7_@%3;YKA>/=H?YC)3Y^*\B_\7%5#>'VY56%G?E5:6?D*K`LK.25F5`'^ -M1Y\G2_[^=PS`OX>+K/R]MWW/V_"_-X4/&5;.MJ8W^O-TW;X#(>9[/T*D17#_?VFP[CILO^9QV>YF+3B1AZ+S1]3N''2>-U_ZG'ZX-$XO -MNWS>Q7\;)^?WG/?$)XF=[@J+8Z/Q?Z<&%V-EV.\U<7UYOS\5?>XS-'_&:F_. -MT/(5#'S>M3KN/;;&N>(Y5KRXW;XL!!KR]_%\_U_!6R49'6ZANGZ!H.KJC.(Z -M.$DH=@@CUSK^*YDA>>MWJY5KOTI<24F/7H89)2XF[B+NJ#__#_UPO]<9P>'Q -M??X+SA^YO]]P-_[WN[[A\/I/P9+P/^#XN%&'P;X!/N<#VQ^^ -M[[F]WON^WP=_P-+;:W0<2QT7NT?N\#A_!P_;$%?_.WV]]SA[W=;SW=U\'M_! -M_WMX/]M^'OMH'L\/=;GV_=JNNWOO>W[WP[W><+;^X(3A[OV]OO-[W7,;S=\# -MVN!OOB$+&'I36EZGVP2']CD6_N![`]/;X&SS'M>T))NM_NA*/<]3A_]Q-[P= -MY\.\$R>Z"!'IN_:V[WL-#ON%Z^\]_>"9N")B^/V]W[N\W.^W?P_!_S\&W\^? -M``"L^#=^^)1[^]]G=;O2[OL@7(DOL^P)JW.[$\>V"CV_"XMSV`A^_B>]*..* -M77Q>,03P7:N2MWI.X^<5-N7(/>&O=`CCR%+]UQ'_P-HYH0LOFBY:C5^&ZXES -M*)L]COW+[AR3[_X9^N*Q>JD\(^P)3XQ?=T@;GY49-9IW\KI3KBF*!?/!][Y& -MV_E/>N6P,:=7/7ZJ<\5SQ>,`^_B1]@78SPN@61W1@(%OSC8'6;Z5%!CLB^%=J35`?$;Y%%M[Z0]>;VYM-OC^.!\+[XW7PN8/$AN.!#:^ -MQ-+F`X5`.&'Y[`\:\IX)A8P3^GZB>8(A5.TA#A3B'NH"9'&29![R2E,9`C(; -M$O2^W-ZX$:3@N%>F`S@&X2:L>>&)[4-F7$>'^CH[NNI^K$.?_^VQ^KX8^OZ: -M'PG!\.OL:65_WW%CT>%_AM.YXN7^3@K_(CJS?Z\KWU)^[O8V:CN2$Y_/9N-A -M>IO8:CQ_+S^SVO!E7'EY)QV5CC_V_RPFPI?RYQQZ_K\KF0`=S4X\OC\%TO -MW>BOG8..]Z)QAI28_,X]/O/.R&G<4O0^U5473O<\X\3&]CC^8R7EZC`^5\.H -M]7EYO!;&5W?KXQQF/'[/RMGHOZWOI^)YM6X[&RZ'XN_J=GO.(Z6^/]F:#,:R -M['_3/:CJGD[ZO<_D\CULCN=-O8O\^+@]]%W5YW7$^6MUOR\3=_+[_!XYQF_S -M7'7_#B_'Y?)_H_Y+(G1`@>_EB/@_'SW@\SX.%]%YZ]GM7&HU&DU?,>%U>IZP -M%MO77:N-,X[.NM_7U&LL/N]*X[G99FDPDRXR_/^")HVV.B]Q4D?W?JO'?V\O -MW5/&C4Y7D,YQ?#1%CV7N>3SOZLCE\;UP20XVGWN2L,E`IO3\_Q''>0_Q=_E^ -M2SO%:V$5[F1R*SB -M7:PI^9V%3YML4_;>J%3DT3A&+LR4;B.KM>QP]G)J+C_U-M\-I-U*W -M5L2)_ENV'O$L79A2@?EZ9UR/V<<5D%!\-O\U0!SWS168YTW3V-G96=I551NF -MM@.Q36>C'5,MAT%:'-G7V-E3:"TT@DM?H[!/DIXQM)CL9=@( -M?52X<6-CH.HIJFNL['J'%4'6CJ0`6FCT?4'(I%Z>OEO)A4CVE!(=G]2'3U;; -MK@AMUYC)=@K-=7YL]H+)ZK[C]3!R'8GZNFRI#IL9CJA9GIQVY=6Y2/8NC;J; -MF1['SDNI2I/J\QOV&&UV#M08S'T6+9ZZB8Z_J8['2NCK$*Y=-T*\F`^-Q(^T -M]A0I=4DEV&!(`>.BX^0AL=(2K'8I&N.+21#<>6F/+7'EICXN*HBL.D:1@BT! -M&M&6E&6M&6E&6M(6E(6M(6E(2C]13L]7B)ZM0/MM4!&+,ZX_:K[,+C*.C:]U -MT&W3>7&NFL+ETQU(],"2;RZ>D0N@N72G+>!J]+3'L&[N,S&9^,[!T*[@;ZML%R4[!^EL -M/V=@\S(0V)^G;!?(]A#ZVF!.PBQ;0;':)#&P=V;4P5ES$C;82LR$;BKKZZR/ -MNQ6YD2)>W'"NN>F\(K803MH7^Z[!K%.PFP;#RZ4S)V$L-S(2GMFRI*MA+DVA -M)#8.`G7A;1O&=@X8WV$H+:5IV%)3:#/851W(@!VXG<8DNYZ)#86_`'8V!D?S -M[8.^)V$_+:89+MR]6PN=N2[3;8/1Q]A:PQQ2NA=TJ^C;!]Y.PN -M9D!?1XK_SM@_BGNAYL8?S[80"W17&^D["!K1W0IJG8;#-H/_P-A"$K88&-FC -M]D73_XVPAH5L.(VQ!_/-A#ZSL.G/G-OO9)[,`/S!;W)B?57.WI;W6QC8;#M@ -M7YYL(UV-AWZVEO_\VPCM/MG1M/EU>PH![#^9L$7;L)%&-AS0V#KMV$E0V'>; -M8*:ZY\3L/?VT;=^PE0D/+N=':E?.-A+.8AN^9E=PG)\N=-W@AL^N,;$7+YK8 -M33IQ)]A=TP27=Y3&P_GN\-XUL)T4UN;NE?&-A/));$(2[;Y9)X7-6Q&3;!DC -ML14I%BHQL2@(]'Z?8WMM+F>\JG%`95V>@T)\1,2%6-.3.D2BPN`%(JF@R>4S -M.('C$P,"P,[+@#V:>.N=0'Y;C'R+\ -M;1_TA1Q9$O_`FXV.EKP-QC9O+K1 -M_&?7,R_*1<=A+C&D>HTO!=/91]EL7=&RWWOGS%/_87&9NB;<<^WD$JC/:QLZ -MC%(Q@]6CL:^OP(SL-K&Q#^9+^W;5?VVRZ_B_%V[?LB6ZFB]&'+M_?WI+59(O1CBINC_FMP2_#=L_H>5+MX/Q$L^X -M<%^;FZ^A+J7XT*BOT7`,-:V[7]_(*=R7UJ[VP-CK -MRDGN5P(3"[RP``3HJ!;M@P)=CGKX@!4!-VAO;64O86YT96LO=&5M<"]B=6EL -M9"]U;G)AT1.U13)#`@**D5$14P1$5@P$@@)`F'OG57*P]^>^?M?O/K[](DOE5P6)I+.2@ -MO,I3/3:6;S\U:>Z#/)2:;7E<+*-#P'Z,HUH8+W$PBDVCSLT(S47P(#JN_V/Q -M\)G!*&^F6+PR?17JI7O:(_)XZV6NT1\;9BR,NSSEFSENMEF+WV>1S%GA$(F^ -M*!=ZOZ'N'--I;5,ZDI-GI]E7ML^S6.VE@R,=MM\Z?1)7*MOF>FY4U)AU".\` -M>KW2U.^EV\Q!#&C7Z4Y#=]5AH'E/D%J8'&V7F+X75W_RG*#?( -MV,]5=3FF*-RVZY_DX;97G<1$"NBJE6\`N_37U#3.E>>+_C<`OJ!4%='=TI,0 -M=2*08CGE331WFTE*]YNQ:O^.6@+8M>;R^ZG'+LLNTV"QOV]J/U1T+Q`&+I1I -M<6!C5O?CE.L:!'*2\@!D4LDEE4H]++)9=*02S*4BH%L@&:6:2S:6>6EO/@:! -M+0I:)(S`Y-O0_4@2J4LEK$M:,RX&NI'V`&QI,^@!LTMHMI]J!ZJ7KI;A+V4O -M:;S7[;3/N`;I+=C/O`?Y2]]+X*3.]2^,#?I4 -MM.?,`^927]*G7Z@/K2^RDSSP/M2-`&^X#HJ3_X@=)+II=1*:2_)+\V]5_T`F -MY9%F3L;)/KV5*/\OKD+KS._!O&SQMBS&B88)E^'ZV.^^AC;C[EM^;@^_!YKF -M\#*[_V)&O?JP?>_PO!B;CC;'[^;_QE=Q^?MS7E;:NU_9_A]'Y^G`8GD>_]6Y -M_7O_IBKE=?8^W><]R'O9;OV*P5/X[U\T]ZG-NW%Q+#*][!2?E0LMI7NHZCL9;19K01>!VNJ -MK4%6-7`6#Y=+-UJ`T=.OG>C\IY6`Y;)YOG&EZ#TRB<)COQ[7W8?U/U)U7N_/?,IZ5O_F5@, -MKKO+Y6`>M_[]\^_X\)?>@5)WE=]D7T/N+US7G4?V?V>.IJ[/W?7J=DH=9A^#M]=FL+*:J%8T)6=YQGE7SJ_?4=%P?ZL_B -MP^BVKS\W-OQ>W&VSA>S+=*P4,AWZ#J;C4::U,RJ7/Q]MA-3I-$^6_U+KYW;W -M>3ZGAE?,PD!C[W'QF$YG8W5]_.8?JY^%8^G86^L<'\]?GW/+;FT3^#HK-$6_ -M^/Z^.4:8N\/]O9Z?O=WJO52ZWILN,5)]3">U&]4W?]:[#_GQ"M;L,3I?7>[A -MZ#S^5ZH/L>Z#[WS]C49_WV[1>O.O'G="G8+6,=]E-%Z6?G#S[[]>W[30=MH/ -MX2]4M0=1@M5;MS9O>K<.ZT,_4^,[6[T9SMT/^#*W1?'D?2\!@/*TZ\=#$>SV -M[39]SI(/,70I/TE\T>47?_2_-Y@I6\?AFG;;QDS3N7&Q/3JZZ]SV.HLYN+U^ -M71L>"?92J[>CW*Z=V=^U.,Y]ZE9OA0471C[AXL1C77 -MZV?]:31?MTH2H1>AB<_8,-[&+N/^;W[ELW7HN7@S\[OGWY[[D<'"1-TU7[]V -MX]*)SW)*MGSR+AX)B#?<)[&KKM%%?#^-OK/Z:*:XF4 -M^O!NCYXN^\]FK44_WGV>R?I]NG]QR_[=?\4P?:WY>S_6?RVQA:"L;38W;REU -M<\^H6:UYV4H?NJV=NGQ03S&]JQ=1\V-5A+<[=S3;+\>]^4/GM'UK9E,)LV.. -MFZ+XLCL,G_5OYEM]RN_+<.[V.]]5\AE]?O>T[CH\.?<8^#Q.2^?73^=2:&C+?(T!;WVC3OG*-3X- -MWKTP`O8O5"2SJ^D-$Y+1XTVM!34B]H:$U^D6<+_Q2X;YH3?!J!<@-*%N2A=H -MSAZ92.0G(TCZ_E?>[VZCXJ"A=N^\QQ;_&C/@%O_4?G.Z;M^_]4,AL7OQ=G.R -M]`N?(W:.JX?B_4%V_J? -M>OY=6,9K%Q/Q7Q]-VHW/^E[SWW/N.]#4/XD=C1SY/[^2FZ[=%WW7PU*@HG/P -MND=K'*A=G;P$^WN[/<\/6U#Q6UXF+Y*X&-ZN>@%SW]57O5':H5F&S;G -MA_4\/QU_E3/!=/+U=W).O>#WX#UYSNP71\WE.].M&=D[JY -M87HQMY;=?;]G;^;ZWC:?^OIYVU88?DRLW7/2T4[6 -M*BGYY][;JQB]91,'*B7$^Z\%.1=Y45%X2Y^ZC73[DY+BG(O[XF!;Q5>6[++2 -M^)U/0+SW>D^>>/)3O"3?M`Y'ZN4\ZN7].]$6[TG_"]4+F4'/>)HO5*.B+E5&A*"%ZE*A1_NO/A=*#Q,:/PTY!B*$E%RY5SLNKKW6+KXK;9RR -M_Y=/`QG?_5W?^U83C]XH[5O;OV5[KX7>A=\AM/"N'XK:43EW%U1&#^N?=> -MYF=A/T=02]'PUO[W5CW9^H1>U\#EE=B[>&>7?^K_/0>("\:M[38-M[M4]WZX^;(?A:\=C^O3GC![O4^&LP^JIW/\KVO5RE]B8;%9S= -M]ZN77:V+F?'9/%^TQU+5KZ@\XB0]'NX=WO5AJ?:Y_GV;>VJ=O>$_)U^F_.VT -M75E]=\]A]9?]W'2;#7^FYS?M^CE,WR/0JGZX6^_KI(IV^&G:Y=S;#]L/SOUM -MOW9 -MM/TS/NVJL0E.]%W^#3^CH/XP=JA("]^KJ\KO[SAI/0L5(6/X;-\G]? -M?+_E++G9Y[;W'>I/.?>HWRB7.7?GW2B+F+J,^8[+F.CYB\TM?13[J;LH'1>6 -M2B]D-^EOKRYH?OO%`YG`39HDX>::-F6S2C?#E1(DF)CE/,*/PN_B=:&A=9]? -M0E[W0T^Z4+"AH%SJOGRE=SH:-UHB]CLZ3Q:>CGW>BHG2@H"A;I/N;H44GG:? -MH7:CHBTACV5!RD9>YT%$P\-.*`,"I:4O%(=$9-"A),%))3=XBTQ93D4G^)W* -M<5WBHW,I(8.7B7,&F')A/43N8<\3MX6!224Q.9@MTVL\6B>OW85'OFU@[9NW -M:>LEJ__59?_T'1T[KE'^K0>)TG7)\GJ/O//B7YEYJ![3HY%QI7A[S"G>"??*'OO:[_U/YMJG_%%0>%AWJ>Y8_8^&H47;9 -M;3_M[O_NC/?>1Y4K2^/FOZ>$=ZYY:T%$Y4B(FR0W?B)[U;%UZ'^'Y=XNZZ^% -MT>*#)ZQZ\-.7KB?B?KX\?L7N>[JYEZLX^T<\\QGH^!VH)!=(LHW,,V2[(2!? -MC'KLM'9;'R&=+V8^/S$C'+LS&9>-79O'R./RQ0;+1D>6;QY@W,X^,&,Q(1Q: -M+)YE=%Q>/99TLN+QT6>DR,82CR]F=+W%*A25'1D:7=N8.)8_-E,D>;KG"SI:,L_F\SDRB!>A"4,R>1C"D0I(RZXM'F -M,F4%*42H*7N*DB$&R10R1*0XZ0.@A1N+*4,N6DR>>CCJ'ELQFB]2C./CI&10 -M%&3\W0R*9@Z9%WDK'Q9>^,S+*+*JI15=FBKV4YY=ED"@>74D$QG#4[(W7(4D -MQXT<=Q\BS.<"HD5$,O$YXI%71V<*7S)5%E,F0*9BJP4\FIBHX4HE5;#"#@^9 -MSV3*@Y5;*1XO,2!U4B[Q%LY"0CD4F"9Y>\9@J;F;@V`.$&6R;R&0CXS(R)Q2 -M].!0D(PJX2&2*A!:NS26F$3A2IE5$-63>3D8O+Y@HMDHS,HJ5.CQR8WBJM.V -MC)5?R*9UD<[ECTL69PE8`G-11[,1KB@9P:1RI3+(%$\B4;CF15:71<=&QC*, -M3)N0S&9*#%Z9>.S>/;54\U/M4;"6K>+C\SGFT"D7`_1AG)3)1CX[+LFT)9LR -MU.'1MF4UE0LI]<4W.,)B)08M@EL&RAT=('1XH>@+D6VDC\]F&VHORZ4JZ*M) -M7YXM#.XYE2BKY%N59:W9YF.I0ZYP6*I.6C!4U.6O6)*$E3R]Y&*K/+-K/L,*9HLB1-.)P3,@X+5CLF7LR2%N64$=Y -MK.,CS)$6VAD6]XA-[,@J*66X7*ILA&%+J(U<469*"7;(%IRP"8YEA#`UVQ\?35 -M9REL!93F%%'+"U"W]QH2)89<@XCF4;KU]99 -MO4FXS'Q[=&X6*EDHZ/D'&I;'9Z$<5;S#)2P0V,J02FRT@W7H/F)PR%@&S,W= -MN(S,K<68AQ0MPC-HNCCVO&R>BG"WN>[OI8H+0,M@O,9D]LHF]W>\1<)9[3:U92R3:AHO_0ILQX2J?> -MYMLVZ(^6LZP5GZ4"6E'14GNM*T;G2I%;?%U(MCKO/=1@O^Y=(#S=2R>3+H(91+ZU.^ -MHB"B?2)EG5LG3C50_JH3T^5SNY,P/F$7,;Y^9B@MSUA9KW[PE[)XDU/F"7J? -MSJ%\EXJ@3#X*>G?_'_Z;`?YY3\FG>>'UDNA7ZRIQ`EI?_8G/_C'Z=29_I623 -MG2@QY.GZPBB7?_]OQ#UY/^7I[_^)#E7_\Z.2[+B?ZBGNY.^"?G_WH/M[6NHV -MD45&*-W:KW42W]I-Z).?PRXG^(G7T\-MK;Q8^2RNEJ/1X=GR,F^?CP(3'ZE[ -MZ>^M6.U3SU;QNO2Q7?GOYH/U=66AM=&:#+9#3 -M_';-Y<*]\V&]*H]7Y*S#;O:17V0%9^KMN<9J=W=>;6>+8['S.F_2N1T65DATOG2>:U4C+9?7Y;89# -MTL454M[Y7`O/!AIBZ<>Y\BX(E6'RZUR71$G,,G*CF2S/)=^02*.%ZQIZCK_7-\ -ML:U#&DG[\D>B[$!@%Q!^`*\-]8+D&^8%S#<<%T#<`%@&]\%U#?X!=@WK`NX; -MT@:<&UX+P&U0+R&TH+T&SP+V&S(-/#90%B&QP+X&Q`+Z&P0-0#7P&HAKN#4@ -MUP!?@T(#4PUC!J@:N`OX:K`U4-4`:L&>`:N&<@8`-XM8!6`W\@UD-^X-:#=8 -M&!#?@#6PWU@UP-\P-=#<<&O!N`#7PWO@V`-_@&PAO6!@@WI`V(-KP;&&U0-D -M#:4&RAL\#9@V9!LX;*`V@-C@8,-B`;2&P0,(&O@-J#7<&UAK@#"AH0&V!K&# -M;0U`;B&<@;D&\4L!U>Y3ZL9$2G6B)+KSN`PD3+,/BUR]=$2SW=4=+GK"Q'J-^S -M.J*+]Z7-W:38%BKE`\\?I;YYD_%BU>5J@J=1S3&M:,T4SD*=3!^!$0M\!L5% -M$<:B;N7F%GFF.RA-I6'-.P\Z;K,I3R4ZQ^)=C`*\&2+,KVL]BF;LCOG,`TFQLX><8-H'8V4ZL#FVB8\0ICE4I3H%-/+F]U -M@3J\8XR6@GES*%3`GP].8)MW'9V!04TTPSIQDS[B4Y44R:7XGE_8RAIB7G%\ -MN4>[*3T7YFRE[8S!0^8G',HO-_+R%%VA@2KKSR](KF%_;],4DE#^8N9VB4F>--.2^97S!9_KM6"3$E-P:\W>M9I:-"\B;?H>4 -ML7IWI,%(A5/G&;6ELS/&M@P8">3(\4HKS@OEE915<,F>YL/-B\VE5`\X\;XV -M^&(7"2T!5*SCX5IY6#:`Z%7$8T,&LIS3,M@"GDJSE-W9EKX61?NS$8_ZXB6> -MMDAIL4!\THY*"_USD@HQJ+--%"2NX%_Q4>)@OR5*2V*^.9!4=LK#.Z'BXJ>0 -MU0[F%?+7@6QS6BU*H.E*U<=<'K@=<'T3N-L#"$XP0FC5Q:!E"T/%.,S?9P1? -M@IKH"@=`8Q'[#2?!,UTHDJ%M;',:4S.E?-=@'1RTE2F6OTT69+/%_76DQYAD -MQ7E_V!+AC_*?"];L^2K`V$O,E]6+;U\O6I%4TP5?C$GZ6AN6$.FS#V#T*@+Z -M(,M%30O+FL)E/=J"*ITWJRV.5$=TG9FD(?PX(RNEZ;W#"-EC4I;)`1,I)R`B -M6S@&F:8@6-BA]&7]OTNE%;=+%[Q*.F$LM,I,YI+03JU9I.(,)E6GER<&;J;# -M=%DVL"#/22T.99Y.W'-,M)X!!PDX9';LH,&5DTT3/5W%X="CH)__EJ5$22"^ -MN9O<1RV%R]-&Z"SF&_^-8>46/WVBW-DWTL&<58?D:66=8=;;.7DESE-!/2C/ -MO&K?,'\!(LGO%D;\XQBVP!E6$<8IR4PO+28HY<+WR>V08\T?H52)$@(6HKI. -MS.JM+E-[7D-*?Q]85!.9JU$4XNK!38Y7`A,+O+`` -M!.BH%NV#`EV.>OB`%0$W:&]M92]A;G1E:R]T96UP+V)U:6QD+W5NG(I3D -M`9Y>SLE*@FY3()J9CZ9H]135C#!LX_%%;@$Q]1.>O0"*TG\?)*[*O-]:/!UZ -M]=OCP(J$T?IK7F_MKZI@GT18J&S6T1;4M8'/-+/&G9%NT&'*/0H+V0%N6P]K -M:(K#*"9:50P)X+.9Z5"\@Z/)=DRK:">*-6"5/!SKX$^;`TRG&X!L4CQ%Z,%" -M[&.DWNL(EGRX1*7:V>9UT$/\__W4$2"GQ-EGQ6#GQ2W3X@X:3$L_IT<,?HB( -MF>S*57Y+TB0RI#RV'F@'_)6%\X\P6FCP2D5,7^HLE^NYL/&4>0W.I8HS:'?5 -M`%O.6%'*%=8878XDM=ON1ICENA?6Y)J7JRB;]G0E'+R=1\"G:YE(J=+@=IN) -ME(>:E8KO*X/WJ8DUZ[.KF=G+<+S+'-:)MLO!FIM,J4TET2_M^F:8/- -MQ+2,WA!S[%HC#S90@QZFAF]RG,3/OXZUQ6MF7!67XW[%)%7E5>9%/"A'"B8H')E0%[* -MK=C_*<\YLLZ`Z,=,ZE9,B<,5I*:T1\(/-RA<+M0*H25'IA>C#?U\OO/BYFR& -M3):93#/&FG4M&[)('EH@4HW6G3/_2*:@&Y>3.[TQ^.8-6X4,XYBA4!CZ^-UG -M72=:88I4[CMQ%30R'[VDT'>HS)6QU'J+ -M%J6<\``6Q2SF)2*X4I?M\WXH`V,N/ENXKF%E<([__PZL5DM`5:F=3-/^V*]C -M+9!%URW3M3CCLI+BV<`7%EQ4PFRVC`+"_*2YIW96@_SFW+8T"Q"U^`JHM<#%.M9JLT@T.;?RM;0KD]*MH'4VL_ -M^8J=03WN+&3M![^BY^^W4YHN[*GF!BP,^7-XHL;9/(/()FV%2A99;'3=LW=R -MX?I'G4Q:'3;XF/&[YLPS(-R/7I`%<2AS)]-2>8*ER5Z#9=V^=ZY8("\HJG(L -M12K)%.B]$0J_%J5AU,@M:2Q4BYE$V6>T7HF(RX7Z2"YV=4V3IPS.OYXSB*7[ -MQ4TQ^`VXTHW-6GJ:N[C9V:;E&?7/%4)B9+<.B!S&5?/%Q90 -M1\\2RK;0L?[M0*Y'*@<@3!\\(D,HA?)E[55.7-TXHW#N:^]4&L8JHQ&U -MA829I>\3(&Z'SS:E]]%9-$462;H6<">D<;:U,UA%9%J2OYHK(*8"ZJ/&%;%2 -M<$[<\Y6$]2UU5DM=^^S/WIU\[Y2%[B#.1E)AE%?VRKOY; -MM*)Y9#@R3C5]-G8[QO[:QZ3LS*,^;$`2F]O)\X!LC9U1NQ'TKLD4K1I--KP-F[,C]C],P=,Y.7.(JOP)SM-%2 -MBTHNH0#L.\6E%2S%`+**!+0O=3(LW9<(?0CL`>=DN&?HN9UAJ#(*7SBLXS4- -MW`+]);1%S1\L?+XYB'AD)3LD^DL@HRTG.@(T6DQL[.`$-@0F`[]X1&C;Q%'2E=2*,F$!!*IS\11D -MVN0!YV5WJT::+#:0>DY?"O-RYJY/&D3.#V8'<@\>ON`=Q',\`/)\`C?(Z2V\ -M`<&"(`B80'D8LP@3EH7FZ-L)TF[%IL&2X9P,N9$-)/,49EP:S;$PT -M>2I6JU`D4$V'18=K,B#LD")7)T4_U'=W;'42GCHH1793?@:NH4R$=("50'7% -M$MG'%0$_:N9VDLCI"()P2-O1E>)3(YMFQEI:=GUJ1+;K)W['.\U&W)>0*TK+ -M+*ARN$Z#1#""0V6YCU)GM*>;HFZVMO%:*-%?[]CC^QIG=99)M->L(A7::TT# -M^-"/E\F=1@;K8LNI$SW1Z`>G -M8^AF;-`EW':(V9R?)E;7K8?LJ7YYW(3;KO,L[4833$4]P&6N -MVU,Y$08,`H]2@\WY-*RI1IP'!U93!4E5PE#;A-H;&7OCY -M@.>WZV-=.7`Q`BA50:F4DTU*F+C'J598VI\X8*+F2C/D@;Y+>2L5R3DQLJQW -M@'?SX[%$F8@BYV?'K!YQ!3WRN:12FWK>_HU6U\B*0(R.CT7"CS0P;"HSD&G2KKD\,[FH` -MW)[9PAY2>G1&H:ZJ(.4NH'EV*>GDR7?)MK.+UE`SK:5*.DF8B3"&ARS]['G$ -MY)XK*W^<2Q5[T.`$L]\X.>+!B-%3/9H$C/U;XE9RS&#?TSPY*!/^V[%@RWG. -MI0(:#4RC/3-,;+.(V>F0;L!Q-C!<7?,'&3=9D$O39A;4&5BM,8QZE:\RF2Y: -M'VY7H-9GECO%Z]E!3Z*,Z-'IV+-H4(9O`3<)WWB\[4 -ME-FTE3[50;@(AMN"9]-#<(>:/HPS'3?.N1H:)^`XM7VIA&J4Q,K?E4/*AGZ9 -MUPKW;&N3`D\'%:VAN2:Y^,2$MJLM`]?:%%%C#P#Z5 -M#^@H@T/S)R[I\*9>V3RUE/#-V!+:)T>@*%,WP_8BQ&9HNY7J=^I*1S=W,2BM -MN@GHSE&9]TK("FACIOE0S_RKU-,-9.A1;9KVT;S/UJ,<0+N*#DUM0 -M5B$DQ):#9KF=K+\[4^Z#JN!MSC39LF7\7-EQAT`*1&DY)K@ -MG$XM;JXBW7QTR[QRQS.,R7HM>-D#S1Z3A<,_LNBF*EX2%$6_ -MCLZL::45W&DRGDXV'^WEL3;"^8,FFS*,E4#4:);E-[W48-KHQ$%1I0-&D7B/]Y*5]2;B;S@ZH@2E9.W4QH\\$&:*\T8)_ -MDB.`2N]6D5HN+Y"NWL1NF)ACQ$(G)3V.95XOQEF502C&=A1@+3Z3#.>4>&"I -MV6^(Y:)!W+;*4<1Q6!A=\@;FHV);#E\^"`7@[4T`7EG8*C%,2>`4E:/AG(&. -M4U%DZ(EUKPN"S_PN:I>]'P]J=L=/I)3;Q$6]"#Y]_5FYA>,L=9X#F12?LC2" -MD#C%2Q!KB4],XI5FTEV7?`WXH2UU=;X9`;27)?*5:*IIQMQDS5X&PU"%A-WG -M7-EE"GN60RCAD\J/>G#2_,"(.0+W*>&[*/'86E4,@?][3@*7V_,NVG]%OL4& -M1#*+KMOR[UJN*@Q[&_SZ1#`:7LUMXTO"NR$7/D\:7(7^ZAN.'\&.'N77A5P5 -M&(1;)/:6EH:E;7%Y5U8@G*W#8SR",;17R_66@M[8W -MB_%V"(\ZAO],-Y:W%57RQ/W_&+66X^@_^$MB-?&+K[B'@"KOA!%44B0W&3@U -MJ\7\8X:(55'IV-QJB83M;+BW]=S+_$ -MM_CBAEA\4D=UA(M_'92/C#%5ALF*'R0E2RHHV%H]*[ -MBO^]'IY,>6OI*D_97.1^;VGR5%2"=Z -M(0N'*I!/XV@PG<;5X17AIW$+2*13N2'KP98Z^1%$UJUVX#PLHR[:D=+URF'Q -M1-RTM,+$6X%E7J<"NH$;LA!'I2C$$#G;EXQ'^?.5QPVE3W\C_T,HJ -M3$ZX;64?AL4VHO9^+=PC=.8,16#["`VJMY\F8VTQM>MCR(_14T,0F)J\RD/S -MXDO7F-_(BS,SSC`NL&%J3W"\04/X_$NQW^NF4,XDK0CP+X@H70<,$V%0W)-F.FDC=Y9//*C=0;-3P+:XG -M*<68Y\1LVOCHY6`%T-J4^DP&]`V\897I86G%$%P^>1, -MIS^*%?[N@#N#^3;R&GY\"=]]8D9$3%%&CE-A<6-%YH+?1H^)\:^$X.-I&'G4 -M>1N(1%6X(7TSXQ(^48AWHTESC?&ESO#N,FBV(%8=\-&2HTB\G*?"]*R:8?!% -M2-)=Q"<:V\;%;?=OXVN0BY`YTUR(<`E=ZM\6E:&P1@]4&9JBM0">4]"&/.*I -M`_)'IMR`^)FQ<(1GA)6_%6+@<[P8/\_8VG)*XKS(CP?O$<;Q.QY/&GBI-8N. -M3$RKH,#XKY!G*RQRY_:'#X".6V4,X,8X1:P"6N0\-UCO[?#7]`#6"4IP$[F<1<;AS'+6Q0IT8G0N8MX">_>12?L0^V:#TUC1MQ@Y$8/B+KG/D$U;.""Q<83Y.R/T*2SV/B/MN7F&O -M)X?LEQ-I=M\*;]!-EZ0\PM8*WZ43\V-'P3D8K&U.)6Q(]9R/*TF2YD,7A=:A<S%5U'R;76SP+. -M5/PCTUS>B5/3CPCT+-EC\TW-X,\?T`_9V77I7T%C]+65&EXRH8FHX,O',ZJI -MW.0.:9H+3F"YM1*,6%[',JF)Q[(:C5?1(J+Q+6XP3S,00&2,IM]`V`>1I!90 -M%[U8!<.7:C.+%#]0!-[&+,Q9J0HD64-4"QV+:1M0%"I0PTJQ\[02^3R/A%%3 -MQI4NV/D&\7!;GQ6_Q#X^&^I#7548A?8,XESQCGKF576`$(-C.6K*:\-JL''& -M]4XH+RTH_%C)MZ\WSF>;?K@8!XF#3IXD%\RYY9E>EH6S8QPX.I.H:M#]%&&* -MP"\["K?QV.O;3PO"PZ7=Q2C3$9!M'%F>]BVZI?HFB-HU"I0AX&C9S<265VS! -M-[+>8ED_N`7)BDRSZ(.3RJ-;5+AAWU-'D;=GV*?Z:#DFE:^9438J760W< -M?B2?1I5PG08H1CPK8L3R'Z)]@O:D8O%&R$OH<>64\3/M.S6N]Q%*+&HK[]D# -M46"RCD97L(D7HPP1U;+VNRBQ90+XL2'40-R#N0A4X50;&`YYY;K&5;Q8C+A8 -M3$C>G>,3:&$/($`%74L!BDO-2H\0.#R'>:89U./]--G/++E4,"UJW9<]K*LS -M+Y4K0RXB5G9?!-O44=/WQ2:*P0_I(9C\99?QS$E-.Y7--8H66.R;&28A#@VB -M2M&($EEWW%-['3\:G\=H_>:42)DT@QYWQC7=CW'N_/G#BHKN33/$]I,]7@ -M%\UIY<+MJ0EFI3$@)Y.RQF2S.HGG[1'%?>">P6W0K$;O64ZXP`J"88#%J)+@ -M!#.U&SPT^CCTM>)Z&O# -M?3KQ,QKQJTI<_$#AM!K9)-?0T$FF4+:,9L:?IJ[@&S$*"IJAQOXU$`*5JPRJ -M.P@;87<3>AQ>QIV6K-1ZX3W-<-7Q4D/`X_/KA/*UP;B#6\#+QKFX<<)4:DP^ -M@&LP&WUV$RPXWP:O(>Y#5G#9@:\L<:<-.8>?EQ/:EQJP)/HX\R7$\>7#<`:W -M0;IPPG[,,.&H&M(D;#CM_J)%AZ9AU2^1NV_7*[8\>VB6"0RIPAG%*6S3!%*X -MSV;Z]:["[.IZK;=O7.*177+>94IC$2^/+-H44&ZY\71UVHF3@1)ZHEG#`988 -M^3]ZCHZ;0Z1@0%`^(\DA:@/`IE=]`.B4U#-\(3R6YBM?1%*/%^"B*,9K;MPC -M^>ES\V"6>LR\Y>E.(1X-3"/7Z>1@Y4QP]''^[1T:HEG:DMCEJFM%$]GN)T4>,[=%&)O;?2!9DLG6_6,T>.V3R'!D'E&J^MC"&U=.BGZWYEF&,\Q5TY`W -MA$UHF]69)Y5<:9^<09[AEYC?CE%S=>>1_F"/I>%P/\X(90AB%>M@GB&V:$YP -MVN"3\`=GH@&*/SZVF4]/%DG'@_"*>EA%O!]BZG?H/U5]-Y0*X1U1]YU1KJBW -M5%>J%U4NJEU165811;G>2GG+0U=6D/D+XI;J#RM$5G6!2DZ\;ME4?)BR=%J: -MVA;;UL1DNHT.]QO4_[-B.S,5WPD;7J"NWZ@IN>H(.&D&-Z@Y-9F6A7V^K?%G -M-'U*,$_13RS'C;D%.B,Z0:"KQS$'>(F.5*?<40 -M_2YZ%01MZ.W00S:JEO'DJ6EG));ZJ@/':TZ-KZDCN=+F52;0!#ISY3)9\<\D -MWQ@CYER%VF"I3PO:K*ZZ/I<$*'2\^TS''YIJQ_=)CJ(I9H#2OHQF,P0JKX5P -MUL5PSH(YCAY:J7#G<:Z@RQZ1/QZ(J;5L),KY\Y]5HK+>VSR'=:+H0_N8%MBL -M<,X"WQ6^S@1&->5P/GWX95#=-FG,_D,*PN\1I!6U('17HC;U[\+]$9QIP<3(H?I1L] -M8W-Y4<04[O(U"S#7B1A-J:\\G:Y&I/G%KRPF9QV-(M]V6.9\(['V'Q6YR09HG!D%J.)LW\WI&XXSB$GP##M2% -MA,`+RXQQ0"^S>MB%\YN[EP]`=BF4+Z\1:^Q3NQ$)^SOM#$MU#]@1LXJW4'Q` -MO3D9*>OJ"Z1;%4"'P_N\M;Y+H427Z304#&PI9J6B.6PWI@H_YP-';EZ/)&Z3 -M$>8DS?9P*SV7K(%Q0\IP]KVSXN^7[;AQ/EA^UM**2DGN#419?5$;E+F@%;6Q -MTQ?ZTE,FM_E9-!&&\<3?G@QOW[^*( -MA('4XPAQ/M>D+[IX1E:[*8W]2V'(NR0"RT+,7^F>>U>.0J[#)L:*F2/ -M3I2$LI1:H(F6'NF0#QQ;_2T#)4KTH),7UP23QP][(@SG"BQRE@410SLV89B3D]T9W5'R:'UY%>_6LX+H7Z -M0-Y;#U=,BP6VCIC7!"JQS">"BKP+>[:Q3MQ(\&'OF"K(>QI*<;QR3O`!O;^4 -MF@0W(]_OLQX$IN)A4/O'L;Y"UA&COF6W!F[B+QA%V`1E7SY1_Q6I(TG,K&`, -M'L1A+N-,L'XXGW$`S;D0F9^^K=.]4?^11?N*^.*4[94)%_8W<-KDL]E?5L`, -MV$6OH'SX!$N8#]Q*=2J<2&@@^$2SB6Y2WB722GDH&_!JZ)4N*+B#2S"NG9$0 -M!T_73?AB6Q9S1^95@;*/V\LG/\!5X5LW7U'G79NO1&9H]OM;F#T>9C38$VN+ -ML9A2KP;2?W)_5@\G$C*PTG(ITT3TR1P*"-/?)&4'&UI'X^SPU?/=4;O`IJ'9 -MH8%JN*]NA=GHI9[HSZ(05G$+`7FE/)KS^>_,9.^L&OD@"-Z"XY\W/8B[J=@* -M,_MX`]*?1:[+@O(!AJ$L+RVG/-(NQ>#)Z>*^B&)`(87,SE66>QG%!R93T#ZF -M*$WG73+F%]C\MK`;3$(-5@=>K$":"&'E;1]>RM8I -M#S/`=T:(;I8@5D\HO3ISY`=L=!NMM'1Y55."'GD%X^NV]J%J43/3WH=,+>A+ -M*ZCRWJX?7=F$#&QE19GF^4!+7-SO2VY95W8ZKMT^68A`#W7JL;.7G'PO^>TG -MA)V24S^'1I3SXM9YQ^IM!<[YXCHM>_&Z\`P^U]+7\Q]&)3AW+^#@^]@_X;_2 -MT_+DX@TX=)2R8D:P"6$&8AIC;K)4NELQEPC:R>Y-0GS;QY#;&A3FDXWWC:=$ -M<3A&F(,$V;9D]&B2GT+VY((D-2$W:Z!_`7\`FO3JO8PGX/]4..$KLE"YJ1!\ -M]WM2\$QO:A^/PA^GK>W%,ZR,IH(A%Y4[6)0[:"SR*5?)(FUZP:TTPS]N53`L -M?,M3FHR#4M38QTS!>XLRE.0H!JS*_HE:.Y-R=:NF&'/5B'#CWD<6XQ2V&7N- -M72]J"RSTL/OX&L'2G.F_GP=*IT6S1+;E:V8_AN6"I@*58M:#63SI+92`N5X_ -MC-I%FK`-%QOK^:8?E@')R!ASL:+C(6%T;`A^`[MX%IS$&G.L-*`OU#:U@<8; -M;Q*GC##UP%.\P%Z38)EWZCUK"Y+DV^:MLHL&:8\Y:3MFAE>S38S$EJ9*OC,P -MY*L,Q83Z"WGWDLJ-$.6A?EEJ`ICO@"X*WK"DPOIIXKRYK,+OV*YR3MY3LW&X -MH8QDW1R63A])EV3=:.3?5[#XF.G[$]5-/*1[>%D\,>>*B&<&9+AGF)!D]IR, -MR4SRBY4>/Z>L?%;=!Q68@@(.J#'4%]`%2DPI]4;%"8XKH!LK47Z'-PYI97 -ME:.:Y;#\*^BL<["B]W.%#'M!FE&$,SL# -M?\'[\44`U0,P!I`;ZJ-W88D6M%E`8,F&$+7UC%]'=AZ+6Z,9.X%\:!6MH+-= -MA36L&$FR'#"PPY:D*7%FLSR^,?5)93CHX$U] -MW\[LW@BJ=]JXD_85`HB:44?%(BE[PGQ;P:KBPBL*N-3K4CS-T/O=LQVT_"'[^7"[ -M\2!3S5G"1'3D'"Z.;+Y!?R%2"K=0%2]UB+F;`:9HSC6GK@4$'\5T'"6X:"/* -M[U%\WLD13I.:/.279=R[PL:8P)O.')T+IW2EM.RDN2^*"[73J/2.TY?V*QRC?4P;#]:VC2;ZM\9VX[=" -M>I])1A\IJ3BE^VP)O%(T.?)70942)&)0T-T%%@@4NL@"I;G-$8T:`0<.Q(J: -MBZT@YC.1%BZW(X!?0@5=97-W>TJ->7=&W2I[G7;FHE)(^,*7IX9G9RNF411#@)]P#MW^3Z?4^R -M1\96725?SK1]0:\M-P),;N*$XS_O-D5=D[J7N[=%N[9?,6F'I()!>W[`$]>< -M\>IVY6]Q1W&A:G8+ES:ZYOKD,RJ%<.SC=7(4E4*4B@]T685.D!(W8OWZR,^\ -M+S0G>"_(`,D&F_H;>J)5J)[%YYIT6/W4OI]W]51/5G&6-\<#65*S5 -MQ\:^=+/W4-3\1^8G9IT[(GK.RI[+9S.EO#-66GNTU*^MRBS<\UXN4:?<-Y)8 -M>W'J6_>7(S<`ES+D/`F*@JBWS"I_0>\E-7MOY\)O[D(M29_A`=BKL -MN7'RHB?JZ6Z\>>_/RHDZP+.6[,HTZ?JTWM#:',:<,%@507U&U0%4OE+BHS*] -M!:*XJ)EXW>D3;PL5/]P"41VYUDLN$6:RFW,3TP5=2TXE&@W<;@/"R^0/:8(6 -MM;OHI>[<@$!E>"N1**FGMH10?DW$1=#D:S! -M]1U@TAMWUA-->/Q+@F/90&>:L;;;;9JM]^?#G%.=E.G%T"A0>!JFP4Y0L\(" -M'[P7`@A@EP+SJ137"I=2SY9@]J-NYSA=PN3<`*LR%(H6<@M.#>0M:<4K6H%( -M&EU:^4AB`L0"2TY8%@ -M`3.,R]+\B!/[,1FX7G.2,35%IB[^"0FW@_(@2IA,WTE&?ZBI4Q8YT=VMO;/' -MO:`PF^""@Z8#ZPT=/S_8*BEJ@ZW-;>6OMY_$&XU-!=?;FVU3-GH\@%F@47*S -M]BS,)R86,MR?C[IVBA4/L8+(+ -MZ;:))C)VX!F%\5M<*F7Q$5'/I;(X`PUYD,^_Z$XDB(?)B1SSG^6A?H1TN?+. -MN6*^I`KP3RZOSCK\U#/:"]E+=A_6$J('OB_^7)E]F3F_@WQWZ!]6@Z-$GBS/,+IM1^R(X'R7_L\ -MD_^/F;.M$<;]W-;A!W(_0W98BJK*?,6?DIB,.K^RFD:`J@@E`-2;%='EKVLW -M<4'G,^DU[S9L*4-[/(Y6F8''&@EIE!_^CYT_PEG$\RT1!TH3"T&IV*"<7063 -MDVG,=/[:-");RV8L%R__&[#3'_+-^/S5S:FOC3;D3'([\%BM;QR_!(F3S?D2 -M,WM)Y2Z++V;9!0+AN:)9G)%+"><+N#][E"ZND]R%L180TB7FVP55'4.(<9JD -M[7BBNCQ1L#@75FY)%"OB-(A4S/'L=/,T),&P*TV-FS$0P;D-YN3^QK%N9USB -M:]-'.?"@<+$HET8"+>-WQBL5F>A0-D%[,*I$)I,30.?.>%8"_VPJF!HZ<*IA -M$_/"RL*1YO/&0N4D^D92VIFW8/HA742UI-@#Z05<&V(B_PHJB@6_<*'+Q#F?A%;ABTG*%$ -M>J%%VL9I4AR0@W%=9JAHP?QM8WV2=$@!OB0[A,R^&U(\8#) -MQK`:=HA&>'@@!)@Y:W(7I@[R7'/CX<;5X?'N@KP)3>J8Z;X%U+F?$!DV4<:U -M"]*BM><4=ER;$"=$F5SU]2-J%'`!0G_P!24(GBVN4BDC6TC78711(>-,0=\% -M=@3/$R02:BW$]BUCJX]"UW-?:G&S[.P@F+A$N"%VK2'\=RR>0UJ -M8WETA@Z"*;I1%:X&3%CQ+5]_VEU+)-YWF-[/.M!CJL%/*245OWR;J42EU\HK]?'/ -M\@O>M#7'"N!QY\4X)-FAV-NM:AM@5'^D]=9XG[$7E6A3'!<%VK1BQU&V7B_,M`;A6@94)K6K=">VT6;P)#;&WT0,^IJ6Z+Q'VV8FFX; -M5KA_G!C*8#E%QX-?2LZ?HYW]K.$ZIE&2!DL@2'QJNE*)SH+./(^\B[-JYHW> -MD:S -M!69,WWD5)C)G4:#"@K(1L0>?M(3X-%0'<843=Z51_3JTM])XUL4_6RA6Y+<6 -M,6@0;B%J;&&J(-R"D*2>*;'A3>8_!$[=;(XU$6>R"=M8TKJ%9&P\+,Y,5]WW -MT)$C.)-<"9?TQ;O6(F5-/;;SCG[*)L@UY86_L3;7U>_,$X6RBW>`LBM+*)$7 -M>#\JQ)2MD"PJ5[;3?+/V;LA!B`K-8E:XN-%"8NR4H@_KJTN22)PN@HYC./"X -MT$+7,'(!>Q!-&@SS^1"EA/%C2/[HX^H-<""$Y0*(@AP3`,PE803Z(+:RX'F; -MLQ;OF;K'6:_Q`N5PXQAP)WOE<@B5*;T#7T77M]LBGHAEAF\(HRMG9'&Q9AU: -M65LA/#3"F=3:38TS7U6E\4T*>PK.Q% -M)Z@U:&U15J26QJW3)V037$S?B6Z#@=:U-<WN1.@!:;,K&E0(/.9H4 -M++@V`)W6BWF!10-A"[!UA[>M/JU&!:&""^I8Q&[@V(+?CI8TO7P0I6!5'KH! -MD]S?S)XGO^1##+MHH[TRT9B-7=)-A=K)?(+5P?R/?PK\M7?PV,C7LC_E8R-: -M0CV)G*YQ+.G-:(%/0_)^QBC:VJJ#I;L"*/`ZU'U! -M5S;13OV,G6@L8FT#:MB^##L$KB%<`_ZI6Q+Z4JR%6`_O)55+T$GA+1#A'AYL -M>+H.GT>6*>"QCIBA;9DKUB=NP-0`VIXO=0_\K&9V$*P$?[$JXEP4B$@IP?:I -M,$M,E_5C#1XX8.TK\). -MW!&OXL8O-)/H?DI>%#,YZQD;V`_>L8:6#D)!^(?+I?" -M.FKOHINQUO`MA6E?1)VVXU]@V^07\%C#>V'ZH74#ZI+\$LREQPN,'P:7#2N* -M6[2KHX/@?5CQVXZ5N^"FP'6L^J*]F]BFA':3&M\-O\"_3#ZQ+Y`N2'S"4PEA -M4MR%[0>W)>NE`I;%)W'#OV(-G1XRPZ?%$"FC'7(BVD)7*D[9D:]@;>@+_*'\ -MY+_(6\#XI+=)7E)H2#8!Z^EK4GM+1I=^Q#?K!\8/',CI?;T*1PZ[P6J;2N`) -MVPHUJAMGQ?W0^-2V06Q#W9*72L26<"S8=X2D4OYL0:-#_@.'+#W@>.%'2:AQ -M2^#KJVV-7[C2L*3MP)9M*GI186,#]NQ!L0'^YH]]2 -MXHX;H/!CD9E>&J!00[74:H+$)3J:@"4*%,'0W?OV"*-^GH)6JKO02>TT&`[`'JS0*5 -M;3+1W=+>'(]F"W0DT_^QQM.M_8K-)PZ-(;0%GP_R@P84:"FP'9W<3N[$.OR6 -M(3XH)*%"JT%2E0G0.:K8%X;"1N)2&VA?D"3+\J@7KCMP!K-I6\+T+"2VBL(: -M1L(%P"S%A#>JM`]D#<0KZ)I!)`W(*U`^U(B,NT'$N9%5P4VP19#=`G,/@`;J -M%.6!OXF$L]_#S2WZ>\L*/I[-'EI2S^"^$>K$X$W\"-J?P&*;WY;-@O#/D;YL -M^FO7#F!/J0PG;03;$\ZY_Y)Z4;WZYJ9KZSC@D:=XG6]KVW5!KGP()MWKM^^P -MZ^VX*.5>.-Z_%Y$%2GOD8H/PVXB'7V2GF#=M47!@EX*=4#Q!-_O*GVG`BF+4 -M+S$SE-[_P+-F6X"9*3J[XH)&3Y\DPS%U49?[`]#.Z$UDK"%>DL=81;/#;6@W -ML*%5=%N>D;PA[TYRP4/UP-]"8`^&00EO&N@G1#T^2P!^!8`O+2^&P"V*&V:@ -MFO)A=18"-E1MT:0DQHP<&%A:0D/C]JK@W#W&_?H(1-&E8@*;4L>)X!SD7-9R -M4S%P5,058V"$^@-5X*4;M??W\$KJZ66@E;[#U8(0:Q&I=,7^"::>Y=.FTP*= -MTM:"/YH6*!3NG7PA_71JP4D\!+/$V3N-YJPJ(8;G5Q??F4M"P=+66#_53\ZV -M?>I+=Q()%@I.Y7TQ.7CZKG'W4=U+"3/+AYOWZ`^!"_"PC;F6%7`V?)84IYQ" -M?U!)G:$DM>?.N*C^/T6$43^L-55C.AY`G@D,,312T[&:O7`H9JV]IAD-?R-F -MUGSF%74J&P$T9YTO*6;)!*[!QU#TU]T*##4!I]@AYD)`F\3M"<+"1\^1]Y3A=B/5B3X]Q5K@&JA!*U>'0=I#6DN@*=2W<4P&Y7`[%!#:J+* -MJ.6LR2U43;V%7'=659@_- -M382-4B._V\3E[".LM81/RV%).W[\S9&A*3?FMPG;CM[PUYR5G6.7K,*5QK"` -M[KA&XL"N)7PE@(WKK0/:`IXF.#)+028-I"?U;B9^S1Y^$"7!\B#:@INO@,8M -M/R=LNT*GI$\/WS2%-L$*LP]?P5\C?';1-8':Y#62L`E/$(Y.ODMDU2;=;`.M -M_L`FK#2F(O)1H,;8`UXKZN(_[M>(UW6@=P!3Q)?.)+05ZP-?"9;!,2V,21]C3-T%[(6`1? -M`GBO#3]@[`K@ROYKH$_F!']0HGYZ]3#`OX6KKJ -MN/6.0E,'NR6S_R@X`+%`TF>`0IX/J\D?W`<$%906QK1JO\*$QKI':'#!>"N$ -MT_3EK`E6'>M:C`;O7QUP-?$^Q74L2%[-<;7PO95)N?KHZRM=$X4:Q86&%"#; -M5T-HZX!C`H.N++?]=`BUP5<#GG\:3)'R(,83-;!Q(8[8,@N(JVJT/84AR+3) -M"TS[5J$;RU"395@:V(U`7?K(:Z'2S4A=.LDDF+R#*!?)61?5`ZP+^K9,J>0N5M7!^;2MJXKWGUMNXK3RJVKA#O-K9&>T(R;Z6R1]Q->Y6V -MVH[X3`O[6<;;T:/Q7DF"-PZV']^MMFC>=^!);95M73G_O602M0>?MP7&#%_C -M+:%U\"XYFH_\BD-SFL2A^)/"$9Z!5YH]@#^NE"DZYF_J`]MT>>M)BZ>#TNY* -M5<)3[`8?J@8+P648&7;NF!RQ6.\='4^V(3^[U2Y9>M-GUJ`4@,#??AS4C=*! -M!&4&7[P5IORQ'Z5I7*IXVM*Y;+H.(3R04\ -MIG;"28Y;VM"/A/368*J$D@]@+<`IY2.>K)&RX6L!3@+?>1\^%H04X#'`(S]' -MUI6`-ZS?'"P1Z2UA29-2K#L6-2-5;:U3%Y%C*T).GQ$G;QN-9%NS60U:67"$ -MDJ9L"'@%."Y%$>>"\585RKEL(S]-GGTX+=9(5M0?SUE7*2KZP1HZQ"?@K -M(Z_A61)T^(D[5'QP!+9`&'"VD`&HX(3^E8'7O5@3P:PV^B7<"W&5[^"`:1[T -M`KEP[/`$;W4Z;=`WL)B'VP6U!3RW,[5R-D`M."GEP/J([(+-`Q(7OAGZ-//I -MY:WTB%;4&=>U,K]H*NT;\K")YU,L==2:.GQ$GEF+55R6T585UI>J58HTY" -MFTI@1.@*>8OR))XNX;3#/58##A7@'@:I!"_6K)3;0X@*O-&?N@>?3S'+T0F8 -M53%Q(]5@-$5@5 -MD9^R,`1MLWV'+]`$;1D?DUX3"4R]MAQK;I-,VQI?]JN1JL1\8J98T=I$:N"3 -M3,RTH00B'V;/5R-[JQ_BRA62KD;6+::`"JX),Y@C_HA_-@0M,X`C]T+OU8C6 -MDC/WYU8C56K"_+JX:@JJ4-71.[JXZ_;5Q)T^)7WZJ+1E7#>?54OPK@F:JPZ] -MNK"?BJPO$U6FX4'L556XIKU5)EN@Q;:JJW%RZJD;6541+54C?D_TO"ES-55N -M,^&_K"%C0L=52-Z9)(,!50VG?VZI+ZJL1LF_I>[6Q/!IEEG\C4I527K3^+96 -MK!G-_2O2IEOU5'7%54371HF=_5!X5`@).NJE)T>']6XXRU45:?/U01XJH1K_ -M5!TZM4#6-:0OH"YU4(SR22#AU0-W:F*F7)?5F^+;VZJKL]O=JJL9?IU5P">: -M"TS\I)*VGIUH3/CLY-:S[*U?\KH6B%%'.G>K*[9[C&MLTL_.U56["\I99_Q" -MJ!=$=NVUKL]M).[7H']MU`?I/[7A2TR_JW<'/?U=@.XBT#]\%.[:WA):#A55 -M6[(V;^1O=JJMV#HUL_Z8*=UUDF^R;IJJK=`WTFJ3$>#"!6I:__61,4.S(:\] -M_$IW8W8)0QE^6J)0H1G@%->6^,\^G=8;TDFVK)8QZ6JBMUP>Q>TS[+^KH9^= -MJA&]`\^G=/1A"M8,[556Y:O-4(W;?U;E.RM11H(:L">@_CKVG\3K:HDG^#S3P@NE4U;C3 -M?'`H3.-(^BIJW%NW?EBH\2ID;4OQ+VA_(V5?B-5`<"%@WX-D:N)H:H.M2&OB -M?A*=Q33B6?GTZ-80+M5)5,GON?,A:9]^:^LL?IJ1&[+\1OBJ5+\94/]J5\ZJ -M"J/IHQ'UUD^K/7YK9_&T+6(F=P].!KJE'^3:;_1.ZK1??JBL$*.;`3I`%8EL -MZHWQU=15%<8A:JH3)Q'W0L@-\*"GC(UY*:$*UC>R`IPN^=4R/Y83D-Z.IJPU -M=L2D"%,U,;=`&U!944[CL(],;^Z"G#OMY*<<*/&^F!3B"NQ*;``TWE@:>7-W -MFXZ!"Y$W<:=QX/C/9%]]J:\%/&G[M^6:JV4S-?9&[D'KE3$J4CL'=QM3@_=? -MA=W#^N+)^R787;/R%)XS\/72/PCR@NO4@^:=:8.3\X(>O#X@:4MIWQ^2\Q^` -M7K(4K.I$I2IJX52'CVZD-NK4A,Y4DDX:KP2AO[8_RM+'#%CRT(WRXUGDO+"] -M&HTQ[/ZE6&+J:GH2BI.//?FWBNT74A"<+2[5%>3434E<5G8JBK&VNE25Q5CZ -MUGVDV2I*XF[O5!9!PE'1".3#\)IXJ8:A@<8%OP5#?:@4]ZF]5;/V`''!2@-K -M1>^5,AQX7FAW@&-"PX*=]915$"."NQ'[X.0"L2TC]DA3WM%]:/^8.2"\+ZH' -MG<,?S4O/!R@7X@H%95A[U248A\E1%^\<2D`MR"3/ZGG_-"EQ*E0'V'I&04B" -M27ES$754W[T;?>#FPK<'YH.<"@:1^&"IO%[[2-[K0^<%.O@;U0<^%T029V0. -M@"F%H?JP4]X1W-(\D"3,N1\\#HPLX)I-94'2A8AK2J,UQ8.G"N;X'Z*\13JB -M)NHV\T&4"@98+@$> -MX@ZP+U@29M`*>\:ZIH]@!EPLRM(]8!UP6(#U(%IF[L:39@#L0J\U%23X*@!Z -M`3LQ;>0;31Z39A?O3Q?Z`?1"^@;<$%'L#'>$DL0^D<)V@6G!(9R"E -MYROE_U<2K24`E54JFE47'ZH(^59Z-ZQE0<"[$@P(414&WD*&D3PR=P?&C>=2%/-`UQ\5:W]#X-J!BKFDYYB1NNQ$>P^*ZG/][$ -MC2U/$U<=H0:\M\$IYI;6L26S;$-E6*N:FR+$C5=\2=7PC7ABD9FY)LBR&]C7 -MPC5%;/X$&'"GZ>FR93UZ/@%F2S]DX2G@Y_JIZK:-8^*YA'?T]NJ=S;XKF%MJ -ML%'N+?#M;^:GM>/_:"GJ:^/*L+2]M)NKYY+AL1FN$&$"A:>-/<\BL+'T]7,+ -MU.GJZ<)?Z>1J)[5B]V-BKA8OU>TJNQ2^E[:\.Q>CS^'"^(%:P+?'I,4%Z()$ -M_;=H<6%I'`4NH*>%TC2,]V%-4->]JX7N'>U6;^%Y$ZBGTP\GZ=/$\%[2C`I] -MZ#I^\]["]JX<[\'I/51BO&5![#O:N':^)Z(W6>R-Z;TJT?['LC:=;/\D$FB-C&A3PX-O%0O*K1_\O`EV' -M:P#4B]"4WA2M)YCR&X3RKB6X]Y(VS>B-A'DC2 -MAY_,A7(/G@9$*O`DIO7MKR+=V>2-MFA3Q-';>&E_=>E<3;];P1ME2`"(\W]> -M8`9453(D:'!&AN0"!"""-VC;;BXQL0%)AY)#"D$$!040$Q*@H3$$2$@3`$!P -MBC@,"**VMN`5%L?0-MC:.`3'#')#T%`0)#'#T'UONM\JJW6]U6]\YR8`?/WG -ME]?WP']_C@23"K34* -ME:_PT*1KK7"-"PI&[BN$;AULC15<(VPK;@RW%`QH/ZUM=MD=G\T'XGQ[:NMM -M8D&QQ$4Q)CQMZ)OXNF2M_>)6R-DF#$>F<%>@#W%;2?7B5H*"K@Z^!TP67K:R -M%R]QH0CN+CO=?6TKG[30A-%/U!UL-RC,^9R)#\T(FB_ZXD9BMD.R/ZP!-1Y`J>G]:XE=#=PB8GWQ/1ZP,(^/:T0B5UK>UI -MZU?7@EH0X(]<'-UHC4T*,\.M"/8!^&M!KY60HV%'6\PH75PBR%[/P*T3PQE: -M2O?HJM$;!UI:_UI*^+TU:(W;PJUAA4KW^EK(C;6T]`7U,(UK?S0UEZT&=G]T -M'\0_'/!OO`Y4@7#E?>[&%6KL*UE(6MPL$)MCZZ[*`36UK8;K";P@!-9A"( -MD=KA3QX]F$2L_>C")7B,4DR/[X%9!]8"T`VT/YBV(`M(/7*3!5@K;6`VJP1ZS6TK]_?5HCW!IJ1'L0::@3I#L]Y!\D(IRL -MQ!AOJ.Y45'SPB!![V4(^3`14<68B.3^LKMV!,O2[K*[5E5GZ@`FN!6%[_@=L -MOP-$`37O/0]UF*PNWHKP2V<@TU)/TZP1O\]"K#7W08ZZZ#"=P:S-216"6AZP -MUE,BR5@C>)6"-U#3.O%TK`:VUA-2/;^KD:)560$I?H,-)U=:WD!-72KI/>[%>"6O=834FX:KD:S<\*L#MVPG[ZN% -MA0==5A;-59K*A/Z58C<)Z%]98B7C:U8-J:LFI&XRK*'*>A?6#5"LA5R-=R`F -MKPN":M!'MX$X"[`5/%E*PNU7JQ&\U<(J1&]@EVS-7&W%JR:DGFX(C:OFA6^L -M#K-5@*\58E\3!$M@()-2,OT$1LG!)J/UO@B-Y,$M-02[=C!$:0@B-6E0JZJQ -M&X+I=N$=P\L'6JL^W`\P']@%Z;NKIJ0_PNB-1+A%1UR#I=OV&_K02:C]@71& -MG.8%YD$.OS007"=$OU3HEN?T'351TY9NMDY42Z32+=FO#U:P[E0]7#LZ^N%SB-S3 -M@E?6O7!-G&ALQ3/5N"YT".O&N=)N$7RCM:[Z!T/ -M@-,,-9>ICC@M[K=FZR=2^.'2'<]`Z3IW;&1XX5D':T"8]J4 -M3'J24+OW8%L!P_/%HX>/3"_5NCH.HJ5^Q<]=JXOX0[H#IA%9!Z=;6\\AM[UR -M=?(XP7[M'W)?>&:"&)YX5R!\KG"W%-+OHJ,)(C+YV_0=#O6!?-,(.W1;^O.# -M?2/#0#-8$98'[5M%SED5+S2 -MT/%S(KH>:,HJ(E=RR-MN:.]7YP"XV1#N5OJYBV"6^SECP -MO/#"^[GCK0\\*#YBV%!O?+%M[STW#W:>62VOY]3T'?]\L90OM<'E$;_/+'?, -M,Z*>*-8L'`CI6A&1*7103^EISB-][)9+A@U^)8TISIF/>$ZK10&2]G%3;1RW%ZNQG..@OC@=$S,9J"I.'V;\Y56#*9^F+T -MO-)>F&VM8E'(7H>(N_5(V7T>#7&-M%6[YT$T6YOA\U2FW9.4Q85M.K8,/ -M.O'#/.0S0'_F(.RHW*/,')^B":V8O<*%<.,L>6N41O_I=QW[+FCP\WF!\4B8 -MAEP9GF$Y]5!#-&'IV'V6Y@\*T*7P:2'3R-!9+/G\D!6LF8@S#F:)@XG -ML\AFO<%FTS'.NF6.(#_+1ZQ9G5(<\T`QG!NV$@C[P^*'G>\94-.ZY(H^7/Z[ -M4U6LL'(8ET;!$$5P!.DS&DW;06M(]&DXX?-<<':+?AQP[-A^QIC";8'U^.31 -M9.&(/?T$4M&7:[P41+D)KP]%R%(\:W`,8*%4]^PY+#-P`*X65L^@]6SQ:P1# -M3<9;=+;KC/T@;#D"-V#G^,+_KR`T]2A?AR!YSWב-\#)"A(_3D#/8#OV -MR]'8UP`>J)RG@.$#QN*+WX/\M(%?!Z/EXH?W>*#Q5O6XHM,`W7C#M?B4NXUQ -MP>Z%"+M0.4#81M70^NW059'HUW$#Z;B`\U;.\06ZD'R>*.V1)3/!Q`HVF -M6]5QQMG..UXUFS/'(W#-UJ:I2SEB9OQCV>.];F\<5_8'0;FK*;-V.H#%\`C6 -M#Y#MS7Q13RB-JP*?V;AG^4$/R=P\.;ZP[+EF)R/G2_5CL9UEIG;E"-;"??2X -M\`J@GU<<+@\=:(!SC>1%'ZCCJT;68-O$/9*P`9M -MRX@>`X$2D:M,.VX$]TM:`?ZB];Y`M8QGKS)?[40TG%#?R7';@T`#@4JQR!U[ -M/D!9?C.+)VQS:1_9A%P`M@."#VD#N`;L.']AVMXF.6MP,(+=2,R8'<@TG$#> -M"!;P:#B#>X#M)"@T'#%6*Y_IVVY)CD.9C_XAP>VQ%D($2?S -M"=WR`KFRBLBUOW(J?8/!R_)MLPRB^.LZ-K!G^OD`&G%?)Y!,G&HD?W0IH -MLI#C>/`[%UVM&%*0(IO-$UA9$P=9..3AMN./@S?'&8X'8\8LQ#[W&Z*L4PX9WKY0I:_CNFFLX.D%"1]_%#?)Q4T;__/%4 -M*[7'9[2#D0$7JI_CC)HW9OBD;'+A?5^(^*`M8-O`7I2\9-$EVG%(U"N+:#7N -M*DQ&\V07X\8=31?$.':GK4;,0$H:!_IXB:([Y>(F^B]GQ$F>HCN6X`^:`363 -M`11"R_$4*[R^*FA\O2K/-`$U:P%3$>,`B@AV/$(TD`35:XA&_?8A7,5?V13] -M_XQYJWO@?VX8T8JOHX8;WS=;-R$^YPUVH3L]V!QH"$":Z`C0#E=\3Q'1&X:[ -M8-<7@'MP&,BV>"0,864[,@7I]9C;WP&L\-)FO8>B^@\#A$;1[`+&<6`((]_B -MA=_PUO!!RW";R*/1X0;&<(1X0/C\(-]ST7X&3`)K#&-PQA::Z/0]U($'A@QH -M>\`>(#UW")>S\5-R>]"F(W8KB1!I`":SNO"K<(*3!]VF)8NVQ#-R -MJ^73*%)^!V>5!E@\Z8RF"![\@7U*D&#!M(>^@2P/94SDO-UQ&M:.:P1].N$: -MT4\%=M#K@OPX@Z[GB!7:F6F0?AX+=`/(<$-Y/!$88'%\$-]CT8<&1`)K?')B -M:![Q=[X]AFY2'BX08CNR!C"G_K"/:`)T&K<%P9Z9`7UN>`1KZ!B@=,N":^;6 -MA=P*O^8[AN$,^,#YW`&C!&'X#6M/6%X"A/OA.S^0#>P^U(/)!CR/WX:3WXC'`X%Z":]<@QX-R#ZC@M84#BB/:S&_9$'JR![J'(/1!=`$U -MV!!D@:7?"*3F\_H,VX46W()\]Z4O*^!C4+VV`YKA.A/%X3:P2<>(+X1/<-\6 -M-.$FDAC.$1%9Z,!%'K@R#4^P9@0]H_.D'TGVV^]MJVKTIX5/6->T?"=!OVX0 -M**,*L\(E"A;6:H+*#T3HIXHTBBK^ZF?BUSDN$F_PLFF9]CS@JEZF2/9./`3# -M^8'HY%,'WU,"BC$C"42YL=PF!'\PTCSP`84@\'^Z4])Q2A^W_!),??U1DR^I -M"OP]%Z%+F->(#D^"*P0.$6VO!:Q@_P7!)?P0$44W>$>W+?R$VT>C[N"'^/@@ -MRBV_X`Y2(-K`117L]P"7NZE$'\G`(UH#S.H"CAZ*\*5<:EP>\'/O@?:X":-3 -MLB*!6`FQ1#?R4CA)JT7)IDU>S*43\)1C;8>\M+5$\*`U -M&'""]_A.+!$]95,#*I^16`L2I3]G2_KZP"C.;X:S2?"?:\?I3"W24(6,IG([ -M:5+4\)VQ0G>-4_J*M+M."O;].$FP+LXI3`^U<1@/S\$6RHXTS'P__SC5@-?Y -MX0$(R)Q(\GA#.,X0KWW!&T'9().NC?F,`B%$7H&_+8`:15_U9)NFQ1O;H`HS -M@N#GO*2U=>3M>A/N\$)%"]ZG`);TN$FKU3JE/3YG"(WA\!>TT.I;&MN4X^'6 -MNM,%;V!8T(B)IE<-WN;OZ?.E%TP57IADT[<2*\R"$5@C+DW;[LS>,9&# -MC].R'X*J'-=7%U(Y'YU-4E*O -ME<`*@X`SJN`MK.`P9-%7Q_G?+^C*G.U!"/3!R2V79!"*PQ?R;]$^/=6-B)\J -MG;V8/]J8-X%,*W&"&?%IAMX5,F;.W'!3.:X/2A6R`Q=WL3Z34S+#@^V+'M'C -M"&,;`?(5]C=ITHC,A[VZFJ?:5[LF%KN-6ZK@DY=K3(PX/RN"JG[7QJ.!U_`' -MA4^*,T#YK@N3Y_;P6O)/WSD?CZ,+5<%O2];A!C:/@U$<,OT/]SGD,;'U"H-V -M4'N>"&^/@BO-0X_Q;3C+;RA[]JM/7\0U%`TH&?X7/Z!HZ]W]CIS&,Q4RT1*? -MGP&V'Y[]P1\';\$91/WL/P'[&^/!I\5_?S7)_8D=0R.MH!C2=JZ)^S?!(4A.L)1>.AO5JPZ&8;?IO/?A[U-P -M>_MOE'+5P.Y!TX1(\4[.A2'_`@7U?B!"BQ[Q'N@%Q!\\!>AC=(Q[/+;U=NL> -MBY@]_O2-E\^%5X"93K!.4WH3-L\[TEM]O`VQWB5);:[PC?2H;CW-ZE2??GO% -MVOJ\+K_.\7:Y'9[L#D0]I`0HPFR!>AD/&;9&OF\7;SGH17P[8T]C%";>PWRA -M=O&L?)=3O$W9U=7UU[W=IMI7>;M=KKG@NFWHZ]GO0H[>+(K[>5W;<]'G;L-\ -MN\3;4L]NR-<5(C,>!X0-ZW9&ICL]^!M>[(VV(+^#_8/J`$6TCIB!>G=&C-P( -M/!I1&_ZLVA)40]$@#K0/$WG/Z#V#&*);U=VFP#WU'==T_KT%J3>#;S:41)`X -MT"&$+Q29P(QQ2<[IO`M/2_VQ'YC,H#:3@N(WC%,PO'84H:2WB;`DZ@[I_+G' -M(>#VBKEM0&"!W](D]&/W:;;=U=(MBSL\L#^H?"`>*#\0#?<>UK)!V@/TJ)CX[-U9.Q"0R:"<^5NV3 -MR1.\<5_]XCA,O*!ZQO$TK%F42GX6[38!78$?;[M-*U62/J3L]E!X!TBJ3G]! -M=9C=II%Z(@[OJAGX'H0K/9@@_&D7SR*4;;NE32'_3(/C.`\C!X3-*F?>&.WC -MB?Y;L)%)?MQP?^ND:1QY5*(JX,S2I6$_ZD%JYAG3DK!JJ5-)+!'9^KXPSGP+ -M,#NU$7?P(+.#1$X/E4NY8O8-V&N>['*_;L;=[NPVK.,LY8#FSM/[+J)@)K_= -M"?*6)K(D&,W0)-7_=CZGF['P&BV:W:N5HXB]J>OIJ+J=:W8$&(WE*,F2')&_ -MI041D:.D_A*I=[3XE+CZ5*[*><15NI6G_U"^JE[+QLP]XYNE'M]/YN$@F=A' -M7M(>K/SR":JH<(>'(RC,DE'^C2^JS"3W.=4?WSB\4QLY'*CLA-K-4A&]&EV# -M8$^,&UH\$+!L\1[A2PWCK1@;W!X(5=XHC^/2^**RK6C,!7RD?]C?\)2#WL%\`MGMT&M#>,;<`W.D)X7&D#VJ -MD%?%J3*?0B_PTNZ4SVG7"Z31*]QNDUH.,_X%BM -MT.N3W06@W3BQ^>-N5(CS4/T+7FOW*5/GUUQ8@Y(UZ2SY&#N2 -M8?U[X:Q%5YBX57.'[OA`S%'U.Y2E>K^Y(W-W"4JN21-/;M@$)7]BS& -MPTV5\!"Z=F2(IO#A-Q2@W"4K/[[@BR1_H1?$SH3LK??&9^FX9B$GQ*$U;L2K -M'T>*0OQ,0]E!OD`$)IV`G/!CC@!-R60G]0_N3PMHW>`(J]GL?NFQMX9]=?:@ -M(DCRY$O'L_Z"ZK<#K<4C?,AWN`WX[= -MPAC&;A*9'N;=*.V#(^-VZ9AC[/N"NT"%RZ"?NV[?)-%I)?,;=-J_=>0,>`_V -M=.S]P#!AY$"V@[_;)D[=L06X'5A_?_=-JE?J0-B\TIVQ"]3E2!?7^WH[H''; -M8C?[^T+X?W'7-_N%^&V6[L&V;86S.V3:OT-MB-H5POJ%(^"`0O[<.C>M%+CO -M0=@'RVW3:JV<(.33V^R9K"[CL&X_N&Q7[BO]P<=^XVQ'[I5OH-225)OKKO`" -M)N]L=N1K:-X@!$W]]Q$9GKX")OOVB#4^P>*BN_8%S-N.L*)M#4C\BEUNVW?E -MP?^I_=,T]$*2)N;MTS.?5$?(?6%1P(1.1MPLN2430>EVS>R^^RV[6*/]@VZ9 -MG&6VR;7%JZKEY&V33IXPC[G;!M>`BHV7\B,S^]MTTXMP($9"?D"*;%E(^,`) -MKJ5)%N.^H*5@)@_($_>244QNCHWY$-Z6W33%?-1D;$;I1D:#2(E^'::$Q -M2R)JONR47C*48;)T:9K?L:-)OWDT9&K5&UD`J75?N!HTS8?[[4C6';$;2;5= -MNJVQ&^]5GK0%O!]P`Y;U)49\SMDR3OR4F]_CVQ&^%S.6:O;)42O.VSA1G.!V -M5#W![9=CA,EO[[9*A%;-LF7MYKZZ_1`[91%E\4$KEMAPD=L%A=LWR>=049/# -MN7V'CSJT0#Z]&3E7AQ@Q/`HW$M6[D\=U1C;74:98?5$1G7H1O0@(ED[[:I4@ -M0GSA9FC'7?T85M2-^T`_#M26_+Y@NKVPZQ*2]X>U"1*6O3<'\E8#'N947+1M -M7"-=CVR9(O6[5*3U?VR9'-7VJ9<_8I%SD0(JN*)OI)1)KS&T);`;5,F_[NT3 -M2GI;:D;SE6>$`N`.%#_1M$J+E[($4XV7(%]1Y'B:-*A582!4RE_HTT_<)M"- -M<%POJFV:[=-\H3P=N_$W#:!74'X]F+73:)O4K(;,C7QZ+N#-!^-LVLG=>$1_ -M9`O`/<@+Z^$@O(/:A^NVJ;UU_ELZC4L(NNZ?VHX(G5%<.>4GQJW,+1;4=:;: -MA6=J1,A31#T;ZV&U4?%E![ -M:C3.]_F1[%1IG=O\J4#/5T:9V3(M,[;7URL/DR/R-JH]N.1\Y\076CMV(FW4 -M;B=T^G:ML$!0S[#/E`(\5TD?O!/$@,37($Z)J6LA49C7M^3M1MO0$3F]9#ZC -M+!:8G:@$]^LOK]-H2U"-_3VB;ML]+:$;PA-7':M"=?M'$]?N!+^&-^8`A4\Z -MHC[?_(6SV@Z[7:!2`E$][I=F_%:?<[1,XG]&S(VF(_K*35[`)$3+BI=XC);. -M9VBLKAMCR+;)%N?V;?/I]X2AM\_)ZEE!]/LTWR+S]DFJ(JVS(WH[1K!-6\V1 -M&\C:$;4*L\PI.(_(@5GO+UM$S>WN[))C]K`)KSMD1N_^$*Q0&)+NA-#L@KV# -MV^R;K6KO9*%=\0%\!_GLDU!:C5#L2-BMFU@F+6[$C>*=G\$']@]^` -M\('Y`%3*41VSPP<@`3687'B`S6Q(UL^`++;,==)LPOUV*V!!L>Q%J[L0WJ[% -MK!-SK8D;3*N7]`)$'9;`C2NR:P2QGM@1KZ=GDP?I#W("4!_N`2F`V;6!]\3L -M"-W8!-8#8$;MLJ%%CM=Q/S[`+"`V#8"W+UX;K]BUF2C?O877Y;`-S]@UDE&B -MUY&O)W[,`_<`35P>B9!]H/'`88'RP'&LR+:+E^1-_\2Z&!OGR*'I<][1=6G] -M=^#9.9OSUMDFB2R.R(U)[P67V3>9YSQFW1"=:L^:>>;79.@VJV2NT-KL=DW4 -M'__-DFBBJZDQ]\VR2OV;U,D4NF6<=_C9/MT-L?'V#KKD16?9,W@[V6R&;3L5NKV0K8MB+:XEZ;8M`B -MEV(SP-@M1[$%%%/1[`G!>E&3,((^T']$"?S)-=N#[0XKT]HDRP,ZMC1I%'7> -M"7HTZ2'C_4-P)I#L\VW%B+8VG.[VWTO-+J'9F_RNV^SUUQ -M^AY&\S?+J^/T.;Y/8V3.8^APF:ZRR9O'Z$OT#;R6C-M*K@M&5'!;"Z++>Z?\ -M*Q"8ZK%U#P<4[3<->FHW\3KR-J?<"^#8/LA7+I;< -MZL3AI->'S6O5P%;7->2WO[!-3"X.N(WJ;!-,YK=<2V-UXX4K\U$ROFP4P&3D -M]@QFCN4&;:B983?2#2C)7.2R;J%1(TM.7 -M)Q>@R%S0I>QKQ'0G:,P-\=(G8D:13MX4ESF,K*QOH/?M"Q*#)I&L<0V[7#-K -M&D4_78/X'0@X=4)W6M&>&@IZX-7X&@UCF66KE2_<=<8]>NK#[.K(P6+DW5>@*:YDR6LTNRNK4P"MDLJ&:R#U(U.`_OJ7,M,J -M=OL?5SV?A:>JVM:T&N_#4K;S6+>]J5N7ZX5#K'U.[9);=NL3AP]2'I-2#XZS -MS4BWYZQK0;[JM21OLUA&Y^H(D_*JXVK2]"4S6R,VG^#C/EK4&H0LUM_."K?Y -M,):ZH\%CT_;B+-K&LZ`>:QQ;=E_.V0P-@")'>:P;6L[K[,'>ZMT28@F[L#^P -M.;"1\3K;F9Z5L;N@.T!]((L3&UU;#=3:M-DJ3)`QM'7W6K?`5^^K39(]Q(^D -M!U0':@]H`QYKD^?UF4,]#JU40-K&R5T&J%B_6GO.1;*XY\NJ -M9O(]D8.RIA_\*Q[R8EJ\F*O\-6FZ3L)JB:,_W!]4+W7`^9&#U26KZ14J1W_- -M6UC5'B:I-B"=1JF:G@OT-2M/[W'P-XL3\HV^\/6`$>0@:DFFB2]L"X`^WJ0W -M8"?)&U7$^6-O\!\EJ4K!UMU)&SWJ!8L;?,EJR`L6YY=6FQ*>&S+E:(;R0$*G -MVKU!&\%(!@B;6Q+5.$\M#J$V%+XVH36N\:JY?]`>"#?0FA<\4#Q`;4&L&9R8 -MC(P?_,FT)'?.1CL&40X_7$WE\&K$!^QU";`[U%$1I$/6]0FP1_K:;1$:$!@A/8O@JQ^K:PRE\E$FO>6Q=XE5RXT!%?(ZPB)BNX2B82 -M]U::^?YE"(HLDH,_-U36D8NTH2-(^F,W[TPMMJA?H:H-!`3H/LT(;A*N79T( -MC$`S@1(S]",FF9D>./][73^.U]QW7Y0/;*CI]GI#/R^D%[`VT(>ZG$[S`=S0 -M$;.!^U`QH.;H`WWZIAN_P0>:#\)`J=K*@>>#YU`&K:!GJPG&#;_0?Y:!K2&+ -MN"/]*WFGN#D`-UC%)FD@_P#A0_"]$DDVUB\S)-L6#D`/;!ZL;,"=E0>9IB-Y0F6&TF -M)\4;>P#\X&6!^/3"_T@?&#CP]=$^H-N'D0LF-OV!UH'S@QHVH@/I!_H']Q(8 -MS!-L8)UHVVX/'`^T'.:47Y('^@?BTH:R"=J-J\)YPVKC"FOV>K$?@#=R)J8& -M_N'KYW7^H/::4C?/D!G_.0"X0V[52<[N>E$9H&CTA&ZM6?S.YN+;G2 -M",X#[(1B8W>D&:,QKCHQ&L)I4=/8)0[EUI-$?'J@FX`:X'D:)0F++HTK'6O!UVB<1 -M17T#8@_GH@W<8X9M&."LPV\-40\YHA&T!G0B1WJI%_D=R[4'OP]L(^+(*,&' -M(\CHAG^8&V!KP3*X`[G0DTI\B;>86+\3/$-T7+(UV[^@!XQW+P`94/UQ'],@X(/ -MST*)B\2.TU(O1G=7.!Y<^3C7PH0&4\\/]HVX>I4&3?3XAU!#/OSY&/"A%"@0 -M2'+XP?5*@G+`58&^A+Q]H/E`5=#=:`%9XO+';(4'K9\C>_YP62U(OYJ6KVWP -MG_Z!Z\!TX.;T`;YE7+R=`U\3[_ND1H$[(3T[Y#^LB9P;>N'R9PWU0-O(_;+8 -ML#^@/8AH%8**?TUGLNI#26I&U_U+H35M2Z6LWFA=QJ1?K4M5I;E8I7>L#J0C -M'85SK5[NH7H53HU*;`5\MFKA&553L_:@RP8VE!$QJ7]IK/Y>-"R&H%Y5+5:X -M$.V-$\74+WI35(/ZOG1F]2P:+4NEYTM$&_74NA/^Z(6^I[QIB:E[D$:0^(?/ -MU(SD=2MDM2*WVB&];%/3U+H:D$`C!K2XU9P:^-R-&^8%'T0O_5+5$P$YZ5$_ -M)1+W]RA%O;U+H3Y5"&]+4NA."H1;R2>W):@*TZ@9MFH6MI_9K=@K"T*_H[(9 -M@A%?!KRW8L@BX`YV@)X4F,"IJ`7TJ6K.:@G7E:@+PJ%OHG5=:`EHS4INL\\H -M"-8@.^!ZR@%OZ#J73K27?#K5ZB"I=01<&A5TU;S&GI\Z7"H5UG:$9T="MIV0 -M1WX,T-R7X7L<_H9.JF:![AJ!M&ZA-J?HC4$9YY06!@,3?E""D_8HARG=017EA.+P%K]J%Z^#3DNCOO)"[:!%-W@G7T2]^ -MA0DX?A1#X#DQCUY^ZA'+)T2ZF*(9FZ);$41*SE"/K??@%9\-$Z"^E'47Z@M_ -MF)#=#GVJ)-%X$A;W!Z,0*80:M" -MEF(<8>=]ZB:QLMB4V6K!['QFH3]0>BL"G*1,.QX/:-T>D;T##A?XQ%+??\J( -M\EB.W7K<]CY\*G^TIUJ!<>(8O%/UF2411%Y]6=:*NJW`^]&'?4JJ3L=X@B^7 -M@RA^H&9PV[L@E%%WY$!H%V346,!%")=Z`C?[Q876#T;.@#ZB@![I;H:<=["* -MF\C#MMM_O5,2G;DME].--#S6@$40_LZ=IA?=T+6))J/3$:X"=@/0:SXR3(Z<&]+>GIAW/)Z)Y?'0#-\!N(55: -M-&4H1MZ-"F[]//H2->)X+[:%_:!SYVAJMH5_]RA'6N4(;TZ%^:!]*"03A\]" -M']^A7K]U`3V<+0CX.^H24O%`.5Y.IC5D180;2M::$E;!0?P.K#QH(WM`YC:V -M-`&U=`MBL0%T*`=*X/G'+%4"-&7;W0#,A0+8"@)7$Z=[^-71OSM.E9^Y&G6^^<"[ -M(G6S4%5M)%:]0#KX^G3&U""Q'L3E_15+Z)+QM.`DCWHG@36^TP;-:.?[!#S?#/-[TZLL_?`R'LUN3C\;#LR.4),B+C?U('PBOU!M:V2TP:VC3'PT2_UAB1D?70 -MRG7(5*('S:8/[VF!1(-=DJC!GQ=$>933M9@LY9D-F-U6M]T[I>=OI6<*BL1\ -MJ#96@;D)B!Q?YCOKTPRA++R6D[Y;ZLTZ5:N53#N2L'7'9[V#=0&/@47YDRY$ -M:"'OV0'P5N5I`W/TS627^V>A?5,07X'1`$USI@7U6F'O9;2C.!!G`^HTS6*6 -MK^1\\!(@W`//#;Y!Q?$.YG2!Y/2*[$2MUHR5L'LZ9K)(VCT:@IY#3$;_2K/X -MX'B@^V`;,/+'V.1I1)_;"C-W$WRIQO\KI!F`Z),1C=9# -MDCC8;[!>C_=[-U;H_VI0.++XS=4(]`5K@C)Y$WV)-_E@I65E3Y!+JPG)7**R -M+#J/"]WYR/L'D@J''Z/'5^G7RQ]Z?-DS>/T;X!N>+LEE!XWDQ?3^AV#CY>U5 -M=4MN1I`F0&U\TE*_H6,X9L(J5F<_DCHZRV`S-ZHK -M7A'_M&45)[\`8N?&M[URK9^0/4@&E#Y/&L)Z(+.S=/Z4)3_RZ-\O?14(_5"+ -MPM(U]NL;7VX=GEMG^W'C\BXU%9V"]E^G=6?\[<?\ZC9[M[Y!> -MO9!1K+PC%W/Y%RB^+]=O#+-DH[E:-TS])#[&L/HQ'']JWY.=J-_I\5HP,BP+ -M/;L=G3Y+#GIWU0@?&BNX0(A!5^G](OUWS:"X\$TW'L\&,L&?D%ZT<`M7B_:, -M+TM&WTSAC&\\?9$2N_.,M6?9X6C:SN%[)NME>C[EF<%JG:C:NZ&*^:--XK^9 -MHQ*/%\6C>M9=&$5UW\^`G+Z=N1\?Z2`_T$\QUN)F/M9V*RWJ!9"$_MHQF)!T -MFB2N14KC>'Y"G!OTD+ZV4VB%9^EQGE&\."VG!!:W1-ZKWLB_;1&F*38Z)2DS -MH=$KE@]&Z(EOOT36+RNKT1&^$[/'@NA);/Q*A9"H!&O@IWHU;@?LT(K'X+1* -MK2#0_TX%P!\S0AK,)_V/1KM"'TVA!N:T6+^HM'_*X8"T^)1J&/U'HD!2^#2% -MD7\I\E;``RLD^]/B2E!\A_;A/ICT?O/A]=/JY3:M9+RH"%EIV1[^-L[)A8<> -MB4%/"&L`#F=`+74!"RG\.@3&B^)@]:QZ.3H`^_T"OCKWOR7KX$J#'"2LY?GW -M$RLE=>J(U%)!4FA'G-BF#&L(#I<^+%PQFC*+_[<^I!Z3$_./1613F9]7)Y>` -M)8]Z?8S0CI1JQ:'2NJY-$TA:LKC<*JU^:)T*,HO1&A&>KSZW:,@)"VKH\\][ -MP=?SX>#&D;F\9XE;!1&!B,G'N^SU1T)YF@8^8[Y[`'XF<'KEE1 -M'9^Q!R0"F>KOV.V.P<,T]B+X@.R!O(V]("&!LP1BL\J?GS[#INX% -MQ!]0`F2JTS<)(W:$7.?38QTEGF=6'H_N'R'O#GTV!G:E1IO@V\@"2!ZA5U3H -MV]\!$_U2YT1M/9Y_052(J_B!>7/CKE9\+SL\LB>L]?.DV^_PPLQ`@#7"8Y:9 -M!N(H1<,Y"HGS/[9U=KDF#-<.VS$Z/.A30.PSA+;P;=-H4V$%]6<(T%H1?M-" -MUDC+S575]N>%]/GFLR^7XB9B/11F3@.1%KN5SC#ZKIX#1NR`0(1N=:$:=_A5=59SXO%`9`'%!*_.3Q$\E],^ -MBI%LXY_3[68KO34G^-"&9=?XJ3R4HNEX^D;^ZI/.]N1--F2`14[_8.:(;Q@$ -M3W^"(^&?8%D9]/C8&@)>\`64'\M`+VX"'!]W0!K0-^V`B`9L;=>`BJK7PFW3 -M`10-I#U<;\C0)H7W3DVW9VQX#P\^H"-GH!MJ-`FMPT.?33*G+^2,_H$T.GS` -M$SD8/R/!9EF?G`:%/8">KGQ=NKH*#\2)XP[?>:!-!OJ6FPBMHC7(+_L-`1OH`0HF:5#=0`(H*/1(M[#,U9G%9Y-V*9?0" -MAB!><^YB+S(%T!MF>&E:,SZ40O]8%U!ZH(P3^!\C=_P!=P=]G27,J9^>0X_0 -M)JW>>SJA4>.#C`+T#\26XM]XOH7BP&+>8$]3GPF,"]W[.MY\Z;T#]G'/`SZ; -M@9LF=(WD/]W[8!X8/,S@;$CG*`(JVVF(^*'.3`13A^^0'^$_D?XQ.=T`15I< -M.1,Q,SV@:S.B]9QPD[(`84&SYP7,@1:\\,W+0)IA^GSB(EVSIL0/:@(I1*3- -MI0NZ\;]2`BJ7_US;\2"[9`3YF?3;Z7KD?@/B:FZ.ZYX'"+\H,'3@8L&WA-G3 -MP\Z,_<`BE8ZTB+G?%Z"]S/P!(O*9\+(9Q;R0:+-!VT+ZABG/9,@\P'XLT&Q0 -MG%#MY(GJ5L:#?AROPB_@X,U/;Z`,3FFE$2NQZ&[F`(IXZ^1,H_^O.V8\'B?L -MA-LBZPY'9('6$VK8'I`Y@`Z7*,E:'#'I@Y0`^SKR/ILX_9`GW9UK-$4Q^R9+ -MV\?[O_&!ZX-M#^;GAR]T#V@?Y?LF4>\\G/%@90'<9D37?081_FJ`,S[Y#G\R -MQDR1&F6>1@_5O!OIDJ\?/,?8+F:&&-AG[,]R?)'V#4GZO8SPH9U)X0L6Z^W/ -M'ZVW7POZX]NO=NQ_.MUZNF2L)=J)Q0;DH<_O>;I9#6PG"8*EYMV,#V;YU7G. -MPB]B?A$)NF/Y9?_Q[AC^#;NAU.R*YL[!7*T[.=WB^,]"7[P[=?[<7\\2W8!3 -MA#E/`$\(?V3/WE'3AE__/-],\70L/Y\DO[?C>ENRPK*OQXDN2VX7:6>%UO__ -M0GJ"I_C'#L,W:K#)VIVZA73LF+A*34=EY(8G[W.Z]V< -M$.KI7(PR&Y*J;'#%Z8:R&$9WV4>]!H`QZ+U1]AEYX&-U,RK!VC-=C0YBB_=E$0HGS\CRSO$RQQS*))G"[3$OBDBT5HE#'MF9H -MO[DIPIT3DA.*G/]T;I+"V#*3)3;%B/&Y'K]J9!+M#8:#UJ2)^WL:,F%9[7 -MBS8538DQE;[NCN2W-"0]-S/R7O.YL9=E_#,K8(8 -MB6*B?*+LFQ[%0G.!T5`TK-)&F$CF8*P2V%E$A!PR4%F@>2.S$P66'96/V4'%).9+#)H?8*9A75/ -M.$188JTL/ADP[9E?'R7E*%+US+9WID[E?0@K0[L1?\S3H=P\.S`Y0ZST1!^6!5V\;,!>5]1#A?7=4'DF@XFIU?$H6B_ -MRAY!2D+3*.](6=$P88HITY!;B"SF*+RA^8`M.,[[9@RI_5\9"^%G9L\U/-3C -M%)I8BF^:./(EY7(L.Z:>$'YP,/8BQ?IS$RA@F=JFI#"G1S/.*,P]-I`L-#NX -M9T7\1QWQ%>"P5+FE(*_Q1>P6#/.!IB//^,DX[71]Q -MT8,&#^/091DP"FUPQ8HF`Z49$*)-_.?_?YHJHY#%_"@@KTD$\K&41%-NPK7; -M#HU&4VRQTIZW4B7D]O.X@PN`_&^*8.`P;E``#E``"```$"44\WL#A.8`#==ER(]4(L -M5P(;"X'V``3HJ!;M@P+]F?Z`@!4!-VAO;64O86YT96LO=&5M<"]B=6EL9"]U -M;G)A%K5P(;"X'V``3HJ!;M@P(] -M(D2J@!4!-VAO;64O86YT96LO=&5M<"]B=6EL9"]U;G)AR -ME$,I7L,7KCB]D//65AG,S3PTQU3)DAR09O+RB+DR4O)*7P$J5RX4W*V18[([ -M-RT7S2PCM)EG!EDYU;\*BEZ4I"3T=:)8KA0%L,NRK(F95"@D>0:RH[A<;?=B_ECPU^BO#LC\9(L0Q!CJXL&M/RW>PJO -M*WR?E&6;\LJ5.\KA[PG]RG"0+E'Y?G+*&_>6B^WY2^H%RK7/[E-T<6M#7*CY5$6]]Y3/GYRIU/SE-HNC]8WYRU4OSEQXO:_'P% -MI"GN56Z1?_*Q_?G*=??>7/=_7$:XNIG".['>;)"F]RKE^W7.Z0K:PN;S.X7" -MR$T6M([H]<-,OV'6'"SDL89NL,/9HV;9ZF)[%QO%XNUX+VL3K!["%-/0+_\, -M[+RWUF6_Z)V.(*0,$ZQ)NB%IU\MWK;VSI9GF%($+.*I=DUA73O%%&8JA3-X-D&%`5V1 -M#=J/6N8>3186A['W86KBE_Q3-C\V4]%2Q8^Y9LDUA]0^$&.]+)@R*IGX>3HP -M+2+$$0/UJ5;6`1-SIN8+3^N^YO-PO5NO`Q,8B6+5;^%-7><1(34L<&,0 -M;AR_G?SLL6'(A->Q#E%ZUEBY-#R80:,ACEN%-7EF]+N_RA;YV:FCP>:JK^(4 -M")U!MRQ",`YB+DHC3:#&ELJTH8=ED>G/Y-L#3B!@JOW(S,V8>+=B#,QR#0X6 -MHS?84)Y)7G[BPMX5O+)P#R(+1FF44["Q43YOK\9*PG[B(@B9V;FHF9D?%57^ -M60RQ9I+XI!)L:%OP928+8,18X&$PLM&":,>,5EJA679>RDF8^;$@4X>93'*@ -M[+HC.F58(:.DS)[NT[.)5C8ATQ'DZO7?7>X7-CV+^7%G]'8"DYA<,RYL!W5S*QWEB32@8H^6 -M0`,C_O1I#*:\(TQZIC!,J_KW!0'%1DFE\IB.17(3C@%-1%7.580G. -MB::H/RN!5)2REDY%3/RY;"&+:1!ZXY,&1)4?-X;1M*.EA;7+)<81RO"$Q40* -MS;)%QGBOV2EC*=Q;9K5K#Y+@Z-;-%SNIUH0IAIMBR?UZF2BM+G32.Q39I$=J -M=M>K#:#VF;>DD?-8LS9I:MG@K=),(^VI[P:?1-7G"2V&-!,IAIDK>R`+Y-0O -M'&EQ)C=V.PR;,XE-EHIB^K@@Y)[,C;O9BA9DT&<-3TE@*REL"-+P5MB(AU]/ -MY\_H1OZ0#\_-^M>C,Q[->.2N\((_JL>W\?^[ZZ7N,.K$\ZN+U@!5_^X9_&;, -M"-:U2;9Y[CLG1JO'8U.96_97?:#%D=11W_J58Q)>@\Y$Q^L!%%L80_J%@$)= -MN[D)$J+C*"\051?)LY=-&P86;&9M,`'M.7M'<5%E]60U7+9%A0(DS*2:9V7Q3"CG,8IE1):GS;5"NW?:MK'Y2P)@4TAXU;Y/4\Y5 -MJM,=%GI/6>"GMBWD9&QUFL]HM+'-2U8X9+##65W%F_\452KLA73%%L4:8PC$ -M.LVB:99\.P.VFEJU-B<#L)5:J(9IN21)%(6'.49O_;"SR[-C1/#]A;/DPD0: -MRV#USLLZ?Q$SA#1+,O@J+\K4ERL@$\,-`4X4G9AAQ,6;PSV-.^Z?H9;OYTV> -M1Z\RQOB61OB4.QX!'4CT6R'7CJ6+(.FBV9G8Y&=E2FVZ(B9.&2Q,(LE=B=Z* -M)\M/*58FD)=F[]VN\MW^Q3J5=%9\*6&G1[>4N9H+FC-+N;+"LM.8I`":GIY8 -M]VI'B<-2,3=^EO#:1)E36%5+G_6%6FUBZ!OS^YR./='SL_2Q=42C(:-=D6B] -M)A4DSO23E9?"E_;B[%S.4]HUE;4PP@V6&LD>86D]CNUE0\PI2"5&Q+7X;K#/ -MQU'M.5F6K-X-FH?&N9TM+R4S-#S^AGJ(OY5Q&>'$[>TY2;'>N&ERK5YHIV.R -M&LB4R64.H>WEJ-$2S$_=E:"W)V[PI1`[MBB1L!3=AF`;#*IMM/=RFB!)OJ=3 -M85354>'3"8R";-TEM_RR/PF6R?ZJI4/V3"&IX(,BE$JHJQ)T6&/79GLAS0($!L/[O'UI>"&A0Z:%^_BP:TO":G!X__9,@Q"?PQH[F:Z^BD45SL7! -MPA3;FYW#,+J9:@H50Z,REFA)PTC6!(LFM?__WAV3$(3]`]I_$_BQ;H?W_\.= -M@CD]Q\."7_[]*F7'Z4N/Y9RB'W1!$IP+,R0CQC]QB;.9AVJX5)8:6F6J\Z[.]4%(@CG;9\MH@ -M53`2D4AHFV'TU'@M?]5!;]CC?T(J6^F\,OL3*+2K5(YX/2_!)J:^GT2WCX6' -M@^Y?Q)5B`0Y<&Y%=I_VUB+)KM/!AK#=Z,MF#`(+8M3,#,8H-P4I,%#)KMN*G -M?P9K%%-;D&(-B'3:&E149A%R.!V,/;-8I:3B&,H"PQ<1^6R/=V9;NI::+=BQ -M>?*LTH[!OQ_T7T!W8F+V[L1L-MHZW4M,8"5.\8!:QX:RNX9#0?(OA23*;50V -M30[,>C-E2BM2]600H2DV:\OC78?,"RXEJ8.$ZP;]`&OH,L$31L4QS -M?_SZ`#@C"SI[6/,\`9APLW@K(XN= -MYG()+L]]9-3_U5QY4PYPU0!)FZ67L:)UM/5O+8P@2SC$F*+C(9L?:I3_MIG5 -MN$ZA`9_W&)!+P\([(?`Y?]^B.\?PA-/*,=5)@"7>?H?QD#)$8,QJ7_C6#'U_ -M=7W?L.LA.3B^BY[EMB58J&!$+QFG(?Q):B5?'U:*FOF& -MAF[\9]%O>J9F39:1'G=;LV+!(\I3%J0^"4ZBX%/Q\59XZ.A73"I_/3C1/?7& -M]6ZZ7;NV+LO]*3-+-W*&=+J0D6/X[_L3;W@+HO0?]M4!G@OLDQ+B0.5= -MGB$7JK$R2(M6NTQ^8%6055!3B@,8]/V?>:?DE3E5!3CR?M6_MZQRX'BY.![> -M"KP&`5DGH@%5#/\L,4`#!4%C4*1XZ6/WX-.P2_QA_!!IN071\A%T'^T70?C7 -M0?J70?K+_6395:,Z0D0NPVI^JQT^JDJNI_V?>=*V7"H5WLG>J2]I4"]0@079 -M]#*",J=9Q-4@$_TC(""%^52X14NIFIJ9D:I'BCBQ.#Z6?6) -M-/\]'R,7H26@#+7-'4J?HE2%XAD)B,74:M'+69:%*)G;'B6+"DW.)Q?Q*UU` -M3KL*D#0J729,9&+P7^*8Q>4?%Y*LL!?^IAO2'O3MIX=VQV2C/8Q5\X\!^8;C -M3+/,I)OW1HM'+69:%21, -MT+PY<;T-B.>,D0\;$.\2-SQ)"J,<93AJ6#.Q@U&-@M&*`(DJL:#,Q@>,6C!: -M,6C%HQ9/="H(NJ4=+1HB5>!GBS9E)IX'>+/'!`>+/%GBSQ:-1^\`T(['2B<$ -M,ZT]#-:-Z-NW#;.%X\PA*RY3M+2V3^I=&&DMU$M*%?_TJ7%[Z-H^ -M;WT8*487^&XB7N$M-0$P&3JP`2468?2B=',@F[U5!3Z0*J@)])JS,B3>ZJ`D -MG![\KZ)5G.>-JJ=J=CB">E8'M'2TI'@"5+\DD&/:-D*FW%"0)E#@W)%3GU`E -MR_5*5":IV3>8AV%=&T!3-HN%3X1#^`[4==.KA#@H=%`I^2GR!M/^WC,]LJQ, -MRD:RB -M09K+9QXD%,B]Q'A%&)7(L[\1!3[R?LC9@%*O,VD*#T-=ZP+I)HKW -M0KJ+>-R)C8@N+C6A3C8&;E^NHF\:)8=]@=XV`C<9OPS$;D=%#$;(E_(J,$1K -MW%W[VKUAU&N#PC@2K_314I$V.IX_-1/I]K>;`.5?E1)(*`Y;!3$R;4-U6!V) -M,[E#FS1$\7T_A/6:`*[-3'T3=`.7EK34F0G9R9AVA]:LPBSN)8]G@5"35(!/ -MLV8P&%7!@(@C?E66K"Q=*XS?Q$XD,$O@MV%JZ5S&NB;I";@4.3<1))@/#SL@ -M5YRLL4/V\"'92NMJOQL=TB):?I5)C"SPX2/T'/$I6@6]VEE0%"X2NAS&\EIM -MBD-?HY6Q+U5'7`/R"2UI>+1VH$=^0RAG+HKXQ#Z`P6W))LPI@^CO-`$="2G7 -M=5IJ,JU#@MBKY;'44*"O>H(:/9^0B`EF_83?D9#8N6[#$RJ"O]++X)%E1A), -M:=`9LGO`&8&1-4[U)G%Z-="1VA.B5#O`F,$&^DBISZ?I/,>GM'^3IB4PTMAE",>"7BI^4B=#R -M);_9;BM&#C&((^Z?I`JD`GZ2[9O45A6P>BQ:-'&-I\45/`1/"-$QHX-P_CAQ -MCFA>7ZO?=7\(X2A63>TM$7:7C>`[,.-F@*4*J`*G!DLPE15NZ5JI+.H"&9M" -M@\/<0\.EN-289!2)DIKM?JUBJP"<5715THJM3%07*#\A-RA0D:H'X9T^,):J -MY%V9L.*HC^)T)]72M#2QJ,VU9'/_Z=ZI3MLN,.-M9=51`$`%RIAX52MF-U5`_/2R`*H!)]K!-3QIC!^< -MOY/VVQE^].(5GZ+35&(F,'GT9.$GU:/Q$DIA6EC7<\=I?F%;&*0MFL,H`1JB -M(CI9K`S/:0L]BF4G%*RRH!'N'`&3WLU(94%(ZF2"4J=+=G@55K?X\6QN_6X^ -MX"!0W$RK7>T+]Q5^7+:U5>Z?$-R73XRJB.TQGJ_;<6WRLXJJ9MM$?MCEX<1* -M*F0Y8VPMM=#^%FG#1P$2X`@\W-2^LL3*](2(,ZS6*:;*,3\'YI#0WTF1%N-) -MHCOEW;#Y6"+5S9Z<9R1(QVN)KGI`%.%)A5TNFT'-!^XTI9>+P8NX^+LY^@Y? -M1Y;]>1_Z>$MX*L=K]G@?^'!3:AAU#11O3R+=EQO\SU$P>RZNV=Q -M95N%H*XTB4=RI[$N=Y:;.73W\W(Z-JH0\:*L=L`-3_`!I^&>C0\:*1KIK5HE -M@QSA!$8.%/"=&"L93I4_P`:)QC`\8*&R`>+C_Z+Z/F$%T8/FJ\M3-(OF:RRI -M5#D/RG:H9`*J34A].)@EL%'Y6#W=WCPB@%SN9;ES++1MJLD,Z99G56K -M!>TU8/O/X"N(\56N,^*E`)@A)5R7]MUU,TM^*%D:Q/S,LB4L824F#J1K]+CN -M?"P=I*4Y_V8GZ,2LEDQQ9_UTHJPPABI?M9#2&G,;+ESN(PC,+%W6352P":'H -M,/D6?]/X)G9JB`#.4E3!$80//^NKA,/A.C;_)PE3!4.9D\6(I7%WSJG/`ZJ+ -ML.2<]T@D2^!R2=(PS.Y,S8:=P2$_#`JGG=29EY.%J**AP((>'..(<9AUJEX6 -M154!0`=.D3\R[-`B7'\$N/NEQ^;=+QX1Z!]#.C])?Y?@1W2M`2?2OQR4"L=0 -M%?;==[F$G/,WT$8-,70AGQ=8OA%Q(Q,A-L.B61Y*5.'YX29`Z*XS+R!1P6!3 -MBS`03.S9KIR*PRD\QJ^P<"HNGICR'F8*%`B6,P'D&?`8&8]V(MHA6]YD5%%4)HV3+^1=HAG58AN^ZM-*% -MTL@SA3X2,)4K'TN@TSZJF@@T-,H1,B34U1?7^>CI._E50&D;EV)=X9U&?P9D -M3.&'"9PP^!GU4O2WYD/ZFEN]@Q=6BTE0?20Q'2!O>50LKR8@W?%R"XAG6/NG -MA79U787K(4IFK3TOH("8/D=MK#B[-)U`<_/%=]^Y=*&IZG*5%./)O!S#2ZGG_H&S,5+'#]+F8Z(+I139BY:8Z.C)9\4P+@Y^7_ -M1,B90Y15RI"<*+S/;#,^`U\++2.@:QI.*SDG -M!Z;DD_@)P1%>8-"`%T]Z5`^B>UT:6%_!O"W2TX!KQZN3Z+<_^7/CIT,U(%FIH*?N#G -M:<%%/`RI6$L5.$TNE>DKT?=%,TI<<'$D^YNM$7`M+-G[I9RYE/HLG=5T/_2T -M4K_,:66E`D8XTL\JMI9T7Q44XU,@8!W@\IH;I?SI1_L-%N2A'68XT -MG&0W\I1V`*&)V8+E2HKJ,0;I@C3/5DESNAGN:)IA[J,^C);,V(*J)R;%,JQTQ(!J*A':N$9U.98G/]FA*3 -M9^"]!X;/`(EVD2G=L,GJ4YI_'.1S)J=+"_HGO34&&`R;'YJEH,G@1!30\ -MJ-K!F`DQR())=KO9BYL -MT@X3PPW._'=LPE#JH/,ALSU1[(0%:E$MV5F4@JJF7!D\FDI3`M'LP:#ZZG#:T(L`<\BV$%0P]`3&V<&SR* -M_G(BZXM$@U#Y':E&=PBRRU/L<+1(,@HFDSGK_9HL&15B)0POZ9N;B)(JS-=H -MD607`(9D1SM+0S23B*DK!4LS+Y%_:?5O9[60]`S0DAZ)-R+,G4L -MS).$F*R:\R8]$F.<7%2%3YE!IZ.\M3UJ69JE-BI!H*N)YE1A:>SEF5ER%97_ -M.HJ,2(#,WSA)GW?19D1TD1RBZJSP#B]-WA(D1<@T"2;1;_,]%CG%R-.&9O$# -M,/%C46-XL=(L-*JPHO&#?HQ&9%1DC!J,?1,C(".T8OUC548(8:<56E5NE* -MO$4:<7$X)CI,YS?F+3*SC68':&C%XMPP&=YU3X9J:&)GI*J@9V/S__FX]@8N -MX^S%L6DN-!)WI''A=/X]A_$055/'ND79[/%QL8,L]1&BK0/:*/!`^V:3&.28 -MJACC*G4"E&:4?NN]%.:-`0'"Y8N1THS",SVH+IGL:S$73 -MNC:%`HOAP%D]Z,L^*AI'4R5C:Y0&I)V[;``@4(B95&P85$ -M8UD-)L='MJ\:Y?YHV&7DT0S_&SEY_3XQN#//C*J,[3&8:61.=QZ+>9::F -MQRTY@Y)\S:,6V.7AQ&4J<#EC-F,#D?[^%FG#9P$2X`BLW-R^LIA!TO.Y<6Q\ZSXOP/"+B -MV9&>^.E34XM3*5.+'PU+\Z\0]32WC4:APM!=/%K0@K_8Y&$=(QKGTL5)_*GC -M9`!V/_T<:P8AI_X^2J9CX#`%7_17]_I00D'_U2Q\F\*@S(QQO)YSU/NT1ARQQ@XQHR7:">:M[5QVFK&^)/=?KB]ZZJI$M0HVORG$.S.8M4\P -M6+/@9ACND$)%,]B:=QI\SV(4H'TSB9B4/KQ2V!9[_T88I%L#\BE5C-W(U'9F -MI29_I22D"X'R/K`?.F)@C$DB[%S:D#%_G4`?RFL5@*35B8 -MF")9#*#R?S+PJ=Y`RO&Q9O`4LSI1C26'\7QPA\#48*1@F,6C`U.AE -M4<\6OI4Z\8"EF=*,=0!F(?3&1DDV#4D)DEGI>^^T.4F*28F367TH^CBM4$$F -ML20K@B`HU4(C6@]&M!^AA=?=&=#H;5G\;=9/NT).I/B.^:]&D,+'#W&SM7Y? -MPP!58"F1@^[9VD6F]%-;/=(EU"JKY,Y4SRVB<'_`;W><0\LD+=2M+$[AWW91X-)Z -M:!*-5,.V"74?4CBG!8=2!F#;SCQ -M#+MQ"7>:<+LW>5V4>=V:>B&-U&.K&6319)M&'!67AR3,\&G@FF,BDXKHV4!M -MMY?,^$DY-'B*>3&&>F5*T2[#7+C$V?R_:QW38PC(M"MPLDR462N_%G_&Z$8]%?8!48"+D#U -M0"OS(%)AB/MZ?%3RP9<*'C*\:=V-XX<+(6*WE_4FR/I23BF'R6(OHA^1:D,E -M/E59_383,(FWAP(KNL_394@(G.S3DF)F6-IS#&'/50:\9`TF,,PP_G1)O&H! -M+]$#"7%Y<:9NR0XY,+MXH)*N]FH!CKO*8&2"GC<$GD&=&@QB209#Y_(Z*X8T -M?)#YODBFHP$5(*GY,551):0P3^%_2DGCF4FU)_L`)Q`(&Z&X:J5)1@Y`L[G( -MEW5R(G(,H>O#R:$1PZ/`E49$"_A[[_%"TLD%I!3_D7GY`'@>H)$'Z/'1-"!K -M:O4]P=8D58)57L>-NLY3F=LFW8Y -M5LY(QMUFHTCNZ4;LDJV*8"$9,$P -M53]R.!]<[B9<4EAFB@:?K/MW?&M&&#+)6EIQ7;4PS*9[D]FP:F`C/D^[.TIC -MTDC>V<8[EY4"#61$S`L`=JAX'W+WRK^IIE*5;;VYFGT=W/@14;U,85XC]Q+9 -M`MX,IZ7C./&F6-M&?>+8.699&\8[P%3J1%Y=WV)=XXBY?SD;1=)$:-;A5XW> -M;]\;`?CH@`:B9-7KE:EQ,E_HF>DW1/D0]4P8S-/W+!&,:^A5.GVIIH7! -MWOINKS5'3WK948^O<4>N5>'Z!M=54)?C2O<ZK64GMEJKOQMM7M[Z-Y#`2.`P-VO^EH_/^'UY[PO^/WW7?[S;XO8S_J_I]'9>UW4_J\]\=%M-IQH_ -M=%%7ZLMXESL=JS4G9H79WKXLKNMIW-BM5SVO6_?]O-_>AR=-1T=C==##SF_B -M=+_:K5YUEBRL?S@J:8D.67^I!8K05&4O+2X7_\_G=`WZYYNTS,7LY:\,.(W^ -M.VGARN&8!'?G-*`V'!C_'_10>YQ7[ -MQRLW+YG0Y'%XO)YIG(5Z\=US>85EY7.)@P#+Z*U?R^5R&)` -M]K=8[$E\3+\S?Z_N'N/1@JQ6>-.?QR>.A_Y`*Z"/Z3XOPBNL&/@B_^=1*NO^ -MH_I%(-_2_`@X6J-*XMU>K_GU:WUVLU;A]-6H0_]8,/'$0GQ\[H?TJRK?5_Y5 -M8[B(,H<#_(3%E("+!,/XF?T$5SY1CWA2K>TD(V0C'DC2"N@$\T1&_,,<45X( -MGKC#B$^&[QWPG]!%M^H8DUZX`3LB1YJ\3`K+">:(U"T!,CKBQ,^1]9,?,VB1EA-K -M>Q6?N'A?Q'I_>,,)\SF!C<"NU$]<68NO_Y$QO6[QNA-K,WV+]!CGDKRA-_ -M$0?ZC';MQ19A/CDAW^PQ-BLP)R@B;7\?T$:!;+KU^T3LA%^S8Q)-X1X@R[$< -MU;WLZ,?UK(>Y8VKU?IJRF!7=8&/6T2UK%;.)MKV/LT8Q@!7PA.!$<#24X0N, -M)%NTH\,J(_NM]9*_,T<7-+Q#4`QWI*]T)HR1WRUO%/)3)E+_6E>PU.O#M['N -M$\;:(S*W,%>.)P(CVJ&G`C&",\O!.V5$4A(WQ*T@G-"/OHH')EHR1DM1`T)2 -M_2I=#:HF,0W;\.)=B)[5C'P"N4$VT1RM9`YX7`DC$ZTSP2N4$XP1R5LJW"/< -M$Y4\(UXQ]Q*_2)S0BM[`8RPK[XFC$9)>(T4F5(\5H8^`D.VR*.M$NR#9#&+% -M9T3;1',V@QXC<<>")P)(M-&,805E1.,$>;MAC'5@4QM8"RHC?;D8^->OP/67 -MB:W0QX/$ORF=SQ/%V(WZU[%;N)MHB&I*<>,"([TGCC!$X/'*B/=' -MCFA&@'C1B."/$O]%%W5TI/!V(MRT!C1;21Y6[&/J>U^43@1'3;P8N1*V\3C! -M$:MF17,""1GP& -MX19A.:$4?&&/U;BC\1GJWH)'D:(\_F#&AK(IG3T?[^QW+7!B(JW -M/Z$57G%(CLZ\@8F03<#.FS5\8GVXRYP3)KQL^H&.Y;M\>)\T1T/Y#`"(6=U6 -M4`E55$(C9F!)>*[WM=JNUBO!57E+R`7867=F=`3`F%2W`,LR*!8"F%"[`04% -M,,'%`45(Q0LU=W1 -M@5\\\^^^/4\]]FI]]K7VO?P"BJ[OG-\W@YS?-\P]P5?;ZO\0W_PG^P[WOO.\ -MLZ4(&M5=V_GS1^=\LU$=X#.\$STH`[>SR_M`SR@/;RH#36:>/1AF]$\1DO@T -MP#,.X#N7X#WF3X:H]^Z5#+48G73`"[V:>>Y1F!\"4`VVA -M`I$\.B`?T#7^(-"1]^!W-(`X[@"VZ!_/9.Z,3_>&BOHV*A_"!ZFT\3D -M52M_``9FU".0OJ[8&Q`^[3AX>>!J:@/ -M#X0/45(>#\FY_UU0^%L`R=P#PPH'&7$!GU@TSBP7E@/Y;H`K6=>B#.O$_5$V -MEFJ#_E#-B)[2[@/#'7P`SSQ-%>0$K9Y?)!GP@9F]`+0]#28>MU[W\@`E\%$U -M%F3^_B>H6#6X&+YW"@*.S.-YX&RN@./T//`+J&MP#*X#K*P!F+-4KRH9K!/N -M8P!?K+-/H[%XGXS)=8T!AW@Z5;P+]03=\F`_D^#3V'P7P0/TYL!DWX:=&_"X -MH!R/:`*`=9P,X(&M[82]#5[8K_)`,IL./O+Q;) -MY^)^JS-S[@,Z`3_GO`$S9J7Y0,KA/Q_C`=U9FQ^Y#-8)S?@@/XAKZX9XP&HV -M0#G[-0_S@9Z@G(>,`Q=G7_[P=!.O_-R0_PY,!/^/$_/%U\4,N#)\?:`/6L\O -M],,Z`#FML`\P=?(#*X#*[@!>[--_=PS6";EY`#N+-2_VP9XPGQ?+`>;%U\L, -M]0#B]V`_R&OR!G!`U7H`*&SH_:`R'"`7']L38V:M__X#+A%/D?O`8JS,?]"& -M=`)X7\@&/D0TQ4B%UP&\?'R-A_6";E_CD;7_C";I\P#<6=7_T!GJ"?5^H!ZX -MZ^H&<$#^#A\CH?APP%QXO)*?XI\]3B\6?8#2;8'!/['@#?#K[8=!/9/@'-V: -M=_`AFL$_ID@%6&N$#/&`_WE@#FS._^*P&"?3G@$Y9:W]8'3@B?1B6L-,B$OS -MADR@#VQ.2!8`!^!6_P9?L5B]I[L',2U=>O@8-1J'42Z:5WS4&]Y@ODB'4%ZM -M7,E'B)>)(Q&&0^2<^I7B*<.3]"UYS4<:1ZCT7'F_&S_,I'%9U--[_D8=UKL7PNYR?H_IZ -M;ZM+I/>TG::+UO`A4_Z>_T_IWGV=_^ZJX63U,EPO:M.KM]XI.MJ]K_*M]K8Y -MZAQ?5UWSZS&\+OKVZVFTS_H=IUGN8OPO\^!A7N'["T9VLJI#PWV$W?O8]+# -M]NMD.)J=!<+UV',6CO)JEVN9W6[ARF\\;)[[M^E^K/Y^1VE#0_S^*JFN]O?( -M9W_`41FW.SJYC^M#[3AP?^5^I;W+1]#O@GA_'$][?T%@1/,NWIVW@0"\L>;] -MU/Q5/4MG&ZT8B4;.S!\8)#_Q)&+1O_IN'H\*G]7A3>_1ZFO>X4S[_"F/@X4O -M\/"E?[<*4_OPH7R<*3^3AR/`X'!_QPW_S<-CZN&ZX?#<\7AJJDXO4:?BY[K>+7=AQ+S6TXM_VKB][EQS'DN+S]?^4)/%/R^6S_UE\D@7B63\ -M?]>2>21/9QC_IOX?F+B_\CT23#_=XJH8S^AJ\SR.)R?XO:":P.]]]T)WH=\>%>+Q_\HE] -MG5#/S57VR/YJ^WV[3UJYKG,/:YZZ4]53U#BV-^35XP#M?0A(/']YBVA^55"[ -MGB`G\LV'EZ%U"VO*N(_6H/EG;T%^U^P)L%P\LA?@O1>F$\61#RT&$"ZC>A/W -MN'`>.OPP6OO@DGR=/_,Y\+EO="=*/G]/W@O2?U#TJ?%A?Q;\/2Z/'A=9[X>E -MVN1"_U?`'I>;E`NG^(/2XF6"_P_V#TJKI@MS\8>E6UX7F?D#TNWZ<+]CY0]+ -MT.I"T>+KF(S_)JE^^ZL+V_S!)X?/-Z@+]KZ0GACY^9UH7U_""2JH>7#[$+[K -MB!+0]#RH.S"]RPTA&HY.G_B]L%X!_%E&Z#RW?X@OI6JK%U'S]O7A?>2X3,6\V(7UMO"9-^'EPMF%_)>@FT=AY4_Y;% -M#^:"?3R:B_"[8+[WG@EN%]UEQG\8OG_/UPOJLR$Y_DU%_S^ -MT%^GG0F+Y-.?.^X%V[I_L2?\[[H7Z6@"?G9\[#WPO4]2$];DY?_O_8+Q^C"> -M9%\^8X`72=6$O?)J7\/\P76Z8)W')FG^'P@M7K`GFQ?.&HHV/^?UX3_(^>V= -M#?DZL)0\G6_^CT;WW9!-CR9U>Q(#>K_"$Q7)JE_=PAOX>["8_DUS/PDP-X7Q -MF?2[&<&ZW]'V&O?N9\;U.U";CDTY\_2!>`W(3UP\\U2A<[Y/V%F_]-.-[[]7 -MV%O^#;QMN_T3[`^7/W0+;P`&^B^?F7AFV\`QS?)F#X=\"V\!A5\G'Z:_A;>! -M(<\FLO^9P3-MX&"<<.!\<1S86W@>+6/X9-5KSB_&%.[$OS>#\#D&`X5+P%$) -M=6T,='%*W4(@9YZ?+Y%;MY(P)^0RJ"0L7[:?E:!WH63(N'*Z1XO?.@72CK[P -MEV>89,%$EY=H;IAWUPIA?^+7QZZ1=CG!2KO(1'+O5-2RK3"+R2B!EWJ`+R^, -ME3"KH-D]]YI)Y9ICQ3N-88P]OZ1&61MJZO`O>Y2%1HD`B_/>K!W1"C?9A^!PSIH>Z!^7Y4CD%`"5C_*Y'/@*MN-Q<#LFT!GVF7L -MV?R_SN:(2Q")FA&/<0=Q6-1>*<18^.;M3.R+0@5]Y7803B][:!+O09E&4:FA -MLE"7S.(RO/?23&S#4JP+2ET=.T%>WV+!6EM'*Q\F1VJ,E;\T5M<$*?UQ`4H4 -M:`^-VFHKRR"_K9A*%;]X![>+%4#^NF0>]0D5A.Z%+2Y;M0*[&< -M3$_$@5\2;!OD([^EJ6RZ"3Y,_$=L8-1$P"#$Y1MKW`TC6O\GXH+(01.'DO-! -M0'X'+0K8@3-=W4U"14XZIVN\+@F%Y-G".WOT8(IYX)HHP^+]8- -MQ.,G]^*O_(O'C$^JV+O'T2&!>/Y2Z`U4U?%4UK7J%=O2K9YG2(NQ,VZI[3L2 -M*P(U1>U$#2"YLI]GMQ@=\A1GA<$FO;S(;AP@Y]V@#F()S.2[SG42.]P.Q`S; -MS3HB;Y`[<#//.Y7B7UXXP7E'AWP![TDLA0<^6PA=9 -MY9M8"+4#AF-/K;!OT2`7Z>.WU.G;7Z`F,7\S#.H0O_,TI@6J:JSDT'R3'\0> -MP]RI^V5C$@J)??-`)(1-AY1&+2%S2!(O,\Z`W0'+O, -M.P!NH.>>:2`!NP.U/,FJ!NX,IS)`3>`8A1$3>0=[>;-!`O8/`O*M<#?`=61- -M<@>9!UCSH5@-^E<`8ACWDH*P$/"F!E'G>(D>!2FN:>8%$3@HKKGG:OP.#?'2 -M=GWF?97-R=P`]4\H4*%SA##)TCP[Z_(89CGC(^E>5R)'SLAT9@:EYVX+$0/5 -M$ZIYV`K%2V7.)UI'0YD,7,9^*;!YL4*?C$H=W[PDJ$XUX<[^S>?S0!CGNH`^ -M.\^\RL>E&]R\]H5T;&B.1^4X7[,R=(NY@Z0Y+RUF3309,OV8_.V+XNCW1$(J -M1(1=JG@H6ZF!)]:_1M92)L'T3.+MC?8A<(#SIP#E$"OOS]I*X2]^,I0.Y*8> -M2ZR#XB3(;`<#0E/I)=:F!@7"6/;ZX)TACTG,OT)X]U@GW5T%=S[*(O\T$#-3 -M*(*`;3,G:$B\#\J(>=!P_G*:-?`J2Z(AS(.D&^TG[RDJ[,R"I>@0T=(N) -MEVD>?H6)B8N#'\42OSC1*8N3Q+@^\H56YI`(3(=_,!FD"J&:OH=M3PWH279] -MRFWIK-.)E-H]HISF)F7=U!P4[ZI47S,RDZSM65-DS-(J5$N=V-89FT2J).PQ -M-714N&AWE"8[-7:#[B4!^F@BXI^$[Q8#C)&K2@?TH4'*/4&N10=LLKW\2B. -MBW,2&ABMA`GF6DT%5ROKQ"XNXFLZV5"XH]FL\VK&C!9^$=:=^23YJ:MZ]]>@ -M:YB)<72=O$H,%X=7@Z8B\[DZ:OSHZ0)_'9NN`85T=%$[U9SC="Z.@.=)"Q.5 -M:6_UG@'-.M,"T"-OIW2$T<)/O/O6F69HKEI-43S7/8E85=N:I&FF,P" -MWDTB)I0;"+>B:J(C]YWR$MT+Q"U2+A?NCGCZA=!=7-[%-X&1-L.>8G)U?UD* -MAX(&"'[.$>N`!(8^)ZTVQ.)V437.V$(L7NB4OSR^[6SDTQ=R8H> -M8DUGG*1?\R)4\YMR!IY'RT6J6M-*9RI!ZEY+$UM.7!^=:75)>OX1\VN][)54 -M$F806YNT*3*(B8]=`$Z$H#RGA3\4!XMZ-T3AAZ`N*PU-<<#N@O+@M@!]L*H? -MC=`?J0YO*%O?O*A/27`\,*OP7MG('BA6!B45O>`2_C<-A0LW*ZCP;JXET>@7 -MP7T$3\SX#`"ZRQ(BH&12[0$8\+70A$H-Y2)Z*"W*J(LJ1&:"D.F=83.E&*XL -M@0OS:#9;R-VE?BNJ"J3+YS)@+@%]5]`5@H+A$-,A-2%J"NZ`J>=;`:9,Y@I:C%.=L_AZE) -M4:\QQ6EV:%L\6`HA"_=V[A/\J(+>(EW!-C4UO>I$D5EEM7L<73>A()@);Z'0 -M*PQ=$C&+^-`A8U$P;EX$HD8SW\L!T@BEC$,9295D?F@.FB/X^+I.D0%`";8B -M+,FU64!#";D!TSX'0A/*`>&$N,3=$0:!&-R]$A$N.)5/'@,7Z* -M]5C*(N0G2GZ($$YG61ZQ".Z0GFT*1#._)%"_,-!3:QA'VP!YM`H=/>\@L)G.\_%M/>CI>:8UM -MQY(>I?H"B"_:/SM%'=.FV'NK)U]49%`A+IF=\?1T4D;4N`@/-0HC('J+M7*0 -MY0)5T56($V[D+S)<+SY5`A!3.7U^.IDL2OYQ,S'58ZB+]IX2FY?M -M,;>V4!U9S_>4(]YV"L`'@(4ORW[52#6,C\B$K\P;UH#''.9^L;[C'$MNP01- -M>2,*;-F7<,V\D!SSY,=#:4C%TV[=)#G@E8A9M@_D+N%576JH1)\1S\-LFN`O -MX@79228ZD0`R,H5GRA7:6](17PGR)G,(W*="&8*3`XAZD2FFF)M%29PLHV_0 -M^@WI#=WHD'ER0V1NM$2%\(V2-8(\O9!-19%904>W911T^S6>2RQ -MVKYVB-*=_/&4HH[9\QXB1#=$&7.SPX"`$]$I#S)S=ZU\AJID>MGDV'/H286L -M2"%K -M5P(;"X'V``3HJ!;M@P(](D2J@!4!-VAO;64O86YT96LO=&5M<"]B=6EL9"]U -M;G)AM_S>`T=L>UF3U(95SP!J/\HNSTC5?K -M0E-]`?Q[\)^&-0![HK"L)CI5IO:F\!\D.DDTUEJC+9+,"K>FM-@:+@*`;^^> -MYAFJTJXC2C",>XI<.=.4@^0X7PG?!.S5"^]AB2'4B4-`#DEIVVCJ*W+UR(&T -MH0,1Z,2X4246DHH\%(IL]QHT,,280H"PV\3HBF]LVX[PBDE(C2AD)2@S4[@"BG/A/1ZH3+AO0K6[A*`<1Z%:S<`*KN -MCLA?@(TP6S+31J+>@%5R(R7T"9^R1?FH`&Y!*OO(FXL9#^8#3>#+)$I=-+^! -M0<;J$*OL2(9#+"+N]8O#M)1HH1NB[X]@]BW2?C#>:>R\286`K`ADS*A9"33( -M.42WV0=J;(=-VRXN[3[I+,,LP+P+3_@C&>`D4_&(.='%=V,V09V,3\876!/Q -MA=6EE,@[D*-J5)S\%XPEL7'T0O9/&VM1']#JDX]I5^'L(F-C4H_W$T0/IGC< -MQ=)6E8_YMXU-U6'.00+T:HOQ()Y!P`G0$8/:!+9^J2Y":3LH:8"=0%$47<5 -M4#5D#66#)I$/1#/7L`VN` -MSISJQ_L&2W&E&WS(7^V)4!K%`U<`SS`6X">AK@VTX9N0NU!J(&K8&*(N%N>8;-5E%84N5,-1^TJ -M[P*N$:J%-V@;(2G&G332K$':6INZ:K&5,0KC+3'3?_ET+R6K"=X&=58E,A*B -M'4@Z<;^4Z3?F=23=PAAP8KI!HC'XB'6PSQM5$\0,X,0A*CC$-ED';AG01/Y! -M>!""!J]T7/&P'_-U&Q#M+V)UDM:T!.A9"4^SJ0=,-HN0OX1Z5 -MC]ES34?5TUY>`Z-MN;7P!=TGW5DJT>/&1/(V]ZVO6EB47[39B_6Z?-W1HJMA -MW@32-)KG.QB;"--3!G@LA*>LU!I!THWH5Q=X&TIJR,%&IQMD5=,$_?V$37!F -M;L3&0E0#J0=L&T3,YNQIQ2O)!T+-VZY`K^$N'7MJ/&G]FI\+(2EVJK_4-&0H -M"@34@TPA%8'`.@KY]"T9F1:0GQZ%-_FYUT[04&1L^I153YYT%6'4461-UYS[ -MI%Y\9&MZ@ZP?0.@K6=0G`WVR?"J8JL>!4B432"@I<1<6\ZP)^4,NU`%D)#W -M*`'N('N('LXB*!IXASX_S&2&IB?3&8KWHX0E/CV*`IA["+R.2S`O"I>4V&BH -ML:=JA_1>-D-*$'WJX5Y6BM^*;/5+$2F_]UY`+.)ZY&7G-)30_?B?"&=+0A9" -M5"/8H"VCV\E>2#.W4%SMFFP])>)^Y<.M:"V@3V]1$OH9^FQ08A*UV:JX0=O& -MTH(R+^S1%/RP7BA.T"L(&5-$%D)6>M@08Y%?Y%QNHKD`SVA:=D0@1!VH)@2O -MJIO3>T:./;Z>)]09[,3M(^G;M(G:!UPS],!A&YS*)#1W;6,WQSFZT+W6BM^^ -M;/519:=N[#6Y&\P[`9][3Q\]]NHPLA*VCJ0=S'7L8TS8C@'8=:<8_TX;;"Q* -M9"5(.I!U`ZZB+KJ`[L@>F'-V/HAF[TW&*+_@,T44B`?C/1ZN)X4:Z[9"TA;\;[\*9`UWD2`W6"UNB -M0=(`0M`\T31U@1!&I*`^])`[?@U$N3*;I'PN\M**6D=HD,@N_M2&-?'T5%B% -M$P$()N4,[2(7XR:\=S#I;[`VT,C0XNC7>A"S1@K].@R<1R+QC:]YR-/ -M;^L<(2M+.I!U(W?3J&\5R-TV"9E%&NHW^#F:^5HQ^_U0;4UJ"R$J$=2#MHZ\ -M`.X@6$Z[1Q,=&L=_*'(HF&9W_4Q"@*$9W@A)E\P((UL3!!**)JCMIZ -MD1[3EJ>/=7M-Q-\!RUABLH>?$>"Y;NWK(TATQ502Y9^),.@O,TL0A* -MXM7+%IMXH"]#."%6]N9K?LC\ZP-*""/;T32"W$+P*=&LN3EK/$=5HZ+3H,ES -ML=KY=!"=-LV:,V[NK1N1I%F20 -MLQ0$!.*MO=)D"!NSEVFJ[]\H[W%`-W;H9U)0%Q=@YL)U^C<4OWT*EP5D34>G -M7A,A&<#U%,WG?1"5+&Q",5E`709XPA$PPC!LPDWJ*W,(#Q80E6HD7@S_*S=% -MM%\Z,#JM!"J+FW:0Y0)6%G0"GSK-YY:>?6?0LU2WA:3.(!>!"?':I!:_:TH% -MHKH^Z^?M'"$J.S8O(@[>-I3YD7]O`%U&<0%AFHZ]I4QD8T9LPKT@Q"6?N#7T -MPLL6]TZ%9V[2/>#G(]P//VP;(2L[FL@[B-$?T`\U&L*_%.SQ\%HHW0-\X&$) -M6=RR0=3%ZD#?1RO.X@Z49P\U$N\9@.\VT+(2H!K,A"@*@:S)32U+*YEFA55$ -MY\)89FBTB"'IUF]';9&I!:@,SU)6F0OOK-Z/9F2#J@3>CUB$&+4K-W'-DU0) -MZ$\_,DI-W.U'RXSBYF)Q!SNQPA*D&;IJOL4!VM+R)J,=G1-.M)# -MF=R*`VU$V8@M$$MRS]MTZ061BJ:;KRU'1LBH61AI3J;='D65,-&QBF+QSWS# -MH4Z#5(TB#75-N`#??@8K&K!*^/0A7*A*]O0EBKI!T8Z/PLE/06X$8+'T7X -MCM8H,98,HXJ;8C##*J8C*M*I#C5?=>5]/J,TB,E&U:J,WDJU`;5P'O:$8(&H -M02T/G4EQD79J`V:+&+^BK?&C<"B@7S[%:TSS_L5?1"W8[+>!FI?G[*=T2*]7DVD)>1F'-69'(B(C& -M[%RHSR`;2T8*NW_P;D7865VA"4"IYX[(&K5@?Q3]#P/QQF6ZJWIF;JXQL,^9I`518GLN=4)P%S:S0@ -M0D^"+Z$[_1GGB//*MMLVVL3T^%\EPU_/R"!*;0!%-1G$`VUMG+,"KFWKW.403N&I#]HQMX2!,-$DCOE"P0]C/*E! -MI&,'EJ1!@DE7S29Y$FET;+TM^/4$=&<*<5PY_8>W2[\ZH7OM)?TF/B><.9NX -M-LH$)3[.I!TPZ?`2'6I4>A!3HZ"+:U&LP1>1U(/FANEQJ#9[32'\+'1,P&>9 -M$(2L^=4D&.)T+92ZQKBE_!`AZ+13UH5D0R[7$+(2M`ZD':AOMEQ=4$Q]-ICN -M>_I*1L(RO&$8#&M&?GHS@3L+BUN#R4P(I,!7,6*A;<%7-1TK)MOQZTW%>;(?E\6$^.Q0 -M*?N3=P5S8VWH9$46L;:20H"[LW<$HG7!=AHG%R]A":U@CW,4$N09T5R;G6K( -MZBJL#'%S]$[4RK4=;EN7T`9L+%(ZN.9Z(.W1;JCW8QN1'_S\2$X(9_0"TH)1 -MTI&6-F70.M3V)W_VE$*8F/;\H[G&()1TL/:V!IV`*7`9#$!-<&5T01+MO<$2 -M\@J-$7%-%\QT2S31/-CEVP7`OMT^(V/^S8Z%2-P[9;+$KW5&6(=G+(C2M":% -M&6'=H\:"*PF+@TURXJG+?#V]+(A([DM-F)\?^*>'FG(=7,1S$\R&PB+\Q![2(O>X'31%[Y`ZF -M(N&B]_26AB^#@;(,7YR2]-P%KUH -M66V*LX_!.K:7['IRVV4ZIQ;!\,JNZECSE@IV&CNY/$BHMW`A^^)&.PT=Q'>#? -M;(,=AH[B.\,Q\:P6[YTAMR-N\1`_0&.\5+/G(6[Q!CL-'?1L3;D$YB,.YB_&2(`IW308,1TQ_)9'NB(>FW6A%T4IHA=X<7! -MZU^C:=.0.P?`I("D;M@7"`EXB8CM$"_+ADEYUD&^GMND4[OV4\ZV*WXIYUT6 -M"GH4;F?/G_B39WET19<,DO9J91!/Q3T(_!/9U,.7[*;''B1D$(_ORX71?:\D -MF1(V4^"/P3[821UW7XI]WS0F*?!'X)]X8N1%/@J1!/YU60A+H4]#4+*?S[4$ -M_%0*)+?(J`$?@H`1_0`8`21+A;J#IE(9S5R(J#^1L`5!_,,DJ$GMBE(I'O:U -M.XDSQHMJ@X11O0A/>,>+U0+QGT_>A4=RL>K*$?V>0/7UV'3&GLCR_3AWCG@Y -MN)G-M@Z-&V*@E[D\3(7HI>YI`D7HI>Z"Y=Z*7NHN>> -MBE[L+M3T4O=Q=0]%+W@7='HI>\B[V]%+WL7@7HI>^"ZMZ*7YD76/12]^E3S$ -M_'O12^`AY5DY1Z*7"GH)<*>@E\&^R41[$7"GH)<*>@E\,QF50+T$OSLAHQ.I -M>BE\0A_YJGHI?%2Q;[+ZUZ*7Q@>R0]/T8V]`H@F!3ZB2WR*?!&`3X(P"?!U?@3FK%OP*0!3\"*DLJ*SZGT_ -MN"::-=W:4Y%)ZU$;H(*!D[^9"U2`\2H7*1%E=O&\:+2ZCF5*%.\;XN2`S#5X!ZI`$RBNZP\P`J=E[@R\.*GH5M`R;S6 -M@I]ZB7PG"*Y4LI&QPS\NTL1!TVP4+5!%+TZ=N0%NJEC] -M:K5V0=!HZN3SK@QUG1SLEF<@@G -MNO)`$2-E/;`8*>A(()[WS0F*>A(()Z$DP3T*DP3X#((O,"#E)LI\!1!013^B -M2WR*?U310%/PD$$_"28*`!.:N3%0`*0!4`"*2K?6-WFS=.(78GK_&4@].)>+ -M=4G?!6'LT0N744<[V/QMTI=T15]`3_N!/Z1GD-)4#LV%Y9Q+]&@U^2IG/8:%-PO&'(1,%S!\-P> -M3#1\%DR.AA89`[Y3M$65Y2(/,`O+"O;ZF9RL4>8\":T`77MID/PG?Z&:FO:: -M+C7/@B9R)9$W\L@A1RR-HH^G"OW!A1W^'E$DN;/0D"6;7?YA4J0O'`Y4U*^9 -MY4)#]`I;X@5,!9ESB/NN2?-SH40*&^D$Z;%+*$PH;QDO?\\:,O<;D/K+ETW` -M4^^I=$_\71=W;WVT.I+"1EG_66,Q*-//ZT=>N;TZP:Z]T-$ADOJ$%SI2(#5D -M7X<:SWW\7,N[WX1),S#4ZVY('I`+X)NNI:3?YPOZ'$YKP5W1N:H2\1$VB-D$CBH0XFX@=.G"H[GU=SUM'E#(A(^O4.\(\N6C -M8IUIQGQ7H9Z(5'="LIZW#RAM0D?7J'U'#\,DX02.Z-;?VJ!Y0Y^$#9V'U%(` -M9U`5'=*NMK5#RADPC.P^HK!#/W!4=TZ^ZRX#RAN`C.P^HM(!EJAA([J6%T-R -M'E"%#!L[#ZCF1#.D"H[JV-170>4-D$9V'U%Y(,_4%1W6LK@74>4%Y0&SL/J. -MI,,F90)'=>SO(NX\H8H(SL/J.X09F0J.^A:78WD>4/%",[#^:$#8AAFZ"H[Z -M-K8R]#R@ZE0;.RG<'Q(&7K^MBX6EI4)'?2KVJO@\H5H*G4H?G";14+OQR(N& -M;J@*Z"3S1`5*48$8^%FD2>J>:M(58XA\X@.@4^]9'&U:XC$N4.54$TGD4-*X -MM(U2^",D\L73&5HCY015H=&4DJ&;(*COIXU<+Z/*'6@IM2/KU1^#7JY/2(&) -MV+6!Q]>I/*T^V(C; -M1((VV15N(4:@HF:D#XMBXD_ -M@%1WULZ>X(>4-T"G5(NPG-5!8(%*$%T*BD\X61X/-6GH4=&Y/B$#WFCA;-!$ -MHVQOQR#/GVY2"U=7>X7CHCK6V%@87=`J4*JX?Z@5_)`T_7W=O1XY"9#*F7"1 -MWU^:7P@\H3DN#CZ]0E+A;^P=-0%1WV.!?\V/*&;"1=A.&!_LF@SUPJ.^SM$M -MAAY/@(]G[EM6RVY+]:'$T/A,EXML]^G-*)+T40LX%>C$DYF8`SJD78G*6A![ -M>;#+M,!([[7%R/.CR?):$W"U(IT+5>K#Q$[DFUH"U-=#^#R02UM;U-0B^F@J -ME*V%CW$.G0'.*1&W&U^<1NB(&8.,F&M7>D[-T1.3HVGP3@9WC3GZ.^W[7#Y\ -M>4-],,N/KU#NEQ)[-H#/H"H[[GG]7T(\H7:9!Q=AWIP?G3H9BYD)'?=\23Q` -M\HTR?4,K:SP9^]IQC'?>\:[XH?V>0=;4^2 -M.2>Y#KW(+M7H&]R1M\N9PW*N&DLDVYAVP>V"UZ=.V,=5+&@"W0:.KD\ -M[8,=7-(`QU=!8QU=18QU=A8QU=Q8QU>!8QU>18QU>Q8QU?!8QUS(L8ZOTKV8 -M8ZP$/\,1T&CJ(ZP;[J0QT&CJ(ZPS&O#'7.R'AQ'6(@=9$=8J6VD1UBYCRXCK -M&)0X8ZQKSM`QUCGOD1'0:.NC8\X.CMW,<`+=!G8@^`"[DM]4QTU`=/RQ-RJV -M-^R.G>.`/LA;'60?E!Z`+8ZU,"+8ZYK;L>H/L#^;)M*P.;6"GDU,VEE,]66\ -MG4P\`Z.<>SW>Z^#5A<6A8T+>]\T)L]66-"QL6*\D7VP6*\D;?T26^6>K+&A8 -MTYM,T!HY!.W=05)+'6?=EUMERK$0!`G#B==8YN^[[$]N2QYD`LD\1#O%O -M;O[6;G>.B%\U10O.PG1_,2WT]$^8]F%PT1W[6NH1N4AYM`,@$RSB4Z1E0$?0 -MTB0PK1!O"H67W)&E;\T)3*$8+-HX52@1D8 -MQTO<)>;/Z"GL4#E`=9"?!)")CX7[4#\PI!NHO`PN"$EXE7#Z)D3,8O>.1OZ- -M`3P)MC/PI^T:[]+=T;_[<$J,RU,>XE^L03>"IO<(I9_L>7+E4-F#^L7_!H_9 -M3E0LP?U)"X+?T*.F<\B69!$S[=@5=8T\,Q[Z8V=1`E]/;IC^Z0ZD)J@%2#N[ -M7T\/DMV*R3]=,?WXC]LR"A!-B`A"JV1JTS#R4XD*:"5'9Z.:*=+ -M--3P>-HVNF5G14`92382._`K3FLID]$B);OHF4;QNW.T(9F -MFG$T=^#5=/T0\H?DFV7'UZA.:LG$]^?FWRB#/::<8QWX56\#HQY0 -MW8*;4CZ]47?#`ZFC#.8G`D=^'46'R0\H4TX!NJE"S7ZEANU)Y-R7>,XHA6A` -MW/J-N%HWT&2AG]60)]OZ1RN+TAREA:0,T05'?B6+C,F/*'G`IM2/KU")/R$1 -M-H:P5=9)G][A+1#:Y6;V34/JMO([.;M(9_-IR%'?BVQ694>4)ZT,N/KU#^3" -M`[S:@R]V@)'?C6U/]*/*%4EQC%V';-@6^9VI./I\+A'R(NNJF,S(=KQ:PSK& -MG)T=^/?/`RP\H:$%-J1]>I3N$[C5S5*&>4TX6COR+@5S(\H09T'%VXWZ4*8W$TXI%V^PY%]]5BXQZ\*CORK9[G-CRAU`*;4B[# -M+1%TG8D\';GU*WJ0M+D[Z;8&>P%1WY=\;FN'E#=@IQ2/KU?;,T-NRG,:-GM] -M%M#)>>"1WYF+]GG1Y0Z&>!Q=A_5NBBW5V?17/GIPRO&H[\W-JW/CRADP4VI% -MVBE'WV&WEN#-FTX6COSL=N&@9_RCP4OEX][6S5HD`Z)NWWZZ@,?3X2.[`2MX -MZ@>4,)/@X^O4.=]4Q*]IPM'=A'R@T3/^4<:;Y><4CWM;-3L$.E"#[6J#/T!4 -M=V)]*GJAY0X82/KU<;O&'/@]1;PR@H`D=V-Z]_U8\H0Z!#B:+M'\F/>V!YVX -M!G2M.)(_LCP:8>4,8"G5(NPD_P?_GV^MU1=;]*!OK=3FJD3`:Y$#'^3NM"UR -M'Y95$#+F[+)]\@PT3]J,Q\(G/='&YR#Y4P7@39Z-'6_#2*;?NU`I.5':BXAG -MF-.FH[LLE^1J&?\H^.F\@1[VMFK0'6]`\[<@R6H0D=V;P\AUH\H*4(./KU?\ -M'EA;GKF&9EIR%'=G];%]>/*&)!3BD7:+^3&`\G=`SS6G&,=VCV)[L1Y0>T0& -M;4B["?(-R70-_6TWQ$!4(562?Z`5$QU+3E$^P*Y1M.4\">5.4@,@+\UPYCE+ -MK&S'E#^X*;4B[?;>4-N@\P+OBX+)7@,O- -M&$CNVC,QVH\H9^C!L[(_+>N-].A"[#UUCM.P87:($.G887B?,4@E`6@8ET]@Q"% -M.(#T(,MT:^X0%U#%J3':0`X!=2Q=(KU0#\`+1(J["._(G4X+1NVNQZ"GZH4H -M-L$8AFR7C!O0EJ"Y8)=`N`XE`2=N1$9E%V3S]Y#/SM/1([MR]^IK1Y0[NC9< -M?7J4[C),JQX&:+L:E(WE>G7:(MD>WF865L7JWGD#T@%X$]$!TH%^$]3,N#\5 -M(24.<`NR3_@T.@R_-.38[N#N4GIO[2P]+>XGQS!D1D.Z1Q%3`4:A/*=2]3$:7E) -MBC4&>]R_:\S,(+;U<.JLN:LW"/@'X%@-(!(H@A(EL%K:*F@C)Q\Q(63CJPV1 -M+UK(E#EI.EY6RH`:MH60U7C+6Q"4LLS;P-GJBA;"(E]/F3K<<"_CYSX%F6*] -M3%X-)8*#H@O2%D'!4B%M%R2LB-EG7L(P$2R%/FLT-N*7:3:4*P(<2KE0E:95 -MD/I\[99@R>L -MRUFFAGX%DH_(*@(W+[-73D5:$1=8^L_]HJGV>J -M0N$%BFW%,:D3[151XVJ!`LM1F"%R`*1XUN"2CEQLJWR;3,@_V..)V\CY@GL1 -M]9E=?AB62P9*1\ULK_T+X?[0QNN'ZDK9G14 -M!NNQ:PY=UOA/W'.RU[+)K#D/E]R"6%_JVXXPO_>.,L^S5SO]LZWO^O%^_^V?= -M_^HM[I/]&4G?ZYN/7)\13_];INW_LRN__J'(*?^RZG:X5UE$' -M#EQW9AXRZ!IF)E&N&AO]H][@_]*J\7Z"DB]%W>=R)OU02/"?'$T/_*?:/((# -M<.+)MT^01+K*'E`3AN7>X5=RR&,84,6 -MVOA%X$1\F$=6Y=_]XM@0\9#LO=T45+X@HVNBAC!D.YY>1."+TQA4>[["&0J@ -MHUTMF*PB&L\+V;+YGEX9+&Y4K2VT?%<)5=5AH<7R0U>:HO\QE"'0)0'FEKXH*30-\O):X -M04G&2E1))!TJ%`0M0(EF'C*U+:E'RZK40A3,.L0JJ3!&&G38:Z%4/WC\ -M=[5/[7C;=T>5KH^!SG3\=$BE_3YK)-PYE6W9/(9"W9^Z7+'7*X6W-9!'_GFC -MR9>UN/]1MD:4V8S( -MEU8EZOLA?.!Z+-Y-H^7CHRB,L*/O`PME7`8+"W]HHV3901F;Z?.%XL?A?N"@ -M:*"$%:BJ_,'"9%K;R9*#F&14]U=[O(HV91-X5 -MK$$:B7D]\0D4%,F,D#MUZ+PEZ8]J0$+9->;J"V-Z4,1QMLJQP2-12IB&A"$5 -MX*Q#C!37(2!VP1ZD=FA+9#$$7->L1]*7.EGFT:3]CW61B;XTFM$")6?ZH057 -MPE:8@)PMNAK3B:\A3?+/TH*:VL0C/ZM`7N\-1[S;SA+<)'WI!*Z]6UPE;2CT4;JXF(N)(TM+?*4=L&01?E>Z-/"51Z7J3(:=%" -MOJ484-1I<]RQ#,_NB`V)),21L8/CPB:"V<.4` -M/R/4N4A=DE3XDTD#V"E3JV7H@-V7QL#=Y<9(?K@T%'=@R]/Q#6Q9"U37L`1P -M>YY=9;IJY:!>"52TQ"@'>=1,%>:E@B1!WRZI/Q"G86KRFI5Q);1_$YB%YHDC -MF"D$B7J"K2PRC&),MBW<=^'=00FE[\ODV#*YD4BHQ71%H.D,D5323JG\*^J? -MLY-.UT_+%O*5E/JGLK/R[5E+7)L:(HG4?`U7FBK%N)L9*"K/*GL1CGV[E@AK\VLN=8102GV.0[4J#+D3?U&>V9ZU!D.&=!KPG-_JKN<0BY -MC*]#&2A?NT.9\ZK5%+@(&P(-6A*10,FGYR?K)GYU1-YF+% -MZ=V!PY(\MGB-[G%7TTIWV^(6)?=>QKV>R'T9'27,Y2:&\O7M9R -M_Y6.R7HSL/2M0V--KVJ(CV\LU/U93&^`.=HO,D68!$JB(TTI7E:\)-BX!\0O -M(;I!U=[;2HO(]N:ONCG"8C$114(VK19KU-4G\*D#2BMB0MA2/1.QB7 -M8C[VFLL_)]U0'3^F!P:*D*(B.5);)E/17L;8W53'A-J<52E@E>>;\DW)NO3+ -MS93.YU#6Y?-#"0KUJ2PIW9MD3QU,:=-0:L2V,4W,D3.92R#LBF4)8G),\:\B -MP^+T]L#KLH5=9.`068K$8!]:\-A7A%`9BD^"N[2;5B*[""O(8TZHT+!H/)39 -M.N,5YV`=5[>"80TNC`)'86JXA,X7X5Z*RI7L61ER0%"3X0.TD`-!6*A=VC"! -M2!/9ER+,CAR53:$@6#0^!4P32+D0WBSTGVIH\6$F-47O9(E<$WN!`4$1@Y9+ -M7A/P[]4EH-#SV8!'22/X?5[9;M:<#W:&W;+GY$OYK0VX;(R2/J@[=$*GM,?@ -M0SND1L`,G@U7`3:9EELGM=JE@0I$;I>R%*[`')X,\FQ$?*2]^,,[P.MT:&4F -M)C(MB7=:\RP;(+=;/WR8UZ0ULX"*B:6--@`KEYHYFBPR#$\1ZQ)DF[JVJ'KT -M(FDY+:"N3AW<&TR?6K/=4EIJXH<^+3&].5Y,3O(HU;3J-U81P<#.D9B(]"7J -MUM)_*M6=5A^[FN:2YUB4.8VBK6MVJ,-MR&[X_#DAMR!4P?"4[DF5P -M2*M3)VZR>Y7558YB(:T/7'9NK[)-;1*1'89.A%I:@VK61SNU<1*'? -M?7]@U!?*5SK%1[Y@I[3156GA6\]FW`[A8P8H9;U:,TUWY7KIZ:HR;)/X7\)> -M`T=7V\0L5YE`C&-X\54D%:2LB[RS4K@-6F&E00N8AQGX")W$4=1CL_`K^'8G -M/@`KU#"L8DO_!QLZI6%:Y6\M>V$4VB+CUNE["R*Q":M#7X!T?PYPAP)-'Y]`LP%+3K!*L[8A63(IS -M]G,:^NZ]K"2)LRT$TUN(-*8+E;;>&O*%@[]IE"2S5@2MO\F2>T!5R":K5SQ3 -M$F<$X4'*D[CE2NOM.2'&7.D/!SJU[&U*QYK[%#&,N:0PD/&D6X-FCCM8)]AI -MI*X*W`D(AK6_>D+E5!\(BM9KN1:W`'7<=<(+[",-%81+_DL0"B9/QEYPAB$; -M"$GG6MJU`'6>.7^P'1NK6B@,KTNJM:"0)VE,M+8S4&=22OO3I5L8(Z:OK1(I -MS9A+*$A&97N\-,3G4U]*UI+V>KSJ++=QZ=-9#CR'K@;$,LO==]I'01V[O=V0 -MEY\WV#S9%[^&0E;BOUN)?'=81"Q)9#GLK[\J -M\/?EM\$U/*>8F5&-@4P/A`%:4JN^H7>FMKE@CHKIU;BJ6# -M"ND\M+E:].N;/(]CJ1>%OEY$EHF#E18?5J3N@3'JHLWL&$8=?>*-RI2_)K0" -MQ/^%;ECLF&2;#/9>6!Q=Q_X<2[VQ0`A_A#K+L%@28#(>@JKDLC'WD\W?D283 -M\-D*VM-49[DSIEK\G++*,%(L;Y&6C'>N3?984V*2^-(D2/8GF\M100RI=-R>>``6U9C -MQ8=Z6."+!HDT%"*_N9PIHSA*,!(1("M$1#E*\VUD#N^1$FCQ/G9'7'A`Y4K/ -M8KA9>`!GC?)FKKRO"93+%4D8O;6%--39,LH@*T(AX1&*5R:L96`71'-J6H*L?+X(-HC:H'>0]-V#W5F/Y+L\6Z6N6SY0C!E]SXB;[$M-H -M5Q0I"LMSQW"V^$QS2SS&+.>'W@W8]@ISSPOQY"L65=%`PJ8H1#W/O$$*O`E+ -MWX1TM`WK=S&A5YL606KF8Q0)L;2)<]$6+13O!7D[-8TJ8E;UE"8>]=)I8\O'WJ*T5F&H3$,]*>5*L% -MYYC%)*D_7\TK*J'92C.@(98?HL;ZK=BM^M\0N=G%0R:,7=6IRY/!Q#I36DL& -MK=".$FP5NH1LF%WK2T!`B%+ -M;9>BTA*CIT.O&,(G*1H'=$@VRL@18EQV(6+(QC-Y,+$X?HR#H26TK/NC*N(G -M9/Y8QC%4ACC:'G,T"[G:T'E0/.'(SE"'+%$(H(AHU1"4[+&4^LCNE`TL,/QY -M4%R.6E0:6?3E2TE/;2'AE.3QQ,0:LMPO)K;?1ZY>26D[QS*SV\7T@[ -M]S)X`6>*?5UMP'`1BR\)5%43=?U7@$,EB#*$O3%@>JK;$\UO8_(QBT33D6I? -MU19;#!55)!:#@UWPDLI.G#JJEJ1M@>7JV!QQI^64;:YNXA-9T*`V!N.M@4C_HO,$+4 -M9J]O2L%I`[X-!,8FS5J^$%M$7R`LD,/`UE9A-[.$#=V\%)CT&2>/,V -MWFE/):X!@%EJ4@6?R>$F\Z%D$V[0L!:LE!X!SM.L0Q_A>7.K&8V5M@Y]A>45 -MN!,6%M2A95&5_[(V+^R4B-$"=N$NS^H+WWAV-Y[;%0U"5#'!*V#YPG'.NZE! -M<OV=>;ZJ1U[6F/V!_TG!QH\ -M2>>L>S`]\C.6;"^P9.MA5%]6QN]\:\;Y&97Q1!MR$/)"-Z>54%*:8G@V?/!"/9XR;(^\D]Z4T(TK7]--M,W!G< -M[CE$B5*QNQ%\(AS\JKCY%O+LEG`K])YP')(O,;G$'-@JQI]^3-4U[J;#_=NM -MZJ^+70/=B*N.P4_X>NI)_>Q3QNN6_\G7)^,UVZQ%/MVX_U1QFNTQM=26^S:X -MZO]BUO%JA5B,=8>R\+2?76)1= -MM,'$3N@U7@%=JQGF$Y/\?^5HBQZK&WC0"`MK'$M$,5J_7WPP,\<45J$3TLCB -MK3E>U#__CLDV*"N6V56N^!^M=U"N45!@SO_#^GVB\EOSN,TE7V3W -M*R9+*0WN)769$M9-)&/,$G]DUF9BVIL0RU6C@HN$TOIHH5IR%'E8O",(\D*( -ME3.\+5)"NF"MI+&=%$0P,$`[B3Q7!UCU3N+A14Z-3.5SJ2FJQS"3FJK?R -MMZ$P!"5V%+=,6Y+S1V46DF)-CNMBC5*<4VV63N`FRH!W!U7PB;O3_45*E2=U -MX@KAY?B0RY$E%1*(]Z.(5I'1E;YEHZ.F1!GZH!"4../:1"O2@FO3E/1:>CO6 -M97+39HRH9L8RZ%R]X]3K>=FG/9&CQG!S7 -MH/$H%'%L(]G97G/5G(*.5#&-6V=\B%EJF"G_=%=K"UU'=&B=/#/!R7@O70P\2C9P$2H.2E$`Y#L0V,?T(?"3F/"$J.*Q19,JARWX"+D)GQ^K6;R4F -MN5>R@:[X.:T^H=@(C$,-4DPDV#B*+=E$T`?5[/Y*E'*O1>UWM_EIM1%8#PMJ -MKSQU9=XU_HU&'F@^H#[$CR5N>5>C*6]T.WAKNCSGZ@A-ZHG`3N-GI;-24QV1 -M/-Z"'RVTFH\EB\?>-)_4/W]V#T(?8^5NDSXM__W36:RP>^UGOA_]66#WS]7P -M!_]>@N#/O=/\0?O^<#ZD/LF7Z+E:I._#_;_NNLYF0][<_'_W3:;Y\/?,S\G_ -M=+VDO",XY6J3O8^4/W_2^[>:TV;R;#!]XO_!L:25<*K2PC],>NKSDHC3U.//7RWHH+>G[9%LJTY;[5V^6/=/!N-*G -M!`CZ\=`*,;Q&OM[C[MY\E'>3,V/O'M?3&KL:1>#OO#3GRD(&?]3ODM7%OO:L -MQLBTZPI+MD4@^/$Z.ZXEDM5].6X$!TVTL)`A#3 -M#MQ9P&'E&I#R6":(*M'#LY"XPM66`\T'&MU_F4Y8V5^5_7&6NX_*M.EQ3=OU -MV-+LO#7G=DO<6)Y>W[1>7O"ZO`8Q#%2='^U:USA6D/<8]&N=.V,^?"G]-)GR -MI;5J"^5=,K?"C>:1Z766T"N"4Y@H.D(V[56:*FA;EBEDP_ -MG-6-J:<>1Q$9@K_'+%8&88?D/>2XXNKA$T[<>QT.>;@D`-0?)8'>1T=O(UP% -M][EBKTM3XJ\+X+DT66RK$AH%(UY(=L9Y*%*Z5BP0R]7V -M3^IY-A&.9]$9Q@WG0^(KF-]>)JH;%3_5Z!;LM&K;%%Z.\KTA>J6\E_K;$/W6 -MOJSZ\%"K0[PM,11)EM*+3,\AW+U7+$W9AP^0M=O4A.%*BE&%+6>J\XHAU*KJ$1Z,'7O&\'YO&F/<]&M1"=^;5N41T+O`]../WV*,* -M^^>%HV-4307IN$M!]@_&^*8.`P;E``#E``"```$"44\@K5VG8`#==ES=K"Q/ -M5P(;"X'V``3HJ!;M@P*V0J=E@!4!-VAO;64O86YT96LO=&5M<"]B=6EL9"]U -M;G)AD75]Y6EE$6MB<^R//L(18\[;_\R#E`VW`?#QX7/(-98"P -MY!=R']2/YR.\H['.0RV1\3IN@QT'\/C_.,5W&M7^:"OZ$G#%. -MNZ+DI[;V,1&Y))7,)K^/0K_7IY+#/^\+8O".0P-8CD&(0+_LU[CP%UB#=F\B -M.\6/DR&/A"Y5JEM02(#J(P"Q#7+N0^6JV2**PJ]NN\3$E#%!31!.>T7JN/I9QV%@6!\W6>H+C.I_4%R`"(_VJ6:Y@T/CY,`OM*?+"E5:OKFN -M1';Q:DTD;DP&7)-99:18TA"-/N2>-O9Z]_+%&^*4L+2E<5\Y6_FXTB#->&,( -MD_D],;Y+K+]Z43H0.%#LCF.<7'JAV(Q2UH:X50A1N7!*\SB3Y6B -M\`J2[]+*X0]73.]3:"-M9U&QR'XT)O\CIF\C[M;G/\;Y&BH^\>IT,?<(RIRY -MR5:MJ3MNX\-NVWQO+%@<4^*_WRM4A?YK([%ZQ5SDQR/+VX^_UV6_T9ZS:?3& -MA?KI;R,2XPH)@OK(B-F(CE7[L[D01WD52#[PUVN6SXMC6AE"BN9X<8)X#\)6_GK%VWXR%P0+:Q\-LB'(8$N88NT18R>7]VMT8 -M;/Y#JX^\.,M9+A*[W[?(MZTRS5PP+V6$%T1'5O*<_-LEPME0/H^ -MZR]EN]7OG?VI1C=MT<+WD\1J7(_Y#]);$L0D89_$[6R9-R7-IUJ[_ON6++X. -ME#WOJLS9+OS5JTL,[KWR#WF>37@[C,XMI87V2(C7:Q->#3!]=XWR(6>5=AUK -MM&(-\"];=ND3GH?&4KV,%&I1Y8[7O+![_;NG#]+;!\$ZA]3G@^N\KG&(/I:" -MRWSEJU]\T.I\\G:==SB"YP`N\:D"VISR1/1-%SA++%6P):@UQ8.GL>:KHHC( -MK:94JZJ+<:M;IHU.NQ76^$Z6FN#J,%"LWP6XL1^H;=/UCG:_&0!,#YU%=7W% -M.6'.YD>1%=RM5VE>LX_OY=BF]UPBXS6A\@XSOLL1&T4]O?PI]RQ5[3\AT(?G -M_G]?&MLQ"H:\>KX2H"4#X(U?*4CM+;.OI^0'H@^NV7R(&.5>OPUV+=8W-)-B -M%Q[FDK#Y8LSTZ8/>]]V5DNP*T#2?6YGLUQ5.CIY4WO;KR?-`OK8)=9;$GO7= -M:4;UV[BG@F+DG%;)$KFI0^NZ -MA='`'GAET@SI4<^>JE/4/1'PPCKH:MNEWPR@!6U'2M'!M;P(.L2O*[U&7,%I`O4S>"J=R\]M6\2UKE@6L^[ER>SG_G-R5^'N[)@@U=^U!>M90"9K_A]:(DBOM-&Y$,GY_A$L&PQE@W'B3*?LAOQ -MA6Y$>^/"Y(#_':KR)=!=_O6/1**-TY78\U'P8R/P+/SZFON4=>+7*"&CY^WD -M=CVD^^UB6`=+$5A\=B5U#]D9>?_CEAW,%LGCZ)#[QA?&#^&GV;?- -M;G[MML?>*W]'_#WLLM'+#O&4CQWLN5O18=K9*W,'WMDNKXJ,^27=_ -MH778^5=;"F%:9>.WC%/@AM$&_`%OX=KUW*N`DTZL/?CIULT5OFCW@-S]ETW\]5M^LT:WSP^Q\K=*$[Y/_3Z;[/*\L.JHP?Z[S>>M%"TBK:2S"UC5E1<7TRM -M+9X!,<78[8/@%7TMLL7U+(55M4,X,G!3'3ER3.2';81\!KYVQ!KP.>#XKLGE -M\W8DI,<\1*M9H,PD80(6>`$A*!A11)IIMD3\*T -MFXW"T\;2TIJF8>&2Z`N6D(!AY4"E(!9#PAAXPRGA#(%'"X6PA"-Q^\SZ/73 -MI_L$(=S2]A3:FL[_L?5K2\">WA;6[QZ/NM.S\C\F]_UL!17_*K&'ZY.Q=;L_4=3?K82956;^V=D75QJL3-=- -M[5>@ICIF<+GT;KI1VA7D6/:P\K]6OMYP\Y_TY^?H;9M>%3?5*C&83$S>X/]O -M3&1+__P?)A,652&&,5-:KAC6SF6SMGBV);#>64OQAKQ+.JG&,)H(7^!T\XZ^ -MK7:PHW;QBK=XM_Z-OB8Y_>XCHAO)$=QN\IDB/:O+[5".S==$/QCR$<<&]"N\ -M6/XLVY5K_3F]DT<,<(6,;N"L7.?(JP3;Z;7JK^[`_J^K>.%;;=+E -M;O"/]L.9G)&H?=0CX(ZO1"3X&]*]UI<QBE/V -MU9$P)H/1L]!/^]-L2RY:]S(,8R;.?XC?//XN8)+Z)J](T0V3CZ+'$DVCE2/_ -M6;/RPE?+'W#_GTZI%T&\:)+;$S/3JV_8KYPZCJXMWO5*W[&8'P:OTYCH6/I= -M6GHJ-X'MQ>I.1(_2CK0/NDP`/T)<-Q<;2%ND@BW(Z)MO3"STCAZ<4%1^&LVX -M1+4+'_FW^V#=S&41]AN#2:">SAMHT7.Y6FA!QT7-EO\K*6A)D:$'-D(YQ!C1 -MJ(SCC4I,'`:8K+I-XUA1G:^\/T5`^7CDO"TSS0HPEH?A3&"-`ZSQVN'^T0M: -M[?!M*9Q,/WT(V"1D1-HBC$#'/I![+KLYH!Z?HV[)SD'P)BZ+@T+R!`9@<[>T -M3\3XJ4=2[J'[\I=3[B]T'FGK*@.HY!.7'9*072^_Q-7("A*2L;L^]4C`?>N4 -M!0'U%.WCY]5!B7*4ZH=3\7?Z@HQ%_AHB&8D@29XC@]<`_L@E%N,&X>5$(MCJ -MJ,YE,<:(YG<`_`!S#Z3%_T<>"(_#>72@FF+#OUE*^A4A=88?$1TJQ--K1``5 -M_2BYK"HIE$)\*;152!5;$58&K+;!_=8J.&IMKA]-X*+X].ZF14+8_3/)]R]R>'@?%8>@R*&121,;JN -MQV5/L\?DP_;PE'\QBFM4"\D?B).L*C>7]1/$P^0YJ'TKFH*"36">.8-(@6_S -MH@M4#WOBE+W0)`@/.O(&XA\N9XH4@=3X1M-1/*J<\!4JZDN`=R`_4HY<)3,K -M)XA[E3.*(1I?1"HN45HL^(;P3A^5HM-ZLH^#M]3[+J&H'!Y%\,$C@@3J?]/= -MJ%JQLK-9%3X$,7AE"['2/4U/7&-.`1.$YC`@'IK*&":=^%6(FK$IHJ-A]DHV -M'+V-KLU>80_CP?VMHM/6@R49U%[$TXPIA!TOC<#7AAI)A-$^/)()B0[7R]F. -MPI8UE^H6#=4QQ-!:KORFM8M!2ZE.>'B&T1JIEZESB(#QFC`(DT[%#4]G([(0 -M6P%C\59`\TQKJ,0D6!B@(3"DXA2!!8<[!#1\2J$;C;FH2J/4E$$($!L(#J.W -M;YY7"%U'20H\'Z2E(V>P_9DFJ05"JNHHSMA!00]N@9SJ:PTMHLP1,^_8N(#B -M"?R8@>.R'ZZF?0G\JJ46#YYM(14J8Z(&KH#^7VX?[DS;VFG>,72G.%,ZE#E% -M$$4U5P_R`J]<\?UGXX'Z=E`\%RB@/H+-A:J&G#S@,7>I -MKH1PNFH+&=Z+AJ%7`@&DF-)B:G4=R$IA), -MW597\)Z%ZE/4$III'NZ313HR,>#!`TF.B#2"9!*D<BG=5H(8L-3$"C`@:P43`91M^5Q:OHK"+B#U+G?>)"!I44 -MFP!I2_9O,E*H6&]8FL8M(*,U"?B\0&I@(NJRF^*0,]GH2DVE%%3JZ*N<0_X= -MD02F*Q^6@3EU(Q4,)FL*5U"9M(YPF?UAN:RA$F*E-!HRICR00=@@NSU,4Q`- -MHQJ+()'P.-?X%!IY`$&7A0RK$5XW(0;D@""-3@6>']7IHR/WTK*:%+`@M`4FP(&8 -MGS2HPM::JE'Q!#]FTL*WD!L(\GI7H!6*D(8&ZE-,>4_"9E:"$#%4:Y^(K5L(4_S.VK/? -MTEER%B4XYZD="BA\]@/*?5F:!+$O6P-)-6$P.(8O/';*EV((?B[IJC0$*6\] -M=Q&<@BDOV#`&Y>F^AY&B00@<@N(-^&IVBX?*!SV%6N64X/=?T-(PC%5U0E>@""P,Y3,TIG -M.X"&1#<0@+<1"&,J@CXL7U6'EQ/:NU=.)^'T^QEY#7FD=R7AHF%C1#8/)X[/ -MN-+ZI"F5#*"DMZS$6"T4RX",=*_KEV\RD#Z?X'N&1'P?;J*C\\Y)MQ\A*BDF -M@,`\%#:H6#5,?\=_*:/3:;HG>DS_3'O_#NCB\O'_'^#*D?L^*N86#B*A]/$R -M+M!)<"PGR\;1]94'ZT^H92I60TFLYB)5-4C-<,7P8NT#TB6.A`J`;!03K6/R -M#CQ?#5M^,2HQJ4/N6()=4@',&*:44O*/LD:W!1[FEHK&_$& -ML]`_>Y&6*B_;/#&5LP1$(-(LK*H8C"D&(N!I-V4$V3_,_#=AX/R/$<'L:IX; -ME!T9R0B,,F^\1)6Q`4A(ORM*@]10F8WV@/& -M#?9MX.4]$Y5-C">;3S*1JGJ[)6?48E$7BM3[ME4\0'"5N4<;&U2+DDTTSR6][(+*[]J'"+*: -MG_+*I"502R531^),ORM;]% -M@:XS>/IMG#*UL.G7R7UGM*Q0::TW<-6K2N5ZMM=^EW=0^[+).S-WV.52TOJB -MV3*A9LL;L?=LT2N2=;*]/=KG/&K4;V[9V6Y\DGWB%3E]#8]GE^,^OVQO,J5I -M4@V&68EC=(X4+BJ(+\8=U.$;YZWQ>2T?/D4;J:.42`G\ -MVA/R7;=?<;FXVM)7]M7WM[B -M]IJM>RXM?MMIX>J6&T^+*;2^/XO51B7O8*%P\W0=GB]OFLE^'[GN[/_:)R5] -M"[.^6S=9Z]!P=U]>:4R?I>GJNQAW@W,A'*MX"4'HHX]%N=M;<@J9W->S\.*O -M[''R2-GF:.X5&/G:2=Z;K]?4]USEBK']LE^G6"#4VZA]5L%-5>:?,>KJEA_A -MY&,[_\VXT?F:#TO4_Q?\M_&O[_5=K`M`W9SVN\?^UG">>K[>:RNW$9_0\!3% -M>_F*;)ZZ;VG8FV<`5?U/M]O8=FJ-EH=C]_5>YM]EO-5#K>?P^>4NN.4KLE1* -M?\_SU:F7V]AC5-MJ>)I.PPLXIKM7-9?#=KGHF/L:#M9^*0^\&>]@>,IC>A$OWJ\WYG\QPO"P -M!N>DKX<2^WMS#4N;)3AT]YSP67*@TPPNBGH\`B*0.._17?)XNIQS$E_;1/Q# -M\GE_N>_MA\3I_!OH=E#N[I^IT7E.4KG8@O^/TGD"*>8AP_?RO?.^)?<*'NF[ -M@G#_C./'J6.ZR.`=G#OHFCBG]M#(YM>9]CDUHP_#X>'X&'G_5F^VI;!1WWWX -M/$4ZGP'G>NH>.PU!V&S];O514.O].N^77U/;"/>3^3K+S,0;I[X?/]_%'X_S -M<__+PNG5.MV&[[2L4["C!_]2QJ*[^O4ZG=#I1;/>=ZC%0OR*CG-IT?DY&FJ] -MA6[S6:G29_P5.L[)3O/A[?%UOQ=\IM=KX'MJ9#?WN,ZJ)^E2VY#OMO_?F9JH -MVN=GZ[RIC[/9=7=\MK<7T6:_+8]'N.3^UX_+[_;3[_J,]1;+X:Z;O?KP<-`Z^P[N_I^XT?L=7^'7=QR76 -M^WWW=4G<V>G7,Q"AN)V$A\`IGA;$4/M[(W23P,3DR.@O$YS\B7 -M0,ZS<)B^=-H]F$Y\3QF.9FSS:1/B+FA=L/P:'`A#:A#Z)XF>C#K0*"[FB"E! -M5EY(F;F(R//_ZJ\&P:LY>7T6;Z:ONKV_\[U437N^;VWEZ[Q/P:^[V/\,3FZ. -M.XA_VNM[KE>:]8=/TICPN\N_5[N%^3W<2U%/JN\?Q9L5,?Z'.JFZV_'V_-12 -M!-H:1^+-3DK.8Q@XE4\_H(HW61O9OQE.XUNB#=\GY=?VO -MW=%IOX=I6"$.$ZCKLEV?MY_$#+C>C0?VR7PFIU-#W_CX_ -M<54[8[$VTAZZCR[K7=S7JCEMQV76#)#^1E,IFZ'H<1R"A=;"ZGP+ZSVP+E[[ -MD+V5.7ZOT.AU?/;%3V<]W%;4\C5C&E8NR)Q)DA14@.0./A34.)-23=-(WT42MN&V$4.@)PIWF%F6F,R!_O" -M_Y1W\3B83?'A\T,IQ.!=3 -M5[;;^XN=_OK>XO;WD-X^[.VNKL.*[]NK";#G6%W:V>]WMD -M7FQ']8VMUO[.TLC>+R\LKH>MQ:\"VL;FXL;*SN;&T!R^6TMK6UN+"SL+"XB@ -M.^S!O#&R'1M=]]?XI[U(=52V\];@KWEZ''=='W=P'7>V@<6]O+6\W5IN^YZ? -M?VEJ&=K8;T-V\O0:[6WLON^N&6^X-N#@.C9V>[$!;2]^:RM=W9\"T^;F_)MP -MU66_N;3?V%SPAR[RUM/ST5EUNL'"W^4GD&T'+YAZ7(,MIY$">!<#J"`-T#W9<,CF([6HB -MI8B'O!O/AO-V(V_/^O4%'<-=MOQX$>>`()6]M;<`CU;;VR@T'-6UN74!-N-X -M(-B!XD,!3B3EX6%C2;=XB/%R]FXP\3/$4Q6^98N96OIIR@PIA^`9^.4?HD?8), -MW4Y=R2/G_VGQQ%ML0O>QR[+WQ'4.9;]G;7]W.16LF)`0B<8?YB1#=(=K?WN= -M?WO8%_B'YIF(APR,5C%F>(Z._AVQZ(.U"CS<-NKO\5OH\*:9Q=H%-AI(]0*; -M&GB5,2=UQC(VYF,P?X.:DNX><5D#`_%7T179EAM7)[O"87A\KN\AN(O6(#4? -M@5^NO@E[N.S_G<@\V(V\JBA;AB$,5#M1>4=Y),W8%E$=X?$G9&?2';OA"8<;'$,/8[>?E!YQZ.-RC^NT,E$&8F)Y!&84H -M8+M2'F@Z-"(;U9B*/9#I'['\U%1LI9\')#G:E+_#"B%=/6HLCK(?$3_W-A*O -MN0OJ6GI80T@[50H,*K?ORYGU%545'2AB/GS],$.U4Y(MZ?5#NC'.]>0!RPJB -MJ@NWE76EI?HRMLAG)_.YN..0D/.#DJJIY7'TP\_'-340<%734U<3R:L0*5V- -MW4U2,\T2'PT0E@DBP=)&&S9&K;"(\ETB*&1``RAHAHCD0Z#U&B#T$(<;70A/ -M&(AW:HYY20U\U1WPV0R>W1&BFC6S>>R^:71="A&=Z$=KN")1XQ!^1U -M;Q_.9@>3(VF-S3[9&XK1QYV_SS1NSK1]9W,K+G54:NW/*IGE5SRJ9Z_S.75Z -M',LD4+=+!99Y5)Y59Y5)Y59]5)]59]5)]664+8KHC),B%4DGIAT9L2,LI)D7 -M;CJ#/Y( -M@ON/(*HE;1F8N@M+J8,0'\Y("^::%"C4`?.*``G'7PSAKUO!&O# -MVTO>"-1C,VL97'6#$CU@6UUB$X:MHDFK -M+F-5LN.JCH[JNYIJG"2:HE3U.U(]2KI]9SU(Y&ZCAC=0SIM4>T_8XZ>N3;&N -MG;L$Z=#3TWFFSC(UR33%SCI96,;$]*NQNDYDM(X,LX]I!:.:.4C=&L,-3EHR -M(D3#Z'I,_I.>=\]I>=',3$PK`ZVP7(1T6^@U!T65$P@([Y_2]*"YT"YEZ#G>D6.HTE`P;^?T>FT&?T;O3:'0Z?GM0.AG]!HPY$A -M6)PA68_G.<9%.S@@'5)I0CHPA6>A+IN:1`Q<\A,-:3K0*S.I-RZ/,"5P>7`] -M%K'5V9*H8FV,C+-)S."$0G>BU&D=LXJ(2-%BH-0$KJG2\*D0Y8%98Q0PH:FN -M2*%,$RL)-3=33"'4.*@W8.%9HQ*U!3*LD%9M5T;*1Y\-DNK`5M;D)C$J:!6Z -M])S?2L5GU(5RG2A&@5Q*:-V8.*Y7I.F0)+2$%(UW.-F:??<2).A=+20H'&5Z -MJ"X/SF1F@D<5Q12I2TD:=C6+5#JW8Z0_BR"K3JYF1BM7AD["I$Z0H`.(5U6D -M#PC@K7(B@FD^3BNIR3;]""MA]-1'K"26?)-3D79FD`KV$D02%>L$FLPKVFDV -M&I-1DYK(K<>5J*EU<$"MS20KV`D0RCM&6XS\H:P8_,,1E"8%JA.!K9.A!22P -M52G3&P6*X%$*_#I&&/"N#T`R6/6M<25Q7#$6D1LG9):"+"2.1%FCIB;5K.W9 -MZZD>?4G%<;"%A6FA!GLS+8KC^9.H24$\%BN29A8.%)^%;Z1E+'Z*%396MRCU@@5TXP`X2 -M^2P*ZFD=C8A9*^CXI%=9"LXY8%=:26.B)+%7J"LH'\;BOC"R)J39@L5VGK(+ -MC>`_^4*[>IJ?TC-"]R%=V"38FE$-R^EV&N,`CA5.@X5^6&02*/&`5X5.++E8 -M#<:A7BL&FHI4C`PD@LA9Q]QZLL"O*+18R:9E7DXKS0133@:FG9\RJ*0DY/H( -M5Z.-EQ'++A2D*]4&[X,E@9(Y]#`'%H$8^[9>%>TC6Z4@RM2^`<3^EUFHM&G) -M*)XH2G5E<'%T'[OR'73I6@+06FZ:W31Z-M$TO03)0<2?T@%?9E,L46!!EZ7$ -M036FD8Y1)V"94X`%/&BRV?T&BRH3]TAC1T]7EB^JN,J/8DXMJ0L"/EGU=3D3 -MT<5@CHKX>!LP%PQEA#B`\,Z%^6I@0C'(8'W+%4\'J;LC`Z=0;-`Y:BI$>T[T -MCZJ:,4/$_9CUI8YR+`ZXE.!U$+S^B#`@F"[VP`/K*JBIS-86(^B>[RGHQ5D7 -M9#ZGU9Z3UZ(15C#$L/(QSGC(CF7?TO^.495&"UH35.&:O]N,4 -MOSJSI:==GEGW;I+C]I;CSJIX$2)4*WFYE9K1=X81CKX#Z4__VL!:][ADN.=Q -MJLX5>/<6^/5K4MABE/+Y'`;?\=(Y/^J5,1K#_)JS8U^!6FF)&_^% -M%K+M&J+C]9-OF$^,S,.7R+G@X%9>26?_(+:[S9Z=,W02 -M0_\PKI[ZNBSF/!5X9U6DY/_@R)ZO&MY9;A0*Z=+H8LZI11;?,.0JK7Y46NFR -MBL\JJ?<<+7^<:T.XJS=2K(__SRX&$8?_K8&G4]HK/1S"O``/QOBF#@,&Y0`` -MY0``@``!`E%/)F(;8F``WD9Q%Y^ -M@!T!"F-E8G5L82YT>'0*`Q/8Y%145$1$141$145%1.^>;>U=^K-WCMV<@_CTG";^$.F?K1 -MFY=Y=U5>]ZKPS2O\[5755=5ZZNJ]=X7ZO?WL#"_PNS`N_\-K&I$ZZ977UCC$ -MJ9,:MW&+6GHV2_23&6)DIIAL83YEYX#[M"8Y>[NUE#9V+3S[#SDB\W0=#W'K -MET]BI$C2L5Y+BK/N31%LU-.5:XT"H&#=.8'5!HYSND".4WER>-,XMV2-@KC4 -M;S6F*GM3`](Z437!*Q2>8,LMH;3]2F3`@8%'3/8\;=F*C -M9I+#\]QVR-3`&D@!+,7-$ -M.//S@J'9T4]GF*B?[EZ@>XV"H&Y$FJ;ZO86DIXR0:ZV -MHEC][MY[?M>S=^OZOJ>EZ'G^=YOF>7Y7D>-XGA^%X/?]]WO>=WW7<]Q -MVW:=GN>Q[#KJ'6=6^[-F74NXMI,CJNIW'4=/TW2[39[+H]CT/0:VSU>JU.HY -M[G>;YKF;*QTEAHM#H&.5Y3DN0X_C>,XKB>(7X;A.#RZV)DV)6QS0U>$-5^WC -MJ%(2ZWLI):36Y"G$*2:4JDPDU6"I2U84RI;?^M#B*NMEELMP5*V8S",SPJ,Y -MPZ,]F4:/-(T^;1K^+1M\XAOCD=EG4;OD4>GR:/ESR/WSZ,WH$:70HVVB1UM@ -MCQ](CXK%%_9(Y;2HM-,CM^<1[&G1_7/HY?4H:U2/%U:/MLT9_7(9UZ/)V"/T -MZ)&FV2.OV:/?VB,[MD6]HCUMNC-;A`!NQ<]L)P(#"Y(!!(`@I(,"QK(3?L`= -M`0ET97-T,2YB:6X*`Q-G7ZQ;&EJ>$$21CZ(`(`(`:V3GPCE^!]$U^_]''MAU -M>&'5?MXZPTA+K>RDEI-;D*<(I)I2J3"358*E+5A3+[P2)>)2O6"H):I4DM)K -ME^L6RU4R_RM7\V5\O\Q_F`E[Z/ -MJR<"`PNS``2`(*2#`O)5T;G`'0$)=&5S=#4N8FEN"@,37&>L6QO411!#*3"B -M`"`"`'A1_+_.^J_SB]RS8D-+M219L+#I=J2+-@8-+M219KZ_I?PM7\V5\O\Q -M_F#Z$YWU)P(#"YP`!(`@I(,"_TBD-L`=`0ET97-T-BYB:6X*`Q-?9ZQ;.X_4 -M%T$"&:(`(`(`>#'\O\X[X*1[+_*U?S97R_S'^8"MJZ3<,@(3"\?9``2XQ07M -M@P(B1.PAP!T!$F5L9BU,:6YU>"U!4DUV-RUL<$DR9(!D)!8PBF1!6,07#@5EE%<%%1:5N`Q45/4@G`BHK$!4 -MI2MR!#@0(V'`@)P)+:6I6BLK2VE:-L%@I1&LJ#;*I:YP&)$0&*BV+12[UO,[ -M[\WO<,"MX/?OO??OO[W[_/WX#+=N];UP><.M:\UYKS7!A^+9F=;WG>\SK>9U -MUUWK7F\[FY-[#/[^V2$_!_[``@`J_[(`*H`"`?]D`&4`"'_9`"%``0#_L@!* -M@&V_[0```+<,3^UT^'ZAPX<<;[KLL4/^V5JUY0F>8CM63*G!*D-6TIX8DPW+NE1PIK&-SZR[N6G]:_H\(E -MB3#<6DNQMS)U1FG6T?-#R2[E3;+RARK3PT\,23+DHPSB2UBMX59>YD\1(RV/ -M_O1?):ESV3[?M91C[\/7=]]E^=RO><[@6H]\V6]3UG7-)%JA>6Z:@;/4EW-3 -MF($/3>?X?,>_K_)]+"_AT?>Z;V7N-;G/U+U`>.J?:1SA;SS,%]!B=*M5+:/" -M80"]92>GL;AJ"E26>$[]7S8G_'NF6@K7SR9Y]67TR$W!ZNDT?*>3A'0X80%+C[K2?5B;#"Z9R*S\XSW-C_@%NK>75Q97X`Y@T,/'^ -MV_K`7QX3VO`.[KHK&EF6A`#XN2)O^NC9RQQ/,-W7O#?WR:GE%Z.7F] -M*RD4\PW#YI3S:LIE-]7@+X!N+P+?OH%-.O4+X-?HU^D7PB_4K]4W/=6QGU%. -M'DYUBG$K]:O4K]I[#Z"N<4I[%?LF'%K]HO5+XY7WRN+C-/I:-U]GE -ML/][LO>K^O]D0]AW_:]5TW@Q#PGY^#[G3>=ZSHOC]G^@,_N/+P5M -MC,M]/;9^:=K^C\'3YGNLKG-MT%VMO*Z'S-% -MZM5J?>N_;=5U7+N+W\FO>PJGZFM_2`W2]/Z_`T_.XM[_5=O+W^Z]ZZ[?Z4&]_=>6WN3TVH_AW,+[77?R[WZ5MA7TY&]W96O>XJCQW\[Y, -M:+THE5L=?"YBFM(O+_D^[_2[WG7?O\[]?-7CH/TQ])F?FW4&[=5[OLO,]]3. -M>WYT+O_&]ZDQUV]&+\?Y]7HWG%^#DO;^+VL)]_]-UZ6\?D_IWGTK"#]OE?FI -M>5T5'2>K-BGO+"7^7[=O/W_9YJZ9;U_*=_CZOI_J?K]CL+S9VG\J#T^N]-_^ -MK.@K=_WD>K^QC;Z^OG?"9XW+^EL'70]_\VGK.EV#_M5Z -M_-9VWT^9KZ?\N8]WO/'_I?_>]S:>].8CY*\T)'W+]]W2_O]+!=%Y/TKI_#UM -MMS7N_Q\.WP-F"Z-V%G0S_E7'-1.U+P[NU>&Y_G\M=-<_= -M.KGAU\$%5QK_%E@7KA5=6,J\<%7XONL8J[F7J=6JJLTH:KWBF#JE5YLEM%65 -MEXW7G<_*;YX -MRJY1AWLO+\V1VSEP5W4Y^7(NBE,[+TM;*<5)OY2;4$N5>`PU,O._%)=3V\L3 -M?FDJTO+QR&LY<%W;#M)9#7Z2ZR7*MTX4R\[BJ7\N.C*=%+_?)$-AI<5D6&CE -MSJD4US)5@Y9!?FY"LN[,O0RX[MU,*7*MS);Y+TOLFHI?[WSB6+D( -MNN,O;JOY"+[J9<$<'UIKW#&75;]"%4N7>,9T[QPHAZPLO2TYE\E+_?ARG!W* -M*G$P>T4LCLG*=BQ?O$FHY<4\=,,O?*4OE77\A>:_2FAEJNS+,Y_+)K7*7?'$4EIY'EYWAFE52XZD8=Y+(;M&&X8NW,OKY?[>,-;*OR.01VX(;ARX+ZBG;J -MN*9>E5?/DVLE660ULQ?VS2JY>=HR11%7^.2TLF_PH72R"\`Y!X8NP/O!,7B3 -M.S\O]_?(++2X8LP/I<=2&7Q\O.R!I6:K'YI^M-)OQ%-#+FWNL."EY?]9\JF+ -MAG":62S@TN(JZHF=;"5>V/WCY?"(W6ESK]YI0%7ZS#IE7AY3;2;Y*4Y.7G#X -M[?M<=C:LY,YP"V,ZJI^KC,?D,ID.V[?*Y8>I)TV3[SN\A4XWM#_^0R^6$\9^\LA/K&X[)KW]8P&:&0[O+93Z_&^01QVTD^O5Y!F(-.A -M*@OG'M!QIWVV.QP*S5/X*^8W(`CSV^,[[N_`7$_..JV"KRD!D_A)^.@6R.1R -M??97)+`OSE!)_7,_XE1/9;(B?62[D27=]UC\$IE>W[;NP/$?O*JF53[!,`H -M)]Y7N33H5'T"]I3V#^L:#_BW;Y7P&2^ULH#_.3)'E8'X`]!+Z`YA-/8#UC>Z -M"6[\F?07R*SX`_`/XA?W(CY,`(NA6`K?K($?..*7^B9`_P^.^R@]8W+D7H4^ -MY9LSDT_L#0NB#C)Y#NU@?C(8Y"N";Y$_81^P7\$%/3*/_C@/COTFG_Y%X)WG -MN^\QF3;(_!)]`//08)*>"EZ:0AG[R.7)WO+&1QA!UW!DC%2U4$7>-Q^/00B/ -MZA/`1=>!V^/RQK3']YWPD,B)7(=SWC84A,BB=0CK+"6"7MHPR@/]F,";XEH\ -M@7&3XP]C.^R(GX\!;N\F(O&@[R);(]XR5VS5]RT^64?CM4-\H0Y`G(L/_&Y3 -MMD+\BI]"<*=H3Z)^)7IHKR#^A3D)N^\[5FL^]WD!(9+ON[!O*3_APO8M'K*X -MX#,B@(@2'Z0>C;N.[!'K(^!E`5@7X-F\"K_]YD=_D -M.,B`9P*CTMVHN_LW7H"_=UC3],H.^-=^D+^I8OK5=QD\8G[-^1='+&\E6#/* -M2I4'+2M\,@]DOR"XWI-B]H`!/LW#Z1V42P>LC5]]ELK+"Y*B[[SMF3_?:= -M1^:_G7T/_ID^./[XW_!%R?@X_WY%PJT_IC_3/F5_"6GI8R=LF4S]'1'_M -M,TZPB6D+HO0XOC=;;SM!S_I\6<]N)XNHYS;<1(<#:OOQ=<_B8;[W*[V@X$[P -MW?$XCNX><.=H?;Y+?W?A77X'OQS/RN?G^=S\LS\;WX+KPKOO^2]NBC-VNJR.G[C2 -M=WX>4T'?YW,9KP?!S68SO?Z#*>'W>D[C3Y'5=KXW:?=[+\'7^1B?*ZSS.K_- -MU'F]+^KH_/J/1Z#<8#]O.^M3?OYGV.7_GRT:B_ZP_Y<1W.W'R3('Q`M(5C/\%];U.QZWR?I[; -MFOX_5_)\SIWQ/]Z>]JD^M^/#[+"?K`/'`H)WA]-YT6]4-M?-Y -M]+TL'9@WH%?P5X]^[`W_R?N1'X,_VM*#>.5CXCRP7UZ_.=3^AU\P%Y!_CV>8 -M<<4&^`[_>IT_Z;S(`],?U@V5/M\3Y4U\@/^WJ+V&P'_0=]$F(E@^*`Y4__M_^69KO -MC!\+3I/GRS,M#^*<6__>_N2YY@UG9N1[OZ]@J7Q1KU2\J-@J8Y1L53LU%BJ# -M(?C9,3ME#R#?O<\=\M[KR'YUL[B7Z0/-=(NL3[<1Y;_JD:FR%CO1^W&H]QHH -MVIM]I(N8=>J\^O#7RZ]6ODEZI?%+PE\,O!7IUX"]*N_7H5WR[Q=967E3<<55 -M6ZKMEXB]JO:+[=>R7V:]BOL%[!?4KUZ^?7AKY=>K7R2]4OBEX2^&7@KTZ\!> -ME7?KT*[Y=XNLOU7M%]NO9+[->Q7V"]@OJ5Z]?/KPU\NO5KY) -M>J7Q2\)?#+P5Z=>`O2KOUZ%=\N\767N/F55NJ[9>(O:KVB^W7LE]FO8K[!>P -M7U*]>OGUX:^77JU\DO5+XI>$OAEX*].O`7I5)6I.K:Z1.OI2_7@*-=-+>[._ -MB<+<#R%_P74.FOORC!]&(^W^L)O]/:^K&6@:60M!L(H='^D;O`UTAQ"E&+P( -MH/KT)DRM81_^)J2\LH?762>"PO#[\R94.R`;D -MNE#\Q]57R/QTWIB92*8`\A4VAD"G_KP+/XD>MJ!#>0)14F+\Z_B8'/YZZ$G' -MWI]N%SJGZT!$D=%K5Y)"C[GO=#>/.QOIWC9W#!8RG9=Q*'9GMG*>`P_+,D.JX48:LSW#5P!G9!9, -MG9X"V+GN9,G`495VMYJ$#J>U.^\;H1%PC,?D8[P&A:I52ARI$W]\@:H_H^6$ -MZB<+@NY43*=_71K12/NKCNV&WP8B_CO2_Y(&C"9ZU@`"\1)U@0&>$.V5_T,H -M)$]0%526JKI$R^`V9E-+`%-WL$H*%%]$?\HKCHI)2O]:#2DS8H0Q-MO))>JU -M%]DD:AABF6LHC-(#S!,$!F;Z)>Q-"^V0B[S--$FE.'I$IKU?TU?^ZP76?R\KEK*"=G:?=OIT9$XG>'1[U:^B#@GV66U.2U -M^+9E[%\HI7E!2SMCBYW#[3%3I_C/O+3N+68_X[&G)/K!@GSV/_K`\.&M)^Q_ -M@N_#WQ6?LPT:4:V']_.W_S^LQ_7C4Y(=#7UTCUU0Q^WE/K,-+RC6!XQ=B%H6K@ -M3L.]'G+75@N+[M8MN_T,7;F>67N05E`VLCT#%B'JT6\YE.RJ-"9>)'HQ@L_= -MEX!!O'2&PT -M<,1^O2@V)2+L)+N_2),3A9>;"W0KNQ[EEX3:GW72U$/L+N(]I6Q:Y`?;;$^8 -M2;1-DCI?/M_:Q#F)6J9@S3AVK&'%="1JVED8J[L'V5+IN3S"G;\FRCVU",[^ -M3EF1V5;%:8(:K;(2E>Z,/#S.N9`X9OWDC%[*H93)H.F#03&.ED]*9\0]!>.T -M;*T_S`H;WF$'M)(MN9%;&8(\0_3!\]N)*Y/WP[P?8,G%OSYGH)KZN$TP[8R] -M"M7>YO4CPQ1YG2+>Z<,J087;LT)@6)='[^\<8S[32.S/MRV,A=`IJQ0P9(VQ -M-)V$=L).A%Z^88'H#K:^I,?**&!FHUZYH4("HXS<2^8*OD&P5^4U;='++U:D -MU0E+@<^KE;\PJ9J)<8%1*G*L-3R7&MI7J>JXIL5)"QY>#+OB`UYIMOIF@P!: -M0"C.G2+3I$38FQ;4RZ!C314L#/>*C$,PPVF":)@7PQO>.VC6$V2T"]3>%2LB -M;MA->?'\RAX0/M!*7PS=G3:MFELQ=H#H9ACS@_,S8=Y)*=_*6[N9G+23VS]U -M+8VK7R:G@:9HV -M^!%@"&%?H\F39"TI"/';*$S-FANT436*397$&@;*?49:4\U@HN6Z,3VQ,G[#_-Q;5QJI!4SAWN@D>2V?0!>-Y'S,W*DS -MQS#M]*AXS:D7EBNA?9`K=^&(Y68V;C@Z'S18J?9M9)C&FZ#Y^`'4T["$B(>M -M0.BFV8,]W[J4BTSH&QS:B,ZTD#:MFV,N9/[39>*O,RW#V*GZZL-G>_8Q+_,. -MQG^,M0J&[ML(GWW*#66DTG1L[RW'1>-5OE%)2/LA)G5EI(OPN%GKMSJQ?B$5 -M#M+^EPMH$/;@@-"OPPO;4GW,&7^J%UK.D$T3]8F.'9\ZJ!@`H1_TL9U89J(Z -M?>MOC8(.V^/10U:72UYIG#[Y4L6^3B\6B0.0)4$B27M?NBEM!;%)[38#V4J! -MU*07:IF&3F?$?N+QL",V)$N%T&_E<*&U8Z4EVQOX0ZJTLC1-@'(,[HM$+DY= -M*!G'_CWS*AJ3]5PHHWZ^+4NUQ/[B9_&&7W-(;9#[Q9A\"DW2M=B9N[8SKU/F -M42BOIO09,G@L3HN7:DYB4V;=(V2\F_[I6OJ$"B[.7`W1BTR2_.DEQYB^(,OV -M?%TC?4UI.BPYW5Y&)0K23O[R;2]@*BZCSW6(SEEC!0]AQ59V,"K\HN^91M"3 -MRB?G(S4Q?Z<7B[@4F4%?"&<&CEA\;CTG2V_&P//MP,R[;J-EBQ#Q?*K[`^[X -M8O%;M1EV&?J1/OM>(`<;24N_347<;P\?>'/EA:*.'^Q>Q,.S8;8@VQ7Q6Y,6 -MPVVP459C]H?>22`PV["=?9^-&_5EZAER-M3Y -M0?M8,$2"R,W;RG=L*Q/[R]F/6S]"2:R4PS+\,C80SEN(?NOW2;#4;!:AR0MG -M)H#9F\`C;<^4)"89AWFODI]VQ%1`J^-Z<[/;2@;)MAR!P1%M2D\*SO7F99RF -MI/W#DM4?>7")JV'6>HSGHUIGM%)81BWB\[^!0[).M"'69`VAATI"[?LR0OKU -MQRE'JH%17P`YD;(5S-"]&E&)3^"51M-(S1F.V_;]A8ALF_&+(/(.KD54"]&> -MJ8XG5T@9X7M7"'V_ARBQI/$#A'4I9L\K[!P\@9R26'BS!NH_LB%L-89/LH_Y -M30P*"F$V=$VUD.X0IKX&01FTBO21"/SLCA-9W9P,!K%J[4`@?L&B"X1X4K'Z -MT`?-A#.AM5[#ZUA%0G>>+\[R_@D^/7"/^/U1YNH?A1069N,^,[>!3ZXK/4BE -M:5!`KDM\Q!#)##90ZW?[>+:T@F6(4FN##YR_,KIZ$D8>\5%PQNA6`-NZ8%EI -M4#QS`QT2[$E^P+EJG`$>^VHM*(4;4B0,K!#>Z$@VUBY,R:1=O*6U!!"T5CHQ -M'_CJ/XL_?TB;;3:L'\X&\5JEZ6]7B=,R!=U#AIR\"FOD4+\>##"**QP+A_Z& -M"$7#Y_'.UJ;9A%G!.1[`PJT>9I@&"$=)O\P8R+\2U@ZXM73ST,I;1,=&$5T\ -MH%!42@!B#/Y$V86\1SVI\]1Q*@5=S@\=D,)/$Q?N`#4;OETCTG:0^9MF&DOQ -M$;6`3%NB7@HQROJ!5"!7+9,C.:$?!A$5.7&$]0&T/.AS\#MWQKB%"C8T*P+2 -M,_!S@_=U_BL_?2LSWBE -MB-%+)[WYEFLOC%BVLY,0XO%9P[5]0SD@\PLN4#-S)EMHT6%0G'&`N6GBE9A2 -M78E9_5ECTX]DQZEF\9,JU7W2A[K[V`SO`9J1F33&A'6Z=EFWI$;$[!%Z>X%G -M''CZ_-M`,>)-[,U>>C(1MB2:97STU)WP^*H%+^$CG"&TPNMMS+I/4`8S'&A' -M5+^%&VH">:*MCN0YS;0AJ/]3!F=JOCSY?%Q;:/U(%J)O"+V2'%&4;_-R,(<@ -M!(FW;/E_-Q7KAIDY9IU+VY,H,Q>D=586\7I&4PIZ!&991[*/\9)6)8:\2?LL -M2>U:G<1."T3M'P`E56T#R!"-A0N$]?9IFLDK -MM5JWJ3)ZEN/\\TV8&:=0F+L7NZ9&TSE0VQ9ZP3[6T8EZ=2\@,U^PHNSKT#+: -M7_$MKFW*N70FPU"K1=YMO`Y^F/D[XG'W5,-T9.?W(6]_`60W:% -MM$OB(^C+.XB,G3A2#Q$K'+,.M)VS)%<^0,J>D3`%8K)$.\#W,29YYBW=?J[E -M9;M5E5C%E=FR1QAIT0I?@Q&SM]"PDD]]12'(#UMA5`;O2*-1F\/>W4MVJ-M= -MGGU&[O]JK70G[;;D\4ST#JFA53RAJ1H>.?(8'1>SF3D&'NF06&#FS"E*!^,[ -MED/)T85@RG,1^";`G#%P^\_!"3S?/_F$93%4;9[43=U#T,5SDV;6N+(:1)), -M3SU&2Z_?\P8]5S\13+V*;L]8*SQA5UW@>N9?IHV5@>][ -M=T,F$NS>%>WKQ'5_AU^SO&E\0N-7I4P_9KRU&)B)"#IHCB%]\>&@<4V&"\'G -M97H.&/$%\V5-LJ+=W_UV107FHO,J&H?1J34B#CC!4"NQOR65*R:5LW?%0M\? -M"UD^P:,8E;NB_SM*5O%1P;%+1O$;FNV\483+/&K839F88Q)?:=6)IN$W8\J?3$7-AEZ2:QIB[12.R)QN3-?+ZTS#G4S)^ -M[2H#C"F'CI_VL2[$D&3+5::\EHK1HT2^%1!:[R'DZHNSZ(S1M"1H-E71GPKV -MT)"*;2VP\T5M.A#%J-])IJ#,"XXI3_*W3>"1F\PM\,YXU@4,!GM#ARJ*4#,^ -MCY,_>F#'VBP8B]%AV5<[,TH%56CA=ZWYRZF_+N%LI&P)2=(CRVE"#+X]-OBM -MS3&+^$(&RPA2ZI2^,^+#L>NX@U,;^J9W4DX2:=B1YOKL&1@)W.KT5BW1YM!1 -M#O(IFA:]G[?W0591CR^7X^R4G4I\NZ^%&=M)]X1&C[T2O78D^P_*_XU3686- -MDN5_Y;.W._(RY1XA"H386^J*UZ"PO&UC);$@M.+B^7RU;&V=T:A\-QID<6V? -M1#[L^59P#%?#FDTN^Z4TVU-R&E`;`$CV=:P=L@=IC\=1Y\Q]XE:X(&X-&X)[ -M<=$K9KI;EA#U350UQQA%Q#?W0&&`8R\#=2.Z/WG5SYOZ#HY0_:SV@G:5''GX -MA@NPMUO2.2<<%`70BL:6JA;]?3?DLK&3QYHV&$%8M-.A0T>_%7ZPA#[AV#@' -M?1A%#T$9YQTF2<'-#W6RFT1IUC-L8QPR[*W$BR\H735>@D;L!P]K: -MJ1$(-VC9US\IX'C7I-33Q_+ZJ,7VNI#KZA@UR,9:GI=7(U.:'VY>`JNHU+U] -M,?DY+-3V>B#Z$.LNX]NU+A]X43[AL`1W77]@L"%O"C0:GEP*OI8^)T5'A7ZD -MG5NP(@$/N!)"+J8N]'O0&J0,$]X/]1%Y>]7KZ!W>XS0;OE.IZ1+`,T`(S<@, -MH;_8>6HB!Y=NX!.Q\W9.=W/ZY7JS(K(FBBHA90O/MFZ4;,S-G>SX:)L(Z:3O -M9*E."[T)'9"P&2(= -MD@\NLGH*VO=4J9$2[@.K]27`N=9,%5^M>M/F%7Q>N3@QU3NM=KW)N"S?Q]5U[,6@\'=N_@&HG^ZWO1*(XAUP+C,"GH_\4DT9 -M1]9+FF:&1/BASZLC0EP.3()H)+@ET))V!GDCT;=>" -M'&Y5K(H0H7G^PG_M&:E)*.9,.@:T!U?@-6*8ER42R:5(C[$Q\-`5`IRC.S#0 -M1-$O5^4T,BY"BU$^@;)26YS=ON:Y$"X)4<7;1]JKEGK=F&S%K:!5,/QG2O6" -MBT@)X/ORDXDGS)$ZPQ?N278P5&Q67F@DWH#.-KWW()\UI%5\( -M;']^5EJSY!FE"WC>+,OQ']8*]%B-_EEF;?JNK:+B?IZ@XG&N^U(OA7M.YIUI -MWAZX2_(;"^]5EW3P`\6,]9F'LS369\V"]#*;Y*8"19G89AN#0 -M>#C'P#NP/1!;1]K=[=#9I_?@^8'CZR)=9#V=GX$"Z)$-F>L->0OC"GO!GW0& -M/H"9.H'VXCE_I1;W$Q^6XO/.,C\8+V#U!(G";F%^0#]4@540'?^MCO(?G:E* -M*S4-Y@10BGW;#CY?U9Y$B4U*II59TU_&+G29N)Z#ZQ2:\0>04D/`2])OD:,- -M"*I!_&[9%GRBAL7S+R01=F#8SKX4.DJ"1%U]SD4N25@#QR3(*CV!56]Q3%.& -M;J"RZRBYKJ$U!F2"`L9,7S6D$1]H'=@!=<,*U2$'RPGW$E$N)@1$6U--:O]S -M*<0O"5E@Z&4]ORFEG[+E$--3"3C7*#T(R<,,`P[_FXB2[L*2#_<]<([=.E0/ -MR -MB1_M0[`B,7'G0O+J6#?WST6#7[9?9!]S;GVM7[L";#JHW0!S8],RH7Q>W4?[ -M7FRVRNRKVZNA)-C[*MVZNA:P)U7]6&-NQCBX^M4XJ_1WKB%G(Q1.R.K%9"7Z -M((K^4H>ZN2XLP_QK]H?=@U@O"*C0LW(MYIFR"4,NU47CJ>(23=_^9\=_L5_!CNH/V?_`)J/_*(I6, -M@'W3R\]!,/>?Z0[>\C]\!6<->QEQUZLIT8F"S86-;LSRBG/=[H(D"KZF-Q:N -M:C))T!LH+"W<6;3`LA,V6+--83_(P:`#V'C'%=.A2;XN*S[CG+Z]82UE=& -M'WEYM?@K@I8.$I!0*9R8?@5?O>WOV'[2\A+[Q>\K^PB -M`Q,?S&!ZX8;ZA9#XUZ/3)(<"PW5#6PL?#!<[?!K:##&(;-&'#3`DK>N$FPE# -MY2X&DXY)DE!-UQUX""]1;#'1)%&MD)FY;BV<%&`$UF'VP79!S).(`JQ9DW(PO`_"F['`AZ:3T`/$1NS"F3.4@:1[05JP/5G#*5*"K8`^ -MWPU!PFCS](K"C0[/I**I>,[R,,#:?BS2/VU[&8M=XKAK&E%Y-B+"\!-E -MHC,7,ZD(].$T=OO$D3NIZ&#`)<`;$$DS=W+UFX1QYGI%Q]OSK8>Q-%N-^;'#7'\RG#80)HR]+9U -M0#K,-T/PQ]0A)&PQ?TG3><6-;&3[.5J<;BPAHM&,<)1J..T`TVJ^3$I3-;U# -M[!H.X.,\/ -MVL^U"90QM"=]>!A$P8O8`'Y9!=9B\+&H&3=_@T2214YR@@I!CIQ>EDO"^EOA -M"N-"C"RT5R3J\FX8SWLX`!T,526:9S)07&( -MCZZ13P#6.MD?$U69X0HX++^Q$YS[`#K[*3A.@SYX)T5S3?4&';1R(*SD?;T0 -M\'`'NE`^XQTNG-$&!$R81(]+93DC]G0J7L*.A+DU%,)<3DI4K["1J=\HMPXS -M>=C4*>OC\N%)DE\&^GFMHN>_Q/`B%+N)3(9J=:[G6:BXW`,O[DCX+^[M; -M1YZYJ!]G.()Z?&XE!>@#V7YY`N9\\"D#4K^\B^6L9%@`K+P<1#<]IR0/[11; -MBW:Y&^`J$)3D&=U>;B30LEGD,>X48+-:Z0N(+F'_31J(E6);"EC:!9.I)99U$I@@DCIRS3_MXDRID,\ -M&<5!=4AP8>'/N^0!->+:7?=_,LZVC@2[I8EF"4>:X@=5&>OJV(X?_"'35F,= -M*DJBHGM?X4249P9SM.F8H6<,C44.9:@HM3A$%1[QQ82[0(<::@>@#BT^K -M$0I>/ZX2[]@.:5-3@"(S=>&NB_`Y%%=&IY::9J"98(J!@38056ZF4#"9"C-$ -M!YC^OBN.;&GP-/48<:$CRJ^Q+0D`G -M82Z-8;A)Q?-D^WUFC,VV2+?J7\G^KV"Y@8]-EC)B3!"W_47H4#11H3^&KP_Z6 -MZO8_YK1/6-5BQ/_:"C=`7(3TR52PM_NA9=-+*%O\Y;HT0UZ8]K_2&:+F@[5L -M?25FG"M=JAQ&6FT4FS#3S-QB%L>9V9SWGFYYQ^SK -M1@AF8T[`_)$DPL99\/3UGM002C%Q^49"-CU$H>O<0=+:B@MTNJ6GCC^=4THG -MU294G5(<,(V]V9N18TPP">NN4Q`?L]Z'Y7F([]Z(TR4DF2BPBI[FH&)DN5C. -MEVV"Q8=]:\%F&%&(Y[!@:[D=E0X@LLN$VIKX9?9TB@Z(@]YLS=,+G`2U]6-AJP4V&_&0HP]V^CM9(FI6[&/K\!72$VC;4GWUL?"& -M'::-05]#8VOJ1EZU,,S-(N(A3H'"3N^OY?6LEXM[&^H;S40-:Y -M&&V7&FV+2""0W.W^9@>PR'#%9UZXJ8;(4;(3=0XBT(QC'9"0 -M5`V05R`VZFUF;)F7P=_;CZ]1^AK!Y&CF&XNZ<2D7#]$%% -MC87^9DE()\]G%H`K<`>P5Q]XPQXM461IK+E]#F,,Z -MM@9.XP@<'MXL -M''T#-BRZ4"<,M8RXW[4Z2Q#CB809$`9H]`N]N!88;2H9Z(ZV`DCBK9S&O++2 -ML(IG8=+)NAWH!S5FT;I0@=U>QD"Y[53@Y4!S!$4`8&MNBZ.OCX4A=9WJ6JCZ -M:>+E4#SUQI=]S?)(<`;.O]0.8$*9_73!UCA2&9G$CQWRZXAUQV;@+P]O"QP1 -MSPQ=Z&88X$':A`EB(BC#>M(UW`38+@1#9L=B"ZT,[@X#!L```,```(```0)1 -M3SO.F(P[`/Y9-ZVKI-PR`A,+Q]D`!+C%!>V#`B)$["'`'0$296QF+4QI;G5X -E+4%2378W+6QS"@,3JRFO6QUI@`R+1U$F`P4$`0`````````````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_multiarchive_solid.part02.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar5_multiarchive_solid.part02.rar.uu deleted file mode 100644 index 1d77567e3..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_multiarchive_solid.part02.rar.uu +++ /dev/null @@ -1,299 +0,0 @@ -begin 644 test_read_format_rar5_multiarchive_solid.part02.rar -M4F%R(1H'`0#DXV:^#0$%"``@`":(E[$,@(;"\OF``2XQ07M@P)P -M7N0FP!T!$F5L9BU,:6YU>"U!4DUV-RULG"KNSBH>3 -MI(PX'#!UPNKA8QM*13CXV$;FBU+2B9_FLSA(2[)!MK9(-2YR,U[:!I''!/NG:=FBK)X6@-/?7C8_"&LO: -MW=G=UAI*H`.GZ!P!#=9'!\@4;_0K>@#2AH!L6&=R,^6K4R\##`[(6LY-10F+ -M3V\;DUE)T9V#)!,#I9"4SSWF!/L3?0D=Z07#EL_Y` -M8>'B?HO'"2]18EN9>M"DVF,S3#/J["!#Y`F6H.S[5HL)=&M>'ZYVLX#;*>0W -M%RKA(QFO9\7K65_SJ//L>SQS;HEO&Z'&0:B$\FX&DKUY@&=.D+5>Z9G>L(`T -MRD.F=_6FR9IZ4AB.!\@];]2$*2M"PH5R*\=!98;_S1?=`)W5EW3V0W%8[["& -M-IUY278@]YR1<8$1_#I-,FKZLTZ;)O -MO@"V=_TS&X"A"$?=;(^B#5:G8WM70-\N0IOBDY?+?/`Y0P65G[9(]KFRW[(= -ML.&M>L,W%%0V&GD9E_^\*DO<9"-SAD[L]>ACF%'K9*X/OQ5Q_,'@I]L(?>.L -M@8;HRKXQ=RPSB]TDD_V:^_-D7?2Z:0\:4@BLD]F[98/&@JEO`9 -M"GB3B'UD*$Z%7@79,[$H*AJ`2:>YU-AL?'U5IV:;X2(&P_4I, -M;[@&=?`UD:QF%$54-9I>L/%:M`UMBQJKO_H8LYT9;>KC#GQO82_1.;$$?X4= -ME4YTY;MT:Q"5CM<'2YHE-$\=:;&C5YQN=B.X&G3D5FF.KF>("BJW'&3">\>W -M]APM'Z4CQNF+-)3XIKOF2&2?R/MS.44>=14,L7GC?V,W^M^S%A,P$T4W7B3J -ML[=_9"0\GBR4T:)>>5?)-_=HPG0"SD/8H.RH9BS#GQM*G,Z),F -M#K:RA[=Y>72+/W/E_^O''[[=6L]&*8^?_(0'5-AI;??75AV*]&$@-MSW*C5< -ME)OMB*3[^\CMF6CS#G_&--^Z5D3M&5.0\6SH,%9-H?'+E-@$7>.BP"MC82.Y -M<"GW0K,U.H&_;Y2-@NSWSM!D!6S81%9!6&T"WMI"'G4!M74^?)$P833721R+ -M3.A4M`XKFM?X++/F=L!7CB=DW(AN>R!($9B%?%VV!/==;&^!=58\T-=T9)U( -M6OWB)FR!*M1`971C>R;?X\-!B[E/,/1M803X)'Q[UGHT[!&<=29N)FL`&`'U -M9$L"OE]X4;>'W'Y!K`;+`9T\+3`5?!:QZO^0--CJ0$S,&TD%Y>*D#NS7LH.E -MUB^B6D;@F&*AC[R5D/`59Q@)&I1#D<_2RC+884:6H96#^4ST,[RR2_M`NH\&NV"D)QG=;J`-!%]&'O6AL- -M51&>"Q["S_.Q'X3SB!Z.]$?U\7B%_N6#SZ!;L@94+OQJ9U$A!%]\UG$MHIH" -MP0\46?'/@FZZV.WW/X@O2!)O^Z!'Z3-!$;28?<`1:NMM%MW_J1;6^[>+<'WF1E$.C.. -M_.%K,-4::0YEDP`+*;#WK1HCBYC2R9?*IPKA_TL8;N@1?P2'",[,IR3/DED^ -M+8T[--;0MZ,BY+D(.C:SY8-2\Z#72.KX(**6)X<:$]E#I]XV^J=PC(:*[@:J -M1T`'UN`E?-G8F.).[2/@!]^;:R#JBPXCA@B_M$8.3'PX5;CU3/.K+)KXN/N4 -MCR<>FP;_G"0"V,ANUWUB5JH6M@J^DR>_.F3E^8`@W*-RSH9703:V1?!JPW9; -MK(U5S\L6&ZXO2AHM1P-_;OL&3R<@@32G``[UTQ,BN6[3N(.?<+2K6']]IC:(V6FFM&=L]JPU?;1)VRST3;AE\U -MOAAM_PDZV1MPLFK&4FM#.I&6\5'8N_/@K'Q5 -M:GG#.>YQ[#.2""1`V($()-"5]/S'A6`F@@TX_D0:F0K>?D -M31P$"-O+VS=]:8W2'BV6LSMHK@/R0IVBLW07CX(5C5YY-#]$,VT#2B=2E7(A -M"B9I7K/1/:)%GS,X#6D6IAA5>")=BN4^_/4Y;`M%+MK(!HB+:AI*B>SHSC:( -M:`[-Q)49JBPCL<-I-8H#!())G*.*1_$6-"%?DY!V!K@J*4>_/RAN_JQH(>7P -MTU/3-`V5DS`OEVDVMZ1@0`9.*- -MS&"5W#=U;Z"-YJ3'$]GTT2;0/,/FH6<7>L/(X"@BA7_H[YDVJ@X?/_0D8MAI -M196^V3!A:(%W+NY(_%ST[.PXL$7Q$R(*^R8HV2?'[U;WAH49N+A32'#/&RI5VH[)JF&_6*NJ-"(:@1<-.S)V%_9KX -MW=G9;`0K,(V,Z%W!TVUJ[VT4NJ+=SZD7=+*+A8>W,Z79++JFW696^M#+L:&O -M#U)IIT-*>&;;-6Y^JI@&+*XW;ZK-4!*6:4N54OCRA1IGNL`"PK-\ -M4*5U(A'Z=:Y:!\!F5DWI1L&910DQR/;5GG)>J!GD&M"R@"7/R!M`1O2R4R!, -M;@&,276T4CW^0TA#JN[P^4;3-M?P1/Q4]%=N*6A;$P]W^).?&'/L^F,@=<,^ -M[8^9B,N=;#)G7-&QJ#F4YB:"J38VC8P.X7YD=9N0V'CQ.A-HDZ%[/!D#T -MI%I?Q[MCY?:A1@E-.O@U[ZMGAIFN+JLUP=EJE&+!O$*VF9TX$)!#S]K%M>FL@[C8D!++=!0JWFEX.=67KLP[D_'1HXGQ\56F]'Y# -M#^O_H:-2#T]Q^A.1!7(=_F)`YK,?'^"L&P2_YQEV6_5T(#&L`!DC!M5;65:R -MN&:M8GY?C5Y&"_PDYO00R>CUTC)UBMG'!P%0'0.]P7S;=GD]KK+:")?P6F$U -M-X%D73;`5K,[@,]J^+TPJ-?"L4B'X>[')Z-C4=!QXK)Q95(!MMKI%%DK=M`U -MTQ?$>8C&D]E^:ID`"Q,[+A8+$*UIR`R^`&R`9Q?:E -M6CN&/,+\2]K\ -M"Y?'%UE+Z27$DE,6E6#T-Z-)=(;?`#E7/ZUE&T=\UTP7ZONJ1,U+2O1L*1?C -M!:Y%"%^V+^*^V!Z']%*ADCZBC+E]JT60-P>F#3?Q(Q`9WWNEWR3)411L*� -M<(6JSD9W@!+S(^QC3UQ"DO`)2`OU8!U'\#'H]WL-+7OCC,XL&=,=N5/T1V<5 -M[4N'ZM1-M:8OKJ6N76LB/8*]IUCST/1SEG022V0I@E1H-<_RBIIV]KLY%2G: -M\0F@OZ%DY@`IFCHXZ&[(Y@7``;0#8^FSU83J=A$>P!GJ^"=HV\)-+IEW5-Z/ -M-Q"__)]K0]&=G0XAC0>,7*-2>-VTQ*G@T:#H;LSRZ=3:Q$+'C**CG2+.N]"Z -MQW7Y;?XN?:,5@AIJ&#)VSQ!CF,=5>>B&HSRR3G$&^Y).8AZS?-U@]6&ZYZ\1 -MXMXDP:3L;W`DOH4U+;88/4:9DD,\4(DNA3NY)1=JI65BUWU9XBE`L$.@=2N` -M.;#82775E8T3&SR/_=*AQ%=R]F!6:KI-=X@0'B=,'1V/O[-9)I`5Z;@1"EZB -M")4^7LE!OS.C,$]@$L@)MZH+"/>K1`S>(TF^.J!,-B949(7ZB=?:M-(9[C1, -M0BY@#U,=22::T;1"Q$8;0$%;.1)EI'C4;?2UG:13LX"J=*A+$JDY"I2@\QW3 -MREN[8*#11A#H)QD1K?[M9!R*L&WJ2_/UO.MOP^X)Z^L[<3GE+7$W;^7A_I7T -M*_2RVA9_Z+$G^O&-N?\6%C&V*^+AL5_]XAQ]LKV?^X8EZ67(PVDK;`(V:I>3 -M2C2VPVE7^QLS0UZQHL\,?+3M)V6VQ4"L5IPK%E\4KPZGE=\G -M_11?_4MEQ/;E?B8>5VU;/$O+56C.P[%T-D5(BTV'XI],2<@!:Q/UD\&P[5;6?4Y\O^R%OOJ^%4SK/F0X,7-[&U&8/$D?ZA$GD-88.Y) -M,^7X/[C&Y$5ZO'BJS+FC)E"+`CV'IF(70W'8C==''5>CA;G$IG!E1A0&7Q(T -M?T8N]D]TRDNRR4#8L.SX`*N7#D-3P&AW"'2O@D#HE65VLB/_Q^G+Q.-P$T[] -M@"/5&>,\T*C/]7J)$[$'E.ZG"1'.UVD6E6$--1Z&I"&!O0EY\:.-UC>&'^Y@ -M\/&PT>P9\E1T%))B@?0<[(\(F;15!`^A>5%?O)'/+=BF>D4#H(8B/T0?UJ?[ -MPDRQ:\K\[&_,P4SIGB:CB#J]GBRFO"A0Q'9XTDP$UF7_HR/3/&NT\B[4SF,Y -MF\3'&GV>[FDU";&0P\%3!^A2>LS]\FI\CG1G,@^C%]9;/"Y;KB$J7#UGLF,8 -M@L,UGD#.Q\,'/-<8=%0%P^43G/C]S^7?`W"O)X=;U2TW\)$.4C0(BEW)0C5( -MNPTN7J^55)L/V#[W.C``=([5P,Z=R+:X7T49C;N__P1NSEY+RR$M_$]ZT//) -M;TY(1U27DZ[ZD8H'"Z6<`MHF$9';V02-T[3_A.H&]A6O1<+*6H?F*8%0""=\)G/+XY^P#:D:#X1=QGU;+BMEQ;, -M;.6]_U+(:W<9]D*X)KMVS#:H+.KR>D$&W,.64O*1'`\L=OKCP=$-!P=R&TJ7 -MMS<\'*O)&K=@K>Q($9]H^K(W;TB!L3']I+B9:,3S`K&3F1Y/A[^HC9;#O#I( -M"FQXV9,8=>5VD?&C,%I'J0X4?M%*`.S/O1D6HU9^U-/7$1Z\@QLH=4RSO^J2 -MT6A-K<`RBUGQ^P6K3/2VQ.AG[EMB)F6&6V%[9*<'*2Y4Q#!JD*<*2&7MS6-Z -MCS&&7>UO)Z[Z'JS3G18ANV"IT^:$^.D"ET\[VM -M!>8W/:_G]=MK07G8)-H>BX:?!2A4DPN2&N-4(^\J1YSHXGRV@B`W[#C35AN` -M<6GU3#KHPUW'KV(<]FCRTWKDQYMI<"P4V*O$K4PC^QD<\8O -MGA3N?,]0-KB-\)EA-CSDNAU?M0`K[='&"29Z(XX>BA(\0F[>AW-HZAG3XO*2 -M;7:SB9%V&_(3RC"B;D_7VH5O8X)1?7JY3K6P!RX1U*^'W?8@\*N*2^*+K?&FL,VL-P)*A:=-LMYY -M`0Q+WN\\:CA5,&BU!/U8GXU4"PVKN^"D+F1,*]S6VPU-J$<;6][$7AJ@?=F3 -MXK89[$)[:C5(TC2!P2S-QU.2'L.99L$R]XSLCUS9V!NSRX?YMSWV^:39U&X7 -MX#%R8Y@>$'!X#1O4IN!H!V`@?9=:S3#?4(>FV/3F:7/[>3+-TQ?CK,66<,/A -MA2KI/PG(OJ"H:QG;A3#/9\&Y7V8'HR-,?N^"RV6@)N:CI,2^%L(=KN)S,M86 -M8AJ[)NFL:C^#>`ZBFVY?C%M=%Y\7 -M#A/C<7B:'P51I).L$+"0&%&"4V6$59_#/X'O`&@VVXU11V.(Z85M96,`X4^OLW, -M#JB1-S9_#N;6=TO,\9;@J7T!=[T-^`.X'X%7)*1+8B?Z\TV,,.PYZPGD,D?D -MC$]##*L<34LB*?Q..F@:\R5(CVU^]@DKA_ZZ+Z&!K@.Z7MNV8'4".IFU7^)3N6>=0;*C;L7: -MF"VTWB3C.HCXRC6=A"#M#D0R,*!9(GRBY/S;K1PV?=^+16JWHQS&6?E`8__Q'(#8B.K]IH_>5]P"]HE+' -MB8YC]KZ4;_X]BT)3"5XLU[S'[3N8W_DN5V_%PF/N*I35*\7[*OVL6*KV);BC -MD*6]*6\_X.*)R+PF#II"M-:HOT7%%ZZ/,?X'>#M6;**QR_Y1>E[SD(W^+BY5 -MZO+^+@_](6?XTS7J_Q]BKF.7]#)*7BE@,E@*\\9PH6C2R;7L[I$_F&/V;[NT//W9S+4?!5TWU>A7=KV -M]W5T;Q73MU]DO8+Z)?+KX]>$O@UZ5>@767X$\KHM5=-FO8KZQ?/KY97TX^>U -MW'=\(-P@,M`ZI[#W].+D;6-VC8/D9T`S(%)KO[K4O_HB`RYNF_X:SGI(L]&Z -M[.N-^*<7J7`Y#M?H4L23'(D5^'>=/N0,/\T[?*1VMN"&1=59(>\6I/$@87WD -ML&+/F3\I1LK$R_F,#O9+X53`_*H@_F7WOYU\O^A>)YJ]3M%WGZE[13K+)1J? -M/7I?07T5FO;;9>A]%>$IX"\[MU&O4[1?=KW"]LN_"D*IAV*^/9Y6X]1D%%'E -M"!7/U)IO\2-[#L=P*MK9'ZB=G%S,1(GJ/O-&T+%Z&#BJ>&UF'3NG0I0^/4@( -MO&(=P,.*P^@:.Y<3BK#]\RWQ5M@WFS#I\N9"X!S^.29ZTA\R(6>H!>,A$[4, -MXG`[%Z>_>X;)K"#KLXX@UFD0E^8ASN2EYE,,[9HY[UFS^S.NQ+1U5Q6*!"V@ -M/=..,M'K0?:,EVJ>F&YP@$^ZPLDY'KYG042A<9P#9.AR08?@CQ"Q.=[LQ^ -M26B\ZCI\+.#O91^`!8`E.C:'YF_'?!.V?Q52]`28[L?SR!T[B4AM%>289MGO -MMAQ.W&M\>L9HF14!.=X.H6>!R1IZA_$NJ8<9B/,6%@X]P[^,GY&,7BLO6$$Q -MSGA;CW`)T^>&\SN"3313J7(57!VW&4&DB#PW..G*;.PGVNF#Y>&(W>`R\69N -MY\ -M\56@&U*:=X/;@9@-GB?47+!,';M6`F1*=FX;4OV7,KUO%4G9W"V8#56=C)2F -M@G'R6JZ]%033]J;P`D&N_N]Q.5B326#L*K&\;#,&/WB_X=N=;YY.M6!PP='$ -M94S;D\>;H7U/@WU!LJ.^=0Y"9_2D"$=P&;BYYIYVMZSSM@57333ET=V, -MWJW&Z40_=&*YP+/2SC.MD$(!%/^C2UJ'PY4@ZW<@T.6_;]W"_.B73+76C+,V -M;%`FTR#?B:02!':,DYN06VL,%GD^W:WH*]6;6J^15JVED>+TUR_W/1W>PG7/ -M.&;4N?L_DFU[(66H#=R-V,-@LM+.HQ9S22I8U.W($,\NV=]R(]/W8S=7FM]U -M3MB,^8:4+ZW+I3%X(;7DGN&STL"&AJVA%67QA'Z)A=14[>O^@VDCGH%2#F#E -M8SJ#LHA[&I;(1`"A1:<%[4@+G(CA^7RS.J28NVN?LPZ$=#BDT=%T+QM`DNW5 -MXOKG%55@+5"RZKAG8X`OUG8GS)<*%&'*E/*<)VT,F"VG.HIMMN3FA-GF53MM -MOFZM'9)N>:?*`@`(^E -M8#K(C7YKH3DZ5V%'?,GZM5Z?-G9)-B'[>2>">/9+;7:H6/4&WX-[IY9G5TQY -MAE7:9&$G:R6<7D43^5/VXG7P"62^4LF"&L8 -M9,O`)@YG)("C:R'%D/'+]1))#5Z<0*$JA(A=EU/\476:"9 -M=2.&>>2\O[2D%-?(_$UCI@Z6YQPH2]9/9NV*EG8,):D8:^L?Y(WHK![S/4:?@],\=$K]ST8=*D.@K)::PA1C68K6G) -M+0F>YY%[L4-):R]LU8L_0$-?H(D>1'3E^*(]Y]-:],OVJ"?B/61Y1H[-\X@! -MT&.#)U7'_KLTMX+1OD9[8UMP4)-.CQY5GN^QU`PL=OP/[Y\?"66'CF3:X`9$:3),S:'"C/N-_@IW=)#:T%TVP -M\Z^RL9.E^278,@D6ME#Q70')/8M-4HZ/17F:X`YG]>,(]]^]-3E`#E\O)*EK -M5LZED"!F'9]@4'(@MNKHSRJK@Y-'F6I6=9P#A5(^]ZE8XB24=8N^7'=AG`G(CMD.A49V:OW -MF&Q,F48&&'(9U?E&@$/I5:SR'-@)KJ&`@[-HZ>XAPTGOED0+%)G9Q_!0V&R/5_: -MK`5<)OEK''`@?H"E$[8Z&(;6SD`GP7$P=;']92E`;S"E9)/,(X$ZPBH:#O&4P4?7/:Z'&[.3/&81NC/,Q]IIMCY>>$/2.G418N^5JV -MV;R_UR-$%H9^<+LQNN"_S&NX/I9CA\)]\OO\(.P -M[]CE>X]K@^VW]T"CLG7<:7@\HD7W&R5H7&]A;N!367CF&IA+>RNDO0%T-!(W-B$:'3,+.1'( -MM9-#5VFFG;@:@J+F&DY)J$SD]%;`@SIY7!80<,GFC#>(\ -M+8`XBSD,)A6&`&6;`TK!3/+'DI$RCI#LQWHH#H/)(H!"(/E1FG5Z8;A[`L). -M'(.20V%6L=,B&G'S*1=E#F?QCA^IQ.V7B'GB%99*0G"B(O.&96LEE\@YQD"/ -MU)D("K1W83)"26!J9`[>,;,_O';EA<,6%..%,B4J\GY--\+ZEG)"&V1)WQ^` -MS)(1X?X%P?@0SK\!R!1T89D,10B\_(06VBDX]#J,R4$V]0`,LV@=\TMF*X2JF!![Z(@0:[4EEM.D4P`6:_'W/E84&!S")ME`R&L8AON -M08@HI(WB1WPPC8=@"'B8'$.!-I!#AZ2258\P*%T2L4C*`_[N(^(U$;"K%$%2 -M_Y:Y9<=F&6;&MUR/O27-G4+P*U3%!X$;$\.-,+=HK37Y4,RTX)>,_H7DC\DS -M^517YB9X4TPI%XI3D>SV?"K]`H2>R/V!#NG=\=_M3,_G6E)F0#..BUD`)LL[6Q38\CNTW6O"?DV -MD*C=A`!16J6O]9OG9DUMK61%0=I"4@;L3:)MI3VJ3N#L62A)G]&%W9:>1-$J -M0,&H=!;W.0\G-P1ZB.;>AA)@D3;@%[%)S^1BC/(E-3(:_1[/&ZR63KU.@:JZ -M3&(R\@J48V'1+GD//APEUL4-_M`V]"IVM_6:9!>MV+26L.$)R+-&F^.:&O?:Y'68Q[B@A5LCQ1^=:UBK,-.MV -MV;BS8X?8F&KP/^3D33)QB3UO9W! -M'V_?^(EV)QIRZRY@TR8[DDRP0<0P`<;#\"#K8WPL[V!PEUW)LSC;\\JIH3Q\ -M-<$:.5MH$Z+L*8?B_)CJU=5^U>\@QN^%&UA^#F80NQO'LSHYG<%/T -MBQ+3^-JE!O%SX5+>*3KZ&:UT<26>&JQ0^PO5-HSKRM6F.CDE*9#K9P>QQ9MP -M"SQ$50VJ7Y&QJ#P[?&WDOJG`CIV6>PZT=00F!PUDQ2PHT'K^4>"52ASG]UAJ -MZ1S;3_JAAB91U9'H@J,&4,[]R&>86NBS+W`!1-.!0DC`P -M,#!]6F9=YA7E%?$T:I(/=;('9Y'&IF7(]1L]7[S''))836W*,-^BQI?3 -M@.SC+TPW>:_8G'0(271DE!1]O%WB\ZO.KH1D(!^425NLX&8B,\9ZY,65<2F( -M:NC%!GU,WNO7K/#F%3[K;P<;6WMKGN/$X-`*AZCN+@9$VZX+H_?4#(IX^8R/ -M"WS62X5_>X=P4X;+>$C=B>A5!8"^):GQ$9>//K,*U4RS`AN-LP[3<^%QBRT6 -M%F(;D,RX9M-NK5GLF"H@$OKJUDMP7U1,\(V/2L$^U^5F.2ZI,F.QVY.IB^[ZNBC%2#JRF3UT2UC7GH8TXT]D=P]0+?08SY.*D'I5A -M>\&0.2P0&'$%U8V%(D]BS]@&"@*L3G\E8`D8=A66DZ.P*]1O]-#,`OJH'Z<( -M_QA'ME,M+/7)V2:"BI1D=,:&'PJ4*XP<*2.+'.1BDLS?@%V -M&!N>KG49EP&KN#)B0T-U]/Z^&+;_++3B.'H1Z,@5AH`&Y),NE&0Y-&B!UI_3 -MQ.HN_;J]=P4&#]6Z;)>05!4H%N1@CP3I/RE0I$=6M.PNX/2"C>E?:&]/67>G2.5IY&EF?Q_9AGIOJX$= -M46B%^78M27QAK('-?%K0J:3+06!;K[[4I3[2/2+?#$=0/KG_,7K2DE;!X'M)*DORI11#01 -M#3+55LY84I#IDIQ;LB$UJ.70ZVT#L_8QG7L.M,#_%CNB+Y#/^"/3M?D(AMQ,,\7 -M[FX"2X,!L#CI*8H:`[<#N:BAF?Z^01O]P_QH(VXV\.J:?-VO,0NY9/3J7IQ^ -MUJ6P$X717FXJ>["PGIL>.!^[Y-DV,.DFZ_N(F*!5&F&KJS;[11'MS2#GM;$O -M#LV#>TWL-ZR9X8%ZE:+%L\F`-3'[=@GQ<2\.(%G0#W77C`#--NA)8&9E1#,C -M16!0=[X%P6DK`MM,(AQR%,;8TV)-VFV`\8R.V/C!`TVTP?#,%Q-M1IM(7`^` -MAF8FTV-C;)$-L(QQR-.!-X;S#>\4P)O)DPW-H;`A"$S"8!(\F$^W:M-`X881 -MYGQA#ZXKH_DZ -MJN]57FJUWJJ\[[\UKRK]K2N[Z5]*^E_%(NY#/L@?)D""=\>#-Q^%1`SD7>QY3?,A*Z=LY99>/T@#- -MB,-L*%\$SL9NA93)\U2D<#`?*:Y]85",,5MB<&92>J%W -MY5&=8;==O(BE3BUZ-\CHCAZLK,Q>(;2F+&T^I1;4`4!AEX,F$-(>9C[^F(6( -M8Z".LOTPB9@":`R!'G&N$#T08_XLYX\>"(&\9M8R9EHE_JE1E#PSN<^K81=' -M=22'&-.`AS8CJG(@CIR7G'JXYS"U!.G@X2Z[SQ%&_>DIC6XOC+S&W7(,S[RP -MX;:V=(K\YU,SD4^_)SG!D9L^<$:DL1+R_9P48&9"YC2O8IH) -MRP4MY!9D4Z/_X2%&P5$%H?>V$I1*QKMKY!I/+RJ6&RC*6$(C'VR7D\4M<"W# -M$7A3"BF_L6V]%^\XEXD\7Z;[PCAR0*4(G.W`*8"]1U&-Q- -MK9S3@J$X<$AKW]0HW?4SKFVC6R1H]=@A34XPTIP:/--Z3C#L233C(5)U1[]^ -MZ"TQO_5,$-A+NWSPB(@">F+V\O[_]U.N5TOAZW`#5!G\*\-%'0)J!/04B!T] -M]VI@EL"ZBT(T.YN.GN0"SS7A#SKBU__C+C:3J\]2^]=-^LYI\_A9<:;ZH-?S -MQ7N(;9U%[WAO:>P-M=F%JP,7!12+["U<+[>8D:CX8MV;+$I,L*C(S5T@O_)` -MS*,VO#`0HUMS?91RD%IO`%IC>7QN6@7:B^*\@X=Y3;%?$XN=3$#>?;$6QN*W -M3K6$TWJHKJ/6\9Q+5?8D8MK@JRG>J9JQ5P:R'[6AYK?>JY]YXA2$PL#;*_%4KWI" -MT;J_BZ.^E!GPW^\Q4'7(@]PFOB3[MTKTF<1[!;+9:^B%?XLX:E8%QC`UD+72 -M8#@S=TF`P&0Z0`FE@#WW(LI+?NW3C(G=:\!$0<^3NGO_,%PC^YG<3-7._B!, -M6"@0#3&'%#(1[PD>5"ZXN4%2H4)![\KFG4/21/A8H2S;0=0]TY2N8TV4(2]$0&+:T"4> -M]T$G-#(.+>#">KP84U*`0J([5VR"3:J497]W=N:1U:J.!'9C -M+9Q[O-7^#UG1&IL5/-33]J6"E6RU"8TG2,@-WN6%B#L,]),T]'6=$@&-J1Y< -M["+-DBGJD+YCC%ICX+B).E$AF[`<)TXTXQ.X;`%DODTCZZ6I&(@:)`U)\S*I -M0P?`OH;.K[C^YMI`*VQ?8%3NE6M52V-LF&N?3,%GO#WGMOD7>Z>]],^\P+?C -MI)/[&4^BS#!Q])R)F8BSP5=?K\U?#/3?:7DHNA5S?)$!O?6DUII_80,!D\O. -M610)1K>48*58I<*&DDDPMLMO8YJ6/_=>V.O+JO[+_#A/7\,[P@:?4UB6QMHY7G'IN -MTQH=&?Z@=O>S=,G`N9Z03B/[H=P>*J16S=(.`PT6$>ACZ(% -M)'O8,77HJ%[`+H!L*`?`.#>!)A++M,4\,7TS)*S;5:)2AO>WB$VE'*N9W[%] -MM65,OSK)P/H36!3_6L'&D<6C?]UD\>:3U'^U2ZH&.FKO;NM0>XLV#J,(QC,ZQ9-7H"297P`)W\M,$.^TPWG!;EZHZ8'?U8BI*+.2 -M*,/XE?'AOQ&JI7\B,;T:T8TJ- -MC"X6W'!D(I6BG@PTD/<^)[9NFBPVZX$B>%[4F+:2>+6'7P9#U01Z]:! -M%#TXL4`XG4.0M9C -M`[V))HWIY*@JQ:E[D<>]#SRQB<"QPN]X_MF8Q;>8@:V,=&<;D5A8C@QV:LIH -M/68XGK%:JQ![-XA'781R:JY#9^L'>/?#:H;A]<(A5F[_"90U[ST`51UPTL4R -M1_C;:/O67$)LA1NP7*KS2!,EQ*3^[R1-1:P\*P&4VCOH)%0+W2;O\L)"7MMM -M+@ -MAPK:,L"/PDM`XXHL:<*NICPHX'<&W)0)-,SS&#^K[_N.AHD4Y4;$#F$O#'); -M@8S[XR'+7JA4TY5[J5[C]?O>].IZQN`JZ%3\UN"W1GSH&YAO,M]2W,LOZF)2 -ME7U[ZY)9:RF_F:),%K?P3M64XFUA*`)# -M(J;NHX'SR[93BS3S/_HIFWA*4AKD:4M*\MT(Z<<]>2WY#?E-W+9,%M%/WO=& -MF;#K06\?7?V02"ESR&S5=\D(M*\3ISYN2C%Q71M+J.<=U\H2;Q44:09`V16, -M7$)?"=F84\VF,%U2BB/5>O\>Y,:MPBTRL(^H\-((M+R$7*&L5F2A&1NZ,AG/ -M!.)W%?(M^?4\UO'L5ZB7L^-XB:-/=?(%5M\9"ZT,[@X#!L```,```(```0)1 -M3^Z#+\,[`()G-YHB7L0R`AL+R^8`!+C%!>V#`G!>Y";`'0$296QF+4QI;G5X -E+4%2378W+6QS"@,3JRFO6QUI@`R+1U$F`P4$`0`````````````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_multiarchive_solid.part03.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar5_multiarchive_solid.part03.rar.uu deleted file mode 100644 index 4ec0e551f..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_multiarchive_solid.part03.rar.uu +++ /dev/null @@ -1,299 +0,0 @@ -begin 644 test_read_format_rar5_multiarchive_solid.part03.rar -M4F%R(1H'`0`AW^N'#0$%"`<"!P$!E.>`@`"ZSSQ%,@(;"\OF``2XQ07M@P+@ -MS>)=P!T!$F5L9BU,:6YU>"U!4DUV-RUL;\CU%4T+;3=`W$;A-^OJ6-[GTJ?4JQ2O=Z& -MG5OU^[=X1GD_R0`YVUVH8((UN_Y)">9W!(#/K!N%G&?M?FOLXG&1$FC)/9]O&W<:1W\3]?M?.?:8H -M8;_O[O^CV@E5O;N@Y%]U7J&OR&BS#YCZ_HCKR^SCZG1`J+L#L(-T;`'J=D`T -M;Q3J[SK8ES;EGWD")ZF]@82QP568%&')G"UR9%>#29NVGV\M).L:F3Q -MP0U*0:3C^WB,M/QWZ'>=W>ST\WYTEXJPE.#FZX93IBY4!USWF:8YEYC%5D$&\Q+V%N,,P@KA -MIELH6$!ET&O6%"$BWT1N7H`WJ -M.#FR0:%9O7`H,DV(V!:;NDH;1S4H-H8YV76H9\SJN1?5Y8UK%:;M3W^!O:-E,BT;E`.Q?W\K?PLBJYT9N)+#)].H4I/42ERJ;*)QOX%KF-^9N18K)Q`\ -MWHZW;B6-I6X+3)RDNQ1;2_1(A&8EP;Y`IW;6+_X]I&,IW,V;X%JXOO+:X5YU -MN1&$0ZT*;("'N0WV)O.V/%X0"9L23KA51/1+>/C[;[!XRKF[D*+J6@-5>PQ& -MQ_=[M)S9A]R^RAD4R'CW.Y$'6_W4.YY8&A:T8_M\E1-TTS(F[F=W4$3.FXXE -M.%I6Z88Z9QE@E,H?TWP,FTTZ6/30DFM'\3+]J0KI&N9+ZE\L8+7$\_D)6SCI=]>KH^!#$`!^"3>M5E'"!>9 -MRW=SZE&,UX/G;*<>4I-@Q'2`Z\5N;EW5ZOS@R#'84#GOE -MP:_D.+P(ZSRZR\-?(C\YHIP9D2"T*-69TR8EC18#J+H"]^%((>_P*D=03(5D -M-=K(S81QI6Z87^75"_F(<9;;R/"C`2 -M5$D11-G18QK&6XHY5+G45J;:]V1J9/>Q;^1-+1K<]VB@;2EOFXH#(5M;A#WW -M[[6BVIC5[/*+OGW+$5:IUYNLPCNY_LD%&V4#"?`70-2K$FV***P1%*T*SA&) -ML^S1MD!'IFQ&M,$EFJ-YB+XIKA>9;)K]?M9M*)=->_!T.CQD,0+UI^P30X[% -M2P4DQ.X'&UDM/)_`/.=WY]Z%'!J4951WSJ:4VZ-=_@PN\*@'SN1?8RX7-4SY -M^BYH)E;OD+]Y,U18\*&A-5]889C[A -MV^EK@"=T\.FYK-IRA[>B[E]SBB(GV14T*='5?'+>Y3TG7$IR8WXV*,<%2)C[ -MM6,B\3*"78^M4E1]\QEC7SM,^S/DMT3,S]N6*XJ]MLW8X"<&&=IOK)RT!]<" -M"$1U9T/9]8XL$*G,T_NO`D?/@?3&9PWXXX0,?C%@VU[X'W'3&&!\#S@HB6/UQ9>22B&(&BD).]- -MSL-AH.&F#=R(;28K6&Q1).KP6-`2TUVT"YG!CS=_=);@MCF;/`Q&\]N"O=Q* -M`@3JHJ3BL]SQ/TPM"W178Z1K`TX#9@N,&7X,(%O1#0%`PJBB0Q(:5GJ0II\0 -M-?1=\`#$"AB8;,T;CZ8FG&\G*8'2L\2V5XS*KR>4@X`6` -M-Q\$,ONLB/Y$/.\/VS7CF'YR',B`"\Q\3G(..R@?7\^!H;J"!FS#1>IO.IQ[) -MN(0P&*D/Q+RE2T/`?IIM&L*=U>P@2[D'!MPIB<8/OB(B47<\TYR0AQV5]Q;Z -M,-#03>-3R9X_S9Y`-%=@Z:+6'(?``U1U[Y">T;S=WR:,(FY5'IZ#"C0-0\_Q -M![$&$\^8KJ(NA3_9,!,O$UJE.7I1H8L431S!6TG0P$QWSPF+YUG9 -M!C#IX4B**"&B$5YY!J/D'P9_XYU%7C'>DAO_E2-0)-!4`0%Z'M*`4V-AH%-Q -MZ.!M4@:\:MEL4RPSJ'WX.<@\Z8OOV^U+T1T&2A"C[(F,[;QT;^LIIE;&.OLJ -M>#SBLUBW>*OI0KF[X@8_3R))E#E`?G^A11PWS%]**>>RGU8Y$CGC)F:B)C8N -M:$P.8\*F@RG<68,K!C8(6L$/P<[`"/3,6LN3S>R6NR(7-&XH*]((#\30;GP_ -M@E1/WD9D-\-2^;PV,/UW^.>(X!5+I=I@TCDZ=3#>?$#'LU2[5Z@9;V)OHX+-['`YWIS04->?D#%FP -MZ0'&1:J^^%E]!S!FQ/W('$J^4F@Q/Z079AQ-U+Y.["MPK&AND+OBWV?^J"D< -MC6PPB*M00&.AN^/?=_,-QBS_I"[&*++$.VT8H`X,T*9^R84&6K#8WN/N@@R. -M/_"YA1=@>6'/-/'OF]D)?*->CBAUZ\JR=Z<6H,@>XS>7,I;469:/PA*+2;OU -MCD2$@(I%1HE3JQ7!CCY\ENC7PU"+$I3H(CZFCVX4J;_;_/Y"WPWMV<2W\U!Q -M:,SIMY'`)&D;P;CM0>`-YH]T>TR.F_4:D:55_1`TT=+:(X_$\$ZTL'>^11H% -MLA9]`W<-Z5L9S+X1\X8J.]\Q;)^M3JJY14?_&]-6?_L`G/^DKV8QRQS#-\]" -MQ#W]3O5%U)>*V[V[\^^9>8]57JW3'OSCU<;)1\5BQ[^?LW4];ZU8QW=JP),.0BPIP:A -M9\J3MICYF@7W9[D7W?X_["4FS;+SS_I,/L7NU+__%>Z=1E2EVN@FS+YV2;$- -M2A>3B<.. -MXV<44ANSLDUMYZ1RUWNCP74W]I4.`XW'"N7+RV*.PEXI69IJX4<*QPCT%+]H -M4*S+2T[DR>!&:J]W3IBZ(&,1PGO!B`5G'4)IKWLG@B.76?'GX1TB4Q5$42#%,J*A:W&1]U)0IT -M.CD&+)#>9!P)TH\RV1]^2*FD517ZY\9E3^6#@98C!*8A5Y9&AO8O*( -MRG>W4HX>F!>B(?XSBD@H0%B3-#%P70#?X2/.^/F%BQ_YI`&JXT>-!`QUO0Z/ -MWP1!YVD+D#K,MW$/E1^'F_3CUCB"'=1_4Z@!G*ZVHCP[G?AGRWI`EMM]'Y6< -M#'Z66JQY[JJCP3W],#Y<*3M8\+N&X_["Q$Y>E\NTL02H(3S+6KDA%UG1-CJVZ?ZP'H -MPG%B;MRX1!K>K'%Z4";R89F7I@R`SZI;*;MM%PWB -MWU\]#3>-7)YG7#1J!"\+'7G]-H)"O=.+X,Y"$>>:%*@Y;DT8@LA"Y?ID,[A_7V3UP><%-V18C"JM -M;^1BZ@&@/ -M'\3M>;SRLRF\V@0Y+=SY:`"J.Y4.]2YIG;H!I12VT!:IV%<[*/.W(T.)K"8W -MEA,CSMP&O]!5C.\$H#G80LO."KT* -MWG&,7)]BK:C>*"<,73VW1\/G/LT80,;!R;J -M3DH%F%Y2V*G!K4CTG13$%0X&&=,JSUSL1YDW#U6T)58+C$9*M5T.BL81P7N. -M0@DZN%35RU6W]_/Q^U^K&CZ'[N;/N_&K?>]'HJ^.=5:ME"EGT%TJ'(I!1Y$= -M5TFV1E;XX0M\L9QDTPQ#SS7J1S$)0LH[1@]P0FJG^\!@AI$#.%\5VZUX-A$, -M_U>8^Z;Q^.Y"&&T`I-Q@/,FHMNN"&E(_`!32K34-5'^+=!TW6-!WL4=0XM7' -MFW7BV_*=`>SEB?3M<:H]MAA,YT%;]*!R%BN,<0&CI!9`>>W$%6-/1*.8JQ5( -M+EK>Y>`5"W4WN@'?TR-[=O-=`I=ABU&?[ZKB>A@39(2GRWFN>;S`G\]^D"YFY)%ME&*"MPW`WO,J- -M'(W4AV9L'AX>6`J.+C#5?&#:;M^*Q@CZ5Q7/D:P;YH70_CRIU'K>\?\?+C -MF-!FP<\)&&=E5T%H^??"_IQ;@1:][_54_N:*]2J\;H*V*HG#\7H='Y51:,FS -MP'H)QU0PSH,7E/4']#\'?-^AY?VO#?>P_??"%Y.PU[AP@Z]'W3YQSU^0NQ$R -M(?]Q!-<]9O/\M-M!6.Q83]]P\?I.%[OXAX&LSP`"SIF+NGZZN`)>L#$J8[D!TGC[L//OUEV.=:AC&."O4X>G2]7-)IAJ>BL#$S -MMMOY&:!R@?J?/6CQ(5N@/=QH^I\RV`)RXMU><7=;F.\D;R470`^T9/9]P,_` -MNNU1'H5)2+$X$ATC#J)&'*`,69Q)D(822Y^XE3P3:?U&:AJ-(#^$1]Z\W:!= -M*-0-LE0[IJD-42"$:C^Y[8X\`989]$.OIX\O?0Y!E9J[T5K,:6?+OW=`IY'Q -M.;&882%1P%"SAD5MQ0ZF?"KU,)0Q%GFQ4(;G0`NE"5E1K0B;+U,M(*,J:P5- -M>)>FEGFXWK$N47C/2;;+FU)CLHVQJWC_]OC73SI_C69!_)M`#(_T/-?CHH6N -MDR\XF&S+W-\H07:Y00$O*P);)'@L.\^'XEF1>E@G%$_;W"3\^*]!?\OB9!"C -M=W16G1:T\H(->%!@1[K+""\-KK8YU`T'2SA`XI`HE(@#>*4=9HL_"BL=$>S$ -MNX/XP*6]'3/GWF7G+L0:(XLU(YA9R/B3;D/TKTCY[:\>*P@8%E!FO4FE4H6T -M8L<6)T%++3%NE(ZR[YE>V@=N)5(BK%4NCCII5J[.*0QZ"1-+T4$S$EYA6E\+ -M:07*86]-J:51!G. -M27[DS<7/)0:%#3TQ,C'LGT>H"^5?9>@FGZ/1EBJ[X<7*)^XDB3$9P1=T)'') -MYADQ?+LF/^):?PQYU"D!1@_J.Q.WKNAT=9%[`.D$5+!#2H<% -MP*LV*T[;M5`K]O_R1HD$J/0-"+:1#NP\-!8:;C<2=TT1>H$-!KD]?XEVGCUJ -M8Y/G?$INL\+OGYH_#!>I&J+/,(UX79@@_&IY4`#E`*P3/1=836WGJETFVZ`B -M'LES=Y<..KZ<5I0#$?G$@?24+JC\FTG21?ADKU90:JU^1,E#$H4\<^]/Z(#8URX%;DFS*!LY8ESZP3T+/#"2UH];O\ZC](,^<>?/XOS*(I] -M^>XOFZ!QS$EIV]NWW*9K`;/;G -M\%(48"7,X-Q1-M*1L*`XV[NO1Z/N5_Y\*V;HSD))-Z,NZ_BV,D1>!3JD%L;` -M0,"]-\RS(E1I8AS<&@3'J`';[-<29#)F3!?<7R+*`/>JM,K"\HZ:E?*PV"LR -MUP^Z9LK8TTA42\1C>&=0&TSX_F/5\EJTXKPW>6\>-NXHY:5#C>)<5?%F'\?X -M5\\U2"&V`.42RSX=XMQ`%EM`_T>'?YC_2W`15N260(S'DRN_^'#O?$(;8M\I -MYZ@*F2I`P41@U0@\-0:M^%]J+;W`TCP->Y/$IAD;YBQ8"Y&)=^%X!_SO]9"' -M`@)Q;Y>#D6'Z_138%-5-*X>U.*:.//C-DD,C(KK+[$-B6QWF*L)T5;,T!RD9 -MCV3BC4R#-*G&HN`W=DGT&QP>8)J_>]-1CS<9=*FLQ(:].H0.VF)%I&Z/M/231KU]&8C)M26' -MZOA.:."<39P))&MKYF^)<>@;<#6==6BZ#6G4R>-?+TG#%Q5[/$.HY*;_"2ZE -M,NLMM[?>U)>M+HG-(JC6+C:__L%*1;B]@O(S>U)<\_>/WT/=LZX+WGS'N[O5H][Z.79XF#<"5>BX;<'\XC -MD9:0Q]@1MW>C$5)I_M[W?!K\-+&@Q"@24&#.3K7@QQG0H[_X>W!#DZ,Z7D_] -M5,&*E]U@3.J#W=W-(IRXYL<,]32V>93K-KSZHVFZ)[,<*HN7^O"A-&`%MW3C -M4*AXL[>X-\A*LDU3D1;U<;ANW5V]A7,PK]OX5*WXJGAX3`?,>$J>?SU+G2>XM -M3/#EB96:DYWIHH]X= -M-X7].;#C[?CS2\3!$31O'U,M(1\U@3J(.>V;N$][YLG8A\Q18GJA;IFY1V77 -M'LX4H#<_UR:_L;G$8RQ\*`K43USQ81\^YF;83$SSH_`TW#!Y]12^N_K'6>">`<6QJ#HB7QDOMA.YHV*R'-^ -MRKQS[GTKSFJT'2\C53$TF)F%_B`FK+[HV'=Z1KKSDQ/90\%2_5O5/V_ -MHNSMW$S""S#+GB9]3Q0MK/'\%G5$]Y[?@L[N]9A[W]+@2S'KN!@G'/W[O#DW -M;K082SN]NKX24P<731:+X)/_\E&+-]2 -M9%@5'@7HSP5+L[$_QD=0%L6=N>-'GKK^=*78D1%1H0UX(/,WH5#/9]M#R!CG -M]ZY?]E(U+DWQD\-ME#>_^,&DX&8`A_-V=O>;_'C4P`BQ1P&GUS -M'RX'+8=[J_-=_T4_V_*8&$KZOEJ_3,*^KQ5?IF5?5_B5.0KT^;_$6NXG)R/3MVXF-"K4$!BZS3SNN><<+/@7^G-1R -MC[Q7O>4X]IRI7LE/A*G]=_^#&FO6@5DU'1_W\CX=9Q\]7Q:PN"LI(7R_* -MU33)R/AW"IGU,:X.J(GO0UG?J::S"P`1,I;CX=+U%J0624@,BD, -M8>V>1;(G,469P'O&WD<)N>VJ=,Q?,F+_2[@P"N3+6-$&OU[D![AQ -MVDN`J!N37\P%!>DW6)8,.P@<0+"^CG!EX.#J=^Q`;<0&:>I32-^@U7R#'Z=]P)#-NH&'*#"DS*]Q0&DW)Z/OSL-N5.WS -M/3^8>797WE\ZZB^L)Z[_VP3/J`\T=>;%_M.HC('5A'5>D("E3[XWH)J7A8,! -MYJ#KEWQ"\\1=N1]ZV8'OO.PV3ADYTZ@]II_X#F0B?GCF./>A7L%R+-IC>!O/ -ML-KPCRB;G%[BT%Q._T0U\0J#"4QGO-[2/EW]G(U>+@X+A5]NHYU$E]P(_LG1N<^OS"T$Z:B/P8/XAHBF$DS+ -M*HG_SDQ9[WOX!H11Z?A%L1>OI)R+Y_MSK,A4C;Z^J2$]*F$=3^BB#J#%]@YL -MX/Q*T2=ZD6>$X[N,'/O)7X+M6X'+2?!10M0I\I2LJ)H'@PY7W*> -M,M<+*#==3+2Z_\C+M_I$J#2A+G\Z]>)[LP/XI?S0D&E32)4OKG$KDT\KP13S -MB'KR&X?]ZCS#WMG%Y823`Z-[>O@45!,K.2MLE2@7EY]GOU+-TV+WZD:-+II, -M.VHQY]PWG4O+$4;T#'Z_U&U\P\SUII-7"$Q+U12^91XM[&4>%RGE-%,=?Z$S -MLH4@JK/P9SR/.,<\2^?PY\[G;*@J.)4)S"/2JT@1+C]0R'0V-1R>K)E"+B:3 -M`CNG)T3HSI#+`B`_"&1!I$0N3,YCSS.7NSLS1./D#I(M+T:2%&P6K)L933*& -M:Q=FDFKXM]SYGT4WI;%Y9%G@)R$I?[U\?M:8K0K^T&71%IP4B\8%N('X.B=B -M9RPO,1E1U!B]K'ZR+9R+>+;Q$)L'_3ZHG>@$W/4!8]:^U''>,T_>\W!PW/3O -M,_3J7*Z.O3*O3*7:Z.L-5AJ7:Z.L\JSREVNCK.JLZI=KHZSBK.*7:Z.L)5A* -M7:Z.LVJS:EVNCK-*LTI=KHZS*K,J7:Z.LPJS"EVNCK!58*EVNCK`58"EVNCJ -M_57ZEVNCJ^57REVNCA`7SV1^O\J%=ADKUC55(BP&-:;'9'G^I#L'!,BLY.P3 -M/H5#(FYPGT$&*YT[?4@8C&R'QTP+CA00.-R*5+<:AM?9@4,B@'-WQ,1`N_$Q -M'G^GS\1Z!ZW`F1Y';!O^WK+05?*W^D3<_1,QMV#FM!&9C14=%_C$QU_[]B,P -M9;?]]]`?XB]?]4H?^C -M3/>9LAI^F3`MUU[BYX"UK4#:1/YH;7"!Z7WZ,5=B^8$G,1#44F))N01,4+YXU -M=U7]^(/O%QFY_+$@7/Y8,:GCB&;FY4\EOR9B-'O.L#'(Z9`,;B&)GIXHC@#: -MR1%F))B(%L`7%;Q8P&^L8SP%,PH2M5QI)BYO_,/_S`'>QQTA_U6-!6@"#JFT -M&)&/$$N7BI0*7IA3NXV[X@VLH$:1TCZ&.DO$Q,22'WH/(].Z*^KB[81E?Q!' -MW$;G'(Z/]!Q#`;G+'SS)D3^0#%[U`]T4VHWI!2&8ALS9?OXIWEYB'^AN))W7 -M",+2"$^9N9]@Y%,<#\!4#O#<&A++EHQS+B,YW2#Y)P(6()A*CM4=.&IMF@-. -M5B+F\J9("CIQUTA(9EKU/>4"=/W"A)J8CSKVW0Z4"V -M4UI#3.+@&,.<0)S!-ZR?64),;^,0S7&DHP9SSA%C6ZQ-_WQNZCM1:J1$Y8D@ -MR;!MDF0%KV/I67&`LVP4W.T8TFF@@2C%T#H=X_+;]Z)B^J]Z;+/H?IS/O?A^F&.)Z?S/>AM`BO&Q7L@WM'N^=&U^'C0 -M-RO*_A1[C?];'F:;=1YB-W1[_AC\^-RSM=LON4I?!HGG -MP:)TN)F"'FC+VDH8XP#CAOE=^>O+>(A25>N<1%ZT=8BSW6(Q^^%33DC>*HBQB<;DSL*5 -M]&'Q(?-^;*LW"MKQ,H3J3@`(46YP!YID[!B7]T04+I=;<3&;D(A-_C-*8B4X -MRCF+=D\^T^-1O?VQN&ESPY@7#B.?:7F0D%;I+7A(C;BF1CV3C-V-9'Q_DB*M -MPV18O]`!*C(A4G57KJ!TGJ#[H%V28(C(`R<<=6KRZM7Y'.MLS31[QZ+=DLL68*4<*T^^*S -MP7;6*EIX,:839Y3B_(M[\E158MFRBDJ=L.@ -MWY@(!*NGM''W -M1"%C&EA/<-[M&7VH/#^N)=1@Q2;KP.C*X+:G.:$U%I`C2LX#V3#49]7.*5U; -MJ=4W9J&:MS*FUME-RM`QSJ=5#!.+TAJ-"K%1H6SSQ;41YV__)43KTW+B6"SF -MWWI"0HX!=5>3*45^LDV?QN:U3?I%GFB::;DW`&@U",=O-./PMSZKVBM!KFG) -M4*:A5'?PT<_YN_IVRF9IF]\P]AA9F6.UF9,ECY,C0*7)3.;ZO.P\-OL:1NA\D<'JKI -MSU-.[M/?;W6%F\R'I.OI<%02CZ[C#3`S.-"N^.2+I)&T49H?D0D.[!!#>##1 -M8Y#12UIG!&=XRV859A6MX0CFW-.6G<4,EB5<><>HQ0J=5=@J./B3<%6N%,S) -MQ/LS3.-#NNMFKD:@#A-=ABHYW$2\;]Y.[35<>:V -M-M>=VO@,(TQ(40FP>]TO;KSY"4F^D^VI,I8%QI`QW?!MO"4DRAI9[#-UB`R2 -ME"HY2U`ZF:;ZH@*AR5H$;9:Z;W`2!T(_*^;Q0/RMAVIB+]TX08S*9#95&KE5 -M_MZN++GG;[S`/E.BD#C(J?F8!^A^G>XD7AG\OT"9`'Z:X?4POP.F;^Z&'U%_ -MH@B;]-!'MG862?%FW9NEP#%GF>P.N.>]Q^912JW;=%1SL2']XQQH/ -MTNGF=`N9\>]+)8I9XWZR)3UJN>HA_L;B27'_"H\A3Q3[U_O*/*('7.NWDO2? -MV/_].%#TP!/7^-NQAR3CGWCMXK]JC8^NZ3'^[=W$"G9U(*^KMI85E:SY'0/D=L\IFF -MYUL&&/IM?R/+,O,^Y<>8YG3./-EWV=4^^K.G0\Y@.9?JOE./F-^ -M:WY[?JM\QQYKSR5_,^48R9*???+CXD=!PS:>HC:#3%'OC'5IM]+P."#S@A*C -MY0J3-Y+SA?O-Z0RQL+.NV]&^/[Q+HRYIW9Z;GHU4EUS=0>H?JL%:QQV+=>W8 -MMVC>W;[]NVDPB&[;WSCP6[AOB-\5OCMW+?D-^2\3,4IZ>7AG3/0O4.OSF_FM -MXL]4#?5MUE;M2:\=X")8OC\7C$N]?*KT:;FVR;F+%?+/X/C"X:QO: -M-+]-K6V5F/C(A:[*KRM?9Y2K1U:R%>/D\Z?9#)CNTOY0DH4_@Y[ZML->U0VM -M=M+0"\;<`UF,SF!Z94]NP4=?__2F,?&5]>'=UVO:!& -M]H`="5*.KU]I:[74:G5%ALB/\9C^&\/YL[$!Q7:\/:PB]3O<`O=94K@ZJ;+8 -M6NS(>P[@>P+_`#8-V*#=&#HE.SOW1"_S\;#J_;PS6"$_--4=31&"$2-=+_5@ -M"&.Q7;`B-;?C[/QGMUQ@UMJX%QH`P0=9U6]G8!KP8/7;7I&=;.QKR1RUE&B+ -M!_J/]3^<;4`R1N)/"P_4=>`^GXVVDCOGG017E;4U8;"B?B0_538%S5U(HO." -M_F/UGJ,0[W`=IICNK-(C8CKL+(>NQ$S[`/010#^T%(Z2(K!>JH?&TXHS1L]I -MJ-)K-`[LOI!XC)9F5VMHJJT@_DBX/3$X(TV8*X:T&4V&4HE7Y/^R.!@G<9%@ -M.[-Z#D>35KM*X^P*N'`S2447,9FB[#LNQ(O@(S9F&ZBMK6"U<[[(W@@SMDDG -MM51@[GZ+OA;()CE*!Z#/;$?\):(X>,W: -M&#&1J:_;5.XL\CAY'MD`\@OX3&!_('T*GN11A#]@.+#(D/G3(5DX\'R/C7GK:5=;@3]R8J4 -M>?E"?5G2`ZV`?R']U-H]%!!!\BKHNAI_F@V=35V>1:8_(FN:TG[@@_U_R0O$ -MH3XRWPAZ`=5-4)ONCJ=31$!9L]*^S>D^D%SH6ZL3V"'O7[C!$MB/D&9$3Y6& -M>;(FZ%A_,GE>T^A&[_)&3^9%LJ8>F?-&B!:E_ZOKME6FET^?EQ,U=E8"M,T>W%(_L-F&\^6S4`Z^UW?"2E37K:4J3= -M'7X=)\@KP.A&%SSH5_P'^B:;J@&F)ROS2KL"@?2PI:U]?1I1_L&2%_);D:5G -MOCM%N]!6;!=$NP5[=DR#^JM;3`&SNPVPF"E>$J'>P!>K6QE3SP1VJ-=+Y_=E -M"WX:5EX_]I;O.4PZ>XM=@:Z%FCBI>KW"ZXRPG'EFP;`D-BX[P.[T1G'8=AA7[O<5+W4KE=F*Y+J)YZ/7(VC*R6/X)PTE -M&\V*IL;4()FC*+:2?\2=X*N?Y55]+=MI7A:-)_G:' -MY%_>&'_`(YKP<.<$:.DB]@R="J>2>/W@?-*S^X@_HR#2`Q1VE@9QGY7#\B'7 -M`0=X(2X8``W(0#BQL*YB1>5-^>F_&=C7`;[M*;.T]/H-/W*,.'(!3\H?PH#S -M9A-;7M//UATM!\DJ!]K!!L5/[N`=(:GQ1YW)3LJDV43G=$`>@]4`M#1V.2PXW6_//-#+'G\@)1_`SZ$SO\$: -MHED45-B3^+]+>23S6[<"?VH^3?GI$MFDOT:]P4B_\*1]H]D@+LJZJKD2+#O8 -MT3DT+^C1I:1*2S0R3"+`XEW]8$R9OZR]E/WZ4OL#=UMB+#=DQ]+JG.OE5]I#3=HJ"8>"&`ORCM0_^C -MV`ZPBK5;UYWAD.;)$3X6>S29]#WSW*H'06,_J:_"9OV&;;2]"T*!VA_^#!6@ -MQ8)X\1&M@/-?AL7S?V3\7:G9M9ZD_EA^_UU&$X8+IABW -ME98Q?VEA+UW\Q'SO:)AOS1O%\T:$]6[4:[&>`Z^43+=Q#1;)"?+(V*MG@CKW*9`)@&>`S -M>):+%@BBLF(NG8_(4UBSKMK@7Z2<<68+W+H[_?NS7FLN@7\C]E#N>D(ZEU$M -M>A'AIW"W9ESXT1C:\=<+F[J/D8G$JTOB/RL&I4@HTO2'72N_6SR\ZLES2ZNE -M'J<,JW!^83LK'H=K542X0C<#P1.NJ.T1/,,;=K?B*-;GYE)#TD_RM_]39]*+ -M[+V\_PP6(#D$%2P26M$\L#A/(SCI.]6QLJ\-*YL+)Y0?`=KLUOW*5I;\:)&> -M[*MPQ.,UTI..D?+]"Y+6+[U%/JZ70?(1/%F8=W]#\6[W#*%'K("[,\L\5_X] -M0^^OT.ET_<9VGPRQ';'8)BR?ES>6-E6F=:0\\9$+"*W(]FA.K]W?RH&Z3-A1 -MX4H?H,]\M12F@GCIP)6[2PPP&1.::3@V1VEE-(;1X'Q/>,`U]GATCE(S]"NB -M3\'];_5^X)VZDE8M!/:;2ZC2:ID -M?ZAHMI@7[PFDYP"J_L(5%H@Q3DR_B'-4BP.\]I:6_,.PDO(K[9%Q5'_U4;$3 -M;19E\6[N6HN,RRK2U_X:N>V47UR?O:M.Y=^?"ZT,[@X#!L```,```(```0)1 -M3TK_DO<[`()G-[K//$4R`AL+R^8`!+C%!>V#`N#-XEW`'0$296QF+4QI;G5X -E+4%2378W+6QS"@,3JRFO6QUI@`R+1U$F`P4$`0`````````````` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_multiarchive_solid.part04.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar5_multiarchive_solid.part04.rar.uu deleted file mode 100644 index efba21d50..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_multiarchive_solid.part04.rar.uu +++ /dev/null @@ -1,76 +0,0 @@ -begin 644 test_read_format_rar5_multiarchive_solid.part04.rar -M4F%R(1H'`0":-0&C#0$%"`<#!P$!@("`@`#=A_^>,@(+"_>8``2XQ07M@P+K -MD6^(P!T!$F5L9BU,:6YU>"U!4DUV-RUL -MN64SWV>!5I_7;2651I*@W)FU^2!DC>VEJ42TL3HW*X8;OLDQ.>[-9?)#V/F. -M*2X(JT=&B/=8&2W*DO[.K$-"7=K=U+R6'K@N=J(/[59-VZO7@UA8!6O. -M`6'W1ZISUK)\P5PW]5N&5U)1_R@#6(3XBNLAEPFKL!10UJ-!2CYD782SXD-= -M:;AJ4ZX.Q>J3#"?35/B.T`ZK;)=L\2ZF@W-\IXE1K8U]2(.Q'T%[6RF;`^97 -MQ@75ZJ:\B'TKWEDDN!?F=1>.2B8C@#W8,32+4SR)@E>_@42;>I%E="<_4D7N -M$=\.V3-DA?^9(+2-27=VTSAH&Q&;U8!S+J)P7AJCSM -MPO?_N#T;IN\"WC^%T6"*ZE*AJ+$_6E?B65;4=EQNVC:;X3#VS>4_D#^50HF9 -M:Z90C4Z9V/+)[[1%NTKB<`R%;WHJ3`-SLS<,+9#_H6E\LW^&S69VSM#=)S92 -MZ302_(!0EA6(+]?I/@A_IP5+G`WB`S[LEIA[A;] -M2ZG)*NWV9/,[IZVQ-&T+Q,U5KL#5_I\B/P?01_`@W:@K-?9QMAM+7*238+O/ -MFQ`$4#A+Q_\V/;Z`=O1=SJ6K]R7&QM+2QS65RNV']E'GYRMG8:^TVPF_65OW -M3*J-$B[^:]="Y6@M0&I3DA_PD'HA\M$=U$ERGF\A_[D76\'?*@HLLK9BRC6Y64Q/M-J=+3Z3N=%WB5]T? -M=%)^&(](=AW-=6+.^#1M2TYRTKQ@7_YIE\AGM+2ZGN.YU&$`7C[ZYZ'G^,!W -M3YWM29OL(`)7H4VU\D#QY_KPFPQ5=9K]AL:[95^S<+'O0@?MKM=MFMN'&>S^ -MAT6CTF:I>YTVG`^\UJ=5K*1]*@Z2=86,L!C)_QCK*'_.D$ZE%5:6Y3N:XX7-8"T7C[3AO$CL!O<91K4"X3\#\U.T?9^I!718:FK[<%8[Z -MN#@&+/:TNESW;]XD3\/[`>F3-R'Y8Z?2=QH'I7B_'"@WJTS^8+MX=EF<>?=+ -M=[?WXZ-`&(C6M:M(-_1R"U6UY,_GJ=]U^0T>:R'<9)BJ,K3'VCP$'Z`F0U=' -MD-F/^$'2W;=-1E,AW(\^^P;/+NB/)=H/ST\B7E]G8;1%F\&9=+ -M(LHZ90E)&JT2'>4/FS`_HNU:A*N5X*='`K_WG>2J\HP,3Z;3SA?SJ?">_16^ -MLF&NP:#MT/7//TSYU?>2[,,=KM%W9:`/Z$N[H_H;0AX/S\.!%96P!R:>=Y55 -M-G6EU_BR0I-L`_%9*P,4?.U]ED7LO@:1#PNHMUK1AU75:TCX6M&DGDNT/^S4 -MI4/1B<5->;A/-Q1L7LWX?$"&5X7\\OG"(*%&W"F<>0G'Q[_-UH,AE<_I-/H, -M^.Q]Q_FHU/:RWM*:Z-,$/&H=.D4AE#[I]L0JC1^?/_M.\>1K5"/GF[VM;WAA -MT/GP;R37:=HU%0):[0B-AL-H)/^L98FI1_`SA8,2O,L-7)F_LJ7WA1A]?9S. -M`%V9"1:3L\OF'N_8J?8/,>7=N61K[+L\Q2.2*HR[WOF%3,*,L\SN](Z -M?-UO;OA2]/EJ7727C]IYUCQY5F+3[Y"[6/L#=&FF1,3^Y2Z/#YX)9\?/75PQ -MGTF2]\GB0"*__<-P)ER2[5NQ$ -MLB=P@'Q2O]94!73ZNU]&G9\BX62Y"J:R`5UK(:N_\UG>/*4X1\3M7U8CH>JU -MO7F81QKS#NQ/='=U0GV*L];,^];MRWECL[62[!L1_=AMC#74$=%P8U.SJJX,I29PIMPNJZC.;*Y1W5$\Z'Z`O+25)\A -MS49445R]B5]MLY^3U*7.>_\?F#$'I]CGK2\YJ59C[(5]K.EGJK6KV5;:*]95 -MGS69IRM4.0!1K\AD,DB-.SJ=N\[MJO`?M@B#:1Z^[?N-%3TV@UAD`8U1F,B7 -M2FX/0`1:77K[TC:5_5U_^P@I=6#@:?3Z#/4[ZMT&PT6R[?9]Q8TUI3[C5]]K -M"=>,ZUW.II:4Q6-KK8OT6ML%><6(IW)L3YL08W8"Y?T(K-O6U;AN!4?VS">2 -MOKPG4RN4KZZJ"9XK[2CP>*=F+_'.3:\9C][UW2[/4+F*/5/?O_[DQ5O,]=A% -MD6WC/N3_0GU(;UJGDS=:6/BGZC$1=F97>C>GO,DJZ/9CQJA0UB5_9#9Y7(5@ -M_Y#2O(&+\TG?;W<(-XO$E:$=9)+"[/FG9]0Y[)/IVE%:\[064QHJ:EVN7Z_- -M)8#D^[BPM3./V,UI8/6[$]A;48@31)F!]UP*V;!,]$OJ_; -M,):W6=PYO^5`/ET"]W_?W/RX:?\8>841$5PVZ$S#C4,F,'J4@[99[O2;2K"59V=;LSA@=OL:FU*-_(`V[/HV4_T4I -M7ROWKT23]KKNNP/L6U$-!2OLJQ\K\I5RQU@$[R$L<_Q:3O(RS79VNO"*_FRN -M<*=V:(=(RDKVP$W_";>+LUXDF_E;^!NK!JXAK^GA>F7]/:=6I'UAAGU?`8ZV.??&*O^W0Z-A -MP=RO'3/J*W<[Q,FUYQ9)Y?T1IU-_CLO/U"">_Q#D-;!4YY[\[AOOW_^YVJE?-XXT?C?_>.G)Y^MOY13Q'RU -MJ9Y,5_=@,C]B>O@LDW:YU:`NB=VE*/M"][T3MS"LOG?+F\&ZY]5I7+3MZYVU -MC=?+@IH%M)*SZY'4IIB_WCQS9Z&3QSCYA,\H^^,Q;/.[UT!?=/\&]W9K]\H$ -MT6>SV::H17FQ$.)J$_G'\[`Q,Q/O\4_ZE_\R#0/^K?XN!\V#C'_6@7.4L]B3=Z'\CQ7> -M#D=Q;CJMRF=[72"ZGK8/>I0+VJM:ZOK*,69_=T;7H\:S<;060C.X!VQI8@_& -M!].\+795M>CHSPL:^T2'BN/^I8CS*'Z>^PU6!^E-P(?M/W&4"^OJS;CRK=B% -M$"OU;E?STPJ,=/IF#93M,RONM8?Q/,G^>_BEIZRWU[!V?27F`(D(IE) -M=T-33SW';P5;AJSW[PS-,K"9OJV-[[!1=VTNZ(:1QT*K=BD-/V"IJE;Z9WGDX -M`%<>8W,83#/YUY;9!8@%]F3Z?ZEY;ER%`I'<]/+O\Q+S7'FJ]/I2:Y$^P97[ -MWV#&7E;^67!2@M'3IZK_I9"_FEW2[UL"2N&95EWKV7O-V)\>ZN%S#5Y+R38K -H/9W66E.Q+(N>XP"]]!;_)_1#+2813H\*W_]K2Z?M5Y0==U91`P4$```` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_multiple_files.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar5_multiple_files.rar.uu deleted file mode 100644 index 3fa8930c9..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_multiple_files.rar.uu +++ /dev/null @@ -1,40 +0,0 @@ -begin 644 rar5_multiple_files.rar -M4F%R(1H'`0#SX8+K"P$%!P`&`0&`@(```Q:>PB<"`POD`@2`(*2#`L:R$WZ` -M!0$)=&5S=#$N8FEN"@,39U^L6QI:GA#*\6`!$&149R]7!6]2222222222222 -M2222222222222222222222222222222222222222222222223]_>QS,[=]KH -MNGVI+KKMQN[YG1YO.?)\8S,,Z9YISXGZ@`@`@!L,/'3AMZ>?EX^'?W -M=O9U]73T<_-R\G'QUL[&OK:NIIZ6CH9^=FYF7E9.1CXV+B8>%@ -MX%_?7MY=W5S<6]M:VEG96-A7UU;65=54U%/34M)1T5#03\].SDW-3,Q+RTK* -M20G`@,+Y`($@""D@P++KV;Q@`4!"71E -M;SGR?&,S#.G,-:<^)^H`(`(`:F'CIPV]//R\?#O[NWLZ^KI -MZ.?FY>3CXN'@W][=W-O:V=C7UM74T]+1T,_.SVM;2SLK&PKZZMK*NJJ:BGIJ6DHZ*AH)^>G9R;FIF8EY:5E).2D9"/ -MCHV,BXJ)B(>&A82#@H&`?WY]?'MZ_ON^Q[HI<*6[[.*%`9^&`%LZ(WB-`0Z$ -M+6!8#A$[=I:>$/SLT`LP`MG1&Z1H"'0A:P+`<(G;E+3PA^$/SP"W)P(#"_`"!(`@I(,"V2.QGX`%`0ET97-T,RYB -M:6X*`Q-^7ZQ;T#T``\G^;`$0=%5&+W5]2222222222222222222222222222 -M2222222222222222222222222222222223?M^W[>QSF>.F[VO"\=J2\Z]?EX^'?W=O9U]73T<_ -M-R\G'QUL[&OK:NIIZ6CH9^=FYF7E9.1CXV+B8>%@X%_?7MY=W5 -MS<6]M:VEG96-A7UU;65=54U%/34M)1T5#03\].SDW-3,Q+RTK*2]3W!#?Q#9>S$&#J;"`FDX$V"95@TP3;D -MPGC2984NWA$H>#3P`Z&(":3@37)E5S0\:;D`-I,L*7;LB4/!IV`=#$!-)P)K -M$RJQH>--R`&TF6%+MT1*'@TZ`.AB`FDX$U2954T/&FY`#:3+"E]3]\$?F.5' -MWVDCZ;\1\Q.9UASN?OW#G\GZ@`@`@!KNF%E5/3S\O'P[^[ -MM[.OJZ>CGYN7DX^+AX-_>W=S;VMG8U];5U-/2T=#/SLW,R\K)R,?&Q<3#PL' -M`O[Z]O+NZN;BWMK6TL[*QL*^NK:RKJJFHIZ:EI*.BH:"?GIV6E92 -M3DI&0CXZ-C(N*B8B'AH6$@X*!@']^?7Q[>O[[WNO<$-_$-E[,08.IL(":3@3 -M8)E6#3!-N3">-)EA2[7(E#P:7`.AB`FDX$UB958T/&FY`#:3+"EV\(E#P:>` -M'0Q`32<":I,JJ:'C3<@!M)EA2[=D2AX-.P#H8@)I.!-0F54-#QIN0`VDRPI? -D=?O@C\QRH^^TD?3?B/F+D.=:AQZT.#3\5'_^`!UW5E$#!00` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_multiple_files_solid.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar5_multiple_files_solid.rar.uu deleted file mode 100644 index 4a8acb08c..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_multiple_files_solid.rar.uu +++ /dev/null @@ -1,19 +0,0 @@ -begin 644 rar5_multiple_files_solid.rar -M4F%R(1H'`0`)[\AO"P$%!P0&`0&`@(``&8R4_R<"`POY`@2`(*2#`L:R$WZ` -M'0$)=&5S=#$N8FEN"@,39U^L6QI:GA#)YW4!&&5492;T@%?U\^?/DDDDDDDD -MDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDO\\YG#6M -MEU>^U%T\J3G5RSM\>Y[K?1K,SKP\_'=-M[V;Z=_QC-9YYK#.K,Z<_!W``(`( -M`;##?S\>_N[>SKZNGHY^;EY./BX>#?WMWFI:2CHJ&@GYZ=G) -MN:F9B7EI64DY*1D(^.C8R+BHF(AX:%A(."@8!_?GU\>WIY>/__O[_/W[V8]@ -MIG"F6O5\HHC7\D(6UP%MQ8#$T:+90ED3*`YM@Q@Q-FR(B6D(6UP%^8L!B:-% -MLH2R)E`<_(,8,3;R1$2TA"VN`OQ%@,31HME"61,H#GX!C!B;>"(B6D(6UP%] -MXL!B:-%LH2R)E`:8=>%?F.N5]]Q:OIMZKYB^ISUY3E[BG(VOBL7^`#MSXI$G -M`@,+F0`$@""D@P++KV;QP!T!"71E#%ZG\PZ\._C^7^`):4S(``#__^_P```4```& -M`````````````+`!`@`A`/_F````(-(```#_____``@`___[`/_=``(A``++ -M``"`]/^`!P!#^_____\"(2$!`@`A````_R4``B$A`0(`@````0```"#&`/_= -M``(A@/\`AH9ML63,M\R`_P```,@;`````!@`````_0`````````!87(A&@<` -5`(WO`M(``O8'&X`'`#C[_X`E``(A -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_owner.rar.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar5_owner.rar.uu deleted file mode 100644 index 285bdb91c..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_owner.rar.uu +++ /dev/null @@ -1,8 +0,0 @@ -begin 644 test_read_format_rar5_owner.rar -M4F%R(1H'`0`SDK7E"@$%!@`%`0&`@`!W:E-^+0(##H4`!H4`I(,"_8VW7"$7 -MDWV```$('0-!@,$2YT>'01!@,&;F]B;V1Y!VYO9W)O=7`U -M-CB#;(H```0MN=6UE\"T@`"T@"4RQ_5]0#O0````,L?Q_T``(`" -MT@"4RQ_=V-C8`)3+']W=]0"-\`+2`)3+']WU`(WO`M(``M(`E,L?U?4`[P+2 -M`)3+'\?]``"``M(`E,L?W=C8V`"4RQ_=]0#V`(WO`M'UV,?8V-C8$=C8V-C8 -MV(W8V-C8V-C8V-C8V-C8V-C8V-C8V-C8V-C8!]C8V-C8V-C8V-C8V-C8V-C8 -MV-C8V-C8V-C(V-C8V-C2`)3+']W8V-C8V-C8V-C8V-C8V-C8@-C8V-C8V-C8 -MV/+8V-C8V-C8V-C8`038V-C8V-C8V-C8V-C8V-C8V`?8V-C8V-C8V-C8!-C8 -MV-C8V-C8V-C8V-C8V-C8V`?8V-C8V-C8V-C8V-C8`(`"V`7V`(WO`M'U`]L? -MW?4`C>\"T@`"T@"4'__U`(WO`N``E,L?W84`C0`0T@"4RQ_=V-C8V-C8V`"4 -MR_\R]0#V`(W8V-C8V-C8V-C8V-C8V-C8V-C8V-C8V`?8V-C8V-C8V-C8V-C8 -MV-C8V-C8V-C8V-C8R-C8V-C8T@"4RQ_=V-C8V-C8V-C8V-C8V-C8V(#8V-C8 -MV-C8````9-C8V-C8V!'8V-C8V-C8]]C8V-C8V-C8V-C8V/+8V-C8V-C8V-C8 -=`038V-C8V-C8V-C8V-C8V-C8V`?8V-C8V-C8V-@` -` -end diff --git a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_sfx.exe.uu b/thirdparty/libarchive/libarchive/test/test_read_format_rar5_sfx.exe.uu deleted file mode 100644 index fdf83af1a..000000000 --- a/thirdparty/libarchive/libarchive/test/test_read_format_rar5_sfx.exe.uu +++ /dev/null @@ -1,7048 +0,0 @@ -begin 644 - -M35J0``,````$````__\``+@`````````0``````````````````````````` -M````````````````````$`$```X?N@X`M`G-(;@!3,TA5&AIP"0!F<`=7YK! -M,`&9P!U?G<$U`9G`'5^1K`+`&9P"]Y"L`C`9G`)@&8P"L`F<"Q -M7YS!%P&9P+%?F<$G`9G`M%]FP"@.1`#HD[X``&A@(T,`Z"#:`0!9P\S, -MS,S,S,S,S,QH<"-#`.@*V@$`6&I%`.CAW```:(`C0P#HT-D!`%G#S,S,S,S,S,S,S+F" -MVT4`Z,'<``!HD"-#`.BPV0$`6,5$`.A]2@``:+`C0P#H<-D!`%G#S,S,S,S, -MS,S,S%6+[('L6`0``%-65XM]%(VUJ/O__[L``@``A?]T05-7B\90Z!GP``"+ -MQE#H8R<"`%F-M:K[__^--$:-A:C[__^+SBO(B\/1^2O!4%=6Z._O``!6Z#LG -M`@!9C31&@\8"C86H^___B\XKR(O#T?DKP5!HH@```.A"SP``4%;HP.\``%;H -M#"<"`%F-C:C[__^--$:#Q@*+QBO!T?@KV%-HL#5#`%;HF>\``%;HY28"`#/) -M:EAFB4Q&`HU%J%Y645#H/>0!`(M%"(/$$(I=&(M]$(E%K*'0#D0`B46PC86H -M^___B46TBT4,B478C46HB76HB7W$QT7(``@``,=%W`P(`0!0A-MT"/\5/"!& -M`.L&_Q5$($8`B_"%]G4L_Q5`($8`/0(P``!U'3/`9HD'C46H4(3;=`C_%3P@ -M1@#K!O\51"!&`(OPA?9?7@^5P%N+Y5W"%`!5B^R!["P"``"-1?Q0_Q6(($8` -MA@.1``D`0^VP%#_=1C_=0CH/O"$``(B&N"$` -M`(3`="-H\((``.CMT`$`68E%[,9%_`6%P'0)B\CH-9X``.L'B\/K`XM%"(F& -MO"$``(J`H6$``(..P"$``/^#CL0A``#_@X[((0``_VI`B$8BC88((@``4U#' -MAK!L```"````B9ZT;```B9ZX;```B9[`;```B9[0(0``B9[4(0``B)Z\;``` -M9HF>Q&P``(F>V"$``(F>H&P``(F>I&P``(F>J&P``(F>K&P``.@IX0$`:C2- -MAD@B``!34.@:X0$`:B"-AI!%``!34.@+X0$`BTWT@\0DB9[8;```,\")GN!L -M``")GN1L``")GNAL``")GNQL``")GO!L``")GO1L``!FB8;Z;```B\:(GM9L -M``"(GOAL``"(GN`A``!>6V2)#0````"+Y5W"!`!1,\")#"2)@2@0``")@2P0 -M``")@3`0``")@300``"(@3@0``")@4`0``")@400``")@4@0``")@4P0``") -M@5`0``")@500``"+P5G#5E>+\;BT-4,`:@A9B_[SJVH@,_^-1B!74.A%X`$` -MBT0D&(/$#(E^0(E^1(E&2(O&7U["!`!5B^QDH0````!J_VB!'T,`4&2))0`` -M``!6B_&#/@!T&(!^$`!T"O]V"/\VZ.'9``#_-NBE(@(`68M-]&2)#0````!> -MB^5=PU6+[&2A`````&K_:($?0P!09(DE`````%:+\8,^`'0;@'X0`'0-BT8( -M`\!0_S;HE]D``/\VZ%LB`@!9BTWT9(D-`````%Z+Y5W#5HOQ@+ZX(0```,<& -MN#5#`'0@5XN^O"$``(7_=!2+S^CDG```:/""``!7Z,/.`0!965^-COA5``#H -M,O___XV.J#(``.@G____C8[H(```Z"BT``"-CB@0``#H\4D``(O.7NDW@0`` -M@<$H$```Z?[^___,S,S,S,S,S,S,S,Q6B_'H>_____9$)`@!=`UH`'T``%;H -M6\X!`%E9B\9>P@0`BT0D!%:+\0%&!(M.!#M."`^&G0```(M&#%-5O5`/1`!7 -MABK5P``BT8(BUX$P>@"@\`@`T8( -M.]AW`HO8@'X0`%-T.NA1(0(`B_A9A?]U!XO-Z'Q7``"#/@!T./]V"/\V5^C@ -MWP$`@\0,_W8(_S;H5M@``/\VZ!HA`@!9ZQ;_-N@@(0(`B_A9687_=0>+S>@_ -M5P``B3Y?78E>"%M>P@0`BT0D!%:+\0%&!(M.!#M."`^&I@```(M&#%-5O5`/ -M1`!7ACT5@``BT8(BUX$P>@"@\`@ -M`T8(.]AW`HO8@'X0`(T$&U!T0.B7(`(`B_A9A?]U!XO-Z,)6``"#/@!T/HM& -M"`/`4/\V5^@CWP$`BT8(@\0,`\!0_S;HEM<``/\VZ%H@`@!9ZQ;_-NA@(`(` -MB_A9687_=0>+S>A_5@``B3Y?78E>"%M>P@0`BT0D!#M!"'8+*T$$4.@N____ -MZP.)003"!`!6_W0D"(OQZ#+^3/;4XLW.)\D(@``=#V+A\!L``"+3A"#P!13 -M4/\58#)#`(O/_U80B\_H22$``(7`=!6#O]PA``!U=0R+1"00.5@$#Y?`ZSTR -MP.LYZ)L'``"+3A!24/\58#)#`(O/_U80:#`V0P"+S^AW)0``ABL-;7<($`+B3'T,`Z(3+`0"#["Q3B]E65VH'BP.-N_@A``!7 -MQH.\;````,:#Q&P```"+<`R+SO\58#)#`(O+_]:#^`=T!S+`Z9L#``!J!S/V -M5XFSP&P``.BL`P``AB) -M@[!L``"#^`%U-H7V?C*#^1Q]+8-][!]^)XM%R"O!@'@<4G42@'@=4W4,@'@> -M1G4&@'@?6'0*BT7L1COP?*?K0HL#`\YJ`&H`B8O`;```BW`048O._Q5@,D,` -MB\O_UHN#L&P``(/X`G0%@_@#=12+`VH'5XMP#(O._Q5@,D,`B\O_UH.[P&P` -M``"-3``"%P`^5P(A%\CP!=,6*1?.*B\5L``"$R70* -M@'T(``^$S_W__X"[Q&P```!U!(3`=1F$R74+C4,D4&H;Z.]0``"`?0@`#X2I -M_?__@'WR`(J#)"(``(B#MFP```^$#`$``("[X"$```!T#8"[O&P````/A?8` -M``"+`XMP%(O._Q5@,D,`B\O_UHOPB_J+@Z!L``")1>B+@Z1L``")1>R+@ZAL -M``")1>2+@ZQL``")1>"+@]PA``")1=SK1+`!Z4____^+@]PA``"#^`-U(8"[ -MM6P```!T#H"[:%8```!U!3/`0.L",\"(@[EL``#K"H/X`G09@_@%=#.+R^CJ -M`0``B\OH&AT``(7`=;CK'X"[M6P```!T#H"[&#,```!U!3/`0.L",\"(@[EL -M``"+1>B)@Z!L``"+1>R)@Z1L``"+1>2)@ZAL``"+1>")@ZQL``"+1=R)@]PA -M``"+`VH`5U:+6V2)#0````"+Y5W"!`#,S,S,S,R# -M>03_#Y7`PS/)@WPD"`%R2HM$)`2`.%)U08-\)`@'`%A=32`>`)R=2Z` -M>`,A=2B`>`0:=2*`>`4'=1R*0`:$P'4$:@+K$#P!=01J`^L(=@<\!7,#:@19 -MB\'""`"XI1]#`.@JQP$`@^P84S/;B\&)1?")7=R)7>")7>2)7>B(7>Q34XU- -MW(E=_%&+R.AN'```A,`/A(,```!65XM]X(U-W&H!Z(?X__^+3>"+1=R+=0B( -M7`'_C4L;```_[>H;```BW`0B\[_%6`R0P"+S__67U[#N+BI30``BP>+<`B+SO\58#)#`(O/_]8RP%[K`K`! -M7\($`.D)]O__BT0D!#M!"'8+*T$$4.@G]___ZP.)003"!`!6B_&-1B10:AKH -M8$T``&H#N5`/1`#&AL1L```!Z,9/``!>PX.Y?#,```!T&#/`.(%Q,P``#Y3` -M2(/@\(/`((F!I"(``,-6BW0D"%>+^8N6_!```(/Z`G45,\`XAO$0```/E,!( -M@^#P@\`@B48D@_H!=0YH``@``(U&*%#HW)4``(U&*#/V9CDP=$-3:EQ::E]; -M9CD0=0R#O[!L```#=0-FB1AF@S@Z=0-FB1@/MPB#^2]T#F8[RG4,@[^P;``` -M`W0#9HD0@\`"9CDP=<5;7U["!`!6B_%7B[[`;````[X`(@``@[ZP;````G4( -MBX84(@``ZQ'_MA0B``#H<_C__P.&5"(``#/2`\=?$])>PXJ!<3,``,.XL"`` -M`.@_Q0$`5XN\)+@@``")3"0,BU<8B\(KA"2\(```.T<<#X)1!@``*]")1QR# -M^@(/@D,&``!3BYPDQ"```%56B\_HLZ<``(O(A=(/C"4&``!_"(7)#X0;!@`` -MBT<8BW<<*\8/A`T&``"%T@^/!08``'P(.\@/A_L%``"-+`Z+SXEL)"CH<:<` -M`"MO'(OPB\(SR8E$)"2)3"0@#XS6!0``?PB%[0^"S`4``(-[!`$/A8(```"# -M_@%U?87`=7F+S\9#'@'H,J<``(E$)!RH`70OB\_H(Z<``(O("\IT'HM,)!B+ -MB:!L```#R(M$)!B+@*1L```3PHE+((E#)(M$)!RH`G0KB\_H\*8``(O("\IT -M'HM,)!B+B:!L```#R(M$)!B+@*1L```3PHE+,(E#-(M,)""+1"0D@WL$`G0* -M@WL$`P^%&P4``(7`#X<3!0``<@F#_@D#@.$!B(L' -M(0``QH,((@```,9%``"H`70EB\_H\:4``(OPN/\````[\'("B_!658O/Z#VE -M``"+1"0+S^C(I0``B_"X_P```#OP<@*+\%:-JP@B``"+SU7H -M#J4``,8$+@"`NP8A````=`V+S^B8I0``B8,((P``@+L'(0```'0-B\_H@J4` -M`(F##",``,:#!2$```'IUP,``(O/Z&FE``"+SXF#`!$``.AA7HP``:@!0C8M`$```Z/+K``#K -M$NB$HP``4E"-BT`0``#H'>P``(I,)!.*1"04@.$$B$PD%G0MB\^$P'05Z!FC -M``!J`%"-BT@0``#HM.L``.L2Z$:C``!24(V+2!```.C?ZP``BD0D$XK(@.$( -MB$PD%W0T@'PD%`"+SW05Z-JB``!J`%"-BU`0``#H=>L``.L2Z`>C``!24(V+ -M4!```.B@ZP``BD0D$X!\)!0`#X00`@``J!`/A`@"``"`?"05`'0GB\_HDZ(` -M`+W___\_O@#*FCLCQ3O&#G!`` -M``4```#&@YL0```!BTPD*(E/'(M'&"O!@_@"#X/*^?__7EU;7X'$L"```,(, -M`%6#[%RXR1]#`.C9O0$`N"0@``#HJ[X!`%-6B]F-32174XE=(.C3GP``,\EJ -M!XE-'(E-_%\XB[QL``!T<(N3P&P``#/``]<3P3F#I&P``'QB3%0``BP.-311J"%&+<`R+SO\58#)#`(O+_]:#^`AU/3/)C444 -M45%145"+@[PA``"-LR@0```%)%```%!J!%&+SNBU.0``B75$ZP.(35]7C4TD -MZ$^A``"#?3P`=0R+R^C'%@``Z;()``"-323H<)\```^WP(U-)(F#Y"$``,:# -M]"$```#H0)\``(U-)`^V\.A-GP``#[?`C4TDB8/L(0``P>@.)`&(@_0A``#H -M,9\```^WR(F+\"$``(FSZ"$``#O/#Z"$```4```#K(L>#Z"$```,```#K%L>#Z"$```(```#K -M"L>#Z"$```$```"+@^@A``")@]PA``"#^'5U!&H&ZQ*#^`%U"?:#["$```)U -M[HU!^5"-323H9J```/^S\"$``(O+Z"GP__^+BZ!L```#R(N#I&P``(F+J&P` -M`(N+Z"$``(/0`(F#K&P``(E-4(/Y`0^$'0<```^.[08``(/Y`P^.C````(/Y -M!0^%VP8``(V[D$4``(VSY"$``/.EBH.810``BY.810``)`&(@ZQ%``"+RHO" -MT>G!Z`*`X0'!Z@,D`8#B`8B+K44``(B#KD4``(B3KT4``(3)=`Z-323H+IX` -M`(F#I$4``("[KT4````/A&`'``"-323HWIT```^WP(F#J$4``(F#V&P``.E$ -M!P``,\"#^0)J``^5P(UX_X'GL-S__X''T$4```/[B\^)?4CH&(0``&H%68VS -MY"$``#/2\Z6+=4A"BWU0BD8(BTX((L*(AI@0``"+P='H(L*(AID0``"+P<'H -M`B+"B(:;$```B\'!Z`HBPHB&H!```(/_`G4+]L$0=`:+PC/2ZP0STHO"B(;P -M$```@_\"=`KVP1!T!3/`0.L"B\*(AOH0``"XX````"/(.\@/E,"(AO$0``"! -M^>````!U!XO"BU8(ZQ*+5@BX```!`(O*P>D%@^$'T^")AO00``"-322+PL'J -M"\'H`X#B`20!B);S$```B(;R$```Z`>=``"-322)1A3H_)P``(U-)(E%5.BD -MG```C4TDB$88QX9P$````@```.C& -M`!$```$```!FB88$$0``@_\"=`HY3B1]!3/`0.L"B\&(AO@0``"+1@C!Z`@D -M`8B&^1```'0LC4TDZ*B;``"-322+^.B>FP``@WU4_XO0=0R#^O]U!S/`0#/) -MZQ$SR8O!ZPN#?53_B]&+^0^4P(B&FA```#/``T84B898$```$_DSP`-%5(F^ -M7!```!/1B89@$```@+Z:$````(F69!```'01N/___W^)AF`0``")AF00``"+ -M14R__Q\``(E]5#O'-A=#?__]0C4TDZ'&;```SP(-]4`*(A#W0 -MW___=78SR8U^*&:)#_=&"``"``!T/XU-`.@O/@``C870W___4.CW"P(`BU54 -M0%D[T'8@:``(``!7B\HKR%&-C=#?__\#P5"+P8U-`%)0Z`L^```SP&8Y!W44 -M:@%H``@``%>-A=#?__]0Z-#0``!6B\OHP_+__^E6`0``C48H:``(``!0B450 -MC870W___4.@@Z0``BWX,*WU,@^\@]T8(``0``'0#@^\(A?\/C@8!``"-AB@0 -M``!7B\B)15CH&?+__U?_MB@0``"-323HEYH``&@X-D,`C7XH5^C\"@(`65F% -MP`^%T0```(.^+!```!0/@L0```"+15B+.`^V1PN9B\B+\@^V1PH/I,X(F<'A -M"`/(#[9'"1/RF0^DS@C!X0@#R`^V1P@3\ID/I,X(P>$(`\B+P1/RB\X/I,$) -MP>`)B8/`(0``BP.)B\0A``"+B#XP-V+VH#6"O#P>`#B448B_"-323H%Y@``(O. -M#[;`T^"#Q@B+3>@+R(E-Z(/K`77ABW5,:\%DBTRU!(E%Z(U%T%#HX=\``(M% -M6$:)=4R#_@0/C%W___^+72"+=4@SP%!0_[9<$```_[98$```_[.L;```_[.H -M;```Z!$.``")@ZAL``"-322)DZQL``"*AO(0``"(12#_=2#HD9@```^WP#D& -M#X0:`0``:@&Y4`]$`,:#Q&P```'HF#\``(!]7P`/A?T```!7C4,D4&H#["$```"````/A-\```"-323HCY<```&#J&P``(.3K&P```#I -MQ0```(V[""(``(O/Z$A^``!J!5F-L^0A``#SI8U-).@HEP``C4TD9HF#'"(` -M`.A.EP``BHL0(@``B]"`X0&)DR`B``"(B[5L``"+BQ`B``#!Z0.`X0&(B[1L -M``"+BQ`B``"+P<'H`B0!B(.W;```B\'!Z`8D`8B#NVP``(O!P>@')`&(@[QL -M``"%TG4+,\!F.8,<(@``=`,SP$"(@[AL``"+P='H)`&(@R0B``"+P<'H""0! -MP>D$@.$!B(.Y;```B(NZ;```:@=?:@"-323H7Y<```^WP#F#Y"$```^$G@`` -M`(N#Z"$``(/X>0^$CP```(/X=@^$A@```(/X!753@+NN10```'1*BP.+`8O+Z%UI -M``#VV!K`]M`B15Z(15Z#[P%UZ(3`=2YJ`[E0#T0`QH/$;````>CR/0``@'U? -M`'05C4,D4%!J!.B8.P``QH/%;````>L&BT4\B44@")`$Y -M-XB#]"$``(M%9(F#\"$``(N#Z"$``(F#W"$```^5P(A%:X3`=#B+R^AEZ___ -M:@.Y4`]$`,:#Q&P```'H.3L``(!]:@!T&(U#)%!0:@3HWS@``,:#Q6P```'I -M=04``#/`]H/L(0```8E%6(E%5'0HC4TPZ"R4``"+R(E55#/`B4U8.]!R$@^' -M004``#N+\"$```^#-04``/:#["$```*+\(EU9(E%7'00C4TPZ/.3``"+\(E% -M9(E57/^S\"$``(O+Z#[D__^+BZ!L``!J`%I24O]U7`/(BX.D;```5A/"4%'H -MSP@``(F#J&P``#/`B9.L;```0(N3Z"$``#O0#X0%!```#XZ\!```@_H##XXZ -M`0``@_H$=#V#^@4/A:4$``!268V[D$4``(VSY"$``/.EC4TPZ&R3```D`8B# -MK$4``#/`9HF#KD4``(B#K44``.EQ!```:@59C;M((@``C;/D(0``\Z6-33#H -M-Y,``(7`="A0:$`V0P"-10!J%%#HS0D``(/$$(U%`(O+4(U#)%#H9@D``.D[ -M!```C4TPZ`.3```D`8U-,(B#7"(``.BFD0``#[;`B8-@(@``@_@8=@A0:$@V -M0P#KL&H0C8-D(@``4(U-,.@ND@``@+M<(@```'1?:@B-LW0B``!6C4TPZ!22 -M``!J!(U%9%"-33#H!I(``(U%C%#H6<4``&H(5HU%C%#HD\4``(U%"%"-18Q0 -MZ$_$``!J!(U%"%"-1610Z"G*`0"#Q`SWV!K`_L"(@UPB``#&@[QL```!Z7D# -M```SP(/Z`FH`#Y7`C7C_@>>PW/__@& -MD'@.$' -MB$X@B\B#X3^#P3*)3AR#^3)T!\=&'`\G``"-33#H_9```(U-,(A&&.CRD``` -MBXOL(0``,]+!Z09"B_C'AOP0```"````BD88(LJ(CO@0```ZPG4(B9;\$``` -MZPN$P'4'@Z;\$````(M."(O!P>@#(L*(AI@0``"+P<'I!<'H!"+*(L*(COH0 -M``"#?6`"BTUDB(:9$```=0GVP4!T!(O"ZP(SP(B&\!```(J&E!```"+"P>D* -MB(;Q$```@^$/#[;`N@```@#3XO?8&\#WT"/"B8;T$```#[:&FQ```/?8&\"# -MX`6)AIP0``"X_Q\``#OX<@*+^%>-A8S?__]0C4TPZ'V/``#&A#V,W___`(V% -MC-___V@`"```C7XH5U#H8MX``(M-6(O!"T54=`U648U%,(O+4.CJY___BT5@ -M@_@"=1!6B\OH"^?__XM%8(/X`G08:#`V0P!7Z)G_`0!9687`=0?&@[9L```! -M@'UK``^$S@```%>-0R10:ASH+S0``.F]````C8L((@``Z&EU``!J!8OWC;L( -M(@``6?.EC4TPZ'R/``"+T#/`0(K*(LB(B[5L``"+RL'I`B+(B(NT;```B\K! -MZ00BR(O"B(NW;```,\G!Z`-!(L&(B[IL``"(@[ML```SP(B#N&P``/;"`G05 -MC4TPZ"B/``")@]AL```SR3/`0>L&B8/8;```@+NU;````'0(.8/8;```=`*+ -MR(B+N6P``(M-6(O!"T54=!.-@P@B``!048U%,(O+4.CBYO__BT5(B45@ZP>+ -MR^B_Y?__C4TPZ*;;__^+3?2+16!?7EMDB0T`````C65L7<-7B_F`O\5L```` -M=`0SP%_#BP=6BW`4B\[_%6`R0P"+S__6B8>@;```,\F+A[!L``!(B9>D;``` -M7H/H`70.@^@!=4&+S^B,]___ZP>+S^CJ[/__B\B%R70KBX>L;```.X>D;``` -M?QE\#HN'J&P``#N'H&P``'<)B\_H)>7__S/)A'W"$``/\```"+P5_# -MN/`?0P#HB*H!`+C@Y@``Z%JK`0!6B_&`OL1L````=!R-1B10:AWH5#(``&H# -MN5`/1`#HP30``.E4`@``@+[P10``!0^'/`(``#/`@[ZP;````P^5P$B#X!6# -MP!TYANQ%```/AQT"``"+ABA6```+ABQ6``!U#SB&:58``'4'L`'I#0(``%.- -MGN@@``!7B\OHU(\``%.-C109___H,.```#/;C8T4&?__4_^VQ%8``(E=_.@E -M\P``BWT(.5T,=5,YGC16``!\'G\,@;XP5@```````780C48D4&H>Z)\Q``#I -MCP$``(7_=0G&AA$A```!ZR#_MC!6``"+S^CXX____[8P5@``C8[H(```_S?H -M)I```#B>:U8``'1:BY:\(0``.)HD40``#X1(`0``#[:.<%8``(V&DE8``%"- -MAIM6``#WV5#_MKQ6``"-AH%6```;R5"-AG%6```CR(V")%```%%0_[9L5@`` -MC8[H(```4^A?CP``:@'_MD!6``"-CJ`A``#H+W```(N&*%8``(V.Z"```/]U -M#(F&""$``(N&+%8``%:)A@PA``"(GA`A``#H9X\``(I%$(V.Z"```(B&$2$` -M`(J&:58``(B&-R$``(V&T$4``(E!.(E9/(N&,%8``(N6-%8``(F%7&7__XF5 -M8&7__XB==&7__SB>\$4``'4*4E!1Z*Q7``#K$E/_MNQ%``"-C109___H;NX` -M``^VEII6``"-AIM6``#WVHV.H"$``!O2(]"-AD!6``!24.A!;P``A,!U*XV& -M^$4``%"-1B10:A_H5S```&H#N5`/1`#HDS(``(7_=`N+S^BF````ZP*S`8V- -M%!G__^BNX```7XK#6^L-C48D4&H>Z.\O```RP(M-]%YDB0T`````B^5=P@P` -M58OL@^Q,5XOYBX>\(0``@+@D40```'56!210``!0C4,```7HN'O"$``,:`)U$```%?B^5=PU:+\8,^`'0+_S;HM_H!`(,F`%F# -M9@0`@V8(`%[#58OLBU4,4X72?#>+30A_!(7)+\3/;Z.#[__^+^(7_=#F+;"04@_T%=`F#OMPA```%="=#]L-_=07HX\H` -M`#FNW"$``'0=B\[H=^#__XO.Z*?[__^+^(7_=75O"!`"+Q^OU4U97 -MB_$SV^L\@[[<(0``!70^0_;#?W4%Z)W*``"#OMPA```#=1;_="00C8;X10`` -M4.CF^0$`65F%P'06\($`(O'Z_96 -MB_'HA%L``#F&H&P``'48.9:D;```=1`YAJAL``!U"#F6K&P``'07C48D4&HX -MZ!4N``!J`;E0#T0`Z((P``!>P_]T)`B-023_="0(4&HBZ.H]``!J`;E0#T0` -MZ&$P``#""`"X@.Y#`,-5B^S_=1C_=13_=1#_=0S_=0CHX_____]P!/\PZ,$: -M`@"#Q!R%P'D#@\C_7<.-1"004&H`_W0D%/]T)!3_="04Z+O___^#Q!3#S,S, -MS,R+3"0$Z`,```#"!`!358O9O0`"``!65XMS"(M[!.LF@SW0@40``7P/@?X` -M!```<@`2!]G]2#E&+@OP```"!]XQH!9N+7"1DB4PD -M*+F%KF>[B4PD,(L0BT`$@?*KV8,?BTPD7#49S>!;B40D1#/MBT0D:(E$)#R+ -M1"1@B40D'(M$)%B)1"0LBT0D5(E$)#B+1"10B40D((M$)$R);"00B6PD2(ML -M)$2)1"04BT0D$,=$)"0Z]4^EB5PD0(E,)#0/MH"`-D,`BX2$C`````/!BTPD -M%`/(BT0D*(E,)!0SSHMT)#3!P1`#P3/PB40D*(M$)!#!S@R)="0T#[:`@39# -M`(N$A(P````#QHMT)!0#\(M$)#2)="04,_&+3"0HP) -M1"0TBT0D$(M,)"`/MH""-D,`BX2$C`````-$)!P#R(M$)#")3"0@,\^+?"0< -MP<$0`\$S^(E$)#"+1"00P<\,B7PD'`^V@(,V0P"+A(2,`````\>+?"0@`_B+ -M1"0);"0\BVPD$`^VA8@V0P"+A(2,`````T0D'`/(BT0D -M&(E,)!0SRHM4)!S!P1`#P3/0B40D&`^VA8DV0P"+;"04P+@?0```")1"0\#R@@#RAH$(N! -M^`````\I;"1`#RED)'`/*!B+10QF#^\=H.Y#`(M(&(M0$(MP"(LX9@]NT68/ -M;L)F#V[.9@]BRF8/;O=F#V+P9@]B\68/_O2)="0DBW`49@_^]68/[]Z)?"0L -MBW@,#RC[9@]R\Q!F#W+7$(E,)!R+2`1F#^_[#RCOB50D(&8/_BV0[D,`BU`< -M#RC%9@_O1"1`#RC@9@]NSV8/"QF#^_? -MBT`D#RC#9@]RT!!F#W+S$(E\)`QF#^_#BWPD.&8/;DPD#`\H\`\I1"109@_^ -M]`\HQF8/;MAF#^_%9@]NUP\HX&8/8LIF#W+0#&8/#O@`!``!`=D6+AO@` -M``"#`$"+CO@```"#.4`;P/?8`4$$_[;P````5N@HZ?__BX[P````@X8``0`` -MP/^V``$``(U!0%!1Z%V@`0"#Q`R+AO@```"+E@`!```!$(N.^````#D1&\#W -MV`%!!("^!`$```!T"HN&_````(-(!/^+AOP````S_X,(_[B`````BXX``0`` -M*\%0BX;P`````\%74.BBG@$`@\0,_[;P````5NBAZ/__BTPD$(N&]````(L$ -M!XD$#X/'!(/_('SL7U[""`"#/="!1``"?!P/*`50-T,`#RD%D.Y#``\H!4`W -M0P`/*06@[D,`5HMT)`B+SNB)`P``,]*+CO0```"+@B`W0P")!`J#P@2#^B!\ -MZ8N&]````($P(``(`HN.]````(M$)`PQ00B+CO0```"+1"00#0`@``#!X!`Q -M00Q>P@P`45>+?"04A?\/A+(```!358ML)!A6BW0D&(N.``$``+N`````BX;P -M````*]D#P8E\)!`[^W9F4U50Z!R?`0"+AO@```"#Q`P!G@`!``"#`$"+CO@` -M``"#.4`;P/?8`4$$@SW0@40``O^V\````%9\!^AH[/__ZP7HC.?__XN.\``` -M`&I`C4%`4%'HS)X!`(.&``$``,"#Q`PK^^L75U50Z+:>`0`!O@`!``"#Q`R+ -M7"00,_\#ZX7_#X5<____7EU;7UG"#`"![``!``!35597B[PD%`$``(UL)!`S -M]HO?BX=("P``.\9V&BO&@_A`=@-J0%A0C8=("0```\904^C^_O__55/HH_W_ -M_X/&0(/%(('#"`$``('^``(``'+!:@B!QT`(``"-="046VH@5E?HS?[__X/& -M((/K`77O_[0D&`$``%?H9/W__U]>75N!Q``!``#""`!355:+="00,^U7:``" -M``!5C89("0``4.B)G`$`@\0,B:Y("P``C89`"```:@%54.C[_?__B_V+WE57 -M4^CO_?__1X'#"`$``(/_"'+L7\:&1`D```'&ACP(```!7EU;P@0`@^QX4XN< -M)(0```!5BZPDA````%:^``(``%>+A4@+```K\(N\))0```")1"0:D!75>CM_?__@\=` -M@<4(`0``@^X!=>F+O"24`````UPD("M\)"`A="0FG0 -M"`$``(O(P>$&`]4#RXE4)"2-7"0HB4PD((/X"'-6B7L(B4L$B1.#_@%V$XN- -M3`L``%-HL#]``.@JL```ZP>+R^@1Y?__BT0D&(/##(M,)"!`BU0D)(/!0('" -M"`$``(E$)!C_1"00B4PD((E4)"0Y="00@DL@`` -MBT0D&(/X"`^"8?___XOW@>;_`0``*_X#WXM\)!R%]G035HV'2`D```/%4U#H -M,IP!`(/$#(T$-U]>B85("P``75N#Q'C"#`!6:/````"+\6H`5NBLF@$`@Z8` -M`0```(/$#,:&!`$```!>P[A(($,`Z/.)`0!15HOQB77PZ`!7``"#9?P`C8X< -MHP``Z.JE``"-CGRC``#&1?P!Z-NE``"-CMRC``#&1?P"Z,RE``"-CCRD``#& -M1?P#Z+VE``"-CIRD``#&1?P$Z*ZE``"+SL9%_`7HB0$``(M-](O&7F2)#0`` -M``"+Y5W#Z3"Z__^!P3RD``#II*4``+@$(```Z$**`0!35597:@!J`/^T)"@@ -M``#HT5@``(N,)!@@``"+V.A!I@``O0`(``#IH@```(U$)!!0Z$EB``"+\`^W -M#E'HSEX``("\)!P@````=`N$P'0;,\!FB0;K%(3`=!!5:+`U0P"-1"084.BQ -MI```:@!J`(U$)!B+^U#H:U@``(OP9H,^*G4Z#[=.`E'H@UX``(3`="QJ+EAJ -M7&:)A"04$```6%5FB80D%A```(V$)!@0``!34.B.I```C;PD$!```/^T)"@@ -M``!75NB=4@``A,!U)XN,)!@@``"-1"0055#H1J4``(3`#X5$____7UY=6X'$ -M!"```,(4`+`!Z^]5B^Q6:@;_=1"+\?]U"/]U#(V&?*,``%#HX/[__X3`=`2P -M`>LP@'T4`'0H@[[THP```'0?:@;_=1"-AMRC``#_=0C_=0Q0Z++^___VV!K` -M_L#K`C+`7EW"$`"!P3RD``#IR*0``%:+\>@Q5@``,\"-CARC``!FB8;Z@@`` -M9HF&&I,``&:)AO""``")AO2"``"(AOB"``#HN:0``(V.?*,``.BNI```C8[< -MHP``Z*.D``"-CIRD``#HF*0``(V./*0``.B-I```C8YP80``7ND>X/__45%3 -M55:+="0H5XOYA?9T#(-\)#``=@4SP&:)!HM,)!PSVT-3:@"*@?$0``"-:2B( -M1"08B\__="08B6PD(%7HZO[__X3`=32!QQRC``"+SXE\)!#H/Z0``(O/ZQ3_ -M="0D55?H-%$``(3`=1N+3"000^B5HP``B_B%_W7A,\!?7EU;65G"&`"+;"0@ -MA>UT$_]T)!17Z+*B``#WV!K`_L"(10"%]G0+_W0D,%=6Z,>B``"+P^O)4U56 -M5VBP[D,`B]GH)`$``+JP\D,`O@`!``"+B@#\__^+^FH'70^VP<'I"#,,A;#N -M0P")#XV_``0``(/M`77F@\($@^X!==-?7EV+PUO#58OLBU4,4XM="%:+=1"% -M]G0@]L('=!L/M@H/ML,SR,'K"#,"#_@@/@H<```!7 -MB_[![P,S&H/N"(M2!(O*P>D8B\+!Z!`/ML"+#(VP[D,`,PR%L/)#`(O"P>@( -M#[;`,PR%L/9#`(O#P>@8,PR%L/Y#`(O#P>@0#[;`,PR%L`)$`(O#P>@(#[;` -M,PR%L`9$``^VPHM5#(/""(E5##,,A;#Z0P`/ML,S#(6P"D0`B]F#[P%U@%^% -M]G08#[8*#[;#,\C!ZP@S'(VP[D,`0H/N`77H7HO#6UW"#`"+5"0$,\DY2@1U -M)U9J"(O!7J@!=`G1Z#4@@[CMZP+1Z(/N`77LB02*08'Y``$``'+;7L($`+B" -M($,`Z'.%`0!14U97:!!A0`!HD&!``&H$B_EH+`$``%>)??#H7(8!`&@084`` -M:)!@0`!J!&AX`0``C;>T!```,]M6B5W\Z#J&`0"-CYP*``#&1?P!Z/R```!H -ML`0``%-7B9^8"@``Z*R5`0!HX`4``%-6Z*"5`0!H``0``(V'I`L``(F?L`0` -M`%-0B9^4"@``Z(*5`0"+3?2#Q"2+QV2)#0````!?7EN+Y5W#S,S,S,S,S,S, -MS,S,45:+\8ET)`3HOHP``(O&7EG#58OL9*$`````:O]H@1]#`%!DB24````` -M5E>+^6BP!```5^@*CP``:.`%``"-M[0$``!6Z/F.``!H$&%``&H$:'@!``!6 -MZ-J%`0!H$&%``&H$:"P!``!7Z,B%`0"+3?1?9(D-`````%Z+Y5W#S,SI>HP` -M`(/L)%-55HMT)#0SVVH@78,^`G5#BT8$5U-34U.)1"0@C40D)%!J!(U$)"A0 -M5?]T)%SHI`8``(E>!(O3B_L/MD04%(O*@^$#P>$#T^`S^$([U7+JB7X$7X,^ -M`W4G4U-34XU$)""#Q@105595_W0D6.AF!@``58U$)!105NB[E0$`@\0,7EU; -M@\0DP@@`BX&8"@``@\#\@_@!=Q?_="0$@<&<"@``_W0D#/]T)`SHM8,``,(( -M`('L@`$``%-65XN\))@!``"+V8"_``$````/A+L```"+M"24`0``A?8/A*P` -M``!5O8````")LY@*``!5C40D%(O/4.@%C```58V$)!0!``!0C40D&%#HB[8` -M`(/N!'0^@^X!=53_M"2P`0``C40D%(O+_[0DL`$``/^T)+`!``#_M"2P`0`` -M_[0DL`$``%!7_[0DL`$``.@T`P``ZQO_M"2@`0``C40D%(O+4%?_M"2@`0`` -MZ#````!5C80D%`$``%#H1(T``&@``0``C40D%%#H-8T``+`!7>L",L!?7EN! -MQ(`!``#"(`"![!@"``!358O95E>)7"04,_^-LRH!``#_M"0P`@``C8[6_O__ -MZ+F*``"$P'0Q@[PD.`(```!U!8`^`.L<@#X`=!UJ"/^T)#P"``"-1MA0Z)6= -M`0"#Q`R%P`^$/0(``$>!QBP!``"#_P1RK6@(`0``C80D)`$``%#_M"0\`@`` -MZ+&U``#_M"0T`@``Z$+5`0"+Z`/M@[PD/`(```!9=!YJ"/^T)#P"``"-C"0H -M`0```\U1Z.B3`0"#Q`R#Q0B-1"1@4.BBE0``,]M5C80D)`$``%"-1"1H4.A= -ME@``B\.(7"00P>@(B$0D$8O#P>@0B$0D$HU$)!!J`U"-1"1H4.B7E0``]\/_ -M/P``=2]J&%F-1"0X4(V$),0```"-="1DC;PDQ````/.E4.AVE```BD0D2(O+ -MP>D.B$0,*$.!^P``!`!RAHU$)$Q0C40D9%#H490``(M<)!0STFH078UT)!@# -M\C/)BT043-/H@\$(B`9&@_D@+_3F>-`$``'4R_[0D?`(``(O. -MZ+R'``"$P'0@:A#_M"2(`@``C88"`0``4.BIF@$`@\0,A<`/A*(!``!'@<9X -M`0``@_\$-1"0D4(VS$@$``%;H?9`!`%>-1"104(V#.`$``%#H -M:Y`!`%>-1"1\4(V#6`$``%#H69`!`(/$,%5J`5=6Z,F'```YK"20`@``=!57 -MC40D6%#_M"28`@``Z#&0`0"#Q`R+M"24`@``A?9T*&H(55;HNHX!`(/$#(I$ -M+#2+S8/A!S`$,44[[W+O5XU$)#A0Z'Z(``"#O"2(`@```'0G_[0DB`(``(M, -M)!2-1"08:``!``!0_[0DA`(``('!G`H``.C$?```5XU$)!A0Z$*(``!?7EU; -M@<1D`@``PB``:B!?5XV&$@$``%"-1"0<4.B=CP$`@\0,C40D%%555U#H"H<` -M`%>-AC@!``!0C40D/%#H>X\!`%>-AE@!``!0C40D:%#H:8\!`(/$&.D5____ -M@>R\`0``4XN<),@!``!55E=J0%\[WW8]C80D9`$``%#HCI,``%/_M"34`0`` -MC80D;`$``%#HOY,``(U$)%10C80D:`$``%#H=I(``&H@C40D6%OK!XN$)-`! -M``"+K"3D`0``B40D$(7M=!R+E"3H`0``@#H`=!!J&EF+]8V\))0```#SI>MA -M,]*%VW0:B_"-1"04*_"-3"04`\J*!`XT-D*(`3O3-3"04*\,# -MRU!J-E'H0XT!`(/$#(V$))0```!0Z.62``!7C40D&%"-A"2<````4.@8DP`` -MBY0DZ`$``(7M=!:`.@!U$6H:68VT))0```"+_?.EQ@(!_[0DW`$``(V$))@` -M``#_M"3<`0``4.CMFA=MT'HM4)!"-1"04*]`S]HU, -M)!0#SHH$"C1<1H@!._-R[H/[0',7:D!8*\.-3"044`/+:EQ1Z'",`0"#Q`R- -MA"3\````4.@2D@``:D"-1"084(V$)`0!``!0Z$22``"+A"3P`0``A>UT%H`X -M`'41:AI9C;0D_````(O]\Z7&``%J((U$)'A0C80D!`$``%#H#Y(``/^T).`! -M``"-A"0``0``4.C$D```7UY=6X'$O`$``,(D`%6-;"2H@>R0`0``4U:+=6Q7 -M:D!8._!S`HO&4/]U:(U%N%#H+XT!`(/$#,=$-;@````!,\!04%!0C44<4(U& -M!%"-1;A0_W5D_W5@Z*;]__]J(%M3C44<4(U%_%#H]HP!`(M%?(/$#$C&158` -MB45(,_;&15<`:A!8B45,B450BT5PB44\BT5TB45`BT5XB45$BWPU2(7_=$^- -M15=0C84P____4(U%5E"-A0@`=1L[]0^#W@```(H$'D9"B$$$B50D%,=!"`@` -M```/MD$$P>@&@^@`#X1B`0``@^@!#X0L`0``@^@!#X3S````@^@!#X6(```` -M._4/@X`````/MAP>1D*)5"04A-L/B:$````[]7-JBT0D*(/C?XH,!D9"B$PD -M$XE4)!2#PP*+1"0T._@/@R8!```[?"0D#X,<`0``BT0D(&8/OA0'#[;!#[9, -M)!)F`]"X_P```&8CT$`/K\B+1"0P9@/1BDPD$TMFB11X1X7;?[6+5"04BTPD -M&(M$)#3`800"@T$(_HM<)"@[]0^"#/___SOX<@.->/^+1"0P,\EFB0QX7UY= -M6X/$#,(8`(/#`HM$)#0[^'/&.WPD)'/`BT0D($N+;"0P9@^^!`=FB41]`$>+ -M;"0LA=M_UNN>.]5SF@^V3!X!N``!```/K\@/M@0>@\8"9@/(BT0D,&:)#'A' -M@\("B50D%.EJ____._4/@V;___\/MDPD$K@``0``#[84'@^OR(M$)#!F`]%F -MB11X1XM4)!1&0NO*._4/@SG___\/M@0>BUPD,&:)!'M'1D*)5"04Z2'___^+ -M5"04BTPD&.D8____58OL@^Q,_W4(C4VTZ#NH__^+3?2#^0AS"HM%#(E$C;3_ -M1?2-3;3HFZ,``(OE7<((`%6+[(/L3/]U"(U-M.@*J/__BTWT@_D(L",L!>P@@`5HOQ@'X,`'42_W0D"&H* -MZ";___^+SNC@`0``:@*+SNB/`0``7L($`%;_="0,B_'_="0,:@GH,?___XO. -MZ+H!``!J"8O.Z&D!``!>P@@`_W0D!&H`Z,_____"!`#I&P(``%6+[('L``@` -M`(U%$%!J`/]U#(V%`/C__V@`!```4.C7T/__@\04C84`^/__4&H!Z*7^__^+ -M30CH7@$``(OE7PU6+[(/L3%:+ -M\8U-M&H'Z(NF__^-3;3H_:$``&H(B\[HIP```%Z+Y5W#5HOQZ#>:``#_="0, -M_W0D#&H(Z$/^__^+SNC,````:@:+SNA[````7L((`/]T)`1J`.C*____P@0` -M5O]T)`B+\6H`Z`T```!J#(O.Z!L!``!>P@0`5O]T)`R+\?]T)`QJ#.CT_?__ -MB\[H?0```&H,B\[H+````%[""`!6B_&`?@P`=1+_="0(:@OHF_W__XO.Z%4` -M``!J`HO.Z,T```!>P@0`BU0D!(O"@^@!=!&#Z`%T)H/H`704+?P```!U!8,Y -M`'4"B1'_003"!`"#.0MT]<P` -M"```C00D:``$``!0Z)+^__^$P'1B4U56:@U=:@I9C70D##/;5P^W!F8[Q70% -M9CO!=06#Q@+K[F8Y'G0W55;HTJ75N!Q``(``##58OL45:+=0B! -M_O\```!U#8!Y"`!U!UZ+Y5W"!`!6Z!3___]H0+-#`(U%_(EU_%#H$:@!`,S_ -M="0(_W0D"&HAZ*O\__]J`KE0#T0`Z.?^___""`!6_W0D#(OQ_W0D#.@-```` -M:@6+SNB4____7L((`%;_="0,B_'_="0,:@WH;?S__XO.Z/;^__]J!8O.Z*7^ -M__]>P@@`,\")@1`0``")@100``")@1@0``")@1P0``")@2`0``")@200``"+ -MP<-6BW0D"#/`5XOX9CD*````4U5J+H/&`C/;70^W1OY0Z)1)``"$P'1G -M#[<&9H7`=%]0Z())``"$P'559CDN=1X/MT8"4.AO20``A,!U"C/`9CE&`G4* -MZP(SP+,!ZP0SP(K89CDN=1YF.6X"=1@/MT8$4.A"20``A,!U"#/`9CE&!'4" -ML`&$VW4%A,!U`4B-O83O__^+QVCT-T,`4.B&Z`$`@\00]]@:P/[` -MB47PA,!T-&H$C;V,[___B\=H`#A#`%#H8>@!`(/$#(7`=1AJ7%AFB86$W___ -MC;V2[___C86&W___ZP:-A83?__]74.@3Z`$`C86$W___4.BTQ0$`BWT,@\0, -MB47LBT4(.)B780``=3PX7?`/A2\#``"-A@01``!0Z"I'``"$P`^%&P,``(V& -M!!$``%!7C48H4/]U".AM!P``A,`/A/\"``"+10@/MH!'80``4&H!5^C`+@`` -M5^@^,```A,!T'5?H2#```%#HD#```%>$P'0'Z'XO``#K!>C*+P``.)[Q$``` -M#X6V````.)X$(0``#X6J````4VB`````:@%34V@```!`5_\5)#!#`(/X_W40 -M5[E0#T0`Z,'Z___I@@(``%#_%1@P0P"+A@`1``"#^`,/A8P```"+3=2+5>B+ -M1>P#PLP#P&:)1@Z-A83?__]0BT7H@\`)C01&4.C&Y@$` -M@\00Z:$```!35_\5'#!#`(7`#X5X____5U-J%.A!^?__N5`/1`#IK0```(/X -M`G0)@_@!#X72`0``BTW4BU7HBT7L`\+'`0P``*"--!)FB7$*C01%$````&:) -M000SP(E!!HV%A.___U"-0110Z%7F`0"-1@*+==1FB48,BT7L`\!FB48.C86$ -MW___4(M%Z(/`"XT$1E#H+.8!`(M%\(/$$`^VP(/P`8E&$%-H```@`FH#4U-H -M````P%?_%20P0P"+R(E-\(/Y_W4;OE`/1`!7B\[H;_G__XO.:@GHR_K__^DG -M`0``4XU%T%`/MT8$4U.#P`A05FBD``D`4?\5$#!#`(7`=7;_=?#_%1@P0P!7 -M4VH5Z$SX____%0`P0P"#^`5T!STB!0``=1OHOHT``(3`=1)J&(U-A.A"H/__ -MC4V$Z+2;``"^4`]$`(O.Z*/Z__]J"8O.Z%+Z__^+=1!7.)[Q$```=`O_%2`P -M0P#IG````/\5*#!#`.F1````C8U)1>")1>2)1>B) -M1>R(1?"+?0B+SU!0B47\C47@4.A1Q/__A,`/A,H```"`/;(.1```=29H:#=# -M`.@X!@``A,!T!\8%L0Y$``%HD#=#`.@C!@``Q@6R#D0``8`]L0Y$``!6:@=> -M=`-J#UY3BUW@4U;_=0S_%0`@1@"%P'5V:``(``"-A93O__]0_W4,Z'U!``"$ -MP'034U:-A93O__]0_Q4`($8`A__^-393HSYD``&H! -MB\_H>?C__UM>C4W@Z'>>__^+3?1?9(D-`````(OE7<((`%6+[(/L3%;_=12+ -M=1!65NCO1P``5NC]*P``A,!U+/]U#&H6Z+WU__]J%XU-M.C_G?__C4VTZ'&9 -M``!J";E0#T0`Z!CX__\RP.M-BT4(4P^V@$=A``!0:@'_=0SH,RH``&H`5O]U -M#/\5+#!#`(7`#Y7#A-MU'_]U#&H6Z&;U__^^4`]$`(O.Z!OX__]J"8O.Z,KW -M__^*PUM>B^5=PA``N,H@0P#H4&T!`+C(8```Z")N`0!35HMU##/`5V8Y!G0M -M9CE&`G4GOP((``"-A>SO__]7:&`W0P!0Z/F(``!75HV%[.___U#HPX@``.L3 -MOP((``"-A>SO__]75E#HUH@``(M="(V%?+___V@`"```4%/HC0$``&:#O7R_ -M__\Z=!U6C4,D4&I3Z.ST__]J`[E0#T0`Z"CW___I+`$``(!]$`!T+(V-+)__ -M_^@.'P``:@&-A2R?__\S_U!7B\N)??SH!,+__XV-+)___^GU````5XV%?+__ -M_U"-A>SO__]0Z"R(``"-C7S/___H,?C__S/_C85\S___5U!6Z,$M``"+C83? -M__^(1?/VP0%T"H/A_E%6Z"``"`??,`QD7\`G0S:@56C8U4K___Z-0A``"$P'0AC86T -MW___4(V%K-___U"-A:3?__]0_[58K____Q44,$,`_[6$W___5NB*+```C8U4 -MK___Z#@>``"-C<3?___H+1X``(M-]%]>6V2)#0````"+Y5W"#`"+1"0,@[BP -M;````W45!8`B``!0_W0D%/]T)`SH\/?__^L",L#"$`!5B^RX`"```.@F;`$` -MBT4(5X.XL&P```*+B/A5``"+N/Q5``!U(8M%$-'O2#OX<@*+^%:+=0Q75E'H -MTIP``#/`9HD$?E[K-KC_'P``._AR`HOX5U&-A0#@__]0Z/-\`0"#Q`S&A#T` -MX/__`(V%`.#___]U$/]U#%#HSIP``%^+Y5W"#`!145-55E?_="0@Z,@_``"$ -MP`^%Y@```(M\)"A7Z+8_``"$P`^%U````(MT)"0SVXOKB5PD$&8Y'W1>:BZ# -MQP2+PUEF.4_\=31F.4_^=2X/MP=0Z"5```"$P'4%9CD?=14Y7"00=`X/MT?Z -M4.@,0```A,!T`46+1"00:BY9@\<"0(E$)!!F.5_\=;B%[7X*5NAT````A,!U -M9?]T)"#H(/;__XE$)!2+1"0___P!U'X"]Q.___P!T%H/N`HV%`/#__SOP -M=ZLRP%Z+Y5W"!`"P`>OU5HMT)`Q7BWPD#("_`6(```!U*H"_E&$```!T(8V& -M^$4``&@,.$,`4.A7O`$`65F%P'4*_W0D%%;HQOG__XV&^$4``&@4.$,`4.@V -MO`$`65F%P'42#[:'`6(``%#_="085NA?^___7U["#`#"#`!65XOYBP>+<`B+ -MSO\58#)#`(O/_]:+1"0,B4<$7U["!`!5B^R#[!2-1?Q34&H@,]O_%0PP0P!0 -M_Q4(($8`A#)@"-7A"#9@0`B\OH>$P``(M]"#/`@V7\ -M`(E^"&:)AO8```!FB8;X$```(8;D````:.#F``#H-6S&1?P!A+^8NWX````(7V=!2+SNBYGP``:.#F``!6Z`1G`0!9 -M68U/$%]>Z8%,``"+5"0$BT$$.T($=PUR!HL!.P)S!3/`0.L",\#"!`"+1"0$ -MBQ&+200[2`1W$W($.Q!W#3L0=04[2`1T!#/`ZP,SP$#"!`!35HMT)`R#OK!L -M```#=0R#OIPB```R#Y?`ZPJ#OIPB```=#Y7`@+Z@(@````^4P_[+(MAT&O]T -M)!"#QB2Y4`]$`%;HW_'__U9J).A@[O__#[;#7H/P`5O""`#H]"\``"T!!0`` -M]]@;P"4```P`!0``!`##N$@0``#H(6^"`` -M`&:+@/J"``!FB49W?__BTX(A,!UGSB9)U$``'0+@<$D4```Z`5N```YGN0```!U -M/(M&"&:#N/J"``!)="^A4`]$`(/X"W0E.)[X(```=0U7:D3H%>W__Z%0#T0` -MA>___U]>75N!Q$@0``##N`00``#HVF4!`%>+^8M'"("X -M`6(````/A=0!``"`N*AA````4XN<)!`0```/E,!55@^VP(VW^!```/^SI"(` -M`%!6Z&8U# -M)%!JL\,L"(1"03BT<(#[:`1V$``%!J`5;H6"```(M' -M"/^SI"(``("XJ&$````/E,`/ML!05NA&(@``B^B*1"03A>UT((3`#X2!```` -MBT<(@+BH80```'4,_[.D(@``5NA9)```QH?W$````8"_]Q````!T3%93_W<( -MZ*CZ__^+5PB-@]`R``"+BMAR``#WV1O)(\B-@\@R``!1BXK4<@``]]D;R2/( -MC8/`,@``48N*T'(``/?9&\DCR%%6Z&0B``!>75M?@<0$$```P@@`5HU#)%!J -M%.@?Z___O5`/1`"+S>BC[?__:@F+S>A2[?__Z7C___^X4!```.BY8P$`4U6+ -MZ;,!BT4(#[>0^H(``(/Z170)@_I8#X4B`0``@+@!8@````^%%0$``%97B[PD -M9!```(VU^!```&H!C8_`,@``4?^WY#(``(U,)!__M^`R``!1:``(``!6_[0D -MA!```%#H*A(``(3`#X7/````,MLX7"03#X7#````C4G__V@`"```5HU$)&A0Z-U]``!J`5;H_S@` -M`(M%"`^V@$=A``!0:@%6Z(`>``!J`8V'P#(``%#_M^0R``"-1"0?_[?@,@`` -M4&@`"```5O^T)(00``#_=0CH:A$``(3`=`2S`>L/5HU')+E0#T0`4.AZZO__ -M7UY=BL-;@<10$```P@@`5HOQBT8(@+@D40```'4?!210``!0_W0D$&H!Z&F2 -M``"$P'0,BTX(QH$G40```;`!7L((`%%3BUPD&%56BW0D'%>+^5.+1P@%$B`` -M`%!6Z!I]``"+1P@SR042(```B4PD$&8Y"'0D4.@].@``#[

    <" - "A NAME=\"Life_cycle_of_a_te"; - const char file_test_txt5[] = "LE=\"margin-bottom: 0in\">DO use runtime te" - "sts for platform\n\tfeatu"; - const char file_test_txt6[] = "rough test suite is essential\nboth for ver" - "ifying new ports and f"; - const char file_test_txt7[] = "m: 0in\">Creates a temporary directory\n\tw" - "hose name matches the na"; - const char file_test_txt8[] = "lt\ninput file and verify the results. Thes" - "e use \n", buff); - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, -1, archive_seek_data(a, -(((int)sizeof(buff)-1)*2), SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), archive_seek_data(a, 0, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualIntA(a, ((sizeof(buff)-1)*2), archive_seek_data(a, 0, SEEK_CUR)); - assertEqualStringA(a, "\n\n\t\n\t\n\t 0); - - /* Seek to the end minus (sizeof(buff)-1) bytes */ - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, -((int)sizeof(buff)-1), SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - /* Seek back to the beginning */ - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, archive_seek_data(a, -20111, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - /* Test that SEEK_SET works correctly between data blocks */ - assertEqualIntA(a, 0, archive_seek_data(a, 0, SEEK_SET)); - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 13164, - archive_seek_data(a, 13164, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "ertEqualInt,\n\tassertEqualString, " - "assertEqualMem to test equalit", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, 0, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 20111 - (int)(sizeof(buff)-1), SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 13164, - archive_seek_data(a, 13164, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "ertEqualInt,\n\tassertEqualString, " - "assertEqualMem to test equalit", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 20111 - (int)(sizeof(buff)-1), SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, 0, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 20111 - (int)(sizeof(buff)-1), SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 13164, - archive_seek_data(a, 13164, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "ertEqualInt,\n\tassertEqualString, " - "assertEqualMem to test equalit", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, 0, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - /* Test that SEEK_CUR works correctly between data blocks */ - assertEqualIntA(a, 0, archive_seek_data(a, 0, SEEK_SET)); - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 13164, - archive_seek_data(a, 13164, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "ertEqualInt,\n\tassertEqualString, " - "assertEqualMem to test equalit", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -13227, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 19985, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 13164, - archive_seek_data(a, -6947, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "ertEqualInt,\n\tassertEqualString, " - "assertEqualMem to test equalit", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 6821, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -20111, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 19985, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 13164, - archive_seek_data(a, -6947, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "ertEqualInt,\n\tassertEqualString, " - "assertEqualMem to test equalit", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -13227, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - /* Test that SEEK_END works correctly between data blocks */ - assertEqualIntA(a, 0, archive_seek_data(a, 0, SEEK_SET)); - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 13164, - archive_seek_data(a, -6947, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "ertEqualInt,\n\tassertEqualString, " - "assertEqualMem to test equalit", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -20111, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, -((int)sizeof(buff)-1), SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 13164, - archive_seek_data(a, -6947, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "ertEqualInt,\n\tassertEqualString, " - "assertEqualMem to test equalit", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, -((int)sizeof(buff)-1), SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -20111, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, -((int)sizeof(buff)-1), SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 13164, - archive_seek_data(a, -6947, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "ertEqualInt,\n\tassertEqualString, " - "assertEqualMem to test equalit", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -20111, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - test_read_format_rar_multivolume_uncompressed_files_helper(a); - - /* - * Second header. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualStringA(a, "testdir/testsubdir/LibarchiveAddingTest2.html", - archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualIntA(a, 20111, archive_entry_size(ae)); - assertEqualIntA(a, 33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - test_read_format_rar_multivolume_uncompressed_files_helper(a); - - /* Read from the beginning to the end of the file */ - assertEqualIntA(a, 0, archive_seek_data(a, 0, SEEK_SET)); - do - { - memset(buff, 0, sizeof(buff)); - bytes_read = archive_read_data(a, buff, (sizeof(buff)-1)); - } while (bytes_read > 0); - - /* Seek to the end minus (sizeof(buff)-1) bytes */ - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, -((int)sizeof(buff)-1), SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - /* Seek back to the beginning */ - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, archive_seek_data(a, -20111, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - /* Test that SEEK_SET works correctly between data blocks */ - assertEqualIntA(a, 0, archive_seek_data(a, 0, SEEK_SET)); - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 6162, - archive_seek_data(a, 6162, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "arguments satisfy certain conditions. " - "If the assertion fails--f", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 19347, - archive_seek_data(a, 19347, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, " when a block being written out by\n" - "the archive writer is the sa", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 20111 - (int)(sizeof(buff)-1), SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 19347, - archive_seek_data(a, 19347, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, " when a block being written out by\n" - "the archive writer is the sa", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 6162, - archive_seek_data(a, 6162, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "arguments satisfy certain conditions. " - "If the assertion fails--f", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, 0, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 20111 - (int)(sizeof(buff)-1), SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 6162, - archive_seek_data(a, 6162, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "arguments satisfy certain conditions. " - "If the assertion fails--f", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 19347, - archive_seek_data(a, 19347, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, " when a block being written out by\n" - "the archive writer is the sa", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, 0, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 20111 - (int)(sizeof(buff)-1), SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, 0, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 19347, - archive_seek_data(a, 19347, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, " when a block being written out by\n" - "the archive writer is the sa", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 6162, - archive_seek_data(a, 6162, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "arguments satisfy certain conditions. " - "If the assertion fails--f", buff); - - /* Test that SEEK_CUR works correctly between data blocks */ - assertEqualIntA(a, 0, archive_seek_data(a, 0, SEEK_SET)); - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 6162, - archive_seek_data(a, 6162, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "arguments satisfy certain conditions. " - "If the assertion fails--f", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 19347, - archive_seek_data(a, 13122, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, " when a block being written out by\n" - "the archive writer is the sa", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 638, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 19347, - archive_seek_data(a, -764, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, " when a block being written out by\n" - "the archive writer is the sa", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 6162, - archive_seek_data(a, -13248, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "arguments satisfy certain conditions. " - "If the assertion fails--f", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -6225, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 19985, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 6162, - archive_seek_data(a, -13949, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "arguments satisfy certain conditions. " - "If the assertion fails--f", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 19347, - archive_seek_data(a, 13122, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, " when a block being written out by\n" - "the archive writer is the sa", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -19410, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 19985, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -20111, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 19347, - archive_seek_data(a, 19284, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, " when a block being written out by\n" - "the archive writer is the sa", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 6162, - archive_seek_data(a, -13248, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "arguments satisfy certain conditions. " - "If the assertion fails--f", buff); - - /* Test that SEEK_END works correctly between data blocks */ - assertEqualIntA(a, 0, archive_seek_data(a, 0, SEEK_SET)); - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 6162, - archive_seek_data(a, -13949, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "arguments satisfy certain conditions. " - "If the assertion fails--f", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 19347, - archive_seek_data(a, -764, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, " when a block being written out by\n" - "the archive writer is the sa", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, -((int)sizeof(buff)-1), SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 19347, - archive_seek_data(a, -764, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, " when a block being written out by\n" - "the archive writer is the sa", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 6162, - archive_seek_data(a, -13949, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "arguments satisfy certain conditions. " - "If the assertion fails--f", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -20111, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, -((int)sizeof(buff)-1), SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 6162, - archive_seek_data(a, -13949, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "arguments satisfy certain conditions. " - "If the assertion fails--f", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 19347, - archive_seek_data(a, -764, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, " when a block being written out by\n" - "the archive writer is the sa", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -20111, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, -((int)sizeof(buff)-1), SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -20111, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 19347, - archive_seek_data(a, -764, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, " when a block being written out by\n" - "the archive writer is the sa", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 6162, - archive_seek_data(a, -13949, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "arguments satisfy certain conditions. " - "If the assertion fails--f", buff); - - test_read_format_rar_multivolume_uncompressed_files_helper(a); - - /* - * Third header. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualStringA(a, "LibarchiveAddingTest2.html", - archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualIntA(a, 20111, archive_entry_size(ae)); - assertEqualIntA(a, 33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - test_read_format_rar_multivolume_uncompressed_files_helper(a); - - /* Read from the beginning to the end of the file */ - assertEqualIntA(a, 0, archive_seek_data(a, 0, SEEK_SET)); - do - { - memset(buff, 0, sizeof(buff)); - bytes_read = archive_read_data(a, buff, (sizeof(buff)-1)); - } while (bytes_read > 0); - - /* Seek to the end minus (sizeof(buff)-1) bytes */ - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, -((int)sizeof(buff)-1), SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - /* Seek back to the beginning */ - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, archive_seek_data(a, -20111, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - /* Test that SEEK_SET works correctly between data blocks */ - assertEqualIntA(a, 0, archive_seek_data(a, 0, SEEK_SET)); - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 12353, - archive_seek_data(a, 12353, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, " 0.2in\">    " - "extract_reference_file("test_foo.tar", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, 0, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 20111 - (int)(sizeof(buff)-1), SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 12353, - archive_seek_data(a, 12353, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, " 0.2in\">    " - "extract_reference_file("test_foo.tar", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 20111 - (int)(sizeof(buff)-1), SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, 0, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 20111 - (int)(sizeof(buff)-1), SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 12353, - archive_seek_data(a, 12353, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, " 0.2in\">    " - "extract_reference_file("test_foo.tar", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, 0, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - /* Test that SEEK_CUR works correctly between data blocks */ - assertEqualIntA(a, 0, archive_seek_data(a, 0, SEEK_SET)); - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 12353, - archive_seek_data(a, 12353, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, " 0.2in\">    " - "extract_reference_file("test_foo.tar", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -12416, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 19985, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 12353, - archive_seek_data(a, -7758, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, " 0.2in\">    " - "extract_reference_file("test_foo.tar", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 7632, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -20111, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 19985, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 12353, - archive_seek_data(a, -7758, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, " 0.2in\">    " - "extract_reference_file("test_foo.tar", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -12416, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - /* Test that SEEK_END works correctly between data blocks */ - assertEqualIntA(a, 0, archive_seek_data(a, 0, SEEK_SET)); - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 12353, - archive_seek_data(a, -7758, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, " 0.2in\">    " - "extract_reference_file("test_foo.tar", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -20111, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, -((int)sizeof(buff)-1), SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 12353, - archive_seek_data(a, -7758, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, " 0.2in\">    " - "extract_reference_file("test_foo.tar", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, -((int)sizeof(buff)-1), SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -20111, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, -((int)sizeof(buff)-1), SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 12353, - archive_seek_data(a, -7758, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, " 0.2in\">    " - "extract_reference_file("test_foo.tar", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -20111, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - test_read_format_rar_multivolume_uncompressed_files_helper(a); - - /* - * Fourth header. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualStringA(a, "testdir/LibarchiveAddingTest.html", - archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualIntA(a, 20111, archive_entry_size(ae)); - assertEqualIntA(a, 33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - test_read_format_rar_multivolume_uncompressed_files_helper(a); - - /* Read from the beginning to the end of the file */ - assertEqualIntA(a, 0, archive_seek_data(a, 0, SEEK_SET)); - do - { - memset(buff, 0, sizeof(buff)); - bytes_read = archive_read_data(a, buff, (sizeof(buff)-1)); - } while (bytes_read > 0); - - /* Seek to the end minus (sizeof(buff)-1) bytes */ - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, -((int)sizeof(buff)-1), SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - /* Seek back to the beginning */ - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, archive_seek_data(a, -20111, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - /* Test that SEEK_SET works correctly between data blocks */ - assertEqualIntA(a, 0, archive_seek_data(a, 0, SEEK_SET)); - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 5371, - archive_seek_data(a, 5371, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "zip)\n  {\n    " - "/* ... setup omitted ... */\n  ", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 13165, - archive_seek_data(a, 13165, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "rtEqualInt,\n\tassertEqualString, " - "assertEqualMem to test equality", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 20111 - (int)(sizeof(buff)-1), SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 13165, - archive_seek_data(a, 13165, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "rtEqualInt,\n\tassertEqualString, " - "assertEqualMem to test equality", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 5371, - archive_seek_data(a, 5371, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "zip)\n  {\n    " - "/* ... setup omitted ... */\n  ", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, 0, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 20111 - (int)(sizeof(buff)-1), SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 5371, - archive_seek_data(a, 5371, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "zip)\n  {\n    " - "/* ... setup omitted ... */\n  ", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 13165, - archive_seek_data(a, 13165, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "rtEqualInt,\n\tassertEqualString, " - "assertEqualMem to test equality", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, 0, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 20111 - (int)(sizeof(buff)-1), SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, 0, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 13165, - archive_seek_data(a, 13165, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "rtEqualInt,\n\tassertEqualString, " - "assertEqualMem to test equality", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 5371, - archive_seek_data(a, 5371, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "zip)\n  {\n    " - "/* ... setup omitted ... */\n  ", buff); - - /* Test that SEEK_CUR works correctly between data blocks */ - assertEqualIntA(a, 0, archive_seek_data(a, 0, SEEK_SET)); - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 5371, - archive_seek_data(a, 5371, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "zip)\n  {\n    " - "/* ... setup omitted ... */\n  ", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 13165, - archive_seek_data(a, 7731, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "rtEqualInt,\n\tassertEqualString, " - "assertEqualMem to test equality", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 6820, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 13165, - archive_seek_data(a, -6946, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "rtEqualInt,\n\tassertEqualString, " - "assertEqualMem to test equality", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 5371, - archive_seek_data(a, -7857, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "zip)\n  {\n    " - "/* ... setup omitted ... */\n  ", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -5434, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 19985, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 5371, - archive_seek_data(a, -14740, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "zip)\n  {\n    " - "/* ... setup omitted ... */\n  ", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 13165, - archive_seek_data(a, 7731, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "rtEqualInt,\n\tassertEqualString, " - "assertEqualMem to test equality", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -13228, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 19985, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -20111, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 13165, - archive_seek_data(a, 13102, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "rtEqualInt,\n\tassertEqualString, " - "assertEqualMem to test equality", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 5371, - archive_seek_data(a, -7857, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "zip)\n  {\n    " - "/* ... setup omitted ... */\n  ", buff); - - /* Test that SEEK_END works correctly between data blocks */ - assertEqualIntA(a, 0, archive_seek_data(a, 0, SEEK_SET)); - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 5371, - archive_seek_data(a, -14740, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "zip)\n  {\n    " - "/* ... setup omitted ... */\n  ", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 13165, - archive_seek_data(a, -6946, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "rtEqualInt,\n\tassertEqualString, " - "assertEqualMem to test equality", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, -((int)sizeof(buff)-1), SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 13165, - archive_seek_data(a, -6946, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "rtEqualInt,\n\tassertEqualString, " - "assertEqualMem to test equality", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 5371, - archive_seek_data(a, -14740, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "zip)\n  {\n    " - "/* ... setup omitted ... */\n  ", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -20111, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, -((int)sizeof(buff)-1), SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 5371, - archive_seek_data(a, -14740, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "zip)\n  {\n    " - "/* ... setup omitted ... */\n  ", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 13165, - archive_seek_data(a, -6946, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "rtEqualInt,\n\tassertEqualString, " - "assertEqualMem to test equality", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -20111, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, -((int)sizeof(buff)-1), SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -20111, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 13165, - archive_seek_data(a, -6946, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "rtEqualInt,\n\tassertEqualString, " - "assertEqualMem to test equality", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 5371, - archive_seek_data(a, -14740, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "zip)\n  {\n    " - "/* ... setup omitted ... */\n  ", buff); - - test_read_format_rar_multivolume_uncompressed_files_helper(a); - - /* - * Fifth header. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualStringA(a, "testdir/testsubdir/LibarchiveAddingTest.html", - archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualIntA(a, 20111, archive_entry_size(ae)); - assertEqualIntA(a, 33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - test_read_format_rar_multivolume_uncompressed_files_helper(a); - - /* Read from the beginning to the end of the file */ - assertEqualIntA(a, 0, archive_seek_data(a, 0, SEEK_SET)); - do - { - memset(buff, 0, sizeof(buff)); - bytes_read = archive_read_data(a, buff, (sizeof(buff)-1)); - } while (bytes_read > 0); - - /* Seek to the end minus (sizeof(buff)-1) bytes */ - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, -((int)sizeof(buff)-1), SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - /* Seek back to the beginning */ - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, archive_seek_data(a, -20111, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - /* Test that SEEK_SET works correctly between data blocks */ - assertEqualIntA(a, 0, archive_seek_data(a, 0, SEEK_SET)); - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 11568, - archive_seek_data(a, 11568, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ", assertFileContents," - "\n\t\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 20111 - (int)(sizeof(buff)-1), SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 11568, - archive_seek_data(a, 11568, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ", assertFileContents," - "\n\t\n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, 0, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 20111 - (int)(sizeof(buff)-1), SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 11568, - archive_seek_data(a, 11568, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ", assertFileContents," - "\n\t\n", buff); - - /* Test that SEEK_CUR works correctly between data blocks */ - assertEqualIntA(a, 0, archive_seek_data(a, 0, SEEK_SET)); - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 11568, - archive_seek_data(a, 11568, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ", assertFileContents," - "\n\t\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 19985, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 11568, - archive_seek_data(a, -8543, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ", assertFileContents," - "\n\t\n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -20111, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 19985, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 11568, - archive_seek_data(a, -8543, SEEK_CUR)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ", assertFileContents," - "\n\t\n", buff); - - /* Test that SEEK_END works correctly between data blocks */ - assertEqualIntA(a, 0, archive_seek_data(a, 0, SEEK_SET)); - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 11568, - archive_seek_data(a, -8543, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ", assertFileContents," - "\n\t\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, -((int)sizeof(buff)-1), SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 11568, - archive_seek_data(a, -8543, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ", assertFileContents," - "\n\t\n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, - archive_seek_data(a, -20111, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, -((int)sizeof(buff)-1), SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 11568, - archive_seek_data(a, -8543, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ", assertFileContents," - "\n\t\n", buff); - - test_read_format_rar_multivolume_uncompressed_files_helper(a); - - /* - * Sixth header. - */ - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualStringA(a, "LibarchiveAddingTest.html", - archive_entry_pathname(ae)); - assertA((int)archive_entry_mtime(ae)); - assertA((int)archive_entry_ctime(ae)); - assertA((int)archive_entry_atime(ae)); - assertEqualIntA(a, 20111, archive_entry_size(ae)); - assertEqualIntA(a, 33188, archive_entry_mode(ae)); - assertEqualInt(archive_entry_is_encrypted(ae), 0); - assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0); - - test_read_format_rar_multivolume_uncompressed_files_helper(a); - - /* Read from the beginning to the end of the file */ - assertEqualIntA(a, 0, archive_seek_data(a, 0, SEEK_SET)); - do - { - memset(buff, 0, sizeof(buff)); - bytes_read = archive_read_data(a, buff, (sizeof(buff)-1)); - } while (bytes_read > 0); - - /* Seek to the end minus (sizeof(buff)-1) bytes */ - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, -((int)sizeof(buff)-1), SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - /* Seek back to the beginning */ - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 0, archive_seek_data(a, -20111, SEEK_END)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\n", buff); - - /* Test that SEEK_SET works correctly between data blocks */ - assertEqualIntA(a, 0, archive_seek_data(a, 0, SEEK_SET)); - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 4576, - archive_seek_data(a, 4576, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "hat was expected. \n

    \n

    Large tar tester

    \n

    The " - "large tar tester attempts to", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 20111 - (int)(sizeof(buff)-1), - archive_seek_data(a, 20111 - (int)(sizeof(buff)-1), SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, ". \n

    \n


    \n" - "

    \n\n", buff); - - memset(buff, 0, sizeof(buff)); - assertEqualIntA(a, 17749, - archive_seek_data(a, 17749, SEEK_SET)); - assertEqualIntA(a, (sizeof(buff)-1), - archive_read_data(a, buff, (sizeof(buff)-1))); - assertEqualStringA(a, "\">Large tar tester